commit 385638c5e1eccbdfb39ae4d6df2dd9096d5264a9 Author: Migdyn Date: Sat Oct 8 17:16:13 2022 -0400 Initial commit diff --git a/AppImageBuilder.yml b/AppImageBuilder.yml new file mode 100644 index 0000000..5788e24 --- /dev/null +++ b/AppImageBuilder.yml @@ -0,0 +1,54 @@ +version: 1 + +AppDir: + path: ./AppDir + + app_info: + id: minetest + name: Minetest + icon: minetest + version: !ENV ${VERSION} + exec: usr/bin/minetest + exec_args: $@ + runtime: + env: + APPDIR_LIBRARY_PATH: $APPDIR/usr/lib/x86_64-linux-gnu + + apt: + arch: amd64 + sources: + - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic main universe + key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3b4fe6acc0b21f32' + - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-updates main universe + - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-backports main universe + - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-security main universe + + include: + - libc6 + - libcurl3-gnutls + - libfreetype6 + - libgl1 + - libjpeg-turbo8 + - libjsoncpp1 + - libleveldb1v5 + - libopenal1 + - libpng16-16 + - libsqlite3-0 + - libstdc++6 + - libvorbisfile3 + - libx11-6 + - libxxf86vm1 + - zlib1g + + files: + exclude: + - usr/share/man + - usr/share/doc/*/README.* + - usr/share/doc/*/changelog.* + - usr/share/doc/*/NEWS.* + - usr/share/doc/*/TODO.* + +AppImage: + update-information: None + sign-key: None + arch: x86_64 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f19b5cd --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,402 @@ +cmake_minimum_required(VERSION 3.5) + +# Set policies up to 3.9 since we want to enable the IPO option +if(${CMAKE_VERSION} VERSION_LESS 3.9) + cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +else() + cmake_policy(VERSION 3.9) +endif() + +# This can be read from ${PROJECT_NAME} after project() is called +project(minetest) +set(PROJECT_NAME_CAPITALIZED "Minetest") + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED TRUE) +set(GCC_MINIMUM_VERSION "5.1") +set(CLANG_MINIMUM_VERSION "3.5") + +# Also remember to set PROTOCOL_VERSION in network/networkprotocol.h when releasing +set(VERSION_MAJOR 5) +set(VERSION_MINOR 6) +set(VERSION_PATCH 1) +set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string") + +# Change to false for releases +set(DEVELOPMENT_BUILD FALSE) + +set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") +if(VERSION_EXTRA) + set(VERSION_STRING "${VERSION_STRING}-${VERSION_EXTRA}") +elseif(DEVELOPMENT_BUILD) + set(VERSION_STRING "${VERSION_STRING}-dev") +endif() + +if (CMAKE_BUILD_TYPE STREQUAL Debug) + # Append "-debug" to version string + set(VERSION_STRING "${VERSION_STRING}-debug") +endif() + +message(STATUS "*** Will build version ${VERSION_STRING} ***") + + +# Configuration options +set(DEFAULT_RUN_IN_PLACE FALSE) +if(WIN32) + set(DEFAULT_RUN_IN_PLACE TRUE) +endif() +set(RUN_IN_PLACE ${DEFAULT_RUN_IN_PLACE} CACHE BOOL + "Run directly in source directory structure") + + +set(BUILD_CLIENT TRUE CACHE BOOL "Build client") +set(BUILD_SERVER FALSE CACHE BOOL "Build server") +set(BUILD_UNITTESTS TRUE CACHE BOOL "Build unittests") +set(BUILD_BENCHMARKS FALSE CACHE BOOL "Build benchmarks") + +set(WARN_ALL TRUE CACHE BOOL "Enable -Wall for Release build") + +if(NOT CMAKE_BUILD_TYPE) + # Default to release + set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type: Debug or Release" FORCE) +endif() + +set(ENABLE_UPDATE_CHECKER (NOT ${DEVELOPMENT_BUILD}) CACHE BOOL + "Whether to enable update checks by default") + +# Included stuff +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") + + +set(IRRLICHTMT_BUILD_DIR "" CACHE PATH "Path to IrrlichtMt build directory.") +if(NOT "${IRRLICHTMT_BUILD_DIR}" STREQUAL "") + find_package(IrrlichtMt QUIET + PATHS "${IRRLICHTMT_BUILD_DIR}" + NO_DEFAULT_PATH + ) + + if(NOT TARGET IrrlichtMt::IrrlichtMt) + # find_package() searches certain subdirectories. ${PATH}/cmake is not + # the only one, but it is the one where IrrlichtMt is supposed to export + # IrrlichtMtConfig.cmake + message(FATAL_ERROR "Could not find IrrlichtMtConfig.cmake in ${IRRLICHTMT_BUILD_DIR}/cmake.") + endif() +elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib/irrlichtmt") + message(STATUS "Using user-provided IrrlichtMt at subdirectory 'lib/irrlichtmt'") + if(BUILD_CLIENT) + # tell IrrlichtMt to create a static library + set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared library" FORCE) + add_subdirectory(lib/irrlichtmt EXCLUDE_FROM_ALL) + unset(BUILD_SHARED_LIBS CACHE) + + if(NOT TARGET IrrlichtMt) + message(FATAL_ERROR "IrrlichtMt project is missing a CMake target?!") + endif() + else() + add_library(IrrlichtMt::IrrlichtMt INTERFACE IMPORTED) + set_target_properties(IrrlichtMt::IrrlichtMt PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/irrlichtmt/include") + endif() +else() + find_package(IrrlichtMt QUIET) + if(NOT TARGET IrrlichtMt::IrrlichtMt) + string(CONCAT explanation_msg + "The Minetest team has forked Irrlicht to make their own customizations. " + "It can be found here: https://github.com/minetest/irrlicht\n" + "For example use: git clone --depth=1 https://github.com/minetest/irrlicht lib/irrlichtmt\n") + if(BUILD_CLIENT) + message(FATAL_ERROR "IrrlichtMt is required to build the client, but it was not found.\n${explanation_msg}") + endif() + + include(MinetestFindIrrlichtHeaders) + if(NOT IRRLICHT_INCLUDE_DIR) + message(FATAL_ERROR "IrrlichtMt headers are required to build the server, but none found.\n${explanation_msg}") + endif() + message(STATUS "Found IrrlichtMt headers: ${IRRLICHT_INCLUDE_DIR}") + add_library(IrrlichtMt::IrrlichtMt INTERFACE IMPORTED) + # Note that we can't use target_include_directories() since that doesn't work for IMPORTED targets before CMake 3.11 + set_target_properties(IrrlichtMt::IrrlichtMt PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${IRRLICHT_INCLUDE_DIR}") + endif() +endif() + +if(BUILD_CLIENT AND TARGET IrrlichtMt::IrrlichtMt) + # retrieve version somehow + if(NOT IrrlichtMt_VERSION) + get_target_property(IrrlichtMt_VERSION IrrlichtMt VERSION) + endif() + message(STATUS "Found IrrlichtMt ${IrrlichtMt_VERSION}") + + set(TARGET_VER_S 1.9.0mt8) + string(REPLACE "mt" "." TARGET_VER ${TARGET_VER_S}) + if(IrrlichtMt_VERSION VERSION_LESS ${TARGET_VER}) + message(FATAL_ERROR "At least IrrlichtMt ${TARGET_VER_S} is required to build") + elseif(NOT DEVELOPMENT_BUILD AND IrrlichtMt_VERSION VERSION_GREATER ${TARGET_VER}) + message(FATAL_ERROR "IrrlichtMt ${TARGET_VER_S} is required to build") + endif() +endif() + + +# Installation + +if(WIN32) + set(SHAREDIR ".") + set(BINDIR "bin") + set(DOCDIR "doc") + set(EXAMPLE_CONF_DIR ".") + set(LOCALEDIR "locale") +elseif(APPLE) + set(BUNDLE_NAME ${PROJECT_NAME}.app) + set(BUNDLE_PATH "${BUNDLE_NAME}") + set(BINDIR ${BUNDLE_NAME}/Contents/MacOS) + set(SHAREDIR ${BUNDLE_NAME}/Contents/Resources) + set(DOCDIR "${SHAREDIR}/${PROJECT_NAME}") + set(EXAMPLE_CONF_DIR ${DOCDIR}) + set(LOCALEDIR "${SHAREDIR}/locale") +elseif(UNIX) # Linux, BSD etc + if(RUN_IN_PLACE) + set(SHAREDIR ".") + set(BINDIR "bin") + set(DOCDIR "doc") + set(EXAMPLE_CONF_DIR ".") + set(MANDIR "unix/man") + set(XDG_APPS_DIR "unix/applications") + set(APPDATADIR "unix/metainfo") + set(ICONDIR "unix/icons") + set(LOCALEDIR "locale") + else() + include(GNUInstallDirs) + set(SHAREDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}") + set(BINDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}") + set(DOCDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DOCDIR}") + set(MANDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_MANDIR}") + set(EXAMPLE_CONF_DIR ${DOCDIR}) + set(XDG_APPS_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/applications") + set(APPDATADIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/metainfo") + set(ICONDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/icons") + set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}") + endif() +endif() + +set(CUSTOM_SHAREDIR "" CACHE STRING "Directory to install data files into") +if(NOT CUSTOM_SHAREDIR STREQUAL "") + set(SHAREDIR "${CUSTOM_SHAREDIR}") + message(STATUS "Using SHAREDIR=${SHAREDIR}") +endif() + +set(CUSTOM_BINDIR "" CACHE STRING "Directory to install binaries into") +if(NOT CUSTOM_BINDIR STREQUAL "") + set(BINDIR "${CUSTOM_BINDIR}") + message(STATUS "Using BINDIR=${BINDIR}") +endif() + +set(CUSTOM_DOCDIR "" CACHE STRING "Directory to install documentation into") +if(NOT CUSTOM_DOCDIR STREQUAL "") + set(DOCDIR "${CUSTOM_DOCDIR}") + if(NOT RUN_IN_PLACE) + set(EXAMPLE_CONF_DIR ${DOCDIR}) + endif() + message(STATUS "Using DOCDIR=${DOCDIR}") +endif() + +set(CUSTOM_MANDIR "" CACHE STRING "Directory to install manpages into") +if(NOT CUSTOM_MANDIR STREQUAL "") + set(MANDIR "${CUSTOM_MANDIR}") + message(STATUS "Using MANDIR=${MANDIR}") +endif() + +set(CUSTOM_EXAMPLE_CONF_DIR "" CACHE STRING "Directory to install example config file into") +if(NOT CUSTOM_EXAMPLE_CONF_DIR STREQUAL "") + set(EXAMPLE_CONF_DIR "${CUSTOM_EXAMPLE_CONF_DIR}") + message(STATUS "Using EXAMPLE_CONF_DIR=${EXAMPLE_CONF_DIR}") +endif() + +set(CUSTOM_XDG_APPS_DIR "" CACHE STRING "Directory to install .desktop files into") +if(NOT CUSTOM_XDG_APPS_DIR STREQUAL "") + set(XDG_APPS_DIR "${CUSTOM_XDG_APPS_DIR}") + message(STATUS "Using XDG_APPS_DIR=${XDG_APPS_DIR}") +endif() + +set(CUSTOM_ICONDIR "" CACHE STRING "Directory to install icons into") +if(NOT CUSTOM_ICONDIR STREQUAL "") + set(ICONDIR "${CUSTOM_ICONDIR}") + message(STATUS "Using ICONDIR=${ICONDIR}") +endif() + +set(CUSTOM_LOCALEDIR "" CACHE STRING "Directory to install l10n files into") +if(NOT CUSTOM_LOCALEDIR STREQUAL "") + set(LOCALEDIR "${CUSTOM_LOCALEDIR}") + message(STATUS "Using LOCALEDIR=${LOCALEDIR}") +endif() + + +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/builtin" DESTINATION "${SHAREDIR}") +if(RUN_IN_PLACE) + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/mods/mods_here.txt" DESTINATION "${SHAREDIR}/mods") + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/textures/texture_packs_here.txt" DESTINATION "${SHAREDIR}/textures") +endif() + +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest_game" DESTINATION "${SHAREDIR}/games/" + COMPONENT "SUBGAME_MINETEST_GAME" OPTIONAL PATTERN ".git*" EXCLUDE ) +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/devtest" DESTINATION "${SHAREDIR}/games/" + COMPONENT "SUBGAME_MINIMAL" OPTIONAL PATTERN ".git*" EXCLUDE ) + +if(BUILD_CLIENT) + install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client/shaders" DESTINATION "${SHAREDIR}/client") + install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/textures/base/pack" DESTINATION "${SHAREDIR}/textures/base") + if(RUN_IN_PLACE) + install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/clientmods" DESTINATION "${SHAREDIR}") + install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client/serverlist" DESTINATION "${SHAREDIR}/client") + endif() +endif() + +install(FILES "README.md" DESTINATION "${DOCDIR}" COMPONENT "Docs") +install(FILES "doc/lua_api.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs") +install(FILES "doc/client_lua_api.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs") +install(FILES "doc/menu_lua_api.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs") +install(FILES "doc/texture_packs.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs") +install(FILES "doc/world_format.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs") +install(FILES "minetest.conf.example" DESTINATION "${EXAMPLE_CONF_DIR}") + +if(UNIX AND NOT APPLE) + install(FILES "doc/minetest.6" "doc/minetestserver.6" DESTINATION "${MANDIR}/man6") + install(FILES "misc/net.minetest.minetest.desktop" DESTINATION "${XDG_APPS_DIR}") + install(FILES "misc/net.minetest.minetest.appdata.xml" DESTINATION "${APPDATADIR}") + install(FILES "misc/minetest.svg" DESTINATION "${ICONDIR}/hicolor/scalable/apps") + install(FILES "misc/minetest-xorg-icon-128.png" + DESTINATION "${ICONDIR}/hicolor/128x128/apps" + RENAME "minetest.png") +endif() + +if(APPLE) + install(FILES "misc/minetest-icon.icns" DESTINATION "${SHAREDIR}") + install(FILES "misc/Info.plist" DESTINATION "${BUNDLE_PATH}/Contents") +endif() + +# Library pack +find_package(GMP REQUIRED) +find_package(Json REQUIRED) +find_package(Lua REQUIRED) +if(NOT USE_LUAJIT) + set(LUA_BIT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/bitop) + set(LUA_BIT_LIBRARY bitop) + add_subdirectory(lib/bitop) +endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${GCC_MINIMUM_VERSION}") + message(FATAL_ERROR "Insufficient gcc version, found ${CMAKE_CXX_COMPILER_VERSION}. " + "Version ${GCC_MINIMUM_VERSION} or higher is required.") + endif() +elseif(CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${CLANG_MINIMUM_VERSION}") + message(FATAL_ERROR "Insufficient clang version, found ${CMAKE_CXX_COMPILER_VERSION}. " + "Version ${CLANG_MINIMUM_VERSION} or higher is required.") + endif() +endif() + +if(BUILD_BENCHMARKS) + add_subdirectory(lib/catch2) +endif() + +# Subdirectories +# Be sure to add all relevant definitions above this +add_subdirectory(src) + + +# CPack + +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A free open-source voxel game engine with easy modding and game creation.") +set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH}) +set(CPACK_PACKAGE_VENDOR "celeron55") +set(CPACK_PACKAGE_CONTACT "Perttu Ahola ") + +include(CPackComponent) + +cpack_add_component(Docs + DISPLAY_NAME "Documentation" + DESCRIPTION "Documentation about Minetest and Minetest modding" +) + +cpack_add_component(SUBGAME_MINETEST_GAME + DISPLAY_NAME "Minetest Game" + DESCRIPTION "The default game bundled in the Minetest engine. Mainly used as a modding base." + GROUP "Games" +) + +cpack_add_component(SUBGAME_MINIMAL + DISPLAY_NAME "Development Test" + DESCRIPTION "A basic testing environment used for engine development and sometimes for testing mods." + DISABLED #DISABLED does not mean it is disabled, and is just not selected by default. + GROUP "Games" +) + +cpack_add_component_group(Subgames + DESCRIPTION "Games for the Minetest engine." +) + +if(WIN32) + # Include all dynamically linked runtime libaries such as MSVCRxxx.dll + include(InstallRequiredSystemLibraries) + + if(RUN_IN_PLACE) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win64") + else() + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win32") + endif() + + set(CPACK_GENERATOR ZIP) + + else() + set(CPACK_GENERATOR WIX) + set(CPACK_PACKAGE_NAME "${PROJECT_NAME_CAPITALIZED}") + set(CPACK_PACKAGE_INSTALL_DIRECTORY ".") + set(CPACK_PACKAGE_EXECUTABLES ${PROJECT_NAME} "${PROJECT_NAME_CAPITALIZED}") + set(CPACK_CREATE_DESKTOP_LINKS ${PROJECT_NAME}) + set(CPACK_PACKAGING_INSTALL_PREFIX "/${PROJECT_NAME_CAPITALIZED}") + + set(CPACK_WIX_PRODUCT_ICON "${CMAKE_CURRENT_SOURCE_DIR}/misc/minetest-icon.ico") + # Supported languages can be found at + # http://wixtoolset.org/documentation/manual/v3/wixui/wixui_localization.html + #set(CPACK_WIX_CULTURES "ar-SA,bg-BG,ca-ES,hr-HR,cs-CZ,da-DK,nl-NL,en-US,et-EE,fi-FI,fr-FR,de-DE") + set(CPACK_WIX_UI_BANNER "${CMAKE_CURRENT_SOURCE_DIR}/misc/CPACK_WIX_UI_BANNER.BMP") + set(CPACK_WIX_UI_DIALOG "${CMAKE_CURRENT_SOURCE_DIR}/misc/CPACK_WIX_UI_DIALOG.BMP") + + set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/doc/lgpl-2.1.txt") + + # The correct way would be to include both x32 and x64 into one installer + # and install the appropriate one. + # CMake does not support that, so there are two separate GUID's + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(CPACK_WIX_UPGRADE_GUID "745A0FB3-5552-44CA-A587-A91C397CCC56") + else() + set(CPACK_WIX_UPGRADE_GUID "814A2E2D-2779-4BBD-9ACD-FC3BD51FBBA2") + endif() + endif() +elseif(APPLE) + set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0) + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-osx") + set(CPACK_GENERATOR ZIP) +else() + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-linux") + set(CPACK_GENERATOR TGZ) + set(CPACK_SOURCE_GENERATOR TGZ) +endif() + +include(CPack) + + +# Add a target to generate API documentation with Doxygen +find_package(Doxygen) +if(DOXYGEN_FOUND) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in + ${CMAKE_CURRENT_BINARY_DIR}/doc/Doxyfile @ONLY) + add_custom_target(doc + ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doc/Doxyfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc + COMMENT "Generating API documentation with Doxygen" VERBATIM + ) +endif() diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3dd82e7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,71 @@ +ARG DOCKER_IMAGE=alpine:3.14 +FROM $DOCKER_IMAGE AS builder + +ENV MINETEST_GAME_VERSION master +ENV IRRLICHT_VERSION master + +COPY .git /usr/src/minetest/.git +COPY CMakeLists.txt /usr/src/minetest/CMakeLists.txt +COPY README.md /usr/src/minetest/README.md +COPY minetest.conf.example /usr/src/minetest/minetest.conf.example +COPY builtin /usr/src/minetest/builtin +COPY cmake /usr/src/minetest/cmake +COPY doc /usr/src/minetest/doc +COPY fonts /usr/src/minetest/fonts +COPY lib /usr/src/minetest/lib +COPY misc /usr/src/minetest/misc +COPY po /usr/src/minetest/po +COPY src /usr/src/minetest/src +COPY textures /usr/src/minetest/textures + +WORKDIR /usr/src/minetest + +RUN apk add --no-cache git build-base cmake sqlite-dev curl-dev zlib-dev zstd-dev \ + gmp-dev jsoncpp-dev postgresql-dev ninja luajit-dev ca-certificates && \ + git clone --depth=1 -b ${MINETEST_GAME_VERSION} https://github.com/minetest/minetest_game.git ./games/minetest_game && \ + rm -fr ./games/minetest_game/.git + +WORKDIR /usr/src/ +RUN git clone --recursive https://github.com/jupp0r/prometheus-cpp/ && \ + cd prometheus-cpp && \ + cmake -B build \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_BUILD_TYPE=Release \ + -DENABLE_TESTING=0 \ + -GNinja && \ + cmake --build build && \ + cmake --install build + +RUN git clone --depth=1 https://github.com/minetest/irrlicht/ -b ${IRRLICHT_VERSION} && \ + cp -r irrlicht/include /usr/include/irrlichtmt + +WORKDIR /usr/src/minetest +RUN cmake -B build \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SERVER=TRUE \ + -DENABLE_PROMETHEUS=TRUE \ + -DBUILD_UNITTESTS=FALSE \ + -DBUILD_CLIENT=FALSE \ + -GNinja && \ + cmake --build build && \ + cmake --install build + +ARG DOCKER_IMAGE=alpine:3.14 +FROM $DOCKER_IMAGE AS runtime + +RUN apk add --no-cache sqlite-libs curl gmp libstdc++ libgcc libpq luajit jsoncpp zstd-libs && \ + adduser -D minetest --uid 30000 -h /var/lib/minetest && \ + chown -R minetest:minetest /var/lib/minetest + +WORKDIR /var/lib/minetest + +COPY --from=builder /usr/local/share/minetest /usr/local/share/minetest +COPY --from=builder /usr/local/bin/minetestserver /usr/local/bin/minetestserver +COPY --from=builder /usr/local/share/doc/minetest/minetest.conf.example /etc/minetest/minetest.conf + +USER minetest:minetest + +EXPOSE 30000/udp 30000/tcp + +CMD ["/usr/local/bin/minetestserver", "--config", "/etc/minetest/minetest.conf"] diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..1f2c6c3 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,206 @@ + +License of Minetest textures and sounds +--------------------------------------- + +This applies to textures and sounds contained in the main Minetest +distribution. + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +http://creativecommons.org/licenses/by-sa/3.0/ + +textures/base/pack/refresh.png is under the Apache 2 license +https://www.apache.org/licenses/LICENSE-2.0.html + +Textures by Zughy are under CC BY-SA 4.0 +https://creativecommons.org/licenses/by-sa/4.0/ + +textures/base/pack/server_public.png is under CC-BY 4.0, taken from Twitter's Twemoji set +https://creativecommons.org/licenses/by/4.0/ + +Authors of media files +----------------------- +Everything not listed in here: +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +ShadowNinja: + textures/base/pack/smoke_puff.png + +paramat: + textures/base/pack/menu_header.png + textures/base/pack/next_icon.png + textures/base/pack/prev_icon.png + textures/base/pack/clear.png + textures/base/pack/search.png + +rubenwardy, paramat: + textures/base/pack/start_icon.png + textures/base/pack/end_icon.png + +erlehmann: + misc/minetest-icon-24x24.png + misc/minetest-icon.ico + misc/minetest.svg + textures/base/pack/logo.png + +JRottm: + textures/base/pack/player_marker.png + +srifqi: + textures/base/pack/chat_hide_btn.png + textures/base/pack/chat_show_btn.png + textures/base/pack/joystick_bg.png + textures/base/pack/joystick_center.png + textures/base/pack/joystick_off.png + textures/base/pack/minimap_btn.png + +Zughy: + textures/base/pack/cdb_add.png + textures/base/pack/cdb_clear.png + textures/base/pack/cdb_downloading.png + textures/base/pack/cdb_queued.png + textures/base/pack/cdb_update.png + textures/base/pack/cdb_viewonline.png + +appgurueu: + textures/base/pack/server_incompatible.png + +erlehmann, Warr1024, rollerozxa: + textures/base/pack/no_screenshot.png + +kilbith: + textures/base/pack/server_favorite.png + +SmallJoker + textures/base/pack/server_favorite_delete.png (based on server_favorite.png) + +License of Minetest source code +------------------------------- + +Minetest +Copyright (C) 2010-2018 celeron55, Perttu Ahola + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Irrlicht +--------------- + +This program uses IrrlichtMt, Minetest's fork of +the Irrlicht Engine. http://irrlicht.sourceforge.net/ + + The Irrlicht Engine License + +Copyright © 2002-2005 Nikolaus Gebhardt + +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. + + +JThread +--------------- + +This program uses the JThread library. License for JThread follows: + +Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com) + +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. + +Lua +--------------- + +Lua is licensed under the terms of the MIT license reproduced below. +This means that Lua is free software and can be used for both academic +and commercial purposes at absolutely no cost. + +For details and rationale, see https://www.lua.org/license.html . + +Copyright (C) 1994-2008 Lua.org, PUC-Rio. + +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. + +Fonts +--------------- + +Bitstream Vera Fonts Copyright: + + Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is + a trademark of Bitstream, Inc. + +Arimo - Apache License, version 2.0 + Digitized data copyright (c) 2010-2012 Google Corporation. + +Cousine - Apache License, version 2.0 + Digitized data copyright (c) 2010-2012 Google Corporation. + +DroidSansFallBackFull: + + Copyright (C) 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. + 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/Minetest_MSVC_Win32_libraries_compiled_170104.7z b/Minetest_MSVC_Win32_libraries_compiled_170104.7z new file mode 100644 index 0000000..9d4c1d5 Binary files /dev/null and b/Minetest_MSVC_Win32_libraries_compiled_170104.7z differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..0bc5d4b --- /dev/null +++ b/README.md @@ -0,0 +1,480 @@ +Minetest +======== + +![Build Status](https://github.com/minetest/minetest/workflows/build/badge.svg) +[![Translation status](https://hosted.weblate.org/widgets/minetest/-/svg-badge.svg)](https://hosted.weblate.org/engage/minetest/?utm_source=widget) +[![License](https://img.shields.io/badge/license-LGPLv2.1%2B-blue.svg)](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html) + +Minetest is a free open-source voxel game engine with easy modding and game creation. + +Copyright (C) 2010-2022 Perttu Ahola +and contributors (see source file comments and the version control log) + +In case you downloaded the source code +-------------------------------------- +If you downloaded the Minetest Engine source code in which this file is +contained, you probably want to download the [Minetest Game](https://github.com/minetest/minetest_game/) +project too. See its README.txt for more information. + +Table of Contents +------------------ + +1. [Further Documentation](#further-documentation) +2. [Default Controls](#default-controls) +3. [Paths](#paths) +4. [Configuration File](#configuration-file) +5. [Command-line Options](#command-line-options) +6. [Compiling](#compiling) +7. [Docker](#docker) +8. [Version Scheme](#version-scheme) + + +Further documentation +---------------------- +- Website: https://minetest.net/ +- Wiki: https://wiki.minetest.net/ +- Developer wiki: https://dev.minetest.net/ +- Forum: https://forum.minetest.net/ +- GitHub: https://github.com/minetest/minetest/ +- [doc/](doc/) directory of source distribution + +Default controls +---------------- +All controls are re-bindable using settings. +Some can be changed in the key config dialog in the settings tab. + +| Button | Action | +|-------------------------------|----------------------------------------------------------------| +| Move mouse | Look around | +| W, A, S, D | Move | +| Space | Jump/move up | +| Shift | Sneak/move down | +| Q | Drop itemstack | +| Shift + Q | Drop single item | +| Left mouse button | Dig/punch/take item | +| Right mouse button | Place/use | +| Shift + right mouse button | Build (without using) | +| I | Inventory menu | +| Mouse wheel | Select item | +| 0-9 | Select item | +| Z | Zoom (needs zoom privilege) | +| T | Chat | +| / | Command | +| Esc | Pause menu/abort/exit (pauses only singleplayer game) | +| R | Enable/disable full range view | +| + | Increase view range | +| - | Decrease view range | +| K | Enable/disable fly mode (needs fly privilege) | +| P | Enable/disable pitch move mode | +| J | Enable/disable fast mode (needs fast privilege) | +| H | Enable/disable noclip mode (needs noclip privilege) | +| E | Aux1 (Move fast in fast mode. Games may add special features) | +| C | Cycle through camera modes | +| V | Cycle through minimap modes | +| Shift + V | Change minimap orientation | +| F1 | Hide/show HUD | +| F2 | Hide/show chat | +| F3 | Disable/enable fog | +| F4 | Disable/enable camera update (Mapblocks are not updated anymore when disabled, disabled in release builds) | +| F5 | Cycle through debug information screens | +| F6 | Cycle through profiler info screens | +| F10 | Show/hide console | +| F12 | Take screenshot | + +Paths +----- +Locations: + +* `bin` - Compiled binaries +* `share` - Distributed read-only data +* `user` - User-created modifiable data + +Where each location is on each platform: + +* Windows .zip / RUN_IN_PLACE source: + * `bin` = `bin` + * `share` = `.` + * `user` = `.` +* Windows installed: + * `bin` = `C:\Program Files\Minetest\bin (Depends on the install location)` + * `share` = `C:\Program Files\Minetest (Depends on the install location)` + * `user` = `%APPDATA%\Minetest` +* Linux installed: + * `bin` = `/usr/bin` + * `share` = `/usr/share/minetest` + * `user` = `~/.minetest` +* macOS: + * `bin` = `Contents/MacOS` + * `share` = `Contents/Resources` + * `user` = `Contents/User OR ~/Library/Application Support/minetest` + +Worlds can be found as separate folders in: `user/worlds/` + +Configuration file +------------------ +- Default location: + `user/minetest.conf` +- This file is created by closing Minetest for the first time. +- A specific file can be specified on the command line: + `--config ` +- A run-in-place build will look for the configuration file in + `location_of_exe/../minetest.conf` and also `location_of_exe/../../minetest.conf` + +Command-line options +-------------------- +- Use `--help` + +Compiling +--------- +### Compiling on GNU/Linux + +#### Dependencies + +| Dependency | Version | Commentary | +|------------|---------|------------| +| GCC | 5.1+ | or Clang 3.5+ | +| CMake | 3.5+ | | +| IrrlichtMt | - | Custom version of Irrlicht, see https://github.com/minetest/irrlicht | +| Freetype | 2.0+ | | +| SQLite3 | 3+ | | +| Zstd | 1.0+ | | +| LuaJIT | 2.0+ | Bundled Lua 5.1 is used if not present | +| GMP | 5.0.0+ | Bundled mini-GMP is used if not present | +| JsonCPP | 1.0.0+ | Bundled JsonCPP is used if not present | + +For Debian/Ubuntu users: + + sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libxi-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev libluajit-5.1-dev + +For Fedora users: + + sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libvorbis-devel libXi-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel libzstd-devel + +For Arch users: + + sudo pacman -S base-devel libcurl-gnutls cmake libxi libpng sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses zstd + +For Alpine users: + + sudo apk add build-base cmake libpng-dev jpeg-dev libxi-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev zstd-dev + +#### Download + +You can install Git for easily keeping your copy up to date. +If you don’t want Git, read below on how to get the source without Git. +This is an example for installing Git on Debian/Ubuntu: + + sudo apt install git + +For Fedora users: + + sudo dnf install git + +Download source (this is the URL to the latest of source repository, which might not work at all times) using Git: + + git clone --depth 1 https://github.com/minetest/minetest.git + cd minetest + +Download minetest_game (otherwise only the "Development Test" game is available) using Git: + + git clone --depth 1 https://github.com/minetest/minetest_game.git games/minetest_game + +Download IrrlichtMt to `lib/irrlichtmt`, it will be used to satisfy the IrrlichtMt dependency that way: + + git clone --depth 1 https://github.com/minetest/irrlicht.git lib/irrlichtmt + +Download source, without using Git: + + wget https://github.com/minetest/minetest/archive/master.tar.gz + tar xf master.tar.gz + cd minetest-master + +Download minetest_game, without using Git: + + cd games/ + wget https://github.com/minetest/minetest_game/archive/master.tar.gz + tar xf master.tar.gz + mv minetest_game-master minetest_game + cd .. + +Download IrrlichtMt, without using Git: + + cd lib/ + wget https://github.com/minetest/irrlicht/archive/master.tar.gz + tar xf master.tar.gz + mv irrlicht-master irrlichtmt + cd .. + +#### Build + +Build a version that runs directly from the source directory: + + cmake . -DRUN_IN_PLACE=TRUE + make -j$(nproc) + +Run it: + + ./bin/minetest + +- Use `cmake . -LH` to see all CMake options and their current state. +- If you want to install it system-wide (or are making a distribution package), + you will want to use `-DRUN_IN_PLACE=FALSE`. +- You can build a bare server by specifying `-DBUILD_SERVER=TRUE`. +- You can disable the client build by specifying `-DBUILD_CLIENT=FALSE`. +- You can select between Release and Debug build by `-DCMAKE_BUILD_TYPE=`. + - Debug build is slower, but gives much more useful output in a debugger. +- If you build a bare server you don't need to compile IrrlichtMt, just the headers suffice. + - In that case use `-DIRRLICHT_INCLUDE_DIR=/some/where/irrlichtmt/include`. + +- Minetest will use the IrrlichtMt package that is found first, given by the following order: + 1. Specified `IRRLICHTMT_BUILD_DIR` CMake variable + 2. `${PROJECT_SOURCE_DIR}/lib/irrlichtmt` (if existent) + 3. Installation of IrrlichtMt in the system-specific library paths + 4. For server builds with disabled `BUILD_CLIENT` variable, the headers from `IRRLICHT_INCLUDE_DIR` will be used. + - NOTE: Changing the IrrlichtMt build directory (includes system installs) requires regenerating the CMake cache (`rm CMakeCache.txt`) + +### CMake options + +General options and their default values: + + BUILD_CLIENT=TRUE - Build Minetest client + BUILD_SERVER=FALSE - Build Minetest server + BUILD_UNITTESTS=TRUE - Build unittest sources + BUILD_BENCHMARKS=FALSE - Build benchmark sources + CMAKE_BUILD_TYPE=Release - Type of build (Release vs. Debug) + Release - Release build + Debug - Debug build + SemiDebug - Partially optimized debug build + RelWithDebInfo - Release build with debug information + MinSizeRel - Release build with -Os passed to compiler to make executable as small as possible + ENABLE_CURL=ON - Build with cURL; Enables use of online mod repo, public serverlist and remote media fetching via http + ENABLE_CURSES=ON - Build with (n)curses; Enables a server side terminal (command line option: --terminal) + ENABLE_GETTEXT=ON - Build with Gettext; Allows using translations + ENABLE_GLES=OFF - Enable extra support code for OpenGL ES (requires support by IrrlichtMt) + ENABLE_LEVELDB=ON - Build with LevelDB; Enables use of LevelDB map backend + ENABLE_POSTGRESQL=ON - Build with libpq; Enables use of PostgreSQL map backend (PostgreSQL 9.5 or greater recommended) + ENABLE_REDIS=ON - Build with libhiredis; Enables use of Redis map backend + ENABLE_SPATIAL=ON - Build with LibSpatial; Speeds up AreaStores + ENABLE_SOUND=ON - Build with OpenAL, libogg & libvorbis; in-game sounds + ENABLE_LUAJIT=ON - Build with LuaJIT (much faster than non-JIT Lua) + ENABLE_PROMETHEUS=OFF - Build with Prometheus metrics exporter (listens on tcp/30000 by default) + ENABLE_SYSTEM_GMP=ON - Use GMP from system (much faster than bundled mini-gmp) + ENABLE_SYSTEM_JSONCPP=ON - Use JsonCPP from system + RUN_IN_PLACE=FALSE - Create a portable install (worlds, settings etc. in current directory) + ENABLE_UPDATE_CHECKER=TRUE - Whether to enable update checks by default + USE_GPROF=FALSE - Enable profiling using GProf + VERSION_EXTRA= - Text to append to version (e.g. VERSION_EXTRA=foobar -> Minetest 0.4.9-foobar) + ENABLE_TOUCH=FALSE - Enable Touchscreen support (requires support by IrrlichtMt) + +Library specific options: + + CURL_DLL - Only if building with cURL on Windows; path to libcurl.dll + CURL_INCLUDE_DIR - Only if building with cURL; directory where curl.h is located + CURL_LIBRARY - Only if building with cURL; path to libcurl.a/libcurl.so/libcurl.lib + EGL_INCLUDE_DIR - Only if building with GLES; directory that contains egl.h + EGL_LIBRARY - Only if building with GLES; path to libEGL.a/libEGL.so + EXTRA_DLL - Only on Windows; optional paths to additional DLLs that should be packaged + FREETYPE_INCLUDE_DIR_freetype2 - Directory that contains files such as ftimage.h + FREETYPE_INCLUDE_DIR_ft2build - Directory that contains ft2build.h + FREETYPE_LIBRARY - Path to libfreetype.a/libfreetype.so/freetype.lib + FREETYPE_DLL - Only on Windows; path to libfreetype-6.dll + GETTEXT_DLL - Only when building with gettext on Windows; paths to libintl + libiconv DLLs + GETTEXT_INCLUDE_DIR - Only when building with gettext; directory that contains iconv.h + GETTEXT_LIBRARY - Only when building with gettext on Windows; path to libintl.dll.a + GETTEXT_MSGFMT - Only when building with gettext; path to msgfmt/msgfmt.exe + IRRLICHT_DLL - Only on Windows; path to IrrlichtMt.dll + IRRLICHT_INCLUDE_DIR - Directory that contains IrrCompileConfig.h (usable for server build only) + LEVELDB_INCLUDE_DIR - Only when building with LevelDB; directory that contains db.h + LEVELDB_LIBRARY - Only when building with LevelDB; path to libleveldb.a/libleveldb.so/libleveldb.dll.a + LEVELDB_DLL - Only when building with LevelDB on Windows; path to libleveldb.dll + PostgreSQL_INCLUDE_DIR - Only when building with PostgreSQL; directory that contains libpq-fe.h + PostgreSQL_LIBRARY - Only when building with PostgreSQL; path to libpq.a/libpq.so/libpq.lib + REDIS_INCLUDE_DIR - Only when building with Redis; directory that contains hiredis.h + REDIS_LIBRARY - Only when building with Redis; path to libhiredis.a/libhiredis.so + SPATIAL_INCLUDE_DIR - Only when building with LibSpatial; directory that contains spatialindex/SpatialIndex.h + SPATIAL_LIBRARY - Only when building with LibSpatial; path to libspatialindex_c.so/spatialindex-32.lib + LUA_INCLUDE_DIR - Only if you want to use LuaJIT; directory where luajit.h is located + LUA_LIBRARY - Only if you want to use LuaJIT; path to libluajit.a/libluajit.so + OGG_DLL - Only if building with sound on Windows; path to libogg.dll + OGG_INCLUDE_DIR - Only if building with sound; directory that contains an ogg directory which contains ogg.h + OGG_LIBRARY - Only if building with sound; path to libogg.a/libogg.so/libogg.dll.a + OPENAL_DLL - Only if building with sound on Windows; path to OpenAL32.dll + OPENAL_INCLUDE_DIR - Only if building with sound; directory where al.h is located + OPENAL_LIBRARY - Only if building with sound; path to libopenal.a/libopenal.so/OpenAL32.lib + SQLITE3_INCLUDE_DIR - Directory that contains sqlite3.h + SQLITE3_LIBRARY - Path to libsqlite3.a/libsqlite3.so/sqlite3.lib + VORBISFILE_LIBRARY - Only if building with sound; path to libvorbisfile.a/libvorbisfile.so/libvorbisfile.dll.a + VORBIS_DLL - Only if building with sound on Windows; paths to vorbis DLLs + VORBIS_INCLUDE_DIR - Only if building with sound; directory that contains a directory vorbis with vorbisenc.h inside + VORBIS_LIBRARY - Only if building with sound; path to libvorbis.a/libvorbis.so/libvorbis.dll.a + ZLIB_DLL - Only on Windows; path to zlib1.dll + ZLIB_INCLUDE_DIR - Directory that contains zlib.h + ZLIB_LIBRARY - Path to libz.a/libz.so/zlib.lib + ZSTD_DLL - Only on Windows; path to libzstd.dll + ZSTD_INCLUDE_DIR - Directory that contains zstd.h + ZSTD_LIBRARY - Path to libzstd.a/libzstd.so/ztd.lib + +### Compiling on Windows using MSVC + +### Requirements + +- [Visual Studio 2015 or newer](https://visualstudio.microsoft.com) +- [CMake](https://cmake.org/download/) +- [vcpkg](https://github.com/Microsoft/vcpkg) +- [Git](https://git-scm.com/downloads) + +### Compiling and installing the dependencies + +It is highly recommended to use vcpkg as package manager. + +After you successfully built vcpkg you can easily install the required libraries: +```powershell +vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp opengl-registry --triplet x64-windows +``` + +- **Don't forget about IrrlichtMt.** The easiest way is to clone it to `lib/irrlichtmt` as described in the Linux section. +- `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store. +- `openal-soft`, `libvorbis` and `libogg` are optional, but required to use sound. +- `luajit` is optional, it replaces the integrated Lua interpreter with a faster just-in-time interpreter. +- `gmp` and `jsoncpp` are optional, otherwise the bundled versions will be compiled + +There are other optional libraries, but they are not tested if they can build and link correctly. + +Use `--triplet` to specify the target triplet, e.g. `x64-windows` or `x86-windows`. + +### Compile Minetest + +#### a) Using the vcpkg toolchain and CMake GUI +1. Start up the CMake GUI +2. Select **Browse Source...** and select DIR/minetest +3. Select **Browse Build...** and select DIR/minetest-build +4. Select **Configure** +5. Choose the right visual Studio version and target platform. It has to match the version of the installed dependencies +6. Choose **Specify toolchain file for cross-compiling** +7. Click **Next** +8. Select the vcpkg toolchain file e.g. `D:/vcpkg/scripts/buildsystems/vcpkg.cmake` +9. Click Finish +10. Wait until cmake have generated the cash file +11. If there are any errors, solve them and hit **Configure** +12. Click **Generate** +13. Click **Open Project** +14. Compile Minetest inside Visual studio. + +#### b) Using the vcpkg toolchain and the commandline + +Run the following script in PowerShell: + +```powershell +cmake . -G"Visual Studio 15 2017 Win64" -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GETTEXT=OFF -DENABLE_CURSES=OFF +cmake --build . --config Release +``` +Make sure that the right compiler is selected and the path to the vcpkg toolchain is correct. + +### Windows Installer using WiX Toolset + +Requirements: +* [Visual Studio 2017](https://visualstudio.microsoft.com/) +* [WiX Toolset](https://wixtoolset.org/) + +In the Visual Studio 2017 Installer select **Optional Features -> WiX Toolset**. + +Build the binaries as described above, but make sure you unselect `RUN_IN_PLACE`. + +Open the generated project file with Visual Studio. Right-click **Package** and choose **Generate**. +It may take some minutes to generate the installer. + +### Compiling on MacOS + +#### Requirements +- [Homebrew](https://brew.sh/) +- [Git](https://git-scm.com/downloads) + +Install dependencies with homebrew: + +``` +brew install cmake freetype gettext gmp hiredis jpeg jsoncpp leveldb libogg libpng libvorbis luajit zstd +``` + +#### Download + +Download source (this is the URL to the latest of source repository, which might not work at all times) using Git: + +```bash +git clone --depth 1 https://github.com/minetest/minetest.git +cd minetest +``` + +Download minetest_game (otherwise only the "Development Test" game is available) using Git: + +``` +git clone --depth 1 https://github.com/minetest/minetest_game.git games/minetest_game +``` + +Download Minetest's fork of Irrlicht: + +``` +git clone --depth 1 https://github.com/minetest/irrlicht.git lib/irrlichtmt +``` + +#### Build + +```bash +mkdir build +cd build + +cmake .. \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=10.14 \ + -DCMAKE_FIND_FRAMEWORK=LAST \ + -DCMAKE_INSTALL_PREFIX=../build/macos/ \ + -DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE + +make -j$(sysctl -n hw.logicalcpu) +make install +``` + +#### Run + +``` +open ./build/macos/minetest.app +``` + +Docker +------ +We provide Minetest server Docker images using the GitLab mirror registry. + +Images are built on each commit and available using the following tag scheme: + +* `registry.gitlab.com/minetest/minetest/server:latest` (latest build) +* `registry.gitlab.com/minetest/minetest/server:` (current branch or current tag) +* `registry.gitlab.com/minetest/minetest/server:` (current commit id) + +If you want to test it on a Docker server you can easily run: + + sudo docker run registry.gitlab.com/minetest/minetest/server: + +If you want to use it in a production environment you should use volumes bound to the Docker host +to persist data and modify the configuration: + + sudo docker create -v /home/minetest/data/:/var/lib/minetest/ -v /home/minetest/conf/:/etc/minetest/ registry.gitlab.com/minetest/minetest/server:master + +Data will be written to `/home/minetest/data` on the host, and configuration will be read from `/home/minetest/conf/minetest.conf`. + +**Note:** If you don't understand the previous commands please read the official Docker documentation before use. + +You can also host your Minetest server inside a Kubernetes cluster. See our example implementation in [`misc/kubernetes.yml`](misc/kubernetes.yml). + + +Version scheme +-------------- +We use `major.minor.patch` since 5.0.0-dev. Prior to that we used `0.major.minor`. + +- Major is incremented when the release contains breaking changes, all other +numbers are set to 0. +- Minor is incremented when the release contains new non-breaking features, +patch is set to 0. +- Patch is incremented when the release only contains bugfixes and very +minor/trivial features considered necessary. + +Since 5.0.0-dev and 0.4.17-dev, the dev notation refers to the next release, +i.e.: 5.0.0-dev is the development version leading to 5.0.0. +Prior to that we used `previous_version-dev`. diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..e0613f8 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,11 @@ +*.iml +.externalNativeBuild +.gradle +app/build +app/release +app/src/main/assets +build +local.properties +native/.* +native/build +native/deps diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..ce895ed --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,116 @@ +apply plugin: 'com.android.application' +android { + compileSdkVersion 30 + buildToolsVersion '30.0.3' + ndkVersion "$ndk_version" + defaultConfig { + applicationId 'net.minetest.minetest' + minSdkVersion 16 + targetSdkVersion 30 + versionName "${versionMajor}.${versionMinor}.${versionPatch}" + versionCode project.versionCode + } + + // load properties + Properties props = new Properties() + def propfile = file('../local.properties') + if (propfile.exists()) + props.load(new FileInputStream(propfile)) + + if (props.getProperty('keystore') != null) { + signingConfigs { + release { + storeFile file(props['keystore']) + storePassword props['keystore.password'] + keyAlias props['key'] + keyPassword props['key.password'] + } + } + + buildTypes { + release { + minifyEnabled true + signingConfig signingConfigs.release + } + } + } + + // for multiple APKs + splits { + abi { + enable true + reset() + include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +task prepareAssets() { + def assetsFolder = "build/assets" + def projRoot = "../.." + def gameToCopy = "minetest_game" + + copy { + from "${projRoot}/minetest.conf.example", "${projRoot}/README.md" into assetsFolder + } + copy { + from "${projRoot}/doc/lgpl-2.1.txt" into "${assetsFolder}" + } + copy { + from "${projRoot}/builtin" into "${assetsFolder}/builtin" + } + copy { + from "${projRoot}/client/shaders" into "${assetsFolder}/client/shaders" + } + copy { + from "../native/deps/armeabi-v7a/Irrlicht/Shaders" into "${assetsFolder}/client/shaders/Irrlicht" + } + copy { + from "${projRoot}/fonts" include "*.ttf" into "${assetsFolder}/fonts" + } + copy { + from "${projRoot}/games/${gameToCopy}" into "${assetsFolder}/games/${gameToCopy}" + } + fileTree("${projRoot}/po").include("**/*.po").forEach { poFile -> + def moPath = "${assetsFolder}/locale/${poFile.parentFile.name}/LC_MESSAGES/" + file(moPath).mkdirs() + exec { + commandLine 'msgfmt', '-o', "${moPath}/minetest.mo", poFile + } + } + copy { + from "${projRoot}/textures" into "${assetsFolder}/textures" + } + + file("${assetsFolder}/.nomedia").text = ""; + + task zipAssets(type: Zip) { + archiveName "Minetest.zip" + from "${assetsFolder}" + destinationDir file("src/main/assets") + } +} + +preBuild.dependsOn zipAssets + +// Map for the version code that gives each ABI a value. +import com.android.build.OutputFile + +def abiCodes = ['armeabi-v7a': 0, 'arm64-v8a': 1] +android.applicationVariants.all { variant -> + variant.outputs.each { + output -> + def abiName = output.getFilter(OutputFile.ABI) + output.versionCodeOverride = abiCodes.get(abiName, 0) + variant.versionCode + } +} + +dependencies { + implementation project(':native') + implementation 'androidx.appcompat:appcompat:1.3.1' +} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..11c8686 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/java/net/minetest/minetest/CustomEditText.java b/android/app/src/main/java/net/minetest/minetest/CustomEditText.java new file mode 100644 index 0000000..8d0a503 --- /dev/null +++ b/android/app/src/main/java/net/minetest/minetest/CustomEditText.java @@ -0,0 +1,45 @@ +/* +Minetest +Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2020 ubulem, Bektur Mambetov + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.minetest.minetest; + +import android.content.Context; +import android.view.KeyEvent; +import android.view.inputmethod.InputMethodManager; + +import androidx.appcompat.widget.AppCompatEditText; + +import java.util.Objects; + +public class CustomEditText extends AppCompatEditText { + public CustomEditText(Context context) { + super(context); + } + + @Override + public boolean onKeyPreIme(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + InputMethodManager mgr = (InputMethodManager) + getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + Objects.requireNonNull(mgr).hideSoftInputFromWindow(this.getWindowToken(), 0); + } + return false; + } +} diff --git a/android/app/src/main/java/net/minetest/minetest/GameActivity.java b/android/app/src/main/java/net/minetest/minetest/GameActivity.java new file mode 100644 index 0000000..f5e9fd6 --- /dev/null +++ b/android/app/src/main/java/net/minetest/minetest/GameActivity.java @@ -0,0 +1,207 @@ +/* +Minetest +Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2020 ubulem, Bektur Mambetov + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.minetest.minetest; + +import android.app.NativeActivity; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.text.InputType; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; + +import androidx.annotation.Keep; +import androidx.appcompat.app.AlertDialog; +import androidx.core.content.FileProvider; + +import java.io.File; +import java.util.Objects; + +// Native code finds these methods by name (see porting_android.cpp). +// This annotation prevents the minifier/Proguard from mangling them. +@Keep +public class GameActivity extends NativeActivity { + static { + System.loadLibrary("c++_shared"); + System.loadLibrary("Minetest"); + } + + private int messageReturnCode = -1; + private String messageReturnValue = ""; + + public static native void putMessageBoxResult(String text); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + + private void makeFullScreen() { + if (Build.VERSION.SDK_INT >= 19) + this.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + } + + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if (hasFocus) + makeFullScreen(); + } + + @Override + protected void onResume() { + super.onResume(); + makeFullScreen(); + } + + @Override + public void onBackPressed() { + // Ignore the back press so Minetest can handle it + } + + public void showDialog(String acceptButton, String hint, String current, int editType) { + runOnUiThread(() -> showDialogUI(hint, current, editType)); + } + + private void showDialogUI(String hint, String current, int editType) { + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + LinearLayout container = new LinearLayout(this); + container.setOrientation(LinearLayout.VERTICAL); + builder.setView(container); + AlertDialog alertDialog = builder.create(); + EditText editText; + // For multi-line, do not close the dialog after pressing back button + if (editType == 1) { + editText = new EditText(this); + } else { + editText = new CustomEditText(this); + } + container.addView(editText); + editText.setMaxLines(8); + editText.requestFocus(); + editText.setHint(hint); + editText.setText(current); + final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); + Objects.requireNonNull(imm).toggleSoftInput(InputMethodManager.SHOW_FORCED, + InputMethodManager.HIDE_IMPLICIT_ONLY); + if (editType == 1) + editText.setInputType(InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_FLAG_MULTI_LINE); + else if (editType == 3) + editText.setInputType(InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_PASSWORD); + else + editText.setInputType(InputType.TYPE_CLASS_TEXT); + editText.setSelection(editText.getText().length()); + editText.setOnKeyListener((view, keyCode, event) -> { + // For multi-line, do not submit the text after pressing Enter key + if (keyCode == KeyEvent.KEYCODE_ENTER && editType != 1) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + messageReturnCode = 0; + messageReturnValue = editText.getText().toString(); + alertDialog.dismiss(); + return true; + } + return false; + }); + // For multi-line, add Done button since Enter key does not submit text + if (editType == 1) { + Button doneButton = new Button(this); + container.addView(doneButton); + doneButton.setText(R.string.ime_dialog_done); + doneButton.setOnClickListener((view -> { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + messageReturnCode = 0; + messageReturnValue = editText.getText().toString(); + alertDialog.dismiss(); + })); + } + alertDialog.show(); + alertDialog.setOnCancelListener(dialog -> { + getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + messageReturnValue = current; + messageReturnCode = -1; + }); + } + + public int getDialogState() { + return messageReturnCode; + } + + public String getDialogValue() { + messageReturnCode = -1; + return messageReturnValue; + } + + public float getDensity() { + return getResources().getDisplayMetrics().density; + } + + public int getDisplayHeight() { + return getResources().getDisplayMetrics().heightPixels; + } + + public int getDisplayWidth() { + return getResources().getDisplayMetrics().widthPixels; + } + + public void openURI(String uri) { + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri)); + startActivity(browserIntent); + } + + public String getUserDataPath() { + return Utils.getUserDataDirectory(this).getAbsolutePath(); + } + + public String getCachePath() { + return Utils.getCacheDirectory(this).getAbsolutePath(); + } + + public void shareFile(String path) { + File file = new File(path); + if (!file.exists()) { + Log.e("GameActivity", "File " + file.getAbsolutePath() + " doesn't exist"); + return; + } + + Uri fileUri = FileProvider.getUriForFile(this, "net.minetest.minetest.fileprovider", file); + + Intent intent = new Intent(Intent.ACTION_SEND, fileUri); + intent.setDataAndType(fileUri, getContentResolver().getType(fileUri)); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.putExtra(Intent.EXTRA_STREAM, fileUri); + + Intent shareIntent = Intent.createChooser(intent, null); + startActivity(shareIntent); + } +} diff --git a/android/app/src/main/java/net/minetest/minetest/MainActivity.java b/android/app/src/main/java/net/minetest/minetest/MainActivity.java new file mode 100644 index 0000000..b6567b4 --- /dev/null +++ b/android/app/src/main/java/net/minetest/minetest/MainActivity.java @@ -0,0 +1,185 @@ +/* +Minetest +Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2020 ubulem, Bektur Mambetov + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.minetest.minetest; + +import android.Manifest; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static net.minetest.minetest.UnzipService.*; + +public class MainActivity extends AppCompatActivity { + private final static int versionCode = BuildConfig.VERSION_CODE; + private final static int PERMISSIONS = 1; + private static final String[] REQUIRED_SDK_PERMISSIONS = + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}; + private static final String SETTINGS = "MinetestSettings"; + private static final String TAG_VERSION_CODE = "versionCode"; + + private ProgressBar mProgressBar; + private TextView mTextView; + private SharedPreferences sharedPreferences; + + private final BroadcastReceiver myReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + int progress = 0; + @StringRes int message = 0; + if (intent != null) { + progress = intent.getIntExtra(ACTION_PROGRESS, 0); + message = intent.getIntExtra(ACTION_PROGRESS_MESSAGE, 0); + } + + if (progress == FAILURE) { + Toast.makeText(MainActivity.this, intent.getStringExtra(ACTION_FAILURE), Toast.LENGTH_LONG).show(); + finish(); + } else if (progress == SUCCESS) { + startNative(); + } else { + if (mProgressBar != null) { + mProgressBar.setVisibility(View.VISIBLE); + if (progress == INDETERMINATE) { + mProgressBar.setIndeterminate(true); + } else { + mProgressBar.setIndeterminate(false); + mProgressBar.setProgress(progress); + } + } + mTextView.setVisibility(View.VISIBLE); + if (message != 0) + mTextView.setText(message); + } + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + IntentFilter filter = new IntentFilter(ACTION_UPDATE); + registerReceiver(myReceiver, filter); + mProgressBar = findViewById(R.id.progressBar); + mTextView = findViewById(R.id.textView); + sharedPreferences = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && + Build.VERSION.SDK_INT < Build.VERSION_CODES.R) + checkPermission(); + else + checkAppVersion(); + } + + private void checkPermission() { + final List missingPermissions = new ArrayList<>(); + for (final String permission : REQUIRED_SDK_PERMISSIONS) { + final int result = ContextCompat.checkSelfPermission(this, permission); + if (result != PackageManager.PERMISSION_GRANTED) + missingPermissions.add(permission); + } + if (!missingPermissions.isEmpty()) { + final String[] permissions = missingPermissions + .toArray(new String[0]); + ActivityCompat.requestPermissions(this, permissions, PERMISSIONS); + } else { + final int[] grantResults = new int[REQUIRED_SDK_PERMISSIONS.length]; + Arrays.fill(grantResults, PackageManager.PERMISSION_GRANTED); + onRequestPermissionsResult(PERMISSIONS, REQUIRED_SDK_PERMISSIONS, grantResults); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == PERMISSIONS) { + for (int grantResult : grantResults) { + if (grantResult != PackageManager.PERMISSION_GRANTED) { + Toast.makeText(this, R.string.not_granted, Toast.LENGTH_LONG).show(); + finish(); + return; + } + } + checkAppVersion(); + } + } + + private void checkAppVersion() { + if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + Toast.makeText(this, R.string.no_external_storage, Toast.LENGTH_LONG).show(); + finish(); + return; + } + + if (UnzipService.getIsRunning()) { + mProgressBar.setVisibility(View.VISIBLE); + mProgressBar.setIndeterminate(true); + mTextView.setVisibility(View.VISIBLE); + } else if (sharedPreferences.getInt(TAG_VERSION_CODE, 0) == versionCode && + Utils.isInstallValid(this)) { + startNative(); + } else { + mProgressBar.setVisibility(View.VISIBLE); + mProgressBar.setIndeterminate(true); + mTextView.setVisibility(View.VISIBLE); + + Intent intent = new Intent(this, UnzipService.class); + startService(intent); + } + } + + private void startNative() { + sharedPreferences.edit().putInt(TAG_VERSION_CODE, versionCode).apply(); + Intent intent = new Intent(this, GameActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(intent); + } + + @Override + public void onBackPressed() { + // Prevent abrupt interruption when copy game files from assets + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(myReceiver); + } +} diff --git a/android/app/src/main/java/net/minetest/minetest/UnzipService.java b/android/app/src/main/java/net/minetest/minetest/UnzipService.java new file mode 100644 index 0000000..a61a491 --- /dev/null +++ b/android/app/src/main/java/net/minetest/minetest/UnzipService.java @@ -0,0 +1,259 @@ +/* +Minetest +Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2020 ubulem, Bektur Mambetov + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.minetest.minetest; + +import android.app.IntentService; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.Environment; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.annotation.StringRes; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +public class UnzipService extends IntentService { + public static final String ACTION_UPDATE = "net.minetest.minetest.UPDATE"; + public static final String ACTION_PROGRESS = "net.minetest.minetest.PROGRESS"; + public static final String ACTION_PROGRESS_MESSAGE = "net.minetest.minetest.PROGRESS_MESSAGE"; + public static final String ACTION_FAILURE = "net.minetest.minetest.FAILURE"; + public static final int SUCCESS = -1; + public static final int FAILURE = -2; + public static final int INDETERMINATE = -3; + private final int id = 1; + private NotificationManager mNotifyManager; + private boolean isSuccess = true; + private String failureMessage; + + private static boolean isRunning = false; + public static synchronized boolean getIsRunning() { + return isRunning; + } + private static synchronized void setIsRunning(boolean v) { + isRunning = v; + } + + public UnzipService() { + super("net.minetest.minetest.UnzipService"); + } + + @Override + protected void onHandleIntent(Intent intent) { + Notification.Builder notificationBuilder = createNotification(); + final File zipFile = new File(getCacheDir(), "Minetest.zip"); + try { + setIsRunning(true); + File userDataDirectory = Utils.getUserDataDirectory(this); + if (userDataDirectory == null) { + throw new IOException("Unable to find user data directory"); + } + + try (InputStream in = this.getAssets().open(zipFile.getName())) { + try (OutputStream out = new FileOutputStream(zipFile)) { + int readLen; + byte[] readBuffer = new byte[16384]; + while ((readLen = in.read(readBuffer)) != -1) { + out.write(readBuffer, 0, readLen); + } + } + } + + migrate(notificationBuilder, userDataDirectory); + unzip(notificationBuilder, zipFile, userDataDirectory); + } catch (IOException e) { + isSuccess = false; + failureMessage = e.getLocalizedMessage(); + } finally { + setIsRunning(false); + zipFile.delete(); + } + } + + private Notification.Builder createNotification() { + String name = "net.minetest.minetest"; + String channelId = "Minetest channel"; + String description = "notifications from Minetest"; + Notification.Builder builder; + if (mNotifyManager == null) + mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + int importance = NotificationManager.IMPORTANCE_LOW; + NotificationChannel mChannel = null; + if (mNotifyManager != null) + mChannel = mNotifyManager.getNotificationChannel(channelId); + if (mChannel == null) { + mChannel = new NotificationChannel(channelId, name, importance); + mChannel.setDescription(description); + // Configure the notification channel, NO SOUND + mChannel.setSound(null, null); + mChannel.enableLights(false); + mChannel.enableVibration(false); + mNotifyManager.createNotificationChannel(mChannel); + } + builder = new Notification.Builder(this, channelId); + } else { + builder = new Notification.Builder(this); + } + + Intent notificationIntent = new Intent(this, MainActivity.class); + notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP + | Intent.FLAG_ACTIVITY_SINGLE_TOP); + PendingIntent intent = PendingIntent.getActivity(this, 0, + notificationIntent, 0); + + builder.setContentTitle(getString(R.string.notification_title)) + .setSmallIcon(R.mipmap.ic_launcher) + .setContentText(getString(R.string.notification_description)) + .setContentIntent(intent) + .setOngoing(true) + .setProgress(0, 0, true); + + mNotifyManager.notify(id, builder.build()); + return builder; + } + + private void unzip(Notification.Builder notificationBuilder, File zipFile, File userDataDirectory) throws IOException { + int per = 0; + + int size; + try (ZipFile zipSize = new ZipFile(zipFile)) { + size = zipSize.size(); + } + + int readLen; + byte[] readBuffer = new byte[16384]; + try (FileInputStream fileInputStream = new FileInputStream(zipFile); + ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) { + ZipEntry ze; + while ((ze = zipInputStream.getNextEntry()) != null) { + if (ze.isDirectory()) { + ++per; + Utils.createDirs(userDataDirectory, ze.getName()); + continue; + } + publishProgress(notificationBuilder, R.string.loading, 100 * ++per / size); + try (OutputStream outputStream = new FileOutputStream( + new File(userDataDirectory, ze.getName()))) { + while ((readLen = zipInputStream.read(readBuffer)) != -1) { + outputStream.write(readBuffer, 0, readLen); + } + } + } + } + } + + void moveFileOrDir(@NonNull File src, @NonNull File dst) throws IOException { + try { + Process p = new ProcessBuilder("/system/bin/mv", + src.getAbsolutePath(), dst.getAbsolutePath()).start(); + int exitcode = p.waitFor(); + if (exitcode != 0) + throw new IOException("Move failed with exit code " + exitcode); + } catch (InterruptedException e) { + throw new IOException("Move operation interrupted"); + } + } + + boolean recursivelyDeleteDirectory(@NonNull File loc) { + try { + Process p = new ProcessBuilder("/system/bin/rm", "-rf", + loc.getAbsolutePath()).start(); + return p.waitFor() == 0; + } catch (IOException | InterruptedException e) { + return false; + } + } + + /** + * Migrates user data from deprecated external storage to app scoped storage + */ + private void migrate(Notification.Builder notificationBuilder, File newLocation) throws IOException { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + return; + } + + File oldLocation = new File(Environment.getExternalStorageDirectory(), "Minetest"); + if (!oldLocation.isDirectory()) + return; + + publishProgress(notificationBuilder, R.string.migrating, 0); + newLocation.mkdir(); + + String[] dirs = new String[] { "worlds", "games", "mods", "textures", "client" }; + for (int i = 0; i < dirs.length; i++) { + publishProgress(notificationBuilder, R.string.migrating, 100 * i / dirs.length); + File dir = new File(oldLocation, dirs[i]), dir2 = new File(newLocation, dirs[i]); + if (dir.isDirectory() && !dir2.isDirectory()) { + moveFileOrDir(dir, dir2); + } + } + + for (String filename : new String[] { "minetest.conf" }) { + File file = new File(oldLocation, filename), file2 = new File(newLocation, filename); + if (file.isFile() && !file2.isFile()) { + moveFileOrDir(file, file2); + } + } + + recursivelyDeleteDirectory(oldLocation); + } + + private void publishProgress(@Nullable Notification.Builder notificationBuilder, @StringRes int message, int progress) { + Intent intentUpdate = new Intent(ACTION_UPDATE); + intentUpdate.putExtra(ACTION_PROGRESS, progress); + intentUpdate.putExtra(ACTION_PROGRESS_MESSAGE, message); + if (!isSuccess) + intentUpdate.putExtra(ACTION_FAILURE, failureMessage); + sendBroadcast(intentUpdate); + + if (notificationBuilder != null) { + notificationBuilder.setContentText(getString(message)); + if (progress == INDETERMINATE) { + notificationBuilder.setProgress(100, 50, true); + } else { + notificationBuilder.setProgress(100, progress, false); + } + mNotifyManager.notify(id, notificationBuilder.build()); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + mNotifyManager.cancel(id); + publishProgress(null, R.string.loading, isSuccess ? SUCCESS : FAILURE); + } +} diff --git a/android/app/src/main/java/net/minetest/minetest/Utils.java b/android/app/src/main/java/net/minetest/minetest/Utils.java new file mode 100644 index 0000000..b2553c8 --- /dev/null +++ b/android/app/src/main/java/net/minetest/minetest/Utils.java @@ -0,0 +1,39 @@ +package net.minetest.minetest; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import java.io.File; + +public class Utils { + public static @NonNull File createDirs(File root, String dir) { + File f = new File(root, dir); + if (!f.isDirectory()) + f.mkdirs(); + + return f; + } + + public static @Nullable File getUserDataDirectory(Context context) { + File extDir = context.getExternalFilesDir(null); + if (extDir == null) { + return null; + } + + return createDirs(extDir, "Minetest"); + } + + public static @Nullable File getCacheDirectory(Context context) { + return context.getCacheDir(); + } + + public static boolean isInstallValid(Context context) { + File userDataDirectory = getUserDataDirectory(context); + return userDataDirectory != null && userDataDirectory.isDirectory() && + new File(userDataDirectory, "games").isDirectory() && + new File(userDataDirectory, "builtin").isDirectory() && + new File(userDataDirectory, "client").isDirectory() && + new File(userDataDirectory, "textures").isDirectory(); + } +} diff --git a/android/app/src/main/res/drawable/background.png b/android/app/src/main/res/drawable/background.png new file mode 100644 index 0000000..43bd608 Binary files /dev/null and b/android/app/src/main/res/drawable/background.png differ diff --git a/android/app/src/main/res/drawable/bg.xml b/android/app/src/main/res/drawable/bg.xml new file mode 100644 index 0000000..903335e --- /dev/null +++ b/android/app/src/main/res/drawable/bg.xml @@ -0,0 +1,4 @@ + + diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..93508c3 --- /dev/null +++ b/android/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,33 @@ + + + + + + + diff --git a/android/app/src/main/res/mipmap/ic_launcher.png b/android/app/src/main/res/mipmap/ic_launcher.png new file mode 100644 index 0000000..88a8378 Binary files /dev/null and b/android/app/src/main/res/mipmap/ic_launcher.png differ diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..99f948c --- /dev/null +++ b/android/app/src/main/res/values/strings.xml @@ -0,0 +1,13 @@ + + + + Minetest + Loading… + Migrating save data from old install… (this may take a while) + Required permission wasn\'t granted, Minetest can\'t run without it + Loading Minetest + Less than 1 minute… + Done + External storage isn\'t available. If you use an SDCard, please reinsert it. Otherwise, try restarting your phone or contacting the Minetest developers + + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..291a4ea --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/android/app/src/main/res/xml/filepaths.xml b/android/app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..2fff069 --- /dev/null +++ b/android/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,3 @@ + + + diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..8e7a8a9 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,37 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +project.ext.set("versionMajor", 5) // Version Major +project.ext.set("versionMinor", 6) // Version Minor +project.ext.set("versionPatch", 0) // Version Patch +project.ext.set("versionExtra", "") // Version Extra +project.ext.set("versionCode", 42) // Android Version Code +project.ext.set("developmentBuild", 0) // Whether it is a development build, or a release +// NOTE: +2 after each release! +// +1 for ARM and +1 for ARM64 APK's, because +// each APK must have a larger `versionCode` than the previous + +buildscript { + ext.ndk_version = '23.2.8568313' + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:7.0.3' + classpath 'de.undercouch:gradle-download-task:4.1.1' + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir + delete 'native/deps' +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..53b475c --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,11 @@ +<#if isLowMemory> +org.gradle.jvmargs=-Xmx4G -XX:MaxPermSize=2G -XX:+HeapDumpOnOutOfMemoryError +<#else> +org.gradle.jvmargs=-Xmx16G -XX:MaxPermSize=8G -XX:+HeapDumpOnOutOfMemoryError + +org.gradle.daemon=true +org.gradle.parallel=true +org.gradle.parallel.threads=8 +org.gradle.configureondemand=true +android.enableJetifier=true +android.useAndroidX=true diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..5c2d1cf Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..8ad73a7 --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip diff --git a/android/gradlew b/android/gradlew new file mode 100644 index 0000000..25e0c11 --- /dev/null +++ b/android/gradlew @@ -0,0 +1,188 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + command -v java >/dev/null || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat new file mode 100644 index 0000000..9618d8d --- /dev/null +++ b/android/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/android/icons/aux1_btn.svg b/android/icons/aux1_btn.svg new file mode 100644 index 0000000..e0ee97c --- /dev/null +++ b/android/icons/aux1_btn.svg @@ -0,0 +1,143 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + Aux1 + + + diff --git a/android/icons/camera_btn.svg b/android/icons/camera_btn.svg new file mode 100644 index 0000000..a91a7fc --- /dev/null +++ b/android/icons/camera_btn.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/chat_btn.svg b/android/icons/chat_btn.svg new file mode 100644 index 0000000..41dc6f8 --- /dev/null +++ b/android/icons/chat_btn.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/android/icons/chat_hide_btn.svg b/android/icons/chat_hide_btn.svg new file mode 100644 index 0000000..6647b30 --- /dev/null +++ b/android/icons/chat_hide_btn.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/chat_show_btn.svg b/android/icons/chat_show_btn.svg new file mode 100644 index 0000000..fce9de9 --- /dev/null +++ b/android/icons/chat_show_btn.svg @@ -0,0 +1,133 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/checkbox_tick.svg b/android/icons/checkbox_tick.svg new file mode 100644 index 0000000..6b727bb --- /dev/null +++ b/android/icons/checkbox_tick.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/android/icons/debug_btn.svg b/android/icons/debug_btn.svg new file mode 100644 index 0000000..2c37f14 --- /dev/null +++ b/android/icons/debug_btn.svg @@ -0,0 +1,344 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/down.svg b/android/icons/down.svg new file mode 100644 index 0000000..190e7e8 --- /dev/null +++ b/android/icons/down.svg @@ -0,0 +1,542 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/drop_btn.svg b/android/icons/drop_btn.svg new file mode 100644 index 0000000..7cb0e85 --- /dev/null +++ b/android/icons/drop_btn.svg @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/fast_btn.svg b/android/icons/fast_btn.svg new file mode 100644 index 0000000..1436596 --- /dev/null +++ b/android/icons/fast_btn.svg @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/fly_btn.svg b/android/icons/fly_btn.svg new file mode 100644 index 0000000..d203842 --- /dev/null +++ b/android/icons/fly_btn.svg @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/gear_icon.svg b/android/icons/gear_icon.svg new file mode 100644 index 0000000..b44685a --- /dev/null +++ b/android/icons/gear_icon.svg @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/inventory_btn.svg b/android/icons/inventory_btn.svg new file mode 100644 index 0000000..ee3dc3c --- /dev/null +++ b/android/icons/inventory_btn.svg @@ -0,0 +1,509 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/joystick_bg.svg b/android/icons/joystick_bg.svg new file mode 100644 index 0000000..d8836b3 --- /dev/null +++ b/android/icons/joystick_bg.svg @@ -0,0 +1,876 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/joystick_center.svg b/android/icons/joystick_center.svg new file mode 100644 index 0000000..1720229 --- /dev/null +++ b/android/icons/joystick_center.svg @@ -0,0 +1,877 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/joystick_off.svg b/android/icons/joystick_off.svg new file mode 100644 index 0000000..58e1acf --- /dev/null +++ b/android/icons/joystick_off.svg @@ -0,0 +1,882 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/jump_btn.svg b/android/icons/jump_btn.svg new file mode 100644 index 0000000..882c49e --- /dev/null +++ b/android/icons/jump_btn.svg @@ -0,0 +1,547 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/minimap_btn.svg b/android/icons/minimap_btn.svg new file mode 100644 index 0000000..deda327 --- /dev/null +++ b/android/icons/minimap_btn.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/noclip_btn.svg b/android/icons/noclip_btn.svg new file mode 100644 index 0000000..a816edf --- /dev/null +++ b/android/icons/noclip_btn.svg @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/rangeview_btn.svg b/android/icons/rangeview_btn.svg new file mode 100644 index 0000000..f9319e0 --- /dev/null +++ b/android/icons/rangeview_btn.svg @@ -0,0 +1,456 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/rare_controls.svg b/android/icons/rare_controls.svg new file mode 100644 index 0000000..c9991ec --- /dev/null +++ b/android/icons/rare_controls.svg @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/icons/zoom.svg b/android/icons/zoom.svg new file mode 100644 index 0000000..ea8dec3 --- /dev/null +++ b/android/icons/zoom.svg @@ -0,0 +1,599 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/keystore-minetest.jks b/android/keystore-minetest.jks new file mode 100644 index 0000000..8fce68b Binary files /dev/null and b/android/keystore-minetest.jks differ diff --git a/android/native/build.gradle b/android/native/build.gradle new file mode 100644 index 0000000..90e4fe2 --- /dev/null +++ b/android/native/build.gradle @@ -0,0 +1,69 @@ +apply plugin: 'com.android.library' +apply plugin: 'de.undercouch.download' + +android { + compileSdkVersion 30 + buildToolsVersion '30.0.3' + ndkVersion "$ndk_version" + defaultConfig { + minSdkVersion 16 + targetSdkVersion 30 + externalNativeBuild { + ndkBuild { + arguments '-j' + Runtime.getRuntime().availableProcessors(), + "versionMajor=${versionMajor}", + "versionMinor=${versionMinor}", + "versionPatch=${versionPatch}", + "versionExtra=${versionExtra}", + "developmentBuild=${developmentBuild}" + } + } + } + + externalNativeBuild { + ndkBuild { + path file('jni/Android.mk') + } + } + + // supported architectures + splits { + abi { + enable true + reset() + include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' + } + } + + buildTypes { + release { + externalNativeBuild { + ndkBuild { + arguments 'NDEBUG=1' + } + } + + ndk { + debugSymbolLevel 'SYMBOL_TABLE' + } + } + } +} + +// get precompiled deps +task downloadDeps(type: Download) { + src 'https://github.com/minetest/minetest_android_deps/releases/download/latest/deps.zip' + dest new File(buildDir, 'deps.zip') + overwrite false +} + +task getDeps(dependsOn: downloadDeps, type: Copy) { + def deps = new File(buildDir.parent, 'deps') + if (!deps.exists()) { + deps.mkdir() + from zipTree(downloadDeps.dest) + into deps + } +} + +preBuild.dependsOn getDeps diff --git a/android/native/jni/Android.mk b/android/native/jni/Android.mk new file mode 100644 index 0000000..cd9326d --- /dev/null +++ b/android/native/jni/Android.mk @@ -0,0 +1,301 @@ +LOCAL_PATH := $(call my-dir)/.. + +#LOCAL_ADDRESS_SANITIZER:=true +#USE_BUILTIN_LUA:=true + +include $(CLEAR_VARS) +LOCAL_MODULE := Curl +LOCAL_SRC_FILES := deps/$(APP_ABI)/Curl/libcurl.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := libmbedcrypto +LOCAL_SRC_FILES := deps/$(APP_ABI)/Curl/libmbedcrypto.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := libmbedtls +LOCAL_SRC_FILES := deps/$(APP_ABI)/Curl/libmbedtls.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := libmbedx509 +LOCAL_SRC_FILES := deps/$(APP_ABI)/Curl/libmbedx509.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := Freetype +LOCAL_SRC_FILES := deps/$(APP_ABI)/Freetype/libfreetype.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := Iconv +LOCAL_SRC_FILES := deps/$(APP_ABI)/Iconv/libiconv.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := libcharset +LOCAL_SRC_FILES := deps/$(APP_ABI)/Iconv/libcharset.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := Irrlicht +LOCAL_SRC_FILES := deps/$(APP_ABI)/Irrlicht/libIrrlichtMt.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := Irrlicht-libpng +LOCAL_SRC_FILES := deps/$(APP_ABI)/Irrlicht/libpng.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := Irrlicht-libjpeg +LOCAL_SRC_FILES := deps/$(APP_ABI)/Irrlicht/libjpeg.a +include $(PREBUILT_STATIC_LIBRARY) + +ifndef USE_BUILTIN_LUA + +include $(CLEAR_VARS) +LOCAL_MODULE := LuaJIT +LOCAL_SRC_FILES := deps/$(APP_ABI)/LuaJIT/libluajit.a +include $(PREBUILT_STATIC_LIBRARY) + +endif + +include $(CLEAR_VARS) +LOCAL_MODULE := OpenAL +LOCAL_SRC_FILES := deps/$(APP_ABI)/OpenAL-Soft/libopenal.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := Gettext +LOCAL_SRC_FILES := deps/$(APP_ABI)/Gettext/libintl.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := SQLite3 +LOCAL_SRC_FILES := deps/$(APP_ABI)/SQLite/libsqlite3.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := Vorbis +LOCAL_SRC_FILES := deps/$(APP_ABI)/Vorbis/libvorbis.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := libvorbisfile +LOCAL_SRC_FILES := deps/$(APP_ABI)/Vorbis/libvorbisfile.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := libogg +LOCAL_SRC_FILES := deps/$(APP_ABI)/Vorbis/libogg.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := Zstd +LOCAL_SRC_FILES := deps/$(APP_ABI)/Zstd/libzstd.a +include $(PREBUILT_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := Minetest + +LOCAL_CFLAGS += \ + -DJSONCPP_NO_LOCALE_SUPPORT \ + -DHAVE_TOUCHSCREENGUI \ + -DENABLE_GLES=1 \ + -DUSE_CURL=1 \ + -DUSE_SOUND=1 \ + -DUSE_LEVELDB=0 \ + -DUSE_GETTEXT=1 \ + -DVERSION_MAJOR=${versionMajor} \ + -DVERSION_MINOR=${versionMinor} \ + -DVERSION_PATCH=${versionPatch} \ + -DVERSION_EXTRA=${versionExtra} \ + -DDEVELOPMENT_BUILD=${developmentBuild} \ + $(GPROF_DEF) + +ifdef USE_BUILTIN_LUA + LOCAL_CFLAGS += -DUSE_LUAJIT=0 +else + LOCAL_CFLAGS += -DUSE_LUAJIT=1 +endif + +ifdef NDEBUG + LOCAL_CFLAGS += -DNDEBUG=1 +endif + +ifdef GPROF + GPROF_DEF := -DGPROF + PROFILER_LIBS := android-ndk-profiler + LOCAL_CFLAGS += -pg +endif + +LOCAL_C_INCLUDES := \ + ../../src \ + ../../src/script \ + ../../lib/gmp \ + ../../lib/jsoncpp \ + deps/$(APP_ABI)/Curl/include \ + deps/$(APP_ABI)/Freetype/include/freetype2 \ + deps/$(APP_ABI)/Irrlicht/include \ + deps/$(APP_ABI)/Gettext/include \ + deps/$(APP_ABI)/Iconv/include \ + deps/$(APP_ABI)/OpenAL-Soft/include \ + deps/$(APP_ABI)/SQLite/include \ + deps/$(APP_ABI)/Vorbis/include \ + deps/$(APP_ABI)/Zstd/include + +ifdef USE_BUILTIN_LUA + LOCAL_C_INCLUDES += \ + ../../lib/lua/src \ + ../../lib/bitop +else + LOCAL_C_INCLUDES += deps/$(APP_ABI)/LuaJIT/include +endif + +LOCAL_SRC_FILES := \ + $(wildcard ../../src/client/*.cpp) \ + $(wildcard ../../src/client/*/*.cpp) \ + $(wildcard ../../src/content/*.cpp) \ + ../../src/database/database.cpp \ + ../../src/database/database-dummy.cpp \ + ../../src/database/database-files.cpp \ + ../../src/database/database-sqlite3.cpp \ + $(wildcard ../../src/gui/*.cpp) \ + $(wildcard ../../src/irrlicht_changes/*.cpp) \ + $(wildcard ../../src/mapgen/*.cpp) \ + $(wildcard ../../src/network/*.cpp) \ + $(wildcard ../../src/script/*.cpp) \ + $(wildcard ../../src/script/*/*.cpp) \ + $(wildcard ../../src/server/*.cpp) \ + $(wildcard ../../src/threading/*.cpp) \ + $(wildcard ../../src/util/*.c) \ + $(wildcard ../../src/util/*.cpp) \ + ../../src/ban.cpp \ + ../../src/chat.cpp \ + ../../src/clientiface.cpp \ + ../../src/collision.cpp \ + ../../src/content_mapnode.cpp \ + ../../src/content_nodemeta.cpp \ + ../../src/convert_json.cpp \ + ../../src/craftdef.cpp \ + ../../src/debug.cpp \ + ../../src/defaultsettings.cpp \ + ../../src/emerge.cpp \ + ../../src/environment.cpp \ + ../../src/face_position_cache.cpp \ + ../../src/filesys.cpp \ + ../../src/gettext.cpp \ + ../../src/httpfetch.cpp \ + ../../src/hud.cpp \ + ../../src/inventory.cpp \ + ../../src/inventorymanager.cpp \ + ../../src/itemdef.cpp \ + ../../src/itemstackmetadata.cpp \ + ../../src/light.cpp \ + ../../src/log.cpp \ + ../../src/main.cpp \ + ../../src/map.cpp \ + ../../src/map_settings_manager.cpp \ + ../../src/mapblock.cpp \ + ../../src/mapnode.cpp \ + ../../src/mapsector.cpp \ + ../../src/metadata.cpp \ + ../../src/modchannels.cpp \ + ../../src/nameidmapping.cpp \ + ../../src/nodedef.cpp \ + ../../src/nodemetadata.cpp \ + ../../src/nodetimer.cpp \ + ../../src/noise.cpp \ + ../../src/objdef.cpp \ + ../../src/object_properties.cpp \ + ../../src/particles.cpp \ + ../../src/pathfinder.cpp \ + ../../src/player.cpp \ + ../../src/porting.cpp \ + ../../src/porting_android.cpp \ + ../../src/profiler.cpp \ + ../../src/raycast.cpp \ + ../../src/reflowscan.cpp \ + ../../src/remoteplayer.cpp \ + ../../src/rollback.cpp \ + ../../src/rollback_interface.cpp \ + ../../src/serialization.cpp \ + ../../src/server.cpp \ + ../../src/serverenvironment.cpp \ + ../../src/serverlist.cpp \ + ../../src/settings.cpp \ + ../../src/staticobject.cpp \ + ../../src/texture_override.cpp \ + ../../src/tileanimation.cpp \ + ../../src/tool.cpp \ + ../../src/translation.cpp \ + ../../src/version.cpp \ + ../../src/voxel.cpp \ + ../../src/voxelalgorithms.cpp + +# Built-in Lua +ifdef USE_BUILTIN_LUA + LOCAL_SRC_FILES += \ + ../../lib/lua/src/lapi.c \ + ../../lib/lua/src/lauxlib.c \ + ../../lib/lua/src/lbaselib.c \ + ../../lib/lua/src/lcode.c \ + ../../lib/lua/src/ldblib.c \ + ../../lib/lua/src/ldebug.c \ + ../../lib/lua/src/ldo.c \ + ../../lib/lua/src/ldump.c \ + ../../lib/lua/src/lfunc.c \ + ../../lib/lua/src/lgc.c \ + ../../lib/lua/src/linit.c \ + ../../lib/lua/src/liolib.c \ + ../../lib/lua/src/llex.c \ + ../../lib/lua/src/lmathlib.c \ + ../../lib/lua/src/lmem.c \ + ../../lib/lua/src/loadlib.c \ + ../../lib/lua/src/lobject.c \ + ../../lib/lua/src/lopcodes.c \ + ../../lib/lua/src/loslib.c \ + ../../lib/lua/src/lparser.c \ + ../../lib/lua/src/lstate.c \ + ../../lib/lua/src/lstring.c \ + ../../lib/lua/src/lstrlib.c \ + ../../lib/lua/src/ltable.c \ + ../../lib/lua/src/ltablib.c \ + ../../lib/lua/src/ltm.c \ + ../../lib/lua/src/lundump.c \ + ../../lib/lua/src/lvm.c \ + ../../lib/lua/src/lzio.c \ + ../../lib/bitop/bit.c +endif + +# GMP +LOCAL_SRC_FILES += ../../lib/gmp/mini-gmp.c + +# JSONCPP +LOCAL_SRC_FILES += ../../lib/jsoncpp/jsoncpp.cpp + +LOCAL_STATIC_LIBRARIES += \ + Curl libmbedcrypto libmbedtls libmbedx509 \ + Freetype \ + Iconv libcharset \ + Irrlicht Irrlicht-libpng Irrlicht-libjpeg \ + OpenAL \ + Gettext \ + SQLite3 \ + Vorbis libvorbisfile libogg \ + Zstd +ifndef USE_BUILTIN_LUA + LOCAL_STATIC_LIBRARIES += LuaJIT +endif +LOCAL_STATIC_LIBRARIES += android_native_app_glue $(PROFILER_LIBS) + +LOCAL_LDLIBS := -lEGL -lGLESv1_CM -lGLESv2 -landroid -lOpenSLES -lz + +include $(BUILD_SHARED_LIBRARY) + +ifdef GPROF +$(call import-module,android-ndk-profiler) +endif +$(call import-module,android/native_app_glue) diff --git a/android/native/jni/Application.mk b/android/native/jni/Application.mk new file mode 100644 index 0000000..9d95961 --- /dev/null +++ b/android/native/jni/Application.mk @@ -0,0 +1,32 @@ +APP_PLATFORM := ${APP_PLATFORM} +APP_ABI := ${TARGET_ABI} +APP_STL := c++_shared +NDK_TOOLCHAIN_VERSION := clang +APP_SHORT_COMMANDS := true +APP_MODULES := Minetest + +APP_CPPFLAGS := -O2 -fvisibility=hidden + +ifeq ($(APP_ABI),armeabi-v7a) +APP_CPPFLAGS += -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb +endif + +ifeq ($(APP_ABI),x86) +APP_CPPFLAGS += -mssse3 -mfpmath=sse -funroll-loops +endif + +ifndef NDEBUG +APP_CPPFLAGS := -g -Og -fno-omit-frame-pointer +endif + +APP_CFLAGS := $(APP_CPPFLAGS) -Wno-inconsistent-missing-override -Wno-parentheses-equality +APP_CXXFLAGS := $(APP_CPPFLAGS) -fexceptions -frtti -std=gnu++14 +APP_LDFLAGS := -Wl,--no-warn-mismatch,--gc-sections,--icf=safe + +ifeq ($(APP_ABI),arm64-v8a) +APP_LDFLAGS := -Wl,--no-warn-mismatch,--gc-sections +endif + +ifndef NDEBUG +APP_LDFLAGS := +endif diff --git a/android/native/src/main/AndroidManifest.xml b/android/native/src/main/AndroidManifest.xml new file mode 100644 index 0000000..19451c7 --- /dev/null +++ b/android/native/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..b048fca --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = "Minetest" +include ':app', ':native' diff --git a/builddir/LuaJIT-master/COPYRIGHT b/builddir/LuaJIT-master/COPYRIGHT new file mode 100644 index 0000000..b614d3e --- /dev/null +++ b/builddir/LuaJIT-master/COPYRIGHT @@ -0,0 +1,56 @@ +=============================================================================== +LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/ + +Copyright (C) 2005-2016 Mike Pall. 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. + +[ MIT license: http://www.opensource.org/licenses/mit-license.php ] + +=============================================================================== +[ LuaJIT includes code from Lua 5.1/5.2, which has this license statement: ] + +Copyright (C) 1994-2012 Lua.org, PUC-Rio. + +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. + +=============================================================================== +[ LuaJIT includes code from dlmalloc, which has this license statement: ] + +This is a version (aka dlmalloc) of malloc/free/realloc written by +Doug Lea and released to the public domain, as explained at +http://creativecommons.org/licenses/publicdomain + +=============================================================================== diff --git a/builddir/LuaJIT-master/bin/lua51.dll b/builddir/LuaJIT-master/bin/lua51.dll new file mode 100644 index 0000000..44995a7 Binary files /dev/null and b/builddir/LuaJIT-master/bin/lua51.dll differ diff --git a/builddir/LuaJIT-master/bin/lua51.lib b/builddir/LuaJIT-master/bin/lua51.lib new file mode 100644 index 0000000..87aa1a8 Binary files /dev/null and b/builddir/LuaJIT-master/bin/lua51.lib differ diff --git a/builddir/LuaJIT-master/bin/luajit.exe b/builddir/LuaJIT-master/bin/luajit.exe new file mode 100644 index 0000000..5cbab1d Binary files /dev/null and b/builddir/LuaJIT-master/bin/luajit.exe differ diff --git a/builddir/LuaJIT-master/include/lua.h b/builddir/LuaJIT-master/include/lua.h new file mode 100644 index 0000000..c83fd3b --- /dev/null +++ b/builddir/LuaJIT-master/include/lua.h @@ -0,0 +1,393 @@ +/* +** $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 +#include + + +#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 (`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); + +/* From Lua 5.2. */ +LUA_API void *lua_upvalueid (lua_State *L, int idx, int n); +LUA_API void lua_upvaluejoin (lua_State *L, int idx1, int n1, int idx2, int n2); +LUA_API int lua_loadx (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname, const char *mode); + + +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/builddir/LuaJIT-master/include/lua.hpp b/builddir/LuaJIT-master/include/lua.hpp new file mode 100644 index 0000000..07e9002 --- /dev/null +++ b/builddir/LuaJIT-master/include/lua.hpp @@ -0,0 +1,9 @@ +// C++ wrapper for LuaJIT header files. + +extern "C" { +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +#include "luajit.h" +} + diff --git a/builddir/LuaJIT-master/include/luaconf.h b/builddir/LuaJIT-master/include/luaconf.h new file mode 100644 index 0000000..6d9bbaa --- /dev/null +++ b/builddir/LuaJIT-master/include/luaconf.h @@ -0,0 +1,156 @@ +/* +** Configuration header. +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +*/ + +#ifndef luaconf_h +#define luaconf_h + +#ifndef WINVER +#define WINVER 0x0501 +#endif +#include +#include + +/* Default path for loading Lua and C modules with require(). */ +#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;" +#define LUA_CPATH_DEFAULT \ + ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" +#else +/* +** Note to distribution maintainers: do NOT patch the following lines! +** Please read ../doc/install.html#distro and pass PREFIX=/usr instead. +*/ +#ifndef LUA_MULTILIB +#define LUA_MULTILIB "lib" +#endif +#ifndef LUA_LMULTILIB +#define LUA_LMULTILIB "lib" +#endif +#define LUA_LROOT "/usr/local" +#define LUA_LUADIR "/lua/5.1/" +#define LUA_LJDIR "/luajit-2.0.4/" + +#ifdef LUA_ROOT +#define LUA_JROOT LUA_ROOT +#define LUA_RLDIR LUA_ROOT "/share" LUA_LUADIR +#define LUA_RCDIR LUA_ROOT "/" LUA_MULTILIB LUA_LUADIR +#define LUA_RLPATH ";" LUA_RLDIR "?.lua;" LUA_RLDIR "?/init.lua" +#define LUA_RCPATH ";" LUA_RCDIR "?.so" +#else +#define LUA_JROOT LUA_LROOT +#define LUA_RLPATH +#define LUA_RCPATH +#endif + +#define LUA_JPATH ";" LUA_JROOT "/share" LUA_LJDIR "?.lua" +#define LUA_LLDIR LUA_LROOT "/share" LUA_LUADIR +#define LUA_LCDIR LUA_LROOT "/" LUA_LMULTILIB LUA_LUADIR +#define LUA_LLPATH ";" LUA_LLDIR "?.lua;" LUA_LLDIR "?/init.lua" +#define LUA_LCPATH1 ";" LUA_LCDIR "?.so" +#define LUA_LCPATH2 ";" LUA_LCDIR "loadall.so" + +#define LUA_PATH_DEFAULT "./?.lua" LUA_JPATH LUA_LLPATH LUA_RLPATH +#define LUA_CPATH_DEFAULT "./?.so" LUA_LCPATH1 LUA_RCPATH LUA_LCPATH2 +#endif + +/* Environment variable names for path overrides and initialization code. */ +#define LUA_PATH "LUA_PATH" +#define LUA_CPATH "LUA_CPATH" +#define LUA_INIT "LUA_INIT" + +/* Special file system characters. */ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif +#define LUA_PATHSEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXECDIR "!" +#define LUA_IGMARK "-" +#define LUA_PATH_CONFIG \ + LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" \ + LUA_EXECDIR "\n" LUA_IGMARK + +/* Quoting in error messages. */ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + +/* Various tunables. */ +#define LUAI_MAXSTACK 65500 /* Max. # of stack slots for a thread (<64K). */ +#define LUAI_MAXCSTACK 8000 /* Max. # of stack slots for a C func (<10K). */ +#define LUAI_GCPAUSE 200 /* Pause GC until memory is at 200%. */ +#define LUAI_GCMUL 200 /* Run GC at 200% of allocation speed. */ +#define LUA_MAXCAPTURES 32 /* Max. pattern captures. */ + +/* Compatibility with older library function names. */ +#define LUA_COMPAT_MOD /* OLD: math.mod, NEW: math.fmod */ +#define LUA_COMPAT_GFIND /* OLD: string.gfind, NEW: string.gmatch */ + +/* Configuration for the frontend (the luajit executable). */ +#if defined(luajit_c) +#define LUA_PROGNAME "luajit" /* Fallback frontend name. */ +#define LUA_PROMPT "> " /* Interactive prompt. */ +#define LUA_PROMPT2 ">> " /* Continuation prompt. */ +#define LUA_MAXINPUT 512 /* Max. input line length. */ +#endif + +/* Note: changing the following defines breaks the Lua 5.1 ABI. */ +#define LUA_INTEGER ptrdiff_t +#define LUA_IDSIZE 60 /* Size of lua_Debug.short_src. */ +/* +** Size of lauxlib and io.* on-stack buffers. Weird workaround to avoid using +** unreasonable amounts of stack space, but still retain ABI compatibility. +** Blame Lua for depending on BUFSIZ in the ABI, blame **** for wrecking it. +*/ +#define LUAL_BUFFERSIZE (BUFSIZ > 16384 ? 8192 : BUFSIZ) + +/* The following defines are here only for compatibility with luaconf.h +** from the standard Lua distribution. They must not be changed for LuaJIT. +*/ +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double +#define LUAI_UACNUMBER double +#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 +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +/* Linkage of public API functions. */ +#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 + +#define LUALIB_API LUA_API + +/* Support for internal assertions. */ +#if defined(LUA_USE_ASSERT) || defined(LUA_USE_APICHECK) +#include +#endif +#ifdef LUA_USE_ASSERT +#define lua_assert(x) assert(x) +#endif +#ifdef LUA_USE_APICHECK +#define luai_apicheck(L, o) { (void)L; assert(o); } +#else +#define luai_apicheck(L, o) { (void)L; } +#endif + +#endif diff --git a/builddir/LuaJIT-master/include/luajit.h b/builddir/LuaJIT-master/include/luajit.h new file mode 100644 index 0000000..e7adbab --- /dev/null +++ b/builddir/LuaJIT-master/include/luajit.h @@ -0,0 +1,70 @@ +/* +** LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/ +** +** Copyright (C) 2005-2016 Mike Pall. 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. +** +** [ MIT license: http://www.opensource.org/licenses/mit-license.php ] +*/ + +#ifndef _LUAJIT_H +#define _LUAJIT_H + +#include "lua.h" + +#define LUAJIT_VERSION "LuaJIT 2.0.4" +#define LUAJIT_VERSION_NUM 20004 /* Version 2.0.4 = 02.00.04. */ +#define LUAJIT_VERSION_SYM luaJIT_version_2_0_4 +#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2016 Mike Pall" +#define LUAJIT_URL "http://luajit.org/" + +/* Modes for luaJIT_setmode. */ +#define LUAJIT_MODE_MASK 0x00ff + +enum { + LUAJIT_MODE_ENGINE, /* Set mode for whole JIT engine. */ + LUAJIT_MODE_DEBUG, /* Set debug mode (idx = level). */ + + LUAJIT_MODE_FUNC, /* Change mode for a function. */ + LUAJIT_MODE_ALLFUNC, /* Recurse into subroutine protos. */ + LUAJIT_MODE_ALLSUBFUNC, /* Change only the subroutines. */ + + LUAJIT_MODE_TRACE, /* Flush a compiled trace. */ + + LUAJIT_MODE_WRAPCFUNC = 0x10, /* Set wrapper mode for C function calls. */ + + LUAJIT_MODE_MAX +}; + +/* Flags or'ed in to the mode. */ +#define LUAJIT_MODE_OFF 0x0000 /* Turn feature off. */ +#define LUAJIT_MODE_ON 0x0100 /* Turn feature on. */ +#define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */ + +/* LuaJIT public C API. */ + +/* Control the JIT engine. */ +LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode); + +/* Enforce (dynamic) linker error for version mismatches. Call from main. */ +LUA_API void LUAJIT_VERSION_SYM(void); + +#endif diff --git a/builddir/LuaJIT-master/include/lualib.h b/builddir/LuaJIT-master/include/lualib.h new file mode 100644 index 0000000..3a54955 --- /dev/null +++ b/builddir/LuaJIT-master/include/lualib.h @@ -0,0 +1,43 @@ +/* +** Standard library header. +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +*/ + +#ifndef _LUALIB_H +#define _LUALIB_H + +#include "lua.h" + +#define LUA_FILEHANDLE "FILE*" + +#define LUA_COLIBNAME "coroutine" +#define LUA_MATHLIBNAME "math" +#define LUA_STRLIBNAME "string" +#define LUA_TABLIBNAME "table" +#define LUA_IOLIBNAME "io" +#define LUA_OSLIBNAME "os" +#define LUA_LOADLIBNAME "package" +#define LUA_DBLIBNAME "debug" +#define LUA_BITLIBNAME "bit" +#define LUA_JITLIBNAME "jit" +#define LUA_FFILIBNAME "ffi" + +LUALIB_API int luaopen_base(lua_State *L); +LUALIB_API int luaopen_math(lua_State *L); +LUALIB_API int luaopen_string(lua_State *L); +LUALIB_API int luaopen_table(lua_State *L); +LUALIB_API int luaopen_io(lua_State *L); +LUALIB_API int luaopen_os(lua_State *L); +LUALIB_API int luaopen_package(lua_State *L); +LUALIB_API int luaopen_debug(lua_State *L); +LUALIB_API int luaopen_bit(lua_State *L); +LUALIB_API int luaopen_jit(lua_State *L); +LUALIB_API int luaopen_ffi(lua_State *L); + +LUALIB_API void luaL_openlibs(lua_State *L); + +#ifndef lua_assert +#define lua_assert(x) ((void)0) +#endif + +#endif diff --git a/builddir/curl-master/COPYING b/builddir/curl-master/COPYING new file mode 100644 index 0000000..6b5d59f --- /dev/null +++ b/builddir/curl-master/COPYING @@ -0,0 +1,21 @@ +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1996 - 2015, Daniel Stenberg, . + +All rights reserved. + +Permission to use, copy, modify, and distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright +notice and this permission notice appear in all copies. + +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 OF THIRD PARTY RIGHTS. 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. + +Except as contained in this notice, the name of a copyright holder shall not +be used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization of the copyright holder. diff --git a/builddir/curl-master/bin/libcurl.dll b/builddir/curl-master/bin/libcurl.dll new file mode 100644 index 0000000..a806f31 Binary files /dev/null and b/builddir/curl-master/bin/libcurl.dll differ diff --git a/builddir/curl-master/bin/libcurl_imp.exp b/builddir/curl-master/bin/libcurl_imp.exp new file mode 100644 index 0000000..0da082b Binary files /dev/null and b/builddir/curl-master/bin/libcurl_imp.exp differ diff --git a/builddir/curl-master/bin/libcurl_imp.lib b/builddir/curl-master/bin/libcurl_imp.lib new file mode 100644 index 0000000..4abb115 Binary files /dev/null and b/builddir/curl-master/bin/libcurl_imp.lib differ diff --git a/builddir/curl-master/include/README b/builddir/curl-master/include/README new file mode 100644 index 0000000..3e52a1d --- /dev/null +++ b/builddir/curl-master/include/README @@ -0,0 +1,55 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +Include files for libcurl, external users. + +They're all placed in the curl subdirectory here for better fit in any kind +of environment. You must include files from here using... + + #include + +... style and point the compiler's include path to the directory holding the +curl subdirectory. It makes it more likely to survive future modifications. + +NOTE FOR LIBCURL HACKERS + +The following notes apply to libcurl version 7.19.0 and later. + +* The distributed curl/curlbuild.h file is only intended to be used on systems + which can not run the also distributed configure script. + +* The distributed curlbuild.h file is generated as a copy of curlbuild.h.dist + when the libcurl source code distribution archive file is originally created. + +* If you check out from git on a non-configure platform, you must run the + appropriate buildconf* script to set up curlbuild.h and other local files + before being able of compiling the library. + +* On systems capable of running the configure script, the configure process + will overwrite the distributed include/curl/curlbuild.h file with one that + is suitable and specific to the library being configured and built, which + is generated from the include/curl/curlbuild.h.in template file. + +* If you intend to distribute an already compiled libcurl library you _MUST_ + also distribute along with it the generated curl/curlbuild.h which has been + used to compile it. Otherwise the library will be of no use for the users of + the library that you have built. It is _your_ responsibility to provide this + file. No one at the cURL project can know how you have built the library. + +* File curl/curlbuild.h includes platform and configuration dependent info, + and must not be modified by anyone. Configure script generates it for you. + +* We cannot assume anything else but very basic compiler features being + present. While libcurl requires an ANSI C compiler to build, some of the + earlier ANSI compilers clearly can't deal with some preprocessor operators. + +* Newlines must remain unix-style for older compilers' sake. + +* Comments must be written in the old-style /* unnested C-fashion */ + +To figure out how to do good and portable checks for features, operating +systems or specific hardwarare, a very good resource is Bjorn Reese's +collection at http://predef.sf.net/ diff --git a/builddir/curl-master/include/curl/curl.h b/builddir/curl-master/include/curl/curl.h new file mode 100644 index 0000000..516ede6 --- /dev/null +++ b/builddir/curl-master/include/curl/curl.h @@ -0,0 +1,2440 @@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * If you have libcurl problems, all docs and details are found here: + * https://curl.haxx.se/libcurl/ + * + * curl-library mailing list subscription and unsubscription web interface: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + */ + +#include "curlver.h" /* libcurl version defines */ +#include "curlbuild.h" /* libcurl build definitions */ +#include "curlrules.h" /* libcurl rules enforcement */ + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && \ + !defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#include +#include + +#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) +/* Needed for __FreeBSD_version symbol definition */ +#include +#endif + +/* The include stuff here below is mainly for time_t! */ +#include +#include + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ + defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include +#include +#endif +#endif + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on systems that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ + defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ + (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) +#include +#endif + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif + +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) +#include +#endif + +#ifdef __BEOS__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Curl_easy CURL; + +/* + * libcurl external API function linkage decorations. + */ + +#ifdef CURL_STATICLIB +# define CURL_EXTERN +#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) +# if defined(BUILDING_LIBCURL) +# define CURL_EXTERN __declspec(dllexport) +# else +# define CURL_EXTERN __declspec(dllimport) +# endif +#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) +# define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +# define CURL_EXTERN +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field, see also + CURL_HTTPPOST_LARGE */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist* contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ + +/* specified content is a file name */ +#define CURL_HTTPPOST_FILENAME (1<<0) +/* specified content is a file name */ +#define CURL_HTTPPOST_READFILE (1<<1) +/* name is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRNAME (1<<2) +/* contents is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRCONTENTS (1<<3) +/* upload file from buffer */ +#define CURL_HTTPPOST_BUFFER (1<<4) +/* upload file from pointer contents */ +#define CURL_HTTPPOST_PTRBUFFER (1<<5) +/* upload file contents by using the regular read callback to get the data and + pass the given pointer as custom pointer */ +#define CURL_HTTPPOST_CALLBACK (1<<6) +/* use size in 'contentlen', added in 7.46.0 */ +#define CURL_HTTPPOST_LARGE (1<<7) + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ + void *userp; /* custom pointer used for + HTTPPOST_CALLBACK posts */ + curl_off_t contentlen; /* alternative length of contents + field. Used if CURL_HTTPPOST_LARGE is + set. Added in 7.46.0 */ +}; + +/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered + deprecated but was the only choice up until 7.31.0 */ +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in + 7.32.0, it avoids floating point and provides more detailed information. */ +typedef int (*curl_xferinfo_callback)(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow); + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. The practical minimum is about + 400 bytes since libcurl uses a buffer of this size as a scratch area + (unrelated to network send operations). */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif + +#ifndef CURL_MAX_HTTP_HEADER +/* The only reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause reallocs + infinitely */ +#define CURL_MAX_HTTP_HEADER (100*1024) +#endif + +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + + + +/* enumeration of file types */ +typedef enum { + CURLFILETYPE_FILE = 0, + CURLFILETYPE_DIRECTORY, + CURLFILETYPE_SYMLINK, + CURLFILETYPE_DEVICE_BLOCK, + CURLFILETYPE_DEVICE_CHAR, + CURLFILETYPE_NAMEDPIPE, + CURLFILETYPE_SOCKET, + CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ + + CURLFILETYPE_UNKNOWN /* should never occur */ +} curlfiletype; + +#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) +#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) +#define CURLFINFOFLAG_KNOWN_TIME (1<<2) +#define CURLFINFOFLAG_KNOWN_PERM (1<<3) +#define CURLFINFOFLAG_KNOWN_UID (1<<4) +#define CURLFINFOFLAG_KNOWN_GID (1<<5) +#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) +#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) + +/* Content of this structure depends on information which is known and is + achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man + page for callbacks returning this structure -- some fields are mandatory, + some others are optional. The FLAG field has special meaning. */ +struct curl_fileinfo { + char *filename; + curlfiletype filetype; + time_t time; + unsigned int perm; + int uid; + int gid; + curl_off_t size; + long int hardlinks; + + struct { + /* If some of these fields is not NULL, it is a pointer to b_data. */ + char *time; + char *perm; + char *user; + char *group; + char *target; /* pointer to the target filename of a symlink */ + } strings; + + unsigned int flags; + + /* used internally */ + char * b_data; + size_t b_size; + size_t b_used; +}; + +/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ +#define CURL_CHUNK_BGN_FUNC_OK 0 +#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ +#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ + +/* if splitting of data transfer is enabled, this callback is called before + download of an individual chunk started. Note that parameter "remains" works + only for FTP wildcard downloading (for now), otherwise is not used */ +typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, + void *ptr, + int remains); + +/* return codes for CURLOPT_CHUNK_END_FUNCTION */ +#define CURL_CHUNK_END_FUNC_OK 0 +#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ + +/* If splitting of data transfer is enabled this callback is called after + download of an individual chunk finished. + Note! After this callback was set then it have to be called FOR ALL chunks. + Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. + This is the reason why we don't need "transfer_info" parameter in this + callback and we are not interested in "remains" parameter too. */ +typedef long (*curl_chunk_end_callback)(void *ptr); + +/* return codes for FNMATCHFUNCTION */ +#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ +#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ +#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ + +/* callback type for wildcard downloading pattern matching. If the + string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ +typedef int (*curl_fnmatch_callback)(void *ptr, + const char *pattern, + const char *string); + +/* These are the return codes for the seek callbacks */ +#define CURL_SEEKFUNC_OK 0 +#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so + libcurl might try other means instead */ +typedef int (*curl_seek_callback)(void *instream, + curl_off_t offset, + int origin); /* 'whence' */ + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +/* The return code from the sockopt_callback can signal information back + to libcurl: */ +#define CURL_SOCKOPT_OK 0 +#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return + CURLE_ABORTED_BY_CALLBACK */ +#define CURL_SOCKOPT_ALREADY_CONNECTED 2 + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it + turned really ugly and painful on the systems that + lack this type */ + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +typedef int +(*curl_closesocket_callback)(void *clientp, curl_socket_t item); + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +#define CURL_DID_MEMORY_FUNC_TYPEDEFS +#endif + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for + 7.17.0, reused in April 2011 for 7.21.5] */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for + 7.15.4, reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server + [was obsoleted in August 2007 for 7.17.0, + reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. + [was obsoleted in August 2007 for 7.17.0, + reused in July 2014 for 7.38.0] */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ + CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ + CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ + CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ + CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the + session will be queued */ + CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not + match */ + CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ + CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer + */ + CURL_LAST /* never use! */ +} CURLcode; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Previously obsolete error code re-used in 7.38.0 */ +#define CURLE_OBSOLETE16 CURLE_HTTP2 + +/* Previously obsolete error codes re-used in 7.24.0 */ +#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED +#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT + +/* compatibility with older names */ +#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING + +/* The following were added in 7.21.5, April 2011 */ +#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +/* Provide defines for really old option names */ +#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ +#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ +#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA + +/* Since long deprecated options with no code in the lib that does anything + with them. */ +#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 +#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an + OpenSSL SSL_CTX */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +/* + * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: + * + * CURLAUTH_NONE - No HTTP authentication + * CURLAUTH_BASIC - HTTP Basic authentication (default) + * CURLAUTH_DIGEST - HTTP Digest authentication + * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication + * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) + * CURLAUTH_NTLM - HTTP NTLM authentication + * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour + * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper + * CURLAUTH_ONLY - Use together with a single other type to force no + * authentication or just that single type + * CURLAUTH_ANY - All fine types set + * CURLAUTH_ANYSAFE - All fine types except Basic + */ + +#define CURLAUTH_NONE ((unsigned long)0) +#define CURLAUTH_BASIC (((unsigned long)1)<<0) +#define CURLAUTH_DIGEST (((unsigned long)1)<<1) +#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) +/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ +#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE +#define CURLAUTH_NTLM (((unsigned long)1)<<3) +#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) +#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) +#define CURLAUTH_ONLY (((unsigned long)1)<<31) +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ +#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ + +#define CURL_ERROR_SIZE 256 + +enum curl_khtype { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS +}; + +struct curl_khkey { + const char *key; /* points to a zero-terminated string encoded with base64 + if len is zero, otherwise to the "raw" data */ + size_t len; + enum curl_khtype keytype; +}; + +/* this is the set of return values expected from the curl_sshkeycallback + callback */ +enum curl_khstat { + CURLKHSTAT_FINE_ADD_TO_FILE, + CURLKHSTAT_FINE, + CURLKHSTAT_REJECT, /* reject the connection, return an error */ + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so + this causes a CURLE_DEFER error but otherwise the + connection will be left intact etc */ + CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ +}; + +/* this is the set of status codes pass in to the callback */ +enum curl_khmatch { + CURLKHMATCH_OK, /* match */ + CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ + CURLKHMATCH_MISSING, /* no matching host/key found */ + CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ +}; + +typedef int + (*curl_sshkeycallback) (CURL *easy, /* easy handle */ + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch, /* libcurl's view on the keys */ + void *clientp); /* custom pointer passed from app */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ + +/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the + name of improving interoperability with older servers. Some SSL libraries + have introduced work-arounds for this flaw but those work-arounds sometimes + make the SSL communication fail. To regain functionality with those broken + servers, a user can this way allow the vulnerability back. */ +#define CURLSSLOPT_ALLOW_BEAST (1<<0) + +/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those + SSL backends where such behavior is present. */ +#define CURLSSLOPT_NO_REVOKE (1<<1) + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +typedef enum { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} curl_ftpcreatedir; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* bitmask defines for CURLOPT_HEADEROPT */ +#define CURLHEADER_UNIFIED 0 +#define CURLHEADER_SEPARATE (1<<0) + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_IMAP (1<<12) +#define CURLPROTO_IMAPS (1<<13) +#define CURLPROTO_POP3 (1<<14) +#define CURLPROTO_POP3S (1<<15) +#define CURLPROTO_SMTP (1<<16) +#define CURLPROTO_SMTPS (1<<17) +#define CURLPROTO_RTSP (1<<18) +#define CURLPROTO_RTMP (1<<19) +#define CURLPROTO_RTMPT (1<<20) +#define CURLPROTO_RTMPE (1<<21) +#define CURLPROTO_RTMPTE (1<<22) +#define CURLPROTO_RTMPS (1<<23) +#define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_SMB (1<<26) +#define CURLPROTO_SMBS (1<<27) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_STRINGPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the + string options from the header file */ + +/* name is uppercase CURLOPT_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif + +#ifdef CURL_ISOCPP +#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define STRINGPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(WRITEDATA, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, STRINGPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, STRINGPOINT, 4), + + /* "user:password;options" to use when fetching. */ + CINIT(USERPWD, STRINGPOINT, 5), + + /* "user:password" to use with proxy. */ + CINIT(PROXYUSERPWD, STRINGPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, STRINGPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(READDATA, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. If this is not used, error messages go to stderr instead: */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, STRINGPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, STRINGPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, STRINGPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, STRINGPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind. This + list is also used for RTSP (in spite of its name) */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, STRINGPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, STRINGPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(HEADERDATA, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, STRINGPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, STRINGPOINT, 36), + + /* FILE handle to use instead of stderr */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* DEPRECATED + * Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION + callbacks */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), +#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, STRINGPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, STRINGPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, STRINGPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, STRINGPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, STRINGPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects are + OK within this time, then fine... This only aborts the connect phase. */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, STRINGPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, STRINGPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, STRINGPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, STRINGPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, STRINGPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, STRINGPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. Before 7.21.6, this was known as + CURLOPT_ENCODING */ + CINIT(ACCEPT_ENCODING, STRINGPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( + it also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, STRINGPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLUSESSL_TRY - try using SSL, proceed anyway otherwise + CURLUSESSL_CONTROL - SSL for the control connection or fail + CURLUSESSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, STRINGPOINT, 134), + + /* feed cookie into cookie engine */ + CINIT(COOKIELIST, STRINGPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, STRINGPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, STRINGPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, STRINGPOINT, 173), + CINIT(PASSWORD, STRINGPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, STRINGPOINT, 175), + CINIT(PROXYPASSWORD, STRINGPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, STRINGPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */ + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + /* set the SMTP mail originator */ + CINIT(MAIL_FROM, STRINGPOINT, 186), + + /* set the list of SMTP mail receiver(s) */ + CINIT(MAIL_RCPT, OBJECTPOINT, 187), + + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + + /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ + CINIT(RTSP_REQUEST, LONG, 189), + + /* The RTSP session identifier */ + CINIT(RTSP_SESSION_ID, STRINGPOINT, 190), + + /* The RTSP stream URI */ + CINIT(RTSP_STREAM_URI, STRINGPOINT, 191), + + /* The Transport: header to use in RTSP requests */ + CINIT(RTSP_TRANSPORT, STRINGPOINT, 192), + + /* Manually initialize the client RTSP CSeq for this handle */ + CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + + /* Manually initialize the server RTSP CSeq for this handle */ + CINIT(RTSP_SERVER_CSEQ, LONG, 194), + + /* The stream to pass to INTERLEAVEFUNCTION. */ + CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + + /* Let the application define a custom write method for RTP data */ + CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + + /* Turn on wildcard matching */ + CINIT(WILDCARDMATCH, LONG, 197), + + /* Directory matching callback called before downloading of an + individual file (chunk) started */ + CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + + /* Directory matching callback called after the file (chunk) + was downloaded, or skipped */ + CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + + /* Change match (fnmatch-like) callback for wildcard matching */ + CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + + /* Let the application define custom chunk data pointer */ + CINIT(CHUNK_DATA, OBJECTPOINT, 201), + + /* FNMATCH_FUNCTION user pointer */ + CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + + /* send linked-list of name:port:address sets */ + CINIT(RESOLVE, OBJECTPOINT, 203), + + /* Set a username for authenticated TLS */ + CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204), + + /* Set a password for authenticated TLS */ + CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205), + + /* Set authentication type for authenticated TLS */ + CINIT(TLSAUTH_TYPE, STRINGPOINT, 206), + + /* Set to 1 to enable the "TE:" header in HTTP requests to ask for + compressed transfer-encoded responses. Set to 0 to disable the use of TE: + in outgoing requests. The current default is 0, but it might change in a + future libcurl release. + + libcurl will ask for the compressed methods it knows of, and if that + isn't any, it will not ask for transfer-encoding at all even if this + option is set to 1. + + */ + CINIT(TRANSFER_ENCODING, LONG, 207), + + /* Callback function for closing socket (instead of close(2)). The callback + should have type curl_closesocket_callback */ + CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), + CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), + + /* allow GSSAPI credential delegation */ + CINIT(GSSAPI_DELEGATION, LONG, 210), + + /* Set the name servers to use for DNS resolution */ + CINIT(DNS_SERVERS, STRINGPOINT, 211), + + /* Time-out accept operations (currently for FTP only) after this amount + of miliseconds. */ + CINIT(ACCEPTTIMEOUT_MS, LONG, 212), + + /* Set TCP keepalive */ + CINIT(TCP_KEEPALIVE, LONG, 213), + + /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ + CINIT(TCP_KEEPIDLE, LONG, 214), + CINIT(TCP_KEEPINTVL, LONG, 215), + + /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ + CINIT(SSL_OPTIONS, LONG, 216), + + /* Set the SMTP auth originator */ + CINIT(MAIL_AUTH, STRINGPOINT, 217), + + /* Enable/disable SASL initial response */ + CINIT(SASL_IR, LONG, 218), + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_xferinfo_callback + * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ + CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), + + /* The XOAUTH2 bearer token */ + CINIT(XOAUTH2_BEARER, STRINGPOINT, 220), + + /* Set the interface string to use as outgoing network + * interface for DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_INTERFACE, STRINGPOINT, 221), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), + + /* Set authentication options directly */ + CINIT(LOGIN_OPTIONS, STRINGPOINT, 224), + + /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_NPN, LONG, 225), + + /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_ALPN, LONG, 226), + + /* Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. */ + CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), + + /* This points to a linked list of headers used for proxy requests only, + struct curl_slist kind */ + CINIT(PROXYHEADER, OBJECTPOINT, 228), + + /* Pass in a bitmask of "header options" */ + CINIT(HEADEROPT, LONG, 229), + + /* The public key in DER form used to validate the peer public key + this option is used only if SSL_VERIFYPEER is true */ + CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230), + + /* Path to Unix domain socket */ + CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231), + + /* Set if we should verify the certificate status. */ + CINIT(SSL_VERIFYSTATUS, LONG, 232), + + /* Set if we should enable TLS false start. */ + CINIT(SSL_FALSESTART, LONG, 233), + + /* Do not squash dot-dot sequences */ + CINIT(PATH_AS_IS, LONG, 234), + + /* Proxy Service Name */ + CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235), + + /* Service Name */ + CINIT(SERVICE_NAME, STRINGPOINT, 236), + + /* Wait/don't wait for pipe/mutex to clarify */ + CINIT(PIPEWAIT, LONG, 237), + + /* Set the protocol used when curl is given a URL without a protocol */ + CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238), + + /* Set stream weight, 1 - 256 (default is 16) */ + CINIT(STREAM_WEIGHT, LONG, 239), + + /* Set stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS, OBJECTPOINT, 240), + + /* Set E-xclusive stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241), + + /* Do not send any tftp option requests to the server */ + CINIT(TFTP_NO_OPTIONS, LONG, 242), + + /* Linked-list of host:port:connect-to-host:connect-to-port, + overrides the URL's host:port (only for the network layer) */ + CINIT(CONNECT_TO, OBJECTPOINT, 243), + + /* Set TCP Fast Open */ + CINIT(TCP_FASTOPEN, LONG, 244), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2011 */ + +/* This was added in version 7.19.1 */ +#define CURLOPT_POST301 CURLOPT_POSTREDIR + +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ + CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 + Upgrade */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + +/* Convenience definition simple because the name of the version is HTTP/2 and + not 2.0. The 2_0 version of the enum name was set while the version was + still planned to be 2.0 and we stick to it for compatibility. */ +#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 + +/* + * Public API enums for RTSP requests + */ +enum { + CURL_RTSPREQ_NONE, /* first in list */ + CURL_RTSPREQ_OPTIONS, + CURL_RTSPREQ_DESCRIBE, + CURL_RTSPREQ_ANNOUNCE, + CURL_RTSPREQ_SETUP, + CURL_RTSPREQ_PLAY, + CURL_RTSPREQ_PAUSE, + CURL_RTSPREQ_TEARDOWN, + CURL_RTSPREQ_GET_PARAMETER, + CURL_RTSPREQ_SET_PARAMETER, + CURL_RTSPREQ_RECORD, + CURL_RTSPREQ_RECEIVE, + CURL_RTSPREQ_LAST /* last in list */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, /* TLS 1.x */ + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + CURL_SSLVERSION_TLSv1_0, + CURL_SSLVERSION_TLSv1_1, + CURL_SSLVERSION_TLSv1_2, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + +enum CURL_TLSAUTH { + CURL_TLSAUTH_NONE, + CURL_TLSAUTH_SRP, + CURL_TLSAUTH_LAST /* never use, keep last */ +}; + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 + can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 + | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_303 4 +#define CURL_REDIR_POST_ALL \ + (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + libcurl, see lib/README.curlx for details */ +CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); +CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); + +/* name is uppercase CURLFORM_ */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */ + + CURLFORM_LASTENTRY /* the last unused */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanced function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to + * curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on + * success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, + size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl and before any call of other libcurl functions. + * + * This function is not thread-safe! + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +/* info about the certificate chain, only for OpenSSL builds. Asked + for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +struct curl_certinfo { + int num_of_certs; /* number of certificates with information */ + struct curl_slist **certinfo; /* for each index in this array, there's a + linked list with textual information in the + format "name: value" */ +}; + +/* enum for the different supported SSL backends */ +typedef enum { + CURLSSLBACKEND_NONE = 0, + CURLSSLBACKEND_OPENSSL = 1, + CURLSSLBACKEND_GNUTLS = 2, + CURLSSLBACKEND_NSS = 3, + CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ + CURLSSLBACKEND_GSKIT = 5, + CURLSSLBACKEND_POLARSSL = 6, + CURLSSLBACKEND_CYASSL = 7, + CURLSSLBACKEND_SCHANNEL = 8, + CURLSSLBACKEND_DARWINSSL = 9, + CURLSSLBACKEND_AXTLS = 10, + CURLSSLBACKEND_MBEDTLS = 11 +} curl_sslbackend; + +/* aliases for library clones and renames */ +#define CURLSSLBACKEND_LIBRESSL 1 +#define CURLSSLBACKEND_BORINGSSL 1 +#define CURLSSLBACKEND_WOLFSSL 6 + +/* Information about the SSL library used and the respective internal SSL + handle, which can be used to obtain further information regarding the + connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ +struct curl_tlssessioninfo { + curl_sslbackend backend; + void *internals; +}; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_SOCKET 0x500000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_SLIST + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43, + CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, + CURLINFO_TLS_SSL_PTR = CURLINFO_SLIST + 45, + CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 46 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL +#define CURL_GLOBAL_ACK_EINTR (1<<2) + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internally to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + +typedef struct Curl_share CURLSH; + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* 4 out of memory */ + CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basically all programs ever that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FOURTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported + (deprecated) */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported + (deprecated) */ +#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ +#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are + supported */ +#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ +#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ +#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ +#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper + is suported */ +#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ +#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ +#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ +#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ +#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used + for cookie domain verification */ + + /* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +/* + * NAME curl_easy_pause() + * + * DESCRIPTION + * + * The curl_easy_pause function pauses or unpauses transfers. Select the new + * state by setting the bitmask, use the convenience defines below. + * + */ +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" + +/* the typechecker doesn't work in C++ (yet) */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ + !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) +#include "typecheck-gcc.h" +#else +#if defined(__STDC__) && (__STDC__ >= 1) +/* This preprocessor magic that replaces a call with the exact same call is + only done to make sure application authors pass exactly three arguments + to these functions. */ +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) +#endif /* __STDC__ >= 1 */ +#endif /* gcc >= 4.3 && !__cplusplus */ + +#endif /* __CURL_CURL_H */ diff --git a/builddir/curl-master/include/curl/curlbuild.h b/builddir/curl-master/include/curl/curlbuild.h new file mode 100644 index 0000000..eb3afab --- /dev/null +++ b/builddir/curl-master/include/curl/curlbuild.h @@ -0,0 +1,197 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ +#define CURL_PULL_WS2TCPIP_H +#ifdef CURL_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# include +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +/* #undef CURL_PULL_SYS_TYPES_H */ +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +/* #undef CURL_PULL_STDINT_H */ +#ifdef CURL_PULL_STDINT_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +/* #undef CURL_PULL_INTTYPES_H */ +#ifdef CURL_PULL_INTTYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +/* #undef CURL_PULL_SYS_SOCKET_H */ +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/poll.h must be included by the external interface. */ +/* #undef CURL_PULL_SYS_POLL_H */ +#ifdef CURL_PULL_SYS_POLL_H +# include +#endif + +/* The size of `long', as computed by sizeof. */ +#define CURL_SIZEOF_LONG 4 + +/* Integral data type used for curl_socklen_t. */ +#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* Signed integral data type used for curl_off_t. */ +#define CURL_TYPEOF_CURL_OFF_T long long + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_T "lld" + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_TU "llu" + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#define CURL_FORMAT_OFF_T "%lld" + +/* The size of `curl_off_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_OFF_T 8 + +/* curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_T LL + +/* unsigned curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_TU ULL + +#endif /* __CURL_CURLBUILD_H */ diff --git a/builddir/curl-master/include/curl/curlrules.h b/builddir/curl-master/include/curl/curlrules.h new file mode 100644 index 0000000..55d21f6 --- /dev/null +++ b/builddir/curl-master/include/curl/curlrules.h @@ -0,0 +1,262 @@ +#ifndef __CURL_CURLRULES_H +#define __CURL_CURLRULES_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* COMPILE TIME SANITY CHECKS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * All checks done in this file are intentionally placed in a public + * header file which is pulled by curl/curl.h when an application is + * being built using an already built libcurl library. Additionally + * this file is also included and used when building the library. + * + * If compilation fails on this file it is certainly sure that the + * problem is elsewhere. It could be a problem in the curlbuild.h + * header file, or simply that you are using different compilation + * settings than those used to build the library. + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * Do not deactivate any check, these are done to make sure that the + * library is properly built and used. + * + * You can find further help on the libcurl development mailing list: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * NOTE 2 + * ------ + * + * Some of the following compile time checks are based on the fact + * that the dimension of a constant array can not be a negative one. + * In this way if the compile time verification fails, the compilation + * will fail issuing an error. The error description wording is compiler + * dependent but it will be quite similar to one of the following: + * + * "negative subscript or subscript is too large" + * "array must have at least one element" + * "-1 is an illegal array size" + * "size of array is negative" + * + * If you are building an application which tries to use an already + * built libcurl library and you are getting this kind of errors on + * this file, it is a clear indication that there is a mismatch between + * how the library was built and how you are trying to use it for your + * application. Your already compiled or binary library provider is the + * only one who can give you the details you need to properly use it. + */ + +/* + * Verify that some macros are actually defined. + */ + +#ifndef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing +#endif + +#ifndef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing +#endif + +/* + * Macros private to this header file. + */ + +#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 + +#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 + +/* + * Verify that the size previously defined and expected for long + * is the same as the one reported by sizeof() at compile time. + */ + +typedef char + __curl_rule_01__ + [CurlchkszEQ(long, CURL_SIZEOF_LONG)]; + +/* + * Verify that the size previously defined and expected for + * curl_off_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_02__ + [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; + +/* + * Verify at compile time that the size of curl_off_t as reported + * by sizeof() is greater or equal than the one reported for long + * for the current compilation. + */ + +typedef char + __curl_rule_03__ + [CurlchkszGE(curl_off_t, long)]; + +/* + * Verify that the size previously defined and expected for + * curl_socklen_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_04__ + [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; + +/* + * Verify at compile time that the size of curl_socklen_t as reported + * by sizeof() is greater or equal than the one reported for int for + * the current compilation. + */ + +typedef char + __curl_rule_05__ + [CurlchkszGE(curl_socklen_t, int)]; + +/* ================================================================ */ +/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ +/* ================================================================ */ + +/* + * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow + * these to be visible and exported by the external libcurl interface API, + * while also making them visible to the library internals, simply including + * curl_setup.h, without actually needing to include curl.h internally. + * If some day this section would grow big enough, all this should be moved + * to its own header file. + */ + +/* + * Figure out if we can use the ## preprocessor operator, which is supported + * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ + * or __cplusplus so we need to carefully check for them too. + */ + +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +/* + * Macros for minimum-width signed and unsigned curl_off_t integer constants. + */ + +#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) +# define __CURL_OFF_T_C_HLPR2(x) x +# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) +#else +# ifdef CURL_ISOCPP +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix +# else +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix +# endif +# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) +#endif + +/* + * Get rid of macros private to this header file. + */ + +#undef CurlchkszEQ +#undef CurlchkszGE + +/* + * Get rid of macros not intended to exist beyond this point. + */ + +#undef CURL_PULL_WS2TCPIP_H +#undef CURL_PULL_SYS_TYPES_H +#undef CURL_PULL_SYS_SOCKET_H +#undef CURL_PULL_SYS_POLL_H +#undef CURL_PULL_STDINT_H +#undef CURL_PULL_INTTYPES_H + +#undef CURL_TYPEOF_CURL_SOCKLEN_T +#undef CURL_TYPEOF_CURL_OFF_T + +#ifdef CURL_NO_OLDIES +#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */ +#endif + +#endif /* __CURL_CURLRULES_H */ diff --git a/builddir/curl-master/include/curl/curlver.h b/builddir/curl-master/include/curl/curlver.h new file mode 100644 index 0000000..f5f9564 --- /dev/null +++ b/builddir/curl-master/include/curl/curlver.h @@ -0,0 +1,77 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the global package copyright */ +#define LIBCURL_COPYRIGHT "1996 - 2016 Daniel Stenberg, ." + +/* This is the version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.50.0-DEV" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 50 +#define LIBCURL_VERSION_PATCH 0 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. + + Note: This define is the full hex number and _does not_ use the + CURL_VERSION_BITS() macro since curl's own configure script greps for it + and needs it to contain the full number. +*/ +#define LIBCURL_VERSION_NUM 0x073200 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in git, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBCURL_TIMESTAMP "DEV" + +#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) +#define CURL_AT_LEAST_VERSION(x,y,z) \ + (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) + +#endif /* __CURL_CURLVER_H */ diff --git a/builddir/curl-master/include/curl/easy.h b/builddir/curl-master/include/curl/easy.h new file mode 100644 index 0000000..afc766c --- /dev/null +++ b/builddir/curl-master/include/curl/easy.h @@ -0,0 +1,102 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN CURL *curl_easy_init(void); +CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); +CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); +CURL_EXTERN void curl_easy_cleanup(CURL *curl); + +/* + * NAME curl_easy_getinfo() + * + * DESCRIPTION + * + * Request internal information from the curl session with this function. The + * third argument MUST be a pointer to a long, a pointer to a char * or a + * pointer to a double (as the documentation describes elsewhere). The data + * pointed to will be filled in accordingly and can be relied upon only if the + * function returns CURLE_OK. This function is intended to get used *AFTER* a + * performed transfer, all results from this function are undefined until the + * transfer is completed. + */ +CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); + + +/* + * NAME curl_easy_duphandle() + * + * DESCRIPTION + * + * Creates a new curl session handle with the same options set for the handle + * passed in. Duplicating a handle could only be a matter of cloning data and + * options, internal state info and things like persistent connections cannot + * be transferred. It is useful in multithreaded applications when you can run + * curl_easy_duphandle() for each new thread to avoid a series of identical + * curl_easy_setopt() invokes in every thread. + */ +CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl); + +/* + * NAME curl_easy_reset() + * + * DESCRIPTION + * + * Re-initializes a CURL handle to the default values. This puts back the + * handle to the same state as it was in when it was just created. + * + * It does keep: live connections, the Session ID cache, the DNS cache and the + * cookies. + */ +CURL_EXTERN void curl_easy_reset(CURL *curl); + +/* + * NAME curl_easy_recv() + * + * DESCRIPTION + * + * Receives data from the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, + size_t *n); + +/* + * NAME curl_easy_send() + * + * DESCRIPTION + * + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, + size_t buflen, size_t *n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/builddir/curl-master/include/curl/mprintf.h b/builddir/curl-master/include/curl/mprintf.h new file mode 100644 index 0000000..e20f546 --- /dev/null +++ b/builddir/curl-master/include/curl/mprintf.h @@ -0,0 +1,50 @@ +#ifndef __CURL_MPRINTF_H +#define __CURL_MPRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include +#include /* needed for FILE */ +#include "curl.h" /* for CURL_EXTERN */ + +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN int curl_mprintf(const char *format, ...); +CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); +CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); +CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, + const char *format, ...); +CURL_EXTERN int curl_mvprintf(const char *format, va_list args); +CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); +CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); +CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, + const char *format, va_list args); +CURL_EXTERN char *curl_maprintf(const char *format, ...); +CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); + +#ifdef __cplusplus +} +#endif + +#endif /* __CURL_MPRINTF_H */ diff --git a/builddir/curl-master/include/curl/multi.h b/builddir/curl-master/include/curl/multi.h new file mode 100644 index 0000000..7a1040f --- /dev/null +++ b/builddir/curl-master/include/curl/multi.h @@ -0,0 +1,435 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + This is an "external" header file. Don't give away any internals here! + + GOALS + + o Enable a "pull" interface. The application that uses libcurl decides where + and when to ask libcurl to get/send data. + + o Enable multiple simultaneous transfers in the same thread without making it + complicated for the application. + + o Enable the application to select() on its own file descriptors and curl's + file descriptors simultaneous easily. + +*/ + +/* + * This header file should not really need to include "curl.h" since curl.h + * itself includes this file and we expect user applications to do #include + * without the need for especially including multi.h. + * + * For some reason we added this include here at one point, and rather than to + * break existing (wrongly written) libcurl applications, we leave it as-is + * but with this warning attached. + */ +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Curl_multi CURLM; + +typedef enum { + CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or + curl_multi_socket*() soon */ + CURLM_OK, + CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ + CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ + CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ + CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ + CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ + CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was + attempted to get added - again */ + CURLM_LAST +} CURLMcode; + +/* just to make code nicer when using curl_multi_socket() you can now check + for CURLM_CALL_MULTI_SOCKET too in the same style it works for + curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ +#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM + +/* bitmask bits for CURLMOPT_PIPELINING */ +#define CURLPIPE_NOTHING 0L +#define CURLPIPE_HTTP1 1L +#define CURLPIPE_MULTIPLEX 2L + +typedef enum { + CURLMSG_NONE, /* first, not used */ + CURLMSG_DONE, /* This easy handle has completed. 'result' contains + the CURLcode of the transfer */ + CURLMSG_LAST /* last, not used */ +} CURLMSG; + +struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; +}; +typedef struct CURLMsg CURLMsg; + +/* Based on poll(2) structure and values. + * We don't use pollfd and POLL* constants explicitly + * to cover platforms without poll(). */ +#define CURL_WAIT_POLLIN 0x0001 +#define CURL_WAIT_POLLPRI 0x0002 +#define CURL_WAIT_POLLOUT 0x0004 + +struct curl_waitfd { + curl_socket_t fd; + short events; + short revents; /* not supported yet */ +}; + +/* + * Name: curl_multi_init() + * + * Desc: inititalize multi-style curl usage + * + * Returns: a new CURLM handle to use in all 'curl_multi' functions. + */ +CURL_EXTERN CURLM *curl_multi_init(void); + +/* + * Name: curl_multi_add_handle() + * + * Desc: add a standard curl handle to the multi stack + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_remove_handle() + * + * Desc: removes a curl handle from the multi stack again + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_fdset() + * + * Desc: Ask curl for its fd_set sets. The app can use these to select() or + * poll() on. We want curl_multi_perform() called as soon as one of + * them are ready. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); + +/* + * Name: curl_multi_wait() + * + * Desc: Poll on all fds within a CURLM set as well as any + * additional fds passed to the function. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret); + + /* + * Name: curl_multi_perform() + * + * Desc: When the app thinks there's data available for curl it calls this + * function to read/write whatever there is right now. This returns + * as soon as the reads and writes are done. This function does not + * require that there actually is data available for reading or that + * data can be written, it can be called just in case. It returns + * the number of handles that still transfer data in the second + * argument's integer-pointer. + * + * Returns: CURLMcode type, general multi error code. *NOTE* that this only + * returns errors etc regarding the whole multi stack. There might + * still have occurred problems on invidual transfers even when this + * returns OK. + */ +CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, + int *running_handles); + + /* + * Name: curl_multi_cleanup() + * + * Desc: Cleans up and removes a whole multi stack. It does not free or + * touch any individual easy handles in any way. We need to define + * in what state those handles will be if this function is called + * in the middle of a transfer. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); + +/* + * Name: curl_multi_info_read() + * + * Desc: Ask the multi handle if there's any messages/informationals from + * the individual transfers. Messages include informationals such as + * error code from the transfer or just the fact that a transfer is + * completed. More details on these should be written down as well. + * + * Repeated calls to this function will return a new struct each + * time, until a special "end of msgs" struct is returned as a signal + * that there is no more to get at this point. + * + * The data the returned pointer points to will not survive calling + * curl_multi_cleanup(). + * + * The 'CURLMsg' struct is meant to be very simple and only contain + * very basic informations. If more involved information is wanted, + * we will provide the particular "transfer handle" in that struct + * and that should/could/would be used in subsequent + * curl_easy_getinfo() calls (or similar). The point being that we + * must never expose complex structs to applications, as then we'll + * undoubtably get backwards compatibility problems in the future. + * + * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out + * of structs. It also writes the number of messages left in the + * queue (after this read) in the integer the second argument points + * to. + */ +CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, + int *msgs_in_queue); + +/* + * Name: curl_multi_strerror() + * + * Desc: The curl_multi_strerror function may be used to turn a CURLMcode + * value into the equivalent human readable error string. This is + * useful for printing meaningful error messages. + * + * Returns: A pointer to a zero-terminated error message. + */ +CURL_EXTERN const char *curl_multi_strerror(CURLMcode); + +/* + * Name: curl_multi_socket() and + * curl_multi_socket_all() + * + * Desc: An alternative version of curl_multi_perform() that allows the + * application to pass in one of the file descriptors that have been + * detected to have "action" on them and let libcurl perform. + * See man page for details. + */ +#define CURL_POLL_NONE 0 +#define CURL_POLL_IN 1 +#define CURL_POLL_OUT 2 +#define CURL_POLL_INOUT 3 +#define CURL_POLL_REMOVE 4 + +#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD + +#define CURL_CSELECT_IN 0x01 +#define CURL_CSELECT_OUT 0x02 +#define CURL_CSELECT_ERR 0x04 + +typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp); /* private socket + pointer */ +/* + * Name: curl_multi_timer_callback + * + * Desc: Called by libcurl whenever the library detects a change in the + * maximum number of milliseconds the app is allowed to wait before + * curl_multi_socket() or curl_multi_perform() must be called + * (to allow libcurl's timed events to take place). + * + * Returns: The callback should return zero. + */ +typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp); /* private callback + pointer */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, + curl_socket_t s, + int ev_bitmask, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +#ifndef CURL_ALLOW_OLD_MULTI_SOCKET +/* This macro below was added in 7.16.3 to push users who recompile to use + the new curl_multi_socket_action() instead of the old curl_multi_socket() +*/ +#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) +#endif + +/* + * Name: curl_multi_timeout() + * + * Desc: Returns the maximum number of milliseconds the app is allowed to + * wait before curl_multi_socket() or curl_multi_perform() must be + * called (to allow libcurl's timed events to take place). + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, + long *milliseconds); + +#undef CINIT /* re-using the same name as in curl.h */ + +#ifdef CURL_ISOCPP +#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLMOPT_/**/name = type + number +#endif + +typedef enum { + /* This is the socket callback function pointer */ + CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + + /* This is the argument passed to the socket callback */ + CINIT(SOCKETDATA, OBJECTPOINT, 2), + + /* set to 1 to enable pipelining for this multi handle */ + CINIT(PIPELINING, LONG, 3), + + /* This is the timer callback function pointer */ + CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + + /* This is the argument passed to the timer callback */ + CINIT(TIMERDATA, OBJECTPOINT, 5), + + /* maximum number of entries in the connection cache */ + CINIT(MAXCONNECTS, LONG, 6), + + /* maximum number of (pipelining) connections to one host */ + CINIT(MAX_HOST_CONNECTIONS, LONG, 7), + + /* maximum number of requests in a pipeline */ + CINIT(MAX_PIPELINE_LENGTH, LONG, 8), + + /* a connection with a content-length longer than this + will not be considered for pipelining */ + CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9), + + /* a connection with a chunk length longer than this + will not be considered for pipelining */ + CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10), + + /* a list of site names(+port) that are blacklisted from + pipelining */ + CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11), + + /* a list of server types that are blacklisted from + pipelining */ + CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12), + + /* maximum number of open connections in total */ + CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13), + + /* This is the server push callback function pointer */ + CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14), + + /* This is the argument passed to the server push callback */ + CINIT(PUSHDATA, OBJECTPOINT, 15), + + CURLMOPT_LASTENTRY /* the last unused */ +} CURLMoption; + + +/* + * Name: curl_multi_setopt() + * + * Desc: Sets options for the multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, + CURLMoption option, ...); + + +/* + * Name: curl_multi_assign() + * + * Desc: This function sets an association in the multi handle between the + * given socket and a private pointer of the application. This is + * (only) useful for curl_multi_socket uses. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, + curl_socket_t sockfd, void *sockp); + + +/* + * Name: curl_push_callback + * + * Desc: This callback gets called when a new stream is being pushed by the + * server. It approves or denies the new stream. + * + * Returns: CURL_PUSH_OK or CURL_PUSH_DENY. + */ +#define CURL_PUSH_OK 0 +#define CURL_PUSH_DENY 1 + +struct curl_pushheaders; /* forward declaration only */ + +CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, + size_t num); +CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, + const char *name); + +typedef int (*curl_push_callback)(CURL *parent, + CURL *easy, + size_t num_headers, + struct curl_pushheaders *headers, + void *userp); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/builddir/curl-master/include/curl/stdcheaders.h b/builddir/curl-master/include/curl/stdcheaders.h new file mode 100644 index 0000000..6f0f7f3 --- /dev/null +++ b/builddir/curl-master/include/curl/stdcheaders.h @@ -0,0 +1,33 @@ +#ifndef __STDC_HEADERS_H +#define __STDC_HEADERS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +size_t fread (void *, size_t, size_t, FILE *); +size_t fwrite (const void *, size_t, size_t, FILE *); + +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); + +#endif /* __STDC_HEADERS_H */ diff --git a/builddir/curl-master/include/curl/typecheck-gcc.h b/builddir/curl-master/include/curl/typecheck-gcc.h new file mode 100644 index 0000000..6ec8bcf --- /dev/null +++ b/builddir/curl-master/include/curl/typecheck-gcc.h @@ -0,0 +1,622 @@ +#ifndef __CURL_TYPECHECK_GCC_H +#define __CURL_TYPECHECK_GCC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* wraps curl_easy_setopt() with typechecking */ + +/* To add a new kind of warning, add an + * if(_curl_is_sometype_option(_curl_opt)) + * if(!_curl_is_sometype(value)) + * _curl_easy_setopt_err_sometype(); + * block and define _curl_is_sometype_option, _curl_is_sometype and + * _curl_easy_setopt_err_sometype below + * + * NOTE: We use two nested 'if' statements here instead of the && operator, in + * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x + * when compiling with -Wlogical-op. + * + * To add an option that uses the same type as an existing option, you'll just + * need to extend the appropriate _curl_*_option macro + */ +#define curl_easy_setopt(handle, option, value) \ +__extension__ ({ \ + __typeof__ (option) _curl_opt = option; \ + if(__builtin_constant_p(_curl_opt)) { \ + if(_curl_is_long_option(_curl_opt)) \ + if(!_curl_is_long(value)) \ + _curl_easy_setopt_err_long(); \ + if(_curl_is_off_t_option(_curl_opt)) \ + if(!_curl_is_off_t(value)) \ + _curl_easy_setopt_err_curl_off_t(); \ + if(_curl_is_string_option(_curl_opt)) \ + if(!_curl_is_string(value)) \ + _curl_easy_setopt_err_string(); \ + if(_curl_is_write_cb_option(_curl_opt)) \ + if(!_curl_is_write_cb(value)) \ + _curl_easy_setopt_err_write_callback(); \ + if((_curl_opt) == CURLOPT_READFUNCTION) \ + if(!_curl_is_read_cb(value)) \ + _curl_easy_setopt_err_read_cb(); \ + if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ + if(!_curl_is_ioctl_cb(value)) \ + _curl_easy_setopt_err_ioctl_cb(); \ + if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ + if(!_curl_is_sockopt_cb(value)) \ + _curl_easy_setopt_err_sockopt_cb(); \ + if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ + if(!_curl_is_opensocket_cb(value)) \ + _curl_easy_setopt_err_opensocket_cb(); \ + if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ + if(!_curl_is_progress_cb(value)) \ + _curl_easy_setopt_err_progress_cb(); \ + if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ + if(!_curl_is_debug_cb(value)) \ + _curl_easy_setopt_err_debug_cb(); \ + if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ + if(!_curl_is_ssl_ctx_cb(value)) \ + _curl_easy_setopt_err_ssl_ctx_cb(); \ + if(_curl_is_conv_cb_option(_curl_opt)) \ + if(!_curl_is_conv_cb(value)) \ + _curl_easy_setopt_err_conv_cb(); \ + if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ + if(!_curl_is_seek_cb(value)) \ + _curl_easy_setopt_err_seek_cb(); \ + if(_curl_is_cb_data_option(_curl_opt)) \ + if(!_curl_is_cb_data(value)) \ + _curl_easy_setopt_err_cb_data(); \ + if((_curl_opt) == CURLOPT_ERRORBUFFER) \ + if(!_curl_is_error_buffer(value)) \ + _curl_easy_setopt_err_error_buffer(); \ + if((_curl_opt) == CURLOPT_STDERR) \ + if(!_curl_is_FILE(value)) \ + _curl_easy_setopt_err_FILE(); \ + if(_curl_is_postfields_option(_curl_opt)) \ + if(!_curl_is_postfields(value)) \ + _curl_easy_setopt_err_postfields(); \ + if((_curl_opt) == CURLOPT_HTTPPOST) \ + if(!_curl_is_arr((value), struct curl_httppost)) \ + _curl_easy_setopt_err_curl_httpost(); \ + if(_curl_is_slist_option(_curl_opt)) \ + if(!_curl_is_arr((value), struct curl_slist)) \ + _curl_easy_setopt_err_curl_slist(); \ + if((_curl_opt) == CURLOPT_SHARE) \ + if(!_curl_is_ptr((value), CURLSH)) \ + _curl_easy_setopt_err_CURLSH(); \ + } \ + curl_easy_setopt(handle, _curl_opt, value); \ +}) + +/* wraps curl_easy_getinfo() with typechecking */ +/* FIXME: don't allow const pointers */ +#define curl_easy_getinfo(handle, info, arg) \ +__extension__ ({ \ + __typeof__ (info) _curl_info = info; \ + if(__builtin_constant_p(_curl_info)) { \ + if(_curl_is_string_info(_curl_info)) \ + if(!_curl_is_arr((arg), char *)) \ + _curl_easy_getinfo_err_string(); \ + if(_curl_is_long_info(_curl_info)) \ + if(!_curl_is_arr((arg), long)) \ + _curl_easy_getinfo_err_long(); \ + if(_curl_is_double_info(_curl_info)) \ + if(!_curl_is_arr((arg), double)) \ + _curl_easy_getinfo_err_double(); \ + if(_curl_is_slist_info(_curl_info)) \ + if(!_curl_is_arr((arg), struct curl_slist *)) \ + _curl_easy_getinfo_err_curl_slist(); \ + } \ + curl_easy_getinfo(handle, _curl_info, arg); \ +}) + +/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), + * for now just make sure that the functions are called with three + * arguments + */ +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) + + +/* the actual warnings, triggered by calling the _curl_easy_setopt_err* + * functions */ + +/* To define a new warning, use _CURL_WARNING(identifier, "message") */ +#define _CURL_WARNING(id, message) \ + static void __attribute__((__warning__(message))) \ + __attribute__((__unused__)) __attribute__((__noinline__)) \ + id(void) { __asm__(""); } + +_CURL_WARNING(_curl_easy_setopt_err_long, + "curl_easy_setopt expects a long argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, + "curl_easy_setopt expects a curl_off_t argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_string, + "curl_easy_setopt expects a " + "string (char* or char[]) argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_write_callback, + "curl_easy_setopt expects a curl_write_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_read_cb, + "curl_easy_setopt expects a curl_read_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, + "curl_easy_setopt expects a curl_ioctl_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, + "curl_easy_setopt expects a curl_sockopt_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, + "curl_easy_setopt expects a " + "curl_opensocket_callback argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_progress_cb, + "curl_easy_setopt expects a curl_progress_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_debug_cb, + "curl_easy_setopt expects a curl_debug_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, + "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_conv_cb, + "curl_easy_setopt expects a curl_conv_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_seek_cb, + "curl_easy_setopt expects a curl_seek_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_cb_data, + "curl_easy_setopt expects a " + "private data pointer as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_error_buffer, + "curl_easy_setopt expects a " + "char buffer of CURL_ERROR_SIZE as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_FILE, + "curl_easy_setopt expects a FILE* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_postfields, + "curl_easy_setopt expects a void* or char* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, + "curl_easy_setopt expects a struct curl_httppost* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_slist, + "curl_easy_setopt expects a struct curl_slist* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_CURLSH, + "curl_easy_setopt expects a CURLSH* argument for this option") + +_CURL_WARNING(_curl_easy_getinfo_err_string, + "curl_easy_getinfo expects a pointer to char * for this info") +_CURL_WARNING(_curl_easy_getinfo_err_long, + "curl_easy_getinfo expects a pointer to long for this info") +_CURL_WARNING(_curl_easy_getinfo_err_double, + "curl_easy_getinfo expects a pointer to double for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, + "curl_easy_getinfo expects a pointer to struct curl_slist * for this info") + +/* groups of curl_easy_setops options that take the same type of argument */ + +/* To add a new option to one of the groups, just add + * (option) == CURLOPT_SOMETHING + * to the or-expression. If the option takes a long or curl_off_t, you don't + * have to do anything + */ + +/* evaluates to true if option takes a long argument */ +#define _curl_is_long_option(option) \ + (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) + +#define _curl_is_off_t_option(option) \ + ((option) > CURLOPTTYPE_OFF_T) + +/* evaluates to true if option takes a char* argument */ +#define _curl_is_string_option(option) \ + ((option) == CURLOPT_ACCEPT_ENCODING || \ + (option) == CURLOPT_CAINFO || \ + (option) == CURLOPT_CAPATH || \ + (option) == CURLOPT_COOKIE || \ + (option) == CURLOPT_COOKIEFILE || \ + (option) == CURLOPT_COOKIEJAR || \ + (option) == CURLOPT_COOKIELIST || \ + (option) == CURLOPT_CRLFILE || \ + (option) == CURLOPT_CUSTOMREQUEST || \ + (option) == CURLOPT_DEFAULT_PROTOCOL || \ + (option) == CURLOPT_DNS_INTERFACE || \ + (option) == CURLOPT_DNS_LOCAL_IP4 || \ + (option) == CURLOPT_DNS_LOCAL_IP6 || \ + (option) == CURLOPT_DNS_SERVERS || \ + (option) == CURLOPT_EGDSOCKET || \ + (option) == CURLOPT_FTPPORT || \ + (option) == CURLOPT_FTP_ACCOUNT || \ + (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ + (option) == CURLOPT_INTERFACE || \ + (option) == CURLOPT_ISSUERCERT || \ + (option) == CURLOPT_KEYPASSWD || \ + (option) == CURLOPT_KRBLEVEL || \ + (option) == CURLOPT_LOGIN_OPTIONS || \ + (option) == CURLOPT_MAIL_AUTH || \ + (option) == CURLOPT_MAIL_FROM || \ + (option) == CURLOPT_NETRC_FILE || \ + (option) == CURLOPT_NOPROXY || \ + (option) == CURLOPT_PASSWORD || \ + (option) == CURLOPT_PINNEDPUBLICKEY || \ + (option) == CURLOPT_PROXY || \ + (option) == CURLOPT_PROXYPASSWORD || \ + (option) == CURLOPT_PROXYUSERNAME || \ + (option) == CURLOPT_PROXYUSERPWD || \ + (option) == CURLOPT_PROXY_SERVICE_NAME || \ + (option) == CURLOPT_RANDOM_FILE || \ + (option) == CURLOPT_RANGE || \ + (option) == CURLOPT_REFERER || \ + (option) == CURLOPT_RTSP_SESSION_ID || \ + (option) == CURLOPT_RTSP_STREAM_URI || \ + (option) == CURLOPT_RTSP_TRANSPORT || \ + (option) == CURLOPT_SERVICE_NAME || \ + (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ + (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ + (option) == CURLOPT_SSH_KNOWNHOSTS || \ + (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ + (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ + (option) == CURLOPT_SSLCERT || \ + (option) == CURLOPT_SSLCERTTYPE || \ + (option) == CURLOPT_SSLENGINE || \ + (option) == CURLOPT_SSLKEY || \ + (option) == CURLOPT_SSLKEYTYPE || \ + (option) == CURLOPT_SSL_CIPHER_LIST || \ + (option) == CURLOPT_TLSAUTH_PASSWORD || \ + (option) == CURLOPT_TLSAUTH_TYPE || \ + (option) == CURLOPT_TLSAUTH_USERNAME || \ + (option) == CURLOPT_UNIX_SOCKET_PATH || \ + (option) == CURLOPT_URL || \ + (option) == CURLOPT_USERAGENT || \ + (option) == CURLOPT_USERNAME || \ + (option) == CURLOPT_USERPWD || \ + (option) == CURLOPT_XOAUTH2_BEARER || \ + 0) + +/* evaluates to true if option takes a curl_write_callback argument */ +#define _curl_is_write_cb_option(option) \ + ((option) == CURLOPT_HEADERFUNCTION || \ + (option) == CURLOPT_WRITEFUNCTION) + +/* evaluates to true if option takes a curl_conv_callback argument */ +#define _curl_is_conv_cb_option(option) \ + ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) + +/* evaluates to true if option takes a data argument to pass to a callback */ +#define _curl_is_cb_data_option(option) \ + ((option) == CURLOPT_CHUNK_DATA || \ + (option) == CURLOPT_CLOSESOCKETDATA || \ + (option) == CURLOPT_DEBUGDATA || \ + (option) == CURLOPT_FNMATCH_DATA || \ + (option) == CURLOPT_HEADERDATA || \ + (option) == CURLOPT_INTERLEAVEDATA || \ + (option) == CURLOPT_IOCTLDATA || \ + (option) == CURLOPT_OPENSOCKETDATA || \ + (option) == CURLOPT_PRIVATE || \ + (option) == CURLOPT_PROGRESSDATA || \ + (option) == CURLOPT_READDATA || \ + (option) == CURLOPT_SEEKDATA || \ + (option) == CURLOPT_SOCKOPTDATA || \ + (option) == CURLOPT_SSH_KEYDATA || \ + (option) == CURLOPT_SSL_CTX_DATA || \ + (option) == CURLOPT_WRITEDATA || \ + 0) + +/* evaluates to true if option takes a POST data argument (void* or char*) */ +#define _curl_is_postfields_option(option) \ + ((option) == CURLOPT_POSTFIELDS || \ + (option) == CURLOPT_COPYPOSTFIELDS || \ + 0) + +/* evaluates to true if option takes a struct curl_slist * argument */ +#define _curl_is_slist_option(option) \ + ((option) == CURLOPT_HTTP200ALIASES || \ + (option) == CURLOPT_HTTPHEADER || \ + (option) == CURLOPT_MAIL_RCPT || \ + (option) == CURLOPT_POSTQUOTE || \ + (option) == CURLOPT_PREQUOTE || \ + (option) == CURLOPT_PROXYHEADER || \ + (option) == CURLOPT_QUOTE || \ + (option) == CURLOPT_RESOLVE || \ + (option) == CURLOPT_TELNETOPTIONS || \ + 0) + +/* groups of curl_easy_getinfo infos that take the same type of argument */ + +/* evaluates to true if info expects a pointer to char * argument */ +#define _curl_is_string_info(info) \ + (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) + +/* evaluates to true if info expects a pointer to long argument */ +#define _curl_is_long_info(info) \ + (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) + +/* evaluates to true if info expects a pointer to double argument */ +#define _curl_is_double_info(info) \ + (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) + +/* true if info expects a pointer to struct curl_slist * argument */ +#define _curl_is_slist_info(info) \ + (CURLINFO_SLIST < (info)) + + +/* typecheck helpers -- check whether given expression has requested type*/ + +/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, + * otherwise define a new macro. Search for __builtin_types_compatible_p + * in the GCC manual. + * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is + * the actual expression passed to the curl_easy_setopt macro. This + * means that you can only apply the sizeof and __typeof__ operators, no + * == or whatsoever. + */ + +/* XXX: should evaluate to true iff expr is a pointer */ +#define _curl_is_any_ptr(expr) \ + (sizeof(expr) == sizeof(void*)) + +/* evaluates to true if expr is NULL */ +/* XXX: must not evaluate expr, so this check is not accurate */ +#define _curl_is_NULL(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) + +/* evaluates to true if expr is type*, const type* or NULL */ +#define _curl_is_ptr(expr, type) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), type *) || \ + __builtin_types_compatible_p(__typeof__(expr), const type *)) + +/* evaluates to true if expr is one of type[], type*, NULL or const type* */ +#define _curl_is_arr(expr, type) \ + (_curl_is_ptr((expr), type) || \ + __builtin_types_compatible_p(__typeof__(expr), type [])) + +/* evaluates to true if expr is a string */ +#define _curl_is_string(expr) \ + (_curl_is_arr((expr), char) || \ + _curl_is_arr((expr), signed char) || \ + _curl_is_arr((expr), unsigned char)) + +/* evaluates to true if expr is a long (no matter the signedness) + * XXX: for now, int is also accepted (and therefore short and char, which + * are promoted to int when passed to a variadic function) */ +#define _curl_is_long(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), long) || \ + __builtin_types_compatible_p(__typeof__(expr), signed long) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ + __builtin_types_compatible_p(__typeof__(expr), int) || \ + __builtin_types_compatible_p(__typeof__(expr), signed int) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ + __builtin_types_compatible_p(__typeof__(expr), short) || \ + __builtin_types_compatible_p(__typeof__(expr), signed short) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ + __builtin_types_compatible_p(__typeof__(expr), char) || \ + __builtin_types_compatible_p(__typeof__(expr), signed char) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned char)) + +/* evaluates to true if expr is of type curl_off_t */ +#define _curl_is_off_t(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) + +/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ +/* XXX: also check size of an char[] array? */ +#define _curl_is_error_buffer(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), char *) || \ + __builtin_types_compatible_p(__typeof__(expr), char[])) + +/* evaluates to true if expr is of type (const) void* or (const) FILE* */ +#if 0 +#define _curl_is_cb_data(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_ptr((expr), FILE)) +#else /* be less strict */ +#define _curl_is_cb_data(expr) \ + _curl_is_any_ptr(expr) +#endif + +/* evaluates to true if expr is of type FILE* */ +#define _curl_is_FILE(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), FILE *)) + +/* evaluates to true if expr can be passed as POST data (void* or char*) */ +#define _curl_is_postfields(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_arr((expr), char)) + +/* FIXME: the whole callback checking is messy... + * The idea is to tolerate char vs. void and const vs. not const + * pointers in arguments at least + */ +/* helper: __builtin_types_compatible_p distinguishes between functions and + * function pointers, hide it */ +#define _curl_callback_compatible(func, type) \ + (__builtin_types_compatible_p(__typeof__(func), type) || \ + __builtin_types_compatible_p(__typeof__(func), type*)) + +/* evaluates to true if expr is of type curl_read_callback or "similar" */ +#define _curl_is_read_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \ + _curl_callback_compatible((expr), _curl_read_callback1) || \ + _curl_callback_compatible((expr), _curl_read_callback2) || \ + _curl_callback_compatible((expr), _curl_read_callback3) || \ + _curl_callback_compatible((expr), _curl_read_callback4) || \ + _curl_callback_compatible((expr), _curl_read_callback5) || \ + _curl_callback_compatible((expr), _curl_read_callback6)) +typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*); +typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*); +typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*); +typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*); +typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*); +typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*); + +/* evaluates to true if expr is of type curl_write_callback or "similar" */ +#define _curl_is_write_cb(expr) \ + (_curl_is_read_cb(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \ + _curl_callback_compatible((expr), _curl_write_callback1) || \ + _curl_callback_compatible((expr), _curl_write_callback2) || \ + _curl_callback_compatible((expr), _curl_write_callback3) || \ + _curl_callback_compatible((expr), _curl_write_callback4) || \ + _curl_callback_compatible((expr), _curl_write_callback5) || \ + _curl_callback_compatible((expr), _curl_write_callback6)) +typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*); +typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, + const void*); +typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*); +typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*); +typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, + const void*); +typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*); + +/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ +#define _curl_is_ioctl_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback4)) +typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*); +typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*); +typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*); +typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*); + +/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ +#define _curl_is_sockopt_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback2)) +typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); +typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, + curlsocktype); + +/* evaluates to true if expr is of type curl_opensocket_callback or + "similar" */ +#define _curl_is_opensocket_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\ + _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback4)) +typedef curl_socket_t (_curl_opensocket_callback1) + (void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback2) + (void *, curlsocktype, const struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback3) + (const void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback4) + (const void *, curlsocktype, const struct curl_sockaddr *); + +/* evaluates to true if expr is of type curl_progress_callback or "similar" */ +#define _curl_is_progress_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \ + _curl_callback_compatible((expr), _curl_progress_callback1) || \ + _curl_callback_compatible((expr), _curl_progress_callback2)) +typedef int (_curl_progress_callback1)(void *, + double, double, double, double); +typedef int (_curl_progress_callback2)(const void *, + double, double, double, double); + +/* evaluates to true if expr is of type curl_debug_callback or "similar" */ +#define _curl_is_debug_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \ + _curl_callback_compatible((expr), _curl_debug_callback1) || \ + _curl_callback_compatible((expr), _curl_debug_callback2) || \ + _curl_callback_compatible((expr), _curl_debug_callback3) || \ + _curl_callback_compatible((expr), _curl_debug_callback4) || \ + _curl_callback_compatible((expr), _curl_debug_callback5) || \ + _curl_callback_compatible((expr), _curl_debug_callback6) || \ + _curl_callback_compatible((expr), _curl_debug_callback7) || \ + _curl_callback_compatible((expr), _curl_debug_callback8)) +typedef int (_curl_debug_callback1) (CURL *, + curl_infotype, char *, size_t, void *); +typedef int (_curl_debug_callback2) (CURL *, + curl_infotype, char *, size_t, const void *); +typedef int (_curl_debug_callback3) (CURL *, + curl_infotype, const char *, size_t, void *); +typedef int (_curl_debug_callback4) (CURL *, + curl_infotype, const char *, size_t, const void *); +typedef int (_curl_debug_callback5) (CURL *, + curl_infotype, unsigned char *, size_t, void *); +typedef int (_curl_debug_callback6) (CURL *, + curl_infotype, unsigned char *, size_t, const void *); +typedef int (_curl_debug_callback7) (CURL *, + curl_infotype, const unsigned char *, size_t, void *); +typedef int (_curl_debug_callback8) (CURL *, + curl_infotype, const unsigned char *, size_t, const void *); + +/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ +/* this is getting even messier... */ +#define _curl_is_ssl_ctx_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) +typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); +typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); +#ifdef HEADER_SSL_H +/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX + * this will of course break if we're included before OpenSSL headers... + */ +typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); +typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, + const void *); +#else +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; +#endif + +/* evaluates to true if expr is of type curl_conv_callback or "similar" */ +#define _curl_is_conv_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \ + _curl_callback_compatible((expr), _curl_conv_callback1) || \ + _curl_callback_compatible((expr), _curl_conv_callback2) || \ + _curl_callback_compatible((expr), _curl_conv_callback3) || \ + _curl_callback_compatible((expr), _curl_conv_callback4)) +typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); +typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); +typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); +typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); + +/* evaluates to true if expr is of type curl_seek_callback or "similar" */ +#define _curl_is_seek_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \ + _curl_callback_compatible((expr), _curl_seek_callback1) || \ + _curl_callback_compatible((expr), _curl_seek_callback2)) +typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); +typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); + + +#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/builddir/freetype-2.7.0/README b/builddir/freetype-2.7.0/README new file mode 100644 index 0000000..5a49290 --- /dev/null +++ b/builddir/freetype-2.7.0/README @@ -0,0 +1,84 @@ + FreeType 2.7 + ============ + + Homepage: http://www.freetype.org + + FreeType is a freely available software library to render fonts. + + It is written in C, designed to be small, efficient, highly + customizable, and portable while capable of producing high-quality + output (glyph images) of most vector and bitmap font formats. + + Please read the docs/CHANGES file, it contains IMPORTANT + INFORMATION. + + Read the files `docs/INSTALL*' for installation instructions; see + the file `docs/LICENSE.TXT' for the available licenses. + + The FreeType 2 API reference is located in `docs/reference'; use the + file `ft2-toc.html' as the top entry point. Additional + documentation is available as a separate package from our sites. Go + to + + http://download.savannah.gnu.org/releases/freetype/ + + and download one of the following files. + + freetype-doc-2.7.tar.bz2 + freetype-doc-2.7.tar.gz + ftdoc27.zip + + To view the documentation online, go to + + http://www.freetype.org/freetype2/documentation.html + + + Mailing Lists + ============= + + The preferred way of communication with the FreeType team is using + e-mail lists. + + general use and discussion: freetype@nongnu.org + engine internals, porting, etc.: freetype-devel@nongnu.org + announcements: freetype-announce@nongnu.org + git repository tracker: freetype-commit@nongnu.org + + The lists are moderated; see + + http://www.freetype.org/contact.html + + how to subscribe. + + + Bugs + ==== + + Please submit bug reports at + + https://savannah.nongnu.org/bugs/?group=freetype + + Alternatively, you might report bugs by e-mail to + `freetype-devel@nongnu.org'. Don't forget to send a detailed + explanation of the problem -- there is nothing worse than receiving + a terse message that only says `it doesn't work'. + + + Enjoy! + + + The FreeType Team + +---------------------------------------------------------------------- + +Copyright 2006-2016 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. + + +--- end of README --- diff --git a/builddir/freetype-2.7.0/bin/freetype27.lib b/builddir/freetype-2.7.0/bin/freetype27.lib new file mode 100644 index 0000000..ebee509 Binary files /dev/null and b/builddir/freetype-2.7.0/bin/freetype27.lib differ diff --git a/builddir/freetype-2.7.0/include/freetype/config/ftconfig.h b/builddir/freetype-2.7.0/include/freetype/config/ftconfig.h new file mode 100644 index 0000000..157a704 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/config/ftconfig.h @@ -0,0 +1,473 @@ +/***************************************************************************/ +/* */ +/* ftconfig.h */ +/* */ +/* ANSI-specific configuration file (specification only). */ +/* */ +/* Copyright 1996-2016 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 header file contains a number of macro definitions that are used */ + /* by the rest of the engine. Most of the macros here are automatically */ + /* determined at compile time, and you should not need to change it to */ + /* port FreeType, except to compile the library with a non-ANSI */ + /* compiler. */ + /* */ + /* Note however that if some specific modifications are needed, we */ + /* advise you to place a modified copy in your build directory. */ + /* */ + /* The build directory is usually `builds/', and contains */ + /* system-specific files that are always included first when building */ + /* the library. */ + /* */ + /* This ANSI version should stay in `include/config/'. */ + /* */ + /*************************************************************************/ + +#ifndef FTCONFIG_H_ +#define FTCONFIG_H_ + +#include +#include FT_CONFIG_OPTIONS_H +#include FT_CONFIG_STANDARD_LIBRARY_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ + /* */ + /* These macros can be toggled to suit a specific system. The current */ + /* ones are defaults used to compile FreeType in an ANSI C environment */ + /* (16bit compilers are also supported). Copy this file to your own */ + /* `builds/' directory, and edit it to port the engine. */ + /* */ + /*************************************************************************/ + + + /* There are systems (like the Texas Instruments 'C54x) where a `char' */ + /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ + /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ + /* is probably unexpected. */ + /* */ + /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ + /* `char' type. */ + +#ifndef FT_CHAR_BIT +#define FT_CHAR_BIT CHAR_BIT +#endif + + + /* The size of an `int' type. */ +#if FT_UINT_MAX == 0xFFFFUL +#define FT_SIZEOF_INT (16 / FT_CHAR_BIT) +#elif FT_UINT_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_INT (32 / FT_CHAR_BIT) +#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL +#define FT_SIZEOF_INT (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `int' type!" +#endif + + /* The size of a `long' type. A five-byte `long' (as used e.g. on the */ + /* DM642) is recognized but avoided. */ +#if FT_ULONG_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL +#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `long' type!" +#endif + + + /* FT_UNUSED is a macro used to indicate that a given parameter is not */ + /* used -- this is only used to get rid of unpleasant compiler warnings */ +#ifndef FT_UNUSED +#define FT_UNUSED( arg ) ( (arg) = (arg) ) +#endif + + + /*************************************************************************/ + /* */ + /* AUTOMATIC CONFIGURATION MACROS */ + /* */ + /* These macros are computed from the ones defined above. Don't touch */ + /* their definition, unless you know precisely what you are doing. No */ + /* porter should need to mess with them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Mac support */ + /* */ + /* This is the only necessary change, so it is defined here instead */ + /* providing a new configuration file. */ + /* */ +#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) ) + /* no Carbon frameworks for 64bit 10.4.x */ + /* AvailabilityMacros.h is available since Mac OS X 10.2, */ + /* so guess the system version by maximum errno before inclusion */ +#include +#ifdef ECANCELED /* defined since 10.2 */ +#include "AvailabilityMacros.h" +#endif +#if defined( __LP64__ ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 ) +#undef FT_MACINTOSH +#endif + +#elif defined( __SC__ ) || defined( __MRC__ ) + /* Classic MacOS compilers */ +#include "ConditionalMacros.h" +#if TARGET_OS_MAC +#define FT_MACINTOSH 1 +#endif + +#endif + + + /*************************************************************************/ + /* */ + /*
*/ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int16 */ + /* */ + /* */ + /* A typedef for a 16bit signed integer type. */ + /* */ + typedef signed short FT_Int16; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt16 */ + /* */ + /* */ + /* A typedef for a 16bit unsigned integer type. */ + /* */ + typedef unsigned short FT_UInt16; + + /* */ + + + /* this #if 0 ... #endif clause is for documentation purposes */ +#if 0 + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int32 */ + /* */ + /* */ + /* A typedef for a 32bit signed integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef signed XXX FT_Int32; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt32 */ + /* */ + /* A typedef for a 32bit unsigned integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef unsigned XXX FT_UInt32; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int64 */ + /* */ + /* A typedef for a 64bit signed integer type. The size depends on */ + /* the configuration. Only defined if there is real 64bit support; */ + /* otherwise, it gets emulated with a structure (if necessary). */ + /* */ + typedef signed XXX FT_Int64; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt64 */ + /* */ + /* A typedef for a 64bit unsigned integer type. The size depends on */ + /* the configuration. Only defined if there is real 64bit support; */ + /* otherwise, it gets emulated with a structure (if necessary). */ + /* */ + typedef unsigned XXX FT_UInt64; + + /* */ + +#endif + +#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) + + typedef signed int FT_Int32; + typedef unsigned int FT_UInt32; + +#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT) + + typedef signed long FT_Int32; + typedef unsigned long FT_UInt32; + +#else +#error "no 32bit type found -- please check your configuration files" +#endif + + + /* look up an integer type that is at least 32 bits */ +#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) + + typedef int FT_Fast; + typedef unsigned int FT_UFast; + +#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT) + + typedef long FT_Fast; + typedef unsigned long FT_UFast; + +#endif + + + /* determine whether we have a 64-bit int type for platforms without */ + /* Autoconf */ +#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) + + /* FT_LONG64 must be defined if a 64-bit type is available */ +#define FT_LONG64 +#define FT_INT64 long +#define FT_UINT64 unsigned long + + /*************************************************************************/ + /* */ + /* A 64-bit data type may create compilation problems if you compile */ + /* in strict ANSI mode. To avoid them, we disable other 64-bit data */ + /* types if __STDC__ is defined. You can however ignore this rule */ + /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* */ +#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) + +#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L + +#define FT_LONG64 +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + +#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 +#define FT_UINT64 unsigned __int64 + +#elif defined( __BORLANDC__ ) /* Borland C++ */ + + /* XXXX: We should probably check the value of __BORLANDC__ in order */ + /* to test the compiler version. */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 +#define FT_UINT64 unsigned __int64 + +#elif defined( __WATCOMC__ ) /* Watcom C++ */ + + /* Watcom doesn't provide 64-bit data types */ + +#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */ + +#define FT_LONG64 +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + +#elif defined( __GNUC__ ) + + /* GCC provides the `long long' type */ +#define FT_LONG64 +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + +#endif /* __STDC_VERSION__ >= 199901L */ + +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ + +#ifdef FT_LONG64 + typedef FT_INT64 FT_Int64; + typedef FT_UINT64 FT_UInt64; +#endif + + + /*************************************************************************/ + /* */ + /* miscellaneous */ + /* */ + /*************************************************************************/ + + +#define FT_BEGIN_STMNT do { +#define FT_END_STMNT } while ( 0 ) +#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT + + + /* typeof condition taken from gnulib's `intprops.h' header file */ +#if ( __GNUC__ >= 2 || \ + defined( __IBM__TYPEOF__ ) || \ + ( __SUNPRO_C >= 0x5110 && !__STDC__ ) ) +#define FT_TYPEOF( type ) (__typeof__ (type)) +#else +#define FT_TYPEOF( type ) /* empty */ +#endif + + +#ifdef FT_MAKE_OPTION_SINGLE_OBJECT + +#define FT_LOCAL( x ) static x +#define FT_LOCAL_DEF( x ) static x + +#else + +#ifdef __cplusplus +#define FT_LOCAL( x ) extern "C" x +#define FT_LOCAL_DEF( x ) extern "C" x +#else +#define FT_LOCAL( x ) extern x +#define FT_LOCAL_DEF( x ) x +#endif + +#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ + +#define FT_LOCAL_ARRAY( x ) extern const x +#define FT_LOCAL_ARRAY_DEF( x ) const x + + +#ifndef FT_BASE + +#ifdef __cplusplus +#define FT_BASE( x ) extern "C" x +#else +#define FT_BASE( x ) extern x +#endif + +#endif /* !FT_BASE */ + + +#ifndef FT_BASE_DEF + +#ifdef __cplusplus +#define FT_BASE_DEF( x ) x +#else +#define FT_BASE_DEF( x ) x +#endif + +#endif /* !FT_BASE_DEF */ + + +#ifndef FT_EXPORT + +#ifdef __cplusplus +#define FT_EXPORT( x ) extern "C" x +#else +#define FT_EXPORT( x ) extern x +#endif + +#endif /* !FT_EXPORT */ + + +#ifndef FT_EXPORT_DEF + +#ifdef __cplusplus +#define FT_EXPORT_DEF( x ) extern "C" x +#else +#define FT_EXPORT_DEF( x ) extern x +#endif + +#endif /* !FT_EXPORT_DEF */ + + +#ifndef FT_EXPORT_VAR + +#ifdef __cplusplus +#define FT_EXPORT_VAR( x ) extern "C" x +#else +#define FT_EXPORT_VAR( x ) extern x +#endif + +#endif /* !FT_EXPORT_VAR */ + + /* The following macros are needed to compile the library with a */ + /* C++ compiler and with 16bit compilers. */ + /* */ + + /* This is special. Within C++, you must specify `extern "C"' for */ + /* functions which are used via function pointers, and you also */ + /* must do that for structures which contain function pointers to */ + /* assure C linkage -- it's not possible to have (local) anonymous */ + /* functions which are accessed by (global) function pointers. */ + /* */ + /* */ + /* FT_CALLBACK_DEF is used to _define_ a callback function. */ + /* */ + /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ + /* contains pointers to callback functions. */ + /* */ + /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ + /* that contains pointers to callback functions. */ + /* */ + /* */ + /* Some 16bit compilers have to redefine these macros to insert */ + /* the infamous `_cdecl' or `__fastcall' declarations. */ + /* */ +#ifndef FT_CALLBACK_DEF +#ifdef __cplusplus +#define FT_CALLBACK_DEF( x ) extern "C" x +#else +#define FT_CALLBACK_DEF( x ) static x +#endif +#endif /* FT_CALLBACK_DEF */ + +#ifndef FT_CALLBACK_TABLE +#ifdef __cplusplus +#define FT_CALLBACK_TABLE extern "C" +#define FT_CALLBACK_TABLE_DEF extern "C" +#else +#define FT_CALLBACK_TABLE extern +#define FT_CALLBACK_TABLE_DEF /* nothing */ +#endif +#endif /* FT_CALLBACK_TABLE */ + + +FT_END_HEADER + + +#endif /* FTCONFIG_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/config/ftheader.h b/builddir/freetype-2.7.0/include/freetype/config/ftheader.h new file mode 100644 index 0000000..68e1483 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/config/ftheader.h @@ -0,0 +1,833 @@ +/***************************************************************************/ +/* */ +/* ftheader.h */ +/* */ +/* Build macros of the FreeType 2 library. */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + +#ifndef FTHEADER_H_ +#define FTHEADER_H_ + + + /*@***********************************************************************/ + /* */ + /* */ + /* FT_BEGIN_HEADER */ + /* */ + /* */ + /* This macro is used in association with @FT_END_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_BEGIN_HEADER extern "C" { +#else +#define FT_BEGIN_HEADER /* nothing */ +#endif + + + /*@***********************************************************************/ + /* */ + /* */ + /* FT_END_HEADER */ + /* */ + /* */ + /* This macro is used in association with @FT_BEGIN_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_END_HEADER } +#else +#define FT_END_HEADER /* nothing */ +#endif + + + /*************************************************************************/ + /* */ + /* Aliases for the FreeType 2 public and configuration files. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /*
*/ + /* header_file_macros */ + /* */ + /* */ + /* Header File Macros */ + /* */ + /* <Abstract> */ + /* Macro definitions used to #include specific header files. */ + /* */ + /* <Description> */ + /* The following macros are defined to the name of specific */ + /* FreeType~2 header files. They can be used directly in #include */ + /* statements as in: */ + /* */ + /* { */ + /* #include FT_FREETYPE_H */ + /* #include FT_MULTIPLE_MASTERS_H */ + /* #include FT_GLYPH_H */ + /* } */ + /* */ + /* There are several reasons why we are now using macros to name */ + /* public header files. The first one is that such macros are not */ + /* limited to the infamous 8.3~naming rule required by DOS (and */ + /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ + /* */ + /* The second reason is that it allows for more flexibility in the */ + /* way FreeType~2 is installed on a given system. */ + /* */ + /*************************************************************************/ + + + /* configuration files */ + + /************************************************************************* + * + * @macro: + * FT_CONFIG_CONFIG_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 configuration data. + * + */ +#ifndef FT_CONFIG_CONFIG_H +#define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_STANDARD_LIBRARY_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 interface to the standard C library functions. + * + */ +#ifndef FT_CONFIG_STANDARD_LIBRARY_H +#define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_OPTIONS_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 project-specific configuration options. + * + */ +#ifndef FT_CONFIG_OPTIONS_H +#define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_MODULES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 modules that are statically linked to new library + * instances in @FT_Init_FreeType. + * + */ +#ifndef FT_CONFIG_MODULES_H +#define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h> +#endif + + /* */ + + /* public headers */ + + /************************************************************************* + * + * @macro: + * FT_FREETYPE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * base FreeType~2 API. + * + */ +#define FT_FREETYPE_H <freetype/freetype.h> + + + /************************************************************************* + * + * @macro: + * FT_ERRORS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 error codes (and messages). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_ERRORS_H <freetype/fterrors.h> + + + /************************************************************************* + * + * @macro: + * FT_MODULE_ERRORS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 module error offsets (and messages). + * + */ +#define FT_MODULE_ERRORS_H <freetype/ftmoderr.h> + + + /************************************************************************* + * + * @macro: + * FT_SYSTEM_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 interface to low-level operations (i.e., memory management + * and stream i/o). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_SYSTEM_H <freetype/ftsystem.h> + + + /************************************************************************* + * + * @macro: + * FT_IMAGE_H + * + * @description: + * A macro used in #include statements to name the file containing type + * definitions related to glyph images (i.e., bitmaps, outlines, + * scan-converter parameters). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_IMAGE_H <freetype/ftimage.h> + + + /************************************************************************* + * + * @macro: + * FT_TYPES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * basic data types defined by FreeType~2. + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_TYPES_H <freetype/fttypes.h> + + + /************************************************************************* + * + * @macro: + * FT_LIST_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list management API of FreeType~2. + * + * (Most applications will never need to include this file.) + * + */ +#define FT_LIST_H <freetype/ftlist.h> + + + /************************************************************************* + * + * @macro: + * FT_OUTLINE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * scalable outline management API of FreeType~2. + * + */ +#define FT_OUTLINE_H <freetype/ftoutln.h> + + + /************************************************************************* + * + * @macro: + * FT_SIZES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API which manages multiple @FT_Size objects per face. + * + */ +#define FT_SIZES_H <freetype/ftsizes.h> + + + /************************************************************************* + * + * @macro: + * FT_MODULE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * module management API of FreeType~2. + * + */ +#define FT_MODULE_H <freetype/ftmodapi.h> + + + /************************************************************************* + * + * @macro: + * FT_RENDER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * renderer module management API of FreeType~2. + * + */ +#define FT_RENDER_H <freetype/ftrender.h> + + + /************************************************************************* + * + * @macro: + * FT_AUTOHINTER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the auto-hinting module. + * + */ +#define FT_AUTOHINTER_H <freetype/ftautoh.h> + + + /************************************************************************* + * + * @macro: + * FT_CFF_DRIVER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the CFF driver module. + * + */ +#define FT_CFF_DRIVER_H <freetype/ftcffdrv.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_DRIVER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the TrueType driver module. + * + */ +#define FT_TRUETYPE_DRIVER_H <freetype/ftttdrv.h> + + + /************************************************************************* + * + * @macro: + * FT_TYPE1_TABLES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * types and API specific to the Type~1 format. + * + */ +#define FT_TYPE1_TABLES_H <freetype/t1tables.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_IDS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * enumeration values which identify name strings, languages, encodings, + * etc. This file really contains a _large_ set of constant macro + * definitions, taken from the TrueType and OpenType specifications. + * + */ +#define FT_TRUETYPE_IDS_H <freetype/ttnameid.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_TABLES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * types and API specific to the TrueType (as well as OpenType) format. + * + */ +#define FT_TRUETYPE_TABLES_H <freetype/tttables.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_TAGS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of TrueType four-byte `tags' which identify blocks in + * SFNT-based font formats (i.e., TrueType and OpenType). + * + */ +#define FT_TRUETYPE_TAGS_H <freetype/tttags.h> + + + /************************************************************************* + * + * @macro: + * FT_BDF_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which accesses BDF-specific strings from a + * face. + * + */ +#define FT_BDF_H <freetype/ftbdf.h> + + + /************************************************************************* + * + * @macro: + * FT_CID_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which access CID font information from a + * face. + * + */ +#define FT_CID_H <freetype/ftcid.h> + + + /************************************************************************* + * + * @macro: + * FT_GZIP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports gzip-compressed files. + * + */ +#define FT_GZIP_H <freetype/ftgzip.h> + + + /************************************************************************* + * + * @macro: + * FT_LZW_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports LZW-compressed files. + * + */ +#define FT_LZW_H <freetype/ftlzw.h> + + + /************************************************************************* + * + * @macro: + * FT_BZIP2_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports bzip2-compressed files. + * + */ +#define FT_BZIP2_H <freetype/ftbzip2.h> + + + /************************************************************************* + * + * @macro: + * FT_WINFONTS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports Windows FNT files. + * + */ +#define FT_WINFONTS_H <freetype/ftwinfnt.h> + + + /************************************************************************* + * + * @macro: + * FT_GLYPH_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional glyph management component. + * + */ +#define FT_GLYPH_H <freetype/ftglyph.h> + + + /************************************************************************* + * + * @macro: + * FT_BITMAP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional bitmap conversion component. + * + */ +#define FT_BITMAP_H <freetype/ftbitmap.h> + + + /************************************************************************* + * + * @macro: + * FT_BBOX_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional exact bounding box computation routines. + * + */ +#define FT_BBOX_H <freetype/ftbbox.h> + + + /************************************************************************* + * + * @macro: + * FT_CACHE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional FreeType~2 cache sub-system. + * + */ +#define FT_CACHE_H <freetype/ftcache.h> + + + /************************************************************************* + * + * @macro: + * FT_CACHE_IMAGE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `glyph image' API of the FreeType~2 cache sub-system. + * + * It is used to define a cache for @FT_Glyph elements. You can also + * use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to + * store small glyph bitmaps, as it will use less memory. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * glyph image-related cache declarations. + * + */ +#define FT_CACHE_IMAGE_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_CACHE_SMALL_BITMAPS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `small bitmaps' API of the FreeType~2 cache sub-system. + * + * It is used to define a cache for small glyph bitmaps in a relatively + * memory-efficient way. You can also use the API defined in + * @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images, + * including scalable outlines. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * small bitmaps-related cache declarations. + * + */ +#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_CACHE_CHARMAP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `charmap' API of the FreeType~2 cache sub-system. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * charmap-based cache declarations. + * + */ +#define FT_CACHE_CHARMAP_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_MAC_H + * + * @description: + * A macro used in #include statements to name the file containing the + * Macintosh-specific FreeType~2 API. The latter is used to access + * fonts embedded in resource forks. + * + * This header file must be explicitly included by client applications + * compiled on the Mac (note that the base API still works though). + * + */ +#define FT_MAC_H <freetype/ftmac.h> + + + /************************************************************************* + * + * @macro: + * FT_MULTIPLE_MASTERS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional multiple-masters management API of FreeType~2. + * + */ +#define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h> + + + /************************************************************************* + * + * @macro: + * FT_SFNT_NAMES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which accesses embedded `name' strings in + * SFNT-based font formats (i.e., TrueType and OpenType). + * + */ +#define FT_SFNT_NAMES_H <freetype/ftsnames.h> + + + /************************************************************************* + * + * @macro: + * FT_OPENTYPE_VALIDATE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which validates OpenType tables (BASE, GDEF, + * GPOS, GSUB, JSTF). + * + */ +#define FT_OPENTYPE_VALIDATE_H <freetype/ftotval.h> + + + /************************************************************************* + * + * @macro: + * FT_GX_VALIDATE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat, + * mort, morx, bsln, just, kern, opbd, trak, prop). + * + */ +#define FT_GX_VALIDATE_H <freetype/ftgxval.h> + + + /************************************************************************* + * + * @macro: + * FT_PFR_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which accesses PFR-specific data. + * + */ +#define FT_PFR_H <freetype/ftpfr.h> + + + /************************************************************************* + * + * @macro: + * FT_STROKER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which provides functions to stroke outline paths. + */ +#define FT_STROKER_H <freetype/ftstroke.h> + + + /************************************************************************* + * + * @macro: + * FT_SYNTHESIS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs artificial obliquing and emboldening. + */ +#define FT_SYNTHESIS_H <freetype/ftsynth.h> + + + /************************************************************************* + * + * @macro: + * FT_FONT_FORMATS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which provides functions specific to font formats. + */ +#define FT_FONT_FORMATS_H <freetype/ftfntfmt.h> + + /* deprecated */ +#define FT_XFREE86_H FT_FONT_FORMATS_H + + + /************************************************************************* + * + * @macro: + * FT_TRIGONOMETRY_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs trigonometric computations (e.g., + * cosines and arc tangents). + */ +#define FT_TRIGONOMETRY_H <freetype/fttrigon.h> + + + /************************************************************************* + * + * @macro: + * FT_LCD_FILTER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_LCD_FILTER_H <freetype/ftlcdfil.h> + + + /************************************************************************* + * + * @macro: + * FT_UNPATENTED_HINTING_H + * + * @description: + * Deprecated. + */ +#define FT_UNPATENTED_HINTING_H <freetype/ttunpat.h> + + + /************************************************************************* + * + * @macro: + * FT_INCREMENTAL_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs incremental glyph loading. + */ +#define FT_INCREMENTAL_H <freetype/ftincrem.h> + + + /************************************************************************* + * + * @macro: + * FT_GASP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which returns entries from the TrueType GASP table. + */ +#define FT_GASP_H <freetype/ftgasp.h> + + + /************************************************************************* + * + * @macro: + * FT_ADVANCES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which returns individual and ranged glyph advances. + */ +#define FT_ADVANCES_H <freetype/ftadvanc.h> + + + /* */ + +#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h> + + + /* The internals of the cache sub-system are no longer exposed. We */ + /* default to FT_CACHE_H at the moment just in case, but we know of */ + /* no rogue client that uses them. */ + /* */ +#define FT_CACHE_MANAGER_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_MRU_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_MANAGER_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_CACHE_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_GLYPH_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_IMAGE_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_SBITS_H <freetype/ftcache.h> + + +#define FT_INCREMENTAL_H <freetype/ftincrem.h> + +#define FT_TRUETYPE_UNPATENTED_H <freetype/ttunpat.h> + + + /* + * Include internal headers definitions from <internal/...> + * only when building the library. + */ +#ifdef FT2_BUILD_LIBRARY +#define FT_INTERNAL_INTERNAL_H <freetype/internal/internal.h> +#include FT_INTERNAL_INTERNAL_H +#endif /* FT2_BUILD_LIBRARY */ + + +#endif /* FTHEADER_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/config/ftmodule.h b/builddir/freetype-2.7.0/include/freetype/config/ftmodule.h new file mode 100644 index 0000000..76d271a --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/config/ftmodule.h @@ -0,0 +1,32 @@ +/* + * This file registers the FreeType modules compiled into the library. + * + * If you use GNU make, this file IS NOT USED! Instead, it is created in + * the objects directory (normally `<topdir>/objs/') based on information + * from `<topdir>/modules.cfg'. + * + * Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile + * FreeType without GNU make. + * + */ + +FT_USE_MODULE( FT_Module_Class, autofit_module_class ) +FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class ) +FT_USE_MODULE( FT_Module_Class, psaux_module_class ) +FT_USE_MODULE( FT_Module_Class, psnames_module_class ) +FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) +FT_USE_MODULE( FT_Module_Class, sfnt_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class ) +FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) + +/* EOF */ diff --git a/builddir/freetype-2.7.0/include/freetype/config/ftoption.h b/builddir/freetype-2.7.0/include/freetype/config/ftoption.h new file mode 100644 index 0000000..90c123e --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/config/ftoption.h @@ -0,0 +1,933 @@ +/***************************************************************************/ +/* */ +/* ftoption.h */ +/* */ +/* User-selectable configuration macros (specification only). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTOPTION_H_ +#define FTOPTION_H_ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* USER-SELECTABLE CONFIGURATION MACROS */ + /* */ + /* This file contains the default configuration macro definitions for */ + /* a standard build of the FreeType library. There are three ways to */ + /* use this file to build project-specific versions of the library: */ + /* */ + /* - You can modify this file by hand, but this is not recommended in */ + /* cases where you would like to build several versions of the */ + /* library from a single source directory. */ + /* */ + /* - You can put a copy of this file in your build directory, more */ + /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ + /* is the name of a directory that is included _before_ the FreeType */ + /* include path during compilation. */ + /* */ + /* The default FreeType Makefiles and Jamfiles use the build */ + /* directory `builds/<system>' by default, but you can easily change */ + /* that for your own projects. */ + /* */ + /* - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it */ + /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ + /* locate this file during the build. For example, */ + /* */ + /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ + /* #include <freetype/config/ftheader.h> */ + /* */ + /* will use `$BUILD/myftoptions.h' instead of this file for macro */ + /* definitions. */ + /* */ + /* Note also that you can similarly pre-define the macro */ + /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ + /* that are statically linked to the library at compile time. By */ + /* default, this file is <freetype/config/ftmodule.h>. */ + /* */ + /* We highly recommend using the third method whenever possible. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* If you enable this configuration option, FreeType recognizes an */ + /* environment variable called `FREETYPE_PROPERTIES', which can be used */ + /* to control the various font drivers and modules. The controllable */ + /* properties are listed in the section `Controlling FreeType Modules' */ + /* in the reference's table of contents; currently there are properties */ + /* for the auto-hinter (file `ftautoh.h'), CFF (file `ftcffdrv.h'), and */ + /* TrueType (file `ftttdrv.h'). */ + /* */ + /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */ + /* multiple lines for better readability). */ + /* */ + /* <optional whitespace> */ + /* <module-name1> ':' */ + /* <property-name1> '=' <property-value1> */ + /* <whitespace> */ + /* <module-name2> ':' */ + /* <property-name2> '=' <property-value2> */ + /* ... */ + /* */ + /* Example: */ + /* */ + /* FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ */ + /* cff:no-stem-darkening=1 \ */ + /* autofitter:warping=1 */ + /* */ +#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + + + /*************************************************************************/ + /* */ + /* Uncomment the line below if you want to activate sub-pixel rendering */ + /* (a.k.a. LCD rendering, or ClearType) in this build of the library. */ + /* */ + /* Note that this feature is covered by several Microsoft patents */ + /* and should not be activated in any default build of the library. */ + /* */ + /* This macro has no impact on the FreeType API, only on its */ + /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ + /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ + /* the original size in case this macro isn't defined; however, each */ + /* triplet of subpixels has R=G=B. */ + /* */ + /* This is done to allow FreeType clients to run unmodified, forcing */ + /* them to display normal gray-level anti-aliased glyphs. */ + /* */ +/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + + /*************************************************************************/ + /* */ + /* Many compilers provide a non-ANSI 64-bit data type that can be used */ + /* by FreeType to speed up some computations. However, this will create */ + /* some problems when compiling the library in strict ANSI mode. */ + /* */ + /* For this reason, the use of 64-bit integers is normally disabled when */ + /* the __STDC__ macro is defined. You can however disable this by */ + /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ + /* */ + /* For most compilers, this will only create compilation warnings when */ + /* building the library. */ + /* */ + /* ObNote: The compiler-specific 64-bit integers are detected in the */ + /* file `ftconfig.h' either statically or through the */ + /* `configure' script on supported platforms. */ + /* */ +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* If this macro is defined, do not try to use an assembler version of */ + /* performance-critical functions (e.g. FT_MulFix). You should only do */ + /* that to verify that the assembler function works properly, or to */ + /* execute benchmark tests of the various implementations. */ +/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ + + + /*************************************************************************/ + /* */ + /* If this macro is defined, try to use an inlined assembler version of */ + /* the `FT_MulFix' function, which is a `hotspot' when loading and */ + /* hinting glyphs, and which should be executed as fast as possible. */ + /* */ + /* Note that if your compiler or CPU is not supported, this will default */ + /* to the standard and portable implementation found in `ftcalc.c'. */ + /* */ +#define FT_CONFIG_OPTION_INLINE_MULFIX + + + /*************************************************************************/ + /* */ + /* LZW-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `compress' program. This is mostly used to parse many of the PCF */ + /* files that come with various X11 distributions. The implementation */ + /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ + /* (see src/lzw/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +#define FT_CONFIG_OPTION_USE_LZW + + + /*************************************************************************/ + /* */ + /* Gzip-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `gzip' program. This is mostly used to parse many of the PCF files */ + /* that come with XFree86. The implementation uses `zlib' to */ + /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. See also */ + /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ + /* */ +#define FT_CONFIG_OPTION_USE_ZLIB + + + /*************************************************************************/ + /* */ + /* ZLib library selection */ + /* */ + /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ + /* It allows FreeType's `ftgzip' component to link to the system's */ + /* installation of the ZLib library. This is useful on systems like */ + /* Unix or VMS where it generally is already available. */ + /* */ + /* If you let it undefined, the component will use its own copy */ + /* of the zlib sources instead. These have been modified to be */ + /* included directly within the component and *not* export external */ + /* function names. This allows you to link any program with FreeType */ + /* _and_ ZLib without linking conflicts. */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ + + + /*************************************************************************/ + /* */ + /* Bzip2-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `bzip2' program. This is mostly used to parse many of the PCF */ + /* files that come with XFree86. The implementation uses `libbz2' to */ + /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ + /* Contrary to gzip, bzip2 currently is not included and need to use */ + /* the system available bzip2 implementation. */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_BZIP2 */ + + + /*************************************************************************/ + /* */ + /* Define to disable the use of file stream functions and types, FILE, */ + /* fopen() etc. Enables the use of smaller system libraries on embedded */ + /* systems that have multiple system libraries, some with or without */ + /* file stream support, in the cases where file stream support is not */ + /* necessary such as memory loading of font files. */ + /* */ +/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ + + + /*************************************************************************/ + /* */ + /* PNG bitmap support. */ + /* */ + /* FreeType now handles loading color bitmap glyphs in the PNG format. */ + /* This requires help from the external libpng library. Uncompressed */ + /* color bitmaps do not need any external libraries and will be */ + /* supported regardless of this configuration. */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_PNG */ + + + /*************************************************************************/ + /* */ + /* HarfBuzz support. */ + /* */ + /* FreeType uses the HarfBuzz library to improve auto-hinting of */ + /* OpenType fonts. If available, many glyphs not directly addressable */ + /* by a font's character map will be hinted also. */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */ + + + /*************************************************************************/ + /* */ + /* DLL export compilation */ + /* */ + /* When compiling FreeType as a DLL, some systems/compilers need a */ + /* special keyword in front OR after the return type of function */ + /* declarations. */ + /* */ + /* Two macros are used within the FreeType source code to define */ + /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ + /* */ + /* FT_EXPORT( return_type ) */ + /* */ + /* is used in a function declaration, as in */ + /* */ + /* FT_EXPORT( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ); */ + /* */ + /* */ + /* FT_EXPORT_DEF( return_type ) */ + /* */ + /* is used in a function definition, as in */ + /* */ + /* FT_EXPORT_DEF( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ) */ + /* { */ + /* ... some code ... */ + /* return FT_Err_Ok; */ + /* } */ + /* */ + /* You can provide your own implementation of FT_EXPORT and */ + /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ + /* will be later automatically defined as `extern return_type' to */ + /* allow normal compilation. */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_EXPORT(x) extern x */ +/* #define FT_EXPORT_DEF(x) x */ + + + /*************************************************************************/ + /* */ + /* Glyph Postscript Names handling */ + /* */ + /* By default, FreeType 2 is compiled with the `psnames' module. This */ + /* module is in charge of converting a glyph name string into a */ + /* Unicode value, or return a Macintosh standard glyph name for the */ + /* use with the TrueType `post' table. */ + /* */ + /* Undefine this macro if you do not want `psnames' compiled in your */ + /* build of FreeType. This has the following effects: */ + /* */ + /* - The TrueType driver will provide its own set of glyph names, */ + /* if you build it to support postscript names in the TrueType */ + /* `post' table. */ + /* */ + /* - The Type 1 driver will not be able to synthesize a Unicode */ + /* charmap out of the glyphs found in the fonts. */ + /* */ + /* You would normally undefine this configuration macro when building */ + /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ + /* */ +#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Postscript Names to Unicode Values support */ + /* */ + /* By default, FreeType 2 is built with the `PSNames' module compiled */ + /* in. Among other things, the module is used to convert a glyph name */ + /* into a Unicode value. This is especially useful in order to */ + /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* through a big table named the `Adobe Glyph List' (AGL). */ + /* */ + /* Undefine this macro if you do not want the Adobe Glyph List */ + /* compiled in your `PSNames' module. The Type 1 driver will not be */ + /* able to synthesize a Unicode charmap out of the glyphs found in the */ + /* fonts. */ + /* */ +#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + + /*************************************************************************/ + /* */ + /* Support for Mac fonts */ + /* */ + /* Define this macro if you want support for outline fonts in Mac */ + /* format (mac dfont, mac resource, macbinary containing a mac */ + /* resource) on non-Mac platforms. */ + /* */ + /* Note that the `FOND' resource isn't checked. */ + /* */ +#define FT_CONFIG_OPTION_MAC_FONTS + + + /*************************************************************************/ + /* */ + /* Guessing methods to access embedded resource forks */ + /* */ + /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ + /* GNU/Linux). */ + /* */ + /* Resource forks which include fonts data are stored sometimes in */ + /* locations which users or developers don't expected. In some cases, */ + /* resource forks start with some offset from the head of a file. In */ + /* other cases, the actual resource fork is stored in file different */ + /* from what the user specifies. If this option is activated, */ + /* FreeType tries to guess whether such offsets or different file */ + /* names must be used. */ + /* */ + /* Note that normal, direct access of resource forks is controlled via */ + /* the FT_CONFIG_OPTION_MAC_FONTS option. */ + /* */ +#ifdef FT_CONFIG_OPTION_MAC_FONTS +#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#endif + + + /*************************************************************************/ + /* */ + /* Allow the use of FT_Incremental_Interface to load typefaces that */ + /* contain no glyph data, but supply it via a callback function. */ + /* This is required by clients supporting document formats which */ + /* supply font data incrementally as the document is parsed, such */ + /* as the Ghostscript interpreter for the PostScript language. */ + /* */ +#define FT_CONFIG_OPTION_INCREMENTAL + + + /*************************************************************************/ + /* */ + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ + /* */ +#define FT_RENDER_POOL_SIZE 16384L + + + /*************************************************************************/ + /* */ + /* FT_MAX_MODULES */ + /* */ + /* The maximum number of modules that can be registered in a single */ + /* FreeType library object. 32 is the default. */ + /* */ +#define FT_MAX_MODULES 32 + + + /*************************************************************************/ + /* */ + /* Debug level */ + /* */ + /* FreeType can be compiled in debug or trace mode. In debug mode, */ + /* errors are reported through the `ftdebug' component. In trace */ + /* mode, additional messages are sent to the standard output during */ + /* execution. */ + /* */ + /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ + /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ + /* */ + /* Don't define any of these macros to compile in `release' mode! */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_DEBUG_LEVEL_ERROR */ +/* #define FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* Autofitter debugging */ + /* */ + /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ + /* control the autofitter behaviour for debugging purposes with global */ + /* boolean variables (consequently, you should *never* enable this */ + /* while compiling in `release' mode): */ + /* */ + /* _af_debug_disable_horz_hints */ + /* _af_debug_disable_vert_hints */ + /* _af_debug_disable_blue_hints */ + /* */ + /* Additionally, the following functions provide dumps of various */ + /* internal autofit structures to stdout (using `printf'): */ + /* */ + /* af_glyph_hints_dump_points */ + /* af_glyph_hints_dump_segments */ + /* af_glyph_hints_dump_edges */ + /* af_glyph_hints_get_num_segments */ + /* af_glyph_hints_get_segment_offset */ + /* */ + /* As an argument, they use another global variable: */ + /* */ + /* _af_debug_hints */ + /* */ + /* Please have a look at the `ftgrid' demo program to see how those */ + /* variables and macros should be used. */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_DEBUG_AUTOFIT */ + + + /*************************************************************************/ + /* */ + /* Memory Debugging */ + /* */ + /* FreeType now comes with an integrated memory debugger that is */ + /* capable of detecting simple errors like memory leaks or double */ + /* deletes. To compile it within your build of the library, you */ + /* should define FT_DEBUG_MEMORY here. */ + /* */ + /* Note that the memory debugger is only activated at runtime when */ + /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_DEBUG_MEMORY */ + + + /*************************************************************************/ + /* */ + /* Module errors */ + /* */ + /* If this macro is set (which is _not_ the default), the higher byte */ + /* of an error code gives the module in which the error has occurred, */ + /* while the lower byte is the real error code. */ + /* */ + /* Setting this macro makes sense for debugging purposes only, since */ + /* it would break source compatibility of certain programs that use */ + /* FreeType 2. */ + /* */ + /* More details can be found in the files ftmoderr.h and fterrors.h. */ + /* */ +#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + + + /*************************************************************************/ + /* */ + /* Position Independent Code */ + /* */ + /* If this macro is set (which is _not_ the default), FreeType2 will */ + /* avoid creating constants that require address fixups. Instead the */ + /* constants will be moved into a struct and additional intialization */ + /* code will be used. */ + /* */ + /* Setting this macro is needed for systems that prohibit address */ + /* fixups, such as BREW. [Note that standard compilers like gcc or */ + /* clang handle PIC generation automatically; you don't have to set */ + /* FT_CONFIG_OPTION_PIC, which is only necessary for very special */ + /* compilers.] */ + /* */ + /* Note that FT_CONFIG_OPTION_PIC support is not available for all */ + /* modules (see `modules.cfg' for a complete list). For building with */ + /* FT_CONFIG_OPTION_PIC support, do the following. */ + /* */ + /* 0. Clone the repository. */ + /* 1. Define FT_CONFIG_OPTION_PIC. */ + /* 2. Remove all subdirectories in `src' that don't have */ + /* FT_CONFIG_OPTION_PIC support. */ + /* 3. Comment out the corresponding modules in `modules.cfg'. */ + /* 4. Compile. */ + /* */ +/* #define FT_CONFIG_OPTION_PIC */ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ + /* embedded bitmaps in all formats using the SFNT module (namely */ + /* TrueType & OpenType). */ + /* */ +#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ + /* load and enumerate the glyph Postscript names in a TrueType or */ + /* OpenType file. */ + /* */ + /* Note that when you do not compile the `PSNames' module by undefining */ + /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ + /* contain additional code used to read the PS Names table from a font. */ + /* */ + /* (By default, the module uses `PSNames' to extract glyph names.) */ + /* */ +#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ + /* access the internal name table in a SFNT-based format like TrueType */ + /* or OpenType. The name table contains various strings used to */ + /* describe the font, like family name, copyright, version, etc. It */ + /* does not contain any glyph name though. */ + /* */ + /* Accessing SFNT names is done through the functions declared in */ + /* `ftsnames.h'. */ + /* */ +#define TT_CONFIG_OPTION_SFNT_NAMES + + + /*************************************************************************/ + /* */ + /* TrueType CMap support */ + /* */ + /* Here you can fine-tune which TrueType CMap table format shall be */ + /* supported. */ +#define TT_CONFIG_CMAP_FORMAT_0 +#define TT_CONFIG_CMAP_FORMAT_2 +#define TT_CONFIG_CMAP_FORMAT_4 +#define TT_CONFIG_CMAP_FORMAT_6 +#define TT_CONFIG_CMAP_FORMAT_8 +#define TT_CONFIG_CMAP_FORMAT_10 +#define TT_CONFIG_CMAP_FORMAT_12 +#define TT_CONFIG_CMAP_FORMAT_13 +#define TT_CONFIG_CMAP_FORMAT_14 + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ + /* a bytecode interpreter in the TrueType driver. */ + /* */ + /* By undefining this, you will only compile the code necessary to load */ + /* TrueType glyphs without hinting. */ + /* */ + /* Do not #undef this macro here, since the build system might */ + /* define it for certain configurations only. */ + /* */ +#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ + /* subpixel hinting support into the TrueType driver. This modifies the */ + /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is */ + /* requested. */ + /* */ + /* In particular, it modifies the bytecode interpreter to interpret (or */ + /* not) instructions in a certain way so that all TrueType fonts look */ + /* like they do in a Windows ClearType (DirectWrite) environment. See */ + /* [1] for a technical overview on what this means. See `ttinterp.h' */ + /* for more details on the LEAN option. */ + /* */ + /* There are three options. */ + /* */ + /* 1. This option is associated with the `Infinality' moniker. */ + /* Contributed by an individual nicknamed Infinality with the goal of */ + /* making TrueType fonts render better than on Windows. A high */ + /* amount of configurability and flexibility, down to rules for */ + /* single glyphs in fonts, but also very slow. Its experimental and */ + /* slow nature and the original developer losing interest meant that */ + /* this option was never enabled in default builds. */ + /* */ + /* 2. The new default mode for the TrueType driver. The Infinality code */ + /* base was stripped to the bare minimum and all configurability */ + /* removed in the name of speed and simplicity. The configurability */ + /* was mainly aimed at legacy fonts like Arial, Times New Roman, or */ + /* Courier. Legacy fonts are fonts that modify vertical stems to */ + /* achieve clean black-and-white bitmaps. The new mode focuses on */ + /* applying a minimal set of rules to all fonts indiscriminately so */ + /* that modern and web fonts render well while legacy fonts render */ + /* okay. */ + /* */ + /* 3. Compile both. */ + /* */ + /* By undefining these, you get rendering behavior like on Windows */ + /* without ClearType, i.e., Windows XP without ClearType enabled and */ + /* Win9x (interpreter version v35). Or not, depending on how much */ + /* hinting blood and testing tears the font designer put into a given */ + /* font. If you define one or both subpixel hinting options, you can */ + /* switch between between v35 and the ones you define. */ + /* */ + /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ + /* defined. */ + /* */ + /* [1] http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ + /* */ +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ +#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ + /* TrueType glyph loader to use Apple's definition of how to handle */ + /* component offsets in composite glyphs. */ + /* */ + /* Apple and MS disagree on the default behavior of component offsets */ + /* in composites. Apple says that they should be scaled by the scaling */ + /* factors in the transformation matrix (roughly, it's more complex) */ + /* while MS says they should not. OpenType defines two bits in the */ + /* composite flags array which can be used to disambiguate, but old */ + /* fonts will not have them. */ + /* */ + /* http://www.microsoft.com/typography/otspec/glyf.htm */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */ + /* */ +#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ + /* support for Apple's distortable font technology (fvar, gvar, cvar, */ + /* and avar tables). This has many similarities to Type 1 Multiple */ + /* Masters support. */ + /* */ +#define TT_CONFIG_OPTION_GX_VAR_SUPPORT + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ + /* an embedded `BDF ' table within SFNT-based bitmap formats. */ + /* */ +#define TT_CONFIG_OPTION_BDF + + + /*************************************************************************/ + /* */ + /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum */ + /* number of bytecode instructions executed for a single run of the */ + /* bytecode interpreter, needed to prevent infinite loops. You don't */ + /* want to change this except for very special situations (e.g., making */ + /* a library fuzzer spend less time to handle broken fonts). */ + /* */ + /* It is not expected that this value is ever modified by a configuring */ + /* script; instead, it gets surrounded with #ifndef ... #endif so that */ + /* the value can be set as a preprocessor option on the compiler's */ + /* command line. */ + /* */ +#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES +#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */ + /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ + /* required. */ + /* */ +#define T1_MAX_DICT_DEPTH 5 + + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 16 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ + /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 256 + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ + /* files into an existing face. Note that if set, the T1 driver will be */ + /* unable to produce kerning distances. */ + /* */ +#undef T1_CONFIG_OPTION_NO_AFM + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of the Multiple Masters font support in the Type 1 */ + /* driver. */ + /* */ +#undef T1_CONFIG_OPTION_NO_MM_SUPPORT + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** C F F D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is */ + /* possible to set up the default values of the four control points that */ + /* define the stem darkening behaviour of the (new) CFF engine. For */ + /* more details please read the documentation of the */ + /* `darkening-parameters' property of the cff driver module (file */ + /* `ftcffdrv.h'), which allows the control at run-time. */ + /* */ + /* Do *not* undefine these macros! */ + /* */ +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 1000 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 275 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 1667 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 275 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 2333 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0 + + + /*************************************************************************/ + /* */ + /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ + /* engine gets compiled into FreeType. If defined, it is possible to */ + /* switch between the two engines using the `hinting-engine' property of */ + /* the cff driver module. */ + /* */ +/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ + /* support. */ + /* */ +#define AF_CONFIG_OPTION_CJK + + /*************************************************************************/ + /* */ + /* Compile autofit module with Indic script support. */ + /* */ +#define AF_CONFIG_OPTION_INDIC + + /*************************************************************************/ + /* */ + /* Compile autofit module with warp hinting. The idea of the warping */ + /* code is to slightly scale and shift a glyph within a single dimension */ + /* so that as much of its segments are aligned (more or less) on the */ + /* grid. To find out the optimal scaling and shifting value, various */ + /* parameter combinations are tried and scored. */ + /* */ + /* This experimental option is active only if the rendering mode is */ + /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the */ + /* `warping' property of the auto-hinter (see file `ftautoh.h' for more */ + /* information; by default it is switched off). */ + /* */ +#define AF_CONFIG_OPTION_USE_WARPER + + /* */ + + + /* + * This macro is obsolete. Support has been removed in FreeType + * version 2.5. + */ +/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /* + * This macro is defined if native TrueType hinting is requested by the + * definitions above. + */ +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#define TT_USE_BYTECODE_INTERPRETER + +#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1 +#define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY +#endif + +#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2 +#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL +#endif +#endif + + + /* + * Check CFF darkening parameters. The checks are the same as in function + * `cff_property_set' in file `cffdrivr.c'. + */ +#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500 +#error "Invalid CFF darkening parameters!" +#endif + +FT_END_HEADER + + +#endif /* FTOPTION_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/config/ftstdlib.h b/builddir/freetype-2.7.0/include/freetype/config/ftstdlib.h new file mode 100644 index 0000000..6eefa9f --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/config/ftstdlib.h @@ -0,0 +1,175 @@ +/***************************************************************************/ +/* */ +/* ftstdlib.h */ +/* */ +/* ANSI-specific library and header configuration file (specification */ +/* only). */ +/* */ +/* Copyright 2002-2016 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 file is used to group all #includes to the ANSI C library that */ + /* FreeType normally requires. It also defines macros to rename the */ + /* standard functions within the FreeType source code. */ + /* */ + /* Load a file which defines FTSTDLIB_H_ before this one to override it. */ + /* */ + /*************************************************************************/ + + +#ifndef FTSTDLIB_H_ +#define FTSTDLIB_H_ + + +#include <stddef.h> + +#define ft_ptrdiff_t ptrdiff_t + + + /**********************************************************************/ + /* */ + /* integer limits */ + /* */ + /* UINT_MAX and ULONG_MAX are used to automatically compute the size */ + /* of `int' and `long' in bytes at compile-time. So far, this works */ + /* for all platforms the library has been tested on. */ + /* */ + /* Note that on the extremely rare platforms that do not provide */ + /* integer types that are _exactly_ 16 and 32 bits wide (e.g. some */ + /* old Crays where `int' is 36 bits), we do not make any guarantee */ + /* about the correct behaviour of FT2 with all fonts. */ + /* */ + /* In these case, `ftconfig.h' will refuse to compile anyway with a */ + /* message like `couldn't find 32-bit type' or something similar. */ + /* */ + /**********************************************************************/ + + +#include <limits.h> + +#define FT_CHAR_BIT CHAR_BIT +#define FT_USHORT_MAX USHRT_MAX +#define FT_INT_MAX INT_MAX +#define FT_INT_MIN INT_MIN +#define FT_UINT_MAX UINT_MAX +#define FT_LONG_MIN LONG_MIN +#define FT_LONG_MAX LONG_MAX +#define FT_ULONG_MAX ULONG_MAX + + + /**********************************************************************/ + /* */ + /* character and string processing */ + /* */ + /**********************************************************************/ + + +#include <string.h> + +#define ft_memchr memchr +#define ft_memcmp memcmp +#define ft_memcpy memcpy +#define ft_memmove memmove +#define ft_memset memset +#define ft_strcat strcat +#define ft_strcmp strcmp +#define ft_strcpy strcpy +#define ft_strlen strlen +#define ft_strncmp strncmp +#define ft_strncpy strncpy +#define ft_strrchr strrchr +#define ft_strstr strstr + + + /**********************************************************************/ + /* */ + /* file handling */ + /* */ + /**********************************************************************/ + + +#include <stdio.h> + +#define FT_FILE FILE +#define ft_fclose fclose +#define ft_fopen fopen +#define ft_fread fread +#define ft_fseek fseek +#define ft_ftell ftell +#define ft_sprintf sprintf + + + /**********************************************************************/ + /* */ + /* sorting */ + /* */ + /**********************************************************************/ + + +#include <stdlib.h> + +#define ft_qsort qsort + + + /**********************************************************************/ + /* */ + /* memory allocation */ + /* */ + /**********************************************************************/ + + +#define ft_scalloc calloc +#define ft_sfree free +#define ft_smalloc malloc +#define ft_srealloc realloc + + + /**********************************************************************/ + /* */ + /* miscellaneous */ + /* */ + /**********************************************************************/ + + +#define ft_strtol strtol +#define ft_getenv getenv + + + /**********************************************************************/ + /* */ + /* execution control */ + /* */ + /**********************************************************************/ + + +#include <setjmp.h> + +#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */ + /* jmp_buf is defined as a macro */ + /* on certain platforms */ + +#define ft_longjmp longjmp +#define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) /* same thing here */ + + + /* the following is only used for debugging purposes, i.e., if */ + /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined */ + +#include <stdarg.h> + + +#endif /* FTSTDLIB_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/freetype.h b/builddir/freetype-2.7.0/include/freetype/freetype.h new file mode 100644 index 0000000..3a50734 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/freetype.h @@ -0,0 +1,4306 @@ +/***************************************************************************/ +/* */ +/* freetype.h */ +/* */ +/* FreeType high-level API and common types (specification only). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FREETYPE_H_ +#define FREETYPE_H_ + + +#ifndef FT_FREETYPE_H +#error "`ft2build.h' hasn't been included yet!" +#error "Please always use macros to include FreeType header files." +#error "Example:" +#error " #include <ft2build.h>" +#error " #include FT_FREETYPE_H" +#endif + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_TYPES_H +#include FT_ERRORS_H + + +FT_BEGIN_HEADER + + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* header_inclusion */ + /* */ + /* <Title> */ + /* FreeType's header inclusion scheme */ + /* */ + /* <Abstract> */ + /* How client applications should include FreeType header files. */ + /* */ + /* <Description> */ + /* To be as flexible as possible (and for historical reasons), */ + /* FreeType uses a very special inclusion scheme to load header */ + /* files, for example */ + /* */ + /* { */ + /* #include <ft2build.h> */ + /* */ + /* #include FT_FREETYPE_H */ + /* #include FT_OUTLINE_H */ + /* } */ + /* */ + /* A compiler and its preprocessor only needs an include path to find */ + /* the file `ft2build.h'; the exact locations and names of the other */ + /* FreeType header files are hidden by preprocessor macro names, */ + /* loaded by `ft2build.h'. The API documentation always gives the */ + /* header macro name needed for a particular function. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* user_allocation */ + /* */ + /* <Title> */ + /* User allocation */ + /* */ + /* <Abstract> */ + /* How client applications should allocate FreeType data structures. */ + /* */ + /* <Description> */ + /* FreeType assumes that structures allocated by the user and passed */ + /* as arguments are zeroed out except for the actual data. In other */ + /* words, it is recommended to use `calloc' (or variants of it) */ + /* instead of `malloc' for allocation. */ + /* */ + /*************************************************************************/ + + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S I C T Y P E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* base_interface */ + /* */ + /* <Title> */ + /* Base Interface */ + /* */ + /* <Abstract> */ + /* The FreeType~2 base font interface. */ + /* */ + /* <Description> */ + /* This section describes the most important public high-level API */ + /* functions of FreeType~2. */ + /* */ + /* <Order> */ + /* FT_Library */ + /* FT_Face */ + /* FT_Size */ + /* FT_GlyphSlot */ + /* FT_CharMap */ + /* FT_Encoding */ + /* FT_ENC_TAG */ + /* */ + /* FT_FaceRec */ + /* */ + /* FT_FACE_FLAG_SCALABLE */ + /* FT_FACE_FLAG_FIXED_SIZES */ + /* FT_FACE_FLAG_FIXED_WIDTH */ + /* FT_FACE_FLAG_HORIZONTAL */ + /* FT_FACE_FLAG_VERTICAL */ + /* FT_FACE_FLAG_COLOR */ + /* FT_FACE_FLAG_SFNT */ + /* FT_FACE_FLAG_CID_KEYED */ + /* FT_FACE_FLAG_TRICKY */ + /* FT_FACE_FLAG_KERNING */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS */ + /* FT_FACE_FLAG_GLYPH_NAMES */ + /* FT_FACE_FLAG_EXTERNAL_STREAM */ + /* FT_FACE_FLAG_HINTER */ + /* */ + /* FT_HAS_HORIZONTAL */ + /* FT_HAS_VERTICAL */ + /* FT_HAS_KERNING */ + /* FT_HAS_FIXED_SIZES */ + /* FT_HAS_GLYPH_NAMES */ + /* FT_HAS_MULTIPLE_MASTERS */ + /* FT_HAS_COLOR */ + /* */ + /* FT_IS_SFNT */ + /* FT_IS_SCALABLE */ + /* FT_IS_FIXED_WIDTH */ + /* FT_IS_CID_KEYED */ + /* FT_IS_TRICKY */ + /* */ + /* FT_STYLE_FLAG_BOLD */ + /* FT_STYLE_FLAG_ITALIC */ + /* */ + /* FT_SizeRec */ + /* FT_Size_Metrics */ + /* */ + /* FT_GlyphSlotRec */ + /* FT_Glyph_Metrics */ + /* FT_SubGlyph */ + /* */ + /* FT_Bitmap_Size */ + /* */ + /* FT_Init_FreeType */ + /* FT_Done_FreeType */ + /* */ + /* FT_New_Face */ + /* FT_Done_Face */ + /* FT_Reference_Face */ + /* FT_New_Memory_Face */ + /* FT_Open_Face */ + /* FT_Open_Args */ + /* FT_Parameter */ + /* FT_Attach_File */ + /* FT_Attach_Stream */ + /* */ + /* FT_Set_Char_Size */ + /* FT_Set_Pixel_Sizes */ + /* FT_Request_Size */ + /* FT_Select_Size */ + /* FT_Size_Request_Type */ + /* FT_Size_RequestRec */ + /* FT_Size_Request */ + /* FT_Set_Transform */ + /* FT_Load_Glyph */ + /* FT_Get_Char_Index */ + /* FT_Get_First_Char */ + /* FT_Get_Next_Char */ + /* FT_Get_Name_Index */ + /* FT_Load_Char */ + /* */ + /* FT_OPEN_MEMORY */ + /* FT_OPEN_STREAM */ + /* FT_OPEN_PATHNAME */ + /* FT_OPEN_DRIVER */ + /* FT_OPEN_PARAMS */ + /* */ + /* FT_LOAD_DEFAULT */ + /* FT_LOAD_RENDER */ + /* FT_LOAD_MONOCHROME */ + /* FT_LOAD_LINEAR_DESIGN */ + /* FT_LOAD_NO_SCALE */ + /* FT_LOAD_NO_HINTING */ + /* FT_LOAD_NO_BITMAP */ + /* FT_LOAD_NO_AUTOHINT */ + /* FT_LOAD_COLOR */ + /* */ + /* FT_LOAD_VERTICAL_LAYOUT */ + /* FT_LOAD_IGNORE_TRANSFORM */ + /* FT_LOAD_FORCE_AUTOHINT */ + /* FT_LOAD_NO_RECURSE */ + /* FT_LOAD_PEDANTIC */ + /* */ + /* FT_LOAD_TARGET_NORMAL */ + /* FT_LOAD_TARGET_LIGHT */ + /* FT_LOAD_TARGET_MONO */ + /* FT_LOAD_TARGET_LCD */ + /* FT_LOAD_TARGET_LCD_V */ + /* */ + /* FT_LOAD_TARGET_MODE */ + /* */ + /* FT_Render_Glyph */ + /* FT_Render_Mode */ + /* FT_Get_Kerning */ + /* FT_Kerning_Mode */ + /* FT_Get_Track_Kerning */ + /* FT_Get_Glyph_Name */ + /* FT_Get_Postscript_Name */ + /* */ + /* FT_CharMapRec */ + /* FT_Select_Charmap */ + /* FT_Set_Charmap */ + /* FT_Get_Charmap_Index */ + /* */ + /* FT_Get_FSType_Flags */ + /* FT_Get_SubGlyph_Info */ + /* */ + /* FT_Face_Internal */ + /* FT_Size_Internal */ + /* FT_Slot_Internal */ + /* */ + /* FT_FACE_FLAG_XXX */ + /* FT_STYLE_FLAG_XXX */ + /* FT_OPEN_XXX */ + /* FT_LOAD_XXX */ + /* FT_LOAD_TARGET_XXX */ + /* FT_SUBGLYPH_FLAG_XXX */ + /* FT_FSTYPE_XXX */ + /* */ + /* FT_HAS_FAST_GLYPHS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Glyph_Metrics */ + /* */ + /* <Description> */ + /* A structure used to model the metrics of a single glyph. The */ + /* values are expressed in 26.6 fractional pixel format; if the flag */ + /* @FT_LOAD_NO_SCALE has been used while loading the glyph, values */ + /* are expressed in font units instead. */ + /* */ + /* <Fields> */ + /* width :: */ + /* The glyph's width. */ + /* */ + /* height :: */ + /* The glyph's height. */ + /* */ + /* horiBearingX :: */ + /* Left side bearing for horizontal layout. */ + /* */ + /* horiBearingY :: */ + /* Top side bearing for horizontal layout. */ + /* */ + /* horiAdvance :: */ + /* Advance width for horizontal layout. */ + /* */ + /* vertBearingX :: */ + /* Left side bearing for vertical layout. */ + /* */ + /* vertBearingY :: */ + /* Top side bearing for vertical layout. Larger positive values */ + /* mean further below the vertical glyph origin. */ + /* */ + /* vertAdvance :: */ + /* Advance height for vertical layout. Positive values mean the */ + /* glyph has a positive advance downward. */ + /* */ + /* <Note> */ + /* If not disabled with @FT_LOAD_NO_HINTING, the values represent */ + /* dimensions of the hinted glyph (in case hinting is applicable). */ + /* */ + /* Stroking a glyph with an outside border does not increase */ + /* `horiAdvance' or `vertAdvance'; you have to manually adjust these */ + /* values to account for the added width and height. */ + /* */ + typedef struct FT_Glyph_Metrics_ + { + FT_Pos width; + FT_Pos height; + + FT_Pos horiBearingX; + FT_Pos horiBearingY; + FT_Pos horiAdvance; + + FT_Pos vertBearingX; + FT_Pos vertBearingY; + FT_Pos vertAdvance; + + } FT_Glyph_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap_Size */ + /* */ + /* <Description> */ + /* This structure models the metrics of a bitmap strike (i.e., a set */ + /* of glyphs for a given point size and resolution) in a bitmap font. */ + /* It is used for the `available_sizes' field of @FT_Face. */ + /* */ + /* <Fields> */ + /* height :: The vertical distance, in pixels, between two */ + /* consecutive baselines. It is always positive. */ + /* */ + /* width :: The average width, in pixels, of all glyphs in the */ + /* strike. */ + /* */ + /* size :: The nominal size of the strike in 26.6 fractional */ + /* points. This field is not very useful. */ + /* */ + /* x_ppem :: The horizontal ppem (nominal width) in 26.6 fractional */ + /* pixels. */ + /* */ + /* y_ppem :: The vertical ppem (nominal height) in 26.6 fractional */ + /* pixels. */ + /* */ + /* <Note> */ + /* Windows FNT: */ + /* The nominal size given in a FNT font is not reliable. Thus when */ + /* the driver finds it incorrect, it sets `size' to some calculated */ + /* values and sets `x_ppem' and `y_ppem' to the pixel width and */ + /* height given in the font, respectively. */ + /* */ + /* TrueType embedded bitmaps: */ + /* `size', `width', and `height' values are not contained in the */ + /* bitmap strike itself. They are computed from the global font */ + /* parameters. */ + /* */ + typedef struct FT_Bitmap_Size_ + { + FT_Short height; + FT_Short width; + + FT_Pos size; + + FT_Pos x_ppem; + FT_Pos y_ppem; + + } FT_Bitmap_Size; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Library */ + /* */ + /* <Description> */ + /* A handle to a FreeType library instance. Each `library' is */ + /* completely independent from the others; it is the `root' of a set */ + /* of objects like fonts, faces, sizes, etc. */ + /* */ + /* It also embeds a memory manager (see @FT_Memory), as well as a */ + /* scan-line converter object (see @FT_Raster). */ + /* */ + /* In multi-threaded applications it is easiest to use one */ + /* `FT_Library' object per thread. In case this is too cumbersome, */ + /* a single `FT_Library' object across threads is possible also */ + /* (since FreeType version 2.5.6), as long as a mutex lock is used */ + /* around @FT_New_Face and @FT_Done_Face. */ + /* */ + /* <Note> */ + /* Library objects are normally created by @FT_Init_FreeType, and */ + /* destroyed with @FT_Done_FreeType. If you need reference-counting */ + /* (cf. @FT_Reference_Library), use @FT_New_Library and */ + /* @FT_Done_Library. */ + /* */ + typedef struct FT_LibraryRec_ *FT_Library; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Module */ + /* */ + /* <Description> */ + /* A handle to a given FreeType module object. Each module can be a */ + /* font driver, a renderer, or anything else that provides services */ + /* to the formers. */ + /* */ + typedef struct FT_ModuleRec_* FT_Module; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Driver */ + /* */ + /* <Description> */ + /* A handle to a given FreeType font driver object. Each font driver */ + /* is a special module capable of creating faces from font files. */ + /* */ + typedef struct FT_DriverRec_* FT_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Renderer */ + /* */ + /* <Description> */ + /* A handle to a given FreeType renderer. A renderer is a special */ + /* module in charge of converting a glyph image to a bitmap, when */ + /* necessary. Each renderer supports a given glyph image format, and */ + /* one or more target surface depths. */ + /* */ + typedef struct FT_RendererRec_* FT_Renderer; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* base_interface */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face */ + /* */ + /* <Description> */ + /* A handle to a given typographic face object. A face object models */ + /* a given typeface, in a given style. */ + /* */ + /* <Note> */ + /* Each face object also owns a single @FT_GlyphSlot object, as well */ + /* as one or more @FT_Size objects. */ + /* */ + /* Use @FT_New_Face or @FT_Open_Face to create a new face object from */ + /* a given filepathname or a custom input stream. */ + /* */ + /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ + /* */ + /* An `FT_Face' object can only be safely used from one thread at a */ + /* time. Similarly, creation and destruction of `FT_Face' with the */ + /* same @FT_Library object can only be done from one thread at a */ + /* time. On the other hand, functions like @FT_Load_Glyph and its */ + /* siblings are thread-safe and do not need the lock to be held as */ + /* long as the same `FT_Face' object is not used from multiple */ + /* threads at the same time. */ + /* */ + /* <Also> */ + /* See @FT_FaceRec for the publicly accessible fields of a given face */ + /* object. */ + /* */ + typedef struct FT_FaceRec_* FT_Face; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size */ + /* */ + /* <Description> */ + /* A handle to an object used to model a face scaled to a given */ + /* character size. */ + /* */ + /* <Note> */ + /* Each @FT_Face has an _active_ @FT_Size object that is used by */ + /* functions like @FT_Load_Glyph to determine the scaling */ + /* transformation that in turn is used to load and hint glyphs and */ + /* metrics. */ + /* */ + /* You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, */ + /* @FT_Request_Size or even @FT_Select_Size to change the content */ + /* (i.e., the scaling values) of the active @FT_Size. */ + /* */ + /* You can use @FT_New_Size to create additional size objects for a */ + /* given @FT_Face, but they won't be used by other functions until */ + /* you activate it through @FT_Activate_Size. Only one size can be */ + /* activated at any given time per face. */ + /* */ + /* <Also> */ + /* See @FT_SizeRec for the publicly accessible fields of a given size */ + /* object. */ + /* */ + typedef struct FT_SizeRec_* FT_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a given `glyph slot'. A slot is a container where it */ + /* is possible to load any of the glyphs contained in its parent */ + /* face. */ + /* */ + /* In other words, each time you call @FT_Load_Glyph or */ + /* @FT_Load_Char, the slot's content is erased by the new glyph data, */ + /* i.e., the glyph's metrics, its image (bitmap or outline), and */ + /* other control information. */ + /* */ + /* <Also> */ + /* See @FT_GlyphSlotRec for the publicly accessible glyph fields. */ + /* */ + typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_CharMap */ + /* */ + /* <Description> */ + /* A handle to a given character map. A charmap is used to translate */ + /* character codes in a given encoding into glyph indexes for its */ + /* parent's face. Some font formats may provide several charmaps per */ + /* font. */ + /* */ + /* Each face object owns zero or more charmaps, but only one of them */ + /* can be `active' and used by @FT_Get_Char_Index or @FT_Load_Char. */ + /* */ + /* The list of available charmaps in a face is available through the */ + /* `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec. */ + /* */ + /* The currently active charmap is available as `face->charmap'. */ + /* You should call @FT_Set_Charmap to change it. */ + /* */ + /* <Note> */ + /* When a new face is created (either through @FT_New_Face or */ + /* @FT_Open_Face), the library looks for a Unicode charmap within */ + /* the list and automatically activates it. */ + /* */ + /* <Also> */ + /* See @FT_CharMapRec for the publicly accessible fields of a given */ + /* character map. */ + /* */ + typedef struct FT_CharMapRec_* FT_CharMap; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_ENC_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags into an unsigned long. It is */ + /* used to define `encoding' identifiers (see @FT_Encoding). */ + /* */ + /* <Note> */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* { */ + /* #define FT_ENC_TAG( value, a, b, c, d ) value */ + /* } */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ + +#ifndef FT_ENC_TAG +#define FT_ENC_TAG( value, a, b, c, d ) \ + value = ( ( (FT_UInt32)(a) << 24 ) | \ + ( (FT_UInt32)(b) << 16 ) | \ + ( (FT_UInt32)(c) << 8 ) | \ + (FT_UInt32)(d) ) + +#endif /* FT_ENC_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Encoding */ + /* */ + /* <Description> */ + /* An enumeration used to specify character sets supported by */ + /* charmaps. Used in the @FT_Select_Charmap API function. */ + /* */ + /* <Note> */ + /* Despite the name, this enumeration lists specific character */ + /* repertories (i.e., charsets), and not text encoding methods (e.g., */ + /* UTF-8, UTF-16, etc.). */ + /* */ + /* Other encodings might be defined in the future. */ + /* */ + /* <Values> */ + /* FT_ENCODING_NONE :: */ + /* The encoding value~0 is reserved. */ + /* */ + /* FT_ENCODING_UNICODE :: */ + /* Corresponds to the Unicode character set. This value covers */ + /* all versions of the Unicode repertoire, including ASCII and */ + /* Latin-1. Most fonts include a Unicode charmap, but not all */ + /* of them. */ + /* */ + /* For example, if you want to access Unicode value U+1F028 (and */ + /* the font contains it), use value 0x1F028 as the input value for */ + /* @FT_Get_Char_Index. */ + /* */ + /* FT_ENCODING_MS_SYMBOL :: */ + /* Corresponds to the Microsoft Symbol encoding, used to encode */ + /* mathematical symbols and wingdings. For more information, see */ + /* `http://www.microsoft.com/typography/otspec/recom.htm', */ + /* `http://www.kostis.net/charsets/symbol.htm', and */ + /* `http://www.kostis.net/charsets/wingding.htm'. */ + /* */ + /* This encoding uses character codes from the PUA (Private Unicode */ + /* Area) in the range U+F020-U+F0FF. */ + /* */ + /* FT_ENCODING_SJIS :: */ + /* Corresponds to Japanese SJIS encoding. More info at */ + /* `http://en.wikipedia.org/wiki/Shift_JIS'. */ + /* See note on multi-byte encodings below. */ + /* */ + /* FT_ENCODING_GB2312 :: */ + /* Corresponds to an encoding system for Simplified Chinese as */ + /* used in mainland China. */ + /* */ + /* FT_ENCODING_BIG5 :: */ + /* Corresponds to an encoding system for Traditional Chinese as */ + /* used in Taiwan and Hong Kong. */ + /* */ + /* FT_ENCODING_WANSUNG :: */ + /* Corresponds to the Korean encoding system known as Wansung. */ + /* For more information see */ + /* `https://msdn.microsoft.com/en-US/goglobal/cc305154'. */ + /* */ + /* FT_ENCODING_JOHAB :: */ + /* The Korean standard character set (KS~C 5601-1992), which */ + /* corresponds to MS Windows code page 1361. This character set */ + /* includes all possible Hangeul character combinations. */ + /* */ + /* FT_ENCODING_ADOBE_LATIN_1 :: */ + /* Corresponds to a Latin-1 encoding as defined in a Type~1 */ + /* PostScript font. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_ADOBE_STANDARD :: */ + /* Corresponds to the Adobe Standard encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_EXPERT :: */ + /* Corresponds to the Adobe Expert encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_CUSTOM :: */ + /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ + /* OpenType/CFF fonts. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_APPLE_ROMAN :: */ + /* Corresponds to the 8-bit Apple roman encoding. Many TrueType */ + /* and OpenType fonts contain a charmap for this encoding, since */ + /* older versions of Mac OS are able to use it. */ + /* */ + /* FT_ENCODING_OLD_LATIN_2 :: */ + /* This value is deprecated and was never used nor reported by */ + /* FreeType. Don't use or test for it. */ + /* */ + /* FT_ENCODING_MS_SJIS :: */ + /* Same as FT_ENCODING_SJIS. Deprecated. */ + /* */ + /* FT_ENCODING_MS_GB2312 :: */ + /* Same as FT_ENCODING_GB2312. Deprecated. */ + /* */ + /* FT_ENCODING_MS_BIG5 :: */ + /* Same as FT_ENCODING_BIG5. Deprecated. */ + /* */ + /* FT_ENCODING_MS_WANSUNG :: */ + /* Same as FT_ENCODING_WANSUNG. Deprecated. */ + /* */ + /* FT_ENCODING_MS_JOHAB :: */ + /* Same as FT_ENCODING_JOHAB. Deprecated. */ + /* */ + /* <Note> */ + /* By default, FreeType automatically synthesizes a Unicode charmap */ + /* for PostScript fonts, using their glyph names dictionaries. */ + /* However, it also reports the encodings defined explicitly in the */ + /* font file, for the cases when they are needed, with the Adobe */ + /* values as well. */ + /* */ + /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ + /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ + /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out */ + /* which encoding is really present. If, for example, the */ + /* `cs_registry' field is `KOI8' and the `cs_encoding' field is `R', */ + /* the font is encoded in KOI8-R. */ + /* */ + /* FT_ENCODING_NONE is always set (with a single exception) by the */ + /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ + /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ + /* which encoding is really present. For example, */ + /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ + /* Russian). */ + /* */ + /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ + /* and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to */ + /* FT_ENCODING_APPLE_ROMAN). */ + /* */ + /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ + /* @FT_Get_CMap_Language_ID to query the Mac language ID that may */ + /* be needed to be able to distinguish Apple encoding variants. See */ + /* */ + /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt */ + /* */ + /* to get an idea how to do that. Basically, if the language ID */ + /* is~0, don't use it, otherwise subtract 1 from the language ID. */ + /* Then examine `encoding_id'. If, for example, `encoding_id' is */ + /* @TT_MAC_ID_ROMAN and the language ID (minus~1) is */ + /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ + /* @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi */ + /* variant the Arabic encoding. */ + /* */ + typedef enum FT_Encoding_ + { + FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ), + + FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ), + FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ), + + FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ), + FT_ENC_TAG( FT_ENCODING_GB2312, 'g', 'b', ' ', ' ' ), + FT_ENC_TAG( FT_ENCODING_BIG5, 'b', 'i', 'g', '5' ), + FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ), + FT_ENC_TAG( FT_ENCODING_JOHAB, 'j', 'o', 'h', 'a' ), + + /* for backwards compatibility */ + FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS, + FT_ENCODING_MS_GB2312 = FT_ENCODING_GB2312, + FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5, + FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG, + FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB, + + FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT, 'A', 'D', 'B', 'E' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM, 'A', 'D', 'B', 'C' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1, 'l', 'a', 't', '1' ), + + FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ), + + FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' ) + + } FT_Encoding; + + + /* these constants are deprecated; use the corresponding `FT_Encoding' */ + /* values instead */ +#define ft_encoding_none FT_ENCODING_NONE +#define ft_encoding_unicode FT_ENCODING_UNICODE +#define ft_encoding_symbol FT_ENCODING_MS_SYMBOL +#define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1 +#define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2 +#define ft_encoding_sjis FT_ENCODING_SJIS +#define ft_encoding_gb2312 FT_ENCODING_GB2312 +#define ft_encoding_big5 FT_ENCODING_BIG5 +#define ft_encoding_wansung FT_ENCODING_WANSUNG +#define ft_encoding_johab FT_ENCODING_JOHAB + +#define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD +#define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT +#define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM +#define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_CharMapRec */ + /* */ + /* <Description> */ + /* The base charmap structure. */ + /* */ + /* <Fields> */ + /* face :: A handle to the parent face object. */ + /* */ + /* encoding :: An @FT_Encoding tag identifying the charmap. Use */ + /* this with @FT_Select_Charmap. */ + /* */ + /* platform_id :: An ID number describing the platform for the */ + /* following encoding ID. This comes directly from */ + /* the TrueType specification and should be emulated */ + /* for other formats. */ + /* */ + /* encoding_id :: A platform specific encoding number. This also */ + /* comes from the TrueType specification and should be */ + /* emulated similarly. */ + /* */ + typedef struct FT_CharMapRec_ + { + FT_Face face; + FT_Encoding encoding; + FT_UShort platform_id; + FT_UShort encoding_id; + + } FT_CharMapRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S E O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Face_InternalRec' structure, used to */ + /* model private data of a given @FT_Face object. */ + /* */ + /* This structure might change between releases of FreeType~2 and is */ + /* not generally available to client applications. */ + /* */ + typedef struct FT_Face_InternalRec_* FT_Face_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_FaceRec */ + /* */ + /* <Description> */ + /* FreeType root face class structure. A face object models a */ + /* typeface in a font file. */ + /* */ + /* <Fields> */ + /* num_faces :: The number of faces in the font file. Some */ + /* font formats can have multiple faces in */ + /* a font file. */ + /* */ + /* face_index :: This field holds two different values. */ + /* Bits 0-15 are the index of the face in the */ + /* font file (starting with value~0). They */ + /* are set to~0 if there is only one face in */ + /* the font file. */ + /* */ + /* Bits 16-30 are relevant to GX variation */ + /* fonts only, holding the named instance */ + /* index for the current face index (starting */ + /* with value~1; value~0 indicates font access */ + /* without GX variation data). For non-GX */ + /* fonts, bits 16-30 are ignored. If we have */ + /* the third named instance of face~4, say, */ + /* `face_index' is set to 0x00030004. */ + /* */ + /* Bit 31 is always zero (this is, */ + /* `face_index' is always a positive value). */ + /* */ + /* face_flags :: A set of bit flags that give important */ + /* information about the face; see */ + /* @FT_FACE_FLAG_XXX for the details. */ + /* */ + /* style_flags :: The lower 16~bits contain a set of bit */ + /* flags indicating the style of the face; see */ + /* @FT_STYLE_FLAG_XXX for the details. Bits */ + /* 16-30 hold the number of named instances */ + /* available for the current face if we have a */ + /* GX variation (sub)font. Bit 31 is always */ + /* zero (this is, `style_flags' is always a */ + /* positive value). */ + /* */ + /* num_glyphs :: The number of glyphs in the face. If the */ + /* face is scalable and has sbits (see */ + /* `num_fixed_sizes'), it is set to the number */ + /* of outline glyphs. */ + /* */ + /* For CID-keyed fonts, this value gives the */ + /* highest CID used in the font. */ + /* */ + /* family_name :: The face's family name. This is an ASCII */ + /* string, usually in English, that describes */ + /* the typeface's family (like `Times New */ + /* Roman', `Bodoni', `Garamond', etc). This */ + /* is a least common denominator used to list */ + /* fonts. Some formats (TrueType & OpenType) */ + /* provide localized and Unicode versions of */ + /* this string. Applications should use the */ + /* format specific interface to access them. */ + /* Can be NULL (e.g., in fonts embedded in a */ + /* PDF file). */ + /* */ + /* In case the font doesn't provide a specific */ + /* family name entry, FreeType tries to */ + /* synthesize one, deriving it from other name */ + /* entries. */ + /* */ + /* style_name :: The face's style name. This is an ASCII */ + /* string, usually in English, that describes */ + /* the typeface's style (like `Italic', */ + /* `Bold', `Condensed', etc). Not all font */ + /* formats provide a style name, so this field */ + /* is optional, and can be set to NULL. As */ + /* for `family_name', some formats provide */ + /* localized and Unicode versions of this */ + /* string. Applications should use the format */ + /* specific interface to access them. */ + /* */ + /* num_fixed_sizes :: The number of bitmap strikes in the face. */ + /* Even if the face is scalable, there might */ + /* still be bitmap strikes, which are called */ + /* `sbits' in that case. */ + /* */ + /* available_sizes :: An array of @FT_Bitmap_Size for all bitmap */ + /* strikes in the face. It is set to NULL if */ + /* there is no bitmap strike. */ + /* */ + /* num_charmaps :: The number of charmaps in the face. */ + /* */ + /* charmaps :: An array of the charmaps of the face. */ + /* */ + /* generic :: A field reserved for client uses. See the */ + /* @FT_Generic type description. */ + /* */ + /* bbox :: The font bounding box. Coordinates are */ + /* expressed in font units (see */ + /* `units_per_EM'). The box is large enough */ + /* to contain any glyph from the font. Thus, */ + /* `bbox.yMax' can be seen as the `maximum */ + /* ascender', and `bbox.yMin' as the `minimum */ + /* descender'. Only relevant for scalable */ + /* formats. */ + /* */ + /* Note that the bounding box might be off by */ + /* (at least) one pixel for hinted fonts. See */ + /* @FT_Size_Metrics for further discussion. */ + /* */ + /* units_per_EM :: The number of font units per EM square for */ + /* this face. This is typically 2048 for */ + /* TrueType fonts, and 1000 for Type~1 fonts. */ + /* Only relevant for scalable formats. */ + /* */ + /* ascender :: The typographic ascender of the face, */ + /* expressed in font units. For font formats */ + /* not having this information, it is set to */ + /* `bbox.yMax'. Only relevant for scalable */ + /* formats. */ + /* */ + /* descender :: The typographic descender of the face, */ + /* expressed in font units. For font formats */ + /* not having this information, it is set to */ + /* `bbox.yMin'. Note that this field is */ + /* usually negative. Only relevant for */ + /* scalable formats. */ + /* */ + /* height :: This value is the vertical distance */ + /* between two consecutive baselines, */ + /* expressed in font units. It is always */ + /* positive. Only relevant for scalable */ + /* formats. */ + /* */ + /* If you want the global glyph height, use */ + /* `ascender - descender'. */ + /* */ + /* max_advance_width :: The maximum advance width, in font units, */ + /* for all glyphs in this face. This can be */ + /* used to make word wrapping computations */ + /* faster. Only relevant for scalable */ + /* formats. */ + /* */ + /* max_advance_height :: The maximum advance height, in font units, */ + /* for all glyphs in this face. This is only */ + /* relevant for vertical layouts, and is set */ + /* to `height' for fonts that do not provide */ + /* vertical metrics. Only relevant for */ + /* scalable formats. */ + /* */ + /* underline_position :: The position, in font units, of the */ + /* underline line for this face. It is the */ + /* center of the underlining stem. Only */ + /* relevant for scalable formats. */ + /* */ + /* underline_thickness :: The thickness, in font units, of the */ + /* underline for this face. Only relevant for */ + /* scalable formats. */ + /* */ + /* glyph :: The face's associated glyph slot(s). */ + /* */ + /* size :: The current active size for this face. */ + /* */ + /* charmap :: The current active charmap for this face. */ + /* */ + /* <Note> */ + /* Fields may be changed after a call to @FT_Attach_File or */ + /* @FT_Attach_Stream. */ + /* */ + typedef struct FT_FaceRec_ + { + FT_Long num_faces; + FT_Long face_index; + + FT_Long face_flags; + FT_Long style_flags; + + FT_Long num_glyphs; + + FT_String* family_name; + FT_String* style_name; + + FT_Int num_fixed_sizes; + FT_Bitmap_Size* available_sizes; + + FT_Int num_charmaps; + FT_CharMap* charmaps; + + FT_Generic generic; + + /*# The following member variables (down to `underline_thickness') */ + /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */ + /*# for bitmap fonts. */ + FT_BBox bbox; + + FT_UShort units_per_EM; + FT_Short ascender; + FT_Short descender; + FT_Short height; + + FT_Short max_advance_width; + FT_Short max_advance_height; + + FT_Short underline_position; + FT_Short underline_thickness; + + FT_GlyphSlot glyph; + FT_Size size; + FT_CharMap charmap; + + /*@private begin */ + + FT_Driver driver; + FT_Memory memory; + FT_Stream stream; + + FT_ListRec sizes_list; + + FT_Generic autohint; /* face-specific auto-hinter data */ + void* extensions; /* unused */ + + FT_Face_Internal internal; + + /*@private end */ + + } FT_FaceRec; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_FACE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used in the `face_flags' field of the */ + /* @FT_FaceRec structure. They inform client applications of */ + /* properties of the corresponding face. */ + /* */ + /* <Values> */ + /* FT_FACE_FLAG_SCALABLE :: */ + /* Indicates that the face contains outline glyphs. This doesn't */ + /* prevent bitmap strikes, i.e., a face can have both this and */ + /* @FT_FACE_FLAG_FIXED_SIZES set. */ + /* */ + /* FT_FACE_FLAG_FIXED_SIZES :: */ + /* Indicates that the face contains bitmap strikes. See also the */ + /* `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec. */ + /* */ + /* FT_FACE_FLAG_FIXED_WIDTH :: */ + /* Indicates that the face contains fixed-width characters (like */ + /* Courier, Lucido, MonoType, etc.). */ + /* */ + /* FT_FACE_FLAG_SFNT :: */ + /* Indicates that the face uses the `sfnt' storage scheme. For */ + /* now, this means TrueType and OpenType. */ + /* */ + /* FT_FACE_FLAG_HORIZONTAL :: */ + /* Indicates that the face contains horizontal glyph metrics. This */ + /* should be set for all common formats. */ + /* */ + /* FT_FACE_FLAG_VERTICAL :: */ + /* Indicates that the face contains vertical glyph metrics. This */ + /* is only available in some formats, not all of them. */ + /* */ + /* FT_FACE_FLAG_KERNING :: */ + /* Indicates that the face contains kerning information. If set, */ + /* the kerning distance can be retrieved through the function */ + /* @FT_Get_Kerning. Otherwise the function always return the */ + /* vector (0,0). Note that FreeType doesn't handle kerning data */ + /* from the `GPOS' table (as present in some OpenType fonts). */ + /* */ + /* FT_FACE_FLAG_FAST_GLYPHS :: */ + /* THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. */ + /* */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS :: */ + /* Indicates that the font contains multiple masters and is capable */ + /* of interpolating between them. See the multiple-masters */ + /* specific API for details. */ + /* */ + /* FT_FACE_FLAG_GLYPH_NAMES :: */ + /* Indicates that the font contains glyph names that can be */ + /* retrieved through @FT_Get_Glyph_Name. Note that some TrueType */ + /* fonts contain broken glyph name tables. Use the function */ + /* @FT_Has_PS_Glyph_Names when needed. */ + /* */ + /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ + /* Used internally by FreeType to indicate that a face's stream was */ + /* provided by the client application and should not be destroyed */ + /* when @FT_Done_Face is called. Don't read or test this flag. */ + /* */ + /* FT_FACE_FLAG_HINTER :: */ + /* Set if the font driver has a hinting machine of its own. For */ + /* example, with TrueType fonts, it makes sense to use data from */ + /* the SFNT `gasp' table only if the native TrueType hinting engine */ + /* (with the bytecode interpreter) is available and active. */ + /* */ + /* FT_FACE_FLAG_CID_KEYED :: */ + /* Set if the font is CID-keyed. In that case, the font is not */ + /* accessed by glyph indices but by CID values. For subsetted */ + /* CID-keyed fonts this has the consequence that not all index */ + /* values are a valid argument to FT_Load_Glyph. Only the CID */ + /* values for which corresponding glyphs in the subsetted font */ + /* exist make FT_Load_Glyph return successfully; in all other cases */ + /* you get an `FT_Err_Invalid_Argument' error. */ + /* */ + /* Note that CID-keyed fonts that are in an SFNT wrapper don't */ + /* have this flag set since the glyphs are accessed in the normal */ + /* way (using contiguous indices); the `CID-ness' isn't visible to */ + /* the application. */ + /* */ + /* FT_FACE_FLAG_TRICKY :: */ + /* Set if the font is `tricky', this is, it always needs the */ + /* font format's native hinting engine to get a reasonable result. */ + /* A typical example is the Chinese font `mingli.ttf' that uses */ + /* TrueType bytecode instructions to move and scale all of its */ + /* subglyphs. */ + /* */ + /* It is not possible to auto-hint such fonts using */ + /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ + /* @FT_LOAD_NO_HINTING. You have to set both @FT_LOAD_NO_HINTING */ + /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ + /* probably never want this except for demonstration purposes. */ + /* */ + /* Currently, there are about a dozen TrueType fonts in the list of */ + /* tricky fonts; they are hard-coded in file `ttobjs.c'. */ + /* */ + /* FT_FACE_FLAG_COLOR :: */ + /* Set if the font has color glyph tables. To access color glyphs */ + /* use @FT_LOAD_COLOR. */ + /* */ +#define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) +#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) +#define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) +#define FT_FACE_FLAG_SFNT ( 1L << 3 ) +#define FT_FACE_FLAG_HORIZONTAL ( 1L << 4 ) +#define FT_FACE_FLAG_VERTICAL ( 1L << 5 ) +#define FT_FACE_FLAG_KERNING ( 1L << 6 ) +#define FT_FACE_FLAG_FAST_GLYPHS ( 1L << 7 ) +#define FT_FACE_FLAG_MULTIPLE_MASTERS ( 1L << 8 ) +#define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 ) +#define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 ) +#define FT_FACE_FLAG_HINTER ( 1L << 11 ) +#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) +#define FT_FACE_FLAG_TRICKY ( 1L << 13 ) +#define FT_FACE_FLAG_COLOR ( 1L << 14 ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_HORIZONTAL( face ) + * + * @description: + * A macro that returns true whenever a face object contains + * horizontal metrics (this is true for all font formats though). + * + * @also: + * @FT_HAS_VERTICAL can be used to check for vertical metrics. + * + */ +#define FT_HAS_HORIZONTAL( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_VERTICAL( face ) + * + * @description: + * A macro that returns true whenever a face object contains real + * vertical metrics (and not only synthesized ones). + * + */ +#define FT_HAS_VERTICAL( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_VERTICAL ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_KERNING( face ) + * + * @description: + * A macro that returns true whenever a face object contains kerning + * data that can be accessed with @FT_Get_Kerning. + * + */ +#define FT_HAS_KERNING( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_KERNING ) + + + /************************************************************************* + * + * @macro: + * FT_IS_SCALABLE( face ) + * + * @description: + * A macro that returns true whenever a face object contains a scalable + * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, + * and PFR font formats. + * + */ +#define FT_IS_SCALABLE( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_SCALABLE ) + + + /************************************************************************* + * + * @macro: + * FT_IS_SFNT( face ) + * + * @description: + * A macro that returns true whenever a face object contains a font + * whose format is based on the SFNT storage scheme. This usually + * means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded + * bitmap fonts. + * + * If this macro is true, all functions defined in @FT_SFNT_NAMES_H and + * @FT_TRUETYPE_TABLES_H are available. + * + */ +#define FT_IS_SFNT( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_SFNT ) + + + /************************************************************************* + * + * @macro: + * FT_IS_FIXED_WIDTH( face ) + * + * @description: + * A macro that returns true whenever a face object contains a font face + * that contains fixed-width (or `monospace', `fixed-pitch', etc.) + * glyphs. + * + */ +#define FT_IS_FIXED_WIDTH( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_FIXED_SIZES( face ) + * + * @description: + * A macro that returns true whenever a face object contains some + * embedded bitmaps. See the `available_sizes' field of the + * @FT_FaceRec structure. + * + */ +#define FT_HAS_FIXED_SIZES( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_FAST_GLYPHS( face ) + * + * @description: + * Deprecated. + * + */ +#define FT_HAS_FAST_GLYPHS( face ) 0 + + + /************************************************************************* + * + * @macro: + * FT_HAS_GLYPH_NAMES( face ) + * + * @description: + * A macro that returns true whenever a face object contains some glyph + * names that can be accessed through @FT_Get_Glyph_Name. + * + */ +#define FT_HAS_GLYPH_NAMES( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_MULTIPLE_MASTERS( face ) + * + * @description: + * A macro that returns true whenever a face object contains some + * multiple masters. The functions provided by @FT_MULTIPLE_MASTERS_H + * are then available to choose the exact design you want. + * + */ +#define FT_HAS_MULTIPLE_MASTERS( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + + + /************************************************************************* + * + * @macro: + * FT_IS_NAMED_INSTANCE( face ) + * + * @description: + * A macro that returns true whenever a face object is a named instance + * of a GX variation font. + * + */ +#define FT_IS_NAMED_INSTANCE( face ) \ + ( (face)->face_index & 0x7FFF0000L ) + + + /************************************************************************* + * + * @macro: + * FT_IS_CID_KEYED( face ) + * + * @description: + * A macro that returns true whenever a face object contains a CID-keyed + * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more + * details. + * + * If this macro is true, all functions defined in @FT_CID_H are + * available. + * + */ +#define FT_IS_CID_KEYED( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_CID_KEYED ) + + + /************************************************************************* + * + * @macro: + * FT_IS_TRICKY( face ) + * + * @description: + * A macro that returns true whenever a face represents a `tricky' font. + * See the discussion of @FT_FACE_FLAG_TRICKY for more details. + * + */ +#define FT_IS_TRICKY( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_TRICKY ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_COLOR( face ) + * + * @description: + * A macro that returns true whenever a face object contains + * tables for color glyphs. + * + */ +#define FT_HAS_COLOR( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_COLOR ) + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* FT_STYLE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used to indicate the style of a given face. */ + /* These are used in the `style_flags' field of @FT_FaceRec. */ + /* */ + /* <Values> */ + /* FT_STYLE_FLAG_ITALIC :: */ + /* Indicates that a given face style is italic or oblique. */ + /* */ + /* FT_STYLE_FLAG_BOLD :: */ + /* Indicates that a given face is bold. */ + /* */ + /* <Note> */ + /* The style information as provided by FreeType is very basic. More */ + /* details are beyond the scope and should be done on a higher level */ + /* (for example, by analyzing various fields of the `OS/2' table in */ + /* SFNT based fonts). */ + /* */ +#define FT_STYLE_FLAG_ITALIC ( 1 << 0 ) +#define FT_STYLE_FLAG_BOLD ( 1 << 1 ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Size_InternalRec' structure, used to */ + /* model private data of a given @FT_Size object. */ + /* */ + typedef struct FT_Size_InternalRec_* FT_Size_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_Metrics */ + /* */ + /* <Description> */ + /* The size metrics structure gives the metrics of a size object. */ + /* */ + /* <Fields> */ + /* x_ppem :: The width of the scaled EM square in pixels, hence */ + /* the term `ppem' (pixels per EM). It is also */ + /* referred to as `nominal width'. */ + /* */ + /* y_ppem :: The height of the scaled EM square in pixels, */ + /* hence the term `ppem' (pixels per EM). It is also */ + /* referred to as `nominal height'. */ + /* */ + /* x_scale :: A 16.16 fractional scaling value used to convert */ + /* horizontal metrics from font units to 26.6 */ + /* fractional pixels. Only relevant for scalable */ + /* font formats. */ + /* */ + /* y_scale :: A 16.16 fractional scaling value used to convert */ + /* vertical metrics from font units to 26.6 */ + /* fractional pixels. Only relevant for scalable */ + /* font formats. */ + /* */ + /* ascender :: The ascender in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* descender :: The descender in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* height :: The height in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* max_advance :: The maximum advance width in 26.6 fractional */ + /* pixels. See @FT_FaceRec for the details. */ + /* */ + /* <Note> */ + /* The scaling values, if relevant, are determined first during a */ + /* size changing operation. The remaining fields are then set by the */ + /* driver. For scalable formats, they are usually set to scaled */ + /* values of the corresponding fields in @FT_FaceRec. */ + /* */ + /* Note that due to glyph hinting, these values might not be exact */ + /* for certain fonts. Thus they must be treated as unreliable */ + /* with an error margin of at least one pixel! */ + /* */ + /* Indeed, the only way to get the exact metrics is to render _all_ */ + /* glyphs. As this would be a definite performance hit, it is up to */ + /* client applications to perform such computations. */ + /* */ + /* The FT_Size_Metrics structure is valid for bitmap fonts also. */ + /* */ + typedef struct FT_Size_Metrics_ + { + FT_UShort x_ppem; /* horizontal pixels per EM */ + FT_UShort y_ppem; /* vertical pixels per EM */ + + FT_Fixed x_scale; /* scaling values used to convert font */ + FT_Fixed y_scale; /* units to 26.6 fractional pixels */ + + FT_Pos ascender; /* ascender in 26.6 frac. pixels */ + FT_Pos descender; /* descender in 26.6 frac. pixels */ + FT_Pos height; /* text height in 26.6 frac. pixels */ + FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */ + + } FT_Size_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SizeRec */ + /* */ + /* <Description> */ + /* FreeType root size class structure. A size object models a face */ + /* object at a given size. */ + /* */ + /* <Fields> */ + /* face :: Handle to the parent face object. */ + /* */ + /* generic :: A typeless pointer, unused by the FreeType library or */ + /* any of its drivers. It can be used by client */ + /* applications to link their own data to each size */ + /* object. */ + /* */ + /* metrics :: Metrics for this size object. This field is read-only. */ + /* */ + typedef struct FT_SizeRec_ + { + FT_Face face; /* parent face object */ + FT_Generic generic; /* generic pointer for client uses */ + FT_Size_Metrics metrics; /* size metrics */ + FT_Size_Internal internal; + + } FT_SizeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SubGlyph */ + /* */ + /* <Description> */ + /* The subglyph structure is an internal object used to describe */ + /* subglyphs (for example, in the case of composites). */ + /* */ + /* <Note> */ + /* The subglyph implementation is not part of the high-level API, */ + /* hence the forward structure declaration. */ + /* */ + /* You can however retrieve subglyph information with */ + /* @FT_Get_SubGlyph_Info. */ + /* */ + typedef struct FT_SubGlyphRec_* FT_SubGlyph; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Slot_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Slot_InternalRec' structure, used to */ + /* model private data of a given @FT_GlyphSlot object. */ + /* */ + typedef struct FT_Slot_InternalRec_* FT_Slot_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphSlotRec */ + /* */ + /* <Description> */ + /* FreeType root glyph slot class structure. A glyph slot is a */ + /* container where individual glyphs can be loaded, be they in */ + /* outline or bitmap format. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library instance */ + /* this slot belongs to. */ + /* */ + /* face :: A handle to the parent face object. */ + /* */ + /* next :: In some cases (like some font tools), several */ + /* glyph slots per face object can be a good */ + /* thing. As this is rare, the glyph slots are */ + /* listed through a direct, single-linked list */ + /* using its `next' field. */ + /* */ + /* generic :: A typeless pointer unused by the FreeType */ + /* library or any of its drivers. It can be */ + /* used by client applications to link their own */ + /* data to each glyph slot object. */ + /* */ + /* metrics :: The metrics of the last loaded glyph in the */ + /* slot. The returned values depend on the last */ + /* load flags (see the @FT_Load_Glyph API */ + /* function) and can be expressed either in 26.6 */ + /* fractional pixels or font units. */ + /* */ + /* Note that even when the glyph image is */ + /* transformed, the metrics are not. */ + /* */ + /* linearHoriAdvance :: The advance width of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ + /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ + /* */ + /* linearVertAdvance :: The advance height of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ + /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ + /* */ + /* advance :: This shorthand is, depending on */ + /* @FT_LOAD_IGNORE_TRANSFORM, the transformed */ + /* (hinted) advance width for the glyph, in 26.6 */ + /* fractional pixel format. As specified with */ + /* @FT_LOAD_VERTICAL_LAYOUT, it uses either the */ + /* `horiAdvance' or the `vertAdvance' value of */ + /* `metrics' field. */ + /* */ + /* format :: This field indicates the format of the image */ + /* contained in the glyph slot. Typically */ + /* @FT_GLYPH_FORMAT_BITMAP, */ + /* @FT_GLYPH_FORMAT_OUTLINE, or */ + /* @FT_GLYPH_FORMAT_COMPOSITE, but others are */ + /* possible. */ + /* */ + /* bitmap :: This field is used as a bitmap descriptor */ + /* when the slot format is */ + /* @FT_GLYPH_FORMAT_BITMAP. Note that the */ + /* address and content of the bitmap buffer can */ + /* change between calls of @FT_Load_Glyph and a */ + /* few other functions. */ + /* */ + /* bitmap_left :: The bitmap's left bearing expressed in */ + /* integer pixels. Only valid if the format is */ + /* @FT_GLYPH_FORMAT_BITMAP, this is, if the */ + /* glyph slot contains a bitmap. */ + /* */ + /* bitmap_top :: The bitmap's top bearing expressed in integer */ + /* pixels. Remember that this is the distance */ + /* from the baseline to the top-most glyph */ + /* scanline, upwards y~coordinates being */ + /* *positive*. */ + /* */ + /* outline :: The outline descriptor for the current glyph */ + /* image if its format is */ + /* @FT_GLYPH_FORMAT_OUTLINE. Once a glyph is */ + /* loaded, `outline' can be transformed, */ + /* distorted, embolded, etc. However, it must */ + /* not be freed. */ + /* */ + /* num_subglyphs :: The number of subglyphs in a composite glyph. */ + /* This field is only valid for the composite */ + /* glyph format that should normally only be */ + /* loaded with the @FT_LOAD_NO_RECURSE flag. */ + /* */ + /* subglyphs :: An array of subglyph descriptors for */ + /* composite glyphs. There are `num_subglyphs' */ + /* elements in there. Currently internal to */ + /* FreeType. */ + /* */ + /* control_data :: Certain font drivers can also return the */ + /* control data for a given glyph image (e.g. */ + /* TrueType bytecode, Type~1 charstrings, etc.). */ + /* This field is a pointer to such data. */ + /* */ + /* control_len :: This is the length in bytes of the control */ + /* data. */ + /* */ + /* other :: Really wicked formats can use this pointer to */ + /* present their own glyph image to client */ + /* applications. Note that the application */ + /* needs to know about the image format. */ + /* */ + /* lsb_delta :: The difference between hinted and unhinted */ + /* left side bearing while auto-hinting is */ + /* active. Zero otherwise. */ + /* */ + /* rsb_delta :: The difference between hinted and unhinted */ + /* right side bearing while auto-hinting is */ + /* active. Zero otherwise. */ + /* */ + /* <Note> */ + /* If @FT_Load_Glyph is called with default flags (see */ + /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ + /* its native format (e.g., an outline glyph for TrueType and Type~1 */ + /* formats). */ + /* */ + /* This image can later be converted into a bitmap by calling */ + /* @FT_Render_Glyph. This function finds the current renderer for */ + /* the native image's format, then invokes it. */ + /* */ + /* The renderer is in charge of transforming the native image through */ + /* the slot's face transformation fields, then converting it into a */ + /* bitmap that is returned in `slot->bitmap'. */ + /* */ + /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ + /* to specify the position of the bitmap relative to the current pen */ + /* position (e.g., coordinates (0,0) on the baseline). Of course, */ + /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ + /* */ + /* <Note> */ + /* Here is a small pseudo code fragment that shows how to use */ + /* `lsb_delta' and `rsb_delta': */ + /* */ + /* { */ + /* FT_Pos origin_x = 0; */ + /* FT_Pos prev_rsb_delta = 0; */ + /* */ + /* */ + /* for all glyphs do */ + /* <compute kern between current and previous glyph and add it to */ + /* `origin_x'> */ + /* */ + /* <load glyph with `FT_Load_Glyph'> */ + /* */ + /* if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 ) */ + /* origin_x -= 64; */ + /* else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 ) */ + /* origin_x += 64; */ + /* */ + /* prev_rsb_delta = face->glyph->rsb_delta; */ + /* */ + /* <save glyph image, or render glyph, or ...> */ + /* */ + /* origin_x += face->glyph->advance.x; */ + /* endfor */ + /* } */ + /* */ + typedef struct FT_GlyphSlotRec_ + { + FT_Library library; + FT_Face face; + FT_GlyphSlot next; + FT_UInt reserved; /* retained for binary compatibility */ + FT_Generic generic; + + FT_Glyph_Metrics metrics; + FT_Fixed linearHoriAdvance; + FT_Fixed linearVertAdvance; + FT_Vector advance; + + FT_Glyph_Format format; + + FT_Bitmap bitmap; + FT_Int bitmap_left; + FT_Int bitmap_top; + + FT_Outline outline; + + FT_UInt num_subglyphs; + FT_SubGlyph subglyphs; + + void* control_data; + long control_len; + + FT_Pos lsb_delta; + FT_Pos rsb_delta; + + void* other; + + FT_Slot_Internal internal; + + } FT_GlyphSlotRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* F U N C T I O N S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Init_FreeType */ + /* */ + /* <Description> */ + /* Initialize a new FreeType library object. The set of modules */ + /* that are registered by this function is determined at build time. */ + /* */ + /* <Output> */ + /* alibrary :: A handle to a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* In case you want to provide your own memory allocating routines, */ + /* use @FT_New_Library instead, followed by a call to */ + /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */ + /* */ + /* See the documentation of @FT_Library and @FT_Face for */ + /* multi-threading issues. */ + /* */ + /* If you need reference-counting (cf. @FT_Reference_Library), use */ + /* @FT_New_Library and @FT_Done_Library. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Init_FreeType( FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_FreeType */ + /* */ + /* <Description> */ + /* Destroy a given FreeType library object and all of its children, */ + /* including resources, drivers, faces, sizes, etc. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_FreeType( FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_OPEN_XXX */ + /* */ + /* <Description> */ + /* A list of bit field constants used within the `flags' field of the */ + /* @FT_Open_Args structure. */ + /* */ + /* <Values> */ + /* FT_OPEN_MEMORY :: This is a memory-based stream. */ + /* */ + /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ + /* */ + /* FT_OPEN_PATHNAME :: Create a new input stream from a C~path */ + /* name. */ + /* */ + /* FT_OPEN_DRIVER :: Use the `driver' field. */ + /* */ + /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ + /* */ + /* <Note> */ + /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ + /* flags are mutually exclusive. */ + /* */ +#define FT_OPEN_MEMORY 0x1 +#define FT_OPEN_STREAM 0x2 +#define FT_OPEN_PATHNAME 0x4 +#define FT_OPEN_DRIVER 0x8 +#define FT_OPEN_PARAMS 0x10 + + + /* these constants are deprecated; use the corresponding `FT_OPEN_XXX' */ + /* values instead */ +#define ft_open_memory FT_OPEN_MEMORY +#define ft_open_stream FT_OPEN_STREAM +#define ft_open_pathname FT_OPEN_PATHNAME +#define ft_open_driver FT_OPEN_DRIVER +#define ft_open_params FT_OPEN_PARAMS + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Parameter */ + /* */ + /* <Description> */ + /* A simple structure used to pass more or less generic parameters to */ + /* @FT_Open_Face. */ + /* */ + /* <Fields> */ + /* tag :: A four-byte identification tag. */ + /* */ + /* data :: A pointer to the parameter data. */ + /* */ + /* <Note> */ + /* The ID and function of parameters are driver-specific. See the */ + /* various FT_PARAM_TAG_XXX flags for more information. */ + /* */ + typedef struct FT_Parameter_ + { + FT_ULong tag; + FT_Pointer data; + + } FT_Parameter; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Open_Args */ + /* */ + /* <Description> */ + /* A structure used to indicate how to open a new font file or */ + /* stream. A pointer to such a structure can be used as a parameter */ + /* for the functions @FT_Open_Face and @FT_Attach_Stream. */ + /* */ + /* <Fields> */ + /* flags :: A set of bit flags indicating how to use the */ + /* structure. */ + /* */ + /* memory_base :: The first byte of the file in memory. */ + /* */ + /* memory_size :: The size in bytes of the file in memory. */ + /* */ + /* pathname :: A pointer to an 8-bit file pathname. */ + /* */ + /* stream :: A handle to a source stream object. */ + /* */ + /* driver :: This field is exclusively used by @FT_Open_Face; */ + /* it simply specifies the font driver to use to open */ + /* the face. If set to~0, FreeType tries to load the */ + /* face with each one of the drivers in its list. */ + /* */ + /* num_params :: The number of extra parameters. */ + /* */ + /* params :: Extra parameters passed to the font driver when */ + /* opening a new face. */ + /* */ + /* <Note> */ + /* The stream type is determined by the contents of `flags' that */ + /* are tested in the following order by @FT_Open_Face: */ + /* */ + /* If the @FT_OPEN_MEMORY bit is set, assume that this is a */ + /* memory file of `memory_size' bytes, located at `memory_address'. */ + /* The data are not copied, and the client is responsible for */ + /* releasing and destroying them _after_ the corresponding call to */ + /* @FT_Done_Face. */ + /* */ + /* Otherwise, if the @FT_OPEN_STREAM bit is set, assume that a */ + /* custom input stream `stream' is used. */ + /* */ + /* Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this */ + /* is a normal file and use `pathname' to open it. */ + /* */ + /* If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to */ + /* open the file with the driver whose handler is in `driver'. */ + /* */ + /* If the @FT_OPEN_PARAMS bit is set, the parameters given by */ + /* `num_params' and `params' is used. They are ignored otherwise. */ + /* */ + /* Ideally, both the `pathname' and `params' fields should be tagged */ + /* as `const'; this is missing for API backwards compatibility. In */ + /* other words, applications should treat them as read-only. */ + /* */ + typedef struct FT_Open_Args_ + { + FT_UInt flags; + const FT_Byte* memory_base; + FT_Long memory_size; + FT_String* pathname; + FT_Stream stream; + FT_Module driver; + FT_Int num_params; + FT_Parameter* params; + + } FT_Open_Args; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face */ + /* */ + /* <Description> */ + /* This function calls @FT_Open_Face to open a font by its pathname. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* pathname :: A path to the font file. */ + /* */ + /* face_index :: See @FT_Open_Face for a detailed description of this */ + /* parameter. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Use @FT_Done_Face to destroy the created @FT_Face object (along */ + /* with its slot and sizes). */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face( FT_Library library, + const char* filepathname, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory_Face */ + /* */ + /* <Description> */ + /* This function calls @FT_Open_Face to open a font that has been */ + /* loaded into memory. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* file_base :: A pointer to the beginning of the font data. */ + /* */ + /* file_size :: The size of the memory chunk used by the font data. */ + /* */ + /* face_index :: See @FT_Open_Face for a detailed description of this */ + /* parameter. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You must not deallocate the memory before calling @FT_Done_Face. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Memory_Face( FT_Library library, + const FT_Byte* file_base, + FT_Long file_size, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Open_Face */ + /* */ + /* <Description> */ + /* Create a face object from a given resource described by */ + /* @FT_Open_Args. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* args :: A pointer to an `FT_Open_Args' structure that must */ + /* be filled by the caller. */ + /* */ + /* face_index :: This field holds two different values. Bits 0-15 */ + /* are the index of the face in the font file (starting */ + /* with value~0). Set it to~0 if there is only one */ + /* face in the font file. */ + /* */ + /* Bits 16-30 are relevant to GX variation fonts only, */ + /* specifying the named instance index for the current */ + /* face index (starting with value~1; value~0 makes */ + /* FreeType ignore named instances). For non-GX fonts, */ + /* bits 16-30 are ignored. Assuming that you want to */ + /* access the third named instance in face~4, */ + /* `face_index' should be set to 0x00030004. If you */ + /* want to access face~4 without GX variation handling, */ + /* simply set `face_index' to value~4. */ + /* */ + /* FT_Open_Face and its siblings can be used to quickly */ + /* check whether the font format of a given font */ + /* resource is supported by FreeType. In general, if */ + /* the `face_index' argument is negative, the */ + /* function's return value is~0 if the font format is */ + /* recognized, or non-zero otherwise. The function */ + /* allocates a more or less empty face handle in */ + /* `*aface' (if `aface' isn't NULL); the only two */ + /* useful fields in this special case are */ + /* `face->num_faces' and `face->style_flags'. For any */ + /* negative value of `face_index', `face->num_faces' */ + /* gives the number of faces within the font file. For */ + /* the negative value `-(N+1)' (with `N' a 16-bit */ + /* value), bits 16-30 in `face->style_flags' give the */ + /* number of named instances in face `N' if we have a */ + /* GX variation font (or zero otherwise). After */ + /* examination, the returned @FT_Face structure should */ + /* be deallocated with a call to @FT_Done_Face. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Unlike FreeType 1.x, this function automatically creates a glyph */ + /* slot for the face object that can be accessed directly through */ + /* `face->glyph'. */ + /* */ + /* Each new face object created with this function also owns a */ + /* default @FT_Size object, accessible as `face->size'. */ + /* */ + /* One @FT_Library instance can have multiple face objects, this is, */ + /* @FT_Open_Face and its siblings can be called multiple times using */ + /* the same `library' argument. */ + /* */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Face. */ + /* */ + /* To loop over all faces, use code similar to the following snippet */ + /* (omitting the error handling). */ + /* */ + /* { */ + /* ... */ + /* FT_Face face; */ + /* FT_Long i, num_faces; */ + /* */ + /* */ + /* error = FT_Open_Face( library, args, -1, &face ); */ + /* if ( error ) { ... } */ + /* */ + /* num_faces = face->num_faces; */ + /* FT_Done_Face( face ); */ + /* */ + /* for ( i = 0; i < num_faces; i++ ) */ + /* { */ + /* ... */ + /* error = FT_Open_Face( library, args, i, &face ); */ + /* ... */ + /* FT_Done_Face( face ); */ + /* ... */ + /* } */ + /* } */ + /* */ + /* To loop over all valid values for `face_index', use something */ + /* similar to the following snippet, again without error handling. */ + /* The code accesses all faces immediately (thus only a single call */ + /* of `FT_Open_Face' within the do-loop), with and without named */ + /* instances. */ + /* */ + /* { */ + /* ... */ + /* FT_Face face; */ + /* */ + /* FT_Long num_faces = 0; */ + /* FT_Long num_instances = 0; */ + /* */ + /* FT_Long face_idx = 0; */ + /* FT_Long instance_idx = 0; */ + /* */ + /* */ + /* do */ + /* { */ + /* FT_Long id = ( instance_idx << 16 ) + face_idx; */ + /* */ + /* */ + /* error = FT_Open_Face( library, args, id, &face ); */ + /* if ( error ) { ... } */ + /* */ + /* num_faces = face->num_faces; */ + /* num_instances = face->style_flags >> 16; */ + /* */ + /* ... */ + /* */ + /* FT_Done_Face( face ); */ + /* */ + /* if ( instance_idx < num_instances ) */ + /* instance_idx++; */ + /* else */ + /* { */ + /* face_idx++; */ + /* instance_idx = 0; */ + /* } */ + /* */ + /* } while ( face_idx < num_faces ) */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_Open_Face( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_File */ + /* */ + /* <Description> */ + /* This function calls @FT_Attach_Stream to attach a file. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* filepathname :: The pathname. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_File( FT_Face face, + const char* filepathname ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_Stream */ + /* */ + /* <Description> */ + /* `Attach' data to a face object. Normally, this is used to read */ + /* additional information for the face object. For example, you can */ + /* attach an AFM file that comes with a Type~1 font to get the */ + /* kerning values and other metrics. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* parameters :: A pointer to @FT_Open_Args that must be filled by */ + /* the caller. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The meaning of the `attach' (i.e., what really happens when the */ + /* new file is read) is not fixed by FreeType itself. It really */ + /* depends on the font format (and thus the font driver). */ + /* */ + /* Client applications are expected to know what they are doing */ + /* when invoking this function. Most drivers simply do not implement */ + /* file attachments. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_Stream( FT_Face face, + FT_Open_Args* parameters ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Reference_Face */ + /* */ + /* <Description> */ + /* A counter gets initialized to~1 at the time an @FT_Face structure */ + /* is created. This function increments the counter. @FT_Done_Face */ + /* then only destroys a face if the counter is~1, otherwise it simply */ + /* decrements the counter. */ + /* */ + /* This function helps in managing life-cycles of structures that */ + /* reference @FT_Face objects. */ + /* */ + /* <Input> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Since> */ + /* 2.4.2 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Reference_Face( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Face */ + /* */ + /* <Description> */ + /* Discard a given face object, as well as all of its child slots and */ + /* sizes. */ + /* */ + /* <Input> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Face. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Face( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Select_Size */ + /* */ + /* <Description> */ + /* Select a bitmap strike. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* strike_index :: The index of the bitmap strike in the */ + /* `available_sizes' field of @FT_FaceRec structure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Select_Size( FT_Face face, + FT_Int strike_index ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Size_Request_Type */ + /* */ + /* <Description> */ + /* An enumeration type that lists the supported size request types, */ + /* i.e., what input size (in font units) maps to the requested output */ + /* size (in pixels, as computed from the arguments of */ + /* @FT_Size_Request). */ + /* */ + /* <Values> */ + /* FT_SIZE_REQUEST_TYPE_NOMINAL :: */ + /* The nominal size. The `units_per_EM' field of @FT_FaceRec is */ + /* used to determine both scaling values. */ + /* */ + /* This is the standard scaling found in most applications. In */ + /* particular, use this size request type for TrueType fonts if */ + /* they provide optical scaling or something similar. Note, */ + /* however, that `units_per_EM' is a rather abstract value which */ + /* bears no relation to the actual size of the glyphs in a font. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ + /* The real dimension. The sum of the `ascender' and (minus of) */ + /* the `descender' fields of @FT_FaceRec are used to determine both */ + /* scaling values. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_BBOX :: */ + /* The font bounding box. The width and height of the `bbox' field */ + /* of @FT_FaceRec are used to determine the horizontal and vertical */ + /* scaling value, respectively. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_CELL :: */ + /* The `max_advance_width' field of @FT_FaceRec is used to */ + /* determine the horizontal scaling value; the vertical scaling */ + /* value is determined the same way as */ + /* @FT_SIZE_REQUEST_TYPE_REAL_DIM does. Finally, both scaling */ + /* values are set to the smaller one. This type is useful if you */ + /* want to specify the font size for, say, a window of a given */ + /* dimension and 80x24 cells. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_SCALES :: */ + /* Specify the scaling values directly. */ + /* */ + /* <Note> */ + /* The above descriptions only apply to scalable formats. For bitmap */ + /* formats, the behaviour is up to the driver. */ + /* */ + /* See the note section of @FT_Size_Metrics if you wonder how size */ + /* requesting relates to scaling values. */ + /* */ + typedef enum FT_Size_Request_Type_ + { + FT_SIZE_REQUEST_TYPE_NOMINAL, + FT_SIZE_REQUEST_TYPE_REAL_DIM, + FT_SIZE_REQUEST_TYPE_BBOX, + FT_SIZE_REQUEST_TYPE_CELL, + FT_SIZE_REQUEST_TYPE_SCALES, + + FT_SIZE_REQUEST_TYPE_MAX + + } FT_Size_Request_Type; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_RequestRec */ + /* */ + /* <Description> */ + /* A structure used to model a size request. */ + /* */ + /* <Fields> */ + /* type :: See @FT_Size_Request_Type. */ + /* */ + /* width :: The desired width, given as a 26.6 fractional */ + /* point value (with 72pt = 1in). */ + /* */ + /* height :: The desired height, given as a 26.6 fractional */ + /* point value (with 72pt = 1in). */ + /* */ + /* horiResolution :: The horizontal resolution (dpi, i.e., pixels per */ + /* inch). If set to zero, `width' is treated as a */ + /* 26.6 fractional *pixel* value. */ + /* */ + /* vertResolution :: The vertical resolution (dpi, i.e., pixels per */ + /* inch). If set to zero, `height' is treated as a */ + /* 26.6 fractional *pixel* value. */ + /* */ + /* <Note> */ + /* If `width' is zero, then the horizontal scaling value is set equal */ + /* to the vertical scaling value, and vice versa. */ + /* */ + /* If `type' is FT_SIZE_REQUEST_TYPE_SCALES, `width' and `height' are */ + /* interpreted directly as 16.16 fractional scaling values, without */ + /* any further modification, and both `horiResolution' and */ + /* `vertResolution' are ignored. */ + /* */ + typedef struct FT_Size_RequestRec_ + { + FT_Size_Request_Type type; + FT_Long width; + FT_Long height; + FT_UInt horiResolution; + FT_UInt vertResolution; + + } FT_Size_RequestRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_Request */ + /* */ + /* <Description> */ + /* A handle to a size request structure. */ + /* */ + typedef struct FT_Size_RequestRec_ *FT_Size_Request; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Request_Size */ + /* */ + /* <Description> */ + /* Resize the scale of the active @FT_Size object in a face. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* req :: A pointer to a @FT_Size_RequestRec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Although drivers may select the bitmap strike matching the */ + /* request, you should not rely on this if you intend to select a */ + /* particular bitmap strike. Use @FT_Select_Size instead in that */ + /* case. */ + /* */ + /* The relation between the requested size and the resulting glyph */ + /* size is dependent entirely on how the size is defined in the */ + /* source face. The font designer chooses the final size of each */ + /* glyph relative to this size. For more information refer to */ + /* `http://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html' */ + /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Request_Size( FT_Face face, + FT_Size_Request req ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Char_Size */ + /* */ + /* <Description> */ + /* This function calls @FT_Request_Size to request the nominal size */ + /* (in points). */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* char_width :: The nominal width, in 26.6 fractional points. */ + /* */ + /* char_height :: The nominal height, in 26.6 fractional points. */ + /* */ + /* horz_resolution :: The horizontal resolution in dpi. */ + /* */ + /* vert_resolution :: The vertical resolution in dpi. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If either the character width or height is zero, it is set equal */ + /* to the other value. */ + /* */ + /* If either the horizontal or vertical resolution is zero, it is set */ + /* equal to the other value. */ + /* */ + /* A character width or height smaller than 1pt is set to 1pt; if */ + /* both resolution values are zero, they are set to 72dpi. */ + /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Char_Size( FT_Face face, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Pixel_Sizes */ + /* */ + /* <Description> */ + /* This function calls @FT_Request_Size to request the nominal size */ + /* (in pixels). */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* pixel_width :: The nominal width, in pixels. */ + /* */ + /* pixel_height :: The nominal height, in pixels. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You should not rely on the resulting glyphs matching, or being */ + /* constrained, to this pixel size. Refer to @FT_Request_Size to */ + /* understand how requested sizes relate to actual sizes. */ + /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Pixel_Sizes( FT_Face face, + FT_UInt pixel_width, + FT_UInt pixel_height ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Glyph */ + /* */ + /* <Description> */ + /* A function used to load a single glyph into the glyph slot of a */ + /* face object. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object where the glyph */ + /* is loaded. */ + /* */ + /* <Input> */ + /* glyph_index :: The index of the glyph in the font file. For */ + /* CID-keyed fonts (either in PS or in CFF format) */ + /* this argument specifies the CID value. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The loaded glyph may be transformed. See @FT_Set_Transform for */ + /* the details. */ + /* */ + /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ + /* returned for invalid CID values (this is, for CID values that */ + /* don't have a corresponding glyph in the font). See the discussion */ + /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ + /* */ + /* If you receive `FT_Err_Glyph_Too_Big', try getting the glyph */ + /* outline at EM size, then scale it manually and fill it as a */ + /* graphics operation. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Glyph( FT_Face face, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Char */ + /* */ + /* <Description> */ + /* A function used to load a single glyph into the glyph slot of a */ + /* face object, according to its character code. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object where the glyph */ + /* is loaded. */ + /* */ + /* <Input> */ + /* char_code :: The glyph's character code, according to the */ + /* current charmap used in the face. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Char( FT_Face face, + FT_ULong char_code, + FT_Int32 load_flags ); + + + /************************************************************************* + * + * @enum: + * FT_LOAD_XXX + * + * @description: + * A list of bit field constants used with @FT_Load_Glyph to indicate + * what kind of operations to perform during glyph loading. + * + * @values: + * FT_LOAD_DEFAULT :: + * Corresponding to~0, this value is used as the default glyph load + * operation. In this case, the following happens: + * + * 1. FreeType looks for a bitmap for the glyph corresponding to the + * face's current size. If one is found, the function returns. + * The bitmap data can be accessed from the glyph slot (see note + * below). + * + * 2. If no embedded bitmap is searched or found, FreeType looks for a + * scalable outline. If one is found, it is loaded from the font + * file, scaled to device pixels, then `hinted' to the pixel grid + * in order to optimize it. The outline data can be accessed from + * the glyph slot (see note below). + * + * Note that by default, the glyph loader doesn't render outlines into + * bitmaps. The following flags are used to modify this default + * behaviour to more specific and useful cases. + * + * FT_LOAD_NO_SCALE :: + * Don't scale the loaded outline glyph but keep it in font units. + * + * This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and + * unsets @FT_LOAD_RENDER. + * + * If the font is `tricky' (see @FT_FACE_FLAG_TRICKY for more), using + * FT_LOAD_NO_SCALE usually yields meaningless outlines because the + * subglyphs must be scaled and positioned with hinting instructions. + * This can be solved by loading the font without FT_LOAD_NO_SCALE and + * setting the character size to `font->units_per_EM'. + * + * FT_LOAD_NO_HINTING :: + * Disable hinting. This generally generates `blurrier' bitmap glyphs + * when the glyph are rendered in any of the anti-aliased modes. See + * also the note below. + * + * This flag is implied by @FT_LOAD_NO_SCALE. + * + * FT_LOAD_RENDER :: + * Call @FT_Render_Glyph after the glyph is loaded. By default, the + * glyph is rendered in @FT_RENDER_MODE_NORMAL mode. This can be + * overridden by @FT_LOAD_TARGET_XXX or @FT_LOAD_MONOCHROME. + * + * This flag is unset by @FT_LOAD_NO_SCALE. + * + * FT_LOAD_NO_BITMAP :: + * Ignore bitmap strikes when loading. Bitmap-only fonts ignore this + * flag. + * + * @FT_LOAD_NO_SCALE always sets this flag. + * + * FT_LOAD_VERTICAL_LAYOUT :: + * Load the glyph for vertical text layout. In particular, the + * `advance' value in the @FT_GlyphSlotRec structure is set to the + * `vertAdvance' value of the `metrics' field. + * + * In case @FT_HAS_VERTICAL doesn't return true, you shouldn't use + * this flag currently. Reason is that in this case vertical metrics + * get synthesized, and those values are not always consistent across + * various font formats. + * + * FT_LOAD_FORCE_AUTOHINT :: + * Indicates that the auto-hinter is preferred over the font's native + * hinter. See also the note below. + * + * FT_LOAD_PEDANTIC :: + * Indicates that the font driver should perform pedantic verifications + * during glyph loading. This is mostly used to detect broken glyphs + * in fonts. By default, FreeType tries to handle broken fonts also. + * + * In particular, errors from the TrueType bytecode engine are not + * passed to the application if this flag is not set; this might + * result in partially hinted or distorted glyphs in case a glyph's + * bytecode is buggy. + * + * FT_LOAD_NO_RECURSE :: + * Indicate that the font driver should not load composite glyphs + * recursively. Instead, it should set the `num_subglyph' and + * `subglyphs' values of the glyph slot accordingly, and set + * `glyph->format' to @FT_GLYPH_FORMAT_COMPOSITE. The description of + * subglyphs can then be accessed with @FT_Get_SubGlyph_Info. + * + * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. + * + * FT_LOAD_IGNORE_TRANSFORM :: + * Indicates that the transform matrix set by @FT_Set_Transform should + * be ignored. + * + * FT_LOAD_MONOCHROME :: + * This flag is used with @FT_LOAD_RENDER to indicate that you want to + * render an outline glyph to a 1-bit monochrome bitmap glyph, with + * 8~pixels packed into each byte of the bitmap data. + * + * Note that this has no effect on the hinting algorithm used. You + * should rather use @FT_LOAD_TARGET_MONO so that the + * monochrome-optimized hinting algorithm is used. + * + * FT_LOAD_LINEAR_DESIGN :: + * Indicates that the `linearHoriAdvance' and `linearVertAdvance' + * fields of @FT_GlyphSlotRec should be kept in font units. See + * @FT_GlyphSlotRec for details. + * + * FT_LOAD_NO_AUTOHINT :: + * Disable auto-hinter. See also the note below. + * + * FT_LOAD_COLOR :: + * This flag is used to request loading of color embedded-bitmap + * images. The resulting color bitmaps, if available, will have the + * @FT_PIXEL_MODE_BGRA format. When the flag is not used and color + * bitmaps are found, they will be converted to 256-level gray + * bitmaps transparently. Those bitmaps will be in the + * @FT_PIXEL_MODE_GRAY format. + * + * FT_LOAD_COMPUTE_METRICS :: + * This flag sets computing glyph metrics without the use of bundled + * metrics tables (for example, the `hdmx' table in TrueType fonts). + * Well-behaving fonts have optimized bundled metrics and these should + * be used. This flag is mainly used by font validating or font + * editing applications, which need to ignore, verify, or edit those + * tables. + * + * Currently, this flag is only implemented for TrueType fonts. + * + * FT_LOAD_CROP_BITMAP :: + * Ignored. Deprecated. + * + * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: + * Ignored. Deprecated. + * + * @note: + * By default, hinting is enabled and the font's native hinter (see + * @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can + * disable hinting by setting @FT_LOAD_NO_HINTING or change the + * precedence by setting @FT_LOAD_FORCE_AUTOHINT. You can also set + * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be + * used at all. + * + * See the description of @FT_FACE_FLAG_TRICKY for a special exception + * (affecting only a handful of Asian fonts). + * + * Besides deciding which hinter to use, you can also decide which + * hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details. + * + * Note that the auto-hinter needs a valid Unicode cmap (either a native + * one or synthesized by FreeType) for producing correct results. If a + * font provides an incorrect mapping (for example, assigning the + * character code U+005A, LATIN CAPITAL LETTER Z, to a glyph depicting a + * mathematical integral sign), the auto-hinter might produce useless + * results. + * + */ +#define FT_LOAD_DEFAULT 0x0 +#define FT_LOAD_NO_SCALE ( 1L << 0 ) +#define FT_LOAD_NO_HINTING ( 1L << 1 ) +#define FT_LOAD_RENDER ( 1L << 2 ) +#define FT_LOAD_NO_BITMAP ( 1L << 3 ) +#define FT_LOAD_VERTICAL_LAYOUT ( 1L << 4 ) +#define FT_LOAD_FORCE_AUTOHINT ( 1L << 5 ) +#define FT_LOAD_CROP_BITMAP ( 1L << 6 ) +#define FT_LOAD_PEDANTIC ( 1L << 7 ) +#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ( 1L << 9 ) +#define FT_LOAD_NO_RECURSE ( 1L << 10 ) +#define FT_LOAD_IGNORE_TRANSFORM ( 1L << 11 ) +#define FT_LOAD_MONOCHROME ( 1L << 12 ) +#define FT_LOAD_LINEAR_DESIGN ( 1L << 13 ) +#define FT_LOAD_NO_AUTOHINT ( 1L << 15 ) + /* Bits 16..19 are used by `FT_LOAD_TARGET_' */ +#define FT_LOAD_COLOR ( 1L << 20 ) +#define FT_LOAD_COMPUTE_METRICS ( 1L << 21 ) + + /* */ + + /* used internally only by certain font drivers! */ +#define FT_LOAD_ADVANCE_ONLY ( 1L << 8 ) +#define FT_LOAD_SBITS_ONLY ( 1L << 14 ) + + + /************************************************************************** + * + * @enum: + * FT_LOAD_TARGET_XXX + * + * @description: + * A list of values that are used to select a specific hinting algorithm + * to use by the hinter. You should OR one of these values to your + * `load_flags' when calling @FT_Load_Glyph. + * + * Note that font's native hinters may ignore the hinting algorithm you + * have specified (e.g., the TrueType bytecode interpreter). You can set + * @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used. + * + * @values: + * FT_LOAD_TARGET_NORMAL :: + * This corresponds to the default hinting algorithm, optimized for + * standard gray-level rendering. For monochrome output, use + * @FT_LOAD_TARGET_MONO instead. + * + * FT_LOAD_TARGET_LIGHT :: + * A lighter hinting algorithm for gray-level modes. Many generated + * glyphs are fuzzier but better resemble their original shape. This + * is achieved by snapping glyphs to the pixel grid only vertically + * (Y-axis), as is done by Microsoft's ClearType and Adobe's + * proprietary font renderer. This preserves inter-glyph spacing in + * horizontal text. The snapping is done either by the native font + * driver if the driver itself and the font support it or by the + * auto-hinter. + * + * FT_LOAD_TARGET_MONO :: + * Strong hinting algorithm that should only be used for monochrome + * output. The result is probably unpleasant if the glyph is rendered + * in non-monochrome modes. + * + * FT_LOAD_TARGET_LCD :: + * A variant of @FT_LOAD_TARGET_NORMAL optimized for horizontally + * decimated LCD displays. + * + * FT_LOAD_TARGET_LCD_V :: + * A variant of @FT_LOAD_TARGET_NORMAL optimized for vertically + * decimated LCD displays. + * + * @note: + * You should use only _one_ of the FT_LOAD_TARGET_XXX values in your + * `load_flags'. They can't be ORed. + * + * If @FT_LOAD_RENDER is also set, the glyph is rendered in the + * corresponding mode (i.e., the mode that matches the used algorithm + * best). An exception is FT_LOAD_TARGET_MONO since it implies + * @FT_LOAD_MONOCHROME. + * + * You can use a hinting algorithm that doesn't correspond to the same + * rendering mode. As an example, it is possible to use the `light' + * hinting algorithm and have the results rendered in horizontal LCD + * pixel mode, with code like + * + * { + * FT_Load_Glyph( face, glyph_index, + * load_flags | FT_LOAD_TARGET_LIGHT ); + * + * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); + * } + * + */ +#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) + +#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) +#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) +#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) +#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) +#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) + + + /************************************************************************** + * + * @macro: + * FT_LOAD_TARGET_MODE + * + * @description: + * Return the @FT_Render_Mode corresponding to a given + * @FT_LOAD_TARGET_XXX value. + * + */ +#define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Transform */ + /* */ + /* <Description> */ + /* A function used to set the transformation that is applied to glyph */ + /* images when they are loaded into a glyph slot through */ + /* @FT_Load_Glyph. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use~0 for */ + /* the identity matrix. */ + /* delta :: A pointer to the translation vector. Use~0 for the null */ + /* vector. */ + /* */ + /* <Note> */ + /* The transformation is only applied to scalable image formats after */ + /* the glyph has been loaded. It means that hinting is unaltered by */ + /* the transformation and is performed on the character size given in */ + /* the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes. */ + /* */ + /* Note that this also transforms the `face.glyph.advance' field, but */ + /* *not* the values in `face.glyph.metrics'. */ + /* */ + FT_EXPORT( void ) + FT_Set_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Render_Mode */ + /* */ + /* <Description> */ + /* An enumeration type that lists the render modes supported by */ + /* FreeType~2. Each mode corresponds to a specific type of scanline */ + /* conversion performed on the outline. */ + /* */ + /* For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode' */ + /* field in the @FT_GlyphSlotRec structure gives the format of the */ + /* returned bitmap. */ + /* */ + /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity, */ + /* indicating pixel coverage. Use linear alpha blending and gamma */ + /* correction to correctly render non-monochrome glyph bitmaps onto a */ + /* surface; see @FT_Render_Glyph. */ + /* */ + /* <Values> */ + /* FT_RENDER_MODE_NORMAL :: */ + /* This is the default render mode; it corresponds to 8-bit */ + /* anti-aliased bitmaps. */ + /* */ + /* FT_RENDER_MODE_LIGHT :: */ + /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ + /* defined as a separate value because render modes are also used */ + /* indirectly to define hinting algorithm selectors. See */ + /* @FT_LOAD_TARGET_XXX for details. */ + /* */ + /* FT_RENDER_MODE_MONO :: */ + /* This mode corresponds to 1-bit bitmaps (with 2~levels of */ + /* opacity). */ + /* */ + /* FT_RENDER_MODE_LCD :: */ + /* This mode corresponds to horizontal RGB and BGR sub-pixel */ + /* displays like LCD screens. It produces 8-bit bitmaps that are */ + /* 3~times the width of the original glyph outline in pixels, and */ + /* which use the @FT_PIXEL_MODE_LCD mode. */ + /* */ + /* FT_RENDER_MODE_LCD_V :: */ + /* This mode corresponds to vertical RGB and BGR sub-pixel displays */ + /* (like PDA screens, rotated LCD displays, etc.). It produces */ + /* 8-bit bitmaps that are 3~times the height of the original */ + /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ + /* */ + /* <Note> */ + /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */ + /* filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */ + /* (not active in the default builds). It is up to the caller to */ + /* either call @FT_Library_SetLcdFilter (if available) or do the */ + /* filtering itself. */ + /* */ + /* The selected render mode only affects vector glyphs of a font. */ + /* Embedded bitmaps often have a different pixel mode like */ + /* @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform */ + /* them into 8-bit pixmaps. */ + /* */ + typedef enum FT_Render_Mode_ + { + FT_RENDER_MODE_NORMAL = 0, + FT_RENDER_MODE_LIGHT, + FT_RENDER_MODE_MONO, + FT_RENDER_MODE_LCD, + FT_RENDER_MODE_LCD_V, + + FT_RENDER_MODE_MAX + + } FT_Render_Mode; + + + /* these constants are deprecated; use the corresponding */ + /* `FT_Render_Mode' values instead */ +#define ft_render_mode_normal FT_RENDER_MODE_NORMAL +#define ft_render_mode_mono FT_RENDER_MODE_MONO + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Render_Glyph */ + /* */ + /* <Description> */ + /* Convert a given glyph image to a bitmap. It does so by inspecting */ + /* the glyph image format, finding the relevant renderer, and */ + /* invoking it. */ + /* */ + /* <InOut> */ + /* slot :: A handle to the glyph slot containing the image to */ + /* convert. */ + /* */ + /* <Input> */ + /* render_mode :: This is the render mode used to render the glyph */ + /* image into a bitmap. See @FT_Render_Mode for a */ + /* list of possible values. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* To get meaningful results, font scaling values must be set with */ + /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ + /* */ + /* When FreeType outputs a bitmap of a glyph, it really outputs an */ + /* alpha coverage map. If a pixel is completely covered by a */ + /* filled-in outline, the bitmap contains 0xFF at that pixel, meaning */ + /* that 0xFF/0xFF fraction of that pixel is covered, meaning the */ + /* pixel is 100% black (or 0% bright). If a pixel is only 50% */ + /* covered (value 0x80), the pixel is made 50% black (50% bright or a */ + /* middle shade of grey). 0% covered means 0% black (100% bright or */ + /* white). */ + /* */ + /* On high-DPI screens like on smartphones and tablets, the pixels */ + /* are so small that their chance of being completely covered and */ + /* therefore completely black are fairly good. On the low-DPI */ + /* screens, however, the situation is different. The pixels are too */ + /* large for most of the details of a glyph and shades of gray are */ + /* the norm rather than the exception. */ + /* */ + /* This is relevant because all our screens have a second problem: */ + /* they are not linear. 1~+~1 is not~2. Twice the value does not */ + /* result in twice the brightness. When a pixel is only 50% covered, */ + /* the coverage map says 50% black, and this translates to a pixel */ + /* value of 128 when you use 8~bits per channel (0-255). However, */ + /* this does not translate to 50% brightness for that pixel on our */ + /* sRGB and gamma~2.2 screens. Due to their non-linearity, they */ + /* dwell longer in the darks and only a pixel value of about 186 */ + /* results in 50% brightness – 128 ends up too dark on both bright */ + /* and dark backgrounds. The net result is that dark text looks */ + /* burnt-out, pixely and blotchy on bright background, bright text */ + /* too frail on dark backgrounds, and colored text on colored */ + /* background (for example, red on green) seems to have dark halos or */ + /* `dirt' around it. The situation is especially ugly for diagonal */ + /* stems like in `w' glyph shapes where the quality of FreeType's */ + /* anti-aliasing depends on the correct display of grays. On */ + /* high-DPI screens where smaller, fully black pixels reign supreme, */ + /* this doesn't matter, but on our low-DPI screens with all the gray */ + /* shades, it does. 0% and 100% brightness are the same things in */ + /* linear and non-linear space, just all the shades in-between */ + /* aren't. */ + /* */ + /* The blending function for placing text over a background is */ + /* */ + /* { */ + /* dst = alpha * src + (1 - alpha) * dst , */ + /* } */ + /* */ + /* which is known as the OVER operator. */ + /* */ + /* To correctly composite an antialiased pixel of a glyph onto a */ + /* surface, */ + /* */ + /* 1. take the foreground and background colors (e.g., in sRGB space) */ + /* and apply gamma to get them in a linear space, */ + /* */ + /* 2. use OVER to blend the two linear colors using the glyph pixel */ + /* as the alpha value (remember, the glyph bitmap is an alpha */ + /* coverage bitmap), and */ + /* */ + /* 3. apply inverse gamma to the blended pixel and write it back to */ + /* the image. */ + /* */ + /* Internal testing at Adobe found that a target inverse gamma of~1.8 */ + /* for step~3 gives good results across a wide range of displays with */ + /* an sRGB gamma curve or a similar one. */ + /* */ + /* This process can cost performance. There is an approximation that */ + /* does not need to know about the background color; see */ + /* https://bel.fi/alankila/lcd/ and */ + /* https://bel.fi/alankila/lcd/alpcor.html for details. */ + /* */ + /* *ATTENTION*: Linear blending is even more important when dealing */ + /* with subpixel-rendered glyphs to prevent color-fringing! A */ + /* subpixel-rendered glyph must first be filtered with a filter that */ + /* gives equal weight to the three color primaries and does not */ + /* exceed a sum of 0x100, see section @lcd_filtering. Then the */ + /* only difference to gray linear blending is that subpixel-rendered */ + /* linear blending is done 3~times per pixel: red foreground subpixel */ + /* to red background subpixel and so on for green and blue. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Render_Glyph( FT_GlyphSlot slot, + FT_Render_Mode render_mode ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Kerning_Mode */ + /* */ + /* <Description> */ + /* An enumeration used to specify which kerning values to return in */ + /* @FT_Get_Kerning. */ + /* */ + /* <Values> */ + /* FT_KERNING_DEFAULT :: Return grid-fitted kerning distances in */ + /* pixels (value is~0). Whether they are */ + /* scaled depends on @FT_LOAD_NO_SCALE. */ + /* */ + /* FT_KERNING_UNFITTED :: Return un-grid-fitted kerning distances in */ + /* 26.6 fractional pixels. Whether they are */ + /* scaled depends on @FT_LOAD_NO_SCALE. */ + /* */ + /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ + /* units. */ + /* */ + /* <Note> */ + /* FT_KERNING_DEFAULT returns full pixel values; it also makes */ + /* FreeType heuristically scale down kerning distances at small ppem */ + /* values so that they don't become too big. */ + /* */ + typedef enum FT_Kerning_Mode_ + { + FT_KERNING_DEFAULT = 0, + FT_KERNING_UNFITTED, + FT_KERNING_UNSCALED + + } FT_Kerning_Mode; + + + /* these constants are deprecated; use the corresponding */ + /* `FT_Kerning_Mode' values instead */ +#define ft_kerning_default FT_KERNING_DEFAULT +#define ft_kerning_unfitted FT_KERNING_UNFITTED +#define ft_kerning_unscaled FT_KERNING_UNSCALED + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Kerning */ + /* */ + /* <Description> */ + /* Return the kerning vector between two glyphs of a same face. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* kern_mode :: See @FT_Kerning_Mode for more information. */ + /* Determines the scale and dimension of the returned */ + /* kerning vector. */ + /* */ + /* <Output> */ + /* akerning :: The kerning vector. This is either in font units, */ + /* fractional pixels (26.6 format), or pixels for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this method. Other layouts, or more sophisticated */ + /* kernings, are out of the scope of this API function -- they can be */ + /* implemented through format-specific interfaces. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Kerning( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_UInt kern_mode, + FT_Vector *akerning ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Track_Kerning */ + /* */ + /* <Description> */ + /* Return the track kerning for a given face object at a given size. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* point_size :: The point size in 16.16 fractional points. */ + /* */ + /* degree :: The degree of tightness. Increasingly negative */ + /* values represent tighter track kerning, while */ + /* increasingly positive values represent looser track */ + /* kerning. Value zero means no track kerning. */ + /* */ + /* <Output> */ + /* akerning :: The kerning in 16.16 fractional points, to be */ + /* uniformly applied between all glyphs. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Currently, only the Type~1 font driver supports track kerning, */ + /* using data from AFM files (if attached with @FT_Attach_File or */ + /* @FT_Attach_Stream). */ + /* */ + /* Only very few AFM files come with track kerning data; please refer */ + /* to the Adobe's AFM specification for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Track_Kerning( FT_Face face, + FT_Fixed point_size, + FT_Int degree, + FT_Fixed* akerning ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph_Name */ + /* */ + /* <Description> */ + /* Retrieve the ASCII name of a given glyph in a face. This only */ + /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* buffer_max :: The maximum number of bytes available in the */ + /* buffer. */ + /* */ + /* <Output> */ + /* buffer :: A pointer to a target buffer where the name is */ + /* copied to. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* An error is returned if the face doesn't provide glyph names or if */ + /* the glyph index is invalid. In all cases of failure, the first */ + /* byte of `buffer' is set to~0 to indicate an empty name. */ + /* */ + /* The glyph name is truncated to fit within the buffer if it is too */ + /* long. The returned string is always zero-terminated. */ + /* */ + /* Be aware that FreeType reorders glyph indices internally so that */ + /* glyph index~0 always corresponds to the `missing glyph' (called */ + /* `.notdef'). */ + /* */ + /* This function always returns an error if the config macro */ + /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoption.h'. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph_Name( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Postscript_Name */ + /* */ + /* <Description> */ + /* Retrieve the ASCII PostScript name of a given face, if available. */ + /* This only works with PostScript and TrueType fonts. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to the face's PostScript name. NULL if unavailable. */ + /* */ + /* <Note> */ + /* The returned pointer is owned by the face and is destroyed with */ + /* it. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_Postscript_Name( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Select_Charmap */ + /* */ + /* <Description> */ + /* Select a given charmap by its encoding tag (as listed in */ + /* `freetype.h'). */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* encoding :: A handle to the selected encoding. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function returns an error if no charmap in the face */ + /* corresponds to the encoding queried here. */ + /* */ + /* Because many fonts contain more than a single cmap for Unicode */ + /* encoding, this function has some special code to select the one */ + /* that covers Unicode best (`best' in the sense that a UCS-4 cmap is */ + /* preferred to a UCS-2 cmap). It is thus preferable to */ + /* @FT_Set_Charmap in this case. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Select_Charmap( FT_Face face, + FT_Encoding encoding ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Charmap */ + /* */ + /* <Description> */ + /* Select a given charmap for character code to glyph index mapping. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* charmap :: A handle to the selected charmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function returns an error if the charmap is not part of */ + /* the face (i.e., if it is not listed in the `face->charmaps' */ + /* table). */ + /* */ + /* It also fails if a type~14 charmap is selected. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Charmap( FT_Face face, + FT_CharMap charmap ); + + + /************************************************************************* + * + * @function: + * FT_Get_Charmap_Index + * + * @description: + * Retrieve index of a given charmap. + * + * @input: + * charmap :: + * A handle to a charmap. + * + * @return: + * The index into the array of character maps within the face to which + * `charmap' belongs. If an error occurs, -1 is returned. + * + */ + FT_EXPORT( FT_Int ) + FT_Get_Charmap_Index( FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Char_Index */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code. This function */ + /* uses a charmap object to do the mapping. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* charcode :: The character code. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means `undefined character code'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within the */ + /* file. This is done to ensure that value~0 always corresponds to */ + /* the `missing glyph'. If the first glyph is not named `.notdef', */ + /* then for Type~1 and Type~42 fonts, `.notdef' will be moved into */ + /* the glyph ID~0 position, and whatever was there will be moved to */ + /* the position `.notdef' had. For Type~1 fonts, if there is no */ + /* `.notdef' glyph at all, then one will be created at index~0 and */ + /* whatever was there will be moved to the last index -- Type~42 */ + /* fonts are considered invalid under this condition. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Char_Index( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_First_Char */ + /* */ + /* <Description> */ + /* This function is used to return the first character code in the */ + /* current charmap of a given face. It also returns the */ + /* corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of first character code. 0~if charmap is */ + /* empty. */ + /* */ + /* <Return> */ + /* The charmap's first character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_Next_Char to be able to */ + /* parse all character codes available in a given charmap. The code */ + /* should look like this: */ + /* */ + /* { */ + /* FT_ULong charcode; */ + /* FT_UInt gindex; */ + /* */ + /* */ + /* charcode = FT_Get_First_Char( face, &gindex ); */ + /* while ( gindex != 0 ) */ + /* { */ + /* ... do something with (charcode,gindex) pair ... */ + /* */ + /* charcode = FT_Get_Next_Char( face, charcode, &gindex ); */ + /* } */ + /* } */ + /* */ + /* Be aware that character codes can have values up to 0xFFFFFFFF; */ + /* this might happen for non-Unicode or malformed cmaps. However, */ + /* even with regular Unicode encoding, so-called `last resort fonts' */ + /* (using SFNT cmap format 13, see function @FT_Get_CMap_Format) */ + /* normally have entries for all Unicode characters up to 0x1FFFFF, */ + /* which can cause *a lot* of iterations. */ + /* */ + /* Note that `*agindex' is set to~0 if the charmap is empty. The */ + /* result itself can be~0 in two cases: if the charmap is empty or */ + /* if the value~0 is the first valid character code. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_First_Char( FT_Face face, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Next_Char */ + /* */ + /* <Description> */ + /* This function is used to return the next character code in the */ + /* current charmap of a given face following the value `char_code', */ + /* as well as the corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* char_code :: The starting character code. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of next character code. 0~if charmap */ + /* is empty. */ + /* */ + /* <Return> */ + /* The charmap's next character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_First_Char to walk */ + /* over all character codes available in a given charmap. See the */ + /* note for this function for a simple code example. */ + /* */ + /* Note that `*agindex' is set to~0 when there are no more codes in */ + /* the charmap. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_Next_Char( FT_Face face, + FT_ULong char_code, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Name_Index */ + /* */ + /* <Description> */ + /* Return the glyph index of a given glyph name. This function uses */ + /* driver specific objects to do the translation. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* glyph_name :: The glyph name. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means `undefined character code'. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Name_Index( FT_Face face, + FT_String* glyph_name ); + + + /************************************************************************* + * + * @macro: + * FT_SUBGLYPH_FLAG_XXX + * + * @description: + * A list of constants used to describe subglyphs. Please refer to the + * TrueType specification for the meaning of the various flags. + * + * @values: + * FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS :: + * FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES :: + * FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID :: + * FT_SUBGLYPH_FLAG_SCALE :: + * FT_SUBGLYPH_FLAG_XY_SCALE :: + * FT_SUBGLYPH_FLAG_2X2 :: + * FT_SUBGLYPH_FLAG_USE_MY_METRICS :: + * + */ +#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 +#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 +#define FT_SUBGLYPH_FLAG_SCALE 8 +#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 +#define FT_SUBGLYPH_FLAG_2X2 0x80 +#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 + + + /************************************************************************* + * + * @func: + * FT_Get_SubGlyph_Info + * + * @description: + * Retrieve a description of a given subglyph. Only use it if + * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is + * returned otherwise. + * + * @input: + * glyph :: + * The source glyph slot. + * + * sub_index :: + * The index of the subglyph. Must be less than + * `glyph->num_subglyphs'. + * + * @output: + * p_index :: + * The glyph index of the subglyph. + * + * p_flags :: + * The subglyph flags, see @FT_SUBGLYPH_FLAG_XXX. + * + * p_arg1 :: + * The subglyph's first argument (if any). + * + * p_arg2 :: + * The subglyph's second argument (if any). + * + * p_transform :: + * The subglyph transformation (if any). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be + * interpreted depending on the flags returned in `*p_flags'. See the + * TrueType specification for details. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, + FT_UInt sub_index, + FT_Int *p_index, + FT_UInt *p_flags, + FT_Int *p_arg1, + FT_Int *p_arg2, + FT_Matrix *p_transform ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_FSTYPE_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used in the `fsType' field of the OS/2 table */ + /* in a TrueType or OpenType font and the `FSType' entry in a */ + /* PostScript font. These bit flags are returned by */ + /* @FT_Get_FSType_Flags; they inform client applications of embedding */ + /* and subsetting restrictions associated with a font. */ + /* */ + /* See */ + /* http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/FontPolicies.pdf */ + /* for more details. */ + /* */ + /* <Values> */ + /* FT_FSTYPE_INSTALLABLE_EMBEDDING :: */ + /* Fonts with no fsType bit set may be embedded and permanently */ + /* installed on the remote system by an application. */ + /* */ + /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING :: */ + /* Fonts that have only this bit set must not be modified, embedded */ + /* or exchanged in any manner without first obtaining permission of */ + /* the font software copyright owner. */ + /* */ + /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: */ + /* If this bit is set, the font may be embedded and temporarily */ + /* loaded on the remote system. Documents containing Preview & */ + /* Print fonts must be opened `read-only'; no edits can be applied */ + /* to the document. */ + /* */ + /* FT_FSTYPE_EDITABLE_EMBEDDING :: */ + /* If this bit is set, the font may be embedded but must only be */ + /* installed temporarily on other systems. In contrast to Preview */ + /* & Print fonts, documents containing editable fonts may be opened */ + /* for reading, editing is permitted, and changes may be saved. */ + /* */ + /* FT_FSTYPE_NO_SUBSETTING :: */ + /* If this bit is set, the font may not be subsetted prior to */ + /* embedding. */ + /* */ + /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: */ + /* If this bit is set, only bitmaps contained in the font may be */ + /* embedded; no outline data may be embedded. If there are no */ + /* bitmaps available in the font, then the font is unembeddable. */ + /* */ + /* <Note> */ + /* The flags are ORed together, thus more than a single value can be */ + /* returned. */ + /* */ + /* While the fsType flags can indicate that a font may be embedded, a */ + /* license with the font vendor may be separately required to use the */ + /* font in this way. */ + /* */ +#define FT_FSTYPE_INSTALLABLE_EMBEDDING 0x0000 +#define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING 0x0002 +#define FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING 0x0004 +#define FT_FSTYPE_EDITABLE_EMBEDDING 0x0008 +#define FT_FSTYPE_NO_SUBSETTING 0x0100 +#define FT_FSTYPE_BITMAP_EMBEDDING_ONLY 0x0200 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_FSType_Flags */ + /* */ + /* <Description> */ + /* Return the fsType flags for a font. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* The fsType flags, @FT_FSTYPE_XXX. */ + /* */ + /* <Note> */ + /* Use this function rather than directly reading the `fs_type' field */ + /* in the @PS_FontInfoRec structure, which is only guaranteed to */ + /* return the correct results for Type~1 fonts. */ + /* */ + /* <Since> */ + /* 2.3.8 */ + /* */ + FT_EXPORT( FT_UShort ) + FT_Get_FSType_Flags( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* glyph_variants */ + /* */ + /* <Title> */ + /* Glyph Variants */ + /* */ + /* <Abstract> */ + /* The FreeType~2 interface to Unicode Ideographic Variation */ + /* Sequences (IVS), using the SFNT cmap format~14. */ + /* */ + /* <Description> */ + /* Many CJK characters have variant forms. They are a sort of grey */ + /* area somewhere between being totally irrelevant and semantically */ + /* distinct; for this reason, the Unicode consortium decided to */ + /* introduce Ideographic Variation Sequences (IVS), consisting of a */ + /* Unicode base character and one of 240 variant selectors */ + /* (U+E0100-U+E01EF), instead of further extending the already huge */ + /* code range for CJK characters. */ + /* */ + /* An IVS is registered and unique; for further details please refer */ + /* to Unicode Technical Standard #37, the Ideographic Variation */ + /* Database: */ + /* */ + /* http://www.unicode.org/reports/tr37/ */ + /* */ + /* To date (November 2014), the character with the most variants is */ + /* U+9089, having 32 such IVS. */ + /* */ + /* Adobe and MS decided to support IVS with a new cmap subtable */ + /* (format~14). It is an odd subtable because it is not a mapping of */ + /* input code points to glyphs, but contains lists of all variants */ + /* supported by the font. */ + /* */ + /* A variant may be either `default' or `non-default'. A default */ + /* variant is the one you will get for that code point if you look it */ + /* up in the standard Unicode cmap. A non-default variant is a */ + /* different glyph. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIndex */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code as modified by */ + /* the variation selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character code point in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode code point of the variation selector. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means either `undefined character code', or */ + /* `undefined selector code', or `no variation selector cmap */ + /* subtable', or `current CharMap is not Unicode'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within */ + /* the file. This is done to ensure that value~0 always corresponds */ + /* to the `missing glyph'. */ + /* */ + /* This function is only meaningful if */ + /* a) the font has a variation selector cmap sub table, */ + /* and */ + /* b) the current charmap has a Unicode encoding. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIsDefault */ + /* */ + /* <Description> */ + /* Check whether this variant of this Unicode character is the one to */ + /* be found in the `cmap'. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode codepoint of the variation selector. */ + /* */ + /* <Return> */ + /* 1~if found in the standard (Unicode) cmap, 0~if found in the */ + /* variation selector cmap, or -1 if it is not a variant. */ + /* */ + /* <Note> */ + /* This function is only meaningful if the font has a variation */ + /* selector cmap subtable. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantSelectors */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* in the font. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to an array of selector code points, or NULL if there is */ + /* no valid variant selector cmap subtable. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantsOfChar */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* for the specified character code. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* <Return> */ + /* A pointer to an array of variant selector code points that are */ + /* active for the given character, or NULL if the corresponding list */ + /* is empty. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharsOfVariant */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode character codes found for */ + /* the specified variant selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* variantSelector :: */ + /* The variant selector code point in Unicode. */ + /* */ + /* <Return> */ + /* A list of all the code points that are specified by this selector */ + /* (both default and non-default codes are returned) or NULL if there */ + /* is no valid cmap or the variant selector is invalid. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /* <Title> */ + /* Computations */ + /* */ + /* <Abstract> */ + /* Crunching fixed numbers and vectors. */ + /* */ + /* <Description> */ + /* This section contains various functions used to perform */ + /* computations on 16.16 fixed-float numbers or 2d vectors. */ + /* */ + /* <Order> */ + /* FT_MulDiv */ + /* FT_MulFix */ + /* FT_DivFix */ + /* FT_RoundFix */ + /* FT_CeilFix */ + /* FT_FloorFix */ + /* FT_Vector_Transform */ + /* FT_Matrix_Multiply */ + /* FT_Matrix_Invert */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulDiv */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation `(a*b)/c' */ + /* with maximum accuracy (it uses a 64-bit intermediate integer */ + /* whenever necessary). */ + /* */ + /* This function isn't necessarily as fast as some processor specific */ + /* operations, but is at least completely portable. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. */ + /* c :: The divisor. */ + /* */ + /* <Return> */ + /* The result of `(a*b)/c'. This function never traps when trying to */ + /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ + /* on the signs of `a' and `b'. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*b)/0x10000' with maximum accuracy. Most of the time this is */ + /* used to multiply a given value by a 16.16 fixed-point factor. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. Use a 16.16 factor here whenever */ + /* possible (see note below). */ + /* */ + /* <Return> */ + /* The result of `(a*b)/0x10000'. */ + /* */ + /* <Note> */ + /* This function has been optimized for the case where the absolute */ + /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ + /* As this happens mainly when scaling from notional units to */ + /* fractional pixels in FreeType, it resulted in noticeable speed */ + /* improvements between versions 2.x and 1.x. */ + /* */ + /* As a conclusion, always try to place a 16.16 factor as the */ + /* _second_ argument of this function; this can make a great */ + /* difference. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_DivFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*0x10000)/b' with maximum accuracy. Most of the time, this is */ + /* used to divide a given value by a 16.16 fixed-point factor. */ + /* */ + /* <Input> */ + /* a :: The numerator. */ + /* b :: The denominator. Use a 16.16 factor here. */ + /* */ + /* <Return> */ + /* The result of `(a*0x10000)/b'. */ + /* */ + FT_EXPORT( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_RoundFix */ + /* */ + /* <Description> */ + /* A very simple function used to round a 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number to be rounded. */ + /* */ + /* <Return> */ + /* `a' rounded to nearest 16.16 fixed integer, halfway cases away */ + /* from zero. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_RoundFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_CeilFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the ceiling function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the ceiling function is to be computed. */ + /* */ + /* <Return> */ + /* `a' rounded towards plus infinity. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_CeilFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_FloorFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the floor function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the floor function is to be computed. */ + /* */ + /* <Return> */ + /* `a' rounded towards minus infinity. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_FloorFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Vector_Transform */ + /* */ + /* <Description> */ + /* Transform a single vector through a 2x2 matrix. */ + /* */ + /* <InOut> */ + /* vector :: The target vector to transform. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the source 2x2 matrix. */ + /* */ + /* <Note> */ + /* The result is undefined if either `vector' or `matrix' is invalid. */ + /* */ + FT_EXPORT( void ) + FT_Vector_Transform( FT_Vector* vec, + const FT_Matrix* matrix ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* version */ + /* */ + /* <Title> */ + /* FreeType Version */ + /* */ + /* <Abstract> */ + /* Functions and macros related to FreeType versions. */ + /* */ + /* <Description> */ + /* Note that those functions and macros are of limited use because */ + /* even a new release of FreeType with only documentation changes */ + /* increases the version number. */ + /* */ + /* <Order> */ + /* FT_Library_Version */ + /* */ + /* FREETYPE_MAJOR */ + /* FREETYPE_MINOR */ + /* FREETYPE_PATCH */ + /* */ + /* FT_Face_CheckTrueTypePatents */ + /* FT_Face_SetUnpatentedHinting */ + /* */ + /* FREETYPE_XXX */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @enum: + * FREETYPE_XXX + * + * @description: + * These three macros identify the FreeType source code version. + * Use @FT_Library_Version to access them at runtime. + * + * @values: + * FREETYPE_MAJOR :: The major version number. + * FREETYPE_MINOR :: The minor version number. + * FREETYPE_PATCH :: The patch level. + * + * @note: + * The version number of FreeType if built as a dynamic link library + * with the `libtool' package is _not_ controlled by these three + * macros. + * + */ +#define FREETYPE_MAJOR 2 +#define FREETYPE_MINOR 7 +#define FREETYPE_PATCH 0 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Library_Version */ + /* */ + /* <Description> */ + /* Return the version of the FreeType library being used. This is */ + /* useful when dynamically linking to the library, since one cannot */ + /* use the macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and */ + /* @FREETYPE_PATCH. */ + /* */ + /* <Input> */ + /* library :: A source library handle. */ + /* */ + /* <Output> */ + /* amajor :: The major version number. */ + /* */ + /* aminor :: The minor version number. */ + /* */ + /* apatch :: The patch version number. */ + /* */ + /* <Note> */ + /* The reason why this function takes a `library' argument is because */ + /* certain programs implement library initialization in a custom way */ + /* that doesn't use @FT_Init_FreeType. */ + /* */ + /* In such cases, the library version might not be available before */ + /* the library object has been created. */ + /* */ + FT_EXPORT( void ) + FT_Library_Version( FT_Library library, + FT_Int *amajor, + FT_Int *aminor, + FT_Int *apatch ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_CheckTrueTypePatents */ + /* */ + /* <Description> */ + /* Deprecated, does nothing. */ + /* */ + /* <Input> */ + /* face :: A face handle. */ + /* */ + /* <Return> */ + /* Always returns false. */ + /* */ + /* <Note> */ + /* Since May 2010, TrueType hinting is no longer patented. */ + /* */ + /* <Since> */ + /* 2.3.5 */ + /* */ + FT_EXPORT( FT_Bool ) + FT_Face_CheckTrueTypePatents( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_SetUnpatentedHinting */ + /* */ + /* <Description> */ + /* Deprecated, does nothing. */ + /* */ + /* <Input> */ + /* face :: A face handle. */ + /* */ + /* value :: New boolean setting. */ + /* */ + /* <Return> */ + /* Always returns false. */ + /* */ + /* <Note> */ + /* Since May 2010, TrueType hinting is no longer patented. */ + /* */ + /* <Since> */ + /* 2.3.5 */ + /* */ + FT_EXPORT( FT_Bool ) + FT_Face_SetUnpatentedHinting( FT_Face face, + FT_Bool value ); + + /* */ + + +FT_END_HEADER + +#endif /* FREETYPE_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftadvanc.h b/builddir/freetype-2.7.0/include/freetype/ftadvanc.h new file mode 100644 index 0000000..023dd84 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftadvanc.h @@ -0,0 +1,187 @@ +/***************************************************************************/ +/* */ +/* ftadvanc.h */ +/* */ +/* Quick computation of advance widths (specification only). */ +/* */ +/* Copyright 2008-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTADVANC_H_ +#define FTADVANC_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * quick_advance + * + * @title: + * Quick retrieval of advance values + * + * @abstract: + * Retrieve horizontal and vertical advance values without processing + * glyph outlines, if possible. + * + * @description: + * This section contains functions to quickly extract advance values + * without handling glyph outlines, if possible. + * + * @order: + * FT_Get_Advance + * FT_Get_Advances + * + */ + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* FT_ADVANCE_FLAG_FAST_ONLY */ + /* */ + /* <Description> */ + /* A bit-flag to be OR-ed with the `flags' parameter of the */ + /* @FT_Get_Advance and @FT_Get_Advances functions. */ + /* */ + /* If set, it indicates that you want these functions to fail if the */ + /* corresponding hinting mode or font driver doesn't allow for very */ + /* quick advance computation. */ + /* */ + /* Typically, glyphs that are either unscaled, unhinted, bitmapped, */ + /* or light-hinted can have their advance width computed very */ + /* quickly. */ + /* */ + /* Normal and bytecode hinted modes that require loading, scaling, */ + /* and hinting of the glyph outline, are extremely slow by */ + /* comparison. */ + /* */ +#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000L + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advance */ + /* */ + /* <Description> */ + /* Retrieve the advance value of a given glyph outline in an */ + /* @FT_Face. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph, used to determine what kind */ + /* of advances you need. */ + /* <Output> */ + /* padvance :: The advance value. If scaling is performed (based on */ + /* the value of `load_flags'), the advance value is in */ + /* 16.16 format. Otherwise, it is in font units. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the */ + /* vertical advance corresponding to a vertical layout. */ + /* Otherwise, it is the horizontal advance in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* A scaled advance is returned in 16.16 format but isn't transformed */ + /* by the affine transformation specified by @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advance( FT_Face face, + FT_UInt gindex, + FT_Int32 load_flags, + FT_Fixed *padvance ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advances */ + /* */ + /* <Description> */ + /* Retrieve the advance values of several glyph outlines in an */ + /* @FT_Face. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* start :: The first glyph index. */ + /* */ + /* count :: The number of advance values you want to retrieve. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph. */ + /* */ + /* <Output> */ + /* padvance :: The advance values. This array, to be provided by the */ + /* caller, must contain at least `count' elements. */ + /* */ + /* If scaling is performed (based on the value of */ + /* `load_flags'), the advance values are in 16.16 format. */ + /* Otherwise, they are in font units. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the */ + /* vertical advances corresponding to a vertical layout. */ + /* Otherwise, they are the horizontal advances in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* Scaled advances are returned in 16.16 format but aren't */ + /* transformed by the affine transformation specified by */ + /* @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 load_flags, + FT_Fixed *padvances ); + + /* */ + + +FT_END_HEADER + +#endif /* FTADVANC_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftautoh.h b/builddir/freetype-2.7.0/include/freetype/ftautoh.h new file mode 100644 index 0000000..48ff1aa --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftautoh.h @@ -0,0 +1,511 @@ +/***************************************************************************/ +/* */ +/* ftautoh.h */ +/* */ +/* FreeType API for controlling the auto-hinter (specification only). */ +/* */ +/* Copyright 2012-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTAUTOH_H_ +#define FTAUTOH_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * auto_hinter + * + * @title: + * The auto-hinter + * + * @abstract: + * Controlling the auto-hinting module. + * + * @description: + * While FreeType's auto-hinter doesn't expose API functions by itself, + * it is possible to control its behaviour with @FT_Property_Set and + * @FT_Property_Get. The following lists the available properties + * together with the necessary macros and structures. + * + * Note that the auto-hinter's module name is `autofitter' for + * historical reasons. + * + */ + + + /************************************************************************** + * + * @property: + * glyph-to-script-map + * + * @description: + * *Experimental* *only* + * + * The auto-hinter provides various script modules to hint glyphs. + * Examples of supported scripts are Latin or CJK. Before a glyph is + * auto-hinted, the Unicode character map of the font gets examined, and + * the script is then determined based on Unicode character ranges, see + * below. + * + * OpenType fonts, however, often provide much more glyphs than + * character codes (small caps, superscripts, ligatures, swashes, etc.), + * to be controlled by so-called `features'. Handling OpenType features + * can be quite complicated and thus needs a separate library on top of + * FreeType. + * + * The mapping between glyph indices and scripts (in the auto-hinter + * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an + * array with `num_glyphs' elements, as found in the font's @FT_Face + * structure. The `glyph-to-script-map' property returns a pointer to + * this array, which can be modified as needed. Note that the + * modification should happen before the first glyph gets processed by + * the auto-hinter so that the global analysis of the font shapes + * actually uses the modified mapping. + * + * The following example code demonstrates how to access it (omitting + * the error handling). + * + * { + * FT_Library library; + * FT_Face face; + * FT_Prop_GlyphToScriptMap prop; + * + * + * FT_Init_FreeType( &library ); + * FT_New_Face( library, "foo.ttf", 0, &face ); + * + * prop.face = face; + * + * FT_Property_Get( library, "autofitter", + * "glyph-to-script-map", &prop ); + * + * // adjust `prop.map' as needed right here + * + * FT_Load_Glyph( face, ..., FT_LOAD_FORCE_AUTOHINT ); + * } + * + */ + + + /************************************************************************** + * + * @enum: + * FT_AUTOHINTER_SCRIPT_XXX + * + * @description: + * *Experimental* *only* + * + * A list of constants used for the @glyph-to-script-map property to + * specify the script submodule the auto-hinter should use for hinting a + * particular glyph. + * + * @values: + * FT_AUTOHINTER_SCRIPT_NONE :: + * Don't auto-hint this glyph. + * + * FT_AUTOHINTER_SCRIPT_LATIN :: + * Apply the latin auto-hinter. For the auto-hinter, `latin' is a + * very broad term, including Cyrillic and Greek also since characters + * from those scripts share the same design constraints. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+0020 - U+007F // Basic Latin (no control characters) + * U+00A0 - U+00FF // Latin-1 Supplement (no control characters) + * U+0100 - U+017F // Latin Extended-A + * U+0180 - U+024F // Latin Extended-B + * U+0250 - U+02AF // IPA Extensions + * U+02B0 - U+02FF // Spacing Modifier Letters + * U+0300 - U+036F // Combining Diacritical Marks + * U+0370 - U+03FF // Greek and Coptic + * U+0400 - U+04FF // Cyrillic + * U+0500 - U+052F // Cyrillic Supplement + * U+1D00 - U+1D7F // Phonetic Extensions + * U+1D80 - U+1DBF // Phonetic Extensions Supplement + * U+1DC0 - U+1DFF // Combining Diacritical Marks Supplement + * U+1E00 - U+1EFF // Latin Extended Additional + * U+1F00 - U+1FFF // Greek Extended + * U+2000 - U+206F // General Punctuation + * U+2070 - U+209F // Superscripts and Subscripts + * U+20A0 - U+20CF // Currency Symbols + * U+2150 - U+218F // Number Forms + * U+2460 - U+24FF // Enclosed Alphanumerics + * U+2C60 - U+2C7F // Latin Extended-C + * U+2DE0 - U+2DFF // Cyrillic Extended-A + * U+2E00 - U+2E7F // Supplemental Punctuation + * U+A640 - U+A69F // Cyrillic Extended-B + * U+A720 - U+A7FF // Latin Extended-D + * U+FB00 - U+FB06 // Alphab. Present. Forms (Latin Ligatures) + * U+1D400 - U+1D7FF // Mathematical Alphanumeric Symbols + * U+1F100 - U+1F1FF // Enclosed Alphanumeric Supplement + * } + * + * FT_AUTOHINTER_SCRIPT_CJK :: + * Apply the CJK auto-hinter, covering Chinese, Japanese, Korean, old + * Vietnamese, and some other scripts. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+1100 - U+11FF // Hangul Jamo + * U+2E80 - U+2EFF // CJK Radicals Supplement + * U+2F00 - U+2FDF // Kangxi Radicals + * U+2FF0 - U+2FFF // Ideographic Description Characters + * U+3000 - U+303F // CJK Symbols and Punctuation + * U+3040 - U+309F // Hiragana + * U+30A0 - U+30FF // Katakana + * U+3100 - U+312F // Bopomofo + * U+3130 - U+318F // Hangul Compatibility Jamo + * U+3190 - U+319F // Kanbun + * U+31A0 - U+31BF // Bopomofo Extended + * U+31C0 - U+31EF // CJK Strokes + * U+31F0 - U+31FF // Katakana Phonetic Extensions + * U+3200 - U+32FF // Enclosed CJK Letters and Months + * U+3300 - U+33FF // CJK Compatibility + * U+3400 - U+4DBF // CJK Unified Ideographs Extension A + * U+4DC0 - U+4DFF // Yijing Hexagram Symbols + * U+4E00 - U+9FFF // CJK Unified Ideographs + * U+A960 - U+A97F // Hangul Jamo Extended-A + * U+AC00 - U+D7AF // Hangul Syllables + * U+D7B0 - U+D7FF // Hangul Jamo Extended-B + * U+F900 - U+FAFF // CJK Compatibility Ideographs + * U+FE10 - U+FE1F // Vertical forms + * U+FE30 - U+FE4F // CJK Compatibility Forms + * U+FF00 - U+FFEF // Halfwidth and Fullwidth Forms + * U+1B000 - U+1B0FF // Kana Supplement + * U+1D300 - U+1D35F // Tai Xuan Hing Symbols + * U+1F200 - U+1F2FF // Enclosed Ideographic Supplement + * U+20000 - U+2A6DF // CJK Unified Ideographs Extension B + * U+2A700 - U+2B73F // CJK Unified Ideographs Extension C + * U+2B740 - U+2B81F // CJK Unified Ideographs Extension D + * U+2F800 - U+2FA1F // CJK Compatibility Ideographs Supplement + * } + * + * FT_AUTOHINTER_SCRIPT_INDIC :: + * Apply the indic auto-hinter, covering all major scripts from the + * Indian sub-continent and some other related scripts like Thai, Lao, + * or Tibetan. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+0900 - U+0DFF // Indic Range + * U+0F00 - U+0FFF // Tibetan + * U+1900 - U+194F // Limbu + * U+1B80 - U+1BBF // Sundanese + * U+A800 - U+A82F // Syloti Nagri + * U+ABC0 - U+ABFF // Meetei Mayek + * U+11800 - U+118DF // Sharada + * } + * + * Note that currently Indic support is rudimentary only, missing blue + * zone support. + * + */ +#define FT_AUTOHINTER_SCRIPT_NONE 0 +#define FT_AUTOHINTER_SCRIPT_LATIN 1 +#define FT_AUTOHINTER_SCRIPT_CJK 2 +#define FT_AUTOHINTER_SCRIPT_INDIC 3 + + + /************************************************************************** + * + * @struct: + * FT_Prop_GlyphToScriptMap + * + * @description: + * *Experimental* *only* + * + * The data exchange structure for the @glyph-to-script-map property. + * + */ + typedef struct FT_Prop_GlyphToScriptMap_ + { + FT_Face face; + FT_UShort* map; + + } FT_Prop_GlyphToScriptMap; + + + /************************************************************************** + * + * @property: + * fallback-script + * + * @description: + * *Experimental* *only* + * + * If no auto-hinter script module can be assigned to a glyph, a + * fallback script gets assigned to it (see also the + * @glyph-to-script-map property). By default, this is + * @FT_AUTOHINTER_SCRIPT_CJK. Using the `fallback-script' property, + * this fallback value can be changed. + * + * { + * FT_Library library; + * FT_UInt fallback_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "fallback-script", &fallback_script ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * It's important to use the right timing for changing this value: The + * creation of the glyph-to-script map that eventually uses the + * fallback script value gets triggered either by setting or reading a + * face-specific property like @glyph-to-script-map, or by auto-hinting + * any glyph from that face. In particular, if you have already created + * an @FT_Face structure but not loaded any glyph (using the + * auto-hinter), a change of the fallback script will affect this face. + * + */ + + + /************************************************************************** + * + * @property: + * default-script + * + * @description: + * *Experimental* *only* + * + * If FreeType gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make + * the HarfBuzz library access OpenType features for getting better + * glyph coverages, this property sets the (auto-fitter) script to be + * used for the default (OpenType) script data of a font's GSUB table. + * Features for the default script are intended for all scripts not + * explicitly handled in GSUB; an example is a `dlig' feature, + * containing the combination of the characters `T', `E', and `L' to + * form a `TEL' ligature. + * + * By default, this is @FT_AUTOHINTER_SCRIPT_LATIN. Using the + * `default-script' property, this default value can be changed. + * + * { + * FT_Library library; + * FT_UInt default_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "default-script", &default_script ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * It's important to use the right timing for changing this value: The + * creation of the glyph-to-script map that eventually uses the + * default script value gets triggered either by setting or reading a + * face-specific property like @glyph-to-script-map, or by auto-hinting + * any glyph from that face. In particular, if you have already created + * an @FT_Face structure but not loaded any glyph (using the + * auto-hinter), a change of the default script will affect this face. + * + */ + + + /************************************************************************** + * + * @property: + * increase-x-height + * + * @description: + * For ppem values in the range 6~<= ppem <= `increase-x-height', round + * up the font's x~height much more often than normally. If the value + * is set to~0, which is the default, this feature is switched off. Use + * this property to improve the legibility of small font sizes if + * necessary. + * + * { + * FT_Library library; + * FT_Face face; + * FT_Prop_IncreaseXHeight prop; + * + * + * FT_Init_FreeType( &library ); + * FT_New_Face( library, "foo.ttf", 0, &face ); + * FT_Set_Char_Size( face, 10 * 64, 0, 72, 0 ); + * + * prop.face = face; + * prop.limit = 14; + * + * FT_Property_Set( library, "autofitter", + * "increase-x-height", &prop ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * Set this value right after calling @FT_Set_Char_Size, but before + * loading any glyph (using the auto-hinter). + * + */ + + + /************************************************************************** + * + * @struct: + * FT_Prop_IncreaseXHeight + * + * @description: + * The data exchange structure for the @increase-x-height property. + * + */ + typedef struct FT_Prop_IncreaseXHeight_ + { + FT_Face face; + FT_UInt limit; + + } FT_Prop_IncreaseXHeight; + + + /************************************************************************** + * + * @property: + * warping + * + * @description: + * *Experimental* *only* + * + * If FreeType gets compiled with option AF_CONFIG_OPTION_USE_WARPER to + * activate the warp hinting code in the auto-hinter, this property + * switches warping on and off. + * + * Warping only works in `light' auto-hinting mode. The idea of the + * code is to slightly scale and shift a glyph along the non-hinted + * dimension (which is usually the horizontal axis) so that as much of + * its segments are aligned (more or less) to the grid. To find out a + * glyph's optimal scaling and shifting value, various parameter + * combinations are tried and scored. + * + * By default, warping is off. The example below shows how to switch on + * warping (omitting the error handling). + * + * { + * FT_Library library; + * FT_Bool warping = 1; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "warping", &warping ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values 1 and 0 for `on' and `off', respectively). + * + * The warping code can also change advance widths. Have a look at the + * `lsb_delta' and `rsb_delta' fields in the @FT_GlyphSlotRec structure + * for details on improving inter-glyph distances while rendering. + * + * Since warping is a global property of the auto-hinter it is best to + * change its value before rendering any face. Otherwise, you should + * reload all faces that get auto-hinted in `light' hinting mode. + * + */ + + + /************************************************************************** + * + * @property: + * no-stem-darkening[autofit] + * + * @description: + * *Experimental* *only,* *requires* *linear* *alpha* *blending* *and* + * *gamma* *correction* + * + * Stem darkening emboldens glyphs at smaller sizes to make them more + * readable on common low-DPI screens when using linear alpha blending + * and gamma correction, see @FT_Render_Glyph. When not using linear + * alpha blending and gamma correction, glyphs will appear heavy and + * fuzzy! + * + * Gamma correction essentially lightens fonts since shades of grey are + * shifted to higher pixel values (=~higher brightness) to match the + * original intention to the reality of our screens. The side-effect is + * that glyphs `thin out'. Mac OS~X and Adobe's proprietary font + * rendering library implement a counter-measure: stem darkening at + * smaller sizes where shades of gray dominate. By emboldening a glyph + * slightly in relation to its pixel size, individual pixels get higher + * coverage of filled-in outlines and are therefore `blacker'. This + * counteracts the `thinning out' of glyphs, making text remain readable + * at smaller sizes. All glyphs that pass through the auto-hinter will + * be emboldened unless this property is set to TRUE. + * + * See the description of the CFF driver for algorithmic details. Total + * consistency with the CFF driver is currently not achieved because the + * emboldening method differs and glyphs must be scaled down on the + * Y-axis to keep outline points inside their precomputed blue zones. + * The smaller the size (especially 9ppem and down), the higher the loss + * of emboldening versus the CFF driver. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable similar to the CFF driver. + * + */ + + + /************************************************************************** + * + * @property: + * darkening-parameters[autofit] + * + * @description: + * *Experimental* *only* + * + * See the description of the CFF driver for details. This + * implementation appropriates the + * CFF_CONFIG_OPTION_DARKENING_PARAMETER_* #defines for consistency. + * Note the differences described in @no-stem-darkening[autofit]. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable similar to the CFF driver. + */ + + + /* */ + + +FT_END_HEADER + +#endif /* FTAUTOH_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftbbox.h b/builddir/freetype-2.7.0/include/freetype/ftbbox.h new file mode 100644 index 0000000..2a4d214 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftbbox.h @@ -0,0 +1,101 @@ +/***************************************************************************/ +/* */ +/* ftbbox.h */ +/* */ +/* FreeType exact bbox computation (specification). */ +/* */ +/* Copyright 1996-2016 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 has a _single_ role: to compute exact outline bounding */ + /* boxes. */ + /* */ + /* It is separated from the rest of the engine for various technical */ + /* reasons. It may well be integrated in `ftoutln' later. */ + /* */ + /*************************************************************************/ + + +#ifndef FTBBOX_H_ +#define FTBBOX_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_BBox */ + /* */ + /* <Description> */ + /* Compute the exact bounding box of an outline. This is slower */ + /* than computing the control box. However, it uses an advanced */ + /* algorithm that returns _very_ quickly when the two boxes */ + /* coincide. Otherwise, the outline Bézier arcs are traversed to */ + /* extract their extrema. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline. */ + /* */ + /* <Output> */ + /* abbox :: The outline's exact bounding box. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If the font is tricky and the glyph has been loaded with */ + /* @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get */ + /* reasonable values for the BBox it is necessary to load the glyph */ + /* at a large ppem value (so that the hinting instructions can */ + /* properly shift and scale the subglyphs), then extracting the BBox, */ + /* which can be eventually converted back to font units. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_BBox( FT_Outline* outline, + FT_BBox *abbox ); + + /* */ + + +FT_END_HEADER + +#endif /* FTBBOX_H_ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftbdf.h b/builddir/freetype-2.7.0/include/freetype/ftbdf.h new file mode 100644 index 0000000..016dba0 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftbdf.h @@ -0,0 +1,210 @@ +/***************************************************************************/ +/* */ +/* ftbdf.h */ +/* */ +/* FreeType API for accessing BDF-specific strings (specification). */ +/* */ +/* Copyright 2002-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTBDF_H_ +#define FTBDF_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bdf_fonts */ + /* */ + /* <Title> */ + /* BDF and PCF Files */ + /* */ + /* <Abstract> */ + /* BDF and PCF specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions specific to BDF */ + /* and PCF fonts. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @enum: + * BDF_PropertyType + * + * @description: + * A list of BDF property types. + * + * @values: + * BDF_PROPERTY_TYPE_NONE :: + * Value~0 is used to indicate a missing property. + * + * BDF_PROPERTY_TYPE_ATOM :: + * Property is a string atom. + * + * BDF_PROPERTY_TYPE_INTEGER :: + * Property is a 32-bit signed integer. + * + * BDF_PROPERTY_TYPE_CARDINAL :: + * Property is a 32-bit unsigned integer. + */ + typedef enum BDF_PropertyType_ + { + BDF_PROPERTY_TYPE_NONE = 0, + BDF_PROPERTY_TYPE_ATOM = 1, + BDF_PROPERTY_TYPE_INTEGER = 2, + BDF_PROPERTY_TYPE_CARDINAL = 3 + + } BDF_PropertyType; + + + /********************************************************************** + * + * @type: + * BDF_Property + * + * @description: + * A handle to a @BDF_PropertyRec structure to model a given + * BDF/PCF property. + */ + typedef struct BDF_PropertyRec_* BDF_Property; + + + /********************************************************************** + * + * @struct: + * BDF_PropertyRec + * + * @description: + * This structure models a given BDF/PCF property. + * + * @fields: + * type :: + * The property type. + * + * u.atom :: + * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. May be + * NULL, indicating an empty string. + * + * u.integer :: + * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. + * + * u.cardinal :: + * An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL. + */ + typedef struct BDF_PropertyRec_ + { + BDF_PropertyType type; + union { + const char* atom; + FT_Int32 integer; + FT_UInt32 cardinal; + + } u; + + } BDF_PropertyRec; + + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Charset_ID + * + * @description: + * Retrieve a BDF font character set identity, according to + * the BDF specification. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * acharset_encoding :: + * Charset encoding, as a C~string, owned by the face. + * + * acharset_registry :: + * Charset registry, as a C~string, owned by the face. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with BDF faces, returning an error otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Charset_ID( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ); + + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Property + * + * @description: + * Retrieve a BDF property from a BDF or PCF font file. + * + * @input: + * face :: A handle to the input face. + * + * name :: The property name. + * + * @output: + * aproperty :: The property. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function works with BDF _and_ PCF fonts. It returns an error + * otherwise. It also returns an error if the property is not in the + * font. + * + * A `property' is a either key-value pair within the STARTPROPERTIES + * ... ENDPROPERTIES block of a BDF font or a key-value pair from the + * `info->props' array within a `FontRec' structure of a PCF font. + * + * Integer properties are always stored as `signed' within PCF fonts; + * consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value + * for BDF fonts only. + * + * In case of error, `aproperty->type' is always set to + * @BDF_PROPERTY_TYPE_NONE. + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Property( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + + /* */ + +FT_END_HEADER + +#endif /* FTBDF_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftbitmap.h b/builddir/freetype-2.7.0/include/freetype/ftbitmap.h new file mode 100644 index 0000000..0eac7b9 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftbitmap.h @@ -0,0 +1,240 @@ +/***************************************************************************/ +/* */ +/* ftbitmap.h */ +/* */ +/* FreeType utility functions for bitmaps (specification). */ +/* */ +/* Copyright 2004-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTBITMAP_H_ +#define FTBITMAP_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bitmap_handling */ + /* */ + /* <Title> */ + /* Bitmap Handling */ + /* */ + /* <Abstract> */ + /* Handling FT_Bitmap objects. */ + /* */ + /* <Description> */ + /* This section contains functions for handling @FT_Bitmap objects. */ + /* Note that none of the functions changes the bitmap's `flow' (as */ + /* indicated by the sign of the `pitch' field in `FT_Bitmap'). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Init */ + /* */ + /* <Description> */ + /* Initialize a pointer to an @FT_Bitmap structure. */ + /* */ + /* <InOut> */ + /* abitmap :: A pointer to the bitmap structure. */ + /* */ + /* <Note> */ + /* A deprecated name for the same function is `FT_Bitmap_New'. */ + /* */ + FT_EXPORT( void ) + FT_Bitmap_Init( FT_Bitmap *abitmap ); + + + /* deprecated */ + FT_EXPORT( void ) + FT_Bitmap_New( FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Copy */ + /* */ + /* <Description> */ + /* Copy a bitmap into another one. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* source :: A handle to the source bitmap. */ + /* */ + /* <Output> */ + /* target :: A handle to the target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Copy( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Embolden */ + /* */ + /* <Description> */ + /* Embolden a bitmap. The new bitmap will be about `xStrength' */ + /* pixels wider and `yStrength' pixels higher. The left and bottom */ + /* borders are kept unchanged. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* xStrength :: How strong the glyph is emboldened horizontally. */ + /* Expressed in 26.6 pixel format. */ + /* */ + /* yStrength :: How strong the glyph is emboldened vertically. */ + /* Expressed in 26.6 pixel format. */ + /* */ + /* <InOut> */ + /* bitmap :: A handle to the target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The current implementation restricts `xStrength' to be less than */ + /* or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ + /* */ + /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ + /* you should call @FT_GlyphSlot_Own_Bitmap on the slot first. */ + /* */ + /* Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format */ + /* are converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Embolden( FT_Library library, + FT_Bitmap* bitmap, + FT_Pos xStrength, + FT_Pos yStrength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Convert */ + /* */ + /* <Description> */ + /* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp */ + /* to a bitmap object with depth 8bpp, making the number of used */ + /* bytes line (a.k.a. the `pitch') a multiple of `alignment'. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* source :: The source bitmap. */ + /* */ + /* alignment :: The pitch of the bitmap is a multiple of this */ + /* parameter. Common values are 1, 2, or 4. */ + /* */ + /* <Output> */ + /* target :: The target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* It is possible to call @FT_Bitmap_Convert multiple times without */ + /* calling @FT_Bitmap_Done (the memory is simply reallocated). */ + /* */ + /* Use @FT_Bitmap_Done to finally remove the bitmap object. */ + /* */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Convert( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GlyphSlot_Own_Bitmap */ + /* */ + /* <Description> */ + /* Make sure that a glyph slot owns `slot->bitmap'. */ + /* */ + /* <Input> */ + /* slot :: The glyph slot. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function is to be used in combination with */ + /* @FT_Bitmap_Embolden. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Done */ + /* */ + /* <Description> */ + /* Destroy a bitmap object initialized with @FT_Bitmap_Init. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* bitmap :: The bitmap object to be freed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Done( FT_Library library, + FT_Bitmap *bitmap ); + + + /* */ + + +FT_END_HEADER + +#endif /* FTBITMAP_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftbzip2.h b/builddir/freetype-2.7.0/include/freetype/ftbzip2.h new file mode 100644 index 0000000..b7f2eee --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftbzip2.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* ftbzip2.h */ +/* */ +/* Bzip2-compressed stream support. */ +/* */ +/* Copyright 2010-2016 by */ +/* Joel Klinghed. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTBZIP2_H_ +#define FTBZIP2_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bzip2 */ + /* */ + /* <Title> */ + /* BZIP2 Streams */ + /* */ + /* <Abstract> */ + /* Using bzip2-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Bzip2-specific functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************ + * + * @function: + * FT_Stream_OpenBzip2 + * + * @description: + * Open a new stream to parse bzip2-compressed font files. This is + * mainly used to support the compressed `*.pcf.bz2' fonts that come + * with XFree86. + * + * @input: + * stream :: + * The target embedding stream. + * + * source :: + * The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream. + * + * In certain builds of the library, bzip2 compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a bzip2 compressed stream + * from it and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with bzip2 support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenBzip2( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* FTBZIP2_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftcache.h b/builddir/freetype-2.7.0/include/freetype/ftcache.h new file mode 100644 index 0000000..883c88d --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftcache.h @@ -0,0 +1,1057 @@ +/***************************************************************************/ +/* */ +/* ftcache.h */ +/* */ +/* FreeType Cache subsystem (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTCACHE_H_ +#define FTCACHE_H_ + + +#include <ft2build.h> +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /************************************************************************* + * + * <Section> + * cache_subsystem + * + * <Title> + * Cache Sub-System + * + * <Abstract> + * How to cache face, size, and glyph data with FreeType~2. + * + * <Description> + * This section describes the FreeType~2 cache sub-system, which is used + * to limit the number of concurrently opened @FT_Face and @FT_Size + * objects, as well as caching information like character maps and glyph + * images while limiting their maximum memory usage. + * + * Note that all types and functions begin with the `FTC_' prefix. + * + * The cache is highly portable and thus doesn't know anything about the + * fonts installed on your system, or how to access them. This implies + * the following scheme: + * + * First, available or installed font faces are uniquely identified by + * @FTC_FaceID values, provided to the cache by the client. Note that + * the cache only stores and compares these values, and doesn't try to + * interpret them in any way. + * + * Second, the cache calls, only when needed, a client-provided function + * to convert an @FTC_FaceID into a new @FT_Face object. The latter is + * then completely managed by the cache, including its termination + * through @FT_Done_Face. To monitor termination of face objects, the + * finalizer callback in the `generic' field of the @FT_Face object can + * be used, which might also be used to store the @FTC_FaceID of the + * face. + * + * Clients are free to map face IDs to anything else. The most simple + * usage is to associate them to a (pathname,face_index) pair that is + * used to call @FT_New_Face. However, more complex schemes are also + * possible. + * + * Note that for the cache to work correctly, the face ID values must be + * *persistent*, which means that the contents they point to should not + * change at runtime, or that their value should not become invalid. + * + * If this is unavoidable (e.g., when a font is uninstalled at runtime), + * you should call @FTC_Manager_RemoveFaceID as soon as possible, to let + * the cache get rid of any references to the old @FTC_FaceID it may + * keep internally. Failure to do so will lead to incorrect behaviour + * or even crashes. + * + * To use the cache, start with calling @FTC_Manager_New to create a new + * @FTC_Manager object, which models a single cache instance. You can + * then look up @FT_Face and @FT_Size objects with + * @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively. + * + * If you want to use the charmap caching, call @FTC_CMapCache_New, then + * later use @FTC_CMapCache_Lookup to perform the equivalent of + * @FT_Get_Char_Index, only much faster. + * + * If you want to use the @FT_Glyph caching, call @FTC_ImageCache, then + * later use @FTC_ImageCache_Lookup to retrieve the corresponding + * @FT_Glyph objects from the cache. + * + * If you need lots of small bitmaps, it is much more memory efficient + * to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup. This + * returns @FTC_SBitRec structures, which are used to store small + * bitmaps directly. (A small bitmap is one whose metrics and + * dimensions all fit into 8-bit integers). + * + * We hope to also provide a kerning cache in the near future. + * + * + * <Order> + * FTC_Manager + * FTC_FaceID + * FTC_Face_Requester + * + * FTC_Manager_New + * FTC_Manager_Reset + * FTC_Manager_Done + * FTC_Manager_LookupFace + * FTC_Manager_LookupSize + * FTC_Manager_RemoveFaceID + * + * FTC_Node + * FTC_Node_Unref + * + * FTC_ImageCache + * FTC_ImageCache_New + * FTC_ImageCache_Lookup + * + * FTC_SBit + * FTC_SBitCache + * FTC_SBitCache_New + * FTC_SBitCache_Lookup + * + * FTC_CMapCache + * FTC_CMapCache_New + * FTC_CMapCache_Lookup + * + *************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BASIC TYPE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: FTC_FaceID + * + * @description: + * An opaque pointer type that is used to identity face objects. The + * contents of such objects is application-dependent. + * + * These pointers are typically used to point to a user-defined + * structure containing a font file path, and face index. + * + * @note: + * Never use NULL as a valid @FTC_FaceID. + * + * Face IDs are passed by the client to the cache manager that calls, + * when needed, the @FTC_Face_Requester to translate them into new + * @FT_Face objects. + * + * If the content of a given face ID changes at runtime, or if the value + * becomes invalid (e.g., when uninstalling a font), you should + * immediately call @FTC_Manager_RemoveFaceID before any other cache + * function. + * + * Failure to do so will result in incorrect behaviour or even + * memory leaks and crashes. + */ + typedef FT_Pointer FTC_FaceID; + + + /************************************************************************ + * + * @functype: + * FTC_Face_Requester + * + * @description: + * A callback function provided by client applications. It is used by + * the cache manager to translate a given @FTC_FaceID into a new valid + * @FT_Face object, on demand. + * + * <Input> + * face_id :: + * The face ID to resolve. + * + * library :: + * A handle to a FreeType library object. + * + * req_data :: + * Application-provided request data (see note below). + * + * <Output> + * aface :: + * A new @FT_Face handle. + * + * <Return> + * FreeType error code. 0~means success. + * + * <Note> + * The third parameter `req_data' is the same as the one passed by the + * client when @FTC_Manager_New is called. + * + * The face requester should not perform funny things on the returned + * face object, like creating a new @FT_Size for it, or setting a + * transformation through @FT_Set_Transform! + */ + typedef FT_Error + (*FTC_Face_Requester)( FTC_FaceID face_id, + FT_Library library, + FT_Pointer req_data, + FT_Face* aface ); + + /* */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE MANAGER OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Manager */ + /* */ + /* <Description> */ + /* This object corresponds to one instance of the cache-subsystem. */ + /* It is used to cache one or more @FT_Face objects, along with */ + /* corresponding @FT_Size objects. */ + /* */ + /* The manager intentionally limits the total number of opened */ + /* @FT_Face and @FT_Size objects to control memory usage. See the */ + /* `max_faces' and `max_sizes' parameters of @FTC_Manager_New. */ + /* */ + /* The manager is also used to cache `nodes' of various types while */ + /* limiting their total memory usage. */ + /* */ + /* All limitations are enforced by keeping lists of managed objects */ + /* in most-recently-used order, and flushing old nodes to make room */ + /* for new ones. */ + /* */ + typedef struct FTC_ManagerRec_* FTC_Manager; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Node */ + /* */ + /* <Description> */ + /* An opaque handle to a cache node object. Each cache node is */ + /* reference-counted. A node with a count of~0 might be flushed */ + /* out of a full cache whenever a lookup request is performed. */ + /* */ + /* If you look up nodes, you have the ability to `acquire' them, */ + /* i.e., to increment their reference count. This will prevent the */ + /* node from being flushed out of the cache until you explicitly */ + /* `release' it (see @FTC_Node_Unref). */ + /* */ + /* See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup. */ + /* */ + typedef struct FTC_NodeRec_* FTC_Node; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_New */ + /* */ + /* <Description> */ + /* Create a new cache manager. */ + /* */ + /* <Input> */ + /* library :: The parent FreeType library handle to use. */ + /* */ + /* max_faces :: Maximum number of opened @FT_Face objects managed by */ + /* this cache instance. Use~0 for defaults. */ + /* */ + /* max_sizes :: Maximum number of opened @FT_Size objects managed by */ + /* this cache instance. Use~0 for defaults. */ + /* */ + /* max_bytes :: Maximum number of bytes to use for cached data nodes. */ + /* Use~0 for defaults. Note that this value does not */ + /* account for managed @FT_Face and @FT_Size objects. */ + /* */ + /* requester :: An application-provided callback used to translate */ + /* face IDs into real @FT_Face objects. */ + /* */ + /* req_data :: A generic pointer that is passed to the requester */ + /* each time it is called (see @FTC_Face_Requester). */ + /* */ + /* <Output> */ + /* amanager :: A handle to a new manager object. 0~in case of */ + /* failure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_New( FT_Library library, + FT_UInt max_faces, + FT_UInt max_sizes, + FT_ULong max_bytes, + FTC_Face_Requester requester, + FT_Pointer req_data, + FTC_Manager *amanager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Reset */ + /* */ + /* <Description> */ + /* Empty a given cache manager. This simply gets rid of all the */ + /* currently cached @FT_Face and @FT_Size objects within the manager. */ + /* */ + /* <InOut> */ + /* manager :: A handle to the manager. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Reset( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Done */ + /* */ + /* <Description> */ + /* Destroy a given manager after emptying it. */ + /* */ + /* <Input> */ + /* manager :: A handle to the target cache manager object. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Done( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_LookupFace */ + /* */ + /* <Description> */ + /* Retrieve the @FT_Face object that corresponds to a given face ID */ + /* through a cache manager. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* face_id :: The ID of the face object. */ + /* */ + /* <Output> */ + /* aface :: A handle to the face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Face object is always owned by the manager. You */ + /* should never try to discard it yourself. */ + /* */ + /* The @FT_Face object doesn't necessarily have a current size object */ + /* (i.e., face->size can be~0). If you need a specific `font size', */ + /* use @FTC_Manager_LookupSize instead. */ + /* */ + /* Never change the face's transformation matrix (i.e., never call */ + /* the @FT_Set_Transform function) on a returned face! If you need */ + /* to transform glyphs, do it yourself after glyph loading. */ + /* */ + /* When you perform a lookup, out-of-memory errors are detected */ + /* _within_ the lookup and force incremental flushes of the cache */ + /* until enough memory is released for the lookup to succeed. */ + /* */ + /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ + /* already been completely flushed, and still no memory was available */ + /* for the operation. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_LookupFace( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_ScalerRec */ + /* */ + /* <Description> */ + /* A structure used to describe a given character size in either */ + /* pixels or points to the cache manager. See */ + /* @FTC_Manager_LookupSize. */ + /* */ + /* <Fields> */ + /* face_id :: The source face ID. */ + /* */ + /* width :: The character width. */ + /* */ + /* height :: The character height. */ + /* */ + /* pixel :: A Boolean. If 1, the `width' and `height' fields are */ + /* interpreted as integer pixel character sizes. */ + /* Otherwise, they are expressed as 1/64th of points. */ + /* */ + /* x_res :: Only used when `pixel' is value~0 to indicate the */ + /* horizontal resolution in dpi. */ + /* */ + /* y_res :: Only used when `pixel' is value~0 to indicate the */ + /* vertical resolution in dpi. */ + /* */ + /* <Note> */ + /* This type is mainly used to retrieve @FT_Size objects through the */ + /* cache manager. */ + /* */ + typedef struct FTC_ScalerRec_ + { + FTC_FaceID face_id; + FT_UInt width; + FT_UInt height; + FT_Int pixel; + FT_UInt x_res; + FT_UInt y_res; + + } FTC_ScalerRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_Scaler */ + /* */ + /* <Description> */ + /* A handle to an @FTC_ScalerRec structure. */ + /* */ + typedef struct FTC_ScalerRec_* FTC_Scaler; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_LookupSize */ + /* */ + /* <Description> */ + /* Retrieve the @FT_Size object that corresponds to a given */ + /* @FTC_ScalerRec pointer through a cache manager. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* scaler :: A scaler handle. */ + /* */ + /* <Output> */ + /* asize :: A handle to the size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Size object is always owned by the manager. You */ + /* should never try to discard it by yourself. */ + /* */ + /* You can access the parent @FT_Face object simply as `size->face' */ + /* if you need it. Note that this object is also owned by the */ + /* manager. */ + /* */ + /* <Note> */ + /* When you perform a lookup, out-of-memory errors are detected */ + /* _within_ the lookup and force incremental flushes of the cache */ + /* until enough memory is released for the lookup to succeed. */ + /* */ + /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ + /* already been completely flushed, and still no memory is available */ + /* for the operation. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_LookupSize( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Node_Unref */ + /* */ + /* <Description> */ + /* Decrement a cache node's internal reference count. When the count */ + /* reaches 0, it is not destroyed but becomes eligible for subsequent */ + /* cache flushes. */ + /* */ + /* <Input> */ + /* node :: The cache node handle. */ + /* */ + /* manager :: The cache manager handle. */ + /* */ + FT_EXPORT( void ) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ); + + + /************************************************************************* + * + * @function: + * FTC_Manager_RemoveFaceID + * + * @description: + * A special function used to indicate to the cache manager that + * a given @FTC_FaceID is no longer valid, either because its + * content changed, or because it was deallocated or uninstalled. + * + * @input: + * manager :: + * The cache manager handle. + * + * face_id :: + * The @FTC_FaceID to be removed. + * + * @note: + * This function flushes all nodes from the cache corresponding to this + * `face_id', with the exception of nodes with a non-null reference + * count. + * + * Such nodes are however modified internally so as to never appear + * in later lookups with the same `face_id' value, and to be immediately + * destroyed when released by all their users. + * + */ + FT_EXPORT( void ) + FTC_Manager_RemoveFaceID( FTC_Manager manager, + FTC_FaceID face_id ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * FTC_CMapCache + * + * @description: + * An opaque handle used to model a charmap cache. This cache is to + * hold character codes -> glyph indices mappings. + * + */ + typedef struct FTC_CMapCacheRec_* FTC_CMapCache; + + + /************************************************************************* + * + * @function: + * FTC_CMapCache_New + * + * @description: + * Create a new charmap cache. + * + * @input: + * manager :: + * A handle to the cache manager. + * + * @output: + * acache :: + * A new cache handle. NULL in case of error. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Like all other caches, this one will be destroyed with the cache + * manager. + * + */ + FT_EXPORT( FT_Error ) + FTC_CMapCache_New( FTC_Manager manager, + FTC_CMapCache *acache ); + + + /************************************************************************ + * + * @function: + * FTC_CMapCache_Lookup + * + * @description: + * Translate a character code into a glyph index, using the charmap + * cache. + * + * @input: + * cache :: + * A charmap cache handle. + * + * face_id :: + * The source face ID. + * + * cmap_index :: + * The index of the charmap in the source face. Any negative value + * means to use the cache @FT_Face's default charmap. + * + * char_code :: + * The character code (in the corresponding charmap). + * + * @return: + * Glyph index. 0~means `no glyph'. + * + */ + FT_EXPORT( FT_UInt ) + FTC_CMapCache_Lookup( FTC_CMapCache cache, + FTC_FaceID face_id, + FT_Int cmap_index, + FT_UInt32 char_code ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** IMAGE CACHE OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************* + * + * @struct: + * FTC_ImageTypeRec + * + * @description: + * A structure used to model the type of images in a glyph cache. + * + * @fields: + * face_id :: + * The face ID. + * + * width :: + * The width in pixels. + * + * height :: + * The height in pixels. + * + * flags :: + * The load flags, as in @FT_Load_Glyph. + * + */ + typedef struct FTC_ImageTypeRec_ + { + FTC_FaceID face_id; + FT_UInt width; + FT_UInt height; + FT_Int32 flags; + + } FTC_ImageTypeRec; + + + /************************************************************************* + * + * @type: + * FTC_ImageType + * + * @description: + * A handle to an @FTC_ImageTypeRec structure. + * + */ + typedef struct FTC_ImageTypeRec_* FTC_ImageType; + + + /* */ + + +#define FTC_IMAGE_TYPE_COMPARE( d1, d2 ) \ + ( (d1)->face_id == (d2)->face_id && \ + (d1)->width == (d2)->width && \ + (d1)->flags == (d2)->flags ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_ImageCache */ + /* */ + /* <Description> */ + /* A handle to a glyph image cache object. They are designed to */ + /* hold many distinct glyph images while not exceeding a certain */ + /* memory threshold. */ + /* */ + typedef struct FTC_ImageCacheRec_* FTC_ImageCache; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_New */ + /* */ + /* <Description> */ + /* Create a new glyph image cache. */ + /* */ + /* <Input> */ + /* manager :: The parent manager for the image cache. */ + /* */ + /* <Output> */ + /* acache :: A handle to the new glyph image cache object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_Lookup */ + /* */ + /* <Description> */ + /* Retrieve a given glyph image from a glyph image cache. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* type :: A pointer to a glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* <Output> */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the @FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the @FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_LookupScaler */ + /* */ + /* <Description> */ + /* A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec */ + /* to specify the face ID and its size. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* scaler :: A pointer to a scaler descriptor. */ + /* */ + /* load_flags :: The corresponding load flags. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* <Output> */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of the corresponding */ + /* cache node after incrementing its reference count */ + /* (see note below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the @FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the @FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + /* Calls to @FT_Set_Char_Size and friends have no effect on cached */ + /* glyphs; you should always use the FreeType cache API instead. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_LookupScaler( FTC_ImageCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_SBit */ + /* */ + /* <Description> */ + /* A handle to a small bitmap descriptor. See the @FTC_SBitRec */ + /* structure for details. */ + /* */ + typedef struct FTC_SBitRec_* FTC_SBit; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_SBitRec */ + /* */ + /* <Description> */ + /* A very compact structure used to describe a small glyph bitmap. */ + /* */ + /* <Fields> */ + /* width :: The bitmap width in pixels. */ + /* */ + /* height :: The bitmap height in pixels. */ + /* */ + /* left :: The horizontal distance from the pen position to the */ + /* left bitmap border (a.k.a. `left side bearing', or */ + /* `lsb'). */ + /* */ + /* top :: The vertical distance from the pen position (on the */ + /* baseline) to the upper bitmap border (a.k.a. `top */ + /* side bearing'). The distance is positive for upwards */ + /* y~coordinates. */ + /* */ + /* format :: The format of the glyph bitmap (monochrome or gray). */ + /* */ + /* max_grays :: Maximum gray level value (in the range 1 to~255). */ + /* */ + /* pitch :: The number of bytes per bitmap line. May be positive */ + /* or negative. */ + /* */ + /* xadvance :: The horizontal advance width in pixels. */ + /* */ + /* yadvance :: The vertical advance height in pixels. */ + /* */ + /* buffer :: A pointer to the bitmap pixels. */ + /* */ + typedef struct FTC_SBitRec_ + { + FT_Byte width; + FT_Byte height; + FT_Char left; + FT_Char top; + + FT_Byte format; + FT_Byte max_grays; + FT_Short pitch; + FT_Char xadvance; + FT_Char yadvance; + + FT_Byte* buffer; + + } FTC_SBitRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_SBitCache */ + /* */ + /* <Description> */ + /* A handle to a small bitmap cache. These are special cache objects */ + /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ + /* much more efficient way than the traditional glyph image cache */ + /* implemented by @FTC_ImageCache. */ + /* */ + typedef struct FTC_SBitCacheRec_* FTC_SBitCache; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_New */ + /* */ + /* <Description> */ + /* Create a new cache to store small glyph bitmaps. */ + /* */ + /* <Input> */ + /* manager :: A handle to the source cache manager. */ + /* */ + /* <Output> */ + /* acache :: A handle to the new sbit cache. NULL in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_Lookup */ + /* */ + /* <Description> */ + /* Look up a given small glyph bitmap in a given sbit cache and */ + /* `lock' it to prevent its flushing from the cache until needed. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* type :: A pointer to the glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* <Output> */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_LookupScaler */ + /* */ + /* <Description> */ + /* A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec */ + /* to specify the face ID and its size. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* scaler :: A pointer to the scaler descriptor. */ + /* */ + /* load_flags :: The corresponding load flags. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* <Output> */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of the corresponding */ + /* cache node after incrementing its reference count */ + /* (see note below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_LookupScaler( FTC_SBitCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + /* */ + + +FT_END_HEADER + +#endif /* FTCACHE_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftcffdrv.h b/builddir/freetype-2.7.0/include/freetype/ftcffdrv.h new file mode 100644 index 0000000..8f88cc4 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftcffdrv.h @@ -0,0 +1,275 @@ +/***************************************************************************/ +/* */ +/* ftcffdrv.h */ +/* */ +/* FreeType API for controlling the CFF driver (specification only). */ +/* */ +/* Copyright 2013-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTCFFDRV_H_ +#define FTCFFDRV_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * cff_driver + * + * @title: + * The CFF driver + * + * @abstract: + * Controlling the CFF driver module. + * + * @description: + * While FreeType's CFF driver doesn't expose API functions by itself, + * it is possible to control its behaviour with @FT_Property_Set and + * @FT_Property_Get. The list below gives the available properties + * together with the necessary macros and structures. + * + * The CFF driver's module name is `cff'. + * + * *Hinting* *and* *antialiasing* *principles* *of* *the* *new* *engine* + * + * The rasterizer is positioning horizontal features (e.g., ascender + * height & x-height, or crossbars) on the pixel grid and minimizing the + * amount of antialiasing applied to them, while placing vertical + * features (vertical stems) on the pixel grid without hinting, thus + * representing the stem position and weight accurately. Sometimes the + * vertical stems may be only partially black. In this context, + * `antialiasing' means that stems are not positioned exactly on pixel + * borders, causing a fuzzy appearance. + * + * There are two principles behind this approach. + * + * 1) No hinting in the horizontal direction: Unlike `superhinted' + * TrueType, which changes glyph widths to accommodate regular + * inter-glyph spacing, Adobe's approach is `faithful to the design' in + * representing both the glyph width and the inter-glyph spacing + * designed for the font. This makes the screen display as close as it + * can be to the result one would get with infinite resolution, while + * preserving what is considered the key characteristics of each glyph. + * Note that the distances between unhinted and grid-fitted positions at + * small sizes are comparable to kerning values and thus would be + * noticeable (and distracting) while reading if hinting were applied. + * + * One of the reasons to not hint horizontally is antialiasing for LCD + * screens: The pixel geometry of modern displays supplies three + * vertical sub-pixels as the eye moves horizontally across each visible + * pixel. On devices where we can be certain this characteristic is + * present a rasterizer can take advantage of the sub-pixels to add + * increments of weight. In Western writing systems this turns out to + * be the more critical direction anyway; the weights and spacing of + * vertical stems (see above) are central to Armenian, Cyrillic, Greek, + * and Latin type designs. Even when the rasterizer uses greyscale + * antialiasing instead of color (a necessary compromise when one + * doesn't know the screen characteristics), the unhinted vertical + * features preserve the design's weight and spacing much better than + * aliased type would. + * + * 2) Alignment in the vertical direction: Weights and spacing along the + * y~axis are less critical; what is much more important is the visual + * alignment of related features (like cap-height and x-height). The + * sense of alignment for these is enhanced by the sharpness of grid-fit + * edges, while the cruder vertical resolution (full pixels instead of + * 1/3 pixels) is less of a problem. + * + * On the technical side, horizontal alignment zones for ascender, + * x-height, and other important height values (traditionally called + * `blue zones') as defined in the font are positioned independently, + * each being rounded to the nearest pixel edge, taking care of + * overshoot suppression at small sizes, stem darkening, and scaling. + * + * Hstems (this is, hint values defined in the font to help align + * horizontal features) that fall within a blue zone are said to be + * `captured' and are aligned to that zone. Uncaptured stems are moved + * in one of four ways, top edge up or down, bottom edge up or down. + * Unless there are conflicting hstems, the smallest movement is taken + * to minimize distortion. + * + * @order: + * hinting-engine[cff] + * no-stem-darkening[cff] + * darkening-parameters[cff] + * + */ + + + /************************************************************************** + * + * @property: + * hinting-engine[cff] + * + * @description: + * Thanks to Adobe, which contributed a new hinting (and parsing) + * engine, an application can select between `freetype' and `adobe' if + * compiled with CFF_CONFIG_OPTION_OLD_ENGINE. If this configuration + * macro isn't defined, `hinting-engine' does nothing. + * + * The default engine is `freetype' if CFF_CONFIG_OPTION_OLD_ENGINE is + * defined, and `adobe' otherwise. + * + * The following example code demonstrates how to select Adobe's hinting + * engine (omitting the error handling). + * + * { + * FT_Library library; + * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "hinting-engine", &hinting_engine ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values `adobe' or `freetype'). + */ + + + /************************************************************************** + * + * @enum: + * FT_CFF_HINTING_XXX + * + * @description: + * A list of constants used for the @hinting-engine[cff] property to + * select the hinting engine for CFF fonts. + * + * @values: + * FT_CFF_HINTING_FREETYPE :: + * Use the old FreeType hinting engine. + * + * FT_CFF_HINTING_ADOBE :: + * Use the hinting engine contributed by Adobe. + * + */ +#define FT_CFF_HINTING_FREETYPE 0 +#define FT_CFF_HINTING_ADOBE 1 + + + /************************************************************************** + * + * @property: + * no-stem-darkening[cff] + * + * @description: + * By default, the Adobe CFF engine darkens stems at smaller sizes, + * regardless of hinting, to enhance contrast. This feature requires + * a rendering system with proper gamma correction. Setting this + * property, stem darkening gets switched off. + * + * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set. + * + * { + * FT_Library library; + * FT_Bool no_stem_darkening = TRUE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "no-stem-darkening", &no_stem_darkening ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values 1 and 0 for `on' and `off', respectively). + * + */ + + + /************************************************************************** + * + * @property: + * darkening-parameters[cff] + * + * @description: + * By default, the Adobe CFF engine darkens stems as follows (if the + * `no-stem-darkening' property isn't set): + * + * { + * stem width <= 0.5px: darkening amount = 0.4px + * stem width = 1px: darkening amount = 0.275px + * stem width = 1.667px: darkening amount = 0.275px + * stem width >= 2.333px: darkening amount = 0px + * } + * + * and piecewise linear in-between. At configuration time, these four + * control points can be set with the macro + * `CFF_CONFIG_OPTION_DARKENING_PARAMETERS'. At runtime, the control + * points can be changed using the `darkening-parameters' property, as + * the following example demonstrates. + * + * { + * FT_Library library; + * FT_Int darken_params[8] = { 500, 300, // x1, y1 + * 1000, 200, // x2, y2 + * 1500, 100, // x3, y3 + * 2000, 0 }; // x4, y4 + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "darkening-parameters", darken_params ); + * } + * + * The x~values give the stem width, and the y~values the darkening + * amount. The unit is 1000th of pixels. All coordinate values must be + * positive; the x~values must be monotonically increasing; the + * y~values must be monotonically decreasing and smaller than or + * equal to 500 (corresponding to half a pixel); the slope of each + * linear piece must be shallower than -1 (e.g., -.4). + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable, using eight comma-separated integers without spaces. Here + * the above example, using `\' to break the line for readability. + * + * { + * FREETYPE_PROPERTIES=\ + * cff:darkening-parameters=500,300,1000,200,1500,100,2000,0 + * } + */ + + /* */ + + +FT_END_HEADER + + +#endif /* FTCFFDRV_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftchapters.h b/builddir/freetype-2.7.0/include/freetype/ftchapters.h new file mode 100644 index 0000000..ab43895 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftchapters.h @@ -0,0 +1,135 @@ +/***************************************************************************/ +/* */ +/* This file defines the structure of the FreeType reference. */ +/* It is used by the python script that generates the HTML files. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* general_remarks */ +/* */ +/* <Title> */ +/* General Remarks */ +/* */ +/* <Sections> */ +/* header_inclusion */ +/* user_allocation */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* core_api */ +/* */ +/* <Title> */ +/* Core API */ +/* */ +/* <Sections> */ +/* version */ +/* basic_types */ +/* base_interface */ +/* glyph_variants */ +/* glyph_management */ +/* mac_specific */ +/* sizes_management */ +/* header_file_macros */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* format_specific */ +/* */ +/* <Title> */ +/* Format-Specific API */ +/* */ +/* <Sections> */ +/* multiple_masters */ +/* truetype_tables */ +/* type1_tables */ +/* sfnt_names */ +/* bdf_fonts */ +/* cid_fonts */ +/* pfr_fonts */ +/* winfnt_fonts */ +/* font_formats */ +/* gasp_table */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* module_specific */ +/* */ +/* <Title> */ +/* Controlling FreeType Modules */ +/* */ +/* <Sections> */ +/* auto_hinter */ +/* cff_driver */ +/* tt_driver */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* cache_subsystem */ +/* */ +/* <Title> */ +/* Cache Sub-System */ +/* */ +/* <Sections> */ +/* cache_subsystem */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* support_api */ +/* */ +/* <Title> */ +/* Support API */ +/* */ +/* <Sections> */ +/* computations */ +/* list_processing */ +/* outline_processing */ +/* quick_advance */ +/* bitmap_handling */ +/* raster */ +/* glyph_stroker */ +/* system_interface */ +/* module_management */ +/* gzip */ +/* lzw */ +/* bzip2 */ +/* lcd_filtering */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* error_codes */ +/* */ +/* <Title> */ +/* Error Codes */ +/* */ +/* <Sections> */ +/* error_enumerations */ +/* error_code_values */ +/* */ +/***************************************************************************/ diff --git a/builddir/freetype-2.7.0/include/freetype/ftcid.h b/builddir/freetype-2.7.0/include/freetype/ftcid.h new file mode 100644 index 0000000..e1bc9fe --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftcid.h @@ -0,0 +1,168 @@ +/***************************************************************************/ +/* */ +/* ftcid.h */ +/* */ +/* FreeType API for accessing CID font information (specification). */ +/* */ +/* Copyright 2007-2016 by */ +/* Dereg Clegg and Michael Toftdal. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTCID_H_ +#define FTCID_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cid_fonts */ + /* */ + /* <Title> */ + /* CID Fonts */ + /* */ + /* <Abstract> */ + /* CID-keyed font specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of CID-keyed font specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Registry_Ordering_Supplement + * + * @description: + * Retrieve the Registry/Ordering/Supplement triple (also known as the + * "R/O/S") from a CID-keyed font. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * registry :: + * The registry, as a C~string, owned by the face. + * + * ordering :: + * The ordering, as a C~string, owned by the face. + * + * supplement :: + * The supplement. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces, returning an error + * otherwise. + * + * @since: + * 2.3.6 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Is_Internally_CID_Keyed + * + * @description: + * Retrieve the type of the input face, CID keyed or not. In + * contrast to the @FT_IS_CID_KEYED macro this function returns + * successfully also for CID-keyed fonts in an SFNT wrapper. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * is_cid :: + * The type of the face as an @FT_Bool. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid ); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_From_Glyph_Index + * + * @description: + * Retrieve the CID of the input glyph index. + * + * @input: + * face :: + * A handle to the input face. + * + * glyph_index :: + * The input glyph index. + * + * @output: + * cid :: + * The CID as an @FT_UInt. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ); + + /* */ + + +FT_END_HEADER + +#endif /* FTCID_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/fterrdef.h b/builddir/freetype-2.7.0/include/freetype/fterrdef.h new file mode 100644 index 0000000..3f53dd5 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/fterrdef.h @@ -0,0 +1,276 @@ +/***************************************************************************/ +/* */ +/* fterrdef.h */ +/* */ +/* FreeType error codes (specification). */ +/* */ +/* Copyright 2002-2016 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* error_code_values */ + /* */ + /* <Title> */ + /* Error Code Values */ + /* */ + /* <Abstract> */ + /* All possible error codes returned by FreeType functions. */ + /* */ + /* <Description> */ + /* The list below is taken verbatim from the file `fterrdef.h' */ + /* (loaded automatically by including `FT_FREETYPE_H'). The first */ + /* argument of the `FT_ERROR_DEF_' macro is the error label; by */ + /* default, the prefix `FT_Err_' gets added so that you get error */ + /* names like `FT_Err_Cannot_Open_Resource'. The second argument is */ + /* the error code, and the last argument an error string, which is not */ + /* used by FreeType. */ + /* */ + /* Within your application you should *only* use error names and */ + /* *never* its numeric values! The latter might (and actually do) */ + /* change in forthcoming FreeType versions. */ + /* */ + /* Macro `FT_NOERRORDEF_' defines `FT_Err_Ok', which is always zero. */ + /* See the `Error Enumerations' subsection how to automatically */ + /* generate a list of error strings. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Err_XXX */ + /* */ + /*************************************************************************/ + + /* generic errors */ + + FT_NOERRORDEF_( Ok, 0x00, + "no error" ) + + FT_ERRORDEF_( Cannot_Open_Resource, 0x01, + "cannot open resource" ) + FT_ERRORDEF_( Unknown_File_Format, 0x02, + "unknown file format" ) + FT_ERRORDEF_( Invalid_File_Format, 0x03, + "broken file" ) + FT_ERRORDEF_( Invalid_Version, 0x04, + "invalid FreeType version" ) + FT_ERRORDEF_( Lower_Module_Version, 0x05, + "module version is too low" ) + FT_ERRORDEF_( Invalid_Argument, 0x06, + "invalid argument" ) + FT_ERRORDEF_( Unimplemented_Feature, 0x07, + "unimplemented feature" ) + FT_ERRORDEF_( Invalid_Table, 0x08, + "broken table" ) + FT_ERRORDEF_( Invalid_Offset, 0x09, + "broken offset within table" ) + FT_ERRORDEF_( Array_Too_Large, 0x0A, + "array allocation size too large" ) + FT_ERRORDEF_( Missing_Module, 0x0B, + "missing module" ) + FT_ERRORDEF_( Missing_Property, 0x0C, + "missing property" ) + + /* glyph/character errors */ + + FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, + "invalid glyph index" ) + FT_ERRORDEF_( Invalid_Character_Code, 0x11, + "invalid character code" ) + FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, + "unsupported glyph image format" ) + FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, + "cannot render this glyph format" ) + FT_ERRORDEF_( Invalid_Outline, 0x14, + "invalid outline" ) + FT_ERRORDEF_( Invalid_Composite, 0x15, + "invalid composite glyph" ) + FT_ERRORDEF_( Too_Many_Hints, 0x16, + "too many hints" ) + FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, + "invalid pixel size" ) + + /* handle errors */ + + FT_ERRORDEF_( Invalid_Handle, 0x20, + "invalid object handle" ) + FT_ERRORDEF_( Invalid_Library_Handle, 0x21, + "invalid library handle" ) + FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, + "invalid module handle" ) + FT_ERRORDEF_( Invalid_Face_Handle, 0x23, + "invalid face handle" ) + FT_ERRORDEF_( Invalid_Size_Handle, 0x24, + "invalid size handle" ) + FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, + "invalid glyph slot handle" ) + FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, + "invalid charmap handle" ) + FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, + "invalid cache manager handle" ) + FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, + "invalid stream handle" ) + + /* driver errors */ + + FT_ERRORDEF_( Too_Many_Drivers, 0x30, + "too many modules" ) + FT_ERRORDEF_( Too_Many_Extensions, 0x31, + "too many extensions" ) + + /* memory errors */ + + FT_ERRORDEF_( Out_Of_Memory, 0x40, + "out of memory" ) + FT_ERRORDEF_( Unlisted_Object, 0x41, + "unlisted object" ) + + /* stream errors */ + + FT_ERRORDEF_( Cannot_Open_Stream, 0x51, + "cannot open stream" ) + FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, + "invalid stream seek" ) + FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, + "invalid stream skip" ) + FT_ERRORDEF_( Invalid_Stream_Read, 0x54, + "invalid stream read" ) + FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, + "invalid stream operation" ) + FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, + "invalid frame operation" ) + FT_ERRORDEF_( Nested_Frame_Access, 0x57, + "nested frame access" ) + FT_ERRORDEF_( Invalid_Frame_Read, 0x58, + "invalid frame read" ) + + /* raster errors */ + + FT_ERRORDEF_( Raster_Uninitialized, 0x60, + "raster uninitialized" ) + FT_ERRORDEF_( Raster_Corrupted, 0x61, + "raster corrupted" ) + FT_ERRORDEF_( Raster_Overflow, 0x62, + "raster overflow" ) + FT_ERRORDEF_( Raster_Negative_Height, 0x63, + "negative height while rastering" ) + + /* cache errors */ + + FT_ERRORDEF_( Too_Many_Caches, 0x70, + "too many registered caches" ) + + /* TrueType and SFNT errors */ + + FT_ERRORDEF_( Invalid_Opcode, 0x80, + "invalid opcode" ) + FT_ERRORDEF_( Too_Few_Arguments, 0x81, + "too few arguments" ) + FT_ERRORDEF_( Stack_Overflow, 0x82, + "stack overflow" ) + FT_ERRORDEF_( Code_Overflow, 0x83, + "code overflow" ) + FT_ERRORDEF_( Bad_Argument, 0x84, + "bad argument" ) + FT_ERRORDEF_( Divide_By_Zero, 0x85, + "division by zero" ) + FT_ERRORDEF_( Invalid_Reference, 0x86, + "invalid reference" ) + FT_ERRORDEF_( Debug_OpCode, 0x87, + "found debug opcode" ) + FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, + "found ENDF opcode in execution stream" ) + FT_ERRORDEF_( Nested_DEFS, 0x89, + "nested DEFS" ) + FT_ERRORDEF_( Invalid_CodeRange, 0x8A, + "invalid code range" ) + FT_ERRORDEF_( Execution_Too_Long, 0x8B, + "execution context too long" ) + FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, + "too many function definitions" ) + FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, + "too many instruction definitions" ) + FT_ERRORDEF_( Table_Missing, 0x8E, + "SFNT font table missing" ) + FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, + "horizontal header (hhea) table missing" ) + FT_ERRORDEF_( Locations_Missing, 0x90, + "locations (loca) table missing" ) + FT_ERRORDEF_( Name_Table_Missing, 0x91, + "name table missing" ) + FT_ERRORDEF_( CMap_Table_Missing, 0x92, + "character map (cmap) table missing" ) + FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, + "horizontal metrics (hmtx) table missing" ) + FT_ERRORDEF_( Post_Table_Missing, 0x94, + "PostScript (post) table missing" ) + FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, + "invalid horizontal metrics" ) + FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, + "invalid character map (cmap) format" ) + FT_ERRORDEF_( Invalid_PPem, 0x97, + "invalid ppem value" ) + FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, + "invalid vertical metrics" ) + FT_ERRORDEF_( Could_Not_Find_Context, 0x99, + "could not find context" ) + FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, + "invalid PostScript (post) table format" ) + FT_ERRORDEF_( Invalid_Post_Table, 0x9B, + "invalid PostScript (post) table" ) + + /* CFF, CID, and Type 1 errors */ + + FT_ERRORDEF_( Syntax_Error, 0xA0, + "opcode syntax error" ) + FT_ERRORDEF_( Stack_Underflow, 0xA1, + "argument stack underflow" ) + FT_ERRORDEF_( Ignore, 0xA2, + "ignore" ) + FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, + "no Unicode glyph name found" ) + FT_ERRORDEF_( Glyph_Too_Big, 0xA4, + "glyph too big for hinting" ) + + /* BDF errors */ + + FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, + "`STARTFONT' field missing" ) + FT_ERRORDEF_( Missing_Font_Field, 0xB1, + "`FONT' field missing" ) + FT_ERRORDEF_( Missing_Size_Field, 0xB2, + "`SIZE' field missing" ) + FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, + "`FONTBOUNDINGBOX' field missing" ) + FT_ERRORDEF_( Missing_Chars_Field, 0xB4, + "`CHARS' field missing" ) + FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, + "`STARTCHAR' field missing" ) + FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, + "`ENCODING' field missing" ) + FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, + "`BBX' field missing" ) + FT_ERRORDEF_( Bbx_Too_Big, 0xB8, + "`BBX' too big" ) + FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, + "Font header corrupted or missing fields" ) + FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, + "Font glyphs corrupted or missing fields" ) + + /* */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/fterrors.h b/builddir/freetype-2.7.0/include/freetype/fterrors.h new file mode 100644 index 0000000..e15bfb0 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/fterrors.h @@ -0,0 +1,226 @@ +/***************************************************************************/ +/* */ +/* fterrors.h */ +/* */ +/* FreeType error code handling (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* error_enumerations */ + /* */ + /* <Title> */ + /* Error Enumerations */ + /* */ + /* <Abstract> */ + /* How to handle errors and error strings. */ + /* */ + /* <Description> */ + /* The header file `fterrors.h' (which is automatically included by */ + /* `freetype.h' defines the handling of FreeType's enumeration */ + /* constants. It can also be used to generate error message strings */ + /* with a small macro trick explained below. */ + /* */ + /* *Error* *Formats* */ + /* */ + /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ + /* defined in `ftoption.h' in order to make the higher byte indicate */ + /* the module where the error has happened (this is not compatible */ + /* with standard builds of FreeType 2, however). See the file */ + /* `ftmoderr.h' for more details. */ + /* */ + /* *Error* *Message* *Strings* */ + /* */ + /* Error definitions are set up with special macros that allow client */ + /* applications to build a table of error message strings. The */ + /* strings are not included in a normal build of FreeType 2 to */ + /* save space (most client applications do not use them). */ + /* */ + /* To do so, you have to define the following macros before including */ + /* this file. */ + /* */ + /* { */ + /* FT_ERROR_START_LIST */ + /* } */ + /* */ + /* This macro is called before anything else to define the start of */ + /* the error list. It is followed by several FT_ERROR_DEF calls. */ + /* */ + /* { */ + /* FT_ERROR_DEF( e, v, s ) */ + /* } */ + /* */ + /* This macro is called to define one single error. `e' is the error */ + /* code identifier (e.g., `Invalid_Argument'), `v' is the error's */ + /* numerical value, and `s' is the corresponding error string. */ + /* */ + /* { */ + /* FT_ERROR_END_LIST */ + /* } */ + /* */ + /* This macro ends the list. */ + /* */ + /* Additionally, you have to undefine `FTERRORS_H_' before #including */ + /* this file. */ + /* */ + /* Here is a simple example. */ + /* */ + /* { */ + /* #undef FTERRORS_H_ */ + /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ + /* #define FT_ERROR_START_LIST { */ + /* #define FT_ERROR_END_LIST { 0, NULL } }; */ + /* */ + /* const struct */ + /* { */ + /* int err_code; */ + /* const char* err_msg; */ + /* } ft_errors[] = */ + /* */ + /* #include FT_ERRORS_H */ + /* } */ + /* */ + /* Note that `FT_Err_Ok' is _not_ defined with `FT_ERRORDEF' but with */ + /* `FT_NOERRORDEF'; it is always zero. */ + /* */ + /*************************************************************************/ + + /* */ + + /* In previous FreeType versions we used `__FTERRORS_H__'. However, */ + /* using two successive underscores in a non-system symbol name */ + /* violates the C (and C++) standard, so it was changed to the */ + /* current form. In spite of this, we have to make */ + /* */ + /* #undefine __FTERRORS_H__ */ + /* */ + /* work for backwards compatibility. */ + /* */ +#if !( defined( FTERRORS_H_ ) && defined ( __FTERRORS_H__ ) ) +#define FTERRORS_H_ +#define __FTERRORS_H__ + + + /* include module base error codes */ +#include FT_MODULE_ERRORS_H + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + + + /* FT_ERR_PREFIX is used as a prefix for error identifiers. */ + /* By default, we use `FT_Err_'. */ + /* */ +#ifndef FT_ERR_PREFIX +#define FT_ERR_PREFIX FT_Err_ +#endif + + + /* FT_ERR_BASE is used as the base for module-specific errors. */ + /* */ +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS + +#ifndef FT_ERR_BASE +#define FT_ERR_BASE FT_Mod_Err_Base +#endif + +#else + +#undef FT_ERR_BASE +#define FT_ERR_BASE 0 + +#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */ + + + /* If FT_ERRORDEF is not defined, we need to define a simple */ + /* enumeration type. */ + /* */ +#ifndef FT_ERRORDEF + +#define FT_ERRORDEF( e, v, s ) e = v, +#define FT_ERROR_START_LIST enum { +#define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_ERRORDEF */ + + + /* this macro is used to define an error */ +#define FT_ERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s ) + + /* this is only used for <module>_Err_Ok, which must be 0! */ +#define FT_NOERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s ) + + +#ifdef FT_ERROR_START_LIST + FT_ERROR_START_LIST +#endif + + + /* now include the error codes */ +#include FT_ERROR_DEFINITIONS_H + + +#ifdef FT_ERROR_END_LIST + FT_ERROR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SIMPLE CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_ERROR_START_LIST +#undef FT_ERROR_END_LIST + +#undef FT_ERRORDEF +#undef FT_ERRORDEF_ +#undef FT_NOERRORDEF_ + +#undef FT_NEED_EXTERN_C +#undef FT_ERR_BASE + + /* FT_ERR_PREFIX is needed internally */ +#ifndef FT2_BUILD_LIBRARY +#undef FT_ERR_PREFIX +#endif + +#endif /* !(FTERRORS_H_ && __FTERRORS_H__) */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftfntfmt.h b/builddir/freetype-2.7.0/include/freetype/ftfntfmt.h new file mode 100644 index 0000000..bd42324 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftfntfmt.h @@ -0,0 +1,95 @@ +/***************************************************************************/ +/* */ +/* ftfntfmt.h */ +/* */ +/* Support functions for font formats. */ +/* */ +/* Copyright 2002-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTFNTFMT_H_ +#define FTFNTFMT_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* font_formats */ + /* */ + /* <Title> */ + /* Font Formats */ + /* */ + /* <Abstract> */ + /* Getting the font format. */ + /* */ + /* <Description> */ + /* The single function in this section can be used to get the font */ + /* format. Note that this information is not needed normally; */ + /* however, there are special cases (like in PDF devices) where it is */ + /* important to differentiate, in spite of FreeType's uniform API. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Font_Format */ + /* */ + /* <Description> */ + /* Return a string describing the format of a given face. Possible */ + /* values are `TrueType', `Type~1', `BDF', `PCF', `Type~42', */ + /* `CID~Type~1', `CFF', `PFR', and `Windows~FNT'. */ + /* */ + /* The return value is suitable to be used as an X11 FONT_PROPERTY. */ + /* */ + /* <Input> */ + /* face :: */ + /* Input face handle. */ + /* */ + /* <Return> */ + /* Font format string. NULL in case of error. */ + /* */ + /* <Note> */ + /* A deprecated name for the same function is */ + /* `FT_Get_X11_Font_Format'. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_Font_Format( FT_Face face ); + + + /* deprecated */ + FT_EXPORT( const char* ) + FT_Get_X11_Font_Format( FT_Face face ); + + + /* */ + + +FT_END_HEADER + +#endif /* FTFNTFMT_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftgasp.h b/builddir/freetype-2.7.0/include/freetype/ftgasp.h new file mode 100644 index 0000000..3f5b3bc --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftgasp.h @@ -0,0 +1,129 @@ +/***************************************************************************/ +/* */ +/* ftgasp.h */ +/* */ +/* Access of TrueType's `gasp' table (specification). */ +/* */ +/* Copyright 2007-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTGASP_H_ +#define FTGASP_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + + /*************************************************************************** + * + * @section: + * gasp_table + * + * @title: + * Gasp Table + * + * @abstract: + * Retrieving TrueType `gasp' table entries. + * + * @description: + * The function @FT_Get_Gasp can be used to query a TrueType or OpenType + * font for specific entries in its `gasp' table, if any. This is + * mainly useful when implementing native TrueType hinting with the + * bytecode interpreter to duplicate the Windows text rendering results. + */ + + /************************************************************************* + * + * @enum: + * FT_GASP_XXX + * + * @description: + * A list of values and/or bit-flags returned by the @FT_Get_Gasp + * function. + * + * @values: + * FT_GASP_NO_TABLE :: + * This special value means that there is no GASP table in this face. + * It is up to the client to decide what to do. + * + * FT_GASP_DO_GRIDFIT :: + * Grid-fitting and hinting should be performed at the specified ppem. + * This *really* means TrueType bytecode interpretation. If this bit + * is not set, no hinting gets applied. + * + * FT_GASP_DO_GRAY :: + * Anti-aliased rendering should be performed at the specified ppem. + * If not set, do monochrome rendering. + * + * FT_GASP_SYMMETRIC_SMOOTHING :: + * If set, smoothing along multiple axes must be used with ClearType. + * + * FT_GASP_SYMMETRIC_GRIDFIT :: + * Grid-fitting must be used with ClearType's symmetric smoothing. + * + * @note: + * The bit-flags `FT_GASP_DO_GRIDFIT' and `FT_GASP_DO_GRAY' are to be + * used for standard font rasterization only. Independently of that, + * `FT_GASP_SYMMETRIC_SMOOTHING' and `FT_GASP_SYMMETRIC_GRIDFIT' are to + * be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT' and + * `FT_GASP_DO_GRAY' are consequently ignored). + * + * `ClearType' is Microsoft's implementation of LCD rendering, partly + * protected by patents. + * + * @since: + * 2.3.0 + */ +#define FT_GASP_NO_TABLE -1 +#define FT_GASP_DO_GRIDFIT 0x01 +#define FT_GASP_DO_GRAY 0x02 +#define FT_GASP_SYMMETRIC_SMOOTHING 0x08 +#define FT_GASP_SYMMETRIC_GRIDFIT 0x10 + + + /************************************************************************* + * + * @func: + * FT_Get_Gasp + * + * @description: + * Read the `gasp' table from a TrueType or OpenType font file and + * return the entry corresponding to a given character pixel size. + * + * @input: + * face :: The source face handle. + * ppem :: The vertical character pixel size. + * + * @return: + * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no + * `gasp' table in the face. + * + * @since: + * 2.3.0 + */ + FT_EXPORT( FT_Int ) + FT_Get_Gasp( FT_Face face, + FT_UInt ppem ); + + /* */ + + +#endif /* FTGASP_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftglyph.h b/builddir/freetype-2.7.0/include/freetype/ftglyph.h new file mode 100644 index 0000000..d9840a8 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftglyph.h @@ -0,0 +1,605 @@ +/***************************************************************************/ +/* */ +/* ftglyph.h */ +/* */ +/* FreeType convenience functions to handle glyphs (specification). */ +/* */ +/* Copyright 1996-2016 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 file contains the definition of several convenience functions */ + /* that can be used by client applications to easily retrieve glyph */ + /* bitmaps and outlines from a given face. */ + /* */ + /* These functions should be optional if you are writing a font server */ + /* or text layout engine on top of FreeType. However, they are pretty */ + /* handy for many other simple uses of the library. */ + /* */ + /*************************************************************************/ + + +#ifndef FTGLYPH_H_ +#define FTGLYPH_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* glyph_management */ + /* */ + /* <Title> */ + /* Glyph Management */ + /* */ + /* <Abstract> */ + /* Generic interface to manage individual glyph data. */ + /* */ + /* <Description> */ + /* This section contains definitions used to manage glyph data */ + /* through generic FT_Glyph objects. Each of them can contain a */ + /* bitmap, a vector outline, or even images in other formats. */ + /* */ + /*************************************************************************/ + + + /* forward declaration to a private type */ + typedef struct FT_Glyph_Class_ FT_Glyph_Class; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Glyph */ + /* */ + /* <Description> */ + /* Handle to an object used to model generic glyph images. It is a */ + /* pointer to the @FT_GlyphRec structure and can contain a glyph */ + /* bitmap or pointer. */ + /* */ + /* <Note> */ + /* Glyph objects are not owned by the library. You must thus release */ + /* them manually (through @FT_Done_Glyph) _before_ calling */ + /* @FT_Done_FreeType. */ + /* */ + typedef struct FT_GlyphRec_* FT_Glyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphRec */ + /* */ + /* <Description> */ + /* The root glyph structure contains a given glyph image plus its */ + /* advance width in 16.16 fixed-point format. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library object. */ + /* */ + /* clazz :: A pointer to the glyph's class. Private. */ + /* */ + /* format :: The format of the glyph's image. */ + /* */ + /* advance :: A 16.16 vector that gives the glyph's advance width. */ + /* */ + typedef struct FT_GlyphRec_ + { + FT_Library library; + const FT_Glyph_Class* clazz; + FT_Glyph_Format format; + FT_Vector advance; + + } FT_GlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_BitmapGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model a bitmap glyph image. This is */ + /* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. */ + /* */ + typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BitmapGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for bitmap glyph images. This really is a */ + /* `sub-class' of @FT_GlyphRec. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Glyph fields. */ + /* */ + /* left :: The left-side bearing, i.e., the horizontal distance */ + /* from the current pen position to the left border of the */ + /* glyph bitmap. */ + /* */ + /* top :: The top-side bearing, i.e., the vertical distance from */ + /* the current pen position to the top border of the glyph */ + /* bitmap. This distance is positive for upwards~y! */ + /* */ + /* bitmap :: A descriptor for the bitmap. */ + /* */ + /* <Note> */ + /* You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have */ + /* `glyph->format == FT_GLYPH_FORMAT_BITMAP'. This lets you access */ + /* the bitmap's contents easily. */ + /* */ + /* The corresponding pixel buffer is always owned by @FT_BitmapGlyph */ + /* and is thus created and destroyed with it. */ + /* */ + typedef struct FT_BitmapGlyphRec_ + { + FT_GlyphRec root; + FT_Int left; + FT_Int top; + FT_Bitmap bitmap; + + } FT_BitmapGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_OutlineGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model an outline glyph image. This */ + /* is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. */ + /* */ + typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_OutlineGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for outline (vectorial) glyph images. This */ + /* really is a `sub-class' of @FT_GlyphRec. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Glyph fields. */ + /* */ + /* outline :: A descriptor for the outline. */ + /* */ + /* <Note> */ + /* You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have */ + /* `glyph->format == FT_GLYPH_FORMAT_OUTLINE'. This lets you access */ + /* the outline's content easily. */ + /* */ + /* As the outline is extracted from a glyph slot, its coordinates are */ + /* expressed normally in 26.6 pixels, unless the flag */ + /* @FT_LOAD_NO_SCALE was used in @FT_Load_Glyph() or @FT_Load_Char(). */ + /* */ + /* The outline's tables are always owned by the object and are */ + /* destroyed with it. */ + /* */ + typedef struct FT_OutlineGlyphRec_ + { + FT_GlyphRec root; + FT_Outline outline; + + } FT_OutlineGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph */ + /* */ + /* <Description> */ + /* A function used to extract a glyph image from a slot. Note that */ + /* the created @FT_Glyph object must be released with @FT_Done_Glyph. */ + /* */ + /* <Input> */ + /* slot :: A handle to the source glyph slot. */ + /* */ + /* <Output> */ + /* aglyph :: A handle to the glyph object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph( FT_GlyphSlot slot, + FT_Glyph *aglyph ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Copy */ + /* */ + /* <Description> */ + /* A function used to copy a glyph image. Note that the created */ + /* @FT_Glyph object must be released with @FT_Done_Glyph. */ + /* */ + /* <Input> */ + /* source :: A handle to the source glyph object. */ + /* */ + /* <Output> */ + /* target :: A handle to the target glyph object. 0~in case of */ + /* error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Copy( FT_Glyph source, + FT_Glyph *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Transform */ + /* */ + /* <Description> */ + /* Transform a glyph image if its format is scalable. */ + /* */ + /* <InOut> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to a 2x2 matrix to apply. */ + /* */ + /* delta :: A pointer to a 2d vector to apply. Coordinates are */ + /* expressed in 1/64th of a pixel. */ + /* */ + /* <Return> */ + /* FreeType error code (if not 0, the glyph format is not scalable). */ + /* */ + /* <Note> */ + /* The 2x2 transformation matrix is also applied to the glyph's */ + /* advance vector. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Transform( FT_Glyph glyph, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Glyph_BBox_Mode */ + /* */ + /* <Description> */ + /* The mode how the values of @FT_Glyph_Get_CBox are returned. */ + /* */ + /* <Values> */ + /* FT_GLYPH_BBOX_UNSCALED :: */ + /* Return unscaled font units. */ + /* */ + /* FT_GLYPH_BBOX_SUBPIXELS :: */ + /* Return unfitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_GRIDFIT :: */ + /* Return grid-fitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_TRUNCATE :: */ + /* Return coordinates in integer pixels. */ + /* */ + /* FT_GLYPH_BBOX_PIXELS :: */ + /* Return grid-fitted pixel coordinates. */ + /* */ + typedef enum FT_Glyph_BBox_Mode_ + { + FT_GLYPH_BBOX_UNSCALED = 0, + FT_GLYPH_BBOX_SUBPIXELS = 0, + FT_GLYPH_BBOX_GRIDFIT = 1, + FT_GLYPH_BBOX_TRUNCATE = 2, + FT_GLYPH_BBOX_PIXELS = 3 + + } FT_Glyph_BBox_Mode; + + + /* these constants are deprecated; use the corresponding */ + /* `FT_Glyph_BBox_Mode' values instead */ +#define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED +#define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS +#define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT +#define ft_glyph_bbox_truncate FT_GLYPH_BBOX_TRUNCATE +#define ft_glyph_bbox_pixels FT_GLYPH_BBOX_PIXELS + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Get_CBox */ + /* */ + /* <Description> */ + /* Return a glyph's `control box'. The control box encloses all the */ + /* outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* that contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component, which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the source glyph object. */ + /* */ + /* mode :: The mode that indicates how to interpret the returned */ + /* bounding box values. */ + /* */ + /* <Output> */ + /* acbox :: The glyph coordinate bounding box. Coordinates are */ + /* expressed in 1/64th of pixels if it is grid-fitted. */ + /* */ + /* <Note> */ + /* Coordinates are relative to the glyph origin, using the y~upwards */ + /* convention. */ + /* */ + /* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' */ + /* must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font */ + /* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS */ + /* is another name for this constant. */ + /* */ + /* If the font is tricky and the glyph has been loaded with */ + /* @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get */ + /* reasonable values for the CBox it is necessary to load the glyph */ + /* at a large ppem value (so that the hinting instructions can */ + /* properly shift and scale the subglyphs), then extracting the CBox, */ + /* which can be eventually converted back to font units. */ + /* */ + /* Note that the maximum coordinates are exclusive, which means that */ + /* one can compute the width and height of the glyph image (be it in */ + /* integer or 26.6 pixels) as: */ + /* */ + /* { */ + /* width = bbox.xMax - bbox.xMin; */ + /* height = bbox.yMax - bbox.yMin; */ + /* } */ + /* */ + /* Note also that for 26.6 coordinates, if `bbox_mode' is set to */ + /* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, */ + /* which corresponds to: */ + /* */ + /* { */ + /* bbox.xMin = FLOOR(bbox.xMin); */ + /* bbox.yMin = FLOOR(bbox.yMin); */ + /* bbox.xMax = CEILING(bbox.xMax); */ + /* bbox.yMax = CEILING(bbox.yMax); */ + /* } */ + /* */ + /* To get the bbox in pixel coordinates, set `bbox_mode' to */ + /* @FT_GLYPH_BBOX_TRUNCATE. */ + /* */ + /* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' */ + /* to @FT_GLYPH_BBOX_PIXELS. */ + /* */ + FT_EXPORT( void ) + FT_Glyph_Get_CBox( FT_Glyph glyph, + FT_UInt bbox_mode, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_To_Bitmap */ + /* */ + /* <Description> */ + /* Convert a given glyph object to a bitmap glyph object. */ + /* */ + /* <InOut> */ + /* the_glyph :: A pointer to a handle to the target glyph. */ + /* */ + /* <Input> */ + /* render_mode :: An enumeration that describes how the data is */ + /* rendered. */ + /* */ + /* origin :: A pointer to a vector used to translate the glyph */ + /* image before rendering. Can be~0 (if no */ + /* translation). The origin is expressed in */ + /* 26.6 pixels. */ + /* */ + /* destroy :: A boolean that indicates that the original glyph */ + /* image should be destroyed by this function. It is */ + /* never destroyed in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function does nothing if the glyph format isn't scalable. */ + /* */ + /* The glyph image is translated with the `origin' vector before */ + /* rendering. */ + /* */ + /* The first parameter is a pointer to an @FT_Glyph handle, that will */ + /* be _replaced_ by this function (with newly allocated data). */ + /* Typically, you would use (omitting error handling): */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyph; */ + /* FT_BitmapGlyph glyph_bitmap; */ + /* */ + /* */ + /* // load glyph */ + /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); */ + /* */ + /* // extract glyph image */ + /* error = FT_Get_Glyph( face->glyph, &glyph ); */ + /* */ + /* // convert to a bitmap (default render mode + destroying old) */ + /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ + /* { */ + /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, */ + /* 0, 1 ); */ + /* if ( error ) // `glyph' unchanged */ + /* ... */ + /* } */ + /* */ + /* // access bitmap content by typecasting */ + /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ + /* */ + /* // do funny stuff with it, like blitting/drawing */ + /* ... */ + /* */ + /* // discard glyph image (bitmap or not) */ + /* FT_Done_Glyph( glyph ); */ + /* } */ + /* */ + /* */ + /* Here another example, again without error handling: */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyphs[MAX_GLYPHS] */ + /* */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) || */ + /* FT_Get_Glyph ( face->glyph, &glyph[idx] ); */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* { */ + /* FT_Glyph bitmap = glyphs[idx]; */ + /* */ + /* */ + /* ... */ + /* */ + /* // after this call, `bitmap' no longer points into */ + /* // the `glyphs' array (and the old value isn't destroyed) */ + /* FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 ); */ + /* */ + /* ... */ + /* */ + /* FT_Done_Glyph( bitmap ); */ + /* } */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* FT_Done_Glyph( glyphs[idx] ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, + FT_Render_Mode render_mode, + FT_Vector* origin, + FT_Bool destroy ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Glyph */ + /* */ + /* <Description> */ + /* Destroy a given glyph. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + FT_EXPORT( void ) + FT_Done_Glyph( FT_Glyph glyph ); + + /* */ + + + /* other helpful functions */ + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Multiply */ + /* */ + /* <Description> */ + /* Perform the matrix operation `b = a*b'. */ + /* */ + /* <Input> */ + /* a :: A pointer to matrix `a'. */ + /* */ + /* <InOut> */ + /* b :: A pointer to matrix `b'. */ + /* */ + /* <Note> */ + /* The result is undefined if either `a' or `b' is zero. */ + /* */ + FT_EXPORT( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix* b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Invert */ + /* */ + /* <Description> */ + /* Invert a 2x2 matrix. Return an error if it can't be inverted. */ + /* */ + /* <InOut> */ + /* matrix :: A pointer to the target matrix. Remains untouched in */ + /* case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ); + + /* */ + + +FT_END_HEADER + +#endif /* FTGLYPH_H_ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftgxval.h b/builddir/freetype-2.7.0/include/freetype/ftgxval.h new file mode 100644 index 0000000..a58e86a --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftgxval.h @@ -0,0 +1,357 @@ +/***************************************************************************/ +/* */ +/* ftgxval.h */ +/* */ +/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ +/* */ +/* Copyright 2004-2016 by */ +/* Masatake YAMATO, Redhat K.K, */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef FTGXVAL_H_ +#define FTGXVAL_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* gx_validation */ + /* */ + /* <Title> */ + /* TrueTypeGX/AAT Validation */ + /* */ + /* <Abstract> */ + /* An API to validate TrueTypeGX/AAT tables. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions to validate */ + /* some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, */ + /* trak, prop, lcar). */ + /* */ + /* <Order> */ + /* FT_TrueTypeGX_Validate */ + /* FT_TrueTypeGX_Free */ + /* */ + /* FT_ClassicKern_Validate */ + /* FT_ClassicKern_Free */ + /* */ + /* FT_VALIDATE_GX_LENGTH */ + /* FT_VALIDATE_GXXXX */ + /* FT_VALIDATE_CKERNXXX */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* */ + /* Warning: Use FT_VALIDATE_XXX to validate a table. */ + /* Following definitions are for gxvalid developers. */ + /* */ + /* */ + /*************************************************************************/ + +#define FT_VALIDATE_feat_INDEX 0 +#define FT_VALIDATE_mort_INDEX 1 +#define FT_VALIDATE_morx_INDEX 2 +#define FT_VALIDATE_bsln_INDEX 3 +#define FT_VALIDATE_just_INDEX 4 +#define FT_VALIDATE_kern_INDEX 5 +#define FT_VALIDATE_opbd_INDEX 6 +#define FT_VALIDATE_trak_INDEX 7 +#define FT_VALIDATE_prop_INDEX 8 +#define FT_VALIDATE_lcar_INDEX 9 +#define FT_VALIDATE_GX_LAST_INDEX FT_VALIDATE_lcar_INDEX + + + /************************************************************************* + * + * @macro: + * FT_VALIDATE_GX_LENGTH + * + * @description: + * The number of tables checked in this module. Use it as a parameter + * for the `table-length' argument of function @FT_TrueTypeGX_Validate. + */ +#define FT_VALIDATE_GX_LENGTH (FT_VALIDATE_GX_LAST_INDEX + 1) + + /* */ + + /* Up to 0x1000 is used by otvalid. + Ox2xxx is reserved for feature OT extension. */ +#define FT_VALIDATE_GX_START 0x4000 +#define FT_VALIDATE_GX_BITFIELD( tag ) \ + ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX ) + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_GXXXX + * + * @description: + * A list of bit-field constants used with @FT_TrueTypeGX_Validate to + * indicate which TrueTypeGX/AAT Type tables should be validated. + * + * @values: + * FT_VALIDATE_feat :: + * Validate `feat' table. + * + * FT_VALIDATE_mort :: + * Validate `mort' table. + * + * FT_VALIDATE_morx :: + * Validate `morx' table. + * + * FT_VALIDATE_bsln :: + * Validate `bsln' table. + * + * FT_VALIDATE_just :: + * Validate `just' table. + * + * FT_VALIDATE_kern :: + * Validate `kern' table. + * + * FT_VALIDATE_opbd :: + * Validate `opbd' table. + * + * FT_VALIDATE_trak :: + * Validate `trak' table. + * + * FT_VALIDATE_prop :: + * Validate `prop' table. + * + * FT_VALIDATE_lcar :: + * Validate `lcar' table. + * + * FT_VALIDATE_GX :: + * Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern, + * opbd, trak, prop and lcar). + * + */ + +#define FT_VALIDATE_feat FT_VALIDATE_GX_BITFIELD( feat ) +#define FT_VALIDATE_mort FT_VALIDATE_GX_BITFIELD( mort ) +#define FT_VALIDATE_morx FT_VALIDATE_GX_BITFIELD( morx ) +#define FT_VALIDATE_bsln FT_VALIDATE_GX_BITFIELD( bsln ) +#define FT_VALIDATE_just FT_VALIDATE_GX_BITFIELD( just ) +#define FT_VALIDATE_kern FT_VALIDATE_GX_BITFIELD( kern ) +#define FT_VALIDATE_opbd FT_VALIDATE_GX_BITFIELD( opbd ) +#define FT_VALIDATE_trak FT_VALIDATE_GX_BITFIELD( trak ) +#define FT_VALIDATE_prop FT_VALIDATE_GX_BITFIELD( prop ) +#define FT_VALIDATE_lcar FT_VALIDATE_GX_BITFIELD( lcar ) + +#define FT_VALIDATE_GX ( FT_VALIDATE_feat | \ + FT_VALIDATE_mort | \ + FT_VALIDATE_morx | \ + FT_VALIDATE_bsln | \ + FT_VALIDATE_just | \ + FT_VALIDATE_kern | \ + FT_VALIDATE_opbd | \ + FT_VALIDATE_trak | \ + FT_VALIDATE_prop | \ + FT_VALIDATE_lcar ) + + + /********************************************************************** + * + * @function: + * FT_TrueTypeGX_Validate + * + * @description: + * Validate various TrueTypeGX tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library that + * actually does the text layout can access those tables without + * error checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field that specifies the tables to be validated. See + * @FT_VALIDATE_GXXXX for possible values. + * + * table_length :: + * The size of the `tables' array. Normally, @FT_VALIDATE_GX_LENGTH + * should be passed. + * + * @output: + * tables :: + * The array where all validated sfnt tables are stored. + * The array itself must be allocated by a client. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with TrueTypeGX fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the buffers pointed to by + * each `tables' element, by calling @FT_TrueTypeGX_Free. A NULL value + * indicates that the table either doesn't exist in the font, the + * application hasn't asked for validation, or the validator doesn't have + * the ability to validate the sfnt table. + */ + FT_EXPORT( FT_Error ) + FT_TrueTypeGX_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_length ); + + + /********************************************************************** + * + * @function: + * FT_TrueTypeGX_Free + * + * @description: + * Free the buffer allocated by TrueTypeGX validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer allocated by + * @FT_TrueTypeGX_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_TrueTypeGX_Validate only. + */ + FT_EXPORT( void ) + FT_TrueTypeGX_Free( FT_Face face, + FT_Bytes table ); + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_CKERNXXX + * + * @description: + * A list of bit-field constants used with @FT_ClassicKern_Validate + * to indicate the classic kern dialect or dialects. If the selected + * type doesn't fit, @FT_ClassicKern_Validate regards the table as + * invalid. + * + * @values: + * FT_VALIDATE_MS :: + * Handle the `kern' table as a classic Microsoft kern table. + * + * FT_VALIDATE_APPLE :: + * Handle the `kern' table as a classic Apple kern table. + * + * FT_VALIDATE_CKERN :: + * Handle the `kern' as either classic Apple or Microsoft kern table. + */ +#define FT_VALIDATE_MS ( FT_VALIDATE_GX_START << 0 ) +#define FT_VALIDATE_APPLE ( FT_VALIDATE_GX_START << 1 ) + +#define FT_VALIDATE_CKERN ( FT_VALIDATE_MS | FT_VALIDATE_APPLE ) + + + /********************************************************************** + * + * @function: + * FT_ClassicKern_Validate + * + * @description: + * Validate classic (16-bit format) kern table to assure that the offsets + * and indices are valid. The idea is that a higher-level library that + * actually does the text layout can access those tables without error + * checking (which can be quite time consuming). + * + * The `kern' table validator in @FT_TrueTypeGX_Validate deals with both + * the new 32-bit format and the classic 16-bit format, while + * FT_ClassicKern_Validate only supports the classic 16-bit format. + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field that specifies the dialect to be validated. See + * @FT_VALIDATE_CKERNXXX for possible values. + * + * @output: + * ckern_table :: + * A pointer to the kern table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * After use, the application should deallocate the buffers pointed to by + * `ckern_table', by calling @FT_ClassicKern_Free. A NULL value + * indicates that the table doesn't exist in the font. + */ + FT_EXPORT( FT_Error ) + FT_ClassicKern_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *ckern_table ); + + + /********************************************************************** + * + * @function: + * FT_ClassicKern_Free + * + * @description: + * Free the buffer allocated by classic Kern validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_ClassicKern_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_ClassicKern_Validate only. + */ + FT_EXPORT( void ) + FT_ClassicKern_Free( FT_Face face, + FT_Bytes table ); + + /* */ + + +FT_END_HEADER + +#endif /* FTGXVAL_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftgzip.h b/builddir/freetype-2.7.0/include/freetype/ftgzip.h new file mode 100644 index 0000000..3932ce6 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftgzip.h @@ -0,0 +1,148 @@ +/***************************************************************************/ +/* */ +/* ftgzip.h */ +/* */ +/* Gzip-compressed stream support. */ +/* */ +/* Copyright 2002-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTGZIP_H_ +#define FTGZIP_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* gzip */ + /* */ + /* <Title> */ + /* GZIP Streams */ + /* */ + /* <Abstract> */ + /* Using gzip-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Gzip-specific functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************ + * + * @function: + * FT_Stream_OpenGzip + * + * @description: + * Open a new stream to parse gzip-compressed font files. This is + * mainly used to support the compressed `*.pcf.gz' fonts that come + * with XFree86. + * + * @input: + * stream :: + * The target embedding stream. + * + * source :: + * The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream. + * + * In certain builds of the library, gzip compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a gzipped stream from + * it and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with zlib support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ); + + + /************************************************************************ + * + * @function: + * FT_Gzip_Uncompress + * + * @description: + * Decompress a zipped input buffer into an output buffer. This function + * is modeled after zlib's `uncompress' function. + * + * @input: + * memory :: + * A FreeType memory handle. + * + * input :: + * The input buffer. + * + * input_len :: + * The length of the input buffer. + * + * @output: + * output:: + * The output buffer. + * + * @inout: + * output_len :: + * Before calling the function, this is the total size of the output + * buffer, which must be large enough to hold the entire uncompressed + * data (so the size of the uncompressed data must be known in + * advance). After calling the function, `output_len' is the size of + * the used data in `output'. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with zlib support. + */ + FT_EXPORT( FT_Error ) + FT_Gzip_Uncompress( FT_Memory memory, + FT_Byte* output, + FT_ULong* output_len, + const FT_Byte* input, + FT_ULong input_len ); + + /* */ + + +FT_END_HEADER + +#endif /* FTGZIP_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftimage.h b/builddir/freetype-2.7.0/include/freetype/ftimage.h new file mode 100644 index 0000000..4f86c56 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftimage.h @@ -0,0 +1,1204 @@ +/***************************************************************************/ +/* */ +/* ftimage.h */ +/* */ +/* FreeType glyph image formats and default raster interface */ +/* (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Note: A `raster' is simply a scan-line converter, used to render */ + /* FT_Outlines into FT_Bitmaps. */ + /* */ + /*************************************************************************/ + + +#ifndef FTIMAGE_H_ +#define FTIMAGE_H_ + + + /* STANDALONE_ is from ftgrays.c */ +#ifndef STANDALONE_ +#include <ft2build.h> +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pos */ + /* */ + /* <Description> */ + /* The type FT_Pos is used to store vectorial coordinates. Depending */ + /* on the context, these can represent distances in integer font */ + /* units, or 16.16, or 26.6 fixed-point pixel coordinates. */ + /* */ + typedef signed long FT_Pos; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Vector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector; coordinates are of */ + /* the FT_Pos type. */ + /* */ + /* <Fields> */ + /* x :: The horizontal coordinate. */ + /* y :: The vertical coordinate. */ + /* */ + typedef struct FT_Vector_ + { + FT_Pos x; + FT_Pos y; + + } FT_Vector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BBox */ + /* */ + /* <Description> */ + /* A structure used to hold an outline's bounding box, i.e., the */ + /* coordinates of its extrema in the horizontal and vertical */ + /* directions. */ + /* */ + /* <Fields> */ + /* xMin :: The horizontal minimum (left-most). */ + /* */ + /* yMin :: The vertical minimum (bottom-most). */ + /* */ + /* xMax :: The horizontal maximum (right-most). */ + /* */ + /* yMax :: The vertical maximum (top-most). */ + /* */ + /* <Note> */ + /* The bounding box is specified with the coordinates of the lower */ + /* left and the upper right corner. In PostScript, those values are */ + /* often called (llx,lly) and (urx,ury), respectively. */ + /* */ + /* If `yMin' is negative, this value gives the glyph's descender. */ + /* Otherwise, the glyph doesn't descend below the baseline. */ + /* Similarly, if `ymax' is positive, this value gives the glyph's */ + /* ascender. */ + /* */ + /* `xMin' gives the horizontal distance from the glyph's origin to */ + /* the left edge of the glyph's bounding box. If `xMin' is negative, */ + /* the glyph extends to the left of the origin. */ + /* */ + typedef struct FT_BBox_ + { + FT_Pos xMin, yMin; + FT_Pos xMax, yMax; + + } FT_BBox; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Pixel_Mode */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of pixels in a */ + /* given bitmap. Note that additional formats may be added in the */ + /* future. */ + /* */ + /* <Values> */ + /* FT_PIXEL_MODE_NONE :: */ + /* Value~0 is reserved. */ + /* */ + /* FT_PIXEL_MODE_MONO :: */ + /* A monochrome bitmap, using 1~bit per pixel. Note that pixels */ + /* are stored in most-significant order (MSB), which means that */ + /* the left-most pixel in a byte has value 128. */ + /* */ + /* FT_PIXEL_MODE_GRAY :: */ + /* An 8-bit bitmap, generally used to represent anti-aliased glyph */ + /* images. Each pixel is stored in one byte. Note that the number */ + /* of `gray' levels is stored in the `num_grays' field of the */ + /* @FT_Bitmap structure (it generally is 256). */ + /* */ + /* FT_PIXEL_MODE_GRAY2 :: */ + /* A 2-bit per pixel bitmap, used to represent embedded */ + /* anti-aliased bitmaps in font files according to the OpenType */ + /* specification. We haven't found a single font using this */ + /* format, however. */ + /* */ + /* FT_PIXEL_MODE_GRAY4 :: */ + /* A 4-bit per pixel bitmap, representing embedded anti-aliased */ + /* bitmaps in font files according to the OpenType specification. */ + /* We haven't found a single font using this format, however. */ + /* */ + /* FT_PIXEL_MODE_LCD :: */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on LCD displays; the bitmap is three times */ + /* wider than the original glyph image. See also */ + /* @FT_RENDER_MODE_LCD. */ + /* */ + /* FT_PIXEL_MODE_LCD_V :: */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on rotated LCD displays; the bitmap is three */ + /* times taller than the original glyph image. See also */ + /* @FT_RENDER_MODE_LCD_V. */ + /* */ + /* FT_PIXEL_MODE_BGRA :: */ + /* An image with four 8-bit channels per pixel, representing a */ + /* color image (such as emoticons) with alpha channel. For each */ + /* pixel, the format is BGRA, which means, the blue channel comes */ + /* first in memory. The color channels are pre-multiplied and in */ + /* the sRGB colorspace. For example, full red at half-translucent */ + /* opacity will be represented as `00,00,80,80', not `00,00,FF,80'. */ + /* See also @FT_LOAD_COLOR. */ + /* */ + typedef enum FT_Pixel_Mode_ + { + FT_PIXEL_MODE_NONE = 0, + FT_PIXEL_MODE_MONO, + FT_PIXEL_MODE_GRAY, + FT_PIXEL_MODE_GRAY2, + FT_PIXEL_MODE_GRAY4, + FT_PIXEL_MODE_LCD, + FT_PIXEL_MODE_LCD_V, + FT_PIXEL_MODE_BGRA, + + FT_PIXEL_MODE_MAX /* do not remove */ + + } FT_Pixel_Mode; + + + /* these constants are deprecated; use the corresponding `FT_Pixel_Mode' */ + /* values instead. */ +#define ft_pixel_mode_none FT_PIXEL_MODE_NONE +#define ft_pixel_mode_mono FT_PIXEL_MODE_MONO +#define ft_pixel_mode_grays FT_PIXEL_MODE_GRAY +#define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2 +#define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap */ + /* */ + /* <Description> */ + /* A structure used to describe a bitmap or pixmap to the raster. */ + /* Note that we now manage pixmaps of various depths through the */ + /* `pixel_mode' field. */ + /* */ + /* <Fields> */ + /* rows :: The number of bitmap rows. */ + /* */ + /* width :: The number of pixels in bitmap row. */ + /* */ + /* pitch :: The pitch's absolute value is the number of bytes */ + /* taken by one bitmap row, including padding. */ + /* However, the pitch is positive when the bitmap has */ + /* a `down' flow, and negative when it has an `up' */ + /* flow. In all cases, the pitch is an offset to add */ + /* to a bitmap pointer in order to go down one row. */ + /* */ + /* Note that `padding' means the alignment of a */ + /* bitmap to a byte border, and FreeType functions */ + /* normally align to the smallest possible integer */ + /* value. */ + /* */ + /* For the B/W rasterizer, `pitch' is always an even */ + /* number. */ + /* */ + /* To change the pitch of a bitmap (say, to make it a */ + /* multiple of 4), use @FT_Bitmap_Convert. */ + /* Alternatively, you might use callback functions to */ + /* directly render to the application's surface; see */ + /* the file `example2.cpp' in the tutorial for a */ + /* demonstration. */ + /* */ + /* buffer :: A typeless pointer to the bitmap buffer. This */ + /* value should be aligned on 32-bit boundaries in */ + /* most cases. */ + /* */ + /* num_grays :: This field is only used with */ + /* @FT_PIXEL_MODE_GRAY; it gives the number of gray */ + /* levels used in the bitmap. */ + /* */ + /* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. */ + /* See @FT_Pixel_Mode for possible values. */ + /* */ + /* palette_mode :: This field is intended for paletted pixel modes; */ + /* it indicates how the palette is stored. Not */ + /* used currently. */ + /* */ + /* palette :: A typeless pointer to the bitmap palette; this */ + /* field is intended for paletted pixel modes. Not */ + /* used currently. */ + /* */ + typedef struct FT_Bitmap_ + { + unsigned int rows; + unsigned int width; + int pitch; + unsigned char* buffer; + unsigned short num_grays; + unsigned char pixel_mode; + unsigned char palette_mode; + void* palette; + + } FT_Bitmap; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline */ + /* */ + /* <Description> */ + /* This structure is used to describe an outline to the scan-line */ + /* converter. */ + /* */ + /* <Fields> */ + /* n_contours :: The number of contours in the outline. */ + /* */ + /* n_points :: The number of points in the outline. */ + /* */ + /* points :: A pointer to an array of `n_points' @FT_Vector */ + /* elements, giving the outline's point coordinates. */ + /* */ + /* tags :: A pointer to an array of `n_points' chars, giving */ + /* each outline point's type. */ + /* */ + /* If bit~0 is unset, the point is `off' the curve, */ + /* i.e., a Bézier control point, while it is `on' if */ + /* set. */ + /* */ + /* Bit~1 is meaningful for `off' points only. If set, */ + /* it indicates a third-order Bézier arc control point; */ + /* and a second-order control point if unset. */ + /* */ + /* If bit~2 is set, bits 5-7 contain the drop-out mode */ + /* (as defined in the OpenType specification; the value */ + /* is the same as the argument to the SCANMODE */ + /* instruction). */ + /* */ + /* Bits 3 and~4 are reserved for internal purposes. */ + /* */ + /* contours :: An array of `n_contours' shorts, giving the end */ + /* point of each contour within the outline. For */ + /* example, the first contour is defined by the points */ + /* `0' to `contours[0]', the second one is defined by */ + /* the points `contours[0]+1' to `contours[1]', etc. */ + /* */ + /* flags :: A set of bit flags used to characterize the outline */ + /* and give hints to the scan-converter and hinter on */ + /* how to convert/grid-fit it. See @FT_OUTLINE_XXX. */ + /* */ + /* <Note> */ + /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ + /* first point of each contour. The drop-out mode as given with */ + /* @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and */ + /* @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden. */ + /* */ + typedef struct FT_Outline_ + { + short n_contours; /* number of contours in glyph */ + short n_points; /* number of points in the glyph */ + + FT_Vector* points; /* the outline's points */ + char* tags; /* the points flags */ + short* contours; /* the contour end points */ + + int flags; /* outline masks */ + + } FT_Outline; + + /* */ + + /* Following limits must be consistent with */ + /* FT_Outline.{n_contours,n_points} */ +#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX +#define FT_OUTLINE_POINTS_MAX SHRT_MAX + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_OUTLINE_XXX */ + /* */ + /* <Description> */ + /* A list of bit-field constants use for the flags in an outline's */ + /* `flags' field. */ + /* */ + /* <Values> */ + /* FT_OUTLINE_NONE :: */ + /* Value~0 is reserved. */ + /* */ + /* FT_OUTLINE_OWNER :: */ + /* If set, this flag indicates that the outline's field arrays */ + /* (i.e., `points', `flags', and `contours') are `owned' by the */ + /* outline object, and should thus be freed when it is destroyed. */ + /* */ + /* FT_OUTLINE_EVEN_ODD_FILL :: */ + /* By default, outlines are filled using the non-zero winding rule. */ + /* If set to 1, the outline will be filled using the even-odd fill */ + /* rule (only works with the smooth rasterizer). */ + /* */ + /* FT_OUTLINE_REVERSE_FILL :: */ + /* By default, outside contours of an outline are oriented in */ + /* clock-wise direction, as defined in the TrueType specification. */ + /* This flag is set if the outline uses the opposite direction */ + /* (typically for Type~1 fonts). This flag is ignored by the scan */ + /* converter. */ + /* */ + /* FT_OUTLINE_IGNORE_DROPOUTS :: */ + /* By default, the scan converter will try to detect drop-outs in */ + /* an outline and correct the glyph bitmap to ensure consistent */ + /* shape continuity. If set, this flag hints the scan-line */ + /* converter to ignore such cases. See below for more information. */ + /* */ + /* FT_OUTLINE_SMART_DROPOUTS :: */ + /* Select smart dropout control. If unset, use simple dropout */ + /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See */ + /* below for more information. */ + /* */ + /* FT_OUTLINE_INCLUDE_STUBS :: */ + /* If set, turn pixels on for `stubs', otherwise exclude them. */ + /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for */ + /* more information. */ + /* */ + /* FT_OUTLINE_HIGH_PRECISION :: */ + /* This flag indicates that the scan-line converter should try to */ + /* convert this outline to bitmaps with the highest possible */ + /* quality. It is typically set for small character sizes. Note */ + /* that this is only a hint that might be completely ignored by a */ + /* given scan-converter. */ + /* */ + /* FT_OUTLINE_SINGLE_PASS :: */ + /* This flag is set to force a given scan-converter to only use a */ + /* single pass over the outline to render a bitmap glyph image. */ + /* Normally, it is set for very large character sizes. It is only */ + /* a hint that might be completely ignored by a given */ + /* scan-converter. */ + /* */ + /* <Note> */ + /* The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */ + /* and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth */ + /* rasterizer. */ + /* */ + /* There exists a second mechanism to pass the drop-out mode to the */ + /* B/W rasterizer; see the `tags' field in @FT_Outline. */ + /* */ + /* Please refer to the description of the `SCANTYPE' instruction in */ + /* the OpenType specification (in file `ttinst1.doc') how simple */ + /* drop-outs, smart drop-outs, and stubs are defined. */ + /* */ +#define FT_OUTLINE_NONE 0x0 +#define FT_OUTLINE_OWNER 0x1 +#define FT_OUTLINE_EVEN_ODD_FILL 0x2 +#define FT_OUTLINE_REVERSE_FILL 0x4 +#define FT_OUTLINE_IGNORE_DROPOUTS 0x8 +#define FT_OUTLINE_SMART_DROPOUTS 0x10 +#define FT_OUTLINE_INCLUDE_STUBS 0x20 + +#define FT_OUTLINE_HIGH_PRECISION 0x100 +#define FT_OUTLINE_SINGLE_PASS 0x200 + + + /* these constants are deprecated; use the corresponding */ + /* `FT_OUTLINE_XXX' values instead */ +#define ft_outline_none FT_OUTLINE_NONE +#define ft_outline_owner FT_OUTLINE_OWNER +#define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL +#define ft_outline_reverse_fill FT_OUTLINE_REVERSE_FILL +#define ft_outline_ignore_dropouts FT_OUTLINE_IGNORE_DROPOUTS +#define ft_outline_high_precision FT_OUTLINE_HIGH_PRECISION +#define ft_outline_single_pass FT_OUTLINE_SINGLE_PASS + + /* */ + +#define FT_CURVE_TAG( flag ) ( flag & 3 ) + +#define FT_CURVE_TAG_ON 1 +#define FT_CURVE_TAG_CONIC 0 +#define FT_CURVE_TAG_CUBIC 2 + +#define FT_CURVE_TAG_HAS_SCANMODE 4 + +#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ + +#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ + FT_CURVE_TAG_TOUCH_Y ) + +#define FT_Curve_Tag_On FT_CURVE_TAG_ON +#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC +#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC +#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X +#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_MoveToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `move */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `move to' is emitted to start a new contour in an outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `move to'. */ + /* */ + /* user :: A typeless pointer, which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_MoveToFunc)( const FT_Vector* to, + void* user ); + +#define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_LineToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `line */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `line to' is emitted to indicate a segment in the outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `line to'. */ + /* */ + /* user :: A typeless pointer, which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_LineToFunc)( const FT_Vector* to, + void* user ); + +#define FT_Outline_LineTo_Func FT_Outline_LineToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_ConicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `conic */ + /* to' function during outline walking or decomposition. */ + /* */ + /* A `conic to' is emitted to indicate a second-order Bézier arc in */ + /* the outline. */ + /* */ + /* <Input> */ + /* control :: An intermediate control point between the last position */ + /* and the new target in `to'. */ + /* */ + /* to :: A pointer to the target end point of the conic arc. */ + /* */ + /* user :: A typeless pointer, which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_ConicToFunc)( const FT_Vector* control, + const FT_Vector* to, + void* user ); + +#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_CubicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `cubic */ + /* to' function during outline walking or decomposition. */ + /* */ + /* A `cubic to' is emitted to indicate a third-order Bézier arc. */ + /* */ + /* <Input> */ + /* control1 :: A pointer to the first Bézier control point. */ + /* */ + /* control2 :: A pointer to the second Bézier control point. */ + /* */ + /* to :: A pointer to the target end point. */ + /* */ + /* user :: A typeless pointer, which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_CubicToFunc)( const FT_Vector* control1, + const FT_Vector* control2, + const FT_Vector* to, + void* user ); + +#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline_Funcs */ + /* */ + /* <Description> */ + /* A structure to hold various function pointers used during outline */ + /* decomposition in order to emit segments, conic, and cubic Béziers. */ + /* */ + /* <Fields> */ + /* move_to :: The `move to' emitter. */ + /* */ + /* line_to :: The segment emitter. */ + /* */ + /* conic_to :: The second-order Bézier arc emitter. */ + /* */ + /* cubic_to :: The third-order Bézier arc emitter. */ + /* */ + /* shift :: The shift that is applied to coordinates before they */ + /* are sent to the emitter. */ + /* */ + /* delta :: The delta that is applied to coordinates before they */ + /* are sent to the emitter, but after the shift. */ + /* */ + /* <Note> */ + /* The point coordinates sent to the emitters are the transformed */ + /* version of the original coordinates (this is important for high */ + /* accuracy during scan-conversion). The transformation is simple: */ + /* */ + /* { */ + /* x' = (x << shift) - delta */ + /* y' = (x << shift) - delta */ + /* } */ + /* */ + /* Set the values of `shift' and `delta' to~0 to get the original */ + /* point coordinates. */ + /* */ + typedef struct FT_Outline_Funcs_ + { + FT_Outline_MoveToFunc move_to; + FT_Outline_LineToFunc line_to; + FT_Outline_ConicToFunc conic_to; + FT_Outline_CubicToFunc cubic_to; + + int shift; + FT_Pos delta; + + } FT_Outline_Funcs; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_IMAGE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags to an unsigned long type. */ + /* */ + /* <Note> */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* { */ + /* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value */ + /* } */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ +#ifndef FT_IMAGE_TAG +#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \ + value = ( ( (unsigned long)_x1 << 24 ) | \ + ( (unsigned long)_x2 << 16 ) | \ + ( (unsigned long)_x3 << 8 ) | \ + (unsigned long)_x4 ) +#endif /* FT_IMAGE_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Glyph_Format */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of a given glyph */ + /* image. Note that this version of FreeType only supports two image */ + /* formats, even though future font drivers will be able to register */ + /* their own format. */ + /* */ + /* <Values> */ + /* FT_GLYPH_FORMAT_NONE :: */ + /* The value~0 is reserved. */ + /* */ + /* FT_GLYPH_FORMAT_COMPOSITE :: */ + /* The glyph image is a composite of several other images. This */ + /* format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to */ + /* report compound glyphs (like accented characters). */ + /* */ + /* FT_GLYPH_FORMAT_BITMAP :: */ + /* The glyph image is a bitmap, and can be described as an */ + /* @FT_Bitmap. You generally need to access the `bitmap' field of */ + /* the @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_OUTLINE :: */ + /* The glyph image is a vectorial outline made of line segments */ + /* and Bézier arcs; it can be described as an @FT_Outline; you */ + /* generally want to access the `outline' field of the */ + /* @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_PLOTTER :: */ + /* The glyph image is a vectorial path with no inside and outside */ + /* contours. Some Type~1 fonts, like those in the Hershey family, */ + /* contain glyphs in this format. These are described as */ + /* @FT_Outline, but FreeType isn't currently capable of rendering */ + /* them correctly. */ + /* */ + typedef enum FT_Glyph_Format_ + { + FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ), + + FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP, 'b', 'i', 't', 's' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE, 'o', 'u', 't', 'l' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' ) + + } FT_Glyph_Format; + + + /* these constants are deprecated; use the corresponding */ + /* `FT_Glyph_Format' values instead. */ +#define ft_glyph_format_none FT_GLYPH_FORMAT_NONE +#define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE +#define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP +#define ft_glyph_format_outline FT_GLYPH_FORMAT_OUTLINE +#define ft_glyph_format_plotter FT_GLYPH_FORMAT_PLOTTER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** R A S T E R D E F I N I T I O N S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* A raster is a scan converter, in charge of rendering an outline into */ + /* a bitmap. This section contains the public API for rasters. */ + /* */ + /* Note that in FreeType 2, all rasters are now encapsulated within */ + /* specific modules called `renderers'. See `ftrender.h' for more */ + /* details on renderers. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* raster */ + /* */ + /* <Title> */ + /* Scanline Converter */ + /* */ + /* <Abstract> */ + /* How vectorial outlines are converted into bitmaps and pixmaps. */ + /* */ + /* <Description> */ + /* This section contains technical definitions. */ + /* */ + /* <Order> */ + /* FT_Raster */ + /* FT_Span */ + /* FT_SpanFunc */ + /* */ + /* FT_Raster_Params */ + /* FT_RASTER_FLAG_XXX */ + /* */ + /* FT_Raster_NewFunc */ + /* FT_Raster_DoneFunc */ + /* FT_Raster_ResetFunc */ + /* FT_Raster_SetModeFunc */ + /* FT_Raster_RenderFunc */ + /* FT_Raster_Funcs */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Raster */ + /* */ + /* <Description> */ + /* An opaque handle (pointer) to a raster object. Each object can be */ + /* used independently to convert an outline into a bitmap or pixmap. */ + /* */ + typedef struct FT_RasterRec_* FT_Raster; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Span */ + /* */ + /* <Description> */ + /* A structure used to model a single span of gray pixels when */ + /* rendering an anti-aliased bitmap. */ + /* */ + /* <Fields> */ + /* x :: The span's horizontal start position. */ + /* */ + /* len :: The span's length in pixels. */ + /* */ + /* coverage :: The span color/coverage, ranging from 0 (background) */ + /* to 255 (foreground). */ + /* */ + /* <Note> */ + /* This structure is used by the span drawing callback type named */ + /* @FT_SpanFunc that takes the y~coordinate of the span as a */ + /* parameter. */ + /* */ + /* The coverage value is always between 0 and 255. If you want less */ + /* gray values, the callback function has to reduce them. */ + /* */ + typedef struct FT_Span_ + { + short x; + unsigned short len; + unsigned char coverage; + + } FT_Span; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_SpanFunc */ + /* */ + /* <Description> */ + /* A function used as a call-back by the anti-aliased renderer in */ + /* order to let client applications draw themselves the gray pixel */ + /* spans on each scan line. */ + /* */ + /* <Input> */ + /* y :: The scanline's y~coordinate. */ + /* */ + /* count :: The number of spans to draw on this scanline. */ + /* */ + /* spans :: A table of `count' spans to draw on the scanline. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Note> */ + /* This callback allows client applications to directly render the */ + /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ + /* */ + /* This can be used to write anti-aliased outlines directly to a */ + /* given background bitmap, and even perform translucency. */ + /* */ + typedef void + (*FT_SpanFunc)( int y, + int count, + const FT_Span* spans, + void* user ); + +#define FT_Raster_Span_Func FT_SpanFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitTest_Func */ + /* */ + /* <Description> */ + /* Deprecated, unimplemented. */ + /* */ + typedef int + (*FT_Raster_BitTest_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitSet_Func */ + /* */ + /* <Description> */ + /* Deprecated, unimplemented. */ + /* */ + typedef void + (*FT_Raster_BitSet_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_RASTER_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flag constants as used in the `flags' field of a */ + /* @FT_Raster_Params structure. */ + /* */ + /* <Values> */ + /* FT_RASTER_FLAG_DEFAULT :: This value is 0. */ + /* */ + /* FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ + /* anti-aliased glyph image should be */ + /* generated. Otherwise, it will be */ + /* monochrome (1-bit). */ + /* */ + /* FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ + /* rendering. In this mode, client */ + /* applications must provide their own span */ + /* callback. This lets them directly */ + /* draw or compose over an existing bitmap. */ + /* If this bit is not set, the target */ + /* pixmap's buffer _must_ be zeroed before */ + /* rendering. */ + /* */ + /* Direct rendering is only possible with */ + /* anti-aliased glyphs. */ + /* */ + /* FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ + /* rendering mode. If set, the output will */ + /* be clipped to a box specified in the */ + /* `clip_box' field of the */ + /* @FT_Raster_Params structure. */ + /* */ + /* Note that by default, the glyph bitmap */ + /* is clipped to the target pixmap, except */ + /* in direct rendering mode where all spans */ + /* are generated if no clipping box is set. */ + /* */ +#define FT_RASTER_FLAG_DEFAULT 0x0 +#define FT_RASTER_FLAG_AA 0x1 +#define FT_RASTER_FLAG_DIRECT 0x2 +#define FT_RASTER_FLAG_CLIP 0x4 + + /* these constants are deprecated; use the corresponding */ + /* `FT_RASTER_FLAG_XXX' values instead */ +#define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT +#define ft_raster_flag_aa FT_RASTER_FLAG_AA +#define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT +#define ft_raster_flag_clip FT_RASTER_FLAG_CLIP + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Params */ + /* */ + /* <Description> */ + /* A structure to hold the arguments used by a raster's render */ + /* function. */ + /* */ + /* <Fields> */ + /* target :: The target bitmap. */ + /* */ + /* source :: A pointer to the source glyph image (e.g., an */ + /* @FT_Outline). */ + /* */ + /* flags :: The rendering flags. */ + /* */ + /* gray_spans :: The gray span drawing callback. */ + /* */ + /* black_spans :: Unused. */ + /* */ + /* bit_test :: Unused. */ + /* */ + /* bit_set :: Unused. */ + /* */ + /* user :: User-supplied data that is passed to each drawing */ + /* callback. */ + /* */ + /* clip_box :: An optional clipping box. It is only used in */ + /* direct rendering mode. Note that coordinates here */ + /* should be expressed in _integer_ pixels (and not in */ + /* 26.6 fixed-point units). */ + /* */ + /* <Note> */ + /* An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA */ + /* bit flag is set in the `flags' field, otherwise a monochrome */ + /* bitmap is generated. */ + /* */ + /* If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ + /* raster will call the `gray_spans' callback to draw gray pixel */ + /* spans. This allows direct composition over a pre-existing bitmap */ + /* through user-provided callbacks to perform the span drawing and */ + /* composition. Not supported by the monochrome rasterizer. */ + /* */ + typedef struct FT_Raster_Params_ + { + const FT_Bitmap* target; + const void* source; + int flags; + FT_SpanFunc gray_spans; + FT_SpanFunc black_spans; /* unused */ + FT_Raster_BitTest_Func bit_test; /* unused */ + FT_Raster_BitSet_Func bit_set; /* unused */ + void* user; + FT_BBox clip_box; + + } FT_Raster_Params; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_NewFunc */ + /* */ + /* <Description> */ + /* A function used to create a new raster object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory allocator. */ + /* */ + /* <Output> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `memory' parameter is a typeless pointer in order to avoid */ + /* un-wanted dependencies on the rest of the FreeType code. In */ + /* practice, it is an @FT_Memory object, i.e., a handle to the */ + /* standard FreeType memory allocator. However, this field can be */ + /* completely ignored by a given raster implementation. */ + /* */ + typedef int + (*FT_Raster_NewFunc)( void* memory, + FT_Raster* raster ); + +#define FT_Raster_New_Func FT_Raster_NewFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_DoneFunc */ + /* */ + /* <Description> */ + /* A function used to destroy a given raster object. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + typedef void + (*FT_Raster_DoneFunc)( FT_Raster raster ); + +#define FT_Raster_Done_Func FT_Raster_DoneFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_ResetFunc */ + /* */ + /* <Description> */ + /* FreeType used to provide an area of memory called the `render */ + /* pool' available to all registered rasters. This was not thread */ + /* safe however and now FreeType never allocates this pool. NULL */ + /* is always passed in as pool_base. */ + /* */ + /* This function is called each time the render pool changes, or just */ + /* after a new raster object is created. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* pool_base :: The address in memory of the render pool. */ + /* */ + /* pool_size :: The size in bytes of the render pool. */ + /* */ + /* <Note> */ + /* Rasters should ignore the render pool and rely on dynamic or stack */ + /* allocation if they want to (a handle to the memory allocator is */ + /* passed to the raster constructor). */ + /* */ + typedef void + (*FT_Raster_ResetFunc)( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ); + +#define FT_Raster_Reset_Func FT_Raster_ResetFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_SetModeFunc */ + /* */ + /* <Description> */ + /* This function is a generic facility to change modes or attributes */ + /* in a given raster. This can be used for debugging purposes, or */ + /* simply to allow implementation-specific `features' in a given */ + /* raster module. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* mode :: A 4-byte tag used to name the mode or property. */ + /* */ + /* args :: A pointer to the new mode/property to use. */ + /* */ + typedef int + (*FT_Raster_SetModeFunc)( FT_Raster raster, + unsigned long mode, + void* args ); + +#define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_RenderFunc */ + /* */ + /* <Description> */ + /* Invoke a given raster to scan-convert a given glyph image into a */ + /* target bitmap. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + /* params :: A pointer to an @FT_Raster_Params structure used to */ + /* store the rendering parameters. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + /* <Note> */ + /* The exact format of the source image depends on the raster's glyph */ + /* format defined in its @FT_Raster_Funcs structure. It can be an */ + /* @FT_Outline or anything else in order to support a large array of */ + /* glyph formats. */ + /* */ + /* Note also that the render function can fail and return a */ + /* `FT_Err_Unimplemented_Feature' error code if the raster used does */ + /* not support direct composition. */ + /* */ + /* XXX: For now, the standard raster doesn't support direct */ + /* composition but this should change for the final release (see */ + /* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ + /* for examples of distinct implementations that support direct */ + /* composition). */ + /* */ + typedef int + (*FT_Raster_RenderFunc)( FT_Raster raster, + const FT_Raster_Params* params ); + +#define FT_Raster_Render_Func FT_Raster_RenderFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Funcs */ + /* */ + /* <Description> */ + /* A structure used to describe a given raster class to the library. */ + /* */ + /* <Fields> */ + /* glyph_format :: The supported glyph format for this raster. */ + /* */ + /* raster_new :: The raster constructor. */ + /* */ + /* raster_reset :: Used to reset the render pool within the raster. */ + /* */ + /* raster_render :: A function to render a glyph into a given bitmap. */ + /* */ + /* raster_done :: The raster destructor. */ + /* */ + typedef struct FT_Raster_Funcs_ + { + FT_Glyph_Format glyph_format; + FT_Raster_NewFunc raster_new; + FT_Raster_ResetFunc raster_reset; + FT_Raster_SetModeFunc raster_set_mode; + FT_Raster_RenderFunc raster_render; + FT_Raster_DoneFunc raster_done; + + } FT_Raster_Funcs; + + /* */ + + +FT_END_HEADER + +#endif /* FTIMAGE_H_ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftincrem.h b/builddir/freetype-2.7.0/include/freetype/ftincrem.h new file mode 100644 index 0000000..46b58b7 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftincrem.h @@ -0,0 +1,354 @@ +/***************************************************************************/ +/* */ +/* ftincrem.h */ +/* */ +/* FreeType incremental loading (specification). */ +/* */ +/* Copyright 2002-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTINCREM_H_ +#define FTINCREM_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************** + * + * @section: + * incremental + * + * @title: + * Incremental Loading + * + * @abstract: + * Custom Glyph Loading. + * + * @description: + * This section contains various functions used to perform so-called + * `incremental' glyph loading. This is a mode where all glyphs loaded + * from a given @FT_Face are provided by the client application. + * + * Apart from that, all other tables are loaded normally from the font + * file. This mode is useful when FreeType is used within another + * engine, e.g., a PostScript Imaging Processor. + * + * To enable this mode, you must use @FT_Open_Face, passing an + * @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an + * @FT_Incremental_Interface value. See the comments for + * @FT_Incremental_InterfaceRec for an example. + * + */ + + + /*************************************************************************** + * + * @type: + * FT_Incremental + * + * @description: + * An opaque type describing a user-provided object used to implement + * `incremental' glyph loading within FreeType. This is used to support + * embedded fonts in certain environments (e.g., PostScript interpreters), + * where the glyph data isn't in the font file, or must be overridden by + * different values. + * + * @note: + * It is up to client applications to create and implement @FT_Incremental + * objects, as long as they provide implementations for the methods + * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc + * and @FT_Incremental_GetGlyphMetricsFunc. + * + * See the description of @FT_Incremental_InterfaceRec to understand how + * to use incremental objects with FreeType. + * + */ + typedef struct FT_IncrementalRec_* FT_Incremental; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_MetricsRec + * + * @description: + * A small structure used to contain the basic glyph metrics returned + * by the @FT_Incremental_GetGlyphMetricsFunc method. + * + * @fields: + * bearing_x :: + * Left bearing, in font units. + * + * bearing_y :: + * Top bearing, in font units. + * + * advance :: + * Horizontal component of glyph advance, in font units. + * + * advance_v :: + * Vertical component of glyph advance, in font units. + * + * @note: + * These correspond to horizontal or vertical metrics depending on the + * value of the `vertical' argument to the function + * @FT_Incremental_GetGlyphMetricsFunc. + * + */ + typedef struct FT_Incremental_MetricsRec_ + { + FT_Long bearing_x; + FT_Long bearing_y; + FT_Long advance; + FT_Long advance_v; /* since 2.3.12 */ + + } FT_Incremental_MetricsRec; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_Metrics + * + * @description: + * A handle to an @FT_Incremental_MetricsRec structure. + * + */ + typedef struct FT_Incremental_MetricsRec_* FT_Incremental_Metrics; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphDataFunc + * + * @description: + * A function called by FreeType to access a given glyph's data bytes + * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is + * enabled. + * + * Note that the format of the glyph's data bytes depends on the font + * file format. For TrueType, it must correspond to the raw bytes within + * the `glyf' table. For PostScript formats, it must correspond to the + * *unencrypted* charstring bytes, without any `lenIV' header. It is + * undefined for any other format. + * + * @input: + * incremental :: + * Handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * @output: + * adata :: + * A structure describing the returned glyph data bytes (which will be + * accessed as a read-only byte block). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If this function returns successfully the method + * @FT_Incremental_FreeGlyphDataFunc will be called later to release + * the data bytes. + * + * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for + * compound glyphs. + * + */ + typedef FT_Error + (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Data* adata ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_FreeGlyphDataFunc + * + * @description: + * A function used to release the glyph data bytes returned by a + * successful call to @FT_Incremental_GetGlyphDataFunc. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * data :: + * A structure describing the glyph data bytes (which will be accessed + * as a read-only byte block). + * + */ + typedef void + (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental, + FT_Data* data ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphMetricsFunc + * + * @description: + * A function used to retrieve the basic metrics of a given glyph index + * before accessing its data. This is necessary because, in certain + * formats like TrueType, the metrics are stored in a different place from + * the glyph images proper. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * vertical :: + * If true, return vertical metrics. + * + * ametrics :: + * This parameter is used for both input and output. + * The original glyph metrics, if any, in font units. If metrics are + * not available all the values must be set to zero. + * + * @output: + * ametrics :: + * The replacement glyph metrics in font units. + * + */ + typedef FT_Error + (*FT_Incremental_GetGlyphMetricsFunc) + ( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Bool vertical, + FT_Incremental_MetricsRec *ametrics ); + + + /************************************************************************** + * + * @struct: + * FT_Incremental_FuncsRec + * + * @description: + * A table of functions for accessing fonts that load data + * incrementally. Used in @FT_Incremental_InterfaceRec. + * + * @fields: + * get_glyph_data :: + * The function to get glyph data. Must not be null. + * + * free_glyph_data :: + * The function to release glyph data. Must not be null. + * + * get_glyph_metrics :: + * The function to get glyph metrics. May be null if the font does + * not provide overriding glyph metrics. + * + */ + typedef struct FT_Incremental_FuncsRec_ + { + FT_Incremental_GetGlyphDataFunc get_glyph_data; + FT_Incremental_FreeGlyphDataFunc free_glyph_data; + FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics; + + } FT_Incremental_FuncsRec; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_InterfaceRec + * + * @description: + * A structure to be used with @FT_Open_Face to indicate that the user + * wants to support incremental glyph loading. You should use it with + * @FT_PARAM_TAG_INCREMENTAL as in the following example: + * + * { + * FT_Incremental_InterfaceRec inc_int; + * FT_Parameter parameter; + * FT_Open_Args open_args; + * + * + * // set up incremental descriptor + * inc_int.funcs = my_funcs; + * inc_int.object = my_object; + * + * // set up optional parameter + * parameter.tag = FT_PARAM_TAG_INCREMENTAL; + * parameter.data = &inc_int; + * + * // set up FT_Open_Args structure + * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; + * open_args.pathname = my_font_pathname; + * open_args.num_params = 1; + * open_args.params = ¶meter; // we use one optional argument + * + * // open the font + * error = FT_Open_Face( library, &open_args, index, &face ); + * ... + * } + * + */ + typedef struct FT_Incremental_InterfaceRec_ + { + const FT_Incremental_FuncsRec* funcs; + FT_Incremental object; + + } FT_Incremental_InterfaceRec; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_Interface + * + * @description: + * A pointer to an @FT_Incremental_InterfaceRec structure. + * + */ + typedef FT_Incremental_InterfaceRec* FT_Incremental_Interface; + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_INCREMENTAL + * + * @description: + * A constant used as the tag of @FT_Parameter structures to indicate + * an incremental loading object to be used by FreeType. + * + */ +#define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) + + /* */ + + +FT_END_HEADER + +#endif /* FTINCREM_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftlcdfil.h b/builddir/freetype-2.7.0/include/freetype/ftlcdfil.h new file mode 100644 index 0000000..e06a895 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftlcdfil.h @@ -0,0 +1,286 @@ +/***************************************************************************/ +/* */ +/* ftlcdfil.h */ +/* */ +/* FreeType API for color filtering of subpixel bitmap glyphs */ +/* (specification). */ +/* */ +/* Copyright 2006-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTLCDFIL_H_ +#define FTLCDFIL_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************** + * + * @section: + * lcd_filtering + * + * @title: + * LCD Filtering + * + * @abstract: + * Reduce color fringes of subpixel-rendered bitmaps. + * + * @description: + * Subpixel rendering exploits the color-striped structure of LCD + * pixels, increasing the available resolution in the direction of the + * stripe (usually horizontal RGB) by a factor of~3. Since these + * subpixels are color pixels, using them unfiltered creates severe + * color fringes. Use the @FT_Library_SetLcdFilter API to specify a + * low-pass filter, which is then applied to subpixel-rendered bitmaps + * generated through @FT_Render_Glyph. The filter sacrifices some of + * the higher resolution to reduce color fringes, making the glyph image + * slightly blurrier. Positional improvements will remain. + * + * Note that no filter is active by default, and that this function is + * *not* implemented in default builds of the library. You need to + * #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file + * in order to activate it and explicitly call @FT_Library_SetLcdFilter + * to enable it. + * + * A filter should have two properties: + * + * 1) It should be normalized, meaning the sum of the 5~components + * should be 256 (0x100). It is possible to go above or under this + * target sum, however: going under means tossing out contrast, going + * over means invoking clamping and thereby non-linearities that + * increase contrast somewhat at the expense of greater distortion + * and color-fringing. Contrast is better enhanced through stem + * darkening. + * + * 2) It should be color-balanced, meaning a filter `{~a, b, c, b, a~}' + * where a~+ b~=~c. It distributes the computed coverage for one + * subpixel to all subpixels equally, sacrificing some won resolution + * but drastically reducing color-fringing. Positioning improvements + * remain! Note that color-fringing can only really be minimized + * when using a color-balanced filter and alpha-blending the glyph + * onto a surface in linear space; see @FT_Render_Glyph. + * + * Regarding the form, a filter can be a `boxy' filter or a `beveled' + * filter. Boxy filters are sharper but are less forgiving of non-ideal + * gamma curves of a screen (viewing angles!), beveled filters are + * fuzzier but more tolerant. + * + * Examples: + * + * - [0x10 0x40 0x70 0x40 0x10] is beveled and neither balanced nor + * normalized. + * + * - [0x1A 0x33 0x4D 0x33 0x1A] is beveled and balanced but not + * normalized. + * + * - [0x19 0x33 0x66 0x4c 0x19] is beveled and normalized but not + * balanced. + * + * - [0x00 0x4c 0x66 0x4c 0x00] is boxily beveled and normalized but not + * balanced. + * + * - [0x00 0x55 0x56 0x55 0x00] is boxy, normalized, and almost + * balanced. + * + * - [0x08 0x4D 0x56 0x4D 0x08] is beveled, normalized and, almost + * balanced. + * + * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, + * @FT_Load_Glyph, and @FT_Load_Char. It does _not_ affect the output + * of @FT_Outline_Render and @FT_Outline_Get_Bitmap. + * + * If this feature is activated, the dimensions of LCD glyph bitmaps are + * either wider or taller than the dimensions of the corresponding + * outline with regard to the pixel grid. For example, for + * @FT_RENDER_MODE_LCD, the filter adds 3~subpixels to the left, and + * 3~subpixels to the right. The bitmap offset values are adjusted + * accordingly, so clients shouldn't need to modify their layout and + * glyph positioning code when enabling the filter. + * + * It is important to understand that linear alpha blending and gamma + * correction is critical for correctly rendering glyphs onto surfaces + * without artifacts and even more critical when subpixel rendering is + * involved. + * + * Each of the 3~alpha values (subpixels) is independently used to blend + * one color channel. That is, red alpha blends the red channel of the + * text color with the red channel of the background pixel. The + * distribution of density values by the color-balanced filter assumes + * alpha blending is done in linear space; only then color artifacts + * cancel out. + */ + + + /**************************************************************************** + * + * @enum: + * FT_LcdFilter + * + * @description: + * A list of values to identify various types of LCD filters. + * + * @values: + * FT_LCD_FILTER_NONE :: + * Do not perform filtering. When used with subpixel rendering, this + * results in sometimes severe color fringes. + * + * FT_LCD_FILTER_DEFAULT :: + * The default filter reduces color fringes considerably, at the cost + * of a slight blurriness in the output. + * + * It is a beveled, normalized, and color-balanced five-tap filter + * that is more forgiving to screens with non-ideal gamma curves and + * viewing angles. Note that while color-fringing is reduced, it can + * only be minimized by using linear alpha blending and gamma + * correction to render glyphs onto surfaces. The default filter + * weights are [0x08 0x4D 0x56 0x4D 0x08]. + * + * FT_LCD_FILTER_LIGHT :: + * The light filter is a variant that is sharper at the cost of + * slightly more color fringes than the default one. + * + * It is a boxy, normalized, and color-balanced three-tap filter that + * is less forgiving to screens with non-ideal gamma curves and + * viewing angles. This filter works best when the rendering system + * uses linear alpha blending and gamma correction to render glyphs + * onto surfaces. The light filter weights are + * [0x00 0x55 0x56 0x55 0x00]. + * + * FT_LCD_FILTER_LEGACY :: + * This filter corresponds to the original libXft color filter. It + * provides high contrast output but can exhibit really bad color + * fringes if glyphs are not extremely well hinted to the pixel grid. + * In other words, it only works well if the TrueType bytecode + * interpreter is enabled *and* high-quality hinted fonts are used. + * + * This filter is only provided for comparison purposes, and might be + * disabled or stay unsupported in the future. + * + * FT_LCD_FILTER_LEGACY1 :: + * For historical reasons, the FontConfig library returns a different + * enumeration value for legacy LCD filtering. To make code work that + * (incorrectly) forwards FontConfig's enumeration value to + * @FT_Library_SetLcdFilter without proper mapping, it is thus easiest + * to have another enumeration value, which is completely equal to + * `FT_LCD_FILTER_LEGACY'. + * + * @since: + * 2.3.0 (`FT_LCD_FILTER_LEGACY1' since 2.6.2) + */ + typedef enum FT_LcdFilter_ + { + FT_LCD_FILTER_NONE = 0, + FT_LCD_FILTER_DEFAULT = 1, + FT_LCD_FILTER_LIGHT = 2, + FT_LCD_FILTER_LEGACY1 = 3, + FT_LCD_FILTER_LEGACY = 16, + + FT_LCD_FILTER_MAX /* do not remove */ + + } FT_LcdFilter; + + + /************************************************************************** + * + * @func: + * FT_Library_SetLcdFilter + * + * @description: + * This function is used to apply color filtering to LCD decimated + * bitmaps, like the ones used when calling @FT_Render_Glyph with + * @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V. + * + * @input: + * library :: + * A handle to the target library instance. + * + * filter :: + * The filter type. + * + * You can use @FT_LCD_FILTER_NONE here to disable this feature, or + * @FT_LCD_FILTER_DEFAULT to use a default filter that should work + * well on most LCD screens. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This feature is always disabled by default. Clients must make an + * explicit call to this function with a `filter' value other than + * @FT_LCD_FILTER_NONE in order to enable it. + * + * Due to *PATENTS* covering subpixel rendering, this function doesn't + * do anything except returning `FT_Err_Unimplemented_Feature' if the + * configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not + * defined in your build of the library, which should correspond to all + * default builds of FreeType. + * + * @since: + * 2.3.0 + */ + FT_EXPORT( FT_Error ) + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ); + + + /************************************************************************** + * + * @func: + * FT_Library_SetLcdFilterWeights + * + * @description: + * This function can be used to enable LCD filter with custom weights, + * instead of using presets in @FT_Library_SetLcdFilter. + * + * @input: + * library :: + * A handle to the target library instance. + * + * weights :: + * A pointer to an array; the function copies the first five bytes and + * uses them to specify the filter weights. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Due to *PATENTS* covering subpixel rendering, this function doesn't + * do anything except returning `FT_Err_Unimplemented_Feature' if the + * configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not + * defined in your build of the library, which should correspond to all + * default builds of FreeType. + * + * @since: + * 2.4.0 + */ + FT_EXPORT( FT_Error ) + FT_Library_SetLcdFilterWeights( FT_Library library, + unsigned char *weights ); + + /* */ + + +FT_END_HEADER + +#endif /* FTLCDFIL_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftlist.h b/builddir/freetype-2.7.0/include/freetype/ftlist.h new file mode 100644 index 0000000..82f437a --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftlist.h @@ -0,0 +1,276 @@ +/***************************************************************************/ +/* */ +/* ftlist.h */ +/* */ +/* Generic list support for FreeType (specification). */ +/* */ +/* Copyright 1996-2016 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 file implements functions relative to list processing. Its */ + /* data structures are defined in `freetype.h'. */ + /* */ + /*************************************************************************/ + + +#ifndef FTLIST_H_ +#define FTLIST_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /* <Title> */ + /* List Processing */ + /* */ + /* <Abstract> */ + /* Simple management of lists. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to list */ + /* processing using doubly-linked nodes. */ + /* */ + /* <Order> */ + /* FT_List */ + /* FT_ListNode */ + /* FT_ListRec */ + /* FT_ListNodeRec */ + /* */ + /* FT_List_Add */ + /* FT_List_Insert */ + /* FT_List_Find */ + /* FT_List_Remove */ + /* FT_List_Up */ + /* FT_List_Iterate */ + /* FT_List_Iterator */ + /* FT_List_Finalize */ + /* FT_List_Destructor */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Find */ + /* */ + /* <Description> */ + /* Find the list node for a given listed object. */ + /* */ + /* <Input> */ + /* list :: A pointer to the parent list. */ + /* data :: The address of the listed object. */ + /* */ + /* <Return> */ + /* List node. NULL if it wasn't found. */ + /* */ + FT_EXPORT( FT_ListNode ) + FT_List_Find( FT_List list, + void* data ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Add */ + /* */ + /* <Description> */ + /* Append an element to the end of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to append. */ + /* */ + FT_EXPORT( void ) + FT_List_Add( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Insert */ + /* */ + /* <Description> */ + /* Insert an element at the head of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to parent list. */ + /* node :: The node to insert. */ + /* */ + FT_EXPORT( void ) + FT_List_Insert( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Remove */ + /* */ + /* <Description> */ + /* Remove a node from a list. This function doesn't check whether */ + /* the node is in the list! */ + /* */ + /* <Input> */ + /* node :: The node to remove. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* */ + FT_EXPORT( void ) + FT_List_Remove( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Up */ + /* */ + /* <Description> */ + /* Move a node to the head/top of a list. Used to maintain LRU */ + /* lists. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to move. */ + /* */ + FT_EXPORT( void ) + FT_List_Up( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Iterator */ + /* */ + /* <Description> */ + /* An FT_List iterator function that is called during a list parse */ + /* by @FT_List_Iterate. */ + /* */ + /* <Input> */ + /* node :: The current iteration list node. */ + /* */ + /* user :: A typeless pointer passed to @FT_List_Iterate. */ + /* Can be used to point to the iteration's state. */ + /* */ + typedef FT_Error + (*FT_List_Iterator)( FT_ListNode node, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Iterate */ + /* */ + /* <Description> */ + /* Parse a list and calls a given iterator function on each element. */ + /* Note that parsing is stopped as soon as one of the iterator calls */ + /* returns a non-zero value. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* iterator :: An iterator function, called on each node of the list. */ + /* user :: A user-supplied field that is passed as the second */ + /* argument to the iterator. */ + /* */ + /* <Return> */ + /* The result (a FreeType error code) of the last iterator call. */ + /* */ + FT_EXPORT( FT_Error ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Destructor */ + /* */ + /* <Description> */ + /* An @FT_List iterator function that is called during a list */ + /* finalization by @FT_List_Finalize to destroy all elements in a */ + /* given list. */ + /* */ + /* <Input> */ + /* system :: The current system object. */ + /* */ + /* data :: The current object to destroy. */ + /* */ + /* user :: A typeless pointer passed to @FT_List_Iterate. It can */ + /* be used to point to the iteration's state. */ + /* */ + typedef void + (*FT_List_Destructor)( FT_Memory memory, + void* data, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Finalize */ + /* */ + /* <Description> */ + /* Destroy all elements in the list as well as the list itself. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* */ + /* destroy :: A list destructor that will be applied to each element */ + /* of the list. Set this to NULL if not needed. */ + /* */ + /* memory :: The current memory object that handles deallocation. */ + /* */ + /* user :: A user-supplied field that is passed as the last */ + /* argument to the destructor. */ + /* */ + /* <Note> */ + /* This function expects that all nodes added by @FT_List_Add or */ + /* @FT_List_Insert have been dynamically allocated. */ + /* */ + FT_EXPORT( void ) + FT_List_Finalize( FT_List list, + FT_List_Destructor destroy, + FT_Memory memory, + void* user ); + + /* */ + + +FT_END_HEADER + +#endif /* FTLIST_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftlzw.h b/builddir/freetype-2.7.0/include/freetype/ftlzw.h new file mode 100644 index 0000000..582e2c1 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftlzw.h @@ -0,0 +1,99 @@ +/***************************************************************************/ +/* */ +/* ftlzw.h */ +/* */ +/* LZW-compressed stream support. */ +/* */ +/* Copyright 2004-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTLZW_H_ +#define FTLZW_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* lzw */ + /* */ + /* <Title> */ + /* LZW Streams */ + /* */ + /* <Abstract> */ + /* Using LZW-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of LZW-specific functions. */ + /* */ + /*************************************************************************/ + + /************************************************************************ + * + * @function: + * FT_Stream_OpenLZW + * + * @description: + * Open a new stream to parse LZW-compressed font files. This is + * mainly used to support the compressed `*.pcf.Z' fonts that come + * with XFree86. + * + * @input: + * stream :: The target embedding stream. + * + * source :: The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream + * + * In certain builds of the library, LZW compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a LZW stream from it + * and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with LZW support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* FTLZW_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftmac.h b/builddir/freetype-2.7.0/include/freetype/ftmac.h new file mode 100644 index 0000000..adb15ca --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftmac.h @@ -0,0 +1,274 @@ +/***************************************************************************/ +/* */ +/* ftmac.h */ +/* */ +/* Additional Mac-specific API. */ +/* */ +/* Copyright 1996-2016 by */ +/* Just van Rossum, 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. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* NOTE: Include this file after FT_FREETYPE_H and after any */ +/* Mac-specific headers (because this header uses Mac types such as */ +/* Handle, FSSpec, FSRef, etc.) */ +/* */ +/***************************************************************************/ + + +#ifndef FTMAC_H_ +#define FTMAC_H_ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + +/* gcc-3.4.1 and later can warn about functions tagged as deprecated */ +#ifndef FT_DEPRECATED_ATTRIBUTE +#if defined(__GNUC__) && \ + ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) +#define FT_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) +#else +#define FT_DEPRECATED_ATTRIBUTE +#endif +#endif + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* mac_specific */ + /* */ + /* <Title> */ + /* Mac Specific Interface */ + /* */ + /* <Abstract> */ + /* Only available on the Macintosh. */ + /* */ + /* <Description> */ + /* The following definitions are only available if FreeType is */ + /* compiled on a Macintosh. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FOND */ + /* */ + /* <Description> */ + /* Create a new face object from a FOND resource. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* fond :: A FOND resource. */ + /* */ + /* face_index :: Only supported for the -1 `sanity check' special */ + /* case. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Notes> */ + /* This function can be used to create @FT_Face objects from fonts */ + /* that are installed in the system as follows. */ + /* */ + /* { */ + /* fond = GetResource( 'FOND', fontName ); */ + /* error = FT_New_Face_From_FOND( library, fond, 0, &face ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FOND( FT_Library library, + Handle fond, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFile_From_Mac_Name */ + /* */ + /* <Description> */ + /* Return an FSSpec for the disk file containing the named font. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font (e.g., Times New Roman */ + /* Bold). */ + /* */ + /* <Output> */ + /* pathSpec :: FSSpec to the file. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* face_index :: Index of the face. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFile_From_Mac_ATS_Name */ + /* */ + /* <Description> */ + /* Return an FSSpec for the disk file containing the named font. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font in ATS framework. */ + /* */ + /* <Output> */ + /* pathSpec :: FSSpec to the file. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* face_index :: Index of the face. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFile_From_Mac_ATS_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFilePath_From_Mac_ATS_Name */ + /* */ + /* <Description> */ + /* Return a pathname of the disk file and face index for given font */ + /* name that is handled by ATS framework. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font in ATS framework. */ + /* */ + /* <Output> */ + /* path :: Buffer to store pathname of the file. For passing */ + /* to @FT_New_Face. The client must allocate this */ + /* buffer before calling this function. */ + /* */ + /* maxPathSize :: Lengths of the buffer `path' that client allocated. */ + /* */ + /* face_index :: Index of the face. For passing to @FT_New_Face. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, + UInt8* path, + UInt32 maxPathSize, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSSpec */ + /* */ + /* <Description> */ + /* Create a new face object from a given resource and typeface index */ + /* using an FSSpec to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* spec :: FSSpec to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index~0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except */ + /* it accepts an FSSpec instead of a path. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FSSpec( FT_Library library, + const FSSpec *spec, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSRef */ + /* */ + /* <Description> */ + /* Create a new face object from a given resource and typeface index */ + /* using an FSRef to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* spec :: FSRef to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index~0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* @FT_New_Face_From_FSRef is identical to @FT_New_Face except */ + /* it accepts an FSRef instead of a path. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FSRef( FT_Library library, + const FSRef *ref, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + /* */ + + +FT_END_HEADER + + +#endif /* FTMAC_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftmm.h b/builddir/freetype-2.7.0/include/freetype/ftmm.h new file mode 100644 index 0000000..b5d6858 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftmm.h @@ -0,0 +1,388 @@ +/***************************************************************************/ +/* */ +/* ftmm.h */ +/* */ +/* FreeType Multiple Master font interface (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTMM_H_ +#define FTMM_H_ + + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* multiple_masters */ + /* */ + /* <Title> */ + /* Multiple Masters */ + /* */ + /* <Abstract> */ + /* How to manage Multiple Masters fonts. */ + /* */ + /* <Description> */ + /* The following types and functions are used to manage Multiple */ + /* Master fonts, i.e., the selection of specific design instances by */ + /* setting design axis coordinates. */ + /* */ + /* George Williams has extended this interface to make it work with */ + /* both Type~1 Multiple Masters fonts and GX distortable (var) */ + /* fonts. Some of these routines only work with MM fonts, others */ + /* will work with both types. They are similar enough that a */ + /* consistent interface makes sense. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_MM_Axis */ + /* */ + /* <Description> */ + /* A simple structure used to model a given axis in design space for */ + /* Multiple Masters fonts. */ + /* */ + /* This structure can't be used for GX var fonts. */ + /* */ + /* <Fields> */ + /* name :: The axis's name. */ + /* */ + /* minimum :: The axis's minimum design coordinate. */ + /* */ + /* maximum :: The axis's maximum design coordinate. */ + /* */ + typedef struct FT_MM_Axis_ + { + FT_String* name; + FT_Long minimum; + FT_Long maximum; + + } FT_MM_Axis; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Multi_Master */ + /* */ + /* <Description> */ + /* A structure used to model the axes and space of a Multiple Masters */ + /* font. */ + /* */ + /* This structure can't be used for GX var fonts. */ + /* */ + /* <Fields> */ + /* num_axis :: Number of axes. Cannot exceed~4. */ + /* */ + /* num_designs :: Number of designs; should be normally 2^num_axis */ + /* even though the Type~1 specification strangely */ + /* allows for intermediate designs to be present. */ + /* This number cannot exceed~16. */ + /* */ + /* axis :: A table of axis descriptors. */ + /* */ + typedef struct FT_Multi_Master_ + { + FT_UInt num_axis; + FT_UInt num_designs; + FT_MM_Axis axis[T1_MAX_MM_AXIS]; + + } FT_Multi_Master; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Var_Axis */ + /* */ + /* <Description> */ + /* A simple structure used to model a given axis in design space for */ + /* Multiple Masters and GX var fonts. */ + /* */ + /* <Fields> */ + /* name :: The axis's name. */ + /* Not always meaningful for GX. */ + /* */ + /* minimum :: The axis's minimum design coordinate. */ + /* */ + /* def :: The axis's default design coordinate. */ + /* FreeType computes meaningful default values for MM; it */ + /* is then an integer value, not in 16.16 format. */ + /* */ + /* maximum :: The axis's maximum design coordinate. */ + /* */ + /* tag :: The axis's tag (the GX equivalent to `name'). */ + /* FreeType provides default values for MM if possible. */ + /* */ + /* strid :: The entry in `name' table (another GX version of */ + /* `name'). */ + /* Not meaningful for MM. */ + /* */ + typedef struct FT_Var_Axis_ + { + FT_String* name; + + FT_Fixed minimum; + FT_Fixed def; + FT_Fixed maximum; + + FT_ULong tag; + FT_UInt strid; + + } FT_Var_Axis; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Var_Named_Style */ + /* */ + /* <Description> */ + /* A simple structure used to model a named style in a GX var font. */ + /* */ + /* This structure can't be used for MM fonts. */ + /* */ + /* <Fields> */ + /* coords :: The design coordinates for this style. */ + /* This is an array with one entry for each axis. */ + /* */ + /* strid :: The entry in `name' table identifying this style. */ + /* */ + typedef struct FT_Var_Named_Style_ + { + FT_Fixed* coords; + FT_UInt strid; + + } FT_Var_Named_Style; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_MM_Var */ + /* */ + /* <Description> */ + /* A structure used to model the axes and space of a Multiple Masters */ + /* or GX var distortable font. */ + /* */ + /* Some fields are specific to one format and not to the other. */ + /* */ + /* <Fields> */ + /* num_axis :: The number of axes. The maximum value is~4 for */ + /* MM; no limit in GX. */ + /* */ + /* num_designs :: The number of designs; should be normally */ + /* 2^num_axis for MM fonts. Not meaningful for GX */ + /* (where every glyph could have a different */ + /* number of designs). */ + /* */ + /* num_namedstyles :: The number of named styles; a `named style' is */ + /* a tuple of design coordinates that has a string */ + /* ID (in the `name' table) associated with it. */ + /* The font can tell the user that, for example, */ + /* [Weight=1.5,Width=1.1] is `Bold'. */ + /* */ + /* For Type 1 Multiple Masters fonts, this value */ + /* is always zero because the format does not */ + /* support named styles. */ + /* */ + /* axis :: An axis descriptor table. */ + /* GX fonts contain slightly more data than MM. */ + /* Memory management of this pointer is done */ + /* internally by FreeType. */ + /* */ + /* namedstyle :: A named style table. */ + /* Only meaningful with GX. */ + /* Memory management of this pointer is done */ + /* internally by FreeType. */ + /* */ + typedef struct FT_MM_Var_ + { + FT_UInt num_axis; + FT_UInt num_designs; + FT_UInt num_namedstyles; + FT_Var_Axis* axis; + FT_Var_Named_Style* namedstyle; + + } FT_MM_Var; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Multi_Master */ + /* */ + /* <Description> */ + /* Retrieve the Multiple Master descriptor of a given font. */ + /* */ + /* This function can't be used with GX fonts. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Output> */ + /* amaster :: The Multiple Masters descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Multi_Master( FT_Face face, + FT_Multi_Master *amaster ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_MM_Var */ + /* */ + /* <Description> */ + /* Retrieve the Multiple Master/GX var descriptor of a given font. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Output> */ + /* amaster :: The Multiple Masters/GX var descriptor. */ + /* Allocates a data structure, which the user must */ + /* deallocate with `free' after use. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_MM_Var( FT_Face face, + FT_MM_Var* *amaster ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Design_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters fonts, choose an interpolated font design */ + /* through design coordinates. */ + /* */ + /* This function can't be used with GX fonts. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of available design coordinates. If it */ + /* is larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use default values for the remaining axes. */ + /* */ + /* coords :: An array of design coordinates. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Var_Design_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Master or GX Var fonts, choose an interpolated font */ + /* design through design coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of available design coordinates. If it */ + /* is larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use default values for the remaining axes. */ + /* */ + /* coords :: An array of design coordinates. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Blend_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters and GX var fonts, choose an interpolated font */ + /* design through normalized blend coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of available design coordinates. If it */ + /* is larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use default values for the remaining axes. */ + /* */ + /* coords :: The design coordinates array (each element must be */ + /* between 0 and 1.0). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Var_Blend_Coordinates */ + /* */ + /* <Description> */ + /* This is another name of @FT_Set_MM_Blend_Coordinates. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + /* */ + + +FT_END_HEADER + +#endif /* FTMM_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftmodapi.h b/builddir/freetype-2.7.0/include/freetype/ftmodapi.h new file mode 100644 index 0000000..b4d2758 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftmodapi.h @@ -0,0 +1,667 @@ +/***************************************************************************/ +/* */ +/* ftmodapi.h */ +/* */ +/* FreeType modules public interface (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTMODAPI_H_ +#define FTMODAPI_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /* <Title> */ + /* Module Management */ + /* */ + /* <Abstract> */ + /* How to add, upgrade, remove, and control modules from FreeType. */ + /* */ + /* <Description> */ + /* The definitions below are used to manage modules within FreeType. */ + /* Modules can be added, upgraded, and removed at runtime. */ + /* Additionally, some module properties can be controlled also. */ + /* */ + /* Here is a list of possible values of the `module_name' field in */ + /* the @FT_Module_Class structure. */ + /* */ + /* { */ + /* autofitter */ + /* bdf */ + /* cff */ + /* gxvalid */ + /* otvalid */ + /* pcf */ + /* pfr */ + /* psaux */ + /* pshinter */ + /* psnames */ + /* raster1 */ + /* sfnt */ + /* smooth, smooth-lcd, smooth-lcdv */ + /* truetype */ + /* type1 */ + /* type42 */ + /* t1cid */ + /* winfonts */ + /* } */ + /* */ + /* Note that the FreeType Cache sub-system is not a FreeType module. */ + /* */ + /* <Order> */ + /* FT_Module */ + /* FT_Module_Constructor */ + /* FT_Module_Destructor */ + /* FT_Module_Requester */ + /* FT_Module_Class */ + /* */ + /* FT_Add_Module */ + /* FT_Get_Module */ + /* FT_Remove_Module */ + /* FT_Add_Default_Modules */ + /* */ + /* FT_Property_Set */ + /* FT_Property_Get */ + /* */ + /* FT_New_Library */ + /* FT_Done_Library */ + /* FT_Reference_Library */ + /* */ + /* FT_Renderer */ + /* FT_Renderer_Class */ + /* */ + /* FT_Get_Renderer */ + /* FT_Set_Renderer */ + /* */ + /* FT_Set_Debug_Hook */ + /* */ + /*************************************************************************/ + + + /* module bit flags */ +#define FT_MODULE_FONT_DRIVER 1 /* this module is a font driver */ +#define FT_MODULE_RENDERER 2 /* this module is a renderer */ +#define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ +#define FT_MODULE_STYLER 8 /* this module is a styler */ + +#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ + /* scalable fonts */ +#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ + /* support vector outlines */ +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ + /* own hinter */ +#define FT_MODULE_DRIVER_HINTS_LIGHTLY 0x800 /* the driver's hinter */ + /* produces LIGHT hints */ + + + /* deprecated values */ +#define ft_module_font_driver FT_MODULE_FONT_DRIVER +#define ft_module_renderer FT_MODULE_RENDERER +#define ft_module_hinter FT_MODULE_HINTER +#define ft_module_styler FT_MODULE_STYLER + +#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE +#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES +#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER +#define ft_module_driver_hints_lightly FT_MODULE_DRIVER_HINTS_LIGHTLY + + + typedef FT_Pointer FT_Module_Interface; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Constructor */ + /* */ + /* <Description> */ + /* A function used to initialize (not create) a new module object. */ + /* */ + /* <Input> */ + /* module :: The module to initialize. */ + /* */ + typedef FT_Error + (*FT_Module_Constructor)( FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destructor */ + /* */ + /* <Description> */ + /* A function used to finalize (not destroy) a given module object. */ + /* */ + /* <Input> */ + /* module :: The module to finalize. */ + /* */ + typedef void + (*FT_Module_Destructor)( FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Requester */ + /* */ + /* <Description> */ + /* A function used to query a given module for a specific interface. */ + /* */ + /* <Input> */ + /* module :: The module to be searched. */ + /* */ + /* name :: The name of the interface in the module. */ + /* */ + typedef FT_Module_Interface + (*FT_Module_Requester)( FT_Module module, + const char* name ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Module_Class */ + /* */ + /* <Description> */ + /* The module class descriptor. */ + /* */ + /* <Fields> */ + /* module_flags :: Bit flags describing the module. */ + /* */ + /* module_size :: The size of one module object/instance in */ + /* bytes. */ + /* */ + /* module_name :: The name of the module. */ + /* */ + /* module_version :: The version, as a 16.16 fixed number */ + /* (major.minor). */ + /* */ + /* module_requires :: The version of FreeType this module requires, */ + /* as a 16.16 fixed number (major.minor). Starts */ + /* at version 2.0, i.e., 0x20000. */ + /* */ + /* module_init :: The initializing function. */ + /* */ + /* module_done :: The finalizing function. */ + /* */ + /* get_interface :: The interface requesting function. */ + /* */ + typedef struct FT_Module_Class_ + { + FT_ULong module_flags; + FT_Long module_size; + const FT_String* module_name; + FT_Fixed module_version; + FT_Fixed module_requires; + + const void* module_interface; + + FT_Module_Constructor module_init; + FT_Module_Destructor module_done; + FT_Module_Requester get_interface; + + } FT_Module_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Module */ + /* */ + /* <Description> */ + /* Add a new module to a given library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* clazz :: A pointer to class descriptor for the module. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Add_Module( FT_Library library, + const FT_Module_Class* clazz ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Module */ + /* */ + /* <Description> */ + /* Find a module by its name. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* module_name :: The module's name (as an ASCII string). */ + /* */ + /* <Return> */ + /* A module handle. 0~if none was found. */ + /* */ + /* <Note> */ + /* FreeType's internal modules aren't documented very well, and you */ + /* should look up the source code for details. */ + /* */ + FT_EXPORT( FT_Module ) + FT_Get_Module( FT_Library library, + const char* module_name ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Remove_Module */ + /* */ + /* <Description> */ + /* Remove a given module from a library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to a library object. */ + /* */ + /* <Input> */ + /* module :: A handle to a module object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The module object is destroyed by the function in case of success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Remove_Module( FT_Library library, + FT_Module module ); + + + /********************************************************************** + * + * @function: + * FT_Property_Set + * + * @description: + * Set a property for a given module. + * + * @input: + * library :: + * A handle to the library the module is part of. + * + * module_name :: + * The module name. + * + * property_name :: + * The property name. Properties are described in the `Synopsis' + * subsection of the module's documentation. + * + * Note that only a few modules have properties. + * + * value :: + * A generic pointer to a variable or structure that gives the new + * value of the property. The exact definition of `value' is + * dependent on the property; see the `Synopsis' subsection of the + * module's documentation. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `module_name' isn't a valid module name, or `property_name' + * doesn't specify a valid property, or if `value' doesn't represent a + * valid value for the given property, an error is returned. + * + * The following example sets property `bar' (a simple integer) in + * module `foo' to value~1. + * + * { + * FT_UInt bar; + * + * + * bar = 1; + * FT_Property_Set( library, "foo", "bar", &bar ); + * } + * + * Note that the FreeType Cache sub-system doesn't recognize module + * property changes. To avoid glyph lookup confusion within the cache + * you should call @FTC_Manager_Reset to completely flush the cache if + * a module property gets changed after @FTC_Manager_New has been + * called. + * + * It is not possible to set properties of the FreeType Cache + * sub-system itself with FT_Property_Set; use @FTC_Property_Set + * instead. + * + * @since: + * 2.4.11 + * + */ + FT_EXPORT( FT_Error ) + FT_Property_Set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + const void* value ); + + + /********************************************************************** + * + * @function: + * FT_Property_Get + * + * @description: + * Get a module's property value. + * + * @input: + * library :: + * A handle to the library the module is part of. + * + * module_name :: + * The module name. + * + * property_name :: + * The property name. Properties are described in the `Synopsis' + * subsection of the module's documentation. + * + * @inout: + * value :: + * A generic pointer to a variable or structure that gives the + * value of the property. The exact definition of `value' is + * dependent on the property; see the `Synopsis' subsection of the + * module's documentation. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `module_name' isn't a valid module name, or `property_name' + * doesn't specify a valid property, or if `value' doesn't represent a + * valid value for the given property, an error is returned. + * + * The following example gets property `baz' (a range) in module `foo'. + * + * { + * typedef range_ + * { + * FT_Int32 min; + * FT_Int32 max; + * + * } range; + * + * range baz; + * + * + * FT_Property_Get( library, "foo", "baz", &baz ); + * } + * + * It is not possible to retrieve properties of the FreeType Cache + * sub-system with FT_Property_Get; use @FTC_Property_Get instead. + * + * @since: + * 2.4.11 + * + */ + FT_EXPORT( FT_Error ) + FT_Property_Get( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + void* value ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Reference_Library */ + /* */ + /* <Description> */ + /* A counter gets initialized to~1 at the time an @FT_Library */ + /* structure is created. This function increments the counter. */ + /* @FT_Done_Library then only destroys a library if the counter is~1, */ + /* otherwise it simply decrements the counter. */ + /* */ + /* This function helps in managing life-cycles of structures that */ + /* reference @FT_Library objects. */ + /* */ + /* <Input> */ + /* library :: A handle to a target library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Since> */ + /* 2.4.2 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Reference_Library( FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Library */ + /* */ + /* <Description> */ + /* This function is used to create a new FreeType library instance */ + /* from a given memory object. It is thus possible to use libraries */ + /* with distinct memory allocators within the same program. Note, */ + /* however, that the used @FT_Memory structure is expected to remain */ + /* valid for the life of the @FT_Library object. */ + /* */ + /* Normally, you would call this function (followed by a call to */ + /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ + /* instead of @FT_Init_FreeType to initialize the FreeType library. */ + /* */ + /* Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a */ + /* library instance. */ + /* */ + /* <Input> */ + /* memory :: A handle to the original memory object. */ + /* */ + /* <Output> */ + /* alibrary :: A pointer to handle of a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Library. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Library( FT_Memory memory, + FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Library */ + /* */ + /* <Description> */ + /* Discard a given library object. This closes all drivers and */ + /* discards all resource objects. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Library. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Library( FT_Library library ); + + /* */ + + typedef void + (*FT_DebugHook_Func)( void* arg ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Debug_Hook */ + /* */ + /* <Description> */ + /* Set a debug hook function for debugging the interpreter of a font */ + /* format. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* hook_index :: The index of the debug hook. You should use the */ + /* values defined in `ftobjs.h', e.g., */ + /* `FT_DEBUG_HOOK_TRUETYPE'. */ + /* */ + /* debug_hook :: The function used to debug the interpreter. */ + /* */ + /* <Note> */ + /* Currently, four debug hook slots are available, but only two (for */ + /* the TrueType and the Type~1 interpreter) are defined. */ + /* */ + /* Since the internal headers of FreeType are no longer installed, */ + /* the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly. */ + /* This is a bug and will be fixed in a forthcoming release. */ + /* */ + FT_EXPORT( void ) + FT_Set_Debug_Hook( FT_Library library, + FT_UInt hook_index, + FT_DebugHook_Func debug_hook ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Default_Modules */ + /* */ + /* <Description> */ + /* Add the set of default drivers to a given library object. */ + /* This is only useful when you create a library object with */ + /* @FT_New_Library (usually to plug a custom memory manager). */ + /* */ + /* <InOut> */ + /* library :: A handle to a new library object. */ + /* */ + FT_EXPORT( void ) + FT_Add_Default_Modules( FT_Library library ); + + + + /************************************************************************** + * + * @section: + * truetype_engine + * + * @title: + * The TrueType Engine + * + * @abstract: + * TrueType bytecode support. + * + * @description: + * This section contains a function used to query the level of TrueType + * bytecode support compiled in this version of the library. + * + */ + + + /************************************************************************** + * + * @enum: + * FT_TrueTypeEngineType + * + * @description: + * A list of values describing which kind of TrueType bytecode + * engine is implemented in a given FT_Library instance. It is used + * by the @FT_Get_TrueType_Engine_Type function. + * + * @values: + * FT_TRUETYPE_ENGINE_TYPE_NONE :: + * The library doesn't implement any kind of bytecode interpreter. + * + * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: + * Deprecated and removed. + * + * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: + * The library implements a bytecode interpreter that covers + * the full instruction set of the TrueType virtual machine (this + * was governed by patents until May 2010, hence the name). + * + * @since: + * 2.2 + * + */ + typedef enum FT_TrueTypeEngineType_ + { + FT_TRUETYPE_ENGINE_TYPE_NONE = 0, + FT_TRUETYPE_ENGINE_TYPE_UNPATENTED, + FT_TRUETYPE_ENGINE_TYPE_PATENTED + + } FT_TrueTypeEngineType; + + + /************************************************************************** + * + * @func: + * FT_Get_TrueType_Engine_Type + * + * @description: + * Return an @FT_TrueTypeEngineType value to indicate which level of + * the TrueType virtual machine a given library instance supports. + * + * @input: + * library :: + * A library instance. + * + * @return: + * A value indicating which level is supported. + * + * @since: + * 2.2 + * + */ + FT_EXPORT( FT_TrueTypeEngineType ) + FT_Get_TrueType_Engine_Type( FT_Library library ); + + /* */ + + +FT_END_HEADER + +#endif /* FTMODAPI_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftmoderr.h b/builddir/freetype-2.7.0/include/freetype/ftmoderr.h new file mode 100644 index 0000000..2a7671c --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftmoderr.h @@ -0,0 +1,194 @@ +/***************************************************************************/ +/* */ +/* ftmoderr.h */ +/* */ +/* FreeType module error offsets (specification). */ +/* */ +/* Copyright 2001-2016 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 file is used to define the FreeType module error codes. */ + /* */ + /* If the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in `ftoption.h' is */ + /* set, the lower byte of an error value identifies the error code as */ + /* usual. In addition, the higher byte identifies the module. For */ + /* example, the error `FT_Err_Invalid_File_Format' has value 0x0003, the */ + /* error `TT_Err_Invalid_File_Format' has value 0x1303, the error */ + /* `T1_Err_Invalid_File_Format' has value 0x1403, etc. */ + /* */ + /* Note that `FT_Err_Ok', `TT_Err_Ok', etc. are always equal to zero, */ + /* including the high byte. */ + /* */ + /* If FT_CONFIG_OPTION_USE_MODULE_ERRORS isn't set, the higher byte of */ + /* an error value is set to zero. */ + /* */ + /* To hide the various `XXX_Err_' prefixes in the source code, FreeType */ + /* provides some macros in `fttypes.h'. */ + /* */ + /* FT_ERR( err ) */ + /* Add current error module prefix (as defined with the */ + /* `FT_ERR_PREFIX' macro) to `err'. For example, in the BDF module */ + /* the line */ + /* */ + /* error = FT_ERR( Invalid_Outline ); */ + /* */ + /* expands to */ + /* */ + /* error = BDF_Err_Invalid_Outline; */ + /* */ + /* For simplicity, you can always use `FT_Err_Ok' directly instead */ + /* of `FT_ERR( Ok )'. */ + /* */ + /* FT_ERR_EQ( errcode, err ) */ + /* FT_ERR_NEQ( errcode, err ) */ + /* Compare error code `errcode' with the error `err' for equality */ + /* and inequality, respectively. Example: */ + /* */ + /* if ( FT_ERR_EQ( error, Invalid_Outline ) ) */ + /* ... */ + /* */ + /* Using this macro you don't have to think about error prefixes. */ + /* Of course, if module errors are not active, the above example is */ + /* the same as */ + /* */ + /* if ( error == FT_Err_Invalid_Outline ) */ + /* ... */ + /* */ + /* FT_ERROR_BASE( errcode ) */ + /* FT_ERROR_MODULE( errcode ) */ + /* Get base error and module error code, respectively. */ + /* */ + /* */ + /* It can also be used to create a module error message table easily */ + /* with something like */ + /* */ + /* { */ + /* #undef FTMODERR_H_ */ + /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ + /* #define FT_MODERR_START_LIST { */ + /* #define FT_MODERR_END_LIST { 0, 0 } }; */ + /* */ + /* const struct */ + /* { */ + /* int mod_err_offset; */ + /* const char* mod_err_msg */ + /* } ft_mod_errors[] = */ + /* */ + /* #include FT_MODULE_ERRORS_H */ + /* } */ + /* */ + /*************************************************************************/ + + +#ifndef FTMODERR_H_ +#define FTMODERR_H_ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + +#ifndef FT_MODERRDEF + +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = v, +#else +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = 0, +#endif + +#define FT_MODERR_START_LIST enum { +#define FT_MODERR_END_LIST FT_Mod_Err_Max }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_MODERRDEF */ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** LIST MODULE ERROR BASES *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_MODERR_START_LIST + FT_MODERR_START_LIST +#endif + + + FT_MODERRDEF( Base, 0x000, "base module" ) + FT_MODERRDEF( Autofit, 0x100, "autofitter module" ) + FT_MODERRDEF( BDF, 0x200, "BDF module" ) + FT_MODERRDEF( Bzip2, 0x300, "Bzip2 module" ) + FT_MODERRDEF( Cache, 0x400, "cache module" ) + FT_MODERRDEF( CFF, 0x500, "CFF module" ) + FT_MODERRDEF( CID, 0x600, "CID module" ) + FT_MODERRDEF( Gzip, 0x700, "Gzip module" ) + FT_MODERRDEF( LZW, 0x800, "LZW module" ) + FT_MODERRDEF( OTvalid, 0x900, "OpenType validation module" ) + FT_MODERRDEF( PCF, 0xA00, "PCF module" ) + FT_MODERRDEF( PFR, 0xB00, "PFR module" ) + FT_MODERRDEF( PSaux, 0xC00, "PS auxiliary module" ) + FT_MODERRDEF( PShinter, 0xD00, "PS hinter module" ) + FT_MODERRDEF( PSnames, 0xE00, "PS names module" ) + FT_MODERRDEF( Raster, 0xF00, "raster module" ) + FT_MODERRDEF( SFNT, 0x1000, "SFNT module" ) + FT_MODERRDEF( Smooth, 0x1100, "smooth raster module" ) + FT_MODERRDEF( TrueType, 0x1200, "TrueType module" ) + FT_MODERRDEF( Type1, 0x1300, "Type 1 module" ) + FT_MODERRDEF( Type42, 0x1400, "Type 42 module" ) + FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" ) + FT_MODERRDEF( GXvalid, 0x1600, "GX validation module" ) + + +#ifdef FT_MODERR_END_LIST + FT_MODERR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_MODERR_START_LIST +#undef FT_MODERR_END_LIST +#undef FT_MODERRDEF +#undef FT_NEED_EXTERN_C + + +#endif /* FTMODERR_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftotval.h b/builddir/freetype-2.7.0/include/freetype/ftotval.h new file mode 100644 index 0000000..3e6e18d --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftotval.h @@ -0,0 +1,204 @@ +/***************************************************************************/ +/* */ +/* ftotval.h */ +/* */ +/* FreeType API for validating OpenType tables (specification). */ +/* */ +/* Copyright 2004-2016 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. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* */ +/* Warning: This module might be moved to a different library in the */ +/* future to avoid a tight dependency between FreeType and the */ +/* OpenType specification. */ +/* */ +/* */ +/***************************************************************************/ + + +#ifndef FTOTVAL_H_ +#define FTOTVAL_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* ot_validation */ + /* */ + /* <Title> */ + /* OpenType Validation */ + /* */ + /* <Abstract> */ + /* An API to validate OpenType tables. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions to validate */ + /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ + /* */ + /* <Order> */ + /* FT_OpenType_Validate */ + /* FT_OpenType_Free */ + /* */ + /* FT_VALIDATE_OTXXX */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_OTXXX + * + * @description: + * A list of bit-field constants used with @FT_OpenType_Validate to + * indicate which OpenType tables should be validated. + * + * @values: + * FT_VALIDATE_BASE :: + * Validate BASE table. + * + * FT_VALIDATE_GDEF :: + * Validate GDEF table. + * + * FT_VALIDATE_GPOS :: + * Validate GPOS table. + * + * FT_VALIDATE_GSUB :: + * Validate GSUB table. + * + * FT_VALIDATE_JSTF :: + * Validate JSTF table. + * + * FT_VALIDATE_MATH :: + * Validate MATH table. + * + * FT_VALIDATE_OT :: + * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). + * + */ +#define FT_VALIDATE_BASE 0x0100 +#define FT_VALIDATE_GDEF 0x0200 +#define FT_VALIDATE_GPOS 0x0400 +#define FT_VALIDATE_GSUB 0x0800 +#define FT_VALIDATE_JSTF 0x1000 +#define FT_VALIDATE_MATH 0x2000 + +#define FT_VALIDATE_OT ( FT_VALIDATE_BASE | \ + FT_VALIDATE_GDEF | \ + FT_VALIDATE_GPOS | \ + FT_VALIDATE_GSUB | \ + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH ) + + /********************************************************************** + * + * @function: + * FT_OpenType_Validate + * + * @description: + * Validate various OpenType tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library that + * actually does the text layout can access those tables without + * error checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field that specifies the tables to be validated. See + * @FT_VALIDATE_OTXXX for possible values. + * + * @output: + * BASE_table :: + * A pointer to the BASE table. + * + * GDEF_table :: + * A pointer to the GDEF table. + * + * GPOS_table :: + * A pointer to the GPOS table. + * + * GSUB_table :: + * A pointer to the GSUB table. + * + * JSTF_table :: + * A pointer to the JSTF table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with OpenType fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the five tables with + * @FT_OpenType_Free. A NULL value indicates that the table either + * doesn't exist in the font, or the application hasn't asked for + * validation. + */ + FT_EXPORT( FT_Error ) + FT_OpenType_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *BASE_table, + FT_Bytes *GDEF_table, + FT_Bytes *GPOS_table, + FT_Bytes *GSUB_table, + FT_Bytes *JSTF_table ); + + /********************************************************************** + * + * @function: + * FT_OpenType_Free + * + * @description: + * Free the buffer allocated by OpenType validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_OpenType_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_OpenType_Validate only. + */ + FT_EXPORT( void ) + FT_OpenType_Free( FT_Face face, + FT_Bytes table ); + + /* */ + + +FT_END_HEADER + +#endif /* FTOTVAL_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftoutln.h b/builddir/freetype-2.7.0/include/freetype/ftoutln.h new file mode 100644 index 0000000..ef66d48 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftoutln.h @@ -0,0 +1,582 @@ +/***************************************************************************/ +/* */ +/* ftoutln.h */ +/* */ +/* Support for the FT_Outline type used to store glyph shapes of */ +/* most scalable font formats (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTOUTLN_H_ +#define FTOUTLN_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /* <Title> */ + /* Outline Processing */ + /* */ + /* <Abstract> */ + /* Functions to create, transform, and render vectorial glyph images. */ + /* */ + /* <Description> */ + /* This section contains routines used to create and destroy scalable */ + /* glyph images known as `outlines'. These can also be measured, */ + /* transformed, and converted into bitmaps and pixmaps. */ + /* */ + /* <Order> */ + /* FT_Outline */ + /* FT_Outline_New */ + /* FT_Outline_Done */ + /* FT_Outline_Copy */ + /* FT_Outline_Translate */ + /* FT_Outline_Transform */ + /* FT_Outline_Embolden */ + /* FT_Outline_EmboldenXY */ + /* FT_Outline_Reverse */ + /* FT_Outline_Check */ + /* */ + /* FT_Outline_Get_CBox */ + /* FT_Outline_Get_BBox */ + /* */ + /* FT_Outline_Get_Bitmap */ + /* FT_Outline_Render */ + /* FT_Outline_Decompose */ + /* FT_Outline_Funcs */ + /* FT_Outline_MoveToFunc */ + /* FT_Outline_LineToFunc */ + /* FT_Outline_ConicToFunc */ + /* FT_Outline_CubicToFunc */ + /* */ + /* FT_Orientation */ + /* FT_Outline_Get_Orientation */ + /* */ + /* FT_OUTLINE_XXX */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Decompose */ + /* */ + /* <Description> */ + /* Walk over an outline's structure to decompose it into individual */ + /* segments and Bézier arcs. This function also emits `move to' */ + /* operations to indicate the start of new contours in the outline. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source target. */ + /* */ + /* func_interface :: A table of `emitters', i.e., function pointers */ + /* called during decomposition to indicate path */ + /* operations. */ + /* */ + /* <InOut> */ + /* user :: A typeless pointer that is passed to each */ + /* emitter during the decomposition. It can be */ + /* used to store the state during the */ + /* decomposition. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* A contour that contains a single point only is represented by a */ + /* `move to' operation followed by `line to' to the same point. In */ + /* most cases, it is best to filter this out before using the */ + /* outline for stroking purposes (otherwise it would result in a */ + /* visible dot when round caps are used). */ + /* */ + /* Similarly, the function returns success for an empty outline also */ + /* (doing nothing, this is, not calling any emitter); if necessary, */ + /* you should filter this out, too. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Decompose( FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_New */ + /* */ + /* <Description> */ + /* Create a new outline of a given size. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object from where the */ + /* outline is allocated. Note however that the new */ + /* outline will *not* necessarily be *freed*, when */ + /* destroying the library, by @FT_Done_FreeType. */ + /* */ + /* numPoints :: The maximum number of points within the outline. */ + /* Must be smaller than or equal to 0xFFFF (65535). */ + /* */ + /* numContours :: The maximum number of contours within the outline. */ + /* This value must be in the range 0 to `numPoints'. */ + /* */ + /* <Output> */ + /* anoutline :: A handle to the new outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The reason why this function takes a `library' parameter is simply */ + /* to use the library's memory allocator. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_New( FT_Library library, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_New_Internal( FT_Memory memory, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Done */ + /* */ + /* <Description> */ + /* Destroy an outline created with @FT_Outline_New. */ + /* */ + /* <Input> */ + /* library :: A handle of the library object used to allocate the */ + /* outline. */ + /* */ + /* outline :: A pointer to the outline object to be discarded. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If the outline's `owner' field is not set, only the outline */ + /* descriptor will be released. */ + /* */ + /* The reason why this function takes an `library' parameter is */ + /* simply to use ft_mem_free(). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Done( FT_Library library, + FT_Outline* outline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_Done_Internal( FT_Memory memory, + FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Check */ + /* */ + /* <Description> */ + /* Check the contents of an outline descriptor. */ + /* */ + /* <Input> */ + /* outline :: A handle to a source outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* An empty outline, or an outline with a single point only is also */ + /* valid. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Check( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_CBox */ + /* */ + /* <Description> */ + /* Return an outline's `control box'. The control box encloses all */ + /* the outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* that contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component, which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <Output> */ + /* acbox :: The outline's control box. */ + /* */ + /* <Note> */ + /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Translate */ + /* */ + /* <Description> */ + /* Apply a simple translation to the points of an outline. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* xOffset :: The horizontal offset. */ + /* */ + /* yOffset :: The vertical offset. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Translate( const FT_Outline* outline, + FT_Pos xOffset, + FT_Pos yOffset ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Copy */ + /* */ + /* <Description> */ + /* Copy an outline into another one. Both objects must have the */ + /* same sizes (number of points & number of contours) when this */ + /* function is called. */ + /* */ + /* <Input> */ + /* source :: A handle to the source outline. */ + /* */ + /* <Output> */ + /* target :: A handle to the target outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Copy( const FT_Outline* source, + FT_Outline *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Transform */ + /* */ + /* <Description> */ + /* Apply a simple 2x2 matrix to all of an outline's points. Useful */ + /* for applying rotations, slanting, flipping, etc. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation matrix. */ + /* */ + /* <Note> */ + /* You can use @FT_Outline_Translate if you need to translate the */ + /* outline's points. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Transform( const FT_Outline* outline, + const FT_Matrix* matrix ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Embolden */ + /* */ + /* <Description> */ + /* Embolden an outline. The new outline will be at most 4~times */ + /* `strength' pixels wider and higher. You may think of the left and */ + /* bottom borders as unchanged. */ + /* */ + /* Negative `strength' values to reduce the outline thickness are */ + /* possible also. */ + /* */ + /* <InOut> */ + /* outline :: A handle to the target outline. */ + /* */ + /* <Input> */ + /* strength :: How strong the glyph is emboldened. Expressed in */ + /* 26.6 pixel format. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The used algorithm to increase or decrease the thickness of the */ + /* glyph doesn't change the number of points; this means that certain */ + /* situations like acute angles or intersections are sometimes */ + /* handled incorrectly. */ + /* */ + /* If you need `better' metrics values you should call */ + /* @FT_Outline_Get_CBox or @FT_Outline_Get_BBox. */ + /* */ + /* Example call: */ + /* */ + /* { */ + /* FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); */ + /* if ( face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) */ + /* FT_Outline_Embolden( &face->glyph->outline, strength ); */ + /* } */ + /* */ + /* To get meaningful results, font scaling values must be set with */ + /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Embolden( FT_Outline* outline, + FT_Pos strength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_EmboldenXY */ + /* */ + /* <Description> */ + /* Embolden an outline. The new outline will be `xstrength' pixels */ + /* wider and `ystrength' pixels higher. Otherwise, it is similar to */ + /* @FT_Outline_Embolden, which uses the same strength in both */ + /* directions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_EmboldenXY( FT_Outline* outline, + FT_Pos xstrength, + FT_Pos ystrength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Reverse */ + /* */ + /* <Description> */ + /* Reverse the drawing direction of an outline. This is used to */ + /* ensure consistent fill conventions for mirrored glyphs. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Note> */ + /* This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ + /* the outline's `flags' field. */ + /* */ + /* It shouldn't be used by a normal client application, unless it */ + /* knows what it is doing. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Reverse( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_Bitmap */ + /* */ + /* <Description> */ + /* Render an outline within a bitmap. The outline's image is simply */ + /* OR-ed to the target bitmap. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <InOut> */ + /* abitmap :: A pointer to the target bitmap descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function does NOT CREATE the bitmap, it only renders an */ + /* outline image within the one you pass to it! Consequently, the */ + /* various fields in `abitmap' should be set accordingly. */ + /* */ + /* It will use the raster corresponding to the default glyph format. */ + /* */ + /* The value of the `num_grays' field in `abitmap' is ignored. If */ + /* you select the gray-level rasterizer, and you want less than 256 */ + /* gray levels, you have to use @FT_Outline_Render directly. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_Bitmap( FT_Library library, + FT_Outline* outline, + const FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Render */ + /* */ + /* <Description> */ + /* Render an outline within a bitmap using the current scan-convert. */ + /* This function uses an @FT_Raster_Params structure as an argument, */ + /* allowing advanced features like direct composition, translucency, */ + /* etc. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <InOut> */ + /* params :: A pointer to an @FT_Raster_Params structure used to */ + /* describe the rendering operation. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You should know what you are doing and how @FT_Raster_Params works */ + /* to use this function. */ + /* */ + /* The field `params.source' will be set to `outline' before the scan */ + /* converter is called, which means that the value you give to it is */ + /* actually ignored. */ + /* */ + /* The gray-level rasterizer always uses 256 gray levels. If you */ + /* want less gray levels, you have to provide your own span callback. */ + /* See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the */ + /* @FT_Raster_Params structure for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Render( FT_Library library, + FT_Outline* outline, + FT_Raster_Params* params ); + + + /************************************************************************** + * + * @enum: + * FT_Orientation + * + * @description: + * A list of values used to describe an outline's contour orientation. + * + * The TrueType and PostScript specifications use different conventions + * to determine whether outline contours should be filled or unfilled. + * + * @values: + * FT_ORIENTATION_TRUETYPE :: + * According to the TrueType specification, clockwise contours must + * be filled, and counter-clockwise ones must be unfilled. + * + * FT_ORIENTATION_POSTSCRIPT :: + * According to the PostScript specification, counter-clockwise contours + * must be filled, and clockwise ones must be unfilled. + * + * FT_ORIENTATION_FILL_RIGHT :: + * This is identical to @FT_ORIENTATION_TRUETYPE, but is used to + * remember that in TrueType, everything that is to the right of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_FILL_LEFT :: + * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to + * remember that in PostScript, everything that is to the left of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_NONE :: + * The orientation cannot be determined. That is, different parts of + * the glyph have different orientation. + * + */ + typedef enum FT_Orientation_ + { + FT_ORIENTATION_TRUETYPE = 0, + FT_ORIENTATION_POSTSCRIPT = 1, + FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE, + FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT, + FT_ORIENTATION_NONE + + } FT_Orientation; + + + /************************************************************************** + * + * @function: + * FT_Outline_Get_Orientation + * + * @description: + * This function analyzes a glyph outline and tries to compute its + * fill orientation (see @FT_Orientation). This is done by integrating + * the total area covered by the outline. The positive integral + * corresponds to the clockwise orientation and @FT_ORIENTATION_POSTSCRIPT + * is returned. The negative integral corresponds to the counter-clockwise + * orientation and @FT_ORIENTATION_TRUETYPE is returned. + * + * Note that this will return @FT_ORIENTATION_TRUETYPE for empty + * outlines. + * + * @input: + * outline :: + * A handle to the source outline. + * + * @return: + * The orientation. + * + */ + FT_EXPORT( FT_Orientation ) + FT_Outline_Get_Orientation( FT_Outline* outline ); + + /* */ + + +FT_END_HEADER + +#endif /* FTOUTLN_H_ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftpfr.h b/builddir/freetype-2.7.0/include/freetype/ftpfr.h new file mode 100644 index 0000000..2e1bff2 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftpfr.h @@ -0,0 +1,172 @@ +/***************************************************************************/ +/* */ +/* ftpfr.h */ +/* */ +/* FreeType API for accessing PFR-specific data (specification only). */ +/* */ +/* Copyright 2002-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTPFR_H_ +#define FTPFR_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* pfr_fonts */ + /* */ + /* <Title> */ + /* PFR Fonts */ + /* */ + /* <Abstract> */ + /* PFR/TrueDoc specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of PFR-specific functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Metrics + * + * @description: + * Return the outline and metrics resolutions of a given PFR face. + * + * @input: + * face :: Handle to the input face. It can be a non-PFR face. + * + * @output: + * aoutline_resolution :: + * Outline resolution. This is equivalent to `face->units_per_EM' + * for non-PFR fonts. Optional (parameter can be NULL). + * + * ametrics_resolution :: + * Metrics resolution. This is equivalent to `outline_resolution' + * for non-PFR fonts. Optional (parameter can be NULL). + * + * ametrics_x_scale :: + * A 16.16 fixed-point number used to scale distance expressed + * in metrics units to device sub-pixels. This is equivalent to + * `face->size->x_scale', but for metrics only. Optional (parameter + * can be NULL). + * + * ametrics_y_scale :: + * Same as `ametrics_x_scale' but for the vertical direction. + * optional (parameter can be NULL). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If the input face is not a PFR, this function will return an error. + * However, in all cases, it will return valid values. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ); + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Kerning + * + * @description: + * Return the kerning pair corresponding to two glyphs in a PFR face. + * The distance is expressed in metrics units, unlike the result of + * @FT_Get_Kerning. + * + * @input: + * face :: A handle to the input face. + * + * left :: Index of the left glyph. + * + * right :: Index of the right glyph. + * + * @output: + * avector :: A kerning vector. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function always return distances in original PFR metrics + * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED + * mode, which always returns distances converted to outline units. + * + * You can use the value of the `x_scale' and `y_scale' parameters + * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Kerning( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Advance + * + * @description: + * Return a given glyph advance, expressed in original metrics units, + * from a PFR font. + * + * @input: + * face :: A handle to the input face. + * + * gindex :: The glyph index. + * + * @output: + * aadvance :: The glyph advance in metrics units. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics + * to convert the advance to device sub-pixels (i.e., 1/64th of pixels). + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + /* */ + + +FT_END_HEADER + +#endif /* FTPFR_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftrender.h b/builddir/freetype-2.7.0/include/freetype/ftrender.h new file mode 100644 index 0000000..9f7ed9e --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftrender.h @@ -0,0 +1,232 @@ +/***************************************************************************/ +/* */ +/* ftrender.h */ +/* */ +/* FreeType renderer modules public interface (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTRENDER_H_ +#define FTRENDER_H_ + + +#include <ft2build.h> +#include FT_MODULE_H +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /*************************************************************************/ + + + /* create a new glyph object */ + typedef FT_Error + (*FT_Glyph_InitFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + + /* destroys a given glyph object */ + typedef void + (*FT_Glyph_DoneFunc)( FT_Glyph glyph ); + + typedef void + (*FT_Glyph_TransformFunc)( FT_Glyph glyph, + const FT_Matrix* matrix, + const FT_Vector* delta ); + + typedef void + (*FT_Glyph_GetBBoxFunc)( FT_Glyph glyph, + FT_BBox* abbox ); + + typedef FT_Error + (*FT_Glyph_CopyFunc)( FT_Glyph source, + FT_Glyph target ); + + typedef FT_Error + (*FT_Glyph_PrepareFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + +/* deprecated */ +#define FT_Glyph_Init_Func FT_Glyph_InitFunc +#define FT_Glyph_Done_Func FT_Glyph_DoneFunc +#define FT_Glyph_Transform_Func FT_Glyph_TransformFunc +#define FT_Glyph_BBox_Func FT_Glyph_GetBBoxFunc +#define FT_Glyph_Copy_Func FT_Glyph_CopyFunc +#define FT_Glyph_Prepare_Func FT_Glyph_PrepareFunc + + + struct FT_Glyph_Class_ + { + FT_Long glyph_size; + FT_Glyph_Format glyph_format; + FT_Glyph_InitFunc glyph_init; + FT_Glyph_DoneFunc glyph_done; + FT_Glyph_CopyFunc glyph_copy; + FT_Glyph_TransformFunc glyph_transform; + FT_Glyph_GetBBoxFunc glyph_bbox; + FT_Glyph_PrepareFunc glyph_prepare; + }; + + + typedef FT_Error + (*FT_Renderer_RenderFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_UInt mode, + const FT_Vector* origin ); + + typedef FT_Error + (*FT_Renderer_TransformFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + const FT_Matrix* matrix, + const FT_Vector* delta ); + + + typedef void + (*FT_Renderer_GetCBoxFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_BBox* cbox ); + + + typedef FT_Error + (*FT_Renderer_SetModeFunc)( FT_Renderer renderer, + FT_ULong mode_tag, + FT_Pointer mode_ptr ); + +/* deprecated identifiers */ +#define FTRenderer_render FT_Renderer_RenderFunc +#define FTRenderer_transform FT_Renderer_TransformFunc +#define FTRenderer_getCBox FT_Renderer_GetCBoxFunc +#define FTRenderer_setMode FT_Renderer_SetModeFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Renderer_Class */ + /* */ + /* <Description> */ + /* The renderer module class descriptor. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Module_Class fields. */ + /* */ + /* glyph_format :: The glyph image format this renderer handles. */ + /* */ + /* render_glyph :: A method used to render the image that is in a */ + /* given glyph slot into a bitmap. */ + /* */ + /* transform_glyph :: A method used to transform the image that is in */ + /* a given glyph slot. */ + /* */ + /* get_glyph_cbox :: A method used to access the glyph's cbox. */ + /* */ + /* set_mode :: A method used to pass additional parameters. */ + /* */ + /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ + /* This is a pointer to its raster's class. */ + /* */ + typedef struct FT_Renderer_Class_ + { + FT_Module_Class root; + + FT_Glyph_Format glyph_format; + + FT_Renderer_RenderFunc render_glyph; + FT_Renderer_TransformFunc transform_glyph; + FT_Renderer_GetCBoxFunc get_glyph_cbox; + FT_Renderer_SetModeFunc set_mode; + + FT_Raster_Funcs* raster_class; + + } FT_Renderer_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Renderer */ + /* */ + /* <Description> */ + /* Retrieve the current renderer for a given glyph format. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* format :: The glyph format. */ + /* */ + /* <Return> */ + /* A renderer handle. 0~if none found. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + /* To add a new renderer, simply use @FT_Add_Module. To retrieve a */ + /* renderer by its name, use @FT_Get_Module. */ + /* */ + FT_EXPORT( FT_Renderer ) + FT_Get_Renderer( FT_Library library, + FT_Glyph_Format format ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Renderer */ + /* */ + /* <Description> */ + /* Set the current renderer to use, and set additional mode. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* renderer :: A handle to the renderer object. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* parameters :: Additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* In case of success, the renderer will be used to convert glyph */ + /* images in the renderer's known format into bitmaps. */ + /* */ + /* This doesn't change the current renderer for other formats. */ + /* */ + /* Currently, no FreeType renderer module uses `parameters'; you */ + /* should thus always pass NULL as the value. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Renderer( FT_Library library, + FT_Renderer renderer, + FT_UInt num_params, + FT_Parameter* parameters ); + + /* */ + + +FT_END_HEADER + +#endif /* FTRENDER_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftsizes.h b/builddir/freetype-2.7.0/include/freetype/ftsizes.h new file mode 100644 index 0000000..55e0d5c --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftsizes.h @@ -0,0 +1,159 @@ +/***************************************************************************/ +/* */ +/* ftsizes.h */ +/* */ +/* FreeType size objects management (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Typical application would normally not need to use these functions. */ + /* However, they have been placed in a public API for the rare cases */ + /* where they are needed. */ + /* */ + /*************************************************************************/ + + +#ifndef FTSIZES_H_ +#define FTSIZES_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sizes_management */ + /* */ + /* <Title> */ + /* Size Management */ + /* */ + /* <Abstract> */ + /* Managing multiple sizes per face. */ + /* */ + /* <Description> */ + /* When creating a new face object (e.g., with @FT_New_Face), an */ + /* @FT_Size object is automatically created and used to store all */ + /* pixel-size dependent information, available in the `face->size' */ + /* field. */ + /* */ + /* It is however possible to create more sizes for a given face, */ + /* mostly in order to manage several character pixel sizes of the */ + /* same font family and style. See @FT_New_Size and @FT_Done_Size. */ + /* */ + /* Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only */ + /* modify the contents of the current `active' size; you thus need */ + /* to use @FT_Activate_Size to change it. */ + /* */ + /* 99% of applications won't need the functions provided here, */ + /* especially if they use the caching sub-system, so be cautious */ + /* when using these. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Size */ + /* */ + /* <Description> */ + /* Create a new size object from a given face object. */ + /* */ + /* <Input> */ + /* face :: A handle to a parent face object. */ + /* */ + /* <Output> */ + /* asize :: A handle to a new size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You need to call @FT_Activate_Size in order to select the new size */ + /* for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size, */ + /* @FT_Load_Glyph, @FT_Load_Char, etc. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Size( FT_Face face, + FT_Size* size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Size */ + /* */ + /* <Description> */ + /* Discard a given size object. Note that @FT_Done_Face */ + /* automatically discards all size objects allocated with */ + /* @FT_New_Size. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Size( FT_Size size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Activate_Size */ + /* */ + /* <Description> */ + /* Even though it is possible to create several size objects for a */ + /* given face (see @FT_New_Size for details), functions like */ + /* @FT_Load_Glyph or @FT_Load_Char only use the one that has been */ + /* activated last to determine the `current character pixel size'. */ + /* */ + /* This function can be used to `activate' a previously created size */ + /* object. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If `face' is the size's parent face object, this function changes */ + /* the value of `face->size' to the input size handle. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Activate_Size( FT_Size size ); + + /* */ + + +FT_END_HEADER + +#endif /* FTSIZES_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftsnames.h b/builddir/freetype-2.7.0/include/freetype/ftsnames.h new file mode 100644 index 0000000..a7b51c2 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftsnames.h @@ -0,0 +1,200 @@ +/***************************************************************************/ +/* */ +/* ftsnames.h */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (specification). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTSNAMES_H_ +#define FTSNAMES_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sfnt_names */ + /* */ + /* <Title> */ + /* SFNT Names */ + /* */ + /* <Abstract> */ + /* Access the names embedded in TrueType and OpenType files. */ + /* */ + /* <Description> */ + /* The TrueType and OpenType specifications allow the inclusion of */ + /* a special `names table' in font files. This table contains */ + /* textual (and internationalized) information regarding the font, */ + /* like family name, copyright, version, etc. */ + /* */ + /* The definitions below are used to access them if available. */ + /* */ + /* Note that this has nothing to do with glyph names! */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SfntName */ + /* */ + /* <Description> */ + /* A structure used to model an SFNT `name' table entry. */ + /* */ + /* <Fields> */ + /* platform_id :: The platform ID for `string'. */ + /* */ + /* encoding_id :: The encoding ID for `string'. */ + /* */ + /* language_id :: The language ID for `string'. */ + /* */ + /* name_id :: An identifier for `string'. */ + /* */ + /* string :: The `name' string. Note that its format differs */ + /* depending on the (platform,encoding) pair. It can */ + /* be a Pascal String, a UTF-16 one, etc. */ + /* */ + /* Generally speaking, the string is not */ + /* zero-terminated. Please refer to the TrueType */ + /* specification for details. */ + /* */ + /* string_len :: The length of `string' in bytes. */ + /* */ + /* <Note> */ + /* Possible values for `platform_id', `encoding_id', `language_id', */ + /* and `name_id' are given in the file `ttnameid.h'. For details */ + /* please refer to the TrueType or OpenType specification. */ + /* */ + /* See also @TT_PLATFORM_XXX, @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX, */ + /* @TT_ISO_ID_XXX, and @TT_MS_ID_XXX. */ + /* */ + typedef struct FT_SfntName_ + { + FT_UShort platform_id; + FT_UShort encoding_id; + FT_UShort language_id; + FT_UShort name_id; + + FT_Byte* string; /* this string is *not* null-terminated! */ + FT_UInt string_len; /* in bytes */ + + } FT_SfntName; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name_Count */ + /* */ + /* <Description> */ + /* Retrieve the number of name strings in the SFNT `name' table. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Return> */ + /* The number of strings in the `name' table. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name */ + /* */ + /* <Description> */ + /* Retrieve a string of the SFNT `name' table for a given index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* idx :: The index of the `name' string. */ + /* */ + /* <Output> */ + /* aname :: The indexed @FT_SfntName structure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `string' array returned in the `aname' structure is not */ + /* null-terminated. The application should deallocate it if it is no */ + /* longer in use. */ + /* */ + /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ + /* `name' table entries, then do a loop until you get the right */ + /* platform, encoding, and name ID. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ); + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred family subfamily names in `name' + * table since OpenType version 1.4. For backwards compatibility with + * legacy systems that have a 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred subfamily names in `name' table since + * OpenType version 1.4. For backwards compatibility with legacy + * systems that have a 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG( 'i', 'g', 'p', 's' ) + + /* */ + + +FT_END_HEADER + +#endif /* FTSNAMES_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftstroke.h b/builddir/freetype-2.7.0/include/freetype/ftstroke.h new file mode 100644 index 0000000..b3b9922 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftstroke.h @@ -0,0 +1,785 @@ +/***************************************************************************/ +/* */ +/* ftstroke.h */ +/* */ +/* FreeType path stroker (specification). */ +/* */ +/* Copyright 2002-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTSTROKE_H_ +#define FTSTROKE_H_ + +#include <ft2build.h> +#include FT_OUTLINE_H +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /************************************************************************ + * + * @section: + * glyph_stroker + * + * @title: + * Glyph Stroker + * + * @abstract: + * Generating bordered and stroked glyphs. + * + * @description: + * This component generates stroked outlines of a given vectorial + * glyph. It also allows you to retrieve the `outside' and/or the + * `inside' borders of the stroke. + * + * This can be useful to generate `bordered' glyph, i.e., glyphs + * displayed with a coloured (and anti-aliased) border around their + * shape. + * + * @order: + * FT_Stroker + * + * FT_Stroker_LineJoin + * FT_Stroker_LineCap + * FT_StrokerBorder + * + * FT_Outline_GetInsideBorder + * FT_Outline_GetOutsideBorder + * + * FT_Glyph_Stroke + * FT_Glyph_StrokeBorder + * + * FT_Stroker_New + * FT_Stroker_Set + * FT_Stroker_Rewind + * FT_Stroker_ParseOutline + * FT_Stroker_Done + * + * FT_Stroker_BeginSubPath + * FT_Stroker_EndSubPath + * + * FT_Stroker_LineTo + * FT_Stroker_ConicTo + * FT_Stroker_CubicTo + * + * FT_Stroker_GetBorderCounts + * FT_Stroker_ExportBorder + * FT_Stroker_GetCounts + * FT_Stroker_Export + * + */ + + + /************************************************************** + * + * @type: + * FT_Stroker + * + * @description: + * Opaque handle to a path stroker object. + */ + typedef struct FT_StrokerRec_* FT_Stroker; + + + /************************************************************** + * + * @enum: + * FT_Stroker_LineJoin + * + * @description: + * These values determine how two joining lines are rendered + * in a stroker. + * + * @values: + * FT_STROKER_LINEJOIN_ROUND :: + * Used to render rounded line joins. Circular arcs are used + * to join two lines smoothly. + * + * FT_STROKER_LINEJOIN_BEVEL :: + * Used to render beveled line joins. The outer corner of + * the joined lines is filled by enclosing the triangular + * region of the corner with a straight line between the + * outer corners of each stroke. + * + * FT_STROKER_LINEJOIN_MITER_FIXED :: + * Used to render mitered line joins, with fixed bevels if the + * miter limit is exceeded. The outer edges of the strokes + * for the two segments are extended until they meet at an + * angle. If the segments meet at too sharp an angle (such + * that the miter would extend from the intersection of the + * segments a distance greater than the product of the miter + * limit value and the border radius), then a bevel join (see + * above) is used instead. This prevents long spikes being + * created. FT_STROKER_LINEJOIN_MITER_FIXED generates a miter + * line join as used in PostScript and PDF. + * + * FT_STROKER_LINEJOIN_MITER_VARIABLE :: + * FT_STROKER_LINEJOIN_MITER :: + * Used to render mitered line joins, with variable bevels if + * the miter limit is exceeded. The intersection of the + * strokes is clipped at a line perpendicular to the bisector + * of the angle between the strokes, at the distance from the + * intersection of the segments equal to the product of the + * miter limit value and the border radius. This prevents + * long spikes being created. + * FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line + * join as used in XPS. FT_STROKER_LINEJOIN_MITER is an alias + * for FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for + * backwards compatibility. + */ + typedef enum FT_Stroker_LineJoin_ + { + FT_STROKER_LINEJOIN_ROUND = 0, + FT_STROKER_LINEJOIN_BEVEL = 1, + FT_STROKER_LINEJOIN_MITER_VARIABLE = 2, + FT_STROKER_LINEJOIN_MITER = FT_STROKER_LINEJOIN_MITER_VARIABLE, + FT_STROKER_LINEJOIN_MITER_FIXED = 3 + + } FT_Stroker_LineJoin; + + + /************************************************************** + * + * @enum: + * FT_Stroker_LineCap + * + * @description: + * These values determine how the end of opened sub-paths are + * rendered in a stroke. + * + * @values: + * FT_STROKER_LINECAP_BUTT :: + * The end of lines is rendered as a full stop on the last + * point itself. + * + * FT_STROKER_LINECAP_ROUND :: + * The end of lines is rendered as a half-circle around the + * last point. + * + * FT_STROKER_LINECAP_SQUARE :: + * The end of lines is rendered as a square around the + * last point. + */ + typedef enum FT_Stroker_LineCap_ + { + FT_STROKER_LINECAP_BUTT = 0, + FT_STROKER_LINECAP_ROUND, + FT_STROKER_LINECAP_SQUARE + + } FT_Stroker_LineCap; + + + /************************************************************** + * + * @enum: + * FT_StrokerBorder + * + * @description: + * These values are used to select a given stroke border + * in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. + * + * @values: + * FT_STROKER_BORDER_LEFT :: + * Select the left border, relative to the drawing direction. + * + * FT_STROKER_BORDER_RIGHT :: + * Select the right border, relative to the drawing direction. + * + * @note: + * Applications are generally interested in the `inside' and `outside' + * borders. However, there is no direct mapping between these and the + * `left' and `right' ones, since this really depends on the glyph's + * drawing orientation, which varies between font formats. + * + * You can however use @FT_Outline_GetInsideBorder and + * @FT_Outline_GetOutsideBorder to get these. + */ + typedef enum FT_StrokerBorder_ + { + FT_STROKER_BORDER_LEFT = 0, + FT_STROKER_BORDER_RIGHT + + } FT_StrokerBorder; + + + /************************************************************** + * + * @function: + * FT_Outline_GetInsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `inside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_RIGHT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetInsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Outline_GetOutsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `outside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetOutsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_New + * + * @description: + * Create a new stroker object. + * + * @input: + * library :: + * FreeType library handle. + * + * @output: + * astroker :: + * A new stroker object handle. NULL in case of error. + * + * @return: + * FreeType error code. 0~means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_New( FT_Library library, + FT_Stroker *astroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Set + * + * @description: + * Reset a stroker object's attributes. + * + * @input: + * stroker :: + * The target stroker handle. + * + * radius :: + * The border radius. + * + * line_cap :: + * The line cap style. + * + * line_join :: + * The line join style. + * + * miter_limit :: + * The miter limit for the FT_STROKER_LINEJOIN_MITER_FIXED and + * FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles, + * expressed as 16.16 fixed-point value. + * + * @note: + * The radius is expressed in the same units as the outline + * coordinates. + * + * This function calls @FT_Stroker_Rewind automatically. + */ + FT_EXPORT( void ) + FT_Stroker_Set( FT_Stroker stroker, + FT_Fixed radius, + FT_Stroker_LineCap line_cap, + FT_Stroker_LineJoin line_join, + FT_Fixed miter_limit ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Rewind + * + * @description: + * Reset a stroker object without changing its attributes. + * You should call this function before beginning a new + * series of calls to @FT_Stroker_BeginSubPath or + * @FT_Stroker_EndSubPath. + * + * @input: + * stroker :: + * The target stroker handle. + */ + FT_EXPORT( void ) + FT_Stroker_Rewind( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ParseOutline + * + * @description: + * A convenience function used to parse a whole outline with + * the stroker. The resulting outline(s) can be retrieved + * later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The source outline. + * + * opened :: + * A boolean. If~1, the outline is treated as an open path instead + * of a closed one. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `opened' is~0 (the default), the outline is treated as a closed + * path, and the stroker generates two distinct `border' outlines. + * + * If `opened' is~1, the outline is processed as an open path, and the + * stroker generates a single `stroke' outline. + * + * This function calls @FT_Stroker_Rewind automatically. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ParseOutline( FT_Stroker stroker, + FT_Outline* outline, + FT_Bool opened ); + + + /************************************************************** + * + * @function: + * FT_Stroker_BeginSubPath + * + * @description: + * Start a new sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the start vector. + * + * open :: + * A boolean. If~1, the sub-path is treated as an open one. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function is useful when you need to stroke a path that is + * not stored as an @FT_Outline object. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_BeginSubPath( FT_Stroker stroker, + FT_Vector* to, + FT_Bool open ); + + + /************************************************************** + * + * @function: + * FT_Stroker_EndSubPath + * + * @description: + * Close the current sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function after @FT_Stroker_BeginSubPath. + * If the subpath was not `opened', this function `draws' a + * single line segment to the start position when needed. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_EndSubPath( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_LineTo + * + * @description: + * `Draw' a single line segment in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_LineTo( FT_Stroker stroker, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ConicTo + * + * @description: + * `Draw' a single quadratic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control :: + * A pointer to a Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ConicTo( FT_Stroker stroker, + FT_Vector* control, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_CubicTo + * + * @description: + * `Draw' a single cubic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control1 :: + * A pointer to the first Bézier control point. + * + * control2 :: + * A pointer to second Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_CubicTo( FT_Stroker stroker, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetBorderCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export one of the `border' or `stroke' + * outlines generated by the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right'. + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_GetCounts instead if you want to + * retrieve the counts associated to both borders. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetBorderCounts( FT_Stroker stroker, + FT_StrokerBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ExportBorder + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export the corresponding border to your own @FT_Outline + * structure. + * + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * outline :: + * The target outline handle. + * + * @note: + * Always call this function after @FT_Stroker_GetBorderCounts to + * get sure that there is enough room in your @FT_Outline object to + * receive all new data. + * + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right'. + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_Export instead if you want to + * retrieve all borders at once. + */ + FT_EXPORT( void ) + FT_Stroker_ExportBorder( FT_Stroker stroker, + FT_StrokerBorder border, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export all points/borders from the stroked + * outline/path. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0~means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetCounts( FT_Stroker stroker, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Export + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export all borders to your own @FT_Outline structure. + * + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The target outline handle. + */ + FT_EXPORT( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Done + * + * @description: + * Destroy a stroker object. + * + * @input: + * stroker :: + * A stroker handle. Can be NULL. + */ + FT_EXPORT( void ) + FT_Stroker_Done( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Glyph_Stroke + * + * @description: + * Stroke a given outline glyph object with a given stroker. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * destroy :: + * A Boolean. If~1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source glyph is untouched in case of error. + * + * Adding stroke may yield a significantly wider and taller glyph + * depending on how large of a radius was used to stroke the glyph. You + * may need to manually adjust horizontal and vertical advance amounts + * to account for this added size. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_Stroke( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool destroy ); + + + /************************************************************** + * + * @function: + * FT_Glyph_StrokeBorder + * + * @description: + * Stroke a given outline glyph object with a given stroker, but + * only return either its inside or outside border. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * inside :: + * A Boolean. If~1, return the inside border, otherwise + * the outside border. + * + * destroy :: + * A Boolean. If~1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source glyph is untouched in case of error. + * + * Adding stroke may yield a significantly wider and taller glyph + * depending on how large of a radius was used to stroke the glyph. You + * may need to manually adjust horizontal and vertical advance amounts + * to account for this added size. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_StrokeBorder( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool inside, + FT_Bool destroy ); + + /* */ + +FT_END_HEADER + +#endif /* FTSTROKE_H_ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftsynth.h b/builddir/freetype-2.7.0/include/freetype/ftsynth.h new file mode 100644 index 0000000..fdfcb69 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftsynth.h @@ -0,0 +1,84 @@ +/***************************************************************************/ +/* */ +/* ftsynth.h */ +/* */ +/* FreeType synthesizing code for emboldening and slanting */ +/* (specification). */ +/* */ +/* Copyright 2000-2016 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS ALPHA CODE! THIS API *********/ + /********* IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE *********/ + /********* FREETYPE DEVELOPMENT TEAM *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* Main reason for not lifting the functions in this module to a */ + /* `standard' API is that the used parameters for emboldening and */ + /* slanting are not configurable. Consider the functions as a */ + /* code resource that should be copied into the application and */ + /* adapted to the particular needs. */ + + +#ifndef FTSYNTH_H_ +#define FTSYNTH_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /* Embolden a glyph by a `reasonable' value (which is highly a matter of */ + /* taste). This function is actually a convenience function, providing */ + /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */ + /* */ + /* For emboldened outlines the height, width, and advance metrics are */ + /* increased by the strength of the emboldening -- this even affects */ + /* mono-width fonts! */ + /* */ + /* You can also call @FT_Outline_Get_CBox to get precise values. */ + FT_EXPORT( void ) + FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); + + /* Slant an outline glyph to the right by about 12 degrees. */ + FT_EXPORT( void ) + FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); + + /* */ + + +FT_END_HEADER + +#endif /* FTSYNTH_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftsystem.h b/builddir/freetype-2.7.0/include/freetype/ftsystem.h new file mode 100644 index 0000000..a75f958 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftsystem.h @@ -0,0 +1,355 @@ +/***************************************************************************/ +/* */ +/* ftsystem.h */ +/* */ +/* FreeType low-level system interface definition (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTSYSTEM_H_ +#define FTSYSTEM_H_ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* system_interface */ + /* */ + /* <Title> */ + /* System Interface */ + /* */ + /* <Abstract> */ + /* How FreeType manages memory and i/o. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to memory */ + /* management and i/o access. You need to understand this */ + /* information if you want to use a custom memory manager or you own */ + /* i/o streams. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* M E M O R Y M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Memory + * + * @description: + * A handle to a given memory manager object, defined with an + * @FT_MemoryRec structure. + * + */ + typedef struct FT_MemoryRec_* FT_Memory; + + + /************************************************************************* + * + * @functype: + * FT_Alloc_Func + * + * @description: + * A function used to allocate `size' bytes from `memory'. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * size :: + * The size in bytes to allocate. + * + * @return: + * Address of new memory block. 0~in case of failure. + * + */ + typedef void* + (*FT_Alloc_Func)( FT_Memory memory, + long size ); + + + /************************************************************************* + * + * @functype: + * FT_Free_Func + * + * @description: + * A function used to release a given block of memory. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * block :: + * The address of the target memory block. + * + */ + typedef void + (*FT_Free_Func)( FT_Memory memory, + void* block ); + + + /************************************************************************* + * + * @functype: + * FT_Realloc_Func + * + * @description: + * A function used to re-allocate a given block of memory. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * cur_size :: + * The block's current size in bytes. + * + * new_size :: + * The block's requested new size. + * + * block :: + * The block's current address. + * + * @return: + * New block address. 0~in case of memory shortage. + * + * @note: + * In case of error, the old block must still be available. + * + */ + typedef void* + (*FT_Realloc_Func)( FT_Memory memory, + long cur_size, + long new_size, + void* block ); + + + /************************************************************************* + * + * @struct: + * FT_MemoryRec + * + * @description: + * A structure used to describe a given memory manager to FreeType~2. + * + * @fields: + * user :: + * A generic typeless pointer for user data. + * + * alloc :: + * A pointer type to an allocation function. + * + * free :: + * A pointer type to an memory freeing function. + * + * realloc :: + * A pointer type to a reallocation function. + * + */ + struct FT_MemoryRec_ + { + void* user; + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + }; + + + /*************************************************************************/ + /* */ + /* I / O M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Stream + * + * @description: + * A handle to an input stream. + * + * @also: + * See @FT_StreamRec for the publicly accessible fields of a given + * stream object. + * + */ + typedef struct FT_StreamRec_* FT_Stream; + + + /************************************************************************* + * + * @struct: + * FT_StreamDesc + * + * @description: + * A union type used to store either a long or a pointer. This is used + * to store a file descriptor or a `FILE*' in an input stream. + * + */ + typedef union FT_StreamDesc_ + { + long value; + void* pointer; + + } FT_StreamDesc; + + + /************************************************************************* + * + * @functype: + * FT_Stream_IoFunc + * + * @description: + * A function used to seek and read data from a given input stream. + * + * @input: + * stream :: + * A handle to the source stream. + * + * offset :: + * The offset of read in stream (always from start). + * + * buffer :: + * The address of the read buffer. + * + * count :: + * The number of bytes to read from the stream. + * + * @return: + * The number of bytes effectively read by the stream. + * + * @note: + * This function might be called to perform a seek or skip operation + * with a `count' of~0. A non-zero return value then indicates an + * error. + * + */ + typedef unsigned long + (*FT_Stream_IoFunc)( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ); + + + /************************************************************************* + * + * @functype: + * FT_Stream_CloseFunc + * + * @description: + * A function used to close a given input stream. + * + * @input: + * stream :: + * A handle to the target stream. + * + */ + typedef void + (*FT_Stream_CloseFunc)( FT_Stream stream ); + + + /************************************************************************* + * + * @struct: + * FT_StreamRec + * + * @description: + * A structure used to describe an input stream. + * + * @input: + * base :: + * For memory-based streams, this is the address of the first stream + * byte in memory. This field should always be set to NULL for + * disk-based streams. + * + * size :: + * The stream size in bytes. + * + * In case of compressed streams where the size is unknown before + * actually doing the decompression, the value is set to 0x7FFFFFFF. + * (Note that this size value can occur for normal streams also; it is + * thus just a hint.) + * + * pos :: + * The current position within the stream. + * + * descriptor :: + * This field is a union that can hold an integer or a pointer. It is + * used by stream implementations to store file descriptors or `FILE*' + * pointers. + * + * pathname :: + * This field is completely ignored by FreeType. However, it is often + * useful during debugging to use it to store the stream's filename + * (where available). + * + * read :: + * The stream's input function. + * + * close :: + * The stream's close function. + * + * memory :: + * The memory manager to use to preload frames. This is set + * internally by FreeType and shouldn't be touched by stream + * implementations. + * + * cursor :: + * This field is set and used internally by FreeType when parsing + * frames. + * + * limit :: + * This field is set and used internally by FreeType when parsing + * frames. + * + */ + typedef struct FT_StreamRec_ + { + unsigned char* base; + unsigned long size; + unsigned long pos; + + FT_StreamDesc descriptor; + FT_StreamDesc pathname; + FT_Stream_IoFunc read; + FT_Stream_CloseFunc close; + + FT_Memory memory; + unsigned char* cursor; + unsigned char* limit; + + } FT_StreamRec; + + /* */ + + +FT_END_HEADER + +#endif /* FTSYSTEM_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/fttrigon.h b/builddir/freetype-2.7.0/include/freetype/fttrigon.h new file mode 100644 index 0000000..f789b52 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/fttrigon.h @@ -0,0 +1,350 @@ +/***************************************************************************/ +/* */ +/* fttrigon.h */ +/* */ +/* FreeType trigonometric functions (specification). */ +/* */ +/* Copyright 2001-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTTRIGON_H_ +#define FTTRIGON_H_ + +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Angle + * + * @description: + * This type is used to model angle values in FreeType. Note that the + * angle is a 16.16 fixed-point value expressed in degrees. + * + */ + typedef FT_Fixed FT_Angle; + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI + * + * @description: + * The angle pi expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI ( 180L << 16 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_2PI + * + * @description: + * The angle 2*pi expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_2PI ( FT_ANGLE_PI * 2 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI2 + * + * @description: + * The angle pi/2 expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI2 ( FT_ANGLE_PI / 2 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI4 + * + * @description: + * The angle pi/4 expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI4 ( FT_ANGLE_PI / 4 ) + + + /************************************************************************* + * + * @function: + * FT_Sin + * + * @description: + * Return the sinus of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The sinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @FT_Vector_Unit. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Sin( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Cos + * + * @description: + * Return the cosinus of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The cosinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @FT_Vector_Unit. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Cos( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Tan + * + * @description: + * Return the tangent of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The tangent value. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Tan( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Atan2 + * + * @description: + * Return the arc-tangent corresponding to a given vector (x,y) in + * the 2d plane. + * + * @input: + * x :: + * The horizontal vector coordinate. + * + * y :: + * The vertical vector coordinate. + * + * @return: + * The arc-tangent value (i.e. angle). + * + */ + FT_EXPORT( FT_Angle ) + FT_Atan2( FT_Fixed x, + FT_Fixed y ); + + + /************************************************************************* + * + * @function: + * FT_Angle_Diff + * + * @description: + * Return the difference between two angles. The result is always + * constrained to the ]-PI..PI] interval. + * + * @input: + * angle1 :: + * First angle. + * + * angle2 :: + * Second angle. + * + * @return: + * Constrained value of `value2-value1'. + * + */ + FT_EXPORT( FT_Angle ) + FT_Angle_Diff( FT_Angle angle1, + FT_Angle angle2 ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Unit + * + * @description: + * Return the unit vector corresponding to a given angle. After the + * call, the value of `vec.x' will be `cos(angle)', and the value of + * `vec.y' will be `sin(angle)'. + * + * This function is useful to retrieve both the sinus and cosinus of a + * given angle quickly. + * + * @output: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The input angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Unit( FT_Vector* vec, + FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Rotate + * + * @description: + * Rotate a vector by a given angle. + * + * @inout: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The input angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Rotate( FT_Vector* vec, + FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Length + * + * @description: + * Return the length of a given vector. + * + * @input: + * vec :: + * The address of target vector. + * + * @return: + * The vector length, expressed in the same units that the original + * vector coordinates. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Vector_Length( FT_Vector* vec ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Polarize + * + * @description: + * Compute both the length and angle of a given vector. + * + * @input: + * vec :: + * The address of source vector. + * + * @output: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Polarize( FT_Vector* vec, + FT_Fixed *length, + FT_Angle *angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_From_Polar + * + * @description: + * Compute vector coordinates from a length and angle. + * + * @output: + * vec :: + * The address of source vector. + * + * @input: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ + FT_EXPORT( void ) + FT_Vector_From_Polar( FT_Vector* vec, + FT_Fixed length, + FT_Angle angle ); + + /* */ + + +FT_END_HEADER + +#endif /* FTTRIGON_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftttdrv.h b/builddir/freetype-2.7.0/include/freetype/ftttdrv.h new file mode 100644 index 0000000..22186ee --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftttdrv.h @@ -0,0 +1,329 @@ +/***************************************************************************/ +/* */ +/* ftttdrv.h */ +/* */ +/* FreeType API for controlling the TrueType driver */ +/* (specification only). */ +/* */ +/* Copyright 2013-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTTTDRV_H_ +#define FTTTDRV_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * tt_driver + * + * @title: + * The TrueType driver + * + * @abstract: + * Controlling the TrueType driver module. + * + * @description: + * While FreeType's TrueType driver doesn't expose API functions by + * itself, it is possible to control its behaviour with @FT_Property_Set + * and @FT_Property_Get. The following lists the available properties + * together with the necessary macros and structures. + * + * The TrueType driver's module name is `truetype'. + * + * We start with a list of definitions, kindly provided by Greg + * Hitchcock. + * + * _Bi-Level_ _Rendering_ + * + * Monochromatic rendering, exclusively used in the early days of + * TrueType by both Apple and Microsoft. Microsoft's GDI interface + * supported hinting of the right-side bearing point, such that the + * advance width could be non-linear. Most often this was done to + * achieve some level of glyph symmetry. To enable reasonable + * performance (e.g., not having to run hinting on all glyphs just to + * get the widths) there was a bit in the head table indicating if the + * side bearing was hinted, and additional tables, `hdmx' and `LTSH', to + * cache hinting widths across multiple sizes and device aspect ratios. + * + * _Font_ _Smoothing_ + * + * Microsoft's GDI implementation of anti-aliasing. Not traditional + * anti-aliasing as the outlines were hinted before the sampling. The + * widths matched the bi-level rendering. + * + * _ClearType_ _Rendering_ + * + * Technique that uses physical subpixels to improve rendering on LCD + * (and other) displays. Because of the higher resolution, many methods + * of improving symmetry in glyphs through hinting the right-side + * bearing were no longer necessary. This lead to what GDI calls + * `natural widths' ClearType, see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec21. Since hinting + * has extra resolution, most non-linearity went away, but it is still + * possible for hints to change the advance widths in this mode. + * + * _ClearType_ _Compatible_ _Widths_ + * + * One of the earliest challenges with ClearType was allowing the + * implementation in GDI to be selected without requiring all UI and + * documents to reflow. To address this, a compatible method of + * rendering ClearType was added where the font hints are executed once + * to determine the width in bi-level rendering, and then re-run in + * ClearType, with the difference in widths being absorbed in the font + * hints for ClearType (mostly in the white space of hints); see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec20. Somewhat by + * definition, compatible width ClearType allows for non-linear widths, + * but only when the bi-level version has non-linear widths. + * + * _ClearType_ _Subpixel_ _Positioning_ + * + * One of the nice benefits of ClearType is the ability to more crisply + * display fractional widths; unfortunately, the GDI model of integer + * bitmaps did not support this. However, the WPF and Direct Write + * frameworks do support fractional widths. DWrite calls this `natural + * mode', not to be confused with GDI's `natural widths'. Subpixel + * positioning, in the current implementation of Direct Write, + * unfortunately does not support hinted advance widths, see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec22. Note that the + * TrueType interpreter fully allows the advance width to be adjusted in + * this mode, just the DWrite client will ignore those changes. + * + * _ClearType_ _Backwards_ _Compatibility_ + * + * This is a set of exceptions made in the TrueType interpreter to + * minimize hinting techniques that were problematic with the extra + * resolution of ClearType; see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec1 and + * http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx. + * This technique is not to be confused with ClearType compatible + * widths. ClearType backwards compatibility has no direct impact on + * changing advance widths, but there might be an indirect impact on + * disabling some deltas. This could be worked around in backwards + * compatibility mode. + * + * _Native_ _ClearType_ _Mode_ + * + * (Not to be confused with `natural widths'.) This mode removes all + * the exceptions in the TrueType interpreter when running with + * ClearType. Any issues on widths would still apply, though. + * + */ + + + /************************************************************************** + * + * @property: + * interpreter-version + * + * @description: + + * Currently, three versions are available, two representing the + * bytecode interpreter with subpixel hinting support (old `Infinality' + * code and new stripped-down and higher performance `minimal' code) and + * one without, respectively. The default is subpixel support if + * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel support + * otherwise (since it isn't available then). + * + * If subpixel hinting is on, many TrueType bytecode instructions behave + * differently compared to B/W or grayscale rendering (except if `native + * ClearType' is selected by the font). Microsoft's main idea is to + * render at a much increased horizontal resolution, then sampling down + * the created output to subpixel precision. However, many older fonts + * are not suited to this and must be specially taken care of by + * applying (hardcoded) tweaks in Microsoft's interpreter. + * + * Details on subpixel hinting and some of the necessary tweaks can be + * found in Greg Hitchcock's whitepaper at + * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. + * Note that FreeType currently doesn't really `subpixel hint' (6x1, 6x2, + * or 6x5 supersampling) like discussed in the paper. Depending on the + * chosen interpreter, it simply ignores instructions on vertical stems + * to arrive at very similar results. + * + * The following example code demonstrates how to deactivate subpixel + * hinting (omitting the error handling). + * + * { + * FT_Library library; + * FT_Face face; + * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_35; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "truetype", + * "interpreter-version", + * &interpreter_version ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values `35', `38', or `40'). + */ + + + /************************************************************************** + * + * @enum: + * TT_INTERPRETER_VERSION_XXX + * + * @description: + * A list of constants used for the @interpreter-version property to + * select the hinting engine for Truetype fonts. + * + * The numeric value in the constant names represents the version + * number as returned by the `GETINFO' bytecode instruction. + * + * @values: + * TT_INTERPRETER_VERSION_35 :: + * Version~35 corresponds to MS rasterizer v.1.7 as used e.g. in + * Windows~98; only grayscale and B/W rasterizing is supported. + * + * TT_INTERPRETER_VERSION_38 :: + * Version~38 corresponds to MS rasterizer v.1.9; it is roughly + * equivalent to the hinting provided by DirectWrite ClearType (as can + * be found, for example, in the Internet Explorer~9 running on + * Windows~7). It is used in FreeType to select the `Infinality' + * subpixel hinting code. The code may be removed in a future + * version. + * + * TT_INTERPRETER_VERSION_40 :: + * Version~40 corresponds to MS rasterizer v.2.1; it is roughly + * equivalent to the hinting provided by DirectWrite ClearType (as can + * be found, for example, in Microsoft's Edge Browser on Windows~10). + * It is used in FreeType to select the `minimal' subpixel hinting + * code, a stripped-down and higher performance version of the + * `Infinality' code. + * + * @note: + * This property controls the behaviour of the bytecode interpreter + * and thus how outlines get hinted. It does *not* control how glyph + * get rasterized! In particular, it does not control subpixel color + * filtering. + * + * If FreeType has not been compiled with the configuration option + * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 or~40 causes + * an `FT_Err_Unimplemented_Feature' error. + * + * Depending on the graphics framework, Microsoft uses different + * bytecode and rendering engines. As a consequence, the version + * numbers returned by a call to the `GETINFO' bytecode instruction are + * more convoluted than desired. + * + * Here are two tables that try to shed some light on the possible + * values for the MS rasterizer engine, together with the additional + * features introduced by it. + * + * { + * GETINFO framework version feature + * ------------------------------------------------------------------- + * 3 GDI (Win 3.1), v1.0 16-bit, first version + * TrueImage + * 33 GDI (Win NT 3.1), v1.5 32-bit + * HP Laserjet + * 34 GDI (Win 95) v1.6 font smoothing, + * new SCANTYPE opcode + * 35 GDI (Win 98/2000) v1.7 (UN)SCALED_COMPONENT_OFFSET + * bits in composite glyphs + * 36 MGDI (Win CE 2) v1.6+ classic ClearType + * 37 GDI (XP and later), v1.8 ClearType + * GDI+ old (before Vista) + * 38 GDI+ old (Vista, Win 7), v1.9 subpixel ClearType, + * WPF Y-direction ClearType, + * additional error checking + * 39 DWrite (before Win 8) v2.0 subpixel ClearType flags + * in GETINFO opcode, + * bug fixes + * 40 GDI+ (after Win 7), v2.1 Y-direction ClearType flag + * DWrite (Win 8) in GETINFO opcode, + * Gray ClearType + * } + * + * The `version' field gives a rough orientation only, since some + * applications provided certain features much earlier (as an example, + * Microsoft Reader used subpixel and Y-direction ClearType already in + * Windows 2000). Similarly, updates to a given framework might include + * improved hinting support. + * + * { + * version sampling rendering comment + * x y x y + * -------------------------------------------------------------- + * v1.0 normal normal B/W B/W bi-level + * v1.6 high high gray gray grayscale + * v1.8 high normal color-filter B/W (GDI) ClearType + * v1.9 high high color-filter gray Color ClearType + * v2.1 high normal gray B/W Gray ClearType + * v2.1 high high gray gray Gray ClearType + * } + * + * Color and Gray ClearType are the two available variants of + * `Y-direction ClearType', meaning grayscale rasterization along the + * Y-direction; the name used in the TrueType specification for this + * feature is `symmetric smoothing'. `Classic ClearType' is the + * original algorithm used before introducing a modified version in + * Win~XP. Another name for v1.6's grayscale rendering is `font + * smoothing', and `Color ClearType' is sometimes also called `DWrite + * ClearType'. To differentiate between today's Color ClearType and the + * earlier ClearType variant with B/W rendering along the vertical axis, + * the latter is sometimes called `GDI ClearType'. + * + * `Normal' and `high' sampling describe the (virtual) resolution to + * access the rasterized outline after the hinting process. `Normal' + * means 1 sample per grid line (i.e., B/W). In the current Microsoft + * implementation, `high' means an extra virtual resolution of 16x16 (or + * 16x1) grid lines per pixel for bytecode instructions like `MIRP'. + * After hinting, these 16 grid lines are mapped to 6x5 (or 6x1) grid + * lines for color filtering if Color ClearType is activated. + * + * Note that `Gray ClearType' is essentially the same as v1.6's + * grayscale rendering. However, the GETINFO instruction handles it + * differently: v1.6 returns bit~12 (hinting for grayscale), while v2.1 + * returns bits~13 (hinting for ClearType), 18 (symmetrical smoothing), + * and~19 (Gray ClearType). Also, this mode respects bits 2 and~3 for + * the version~1 gasp table exclusively (like Color ClearType), while + * v1.6 only respects the values of version~0 (bits 0 and~1). + * + * Keep in mind that the features of the above interpreter versions + * might not map exactly to FreeType features or behavior because it is + * a fundamentally different library with different internals. + * + */ +#define TT_INTERPRETER_VERSION_35 35 +#define TT_INTERPRETER_VERSION_38 38 +#define TT_INTERPRETER_VERSION_40 40 + + /* */ + + +FT_END_HEADER + + +#endif /* FTTTDRV_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/fttypes.h b/builddir/freetype-2.7.0/include/freetype/fttypes.h new file mode 100644 index 0000000..2673e79 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/fttypes.h @@ -0,0 +1,602 @@ +/***************************************************************************/ +/* */ +/* fttypes.h */ +/* */ +/* FreeType simple types definitions (specification only). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTTYPES_H_ +#define FTTYPES_H_ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_SYSTEM_H +#include FT_IMAGE_H + +#include <stddef.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /* <Title> */ + /* Basic Data Types */ + /* */ + /* <Abstract> */ + /* The basic data types defined by the library. */ + /* */ + /* <Description> */ + /* This section contains the basic data types defined by FreeType~2, */ + /* ranging from simple scalar types to bitmap descriptors. More */ + /* font-specific structures are defined in a different section. */ + /* */ + /* <Order> */ + /* FT_Byte */ + /* FT_Bytes */ + /* FT_Char */ + /* FT_Int */ + /* FT_UInt */ + /* FT_Int16 */ + /* FT_UInt16 */ + /* FT_Int32 */ + /* FT_UInt32 */ + /* FT_Int64 */ + /* FT_UInt64 */ + /* FT_Short */ + /* FT_UShort */ + /* FT_Long */ + /* FT_ULong */ + /* FT_Bool */ + /* FT_Offset */ + /* FT_PtrDist */ + /* FT_String */ + /* FT_Tag */ + /* FT_Error */ + /* FT_Fixed */ + /* FT_Pointer */ + /* FT_Pos */ + /* FT_Vector */ + /* FT_BBox */ + /* FT_Matrix */ + /* FT_FWord */ + /* FT_UFWord */ + /* FT_F2Dot14 */ + /* FT_UnitVector */ + /* FT_F26Dot6 */ + /* FT_Data */ + /* */ + /* FT_MAKE_TAG */ + /* */ + /* FT_Generic */ + /* FT_Generic_Finalizer */ + /* */ + /* FT_Bitmap */ + /* FT_Pixel_Mode */ + /* FT_Palette_Mode */ + /* FT_Glyph_Format */ + /* FT_IMAGE_TAG */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bool */ + /* */ + /* <Description> */ + /* A typedef of unsigned char, used for simple booleans. As usual, */ + /* values 1 and~0 represent true and false, respectively. */ + /* */ + typedef unsigned char FT_Bool; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_FWord */ + /* */ + /* <Description> */ + /* A signed 16-bit integer used to store a distance in original font */ + /* units. */ + /* */ + typedef signed short FT_FWord; /* distance in FUnits */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UFWord */ + /* */ + /* <Description> */ + /* An unsigned 16-bit integer used to store a distance in original */ + /* font units. */ + /* */ + typedef unsigned short FT_UFWord; /* unsigned distance */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Char */ + /* */ + /* <Description> */ + /* A simple typedef for the _signed_ char type. */ + /* */ + typedef signed char FT_Char; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Byte */ + /* */ + /* <Description> */ + /* A simple typedef for the _unsigned_ char type. */ + /* */ + typedef unsigned char FT_Byte; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bytes */ + /* */ + /* <Description> */ + /* A typedef for constant memory areas. */ + /* */ + typedef const FT_Byte* FT_Bytes; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Tag */ + /* */ + /* <Description> */ + /* A typedef for 32-bit tags (as used in the SFNT format). */ + /* */ + typedef FT_UInt32 FT_Tag; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_String */ + /* */ + /* <Description> */ + /* A simple typedef for the char type, usually used for strings. */ + /* */ + typedef char FT_String; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Short */ + /* */ + /* <Description> */ + /* A typedef for signed short. */ + /* */ + typedef signed short FT_Short; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UShort */ + /* */ + /* <Description> */ + /* A typedef for unsigned short. */ + /* */ + typedef unsigned short FT_UShort; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Int */ + /* */ + /* <Description> */ + /* A typedef for the int type. */ + /* */ + typedef signed int FT_Int; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UInt */ + /* */ + /* <Description> */ + /* A typedef for the unsigned int type. */ + /* */ + typedef unsigned int FT_UInt; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Long */ + /* */ + /* <Description> */ + /* A typedef for signed long. */ + /* */ + typedef signed long FT_Long; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ULong */ + /* */ + /* <Description> */ + /* A typedef for unsigned long. */ + /* */ + typedef unsigned long FT_ULong; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F2Dot14 */ + /* */ + /* <Description> */ + /* A signed 2.14 fixed-point type used for unit vectors. */ + /* */ + typedef signed short FT_F2Dot14; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F26Dot6 */ + /* */ + /* <Description> */ + /* A signed 26.6 fixed-point type used for vectorial pixel */ + /* coordinates. */ + /* */ + typedef signed long FT_F26Dot6; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Fixed */ + /* */ + /* <Description> */ + /* This type is used to store 16.16 fixed-point values, like scaling */ + /* values or matrix coefficients. */ + /* */ + typedef signed long FT_Fixed; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Error */ + /* */ + /* <Description> */ + /* The FreeType error code type. A value of~0 is always interpreted */ + /* as a successful operation. */ + /* */ + typedef int FT_Error; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pointer */ + /* */ + /* <Description> */ + /* A simple typedef for a typeless pointer. */ + /* */ + typedef void* FT_Pointer; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Offset */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI~C `size_t' type, i.e., the largest */ + /* _unsigned_ integer type used to express a file size or position, */ + /* or a memory block size. */ + /* */ + typedef size_t FT_Offset; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_PtrDist */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the */ + /* largest _signed_ integer type used to express the distance */ + /* between two pointers. */ + /* */ + typedef ft_ptrdiff_t FT_PtrDist; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_UnitVector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector unit vector. Uses */ + /* FT_F2Dot14 types. */ + /* */ + /* <Fields> */ + /* x :: Horizontal coordinate. */ + /* */ + /* y :: Vertical coordinate. */ + /* */ + typedef struct FT_UnitVector_ + { + FT_F2Dot14 x; + FT_F2Dot14 y; + + } FT_UnitVector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Matrix */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2x2 matrix. Coefficients are */ + /* in 16.16 fixed-point format. The computation performed is: */ + /* */ + /* { */ + /* x' = x*xx + y*xy */ + /* y' = x*yx + y*yy */ + /* } */ + /* */ + /* <Fields> */ + /* xx :: Matrix coefficient. */ + /* */ + /* xy :: Matrix coefficient. */ + /* */ + /* yx :: Matrix coefficient. */ + /* */ + /* yy :: Matrix coefficient. */ + /* */ + typedef struct FT_Matrix_ + { + FT_Fixed xx, xy; + FT_Fixed yx, yy; + + } FT_Matrix; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Data */ + /* */ + /* <Description> */ + /* Read-only binary data represented as a pointer and a length. */ + /* */ + /* <Fields> */ + /* pointer :: The data. */ + /* */ + /* length :: The length of the data in bytes. */ + /* */ + typedef struct FT_Data_ + { + const FT_Byte* pointer; + FT_Int length; + + } FT_Data; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Generic_Finalizer */ + /* */ + /* <Description> */ + /* Describe a function used to destroy the `client' data of any */ + /* FreeType object. See the description of the @FT_Generic type for */ + /* details of usage. */ + /* */ + /* <Input> */ + /* The address of the FreeType object that is under finalization. */ + /* Its client data is accessed through its `generic' field. */ + /* */ + typedef void (*FT_Generic_Finalizer)(void* object); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Generic */ + /* */ + /* <Description> */ + /* Client applications often need to associate their own data to a */ + /* variety of FreeType core objects. For example, a text layout API */ + /* might want to associate a glyph cache to a given size object. */ + /* */ + /* Some FreeType object contains a `generic' field, of type */ + /* FT_Generic, which usage is left to client applications and font */ + /* servers. */ + /* */ + /* It can be used to store a pointer to client-specific data, as well */ + /* as the address of a `finalizer' function, which will be called by */ + /* FreeType when the object is destroyed (for example, the previous */ + /* client example would put the address of the glyph cache destructor */ + /* in the `finalizer' field). */ + /* */ + /* <Fields> */ + /* data :: A typeless pointer to any client-specified data. This */ + /* field is completely ignored by the FreeType library. */ + /* */ + /* finalizer :: A pointer to a `generic finalizer' function, which */ + /* will be called when the object is destroyed. If this */ + /* field is set to NULL, no code will be called. */ + /* */ + typedef struct FT_Generic_ + { + void* data; + FT_Generic_Finalizer finalizer; + + } FT_Generic; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_MAKE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags that are used to label */ + /* TrueType tables into an unsigned long, to be used within FreeType. */ + /* */ + /* <Note> */ + /* The produced values *must* be 32-bit integers. Don't redefine */ + /* this macro. */ + /* */ +#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + (FT_Tag) \ + ( ( (FT_ULong)_x1 << 24 ) | \ + ( (FT_ULong)_x2 << 16 ) | \ + ( (FT_ULong)_x3 << 8 ) | \ + (FT_ULong)_x4 ) + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* L I S T M A N A G E M E N T */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ListNode */ + /* */ + /* <Description> */ + /* Many elements and objects in FreeType are listed through an */ + /* @FT_List record (see @FT_ListRec). As its name suggests, an */ + /* FT_ListNode is a handle to a single list element. */ + /* */ + typedef struct FT_ListNodeRec_* FT_ListNode; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_List */ + /* */ + /* <Description> */ + /* A handle to a list record (see @FT_ListRec). */ + /* */ + typedef struct FT_ListRec_* FT_List; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListNodeRec */ + /* */ + /* <Description> */ + /* A structure used to hold a single list element. */ + /* */ + /* <Fields> */ + /* prev :: The previous element in the list. NULL if first. */ + /* */ + /* next :: The next element in the list. NULL if last. */ + /* */ + /* data :: A typeless pointer to the listed object. */ + /* */ + typedef struct FT_ListNodeRec_ + { + FT_ListNode prev; + FT_ListNode next; + void* data; + + } FT_ListNodeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListRec */ + /* */ + /* <Description> */ + /* A structure used to hold a simple doubly-linked list. These are */ + /* used in many parts of FreeType. */ + /* */ + /* <Fields> */ + /* head :: The head (first element) of doubly-linked list. */ + /* */ + /* tail :: The tail (last element) of doubly-linked list. */ + /* */ + typedef struct FT_ListRec_ + { + FT_ListNode head; + FT_ListNode tail; + + } FT_ListRec; + + /* */ + + +#define FT_IS_EMPTY( list ) ( (list).head == 0 ) +#define FT_BOOL( x ) ( (FT_Bool)( x ) ) + + /* concatenate C tokens */ +#define FT_ERR_XCAT( x, y ) x ## y +#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) + + /* see `ftmoderr.h' for descriptions of the following macros */ + +#define FT_ERR( e ) FT_ERR_CAT( FT_ERR_PREFIX, e ) + +#define FT_ERROR_BASE( x ) ( (x) & 0xFF ) +#define FT_ERROR_MODULE( x ) ( (x) & 0xFF00U ) + +#define FT_ERR_EQ( x, e ) \ + ( FT_ERROR_BASE( x ) == FT_ERROR_BASE( FT_ERR( e ) ) ) +#define FT_ERR_NEQ( x, e ) \ + ( FT_ERROR_BASE( x ) != FT_ERROR_BASE( FT_ERR( e ) ) ) + + +FT_END_HEADER + +#endif /* FTTYPES_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ftwinfnt.h b/builddir/freetype-2.7.0/include/freetype/ftwinfnt.h new file mode 100644 index 0000000..a1a715b --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ftwinfnt.h @@ -0,0 +1,275 @@ +/***************************************************************************/ +/* */ +/* ftwinfnt.h */ +/* */ +/* FreeType API for accessing Windows fnt-specific data. */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTWINFNT_H_ +#define FTWINFNT_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* winfnt_fonts */ + /* */ + /* <Title> */ + /* Window FNT Files */ + /* */ + /* <Abstract> */ + /* Windows FNT specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Windows FNT specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @enum: + * FT_WinFNT_ID_XXX + * + * @description: + * A list of valid values for the `charset' byte in + * @FT_WinFNT_HeaderRec. Exact mapping tables for the various cpXXXX + * encodings (except for cp1361) can be found at + * ftp://ftp.unicode.org/Public in the MAPPINGS/VENDORS/MICSFT/WINDOWS + * subdirectory. cp1361 is roughly a superset of + * MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. + * + * @values: + * FT_WinFNT_ID_DEFAULT :: + * This is used for font enumeration and font creation as a + * `don't care' value. Valid font files don't contain this value. + * When querying for information about the character set of the font + * that is currently selected into a specified device context, this + * return value (of the related Windows API) simply denotes failure. + * + * FT_WinFNT_ID_SYMBOL :: + * There is no known mapping table available. + * + * FT_WinFNT_ID_MAC :: + * Mac Roman encoding. + * + * FT_WinFNT_ID_OEM :: + * From Michael Pöttgen <michael@poettgen.de>: + * + * The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM + * is used for the charset of vector fonts, like `modern.fon', + * `roman.fon', and `script.fon' on Windows. + * + * The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value + * specifies a character set that is operating-system dependent. + * + * The `IFIMETRICS' documentation from the `Windows Driver + * Development Kit' says: This font supports an OEM-specific + * character set. The OEM character set is system dependent. + * + * In general OEM, as opposed to ANSI (i.e., cp1252), denotes the + * second default codepage that most international versions of + * Windows have. It is one of the OEM codepages from + * + * https://msdn.microsoft.com/en-us/goglobal/bb964655, + * + * and is used for the `DOS boxes', to support legacy applications. + * A German Windows version for example usually uses ANSI codepage + * 1252 and OEM codepage 850. + * + * FT_WinFNT_ID_CP874 :: + * A superset of Thai TIS 620 and ISO 8859-11. + * + * FT_WinFNT_ID_CP932 :: + * A superset of Japanese Shift-JIS (with minor deviations). + * + * FT_WinFNT_ID_CP936 :: + * A superset of simplified Chinese GB 2312-1980 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP949 :: + * A superset of Korean Hangul KS~C 5601-1987 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP950 :: + * A superset of traditional Chinese Big~5 ETen (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP1250 :: + * A superset of East European ISO 8859-2 (with slightly different + * ordering). + * + * FT_WinFNT_ID_CP1251 :: + * A superset of Russian ISO 8859-5 (with different ordering). + * + * FT_WinFNT_ID_CP1252 :: + * ANSI encoding. A superset of ISO 8859-1. + * + * FT_WinFNT_ID_CP1253 :: + * A superset of Greek ISO 8859-7 (with minor modifications). + * + * FT_WinFNT_ID_CP1254 :: + * A superset of Turkish ISO 8859-9. + * + * FT_WinFNT_ID_CP1255 :: + * A superset of Hebrew ISO 8859-8 (with some modifications). + * + * FT_WinFNT_ID_CP1256 :: + * A superset of Arabic ISO 8859-6 (with different ordering). + * + * FT_WinFNT_ID_CP1257 :: + * A superset of Baltic ISO 8859-13 (with some deviations). + * + * FT_WinFNT_ID_CP1258 :: + * For Vietnamese. This encoding doesn't cover all necessary + * characters. + * + * FT_WinFNT_ID_CP1361 :: + * Korean (Johab). + */ + +#define FT_WinFNT_ID_CP1252 0 +#define FT_WinFNT_ID_DEFAULT 1 +#define FT_WinFNT_ID_SYMBOL 2 +#define FT_WinFNT_ID_MAC 77 +#define FT_WinFNT_ID_CP932 128 +#define FT_WinFNT_ID_CP949 129 +#define FT_WinFNT_ID_CP1361 130 +#define FT_WinFNT_ID_CP936 134 +#define FT_WinFNT_ID_CP950 136 +#define FT_WinFNT_ID_CP1253 161 +#define FT_WinFNT_ID_CP1254 162 +#define FT_WinFNT_ID_CP1258 163 +#define FT_WinFNT_ID_CP1255 177 +#define FT_WinFNT_ID_CP1256 178 +#define FT_WinFNT_ID_CP1257 186 +#define FT_WinFNT_ID_CP1251 204 +#define FT_WinFNT_ID_CP874 222 +#define FT_WinFNT_ID_CP1250 238 +#define FT_WinFNT_ID_OEM 255 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_HeaderRec */ + /* */ + /* <Description> */ + /* Windows FNT Header info. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_ + { + FT_UShort version; + FT_ULong file_size; + FT_Byte copyright[60]; + FT_UShort file_type; + FT_UShort nominal_point_size; + FT_UShort vertical_resolution; + FT_UShort horizontal_resolution; + FT_UShort ascent; + FT_UShort internal_leading; + FT_UShort external_leading; + FT_Byte italic; + FT_Byte underline; + FT_Byte strike_out; + FT_UShort weight; + FT_Byte charset; + FT_UShort pixel_width; + FT_UShort pixel_height; + FT_Byte pitch_and_family; + FT_UShort avg_width; + FT_UShort max_width; + FT_Byte first_char; + FT_Byte last_char; + FT_Byte default_char; + FT_Byte break_char; + FT_UShort bytes_per_row; + FT_ULong device_offset; + FT_ULong face_name_offset; + FT_ULong bits_pointer; + FT_ULong bits_offset; + FT_Byte reserved; + FT_ULong flags; + FT_UShort A_space; + FT_UShort B_space; + FT_UShort C_space; + FT_UShort color_table_offset; + FT_ULong reserved1[4]; + + } FT_WinFNT_HeaderRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_Header */ + /* */ + /* <Description> */ + /* A handle to an @FT_WinFNT_HeaderRec structure. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_* FT_WinFNT_Header; + + + /********************************************************************** + * + * @function: + * FT_Get_WinFNT_Header + * + * @description: + * Retrieve a Windows FNT font info header. + * + * @input: + * face :: A handle to the input face. + * + * @output: + * aheader :: The WinFNT header. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with Windows FNT faces, returning an error + * otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *aheader ); + + /* */ + + +FT_END_HEADER + +#endif /* FTWINFNT_H_ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/autohint.h b/builddir/freetype-2.7.0/include/freetype/internal/autohint.h new file mode 100644 index 0000000..7ef82b8 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/autohint.h @@ -0,0 +1,244 @@ +/***************************************************************************/ +/* */ +/* autohint.h */ +/* */ +/* High-level `autohint' module-specific interface (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The auto-hinter is used to load and automatically hint glyphs if a */ + /* format-specific hinter isn't available. */ + /* */ + /*************************************************************************/ + + +#ifndef AUTOHINT_H_ +#define AUTOHINT_H_ + + + /*************************************************************************/ + /* */ + /* A small technical note regarding automatic hinting in order to */ + /* clarify this module interface. */ + /* */ + /* An automatic hinter might compute two kinds of data for a given face: */ + /* */ + /* - global hints: Usually some metrics that describe global properties */ + /* of the face. It is computed by scanning more or less */ + /* aggressively the glyphs in the face, and thus can be */ + /* very slow to compute (even if the size of global */ + /* hints is really small). */ + /* */ + /* - glyph hints: These describe some important features of the glyph */ + /* outline, as well as how to align them. They are */ + /* generally much faster to compute than global hints. */ + /* */ + /* The current FreeType auto-hinter does a pretty good job while */ + /* performing fast computations for both global and glyph hints. */ + /* However, we might be interested in introducing more complex and */ + /* powerful algorithms in the future, like the one described in the John */ + /* D. Hobby paper, which unfortunately requires a lot more horsepower. */ + /* */ + /* Because a sufficiently sophisticated font management system would */ + /* typically implement an LRU cache of opened face objects to reduce */ + /* memory usage, it is a good idea to be able to avoid recomputing */ + /* global hints every time the same face is re-opened. */ + /* */ + /* We thus provide the ability to cache global hints outside of the face */ + /* object, in order to speed up font re-opening time. Of course, this */ + /* feature is purely optional, so most client programs won't even notice */ + /* it. */ + /* */ + /* I initially thought that it would be a good idea to cache the glyph */ + /* hints too. However, my general idea now is that if you really need */ + /* to cache these too, you are simply in need of a new font format, */ + /* where all this information could be stored within the font file and */ + /* decoded on the fly. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef struct FT_AutoHinterRec_ *FT_AutoHinter; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalGetFunc */ + /* */ + /* <Description> */ + /* Retrieve the global hints computed for a given face object. The */ + /* resulting data is dissociated from the face and will survive a */ + /* call to FT_Done_Face(). It must be discarded through the API */ + /* FT_AutoHinter_GlobalDoneFunc(). */ + /* */ + /* <Input> */ + /* hinter :: A handle to the source auto-hinter. */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* <Output> */ + /* global_hints :: A typeless pointer to the global hints. */ + /* */ + /* global_len :: The size in bytes of the global hints. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalGetFunc)( FT_AutoHinter hinter, + FT_Face face, + void** global_hints, + long* global_len ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalDoneFunc */ + /* */ + /* <Description> */ + /* Discard the global hints retrieved through */ + /* FT_AutoHinter_GlobalGetFunc(). This is the only way these hints */ + /* are freed from memory. */ + /* */ + /* <Input> */ + /* hinter :: A handle to the auto-hinter module. */ + /* */ + /* global :: A pointer to retrieved global hints to discard. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalDoneFunc)( FT_AutoHinter hinter, + void* global ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalResetFunc */ + /* */ + /* <Description> */ + /* This function is used to recompute the global metrics in a given */ + /* font. This is useful when global font data changes (e.g. Multiple */ + /* Masters fonts where blend coordinates change). */ + /* */ + /* <Input> */ + /* hinter :: A handle to the source auto-hinter. */ + /* */ + /* face :: A handle to the face. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalResetFunc)( FT_AutoHinter hinter, + FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlyphLoadFunc */ + /* */ + /* <Description> */ + /* This function is used to load, scale, and automatically hint a */ + /* glyph from a given face. */ + /* */ + /* <Input> */ + /* face :: A handle to the face. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* load_flags :: The load flags. */ + /* */ + /* <Note> */ + /* This function is capable of loading composite glyphs by hinting */ + /* each sub-glyph independently (which improves quality). */ + /* */ + /* It will call the font driver with @FT_Load_Glyph, with */ + /* @FT_LOAD_NO_SCALE set. */ + /* */ + typedef FT_Error + (*FT_AutoHinter_GlyphLoadFunc)( FT_AutoHinter hinter, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_AutoHinter_InterfaceRec */ + /* */ + /* <Description> */ + /* The auto-hinter module's interface. */ + /* */ + typedef struct FT_AutoHinter_InterfaceRec_ + { + FT_AutoHinter_GlobalResetFunc reset_face; + FT_AutoHinter_GlobalGetFunc get_global_hints; + FT_AutoHinter_GlobalDoneFunc done_global_hints; + FT_AutoHinter_GlyphLoadFunc load_glyph; + + } FT_AutoHinter_InterfaceRec, *FT_AutoHinter_Interface; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_AUTOHINTER_INTERFACE( \ + class_, \ + reset_face_, \ + get_global_hints_, \ + done_global_hints_, \ + load_glyph_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_AutoHinter_InterfaceRec class_ = \ + { \ + reset_face_, \ + get_global_hints_, \ + done_global_hints_, \ + load_glyph_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_AUTOHINTER_INTERFACE( \ + class_, \ + reset_face_, \ + get_global_hints_, \ + done_global_hints_, \ + load_glyph_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_AutoHinter_InterfaceRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->reset_face = reset_face_; \ + clazz->get_global_hints = get_global_hints_; \ + clazz->done_global_hints = done_global_hints_; \ + clazz->load_glyph = load_glyph_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* AUTOHINT_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/ftcalc.h b/builddir/freetype-2.7.0/include/freetype/internal/ftcalc.h new file mode 100644 index 0000000..8a884f6 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/ftcalc.h @@ -0,0 +1,418 @@ +/***************************************************************************/ +/* */ +/* ftcalc.h */ +/* */ +/* Arithmetic computations (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTCALC_H_ +#define FTCALC_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ + /* */ + /*************************************************************************/ + +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER + /* Provide assembler fragments for performance-critical functions. */ + /* These must be defined `static __inline__' with GCC. */ + +#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ + +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 t, t2; + + + __asm + { + smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ + mov a, t, asr #31 /* a = (hi >> 31) */ + add a, a, #0x8000 /* a += 0x8000 */ + adds t2, t2, a /* t2 += a */ + adc t, t, #0 /* t += carry */ + mov a, t2, lsr #16 /* a = t2 >> 16 */ + orr a, a, t, lsl #16 /* a |= t << 16 */ + } + return a; + } + +#endif /* __CC_ARM || __ARMCC__ */ + + +#ifdef __GNUC__ + +#if defined( __arm__ ) && \ + ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \ + !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 t, t2; + + + __asm__ __volatile__ ( + "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ + "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ +#if defined( __clang__ ) && defined( __thumb2__ ) + "add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ +#else + "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ +#endif + "adds %1, %1, %0\n\t" /* %1 += %0 */ + "adc %2, %2, #0\n\t" /* %2 += carry */ + "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ + "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ + : "=r"(a), "=&r"(t2), "=&r"(t) + : "r"(a), "r"(b) + : "cc" ); + return a; + } + +#endif /* __arm__ && */ + /* ( __thumb2__ || !__thumb__ ) && */ + /* !( __CC_ARM || __ARMCC__ ) */ + + +#if defined( __i386__ ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 result; + + + __asm__ __volatile__ ( + "imul %%edx\n" + "movl %%edx, %%ecx\n" + "sarl $31, %%ecx\n" + "addl $0x8000, %%ecx\n" + "addl %%ecx, %%eax\n" + "adcl $0, %%edx\n" + "shrl $16, %%eax\n" + "shll $16, %%edx\n" + "addl %%edx, %%eax\n" + : "=a"(result), "=d"(b) + : "a"(a), "d"(b) + : "%ecx", "cc" ); + return result; + } + +#endif /* i386 */ + +#endif /* __GNUC__ */ + + +#ifdef _MSC_VER /* Visual C++ */ + +#ifdef _M_IX86 + +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + FT_Int32 result; + + __asm + { + mov eax, a + mov edx, b + imul edx + mov ecx, edx + sar ecx, 31 + add ecx, 8000h + add eax, ecx + adc edx, 0 + shr eax, 16 + shl edx, 16 + add eax, edx + mov result, eax + } + return result; + } + +#endif /* _M_IX86 */ + +#endif /* _MSC_VER */ + + +#if defined( __GNUC__ ) && defined( __x86_64__ ) + +#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64 + + static __inline__ FT_Int32 + FT_MulFix_x86_64( FT_Int32 a, + FT_Int32 b ) + { + /* Temporarily disable the warning that C90 doesn't support */ + /* `long long'. */ +#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlong-long" +#endif + +#if 1 + /* Technically not an assembly fragment, but GCC does a really good */ + /* job at inlining it and generating good machine code for it. */ + long long ret, tmp; + + + ret = (long long)a * b; + tmp = ret >> 63; + ret += 0x8000 + tmp; + + return (FT_Int32)( ret >> 16 ); +#else + + /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */ + /* code from the lines below. The main issue is that `wide_a' is not */ + /* properly initialized by sign-extending `a'. Instead, the generated */ + /* machine code assumes that the register that contains `a' on input */ + /* can be used directly as a 64-bit value, which is wrong most of the */ + /* time. */ + long long wide_a = (long long)a; + long long wide_b = (long long)b; + long long result; + + + __asm__ __volatile__ ( + "imul %2, %1\n" + "mov %1, %0\n" + "sar $63, %0\n" + "lea 0x8000(%1, %0), %0\n" + "sar $16, %0\n" + : "=&r"(result), "=&r"(wide_a) + : "r"(wide_b) + : "cc" ); + + return (FT_Int32)result; +#endif + +#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 ) +#pragma GCC diagnostic pop +#endif + } + +#endif /* __GNUC__ && __x86_64__ */ + +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + + +#ifdef FT_CONFIG_OPTION_INLINE_MULFIX +#ifdef FT_MULFIX_ASSEMBLER +#define FT_MulFix( a, b ) FT_MULFIX_ASSEMBLER( (FT_Int32)(a), (FT_Int32)(b) ) +#endif +#endif + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulDiv_No_Round */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation `(a*b)/c' */ + /* (without rounding) with maximum accuracy (it uses a 64-bit */ + /* intermediate integer whenever necessary). */ + /* */ + /* This function isn't necessarily as fast as some processor specific */ + /* operations, but is at least completely portable. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. */ + /* c :: The divisor. */ + /* */ + /* <Return> */ + /* The result of `(a*b)/c'. This function never traps when trying to */ + /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ + /* on the signs of `a' and `b'. */ + /* */ + FT_BASE( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ); + + + /* + * A variant of FT_Matrix_Multiply which scales its result afterwards. + * The idea is that both `a' and `b' are scaled by factors of 10 so that + * the values are as precise as possible to get a correct result during + * the 64bit multiplication. Let `sa' and `sb' be the scaling factors of + * `a' and `b', respectively, then the scaling factor of the result is + * `sa*sb'. + */ + FT_BASE( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ); + + + /* + * A variant of FT_Vector_Transform. See comments for + * FT_Matrix_Multiply_Scaled. + */ + FT_BASE( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ); + + + /* + * This function normalizes a vector and returns its original length. + * The normalized vector is a 16.16 fixed-point unit vector with length + * close to 0x10000. The accuracy of the returned length is limited to + * 16 bits also. The function utilizes quick inverse square root + * approximation without divisions and square roots relying on Newton's + * iterations instead. + */ + FT_BASE( FT_UInt32 ) + FT_Vector_NormLen( FT_Vector* vector ); + + + /* + * Return -1, 0, or +1, depending on the orientation of a given corner. + * We use the Cartesian coordinate system, with positive vertical values + * going upwards. The function returns +1 if the corner turns to the + * left, -1 to the right, and 0 for undecidable cases. + */ + FT_BASE( FT_Int ) + ft_corner_orientation( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ); + + + /* + * Return TRUE if a corner is flat or nearly flat. This is equivalent to + * saying that the corner point is close to its neighbors, or inside an + * ellipse defined by the neighbor focal points to be more precise. + */ + FT_BASE( FT_Int ) + ft_corner_is_flat( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ); + + + /* + * Return the most significant bit index. + */ + +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER +#if defined( __GNUC__ ) && \ + ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) ) + +#if FT_SIZEOF_INT == 4 + +#define FT_MSB( x ) ( 31 - __builtin_clz( x ) ) + +#elif FT_SIZEOF_LONG == 4 + +#define FT_MSB( x ) ( 31 - __builtin_clzl( x ) ) + +#endif + +#endif /* __GNUC__ */ +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + +#ifndef FT_MSB + + FT_BASE( FT_Int ) + FT_MSB( FT_UInt32 z ); + +#endif + + + /* + * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses + * two fixed-point arguments instead. + */ + FT_BASE( FT_Fixed ) + FT_Hypot( FT_Fixed x, + FT_Fixed y ); + + +#if 0 + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_SqrtFixed */ + /* */ + /* <Description> */ + /* Computes the square root of a 16.16 fixed-point value. */ + /* */ + /* <Input> */ + /* x :: The value to compute the root for. */ + /* */ + /* <Return> */ + /* The result of `sqrt(x)'. */ + /* */ + /* <Note> */ + /* This function is not very fast. */ + /* */ + FT_BASE( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ); + +#endif /* 0 */ + + +#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) +#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) +#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) +#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) +#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) +#define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 ) + +#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ + : ( -( ( 32 - (x) ) & -64 ) ) ) + + +FT_END_HEADER + +#endif /* FTCALC_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/ftdebug.h b/builddir/freetype-2.7.0/include/freetype/internal/ftdebug.h new file mode 100644 index 0000000..d110457 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/ftdebug.h @@ -0,0 +1,255 @@ +/***************************************************************************/ +/* */ +/* ftdebug.h */ +/* */ +/* Debugging and logging component (specification). */ +/* */ +/* Copyright 1996-2016 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 and FT_THROW macros. The call to `FT_Throw' */ + /* makes it possible to easily set a breakpoint at this function. */ + /* */ + /*************************************************************************/ + +#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 ) + +#define FT_THROW( e ) \ + ( FT_Throw( FT_ERR_CAT( FT_ERR_PREFIX, e ), \ + __LINE__, \ + __FILE__ ) | \ + FT_ERR_CAT( FT_ERR_PREFIX, e ) ) + +#else /* !FT_DEBUG_LEVEL_ERROR */ + +#define FT_ASSERT( condition ) do { } while ( 0 ) + +#define FT_THROW( e ) FT_ERR_CAT( FT_ERR_PREFIX, e ) + +#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, + ... ); + + /* report file name and line number of an error */ + FT_BASE( int ) + FT_Throw( FT_Error error, + int line, + const char* file ); + +#endif /* FT_DEBUG_LEVEL_ERROR */ + + + FT_BASE( void ) + ft_debug_init( void ); + +FT_END_HEADER + +#endif /* FTDEBUG_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/ftdriver.h b/builddir/freetype-2.7.0/include/freetype/internal/ftdriver.h new file mode 100644 index 0000000..902f02f --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/ftdriver.h @@ -0,0 +1,400 @@ +/***************************************************************************/ +/* */ +/* ftdriver.h */ +/* */ +/* FreeType font driver interface (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTDRIVER_H_ +#define FTDRIVER_H_ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + typedef FT_Error + (*FT_Face_InitFunc)( FT_Stream stream, + FT_Face face, + FT_Int typeface_index, + FT_Int num_params, + FT_Parameter* parameters ); + + typedef void + (*FT_Face_DoneFunc)( FT_Face face ); + + + typedef FT_Error + (*FT_Size_InitFunc)( FT_Size size ); + + typedef void + (*FT_Size_DoneFunc)( FT_Size size ); + + + typedef FT_Error + (*FT_Slot_InitFunc)( FT_GlyphSlot slot ); + + typedef void + (*FT_Slot_DoneFunc)( FT_GlyphSlot slot ); + + + typedef FT_Error + (*FT_Size_RequestFunc)( FT_Size size, + FT_Size_Request req ); + + typedef FT_Error + (*FT_Size_SelectFunc)( FT_Size size, + FT_ULong size_index ); + + typedef FT_Error + (*FT_Slot_LoadFunc)( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + typedef FT_Error + (*FT_Face_GetKerningFunc)( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ); + + + typedef FT_Error + (*FT_Face_AttachFunc)( FT_Face face, + FT_Stream stream ); + + + typedef FT_Error + (*FT_Face_GetAdvancesFunc)( FT_Face face, + FT_UInt first, + FT_UInt count, + FT_Int32 flags, + FT_Fixed* advances ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Driver_ClassRec */ + /* */ + /* <Description> */ + /* The font driver class. This structure mostly contains pointers to */ + /* driver methods. */ + /* */ + /* <Fields> */ + /* root :: The parent module. */ + /* */ + /* face_object_size :: The size of a face object in bytes. */ + /* */ + /* size_object_size :: The size of a size object in bytes. */ + /* */ + /* slot_object_size :: The size of a glyph object in bytes. */ + /* */ + /* init_face :: The format-specific face constructor. */ + /* */ + /* done_face :: The format-specific face destructor. */ + /* */ + /* init_size :: The format-specific size constructor. */ + /* */ + /* done_size :: The format-specific size destructor. */ + /* */ + /* init_slot :: The format-specific slot constructor. */ + /* */ + /* done_slot :: The format-specific slot destructor. */ + /* */ + /* */ + /* load_glyph :: A function handle to load a glyph to a slot. */ + /* This field is mandatory! */ + /* */ + /* get_kerning :: A function handle to return the unscaled */ + /* kerning for a given pair of glyphs. Can be */ + /* set to 0 if the format doesn't support */ + /* kerning. */ + /* */ + /* attach_file :: This function handle is used to read */ + /* additional data for a face from another */ + /* file/stream. For example, this can be used to */ + /* add data from AFM or PFM files on a Type 1 */ + /* face, or a CIDMap on a CID-keyed face. */ + /* */ + /* get_advances :: A function handle used to return advance */ + /* widths of `count' glyphs (in font units), */ + /* starting at `first'. The `vertical' flag must */ + /* be set to get vertical advance heights. The */ + /* `advances' buffer is caller-allocated. */ + /* The idea of this function is to be able to */ + /* perform device-independent text layout without */ + /* loading a single glyph image. */ + /* */ + /* request_size :: A handle to a function used to request the new */ + /* character size. Can be set to 0 if the */ + /* scaling done in the base layer suffices. */ + /* */ + /* select_size :: A handle to a function used to select a new */ + /* fixed size. It is used only if */ + /* @FT_FACE_FLAG_FIXED_SIZES is set. Can be set */ + /* to 0 if the scaling done in the base layer */ + /* suffices. */ + /* <Note> */ + /* Most function pointers, with the exception of `load_glyph', can be */ + /* set to 0 to indicate a default behaviour. */ + /* */ + typedef struct FT_Driver_ClassRec_ + { + FT_Module_Class root; + + FT_Long face_object_size; + FT_Long size_object_size; + FT_Long slot_object_size; + + FT_Face_InitFunc init_face; + FT_Face_DoneFunc done_face; + + FT_Size_InitFunc init_size; + FT_Size_DoneFunc done_size; + + FT_Slot_InitFunc init_slot; + FT_Slot_DoneFunc done_slot; + + FT_Slot_LoadFunc load_glyph; + + FT_Face_GetKerningFunc get_kerning; + FT_Face_AttachFunc attach_file; + FT_Face_GetAdvancesFunc get_advances; + + /* since version 2.2 */ + FT_Size_RequestFunc request_size; + FT_Size_SelectFunc select_size; + + } FT_Driver_ClassRec, *FT_Driver_Class; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_DRIVER */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of an FT_Driver_ClassRec */ + /* struct instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_DRIVER */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Driver_ClassRec struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function has to be */ + /* called with a pointer where the allocated structure is returned. */ + /* And when it is no longer needed a `destroy' function needs to be */ + /* called to release that allocation. */ + /* */ + /* `ftinit.c' (ft_create_default_module_classes) already contains a */ + /* mechanism to call these functions for the default modules */ + /* described in `ftmodule.h'. */ + /* */ + /* Notice that the created `create' and `destroy' functions call */ + /* `pic_init' and `pic_free' to allow you to manually allocate and */ + /* initialize any additional global data, like a module specific */ + /* interface, and put them in the global pic container defined in */ + /* `ftpic.h'. If you don't need them just implement the functions as */ + /* empty to resolve the link error. Also the `pic_init' and */ + /* `pic_free' functions should be declared in `pic.h', to be referred */ + /* by driver definition calling `FT_DEFINE_DRIVER' in following. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro is */ + /* used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_DRIVER( class_ ) \ + FT_CALLBACK_TABLE \ + const FT_Driver_ClassRec class_; + +#define FT_DEFINE_DRIVER( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_, \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + init_face_, \ + done_face_, \ + init_size_, \ + done_size_, \ + init_slot_, \ + done_slot_, \ + load_glyph_, \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + request_size_, \ + select_size_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Driver_ClassRec class_ = \ + { \ + FT_DEFINE_ROOT_MODULE( flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + \ + init_face_, \ + done_face_, \ + \ + init_size_, \ + done_size_, \ + \ + init_slot_, \ + done_slot_, \ + \ + load_glyph_, \ + \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + \ + request_size_, \ + select_size_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_DRIVER( class_ ) FT_DECLARE_MODULE( class_ ) + +#define FT_DEFINE_DRIVER( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_, \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + init_face_, \ + done_face_, \ + init_size_, \ + done_size_, \ + init_slot_, \ + done_slot_, \ + load_glyph_, \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + request_size_, \ + select_size_ ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + FT_Driver_Class dclazz = (FT_Driver_Class)clazz; \ + \ + \ + class_ ## _pic_free( library ); \ + if ( dclazz ) \ + FT_FREE( dclazz ); \ + } \ + \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Driver_Class clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ + return error; \ + \ + error = class_ ## _pic_init( library ); \ + if ( error ) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + FT_DEFINE_ROOT_MODULE( flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + \ + clazz->face_object_size = face_object_size_; \ + clazz->size_object_size = size_object_size_; \ + clazz->slot_object_size = slot_object_size_; \ + \ + clazz->init_face = init_face_; \ + clazz->done_face = done_face_; \ + \ + clazz->init_size = init_size_; \ + clazz->done_size = done_size_; \ + \ + clazz->init_slot = init_slot_; \ + clazz->done_slot = done_slot_; \ + \ + clazz->load_glyph = load_glyph_; \ + \ + clazz->get_kerning = get_kerning_; \ + clazz->attach_file = attach_file_; \ + clazz->get_advances = get_advances_; \ + \ + clazz->request_size = request_size_; \ + clazz->select_size = select_size_; \ + \ + *output_class = (FT_Module_Class*)clazz; \ + \ + return FT_Err_Ok; \ + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* FTDRIVER_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/ftgloadr.h b/builddir/freetype-2.7.0/include/freetype/internal/ftgloadr.h new file mode 100644 index 0000000..bebf5db --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/ftgloadr.h @@ -0,0 +1,154 @@ +/***************************************************************************/ +/* */ +/* ftgloadr.h */ +/* */ +/* The FreeType glyph loader (specification). */ +/* */ +/* Copyright 2002-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTGLOADR_H_ +#define FTGLOADR_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphLoader */ + /* */ + /* <Description> */ + /* The glyph loader is an internal object used to load several glyphs */ + /* together (for example, in the case of composites). */ + /* */ + typedef struct FT_SubGlyphRec_ + { + FT_Int index; + FT_UShort flags; + FT_Int arg1; + FT_Int arg2; + FT_Matrix transform; + + } FT_SubGlyphRec; + + + typedef struct FT_GlyphLoadRec_ + { + FT_Outline outline; /* outline */ + FT_Vector* extra_points; /* extra points table */ + FT_Vector* extra_points2; /* second extra points table */ + FT_UInt num_subglyphs; /* number of subglyphs */ + FT_SubGlyph subglyphs; /* subglyphs */ + + } FT_GlyphLoadRec, *FT_GlyphLoad; + + + typedef struct FT_GlyphLoaderRec_ + { + FT_Memory memory; + FT_UInt max_points; + FT_UInt max_contours; + FT_UInt max_subglyphs; + FT_Bool use_extra; + + FT_GlyphLoadRec base; + FT_GlyphLoadRec current; + + void* other; /* for possible future extension? */ + + } FT_GlyphLoaderRec, *FT_GlyphLoader; + + + /* create new empty glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_New( FT_Memory memory, + FT_GlyphLoader *aloader ); + + /* add an extra points table to a glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ); + + /* destroy a glyph loader */ + FT_BASE( void ) + FT_GlyphLoader_Done( FT_GlyphLoader loader ); + + /* reset a glyph loader (frees everything int it) */ + FT_BASE( void ) + FT_GlyphLoader_Reset( FT_GlyphLoader loader ); + + /* rewind a glyph loader */ + FT_BASE( void ) + FT_GlyphLoader_Rewind( FT_GlyphLoader loader ); + + /* check that there is enough space to add `n_points' and `n_contours' */ + /* to the glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, + FT_UInt n_points, + FT_UInt n_contours ); + + +#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ + ( (_count) == 0 || \ + ( (FT_UInt)(_loader)->base.outline.n_points + \ + (FT_UInt)(_loader)->current.outline.n_points + \ + (FT_UInt)(_count) ) <= (_loader)->max_points ) + +#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ + ( (_count) == 0 || \ + ( (FT_UInt)(_loader)->base.outline.n_contours + \ + (FT_UInt)(_loader)->current.outline.n_contours + \ + (FT_UInt)(_count) ) <= (_loader)->max_contours ) + +#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points, _contours ) \ + ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ + FT_GLYPHLOADER_CHECK_C( _loader, _contours ) ) \ + ? 0 \ + : FT_GlyphLoader_CheckPoints( (_loader), \ + (FT_UInt)(_points), \ + (FT_UInt)(_contours) ) ) + + + /* check that there is enough space to add `n_subs' sub-glyphs to */ + /* a glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, + FT_UInt n_subs ); + + /* prepare a glyph loader, i.e. empty the current glyph */ + FT_BASE( void ) + FT_GlyphLoader_Prepare( FT_GlyphLoader loader ); + + /* add the current glyph to the base glyph */ + FT_BASE( void ) + FT_GlyphLoader_Add( FT_GlyphLoader loader ); + + /* copy points from one glyph loader to another */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, + FT_GlyphLoader source ); + + /* */ + + +FT_END_HEADER + +#endif /* FTGLOADR_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/fthash.h b/builddir/freetype-2.7.0/include/freetype/internal/fthash.h new file mode 100644 index 0000000..f22f9d5 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/fthash.h @@ -0,0 +1,136 @@ +/***************************************************************************/ +/* */ +/* fthash.h */ +/* */ +/* Hashing functions (specification). */ +/* */ +/***************************************************************************/ + +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2015 + * Francesco Zappa Nardelli + * + * 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 COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY 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. + */ + + /*************************************************************************/ + /* */ + /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#ifndef FTHASH_H_ +#define FTHASH_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef union FT_Hashkey_ + { + FT_Int num; + const char* str; + + } FT_Hashkey; + + + typedef struct FT_HashnodeRec_ + { + FT_Hashkey key; + size_t data; + + } FT_HashnodeRec; + + typedef struct FT_HashnodeRec_ *FT_Hashnode; + + + typedef FT_ULong + (*FT_Hash_LookupFunc)( FT_Hashkey* key ); + + typedef FT_Bool + (*FT_Hash_CompareFunc)( FT_Hashkey* a, + FT_Hashkey* b ); + + + typedef struct FT_HashRec_ + { + FT_UInt limit; + FT_UInt size; + FT_UInt used; + + FT_Hash_LookupFunc lookup; + FT_Hash_CompareFunc compare; + + FT_Hashnode* table; + + } FT_HashRec; + + typedef struct FT_HashRec_ *FT_Hash; + + + FT_Error + ft_hash_str_init( FT_Hash hash, + FT_Memory memory ); + + FT_Error + ft_hash_num_init( FT_Hash hash, + FT_Memory memory ); + + void + ft_hash_str_free( FT_Hash hash, + FT_Memory memory ); + +#define ft_hash_num_free ft_hash_str_free + + FT_Error + ft_hash_str_insert( const char* key, + size_t data, + FT_Hash hash, + FT_Memory memory ); + + FT_Error + ft_hash_num_insert( FT_Int num, + size_t data, + FT_Hash hash, + FT_Memory memory ); + + size_t* + ft_hash_str_lookup( const char* key, + FT_Hash hash ); + + size_t* + ft_hash_num_lookup( FT_Int num, + FT_Hash hash ); + + +FT_END_HEADER + + +#endif /* FTHASH_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/ftmemory.h b/builddir/freetype-2.7.0/include/freetype/internal/ftmemory.h new file mode 100644 index 0000000..fc33b2f --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/ftmemory.h @@ -0,0 +1,393 @@ +/***************************************************************************/ +/* */ +/* ftmemory.h */ +/* */ +/* The FreeType memory management macros (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTMEMORY_H_ +#define FTMEMORY_H_ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_SET_ERROR */ + /* */ + /* <Description> */ + /* This macro is used to set an implicit `error' variable to a given */ + /* expression's value (usually a function call), and convert it to a */ + /* boolean which is set whenever the value is != 0. */ + /* */ +#undef FT_SET_ERROR +#define FT_SET_ERROR( expression ) \ + ( ( error = (expression) ) != 0 ) + + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M E M O R Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* + * C++ refuses to handle statements like p = (void*)anything, with `p' a + * typed pointer. Since we don't have a `typeof' operator in standard + * C++, we have to use a template to emulate it. + */ + +#ifdef __cplusplus + +extern "C++" +{ + template <typename T> inline T* + cplusplus_typeof( T*, + void *v ) + { + return static_cast <T*> ( v ); + } +} + +#define FT_ASSIGNP( p, val ) (p) = cplusplus_typeof( (p), (val) ) + +#else + +#define FT_ASSIGNP( p, val ) (p) = (val) + +#endif + + + +#ifdef FT_DEBUG_MEMORY + + FT_BASE( const char* ) _ft_debug_file; + FT_BASE( long ) _ft_debug_lineno; + +#define FT_DEBUG_INNER( exp ) ( _ft_debug_file = __FILE__, \ + _ft_debug_lineno = __LINE__, \ + (exp) ) + +#define FT_ASSIGNP_INNER( p, exp ) ( _ft_debug_file = __FILE__, \ + _ft_debug_lineno = __LINE__, \ + FT_ASSIGNP( p, exp ) ) + +#else /* !FT_DEBUG_MEMORY */ + +#define FT_DEBUG_INNER( exp ) (exp) +#define FT_ASSIGNP_INNER( p, exp ) FT_ASSIGNP( p, exp ) + +#endif /* !FT_DEBUG_MEMORY */ + + + /* + * The allocation functions return a pointer, and the error code + * is written to through the `p_error' parameter. + */ + + /* The `q' variants of the functions below (`q' for `quick') don't fill */ + /* the allocated or reallocated memory with zero bytes. */ + + FT_BASE( FT_Pointer ) + ft_mem_alloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_qalloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_realloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_qrealloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ); + + FT_BASE( void ) + ft_mem_free( FT_Memory memory, + const void* P ); + + + /* The `Q' variants of the macros below (`Q' for `quick') don't fill */ + /* the allocated or reallocated memory with zero bytes. */ + +#define FT_MEM_ALLOC( ptr, size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, \ + (FT_Long)(size), \ + &error ) ) + +#define FT_MEM_FREE( ptr ) \ + FT_BEGIN_STMNT \ + ft_mem_free( memory, (ptr) ); \ + (ptr) = NULL; \ + FT_END_STMNT + +#define FT_MEM_NEW( ptr ) \ + FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) ) + +#define FT_MEM_REALLOC( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ + 1, \ + (FT_Long)(cursz), \ + (FT_Long)(newsz), \ + (ptr), \ + &error ) ) + +#define FT_MEM_QALLOC( ptr, size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, \ + (FT_Long)(size), \ + &error ) ) + +#define FT_MEM_QNEW( ptr ) \ + FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) ) + +#define FT_MEM_QREALLOC( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ + 1, \ + (FT_Long)(cursz), \ + (FT_Long)(newsz), \ + (ptr), \ + &error ) ) + +#define FT_MEM_ALLOC_MULT( ptr, count, item_size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ + (FT_Long)(item_size), \ + 0, \ + (FT_Long)(count), \ + NULL, \ + &error ) ) + +#define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ + (FT_Long)(itmsz), \ + (FT_Long)(oldcnt), \ + (FT_Long)(newcnt), \ + (ptr), \ + &error ) ) + +#define FT_MEM_QALLOC_MULT( ptr, count, item_size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ + (FT_Long)(item_size), \ + 0, \ + (FT_Long)(count), \ + NULL, \ + &error ) ) + +#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ + (FT_Long)(itmsz), \ + (FT_Long)(oldcnt), \ + (FT_Long)(newcnt), \ + (ptr), \ + &error ) ) + + +#define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 ) + + +#define FT_MEM_SET( dest, byte, count ) \ + ft_memset( dest, byte, (FT_Offset)(count) ) + +#define FT_MEM_COPY( dest, source, count ) \ + ft_memcpy( dest, source, (FT_Offset)(count) ) + +#define FT_MEM_MOVE( dest, source, count ) \ + ft_memmove( dest, source, (FT_Offset)(count) ) + + +#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) + +#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) + + +#define FT_ARRAY_ZERO( dest, count ) \ + FT_MEM_ZERO( dest, \ + (FT_Offset)(count) * sizeof ( *(dest) ) ) + +#define FT_ARRAY_COPY( dest, source, count ) \ + FT_MEM_COPY( dest, \ + source, \ + (FT_Offset)(count) * sizeof ( *(dest) ) ) + +#define FT_ARRAY_MOVE( dest, source, count ) \ + FT_MEM_MOVE( dest, \ + source, \ + (FT_Offset)(count) * sizeof ( *(dest) ) ) + + + /* + * Return the maximum number of addressable elements in an array. + * We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid + * any problems. + */ +#define FT_ARRAY_MAX( ptr ) ( FT_INT_MAX / sizeof ( *(ptr) ) ) + +#define FT_ARRAY_CHECK( ptr, count ) ( (count) <= FT_ARRAY_MAX( ptr ) ) + + + /*************************************************************************/ + /* */ + /* The following functions macros expect that their pointer argument is */ + /* _typed_ in order to automatically compute array element sizes. */ + /* */ + +#define FT_MEM_NEW_ARRAY( ptr, count ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ + sizeof ( *(ptr) ), \ + 0, \ + (FT_Long)(count), \ + NULL, \ + &error ) ) + +#define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ + sizeof ( *(ptr) ), \ + (FT_Long)(cursz), \ + (FT_Long)(newsz), \ + (ptr), \ + &error ) ) + +#define FT_MEM_QNEW_ARRAY( ptr, count ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ + sizeof ( *(ptr) ), \ + 0, \ + (FT_Long)(count), \ + NULL, \ + &error ) ) + +#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ + sizeof ( *(ptr) ), \ + (FT_Long)(cursz), \ + (FT_Long)(newsz), \ + (ptr), \ + &error ) ) + +#define FT_ALLOC( ptr, size ) \ + FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) ) + +#define FT_REALLOC( ptr, cursz, newsz ) \ + FT_MEM_SET_ERROR( FT_MEM_REALLOC( ptr, cursz, newsz ) ) + +#define FT_ALLOC_MULT( ptr, count, item_size ) \ + FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT( ptr, count, item_size ) ) + +#define FT_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT( ptr, oldcnt, \ + newcnt, itmsz ) ) + +#define FT_QALLOC( ptr, size ) \ + FT_MEM_SET_ERROR( FT_MEM_QALLOC( ptr, size ) ) + +#define FT_QREALLOC( ptr, cursz, newsz ) \ + FT_MEM_SET_ERROR( FT_MEM_QREALLOC( ptr, cursz, newsz ) ) + +#define FT_QALLOC_MULT( ptr, count, item_size ) \ + FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT( ptr, count, item_size ) ) + +#define FT_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT( ptr, oldcnt, \ + newcnt, itmsz ) ) + +#define FT_FREE( ptr ) FT_MEM_FREE( ptr ) + +#define FT_NEW( ptr ) FT_MEM_SET_ERROR( FT_MEM_NEW( ptr ) ) + +#define FT_NEW_ARRAY( ptr, count ) \ + FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) + +#define FT_RENEW_ARRAY( ptr, curcnt, newcnt ) \ + FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) + +#define FT_QNEW( ptr ) \ + FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) ) + +#define FT_QNEW_ARRAY( ptr, count ) \ + FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) + +#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt ) \ + FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) + + + FT_BASE( FT_Pointer ) + ft_mem_strdup( FT_Memory memory, + const char* str, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_dup( FT_Memory memory, + const void* address, + FT_ULong size, + FT_Error *p_error ); + + +#define FT_MEM_STRDUP( dst, str ) \ + (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error ) + +#define FT_STRDUP( dst, str ) \ + FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) ) + +#define FT_MEM_DUP( dst, address, size ) \ + (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error ) + +#define FT_DUP( dst, address, size ) \ + FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) ) + + + /* Return >= 1 if a truncation occurs. */ + /* Return 0 if the source string fits the buffer. */ + /* This is *not* the same as strlcpy(). */ + FT_BASE( FT_Int ) + ft_mem_strcpyn( char* dst, + const char* src, + FT_ULong size ); + +#define FT_STRCPYN( dst, src, size ) \ + ft_mem_strcpyn( (char*)dst, (const char*)(src), (FT_ULong)(size) ) + + /* */ + + +FT_END_HEADER + +#endif /* FTMEMORY_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/ftobjs.h b/builddir/freetype-2.7.0/include/freetype/internal/ftobjs.h new file mode 100644 index 0000000..0a9f2d4 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/ftobjs.h @@ -0,0 +1,1568 @@ +/***************************************************************************/ +/* */ +/* ftobjs.h */ +/* */ +/* The FreeType private base classes (specification). */ +/* */ +/* Copyright 1996-2016 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 file contains the definition of all internal FreeType classes. */ + /* */ + /*************************************************************************/ + + +#ifndef FTOBJS_H_ +#define FTOBJS_H_ + +#include <ft2build.h> +#include FT_RENDER_H +#include FT_SIZES_H +#include FT_LCD_FILTER_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_GLYPH_LOADER_H +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_AUTOHINT_H +#include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_PIC_H + +#ifdef FT_CONFIG_OPTION_INCREMENTAL +#include FT_INCREMENTAL_H +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* Some generic definitions. */ + /* */ +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL (void*)0 +#endif + + + /*************************************************************************/ + /* */ + /* The min and max functions missing in C. As usual, be careful not to */ + /* write things like FT_MIN( a++, b++ ) to avoid side effects. */ + /* */ +#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) +#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) + +#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) + + /* + * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' + * algorithm. We use alpha = 1, beta = 3/8, giving us results with a + * largest error less than 7% compared to the exact value. + */ +#define FT_HYPOT( x, y ) \ + ( x = FT_ABS( x ), \ + y = FT_ABS( y ), \ + x > y ? x + ( 3 * y >> 3 ) \ + : y + ( 3 * x >> 3 ) ) + + /* we use FT_TYPEOF to suppress signedness compilation warnings */ +#define FT_PAD_FLOOR( x, n ) ( (x) & ~FT_TYPEOF( x )( (n)-1 ) ) +#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n ) +#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n ) + +#define FT_PIX_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 ) +#define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) +#define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) + + + /* + * character classification functions -- since these are used to parse + * font files, we must not use those in <ctypes.h> which are + * locale-dependent + */ +#define ft_isdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U ) + +#define ft_isxdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U || \ + ( (unsigned)(x) - 'a' ) < 6U || \ + ( (unsigned)(x) - 'A' ) < 6U ) + + /* the next two macros assume ASCII representation */ +#define ft_isupper( x ) ( ( (unsigned)(x) - 'A' ) < 26U ) +#define ft_islower( x ) ( ( (unsigned)(x) - 'a' ) < 26U ) + +#define ft_isalpha( x ) ( ft_isupper( x ) || ft_islower( x ) ) +#define ft_isalnum( x ) ( ft_isdigit( x ) || ft_isalpha( x ) ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** C H A R M A P S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to internal charmap object */ + typedef struct FT_CMapRec_* FT_CMap; + + /* handle to charmap class structure */ + typedef const struct FT_CMap_ClassRec_* FT_CMap_Class; + + /* internal charmap object structure */ + typedef struct FT_CMapRec_ + { + FT_CharMapRec charmap; + FT_CMap_Class clazz; + + } FT_CMapRec; + + /* typecase any pointer to a charmap handle */ +#define FT_CMAP( x ) ((FT_CMap)( x )) + + /* obvious macros */ +#define FT_CMAP_PLATFORM_ID( x ) FT_CMAP( x )->charmap.platform_id +#define FT_CMAP_ENCODING_ID( x ) FT_CMAP( x )->charmap.encoding_id +#define FT_CMAP_ENCODING( x ) FT_CMAP( x )->charmap.encoding +#define FT_CMAP_FACE( x ) FT_CMAP( x )->charmap.face + + + /* class method definitions */ + typedef FT_Error + (*FT_CMap_InitFunc)( FT_CMap cmap, + FT_Pointer init_data ); + + typedef void + (*FT_CMap_DoneFunc)( FT_CMap cmap ); + + typedef FT_UInt + (*FT_CMap_CharIndexFunc)( FT_CMap cmap, + FT_UInt32 char_code ); + + typedef FT_UInt + (*FT_CMap_CharNextFunc)( FT_CMap cmap, + FT_UInt32 *achar_code ); + + typedef FT_UInt + (*FT_CMap_CharVarIndexFunc)( FT_CMap cmap, + FT_CMap unicode_cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_Bool + (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_UInt32 * + (*FT_CMap_VariantListFunc)( FT_CMap cmap, + FT_Memory mem ); + + typedef FT_UInt32 * + (*FT_CMap_CharVariantListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 char_code ); + + typedef FT_UInt32 * + (*FT_CMap_VariantCharListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 variant_selector ); + + + typedef struct FT_CMap_ClassRec_ + { + FT_ULong size; + FT_CMap_InitFunc init; + FT_CMap_DoneFunc done; + FT_CMap_CharIndexFunc char_index; + FT_CMap_CharNextFunc char_next; + + /* Subsequent entries are special ones for format 14 -- the variant */ + /* selector subtable which behaves like no other */ + + FT_CMap_CharVarIndexFunc char_var_index; + FT_CMap_CharVarIsDefaultFunc char_var_default; + FT_CMap_VariantListFunc variant_list; + FT_CMap_CharVariantListFunc charvariant_list; + FT_CMap_VariantCharListFunc variantchar_list; + + } FT_CMap_ClassRec; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_CMAP_CLASS( class_ ) \ + FT_CALLBACK_TABLE const FT_CMap_ClassRec class_; + +#define FT_DEFINE_CMAP_CLASS( \ + class_, \ + size_, \ + init_, \ + done_, \ + char_index_, \ + char_next_, \ + char_var_index_, \ + char_var_default_, \ + variant_list_, \ + charvariant_list_, \ + variantchar_list_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_CMap_ClassRec class_ = \ + { \ + size_, \ + init_, \ + done_, \ + char_index_, \ + char_next_, \ + char_var_index_, \ + char_var_default_, \ + variant_list_, \ + charvariant_list_, \ + variantchar_list_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_CMAP_CLASS( class_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_CMap_ClassRec* clazz ); + +#define FT_DEFINE_CMAP_CLASS( \ + class_, \ + size_, \ + init_, \ + done_, \ + char_index_, \ + char_next_, \ + char_var_index_, \ + char_var_default_, \ + variant_list_, \ + charvariant_list_, \ + variantchar_list_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_CMap_ClassRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->size = size_; \ + clazz->init = init_; \ + clazz->done = done_; \ + clazz->char_index = char_index_; \ + clazz->char_next = char_next_; \ + clazz->char_var_index = char_var_index_; \ + clazz->char_var_default = char_var_default_; \ + clazz->variant_list = variant_list_; \ + clazz->charvariant_list = charvariant_list_; \ + clazz->variantchar_list = variantchar_list_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /* create a new charmap and add it to charmap->face */ + FT_BASE( FT_Error ) + FT_CMap_New( FT_CMap_Class clazz, + FT_Pointer init_data, + FT_CharMap charmap, + FT_CMap *acmap ); + + /* destroy a charmap and remove it from face's list */ + FT_BASE( void ) + FT_CMap_Done( FT_CMap cmap ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Face_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_Face */ + /* object. These fields may change between different releases of */ + /* FreeType. */ + /* */ + /* <Fields> */ + /* max_points :: */ + /* The maximum number of points used to store the vectorial outline */ + /* of any glyph in this face. If this value cannot be known in */ + /* advance, or if the face isn't scalable, this should be set to 0. */ + /* Only relevant for scalable formats. */ + /* */ + /* max_contours :: */ + /* The maximum number of contours used to store the vectorial */ + /* outline of any glyph in this face. If this value cannot be */ + /* known in advance, or if the face isn't scalable, this should be */ + /* set to 0. Only relevant for scalable formats. */ + /* */ + /* transform_matrix :: */ + /* A 2x2 matrix of 16.16 coefficients used to transform glyph */ + /* outlines after they are loaded from the font. Only used by the */ + /* convenience functions. */ + /* */ + /* transform_delta :: */ + /* A translation vector used to transform glyph outlines after they */ + /* are loaded from the font. Only used by the convenience */ + /* functions. */ + /* */ + /* transform_flags :: */ + /* Some flags used to classify the transform. Only used by the */ + /* convenience functions. */ + /* */ + /* services :: */ + /* A cache for frequently used services. It should be only */ + /* accessed with the macro `FT_FACE_LOOKUP_SERVICE'. */ + /* */ + /* incremental_interface :: */ + /* If non-null, the interface through which glyph data and metrics */ + /* are loaded incrementally for faces that do not provide all of */ + /* this data when first opened. This field exists only if */ + /* @FT_CONFIG_OPTION_INCREMENTAL is defined. */ + /* */ + /* refcount :: */ + /* A counter initialized to~1 at the time an @FT_Face structure is */ + /* created. @FT_Reference_Face increments this counter, and */ + /* @FT_Done_Face only destroys a face if the counter is~1, */ + /* otherwise it simply decrements it. */ + /* */ + typedef struct FT_Face_InternalRec_ + { + FT_Matrix transform_matrix; + FT_Vector transform_delta; + FT_Int transform_flags; + + FT_ServiceCacheRec services; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec* incremental_interface; +#endif + + FT_Int refcount; + + } FT_Face_InternalRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Slot_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_GlyphSlot */ + /* object. These fields may change between different releases of */ + /* FreeType. */ + /* */ + /* <Fields> */ + /* loader :: The glyph loader object used to load outlines */ + /* into the glyph slot. */ + /* */ + /* flags :: Possible values are zero or */ + /* FT_GLYPH_OWN_BITMAP. The latter indicates */ + /* that the FT_GlyphSlot structure owns the */ + /* bitmap buffer. */ + /* */ + /* glyph_transformed :: Boolean. Set to TRUE when the loaded glyph */ + /* must be transformed through a specific */ + /* font transformation. This is _not_ the same */ + /* as the face transform set through */ + /* FT_Set_Transform(). */ + /* */ + /* glyph_matrix :: The 2x2 matrix corresponding to the glyph */ + /* transformation, if necessary. */ + /* */ + /* glyph_delta :: The 2d translation vector corresponding to */ + /* the glyph transformation, if necessary. */ + /* */ + /* glyph_hints :: Format-specific glyph hints management. */ + /* */ + +#define FT_GLYPH_OWN_BITMAP 0x1U + + typedef struct FT_Slot_InternalRec_ + { + FT_GlyphLoader loader; + FT_UInt flags; + FT_Bool glyph_transformed; + FT_Matrix glyph_matrix; + FT_Vector glyph_delta; + void* glyph_hints; + + } FT_GlyphSlot_InternalRec; + + +#if 0 + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_Size */ + /* object. Currently, it's empty. */ + /* */ + /*************************************************************************/ + + typedef struct FT_Size_InternalRec_ + { + /* empty */ + + } FT_Size_InternalRec; + +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M O D U L E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ModuleRec */ + /* */ + /* <Description> */ + /* A module object instance. */ + /* */ + /* <Fields> */ + /* clazz :: A pointer to the module's class. */ + /* */ + /* library :: A handle to the parent library object. */ + /* */ + /* memory :: A handle to the memory manager. */ + /* */ + typedef struct FT_ModuleRec_ + { + FT_Module_Class* clazz; + FT_Library library; + FT_Memory memory; + + } FT_ModuleRec; + + + /* typecast an object to an FT_Module */ +#define FT_MODULE( x ) ((FT_Module)( x )) +#define FT_MODULE_CLASS( x ) FT_MODULE( x )->clazz +#define FT_MODULE_LIBRARY( x ) FT_MODULE( x )->library +#define FT_MODULE_MEMORY( x ) FT_MODULE( x )->memory + + +#define FT_MODULE_IS_DRIVER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_FONT_DRIVER ) + +#define FT_MODULE_IS_RENDERER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_RENDERER ) + +#define FT_MODULE_IS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_HINTER ) + +#define FT_MODULE_IS_STYLER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_STYLER ) + +#define FT_DRIVER_IS_SCALABLE( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_SCALABLE ) + +#define FT_DRIVER_USES_OUTLINES( x ) !( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_NO_OUTLINES ) + +#define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_HAS_HINTER ) + +#define FT_DRIVER_HINTS_LIGHTLY( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_HINTS_LIGHTLY ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Module_Interface */ + /* */ + /* <Description> */ + /* Finds a module and returns its specific interface as a typeless */ + /* pointer. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* module_name :: The module's name (as an ASCII string). */ + /* */ + /* <Return> */ + /* A module-specific interface if available, 0 otherwise. */ + /* */ + /* <Note> */ + /* You should better be familiar with FreeType internals to know */ + /* which module to look for, and what its interface is :-) */ + /* */ + FT_BASE( const void* ) + FT_Get_Module_Interface( FT_Library library, + const char* mod_name ); + + FT_BASE( FT_Pointer ) + ft_module_get_service( FT_Module module, + const char* service_id ); + +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_BASE( FT_Error ) + ft_property_string_set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + FT_String* value ); +#endif + + /* */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F A C E, S I Z E & G L Y P H S L O T O B J E C T S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* a few macros used to perform easy typecasts with minimal brain damage */ + +#define FT_FACE( x ) ((FT_Face)(x)) +#define FT_SIZE( x ) ((FT_Size)(x)) +#define FT_SLOT( x ) ((FT_GlyphSlot)(x)) + +#define FT_FACE_DRIVER( x ) FT_FACE( x )->driver +#define FT_FACE_LIBRARY( x ) FT_FACE_DRIVER( x )->root.library +#define FT_FACE_MEMORY( x ) FT_FACE( x )->memory +#define FT_FACE_STREAM( x ) FT_FACE( x )->stream + +#define FT_SIZE_FACE( x ) FT_SIZE( x )->face +#define FT_SLOT_FACE( x ) FT_SLOT( x )->face + +#define FT_FACE_SLOT( x ) FT_FACE( x )->glyph +#define FT_FACE_SIZE( x ) FT_FACE( x )->size + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_GlyphSlot */ + /* */ + /* <Description> */ + /* It is sometimes useful to have more than one glyph slot for a */ + /* given face object. This function is used to create additional */ + /* slots. All of them are automatically discarded when the face is */ + /* destroyed. */ + /* */ + /* <Input> */ + /* face :: A handle to a parent face object. */ + /* */ + /* <Output> */ + /* aslot :: A handle to a new glyph slot object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_BASE( FT_Error ) + FT_New_GlyphSlot( FT_Face face, + FT_GlyphSlot *aslot ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_GlyphSlot */ + /* */ + /* <Description> */ + /* Destroys a given glyph slot. Remember however that all slots are */ + /* automatically destroyed with its parent. Using this function is */ + /* not always mandatory. */ + /* */ + /* <Input> */ + /* slot :: A handle to a target glyph slot. */ + /* */ + FT_BASE( void ) + FT_Done_GlyphSlot( FT_GlyphSlot slot ); + + /* */ + +#define FT_REQUEST_WIDTH( req ) \ + ( (req)->horiResolution \ + ? ( (req)->width * (FT_Pos)(req)->horiResolution + 36 ) / 72 \ + : (req)->width ) + +#define FT_REQUEST_HEIGHT( req ) \ + ( (req)->vertResolution \ + ? ( (req)->height * (FT_Pos)(req)->vertResolution + 36 ) / 72 \ + : (req)->height ) + + + /* Set the metrics according to a bitmap strike. */ + FT_BASE( void ) + FT_Select_Metrics( FT_Face face, + FT_ULong strike_index ); + + + /* Set the metrics according to a size request. */ + FT_BASE( void ) + FT_Request_Metrics( FT_Face face, + FT_Size_Request req ); + + + /* Match a size request against `available_sizes'. */ + FT_BASE( FT_Error ) + FT_Match_Size( FT_Face face, + FT_Size_Request req, + FT_Bool ignore_width, + FT_ULong* size_index ); + + + /* Use the horizontal metrics to synthesize the vertical metrics. */ + /* If `advance' is zero, it is also synthesized. */ + FT_BASE( void ) + ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, + FT_Pos advance ); + + + /* Free the bitmap of a given glyphslot when needed (i.e., only when it */ + /* was allocated with ft_glyphslot_alloc_bitmap). */ + FT_BASE( void ) + ft_glyphslot_free_bitmap( FT_GlyphSlot slot ); + + + /* Allocate a new bitmap buffer in a glyph slot. */ + FT_BASE( FT_Error ) + ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, + FT_ULong size ); + + + /* Set the bitmap buffer in a glyph slot to a given pointer. The buffer */ + /* will not be freed by a later call to ft_glyphslot_free_bitmap. */ + FT_BASE( void ) + ft_glyphslot_set_bitmap( FT_GlyphSlot slot, + FT_Byte* buffer ); + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** R E N D E R E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#define FT_RENDERER( x ) ((FT_Renderer)( x )) +#define FT_GLYPH( x ) ((FT_Glyph)( x )) +#define FT_BITMAP_GLYPH( x ) ((FT_BitmapGlyph)( x )) +#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x )) + + + typedef struct FT_RendererRec_ + { + FT_ModuleRec root; + FT_Renderer_Class* clazz; + FT_Glyph_Format glyph_format; + FT_Glyph_Class glyph_class; + + FT_Raster raster; + FT_Raster_Render_Func raster_render; + FT_Renderer_RenderFunc render; + + } FT_RendererRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F O N T D R I V E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* typecast a module into a driver easily */ +#define FT_DRIVER( x ) ((FT_Driver)(x)) + + /* typecast a module as a driver, and get its driver class */ +#define FT_DRIVER_CLASS( x ) FT_DRIVER( x )->clazz + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_DriverRec */ + /* */ + /* <Description> */ + /* The root font driver class. A font driver is responsible for */ + /* managing and loading font files of a given format. */ + /* */ + /* <Fields> */ + /* root :: Contains the fields of the root module class. */ + /* */ + /* clazz :: A pointer to the font driver's class. Note that */ + /* this is NOT root.clazz. `class' wasn't used */ + /* as it is a reserved word in C++. */ + /* */ + /* faces_list :: The list of faces currently opened by this */ + /* driver. */ + /* */ + /* glyph_loader :: Unused. Used to be glyph loader for all faces */ + /* managed by this driver. */ + /* */ + typedef struct FT_DriverRec_ + { + FT_ModuleRec root; + FT_Driver_Class clazz; + FT_ListRec faces_list; + FT_GlyphLoader glyph_loader; + + } FT_DriverRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** L I B R A R I E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* This hook is used by the TrueType debugger. It must be set to an */ + /* alternate truetype bytecode interpreter function. */ +#define FT_DEBUG_HOOK_TRUETYPE 0 + + + typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap, + FT_Render_Mode render_mode, + FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_LibraryRec */ + /* */ + /* <Description> */ + /* The FreeType library class. This is the root of all FreeType */ + /* data. Use FT_New_Library() to create a library object, and */ + /* FT_Done_Library() to discard it and all child objects. */ + /* */ + /* <Fields> */ + /* memory :: The library's memory object. Manages memory */ + /* allocation. */ + /* */ + /* version_major :: The major version number of the library. */ + /* */ + /* version_minor :: The minor version number of the library. */ + /* */ + /* version_patch :: The current patch level of the library. */ + /* */ + /* num_modules :: The number of modules currently registered */ + /* within this library. This is set to 0 for new */ + /* libraries. New modules are added through the */ + /* FT_Add_Module() API function. */ + /* */ + /* modules :: A table used to store handles to the currently */ + /* registered modules. Note that each font driver */ + /* contains a list of its opened faces. */ + /* */ + /* renderers :: The list of renderers currently registered */ + /* within the library. */ + /* */ + /* cur_renderer :: The current outline renderer. This is a */ + /* shortcut used to avoid parsing the list on */ + /* each call to FT_Outline_Render(). It is a */ + /* handle to the current renderer for the */ + /* FT_GLYPH_FORMAT_OUTLINE format. */ + /* */ + /* auto_hinter :: XXX */ + /* */ + /* raster_pool :: The raster object's render pool. This can */ + /* ideally be changed dynamically at run-time. */ + /* */ + /* raster_pool_size :: The size of the render pool in bytes. */ + /* */ + /* debug_hooks :: XXX */ + /* */ + /* lcd_filter :: If subpixel rendering is activated, the */ + /* selected LCD filter mode. */ + /* */ + /* lcd_extra :: If subpixel rendering is activated, the number */ + /* of extra pixels needed for the LCD filter. */ + /* */ + /* lcd_weights :: If subpixel rendering is activated, the LCD */ + /* filter weights, if any. */ + /* */ + /* lcd_filter_func :: If subpixel rendering is activated, the LCD */ + /* filtering callback function. */ + /* */ + /* pic_container :: Contains global structs and tables, instead */ + /* of defining them globally. */ + /* */ + /* refcount :: A counter initialized to~1 at the time an */ + /* @FT_Library structure is created. */ + /* @FT_Reference_Library increments this counter, */ + /* and @FT_Done_Library only destroys a library */ + /* if the counter is~1, otherwise it simply */ + /* decrements it. */ + /* */ + typedef struct FT_LibraryRec_ + { + FT_Memory memory; /* library's memory manager */ + + FT_Int version_major; + FT_Int version_minor; + FT_Int version_patch; + + FT_UInt num_modules; + FT_Module modules[FT_MAX_MODULES]; /* module objects */ + + FT_ListRec renderers; /* list of renderers */ + FT_Renderer cur_renderer; /* current outline renderer */ + FT_Module auto_hinter; + + FT_Byte* raster_pool; /* scan-line conversion */ + /* render pool */ + FT_ULong raster_pool_size; /* size of render pool in bytes */ + + FT_DebugHook_Func debug_hooks[4]; + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + FT_LcdFilter lcd_filter; + FT_Int lcd_extra; /* number of extra pixels */ + FT_Byte lcd_weights[7]; /* filter weights, if any */ + FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ +#endif + +#ifdef FT_CONFIG_OPTION_PIC + FT_PIC_Container pic_container; +#endif + + FT_Int refcount; + + } FT_LibraryRec; + + + FT_BASE( FT_Renderer ) + FT_Lookup_Renderer( FT_Library library, + FT_Glyph_Format format, + FT_ListNode* node ); + + FT_BASE( FT_Error ) + FT_Render_Glyph_Internal( FT_Library library, + FT_GlyphSlot slot, + FT_Render_Mode render_mode ); + + typedef const char* + (*FT_Face_GetPostscriptNameFunc)( FT_Face face ); + + typedef FT_Error + (*FT_Face_GetGlyphNameFunc)( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + typedef FT_UInt + (*FT_Face_GetGlyphNameIndexFunc)( FT_Face face, + FT_String* glyph_name ); + + +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory */ + /* */ + /* <Description> */ + /* Creates a new memory object. */ + /* */ + /* <Return> */ + /* A pointer to the new memory object. 0 in case of error. */ + /* */ + FT_BASE( FT_Memory ) + FT_New_Memory( void ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Memory */ + /* */ + /* <Description> */ + /* Discards memory manager. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* */ + FT_BASE( void ) + FT_Done_Memory( FT_Memory memory ); + +#endif /* !FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ + + + /* Define default raster's interface. The default raster is located in */ + /* `src/base/ftraster.c'. */ + /* */ + /* Client applications can register new rasters through the */ + /* FT_Set_Raster() API. */ + +#ifndef FT_NO_DEFAULT_RASTER + FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster; +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** P I C S U P P O R T ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* PIC support macros for ftimage.h */ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_OUTLINE_FUNCS */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Outline_Funcs struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_OUTLINE_FUNCS( \ + class_, \ + move_to_, \ + line_to_, \ + conic_to_, \ + cubic_to_, \ + shift_, \ + delta_ ) \ + static const FT_Outline_Funcs class_ = \ + { \ + move_to_, \ + line_to_, \ + conic_to_, \ + cubic_to_, \ + shift_, \ + delta_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_OUTLINE_FUNCS( \ + class_, \ + move_to_, \ + line_to_, \ + conic_to_, \ + cubic_to_, \ + shift_, \ + delta_ ) \ + static FT_Error \ + Init_Class_ ## class_( FT_Outline_Funcs* clazz ) \ + { \ + clazz->move_to = move_to_; \ + clazz->line_to = line_to_; \ + clazz->conic_to = conic_to_; \ + clazz->cubic_to = cubic_to_; \ + clazz->shift = shift_; \ + clazz->delta = delta_; \ + \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_RASTER_FUNCS */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Raster_Funcs struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_RASTER_FUNCS( \ + class_, \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ ) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_RASTER_FUNCS( \ + class_, \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Raster_Funcs* clazz ) \ + { \ + clazz->glyph_format = glyph_format_; \ + clazz->raster_new = raster_new_; \ + clazz->raster_reset = raster_reset_; \ + clazz->raster_set_mode = raster_set_mode_; \ + clazz->raster_render = raster_render_; \ + clazz->raster_done = raster_done_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /* PIC support macros for ftrender.h */ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_GLYPH */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Glyph_Class struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_GLYPH( \ + class_, \ + size_, \ + format_, \ + init_, \ + done_, \ + copy_, \ + transform_, \ + bbox_, \ + prepare_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Glyph_Class class_ = \ + { \ + size_, \ + format_, \ + init_, \ + done_, \ + copy_, \ + transform_, \ + bbox_, \ + prepare_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_GLYPH( \ + class_, \ + size_, \ + format_, \ + init_, \ + done_, \ + copy_, \ + transform_, \ + bbox_, \ + prepare_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Glyph_Class* clazz ) \ + { \ + clazz->glyph_size = size_; \ + clazz->glyph_format = format_; \ + clazz->glyph_init = init_; \ + clazz->glyph_done = done_; \ + clazz->glyph_copy = copy_; \ + clazz->glyph_transform = transform_; \ + clazz->glyph_bbox = bbox_; \ + clazz->glyph_prepare = prepare_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_RENDERER */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Renderer_Class struct instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_RENDERER */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Renderer_Class struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function will */ + /* need to be called with a pointer where the allocated structure is */ + /* returned. And when it is no longer needed a `destroy' function */ + /* needs to be called to release that allocation. */ + /* `ftinit.c' (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in `ftmodule.h'. */ + /* */ + /* Notice that the created `create' and `destroy' functions call */ + /* `pic_init' and `pic_free' to allow you to manually allocate and */ + /* initialize any additional global data, like a module specific */ + /* interface, and put them in the global pic container defined in */ + /* `ftpic.h'. If you don't need them just implement the functions as */ + /* empty to resolve the link error. Also the `pic_init' and */ + /* `pic_free' functions should be declared in `pic.h', to be referred */ + /* by the renderer definition calling `FT_DEFINE_RENDERER' in the */ + /* following. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_RENDERER( class_ ) \ + FT_EXPORT_VAR( const FT_Renderer_Class ) class_; + +#define FT_DEFINE_RENDERER( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_, \ + glyph_format_, \ + render_glyph_, \ + transform_glyph_, \ + get_glyph_cbox_, \ + set_mode_, \ + raster_class_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Renderer_Class class_ = \ + { \ + FT_DEFINE_ROOT_MODULE( flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + glyph_format_, \ + \ + render_glyph_, \ + transform_glyph_, \ + get_glyph_cbox_, \ + set_mode_, \ + \ + raster_class_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_RENDERER( class_ ) FT_DECLARE_MODULE( class_ ) + +#define FT_DEFINE_RENDERER( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_, \ + glyph_format_, \ + render_glyph_, \ + transform_glyph_, \ + get_glyph_cbox_, \ + set_mode_, \ + raster_class_ ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz; \ + FT_Memory memory = library->memory; \ + \ + \ + class_ ## _pic_free( library ); \ + if ( rclazz ) \ + FT_FREE( rclazz ); \ + } \ + \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Renderer_Class* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ + return error; \ + \ + error = class_ ## _pic_init( library ); \ + if ( error ) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + FT_DEFINE_ROOT_MODULE( flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + \ + clazz->glyph_format = glyph_format_; \ + \ + clazz->render_glyph = render_glyph_; \ + clazz->transform_glyph = transform_glyph_; \ + clazz->get_glyph_cbox = get_glyph_cbox_; \ + clazz->set_mode = set_mode_; \ + \ + clazz->raster_class = raster_class_; \ + \ + *output_class = (FT_Module_Class*)clazz; \ + \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /* PIC support macros for ftmodapi.h **/ + + +#ifdef FT_CONFIG_OPTION_PIC + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Creator */ + /* */ + /* <Description> */ + /* A function used to create (allocate) a new module class object. */ + /* The object's members are initialized, but the module itself is */ + /* not. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* output_class :: Initialized with the newly allocated class. */ + /* */ + typedef FT_Error + (*FT_Module_Creator)( FT_Memory memory, + FT_Module_Class** output_class ); + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destroyer */ + /* */ + /* <Description> */ + /* A function used to destroy (deallocate) a module class object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* clazz :: Module class to destroy. */ + /* */ + typedef void + (*FT_Module_Destroyer)( FT_Memory memory, + FT_Module_Class* clazz ); + +#endif + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_MODULE */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Module_Class struct instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_MODULE */ + /* */ + /* <Description> */ + /* Used to initialize an instance of an FT_Module_Class struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function needs */ + /* to be called with a pointer where the allocated structure is */ + /* returned. And when it is no longer needed a `destroy' function */ + /* needs to be called to release that allocation. */ + /* `ftinit.c' (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in `ftmodule.h'. */ + /* */ + /* Notice that the created `create' and `destroy' functions call */ + /* `pic_init' and `pic_free' to allow you to manually allocate and */ + /* initialize any additional global data, like a module specific */ + /* interface, and put them in the global pic container defined in */ + /* `ftpic.h'. If you don't need them just implement the functions as */ + /* empty to resolve the link error. Also the `pic_init' and */ + /* `pic_free' functions should be declared in `pic.h', to be referred */ + /* by the module definition calling `FT_DEFINE_MODULE' in the */ + /* following. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ + /* <Macro> */ + /* FT_DEFINE_ROOT_MODULE */ + /* */ + /* <Description> */ + /* Used to initialize an instance of an FT_Module_Class struct inside */ + /* another struct that contains it or in a function that initializes */ + /* that containing struct. */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_MODULE( class_ ) \ + FT_CALLBACK_TABLE \ + const FT_Module_Class class_; + +#define FT_DEFINE_ROOT_MODULE( \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + { \ + flags_, \ + size_, \ + \ + name_, \ + version_, \ + requires_, \ + \ + interface_, \ + \ + init_, \ + done_, \ + get_interface_, \ + }, + +#define FT_DEFINE_MODULE( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Module_Class class_ = \ + { \ + flags_, \ + size_, \ + \ + name_, \ + version_, \ + requires_, \ + \ + interface_, \ + \ + init_, \ + done_, \ + get_interface_, \ + }; + + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_MODULE( class_ ) \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_Module_Class** output_class ); \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_Module_Class* clazz ); + +#define FT_DEFINE_ROOT_MODULE( \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + clazz->root.module_flags = flags_; \ + clazz->root.module_size = size_; \ + clazz->root.module_name = name_; \ + clazz->root.module_version = version_; \ + clazz->root.module_requires = requires_; \ + \ + clazz->root.module_interface = interface_; \ + \ + clazz->root.module_init = init_; \ + clazz->root.module_done = done_; \ + clazz->root.get_interface = get_interface_; + +#define FT_DEFINE_MODULE( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + class_ ## _pic_free( library ); \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Memory memory = library->memory; \ + FT_Module_Class* clazz = NULL; \ + FT_Error error; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ + return error; \ + error = class_ ## _pic_init( library ); \ + if ( error ) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + clazz->module_flags = flags_; \ + clazz->module_size = size_; \ + clazz->module_name = name_; \ + clazz->module_version = version_; \ + clazz->module_requires = requires_; \ + \ + clazz->module_interface = interface_; \ + \ + clazz->module_init = init_; \ + clazz->module_done = done_; \ + clazz->get_interface = get_interface_; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +FT_END_HEADER + +#endif /* FTOBJS_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/ftpic.h b/builddir/freetype-2.7.0/include/freetype/internal/ftpic.h new file mode 100644 index 0000000..6d800a0 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/ftpic.h @@ -0,0 +1,71 @@ +/***************************************************************************/ +/* */ +/* ftpic.h */ +/* */ +/* The FreeType position independent code services (declaration). */ +/* */ +/* Copyright 2009-2016 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Modules that ordinarily have const global data that need address */ + /* can instead define pointers here. */ + /* */ + /*************************************************************************/ + + +#ifndef FTPIC_H_ +#define FTPIC_H_ + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC + + typedef struct FT_PIC_Container_ + { + /* pic containers for base */ + void* base; + + /* pic containers for modules */ + void* autofit; + void* cff; + void* pshinter; + void* psnames; + void* raster; + void* sfnt; + void* smooth; + void* truetype; + + } FT_PIC_Container; + + + /* Initialize the various function tables, structs, etc. */ + /* stored in the container. */ + FT_BASE( FT_Error ) + ft_pic_container_init( FT_Library library ); + + + /* Destroy the contents of the container. */ + FT_BASE( void ) + ft_pic_container_destroy( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* FTPIC_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/ftrfork.h b/builddir/freetype-2.7.0/include/freetype/internal/ftrfork.h new file mode 100644 index 0000000..b923401 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/ftrfork.h @@ -0,0 +1,266 @@ +/***************************************************************************/ +/* */ +/* ftrfork.h */ +/* */ +/* Embedded resource forks accessor (specification). */ +/* */ +/* Copyright 2004-2016 by */ +/* Masatake YAMATO and Redhat K.K. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* Development of the code in this file is support of */ +/* Information-technology Promotion Agency, Japan. */ +/***************************************************************************/ + + +#ifndef FTRFORK_H_ +#define FTRFORK_H_ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* Number of guessing rules supported in `FT_Raccess_Guess'. */ + /* Don't forget to increment the number if you add a new guessing rule. */ +#define FT_RACCESS_N_RULES 9 + + + /* A structure to describe a reference in a resource by its resource ID */ + /* and internal offset. The `POST' resource expects to be concatenated */ + /* by the order of resource IDs instead of its appearance in the file. */ + + typedef struct FT_RFork_Ref_ + { + FT_UShort res_id; + FT_Long offset; + + } FT_RFork_Ref; + +#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK + typedef FT_Error + (*ft_raccess_guess_func)( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + typedef enum FT_RFork_Rule_ { + FT_RFork_Rule_invalid = -2, + FT_RFork_Rule_uknown, /* -1 */ + FT_RFork_Rule_apple_double, + FT_RFork_Rule_apple_single, + FT_RFork_Rule_darwin_ufs_export, + FT_RFork_Rule_darwin_newvfs, + FT_RFork_Rule_darwin_hfsplus, + FT_RFork_Rule_vfat, + FT_RFork_Rule_linux_cap, + FT_RFork_Rule_linux_double, + FT_RFork_Rule_linux_netatalk + } FT_RFork_Rule; + + /* For fast translation between rule index and rule type, + * the macros FT_RFORK_xxx should be kept consistent with + * the raccess_guess_funcs table + */ + typedef struct ft_raccess_guess_rec_ { + ft_raccess_guess_func func; + FT_RFork_Rule type; + } ft_raccess_guess_rec; + +#ifndef FT_CONFIG_OPTION_PIC + + /* this array is a storage in non-PIC mode, so ; is needed in END */ +#define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ + static const type name[] = { +#define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \ + { raccess_guess_ ## func_suffix, \ + FT_RFork_Rule_ ## type_suffix }, +#define CONST_FT_RFORK_RULE_ARRAY_END }; + +#else /* FT_CONFIG_OPTION_PIC */ + + /* this array is a function in PIC mode, so no ; is needed in END */ +#define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type ) \ + void \ + FT_Init_Table_ ## name( type* storage ) \ + { \ + type* local = storage; \ + \ + \ + int i = 0; +#define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix ) \ + local[i].func = raccess_guess_ ## func_suffix; \ + local[i].type = FT_RFork_Rule_ ## type_suffix; \ + i++; +#define CONST_FT_RFORK_RULE_ARRAY_END } + +#endif /* FT_CONFIG_OPTION_PIC */ + +#endif /* FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Guess */ + /* */ + /* <Description> */ + /* Guess a file name and offset where the actual resource fork is */ + /* stored. The macro FT_RACCESS_N_RULES holds the number of */ + /* guessing rules; the guessed result for the Nth rule is */ + /* represented as a triplet: a new file name (new_names[N]), a file */ + /* offset (offsets[N]), and an error code (errors[N]). */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* base_name :: */ + /* The (base) file name of the resource fork used for some */ + /* guessing rules. */ + /* */ + /* <Output> */ + /* new_names :: */ + /* An array of guessed file names in which the resource forks may */ + /* exist. If `new_names[N]' is NULL, the guessed file name is */ + /* equal to `base_name'. */ + /* */ + /* offsets :: */ + /* An array of guessed file offsets. `offsets[N]' holds the file */ + /* offset of the possible start of the resource fork in file */ + /* `new_names[N]'. */ + /* */ + /* errors :: */ + /* An array of FreeType error codes. `errors[N]' is the error */ + /* code of Nth guessing rule function. If `errors[N]' is not */ + /* FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless. */ + /* */ + FT_BASE( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char* base_name, + char** new_names, + FT_Long* offsets, + FT_Error* errors ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Get_HeaderInfo */ + /* */ + /* <Description> */ + /* Get the information from the header of resource fork. The */ + /* information includes the file offset where the resource map */ + /* starts, and the file offset where the resource data starts. */ + /* `FT_Raccess_Get_DataOffsets' requires these two data. */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* rfork_offset :: */ + /* The file offset where the resource fork starts. */ + /* */ + /* <Output> */ + /* map_offset :: */ + /* The file offset where the resource map starts. */ + /* */ + /* rdata_pos :: */ + /* The file offset where the resource data starts. */ + /* */ + /* <Return> */ + /* FreeType error code. FT_Err_Ok means success. */ + /* */ + FT_BASE( FT_Error ) + FT_Raccess_Get_HeaderInfo( FT_Library library, + FT_Stream stream, + FT_Long rfork_offset, + FT_Long *map_offset, + FT_Long *rdata_pos ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Get_DataOffsets */ + /* */ + /* <Description> */ + /* Get the data offsets for a tag in a resource fork. Offsets are */ + /* stored in an array because, in some cases, resources in a resource */ + /* fork have the same tag. */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* map_offset :: */ + /* The file offset where the resource map starts. */ + /* */ + /* rdata_pos :: */ + /* The file offset where the resource data starts. */ + /* */ + /* tag :: */ + /* The resource tag. */ + /* */ + /* sort_by_res_id :: */ + /* A Boolean to sort the fragmented resource by their ids. */ + /* The fragmented resources for `POST' resource should be sorted */ + /* to restore Type1 font properly. For `sfnt' resources, sorting */ + /* may induce a different order of the faces in comparison to that */ + /* by QuickDraw API. */ + /* */ + /* <Output> */ + /* offsets :: */ + /* The stream offsets for the resource data specified by `tag'. */ + /* This array is allocated by the function, so you have to call */ + /* @ft_mem_free after use. */ + /* */ + /* count :: */ + /* The length of offsets array. */ + /* */ + /* <Return> */ + /* FreeType error code. FT_Err_Ok means success. */ + /* */ + /* <Note> */ + /* Normally you should use `FT_Raccess_Get_HeaderInfo' to get the */ + /* value for `map_offset' and `rdata_pos'. */ + /* */ + FT_BASE( FT_Error ) + FT_Raccess_Get_DataOffsets( FT_Library library, + FT_Stream stream, + FT_Long map_offset, + FT_Long rdata_pos, + FT_Long tag, + FT_Bool sort_by_res_id, + FT_Long **offsets, + FT_Long *count ); + + +FT_END_HEADER + +#endif /* FTRFORK_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/ftserv.h b/builddir/freetype-2.7.0/include/freetype/internal/ftserv.h new file mode 100644 index 0000000..9189717 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/ftserv.h @@ -0,0 +1,763 @@ +/***************************************************************************/ +/* */ +/* ftserv.h */ +/* */ +/* The FreeType services (specification only). */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Each module can export one or more `services'. Each service is */ + /* identified by a constant string and modeled by a pointer; the latter */ + /* generally corresponds to a structure containing function pointers. */ + /* */ + /* Note that a service's data cannot be a mere function pointer because */ + /* in C it is possible that function pointers might be implemented */ + /* differently than data pointers (e.g. 48 bits instead of 32). */ + /* */ + /*************************************************************************/ + + +#ifndef FTSERV_H_ +#define FTSERV_H_ + + +FT_BEGIN_HEADER + + /* + * @macro: + * FT_FACE_FIND_SERVICE + * + * @description: + * This macro is used to look up a service from a face's driver module. + * + * @input: + * face :: + * The source face handle. + * + * id :: + * A string describing the service as defined in the service's + * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * `multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_'. + * + * @output: + * ptr :: + * A variable that receives the service pointer. Will be NULL + * if not found. + */ +#ifdef __cplusplus + +#define FT_FACE_FIND_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_ = NULL; \ + FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ + \ + \ + if ( module->clazz->get_interface ) \ + _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ + *_pptr_ = _tmp_; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_FIND_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_ = NULL; \ + \ + if ( module->clazz->get_interface ) \ + _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ + ptr = _tmp_; \ + FT_END_STMNT + +#endif /* !C++ */ + + + /* + * @macro: + * FT_FACE_FIND_GLOBAL_SERVICE + * + * @description: + * This macro is used to look up a service from all modules. + * + * @input: + * face :: + * The source face handle. + * + * id :: + * A string describing the service as defined in the service's + * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * `multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_'. + * + * @output: + * ptr :: + * A variable that receives the service pointer. Will be NULL + * if not found. + */ +#ifdef __cplusplus + +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ + *_pptr_ = _tmp_; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ + ptr = _tmp_; \ + FT_END_STMNT + +#endif /* !C++ */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S E R V I C E D E S C R I P T O R S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The following structure is used to _describe_ a given service + * to the library. This is useful to build simple static service lists. + */ + typedef struct FT_ServiceDescRec_ + { + const char* serv_id; /* service name */ + const void* serv_data; /* service pointer/data */ + + } FT_ServiceDescRec; + + typedef const FT_ServiceDescRec* FT_ServiceDesc; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_SERVICEDESCREC1 */ + /* FT_DEFINE_SERVICEDESCREC2 */ + /* FT_DEFINE_SERVICEDESCREC3 */ + /* FT_DEFINE_SERVICEDESCREC4 */ + /* FT_DEFINE_SERVICEDESCREC5 */ + /* FT_DEFINE_SERVICEDESCREC6 */ + /* FT_DEFINE_SERVICEDESCREC7 */ + /* */ + /* <Description> */ + /* Used to initialize an array of FT_ServiceDescRec structures. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function needs to */ + /* be called with a pointer to return an allocated array. As soon as */ + /* it is no longer needed, a `destroy' function needs to be called to */ + /* release that allocation. */ + /* */ + /* These functions should be manually called from the `pic_init' and */ + /* `pic_free' functions of your module (see FT_DEFINE_MODULE). */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the array will be */ + /* allocated in the global scope (or the scope where the macro is */ + /* used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICEDESCREC1( class_, \ + serv_id_1, serv_data_1 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC2( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC3( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC4( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC5( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { serv_id_5, serv_data_5 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC6( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { serv_id_5, serv_data_5 }, \ + { serv_id_6, serv_data_6 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC7( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { serv_id_5, serv_data_5 }, \ + { serv_id_6, serv_data_6 }, \ + { serv_id_7, serv_data_7 }, \ + { NULL, NULL } \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICEDESCREC1( class_, \ + serv_id_1, serv_data_1 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 2 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = NULL; \ + clazz[1].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC2( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 3 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = NULL; \ + clazz[2].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC3( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 4 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = NULL; \ + clazz[3].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC4( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 5 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = NULL; \ + clazz[4].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC5( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 6 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = NULL; \ + clazz[5].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC6( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 7 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = serv_id_6; \ + clazz[5].serv_data = serv_data_6; \ + clazz[6].serv_id = NULL; \ + clazz[6].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC7( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 8 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = serv_id_6; \ + clazz[5].serv_data = serv_data_6; \ + clazz[6].serv_id = serv_id_7; \ + clazz[6].serv_data = serv_data_7; \ + clazz[7].serv_id = NULL; \ + clazz[7].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + + /* + * Parse a list of FT_ServiceDescRec descriptors and look for + * a specific service by ID. Note that the last element in the + * array must be { NULL, NULL }, and that the function should + * return NULL if the service isn't available. + * + * This function can be used by modules to implement their + * `get_service' method. + */ + FT_BASE( FT_Pointer ) + ft_service_list_lookup( FT_ServiceDesc service_descriptors, + const char* service_id ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S E R V I C E S C A C H E *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * This structure is used to store a cache for several frequently used + * services. It is the type of `face->internal->services'. You + * should only use FT_FACE_LOOKUP_SERVICE to access it. + * + * All fields should have the type FT_Pointer to relax compilation + * dependencies. We assume the developer isn't completely stupid. + * + * Each field must be named `service_XXXX' where `XXX' corresponds to + * the correct FT_SERVICE_ID_XXXX macro. See the definition of + * FT_FACE_LOOKUP_SERVICE below how this is implemented. + * + */ + typedef struct FT_ServiceCacheRec_ + { + FT_Pointer service_POSTSCRIPT_FONT_NAME; + FT_Pointer service_MULTI_MASTERS; + FT_Pointer service_GLYPH_DICT; + FT_Pointer service_PFR_METRICS; + FT_Pointer service_WINFNT; + + } FT_ServiceCacheRec, *FT_ServiceCache; + + + /* + * A magic number used within the services cache. + */ + + /* ensure that value `1' has the same width as a pointer */ +#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)~(FT_PtrDist)1) + + + /* + * @macro: + * FT_FACE_LOOKUP_SERVICE + * + * @description: + * This macro is used to lookup a service from a face's driver module + * using its cache. + * + * @input: + * face:: + * The source face handle containing the cache. + * + * field :: + * The field name in the cache. + * + * id :: + * The service ID. + * + * @output: + * ptr :: + * A variable receiving the service data. NULL if not available. + */ +#ifdef __cplusplus + +#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Pointer svc; \ + FT_Pointer* Pptr = (FT_Pointer*)&(ptr); \ + \ + \ + svc = FT_FACE( face )->internal->services. service_ ## id; \ + if ( svc == FT_SERVICE_UNAVAILABLE ) \ + svc = NULL; \ + else if ( svc == NULL ) \ + { \ + FT_FACE_FIND_SERVICE( face, svc, id ); \ + \ + FT_FACE( face )->internal->services. service_ ## id = \ + (FT_Pointer)( svc != NULL ? svc \ + : FT_SERVICE_UNAVAILABLE ); \ + } \ + *Pptr = svc; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Pointer svc; \ + \ + \ + svc = FT_FACE( face )->internal->services. service_ ## id; \ + if ( svc == FT_SERVICE_UNAVAILABLE ) \ + svc = NULL; \ + else if ( svc == NULL ) \ + { \ + FT_FACE_FIND_SERVICE( face, svc, id ); \ + \ + FT_FACE( face )->internal->services. service_ ## id = \ + (FT_Pointer)( svc != NULL ? svc \ + : FT_SERVICE_UNAVAILABLE ); \ + } \ + ptr = svc; \ + FT_END_STMNT + +#endif /* !C++ */ + + /* + * A macro used to define new service structure types. + */ + +#define FT_DEFINE_SERVICE( name ) \ + typedef struct FT_Service_ ## name ## Rec_ \ + FT_Service_ ## name ## Rec ; \ + typedef struct FT_Service_ ## name ## Rec_ \ + const * FT_Service_ ## name ; \ + struct FT_Service_ ## name ## Rec_ + + /* */ + + /* + * The header files containing the services. + */ + +#define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h> +#define FT_SERVICE_CID_H <freetype/internal/services/svcid.h> +#define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h> +#define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h> +#define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h> +#define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h> +#define FT_SERVICE_OPENTYPE_VALIDATE_H <freetype/internal/services/svotval.h> +#define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h> +#define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h> +#define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h> +#define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h> +#define FT_SERVICE_PROPERTIES_H <freetype/internal/services/svprop.h> +#define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h> +#define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h> +#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> +#define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h> +#define FT_SERVICE_FONT_FORMAT_H <freetype/internal/services/svfntfmt.h> +#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h> + + /* */ + +FT_END_HEADER + +#endif /* FTSERV_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/ftstream.h b/builddir/freetype-2.7.0/include/freetype/internal/ftstream.h new file mode 100644 index 0000000..6d04875 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/ftstream.h @@ -0,0 +1,536 @@ +/***************************************************************************/ +/* */ +/* ftstream.h */ +/* */ +/* Stream handling (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTSTREAM_H_ +#define FTSTREAM_H_ + + +#include <ft2build.h> +#include FT_SYSTEM_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* format of an 8-bit frame_op value: */ + /* */ + /* bit 76543210 */ + /* xxxxxxes */ + /* */ + /* s is set to 1 if the value is signed. */ + /* e is set to 1 if the value is little-endian. */ + /* xxx is a command. */ + +#define FT_FRAME_OP_SHIFT 2 +#define FT_FRAME_OP_SIGNED 1 +#define FT_FRAME_OP_LITTLE 2 +#define FT_FRAME_OP_COMMAND( x ) ( x >> FT_FRAME_OP_SHIFT ) + +#define FT_MAKE_FRAME_OP( command, little, sign ) \ + ( ( command << FT_FRAME_OP_SHIFT ) | ( little << 1 ) | sign ) + +#define FT_FRAME_OP_END 0 +#define FT_FRAME_OP_START 1 /* start a new frame */ +#define FT_FRAME_OP_BYTE 2 /* read 1-byte value */ +#define FT_FRAME_OP_SHORT 3 /* read 2-byte value */ +#define FT_FRAME_OP_LONG 4 /* read 4-byte value */ +#define FT_FRAME_OP_OFF3 5 /* read 3-byte value */ +#define FT_FRAME_OP_BYTES 6 /* read a bytes sequence */ + + + typedef enum FT_Frame_Op_ + { + ft_frame_end = 0, + ft_frame_start = FT_MAKE_FRAME_OP( FT_FRAME_OP_START, 0, 0 ), + + ft_frame_byte = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 0 ), + ft_frame_schar = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 1 ), + + ft_frame_ushort_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 0 ), + ft_frame_short_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 1 ), + ft_frame_ushort_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 0 ), + ft_frame_short_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 1 ), + + ft_frame_ulong_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 0 ), + ft_frame_long_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 1 ), + ft_frame_ulong_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 0 ), + ft_frame_long_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 1 ), + + ft_frame_uoff3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 0 ), + ft_frame_off3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 1 ), + ft_frame_uoff3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 0 ), + ft_frame_off3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 1 ), + + ft_frame_bytes = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 0 ), + ft_frame_skip = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 1 ) + + } FT_Frame_Op; + + + typedef struct FT_Frame_Field_ + { + FT_Byte value; + FT_Byte size; + FT_UShort offset; + + } FT_Frame_Field; + + + /* Construct an FT_Frame_Field out of a structure type and a field name. */ + /* The structure type must be set in the FT_STRUCTURE macro before */ + /* calling the FT_FRAME_START() macro. */ + /* */ +#define FT_FIELD_SIZE( f ) \ + (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f ) + +#define FT_FIELD_SIZE_DELTA( f ) \ + (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f[0] ) + +#define FT_FIELD_OFFSET( f ) \ + (FT_UShort)( offsetof( FT_STRUCTURE, f ) ) + +#define FT_FRAME_FIELD( frame_op, field ) \ + { \ + frame_op, \ + FT_FIELD_SIZE( field ), \ + FT_FIELD_OFFSET( field ) \ + } + +#define FT_MAKE_EMPTY_FIELD( frame_op ) { frame_op, 0, 0 } + +#define FT_FRAME_START( size ) { ft_frame_start, 0, size } +#define FT_FRAME_END { ft_frame_end, 0, 0 } + +#define FT_FRAME_LONG( f ) FT_FRAME_FIELD( ft_frame_long_be, f ) +#define FT_FRAME_ULONG( f ) FT_FRAME_FIELD( ft_frame_ulong_be, f ) +#define FT_FRAME_SHORT( f ) FT_FRAME_FIELD( ft_frame_short_be, f ) +#define FT_FRAME_USHORT( f ) FT_FRAME_FIELD( ft_frame_ushort_be, f ) +#define FT_FRAME_OFF3( f ) FT_FRAME_FIELD( ft_frame_off3_be, f ) +#define FT_FRAME_UOFF3( f ) FT_FRAME_FIELD( ft_frame_uoff3_be, f ) +#define FT_FRAME_BYTE( f ) FT_FRAME_FIELD( ft_frame_byte, f ) +#define FT_FRAME_CHAR( f ) FT_FRAME_FIELD( ft_frame_schar, f ) + +#define FT_FRAME_LONG_LE( f ) FT_FRAME_FIELD( ft_frame_long_le, f ) +#define FT_FRAME_ULONG_LE( f ) FT_FRAME_FIELD( ft_frame_ulong_le, f ) +#define FT_FRAME_SHORT_LE( f ) FT_FRAME_FIELD( ft_frame_short_le, f ) +#define FT_FRAME_USHORT_LE( f ) FT_FRAME_FIELD( ft_frame_ushort_le, f ) +#define FT_FRAME_OFF3_LE( f ) FT_FRAME_FIELD( ft_frame_off3_le, f ) +#define FT_FRAME_UOFF3_LE( f ) FT_FRAME_FIELD( ft_frame_uoff3_le, f ) + +#define FT_FRAME_SKIP_LONG { ft_frame_long_be, 0, 0 } +#define FT_FRAME_SKIP_SHORT { ft_frame_short_be, 0, 0 } +#define FT_FRAME_SKIP_BYTE { ft_frame_byte, 0, 0 } + +#define FT_FRAME_BYTES( field, count ) \ + { \ + ft_frame_bytes, \ + count, \ + FT_FIELD_OFFSET( field ) \ + } + +#define FT_FRAME_SKIP_BYTES( count ) { ft_frame_skip, count, 0 } + + + /*************************************************************************/ + /* */ + /* Integer extraction macros -- the `buffer' parameter must ALWAYS be of */ + /* type `char*' or equivalent (1-byte elements). */ + /* */ + +#define FT_BYTE_( p, i ) ( ((const FT_Byte*)(p))[(i)] ) + +#define FT_INT16( x ) ( (FT_Int16)(x) ) +#define FT_UINT16( x ) ( (FT_UInt16)(x) ) +#define FT_INT32( x ) ( (FT_Int32)(x) ) +#define FT_UINT32( x ) ( (FT_UInt32)(x) ) + + +#define FT_BYTE_U16( p, i, s ) ( FT_UINT16( FT_BYTE_( p, i ) ) << (s) ) +#define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) ) + + +#define FT_PEEK_SHORT( p ) FT_INT16( FT_BYTE_U16( p, 0, 8) | \ + FT_BYTE_U16( p, 1, 0) ) + +#define FT_PEEK_USHORT( p ) FT_UINT16( FT_BYTE_U16( p, 0, 8 ) | \ + FT_BYTE_U16( p, 1, 0 ) ) + +#define FT_PEEK_LONG( p ) FT_INT32( FT_BYTE_U32( p, 0, 24 ) | \ + FT_BYTE_U32( p, 1, 16 ) | \ + FT_BYTE_U32( p, 2, 8 ) | \ + FT_BYTE_U32( p, 3, 0 ) ) + +#define FT_PEEK_ULONG( p ) FT_UINT32( FT_BYTE_U32( p, 0, 24 ) | \ + FT_BYTE_U32( p, 1, 16 ) | \ + FT_BYTE_U32( p, 2, 8 ) | \ + FT_BYTE_U32( p, 3, 0 ) ) + +#define FT_PEEK_OFF3( p ) FT_INT32( FT_BYTE_U32( p, 0, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 2, 0 ) ) + +#define FT_PEEK_UOFF3( p ) FT_UINT32( FT_BYTE_U32( p, 0, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 2, 0 ) ) + +#define FT_PEEK_SHORT_LE( p ) FT_INT16( FT_BYTE_U16( p, 1, 8 ) | \ + FT_BYTE_U16( p, 0, 0 ) ) + +#define FT_PEEK_USHORT_LE( p ) FT_UINT16( FT_BYTE_U16( p, 1, 8 ) | \ + FT_BYTE_U16( p, 0, 0 ) ) + +#define FT_PEEK_LONG_LE( p ) FT_INT32( FT_BYTE_U32( p, 3, 24 ) | \ + FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + +#define FT_PEEK_ULONG_LE( p ) FT_UINT32( FT_BYTE_U32( p, 3, 24 ) | \ + FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + +#define FT_PEEK_OFF3_LE( p ) FT_INT32( FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + +#define FT_PEEK_UOFF3_LE( p ) FT_UINT32( FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + + +#define FT_NEXT_CHAR( buffer ) \ + ( (signed char)*buffer++ ) + +#define FT_NEXT_BYTE( buffer ) \ + ( (unsigned char)*buffer++ ) + +#define FT_NEXT_SHORT( buffer ) \ + ( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) ) + +#define FT_NEXT_USHORT( buffer ) \ + ( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) ) + +#define FT_NEXT_OFF3( buffer ) \ + ( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) ) + +#define FT_NEXT_UOFF3( buffer ) \ + ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) ) + +#define FT_NEXT_LONG( buffer ) \ + ( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) ) + +#define FT_NEXT_ULONG( buffer ) \ + ( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) ) + + +#define FT_NEXT_SHORT_LE( buffer ) \ + ( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) ) + +#define FT_NEXT_USHORT_LE( buffer ) \ + ( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) ) + +#define FT_NEXT_OFF3_LE( buffer ) \ + ( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) ) + +#define FT_NEXT_UOFF3_LE( buffer ) \ + ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) ) + +#define FT_NEXT_LONG_LE( buffer ) \ + ( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) ) + +#define FT_NEXT_ULONG_LE( buffer ) \ + ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) ) + + + /*************************************************************************/ + /* */ + /* Each GET_xxxx() macro uses an implicit `stream' variable. */ + /* */ +#if 0 +#define FT_GET_MACRO( type ) FT_NEXT_ ## type ( stream->cursor ) + +#define FT_GET_CHAR() FT_GET_MACRO( CHAR ) +#define FT_GET_BYTE() FT_GET_MACRO( BYTE ) +#define FT_GET_SHORT() FT_GET_MACRO( SHORT ) +#define FT_GET_USHORT() FT_GET_MACRO( USHORT ) +#define FT_GET_OFF3() FT_GET_MACRO( OFF3 ) +#define FT_GET_UOFF3() FT_GET_MACRO( UOFF3 ) +#define FT_GET_LONG() FT_GET_MACRO( LONG ) +#define FT_GET_ULONG() FT_GET_MACRO( ULONG ) +#define FT_GET_TAG4() FT_GET_MACRO( ULONG ) + +#define FT_GET_SHORT_LE() FT_GET_MACRO( SHORT_LE ) +#define FT_GET_USHORT_LE() FT_GET_MACRO( USHORT_LE ) +#define FT_GET_LONG_LE() FT_GET_MACRO( LONG_LE ) +#define FT_GET_ULONG_LE() FT_GET_MACRO( ULONG_LE ) + +#else +#define FT_GET_MACRO( func, type ) ( (type)func( stream ) ) + +#define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetChar, FT_Char ) +#define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetChar, FT_Byte ) +#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_Short ) +#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetUShort, FT_UShort ) +#define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_Long ) +#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_ULong ) +#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetULong, FT_Long ) +#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetULong, FT_ULong ) +#define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetULong, FT_ULong ) + +#define FT_GET_SHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Short ) +#define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UShort ) +#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_Long ) +#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetULongLE, FT_ULong ) +#endif + +#define FT_READ_MACRO( func, type, var ) \ + ( var = (type)func( stream, &error ), \ + error != FT_Err_Ok ) + +#define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var ) +#define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var ) +#define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_Short, var ) +#define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadUShort, FT_UShort, var ) +#define FT_READ_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_Long, var ) +#define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_ULong, var ) +#define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_Long, var ) +#define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadULong, FT_ULong, var ) + +#define FT_READ_SHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Short, var ) +#define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UShort, var ) +#define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Long, var ) +#define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadULongLE, FT_ULong, var ) + + +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM + + /* initialize a stream for reading a regular system stream */ + FT_BASE( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ); + +#endif /* FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ + + + /* create a new (input) stream from an FT_Open_Args structure */ + FT_BASE( FT_Error ) + FT_Stream_New( FT_Library library, + const FT_Open_Args* args, + FT_Stream *astream ); + + /* free a stream */ + FT_BASE( void ) + FT_Stream_Free( FT_Stream stream, + FT_Int external ); + + /* initialize a stream for reading in-memory data */ + FT_BASE( void ) + FT_Stream_OpenMemory( FT_Stream stream, + const FT_Byte* base, + FT_ULong size ); + + /* close a stream (does not destroy the stream structure) */ + FT_BASE( void ) + FT_Stream_Close( FT_Stream stream ); + + + /* seek within a stream. position is relative to start of stream */ + FT_BASE( FT_Error ) + FT_Stream_Seek( FT_Stream stream, + FT_ULong pos ); + + /* skip bytes in a stream */ + FT_BASE( FT_Error ) + FT_Stream_Skip( FT_Stream stream, + FT_Long distance ); + + /* return current stream position */ + FT_BASE( FT_ULong ) + FT_Stream_Pos( FT_Stream stream ); + + /* read bytes from a stream into a user-allocated buffer, returns an */ + /* error if not all bytes could be read. */ + FT_BASE( FT_Error ) + FT_Stream_Read( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ); + + /* read bytes from a stream at a given position */ + FT_BASE( FT_Error ) + FT_Stream_ReadAt( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ); + + /* try to read bytes at the end of a stream; return number of bytes */ + /* really available */ + FT_BASE( FT_ULong ) + FT_Stream_TryRead( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ); + + /* Enter a frame of `count' consecutive bytes in a stream. Returns an */ + /* error if the frame could not be read/accessed. The caller can use */ + /* the FT_Stream_Get_XXX functions to retrieve frame data without */ + /* error checks. */ + /* */ + /* You must _always_ call FT_Stream_ExitFrame() once you have entered */ + /* a stream frame! */ + /* */ + FT_BASE( FT_Error ) + FT_Stream_EnterFrame( FT_Stream stream, + FT_ULong count ); + + /* exit a stream frame */ + FT_BASE( void ) + FT_Stream_ExitFrame( FT_Stream stream ); + + /* Extract a stream frame. If the stream is disk-based, a heap block */ + /* is allocated and the frame bytes are read into it. If the stream */ + /* is memory-based, this function simply set a pointer to the data. */ + /* */ + /* Useful to optimize access to memory-based streams transparently. */ + /* */ + /* All extracted frames must be `freed' with a call to the function */ + /* FT_Stream_ReleaseFrame(). */ + /* */ + FT_BASE( FT_Error ) + FT_Stream_ExtractFrame( FT_Stream stream, + FT_ULong count, + FT_Byte** pbytes ); + + /* release an extract frame (see FT_Stream_ExtractFrame) */ + FT_BASE( void ) + FT_Stream_ReleaseFrame( FT_Stream stream, + FT_Byte** pbytes ); + + /* read a byte from an entered frame */ + FT_BASE( FT_Char ) + FT_Stream_GetChar( FT_Stream stream ); + + /* read a 16-bit big-endian unsigned integer from an entered frame */ + FT_BASE( FT_UShort ) + FT_Stream_GetUShort( FT_Stream stream ); + + /* read a 24-bit big-endian unsigned integer from an entered frame */ + FT_BASE( FT_ULong ) + FT_Stream_GetUOffset( FT_Stream stream ); + + /* read a 32-bit big-endian unsigned integer from an entered frame */ + FT_BASE( FT_ULong ) + FT_Stream_GetULong( FT_Stream stream ); + + /* read a 16-bit little-endian unsigned integer from an entered frame */ + FT_BASE( FT_UShort ) + FT_Stream_GetUShortLE( FT_Stream stream ); + + /* read a 32-bit little-endian unsigned integer from an entered frame */ + FT_BASE( FT_ULong ) + FT_Stream_GetULongLE( FT_Stream stream ); + + + /* read a byte from a stream */ + FT_BASE( FT_Char ) + FT_Stream_ReadChar( FT_Stream stream, + FT_Error* error ); + + /* read a 16-bit big-endian unsigned integer from a stream */ + FT_BASE( FT_UShort ) + FT_Stream_ReadUShort( FT_Stream stream, + FT_Error* error ); + + /* read a 24-bit big-endian unsigned integer from a stream */ + FT_BASE( FT_ULong ) + FT_Stream_ReadUOffset( FT_Stream stream, + FT_Error* error ); + + /* read a 32-bit big-endian integer from a stream */ + FT_BASE( FT_ULong ) + FT_Stream_ReadULong( FT_Stream stream, + FT_Error* error ); + + /* read a 16-bit little-endian unsigned integer from a stream */ + FT_BASE( FT_UShort ) + FT_Stream_ReadUShortLE( FT_Stream stream, + FT_Error* error ); + + /* read a 32-bit little-endian unsigned integer from a stream */ + FT_BASE( FT_ULong ) + FT_Stream_ReadULongLE( FT_Stream stream, + FT_Error* error ); + + /* Read a structure from a stream. The structure must be described */ + /* by an array of FT_Frame_Field records. */ + FT_BASE( FT_Error ) + FT_Stream_ReadFields( FT_Stream stream, + const FT_Frame_Field* fields, + void* structure ); + + +#define FT_STREAM_POS() \ + FT_Stream_Pos( stream ) + +#define FT_STREAM_SEEK( position ) \ + FT_SET_ERROR( FT_Stream_Seek( stream, \ + (FT_ULong)(position) ) ) + +#define FT_STREAM_SKIP( distance ) \ + FT_SET_ERROR( FT_Stream_Skip( stream, \ + (FT_Long)(distance) ) ) + +#define FT_STREAM_READ( buffer, count ) \ + FT_SET_ERROR( FT_Stream_Read( stream, \ + (FT_Byte*)(buffer), \ + (FT_ULong)(count) ) ) + +#define FT_STREAM_READ_AT( position, buffer, count ) \ + FT_SET_ERROR( FT_Stream_ReadAt( stream, \ + (FT_ULong)(position), \ + (FT_Byte*)buffer, \ + (FT_ULong)(count) ) ) + +#define FT_STREAM_READ_FIELDS( fields, object ) \ + FT_SET_ERROR( FT_Stream_ReadFields( stream, fields, object ) ) + + +#define FT_FRAME_ENTER( size ) \ + FT_SET_ERROR( \ + FT_DEBUG_INNER( FT_Stream_EnterFrame( stream, \ + (FT_ULong)(size) ) ) ) + +#define FT_FRAME_EXIT() \ + FT_DEBUG_INNER( FT_Stream_ExitFrame( stream ) ) + +#define FT_FRAME_EXTRACT( size, bytes ) \ + FT_SET_ERROR( \ + FT_DEBUG_INNER( FT_Stream_ExtractFrame( stream, \ + (FT_ULong)(size), \ + (FT_Byte**)&(bytes) ) ) ) + +#define FT_FRAME_RELEASE( bytes ) \ + FT_DEBUG_INNER( FT_Stream_ReleaseFrame( stream, \ + (FT_Byte**)&(bytes) ) ) + + +FT_END_HEADER + +#endif /* FTSTREAM_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/fttrace.h b/builddir/freetype-2.7.0/include/freetype/internal/fttrace.h new file mode 100644 index 0000000..efb3355 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/fttrace.h @@ -0,0 +1,154 @@ +/***************************************************************************/ +/* */ +/* fttrace.h */ +/* */ +/* Tracing handling (specification only). */ +/* */ +/* Copyright 2002-2016 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. */ +/* */ +/***************************************************************************/ + + + /* definitions of trace levels for FreeType 2 */ + + /* the first level must always be `trace_any' */ +FT_TRACE_DEF( any ) + + /* base components */ +FT_TRACE_DEF( calc ) /* calculations (ftcalc.c) */ +FT_TRACE_DEF( memory ) /* memory manager (ftobjs.c) */ +FT_TRACE_DEF( stream ) /* stream manager (ftstream.c) */ +FT_TRACE_DEF( io ) /* i/o interface (ftsystem.c) */ +FT_TRACE_DEF( list ) /* list management (ftlist.c) */ +FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ +FT_TRACE_DEF( objs ) /* base objects (ftobjs.c) */ +FT_TRACE_DEF( outline ) /* outline management (ftoutln.c) */ +FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ +FT_TRACE_DEF( gloader ) /* glyph loader (ftgloadr.c) */ + +FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ +FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ +FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ +FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ +FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */ +FT_TRACE_DEF( bitmap ) /* bitmap checksum (ftobjs.c) */ + + /* Cache sub-system */ +FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ + + /* SFNT driver components */ +FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */ +FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ +FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ +FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */ +FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ +FT_TRACE_DEF( ttmtx ) /* metrics-related tables (ttmtx.c) */ +FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ +FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ +FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */ + + /* TrueType driver components */ +FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */ +FT_TRACE_DEF( ttgload ) /* TT glyph loader (ttgload.c) */ +FT_TRACE_DEF( ttinterp ) /* bytecode interpreter (ttinterp.c) */ +FT_TRACE_DEF( ttobjs ) /* TT objects manager (ttobjs.c) */ +FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */ +FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ + + /* Type 1 driver components */ +FT_TRACE_DEF( t1afm ) +FT_TRACE_DEF( t1driver ) +FT_TRACE_DEF( t1gload ) +FT_TRACE_DEF( t1hint ) +FT_TRACE_DEF( t1load ) +FT_TRACE_DEF( t1objs ) +FT_TRACE_DEF( t1parse ) + + /* PostScript helper module `psaux' */ +FT_TRACE_DEF( t1decode ) +FT_TRACE_DEF( psobjs ) +FT_TRACE_DEF( psconv ) + + /* PostScript hinting module `pshinter' */ +FT_TRACE_DEF( pshrec ) +FT_TRACE_DEF( pshalgo1 ) +FT_TRACE_DEF( pshalgo2 ) + + /* Type 2 driver components */ +FT_TRACE_DEF( cffdriver ) +FT_TRACE_DEF( cffgload ) +FT_TRACE_DEF( cffload ) +FT_TRACE_DEF( cffobjs ) +FT_TRACE_DEF( cffparse ) + +FT_TRACE_DEF( cf2blues ) +FT_TRACE_DEF( cf2hints ) +FT_TRACE_DEF( cf2interp ) + + /* Type 42 driver component */ +FT_TRACE_DEF( t42 ) + + /* CID driver components */ +FT_TRACE_DEF( cidafm ) +FT_TRACE_DEF( ciddriver ) +FT_TRACE_DEF( cidgload ) +FT_TRACE_DEF( cidload ) +FT_TRACE_DEF( cidobjs ) +FT_TRACE_DEF( cidparse ) + + /* Windows font component */ +FT_TRACE_DEF( winfnt ) + + /* PCF font components */ +FT_TRACE_DEF( pcfdriver ) +FT_TRACE_DEF( pcfread ) + + /* BDF font components */ +FT_TRACE_DEF( bdfdriver ) +FT_TRACE_DEF( bdflib ) + + /* PFR font component */ +FT_TRACE_DEF( pfr ) + + /* OpenType validation components */ +FT_TRACE_DEF( otvmodule ) +FT_TRACE_DEF( otvcommon ) +FT_TRACE_DEF( otvbase ) +FT_TRACE_DEF( otvgdef ) +FT_TRACE_DEF( otvgpos ) +FT_TRACE_DEF( otvgsub ) +FT_TRACE_DEF( otvjstf ) +FT_TRACE_DEF( otvmath ) + + /* TrueTypeGX/AAT validation components */ +FT_TRACE_DEF( gxvmodule ) +FT_TRACE_DEF( gxvcommon ) +FT_TRACE_DEF( gxvfeat ) +FT_TRACE_DEF( gxvmort ) +FT_TRACE_DEF( gxvmorx ) +FT_TRACE_DEF( gxvbsln ) +FT_TRACE_DEF( gxvjust ) +FT_TRACE_DEF( gxvkern ) +FT_TRACE_DEF( gxvopbd ) +FT_TRACE_DEF( gxvtrak ) +FT_TRACE_DEF( gxvprop ) +FT_TRACE_DEF( gxvlcar ) + + /* autofit components */ +FT_TRACE_DEF( afmodule ) +FT_TRACE_DEF( afhints ) +FT_TRACE_DEF( afcjk ) +FT_TRACE_DEF( aflatin ) +FT_TRACE_DEF( aflatin2 ) +FT_TRACE_DEF( afwarp ) +FT_TRACE_DEF( afshaper ) +FT_TRACE_DEF( afglobal ) + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/ftvalid.h b/builddir/freetype-2.7.0/include/freetype/internal/ftvalid.h new file mode 100644 index 0000000..aac92c9 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/ftvalid.h @@ -0,0 +1,159 @@ +/***************************************************************************/ +/* */ +/* ftvalid.h */ +/* */ +/* FreeType validation support (specification). */ +/* */ +/* Copyright 2004-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef FTVALID_H_ +#define FTVALID_H_ + +#include <ft2build.h> +#include FT_CONFIG_STANDARD_LIBRARY_H /* for ft_setjmp and ft_longjmp */ + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** V A L I D A T I O N ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to a validation object */ + typedef struct FT_ValidatorRec_ volatile* FT_Validator; + + + /*************************************************************************/ + /* */ + /* There are three distinct validation levels defined here: */ + /* */ + /* FT_VALIDATE_DEFAULT :: */ + /* A table that passes this validation level can be used reliably by */ + /* FreeType. It generally means that all offsets have been checked to */ + /* prevent out-of-bound reads, that array counts are correct, etc. */ + /* */ + /* FT_VALIDATE_TIGHT :: */ + /* A table that passes this validation level can be used reliably and */ + /* doesn't contain invalid data. For example, a charmap table that */ + /* returns invalid glyph indices will not pass, even though it can */ + /* be used with FreeType in default mode (the library will simply */ + /* return an error later when trying to load the glyph). */ + /* */ + /* It also checks that fields which must be a multiple of 2, 4, or 8, */ + /* don't have incorrect values, etc. */ + /* */ + /* FT_VALIDATE_PARANOID :: */ + /* Only for font debugging. Checks that a table follows the */ + /* specification by 100%. Very few fonts will be able to pass this */ + /* level anyway but it can be useful for certain tools like font */ + /* editors/converters. */ + /* */ + typedef enum FT_ValidationLevel_ + { + FT_VALIDATE_DEFAULT = 0, + FT_VALIDATE_TIGHT, + FT_VALIDATE_PARANOID + + } FT_ValidationLevel; + + +#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ + /* We disable the warning `structure was padded due to */ + /* __declspec(align())' in order to compile cleanly with */ + /* the maximum level of warnings. */ +#pragma warning( push ) +#pragma warning( disable : 4324 ) +#endif /* _MSC_VER */ + + /* validator structure */ + typedef struct FT_ValidatorRec_ + { + ft_jmp_buf jump_buffer; /* used for exception handling */ + + const FT_Byte* base; /* address of table in memory */ + const FT_Byte* limit; /* `base' + sizeof(table) in memory */ + FT_ValidationLevel level; /* validation level */ + FT_Error error; /* error returned. 0 means success */ + + } FT_ValidatorRec; + +#if defined( _MSC_VER ) +#pragma warning( pop ) +#endif + +#define FT_VALIDATOR( x ) ( (FT_Validator)( x ) ) + + + FT_BASE( void ) + ft_validator_init( FT_Validator valid, + const FT_Byte* base, + const FT_Byte* limit, + FT_ValidationLevel level ); + + /* Do not use this. It's broken and will cause your validator to crash */ + /* if you run it on an invalid font. */ + FT_BASE( FT_Int ) + ft_validator_run( FT_Validator valid ); + + /* Sets the error field in a validator, then calls `longjmp' to return */ + /* to high-level caller. Using `setjmp/longjmp' avoids many stupid */ + /* error checks within the validation routines. */ + /* */ + FT_BASE( void ) + ft_validator_error( FT_Validator valid, + FT_Error error ); + + + /* Calls ft_validate_error. Assumes that the `valid' local variable */ + /* holds a pointer to the current validator object. */ + /* */ +#define FT_INVALID( _error ) FT_INVALID_( _error ) +#define FT_INVALID_( _error ) \ + ft_validator_error( valid, FT_THROW( _error ) ) + + /* called when a broken table is detected */ +#define FT_INVALID_TOO_SHORT \ + FT_INVALID( Invalid_Table ) + + /* called when an invalid offset is detected */ +#define FT_INVALID_OFFSET \ + FT_INVALID( Invalid_Offset ) + + /* called when an invalid format/value is detected */ +#define FT_INVALID_FORMAT \ + FT_INVALID( Invalid_Table ) + + /* called when an invalid glyph index is detected */ +#define FT_INVALID_GLYPH_ID \ + FT_INVALID( Invalid_Glyph_Index ) + + /* called when an invalid field value is detected */ +#define FT_INVALID_DATA \ + FT_INVALID( Invalid_Table ) + + +FT_END_HEADER + +#endif /* FTVALID_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/internal.h b/builddir/freetype-2.7.0/include/freetype/internal/internal.h new file mode 100644 index 0000000..8c3c14c --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/internal.h @@ -0,0 +1,63 @@ +/***************************************************************************/ +/* */ +/* internal.h */ +/* */ +/* Internal header files (specification only). */ +/* */ +/* Copyright 1996-2016 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 file is automatically included by `ft2build.h'. */ + /* Do not include it manually! */ + /* */ + /*************************************************************************/ + + +#define FT_INTERNAL_OBJECTS_H <freetype/internal/ftobjs.h> +#define FT_INTERNAL_PIC_H <freetype/internal/ftpic.h> +#define FT_INTERNAL_STREAM_H <freetype/internal/ftstream.h> +#define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> +#define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> +#define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> +#define FT_INTERNAL_HASH_H <freetype/internal/fthash.h> +#define FT_INTERNAL_DRIVER_H <freetype/internal/ftdriver.h> +#define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> +#define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> +#define FT_INTERNAL_SFNT_H <freetype/internal/sfnt.h> +#define FT_INTERNAL_SERVICE_H <freetype/internal/ftserv.h> +#define FT_INTERNAL_RFORK_H <freetype/internal/ftrfork.h> +#define FT_INTERNAL_VALIDATE_H <freetype/internal/ftvalid.h> + +#define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h> +#define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h> + +#define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> +#define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> + +#define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> + + +#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. */ + /* In particular, the warning complains about stuff like `while(0)' */ + /* which is very useful in macro definitions. There is no benefit */ + /* in having it enabled. */ +#pragma warning( disable : 4127 ) + +#endif /* _MSC_VER */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/psaux.h b/builddir/freetype-2.7.0/include/freetype/internal/psaux.h new file mode 100644 index 0000000..15dedfd --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/psaux.h @@ -0,0 +1,879 @@ +/***************************************************************************/ +/* */ +/* psaux.h */ +/* */ +/* Auxiliary functions and data structures related to PostScript fonts */ +/* (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef PSAUX_H_ +#define PSAUX_H_ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_HASH_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct PS_TableRec_* PS_Table; + typedef const struct PS_Table_FuncsRec_* PS_Table_Funcs; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Table_FuncsRec */ + /* */ + /* <Description> */ + /* A set of function pointers to manage PS_Table objects. */ + /* */ + /* <Fields> */ + /* table_init :: Used to initialize a table. */ + /* */ + /* table_done :: Finalizes resp. destroy a given table. */ + /* */ + /* table_add :: Adds a new object to a table. */ + /* */ + /* table_release :: Releases table data, then finalizes it. */ + /* */ + typedef struct PS_Table_FuncsRec_ + { + FT_Error + (*init)( PS_Table table, + FT_Int count, + FT_Memory memory ); + + void + (*done)( PS_Table table ); + + FT_Error + (*add)( PS_Table table, + FT_Int idx, + void* object, + FT_UInt length ); + + void + (*release)( PS_Table table ); + + } PS_Table_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_TableRec */ + /* */ + /* <Description> */ + /* A PS_Table is a simple object used to store an array of objects in */ + /* a single memory block. */ + /* */ + /* <Fields> */ + /* block :: The address in memory of the growheap's block. This */ + /* can change between two object adds, due to */ + /* reallocation. */ + /* */ + /* cursor :: The current top of the grow heap within its block. */ + /* */ + /* capacity :: The current size of the heap block. Increments by */ + /* 1kByte chunks. */ + /* */ + /* init :: Set to 0xDEADBEEF if `elements' and `lengths' have */ + /* been allocated. */ + /* */ + /* max_elems :: The maximum number of elements in table. */ + /* */ + /* num_elems :: The current number of elements in table. */ + /* */ + /* elements :: A table of element addresses within the block. */ + /* */ + /* lengths :: A table of element sizes within the block. */ + /* */ + /* memory :: The object used for memory operations */ + /* (alloc/realloc). */ + /* */ + /* funcs :: A table of method pointers for this object. */ + /* */ + typedef struct PS_TableRec_ + { + FT_Byte* block; /* current memory block */ + FT_Offset cursor; /* current cursor in memory block */ + FT_Offset capacity; /* current size of memory block */ + FT_ULong init; + + FT_Int max_elems; + FT_Int num_elems; + FT_Byte** elements; /* addresses of table elements */ + FT_UInt* lengths; /* lengths of table elements */ + + FT_Memory memory; + PS_Table_FuncsRec funcs; + + } PS_TableRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 FIELDS & TOKENS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PS_ParserRec_* PS_Parser; + + typedef struct T1_TokenRec_* T1_Token; + + typedef struct T1_FieldRec_* T1_Field; + + + /* simple enumeration type used to identify token types */ + typedef enum T1_TokenType_ + { + T1_TOKEN_TYPE_NONE = 0, + T1_TOKEN_TYPE_ANY, + T1_TOKEN_TYPE_STRING, + T1_TOKEN_TYPE_ARRAY, + T1_TOKEN_TYPE_KEY, /* aka `name' */ + + /* do not remove */ + T1_TOKEN_TYPE_MAX + + } T1_TokenType; + + + /* a simple structure used to identify tokens */ + typedef struct T1_TokenRec_ + { + FT_Byte* start; /* first character of token in input stream */ + FT_Byte* limit; /* first character after the token */ + T1_TokenType type; /* type of token */ + + } T1_TokenRec; + + + /* enumeration type used to identify object fields */ + typedef enum T1_FieldType_ + { + T1_FIELD_TYPE_NONE = 0, + T1_FIELD_TYPE_BOOL, + T1_FIELD_TYPE_INTEGER, + T1_FIELD_TYPE_FIXED, + T1_FIELD_TYPE_FIXED_1000, + T1_FIELD_TYPE_STRING, + T1_FIELD_TYPE_KEY, + T1_FIELD_TYPE_BBOX, + T1_FIELD_TYPE_MM_BBOX, + T1_FIELD_TYPE_INTEGER_ARRAY, + T1_FIELD_TYPE_FIXED_ARRAY, + T1_FIELD_TYPE_CALLBACK, + + /* do not remove */ + T1_FIELD_TYPE_MAX + + } T1_FieldType; + + + typedef enum T1_FieldLocation_ + { + T1_FIELD_LOCATION_CID_INFO, + T1_FIELD_LOCATION_FONT_DICT, + T1_FIELD_LOCATION_FONT_EXTRA, + T1_FIELD_LOCATION_FONT_INFO, + T1_FIELD_LOCATION_PRIVATE, + T1_FIELD_LOCATION_BBOX, + T1_FIELD_LOCATION_LOADER, + T1_FIELD_LOCATION_FACE, + T1_FIELD_LOCATION_BLEND, + + /* do not remove */ + T1_FIELD_LOCATION_MAX + + } T1_FieldLocation; + + + typedef void + (*T1_Field_ParseFunc)( FT_Face face, + FT_Pointer parser ); + + + /* structure type used to model object fields */ + typedef struct T1_FieldRec_ + { + const char* ident; /* field identifier */ + T1_FieldLocation location; + T1_FieldType type; /* type of field */ + T1_Field_ParseFunc reader; + FT_UInt offset; /* offset of field in object */ + FT_Byte size; /* size of field in bytes */ + FT_UInt array_max; /* maximum number of elements for */ + /* array */ + FT_UInt count_offset; /* offset of element count for */ + /* arrays; must not be zero if in */ + /* use -- in other words, a */ + /* `num_FOO' element must not */ + /* start the used structure if we */ + /* parse a `FOO' array */ + FT_UInt dict; /* where we expect it */ + } T1_FieldRec; + +#define T1_FIELD_DICT_FONTDICT ( 1 << 0 ) /* also FontInfo and FDArray */ +#define T1_FIELD_DICT_PRIVATE ( 1 << 1 ) + + + +#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE( _fname ), \ + 0, 0, \ + _dict \ + }, + +#define T1_NEW_CALLBACK_FIELD( _ident, _reader, _dict ) \ + { \ + _ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \ + (T1_Field_ParseFunc)_reader, \ + 0, 0, \ + 0, 0, \ + _dict \ + }, + +#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, \ + FT_FIELD_OFFSET( num_ ## _fname ), \ + _dict \ + }, + +#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, 0, \ + _dict \ + }, + + +#define T1_FIELD_BOOL( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname, _dict ) + +#define T1_FIELD_NUM( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname, _dict ) + +#define T1_FIELD_FIXED( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname, _dict ) + +#define T1_FIELD_FIXED_1000( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname, \ + _dict ) + +#define T1_FIELD_STRING( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname, _dict ) + +#define T1_FIELD_KEY( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname, _dict ) + +#define T1_FIELD_BBOX( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname, _dict ) + + +#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_CALLBACK( _ident, _name, _dict ) \ + T1_NEW_CALLBACK_FIELD( _ident, _name, _dict ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef const struct PS_Parser_FuncsRec_* PS_Parser_Funcs; + + typedef struct PS_Parser_FuncsRec_ + { + void + (*init)( PS_Parser parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ); + + void + (*done)( PS_Parser parser ); + + void + (*skip_spaces)( PS_Parser parser ); + void + (*skip_PS_token)( PS_Parser parser ); + + FT_Long + (*to_int)( PS_Parser parser ); + FT_Fixed + (*to_fixed)( PS_Parser parser, + FT_Int power_ten ); + + FT_Error + (*to_bytes)( PS_Parser parser, + FT_Byte* bytes, + FT_Offset max_bytes, + FT_ULong* pnum_bytes, + FT_Bool delimiters ); + + FT_Int + (*to_coord_array)( PS_Parser parser, + FT_Int max_coords, + FT_Short* coords ); + FT_Int + (*to_fixed_array)( PS_Parser parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ); + + void + (*to_token)( PS_Parser parser, + T1_Token token ); + void + (*to_token_array)( PS_Parser parser, + T1_Token tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ); + + FT_Error + (*load_field)( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_Error + (*load_field_table)( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + } PS_Parser_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_ParserRec */ + /* */ + /* <Description> */ + /* A PS_Parser is an object used to parse a Type 1 font very quickly. */ + /* */ + /* <Fields> */ + /* cursor :: The current position in the text. */ + /* */ + /* base :: Start of the processed text. */ + /* */ + /* limit :: End of the processed text. */ + /* */ + /* error :: The last error returned. */ + /* */ + /* memory :: The object used for memory operations (alloc/realloc). */ + /* */ + /* funcs :: A table of functions for the parser. */ + /* */ + typedef struct PS_ParserRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + FT_Error error; + FT_Memory memory; + + PS_Parser_FuncsRec funcs; + + } PS_ParserRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct T1_BuilderRec_* T1_Builder; + + + typedef FT_Error + (*T1_Builder_Check_Points_Func)( T1_Builder builder, + FT_Int count ); + + typedef void + (*T1_Builder_Add_Point_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + + typedef FT_Error + (*T1_Builder_Add_Point1_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + typedef FT_Error + (*T1_Builder_Add_Contour_Func)( T1_Builder builder ); + + typedef FT_Error + (*T1_Builder_Start_Point_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + typedef void + (*T1_Builder_Close_Contour_Func)( T1_Builder builder ); + + + typedef const struct T1_Builder_FuncsRec_* T1_Builder_Funcs; + + typedef struct T1_Builder_FuncsRec_ + { + void + (*init)( T1_Builder builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Bool hinting ); + + void + (*done)( T1_Builder builder ); + + T1_Builder_Check_Points_Func check_points; + T1_Builder_Add_Point_Func add_point; + T1_Builder_Add_Point1_Func add_point1; + T1_Builder_Add_Contour_Func add_contour; + T1_Builder_Start_Point_Func start_point; + T1_Builder_Close_Contour_Func close_contour; + + } T1_Builder_FuncsRec; + + + /* an enumeration type to handle charstring parsing states */ + typedef enum T1_ParseState_ + { + T1_Parse_Start, + T1_Parse_Have_Width, + T1_Parse_Have_Moveto, + T1_Parse_Have_Path + + } T1_ParseState; + + + /*************************************************************************/ + /* */ + /* <Structure> */ + /* T1_BuilderRec */ + /* */ + /* <Description> */ + /* A structure used during glyph loading to store its outline. */ + /* */ + /* <Fields> */ + /* memory :: The current memory object. */ + /* */ + /* face :: The current face object. */ + /* */ + /* glyph :: The current glyph slot. */ + /* */ + /* loader :: XXX */ + /* */ + /* base :: The base glyph outline. */ + /* */ + /* current :: The current glyph outline. */ + /* */ + /* max_points :: maximum points in builder outline */ + /* */ + /* max_contours :: Maximum number of contours in builder outline. */ + /* */ + /* pos_x :: The horizontal translation (if composite glyph). */ + /* */ + /* pos_y :: The vertical translation (if composite glyph). */ + /* */ + /* left_bearing :: The left side bearing point. */ + /* */ + /* advance :: The horizontal advance vector. */ + /* */ + /* bbox :: Unused. */ + /* */ + /* parse_state :: An enumeration which controls the charstring */ + /* parsing state. */ + /* */ + /* load_points :: If this flag is not set, no points are loaded. */ + /* */ + /* no_recurse :: Set but not used. */ + /* */ + /* metrics_only :: A boolean indicating that we only want to compute */ + /* the metrics of a given glyph, not load all of its */ + /* points. */ + /* */ + /* funcs :: An array of function pointers for the builder. */ + /* */ + typedef struct T1_BuilderRec_ + { + FT_Memory memory; + FT_Face face; + FT_GlyphSlot glyph; + FT_GlyphLoader loader; + FT_Outline* base; + FT_Outline* current; + + FT_Pos pos_x; + FT_Pos pos_y; + + FT_Vector left_bearing; + FT_Vector advance; + + FT_BBox bbox; /* bounding box */ + T1_ParseState parse_state; + FT_Bool load_points; + FT_Bool no_recurse; + + FT_Bool metrics_only; + + void* hints_funcs; /* hinter-specific */ + void* hints_globals; /* hinter-specific */ + + T1_Builder_FuncsRec funcs; + + } T1_BuilderRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 DECODER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#if 0 + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 8 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 32 + +#endif /* 0 */ + + + typedef struct T1_Decoder_ZoneRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + + } T1_Decoder_ZoneRec, *T1_Decoder_Zone; + + + typedef struct T1_DecoderRec_* T1_Decoder; + typedef const struct T1_Decoder_FuncsRec_* T1_Decoder_Funcs; + + + typedef FT_Error + (*T1_Decoder_Callback)( T1_Decoder decoder, + FT_UInt glyph_index ); + + + typedef struct T1_Decoder_FuncsRec_ + { + FT_Error + (*init)( T1_Decoder decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + PS_Blend blend, + FT_Bool hinting, + FT_Render_Mode hint_mode, + T1_Decoder_Callback callback ); + + void + (*done)( T1_Decoder decoder ); + + FT_Error + (*parse_charstrings)( T1_Decoder decoder, + FT_Byte* base, + FT_UInt len ); + + } T1_Decoder_FuncsRec; + + + typedef struct T1_DecoderRec_ + { + T1_BuilderRec builder; + + FT_Long stack[T1_MAX_CHARSTRINGS_OPERANDS]; + FT_Long* top; + + T1_Decoder_ZoneRec zones[T1_MAX_SUBRS_CALLS + 1]; + T1_Decoder_Zone zone; + + FT_Service_PsCMaps psnames; /* for seac */ + FT_UInt num_glyphs; + FT_Byte** glyph_names; + + FT_Int lenIV; /* internal for sub routine calls */ + FT_Int num_subrs; + FT_Byte** subrs; + FT_UInt* subrs_len; /* array of subrs length (optional) */ + FT_Hash subrs_hash; /* used if `num_subrs' was massaged */ + + FT_Matrix font_matrix; + FT_Vector font_offset; + + FT_Int flex_state; + FT_Int num_flex_vectors; + FT_Vector flex_vectors[7]; + + PS_Blend blend; /* for multiple master support */ + + FT_Render_Mode hint_mode; + + T1_Decoder_Callback parse_callback; + T1_Decoder_FuncsRec funcs; + + FT_Long* buildchar; + FT_UInt len_buildchar; + + FT_Bool seac; + + } T1_DecoderRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** AFM PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AFM_ParserRec_* AFM_Parser; + + typedef struct AFM_Parser_FuncsRec_ + { + FT_Error + (*init)( AFM_Parser parser, + FT_Memory memory, + FT_Byte* base, + FT_Byte* limit ); + + void + (*done)( AFM_Parser parser ); + + FT_Error + (*parse)( AFM_Parser parser ); + + } AFM_Parser_FuncsRec; + + + typedef struct AFM_StreamRec_* AFM_Stream; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* AFM_ParserRec */ + /* */ + /* <Description> */ + /* An AFM_Parser is a parser for the AFM files. */ + /* */ + /* <Fields> */ + /* memory :: The object used for memory operations (alloc and */ + /* realloc). */ + /* */ + /* stream :: This is an opaque object. */ + /* */ + /* FontInfo :: The result will be stored here. */ + /* */ + /* get_index :: A user provided function to get a glyph index by its */ + /* name. */ + /* */ + typedef struct AFM_ParserRec_ + { + FT_Memory memory; + AFM_Stream stream; + + AFM_FontInfo FontInfo; + + FT_Int + (*get_index)( const char* name, + FT_Offset len, + void* user_data ); + + void* user_data; + + } AFM_ParserRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 CHARMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef const struct T1_CMap_ClassesRec_* T1_CMap_Classes; + + typedef struct T1_CMap_ClassesRec_ + { + FT_CMap_Class standard; + FT_CMap_Class expert; + FT_CMap_Class custom; + FT_CMap_Class unicode; + + } T1_CMap_ClassesRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PSAux Module Interface *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PSAux_ServiceRec_ + { + /* don't use `PS_Table_Funcs' and friends to avoid compiler warnings */ + const PS_Table_FuncsRec* ps_table_funcs; + const PS_Parser_FuncsRec* ps_parser_funcs; + const T1_Builder_FuncsRec* t1_builder_funcs; + const T1_Decoder_FuncsRec* t1_decoder_funcs; + + void + (*t1_decrypt)( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ); + + T1_CMap_Classes t1_cmap_classes; + + /* fields after this comment line were added after version 2.1.10 */ + const AFM_Parser_FuncsRec* afm_parser_funcs; + + } PSAux_ServiceRec, *PSAux_Service; + + /* backwards-compatible type definition */ + typedef PSAux_ServiceRec PSAux_Interface; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Some convenience functions *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define IS_PS_NEWLINE( ch ) \ + ( (ch) == '\r' || \ + (ch) == '\n' ) + +#define IS_PS_SPACE( ch ) \ + ( (ch) == ' ' || \ + IS_PS_NEWLINE( ch ) || \ + (ch) == '\t' || \ + (ch) == '\f' || \ + (ch) == '\0' ) + +#define IS_PS_SPECIAL( ch ) \ + ( (ch) == '/' || \ + (ch) == '(' || (ch) == ')' || \ + (ch) == '<' || (ch) == '>' || \ + (ch) == '[' || (ch) == ']' || \ + (ch) == '{' || (ch) == '}' || \ + (ch) == '%' ) + +#define IS_PS_DELIM( ch ) \ + ( IS_PS_SPACE( ch ) || \ + IS_PS_SPECIAL( ch ) ) + +#define IS_PS_DIGIT( ch ) \ + ( (ch) >= '0' && (ch) <= '9' ) + +#define IS_PS_XDIGIT( ch ) \ + ( IS_PS_DIGIT( ch ) || \ + ( (ch) >= 'A' && (ch) <= 'F' ) || \ + ( (ch) >= 'a' && (ch) <= 'f' ) ) + +#define IS_PS_BASE85( ch ) \ + ( (ch) >= '!' && (ch) <= 'u' ) + +#define IS_PS_TOKEN( cur, limit, token ) \ + ( (char)(cur)[0] == (token)[0] && \ + ( (cur) + sizeof ( (token) ) == (limit) || \ + ( (cur) + sizeof( (token) ) < (limit) && \ + IS_PS_DELIM( (cur)[sizeof ( (token) ) - 1] ) ) ) && \ + ft_strncmp( (char*)(cur), (token), sizeof ( (token) ) - 1 ) == 0 ) + + +FT_END_HEADER + +#endif /* PSAUX_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/pshints.h b/builddir/freetype-2.7.0/include/freetype/internal/pshints.h new file mode 100644 index 0000000..e60dc9c --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/pshints.h @@ -0,0 +1,722 @@ +/***************************************************************************/ +/* */ +/* pshints.h */ +/* */ +/* Interface to Postscript-specific (Type 1 and Type 2) hints */ +/* recorders (specification only). These are used to support native */ +/* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ +/* */ +/* Copyright 2001-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef PSHINTS_H_ +#define PSHINTS_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** INTERNAL REPRESENTATION OF GLOBALS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PSH_GlobalsRec_* PSH_Globals; + + typedef FT_Error + (*PSH_Globals_NewFunc)( FT_Memory memory, + T1_Private* private_dict, + PSH_Globals* aglobals ); + + typedef void + (*PSH_Globals_SetScaleFunc)( PSH_Globals globals, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Fixed x_delta, + FT_Fixed y_delta ); + + typedef void + (*PSH_Globals_DestroyFunc)( PSH_Globals globals ); + + + typedef struct PSH_Globals_FuncsRec_ + { + PSH_Globals_NewFunc create; + PSH_Globals_SetScaleFunc set_scale; + PSH_Globals_DestroyFunc destroy; + + } PSH_Globals_FuncsRec, *PSH_Globals_Funcs; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PUBLIC TYPE 1 HINTS RECORDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * T1_Hints + * + * @description: + * This is a handle to an opaque structure used to record glyph hints + * from a Type 1 character glyph character string. + * + * The methods used to operate on this object are defined by the + * @T1_Hints_FuncsRec structure. Recording glyph hints is normally + * achieved through the following scheme: + * + * - Open a new hint recording session by calling the `open' method. + * This rewinds the recorder and prepare it for new input. + * + * - For each hint found in the glyph charstring, call the corresponding + * method (`stem', `stem3', or `reset'). Note that these functions do + * not return an error code. + * + * - Close the recording session by calling the `close' method. It + * returns an error code if the hints were invalid or something + * strange happened (e.g., memory shortage). + * + * The hints accumulated in the object can later be used by the + * PostScript hinter. + * + */ + typedef struct T1_HintsRec_* T1_Hints; + + + /************************************************************************* + * + * @type: + * T1_Hints_Funcs + * + * @description: + * A pointer to the @T1_Hints_FuncsRec structure that defines the API of + * a given @T1_Hints object. + * + */ + typedef const struct T1_Hints_FuncsRec_* T1_Hints_Funcs; + + + /************************************************************************* + * + * @functype: + * T1_Hints_OpenFunc + * + * @description: + * A method of the @T1_Hints class used to prepare it for a new Type 1 + * hints recording session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * @note: + * You should always call the @T1_Hints_CloseFunc method in order to + * close an opened recording session. + * + */ + typedef void + (*T1_Hints_OpenFunc)( T1_Hints hints ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_SetStemFunc + * + * @description: + * A method of the @T1_Hints class used to record a new horizontal or + * vertical stem. This corresponds to the Type 1 `hstem' and `vstem' + * operators. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * dimension :: + * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). + * + * coords :: + * Array of 2 coordinates in 16.16 format, used as (position,length) + * stem descriptor. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * `coords[0]' is the absolute stem position (lowest coordinate); + * `coords[1]' is the length. + * + * The length can be negative, in which case it must be either -20 or + * -21. It is interpreted as a `ghost' stem, according to the Type 1 + * specification. + * + * If the length is -21 (corresponding to a bottom ghost stem), then + * the real stem position is `coords[0]+coords[1]'. + * + */ + typedef void + (*T1_Hints_SetStemFunc)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_SetStem3Func + * + * @description: + * A method of the @T1_Hints class used to record three + * counter-controlled horizontal or vertical stems at once. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * dimension :: + * 0 for horizontal stems, 1 for vertical ones. + * + * coords :: + * An array of 6 values in 16.16 format, holding 3 (position,length) + * pairs for the counter-controlled stems. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * The lengths cannot be negative (ghost stems are never + * counter-controlled). + * + */ + typedef void + (*T1_Hints_SetStem3Func)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_ResetFunc + * + * @description: + * A method of the @T1_Hints class used to reset the stems hints in a + * recording session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph in which the + * previously defined hints apply. + * + */ + typedef void + (*T1_Hints_ResetFunc)( T1_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_CloseFunc + * + * @description: + * A method of the @T1_Hints class used to close a hint recording + * session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The error code is set to indicate that an error occurred during the + * recording session. + * + */ + typedef FT_Error + (*T1_Hints_CloseFunc)( T1_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_ApplyFunc + * + * @description: + * A method of the @T1_Hints class used to apply hints to the + * corresponding glyph outline. Must be called once all hints have been + * recorded. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * outline :: + * A pointer to the target outline descriptor. + * + * globals :: + * The hinter globals for this font. + * + * hint_mode :: + * Hinting information. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * On input, all points within the outline are in font coordinates. On + * output, they are in 1/64th of pixels. + * + * The scaling transformation is taken from the `globals' object which + * must correspond to the same font as the glyph. + * + */ + typedef FT_Error + (*T1_Hints_ApplyFunc)( T1_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + + /************************************************************************* + * + * @struct: + * T1_Hints_FuncsRec + * + * @description: + * The structure used to provide the API to @T1_Hints objects. + * + * @fields: + * hints :: + * A handle to the T1 Hints recorder. + * + * open :: + * The function to open a recording session. + * + * close :: + * The function to close a recording session. + * + * stem :: + * The function to set a simple stem. + * + * stem3 :: + * The function to set counter-controlled stems. + * + * reset :: + * The function to reset stem hints. + * + * apply :: + * The function to apply the hints to the corresponding glyph outline. + * + */ + typedef struct T1_Hints_FuncsRec_ + { + T1_Hints hints; + T1_Hints_OpenFunc open; + T1_Hints_CloseFunc close; + T1_Hints_SetStemFunc stem; + T1_Hints_SetStem3Func stem3; + T1_Hints_ResetFunc reset; + T1_Hints_ApplyFunc apply; + + } T1_Hints_FuncsRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PUBLIC TYPE 2 HINTS RECORDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * T2_Hints + * + * @description: + * This is a handle to an opaque structure used to record glyph hints + * from a Type 2 character glyph character string. + * + * The methods used to operate on this object are defined by the + * @T2_Hints_FuncsRec structure. Recording glyph hints is normally + * achieved through the following scheme: + * + * - Open a new hint recording session by calling the `open' method. + * This rewinds the recorder and prepare it for new input. + * + * - For each hint found in the glyph charstring, call the corresponding + * method (`stems', `hintmask', `counters'). Note that these + * functions do not return an error code. + * + * - Close the recording session by calling the `close' method. It + * returns an error code if the hints were invalid or something + * strange happened (e.g., memory shortage). + * + * The hints accumulated in the object can later be used by the + * Postscript hinter. + * + */ + typedef struct T2_HintsRec_* T2_Hints; + + + /************************************************************************* + * + * @type: + * T2_Hints_Funcs + * + * @description: + * A pointer to the @T2_Hints_FuncsRec structure that defines the API of + * a given @T2_Hints object. + * + */ + typedef const struct T2_Hints_FuncsRec_* T2_Hints_Funcs; + + + /************************************************************************* + * + * @functype: + * T2_Hints_OpenFunc + * + * @description: + * A method of the @T2_Hints class used to prepare it for a new Type 2 + * hints recording session. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * @note: + * You should always call the @T2_Hints_CloseFunc method in order to + * close an opened recording session. + * + */ + typedef void + (*T2_Hints_OpenFunc)( T2_Hints hints ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_StemsFunc + * + * @description: + * A method of the @T2_Hints class used to set the table of stems in + * either the vertical or horizontal dimension. Equivalent to the + * `hstem', `vstem', `hstemhm', and `vstemhm' Type 2 operators. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * dimension :: + * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). + * + * count :: + * The number of stems. + * + * coords :: + * An array of `count' (position,length) pairs in 16.16 format. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * There are `2*count' elements in the `coords' array. Each even + * element is an absolute position in font units, each odd element is a + * length in font units. + * + * A length can be negative, in which case it must be either -20 or + * -21. It is interpreted as a `ghost' stem, according to the Type 1 + * specification. + * + */ + typedef void + (*T2_Hints_StemsFunc)( T2_Hints hints, + FT_UInt dimension, + FT_Int count, + FT_Fixed* coordinates ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_MaskFunc + * + * @description: + * A method of the @T2_Hints class used to set a given hintmask (this + * corresponds to the `hintmask' Type 2 operator). + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * The glyph index of the last point to which the previously defined + * or activated hints apply. + * + * bit_count :: + * The number of bits in the hint mask. + * + * bytes :: + * An array of bytes modelling the hint mask. + * + * @note: + * If the hintmask starts the charstring (before any glyph point + * definition), the value of `end_point' should be 0. + * + * `bit_count' is the number of meaningful bits in the `bytes' array; it + * must be equal to the total number of hints defined so far (i.e., + * horizontal+verticals). + * + * The `bytes' array can come directly from the Type 2 charstring and + * respects the same format. + * + */ + typedef void + (*T2_Hints_MaskFunc)( T2_Hints hints, + FT_UInt end_point, + FT_UInt bit_count, + const FT_Byte* bytes ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_CounterFunc + * + * @description: + * A method of the @T2_Hints class used to set a given counter mask + * (this corresponds to the `hintmask' Type 2 operator). + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * A glyph index of the last point to which the previously defined or + * active hints apply. + * + * bit_count :: + * The number of bits in the hint mask. + * + * bytes :: + * An array of bytes modelling the hint mask. + * + * @note: + * If the hintmask starts the charstring (before any glyph point + * definition), the value of `end_point' should be 0. + * + * `bit_count' is the number of meaningful bits in the `bytes' array; it + * must be equal to the total number of hints defined so far (i.e., + * horizontal+verticals). + * + * The `bytes' array can come directly from the Type 2 charstring and + * respects the same format. + * + */ + typedef void + (*T2_Hints_CounterFunc)( T2_Hints hints, + FT_UInt bit_count, + const FT_Byte* bytes ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_CloseFunc + * + * @description: + * A method of the @T2_Hints class used to close a hint recording + * session. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The error code is set to indicate that an error occurred during the + * recording session. + * + */ + typedef FT_Error + (*T2_Hints_CloseFunc)( T2_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_ApplyFunc + * + * @description: + * A method of the @T2_Hints class used to apply hints to the + * corresponding glyph outline. Must be called after the `close' + * method. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * outline :: + * A pointer to the target outline descriptor. + * + * globals :: + * The hinter globals for this font. + * + * hint_mode :: + * Hinting information. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * On input, all points within the outline are in font coordinates. On + * output, they are in 1/64th of pixels. + * + * The scaling transformation is taken from the `globals' object which + * must correspond to the same font than the glyph. + * + */ + typedef FT_Error + (*T2_Hints_ApplyFunc)( T2_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + + /************************************************************************* + * + * @struct: + * T2_Hints_FuncsRec + * + * @description: + * The structure used to provide the API to @T2_Hints objects. + * + * @fields: + * hints :: + * A handle to the T2 hints recorder object. + * + * open :: + * The function to open a recording session. + * + * close :: + * The function to close a recording session. + * + * stems :: + * The function to set the dimension's stems table. + * + * hintmask :: + * The function to set hint masks. + * + * counter :: + * The function to set counter masks. + * + * apply :: + * The function to apply the hints on the corresponding glyph outline. + * + */ + typedef struct T2_Hints_FuncsRec_ + { + T2_Hints hints; + T2_Hints_OpenFunc open; + T2_Hints_CloseFunc close; + T2_Hints_StemsFunc stems; + T2_Hints_MaskFunc hintmask; + T2_Hints_CounterFunc counter; + T2_Hints_ApplyFunc apply; + + } T2_Hints_FuncsRec; + + + /* */ + + + typedef struct PSHinter_Interface_ + { + PSH_Globals_Funcs (*get_globals_funcs)( FT_Module module ); + T1_Hints_Funcs (*get_t1_funcs) ( FT_Module module ); + T2_Hints_Funcs (*get_t2_funcs) ( FT_Module module ); + + } PSHinter_Interface; + + typedef PSHinter_Interface* PSHinter_Service; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_PSHINTER_INTERFACE( \ + class_, \ + get_globals_funcs_, \ + get_t1_funcs_, \ + get_t2_funcs_ ) \ + static const PSHinter_Interface class_ = \ + { \ + get_globals_funcs_, \ + get_t1_funcs_, \ + get_t2_funcs_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_PSHINTER_INTERFACE( \ + class_, \ + get_globals_funcs_, \ + get_t1_funcs_, \ + get_t2_funcs_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + PSHinter_Interface* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->get_globals_funcs = get_globals_funcs_; \ + clazz->get_t1_funcs = get_t1_funcs_; \ + clazz->get_t2_funcs = get_t2_funcs_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* PSHINTS_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svbdf.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svbdf.h new file mode 100644 index 0000000..c24475f --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svbdf.h @@ -0,0 +1,82 @@ +/***************************************************************************/ +/* */ +/* svbdf.h */ +/* */ +/* The FreeType BDF services (specification). */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVBDF_H_ +#define SVBDF_H_ + +#include FT_BDF_H +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_BDF "bdf" + + typedef FT_Error + (*FT_BDF_GetCharsetIdFunc)( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ); + + typedef FT_Error + (*FT_BDF_GetPropertyFunc)( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + + + FT_DEFINE_SERVICE( BDF ) + { + FT_BDF_GetCharsetIdFunc get_charset_id; + FT_BDF_GetPropertyFunc get_property; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_BDFRec( class_, \ + get_charset_id_, \ + get_property_ ) \ + static const FT_Service_BDFRec class_ = \ + { \ + get_charset_id_, get_property_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_BDFRec( class_, \ + get_charset_id_, \ + get_property_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_BDFRec* clazz ) \ + { \ + clazz->get_charset_id = get_charset_id_; \ + clazz->get_property = get_property_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* SVBDF_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svcid.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svcid.h new file mode 100644 index 0000000..dbbe604 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svcid.h @@ -0,0 +1,90 @@ +/***************************************************************************/ +/* */ +/* svcid.h */ +/* */ +/* The FreeType CID font services (specification). */ +/* */ +/* Copyright 2007-2016 by */ +/* Derek Clegg and Michael Toftdal. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVCID_H_ +#define SVCID_H_ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_CID "CID" + + typedef FT_Error + (*FT_CID_GetRegistryOrderingSupplementFunc)( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ); + typedef FT_Error + (*FT_CID_GetIsInternallyCIDKeyedFunc)( FT_Face face, + FT_Bool *is_cid ); + typedef FT_Error + (*FT_CID_GetCIDFromGlyphIndexFunc)( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ); + + FT_DEFINE_SERVICE( CID ) + { + FT_CID_GetRegistryOrderingSupplementFunc get_ros; + FT_CID_GetIsInternallyCIDKeyedFunc get_is_cid; + FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_CIDREC( class_, \ + get_ros_, \ + get_is_cid_, \ + get_cid_from_glyph_index_ ) \ + static const FT_Service_CIDRec class_ = \ + { \ + get_ros_, get_is_cid_, get_cid_from_glyph_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_CIDREC( class_, \ + get_ros_, \ + get_is_cid_, \ + get_cid_from_glyph_index_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_CIDRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->get_ros = get_ros_; \ + clazz->get_is_cid = get_is_cid_; \ + clazz->get_cid_from_glyph_index = get_cid_from_glyph_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* SVCID_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svfntfmt.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svfntfmt.h new file mode 100644 index 0000000..bd295c9 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svfntfmt.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* svfntfmt.h */ +/* */ +/* The FreeType font format service (specification only). */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVFNTFMT_H_ +#define SVFNTFMT_H_ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A trivial service used to return the name of a face's font driver, + * according to the XFree86 nomenclature. Note that the service data + * is a simple constant string pointer. + */ + +#define FT_SERVICE_ID_FONT_FORMAT "font-format" + +#define FT_FONT_FORMAT_TRUETYPE "TrueType" +#define FT_FONT_FORMAT_TYPE_1 "Type 1" +#define FT_FONT_FORMAT_BDF "BDF" +#define FT_FONT_FORMAT_PCF "PCF" +#define FT_FONT_FORMAT_TYPE_42 "Type 42" +#define FT_FONT_FORMAT_CID "CID Type 1" +#define FT_FONT_FORMAT_CFF "CFF" +#define FT_FONT_FORMAT_PFR "PFR" +#define FT_FONT_FORMAT_WINFNT "Windows FNT" + + /* */ + + +FT_END_HEADER + + +#endif /* SVFNTFMT_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svgldict.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svgldict.h new file mode 100644 index 0000000..fff29bc --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svgldict.h @@ -0,0 +1,91 @@ +/***************************************************************************/ +/* */ +/* svgldict.h */ +/* */ +/* The FreeType glyph dictionary services (specification). */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVGLDICT_H_ +#define SVGLDICT_H_ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service used to retrieve glyph names, as well as to find the + * index of a given glyph name in a font. + * + */ + +#define FT_SERVICE_ID_GLYPH_DICT "glyph-dict" + + + typedef FT_Error + (*FT_GlyphDict_GetNameFunc)( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + typedef FT_UInt + (*FT_GlyphDict_NameIndexFunc)( FT_Face face, + FT_String* glyph_name ); + + + FT_DEFINE_SERVICE( GlyphDict ) + { + FT_GlyphDict_GetNameFunc get_name; + FT_GlyphDict_NameIndexFunc name_index; /* optional */ + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \ + get_name_, \ + name_index_) \ + static const FT_Service_GlyphDictRec class_ = \ + { \ + get_name_, name_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \ + get_name_, \ + name_index_) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_GlyphDictRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->get_name = get_name_; \ + clazz->name_index = name_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* SVGLDICT_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svgxval.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svgxval.h new file mode 100644 index 0000000..fb8ffba --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svgxval.h @@ -0,0 +1,72 @@ +/***************************************************************************/ +/* */ +/* svgxval.h */ +/* */ +/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ +/* */ +/* Copyright 2004-2016 by */ +/* Masatake YAMATO, Red Hat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef SVGXVAL_H_ +#define SVGXVAL_H_ + +#include FT_GX_VALIDATE_H +#include FT_INTERNAL_VALIDATE_H + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_GX_VALIDATE "truetypegx-validate" +#define FT_SERVICE_ID_CLASSICKERN_VALIDATE "classickern-validate" + + typedef FT_Error + (*gxv_validate_func)( FT_Face face, + FT_UInt gx_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_length ); + + + typedef FT_Error + (*ckern_validate_func)( FT_Face face, + FT_UInt ckern_flags, + FT_Bytes *ckern_table ); + + + FT_DEFINE_SERVICE( GXvalidate ) + { + gxv_validate_func validate; + }; + + FT_DEFINE_SERVICE( CKERNvalidate ) + { + ckern_validate_func validate; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* SVGXVAL_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svkern.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svkern.h new file mode 100644 index 0000000..a636f1a --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svkern.h @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* svkern.h */ +/* */ +/* The FreeType Kerning service (specification). */ +/* */ +/* Copyright 2006-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVKERN_H_ +#define SVKERN_H_ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + +#define FT_SERVICE_ID_KERNING "kerning" + + + typedef FT_Error + (*FT_Kerning_TrackGetFunc)( FT_Face face, + FT_Fixed point_size, + FT_Int degree, + FT_Fixed* akerning ); + + FT_DEFINE_SERVICE( Kerning ) + { + FT_Kerning_TrackGetFunc get_track; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* SVKERN_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svmm.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svmm.h new file mode 100644 index 0000000..b78a19f --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svmm.h @@ -0,0 +1,113 @@ +/***************************************************************************/ +/* */ +/* svmm.h */ +/* */ +/* The FreeType Multiple Masters and GX var services (specification). */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVMM_H_ +#define SVMM_H_ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service used to manage multiple-masters data in a given face. + * + * See the related APIs in `ftmm.h' (FT_MULTIPLE_MASTERS_H). + * + */ + +#define FT_SERVICE_ID_MULTI_MASTERS "multi-masters" + + + typedef FT_Error + (*FT_Get_MM_Func)( FT_Face face, + FT_Multi_Master* master ); + + typedef FT_Error + (*FT_Get_MM_Var_Func)( FT_Face face, + FT_MM_Var* *master ); + + typedef FT_Error + (*FT_Set_MM_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + typedef FT_Error + (*FT_Set_Var_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + typedef FT_Error + (*FT_Set_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + FT_DEFINE_SERVICE( MultiMasters ) + { + FT_Get_MM_Func get_mm; + FT_Set_MM_Design_Func set_mm_design; + FT_Set_MM_Blend_Func set_mm_blend; + FT_Get_MM_Var_Func get_mm_var; + FT_Set_Var_Design_Func set_var_design; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_var_, \ + set_var_design_ ) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_var_, \ + set_var_design_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ + { \ + clazz->get_mm = get_mm_; \ + clazz->set_mm_design = set_mm_design_; \ + clazz->set_mm_blend = set_mm_blend_; \ + clazz->get_mm_var = get_mm_var_; \ + clazz->set_var_design = set_var_design_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* SVMM_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svotval.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svotval.h new file mode 100644 index 0000000..bc929d4 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svotval.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* svotval.h */ +/* */ +/* The FreeType OpenType validation service (specification). */ +/* */ +/* Copyright 2004-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVOTVAL_H_ +#define SVOTVAL_H_ + +#include FT_OPENTYPE_VALIDATE_H +#include FT_INTERNAL_VALIDATE_H + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_OPENTYPE_VALIDATE "opentype-validate" + + + typedef FT_Error + (*otv_validate_func)( FT_Face volatile face, + FT_UInt ot_flags, + FT_Bytes *base, + FT_Bytes *gdef, + FT_Bytes *gpos, + FT_Bytes *gsub, + FT_Bytes *jstf ); + + + FT_DEFINE_SERVICE( OTvalidate ) + { + otv_validate_func validate; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* SVOTVAL_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svpfr.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svpfr.h new file mode 100644 index 0000000..d0f7c4d --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svpfr.h @@ -0,0 +1,66 @@ +/***************************************************************************/ +/* */ +/* svpfr.h */ +/* */ +/* Internal PFR service functions (specification). */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVPFR_H_ +#define SVPFR_H_ + +#include FT_PFR_H +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_PFR_METRICS "pfr-metrics" + + + typedef FT_Error + (*FT_PFR_GetMetricsFunc)( FT_Face face, + FT_UInt *aoutline, + FT_UInt *ametrics, + FT_Fixed *ax_scale, + FT_Fixed *ay_scale ); + + typedef FT_Error + (*FT_PFR_GetKerningFunc)( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + typedef FT_Error + (*FT_PFR_GetAdvanceFunc)( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + + FT_DEFINE_SERVICE( PfrMetrics ) + { + FT_PFR_GetMetricsFunc get_metrics; + FT_PFR_GetKerningFunc get_kerning; + FT_PFR_GetAdvanceFunc get_advance; + + }; + + /* */ + +FT_END_HEADER + +#endif /* SVPFR_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svpostnm.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svpostnm.h new file mode 100644 index 0000000..f124380 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svpostnm.h @@ -0,0 +1,81 @@ +/***************************************************************************/ +/* */ +/* svpostnm.h */ +/* */ +/* The FreeType PostScript name services (specification). */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVPOSTNM_H_ +#define SVPOSTNM_H_ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + /* + * A trivial service used to retrieve the PostScript name of a given + * font when available. The `get_name' field should never be NULL. + * + * The corresponding function can return NULL to indicate that the + * PostScript name is not available. + * + * The name is owned by the face and will be destroyed with it. + */ + +#define FT_SERVICE_ID_POSTSCRIPT_FONT_NAME "postscript-font-name" + + + typedef const char* + (*FT_PsName_GetFunc)( FT_Face face ); + + + FT_DEFINE_SERVICE( PsFontName ) + { + FT_PsName_GetFunc get_ps_font_name; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC( class_, get_ps_font_name_ ) \ + static const FT_Service_PsFontNameRec class_ = \ + { \ + get_ps_font_name_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC( class_, get_ps_font_name_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_PsFontNameRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->get_ps_font_name = get_ps_font_name_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* SVPOSTNM_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svprop.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svprop.h new file mode 100644 index 0000000..75e6244 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svprop.h @@ -0,0 +1,82 @@ +/***************************************************************************/ +/* */ +/* svprop.h */ +/* */ +/* The FreeType property service (specification). */ +/* */ +/* Copyright 2012-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVPROP_H_ +#define SVPROP_H_ + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_PROPERTIES "properties" + + + typedef FT_Error + (*FT_Properties_SetFunc)( FT_Module module, + const char* property_name, + const void* value, + FT_Bool value_is_string ); + + typedef FT_Error + (*FT_Properties_GetFunc)( FT_Module module, + const char* property_name, + void* value ); + + + FT_DEFINE_SERVICE( Properties ) + { + FT_Properties_SetFunc set_property; + FT_Properties_GetFunc get_property; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \ + set_property_, \ + get_property_ ) \ + static const FT_Service_PropertiesRec class_ = \ + { \ + set_property_, \ + get_property_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PROPERTIESREC( class_, \ + set_property_, \ + get_property_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_PropertiesRec* clazz ) \ + { \ + clazz->set_property = set_property_; \ + clazz->get_property = get_property_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* SVPROP_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svpscmap.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svpscmap.h new file mode 100644 index 0000000..9acc216 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svpscmap.h @@ -0,0 +1,177 @@ +/***************************************************************************/ +/* */ +/* svpscmap.h */ +/* */ +/* The FreeType PostScript charmap service (specification). */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVPSCMAP_H_ +#define SVPSCMAP_H_ + +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_POSTSCRIPT_CMAPS "postscript-cmaps" + + + /* + * Adobe glyph name to unicode value. + */ + typedef FT_UInt32 + (*PS_Unicode_ValueFunc)( const char* glyph_name ); + + /* + * Macintosh name id to glyph name. NULL if invalid index. + */ + typedef const char* + (*PS_Macintosh_NameFunc)( FT_UInt name_index ); + + /* + * Adobe standard string ID to glyph name. NULL if invalid index. + */ + typedef const char* + (*PS_Adobe_Std_StringsFunc)( FT_UInt string_index ); + + + /* + * Simple unicode -> glyph index charmap built from font glyph names + * table. + */ + typedef struct PS_UniMap_ + { + FT_UInt32 unicode; /* bit 31 set: is glyph variant */ + FT_UInt glyph_index; + + } PS_UniMap; + + + typedef struct PS_UnicodesRec_* PS_Unicodes; + + typedef struct PS_UnicodesRec_ + { + FT_CMapRec cmap; + FT_UInt num_maps; + PS_UniMap* maps; + + } PS_UnicodesRec; + + + /* + * A function which returns a glyph name for a given index. Returns + * NULL if invalid index. + */ + typedef const char* + (*PS_GetGlyphNameFunc)( FT_Pointer data, + FT_UInt string_index ); + + /* + * A function used to release the glyph name returned by + * PS_GetGlyphNameFunc, when needed + */ + typedef void + (*PS_FreeGlyphNameFunc)( FT_Pointer data, + const char* name ); + + typedef FT_Error + (*PS_Unicodes_InitFunc)( FT_Memory memory, + PS_Unicodes unicodes, + FT_UInt num_glyphs, + PS_GetGlyphNameFunc get_glyph_name, + PS_FreeGlyphNameFunc free_glyph_name, + FT_Pointer glyph_data ); + + typedef FT_UInt + (*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes, + FT_UInt32 unicode ); + + typedef FT_UInt32 + (*PS_Unicodes_CharNextFunc)( PS_Unicodes unicodes, + FT_UInt32 *unicode ); + + + FT_DEFINE_SERVICE( PsCMaps ) + { + PS_Unicode_ValueFunc unicode_value; + + PS_Unicodes_InitFunc unicodes_init; + PS_Unicodes_CharIndexFunc unicodes_char_index; + PS_Unicodes_CharNextFunc unicodes_char_next; + + PS_Macintosh_NameFunc macintosh_name; + PS_Adobe_Std_StringsFunc adobe_std_strings; + const unsigned short* adobe_std_encoding; + const unsigned short* adobe_expert_encoding; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSCMAPSREC( class_, \ + unicode_value_, \ + unicodes_init_, \ + unicodes_char_index_, \ + unicodes_char_next_, \ + macintosh_name_, \ + adobe_std_strings_, \ + adobe_std_encoding_, \ + adobe_expert_encoding_ ) \ + static const FT_Service_PsCMapsRec class_ = \ + { \ + unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSCMAPSREC( class_, \ + unicode_value_, \ + unicodes_init_, \ + unicodes_char_index_, \ + unicodes_char_next_, \ + macintosh_name_, \ + adobe_std_strings_, \ + adobe_std_encoding_, \ + adobe_expert_encoding_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_PsCMapsRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->unicode_value = unicode_value_; \ + clazz->unicodes_init = unicodes_init_; \ + clazz->unicodes_char_index = unicodes_char_index_; \ + clazz->unicodes_char_next = unicodes_char_next_; \ + clazz->macintosh_name = macintosh_name_; \ + clazz->adobe_std_strings = adobe_std_strings_; \ + clazz->adobe_std_encoding = adobe_std_encoding_; \ + clazz->adobe_expert_encoding = adobe_expert_encoding_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* SVPSCMAP_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svpsinfo.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svpsinfo.h new file mode 100644 index 0000000..f2c8060 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svpsinfo.h @@ -0,0 +1,111 @@ +/***************************************************************************/ +/* */ +/* svpsinfo.h */ +/* */ +/* The FreeType PostScript info service (specification). */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVPSINFO_H_ +#define SVPSINFO_H_ + +#include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_POSTSCRIPT_INFO "postscript-info" + + + typedef FT_Error + (*PS_GetFontInfoFunc)( FT_Face face, + PS_FontInfoRec* afont_info ); + + typedef FT_Error + (*PS_GetFontExtraFunc)( FT_Face face, + PS_FontExtraRec* afont_extra ); + + typedef FT_Int + (*PS_HasGlyphNamesFunc)( FT_Face face ); + + typedef FT_Error + (*PS_GetFontPrivateFunc)( FT_Face face, + PS_PrivateRec* afont_private ); + + typedef FT_Long + (*PS_GetFontValueFunc)( FT_Face face, + PS_Dict_Keys key, + FT_UInt idx, + void *value, + FT_Long value_len ); + + + FT_DEFINE_SERVICE( PsInfo ) + { + PS_GetFontInfoFunc ps_get_font_info; + PS_GetFontExtraFunc ps_get_font_extra; + PS_HasGlyphNamesFunc ps_has_glyph_names; + PS_GetFontPrivateFunc ps_get_font_private; + PS_GetFontValueFunc ps_get_font_value; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSINFOREC( class_, \ + get_font_info_, \ + ps_get_font_extra_, \ + has_glyph_names_, \ + get_font_private_, \ + get_font_value_ ) \ + static const FT_Service_PsInfoRec class_ = \ + { \ + get_font_info_, ps_get_font_extra_, has_glyph_names_, \ + get_font_private_, get_font_value_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSINFOREC( class_, \ + get_font_info_, \ + ps_get_font_extra_, \ + has_glyph_names_, \ + get_font_private_, \ + get_font_value_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_PsInfoRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->ps_get_font_info = get_font_info_; \ + clazz->ps_get_font_extra = ps_get_font_extra_; \ + clazz->ps_has_glyph_names = has_glyph_names_; \ + clazz->ps_get_font_private = get_font_private_; \ + clazz->ps_get_font_value = get_font_value_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* SVPSINFO_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svsfnt.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svsfnt.h new file mode 100644 index 0000000..0f38cf1 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svsfnt.h @@ -0,0 +1,103 @@ +/***************************************************************************/ +/* */ +/* svsfnt.h */ +/* */ +/* The FreeType SFNT table loading service (specification). */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVSFNT_H_ +#define SVSFNT_H_ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + + /* + * SFNT table loading service. + */ + +#define FT_SERVICE_ID_SFNT_TABLE "sfnt-table" + + + /* + * Used to implement FT_Load_Sfnt_Table(). + */ + typedef FT_Error + (*FT_SFNT_TableLoadFunc)( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + /* + * Used to implement FT_Get_Sfnt_Table(). + */ + typedef void* + (*FT_SFNT_TableGetFunc)( FT_Face face, + FT_Sfnt_Tag tag ); + + + /* + * Used to implement FT_Sfnt_Table_Info(). + */ + typedef FT_Error + (*FT_SFNT_TableInfoFunc)( FT_Face face, + FT_UInt idx, + FT_ULong *tag, + FT_ULong *offset, + FT_ULong *length ); + + + FT_DEFINE_SERVICE( SFNT_Table ) + { + FT_SFNT_TableLoadFunc load_table; + FT_SFNT_TableGetFunc get_table; + FT_SFNT_TableInfoFunc table_info; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC( class_, load_, get_, info_ ) \ + static const FT_Service_SFNT_TableRec class_ = \ + { \ + load_, get_, info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC( class_, load_, get_, info_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_SFNT_TableRec* clazz ) \ + { \ + clazz->load_table = load_; \ + clazz->get_table = get_; \ + clazz->table_info = info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* SVSFNT_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svttcmap.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svttcmap.h new file mode 100644 index 0000000..772c721 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svttcmap.h @@ -0,0 +1,106 @@ +/***************************************************************************/ +/* */ +/* svttcmap.h */ +/* */ +/* The FreeType TrueType/sfnt cmap extra information service. */ +/* */ +/* Copyright 2003-2016 by */ +/* Masatake YAMATO, Redhat K.K., */ +/* 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. */ +/* */ +/***************************************************************************/ + +/* Development of this service is support of + Information-technology Promotion Agency, Japan. */ + +#ifndef SVTTCMAP_H_ +#define SVTTCMAP_H_ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_TT_CMAP "tt-cmaps" + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_CMapInfo */ + /* */ + /* <Description> */ + /* A structure used to store TrueType/sfnt specific cmap information */ + /* which is not covered by the generic @FT_CharMap structure. This */ + /* structure can be accessed with the @FT_Get_TT_CMap_Info function. */ + /* */ + /* <Fields> */ + /* language :: */ + /* The language ID used in Mac fonts. Definitions of values are in */ + /* `ttnameid.h'. */ + /* */ + /* format :: */ + /* The cmap format. OpenType 1.6 defines the formats 0 (byte */ + /* encoding table), 2~(high-byte mapping through table), 4~(segment */ + /* mapping to delta values), 6~(trimmed table mapping), 8~(mixed */ + /* 16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented */ + /* coverage), 13~(last resort font), and 14 (Unicode Variation */ + /* Sequences). */ + /* */ + typedef struct TT_CMapInfo_ + { + FT_ULong language; + FT_Long format; + + } TT_CMapInfo; + + + typedef FT_Error + (*TT_CMap_Info_GetFunc)( FT_CharMap charmap, + TT_CMapInfo *cmap_info ); + + + FT_DEFINE_SERVICE( TTCMaps ) + { + TT_CMap_Info_GetFunc get_cmap_info; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTCMAPSREC( class_, get_cmap_info_ ) \ + static const FT_Service_TTCMapsRec class_ = \ + { \ + get_cmap_info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTCMAPSREC( class_, get_cmap_info_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + FT_Service_TTCMapsRec* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->get_cmap_info = get_cmap_info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* SVTTCMAP_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svtteng.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svtteng.h new file mode 100644 index 0000000..c55061a --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svtteng.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* svtteng.h */ +/* */ +/* The FreeType TrueType engine query service (specification). */ +/* */ +/* Copyright 2006-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVTTENG_H_ +#define SVTTENG_H_ + +#include FT_INTERNAL_SERVICE_H +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + /* + * SFNT table loading service. + */ + +#define FT_SERVICE_ID_TRUETYPE_ENGINE "truetype-engine" + + /* + * Used to implement FT_Get_TrueType_Engine_Type + */ + + FT_DEFINE_SERVICE( TrueTypeEngine ) + { + FT_TrueTypeEngineType engine_type; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* SVTTENG_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svttglyf.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svttglyf.h new file mode 100644 index 0000000..c33edd4 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svttglyf.h @@ -0,0 +1,69 @@ +/***************************************************************************/ +/* */ +/* svttglyf.h */ +/* */ +/* The FreeType TrueType glyph service. */ +/* */ +/* Copyright 2007-2016 by */ +/* David Turner. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + +#ifndef SVTTGLYF_H_ +#define SVTTGLYF_H_ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_TT_GLYF "tt-glyf" + + + typedef FT_ULong + (*TT_Glyf_GetLocationFunc)( FT_Face face, + FT_UInt gindex, + FT_ULong *psize ); + + FT_DEFINE_SERVICE( TTGlyf ) + { + TT_Glyf_GetLocationFunc get_location; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTGLYFREC( class_, get_location_ ) \ + static const FT_Service_TTGlyfRec class_ = \ + { \ + get_location_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTGLYFREC( class_, get_location_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_TTGlyfRec* clazz ) \ + { \ + clazz->get_location = get_location_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* SVTTGLYF_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/services/svwinfnt.h b/builddir/freetype-2.7.0/include/freetype/internal/services/svwinfnt.h new file mode 100644 index 0000000..c2f6d4c --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/services/svwinfnt.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* svwinfnt.h */ +/* */ +/* The FreeType Windows FNT/FONT service (specification). */ +/* */ +/* Copyright 2003-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SVWINFNT_H_ +#define SVWINFNT_H_ + +#include FT_INTERNAL_SERVICE_H +#include FT_WINFONTS_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_WINFNT "winfonts" + + typedef FT_Error + (*FT_WinFnt_GetHeaderFunc)( FT_Face face, + FT_WinFNT_HeaderRec *aheader ); + + + FT_DEFINE_SERVICE( WinFnt ) + { + FT_WinFnt_GetHeaderFunc get_header; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* SVWINFNT_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/sfnt.h b/builddir/freetype-2.7.0/include/freetype/internal/sfnt.h new file mode 100644 index 0000000..e139315 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/sfnt.h @@ -0,0 +1,748 @@ +/***************************************************************************/ +/* */ +/* sfnt.h */ +/* */ +/* High-level `sfnt' driver interface (specification). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef SFNT_H_ +#define SFNT_H_ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Init_Face_Func */ + /* */ + /* <Description> */ + /* First part of the SFNT face object initialization. This finds */ + /* the face in a SFNT file or collection, and load its format tag in */ + /* face->format_tag. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* params :: Optional additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + /* This function recognizes fonts embedded in a `TrueType */ + /* collection'. */ + /* */ + /* Once the format tag has been validated by the font driver, it */ + /* should then call the TT_Load_Face_Func() callback to read the rest */ + /* of the SFNT tables in the object. */ + /* */ + typedef FT_Error + (*TT_Init_Face_Func)( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Face_Func */ + /* */ + /* <Description> */ + /* Second part of the SFNT face object initialization. This loads */ + /* the common SFNT tables (head, OS/2, maxp, metrics, etc.) in the */ + /* face object. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* params :: Optional additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function must be called after TT_Init_Face_Func(). */ + /* */ + typedef FT_Error + (*TT_Load_Face_Func)( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Done_Face_Func */ + /* */ + /* <Description> */ + /* A callback used to delete the common SFNT data from a face. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Note> */ + /* This function does NOT destroy the face object. */ + /* */ + typedef void + (*TT_Done_Face_Func)( TT_Face face ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Any_Func */ + /* */ + /* <Description> */ + /* Load any font table into client memory. */ + /* */ + /* <Input> */ + /* face :: The face object to look for. */ + /* */ + /* tag :: The tag of table to load. Use the value 0 if you want */ + /* to access the whole font file, else set this parameter */ + /* to a valid TrueType table tag that you can forge with */ + /* the MAKE_TT_TAG macro. */ + /* */ + /* offset :: The starting offset in the table (or the file if */ + /* tag == 0). */ + /* */ + /* length :: The address of the decision variable: */ + /* */ + /* If length == NULL: */ + /* Loads the whole table. Returns an error if */ + /* `offset' == 0! */ + /* */ + /* If *length == 0: */ + /* Exits immediately; returning the length of the given */ + /* table or of the font file, depending on the value of */ + /* `tag'. */ + /* */ + /* If *length != 0: */ + /* Loads the next `length' bytes of table or font, */ + /* starting at offset `offset' (in table or font too). */ + /* */ + /* <Output> */ + /* buffer :: The address of target buffer. */ + /* */ + /* <Return> */ + /* TrueType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Load_Any_Func)( TT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte *buffer, + FT_ULong* length ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Find_SBit_Image_Func */ + /* */ + /* <Description> */ + /* Check whether an embedded bitmap (an `sbit') exists for a given */ + /* glyph, at a given strike. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* strike_index :: The current strike index. */ + /* */ + /* <Output> */ + /* arange :: The SBit range containing the glyph index. */ + /* */ + /* astrike :: The SBit strike containing the glyph index. */ + /* */ + /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns */ + /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */ + /* glyph. */ + /* */ + typedef FT_Error + (*TT_Find_SBit_Image_Func)( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SBit_Metrics_Func */ + /* */ + /* <Description> */ + /* Get the big metrics for a given embedded bitmap. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* range :: The SBit range containing the glyph. */ + /* */ + /* <Output> */ + /* big_metrics :: A big SBit metrics structure for the glyph. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be positioned at the glyph's offset within */ + /* the `EBDT' table before the call. */ + /* */ + /* If the image format uses variable metrics, the stream cursor is */ + /* positioned just after the metrics header in the `EBDT' table on */ + /* function exit. */ + /* */ + typedef FT_Error + (*TT_Load_SBit_Metrics_Func)( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SBit_Image_Func */ + /* */ + /* <Description> */ + /* Load a given glyph sbit image from the font resource. This also */ + /* returns its metrics. */ + /* */ + /* <Input> */ + /* face :: */ + /* The target face object. */ + /* */ + /* strike_index :: */ + /* The strike index. */ + /* */ + /* glyph_index :: */ + /* The current glyph index. */ + /* */ + /* load_flags :: */ + /* The current load flags. */ + /* */ + /* stream :: */ + /* The input stream. */ + /* */ + /* <Output> */ + /* amap :: */ + /* The target pixmap. */ + /* */ + /* ametrics :: */ + /* A big sbit metrics structure for the glyph image. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* glyph sbit exists for the index. */ + /* */ + /* <Note> */ + /* The `map.buffer' field is always freed before the glyph is loaded. */ + /* */ + typedef FT_Error + (*TT_Load_SBit_Image_Func)( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *amap, + TT_SBit_MetricsRec *ametrics ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Set_SBit_Strike_Func */ + /* */ + /* <Description> */ + /* Select an sbit strike for a given size request. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* req :: The size request. */ + /* */ + /* <Output> */ + /* astrike_index :: The index of the sbit strike. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* sbit strike exists for the selected ppem values. */ + /* */ + typedef FT_Error + (*TT_Set_SBit_Strike_Func)( TT_Face face, + FT_Size_Request req, + FT_ULong* astrike_index ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Strike_Metrics_Func */ + /* */ + /* <Description> */ + /* Load the metrics of a given strike. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* strike_index :: The strike index. */ + /* */ + /* <Output> */ + /* metrics :: the metrics of the strike. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* such sbit strike exists. */ + /* */ + typedef FT_Error + (*TT_Load_Strike_Metrics_Func)( TT_Face face, + FT_ULong strike_index, + FT_Size_Metrics* metrics ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_PS_Name_Func */ + /* */ + /* <Description> */ + /* Get the PostScript glyph name of a glyph. */ + /* */ + /* <Input> */ + /* idx :: The glyph index. */ + /* */ + /* PSname :: The address of a string pointer. Will be NULL in case */ + /* of error, otherwise it is a pointer to the glyph name. */ + /* */ + /* You must not modify the returned string! */ + /* */ + /* <Output> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Get_PS_Name_Func)( TT_Face face, + FT_UInt idx, + FT_String** PSname ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Metrics_Func */ + /* */ + /* <Description> */ + /* Load a metrics table, which is a table with a horizontal and a */ + /* vertical version. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load the vertical one. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Load_Metrics_Func)( TT_Face face, + FT_Stream stream, + FT_Bool vertical ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_Metrics_Func */ + /* */ + /* <Description> */ + /* Load the horizontal or vertical header in a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* vertical :: A boolean flag. If set, load vertical metrics. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* <Output> */ + /* abearing :: The horizontal (or vertical) bearing. Set to zero in */ + /* case of error. */ + /* */ + /* aadvance :: The horizontal (or vertical) advance. Set to zero in */ + /* case of error. */ + /* */ + typedef void + (*TT_Get_Metrics_Func)( TT_Face face, + FT_Bool vertical, + FT_UInt gindex, + FT_Short* abearing, + FT_UShort* aadvance ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_Name_Func */ + /* */ + /* <Description> */ + /* From the `name' table, return a given ENGLISH name record in */ + /* ASCII. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* nameid :: The name id of the name record to return. */ + /* */ + /* <InOut> */ + /* name :: The address of an allocated string pointer. NULL if */ + /* no name is present. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Get_Name_Func)( TT_Face face, + FT_UShort nameid, + FT_String** name ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Table_Func */ + /* */ + /* <Description> */ + /* Load a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The function uses `face->goto_table' to seek the stream to the */ + /* start of the table, except while loading the font directory. */ + /* */ + typedef FT_Error + (*TT_Load_Table_Func)( TT_Face face, + FT_Stream stream ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Free_Table_Func */ + /* */ + /* <Description> */ + /* Free a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + typedef void + (*TT_Free_Table_Func)( TT_Face face ); + + + /* + * @functype: + * TT_Face_GetKerningFunc + * + * @description: + * Return the horizontal kerning value between two glyphs. + * + * @input: + * face :: A handle to the source face object. + * left_glyph :: The left glyph index. + * right_glyph :: The right glyph index. + * + * @return: + * The kerning value in font units. + */ + typedef FT_Int + (*TT_Face_GetKerningFunc)( TT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* SFNT_Interface */ + /* */ + /* <Description> */ + /* This structure holds pointers to the functions used to load and */ + /* free the basic tables that are required in a `sfnt' font file. */ + /* */ + /* <Fields> */ + /* Check the various xxx_Func() descriptions for details. */ + /* */ + typedef struct SFNT_Interface_ + { + TT_Loader_GotoTableFunc goto_table; + + TT_Init_Face_Func init_face; + TT_Load_Face_Func load_face; + TT_Done_Face_Func done_face; + FT_Module_Requester get_interface; + + TT_Load_Any_Func load_any; + + /* these functions are called by `load_face' but they can also */ + /* be called from external modules, if there is a need to do so */ + TT_Load_Table_Func load_head; + TT_Load_Metrics_Func load_hhea; + TT_Load_Table_Func load_cmap; + TT_Load_Table_Func load_maxp; + TT_Load_Table_Func load_os2; + TT_Load_Table_Func load_post; + + TT_Load_Table_Func load_name; + TT_Free_Table_Func free_name; + + /* this field was called `load_kerning' up to version 2.1.10 */ + TT_Load_Table_Func load_kern; + + TT_Load_Table_Func load_gasp; + TT_Load_Table_Func load_pclt; + + /* see `ttload.h'; this field was called `load_bitmap_header' up to */ + /* version 2.1.10 */ + TT_Load_Table_Func load_bhed; + + TT_Load_SBit_Image_Func load_sbit_image; + + /* see `ttpost.h' */ + TT_Get_PS_Name_Func get_psname; + TT_Free_Table_Func free_psnames; + + /* starting here, the structure differs from version 2.1.7 */ + + /* this field was introduced in version 2.1.8, named `get_psname' */ + TT_Face_GetKerningFunc get_kerning; + + /* new elements introduced after version 2.1.10 */ + + /* load the font directory, i.e., the offset table and */ + /* the table directory */ + TT_Load_Table_Func load_font_dir; + TT_Load_Metrics_Func load_hmtx; + + TT_Load_Table_Func load_eblc; + TT_Free_Table_Func free_eblc; + + TT_Set_SBit_Strike_Func set_sbit_strike; + TT_Load_Strike_Metrics_Func load_strike_metrics; + + TT_Get_Metrics_Func get_metrics; + + TT_Get_Name_Func get_name; + + } SFNT_Interface; + + + /* transitional */ + typedef SFNT_Interface* SFNT_Service; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SFNT_INTERFACE( \ + class_, \ + goto_table_, \ + init_face_, \ + load_face_, \ + done_face_, \ + get_interface_, \ + load_any_, \ + load_head_, \ + load_hhea_, \ + load_cmap_, \ + load_maxp_, \ + load_os2_, \ + load_post_, \ + load_name_, \ + free_name_, \ + load_kern_, \ + load_gasp_, \ + load_pclt_, \ + load_bhed_, \ + load_sbit_image_, \ + get_psname_, \ + free_psnames_, \ + get_kerning_, \ + load_font_dir_, \ + load_hmtx_, \ + load_eblc_, \ + free_eblc_, \ + set_sbit_strike_, \ + load_strike_metrics_, \ + get_metrics_, \ + get_name_ ) \ + static const SFNT_Interface class_ = \ + { \ + goto_table_, \ + init_face_, \ + load_face_, \ + done_face_, \ + get_interface_, \ + load_any_, \ + load_head_, \ + load_hhea_, \ + load_cmap_, \ + load_maxp_, \ + load_os2_, \ + load_post_, \ + load_name_, \ + free_name_, \ + load_kern_, \ + load_gasp_, \ + load_pclt_, \ + load_bhed_, \ + load_sbit_image_, \ + get_psname_, \ + free_psnames_, \ + get_kerning_, \ + load_font_dir_, \ + load_hmtx_, \ + load_eblc_, \ + free_eblc_, \ + set_sbit_strike_, \ + load_strike_metrics_, \ + get_metrics_, \ + get_name_, \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_INTERNAL( a, a_ ) \ + clazz->a = a_; + +#define FT_DEFINE_SFNT_INTERFACE( \ + class_, \ + goto_table_, \ + init_face_, \ + load_face_, \ + done_face_, \ + get_interface_, \ + load_any_, \ + load_head_, \ + load_hhea_, \ + load_cmap_, \ + load_maxp_, \ + load_os2_, \ + load_post_, \ + load_name_, \ + free_name_, \ + load_kern_, \ + load_gasp_, \ + load_pclt_, \ + load_bhed_, \ + load_sbit_image_, \ + get_psname_, \ + free_psnames_, \ + get_kerning_, \ + load_font_dir_, \ + load_hmtx_, \ + load_eblc_, \ + free_eblc_, \ + set_sbit_strike_, \ + load_strike_metrics_, \ + get_metrics_, \ + get_name_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Library library, \ + SFNT_Interface* clazz ) \ + { \ + FT_UNUSED( library ); \ + \ + clazz->goto_table = goto_table_; \ + clazz->init_face = init_face_; \ + clazz->load_face = load_face_; \ + clazz->done_face = done_face_; \ + clazz->get_interface = get_interface_; \ + clazz->load_any = load_any_; \ + clazz->load_head = load_head_; \ + clazz->load_hhea = load_hhea_; \ + clazz->load_cmap = load_cmap_; \ + clazz->load_maxp = load_maxp_; \ + clazz->load_os2 = load_os2_; \ + clazz->load_post = load_post_; \ + clazz->load_name = load_name_; \ + clazz->free_name = free_name_; \ + clazz->load_kern = load_kern_; \ + clazz->load_gasp = load_gasp_; \ + clazz->load_pclt = load_pclt_; \ + clazz->load_bhed = load_bhed_; \ + clazz->load_sbit_image = load_sbit_image_; \ + clazz->get_psname = get_psname_; \ + clazz->free_psnames = free_psnames_; \ + clazz->get_kerning = get_kerning_; \ + clazz->load_font_dir = load_font_dir_; \ + clazz->load_hmtx = load_hmtx_; \ + clazz->load_eblc = load_eblc_; \ + clazz->free_eblc = free_eblc_; \ + clazz->set_sbit_strike = set_sbit_strike_; \ + clazz->load_strike_metrics = load_strike_metrics_; \ + clazz->get_metrics = get_metrics_; \ + clazz->get_name = get_name_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* SFNT_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/t1types.h b/builddir/freetype-2.7.0/include/freetype/internal/t1types.h new file mode 100644 index 0000000..494c011 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/t1types.h @@ -0,0 +1,257 @@ +/***************************************************************************/ +/* */ +/* t1types.h */ +/* */ +/* Basic Type1/Type2 type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef T1TYPES_H_ +#define T1TYPES_H_ + + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_HASH_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_EncodingRec */ + /* */ + /* <Description> */ + /* A structure modeling a custom encoding. */ + /* */ + /* <Fields> */ + /* num_chars :: The number of character codes in the encoding. */ + /* Usually 256. */ + /* */ + /* code_first :: The lowest valid character code in the encoding. */ + /* */ + /* code_last :: The highest valid character code in the encoding */ + /* + 1. When equal to code_first there are no valid */ + /* character codes. */ + /* */ + /* char_index :: An array of corresponding glyph indices. */ + /* */ + /* char_name :: An array of corresponding glyph names. */ + /* */ + typedef struct T1_EncodingRecRec_ + { + FT_Int num_chars; + FT_Int code_first; + FT_Int code_last; + + FT_UShort* char_index; + FT_String** char_name; + + } T1_EncodingRec, *T1_Encoding; + + + /* used to hold extra data of PS_FontInfoRec that + * cannot be stored in the publicly defined structure. + * + * Note these can't be blended with multiple-masters. + */ + typedef struct PS_FontExtraRec_ + { + FT_UShort fs_type; + + } PS_FontExtraRec; + + + typedef struct T1_FontRec_ + { + PS_FontInfoRec font_info; /* font info dictionary */ + PS_FontExtraRec font_extra; /* font info extra fields */ + PS_PrivateRec private_dict; /* private dictionary */ + FT_String* font_name; /* top-level dictionary */ + + T1_EncodingType encoding_type; + T1_EncodingRec encoding; + + FT_Byte* subrs_block; + FT_Byte* charstrings_block; + FT_Byte* glyph_names_block; + + FT_Int num_subrs; + FT_Byte** subrs; + FT_UInt* subrs_len; + FT_Hash subrs_hash; + + FT_Int num_glyphs; + FT_String** glyph_names; /* array of glyph names */ + FT_Byte** charstrings; /* array of glyph charstrings */ + FT_UInt* charstrings_len; + + FT_Byte paint_type; + FT_Byte font_type; + FT_Matrix font_matrix; + FT_Vector font_offset; + FT_BBox font_bbox; + FT_Long font_id; + + FT_Fixed stroke_width; + + } T1_FontRec, *T1_Font; + + + typedef struct CID_SubrsRec_ + { + FT_Int num_subrs; + FT_Byte** code; + + } CID_SubrsRec, *CID_Subrs; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** AFM FONT INFORMATION STRUCTURES ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AFM_TrackKernRec_ + { + FT_Int degree; + FT_Fixed min_ptsize; + FT_Fixed min_kern; + FT_Fixed max_ptsize; + FT_Fixed max_kern; + + } AFM_TrackKernRec, *AFM_TrackKern; + + typedef struct AFM_KernPairRec_ + { + FT_UInt index1; + FT_UInt index2; + FT_Int x; + FT_Int y; + + } AFM_KernPairRec, *AFM_KernPair; + + typedef struct AFM_FontInfoRec_ + { + FT_Bool IsCIDFont; + FT_BBox FontBBox; + FT_Fixed Ascender; + FT_Fixed Descender; + AFM_TrackKern TrackKerns; /* free if non-NULL */ + FT_UInt NumTrackKern; + AFM_KernPair KernPairs; /* free if non-NULL */ + FT_UInt NumKernPair; + + } AFM_FontInfoRec, *AFM_FontInfo; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** ORIGINAL T1_FACE CLASS DEFINITION ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct T1_FaceRec_* T1_Face; + typedef struct CID_FaceRec_* CID_Face; + + + typedef struct T1_FaceRec_ + { + FT_FaceRec root; + T1_FontRec type1; + const void* psnames; + const void* psaux; + const void* afm_data; + FT_CharMapRec charmaprecs[2]; + FT_CharMap charmaps[2]; + + /* support for Multiple Masters fonts */ + PS_Blend blend; + + /* undocumented, optional: indices of subroutines that express */ + /* the NormalizeDesignVector and the ConvertDesignVector procedure, */ + /* respectively, as Type 2 charstrings; -1 if keywords not present */ + FT_Int ndv_idx; + FT_Int cdv_idx; + + /* undocumented, optional: has the same meaning as len_buildchar */ + /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25 */ + FT_UInt len_buildchar; + FT_Long* buildchar; + + /* since version 2.1 - interface to PostScript hinter */ + const void* pshinter; + + } T1_FaceRec; + + + typedef struct CID_FaceRec_ + { + FT_FaceRec root; + void* psnames; + void* psaux; + CID_FaceInfoRec cid; + PS_FontExtraRec font_extra; +#if 0 + void* afm_data; +#endif + CID_Subrs subrs; + + /* since version 2.1 - interface to PostScript hinter */ + void* pshinter; + + /* since version 2.1.8, but was originally positioned after `afm_data' */ + FT_Byte* binary_data; /* used if hex data has been converted */ + FT_Stream cid_stream; + + } CID_FaceRec; + + +FT_END_HEADER + +#endif /* T1TYPES_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/internal/tttypes.h b/builddir/freetype-2.7.0/include/freetype/internal/tttypes.h new file mode 100644 index 0000000..4ed980b --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/internal/tttypes.h @@ -0,0 +1,1528 @@ +/***************************************************************************/ +/* */ +/* tttypes.h */ +/* */ +/* Basic SFNT/TrueType type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef TTTYPES_H_ +#define TTTYPES_H_ + + +#include <ft2build.h> +#include FT_TRUETYPE_TABLES_H +#include FT_INTERNAL_OBJECTS_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TTC_HeaderRec */ + /* */ + /* <Description> */ + /* TrueType collection header. This table contains the offsets of */ + /* the font headers of each distinct TrueType face in the file. */ + /* */ + /* <Fields> */ + /* tag :: Must be `ttc ' to indicate a TrueType collection. */ + /* */ + /* version :: The version number. */ + /* */ + /* count :: The number of faces in the collection. The */ + /* specification says this should be an unsigned long, but */ + /* we use a signed long since we need the value -1 for */ + /* specific purposes. */ + /* */ + /* offsets :: The offsets of the font headers, one per face. */ + /* */ + typedef struct TTC_HeaderRec_ + { + FT_ULong tag; + FT_Fixed version; + FT_Long count; + FT_ULong* offsets; + + } TTC_HeaderRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* SFNT_HeaderRec */ + /* */ + /* <Description> */ + /* SFNT file format header. */ + /* */ + /* <Fields> */ + /* format_tag :: The font format tag. */ + /* */ + /* num_tables :: The number of tables in file. */ + /* */ + /* search_range :: Must be `16 * (max power of 2 <= num_tables)'. */ + /* */ + /* entry_selector :: Must be log2 of `search_range / 16'. */ + /* */ + /* range_shift :: Must be `num_tables * 16 - search_range'. */ + /* */ + typedef struct SFNT_HeaderRec_ + { + FT_ULong format_tag; + FT_UShort num_tables; + FT_UShort search_range; + FT_UShort entry_selector; + FT_UShort range_shift; + + FT_ULong offset; /* not in file */ + + } SFNT_HeaderRec, *SFNT_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_TableRec */ + /* */ + /* <Description> */ + /* This structure describes a given table of a TrueType font. */ + /* */ + /* <Fields> */ + /* Tag :: A four-bytes tag describing the table. */ + /* */ + /* CheckSum :: The table checksum. This value can be ignored. */ + /* */ + /* Offset :: The offset of the table from the start of the TrueType */ + /* font in its resource. */ + /* */ + /* Length :: The table length (in bytes). */ + /* */ + typedef struct TT_TableRec_ + { + FT_ULong Tag; /* table type */ + FT_ULong CheckSum; /* table checksum */ + FT_ULong Offset; /* table file offset */ + FT_ULong Length; /* table length */ + + } TT_TableRec, *TT_Table; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* WOFF_HeaderRec */ + /* */ + /* <Description> */ + /* WOFF file format header. */ + /* */ + /* <Fields> */ + /* See */ + /* */ + /* http://www.w3.org/TR/WOFF/#WOFFHeader */ + /* */ + typedef struct WOFF_HeaderRec_ + { + FT_ULong signature; + FT_ULong flavor; + FT_ULong length; + FT_UShort num_tables; + FT_UShort reserved; + FT_ULong totalSfntSize; + FT_UShort majorVersion; + FT_UShort minorVersion; + FT_ULong metaOffset; + FT_ULong metaLength; + FT_ULong metaOrigLength; + FT_ULong privOffset; + FT_ULong privLength; + + } WOFF_HeaderRec, *WOFF_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* WOFF_TableRec */ + /* */ + /* <Description> */ + /* This structure describes a given table of a WOFF font. */ + /* */ + /* <Fields> */ + /* Tag :: A four-bytes tag describing the table. */ + /* */ + /* Offset :: The offset of the table from the start of the WOFF */ + /* font in its resource. */ + /* */ + /* CompLength :: Compressed table length (in bytes). */ + /* */ + /* OrigLength :: Uncompressed table length (in bytes). */ + /* */ + /* CheckSum :: The table checksum. This value can be ignored. */ + /* */ + /* OrigOffset :: The uncompressed table file offset. This value gets */ + /* computed while constructing the (uncompressed) SFNT */ + /* header. It is not contained in the WOFF file. */ + /* */ + typedef struct WOFF_TableRec_ + { + FT_ULong Tag; /* table ID */ + FT_ULong Offset; /* table file offset */ + FT_ULong CompLength; /* compressed table length */ + FT_ULong OrigLength; /* uncompressed table length */ + FT_ULong CheckSum; /* uncompressed checksum */ + + FT_ULong OrigOffset; /* uncompressed table file offset */ + /* (not in the WOFF file) */ + } WOFF_TableRec, *WOFF_Table; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_LongMetricsRec */ + /* */ + /* <Description> */ + /* A structure modeling the long metrics of the `hmtx' and `vmtx' */ + /* TrueType tables. The values are expressed in font units. */ + /* */ + /* <Fields> */ + /* advance :: The advance width or height for the glyph. */ + /* */ + /* bearing :: The left-side or top-side bearing for the glyph. */ + /* */ + typedef struct TT_LongMetricsRec_ + { + FT_UShort advance; + FT_Short bearing; + + } TT_LongMetricsRec, *TT_LongMetrics; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_ShortMetrics */ + /* */ + /* <Description> */ + /* A simple type to model the short metrics of the `hmtx' and `vmtx' */ + /* tables. */ + /* */ + typedef FT_Short TT_ShortMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_NameEntryRec */ + /* */ + /* <Description> */ + /* A structure modeling TrueType name records. Name records are used */ + /* to store important strings like family name, style name, */ + /* copyright, etc. in _localized_ versions (i.e., language, encoding, */ + /* etc). */ + /* */ + /* <Fields> */ + /* platformID :: The ID of the name's encoding platform. */ + /* */ + /* encodingID :: The platform-specific ID for the name's encoding. */ + /* */ + /* languageID :: The platform-specific ID for the name's language. */ + /* */ + /* nameID :: The ID specifying what kind of name this is. */ + /* */ + /* stringLength :: The length of the string in bytes. */ + /* */ + /* stringOffset :: The offset to the string in the `name' table. */ + /* */ + /* string :: A pointer to the string's bytes. Note that these */ + /* are usually UTF-16 encoded characters. */ + /* */ + typedef struct TT_NameEntryRec_ + { + FT_UShort platformID; + FT_UShort encodingID; + FT_UShort languageID; + FT_UShort nameID; + FT_UShort stringLength; + FT_ULong stringOffset; + + /* this last field is not defined in the spec */ + /* but used by the FreeType engine */ + + FT_Byte* string; + + } TT_NameEntryRec, *TT_NameEntry; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_NameTableRec */ + /* */ + /* <Description> */ + /* A structure modeling the TrueType name table. */ + /* */ + /* <Fields> */ + /* format :: The format of the name table. */ + /* */ + /* numNameRecords :: The number of names in table. */ + /* */ + /* storageOffset :: The offset of the name table in the `name' */ + /* TrueType table. */ + /* */ + /* names :: An array of name records. */ + /* */ + /* stream :: the file's input stream. */ + /* */ + typedef struct TT_NameTableRec_ + { + FT_UShort format; + FT_UInt numNameRecords; + FT_UInt storageOffset; + TT_NameEntryRec* names; + FT_Stream stream; + + } TT_NameTableRec, *TT_NameTable; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GaspRangeRec */ + /* */ + /* <Description> */ + /* A tiny structure used to model a gasp range according to the */ + /* TrueType specification. */ + /* */ + /* <Fields> */ + /* maxPPEM :: The maximum ppem value to which `gaspFlag' applies. */ + /* */ + /* gaspFlag :: A flag describing the grid-fitting and anti-aliasing */ + /* modes to be used. */ + /* */ + typedef struct TT_GaspRangeRec_ + { + FT_UShort maxPPEM; + FT_UShort gaspFlag; + + } TT_GaspRangeRec, *TT_GaspRange; + + +#define TT_GASP_GRIDFIT 0x01 +#define TT_GASP_DOGRAY 0x02 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GaspRec */ + /* */ + /* <Description> */ + /* A structure modeling the TrueType `gasp' table used to specify */ + /* grid-fitting and anti-aliasing behaviour. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* numRanges :: The number of gasp ranges in table. */ + /* */ + /* gaspRanges :: An array of gasp ranges. */ + /* */ + typedef struct TT_Gasp_ + { + FT_UShort version; + FT_UShort numRanges; + TT_GaspRange gaspRanges; + + } TT_GaspRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** EMBEDDED BITMAPS SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_MetricsRec */ + /* */ + /* <Description> */ + /* A structure used to hold the big metrics of a given glyph bitmap */ + /* in a TrueType or OpenType font. These are usually found in the */ + /* `EBDT' (Microsoft) or `bloc' (Apple) table. */ + /* */ + /* <Fields> */ + /* height :: The glyph height in pixels. */ + /* */ + /* width :: The glyph width in pixels. */ + /* */ + /* horiBearingX :: The horizontal left bearing. */ + /* */ + /* horiBearingY :: The horizontal top bearing. */ + /* */ + /* horiAdvance :: The horizontal advance. */ + /* */ + /* vertBearingX :: The vertical left bearing. */ + /* */ + /* vertBearingY :: The vertical top bearing. */ + /* */ + /* vertAdvance :: The vertical advance. */ + /* */ + typedef struct TT_SBit_MetricsRec_ + { + FT_UShort height; + FT_UShort width; + + FT_Short horiBearingX; + FT_Short horiBearingY; + FT_UShort horiAdvance; + + FT_Short vertBearingX; + FT_Short vertBearingY; + FT_UShort vertAdvance; + + } TT_SBit_MetricsRec, *TT_SBit_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_SmallMetricsRec */ + /* */ + /* <Description> */ + /* A structure used to hold the small metrics of a given glyph bitmap */ + /* in a TrueType or OpenType font. These are usually found in the */ + /* `EBDT' (Microsoft) or the `bdat' (Apple) table. */ + /* */ + /* <Fields> */ + /* height :: The glyph height in pixels. */ + /* */ + /* width :: The glyph width in pixels. */ + /* */ + /* bearingX :: The left-side bearing. */ + /* */ + /* bearingY :: The top-side bearing. */ + /* */ + /* advance :: The advance width or height. */ + /* */ + typedef struct TT_SBit_Small_Metrics_ + { + FT_Byte height; + FT_Byte width; + + FT_Char bearingX; + FT_Char bearingY; + FT_Byte advance; + + } TT_SBit_SmallMetricsRec, *TT_SBit_SmallMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_LineMetricsRec */ + /* */ + /* <Description> */ + /* A structure used to describe the text line metrics of a given */ + /* bitmap strike, for either a horizontal or vertical layout. */ + /* */ + /* <Fields> */ + /* ascender :: The ascender in pixels. */ + /* */ + /* descender :: The descender in pixels. */ + /* */ + /* max_width :: The maximum glyph width in pixels. */ + /* */ + /* caret_slope_enumerator :: Rise of the caret slope, typically set */ + /* to 1 for non-italic fonts. */ + /* */ + /* caret_slope_denominator :: Rise of the caret slope, typically set */ + /* to 0 for non-italic fonts. */ + /* */ + /* caret_offset :: Offset in pixels to move the caret for */ + /* proper positioning. */ + /* */ + /* min_origin_SB :: Minimum of horiBearingX (resp. */ + /* vertBearingY). */ + /* min_advance_SB :: Minimum of */ + /* */ + /* horizontal advance - */ + /* ( horiBearingX + width ) */ + /* */ + /* resp. */ + /* */ + /* vertical advance - */ + /* ( vertBearingY + height ) */ + /* */ + /* max_before_BL :: Maximum of horiBearingY (resp. */ + /* vertBearingY). */ + /* */ + /* min_after_BL :: Minimum of */ + /* */ + /* horiBearingY - height */ + /* */ + /* resp. */ + /* */ + /* vertBearingX - width */ + /* */ + /* pads :: Unused (to make the size of the record */ + /* a multiple of 32 bits. */ + /* */ + typedef struct TT_SBit_LineMetricsRec_ + { + FT_Char ascender; + FT_Char descender; + FT_Byte max_width; + FT_Char caret_slope_numerator; + FT_Char caret_slope_denominator; + FT_Char caret_offset; + FT_Char min_origin_SB; + FT_Char min_advance_SB; + FT_Char max_before_BL; + FT_Char min_after_BL; + FT_Char pads[2]; + + } TT_SBit_LineMetricsRec, *TT_SBit_LineMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_RangeRec */ + /* */ + /* <Description> */ + /* A TrueType/OpenType subIndexTable as defined in the `EBLC' */ + /* (Microsoft) or `bloc' (Apple) tables. */ + /* */ + /* <Fields> */ + /* first_glyph :: The first glyph index in the range. */ + /* */ + /* last_glyph :: The last glyph index in the range. */ + /* */ + /* index_format :: The format of index table. Valid values are 1 */ + /* to 5. */ + /* */ + /* image_format :: The format of `EBDT' image data. */ + /* */ + /* image_offset :: The offset to image data in `EBDT'. */ + /* */ + /* image_size :: For index formats 2 and 5. This is the size in */ + /* bytes of each glyph bitmap. */ + /* */ + /* big_metrics :: For index formats 2 and 5. This is the big */ + /* metrics for each glyph bitmap. */ + /* */ + /* num_glyphs :: For index formats 4 and 5. This is the number of */ + /* glyphs in the code array. */ + /* */ + /* glyph_offsets :: For index formats 1 and 3. */ + /* */ + /* glyph_codes :: For index formats 4 and 5. */ + /* */ + /* table_offset :: The offset of the index table in the `EBLC' */ + /* table. Only used during strike loading. */ + /* */ + typedef struct TT_SBit_RangeRec_ + { + FT_UShort first_glyph; + FT_UShort last_glyph; + + FT_UShort index_format; + FT_UShort image_format; + FT_ULong image_offset; + + FT_ULong image_size; + TT_SBit_MetricsRec metrics; + FT_ULong num_glyphs; + + FT_ULong* glyph_offsets; + FT_UShort* glyph_codes; + + FT_ULong table_offset; + + } TT_SBit_RangeRec, *TT_SBit_Range; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_StrikeRec */ + /* */ + /* <Description> */ + /* A structure used describe a given bitmap strike in the `EBLC' */ + /* (Microsoft) or `bloc' (Apple) tables. */ + /* */ + /* <Fields> */ + /* num_index_ranges :: The number of index ranges. */ + /* */ + /* index_ranges :: An array of glyph index ranges. */ + /* */ + /* color_ref :: Unused. `color_ref' is put in for future */ + /* enhancements, but these fields are already */ + /* in use by other platforms (e.g. Newton). */ + /* For details, please see */ + /* */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html */ + /* */ + /* hori :: The line metrics for horizontal layouts. */ + /* */ + /* vert :: The line metrics for vertical layouts. */ + /* */ + /* start_glyph :: The lowest glyph index for this strike. */ + /* */ + /* end_glyph :: The highest glyph index for this strike. */ + /* */ + /* x_ppem :: The number of horizontal pixels per EM. */ + /* */ + /* y_ppem :: The number of vertical pixels per EM. */ + /* */ + /* bit_depth :: The bit depth. Valid values are 1, 2, 4, */ + /* and 8. */ + /* */ + /* flags :: Is this a vertical or horizontal strike? For */ + /* details, please see */ + /* */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html */ + /* */ + typedef struct TT_SBit_StrikeRec_ + { + FT_Int num_ranges; + TT_SBit_Range sbit_ranges; + FT_ULong ranges_offset; + + FT_ULong color_ref; + + TT_SBit_LineMetricsRec hori; + TT_SBit_LineMetricsRec vert; + + FT_UShort start_glyph; + FT_UShort end_glyph; + + FT_Byte x_ppem; + FT_Byte y_ppem; + + FT_Byte bit_depth; + FT_Char flags; + + } TT_SBit_StrikeRec, *TT_SBit_Strike; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_ComponentRec */ + /* */ + /* <Description> */ + /* A simple structure to describe a compound sbit element. */ + /* */ + /* <Fields> */ + /* glyph_code :: The element's glyph index. */ + /* */ + /* x_offset :: The element's left bearing. */ + /* */ + /* y_offset :: The element's top bearing. */ + /* */ + typedef struct TT_SBit_ComponentRec_ + { + FT_UShort glyph_code; + FT_Char x_offset; + FT_Char y_offset; + + } TT_SBit_ComponentRec, *TT_SBit_Component; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_ScaleRec */ + /* */ + /* <Description> */ + /* A structure used describe a given bitmap scaling table, as defined */ + /* in the `EBSC' table. */ + /* */ + /* <Fields> */ + /* hori :: The horizontal line metrics. */ + /* */ + /* vert :: The vertical line metrics. */ + /* */ + /* x_ppem :: The number of horizontal pixels per EM. */ + /* */ + /* y_ppem :: The number of vertical pixels per EM. */ + /* */ + /* x_ppem_substitute :: Substitution x_ppem value. */ + /* */ + /* y_ppem_substitute :: Substitution y_ppem value. */ + /* */ + typedef struct TT_SBit_ScaleRec_ + { + TT_SBit_LineMetricsRec hori; + TT_SBit_LineMetricsRec vert; + + FT_Byte x_ppem; + FT_Byte y_ppem; + + FT_Byte x_ppem_substitute; + FT_Byte y_ppem_substitute; + + } TT_SBit_ScaleRec, *TT_SBit_Scale; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** POSTSCRIPT GLYPH NAMES SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_20Rec */ + /* */ + /* <Description> */ + /* Postscript names sub-table, format 2.0. Stores the PS name of */ + /* each glyph in the font face. */ + /* */ + /* <Fields> */ + /* num_glyphs :: The number of named glyphs in the table. */ + /* */ + /* num_names :: The number of PS names stored in the table. */ + /* */ + /* glyph_indices :: The indices of the glyphs in the names arrays. */ + /* */ + /* glyph_names :: The PS names not in Mac Encoding. */ + /* */ + typedef struct TT_Post_20Rec_ + { + FT_UShort num_glyphs; + FT_UShort num_names; + FT_UShort* glyph_indices; + FT_Char** glyph_names; + + } TT_Post_20Rec, *TT_Post_20; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_25Rec */ + /* */ + /* <Description> */ + /* Postscript names sub-table, format 2.5. Stores the PS name of */ + /* each glyph in the font face. */ + /* */ + /* <Fields> */ + /* num_glyphs :: The number of glyphs in the table. */ + /* */ + /* offsets :: An array of signed offsets in a normal Mac */ + /* Postscript name encoding. */ + /* */ + typedef struct TT_Post_25_ + { + FT_UShort num_glyphs; + FT_Char* offsets; + + } TT_Post_25Rec, *TT_Post_25; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_NamesRec */ + /* */ + /* <Description> */ + /* Postscript names table, either format 2.0 or 2.5. */ + /* */ + /* <Fields> */ + /* loaded :: A flag to indicate whether the PS names are loaded. */ + /* */ + /* format_20 :: The sub-table used for format 2.0. */ + /* */ + /* format_25 :: The sub-table used for format 2.5. */ + /* */ + typedef struct TT_Post_NamesRec_ + { + FT_Bool loaded; + + union + { + TT_Post_20Rec format_20; + TT_Post_25Rec format_25; + + } names; + + } TT_Post_NamesRec, *TT_Post_Names; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** GX VARIATION TABLE SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + typedef struct GX_BlendRec_ *GX_Blend; +#endif + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** EMBEDDED BDF PROPERTIES TABLE SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * These types are used to support a `BDF ' table that isn't part of the + * official TrueType specification. It is mainly used in SFNT-based + * bitmap fonts that were generated from a set of BDF fonts. + * + * The format of the table is as follows. + * + * USHORT version `BDF ' table version number, should be 0x0001. + * USHORT strikeCount Number of strikes (bitmap sizes) in this table. + * ULONG stringTable Offset (from start of BDF table) to string + * table. + * + * This is followed by an array of `strikeCount' descriptors, having the + * following format. + * + * USHORT ppem Vertical pixels per EM for this strike. + * USHORT numItems Number of items for this strike (properties and + * atoms). Maximum is 255. + * + * This array in turn is followed by `strikeCount' value sets. Each + * `value set' is an array of `numItems' items with the following format. + * + * ULONG item_name Offset in string table to item name. + * USHORT item_type The item type. Possible values are + * 0 => string (e.g., COMMENT) + * 1 => atom (e.g., FONT or even SIZE) + * 2 => int32 + * 3 => uint32 + * 0x10 => A flag to indicate a properties. This + * is ORed with the above values. + * ULONG item_value For strings => Offset into string table without + * the corresponding double quotes. + * For atoms => Offset into string table. + * For integers => Direct value. + * + * All strings in the string table consist of bytes and are + * zero-terminated. + * + */ + +#ifdef TT_CONFIG_OPTION_BDF + + typedef struct TT_BDFRec_ + { + FT_Byte* table; + FT_Byte* table_end; + FT_Byte* strings; + FT_ULong strings_size; + FT_UInt num_strikes; + FT_Bool loaded; + + } TT_BDFRec, *TT_BDF; + +#endif /* TT_CONFIG_OPTION_BDF */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** ORIGINAL TT_FACE CLASS DEFINITION ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This structure/class is defined here because it is common to the */ + /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ + /* */ + /* Note, however, that the classes TT_Size and TT_GlyphSlot are not */ + /* shared between font drivers, and are thus defined in `ttobjs.h'. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Face */ + /* */ + /* <Description> */ + /* A handle to a TrueType face/font object. A TT_Face encapsulates */ + /* the resolution and scaling independent parts of a TrueType font */ + /* resource. */ + /* */ + /* <Note> */ + /* The TT_Face structure is also used as a `parent class' for the */ + /* OpenType-CFF class (T2_Face). */ + /* */ + typedef struct TT_FaceRec_* TT_Face; + + + /* a function type used for the truetype bytecode interpreter hooks */ + typedef FT_Error + (*TT_Interpreter)( void* exec_context ); + + /* forward declaration */ + typedef struct TT_LoaderRec_* TT_Loader; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_GotoTableFunc */ + /* */ + /* <Description> */ + /* Seeks a stream to the start of a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* tag :: A 4-byte tag used to name the table. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Output> */ + /* length :: The length of the table in bytes. Set to 0 if not */ + /* needed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + typedef FT_Error + (*TT_Loader_GotoTableFunc)( TT_Face face, + FT_ULong tag, + FT_Stream stream, + FT_ULong* length ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_StartGlyphFunc */ + /* */ + /* <Description> */ + /* Seeks a stream to the start of a given glyph element, and opens a */ + /* frame for it. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + /* glyph index :: The index of the glyph to access. */ + /* */ + /* offset :: The offset of the glyph according to the */ + /* `locations' table. */ + /* */ + /* byte_count :: The size of the frame in bytes. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function is normally equivalent to FT_STREAM_SEEK(offset) */ + /* followed by FT_FRAME_ENTER(byte_count) with the loader's stream, */ + /* but alternative formats (e.g. compressed ones) might use something */ + /* different. */ + /* */ + typedef FT_Error + (*TT_Loader_StartGlyphFunc)( TT_Loader loader, + FT_UInt glyph_index, + FT_ULong offset, + FT_UInt byte_count ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_ReadGlyphFunc */ + /* */ + /* <Description> */ + /* Reads one glyph element (its header, a simple glyph, or a */ + /* composite) from the loader's current stream frame. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Loader_ReadGlyphFunc)( TT_Loader loader ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_EndGlyphFunc */ + /* */ + /* <Description> */ + /* Closes the current loader stream frame for the glyph. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + typedef void + (*TT_Loader_EndGlyphFunc)( TT_Loader loader ); + + + typedef enum TT_SbitTableType_ + { + TT_SBIT_TABLE_TYPE_NONE = 0, + TT_SBIT_TABLE_TYPE_EBLC, /* `EBLC' (Microsoft), */ + /* `bloc' (Apple) */ + TT_SBIT_TABLE_TYPE_CBLC, /* `CBLC' (Google) */ + TT_SBIT_TABLE_TYPE_SBIX, /* `sbix' (Apple) */ + + /* do not remove */ + TT_SBIT_TABLE_TYPE_MAX + + } TT_SbitTableType; + + + /*************************************************************************/ + /* */ + /* TrueType Face Type */ + /* */ + /* <Struct> */ + /* TT_Face */ + /* */ + /* <Description> */ + /* The TrueType face class. These objects model the resolution and */ + /* point-size independent data found in a TrueType font file. */ + /* */ + /* <Fields> */ + /* root :: The base FT_Face structure, managed by the */ + /* base layer. */ + /* */ + /* ttc_header :: The TrueType collection header, used when */ + /* the file is a `ttc' rather than a `ttf'. */ + /* For ordinary font files, the field */ + /* `ttc_header.count' is set to 0. */ + /* */ + /* format_tag :: The font format tag. */ + /* */ + /* num_tables :: The number of TrueType tables in this font */ + /* file. */ + /* */ + /* dir_tables :: The directory of TrueType tables for this */ + /* font file. */ + /* */ + /* header :: The font's font header (`head' table). */ + /* Read on font opening. */ + /* */ + /* horizontal :: The font's horizontal header (`hhea' */ + /* table). This field also contains the */ + /* associated horizontal metrics table */ + /* (`hmtx'). */ + /* */ + /* max_profile :: The font's maximum profile table. Read on */ + /* font opening. Note that some maximum */ + /* values cannot be taken directly from this */ + /* table. We thus define additional fields */ + /* below to hold the computed maxima. */ + /* */ + /* vertical_info :: A boolean which is set when the font file */ + /* contains vertical metrics. If not, the */ + /* value of the `vertical' field is */ + /* undefined. */ + /* */ + /* vertical :: The font's vertical header (`vhea' table). */ + /* This field also contains the associated */ + /* vertical metrics table (`vmtx'), if found. */ + /* IMPORTANT: The contents of this field is */ + /* undefined if the `vertical_info' field is */ + /* unset. */ + /* */ + /* num_names :: The number of name records within this */ + /* TrueType font. */ + /* */ + /* name_table :: The table of name records (`name'). */ + /* */ + /* os2 :: The font's OS/2 table (`OS/2'). */ + /* */ + /* postscript :: The font's PostScript table (`post' */ + /* table). The PostScript glyph names are */ + /* not loaded by the driver on face opening. */ + /* See the `ttpost' module for more details. */ + /* */ + /* cmap_table :: Address of the face's `cmap' SFNT table */ + /* in memory (it's an extracted frame). */ + /* */ + /* cmap_size :: The size in bytes of the `cmap_table' */ + /* described above. */ + /* */ + /* goto_table :: A function called by each TrueType table */ + /* loader to position a stream's cursor to */ + /* the start of a given table according to */ + /* its tag. It defaults to TT_Goto_Face but */ + /* can be different for strange formats (e.g. */ + /* Type 42). */ + /* */ + /* access_glyph_frame :: A function used to access the frame of a */ + /* given glyph within the face's font file. */ + /* */ + /* forget_glyph_frame :: A function used to forget the frame of a */ + /* given glyph when all data has been loaded. */ + /* */ + /* read_glyph_header :: A function used to read a glyph header. */ + /* It must be called between an `access' and */ + /* `forget'. */ + /* */ + /* read_simple_glyph :: A function used to read a simple glyph. */ + /* It must be called after the header was */ + /* read, and before the `forget'. */ + /* */ + /* read_composite_glyph :: A function used to read a composite glyph. */ + /* It must be called after the header was */ + /* read, and before the `forget'. */ + /* */ + /* sfnt :: A pointer to the SFNT service. */ + /* */ + /* psnames :: A pointer to the PostScript names service. */ + /* */ + /* hdmx :: The face's horizontal device metrics */ + /* (`hdmx' table). This table is optional in */ + /* TrueType/OpenType fonts. */ + /* */ + /* gasp :: The grid-fitting and scaling properties */ + /* table (`gasp'). This table is optional in */ + /* TrueType/OpenType fonts. */ + /* */ + /* pclt :: The `pclt' SFNT table. */ + /* */ + /* num_sbit_scales :: The number of sbit scales for this font. */ + /* */ + /* sbit_scales :: Array of sbit scales embedded in this */ + /* font. This table is optional in a */ + /* TrueType/OpenType font. */ + /* */ + /* postscript_names :: A table used to store the Postscript names */ + /* of the glyphs for this font. See the */ + /* file `ttconfig.h' for comments on the */ + /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ + /* */ + /* num_locations :: The number of glyph locations in this */ + /* TrueType file. This should be */ + /* identical to the number of glyphs. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* glyph_locations :: An array of longs. These are offsets to */ + /* glyph data within the `glyf' table. */ + /* Ignored for Type 2 font faces. */ + /* */ + /* glyf_len :: The length of the `glyf' table. Needed */ + /* for malformed `loca' tables. */ + /* */ + /* font_program_size :: Size in bytecodes of the face's font */ + /* program. 0 if none defined. Ignored for */ + /* Type 2 fonts. */ + /* */ + /* font_program :: The face's font program (bytecode stream) */ + /* executed at load time, also used during */ + /* glyph rendering. Comes from the `fpgm' */ + /* table. Ignored for Type 2 font fonts. */ + /* */ + /* cvt_program_size :: The size in bytecodes of the face's cvt */ + /* program. Ignored for Type 2 fonts. */ + /* */ + /* cvt_program :: The face's cvt program (bytecode stream) */ + /* executed each time an instance/size is */ + /* changed/reset. Comes from the `prep' */ + /* table. Ignored for Type 2 fonts. */ + /* */ + /* cvt_size :: Size of the control value table (in */ + /* entries). Ignored for Type 2 fonts. */ + /* */ + /* cvt :: The face's original control value table. */ + /* Coordinates are expressed in unscaled font */ + /* units. Comes from the `cvt ' table. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* num_kern_pairs :: The number of kerning pairs present in the */ + /* font file. The engine only loads the */ + /* first horizontal format 0 kern table it */ + /* finds in the font file. Ignored for */ + /* Type 2 fonts. */ + /* */ + /* kern_table_index :: The index of the kerning table in the font */ + /* kerning directory. Ignored for Type 2 */ + /* fonts. */ + /* */ + /* interpreter :: A pointer to the TrueType bytecode */ + /* interpreters field is also used to hook */ + /* the debugger in `ttdebug'. */ + /* */ + /* doblend :: A boolean which is set if the font should */ + /* be blended (this is for GX var). */ + /* */ + /* blend :: Contains the data needed to control GX */ + /* variation tables (rather like Multiple */ + /* Master data). */ + /* */ + /* extra :: Reserved for third-party font drivers. */ + /* */ + /* postscript_name :: The PS name of the font. Used by the */ + /* postscript name service. */ + /* */ + typedef struct TT_FaceRec_ + { + FT_FaceRec root; + + TTC_HeaderRec ttc_header; + + FT_ULong format_tag; + FT_UShort num_tables; + TT_Table dir_tables; + + TT_Header header; /* TrueType header table */ + TT_HoriHeader horizontal; /* TrueType horizontal header */ + + TT_MaxProfile max_profile; + + FT_Bool vertical_info; + TT_VertHeader vertical; /* TT Vertical header, if present */ + + FT_UShort num_names; /* number of name records */ + TT_NameTableRec name_table; /* name table */ + + TT_OS2 os2; /* TrueType OS/2 table */ + TT_Postscript postscript; /* TrueType Postscript table */ + + FT_Byte* cmap_table; /* extracted `cmap' table */ + FT_ULong cmap_size; + + TT_Loader_GotoTableFunc goto_table; + + TT_Loader_StartGlyphFunc access_glyph_frame; + TT_Loader_EndGlyphFunc forget_glyph_frame; + TT_Loader_ReadGlyphFunc read_glyph_header; + TT_Loader_ReadGlyphFunc read_simple_glyph; + TT_Loader_ReadGlyphFunc read_composite_glyph; + + /* a typeless pointer to the SFNT_Interface table used to load */ + /* the basic TrueType tables in the face object */ + void* sfnt; + + /* a typeless pointer to the FT_Service_PsCMapsRec table used to */ + /* handle glyph names <-> unicode & Mac values */ + void* psnames; + + + /***********************************************************************/ + /* */ + /* Optional TrueType/OpenType tables */ + /* */ + /***********************************************************************/ + + /* grid-fitting and scaling table */ + TT_GaspRec gasp; /* the `gasp' table */ + + /* PCL 5 table */ + TT_PCLT pclt; + + /* embedded bitmaps support */ + FT_ULong num_sbit_scales; + TT_SBit_Scale sbit_scales; + + /* postscript names table */ + TT_Post_NamesRec postscript_names; + + + /***********************************************************************/ + /* */ + /* TrueType-specific fields (ignored by the OTF-Type2 driver) */ + /* */ + /***********************************************************************/ + + /* the font program, if any */ + FT_ULong font_program_size; + FT_Byte* font_program; + + /* the cvt program, if any */ + FT_ULong cvt_program_size; + FT_Byte* cvt_program; + + /* the original, unscaled, control value table */ + FT_ULong cvt_size; + FT_Short* cvt; + + /* A pointer to the bytecode interpreter to use. This is also */ + /* used to hook the debugger for the `ttdebug' utility. */ + TT_Interpreter interpreter; + + + /***********************************************************************/ + /* */ + /* Other tables or fields. This is used by derivative formats like */ + /* OpenType. */ + /* */ + /***********************************************************************/ + + FT_Generic extra; + + const char* postscript_name; + + FT_ULong glyf_len; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Bool doblend; + GX_Blend blend; +#endif + + /* since version 2.2 */ + + FT_Byte* horz_metrics; + FT_ULong horz_metrics_size; + + FT_Byte* vert_metrics; + FT_ULong vert_metrics_size; + + FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ + FT_Byte* glyph_locations; + + FT_Byte* hdmx_table; + FT_ULong hdmx_table_size; + FT_UInt hdmx_record_count; + FT_ULong hdmx_record_size; + FT_Byte* hdmx_record_sizes; + + FT_Byte* sbit_table; + FT_ULong sbit_table_size; + TT_SbitTableType sbit_table_type; + FT_UInt sbit_num_strikes; + + FT_Byte* kern_table; + FT_ULong kern_table_size; + FT_UInt num_kern_tables; + FT_UInt32 kern_avail_bits; + FT_UInt32 kern_order_bits; + +#ifdef TT_CONFIG_OPTION_BDF + TT_BDFRec bdf; +#endif /* TT_CONFIG_OPTION_BDF */ + + /* since 2.3.0 */ + FT_ULong horz_metrics_offset; + FT_ULong vert_metrics_offset; + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + /* since 2.4.12 */ + FT_ULong sph_found_func_flags; /* special functions found */ + /* for this face */ + FT_Bool sph_compatibility_mode; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + /* since 2.7 */ + FT_ULong ebdt_start; /* either `CBDT', `EBDT', or `bdat' */ + FT_ULong ebdt_size; +#endif + + } TT_FaceRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GlyphZoneRec */ + /* */ + /* <Description> */ + /* A glyph zone is used to load, scale and hint glyph outline */ + /* coordinates. */ + /* */ + /* <Fields> */ + /* memory :: A handle to the memory manager. */ + /* */ + /* max_points :: The maximum size in points of the zone. */ + /* */ + /* max_contours :: Max size in links contours of the zone. */ + /* */ + /* n_points :: The current number of points in the zone. */ + /* */ + /* n_contours :: The current number of contours in the zone. */ + /* */ + /* org :: The original glyph coordinates (font */ + /* units/scaled). */ + /* */ + /* cur :: The current glyph coordinates (scaled/hinted). */ + /* */ + /* tags :: The point control tags. */ + /* */ + /* contours :: The contours end points. */ + /* */ + /* first_point :: Offset of the current subglyph's first point. */ + /* */ + typedef struct TT_GlyphZoneRec_ + { + FT_Memory memory; + FT_UShort max_points; + FT_Short max_contours; + FT_UShort n_points; /* number of points in zone */ + FT_Short n_contours; /* number of contours */ + + FT_Vector* org; /* original point coordinates */ + FT_Vector* cur; /* current point coordinates */ + FT_Vector* orus; /* original (unscaled) point coordinates */ + + FT_Byte* tags; /* current touch flags */ + FT_UShort* contours; /* contour end points */ + + FT_UShort first_point; /* offset of first (#0) point */ + + } TT_GlyphZoneRec, *TT_GlyphZone; + + + /* handle to execution context */ + typedef struct TT_ExecContextRec_* TT_ExecContext; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Size */ + /* */ + /* <Description> */ + /* A handle to a TrueType size object. */ + /* */ + typedef struct TT_SizeRec_* TT_Size; + + + /* glyph loader structure */ + typedef struct TT_LoaderRec_ + { + TT_Face face; + TT_Size size; + FT_GlyphSlot glyph; + FT_GlyphLoader gloader; + + FT_ULong load_flags; + FT_UInt glyph_index; + + FT_Stream stream; + FT_Int byte_len; + + FT_Short n_contours; + FT_BBox bbox; + FT_Int left_bearing; + FT_Int advance; + FT_Int linear; + FT_Bool linear_def; + FT_Vector pp1; + FT_Vector pp2; + + FT_ULong glyf_offset; + + /* the zone where we load our glyphs */ + TT_GlyphZoneRec base; + TT_GlyphZoneRec zone; + + TT_ExecContext exec; + FT_Byte* instructions; + FT_ULong ins_pos; + + /* for possible extensibility in other formats */ + void* other; + + /* since version 2.1.8 */ + FT_Int top_bearing; + FT_Int vadvance; + FT_Vector pp3; + FT_Vector pp4; + + /* since version 2.2.1 */ + FT_Byte* cursor; + FT_Byte* limit; + + /* since version 2.6.2 */ + FT_ListRec composites; + + } TT_LoaderRec; + + +FT_END_HEADER + +#endif /* TTTYPES_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/t1tables.h b/builddir/freetype-2.7.0/include/freetype/t1tables.h new file mode 100644 index 0000000..e272324 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/t1tables.h @@ -0,0 +1,761 @@ +/***************************************************************************/ +/* */ +/* t1tables.h */ +/* */ +/* Basic Type 1/Type 2 tables definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef T1TABLES_H_ +#define T1TABLES_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* type1_tables */ + /* */ + /* <Title> */ + /* Type 1 Tables */ + /* */ + /* <Abstract> */ + /* Type~1 (PostScript) specific font tables. */ + /* */ + /* <Description> */ + /* This section contains the definition of Type 1-specific tables, */ + /* including structures related to other PostScript font formats. */ + /* */ + /* <Order> */ + /* PS_FontInfoRec */ + /* PS_FontInfo */ + /* PS_PrivateRec */ + /* PS_Private */ + /* */ + /* CID_FaceDictRec */ + /* CID_FaceDict */ + /* CID_FaceInfoRec */ + /* CID_FaceInfo */ + /* */ + /* FT_Has_PS_Glyph_Names */ + /* FT_Get_PS_Font_Info */ + /* FT_Get_PS_Font_Private */ + /* FT_Get_PS_Font_Value */ + /* */ + /* T1_Blend_Flags */ + /* T1_EncodingType */ + /* PS_Dict_Keys */ + /* */ + /*************************************************************************/ + + + /* Note that we separate font data in PS_FontInfoRec and PS_PrivateRec */ + /* structures in order to support Multiple Master fonts. */ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfoRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type~1 or Type~2 FontInfo dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* FontInfo dictionary. */ + /* */ + typedef struct PS_FontInfoRec_ + { + FT_String* version; + FT_String* notice; + FT_String* full_name; + FT_String* family_name; + FT_String* weight; + FT_Long italic_angle; + FT_Bool is_fixed_pitch; + FT_Short underline_position; + FT_UShort underline_thickness; + + } PS_FontInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfo */ + /* */ + /* <Description> */ + /* A handle to a @PS_FontInfoRec structure. */ + /* */ + typedef struct PS_FontInfoRec_* PS_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_FontInfo */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_FontInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_FontInfoRec T1_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_PrivateRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type~1 or Type~2 private dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* Private dictionary. */ + /* */ + typedef struct PS_PrivateRec_ + { + FT_Int unique_id; + FT_Int lenIV; + + FT_Byte num_blue_values; + FT_Byte num_other_blues; + FT_Byte num_family_blues; + FT_Byte num_family_other_blues; + + FT_Short blue_values[14]; + FT_Short other_blues[10]; + + FT_Short family_blues [14]; + FT_Short family_other_blues[10]; + + FT_Fixed blue_scale; + FT_Int blue_shift; + FT_Int blue_fuzz; + + FT_UShort standard_width[1]; + FT_UShort standard_height[1]; + + FT_Byte num_snap_widths; + FT_Byte num_snap_heights; + FT_Bool force_bold; + FT_Bool round_stem_up; + + FT_Short snap_widths [13]; /* including std width */ + FT_Short snap_heights[13]; /* including std height */ + + FT_Fixed expansion_factor; + + FT_Long language_group; + FT_Long password; + + FT_Short min_feature[2]; + + } PS_PrivateRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Private */ + /* */ + /* <Description> */ + /* A handle to a @PS_PrivateRec structure. */ + /* */ + typedef struct PS_PrivateRec_* PS_Private; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_Private */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_PrivateRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_PrivateRec T1_Private; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* T1_Blend_Flags */ + /* */ + /* <Description> */ + /* A set of flags used to indicate which fields are present in a */ + /* given blend dictionary (font info or private). Used to support */ + /* Multiple Masters fonts. */ + /* */ + /* <Values> */ + /* T1_BLEND_UNDERLINE_POSITION :: */ + /* T1_BLEND_UNDERLINE_THICKNESS :: */ + /* T1_BLEND_ITALIC_ANGLE :: */ + /* T1_BLEND_BLUE_VALUES :: */ + /* T1_BLEND_OTHER_BLUES :: */ + /* T1_BLEND_STANDARD_WIDTH :: */ + /* T1_BLEND_STANDARD_HEIGHT :: */ + /* T1_BLEND_STEM_SNAP_WIDTHS :: */ + /* T1_BLEND_STEM_SNAP_HEIGHTS :: */ + /* T1_BLEND_BLUE_SCALE :: */ + /* T1_BLEND_BLUE_SHIFT :: */ + /* T1_BLEND_FAMILY_BLUES :: */ + /* T1_BLEND_FAMILY_OTHER_BLUES :: */ + /* T1_BLEND_FORCE_BOLD :: */ + /* */ + typedef enum T1_Blend_Flags_ + { + /* required fields in a FontInfo blend dictionary */ + T1_BLEND_UNDERLINE_POSITION = 0, + T1_BLEND_UNDERLINE_THICKNESS, + T1_BLEND_ITALIC_ANGLE, + + /* required fields in a Private blend dictionary */ + T1_BLEND_BLUE_VALUES, + T1_BLEND_OTHER_BLUES, + T1_BLEND_STANDARD_WIDTH, + T1_BLEND_STANDARD_HEIGHT, + T1_BLEND_STEM_SNAP_WIDTHS, + T1_BLEND_STEM_SNAP_HEIGHTS, + T1_BLEND_BLUE_SCALE, + T1_BLEND_BLUE_SHIFT, + T1_BLEND_FAMILY_BLUES, + T1_BLEND_FAMILY_OTHER_BLUES, + T1_BLEND_FORCE_BOLD, + + T1_BLEND_MAX /* do not remove */ + + } T1_Blend_Flags; + + + /* these constants are deprecated; use the corresponding */ + /* `T1_Blend_Flags' values instead */ +#define t1_blend_underline_position T1_BLEND_UNDERLINE_POSITION +#define t1_blend_underline_thickness T1_BLEND_UNDERLINE_THICKNESS +#define t1_blend_italic_angle T1_BLEND_ITALIC_ANGLE +#define t1_blend_blue_values T1_BLEND_BLUE_VALUES +#define t1_blend_other_blues T1_BLEND_OTHER_BLUES +#define t1_blend_standard_widths T1_BLEND_STANDARD_WIDTH +#define t1_blend_standard_height T1_BLEND_STANDARD_HEIGHT +#define t1_blend_stem_snap_widths T1_BLEND_STEM_SNAP_WIDTHS +#define t1_blend_stem_snap_heights T1_BLEND_STEM_SNAP_HEIGHTS +#define t1_blend_blue_scale T1_BLEND_BLUE_SCALE +#define t1_blend_blue_shift T1_BLEND_BLUE_SHIFT +#define t1_blend_family_blues T1_BLEND_FAMILY_BLUES +#define t1_blend_family_other_blues T1_BLEND_FAMILY_OTHER_BLUES +#define t1_blend_force_bold T1_BLEND_FORCE_BOLD +#define t1_blend_max T1_BLEND_MAX + + /* */ + + + /* maximum number of Multiple Masters designs, as defined in the spec */ +#define T1_MAX_MM_DESIGNS 16 + + /* maximum number of Multiple Masters axes, as defined in the spec */ +#define T1_MAX_MM_AXIS 4 + + /* maximum number of elements in a design map */ +#define T1_MAX_MM_MAP_POINTS 20 + + + /* this structure is used to store the BlendDesignMap entry for an axis */ + typedef struct PS_DesignMap_ + { + FT_Byte num_points; + FT_Long* design_points; + FT_Fixed* blend_points; + + } PS_DesignMapRec, *PS_DesignMap; + + /* backwards-compatible definition */ + typedef PS_DesignMapRec T1_DesignMap; + + + typedef struct PS_BlendRec_ + { + FT_UInt num_designs; + FT_UInt num_axis; + + FT_String* axis_names[T1_MAX_MM_AXIS]; + FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; + PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; + + FT_Fixed* weight_vector; + FT_Fixed* default_weight_vector; + + PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; + PS_Private privates [T1_MAX_MM_DESIGNS + 1]; + + FT_ULong blend_bitflags; + + FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1]; + + /* since 2.3.0 */ + + /* undocumented, optional: the default design instance; */ + /* corresponds to default_weight_vector -- */ + /* num_default_design_vector == 0 means it is not present */ + /* in the font and associated metrics files */ + FT_UInt default_design_vector[T1_MAX_MM_DESIGNS]; + FT_UInt num_default_design_vector; + + } PS_BlendRec, *PS_Blend; + + + /* backwards-compatible definition */ + typedef PS_BlendRec T1_Blend; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDictRec */ + /* */ + /* <Description> */ + /* A structure used to represent data in a CID top-level dictionary. */ + /* */ + typedef struct CID_FaceDictRec_ + { + PS_PrivateRec private_dict; + + FT_UInt len_buildchar; + FT_Fixed forcebold_threshold; + FT_Pos stroke_width; + FT_Fixed expansion_factor; + + FT_Byte paint_type; + FT_Byte font_type; + FT_Matrix font_matrix; + FT_Vector font_offset; + + FT_UInt num_subrs; + FT_ULong subrmap_offset; + FT_Int sd_bytes; + + } CID_FaceDictRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDict */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceDictRec structure. */ + /* */ + typedef struct CID_FaceDictRec_* CID_FaceDict; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FontDict */ + /* */ + /* <Description> */ + /* This type is equivalent to @CID_FaceDictRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef CID_FaceDictRec CID_FontDict; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfoRec */ + /* */ + /* <Description> */ + /* A structure used to represent CID Face information. */ + /* */ + typedef struct CID_FaceInfoRec_ + { + FT_String* cid_font_name; + FT_Fixed cid_version; + FT_Int cid_font_type; + + FT_String* registry; + FT_String* ordering; + FT_Int supplement; + + PS_FontInfoRec font_info; + FT_BBox font_bbox; + FT_ULong uid_base; + + FT_Int num_xuid; + FT_ULong xuid[16]; + + FT_ULong cidmap_offset; + FT_Int fd_bytes; + FT_Int gd_bytes; + FT_ULong cid_count; + + FT_Int num_dicts; + CID_FaceDict font_dicts; + + FT_ULong data_offset; + + } CID_FaceInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfo */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceInfoRec structure. */ + /* */ + typedef struct CID_FaceInfoRec_* CID_FaceInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_Info */ + /* */ + /* <Description> */ + /* This type is equivalent to @CID_FaceInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef CID_FaceInfoRec CID_Info; + + + /************************************************************************ + * + * @function: + * FT_Has_PS_Glyph_Names + * + * @description: + * Return true if a given face provides reliable PostScript glyph + * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, + * except that certain fonts (mostly TrueType) contain incorrect + * glyph name tables. + * + * When this function returns true, the caller is sure that the glyph + * names returned by @FT_Get_Glyph_Name are reliable. + * + * @input: + * face :: + * face handle + * + * @return: + * Boolean. True if glyph names are reliable. + * + */ + FT_EXPORT( FT_Int ) + FT_Has_PS_Glyph_Names( FT_Face face ); + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Info + * + * @description: + * Retrieve the @PS_FontInfoRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_info :: + * Output font info structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * String pointers within the @PS_FontInfoRec structure are owned by + * the face and don't need to be freed by the caller. Missing entries + * in the font's FontInfo dictionary are represented by NULL pointers. + * + * If the font's format is not PostScript-based, this function will + * return the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfo afont_info ); + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Private + * + * @description: + * Retrieve the @PS_PrivateRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_private :: + * Output private dictionary structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the @PS_PrivateRec structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function returns + * the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_PS_Font_Private( FT_Face face, + PS_Private afont_private ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* T1_EncodingType */ + /* */ + /* <Description> */ + /* An enumeration describing the `Encoding' entry in a Type 1 */ + /* dictionary. */ + /* */ + /* <Values> */ + /* T1_ENCODING_TYPE_NONE :: */ + /* T1_ENCODING_TYPE_ARRAY :: */ + /* T1_ENCODING_TYPE_STANDARD :: */ + /* T1_ENCODING_TYPE_ISOLATIN1 :: */ + /* T1_ENCODING_TYPE_EXPERT :: */ + /* */ + typedef enum T1_EncodingType_ + { + T1_ENCODING_TYPE_NONE = 0, + T1_ENCODING_TYPE_ARRAY, + T1_ENCODING_TYPE_STANDARD, + T1_ENCODING_TYPE_ISOLATIN1, + T1_ENCODING_TYPE_EXPERT + + } T1_EncodingType; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* PS_Dict_Keys */ + /* */ + /* <Description> */ + /* An enumeration used in calls to @FT_Get_PS_Font_Value to identify */ + /* the Type~1 dictionary entry to retrieve. */ + /* */ + /* <Values> */ + /* PS_DICT_FONT_TYPE :: */ + /* PS_DICT_FONT_MATRIX :: */ + /* PS_DICT_FONT_BBOX :: */ + /* PS_DICT_PAINT_TYPE :: */ + /* PS_DICT_FONT_NAME :: */ + /* PS_DICT_UNIQUE_ID :: */ + /* PS_DICT_NUM_CHAR_STRINGS :: */ + /* PS_DICT_CHAR_STRING_KEY :: */ + /* PS_DICT_CHAR_STRING :: */ + /* PS_DICT_ENCODING_TYPE :: */ + /* PS_DICT_ENCODING_ENTRY :: */ + /* PS_DICT_NUM_SUBRS :: */ + /* PS_DICT_SUBR :: */ + /* PS_DICT_STD_HW :: */ + /* PS_DICT_STD_VW :: */ + /* PS_DICT_NUM_BLUE_VALUES :: */ + /* PS_DICT_BLUE_VALUE :: */ + /* PS_DICT_BLUE_FUZZ :: */ + /* PS_DICT_NUM_OTHER_BLUES :: */ + /* PS_DICT_OTHER_BLUE :: */ + /* PS_DICT_NUM_FAMILY_BLUES :: */ + /* PS_DICT_FAMILY_BLUE :: */ + /* PS_DICT_NUM_FAMILY_OTHER_BLUES :: */ + /* PS_DICT_FAMILY_OTHER_BLUE :: */ + /* PS_DICT_BLUE_SCALE :: */ + /* PS_DICT_BLUE_SHIFT :: */ + /* PS_DICT_NUM_STEM_SNAP_H :: */ + /* PS_DICT_STEM_SNAP_H :: */ + /* PS_DICT_NUM_STEM_SNAP_V :: */ + /* PS_DICT_STEM_SNAP_V :: */ + /* PS_DICT_FORCE_BOLD :: */ + /* PS_DICT_RND_STEM_UP :: */ + /* PS_DICT_MIN_FEATURE :: */ + /* PS_DICT_LEN_IV :: */ + /* PS_DICT_PASSWORD :: */ + /* PS_DICT_LANGUAGE_GROUP :: */ + /* PS_DICT_VERSION :: */ + /* PS_DICT_NOTICE :: */ + /* PS_DICT_FULL_NAME :: */ + /* PS_DICT_FAMILY_NAME :: */ + /* PS_DICT_WEIGHT :: */ + /* PS_DICT_IS_FIXED_PITCH :: */ + /* PS_DICT_UNDERLINE_POSITION :: */ + /* PS_DICT_UNDERLINE_THICKNESS :: */ + /* PS_DICT_FS_TYPE :: */ + /* PS_DICT_ITALIC_ANGLE :: */ + /* */ + typedef enum PS_Dict_Keys_ + { + /* conventionally in the font dictionary */ + PS_DICT_FONT_TYPE, /* FT_Byte */ + PS_DICT_FONT_MATRIX, /* FT_Fixed */ + PS_DICT_FONT_BBOX, /* FT_Fixed */ + PS_DICT_PAINT_TYPE, /* FT_Byte */ + PS_DICT_FONT_NAME, /* FT_String* */ + PS_DICT_UNIQUE_ID, /* FT_Int */ + PS_DICT_NUM_CHAR_STRINGS, /* FT_Int */ + PS_DICT_CHAR_STRING_KEY, /* FT_String* */ + PS_DICT_CHAR_STRING, /* FT_String* */ + PS_DICT_ENCODING_TYPE, /* T1_EncodingType */ + PS_DICT_ENCODING_ENTRY, /* FT_String* */ + + /* conventionally in the font Private dictionary */ + PS_DICT_NUM_SUBRS, /* FT_Int */ + PS_DICT_SUBR, /* FT_String* */ + PS_DICT_STD_HW, /* FT_UShort */ + PS_DICT_STD_VW, /* FT_UShort */ + PS_DICT_NUM_BLUE_VALUES, /* FT_Byte */ + PS_DICT_BLUE_VALUE, /* FT_Short */ + PS_DICT_BLUE_FUZZ, /* FT_Int */ + PS_DICT_NUM_OTHER_BLUES, /* FT_Byte */ + PS_DICT_OTHER_BLUE, /* FT_Short */ + PS_DICT_NUM_FAMILY_BLUES, /* FT_Byte */ + PS_DICT_FAMILY_BLUE, /* FT_Short */ + PS_DICT_NUM_FAMILY_OTHER_BLUES, /* FT_Byte */ + PS_DICT_FAMILY_OTHER_BLUE, /* FT_Short */ + PS_DICT_BLUE_SCALE, /* FT_Fixed */ + PS_DICT_BLUE_SHIFT, /* FT_Int */ + PS_DICT_NUM_STEM_SNAP_H, /* FT_Byte */ + PS_DICT_STEM_SNAP_H, /* FT_Short */ + PS_DICT_NUM_STEM_SNAP_V, /* FT_Byte */ + PS_DICT_STEM_SNAP_V, /* FT_Short */ + PS_DICT_FORCE_BOLD, /* FT_Bool */ + PS_DICT_RND_STEM_UP, /* FT_Bool */ + PS_DICT_MIN_FEATURE, /* FT_Short */ + PS_DICT_LEN_IV, /* FT_Int */ + PS_DICT_PASSWORD, /* FT_Long */ + PS_DICT_LANGUAGE_GROUP, /* FT_Long */ + + /* conventionally in the font FontInfo dictionary */ + PS_DICT_VERSION, /* FT_String* */ + PS_DICT_NOTICE, /* FT_String* */ + PS_DICT_FULL_NAME, /* FT_String* */ + PS_DICT_FAMILY_NAME, /* FT_String* */ + PS_DICT_WEIGHT, /* FT_String* */ + PS_DICT_IS_FIXED_PITCH, /* FT_Bool */ + PS_DICT_UNDERLINE_POSITION, /* FT_Short */ + PS_DICT_UNDERLINE_THICKNESS, /* FT_UShort */ + PS_DICT_FS_TYPE, /* FT_UShort */ + PS_DICT_ITALIC_ANGLE, /* FT_Long */ + + PS_DICT_MAX = PS_DICT_ITALIC_ANGLE + + } PS_Dict_Keys; + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Value + * + * @description: + * Retrieve the value for the supplied key from a PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * key :: + * An enumeration value representing the dictionary key to retrieve. + * + * idx :: + * For array values, this specifies the index to be returned. + * + * value :: + * A pointer to memory into which to write the value. + * + * valen_len :: + * The size, in bytes, of the memory supplied for the value. + * + * @output: + * value :: + * The value matching the above key, if it exists. + * + * @return: + * The amount of memory (in bytes) required to hold the requested + * value (if it exists, -1 otherwise). + * + * @note: + * The values returned are not pointers into the internal structures of + * the face, but are `fresh' copies, so that the memory containing them + * belongs to the calling application. This also enforces the + * `read-only' nature of these values, i.e., this function cannot be + * used to manipulate the face. + * + * `value' is a void pointer because the values returned can be of + * various types. + * + * If either `value' is NULL or `value_len' is too small, just the + * required memory size for the requested entry is returned. + * + * The `idx' parameter is used, not only to retrieve elements of, for + * example, the FontMatrix or FontBBox, but also to retrieve name keys + * from the CharStrings dictionary, and the charstrings themselves. It + * is ignored for atomic values. + * + * PS_DICT_BLUE_SCALE returns a value that is scaled up by 1000. To + * get the value as in the font stream, you need to divide by + * 65536000.0 (to remove the FT_Fixed scale, and the x1000 scale). + * + * IMPORTANT: Only key/value pairs read by the FreeType interpreter can + * be retrieved. So, for example, PostScript procedures such as NP, + * ND, and RD are not available. Arbitrary keys are, obviously, not be + * available either. + * + * If the font's format is not PostScript-based, this function returns + * the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Long ) + FT_Get_PS_Font_Value( FT_Face face, + PS_Dict_Keys key, + FT_UInt idx, + void *value, + FT_Long value_len ); + + /* */ + +FT_END_HEADER + +#endif /* T1TABLES_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ttnameid.h b/builddir/freetype-2.7.0/include/freetype/ttnameid.h new file mode 100644 index 0000000..ce707f1 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ttnameid.h @@ -0,0 +1,1237 @@ +/***************************************************************************/ +/* */ +/* ttnameid.h */ +/* */ +/* TrueType name ID definitions (specification only). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef TTNAMEID_H_ +#define TTNAMEID_H_ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + + + /*************************************************************************/ + /* */ + /* Possible values for the `platform' identifier code in the name */ + /* records of the TTF `name' table. */ + /* */ + /*************************************************************************/ + + + /*********************************************************************** + * + * @enum: + * TT_PLATFORM_XXX + * + * @description: + * A list of valid values for the `platform_id' identifier code in + * @FT_CharMapRec and @FT_SfntName structures. + * + * @values: + * TT_PLATFORM_APPLE_UNICODE :: + * Used by Apple to indicate a Unicode character map and/or name entry. + * See @TT_APPLE_ID_XXX for corresponding `encoding_id' values. Note + * that name entries in this format are coded as big-endian UCS-2 + * character codes _only_. + * + * TT_PLATFORM_MACINTOSH :: + * Used by Apple to indicate a MacOS-specific charmap and/or name entry. + * See @TT_MAC_ID_XXX for corresponding `encoding_id' values. Note that + * most TrueType fonts contain an Apple roman charmap to be usable on + * MacOS systems (even if they contain a Microsoft charmap as well). + * + * TT_PLATFORM_ISO :: + * This value was used to specify ISO/IEC 10646 charmaps. It is however + * now deprecated. See @TT_ISO_ID_XXX for a list of corresponding + * `encoding_id' values. + * + * TT_PLATFORM_MICROSOFT :: + * Used by Microsoft to indicate Windows-specific charmaps. See + * @TT_MS_ID_XXX for a list of corresponding `encoding_id' values. + * Note that most fonts contain a Unicode charmap using + * (TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS). + * + * TT_PLATFORM_CUSTOM :: + * Used to indicate application-specific charmaps. + * + * TT_PLATFORM_ADOBE :: + * This value isn't part of any font format specification, but is used + * by FreeType to report Adobe-specific charmaps in an @FT_CharMapRec + * structure. See @TT_ADOBE_ID_XXX. + */ + +#define TT_PLATFORM_APPLE_UNICODE 0 +#define TT_PLATFORM_MACINTOSH 1 +#define TT_PLATFORM_ISO 2 /* deprecated */ +#define TT_PLATFORM_MICROSOFT 3 +#define TT_PLATFORM_CUSTOM 4 +#define TT_PLATFORM_ADOBE 7 /* artificial */ + + + /*********************************************************************** + * + * @enum: + * TT_APPLE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_APPLE_UNICODE charmaps and name entries. + * + * @values: + * TT_APPLE_ID_DEFAULT :: + * Unicode version 1.0. + * + * TT_APPLE_ID_UNICODE_1_1 :: + * Unicode 1.1; specifies Hangul characters starting at U+34xx. + * + * TT_APPLE_ID_ISO_10646 :: + * Deprecated (identical to preceding). + * + * TT_APPLE_ID_UNICODE_2_0 :: + * Unicode 2.0 and beyond (UTF-16 BMP only). + * + * TT_APPLE_ID_UNICODE_32 :: + * Unicode 3.1 and beyond, using UTF-32. + * + * TT_APPLE_ID_VARIANT_SELECTOR :: + * From Adobe, not Apple. Not a normal cmap. Specifies variations + * on a real cmap. + */ + +#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ +#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ +#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ +#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ +#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ +#define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */ + + + /*********************************************************************** + * + * @enum: + * TT_MAC_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MACINTOSH charmaps and name entries. + * + * @values: + * TT_MAC_ID_ROMAN :: + * TT_MAC_ID_JAPANESE :: + * TT_MAC_ID_TRADITIONAL_CHINESE :: + * TT_MAC_ID_KOREAN :: + * TT_MAC_ID_ARABIC :: + * TT_MAC_ID_HEBREW :: + * TT_MAC_ID_GREEK :: + * TT_MAC_ID_RUSSIAN :: + * TT_MAC_ID_RSYMBOL :: + * TT_MAC_ID_DEVANAGARI :: + * TT_MAC_ID_GURMUKHI :: + * TT_MAC_ID_GUJARATI :: + * TT_MAC_ID_ORIYA :: + * TT_MAC_ID_BENGALI :: + * TT_MAC_ID_TAMIL :: + * TT_MAC_ID_TELUGU :: + * TT_MAC_ID_KANNADA :: + * TT_MAC_ID_MALAYALAM :: + * TT_MAC_ID_SINHALESE :: + * TT_MAC_ID_BURMESE :: + * TT_MAC_ID_KHMER :: + * TT_MAC_ID_THAI :: + * TT_MAC_ID_LAOTIAN :: + * TT_MAC_ID_GEORGIAN :: + * TT_MAC_ID_ARMENIAN :: + * TT_MAC_ID_MALDIVIAN :: + * TT_MAC_ID_SIMPLIFIED_CHINESE :: + * TT_MAC_ID_TIBETAN :: + * TT_MAC_ID_MONGOLIAN :: + * TT_MAC_ID_GEEZ :: + * TT_MAC_ID_SLAVIC :: + * TT_MAC_ID_VIETNAMESE :: + * TT_MAC_ID_SINDHI :: + * TT_MAC_ID_UNINTERP :: + */ + +#define TT_MAC_ID_ROMAN 0 +#define TT_MAC_ID_JAPANESE 1 +#define TT_MAC_ID_TRADITIONAL_CHINESE 2 +#define TT_MAC_ID_KOREAN 3 +#define TT_MAC_ID_ARABIC 4 +#define TT_MAC_ID_HEBREW 5 +#define TT_MAC_ID_GREEK 6 +#define TT_MAC_ID_RUSSIAN 7 +#define TT_MAC_ID_RSYMBOL 8 +#define TT_MAC_ID_DEVANAGARI 9 +#define TT_MAC_ID_GURMUKHI 10 +#define TT_MAC_ID_GUJARATI 11 +#define TT_MAC_ID_ORIYA 12 +#define TT_MAC_ID_BENGALI 13 +#define TT_MAC_ID_TAMIL 14 +#define TT_MAC_ID_TELUGU 15 +#define TT_MAC_ID_KANNADA 16 +#define TT_MAC_ID_MALAYALAM 17 +#define TT_MAC_ID_SINHALESE 18 +#define TT_MAC_ID_BURMESE 19 +#define TT_MAC_ID_KHMER 20 +#define TT_MAC_ID_THAI 21 +#define TT_MAC_ID_LAOTIAN 22 +#define TT_MAC_ID_GEORGIAN 23 +#define TT_MAC_ID_ARMENIAN 24 +#define TT_MAC_ID_MALDIVIAN 25 +#define TT_MAC_ID_SIMPLIFIED_CHINESE 25 +#define TT_MAC_ID_TIBETAN 26 +#define TT_MAC_ID_MONGOLIAN 27 +#define TT_MAC_ID_GEEZ 28 +#define TT_MAC_ID_SLAVIC 29 +#define TT_MAC_ID_VIETNAMESE 30 +#define TT_MAC_ID_SINDHI 31 +#define TT_MAC_ID_UNINTERP 32 + + + /*********************************************************************** + * + * @enum: + * TT_ISO_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ISO charmaps and name entries. + * + * Their use is now deprecated. + * + * @values: + * TT_ISO_ID_7BIT_ASCII :: + * ASCII. + * TT_ISO_ID_10646 :: + * ISO/10646. + * TT_ISO_ID_8859_1 :: + * Also known as Latin-1. + */ + +#define TT_ISO_ID_7BIT_ASCII 0 +#define TT_ISO_ID_10646 1 +#define TT_ISO_ID_8859_1 2 + + + /*********************************************************************** + * + * @enum: + * TT_MS_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MICROSOFT charmaps and name entries. + * + * @values: + * TT_MS_ID_SYMBOL_CS :: + * Corresponds to Microsoft symbol encoding. See + * @FT_ENCODING_MS_SYMBOL. + * + * TT_MS_ID_UNICODE_CS :: + * Corresponds to a Microsoft WGL4 charmap, matching Unicode. See + * @FT_ENCODING_UNICODE. + * + * TT_MS_ID_SJIS :: + * Corresponds to SJIS Japanese encoding. See @FT_ENCODING_SJIS. + * + * TT_MS_ID_GB2312 :: + * Corresponds to Simplified Chinese as used in Mainland China. See + * @FT_ENCODING_GB2312. + * + * TT_MS_ID_BIG_5 :: + * Corresponds to Traditional Chinese as used in Taiwan and Hong Kong. + * See @FT_ENCODING_BIG5. + * + * TT_MS_ID_WANSUNG :: + * Corresponds to Korean Wansung encoding. See @FT_ENCODING_WANSUNG. + * + * TT_MS_ID_JOHAB :: + * Corresponds to Johab encoding. See @FT_ENCODING_JOHAB. + * + * TT_MS_ID_UCS_4 :: + * Corresponds to UCS-4 or UTF-32 charmaps. This has been added to + * the OpenType specification version 1.4 (mid-2001.) + */ + +#define TT_MS_ID_SYMBOL_CS 0 +#define TT_MS_ID_UNICODE_CS 1 +#define TT_MS_ID_SJIS 2 +#define TT_MS_ID_GB2312 3 +#define TT_MS_ID_BIG_5 4 +#define TT_MS_ID_WANSUNG 5 +#define TT_MS_ID_JOHAB 6 +#define TT_MS_ID_UCS_4 10 + + + /*********************************************************************** + * + * @enum: + * TT_ADOBE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ADOBE charmaps. This is a FreeType-specific extension! + * + * @values: + * TT_ADOBE_ID_STANDARD :: + * Adobe standard encoding. + * TT_ADOBE_ID_EXPERT :: + * Adobe expert encoding. + * TT_ADOBE_ID_CUSTOM :: + * Adobe custom encoding. + * TT_ADOBE_ID_LATIN_1 :: + * Adobe Latin~1 encoding. + */ + +#define TT_ADOBE_ID_STANDARD 0 +#define TT_ADOBE_ID_EXPERT 1 +#define TT_ADOBE_ID_CUSTOM 2 +#define TT_ADOBE_ID_LATIN_1 3 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if the `platform' identifier code is */ + /* TT_PLATFORM_MACINTOSH. These values are also used as return values */ + /* for function @FT_Get_CMap_Language_ID. */ + /* */ + /* The canonical source for the Apple assigned Language ID's is at */ + /* */ + /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html */ + /* */ +#define TT_MAC_LANGID_ENGLISH 0 +#define TT_MAC_LANGID_FRENCH 1 +#define TT_MAC_LANGID_GERMAN 2 +#define TT_MAC_LANGID_ITALIAN 3 +#define TT_MAC_LANGID_DUTCH 4 +#define TT_MAC_LANGID_SWEDISH 5 +#define TT_MAC_LANGID_SPANISH 6 +#define TT_MAC_LANGID_DANISH 7 +#define TT_MAC_LANGID_PORTUGUESE 8 +#define TT_MAC_LANGID_NORWEGIAN 9 +#define TT_MAC_LANGID_HEBREW 10 +#define TT_MAC_LANGID_JAPANESE 11 +#define TT_MAC_LANGID_ARABIC 12 +#define TT_MAC_LANGID_FINNISH 13 +#define TT_MAC_LANGID_GREEK 14 +#define TT_MAC_LANGID_ICELANDIC 15 +#define TT_MAC_LANGID_MALTESE 16 +#define TT_MAC_LANGID_TURKISH 17 +#define TT_MAC_LANGID_CROATIAN 18 +#define TT_MAC_LANGID_CHINESE_TRADITIONAL 19 +#define TT_MAC_LANGID_URDU 20 +#define TT_MAC_LANGID_HINDI 21 +#define TT_MAC_LANGID_THAI 22 +#define TT_MAC_LANGID_KOREAN 23 +#define TT_MAC_LANGID_LITHUANIAN 24 +#define TT_MAC_LANGID_POLISH 25 +#define TT_MAC_LANGID_HUNGARIAN 26 +#define TT_MAC_LANGID_ESTONIAN 27 +#define TT_MAC_LANGID_LETTISH 28 +#define TT_MAC_LANGID_SAAMISK 29 +#define TT_MAC_LANGID_FAEROESE 30 +#define TT_MAC_LANGID_FARSI 31 +#define TT_MAC_LANGID_RUSSIAN 32 +#define TT_MAC_LANGID_CHINESE_SIMPLIFIED 33 +#define TT_MAC_LANGID_FLEMISH 34 +#define TT_MAC_LANGID_IRISH 35 +#define TT_MAC_LANGID_ALBANIAN 36 +#define TT_MAC_LANGID_ROMANIAN 37 +#define TT_MAC_LANGID_CZECH 38 +#define TT_MAC_LANGID_SLOVAK 39 +#define TT_MAC_LANGID_SLOVENIAN 40 +#define TT_MAC_LANGID_YIDDISH 41 +#define TT_MAC_LANGID_SERBIAN 42 +#define TT_MAC_LANGID_MACEDONIAN 43 +#define TT_MAC_LANGID_BULGARIAN 44 +#define TT_MAC_LANGID_UKRAINIAN 45 +#define TT_MAC_LANGID_BYELORUSSIAN 46 +#define TT_MAC_LANGID_UZBEK 47 +#define TT_MAC_LANGID_KAZAKH 48 +#define TT_MAC_LANGID_AZERBAIJANI 49 +#define TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT 49 +#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT 50 +#define TT_MAC_LANGID_ARMENIAN 51 +#define TT_MAC_LANGID_GEORGIAN 52 +#define TT_MAC_LANGID_MOLDAVIAN 53 +#define TT_MAC_LANGID_KIRGHIZ 54 +#define TT_MAC_LANGID_TAJIKI 55 +#define TT_MAC_LANGID_TURKMEN 56 +#define TT_MAC_LANGID_MONGOLIAN 57 +#define TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT 57 +#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT 58 +#define TT_MAC_LANGID_PASHTO 59 +#define TT_MAC_LANGID_KURDISH 60 +#define TT_MAC_LANGID_KASHMIRI 61 +#define TT_MAC_LANGID_SINDHI 62 +#define TT_MAC_LANGID_TIBETAN 63 +#define TT_MAC_LANGID_NEPALI 64 +#define TT_MAC_LANGID_SANSKRIT 65 +#define TT_MAC_LANGID_MARATHI 66 +#define TT_MAC_LANGID_BENGALI 67 +#define TT_MAC_LANGID_ASSAMESE 68 +#define TT_MAC_LANGID_GUJARATI 69 +#define TT_MAC_LANGID_PUNJABI 70 +#define TT_MAC_LANGID_ORIYA 71 +#define TT_MAC_LANGID_MALAYALAM 72 +#define TT_MAC_LANGID_KANNADA 73 +#define TT_MAC_LANGID_TAMIL 74 +#define TT_MAC_LANGID_TELUGU 75 +#define TT_MAC_LANGID_SINHALESE 76 +#define TT_MAC_LANGID_BURMESE 77 +#define TT_MAC_LANGID_KHMER 78 +#define TT_MAC_LANGID_LAO 79 +#define TT_MAC_LANGID_VIETNAMESE 80 +#define TT_MAC_LANGID_INDONESIAN 81 +#define TT_MAC_LANGID_TAGALOG 82 +#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT 83 +#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT 84 +#define TT_MAC_LANGID_AMHARIC 85 +#define TT_MAC_LANGID_TIGRINYA 86 +#define TT_MAC_LANGID_GALLA 87 +#define TT_MAC_LANGID_SOMALI 88 +#define TT_MAC_LANGID_SWAHILI 89 +#define TT_MAC_LANGID_RUANDA 90 +#define TT_MAC_LANGID_RUNDI 91 +#define TT_MAC_LANGID_CHEWA 92 +#define TT_MAC_LANGID_MALAGASY 93 +#define TT_MAC_LANGID_ESPERANTO 94 +#define TT_MAC_LANGID_WELSH 128 +#define TT_MAC_LANGID_BASQUE 129 +#define TT_MAC_LANGID_CATALAN 130 +#define TT_MAC_LANGID_LATIN 131 +#define TT_MAC_LANGID_QUECHUA 132 +#define TT_MAC_LANGID_GUARANI 133 +#define TT_MAC_LANGID_AYMARA 134 +#define TT_MAC_LANGID_TATAR 135 +#define TT_MAC_LANGID_UIGHUR 136 +#define TT_MAC_LANGID_DZONGKHA 137 +#define TT_MAC_LANGID_JAVANESE 138 +#define TT_MAC_LANGID_SUNDANESE 139 + + +#if 0 /* these seem to be errors that have been dropped */ + +#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 +#define TT_MAC_LANGID_IRISH_GAELIC 141 + +#endif + + + /* The following codes are new as of 2000-03-10 */ +#define TT_MAC_LANGID_GALICIAN 140 +#define TT_MAC_LANGID_AFRIKAANS 141 +#define TT_MAC_LANGID_BRETON 142 +#define TT_MAC_LANGID_INUKTITUT 143 +#define TT_MAC_LANGID_SCOTTISH_GAELIC 144 +#define TT_MAC_LANGID_MANX_GAELIC 145 +#define TT_MAC_LANGID_IRISH_GAELIC 146 +#define TT_MAC_LANGID_TONGAN 147 +#define TT_MAC_LANGID_GREEK_POLYTONIC 148 +#define TT_MAC_LANGID_GREELANDIC 149 +#define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if the `platform' identifier code is */ + /* TT_PLATFORM_MICROSOFT. */ + /* */ + /* The canonical source for the MS assigned LCIDs is */ + /* */ + /* http://www.microsoft.com/globaldev/reference/lcid-all.mspx */ + /* */ + +#define TT_MS_LANGID_ARABIC_GENERAL 0x0001 +#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 +#define TT_MS_LANGID_ARABIC_IRAQ 0x0801 +#define TT_MS_LANGID_ARABIC_EGYPT 0x0C01 +#define TT_MS_LANGID_ARABIC_LIBYA 0x1001 +#define TT_MS_LANGID_ARABIC_ALGERIA 0x1401 +#define TT_MS_LANGID_ARABIC_MOROCCO 0x1801 +#define TT_MS_LANGID_ARABIC_TUNISIA 0x1C01 +#define TT_MS_LANGID_ARABIC_OMAN 0x2001 +#define TT_MS_LANGID_ARABIC_YEMEN 0x2401 +#define TT_MS_LANGID_ARABIC_SYRIA 0x2801 +#define TT_MS_LANGID_ARABIC_JORDAN 0x2C01 +#define TT_MS_LANGID_ARABIC_LEBANON 0x3001 +#define TT_MS_LANGID_ARABIC_KUWAIT 0x3401 +#define TT_MS_LANGID_ARABIC_UAE 0x3801 +#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3C01 +#define TT_MS_LANGID_ARABIC_QATAR 0x4001 +#define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 +#define TT_MS_LANGID_CATALAN_SPAIN 0x0403 +#define TT_MS_LANGID_CHINESE_GENERAL 0x0004 +#define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 +#define TT_MS_LANGID_CHINESE_PRC 0x0804 +#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0C04 +#define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 + +#if 1 /* this looks like the correct value */ +#define TT_MS_LANGID_CHINESE_MACAU 0x1404 +#else /* but beware, Microsoft may change its mind... + the most recent Word reference has the following: */ +#define TT_MS_LANGID_CHINESE_MACAU TT_MS_LANGID_CHINESE_HONG_KONG +#endif + +#if 0 /* used only with .NET `cultures'; commented out */ +#define TT_MS_LANGID_CHINESE_TRADITIONAL 0x7C04 +#endif + +#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC 0x0405 +#define TT_MS_LANGID_DANISH_DENMARK 0x0406 +#define TT_MS_LANGID_GERMAN_GERMANY 0x0407 +#define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 +#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0C07 +#define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 +#define TT_MS_LANGID_GERMAN_LIECHTENSTEI 0x1407 +#define TT_MS_LANGID_GREEK_GREECE 0x0408 + + /* don't ask what this one means... It is commented out currently. */ +#if 0 +#define TT_MS_LANGID_GREEK_GREECE2 0x2008 +#endif + +#define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 +#define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 +#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 +#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0C09 +#define TT_MS_LANGID_ENGLISH_CANADA 0x1009 +#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND 0x1409 +#define TT_MS_LANGID_ENGLISH_IRELAND 0x1809 +#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1C09 +#define TT_MS_LANGID_ENGLISH_JAMAICA 0x2009 +#define TT_MS_LANGID_ENGLISH_CARIBBEAN 0x2409 +#define TT_MS_LANGID_ENGLISH_BELIZE 0x2809 +#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2C09 +#define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 +#define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 +#define TT_MS_LANGID_ENGLISH_INDONESIA 0x3809 +#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3C09 +#define TT_MS_LANGID_ENGLISH_INDIA 0x4009 +#define TT_MS_LANGID_ENGLISH_MALAYSIA 0x4409 +#define TT_MS_LANGID_ENGLISH_SINGAPORE 0x4809 +#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040A +#define TT_MS_LANGID_SPANISH_MEXICO 0x080A +#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0C0A +#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100A +#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140A +#define TT_MS_LANGID_SPANISH_PANAMA 0x180A +#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1C0A +#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200A +#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240A +#define TT_MS_LANGID_SPANISH_PERU 0x280A +#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2C0A +#define TT_MS_LANGID_SPANISH_ECUADOR 0x300A +#define TT_MS_LANGID_SPANISH_CHILE 0x340A +#define TT_MS_LANGID_SPANISH_URUGUAY 0x380A +#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3C0A +#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400A +#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440A +#define TT_MS_LANGID_SPANISH_HONDURAS 0x480A +#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4C0A +#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500A +#define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540A + /* The following ID blatantly violate MS specs by using a */ + /* sublanguage > 0x1F. */ +#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40AU +#define TT_MS_LANGID_FINNISH_FINLAND 0x040B +#define TT_MS_LANGID_FRENCH_FRANCE 0x040C +#define TT_MS_LANGID_FRENCH_BELGIUM 0x080C +#define TT_MS_LANGID_FRENCH_CANADA 0x0C0C +#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100C +#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140C +#define TT_MS_LANGID_FRENCH_MONACO 0x180C +#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1C0C +#define TT_MS_LANGID_FRENCH_REUNION 0x200C +#define TT_MS_LANGID_FRENCH_CONGO 0x240C + /* which was formerly: */ +#define TT_MS_LANGID_FRENCH_ZAIRE TT_MS_LANGID_FRENCH_CONGO +#define TT_MS_LANGID_FRENCH_SENEGAL 0x280C +#define TT_MS_LANGID_FRENCH_CAMEROON 0x2C0C +#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300C +#define TT_MS_LANGID_FRENCH_MALI 0x340C +#define TT_MS_LANGID_FRENCH_MOROCCO 0x380C +#define TT_MS_LANGID_FRENCH_HAITI 0x3C0C + /* and another violation of the spec (see 0xE40AU) */ +#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40CU +#define TT_MS_LANGID_HEBREW_ISRAEL 0x040D +#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040E +#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040F +#define TT_MS_LANGID_ITALIAN_ITALY 0x0410 +#define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 +#define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 +#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA 0x0412 +#define TT_MS_LANGID_KOREAN_JOHAB_KOREA 0x0812 +#define TT_MS_LANGID_DUTCH_NETHERLANDS 0x0413 +#define TT_MS_LANGID_DUTCH_BELGIUM 0x0813 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL 0x0414 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK 0x0814 +#define TT_MS_LANGID_POLISH_POLAND 0x0415 +#define TT_MS_LANGID_PORTUGUESE_BRAZIL 0x0416 +#define TT_MS_LANGID_PORTUGUESE_PORTUGAL 0x0816 +#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND 0x0417 +#define TT_MS_LANGID_ROMANIAN_ROMANIA 0x0418 +#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 +#define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 +#define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 +#define TT_MS_LANGID_CROATIAN_CROATIA 0x041A +#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081A +#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0C1A + +#if 0 /* this used to be this value, but it looks like we were wrong */ +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101A +#else /* current sources say */ +#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101A +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141A + /* and XPsp2 Platform SDK added (2004-07-26) */ + /* Names are shortened to be significant within 40 chars. */ +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181A +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x181A +#endif + +#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041B +#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041C +#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041D +#define TT_MS_LANGID_SWEDISH_FINLAND 0x081D +#define TT_MS_LANGID_THAI_THAILAND 0x041E +#define TT_MS_LANGID_TURKISH_TURKEY 0x041F +#define TT_MS_LANGID_URDU_PAKISTAN 0x0420 +#define TT_MS_LANGID_URDU_INDIA 0x0820 +#define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 +#define TT_MS_LANGID_UKRAINIAN_UKRAINE 0x0422 +#define TT_MS_LANGID_BELARUSIAN_BELARUS 0x0423 +#define TT_MS_LANGID_SLOVENE_SLOVENIA 0x0424 +#define TT_MS_LANGID_ESTONIAN_ESTONIA 0x0425 +#define TT_MS_LANGID_LATVIAN_LATVIA 0x0426 +#define TT_MS_LANGID_LITHUANIAN_LITHUANIA 0x0427 +#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 +#define TT_MS_LANGID_TAJIK_TAJIKISTAN 0x0428 +#define TT_MS_LANGID_FARSI_IRAN 0x0429 +#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042A +#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042B +#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042C +#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082C +#define TT_MS_LANGID_BASQUE_SPAIN 0x042D +#define TT_MS_LANGID_SORBIAN_GERMANY 0x042E +#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042F +#define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 +#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 +#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA 0x0432 +#define TT_MS_LANGID_VENDA_SOUTH_AFRICA 0x0433 +#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA 0x0434 +#define TT_MS_LANGID_ZULU_SOUTH_AFRICA 0x0435 +#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA 0x0436 +#define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 +#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 +#define TT_MS_LANGID_HINDI_INDIA 0x0439 +#define TT_MS_LANGID_MALTESE_MALTA 0x043A + /* Added by XPsp2 Platform SDK (2004-07-26) */ +#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043B +#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083B +#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3B +#define TT_MS_LANGID_SAMI_LULE_NORWAY 0x103B +#define TT_MS_LANGID_SAMI_LULE_SWEDEN 0x143B +#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY 0x183B +#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3B +#define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203B +#define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243B + /* ... and we also keep our old identifier... */ +#define TT_MS_LANGID_SAAMI_LAPONIA 0x043B + +#if 0 /* this seems to be a previous inversion */ +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C +#else +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C +#endif + +#define TT_MS_LANGID_YIDDISH_GERMANY 0x043D +#define TT_MS_LANGID_MALAY_MALAYSIA 0x043E +#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083E +#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043F +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ + TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN + +#define TT_MS_LANGID_SWAHILI_KENYA 0x0441 +#define TT_MS_LANGID_TURKMEN_TURKMENISTAN 0x0442 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN 0x0443 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC 0x0843 +#define TT_MS_LANGID_TATAR_TATARSTAN 0x0444 +#define TT_MS_LANGID_BENGALI_INDIA 0x0445 +#define TT_MS_LANGID_BENGALI_BANGLADESH 0x0845 +#define TT_MS_LANGID_PUNJABI_INDIA 0x0446 +#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN 0x0846 +#define TT_MS_LANGID_GUJARATI_INDIA 0x0447 +#define TT_MS_LANGID_ORIYA_INDIA 0x0448 +#define TT_MS_LANGID_TAMIL_INDIA 0x0449 +#define TT_MS_LANGID_TELUGU_INDIA 0x044A +#define TT_MS_LANGID_KANNADA_INDIA 0x044B +#define TT_MS_LANGID_MALAYALAM_INDIA 0x044C +#define TT_MS_LANGID_ASSAMESE_INDIA 0x044D +#define TT_MS_LANGID_MARATHI_INDIA 0x044E +#define TT_MS_LANGID_SANSKRIT_INDIA 0x044F +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450 +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN 0x0850 +#define TT_MS_LANGID_TIBETAN_CHINA 0x0451 + /* Don't use the next constant! It has */ + /* (1) the wrong spelling (Dzonghka) */ + /* (2) Microsoft doesn't officially define it -- */ + /* at least it is not in the List of Local */ + /* ID Values. */ + /* (3) Dzongkha is not the same language as */ + /* Tibetan, so merging it is wrong anyway. */ + /* */ + /* TT_MS_LANGID_TIBETAN_BHUTAN is correct, BTW. */ +#define TT_MS_LANGID_DZONGHKA_BHUTAN 0x0851 + +#if 0 + /* the following used to be defined */ +#define TT_MS_LANGID_TIBETAN_BHUTAN 0x0451 + /* ... but it was changed; */ +#else + /* So we will continue to #define it, but with the correct value */ +#define TT_MS_LANGID_TIBETAN_BHUTAN TT_MS_LANGID_DZONGHKA_BHUTAN +#endif + +#define TT_MS_LANGID_WELSH_WALES 0x0452 +#define TT_MS_LANGID_KHMER_CAMBODIA 0x0453 +#define TT_MS_LANGID_LAO_LAOS 0x0454 +#define TT_MS_LANGID_BURMESE_MYANMAR 0x0455 +#define TT_MS_LANGID_GALICIAN_SPAIN 0x0456 +#define TT_MS_LANGID_KONKANI_INDIA 0x0457 +#define TT_MS_LANGID_MANIPURI_INDIA /* Bengali */ 0x0458 +#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */ 0x0459 +#define TT_MS_LANGID_SINDHI_PAKISTAN 0x0859 + /* Missing a LCID for Sindhi in Devanagari script */ +#define TT_MS_LANGID_SYRIAC_SYRIA 0x045A +#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045B +#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045C +#define TT_MS_LANGID_INUKTITUT_CANADA 0x045D +#define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045E +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045F +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085F + /* Missing a LCID for Tifinagh script */ +#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */ 0x0460 + /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */ + /* script is yet unclear... might be Arabic, Nagari or Sharada */ +#define TT_MS_LANGID_KASHMIRI_SASIA 0x0860 + /* ... and aliased (by MS) for compatibility reasons. */ +#define TT_MS_LANGID_KASHMIRI_INDIA TT_MS_LANGID_KASHMIRI_SASIA +#define TT_MS_LANGID_NEPALI_NEPAL 0x0461 +#define TT_MS_LANGID_NEPALI_INDIA 0x0861 +#define TT_MS_LANGID_FRISIAN_NETHERLANDS 0x0462 +#define TT_MS_LANGID_PASHTO_AFGHANISTAN 0x0463 +#define TT_MS_LANGID_FILIPINO_PHILIPPINES 0x0464 +#define TT_MS_LANGID_DHIVEHI_MALDIVES 0x0465 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_DIVEHI_MALDIVES TT_MS_LANGID_DHIVEHI_MALDIVES +#define TT_MS_LANGID_EDO_NIGERIA 0x0466 +#define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 +#define TT_MS_LANGID_HAUSA_NIGERIA 0x0468 +#define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 +#define TT_MS_LANGID_YORUBA_NIGERIA 0x046A +#define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046B +#define TT_MS_LANGID_QUECHUA_ECUADOR 0x086B +#define TT_MS_LANGID_QUECHUA_PERU 0x0C6B +#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA 0x046C + /* Also spelled by XPsp2 Platform SDK (2004-07-26) */ +#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \ + TT_MS_LANGID_SEPEDI_SOUTH_AFRICA + /* language codes 0x046D, 0x046E and 0x046F are (still) unknown. */ +#define TT_MS_LANGID_IGBO_NIGERIA 0x0470 +#define TT_MS_LANGID_KANURI_NIGERIA 0x0471 +#define TT_MS_LANGID_OROMO_ETHIOPIA 0x0472 +#define TT_MS_LANGID_TIGRIGNA_ETHIOPIA 0x0473 +#define TT_MS_LANGID_TIGRIGNA_ERYTHREA 0x0873 + /* also spelled in the `Passport SDK' list as: */ +#define TT_MS_LANGID_TIGRIGNA_ERYTREA TT_MS_LANGID_TIGRIGNA_ERYTHREA +#define TT_MS_LANGID_GUARANI_PARAGUAY 0x0474 +#define TT_MS_LANGID_HAWAIIAN_UNITED_STATES 0x0475 +#define TT_MS_LANGID_LATIN 0x0476 +#define TT_MS_LANGID_SOMALI_SOMALIA 0x0477 + /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */ + /* not written (but OTOH the peculiar writing system is worth */ + /* studying). */ +#define TT_MS_LANGID_YI_CHINA 0x0478 +#define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES 0x0479 + /* language codes from 0x047A to 0x047F are (still) unknown. */ +#define TT_MS_LANGID_UIGHUR_CHINA 0x0480 +#define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0481 + +#if 0 /* not deemed useful for fonts */ +#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE 0x04FF +#endif + + + /*************************************************************************/ + /* */ + /* Possible values of the `name' identifier field in the name records of */ + /* the TTF `name' table. These values are platform independent. */ + /* */ +#define TT_NAME_ID_COPYRIGHT 0 +#define TT_NAME_ID_FONT_FAMILY 1 +#define TT_NAME_ID_FONT_SUBFAMILY 2 +#define TT_NAME_ID_UNIQUE_ID 3 +#define TT_NAME_ID_FULL_NAME 4 +#define TT_NAME_ID_VERSION_STRING 5 +#define TT_NAME_ID_PS_NAME 6 +#define TT_NAME_ID_TRADEMARK 7 + + /* the following values are from the OpenType spec */ +#define TT_NAME_ID_MANUFACTURER 8 +#define TT_NAME_ID_DESIGNER 9 +#define TT_NAME_ID_DESCRIPTION 10 +#define TT_NAME_ID_VENDOR_URL 11 +#define TT_NAME_ID_DESIGNER_URL 12 +#define TT_NAME_ID_LICENSE 13 +#define TT_NAME_ID_LICENSE_URL 14 + /* number 15 is reserved */ +#define TT_NAME_ID_PREFERRED_FAMILY 16 +#define TT_NAME_ID_PREFERRED_SUBFAMILY 17 +#define TT_NAME_ID_MAC_FULL_NAME 18 + + /* The following code is new as of 2000-01-21 */ +#define TT_NAME_ID_SAMPLE_TEXT 19 + + /* This is new in OpenType 1.3 */ +#define TT_NAME_ID_CID_FINDFONT_NAME 20 + + /* This is new in OpenType 1.5 */ +#define TT_NAME_ID_WWS_FAMILY 21 +#define TT_NAME_ID_WWS_SUBFAMILY 22 + + + /*************************************************************************/ + /* */ + /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ + /* */ + /* Updated 08-Nov-2008. */ + /* */ + + /* Bit 0 Basic Latin */ +#define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ + /* Bit 1 C1 Controls and Latin-1 Supplement */ +#define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) /* U+0080-U+00FF */ + /* Bit 2 Latin Extended-A */ +#define TT_UCR_LATIN_EXTENDED_A (1L << 2) /* U+0100-U+017F */ + /* Bit 3 Latin Extended-B */ +#define TT_UCR_LATIN_EXTENDED_B (1L << 3) /* U+0180-U+024F */ + /* Bit 4 IPA Extensions */ + /* Phonetic Extensions */ + /* Phonetic Extensions Supplement */ +#define TT_UCR_IPA_EXTENSIONS (1L << 4) /* U+0250-U+02AF */ + /* U+1D00-U+1D7F */ + /* U+1D80-U+1DBF */ + /* Bit 5 Spacing Modifier Letters */ + /* Modifier Tone Letters */ +#define TT_UCR_SPACING_MODIFIER (1L << 5) /* U+02B0-U+02FF */ + /* U+A700-U+A71F */ + /* Bit 6 Combining Diacritical Marks */ + /* Combining Diacritical Marks Supplement */ +#define TT_UCR_COMBINING_DIACRITICS (1L << 6) /* U+0300-U+036F */ + /* U+1DC0-U+1DFF */ + /* Bit 7 Greek and Coptic */ +#define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ + /* Bit 8 Coptic */ +#define TT_UCR_COPTIC (1L << 8) /* U+2C80-U+2CFF */ + /* Bit 9 Cyrillic */ + /* Cyrillic Supplement */ + /* Cyrillic Extended-A */ + /* Cyrillic Extended-B */ +#define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ + /* U+0500-U+052F */ + /* U+2DE0-U+2DFF */ + /* U+A640-U+A69F */ + /* Bit 10 Armenian */ +#define TT_UCR_ARMENIAN (1L << 10) /* U+0530-U+058F */ + /* Bit 11 Hebrew */ +#define TT_UCR_HEBREW (1L << 11) /* U+0590-U+05FF */ + /* Bit 12 Vai */ +#define TT_UCR_VAI (1L << 12) /* U+A500-U+A63F */ + /* Bit 13 Arabic */ + /* Arabic Supplement */ +#define TT_UCR_ARABIC (1L << 13) /* U+0600-U+06FF */ + /* U+0750-U+077F */ + /* Bit 14 NKo */ +#define TT_UCR_NKO (1L << 14) /* U+07C0-U+07FF */ + /* Bit 15 Devanagari */ +#define TT_UCR_DEVANAGARI (1L << 15) /* U+0900-U+097F */ + /* Bit 16 Bengali */ +#define TT_UCR_BENGALI (1L << 16) /* U+0980-U+09FF */ + /* Bit 17 Gurmukhi */ +#define TT_UCR_GURMUKHI (1L << 17) /* U+0A00-U+0A7F */ + /* Bit 18 Gujarati */ +#define TT_UCR_GUJARATI (1L << 18) /* U+0A80-U+0AFF */ + /* Bit 19 Oriya */ +#define TT_UCR_ORIYA (1L << 19) /* U+0B00-U+0B7F */ + /* Bit 20 Tamil */ +#define TT_UCR_TAMIL (1L << 20) /* U+0B80-U+0BFF */ + /* Bit 21 Telugu */ +#define TT_UCR_TELUGU (1L << 21) /* U+0C00-U+0C7F */ + /* Bit 22 Kannada */ +#define TT_UCR_KANNADA (1L << 22) /* U+0C80-U+0CFF */ + /* Bit 23 Malayalam */ +#define TT_UCR_MALAYALAM (1L << 23) /* U+0D00-U+0D7F */ + /* Bit 24 Thai */ +#define TT_UCR_THAI (1L << 24) /* U+0E00-U+0E7F */ + /* Bit 25 Lao */ +#define TT_UCR_LAO (1L << 25) /* U+0E80-U+0EFF */ + /* Bit 26 Georgian */ + /* Georgian Supplement */ +#define TT_UCR_GEORGIAN (1L << 26) /* U+10A0-U+10FF */ + /* U+2D00-U+2D2F */ + /* Bit 27 Balinese */ +#define TT_UCR_BALINESE (1L << 27) /* U+1B00-U+1B7F */ + /* Bit 28 Hangul Jamo */ +#define TT_UCR_HANGUL_JAMO (1L << 28) /* U+1100-U+11FF */ + /* Bit 29 Latin Extended Additional */ + /* Latin Extended-C */ + /* Latin Extended-D */ +#define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) /* U+1E00-U+1EFF */ + /* U+2C60-U+2C7F */ + /* U+A720-U+A7FF */ + /* Bit 30 Greek Extended */ +#define TT_UCR_GREEK_EXTENDED (1L << 30) /* U+1F00-U+1FFF */ + /* Bit 31 General Punctuation */ + /* Supplemental Punctuation */ +#define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ + /* U+2E00-U+2E7F */ + /* Bit 32 Superscripts And Subscripts */ +#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ + /* Bit 33 Currency Symbols */ +#define TT_UCR_CURRENCY_SYMBOLS (1L << 1) /* U+20A0-U+20CF */ + /* Bit 34 Combining Diacritical Marks For Symbols */ +#define TT_UCR_COMBINING_DIACRITICS_SYMB (1L << 2) /* U+20D0-U+20FF */ + /* Bit 35 Letterlike Symbols */ +#define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ + /* Bit 36 Number Forms */ +#define TT_UCR_NUMBER_FORMS (1L << 4) /* U+2150-U+218F */ + /* Bit 37 Arrows */ + /* Supplemental Arrows-A */ + /* Supplemental Arrows-B */ + /* Miscellaneous Symbols and Arrows */ +#define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ + /* U+27F0-U+27FF */ + /* U+2900-U+297F */ + /* U+2B00-U+2BFF */ + /* Bit 38 Mathematical Operators */ + /* Supplemental Mathematical Operators */ + /* Miscellaneous Mathematical Symbols-A */ + /* Miscellaneous Mathematical Symbols-B */ +#define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ + /* U+2A00-U+2AFF */ + /* U+27C0-U+27EF */ + /* U+2980-U+29FF */ + /* Bit 39 Miscellaneous Technical */ +#define TT_UCR_MISCELLANEOUS_TECHNICAL (1L << 7) /* U+2300-U+23FF */ + /* Bit 40 Control Pictures */ +#define TT_UCR_CONTROL_PICTURES (1L << 8) /* U+2400-U+243F */ + /* Bit 41 Optical Character Recognition */ +#define TT_UCR_OCR (1L << 9) /* U+2440-U+245F */ + /* Bit 42 Enclosed Alphanumerics */ +#define TT_UCR_ENCLOSED_ALPHANUMERICS (1L << 10) /* U+2460-U+24FF */ + /* Bit 43 Box Drawing */ +#define TT_UCR_BOX_DRAWING (1L << 11) /* U+2500-U+257F */ + /* Bit 44 Block Elements */ +#define TT_UCR_BLOCK_ELEMENTS (1L << 12) /* U+2580-U+259F */ + /* Bit 45 Geometric Shapes */ +#define TT_UCR_GEOMETRIC_SHAPES (1L << 13) /* U+25A0-U+25FF */ + /* Bit 46 Miscellaneous Symbols */ +#define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) /* U+2600-U+26FF */ + /* Bit 47 Dingbats */ +#define TT_UCR_DINGBATS (1L << 15) /* U+2700-U+27BF */ + /* Bit 48 CJK Symbols and Punctuation */ +#define TT_UCR_CJK_SYMBOLS (1L << 16) /* U+3000-U+303F */ + /* Bit 49 Hiragana */ +#define TT_UCR_HIRAGANA (1L << 17) /* U+3040-U+309F */ + /* Bit 50 Katakana */ + /* Katakana Phonetic Extensions */ +#define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ + /* U+31F0-U+31FF */ + /* Bit 51 Bopomofo */ + /* Bopomofo Extended */ +#define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ + /* U+31A0-U+31BF */ + /* Bit 52 Hangul Compatibility Jamo */ +#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ + /* Bit 53 Phags-Pa */ +#define TT_UCR_CJK_MISC (1L << 21) /* U+A840-U+A87F */ +#define TT_UCR_KANBUN TT_UCR_CJK_MISC /* deprecated */ +#define TT_UCR_PHAGSPA + /* Bit 54 Enclosed CJK Letters and Months */ +#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) /* U+3200-U+32FF */ + /* Bit 55 CJK Compatibility */ +#define TT_UCR_CJK_COMPATIBILITY (1L << 23) /* U+3300-U+33FF */ + /* Bit 56 Hangul Syllables */ +#define TT_UCR_HANGUL (1L << 24) /* U+AC00-U+D7A3 */ + /* Bit 57 High Surrogates */ + /* High Private Use Surrogates */ + /* Low Surrogates */ + /* */ + /* According to OpenType specs v.1.3+, */ + /* setting bit 57 implies that there is */ + /* at least one codepoint beyond the */ + /* Basic Multilingual Plane that is */ + /* supported by this font. So it really */ + /* means >= U+10000 */ +#define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DB7F */ + /* U+DB80-U+DBFF */ + /* U+DC00-U+DFFF */ +#define TT_UCR_NON_PLANE_0 TT_UCR_SURROGATES + /* Bit 58 Phoenician */ +#define TT_UCR_PHOENICIAN (1L << 26) /*U+10900-U+1091F*/ + /* Bit 59 CJK Unified Ideographs */ + /* CJK Radicals Supplement */ + /* Kangxi Radicals */ + /* Ideographic Description Characters */ + /* CJK Unified Ideographs Extension A */ + /* CJK Unified Ideographs Extension B */ + /* Kanbun */ +#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ + /* U+2E80-U+2EFF */ + /* U+2F00-U+2FDF */ + /* U+2FF0-U+2FFF */ + /* U+3400-U+4DB5 */ + /*U+20000-U+2A6DF*/ + /* U+3190-U+319F */ + /* Bit 60 Private Use */ +#define TT_UCR_PRIVATE_USE (1L << 28) /* U+E000-U+F8FF */ + /* Bit 61 CJK Strokes */ + /* CJK Compatibility Ideographs */ + /* CJK Compatibility Ideographs Supplement */ +#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+31C0-U+31EF */ + /* U+F900-U+FAFF */ + /*U+2F800-U+2FA1F*/ + /* Bit 62 Alphabetic Presentation Forms */ +#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ + /* Bit 63 Arabic Presentation Forms-A */ +#define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) /* U+FB50-U+FDFF */ + /* Bit 64 Combining Half Marks */ +#define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ + /* Bit 65 Vertical forms */ + /* CJK Compatibility Forms */ +#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE10-U+FE1F */ + /* U+FE30-U+FE4F */ + /* Bit 66 Small Form Variants */ +#define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ + /* Bit 67 Arabic Presentation Forms-B */ +#define TT_UCR_ARABIC_PRESENTATIONS_B (1L << 3) /* U+FE70-U+FEFE */ + /* Bit 68 Halfwidth and Fullwidth Forms */ +#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1L << 4) /* U+FF00-U+FFEF */ + /* Bit 69 Specials */ +#define TT_UCR_SPECIALS (1L << 5) /* U+FFF0-U+FFFD */ + /* Bit 70 Tibetan */ +#define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FFF */ + /* Bit 71 Syriac */ +#define TT_UCR_SYRIAC (1L << 7) /* U+0700-U+074F */ + /* Bit 72 Thaana */ +#define TT_UCR_THAANA (1L << 8) /* U+0780-U+07BF */ + /* Bit 73 Sinhala */ +#define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ + /* Bit 74 Myanmar */ +#define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ + /* Bit 75 Ethiopic */ + /* Ethiopic Supplement */ + /* Ethiopic Extended */ +#define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+137F */ + /* U+1380-U+139F */ + /* U+2D80-U+2DDF */ + /* Bit 76 Cherokee */ +#define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ + /* Bit 77 Unified Canadian Aboriginal Syllabics */ +#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS (1L << 13) /* U+1400-U+167F */ + /* Bit 78 Ogham */ +#define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ + /* Bit 79 Runic */ +#define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ + /* Bit 80 Khmer */ + /* Khmer Symbols */ +#define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ + /* U+19E0-U+19FF */ + /* Bit 81 Mongolian */ +#define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ + /* Bit 82 Braille Patterns */ +#define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ + /* Bit 83 Yi Syllables */ + /* Yi Radicals */ +#define TT_UCR_YI (1L << 19) /* U+A000-U+A48F */ + /* U+A490-U+A4CF */ + /* Bit 84 Tagalog */ + /* Hanunoo */ + /* Buhid */ + /* Tagbanwa */ +#define TT_UCR_PHILIPPINE (1L << 20) /* U+1700-U+171F */ + /* U+1720-U+173F */ + /* U+1740-U+175F */ + /* U+1760-U+177F */ + /* Bit 85 Old Italic */ +#define TT_UCR_OLD_ITALIC (1L << 21) /*U+10300-U+1032F*/ + /* Bit 86 Gothic */ +#define TT_UCR_GOTHIC (1L << 22) /*U+10330-U+1034F*/ + /* Bit 87 Deseret */ +#define TT_UCR_DESERET (1L << 23) /*U+10400-U+1044F*/ + /* Bit 88 Byzantine Musical Symbols */ + /* Musical Symbols */ + /* Ancient Greek Musical Notation */ +#define TT_UCR_MUSICAL_SYMBOLS (1L << 24) /*U+1D000-U+1D0FF*/ + /*U+1D100-U+1D1FF*/ + /*U+1D200-U+1D24F*/ + /* Bit 89 Mathematical Alphanumeric Symbols */ +#define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS (1L << 25) /*U+1D400-U+1D7FF*/ + /* Bit 90 Private Use (plane 15) */ + /* Private Use (plane 16) */ +#define TT_UCR_PRIVATE_USE_SUPPLEMENTARY (1L << 26) /*U+F0000-U+FFFFD*/ + /*U+100000-U+10FFFD*/ + /* Bit 91 Variation Selectors */ + /* Variation Selectors Supplement */ +#define TT_UCR_VARIATION_SELECTORS (1L << 27) /* U+FE00-U+FE0F */ + /*U+E0100-U+E01EF*/ + /* Bit 92 Tags */ +#define TT_UCR_TAGS (1L << 28) /*U+E0000-U+E007F*/ + /* Bit 93 Limbu */ +#define TT_UCR_LIMBU (1L << 29) /* U+1900-U+194F */ + /* Bit 94 Tai Le */ +#define TT_UCR_TAI_LE (1L << 30) /* U+1950-U+197F */ + /* Bit 95 New Tai Lue */ +#define TT_UCR_NEW_TAI_LUE (1L << 31) /* U+1980-U+19DF */ + /* Bit 96 Buginese */ +#define TT_UCR_BUGINESE (1L << 0) /* U+1A00-U+1A1F */ + /* Bit 97 Glagolitic */ +#define TT_UCR_GLAGOLITIC (1L << 1) /* U+2C00-U+2C5F */ + /* Bit 98 Tifinagh */ +#define TT_UCR_TIFINAGH (1L << 2) /* U+2D30-U+2D7F */ + /* Bit 99 Yijing Hexagram Symbols */ +#define TT_UCR_YIJING (1L << 3) /* U+4DC0-U+4DFF */ + /* Bit 100 Syloti Nagri */ +#define TT_UCR_SYLOTI_NAGRI (1L << 4) /* U+A800-U+A82F */ + /* Bit 101 Linear B Syllabary */ + /* Linear B Ideograms */ + /* Aegean Numbers */ +#define TT_UCR_LINEAR_B (1L << 5) /*U+10000-U+1007F*/ + /*U+10080-U+100FF*/ + /*U+10100-U+1013F*/ + /* Bit 102 Ancient Greek Numbers */ +#define TT_UCR_ANCIENT_GREEK_NUMBERS (1L << 6) /*U+10140-U+1018F*/ + /* Bit 103 Ugaritic */ +#define TT_UCR_UGARITIC (1L << 7) /*U+10380-U+1039F*/ + /* Bit 104 Old Persian */ +#define TT_UCR_OLD_PERSIAN (1L << 8) /*U+103A0-U+103DF*/ + /* Bit 105 Shavian */ +#define TT_UCR_SHAVIAN (1L << 9) /*U+10450-U+1047F*/ + /* Bit 106 Osmanya */ +#define TT_UCR_OSMANYA (1L << 10) /*U+10480-U+104AF*/ + /* Bit 107 Cypriot Syllabary */ +#define TT_UCR_CYPRIOT_SYLLABARY (1L << 11) /*U+10800-U+1083F*/ + /* Bit 108 Kharoshthi */ +#define TT_UCR_KHAROSHTHI (1L << 12) /*U+10A00-U+10A5F*/ + /* Bit 109 Tai Xuan Jing Symbols */ +#define TT_UCR_TAI_XUAN_JING (1L << 13) /*U+1D300-U+1D35F*/ + /* Bit 110 Cuneiform */ + /* Cuneiform Numbers and Punctuation */ +#define TT_UCR_CUNEIFORM (1L << 14) /*U+12000-U+123FF*/ + /*U+12400-U+1247F*/ + /* Bit 111 Counting Rod Numerals */ +#define TT_UCR_COUNTING_ROD_NUMERALS (1L << 15) /*U+1D360-U+1D37F*/ + /* Bit 112 Sundanese */ +#define TT_UCR_SUNDANESE (1L << 16) /* U+1B80-U+1BBF */ + /* Bit 113 Lepcha */ +#define TT_UCR_LEPCHA (1L << 17) /* U+1C00-U+1C4F */ + /* Bit 114 Ol Chiki */ +#define TT_UCR_OL_CHIKI (1L << 18) /* U+1C50-U+1C7F */ + /* Bit 115 Saurashtra */ +#define TT_UCR_SAURASHTRA (1L << 19) /* U+A880-U+A8DF */ + /* Bit 116 Kayah Li */ +#define TT_UCR_KAYAH_LI (1L << 20) /* U+A900-U+A92F */ + /* Bit 117 Rejang */ +#define TT_UCR_REJANG (1L << 21) /* U+A930-U+A95F */ + /* Bit 118 Cham */ +#define TT_UCR_CHAM (1L << 22) /* U+AA00-U+AA5F */ + /* Bit 119 Ancient Symbols */ +#define TT_UCR_ANCIENT_SYMBOLS (1L << 23) /*U+10190-U+101CF*/ + /* Bit 120 Phaistos Disc */ +#define TT_UCR_PHAISTOS_DISC (1L << 24) /*U+101D0-U+101FF*/ + /* Bit 121 Carian */ + /* Lycian */ + /* Lydian */ +#define TT_UCR_OLD_ANATOLIAN (1L << 25) /*U+102A0-U+102DF*/ + /*U+10280-U+1029F*/ + /*U+10920-U+1093F*/ + /* Bit 122 Domino Tiles */ + /* Mahjong Tiles */ +#define TT_UCR_GAME_TILES (1L << 26) /*U+1F030-U+1F09F*/ + /*U+1F000-U+1F02F*/ + /* Bit 123-127 Reserved for process-internal usage */ + + + /*************************************************************************/ + /* */ + /* Some compilers have a very limited length of identifiers. */ + /* */ +#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ ) +#define HAVE_LIMIT_ON_IDENTS +#endif + + +#ifndef HAVE_LIMIT_ON_IDENTS + + + /*************************************************************************/ + /* */ + /* Here some alias #defines in order to be clearer. */ + /* */ + /* These are not always #defined to stay within the 31~character limit, */ + /* which some compilers have. */ + /* */ + /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern */ + /* Borland compilers (read: from BC++ 3.1 on) can increase this limit. */ + /* If you get a warning with such a compiler, use the -i40 switch. */ + /* */ +#define TT_UCR_ARABIC_PRESENTATION_FORMS_A \ + TT_UCR_ARABIC_PRESENTATIONS_A +#define TT_UCR_ARABIC_PRESENTATION_FORMS_B \ + TT_UCR_ARABIC_PRESENTATIONS_B + +#define TT_UCR_COMBINING_DIACRITICAL_MARKS \ + TT_UCR_COMBINING_DIACRITICS +#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \ + TT_UCR_COMBINING_DIACRITICS_SYMB + + +#endif /* !HAVE_LIMIT_ON_IDENTS */ + + +FT_END_HEADER + +#endif /* TTNAMEID_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/tttables.h b/builddir/freetype-2.7.0/include/freetype/tttables.h new file mode 100644 index 0000000..1c075dc --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/tttables.h @@ -0,0 +1,829 @@ +/***************************************************************************/ +/* */ +/* tttables.h */ +/* */ +/* Basic SFNT/TrueType tables definitions and interface */ +/* (specification only). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef TTTABLES_H_ +#define TTTABLES_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + /* <Title> */ + /* TrueType Tables */ + /* */ + /* <Abstract> */ + /* TrueType specific table types and functions. */ + /* */ + /* <Description> */ + /* This section contains the definition of TrueType-specific tables */ + /* as well as some routines used to access and process them. */ + /* */ + /* <Order> */ + /* TT_Header */ + /* TT_HoriHeader */ + /* TT_VertHeader */ + /* TT_OS2 */ + /* TT_Postscript */ + /* TT_PCLT */ + /* TT_MaxProfile */ + /* */ + /* FT_Sfnt_Tag */ + /* FT_Get_Sfnt_Table */ + /* FT_Load_Sfnt_Table */ + /* FT_Sfnt_Table_Info */ + /* */ + /* FT_Get_CMap_Language_ID */ + /* FT_Get_CMap_Format */ + /* */ + /* FT_PARAM_TAG_UNPATENTED_HINTING */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Header */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType font header table. All */ + /* fields follow the TrueType specification. */ + /* */ + typedef struct TT_Header_ + { + FT_Fixed Table_Version; + FT_Fixed Font_Revision; + + FT_Long CheckSum_Adjust; + FT_Long Magic_Number; + + FT_UShort Flags; + FT_UShort Units_Per_EM; + + FT_Long Created [2]; + FT_Long Modified[2]; + + FT_Short xMin; + FT_Short yMin; + FT_Short xMax; + FT_Short yMax; + + FT_UShort Mac_Style; + FT_UShort Lowest_Rec_PPEM; + + FT_Short Font_Direction; + FT_Short Index_To_Loc_Format; + FT_Short Glyph_Data_Format; + + } TT_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HoriHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType horizontal header, the `hhea' */ + /* table, as well as the corresponding horizontal metrics table, */ + /* i.e., the `hmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of all */ + /* glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoAscender' field */ + /* of the OS/2 table instead if you want */ + /* the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the distance */ + /* from the baseline to the bottom-most of */ + /* all glyph points found in the font. It */ + /* is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Width_Max :: This field is the maximum of all advance */ + /* widths found in the font. It can be */ + /* used to compute the maximum width of an */ + /* arbitrary string of text. */ + /* */ + /* min_Left_Side_Bearing :: The minimum left side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Right_Side_Bearing :: The minimum right side bearing of all */ + /* glyphs within the font. */ + /* */ + /* xMax_Extent :: The maximum horizontal extent (i.e., the */ + /* `width' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* Reserved :: 8~reserved bytes. */ + /* */ + /* metric_Data_Format :: Always~0. */ + /* */ + /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ + /* table -- this value can be smaller than */ + /* the total number of glyphs in the font. */ + /* */ + /* long_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields, */ + /* which are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_HoriHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Width_Max; /* advance width maximum */ + + FT_Short min_Left_Side_Bearing; /* minimum left-sb */ + FT_Short min_Right_Side_Bearing; /* minimum right-sb */ + FT_Short xMax_Extent; /* xmax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_UShort number_Of_HMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they are used to connect the metrics header to the relevant */ + /* `HMTX' table. */ + + void* long_metrics; + void* short_metrics; + + } TT_HoriHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_VertHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType vertical header, the `vhea' */ + /* table, as well as the corresponding vertical metrics table, i.e., */ + /* the `vmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of */ + /* all glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoAscender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the */ + /* distance from the baseline to the */ + /* bottom-most of all glyph points found */ + /* in the font. It is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Height_Max :: This field is the maximum of all */ + /* advance heights found in the font. It */ + /* can be used to compute the maximum */ + /* height of an arbitrary string of text. */ + /* */ + /* min_Top_Side_Bearing :: The minimum top side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */ + /* glyphs within the font. */ + /* */ + /* yMax_Extent :: The maximum vertical extent (i.e., the */ + /* `height' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* caret_Offset :: The cursor's offset for slanted fonts. */ + /* This value is `reserved' in vmtx */ + /* version 1.0. */ + /* */ + /* Reserved :: 8~reserved bytes. */ + /* */ + /* metric_Data_Format :: Always~0. */ + /* */ + /* number_Of_HMetrics :: Number of VMetrics entries in the */ + /* `vmtx' table -- this value can be */ + /* smaller than the total number of glyphs */ + /* in the font. */ + /* */ + /* long_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields, */ + /* which are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_VertHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Height_Max; /* advance height maximum */ + + FT_Short min_Top_Side_Bearing; /* minimum left-sb or top-sb */ + FT_Short min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ + FT_Short yMax_Extent; /* xmax or ymax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_UShort number_Of_VMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they're used to connect the metrics header to the relevant */ + /* `HMTX' or `VMTX' table. */ + + void* long_metrics; + void* short_metrics; + + } TT_VertHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_OS2 */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType OS/2 table. All fields */ + /* comply to the OpenType specification. */ + /* */ + /* Note that we now support old Mac fonts that do not include an OS/2 */ + /* table. In this case, the `version' field is always set to 0xFFFF. */ + /* */ + typedef struct TT_OS2_ + { + FT_UShort version; /* 0x0001 - more or 0xFFFF */ + FT_Short xAvgCharWidth; + FT_UShort usWeightClass; + FT_UShort usWidthClass; + FT_UShort fsType; + FT_Short ySubscriptXSize; + FT_Short ySubscriptYSize; + FT_Short ySubscriptXOffset; + FT_Short ySubscriptYOffset; + FT_Short ySuperscriptXSize; + FT_Short ySuperscriptYSize; + FT_Short ySuperscriptXOffset; + FT_Short ySuperscriptYOffset; + FT_Short yStrikeoutSize; + FT_Short yStrikeoutPosition; + FT_Short sFamilyClass; + + FT_Byte panose[10]; + + FT_ULong ulUnicodeRange1; /* Bits 0-31 */ + FT_ULong ulUnicodeRange2; /* Bits 32-63 */ + FT_ULong ulUnicodeRange3; /* Bits 64-95 */ + FT_ULong ulUnicodeRange4; /* Bits 96-127 */ + + FT_Char achVendID[4]; + + FT_UShort fsSelection; + FT_UShort usFirstCharIndex; + FT_UShort usLastCharIndex; + FT_Short sTypoAscender; + FT_Short sTypoDescender; + FT_Short sTypoLineGap; + FT_UShort usWinAscent; + FT_UShort usWinDescent; + + /* only version 1 and higher: */ + + FT_ULong ulCodePageRange1; /* Bits 0-31 */ + FT_ULong ulCodePageRange2; /* Bits 32-63 */ + + /* only version 2 and higher: */ + + FT_Short sxHeight; + FT_Short sCapHeight; + FT_UShort usDefaultChar; + FT_UShort usBreakChar; + FT_UShort usMaxContext; + + /* only version 5 and higher: */ + + FT_UShort usLowerOpticalPointSize; /* in twips (1/20th points) */ + FT_UShort usUpperOpticalPointSize; /* in twips (1/20th points) */ + + } TT_OS2; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Postscript */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType PostScript table. All fields */ + /* comply to the TrueType specification. This structure does not */ + /* reference the PostScript glyph names, which can be nevertheless */ + /* accessed with the `ttpost' module. */ + /* */ + typedef struct TT_Postscript_ + { + FT_Fixed FormatType; + FT_Fixed italicAngle; + FT_Short underlinePosition; + FT_Short underlineThickness; + FT_ULong isFixedPitch; + FT_ULong minMemType42; + FT_ULong maxMemType42; + FT_ULong minMemType1; + FT_ULong maxMemType1; + + /* Glyph names follow in the file, but we don't */ + /* load them by default. See the ttpost.c file. */ + + } TT_Postscript; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_PCLT */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType PCLT table. All fields */ + /* comply to the TrueType specification. */ + /* */ + typedef struct TT_PCLT_ + { + FT_Fixed Version; + FT_ULong FontNumber; + FT_UShort Pitch; + FT_UShort xHeight; + FT_UShort Style; + FT_UShort TypeFamily; + FT_UShort CapHeight; + FT_UShort SymbolSet; + FT_Char TypeFace[16]; + FT_Char CharacterComplement[8]; + FT_Char FileName[6]; + FT_Char StrokeWeight; + FT_Char WidthType; + FT_Byte SerifStyle; + FT_Byte Reserved; + + } TT_PCLT; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_MaxProfile */ + /* */ + /* <Description> */ + /* The maximum profile is a table containing many max values, which */ + /* can be used to pre-allocate arrays. This ensures that no memory */ + /* allocation occurs during a glyph load. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* numGlyphs :: The number of glyphs in this TrueType */ + /* font. */ + /* */ + /* maxPoints :: The maximum number of points in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositePoints'. */ + /* */ + /* maxContours :: The maximum number of contours in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositeContours'. */ + /* */ + /* maxCompositePoints :: The maximum number of points in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxPoints'. */ + /* */ + /* maxCompositeContours :: The maximum number of contours in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxContours'. */ + /* */ + /* maxZones :: The maximum number of zones used for */ + /* glyph hinting. */ + /* */ + /* maxTwilightPoints :: The maximum number of points in the */ + /* twilight zone used for glyph hinting. */ + /* */ + /* maxStorage :: The maximum number of elements in the */ + /* storage area used for glyph hinting. */ + /* */ + /* maxFunctionDefs :: The maximum number of function */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxInstructionDefs :: The maximum number of instruction */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxStackElements :: The maximum number of stack elements used */ + /* during bytecode interpretation. */ + /* */ + /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */ + /* used for glyph hinting. */ + /* */ + /* maxComponentElements :: The maximum number of simple (i.e., non- */ + /* composite) glyphs in a composite glyph. */ + /* */ + /* maxComponentDepth :: The maximum nesting depth of composite */ + /* glyphs. */ + /* */ + /* <Note> */ + /* This structure is only used during font loading. */ + /* */ + typedef struct TT_MaxProfile_ + { + FT_Fixed version; + FT_UShort numGlyphs; + FT_UShort maxPoints; + FT_UShort maxContours; + FT_UShort maxCompositePoints; + FT_UShort maxCompositeContours; + FT_UShort maxZones; + FT_UShort maxTwilightPoints; + FT_UShort maxStorage; + FT_UShort maxFunctionDefs; + FT_UShort maxInstructionDefs; + FT_UShort maxStackElements; + FT_UShort maxSizeOfInstructions; + FT_UShort maxComponentElements; + FT_UShort maxComponentDepth; + + } TT_MaxProfile; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Sfnt_Tag */ + /* */ + /* <Description> */ + /* An enumeration used to specify the index of an SFNT table. */ + /* Used in the @FT_Get_Sfnt_Table API function. */ + /* */ + /* <Values> */ + /* FT_SFNT_HEAD :: To access the font's @TT_Header structure. */ + /* */ + /* FT_SFNT_MAXP :: To access the font's @TT_MaxProfile structure. */ + /* */ + /* FT_SFNT_OS2 :: To access the font's @TT_OS2 structure. */ + /* */ + /* FT_SFNT_HHEA :: To access the font's @TT_HoriHeader structure. */ + /* */ + /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader structure. */ + /* */ + /* FT_SFNT_POST :: To access the font's @TT_Postscript structure. */ + /* */ + /* FT_SFNT_PCLT :: To access the font's @TT_PCLT structure. */ + /* */ + typedef enum FT_Sfnt_Tag_ + { + FT_SFNT_HEAD, + FT_SFNT_MAXP, + FT_SFNT_OS2, + FT_SFNT_HHEA, + FT_SFNT_VHEA, + FT_SFNT_POST, + FT_SFNT_PCLT, + + FT_SFNT_MAX + + } FT_Sfnt_Tag; + + /* these constants are deprecated; use the corresponding `FT_Sfnt_Tag' */ + /* values instead */ +#define ft_sfnt_head FT_SFNT_HEAD +#define ft_sfnt_maxp FT_SFNT_MAXP +#define ft_sfnt_os2 FT_SFNT_OS2 +#define ft_sfnt_hhea FT_SFNT_HHEA +#define ft_sfnt_vhea FT_SFNT_VHEA +#define ft_sfnt_post FT_SFNT_POST +#define ft_sfnt_pclt FT_SFNT_PCLT + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Table */ + /* */ + /* <Description> */ + /* Return a pointer to a given SFNT table within a face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source. */ + /* */ + /* tag :: The index of the SFNT table. */ + /* */ + /* <Return> */ + /* A type-less pointer to the table. This will be~0 in case of */ + /* error, or if the corresponding table was not found *OR* loaded */ + /* from the file. */ + /* */ + /* Use a typecast according to `tag' to access the structure */ + /* elements. */ + /* */ + /* <Note> */ + /* The table is owned by the face object and disappears with it. */ + /* */ + /* This function is only useful to access SFNT tables that are loaded */ + /* by the sfnt, truetype, and opentype drivers. See @FT_Sfnt_Tag for */ + /* a list. */ + /* */ + /* Here an example how to access the `vhea' table: */ + /* */ + /* { */ + /* TT_VertHeader* vert_header; */ + /* */ + /* */ + /* vert_header = */ + /* (TT_VertHeader*)FT_Get_Sfnt_Table( face, FT_SFNT_VHEA ); */ + /* } */ + /* */ + FT_EXPORT( void* ) + FT_Get_Sfnt_Table( FT_Face face, + FT_Sfnt_Tag tag ); + + + /************************************************************************** + * + * @function: + * FT_Load_Sfnt_Table + * + * @description: + * Load any font table into client memory. + * + * @input: + * face :: + * A handle to the source face. + * + * tag :: + * The four-byte tag of the table to load. Use the value~0 if you want + * to access the whole font file. Otherwise, you can use one of the + * definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new + * one with @FT_MAKE_TAG. + * + * offset :: + * The starting offset in the table (or file if tag == 0). + * + * @output: + * buffer :: + * The target buffer address. The client must ensure that the memory + * array is big enough to hold the data. + * + * @inout: + * length :: + * If the `length' parameter is NULL, then try to load the whole table. + * Return an error code if it fails. + * + * Else, if `*length' is~0, exit immediately while returning the + * table's (or file) full size in it. + * + * Else the number of bytes to read from the table or file, from the + * starting offset. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If you need to determine the table's length you should first call this + * function with `*length' set to~0, as in the following example: + * + * { + * FT_ULong length = 0; + * + * + * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); + * if ( error ) { ... table does not exist ... } + * + * buffer = malloc( length ); + * if ( buffer == NULL ) { ... not enough memory ... } + * + * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); + * if ( error ) { ... could not load table ... } + * } + * + * Note that structures like @TT_Header or @TT_OS2 can't be used with + * this function; they are limited to @FT_Get_Sfnt_Table. Reason is that + * those structures depend on the processor architecture, with varying + * size (e.g. 32bit vs. 64bit) or order (big endian vs. little endian). + * + */ + FT_EXPORT( FT_Error ) + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + + /************************************************************************** + * + * @function: + * FT_Sfnt_Table_Info + * + * @description: + * Return information on an SFNT table. + * + * @input: + * face :: + * A handle to the source face. + * + * table_index :: + * The index of an SFNT table. The function returns + * FT_Err_Table_Missing for an invalid value. + * + * @inout: + * tag :: + * The name tag of the SFNT table. If the value is NULL, `table_index' + * is ignored, and `length' returns the number of SFNT tables in the + * font. + * + * @output: + * length :: + * The length of the SFNT table (or the number of SFNT tables, depending + * on `tag'). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * While parsing fonts, FreeType handles SFNT tables with length zero as + * missing. + * + */ + FT_EXPORT( FT_Error ) + FT_Sfnt_Table_Info( FT_Face face, + FT_UInt table_index, + FT_ULong *tag, + FT_ULong *length ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_CMap_Language_ID */ + /* */ + /* <Description> */ + /* Return TrueType/sfnt specific cmap language ID. Definitions of */ + /* language ID values are in `ttnameid.h'. */ + /* */ + /* <Input> */ + /* charmap :: */ + /* The target charmap. */ + /* */ + /* <Return> */ + /* The language ID of `charmap'. If `charmap' doesn't belong to a */ + /* TrueType/sfnt face, just return~0 as the default value. */ + /* */ + /* For a format~14 cmap (to access Unicode IVS), the return value is */ + /* 0xFFFFFFFF. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_CMap_Language_ID( FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_CMap_Format */ + /* */ + /* <Description> */ + /* Return TrueType/sfnt specific cmap format. */ + /* */ + /* <Input> */ + /* charmap :: */ + /* The target charmap. */ + /* */ + /* <Return> */ + /* The format of `charmap'. If `charmap' doesn't belong to a */ + /* TrueType/sfnt face, return -1. */ + /* */ + FT_EXPORT( FT_Long ) + FT_Get_CMap_Format( FT_CharMap charmap ); + + /* */ + + +FT_END_HEADER + +#endif /* TTTABLES_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/tttags.h b/builddir/freetype-2.7.0/include/freetype/tttags.h new file mode 100644 index 0000000..f3c9aa5 --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/tttags.h @@ -0,0 +1,111 @@ +/***************************************************************************/ +/* */ +/* tttags.h */ +/* */ +/* Tags for TrueType and OpenType tables (specification only). */ +/* */ +/* Copyright 1996-2016 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. */ +/* */ +/***************************************************************************/ + + +#ifndef TTAGS_H_ +#define TTAGS_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + +#define TTAG_avar FT_MAKE_TAG( 'a', 'v', 'a', 'r' ) +#define TTAG_BASE FT_MAKE_TAG( 'B', 'A', 'S', 'E' ) +#define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' ) +#define TTAG_BDF FT_MAKE_TAG( 'B', 'D', 'F', ' ' ) +#define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' ) +#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) +#define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' ) +#define TTAG_CBDT FT_MAKE_TAG( 'C', 'B', 'D', 'T' ) +#define TTAG_CBLC FT_MAKE_TAG( 'C', 'B', 'L', 'C' ) +#define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) +#define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) +#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) +#define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) +#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) +#define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) +#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' ) +#define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) +#define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) +#define TTAG_feat FT_MAKE_TAG( 'f', 'e', 'a', 't' ) +#define TTAG_FOND FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) +#define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) +#define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) +#define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) +#define TTAG_GDEF FT_MAKE_TAG( 'G', 'D', 'E', 'F' ) +#define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' ) +#define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' ) +#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) +#define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' ) +#define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) +#define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) +#define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) +#define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' ) +#define TTAG_JSTF FT_MAKE_TAG( 'J', 'S', 'T', 'F' ) +#define TTAG_just FT_MAKE_TAG( 'j', 'u', 's', 't' ) +#define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' ) +#define TTAG_lcar FT_MAKE_TAG( 'l', 'c', 'a', 'r' ) +#define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) +#define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) +#define TTAG_LWFN FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) +#define TTAG_MATH FT_MAKE_TAG( 'M', 'A', 'T', 'H' ) +#define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) +#define TTAG_META FT_MAKE_TAG( 'M', 'E', 'T', 'A' ) +#define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) +#define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) +#define TTAG_mort FT_MAKE_TAG( 'm', 'o', 'r', 't' ) +#define TTAG_morx FT_MAKE_TAG( 'm', 'o', 'r', 'x' ) +#define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) +#define TTAG_opbd FT_MAKE_TAG( 'o', 'p', 'b', 'd' ) +#define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) +#define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) +#define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) +#define TTAG_POST FT_MAKE_TAG( 'P', 'O', 'S', 'T' ) +#define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) +#define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) +#define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' ) +#define TTAG_sbix FT_MAKE_TAG( 's', 'b', 'i', 'x' ) +#define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' ) +#define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) +#define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) +#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) +#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) +#define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) +#define TTAG_TYP1 FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) +#define TTAG_typ1 FT_MAKE_TAG( 't', 'y', 'p', '1' ) +#define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) +#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) +#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) +#define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' ) + + +FT_END_HEADER + +#endif /* TTAGS_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/freetype/ttunpat.h b/builddir/freetype-2.7.0/include/freetype/ttunpat.h new file mode 100644 index 0000000..ca4676b --- /dev/null +++ b/builddir/freetype-2.7.0/include/freetype/ttunpat.h @@ -0,0 +1,63 @@ +/***************************************************************************/ +/* */ +/* ttunpat.h */ +/* */ +/* Definitions for the unpatented TrueType hinting system. */ +/* Obsolete, retained for backwards compatibility. */ +/* */ +/* Copyright 2003-2016 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by Graham Asher <graham.asher@btinternet.com> */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef TTUNPAT_H_ +#define TTUNPAT_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_UNPATENTED_HINTING + * + * @description: + * Deprecated. + * + * Previously: A constant used as the tag of an @FT_Parameter structure to + * indicate that unpatented methods only should be used by the TrueType + * bytecode interpreter for a typeface opened by @FT_Open_Face. + * + */ +#define FT_PARAM_TAG_UNPATENTED_HINTING FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) + + /* */ + + +FT_END_HEADER + + +#endif /* TTUNPAT_H_ */ + + +/* END */ diff --git a/builddir/freetype-2.7.0/include/ft2build.h b/builddir/freetype-2.7.0/include/ft2build.h new file mode 100644 index 0000000..c89cb46 --- /dev/null +++ b/builddir/freetype-2.7.0/include/ft2build.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* ft2build.h */ +/* */ +/* FreeType 2 build and setup macros. */ +/* */ +/* Copyright 1996-2016 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 is the `entry point' for FreeType header file inclusions. It is */ + /* the only header file which should be included directly; all other */ + /* FreeType header files should be accessed with macro names (after */ + /* including `ft2build.h'). */ + /* */ + /* A typical example is */ + /* */ + /* #include <ft2build.h> */ + /* #include FT_FREETYPE_H */ + /* */ + /*************************************************************************/ + + +#ifndef FT2BUILD_H_ +#define FT2BUILD_H_ + +#include <freetype/config/ftheader.h> + +#endif /* FT2BUILD_H_ */ + + +/* END */ diff --git a/builddir/irrlicht-1.8.1/bin/Irrlicht.dll b/builddir/irrlicht-1.8.1/bin/Irrlicht.dll new file mode 100644 index 0000000..c18a095 Binary files /dev/null and b/builddir/irrlicht-1.8.1/bin/Irrlicht.dll differ diff --git a/builddir/irrlicht-1.8.1/bin/Irrlicht.exp b/builddir/irrlicht-1.8.1/bin/Irrlicht.exp new file mode 100644 index 0000000..f5e7c8f Binary files /dev/null and b/builddir/irrlicht-1.8.1/bin/Irrlicht.exp differ diff --git a/builddir/irrlicht-1.8.1/bin/Irrlicht.lib b/builddir/irrlicht-1.8.1/bin/Irrlicht.lib new file mode 100644 index 0000000..b9b1240 Binary files /dev/null and b/builddir/irrlicht-1.8.1/bin/Irrlicht.lib differ diff --git a/builddir/irrlicht-1.8.1/include/CDynamicMeshBuffer.h b/builddir/irrlicht-1.8.1/include/CDynamicMeshBuffer.h new file mode 100644 index 0000000..016af9c --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/CDynamicMeshBuffer.h @@ -0,0 +1,116 @@ +// Copyright (C) 2008-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_DYNAMIC_MESHBUFFER_H_INCLUDED__ +#define __C_DYNAMIC_MESHBUFFER_H_INCLUDED__ + +#include "IDynamicMeshBuffer.h" + +#include "CVertexBuffer.h" +#include "CIndexBuffer.h" + +namespace irr +{ +namespace scene +{ + + class CDynamicMeshBuffer: public IDynamicMeshBuffer + { + public: + //! constructor + CDynamicMeshBuffer(video::E_VERTEX_TYPE vertexType, video::E_INDEX_TYPE indexType) + { + VertexBuffer=new CVertexBuffer(vertexType); + IndexBuffer=new CIndexBuffer(indexType); + } + + //! destructor + virtual ~CDynamicMeshBuffer() + { + if (VertexBuffer) + VertexBuffer->drop(); + if (IndexBuffer) + IndexBuffer->drop(); + } + + virtual IVertexBuffer& getVertexBuffer() const + { + return *VertexBuffer; + } + + virtual IIndexBuffer& getIndexBuffer() const + { + return *IndexBuffer; + } + + virtual void setVertexBuffer(IVertexBuffer *newVertexBuffer) + { + if (newVertexBuffer) + newVertexBuffer->grab(); + if (VertexBuffer) + VertexBuffer->drop(); + + VertexBuffer=newVertexBuffer; + } + + virtual void setIndexBuffer(IIndexBuffer *newIndexBuffer) + { + if (newIndexBuffer) + newIndexBuffer->grab(); + if (IndexBuffer) + IndexBuffer->drop(); + + IndexBuffer=newIndexBuffer; + } + + //! Get Material of this buffer. + virtual const video::SMaterial& getMaterial() const + { + return Material; + } + + //! Get Material of this buffer. + virtual video::SMaterial& getMaterial() + { + return Material; + } + + //! Get bounding box + virtual const core::aabbox3d<f32>& getBoundingBox() const + { + return BoundingBox; + } + + //! Set bounding box + virtual void setBoundingBox( const core::aabbox3df& box) + { + BoundingBox = box; + } + + //! Recalculate bounding box + virtual void recalculateBoundingBox() + { + if (!getVertexBuffer().size()) + BoundingBox.reset(0,0,0); + else + { + BoundingBox.reset(getVertexBuffer()[0].Pos); + for (u32 i=1; i<getVertexBuffer().size(); ++i) + BoundingBox.addInternalPoint(getVertexBuffer()[i].Pos); + } + } + + video::SMaterial Material; + core::aabbox3d<f32> BoundingBox; + private: + IVertexBuffer *VertexBuffer; + IIndexBuffer *IndexBuffer; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/CIndexBuffer.h b/builddir/irrlicht-1.8.1/include/CIndexBuffer.h new file mode 100644 index 0000000..4ecadb7 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/CIndexBuffer.h @@ -0,0 +1,226 @@ +// Copyright (C) 2008-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_INDEX_BUFFER_H_INCLUDED__ +#define __C_INDEX_BUFFER_H_INCLUDED__ + +#include "IIndexBuffer.h" + +namespace irr +{ +namespace scene +{ + + class CIndexBuffer : public IIndexBuffer + { + + class IIndexList + { + public: + virtual ~IIndexList(){}; + + virtual u32 stride() const =0; + virtual u32 size() const =0; + virtual void push_back(const u32 &element) =0; + virtual u32 operator [](u32 index) const =0; + virtual u32 getLast() =0; + virtual void setValue(u32 index, u32 value) =0; + virtual void set_used(u32 usedNow) =0; + virtual void reallocate(u32 new_size) =0; + virtual u32 allocated_size() const =0; + virtual void* pointer() =0; + virtual video::E_INDEX_TYPE getType() const =0; + }; + + template <class T> + class CSpecificIndexList : public IIndexList + { + public: + core::array<T> Indices; + + virtual u32 stride() const {return sizeof(T);} + + virtual u32 size() const {return Indices.size();} + + virtual void push_back(const u32 &element) + { + // push const ref due to compiler problem with gcc 4.6, big endian + Indices.push_back((const T&)element); + } + + virtual u32 operator [](u32 index) const + { + return (u32)(Indices[index]); + } + + virtual u32 getLast() {return (u32)Indices.getLast();} + + virtual void setValue(u32 index, u32 value) + { + Indices[index]=(T)value; + } + + virtual void set_used(u32 usedNow) + { + Indices.set_used(usedNow); + } + + virtual void reallocate(u32 new_size) + { + Indices.reallocate(new_size); + } + + virtual u32 allocated_size() const + { + return Indices.allocated_size(); + } + + virtual void* pointer() {return Indices.pointer();} + + virtual video::E_INDEX_TYPE getType() const + { + if (sizeof(T)==sizeof(u16)) + return video::EIT_16BIT; + else + return video::EIT_32BIT; + } + }; + + public: + IIndexList *Indices; + + CIndexBuffer(video::E_INDEX_TYPE IndexType) :Indices(0), MappingHint(EHM_NEVER), ChangedID(1) + { + setType(IndexType); + } + + CIndexBuffer(const IIndexBuffer &IndexBufferCopy) :Indices(0), MappingHint(EHM_NEVER), ChangedID(1) + { + setType(IndexBufferCopy.getType()); + reallocate(IndexBufferCopy.size()); + + for (u32 n=0;n<IndexBufferCopy.size();++n) + push_back(IndexBufferCopy[n]); + } + + virtual ~CIndexBuffer() + { + delete Indices; + } + + //virtual void setType(video::E_INDEX_TYPE IndexType); + virtual void setType(video::E_INDEX_TYPE IndexType) + { + IIndexList *NewIndices=0; + + switch (IndexType) + { + case video::EIT_16BIT: + { + NewIndices=new CSpecificIndexList<u16>; + break; + } + case video::EIT_32BIT: + { + NewIndices=new CSpecificIndexList<u32>; + break; + } + } + + if (Indices) + { + NewIndices->reallocate( Indices->size() ); + + for(u32 n=0;n<Indices->size();++n) + NewIndices->push_back((*Indices)[n]); + + delete Indices; + } + + Indices=NewIndices; + } + + virtual void* getData() {return Indices->pointer();} + + virtual video::E_INDEX_TYPE getType() const {return Indices->getType();} + + virtual u32 stride() const {return Indices->stride();} + + virtual u32 size() const + { + return Indices->size(); + } + + virtual void push_back(const u32 &element) + { + Indices->push_back(element); + } + + virtual u32 operator [](u32 index) const + { + return (*Indices)[index]; + } + + virtual u32 getLast() + { + return Indices->getLast(); + } + + virtual void setValue(u32 index, u32 value) + { + Indices->setValue(index, value); + } + + virtual void set_used(u32 usedNow) + { + Indices->set_used(usedNow); + } + + virtual void reallocate(u32 new_size) + { + Indices->reallocate(new_size); + } + + virtual u32 allocated_size() const + { + return Indices->allocated_size(); + } + + virtual void* pointer() + { + return Indices->pointer(); + } + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint() const + { + return MappingHint; + } + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint ) + { + MappingHint=NewMappingHint; + } + + //! flags the mesh as changed, reloads hardware buffers + virtual void setDirty() + { + ++ChangedID; + } + + //! Get the currently used ID for identification of changes. + /** This shouldn't be used for anything outside the VideoDriver. */ + virtual u32 getChangedID() const {return ChangedID;} + + E_HARDWARE_MAPPING MappingHint; + u32 ChangedID; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/CMeshBuffer.h b/builddir/irrlicht-1.8.1/include/CMeshBuffer.h new file mode 100644 index 0000000..24a95e2 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/CMeshBuffer.h @@ -0,0 +1,301 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __T_MESH_BUFFER_H_INCLUDED__ +#define __T_MESH_BUFFER_H_INCLUDED__ + +#include "irrArray.h" +#include "IMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + //! Template implementation of the IMeshBuffer interface + template <class T> + class CMeshBuffer : public IMeshBuffer + { + public: + //! Default constructor for empty meshbuffer + CMeshBuffer():ChangedID_Vertex(1),ChangedID_Index(1),MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER) + { + #ifdef _DEBUG + setDebugName("SMeshBuffer"); + #endif + } + + + //! Get material of this meshbuffer + /** \return Material of this buffer */ + virtual const video::SMaterial& getMaterial() const + { + return Material; + } + + + //! Get material of this meshbuffer + /** \return Material of this buffer */ + virtual video::SMaterial& getMaterial() + { + return Material; + } + + + //! Get pointer to vertices + /** \return Pointer to vertices. */ + virtual const void* getVertices() const + { + return Vertices.const_pointer(); + } + + + //! Get pointer to vertices + /** \return Pointer to vertices. */ + virtual void* getVertices() + { + return Vertices.pointer(); + } + + + //! Get number of vertices + /** \return Number of vertices. */ + virtual u32 getVertexCount() const + { + return Vertices.size(); + } + + //! Get type of index data which is stored in this meshbuffer. + /** \return Index type of this buffer. */ + virtual video::E_INDEX_TYPE getIndexType() const + { + return video::EIT_16BIT; + } + + //! Get pointer to indices + /** \return Pointer to indices. */ + virtual const u16* getIndices() const + { + return Indices.const_pointer(); + } + + + //! Get pointer to indices + /** \return Pointer to indices. */ + virtual u16* getIndices() + { + return Indices.pointer(); + } + + + //! Get number of indices + /** \return Number of indices. */ + virtual u32 getIndexCount() const + { + return Indices.size(); + } + + + //! Get the axis aligned bounding box + /** \return Axis aligned bounding box of this buffer. */ + virtual const core::aabbox3d<f32>& getBoundingBox() const + { + return BoundingBox; + } + + + //! Set the axis aligned bounding box + /** \param box New axis aligned bounding box for this buffer. */ + //! set user axis aligned bounding box + virtual void setBoundingBox(const core::aabbox3df& box) + { + BoundingBox = box; + } + + + //! Recalculate the bounding box. + /** should be called if the mesh changed. */ + virtual void recalculateBoundingBox() + { + if (Vertices.empty()) + BoundingBox.reset(0,0,0); + else + { + BoundingBox.reset(Vertices[0].Pos); + for (u32 i=1; i<Vertices.size(); ++i) + BoundingBox.addInternalPoint(Vertices[i].Pos); + } + } + + + //! Get type of vertex data stored in this buffer. + /** \return Type of vertex data. */ + virtual video::E_VERTEX_TYPE getVertexType() const + { + return T().getType(); + } + + //! returns position of vertex i + virtual const core::vector3df& getPosition(u32 i) const + { + return Vertices[i].Pos; + } + + //! returns position of vertex i + virtual core::vector3df& getPosition(u32 i) + { + return Vertices[i].Pos; + } + + //! returns normal of vertex i + virtual const core::vector3df& getNormal(u32 i) const + { + return Vertices[i].Normal; + } + + //! returns normal of vertex i + virtual core::vector3df& getNormal(u32 i) + { + return Vertices[i].Normal; + } + + //! returns texture coord of vertex i + virtual const core::vector2df& getTCoords(u32 i) const + { + return Vertices[i].TCoords; + } + + //! returns texture coord of vertex i + virtual core::vector2df& getTCoords(u32 i) + { + return Vertices[i].TCoords; + } + + + //! Append the vertices and indices to the current buffer + /** Only works for compatible types, i.e. either the same type + or the main buffer is of standard type. Otherwise, behavior is + undefined. + */ + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) + { + if (vertices == getVertices()) + return; + + const u32 vertexCount = getVertexCount(); + u32 i; + + Vertices.reallocate(vertexCount+numVertices); + for (i=0; i<numVertices; ++i) + { + Vertices.push_back(reinterpret_cast<const T*>(vertices)[i]); + BoundingBox.addInternalPoint(reinterpret_cast<const T*>(vertices)[i].Pos); + } + + Indices.reallocate(getIndexCount()+numIndices); + for (i=0; i<numIndices; ++i) + { + Indices.push_back(indices[i]+vertexCount); + } + } + + + //! Append the meshbuffer to the current buffer + /** Only works for compatible types, i.e. either the same type + or the main buffer is of standard type. Otherwise, behavior is + undefined. + \param other Meshbuffer to be appended to this one. + */ + virtual void append(const IMeshBuffer* const other) + { + /* + if (this==other) + return; + + const u32 vertexCount = getVertexCount(); + u32 i; + + Vertices.reallocate(vertexCount+other->getVertexCount()); + for (i=0; i<other->getVertexCount(); ++i) + { + Vertices.push_back(reinterpret_cast<const T*>(other->getVertices())[i]); + } + + Indices.reallocate(getIndexCount()+other->getIndexCount()); + for (i=0; i<other->getIndexCount(); ++i) + { + Indices.push_back(other->getIndices()[i]+vertexCount); + } + BoundingBox.addInternalBox(other->getBoundingBox()); + */ + } + + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const + { + return MappingHint_Vertex; + } + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint_Index() const + { + return MappingHint_Index; + } + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX ) + { + if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_VERTEX) + MappingHint_Vertex=NewMappingHint; + if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_INDEX) + MappingHint_Index=NewMappingHint; + } + + + //! flags the mesh as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX) + { + if (Buffer==EBT_VERTEX_AND_INDEX ||Buffer==EBT_VERTEX) + ++ChangedID_Vertex; + if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_INDEX) + ++ChangedID_Index; + } + + //! Get the currently used ID for identification of changes. + /** This shouldn't be used for anything outside the VideoDriver. */ + virtual u32 getChangedID_Vertex() const {return ChangedID_Vertex;} + + //! Get the currently used ID for identification of changes. + /** This shouldn't be used for anything outside the VideoDriver. */ + virtual u32 getChangedID_Index() const {return ChangedID_Index;} + + u32 ChangedID_Vertex; + u32 ChangedID_Index; + + //! hardware mapping hint + E_HARDWARE_MAPPING MappingHint_Vertex; + E_HARDWARE_MAPPING MappingHint_Index; + + //! Material for this meshbuffer. + video::SMaterial Material; + //! Vertices of this buffer + core::array<T> Vertices; + //! Indices into the vertices of this buffer. + core::array<u16> Indices; + //! Bounding box of this meshbuffer. + core::aabbox3d<f32> BoundingBox; + }; + + //! Standard meshbuffer + typedef CMeshBuffer<video::S3DVertex> SMeshBuffer; + //! Meshbuffer with two texture coords per vertex, e.g. for lightmaps + typedef CMeshBuffer<video::S3DVertex2TCoords> SMeshBufferLightMap; + //! Meshbuffer with vertices having tangents stored, e.g. for normal mapping + typedef CMeshBuffer<video::S3DVertexTangents> SMeshBufferTangents; +} // end namespace scene +} // end namespace irr + +#endif + + diff --git a/builddir/irrlicht-1.8.1/include/CVertexBuffer.h b/builddir/irrlicht-1.8.1/include/CVertexBuffer.h new file mode 100644 index 0000000..975b0e7 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/CVertexBuffer.h @@ -0,0 +1,210 @@ +// Copyright (C) 2008-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_VERTEX_BUFFER_H_INCLUDED__ +#define __C_VERTEX_BUFFER_H_INCLUDED__ + +#include "IVertexBuffer.h" + + +namespace irr +{ +namespace scene +{ + + class CVertexBuffer : public IVertexBuffer + { + class IVertexList + { + public: + virtual ~IVertexList(){}; + + virtual u32 stride() const =0; + + virtual u32 size() const =0; + + virtual void push_back (const video::S3DVertex &element) =0; + virtual video::S3DVertex& operator [](const u32 index) const =0; + virtual video::S3DVertex& getLast() =0; + virtual void set_used(u32 usedNow) =0; + virtual void reallocate(u32 new_size) =0; + virtual u32 allocated_size() const =0; + virtual video::S3DVertex* pointer() =0; + virtual video::E_VERTEX_TYPE getType() const =0; + }; + + template <class T> + class CSpecificVertexList : public IVertexList + { + public: + core::array<T> Vertices; + + virtual u32 stride() const {return sizeof(T);} + + virtual u32 size() const {return Vertices.size();} + + virtual void push_back (const video::S3DVertex &element) + {Vertices.push_back((T&)element);} + + virtual video::S3DVertex& operator [](const u32 index) const + {return (video::S3DVertex&)Vertices[index];} + + virtual video::S3DVertex& getLast() + {return (video::S3DVertex&)Vertices.getLast();} + + virtual void set_used(u32 usedNow) + {Vertices.set_used(usedNow);} + + virtual void reallocate(u32 new_size) + {Vertices.reallocate(new_size);} + + virtual u32 allocated_size() const + { + return Vertices.allocated_size(); + } + + virtual video::S3DVertex* pointer() {return Vertices.pointer();} + + virtual video::E_VERTEX_TYPE getType() const {return T().getType();} + }; + + public: + IVertexList *Vertices; + + CVertexBuffer(video::E_VERTEX_TYPE vertexType) : Vertices(0), + MappingHint(EHM_NEVER), ChangedID(1) + { + setType(vertexType); + } + + CVertexBuffer(const IVertexBuffer &VertexBufferCopy) : + Vertices(0), MappingHint(EHM_NEVER), + ChangedID(1) + { + setType(VertexBufferCopy.getType()); + reallocate(VertexBufferCopy.size()); + + for (u32 n=0;n<VertexBufferCopy.size();++n) + push_back(VertexBufferCopy[n]); + } + + virtual ~CVertexBuffer() + { + delete Vertices; + } + + + virtual void setType(video::E_VERTEX_TYPE vertexType) + { + IVertexList *NewVertices=0; + + switch (vertexType) + { + case video::EVT_STANDARD: + { + NewVertices=new CSpecificVertexList<video::S3DVertex>; + break; + } + case video::EVT_2TCOORDS: + { + NewVertices=new CSpecificVertexList<video::S3DVertex2TCoords>; + break; + } + case video::EVT_TANGENTS: + { + NewVertices=new CSpecificVertexList<video::S3DVertexTangents>; + break; + } + } + if (Vertices) + { + NewVertices->reallocate( Vertices->size() ); + + for(u32 n=0;n<Vertices->size();++n) + NewVertices->push_back((*Vertices)[n]); + + delete Vertices; + } + + Vertices=NewVertices; + } + + virtual void* getData() {return Vertices->pointer();} + + virtual video::E_VERTEX_TYPE getType() const {return Vertices->getType();} + + virtual u32 stride() const {return Vertices->stride();} + + virtual u32 size() const + { + return Vertices->size(); + } + + virtual void push_back (const video::S3DVertex &element) + { + Vertices->push_back(element); + } + + virtual video::S3DVertex& operator [](const u32 index) const + { + return (*Vertices)[index]; + } + + virtual video::S3DVertex& getLast() + { + return Vertices->getLast(); + } + + virtual void set_used(u32 usedNow) + { + Vertices->set_used(usedNow); + } + + virtual void reallocate(u32 new_size) + { + Vertices->reallocate(new_size); + } + + virtual u32 allocated_size() const + { + return Vertices->allocated_size(); + } + + virtual video::S3DVertex* pointer() + { + return Vertices->pointer(); + } + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint() const + { + return MappingHint; + } + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint ) + { + MappingHint=NewMappingHint; + } + + //! flags the mesh as changed, reloads hardware buffers + virtual void setDirty() + { + ++ChangedID; + } + + //! Get the currently used ID for identification of changes. + /** This shouldn't be used for anything outside the VideoDriver. */ + virtual u32 getChangedID() const {return ChangedID;} + + E_HARDWARE_MAPPING MappingHint; + u32 ChangedID; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/D3Dcommon.h b/builddir/irrlicht-1.8.1/include/D3Dcommon.h new file mode 100644 index 0000000..032b8b5 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/D3Dcommon.h @@ -0,0 +1,787 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0555 */ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the <rpcndr.h> version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +/* verify that the <rpcsal.h> version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of <rpcndr.h> +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __d3dcommon_h__ +#define __d3dcommon_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ID3D10Blob_FWD_DEFINED__ +#define __ID3D10Blob_FWD_DEFINED__ +typedef interface ID3D10Blob ID3D10Blob; +#endif /* __ID3D10Blob_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_d3dcommon_0000_0000 */ +/* [local] */ + +typedef +enum D3D_DRIVER_TYPE + { D3D_DRIVER_TYPE_UNKNOWN = 0, + D3D_DRIVER_TYPE_HARDWARE = ( D3D_DRIVER_TYPE_UNKNOWN + 1 ) , + D3D_DRIVER_TYPE_REFERENCE = ( D3D_DRIVER_TYPE_HARDWARE + 1 ) , + D3D_DRIVER_TYPE_NULL = ( D3D_DRIVER_TYPE_REFERENCE + 1 ) , + D3D_DRIVER_TYPE_SOFTWARE = ( D3D_DRIVER_TYPE_NULL + 1 ) , + D3D_DRIVER_TYPE_WARP = ( D3D_DRIVER_TYPE_SOFTWARE + 1 ) + } D3D_DRIVER_TYPE; + +typedef +enum D3D_FEATURE_LEVEL + { D3D_FEATURE_LEVEL_9_1 = 0x9100, + D3D_FEATURE_LEVEL_9_2 = 0x9200, + D3D_FEATURE_LEVEL_9_3 = 0x9300, + D3D_FEATURE_LEVEL_10_0 = 0xa000, + D3D_FEATURE_LEVEL_10_1 = 0xa100, + D3D_FEATURE_LEVEL_11_0 = 0xb000 + } D3D_FEATURE_LEVEL; + +typedef +enum D3D_PRIMITIVE_TOPOLOGY + { D3D_PRIMITIVE_TOPOLOGY_UNDEFINED = 0, + D3D_PRIMITIVE_TOPOLOGY_POINTLIST = 1, + D3D_PRIMITIVE_TOPOLOGY_LINELIST = 2, + D3D_PRIMITIVE_TOPOLOGY_LINESTRIP = 3, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5, + D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10, + D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = 12, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = 13, + D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33, + D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = 34, + D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = 35, + D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = 36, + D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = 37, + D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = 38, + D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = 39, + D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = 40, + D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = 41, + D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = 42, + D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST = 43, + D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST = 44, + D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST = 45, + D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST = 46, + D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST = 47, + D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST = 48, + D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST = 49, + D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST = 50, + D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST = 51, + D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST = 52, + D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST = 53, + D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST = 54, + D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST = 55, + D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST = 56, + D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST = 57, + D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST = 58, + D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST = 59, + D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST = 60, + D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST = 61, + D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST = 62, + D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = 63, + D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = 64, + D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED, + D3D10_PRIMITIVE_TOPOLOGY_POINTLIST = D3D_PRIMITIVE_TOPOLOGY_POINTLIST, + D3D10_PRIMITIVE_TOPOLOGY_LINELIST = D3D_PRIMITIVE_TOPOLOGY_LINELIST, + D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, + D3D10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ, + D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED, + D3D11_PRIMITIVE_TOPOLOGY_POINTLIST = D3D_PRIMITIVE_TOPOLOGY_POINTLIST, + D3D11_PRIMITIVE_TOPOLOGY_LINELIST = D3D_PRIMITIVE_TOPOLOGY_LINELIST, + D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, + D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST + } D3D_PRIMITIVE_TOPOLOGY; + +typedef +enum D3D_PRIMITIVE + { D3D_PRIMITIVE_UNDEFINED = 0, + D3D_PRIMITIVE_POINT = 1, + D3D_PRIMITIVE_LINE = 2, + D3D_PRIMITIVE_TRIANGLE = 3, + D3D_PRIMITIVE_LINE_ADJ = 6, + D3D_PRIMITIVE_TRIANGLE_ADJ = 7, + D3D_PRIMITIVE_1_CONTROL_POINT_PATCH = 8, + D3D_PRIMITIVE_2_CONTROL_POINT_PATCH = 9, + D3D_PRIMITIVE_3_CONTROL_POINT_PATCH = 10, + D3D_PRIMITIVE_4_CONTROL_POINT_PATCH = 11, + D3D_PRIMITIVE_5_CONTROL_POINT_PATCH = 12, + D3D_PRIMITIVE_6_CONTROL_POINT_PATCH = 13, + D3D_PRIMITIVE_7_CONTROL_POINT_PATCH = 14, + D3D_PRIMITIVE_8_CONTROL_POINT_PATCH = 15, + D3D_PRIMITIVE_9_CONTROL_POINT_PATCH = 16, + D3D_PRIMITIVE_10_CONTROL_POINT_PATCH = 17, + D3D_PRIMITIVE_11_CONTROL_POINT_PATCH = 18, + D3D_PRIMITIVE_12_CONTROL_POINT_PATCH = 19, + D3D_PRIMITIVE_13_CONTROL_POINT_PATCH = 20, + D3D_PRIMITIVE_14_CONTROL_POINT_PATCH = 21, + D3D_PRIMITIVE_15_CONTROL_POINT_PATCH = 22, + D3D_PRIMITIVE_16_CONTROL_POINT_PATCH = 23, + D3D_PRIMITIVE_17_CONTROL_POINT_PATCH = 24, + D3D_PRIMITIVE_18_CONTROL_POINT_PATCH = 25, + D3D_PRIMITIVE_19_CONTROL_POINT_PATCH = 26, + D3D_PRIMITIVE_20_CONTROL_POINT_PATCH = 28, + D3D_PRIMITIVE_21_CONTROL_POINT_PATCH = 29, + D3D_PRIMITIVE_22_CONTROL_POINT_PATCH = 30, + D3D_PRIMITIVE_23_CONTROL_POINT_PATCH = 31, + D3D_PRIMITIVE_24_CONTROL_POINT_PATCH = 32, + D3D_PRIMITIVE_25_CONTROL_POINT_PATCH = 33, + D3D_PRIMITIVE_26_CONTROL_POINT_PATCH = 34, + D3D_PRIMITIVE_27_CONTROL_POINT_PATCH = 35, + D3D_PRIMITIVE_28_CONTROL_POINT_PATCH = 36, + D3D_PRIMITIVE_29_CONTROL_POINT_PATCH = 37, + D3D_PRIMITIVE_30_CONTROL_POINT_PATCH = 38, + D3D_PRIMITIVE_31_CONTROL_POINT_PATCH = 39, + D3D_PRIMITIVE_32_CONTROL_POINT_PATCH = 40, + D3D10_PRIMITIVE_UNDEFINED = D3D_PRIMITIVE_UNDEFINED, + D3D10_PRIMITIVE_POINT = D3D_PRIMITIVE_POINT, + D3D10_PRIMITIVE_LINE = D3D_PRIMITIVE_LINE, + D3D10_PRIMITIVE_TRIANGLE = D3D_PRIMITIVE_TRIANGLE, + D3D10_PRIMITIVE_LINE_ADJ = D3D_PRIMITIVE_LINE_ADJ, + D3D10_PRIMITIVE_TRIANGLE_ADJ = D3D_PRIMITIVE_TRIANGLE_ADJ, + D3D11_PRIMITIVE_UNDEFINED = D3D_PRIMITIVE_UNDEFINED, + D3D11_PRIMITIVE_POINT = D3D_PRIMITIVE_POINT, + D3D11_PRIMITIVE_LINE = D3D_PRIMITIVE_LINE, + D3D11_PRIMITIVE_TRIANGLE = D3D_PRIMITIVE_TRIANGLE, + D3D11_PRIMITIVE_LINE_ADJ = D3D_PRIMITIVE_LINE_ADJ, + D3D11_PRIMITIVE_TRIANGLE_ADJ = D3D_PRIMITIVE_TRIANGLE_ADJ, + D3D11_PRIMITIVE_1_CONTROL_POINT_PATCH = D3D_PRIMITIVE_1_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_2_CONTROL_POINT_PATCH = D3D_PRIMITIVE_2_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_3_CONTROL_POINT_PATCH = D3D_PRIMITIVE_3_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_4_CONTROL_POINT_PATCH = D3D_PRIMITIVE_4_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_5_CONTROL_POINT_PATCH = D3D_PRIMITIVE_5_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_6_CONTROL_POINT_PATCH = D3D_PRIMITIVE_6_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_7_CONTROL_POINT_PATCH = D3D_PRIMITIVE_7_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_8_CONTROL_POINT_PATCH = D3D_PRIMITIVE_8_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_9_CONTROL_POINT_PATCH = D3D_PRIMITIVE_9_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_10_CONTROL_POINT_PATCH = D3D_PRIMITIVE_10_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_11_CONTROL_POINT_PATCH = D3D_PRIMITIVE_11_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_12_CONTROL_POINT_PATCH = D3D_PRIMITIVE_12_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_13_CONTROL_POINT_PATCH = D3D_PRIMITIVE_13_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_14_CONTROL_POINT_PATCH = D3D_PRIMITIVE_14_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_15_CONTROL_POINT_PATCH = D3D_PRIMITIVE_15_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_16_CONTROL_POINT_PATCH = D3D_PRIMITIVE_16_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_17_CONTROL_POINT_PATCH = D3D_PRIMITIVE_17_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_18_CONTROL_POINT_PATCH = D3D_PRIMITIVE_18_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_19_CONTROL_POINT_PATCH = D3D_PRIMITIVE_19_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_20_CONTROL_POINT_PATCH = D3D_PRIMITIVE_20_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_21_CONTROL_POINT_PATCH = D3D_PRIMITIVE_21_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_22_CONTROL_POINT_PATCH = D3D_PRIMITIVE_22_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_23_CONTROL_POINT_PATCH = D3D_PRIMITIVE_23_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_24_CONTROL_POINT_PATCH = D3D_PRIMITIVE_24_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_25_CONTROL_POINT_PATCH = D3D_PRIMITIVE_25_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_26_CONTROL_POINT_PATCH = D3D_PRIMITIVE_26_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_27_CONTROL_POINT_PATCH = D3D_PRIMITIVE_27_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_28_CONTROL_POINT_PATCH = D3D_PRIMITIVE_28_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_29_CONTROL_POINT_PATCH = D3D_PRIMITIVE_29_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_30_CONTROL_POINT_PATCH = D3D_PRIMITIVE_30_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_31_CONTROL_POINT_PATCH = D3D_PRIMITIVE_31_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_32_CONTROL_POINT_PATCH = D3D_PRIMITIVE_32_CONTROL_POINT_PATCH + } D3D_PRIMITIVE; + +typedef +enum D3D_SRV_DIMENSION + { D3D_SRV_DIMENSION_UNKNOWN = 0, + D3D_SRV_DIMENSION_BUFFER = 1, + D3D_SRV_DIMENSION_TEXTURE1D = 2, + D3D_SRV_DIMENSION_TEXTURE1DARRAY = 3, + D3D_SRV_DIMENSION_TEXTURE2D = 4, + D3D_SRV_DIMENSION_TEXTURE2DARRAY = 5, + D3D_SRV_DIMENSION_TEXTURE2DMS = 6, + D3D_SRV_DIMENSION_TEXTURE2DMSARRAY = 7, + D3D_SRV_DIMENSION_TEXTURE3D = 8, + D3D_SRV_DIMENSION_TEXTURECUBE = 9, + D3D_SRV_DIMENSION_TEXTURECUBEARRAY = 10, + D3D_SRV_DIMENSION_BUFFEREX = 11, + D3D10_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN, + D3D10_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER, + D3D10_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D, + D3D10_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY, + D3D10_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D, + D3D10_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY, + D3D10_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS, + D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D10_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D, + D3D10_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE, + D3D10_1_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN, + D3D10_1_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER, + D3D10_1_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D, + D3D10_1_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D, + D3D10_1_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS, + D3D10_1_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D, + D3D10_1_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE, + D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY = D3D_SRV_DIMENSION_TEXTURECUBEARRAY, + D3D11_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN, + D3D11_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER, + D3D11_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D, + D3D11_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY, + D3D11_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D, + D3D11_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY, + D3D11_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS, + D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D11_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D, + D3D11_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE, + D3D11_SRV_DIMENSION_TEXTURECUBEARRAY = D3D_SRV_DIMENSION_TEXTURECUBEARRAY, + D3D11_SRV_DIMENSION_BUFFEREX = D3D_SRV_DIMENSION_BUFFEREX + } D3D_SRV_DIMENSION; + +typedef struct _D3D_SHADER_MACRO + { + LPCSTR Name; + LPCSTR Definition; + } D3D_SHADER_MACRO; + +typedef struct _D3D_SHADER_MACRO *LPD3D_SHADER_MACRO; + +DEFINE_GUID(IID_ID3D10Blob, 0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58, 0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2); + + +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0000_v0_0_s_ifspec; + +#ifndef __ID3D10Blob_INTERFACE_DEFINED__ +#define __ID3D10Blob_INTERFACE_DEFINED__ + +/* interface ID3D10Blob */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Blob; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8BA5FB08-5195-40e2-AC58-0D989C3A0102") + ID3D10Blob : public IUnknown + { + public: + virtual LPVOID STDMETHODCALLTYPE GetBufferPointer( void) = 0; + + virtual SIZE_T STDMETHODCALLTYPE GetBufferSize( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct ID3D10BlobVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Blob * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Blob * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Blob * This); + + LPVOID ( STDMETHODCALLTYPE *GetBufferPointer )( + ID3D10Blob * This); + + SIZE_T ( STDMETHODCALLTYPE *GetBufferSize )( + ID3D10Blob * This); + + END_INTERFACE + } ID3D10BlobVtbl; + + interface ID3D10Blob + { + CONST_VTBL struct ID3D10BlobVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Blob_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Blob_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Blob_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Blob_GetBufferPointer(This) \ + ( (This)->lpVtbl -> GetBufferPointer(This) ) + +#define ID3D10Blob_GetBufferSize(This) \ + ( (This)->lpVtbl -> GetBufferSize(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Blob_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3dcommon_0000_0001 */ +/* [local] */ + +typedef interface ID3D10Blob* LPD3D10BLOB; +typedef ID3D10Blob ID3DBlob; +typedef ID3DBlob* LPD3DBLOB; +#define IID_ID3DBlob IID_ID3D10Blob +typedef +enum _D3D_INCLUDE_TYPE + { D3D_INCLUDE_LOCAL = 0, + D3D_INCLUDE_SYSTEM = ( D3D_INCLUDE_LOCAL + 1 ) , + D3D10_INCLUDE_LOCAL = D3D_INCLUDE_LOCAL, + D3D10_INCLUDE_SYSTEM = D3D_INCLUDE_SYSTEM, + D3D_INCLUDE_FORCE_DWORD = 0x7fffffff + } D3D_INCLUDE_TYPE; + +typedef interface ID3DInclude ID3DInclude; +#undef INTERFACE +#define INTERFACE ID3DInclude +DECLARE_INTERFACE(ID3DInclude) +{ + STDMETHOD(Open)(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) PURE; + STDMETHOD(Close)(THIS_ LPCVOID pData) PURE; +}; +typedef ID3DInclude* LPD3DINCLUDE; +typedef +enum _D3D_SHADER_VARIABLE_CLASS + { D3D_SVC_SCALAR = 0, + D3D_SVC_VECTOR = ( D3D_SVC_SCALAR + 1 ) , + D3D_SVC_MATRIX_ROWS = ( D3D_SVC_VECTOR + 1 ) , + D3D_SVC_MATRIX_COLUMNS = ( D3D_SVC_MATRIX_ROWS + 1 ) , + D3D_SVC_OBJECT = ( D3D_SVC_MATRIX_COLUMNS + 1 ) , + D3D_SVC_STRUCT = ( D3D_SVC_OBJECT + 1 ) , + D3D_SVC_INTERFACE_CLASS = ( D3D_SVC_STRUCT + 1 ) , + D3D_SVC_INTERFACE_POINTER = ( D3D_SVC_INTERFACE_CLASS + 1 ) , + D3D10_SVC_SCALAR = D3D_SVC_SCALAR, + D3D10_SVC_VECTOR = D3D_SVC_VECTOR, + D3D10_SVC_MATRIX_ROWS = D3D_SVC_MATRIX_ROWS, + D3D10_SVC_MATRIX_COLUMNS = D3D_SVC_MATRIX_COLUMNS, + D3D10_SVC_OBJECT = D3D_SVC_OBJECT, + D3D10_SVC_STRUCT = D3D_SVC_STRUCT, + D3D11_SVC_INTERFACE_CLASS = D3D_SVC_INTERFACE_CLASS, + D3D11_SVC_INTERFACE_POINTER = D3D_SVC_INTERFACE_POINTER, + D3D_SVC_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_VARIABLE_CLASS; + +typedef +enum _D3D_SHADER_VARIABLE_FLAGS + { D3D_SVF_USERPACKED = 1, + D3D_SVF_USED = 2, + D3D_SVF_INTERFACE_POINTER = 4, + D3D_SVF_INTERFACE_PARAMETER = 8, + D3D10_SVF_USERPACKED = D3D_SVF_USERPACKED, + D3D10_SVF_USED = D3D_SVF_USED, + D3D11_SVF_INTERFACE_POINTER = D3D_SVF_INTERFACE_POINTER, + D3D11_SVF_INTERFACE_PARAMETER = D3D_SVF_INTERFACE_PARAMETER, + D3D_SVF_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_VARIABLE_FLAGS; + +typedef +enum _D3D_SHADER_VARIABLE_TYPE + { D3D_SVT_VOID = 0, + D3D_SVT_BOOL = 1, + D3D_SVT_INT = 2, + D3D_SVT_FLOAT = 3, + D3D_SVT_STRING = 4, + D3D_SVT_TEXTURE = 5, + D3D_SVT_TEXTURE1D = 6, + D3D_SVT_TEXTURE2D = 7, + D3D_SVT_TEXTURE3D = 8, + D3D_SVT_TEXTURECUBE = 9, + D3D_SVT_SAMPLER = 10, + D3D_SVT_SAMPLER1D = 11, + D3D_SVT_SAMPLER2D = 12, + D3D_SVT_SAMPLER3D = 13, + D3D_SVT_SAMPLERCUBE = 14, + D3D_SVT_PIXELSHADER = 15, + D3D_SVT_VERTEXSHADER = 16, + D3D_SVT_PIXELFRAGMENT = 17, + D3D_SVT_VERTEXFRAGMENT = 18, + D3D_SVT_UINT = 19, + D3D_SVT_UINT8 = 20, + D3D_SVT_GEOMETRYSHADER = 21, + D3D_SVT_RASTERIZER = 22, + D3D_SVT_DEPTHSTENCIL = 23, + D3D_SVT_BLEND = 24, + D3D_SVT_BUFFER = 25, + D3D_SVT_CBUFFER = 26, + D3D_SVT_TBUFFER = 27, + D3D_SVT_TEXTURE1DARRAY = 28, + D3D_SVT_TEXTURE2DARRAY = 29, + D3D_SVT_RENDERTARGETVIEW = 30, + D3D_SVT_DEPTHSTENCILVIEW = 31, + D3D_SVT_TEXTURE2DMS = 32, + D3D_SVT_TEXTURE2DMSARRAY = 33, + D3D_SVT_TEXTURECUBEARRAY = 34, + D3D_SVT_HULLSHADER = 35, + D3D_SVT_DOMAINSHADER = 36, + D3D_SVT_INTERFACE_POINTER = 37, + D3D_SVT_COMPUTESHADER = 38, + D3D_SVT_DOUBLE = 39, + D3D_SVT_RWTEXTURE1D = 40, + D3D_SVT_RWTEXTURE1DARRAY = 41, + D3D_SVT_RWTEXTURE2D = 42, + D3D_SVT_RWTEXTURE2DARRAY = 43, + D3D_SVT_RWTEXTURE3D = 44, + D3D_SVT_RWBUFFER = 45, + D3D_SVT_BYTEADDRESS_BUFFER = 46, + D3D_SVT_RWBYTEADDRESS_BUFFER = 47, + D3D_SVT_STRUCTURED_BUFFER = 48, + D3D_SVT_RWSTRUCTURED_BUFFER = 49, + D3D_SVT_APPEND_STRUCTURED_BUFFER = 50, + D3D_SVT_CONSUME_STRUCTURED_BUFFER = 51, + D3D10_SVT_VOID = D3D_SVT_VOID, + D3D10_SVT_BOOL = D3D_SVT_BOOL, + D3D10_SVT_INT = D3D_SVT_INT, + D3D10_SVT_FLOAT = D3D_SVT_FLOAT, + D3D10_SVT_STRING = D3D_SVT_STRING, + D3D10_SVT_TEXTURE = D3D_SVT_TEXTURE, + D3D10_SVT_TEXTURE1D = D3D_SVT_TEXTURE1D, + D3D10_SVT_TEXTURE2D = D3D_SVT_TEXTURE2D, + D3D10_SVT_TEXTURE3D = D3D_SVT_TEXTURE3D, + D3D10_SVT_TEXTURECUBE = D3D_SVT_TEXTURECUBE, + D3D10_SVT_SAMPLER = D3D_SVT_SAMPLER, + D3D10_SVT_SAMPLER1D = D3D_SVT_SAMPLER1D, + D3D10_SVT_SAMPLER2D = D3D_SVT_SAMPLER2D, + D3D10_SVT_SAMPLER3D = D3D_SVT_SAMPLER3D, + D3D10_SVT_SAMPLERCUBE = D3D_SVT_SAMPLERCUBE, + D3D10_SVT_PIXELSHADER = D3D_SVT_PIXELSHADER, + D3D10_SVT_VERTEXSHADER = D3D_SVT_VERTEXSHADER, + D3D10_SVT_PIXELFRAGMENT = D3D_SVT_PIXELFRAGMENT, + D3D10_SVT_VERTEXFRAGMENT = D3D_SVT_VERTEXFRAGMENT, + D3D10_SVT_UINT = D3D_SVT_UINT, + D3D10_SVT_UINT8 = D3D_SVT_UINT8, + D3D10_SVT_GEOMETRYSHADER = D3D_SVT_GEOMETRYSHADER, + D3D10_SVT_RASTERIZER = D3D_SVT_RASTERIZER, + D3D10_SVT_DEPTHSTENCIL = D3D_SVT_DEPTHSTENCIL, + D3D10_SVT_BLEND = D3D_SVT_BLEND, + D3D10_SVT_BUFFER = D3D_SVT_BUFFER, + D3D10_SVT_CBUFFER = D3D_SVT_CBUFFER, + D3D10_SVT_TBUFFER = D3D_SVT_TBUFFER, + D3D10_SVT_TEXTURE1DARRAY = D3D_SVT_TEXTURE1DARRAY, + D3D10_SVT_TEXTURE2DARRAY = D3D_SVT_TEXTURE2DARRAY, + D3D10_SVT_RENDERTARGETVIEW = D3D_SVT_RENDERTARGETVIEW, + D3D10_SVT_DEPTHSTENCILVIEW = D3D_SVT_DEPTHSTENCILVIEW, + D3D10_SVT_TEXTURE2DMS = D3D_SVT_TEXTURE2DMS, + D3D10_SVT_TEXTURE2DMSARRAY = D3D_SVT_TEXTURE2DMSARRAY, + D3D10_SVT_TEXTURECUBEARRAY = D3D_SVT_TEXTURECUBEARRAY, + D3D11_SVT_HULLSHADER = D3D_SVT_HULLSHADER, + D3D11_SVT_DOMAINSHADER = D3D_SVT_DOMAINSHADER, + D3D11_SVT_INTERFACE_POINTER = D3D_SVT_INTERFACE_POINTER, + D3D11_SVT_COMPUTESHADER = D3D_SVT_COMPUTESHADER, + D3D11_SVT_DOUBLE = D3D_SVT_DOUBLE, + D3D11_SVT_RWTEXTURE1D = D3D_SVT_RWTEXTURE1D, + D3D11_SVT_RWTEXTURE1DARRAY = D3D_SVT_RWTEXTURE1DARRAY, + D3D11_SVT_RWTEXTURE2D = D3D_SVT_RWTEXTURE2D, + D3D11_SVT_RWTEXTURE2DARRAY = D3D_SVT_RWTEXTURE2DARRAY, + D3D11_SVT_RWTEXTURE3D = D3D_SVT_RWTEXTURE3D, + D3D11_SVT_RWBUFFER = D3D_SVT_RWBUFFER, + D3D11_SVT_BYTEADDRESS_BUFFER = D3D_SVT_BYTEADDRESS_BUFFER, + D3D11_SVT_RWBYTEADDRESS_BUFFER = D3D_SVT_RWBYTEADDRESS_BUFFER, + D3D11_SVT_STRUCTURED_BUFFER = D3D_SVT_STRUCTURED_BUFFER, + D3D11_SVT_RWSTRUCTURED_BUFFER = D3D_SVT_RWSTRUCTURED_BUFFER, + D3D11_SVT_APPEND_STRUCTURED_BUFFER = D3D_SVT_APPEND_STRUCTURED_BUFFER, + D3D11_SVT_CONSUME_STRUCTURED_BUFFER = D3D_SVT_CONSUME_STRUCTURED_BUFFER, + D3D_SVT_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_VARIABLE_TYPE; + +typedef +enum _D3D_SHADER_INPUT_FLAGS + { D3D_SIF_USERPACKED = 1, + D3D_SIF_COMPARISON_SAMPLER = 2, + D3D_SIF_TEXTURE_COMPONENT_0 = 4, + D3D_SIF_TEXTURE_COMPONENT_1 = 8, + D3D_SIF_TEXTURE_COMPONENTS = 12, + D3D10_SIF_USERPACKED = D3D_SIF_USERPACKED, + D3D10_SIF_COMPARISON_SAMPLER = D3D_SIF_COMPARISON_SAMPLER, + D3D10_SIF_TEXTURE_COMPONENT_0 = D3D_SIF_TEXTURE_COMPONENT_0, + D3D10_SIF_TEXTURE_COMPONENT_1 = D3D_SIF_TEXTURE_COMPONENT_1, + D3D10_SIF_TEXTURE_COMPONENTS = D3D_SIF_TEXTURE_COMPONENTS, + D3D_SIF_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_INPUT_FLAGS; + +typedef +enum _D3D_SHADER_INPUT_TYPE + { D3D_SIT_CBUFFER = 0, + D3D_SIT_TBUFFER = ( D3D_SIT_CBUFFER + 1 ) , + D3D_SIT_TEXTURE = ( D3D_SIT_TBUFFER + 1 ) , + D3D_SIT_SAMPLER = ( D3D_SIT_TEXTURE + 1 ) , + D3D_SIT_UAV_RWTYPED = ( D3D_SIT_SAMPLER + 1 ) , + D3D_SIT_STRUCTURED = ( D3D_SIT_UAV_RWTYPED + 1 ) , + D3D_SIT_UAV_RWSTRUCTURED = ( D3D_SIT_STRUCTURED + 1 ) , + D3D_SIT_BYTEADDRESS = ( D3D_SIT_UAV_RWSTRUCTURED + 1 ) , + D3D_SIT_UAV_RWBYTEADDRESS = ( D3D_SIT_BYTEADDRESS + 1 ) , + D3D_SIT_UAV_APPEND_STRUCTURED = ( D3D_SIT_UAV_RWBYTEADDRESS + 1 ) , + D3D_SIT_UAV_CONSUME_STRUCTURED = ( D3D_SIT_UAV_APPEND_STRUCTURED + 1 ) , + D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER = ( D3D_SIT_UAV_CONSUME_STRUCTURED + 1 ) , + D3D10_SIT_CBUFFER = D3D_SIT_CBUFFER, + D3D10_SIT_TBUFFER = D3D_SIT_TBUFFER, + D3D10_SIT_TEXTURE = D3D_SIT_TEXTURE, + D3D10_SIT_SAMPLER = D3D_SIT_SAMPLER, + D3D11_SIT_UAV_RWTYPED = D3D_SIT_UAV_RWTYPED, + D3D11_SIT_STRUCTURED = D3D_SIT_STRUCTURED, + D3D11_SIT_UAV_RWSTRUCTURED = D3D_SIT_UAV_RWSTRUCTURED, + D3D11_SIT_BYTEADDRESS = D3D_SIT_BYTEADDRESS, + D3D11_SIT_UAV_RWBYTEADDRESS = D3D_SIT_UAV_RWBYTEADDRESS, + D3D11_SIT_UAV_APPEND_STRUCTURED = D3D_SIT_UAV_APPEND_STRUCTURED, + D3D11_SIT_UAV_CONSUME_STRUCTURED = D3D_SIT_UAV_CONSUME_STRUCTURED, + D3D11_SIT_UAV_RWSTRUCTURED_WITH_COUNTER = D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER + } D3D_SHADER_INPUT_TYPE; + +typedef +enum _D3D_SHADER_CBUFFER_FLAGS + { D3D_CBF_USERPACKED = 1, + D3D10_CBF_USERPACKED = D3D_CBF_USERPACKED, + D3D_CBF_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_CBUFFER_FLAGS; + +typedef +enum _D3D_CBUFFER_TYPE + { D3D_CT_CBUFFER = 0, + D3D_CT_TBUFFER = ( D3D_CT_CBUFFER + 1 ) , + D3D_CT_INTERFACE_POINTERS = ( D3D_CT_TBUFFER + 1 ) , + D3D_CT_RESOURCE_BIND_INFO = ( D3D_CT_INTERFACE_POINTERS + 1 ) , + D3D10_CT_CBUFFER = D3D_CT_CBUFFER, + D3D10_CT_TBUFFER = D3D_CT_TBUFFER, + D3D11_CT_CBUFFER = D3D_CT_CBUFFER, + D3D11_CT_TBUFFER = D3D_CT_TBUFFER, + D3D11_CT_INTERFACE_POINTERS = D3D_CT_INTERFACE_POINTERS, + D3D11_CT_RESOURCE_BIND_INFO = D3D_CT_RESOURCE_BIND_INFO + } D3D_CBUFFER_TYPE; + +typedef +enum D3D_NAME + { D3D_NAME_UNDEFINED = 0, + D3D_NAME_POSITION = 1, + D3D_NAME_CLIP_DISTANCE = 2, + D3D_NAME_CULL_DISTANCE = 3, + D3D_NAME_RENDER_TARGET_ARRAY_INDEX = 4, + D3D_NAME_VIEWPORT_ARRAY_INDEX = 5, + D3D_NAME_VERTEX_ID = 6, + D3D_NAME_PRIMITIVE_ID = 7, + D3D_NAME_INSTANCE_ID = 8, + D3D_NAME_IS_FRONT_FACE = 9, + D3D_NAME_SAMPLE_INDEX = 10, + D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR = 11, + D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR = 12, + D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR = 13, + D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR = 14, + D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR = 15, + D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR = 16, + D3D_NAME_TARGET = 64, + D3D_NAME_DEPTH = 65, + D3D_NAME_COVERAGE = 66, + D3D_NAME_DEPTH_GREATER_EQUAL = 67, + D3D_NAME_DEPTH_LESS_EQUAL = 68, + D3D10_NAME_UNDEFINED = D3D_NAME_UNDEFINED, + D3D10_NAME_POSITION = D3D_NAME_POSITION, + D3D10_NAME_CLIP_DISTANCE = D3D_NAME_CLIP_DISTANCE, + D3D10_NAME_CULL_DISTANCE = D3D_NAME_CULL_DISTANCE, + D3D10_NAME_RENDER_TARGET_ARRAY_INDEX = D3D_NAME_RENDER_TARGET_ARRAY_INDEX, + D3D10_NAME_VIEWPORT_ARRAY_INDEX = D3D_NAME_VIEWPORT_ARRAY_INDEX, + D3D10_NAME_VERTEX_ID = D3D_NAME_VERTEX_ID, + D3D10_NAME_PRIMITIVE_ID = D3D_NAME_PRIMITIVE_ID, + D3D10_NAME_INSTANCE_ID = D3D_NAME_INSTANCE_ID, + D3D10_NAME_IS_FRONT_FACE = D3D_NAME_IS_FRONT_FACE, + D3D10_NAME_SAMPLE_INDEX = D3D_NAME_SAMPLE_INDEX, + D3D10_NAME_TARGET = D3D_NAME_TARGET, + D3D10_NAME_DEPTH = D3D_NAME_DEPTH, + D3D10_NAME_COVERAGE = D3D_NAME_COVERAGE, + D3D11_NAME_FINAL_QUAD_EDGE_TESSFACTOR = D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR, + D3D11_NAME_FINAL_QUAD_INSIDE_TESSFACTOR = D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR, + D3D11_NAME_FINAL_TRI_EDGE_TESSFACTOR = D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR, + D3D11_NAME_FINAL_TRI_INSIDE_TESSFACTOR = D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR, + D3D11_NAME_FINAL_LINE_DETAIL_TESSFACTOR = D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR, + D3D11_NAME_FINAL_LINE_DENSITY_TESSFACTOR = D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR, + D3D11_NAME_DEPTH_GREATER_EQUAL = D3D_NAME_DEPTH_GREATER_EQUAL, + D3D11_NAME_DEPTH_LESS_EQUAL = D3D_NAME_DEPTH_LESS_EQUAL + } D3D_NAME; + +typedef +enum D3D_RESOURCE_RETURN_TYPE + { D3D_RETURN_TYPE_UNORM = 1, + D3D_RETURN_TYPE_SNORM = 2, + D3D_RETURN_TYPE_SINT = 3, + D3D_RETURN_TYPE_UINT = 4, + D3D_RETURN_TYPE_FLOAT = 5, + D3D_RETURN_TYPE_MIXED = 6, + D3D_RETURN_TYPE_DOUBLE = 7, + D3D_RETURN_TYPE_CONTINUED = 8, + D3D10_RETURN_TYPE_UNORM = D3D_RETURN_TYPE_UNORM, + D3D10_RETURN_TYPE_SNORM = D3D_RETURN_TYPE_SNORM, + D3D10_RETURN_TYPE_SINT = D3D_RETURN_TYPE_SINT, + D3D10_RETURN_TYPE_UINT = D3D_RETURN_TYPE_UINT, + D3D10_RETURN_TYPE_FLOAT = D3D_RETURN_TYPE_FLOAT, + D3D10_RETURN_TYPE_MIXED = D3D_RETURN_TYPE_MIXED, + D3D11_RETURN_TYPE_UNORM = D3D_RETURN_TYPE_UNORM, + D3D11_RETURN_TYPE_SNORM = D3D_RETURN_TYPE_SNORM, + D3D11_RETURN_TYPE_SINT = D3D_RETURN_TYPE_SINT, + D3D11_RETURN_TYPE_UINT = D3D_RETURN_TYPE_UINT, + D3D11_RETURN_TYPE_FLOAT = D3D_RETURN_TYPE_FLOAT, + D3D11_RETURN_TYPE_MIXED = D3D_RETURN_TYPE_MIXED, + D3D11_RETURN_TYPE_DOUBLE = D3D_RETURN_TYPE_DOUBLE, + D3D11_RETURN_TYPE_CONTINUED = D3D_RETURN_TYPE_CONTINUED + } D3D_RESOURCE_RETURN_TYPE; + +typedef +enum D3D_REGISTER_COMPONENT_TYPE + { D3D_REGISTER_COMPONENT_UNKNOWN = 0, + D3D_REGISTER_COMPONENT_UINT32 = 1, + D3D_REGISTER_COMPONENT_SINT32 = 2, + D3D_REGISTER_COMPONENT_FLOAT32 = 3, + D3D10_REGISTER_COMPONENT_UNKNOWN = D3D_REGISTER_COMPONENT_UNKNOWN, + D3D10_REGISTER_COMPONENT_UINT32 = D3D_REGISTER_COMPONENT_UINT32, + D3D10_REGISTER_COMPONENT_SINT32 = D3D_REGISTER_COMPONENT_SINT32, + D3D10_REGISTER_COMPONENT_FLOAT32 = D3D_REGISTER_COMPONENT_FLOAT32 + } D3D_REGISTER_COMPONENT_TYPE; + +typedef +enum D3D_TESSELLATOR_DOMAIN + { D3D_TESSELLATOR_DOMAIN_UNDEFINED = 0, + D3D_TESSELLATOR_DOMAIN_ISOLINE = 1, + D3D_TESSELLATOR_DOMAIN_TRI = 2, + D3D_TESSELLATOR_DOMAIN_QUAD = 3, + D3D11_TESSELLATOR_DOMAIN_UNDEFINED = D3D_TESSELLATOR_DOMAIN_UNDEFINED, + D3D11_TESSELLATOR_DOMAIN_ISOLINE = D3D_TESSELLATOR_DOMAIN_ISOLINE, + D3D11_TESSELLATOR_DOMAIN_TRI = D3D_TESSELLATOR_DOMAIN_TRI, + D3D11_TESSELLATOR_DOMAIN_QUAD = D3D_TESSELLATOR_DOMAIN_QUAD + } D3D_TESSELLATOR_DOMAIN; + +typedef +enum D3D_TESSELLATOR_PARTITIONING + { D3D_TESSELLATOR_PARTITIONING_UNDEFINED = 0, + D3D_TESSELLATOR_PARTITIONING_INTEGER = 1, + D3D_TESSELLATOR_PARTITIONING_POW2 = 2, + D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = 3, + D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4, + D3D11_TESSELLATOR_PARTITIONING_UNDEFINED = D3D_TESSELLATOR_PARTITIONING_UNDEFINED, + D3D11_TESSELLATOR_PARTITIONING_INTEGER = D3D_TESSELLATOR_PARTITIONING_INTEGER, + D3D11_TESSELLATOR_PARTITIONING_POW2 = D3D_TESSELLATOR_PARTITIONING_POW2, + D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD, + D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN + } D3D_TESSELLATOR_PARTITIONING; + +typedef +enum D3D_TESSELLATOR_OUTPUT_PRIMITIVE + { D3D_TESSELLATOR_OUTPUT_UNDEFINED = 0, + D3D_TESSELLATOR_OUTPUT_POINT = 1, + D3D_TESSELLATOR_OUTPUT_LINE = 2, + D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW = 3, + D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4, + D3D11_TESSELLATOR_OUTPUT_UNDEFINED = D3D_TESSELLATOR_OUTPUT_UNDEFINED, + D3D11_TESSELLATOR_OUTPUT_POINT = D3D_TESSELLATOR_OUTPUT_POINT, + D3D11_TESSELLATOR_OUTPUT_LINE = D3D_TESSELLATOR_OUTPUT_LINE, + D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CW = D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW, + D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CCW = D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW + } D3D_TESSELLATOR_OUTPUT_PRIMITIVE; + +DEFINE_GUID(WKPDID_D3DDebugObjectName,0x429b8c22,0x9188,0x4b0c,0x87,0x42,0xac,0xb0,0xbf,0x85,0xc2,0x00); + + +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0001_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0001_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/builddir/irrlicht-1.8.1/include/D3Dcompiler.h b/builddir/irrlicht-1.8.1/include/D3Dcompiler.h new file mode 100644 index 0000000..fea519f --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/D3Dcompiler.h @@ -0,0 +1,397 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: D3DCompiler.h +// Content: D3D Compilation Types and APIs +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DCOMPILER_H__ +#define __D3DCOMPILER_H__ + +// Current name of the DLL shipped in the same SDK as this header. + + +#define D3DCOMPILER_DLL_W L"d3dcompiler_43.dll" +#define D3DCOMPILER_DLL_A "d3dcompiler_43.dll" + +#ifdef UNICODE + #define D3DCOMPILER_DLL D3DCOMPILER_DLL_W +#else + #define D3DCOMPILER_DLL D3DCOMPILER_DLL_A +#endif + +#include "d3d11shader.h" + +////////////////////////////////////////////////////////////////////////////// +// APIs ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//---------------------------------------------------------------------------- +// D3DCOMPILE flags: +// ----------------- +// D3DCOMPILE_DEBUG +// Insert debug file/line/type/symbol information. +// +// D3DCOMPILE_SKIP_VALIDATION +// Do not validate the generated code against known capabilities and +// constraints. This option is only recommended when compiling shaders +// you KNOW will work. (ie. have compiled before without this option.) +// Shaders are always validated by D3D before they are set to the device. +// +// D3DCOMPILE_SKIP_OPTIMIZATION +// Instructs the compiler to skip optimization steps during code generation. +// Unless you are trying to isolate a problem in your code using this option +// is not recommended. +// +// D3DCOMPILE_PACK_MATRIX_ROW_MAJOR +// Unless explicitly specified, matrices will be packed in row-major order +// on input and output from the shader. +// +// D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR +// Unless explicitly specified, matrices will be packed in column-major +// order on input and output from the shader. This is generally more +// efficient, since it allows vector-matrix multiplication to be performed +// using a series of dot-products. +// +// D3DCOMPILE_PARTIAL_PRECISION +// Force all computations in resulting shader to occur at partial precision. +// This may result in faster evaluation of shaders on some hardware. +// +// D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT +// Force compiler to compile against the next highest available software +// target for vertex shaders. This flag also turns optimizations off, +// and debugging on. +// +// D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT +// Force compiler to compile against the next highest available software +// target for pixel shaders. This flag also turns optimizations off, +// and debugging on. +// +// D3DCOMPILE_NO_PRESHADER +// Disables Preshaders. Using this flag will cause the compiler to not +// pull out static expression for evaluation on the host cpu +// +// D3DCOMPILE_AVOID_FLOW_CONTROL +// Hint compiler to avoid flow-control constructs where possible. +// +// D3DCOMPILE_PREFER_FLOW_CONTROL +// Hint compiler to prefer flow-control constructs where possible. +// +// D3DCOMPILE_ENABLE_STRICTNESS +// By default, the HLSL/Effect compilers are not strict on deprecated syntax. +// Specifying this flag enables the strict mode. Deprecated syntax may be +// removed in a future release, and enabling syntax is a good way to make +// sure your shaders comply to the latest spec. +// +// D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY +// This enables older shaders to compile to 4_0 targets. +// +//---------------------------------------------------------------------------- + +#define D3DCOMPILE_DEBUG (1 << 0) +#define D3DCOMPILE_SKIP_VALIDATION (1 << 1) +#define D3DCOMPILE_SKIP_OPTIMIZATION (1 << 2) +#define D3DCOMPILE_PACK_MATRIX_ROW_MAJOR (1 << 3) +#define D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR (1 << 4) +#define D3DCOMPILE_PARTIAL_PRECISION (1 << 5) +#define D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT (1 << 6) +#define D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT (1 << 7) +#define D3DCOMPILE_NO_PRESHADER (1 << 8) +#define D3DCOMPILE_AVOID_FLOW_CONTROL (1 << 9) +#define D3DCOMPILE_PREFER_FLOW_CONTROL (1 << 10) +#define D3DCOMPILE_ENABLE_STRICTNESS (1 << 11) +#define D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY (1 << 12) +#define D3DCOMPILE_IEEE_STRICTNESS (1 << 13) +#define D3DCOMPILE_OPTIMIZATION_LEVEL0 (1 << 14) +#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0 +#define D3DCOMPILE_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15)) +#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15) +#define D3DCOMPILE_RESERVED16 (1 << 16) +#define D3DCOMPILE_RESERVED17 (1 << 17) +#define D3DCOMPILE_WARNINGS_ARE_ERRORS (1 << 18) + +//---------------------------------------------------------------------------- +// D3DCOMPILE_EFFECT flags: +// ------------------------------------- +// These flags are passed in when creating an effect, and affect +// either compilation behavior or runtime effect behavior +// +// D3DCOMPILE_EFFECT_CHILD_EFFECT +// Compile this .fx file to a child effect. Child effects have no +// initializers for any shared values as these are initialied in the +// master effect (pool). +// +// D3DCOMPILE_EFFECT_ALLOW_SLOW_OPS +// By default, performance mode is enabled. Performance mode +// disallows mutable state objects by preventing non-literal +// expressions from appearing in state object definitions. +// Specifying this flag will disable the mode and allow for mutable +// state objects. +// +//---------------------------------------------------------------------------- + +#define D3DCOMPILE_EFFECT_CHILD_EFFECT (1 << 0) +#define D3DCOMPILE_EFFECT_ALLOW_SLOW_OPS (1 << 1) + +//---------------------------------------------------------------------------- +// D3DCompile: +// ---------- +// Compile source text into bytecode appropriate for the given target. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DCompile(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in_opt LPCSTR pSourceName, + __in_xcount_opt(pDefines->Name != NULL) CONST D3D_SHADER_MACRO* pDefines, + __in_opt ID3DInclude* pInclude, + __in LPCSTR pEntrypoint, + __in LPCSTR pTarget, + __in UINT Flags1, + __in UINT Flags2, + __out ID3DBlob** ppCode, + __out_opt ID3DBlob** ppErrorMsgs); + +typedef HRESULT (WINAPI *pD3DCompile) + (LPCVOID pSrcData, + SIZE_T SrcDataSize, + LPCSTR pFileName, + CONST D3D_SHADER_MACRO* pDefines, + ID3DInclude* pInclude, + LPCSTR pEntrypoint, + LPCSTR pTarget, + UINT Flags1, + UINT Flags2, + ID3DBlob** ppCode, + ID3DBlob** ppErrorMsgs); + +//---------------------------------------------------------------------------- +// D3DPreprocess: +// ---------- +// Process source text with the compiler's preprocessor and return +// the resulting text. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DPreprocess(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in_opt LPCSTR pSourceName, + __in_opt CONST D3D_SHADER_MACRO* pDefines, + __in_opt ID3DInclude* pInclude, + __out ID3DBlob** ppCodeText, + __out_opt ID3DBlob** ppErrorMsgs); + +typedef HRESULT (WINAPI *pD3DPreprocess) + (LPCVOID pSrcData, + SIZE_T SrcDataSize, + LPCSTR pFileName, + CONST D3D_SHADER_MACRO* pDefines, + ID3DInclude* pInclude, + ID3DBlob** ppCodeText, + ID3DBlob** ppErrorMsgs); + +//---------------------------------------------------------------------------- +// D3DGetDebugInfo: +// ----------------------- +// Gets shader debug info. Debug info is generated by D3DCompile and is +// embedded in the body of the shader. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DGetDebugInfo(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __out ID3DBlob** ppDebugInfo); + +//---------------------------------------------------------------------------- +// D3DReflect: +// ---------- +// Shader code contains metadata that can be inspected via the +// reflection APIs. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DReflect(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in REFIID pInterface, + __out void** ppReflector); + +//---------------------------------------------------------------------------- +// D3DDisassemble: +// ---------------------- +// Takes a binary shader and returns a buffer containing text assembly. +//---------------------------------------------------------------------------- + +#define D3D_DISASM_ENABLE_COLOR_CODE 0x00000001 +#define D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS 0x00000002 +#define D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING 0x00000004 +#define D3D_DISASM_ENABLE_INSTRUCTION_CYCLE 0x00000008 +#define D3D_DISASM_DISABLE_DEBUG_INFO 0x00000010 + +HRESULT WINAPI +D3DDisassemble(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in UINT Flags, + __in_opt LPCSTR szComments, + __out ID3DBlob** ppDisassembly); + +typedef HRESULT (WINAPI *pD3DDisassemble) + (__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in UINT Flags, + __in_opt LPCSTR szComments, + __out ID3DBlob** ppDisassembly); + +//---------------------------------------------------------------------------- +// D3DDisassemble10Effect: +// ----------------------- +// Takes a D3D10 effect interface and returns a +// buffer containing text assembly. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DDisassemble10Effect(__in interface ID3D10Effect *pEffect, + __in UINT Flags, + __out ID3DBlob** ppDisassembly); + +//---------------------------------------------------------------------------- +// D3DGetInputSignatureBlob: +// ----------------------- +// Retrieve the input signature from a compilation result. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DGetInputSignatureBlob(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __out ID3DBlob** ppSignatureBlob); + +//---------------------------------------------------------------------------- +// D3DGetOutputSignatureBlob: +// ----------------------- +// Retrieve the output signature from a compilation result. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DGetOutputSignatureBlob(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __out ID3DBlob** ppSignatureBlob); + +//---------------------------------------------------------------------------- +// D3DGetInputAndOutputSignatureBlob: +// ----------------------- +// Retrieve the input and output signatures from a compilation result. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DGetInputAndOutputSignatureBlob(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __out ID3DBlob** ppSignatureBlob); + +//---------------------------------------------------------------------------- +// D3DStripShader: +// ----------------------- +// Removes unwanted blobs from a compilation result +//---------------------------------------------------------------------------- + +typedef enum D3DCOMPILER_STRIP_FLAGS +{ + D3DCOMPILER_STRIP_REFLECTION_DATA = 1, + D3DCOMPILER_STRIP_DEBUG_INFO = 2, + D3DCOMPILER_STRIP_TEST_BLOBS = 4, + D3DCOMPILER_STRIP_FORCE_DWORD = 0x7fffffff, +} D3DCOMPILER_STRIP_FLAGS; + +HRESULT WINAPI +D3DStripShader(__in_bcount(BytecodeLength) LPCVOID pShaderBytecode, + __in SIZE_T BytecodeLength, + __in UINT uStripFlags, + __out ID3DBlob** ppStrippedBlob); + +//---------------------------------------------------------------------------- +// D3DGetBlobPart: +// ----------------------- +// Extracts information from a compilation result. +//---------------------------------------------------------------------------- + +typedef enum D3D_BLOB_PART +{ + D3D_BLOB_INPUT_SIGNATURE_BLOB, + D3D_BLOB_OUTPUT_SIGNATURE_BLOB, + D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB, + D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB, + D3D_BLOB_ALL_SIGNATURE_BLOB, + D3D_BLOB_DEBUG_INFO, + D3D_BLOB_LEGACY_SHADER, + D3D_BLOB_XNA_PREPASS_SHADER, + D3D_BLOB_XNA_SHADER, + + // Test parts are only produced by special compiler versions and so + // are usually not present in shaders. + D3D_BLOB_TEST_ALTERNATE_SHADER = 0x8000, + D3D_BLOB_TEST_COMPILE_DETAILS, + D3D_BLOB_TEST_COMPILE_PERF, +} D3D_BLOB_PART; + +HRESULT WINAPI +D3DGetBlobPart(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in D3D_BLOB_PART Part, + __in UINT Flags, + __out ID3DBlob** ppPart); + +//---------------------------------------------------------------------------- +// D3DCompressShaders: +// ----------------------- +// Compresses a set of shaders into a more compact form. +//---------------------------------------------------------------------------- + +typedef struct _D3D_SHADER_DATA +{ + LPCVOID pBytecode; + SIZE_T BytecodeLength; +} D3D_SHADER_DATA; + +#define D3D_COMPRESS_SHADER_KEEP_ALL_PARTS 0x00000001 + +HRESULT WINAPI +D3DCompressShaders(__in UINT uNumShaders, + __in_ecount(uNumShaders) D3D_SHADER_DATA* pShaderData, + __in UINT uFlags, + __out ID3DBlob** ppCompressedData); + +//---------------------------------------------------------------------------- +// D3DDecompressShaders: +// ----------------------- +// Decompresses one or more shaders from a compressed set. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DDecompressShaders(__in_bcount(SrcDataSize) LPCVOID pSrcData, + __in SIZE_T SrcDataSize, + __in UINT uNumShaders, + __in UINT uStartIndex, + __in_ecount_opt(uNumShaders) UINT* pIndices, + __in UINT uFlags, + __out_ecount(uNumShaders) ID3DBlob** ppShaders, + __out_opt UINT* pTotalShaders); + +//---------------------------------------------------------------------------- +// D3DCreateBlob: +// ----------------------- +// Create an ID3DBlob instance. +//---------------------------------------------------------------------------- + +HRESULT WINAPI +D3DCreateBlob(__in SIZE_T Size, + __out ID3DBlob** ppBlob); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif // #ifndef __D3DCOMPILER_H__ diff --git a/builddir/irrlicht-1.8.1/include/EAttributes.h b/builddir/irrlicht-1.8.1/include/EAttributes.h new file mode 100644 index 0000000..121b6b3 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EAttributes.h @@ -0,0 +1,101 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_ATTRIBUTES_H_INCLUDED__ +#define __E_ATTRIBUTES_H_INCLUDED__ + +namespace irr +{ +namespace io +{ + +//! Types of attributes available for IAttributes +enum E_ATTRIBUTE_TYPE +{ + // integer attribute + EAT_INT = 0, + + // float attribute + EAT_FLOAT, + + // string attribute + EAT_STRING, + + // boolean attribute + EAT_BOOL, + + // enumeration attribute + EAT_ENUM, + + // color attribute + EAT_COLOR, + + // floating point color attribute + EAT_COLORF, + + // 3d vector attribute + EAT_VECTOR3D, + + // 2d position attribute + EAT_POSITION2D, + + // vector 2d attribute + EAT_VECTOR2D, + + // rectangle attribute + EAT_RECT, + + // matrix attribute + EAT_MATRIX, + + // quaternion attribute + EAT_QUATERNION, + + // 3d bounding box + EAT_BBOX, + + // plane + EAT_PLANE, + + // 3d triangle + EAT_TRIANGLE3D, + + // line 2d + EAT_LINE2D, + + // line 3d + EAT_LINE3D, + + // array of stringws attribute + EAT_STRINGWARRAY, + + // array of float + EAT_FLOATARRAY, + + // array of int + EAT_INTARRAY, + + // binary data attribute + EAT_BINARY, + + // texture reference attribute + EAT_TEXTURE, + + // user pointer void* + EAT_USER_POINTER, + + // dimension attribute + EAT_DIMENSION2D, + + // known attribute type count + EAT_COUNT, + + // unknown attribute + EAT_UNKNOWN +}; + +} // end namespace io +} // end namespace irr + +#endif diff --git a/builddir/irrlicht-1.8.1/include/ECullingTypes.h b/builddir/irrlicht-1.8.1/include/ECullingTypes.h new file mode 100644 index 0000000..7178c05 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ECullingTypes.h @@ -0,0 +1,41 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_CULLING_TYPES_H_INCLUDED__ +#define __E_CULLING_TYPES_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace scene +{ + + //! An enumeration for all types of automatic culling for built-in scene nodes + enum E_CULLING_TYPE + { + EAC_OFF = 0, + EAC_BOX = 1, + EAC_FRUSTUM_BOX = 2, + EAC_FRUSTUM_SPHERE = 4, + EAC_OCC_QUERY = 8 + }; + + //! Names for culling type + const c8* const AutomaticCullingNames[] = + { + "false", + "box", // camera box against node box + "frustum_box", // camera frustum against node box + "frustum_sphere", // camera frustum against node sphere + "occ_query", // occlusion query + 0 + }; + +} // end namespace scene +} // end namespace irr + + +#endif // __E_CULLING_TYPES_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/EDebugSceneTypes.h b/builddir/irrlicht-1.8.1/include/EDebugSceneTypes.h new file mode 100644 index 0000000..64ebcaa --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EDebugSceneTypes.h @@ -0,0 +1,50 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_DEBUG_SCENE_TYPES_H_INCLUDED__ +#define __E_DEBUG_SCENE_TYPES_H_INCLUDED__ + +namespace irr +{ +namespace scene +{ + + //! An enumeration for all types of debug data for built-in scene nodes (flags) + enum E_DEBUG_SCENE_TYPE + { + //! No Debug Data ( Default ) + EDS_OFF = 0, + + //! Show Bounding Boxes of SceneNode + EDS_BBOX = 1, + + //! Show Vertex Normals + EDS_NORMALS = 2, + + //! Shows Skeleton/Tags + EDS_SKELETON = 4, + + //! Overlays Mesh Wireframe + EDS_MESH_WIRE_OVERLAY = 8, + + //! Temporary use transparency Material Type + EDS_HALF_TRANSPARENCY = 16, + + //! Show Bounding Boxes of all MeshBuffers + EDS_BBOX_BUFFERS = 32, + + //! EDS_BBOX | EDS_BBOX_BUFFERS + EDS_BBOX_ALL = EDS_BBOX | EDS_BBOX_BUFFERS, + + //! Show all debug infos + EDS_FULL = 0xffffffff + }; + + +} // end namespace scene +} // end namespace irr + + +#endif // __E_DEBUG_SCENE_TYPES_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/EDeviceTypes.h b/builddir/irrlicht-1.8.1/include/EDeviceTypes.h new file mode 100644 index 0000000..d7e9627 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EDeviceTypes.h @@ -0,0 +1,60 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_DEVICE_TYPES_H_INCLUDED__ +#define __E_DEVICE_TYPES_H_INCLUDED__ + +namespace irr +{ + + //! An enum for the different device types supported by the Irrlicht Engine. + enum E_DEVICE_TYPE + { + + //! A device native to Microsoft Windows + /** This device uses the Win32 API and works in all versions of Windows. */ + EIDT_WIN32, + + //! A device native to Windows CE devices + /** This device works on Windows Mobile, Pocket PC and Microsoft SmartPhone devices */ + EIDT_WINCE, + + //! A device native to Unix style operating systems. + /** This device uses the X11 windowing system and works in Linux, Solaris, FreeBSD, OSX and + other operating systems which support X11. */ + EIDT_X11, + + //! A device native to Mac OSX + /** This device uses Apple's Cocoa API and works in Mac OSX 10.2 and above. */ + EIDT_OSX, + + //! A device which uses Simple DirectMedia Layer + /** The SDL device works under all platforms supported by SDL but first must be compiled + in by defining the IRR_USE_SDL_DEVICE macro in IrrCompileConfig.h */ + EIDT_SDL, + + //! A device for raw framebuffer access + /** Best used with embedded devices and mobile systems. + Does not need X11 or other graphical subsystems. + May support hw-acceleration via OpenGL-ES for FBDirect */ + EIDT_FRAMEBUFFER, + + //! A simple text only device supported by all platforms. + /** This device allows applications to run from the command line without opening a window. + It can render the output of the software drivers to the console as ASCII. It only supports + mouse and keyboard in Windows operating systems. */ + EIDT_CONSOLE, + + //! This selection allows Irrlicht to choose the best device from the ones available. + /** If this selection is chosen then Irrlicht will try to use the IrrlichtDevice native + to your operating system. If this is unavailable then the X11, SDL and then console device + will be tried. This ensures that Irrlicht will run even if your platform is unsupported, + although it may not be able to render anything. */ + EIDT_BEST + }; + +} // end namespace irr + +#endif // __E_DEVICE_TYPES_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/EDriverFeatures.h b/builddir/irrlicht-1.8.1/include/EDriverFeatures.h new file mode 100644 index 0000000..931314e --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EDriverFeatures.h @@ -0,0 +1,133 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_DRIVER_FEATURES_H_INCLUDED__ +#define __E_DRIVER_FEATURES_H_INCLUDED__ + +namespace irr +{ +namespace video +{ + + //! enumeration for querying features of the video driver. + enum E_VIDEO_DRIVER_FEATURE + { + //! Is driver able to render to a surface? + EVDF_RENDER_TO_TARGET = 0, + + //! Is hardeware transform and lighting supported? + EVDF_HARDWARE_TL, + + //! Are multiple textures per material possible? + EVDF_MULTITEXTURE, + + //! Is driver able to render with a bilinear filter applied? + EVDF_BILINEAR_FILTER, + + //! Can the driver handle mip maps? + EVDF_MIP_MAP, + + //! Can the driver update mip maps automatically? + EVDF_MIP_MAP_AUTO_UPDATE, + + //! Are stencilbuffers switched on and does the device support stencil buffers? + EVDF_STENCIL_BUFFER, + + //! Is Vertex Shader 1.1 supported? + EVDF_VERTEX_SHADER_1_1, + + //! Is Vertex Shader 2.0 supported? + EVDF_VERTEX_SHADER_2_0, + + //! Is Vertex Shader 3.0 supported? + EVDF_VERTEX_SHADER_3_0, + + //! Is Pixel Shader 1.1 supported? + EVDF_PIXEL_SHADER_1_1, + + //! Is Pixel Shader 1.2 supported? + EVDF_PIXEL_SHADER_1_2, + + //! Is Pixel Shader 1.3 supported? + EVDF_PIXEL_SHADER_1_3, + + //! Is Pixel Shader 1.4 supported? + EVDF_PIXEL_SHADER_1_4, + + //! Is Pixel Shader 2.0 supported? + EVDF_PIXEL_SHADER_2_0, + + //! Is Pixel Shader 3.0 supported? + EVDF_PIXEL_SHADER_3_0, + + //! Are ARB vertex programs v1.0 supported? + EVDF_ARB_VERTEX_PROGRAM_1, + + //! Are ARB fragment programs v1.0 supported? + EVDF_ARB_FRAGMENT_PROGRAM_1, + + //! Is GLSL supported? + EVDF_ARB_GLSL, + + //! Is HLSL supported? + EVDF_HLSL, + + //! Are non-square textures supported? + EVDF_TEXTURE_NSQUARE, + + //! Are non-power-of-two textures supported? + EVDF_TEXTURE_NPOT, + + //! Are framebuffer objects supported? + EVDF_FRAMEBUFFER_OBJECT, + + //! Are vertex buffer objects supported? + EVDF_VERTEX_BUFFER_OBJECT, + + //! Supports Alpha To Coverage + EVDF_ALPHA_TO_COVERAGE, + + //! Supports Color masks (disabling color planes in output) + EVDF_COLOR_MASK, + + //! Supports multiple render targets at once + EVDF_MULTIPLE_RENDER_TARGETS, + + //! Supports separate blend settings for multiple render targets + EVDF_MRT_BLEND, + + //! Supports separate color masks for multiple render targets + EVDF_MRT_COLOR_MASK, + + //! Supports separate blend functions for multiple render targets + EVDF_MRT_BLEND_FUNC, + + //! Supports geometry shaders + EVDF_GEOMETRY_SHADER, + + //! Supports occlusion queries + EVDF_OCCLUSION_QUERY, + + //! Supports polygon offset/depth bias for avoiding z-fighting + EVDF_POLYGON_OFFSET, + + //! Support for different blend functions. Without, only ADD is available + EVDF_BLEND_OPERATIONS, + + //! Support for texture coord transformation via texture matrix + EVDF_TEXTURE_MATRIX, + + //! Support for NVidia's CG shader language + EVDF_CG, + + //! Only used for counting the elements of this enum + EVDF_COUNT + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/EDriverTypes.h b/builddir/irrlicht-1.8.1/include/EDriverTypes.h new file mode 100644 index 0000000..609e261 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EDriverTypes.h @@ -0,0 +1,64 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_DRIVER_TYPES_H_INCLUDED__ +#define __E_DRIVER_TYPES_H_INCLUDED__ + +namespace irr +{ +namespace video +{ + + //! An enum for all types of drivers the Irrlicht Engine supports. + enum E_DRIVER_TYPE + { + //! Null driver, useful for applications to run the engine without visualisation. + /** The null device is able to load textures, but does not + render and display any graphics. */ + EDT_NULL, + + //! The Irrlicht Engine Software renderer. + /** Runs on all platforms, with every hardware. It should only + be used for 2d graphics, but it can also perform some primitive + 3d functions. These 3d drawing functions are quite fast, but + very inaccurate, and don't even support clipping in 3D mode. */ + EDT_SOFTWARE, + + //! The Burning's Software Renderer, an alternative software renderer + /** Basically it can be described as the Irrlicht Software + renderer on steroids. It rasterizes 3D geometry perfectly: It + is able to perform correct 3d clipping, perspective correct + texture mapping, perspective correct color mapping, and renders + sub pixel correct, sub texel correct primitives. In addition, + it does bilinear texel filtering and supports more materials + than the EDT_SOFTWARE driver. This renderer has been written + entirely by Thomas Alten, thanks a lot for this huge + contribution. */ + EDT_BURNINGSVIDEO, + + //! Direct3D8 device, only available on Win32 platforms. + /** Performs hardware accelerated rendering of 3D and 2D + primitives. */ + EDT_DIRECT3D8, + + //! Direct3D 9 device, only available on Win32 platforms. + /** Performs hardware accelerated rendering of 3D and 2D + primitives. */ + EDT_DIRECT3D9, + + //! OpenGL device, available on most platforms. + /** Performs hardware accelerated rendering of 3D and 2D + primitives. */ + EDT_OPENGL, + + //! No driver, just for counting the elements + EDT_COUNT + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/EGUIAlignment.h b/builddir/irrlicht-1.8.1/include/EGUIAlignment.h new file mode 100644 index 0000000..d4caeea --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EGUIAlignment.h @@ -0,0 +1,38 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_GUI_ALIGNMENT_H_INCLUDED__ +#define __E_GUI_ALIGNMENT_H_INCLUDED__ + +namespace irr +{ +namespace gui +{ +enum EGUI_ALIGNMENT +{ + //! Aligned to parent's top or left side (default) + EGUIA_UPPERLEFT=0, + //! Aligned to parent's bottom or right side + EGUIA_LOWERRIGHT, + //! Aligned to the center of parent + EGUIA_CENTER, + //! Stretched to fit parent + EGUIA_SCALE +}; + +//! Names for alignments +const c8* const GUIAlignmentNames[] = +{ + "upperLeft", + "lowerRight", + "center", + "scale", + 0 +}; + +} // namespace gui +} // namespace irr + +#endif // __E_GUI_ALIGNMENT_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/EGUIElementTypes.h b/builddir/irrlicht-1.8.1/include/EGUIElementTypes.h new file mode 100644 index 0000000..aace9e1 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EGUIElementTypes.h @@ -0,0 +1,140 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_GUI_ELEMENT_TYPES_H_INCLUDED__ +#define __E_GUI_ELEMENT_TYPES_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace gui +{ + +//! List of all basic Irrlicht GUI elements. +/** An IGUIElement returns this when calling IGUIElement::getType(); */ +enum EGUI_ELEMENT_TYPE +{ + //! A button (IGUIButton) + EGUIET_BUTTON = 0, + + //! A check box (IGUICheckBox) + EGUIET_CHECK_BOX, + + //! A combo box (IGUIComboBox) + EGUIET_COMBO_BOX, + + //! A context menu (IGUIContextMenu) + EGUIET_CONTEXT_MENU, + + //! A menu (IGUIMenu) + EGUIET_MENU, + + //! An edit box (IGUIEditBox) + EGUIET_EDIT_BOX, + + //! A file open dialog (IGUIFileOpenDialog) + EGUIET_FILE_OPEN_DIALOG, + + //! A color select open dialog (IGUIColorSelectDialog) + EGUIET_COLOR_SELECT_DIALOG, + + //! A in/out fader (IGUIInOutFader) + EGUIET_IN_OUT_FADER, + + //! An image (IGUIImage) + EGUIET_IMAGE, + + //! A list box (IGUIListBox) + EGUIET_LIST_BOX, + + //! A mesh viewer (IGUIMeshViewer) + EGUIET_MESH_VIEWER, + + //! A message box (IGUIWindow) + EGUIET_MESSAGE_BOX, + + //! A modal screen + EGUIET_MODAL_SCREEN, + + //! A scroll bar (IGUIScrollBar) + EGUIET_SCROLL_BAR, + + //! A spin box (IGUISpinBox) + EGUIET_SPIN_BOX, + + //! A static text (IGUIStaticText) + EGUIET_STATIC_TEXT, + + //! A tab (IGUITab) + EGUIET_TAB, + + //! A tab control + EGUIET_TAB_CONTROL, + + //! A Table + EGUIET_TABLE, + + //! A tool bar (IGUIToolBar) + EGUIET_TOOL_BAR, + + //! A Tree View + EGUIET_TREE_VIEW, + + //! A window + EGUIET_WINDOW, + + //! Unknown type. + EGUIET_ELEMENT, + + //! The root of the GUI + EGUIET_ROOT, + + //! Not an element, amount of elements in there + EGUIET_COUNT, + + //! This enum is never used, it only forces the compiler to compile this enumeration to 32 bit. + EGUIET_FORCE_32_BIT = 0x7fffffff + +}; + +//! Names for built-in element types +const c8* const GUIElementTypeNames[] = +{ + "button", + "checkBox", + "comboBox", + "contextMenu", + "menu", + "editBox", + "fileOpenDialog", + "colorSelectDialog", + "inOutFader", + "image", + "listBox", + "meshViewer", + "messageBox", + "modalScreen", + "scrollBar", + "spinBox", + "staticText", + "tab", + "tabControl", + "table", + "toolBar", + "treeview", + "window", + "element", + "root", + 0 +}; + +} // end namespace gui +} // end namespace irr + +#endif + + + + diff --git a/builddir/irrlicht-1.8.1/include/EHardwareBufferFlags.h b/builddir/irrlicht-1.8.1/include/EHardwareBufferFlags.h new file mode 100644 index 0000000..27d5610 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EHardwareBufferFlags.h @@ -0,0 +1,44 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_HARDWARE_BUFFER_FLAGS_INCLUDED__ +#define __E_HARDWARE_BUFFER_FLAGS_INCLUDED__ + +namespace irr +{ +namespace scene +{ + + enum E_HARDWARE_MAPPING + { + //! Don't store on the hardware + EHM_NEVER=0, + + //! Rarely changed, usually stored completely on the hardware + EHM_STATIC, + + //! Sometimes changed, driver optimized placement + EHM_DYNAMIC, + + //! Always changed, cache optimizing on the GPU + EHM_STREAM + }; + + enum E_BUFFER_TYPE + { + //! Does not change anything + EBT_NONE=0, + //! Change the vertex mapping + EBT_VERTEX, + //! Change the index mapping + EBT_INDEX, + //! Change both vertex and index mapping to the same value + EBT_VERTEX_AND_INDEX + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/EMaterialFlags.h b/builddir/irrlicht-1.8.1/include/EMaterialFlags.h new file mode 100644 index 0000000..e336adc --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EMaterialFlags.h @@ -0,0 +1,95 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_MATERIAL_FLAGS_H_INCLUDED__ +#define __E_MATERIAL_FLAGS_H_INCLUDED__ + +namespace irr +{ +namespace video +{ + + //! Material flags + enum E_MATERIAL_FLAG + { + //! Draw as wireframe or filled triangles? Default: false + EMF_WIREFRAME = 0x1, + + //! Draw as point cloud or filled triangles? Default: false + EMF_POINTCLOUD = 0x2, + + //! Flat or Gouraud shading? Default: true + EMF_GOURAUD_SHADING = 0x4, + + //! Will this material be lighted? Default: true + EMF_LIGHTING = 0x8, + + //! Is the ZBuffer enabled? Default: true + EMF_ZBUFFER = 0x10, + + //! May be written to the zbuffer or is it readonly. Default: true + /** This flag is ignored, if the material type is a transparent type. */ + EMF_ZWRITE_ENABLE = 0x20, + + //! Is backface culling enabled? Default: true + EMF_BACK_FACE_CULLING = 0x40, + + //! Is frontface culling enabled? Default: false + /** Overrides EMF_BACK_FACE_CULLING if both are enabled. */ + EMF_FRONT_FACE_CULLING = 0x80, + + //! Is bilinear filtering enabled? Default: true + EMF_BILINEAR_FILTER = 0x100, + + //! Is trilinear filtering enabled? Default: false + /** If the trilinear filter flag is enabled, + the bilinear filtering flag is ignored. */ + EMF_TRILINEAR_FILTER = 0x200, + + //! Is anisotropic filtering? Default: false + /** In Irrlicht you can use anisotropic texture filtering in + conjunction with bilinear or trilinear texture filtering + to improve rendering results. Primitives will look less + blurry with this flag switched on. */ + EMF_ANISOTROPIC_FILTER = 0x400, + + //! Is fog enabled? Default: false + EMF_FOG_ENABLE = 0x800, + + //! Normalizes normals. Default: false + /** You can enable this if you need to scale a dynamic lighted + model. Usually, its normals will get scaled too then and it + will get darker. If you enable the EMF_NORMALIZE_NORMALS flag, + the normals will be normalized again, and the model will look + as bright as it should. */ + EMF_NORMALIZE_NORMALS = 0x1000, + + //! Access to all layers texture wrap settings. Overwrites separate layer settings. + EMF_TEXTURE_WRAP = 0x2000, + + //! AntiAliasing mode + EMF_ANTI_ALIASING = 0x4000, + + //! ColorMask bits, for enabling the color planes + EMF_COLOR_MASK = 0x8000, + + //! ColorMaterial enum for vertex color interpretation + EMF_COLOR_MATERIAL = 0x10000, + + //! Flag for enabling/disabling mipmap usage + EMF_USE_MIP_MAPS = 0x20000, + + //! Flag for blend operation + EMF_BLEND_OPERATION = 0x40000, + + //! Flag for polygon offset + EMF_POLYGON_OFFSET = 0x80000 + }; + +} // end namespace video +} // end namespace irr + + +#endif // __E_MATERIAL_FLAGS_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/EMaterialTypes.h b/builddir/irrlicht-1.8.1/include/EMaterialTypes.h new file mode 100644 index 0000000..5e5e075 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EMaterialTypes.h @@ -0,0 +1,234 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_MATERIAL_TYPES_H_INCLUDED__ +#define __E_MATERIAL_TYPES_H_INCLUDED__ + +namespace irr +{ +namespace video +{ + + //! Abstracted and easy to use fixed function/programmable pipeline material modes. + enum E_MATERIAL_TYPE + { + //! Standard solid material. + /** Only first texture is used, which is supposed to be the + diffuse material. */ + EMT_SOLID = 0, + + //! Solid material with 2 texture layers. + /** The second is blended onto the first using the alpha value + of the vertex colors. This material is currently not implemented in OpenGL. + */ + EMT_SOLID_2_LAYER, + + //! Material type with standard lightmap technique + /** There should be 2 textures: The first texture layer is a + diffuse map, the second is a light map. Dynamic light is + ignored. */ + EMT_LIGHTMAP, + + //! Material type with lightmap technique like EMT_LIGHTMAP. + /** But lightmap and diffuse texture are added instead of modulated. */ + EMT_LIGHTMAP_ADD, + + //! Material type with standard lightmap technique + /** There should be 2 textures: The first texture layer is a + diffuse map, the second is a light map. Dynamic light is + ignored. The texture colors are effectively multiplied by 2 + for brightening. Like known in DirectX as D3DTOP_MODULATE2X. */ + EMT_LIGHTMAP_M2, + + //! Material type with standard lightmap technique + /** There should be 2 textures: The first texture layer is a + diffuse map, the second is a light map. Dynamic light is + ignored. The texture colors are effectively multiplyied by 4 + for brightening. Like known in DirectX as D3DTOP_MODULATE4X. */ + EMT_LIGHTMAP_M4, + + //! Like EMT_LIGHTMAP, but also supports dynamic lighting. + EMT_LIGHTMAP_LIGHTING, + + //! Like EMT_LIGHTMAP_M2, but also supports dynamic lighting. + EMT_LIGHTMAP_LIGHTING_M2, + + //! Like EMT_LIGHTMAP_4, but also supports dynamic lighting. + EMT_LIGHTMAP_LIGHTING_M4, + + //! Detail mapped material. + /** The first texture is diffuse color map, the second is added + to this and usually displayed with a bigger scale value so that + it adds more detail. The detail map is added to the diffuse map + using ADD_SIGNED, so that it is possible to add and substract + color from the diffuse map. For example a value of + (127,127,127) will not change the appearance of the diffuse map + at all. Often used for terrain rendering. */ + EMT_DETAIL_MAP, + + //! Look like a reflection of the environment around it. + /** To make this possible, a texture called 'sphere map' is + used, which must be set as the first texture. */ + EMT_SPHERE_MAP, + + //! A reflecting material with an optional non reflecting texture layer. + /** The reflection map should be set as first texture. */ + EMT_REFLECTION_2_LAYER, + + //! A transparent material. + /** Only the first texture is used. The new color is calculated + by simply adding the source color and the dest color. This + means if for example a billboard using a texture with black + background and a red circle on it is drawn with this material, + the result is that only the red circle will be drawn a little + bit transparent, and everything which was black is 100% + transparent and not visible. This material type is useful for + particle effects. */ + EMT_TRANSPARENT_ADD_COLOR, + + //! Makes the material transparent based on the texture alpha channel. + /** The final color is blended together from the destination + color and the texture color, using the alpha channel value as + blend factor. Only first texture is used. If you are using + this material with small textures, it is a good idea to load + the texture in 32 bit mode + (video::IVideoDriver::setTextureCreationFlag()). Also, an alpha + ref is used, which can be manipulated using + SMaterial::MaterialTypeParam. This value controls how sharp the + edges become when going from a transparent to a solid spot on + the texture. */ + EMT_TRANSPARENT_ALPHA_CHANNEL, + + //! Makes the material transparent based on the texture alpha channel. + /** If the alpha channel value is greater than 127, a + pixel is written to the target, otherwise not. This + material does not use alpha blending and is a lot faster + than EMT_TRANSPARENT_ALPHA_CHANNEL. It is ideal for drawing + stuff like leafes of plants, because the borders are not + blurry but sharp. Only first texture is used. If you are + using this material with small textures and 3d object, it + is a good idea to load the texture in 32 bit mode + (video::IVideoDriver::setTextureCreationFlag()). */ + EMT_TRANSPARENT_ALPHA_CHANNEL_REF, + + //! Makes the material transparent based on the vertex alpha value. + EMT_TRANSPARENT_VERTEX_ALPHA, + + //! A transparent reflecting material with an optional additional non reflecting texture layer. + /** The reflection map should be set as first texture. The + transparency depends on the alpha value in the vertex colors. A + texture which will not reflect can be set as second texture. + Please note that this material type is currently not 100% + implemented in OpenGL. */ + EMT_TRANSPARENT_REFLECTION_2_LAYER, + + //! A solid normal map renderer. + /** First texture is the color map, the second should be the + normal map. Note that you should use this material only when + drawing geometry consisting of vertices of type + S3DVertexTangents (EVT_TANGENTS). You can convert any mesh into + this format using IMeshManipulator::createMeshWithTangents() + (See SpecialFX2 Tutorial). This shader runs on vertex shader + 1.1 and pixel shader 1.1 capable hardware and falls back to a + fixed function lighted material if this hardware is not + available. Only two lights are supported by this shader, if + there are more, the nearest two are chosen. */ + EMT_NORMAL_MAP_SOLID, + + //! A transparent normal map renderer. + /** First texture is the color map, the second should be the + normal map. Note that you should use this material only when + drawing geometry consisting of vertices of type + S3DVertexTangents (EVT_TANGENTS). You can convert any mesh into + this format using IMeshManipulator::createMeshWithTangents() + (See SpecialFX2 Tutorial). This shader runs on vertex shader + 1.1 and pixel shader 1.1 capable hardware and falls back to a + fixed function lighted material if this hardware is not + available. Only two lights are supported by this shader, if + there are more, the nearest two are chosen. */ + EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR, + + //! A transparent (based on the vertex alpha value) normal map renderer. + /** First texture is the color map, the second should be the + normal map. Note that you should use this material only when + drawing geometry consisting of vertices of type + S3DVertexTangents (EVT_TANGENTS). You can convert any mesh into + this format using IMeshManipulator::createMeshWithTangents() + (See SpecialFX2 Tutorial). This shader runs on vertex shader + 1.1 and pixel shader 1.1 capable hardware and falls back to a + fixed function lighted material if this hardware is not + available. Only two lights are supported by this shader, if + there are more, the nearest two are chosen. */ + EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA, + + //! Just like EMT_NORMAL_MAP_SOLID, but uses parallax mapping. + /** Looks a lot more realistic. This only works when the + hardware supports at least vertex shader 1.1 and pixel shader + 1.4. First texture is the color map, the second should be the + normal map. The normal map texture should contain the height + value in the alpha component. The + IVideoDriver::makeNormalMapTexture() method writes this value + automatically when creating normal maps from a heightmap when + using a 32 bit texture. The height scale of the material + (affecting the bumpiness) is being controlled by the + SMaterial::MaterialTypeParam member. If set to zero, the + default value (0.02f) will be applied. Otherwise the value set + in SMaterial::MaterialTypeParam is taken. This value depends on + with which scale the texture is mapped on the material. Too + high or low values of MaterialTypeParam can result in strange + artifacts. */ + EMT_PARALLAX_MAP_SOLID, + + //! A material like EMT_PARALLAX_MAP_SOLID, but transparent. + /** Using EMT_TRANSPARENT_ADD_COLOR as base material. */ + EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR, + + //! A material like EMT_PARALLAX_MAP_SOLID, but transparent. + /** Using EMT_TRANSPARENT_VERTEX_ALPHA as base material. */ + EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA, + + //! BlendFunc = source * sourceFactor + dest * destFactor ( E_BLEND_FUNC ) + /** Using only first texture. Generic blending method. */ + EMT_ONETEXTURE_BLEND, + + //! This value is not used. It only forces this enumeration to compile to 32 bit. + EMT_FORCE_32BIT = 0x7fffffff + }; + + //! Array holding the built in material type names + const char* const sBuiltInMaterialTypeNames[] = + { + "solid", + "solid_2layer", + "lightmap", + "lightmap_add", + "lightmap_m2", + "lightmap_m4", + "lightmap_light", + "lightmap_light_m2", + "lightmap_light_m4", + "detail_map", + "sphere_map", + "reflection_2layer", + "trans_add", + "trans_alphach", + "trans_alphach_ref", + "trans_vertex_alpha", + "trans_reflection_2layer", + "normalmap_solid", + "normalmap_trans_add", + "normalmap_trans_vertexalpha", + "parallaxmap_solid", + "parallaxmap_trans_add", + "parallaxmap_trans_vertexalpha", + "onetexture_blend", + 0 + }; + +} // end namespace video +} // end namespace irr + + +#endif // __E_MATERIAL_TYPES_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/EMeshWriterEnums.h b/builddir/irrlicht-1.8.1/include/EMeshWriterEnums.h new file mode 100644 index 0000000..ceeaa7a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EMeshWriterEnums.h @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_MESH_WRITER_ENUMS_H_INCLUDED__ +#define __E_MESH_WRITER_ENUMS_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace scene +{ + + //! An enumeration for all supported types of built-in mesh writers + /** A scene mesh writers is represented by a four character code + such as 'irrm' or 'coll' instead of simple numbers, to avoid + name clashes with external mesh writers.*/ + enum EMESH_WRITER_TYPE + { + //! Irrlicht native mesh writer, for static .irrmesh files. + EMWT_IRR_MESH = MAKE_IRR_ID('i','r','r','m'), + + //! COLLADA mesh writer for .dae and .xml files + EMWT_COLLADA = MAKE_IRR_ID('c','o','l','l'), + + //! STL mesh writer for .stl files + EMWT_STL = MAKE_IRR_ID('s','t','l',0), + + //! OBJ mesh writer for .obj files + EMWT_OBJ = MAKE_IRR_ID('o','b','j',0), + + //! PLY mesh writer for .ply files + EMWT_PLY = MAKE_IRR_ID('p','l','y',0) + }; + + + //! flags configuring mesh writing + enum E_MESH_WRITER_FLAGS + { + //! no writer flags + EMWF_NONE = 0, + + //! write lightmap textures out if possible + EMWF_WRITE_LIGHTMAPS = 0x1, + + //! write in a way that consumes less disk space + EMWF_WRITE_COMPRESSED = 0x2, + + //! write in binary format rather than text + EMWF_WRITE_BINARY = 0x4 + }; + +} // end namespace scene +} // end namespace irr + + +#endif // __E_MESH_WRITER_ENUMS_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/EMessageBoxFlags.h b/builddir/irrlicht-1.8.1/include/EMessageBoxFlags.h new file mode 100644 index 0000000..ed2d766 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EMessageBoxFlags.h @@ -0,0 +1,36 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_MESSAGE_BOX_FLAGS_H_INCLUDED__ +#define __E_MESSAGE_BOX_FLAGS_H_INCLUDED__ + +namespace irr +{ +namespace gui +{ + +//! enumeration for message box layout flags +enum EMESSAGE_BOX_FLAG +{ + //! Flag for the ok button + EMBF_OK = 0x1, + + //! Flag for the cancel button + EMBF_CANCEL = 0x2, + + //! Flag for the yes button + EMBF_YES = 0x4, + + //! Flag for the no button + EMBF_NO = 0x8, + + //! This value is not used. It only forces this enumeration to compile in 32 bit. + EMBF_FORCE_32BIT = 0x7fffffff +}; + +} // namespace gui +} // namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/EPrimitiveTypes.h b/builddir/irrlicht-1.8.1/include/EPrimitiveTypes.h new file mode 100644 index 0000000..7c61d42 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EPrimitiveTypes.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_PRIMITIVE_TYPES_H_INCLUDED__ +#define __E_PRIMITIVE_TYPES_H_INCLUDED__ + +namespace irr +{ +namespace scene +{ + + //! Enumeration for all primitive types there are. + enum E_PRIMITIVE_TYPE + { + //! All vertices are non-connected points. + EPT_POINTS=0, + + //! All vertices form a single connected line. + EPT_LINE_STRIP, + + //! Just as LINE_STRIP, but the last and the first vertex is also connected. + EPT_LINE_LOOP, + + //! Every two vertices are connected creating n/2 lines. + EPT_LINES, + + //! After the first two vertices each vertex defines a new triangle. + //! Always the two last and the new one form a new triangle. + EPT_TRIANGLE_STRIP, + + //! After the first two vertices each vertex defines a new triangle. + //! All around the common first vertex. + EPT_TRIANGLE_FAN, + + //! Explicitly set all vertices for each triangle. + EPT_TRIANGLES, + + //! After the first two vertices each further tw vetices create a quad with the preceding two. + EPT_QUAD_STRIP, + + //! Every four vertices create a quad. + EPT_QUADS, + + //! Just as LINE_LOOP, but filled. + EPT_POLYGON, + + //! The single vertices are expanded to quad billboards on the GPU. + EPT_POINT_SPRITES + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ESceneNodeAnimatorTypes.h b/builddir/irrlicht-1.8.1/include/ESceneNodeAnimatorTypes.h new file mode 100644 index 0000000..078739d --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ESceneNodeAnimatorTypes.h @@ -0,0 +1,58 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_SCENE_NODE_ANIMATOR_TYPES_H_INCLUDED__ +#define __E_SCENE_NODE_ANIMATOR_TYPES_H_INCLUDED__ + +namespace irr +{ +namespace scene +{ + + //! An enumeration for all types of built-in scene node animators + enum ESCENE_NODE_ANIMATOR_TYPE + { + //! Fly circle scene node animator + ESNAT_FLY_CIRCLE = 0, + + //! Fly straight scene node animator + ESNAT_FLY_STRAIGHT, + + //! Follow spline scene node animator + ESNAT_FOLLOW_SPLINE, + + //! Rotation scene node animator + ESNAT_ROTATION, + + //! Texture scene node animator + ESNAT_TEXTURE, + + //! Deletion scene node animator + ESNAT_DELETION, + + //! Collision respose scene node animator + ESNAT_COLLISION_RESPONSE, + + //! FPS camera animator + ESNAT_CAMERA_FPS, + + //! Maya camera animator + ESNAT_CAMERA_MAYA, + + //! Amount of built-in scene node animators + ESNAT_COUNT, + + //! Unknown scene node animator + ESNAT_UNKNOWN, + + //! This enum is never used, it only forces the compiler to compile this enumeration to 32 bit. + ESNAT_FORCE_32_BIT = 0x7fffffff + }; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ESceneNodeTypes.h b/builddir/irrlicht-1.8.1/include/ESceneNodeTypes.h new file mode 100644 index 0000000..3d43105 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ESceneNodeTypes.h @@ -0,0 +1,106 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_SCENE_NODE_TYPES_H_INCLUDED__ +#define __E_SCENE_NODE_TYPES_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace scene +{ + + //! An enumeration for all types of built-in scene nodes + /** A scene node type is represented by a four character code + such as 'cube' or 'mesh' instead of simple numbers, to avoid + name clashes with external scene nodes.*/ + enum ESCENE_NODE_TYPE + { + //! of type CSceneManager (note that ISceneManager is not(!) an ISceneNode) + ESNT_SCENE_MANAGER = MAKE_IRR_ID('s','m','n','g'), + + //! simple cube scene node + ESNT_CUBE = MAKE_IRR_ID('c','u','b','e'), + + //! Sphere scene node + ESNT_SPHERE = MAKE_IRR_ID('s','p','h','r'), + + //! Text Scene Node + ESNT_TEXT = MAKE_IRR_ID('t','e','x','t'), + + //! Water Surface Scene Node + ESNT_WATER_SURFACE = MAKE_IRR_ID('w','a','t','r'), + + //! Terrain Scene Node + ESNT_TERRAIN = MAKE_IRR_ID('t','e','r','r'), + + //! Sky Box Scene Node + ESNT_SKY_BOX = MAKE_IRR_ID('s','k','y','_'), + + //! Sky Dome Scene Node + ESNT_SKY_DOME = MAKE_IRR_ID('s','k','y','d'), + + //! Shadow Volume Scene Node + ESNT_SHADOW_VOLUME = MAKE_IRR_ID('s','h','d','w'), + + //! Octree Scene Node + ESNT_OCTREE = MAKE_IRR_ID('o','c','t','r'), + + //! Mesh Scene Node + ESNT_MESH = MAKE_IRR_ID('m','e','s','h'), + + //! Light Scene Node + ESNT_LIGHT = MAKE_IRR_ID('l','g','h','t'), + + //! Empty Scene Node + ESNT_EMPTY = MAKE_IRR_ID('e','m','t','y'), + + //! Dummy Transformation Scene Node + ESNT_DUMMY_TRANSFORMATION = MAKE_IRR_ID('d','m','m','y'), + + //! Camera Scene Node + ESNT_CAMERA = MAKE_IRR_ID('c','a','m','_'), + + //! Billboard Scene Node + ESNT_BILLBOARD = MAKE_IRR_ID('b','i','l','l'), + + //! Animated Mesh Scene Node + ESNT_ANIMATED_MESH = MAKE_IRR_ID('a','m','s','h'), + + //! Particle System Scene Node + ESNT_PARTICLE_SYSTEM = MAKE_IRR_ID('p','t','c','l'), + + //! Quake3 Shader Scene Node + ESNT_Q3SHADER_SCENE_NODE = MAKE_IRR_ID('q','3','s','h'), + + //! Quake3 Model Scene Node ( has tag to link to ) + ESNT_MD3_SCENE_NODE = MAKE_IRR_ID('m','d','3','_'), + + //! Volume Light Scene Node + ESNT_VOLUME_LIGHT = MAKE_IRR_ID('v','o','l','l'), + + //! Maya Camera Scene Node + /** Legacy, for loading version <= 1.4.x .irr files */ + ESNT_CAMERA_MAYA = MAKE_IRR_ID('c','a','m','M'), + + //! First Person Shooter Camera + /** Legacy, for loading version <= 1.4.x .irr files */ + ESNT_CAMERA_FPS = MAKE_IRR_ID('c','a','m','F'), + + //! Unknown scene node + ESNT_UNKNOWN = MAKE_IRR_ID('u','n','k','n'), + + //! Will match with any scene node when checking types + ESNT_ANY = MAKE_IRR_ID('a','n','y','_') + }; + + + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/EShaderTypes.h b/builddir/irrlicht-1.8.1/include/EShaderTypes.h new file mode 100644 index 0000000..691930c --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/EShaderTypes.h @@ -0,0 +1,90 @@ +#ifndef __E_SHADER_TYPES_H_INCLUDED__ +#define __E_SHADER_TYPES_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace video +{ + +//! Compile target enumeration for the addHighLevelShaderMaterial() method. +enum E_VERTEX_SHADER_TYPE +{ + EVST_VS_1_1 = 0, + EVST_VS_2_0, + EVST_VS_2_a, + EVST_VS_3_0, + EVST_VS_4_0, + EVST_VS_4_1, + EVST_VS_5_0, + + //! This is not a type, but a value indicating how much types there are. + EVST_COUNT +}; + +//! Names for all vertex shader types, each entry corresponds to a E_VERTEX_SHADER_TYPE entry. +const c8* const VERTEX_SHADER_TYPE_NAMES[] = { + "vs_1_1", + "vs_2_0", + "vs_2_a", + "vs_3_0", + "vs_4_0", + "vs_4_1", + "vs_5_0", + 0 }; + +//! Compile target enumeration for the addHighLevelShaderMaterial() method. +enum E_PIXEL_SHADER_TYPE +{ + EPST_PS_1_1 = 0, + EPST_PS_1_2, + EPST_PS_1_3, + EPST_PS_1_4, + EPST_PS_2_0, + EPST_PS_2_a, + EPST_PS_2_b, + EPST_PS_3_0, + EPST_PS_4_0, + EPST_PS_4_1, + EPST_PS_5_0, + + //! This is not a type, but a value indicating how much types there are. + EPST_COUNT +}; + +//! Names for all pixel shader types, each entry corresponds to a E_PIXEL_SHADER_TYPE entry. +const c8* const PIXEL_SHADER_TYPE_NAMES[] = { + "ps_1_1", + "ps_1_2", + "ps_1_3", + "ps_1_4", + "ps_2_0", + "ps_2_a", + "ps_2_b", + "ps_3_0", + "ps_4_0", + "ps_4_1", + "ps_5_0", + 0 }; + +//! Enum for supported geometry shader types +enum E_GEOMETRY_SHADER_TYPE +{ + EGST_GS_4_0 = 0, + + //! This is not a type, but a value indicating how much types there are. + EGST_COUNT +}; + +//! String names for supported geometry shader types +const c8* const GEOMETRY_SHADER_TYPE_NAMES[] = { + "gs_4_0", + 0 }; + + +} // end namespace video +} // end namespace irr + +#endif // __E_SHADER_TYPES_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/ETerrainElements.h b/builddir/irrlicht-1.8.1/include/ETerrainElements.h new file mode 100644 index 0000000..b09ac39 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ETerrainElements.h @@ -0,0 +1,36 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_TERRAIN_ELEMENTS_H__ +#define __E_TERRAIN_ELEMENTS_H__ + +namespace irr +{ +namespace scene +{ + + //! enumeration for patch sizes specifying the size of patches in the TerrainSceneNode + enum E_TERRAIN_PATCH_SIZE + { + //! patch size of 9, at most, use 4 levels of detail with this patch size. + ETPS_9 = 9, + + //! patch size of 17, at most, use 5 levels of detail with this patch size. + ETPS_17 = 17, + + //! patch size of 33, at most, use 6 levels of detail with this patch size. + ETPS_33 = 33, + + //! patch size of 65, at most, use 7 levels of detail with this patch size. + ETPS_65 = 65, + + //! patch size of 129, at most, use 8 levels of detail with this patch size. + ETPS_129 = 129 + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IAnimatedMesh.h b/builddir/irrlicht-1.8.1/include/IAnimatedMesh.h new file mode 100644 index 0000000..ec6eee0 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IAnimatedMesh.h @@ -0,0 +1,115 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ANIMATED_MESH_H_INCLUDED__ +#define __I_ANIMATED_MESH_H_INCLUDED__ + +#include "aabbox3d.h" +#include "IMesh.h" + +namespace irr +{ +namespace scene +{ + //! Possible types of (animated) meshes. + enum E_ANIMATED_MESH_TYPE + { + //! Unknown animated mesh type. + EAMT_UNKNOWN = 0, + + //! Quake 2 MD2 model file + EAMT_MD2, + + //! Quake 3 MD3 model file + EAMT_MD3, + + //! Maya .obj static model + EAMT_OBJ, + + //! Quake 3 .bsp static Map + EAMT_BSP, + + //! 3D Studio .3ds file + EAMT_3DS, + + //! My3D Mesh, the file format by Zhuck Dimitry + EAMT_MY3D, + + //! Pulsar LMTools .lmts file. This Irrlicht loader was written by Jonas Petersen + EAMT_LMTS, + + //! Cartography Shop .csm file. This loader was created by Saurav Mohapatra. + EAMT_CSM, + + //! .oct file for Paul Nette's FSRad or from Murphy McCauley's Blender .oct exporter. + /** The oct file format contains 3D geometry and lightmaps and + can be loaded directly by Irrlicht */ + EAMT_OCT, + + //! Halflife MDL model file + EAMT_MDL_HALFLIFE, + + //! generic skinned mesh + EAMT_SKINNED + }; + + //! Interface for an animated mesh. + /** There are already simple implementations of this interface available so + you don't have to implement this interface on your own if you need to: + You might want to use irr::scene::SAnimatedMesh, irr::scene::SMesh, + irr::scene::SMeshBuffer etc. */ + class IAnimatedMesh : public IMesh + { + public: + + //! Gets the frame count of the animated mesh. + /** \return The amount of frames. If the amount is 1, + it is a static, non animated mesh. */ + virtual u32 getFrameCount() const = 0; + + //! Gets the animation speed of the animated mesh. + /** \return The number of frames per second to play the + animation with by default. If the amount is 0, + it is a static, non animated mesh. */ + virtual f32 getAnimationSpeed() const = 0; + + //! Sets the animation speed of the animated mesh. + /** \param fps Number of frames per second to play the + animation with by default. If the amount is 0, + it is not animated. The actual speed is set in the + scene node the mesh is instantiated in.*/ + virtual void setAnimationSpeed(f32 fps) =0; + + //! Returns the IMesh interface for a frame. + /** \param frame: Frame number as zero based index. The maximum + frame number is getFrameCount() - 1; + \param detailLevel: Level of detail. 0 is the lowest, 255 the + highest level of detail. Most meshes will ignore the detail level. + \param startFrameLoop: Because some animated meshes (.MD2) are + blended between 2 static frames, and maybe animated in a loop, + the startFrameLoop and the endFrameLoop have to be defined, to + prevent the animation to be blended between frames which are + outside of this loop. + If startFrameLoop and endFrameLoop are both -1, they are ignored. + \param endFrameLoop: see startFrameLoop. + \return Returns the animated mesh based on a detail level. */ + virtual IMesh* getMesh(s32 frame, s32 detailLevel=255, s32 startFrameLoop=-1, s32 endFrameLoop=-1) = 0; + + //! Returns the type of the animated mesh. + /** In most cases it is not neccessary to use this method. + This is useful for making a safe downcast. For example, + if getMeshType() returns EAMT_MD2 it's safe to cast the + IAnimatedMesh to IAnimatedMeshMD2. + \returns Type of the mesh. */ + virtual E_ANIMATED_MESH_TYPE getMeshType() const + { + return EAMT_UNKNOWN; + } + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IAnimatedMeshMD2.h b/builddir/irrlicht-1.8.1/include/IAnimatedMeshMD2.h new file mode 100644 index 0000000..333394e --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IAnimatedMeshMD2.h @@ -0,0 +1,79 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ANIMATED_MESH_MD2_H_INCLUDED__ +#define __I_ANIMATED_MESH_MD2_H_INCLUDED__ + +#include "IAnimatedMesh.h" + +namespace irr +{ +namespace scene +{ + + //! Types of standard md2 animations + enum EMD2_ANIMATION_TYPE + { + EMAT_STAND = 0, + EMAT_RUN, + EMAT_ATTACK, + EMAT_PAIN_A, + EMAT_PAIN_B, + EMAT_PAIN_C, + EMAT_JUMP, + EMAT_FLIP, + EMAT_SALUTE, + EMAT_FALLBACK, + EMAT_WAVE, + EMAT_POINT, + EMAT_CROUCH_STAND, + EMAT_CROUCH_WALK, + EMAT_CROUCH_ATTACK, + EMAT_CROUCH_PAIN, + EMAT_CROUCH_DEATH, + EMAT_DEATH_FALLBACK, + EMAT_DEATH_FALLFORWARD, + EMAT_DEATH_FALLBACKSLOW, + EMAT_BOOM, + + //! Not an animation, but amount of animation types. + EMAT_COUNT + }; + + //! Interface for using some special functions of MD2 meshes + class IAnimatedMeshMD2 : public IAnimatedMesh + { + public: + + //! Get frame loop data for a default MD2 animation type. + /** \param l The EMD2_ANIMATION_TYPE to get the frames for. + \param outBegin The returned beginning frame for animation type specified. + \param outEnd The returned ending frame for the animation type specified. + \param outFPS The number of frames per second, this animation should be played at. + \return beginframe, endframe and frames per second for a default MD2 animation type. */ + virtual void getFrameLoop(EMD2_ANIMATION_TYPE l, s32& outBegin, + s32& outEnd, s32& outFPS) const = 0; + + //! Get frame loop data for a special MD2 animation type, identified by name. + /** \param name Name of the animation. + \param outBegin The returned beginning frame for animation type specified. + \param outEnd The returned ending frame for the animation type specified. + \param outFPS The number of frames per second, this animation should be played at. + \return beginframe, endframe and frames per second for a special MD2 animation type. */ + virtual bool getFrameLoop(const c8* name, + s32& outBegin, s32& outEnd, s32& outFPS) const = 0; + + //! Get amount of md2 animations in this file. + virtual s32 getAnimationCount() const = 0; + + //! Get name of md2 animation. + /** \param nr: Zero based index of animation. */ + virtual const c8* getAnimationName(s32 nr) const = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IAnimatedMeshMD3.h b/builddir/irrlicht-1.8.1/include/IAnimatedMeshMD3.h new file mode 100644 index 0000000..93b24c1 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IAnimatedMeshMD3.h @@ -0,0 +1,304 @@ +// Copyright (C) 2007-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ANIMATED_MESH_MD3_H_INCLUDED__ +#define __I_ANIMATED_MESH_MD3_H_INCLUDED__ + +#include "IAnimatedMesh.h" +#include "IQ3Shader.h" +#include "quaternion.h" + +namespace irr +{ +namespace scene +{ + + enum eMD3Models + { + EMD3_HEAD = 0, + EMD3_UPPER, + EMD3_LOWER, + EMD3_WEAPON, + EMD3_NUMMODELS + }; + + //! Animation list + enum EMD3_ANIMATION_TYPE + { + // Animations for both lower and upper parts of the player + EMD3_BOTH_DEATH_1 = 0, + EMD3_BOTH_DEAD_1, + EMD3_BOTH_DEATH_2, + EMD3_BOTH_DEAD_2, + EMD3_BOTH_DEATH_3, + EMD3_BOTH_DEAD_3, + + // Animations for the upper part + EMD3_TORSO_GESTURE, + EMD3_TORSO_ATTACK_1, + EMD3_TORSO_ATTACK_2, + EMD3_TORSO_DROP, + EMD3_TORSO_RAISE, + EMD3_TORSO_STAND_1, + EMD3_TORSO_STAND_2, + + // Animations for the lower part + EMD3_LEGS_WALK_CROUCH, + EMD3_LEGS_WALK, + EMD3_LEGS_RUN, + EMD3_LEGS_BACK, + EMD3_LEGS_SWIM, + EMD3_LEGS_JUMP_1, + EMD3_LEGS_LAND_1, + EMD3_LEGS_JUMP_2, + EMD3_LEGS_LAND_2, + EMD3_LEGS_IDLE, + EMD3_LEGS_IDLE_CROUCH, + EMD3_LEGS_TURN, + + //! Not an animation, but amount of animation types. + EMD3_ANIMATION_COUNT + }; + + struct SMD3AnimationInfo + { + //! First frame + s32 first; + //! Last frame + s32 num; + //! Looping frames + s32 looping; + //! Frames per second + s32 fps; + }; + + +// byte-align structures +#include "irrpack.h" + + //! this holds the header info of the MD3 file + struct SMD3Header + { + c8 headerID[4]; //id of file, always "IDP3" + s32 Version; //this is a version number, always 15 + s8 fileName[68]; //sometimes left Blank... 65 chars, 32bit aligned == 68 chars + s32 numFrames; //number of KeyFrames + s32 numTags; //number of 'tags' per frame + s32 numMeshes; //number of meshes/skins + s32 numMaxSkins; //maximum number of unique skins used in md3 file. artefact md2 + s32 frameStart; //starting position of frame-structur + s32 tagStart; //starting position of tag-structures + s32 tagEnd; //ending position of tag-structures/starting position of mesh-structures + s32 fileSize; + } PACK_STRUCT; + + //! this holds the header info of an MD3 mesh section + struct SMD3MeshHeader + { + c8 meshID[4]; //id, must be IDP3 + c8 meshName[68]; //name of mesh 65 chars, 32 bit aligned == 68 chars + + s32 numFrames; //number of meshframes in mesh + s32 numShader; //number of skins in mesh + s32 numVertices; //number of vertices + s32 numTriangles; //number of Triangles + + s32 offset_triangles; //starting position of Triangle data, relative to start of Mesh_Header + s32 offset_shaders; //size of header + s32 offset_st; //starting position of texvector data, relative to start of Mesh_Header + s32 vertexStart; //starting position of vertex data,relative to start of Mesh_Header + s32 offset_end; + } PACK_STRUCT; + + + //! Compressed Vertex Data + struct SMD3Vertex + { + s16 position[3]; + u8 normal[2]; + } PACK_STRUCT; + + //! Texture Coordinate + struct SMD3TexCoord + { + f32 u; + f32 v; + } PACK_STRUCT; + + //! Triangle Index + struct SMD3Face + { + s32 Index[3]; + } PACK_STRUCT; + + +// Default alignment +#include "irrunpack.h" + + //! Holding Frame Data for a Mesh + struct SMD3MeshBuffer : public IReferenceCounted + { + SMD3MeshHeader MeshHeader; + + core::stringc Shader; + core::array < s32 > Indices; + core::array < SMD3Vertex > Vertices; + core::array < SMD3TexCoord > Tex; + }; + + //! hold a tag info for connecting meshes + /** Basically its an alternate way to describe a transformation. */ + struct SMD3QuaternionTag + { + virtual ~SMD3QuaternionTag() + { + position.X = 0.f; + } + + // construct copy constructor + SMD3QuaternionTag( const SMD3QuaternionTag & copyMe ) + { + *this = copyMe; + } + + // construct for searching + SMD3QuaternionTag( const core::stringc& name ) + : Name ( name ) {} + + // construct from a position and euler angles in degrees + SMD3QuaternionTag ( const core::vector3df &pos, const core::vector3df &angle ) + : position(pos), rotation(angle * core::DEGTORAD) {} + + // set to matrix + void setto ( core::matrix4 &m ) + { + rotation.getMatrix ( m, position ); + } + + bool operator == ( const SMD3QuaternionTag &other ) const + { + return Name == other.Name; + } + + SMD3QuaternionTag & operator=( const SMD3QuaternionTag & copyMe ) + { + Name = copyMe.Name; + position = copyMe.position; + rotation = copyMe.rotation; + return *this; + } + + core::stringc Name; + core::vector3df position; + core::quaternion rotation; + }; + + //! holds a associative list of named quaternions + struct SMD3QuaternionTagList + { + SMD3QuaternionTagList() + { + Container.setAllocStrategy(core::ALLOC_STRATEGY_SAFE); + } + + // construct copy constructor + SMD3QuaternionTagList(const SMD3QuaternionTagList& copyMe) + { + *this = copyMe; + } + + virtual ~SMD3QuaternionTagList() {} + + SMD3QuaternionTag* get(const core::stringc& name) + { + SMD3QuaternionTag search ( name ); + s32 index = Container.linear_search ( search ); + if ( index >= 0 ) + return &Container[index]; + return 0; + } + + u32 size () const + { + return Container.size(); + } + + void set_used(u32 new_size) + { + s32 diff = (s32) new_size - (s32) Container.allocated_size(); + if ( diff > 0 ) + { + SMD3QuaternionTag e(""); + for ( s32 i = 0; i < diff; ++i ) + Container.push_back(e); + } + } + + const SMD3QuaternionTag& operator[](u32 index) const + { + return Container[index]; + } + + SMD3QuaternionTag& operator[](u32 index) + { + return Container[index]; + } + + void push_back(const SMD3QuaternionTag& other) + { + Container.push_back(other); + } + + SMD3QuaternionTagList& operator = (const SMD3QuaternionTagList & copyMe) + { + Container = copyMe.Container; + return *this; + } + + private: + core::array < SMD3QuaternionTag > Container; + }; + + + //! Holding Frames Buffers and Tag Infos + struct SMD3Mesh: public IReferenceCounted + { + SMD3Mesh () + { + MD3Header.numFrames = 0; + } + + virtual ~SMD3Mesh() + { + for (u32 i=0; i<Buffer.size(); ++i) + Buffer[i]->drop(); + } + + core::stringc Name; + core::array<SMD3MeshBuffer*> Buffer; + SMD3QuaternionTagList TagList; + SMD3Header MD3Header; + }; + + + //! Interface for using some special functions of MD3 meshes + class IAnimatedMeshMD3 : public IAnimatedMesh + { + public: + + //! tune how many frames you want to render inbetween. + virtual void setInterpolationShift(u32 shift, u32 loopMode) =0; + + //! get the tag list of the mesh. + virtual SMD3QuaternionTagList* getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) =0; + + //! get the original md3 mesh. + virtual SMD3Mesh* getOriginalMesh() =0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IAnimatedMeshSceneNode.h b/builddir/irrlicht-1.8.1/include/IAnimatedMeshSceneNode.h new file mode 100644 index 0000000..f34161e --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IAnimatedMeshSceneNode.h @@ -0,0 +1,228 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ANIMATED_MESH_SCENE_NODE_H_INCLUDED__ +#define __I_ANIMATED_MESH_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "IBoneSceneNode.h" +#include "IAnimatedMeshMD2.h" +#include "IAnimatedMeshMD3.h" + +namespace irr +{ +namespace scene +{ + class IShadowVolumeSceneNode; + + enum E_JOINT_UPDATE_ON_RENDER + { + //! do nothing + EJUOR_NONE = 0, + + //! get joints positions from the mesh (for attached nodes, etc) + EJUOR_READ, + + //! control joint positions in the mesh (eg. ragdolls, or set the animation from animateJoints() ) + EJUOR_CONTROL + }; + + + class IAnimatedMeshSceneNode; + + //! Callback interface for catching events of ended animations. + /** Implement this interface and use + IAnimatedMeshSceneNode::setAnimationEndCallback to be able to + be notified if an animation playback has ended. + **/ + class IAnimationEndCallBack : public virtual IReferenceCounted + { + public: + + //! Will be called when the animation playback has ended. + /** See IAnimatedMeshSceneNode::setAnimationEndCallback for + more informations. + \param node: Node of which the animation has ended. */ + virtual void OnAnimationEnd(IAnimatedMeshSceneNode* node) = 0; + }; + + //! Scene node capable of displaying an animated mesh and its shadow. + /** The shadow is optional: If a shadow should be displayed too, just + invoke the IAnimatedMeshSceneNode::createShadowVolumeSceneNode().*/ + class IAnimatedMeshSceneNode : public ISceneNode + { + public: + + //! Constructor + IAnimatedMeshSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) + : ISceneNode(parent, mgr, id, position, rotation, scale) {} + + //! Destructor + virtual ~IAnimatedMeshSceneNode() {} + + //! Sets the current frame number. + /** From now on the animation is played from this frame. + \param frame: Number of the frame to let the animation be started from. + The frame number must be a valid frame number of the IMesh used by this + scene node. Set IAnimatedMesh::getMesh() for details. */ + virtual void setCurrentFrame(f32 frame) = 0; + + //! Sets the frame numbers between the animation is looped. + /** The default is 0 - MaximalFrameCount of the mesh. + \param begin: Start frame number of the loop. + \param end: End frame number of the loop. + \return True if successful, false if not. */ + virtual bool setFrameLoop(s32 begin, s32 end) = 0; + + //! Sets the speed with which the animation is played. + /** \param framesPerSecond: Frames per second played. */ + virtual void setAnimationSpeed(f32 framesPerSecond) = 0; + + //! Gets the speed with which the animation is played. + /** \return Frames per second played. */ + virtual f32 getAnimationSpeed() const =0; + + //! Creates shadow volume scene node as child of this node. + /** The shadow can be rendered using the ZPass or the zfail + method. ZPass is a little bit faster because the shadow volume + creation is easier, but with this method there occur ugly + looking artifacs when the camera is inside the shadow volume. + These error do not occur with the ZFail method. + \param shadowMesh: Optional custom mesh for shadow volume. + \param id: Id of the shadow scene node. This id can be used to + identify the node later. + \param zfailmethod: If set to true, the shadow will use the + zfail method, if not, zpass is used. + \param infinity: Value used by the shadow volume algorithm to + scale the shadow volume (for zfail shadow volume we support only + finite shadows, so camera zfar must be larger than shadow back cap, + which is depend on infinity parameter). + \return Pointer to the created shadow scene node. This pointer + should not be dropped. See IReferenceCounted::drop() for more + information. */ + virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh=0, + s32 id=-1, bool zfailmethod=true, f32 infinity=1000.0f) = 0; + + + //! Get a pointer to a joint in the mesh (if the mesh is a bone based mesh). + /** With this method it is possible to attach scene nodes to + joints for example possible to attach a weapon to the left hand + of an animated model. This example shows how: + \code + ISceneNode* hand = + yourAnimatedMeshSceneNode->getJointNode("LeftHand"); + hand->addChild(weaponSceneNode); + \endcode + Please note that the joint returned by this method may not exist + before this call and the joints in the node were created by it. + \param jointName: Name of the joint. + \return Pointer to the scene node which represents the joint + with the specified name. Returns 0 if the contained mesh is not + an skinned mesh or the name of the joint could not be found. */ + virtual IBoneSceneNode* getJointNode(const c8* jointName)=0; + + //! same as getJointNode(const c8* jointName), but based on id + virtual IBoneSceneNode* getJointNode(u32 jointID) = 0; + + //! Gets joint count. + /** \return Amount of joints in the mesh. */ + virtual u32 getJointCount() const = 0; + + //! Starts a default MD2 animation. + /** With this method it is easily possible to start a Run, + Attack, Die or whatever animation, if the mesh contained in + this scene node is an md2 mesh. Otherwise, nothing happens. + \param anim: An MD2 animation type, which should be played, for + example EMAT_STAND for the standing animation. + \return True if successful, and false if not, for example if + the mesh in the scene node is not a md2 mesh. */ + virtual bool setMD2Animation(EMD2_ANIMATION_TYPE anim) = 0; + + //! Starts a special MD2 animation. + /** With this method it is easily possible to start a Run, + Attack, Die or whatever animation, if the mesh contained in + this scene node is an md2 mesh. Otherwise, nothing happens. + This method uses a character string to identify the animation. + If the animation is a standard md2 animation, you might want to + start this animation with the EMD2_ANIMATION_TYPE enumeration + instead. + \param animationName: Name of the animation which should be + played. + \return Returns true if successful, and false if not, for + example if the mesh in the scene node is not an md2 mesh, or no + animation with this name could be found. */ + virtual bool setMD2Animation(const c8* animationName) = 0; + + //! Returns the currently displayed frame number. + virtual f32 getFrameNr() const = 0; + //! Returns the current start frame number. + virtual s32 getStartFrame() const = 0; + //! Returns the current end frame number. + virtual s32 getEndFrame() const = 0; + + //! Sets looping mode which is on by default. + /** If set to false, animations will not be played looped. */ + virtual void setLoopMode(bool playAnimationLooped) = 0; + + //! returns the current loop mode + /** When true the animations are played looped */ + virtual bool getLoopMode() const = 0; + + //! Sets a callback interface which will be called if an animation playback has ended. + /** Set this to 0 to disable the callback again. + Please note that this will only be called when in non looped + mode, see IAnimatedMeshSceneNode::setLoopMode(). */ + virtual void setAnimationEndCallback(IAnimationEndCallBack* callback=0) = 0; + + //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. + /** In this way it is possible to change the materials a mesh + causing all mesh scene nodes referencing this mesh to change + too. */ + virtual void setReadOnlyMaterials(bool readonly) = 0; + + //! Returns if the scene node should not copy the materials of the mesh but use them in a read only style + virtual bool isReadOnlyMaterials() const = 0; + + //! Sets a new mesh + virtual void setMesh(IAnimatedMesh* mesh) = 0; + + //! Returns the current mesh + virtual IAnimatedMesh* getMesh(void) = 0; + + //! Get the absolute transformation for a special MD3 Tag if the mesh is a md3 mesh, or the absolutetransformation if it's a normal scenenode + virtual const SMD3QuaternionTag* getMD3TagTransformation( const core::stringc & tagname) = 0; + + //! Set how the joints should be updated on render + virtual void setJointMode(E_JOINT_UPDATE_ON_RENDER mode)=0; + + //! Sets the transition time in seconds + /** Note: This needs to enable joints, and setJointmode set to + EJUOR_CONTROL. You must call animateJoints(), or the mesh will + not animate. */ + virtual void setTransitionTime(f32 Time) =0; + + //! animates the joints in the mesh based on the current frame. + /** Also takes in to account transitions. */ + virtual void animateJoints(bool CalculateAbsolutePositions=true) = 0; + + //! render mesh ignoring its transformation. + /** Culling is unaffected. */ + virtual void setRenderFromIdentity( bool On )=0; + + //! Creates a clone of this scene node and its children. + /** \param newParent An optional new parent. + \param newManager An optional new scene manager. + \return The newly created clone of this node. */ + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) = 0; + + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IAttributeExchangingObject.h b/builddir/irrlicht-1.8.1/include/IAttributeExchangingObject.h new file mode 100644 index 0000000..9c64b7d --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IAttributeExchangingObject.h @@ -0,0 +1,71 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ATTRIBUTE_EXCHANGING_OBJECT_H_INCLUDED__ +#define __I_ATTRIBUTE_EXCHANGING_OBJECT_H_INCLUDED__ + +#include "IReferenceCounted.h" + + +namespace irr +{ + +namespace io +{ + +class IAttributes; + +//! Enumeration flags passed through SAttributeReadWriteOptions to the IAttributeExchangingObject object +enum E_ATTRIBUTE_READ_WRITE_FLAGS +{ + //! Serialization/Deserializion is done for an xml file + EARWF_FOR_FILE = 0x00000001, + + //! Serialization/Deserializion is done for an editor property box + EARWF_FOR_EDITOR = 0x00000002, + + //! When writing filenames, relative paths should be used + EARWF_USE_RELATIVE_PATHS = 0x00000004 +}; + + +//! struct holding data describing options +struct SAttributeReadWriteOptions +{ + //! Constructor + SAttributeReadWriteOptions() + : Flags(0), Filename(0) + { + } + + //! Combination of E_ATTRIBUTE_READ_WRITE_FLAGS or other, custom ones + s32 Flags; + + //! Optional filename + const fschar_t* Filename; +}; + + +//! An object which is able to serialize and deserialize its attributes into an attributes object +class IAttributeExchangingObject : virtual public IReferenceCounted +{ +public: + + //! Writes attributes of the object. + /** Implement this to expose the attributes of your scene node animator for + scripting languages, editors, debuggers or xml serialization purposes. */ + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const {} + + //! Reads attributes of the object. + /** Implement this to set the attributes of your scene node animator for + scripting languages, editors, debuggers or xml deserialization purposes. */ + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) {} + +}; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IAttributes.h b/builddir/irrlicht-1.8.1/include/IAttributes.h new file mode 100644 index 0000000..bc77180 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IAttributes.h @@ -0,0 +1,738 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ATTRIBUTES_H_INCLUDED__ +#define __I_ATTRIBUTES_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SColor.h" +#include "vector3d.h" +#include "vector2d.h" +#include "line2d.h" +#include "line3d.h" +#include "triangle3d.h" +#include "position2d.h" +#include "rect.h" +#include "dimension2d.h" +#include "matrix4.h" +#include "quaternion.h" +#include "plane3d.h" +#include "triangle3d.h" +#include "line2d.h" +#include "line3d.h" +#include "irrString.h" +#include "irrArray.h" +#include "IXMLReader.h" +#include "EAttributes.h" +#include "path.h" + +namespace irr +{ +namespace video +{ + class ITexture; +} // end namespace video +namespace io +{ + class IXMLWriter; + +//! Provides a generic interface for attributes and their values and the possiblity to serialize them +class IAttributes : public virtual IReferenceCounted +{ +public: + + //! Returns amount of attributes in this collection of attributes. + virtual u32 getAttributeCount() const = 0; + + //! Returns attribute name by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const c8* getAttributeName(s32 index) = 0; + + //! Returns the type of an attribute + //! \param attributeName: Name for the attribute + virtual E_ATTRIBUTE_TYPE getAttributeType(const c8* attributeName) = 0; + + //! Returns attribute type by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual E_ATTRIBUTE_TYPE getAttributeType(s32 index) = 0; + + //! Returns the type string of the attribute + //! \param attributeName: String for the attribute type + virtual const wchar_t* getAttributeTypeString(const c8* attributeName) = 0; + + //! Returns the type string of the attribute by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const wchar_t* getAttributeTypeString(s32 index) = 0; + + //! Returns if an attribute with a name exists + virtual bool existsAttribute(const c8* attributeName) = 0; + + //! Returns attribute index from name, -1 if not found + virtual s32 findAttribute(const c8* attributeName) const =0; + + //! Removes all attributes + virtual void clear() = 0; + + //! Reads attributes from a xml file. + //! \param reader The XML reader to read from + //! \param readCurrentElementOnly If set to true, reading only works if current element has the name 'attributes' or + //! the name specified using elementName. + //! \param elementName The surrounding element name. If it is null, the default one, "attributes" will be taken. + //! If set to false, the first appearing list of attributes are read. + virtual bool read(io::IXMLReader* reader, bool readCurrentElementOnly=false, const wchar_t* elementName=0) = 0; + + //! Write these attributes into a xml file + //! \param writer: The XML writer to write to + //! \param writeXMLHeader: Writes a header to the XML file, required if at the beginning of the file + //! \param elementName: The surrounding element name. If it is null, the default one, "attributes" will be taken. + virtual bool write(io::IXMLWriter* writer, bool writeXMLHeader=false, const wchar_t* elementName=0) = 0; + + + /* + + Integer Attribute + + */ + + //! Adds an attribute as integer + virtual void addInt(const c8* attributeName, s32 value) = 0; + + //! Sets an attribute as integer value + virtual void setAttribute(const c8* attributeName, s32 value) = 0; + + //! Gets an attribute as integer value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual s32 getAttributeAsInt(const c8* attributeName) const =0; + + //! Gets an attribute as integer value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual s32 getAttributeAsInt(s32 index) const =0; + + //! Sets an attribute as integer value + virtual void setAttribute(s32 index, s32 value) = 0; + + /* + + Float Attribute + + */ + + //! Adds an attribute as float + virtual void addFloat(const c8* attributeName, f32 value) = 0; + + //! Sets a attribute as float value + virtual void setAttribute(const c8* attributeName, f32 value) = 0; + + //! Gets an attribute as float value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual f32 getAttributeAsFloat(const c8* attributeName) = 0; + + //! Gets an attribute as float value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual f32 getAttributeAsFloat(s32 index) = 0; + + //! Sets an attribute as float value + virtual void setAttribute(s32 index, f32 value) = 0; + + /* + + String Attribute + + */ + + //! Adds an attribute as string + virtual void addString(const c8* attributeName, const c8* value) = 0; + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const c8* value) = 0; + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::stringc getAttributeAsString(const c8* attributeName) = 0; + + //! Gets an attribute as string. + //! \param attributeName Name of the attribute to get. + //! \param target Buffer where the string is copied to. + virtual void getAttributeAsString(const c8* attributeName, c8* target) = 0; + + //! Returns attribute value as string by index. + //! \param index Index value, must be between 0 and getAttributeCount()-1. + virtual core::stringc getAttributeAsString(s32 index) = 0; + + //! Sets an attribute value as string. + //! \param index Index value, must be between 0 and getAttributeCount()-1. + //! \param value String to which the attribute is set. + virtual void setAttribute(s32 index, const c8* value) = 0; + + // wide strings + + //! Adds an attribute as string + virtual void addString(const c8* attributeName, const wchar_t* value) = 0; + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const wchar_t* value) = 0; + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::stringw getAttributeAsStringW(const c8* attributeName) = 0; + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \param target: Buffer where the string is copied to. + virtual void getAttributeAsStringW(const c8* attributeName, wchar_t* target) = 0; + + //! Returns attribute value as string by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::stringw getAttributeAsStringW(s32 index) = 0; + + //! Sets an attribute value as string. + //! \param index Index value, must be between 0 and getAttributeCount()-1. + //! \param value String to which the attribute is set. + virtual void setAttribute(s32 index, const wchar_t* value) = 0; + + /* + + Binary Data Attribute + + */ + + //! Adds an attribute as binary data + virtual void addBinary(const c8* attributeName, void* data, s32 dataSizeInBytes) = 0; + + //! Sets an attribute as binary data + virtual void setAttribute(const c8* attributeName, void* data, s32 dataSizeInBytes ) = 0; + + //! Gets an attribute as binary data + /** \param attributeName: Name of the attribute to get. + \param outData Pointer to buffer where data shall be stored. + \param maxSizeInBytes Maximum number of bytes to write into outData. + */ + virtual void getAttributeAsBinaryData(const c8* attributeName, void* outData, s32 maxSizeInBytes) = 0; + + //! Gets an attribute as binary data + /** \param index: Index value, must be between 0 and getAttributeCount()-1. + \param outData Pointer to buffer where data shall be stored. + \param maxSizeInBytes Maximum number of bytes to write into outData. + */ + virtual void getAttributeAsBinaryData(s32 index, void* outData, s32 maxSizeInBytes) = 0; + + //! Sets an attribute as binary data + virtual void setAttribute(s32 index, void* data, s32 dataSizeInBytes ) = 0; + + + /* + Array Attribute + */ + + //! Adds an attribute as wide string array + virtual void addArray(const c8* attributeName, const core::array<core::stringw>& value) = 0; + + //! Sets an attribute value as a wide string array. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const core::array<core::stringw>& value) = 0; + + //! Gets an attribute as an array of wide strings. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::array<core::stringw> getAttributeAsArray(const c8* attributeName) = 0; + + //! Returns attribute value as an array of wide strings by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::array<core::stringw> getAttributeAsArray(s32 index) = 0; + + //! Sets an attribute as an array of wide strings + virtual void setAttribute(s32 index, const core::array<core::stringw>& value) = 0; + + + /* + + Bool Attribute + + */ + + //! Adds an attribute as bool + virtual void addBool(const c8* attributeName, bool value) = 0; + + //! Sets an attribute as boolean value + virtual void setAttribute(const c8* attributeName, bool value) = 0; + + //! Gets an attribute as boolean value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual bool getAttributeAsBool(const c8* attributeName) = 0; + + //! Gets an attribute as boolean value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual bool getAttributeAsBool(s32 index) = 0; + + //! Sets an attribute as boolean value + virtual void setAttribute(s32 index, bool value) = 0; + + /* + + Enumeration Attribute + + */ + + //! Adds an attribute as enum + virtual void addEnum(const c8* attributeName, const c8* enumValue, const c8* const* enumerationLiterals) = 0; + + //! Adds an attribute as enum + virtual void addEnum(const c8* attributeName, s32 enumValue, const c8* const* enumerationLiterals) = 0; + + //! Sets an attribute as enumeration + virtual void setAttribute(const c8* attributeName, const c8* enumValue, const c8* const* enumerationLiterals) = 0; + + //! Gets an attribute as enumeration + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual const c8* getAttributeAsEnumeration(const c8* attributeName) = 0; + + //! Gets an attribute as enumeration + /** \param attributeName: Name of the attribute to get. + \param enumerationLiteralsToUse: Use these enumeration literals to get + the index value instead of the set ones. This is useful when the + attribute list maybe was read from an xml file, and only contains the + enumeration string, but no information about its index. + \return Returns value of the attribute previously set by setAttribute() + */ + virtual s32 getAttributeAsEnumeration(const c8* attributeName, const c8* const* enumerationLiteralsToUse) = 0; + + //! Gets an attribute as enumeration + /** \param index: Index value, must be between 0 and getAttributeCount()-1. + \param enumerationLiteralsToUse: Use these enumeration literals to get + the index value instead of the set ones. This is useful when the + attribute list maybe was read from an xml file, and only contains the + enumeration string, but no information about its index. + \return Returns value of the attribute previously set by setAttribute() + */ + virtual s32 getAttributeAsEnumeration(s32 index, const c8* const* enumerationLiteralsToUse) = 0; + + //! Gets an attribute as enumeration + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const c8* getAttributeAsEnumeration(s32 index) = 0; + + //! Gets the list of enumeration literals of an enumeration attribute + //! \param attributeName Name of the attribute to get. + //! \param outLiterals Set of strings to choose the enum name from. + virtual void getAttributeEnumerationLiteralsOfEnumeration(const c8* attributeName, core::array<core::stringc>& outLiterals) = 0; + + //! Gets the list of enumeration literals of an enumeration attribute + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + //! \param outLiterals Set of strings to choose the enum name from. + virtual void getAttributeEnumerationLiteralsOfEnumeration(s32 index, core::array<core::stringc>& outLiterals) = 0; + + //! Sets an attribute as enumeration + virtual void setAttribute(s32 index, const c8* enumValue, const c8* const* enumerationLiterals) = 0; + + + /* + + SColor Attribute + + */ + + //! Adds an attribute as color + virtual void addColor(const c8* attributeName, video::SColor value) = 0; + + + //! Sets a attribute as color + virtual void setAttribute(const c8* attributeName, video::SColor color) = 0; + + //! Gets an attribute as color + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual video::SColor getAttributeAsColor(const c8* attributeName) = 0; + + //! Gets an attribute as color + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::SColor getAttributeAsColor(s32 index) = 0; + + //! Sets an attribute as color + virtual void setAttribute(s32 index, video::SColor color) = 0; + + /* + + SColorf Attribute + + */ + + //! Adds an attribute as floating point color + virtual void addColorf(const c8* attributeName, video::SColorf value) = 0; + + //! Sets a attribute as floating point color + virtual void setAttribute(const c8* attributeName, video::SColorf color) = 0; + + //! Gets an attribute as floating point color + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual video::SColorf getAttributeAsColorf(const c8* attributeName) = 0; + + //! Gets an attribute as floating point color + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::SColorf getAttributeAsColorf(s32 index) = 0; + + //! Sets an attribute as floating point color + virtual void setAttribute(s32 index, video::SColorf color) = 0; + + + /* + + Vector3d Attribute + + */ + + //! Adds an attribute as 3d vector + virtual void addVector3d(const c8* attributeName, core::vector3df value) = 0; + + //! Sets a attribute as 3d vector + virtual void setAttribute(const c8* attributeName, core::vector3df v) = 0; + + //! Gets an attribute as 3d vector + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::vector3df getAttributeAsVector3d(const c8* attributeName) = 0; + + //! Gets an attribute as 3d vector + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::vector3df getAttributeAsVector3d(s32 index) = 0; + + //! Sets an attribute as vector + virtual void setAttribute(s32 index, core::vector3df v) = 0; + + /* + + Vector2d Attribute + + */ + + //! Adds an attribute as 2d vector + virtual void addVector2d(const c8* attributeName, core::vector2df value) = 0; + + //! Sets a attribute as 2d vector + virtual void setAttribute(const c8* attributeName, core::vector2df v) = 0; + + //! Gets an attribute as vector + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::vector2df getAttributeAsVector2d(const c8* attributeName) = 0; + + //! Gets an attribute as position + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::vector2df getAttributeAsVector2d(s32 index) = 0; + + //! Sets an attribute as 2d vector + virtual void setAttribute(s32 index, core::vector2df v) = 0; + + /* + + Position2d Attribute + + */ + + //! Adds an attribute as 2d position + virtual void addPosition2d(const c8* attributeName, core::position2di value) = 0; + + //! Sets a attribute as 2d position + virtual void setAttribute(const c8* attributeName, core::position2di v) = 0; + + //! Gets an attribute as position + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::position2di getAttributeAsPosition2d(const c8* attributeName) = 0; + + //! Gets an attribute as position + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::position2di getAttributeAsPosition2d(s32 index) = 0; + + //! Sets an attribute as 2d position + virtual void setAttribute(s32 index, core::position2di v) = 0; + + /* + + Rectangle Attribute + + */ + + //! Adds an attribute as rectangle + virtual void addRect(const c8* attributeName, core::rect<s32> value) = 0; + + //! Sets an attribute as rectangle + virtual void setAttribute(const c8* attributeName, core::rect<s32> v) = 0; + + //! Gets an attribute as rectangle + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::rect<s32> getAttributeAsRect(const c8* attributeName) = 0; + + //! Gets an attribute as rectangle + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::rect<s32> getAttributeAsRect(s32 index) = 0; + + //! Sets an attribute as rectangle + virtual void setAttribute(s32 index, core::rect<s32> v) = 0; + + + /* + + Dimension2d Attribute + + */ + + //! Adds an attribute as dimension2d + virtual void addDimension2d(const c8* attributeName, core::dimension2d<u32> value) = 0; + + //! Sets an attribute as dimension2d + virtual void setAttribute(const c8* attributeName, core::dimension2d<u32> v) = 0; + + //! Gets an attribute as dimension2d + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::dimension2d<u32> getAttributeAsDimension2d(const c8* attributeName) = 0; + + //! Gets an attribute as dimension2d + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::dimension2d<u32> getAttributeAsDimension2d(s32 index) = 0; + + //! Sets an attribute as dimension2d + virtual void setAttribute(s32 index, core::dimension2d<u32> v) = 0; + + + /* + matrix attribute + */ + + //! Adds an attribute as matrix + virtual void addMatrix(const c8* attributeName, const core::matrix4& v) = 0; + + //! Sets an attribute as matrix + virtual void setAttribute(const c8* attributeName, const core::matrix4& v) = 0; + + //! Gets an attribute as a matrix4 + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::matrix4 getAttributeAsMatrix(const c8* attributeName) = 0; + + //! Gets an attribute as matrix + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::matrix4 getAttributeAsMatrix(s32 index) = 0; + + //! Sets an attribute as matrix + virtual void setAttribute(s32 index, const core::matrix4& v) = 0; + + /* + quaternion attribute + + */ + + //! Adds an attribute as quaternion + virtual void addQuaternion(const c8* attributeName, core::quaternion v) = 0; + + //! Sets an attribute as quaternion + virtual void setAttribute(const c8* attributeName, core::quaternion v) = 0; + + //! Gets an attribute as a quaternion + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::quaternion getAttributeAsQuaternion(const c8* attributeName) = 0; + + //! Gets an attribute as quaternion + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::quaternion getAttributeAsQuaternion(s32 index) = 0; + + //! Sets an attribute as quaternion + virtual void setAttribute(s32 index, core::quaternion v) = 0; + + /* + + 3d bounding box + + */ + + //! Adds an attribute as axis aligned bounding box + virtual void addBox3d(const c8* attributeName, core::aabbox3df v) = 0; + + //! Sets an attribute as axis aligned bounding box + virtual void setAttribute(const c8* attributeName, core::aabbox3df v) = 0; + + //! Gets an attribute as a axis aligned bounding box + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::aabbox3df getAttributeAsBox3d(const c8* attributeName) = 0; + + //! Gets an attribute as axis aligned bounding box + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::aabbox3df getAttributeAsBox3d(s32 index) = 0; + + //! Sets an attribute as axis aligned bounding box + virtual void setAttribute(s32 index, core::aabbox3df v) = 0; + + /* + + plane + + */ + + //! Adds an attribute as 3d plane + virtual void addPlane3d(const c8* attributeName, core::plane3df v) = 0; + + //! Sets an attribute as 3d plane + virtual void setAttribute(const c8* attributeName, core::plane3df v) = 0; + + //! Gets an attribute as a 3d plane + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::plane3df getAttributeAsPlane3d(const c8* attributeName) = 0; + + //! Gets an attribute as 3d plane + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::plane3df getAttributeAsPlane3d(s32 index) = 0; + + //! Sets an attribute as 3d plane + virtual void setAttribute(s32 index, core::plane3df v) = 0; + + + /* + + 3d triangle + + */ + + //! Adds an attribute as 3d triangle + virtual void addTriangle3d(const c8* attributeName, core::triangle3df v) = 0; + + //! Sets an attribute as 3d trianle + virtual void setAttribute(const c8* attributeName, core::triangle3df v) = 0; + + //! Gets an attribute as a 3d triangle + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::triangle3df getAttributeAsTriangle3d(const c8* attributeName) = 0; + + //! Gets an attribute as 3d triangle + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::triangle3df getAttributeAsTriangle3d(s32 index) = 0; + + //! Sets an attribute as 3d triangle + virtual void setAttribute(s32 index, core::triangle3df v) = 0; + + + /* + + line 2d + + */ + + //! Adds an attribute as a 2d line + virtual void addLine2d(const c8* attributeName, core::line2df v) = 0; + + //! Sets an attribute as a 2d line + virtual void setAttribute(const c8* attributeName, core::line2df v) = 0; + + //! Gets an attribute as a 2d line + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::line2df getAttributeAsLine2d(const c8* attributeName) = 0; + + //! Gets an attribute as a 2d line + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::line2df getAttributeAsLine2d(s32 index) = 0; + + //! Sets an attribute as a 2d line + virtual void setAttribute(s32 index, core::line2df v) = 0; + + + /* + + line 3d + + */ + + //! Adds an attribute as a 3d line + virtual void addLine3d(const c8* attributeName, core::line3df v) = 0; + + //! Sets an attribute as a 3d line + virtual void setAttribute(const c8* attributeName, core::line3df v) = 0; + + //! Gets an attribute as a 3d line + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::line3df getAttributeAsLine3d(const c8* attributeName) = 0; + + //! Gets an attribute as a 3d line + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::line3df getAttributeAsLine3d(s32 index) = 0; + + //! Sets an attribute as a 3d line + virtual void setAttribute(s32 index, core::line3df v) = 0; + + + /* + + Texture Attribute + + */ + + //! Adds an attribute as texture reference + virtual void addTexture(const c8* attributeName, video::ITexture* texture, const io::path& filename = "") = 0; + + //! Sets an attribute as texture reference + virtual void setAttribute(const c8* attributeName, video::ITexture* texture, const io::path& filename = "") = 0; + + //! Gets an attribute as texture reference + //! \param attributeName: Name of the attribute to get. + virtual video::ITexture* getAttributeAsTexture(const c8* attributeName) = 0; + + //! Gets an attribute as texture reference + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::ITexture* getAttributeAsTexture(s32 index) = 0; + + //! Sets an attribute as texture reference + virtual void setAttribute(s32 index, video::ITexture* texture, const io::path& filename = "") = 0; + + + /* + + User Pointer Attribute + + */ + + //! Adds an attribute as user pointner + virtual void addUserPointer(const c8* attributeName, void* userPointer) = 0; + + //! Sets an attribute as user pointer + virtual void setAttribute(const c8* attributeName, void* userPointer) = 0; + + //! Gets an attribute as user pointer + //! \param attributeName: Name of the attribute to get. + virtual void* getAttributeAsUserPointer(const c8* attributeName) = 0; + + //! Gets an attribute as user pointer + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual void* getAttributeAsUserPointer(s32 index) = 0; + + //! Sets an attribute as user pointer + virtual void setAttribute(s32 index, void* userPointer) = 0; + +}; + +} // end namespace io +} // end namespace irr + +#endif + + + diff --git a/builddir/irrlicht-1.8.1/include/IBillboardSceneNode.h b/builddir/irrlicht-1.8.1/include/IBillboardSceneNode.h new file mode 100644 index 0000000..1c931d7 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IBillboardSceneNode.h @@ -0,0 +1,75 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_BILLBOARD_SCENE_NODE_H_INCLUDED__ +#define __I_BILLBOARD_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! A billboard scene node. +/** A billboard is like a 3d sprite: A 2d element, +which always looks to the camera. It is usually used for explosions, fire, +lensflares, particles and things like that. +*/ +class IBillboardSceneNode : public ISceneNode +{ +public: + + //! Constructor + IBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0)) + : ISceneNode(parent, mgr, id, position) {} + + //! Sets the size of the billboard, making it rectangular. + virtual void setSize(const core::dimension2d<f32>& size) = 0; + + //! Sets the size of the billboard with independent widths of the bottom and top edges. + /** \param[in] height The height of the billboard. + \param[in] bottomEdgeWidth The width of the bottom edge of the billboard. + \param[in] topEdgeWidth The width of the top edge of the billboard. + */ + virtual void setSize(f32 height, f32 bottomEdgeWidth, f32 topEdgeWidth) = 0; + + //! Returns the size of the billboard. + /** This will return the width of the bottom edge of the billboard. + Use getWidths() to retrieve the bottom and top edges independently. + \return Size of the billboard. + */ + virtual const core::dimension2d<f32>& getSize() const = 0; + + //! Gets the size of the the billboard and handles independent top and bottom edge widths correctly. + /** \param[out] height The height of the billboard. + \param[out] bottomEdgeWidth The width of the bottom edge of the billboard. + \param[out] topEdgeWidth The width of the top edge of the billboard. + */ + virtual void getSize(f32& height, f32& bottomEdgeWidth, f32& topEdgeWidth) const =0; + + //! Set the color of all vertices of the billboard + /** \param[in] overallColor Color to set */ + virtual void setColor(const video::SColor& overallColor) = 0; + + //! Set the color of the top and bottom vertices of the billboard + /** \param[in] topColor Color to set the top vertices + \param[in] bottomColor Color to set the bottom vertices */ + virtual void setColor(const video::SColor& topColor, + const video::SColor& bottomColor) = 0; + + //! Gets the color of the top and bottom vertices of the billboard + /** \param[out] topColor Stores the color of the top vertices + \param[out] bottomColor Stores the color of the bottom vertices */ + virtual void getColor(video::SColor& topColor, + video::SColor& bottomColor) const = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IBillboardTextSceneNode.h b/builddir/irrlicht-1.8.1/include/IBillboardTextSceneNode.h new file mode 100644 index 0000000..30925da --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IBillboardTextSceneNode.h @@ -0,0 +1,62 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_BILLBOARD_TEXT_SCENE_NODE_H_INCLUDED__ +#define __I_BILLBOARD_TEXT_SCENE_NODE_H_INCLUDED__ + +#include "IBillboardSceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! A billboard text scene node. +/** Acts like a billboard which displays the currently set text. + Due to the exclusion of RTTI in Irrlicht we have to avoid multiple + inheritance. Hence, changes to the ITextSceneNode interface have + to be copied here manually. +*/ +class IBillboardTextSceneNode : public IBillboardSceneNode +{ +public: + + //! Constructor + IBillboardTextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0)) + : IBillboardSceneNode(parent, mgr, id, position) {} + + //! Sets the size of the billboard. + virtual void setSize(const core::dimension2d<f32>& size) = 0; + + //! Returns the size of the billboard. + virtual const core::dimension2d<f32>& getSize() const = 0; + + //! Set the color of all vertices of the billboard + /** \param overallColor: the color to set */ + virtual void setColor(const video::SColor & overallColor) = 0; + + //! Set the color of the top and bottom vertices of the billboard + /** \param topColor: the color to set the top vertices + \param bottomColor: the color to set the bottom vertices */ + virtual void setColor(const video::SColor & topColor, const video::SColor & bottomColor) = 0; + + //! Gets the color of the top and bottom vertices of the billboard + /** \param topColor: stores the color of the top vertices + \param bottomColor: stores the color of the bottom vertices */ + virtual void getColor(video::SColor & topColor, video::SColor & bottomColor) const = 0; + + //! sets the text string + virtual void setText(const wchar_t* text) = 0; + + //! sets the color of the text + virtual void setTextColor(video::SColor color) = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IBoneSceneNode.h b/builddir/irrlicht-1.8.1/include/IBoneSceneNode.h new file mode 100644 index 0000000..d0063b4 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IBoneSceneNode.h @@ -0,0 +1,108 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_BONE_SCENE_NODE_H_INCLUDED__ +#define __I_BONE_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + + //! Enumeration for different bone animation modes + enum E_BONE_ANIMATION_MODE + { + //! The bone is usually animated, unless it's parent is not animated + EBAM_AUTOMATIC=0, + + //! The bone is animated by the skin, if it's parent is not animated then animation will resume from this bone onward + EBAM_ANIMATED, + + //! The bone is not animated by the skin + EBAM_UNANIMATED, + + //! Not an animation mode, just here to count the available modes + EBAM_COUNT + + }; + + enum E_BONE_SKINNING_SPACE + { + //! local skinning, standard + EBSS_LOCAL=0, + + //! global skinning + EBSS_GLOBAL, + + EBSS_COUNT + }; + + //! Names for bone animation modes + const c8* const BoneAnimationModeNames[] = + { + "automatic", + "animated", + "unanimated", + 0, + }; + + + //! Interface for bones used for skeletal animation. + /** Used with ISkinnedMesh and IAnimatedMeshSceneNode. */ + class IBoneSceneNode : public ISceneNode + { + public: + + IBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id=-1) : + ISceneNode(parent, mgr, id),positionHint(-1),scaleHint(-1),rotationHint(-1) { } + + //! Get the name of the bone + /** \deprecated Use getName instead. This method may be removed by Irrlicht 1.9 */ + _IRR_DEPRECATED_ virtual const c8* getBoneName() const { return getName(); } + + //! Get the index of the bone + virtual u32 getBoneIndex() const = 0; + + //! Sets the animation mode of the bone. + /** \return True if successful. (Unused) */ + virtual bool setAnimationMode(E_BONE_ANIMATION_MODE mode) = 0; + + //! Gets the current animation mode of the bone + virtual E_BONE_ANIMATION_MODE getAnimationMode() const = 0; + + //! Get the axis aligned bounding box of this node + virtual const core::aabbox3d<f32>& getBoundingBox() const = 0; + + //! Returns the relative transformation of the scene node. + //virtual core::matrix4 getRelativeTransformation() const = 0; + + //! The animation method. + virtual void OnAnimate(u32 timeMs) =0; + + //! The render method. + /** Does nothing as bones are not visible. */ + virtual void render() { } + + //! How the relative transformation of the bone is used + virtual void setSkinningSpace( E_BONE_SKINNING_SPACE space ) =0; + + //! How the relative transformation of the bone is used + virtual E_BONE_SKINNING_SPACE getSkinningSpace() const =0; + + //! Updates the absolute position based on the relative and the parents position + virtual void updateAbsolutePositionOfAllChildren()=0; + + s32 positionHint; + s32 scaleHint; + s32 rotationHint; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ICameraSceneNode.h b/builddir/irrlicht-1.8.1/include/ICameraSceneNode.h new file mode 100644 index 0000000..dfc1b7a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ICameraSceneNode.h @@ -0,0 +1,207 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_CAMERA_SCENE_NODE_H_INCLUDED__ +#define __I_CAMERA_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "IEventReceiver.h" + +namespace irr +{ +namespace scene +{ + struct SViewFrustum; + + //! Scene Node which is a (controlable) camera. + /** The whole scene will be rendered from the cameras point of view. + Because the ICameraScenNode is a SceneNode, it can be attached to any + other scene node, and will follow its parents movement, rotation and so + on. + */ + class ICameraSceneNode : public ISceneNode, public IEventReceiver + { + public: + + //! Constructor + ICameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f)) + : ISceneNode(parent, mgr, id, position, rotation, scale), IsOrthogonal(false) {} + + //! Sets the projection matrix of the camera. + /** The core::matrix4 class has some methods to build a + projection matrix. e.g: + core::matrix4::buildProjectionMatrixPerspectiveFovLH. + Note that the matrix will only stay as set by this method until + one of the following Methods are called: setNearValue, + setFarValue, setAspectRatio, setFOV. + \param projection The new projection matrix of the camera. + \param isOrthogonal Set this to true if the matrix is an + orthogonal one (e.g. from matrix4::buildProjectionMatrixOrtho). + */ + virtual void setProjectionMatrix(const core::matrix4& projection, bool isOrthogonal=false) =0; + + //! Gets the current projection matrix of the camera. + /** \return The current projection matrix of the camera. */ + virtual const core::matrix4& getProjectionMatrix() const =0; + + //! Gets the current view matrix of the camera. + /** \return The current view matrix of the camera. */ + virtual const core::matrix4& getViewMatrix() const =0; + + //! Sets a custom view matrix affector. + /** The matrix passed here, will be multiplied with the view + matrix when it gets updated. This allows for custom camera + setups like, for example, a reflection camera. + \param affector The affector matrix. */ + virtual void setViewMatrixAffector(const core::matrix4& affector) =0; + + //! Get the custom view matrix affector. + /** \return The affector matrix. */ + virtual const core::matrix4& getViewMatrixAffector() const =0; + + //! It is possible to send mouse and key events to the camera. + /** Most cameras may ignore this input, but camera scene nodes + which are created for example with + ISceneManager::addCameraSceneNodeMaya or + ISceneManager::addCameraSceneNodeFPS, may want to get + this input for changing their position, look at target or + whatever. */ + virtual bool OnEvent(const SEvent& event) =0; + + //! Sets the look at target of the camera + /** If the camera's target and rotation are bound ( @see + bindTargetAndRotation() ) then calling this will also change + the camera's scene node rotation to match the target. + Note that setTarget uses the current absolute position + internally, so if you changed setPosition since last rendering you must + call updateAbsolutePosition before using this function. + \param pos Look at target of the camera, in world co-ordinates. */ + virtual void setTarget(const core::vector3df& pos) =0; + + //! Sets the rotation of the node. + /** This only modifies the relative rotation of the node. + If the camera's target and rotation are bound ( @see + bindTargetAndRotation() ) then calling this will also change + the camera's target to match the rotation. + \param rotation New rotation of the node in degrees. */ + virtual void setRotation(const core::vector3df& rotation) =0; + + //! Gets the current look at target of the camera + /** \return The current look at target of the camera, in world co-ordinates */ + virtual const core::vector3df& getTarget() const =0; + + //! Sets the up vector of the camera. + /** \param pos: New upvector of the camera. */ + virtual void setUpVector(const core::vector3df& pos) =0; + + //! Gets the up vector of the camera. + /** \return The up vector of the camera, in world space. */ + virtual const core::vector3df& getUpVector() const =0; + + //! Gets the value of the near plane of the camera. + /** \return The value of the near plane of the camera. */ + virtual f32 getNearValue() const =0; + + //! Gets the value of the far plane of the camera. + /** \return The value of the far plane of the camera. */ + virtual f32 getFarValue() const =0; + + //! Gets the aspect ratio of the camera. + /** \return The aspect ratio of the camera. */ + virtual f32 getAspectRatio() const =0; + + //! Gets the field of view of the camera. + /** \return The field of view of the camera in radians. */ + virtual f32 getFOV() const =0; + + //! Sets the value of the near clipping plane. (default: 1.0f) + /** \param zn: New z near value. */ + virtual void setNearValue(f32 zn) =0; + + //! Sets the value of the far clipping plane (default: 2000.0f) + /** \param zf: New z far value. */ + virtual void setFarValue(f32 zf) =0; + + //! Sets the aspect ratio (default: 4.0f / 3.0f) + /** \param aspect: New aspect ratio. */ + virtual void setAspectRatio(f32 aspect) =0; + + //! Sets the field of view (Default: PI / 2.5f) + /** \param fovy: New field of view in radians. */ + virtual void setFOV(f32 fovy) =0; + + //! Get the view frustum. + /** Needed sometimes by bspTree or LOD render nodes. + \return The current view frustum. */ + virtual const SViewFrustum* getViewFrustum() const =0; + + //! Disables or enables the camera to get key or mouse inputs. + /** If this is set to true, the camera will respond to key + inputs otherwise not. */ + virtual void setInputReceiverEnabled(bool enabled) =0; + + //! Checks if the input receiver of the camera is currently enabled. + virtual bool isInputReceiverEnabled() const =0; + + //! Checks if a camera is orthogonal. + virtual bool isOrthogonal() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsOrthogonal; + } + + //! Binds the camera scene node's rotation to its target position and vice vera, or unbinds them. + /** When bound, calling setRotation() will update the camera's + target position to be along its +Z axis, and likewise calling + setTarget() will update its rotation so that its +Z axis will + point at the target point. FPS camera use this binding by + default; other cameras do not. + \param bound True to bind the camera's scene node rotation + and targetting, false to unbind them. + @see getTargetAndRotationBinding() */ + virtual void bindTargetAndRotation(bool bound) =0; + + //! Queries if the camera scene node's rotation and its target position are bound together. + /** @see bindTargetAndRotation() */ + virtual bool getTargetAndRotationBinding(void) const =0; + + //! Writes attributes of the camera node + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const + { + ISceneNode::serializeAttributes(out, options); + + if (!out) + return; + out->addBool ("IsOrthogonal", IsOrthogonal ); + } + + //! Reads attributes of the camera node + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) + { + ISceneNode::deserializeAttributes(in, options); + if (!in) + return; + + if ( in->findAttribute("IsOrthogonal") ) + IsOrthogonal = in->getAttributeAsBool("IsOrthogonal"); + } + + protected: + + void cloneMembers(ICameraSceneNode* toCopyFrom) + { + IsOrthogonal = toCopyFrom->IsOrthogonal; + } + + bool IsOrthogonal; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IColladaMeshWriter.h b/builddir/irrlicht-1.8.1/include/IColladaMeshWriter.h new file mode 100644 index 0000000..6b16319 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IColladaMeshWriter.h @@ -0,0 +1,405 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_I_COLLADA_MESH_WRITER_H_INCLUDED__ +#define __IRR_I_COLLADA_MESH_WRITER_H_INCLUDED__ + +#include "IMeshWriter.h" +#include "ISceneNode.h" +#include "IAnimatedMesh.h" +#include "SMaterial.h" + +namespace irr +{ +namespace io +{ + class IWriteFile; +} // end namespace io + +namespace scene +{ + //! Lighting models - more or less the way Collada categorizes materials + enum E_COLLADA_TECHNIQUE_FX + { + //! Blinn-phong which is default for opengl and dx fixed function pipelines. + //! But several well-known renderers don't support it and prefer phong. + ECTF_BLINN, + //! Phong shading, default in many external renderers. + ECTF_PHONG, + //! diffuse shaded surface that is independent of lighting. + ECTF_LAMBERT, + // constantly shaded surface that is independent of lighting. + ECTF_CONSTANT + }; + + //! How to interpret the opacity in collada + enum E_COLLADA_TRANSPARENT_FX + { + //! default - only alpha channel of color or texture is used. + ECOF_A_ONE = 0, + + //! Alpha values for each RGB channel of color or texture are used. + ECOF_RGB_ZERO = 1 + }; + + //! Color names collada uses in it's color samplers + enum E_COLLADA_COLOR_SAMPLER + { + ECCS_DIFFUSE, + ECCS_AMBIENT, + ECCS_EMISSIVE, + ECCS_SPECULAR, + ECCS_TRANSPARENT, + ECCS_REFLECTIVE + }; + + //! Irrlicht colors which can be mapped to E_COLLADA_COLOR_SAMPLER values + enum E_COLLADA_IRR_COLOR + { + //! Don't write this element at all + ECIC_NONE, + + //! Check IColladaMeshWriterProperties for custom color + ECIC_CUSTOM, + + //! Use SMaterial::DiffuseColor + ECIC_DIFFUSE, + + //! Use SMaterial::AmbientColor + ECIC_AMBIENT, + + //! Use SMaterial::EmissiveColor + ECIC_EMISSIVE, + + //! Use SMaterial::SpecularColor + ECIC_SPECULAR + }; + + //! Control when geometry elements are created + enum E_COLLADA_GEOMETRY_WRITING + { + //! Default - write each mesh exactly once to collada. Optimal but will not work with many tools. + ECGI_PER_MESH, + + //! Write each mesh as often as it's used with different materials-names in the scene. + //! Material names which are used here are created on export, so using the IColladaMeshWriterNames + //! interface you have some control over how many geometries are written. + ECGI_PER_MESH_AND_MATERIAL + }; + + //! Callback interface for properties which can be used to influence collada writing + class IColladaMeshWriterProperties : public virtual IReferenceCounted + { + public: + virtual ~IColladaMeshWriterProperties () {} + + //! Which lighting model should be used in the technique (FX) section when exporting effects (materials) + virtual E_COLLADA_TECHNIQUE_FX getTechniqueFx(const video::SMaterial& material) const = 0; + + //! Which texture index should be used when writing the texture of the given sampler color. + /** \return the index to the texture-layer or -1 if that texture should never be exported + Note: for ECCS_TRANSPARENT by default the alpha channel is used, if you want to use RGB you have to set + also the ECOF_RGB_ZERO flag in getTransparentFx. */ + virtual s32 getTextureIdx(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs) const = 0; + + //! Return which color from Irrlicht should be used for the color requested by collada + /** Note that collada allows exporting either texture or color, not both. + So color mapping is only checked if we have no valid texture already. + By default we try to return best fits when possible. For example ECCS_DIFFUSE is mapped to ECIC_DIFFUSE. + When ECIC_CUSTOM is returned then the result of getCustomColor will be used. */ + virtual E_COLLADA_IRR_COLOR getColorMapping(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs) const = 0; + + //! Return custom colors for certain color types requested by collada. + /** Only used when getColorMapping returns ECIC_CUSTOM for the same paramters. */ + virtual video::SColor getCustomColor(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs) const = 0; + + //! Return the transparence color interpretation. + /** Not this is only about ECCS_TRANSPARENT and does not affect getTransparency. */ + virtual E_COLLADA_TRANSPARENT_FX getTransparentFx(const video::SMaterial& material) const = 0; + + //! Transparency value for that material. + /** This value is additional to transparent settings, if both are set they will be multiplicated. + \return 1.0 for fully transparent, 0.0 for not transparent and not written at all when < 0.f */ + virtual f32 getTransparency(const video::SMaterial& material) const = 0; + + //! Reflectivity value for that material + /** The amount of perfect mirror reflection to be added to the reflected light + \return 0.0 - 1.0 for reflectivity and element is not written at all when < 0.f */ + virtual f32 getReflectivity(const video::SMaterial& material) const = 0; + + //! Return index of refraction for that material + /** By default we don't write that. + \return a value greater equal 0.f to write \<index_of_refraction\> when it is lesser than 0 nothing will be written */ + virtual f32 getIndexOfRefraction(const video::SMaterial& material) const = 0; + + //! Should node be used in scene export? (only needed for scene-writing, ignored in mesh-writing) + //! By default all visible nodes are exported. + virtual bool isExportable(const irr::scene::ISceneNode * node) const = 0; + + //! Return the mesh for the given node. If it has no mesh or shouldn't export it's mesh + //! you can return 0 in which case only the transformation matrix of the node will be used. + // Note: Function is not const because there is no const getMesh() function. + virtual IMesh* getMesh(irr::scene::ISceneNode * node) = 0; + + //! Return if the node has it's own material overwriting the mesh-materials + /** Usually true except for mesh-nodes which have isReadOnlyMaterials set. + This is mostly important for naming (as ISceneNode::getMaterial() already returns the correct material). + You have to override it when exporting custom scenenodes with own materials. + \return true => The node's own material is used, false => ignore node material and use the one from the mesh */ + virtual bool useNodeMaterial(const scene::ISceneNode* node) const = 0; + + }; + + //! Callback interface to use custom names on collada writing. + /** You can either modify names and id's written to collada or you can use + this interface to just find out which names are used on writing. + */ + class IColladaMeshWriterNames : public virtual IReferenceCounted + { + public: + + virtual ~IColladaMeshWriterNames () {} + + //! Return a unique name for the given mesh + /** Note that names really must be unique here per mesh-pointer, so + mostly it's a good idea to return the nameForMesh from + IColladaMeshWriter::getDefaultNameGenerator(). Also names must follow + the xs::NCName standard to be valid, you can run them through + IColladaMeshWriter::toNCName to ensure that. + \param mesh Pointer to the mesh which needs a name + \param instance When E_COLLADA_GEOMETRY_WRITING is not ECGI_PER_MESH then + several instances of the same mesh can be written and this counts them. + */ + virtual irr::core::stringw nameForMesh(const scene::IMesh* mesh, int instance) = 0; + + //! Return a unique name for the given node + /** Note that names really must be unique here per node-pointer, so + mostly it's a good idea to return the nameForNode from + IColladaMeshWriter::getDefaultNameGenerator(). Also names must follow + the xs::NCName standard to be valid, you can run them through + IColladaMeshWriter::toNCName to ensure that. + */ + virtual irr::core::stringw nameForNode(const scene::ISceneNode* node) = 0; + + //! Return a name for the material + /** There is one material created in the writer for each unique name. + So you can use this to control the number of materials which get written. + For example Irrlicht does by default write one material for each material + instanced by a node. So if you know that in your application material + instances per node are identical between different nodes you can reduce + the number of exported materials using that knowledge by using identical + names for such shared materials. + Names must follow the xs::NCName standard to be valid, you can run them + through IColladaMeshWriter::toNCName to ensure that. + */ + virtual irr::core::stringw nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node) = 0; + }; + + + //! Interface for writing meshes + class IColladaMeshWriter : public IMeshWriter + { + public: + + IColladaMeshWriter() + : Properties(0), DefaultProperties(0), NameGenerator(0), DefaultNameGenerator(0) + , WriteTextures(true), WriteDefaultScene(true), ExportSMaterialOnce(true) + , AmbientLight(0.f, 0.f, 0.f, 1.f) + , GeometryWriting(ECGI_PER_MESH) + { + } + + //! Destructor + virtual ~IColladaMeshWriter() + { + if ( Properties ) + Properties->drop(); + if ( DefaultProperties ) + DefaultProperties->drop(); + if ( NameGenerator ) + NameGenerator->drop(); + if ( DefaultNameGenerator ) + DefaultNameGenerator->drop(); + } + + //! writes a scene starting with the given node + virtual bool writeScene(io::IWriteFile* file, scene::ISceneNode* root) = 0; + + + //! Set if texture information should be written + virtual void setWriteTextures(bool write) + { + WriteTextures = write; + } + + //! Get if texture information should be written + virtual bool getWriteTextures() const + { + return WriteTextures; + } + + //! Set if a default scene should be written when writing meshes. + /** Many collada readers fail to read a mesh if the collada files doesn't contain a scene as well. + The scene is doing an instantiation of the mesh. + When using writeScene this flag is ignored (as we have scene there already) + */ + virtual void setWriteDefaultScene(bool write) + { + WriteDefaultScene = write; + } + + //! Get if a default scene should be written + virtual bool getWriteDefaultScene() const + { + return WriteDefaultScene; + } + + //! Sets ambient color of the scene to write + virtual void setAmbientLight(const video::SColorf &ambientColor) + { + AmbientLight = ambientColor; + } + + //! Return ambient light of the scene which is written + virtual video::SColorf getAmbientLight() const + { + return AmbientLight; + } + + //! Control when and how often a mesh is written + /** Optimally ECGI_PER_MESH would be always sufficent - writing geometry once per mesh. + Unfortunately many tools (at the time of writing this nearly all of them) have trouble + on import when different materials are used per node. So when you override materials + per node and importing the resuling collada has materials problems in other tools try + using other values here. + \param writeStyle One of the E_COLLADA_GEOMETRY_WRITING settings. + */ + virtual void setGeometryWriting(E_COLLADA_GEOMETRY_WRITING writeStyle) + { + GeometryWriting = writeStyle; + } + + //! Get the current style of geometry writing. + virtual E_COLLADA_GEOMETRY_WRITING getGeometryWriting() const + { + return GeometryWriting; + } + + //! Make certain there is only one collada material generated per Irrlicht material + /** Checks before creating a collada material-name if an identical + irr:::video::SMaterial has been exported already. If so don't export it with + another name. This is set by default and leads to way smaller .dae files. + Note that if you need to disable this flag for some reason you can still + get a similar effect using the IColladaMeshWriterNames::nameForMaterial + by returning identical names for identical materials there. + */ + virtual void setExportSMaterialsOnlyOnce(bool exportOnce) + { + ExportSMaterialOnce = exportOnce; + } + + virtual bool getExportSMaterialsOnlyOnce() const + { + return ExportSMaterialOnce; + } + + //! Set properties to use by the meshwriter instead of it's default properties. + /** Overloading properties with an own class allows modifying the writing process in certain ways. + By default properties are set to the DefaultProperties. */ + virtual void setProperties(IColladaMeshWriterProperties * p) + { + if ( p == Properties ) + return; + if ( p ) + p->grab(); + if ( Properties ) + Properties->drop(); + Properties = p; + } + + //! Get properties which are currently used. + virtual IColladaMeshWriterProperties * getProperties() const + { + return Properties; + } + + //! Return the original default properties of the writer. + /** You can use this pointer in your own properties to access and return default values. */ + IColladaMeshWriterProperties * getDefaultProperties() const + { + return DefaultProperties; + } + + //! Install a generator to create custom names on export. + virtual void setNameGenerator(IColladaMeshWriterNames * nameGenerator) + { + if ( nameGenerator == NameGenerator ) + return; + if ( nameGenerator ) + nameGenerator->grab(); + if ( NameGenerator ) + NameGenerator->drop(); + NameGenerator = nameGenerator; + } + + //! Get currently used name generator + virtual IColladaMeshWriterNames * getNameGenerator() const + { + return NameGenerator; + } + + //! Return the original default name generator of the writer. + /** You can use this pointer in your own generator to access and return default values. */ + IColladaMeshWriterNames * getDefaultNameGenerator() const + { + return DefaultNameGenerator; + } + + //! Restrict the characters of oldString a set of allowed characters in xs::NCName and add the prefix. + /** A tool function to help when using a custom name generator to generative valid names for collada names and id's. */ + virtual irr::core::stringw toNCName(const irr::core::stringw& oldString, const irr::core::stringw& prefix=irr::core::stringw(L"_NC_")) const = 0; + + + protected: + // NOTE: You usually should also call setProperties with the same paraemter when using setDefaultProperties + virtual void setDefaultProperties(IColladaMeshWriterProperties * p) + { + if ( p == DefaultProperties ) + return; + if ( p ) + p->grab(); + if ( DefaultProperties ) + DefaultProperties->drop(); + DefaultProperties = p; + } + + // NOTE: You usually should also call setNameGenerator with the same paraemter when using setDefaultProperties + virtual void setDefaultNameGenerator(IColladaMeshWriterNames * p) + { + if ( p == DefaultNameGenerator ) + return; + if ( p ) + p->grab(); + if ( DefaultNameGenerator ) + DefaultNameGenerator->drop(); + DefaultNameGenerator = p; + } + + private: + IColladaMeshWriterProperties * Properties; + IColladaMeshWriterProperties * DefaultProperties; + IColladaMeshWriterNames * NameGenerator; + IColladaMeshWriterNames * DefaultNameGenerator; + bool WriteTextures; + bool WriteDefaultScene; + bool ExportSMaterialOnce; + video::SColorf AmbientLight; + E_COLLADA_GEOMETRY_WRITING GeometryWriting; + }; + + +} // end namespace +} // end namespace + +#endif diff --git a/builddir/irrlicht-1.8.1/include/ICursorControl.h b/builddir/irrlicht-1.8.1/include/ICursorControl.h new file mode 100644 index 0000000..8e6bc1e --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ICursorControl.h @@ -0,0 +1,192 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_CURSOR_CONTROL_H_INCLUDED__ +#define __I_CURSOR_CONTROL_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "position2d.h" +#include "rect.h" + +namespace irr +{ +namespace gui +{ + + class IGUISpriteBank; + + //! Default icons for cursors + enum ECURSOR_ICON + { + // Following cursors might be system specific, or might use an Irrlicht icon-set. No guarantees so far. + ECI_NORMAL, // arrow + ECI_CROSS, // Crosshair + ECI_HAND, // Hand + ECI_HELP, // Arrow and question mark + ECI_IBEAM, // typical text-selection cursor + ECI_NO, // should not click icon + ECI_WAIT, // hourclass + ECI_SIZEALL, // arrow in all directions + ECI_SIZENESW, // resizes in direction north-east or south-west + ECI_SIZENWSE, // resizes in direction north-west or south-east + ECI_SIZENS, // resizes in direction north or south + ECI_SIZEWE, // resizes in direction west or east + ECI_UP, // up-arrow + + // Implementer note: Should we add system specific cursors, which use guaranteed the system icons, + // then I would recommend using a naming scheme like ECI_W32_CROSS, ECI_X11_CROSSHAIR and adding those + // additionally. + + ECI_COUNT // maximal of defined cursors. Note that higher values can be created at runtime + }; + + //! Names for ECURSOR_ICON + const c8* const GUICursorIconNames[ECI_COUNT+1] = + { + "normal", + "cross", + "hand", + "help", + "ibeam", + "no", + "wait", + "sizeall", + "sizenesw", + "sizenwse", + "sizens", + "sizewe", + "sizeup", + 0 + }; + + //! structure used to set sprites as cursors. + struct SCursorSprite + { + SCursorSprite() + : SpriteBank(0), SpriteId(-1) + { + } + + SCursorSprite( gui::IGUISpriteBank * spriteBank, s32 spriteId, const core::position2d<s32> &hotspot=(core::position2d<s32>(0,0)) ) + : SpriteBank(spriteBank), SpriteId(spriteId), HotSpot(hotspot) + { + } + + IGUISpriteBank * SpriteBank; + s32 SpriteId; + core::position2d<s32> HotSpot; + }; + + //! platform specific behavior flags for the cursor + enum ECURSOR_PLATFORM_BEHAVIOR + { + //! default - no platform specific behavior + ECPB_NONE = 0, + + //! On X11 try caching cursor updates as XQueryPointer calls can be expensive. + /** Update cursor positions only when the irrlicht timer has been updated or the timer is stopped. + This means you usually get one cursor update per device->run() which will be fine in most cases. + See this forum-thread for a more detailed explanation: + http://irrlicht.sourceforge.net/forum/viewtopic.php?f=7&t=45525 + */ + ECPB_X11_CACHE_UPDATES = 1 + }; + + //! Interface to manipulate the mouse cursor. + class ICursorControl : public virtual IReferenceCounted + { + public: + + //! Changes the visible state of the mouse cursor. + /** \param visible: The new visible state. If true, the cursor will be visible, + if false, it will be invisible. */ + virtual void setVisible(bool visible) = 0; + + //! Returns if the cursor is currently visible. + /** \return True if the cursor is visible, false if not. */ + virtual bool isVisible() const = 0; + + //! Sets the new position of the cursor. + /** The position must be + between (0.0f, 0.0f) and (1.0f, 1.0f), where (0.0f, 0.0f) is + the top left corner and (1.0f, 1.0f) is the bottom right corner of the + render window. + \param pos New position of the cursor. */ + virtual void setPosition(const core::position2d<f32> &pos) = 0; + + //! Sets the new position of the cursor. + /** The position must be + between (0.0f, 0.0f) and (1.0f, 1.0f), where (0.0f, 0.0f) is + the top left corner and (1.0f, 1.0f) is the bottom right corner of the + render window. + \param x New x-coord of the cursor. + \param y New x-coord of the cursor. */ + virtual void setPosition(f32 x, f32 y) = 0; + + //! Sets the new position of the cursor. + /** \param pos: New position of the cursor. The coordinates are pixel units. */ + virtual void setPosition(const core::position2d<s32> &pos) = 0; + + //! Sets the new position of the cursor. + /** \param x New x-coord of the cursor. The coordinates are pixel units. + \param y New y-coord of the cursor. The coordinates are pixel units. */ + virtual void setPosition(s32 x, s32 y) = 0; + + //! Returns the current position of the mouse cursor. + /** \return Returns the current position of the cursor. The returned position + is the position of the mouse cursor in pixel units. */ + virtual const core::position2d<s32>& getPosition() = 0; + + //! Returns the current position of the mouse cursor. + /** \return Returns the current position of the cursor. The returned position + is a value between (0.0f, 0.0f) and (1.0f, 1.0f), where (0.0f, 0.0f) is + the top left corner and (1.0f, 1.0f) is the bottom right corner of the + render window. */ + virtual core::position2d<f32> getRelativePosition() = 0; + + //! Sets an absolute reference rect for setting and retrieving the cursor position. + /** If this rect is set, the cursor position is not being calculated relative to + the rendering window but to this rect. You can set the rect pointer to 0 to disable + this feature again. This feature is useful when rendering into parts of foreign windows + for example in an editor. + \param rect: A pointer to an reference rectangle or 0 to disable the reference rectangle.*/ + virtual void setReferenceRect(core::rect<s32>* rect=0) = 0; + + + //! Sets the active cursor icon + /** Setting cursor icons is so far only supported on Win32 and Linux */ + virtual void setActiveIcon(ECURSOR_ICON iconId) {} + + //! Gets the currently active icon + virtual ECURSOR_ICON getActiveIcon() const { return gui::ECI_NORMAL; } + + //! Add a custom sprite as cursor icon. + /** \return Identification for the icon */ + virtual ECURSOR_ICON addIcon(const gui::SCursorSprite& icon) { return gui::ECI_NORMAL; } + + //! replace a cursor icon. + /** Changing cursor icons is so far only supported on Win32 and Linux + Note that this only changes the icons within your application, system cursors outside your + application will not be affected. + */ + virtual void changeIcon(ECURSOR_ICON iconId, const gui::SCursorSprite& sprite) {} + + //! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work. + virtual core::dimension2di getSupportedIconSize() const { return core::dimension2di(0,0); } + + //! Set platform specific behavior flags. + virtual void setPlatformBehavior(ECURSOR_PLATFORM_BEHAVIOR behavior) {} + + //! Return platform specific behavior. + /** \return Behavior set by setPlatformBehavior or ECPB_NONE for platforms not implementing specific behaviors. + */ + virtual ECURSOR_PLATFORM_BEHAVIOR getPlatformBehavior() const { return ECPB_NONE; } + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IDummyTransformationSceneNode.h b/builddir/irrlicht-1.8.1/include/IDummyTransformationSceneNode.h new file mode 100644 index 0000000..d5e7f00 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IDummyTransformationSceneNode.h @@ -0,0 +1,42 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_DUMMY_TRANSFORMATION_SCENE_NODE_H_INCLUDED__ +#define __I_DUMMY_TRANSFORMATION_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! Dummy scene node for adding additional transformations to the scene graph. +/** This scene node does not render itself, and does not respond to set/getPosition, +set/getRotation and set/getScale. Its just a simple scene node that takes a +matrix as relative transformation, making it possible to insert any transformation +anywhere into the scene graph. +This scene node is for example used by the IAnimatedMeshSceneNode for emulating +joint scene nodes when playing skeletal animations. +*/ +class IDummyTransformationSceneNode : public ISceneNode +{ +public: + + //! Constructor + IDummyTransformationSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) + : ISceneNode(parent, mgr, id) {} + + //! Returns a reference to the current relative transformation matrix. + /** This is the matrix, this scene node uses instead of scale, translation + and rotation. */ + virtual core::matrix4& getRelativeTransformationMatrix() = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IDynamicMeshBuffer.h b/builddir/irrlicht-1.8.1/include/IDynamicMeshBuffer.h new file mode 100644 index 0000000..24434df --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IDynamicMeshBuffer.h @@ -0,0 +1,211 @@ +// Copyright (C) 2008-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_DYNAMIC_MESH_BUFFER_H_INCLUDED__ +#define __I_DYNAMIC_MESH_BUFFER_H_INCLUDED__ + +#include "IMeshBuffer.h" +#include "IVertexBuffer.h" +#include "IIndexBuffer.h" + +namespace irr +{ +namespace scene +{ + + /** a dynamic meshBuffer */ + class IDynamicMeshBuffer : public IMeshBuffer + { + public: + virtual IVertexBuffer &getVertexBuffer() const =0; + virtual IIndexBuffer &getIndexBuffer() const =0; + + virtual void setVertexBuffer(IVertexBuffer *vertexBuffer) =0; + virtual void setIndexBuffer(IIndexBuffer *indexBuffer) =0; + + //! Get the material of this meshbuffer + /** \return Material of this buffer. */ + virtual video::SMaterial& getMaterial() =0; + + //! Get the material of this meshbuffer + /** \return Material of this buffer. */ + virtual const video::SMaterial& getMaterial() const =0; + + //! Get the axis aligned bounding box of this meshbuffer. + /** \return Axis aligned bounding box of this buffer. */ + virtual const core::aabbox3df& getBoundingBox() const =0; + + //! Set axis aligned bounding box + /** \param box User defined axis aligned bounding box to use + for this buffer. */ + virtual void setBoundingBox(const core::aabbox3df& box) =0; + + //! Recalculates the bounding box. Should be called if the mesh changed. + virtual void recalculateBoundingBox() =0; + + //! Append the vertices and indices to the current buffer + /** Only works for compatible vertex types. + \param vertices Pointer to a vertex array. + \param numVertices Number of vertices in the array. + \param indices Pointer to index array. + \param numIndices Number of indices in array. */ + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) + { + + } + + //! Append the meshbuffer to the current buffer + /** Only works for compatible vertex types + \param other Buffer to append to this one. */ + virtual void append(const IMeshBuffer* const other) + { + + } + + // ------------------- To be removed? ------------------- // + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const + { + return getVertexBuffer().getHardwareMappingHint(); + } + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint_Index() const + { + return getIndexBuffer().getHardwareMappingHint(); + } + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX ) + { + if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_VERTEX) + getVertexBuffer().setHardwareMappingHint(NewMappingHint); + if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_INDEX) + getIndexBuffer().setHardwareMappingHint(NewMappingHint); + } + + //! flags the mesh as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX) + { + if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_VERTEX) + getVertexBuffer().setDirty(); + if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_INDEX) + getIndexBuffer().setDirty(); + } + + virtual u32 getChangedID_Vertex() const + { + return getVertexBuffer().getChangedID(); + } + + virtual u32 getChangedID_Index() const + { + return getIndexBuffer().getChangedID(); + } + + // ------------------- Old interface ------------------- // + + //! Get type of vertex data which is stored in this meshbuffer. + /** \return Vertex type of this buffer. */ + virtual video::E_VERTEX_TYPE getVertexType() const + { + return getVertexBuffer().getType(); + } + + //! Get access to vertex data. The data is an array of vertices. + /** Which vertex type is used can be determined by getVertexType(). + \return Pointer to array of vertices. */ + virtual const void* getVertices() const + { + return getVertexBuffer().getData(); + } + + //! Get access to vertex data. The data is an array of vertices. + /** Which vertex type is used can be determined by getVertexType(). + \return Pointer to array of vertices. */ + virtual void* getVertices() + { + return getVertexBuffer().getData(); + } + + //! Get amount of vertices in meshbuffer. + /** \return Number of vertices in this buffer. */ + virtual u32 getVertexCount() const + { + return getVertexBuffer().size(); + } + + //! Get type of index data which is stored in this meshbuffer. + /** \return Index type of this buffer. */ + virtual video::E_INDEX_TYPE getIndexType() const + { + return getIndexBuffer().getType(); + } + + //! Get access to Indices. + /** \return Pointer to indices array. */ + virtual const u16* getIndices() const + { + return (u16*)getIndexBuffer().getData(); + } + + //! Get access to Indices. + /** \return Pointer to indices array. */ + virtual u16* getIndices() + { + return (u16*)getIndexBuffer().getData(); + } + + //! Get amount of indices in this meshbuffer. + /** \return Number of indices in this buffer. */ + virtual u32 getIndexCount() const + { + return getIndexBuffer().size(); + } + + //! returns position of vertex i + virtual const core::vector3df& getPosition(u32 i) const + { + return getVertexBuffer()[i].Pos; + } + + //! returns position of vertex i + virtual core::vector3df& getPosition(u32 i) + { + return getVertexBuffer()[i].Pos; + } + + //! returns texture coords of vertex i + virtual const core::vector2df& getTCoords(u32 i) const + { + return getVertexBuffer()[i].TCoords; + } + + //! returns texture coords of vertex i + virtual core::vector2df& getTCoords(u32 i) + { + return getVertexBuffer()[i].TCoords; + } + + //! returns normal of vertex i + virtual const core::vector3df& getNormal(u32 i) const + { + return getVertexBuffer()[i].Normal; + } + + //! returns normal of vertex i + virtual core::vector3df& getNormal(u32 i) + { + return getVertexBuffer()[i].Normal; + } + }; + + +} // end namespace scene +} // end namespace irr + +#endif + + diff --git a/builddir/irrlicht-1.8.1/include/IEventReceiver.h b/builddir/irrlicht-1.8.1/include/IEventReceiver.h new file mode 100644 index 0000000..9c7813f --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IEventReceiver.h @@ -0,0 +1,490 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_EVENT_RECEIVER_H_INCLUDED__ +#define __I_EVENT_RECEIVER_H_INCLUDED__ + +#include "ILogger.h" +#include "Keycodes.h" +#include "irrString.h" + +namespace irr +{ + //! Enumeration for all event types there are. + enum EEVENT_TYPE + { + //! An event of the graphical user interface. + /** GUI events are created by the GUI environment or the GUI elements in response + to mouse or keyboard events. When a GUI element receives an event it will either + process it and return true, or pass the event to its parent. If an event is not absorbed + before it reaches the root element then it will then be passed to the user receiver. */ + EET_GUI_EVENT = 0, + + //! A mouse input event. + /** Mouse events are created by the device and passed to IrrlichtDevice::postEventFromUser + in response to mouse input received from the operating system. + Mouse events are first passed to the user receiver, then to the GUI environment and its elements, + then finally the input receiving scene manager where it is passed to the active camera. + */ + EET_MOUSE_INPUT_EVENT, + + //! A key input event. + /** Like mouse events, keyboard events are created by the device and passed to + IrrlichtDevice::postEventFromUser. They take the same path as mouse events. */ + EET_KEY_INPUT_EVENT, + + //! A joystick (joypad, gamepad) input event. + /** Joystick events are created by polling all connected joysticks once per + device run() and then passing the events to IrrlichtDevice::postEventFromUser. + They take the same path as mouse events. + Windows, SDL: Implemented. + Linux: Implemented, with POV hat issues. + MacOS / Other: Not yet implemented. + */ + EET_JOYSTICK_INPUT_EVENT, + + //! A log event + /** Log events are only passed to the user receiver if there is one. If they are absorbed by the + user receiver then no text will be sent to the console. */ + EET_LOG_TEXT_EVENT, + + //! A user event with user data. + /** This is not used by Irrlicht and can be used to send user + specific data though the system. The Irrlicht 'window handle' + can be obtained from IrrlichtDevice::getExposedVideoData() + The usage and behavior depends on the operating system: + Windows: send a WM_USER message to the Irrlicht Window; the + wParam and lParam will be used to populate the + UserData1 and UserData2 members of the SUserEvent. + Linux: send a ClientMessage via XSendEvent to the Irrlicht + Window; the data.l[0] and data.l[1] members will be + casted to s32 and used as UserData1 and UserData2. + MacOS: Not yet implemented + */ + EET_USER_EVENT, + + //! This enum is never used, it only forces the compiler to + //! compile these enumeration values to 32 bit. + EGUIET_FORCE_32_BIT = 0x7fffffff + + }; + + //! Enumeration for all mouse input events + enum EMOUSE_INPUT_EVENT + { + //! Left mouse button was pressed down. + EMIE_LMOUSE_PRESSED_DOWN = 0, + + //! Right mouse button was pressed down. + EMIE_RMOUSE_PRESSED_DOWN, + + //! Middle mouse button was pressed down. + EMIE_MMOUSE_PRESSED_DOWN, + + //! Left mouse button was left up. + EMIE_LMOUSE_LEFT_UP, + + //! Right mouse button was left up. + EMIE_RMOUSE_LEFT_UP, + + //! Middle mouse button was left up. + EMIE_MMOUSE_LEFT_UP, + + //! The mouse cursor changed its position. + EMIE_MOUSE_MOVED, + + //! The mouse wheel was moved. Use Wheel value in event data to find out + //! in what direction and how fast. + EMIE_MOUSE_WHEEL, + + //! Left mouse button double click. + //! This event is generated after the second EMIE_LMOUSE_PRESSED_DOWN event. + EMIE_LMOUSE_DOUBLE_CLICK, + + //! Right mouse button double click. + //! This event is generated after the second EMIE_RMOUSE_PRESSED_DOWN event. + EMIE_RMOUSE_DOUBLE_CLICK, + + //! Middle mouse button double click. + //! This event is generated after the second EMIE_MMOUSE_PRESSED_DOWN event. + EMIE_MMOUSE_DOUBLE_CLICK, + + //! Left mouse button triple click. + //! This event is generated after the third EMIE_LMOUSE_PRESSED_DOWN event. + EMIE_LMOUSE_TRIPLE_CLICK, + + //! Right mouse button triple click. + //! This event is generated after the third EMIE_RMOUSE_PRESSED_DOWN event. + EMIE_RMOUSE_TRIPLE_CLICK, + + //! Middle mouse button triple click. + //! This event is generated after the third EMIE_MMOUSE_PRESSED_DOWN event. + EMIE_MMOUSE_TRIPLE_CLICK, + + //! No real event. Just for convenience to get number of events + EMIE_COUNT + }; + + //! Masks for mouse button states + enum E_MOUSE_BUTTON_STATE_MASK + { + EMBSM_LEFT = 0x01, + EMBSM_RIGHT = 0x02, + EMBSM_MIDDLE = 0x04, + + //! currently only on windows + EMBSM_EXTRA1 = 0x08, + + //! currently only on windows + EMBSM_EXTRA2 = 0x10, + + EMBSM_FORCE_32_BIT = 0x7fffffff + }; + + namespace gui + { + + class IGUIElement; + + //! Enumeration for all events which are sendable by the gui system + enum EGUI_EVENT_TYPE + { + //! A gui element has lost its focus. + /** GUIEvent.Caller is losing the focus to GUIEvent.Element. + If the event is absorbed then the focus will not be changed. */ + EGET_ELEMENT_FOCUS_LOST = 0, + + //! A gui element has got the focus. + /** If the event is absorbed then the focus will not be changed. */ + EGET_ELEMENT_FOCUSED, + + //! The mouse cursor hovered over a gui element. + /** If an element has sub-elements you also get this message for the subelements */ + EGET_ELEMENT_HOVERED, + + //! The mouse cursor left the hovered element. + /** If an element has sub-elements you also get this message for the subelements */ + EGET_ELEMENT_LEFT, + + //! An element would like to close. + /** Windows and context menus use this event when they would like to close, + this can be cancelled by absorbing the event. */ + EGET_ELEMENT_CLOSED, + + //! A button was clicked. + EGET_BUTTON_CLICKED, + + //! A scrollbar has changed its position. + EGET_SCROLL_BAR_CHANGED, + + //! A checkbox has changed its check state. + EGET_CHECKBOX_CHANGED, + + //! A new item in a listbox was selected. + /** NOTE: You also get this event currently when the same item was clicked again after more than 500 ms. */ + EGET_LISTBOX_CHANGED, + + //! An item in the listbox was selected, which was already selected. + /** NOTE: You get the event currently only if the item was clicked again within 500 ms or selected by "enter" or "space". */ + EGET_LISTBOX_SELECTED_AGAIN, + + //! A file has been selected in the file dialog + EGET_FILE_SELECTED, + + //! A directory has been selected in the file dialog + EGET_DIRECTORY_SELECTED, + + //! A file open dialog has been closed without choosing a file + EGET_FILE_CHOOSE_DIALOG_CANCELLED, + + //! 'Yes' was clicked on a messagebox + EGET_MESSAGEBOX_YES, + + //! 'No' was clicked on a messagebox + EGET_MESSAGEBOX_NO, + + //! 'OK' was clicked on a messagebox + EGET_MESSAGEBOX_OK, + + //! 'Cancel' was clicked on a messagebox + EGET_MESSAGEBOX_CANCEL, + + //! In an editbox 'ENTER' was pressed + EGET_EDITBOX_ENTER, + + //! The text in an editbox was changed. This does not include automatic changes in text-breaking. + EGET_EDITBOX_CHANGED, + + //! The marked area in an editbox was changed. + EGET_EDITBOX_MARKING_CHANGED, + + //! The tab was changed in an tab control + EGET_TAB_CHANGED, + + //! A menu item was selected in a (context) menu + EGET_MENU_ITEM_SELECTED, + + //! The selection in a combo box has been changed + EGET_COMBO_BOX_CHANGED, + + //! The value of a spin box has changed + EGET_SPINBOX_CHANGED, + + //! A table has changed + EGET_TABLE_CHANGED, + EGET_TABLE_HEADER_CHANGED, + EGET_TABLE_SELECTED_AGAIN, + + //! A tree view node lost selection. See IGUITreeView::getLastEventNode(). + EGET_TREEVIEW_NODE_DESELECT, + + //! A tree view node was selected. See IGUITreeView::getLastEventNode(). + EGET_TREEVIEW_NODE_SELECT, + + //! A tree view node was expanded. See IGUITreeView::getLastEventNode(). + EGET_TREEVIEW_NODE_EXPAND, + + //! A tree view node was collapsed. See IGUITreeView::getLastEventNode(). + EGET_TREEVIEW_NODE_COLLAPSE, + + //! deprecated - use EGET_TREEVIEW_NODE_COLLAPSE instead. This + //! may be removed by Irrlicht 1.9 + EGET_TREEVIEW_NODE_COLLAPS = EGET_TREEVIEW_NODE_COLLAPSE, + + //! No real event. Just for convenience to get number of events + EGET_COUNT + }; + } // end namespace gui + + +//! SEvents hold information about an event. See irr::IEventReceiver for details on event handling. +struct SEvent +{ + //! Any kind of GUI event. + struct SGUIEvent + { + //! IGUIElement who called the event + gui::IGUIElement* Caller; + + //! If the event has something to do with another element, it will be held here. + gui::IGUIElement* Element; + + //! Type of GUI Event + gui::EGUI_EVENT_TYPE EventType; + + }; + + //! Any kind of mouse event. + struct SMouseInput + { + //! X position of mouse cursor + s32 X; + + //! Y position of mouse cursor + s32 Y; + + //! mouse wheel delta, often 1.0 or -1.0, but can have other values < 0.f or > 0.f; + /** Only valid if event was EMIE_MOUSE_WHEEL */ + f32 Wheel; + + //! True if shift was also pressed + bool Shift:1; + + //! True if ctrl was also pressed + bool Control:1; + + //! A bitmap of button states. You can use isButtonPressed() to determine + //! if a button is pressed or not. + //! Currently only valid if the event was EMIE_MOUSE_MOVED + u32 ButtonStates; + + //! Is the left button pressed down? + bool isLeftPressed() const { return 0 != ( ButtonStates & EMBSM_LEFT ); } + + //! Is the right button pressed down? + bool isRightPressed() const { return 0 != ( ButtonStates & EMBSM_RIGHT ); } + + //! Is the middle button pressed down? + bool isMiddlePressed() const { return 0 != ( ButtonStates & EMBSM_MIDDLE ); } + + //! Type of mouse event + EMOUSE_INPUT_EVENT Event; + }; + + //! Any kind of keyboard event. + struct SKeyInput + { + //! Character corresponding to the key (0, if not a character) + wchar_t Char; + + //! Key which has been pressed or released + EKEY_CODE Key; + + //! If not true, then the key was left up + bool PressedDown:1; + + //! True if shift was also pressed + bool Shift:1; + + //! True if ctrl was also pressed + bool Control:1; + }; + + //! A joystick event. + /** Unlike other events, joystick events represent the result of polling + * each connected joystick once per run() of the device. Joystick events will + * not be generated by default. If joystick support is available for the + * active device, _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ is defined, and + * @ref irr::IrrlichtDevice::activateJoysticks() has been called, an event of + * this type will be generated once per joystick per @ref IrrlichtDevice::run() + * regardless of whether the state of the joystick has actually changed. */ + struct SJoystickEvent + { + enum + { + NUMBER_OF_BUTTONS = 32, + + AXIS_X = 0, // e.g. analog stick 1 left to right + AXIS_Y, // e.g. analog stick 1 top to bottom + AXIS_Z, // e.g. throttle, or analog 2 stick 2 left to right + AXIS_R, // e.g. rudder, or analog 2 stick 2 top to bottom + AXIS_U, + AXIS_V, + NUMBER_OF_AXES + }; + + /** A bitmap of button states. You can use IsButtonPressed() to + ( check the state of each button from 0 to (NUMBER_OF_BUTTONS - 1) */ + u32 ButtonStates; + + /** For AXIS_X, AXIS_Y, AXIS_Z, AXIS_R, AXIS_U and AXIS_V + * Values are in the range -32768 to 32767, with 0 representing + * the center position. You will receive the raw value from the + * joystick, and so will usually want to implement a dead zone around + * the center of the range. Axes not supported by this joystick will + * always have a value of 0. On Linux, POV hats are represented as axes, + * usually the last two active axis. + */ + s16 Axis[NUMBER_OF_AXES]; + + /** The POV represents the angle of the POV hat in degrees * 100, + * from 0 to 35,900. A value of 65535 indicates that the POV hat + * is centered (or not present). + * This value is only supported on Windows. On Linux, the POV hat + * will be sent as 2 axes instead. */ + u16 POV; + + //! The ID of the joystick which generated this event. + /** This is an internal Irrlicht index; it does not map directly + * to any particular hardware joystick. */ + u8 Joystick; + + //! A helper function to check if a button is pressed. + bool IsButtonPressed(u32 button) const + { + if(button >= (u32)NUMBER_OF_BUTTONS) + return false; + + return (ButtonStates & (1 << button)) ? true : false; + } + }; + + + //! Any kind of log event. + struct SLogEvent + { + //! Pointer to text which has been logged + const c8* Text; + + //! Log level in which the text has been logged + ELOG_LEVEL Level; + }; + + //! Any kind of user event. + struct SUserEvent + { + //! Some user specified data as int + s32 UserData1; + + //! Another user specified data as int + s32 UserData2; + }; + + EEVENT_TYPE EventType; + union + { + struct SGUIEvent GUIEvent; + struct SMouseInput MouseInput; + struct SKeyInput KeyInput; + struct SJoystickEvent JoystickEvent; + struct SLogEvent LogEvent; + struct SUserEvent UserEvent; + }; + +}; + +//! Interface of an object which can receive events. +/** Many of the engine's classes inherit IEventReceiver so they are able to +process events. Events usually start at a postEventFromUser function and are +passed down through a chain of event receivers until OnEvent returns true. See +irr::EEVENT_TYPE for a description of where each type of event starts, and the +path it takes through the system. */ +class IEventReceiver +{ +public: + + //! Destructor + virtual ~IEventReceiver() {} + + //! Called if an event happened. + /** Please take care that you should only return 'true' when you want to _prevent_ Irrlicht + * from processing the event any further. So 'true' does mean that an event is completely done. + * Therefore your return value for all unprocessed events should be 'false'. + \return True if the event was processed. + */ + virtual bool OnEvent(const SEvent& event) = 0; +}; + + +//! Information on a joystick, returned from @ref irr::IrrlichtDevice::activateJoysticks() +struct SJoystickInfo +{ + //! The ID of the joystick + /** This is an internal Irrlicht index; it does not map directly + * to any particular hardware joystick. It corresponds to the + * irr::SJoystickEvent Joystick ID. */ + u8 Joystick; + + //! The name that the joystick uses to identify itself. + core::stringc Name; + + //! The number of buttons that the joystick has. + u32 Buttons; + + //! The number of axes that the joystick has, i.e. X, Y, Z, R, U, V. + /** Note: with a Linux device, the POV hat (if any) will use two axes. These + * will be included in this count. */ + u32 Axes; + + //! An indication of whether the joystick has a POV hat. + /** A Windows device will identify the presence or absence or the POV hat. A + * Linux device cannot, and will always return POV_HAT_UNKNOWN. */ + enum + { + //! A hat is definitely present. + POV_HAT_PRESENT, + + //! A hat is definitely not present. + POV_HAT_ABSENT, + + //! The presence or absence of a hat cannot be determined. + POV_HAT_UNKNOWN + } PovHat; +}; // struct SJoystickInfo + + +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IFileArchive.h b/builddir/irrlicht-1.8.1/include/IFileArchive.h new file mode 100644 index 0000000..8bf8cad --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IFileArchive.h @@ -0,0 +1,132 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt/ Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_FILE_ARCHIVE_H_INCLUDED__ +#define __I_FILE_ARCHIVE_H_INCLUDED__ + +#include "IReadFile.h" +#include "IFileList.h" + +namespace irr +{ + +namespace io +{ + +//! FileSystemType: which Filesystem should be used for e.g. browsing +enum EFileSystemType +{ + FILESYSTEM_NATIVE = 0, // Native OS FileSystem + FILESYSTEM_VIRTUAL // Virtual FileSystem +}; + +//! Contains the different types of archives +enum E_FILE_ARCHIVE_TYPE +{ + //! A PKZIP archive + EFAT_ZIP = MAKE_IRR_ID('Z','I','P', 0), + + //! A gzip archive + EFAT_GZIP = MAKE_IRR_ID('g','z','i','p'), + + //! A virtual directory + EFAT_FOLDER = MAKE_IRR_ID('f','l','d','r'), + + //! An ID Software PAK archive + EFAT_PAK = MAKE_IRR_ID('P','A','K', 0), + + //! A Nebula Device archive + EFAT_NPK = MAKE_IRR_ID('N','P','K', 0), + + //! A Tape ARchive + EFAT_TAR = MAKE_IRR_ID('T','A','R', 0), + + //! A wad Archive, Quake2, Halflife + EFAT_WAD = MAKE_IRR_ID('W','A','D', 0), + + //! The type of this archive is unknown + EFAT_UNKNOWN = MAKE_IRR_ID('u','n','k','n') +}; + +//! The FileArchive manages archives and provides access to files inside them. +class IFileArchive : public virtual IReferenceCounted +{ +public: + + //! Opens a file based on its name + /** Creates and returns a new IReadFile for a file in the archive. + \param filename The file to open + \return Returns A pointer to the created file on success, + or 0 on failure. */ + virtual IReadFile* createAndOpenFile(const path& filename) =0; + + //! Opens a file based on its position in the file list. + /** Creates and returns + \param index The zero based index of the file. + \return Returns a pointer to the created file on success, or 0 on failure. */ + virtual IReadFile* createAndOpenFile(u32 index) =0; + + //! Returns the complete file tree + /** \return Returns the complete directory tree for the archive, + including all files and folders */ + virtual const IFileList* getFileList() const =0; + + //! get the archive type + virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_UNKNOWN; } + + //! An optionally used password string + /** This variable is publicly accessible from the interface in order to + avoid single access patterns to this place, and hence allow some more + obscurity. + */ + core::stringc Password; +}; + +//! Class which is able to create an archive from a file. +/** If you want the Irrlicht Engine be able to load archives of +currently unsupported file formats (e.g .wad), then implement +this and add your new Archive loader with +IFileSystem::addArchiveLoader() to the engine. */ +class IArchiveLoader : public virtual IReferenceCounted +{ +public: + //! Check if the file might be loaded by this class + /** Check based on the file extension (e.g. ".zip") + \param filename Name of file to check. + \return True if file seems to be loadable. */ + virtual bool isALoadableFileFormat(const path& filename) const =0; + + //! Check if the file might be loaded by this class + /** This check may look into the file. + \param file File handle to check. + \return True if file seems to be loadable. */ + virtual bool isALoadableFileFormat(io::IReadFile* file) const =0; + + //! Check to see if the loader can create archives of this type. + /** Check based on the archive type. + \param fileType The archive type to check. + \return True if the archile loader supports this type, false if not */ + virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const =0; + + //! Creates an archive from the filename + /** \param filename File to use. + \param ignoreCase Searching is performed without regarding the case + \param ignorePaths Files are searched for without checking for the directories + \return Pointer to newly created archive, or 0 upon error. */ + virtual IFileArchive* createArchive(const path& filename, bool ignoreCase, bool ignorePaths) const =0; + + //! Creates an archive from the file + /** \param file File handle to use. + \param ignoreCase Searching is performed without regarding the case + \param ignorePaths Files are searched for without checking for the directories + \return Pointer to newly created archive, or 0 upon error. */ + virtual IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const =0; +}; + + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IFileList.h b/builddir/irrlicht-1.8.1/include/IFileList.h new file mode 100644 index 0000000..2eabd7c --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IFileList.h @@ -0,0 +1,94 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_FILE_LIST_H_INCLUDED__ +#define __I_FILE_LIST_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "path.h" + +namespace irr +{ +namespace io +{ + +//! Provides a list of files and folders. +/** File lists usually contain a list of all files in a given folder, +but can also contain a complete directory structure. */ +class IFileList : public virtual IReferenceCounted +{ +public: + //! Get the number of files in the filelist. + /** \return Amount of files and directories in the file list. */ + virtual u32 getFileCount() const = 0; + + //! Gets the name of a file in the list, based on an index. + /** The path is not included in this name. Use getFullFileName for this. + \param index is the zero based index of the file which name should + be returned. The index must be less than the amount getFileCount() returns. + \return File name of the file. Returns 0, if an error occured. */ + virtual const io::path& getFileName(u32 index) const = 0; + + //! Gets the full name of a file in the list including the path, based on an index. + /** \param index is the zero based index of the file which name should + be returned. The index must be less than the amount getFileCount() returns. + \return File name of the file. Returns 0 if an error occured. */ + virtual const io::path& getFullFileName(u32 index) const = 0; + + //! Returns the size of a file in the file list, based on an index. + /** \param index is the zero based index of the file which should be returned. + The index must be less than the amount getFileCount() returns. + \return The size of the file in bytes. */ + virtual u32 getFileSize(u32 index) const = 0; + + //! Returns the file offset of a file in the file list, based on an index. + /** \param index is the zero based index of the file which should be returned. + The index must be less than the amount getFileCount() returns. + \return The offset of the file in bytes. */ + virtual u32 getFileOffset(u32 index) const = 0; + + //! Returns the ID of a file in the file list, based on an index. + /** This optional ID can be used to link the file list entry to information held + elsewhere. For example this could be an index in an IFileArchive, linking the entry + to its data offset, uncompressed size and CRC. + \param index is the zero based index of the file which should be returned. + The index must be less than the amount getFileCount() returns. + \return The ID of the file. */ + virtual u32 getID(u32 index) const = 0; + + //! Check if the file is a directory + /** \param index The zero based index which will be checked. The index + must be less than the amount getFileCount() returns. + \return True if the file is a directory, else false. */ + virtual bool isDirectory(u32 index) const = 0; + + //! Searches for a file or folder in the list + /** Searches for a file by name + \param filename The name of the file to search for. + \param isFolder True if you are searching for a directory path, false if you are searching for a file + \return Returns the index of the file in the file list, or -1 if + no matching name name was found. */ + virtual s32 findFile(const io::path& filename, bool isFolder=false) const = 0; + + //! Returns the base path of the file list + virtual const io::path& getPath() const = 0; + + //! Add as a file or folder to the list + /** \param fullPath The file name including path, from the root of the file list. + \param isDirectory True if this is a directory rather than a file. + \param offset The file offset inside an archive + \param size The size of the file in bytes. + \param id The ID of the file in the archive which owns it */ + virtual u32 addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id=0) = 0; + + //! Sorts the file list. You should call this after adding any items to the file list + virtual void sort() = 0; +}; + +} // end namespace irr +} // end namespace io + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IFileSystem.h b/builddir/irrlicht-1.8.1/include/IFileSystem.h new file mode 100644 index 0000000..0c5244d --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IFileSystem.h @@ -0,0 +1,385 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_FILE_SYSTEM_H_INCLUDED__ +#define __I_FILE_SYSTEM_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "IXMLReader.h" +#include "IFileArchive.h" + +namespace irr +{ +namespace video +{ + class IVideoDriver; +} // end namespace video +namespace io +{ + +class IReadFile; +class IWriteFile; +class IFileList; +class IXMLWriter; +class IAttributes; + + +//! The FileSystem manages files and archives and provides access to them. +/** It manages where files are, so that modules which use the the IO do not +need to know where every file is located. A file could be in a .zip-Archive or +as file on disk, using the IFileSystem makes no difference to this. */ +class IFileSystem : public virtual IReferenceCounted +{ +public: + + //! Opens a file for read access. + /** \param filename: Name of file to open. + \return Pointer to the created file interface. + The returned pointer should be dropped when no longer needed. + See IReferenceCounted::drop() for more information. */ + virtual IReadFile* createAndOpenFile(const path& filename) =0; + + //! Creates an IReadFile interface for accessing memory like a file. + /** This allows you to use a pointer to memory where an IReadFile is requested. + \param memory: A pointer to the start of the file in memory + \param len: The length of the memory in bytes + \param fileName: The name given to this file + \param deleteMemoryWhenDropped: True if the memory should be deleted + along with the IReadFile when it is dropped. + \return Pointer to the created file interface. + The returned pointer should be dropped when no longer needed. + See IReferenceCounted::drop() for more information. + */ + virtual IReadFile* createMemoryReadFile(void* memory, s32 len, const path& fileName, bool deleteMemoryWhenDropped=false) =0; + + //! Creates an IReadFile interface for accessing files inside files. + /** This is useful e.g. for archives. + \param fileName: The name given to this file + \param alreadyOpenedFile: Pointer to the enclosing file + \param pos: Start of the file inside alreadyOpenedFile + \param areaSize: The length of the file + \return A pointer to the created file interface. + The returned pointer should be dropped when no longer needed. + See IReferenceCounted::drop() for more information. + */ + virtual IReadFile* createLimitReadFile(const path& fileName, + IReadFile* alreadyOpenedFile, long pos, long areaSize) =0; + + //! Creates an IWriteFile interface for accessing memory like a file. + /** This allows you to use a pointer to memory where an IWriteFile is requested. + You are responsible for allocating enough memory. + \param memory: A pointer to the start of the file in memory (allocated by you) + \param len: The length of the memory in bytes + \param fileName: The name given to this file + \param deleteMemoryWhenDropped: True if the memory should be deleted + along with the IWriteFile when it is dropped. + \return Pointer to the created file interface. + The returned pointer should be dropped when no longer needed. + See IReferenceCounted::drop() for more information. + */ + virtual IWriteFile* createMemoryWriteFile(void* memory, s32 len, const path& fileName, bool deleteMemoryWhenDropped=false) =0; + + + //! Opens a file for write access. + /** \param filename: Name of file to open. + \param append: If the file already exist, all write operations are + appended to the file. + \return Pointer to the created file interface. 0 is returned, if the + file could not created or opened for writing. + The returned pointer should be dropped when no longer needed. + See IReferenceCounted::drop() for more information. */ + virtual IWriteFile* createAndWriteFile(const path& filename, bool append=false) =0; + + //! Adds an archive to the file system. + /** After calling this, the Irrlicht Engine will also search and open + files directly from this archive. This is useful for hiding data from + the end user, speeding up file access and making it possible to access + for example Quake3 .pk3 files, which are just renamed .zip files. By + default Irrlicht supports ZIP, PAK, TAR, PNK, and directories as + archives. You can provide your own archive types by implementing + IArchiveLoader and passing an instance to addArchiveLoader. + Irrlicht supports AES-encrypted zip files, and the advanced compression + techniques lzma and bzip2. + \param filename: Filename of the archive to add to the file system. + \param ignoreCase: If set to true, files in the archive can be accessed without + writing all letters in the right case. + \param ignorePaths: If set to true, files in the added archive can be accessed + without its complete path. + \param archiveType: If no specific E_FILE_ARCHIVE_TYPE is selected then + the type of archive will depend on the extension of the file name. If + you use a different extension then you can use this parameter to force + a specific type of archive. + \param password An optional password, which is used in case of encrypted archives. + \param retArchive A pointer that will be set to the archive that is added. + \return True if the archive was added successfully, false if not. */ + virtual bool addFileArchive(const path& filename, bool ignoreCase=true, + bool ignorePaths=true, + E_FILE_ARCHIVE_TYPE archiveType=EFAT_UNKNOWN, + const core::stringc& password="", + IFileArchive** retArchive=0) =0; + + //! Adds an archive to the file system. + /** After calling this, the Irrlicht Engine will also search and open + files directly from this archive. This is useful for hiding data from + the end user, speeding up file access and making it possible to access + for example Quake3 .pk3 files, which are just renamed .zip files. By + default Irrlicht supports ZIP, PAK, TAR, PNK, and directories as + archives. You can provide your own archive types by implementing + IArchiveLoader and passing an instance to addArchiveLoader. + Irrlicht supports AES-encrypted zip files, and the advanced compression + techniques lzma and bzip2. + If you want to add a directory as an archive, prefix its name with a + slash in order to let Irrlicht recognize it as a folder mount (mypath/). + Using this technique one can build up a search order, because archives + are read first, and can be used more easily with relative filenames. + \param file: Archive to add to the file system. + \param ignoreCase: If set to true, files in the archive can be accessed without + writing all letters in the right case. + \param ignorePaths: If set to true, files in the added archive can be accessed + without its complete path. + \param archiveType: If no specific E_FILE_ARCHIVE_TYPE is selected then + the type of archive will depend on the extension of the file name. If + you use a different extension then you can use this parameter to force + a specific type of archive. + \param password An optional password, which is used in case of encrypted archives. + \param retArchive A pointer that will be set to the archive that is added. + \return True if the archive was added successfully, false if not. */ + virtual bool addFileArchive(IReadFile* file, bool ignoreCase=true, + bool ignorePaths=true, + E_FILE_ARCHIVE_TYPE archiveType=EFAT_UNKNOWN, + const core::stringc& password="", + IFileArchive** retArchive=0) =0; + + //! Adds an archive to the file system. + /** \param archive: The archive to add to the file system. + \return True if the archive was added successfully, false if not. */ + virtual bool addFileArchive(IFileArchive* archive) =0; + + //! Get the number of archives currently attached to the file system + virtual u32 getFileArchiveCount() const =0; + + //! Removes an archive from the file system. + /** This will close the archive and free any file handles, but will not + close resources which have already been loaded and are now cached, for + example textures and meshes. + \param index: The index of the archive to remove + \return True on success, false on failure */ + virtual bool removeFileArchive(u32 index) =0; + + //! Removes an archive from the file system. + /** This will close the archive and free any file handles, but will not + close resources which have already been loaded and are now cached, for + example textures and meshes. Note that a relative filename might be + interpreted differently on each call, depending on the current working + directory. In case you want to remove an archive that was added using + a relative path name, you have to change to the same working directory + again. This means, that the filename given on creation is not an + identifier for the archive, but just a usual filename that is used for + locating the archive to work with. + \param filename The archive pointed to by the name will be removed + \return True on success, false on failure */ + virtual bool removeFileArchive(const path& filename) =0; + + //! Removes an archive from the file system. + /** This will close the archive and free any file handles, but will not + close resources which have already been loaded and are now cached, for + example textures and meshes. + \param archive The archive to remove. + \return True on success, false on failure */ + virtual bool removeFileArchive(const IFileArchive* archive) =0; + + //! Changes the search order of attached archives. + /** + \param sourceIndex: The index of the archive to change + \param relative: The relative change in position, archives with a lower index are searched first */ + virtual bool moveFileArchive(u32 sourceIndex, s32 relative) =0; + + //! Get the archive at a given index. + virtual IFileArchive* getFileArchive(u32 index) =0; + + //! Adds an external archive loader to the engine. + /** Use this function to add support for new archive types to the + engine, for example proprietary or encrypted file storage. */ + virtual void addArchiveLoader(IArchiveLoader* loader) =0; + + //! Gets the number of archive loaders currently added + virtual u32 getArchiveLoaderCount() const = 0; + + //! Retrieve the given archive loader + /** \param index The index of the loader to retrieve. This parameter is an 0-based + array index. + \return A pointer to the specified loader, 0 if the index is incorrect. */ + virtual IArchiveLoader* getArchiveLoader(u32 index) const = 0; + + //! Adds a zip archive to the file system. + /** \deprecated This function is provided for compatibility + with older versions of Irrlicht and may be removed in Irrlicht 1.9, + you should use addFileArchive instead. + After calling this, the Irrlicht Engine will search and open files directly from this archive too. + This is useful for hiding data from the end user, speeding up file access and making it possible to + access for example Quake3 .pk3 files, which are no different than .zip files. + \param filename: Filename of the zip archive to add to the file system. + \param ignoreCase: If set to true, files in the archive can be accessed without + writing all letters in the right case. + \param ignorePaths: If set to true, files in the added archive can be accessed + without its complete path. + \return True if the archive was added successfully, false if not. */ + _IRR_DEPRECATED_ virtual bool addZipFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true) + { + return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_ZIP); + } + + //! Adds an unzipped archive (or basedirectory with subdirectories..) to the file system. + /** \deprecated This function is provided for compatibility + with older versions of Irrlicht and may be removed in Irrlicht 1.9, + you should use addFileArchive instead. + Useful for handling data which will be in a zip file + \param filename: Filename of the unzipped zip archive base directory to add to the file system. + \param ignoreCase: If set to true, files in the archive can be accessed without + writing all letters in the right case. + \param ignorePaths: If set to true, files in the added archive can be accessed + without its complete path. + \return True if the archive was added successful, false if not. */ + _IRR_DEPRECATED_ virtual bool addFolderFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true) + { + return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_FOLDER); + } + + //! Adds a pak archive to the file system. + /** \deprecated This function is provided for compatibility + with older versions of Irrlicht and may be removed in Irrlicht 1.9, + you should use addFileArchive instead. + After calling this, the Irrlicht Engine will search and open files directly from this archive too. + This is useful for hiding data from the end user, speeding up file access and making it possible to + access for example Quake2/KingPin/Hexen2 .pak files + \param filename: Filename of the pak archive to add to the file system. + \param ignoreCase: If set to true, files in the archive can be accessed without + writing all letters in the right case. + \param ignorePaths: If set to true, files in the added archive can be accessed + without its complete path.(should not use with Quake2 paks + \return True if the archive was added successful, false if not. */ + _IRR_DEPRECATED_ virtual bool addPakFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true) + { + return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_PAK); + } + + //! Get the current working directory. + /** \return Current working directory as a string. */ + virtual const path& getWorkingDirectory() =0; + + //! Changes the current working directory. + /** \param newDirectory: A string specifying the new working directory. + The string is operating system dependent. Under Windows it has + the form "<drive>:\<directory>\<sudirectory>\<..>". An example would be: "C:\Windows\" + \return True if successful, otherwise false. */ + virtual bool changeWorkingDirectoryTo(const path& newDirectory) =0; + + //! Converts a relative path to an absolute (unique) path, resolving symbolic links if required + /** \param filename Possibly relative file or directory name to query. + \result Absolute filename which points to the same file. */ + virtual path getAbsolutePath(const path& filename) const =0; + + //! Get the directory a file is located in. + /** \param filename: The file to get the directory from. + \return String containing the directory of the file. */ + virtual path getFileDir(const path& filename) const =0; + + //! Get the base part of a filename, i.e. the name without the directory part. + /** If no directory is prefixed, the full name is returned. + \param filename: The file to get the basename from + \param keepExtension True if filename with extension is returned otherwise everything + after the final '.' is removed as well. */ + virtual path getFileBasename(const path& filename, bool keepExtension=true) const =0; + + //! flatten a path and file name for example: "/you/me/../." becomes "/you" + virtual path& flattenFilename(path& directory, const path& root="/") const =0; + + //! Get the relative filename, relative to the given directory + virtual path getRelativeFilename(const path& filename, const path& directory) const =0; + + //! Creates a list of files and directories in the current working directory and returns it. + /** \return a Pointer to the created IFileList is returned. After the list has been used + it has to be deleted using its IFileList::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IFileList* createFileList() =0; + + //! Creates an empty filelist + /** \return a Pointer to the created IFileList is returned. After the list has been used + it has to be deleted using its IFileList::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IFileList* createEmptyFileList(const io::path& path, bool ignoreCase, bool ignorePaths) =0; + + //! Set the active type of file system. + virtual EFileSystemType setFileListSystem(EFileSystemType listType) =0; + + //! Determines if a file exists and could be opened. + /** \param filename is the string identifying the file which should be tested for existence. + \return True if file exists, and false if it does not exist or an error occured. */ + virtual bool existFile(const path& filename) const =0; + + //! Creates a XML Reader from a file which returns all parsed strings as wide characters (wchar_t*). + /** Use createXMLReaderUTF8() if you prefer char* instead of wchar_t*. See IIrrXMLReader for + more information on how to use the parser. + \return 0, if file could not be opened, otherwise a pointer to the created + IXMLReader is returned. After use, the reader + has to be deleted using its IXMLReader::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLReader* createXMLReader(const path& filename) =0; + + //! Creates a XML Reader from a file which returns all parsed strings as wide characters (wchar_t*). + /** Use createXMLReaderUTF8() if you prefer char* instead of wchar_t*. See IIrrXMLReader for + more information on how to use the parser. + \return 0, if file could not be opened, otherwise a pointer to the created + IXMLReader is returned. After use, the reader + has to be deleted using its IXMLReader::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLReader* createXMLReader(IReadFile* file) =0; + + //! Creates a XML Reader from a file which returns all parsed strings as ASCII/UTF-8 characters (char*). + /** Use createXMLReader() if you prefer wchar_t* instead of char*. See IIrrXMLReader for + more information on how to use the parser. + \return 0, if file could not be opened, otherwise a pointer to the created + IXMLReader is returned. After use, the reader + has to be deleted using its IXMLReaderUTF8::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLReaderUTF8* createXMLReaderUTF8(const path& filename) =0; + + //! Creates a XML Reader from a file which returns all parsed strings as ASCII/UTF-8 characters (char*). + /** Use createXMLReader() if you prefer wchar_t* instead of char*. See IIrrXMLReader for + more information on how to use the parser. + \return 0, if file could not be opened, otherwise a pointer to the created + IXMLReader is returned. After use, the reader + has to be deleted using its IXMLReaderUTF8::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLReaderUTF8* createXMLReaderUTF8(IReadFile* file) =0; + + //! Creates a XML Writer from a file. + /** \return 0, if file could not be opened, otherwise a pointer to the created + IXMLWriter is returned. After use, the reader + has to be deleted using its IXMLWriter::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLWriter* createXMLWriter(const path& filename) =0; + + //! Creates a XML Writer from a file. + /** \return 0, if file could not be opened, otherwise a pointer to the created + IXMLWriter is returned. After use, the reader + has to be deleted using its IXMLWriter::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLWriter* createXMLWriter(IWriteFile* file) =0; + + //! Creates a new empty collection of attributes, usable for serialization and more. + /** \param driver: Video driver to be used to load textures when specified as attribute values. + Can be null to prevent automatic texture loading by attributes. + \return Pointer to the created object. + If you no longer need the object, you should call IAttributes::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IAttributes* createEmptyAttributes(video::IVideoDriver* driver=0) =0; +}; + + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGPUProgrammingServices.h b/builddir/irrlicht-1.8.1/include/IGPUProgrammingServices.h new file mode 100644 index 0000000..28717d5 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGPUProgrammingServices.h @@ -0,0 +1,474 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GPU_PROGRAMMING_SERVICES_H_INCLUDED__ +#define __I_GPU_PROGRAMMING_SERVICES_H_INCLUDED__ + +#include "EShaderTypes.h" +#include "EMaterialTypes.h" +#include "EPrimitiveTypes.h" +#include "path.h" + +namespace irr +{ + +namespace io +{ + class IReadFile; +} // end namespace io + +namespace video +{ + +class IVideoDriver; +class IShaderConstantSetCallBack; + +//! Enumeration for different types of shading languages +enum E_GPU_SHADING_LANGUAGE +{ + //! The default language, so HLSL for Direct3D and GLSL for OpenGL. + EGSL_DEFAULT = 0, + + //! Cg shading language.*/ + EGSL_CG +}; + +//! Interface making it possible to create and use programs running on the GPU. +class IGPUProgrammingServices +{ +public: + + //! Destructor + virtual ~IGPUProgrammingServices() {} + + //! Adds a new high-level shading material renderer to the VideoDriver. + /** Currently only HLSL/D3D9 and GLSL/OpenGL are supported. + \param vertexShaderProgram String containing the source of the vertex + shader program. This can be 0 if no vertex program shall be used. + \param vertexShaderEntryPointName Name of the entry function of the + vertexShaderProgram (p.e. "main") + \param vsCompileTarget Vertex shader version the high level shader + shall be compiled to. + \param pixelShaderProgram String containing the source of the pixel + shader program. This can be 0 if no pixel shader shall be used. + \param pixelShaderEntryPointName Entry name of the function of the + pixelShaderProgram (p.e. "main") + \param psCompileTarget Pixel shader version the high level shader + shall be compiled to. + \param geometryShaderProgram String containing the source of the + geometry shader program. This can be 0 if no geometry shader shall be + used. + \param geometryShaderEntryPointName Entry name of the function of the + geometryShaderProgram (p.e. "main") + \param gsCompileTarget Geometry shader version the high level shader + shall be compiled to. + \param inType Type of vertices passed to geometry shader + \param outType Type of vertices created by geometry shader + \param verticesOut Maximal number of vertices created by geometry + shader. If 0, maximal number supported is assumed. + \param callback Pointer to an implementation of + IShaderConstantSetCallBack in which you can set the needed vertex, + pixel, and geometry shader program constants. Set this to 0 if you + don't need this. + \param baseMaterial Base material which renderstates will be used to + shade the material. + \param userData a user data int. This int can be set to any value and + will be set as parameter in the callback method when calling + OnSetConstants(). In this way it is easily possible to use the same + callback method for multiple materials and distinguish between them + during the call. + \param shaderLang a type of shading language used in current shader. + \return Number of the material type which can be set in + SMaterial::MaterialType to use the renderer. -1 is returned if an error + occured, e.g. if a shader program could not be compiled or a compile + target is not reachable. The error strings are then printed to the + error log and can be catched with a custom event receiver. */ + virtual s32 addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + const c8* geometryShaderProgram, + const c8* geometryShaderEntryPointName = "main", + E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 verticesOut = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0, + E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT) = 0; + + //! convenience function for use without geometry shaders + s32 addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName="main", + E_VERTEX_SHADER_TYPE vsCompileTarget=EVST_VS_1_1, + const c8* pixelShaderProgram=0, + const c8* pixelShaderEntryPointName="main", + E_PIXEL_SHADER_TYPE psCompileTarget=EPST_PS_1_1, + IShaderConstantSetCallBack* callback=0, + E_MATERIAL_TYPE baseMaterial=video::EMT_SOLID, + s32 userData=0, + E_GPU_SHADING_LANGUAGE shadingLang=EGSL_DEFAULT) + { + return addHighLevelShaderMaterial( + vertexShaderProgram, vertexShaderEntryPointName, + vsCompileTarget, pixelShaderProgram, + pixelShaderEntryPointName, psCompileTarget, + 0, "main", EGST_GS_4_0, + scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, + callback, baseMaterial, userData, shadingLang); + } + + //! convenience function for use with many defaults, without geometry shader + /** All shader names are set to "main" and compile targets are shader + type 1.1. + */ + s32 addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* pixelShaderProgram=0, + IShaderConstantSetCallBack* callback=0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData=0) + { + return addHighLevelShaderMaterial( + vertexShaderProgram, "main", + EVST_VS_1_1, pixelShaderProgram, + "main", EPST_PS_1_1, + 0, "main", EGST_GS_4_0, + scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, + callback, baseMaterial, userData); + } + + //! convenience function for use with many defaults, with geometry shader + /** All shader names are set to "main" and compile targets are shader + type 1.1 and geometry shader 4.0. + */ + s32 addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* pixelShaderProgram = 0, + const c8* geometryShaderProgram = 0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 verticesOut = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0 ) + { + return addHighLevelShaderMaterial( + vertexShaderProgram, "main", + EVST_VS_1_1, pixelShaderProgram, + "main", EPST_PS_1_1, + geometryShaderProgram, "main", EGST_GS_4_0, + inType, outType, verticesOut, + callback, baseMaterial, userData); + } + + //! Like IGPUProgrammingServices::addShaderMaterial(), but loads from files. + /** \param vertexShaderProgramFileName Text file containing the source + of the vertex shader program. Set to empty string if no vertex shader + shall be created. + \param vertexShaderEntryPointName Name of the entry function of the + vertexShaderProgram (p.e. "main") + \param vsCompileTarget Vertex shader version the high level shader + shall be compiled to. + \param pixelShaderProgramFileName Text file containing the source of + the pixel shader program. Set to empty string if no pixel shader shall + be created. + \param pixelShaderEntryPointName Entry name of the function of the + pixelShaderProgram (p.e. "main") + \param psCompileTarget Pixel shader version the high level shader + shall be compiled to. + \param geometryShaderProgramFileName Name of the source of + the geometry shader program. Set to empty string if no geometry shader + shall be created. + \param geometryShaderEntryPointName Entry name of the function of the + geometryShaderProgram (p.e. "main") + \param gsCompileTarget Geometry shader version the high level shader + shall be compiled to. + \param inType Type of vertices passed to geometry shader + \param outType Type of vertices created by geometry shader + \param verticesOut Maximal number of vertices created by geometry + shader. If 0, maximal number supported is assumed. + \param callback Pointer to an implementation of + IShaderConstantSetCallBack in which you can set the needed vertex, + pixel, and geometry shader program constants. Set this to 0 if you + don't need this. + \param baseMaterial Base material which renderstates will be used to + shade the material. + \param userData a user data int. This int can be set to any value and + will be set as parameter in the callback method when calling + OnSetConstants(). In this way it is easily possible to use the same + callback method for multiple materials and distinguish between them + during the call. + \param shaderLang a type of shading language used in current shader. + \return Number of the material type which can be set in + SMaterial::MaterialType to use the renderer. -1 is returned if an error + occured, e.g. if a shader program could not be compiled or a compile + target is not reachable. The error strings are then printed to the + error log and can be catched with a custom event receiver. */ + virtual s32 addHighLevelShaderMaterialFromFiles( + const io::path& vertexShaderProgramFileName, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const io::path& pixelShaderProgramFileName, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + const io::path& geometryShaderProgramFileName, + const c8* geometryShaderEntryPointName = "main", + E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 verticesOut = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0, + E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT) = 0; + + //! convenience function for use without geometry shaders + s32 addHighLevelShaderMaterialFromFiles( + const io::path& vertexShaderProgramFileName, + const c8* vertexShaderEntryPointName = "main", + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + const io::path& pixelShaderProgramFileName = "", + const c8* pixelShaderEntryPointName = "main", + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0, + E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT) + { + return addHighLevelShaderMaterialFromFiles( + vertexShaderProgramFileName, vertexShaderEntryPointName, + vsCompileTarget, pixelShaderProgramFileName, + pixelShaderEntryPointName, psCompileTarget, + "", "main", EGST_GS_4_0, + scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, + callback, baseMaterial, userData, shadingLang); + } + + //! convenience function for use with many defaults, without geometry shader + /** All shader names are set to "main" and compile targets are shader + type 1.1. + */ + s32 addHighLevelShaderMaterialFromFiles( + const io::path& vertexShaderProgramFileName, + const io::path& pixelShaderProgramFileName = "", + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0 ) + { + return addHighLevelShaderMaterialFromFiles( + vertexShaderProgramFileName, "main", + EVST_VS_1_1, pixelShaderProgramFileName, + "main", EPST_PS_1_1, + "", "main", EGST_GS_4_0, + scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, + callback, baseMaterial, userData); + } + + //! convenience function for use with many defaults, with geometry shader + /** All shader names are set to "main" and compile targets are shader + type 1.1 and geometry shader 4.0. + */ + s32 addHighLevelShaderMaterialFromFiles( + const io::path& vertexShaderProgramFileName, + const io::path& pixelShaderProgramFileName = "", + const io::path& geometryShaderProgramFileName = "", + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 verticesOut = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0 ) + { + return addHighLevelShaderMaterialFromFiles( + vertexShaderProgramFileName, "main", + EVST_VS_1_1, pixelShaderProgramFileName, + "main", EPST_PS_1_1, + geometryShaderProgramFileName, "main", EGST_GS_4_0, + inType, outType, verticesOut, + callback, baseMaterial, userData); + } + + //! Like IGPUProgrammingServices::addShaderMaterial(), but loads from files. + /** \param vertexShaderProgram Text file handle containing the source + of the vertex shader program. Set to 0 if no vertex shader shall be + created. + \param vertexShaderEntryPointName Name of the entry function of the + vertexShaderProgram + \param vsCompileTarget Vertex shader version the high level shader + shall be compiled to. + \param pixelShaderProgram Text file handle containing the source of + the pixel shader program. Set to 0 if no pixel shader shall be created. + \param pixelShaderEntryPointName Entry name of the function of the + pixelShaderProgram (p.e. "main") + \param psCompileTarget Pixel shader version the high level shader + shall be compiled to. + \param geometryShaderProgram Text file handle containing the source of + the geometry shader program. Set to 0 if no geometry shader shall be + created. + \param geometryShaderEntryPointName Entry name of the function of the + geometryShaderProgram (p.e. "main") + \param gsCompileTarget Geometry shader version the high level shader + shall be compiled to. + \param inType Type of vertices passed to geometry shader + \param outType Type of vertices created by geometry shader + \param verticesOut Maximal number of vertices created by geometry + shader. If 0, maximal number supported is assumed. + \param callback Pointer to an implementation of + IShaderConstantSetCallBack in which you can set the needed vertex and + pixel shader program constants. Set this to 0 if you don't need this. + \param baseMaterial Base material which renderstates will be used to + shade the material. + \param userData a user data int. This int can be set to any value and + will be set as parameter in the callback method when calling + OnSetConstants(). In this way it is easily possible to use the same + callback method for multiple materials and distinguish between them + during the call. + \param shaderLang a type of shading language used in current shader. + \return Number of the material type which can be set in + SMaterial::MaterialType to use the renderer. -1 is returned if an + error occured, e.g. if a shader program could not be compiled or a + compile target is not reachable. The error strings are then printed to + the error log and can be catched with a custom event receiver. */ + virtual s32 addHighLevelShaderMaterialFromFiles( + io::IReadFile* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + io::IReadFile* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + io::IReadFile* geometryShaderProgram, + const c8* geometryShaderEntryPointName = "main", + E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 verticesOut = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0, + E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT) = 0; + + //! convenience function for use without geometry shaders + s32 addHighLevelShaderMaterialFromFiles( + io::IReadFile* vertexShaderProgram, + const c8* vertexShaderEntryPointName = "main", + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + io::IReadFile* pixelShaderProgram = 0, + const c8* pixelShaderEntryPointName = "main", + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0, + E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT) + { + return addHighLevelShaderMaterialFromFiles( + vertexShaderProgram, vertexShaderEntryPointName, + vsCompileTarget, pixelShaderProgram, + pixelShaderEntryPointName, psCompileTarget, + 0, "main", EGST_GS_4_0, + scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, + callback, baseMaterial, userData, shadingLang); + } + + //! Adds a new ASM shader material renderer to the VideoDriver + /** Note that it is a good idea to call IVideoDriver::queryFeature() in + advance to check if the IVideoDriver supports the vertex and/or pixel + shader version your are using. + + The material is added to the VideoDriver like with + IVideoDriver::addMaterialRenderer() and can be used like it had been + added with that method. + \param vertexShaderProgram String containing the source of the vertex + shader program. This can be 0 if no vertex program shall be used. + + For DX8 programs, the will always input registers look like this: v0: + position, v1: normal, v2: color, v3: texture cooridnates, v4: texture + coordinates 2 if available. + + For DX9 programs, you can manually set the registers using the dcl_ + statements. + \param pixelShaderProgram String containing the source of the pixel + shader program. This can be 0 if you don't want to use a pixel shader. + \param callback Pointer to an implementation of + IShaderConstantSetCallBack in which you can set the needed vertex and + pixel shader program constants. Set this to 0 if you don't need this. + \param baseMaterial Base material which renderstates will be used to + shade the material. + \param userData a user data int. This int can be set to any value and + will be set as parameter in the callback method when calling + OnSetConstants(). In this way it is easily possible to use the same + callback method for multiple materials and distinguish between them + during the call. + \return Returns the number of the material type which can be set in + SMaterial::MaterialType to use the renderer. -1 is returned if an + error occured. -1 is returned for example if a vertex or pixel shader + program could not be compiled, the error strings are then printed out + into the error log, and can be catched with a custom event receiver. */ + virtual s32 addShaderMaterial(const c8* vertexShaderProgram = 0, + const c8* pixelShaderProgram = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0) = 0; + + //! Like IGPUProgrammingServices::addShaderMaterial(), but loads from files. + /** \param vertexShaderProgram Text file containing the source of the + vertex shader program. Set to 0 if no shader shall be created. + \param pixelShaderProgram Text file containing the source of the pixel + shader program. Set to 0 if no shader shall be created. + \param callback Pointer to an IShaderConstantSetCallback object to + which the OnSetConstants function is called. + \param baseMaterial baseMaterial + \param userData a user data int. This int can be set to any value and + will be set as parameter in the callback method when calling + OnSetConstants(). In this way it is easily possible to use the same + callback method for multiple materials and distinguish between them + during the call. + \return Returns the number of the material type which can be set in + SMaterial::MaterialType to use the renderer. -1 is returned if an + error occured. -1 is returned for example if a vertex or pixel shader + program could not be compiled, the error strings are then printed out + into the error log, and can be catched with a custom event receiver. */ + virtual s32 addShaderMaterialFromFiles(io::IReadFile* vertexShaderProgram, + io::IReadFile* pixelShaderProgram, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0) = 0; + + //! Like IGPUProgrammingServices::addShaderMaterial(), but loads from files. + /** \param vertexShaderProgramFileName Text file name containing the + source of the vertex shader program. Set to 0 if no shader shall be + created. + \param pixelShaderProgramFileName Text file name containing the source + of the pixel shader program. Set to 0 if no shader shall be created. + \param callback Pointer to an IShaderConstantSetCallback object on + which the OnSetConstants function is called. + \param baseMaterial baseMaterial + \param userData a user data int. This int can be set to any value and + will be set as parameter in the callback method when calling + OnSetConstants(). In this way it is easily possible to use the same + callback method for multiple materials and distinguish between them + during the call. + \return Returns the number of the material type which can be set in + SMaterial::MaterialType to use the renderer. -1 is returned if an + error occured. -1 is returned for example if a vertex or pixel shader + program could not be compiled, the error strings are then printed out + into the error log, and can be catched with a custom event receiver. */ + virtual s32 addShaderMaterialFromFiles(const io::path& vertexShaderProgramFileName, + const io::path& pixelShaderProgramFileName, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0) = 0; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIButton.h b/builddir/irrlicht-1.8.1/include/IGUIButton.h new file mode 100644 index 0000000..cc0ada1 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIButton.h @@ -0,0 +1,151 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_BUTTON_H_INCLUDED__ +#define __I_GUI_BUTTON_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ + +namespace video +{ + class ITexture; +} // end namespace video + +namespace gui +{ + class IGUIFont; + class IGUISpriteBank; + + enum EGUI_BUTTON_STATE + { + //! The button is not pressed + EGBS_BUTTON_UP=0, + //! The button is currently pressed down + EGBS_BUTTON_DOWN, + //! The mouse cursor is over the button + EGBS_BUTTON_MOUSE_OVER, + //! The mouse cursor is not over the button + EGBS_BUTTON_MOUSE_OFF, + //! The button has the focus + EGBS_BUTTON_FOCUSED, + //! The button doesn't have the focus + EGBS_BUTTON_NOT_FOCUSED, + //! not used, counts the number of enumerated items + EGBS_COUNT + }; + + //! Names for gui button state icons + const c8* const GUIButtonStateNames[] = + { + "buttonUp", + "buttonDown", + "buttonMouseOver", + "buttonMouseOff", + "buttonFocused", + "buttonNotFocused", + 0, + 0, + }; + + //! GUI Button interface. + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_BUTTON_CLICKED + */ + class IGUIButton : public IGUIElement + { + public: + + //! constructor + IGUIButton(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_BUTTON, environment, parent, id, rectangle) {} + + //! Sets another skin independent font. + /** If this is set to zero, the button uses the font of the skin. + \param font: New font to set. */ + virtual void setOverrideFont(IGUIFont* font=0) = 0; + + //! Gets the override font (if any) + /** \return The override font (may be 0) */ + virtual IGUIFont* getOverrideFont(void) const = 0; + + //! Get the font which is used right now for drawing + /** Currently this is the override font when one is set and the + font of the active skin otherwise */ + virtual IGUIFont* getActiveFont() const = 0; + + //! Sets an image which should be displayed on the button when it is in normal state. + /** \param image: Image to be displayed */ + virtual void setImage(video::ITexture* image=0) = 0; + + //! Sets a background image for the button when it is in normal state. + /** \param image: Texture containing the image to be displayed + \param pos: Position in the texture, where the image is located */ + virtual void setImage(video::ITexture* image, const core::rect<s32>& pos) = 0; + + //! Sets a background image for the button when it is in pressed state. + /** If no images is specified for the pressed state via + setPressedImage(), this image is also drawn in pressed state. + \param image: Image to be displayed */ + virtual void setPressedImage(video::ITexture* image=0) = 0; + + //! Sets an image which should be displayed on the button when it is in pressed state. + /** \param image: Texture containing the image to be displayed + \param pos: Position in the texture, where the image is located */ + virtual void setPressedImage(video::ITexture* image, const core::rect<s32>& pos) = 0; + + //! Sets the sprite bank used by the button + virtual void setSpriteBank(IGUISpriteBank* bank=0) = 0; + + //! Sets the animated sprite for a specific button state + /** \param index: Number of the sprite within the sprite bank, use -1 for no sprite + \param state: State of the button to set the sprite for + \param index: The sprite number from the current sprite bank + \param color: The color of the sprite + \param loop: True if the animation should loop, false if not + */ + virtual void setSprite(EGUI_BUTTON_STATE state, s32 index, + video::SColor color=video::SColor(255,255,255,255), bool loop=false) = 0; + + //! Sets if the button should behave like a push button. + /** Which means it can be in two states: Normal or Pressed. With a click on the button, + the user can change the state of the button. */ + virtual void setIsPushButton(bool isPushButton=true) = 0; + + //! Sets the pressed state of the button if this is a pushbutton + virtual void setPressed(bool pressed=true) = 0; + + //! Returns if the button is currently pressed + virtual bool isPressed() const = 0; + + //! Sets if the alpha channel should be used for drawing background images on the button (default is false) + virtual void setUseAlphaChannel(bool useAlphaChannel=true) = 0; + + //! Returns if the alpha channel should be used for drawing background images on the button + virtual bool isAlphaChannelUsed() const = 0; + + //! Returns whether the button is a push button + virtual bool isPushButton() const = 0; + + //! Sets if the button should use the skin to draw its border and button face (default is true) + virtual void setDrawBorder(bool border=true) = 0; + + //! Returns if the border and button face are being drawn using the skin + virtual bool isDrawingBorder() const = 0; + + //! Sets if the button should scale the button images to fit + virtual void setScaleImage(bool scaleImage=true) = 0; + + //! Checks whether the button scales the used images + virtual bool isScalingImage() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUICheckBox.h b/builddir/irrlicht-1.8.1/include/IGUICheckBox.h new file mode 100644 index 0000000..d965ef6 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUICheckBox.h @@ -0,0 +1,38 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_CHECKBOX_H_INCLUDED__ +#define __I_GUI_CHECKBOX_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + + //! GUI Check box interface. + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_CHECKBOX_CHANGED + */ + class IGUICheckBox : public IGUIElement + { + public: + + //! constructor + IGUICheckBox(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_CHECK_BOX, environment, parent, id, rectangle) {} + + //! Set if box is checked. + virtual void setChecked(bool checked) = 0; + + //! Returns true if box is checked. + virtual bool isChecked() const = 0; + }; + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIColorSelectDialog.h b/builddir/irrlicht-1.8.1/include/IGUIColorSelectDialog.h new file mode 100644 index 0000000..0788dbc --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIColorSelectDialog.h @@ -0,0 +1,30 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_COLOR_SELECT_DIALOG_H_INCLUDED__ +#define __I_GUI_COLOR_SELECT_DIALOG_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + + //! Standard color chooser dialog. + class IGUIColorSelectDialog : public IGUIElement + { + public: + + //! constructor + IGUIColorSelectDialog(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_COLOR_SELECT_DIALOG, environment, parent, id, rectangle) {} + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIComboBox.h b/builddir/irrlicht-1.8.1/include/IGUIComboBox.h new file mode 100644 index 0000000..ebee1ec --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIComboBox.h @@ -0,0 +1,74 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_COMBO_BOX_H_INCLUDED__ +#define __I_GUI_COMBO_BOX_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + + //! Combobox widget + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_COMBO_BOX_CHANGED + */ + class IGUIComboBox : public IGUIElement + { + public: + + //! constructor + IGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_COMBO_BOX, environment, parent, id, rectangle) {} + + //! Returns amount of items in box + virtual u32 getItemCount() const = 0; + + //! Returns string of an item. the idx may be a value from 0 to itemCount-1 + virtual const wchar_t* getItem(u32 idx) const = 0; + + //! Returns item data of an item. the idx may be a value from 0 to itemCount-1 + virtual u32 getItemData(u32 idx) const = 0; + + //! Returns index based on item data + virtual s32 getIndexForItemData(u32 data ) const = 0; + + //! Adds an item and returns the index of it + virtual u32 addItem(const wchar_t* text, u32 data = 0) = 0; + + //! Removes an item from the combo box. + /** Warning. This will change the index of all following items */ + virtual void removeItem(u32 idx) = 0; + + //! Deletes all items in the combo box + virtual void clear() = 0; + + //! Returns id of selected item. returns -1 if no item is selected. + virtual s32 getSelected() const = 0; + + //! Sets the selected item. Set this to -1 if no item should be selected + virtual void setSelected(s32 idx) = 0; + + //! Sets text justification of the text area + /** \param horizontal: EGUIA_UPPERLEFT for left justified (default), + EGUIA_LOWEERRIGHT for right justified, or EGUIA_CENTER for centered text. + \param vertical: EGUIA_UPPERLEFT to align with top edge, + EGUIA_LOWEERRIGHT for bottom edge, or EGUIA_CENTER for centered text (default). */ + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) = 0; + + //! Set the maximal number of rows for the selection listbox + virtual void setMaxSelectionRows(u32 max) = 0; + + //! Get the maximimal number of rows for the selection listbox + virtual u32 getMaxSelectionRows() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIContextMenu.h b/builddir/irrlicht-1.8.1/include/IGUIContextMenu.h new file mode 100644 index 0000000..9f5ea25 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIContextMenu.h @@ -0,0 +1,162 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_CONTEXT_MENU_H_INCLUDED__ +#define __I_GUI_CONTEXT_MENU_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + //! Close behavior. + //! Default is ECMC_REMOVE + enum ECONTEXT_MENU_CLOSE + { + //! do nothing - menu stays open + ECMC_IGNORE = 0, + + //! remove the gui element + ECMC_REMOVE = 1, + + //! call setVisible(false) + ECMC_HIDE = 2 + + // note to implementors - this is planned as bitset, so continue with 4 if you need to add further flags. + }; + + //! GUI Context menu interface. + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_ELEMENT_CLOSED + \li EGET_MENU_ITEM_SELECTED + */ + class IGUIContextMenu : public IGUIElement + { + public: + + //! constructor + IGUIContextMenu(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_CONTEXT_MENU, environment, parent, id, rectangle) {} + + //! set behavior when menus are closed + virtual void setCloseHandling(ECONTEXT_MENU_CLOSE onClose) = 0; + + //! get current behavior when the menu will be closed + virtual ECONTEXT_MENU_CLOSE getCloseHandling() const = 0; + + //! Get amount of menu items + virtual u32 getItemCount() const = 0; + + //! Adds a menu item. + /** \param text: Text of menu item. Set this to 0 to create + an separator instead of a real item, which is the same like + calling addSeparator(); + \param commandId: Command id of menu item, a simple id you may + set to whatever you want. + \param enabled: Specifies if the menu item should be enabled. + \param hasSubMenu: Set this to true if there should be a submenu + at this item. You can access this submenu via getSubMenu(). + \param checked: Specifies if the menu item should be initially checked. + \param autoChecking: Specifies if the item should be checked by clicking + \return Returns the index of the new item */ + virtual u32 addItem(const wchar_t* text, s32 commandId=-1, bool enabled=true, + bool hasSubMenu=false, bool checked=false, bool autoChecking=false) = 0; + + //! Insert a menu item at specified position. + /** \param idx: Position to insert the new element, + should be smaller than itemcount otherwise the item is added to the end. + \param text: Text of menu item. Set this to 0 to create + an separator instead of a real item, which is the same like + calling addSeparator(); + \param commandId: Command id of menu item, a simple id you may + set to whatever you want. + \param enabled: Specifies if the menu item should be enabled. + \param hasSubMenu: Set this to true if there should be a submenu + at this item. You can access this submenu via getSubMenu(). + \param checked: Specifies if the menu item should be initially checked. + \param autoChecking: Specifies if the item should be checked by clicking + \return Returns the index of the new item */ + virtual u32 insertItem(u32 idx, const wchar_t* text, s32 commandId=-1, bool enabled=true, + bool hasSubMenu=false, bool checked=false, bool autoChecking=false) = 0; + + //! Find an item by it's CommandID + /** + \param commandId: We are looking for the first item which has this commandID + \param idxStartSearch: Start searching from this index. + \return Returns the index of the item when found or otherwise -1. */ + virtual s32 findItemWithCommandId(s32 commandId, u32 idxStartSearch=0) const = 0; + + //! Adds a separator item to the menu + virtual void addSeparator() = 0; + + //! Get text of the menu item. + /** \param idx: Zero based index of the menu item */ + virtual const wchar_t* getItemText(u32 idx) const = 0; + + //! Sets text of the menu item. + /** \param idx: Zero based index of the menu item + \param text: New text of the item. */ + virtual void setItemText(u32 idx, const wchar_t* text) = 0; + + //! Check if a menu item is enabled + /** \param idx: Zero based index of the menu item */ + virtual bool isItemEnabled(u32 idx) const = 0; + + //! Sets if the menu item should be enabled. + /** \param idx: Zero based index of the menu item + \param enabled: True if it is enabled, otherwise false. */ + virtual void setItemEnabled(u32 idx, bool enabled) = 0; + + //! Sets if the menu item should be checked. + /** \param idx: Zero based index of the menu item + \param enabled: True if it is enabled, otherwise false. */ + virtual void setItemChecked(u32 idx, bool enabled) = 0; + + //! Check if a menu item is checked + /** \param idx: Zero based index of the menu item */ + virtual bool isItemChecked(u32 idx) const = 0; + + //! Removes a menu item + /** \param idx: Zero based index of the menu item */ + virtual void removeItem(u32 idx) = 0; + + //! Removes all menu items + virtual void removeAllItems() = 0; + + //! Get the selected item in the menu + /** \return Index of the selected item, -1 if none selected. */ + virtual s32 getSelectedItem() const = 0; + + //! Get the command id of a menu item + /** \param idx: Zero based index of the menu item */ + virtual s32 getItemCommandId(u32 idx) const = 0; + + //! Sets the command id of a menu item + /** \param idx: Zero based index of the menu item + \param id: Command id of menu item, a simple id you may + set to whatever you want. */ + virtual void setItemCommandId(u32 idx, s32 id) = 0; + + //! Get a pointer to the submenu of an item. + /** 0 is returned if there is no submenu + \param idx: Zero based index of the menu item + \return Returns a pointer to the submenu of an item. */ + virtual IGUIContextMenu* getSubMenu(u32 idx) const = 0; + + //! should the element change the checked status on clicking + virtual void setItemAutoChecking(u32 idx, bool autoChecking) = 0; + + //! does the element change the checked status on clicking + virtual bool getItemAutoChecking(u32 idx) const = 0; + + //! When an eventparent is set it receives events instead of the usual parent element + virtual void setEventParent(IGUIElement *parent) = 0; + }; + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIEditBox.h b/builddir/irrlicht-1.8.1/include/IGUIEditBox.h new file mode 100644 index 0000000..13a9501 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIEditBox.h @@ -0,0 +1,135 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_EDIT_BOX_H_INCLUDED__ +#define __I_GUI_EDIT_BOX_H_INCLUDED__ + +#include "IGUIElement.h" +#include "SColor.h" + +namespace irr +{ +namespace gui +{ + class IGUIFont; + + //! Single line edit box for editing simple text. + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_EDITBOX_ENTER + \li EGET_EDITBOX_CHANGED + \li EGET_EDITBOX_MARKING_CHANGED + */ + class IGUIEditBox : public IGUIElement + { + public: + + //! constructor + IGUIEditBox(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_EDIT_BOX, environment, parent, id, rectangle) {} + + //! Sets another skin independent font. + /** If this is set to zero, the button uses the font of the skin. + \param font: New font to set. */ + virtual void setOverrideFont(IGUIFont* font=0) = 0; + + //! Gets the override font (if any) + /** \return The override font (may be 0) */ + virtual IGUIFont* getOverrideFont() const = 0; + + //! Get the font which is used right now for drawing + /** Currently this is the override font when one is set and the + font of the active skin otherwise */ + virtual IGUIFont* getActiveFont() const = 0; + + //! Sets another color for the text. + /** If set, the edit box does not use the EGDC_BUTTON_TEXT color defined + in the skin, but the set color instead. You don't need to call + IGUIEditBox::enableOverrrideColor(true) after this, this is done + by this function. + If you set a color, and you want the text displayed with the color + of the skin again, call IGUIEditBox::enableOverrideColor(false); + \param color: New color of the text. */ + virtual void setOverrideColor(video::SColor color) = 0; + + //! Gets the override color + virtual video::SColor getOverrideColor() const = 0; + + //! Sets if the text should use the override color or the color in the gui skin. + /** \param enable: If set to true, the override color, which can be set + with IGUIEditBox::setOverrideColor is used, otherwise the + EGDC_BUTTON_TEXT color of the skin. */ + virtual void enableOverrideColor(bool enable) = 0; + + //! Checks if an override color is enabled + /** \return true if the override color is enabled, false otherwise */ + virtual bool isOverrideColorEnabled(void) const = 0; + + //! Sets whether to draw the background + virtual void setDrawBackground(bool draw) = 0; + + //! Turns the border on or off + /** \param border: true if you want the border to be drawn, false if not */ + virtual void setDrawBorder(bool border) = 0; + + //! Sets text justification mode + /** \param horizontal: EGUIA_UPPERLEFT for left justified (default), + EGUIA_LOWERRIGHT for right justified, or EGUIA_CENTER for centered text. + \param vertical: EGUIA_UPPERLEFT to align with top edge, + EGUIA_LOWERRIGHT for bottom edge, or EGUIA_CENTER for centered text (default). */ + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) = 0; + + //! Enables or disables word wrap. + /** \param enable: If set to true, words going over one line are + broken to the next line. */ + virtual void setWordWrap(bool enable) = 0; + + //! Checks if word wrap is enabled + /** \return true if word wrap is enabled, false otherwise */ + virtual bool isWordWrapEnabled() const = 0; + + //! Enables or disables newlines. + /** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired, + instead a newline character will be inserted. */ + virtual void setMultiLine(bool enable) = 0; + + //! Checks if multi line editing is enabled + /** \return true if multi-line is enabled, false otherwise */ + virtual bool isMultiLineEnabled() const = 0; + + //! Enables or disables automatic scrolling with cursor position + /** \param enable: If set to true, the text will move around with the cursor position */ + virtual void setAutoScroll(bool enable) = 0; + + //! Checks to see if automatic scrolling is enabled + /** \return true if automatic scrolling is enabled, false if not */ + virtual bool isAutoScrollEnabled() const = 0; + + //! Sets whether the edit box is a password box. Setting this to true will + /** disable MultiLine, WordWrap and the ability to copy with ctrl+c or ctrl+x + \param passwordBox: true to enable password, false to disable + \param passwordChar: the character that is displayed instead of letters */ + virtual void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*') = 0; + + //! Returns true if the edit box is currently a password box. + virtual bool isPasswordBox() const = 0; + + //! Gets the size area of the text in the edit box + /** \return The size in pixels of the text */ + virtual core::dimension2du getTextDimension() = 0; + + //! Sets the maximum amount of characters which may be entered in the box. + /** \param max: Maximum amount of characters. If 0, the character amount is + infinity. */ + virtual void setMax(u32 max) = 0; + + //! Returns maximum amount of characters, previously set by setMax(); + virtual u32 getMax() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIElement.h b/builddir/irrlicht-1.8.1/include/IGUIElement.h new file mode 100644 index 0000000..098cd79 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIElement.h @@ -0,0 +1,1037 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_ELEMENT_H_INCLUDED__ +#define __I_GUI_ELEMENT_H_INCLUDED__ + +#include "IAttributeExchangingObject.h" +#include "irrList.h" +#include "rect.h" +#include "irrString.h" +#include "IEventReceiver.h" +#include "EGUIElementTypes.h" +#include "EGUIAlignment.h" +#include "IAttributes.h" + +namespace irr +{ +namespace gui +{ + +class IGUIEnvironment; + +//! Base class of all GUI elements. +class IGUIElement : public virtual io::IAttributeExchangingObject, public IEventReceiver +{ +public: + + //! Constructor + IGUIElement(EGUI_ELEMENT_TYPE type, IGUIEnvironment* environment, IGUIElement* parent, + s32 id, const core::rect<s32>& rectangle) + : Parent(0), RelativeRect(rectangle), AbsoluteRect(rectangle), + AbsoluteClippingRect(rectangle), DesiredRect(rectangle), + MaxSize(0,0), MinSize(1,1), IsVisible(true), IsEnabled(true), + IsSubElement(false), NoClip(false), ID(id), IsTabStop(false), TabOrder(-1), IsTabGroup(false), + AlignLeft(EGUIA_UPPERLEFT), AlignRight(EGUIA_UPPERLEFT), AlignTop(EGUIA_UPPERLEFT), AlignBottom(EGUIA_UPPERLEFT), + Environment(environment), Type(type) + { + #ifdef _DEBUG + setDebugName("IGUIElement"); + #endif + + // if we were given a parent to attach to + if (parent) + { + parent->addChildToEnd(this); + recalculateAbsolutePosition(true); + } + } + + + //! Destructor + virtual ~IGUIElement() + { + // delete all children + core::list<IGUIElement*>::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + (*it)->Parent = 0; + (*it)->drop(); + } + } + + + //! Returns parent of this element. + IGUIElement* getParent() const + { + return Parent; + } + + + //! Returns the relative rectangle of this element. + core::rect<s32> getRelativePosition() const + { + return RelativeRect; + } + + + //! Sets the relative rectangle of this element. + /** \param r The absolute position to set */ + void setRelativePosition(const core::rect<s32>& r) + { + if (Parent) + { + const core::rect<s32>& r2 = Parent->getAbsolutePosition(); + + core::dimension2df d((f32)(r2.getSize().Width), (f32)(r2.getSize().Height)); + + if (AlignLeft == EGUIA_SCALE) + ScaleRect.UpperLeftCorner.X = (f32)r.UpperLeftCorner.X / d.Width; + if (AlignRight == EGUIA_SCALE) + ScaleRect.LowerRightCorner.X = (f32)r.LowerRightCorner.X / d.Width; + if (AlignTop == EGUIA_SCALE) + ScaleRect.UpperLeftCorner.Y = (f32)r.UpperLeftCorner.Y / d.Height; + if (AlignBottom == EGUIA_SCALE) + ScaleRect.LowerRightCorner.Y = (f32)r.LowerRightCorner.Y / d.Height; + } + + DesiredRect = r; + updateAbsolutePosition(); + } + + //! Sets the relative rectangle of this element, maintaining its current width and height + /** \param position The new relative position to set. Width and height will not be changed. */ + void setRelativePosition(const core::position2di & position) + { + const core::dimension2di mySize = RelativeRect.getSize(); + const core::rect<s32> rectangle(position.X, position.Y, + position.X + mySize.Width, position.Y + mySize.Height); + setRelativePosition(rectangle); + } + + + //! Sets the relative rectangle of this element as a proportion of its parent's area. + /** \note This method used to be 'void setRelativePosition(const core::rect<f32>& r)' + \param r The rectangle to set, interpreted as a proportion of the parent's area. + Meaningful values are in the range [0...1], unless you intend this element to spill + outside its parent. */ + void setRelativePositionProportional(const core::rect<f32>& r) + { + if (!Parent) + return; + + const core::dimension2di& d = Parent->getAbsolutePosition().getSize(); + + DesiredRect = core::rect<s32>( + core::floor32((f32)d.Width * r.UpperLeftCorner.X), + core::floor32((f32)d.Height * r.UpperLeftCorner.Y), + core::floor32((f32)d.Width * r.LowerRightCorner.X), + core::floor32((f32)d.Height * r.LowerRightCorner.Y)); + + ScaleRect = r; + + updateAbsolutePosition(); + } + + + //! Gets the absolute rectangle of this element + core::rect<s32> getAbsolutePosition() const + { + return AbsoluteRect; + } + + + //! Returns the visible area of the element. + core::rect<s32> getAbsoluteClippingRect() const + { + return AbsoluteClippingRect; + } + + + //! Sets whether the element will ignore its parent's clipping rectangle + /** \param noClip If true, the element will not be clipped by its parent's clipping rectangle. */ + void setNotClipped(bool noClip) + { + NoClip = noClip; + updateAbsolutePosition(); + } + + + //! Gets whether the element will ignore its parent's clipping rectangle + /** \return true if the element is not clipped by its parent's clipping rectangle. */ + bool isNotClipped() const + { + return NoClip; + } + + + //! Sets the maximum size allowed for this element + /** If set to 0,0, there is no maximum size */ + void setMaxSize(core::dimension2du size) + { + MaxSize = size; + updateAbsolutePosition(); + } + + + //! Sets the minimum size allowed for this element + void setMinSize(core::dimension2du size) + { + MinSize = size; + if (MinSize.Width < 1) + MinSize.Width = 1; + if (MinSize.Height < 1) + MinSize.Height = 1; + updateAbsolutePosition(); + } + + + //! The alignment defines how the borders of this element will be positioned when the parent element is resized. + void setAlignment(EGUI_ALIGNMENT left, EGUI_ALIGNMENT right, EGUI_ALIGNMENT top, EGUI_ALIGNMENT bottom) + { + AlignLeft = left; + AlignRight = right; + AlignTop = top; + AlignBottom = bottom; + + if (Parent) + { + core::rect<s32> r(Parent->getAbsolutePosition()); + + core::dimension2df d((f32)r.getSize().Width, (f32)r.getSize().Height); + + if (AlignLeft == EGUIA_SCALE) + ScaleRect.UpperLeftCorner.X = (f32)DesiredRect.UpperLeftCorner.X / d.Width; + if (AlignRight == EGUIA_SCALE) + ScaleRect.LowerRightCorner.X = (f32)DesiredRect.LowerRightCorner.X / d.Width; + if (AlignTop == EGUIA_SCALE) + ScaleRect.UpperLeftCorner.Y = (f32)DesiredRect.UpperLeftCorner.Y / d.Height; + if (AlignBottom == EGUIA_SCALE) + ScaleRect.LowerRightCorner.Y = (f32)DesiredRect.LowerRightCorner.Y / d.Height; + } + } + + + //! Updates the absolute position. + virtual void updateAbsolutePosition() + { + recalculateAbsolutePosition(false); + + // update all children + core::list<IGUIElement*>::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + (*it)->updateAbsolutePosition(); + } + } + + + //! Returns the topmost GUI element at the specific position. + /** + This will check this GUI element and all of its descendants, so it + may return this GUI element. To check all GUI elements, call this + function on device->getGUIEnvironment()->getRootGUIElement(). Note + that the root element is the size of the screen, so doing so (with + an on-screen point) will always return the root element if no other + element is above it at that point. + \param point: The point at which to find a GUI element. + \return The topmost GUI element at that point, or 0 if there are + no candidate elements at this point. + */ + IGUIElement* getElementFromPoint(const core::position2d<s32>& point) + { + IGUIElement* target = 0; + + // we have to search from back to front, because later children + // might be drawn over the top of earlier ones. + + core::list<IGUIElement*>::Iterator it = Children.getLast(); + + if (isVisible()) + { + while(it != Children.end()) + { + target = (*it)->getElementFromPoint(point); + if (target) + return target; + + --it; + } + } + + if (isVisible() && isPointInside(point)) + target = this; + + return target; + } + + + //! Returns true if a point is within this element. + /** Elements with a shape other than a rectangle should override this method */ + virtual bool isPointInside(const core::position2d<s32>& point) const + { + return AbsoluteClippingRect.isPointInside(point); + } + + + //! Adds a GUI element as new child of this element. + virtual void addChild(IGUIElement* child) + { + addChildToEnd(child); + if (child) + { + child->updateAbsolutePosition(); + } + } + + //! Removes a child. + virtual void removeChild(IGUIElement* child) + { + core::list<IGUIElement*>::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + if ((*it) == child) + { + (*it)->Parent = 0; + (*it)->drop(); + Children.erase(it); + return; + } + } + + + //! Removes this element from its parent. + virtual void remove() + { + if (Parent) + Parent->removeChild(this); + } + + + //! Draws the element and its children. + virtual void draw() + { + if ( isVisible() ) + { + core::list<IGUIElement*>::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->draw(); + } + } + + + //! animate the element and its children. + virtual void OnPostRender(u32 timeMs) + { + if ( isVisible() ) + { + core::list<IGUIElement*>::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->OnPostRender( timeMs ); + } + } + + + //! Moves this element. + virtual void move(core::position2d<s32> absoluteMovement) + { + setRelativePosition(DesiredRect + absoluteMovement); + } + + + //! Returns true if element is visible. + virtual bool isVisible() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsVisible; + } + + + //! Sets the visible state of this element. + virtual void setVisible(bool visible) + { + IsVisible = visible; + } + + + //! Returns true if this element was created as part of its parent control + virtual bool isSubElement() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsSubElement; + } + + + //! Sets whether this control was created as part of its parent. + /** For example, it is true when a scrollbar is part of a listbox. + SubElements are not saved to disk when calling guiEnvironment->saveGUI() */ + virtual void setSubElement(bool subElement) + { + IsSubElement = subElement; + } + + + //! If set to true, the focus will visit this element when using the tab key to cycle through elements. + /** If this element is a tab group (see isTabGroup/setTabGroup) then + ctrl+tab will be used instead. */ + void setTabStop(bool enable) + { + IsTabStop = enable; + } + + + //! Returns true if this element can be focused by navigating with the tab key + bool isTabStop() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsTabStop; + } + + + //! Sets the priority of focus when using the tab key to navigate between a group of elements. + /** See setTabGroup, isTabGroup and getTabGroup for information on tab groups. + Elements with a lower number are focused first */ + void setTabOrder(s32 index) + { + // negative = autonumber + if (index < 0) + { + TabOrder = 0; + IGUIElement *el = getTabGroup(); + while (IsTabGroup && el && el->Parent) + el = el->Parent; + + IGUIElement *first=0, *closest=0; + if (el) + { + // find the highest element number + el->getNextElement(-1, true, IsTabGroup, first, closest, true); + if (first) + { + TabOrder = first->getTabOrder() + 1; + } + } + + } + else + TabOrder = index; + } + + + //! Returns the number in the tab order sequence + s32 getTabOrder() const + { + return TabOrder; + } + + + //! Sets whether this element is a container for a group of elements which can be navigated using the tab key. + /** For example, windows are tab groups. + Groups can be navigated using ctrl+tab, providing isTabStop is true. */ + void setTabGroup(bool isGroup) + { + IsTabGroup = isGroup; + } + + + //! Returns true if this element is a tab group. + bool isTabGroup() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsTabGroup; + } + + + //! Returns the container element which holds all elements in this element's tab group. + IGUIElement* getTabGroup() + { + IGUIElement *ret=this; + + while (ret && !ret->isTabGroup()) + ret = ret->getParent(); + + return ret; + } + + + //! Returns true if element is enabled + /** Currently elements do _not_ care about parent-states. + So if you want to affect childs you have to enable/disable them all. + The only exception to this are sub-elements which also check their parent. + */ + virtual bool isEnabled() const + { + if ( isSubElement() && IsEnabled && getParent() ) + return getParent()->isEnabled(); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsEnabled; + } + + + //! Sets the enabled state of this element. + virtual void setEnabled(bool enabled) + { + IsEnabled = enabled; + } + + + //! Sets the new caption of this element. + virtual void setText(const wchar_t* text) + { + Text = text; + } + + + //! Returns caption of this element. + virtual const wchar_t* getText() const + { + return Text.c_str(); + } + + + //! Sets the new caption of this element. + virtual void setToolTipText(const wchar_t* text) + { + ToolTipText = text; + } + + + //! Returns caption of this element. + virtual const core::stringw& getToolTipText() const + { + return ToolTipText; + } + + + //! Returns id. Can be used to identify the element. + virtual s32 getID() const + { + return ID; + } + + + //! Sets the id of this element + virtual void setID(s32 id) + { + ID = id; + } + + + //! Called if an event happened. + virtual bool OnEvent(const SEvent& event) + { + return Parent ? Parent->OnEvent(event) : false; + } + + + //! Brings a child to front + /** \return True if successful, false if not. */ + virtual bool bringToFront(IGUIElement* element) + { + core::list<IGUIElement*>::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + if (element == (*it)) + { + Children.erase(it); + Children.push_back(element); + return true; + } + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + + //! Moves a child to the back, so it's siblings are drawn on top of it + /** \return True if successful, false if not. */ + virtual bool sendToBack(IGUIElement* child) + { + core::list<IGUIElement*>::Iterator it = Children.begin(); + if (child == (*it)) // already there + return true; + for (; it != Children.end(); ++it) + { + if (child == (*it)) + { + Children.erase(it); + Children.push_front(child); + return true; + } + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + //! Returns list with children of this element + virtual const core::list<IGUIElement*>& getChildren() const + { + return Children; + } + + + //! Finds the first element with the given id. + /** \param id: Id to search for. + \param searchchildren: Set this to true, if also children of this + element may contain the element with the searched id and they + should be searched too. + \return Returns the first element with the given id. If no element + with this id was found, 0 is returned. */ + virtual IGUIElement* getElementFromId(s32 id, bool searchchildren=false) const + { + IGUIElement* e = 0; + + core::list<IGUIElement*>::ConstIterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + if ((*it)->getID() == id) + return (*it); + + if (searchchildren) + e = (*it)->getElementFromId(id, true); + + if (e) + return e; + } + + return e; + } + + + //! returns true if the given element is a child of this one. + //! \param child: The child element to check + bool isMyChild(IGUIElement* child) const + { + if (!child) + return false; + do + { + if (child->Parent) + child = child->Parent; + + } while (child->Parent && child != this); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return child == this; + } + + + //! searches elements to find the closest next element to tab to + /** \param startOrder: The TabOrder of the current element, -1 if none + \param reverse: true if searching for a lower number + \param group: true if searching for a higher one + \param first: element with the highest/lowest known tab order depending on search direction + \param closest: the closest match, depending on tab order and direction + \param includeInvisible: includes invisible elements in the search (default=false) + \return true if successfully found an element, false to continue searching/fail */ + bool getNextElement(s32 startOrder, bool reverse, bool group, + IGUIElement*& first, IGUIElement*& closest, bool includeInvisible=false) const + { + // we'll stop searching if we find this number + s32 wanted = startOrder + ( reverse ? -1 : 1 ); + if (wanted==-2) + wanted = 1073741824; // maximum s32 + + core::list<IGUIElement*>::ConstIterator it = Children.begin(); + + s32 closestOrder, currentOrder; + + while(it != Children.end()) + { + // ignore invisible elements and their children + if ( ( (*it)->isVisible() || includeInvisible ) && + (group == true || (*it)->isTabGroup() == false) ) + { + // only check tab stops and those with the same group status + if ((*it)->isTabStop() && ((*it)->isTabGroup() == group)) + { + currentOrder = (*it)->getTabOrder(); + + // is this what we're looking for? + if (currentOrder == wanted) + { + closest = *it; + return true; + } + + // is it closer than the current closest? + if (closest) + { + closestOrder = closest->getTabOrder(); + if ( ( reverse && currentOrder > closestOrder && currentOrder < startOrder) + ||(!reverse && currentOrder < closestOrder && currentOrder > startOrder)) + { + closest = *it; + } + } + else + if ( (reverse && currentOrder < startOrder) || (!reverse && currentOrder > startOrder) ) + { + closest = *it; + } + + // is it before the current first? + if (first) + { + closestOrder = first->getTabOrder(); + + if ( (reverse && closestOrder < currentOrder) || (!reverse && closestOrder > currentOrder) ) + { + first = *it; + } + } + else + { + first = *it; + } + } + // search within children + if ((*it)->getNextElement(startOrder, reverse, group, first, closest)) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return true; + } + } + ++it; + } + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + + //! Returns the type of the gui element. + /** This is needed for the .NET wrapper but will be used + later for serializing and deserializing. + If you wrote your own GUIElements, you need to set the type for your element as first parameter + in the constructor of IGUIElement. For own (=unknown) elements, simply use EGUIET_ELEMENT as type */ + EGUI_ELEMENT_TYPE getType() const + { + return Type; + } + + //! Returns true if the gui element supports the given type. + /** This is mostly used to check if you can cast a gui element to the class that goes with the type. + Most gui elements will only support their own type, but if you derive your own classes from interfaces + you can overload this function and add a check for the type of the base-class additionally. + This allows for checks comparable to the dynamic_cast of c++ with enabled rtti. + Note that you can't do that by calling BaseClass::hasType(type), but you have to do an explicit + comparison check, because otherwise the base class usually just checks for the membervariable + Type which contains the type of your derived class. + */ + virtual bool hasType(EGUI_ELEMENT_TYPE type) const + { + return type == Type; + } + + + //! Returns the type name of the gui element. + /** This is needed serializing elements. For serializing your own elements, override this function + and return your own type name which is created by your IGUIElementFactory */ + virtual const c8* getTypeName() const + { + return GUIElementTypeNames[Type]; + } + + //! Returns the name of the element. + /** \return Name as character string. */ + virtual const c8* getName() const + { + return Name.c_str(); + } + + + //! Sets the name of the element. + /** \param name New name of the gui element. */ + virtual void setName(const c8* name) + { + Name = name; + } + + + //! Sets the name of the element. + /** \param name New name of the gui element. */ + virtual void setName(const core::stringc& name) + { + Name = name; + } + + + //! Writes attributes of the scene node. + /** Implement this to expose the attributes of your scene node for + scripting languages, editors, debuggers or xml serialization purposes. */ + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const + { + out->addString("Name", Name.c_str()); + out->addInt("Id", ID ); + out->addString("Caption", getText()); + out->addRect("Rect", DesiredRect); + out->addPosition2d("MinSize", core::position2di(MinSize.Width, MinSize.Height)); + out->addPosition2d("MaxSize", core::position2di(MaxSize.Width, MaxSize.Height)); + out->addEnum("LeftAlign", AlignLeft, GUIAlignmentNames); + out->addEnum("RightAlign", AlignRight, GUIAlignmentNames); + out->addEnum("TopAlign", AlignTop, GUIAlignmentNames); + out->addEnum("BottomAlign", AlignBottom, GUIAlignmentNames); + out->addBool("Visible", IsVisible); + out->addBool("Enabled", IsEnabled); + out->addBool("TabStop", IsTabStop); + out->addBool("TabGroup", IsTabGroup); + out->addInt("TabOrder", TabOrder); + out->addBool("NoClip", NoClip); + } + + + //! Reads attributes of the scene node. + /** Implement this to set the attributes of your scene node for + scripting languages, editors, debuggers or xml deserialization purposes. */ + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) + { + setName(in->getAttributeAsString("Name")); + setID(in->getAttributeAsInt("Id")); + setText(in->getAttributeAsStringW("Caption").c_str()); + setVisible(in->getAttributeAsBool("Visible")); + setEnabled(in->getAttributeAsBool("Enabled")); + IsTabStop = in->getAttributeAsBool("TabStop"); + IsTabGroup = in->getAttributeAsBool("TabGroup"); + TabOrder = in->getAttributeAsInt("TabOrder"); + + core::position2di p = in->getAttributeAsPosition2d("MaxSize"); + setMaxSize(core::dimension2du(p.X,p.Y)); + + p = in->getAttributeAsPosition2d("MinSize"); + setMinSize(core::dimension2du(p.X,p.Y)); + + setAlignment((EGUI_ALIGNMENT) in->getAttributeAsEnumeration("LeftAlign", GUIAlignmentNames), + (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("RightAlign", GUIAlignmentNames), + (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("TopAlign", GUIAlignmentNames), + (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("BottomAlign", GUIAlignmentNames)); + + setRelativePosition(in->getAttributeAsRect("Rect")); + + setNotClipped(in->getAttributeAsBool("NoClip")); + } + +protected: + // not virtual because needed in constructor + void addChildToEnd(IGUIElement* child) + { + if (child) + { + child->grab(); // prevent destruction when removed + child->remove(); // remove from old parent + child->LastParentRect = getAbsolutePosition(); + child->Parent = this; + Children.push_back(child); + } + } + + // not virtual because needed in constructor + void recalculateAbsolutePosition(bool recursive) + { + core::rect<s32> parentAbsolute(0,0,0,0); + core::rect<s32> parentAbsoluteClip; + f32 fw=0.f, fh=0.f; + + if (Parent) + { + parentAbsolute = Parent->AbsoluteRect; + + if (NoClip) + { + IGUIElement* p=this; + while (p && p->Parent) + p = p->Parent; + parentAbsoluteClip = p->AbsoluteClippingRect; + } + else + parentAbsoluteClip = Parent->AbsoluteClippingRect; + } + + const s32 diffx = parentAbsolute.getWidth() - LastParentRect.getWidth(); + const s32 diffy = parentAbsolute.getHeight() - LastParentRect.getHeight(); + + if (AlignLeft == EGUIA_SCALE || AlignRight == EGUIA_SCALE) + fw = (f32)parentAbsolute.getWidth(); + + if (AlignTop == EGUIA_SCALE || AlignBottom == EGUIA_SCALE) + fh = (f32)parentAbsolute.getHeight(); + + switch (AlignLeft) + { + case EGUIA_UPPERLEFT: + break; + case EGUIA_LOWERRIGHT: + DesiredRect.UpperLeftCorner.X += diffx; + break; + case EGUIA_CENTER: + DesiredRect.UpperLeftCorner.X += diffx/2; + break; + case EGUIA_SCALE: + DesiredRect.UpperLeftCorner.X = core::round32(ScaleRect.UpperLeftCorner.X * fw); + break; + } + + switch (AlignRight) + { + case EGUIA_UPPERLEFT: + break; + case EGUIA_LOWERRIGHT: + DesiredRect.LowerRightCorner.X += diffx; + break; + case EGUIA_CENTER: + DesiredRect.LowerRightCorner.X += diffx/2; + break; + case EGUIA_SCALE: + DesiredRect.LowerRightCorner.X = core::round32(ScaleRect.LowerRightCorner.X * fw); + break; + } + + switch (AlignTop) + { + case EGUIA_UPPERLEFT: + break; + case EGUIA_LOWERRIGHT: + DesiredRect.UpperLeftCorner.Y += diffy; + break; + case EGUIA_CENTER: + DesiredRect.UpperLeftCorner.Y += diffy/2; + break; + case EGUIA_SCALE: + DesiredRect.UpperLeftCorner.Y = core::round32(ScaleRect.UpperLeftCorner.Y * fh); + break; + } + + switch (AlignBottom) + { + case EGUIA_UPPERLEFT: + break; + case EGUIA_LOWERRIGHT: + DesiredRect.LowerRightCorner.Y += diffy; + break; + case EGUIA_CENTER: + DesiredRect.LowerRightCorner.Y += diffy/2; + break; + case EGUIA_SCALE: + DesiredRect.LowerRightCorner.Y = core::round32(ScaleRect.LowerRightCorner.Y * fh); + break; + } + + RelativeRect = DesiredRect; + + const s32 w = RelativeRect.getWidth(); + const s32 h = RelativeRect.getHeight(); + + // make sure the desired rectangle is allowed + if (w < (s32)MinSize.Width) + RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MinSize.Width; + if (h < (s32)MinSize.Height) + RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MinSize.Height; + if (MaxSize.Width && w > (s32)MaxSize.Width) + RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MaxSize.Width; + if (MaxSize.Height && h > (s32)MaxSize.Height) + RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MaxSize.Height; + + RelativeRect.repair(); + + AbsoluteRect = RelativeRect + parentAbsolute.UpperLeftCorner; + + if (!Parent) + parentAbsoluteClip = AbsoluteRect; + + AbsoluteClippingRect = AbsoluteRect; + AbsoluteClippingRect.clipAgainst(parentAbsoluteClip); + + LastParentRect = parentAbsolute; + + if ( recursive ) + { + // update all children + core::list<IGUIElement*>::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + (*it)->recalculateAbsolutePosition(recursive); + } + } + } + +protected: + + //! List of all children of this element + core::list<IGUIElement*> Children; + + //! Pointer to the parent + IGUIElement* Parent; + + //! relative rect of element + core::rect<s32> RelativeRect; + + //! absolute rect of element + core::rect<s32> AbsoluteRect; + + //! absolute clipping rect of element + core::rect<s32> AbsoluteClippingRect; + + //! the rectangle the element would prefer to be, + //! if it was not constrained by parent or max/min size + core::rect<s32> DesiredRect; + + //! for calculating the difference when resizing parent + core::rect<s32> LastParentRect; + + //! relative scale of the element inside its parent + core::rect<f32> ScaleRect; + + //! maximum and minimum size of the element + core::dimension2du MaxSize, MinSize; + + //! is visible? + bool IsVisible; + + //! is enabled? + bool IsEnabled; + + //! is a part of a larger whole and should not be serialized? + bool IsSubElement; + + //! does this element ignore its parent's clipping rectangle? + bool NoClip; + + //! caption + core::stringw Text; + + //! tooltip + core::stringw ToolTipText; + + //! users can set this for identificating the element by string + core::stringc Name; + + //! users can set this for identificating the element by integer + s32 ID; + + //! tab stop like in windows + bool IsTabStop; + + //! tab order + s32 TabOrder; + + //! tab groups are containers like windows, use ctrl+tab to navigate + bool IsTabGroup; + + //! tells the element how to act when its parent is resized + EGUI_ALIGNMENT AlignLeft, AlignRight, AlignTop, AlignBottom; + + //! GUI Environment + IGUIEnvironment* Environment; + + //! type of element + EGUI_ELEMENT_TYPE Type; +}; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIElementFactory.h b/builddir/irrlicht-1.8.1/include/IGUIElementFactory.h new file mode 100644 index 0000000..ca2df8b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIElementFactory.h @@ -0,0 +1,66 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_ELEMENT_FACTORY_H_INCLUDED__ +#define __I_GUI_ELEMENT_FACTORY_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "EGUIElementTypes.h" + +namespace irr +{ + +namespace gui +{ + class IGUIElement; + + //! Interface making it possible to dynamically create GUI elements + /** To be able to add custom elements to Irrlicht and to make it possible for the + scene manager to save and load them, simply implement this interface and register it + in your gui environment via IGUIEnvironment::registerGUIElementFactory. + Note: When implementing your own element factory, don't call IGUIEnvironment::grab() to + increase the reference counter of the environment. This is not necessary because the + it will grab() the factory anyway, and otherwise cyclic references will be created. + */ + class IGUIElementFactory : public virtual IReferenceCounted + { + public: + + //! adds an element to the gui environment based on its type id + /** \param type: Type of the element to add. + \param parent: Parent scene node of the new element, can be null to add to the root. + \return Pointer to the new element or null if not successful. */ + virtual IGUIElement* addGUIElement(EGUI_ELEMENT_TYPE type, IGUIElement* parent=0) = 0; + + //! adds a GUI element to the GUI Environment based on its type name + /** \param typeName: Type name of the element to add. + \param parent: Parent scene node of the new element, can be null to add it to the root. + \return Pointer to the new element or null if not successful. */ + virtual IGUIElement* addGUIElement(const c8* typeName, IGUIElement* parent=0) = 0; + + //! Get amount of GUI element types this factory is able to create + virtual s32 getCreatableGUIElementTypeCount() const = 0; + + //! Get type of a createable element type + /** \param idx: Index of the element type in this factory. Must be a value between 0 and + getCreatableGUIElementTypeCount() */ + virtual EGUI_ELEMENT_TYPE getCreateableGUIElementType(s32 idx) const = 0; + + //! Get type name of a createable GUI element type by index + /** \param idx: Index of the type in this factory. Must be a value between 0 and + getCreatableGUIElementTypeCount() */ + virtual const c8* getCreateableGUIElementTypeName(s32 idx) const = 0; + + //! returns type name of a createable GUI element + /** \param type: Type of GUI element. + \return Name of the type if this factory can create the type, otherwise 0. */ + virtual const c8* getCreateableGUIElementTypeName(EGUI_ELEMENT_TYPE type) const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // __I_GUI_ELEMENT_FACTORY_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/IGUIEnvironment.h b/builddir/irrlicht-1.8.1/include/IGUIEnvironment.h new file mode 100644 index 0000000..219e419 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIEnvironment.h @@ -0,0 +1,620 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_ENVIRONMENT_H_INCLUDED__ +#define __I_GUI_ENVIRONMENT_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "IGUISkin.h" +#include "rect.h" +#include "EMessageBoxFlags.h" +#include "IEventReceiver.h" +#include "IXMLReader.h" +#include "path.h" + +namespace irr +{ + class IOSOperator; + class IEventReceiver; + + namespace io + { + class IXMLWriter; + class IReadFile; + class IWriteFile; + class IFileSystem; + } // end namespace io + namespace video + { + class IVideoDriver; + class ITexture; + } // end namespace video + +namespace gui +{ + +class IGUIElement; +class IGUIFont; +class IGUISpriteBank; +class IGUIScrollBar; +class IGUIImage; +class IGUIMeshViewer; +class IGUICheckBox; +class IGUIListBox; +class IGUITreeView; +class IGUIImageList; +class IGUIFileOpenDialog; +class IGUIColorSelectDialog; +class IGUIInOutFader; +class IGUIStaticText; +class IGUIEditBox; +class IGUISpinBox; +class IGUITabControl; +class IGUITab; +class IGUITable; +class IGUIContextMenu; +class IGUIComboBox; +class IGUIToolBar; +class IGUIButton; +class IGUIWindow; +class IGUIElementFactory; + +//! GUI Environment. Used as factory and manager of all other GUI elements. +/** \par This element can create the following events of type EGUI_EVENT_TYPE (which are passed on to focused sub-elements): +\li EGET_ELEMENT_FOCUS_LOST +\li EGET_ELEMENT_FOCUSED +\li EGET_ELEMENT_LEFT +\li EGET_ELEMENT_HOVERED +*/ +class IGUIEnvironment : public virtual IReferenceCounted +{ +public: + + //! Draws all gui elements by traversing the GUI environment starting at the root node. + virtual void drawAll() = 0; + + //! Sets the focus to an element. + /** Causes a EGET_ELEMENT_FOCUS_LOST event followed by a + EGET_ELEMENT_FOCUSED event. If someone absorbed either of the events, + then the focus will not be changed. + \param element Pointer to the element which shall get the focus. + \return True on success, false on failure */ + virtual bool setFocus(IGUIElement* element) = 0; + + //! Returns the element which holds the focus. + /** \return Pointer to the element with focus. */ + virtual IGUIElement* getFocus() const = 0; + + //! Returns the element which was last under the mouse cursor + /** NOTE: This information is updated _after_ the user-eventreceiver + received it's mouse-events. To find the hovered element while catching + mouse events you have to use instead: + IGUIEnvironment::getRootGUIElement()->getElementFromPoint(mousePos); + \return Pointer to the element under the mouse. */ + virtual IGUIElement* getHovered() const = 0; + + //! Removes the focus from an element. + /** Causes a EGET_ELEMENT_FOCUS_LOST event. If the event is absorbed + then the focus will not be changed. + \param element Pointer to the element which shall lose the focus. + \return True on success, false on failure */ + virtual bool removeFocus(IGUIElement* element) = 0; + + //! Returns whether the element has focus + /** \param element Pointer to the element which is tested. + \return True if the element has focus, else false. */ + virtual bool hasFocus(IGUIElement* element) const = 0; + + //! Returns the current video driver. + /** \return Pointer to the video driver. */ + virtual video::IVideoDriver* getVideoDriver() const = 0; + + //! Returns the file system. + /** \return Pointer to the file system. */ + virtual io::IFileSystem* getFileSystem() const = 0; + + //! returns a pointer to the OS operator + /** \return Pointer to the OS operator. */ + virtual IOSOperator* getOSOperator() const = 0; + + //! Removes all elements from the environment. + virtual void clear() = 0; + + //! Posts an input event to the environment. + /** Usually you do not have to + use this method, it is used by the engine internally. + \param event The event to post. + \return True if succeeded, else false. */ + virtual bool postEventFromUser(const SEvent& event) = 0; + + //! This sets a new event receiver for gui events. + /** Usually you do not have to + use this method, it is used by the engine internally. + \param evr Pointer to the new receiver. */ + virtual void setUserEventReceiver(IEventReceiver* evr) = 0; + + //! Returns pointer to the current gui skin. + /** \return Pointer to the GUI skin. */ + virtual IGUISkin* getSkin() const = 0; + + //! Sets a new GUI Skin + /** You can use this to change the appearance of the whole GUI + Environment. You can set one of the built-in skins or implement your + own class derived from IGUISkin and enable it using this method. + To set for example the built-in Windows classic skin, use the following + code: + \code + gui::IGUISkin* newskin = environment->createSkin(gui::EGST_WINDOWS_CLASSIC); + environment->setSkin(newskin); + newskin->drop(); + \endcode + \param skin New skin to use. + */ + virtual void setSkin(IGUISkin* skin) = 0; + + //! Creates a new GUI Skin based on a template. + /** Use setSkin() to set the created skin. + \param type The type of the new skin. + \return Pointer to the created skin. + If you no longer need it, you should call IGUISkin::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IGUISkin* createSkin(EGUI_SKIN_TYPE type) = 0; + + + //! Creates the image list from the given texture. + /** \param texture Texture to split into images + \param imageSize Dimension of each image + \param useAlphaChannel Flag whether alpha channel of the texture should be honored. + \return Pointer to the font. Returns 0 if the font could not be loaded. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUIImageList* createImageList( video::ITexture* texture, + core::dimension2d<s32> imageSize, + bool useAlphaChannel ) = 0; + + //! Returns pointer to the font with the specified filename. + /** Loads the font if it was not loaded before. + \param filename Filename of the Font. + \return Pointer to the font. Returns 0 if the font could not be loaded. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUIFont* getFont(const io::path& filename) = 0; + + //! Adds an externally loaded font to the font list. + /** This method allows to attach an already loaded font to the list of + existing fonts. The font is grabbed if non-null and adding was successful. + \param name Name the font should be stored as. + \param font Pointer to font to add. + \return Pointer to the font stored. This can differ from given parameter if the name previously existed. */ + virtual IGUIFont* addFont(const io::path& name, IGUIFont* font) = 0; + + //! remove loaded font + virtual void removeFont(IGUIFont* font) = 0; + + //! Returns the default built-in font. + /** \return Pointer to the default built-in font. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUIFont* getBuiltInFont() const = 0; + + //! Returns pointer to the sprite bank with the specified file name. + /** Loads the bank if it was not loaded before. + \param filename Filename of the sprite bank's origin. + \return Pointer to the sprite bank. Returns 0 if it could not be loaded. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUISpriteBank* getSpriteBank(const io::path& filename) = 0; + + //! Adds an empty sprite bank to the manager + /** \param name Name of the new sprite bank. + \return Pointer to the sprite bank. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUISpriteBank* addEmptySpriteBank(const io::path& name) = 0; + + //! Returns the root gui element. + /** This is the first gui element, the (direct or indirect) parent of all + other gui elements. It is a valid IGUIElement, with dimensions the same + size as the screen. + \return Pointer to the root element of the GUI. The returned pointer + should not be dropped. See IReferenceCounted::drop() for more + information. */ + virtual IGUIElement* getRootGUIElement() = 0; + + //! Adds a button element. + /** \param rectangle Rectangle specifying the borders of the button. + \param parent Parent gui element of the button. + \param id Id with which the gui element can be identified. + \param text Text displayed on the button. + \param tooltiptext Text displayed in the tooltip. + \return Pointer to the created button. Returns 0 if an error occurred. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUIButton* addButton(const core::rect<s32>& rectangle, + IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0, const wchar_t* tooltiptext = 0) = 0; + + //! Adds an empty window element. + /** \param rectangle Rectangle specifying the borders of the window. + \param modal Defines if the dialog is modal. This means, that all other + gui elements which were created before the window cannot be used until + it is removed. + \param text Text displayed as the window title. + \param parent Parent gui element of the window. + \param id Id with which the gui element can be identified. + \return Pointer to the created window. Returns 0 if an error occurred. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUIWindow* addWindow(const core::rect<s32>& rectangle, bool modal = false, + const wchar_t* text=0, IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a modal screen. + /** This control stops its parent's members from being able to receive + input until its last child is removed, it then deletes itself. + \param parent Parent gui element of the modal. + \return Pointer to the created modal. Returns 0 if an error occurred. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUIElement* addModalScreen(IGUIElement* parent) = 0; + + //! Adds a message box. + /** \param caption Text to be displayed the title of the message box. + \param text Text to be displayed in the body of the message box. + \param modal Defines if the dialog is modal. This means, that all other + gui elements which were created before the message box cannot be used + until this messagebox is removed. + \param flags Flags specifying the layout of the message box. For example + to create a message box with an OK and a CANCEL button on it, set this + to (EMBF_OK | EMBF_CANCEL). + \param parent Parent gui element of the message box. + \param id Id with which the gui element can be identified. + \param image Optional texture which will be displayed beside the text as an image + \return Pointer to the created message box. Returns 0 if an error + occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIWindow* addMessageBox(const wchar_t* caption, const wchar_t* text=0, + bool modal = true, s32 flags = EMBF_OK, IGUIElement* parent=0, s32 id=-1, video::ITexture* image=0) = 0; + + //! Adds a scrollbar. + /** \param horizontal Specifies if the scroll bar is drawn horizontal + or vertical. + \param rectangle Rectangle specifying the borders of the scrollbar. + \param parent Parent gui element of the scroll bar. + \param id Id to identify the gui element. + \return Pointer to the created scrollbar. Returns 0 if an error + occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIScrollBar* addScrollBar(bool horizontal, const core::rect<s32>& rectangle, + IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds an image element. + /** \param image Image to be displayed. + \param pos Position of the image. The width and height of the image is + taken from the image. + \param useAlphaChannel Sets if the image should use the alpha channel + of the texture to draw itself. + \param parent Parent gui element of the image. + \param id Id to identify the gui element. + \param text Title text of the image. + \return Pointer to the created image element. Returns 0 if an error + occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIImage* addImage(video::ITexture* image, core::position2d<s32> pos, + bool useAlphaChannel=true, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0) = 0; + + //! Adds an image element. + /** Use IGUIImage::setImage later to set the image to be displayed. + \param rectangle Rectangle specifying the borders of the image. + \param parent Parent gui element of the image. + \param id Id to identify the gui element. + \param text Title text of the image. + \param useAlphaChannel Sets if the image should use the alpha channel + of the texture to draw itself. + \return Pointer to the created image element. Returns 0 if an error + occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIImage* addImage(const core::rect<s32>& rectangle, + IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0, bool useAlphaChannel=true) = 0; + + //! Adds a checkbox element. + /** \param checked Define the initial state of the check box. + \param rectangle Rectangle specifying the borders of the check box. + \param parent Parent gui element of the check box. + \param id Id to identify the gui element. + \param text Title text of the check box. + \return Pointer to the created check box. Returns 0 if an error + occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUICheckBox* addCheckBox(bool checked, const core::rect<s32>& rectangle, + IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0) = 0; + + //! Adds a list box element. + /** \param rectangle Rectangle specifying the borders of the list box. + \param parent Parent gui element of the list box. + \param id Id to identify the gui element. + \param drawBackground Flag whether the background should be drawn. + \return Pointer to the created list box. Returns 0 if an error occurred. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUIListBox* addListBox(const core::rect<s32>& rectangle, + IGUIElement* parent=0, s32 id=-1, bool drawBackground=false) = 0; + + //! Adds a tree view element. + /** \param rectangle Position and dimension of list box. + \param parent Parent gui element of the list box. + \param id Id to identify the gui element. + \param drawBackground Flag whether the background should be drawn. + \param scrollBarVertical Flag whether a vertical scrollbar should be used + \param scrollBarHorizontal Flag whether a horizontal scrollbar should be used + \return Pointer to the created list box. Returns 0 if an error occurred. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUITreeView* addTreeView(const core::rect<s32>& rectangle, + IGUIElement* parent=0, s32 id=-1, bool drawBackground=false, + bool scrollBarVertical = true, bool scrollBarHorizontal = false) = 0; + + //! Adds a mesh viewer. Not 100% implemented yet. + /** \param rectangle Rectangle specifying the borders of the mesh viewer. + \param parent Parent gui element of the mesh viewer. + \param id Id to identify the gui element. + \param text Title text of the mesh viewer. + \return Pointer to the created mesh viewer. Returns 0 if an error + occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIMeshViewer* addMeshViewer(const core::rect<s32>& rectangle, + IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0) = 0; + + //! Adds a file open dialog. + /** \param title Text to be displayed as the title of the dialog. + \param modal Defines if the dialog is modal. This means, that all other + gui elements which were created before the message box cannot be used + until this messagebox is removed. + \param parent Parent gui element of the dialog. + \param id Id to identify the gui element. + \param restoreCWD If set to true, the current workingn directory will be + restored after the dialog is closed in some way. Otherwise the working + directory will be the one that the file dialog was last showing. + \param startDir Optional path for which the file dialog will be opened. + \return Pointer to the created file open dialog. Returns 0 if an error + occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIFileOpenDialog* addFileOpenDialog(const wchar_t* title=0, + bool modal=true, IGUIElement* parent=0, s32 id=-1, + bool restoreCWD=false, io::path::char_type* startDir=0) = 0; + + //! Adds a color select dialog. + /** \param title The title of the dialog. + \param modal Defines if the dialog is modal. This means, that all other + gui elements which were created before the dialog cannot be used + until it is removed. + \param parent The parent of the dialog. + \param id The ID of the dialog. + \return Pointer to the created file open dialog. Returns 0 if an error + occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIColorSelectDialog* addColorSelectDialog(const wchar_t* title = 0, + bool modal=true, IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a static text. + /** \param text Text to be displayed. Can be altered after creation by SetText(). + \param rectangle Rectangle specifying the borders of the static text + \param border Set to true if the static text should have a 3d border. + \param wordWrap Enable if the text should wrap into multiple lines. + \param parent Parent item of the element, e.g. a window. + \param id The ID of the element. + \param fillBackground Enable if the background shall be filled. + Defaults to false. + \return Pointer to the created static text. Returns 0 if an error + occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIStaticText* addStaticText(const wchar_t* text, const core::rect<s32>& rectangle, + bool border=false, bool wordWrap=true, IGUIElement* parent=0, s32 id=-1, + bool fillBackground = false) = 0; + + //! Adds an edit box. + /** Supports unicode input from every keyboard around the world, + scrolling, copying and pasting (exchanging data with the clipboard + directly), maximum character amount, marking, and all shortcuts like + ctrl+X, ctrl+V, ctrl+C, shift+Left, shift+Right, Home, End, and so on. + \param text Text to be displayed. Can be altered after creation + by setText(). + \param rectangle Rectangle specifying the borders of the edit box. + \param border Set to true if the edit box should have a 3d border. + \param parent Parent item of the element, e.g. a window. + Set it to 0 to place the edit box directly in the environment. + \param id The ID of the element. + \return Pointer to the created edit box. Returns 0 if an error occurred. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUIEditBox* addEditBox(const wchar_t* text, const core::rect<s32>& rectangle, + bool border=true, IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a spin box. + /** An edit box with up and down buttons + \param text Text to be displayed. Can be altered after creation by setText(). + \param rectangle Rectangle specifying the borders of the spin box. + \param border Set to true if the spin box should have a 3d border. + \param parent Parent item of the element, e.g. a window. + Set it to 0 to place the spin box directly in the environment. + \param id The ID of the element. + \return Pointer to the created spin box. Returns 0 if an error occurred. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUISpinBox* addSpinBox(const wchar_t* text, const core::rect<s32>& rectangle, + bool border=true,IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds an element for fading in or out. + /** \param rectangle Rectangle specifying the borders of the fader. + If the pointer is NULL, the whole screen is used. + \param parent Parent item of the element, e.g. a window. + \param id An identifier for the fader. + \return Pointer to the created in-out-fader. Returns 0 if an error + occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIInOutFader* addInOutFader(const core::rect<s32>* rectangle=0, IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a tab control to the environment. + /** \param rectangle Rectangle specifying the borders of the tab control. + \param parent Parent item of the element, e.g. a window. + Set it to 0 to place the tab control directly in the environment. + \param fillbackground Specifies if the background of the tab control + should be drawn. + \param border Specifies if a flat 3d border should be drawn. This is + usually not necessary unless you place the control directly into + the environment without a window as parent. + \param id An identifier for the tab control. + \return Pointer to the created tab control element. Returns 0 if an + error occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUITabControl* addTabControl(const core::rect<s32>& rectangle, + IGUIElement* parent=0, bool fillbackground=false, + bool border=true, s32 id=-1) = 0; + + //! Adds tab to the environment. + /** You can use this element to group other elements. This is not used + for creating tabs on tab controls, please use IGUITabControl::addTab() + for this instead. + \param rectangle Rectangle specifying the borders of the tab. + \param parent Parent item of the element, e.g. a window. + Set it to 0 to place the tab directly in the environment. + \param id An identifier for the tab. + \return Pointer to the created tab. Returns 0 if an + error occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUITab* addTab(const core::rect<s32>& rectangle, + IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a context menu to the environment. + /** \param rectangle Rectangle specifying the borders of the menu. + Note that the menu is resizing itself based on what items you add. + \param parent Parent item of the element, e.g. a window. + Set it to 0 to place the menu directly in the environment. + \param id An identifier for the menu. + \return Pointer to the created context menu. Returns 0 if an + error occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIContextMenu* addContextMenu(const core::rect<s32>& rectangle, + IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a menu to the environment. + /** This is like the menu you can find on top of most windows in modern + graphical user interfaces. + \param parent Parent item of the element, e.g. a window. + Set it to 0 to place the menu directly in the environment. + \param id An identifier for the menu. + \return Pointer to the created menu. Returns 0 if an + error occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIContextMenu* addMenu(IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a toolbar to the environment. + /** It is like a menu that is always placed on top of its parent, and + contains buttons. + \param parent Parent item of the element, e.g. a window. + Set it to 0 to place the tool bar directly in the environment. + \param id An identifier for the tool bar. + \return Pointer to the created tool bar. Returns 0 if an + error occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIToolBar* addToolBar(IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a combo box to the environment. + /** \param rectangle Rectangle specifying the borders of the combo box. + \param parent Parent item of the element, e.g. a window. + Set it to 0 to place the combo box directly in the environment. + \param id An identifier for the combo box. + \return Pointer to the created combo box. Returns 0 if an + error occurred. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IGUIComboBox* addComboBox(const core::rect<s32>& rectangle, + IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a table to the environment + /** \param rectangle Rectangle specifying the borders of the table. + \param parent Parent item of the element, e.g. a window. Set it to 0 + to place the element directly in the environment. + \param id An identifier for the table. + \param drawBackground Flag whether the background should be drawn. + \return Pointer to the created table. Returns 0 if an error occurred. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUITable* addTable(const core::rect<s32>& rectangle, + IGUIElement* parent=0, s32 id=-1, bool drawBackground=false) =0; + + //! Get the default element factory which can create all built-in elements + /** \return Pointer to the factory. + This pointer should not be dropped. See IReferenceCounted::drop() for + more information. */ + virtual IGUIElementFactory* getDefaultGUIElementFactory() const = 0; + + //! Adds an element factory to the gui environment. + /** Use this to extend the gui environment with new element types which + it should be able to create automatically, for example when loading + data from xml files. + \param factoryToAdd Pointer to new factory. */ + virtual void registerGUIElementFactory(IGUIElementFactory* factoryToAdd) = 0; + + //! Get amount of registered gui element factories. + /** \return Amount of registered gui element factories. */ + virtual u32 getRegisteredGUIElementFactoryCount() const = 0; + + //! Get a gui element factory by index + /** \param index Index of the factory. + \return Factory at given index, or 0 if no such factory exists. */ + virtual IGUIElementFactory* getGUIElementFactory(u32 index) const = 0; + + //! Adds a GUI element by its name + /** Each factory is checked if it can create an element of the given + name. The first match will be created. + \param elementName Name of the element to be created. + \param parent Parent of the new element, if not 0. + \return New GUI element, or 0 if no such element exists. */ + virtual IGUIElement* addGUIElement(const c8* elementName, IGUIElement* parent=0) = 0; + + //! Saves the current gui into a file. + /** \param filename Name of the file. + \param start The GUIElement to start with. Root if 0. + \return True if saving succeeded, else false. */ + virtual bool saveGUI(const io::path& filename, IGUIElement* start=0) = 0; + + //! Saves the current gui into a file. + /** \param file The file to write to. + \param start The GUIElement to start with. Root if 0. + \return True if saving succeeded, else false. */ + virtual bool saveGUI(io::IWriteFile* file, IGUIElement* start=0) = 0; + + //! Loads the gui. Note that the current gui is not cleared before. + /** When a parent is set the elements will be added below the parent, the parent itself does not deserialize. + When the file contains skin-settings from the gui-environment those are always serialized into the + guienvironment independent of the parent setting. + \param filename Name of the file. + \param parent Parent for the loaded GUI, root if 0. + \return True if loading succeeded, else false. */ + virtual bool loadGUI(const io::path& filename, IGUIElement* parent=0) = 0; + + //! Loads the gui. Note that the current gui is not cleared before. + /** When a parent is set the elements will be added below the parent, the parent itself does not deserialize. + When the file contains skin-settings from the gui-environment those are always serialized into the + guienvironment independent of the parent setting. + \param file The file to load from. + \param parent Parent for the loaded GUI, root if 0. + \return True if loading succeeded, else false. */ + virtual bool loadGUI(io::IReadFile* file, IGUIElement* parent=0) = 0; + + //! Writes attributes of the gui environment + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const =0; + + //! Reads attributes of the gui environment + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)=0; + + //! writes an element + virtual void writeGUIElement(io::IXMLWriter* writer, IGUIElement* node) =0; + + //! reads an element + virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* node) =0; +}; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIFileOpenDialog.h b/builddir/irrlicht-1.8.1/include/IGUIFileOpenDialog.h new file mode 100644 index 0000000..f89413b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIFileOpenDialog.h @@ -0,0 +1,44 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_FILE_OPEN_DIALOG_H_INCLUDED__ +#define __I_GUI_FILE_OPEN_DIALOG_H_INCLUDED__ + +#include "IGUIElement.h" +#include "path.h" + +namespace irr +{ +namespace gui +{ + + //! Standard file chooser dialog. + /** \warning When the user selects a folder this does change the current working directory + + \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_DIRECTORY_SELECTED + \li EGET_FILE_SELECTED + \li EGET_FILE_CHOOSE_DIALOG_CANCELLED + */ + class IGUIFileOpenDialog : public IGUIElement + { + public: + + //! constructor + IGUIFileOpenDialog(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_FILE_OPEN_DIALOG, environment, parent, id, rectangle) {} + + //! Returns the filename of the selected file. Returns NULL, if no file was selected. + virtual const wchar_t* getFileName() const = 0; + + //! Returns the directory of the selected file. Returns NULL, if no directory was selected. + virtual const io::path& getDirectoryName() = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIFont.h b/builddir/irrlicht-1.8.1/include/IGUIFont.h new file mode 100644 index 0000000..2e97c82 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIFont.h @@ -0,0 +1,104 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_FONT_H_INCLUDED__ +#define __I_GUI_FONT_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SColor.h" +#include "rect.h" +#include "irrString.h" + +namespace irr +{ +namespace gui +{ + +//! An enum for the different types of GUI font. +enum EGUI_FONT_TYPE +{ + //! Bitmap fonts loaded from an XML file or a texture. + EGFT_BITMAP = 0, + + //! Scalable vector fonts loaded from an XML file. + /** These fonts reside in system memory and use no video memory + until they are displayed. These are slower than bitmap fonts + but can be easily scaled and rotated. */ + EGFT_VECTOR, + + //! A font which uses a the native API provided by the operating system. + /** Currently not used. */ + EGFT_OS, + + //! An external font type provided by the user. + EGFT_CUSTOM +}; + +//! Font interface. +class IGUIFont : public virtual IReferenceCounted +{ +public: + + //! Draws some text and clips it to the specified rectangle if wanted. + /** \param text: Text to draw + \param position: Rectangle specifying position where to draw the text. + \param color: Color of the text + \param hcenter: Specifies if the text should be centered horizontally into the rectangle. + \param vcenter: Specifies if the text should be centered vertically into the rectangle. + \param clip: Optional pointer to a rectangle against which the text will be clipped. + If the pointer is null, no clipping will be done. */ + virtual void draw(const core::stringw& text, const core::rect<s32>& position, + video::SColor color, bool hcenter=false, bool vcenter=false, + const core::rect<s32>* clip=0) = 0; + + //! Calculates the width and height of a given string of text. + /** \return Returns width and height of the area covered by the text if + it would be drawn. */ + virtual core::dimension2d<u32> getDimension(const wchar_t* text) const = 0; + + //! Calculates the index of the character in the text which is on a specific position. + /** \param text: Text string. + \param pixel_x: X pixel position of which the index of the character will be returned. + \return Returns zero based index of the character in the text, and -1 if no no character + is on this position. (=the text is too short). */ + virtual s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const = 0; + + //! Returns the type of this font + virtual EGUI_FONT_TYPE getType() const { return EGFT_CUSTOM; } + + //! Sets global kerning width for the font. + virtual void setKerningWidth (s32 kerning) = 0; + + //! Sets global kerning height for the font. + virtual void setKerningHeight (s32 kerning) = 0; + + //! Gets kerning values (distance between letters) for the font. If no parameters are provided, + /** the global kerning distance is returned. + \param thisLetter: If this parameter is provided, the left side kerning + for this letter is added to the global kerning value. For example, a + space might only be one pixel wide, but it may be displayed as several + pixels. + \param previousLetter: If provided, kerning is calculated for both + letters and added to the global kerning value. For example, in a font + which supports kerning pairs a string such as 'Wo' may have the 'o' + tucked neatly under the 'W'. + */ + virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const = 0; + + //! Returns the distance between letters + virtual s32 getKerningHeight() const = 0; + + //! Define which characters should not be drawn by the font. + /** For example " " would not draw any space which is usually blank in + most fonts. + \param s String of symbols which are not send down to the videodriver + */ + virtual void setInvisibleCharacters( const wchar_t *s ) = 0; +}; + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIFontBitmap.h b/builddir/irrlicht-1.8.1/include/IGUIFontBitmap.h new file mode 100644 index 0000000..c05a652 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIFontBitmap.h @@ -0,0 +1,46 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_FONT_BITMAP_H_INCLUDED__ +#define __I_GUI_FONT_BITMAP_H_INCLUDED__ + +#include "IGUIFont.h" + +namespace irr +{ +namespace gui +{ + class IGUISpriteBank; + +//! Font interface. +class IGUIFontBitmap : public IGUIFont +{ +public: + + //! Returns the type of this font + virtual EGUI_FONT_TYPE getType() const { return EGFT_BITMAP; } + + //! returns the parsed Symbol Information + virtual IGUISpriteBank* getSpriteBank() const = 0; + + //! returns the sprite number from a given character + virtual u32 getSpriteNoFromChar(const wchar_t *c) const = 0; + + //! Gets kerning values (distance between letters) for the font. If no parameters are provided, + /** the global kerning distance is returned. + \param thisLetter: If this parameter is provided, the left side kerning for this letter is added + to the global kerning value. For example, a space might only be one pixel wide, but it may + be displayed as several pixels. + \param previousLetter: If provided, kerning is calculated for both letters and added to the global + kerning value. For example, EGFT_BITMAP will add the right kerning value of previousLetter to the + left side kerning value of thisLetter, then add the global value. + */ + virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const = 0; +}; + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIImage.h b/builddir/irrlicht-1.8.1/include/IGUIImage.h new file mode 100644 index 0000000..5e6d347 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIImage.h @@ -0,0 +1,58 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_IMAGE_H_INCLUDED__ +#define __I_GUI_IMAGE_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace video +{ + class ITexture; +} +namespace gui +{ + + //! GUI element displaying an image. + class IGUIImage : public IGUIElement + { + public: + + //! constructor + IGUIImage(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_IMAGE, environment, parent, id, rectangle) {} + + //! Sets an image texture + virtual void setImage(video::ITexture* image) = 0; + + //! Gets the image texture + virtual video::ITexture* getImage() const = 0; + + //! Sets the color of the image + virtual void setColor(video::SColor color) = 0; + + //! Sets if the image should scale to fit the element + virtual void setScaleImage(bool scale) = 0; + + //! Sets if the image should use its alpha channel to draw itself + virtual void setUseAlphaChannel(bool use) = 0; + + //! Gets the color of the image + virtual video::SColor getColor() const = 0; + + //! Returns true if the image is scaled to fit, false if not + virtual bool isImageScaled() const = 0; + + //! Returns true if the image is using the alpha channel, false if not + virtual bool isAlphaChannelUsed() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIImageList.h b/builddir/irrlicht-1.8.1/include/IGUIImageList.h new file mode 100644 index 0000000..fb4ca4b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIImageList.h @@ -0,0 +1,45 @@ +// This file is part of the "Irrlicht Engine". +// written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de + +#ifndef __I_GUI_IMAGE_LIST_H_INCLUDED__ +#define __I_GUI_IMAGE_LIST_H_INCLUDED__ + +#include "IGUIElement.h" +#include "rect.h" +#include "irrTypes.h" + +namespace irr +{ +namespace gui +{ + +//! Font interface. +class IGUIImageList : public virtual IReferenceCounted +{ +public: + + //! Destructor + virtual ~IGUIImageList() {}; + + //! Draws an image and clips it to the specified rectangle if wanted + //! \param index: Index of the image + //! \param destPos: Position of the image to draw + //! \param clip: Optional pointer to a rectalgle against which the text will be clipped. + //! If the pointer is null, no clipping will be done. + virtual void draw(s32 index, const core::position2d<s32>& destPos, + const core::rect<s32>* clip = 0) = 0; + + //! Returns the count of Images in the list. + //! \return Returns the count of Images in the list. + virtual s32 getImageCount() const = 0; + + //! Returns the size of the images in the list. + //! \return Returns the size of the images in the list. + virtual core::dimension2d<s32> getImageSize() const = 0; +}; + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIInOutFader.h b/builddir/irrlicht-1.8.1/include/IGUIInOutFader.h new file mode 100644 index 0000000..6846d7b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIInOutFader.h @@ -0,0 +1,67 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_IN_OUT_FADER_H_INCLUDED__ +#define __I_GUI_IN_OUT_FADER_H_INCLUDED__ + +#include "IGUIElement.h" +#include "SColor.h" + +namespace irr +{ +namespace gui +{ + + //! Element for fading out or in + /** Here is a small example on how the class is used. In this example we fade + in from a total red screen in the beginning. As you can see, the fader is not + only useful for dramatic in and out fading, but also to show that the player + is hit in a first person shooter game for example. + \code + gui::IGUIInOutFader* fader = device->getGUIEnvironment()->addInOutFader(); + fader->setColor(video::SColor(0,255,0,0)); + fader->fadeIn(4000); + \endcode + */ + class IGUIInOutFader : public IGUIElement + { + public: + + //! constructor + IGUIInOutFader(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_IN_OUT_FADER, environment, parent, id, rectangle) {} + + //! Gets the color to fade out to or to fade in from. + virtual video::SColor getColor() const = 0; + + //! Sets the color to fade out to or to fade in from. + /** \param color: Color to where it is faded out od from it is faded in. */ + virtual void setColor(video::SColor color) = 0; + virtual void setColor(video::SColor source, video::SColor dest) = 0; + + //! Starts the fade in process. + /** In the beginning the whole rect is drawn by the set color + (black by default) and at the end of the overgiven time the + color has faded out. + \param time: Time specifying how long it should need to fade in, + in milliseconds. */ + virtual void fadeIn(u32 time) = 0; + + //! Starts the fade out process. + /** In the beginning everything is visible, and at the end of + the time only the set color (black by the fault) will be drawn. + \param time: Time specifying how long it should need to fade out, + in milliseconds. */ + virtual void fadeOut(u32 time) = 0; + + //! Returns if the fade in or out process is done. + virtual bool isReady() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIListBox.h b/builddir/irrlicht-1.8.1/include/IGUIListBox.h new file mode 100644 index 0000000..de922ce --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIListBox.h @@ -0,0 +1,138 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_LIST_BOX_H_INCLUDED__ +#define __I_GUI_LIST_BOX_H_INCLUDED__ + +#include "IGUIElement.h" +#include "SColor.h" + +namespace irr +{ +namespace gui +{ + class IGUISpriteBank; + + //! Enumeration for listbox colors + enum EGUI_LISTBOX_COLOR + { + //! Color of text + EGUI_LBC_TEXT=0, + //! Color of selected text + EGUI_LBC_TEXT_HIGHLIGHT, + //! Color of icon + EGUI_LBC_ICON, + //! Color of selected icon + EGUI_LBC_ICON_HIGHLIGHT, + //! Not used, just counts the number of available colors + EGUI_LBC_COUNT + }; + + + //! Default list box GUI element. + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_LISTBOX_CHANGED + \li EGET_LISTBOX_SELECTED_AGAIN + */ + class IGUIListBox : public IGUIElement + { + public: + //! constructor + IGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_LIST_BOX, environment, parent, id, rectangle) {} + + //! returns amount of list items + virtual u32 getItemCount() const = 0; + + //! returns string of a list item. the may id be a value from 0 to itemCount-1 + virtual const wchar_t* getListItem(u32 id) const = 0; + + //! adds an list item, returns id of item + virtual u32 addItem(const wchar_t* text) = 0; + + //! adds an list item with an icon + /** \param text Text of list entry + \param icon Sprite index of the Icon within the current sprite bank. Set it to -1 if you want no icon + \return The id of the new created item */ + virtual u32 addItem(const wchar_t* text, s32 icon) = 0; + + //! Removes an item from the list + virtual void removeItem(u32 index) = 0; + + //! get the the id of the item at the given absolute coordinates + /** \return The id of the listitem or -1 when no item is at those coordinates*/ + virtual s32 getItemAt(s32 xpos, s32 ypos) const = 0; + + //! Returns the icon of an item + virtual s32 getIcon(u32 index) const = 0; + + //! Sets the sprite bank which should be used to draw list icons. + /** This font is set to the sprite bank of the built-in-font by + default. A sprite can be displayed in front of every list item. + An icon is an index within the icon sprite bank. Several + default icons are available in the skin through getIcon. */ + virtual void setSpriteBank(IGUISpriteBank* bank) = 0; + + //! clears the list, deletes all items in the listbox + virtual void clear() = 0; + + //! returns id of selected item. returns -1 if no item is selected. + virtual s32 getSelected() const = 0; + + //! sets the selected item. Set this to -1 if no item should be selected + virtual void setSelected(s32 index) = 0; + + //! sets the selected item. Set this to 0 if no item should be selected + virtual void setSelected(const wchar_t *item) = 0; + + //! set whether the listbox should scroll to newly selected items + virtual void setAutoScrollEnabled(bool scroll) = 0; + + //! returns true if automatic scrolling is enabled, false if not. + virtual bool isAutoScrollEnabled() const = 0; + + //! set all item colors at given index to color + virtual void setItemOverrideColor(u32 index, video::SColor color) = 0; + + //! set all item colors of specified type at given index to color + virtual void setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, video::SColor color) = 0; + + //! clear all item colors at index + virtual void clearItemOverrideColor(u32 index) = 0; + + //! clear item color at index for given colortype + virtual void clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) = 0; + + //! has the item at index its color overwritten? + virtual bool hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const = 0; + + //! return the overwrite color at given item index. + virtual video::SColor getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const = 0; + + //! return the default color which is used for the given colorType + virtual video::SColor getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const = 0; + + //! set the item at the given index + virtual void setItem(u32 index, const wchar_t* text, s32 icon) = 0; + + //! Insert the item at the given index + /** \return The index on success or -1 on failure. */ + virtual s32 insertItem(u32 index, const wchar_t* text, s32 icon) = 0; + + //! Swap the items at the given indices + virtual void swapItems(u32 index1, u32 index2) = 0; + + //! set global itemHeight + virtual void setItemHeight( s32 height ) = 0; + + //! Sets whether to draw the background + virtual void setDrawBackground(bool draw) = 0; +}; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIMeshViewer.h b/builddir/irrlicht-1.8.1/include/IGUIMeshViewer.h new file mode 100644 index 0000000..62ff1ab --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIMeshViewer.h @@ -0,0 +1,53 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_MESH_VIEWER_H_INCLUDED__ +#define __I_GUI_MESH_VIEWER_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ + +namespace video +{ + class SMaterial; +} // end namespace video + +namespace scene +{ + class IAnimatedMesh; +} // end namespace scene + +namespace gui +{ + + //! 3d mesh viewing GUI element. + class IGUIMeshViewer : public IGUIElement + { + public: + + //! constructor + IGUIMeshViewer(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_MESH_VIEWER, environment, parent, id, rectangle) {} + + //! Sets the mesh to be shown + virtual void setMesh(scene::IAnimatedMesh* mesh) = 0; + + //! Gets the displayed mesh + virtual scene::IAnimatedMesh* getMesh() const = 0; + + //! Sets the material + virtual void setMaterial(const video::SMaterial& material) = 0; + + //! Gets the material + virtual const video::SMaterial& getMaterial() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIScrollBar.h b/builddir/irrlicht-1.8.1/include/IGUIScrollBar.h new file mode 100644 index 0000000..4064ef9 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIScrollBar.h @@ -0,0 +1,65 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_SCROLL_BAR_H_INCLUDED__ +#define __I_GUI_SCROLL_BAR_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + + //! Default scroll bar GUI element. + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_SCROLL_BAR_CHANGED + */ + class IGUIScrollBar : public IGUIElement + { + public: + + //! constructor + IGUIScrollBar(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_SCROLL_BAR, environment, parent, id, rectangle) {} + + //! sets the maximum value of the scrollbar. + virtual void setMax(s32 max) = 0; + //! gets the maximum value of the scrollbar. + virtual s32 getMax() const = 0; + + //! sets the minimum value of the scrollbar. + virtual void setMin(s32 min) = 0; + //! gets the minimum value of the scrollbar. + virtual s32 getMin() const = 0; + + //! gets the small step value + virtual s32 getSmallStep() const = 0; + + //! Sets the small step + /** That is the amount that the value changes by when clicking + on the buttons or using the cursor keys. */ + virtual void setSmallStep(s32 step) = 0; + + //! gets the large step value + virtual s32 getLargeStep() const = 0; + + //! Sets the large step + /** That is the amount that the value changes by when clicking + in the tray, or using the page up and page down keys. */ + virtual void setLargeStep(s32 step) = 0; + + //! gets the current position of the scrollbar + virtual s32 getPos() const = 0; + + //! sets the current position of the scrollbar + virtual void setPos(s32 pos) = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUISkin.h b/builddir/irrlicht-1.8.1/include/IGUISkin.h new file mode 100644 index 0000000..0500be2 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUISkin.h @@ -0,0 +1,574 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_SKIN_H_INCLUDED__ +#define __I_GUI_SKIN_H_INCLUDED__ + +#include "IAttributeExchangingObject.h" +#include "EGUIAlignment.h" +#include "SColor.h" +#include "rect.h" + +namespace irr +{ +namespace gui +{ + class IGUIFont; + class IGUISpriteBank; + class IGUIElement; + + //! Enumeration of available default skins. + /** To set one of the skins, use the following code, for example to set + the Windows classic skin: + \code + gui::IGUISkin* newskin = environment->createSkin(gui::EGST_WINDOWS_CLASSIC); + environment->setSkin(newskin); + newskin->drop(); + \endcode + */ + enum EGUI_SKIN_TYPE + { + //! Default windows look and feel + EGST_WINDOWS_CLASSIC=0, + + //! Like EGST_WINDOWS_CLASSIC, but with metallic shaded windows and buttons + EGST_WINDOWS_METALLIC, + + //! Burning's skin + EGST_BURNING_SKIN, + + //! An unknown skin, not serializable at present + EGST_UNKNOWN, + + //! this value is not used, it only specifies the number of skin types + EGST_COUNT + }; + + //! Names for gui element types + const c8* const GUISkinTypeNames[EGST_COUNT+1] = + { + "windowsClassic", + "windowsMetallic", + "burning", + "unknown", + 0, + }; + + + //! Enumeration for skin colors + enum EGUI_DEFAULT_COLOR + { + //! Dark shadow for three-dimensional display elements. + EGDC_3D_DARK_SHADOW = 0, + //! Shadow color for three-dimensional display elements (for edges facing away from the light source). + EGDC_3D_SHADOW, + //! Face color for three-dimensional display elements and for dialog box backgrounds. + EGDC_3D_FACE, + //! Highlight color for three-dimensional display elements (for edges facing the light source.) + EGDC_3D_HIGH_LIGHT, + //! Light color for three-dimensional display elements (for edges facing the light source.) + EGDC_3D_LIGHT, + //! Active window border. + EGDC_ACTIVE_BORDER, + //! Active window title bar text. + EGDC_ACTIVE_CAPTION, + //! Background color of multiple document interface (MDI) applications. + EGDC_APP_WORKSPACE, + //! Text on a button + EGDC_BUTTON_TEXT, + //! Grayed (disabled) text. + EGDC_GRAY_TEXT, + //! Item(s) selected in a control. + EGDC_HIGH_LIGHT, + //! Text of item(s) selected in a control. + EGDC_HIGH_LIGHT_TEXT, + //! Inactive window border. + EGDC_INACTIVE_BORDER, + //! Inactive window caption. + EGDC_INACTIVE_CAPTION, + //! Tool tip text color + EGDC_TOOLTIP, + //! Tool tip background color + EGDC_TOOLTIP_BACKGROUND, + //! Scrollbar gray area + EGDC_SCROLLBAR, + //! Window background + EGDC_WINDOW, + //! Window symbols like on close buttons, scroll bars and check boxes + EGDC_WINDOW_SYMBOL, + //! Icons in a list or tree + EGDC_ICON, + //! Selected icons in a list or tree + EGDC_ICON_HIGH_LIGHT, + //! Grayed (disabled) window symbols like on close buttons, scroll bars and check boxes + EGDC_GRAY_WINDOW_SYMBOL, + //! Window background for editable field (editbox, checkbox-field) + EGDC_EDITABLE, + //! Grayed (disabled) window background for editable field (editbox, checkbox-field) + EGDC_GRAY_EDITABLE, + //! Show focus of window background for editable field (editbox or when checkbox-field is pressed) + EGDC_FOCUSED_EDITABLE, + + //! this value is not used, it only specifies the amount of default colors + //! available. + EGDC_COUNT + }; + + //! Names for default skin colors + const c8* const GUISkinColorNames[EGDC_COUNT+1] = + { + "3DDarkShadow", + "3DShadow", + "3DFace", + "3DHighlight", + "3DLight", + "ActiveBorder", + "ActiveCaption", + "AppWorkspace", + "ButtonText", + "GrayText", + "Highlight", + "HighlightText", + "InactiveBorder", + "InactiveCaption", + "ToolTip", + "ToolTipBackground", + "ScrollBar", + "Window", + "WindowSymbol", + "Icon", + "IconHighlight", + "GrayWindowSymbol", + "Editable", + "GrayEditable", + "FocusedEditable", + 0, + }; + + //! Enumeration for default sizes. + enum EGUI_DEFAULT_SIZE + { + //! default with / height of scrollbar + EGDS_SCROLLBAR_SIZE = 0, + //! height of menu + EGDS_MENU_HEIGHT, + //! width of a window button + EGDS_WINDOW_BUTTON_WIDTH, + //! width of a checkbox check + EGDS_CHECK_BOX_WIDTH, + //! \deprecated This may be removed by Irrlicht 1.9 + EGDS_MESSAGE_BOX_WIDTH, + //! \deprecated This may be removed by Irrlicht 1.9 + EGDS_MESSAGE_BOX_HEIGHT, + //! width of a default button + EGDS_BUTTON_WIDTH, + //! height of a default button + EGDS_BUTTON_HEIGHT, + //! distance for text from background + EGDS_TEXT_DISTANCE_X, + //! distance for text from background + EGDS_TEXT_DISTANCE_Y, + //! distance for text in the title bar, from the left of the window rect + EGDS_TITLEBARTEXT_DISTANCE_X, + //! distance for text in the title bar, from the top of the window rect + EGDS_TITLEBARTEXT_DISTANCE_Y, + //! free space in a messagebox between borders and contents on all sides + EGDS_MESSAGE_BOX_GAP_SPACE, + //! minimal space to reserve for messagebox text-width + EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH, + //! maximal space to reserve for messagebox text-width + EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH, + //! minimal space to reserve for messagebox text-height + EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT, + //! maximal space to reserve for messagebox text-height + EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT, + //! pixels to move the button image to the right when a pushbutton is pressed + EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X, + //! pixels to move the button image down when a pushbutton is pressed + EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y, + //! pixels to move the button text to the right when a pushbutton is pressed + EGDS_BUTTON_PRESSED_TEXT_OFFSET_X, + //! pixels to move the button text down when a pushbutton is pressed + EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y, + + //! this value is not used, it only specifies the amount of default sizes + //! available. + EGDS_COUNT + }; + + + //! Names for default skin sizes + const c8* const GUISkinSizeNames[EGDS_COUNT+1] = + { + "ScrollBarSize", + "MenuHeight", + "WindowButtonWidth", + "CheckBoxWidth", + "MessageBoxWidth", + "MessageBoxHeight", + "ButtonWidth", + "ButtonHeight", + "TextDistanceX", + "TextDistanceY", + "TitleBarTextX", + "TitleBarTextY", + "MessageBoxGapSpace", + "MessageBoxMinTextWidth", + "MessageBoxMaxTextWidth", + "MessageBoxMinTextHeight", + "MessageBoxMaxTextHeight", + "ButtonPressedImageOffsetX", + "ButtonPressedImageOffsetY" + "ButtonPressedTextOffsetX", + "ButtonPressedTextOffsetY", + 0 + }; + + + enum EGUI_DEFAULT_TEXT + { + //! Text for the OK button on a message box + EGDT_MSG_BOX_OK = 0, + //! Text for the Cancel button on a message box + EGDT_MSG_BOX_CANCEL, + //! Text for the Yes button on a message box + EGDT_MSG_BOX_YES, + //! Text for the No button on a message box + EGDT_MSG_BOX_NO, + //! Tooltip text for window close button + EGDT_WINDOW_CLOSE, + //! Tooltip text for window maximize button + EGDT_WINDOW_MAXIMIZE, + //! Tooltip text for window minimize button + EGDT_WINDOW_MINIMIZE, + //! Tooltip text for window restore button + EGDT_WINDOW_RESTORE, + + //! this value is not used, it only specifies the number of default texts + EGDT_COUNT + }; + + //! Names for default skin sizes + const c8* const GUISkinTextNames[EGDT_COUNT+1] = + { + "MessageBoxOkay", + "MessageBoxCancel", + "MessageBoxYes", + "MessageBoxNo", + "WindowButtonClose", + "WindowButtonMaximize", + "WindowButtonMinimize", + "WindowButtonRestore", + 0 + }; + + //! Customizable symbols for GUI + enum EGUI_DEFAULT_ICON + { + //! maximize window button + EGDI_WINDOW_MAXIMIZE = 0, + //! restore window button + EGDI_WINDOW_RESTORE, + //! close window button + EGDI_WINDOW_CLOSE, + //! minimize window button + EGDI_WINDOW_MINIMIZE, + //! resize icon for bottom right corner of a window + EGDI_WINDOW_RESIZE, + //! scroll bar up button + EGDI_CURSOR_UP, + //! scroll bar down button + EGDI_CURSOR_DOWN, + //! scroll bar left button + EGDI_CURSOR_LEFT, + //! scroll bar right button + EGDI_CURSOR_RIGHT, + //! icon for menu children + EGDI_MENU_MORE, + //! tick for checkbox + EGDI_CHECK_BOX_CHECKED, + //! down arrow for dropdown menus + EGDI_DROP_DOWN, + //! smaller up arrow + EGDI_SMALL_CURSOR_UP, + //! smaller down arrow + EGDI_SMALL_CURSOR_DOWN, + //! selection dot in a radio button + EGDI_RADIO_BUTTON_CHECKED, + //! << icon indicating there is more content to the left + EGDI_MORE_LEFT, + //! >> icon indicating that there is more content to the right + EGDI_MORE_RIGHT, + //! icon indicating that there is more content above + EGDI_MORE_UP, + //! icon indicating that there is more content below + EGDI_MORE_DOWN, + //! plus icon for trees + EGDI_EXPAND, + + //! minus icon for trees + EGDI_COLLAPSE, + //! file icon for file selection + EGDI_FILE, + //! folder icon for file selection + EGDI_DIRECTORY, + + //! value not used, it only specifies the number of icons + EGDI_COUNT + }; + + const c8* const GUISkinIconNames[EGDI_COUNT+1] = + { + "windowMaximize", + "windowRestore", + "windowClose", + "windowMinimize", + "windowResize", + "cursorUp", + "cursorDown", + "cursorLeft", + "cursorRight", + "menuMore", + "checkBoxChecked", + "dropDown", + "smallCursorUp", + "smallCursorDown", + "radioButtonChecked", + "moreLeft", + "moreRight", + "moreUp", + "moreDown", + "expand", + "collapse", + "file", + "directory", + 0 + }; + + // Customizable fonts + enum EGUI_DEFAULT_FONT + { + //! For static text, edit boxes, lists and most other places + EGDF_DEFAULT=0, + //! Font for buttons + EGDF_BUTTON, + //! Font for window title bars + EGDF_WINDOW, + //! Font for menu items + EGDF_MENU, + //! Font for tooltips + EGDF_TOOLTIP, + //! this value is not used, it only specifies the amount of default fonts + //! available. + EGDF_COUNT + }; + + const c8* const GUISkinFontNames[EGDF_COUNT+1] = + { + "defaultFont", + "buttonFont", + "windowFont", + "menuFont", + "tooltipFont", + 0 + }; + + //! A skin modifies the look of the GUI elements. + class IGUISkin : public virtual io::IAttributeExchangingObject + { + public: + + //! returns default color + virtual video::SColor getColor(EGUI_DEFAULT_COLOR color) const = 0; + + //! sets a default color + virtual void setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor) = 0; + + //! returns size for the given size type + virtual s32 getSize(EGUI_DEFAULT_SIZE size) const = 0; + + //! Returns a default text. + /** For example for Message box button captions: + "OK", "Cancel", "Yes", "No" and so on. */ + virtual const wchar_t* getDefaultText(EGUI_DEFAULT_TEXT text) const = 0; + + //! Sets a default text. + /** For example for Message box button captions: + "OK", "Cancel", "Yes", "No" and so on. */ + virtual void setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText) = 0; + + //! sets a default size + virtual void setSize(EGUI_DEFAULT_SIZE which, s32 size) = 0; + + //! returns the default font + virtual IGUIFont* getFont(EGUI_DEFAULT_FONT which=EGDF_DEFAULT) const = 0; + + //! sets a default font + virtual void setFont(IGUIFont* font, EGUI_DEFAULT_FONT which=EGDF_DEFAULT) = 0; + + //! returns the sprite bank + virtual IGUISpriteBank* getSpriteBank() const = 0; + + //! sets the sprite bank + virtual void setSpriteBank(IGUISpriteBank* bank) = 0; + + //! Returns a default icon + /** Returns the sprite index within the sprite bank */ + virtual u32 getIcon(EGUI_DEFAULT_ICON icon) const = 0; + + //! Sets a default icon + /** Sets the sprite index used for drawing icons like arrows, + close buttons and ticks in checkboxes + \param icon: Enum specifying which icon to change + \param index: The sprite index used to draw this icon */ + virtual void setIcon(EGUI_DEFAULT_ICON icon, u32 index) = 0; + + //! draws a standard 3d button pane + /** Used for drawing for example buttons in normal state. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DButtonPaneStandard(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0) = 0; + + //! draws a pressed 3d button pane + /** Used for drawing for example buttons in pressed state. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DButtonPanePressed(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0) = 0; + + //! draws a sunken 3d pane + /** Used for drawing the background of edit, combo or check boxes. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param bgcolor: Background color. + \param flat: Specifies if the sunken pane should be flat or displayed as sunken + deep into the ground. + \param fillBackGround: Specifies if the background should be filled with the background + color or not be drawn at all. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DSunkenPane(IGUIElement* element, + video::SColor bgcolor, bool flat, bool fillBackGround, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0) = 0; + + //! draws a window background + /** Used for drawing the background of dialogs and windows. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param titleBarColor: Title color. + \param drawTitleBar: True to enable title drawing. + \param rect: Defining area where to draw. + \param clip: Clip area. + \param checkClientArea: When set to non-null the function will not draw anything, + but will instead return the clientArea which can be used for drawing by the calling window. + That is the area without borders and without titlebar. + \return Returns rect where it would be good to draw title bar text. This will + work even when checkClientArea is set to a non-null value.*/ + virtual core::rect<s32> draw3DWindowBackground(IGUIElement* element, + bool drawTitleBar, video::SColor titleBarColor, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0, + core::rect<s32>* checkClientArea=0) = 0; + + //! draws a standard 3d menu pane + /** Used for drawing for menus and context menus. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DMenuPane(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0) = 0; + + //! draws a standard 3d tool bar + /** Used for drawing for toolbars and menus. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DToolBar(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0) = 0; + + //! draws a tab button + /** Used for drawing for tab buttons on top of tabs. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param active: Specifies if the tab is currently active. + \param rect: Defining area where to draw. + \param clip: Clip area. + \param alignment Alignment of GUI element. */ + virtual void draw3DTabButton(IGUIElement* element, bool active, + const core::rect<s32>& rect, const core::rect<s32>* clip=0, gui::EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT) = 0; + + //! draws a tab control body + /** \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param border: Specifies if the border should be drawn. + \param background: Specifies if the background should be drawn. + \param rect: Defining area where to draw. + \param clip: Clip area. + \param tabHeight Height of tab. + \param alignment Alignment of GUI element. */ + virtual void draw3DTabBody(IGUIElement* element, bool border, bool background, + const core::rect<s32>& rect, const core::rect<s32>* clip=0, s32 tabHeight=-1, gui::EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT ) = 0; + + //! draws an icon, usually from the skin's sprite bank + /** \param element: Pointer to the element which wishes to draw this icon. + This parameter is usually not used by IGUISkin, but can be used for example + by more complex implementations to find out how to draw the part exactly. + \param icon: Specifies the icon to be drawn. + \param position: The position to draw the icon + \param starttime: The time at the start of the animation + \param currenttime: The present time, used to calculate the frame number + \param loop: Whether the animation should loop or not + \param clip: Clip area. */ + virtual void drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon, + const core::position2di position, u32 starttime=0, u32 currenttime=0, + bool loop=false, const core::rect<s32>* clip=0) = 0; + + //! draws a 2d rectangle. + /** \param element: Pointer to the element which wishes to draw this icon. + This parameter is usually not used by IGUISkin, but can be used for example + by more complex implementations to find out how to draw the part exactly. + \param color: Color of the rectangle to draw. The alpha component specifies how + transparent the rectangle will be. + \param pos: Position of the rectangle. + \param clip: Pointer to rectangle against which the rectangle will be clipped. + If the pointer is null, no clipping will be performed. */ + virtual void draw2DRectangle(IGUIElement* element, const video::SColor &color, + const core::rect<s32>& pos, const core::rect<s32>* clip = 0) = 0; + + //! get the type of this skin + virtual EGUI_SKIN_TYPE getType() const { return EGST_UNKNOWN; } + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUISpinBox.h b/builddir/irrlicht-1.8.1/include/IGUISpinBox.h new file mode 100644 index 0000000..2310161 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUISpinBox.h @@ -0,0 +1,69 @@ +// Copyright (C) 2006-2012 Michael Zeilfelder +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_SPIN_BOX_H_INCLUDED__ +#define __I_GUI_SPIN_BOX_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + class IGUIEditBox; + + //! Single line edit box + spin buttons + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_SPINBOX_CHANGED + */ + class IGUISpinBox : public IGUIElement + { + public: + + //! constructor + IGUISpinBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_SPIN_BOX, environment, parent, id, rectangle) {} + + //! Access the edit box used in the spin control + virtual IGUIEditBox* getEditBox() const = 0; + + //! set the current value of the spinbox + /** \param val: value to be set in the spinbox */ + virtual void setValue(f32 val) = 0; + + //! Get the current value of the spinbox + virtual f32 getValue() const = 0; + + //! set the range of values which can be used in the spinbox + /** \param min: minimum value + \param max: maximum value */ + virtual void setRange(f32 min, f32 max) = 0; + + //! get the minimum value which can be used in the spinbox + virtual f32 getMin() const = 0; + + //! get the maximum value which can be used in the spinbox + virtual f32 getMax() const = 0; + + //! Step size by which values are changed when pressing the spinbuttons + /** The step size also determines the number of decimal places to display + \param step: stepsize used for value changes when pressing spinbuttons */ + virtual void setStepSize(f32 step=1.f) = 0; + + //! Sets the number of decimal places to display. + //! Note that this also rounds the range to the same number of decimal places. + /** \param places: The number of decimal places to display, use -1 to reset */ + virtual void setDecimalPlaces(s32 places) = 0; + + //! get the current step size + virtual f32 getStepSize() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // __I_GUI_SPIN_BOX_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/IGUISpriteBank.h b/builddir/irrlicht-1.8.1/include/IGUISpriteBank.h new file mode 100644 index 0000000..872bbca --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUISpriteBank.h @@ -0,0 +1,95 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_SPRITE_BANK_H_INCLUDED__ +#define __I_GUI_SPRITE_BANK_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrArray.h" +#include "SColor.h" +#include "rect.h" + +namespace irr +{ + +namespace video +{ + class ITexture; +} // end namespace video + +namespace gui +{ + +//! A single sprite frame. +struct SGUISpriteFrame +{ + u32 textureNumber; + u32 rectNumber; +}; + +//! A sprite composed of several frames. +struct SGUISprite +{ + SGUISprite() : Frames(), frameTime(0) {} + + core::array<SGUISpriteFrame> Frames; + u32 frameTime; +}; + + +//! Sprite bank interface. +/** See http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=25742&highlight=spritebank +* for more information how to use the spritebank. +*/ +class IGUISpriteBank : public virtual IReferenceCounted +{ +public: + + //! Returns the list of rectangles held by the sprite bank + virtual core::array< core::rect<s32> >& getPositions() = 0; + + //! Returns the array of animated sprites within the sprite bank + virtual core::array< SGUISprite >& getSprites() = 0; + + //! Returns the number of textures held by the sprite bank + virtual u32 getTextureCount() const = 0; + + //! Gets the texture with the specified index + virtual video::ITexture* getTexture(u32 index) const = 0; + + //! Adds a texture to the sprite bank + virtual void addTexture(video::ITexture* texture) = 0; + + //! Changes one of the textures in the sprite bank + virtual void setTexture(u32 index, video::ITexture* texture) = 0; + + //! Add the texture and use it for a single non-animated sprite. + //! The texture and the corresponding rectangle and sprite will all be added to the end of each array. + //! returns the index of the sprite or -1 on failure + virtual s32 addTextureAsSprite(video::ITexture* texture) = 0; + + //! clears sprites, rectangles and textures + virtual void clear() = 0; + + //! Draws a sprite in 2d with position and color + virtual void draw2DSprite(u32 index, const core::position2di& pos, + const core::rect<s32>* clip=0, + const video::SColor& color= video::SColor(255,255,255,255), + u32 starttime=0, u32 currenttime=0, + bool loop=true, bool center=false) = 0; + + //! Draws a sprite batch in 2d using an array of positions and a color + virtual void draw2DSpriteBatch(const core::array<u32>& indices, const core::array<core::position2di>& pos, + const core::rect<s32>* clip=0, + const video::SColor& color= video::SColor(255,255,255,255), + u32 starttime=0, u32 currenttime=0, + bool loop=true, bool center=false) = 0; +}; + + +} // end namespace gui +} // end namespace irr + +#endif // __I_GUI_SPRITE_BANK_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/IGUIStaticText.h b/builddir/irrlicht-1.8.1/include/IGUIStaticText.h new file mode 100644 index 0000000..b0594ab --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIStaticText.h @@ -0,0 +1,135 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_STATIC_TEXT_H_INCLUDED__ +#define __I_GUI_STATIC_TEXT_H_INCLUDED__ + +#include "IGUIElement.h" +#include "SColor.h" + +namespace irr +{ +namespace gui +{ + class IGUIFont; + + //! Multi or single line text label. + class IGUIStaticText : public IGUIElement + { + public: + + //! constructor + IGUIStaticText(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_STATIC_TEXT, environment, parent, id, rectangle) {} + + //! Sets another skin independent font. + /** If this is set to zero, the button uses the font of the skin. + \param font: New font to set. */ + virtual void setOverrideFont(IGUIFont* font=0) = 0; + + //! Gets the override font (if any) + /** \return The override font (may be 0) */ + virtual IGUIFont* getOverrideFont(void) const = 0; + + //! Get the font which is used right now for drawing + /** Currently this is the override font when one is set and the + font of the active skin otherwise */ + virtual IGUIFont* getActiveFont() const = 0; + + //! Sets another color for the text. + /** If set, the static text does not use the EGDC_BUTTON_TEXT color defined + in the skin, but the set color instead. You don't need to call + IGUIStaticText::enableOverrrideColor(true) after this, this is done + by this function. + If you set a color, and you want the text displayed with the color + of the skin again, call IGUIStaticText::enableOverrideColor(false); + \param color: New color of the text. */ + virtual void setOverrideColor(video::SColor color) = 0; + + //! Gets the override color + /** \return: The override color */ + virtual video::SColor getOverrideColor(void) const = 0; + + //! Sets if the static text should use the overide color or the color in the gui skin. + /** \param enable: If set to true, the override color, which can be set + with IGUIStaticText::setOverrideColor is used, otherwise the + EGDC_BUTTON_TEXT color of the skin. */ + virtual void enableOverrideColor(bool enable) = 0; + + //! Checks if an override color is enabled + /** \return true if the override color is enabled, false otherwise */ + virtual bool isOverrideColorEnabled(void) const = 0; + + //! Sets another color for the background. + virtual void setBackgroundColor(video::SColor color) = 0; + + //! Sets whether to draw the background + virtual void setDrawBackground(bool draw) = 0; + + //! Gets the background color + /** \return: The background color */ + virtual video::SColor getBackgroundColor() const = 0; + + //! Checks if background drawing is enabled + /** \return true if background drawing is enabled, false otherwise */ + virtual bool isDrawBackgroundEnabled() const = 0; + + //! Sets whether to draw the border + virtual void setDrawBorder(bool draw) = 0; + + //! Checks if border drawing is enabled + /** \return true if border drawing is enabled, false otherwise */ + virtual bool isDrawBorderEnabled() const = 0; + + //! Sets text justification mode + /** \param horizontal: EGUIA_UPPERLEFT for left justified (default), + EGUIA_LOWEERRIGHT for right justified, or EGUIA_CENTER for centered text. + \param vertical: EGUIA_UPPERLEFT to align with top edge, + EGUIA_LOWEERRIGHT for bottom edge, or EGUIA_CENTER for centered text (default). */ + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) = 0; + + //! Enables or disables word wrap for using the static text as multiline text control. + /** \param enable: If set to true, words going over one line are + broken on to the next line. */ + virtual void setWordWrap(bool enable) = 0; + + //! Checks if word wrap is enabled + /** \return true if word wrap is enabled, false otherwise */ + virtual bool isWordWrapEnabled(void) const = 0; + + //! Returns the height of the text in pixels when it is drawn. + /** This is useful for adjusting the layout of gui elements based on the height + of the multiline text in this element. + \return Height of text in pixels. */ + virtual s32 getTextHeight() const = 0; + + //! Returns the width of the current text, in the current font + /** If the text is broken, this returns the width of the widest line + \return The width of the text, or the widest broken line. */ + virtual s32 getTextWidth(void) const = 0; + + //! Set whether the text in this label should be clipped if it goes outside bounds + virtual void setTextRestrainedInside(bool restrainedInside) = 0; + + //! Checks if the text in this label should be clipped if it goes outside bounds + virtual bool isTextRestrainedInside() const = 0; + + //! Set whether the string should be interpreted as right-to-left (RTL) text + /** \note This component does not implement the Unicode bidi standard, the + text of the component should be already RTL if you call this. The + main difference when RTL is enabled is that the linebreaks for multiline + elements are performed starting from the end. + */ + virtual void setRightToLeft(bool rtl) = 0; + + //! Checks whether the text in this element should be interpreted as right-to-left + virtual bool isRightToLeft() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUITabControl.h b/builddir/irrlicht-1.8.1/include/IGUITabControl.h new file mode 100644 index 0000000..d9b4d12 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUITabControl.h @@ -0,0 +1,136 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_TAB_CONTROL_H_INCLUDED__ +#define __I_GUI_TAB_CONTROL_H_INCLUDED__ + +#include "IGUIElement.h" +#include "SColor.h" +#include "IGUISkin.h" + +namespace irr +{ +namespace gui +{ + //! A tab-page, onto which other gui elements could be added. + /** IGUITab refers to the page itself, not to the tab in the tabbar of an IGUITabControl. */ + class IGUITab : public IGUIElement + { + public: + + //! constructor + IGUITab(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_TAB, environment, parent, id, rectangle) {} + + //! Returns zero based index of tab if in tabcontrol. + /** Can be accessed later IGUITabControl::getTab() by this number. + Note that this number can change when other tabs are inserted or removed . + */ + virtual s32 getNumber() const = 0; + + //! sets if the tab should draw its background + virtual void setDrawBackground(bool draw=true) = 0; + + //! sets the color of the background, if it should be drawn. + virtual void setBackgroundColor(video::SColor c) = 0; + + //! returns true if the tab is drawing its background, false if not + virtual bool isDrawingBackground() const = 0; + + //! returns the color of the background + virtual video::SColor getBackgroundColor() const = 0; + + //! sets the color of the text + virtual void setTextColor(video::SColor c) = 0; + + //! gets the color of the text + virtual video::SColor getTextColor() const = 0; + }; + + //! A standard tab control + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_TAB_CHANGED + */ + class IGUITabControl : public IGUIElement + { + public: + + //! constructor + IGUITabControl(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_TAB_CONTROL, environment, parent, id, rectangle) {} + + //! Adds a tab + virtual IGUITab* addTab(const wchar_t* caption, s32 id=-1) = 0; + + //! Insert the tab at the given index + /** \return The tab on success or NULL on failure. */ + virtual IGUITab* insertTab(s32 idx, const wchar_t* caption, s32 id=-1) = 0; + + //! Removes a tab from the tabcontrol + virtual void removeTab(s32 idx) = 0; + + //! Clears the tabcontrol removing all tabs + virtual void clear() = 0; + + //! Returns amount of tabs in the tabcontrol + virtual s32 getTabCount() const = 0; + + //! Returns a tab based on zero based index + /** \param idx: zero based index of tab. Is a value betwenn 0 and getTabcount()-1; + \return Returns pointer to the Tab. Returns 0 if no tab + is corresponding to this tab. */ + virtual IGUITab* getTab(s32 idx) const = 0; + + //! Brings a tab to front. + /** \param idx: number of the tab. + \return Returns true if successful. */ + virtual bool setActiveTab(s32 idx) = 0; + + //! Brings a tab to front. + /** \param tab: pointer to the tab. + \return Returns true if successful. */ + virtual bool setActiveTab(IGUITab *tab) = 0; + + //! Returns which tab is currently active + virtual s32 getActiveTab() const = 0; + + //! get the the id of the tab at the given absolute coordinates + /** \return The id of the tab or -1 when no tab is at those coordinates*/ + virtual s32 getTabAt(s32 xpos, s32 ypos) const = 0; + + //! Set the height of the tabs + virtual void setTabHeight( s32 height ) = 0; + + //! Get the height of the tabs + /** return Returns the height of the tabs */ + virtual s32 getTabHeight() const = 0; + + //! set the maximal width of a tab. Per default width is 0 which means "no width restriction". + virtual void setTabMaxWidth(s32 width ) = 0; + + //! get the maximal width of a tab + virtual s32 getTabMaxWidth() const = 0; + + //! Set the alignment of the tabs + /** Use EGUIA_UPPERLEFT or EGUIA_LOWERRIGHT */ + virtual void setTabVerticalAlignment( gui::EGUI_ALIGNMENT alignment ) = 0; + + //! Get the alignment of the tabs + /** return Returns the alignment of the tabs */ + virtual gui::EGUI_ALIGNMENT getTabVerticalAlignment() const = 0; + + //! Set the extra width added to tabs on each side of the text + virtual void setTabExtraWidth( s32 extraWidth ) = 0; + + //! Get the extra width added to tabs on each side of the text + /** return Returns the extra width of the tabs */ + virtual s32 getTabExtraWidth() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUITable.h b/builddir/irrlicht-1.8.1/include/IGUITable.h new file mode 100644 index 0000000..219d28d --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUITable.h @@ -0,0 +1,205 @@ +// Copyright (C) 2003-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_TABLE_H_INCLUDED__ +#define __I_GUI_TABLE_H_INCLUDED__ + +#include "IGUIElement.h" +#include "irrTypes.h" +#include "SColor.h" +#include "IGUISkin.h" + +namespace irr +{ +namespace gui +{ + + //! modes for ordering used when a column header is clicked + enum EGUI_COLUMN_ORDERING + { + //! Do not use ordering + EGCO_NONE, + + //! Send a EGET_TABLE_HEADER_CHANGED message when a column header is clicked. + EGCO_CUSTOM, + + //! Sort it ascending by it's ascii value like: a,b,c,... + EGCO_ASCENDING, + + //! Sort it descending by it's ascii value like: z,x,y,... + EGCO_DESCENDING, + + //! Sort it ascending on first click, descending on next, etc + EGCO_FLIP_ASCENDING_DESCENDING, + + //! Not used as mode, only to get maximum value for this enum + EGCO_COUNT + }; + + //! Names for EGUI_COLUMN_ORDERING types + const c8* const GUIColumnOrderingNames[] = + { + "none", + "custom", + "ascend", + "descend", + "ascend_descend", + 0, + }; + + enum EGUI_ORDERING_MODE + { + //! No element ordering + EGOM_NONE, + + //! Elements are ordered from the smallest to the largest. + EGOM_ASCENDING, + + //! Elements are ordered from the largest to the smallest. + EGOM_DESCENDING, + + //! this value is not used, it only specifies the amount of default ordering types + //! available. + EGOM_COUNT + }; + + const c8* const GUIOrderingModeNames[] = + { + "none", + "ascending", + "descending", + 0 + }; + + enum EGUI_TABLE_DRAW_FLAGS + { + EGTDF_ROWS = 1, + EGTDF_COLUMNS = 2, + EGTDF_ACTIVE_ROW = 4, + EGTDF_COUNT + }; + + //! Default list box GUI element. + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_TABLE_CHANGED + \li EGET_TABLE_SELECTED_AGAIN + \li EGET_TABLE_HEADER_CHANGED + */ + class IGUITable : public IGUIElement + { + public: + //! constructor + IGUITable(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_TABLE, environment, parent, id, rectangle) {} + + //! Adds a column + /** If columnIndex is outside the current range, do push new colum at the end */ + virtual void addColumn(const wchar_t* caption, s32 columnIndex=-1) = 0; + + //! remove a column from the table + virtual void removeColumn(u32 columnIndex) = 0; + + //! Returns the number of columns in the table control + virtual s32 getColumnCount() const = 0; + + //! Makes a column active. This will trigger an ordering process. + /** \param idx: The id of the column to make active. + \param doOrder: Do also the ordering which depending on mode for active column + \return True if successful. */ + virtual bool setActiveColumn(s32 idx, bool doOrder=false) = 0; + + //! Returns which header is currently active + virtual s32 getActiveColumn() const = 0; + + //! Returns the ordering used by the currently active column + virtual EGUI_ORDERING_MODE getActiveColumnOrdering() const = 0; + + //! Set the width of a column + virtual void setColumnWidth(u32 columnIndex, u32 width) = 0; + + //! Get the width of a column + virtual u32 getColumnWidth(u32 columnIndex) const = 0; + + //! columns can be resized by drag 'n drop + virtual void setResizableColumns(bool resizable) = 0; + + //! can columns be resized by dran 'n drop? + virtual bool hasResizableColumns() const = 0; + + //! This tells the table control which ordering mode should be used when a column header is clicked. + /** \param columnIndex The index of the column header. + \param mode: One of the modes defined in EGUI_COLUMN_ORDERING */ + virtual void setColumnOrdering(u32 columnIndex, EGUI_COLUMN_ORDERING mode) = 0; + + //! Returns which row is currently selected + virtual s32 getSelected() const = 0; + + //! set wich row is currently selected + virtual void setSelected( s32 index ) = 0; + + //! Get amount of rows in the tabcontrol + virtual s32 getRowCount() const = 0; + + //! adds a row to the table + /** \param rowIndex Zero based index of rows. The row will be + inserted at this position, if a row already exist there, it + will be placed after it. If the row is larger than the actual + number of row by more than one, it won't be created. Note that + if you create a row that's not at the end, there might be + performance issues. + \return index of inserted row. */ + virtual u32 addRow(u32 rowIndex) = 0; + + //! Remove a row from the table + virtual void removeRow(u32 rowIndex) = 0; + + //! clears the table rows, but keeps the columns intact + virtual void clearRows() = 0; + + //! Swap two row positions. + virtual void swapRows(u32 rowIndexA, u32 rowIndexB) = 0; + + //! This tells the table to start ordering all the rows. + /** You need to explicitly tell the table to re order the rows + when a new row is added or the cells data is changed. This + makes the system more flexible and doesn't make you pay the + cost of ordering when adding a lot of rows. + \param columnIndex: When set to -1 the active column is used. + \param mode Ordering mode of the rows. */ + virtual void orderRows(s32 columnIndex=-1, EGUI_ORDERING_MODE mode=EGOM_NONE) = 0; + + //! Set the text of a cell + virtual void setCellText(u32 rowIndex, u32 columnIndex, const core::stringw& text) = 0; + + //! Set the text of a cell, and set a color of this cell. + virtual void setCellText(u32 rowIndex, u32 columnIndex, const core::stringw& text, video::SColor color) = 0; + + //! Set the data of a cell + virtual void setCellData(u32 rowIndex, u32 columnIndex, void *data) = 0; + + //! Set the color of a cell text + virtual void setCellColor(u32 rowIndex, u32 columnIndex, video::SColor color) = 0; + + //! Get the text of a cell + virtual const wchar_t* getCellText(u32 rowIndex, u32 columnIndex ) const = 0; + + //! Get the data of a cell + virtual void* getCellData(u32 rowIndex, u32 columnIndex ) const = 0; + + //! clears the table, deletes all items in the table + virtual void clear() = 0; + + //! Set flags, as defined in EGUI_TABLE_DRAW_FLAGS, which influence the layout + virtual void setDrawFlags(s32 flags) = 0; + + //! Get the flags, as defined in EGUI_TABLE_DRAW_FLAGS, which influence the layout + virtual s32 getDrawFlags() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIToolbar.h b/builddir/irrlicht-1.8.1/include/IGUIToolbar.h new file mode 100644 index 0000000..08519fc --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIToolbar.h @@ -0,0 +1,40 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_TOOL_BAR_H_INCLUDED__ +#define __I_GUI_TOOL_BAR_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace video +{ + class ITexture; +} // end namespace video +namespace gui +{ + class IGUIButton; + + //! Stays at the top of its parent like the menu bar and contains tool buttons + class IGUIToolBar : public IGUIElement + { + public: + + //! constructor + IGUIToolBar(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_TOOL_BAR, environment, parent, id, rectangle) {} + + //! Adds a button to the tool bar + virtual IGUIButton* addButton(s32 id=-1, const wchar_t* text=0,const wchar_t* tooltiptext=0, + video::ITexture* img=0, video::ITexture* pressedimg=0, + bool isPushButton=false, bool useAlphaChannel=false) = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUITreeView.h b/builddir/irrlicht-1.8.1/include/IGUITreeView.h new file mode 100644 index 0000000..5f21022 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUITreeView.h @@ -0,0 +1,278 @@ +// written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_TREE_VIEW_H_INCLUDED__ +#define __I_GUI_TREE_VIEW_H_INCLUDED__ + +#include "IGUIElement.h" +#include "IGUIImageList.h" +#include "irrTypes.h" + +namespace irr +{ +namespace gui +{ + class IGUIFont; + class IGUITreeView; + + + //! Node for gui tree view + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_TREEVIEW_NODE_EXPAND + \li EGET_TREEVIEW_NODE_COLLAPS + \li EGET_TREEVIEW_NODE_DESELECT + \li EGET_TREEVIEW_NODE_SELECT + */ + class IGUITreeViewNode : public IReferenceCounted + { + public: + //! returns the owner (tree view) of this node + virtual IGUITreeView* getOwner() const = 0; + + //! Returns the parent node of this node. + /** For the root node this will return 0. */ + virtual IGUITreeViewNode* getParent() const = 0; + + //! returns the text of the node + virtual const wchar_t* getText() const = 0; + + //! sets the text of the node + virtual void setText( const wchar_t* text ) = 0; + + //! returns the icon text of the node + virtual const wchar_t* getIcon() const = 0; + + //! sets the icon text of the node + virtual void setIcon( const wchar_t* icon ) = 0; + + //! returns the image index of the node + virtual u32 getImageIndex() const = 0; + + //! sets the image index of the node + virtual void setImageIndex( u32 imageIndex ) = 0; + + //! returns the image index of the node + virtual u32 getSelectedImageIndex() const = 0; + + //! sets the image index of the node + virtual void setSelectedImageIndex( u32 imageIndex ) = 0; + + //! returns the user data (void*) of this node + virtual void* getData() const = 0; + + //! sets the user data (void*) of this node + virtual void setData( void* data ) = 0; + + //! returns the user data2 (IReferenceCounted) of this node + virtual IReferenceCounted* getData2() const = 0; + + //! sets the user data2 (IReferenceCounted) of this node + virtual void setData2( IReferenceCounted* data ) = 0; + + //! returns the child item count + virtual u32 getChildCount() const = 0; + + //! removes all children (recursive) from this node + virtual void clearChildren() = 0; + + //! removes all children (recursive) from this node + /** \deprecated Deprecated in 1.8, use clearChildren() instead. + This method may be removed by Irrlicht 1.9 */ + _IRR_DEPRECATED_ void clearChilds() + { + return clearChildren(); + } + + //! returns true if this node has child nodes + virtual bool hasChildren() const = 0; + + //! returns true if this node has child nodes + /** \deprecated Deprecated in 1.8, use hasChildren() instead. + This method may be removed by Irrlicht 1.9 */ + _IRR_DEPRECATED_ bool hasChilds() const + { + return hasChildren(); + } + + //! Adds a new node behind the last child node. + /** \param text text of the new node + \param icon icon text of the new node + \param imageIndex index of the image for the new node (-1 = none) + \param selectedImageIndex index of the selected image for the new node (-1 = same as imageIndex) + \param data user data (void*) of the new node + \param data2 user data2 (IReferenceCounted*) of the new node + \return The new node + */ + virtual IGUITreeViewNode* addChildBack( + const wchar_t* text, const wchar_t* icon = 0, + s32 imageIndex=-1, s32 selectedImageIndex=-1, + void* data=0, IReferenceCounted* data2=0) =0; + + //! Adds a new node before the first child node. + /** \param text text of the new node + \param icon icon text of the new node + \param imageIndex index of the image for the new node (-1 = none) + \param selectedImageIndex index of the selected image for the new node (-1 = same as imageIndex) + \param data user data (void*) of the new node + \param data2 user data2 (IReferenceCounted*) of the new node + \return The new node + */ + virtual IGUITreeViewNode* addChildFront( + const wchar_t* text, const wchar_t* icon = 0, + s32 imageIndex=-1, s32 selectedImageIndex=-1, + void* data=0, IReferenceCounted* data2=0 ) =0; + + //! Adds a new node behind the other node. + /** The other node has also te be a child node from this node. + \param other Node to insert after + \param text text of the new node + \param icon icon text of the new node + \param imageIndex index of the image for the new node (-1 = none) + \param selectedImageIndex index of the selected image for the new node (-1 = same as imageIndex) + \param data user data (void*) of the new node + \param data2 user data2 (IReferenceCounted*) of the new node + \return The new node or 0 if other is no child node from this + */ + virtual IGUITreeViewNode* insertChildAfter( + IGUITreeViewNode* other, + const wchar_t* text, const wchar_t* icon = 0, + s32 imageIndex=-1, s32 selectedImageIndex=-1, + void* data=0, IReferenceCounted* data2=0) =0; + + //! Adds a new node before the other node. + /** The other node has also te be a child node from this node. + \param other Node to insert before + \param text text of the new node + \param icon icon text of the new node + \param imageIndex index of the image for the new node (-1 = none) + \param selectedImageIndex index of the selected image for the new node (-1 = same as imageIndex) + \param data user data (void*) of the new node + \param data2 user data2 (IReferenceCounted*) of the new node + \return The new node or 0 if other is no child node from this + */ + virtual IGUITreeViewNode* insertChildBefore( + IGUITreeViewNode* other, + const wchar_t* text, const wchar_t* icon = 0, + s32 imageIndex=-1, s32 selectedImageIndex=-1, + void* data=0, IReferenceCounted* data2=0) = 0; + + //! Return the first child node from this node. + /** \return The first child node or 0 if this node has no children. */ + virtual IGUITreeViewNode* getFirstChild() const = 0; + + //! Return the last child node from this node. + /** \return The last child node or 0 if this node has no children. */ + virtual IGUITreeViewNode* getLastChild() const = 0; + + //! Returns the previous sibling node from this node. + /** \return The previous sibling node from this node or 0 if this is + the first node from the parent node. + */ + virtual IGUITreeViewNode* getPrevSibling() const = 0; + + //! Returns the next sibling node from this node. + /** \return The next sibling node from this node or 0 if this is + the last node from the parent node. + */ + virtual IGUITreeViewNode* getNextSibling() const = 0; + + //! Returns the next visible (expanded, may be out of scrolling) node from this node. + /** \return The next visible node from this node or 0 if this is + the last visible node. */ + virtual IGUITreeViewNode* getNextVisible() const = 0; + + //! Deletes a child node. + /** \return Returns true if the node was found as a child and is deleted. */ + virtual bool deleteChild( IGUITreeViewNode* child ) = 0; + + //! Moves a child node one position up. + /** \return True if the node was found as achild node and was not already the first child. */ + virtual bool moveChildUp( IGUITreeViewNode* child ) = 0; + + //! Moves a child node one position down. + /** \return True if the node was found as achild node and was not already the last child. */ + virtual bool moveChildDown( IGUITreeViewNode* child ) = 0; + + //! Returns true if the node is expanded (children are visible). + virtual bool getExpanded() const = 0; + + //! Sets if the node is expanded. + virtual void setExpanded( bool expanded ) = 0; + + //! Returns true if the node is currently selected. + virtual bool getSelected() const = 0; + + //! Sets this node as selected. + virtual void setSelected( bool selected ) = 0; + + //! Returns true if this node is the root node. + virtual bool isRoot() const = 0; + + //! Returns the level of this node. + /** The root node has level 0. Direct children of the root has level 1 ... */ + virtual s32 getLevel() const = 0; + + //! Returns true if this node is visible (all parents are expanded). + virtual bool isVisible() const = 0; + }; + + + //! Default tree view GUI element. + /** Displays a windows like tree buttons to expand/collaps the child + nodes of an node and optional tree lines. Each node consits of an + text, an icon text and a void pointer for user data. */ + class IGUITreeView : public IGUIElement + { + public: + //! constructor + IGUITreeView(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect<s32> rectangle) + : IGUIElement( EGUIET_TREE_VIEW, environment, parent, id, rectangle ) {} + + //! returns the root node (not visible) from the tree. + virtual IGUITreeViewNode* getRoot() const = 0; + + //! returns the selected node of the tree or 0 if none is selected + virtual IGUITreeViewNode* getSelected() const = 0; + + //! returns true if the tree lines are visible + virtual bool getLinesVisible() const = 0; + + //! sets if the tree lines are visible + /** \param visible true for visible, false for invisible */ + virtual void setLinesVisible( bool visible ) = 0; + + //! Sets the font which should be used as icon font. + /** This font is set to the Irrlicht engine built-in-font by + default. Icons can be displayed in front of every list item. + An icon is a string, displayed with the icon font. When using + the build-in-font of the Irrlicht engine as icon font, the icon + strings defined in GUIIcons.h can be used. + */ + virtual void setIconFont( IGUIFont* font ) = 0; + + //! Sets the image list which should be used for the image and selected image of every node. + /** The default is 0 (no images). */ + virtual void setImageList( IGUIImageList* imageList ) = 0; + + //! Returns the image list which is used for the nodes. + virtual IGUIImageList* getImageList() const = 0; + + //! Sets if the image is left of the icon. Default is true. + virtual void setImageLeftOfIcon( bool bLeftOf ) = 0; + + //! Returns if the Image is left of the icon. Default is true. + virtual bool getImageLeftOfIcon() const = 0; + + //! Returns the node which is associated to the last event. + /** This pointer is only valid inside the OnEvent call! */ + virtual IGUITreeViewNode* getLastEventNode() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGUIWindow.h b/builddir/irrlicht-1.8.1/include/IGUIWindow.h new file mode 100644 index 0000000..23d45da --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGUIWindow.h @@ -0,0 +1,74 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_WINDOW_H_INCLUDED__ +#define __I_GUI_WINDOW_H_INCLUDED__ + +#include "IGUIElement.h" +#include "EMessageBoxFlags.h" + +namespace irr +{ +namespace gui +{ + class IGUIButton; + + //! Default moveable window GUI element with border, caption and close icons. + /** \par This element can create the following events of type EGUI_EVENT_TYPE: + \li EGET_ELEMENT_CLOSED + */ + class IGUIWindow : public IGUIElement + { + public: + + //! constructor + IGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) + : IGUIElement(EGUIET_WINDOW, environment, parent, id, rectangle) {} + + //! Returns pointer to the close button + /** You can hide the button by calling setVisible(false) on the result. */ + virtual IGUIButton* getCloseButton() const = 0; + + //! Returns pointer to the minimize button + /** You can hide the button by calling setVisible(false) on the result. */ + virtual IGUIButton* getMinimizeButton() const = 0; + + //! Returns pointer to the maximize button + /** You can hide the button by calling setVisible(false) on the result. */ + virtual IGUIButton* getMaximizeButton() const = 0; + + //! Returns true if the window can be dragged with the mouse, false if not + virtual bool isDraggable() const = 0; + + //! Sets whether the window can be dragged by the mouse + virtual void setDraggable(bool draggable) = 0; + + //! Set if the window background will be drawn + virtual void setDrawBackground(bool draw) = 0; + + //! Get if the window background will be drawn + virtual bool getDrawBackground() const = 0; + + //! Set if the window titlebar will be drawn + //! Note: If the background is not drawn, then the titlebar is automatically also not drawn + virtual void setDrawTitlebar(bool draw) = 0; + + //! Get if the window titlebar will be drawn + virtual bool getDrawTitlebar() const = 0; + + //! Returns the rectangle of the drawable area (without border and without titlebar) + /** The coordinates are given relative to the top-left position of the gui element.<br> + So to get absolute positions you have to add the resulting rectangle to getAbsolutePosition().UpperLeftCorner.<br> + To get it relative to the parent element you have to add the resulting rectangle to getRelativePosition().UpperLeftCorner. + Beware that adding a menu will not change the clientRect as menus are own gui elements, so in that case you might want to subtract + the menu area additionally. */ + virtual core::rect<s32> getClientRect() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IGeometryCreator.h b/builddir/irrlicht-1.8.1/include/IGeometryCreator.h new file mode 100644 index 0000000..22cd013 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IGeometryCreator.h @@ -0,0 +1,177 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GEOMETRY_CREATOR_H_INCLUDED__ +#define __I_GEOMETRY_CREATOR_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "IMesh.h" +#include "IImage.h" + +namespace irr +{ +namespace video +{ + class IVideoDriver; + class SMaterial; +} + +namespace scene +{ + +//! Helper class for creating geometry on the fly. +/** You can get an instance of this class through ISceneManager::getGeometryCreator() */ +class IGeometryCreator : public IReferenceCounted +{ +public: + + //! Creates a simple cube mesh. + /** + \param size Dimensions of the cube. + \return Generated mesh. + */ + virtual IMesh* createCubeMesh(const core::vector3df& size=core::vector3df(5.f,5.f,5.f)) const =0; + + //! Create a pseudo-random mesh representing a hilly terrain. + /** + \param tileSize The size of each tile. + \param tileCount The number of tiles in each dimension. + \param material The material to apply to the mesh. + \param hillHeight The maximum height of the hills. + \param countHills The number of hills along each dimension. + \param textureRepeatCount The number of times to repeat the material texture along each dimension. + \return Generated mesh. + */ + virtual IMesh* createHillPlaneMesh( + const core::dimension2d<f32>& tileSize, + const core::dimension2d<u32>& tileCount, + video::SMaterial* material, f32 hillHeight, + const core::dimension2d<f32>& countHills, + const core::dimension2d<f32>& textureRepeatCount) const =0; + + //! Create a simple rectangular textured plane mesh. + /** + \param tileSize The size of each tile. + \param tileCount The number of tiles in each dimension. + \param material The material to apply to the mesh. + \param textureRepeatCount The number of times to repeat the material texture along each dimension. + \return Generated mesh. + */ + IMesh* createPlaneMesh( + const core::dimension2d<f32>& tileSize, + const core::dimension2d<u32>& tileCount=core::dimension2du(1,1), + video::SMaterial* material=0, + const core::dimension2df& textureRepeatCount=core::dimension2df(1.f,1.f)) const + { + return createHillPlaneMesh(tileSize, tileCount, material, 0.f, core::dimension2df(), textureRepeatCount); + } + + //! Create a terrain mesh from an image representing a heightfield. + /** + \param texture The texture to apply to the terrain. + \param heightmap An image that will be interpreted as a heightmap. The + brightness (average color) of each pixel is interpreted as a height, + with a 255 brightness pixel producing the maximum height. + \param stretchSize The size that each pixel will produce, i.e. a + 512x512 heightmap + and a stretchSize of (10.f, 20.f) will produce a mesh of size + 5120.f x 10240.f + \param maxHeight The maximum height of the terrain. + \param driver The current video driver. + \param defaultVertexBlockSize (to be documented) + \param debugBorders (to be documented) + \return Generated mesh. + */ + virtual IMesh* createTerrainMesh(video::IImage* texture, + video::IImage* heightmap, + const core::dimension2d<f32>& stretchSize, + f32 maxHeight, video::IVideoDriver* driver, + const core::dimension2d<u32>& defaultVertexBlockSize, + bool debugBorders=false) const =0; + + //! Create an arrow mesh, composed of a cylinder and a cone. + /** + \param tesselationCylinder Number of quads composing the cylinder. + \param tesselationCone Number of triangles composing the cone's roof. + \param height Total height of the arrow + \param cylinderHeight Total height of the cylinder, should be lesser + than total height + \param widthCylinder Diameter of the cylinder + \param widthCone Diameter of the cone's base, should be not smaller + than the cylinder's diameter + \param colorCylinder color of the cylinder + \param colorCone color of the cone + \return Generated mesh. + */ + virtual IMesh* createArrowMesh(const u32 tesselationCylinder = 4, + const u32 tesselationCone = 8, const f32 height = 1.f, + const f32 cylinderHeight = 0.6f, const f32 widthCylinder = 0.05f, + const f32 widthCone = 0.3f, const video::SColor colorCylinder = 0xFFFFFFFF, + const video::SColor colorCone = 0xFFFFFFFF) const =0; + + + //! Create a sphere mesh. + /** + \param radius Radius of the sphere + \param polyCountX Number of quads used for the horizontal tiling + \param polyCountY Number of quads used for the vertical tiling + \return Generated mesh. + */ + virtual IMesh* createSphereMesh(f32 radius = 5.f, + u32 polyCountX = 16, u32 polyCountY = 16) const =0; + + //! Create a cylinder mesh. + /** + \param radius Radius of the cylinder. + \param length Length of the cylinder. + \param tesselation Number of quads around the circumference of the cylinder. + \param color The color of the cylinder. + \param closeTop If true, close the ends of the cylinder, otherwise leave them open. + \param oblique (to be documented) + \return Generated mesh. + */ + virtual IMesh* createCylinderMesh(f32 radius, f32 length, + u32 tesselation, + const video::SColor& color=video::SColor(0xffffffff), + bool closeTop=true, f32 oblique=0.f) const =0; + + //! Create a cone mesh. + /** + \param radius Radius of the cone. + \param length Length of the cone. + \param tesselation Number of quads around the circumference of the cone. + \param colorTop The color of the top of the cone. + \param colorBottom The color of the bottom of the cone. + \param oblique (to be documented) + \return Generated mesh. + */ + virtual IMesh* createConeMesh(f32 radius, f32 length, u32 tesselation, + const video::SColor& colorTop=video::SColor(0xffffffff), + const video::SColor& colorBottom=video::SColor(0xffffffff), + f32 oblique=0.f) const =0; + + //! Create a volume light mesh. + /** + \param subdivideU Horizontal patch count. + \param subdivideV Vertical patch count. + \param footColor Color at the bottom of the light. + \param tailColor Color at the mid of the light. + \param lpDistance Virtual distance of the light point for normals. + \param lightDim Dimensions of the light. + \return Generated mesh. + */ + virtual IMesh* createVolumeLightMesh( + const u32 subdivideU=32, const u32 subdivideV=32, + const video::SColor footColor = 0xffffffff, + const video::SColor tailColor = 0xffffffff, + const f32 lpDistance = 8.f, + const core::vector3df& lightDim = core::vector3df(1.f,1.2f,1.f)) const =0; +}; + + +} // end namespace scene +} // end namespace irr + +#endif // __I_GEOMETRY_CREATOR_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/IImage.h b/builddir/irrlicht-1.8.1/include/IImage.h new file mode 100644 index 0000000..d484293 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IImage.h @@ -0,0 +1,155 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_IMAGE_H_INCLUDED__ +#define __I_IMAGE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "position2d.h" +#include "rect.h" +#include "SColor.h" + +namespace irr +{ +namespace video +{ + +//! Interface for software image data. +/** Image loaders create these images from files. IVideoDrivers convert +these images into their (hardware) textures. +*/ +class IImage : public virtual IReferenceCounted +{ +public: + + //! Lock function. Use this to get a pointer to the image data. + /** After you don't need the pointer anymore, you must call unlock(). + \return Pointer to the image data. What type of data is pointed to + depends on the color format of the image. For example if the color + format is ECF_A8R8G8B8, it is of u32. Be sure to call unlock() after + you don't need the pointer any more. */ + virtual void* lock() = 0; + + //! Unlock function. + /** Should be called after the pointer received by lock() is not + needed anymore. */ + virtual void unlock() = 0; + + //! Returns width and height of image data. + virtual const core::dimension2d<u32>& getDimension() const = 0; + + //! Returns bits per pixel. + virtual u32 getBitsPerPixel() const = 0; + + //! Returns bytes per pixel + virtual u32 getBytesPerPixel() const = 0; + + //! Returns image data size in bytes + virtual u32 getImageDataSizeInBytes() const = 0; + + //! Returns image data size in pixels + virtual u32 getImageDataSizeInPixels() const = 0; + + //! Returns a pixel + virtual SColor getPixel(u32 x, u32 y) const = 0; + + //! Sets a pixel + virtual void setPixel(u32 x, u32 y, const SColor &color, bool blend = false ) = 0; + + //! Returns the color format + virtual ECOLOR_FORMAT getColorFormat() const = 0; + + //! Returns mask for red value of a pixel + virtual u32 getRedMask() const = 0; + + //! Returns mask for green value of a pixel + virtual u32 getGreenMask() const = 0; + + //! Returns mask for blue value of a pixel + virtual u32 getBlueMask() const = 0; + + //! Returns mask for alpha value of a pixel + virtual u32 getAlphaMask() const = 0; + + //! Returns pitch of image + virtual u32 getPitch() const =0; + + //! Copies the image into the target, scaling the image to fit + virtual void copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format=ECF_A8R8G8B8, u32 pitch=0) =0; + + //! Copies the image into the target, scaling the image to fit + virtual void copyToScaling(IImage* target) =0; + + //! copies this surface into another + virtual void copyTo(IImage* target, const core::position2d<s32>& pos=core::position2d<s32>(0,0)) =0; + + //! copies this surface into another + virtual void copyTo(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect=0) =0; + + //! copies this surface into another, using the alpha mask and cliprect and a color to add with + virtual void copyToWithAlpha(IImage* target, const core::position2d<s32>& pos, + const core::rect<s32>& sourceRect, const SColor &color, + const core::rect<s32>* clipRect = 0) =0; + + //! copies this surface into another, scaling it to fit, appyling a box filter + virtual void copyToScalingBoxFilter(IImage* target, s32 bias = 0, bool blend = false) = 0; + + //! fills the surface with given color + virtual void fill(const SColor &color) =0; + + //! get the amount of Bits per Pixel of the given color format + static u32 getBitsPerPixelFromFormat(const ECOLOR_FORMAT format) + { + switch(format) + { + case ECF_A1R5G5B5: + return 16; + case ECF_R5G6B5: + return 16; + case ECF_R8G8B8: + return 24; + case ECF_A8R8G8B8: + return 32; + case ECF_R16F: + return 16; + case ECF_G16R16F: + return 32; + case ECF_A16B16G16R16F: + return 64; + case ECF_R32F: + return 32; + case ECF_G32R32F: + return 64; + case ECF_A32B32G32R32F: + return 128; + default: + return 0; + } + } + + //! test if the color format is only viable for RenderTarget textures + /** Since we don't have support for e.g. floating point IImage formats + one should test if the color format can be used for arbitrary usage, or + if it is restricted to RTTs. */ + static bool isRenderTargetOnlyFormat(const ECOLOR_FORMAT format) + { + switch(format) + { + case ECF_A1R5G5B5: + case ECF_R5G6B5: + case ECF_R8G8B8: + case ECF_A8R8G8B8: + return false; + default: + return true; + } + } + +}; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IImageLoader.h b/builddir/irrlicht-1.8.1/include/IImageLoader.h new file mode 100644 index 0000000..77603f5 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IImageLoader.h @@ -0,0 +1,53 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SURFACE_LOADER_H_INCLUDED__ +#define __I_SURFACE_LOADER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "IImage.h" +#include "path.h" + +namespace irr +{ +namespace io +{ + class IReadFile; +} // end namespace io +namespace video +{ + +//! Class which is able to create a image from a file. +/** If you want the Irrlicht Engine be able to load textures of +currently unsupported file formats (e.g .gif), then implement +this and add your new Surface loader with +IVideoDriver::addExternalImageLoader() to the engine. */ +class IImageLoader : public virtual IReferenceCounted +{ +public: + + //! Check if the file might be loaded by this class + /** Check is based on the file extension (e.g. ".tga") + \param filename Name of file to check. + \return True if file seems to be loadable. */ + virtual bool isALoadableFileExtension(const io::path& filename) const = 0; + + //! Check if the file might be loaded by this class + /** Check might look into the file. + \param file File handle to check. + \return True if file seems to be loadable. */ + virtual bool isALoadableFileFormat(io::IReadFile* file) const = 0; + + //! Creates a surface from the file + /** \param file File handle to check. + \return Pointer to newly created image, or 0 upon error. */ + virtual IImage* loadImage(io::IReadFile* file) const = 0; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IImageWriter.h b/builddir/irrlicht-1.8.1/include/IImageWriter.h new file mode 100644 index 0000000..fd00793 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IImageWriter.h @@ -0,0 +1,45 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _I_IMAGE_WRITER_H_INCLUDED__ +#define _I_IMAGE_WRITER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrString.h" +#include "coreutil.h" + +namespace irr +{ +namespace io +{ + class IWriteFile; +} // end namespace io + +namespace video +{ + class IImage; + + +//! Interface for writing software image data. +class IImageWriter : public IReferenceCounted +{ +public: + //! Check if this writer can write a file with the given extension + /** \param filename Name of the file to check. + \return True if file extension specifies a writable type. */ + virtual bool isAWriteableFileExtension(const io::path& filename) const = 0; + + //! Write image to file + /** \param file File handle to write to. + \param image Image to write into file. + \param param Writer specific parameter, influencing e.g. quality. + \return True if image was successfully written. */ + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param = 0) const = 0; +}; + +} // namespace video +} // namespace irr + +#endif // _I_IMAGE_WRITER_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/IIndexBuffer.h b/builddir/irrlicht-1.8.1/include/IIndexBuffer.h new file mode 100644 index 0000000..ff5738c --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IIndexBuffer.h @@ -0,0 +1,65 @@ +// Copyright (C) 2008-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_INDEX_BUFFER_H_INCLUDED__ +#define __I_INDEX_BUFFER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrArray.h" + +#include "SVertexIndex.h" + +namespace irr +{ + +namespace video +{ + +} + +namespace scene +{ + + class IIndexBuffer : public virtual IReferenceCounted + { + public: + + virtual void* getData() =0; + + virtual video::E_INDEX_TYPE getType() const =0; + virtual void setType(video::E_INDEX_TYPE IndexType) =0; + + virtual u32 stride() const =0; + + virtual u32 size() const =0; + virtual void push_back (const u32 &element) =0; + virtual u32 operator [](u32 index) const =0; + virtual u32 getLast() =0; + virtual void setValue(u32 index, u32 value) =0; + virtual void set_used(u32 usedNow) =0; + virtual void reallocate(u32 new_size) =0; + virtual u32 allocated_size() const=0; + + virtual void* pointer() =0; + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint() const =0; + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint ) =0; + + //! flags the meshbuffer as changed, reloads hardware buffers + virtual void setDirty() = 0; + + //! Get the currently used ID for identification of changes. + /** This shouldn't be used for anything outside the VideoDriver. */ + virtual u32 getChangedID() const = 0; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ILightManager.h b/builddir/irrlicht-1.8.1/include/ILightManager.h new file mode 100644 index 0000000..35fb9cb --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ILightManager.h @@ -0,0 +1,62 @@ +// Written by Colin MacDonald - all rights assigned to Nikolaus Gebhardt +// Copyright (C) 2008-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_LIGHT_MANAGER_H_INCLUDED__ +#define __I_LIGHT_MANAGER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + class ILightSceneNode; + + //! ILightManager provides an interface for user applications to manipulate the list of lights in the scene. + /** The light list can be trimmed or re-ordered before device/ hardware + lights are created, and/or individual lights can be switched on and off + before or after each scene node is rendered. It is assumed that the + ILightManager implementation will store any data that it wishes to + retain, i.e. the ISceneManager to which it is assigned, the lightList, + the current render pass, and the current scene node. */ + class ILightManager : public IReferenceCounted + { + public: + //! Called after the scene's light list has been built, but before rendering has begun. + /** As actual device/hardware lights are not created until the + ESNRP_LIGHT render pass, this provides an opportunity for the + light manager to trim or re-order the light list, before any + device/hardware lights have actually been created. + \param lightList: the Scene Manager's light list, which + the light manager may modify. This reference will remain valid + until OnPostRender(). + */ + virtual void OnPreRender(core::array<ISceneNode*> & lightList) = 0; + + //! Called after the last scene node is rendered. + /** After this call returns, the lightList passed to OnPreRender() becomes invalid. */ + virtual void OnPostRender(void) = 0; + + //! Called before a render pass begins + /** \param renderPass: the render pass that's about to begin */ + virtual void OnRenderPassPreRender(E_SCENE_NODE_RENDER_PASS renderPass) = 0; + + //! Called after the render pass specified in OnRenderPassPreRender() ends + /** \param[in] renderPass: the render pass that has finished */ + virtual void OnRenderPassPostRender(E_SCENE_NODE_RENDER_PASS renderPass) = 0; + + //! Called before the given scene node is rendered + /** \param[in] node: the scene node that's about to be rendered */ + virtual void OnNodePreRender(ISceneNode* node) = 0; + + //! Called after the the node specified in OnNodePreRender() has been rendered + /** \param[in] node: the scene node that has just been rendered */ + virtual void OnNodePostRender(ISceneNode* node) = 0; + }; +} // end namespace scene +} // end namespace irr + +#endif diff --git a/builddir/irrlicht-1.8.1/include/ILightSceneNode.h b/builddir/irrlicht-1.8.1/include/ILightSceneNode.h new file mode 100644 index 0000000..3feb207 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ILightSceneNode.h @@ -0,0 +1,86 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_LIGHT_SCENE_NODE_H_INCLUDED__ +#define __I_LIGHT_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "SLight.h" + +namespace irr +{ +namespace scene +{ + +//! Scene node which is a dynamic light. +/** You can switch the light on and off by making it visible or not. It can be +animated by ordinary scene node animators. If the light type is directional or +spot, the direction of the light source is defined by the rotation of the scene +node (assuming (0,0,1) as the local direction of the light). +*/ +class ILightSceneNode : public ISceneNode +{ +public: + + //! constructor + ILightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0)) + : ISceneNode(parent, mgr, id, position) {} + + //! Sets the light data associated with this ILightSceneNode + /** \param light The new light data. */ + virtual void setLightData(const video::SLight& light) = 0; + + //! Gets the light data associated with this ILightSceneNode + /** \return The light data. */ + virtual const video::SLight& getLightData() const = 0; + + //! Gets the light data associated with this ILightSceneNode + /** \return The light data. */ + virtual video::SLight& getLightData() = 0; + + //! Sets if the node should be visible or not. + /** All children of this node won't be visible either, when set + to true. + \param isVisible If the node shall be visible. */ + virtual void setVisible(bool isVisible) = 0; + + //! Sets the light's radius of influence. + /** Outside this radius the light won't lighten geometry and cast no + shadows. Setting the radius will also influence the attenuation, setting + it to (0,1/radius,0). If you want to override this behavior, set the + attenuation after the radius. + \param radius The new radius. */ + virtual void setRadius(f32 radius) = 0; + + //! Gets the light's radius of influence. + /** \return The current radius. */ + virtual f32 getRadius() const = 0; + + //! Sets the light type. + /** \param type The new type. */ + virtual void setLightType(video::E_LIGHT_TYPE type) = 0; + + //! Gets the light type. + /** \return The current light type. */ + virtual video::E_LIGHT_TYPE getLightType() const = 0; + + //! Sets whether this light casts shadows. + /** Enabling this flag won't automatically cast shadows, the meshes + will still need shadow scene nodes attached. But one can enable or + disable distinct lights for shadow casting for performance reasons. + \param shadow True if this light shall cast shadows. */ + virtual void enableCastShadow(bool shadow=true) = 0; + + //! Check whether this light casts shadows. + /** \return True if light would cast shadows, else false. */ + virtual bool getCastShadow() const = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ILogger.h b/builddir/irrlicht-1.8.1/include/ILogger.h new file mode 100644 index 0000000..53f6273 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ILogger.h @@ -0,0 +1,102 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_LOGGER_H_INCLUDED__ +#define __I_LOGGER_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ + +//! Possible log levels. +//! When used has filter ELL_DEBUG means => log everything and ELL_NONE means => log (nearly) nothing. +//! When used to print logging information ELL_DEBUG will have lowest priority while ELL_NONE +//! messages are never filtered and always printed. +enum ELOG_LEVEL +{ + //! Used for printing information helpful in debugging + ELL_DEBUG, + + //! Useful information to print. For example hardware infos or something started/stopped. + ELL_INFORMATION, + + //! Warnings that something isn't as expected and can cause oddities + ELL_WARNING, + + //! Something did go wrong. + ELL_ERROR, + + //! Logs with ELL_NONE will never be filtered. + //! And used as filter it will remove all logging except ELL_NONE messages. + ELL_NONE +}; + + +//! Interface for logging messages, warnings and errors +class ILogger : public virtual IReferenceCounted +{ +public: + + //! Destructor + virtual ~ILogger() {} + + //! Returns the current set log level. + virtual ELOG_LEVEL getLogLevel() const = 0; + + //! Sets a new log level. + /** With this value, texts which are sent to the logger are filtered + out. For example setting this value to ELL_WARNING, only warnings and + errors are printed out. Setting it to ELL_INFORMATION, which is the + default setting, warnings, errors and informational texts are printed + out. + \param ll: new log level filter value. */ + virtual void setLogLevel(ELOG_LEVEL ll) = 0; + + //! Prints out a text into the log + /** \param text: Text to print out. + \param ll: Log level of the text. If the text is an error, set + it to ELL_ERROR, if it is warning set it to ELL_WARNING, and if it + is just an informational text, set it to ELL_INFORMATION. Texts are + filtered with these levels. If you want to be a text displayed, + independent on what level filter is set, use ELL_NONE. */ + virtual void log(const c8* text, ELOG_LEVEL ll=ELL_INFORMATION) = 0; + + //! Prints out a text into the log + /** \param text: Text to print out. + \param hint: Additional info. This string is added after a " :" to the + string. + \param ll: Log level of the text. If the text is an error, set + it to ELL_ERROR, if it is warning set it to ELL_WARNING, and if it + is just an informational text, set it to ELL_INFORMATION. Texts are + filtered with these levels. If you want to be a text displayed, + independent on what level filter is set, use ELL_NONE. */ + virtual void log(const c8* text, const c8* hint, ELOG_LEVEL ll=ELL_INFORMATION) = 0; + virtual void log(const c8* text, const wchar_t* hint, ELOG_LEVEL ll=ELL_INFORMATION) = 0; + + //! Prints out a text into the log + /** \param text: Text to print out. + \param hint: Additional info. This string is added after a " :" to the + string. + \param ll: Log level of the text. If the text is an error, set + it to ELL_ERROR, if it is warning set it to ELL_WARNING, and if it + is just an informational text, set it to ELL_INFORMATION. Texts are + filtered with these levels. If you want to be a text displayed, + independent on what level filter is set, use ELL_NONE. */ + virtual void log(const wchar_t* text, const wchar_t* hint, ELOG_LEVEL ll=ELL_INFORMATION) = 0; + + //! Prints out a text into the log + /** \param text: Text to print out. + \param ll: Log level of the text. If the text is an error, set + it to ELL_ERROR, if it is warning set it to ELL_WARNING, and if it + is just an informational text, set it to ELL_INFORMATION. Texts are + filtered with these levels. If you want to be a text displayed, + independent on what level filter is set, use ELL_NONE. */ + virtual void log(const wchar_t* text, ELOG_LEVEL ll=ELL_INFORMATION) = 0; +}; + +} // end namespace + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IMaterialRenderer.h b/builddir/irrlicht-1.8.1/include/IMaterialRenderer.h new file mode 100644 index 0000000..a4e1d20 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IMaterialRenderer.h @@ -0,0 +1,101 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MATERIAL_RENDERER_H_INCLUDED__ +#define __I_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SMaterial.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace video +{ + +class IVideoDriver; +class IMaterialRendererServices; + +//! Interface for material rendering. +/** Can be used to extend the engine with new materials. Refer to +IVideoDriver::addMaterialRenderer() for more informations on how to extend the +engine with new materials. */ +class IMaterialRenderer : public virtual IReferenceCounted +{ +public: + + //! Called by the IVideoDriver implementation the let the renderer set its needed render states. + /** This is called during the IVideoDriver::setMaterial() call. + When overriding this, you can set some renderstates or for example a + vertex or pixel shader if you like. + \param material: The new material parameters to be set. The renderer + may change the material flags in this material. For example if this + material does not accept the zbuffer = true, it can set it to false. + This is useful, because in the next lastMaterial will be just the + material in this call. + \param lastMaterial: The material parameters which have been set before + this material. + \param resetAllRenderstates: True if all renderstates should really be + reset. This is usually true if the last rendering mode was not a usual + 3d rendering mode, but for example a 2d rendering mode. + You should reset really all renderstates if this is true, no matter if + the lastMaterial had some similar settings. This is used because in + most cases, some common renderstates are not changed if they are + already there, for example bilinear filtering, wireframe, + gouraudshading, lighting, zbuffer, zwriteenable, backfaceculling and + fogenable. + \param services: Interface providing some methods for changing + advanced, internal states of a IVideoDriver. */ + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) {} + + //! Called every time before a new bunch of geometry is being drawn using this material with for example drawIndexedTriangleList() call. + /** OnSetMaterial should normally only be called if the renderer decides + that the renderstates should be changed, it won't be called if for + example two drawIndexedTriangleList() will be called with the same + material set. This method will be called every time. This is useful for + example for materials with shaders, which don't only set new + renderstates but also shader constants. + \param service: Pointer to interface providing methos for setting + constants and other things. + \param vtxtype: Vertex type with which the next rendering will be done. + This can be used by the material renderer to set some specific + optimized shaders or if this is an incompatible vertex type for this + renderer, to refuse rendering for example. + \return Returns true if everything is ok, and false if nothing should + be rendered. The material renderer can choose to return false for + example if he doesn't support the specified vertex type. This is + actually done in D3D8 and D3D9 when using a normal mapped material with + a vertex type other than EVT_TANGENTS. */ + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) { return true; } + + //! Called by the IVideoDriver to unset this material. + /** Called during the IVideoDriver::setMaterial() call before the new + material will get the OnSetMaterial() call. */ + virtual void OnUnsetMaterial() {} + + //! Returns if the material is transparent. + /** The scene managment needs to know this + for being able to sort the materials by opaque and transparent. */ + virtual bool isTransparent() const { return false; } + + //! Returns the render capability of the material. + /** Because some more complex materials + are implemented in multiple ways and need special hardware capabilities, it is possible + to query how the current material renderer is performing on the current hardware with this + function. + \return Returns 0 if everything is running fine. Any other value is material renderer + specific and means for example that the renderer switched back to a fall back material because + it cannot use the latest shaders. More specific examples: + Fixed function pipeline materials should return 0 in most cases, parallax mapped + material will only return 0 when at least pixel shader 1.4 is available on that machine. */ + virtual s32 getRenderCapability() const { return 0; } +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IMaterialRendererServices.h b/builddir/irrlicht-1.8.1/include/IMaterialRendererServices.h new file mode 100644 index 0000000..dafad09 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IMaterialRendererServices.h @@ -0,0 +1,115 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MATERIAL_RENDERER_SERVICES_H_INCLUDED__ +#define __I_MATERIAL_RENDERER_SERVICES_H_INCLUDED__ + +#include "SMaterial.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace video +{ + +class IVideoDriver; + + +//! Interface providing some methods for changing advanced, internal states of a IVideoDriver. +class IMaterialRendererServices +{ +public: + + //! Destructor + virtual ~IMaterialRendererServices() {} + + //! Can be called by an IMaterialRenderer to make its work easier. + /** Sets all basic renderstates if needed. + Basic render states are diffuse, ambient, specular, and emissive color, + specular power, bilinear and trilinear filtering, wireframe mode, + grouraudshading, lighting, zbuffer, zwriteenable, backfaceculling and + fog enabling. + \param material The new material to be used. + \param lastMaterial The material used until now. + \param resetAllRenderstates Set to true if all renderstates should be + set, regardless of their current state. */ + virtual void setBasicRenderStates(const SMaterial& material, + const SMaterial& lastMaterial, + bool resetAllRenderstates) = 0; + + //! Sets a constant for the vertex shader based on a name. + /** This can be used if you used a high level shader language like GLSL + or HLSL to create a shader. Example: If you created a shader which has + variables named 'mWorldViewProj' (containing the WorldViewProjection + matrix) and another one named 'fTime' containing one float, you can set + them in your IShaderConstantSetCallBack derived class like this: + \code + virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + f32 time = (f32)os::Timer::getTime()/100000.0f; + services->setVertexShaderConstant("fTime", &time, 1); + + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16); + } + \endcode + \param name Name of the variable + \param floats Pointer to array of floats + \param count Amount of floats in array. + \return True if successful. + */ + virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count) = 0; + + //! Bool interface for the above. + virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count) = 0; + + //! Int interface for the above. + virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count) = 0; + + //! Sets a vertex shader constant. + /** Can be used if you created a shader using pixel/vertex shader + assembler or ARB_fragment_program or ARB_vertex_program. + \param data: Data to be set in the constants + \param startRegister: First register to be set + \param constantAmount: Amount of registers to be set. One register consists of 4 floats. */ + virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) = 0; + + //! Sets a constant for the pixel shader based on a name. + /** This can be used if you used a high level shader language like GLSL + or HLSL to create a shader. See setVertexShaderConstant() for an + example on how to use this. + \param name Name of the variable + \param floats Pointer to array of floats + \param count Amount of floats in array. + \return True if successful. */ + virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count) = 0; + + //! Bool interface for the above. + virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count) = 0; + + //! Int interface for the above. + virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count) = 0; + + //! Sets a pixel shader constant. + /** Can be used if you created a shader using pixel/vertex shader + assembler or ARB_fragment_program or ARB_vertex_program. + \param data Data to be set in the constants + \param startRegister First register to be set. + \param constantAmount Amount of registers to be set. One register consists of 4 floats. */ + virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) = 0; + + //! Get pointer to the IVideoDriver interface + /** \return Pointer to the IVideoDriver interface */ + virtual IVideoDriver* getVideoDriver() = 0; +}; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IMesh.h b/builddir/irrlicht-1.8.1/include/IMesh.h new file mode 100644 index 0000000..89f936b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IMesh.h @@ -0,0 +1,75 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_H_INCLUDED__ +#define __I_MESH_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SMaterial.h" +#include "EHardwareBufferFlags.h" + +namespace irr +{ +namespace scene +{ + class IMeshBuffer; + + //! Class which holds the geometry of an object. + /** An IMesh is nothing more than a collection of some mesh buffers + (IMeshBuffer). SMesh is a simple implementation of an IMesh. + A mesh is usually added to an IMeshSceneNode in order to be rendered. + */ + class IMesh : public virtual IReferenceCounted + { + public: + + //! Get the amount of mesh buffers. + /** \return Amount of mesh buffers (IMeshBuffer) in this mesh. */ + virtual u32 getMeshBufferCount() const = 0; + + //! Get pointer to a mesh buffer. + /** \param nr: Zero based index of the mesh buffer. The maximum value is + getMeshBufferCount() - 1; + \return Pointer to the mesh buffer or 0 if there is no such + mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer(u32 nr) const = 0; + + //! Get pointer to a mesh buffer which fits a material + /** \param material: material to search for + \return Pointer to the mesh buffer or 0 if there is no such + mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const = 0; + + //! Get an axis aligned bounding box of the mesh. + /** \return Bounding box of this mesh. */ + virtual const core::aabbox3d<f32>& getBoundingBox() const = 0; + + //! Set user-defined axis aligned bounding box + /** \param box New bounding box to use for the mesh. */ + virtual void setBoundingBox( const core::aabbox3df& box) = 0; + + //! Sets a flag of all contained materials to a new value. + /** \param flag: Flag to set in all materials. + \param newvalue: New value to set in all materials. */ + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) = 0; + + //! Set the hardware mapping hint + /** This methods allows to define optimization hints for the + hardware. This enables, e.g., the use of hardware buffers on + pltforms that support this feature. This can lead to noticeable + performance gains. */ + virtual void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) = 0; + + //! Flag the meshbuffer as changed, reloads hardware buffers + /** This method has to be called every time the vertices or + indices have changed. Otherwise, changes won't be updated + on the GPU in the next render cycle. */ + virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IMeshBuffer.h b/builddir/irrlicht-1.8.1/include/IMeshBuffer.h new file mode 100644 index 0000000..99a9f48 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IMeshBuffer.h @@ -0,0 +1,154 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_BUFFER_H_INCLUDED__ +#define __I_MESH_BUFFER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SMaterial.h" +#include "aabbox3d.h" +#include "S3DVertex.h" +#include "SVertexIndex.h" +#include "EHardwareBufferFlags.h" +#include "EPrimitiveTypes.h" + +namespace irr +{ +namespace scene +{ + //! Struct for holding a mesh with a single material. + /** A part of an IMesh which has the same material on each face of that + group. Logical groups of an IMesh need not be put into separate mesh + buffers, but can be. Separately animated parts of the mesh must be put + into separate mesh buffers. + Some mesh buffer implementations have limitations on the number of + vertices the buffer can hold. In that case, logical grouping can help. + Moreover, the number of vertices should be optimized for the GPU upload, + which often depends on the type of gfx card. Typial figures are + 1000-10000 vertices per buffer. + SMeshBuffer is a simple implementation of a MeshBuffer, which supports + up to 65535 vertices. + + Since meshbuffers are used for drawing, and hence will be exposed + to the driver, chances are high that they are grab()'ed from somewhere. + It's therefore required to dynamically allocate meshbuffers which are + passed to a video driver and only drop the buffer once it's not used in + the current code block anymore. + */ + class IMeshBuffer : public virtual IReferenceCounted + { + public: + + //! Get the material of this meshbuffer + /** \return Material of this buffer. */ + virtual video::SMaterial& getMaterial() = 0; + + //! Get the material of this meshbuffer + /** \return Material of this buffer. */ + virtual const video::SMaterial& getMaterial() const = 0; + + //! Get type of vertex data which is stored in this meshbuffer. + /** \return Vertex type of this buffer. */ + virtual video::E_VERTEX_TYPE getVertexType() const = 0; + + //! Get access to vertex data. The data is an array of vertices. + /** Which vertex type is used can be determined by getVertexType(). + \return Pointer to array of vertices. */ + virtual const void* getVertices() const = 0; + + //! Get access to vertex data. The data is an array of vertices. + /** Which vertex type is used can be determined by getVertexType(). + \return Pointer to array of vertices. */ + virtual void* getVertices() = 0; + + //! Get amount of vertices in meshbuffer. + /** \return Number of vertices in this buffer. */ + virtual u32 getVertexCount() const = 0; + + //! Get type of index data which is stored in this meshbuffer. + /** \return Index type of this buffer. */ + virtual video::E_INDEX_TYPE getIndexType() const =0; + + //! Get access to Indices. + /** \return Pointer to indices array. */ + virtual const u16* getIndices() const = 0; + + //! Get access to Indices. + /** \return Pointer to indices array. */ + virtual u16* getIndices() = 0; + + //! Get amount of indices in this meshbuffer. + /** \return Number of indices in this buffer. */ + virtual u32 getIndexCount() const = 0; + + //! Get the axis aligned bounding box of this meshbuffer. + /** \return Axis aligned bounding box of this buffer. */ + virtual const core::aabbox3df& getBoundingBox() const = 0; + + //! Set axis aligned bounding box + /** \param box User defined axis aligned bounding box to use + for this buffer. */ + virtual void setBoundingBox(const core::aabbox3df& box) = 0; + + //! Recalculates the bounding box. Should be called if the mesh changed. + virtual void recalculateBoundingBox() = 0; + + //! returns position of vertex i + virtual const core::vector3df& getPosition(u32 i) const = 0; + + //! returns position of vertex i + virtual core::vector3df& getPosition(u32 i) = 0; + + //! returns normal of vertex i + virtual const core::vector3df& getNormal(u32 i) const = 0; + + //! returns normal of vertex i + virtual core::vector3df& getNormal(u32 i) = 0; + + //! returns texture coord of vertex i + virtual const core::vector2df& getTCoords(u32 i) const = 0; + + //! returns texture coord of vertex i + virtual core::vector2df& getTCoords(u32 i) = 0; + + //! Append the vertices and indices to the current buffer + /** Only works for compatible vertex types. + \param vertices Pointer to a vertex array. + \param numVertices Number of vertices in the array. + \param indices Pointer to index array. + \param numIndices Number of indices in array. */ + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) = 0; + + //! Append the meshbuffer to the current buffer + /** Only works for compatible vertex types + \param other Buffer to append to this one. */ + virtual void append(const IMeshBuffer* const other) = 0; + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const = 0; + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint_Index() const = 0; + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint( E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX ) = 0; + + //! flags the meshbuffer as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) = 0; + + //! Get the currently used ID for identification of changes. + /** This shouldn't be used for anything outside the VideoDriver. */ + virtual u32 getChangedID_Vertex() const = 0; + + //! Get the currently used ID for identification of changes. + /** This shouldn't be used for anything outside the VideoDriver. */ + virtual u32 getChangedID_Index() const = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + + diff --git a/builddir/irrlicht-1.8.1/include/IMeshCache.h b/builddir/irrlicht-1.8.1/include/IMeshCache.h new file mode 100644 index 0000000..2d2bfa0 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IMeshCache.h @@ -0,0 +1,177 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_CACHE_H_INCLUDED__ +#define __I_MESH_CACHE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "path.h" + +namespace irr +{ + +namespace scene +{ + class IMesh; + class IAnimatedMesh; + class IAnimatedMeshSceneNode; + class IMeshLoader; + + //! The mesh cache stores already loaded meshes and provides an interface to them. + /** You can access it using ISceneManager::getMeshCache(). All existing + scene managers will return a pointer to the same mesh cache, because it + is shared between them. With this interface, it is possible to manually + add new loaded meshes (if ISceneManager::getMesh() is not sufficient), + to remove them and to iterate through already loaded meshes. */ + class IMeshCache : public virtual IReferenceCounted + { + public: + + //! Destructor + virtual ~IMeshCache() {} + + //! Adds a mesh to the internal list of loaded meshes. + /** Usually, ISceneManager::getMesh() is called to load a mesh + from a file. That method searches the list of loaded meshes if + a mesh has already been loaded and returns a pointer to if it + is in that list and already in memory. Otherwise it loads the + mesh. With IMeshCache::addMesh(), it is possible to pretend + that a mesh already has been loaded. This method can be used + for example by mesh loaders who need to load more than one mesh + with one call. They can add additional meshes with this method + to the scene manager. The COLLADA loader for example uses this + method. + \param name Name of the mesh. When calling + ISceneManager::getMesh() with this name it will return the mesh + set by this method. + \param mesh Pointer to a mesh which will now be referenced by + this name. */ + virtual void addMesh(const io::path& name, IAnimatedMesh* mesh) = 0; + + //! Removes the mesh from the cache. + /** After loading a mesh with getMesh(), the mesh can be + removed from the cache using this method, freeing a lot of + memory. + \param mesh Pointer to the mesh which shall be removed. */ + virtual void removeMesh(const IMesh* const mesh) = 0; + + //! Returns amount of loaded meshes in the cache. + /** You can load new meshes into the cache using getMesh() and + addMesh(). If you ever need to access the internal mesh cache, + you can do this using removeMesh(), getMeshNumber(), + getMeshByIndex() and getMeshName(). + \return Number of meshes in cache. */ + virtual u32 getMeshCount() const = 0; + + //! Returns current index number of the mesh or -1 when not found. + /** \param mesh Pointer to the mesh to search for. + \return Index of the mesh in the cache, or -1 if not found. */ + virtual s32 getMeshIndex(const IMesh* const mesh) const = 0; + + //! Returns a mesh based on its index number. + /** \param index: Index of the mesh, number between 0 and + getMeshCount()-1. + Note that this number is only valid until a new mesh is loaded + or removed. + \return Pointer to the mesh or 0 if there is none with this + number. */ + virtual IAnimatedMesh* getMeshByIndex(u32 index) = 0; + + //! Returns a mesh based on its name (often a filename). + /** \deprecated Use getMeshByName() instead. This method may be removed by + Irrlicht 1.9 */ + _IRR_DEPRECATED_ IAnimatedMesh* getMeshByFilename(const io::path& filename) + { + return getMeshByName(filename); + } + + //! Get the name of a loaded mesh, based on its index. (Name is often identical to the filename). + /** \deprecated Use getMeshName() instead. This method may be removed by + Irrlicht 1.9 */ + _IRR_DEPRECATED_ const io::path& getMeshFilename(u32 index) const + { + return getMeshName(index).getInternalName(); + } + + //! Get the name of a loaded mesh, if there is any. (Name is often identical to the filename). + /** \deprecated Use getMeshName() instead. This method may be removed by + Irrlicht 1.9 */ + _IRR_DEPRECATED_ const io::path& getMeshFilename(const IMesh* const mesh) const + { + return getMeshName(mesh).getInternalName(); + } + + //! Renames a loaded mesh. + /** \deprecated Use renameMesh() instead. This method may be removed by + Irrlicht 1.9 */ + _IRR_DEPRECATED_ bool setMeshFilename(u32 index, const io::path& filename) + { + return renameMesh(index, filename); + } + + //! Renames a loaded mesh. + /** \deprecated Use renameMesh() instead. This method may be removed by + Irrlicht 1.9 */ + _IRR_DEPRECATED_ bool setMeshFilename(const IMesh* const mesh, const io::path& filename) + { + return renameMesh(mesh, filename); + } + + //! Returns a mesh based on its name. + /** \param name Name of the mesh. Usually a filename. + \return Pointer to the mesh or 0 if there is none with this number. */ + virtual IAnimatedMesh* getMeshByName(const io::path& name) = 0; + + //! Get the name of a loaded mesh, based on its index. + /** \param index: Index of the mesh, number between 0 and getMeshCount()-1. + \return The name if mesh was found and has a name, else the path is empty. */ + virtual const io::SNamedPath& getMeshName(u32 index) const = 0; + + //! Get the name of the loaded mesh if there is any. + /** \param mesh Pointer to mesh to query. + \return The name if mesh was found and has a name, else the path is empty. */ + virtual const io::SNamedPath& getMeshName(const IMesh* const mesh) const = 0; + + //! Renames a loaded mesh. + /** Note that renaming meshes might change the ordering of the + meshes, and so the index of the meshes as returned by + getMeshIndex() or taken by some methods will change. + \param index The index of the mesh in the cache. + \param name New name for the mesh. + \return True if mesh was renamed. */ + virtual bool renameMesh(u32 index, const io::path& name) = 0; + + //! Renames the loaded mesh + /** Note that renaming meshes might change the ordering of the + meshes, and so the index of the meshes as returned by + getMeshIndex() or taken by some methods will change. + \param mesh Mesh to be renamed. + \param name New name for the mesh. + \return True if mesh was renamed. */ + virtual bool renameMesh(const IMesh* const mesh, const io::path& name) = 0; + + //! Check if a mesh was already loaded. + /** \param name Name of the mesh. Usually a filename. + \return True if the mesh has been loaded, else false. */ + virtual bool isMeshLoaded(const io::path& name) = 0; + + //! Clears the whole mesh cache, removing all meshes. + /** All meshes will be reloaded completely when using ISceneManager::getMesh() + after calling this method. + Warning: If you have pointers to meshes that were loaded with ISceneManager::getMesh() + and you did not grab them, then they may become invalid. */ + virtual void clear() = 0; + + //! Clears all meshes that are held in the mesh cache but not used anywhere else. + /** Warning: If you have pointers to meshes that were loaded with ISceneManager::getMesh() + and you did not grab them, then they may become invalid. */ + virtual void clearUnusedMeshes() = 0; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IMeshLoader.h b/builddir/irrlicht-1.8.1/include/IMeshLoader.h new file mode 100644 index 0000000..3955fb4 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IMeshLoader.h @@ -0,0 +1,53 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_LOADER_H_INCLUDED__ +#define __I_MESH_LOADER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "path.h" + +namespace irr +{ +namespace io +{ + class IReadFile; +} // end namespace io +namespace scene +{ + class IAnimatedMesh; + +//! Class which is able to load an animated mesh from a file. +/** If you want Irrlicht be able to load meshes of +currently unsupported file formats (e.g. .cob), then implement +this and add your new Meshloader with +ISceneManager::addExternalMeshLoader() to the engine. */ +class IMeshLoader : public virtual IReferenceCounted +{ +public: + + //! Destructor + virtual ~IMeshLoader() {} + + //! Returns true if the file might be loaded by this class. + /** This decision should be based on the file extension (e.g. ".cob") + only. + \param filename Name of the file to test. + \return True if the file might be loaded by this class. */ + virtual bool isALoadableFileExtension(const io::path& filename) const = 0; + + //! Creates/loads an animated mesh from the file. + /** \param file File handler to load the file from. + \return Pointer to the created mesh. Returns 0 if loading failed. + If you no longer need the mesh, you should call IAnimatedMesh::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IAnimatedMesh* createMesh(io::IReadFile* file) = 0; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IMeshManipulator.h b/builddir/irrlicht-1.8.1/include/IMeshManipulator.h new file mode 100644 index 0000000..d6ac89f --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IMeshManipulator.h @@ -0,0 +1,393 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_MANIPULATOR_H_INCLUDED__ +#define __I_MESH_MANIPULATOR_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "vector3d.h" +#include "aabbox3d.h" +#include "matrix4.h" +#include "IAnimatedMesh.h" +#include "IMeshBuffer.h" +#include "SVertexManipulator.h" + +namespace irr +{ +namespace scene +{ + + struct SMesh; + + //! An interface for easy manipulation of meshes. + /** Scale, set alpha value, flip surfaces, and so on. This exists for + fixing problems with wrong imported or exported meshes quickly after + loading. It is not intended for doing mesh modifications and/or + animations during runtime. + */ + class IMeshManipulator : public virtual IReferenceCounted + { + public: + + //! Flips the direction of surfaces. + /** Changes backfacing triangles to frontfacing + triangles and vice versa. + \param mesh Mesh on which the operation is performed. */ + virtual void flipSurfaces(IMesh* mesh) const = 0; + + //! Sets the alpha vertex color value of the whole mesh to a new value. + /** \param mesh Mesh on which the operation is performed. + \param alpha New alpha value. Must be a value between 0 and 255. */ + void setVertexColorAlpha(IMesh* mesh, s32 alpha) const + { + apply(scene::SVertexColorSetAlphaManipulator(alpha), mesh); + } + + //! Sets the alpha vertex color value of the whole mesh to a new value. + /** \param buffer Meshbuffer on which the operation is performed. + \param alpha New alpha value. Must be a value between 0 and 255. */ + void setVertexColorAlpha(IMeshBuffer* buffer, s32 alpha) const + { + apply(scene::SVertexColorSetAlphaManipulator(alpha), buffer); + } + + //! Sets the colors of all vertices to one color + /** \param mesh Mesh on which the operation is performed. + \param color New color. */ + void setVertexColors(IMesh* mesh, video::SColor color) const + { + apply(scene::SVertexColorSetManipulator(color), mesh); + } + + //! Sets the colors of all vertices to one color + /** \param buffer Meshbuffer on which the operation is performed. + \param color New color. */ + void setVertexColors(IMeshBuffer* buffer, video::SColor color) const + { + apply(scene::SVertexColorSetManipulator(color), buffer); + } + + //! Recalculates all normals of the mesh. + /** \param mesh: Mesh on which the operation is performed. + \param smooth: If the normals shall be smoothed. + \param angleWeighted: If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. */ + virtual void recalculateNormals(IMesh* mesh, bool smooth = false, + bool angleWeighted = false) const=0; + + //! Recalculates all normals of the mesh buffer. + /** \param buffer: Mesh buffer on which the operation is performed. + \param smooth: If the normals shall be smoothed. + \param angleWeighted: If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. */ + virtual void recalculateNormals(IMeshBuffer* buffer, + bool smooth = false, bool angleWeighted = false) const=0; + + //! Recalculates tangents, requires a tangent mesh + /** \param mesh Mesh on which the operation is performed. + \param recalculateNormals If the normals shall be recalculated, otherwise original normals of the mesh are used unchanged. + \param smooth If the normals shall be smoothed. + \param angleWeighted If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. + */ + virtual void recalculateTangents(IMesh* mesh, + bool recalculateNormals=false, bool smooth=false, + bool angleWeighted=false) const=0; + + //! Recalculates tangents, requires a tangent mesh buffer + /** \param buffer Meshbuffer on which the operation is performed. + \param recalculateNormals If the normals shall be recalculated, otherwise original normals of the buffer are used unchanged. + \param smooth If the normals shall be smoothed. + \param angleWeighted If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. + */ + virtual void recalculateTangents(IMeshBuffer* buffer, + bool recalculateNormals=false, bool smooth=false, + bool angleWeighted=false) const=0; + + //! Scales the actual mesh, not a scene node. + /** \param mesh Mesh on which the operation is performed. + \param factor Scale factor for each axis. */ + void scale(IMesh* mesh, const core::vector3df& factor) const + { + apply(SVertexPositionScaleManipulator(factor), mesh, true); + } + + //! Scales the actual meshbuffer, not a scene node. + /** \param buffer Meshbuffer on which the operation is performed. + \param factor Scale factor for each axis. */ + void scale(IMeshBuffer* buffer, const core::vector3df& factor) const + { + apply(SVertexPositionScaleManipulator(factor), buffer, true); + } + + //! Scales the actual mesh, not a scene node. + /** \deprecated Use scale() instead. This method may be removed by Irrlicht 1.9 + \param mesh Mesh on which the operation is performed. + \param factor Scale factor for each axis. */ + _IRR_DEPRECATED_ void scaleMesh(IMesh* mesh, const core::vector3df& factor) const {return scale(mesh,factor);} + + //! Scale the texture coords of a mesh. + /** \param mesh Mesh on which the operation is performed. + \param factor Vector which defines the scale for each axis. + \param level Number of texture coord, starting from 1. Support for level 2 exists for LightMap buffers. */ + void scaleTCoords(scene::IMesh* mesh, const core::vector2df& factor, u32 level=1) const + { + apply(SVertexTCoordsScaleManipulator(factor, level), mesh); + } + + //! Scale the texture coords of a meshbuffer. + /** \param buffer Meshbuffer on which the operation is performed. + \param factor Vector which defines the scale for each axis. + \param level Number of texture coord, starting from 1. Support for level 2 exists for LightMap buffers. */ + void scaleTCoords(scene::IMeshBuffer* buffer, const core::vector2df& factor, u32 level=1) const + { + apply(SVertexTCoordsScaleManipulator(factor, level), buffer); + } + + //! Applies a transformation to a mesh + /** \param mesh Mesh on which the operation is performed. + \param m transformation matrix. */ + void transform(IMesh* mesh, const core::matrix4& m) const + { + apply(SVertexPositionTransformManipulator(m), mesh, true); + } + + //! Applies a transformation to a meshbuffer + /** \param buffer Meshbuffer on which the operation is performed. + \param m transformation matrix. */ + void transform(IMeshBuffer* buffer, const core::matrix4& m) const + { + apply(SVertexPositionTransformManipulator(m), buffer, true); + } + + //! Applies a transformation to a mesh + /** \deprecated Use transform() instead. This method may be removed by Irrlicht 1.9 + \param mesh Mesh on which the operation is performed. + \param m transformation matrix. */ + _IRR_DEPRECATED_ virtual void transformMesh(IMesh* mesh, const core::matrix4& m) const {return transform(mesh,m);} + + //! Creates a planar texture mapping on the mesh + /** \param mesh: Mesh on which the operation is performed. + \param resolution: resolution of the planar mapping. This is + the value specifying which is the relation between world space + and texture coordinate space. */ + virtual void makePlanarTextureMapping(IMesh* mesh, f32 resolution=0.001f) const=0; + + //! Creates a planar texture mapping on the meshbuffer + /** \param meshbuffer: Buffer on which the operation is performed. + \param resolution: resolution of the planar mapping. This is + the value specifying which is the relation between world space + and texture coordinate space. */ + virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const=0; + + //! Creates a planar texture mapping on the buffer + /** This method is currently implemented towards the LWO planar mapping. A more general biasing might be required. + \param mesh Mesh on which the operation is performed. + \param resolutionS Resolution of the planar mapping in horizontal direction. This is the ratio between object space and texture space. + \param resolutionT Resolution of the planar mapping in vertical direction. This is the ratio between object space and texture space. + \param axis The axis along which the texture is projected. The allowed values are 0 (X), 1(Y), and 2(Z). + \param offset Vector added to the vertex positions (in object coordinates). + */ + virtual void makePlanarTextureMapping(scene::IMesh* mesh, + f32 resolutionS, f32 resolutionT, + u8 axis, const core::vector3df& offset) const=0; + + //! Creates a planar texture mapping on the meshbuffer + /** This method is currently implemented towards the LWO planar mapping. A more general biasing might be required. + \param buffer Buffer on which the operation is performed. + \param resolutionS Resolution of the planar mapping in horizontal direction. This is the ratio between object space and texture space. + \param resolutionT Resolution of the planar mapping in vertical direction. This is the ratio between object space and texture space. + \param axis The axis along which the texture is projected. The allowed values are 0 (X), 1(Y), and 2(Z). + \param offset Vector added to the vertex positions (in object coordinates). + */ + virtual void makePlanarTextureMapping(scene::IMeshBuffer* buffer, + f32 resolutionS, f32 resolutionT, + u8 axis, const core::vector3df& offset) const=0; + + //! Clones a static IMesh into a modifiable SMesh. + /** All meshbuffers in the returned SMesh + are of type SMeshBuffer or SMeshBufferLightMap. + \param mesh Mesh to copy. + \return Cloned mesh. If you no longer need the + cloned mesh, you should call SMesh::drop(). See + IReferenceCounted::drop() for more information. */ + virtual SMesh* createMeshCopy(IMesh* mesh) const = 0; + + //! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices. + /** This is useful if you want to draw tangent space normal + mapped geometry because it calculates the tangent and binormal + data which is needed there. + \param mesh Input mesh + \param recalculateNormals The normals are recalculated if set, + otherwise the original ones are kept. Note that keeping the + normals may introduce inaccurate tangents if the normals are + very different to those calculated from the faces. + \param smooth The normals/tangents are smoothed across the + meshbuffer's faces if this flag is set. + \param angleWeighted Improved smoothing calculation used + \param recalculateTangents Whether are actually calculated, or just the mesh with proper type is created. + \return Mesh consisting only of S3DVertexTangents vertices. If + you no longer need the cloned mesh, you should call + IMesh::drop(). See IReferenceCounted::drop() for more + information. */ + virtual IMesh* createMeshWithTangents(IMesh* mesh, + bool recalculateNormals=false, bool smooth=false, + bool angleWeighted=false, bool recalculateTangents=true) const=0; + + //! Creates a copy of the mesh, which will only consist of S3DVertex2TCoord vertices. + /** \param mesh Input mesh + \return Mesh consisting only of S3DVertex2TCoord vertices. If + you no longer need the cloned mesh, you should call + IMesh::drop(). See IReferenceCounted::drop() for more + information. */ + virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const = 0; + + //! Creates a copy of the mesh, which will only consist of S3DVertex vertices. + /** \param mesh Input mesh + \return Mesh consisting only of S3DVertex vertices. If + you no longer need the cloned mesh, you should call + IMesh::drop(). See IReferenceCounted::drop() for more + information. */ + virtual IMesh* createMeshWith1TCoords(IMesh* mesh) const = 0; + + //! Creates a copy of a mesh with all vertices unwelded + /** \param mesh Input mesh + \return Mesh consisting only of unique faces. All vertices + which were previously shared are now duplicated. If you no + longer need the cloned mesh, you should call IMesh::drop(). See + IReferenceCounted::drop() for more information. */ + virtual IMesh* createMeshUniquePrimitives(IMesh* mesh) const = 0; + + //! Creates a copy of a mesh with vertices welded + /** \param mesh Input mesh + \param tolerance The threshold for vertex comparisons. + \return Mesh without redundant vertices. If you no longer need + the cloned mesh, you should call IMesh::drop(). See + IReferenceCounted::drop() for more information. */ + virtual IMesh* createMeshWelded(IMesh* mesh, f32 tolerance=core::ROUNDING_ERROR_f32) const = 0; + + //! Get amount of polygons in mesh. + /** \param mesh Input mesh + \return Number of polygons in mesh. */ + virtual s32 getPolyCount(IMesh* mesh) const = 0; + + //! Get amount of polygons in mesh. + /** \param mesh Input mesh + \return Number of polygons in mesh. */ + virtual s32 getPolyCount(IAnimatedMesh* mesh) const = 0; + + //! Create a new AnimatedMesh and adds the mesh to it + /** \param mesh Input mesh + \param type The type of the animated mesh to create. + \return Newly created animated mesh with mesh as its only + content. When you don't need the animated mesh anymore, you + should call IAnimatedMesh::drop(). See + IReferenceCounted::drop() for more information. */ + virtual IAnimatedMesh * createAnimatedMesh(IMesh* mesh, + scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) const = 0; + + //! Vertex cache optimization according to the Forsyth paper + /** More information can be found at + http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html + + The function is thread-safe (read: you can optimize several + meshes in different threads). + + \param mesh Source mesh for the operation. + \return A new mesh optimized for the vertex cache. */ + virtual IMesh* createForsythOptimizedMesh(const IMesh *mesh) const = 0; + + //! Apply a manipulator on the Meshbuffer + /** \param func A functor defining the mesh manipulation. + \param buffer The Meshbuffer to apply the manipulator to. + \param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation. + \return True if the functor was successfully applied, else false. */ + template <typename Functor> + bool apply(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate=false) const + { + return apply_(func, buffer, boundingBoxUpdate, func); + } + + + //! Apply a manipulator on the Mesh + /** \param func A functor defining the mesh manipulation. + \param mesh The Mesh to apply the manipulator to. + \param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation. + \return True if the functor was successfully applied, else false. */ + template <typename Functor> + bool apply(const Functor& func, IMesh* mesh, bool boundingBoxUpdate=false) const + { + if (!mesh) + return true; + bool result = true; + core::aabbox3df bufferbox; + for (u32 i=0; i<mesh->getMeshBufferCount(); ++i) + { + result &= apply(func, mesh->getMeshBuffer(i), boundingBoxUpdate); + if (boundingBoxUpdate) + { + if (0==i) + bufferbox.reset(mesh->getMeshBuffer(i)->getBoundingBox()); + else + bufferbox.addInternalBox(mesh->getMeshBuffer(i)->getBoundingBox()); + } + } + if (boundingBoxUpdate) + mesh->setBoundingBox(bufferbox); + return result; + } + +protected: + //! Apply a manipulator based on the type of the functor + /** \param func A functor defining the mesh manipulation. + \param buffer The Meshbuffer to apply the manipulator to. + \param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation. + \param typeTest Unused parameter, which handles the proper call selection based on the type of the Functor which is passed in two times. + \return True if the functor was successfully applied, else false. */ + template <typename Functor> + bool apply_(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate, const IVertexManipulator& typeTest) const + { + if (!buffer) + return true; + + core::aabbox3df bufferbox; + for (u32 i=0; i<buffer->getVertexCount(); ++i) + { + switch (buffer->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* verts = (video::S3DVertex*)buffer->getVertices(); + func(verts[i]); + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* verts = (video::S3DVertex2TCoords*)buffer->getVertices(); + func(verts[i]); + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* verts = (video::S3DVertexTangents*)buffer->getVertices(); + func(verts[i]); + } + break; + } + if (boundingBoxUpdate) + { + if (0==i) + bufferbox.reset(buffer->getPosition(0)); + else + bufferbox.addInternalPoint(buffer->getPosition(i)); + } + } + if (boundingBoxUpdate) + buffer->setBoundingBox(bufferbox); + return true; + } +}; + +} // end namespace scene +} // end namespace irr + + +#endif diff --git a/builddir/irrlicht-1.8.1/include/IMeshSceneNode.h b/builddir/irrlicht-1.8.1/include/IMeshSceneNode.h new file mode 100644 index 0000000..4541069 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IMeshSceneNode.h @@ -0,0 +1,79 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_SCENE_NODE_H_INCLUDED__ +#define __I_MESH_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + +class IShadowVolumeSceneNode; +class IMesh; + + +//! A scene node displaying a static mesh +class IMeshSceneNode : public ISceneNode +{ +public: + + //! Constructor + /** Use setMesh() to set the mesh to display. + */ + IMeshSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1,1,1)) + : ISceneNode(parent, mgr, id, position, rotation, scale) {} + + //! Sets a new mesh to display + /** \param mesh Mesh to display. */ + virtual void setMesh(IMesh* mesh) = 0; + + //! Get the currently defined mesh for display. + /** \return Pointer to mesh which is displayed by this node. */ + virtual IMesh* getMesh(void) = 0; + + //! Creates shadow volume scene node as child of this node. + /** The shadow can be rendered using the ZPass or the zfail + method. ZPass is a little bit faster because the shadow volume + creation is easier, but with this method there occur ugly + looking artifacs when the camera is inside the shadow volume. + These error do not occur with the ZFail method. + \param shadowMesh: Optional custom mesh for shadow volume. + \param id: Id of the shadow scene node. This id can be used to + identify the node later. + \param zfailmethod: If set to true, the shadow will use the + zfail method, if not, zpass is used. + \param infinity: Value used by the shadow volume algorithm to + scale the shadow volume (for zfail shadow volume we support only + finite shadows, so camera zfar must be larger than shadow back cap, + which is depend on infinity parameter). + \return Pointer to the created shadow scene node. This pointer + should not be dropped. See IReferenceCounted::drop() for more + information. */ + virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh=0, + s32 id=-1, bool zfailmethod=true, f32 infinity=1000.0f) = 0; + + //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. + /** In this way it is possible to change the materials of a mesh + causing all mesh scene nodes referencing this mesh to change, too. + \param readonly Flag if the materials shall be read-only. */ + virtual void setReadOnlyMaterials(bool readonly) = 0; + + //! Check if the scene node should not copy the materials of the mesh but use them in a read only style + /** This flag can be set by setReadOnlyMaterials(). + \return Whether the materials are read-only. */ + virtual bool isReadOnlyMaterials() const = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IMeshWriter.h b/builddir/irrlicht-1.8.1/include/IMeshWriter.h new file mode 100644 index 0000000..aef3e28 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IMeshWriter.h @@ -0,0 +1,58 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_I_MESH_WRITER_H_INCLUDED__ +#define __IRR_I_MESH_WRITER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "EMeshWriterEnums.h" + +namespace irr +{ +namespace io +{ + class IWriteFile; +} // end namespace io + +namespace scene +{ + class IMesh; + + //! Interface for writing meshes + class IMeshWriter : public virtual IReferenceCounted + { + public: + + //! Destructor + virtual ~IMeshWriter() {} + + //! Get the type of the mesh writer + /** For own implementations, use MAKE_IRR_ID as shown in the + EMESH_WRITER_TYPE enumeration to return your own unique mesh + type id. + \return Type of the mesh writer. */ + virtual EMESH_WRITER_TYPE getType() const = 0; + + //! Write a static mesh. + /** \param file File handle to write the mesh to. + \param mesh Pointer to mesh to be written. + \param flags Optional flags to set properties of the writer. + \return True if sucessful */ + virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, + s32 flags=EMWF_NONE) = 0; + + // Writes an animated mesh + // for future use, no writer is able to write animated meshes currently + /* \return Returns true if sucessful */ + //virtual bool writeAnimatedMesh(io::IWriteFile* file, + // scene::IAnimatedMesh* mesh, + // s32 flags=EMWF_NONE) = 0; + }; + + +} // end namespace +} // end namespace + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IMetaTriangleSelector.h b/builddir/irrlicht-1.8.1/include/IMetaTriangleSelector.h new file mode 100644 index 0000000..366893a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IMetaTriangleSelector.h @@ -0,0 +1,43 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_META_TRIANGLE_SELECTOR_H_INCLUDED__ +#define __I_META_TRIANGLE_SELECTOR_H_INCLUDED__ + +#include "ITriangleSelector.h" + +namespace irr +{ +namespace scene +{ + +//! Interface for making multiple triangle selectors work as one big selector. +/** This is nothing more than a collection of one or more triangle selectors +providing together the interface of one triangle selector. In this way, +collision tests can be done with different triangle soups in one pass. +*/ +class IMetaTriangleSelector : public ITriangleSelector +{ +public: + + //! Adds a triangle selector to the collection of triangle selectors. + /** \param toAdd: Pointer to an triangle selector to add to the list. */ + virtual void addTriangleSelector(ITriangleSelector* toAdd) = 0; + + //! Removes a specific triangle selector from the collection. + /** \param toRemove: Pointer to an triangle selector which is in the + list but will be removed. + \return True if successful, false if not. */ + virtual bool removeTriangleSelector(ITriangleSelector* toRemove) = 0; + + //! Removes all triangle selectors from the collection. + virtual void removeAllTriangleSelectors() = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IOSOperator.h b/builddir/irrlicht-1.8.1/include/IOSOperator.h new file mode 100644 index 0000000..b5c6236 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IOSOperator.h @@ -0,0 +1,50 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_OS_OPERATOR_H_INCLUDED__ +#define __I_OS_OPERATOR_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrString.h" + +namespace irr +{ + +//! The Operating system operator provides operation system specific methods and informations. +class IOSOperator : public virtual IReferenceCounted +{ +public: + //! Get the current operation system version as string. + virtual const core::stringc& getOperatingSystemVersion() const = 0; + + //! Get the current operation system version as string. + /** \deprecated Use getOperatingSystemVersion instead. This method will be removed in Irrlicht 1.9. */ + _IRR_DEPRECATED_ const wchar_t* getOperationSystemVersion() const + { + return core::stringw(getOperatingSystemVersion()).c_str(); + } + + //! Copies text to the clipboard + virtual void copyToClipboard(const c8* text) const = 0; + + //! Get text from the clipboard + /** \return Returns 0 if no string is in there. */ + virtual const c8* getTextFromClipboard() const = 0; + + //! Get the processor speed in megahertz + /** \param MHz The integer variable to store the speed in. + \return True if successful, false if not */ + virtual bool getProcessorSpeedMHz(u32* MHz) const = 0; + + //! Get the total and available system RAM + /** \param Total: will contain the total system memory + \param Avail: will contain the available memory + \return True if successful, false if not */ + virtual bool getSystemMemory(u32* Total, u32* Avail) const = 0; + +}; + +} // end namespace + +#endif diff --git a/builddir/irrlicht-1.8.1/include/IParticleAffector.h b/builddir/irrlicht-1.8.1/include/IParticleAffector.h new file mode 100644 index 0000000..f5a18c6 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleAffector.h @@ -0,0 +1,72 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_AFFECTOR_H_INCLUDED__ +#define __I_PARTICLE_AFFECTOR_H_INCLUDED__ + +#include "IAttributeExchangingObject.h" +#include "SParticle.h" + +namespace irr +{ +namespace scene +{ + +//! Types of built in particle affectors +enum E_PARTICLE_AFFECTOR_TYPE +{ + EPAT_NONE = 0, + EPAT_ATTRACT, + EPAT_FADE_OUT, + EPAT_GRAVITY, + EPAT_ROTATE, + EPAT_SCALE, + EPAT_COUNT +}; + +//! Names for built in particle affectors +const c8* const ParticleAffectorTypeNames[] = +{ + "None", + "Attract", + "FadeOut", + "Gravity", + "Rotate", + "Scale", + 0 +}; + +//! A particle affector modifies particles. +class IParticleAffector : public virtual io::IAttributeExchangingObject +{ +public: + + //! constructor + IParticleAffector() : Enabled(true) {} + + //! Affects an array of particles. + /** \param now Current time. (Same as ITimer::getTime() would return) + \param particlearray Array of particles. + \param count Amount of particles in array. */ + virtual void affect(u32 now, SParticle* particlearray, u32 count) = 0; + + //! Sets whether or not the affector is currently enabled. + virtual void setEnabled(bool enabled) { Enabled = enabled; } + + //! Gets whether or not the affector is currently enabled. + virtual bool getEnabled() const { return Enabled; } + + //! Get emitter type + virtual E_PARTICLE_AFFECTOR_TYPE getType() const = 0; + +protected: + bool Enabled; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IParticleAnimatedMeshSceneNodeEmitter.h b/builddir/irrlicht-1.8.1/include/IParticleAnimatedMeshSceneNodeEmitter.h new file mode 100644 index 0000000..b64d1d6 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleAnimatedMeshSceneNodeEmitter.h @@ -0,0 +1,54 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" +#include "IAnimatedMeshSceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits particles from mesh vertices. +class IParticleAnimatedMeshSceneNodeEmitter : public IParticleEmitter +{ +public: + + //! Set Mesh to emit particles from + virtual void setAnimatedMeshSceneNode( IAnimatedMeshSceneNode* node ) = 0; + + //! Set whether to use vertex normal for direction, or direction specified + virtual void setUseNormalDirection( bool useNormalDirection = true ) = 0; + + //! Set the amount that the normal is divided by for getting a particles direction + virtual void setNormalDirectionModifier( f32 normalDirectionModifier ) = 0; + + //! Sets whether to emit min<->max particles for every vertex or to pick min<->max vertices + virtual void setEveryMeshVertex( bool everyMeshVertex = true ) = 0; + + //! Get mesh we're emitting particles from + virtual const IAnimatedMeshSceneNode* getAnimatedMeshSceneNode() const = 0; + + //! Get whether to use vertex normal for direction, or direction specified + virtual bool isUsingNormalDirection() const = 0; + + //! Get the amount that the normal is divided by for getting a particles direction + virtual f32 getNormalDirectionModifier() const = 0; + + //! Gets whether to emit min<->max particles for every vertex or to pick min<->max vertices + virtual bool getEveryMeshVertex() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_ANIMATED_MESH; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/IParticleAttractionAffector.h b/builddir/irrlicht-1.8.1/include/IParticleAttractionAffector.h new file mode 100644 index 0000000..7e874e8 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleAttractionAffector.h @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_ATTRACTION_AFFECTOR_H_INCLUDED__ +#define __I_PARTICLE_ATTRACTION_AFFECTOR_H_INCLUDED__ + +#include "IParticleAffector.h" + +namespace irr +{ +namespace scene +{ + +//! A particle affector which attracts or detracts particles. +class IParticleAttractionAffector : public IParticleAffector +{ +public: + + //! Set the point that particles will attract to + virtual void setPoint( const core::vector3df& point ) = 0; + + //! Set whether or not the particles are attracting or detracting + virtual void setAttract( bool attract ) = 0; + + //! Set whether or not this will affect particles in the X direction + virtual void setAffectX( bool affect ) = 0; + + //! Set whether or not this will affect particles in the Y direction + virtual void setAffectY( bool affect ) = 0; + + //! Set whether or not this will affect particles in the Z direction + virtual void setAffectZ( bool affect ) = 0; + + //! Get the point that particles are attracted to + virtual const core::vector3df& getPoint() const = 0; + + //! Get whether or not the particles are attracting or detracting + virtual bool getAttract() const = 0; + + //! Get whether or not the particles X position are affected + virtual bool getAffectX() const = 0; + + //! Get whether or not the particles Y position are affected + virtual bool getAffectY() const = 0; + + //! Get whether or not the particles Z position are affected + virtual bool getAffectZ() const = 0; + + //! Get emitter type + virtual E_PARTICLE_AFFECTOR_TYPE getType() const { return EPAT_ATTRACT; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_PARTICLE_ATTRACTION_AFFECTOR_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/IParticleBoxEmitter.h b/builddir/irrlicht-1.8.1/include/IParticleBoxEmitter.h new file mode 100644 index 0000000..9ea388a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleBoxEmitter.h @@ -0,0 +1,36 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_BOX_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_BOX_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" +#include "aabbox3d.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits particles from a box shaped space +class IParticleBoxEmitter : public IParticleEmitter +{ +public: + + //! Set the box shape + virtual void setBox( const core::aabbox3df& box ) = 0; + + //! Get the box shape set + virtual const core::aabbox3df& getBox() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_BOX; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IParticleCylinderEmitter.h b/builddir/irrlicht-1.8.1/include/IParticleCylinderEmitter.h new file mode 100644 index 0000000..cd063b8 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleCylinderEmitter.h @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_CYLINDER_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_CYLINDER_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits from a cylindrically shaped space. +class IParticleCylinderEmitter : public IParticleEmitter +{ +public: + + //! Set the center of the radius for the cylinder, at one end of the cylinder + virtual void setCenter( const core::vector3df& center ) = 0; + + //! Set the normal of the cylinder + virtual void setNormal( const core::vector3df& normal ) = 0; + + //! Set the radius of the cylinder + virtual void setRadius( f32 radius ) = 0; + + //! Set the length of the cylinder + virtual void setLength( f32 length ) = 0; + + //! Set whether or not to draw points inside the cylinder + virtual void setOutlineOnly( bool outlineOnly = true ) = 0; + + //! Get the center of the cylinder + virtual const core::vector3df& getCenter() const = 0; + + //! Get the normal of the cylinder + virtual const core::vector3df& getNormal() const = 0; + + //! Get the radius of the cylinder + virtual f32 getRadius() const = 0; + + //! Get the center of the cylinder + virtual f32 getLength() const = 0; + + //! Get whether or not to draw points inside the cylinder + virtual bool getOutlineOnly() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_CYLINDER; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IParticleEmitter.h b/builddir/irrlicht-1.8.1/include/IParticleEmitter.h new file mode 100644 index 0000000..6fc9a2c --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleEmitter.h @@ -0,0 +1,129 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_EMITTER_H_INCLUDED__ + +#include "IAttributeExchangingObject.h" +#include "SParticle.h" + +namespace irr +{ +namespace scene +{ + +//! Types of built in particle emitters +enum E_PARTICLE_EMITTER_TYPE +{ + EPET_POINT = 0, + EPET_ANIMATED_MESH, + EPET_BOX, + EPET_CYLINDER, + EPET_MESH, + EPET_RING, + EPET_SPHERE, + EPET_COUNT +}; + +//! Names for built in particle emitters +const c8* const ParticleEmitterTypeNames[] = +{ + "Point", + "AnimatedMesh", + "Box", + "Cylinder", + "Mesh", + "Ring", + "Sphere", + 0 +}; + +//! A particle emitter for using with particle systems. +/** A Particle emitter emitts new particles into a particle system. +*/ +class IParticleEmitter : public virtual io::IAttributeExchangingObject +{ +public: + + //! Prepares an array with new particles to emitt into the system + /** \param now Current time. + \param timeSinceLastCall Time elapsed since last call, in milliseconds. + \param outArray Pointer which will point to the array with the new + particles to add into the system. + \return Amount of new particles in the array. Can be 0. */ + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) = 0; + + //! Set direction the emitter emits particles + virtual void setDirection( const core::vector3df& newDirection ) = 0; + + //! Set minimum number of particles the emitter emits per second + virtual void setMinParticlesPerSecond( u32 minPPS ) = 0; + + //! Set maximum number of particles the emitter emits per second + virtual void setMaxParticlesPerSecond( u32 maxPPS ) = 0; + + //! Set minimum starting color for particles + virtual void setMinStartColor( const video::SColor& color ) = 0; + + //! Set maximum starting color for particles + virtual void setMaxStartColor( const video::SColor& color ) = 0; + + //! Set the maximum starting size for particles + virtual void setMaxStartSize( const core::dimension2df& size ) = 0; + + //! Set the minimum starting size for particles + virtual void setMinStartSize( const core::dimension2df& size ) = 0; + + //! Set the minimum particle life-time in milliseconds + virtual void setMinLifeTime( u32 lifeTimeMin ) = 0; + + //! Set the maximum particle life-time in milliseconds + virtual void setMaxLifeTime( u32 lifeTimeMax ) = 0; + + //! Set maximal random derivation from the direction + virtual void setMaxAngleDegrees( s32 maxAngleDegrees ) = 0; + + //! Get direction the emitter emits particles + virtual const core::vector3df& getDirection() const = 0; + + //! Get the minimum number of particles the emitter emits per second + virtual u32 getMinParticlesPerSecond() const = 0; + + //! Get the maximum number of particles the emitter emits per second + virtual u32 getMaxParticlesPerSecond() const = 0; + + //! Get the minimum starting color for particles + virtual const video::SColor& getMinStartColor() const = 0; + + //! Get the maximum starting color for particles + virtual const video::SColor& getMaxStartColor() const = 0; + + //! Get the maximum starting size for particles + virtual const core::dimension2df& getMaxStartSize() const = 0; + + //! Get the minimum starting size for particles + virtual const core::dimension2df& getMinStartSize() const = 0; + + //! Get the minimum particle life-time in milliseconds + virtual u32 getMinLifeTime() const = 0; + + //! Get the maximum particle life-time in milliseconds + virtual u32 getMaxLifeTime() const = 0; + + //! Get maximal random derivation from the direction + virtual s32 getMaxAngleDegrees() const = 0; + + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_POINT; } +}; + +typedef IParticleEmitter IParticlePointEmitter; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IParticleFadeOutAffector.h b/builddir/irrlicht-1.8.1/include/IParticleFadeOutAffector.h new file mode 100644 index 0000000..c3ce78b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleFadeOutAffector.h @@ -0,0 +1,41 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_FADE_OUT_AFFECTOR_H_INCLUDED__ +#define __I_PARTICLE_FADE_OUT_AFFECTOR_H_INCLUDED__ + +#include "IParticleAffector.h" + +namespace irr +{ +namespace scene +{ + +//! A particle affector which fades out the particles. +class IParticleFadeOutAffector : public IParticleAffector +{ +public: + + //! Sets the targetColor, i.e. the color the particles will interpolate to over time. + virtual void setTargetColor( const video::SColor& targetColor ) = 0; + + //! Sets the time in milliseconds it takes for each particle to fade out (minimal 1 ms) + virtual void setFadeOutTime( u32 fadeOutTime ) = 0; + + //! Gets the targetColor, i.e. the color the particles will interpolate to over time. + virtual const video::SColor& getTargetColor() const = 0; + + //! Gets the time in milliseconds it takes for each particle to fade out. + virtual u32 getFadeOutTime() const = 0; + + //! Get emitter type + virtual E_PARTICLE_AFFECTOR_TYPE getType() const { return EPAT_FADE_OUT; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_PARTICLE_FADE_OUT_AFFECTOR_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/IParticleGravityAffector.h b/builddir/irrlicht-1.8.1/include/IParticleGravityAffector.h new file mode 100644 index 0000000..f0e4f8e --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleGravityAffector.h @@ -0,0 +1,42 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_GRAVITY_AFFECTOR_H_INCLUDED__ +#define __I_PARTICLE_GRAVITY_AFFECTOR_H_INCLUDED__ + +#include "IParticleAffector.h" + +namespace irr +{ +namespace scene +{ + +//! A particle affector which applies gravity to particles. +class IParticleGravityAffector : public IParticleAffector +{ +public: + + //! Set the time in milliseconds when the gravity force is totally lost + /** At that point the particle does not move any more. */ + virtual void setTimeForceLost( f32 timeForceLost ) = 0; + + //! Set the direction and force of gravity in all 3 dimensions. + virtual void setGravity( const core::vector3df& gravity ) = 0; + + //! Get the time in milliseconds when the gravity force is totally lost + virtual f32 getTimeForceLost() const = 0; + + //! Get the direction and force of gravity. + virtual const core::vector3df& getGravity() const = 0; + + //! Get emitter type + virtual E_PARTICLE_AFFECTOR_TYPE getType() const { return EPAT_GRAVITY; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_PARTICLE_GRAVITY_AFFECTOR_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/IParticleMeshEmitter.h b/builddir/irrlicht-1.8.1/include/IParticleMeshEmitter.h new file mode 100644 index 0000000..4d066a1 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleMeshEmitter.h @@ -0,0 +1,54 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_MESH_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_MESH_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" +#include "IMesh.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits from vertices of a mesh +class IParticleMeshEmitter : public IParticleEmitter +{ +public: + + //! Set Mesh to emit particles from + virtual void setMesh( IMesh* mesh ) = 0; + + //! Set whether to use vertex normal for direction, or direction specified + virtual void setUseNormalDirection( bool useNormalDirection = true ) = 0; + + //! Set the amount that the normal is divided by for getting a particles direction + virtual void setNormalDirectionModifier( f32 normalDirectionModifier ) = 0; + + //! Sets whether to emit min<->max particles for every vertex or to pick min<->max vertices + virtual void setEveryMeshVertex( bool everyMeshVertex = true ) = 0; + + //! Get Mesh we're emitting particles from + virtual const IMesh* getMesh() const = 0; + + //! Get whether to use vertex normal for direction, or direction specified + virtual bool isUsingNormalDirection() const = 0; + + //! Get the amount that the normal is divided by for getting a particles direction + virtual f32 getNormalDirectionModifier() const = 0; + + //! Gets whether to emit min<->max particles for every vertex or to pick min<->max vertices + virtual bool getEveryMeshVertex() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_MESH; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IParticleRingEmitter.h b/builddir/irrlicht-1.8.1/include/IParticleRingEmitter.h new file mode 100644 index 0000000..4330092 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleRingEmitter.h @@ -0,0 +1,47 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_RING_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_RING_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits particles along a ring shaped area. +class IParticleRingEmitter : public IParticleEmitter +{ +public: + + //! Set the center of the ring + virtual void setCenter( const core::vector3df& center ) = 0; + + //! Set the radius of the ring + virtual void setRadius( f32 radius ) = 0; + + //! Set the thickness of the ring + virtual void setRingThickness( f32 ringThickness ) = 0; + + //! Get the center of the ring + virtual const core::vector3df& getCenter() const = 0; + + //! Get the radius of the ring + virtual f32 getRadius() const = 0; + + //! Get the thickness of the ring + virtual f32 getRingThickness() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_RING; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IParticleRotationAffector.h b/builddir/irrlicht-1.8.1/include/IParticleRotationAffector.h new file mode 100644 index 0000000..611fc3b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleRotationAffector.h @@ -0,0 +1,41 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_ROTATION_AFFECTOR_H_INCLUDED__ +#define __I_PARTICLE_ROTATION_AFFECTOR_H_INCLUDED__ + +#include "IParticleAffector.h" + +namespace irr +{ +namespace scene +{ + +//! A particle affector which rotates the particle system. +class IParticleRotationAffector : public IParticleAffector +{ +public: + + //! Set the point that particles will rotate around + virtual void setPivotPoint( const core::vector3df& point ) = 0; + + //! Set the speed in degrees per second in all 3 dimensions + virtual void setSpeed( const core::vector3df& speed ) = 0; + + //! Get the point that particles are attracted to + virtual const core::vector3df& getPivotPoint() const = 0; + + //! Get the speed in degrees per second in all 3 dimensions + virtual const core::vector3df& getSpeed() const = 0; + + //! Get emitter type + virtual E_PARTICLE_AFFECTOR_TYPE getType() const { return EPAT_ROTATE; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_PARTICLE_ROTATION_AFFECTOR_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/IParticleSphereEmitter.h b/builddir/irrlicht-1.8.1/include/IParticleSphereEmitter.h new file mode 100644 index 0000000..edde2da --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleSphereEmitter.h @@ -0,0 +1,41 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_SPHERE_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_SPHERE_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits from a spherical space. +class IParticleSphereEmitter : public IParticleEmitter +{ +public: + + //! Set the center of the sphere for particle emissions + virtual void setCenter( const core::vector3df& center ) = 0; + + //! Set the radius of the sphere for particle emissions + virtual void setRadius( f32 radius ) = 0; + + //! Get the center of the sphere for particle emissions + virtual const core::vector3df& getCenter() const = 0; + + //! Get the radius of the sphere for particle emissions + virtual f32 getRadius() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_SPHERE; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IParticleSystemSceneNode.h b/builddir/irrlicht-1.8.1/include/IParticleSystemSceneNode.h new file mode 100644 index 0000000..56a47c8 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IParticleSystemSceneNode.h @@ -0,0 +1,512 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_SYSTEM_SCENE_NODE_H_INCLUDED__ +#define __I_PARTICLE_SYSTEM_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "IParticleAnimatedMeshSceneNodeEmitter.h" +#include "IParticleBoxEmitter.h" +#include "IParticleCylinderEmitter.h" +#include "IParticleMeshEmitter.h" +#include "IParticleRingEmitter.h" +#include "IParticleSphereEmitter.h" +#include "IParticleAttractionAffector.h" +#include "IParticleFadeOutAffector.h" +#include "IParticleGravityAffector.h" +#include "IParticleRotationAffector.h" +#include "dimension2d.h" + +namespace irr +{ +namespace scene +{ + +//! A particle system scene node for creating snow, fire, exlosions, smoke... +/** A scene node controlling a particle System. The behavior of the particles +can be controlled by setting the right particle emitters and affectors. +You can for example easily create a campfire by doing this: + +\code + scene::IParticleSystemSceneNode* p = scenemgr->addParticleSystemSceneNode(); + p->setParticleSize(core::dimension2d<f32>(20.0f, 10.0f)); + scene::IParticleEmitter* em = p->createBoxEmitter( + core::aabbox3d<f32>(-5,0,-5,5,1,5), + core::vector3df(0.0f,0.03f,0.0f), + 40,80, video::SColor(0,255,255,255),video::SColor(0,255,255,255), 1100,2000); + p->setEmitter(em); + em->drop(); + scene::IParticleAffector* paf = p->createFadeOutParticleAffector(); + p->addAffector(paf); + paf->drop(); +\endcode + +*/ +class IParticleSystemSceneNode : public ISceneNode +{ +public: + + //! Constructor + IParticleSystemSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) + : ISceneNode(parent, mgr, id, position, rotation, scale) {} + + //! Sets the size of all particles. + virtual void setParticleSize( + const core::dimension2d<f32> &size = core::dimension2d<f32>(5.0f, 5.0f)) = 0; + + //! Sets if the particles should be global. + /** If they are, the particles are affected by the movement of the + particle system scene node too, otherwise they completely ignore it. + Default is true. */ + virtual void setParticlesAreGlobal(bool global=true) = 0; + + //! Remove all currently visible particles + virtual void clearParticles() = 0; + + //! Do manually update the particles. + //! This should only be called when you want to render the node outside the scenegraph, + //! as the node will care about this otherwise automatically. + virtual void doParticleSystem(u32 time) = 0; + + //! Gets the particle emitter, which creates the particles. + /** \return The particle emitter. Can be 0 if none is set. */ + virtual IParticleEmitter* getEmitter() =0; + + //! Sets the particle emitter, which creates the particles. + /** A particle emitter can be created using one of the createEmitter + methods. For example to create and use a simple PointEmitter, call + IParticleEmitter* p = createPointEmitter(); setEmitter(p); p->drop(); + \param emitter: Sets the particle emitter. You can set this to 0 for + removing the current emitter and stopping the particle system emitting + new particles. */ + virtual void setEmitter(IParticleEmitter* emitter) = 0; + + //! Adds new particle effector to the particle system. + /** A particle affector modifies the particles. For example, the FadeOut + affector lets all particles fade out after some time. It is created and + used in this way: + \code + IParticleAffector* p = createFadeOutParticleAffector(); + addAffector(p); + p->drop(); + \endcode + Please note that an affector is not necessary for the particle system to + work. + \param affector: New affector. */ + virtual void addAffector(IParticleAffector* affector) = 0; + + //! Get a list of all particle affectors. + /** \return The list of particle affectors attached to this node. */ + virtual const core::list<IParticleAffector*>& getAffectors() const = 0; + + //! Removes all particle affectors in the particle system. + virtual void removeAllAffectors() = 0; + + //! Creates a particle emitter for an animated mesh scene node + /** \param node: Pointer to the animated mesh scene node to emit + particles from + \param useNormalDirection: If true, the direction of each particle + created will be the normal of the vertex that it's emitting from. The + normal is divided by the normalDirectionModifier parameter, which + defaults to 100.0f. + \param direction: Direction and speed of particle emission. + \param normalDirectionModifier: If the emitter is using the normal + direction then the normal of the vertex that is being emitted from is + divided by this number. + \param mbNumber: This allows you to specify a specific meshBuffer for + the IMesh* to emit particles from. The default value is -1, which + means a random meshBuffer picked from all of the meshes meshBuffers + will be selected to pick a random vertex from. If the value is 0 or + greater, it will only pick random vertices from the meshBuffer + specified by this value. + \param everyMeshVertex: If true, the emitter will emit between min/max + particles every second, for every vertex in the mesh, if false, it will + emit between min/max particles from random vertices in the mesh. + \param minParticlesPerSecond: Minimal amount of particles emitted per + second. + \param maxParticlesPerSecond: Maximal amount of particles emitted per + second. + \param minStartColor: Minimal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param maxStartColor: Maximal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + \param maxAngleDegrees: Maximal angle in degrees, the emitting + direction of the particle will differ from the original direction. + \param minStartSize: Minimal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \param maxStartSize: Maximal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \return Pointer to the created particle emitter. To set this emitter + as new emitter of this particle system, just call setEmitter(). Note + that you'll have to drop() the returned pointer, after you don't need + it any more, see IReferenceCounted::drop() for more informations. */ + virtual IParticleAnimatedMeshSceneNodeEmitter* createAnimatedMeshSceneNodeEmitter( + scene::IAnimatedMeshSceneNode* node, bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + f32 normalDirectionModifier = 100.0f, s32 mbNumber = -1, + bool everyMeshVertex = false, + u32 minParticlesPerSecond = 5, u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ) = 0; + + //! Creates a box particle emitter. + /** \param box: The box for the emitter. + \param direction: Direction and speed of particle emission. + \param minParticlesPerSecond: Minimal amount of particles emitted per + second. + \param maxParticlesPerSecond: Maximal amount of particles emitted per + second. + \param minStartColor: Minimal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param maxStartColor: Maximal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + \param maxAngleDegrees: Maximal angle in degrees, the emitting + direction of the particle will differ from the original direction. + \param minStartSize: Minimal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \param maxStartSize: Maximal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \return Pointer to the created particle emitter. To set this emitter + as new emitter of this particle system, just call setEmitter(). Note + that you'll have to drop() the returned pointer, after you don't need + it any more, see IReferenceCounted::drop() for more informations. */ + virtual IParticleBoxEmitter* createBoxEmitter( + const core::aabbox3df& box = core::aabbox3df(-10,28,-10,10,30,10), + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ) = 0; + + //! Creates a particle emitter for emitting from a cylinder + /** \param center: The center of the circle at the base of the cylinder + \param radius: The thickness of the cylinder + \param normal: Direction of the length of the cylinder + \param length: The length of the the cylinder + \param outlineOnly: Whether or not to put points inside the cylinder or + on the outline only + \param direction: Direction and speed of particle emission. + \param minParticlesPerSecond: Minimal amount of particles emitted per + second. + \param maxParticlesPerSecond: Maximal amount of particles emitted per + second. + \param minStartColor: Minimal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param maxStartColor: Maximal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + \param maxAngleDegrees: Maximal angle in degrees, the emitting + direction of the particle will differ from the original direction. + \param minStartSize: Minimal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \param maxStartSize: Maximal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \return Pointer to the created particle emitter. To set this emitter + as new emitter of this particle system, just call setEmitter(). Note + that you'll have to drop() the returned pointer, after you don't need + it any more, see IReferenceCounted::drop() for more informations. */ + virtual IParticleCylinderEmitter* createCylinderEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& normal, f32 length, + bool outlineOnly = false, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ) = 0; + + //! Creates a mesh particle emitter. + /** \param mesh: Pointer to mesh to emit particles from + \param useNormalDirection: If true, the direction of each particle + created will be the normal of the vertex that it's emitting from. The + normal is divided by the normalDirectionModifier parameter, which + defaults to 100.0f. + \param direction: Direction and speed of particle emission. + \param normalDirectionModifier: If the emitter is using the normal + direction then the normal of the vertex that is being emitted from is + divided by this number. + \param mbNumber: This allows you to specify a specific meshBuffer for + the IMesh* to emit particles from. The default value is -1, which + means a random meshBuffer picked from all of the meshes meshBuffers + will be selected to pick a random vertex from. If the value is 0 or + greater, it will only pick random vertices from the meshBuffer + specified by this value. + \param everyMeshVertex: If true, the emitter will emit between min/max + particles every second, for every vertex in the mesh, if false, it will + emit between min/max particles from random vertices in the mesh. + \param minParticlesPerSecond: Minimal amount of particles emitted per + second. + \param maxParticlesPerSecond: Maximal amount of particles emitted per + second. + \param minStartColor: Minimal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param maxStartColor: Maximal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + \param maxAngleDegrees: Maximal angle in degrees, the emitting + direction of the particle will differ from the original direction. + \param minStartSize: Minimal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \param maxStartSize: Maximal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \return Pointer to the created particle emitter. To set this emitter + as new emitter of this particle system, just call setEmitter(). Note + that you'll have to drop() the returned pointer, after you don't need + it any more, see IReferenceCounted::drop() for more informations. */ + virtual IParticleMeshEmitter* createMeshEmitter( + scene::IMesh* mesh, bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + f32 normalDirectionModifier = 100.0f, s32 mbNumber = -1, + bool everyMeshVertex = false, + u32 minParticlesPerSecond = 5, u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ) = 0; + + //! Creates a point particle emitter. + /** \param direction: Direction and speed of particle emission. + \param minParticlesPerSecond: Minimal amount of particles emitted per + second. + \param maxParticlesPerSecond: Maximal amount of particles emitted per + second. + \param minStartColor: Minimal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param maxStartColor: Maximal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + \param maxAngleDegrees: Maximal angle in degrees, the emitting + direction of the particle will differ from the original direction. + \param minStartSize: Minimal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \param maxStartSize: Maximal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \return Pointer to the created particle emitter. To set this emitter + as new emitter of this particle system, just call setEmitter(). Note + that you'll have to drop() the returned pointer, after you don't need + it any more, see IReferenceCounted::drop() for more informations. */ + virtual IParticlePointEmitter* createPointEmitter( + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ) = 0; + + //! Creates a ring particle emitter. + /** \param center: Center of ring + \param radius: Distance of points from center, points will be rotated + around the Y axis at a random 360 degrees and will then be shifted by + the provided ringThickness values in each axis. + \param ringThickness : thickness of the ring or how wide the ring is + \param direction: Direction and speed of particle emission. + \param minParticlesPerSecond: Minimal amount of particles emitted per + second. + \param maxParticlesPerSecond: Maximal amount of particles emitted per + second. + \param minStartColor: Minimal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param maxStartColor: Maximal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + \param maxAngleDegrees: Maximal angle in degrees, the emitting + direction of the particle will differ from the original direction. + \param minStartSize: Minimal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \param maxStartSize: Maximal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \return Pointer to the created particle emitter. To set this emitter + as new emitter of this particle system, just call setEmitter(). Note + that you'll have to drop() the returned pointer, after you don't need + it any more, see IReferenceCounted::drop() for more informations. */ + virtual IParticleRingEmitter* createRingEmitter( + const core::vector3df& center, f32 radius, f32 ringThickness, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ) = 0; + + //! Creates a sphere particle emitter. + /** \param center: Center of sphere + \param radius: Radius of sphere + \param direction: Direction and speed of particle emission. + \param minParticlesPerSecond: Minimal amount of particles emitted per + second. + \param maxParticlesPerSecond: Maximal amount of particles emitted per + second. + \param minStartColor: Minimal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param maxStartColor: Maximal initial start color of a particle. The + real color of every particle is calculated as random interpolation + between minStartColor and maxStartColor. + \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + \param maxAngleDegrees: Maximal angle in degrees, the emitting + direction of the particle will differ from the original direction. + \param minStartSize: Minimal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \param maxStartSize: Maximal initial start size of a particle. The + real size of every particle is calculated as random interpolation + between minStartSize and maxStartSize. + \return Pointer to the created particle emitter. To set this emitter + as new emitter of this particle system, just call setEmitter(). Note + that you'll have to drop() the returned pointer, after you don't need + it any more, see IReferenceCounted::drop() for more informations. */ + virtual IParticleSphereEmitter* createSphereEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ) = 0; + + //! Creates a point attraction affector. + /** This affector modifies the positions of the particles and attracts + them to a specified point at a specified speed per second. + \param point: Point to attract particles to. + \param speed: Speed in units per second, to attract to the specified + point. + \param attract: Whether the particles attract or detract from this + point. + \param affectX: Whether or not this will affect the X position of the + particle. + \param affectY: Whether or not this will affect the Y position of the + particle. + \param affectZ: Whether or not this will affect the Z position of the + particle. + \return Pointer to the created particle affector. To add this affector + as new affector of this particle system, just call addAffector(). Note + that you'll have to drop() the returned pointer, after you don't need + it any more, see IReferenceCounted::drop() for more informations. */ + virtual IParticleAttractionAffector* createAttractionAffector( + const core::vector3df& point, f32 speed = 1.0f, bool attract = true, + bool affectX = true, bool affectY = true, bool affectZ = true) = 0; + + //! Creates a scale particle affector. + /** This affector scales the particle to the a multiple of its size defined + by the scaleTo variable. + \param scaleTo: multiple of the size which the particle will be scaled to until deletion + \return Pointer to the created particle affector. + To add this affector as new affector of this particle system, + just call addAffector(). Note that you'll have to drop() the + returned pointer, after you don't need it any more, see + IReferenceCounted::drop() for more information. */ + virtual IParticleAffector* createScaleParticleAffector(const core::dimension2df& scaleTo = core::dimension2df(1.0f, 1.0f)) = 0; + + //! Creates a fade out particle affector. + /** This affector modifies the color of every particle and and reaches + the final color when the particle dies. This affector looks really + good, if the EMT_TRANSPARENT_ADD_COLOR material is used and the + targetColor is video::SColor(0,0,0,0): Particles are fading out into + void with this setting. + \param targetColor: Color whereto the color of the particle is changed. + \param timeNeededToFadeOut: How much time in milli seconds should the + affector need to change the color to the targetColor. + \return Pointer to the created particle affector. To add this affector + as new affector of this particle system, just call addAffector(). Note + that you'll have to drop() the returned pointer, after you don't need + it any more, see IReferenceCounted::drop() for more informations. */ + virtual IParticleFadeOutAffector* createFadeOutParticleAffector( + const video::SColor& targetColor = video::SColor(0,0,0,0), + u32 timeNeededToFadeOut = 1000) = 0; + + //! Creates a gravity affector. + /** This affector modifies the direction of the particle. It assumes + that the particle is fired out of the emitter with huge force, but is + loosing this after some time and is catched by the gravity then. This + affector is ideal for creating things like fountains. + \param gravity: Direction and force of gravity. + \param timeForceLost: Time in milli seconds when the force of the + emitter is totally lost and the particle does not move any more. This + is the time where gravity fully affects the particle. + \return Pointer to the created particle affector. To add this affector + as new affector of this particle system, just call addAffector(). Note + that you'll have to drop() the returned pointer, after you don't need + it any more, see IReferenceCounted::drop() for more informations. */ + virtual IParticleGravityAffector* createGravityAffector( + const core::vector3df& gravity = core::vector3df(0.0f,-0.03f,0.0f), + u32 timeForceLost = 1000) = 0; + + //! Creates a rotation affector. + /** This affector modifies the positions of the particles and attracts + them to a specified point at a specified speed per second. + \param speed: Rotation in degrees per second + \param pivotPoint: Point to rotate the particles around + \return Pointer to the created particle affector. To add this affector + as new affector of this particle system, just call addAffector(). Note + that you'll have to drop() the returned pointer, after you don't need + it any more, see IReferenceCounted::drop() for more informations. */ + virtual IParticleRotationAffector* createRotationAffector( + const core::vector3df& speed = core::vector3df(5.0f,5.0f,5.0f), + const core::vector3df& pivotPoint = core::vector3df(0.0f,0.0f,0.0f) ) = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IQ3LevelMesh.h b/builddir/irrlicht-1.8.1/include/IQ3LevelMesh.h new file mode 100644 index 0000000..f8ff03f --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IQ3LevelMesh.h @@ -0,0 +1,46 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_Q3_LEVEL_MESH_H_INCLUDED__ +#define __I_Q3_LEVEL_MESH_H_INCLUDED__ + +#include "IAnimatedMesh.h" +#include "IQ3Shader.h" + +namespace irr +{ +namespace scene +{ + //! Interface for a Mesh which can be loaded directly from a Quake3 .bsp-file. + /** The Mesh tries to load all textures of the map.*/ + class IQ3LevelMesh : public IAnimatedMesh + { + public: + + //! loads the shader definition from file + /** \param filename Name of the shaderfile, defaults to /scripts if fileNameIsValid is false. + \param fileNameIsValid Specifies whether the filename is valid in the current situation. */ + virtual const quake3::IShader* getShader( const c8* filename, bool fileNameIsValid=true ) = 0; + + //! returns a already loaded Shader + virtual const quake3::IShader* getShader(u32 index) const = 0; + + //! get's an interface to the entities + virtual quake3::tQ3EntityList& getEntityList() = 0; + + //! returns the requested brush entity + /** \param num The number from the model key of the entity. + + Use this interface if you parse the entities yourself.*/ + virtual IMesh* getBrushEntityMesh(s32 num) const = 0; + + //! returns the requested brush entity + virtual IMesh* getBrushEntityMesh(quake3::IEntity &ent) const = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IQ3Shader.h b/builddir/irrlicht-1.8.1/include/IQ3Shader.h new file mode 100644 index 0000000..735fdf8 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IQ3Shader.h @@ -0,0 +1,885 @@ +// Copyright (C) 2006-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_Q3_LEVEL_SHADER_H_INCLUDED__ +#define __I_Q3_LEVEL_SHADER_H_INCLUDED__ + +#include "irrArray.h" +#include "fast_atof.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "coreutil.h" + +namespace irr +{ +namespace scene +{ +namespace quake3 +{ + + static core::stringc irrEmptyStringc(""); + + //! Hold the different Mesh Types used for getMesh + enum eQ3MeshIndex + { + E_Q3_MESH_GEOMETRY = 0, + E_Q3_MESH_ITEMS, + E_Q3_MESH_BILLBOARD, + E_Q3_MESH_FOG, + E_Q3_MESH_UNRESOLVED, + E_Q3_MESH_SIZE + }; + + /*! used to customize Quake3 BSP Loader + */ + + struct Q3LevelLoadParameter + { + Q3LevelLoadParameter () + :defaultLightMapMaterial ( video::EMT_LIGHTMAP_M4 ), + defaultModulate ( video::EMFN_MODULATE_4X ), + defaultFilter ( video::EMF_BILINEAR_FILTER ), + patchTesselation ( 8 ), + verbose ( 0 ), + startTime ( 0 ), endTime ( 0 ), + mergeShaderBuffer ( 1 ), + cleanUnResolvedMeshes ( 1 ), + loadAllShaders ( 0 ), + loadSkyShader ( 0 ), + alpharef ( 1 ), + swapLump ( 0 ), + #ifdef __BIG_ENDIAN__ + swapHeader ( 1 ) + #else + swapHeader ( 0 ) + #endif + { + memcpy ( scriptDir, "scripts\x0", 8 ); + } + + video::E_MATERIAL_TYPE defaultLightMapMaterial; + video::E_MODULATE_FUNC defaultModulate; + video::E_MATERIAL_FLAG defaultFilter; + s32 patchTesselation; + s32 verbose; + u32 startTime; + u32 endTime; + s32 mergeShaderBuffer; + s32 cleanUnResolvedMeshes; + s32 loadAllShaders; + s32 loadSkyShader; + s32 alpharef; + s32 swapLump; + s32 swapHeader; + c8 scriptDir [ 64 ]; + }; + + // some useful typedefs + typedef core::array< core::stringc > tStringList; + typedef core::array< video::ITexture* > tTexArray; + + // string helper.. TODO: move to generic files + inline s16 isEqual ( const core::stringc &string, u32 &pos, const c8 *list[], u16 listSize ) + { + const char * in = string.c_str () + pos; + + for ( u16 i = 0; i != listSize; ++i ) + { + if (string.size() < pos) + return -2; + u32 len = (u32) strlen ( list[i] ); + if (string.size() < pos+len) + continue; + if ( in [len] != 0 && in [len] != ' ' ) + continue; + if ( strncmp ( in, list[i], len ) ) + continue; + + pos += len + 1; + return (s16) i; + } + return -2; + } + + inline f32 getAsFloat ( const core::stringc &string, u32 &pos ) + { + const char * in = string.c_str () + pos; + + f32 value = 0.f; + pos += (u32) ( core::fast_atof_move ( in, value ) - in ) + 1; + return value; + } + + //! get a quake3 vector translated to irrlicht position (x,-z,y ) + inline core::vector3df getAsVector3df ( const core::stringc &string, u32 &pos ) + { + core::vector3df v; + + v.X = getAsFloat ( string, pos ); + v.Z = getAsFloat ( string, pos ); + v.Y = getAsFloat ( string, pos ); + + return v; + } + + + /* + extract substrings + */ + inline void getAsStringList ( tStringList &list, s32 max, const core::stringc &string, u32 &startPos ) + { + list.clear (); + + s32 finish = 0; + s32 endPos; + do + { + endPos = string.findNext ( ' ', startPos ); + if ( endPos == -1 ) + { + finish = 1; + endPos = string.size(); + } + + list.push_back ( string.subString ( startPos, endPos - startPos ) ); + startPos = endPos + 1; + + if ( list.size() >= (u32) max ) + finish = 1; + + } while ( !finish ); + + } + + //! A blend function for a q3 shader. + struct SBlendFunc + { + SBlendFunc ( video::E_MODULATE_FUNC mod ) + : type ( video::EMT_SOLID ), modulate ( mod ), + param0( 0.f ), + isTransparent ( 0 ) {} + + video::E_MATERIAL_TYPE type; + video::E_MODULATE_FUNC modulate; + + f32 param0; + u32 isTransparent; + }; + + // parses the content of Variable cull + inline bool getCullingFunction ( const core::stringc &cull ) + { + if ( cull.size() == 0 ) + return true; + + bool ret = true; + static const c8 * funclist[] = { "none", "disable", "twosided" }; + + u32 pos = 0; + switch ( isEqual ( cull, pos, funclist, 3 ) ) + { + case 0: + case 1: + case 2: + ret = false; + break; + } + return ret; + } + + // parses the content of Variable depthfunc + // return a z-test + inline u8 getDepthFunction ( const core::stringc &string ) + { + u8 ret = video::ECFN_LESSEQUAL; + + if ( string.size() == 0 ) + return ret; + + static const c8 * funclist[] = { "lequal","equal" }; + + u32 pos = 0; + switch ( isEqual ( string, pos, funclist, 2 ) ) + { + case 0: + ret = video::ECFN_LESSEQUAL; + break; + case 1: + ret = video::ECFN_EQUAL; + break; + } + return ret; + } + + + /*! + parses the content of Variable blendfunc,alphafunc + it also make a hint for rendering as transparent or solid node. + + we assume a typical quake scene would look like this.. + 1) Big Static Mesh ( solid ) + 2) static scene item ( may use transparency ) but rendered in the solid pass + 3) additional transparency item in the transparent pass + + it's not 100% accurate! it just empirical.. + */ + inline static void getBlendFunc ( const core::stringc &string, SBlendFunc &blendfunc ) + { + if ( string.size() == 0 ) + return; + + // maps to E_BLEND_FACTOR + static const c8 * funclist[] = + { + "gl_zero", + "gl_one", + "gl_dst_color", + "gl_one_minus_dst_color", + "gl_src_color", + "gl_one_minus_src_color", + "gl_src_alpha", + "gl_one_minus_src_alpha", + "gl_dst_alpha", + "gl_one_minus_dst_alpha", + "gl_src_alpha_sat", + + "add", + "filter", + "blend", + + "ge128", + "gt0", + }; + + + u32 pos = 0; + s32 srcFact = isEqual ( string, pos, funclist, 16 ); + + if ( srcFact < 0 ) + return; + + u32 resolved = 0; + s32 dstFact = isEqual ( string, pos, funclist, 16 ); + + switch ( srcFact ) + { + case video::EBF_ZERO: + switch ( dstFact ) + { + // gl_zero gl_src_color == gl_dst_color gl_zero + case video::EBF_SRC_COLOR: + blendfunc.type = video::EMT_ONETEXTURE_BLEND; + blendfunc.param0 = video::pack_textureBlendFunc ( video::EBF_DST_COLOR, video::EBF_ZERO, blendfunc.modulate ); + blendfunc.isTransparent = 1; + resolved = 1; + break; + } break; + + case video::EBF_ONE: + switch ( dstFact ) + { + // gl_one gl_zero + case video::EBF_ZERO: + blendfunc.type = video::EMT_SOLID; + blendfunc.isTransparent = 0; + resolved = 1; + break; + + // gl_one gl_one + case video::EBF_ONE: + blendfunc.type = video::EMT_TRANSPARENT_ADD_COLOR; + blendfunc.isTransparent = 1; + resolved = 1; + break; + } break; + + case video::EBF_SRC_ALPHA: + switch ( dstFact ) + { + // gl_src_alpha gl_one_minus_src_alpha + case video::EBF_ONE_MINUS_SRC_ALPHA: + blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + blendfunc.param0 = 1.f/255.f; + blendfunc.isTransparent = 1; + resolved = 1; + break; + } break; + + case 11: + // add + blendfunc.type = video::EMT_TRANSPARENT_ADD_COLOR; + blendfunc.isTransparent = 1; + resolved = 1; + break; + case 12: + // filter = gl_dst_color gl_zero or gl_zero gl_src_color + blendfunc.type = video::EMT_ONETEXTURE_BLEND; + blendfunc.param0 = video::pack_textureBlendFunc ( video::EBF_DST_COLOR, video::EBF_ZERO, blendfunc.modulate ); + blendfunc.isTransparent = 1; + resolved = 1; + break; + case 13: + // blend = gl_src_alpha gl_one_minus_src_alpha + blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + blendfunc.param0 = 1.f/255.f; + blendfunc.isTransparent = 1; + resolved = 1; + break; + case 14: + // alphafunc ge128 + blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + blendfunc.param0 = 0.5f; + blendfunc.isTransparent = 1; + resolved = 1; + break; + case 15: + // alphafunc gt0 + blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + blendfunc.param0 = 1.f / 255.f; + blendfunc.isTransparent = 1; + resolved = 1; + break; + + } + + // use the generic blender + if ( 0 == resolved ) + { + blendfunc.type = video::EMT_ONETEXTURE_BLEND; + blendfunc.param0 = video::pack_textureBlendFunc ( + (video::E_BLEND_FACTOR) srcFact, + (video::E_BLEND_FACTOR) dstFact, + blendfunc.modulate); + + blendfunc.isTransparent = 1; + } + } + + // random noise [-1;1] + struct Noiser + { + static f32 get () + { + static u32 RandomSeed = 0x69666966; + RandomSeed = (RandomSeed * 3631 + 1); + + f32 value = ( (f32) (RandomSeed & 0x7FFF ) * (1.0f / (f32)(0x7FFF >> 1) ) ) - 1.f; + return value; + } + }; + + enum eQ3ModifierFunction + { + TCMOD = 0, + DEFORMVERTEXES = 1, + RGBGEN = 2, + TCGEN = 3, + MAP = 4, + ALPHAGEN = 5, + + FUNCTION2 = 0x10, + SCROLL = FUNCTION2 + 1, + SCALE = FUNCTION2 + 2, + ROTATE = FUNCTION2 + 3, + STRETCH = FUNCTION2 + 4, + TURBULENCE = FUNCTION2 + 5, + WAVE = FUNCTION2 + 6, + + IDENTITY = FUNCTION2 + 7, + VERTEX = FUNCTION2 + 8, + TEXTURE = FUNCTION2 + 9, + LIGHTMAP = FUNCTION2 + 10, + ENVIRONMENT = FUNCTION2 + 11, + DOLLAR_LIGHTMAP = FUNCTION2 + 12, + BULGE = FUNCTION2 + 13, + AUTOSPRITE = FUNCTION2 + 14, + AUTOSPRITE2 = FUNCTION2 + 15, + TRANSFORM = FUNCTION2 + 16, + EXACTVERTEX = FUNCTION2 + 17, + CONSTANT = FUNCTION2 + 18, + LIGHTINGSPECULAR = FUNCTION2 + 19, + MOVE = FUNCTION2 + 20, + NORMAL = FUNCTION2 + 21, + IDENTITYLIGHTING = FUNCTION2 + 22, + + WAVE_MODIFIER_FUNCTION = 0x30, + SINUS = WAVE_MODIFIER_FUNCTION + 1, + COSINUS = WAVE_MODIFIER_FUNCTION + 2, + SQUARE = WAVE_MODIFIER_FUNCTION + 3, + TRIANGLE = WAVE_MODIFIER_FUNCTION + 4, + SAWTOOTH = WAVE_MODIFIER_FUNCTION + 5, + SAWTOOTH_INVERSE = WAVE_MODIFIER_FUNCTION + 6, + NOISE = WAVE_MODIFIER_FUNCTION + 7, + + + UNKNOWN = -2 + + }; + + struct SModifierFunction + { + SModifierFunction () + : masterfunc0 ( UNKNOWN ), masterfunc1( UNKNOWN ), func ( SINUS ), + tcgen( TEXTURE ), rgbgen ( IDENTITY ), alphagen ( UNKNOWN ), + base ( 0 ), amp ( 1 ), phase ( 0 ), frequency ( 1 ), + wave ( 1 ), + x ( 0 ), y ( 0 ), z( 0 ), count( 0 ) {} + + // "tcmod","deformvertexes","rgbgen", "tcgen" + eQ3ModifierFunction masterfunc0; + // depends + eQ3ModifierFunction masterfunc1; + // depends + eQ3ModifierFunction func; + + eQ3ModifierFunction tcgen; + eQ3ModifierFunction rgbgen; + eQ3ModifierFunction alphagen; + + union + { + f32 base; + f32 bulgewidth; + }; + + union + { + f32 amp; + f32 bulgeheight; + }; + + f32 phase; + + union + { + f32 frequency; + f32 bulgespeed; + }; + + union + { + f32 wave; + f32 div; + }; + + f32 x; + f32 y; + f32 z; + u32 count; + + f32 evaluate ( f32 dt ) const + { + // phase in 0 and 1.. + f32 x = core::fract( (dt + phase ) * frequency ); + f32 y = 0.f; + + switch ( func ) + { + case SINUS: + y = sinf ( x * core::PI * 2.f ); + break; + case COSINUS: + y = cosf ( x * core::PI * 2.f ); + break; + case SQUARE: + y = x < 0.5f ? 1.f : -1.f; + break; + case TRIANGLE: + y = x < 0.5f ? ( 4.f * x ) - 1.f : ( -4.f * x ) + 3.f; + break; + case SAWTOOTH: + y = x; + break; + case SAWTOOTH_INVERSE: + y = 1.f - x; + break; + case NOISE: + y = Noiser::get(); + break; + default: + break; + } + + return base + ( y * amp ); + } + + + }; + + inline core::vector3df getMD3Normal ( u32 i, u32 j ) + { + const f32 lng = i * 2.0f * core::PI / 255.0f; + const f32 lat = j * 2.0f * core::PI / 255.0f; + return core::vector3df(cosf ( lat ) * sinf ( lng ), + sinf ( lat ) * sinf ( lng ), + cosf ( lng )); + } + + // + inline void getModifierFunc ( SModifierFunction& fill, const core::stringc &string, u32 &pos ) + { + if ( string.size() == 0 ) + return; + + static const c8 * funclist[] = + { + "sin","cos","square", + "triangle", "sawtooth","inversesawtooth", "noise" + }; + + fill.func = (eQ3ModifierFunction) isEqual ( string,pos, funclist,7 ); + fill.func = fill.func == UNKNOWN ? SINUS : (eQ3ModifierFunction) ((u32) fill.func + WAVE_MODIFIER_FUNCTION + 1); + + fill.base = getAsFloat ( string, pos ); + fill.amp = getAsFloat ( string, pos ); + fill.phase = getAsFloat ( string, pos ); + fill.frequency = getAsFloat ( string, pos ); + } + + + // name = "a b c .." + struct SVariable + { + core::stringc name; + core::stringc content; + + SVariable ( const c8 * n, const c8 *c = 0 ) : name ( n ), content (c) {} + virtual ~SVariable () {} + + void clear () + { + name = ""; + content = ""; + } + + s32 isValid () const + { + return name.size(); + } + + bool operator == ( const SVariable &other ) const + { + return 0 == strcmp ( name.c_str(), other.name.c_str () ); + } + + bool operator < ( const SVariable &other ) const + { + return 0 > strcmp ( name.c_str(), other.name.c_str () ); + } + + }; + + + // string database. "a" = "Hello", "b" = "1234.6" + struct SVarGroup + { + SVarGroup () { Variable.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE ); } + virtual ~SVarGroup () {} + + u32 isDefined ( const c8 * name, const c8 * content = 0 ) const + { + for ( u32 i = 0; i != Variable.size (); ++i ) + { + if ( 0 == strcmp ( Variable[i].name.c_str(), name ) && + ( 0 == content || strstr ( Variable[i].content.c_str(), content ) ) + ) + { + return i + 1; + } + } + return 0; + } + + // searches for Variable name and returns is content + // if Variable is not found a reference to an Empty String is returned + const core::stringc &get( const c8 * name ) const + { + SVariable search ( name ); + s32 index = Variable.linear_search ( search ); + if ( index < 0 ) + return irrEmptyStringc; + + return Variable [ index ].content; + } + + // set the Variable name + void set ( const c8 * name, const c8 * content = 0 ) + { + u32 index = isDefined ( name, 0 ); + if ( 0 == index ) + { + Variable.push_back ( SVariable ( name, content ) ); + } + else + { + Variable [ index ].content = content; + } + } + + + core::array < SVariable > Variable; + }; + + //! holding a group a variable + struct SVarGroupList: public IReferenceCounted + { + SVarGroupList () + { + VariableGroup.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE ); + } + virtual ~SVarGroupList () {} + + core::array < SVarGroup > VariableGroup; + }; + + + //! A Parsed Shader Holding Variables ordered in Groups + struct IShader + { + IShader () + : ID ( 0 ), VarGroup ( 0 ) {} + virtual ~IShader () {} + + void operator = (const IShader &other ) + { + ID = other.ID; + VarGroup = other.VarGroup; + name = other.name; + } + + bool operator == (const IShader &other ) const + { + return 0 == strcmp ( name.c_str(), other.name.c_str () ); + //return name == other.name; + } + + bool operator < (const IShader &other ) const + { + return strcmp ( name.c_str(), other.name.c_str () ) < 0; + //return name < other.name; + } + + u32 getGroupSize () const + { + if ( 0 == VarGroup ) + return 0; + return VarGroup->VariableGroup.size (); + } + + const SVarGroup * getGroup ( u32 stage ) const + { + if ( 0 == VarGroup || stage >= VarGroup->VariableGroup.size () ) + return 0; + + return &VarGroup->VariableGroup [ stage ]; + } + + // id + s32 ID; + SVarGroupList *VarGroup; // reference + + // Shader: shader name ( also first variable in first Vargroup ) + // Entity: classname ( variable in Group(1) ) + core::stringc name; + }; + + typedef IShader IEntity; + + typedef core::array < IEntity > tQ3EntityList; + + /* + dump shader like original layout, regardless of internal data holding + no recursive folding.. + */ + inline void dumpVarGroup ( core::stringc &dest, const SVarGroup * group, s32 stack ) + { + core::stringc buf; + s32 i; + + + if ( stack > 0 ) + { + buf = ""; + for ( i = 0; i < stack - 1; ++i ) + buf += '\t'; + + buf += "{\n"; + dest.append ( buf ); + } + + for ( u32 g = 0; g != group->Variable.size(); ++g ) + { + buf = ""; + for ( i = 0; i < stack; ++i ) + buf += '\t'; + + buf += group->Variable[g].name; + buf += " "; + buf += group->Variable[g].content; + buf += "\n"; + dest.append ( buf ); + } + + if ( stack > 1 ) + { + buf = ""; + for ( i = 0; i < stack - 1; ++i ) + buf += '\t'; + + buf += "}\n"; + dest.append ( buf ); + } + + } + + /*! + dump a Shader or an Entity + */ + inline core::stringc & dumpShader ( core::stringc &dest, const IShader * shader, bool entity = false ) + { + if ( 0 == shader ) + return dest; + + const SVarGroup * group; + + const u32 size = shader->VarGroup->VariableGroup.size (); + for ( u32 i = 0; i != size; ++i ) + { + group = &shader->VarGroup->VariableGroup[ i ]; + dumpVarGroup ( dest, group, core::clamp( (int)i, 0, 2 ) ); + } + + if ( !entity ) + { + if ( size <= 1 ) + { + dest.append ( "{\n" ); + } + dest.append ( "}\n" ); + } + return dest; + } + + + /* + quake3 doesn't care much about tga & jpg + load one or multiple files stored in name started at startPos to the texture array textures + if texture is not loaded 0 will be added ( to find missing textures easier) + */ + inline void getTextures(tTexArray &textures, + const core::stringc &name, u32 &startPos, + io::IFileSystem *fileSystem, + video::IVideoDriver* driver) + { + static const char* extension[] = + { + ".jpg", + ".jpeg", + ".png", + ".dds", + ".tga", + ".bmp", + ".pcx" + }; + + tStringList stringList; + getAsStringList(stringList, -1, name, startPos); + + textures.clear(); + + io::path loadFile; + for ( u32 i = 0; i!= stringList.size (); ++i ) + { + video::ITexture* texture = 0; + for (u32 g = 0; g != 7 ; ++g) + { + core::cutFilenameExtension ( loadFile, stringList[i] ); + + if ( loadFile == "$whiteimage" ) + { + texture = driver->getTexture( "$whiteimage" ); + if ( 0 == texture ) + { + core::dimension2du s ( 2, 2 ); + u32 image[4] = { 0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }; + video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image ); + texture = driver->addTexture( "$whiteimage", w ); + w->drop (); + } + + } + else + if ( loadFile == "$redimage" ) + { + texture = driver->getTexture( "$redimage" ); + if ( 0 == texture ) + { + core::dimension2du s ( 2, 2 ); + u32 image[4] = { 0xFFFF0000, 0xFFFF0000,0xFFFF0000,0xFFFF0000 }; + video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image ); + texture = driver->addTexture( "$redimage", w ); + w->drop (); + } + } + else + if ( loadFile == "$blueimage" ) + { + texture = driver->getTexture( "$blueimage" ); + if ( 0 == texture ) + { + core::dimension2du s ( 2, 2 ); + u32 image[4] = { 0xFF0000FF, 0xFF0000FF,0xFF0000FF,0xFF0000FF }; + video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image ); + texture = driver->addTexture( "$blueimage", w ); + w->drop (); + } + } + else + if ( loadFile == "$checkerimage" ) + { + texture = driver->getTexture( "$checkerimage" ); + if ( 0 == texture ) + { + core::dimension2du s ( 2, 2 ); + u32 image[4] = { 0xFFFFFFFF, 0xFF000000,0xFF000000,0xFFFFFFFF }; + video::IImage* w = driver->createImageFromData ( video::ECF_A8R8G8B8, s,&image ); + texture = driver->addTexture( "$checkerimage", w ); + w->drop (); + } + } + else + if ( loadFile == "$lightmap" ) + { + texture = 0; + } + else + { + loadFile.append ( extension[g] ); + } + + if ( fileSystem->existFile ( loadFile ) ) + { + texture = driver->getTexture( loadFile ); + if ( texture ) + break; + texture = 0; + } + } + // take 0 Texture + textures.push_back(texture); + } + } + + + //! Manages various Quake3 Shader Styles + class IShaderManager : public IReferenceCounted + { + }; + +} // end namespace quake3 +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IRandomizer.h b/builddir/irrlicht-1.8.1/include/IRandomizer.h new file mode 100644 index 0000000..2d7d1d8 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IRandomizer.h @@ -0,0 +1,33 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_RANDOMIZER_H_INCLUDED__ +#define __I_RANDOMIZER_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ + +//! Interface for generating random numbers +class IRandomizer : public virtual IReferenceCounted +{ +public: + //! resets the randomizer + /** \param value Initialization value (seed) */ + virtual void reset(s32 value=0x0f0f0f0f) =0; + + //! generates a pseudo random number in the range 0..randMax() + virtual s32 rand() const =0; + + //! generates a pseudo random number in the range 0..1 + virtual f32 frand() const =0; + + //! get maxmimum number generated by rand() + virtual s32 randMax() const =0; +}; + +} // end namespace irr + +#endif diff --git a/builddir/irrlicht-1.8.1/include/IReadFile.h b/builddir/irrlicht-1.8.1/include/IReadFile.h new file mode 100644 index 0000000..eb4f0bd --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IReadFile.h @@ -0,0 +1,58 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_READ_FILE_H_INCLUDED__ +#define __I_READ_FILE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "coreutil.h" + +namespace irr +{ +namespace io +{ + + //! Interface providing read acess to a file. + class IReadFile : public virtual IReferenceCounted + { + public: + //! Reads an amount of bytes from the file. + /** \param buffer Pointer to buffer where read bytes are written to. + \param sizeToRead Amount of bytes to read from the file. + \return How many bytes were read. */ + virtual s32 read(void* buffer, u32 sizeToRead) = 0; + + //! Changes position in file + /** \param finalPos Destination position in the file. + \param relativeMovement If set to true, the position in the file is + changed relative to current position. Otherwise the position is changed + from beginning of file. + \return True if successful, otherwise false. */ + virtual bool seek(long finalPos, bool relativeMovement = false) = 0; + + //! Get size of file. + /** \return Size of the file in bytes. */ + virtual long getSize() const = 0; + + //! Get the current position in the file. + /** \return Current position in the file in bytes. */ + virtual long getPos() const = 0; + + //! Get name of file. + /** \return File name as zero terminated character string. */ + virtual const io::path& getFileName() const = 0; + }; + + //! Internal function, please do not use. + IReadFile* createReadFile(const io::path& fileName); + //! Internal function, please do not use. + IReadFile* createLimitReadFile(const io::path& fileName, IReadFile* alreadyOpenedFile, long pos, long areaSize); + //! Internal function, please do not use. + IReadFile* createMemoryReadFile(void* memory, long size, const io::path& fileName, bool deleteMemoryWhenDropped); + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IReferenceCounted.h b/builddir/irrlicht-1.8.1/include/IReferenceCounted.h new file mode 100644 index 0000000..0eb23a5 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IReferenceCounted.h @@ -0,0 +1,170 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_IREFERENCE_COUNTED_H_INCLUDED__ +#define __I_IREFERENCE_COUNTED_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ + + //! Base class of most objects of the Irrlicht Engine. + /** This class provides reference counting through the methods grab() and drop(). + It also is able to store a debug string for every instance of an object. + Most objects of the Irrlicht + Engine are derived from IReferenceCounted, and so they are reference counted. + + When you create an object in the Irrlicht engine, calling a method + which starts with 'create', an object is created, and you get a pointer + to the new object. If you no longer need the object, you have + to call drop(). This will destroy the object, if grab() was not called + in another part of you program, because this part still needs the object. + Note, that you only need to call drop() to the object, if you created it, + and the method had a 'create' in it. + + A simple example: + + If you want to create a texture, you may want to call an imaginable method + IDriver::createTexture. You call + ITexture* texture = driver->createTexture(dimension2d<u32>(128, 128)); + If you no longer need the texture, call texture->drop(). + + If you want to load a texture, you may want to call imaginable method + IDriver::loadTexture. You do this like + ITexture* texture = driver->loadTexture("example.jpg"); + You will not have to drop the pointer to the loaded texture, because + the name of the method does not start with 'create'. The texture + is stored somewhere by the driver. + */ + class IReferenceCounted + { + public: + + //! Constructor. + IReferenceCounted() + : DebugName(0), ReferenceCounter(1) + { + } + + //! Destructor. + virtual ~IReferenceCounted() + { + } + + //! Grabs the object. Increments the reference counter by one. + /** Someone who calls grab() to an object, should later also + call drop() to it. If an object never gets as much drop() as + grab() calls, it will never be destroyed. The + IReferenceCounted class provides a basic reference counting + mechanism with its methods grab() and drop(). Most objects of + the Irrlicht Engine are derived from IReferenceCounted, and so + they are reference counted. + + When you create an object in the Irrlicht engine, calling a + method which starts with 'create', an object is created, and + you get a pointer to the new object. If you no longer need the + object, you have to call drop(). This will destroy the object, + if grab() was not called in another part of you program, + because this part still needs the object. Note, that you only + need to call drop() to the object, if you created it, and the + method had a 'create' in it. + + A simple example: + + If you want to create a texture, you may want to call an + imaginable method IDriver::createTexture. You call + ITexture* texture = driver->createTexture(dimension2d<u32>(128, 128)); + If you no longer need the texture, call texture->drop(). + If you want to load a texture, you may want to call imaginable + method IDriver::loadTexture. You do this like + ITexture* texture = driver->loadTexture("example.jpg"); + You will not have to drop the pointer to the loaded texture, + because the name of the method does not start with 'create'. + The texture is stored somewhere by the driver. */ + void grab() const { ++ReferenceCounter; } + + //! Drops the object. Decrements the reference counter by one. + /** The IReferenceCounted class provides a basic reference + counting mechanism with its methods grab() and drop(). Most + objects of the Irrlicht Engine are derived from + IReferenceCounted, and so they are reference counted. + + When you create an object in the Irrlicht engine, calling a + method which starts with 'create', an object is created, and + you get a pointer to the new object. If you no longer need the + object, you have to call drop(). This will destroy the object, + if grab() was not called in another part of you program, + because this part still needs the object. Note, that you only + need to call drop() to the object, if you created it, and the + method had a 'create' in it. + + A simple example: + + If you want to create a texture, you may want to call an + imaginable method IDriver::createTexture. You call + ITexture* texture = driver->createTexture(dimension2d<u32>(128, 128)); + If you no longer need the texture, call texture->drop(). + If you want to load a texture, you may want to call imaginable + method IDriver::loadTexture. You do this like + ITexture* texture = driver->loadTexture("example.jpg"); + You will not have to drop the pointer to the loaded texture, + because the name of the method does not start with 'create'. + The texture is stored somewhere by the driver. + \return True, if the object was deleted. */ + bool drop() const + { + // someone is doing bad reference counting. + _IRR_DEBUG_BREAK_IF(ReferenceCounter <= 0) + + --ReferenceCounter; + if (!ReferenceCounter) + { + delete this; + return true; + } + + return false; + } + + //! Get the reference count. + /** \return Current value of the reference counter. */ + s32 getReferenceCount() const + { + return ReferenceCounter; + } + + //! Returns the debug name of the object. + /** The Debugname may only be set and changed by the object + itself. This method should only be used in Debug mode. + \return Returns a string, previously set by setDebugName(); */ + const c8* getDebugName() const + { + return DebugName; + } + + protected: + + //! Sets the debug name of the object. + /** The Debugname may only be set and changed by the object + itself. This method should only be used in Debug mode. + \param newName: New debug name to set. */ + void setDebugName(const c8* newName) + { + DebugName = newName; + } + + private: + + //! The debug name. + const c8* DebugName; + + //! The reference counter. Mutable to do reference counting on const objects. + mutable s32 ReferenceCounter; + }; + +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISceneCollisionManager.h b/builddir/irrlicht-1.8.1/include/ISceneCollisionManager.h new file mode 100644 index 0000000..726936a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISceneCollisionManager.h @@ -0,0 +1,205 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_COLLISION_MANAGER_H_INCLUDED__ +#define __I_SCENE_COLLISION_MANAGER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "vector3d.h" +#include "triangle3d.h" +#include "position2d.h" +#include "line3d.h" + +namespace irr +{ + +namespace scene +{ + class ISceneNode; + class ICameraSceneNode; + class ITriangleSelector; + + //! The Scene Collision Manager provides methods for performing collision tests and picking on scene nodes. + class ISceneCollisionManager : public virtual IReferenceCounted + { + public: + + //! Finds the nearest collision point of a line and lots of triangles, if there is one. + /** \param ray: Line with which collisions are tested. + \param selector: TriangleSelector containing the triangles. It + can be created for example using + ISceneManager::createTriangleSelector() or + ISceneManager::createTriangleOctreeSelector(). + \param outCollisionPoint: If a collision is detected, this will + contain the position of the nearest collision to the line-start. + \param outTriangle: If a collision is detected, this will + contain the triangle with which the ray collided. + \param outNode: If a collision is detected, this will contain + the scene node associated with the triangle that was hit. + \return True if a collision was detected and false if not. */ + virtual bool getCollisionPoint(const core::line3d<f32>& ray, + ITriangleSelector* selector, core::vector3df& outCollisionPoint, + core::triangle3df& outTriangle, ISceneNode*& outNode) =0; + + //! Collides a moving ellipsoid with a 3d world with gravity and returns the resulting new position of the ellipsoid. + /** This can be used for moving a character in a 3d world: The + character will slide at walls and is able to walk up stairs. + The method used how to calculate the collision result position + is based on the paper "Improved Collision detection and + Response" by Kasper Fauerby. + \param selector: TriangleSelector containing the triangles of + the world. It can be created for example using + ISceneManager::createTriangleSelector() or + ISceneManager::createTriangleOctreeSelector(). + \param ellipsoidPosition: Position of the ellipsoid. + \param ellipsoidRadius: Radius of the ellipsoid. + \param ellipsoidDirectionAndSpeed: Direction and speed of the + movement of the ellipsoid. + \param triout: Optional parameter where the last triangle + causing a collision is stored, if there is a collision. + \param hitPosition: Return value for the position of the collision + \param outFalling: Is set to true if the ellipsoid is falling + down, caused by gravity. + \param outNode: the node with which the ellipoid collided (if any) + \param slidingSpeed: DOCUMENTATION NEEDED. + \param gravityDirectionAndSpeed: Direction and force of gravity. + \return New position of the ellipsoid. */ + virtual core::vector3df getCollisionResultPosition( + ITriangleSelector* selector, + const core::vector3df &ellipsoidPosition, + const core::vector3df& ellipsoidRadius, + const core::vector3df& ellipsoidDirectionAndSpeed, + core::triangle3df& triout, + core::vector3df& hitPosition, + bool& outFalling, + ISceneNode*& outNode, + f32 slidingSpeed = 0.0005f, + const core::vector3df& gravityDirectionAndSpeed + = core::vector3df(0.0f, 0.0f, 0.0f)) = 0; + + //! Returns a 3d ray which would go through the 2d screen coodinates. + /** \param pos: Screen coordinates in pixels. + \param camera: Camera from which the ray starts. If null, the + active camera is used. + \return Ray starting from the position of the camera and ending + at a length of the far value of the camera at a position which + would be behind the 2d screen coodinates. */ + virtual core::line3d<f32> getRayFromScreenCoordinates( + const core::position2d<s32>& pos, ICameraSceneNode* camera = 0) = 0; + + //! Calculates 2d screen position from a 3d position. + /** \param pos: 3D position in world space to be transformed + into 2d. + \param camera: Camera to be used. If null, the currently active + camera is used. + \param useViewPort: Calculate screen coordinates relative to + the current view port. Please note that unless the driver does + not take care of the view port, it is usually best to get the + result in absolute screen coordinates (flag=false). + \return 2d screen coordinates which a object in the 3d world + would have if it would be rendered to the screen. If the 3d + position is behind the camera, it is set to (-1000,-1000). In + most cases you can ignore this fact, because if you use this + method for drawing a decorator over a 3d object, it will be + clipped by the screen borders. */ + virtual core::position2d<s32> getScreenCoordinatesFrom3DPosition( + const core::vector3df& pos, ICameraSceneNode* camera=0, bool useViewPort=false) = 0; + + //! Gets the scene node, which is currently visible under the given screencoordinates, viewed from the currently active camera. + /** The collision tests are done using a bounding box for each + scene node. You can limit the recursive search so just all children of the specified root are tested. + \param pos: Position in pixel screen coordinates, under which + the returned scene node will be. + \param idBitMask: Only scene nodes with an id with bits set + like in this mask will be tested. If the BitMask is 0, this + feature is disabled. + Please note that the default node id of -1 will match with + every bitmask != 0 + \param bNoDebugObjects: Doesn't take debug objects into account + when true. These are scene nodes with IsDebugObject() = true. + \param root If different from 0, the search is limited to the children of this node. + \return Visible scene node under screen coordinates with + matching bits in its id. If there is no scene node under this + position, 0 is returned. */ + virtual ISceneNode* getSceneNodeFromScreenCoordinatesBB(const core::position2d<s32>& pos, + s32 idBitMask=0, bool bNoDebugObjects=false, ISceneNode* root=0) =0; + + //! Returns the nearest scene node which collides with a 3d ray and whose id matches a bitmask. + /** The collision tests are done using a bounding box for each + scene node. The recursive search can be limited be specifying a scene node. + \param ray Line with which collisions are tested. + \param idBitMask Only scene nodes with an id which matches at + least one of the bits contained in this mask will be tested. + However, if this parameter is 0, then all nodes are checked. + \param bNoDebugObjects: Doesn't take debug objects into account when true. These + are scene nodes with IsDebugObject() = true. + \param root If different from 0, the search is limited to the children of this node. + \return Scene node nearest to ray.start, which collides with + the ray and matches the idBitMask, if the mask is not null. If + no scene node is found, 0 is returned. */ + virtual ISceneNode* getSceneNodeFromRayBB(const core::line3d<f32>& ray, + s32 idBitMask=0, bool bNoDebugObjects=false, ISceneNode* root=0) =0; + + //! Get the scene node, which the given camera is looking at and whose id matches the bitmask. + /** A ray is simply casted from the position of the camera to + the view target position, and all scene nodes are tested + against this ray. The collision tests are done using a bounding + box for each scene node. + \param camera: Camera from which the ray is casted. + \param idBitMask: Only scene nodes with an id which matches at least one of the + bits contained in this mask will be tested. However, if this parameter is 0, then + all nodes are checked. + feature is disabled. + Please note that the default node id of -1 will match with + every bitmask != 0 + \param bNoDebugObjects: Doesn't take debug objects into account + when true. These are scene nodes with IsDebugObject() = true. + \return Scene node nearest to the camera, which collides with + the ray and matches the idBitMask, if the mask is not null. If + no scene node is found, 0 is returned. */ + virtual ISceneNode* getSceneNodeFromCameraBB(ICameraSceneNode* camera, + s32 idBitMask=0, bool bNoDebugObjects = false) = 0; + + //! Perform a ray/box and ray/triangle collision check on a heirarchy of scene nodes. + /** This checks all scene nodes under the specified one, first by ray/bounding + box, and then by accurate ray/triangle collision, finding the nearest collision, + and the scene node containg it. It returns the node hit, and (via output + parameters) the position of the collision, and the triangle that was hit. + + All scene nodes in the hierarchy tree under the specified node are checked. Only + nodes that are visible, with an ID that matches at least one bit in the supplied + bitmask, and which have a triangle selector are considered as candidates for being hit. + You do not have to build a meta triangle selector; the individual triangle selectors + of each candidate scene node are used automatically. + + \param ray: Line with which collisions are tested. + \param outCollisionPoint: If a collision is detected, this will contain the + position of the nearest collision. + \param outTriangle: If a collision is detected, this will contain the triangle + with which the ray collided. + \param idBitMask: Only scene nodes with an id which matches at least one of the + bits contained in this mask will be tested. However, if this parameter is 0, then + all nodes are checked. + \param collisionRootNode: the scene node at which to begin checking. Only this + node and its children will be checked. If you want to check the entire scene, + pass 0, and the root scene node will be used (this is the default). + \param noDebugObjects: when true, debug objects are not considered viable targets. + Debug objects are scene nodes with IsDebugObject() = true. + \return Returns the scene node containing the hit triangle nearest to ray.start. + If no collision is detected, then 0 is returned. */ + virtual ISceneNode* getSceneNodeAndCollisionPointFromRay( + core::line3df ray, + core::vector3df & outCollisionPoint, + core::triangle3df & outTriangle, + s32 idBitMask = 0, + ISceneNode * collisionRootNode = 0, + bool noDebugObjects = false) = 0; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISceneLoader.h b/builddir/irrlicht-1.8.1/include/ISceneLoader.h new file mode 100644 index 0000000..45a80f3 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISceneLoader.h @@ -0,0 +1,62 @@ +// Copyright (C) 2010-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_LOADER_H_INCLUDED__ +#define __I_SCENE_LOADER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "path.h" + +namespace irr +{ +namespace io +{ + class IReadFile; +} // end namespace io +namespace scene +{ + class ISceneNode; + class ISceneUserDataSerializer; + +//! Class which can load a scene into the scene manager. +/** If you want Irrlicht to be able to load currently unsupported +scene file formats (e.g. .vrml), then implement this and add your +new Sceneloader to the engine with ISceneManager::addExternalSceneLoader(). */ +class ISceneLoader : public virtual IReferenceCounted +{ +public: + + //! Returns true if the class might be able to load this file. + /** This decision should be based on the file extension (e.g. ".vrml") + only. + \param filename Name of the file to test. + \return True if the extension is a recognised type. */ + virtual bool isALoadableFileExtension(const io::path& filename) const = 0; + + //! Returns true if the class might be able to load this file. + /** This decision will be based on a quick look at the contents of the file. + \param file The file to test. + \return True if the extension is a recognised type. */ + virtual bool isALoadableFileFormat(io::IReadFile* file) const = 0; + + //! Loads the scene into the scene manager. + /** \param file File which contains the scene. + \param userDataSerializer: If you want to load user data which may be attached + to some some scene nodes in the file, implement the ISceneUserDataSerializer + interface and provide it as parameter here. Otherwise, simply specify 0 as this + parameter. + \param rootNode The node to load the scene into, if none is provided then the + scene will be loaded into the root node. + \return Returns true on success, false on failure. Returns 0 if loading failed. */ + virtual bool loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0, + ISceneNode* rootNode=0) = 0; + +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISceneManager.h b/builddir/irrlicht-1.8.1/include/ISceneManager.h new file mode 100644 index 0000000..8041348 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISceneManager.h @@ -0,0 +1,1663 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_MANAGER_H_INCLUDED__ +#define __I_SCENE_MANAGER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrArray.h" +#include "irrString.h" +#include "path.h" +#include "vector3d.h" +#include "dimension2d.h" +#include "SColor.h" +#include "ETerrainElements.h" +#include "ESceneNodeTypes.h" +#include "ESceneNodeAnimatorTypes.h" +#include "EMeshWriterEnums.h" +#include "SceneParameters.h" +#include "IGeometryCreator.h" +#include "ISkinnedMesh.h" + +namespace irr +{ + struct SKeyMap; + struct SEvent; + +namespace io +{ + class IReadFile; + class IAttributes; + class IWriteFile; + class IFileSystem; +} // end namespace io + +namespace gui +{ + class IGUIFont; + class IGUIEnvironment; +} // end namespace gui + +namespace video +{ + class IVideoDriver; + class SMaterial; + class IImage; + class ITexture; +} // end namespace video + +namespace scene +{ + //! Enumeration for render passes. + /** A parameter passed to the registerNodeForRendering() method of the ISceneManager, + specifying when the node wants to be drawn in relation to the other nodes. */ + enum E_SCENE_NODE_RENDER_PASS + { + //! No pass currently active + ESNRP_NONE =0, + + //! Camera pass. The active view is set up here. The very first pass. + ESNRP_CAMERA =1, + + //! In this pass, lights are transformed into camera space and added to the driver + ESNRP_LIGHT =2, + + //! This is used for sky boxes. + ESNRP_SKY_BOX =4, + + //! All normal objects can use this for registering themselves. + /** This value will never be returned by + ISceneManager::getSceneNodeRenderPass(). The scene manager + will determine by itself if an object is transparent or solid + and register the object as SNRT_TRANSPARENT or SNRT_SOLD + automatically if you call registerNodeForRendering with this + value (which is default). Note that it will register the node + only as ONE type. If your scene node has both solid and + transparent material types register it twice (one time as + SNRT_SOLID, the other time as SNRT_TRANSPARENT) and in the + render() method call getSceneNodeRenderPass() to find out the + current render pass and render only the corresponding parts of + the node. */ + ESNRP_AUTOMATIC =24, + + //! Solid scene nodes or special scene nodes without materials. + ESNRP_SOLID =8, + + //! Transparent scene nodes, drawn after solid nodes. They are sorted from back to front and drawn in that order. + ESNRP_TRANSPARENT =16, + + //! Transparent effect scene nodes, drawn after Transparent nodes. They are sorted from back to front and drawn in that order. + ESNRP_TRANSPARENT_EFFECT =32, + + //! Drawn after the solid nodes, before the transparent nodes, the time for drawing shadow volumes + ESNRP_SHADOW =64 + }; + + class IAnimatedMesh; + class IAnimatedMeshSceneNode; + class IBillboardSceneNode; + class IBillboardTextSceneNode; + class ICameraSceneNode; + class IDummyTransformationSceneNode; + class ILightManager; + class ILightSceneNode; + class IMesh; + class IMeshBuffer; + class IMeshCache; + class IMeshLoader; + class IMeshManipulator; + class IMeshSceneNode; + class IMeshWriter; + class IMetaTriangleSelector; + class IParticleSystemSceneNode; + class ISceneCollisionManager; + class ISceneLoader; + class ISceneNode; + class ISceneNodeAnimator; + class ISceneNodeAnimatorCollisionResponse; + class ISceneNodeAnimatorFactory; + class ISceneNodeFactory; + class ISceneUserDataSerializer; + class ITerrainSceneNode; + class ITextSceneNode; + class ITriangleSelector; + class IVolumeLightSceneNode; + + namespace quake3 + { + struct IShader; + } // end namespace quake3 + + //! The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff. + /** All Scene nodes can be created only here. There is a always growing + list of scene nodes for lots of purposes: Indoor rendering scene nodes + like the Octree (addOctreeSceneNode()) or the terrain renderer + (addTerrainSceneNode()), different Camera scene nodes + (addCameraSceneNode(), addCameraSceneNodeMaya()), scene nodes for Light + (addLightSceneNode()), Billboards (addBillboardSceneNode()) and so on. + A scene node is a node in the hierachical scene graph. Every scene node + may have children, which are other scene nodes. Children move relative + the their parents position. If the parent of a node is not visible, its + children won't be visible, too. In this way, it is for example easily + possible to attach a light to a moving car or to place a walking + character on a moving platform on a moving ship. + The SceneManager is also able to load 3d mesh files of different + formats. Take a look at getMesh() to find out what formats are + supported. If these formats are not enough, use + addExternalMeshLoader() to add new formats to the engine. + */ + class ISceneManager : public virtual IReferenceCounted + { + public: + + //! Get pointer to an animateable mesh. Loads the file if not loaded already. + /** + * If you want to remove a loaded mesh from the cache again, use removeMesh(). + * Currently there are the following mesh formats supported: + * <TABLE border="1" cellpadding="2" cellspacing="0"> + * <TR> + * <TD>Format</TD> + * <TD>Description</TD> + * </TR> + * <TR> + * <TD>3D Studio (.3ds)</TD> + * <TD>Loader for 3D-Studio files which lots of 3D packages + * are able to export. Only static meshes are currently + * supported by this importer.</TD> + * </TR> + * <TR> + * <TD>3D World Studio (.smf)</TD> + * <TD>Loader for Leadwerks SMF mesh files, a simple mesh format + * containing static geometry for games. The proprietary .STF texture format + * is not supported yet. This loader was originally written by Joseph Ellis. </TD> + * </TR> + * <TR> + * <TD>Bliz Basic B3D (.b3d)</TD> + * <TD>Loader for blitz basic files, developed by Mark + * Sibly. This is the ideal animated mesh format for game + * characters as it is both rigidly defined and widely + * supported by modeling and animation software. + * As this format supports skeletal animations, an + * ISkinnedMesh will be returned by this importer.</TD> + * </TR> + * <TR> + * <TD>Cartography shop 4 (.csm)</TD> + * <TD>Cartography Shop is a modeling program for creating + * architecture and calculating lighting. Irrlicht can + * directly import .csm files thanks to the IrrCSM library + * created by Saurav Mohapatra which is now integrated + * directly in Irrlicht. If you are using this loader, + * please note that you'll have to set the path of the + * textures before loading .csm files. You can do this + * using + * SceneManager->getParameters()->setAttribute(scene::CSM_TEXTURE_PATH, + * "path/to/your/textures");</TD> + * </TR> + * <TR> + * <TD>COLLADA (.dae, .xml)</TD> + * <TD>COLLADA is an open Digital Asset Exchange Schema for + * the interactive 3D industry. There are exporters and + * importers for this format available for most of the + * big 3d packagesat http://collada.org. Irrlicht can + * import COLLADA files by using the + * ISceneManager::getMesh() method. COLLADA files need + * not contain only one single mesh but multiple meshes + * and a whole scene setup with lights, cameras and mesh + * instances, this loader can set up a scene as + * described by the COLLADA file instead of loading and + * returning one single mesh. By default, this loader + * behaves like the other loaders and does not create + * instances, but it can be switched into this mode by + * using + * SceneManager->getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, true); + * Created scene nodes will be named as the names of the + * nodes in the COLLADA file. The returned mesh is just + * a dummy object in this mode. Meshes included in the + * scene will be added into the scene manager with the + * following naming scheme: + * "path/to/file/file.dea#meshname". The loading of such + * meshes is logged. Currently, this loader is able to + + + * create meshes (made of only polygons), lights, and + * cameras. Materials and animations are currently not + * supported but this will change with future releases. + * </TD> + * </TR> + * <TR> + * <TD>Delgine DeleD (.dmf)</TD> + * <TD>DeleD (delgine.com) is a 3D editor and level-editor + * combined into one and is specifically designed for 3D + * game-development. With this loader, it is possible to + * directly load all geometry is as well as textures and + * lightmaps from .dmf files. To set texture and + * material paths, see scene::DMF_USE_MATERIALS_DIRS and + * scene::DMF_TEXTURE_PATH. It is also possible to flip + * the alpha texture by setting + * scene::DMF_FLIP_ALPHA_TEXTURES to true and to set the + * material transparent reference value by setting + * scene::DMF_ALPHA_CHANNEL_REF to a float between 0 and + * 1. The loader is based on Salvatore Russo's .dmf + * loader, I just changed some parts of it. Thanks to + * Salvatore for his work and for allowing me to use his + * code in Irrlicht and put it under Irrlicht's license. + * For newer and more enchanced versions of the loader, + * take a look at delgine.com. + * </TD> + * </TR> + * <TR> + * <TD>DirectX (.x)</TD> + * <TD>Platform independent importer (so not D3D-only) for + * .x files. Most 3D packages can export these natively + * and there are several tools for them available, e.g. + * the Maya exporter included in the DX SDK. + * .x files can include skeletal animations and Irrlicht + * is able to play and display them, users can manipulate + * the joints via the ISkinnedMesh interface. Currently, + * Irrlicht only supports uncompressed .x files.</TD> + * </TR> + * <TR> + * <TD>Half-Life model (.mdl)</TD> + * <TD>This loader opens Half-life 1 models, it was contributed + * by Fabio Concas and adapted by Thomas Alten.</TD> + * </TR> + * <TR> + * <TD>Irrlicht Mesh (.irrMesh)</TD> + * <TD>This is a static mesh format written in XML, native + * to Irrlicht and written by the irr mesh writer. + * This format is exported by the CopperCube engine's + * lightmapper.</TD> + * </TR> + * <TR> + * <TD>LightWave (.lwo)</TD> + * <TD>Native to NewTek's LightWave 3D, the LWO format is well + * known and supported by many exporters. This loader will + * import LWO2 models including lightmaps, bumpmaps and + * reflection textures.</TD> + * </TR> + * <TR> + * <TD>Maya (.obj)</TD> + * <TD>Most 3D software can create .obj files which contain + * static geometry without material data. The material + * files .mtl are also supported. This importer for + * Irrlicht can load them directly. </TD> + * </TR> + * <TR> + * <TD>Milkshape (.ms3d)</TD> + * <TD>.MS3D files contain models and sometimes skeletal + * animations from the Milkshape 3D modeling and animation + * software. Like the other skeletal mesh loaders, oints + * are exposed via the ISkinnedMesh animated mesh type.</TD> + * </TR> + * <TR> + * <TD>My3D (.my3d)</TD> + * <TD>.my3D is a flexible 3D file format. The My3DTools + * contains plug-ins to export .my3D files from several + * 3D packages. With this built-in importer, Irrlicht + * can read and display those files directly. This + * loader was written by Zhuck Dimitry who also created + * the whole My3DTools package. If you are using this + * loader, please note that you can set the path of the + * textures before loading .my3d files. You can do this + * using + * SceneManager->getParameters()->setAttribute(scene::MY3D_TEXTURE_PATH, + * "path/to/your/textures"); + * </TD> + * </TR> + * <TR> + * <TD>OCT (.oct)</TD> + * <TD>The oct file format contains 3D geometry and + * lightmaps and can be loaded directly by Irrlicht. OCT + * files<br> can be created by FSRad, Paul Nette's + * radiosity processor or exported from Blender using + * OCTTools which can be found in the exporters/OCTTools + * directory of the SDK. Thanks to Murphy McCauley for + * creating all this.</TD> + * </TR> + * <TR> + * <TD>OGRE Meshes (.mesh)</TD> + * <TD>Ogre .mesh files contain 3D data for the OGRE 3D + * engine. Irrlicht can read and display them directly + * with this importer. To define materials for the mesh, + * copy a .material file named like the corresponding + * .mesh file where the .mesh file is. (For example + * ogrehead.material for ogrehead.mesh). Thanks to + * Christian Stehno who wrote and contributed this + * loader.</TD> + * </TR> + * <TR> + * <TD>Pulsar LMTools (.lmts)</TD> + * <TD>LMTools is a set of tools (Windows & Linux) for + * creating lightmaps. Irrlicht can directly read .lmts + * files thanks to<br> the importer created by Jonas + * Petersen. If you are using this loader, please note + * that you can set the path of the textures before + * loading .lmts files. You can do this using + * SceneManager->getParameters()->setAttribute(scene::LMTS_TEXTURE_PATH, + * "path/to/your/textures"); + * Notes for<br> this version of the loader:<br> + * - It does not recognise/support user data in the + * *.lmts files.<br> + * - The TGAs generated by LMTools don't work in + * Irrlicht for some reason (the textures are upside + * down). Opening and resaving them in a graphics app + * will solve the problem.</TD> + * </TR> + * <TR> + * <TD>Quake 3 levels (.bsp)</TD> + * <TD>Quake 3 is a popular game by IDSoftware, and .pk3 + * files contain .bsp files and textures/lightmaps + * describing huge prelighted levels. Irrlicht can read + * .pk3 and .bsp files directly and thus render Quake 3 + * levels directly. Written by Nikolaus Gebhardt + * enhanced by Dean P. Macri with the curved surfaces + * feature. </TD> + * </TR> + * <TR> + * <TD>Quake 2 models (.md2)</TD> + * <TD>Quake 2 models are characters with morph target + * animation. Irrlicht can read, display and animate + * them directly with this importer. </TD> + * </TR> + * <TR> + * <TD>Quake 3 models (.md3)</TD> + * <TD>Quake 3 models are characters with morph target + * animation, they contain mount points for weapons and body + * parts and are typically made of several sections which are + * manually joined together.</TD> + * </TR> + * <TR> + * <TD>Stanford Triangle (.ply)</TD> + * <TD>Invented by Stanford University and known as the native + * format of the infamous "Stanford Bunny" model, this is a + * popular static mesh format used by 3D scanning hardware + * and software. This loader supports extremely large models + * in both ASCII and binary format, but only has rudimentary + * material support in the form of vertex colors and texture + * coordinates.</TD> + * </TR> + * <TR> + * <TD>Stereolithography (.stl)</TD> + * <TD>The STL format is used for rapid prototyping and + * computer-aided manufacturing, thus has no support for + * materials.</TD> + * </TR> + * </TABLE> + * + * To load and display a mesh quickly, just do this: + * \code + * SceneManager->addAnimatedMeshSceneNode( + * SceneManager->getMesh("yourmesh.3ds")); + * \endcode + * If you would like to implement and add your own file format loader to Irrlicht, + * see addExternalMeshLoader(). + * \param filename: Filename of the mesh to load. + * \return Null if failed, otherwise pointer to the mesh. + * This pointer should not be dropped. See IReferenceCounted::drop() for more information. + **/ + virtual IAnimatedMesh* getMesh(const io::path& filename) = 0; + + //! Get pointer to an animateable mesh. Loads the file if not loaded already. + /** Works just as getMesh(const char* filename). If you want to + remove a loaded mesh from the cache again, use removeMesh(). + \param file File handle of the mesh to load. + \return NULL if failed and pointer to the mesh if successful. + This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IAnimatedMesh* getMesh(io::IReadFile* file) = 0; + + //! Get interface to the mesh cache which is shared beween all existing scene managers. + /** With this interface, it is possible to manually add new loaded + meshes (if ISceneManager::getMesh() is not sufficient), to remove them and to iterate + through already loaded meshes. */ + virtual IMeshCache* getMeshCache() = 0; + + //! Get the video driver. + /** \return Pointer to the video Driver. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual video::IVideoDriver* getVideoDriver() = 0; + + //! Get the active GUIEnvironment + /** \return Pointer to the GUIEnvironment + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual gui::IGUIEnvironment* getGUIEnvironment() = 0; + + //! Get the active FileSystem + /** \return Pointer to the FileSystem + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual io::IFileSystem* getFileSystem() = 0; + + //! adds Volume Lighting Scene Node. + /** Example Usage: + scene::IVolumeLightSceneNode * n = smgr->addVolumeLightSceneNode(0, -1, + 32, 32, //Subdivide U/V + video::SColor(0, 180, 180, 180), //foot color + video::SColor(0, 0, 0, 0) //tail color + ); + if (n) + { + n->setScale(core::vector3df(46.0f, 45.0f, 46.0f)); + n->getMaterial(0).setTexture(0, smgr->getVideoDriver()->getTexture("lightFalloff.png")); + } + \return Pointer to the volumeLight if successful, otherwise NULL. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IVolumeLightSceneNode* addVolumeLightSceneNode(ISceneNode* parent=0, s32 id=-1, + const u32 subdivU = 32, const u32 subdivV = 32, + const video::SColor foot = video::SColor(51, 0, 230, 180), + const video::SColor tail = video::SColor(0, 0, 0, 0), + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0; + + //! Adds a cube scene node + /** \param size: Size of the cube, uniformly in each dimension. + \param parent: Parent of the scene node. Can be 0 if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent + where the scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \return Pointer to the created test scene node. This + pointer should not be dropped. See IReferenceCounted::drop() + for more information. */ + virtual IMeshSceneNode* addCubeSceneNode(f32 size=10.0f, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0; + + //! Adds a sphere scene node of the given radius and detail + /** \param radius: Radius of the sphere. + \param polyCount: The number of vertices in horizontal and + vertical direction. The total polyCount of the sphere is + polyCount*polyCount. This parameter must be less than 256 to + stay within the 16-bit limit of the indices of a meshbuffer. + \param parent: Parent of the scene node. Can be 0 if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent + where the scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \return Pointer to the created test scene node. This + pointer should not be dropped. See IReferenceCounted::drop() + for more information. */ + virtual IMeshSceneNode* addSphereSceneNode(f32 radius=5.0f, s32 polyCount=16, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0; + + //! Adds a scene node for rendering an animated mesh model. + /** \param mesh: Pointer to the loaded animated mesh to be displayed. + \param parent: Parent of the scene node. Can be NULL if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent where the + scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed. + \return Pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IAnimatedMeshSceneNode* addAnimatedMeshSceneNode(IAnimatedMesh* mesh, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f), + bool alsoAddIfMeshPointerZero=false) = 0; + + //! Adds a scene node for rendering a static mesh. + /** \param mesh: Pointer to the loaded static mesh to be displayed. + \param parent: Parent of the scene node. Can be NULL if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent where the + scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed. + \return Pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IMeshSceneNode* addMeshSceneNode(IMesh* mesh, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f), + bool alsoAddIfMeshPointerZero=false) = 0; + + //! Adds a scene node for rendering a animated water surface mesh. + /** Looks really good when the Material type EMT_TRANSPARENT_REFLECTION + is used. + \param waveHeight: Height of the water waves. + \param waveSpeed: Speed of the water waves. + \param waveLength: Lenght of a water wave. + \param mesh: Pointer to the loaded static mesh to be displayed with water waves on it. + \param parent: Parent of the scene node. Can be NULL if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent where the + scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \return Pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addWaterSurfaceSceneNode(IMesh* mesh, + f32 waveHeight=2.0f, f32 waveSpeed=300.0f, f32 waveLength=10.0f, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0; + + + //! Adds a scene node for rendering using a octree to the scene graph. + /** This a good method for rendering + scenes with lots of geometry. The Octree is built on the fly from the mesh. + \param mesh: The mesh containing all geometry from which the octree will be build. + If this animated mesh has more than one frames in it, the first frame is taken. + \param parent: Parent node of the octree node. + \param id: id of the node. This id can be used to identify the node. + \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node. + If a node gets less polys than this value it will not be split into + smaller nodes. + \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed. + \return Pointer to the Octree if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IMeshSceneNode* addOctreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0, + s32 id=-1, s32 minimalPolysPerNode=512, bool alsoAddIfMeshPointerZero=false) = 0; + + //! Adds a scene node for rendering using a octree to the scene graph. + /** \deprecated Use addOctreeSceneNode instead. This method may be removed by Irrlicht 1.9. */ + _IRR_DEPRECATED_ IMeshSceneNode* addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0, + s32 id=-1, s32 minimalPolysPerNode=512, bool alsoAddIfMeshPointerZero=false) + { + return addOctreeSceneNode(mesh, parent, id, minimalPolysPerNode, alsoAddIfMeshPointerZero); + } + + //! Adds a scene node for rendering using a octree to the scene graph. + /** This a good method for rendering scenes with lots of + geometry. The Octree is built on the fly from the mesh, much + faster then a bsp tree. + \param mesh: The mesh containing all geometry from which the octree will be build. + \param parent: Parent node of the octree node. + \param id: id of the node. This id can be used to identify the node. + \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node. + If a node gets less polys than this value it will not be split into + smaller nodes. + \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed. + \return Pointer to the octree if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IMeshSceneNode* addOctreeSceneNode(IMesh* mesh, ISceneNode* parent=0, + s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) = 0; + + //! Adds a scene node for rendering using a octree to the scene graph. + /** \deprecated Use addOctreeSceneNode instead. This method may be removed by Irrlicht 1.9. */ + _IRR_DEPRECATED_ IMeshSceneNode* addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent=0, + s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) + { + return addOctreeSceneNode(mesh, parent, id, minimalPolysPerNode, alsoAddIfMeshPointerZero); + } + + //! Adds a camera scene node to the scene graph and sets it as active camera. + /** This camera does not react on user input like for example the one created with + addCameraSceneNodeFPS(). If you want to move or animate it, use animators or the + ISceneNode::setPosition(), ICameraSceneNode::setTarget() etc methods. + By default, a camera's look at position (set with setTarget()) and its scene node + rotation (set with setRotation()) are independent. If you want to be able to + control the direction that the camera looks by using setRotation() then call + ICameraSceneNode::bindTargetAndRotation(true) on it. + \param position: Position of the space relative to its parent where the camera will be placed. + \param lookat: Position where the camera will look at. Also known as target. + \param parent: Parent scene node of the camera. Can be null. If the parent moves, + the camera will move too. + \param id: id of the camera. This id can be used to identify the camera. + \param makeActive Flag whether this camera should become the active one. + Make sure you always have one active camera. + \return Pointer to interface to camera if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ICameraSceneNode* addCameraSceneNode(ISceneNode* parent = 0, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& lookat = core::vector3df(0,0,100), + s32 id=-1, bool makeActive=true) = 0; + + //! Adds a maya style user controlled camera scene node to the scene graph. + /** This is a standard camera with an animator that provides mouse control similar + to camera in the 3D Software Maya by Alias Wavefront. + The camera does not react on setPosition anymore after applying this animator. Instead + use setTarget, to fix the target the camera the camera hovers around. And setDistance + to set the current distance from that target, i.e. the radius of the orbit the camera + hovers on. + \param parent: Parent scene node of the camera. Can be null. + \param rotateSpeed: Rotation speed of the camera. + \param zoomSpeed: Zoom speed of the camera. + \param translationSpeed: TranslationSpeed of the camera. + \param id: id of the camera. This id can be used to identify the camera. + \param distance Initial distance of the camera from the object + \param makeActive Flag whether this camera should become the active one. + Make sure you always have one active camera. + \return Returns a pointer to the interface of the camera if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent=0, + f32 rotateSpeed=-1500.f, f32 zoomSpeed=200.f, + f32 translationSpeed=1500.f, s32 id=-1, f32 distance=70.f, + bool makeActive=true) =0; + + //! Adds a camera scene node with an animator which provides mouse and keyboard control appropriate for first person shooters (FPS). + /** This FPS camera is intended to provide a demonstration of a + camera that behaves like a typical First Person Shooter. It is + useful for simple demos and prototyping but is not intended to + provide a full solution for a production quality game. It binds + the camera scene node rotation to the look-at target; @see + ICameraSceneNode::bindTargetAndRotation(). With this camera, + you look with the mouse, and move with cursor keys. If you want + to change the key layout, you can specify your own keymap. For + example to make the camera be controlled by the cursor keys AND + the keys W,A,S, and D, do something like this: + \code + SKeyMap keyMap[8]; + keyMap[0].Action = EKA_MOVE_FORWARD; + keyMap[0].KeyCode = KEY_UP; + keyMap[1].Action = EKA_MOVE_FORWARD; + keyMap[1].KeyCode = KEY_KEY_W; + + keyMap[2].Action = EKA_MOVE_BACKWARD; + keyMap[2].KeyCode = KEY_DOWN; + keyMap[3].Action = EKA_MOVE_BACKWARD; + keyMap[3].KeyCode = KEY_KEY_S; + + keyMap[4].Action = EKA_STRAFE_LEFT; + keyMap[4].KeyCode = KEY_LEFT; + keyMap[5].Action = EKA_STRAFE_LEFT; + keyMap[5].KeyCode = KEY_KEY_A; + + keyMap[6].Action = EKA_STRAFE_RIGHT; + keyMap[6].KeyCode = KEY_RIGHT; + keyMap[7].Action = EKA_STRAFE_RIGHT; + keyMap[7].KeyCode = KEY_KEY_D; + + camera = sceneManager->addCameraSceneNodeFPS(0, 100, 500, -1, keyMap, 8); + \endcode + \param parent: Parent scene node of the camera. Can be null. + \param rotateSpeed: Speed in degress with which the camera is + rotated. This can be done only with the mouse. + \param moveSpeed: Speed in units per millisecond with which + the camera is moved. Movement is done with the cursor keys. + \param id: id of the camera. This id can be used to identify + the camera. + \param keyMapArray: Optional pointer to an array of a keymap, + specifying what keys should be used to move the camera. If this + is null, the default keymap is used. You can define actions + more then one time in the array, to bind multiple keys to the + same action. + \param keyMapSize: Amount of items in the keymap array. + \param noVerticalMovement: Setting this to true makes the + camera only move within a horizontal plane, and disables + vertical movement as known from most ego shooters. Default is + 'false', with which it is possible to fly around in space, if + no gravity is there. + \param jumpSpeed: Speed with which the camera is moved when + jumping. + \param invertMouse: Setting this to true makes the camera look + up when the mouse is moved down and down when the mouse is + moved up, the default is 'false' which means it will follow the + movement of the mouse cursor. + \param makeActive Flag whether this camera should become the active one. + Make sure you always have one active camera. + \return Pointer to the interface of the camera if successful, + otherwise 0. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual ICameraSceneNode* addCameraSceneNodeFPS(ISceneNode* parent = 0, + f32 rotateSpeed = 100.0f, f32 moveSpeed = 0.5f, s32 id=-1, + SKeyMap* keyMapArray=0, s32 keyMapSize=0, bool noVerticalMovement=false, + f32 jumpSpeed = 0.f, bool invertMouse=false, + bool makeActive=true) = 0; + + //! Adds a dynamic light scene node to the scene graph. + /** The light will cast dynamic light on all + other scene nodes in the scene, which have the material flag video::MTF_LIGHTING + turned on. (This is the default setting in most scene nodes). + \param parent: Parent scene node of the light. Can be null. If the parent moves, + the light will move too. + \param position: Position of the space relative to its parent where the light will be placed. + \param color: Diffuse color of the light. Ambient or Specular colors can be set manually with + the ILightSceneNode::getLightData() method. + \param radius: Radius of the light. + \param id: id of the node. This id can be used to identify the node. + \return Pointer to the interface of the light if successful, otherwise NULL. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ILightSceneNode* addLightSceneNode(ISceneNode* parent = 0, + const core::vector3df& position = core::vector3df(0,0,0), + video::SColorf color = video::SColorf(1.0f, 1.0f, 1.0f), + f32 radius=100.0f, s32 id=-1) = 0; + + //! Adds a billboard scene node to the scene graph. + /** A billboard is like a 3d sprite: A 2d element, + which always looks to the camera. It is usually used for things + like explosions, fire, lensflares and things like that. + \param parent Parent scene node of the billboard. Can be null. + If the parent moves, the billboard will move too. + \param size Size of the billboard. This size is 2 dimensional + because a billboard only has width and height. + \param position Position of the space relative to its parent + where the billboard will be placed. + \param id An id of the node. This id can be used to identify + the node. + \param colorTop The color of the vertices at the top of the + billboard (default: white). + \param colorBottom The color of the vertices at the bottom of + the billboard (default: white). + \return Pointer to the billboard if successful, otherwise NULL. + This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual IBillboardSceneNode* addBillboardSceneNode(ISceneNode* parent = 0, + const core::dimension2d<f32>& size = core::dimension2d<f32>(10.0f, 10.0f), + const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1, + video::SColor colorTop = 0xFFFFFFFF, video::SColor colorBottom = 0xFFFFFFFF) = 0; + + //! Adds a skybox scene node to the scene graph. + /** A skybox is a big cube with 6 textures on it and + is drawn around the camera position. + \param top: Texture for the top plane of the box. + \param bottom: Texture for the bottom plane of the box. + \param left: Texture for the left plane of the box. + \param right: Texture for the right plane of the box. + \param front: Texture for the front plane of the box. + \param back: Texture for the back plane of the box. + \param parent: Parent scene node of the skybox. A skybox usually has no parent, + so this should be null. Note: If a parent is set to the skybox, the box will not + change how it is drawn. + \param id: An id of the node. This id can be used to identify the node. + \return Pointer to the sky box if successful, otherwise NULL. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom, + video::ITexture* left, video::ITexture* right, video::ITexture* front, + video::ITexture* back, ISceneNode* parent = 0, s32 id=-1) = 0; + + //! Adds a skydome scene node to the scene graph. + /** A skydome is a large (half-) sphere with a panoramic texture + on the inside and is drawn around the camera position. + \param texture: Texture for the dome. + \param horiRes: Number of vertices of a horizontal layer of the sphere. + \param vertRes: Number of vertices of a vertical layer of the sphere. + \param texturePercentage: How much of the height of the + texture is used. Should be between 0 and 1. + \param spherePercentage: How much of the sphere is drawn. + Value should be between 0 and 2, where 1 is an exact + half-sphere and 2 is a full sphere. + \param radius The Radius of the sphere + \param parent: Parent scene node of the dome. A dome usually has no parent, + so this should be null. Note: If a parent is set, the dome will not + change how it is drawn. + \param id: An id of the node. This id can be used to identify the node. + \return Pointer to the sky dome if successful, otherwise NULL. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addSkyDomeSceneNode(video::ITexture* texture, + u32 horiRes=16, u32 vertRes=8, + f32 texturePercentage=0.9, f32 spherePercentage=2.0,f32 radius = 1000.f, + ISceneNode* parent=0, s32 id=-1) = 0; + + //! Adds a particle system scene node to the scene graph. + /** \param withDefaultEmitter: Creates a default working point emitter + which emitts some particles. Set this to true to see a particle system + in action. If set to false, you'll have to set the emitter you want by + calling IParticleSystemSceneNode::setEmitter(). + \param parent: Parent of the scene node. Can be NULL if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent where the + scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \return Pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IParticleSystemSceneNode* addParticleSystemSceneNode( + bool withDefaultEmitter=true, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0; + + //! Adds a terrain scene node to the scene graph. + /** This node implements is a simple terrain renderer which uses + a technique known as geo mip mapping + for reducing the detail of triangle blocks which are far away. + The code for the TerrainSceneNode is based on the terrain + renderer by Soconne and the GeoMipMapSceneNode developed by + Spintz. They made their code available for Irrlicht and allowed + it to be distributed under this licence. I only modified some + parts. A lot of thanks go to them. + + This scene node is capable of loading terrains and updating + the indices at runtime to enable viewing very large terrains + very quickly. It uses a CLOD (Continuous Level of Detail) + algorithm which updates the indices for each patch based on + a LOD (Level of Detail) which is determined based on a patch's + distance from the camera. + + The patch size of the terrain must always be a size of 2^N+1, + i.e. 8+1(9), 16+1(17), etc. + The MaxLOD available is directly dependent on the patch size + of the terrain. LOD 0 contains all of the indices to draw all + the triangles at the max detail for a patch. As each LOD goes + up by 1 the step taken, in generating indices increases by + -2^LOD, so for LOD 1, the step taken is 2, for LOD 2, the step + taken is 4, LOD 3 - 8, etc. The step can be no larger than + the size of the patch, so having a LOD of 8, with a patch size + of 17, is asking the algoritm to generate indices every 2^8 ( + 256 ) vertices, which is not possible with a patch size of 17. + The maximum LOD for a patch size of 17 is 2^4 ( 16 ). So, + with a MaxLOD of 5, you'll have LOD 0 ( full detail ), LOD 1 ( + every 2 vertices ), LOD 2 ( every 4 vertices ), LOD 3 ( every + 8 vertices ) and LOD 4 ( every 16 vertices ). + \param heightMapFileName: The name of the file on disk, to read vertex data from. This should + be a gray scale bitmap. + \param parent: Parent of the scene node. Can be 0 if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: The absolute position of this node. + \param rotation: The absolute rotation of this node. ( NOT YET IMPLEMENTED ) + \param scale: The scale factor for the terrain. If you're + using a heightmap of size 129x129 and would like your terrain + to be 12900x12900 in game units, then use a scale factor of ( + core::vector ( 100.0f, 100.0f, 100.0f ). If you use a Y + scaling factor of 0.0f, then your terrain will be flat. + \param vertexColor: The default color of all the vertices. If no texture is associated + with the scene node, then all vertices will be this color. Defaults to white. + \param maxLOD: The maximum LOD (level of detail) for the node. Only change if you + know what you are doing, this might lead to strange behavior. + \param patchSize: patch size of the terrain. Only change if you + know what you are doing, this might lead to strange behavior. + \param smoothFactor: The number of times the vertices are smoothed. + \param addAlsoIfHeightmapEmpty: Add terrain node even with empty heightmap. + \return Pointer to the created scene node. Can be null + if the terrain could not be created, for example because the + heightmap could not be loaded. The returned pointer should + not be dropped. See IReferenceCounted::drop() for more + information. */ + virtual ITerrainSceneNode* addTerrainSceneNode( + const io::path& heightMapFileName, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17, s32 smoothFactor=0, + bool addAlsoIfHeightmapEmpty = false) = 0; + + //! Adds a terrain scene node to the scene graph. + /** Just like the other addTerrainSceneNode() method, but takes an IReadFile + pointer as parameter for the heightmap. For more informations take a look + at the other function. + \param heightMapFile: The file handle to read vertex data from. This should + be a gray scale bitmap. + \param parent: Parent of the scene node. Can be 0 if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: The absolute position of this node. + \param rotation: The absolute rotation of this node. ( NOT YET IMPLEMENTED ) + \param scale: The scale factor for the terrain. If you're + using a heightmap of size 129x129 and would like your terrain + to be 12900x12900 in game units, then use a scale factor of ( + core::vector ( 100.0f, 100.0f, 100.0f ). If you use a Y + scaling factor of 0.0f, then your terrain will be flat. + \param vertexColor: The default color of all the vertices. If no texture is associated + with the scene node, then all vertices will be this color. Defaults to white. + \param maxLOD: The maximum LOD (level of detail) for the node. Only change if you + know what you are doing, this might lead to strange behavior. + \param patchSize: patch size of the terrain. Only change if you + know what you are doing, this might lead to strange behavior. + \param smoothFactor: The number of times the vertices are smoothed. + \param addAlsoIfHeightmapEmpty: Add terrain node even with empty heightmap. + \return Pointer to the created scene node. Can be null + if the terrain could not be created, for example because the + heightmap could not be loaded. The returned pointer should + not be dropped. See IReferenceCounted::drop() for more + information. */ + virtual ITerrainSceneNode* addTerrainSceneNode( + io::IReadFile* heightMapFile, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17, s32 smoothFactor=0, + bool addAlsoIfHeightmapEmpty = false) = 0; + + //! Adds a quake3 scene node to the scene graph. + /** A Quake3 Scene renders multiple meshes for a specific HighLanguage Shader (Quake3 Style ) + \return Pointer to the quake3 scene node if successful, otherwise NULL. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IMeshSceneNode* addQuake3SceneNode(const IMeshBuffer* meshBuffer, const quake3::IShader * shader, + ISceneNode* parent=0, s32 id=-1 + ) = 0; + + + //! Adds an empty scene node to the scene graph. + /** Can be used for doing advanced transformations + or structuring the scene graph. + \return Pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addEmptySceneNode(ISceneNode* parent=0, s32 id=-1) = 0; + + //! Adds a dummy transformation scene node to the scene graph. + /** This scene node does not render itself, and does not respond to set/getPosition, + set/getRotation and set/getScale. Its just a simple scene node that takes a + matrix as relative transformation, making it possible to insert any transformation + anywhere into the scene graph. + \return Pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IDummyTransformationSceneNode* addDummyTransformationSceneNode( + ISceneNode* parent=0, s32 id=-1) = 0; + + //! Adds a text scene node, which is able to display 2d text at a position in three dimensional space + virtual ITextSceneNode* addTextSceneNode(gui::IGUIFont* font, const wchar_t* text, + video::SColor color=video::SColor(100,255,255,255), + ISceneNode* parent = 0, const core::vector3df& position = core::vector3df(0,0,0), + s32 id=-1) = 0; + + //! Adds a text scene node, which uses billboards. The node, and the text on it, will scale with distance. + /** + \param font The font to use on the billboard. Pass 0 to use the GUI environment's default font. + \param text The text to display on the billboard. + \param parent The billboard's parent. Pass 0 to use the root scene node. + \param size The billboard's width and height. + \param position The billboards position relative to its parent. + \param id: An id of the node. This id can be used to identify the node. + \param colorTop: The color of the vertices at the top of the billboard (default: white). + \param colorBottom: The color of the vertices at the bottom of the billboard (default: white). + \return Pointer to the billboard if successful, otherwise NULL. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IBillboardTextSceneNode* addBillboardTextSceneNode( gui::IGUIFont* font, const wchar_t* text, + ISceneNode* parent = 0, + const core::dimension2d<f32>& size = core::dimension2d<f32>(10.0f, 10.0f), + const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1, + video::SColor colorTop = 0xFFFFFFFF, video::SColor colorBottom = 0xFFFFFFFF) = 0; + + //! Adds a Hill Plane mesh to the mesh pool. + /** The mesh is generated on the fly + and looks like a plane with some hills on it. It is uses mostly for quick + tests of the engine only. You can specify how many hills there should be + on the plane and how high they should be. Also you must specify a name for + the mesh, because the mesh is added to the mesh pool, and can be retrieved + again using ISceneManager::getMesh() with the name as parameter. + \param name: The name of this mesh which must be specified in order + to be able to retrieve the mesh later with ISceneManager::getMesh(). + \param tileSize: Size of a tile of the mesh. (10.0f, 10.0f) would be a + good value to start, for example. + \param tileCount: Specifies how much tiles there will be. If you specifiy + for example that a tile has the size (10.0f, 10.0f) and the tileCount is + (10,10), than you get a field of 100 tiles which has the dimension 100.0fx100.0f. + \param material: Material of the hill mesh. + \param hillHeight: Height of the hills. If you specify a negative value + you will get holes instead of hills. If the height is 0, no hills will be + created. + \param countHills: Amount of hills on the plane. There will be countHills.X + hills along the X axis and countHills.Y along the Y axis. So in total there + will be countHills.X * countHills.Y hills. + \param textureRepeatCount: Defines how often the texture will be repeated in + x and y direction. + return Null if the creation failed. The reason could be that you + specified some invalid parameters or that a mesh with that name already + exists. If successful, a pointer to the mesh is returned. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IAnimatedMesh* addHillPlaneMesh(const io::path& name, + const core::dimension2d<f32>& tileSize, const core::dimension2d<u32>& tileCount, + video::SMaterial* material = 0, f32 hillHeight = 0.0f, + const core::dimension2d<f32>& countHills = core::dimension2d<f32>(0.0f, 0.0f), + const core::dimension2d<f32>& textureRepeatCount = core::dimension2d<f32>(1.0f, 1.0f)) = 0; + + //! Adds a static terrain mesh to the mesh pool. + /** The mesh is generated on the fly + from a texture file and a height map file. Both files may be huge + (8000x8000 pixels would be no problem) because the generator splits the + files into smaller textures if necessary. + You must specify a name for the mesh, because the mesh is added to the mesh pool, + and can be retrieved again using ISceneManager::getMesh() with the name as parameter. + \param meshname: The name of this mesh which must be specified in order + to be able to retrieve the mesh later with ISceneManager::getMesh(). + \param texture: Texture for the terrain. Please note that this is not a + hardware texture as usual (ITexture), but an IImage software texture. + You can load this texture with IVideoDriver::createImageFromFile(). + \param heightmap: A grayscaled heightmap image. Like the texture, + it can be created with IVideoDriver::createImageFromFile(). The amount + of triangles created depends on the size of this texture, so use a small + heightmap to increase rendering speed. + \param stretchSize: Parameter defining how big a is pixel on the heightmap. + \param maxHeight: Defines how high a white pixel on the heighmap is. + \param defaultVertexBlockSize: Defines the initial dimension between vertices. + \return Null if the creation failed. The reason could be that you + specified some invalid parameters, that a mesh with that name already + exists, or that a texture could not be found. If successful, a pointer to the mesh is returned. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IAnimatedMesh* addTerrainMesh(const io::path& meshname, + video::IImage* texture, video::IImage* heightmap, + const core::dimension2d<f32>& stretchSize = core::dimension2d<f32>(10.0f,10.0f), + f32 maxHeight=200.0f, + const core::dimension2d<u32>& defaultVertexBlockSize = core::dimension2d<u32>(64,64)) = 0; + + //! add a static arrow mesh to the meshpool + /** \param name Name of the mesh + \param vtxColorCylinder color of the cylinder + \param vtxColorCone color of the cone + \param tesselationCylinder Number of quads the cylinder side consists of + \param tesselationCone Number of triangles the cone's roof consits of + \param height Total height of the arrow + \param cylinderHeight Total height of the cylinder, should be lesser than total height + \param widthCylinder Diameter of the cylinder + \param widthCone Diameter of the cone's base, should be not smaller than the cylinder's diameter + \return Pointer to the arrow mesh if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IAnimatedMesh* addArrowMesh(const io::path& name, + video::SColor vtxColorCylinder=0xFFFFFFFF, + video::SColor vtxColorCone=0xFFFFFFFF, + u32 tesselationCylinder=4, u32 tesselationCone=8, + f32 height=1.f, f32 cylinderHeight=0.6f, + f32 widthCylinder=0.05f, f32 widthCone=0.3f) = 0; + + //! add a static sphere mesh to the meshpool + /** \param name Name of the mesh + \param radius Radius of the sphere + \param polyCountX Number of quads used for the horizontal tiling + \param polyCountY Number of quads used for the vertical tiling + \return Pointer to the sphere mesh if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IAnimatedMesh* addSphereMesh(const io::path& name, + f32 radius=5.f, u32 polyCountX = 16, + u32 polyCountY = 16) = 0; + + //! Add a volume light mesh to the meshpool + /** \param name Name of the mesh + \param SubdivideU Horizontal subdivision count + \param SubdivideV Vertical subdivision count + \param FootColor Color of the bottom of the light + \param TailColor Color of the top of the light + \return Pointer to the volume light mesh if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. + */ + virtual IAnimatedMesh* addVolumeLightMesh(const io::path& name, + const u32 SubdivideU = 32, const u32 SubdivideV = 32, + const video::SColor FootColor = video::SColor(51, 0, 230, 180), + const video::SColor TailColor = video::SColor(0, 0, 0, 0)) = 0; + + //! Gets the root scene node. + /** This is the scene node which is parent + of all scene nodes. The root scene node is a special scene node which + only exists to manage all scene nodes. It will not be rendered and cannot + be removed from the scene. + \return Pointer to the root scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* getRootSceneNode() = 0; + + //! Get the first scene node with the specified id. + /** \param id: The id to search for + \param start: Scene node to start from. All children of this scene + node are searched. If null is specified, the root scene node is + taken. + \return Pointer to the first scene node with this id, + and null if no scene node could be found. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* getSceneNodeFromId(s32 id, ISceneNode* start=0) = 0; + + //! Get the first scene node with the specified name. + /** \param name: The name to search for + \param start: Scene node to start from. All children of this scene + node are searched. If null is specified, the root scene node is + taken. + \return Pointer to the first scene node with this id, + and null if no scene node could be found. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* getSceneNodeFromName(const c8* name, ISceneNode* start=0) = 0; + + //! Get the first scene node with the specified type. + /** \param type: The type to search for + \param start: Scene node to start from. All children of this scene + node are searched. If null is specified, the root scene node is + taken. + \return Pointer to the first scene node with this type, + and null if no scene node could be found. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start=0) = 0; + + //! Get scene nodes by type. + /** \param type: Type of scene node to find (ESNT_ANY will return all child nodes). + \param outNodes: array to be filled with results. + \param start: Scene node to start from. All children of this scene + node are searched. If null is specified, the root scene node is + taken. */ + virtual void getSceneNodesFromType(ESCENE_NODE_TYPE type, + core::array<scene::ISceneNode*>& outNodes, + ISceneNode* start=0) = 0; + + //! Get the current active camera. + /** \return The active camera is returned. Note that this can + be NULL, if there was no camera created yet. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ICameraSceneNode* getActiveCamera() const =0; + + //! Sets the currently active camera. + /** The previous active camera will be deactivated. + \param camera: The new camera which should be active. */ + virtual void setActiveCamera(ICameraSceneNode* camera) = 0; + + //! Sets the color of stencil buffers shadows drawn by the scene manager. + virtual void setShadowColor(video::SColor color = video::SColor(150,0,0,0)) = 0; + + //! Get the current color of shadows. + virtual video::SColor getShadowColor() const = 0; + + //! Registers a node for rendering it at a specific time. + /** This method should only be used by SceneNodes when they get a + ISceneNode::OnRegisterSceneNode() call. + \param node: Node to register for drawing. Usually scene nodes would set 'this' + as parameter here because they want to be drawn. + \param pass: Specifies when the node wants to be drawn in relation to the other nodes. + For example, if the node is a shadow, it usually wants to be drawn after all other nodes + and will use ESNRP_SHADOW for this. See scene::E_SCENE_NODE_RENDER_PASS for details. + \return scene will be rendered ( passed culling ) */ + virtual u32 registerNodeForRendering(ISceneNode* node, + E_SCENE_NODE_RENDER_PASS pass = ESNRP_AUTOMATIC) = 0; + + //! Draws all the scene nodes. + /** This can only be invoked between + IVideoDriver::beginScene() and IVideoDriver::endScene(). Please note that + the scene is not only drawn when calling this, but also animated + by existing scene node animators, culling of scene nodes is done, etc. */ + virtual void drawAll() = 0; + + //! Creates a rotation animator, which rotates the attached scene node around itself. + /** \param rotationSpeed Specifies the speed of the animation in degree per 10 milliseconds. + \return The animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will animate it. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimator* createRotationAnimator(const core::vector3df& rotationSpeed) = 0; + + //! Creates a fly circle animator, which lets the attached scene node fly around a center. + /** \param center: Center of the circle. + \param radius: Radius of the circle. + \param speed: The orbital speed, in radians per millisecond. + \param direction: Specifies the upvector used for alignment of the mesh. + \param startPosition: The position on the circle where the animator will + begin. Value is in multiples of a circle, i.e. 0.5 is half way around. (phase) + \param radiusEllipsoid: if radiusEllipsoid != 0 then radius2 froms a ellipsoid + begin. Value is in multiples of a circle, i.e. 0.5 is half way around. (phase) + \return The animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will animate it. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimator* createFlyCircleAnimator( + const core::vector3df& center=core::vector3df(0.f,0.f,0.f), + f32 radius=100.f, f32 speed=0.001f, + const core::vector3df& direction=core::vector3df(0.f, 1.f, 0.f), + f32 startPosition = 0.f, + f32 radiusEllipsoid = 0.f) = 0; + + //! Creates a fly straight animator, which lets the attached scene node fly or move along a line between two points. + /** \param startPoint: Start point of the line. + \param endPoint: End point of the line. + \param timeForWay: Time in milli seconds how long the node should need to + move from the start point to the end point. + \param loop: If set to false, the node stops when the end point is reached. + If loop is true, the node begins again at the start. + \param pingpong Flag to set whether the animator should fly + back from end to start again. + \return The animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will animate it. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimator* createFlyStraightAnimator(const core::vector3df& startPoint, + const core::vector3df& endPoint, u32 timeForWay, bool loop=false, bool pingpong = false) = 0; + + //! Creates a texture animator, which switches the textures of the target scene node based on a list of textures. + /** \param textures: List of textures to use. + \param timePerFrame: Time in milliseconds, how long any texture in the list + should be visible. + \param loop: If set to to false, the last texture remains set, and the animation + stops. If set to true, the animation restarts with the first texture. + \return The animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will animate it. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimator* createTextureAnimator(const core::array<video::ITexture*>& textures, + s32 timePerFrame, bool loop=true) = 0; + + //! Creates a scene node animator, which deletes the scene node after some time automatically. + /** \param timeMs: Time in milliseconds, after when the node will be deleted. + \return The animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will animate it. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimator* createDeleteAnimator(u32 timeMs) = 0; + + //! Creates a special scene node animator for doing automatic collision detection and response. + /** See ISceneNodeAnimatorCollisionResponse for details. + \param world: Triangle selector holding all triangles of the world with which + the scene node may collide. You can create a triangle selector with + ISceneManager::createTriangleSelector(); + \param sceneNode: SceneNode which should be manipulated. After you added this animator + to the scene node, the scene node will not be able to move through walls and is + affected by gravity. If you need to teleport the scene node to a new position without + it being effected by the collision geometry, then call sceneNode->setPosition(); then + animator->setTargetNode(sceneNode); + \param ellipsoidRadius: Radius of the ellipsoid with which collision detection and + response is done. If you have got a scene node, and you are unsure about + how big the radius should be, you could use the following code to determine + it: + \code + const core::aabbox3d<f32>& box = yourSceneNode->getBoundingBox(); + core::vector3df radius = box.MaxEdge - box.getCenter(); + \endcode + \param gravityPerSecond: Sets the gravity of the environment, as an acceleration in + units per second per second. If your units are equivalent to metres, then + core::vector3df(0,-10.0f,0) would give an approximately realistic gravity. + You can disable gravity by setting it to core::vector3df(0,0,0). + \param ellipsoidTranslation: By default, the ellipsoid for collision detection is created around + the center of the scene node, which means that the ellipsoid surrounds + it completely. If this is not what you want, you may specify a translation + for the ellipsoid. + \param slidingValue: DOCUMENTATION NEEDED. + \return The animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will cause it to do collision detection and response. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimatorCollisionResponse* createCollisionResponseAnimator( + ITriangleSelector* world, ISceneNode* sceneNode, + const core::vector3df& ellipsoidRadius = core::vector3df(30,60,30), + const core::vector3df& gravityPerSecond = core::vector3df(0,-10.0f,0), + const core::vector3df& ellipsoidTranslation = core::vector3df(0,0,0), + f32 slidingValue = 0.0005f) = 0; + + //! Creates a follow spline animator. + /** The animator modifies the position of + the attached scene node to make it follow a hermite spline. + It uses a subset of hermite splines: either cardinal splines + (tightness != 0.5) or catmull-rom-splines (tightness == 0.5). + The animator moves from one control point to the next in + 1/speed seconds. This code was sent in by Matthias Gall. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime, + const core::array< core::vector3df >& points, + f32 speed = 1.0f, f32 tightness = 0.5f, bool loop=true, bool pingpong=false) = 0; + + //! Creates a simple ITriangleSelector, based on a mesh. + /** Triangle selectors + can be used for doing collision detection. Don't use this selector + for a huge amount of triangles like in Quake3 maps. + Instead, use for example ISceneManager::createOctreeTriangleSelector(). + Please note that the created triangle selector is not automaticly attached + to the scene node. You will have to call ISceneNode::setTriangleSelector() + for this. To create and attach a triangle selector is done like this: + \code + ITriangleSelector* s = sceneManager->createTriangleSelector(yourMesh, + yourSceneNode); + yourSceneNode->setTriangleSelector(s); + s->drop(); + \endcode + \param mesh: Mesh of which the triangles are taken. + \param node: Scene node of which visibility and transformation is used. + \return The selector, or null if not successful. + If you no longer need the selector, you should call ITriangleSelector::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node) = 0; + + //! Creates a simple ITriangleSelector, based on an animated mesh scene node. + /** Details of the mesh associated with the node will be extracted internally. + Call ITriangleSelector::update() to have the triangle selector updated based + on the current frame of the animated mesh scene node. + \param node The animated mesh scene node from which to build the selector + */ + virtual ITriangleSelector* createTriangleSelector(IAnimatedMeshSceneNode* node) = 0; + + + //! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box. + /** Triangle selectors + can be used for doing collision detection. Every time when triangles are + queried, the triangle selector gets the bounding box of the scene node, + an creates new triangles. In this way, it works good with animated scene nodes. + \param node: Scene node of which the bounding box, visibility and transformation is used. + \return The selector, or null if not successful. + If you no longer need the selector, you should call ITriangleSelector::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ITriangleSelector* createTriangleSelectorFromBoundingBox(ISceneNode* node) = 0; + + //! Creates a Triangle Selector, optimized by an octree. + /** Triangle selectors + can be used for doing collision detection. This triangle selector is + optimized for huge amounts of triangle, it organizes them in an octree. + Please note that the created triangle selector is not automaticly attached + to the scene node. You will have to call ISceneNode::setTriangleSelector() + for this. To create and attach a triangle selector is done like this: + \code + ITriangleSelector* s = sceneManager->createOctreeTriangleSelector(yourMesh, + yourSceneNode); + yourSceneNode->setTriangleSelector(s); + s->drop(); + \endcode + For more informations and examples on this, take a look at the collision + tutorial in the SDK. + \param mesh: Mesh of which the triangles are taken. + \param node: Scene node of which visibility and transformation is used. + \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node. + If a node gets less polys the this value, it will not be splitted into + smaller nodes. + \return The selector, or null if not successful. + If you no longer need the selector, you should call ITriangleSelector::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ITriangleSelector* createOctreeTriangleSelector(IMesh* mesh, + ISceneNode* node, s32 minimalPolysPerNode=32) = 0; + + //! //! Creates a Triangle Selector, optimized by an octree. + /** \deprecated Use createOctreeTriangleSelector instead. This method may be removed by Irrlicht 1.9. */ + _IRR_DEPRECATED_ ITriangleSelector* createOctTreeTriangleSelector(IMesh* mesh, + ISceneNode* node, s32 minimalPolysPerNode=32) + { + return createOctreeTriangleSelector(mesh, node, minimalPolysPerNode); + } + + //! Creates a meta triangle selector. + /** A meta triangle selector is nothing more than a + collection of one or more triangle selectors providing together + the interface of one triangle selector. In this way, + collision tests can be done with different triangle soups in one pass. + \return The selector, or null if not successful. + If you no longer need the selector, you should call ITriangleSelector::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IMetaTriangleSelector* createMetaTriangleSelector() = 0; + + //! Creates a triangle selector which can select triangles from a terrain scene node. + /** \param node: Pointer to the created terrain scene node + \param LOD: Level of detail, 0 for highest detail. + \return The selector, or null if not successful. + If you no longer need the selector, you should call ITriangleSelector::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ITriangleSelector* createTerrainTriangleSelector( + ITerrainSceneNode* node, s32 LOD=0) = 0; + + //! Adds an external mesh loader for extending the engine with new file formats. + /** If you want the engine to be extended with + file formats it currently is not able to load (e.g. .cob), just implement + the IMeshLoader interface in your loading class and add it with this method. + Using this method it is also possible to override built-in mesh loaders with + newer or updated versions without the need to recompile the engine. + \param externalLoader: Implementation of a new mesh loader. */ + virtual void addExternalMeshLoader(IMeshLoader* externalLoader) = 0; + + //! Returns the number of mesh loaders supported by Irrlicht at this time + virtual u32 getMeshLoaderCount() const = 0; + + //! Retrieve the given mesh loader + /** \param index The index of the loader to retrieve. This parameter is an 0-based + array index. + \return A pointer to the specified loader, 0 if the index is incorrect. */ + virtual IMeshLoader* getMeshLoader(u32 index) const = 0; + + //! Adds an external scene loader for extending the engine with new file formats. + /** If you want the engine to be extended with + file formats it currently is not able to load (e.g. .vrml), just implement + the ISceneLoader interface in your loading class and add it with this method. + Using this method it is also possible to override the built-in scene loaders + with newer or updated versions without the need to recompile the engine. + \param externalLoader: Implementation of a new mesh loader. */ + virtual void addExternalSceneLoader(ISceneLoader* externalLoader) = 0; + + //! Returns the number of scene loaders supported by Irrlicht at this time + virtual u32 getSceneLoaderCount() const = 0; + + //! Retrieve the given scene loader + /** \param index The index of the loader to retrieve. This parameter is an 0-based + array index. + \return A pointer to the specified loader, 0 if the index is incorrect. */ + virtual ISceneLoader* getSceneLoader(u32 index) const = 0; + + //! Get pointer to the scene collision manager. + /** \return Pointer to the collision manager + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneCollisionManager* getSceneCollisionManager() = 0; + + //! Get pointer to the mesh manipulator. + /** \return Pointer to the mesh manipulator + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IMeshManipulator* getMeshManipulator() = 0; + + //! Adds a scene node to the deletion queue. + /** The scene node is immediatly + deleted when it's secure. Which means when the scene node does not + execute animators and things like that. This method is for example + used for deleting scene nodes by their scene node animators. In + most other cases, a ISceneNode::remove() call is enough, using this + deletion queue is not necessary. + See ISceneManager::createDeleteAnimator() for details. + \param node: Node to detete. */ + virtual void addToDeletionQueue(ISceneNode* node) = 0; + + //! Posts an input event to the environment. + /** Usually you do not have to + use this method, it is used by the internal engine. */ + virtual bool postEventFromUser(const SEvent& event) = 0; + + //! Clears the whole scene. + /** All scene nodes are removed. */ + virtual void clear() = 0; + + //! Get interface to the parameters set in this scene. + /** String parameters can be used by plugins and mesh loaders. + For example the CMS and LMTS loader want a parameter named 'CSM_TexturePath' + and 'LMTS_TexturePath' set to the path were attached textures can be found. See + CSM_TEXTURE_PATH, LMTS_TEXTURE_PATH, MY3D_TEXTURE_PATH, + COLLADA_CREATE_SCENE_INSTANCES, DMF_TEXTURE_PATH and DMF_USE_MATERIALS_DIRS*/ + virtual io::IAttributes* getParameters() = 0; + + //! Get current render pass. + /** All scene nodes are being rendered in a specific order. + First lights, cameras, sky boxes, solid geometry, and then transparent + stuff. During the rendering process, scene nodes may want to know what the scene + manager is rendering currently, because for example they registered for rendering + twice, once for transparent geometry and once for solid. When knowing what rendering + pass currently is active they can render the correct part of their geometry. */ + virtual E_SCENE_NODE_RENDER_PASS getSceneNodeRenderPass() const = 0; + + //! Get the default scene node factory which can create all built in scene nodes + /** \return Pointer to the default scene node factory + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeFactory* getDefaultSceneNodeFactory() = 0; + + //! Adds a scene node factory to the scene manager. + /** Use this to extend the scene manager with new scene node types which it should be + able to create automaticly, for example when loading data from xml files. */ + virtual void registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd) = 0; + + //! Get amount of registered scene node factories. + virtual u32 getRegisteredSceneNodeFactoryCount() const = 0; + + //! Get a scene node factory by index + /** \return Pointer to the requested scene node factory, or 0 if it does not exist. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeFactory* getSceneNodeFactory(u32 index) = 0; + + //! Get the default scene node animator factory which can create all built-in scene node animators + /** \return Pointer to the default scene node animator factory + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimatorFactory* getDefaultSceneNodeAnimatorFactory() = 0; + + //! Adds a scene node animator factory to the scene manager. + /** Use this to extend the scene manager with new scene node animator types which it should be + able to create automaticly, for example when loading data from xml files. */ + virtual void registerSceneNodeAnimatorFactory(ISceneNodeAnimatorFactory* factoryToAdd) = 0; + + //! Get amount of registered scene node animator factories. + virtual u32 getRegisteredSceneNodeAnimatorFactoryCount() const = 0; + + //! Get scene node animator factory by index + /** \return Pointer to the requested scene node animator factory, or 0 if it does not exist. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimatorFactory* getSceneNodeAnimatorFactory(u32 index) = 0; + + //! Get typename from a scene node type or null if not found + virtual const c8* getSceneNodeTypeName(ESCENE_NODE_TYPE type) = 0; + + //! Returns a typename from a scene node animator type or null if not found + virtual const c8* getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) = 0; + + //! Adds a scene node to the scene by name + /** \return Pointer to the scene node added by a factory + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent=0) = 0; + + //! creates a scene node animator based on its type name + /** \param typeName: Type of the scene node animator to add. + \param target: Target scene node of the new animator. + \return Returns pointer to the new scene node animator or null if not successful. You need to + drop this pointer after calling this, see IReferenceCounted::drop() for details. */ + virtual ISceneNodeAnimator* createSceneNodeAnimator(const char* typeName, ISceneNode* target=0) = 0; + + //! Creates a new scene manager. + /** This can be used to easily draw and/or store two + independent scenes at the same time. The mesh cache will be + shared between all existing scene managers, which means if you + load a mesh in the original scene manager using for example + getMesh(), the mesh will be available in all other scene + managers too, without loading. + The original/main scene manager will still be there and + accessible via IrrlichtDevice::getSceneManager(). If you need + input event in this new scene manager, for example for FPS + cameras, you'll need to forward input to this manually: Just + implement an IEventReceiver and call + yourNewSceneManager->postEventFromUser(), and return true so + that the original scene manager doesn't get the event. + Otherwise, all input will go to the main scene manager + automatically. + If you no longer need the new scene manager, you should call + ISceneManager::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneManager* createNewSceneManager(bool cloneContent=false) = 0; + + //! Saves the current scene into a file. + /** Scene nodes with the option isDebugObject set to true are + not being saved. The scene is usually written to an .irr file, + an xml based format. .irr files can Be edited with the Irrlicht + Engine Editor, irrEdit (http://www.ambiera.com/irredit/). To + load .irr files again, see ISceneManager::loadScene(). + \param filename Name of the file. + \param userDataSerializer If you want to save some user data + for every scene node into the file, implement the + ISceneUserDataSerializer interface and provide it as parameter + here. Otherwise, simply specify 0 as this parameter. + \param node Node which is taken as the top node of the scene. + This node and all of its descendants are saved into the scene + file. Pass 0 or the scene manager to save the full scene (which + is also the default). + \return True if successful. */ + virtual bool saveScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* node=0) = 0; + + //! Saves the current scene into a file. + /** Scene nodes with the option isDebugObject set to true are + not being saved. The scene is usually written to an .irr file, + an xml based format. .irr files can Be edited with the Irrlicht + Engine Editor, irrEdit (http://www.ambiera.com/irredit/). To + load .irr files again, see ISceneManager::loadScene(). + \param file File where the scene is saved into. + \param userDataSerializer If you want to save some user data + for every scene node into the file, implement the + ISceneUserDataSerializer interface and provide it as parameter + here. Otherwise, simply specify 0 as this parameter. + \param node Node which is taken as the top node of the scene. + This node and all of its descendants are saved into the scene + file. Pass 0 or the scene manager to save the full scene (which + is also the default). + \return True if successful. */ + virtual bool saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* node=0) = 0; + + //! Saves the current scene into a file. + /** Scene nodes with the option isDebugObject set to true are + not being saved. The scene is usually written to an .irr file, + an xml based format. .irr files can Be edited with the Irrlicht + Engine Editor, irrEdit (http://www.ambiera.com/irredit/). To + load .irr files again, see ISceneManager::loadScene(). + \param writer XMLWriter with which the scene is saved. + \param currentPath Path which is used for relative file names. + Usually the directory of the file written into. + \param userDataSerializer If you want to save some user data + for every scene node into the file, implement the + ISceneUserDataSerializer interface and provide it as parameter + here. Otherwise, simply specify 0 as this parameter. + \param node Node which is taken as the top node of the scene. + This node and all of its descendants are saved into the scene + file. Pass 0 or the scene manager to save the full scene (which + is also the default). + \return True if successful. */ + virtual bool saveScene(io::IXMLWriter* writer, const io::path& currentPath, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* node=0) = 0; + + //! Loads a scene. Note that the current scene is not cleared before. + /** The scene is usually loaded from an .irr file, an xml based + format, but other scene formats can be added to the engine via + ISceneManager::addExternalSceneLoader. .irr files can Be edited + with the Irrlicht Engine Editor, irrEdit + (http://www.ambiera.com/irredit/) or saved directly by the engine + using ISceneManager::saveScene(). + \param filename Name of the file to load from. + \param userDataSerializer If you want to load user data + possibily saved in that file for some scene nodes in the file, + implement the ISceneUserDataSerializer interface and provide it + as parameter here. Otherwise, simply specify 0 as this + parameter. + \param rootNode Node which is taken as the root node of the + scene. Pass 0 to add the scene directly to the scene manager + (which is also the default). + \return True if successful. */ + virtual bool loadScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* rootNode=0) = 0; + + //! Loads a scene. Note that the current scene is not cleared before. + /** The scene is usually loaded from an .irr file, an xml based + format, but other scene formats can be added to the engine via + ISceneManager::addExternalSceneLoader. .irr files can Be edited + with the Irrlicht Engine Editor, irrEdit + (http://www.ambiera.com/irredit/) or saved directly by the engine + using ISceneManager::saveScene(). + \param file File where the scene is loaded from. + \param userDataSerializer If you want to load user data + possibily saved in that file for some scene nodes in the file, + implement the ISceneUserDataSerializer interface and provide it + as parameter here. Otherwise, simply specify 0 as this + parameter. + \param rootNode Node which is taken as the root node of the + scene. Pass 0 to add the scene directly to the scene manager + (which is also the default). + \return True if successful. */ + virtual bool loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* rootNode=0) = 0; + + //! Get a mesh writer implementation if available + /** Note: You need to drop() the pointer after use again, see IReferenceCounted::drop() + for details. */ + virtual IMeshWriter* createMeshWriter(EMESH_WRITER_TYPE type) = 0; + + //! Get a skinned mesh, which is not available as header-only code + /** Note: You need to drop() the pointer after use again, see IReferenceCounted::drop() + for details. */ + virtual ISkinnedMesh* createSkinnedMesh() = 0; + + //! Sets ambient color of the scene + virtual void setAmbientLight(const video::SColorf &ambientColor) = 0; + + //! Get ambient color of the scene + virtual const video::SColorf& getAmbientLight() const = 0; + + //! Register a custom callbacks manager which gets callbacks during scene rendering. + /** \param[in] lightManager: the new callbacks manager. You may pass 0 to remove the + current callbacks manager and restore the default behavior. */ + virtual void setLightManager(ILightManager* lightManager) = 0; + + //! Get an instance of a geometry creator. + /** The geometry creator provides some helper methods to create various types of + basic geometry. This can be useful for custom scene nodes. */ + virtual const IGeometryCreator* getGeometryCreator(void) const = 0; + + //! Check if node is culled in current view frustum + /** Please note that depending on the used culling method this + check can be rather coarse, or slow. A positive result is + correct, though, i.e. if this method returns true the node is + positively not visible. The node might still be invisible even + if this method returns false. + \param node The scene node which is checked for culling. + \return True if node is not visible in the current scene, else + false. */ + virtual bool isCulled(const ISceneNode* node) const =0; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISceneNode.h b/builddir/irrlicht-1.8.1/include/ISceneNode.h new file mode 100644 index 0000000..63d74f0 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISceneNode.h @@ -0,0 +1,858 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_H_INCLUDED__ +#define __I_SCENE_NODE_H_INCLUDED__ + +#include "IAttributeExchangingObject.h" +#include "ESceneNodeTypes.h" +#include "ECullingTypes.h" +#include "EDebugSceneTypes.h" +#include "ISceneNodeAnimator.h" +#include "ITriangleSelector.h" +#include "SMaterial.h" +#include "irrString.h" +#include "aabbox3d.h" +#include "matrix4.h" +#include "irrList.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + class ISceneManager; + + //! Typedef for list of scene nodes + typedef core::list<ISceneNode*> ISceneNodeList; + //! Typedef for list of scene node animators + typedef core::list<ISceneNodeAnimator*> ISceneNodeAnimatorList; + + //! Scene node interface. + /** A scene node is a node in the hierarchical scene graph. Every scene + node may have children, which are also scene nodes. Children move + relative to their parent's position. If the parent of a node is not + visible, its children won't be visible either. In this way, it is for + example easily possible to attach a light to a moving car, or to place + a walking character on a moving platform on a moving ship. + */ + class ISceneNode : virtual public io::IAttributeExchangingObject + { + public: + + //! Constructor + ISceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) + : RelativeTranslation(position), RelativeRotation(rotation), RelativeScale(scale), + Parent(0), SceneManager(mgr), TriangleSelector(0), ID(id), + AutomaticCullingState(EAC_BOX), DebugDataVisible(EDS_OFF), + IsVisible(true), IsDebugObject(false) + { + if (parent) + parent->addChild(this); + + updateAbsolutePosition(); + } + + + //! Destructor + virtual ~ISceneNode() + { + // delete all children + removeAll(); + + // delete all animators + ISceneNodeAnimatorList::Iterator ait = Animators.begin(); + for (; ait != Animators.end(); ++ait) + (*ait)->drop(); + + if (TriangleSelector) + TriangleSelector->drop(); + } + + + //! This method is called just before the rendering process of the whole scene. + /** Nodes may register themselves in the render pipeline during this call, + precalculate the geometry which should be renderered, and prevent their + children from being able to register themselves if they are clipped by simply + not calling their OnRegisterSceneNode method. + If you are implementing your own scene node, you should overwrite this method + with an implementation code looking like this: + \code + if (IsVisible) + SceneManager->registerNodeForRendering(this); + + ISceneNode::OnRegisterSceneNode(); + \endcode + */ + virtual void OnRegisterSceneNode() + { + if (IsVisible) + { + ISceneNodeList::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->OnRegisterSceneNode(); + } + } + + + //! OnAnimate() is called just before rendering the whole scene. + /** Nodes may calculate or store animations here, and may do other useful things, + depending on what they are. Also, OnAnimate() should be called for all + child scene nodes here. This method will be called once per frame, independent + of whether the scene node is visible or not. + \param timeMs Current time in milliseconds. */ + virtual void OnAnimate(u32 timeMs) + { + if (IsVisible) + { + // animate this node with all animators + + ISceneNodeAnimatorList::Iterator ait = Animators.begin(); + while (ait != Animators.end()) + { + // continue to the next node before calling animateNode() + // so that the animator may remove itself from the scene + // node without the iterator becoming invalid + ISceneNodeAnimator* anim = *ait; + ++ait; + anim->animateNode(this, timeMs); + } + + // update absolute position + updateAbsolutePosition(); + + // perform the post render process on all children + + ISceneNodeList::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->OnAnimate(timeMs); + } + } + + + //! Renders the node. + virtual void render() = 0; + + + //! Returns the name of the node. + /** \return Name as character string. */ + virtual const c8* getName() const + { + return Name.c_str(); + } + + + //! Sets the name of the node. + /** \param name New name of the scene node. */ + virtual void setName(const c8* name) + { + Name = name; + } + + + //! Sets the name of the node. + /** \param name New name of the scene node. */ + virtual void setName(const core::stringc& name) + { + Name = name; + } + + + //! Get the axis aligned, not transformed bounding box of this node. + /** This means that if this node is an animated 3d character, + moving in a room, the bounding box will always be around the + origin. To get the box in real world coordinates, just + transform it with the matrix you receive with + getAbsoluteTransformation() or simply use + getTransformedBoundingBox(), which does the same. + \return The non-transformed bounding box. */ + virtual const core::aabbox3d<f32>& getBoundingBox() const = 0; + + + //! Get the axis aligned, transformed and animated absolute bounding box of this node. + /** \return The transformed bounding box. */ + virtual const core::aabbox3d<f32> getTransformedBoundingBox() const + { + core::aabbox3d<f32> box = getBoundingBox(); + AbsoluteTransformation.transformBoxEx(box); + return box; + } + + + //! Get the absolute transformation of the node. Is recalculated every OnAnimate()-call. + /** NOTE: For speed reasons the absolute transformation is not + automatically recalculated on each change of the relative + transformation or by a transformation change of an parent. Instead the + update usually happens once per frame in OnAnimate. You can enforce + an update with updateAbsolutePosition(). + \return The absolute transformation matrix. */ + virtual const core::matrix4& getAbsoluteTransformation() const + { + return AbsoluteTransformation; + } + + + //! Returns the relative transformation of the scene node. + /** The relative transformation is stored internally as 3 + vectors: translation, rotation and scale. To get the relative + transformation matrix, it is calculated from these values. + \return The relative transformation matrix. */ + virtual core::matrix4 getRelativeTransformation() const + { + core::matrix4 mat; + mat.setRotationDegrees(RelativeRotation); + mat.setTranslation(RelativeTranslation); + + if (RelativeScale != core::vector3df(1.f,1.f,1.f)) + { + core::matrix4 smat; + smat.setScale(RelativeScale); + mat *= smat; + } + + return mat; + } + + + //! Returns whether the node should be visible (if all of its parents are visible). + /** This is only an option set by the user, but has nothing to + do with geometry culling + \return The requested visibility of the node, true means + visible (if all parents are also visible). */ + virtual bool isVisible() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsVisible; + } + + //! Check whether the node is truly visible, taking into accounts its parents' visibility + /** \return true if the node and all its parents are visible, + false if this or any parent node is invisible. */ + virtual bool isTrulyVisible() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + if(!IsVisible) + return false; + + if(!Parent) + return true; + + return Parent->isTrulyVisible(); + } + + //! Sets if the node should be visible or not. + /** All children of this node won't be visible either, when set + to false. Invisible nodes are not valid candidates for selection by + collision manager bounding box methods. + \param isVisible If the node shall be visible. */ + virtual void setVisible(bool isVisible) + { + IsVisible = isVisible; + } + + + //! Get the id of the scene node. + /** This id can be used to identify the node. + \return The id. */ + virtual s32 getID() const + { + return ID; + } + + + //! Sets the id of the scene node. + /** This id can be used to identify the node. + \param id The new id. */ + virtual void setID(s32 id) + { + ID = id; + } + + + //! Adds a child to this scene node. + /** If the scene node already has a parent it is first removed + from the other parent. + \param child A pointer to the new child. */ + virtual void addChild(ISceneNode* child) + { + if (child && (child != this)) + { + // Change scene manager? + if (SceneManager != child->SceneManager) + child->setSceneManager(SceneManager); + + child->grab(); + child->remove(); // remove from old parent + Children.push_back(child); + child->Parent = this; + } + } + + + //! Removes a child from this scene node. + /** If found in the children list, the child pointer is also + dropped and might be deleted if no other grab exists. + \param child A pointer to the child which shall be removed. + \return True if the child was removed, and false if not, + e.g. because it couldn't be found in the children list. */ + virtual bool removeChild(ISceneNode* child) + { + ISceneNodeList::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + if ((*it) == child) + { + (*it)->Parent = 0; + (*it)->drop(); + Children.erase(it); + return true; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + + //! Removes all children of this scene node + /** The scene nodes found in the children list are also dropped + and might be deleted if no other grab exists on them. + */ + virtual void removeAll() + { + ISceneNodeList::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + (*it)->Parent = 0; + (*it)->drop(); + } + + Children.clear(); + } + + + //! Removes this scene node from the scene + /** If no other grab exists for this node, it will be deleted. + */ + virtual void remove() + { + if (Parent) + Parent->removeChild(this); + } + + + //! Adds an animator which should animate this node. + /** \param animator A pointer to the new animator. */ + virtual void addAnimator(ISceneNodeAnimator* animator) + { + if (animator) + { + Animators.push_back(animator); + animator->grab(); + } + } + + + //! Get a list of all scene node animators. + /** \return The list of animators attached to this node. */ + const core::list<ISceneNodeAnimator*>& getAnimators() const + { + return Animators; + } + + + //! Removes an animator from this scene node. + /** If the animator is found, it is also dropped and might be + deleted if not other grab exists for it. + \param animator A pointer to the animator to be deleted. */ + virtual void removeAnimator(ISceneNodeAnimator* animator) + { + ISceneNodeAnimatorList::Iterator it = Animators.begin(); + for (; it != Animators.end(); ++it) + { + if ((*it) == animator) + { + (*it)->drop(); + Animators.erase(it); + return; + } + } + } + + + //! Removes all animators from this scene node. + /** The animators might also be deleted if no other grab exists + for them. */ + virtual void removeAnimators() + { + ISceneNodeAnimatorList::Iterator it = Animators.begin(); + for (; it != Animators.end(); ++it) + (*it)->drop(); + + Animators.clear(); + } + + + //! Returns the material based on the zero based index i. + /** To get the amount of materials used by this scene node, use + getMaterialCount(). This function is needed for inserting the + node into the scene hierarchy at an optimal position for + minimizing renderstate changes, but can also be used to + directly modify the material of a scene node. + \param num Zero based index. The maximal value is getMaterialCount() - 1. + \return The material at that index. */ + virtual video::SMaterial& getMaterial(u32 num) + { + return video::IdentityMaterial; + } + + + //! Get amount of materials used by this scene node. + /** \return Current amount of materials of this scene node. */ + virtual u32 getMaterialCount() const + { + return 0; + } + + + //! Sets all material flags at once to a new value. + /** Useful, for example, if you want the whole mesh to be + affected by light. + \param flag Which flag of all materials to be set. + \param newvalue New value of that flag. */ + void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) + { + for (u32 i=0; i<getMaterialCount(); ++i) + getMaterial(i).setFlag(flag, newvalue); + } + + + //! Sets the texture of the specified layer in all materials of this scene node to the new texture. + /** \param textureLayer Layer of texture to be set. Must be a + value smaller than MATERIAL_MAX_TEXTURES. + \param texture New texture to be used. */ + void setMaterialTexture(u32 textureLayer, video::ITexture* texture) + { + if (textureLayer >= video::MATERIAL_MAX_TEXTURES) + return; + + for (u32 i=0; i<getMaterialCount(); ++i) + getMaterial(i).setTexture(textureLayer, texture); + } + + + //! Sets the material type of all materials in this scene node to a new material type. + /** \param newType New type of material to be set. */ + void setMaterialType(video::E_MATERIAL_TYPE newType) + { + for (u32 i=0; i<getMaterialCount(); ++i) + getMaterial(i).MaterialType = newType; + } + + + //! Gets the scale of the scene node relative to its parent. + /** This is the scale of this node relative to its parent. + If you want the absolute scale, use + getAbsoluteTransformation().getScale() + \return The scale of the scene node. */ + virtual const core::vector3df& getScale() const + { + return RelativeScale; + } + + + //! Sets the relative scale of the scene node. + /** \param scale New scale of the node, relative to its parent. */ + virtual void setScale(const core::vector3df& scale) + { + RelativeScale = scale; + } + + + //! Gets the rotation of the node relative to its parent. + /** Note that this is the relative rotation of the node. + If you want the absolute rotation, use + getAbsoluteTransformation().getRotation() + \return Current relative rotation of the scene node. */ + virtual const core::vector3df& getRotation() const + { + return RelativeRotation; + } + + + //! Sets the rotation of the node relative to its parent. + /** This only modifies the relative rotation of the node. + \param rotation New rotation of the node in degrees. */ + virtual void setRotation(const core::vector3df& rotation) + { + RelativeRotation = rotation; + } + + + //! Gets the position of the node relative to its parent. + /** Note that the position is relative to the parent. If you want + the position in world coordinates, use getAbsolutePosition() instead. + \return The current position of the node relative to the parent. */ + virtual const core::vector3df& getPosition() const + { + return RelativeTranslation; + } + + + //! Sets the position of the node relative to its parent. + /** Note that the position is relative to the parent. + \param newpos New relative position of the scene node. */ + virtual void setPosition(const core::vector3df& newpos) + { + RelativeTranslation = newpos; + } + + + //! Gets the absolute position of the node in world coordinates. + /** If you want the position of the node relative to its parent, + use getPosition() instead. + NOTE: For speed reasons the absolute position is not + automatically recalculated on each change of the relative + position or by a position change of an parent. Instead the + update usually happens once per frame in OnAnimate. You can enforce + an update with updateAbsolutePosition(). + \return The current absolute position of the scene node (updated on last call of updateAbsolutePosition). */ + virtual core::vector3df getAbsolutePosition() const + { + return AbsoluteTransformation.getTranslation(); + } + + + //! Enables or disables automatic culling based on the bounding box. + /** Automatic culling is enabled by default. Note that not + all SceneNodes support culling and that some nodes always cull + their geometry because it is their only reason for existence, + for example the OctreeSceneNode. + \param state The culling state to be used. */ + void setAutomaticCulling( u32 state) + { + AutomaticCullingState = state; + } + + + //! Gets the automatic culling state. + /** \return The automatic culling state. */ + u32 getAutomaticCulling() const + { + return AutomaticCullingState; + } + + + //! Sets if debug data like bounding boxes should be drawn. + /** A bitwise OR of the types from @ref irr::scene::E_DEBUG_SCENE_TYPE. + Please note that not all scene nodes support all debug data types. + \param state The debug data visibility state to be used. */ + virtual void setDebugDataVisible(u32 state) + { + DebugDataVisible = state; + } + + //! Returns if debug data like bounding boxes are drawn. + /** \return A bitwise OR of the debug data values from + @ref irr::scene::E_DEBUG_SCENE_TYPE that are currently visible. */ + u32 isDebugDataVisible() const + { + return DebugDataVisible; + } + + + //! Sets if this scene node is a debug object. + /** Debug objects have some special properties, for example they can be easily + excluded from collision detection or from serialization, etc. */ + void setIsDebugObject(bool debugObject) + { + IsDebugObject = debugObject; + } + + + //! Returns if this scene node is a debug object. + /** Debug objects have some special properties, for example they can be easily + excluded from collision detection or from serialization, etc. + \return If this node is a debug object, true is returned. */ + bool isDebugObject() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsDebugObject; + } + + + //! Returns a const reference to the list of all children. + /** \return The list of all children of this node. */ + const core::list<ISceneNode*>& getChildren() const + { + return Children; + } + + + //! Changes the parent of the scene node. + /** \param newParent The new parent to be used. */ + virtual void setParent(ISceneNode* newParent) + { + grab(); + remove(); + + Parent = newParent; + + if (Parent) + Parent->addChild(this); + + drop(); + } + + + //! Returns the triangle selector attached to this scene node. + /** The Selector can be used by the engine for doing collision + detection. You can create a TriangleSelector with + ISceneManager::createTriangleSelector() or + ISceneManager::createOctreeTriangleSelector and set it with + ISceneNode::setTriangleSelector(). If a scene node got no triangle + selector, but collision tests should be done with it, a triangle + selector is created using the bounding box of the scene node. + \return A pointer to the TriangleSelector or 0, if there + is none. */ + virtual ITriangleSelector* getTriangleSelector() const + { + return TriangleSelector; + } + + + //! Sets the triangle selector of the scene node. + /** The Selector can be used by the engine for doing collision + detection. You can create a TriangleSelector with + ISceneManager::createTriangleSelector() or + ISceneManager::createOctreeTriangleSelector(). Some nodes may + create their own selector by default, so it would be good to + check if there is already a selector in this node by calling + ISceneNode::getTriangleSelector(). + \param selector New triangle selector for this scene node. */ + virtual void setTriangleSelector(ITriangleSelector* selector) + { + if (TriangleSelector != selector) + { + if (TriangleSelector) + TriangleSelector->drop(); + + TriangleSelector = selector; + if (TriangleSelector) + TriangleSelector->grab(); + } + } + + + //! Updates the absolute position based on the relative and the parents position + /** Note: This does not recursively update the parents absolute positions, so if you have a deeper + hierarchy you might want to update the parents first.*/ + virtual void updateAbsolutePosition() + { + if (Parent) + { + AbsoluteTransformation = + Parent->getAbsoluteTransformation() * getRelativeTransformation(); + } + else + AbsoluteTransformation = getRelativeTransformation(); + } + + + //! Returns the parent of this scene node + /** \return A pointer to the parent. */ + scene::ISceneNode* getParent() const + { + return Parent; + } + + + //! Returns type of the scene node + /** \return The type of this node. */ + virtual ESCENE_NODE_TYPE getType() const + { + return ESNT_UNKNOWN; + } + + + //! Writes attributes of the scene node. + /** Implement this to expose the attributes of your scene node + for scripting languages, editors, debuggers or xml + serialization purposes. + \param out The attribute container to write into. + \param options Additional options which might influence the + serialization. */ + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const + { + if (!out) + return; + out->addString ("Name", Name.c_str()); + out->addInt ("Id", ID ); + + out->addVector3d("Position", getPosition() ); + out->addVector3d("Rotation", getRotation() ); + out->addVector3d("Scale", getScale() ); + + out->addBool ("Visible", IsVisible ); + out->addInt ("AutomaticCulling", AutomaticCullingState); + out->addInt ("DebugDataVisible", DebugDataVisible ); + out->addBool ("IsDebugObject", IsDebugObject ); + } + + + //! Reads attributes of the scene node. + /** Implement this to set the attributes of your scene node for + scripting languages, editors, debuggers or xml deserialization + purposes. + \param in The attribute container to read from. + \param options Additional options which might influence the + deserialization. */ + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) + { + if (!in) + return; + Name = in->getAttributeAsString("Name"); + ID = in->getAttributeAsInt("Id"); + + setPosition(in->getAttributeAsVector3d("Position")); + setRotation(in->getAttributeAsVector3d("Rotation")); + setScale(in->getAttributeAsVector3d("Scale")); + + IsVisible = in->getAttributeAsBool("Visible"); + s32 tmpState = in->getAttributeAsEnumeration("AutomaticCulling", + scene::AutomaticCullingNames); + if (tmpState != -1) + AutomaticCullingState = (u32)tmpState; + else + AutomaticCullingState = in->getAttributeAsInt("AutomaticCulling"); + + DebugDataVisible = in->getAttributeAsInt("DebugDataVisible"); + IsDebugObject = in->getAttributeAsBool("IsDebugObject"); + + updateAbsolutePosition(); + } + + //! Creates a clone of this scene node and its children. + /** \param newParent An optional new parent. + \param newManager An optional new scene manager. + \return The newly created clone of this node. */ + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) + { + return 0; // to be implemented by derived classes + } + + //! Retrieve the scene manager for this node. + /** \return The node's scene manager. */ + virtual ISceneManager* getSceneManager(void) const { return SceneManager; } + + protected: + + //! A clone function for the ISceneNode members. + /** This method can be used by clone() implementations of + derived classes + \param toCopyFrom The node from which the values are copied + \param newManager The new scene manager. */ + void cloneMembers(ISceneNode* toCopyFrom, ISceneManager* newManager) + { + Name = toCopyFrom->Name; + AbsoluteTransformation = toCopyFrom->AbsoluteTransformation; + RelativeTranslation = toCopyFrom->RelativeTranslation; + RelativeRotation = toCopyFrom->RelativeRotation; + RelativeScale = toCopyFrom->RelativeScale; + ID = toCopyFrom->ID; + setTriangleSelector(toCopyFrom->TriangleSelector); + AutomaticCullingState = toCopyFrom->AutomaticCullingState; + DebugDataVisible = toCopyFrom->DebugDataVisible; + IsVisible = toCopyFrom->IsVisible; + IsDebugObject = toCopyFrom->IsDebugObject; + + if (newManager) + SceneManager = newManager; + else + SceneManager = toCopyFrom->SceneManager; + + // clone children + + ISceneNodeList::Iterator it = toCopyFrom->Children.begin(); + for (; it != toCopyFrom->Children.end(); ++it) + (*it)->clone(this, newManager); + + // clone animators + + ISceneNodeAnimatorList::Iterator ait = toCopyFrom->Animators.begin(); + for (; ait != toCopyFrom->Animators.end(); ++ait) + { + ISceneNodeAnimator* anim = (*ait)->createClone(this, SceneManager); + if (anim) + { + addAnimator(anim); + anim->drop(); + } + } + } + + //! Sets the new scene manager for this node and all children. + //! Called by addChild when moving nodes between scene managers + void setSceneManager(ISceneManager* newManager) + { + SceneManager = newManager; + + ISceneNodeList::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->setSceneManager(newManager); + } + + //! Name of the scene node. + core::stringc Name; + + //! Absolute transformation of the node. + core::matrix4 AbsoluteTransformation; + + //! Relative translation of the scene node. + core::vector3df RelativeTranslation; + + //! Relative rotation of the scene node. + core::vector3df RelativeRotation; + + //! Relative scale of the scene node. + core::vector3df RelativeScale; + + //! Pointer to the parent + ISceneNode* Parent; + + //! List of all children of this node + core::list<ISceneNode*> Children; + + //! List of all animator nodes + core::list<ISceneNodeAnimator*> Animators; + + //! Pointer to the scene manager + ISceneManager* SceneManager; + + //! Pointer to the triangle selector + ITriangleSelector* TriangleSelector; + + //! ID of the node. + s32 ID; + + //! Automatic culling state + u32 AutomaticCullingState; + + //! Flag if debug data should be drawn, such as Bounding Boxes. + u32 DebugDataVisible; + + //! Is the node visible? + bool IsVisible; + + //! Is debug object? + bool IsDebugObject; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISceneNodeAnimator.h b/builddir/irrlicht-1.8.1/include/ISceneNodeAnimator.h new file mode 100644 index 0000000..c69474b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISceneNodeAnimator.h @@ -0,0 +1,78 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_ANIMATOR_H_INCLUDED__ +#define __I_SCENE_NODE_ANIMATOR_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "vector3d.h" +#include "ESceneNodeAnimatorTypes.h" +#include "IAttributeExchangingObject.h" +#include "IEventReceiver.h" + +namespace irr +{ +namespace io +{ + class IAttributes; +} // end namespace io +namespace scene +{ + class ISceneNode; + class ISceneManager; + + //! Animates a scene node. Can animate position, rotation, material, and so on. + /** A scene node animator is able to animate a scene node in a very simple way. It may + change its position, rotation, scale and/or material. There are lots of animators + to choose from. You can create scene node animators with the ISceneManager interface. + */ + class ISceneNodeAnimator : public io::IAttributeExchangingObject, public IEventReceiver + { + public: + //! Animates a scene node. + /** \param node Node to animate. + \param timeMs Current time in milli seconds. */ + virtual void animateNode(ISceneNode* node, u32 timeMs) =0; + + //! Creates a clone of this animator. + /** Please note that you will have to drop + (IReferenceCounted::drop()) the returned pointer after calling this. */ + virtual ISceneNodeAnimator* createClone(ISceneNode* node, + ISceneManager* newManager=0) =0; + + //! Returns true if this animator receives events. + /** When attached to an active camera, this animator will be + able to respond to events such as mouse and keyboard events. */ + virtual bool isEventReceiverEnabled() const + { + return false; + } + + //! Event receiver, override this function for camera controlling animators + virtual bool OnEvent(const SEvent& event) + { + return false; + } + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const + { + return ESNAT_UNKNOWN; + } + + //! Returns if the animator has finished. + /** This is only valid for non-looping animators with a discrete end state. + \return true if the animator has finished, false if it is still running. */ + virtual bool hasFinished(void) const + { + return false; + } + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorCameraFPS.h b/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorCameraFPS.h new file mode 100644 index 0000000..adfe9e9 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorCameraFPS.h @@ -0,0 +1,69 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_ANIMATOR_CAMERA_FPS_H_INCLUDED__ +#define __I_SCENE_NODE_ANIMATOR_CAMERA_FPS_H_INCLUDED__ + +#include "ISceneNodeAnimator.h" +#include "IEventReceiver.h" +#include "irrArray.h" + +namespace irr +{ + struct SKeyMap; + +namespace scene +{ + + //! Special scene node animator for FPS cameras + /** This scene node animator can be attached to a camera to make it act + like a first person shooter + */ + class ISceneNodeAnimatorCameraFPS : public ISceneNodeAnimator + { + public: + + //! Returns the speed of movement in units per millisecond + virtual f32 getMoveSpeed() const = 0; + + //! Sets the speed of movement in units per millisecond + virtual void setMoveSpeed(f32 moveSpeed) = 0; + + //! Returns the rotation speed in degrees + /** The degrees are equivalent to a half screen movement of the mouse, + i.e. if the mouse cursor had been moved to the border of the screen since + the last animation. */ + virtual f32 getRotateSpeed() const = 0; + + //! Set the rotation speed in degrees + virtual void setRotateSpeed(f32 rotateSpeed) = 0; + + //! Sets the keyboard mapping for this animator (old style) + /** \param map Array of keyboard mappings, see irr::SKeyMap + \param count Size of the keyboard map array. */ + virtual void setKeyMap(SKeyMap *map, u32 count) = 0; + + //! Sets the keyboard mapping for this animator + //! \param keymap The new keymap array + virtual void setKeyMap(const core::array<SKeyMap>& keymap) = 0; + + //! Gets the keyboard mapping for this animator + virtual const core::array<SKeyMap>& getKeyMap() const = 0; + + //! Sets whether vertical movement should be allowed. + /** If vertical movement is enabled then the camera may fight with + gravity causing camera shake. Disable this if the camera has + a collision animator with gravity enabled. */ + virtual void setVerticalMovement(bool allow) = 0; + + //! Sets whether the Y axis of the mouse should be inverted. + /** If enabled then moving the mouse down will cause + the camera to look up. It is disabled by default. */ + virtual void setInvertMouse(bool invert) = 0; + }; +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorCameraMaya.h b/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorCameraMaya.h new file mode 100644 index 0000000..ebee950 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorCameraMaya.h @@ -0,0 +1,58 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_ANIMATOR_CAMERA_MAYA_H_INCLUDED__ +#define __I_SCENE_NODE_ANIMATOR_CAMERA_MAYA_H_INCLUDED__ + +#include "ISceneNodeAnimator.h" + +namespace irr +{ + +namespace scene +{ + + //! Special scene node animator for Maya-style cameras + /** This scene node animator can be attached to a camera to make it act like a 3d + modelling tool. + The camera is moving relative to the target with the mouse, by pressing either + of the three buttons. + In order to move the camera, set a new target for the camera. The distance defines + the current orbit radius the camera moves on. Distance can be changed via the setter + or by mouse events. + */ + class ISceneNodeAnimatorCameraMaya : public ISceneNodeAnimator + { + public: + + //! Returns the speed of movement + virtual f32 getMoveSpeed() const = 0; + + //! Sets the speed of movement + virtual void setMoveSpeed(f32 moveSpeed) = 0; + + //! Returns the rotation speed + virtual f32 getRotateSpeed() const = 0; + + //! Set the rotation speed + virtual void setRotateSpeed(f32 rotateSpeed) = 0; + + //! Returns the zoom speed + virtual f32 getZoomSpeed() const = 0; + + //! Set the zoom speed + virtual void setZoomSpeed(f32 zoomSpeed) = 0; + + //! Returns the current distance, i.e. orbit radius + virtual f32 getDistance() const = 0; + + //! Set the distance + virtual void setDistance(f32 distance) = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorCollisionResponse.h b/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorCollisionResponse.h new file mode 100644 index 0000000..e2bba8a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorCollisionResponse.h @@ -0,0 +1,171 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_ANIMATOR_COLLISION_RESPONSE_H_INCLUDED__ +#define __I_SCENE_NODE_ANIMATOR_COLLISION_RESPONSE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + + class ISceneNodeAnimatorCollisionResponse; + + //! Callback interface for catching events of collisions. + /** Implement this interface and use + ISceneNodeAnimatorCollisionResponse::setCollisionCallback to be able to + be notified if a collision has occurred. + **/ + class ICollisionCallback : public virtual IReferenceCounted + { + public: + + //! Will be called when a collision occurrs. + /** See ISceneNodeAnimatorCollisionResponse::setCollisionCallback for more information. + \param animator: Collision response animator in which the collision occurred. You can call + this animator's methods to find the node, collisionPoint and/or collision triangle. + \retval true if the collision was handled in the animator. The animator's target + node will *not* be stopped at the collision point, but will instead move fully + to the location that triggered the collision check. + \retval false if the collision was not handled in the animator. The animator's + target node will be moved to the collision position. + */ + virtual bool onCollision(const ISceneNodeAnimatorCollisionResponse& animator) = 0; + }; + + //! Special scene node animator for doing automatic collision detection and response. + /** This scene node animator can be attached to any single scene node + and will then prevent it from moving through specified collision geometry + (e.g. walls and floors of the) world, as well as having it fall under gravity. + This animator provides a simple implementation of first person shooter cameras. + Attach it to a camera, and the camera will behave as the player control in a + first person shooter game: The camera stops and slides at walls, walks up stairs, + falls down if there is no floor under it, and so on. + + The animator will treat any change in the position of its target scene + node as movement, including a setPosition(), as movement. If you want to + teleport the target scene node manually to a location without it being effected + by collision geometry, then call setTargetNode(node) after calling node->setPosition(). + */ + class ISceneNodeAnimatorCollisionResponse : public ISceneNodeAnimator + { + public: + + //! Destructor + virtual ~ISceneNodeAnimatorCollisionResponse() {} + + //! Check if the attached scene node is falling. + /** Falling means that there is no blocking wall from the scene + node in the direction of the gravity. The implementation of + this method is very fast, no collision detection is done when + invoking it. + \return True if the scene node is falling, false if not. */ + virtual bool isFalling() const = 0; + + //! Sets the radius of the ellipsoid for collision detection and response. + /** If you have a scene node, and you are unsure about how big + the radius should be, you could use the following code to + determine it: + \code + core::aabbox<f32> box = yourSceneNode->getBoundingBox(); + core::vector3df radius = box.MaxEdge - box.getCenter(); + \endcode + \param radius: New radius of the ellipsoid. */ + virtual void setEllipsoidRadius(const core::vector3df& radius) = 0; + + //! Returns the radius of the ellipsoid for collision detection and response. + /** \return Radius of the ellipsoid. */ + virtual core::vector3df getEllipsoidRadius() const = 0; + + //! Sets the gravity of the environment. + /** A good example value would be core::vector3df(0,-100.0f,0) + for letting gravity affect all object to fall down. For bigger + gravity, make increase the length of the vector. You can + disable gravity by setting it to core::vector3df(0,0,0); + \param gravity: New gravity vector. */ + virtual void setGravity(const core::vector3df& gravity) = 0; + + //! Get current vector of gravity. + //! \return Gravity vector. */ + virtual core::vector3df getGravity() const = 0; + + //! 'Jump' the animator, by adding a jump speed opposite to its gravity + /** \param jumpSpeed The initial speed of the jump; the velocity will be opposite + to this animator's gravity vector. */ + virtual void jump(f32 jumpSpeed) = 0; + + //! Should the Target react on collision ( default = true ) + virtual void setAnimateTarget ( bool enable ) = 0; + virtual bool getAnimateTarget () const = 0; + + //! Set translation of the collision ellipsoid. + /** By default, the ellipsoid for collision detection is + created around the center of the scene node, which means that + the ellipsoid surrounds it completely. If this is not what you + want, you may specify a translation for the ellipsoid. + \param translation: Translation of the ellipsoid relative + to the position of the scene node. */ + virtual void setEllipsoidTranslation(const core::vector3df &translation) = 0; + + //! Get the translation of the ellipsoid for collision detection. + /** See + ISceneNodeAnimatorCollisionResponse::setEllipsoidTranslation() + for more details. + \return Translation of the ellipsoid relative to the position + of the scene node. */ + virtual core::vector3df getEllipsoidTranslation() const = 0; + + //! Sets a triangle selector holding all triangles of the world with which the scene node may collide. + /** \param newWorld: New triangle selector containing triangles + to let the scene node collide with. */ + virtual void setWorld(ITriangleSelector* newWorld) = 0; + + //! Get the current triangle selector containing all triangles for collision detection. + virtual ITriangleSelector* getWorld() const = 0; + + //! Set the single node that this animator will act on. + /** \param node The new target node. Setting this will force the animator to update + its last target position for the node, allowing setPosition() to teleport + the node through collision geometry. */ + virtual void setTargetNode(ISceneNode * node) = 0; + + //! Gets the single node that this animator is acting on. + /** \return The node that this animator is acting on. */ + virtual ISceneNode* getTargetNode(void) const = 0; + + //! Returns true if a collision occurred during the last animateNode() + virtual bool collisionOccurred() const = 0; + + //! Returns the last point of collision. + virtual const core::vector3df & getCollisionPoint() const = 0; + + //! Returns the last triangle that caused a collision + virtual const core::triangle3df & getCollisionTriangle() const = 0; + + //! Returns the position that the target node will be moved to, unless the collision is consumed in a callback. + /** + If you have a collision callback registered, and it consumes the collision, then the + node will ignore the collision and will not stop at this position. Instead, it will + move fully to the position that caused the collision to occur. */ + virtual const core::vector3df & getCollisionResultPosition(void) const = 0; + + //! Returns the node that was collided with. + virtual ISceneNode* getCollisionNode(void) const = 0; + + //! Sets a callback interface which will be called if a collision occurs. + /** \param callback: collision callback handler that will be called when a collision + occurs. Set this to 0 to disable the callback. + */ + virtual void setCollisionCallback(ICollisionCallback* callback) = 0; + + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorFactory.h b/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorFactory.h new file mode 100644 index 0000000..8afe3ef --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISceneNodeAnimatorFactory.h @@ -0,0 +1,69 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_ANIMATOR_FACTORY_H_INCLUDED__ +#define __I_SCENE_NODE_ANIMATOR_FACTORY_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "ESceneNodeAnimatorTypes.h" + +namespace irr +{ +namespace scene +{ + class ISceneNode; + class ISceneNodeAnimator; + + //! Interface for dynamic creation of scene node animators + /** To be able to add custom scene node animators to Irrlicht and to make it possible for the + scene manager to save and load those external animators, simply implement this + interface and register it in you scene manager via ISceneManager::registerSceneNodeAnimatorFactory. + Note: When implementing your own scene node factory, don't call ISceneNodeManager::grab() to + increase the reference counter of the scene node manager. This is not necessary because the + scene node manager will grab() the factory anyway, and otherwise cyclic references will + be created and the scene manager and all its nodes won't get deallocated. + */ + class ISceneNodeAnimatorFactory : public virtual IReferenceCounted + { + public: + + //! creates a scene node animator based on its type id + /** \param type: Type of the scene node animator to add. + \param target: Target scene node of the new animator. + \return Returns pointer to the new scene node animator or null if not successful. You need to + drop this pointer after calling this, see IReferenceCounted::drop() for details. */ + virtual ISceneNodeAnimator* createSceneNodeAnimator(ESCENE_NODE_ANIMATOR_TYPE type, ISceneNode* target) = 0; + + //! creates a scene node animator based on its type name + /** \param typeName: Type of the scene node animator to add. + \param target: Target scene node of the new animator. + \return Returns pointer to the new scene node animator or null if not successful. You need to + drop this pointer after calling this, see IReferenceCounted::drop() for details. */ + virtual ISceneNodeAnimator* createSceneNodeAnimator(const c8* typeName, ISceneNode* target) = 0; + + //! returns amount of scene node animator types this factory is able to create + virtual u32 getCreatableSceneNodeAnimatorTypeCount() const = 0; + + //! returns type of a createable scene node animator type + /** \param idx: Index of scene node animator type in this factory. Must be a value between 0 and + getCreatableSceneNodeTypeCount() */ + virtual ESCENE_NODE_ANIMATOR_TYPE getCreateableSceneNodeAnimatorType(u32 idx) const = 0; + + //! returns type name of a createable scene node animator type + /** \param idx: Index of scene node animator type in this factory. Must be a value between 0 and + getCreatableSceneNodeAnimatorTypeCount() */ + virtual const c8* getCreateableSceneNodeAnimatorTypeName(u32 idx) const = 0; + + //! returns type name of a createable scene node animator type + /** \param type: Type of scene node animator. + \return: Returns name of scene node animator type if this factory can create the type, otherwise 0. */ + virtual const c8* getCreateableSceneNodeAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) const = 0; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISceneNodeFactory.h b/builddir/irrlicht-1.8.1/include/ISceneNodeFactory.h new file mode 100644 index 0000000..247b47b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISceneNodeFactory.h @@ -0,0 +1,68 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_FACTORY_H_INCLUDED__ +#define __I_SCENE_NODE_FACTORY_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "ESceneNodeTypes.h" + +namespace irr +{ + +namespace scene +{ + class ISceneNode; + + //! Interface for dynamic creation of scene nodes + /** To be able to add custom scene nodes to Irrlicht and to make it possible for the + scene manager to save and load those external scene nodes, simply implement this + interface and register it in you scene manager via ISceneManager::registerSceneNodeFactory. + Note: When implementing your own scene node factory, don't call ISceneNodeManager::grab() to + increase the reference counter of the scene node manager. This is not necessary because the + scene node manager will grab() the factory anyway, and otherwise cyclic references will + be created and the scene manager and all its nodes won't get deallocated. + */ + class ISceneNodeFactory : public virtual IReferenceCounted + { + public: + //! adds a scene node to the scene graph based on its type id + /** \param type: Type of the scene node to add. + \param parent: Parent scene node of the new node, can be null to add the scene node to the root. + \return Returns pointer to the new scene node or null if not successful. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addSceneNode(ESCENE_NODE_TYPE type, ISceneNode* parent=0) = 0; + + //! adds a scene node to the scene graph based on its type name + /** \param typeName: Type name of the scene node to add. + \param parent: Parent scene node of the new node, can be null to add the scene node to the root. + \return Returns pointer to the new scene node or null if not successful. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addSceneNode(const c8* typeName, ISceneNode* parent=0) = 0; + + //! returns amount of scene node types this factory is able to create + virtual u32 getCreatableSceneNodeTypeCount() const = 0; + + //! returns type of a createable scene node type + /** \param idx: Index of scene node type in this factory. Must be a value between 0 and + getCreatableSceneNodeTypeCount() */ + virtual ESCENE_NODE_TYPE getCreateableSceneNodeType(u32 idx) const = 0; + + //! returns type name of a createable scene node type by index + /** \param idx: Index of scene node type in this factory. Must be a value between 0 and + getCreatableSceneNodeTypeCount() */ + virtual const c8* getCreateableSceneNodeTypeName(u32 idx) const = 0; + + //! returns type name of a createable scene node type + /** \param type: Type of scene node. + \return: Returns name of scene node type if this factory can create the type, otherwise 0. */ + virtual const c8* getCreateableSceneNodeTypeName(ESCENE_NODE_TYPE type) const = 0; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISceneUserDataSerializer.h b/builddir/irrlicht-1.8.1/include/ISceneUserDataSerializer.h new file mode 100644 index 0000000..0e63440 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISceneUserDataSerializer.h @@ -0,0 +1,51 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_USER_DATA_SERIALIZER_H_INCLUDED__ +#define __I_SCENE_USER_DATA_SERIALIZER_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ +namespace io +{ + class IAttributes; +} // end namespace io +namespace scene +{ + class ISceneNode; + +//! Interface to read and write user data to and from .irr files. +/** This interface is to be implemented by the user, to make it possible to read +and write user data when reading or writing .irr files via ISceneManager. +To be used with ISceneManager::loadScene() and ISceneManager::saveScene() */ +class ISceneUserDataSerializer +{ +public: + + virtual ~ISceneUserDataSerializer() {} + + //! Called when the scene manager create a scene node while loading a file. + virtual void OnCreateNode(ISceneNode* node) = 0; + + //! Called when the scene manager read a scene node while loading a file. + /** The userData pointer contains a list of attributes with userData which + were attached to the scene node in the read scene file.*/ + virtual void OnReadUserData(ISceneNode* forSceneNode, io::IAttributes* userData) = 0; + + //! Called when the scene manager is writing a scene node to an xml file for example. + /** Implement this method and return a list of attributes containing the user data + you want to be saved together with the scene node. Return 0 if no user data should + be added. Please note that the scene manager will call drop() to the returned pointer + after it no longer needs it, so if you didn't create a new object for the return value + and returning a longer existing IAttributes object, simply call grab() before returning it. */ + virtual io::IAttributes* createUserData(ISceneNode* forSceneNode) = 0; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IShaderConstantSetCallBack.h b/builddir/irrlicht-1.8.1/include/IShaderConstantSetCallBack.h new file mode 100644 index 0000000..f88393f --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IShaderConstantSetCallBack.h @@ -0,0 +1,85 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SHADER_CONSTANT_SET_CALLBACT_H_INCLUDED__ +#define __I_SHADER_CONSTANT_SET_CALLBACT_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ +namespace video +{ + class IMaterialRendererServices; + class SMaterial; + +//! Interface making it possible to set constants for gpu programs every frame. +/** Implement this interface in an own class and pass a pointer to it to one of +the methods in IGPUProgrammingServices when creating a shader. The +OnSetConstants method will be called every frame now. */ +class IShaderConstantSetCallBack : public virtual IReferenceCounted +{ +public: + + //! Called to let the callBack know the used material (optional method) + /** + \code + class MyCallBack : public IShaderConstantSetCallBack + { + const video::SMaterial *UsedMaterial; + + OnSetMaterial(const video::SMaterial& material) + { + UsedMaterial=&material; + } + + OnSetConstants(IMaterialRendererServices* services, s32 userData) + { + services->setVertexShaderConstant("myColor", reinterpret_cast<f32*>(&UsedMaterial->color), 4); + } + } + \endcode + */ + virtual void OnSetMaterial(const SMaterial& material) { } + + //! Called by the engine when the vertex and/or pixel shader constants for an material renderer should be set. + /** + Implement the IShaderConstantSetCallBack in an own class and implement your own + OnSetConstants method using the given IMaterialRendererServices interface. + Pass a pointer to this class to one of the methods in IGPUProgrammingServices + when creating a shader. The OnSetConstants method will now be called every time + before geometry is being drawn using your shader material. A sample implementation + would look like this: + \code + virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + // set clip matrix at register 4 + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant(&worldViewProj.M[0], 4, 4); + // for high level shading languages, this would be another solution: + //services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16); + + // set some light color at register 9 + video::SColorf col(0.0f,1.0f,1.0f,0.0f); + services->setVertexShaderConstant(reinterpret_cast<const f32*>(&col), 9, 1); + // for high level shading languages, this would be another solution: + //services->setVertexShaderConstant("myColor", reinterpret_cast<f32*>(&col), 4); + } + \endcode + \param services: Pointer to an interface providing methods to set the constants for the shader. + \param userData: Userdata int which can be specified when creating the shader. + */ + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData) = 0; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IShadowVolumeSceneNode.h b/builddir/irrlicht-1.8.1/include/IShadowVolumeSceneNode.h new file mode 100644 index 0000000..40781a9 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IShadowVolumeSceneNode.h @@ -0,0 +1,38 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SHADOW_VOLUME_SCENE_NODE_H_INCLUDED__ +#define __I_SHADOW_VOLUME_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + class IMesh; + + //! Scene node for rendering a shadow volume into a stencil buffer. + class IShadowVolumeSceneNode : public ISceneNode + { + public: + + //! constructor + IShadowVolumeSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) + : ISceneNode(parent, mgr, id) {} + + //! Sets the mesh from which the shadow volume should be generated. + /** To optimize shadow rendering, use a simpler mesh for shadows. + */ + virtual void setShadowMesh(const IMesh* mesh) = 0; + + //! Updates the shadow volumes for current light positions. + virtual void updateShadowVolumes() = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ISkinnedMesh.h b/builddir/irrlicht-1.8.1/include/ISkinnedMesh.h new file mode 100644 index 0000000..5f0f9cb --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ISkinnedMesh.h @@ -0,0 +1,219 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SKINNED_MESH_H_INCLUDED__ +#define __I_SKINNED_MESH_H_INCLUDED__ + +#include "irrArray.h" +#include "IBoneSceneNode.h" +#include "IAnimatedMesh.h" +#include "SSkinMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + + enum E_INTERPOLATION_MODE + { + // constant does use the current key-values without interpolation + EIM_CONSTANT = 0, + + // linear interpolation + EIM_LINEAR, + + //! count of all available interpolation modes + EIM_COUNT + }; + + + //! Interface for using some special functions of Skinned meshes + class ISkinnedMesh : public IAnimatedMesh + { + public: + + //! Gets joint count. + /** \return Amount of joints in the skeletal animated mesh. */ + virtual u32 getJointCount() const = 0; + + //! Gets the name of a joint. + /** \param number: Zero based index of joint. The last joint + has the number getJointCount()-1; + \return Name of joint and null if an error happened. */ + virtual const c8* getJointName(u32 number) const = 0; + + //! Gets a joint number from its name + /** \param name: Name of the joint. + \return Number of the joint or -1 if not found. */ + virtual s32 getJointNumber(const c8* name) const = 0; + + //! Use animation from another mesh + /** The animation is linked (not copied) based on joint names + so make sure they are unique. + \return True if all joints in this mesh were + matched up (empty names will not be matched, and it's case + sensitive). Unmatched joints will not be animated. */ + virtual bool useAnimationFrom(const ISkinnedMesh *mesh) = 0; + + //! Update Normals when Animating + /** \param on If false don't animate, which is faster. + Else update normals, which allows for proper lighting of + animated meshes. */ + virtual void updateNormalsWhenAnimating(bool on) = 0; + + //! Sets Interpolation Mode + virtual void setInterpolationMode(E_INTERPOLATION_MODE mode) = 0; + + //! Animates this mesh's joints based on frame input + virtual void animateMesh(f32 frame, f32 blend)=0; + + //! Preforms a software skin on this mesh based of joint positions + virtual void skinMesh() = 0; + + //! converts the vertex type of all meshbuffers to tangents. + /** E.g. used for bump mapping. */ + virtual void convertMeshToTangents() = 0; + + //! Allows to enable hardware skinning. + /* This feature is not implementated in Irrlicht yet */ + virtual bool setHardwareSkinning(bool on) = 0; + + //! A vertex weight + struct SWeight + { + //! Index of the mesh buffer + u16 buffer_id; //I doubt 32bits is needed + + //! Index of the vertex + u32 vertex_id; //Store global ID here + + //! Weight Strength/Percentage (0-1) + f32 strength; + + private: + //! Internal members used by CSkinnedMesh + friend class CSkinnedMesh; + bool *Moved; + core::vector3df StaticPos; + core::vector3df StaticNormal; + }; + + + //! Animation keyframe which describes a new position + struct SPositionKey + { + f32 frame; + core::vector3df position; + }; + + //! Animation keyframe which describes a new scale + struct SScaleKey + { + f32 frame; + core::vector3df scale; + }; + + //! Animation keyframe which describes a new rotation + struct SRotationKey + { + f32 frame; + core::quaternion rotation; + }; + + //! Joints + struct SJoint + { + SJoint() : UseAnimationFrom(0), GlobalSkinningSpace(false), + positionHint(-1),scaleHint(-1),rotationHint(-1) + { + } + + //! The name of this joint + core::stringc Name; + + //! Local matrix of this joint + core::matrix4 LocalMatrix; + + //! List of child joints + core::array<SJoint*> Children; + + //! List of attached meshes + core::array<u32> AttachedMeshes; + + //! Animation keys causing translation change + core::array<SPositionKey> PositionKeys; + + //! Animation keys causing scale change + core::array<SScaleKey> ScaleKeys; + + //! Animation keys causing rotation change + core::array<SRotationKey> RotationKeys; + + //! Skin weights + core::array<SWeight> Weights; + + //! Unnecessary for loaders, will be overwritten on finalize + core::matrix4 GlobalMatrix; + core::matrix4 GlobalAnimatedMatrix; + core::matrix4 LocalAnimatedMatrix; + core::vector3df Animatedposition; + core::vector3df Animatedscale; + core::quaternion Animatedrotation; + + core::matrix4 GlobalInversedMatrix; //the x format pre-calculates this + + private: + //! Internal members used by CSkinnedMesh + friend class CSkinnedMesh; + + SJoint *UseAnimationFrom; + bool GlobalSkinningSpace; + + s32 positionHint; + s32 scaleHint; + s32 rotationHint; + }; + + + //Interface for the mesh loaders (finalize should lock these functions, and they should have some prefix like loader_ + + //these functions will use the needed arrays, set values, etc to help the loaders + + //! exposed for loaders: to add mesh buffers + virtual core::array<SSkinMeshBuffer*>& getMeshBuffers() = 0; + + //! exposed for loaders: joints list + virtual core::array<SJoint*>& getAllJoints() = 0; + + //! exposed for loaders: joints list + virtual const core::array<SJoint*>& getAllJoints() const = 0; + + //! loaders should call this after populating the mesh + virtual void finalize() = 0; + + //! Adds a new meshbuffer to the mesh, access it as last one + virtual SSkinMeshBuffer* addMeshBuffer() = 0; + + //! Adds a new joint to the mesh, access it as last one + virtual SJoint* addJoint(SJoint *parent=0) = 0; + + //! Adds a new weight to the mesh, access it as last one + virtual SWeight* addWeight(SJoint *joint) = 0; + + //! Adds a new position key to the mesh, access it as last one + virtual SPositionKey* addPositionKey(SJoint *joint) = 0; + //! Adds a new scale key to the mesh, access it as last one + virtual SScaleKey* addScaleKey(SJoint *joint) = 0; + //! Adds a new rotation key to the mesh, access it as last one + virtual SRotationKey* addRotationKey(SJoint *joint) = 0; + + //! Check if the mesh is non-animated + virtual bool isStatic()=0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ITerrainSceneNode.h b/builddir/irrlicht-1.8.1/include/ITerrainSceneNode.h new file mode 100644 index 0000000..4802710 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ITerrainSceneNode.h @@ -0,0 +1,182 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// The code for the TerrainSceneNode is based on the terrain renderer by +// Soconne and the GeoMipMapSceneNode developed by Spintz. They made their +// code available for Irrlicht and allowed it to be distributed under this +// licence. I only modified some parts. A lot of thanks go to them. + +#ifndef __I_TERRAIN_SCENE_NODE_H__ +#define __I_TERRAIN_SCENE_NODE_H__ + +#include "ETerrainElements.h" +#include "ISceneNode.h" +#include "IDynamicMeshBuffer.h" +#include "irrArray.h" + +namespace irr +{ +namespace io +{ + class IReadFile; +} // end namespace io +namespace scene +{ + class IMesh; + + //! A scene node for displaying terrain using the geo mip map algorithm. + /** The code for the TerrainSceneNode is based on the Terrain renderer by Soconne and + * the GeoMipMapSceneNode developed by Spintz. They made their code available for Irrlicht + * and allowed it to be distributed under this licence. I only modified some parts. + * A lot of thanks go to them. + * + * This scene node is capable of very quickly loading + * terrains and updating the indices at runtime to enable viewing very large terrains. It uses a + * CLOD (Continuous Level of Detail) algorithm which updates the indices for each patch based on + * a LOD (Level of Detail) which is determined based on a patch's distance from the camera. + * + * The Patch Size of the terrain must always be a size of ( 2^N+1, i.e. 8+1(9), 16+1(17), etc. ). + * The MaxLOD available is directly dependent on the patch size of the terrain. LOD 0 contains all + * of the indices to draw all the triangles at the max detail for a patch. As each LOD goes up by 1 + * the step taken, in generating indices increases by - 2^LOD, so for LOD 1, the step taken is 2, for + * LOD 2, the step taken is 4, LOD 3 - 8, etc. The step can be no larger than the size of the patch, + * so having a LOD of 8, with a patch size of 17, is asking the algoritm to generate indices every + * 2^8 ( 256 ) vertices, which is not possible with a patch size of 17. The maximum LOD for a patch + * size of 17 is 2^4 ( 16 ). So, with a MaxLOD of 5, you'll have LOD 0 ( full detail ), LOD 1 ( every + * 2 vertices ), LOD 2 ( every 4 vertices ), LOD 3 ( every 8 vertices ) and LOD 4 ( every 16 vertices ). + **/ + class ITerrainSceneNode : public ISceneNode + { + public: + //! Constructor + ITerrainSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& rotation = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f) ) + : ISceneNode (parent, mgr, id, position, rotation, scale) {} + + //! Get the bounding box of the terrain. + /** \return The bounding box of the entire terrain. */ + virtual const core::aabbox3d<f32>& getBoundingBox() const =0; + + //! Get the bounding box of a patch + /** \return The bounding box of the chosen patch. */ + virtual const core::aabbox3d<f32>& getBoundingBox(s32 patchX, s32 patchZ) const =0; + + //! Get the number of indices currently in the meshbuffer + /** \return The index count. */ + virtual u32 getIndexCount() const =0; + + //! Get pointer to the mesh + /** \return Pointer to the mesh. */ + virtual IMesh* getMesh() =0; + + //! Get pointer to the buffer used by the terrain (most users will not need this) + virtual IMeshBuffer* getRenderBuffer() =0; + + + //! Gets the meshbuffer data based on a specified level of detail. + /** \param mb A reference to an IDynamicMeshBuffer object + \param LOD The level of detail you want the indices from. */ + virtual void getMeshBufferForLOD(IDynamicMeshBuffer& mb, s32 LOD=0) const =0; + + //! Gets the indices for a specified patch at a specified Level of Detail. + /** \param indices A reference to an array of u32 indices. + \param patchX Patch x coordinate. + \param patchZ Patch z coordinate. + \param LOD The level of detail to get for that patch. If -1, + then get the CurrentLOD. If the CurrentLOD is set to -1, + meaning it's not shown, then it will retrieve the triangles at + the highest LOD (0). + \return Number of indices put into the buffer. */ + virtual s32 getIndicesForPatch(core::array<u32>& indices, + s32 patchX, s32 patchZ, s32 LOD=0) =0; + + //! Populates an array with the CurrentLOD of each patch. + /** \param LODs A reference to a core::array<s32> to hold the + values + \return Number of elements in the array */ + virtual s32 getCurrentLODOfPatches(core::array<s32>& LODs) const =0; + + //! Manually sets the LOD of a patch + /** \param patchX Patch x coordinate. + \param patchZ Patch z coordinate. + \param LOD The level of detail to set the patch to. */ + virtual void setLODOfPatch(s32 patchX, s32 patchZ, s32 LOD=0) =0; + + //! Get center of terrain. + virtual const core::vector3df& getTerrainCenter() const =0; + + //! Get height of a point of the terrain. + virtual f32 getHeight(f32 x, f32 y) const =0; + + //! Sets the movement camera threshold. + /** It is used to determine when to recalculate + indices for the scene node. The default value is 10.0f. */ + virtual void setCameraMovementDelta(f32 delta) =0; + + //! Sets the rotation camera threshold. + /** It is used to determine when to recalculate + indices for the scene node. The default value is 1.0f. */ + virtual void setCameraRotationDelta(f32 delta) =0; + + //! Sets whether or not the node should dynamically update its associated selector when the geomipmap data changes. + /** \param bVal: Boolean value representing whether or not to update selector dynamically. */ + virtual void setDynamicSelectorUpdate(bool bVal) =0; + + //! Override the default generation of distance thresholds. + /** For determining the LOD a patch is rendered at. If any LOD + is overridden, then the scene node will no longer apply scaling + factors to these values. If you override these distances, and + then apply a scale to the scene node, it is your responsibility + to update the new distances to work best with your new terrain + size. */ + virtual bool overrideLODDistance(s32 LOD, f64 newDistance) =0; + + //! Scales the base texture, similar to makePlanarTextureMapping. + /** \param scale The scaling amount. Values above 1.0 + increase the number of time the texture is drawn on the + terrain. Values below 0 will decrease the number of times the + texture is drawn on the terrain. Using negative values will + flip the texture, as well as still scaling it. + \param scale2 If set to 0 (default value), this will set the + second texture coordinate set to the same values as in the + first set. If this is another value than zero, it will scale + the second texture coordinate set by this value. */ + virtual void scaleTexture(f32 scale = 1.0f, f32 scale2=0.0f) =0; + + //! Initializes the terrain data. Loads the vertices from the heightMapFile. + /** The file must contain a loadable image of the heightmap. The heightmap + must be square. + \param file The file to read the image from. File is not rewinded. + \param vertexColor Color of all vertices. + \param smoothFactor Number of smoothing passes. */ + virtual bool loadHeightMap(io::IReadFile* file, + video::SColor vertexColor=video::SColor(255,255,255,255), + s32 smoothFactor=0) =0; + + //! Initializes the terrain data. Loads the vertices from the heightMapFile. + /** The data is interpreted as (signed) integers of the given bit size or + floats (with 32bits, signed). Allowed bitsizes for integers are + 8, 16, and 32. The heightmap must be square. + \param file The file to read the RAW data from. File is not rewinded. + \param bitsPerPixel Size of data if integers used, for floats always use 32. + \param signedData Whether we use signed or unsigned ints, ignored for floats. + \param floatVals Whether the data is float or int. + \param width Width (and also Height, as it must be square) of the heightmap. Use 0 for autocalculating from the filesize. + \param vertexColor Color of all vertices. + \param smoothFactor Number of smoothing passes. */ + virtual bool loadHeightMapRAW(io::IReadFile* file, s32 bitsPerPixel=16, + bool signedData=false, bool floatVals=false, s32 width=0, + video::SColor vertexColor=video::SColor(255,255,255,255), + s32 smoothFactor=0) =0; + + }; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_TERRAIN_SCENE_NODE_H__ + diff --git a/builddir/irrlicht-1.8.1/include/ITextSceneNode.h b/builddir/irrlicht-1.8.1/include/ITextSceneNode.h new file mode 100644 index 0000000..e715a46 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ITextSceneNode.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_TEXT_SCENE_NODE_H_INCLUDED__ +#define __I_TEXT_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! A scene node for displaying 2d text at a position in three dimensional space +class ITextSceneNode : public ISceneNode +{ +public: + + //! constructor + ITextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0)) + : ISceneNode(parent, mgr, id, position) {} + + //! sets the text string + virtual void setText(const wchar_t* text) = 0; + + //! sets the color of the text + virtual void setTextColor(video::SColor color) = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ITexture.h b/builddir/irrlicht-1.8.1/include/ITexture.h new file mode 100644 index 0000000..66f039d --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ITexture.h @@ -0,0 +1,219 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_TEXTURE_H_INCLUDED__ +#define __I_TEXTURE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "IImage.h" +#include "dimension2d.h" +#include "EDriverTypes.h" +#include "path.h" +#include "matrix4.h" + +namespace irr +{ +namespace video +{ + + +//! Enumeration flags telling the video driver in which format textures should be created. +enum E_TEXTURE_CREATION_FLAG +{ + /** Forces the driver to create 16 bit textures always, independent of + which format the file on disk has. When choosing this you may lose + some color detail, but gain much speed and memory. 16 bit textures can + be transferred twice as fast as 32 bit textures and only use half of + the space in memory. + When using this flag, it does not make sense to use the flags + ETCF_ALWAYS_32_BIT, ETCF_OPTIMIZED_FOR_QUALITY, or + ETCF_OPTIMIZED_FOR_SPEED at the same time. */ + ETCF_ALWAYS_16_BIT = 0x00000001, + + /** Forces the driver to create 32 bit textures always, independent of + which format the file on disk has. Please note that some drivers (like + the software device) will ignore this, because they are only able to + create and use 16 bit textures. + When using this flag, it does not make sense to use the flags + ETCF_ALWAYS_16_BIT, ETCF_OPTIMIZED_FOR_QUALITY, or + ETCF_OPTIMIZED_FOR_SPEED at the same time. */ + ETCF_ALWAYS_32_BIT = 0x00000002, + + /** Lets the driver decide in which format the textures are created and + tries to make the textures look as good as possible. Usually it simply + chooses the format in which the texture was stored on disk. + When using this flag, it does not make sense to use the flags + ETCF_ALWAYS_16_BIT, ETCF_ALWAYS_32_BIT, or ETCF_OPTIMIZED_FOR_SPEED at + the same time. */ + ETCF_OPTIMIZED_FOR_QUALITY = 0x00000004, + + /** Lets the driver decide in which format the textures are created and + tries to create them maximizing render speed. + When using this flag, it does not make sense to use the flags + ETCF_ALWAYS_16_BIT, ETCF_ALWAYS_32_BIT, or ETCF_OPTIMIZED_FOR_QUALITY, + at the same time. */ + ETCF_OPTIMIZED_FOR_SPEED = 0x00000008, + + /** Automatically creates mip map levels for the textures. */ + ETCF_CREATE_MIP_MAPS = 0x00000010, + + /** Discard any alpha layer and use non-alpha color format. */ + ETCF_NO_ALPHA_CHANNEL = 0x00000020, + + //! Allow the Driver to use Non-Power-2-Textures + /** BurningVideo can handle Non-Power-2 Textures in 2D (GUI), but not in 3D. */ + ETCF_ALLOW_NON_POWER_2 = 0x00000040, + + /** This flag is never used, it only forces the compiler to compile + these enumeration values to 32 bit. */ + ETCF_FORCE_32_BIT_DO_NOT_USE = 0x7fffffff +}; + +//! Enum for the mode for texture locking. Read-Only, write-only or read/write. +enum E_TEXTURE_LOCK_MODE +{ + //! The default mode. Texture can be read and written to. + ETLM_READ_WRITE = 0, + + //! Read only. The texture is downloaded, but not uploaded again. + /** Often used to read back shader generated textures. */ + ETLM_READ_ONLY, + + //! Write only. The texture is not downloaded and might be uninitialised. + /** The updated texture is uploaded to the GPU. + Used for initialising the shader from the CPU. */ + ETLM_WRITE_ONLY +}; + +//! Interface of a Video Driver dependent Texture. +/** An ITexture is created by an IVideoDriver by using IVideoDriver::addTexture +or IVideoDriver::getTexture. After that, the texture may only be used by this +VideoDriver. As you can imagine, textures of the DirectX and the OpenGL device +will, e.g., not be compatible. An exception is the Software device and the +NULL device, their textures are compatible. If you try to use a texture +created by one device with an other device, the device will refuse to do that +and write a warning or an error message to the output buffer. +*/ +class ITexture : public virtual IReferenceCounted +{ +public: + + //! constructor + ITexture(const io::path& name) : NamedPath(name) + { + } + + //! Lock function. + /** Locks the Texture and returns a pointer to access the + pixels. After lock() has been called and all operations on the pixels + are done, you must call unlock(). + Locks are not accumulating, hence one unlock will do for an arbitrary + number of previous locks. You should avoid locking different levels without + unlocking inbetween, though, because only the last level locked will be + unlocked. + The size of the i-th mipmap level is defined as max(getSize().Width>>i,1) + and max(getSize().Height>>i,1) + \param mode Specifies what kind of changes to the locked texture are + allowed. Unspecified behavior will arise if texture is written in read + only mode or read from in write only mode. + Support for this feature depends on the driver, so don't rely on the + texture being write-protected when locking with read-only, etc. + \param mipmapLevel Number of the mipmapLevel to lock. 0 is main texture. + Non-existing levels will silently fail and return 0. + \return Returns a pointer to the pixel data. The format of the pixel can + be determined by using getColorFormat(). 0 is returned, if + the texture cannot be locked. */ + virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) = 0; + + //! Unlock function. Must be called after a lock() to the texture. + /** One should avoid to call unlock more than once before another lock. + The last locked mip level will be unlocked. */ + virtual void unlock() = 0; + + //! Get original size of the texture. + /** The texture is usually scaled, if it was created with an unoptimal + size. For example if the size was not a power of two. This method + returns the size of the texture it had before it was scaled. Can be + useful when drawing 2d images on the screen, which should have the + exact size of the original texture. Use ITexture::getSize() if you want + to know the real size it has now stored in the system. + \return The original size of the texture. */ + virtual const core::dimension2d<u32>& getOriginalSize() const = 0; + + //! Get dimension (=size) of the texture. + /** \return The size of the texture. */ + virtual const core::dimension2d<u32>& getSize() const = 0; + + //! Get driver type of texture. + /** This is the driver, which created the texture. This method is used + internally by the video devices, to check, if they may use a texture + because textures may be incompatible between different devices. + \return Driver type of texture. */ + virtual E_DRIVER_TYPE getDriverType() const = 0; + + //! Get the color format of texture. + /** \return The color format of texture. */ + virtual ECOLOR_FORMAT getColorFormat() const = 0; + + //! Get pitch of the main texture (in bytes). + /** The pitch is the amount of bytes used for a row of pixels in a + texture. + \return Pitch of texture in bytes. */ + virtual u32 getPitch() const = 0; + + //! Check whether the texture has MipMaps + /** \return True if texture has MipMaps, else false. */ + virtual bool hasMipMaps() const { return false; } + + //! Returns if the texture has an alpha channel + virtual bool hasAlpha() const { + return getColorFormat () == video::ECF_A8R8G8B8 || getColorFormat () == video::ECF_A1R5G5B5; + } + + //! Regenerates the mip map levels of the texture. + /** Required after modifying the texture, usually after calling unlock(). + \param mipmapData Optional parameter to pass in image data which will be + used instead of the previously stored or automatically generated mipmap + data. The data has to be a continuous pixel data for all mipmaps until + 1x1 pixel. Each mipmap has to be half the width and height of the previous + level. At least one pixel will be always kept.*/ + virtual void regenerateMipMapLevels(void* mipmapData=0) = 0; + + //! Check whether the texture is a render target + /** Render targets can be set as such in the video driver, in order to + render a scene into the texture. Once unbound as render target, they can + be used just as usual textures again. + \return True if this is a render target, otherwise false. */ + virtual bool isRenderTarget() const { return false; } + + //! Get name of texture (in most cases this is the filename) + const io::SNamedPath& getName() const { return NamedPath; } + +protected: + + //! Helper function, helps to get the desired texture creation format from the flags. + /** \return Either ETCF_ALWAYS_32_BIT, ETCF_ALWAYS_16_BIT, + ETCF_OPTIMIZED_FOR_QUALITY, or ETCF_OPTIMIZED_FOR_SPEED. */ + inline E_TEXTURE_CREATION_FLAG getTextureFormatFromFlags(u32 flags) + { + if (flags & ETCF_OPTIMIZED_FOR_SPEED) + return ETCF_OPTIMIZED_FOR_SPEED; + if (flags & ETCF_ALWAYS_16_BIT) + return ETCF_ALWAYS_16_BIT; + if (flags & ETCF_ALWAYS_32_BIT) + return ETCF_ALWAYS_32_BIT; + if (flags & ETCF_OPTIMIZED_FOR_QUALITY) + return ETCF_OPTIMIZED_FOR_QUALITY; + return ETCF_OPTIMIZED_FOR_SPEED; + } + + io::SNamedPath NamedPath; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/ITimer.h b/builddir/irrlicht-1.8.1/include/ITimer.h new file mode 100644 index 0000000..610d6fa --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ITimer.h @@ -0,0 +1,103 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_TIMER_H_INCLUDED__ +#define __I_TIMER_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ + +//! Interface for getting and manipulating the virtual time +class ITimer : public virtual IReferenceCounted +{ +public: + //! Returns current real time in milliseconds of the system. + /** This value does not start with 0 when the application starts. + For example in one implementation the value returned could be the + amount of milliseconds which have elapsed since the system was started. + */ + virtual u32 getRealTime() const = 0; + + enum EWeekday + { + EWD_SUNDAY=0, + EWD_MONDAY, + EWD_TUESDAY, + EWD_WEDNESDAY, + EWD_THURSDAY, + EWD_FRIDAY, + EWD_SATURDAY + }; + + struct RealTimeDate + { + // Hour of the day, from 0 to 23 + u32 Hour; + // Minute of the hour, from 0 to 59 + u32 Minute; + // Second of the minute, due to extra seconds from 0 to 61 + u32 Second; + // Year of the gregorian calender + s32 Year; + // Month of the year, from 1 to 12 + u32 Month; + // Day of the month, from 1 to 31 + u32 Day; + // Weekday for the current day + EWeekday Weekday; + // Day of the year, from 1 to 366 + u32 Yearday; + // Whether daylight saving is on + bool IsDST; + }; + + virtual RealTimeDate getRealTimeAndDate() const = 0; + + //! Returns current virtual time in milliseconds. + /** This value starts with 0 and can be manipulated using setTime(), + stopTimer(), startTimer(), etc. This value depends on the set speed of + the timer if the timer is stopped, etc. If you need the system time, + use getRealTime() */ + virtual u32 getTime() const = 0; + + //! sets current virtual time + virtual void setTime(u32 time) = 0; + + //! Stops the virtual timer. + /** The timer is reference counted, which means everything which calls + stop() will also have to call start(), otherwise the timer may not + start/stop correctly again. */ + virtual void stop() = 0; + + //! Starts the virtual timer. + /** The timer is reference counted, which means everything which calls + stop() will also have to call start(), otherwise the timer may not + start/stop correctly again. */ + virtual void start() = 0; + + //! Sets the speed of the timer + /** The speed is the factor with which the time is running faster or + slower then the real system time. */ + virtual void setSpeed(f32 speed = 1.0f) = 0; + + //! Returns current speed of the timer + /** The speed is the factor with which the time is running faster or + slower then the real system time. */ + virtual f32 getSpeed() const = 0; + + //! Returns if the virtual timer is currently stopped + virtual bool isStopped() const = 0; + + //! Advances the virtual time + /** Makes the virtual timer update the time value based on the real + time. This is called automatically when calling IrrlichtDevice::run(), + but you can call it manually if you don't use this method. */ + virtual void tick() = 0; +}; + +} // end namespace irr + +#endif diff --git a/builddir/irrlicht-1.8.1/include/ITriangleSelector.h b/builddir/irrlicht-1.8.1/include/ITriangleSelector.h new file mode 100644 index 0000000..9d038df --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/ITriangleSelector.h @@ -0,0 +1,131 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_TRIANGLE_SELECTOR_H_INCLUDED__ +#define __I_TRIANGLE_SELECTOR_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "triangle3d.h" +#include "aabbox3d.h" +#include "matrix4.h" +#include "line3d.h" + +namespace irr +{ +namespace scene +{ + +class ISceneNode; + +//! Interface to return triangles with specific properties. +/** Every ISceneNode may have a triangle selector, available with +ISceneNode::getTriangleScelector() or ISceneManager::createTriangleSelector. +This is used for doing collision detection: For example if you know, that a +collision may have happened in the area between (1,1,1) and (10,10,10), you +can get all triangles of the scene node in this area with the +ITriangleSelector easily and check every triangle if it collided. */ +class ITriangleSelector : public virtual IReferenceCounted +{ +public: + + //! Get amount of all available triangles in this selector + virtual s32 getTriangleCount() const = 0; + + //! Gets the triangles for one associated node. + /** + This returns all triangles for one scene node associated with this + selector. If there is more than one scene node associated (e.g. for + an IMetaTriangleSelector) this this function may be called multiple + times to retrieve all triangles. + \param triangles Array where the resulting triangles will be + written to. + \param arraySize Size of the target array. + \param outTriangleCount: Amount of triangles which have been written + into the array. + \param transform Pointer to matrix for transforming the triangles + before they are returned. Useful for example to scale all triangles + down into an ellipsoid space. If this pointer is null, no + transformation will be done. */ + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::matrix4* transform=0) const = 0; + + //! Gets the triangles for one associated node which may lie within a specific bounding box. + /** + This returns all triangles for one scene node associated with this + selector. If there is more than one scene node associated (e.g. for + an IMetaTriangleSelector) this this function may be called multiple + times to retrieve all triangles. + + This method will return at least the triangles that intersect the box, + but may return other triangles as well. + \param triangles Array where the resulting triangles will be written + to. + \param arraySize Size of the target array. + \param outTriangleCount Amount of triangles which have been written + into the array. + \param box Only triangles which are in this axis aligned bounding box + will be written into the array. + \param transform Pointer to matrix for transforming the triangles + before they are returned. Useful for example to scale all triangles + down into an ellipsoid space. If this pointer is null, no + transformation will be done. */ + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::aabbox3d<f32>& box, + const core::matrix4* transform=0) const = 0; + + //! Gets the triangles for one associated node which have or may have contact with a 3d line. + /** + This returns all triangles for one scene node associated with this + selector. If there is more than one scene node associated (e.g. for + an IMetaTriangleSelector) this this function may be called multiple + times to retrieve all triangles. + + Please note that unoptimized triangle selectors also may return + triangles which are not in contact at all with the 3d line. + \param triangles Array where the resulting triangles will be written + to. + \param arraySize Size of the target array. + \param outTriangleCount Amount of triangles which have been written + into the array. + \param line Only triangles which may be in contact with this 3d line + will be written into the array. + \param transform Pointer to matrix for transforming the triangles + before they are returned. Useful for example to scale all triangles + down into an ellipsoid space. If this pointer is null, no + transformation will be done. */ + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d<f32>& line, + const core::matrix4* transform=0) const = 0; + + //! Get scene node associated with a given triangle. + /** + This allows to find which scene node (potentially of several) is + associated with a specific triangle. + + \param triangleIndex: the index of the triangle for which you want to find + the associated scene node. + \return The scene node associated with that triangle. + */ + virtual ISceneNode* getSceneNodeForTriangle(u32 triangleIndex) const = 0; + + //! Get number of TriangleSelectors that are part of this one + /** Only useful for MetaTriangleSelector, others return 1 + */ + virtual u32 getSelectorCount() const = 0; + + //! Get TriangleSelector based on index based on getSelectorCount + /** Only useful for MetaTriangleSelector, others return 'this' or 0 + */ + virtual ITriangleSelector* getSelector(u32 index) = 0; + + //! Get TriangleSelector based on index based on getSelectorCount + /** Only useful for MetaTriangleSelector, others return 'this' or 0 + */ + virtual const ITriangleSelector* getSelector(u32 index) const = 0; +}; + +} // end namespace scene +} // end namespace irr + +#endif diff --git a/builddir/irrlicht-1.8.1/include/IVertexBuffer.h b/builddir/irrlicht-1.8.1/include/IVertexBuffer.h new file mode 100644 index 0000000..04606b2 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IVertexBuffer.h @@ -0,0 +1,52 @@ +// Copyright (C) 2008-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_VERTEX_BUFFER_H_INCLUDED__ +#define __I_VERTEX_BUFFER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrArray.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace scene +{ + + class IVertexBuffer : public virtual IReferenceCounted + { + public: + virtual void* getData() =0; + virtual video::E_VERTEX_TYPE getType() const =0; + virtual void setType(video::E_VERTEX_TYPE vertexType) =0; + virtual u32 stride() const =0; + virtual u32 size() const =0; + virtual void push_back(const video::S3DVertex &element) =0; + virtual video::S3DVertex& operator [](const u32 index) const =0; + virtual video::S3DVertex& getLast() =0; + virtual void set_used(u32 usedNow) =0; + virtual void reallocate(u32 new_size) =0; + virtual u32 allocated_size() const =0; + virtual video::S3DVertex* pointer() =0; + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint() const =0; + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint ) =0; + + //! flags the meshbuffer as changed, reloads hardware buffers + virtual void setDirty() =0; + + //! Get the currently used ID for identification of changes. + /** This shouldn't be used for anything outside the VideoDriver. */ + virtual u32 getChangedID() const = 0; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IVideoDriver.h b/builddir/irrlicht-1.8.1/include/IVideoDriver.h new file mode 100644 index 0000000..6e788f9 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IVideoDriver.h @@ -0,0 +1,1471 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_I_VIDEO_DRIVER_H_INCLUDED__ +#define __IRR_I_VIDEO_DRIVER_H_INCLUDED__ + +#include "rect.h" +#include "SColor.h" +#include "ITexture.h" +#include "irrArray.h" +#include "matrix4.h" +#include "plane3d.h" +#include "dimension2d.h" +#include "position2d.h" +#include "SMaterial.h" +#include "IMeshBuffer.h" +#include "triangle3d.h" +#include "EDriverTypes.h" +#include "EDriverFeatures.h" +#include "SExposedVideoData.h" + +namespace irr +{ +namespace io +{ + class IAttributes; + struct SAttributeReadWriteOptions; + class IReadFile; + class IWriteFile; +} // end namespace io +namespace scene +{ + class IMeshBuffer; + class IMesh; + class IMeshManipulator; + class ISceneNode; +} // end namespace scene + +namespace video +{ + struct S3DVertex; + struct S3DVertex2TCoords; + struct S3DVertexTangents; + struct SLight; + class IImageLoader; + class IImageWriter; + class IMaterialRenderer; + class IGPUProgrammingServices; + + //! enumeration for geometry transformation states + enum E_TRANSFORMATION_STATE + { + //! View transformation + ETS_VIEW = 0, + //! World transformation + ETS_WORLD, + //! Projection transformation + ETS_PROJECTION, + //! Texture transformation + ETS_TEXTURE_0, + //! Texture transformation + ETS_TEXTURE_1, + //! Texture transformation + ETS_TEXTURE_2, + //! Texture transformation + ETS_TEXTURE_3, +#if _IRR_MATERIAL_MAX_TEXTURES_>4 + //! Texture transformation + ETS_TEXTURE_4, +#if _IRR_MATERIAL_MAX_TEXTURES_>5 + //! Texture transformation + ETS_TEXTURE_5, +#if _IRR_MATERIAL_MAX_TEXTURES_>6 + //! Texture transformation + ETS_TEXTURE_6, +#if _IRR_MATERIAL_MAX_TEXTURES_>7 + //! Texture transformation + ETS_TEXTURE_7, +#endif +#endif +#endif +#endif + //! Not used + ETS_COUNT + }; + + //! enumeration for signaling resources which were lost after the last render cycle + /** These values can be signaled by the driver, telling the app that some resources + were lost and need to be recreated. Irrlicht will sometimes recreate the actual objects, + but the content needs to be recreated by the application. */ + enum E_LOST_RESOURCE + { + //! The whole device/driver is lost + ELR_DEVICE = 1, + //! All texture are lost, rare problem + ELR_TEXTURES = 2, + //! The Render Target Textures are lost, typical problem for D3D + ELR_RTTS = 4, + //! The HW buffers are lost, will be recreated automatically, but might require some more time this frame + ELR_HW_BUFFERS = 8 + }; + + //! Special render targets, which usually map to dedicated hardware + /** These render targets (besides 0 and 1) need not be supported by gfx cards */ + enum E_RENDER_TARGET + { + //! Render target is the main color frame buffer + ERT_FRAME_BUFFER=0, + //! Render target is a render texture + ERT_RENDER_TEXTURE, + //! Multi-Render target textures + ERT_MULTI_RENDER_TEXTURES, + //! Render target is the main color frame buffer + ERT_STEREO_LEFT_BUFFER, + //! Render target is the right color buffer (left is the main buffer) + ERT_STEREO_RIGHT_BUFFER, + //! Render to both stereo buffers at once + ERT_STEREO_BOTH_BUFFERS, + //! Auxiliary buffer 0 + ERT_AUX_BUFFER0, + //! Auxiliary buffer 1 + ERT_AUX_BUFFER1, + //! Auxiliary buffer 2 + ERT_AUX_BUFFER2, + //! Auxiliary buffer 3 + ERT_AUX_BUFFER3, + //! Auxiliary buffer 4 + ERT_AUX_BUFFER4 + }; + + //! Enum for the types of fog distributions to choose from + enum E_FOG_TYPE + { + EFT_FOG_EXP=0, + EFT_FOG_LINEAR, + EFT_FOG_EXP2 + }; + + const c8* const FogTypeNames[] = + { + "FogExp", + "FogLinear", + "FogExp2", + 0 + }; + + struct SOverrideMaterial + { + //! The Material values + SMaterial Material; + //! Which values are taken for override + /** OR'ed values from E_MATERIAL_FLAGS. */ + u32 EnableFlags; + //! Set in which render passes the material override is active. + /** OR'ed values from E_SCENE_NODE_RENDER_PASS. */ + u16 EnablePasses; + //! Global enable flag, overwritten by the SceneManager in each pass + /** The Scenemanager uses the EnablePass array and sets Enabled to + true if the Override material is enabled in the current pass. */ + bool Enabled; + + //! Default constructor + SOverrideMaterial() : EnableFlags(0), EnablePasses(0), Enabled(false) {} + + //! Apply the enabled overrides + void apply(SMaterial& material) + { + if (Enabled) + { + for (u32 i=0; i<32; ++i) + { + const u32 num=(1<<i); + if (EnableFlags & num) + { + switch (num) + { + case EMF_WIREFRAME: material.Wireframe = Material.Wireframe; break; + case EMF_POINTCLOUD: material.PointCloud = Material.PointCloud; break; + case EMF_GOURAUD_SHADING: material.GouraudShading = Material.GouraudShading; break; + case EMF_LIGHTING: material.Lighting = Material.Lighting; break; + case EMF_ZBUFFER: material.ZBuffer = Material.ZBuffer; break; + case EMF_ZWRITE_ENABLE: material.ZWriteEnable = Material.ZWriteEnable; break; + case EMF_BACK_FACE_CULLING: material.BackfaceCulling = Material.BackfaceCulling; break; + case EMF_FRONT_FACE_CULLING: material.FrontfaceCulling = Material.FrontfaceCulling; break; + case EMF_BILINEAR_FILTER: material.TextureLayer[0].BilinearFilter = Material.TextureLayer[0].BilinearFilter; break; + case EMF_TRILINEAR_FILTER: material.TextureLayer[0].TrilinearFilter = Material.TextureLayer[0].TrilinearFilter; break; + case EMF_ANISOTROPIC_FILTER: material.TextureLayer[0].AnisotropicFilter = Material.TextureLayer[0].AnisotropicFilter; break; + case EMF_FOG_ENABLE: material.FogEnable = Material.FogEnable; break; + case EMF_NORMALIZE_NORMALS: material.NormalizeNormals = Material.NormalizeNormals; break; + case EMF_TEXTURE_WRAP: + material.TextureLayer[0].TextureWrapU = Material.TextureLayer[0].TextureWrapU; + material.TextureLayer[0].TextureWrapV = Material.TextureLayer[0].TextureWrapV; + break; + case EMF_ANTI_ALIASING: material.AntiAliasing = Material.AntiAliasing; break; + case EMF_COLOR_MASK: material.ColorMask = Material.ColorMask; break; + case EMF_COLOR_MATERIAL: material.ColorMaterial = Material.ColorMaterial; break; + case EMF_USE_MIP_MAPS: material.UseMipMaps = Material.UseMipMaps; break; + case EMF_BLEND_OPERATION: material.BlendOperation = Material.BlendOperation; break; + case EMF_POLYGON_OFFSET: + material.PolygonOffsetDirection = Material.PolygonOffsetDirection; + material.PolygonOffsetFactor = Material.PolygonOffsetFactor; break; + } + } + } + } + } + + }; + + struct IRenderTarget + { + IRenderTarget(ITexture* texture, + E_COLOR_PLANE colorMask=ECP_ALL, + E_BLEND_FACTOR blendFuncSrc=EBF_ONE, + E_BLEND_FACTOR blendFuncDst=EBF_ONE_MINUS_SRC_ALPHA, + E_BLEND_OPERATION blendOp=EBO_NONE) : + RenderTexture(texture), + TargetType(ERT_RENDER_TEXTURE), ColorMask(colorMask), + BlendFuncSrc(blendFuncSrc), BlendFuncDst(blendFuncDst), + BlendOp(blendOp) {} + IRenderTarget(E_RENDER_TARGET target, + E_COLOR_PLANE colorMask=ECP_ALL, + E_BLEND_FACTOR blendFuncSrc=EBF_ONE, + E_BLEND_FACTOR blendFuncDst=EBF_ONE_MINUS_SRC_ALPHA, + E_BLEND_OPERATION blendOp=EBO_NONE) : + RenderTexture(0), + TargetType(target), ColorMask(colorMask), + BlendFuncSrc(blendFuncSrc), BlendFuncDst(blendFuncDst), + BlendOp(blendOp) {} + bool operator!=(const IRenderTarget& other) const + { + return ((RenderTexture != other.RenderTexture) || + (TargetType != other.TargetType) || + (ColorMask != other.ColorMask) || + (BlendFuncSrc != other.BlendFuncSrc) || + (BlendFuncDst != other.BlendFuncDst) || + (BlendOp != other.BlendOp)); + } + ITexture* RenderTexture; + E_RENDER_TARGET TargetType:8; + E_COLOR_PLANE ColorMask:8; + E_BLEND_FACTOR BlendFuncSrc:4; + E_BLEND_FACTOR BlendFuncDst:4; + E_BLEND_OPERATION BlendOp:4; + }; + + //! Interface to driver which is able to perform 2d and 3d graphics functions. + /** This interface is one of the most important interfaces of + the Irrlicht Engine: All rendering and texture manipulation is done with + this interface. You are able to use the Irrlicht Engine by only + invoking methods of this interface if you like to, although the + irr::scene::ISceneManager interface provides a lot of powerful classes + and methods to make the programmer's life easier. + */ + class IVideoDriver : public virtual IReferenceCounted + { + public: + + //! Applications must call this method before performing any rendering. + /** This method can clear the back- and the z-buffer. + \param backBuffer Specifies if the back buffer should be + cleared, which means that the screen is filled with the color + specified. If this parameter is false, the back buffer will + not be cleared and the color parameter is ignored. + \param zBuffer Specifies if the depth buffer (z buffer) should + be cleared. It is not nesesarry to do so if only 2d drawing is + used. + \param color The color used for back buffer clearing + \param videoData Handle of another window, if you want the + bitmap to be displayed on another window. If this is an empty + element, everything will be displayed in the default window. + Note: This feature is not fully implemented for all devices. + \param sourceRect Pointer to a rectangle defining the source + rectangle of the area to be presented. Set to null to present + everything. Note: not implemented in all devices. + \return False if failed. */ + virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, + SColor color=SColor(255,0,0,0), + const SExposedVideoData& videoData=SExposedVideoData(), + core::rect<s32>* sourceRect=0) =0; + + //! Presents the rendered image to the screen. + /** Applications must call this method after performing any + rendering. + \return False if failed and true if succeeded. */ + virtual bool endScene() =0; + + //! Queries the features of the driver. + /** Returns true if a feature is available + \param feature Feature to query. + \return True if the feature is available, false if not. */ + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const =0; + + //! Disable a feature of the driver. + /** Can also be used to enable the features again. It is not + possible to enable unsupported features this way, though. + \param feature Feature to disable. + \param flag When true the feature is disabled, otherwise it is enabled. */ + virtual void disableFeature(E_VIDEO_DRIVER_FEATURE feature, bool flag=true) =0; + + //! Get attributes of the actual video driver + /** The following names can be queried for the given types: + MaxTextures (int) The maximum number of simultaneous textures supported by the driver. This can be less than the supported number of textures of the driver. Use _IRR_MATERIAL_MAX_TEXTURES_ to adapt the number. + MaxSupportedTextures (int) The maximum number of simultaneous textures supported by the fixed function pipeline of the (hw) driver. The actual supported number of textures supported by the engine can be lower. + MaxLights (int) Number of hardware lights supported in the fixed function pipieline of the driver, typically 6-8. Use light manager or deferred shading for more. + MaxAnisotropy (int) Number of anisotropy levels supported for filtering. At least 1, max is typically at 16 or 32. + MaxUserClipPlanes (int) Number of additional clip planes, which can be set by the user via dedicated driver methods. + MaxAuxBuffers (int) Special render buffers, which are currently not really usable inside Irrlicht. Only supported by OpenGL + MaxMultipleRenderTargets (int) Number of render targets which can be bound simultaneously. Rendering to MRTs is done via shaders. + MaxIndices (int) Number of indices which can be used in one render call (i.e. one mesh buffer). + MaxTextureSize (int) Dimension that a texture may have, both in width and height. + MaxGeometryVerticesOut (int) Number of vertices the geometry shader can output in one pass. Only OpenGL so far. + MaxTextureLODBias (float) Maximum value for LOD bias. Is usually at around 16, but can be lower on some systems. + Version (int) Version of the driver. Should be Major*100+Minor + ShaderLanguageVersion (int) Version of the high level shader language. Should be Major*100+Minor. + AntiAlias (int) Number of Samples the driver uses for each pixel. 0 and 1 means anti aliasing is off, typical values are 2,4,8,16,32 + */ + virtual const io::IAttributes& getDriverAttributes() const=0; + + //! Check if the driver was recently reset. + /** For d3d devices you will need to recreate the RTTs if the + driver was reset. Should be queried right after beginScene(). + */ + virtual bool checkDriverReset() =0; + + //! Sets transformation matrices. + /** \param state Transformation type to be set, e.g. view, + world, or projection. + \param mat Matrix describing the transformation. */ + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) =0; + + //! Returns the transformation set by setTransform + /** \param state Transformation type to query + \return Matrix describing the transformation. */ + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const =0; + + //! Retrieve the number of image loaders + /** \return Number of image loaders */ + virtual u32 getImageLoaderCount() const = 0; + + //! Retrieve the given image loader + /** \param n The index of the loader to retrieve. This parameter is an 0-based + array index. + \return A pointer to the specified loader, 0 if the index is incorrect. */ + virtual IImageLoader* getImageLoader(u32 n) = 0; + + //! Retrieve the number of image writers + /** \return Number of image writers */ + virtual u32 getImageWriterCount() const = 0; + + //! Retrieve the given image writer + /** \param n The index of the writer to retrieve. This parameter is an 0-based + array index. + \return A pointer to the specified writer, 0 if the index is incorrect. */ + virtual IImageWriter* getImageWriter(u32 n) = 0; + + //! Sets a material. + /** All 3d drawing functions will draw geometry using this material thereafter. + \param material: Material to be used from now on. */ + virtual void setMaterial(const SMaterial& material) =0; + + //! Get access to a named texture. + /** Loads the texture from disk if it is not + already loaded and generates mipmap levels if desired. + Texture loading can be influenced using the + setTextureCreationFlag() method. The texture can be in several + imageformats, such as BMP, JPG, TGA, PCX, PNG, and PSD. + \param filename Filename of the texture to be loaded. + \return Pointer to the texture, or 0 if the texture + could not be loaded. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual ITexture* getTexture(const io::path& filename) = 0; + + //! Get access to a named texture. + /** Loads the texture from disk if it is not + already loaded and generates mipmap levels if desired. + Texture loading can be influenced using the + setTextureCreationFlag() method. The texture can be in several + imageformats, such as BMP, JPG, TGA, PCX, PNG, and PSD. + \param file Pointer to an already opened file. + \return Pointer to the texture, or 0 if the texture + could not be loaded. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual ITexture* getTexture(io::IReadFile* file) =0; + + //! Returns a texture by index + /** \param index: Index of the texture, must be smaller than + getTextureCount() Please note that this index might change when + adding or removing textures + \return Pointer to the texture, or 0 if the texture was not + set or index is out of bounds. This pointer should not be + dropped. See IReferenceCounted::drop() for more information. */ + virtual ITexture* getTextureByIndex(u32 index) =0; + + //! Returns amount of textures currently loaded + /** \return Amount of textures currently loaded */ + virtual u32 getTextureCount() const = 0; + + //! Renames a texture + /** \param texture Pointer to the texture to rename. + \param newName New name for the texture. This should be a unique name. */ + virtual void renameTexture(ITexture* texture, const io::path& newName) = 0; + + //! Creates an empty texture of specified size. + /** \param size: Size of the texture. + \param name A name for the texture. Later calls to + getTexture() with this name will return this texture + \param format Desired color format of the texture. Please note + that the driver may choose to create the texture in another + color format. + \return Pointer to the newly created texture. This pointer + should not be dropped. See IReferenceCounted::drop() for more + information. */ + virtual ITexture* addTexture(const core::dimension2d<u32>& size, + const io::path& name, ECOLOR_FORMAT format = ECF_A8R8G8B8) = 0; + + //! Creates a texture from an IImage. + /** \param name A name for the texture. Later calls of + getTexture() with this name will return this texture + \param image Image the texture is created from. + \param mipmapData Optional pointer to a set of images which + build up the whole mipmap set. Must be images of the same color + type as image. If this parameter is not given, the mipmaps are + derived from image. + \return Pointer to the newly created texture. This pointer + should not be dropped. See IReferenceCounted::drop() for more + information. */ + virtual ITexture* addTexture(const io::path& name, IImage* image, void* mipmapData=0) = 0; + + //! Adds a new render target texture to the texture cache. + /** \param size Size of the texture, in pixels. Width and + height should be a power of two (e.g. 64, 128, 256, 512, ...) + and it should not be bigger than the backbuffer, because it + shares the zbuffer with the screen buffer. + \param name An optional name for the RTT. + \param format The color format of the render target. Floating point formats are supported. + \return Pointer to the created texture or 0 if the texture + could not be created. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size, + const io::path& name = "rt", const ECOLOR_FORMAT format = ECF_UNKNOWN) =0; + + //! Removes a texture from the texture cache and deletes it. + /** This method can free a lot of memory! + Please note that after calling this, the pointer to the + ITexture may no longer be valid, if it was not grabbed before + by other parts of the engine for storing it longer. So it is a + good idea to set all materials which are using this texture to + 0 or another texture first. + \param texture Texture to delete from the engine cache. */ + virtual void removeTexture(ITexture* texture) =0; + + //! Removes all textures from the texture cache and deletes them. + /** This method can free a lot of memory! + Please note that after calling this, the pointer to the + ITexture may no longer be valid, if it was not grabbed before + by other parts of the engine for storing it longer. So it is a + good idea to set all materials which are using this texture to + 0 or another texture first. */ + virtual void removeAllTextures() =0; + + //! Remove hardware buffer + virtual void removeHardwareBuffer(const scene::IMeshBuffer* mb) =0; + + //! Remove all hardware buffers + virtual void removeAllHardwareBuffers() =0; + + //! Create occlusion query. + /** Use node for identification and mesh for occlusion test. */ + virtual void addOcclusionQuery(scene::ISceneNode* node, + const scene::IMesh* mesh=0) =0; + + //! Remove occlusion query. + virtual void removeOcclusionQuery(scene::ISceneNode* node) =0; + + //! Remove all occlusion queries. + virtual void removeAllOcclusionQueries() =0; + + //! Run occlusion query. Draws mesh stored in query. + /** If the mesh shall not be rendered visible, use + overrideMaterial to disable the color and depth buffer. */ + virtual void runOcclusionQuery(scene::ISceneNode* node, bool visible=false) =0; + + //! Run all occlusion queries. Draws all meshes stored in queries. + /** If the meshes shall not be rendered visible, use + overrideMaterial to disable the color and depth buffer. */ + virtual void runAllOcclusionQueries(bool visible=false) =0; + + //! Update occlusion query. Retrieves results from GPU. + /** If the query shall not block, set the flag to false. + Update might not occur in this case, though */ + virtual void updateOcclusionQuery(scene::ISceneNode* node, bool block=true) =0; + + //! Update all occlusion queries. Retrieves results from GPU. + /** If the query shall not block, set the flag to false. + Update might not occur in this case, though */ + virtual void updateAllOcclusionQueries(bool block=true) =0; + + //! Return query result. + /** Return value is the number of visible pixels/fragments. + The value is a safe approximation, i.e. can be larger than the + actual value of pixels. */ + virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const =0; + + //! Sets a boolean alpha channel on the texture based on a color key. + /** This makes the texture fully transparent at the texels where + this color key can be found when using for example draw2DImage + with useAlphachannel==true. The alpha of other texels is not modified. + \param texture Texture whose alpha channel is modified. + \param color Color key color. Every texel with this color will + become fully transparent as described above. Please note that the + colors of a texture may be converted when loading it, so the + color values may not be exactly the same in the engine and for + example in picture edit programs. To avoid this problem, you + could use the makeColorKeyTexture method, which takes the + position of a pixel instead a color value. + \param zeroTexels \deprecated If set to true, then any texels that match + the color key will have their color, as well as their alpha, set to zero + (i.e. black). This behavior matches the legacy (buggy) behavior prior + to release 1.5 and is provided for backwards compatibility only. + This parameter may be removed by Irrlicht 1.9. */ + virtual void makeColorKeyTexture(video::ITexture* texture, + video::SColor color, + bool zeroTexels = false) const =0; + + //! Sets a boolean alpha channel on the texture based on the color at a position. + /** This makes the texture fully transparent at the texels where + the color key can be found when using for example draw2DImage + with useAlphachannel==true. The alpha of other texels is not modified. + \param texture Texture whose alpha channel is modified. + \param colorKeyPixelPos Position of a pixel with the color key + color. Every texel with this color will become fully transparent as + described above. + \param zeroTexels \deprecated If set to true, then any texels that match + the color key will have their color, as well as their alpha, set to zero + (i.e. black). This behavior matches the legacy (buggy) behavior prior + to release 1.5 and is provided for backwards compatibility only. + This parameter may be removed by Irrlicht 1.9. */ + virtual void makeColorKeyTexture(video::ITexture* texture, + core::position2d<s32> colorKeyPixelPos, + bool zeroTexels = false) const =0; + + //! Creates a normal map from a height map texture. + /** If the target texture has 32 bit, the height value is + stored in the alpha component of the texture as addition. This + value is used by the video::EMT_PARALLAX_MAP_SOLID material and + similar materials. + \param texture Texture whose alpha channel is modified. + \param amplitude Constant value by which the height + information is multiplied.*/ + virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const =0; + + //! Sets a new render target. + /** This will only work if the driver supports the + EVDF_RENDER_TO_TARGET feature, which can be queried with + queryFeature(). Usually, rendering to textures is done in this + way: + \code + // create render target + ITexture* target = driver->addRenderTargetTexture(core::dimension2d<u32>(128,128), "rtt1"); + + // ... + + driver->setRenderTarget(target); // set render target + // .. draw stuff here + driver->setRenderTarget(0); // set previous render target + \endcode + Please note that you cannot render 3D or 2D geometry with a + render target as texture on it when you are rendering the scene + into this render target at the same time. It is usually only + possible to render into a texture between the + IVideoDriver::beginScene() and endScene() method calls. + \param texture New render target. Must be a texture created with + IVideoDriver::addRenderTargetTexture(). If set to 0, it sets + the previous render target which was set before the last + setRenderTarget() call. + \param clearBackBuffer Clears the backbuffer of the render + target with the color parameter + \param clearZBuffer Clears the zBuffer of the rendertarget. + Note that because the frame buffer may share the zbuffer with + the rendertarget, its zbuffer might be partially cleared too + by this. + \param color The background color for the render target. + \return True if sucessful and false if not. */ + virtual bool setRenderTarget(video::ITexture* texture, + bool clearBackBuffer=true, bool clearZBuffer=true, + SColor color=video::SColor(0,0,0,0)) =0; + + //! set or reset special render targets + /** This method enables access to special color buffers such as + stereoscopic buffers or auxiliary buffers. + \param target Enum value for the render target + \param clearTarget Clears the target buffer with the color + parameter + \param clearZBuffer Clears the zBuffer of the rendertarget. + Note that because the main frame buffer may share the zbuffer with + the rendertarget, its zbuffer might be partially cleared too + by this. + \param color The background color for the render target. + \return True if sucessful and false if not. */ + virtual bool setRenderTarget(E_RENDER_TARGET target, bool clearTarget=true, + bool clearZBuffer=true, + SColor color=video::SColor(0,0,0,0)) =0; + + //! Sets new multiple render targets. + virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture, + bool clearBackBuffer=true, bool clearZBuffer=true, + SColor color=video::SColor(0,0,0,0)) =0; + + //! Sets a new viewport. + /** Every rendering operation is done into this new area. + \param area: Rectangle defining the new area of rendering + operations. */ + virtual void setViewPort(const core::rect<s32>& area) =0; + + //! Gets the area of the current viewport. + /** \return Rectangle of the current viewport. */ + virtual const core::rect<s32>& getViewPort() const =0; + + //! Draws a vertex primitive list + /** Note that, depending on the index type, some vertices might be not + accessible through the index list. The limit is at 65535 vertices for 16bit + indices. Please note that currently not all primitives are available for + all drivers, and some might be emulated via triangle renders. + \param vertices Pointer to array of vertices. + \param vertexCount Amount of vertices in the array. + \param indexList Pointer to array of indices. These define the vertices used + for each primitive. Depending on the pType, indices are interpreted as single + objects (for point like primitives), pairs (for lines), triplets (for + triangles), or quads. + \param primCount Amount of Primitives + \param vType Vertex type, e.g. video::EVT_STANDARD for S3DVertex. + \param pType Primitive type, e.g. scene::EPT_TRIANGLE_FAN for a triangle fan. + \param iType Index type, e.g. video::EIT_16BIT for 16bit indices. */ + virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primCount, + E_VERTEX_TYPE vType=EVT_STANDARD, + scene::E_PRIMITIVE_TYPE pType=scene::EPT_TRIANGLES, + E_INDEX_TYPE iType=EIT_16BIT) =0; + + //! Draws a vertex primitive list in 2d + /** Compared to the general (3d) version of this method, this + one sets up a 2d render mode, and uses only x and y of vectors. + Note that, depending on the index type, some vertices might be + not accessible through the index list. The limit is at 65535 + vertices for 16bit indices. Please note that currently not all + primitives are available for all drivers, and some might be + emulated via triangle renders. This function is not available + for the sw drivers. + \param vertices Pointer to array of vertices. + \param vertexCount Amount of vertices in the array. + \param indexList Pointer to array of indices. These define the + vertices used for each primitive. Depending on the pType, + indices are interpreted as single objects (for point like + primitives), pairs (for lines), triplets (for triangles), or + quads. + \param primCount Amount of Primitives + \param vType Vertex type, e.g. video::EVT_STANDARD for S3DVertex. + \param pType Primitive type, e.g. scene::EPT_TRIANGLE_FAN for a triangle fan. + \param iType Index type, e.g. video::EIT_16BIT for 16bit indices. */ + virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primCount, + E_VERTEX_TYPE vType=EVT_STANDARD, + scene::E_PRIMITIVE_TYPE pType=scene::EPT_TRIANGLES, + E_INDEX_TYPE iType=EIT_16BIT) =0; + + //! Draws an indexed triangle list. + /** Note that there may be at maximum 65536 vertices, because + the index list is an array of 16 bit values each with a maximum + value of 65536. If there are more than 65536 vertices in the + list, results of this operation are not defined. + \param vertices Pointer to array of vertices. + \param vertexCount Amount of vertices in the array. + \param indexList Pointer to array of indices. + \param triangleCount Amount of Triangles. Usually amount of indices / 3. */ + void drawIndexedTriangleList(const S3DVertex* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) + { + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT); + } + + //! Draws an indexed triangle list. + /** Note that there may be at maximum 65536 vertices, because + the index list is an array of 16 bit values each with a maximum + value of 65536. If there are more than 65536 vertices in the + list, results of this operation are not defined. + \param vertices Pointer to array of vertices. + \param vertexCount Amount of vertices in the array. + \param indexList Pointer to array of indices. + \param triangleCount Amount of Triangles. Usually amount of indices / 3. */ + void drawIndexedTriangleList(const S3DVertex2TCoords* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) + { + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_2TCOORDS, scene::EPT_TRIANGLES, EIT_16BIT); + } + + //! Draws an indexed triangle list. + /** Note that there may be at maximum 65536 vertices, because + the index list is an array of 16 bit values each with a maximum + value of 65536. If there are more than 65536 vertices in the + list, results of this operation are not defined. + \param vertices Pointer to array of vertices. + \param vertexCount Amount of vertices in the array. + \param indexList Pointer to array of indices. + \param triangleCount Amount of Triangles. Usually amount of indices / 3. */ + void drawIndexedTriangleList(const S3DVertexTangents* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) + { + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_TANGENTS, scene::EPT_TRIANGLES, EIT_16BIT); + } + + //! Draws an indexed triangle fan. + /** Note that there may be at maximum 65536 vertices, because + the index list is an array of 16 bit values each with a maximum + value of 65536. If there are more than 65536 vertices in the + list, results of this operation are not defined. + \param vertices Pointer to array of vertices. + \param vertexCount Amount of vertices in the array. + \param indexList Pointer to array of indices. + \param triangleCount Amount of Triangles. Usually amount of indices - 2. */ + void drawIndexedTriangleFan(const S3DVertex* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) + { + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_STANDARD, scene::EPT_TRIANGLE_FAN, EIT_16BIT); + } + + //! Draws an indexed triangle fan. + /** Note that there may be at maximum 65536 vertices, because + the index list is an array of 16 bit values each with a maximum + value of 65536. If there are more than 65536 vertices in the + list, results of this operation are not defined. + \param vertices Pointer to array of vertices. + \param vertexCount Amount of vertices in the array. + \param indexList Pointer to array of indices. + \param triangleCount Amount of Triangles. Usually amount of indices - 2. */ + void drawIndexedTriangleFan(const S3DVertex2TCoords* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) + { + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_2TCOORDS, scene::EPT_TRIANGLE_FAN, EIT_16BIT); + } + + //! Draws an indexed triangle fan. + /** Note that there may be at maximum 65536 vertices, because + the index list is an array of 16 bit values each with a maximum + value of 65536. If there are more than 65536 vertices in the + list, results of this operation are not defined. + \param vertices Pointer to array of vertices. + \param vertexCount Amount of vertices in the array. + \param indexList Pointer to array of indices. + \param triangleCount Amount of Triangles. Usually amount of indices - 2. */ + void drawIndexedTriangleFan(const S3DVertexTangents* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) + { + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_TANGENTS, scene::EPT_TRIANGLE_FAN, EIT_16BIT); + } + + //! Draws a 3d line. + /** For some implementations, this method simply calls + drawVertexPrimitiveList for some triangles. + Note that the line is drawn using the current transformation + matrix and material. So if you need to draw the 3D line + independently of the current transformation, use + \code + driver->setMaterial(someMaterial); + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + \endcode + for some properly set up material before drawing the line. + Some drivers support line thickness set in the material. + \param start Start of the 3d line. + \param end End of the 3d line. + \param color Color of the line. */ + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)) =0; + + //! Draws a 3d triangle. + /** This method calls drawVertexPrimitiveList for some triangles. + This method works with all drivers because it simply calls + drawVertexPrimitiveList, but it is hence not very fast. + Note that the triangle is drawn using the current + transformation matrix and material. So if you need to draw it + independently of the current transformation, use + \code + driver->setMaterial(someMaterial); + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + \endcode + for some properly set up material before drawing the triangle. + \param triangle The triangle to draw. + \param color Color of the line. */ + virtual void draw3DTriangle(const core::triangle3df& triangle, + SColor color = SColor(255,255,255,255)) =0; + + //! Draws a 3d axis aligned box. + /** This method simply calls draw3DLine for the edges of the + box. Note that the box is drawn using the current transformation + matrix and material. So if you need to draw it independently of + the current transformation, use + \code + driver->setMaterial(someMaterial); + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + \endcode + for some properly set up material before drawing the box. + \param box The axis aligned box to draw + \param color Color to use while drawing the box. */ + virtual void draw3DBox(const core::aabbox3d<f32>& box, + SColor color = SColor(255,255,255,255)) =0; + + //! Draws a 2d image without any special effects + /** \param texture Pointer to texture to use. + \param destPos Upper left 2d destination position where the + image will be drawn. */ + virtual void draw2DImage(const video::ITexture* texture, + const core::position2d<s32>& destPos) =0; + + //! Draws a 2d image using a color + /** (if color is other than + Color(255,255,255,255)) and the alpha channel of the texture. + \param texture Texture to be drawn. + \param destPos Upper left 2d destination position where the + image will be drawn. + \param sourceRect Source rectangle in the image. + \param clipRect Pointer to rectangle on the screen where the + image is clipped to. + If this pointer is NULL the image is not clipped. + \param color Color with which the image is drawn. If the color + equals Color(255,255,255,255) it is ignored. Note that the + alpha component is used: If alpha is other than 255, the image + will be transparent. + \param useAlphaChannelOfTexture: If true, the alpha channel of + the texture is used to draw the image.*/ + virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, + const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect =0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false) =0; + + //! Draws a set of 2d images, using a color and the alpha channel of the texture. + /** The images are drawn beginning at pos and concatenated in + one line. All drawings are clipped against clipRect (if != 0). + The subtextures are defined by the array of sourceRects and are + chosen by the indices given. + \param texture Texture to be drawn. + \param pos Upper left 2d destination position where the image + will be drawn. + \param sourceRects Source rectangles of the image. + \param indices List of indices which choose the actual + rectangle used each time. + \param kerningWidth Offset to Position on X + \param clipRect Pointer to rectangle on the screen where the + image is clipped to. + If this pointer is 0 then the image is not clipped. + \param color Color with which the image is drawn. + Note that the alpha component is used. If alpha is other than + 255, the image will be transparent. + \param useAlphaChannelOfTexture: If true, the alpha channel of + the texture is used to draw the image. */ + virtual void draw2DImageBatch(const video::ITexture* texture, + const core::position2d<s32>& pos, + const core::array<core::rect<s32> >& sourceRects, + const core::array<s32>& indices, + s32 kerningWidth=0, + const core::rect<s32>* clipRect=0, + SColor color=SColor(255,255,255,255), + bool useAlphaChannelOfTexture=false) =0; + + //! Draws a set of 2d images, using a color and the alpha channel of the texture. + /** All drawings are clipped against clipRect (if != 0). + The subtextures are defined by the array of sourceRects and are + positioned using the array of positions. + \param texture Texture to be drawn. + \param positions Array of upper left 2d destinations where the + images will be drawn. + \param sourceRects Source rectangles of the image. + \param clipRect Pointer to rectangle on the screen where the + images are clipped to. + If this pointer is 0 then the image is not clipped. + \param color Color with which the image is drawn. + Note that the alpha component is used. If alpha is other than + 255, the image will be transparent. + \param useAlphaChannelOfTexture: If true, the alpha channel of + the texture is used to draw the image. */ + virtual void draw2DImageBatch(const video::ITexture* texture, + const core::array<core::position2d<s32> >& positions, + const core::array<core::rect<s32> >& sourceRects, + const core::rect<s32>* clipRect=0, + SColor color=SColor(255,255,255,255), + bool useAlphaChannelOfTexture=false) =0; + + //! Draws a part of the texture into the rectangle. Note that colors must be an array of 4 colors if used. + /** Suggested and first implemented by zola. + \param texture The texture to draw from + \param destRect The rectangle to draw into + \param sourceRect The rectangle denoting a part of the texture + \param clipRect Clips the destination rectangle (may be 0) + \param colors Array of 4 colors denoting the color values of + the corners of the destRect + \param useAlphaChannelOfTexture True if alpha channel will be + blended. */ + virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect, + const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect =0, + const video::SColor * const colors=0, bool useAlphaChannelOfTexture=false) =0; + + //! Draws a 2d rectangle. + /** \param color Color of the rectangle to draw. The alpha + component will not be ignored and specifies how transparent the + rectangle will be. + \param pos Position of the rectangle. + \param clip Pointer to rectangle against which the rectangle + will be clipped. If the pointer is null, no clipping will be + performed. */ + virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos, + const core::rect<s32>* clip =0) =0; + + //! Draws a 2d rectangle with a gradient. + /** \param colorLeftUp Color of the upper left corner to draw. + The alpha component will not be ignored and specifies how + transparent the rectangle will be. + \param colorRightUp Color of the upper right corner to draw. + The alpha component will not be ignored and specifies how + transparent the rectangle will be. + \param colorLeftDown Color of the lower left corner to draw. + The alpha component will not be ignored and specifies how + transparent the rectangle will be. + \param colorRightDown Color of the lower right corner to draw. + The alpha component will not be ignored and specifies how + transparent the rectangle will be. + \param pos Position of the rectangle. + \param clip Pointer to rectangle against which the rectangle + will be clipped. If the pointer is null, no clipping will be + performed. */ + virtual void draw2DRectangle(const core::rect<s32>& pos, + SColor colorLeftUp, SColor colorRightUp, + SColor colorLeftDown, SColor colorRightDown, + const core::rect<s32>* clip =0) =0; + + //! Draws the outline of a 2D rectangle. + /** \param pos Position of the rectangle. + \param color Color of the rectangle to draw. The alpha component + specifies how transparent the rectangle outline will be. */ + virtual void draw2DRectangleOutline(const core::recti& pos, + SColor color=SColor(255,255,255,255)) =0; + + //! Draws a 2d line. Both start and end will be included in coloring. + /** \param start Screen coordinates of the start of the line + in pixels. + \param end Screen coordinates of the start of the line in + pixels. + \param color Color of the line to draw. */ + virtual void draw2DLine(const core::position2d<s32>& start, + const core::position2d<s32>& end, + SColor color=SColor(255,255,255,255)) =0; + + //! Draws a pixel. + /** \param x The x-position of the pixel. + \param y The y-position of the pixel. + \param color Color of the pixel to draw. */ + virtual void drawPixel(u32 x, u32 y, const SColor& color) =0; + + //! Draws a non filled concyclic regular 2d polyon. + /** This method can be used to draw circles, but also + triangles, tetragons, pentagons, hexagons, heptagons, octagons, + enneagons, decagons, hendecagons, dodecagon, triskaidecagons, + etc. I think you'll got it now. And all this by simply + specifying the vertex count. Welcome to the wonders of + geometry. + \param center Position of center of circle (pixels). + \param radius Radius of circle in pixels. + \param color Color of the circle. + \param vertexCount Amount of vertices of the polygon. Specify 2 + to draw a line, 3 to draw a triangle, 4 for tetragons and a lot + (>10) for nearly a circle. */ + virtual void draw2DPolygon(core::position2d<s32> center, + f32 radius, + video::SColor color=SColor(100,255,255,255), + s32 vertexCount=10) =0; + + //! Draws a shadow volume into the stencil buffer. + /** To draw a stencil shadow, do this: First, draw all geometry. + Then use this method, to draw the shadow volume. Then, use + IVideoDriver::drawStencilShadow() to visualize the shadow. + Please note that the code for the opengl version of the method + is based on free code sent in by Philipp Dortmann, lots of + thanks go to him! + \param triangles Array of 3d vectors, specifying the shadow + volume. + \param zfail If set to true, zfail method is used, otherwise + zpass. + \param debugDataVisible The debug data that is enabled for this + shadow node + */ + virtual void drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail=true, u32 debugDataVisible=0) =0; + + //! Fills the stencil shadow with color. + /** After the shadow volume has been drawn into the stencil + buffer using IVideoDriver::drawStencilShadowVolume(), use this + to draw the color of the shadow. + Please note that the code for the opengl version of the method + is based on free code sent in by Philipp Dortmann, lots of + thanks go to him! + \param clearStencilBuffer Set this to false, if you want to + draw every shadow with the same color, and only want to call + drawStencilShadow() once after all shadow volumes have been + drawn. Set this to true, if you want to paint every shadow with + its own color. + \param leftUpEdge Color of the shadow in the upper left corner + of screen. + \param rightUpEdge Color of the shadow in the upper right + corner of screen. + \param leftDownEdge Color of the shadow in the lower left + corner of screen. + \param rightDownEdge Color of the shadow in the lower right + corner of screen. */ + virtual void drawStencilShadow(bool clearStencilBuffer=false, + video::SColor leftUpEdge = video::SColor(255,0,0,0), + video::SColor rightUpEdge = video::SColor(255,0,0,0), + video::SColor leftDownEdge = video::SColor(255,0,0,0), + video::SColor rightDownEdge = video::SColor(255,0,0,0)) =0; + + //! Draws a mesh buffer + /** \param mb Buffer to draw */ + virtual void drawMeshBuffer(const scene::IMeshBuffer* mb) =0; + + //! Draws normals of a mesh buffer + /** \param mb Buffer to draw the normals of + \param length length scale factor of the normals + \param color Color the normals are rendered with + */ + virtual void drawMeshBufferNormals(const scene::IMeshBuffer* mb, f32 length=10.f, SColor color=0xffffffff) =0; + + //! Sets the fog mode. + /** These are global values attached to each 3d object rendered, + which has the fog flag enabled in its material. + \param color Color of the fog + \param fogType Type of fog used + \param start Only used in linear fog mode (linearFog=true). + Specifies where fog starts. + \param end Only used in linear fog mode (linearFog=true). + Specifies where fog ends. + \param density Only used in exponential fog mode + (linearFog=false). Must be a value between 0 and 1. + \param pixelFog Set this to false for vertex fog, and true if + you want per-pixel fog. + \param rangeFog Set this to true to enable range-based vertex + fog. The distance from the viewer is used to compute the fog, + not the z-coordinate. This is better, but slower. This might not + be available with all drivers and fog settings. */ + virtual void setFog(SColor color=SColor(0,255,255,255), + E_FOG_TYPE fogType=EFT_FOG_LINEAR, + f32 start=50.0f, f32 end=100.0f, f32 density=0.01f, + bool pixelFog=false, bool rangeFog=false) =0; + + //! Gets the fog mode. + virtual void getFog(SColor& color, E_FOG_TYPE& fogType, + f32& start, f32& end, f32& density, + bool& pixelFog, bool& rangeFog) = 0; + + //! Get the current color format of the color buffer + /** \return Color format of the color buffer. */ + virtual ECOLOR_FORMAT getColorFormat() const =0; + + //! Get the size of the screen or render window. + /** \return Size of screen or render window. */ + virtual const core::dimension2d<u32>& getScreenSize() const =0; + + //! Get the size of the current render target + /** This method will return the screen size if the driver + doesn't support render to texture, or if the current render + target is the screen. + \return Size of render target or screen/window */ + virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const =0; + + //! Returns current frames per second value. + /** This value is updated approximately every 1.5 seconds and + is only intended to provide a rough guide to the average frame + rate. It is not suitable for use in performing timing + calculations or framerate independent movement. + \return Approximate amount of frames per second drawn. */ + virtual s32 getFPS() const =0; + + //! Returns amount of primitives (mostly triangles) which were drawn in the last frame. + /** Together with getFPS() very useful method for statistics. + \param mode Defines if the primitives drawn are accumulated or + counted per frame. + \return Amount of primitives drawn in the last frame. */ + virtual u32 getPrimitiveCountDrawn( u32 mode =0 ) const =0; + + //! Deletes all dynamic lights which were previously added with addDynamicLight(). + virtual void deleteAllDynamicLights() =0; + + //! adds a dynamic light, returning an index to the light + //! \param light: the light data to use to create the light + //! \return An index to the light, or -1 if an error occurs + virtual s32 addDynamicLight(const SLight& light) =0; + + //! Returns the maximal amount of dynamic lights the device can handle + /** \return Maximal amount of dynamic lights. */ + virtual u32 getMaximalDynamicLightAmount() const =0; + + //! Returns amount of dynamic lights currently set + /** \return Amount of dynamic lights currently set */ + virtual u32 getDynamicLightCount() const =0; + + //! Returns light data which was previously set by IVideoDriver::addDynamicLight(). + /** \param idx Zero based index of the light. Must be 0 or + greater and smaller than IVideoDriver::getDynamicLightCount. + \return Light data. */ + virtual const SLight& getDynamicLight(u32 idx) const =0; + + //! Turns a dynamic light on or off + //! \param lightIndex: the index returned by addDynamicLight + //! \param turnOn: true to turn the light on, false to turn it off + virtual void turnLightOn(s32 lightIndex, bool turnOn) =0; + + //! Gets name of this video driver. + /** \return Returns the name of the video driver, e.g. in case + of the Direct3D8 driver, it would return "Direct3D 8.1". */ + virtual const wchar_t* getName() const =0; + + //! Adds an external image loader to the engine. + /** This is useful if the Irrlicht Engine should be able to load + textures of currently unsupported file formats (e.g. gif). The + IImageLoader only needs to be implemented for loading this file + format. A pointer to the implementation can be passed to the + engine using this method. + \param loader Pointer to the external loader created. */ + virtual void addExternalImageLoader(IImageLoader* loader) =0; + + //! Adds an external image writer to the engine. + /** This is useful if the Irrlicht Engine should be able to + write textures of currently unsupported file formats (e.g + .gif). The IImageWriter only needs to be implemented for + writing this file format. A pointer to the implementation can + be passed to the engine using this method. + \param writer: Pointer to the external writer created. */ + virtual void addExternalImageWriter(IImageWriter* writer) =0; + + //! Returns the maximum amount of primitives + /** (mostly vertices) which the device is able to render with + one drawVertexPrimitiveList call. + \return Maximum amount of primitives. */ + virtual u32 getMaximalPrimitiveCount() const =0; + + //! Enables or disables a texture creation flag. + /** These flags define how textures should be created. By + changing this value, you can influence for example the speed of + rendering a lot. But please note that the video drivers take + this value only as recommendation. It could happen that you + enable the ETCF_ALWAYS_16_BIT mode, but the driver still creates + 32 bit textures. + \param flag Texture creation flag. + \param enabled Specifies if the given flag should be enabled or + disabled. */ + virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled=true) =0; + + //! Returns if a texture creation flag is enabled or disabled. + /** You can change this value using setTextureCreationFlag(). + \param flag Texture creation flag. + \return The current texture creation flag enabled mode. */ + virtual bool getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const =0; + + //! Creates a software image from a file. + /** No hardware texture will be created for this image. This + method is useful for example if you want to read a heightmap + for a terrain renderer. + \param filename Name of the file from which the image is + created. + \return The created image. + If you no longer need the image, you should call IImage::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IImage* createImageFromFile(const io::path& filename) = 0; + + //! Creates a software image from a file. + /** No hardware texture will be created for this image. This + method is useful for example if you want to read a heightmap + for a terrain renderer. + \param file File from which the image is created. + \return The created image. + If you no longer need the image, you should call IImage::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IImage* createImageFromFile(io::IReadFile* file) =0; + + //! Writes the provided image to a file. + /** Requires that there is a suitable image writer registered + for writing the image. + \param image Image to write. + \param filename Name of the file to write. + \param param Control parameter for the backend (e.g. compression + level). + \return True on successful write. */ + virtual bool writeImageToFile(IImage* image, const io::path& filename, u32 param = 0) = 0; + + //! Writes the provided image to a file. + /** Requires that there is a suitable image writer registered + for writing the image. + \param image Image to write. + \param file An already open io::IWriteFile object. The name + will be used to determine the appropriate image writer to use. + \param param Control parameter for the backend (e.g. compression + level). + \return True on successful write. */ + virtual bool writeImageToFile(IImage* image, io::IWriteFile* file, u32 param =0) =0; + + //! Creates a software image from a byte array. + /** No hardware texture will be created for this image. This + method is useful for example if you want to read a heightmap + for a terrain renderer. + \param format Desired color format of the texture + \param size Desired size of the image + \param data A byte array with pixel color information + \param ownForeignMemory If true, the image will use the data + pointer directly and own it afterwards. If false, the memory + will by copied internally. + \param deleteMemory Whether the memory is deallocated upon + destruction. + \return The created image. + If you no longer need the image, you should call IImage::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IImage* createImageFromData(ECOLOR_FORMAT format, + const core::dimension2d<u32>& size, void *data, + bool ownForeignMemory=false, + bool deleteMemory = true) =0; + + //! Creates an empty software image. + /** + \param format Desired color format of the image. + \param size Size of the image to create. + \return The created image. + If you no longer need the image, you should call IImage::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IImage* createImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) =0; + + //! Creates a software image by converting it to given format from another image. + /** \deprecated Create an empty image and use copyTo(). This method may be removed by Irrlicht 1.9. + \param format Desired color format of the image. + \param imageToCopy Image to copy to the new image. + \return The created image. + If you no longer need the image, you should call IImage::drop(). + See IReferenceCounted::drop() for more information. */ + _IRR_DEPRECATED_ virtual IImage* createImage(ECOLOR_FORMAT format, IImage *imageToCopy) =0; + + //! Creates a software image from a part of another image. + /** \deprecated Create an empty image and use copyTo(). This method may be removed by Irrlicht 1.9. + \param imageToCopy Image to copy to the new image in part. + \param pos Position of rectangle to copy. + \param size Extents of rectangle to copy. + \return The created image. + If you no longer need the image, you should call IImage::drop(). + See IReferenceCounted::drop() for more information. */ + _IRR_DEPRECATED_ virtual IImage* createImage(IImage* imageToCopy, + const core::position2d<s32>& pos, + const core::dimension2d<u32>& size) =0; + + //! Creates a software image from a part of a texture. + /** + \param texture Texture to copy to the new image in part. + \param pos Position of rectangle to copy. + \param size Extents of rectangle to copy. + \return The created image. + If you no longer need the image, you should call IImage::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IImage* createImage(ITexture* texture, + const core::position2d<s32>& pos, + const core::dimension2d<u32>& size) =0; + + //! Event handler for resize events. Only used by the engine internally. + /** Used to notify the driver that the window was resized. + Usually, there is no need to call this method. */ + virtual void OnResize(const core::dimension2d<u32>& size) =0; + + //! Adds a new material renderer to the video device. + /** Use this method to extend the VideoDriver with new material + types. To extend the engine using this method do the following: + Derive a class from IMaterialRenderer and override the methods + you need. For setting the right renderstates, you can try to + get a pointer to the real rendering device using + IVideoDriver::getExposedVideoData(). Add your class with + IVideoDriver::addMaterialRenderer(). To use an object being + displayed with your new material, set the MaterialType member of + the SMaterial struct to the value returned by this method. + If you simply want to create a new material using vertex and/or + pixel shaders it would be easier to use the + video::IGPUProgrammingServices interface which you can get + using the getGPUProgrammingServices() method. + \param renderer A pointer to the new renderer. + \param name Optional name for the material renderer entry. + \return The number of the material type which can be set in + SMaterial::MaterialType to use the renderer. -1 is returned if + an error occured. For example if you tried to add an material + renderer to the software renderer or the null device, which do + not accept material renderers. */ + virtual s32 addMaterialRenderer(IMaterialRenderer* renderer, const c8* name =0) =0; + + //! Get access to a material renderer by index. + /** \param idx Id of the material renderer. Can be a value of + the E_MATERIAL_TYPE enum or a value which was returned by + addMaterialRenderer(). + \return Pointer to material renderer or null if not existing. */ + virtual IMaterialRenderer* getMaterialRenderer(u32 idx) =0; + + //! Get amount of currently available material renderers. + /** \return Amount of currently available material renderers. */ + virtual u32 getMaterialRendererCount() const =0; + + //! Get name of a material renderer + /** This string can, e.g., be used to test if a specific + renderer already has been registered/created, or use this + string to store data about materials: This returned name will + be also used when serializing materials. + \param idx Id of the material renderer. Can be a value of the + E_MATERIAL_TYPE enum or a value which was returned by + addMaterialRenderer(). + \return String with the name of the renderer, or 0 if not + exisiting */ + virtual const c8* getMaterialRendererName(u32 idx) const =0; + + //! Sets the name of a material renderer. + /** Will have no effect on built-in material renderers. + \param idx: Id of the material renderer. Can be a value of the + E_MATERIAL_TYPE enum or a value which was returned by + addMaterialRenderer(). + \param name: New name of the material renderer. */ + virtual void setMaterialRendererName(s32 idx, const c8* name) =0; + + //! Creates material attributes list from a material + /** This method is useful for serialization and more. + Please note that the video driver will use the material + renderer names from getMaterialRendererName() to write out the + material type name, so they should be set before. + \param material The material to serialize. + \param options Additional options which might influence the + serialization. + \return The io::IAttributes container holding the material + properties. */ + virtual io::IAttributes* createAttributesFromMaterial(const video::SMaterial& material, + io::SAttributeReadWriteOptions* options=0) =0; + + //! Fills an SMaterial structure from attributes. + /** Please note that for setting material types of the + material, the video driver will need to query the material + renderers for their names, so all non built-in materials must + have been created before calling this method. + \param outMaterial The material to set the properties for. + \param attributes The attributes to read from. */ + virtual void fillMaterialStructureFromAttributes(video::SMaterial& outMaterial, io::IAttributes* attributes) =0; + + //! Returns driver and operating system specific data about the IVideoDriver. + /** This method should only be used if the engine should be + extended without having to modify the source of the engine. + \return Collection of device dependent pointers. */ + virtual const SExposedVideoData& getExposedVideoData() =0; + + //! Get type of video driver + /** \return Type of driver. */ + virtual E_DRIVER_TYPE getDriverType() const =0; + + //! Gets the IGPUProgrammingServices interface. + /** \return Pointer to the IGPUProgrammingServices. Returns 0 + if the video driver does not support this. For example the + Software driver and the Null driver will always return 0. */ + virtual IGPUProgrammingServices* getGPUProgrammingServices() =0; + + //! Returns a pointer to the mesh manipulator. + virtual scene::IMeshManipulator* getMeshManipulator() =0; + + //! Clears the ZBuffer. + /** Note that you usually need not to call this method, as it + is automatically done in IVideoDriver::beginScene() or + IVideoDriver::setRenderTarget() if you enable zBuffer. But if + you have to render some special things, you can clear the + zbuffer during the rendering process with this method any time. + */ + virtual void clearZBuffer() =0; + + //! Make a screenshot of the last rendered frame. + /** \return An image created from the last rendered frame. */ + virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER) =0; + + //! Check if the image is already loaded. + /** Works similar to getTexture(), but does not load the texture + if it is not currently loaded. + \param filename Name of the texture. + \return Pointer to loaded texture, or 0 if not found. */ + virtual video::ITexture* findTexture(const io::path& filename) = 0; + + //! Set or unset a clipping plane. + /** There are at least 6 clipping planes available for the user + to set at will. + \param index The plane index. Must be between 0 and + MaxUserClipPlanes. + \param plane The plane itself. + \param enable If true, enable the clipping plane else disable + it. + \return True if the clipping plane is usable. */ + virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false) =0; + + //! Enable or disable a clipping plane. + /** There are at least 6 clipping planes available for the user + to set at will. + \param index The plane index. Must be between 0 and + MaxUserClipPlanes. + \param enable If true, enable the clipping plane else disable + it. */ + virtual void enableClipPlane(u32 index, bool enable) =0; + + //! Set the minimum number of vertices for which a hw buffer will be created + /** \param count Number of vertices to set as minimum. */ + virtual void setMinHardwareBufferVertexCount(u32 count) =0; + + //! Get the global Material, which might override local materials. + /** Depending on the enable flags, values from this Material + are used to override those of local materials of some + meshbuffer being rendered. + \return Reference to the Override Material. */ + virtual SOverrideMaterial& getOverrideMaterial() =0; + + //! Get the 2d override material for altering its values + /** The 2d override materual allows to alter certain render + states of the 2d methods. Not all members of SMaterial are + honored, especially not MaterialType and Textures. Moreover, + the zbuffer is always ignored, and lighting is always off. All + other flags can be changed, though some might have to effect + in most cases. + Please note that you have to enable/disable this effect with + enableInitMaterial2D(). This effect is costly, as it increases + the number of state changes considerably. Always reset the + values when done. + \return Material reference which should be altered to reflect + the new settings. + */ + virtual SMaterial& getMaterial2D() =0; + + //! Enable the 2d override material + /** \param enable Flag which tells whether the material shall be + enabled or disabled. */ + virtual void enableMaterial2D(bool enable=true) =0; + + //! Get the graphics card vendor name. + virtual core::stringc getVendorInfo() =0; + + //! Only used by the engine internally. + /** The ambient color is set in the scene manager, see + scene::ISceneManager::setAmbientLight(). + \param color New color of the ambient light. */ + virtual void setAmbientLight(const SColorf& color) =0; + + //! Only used by the engine internally. + /** Passes the global material flag AllowZWriteOnTransparent. + Use the SceneManager attribute to set this value from your app. + \param flag Default behavior is to disable ZWrite, i.e. false. */ + virtual void setAllowZWriteOnTransparent(bool flag) =0; + + //! Get the maximum texture size supported. + virtual core::dimension2du getMaxTextureSize() const =0; + + //! Color conversion convenience function + /** Convert an image (as array of pixels) from source to destination + array, thereby converting the color format. The pixel size is + determined by the color formats. + \param sP Pointer to source + \param sF Color format of source + \param sN Number of pixels to convert, both array must be large enough + \param dP Pointer to destination + \param dF Color format of destination + */ + virtual void convertColor(const void* sP, ECOLOR_FORMAT sF, s32 sN, + void* dP, ECOLOR_FORMAT dF) const =0; + }; + +} // end namespace video +} // end namespace irr + + +#endif diff --git a/builddir/irrlicht-1.8.1/include/IVideoModeList.h b/builddir/irrlicht-1.8.1/include/IVideoModeList.h new file mode 100644 index 0000000..aef0f5a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IVideoModeList.h @@ -0,0 +1,62 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_I_VIDEO_MODE_LIST_H_INCLUDED__ +#define __IRR_I_VIDEO_MODE_LIST_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "dimension2d.h" + +namespace irr +{ +namespace video +{ + + //! A list of all available video modes. + /** You can get a list via IrrlichtDevice::getVideoModeList(). If you are confused + now, because you think you have to create an Irrlicht Device with a video + mode before being able to get the video mode list, let me tell you that + there is no need to start up an Irrlicht Device with EDT_DIRECT3D8, EDT_OPENGL or + EDT_SOFTWARE: For this (and for lots of other reasons) the null device, + EDT_NULL exists.*/ + class IVideoModeList : public virtual IReferenceCounted + { + public: + + //! Gets amount of video modes in the list. + /** \return Returns amount of video modes. */ + virtual s32 getVideoModeCount() const = 0; + + //! Get the screen size of a video mode in pixels. + /** \param modeNumber: zero based index of the video mode. + \return Size of screen in pixels of the specified video mode. */ + virtual core::dimension2d<u32> getVideoModeResolution(s32 modeNumber) const = 0; + + //! Get a supported screen size with certain constraints. + /** \param minSize: Minimum dimensions required. + \param maxSize: Maximum dimensions allowed. + \return Size of screen in pixels which matches the requirements. + as good as possible. */ + virtual core::dimension2d<u32> getVideoModeResolution(const core::dimension2d<u32>& minSize, const core::dimension2d<u32>& maxSize) const = 0; + + //! Get the pixel depth of a video mode in bits. + /** \param modeNumber: zero based index of the video mode. + \return Size of each pixel of the specified video mode in bits. */ + virtual s32 getVideoModeDepth(s32 modeNumber) const = 0; + + //! Get current desktop screen resolution. + /** \return Size of screen in pixels of the current desktop video mode. */ + virtual const core::dimension2d<u32>& getDesktopResolution() const = 0; + + //! Get the pixel depth of a video mode in bits. + /** \return Size of each pixel of the current desktop video mode in bits. */ + virtual s32 getDesktopDepth() const = 0; + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IVolumeLightSceneNode.h b/builddir/irrlicht-1.8.1/include/IVolumeLightSceneNode.h new file mode 100644 index 0000000..8ae2d17 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IVolumeLightSceneNode.h @@ -0,0 +1,60 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// created by Dean Wadsworth aka Varmint Dec 31 2007 + +#ifndef __I_VOLUME_LIGHT_SCENE_NODE_H_INCLUDED__ +#define __I_VOLUME_LIGHT_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + class IMeshBuffer; + + class IVolumeLightSceneNode : public ISceneNode + { + public: + + //! constructor + IVolumeLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale) + : ISceneNode(parent, mgr, id, position, rotation, scale) {}; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_VOLUME_LIGHT; } + + //! Sets the number of segments across the U axis + virtual void setSubDivideU(const u32 inU) =0; + + //! Sets the number of segments across the V axis + virtual void setSubDivideV(const u32 inV) =0; + + //! Returns the number of segments across the U axis + virtual u32 getSubDivideU() const =0; + + //! Returns the number of segments across the V axis + virtual u32 getSubDivideV() const =0; + + //! Sets the color of the base of the light + virtual void setFootColor(const video::SColor inColor) =0; + + //! Sets the color of the tip of the light + virtual void setTailColor(const video::SColor inColor) =0; + + //! Returns the color of the base of the light + virtual video::SColor getFootColor() const =0; + + //! Returns the color of the tip of the light + virtual video::SColor getTailColor() const =0; + }; + +} // end namespace scene +} // end namespace irr + +#endif diff --git a/builddir/irrlicht-1.8.1/include/IWriteFile.h b/builddir/irrlicht-1.8.1/include/IWriteFile.h new file mode 100644 index 0000000..7bc9f20 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IWriteFile.h @@ -0,0 +1,50 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_WRITE_FILE_H_INCLUDED__ +#define __I_WRITE_FILE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "path.h" + +namespace irr +{ +namespace io +{ + + //! Interface providing write access to a file. + class IWriteFile : public virtual IReferenceCounted + { + public: + //! Writes an amount of bytes to the file. + /** \param buffer Pointer to buffer of bytes to write. + \param sizeToWrite Amount of bytes to write to the file. + \return How much bytes were written. */ + virtual s32 write(const void* buffer, u32 sizeToWrite) = 0; + + //! Changes position in file + /** \param finalPos Destination position in the file. + \param relativeMovement If set to true, the position in the file is + changed relative to current position. Otherwise the position is changed + from begin of file. + \return True if successful, otherwise false. */ + virtual bool seek(long finalPos, bool relativeMovement = false) = 0; + + //! Get the current position in the file. + /** \return Current position in the file in bytes. */ + virtual long getPos() const = 0; + + //! Get name of file. + /** \return File name as zero terminated character string. */ + virtual const path& getFileName() const = 0; + }; + + //! Internal function, please do not use. + IWriteFile* createWriteFile(const io::path& fileName, bool append); + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IXMLReader.h b/builddir/irrlicht-1.8.1/include/IXMLReader.h new file mode 100644 index 0000000..ec47c00 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IXMLReader.h @@ -0,0 +1,31 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_XML_READER_H_INCLUDED__ +#define __I_XML_READER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrXML.h" + +namespace irr +{ +namespace io +{ + //! An xml reader for wide characters, derived from IReferenceCounted. + /** This XML Parser can read any type of text files from any source + Irrlicht can read. Just call IFileSystem::createXMLReader(). For more + informations on how to use the parser, see IIrrXMLReader */ + typedef IIrrXMLReader<wchar_t, IReferenceCounted> IXMLReader; + + //! An xml reader for ASCII or UTF-8 characters, derived from IReferenceCounted. + /** This XML Parser can read any type of text files from any source + Irrlicht can read. Just call IFileSystem::createXMLReaderUTF8(). For + more informations on how to use the parser, see IIrrXMLReader */ + typedef IIrrXMLReader<c8, IReferenceCounted> IXMLReaderUTF8; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IXMLWriter.h b/builddir/irrlicht-1.8.1/include/IXMLWriter.h new file mode 100644 index 0000000..8b43bc9 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IXMLWriter.h @@ -0,0 +1,77 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_XML_WRITER_H_INCLUDED__ +#define __I_XML_WRITER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrArray.h" +#include "irrString.h" + +namespace irr +{ +namespace io +{ + + //! Interface providing methods for making it easier to write XML files. + /** This XML Writer writes xml files using in the platform dependent + wchar_t format and sets the xml-encoding correspondingly. */ + class IXMLWriter : public virtual IReferenceCounted + { + public: + //! Writes an xml 1.0 header. + /** Looks like <?xml version="1.0"?>. This should always + be called before writing anything other, because also the text + file header for unicode texts is written out with this method. */ + virtual void writeXMLHeader() = 0; + + //! Writes an xml element with maximal 5 attributes like "<foo />" or + //! <foo optAttr="value" />. + /** The element can be empty or not. + \param name: Name of the element + \param empty: Specifies if the element should be empty. Like + "<foo />". If You set this to false, something like this is + written instead: "<foo>". + \param attr1Name: 1st attributes name + \param attr1Value: 1st attributes value + \param attr2Name: 2nd attributes name + \param attr2Value: 2nd attributes value + \param attr3Name: 3rd attributes name + \param attr3Value: 3rd attributes value + \param attr4Name: 4th attributes name + \param attr4Value: 4th attributes value + \param attr5Name: 5th attributes name + \param attr5Value: 5th attributes value */ + virtual void writeElement(const wchar_t* name, bool empty=false, + const wchar_t* attr1Name = 0, const wchar_t* attr1Value = 0, + const wchar_t* attr2Name = 0, const wchar_t* attr2Value = 0, + const wchar_t* attr3Name = 0, const wchar_t* attr3Value = 0, + const wchar_t* attr4Name = 0, const wchar_t* attr4Value = 0, + const wchar_t* attr5Name = 0, const wchar_t* attr5Value = 0) = 0; + + //! Writes an xml element with any number of attributes + virtual void writeElement(const wchar_t* name, bool empty, + core::array<core::stringw> &names, core::array<core::stringw> &values) = 0; + + //! Writes a comment into the xml file + virtual void writeComment(const wchar_t* comment) = 0; + + //! Writes the closing tag for an element. Like "</foo>" + virtual void writeClosingTag(const wchar_t* name) = 0; + + //! Writes a text into the file. + /** All occurrences of special characters such as + & (&), < (<), > (>), and " (") are automaticly + replaced. */ + virtual void writeText(const wchar_t* text) = 0; + + //! Writes a line break + virtual void writeLineBreak() = 0; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/IrrCompileConfig.h b/builddir/irrlicht-1.8.1/include/IrrCompileConfig.h new file mode 100644 index 0000000..ee83f2d --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IrrCompileConfig.h @@ -0,0 +1,832 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_COMPILE_CONFIG_H_INCLUDED__ +#define __IRR_COMPILE_CONFIG_H_INCLUDED__ + +//! Irrlicht SDK Version +#define IRRLICHT_VERSION_MAJOR 1 +#define IRRLICHT_VERSION_MINOR 8 +#define IRRLICHT_VERSION_REVISION 1 +// This flag will be defined only in SVN, the official release code will have +// it undefined +//#define IRRLICHT_VERSION_SVN -alpha +#define IRRLICHT_SDK_VERSION "1.8.1" + +#include <stdio.h> // TODO: Although included elsewhere this is required at least for mingw + +//! The defines for different operating system are: +//! _IRR_XBOX_PLATFORM_ for XBox +//! _IRR_WINDOWS_ for all irrlicht supported Windows versions +//! _IRR_WINDOWS_CE_PLATFORM_ for Windows CE +//! _IRR_WINDOWS_API_ for Windows or XBox +//! _IRR_LINUX_PLATFORM_ for Linux (it is defined here if no other os is defined) +//! _IRR_SOLARIS_PLATFORM_ for Solaris +//! _IRR_OSX_PLATFORM_ for Apple systems running OSX +//! _IRR_POSIX_API_ for Posix compatible systems +//! Note: PLATFORM defines the OS specific layer, API can group several platforms + +//! DEVICE is the windowing system used, several PLATFORMs support more than one DEVICE +//! Irrlicht can be compiled with more than one device +//! _IRR_COMPILE_WITH_WINDOWS_DEVICE_ for Windows API based device +//! _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_ for Windows CE API based device +//! _IRR_COMPILE_WITH_OSX_DEVICE_ for Cocoa native windowing on OSX +//! _IRR_COMPILE_WITH_X11_DEVICE_ for Linux X11 based device +//! _IRR_COMPILE_WITH_SDL_DEVICE_ for platform independent SDL framework +//! _IRR_COMPILE_WITH_CONSOLE_DEVICE_ for no windowing system, used as a fallback +//! _IRR_COMPILE_WITH_FB_DEVICE_ for framebuffer systems + +//! Passing defines to the compiler which have NO in front of the _IRR definename is an alternative +//! way which can be used to disable defines (instead of outcommenting them in this header). +//! So defines can be controlled from Makefiles or Projectfiles which allows building +//! different library versions without having to change the sources. +//! Example: NO_IRR_COMPILE_WITH_X11_ would disable X11 + + +//! Uncomment this line to compile with the SDL device +//#define _IRR_COMPILE_WITH_SDL_DEVICE_ +#ifdef NO_IRR_COMPILE_WITH_SDL_DEVICE_ +#undef _IRR_COMPILE_WITH_SDL_DEVICE_ +#endif + +//! Comment this line to compile without the fallback console device. +#define _IRR_COMPILE_WITH_CONSOLE_DEVICE_ +#ifdef NO_IRR_COMPILE_WITH_CONSOLE_DEVICE_ +#undef _IRR_COMPILE_WITH_CONSOLE_DEVICE_ +#endif + +//! WIN32 for Windows32 +//! WIN64 for Windows64 +// The windows platform and API support SDL and WINDOW device +#if defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64) +#define _IRR_WINDOWS_ +#define _IRR_WINDOWS_API_ +#define _IRR_COMPILE_WITH_WINDOWS_DEVICE_ +#endif + +//! WINCE is a very restricted environment for mobile devices +#if defined(_WIN32_WCE) +#define _IRR_WINDOWS_ +#define _IRR_WINDOWS_API_ +#define _IRR_WINDOWS_CE_PLATFORM_ +#define _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_ +#endif + +#if defined(_MSC_VER) && (_MSC_VER < 1300) +# error "Only Microsoft Visual Studio 7.0 and later are supported." +#endif + +// XBox only suppots the native Window stuff +#if defined(_XBOX) + #undef _IRR_WINDOWS_ + #define _IRR_XBOX_PLATFORM_ + #define _IRR_WINDOWS_API_ + //#define _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + #undef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + //#define _IRR_COMPILE_WITH_SDL_DEVICE_ + + #include <xtl.h> +#endif + +#if defined(__APPLE__) || defined(MACOSX) +#if !defined(MACOSX) +#define MACOSX // legacy support +#endif +#define _IRR_OSX_PLATFORM_ +#define _IRR_COMPILE_WITH_OSX_DEVICE_ +#endif + +#if !defined(_IRR_WINDOWS_API_) && !defined(_IRR_OSX_PLATFORM_) +#ifndef _IRR_SOLARIS_PLATFORM_ +#define _IRR_LINUX_PLATFORM_ +#endif +#define _IRR_POSIX_API_ +#define _IRR_COMPILE_WITH_X11_DEVICE_ +#endif + + +//! Define _IRR_COMPILE_WITH_JOYSTICK_SUPPORT_ if you want joystick events. +#define _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +#ifdef NO_IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +#undef _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +#endif + + +//! Maximum number of texture an SMaterial can have, up to 8 are supported by Irrlicht. +#define _IRR_MATERIAL_MAX_TEXTURES_ 4 + +//! Define _IRR_COMPILE_WITH_DIRECT3D_8_ and _IRR_COMPILE_WITH_DIRECT3D_9_ to +//! compile the Irrlicht engine with Direct3D8 and/or DIRECT3D9. +/** If you only want to use the software device or opengl you can disable those defines. +This switch is mostly disabled because people do not get the g++ compiler compile +directX header files, and directX is only available on Windows platforms. If you +are using Dev-Cpp, and want to compile this using a DX dev pack, you can define +_IRR_COMPILE_WITH_DX9_DEV_PACK_. So you simply need to add something like this +to the compiler settings: -DIRR_COMPILE_WITH_DX9_DEV_PACK +and this to the linker settings: -ld3dx9 -ld3dx8 + +Microsoft have chosen to remove D3D8 headers from their recent DXSDKs, and +so D3D8 support is now disabled by default. If you really want to build +with D3D8 support, then you will have to source a DXSDK with the appropriate +headers, e.g. Summer 2004. This is a Microsoft issue, not an Irrlicht one. +*/ +#if defined(_IRR_WINDOWS_API_) && (!defined(__GNUC__) || defined(IRR_COMPILE_WITH_DX9_DEV_PACK)) + +//! Define _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ if you want to use DirectInput for joystick handling. +/** This only applies to Windows devices, currently only supported under Win32 device. +If not defined, Windows Multimedia library is used, which offers also broad support for joystick devices. */ +#define _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ +#ifdef NO_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ +#undef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ +#endif +// can't get this to compile currently under borland, can be removed if someone has a better solution +#if defined(__BORLANDC__) +#undef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ +#endif + +//! Only define _IRR_COMPILE_WITH_DIRECT3D_8_ if you have an appropriate DXSDK, e.g. Summer 2004 +#define _IRR_COMPILE_WITH_DIRECT3D_8_ +#define _IRR_COMPILE_WITH_DIRECT3D_9_ + +#ifdef NO_IRR_COMPILE_WITH_DIRECT3D_8_ +#undef _IRR_COMPILE_WITH_DIRECT3D_8_ +#endif +#ifdef NO_IRR_COMPILE_WITH_DIRECT3D_9_ +#undef _IRR_COMPILE_WITH_DIRECT3D_9_ +#endif + +#endif + +//! Define _IRR_COMPILE_WITH_OPENGL_ to compile the Irrlicht engine with OpenGL. +/** If you do not wish the engine to be compiled with OpenGL, comment this +define out. */ +#define _IRR_COMPILE_WITH_OPENGL_ +#ifdef NO_IRR_COMPILE_WITH_OPENGL_ +#undef _IRR_COMPILE_WITH_OPENGL_ +#endif + +//! Define _IRR_COMPILE_WITH_SOFTWARE_ to compile the Irrlicht engine with software driver +/** If you do not need the software driver, or want to use Burning's Video instead, +comment this define out */ +#define _IRR_COMPILE_WITH_SOFTWARE_ +#ifdef NO_IRR_COMPILE_WITH_SOFTWARE_ +#undef _IRR_COMPILE_WITH_SOFTWARE_ +#endif + +//! Define _IRR_COMPILE_WITH_BURNINGSVIDEO_ to compile the Irrlicht engine with Burning's video driver +/** If you do not need this software driver, you can comment this define out. */ +#define _IRR_COMPILE_WITH_BURNINGSVIDEO_ +#ifdef NO_IRR_COMPILE_WITH_BURNINGSVIDEO_ +#undef _IRR_COMPILE_WITH_BURNINGSVIDEO_ +#endif + +//! Define _IRR_COMPILE_WITH_X11_ to compile the Irrlicht engine with X11 support. +/** If you do not wish the engine to be compiled with X11, comment this +define out. */ +// Only used in LinuxDevice. +#define _IRR_COMPILE_WITH_X11_ +#ifdef NO_IRR_COMPILE_WITH_X11_ +#undef _IRR_COMPILE_WITH_X11_ +#endif + +//! Define _IRR_OPENGL_USE_EXTPOINTER_ if the OpenGL renderer should use OpenGL extensions via function pointers. +/** On some systems there is no support for the dynamic extension of OpenGL + via function pointers such that this has to be undef'ed. */ +#if !defined(_IRR_OSX_PLATFORM_) && !defined(_IRR_SOLARIS_PLATFORM_) +#define _IRR_OPENGL_USE_EXTPOINTER_ +#endif + +//! On some Linux systems the XF86 vidmode extension or X11 RandR are missing. Use these flags +//! to remove the dependencies such that Irrlicht will compile on those systems, too. +//! If you don't need colored cursors you can also disable the Xcursor extension +#if defined(_IRR_LINUX_PLATFORM_) && defined(_IRR_COMPILE_WITH_X11_) +#define _IRR_LINUX_X11_VIDMODE_ +//#define _IRR_LINUX_X11_RANDR_ +#ifdef NO_IRR_LINUX_X11_VIDMODE_ +#undef _IRR_LINUX_X11_VIDMODE_ +#endif +#ifdef NO_IRR_LINUX_X11_RANDR_ +#undef _IRR_LINUX_X11_RANDR_ +#endif + +//! X11 has by default only monochrome cursors, but using the Xcursor library we can also get color cursor support. +//! If you have the need for custom color cursors on X11 then enable this and make sure you also link +//! to the Xcursor library in your Makefile/Projectfile. +//#define _IRR_LINUX_XCURSOR_ +#ifdef NO_IRR_LINUX_XCURSOR_ +#undef _IRR_LINUX_XCURSOR_ +#endif + +#endif + +//! Define _IRR_COMPILE_WITH_GUI_ to compile the engine with the built-in GUI +/** Disable this if you are using an external library to draw the GUI. If you disable this then +you will not be able to use anything provided by the GUI Environment, including loading fonts. */ +#define _IRR_COMPILE_WITH_GUI_ +#ifdef NO_IRR_COMPILE_WITH_GUI_ +#undef _IRR_COMPILE_WITH_GUI_ +#endif + +//! Define _IRR_WCHAR_FILESYSTEM to enable unicode filesystem support for the engine. +/** This enables the engine to read/write from unicode filesystem. If you +disable this feature, the engine behave as before (ansi). This is currently only supported +for Windows based systems. You also have to set #define UNICODE for this to compile. +*/ +//#define _IRR_WCHAR_FILESYSTEM +#ifdef NO_IRR_WCHAR_FILESYSTEM +#undef _IRR_WCHAR_FILESYSTEM +#endif + +//! Define _IRR_COMPILE_WITH_JPEGLIB_ to enable compiling the engine using libjpeg. +/** This enables the engine to read jpeg images. If you comment this out, +the engine will no longer read .jpeg images. */ +#define _IRR_COMPILE_WITH_LIBJPEG_ +#ifdef NO_IRR_COMPILE_WITH_LIBJPEG_ +#undef _IRR_COMPILE_WITH_LIBJPEG_ +#endif + +//! Define _IRR_USE_NON_SYSTEM_JPEG_LIB_ to let irrlicht use the jpeglib which comes with irrlicht. +/** If this is commented out, Irrlicht will try to compile using the jpeg lib installed in the system. + This is only used when _IRR_COMPILE_WITH_LIBJPEG_ is defined. */ +#define _IRR_USE_NON_SYSTEM_JPEG_LIB_ +#ifdef NO_IRR_USE_NON_SYSTEM_JPEG_LIB_ +#undef _IRR_USE_NON_SYSTEM_JPEG_LIB_ +#endif + +//! Define _IRR_COMPILE_WITH_LIBPNG_ to enable compiling the engine using libpng. +/** This enables the engine to read png images. If you comment this out, +the engine will no longer read .png images. */ +#define _IRR_COMPILE_WITH_LIBPNG_ +#ifdef NO_IRR_COMPILE_WITH_LIBPNG_ +#undef _IRR_COMPILE_WITH_LIBPNG_ +#endif + +//! Define _IRR_USE_NON_SYSTEM_LIBPNG_ to let irrlicht use the libpng which comes with irrlicht. +/** If this is commented out, Irrlicht will try to compile using the libpng installed in the system. + This is only used when _IRR_COMPILE_WITH_LIBPNG_ is defined. */ +#define _IRR_USE_NON_SYSTEM_LIB_PNG_ +#ifdef NO_IRR_USE_NON_SYSTEM_LIB_PNG_ +#undef _IRR_USE_NON_SYSTEM_LIB_PNG_ +#endif + +//! Define _IRR_D3D_NO_SHADER_DEBUGGING to disable shader debugging in D3D9 +/** If _IRR_D3D_NO_SHADER_DEBUGGING is undefined in IrrCompileConfig.h, +it is possible to debug all D3D9 shaders in VisualStudio. All shaders +(which have been generated in memory or read from archives for example) will be emitted +into a temporary file at runtime for this purpose. To debug your shaders, choose +Debug->Direct3D->StartWithDirect3DDebugging in Visual Studio, and for every shader a +file named 'irr_dbg_shader_%%.vsh' or 'irr_dbg_shader_%%.psh' will be created. Drag'n'drop +the file you want to debug into visual studio. That's it. You can now set breakpoints and +watch registers, variables etc. This works with ASM, HLSL, and both with pixel and vertex shaders. +Note that the engine will run in D3D REF for this, which is a lot slower than HAL. */ +#define _IRR_D3D_NO_SHADER_DEBUGGING +#ifdef NO_IRR_D3D_NO_SHADER_DEBUGGING +#undef _IRR_D3D_NO_SHADER_DEBUGGING +#endif + +//! Define _IRR_D3D_USE_LEGACY_HLSL_COMPILER to enable the old HLSL compiler in recent DX SDKs +/** This enables support for ps_1_x shaders for recent DX SDKs. Otherwise, support +for this shader model is not available anymore in SDKs after Oct2006. You need to +distribute the OCT2006_d3dx9_31_x86.cab or OCT2006_d3dx9_31_x64.cab though, in order +to provide the user with the proper DLL. That's why it's disabled by default. */ +//#define _IRR_D3D_USE_LEGACY_HLSL_COMPILER +#ifdef NO_IRR_D3D_USE_LEGACY_HLSL_COMPILER +#undef _IRR_D3D_USE_LEGACY_HLSL_COMPILER +#endif + +//! Define _IRR_COMPILE_WITH_CG_ to enable Cg Shading Language support +//#define _IRR_COMPILE_WITH_CG_ +#ifdef NO_IRR_COMPILE_WITH_CG_ +#undef _IRR_COMPILE_WITH_CG_ +#endif +#if !defined(_IRR_COMPILE_WITH_OPENGL_) && !defined(_IRR_COMPILE_WITH_DIRECT3D_9_) +#undef _IRR_COMPILE_WITH_CG_ +#endif + +//! Define _IRR_USE_NVIDIA_PERFHUD_ to opt-in to using the nVidia PerHUD tool +/** Enable, by opting-in, to use the nVidia PerfHUD performance analysis driver +tool <http://developer.nvidia.com/object/nvperfhud_home.html>. */ +#undef _IRR_USE_NVIDIA_PERFHUD_ + +//! Define one of the three setting for Burning's Video Software Rasterizer +/** So if we were marketing guys we could say Irrlicht has 4 Software-Rasterizers. + In a Nutshell: + All Burnings Rasterizers use 32 Bit Backbuffer, 32Bit Texture & 32 Bit Z or WBuffer, + 16 Bit/32 Bit can be adjusted on a global flag. + + BURNINGVIDEO_RENDERER_BEAUTIFUL + 32 Bit + Vertexcolor + Lighting + Per Pixel Perspective Correct + SubPixel/SubTexel Correct + + Bilinear Texturefiltering + WBuffer + + BURNINGVIDEO_RENDERER_FAST + 32 Bit + Per Pixel Perspective Correct + SubPixel/SubTexel Correct + WBuffer + + Bilinear Dithering TextureFiltering + WBuffer + + BURNINGVIDEO_RENDERER_ULTRA_FAST + 16Bit + SubPixel/SubTexel Correct + ZBuffer +*/ + +#define BURNINGVIDEO_RENDERER_BEAUTIFUL +//#define BURNINGVIDEO_RENDERER_FAST +//#define BURNINGVIDEO_RENDERER_ULTRA_FAST +//#define BURNINGVIDEO_RENDERER_CE + +//! Uncomment the following line if you want to ignore the deprecated warnings +//#define IGNORE_DEPRECATED_WARNING + +//! Define _IRR_COMPILE_WITH_IRR_SCENE_LOADER_ if you want to be able to load +/** .irr scenes using ISceneManager::loadScene */ +#define _IRR_COMPILE_WITH_IRR_SCENE_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_IRR_SCENE_LOADER_ +#undef _IRR_COMPILE_WITH_IRR_SCENE_LOADER_ +#endif + +//! Define _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ if you want to use bone based +/** animated meshes. If you compile without this, you will be unable to load +B3D, MS3D or X meshes */ +#define _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ +#ifdef NO_IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ +#undef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ +#endif + +#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ +//! Define _IRR_COMPILE_WITH_B3D_LOADER_ if you want to use Blitz3D files +#define _IRR_COMPILE_WITH_B3D_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_B3D_LOADER_ +#undef _IRR_COMPILE_WITH_B3D_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_MS3D_LOADER_ if you want to Milkshape files +#define _IRR_COMPILE_WITH_MS3D_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_MS3D_LOADER_ +#undef _IRR_COMPILE_WITH_MS3D_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_X_LOADER_ if you want to use Microsoft X files +#define _IRR_COMPILE_WITH_X_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_X_LOADER_ +#undef _IRR_COMPILE_WITH_X_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_OGRE_LOADER_ if you want to load Ogre 3D files +#define _IRR_COMPILE_WITH_OGRE_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_OGRE_LOADER_ +#undef _IRR_COMPILE_WITH_OGRE_LOADER_ +#endif +#endif // _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + +//! Define _IRR_COMPILE_WITH_IRR_MESH_LOADER_ if you want to load Irrlicht Engine .irrmesh files +#define _IRR_COMPILE_WITH_IRR_MESH_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_IRR_MESH_LOADER_ +#undef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_HALFLIFE_LOADER_ if you want to load Halflife animated files +#define _IRR_COMPILE_WITH_HALFLIFE_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_HALFLIFE_LOADER_ +#undef _IRR_COMPILE_WITH_HALFLIFE_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_MD2_LOADER_ if you want to load Quake 2 animated files +#define _IRR_COMPILE_WITH_MD2_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_MD2_LOADER_ +#undef _IRR_COMPILE_WITH_MD2_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_MD3_LOADER_ if you want to load Quake 3 animated files +#define _IRR_COMPILE_WITH_MD3_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_MD3_LOADER_ +#undef _IRR_COMPILE_WITH_MD3_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_3DS_LOADER_ if you want to load 3D Studio Max files +#define _IRR_COMPILE_WITH_3DS_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_3DS_LOADER_ +#undef _IRR_COMPILE_WITH_3DS_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_COLLADA_LOADER_ if you want to load Collada files +#define _IRR_COMPILE_WITH_COLLADA_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_COLLADA_LOADER_ +#undef _IRR_COMPILE_WITH_COLLADA_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_CSM_LOADER_ if you want to load Cartography Shop files +#define _IRR_COMPILE_WITH_CSM_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_CSM_LOADER_ +#undef _IRR_COMPILE_WITH_CSM_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_BSP_LOADER_ if you want to load Quake 3 BSP files +#define _IRR_COMPILE_WITH_BSP_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_BSP_LOADER_ +#undef _IRR_COMPILE_WITH_BSP_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_DMF_LOADER_ if you want to load DeleD files +#define _IRR_COMPILE_WITH_DMF_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_DMF_LOADER_ +#undef _IRR_COMPILE_WITH_DMF_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_LMTS_LOADER_ if you want to load LMTools files +#define _IRR_COMPILE_WITH_LMTS_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_LMTS_LOADER_ +#undef _IRR_COMPILE_WITH_LMTS_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_MY3D_LOADER_ if you want to load MY3D files +#define _IRR_COMPILE_WITH_MY3D_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_MY3D_LOADER_ +#undef _IRR_COMPILE_WITH_MY3D_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_OBJ_LOADER_ if you want to load Wavefront OBJ files +#define _IRR_COMPILE_WITH_OBJ_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_OBJ_LOADER_ +#undef _IRR_COMPILE_WITH_OBJ_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_OCT_LOADER_ if you want to load FSRad OCT files +#define _IRR_COMPILE_WITH_OCT_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_OCT_LOADER_ +#undef _IRR_COMPILE_WITH_OCT_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_LWO_LOADER_ if you want to load Lightwave3D files +#define _IRR_COMPILE_WITH_LWO_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_LWO_LOADER_ +#undef _IRR_COMPILE_WITH_LWO_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_STL_LOADER_ if you want to load stereolithography files +#define _IRR_COMPILE_WITH_STL_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_STL_LOADER_ +#undef _IRR_COMPILE_WITH_STL_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_PLY_LOADER_ if you want to load Polygon (Stanford Triangle) files +#define _IRR_COMPILE_WITH_PLY_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_PLY_LOADER_ +#undef _IRR_COMPILE_WITH_PLY_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_SMF_LOADER_ if you want to load 3D World Studio mesh files +#define _IRR_COMPILE_WITH_SMF_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_SMF_LOADER_ +#undef _IRR_COMPILE_WITH_SMF_LOADER_ +#endif + +//! Define _IRR_COMPILE_WITH_IRR_WRITER_ if you want to write static .irrMesh files +#define _IRR_COMPILE_WITH_IRR_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_IRR_WRITER_ +#undef _IRR_COMPILE_WITH_IRR_WRITER_ +#endif +//! Define _IRR_COMPILE_WITH_COLLADA_WRITER_ if you want to write Collada files +#define _IRR_COMPILE_WITH_COLLADA_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_COLLADA_WRITER_ +#undef _IRR_COMPILE_WITH_COLLADA_WRITER_ +#endif +//! Define _IRR_COMPILE_WITH_STL_WRITER_ if you want to write .stl files +#define _IRR_COMPILE_WITH_STL_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_STL_WRITER_ +#undef _IRR_COMPILE_WITH_STL_WRITER_ +#endif +//! Define _IRR_COMPILE_WITH_OBJ_WRITER_ if you want to write .obj files +#define _IRR_COMPILE_WITH_OBJ_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_OBJ_WRITER_ +#undef _IRR_COMPILE_WITH_OBJ_WRITER_ +#endif +//! Define _IRR_COMPILE_WITH_PLY_WRITER_ if you want to write .ply files +#define _IRR_COMPILE_WITH_PLY_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_PLY_WRITER_ +#undef _IRR_COMPILE_WITH_PLY_WRITER_ +#endif + +//! Define _IRR_COMPILE_WITH_BMP_LOADER_ if you want to load .bmp files +//! Disabling this loader will also disable the built-in font +#define _IRR_COMPILE_WITH_BMP_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_BMP_LOADER_ +#undef _IRR_COMPILE_WITH_BMP_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_JPG_LOADER_ if you want to load .jpg files +#define _IRR_COMPILE_WITH_JPG_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_JPG_LOADER_ +#undef _IRR_COMPILE_WITH_JPG_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_PCX_LOADER_ if you want to load .pcx files +#define _IRR_COMPILE_WITH_PCX_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_PCX_LOADER_ +#undef _IRR_COMPILE_WITH_PCX_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_PNG_LOADER_ if you want to load .png files +#define _IRR_COMPILE_WITH_PNG_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_PNG_LOADER_ +#undef _IRR_COMPILE_WITH_PNG_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_PPM_LOADER_ if you want to load .ppm/.pgm/.pbm files +#define _IRR_COMPILE_WITH_PPM_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_PPM_LOADER_ +#undef _IRR_COMPILE_WITH_PPM_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_PSD_LOADER_ if you want to load .psd files +#define _IRR_COMPILE_WITH_PSD_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_PSD_LOADER_ +#undef _IRR_COMPILE_WITH_PSD_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_DDS_LOADER_ if you want to load .dds files +// Outcommented because +// a) it doesn't compile on 64-bit currently +// b) anyone enabling it should be aware that S3TC compression algorithm which might be used in that loader +// is patented in the US by S3 and they do collect license fees when it's used in applications. +// So if you are unfortunate enough to develop applications for US market and their broken patent system be careful. +// #define _IRR_COMPILE_WITH_DDS_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_DDS_LOADER_ +#undef _IRR_COMPILE_WITH_DDS_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_TGA_LOADER_ if you want to load .tga files +#define _IRR_COMPILE_WITH_TGA_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_TGA_LOADER_ +#undef _IRR_COMPILE_WITH_TGA_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_WAL_LOADER_ if you want to load .wal files +#define _IRR_COMPILE_WITH_WAL_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_WAL_LOADER_ +#undef _IRR_COMPILE_WITH_WAL_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_LMP_LOADER_ if you want to load .lmp files +#define _IRR_COMPILE_WITH_LMP_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_LMP_LOADER_ +#undef _IRR_COMPILE_WITH_LMP_LOADER_ +#endif +//! Define _IRR_COMPILE_WITH_RGB_LOADER_ if you want to load Silicon Graphics .rgb/.rgba/.sgi/.int/.inta/.bw files +#define _IRR_COMPILE_WITH_RGB_LOADER_ +#ifdef NO_IRR_COMPILE_WITH_RGB_LOADER_ +#undef _IRR_COMPILE_WITH_RGB_LOADER_ +#endif + +//! Define _IRR_COMPILE_WITH_BMP_WRITER_ if you want to write .bmp files +#define _IRR_COMPILE_WITH_BMP_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_BMP_WRITER_ +#undef _IRR_COMPILE_WITH_BMP_WRITER_ +#endif +//! Define _IRR_COMPILE_WITH_JPG_WRITER_ if you want to write .jpg files +#define _IRR_COMPILE_WITH_JPG_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_JPG_WRITER_ +#undef _IRR_COMPILE_WITH_JPG_WRITER_ +#endif +//! Define _IRR_COMPILE_WITH_PCX_WRITER_ if you want to write .pcx files +#define _IRR_COMPILE_WITH_PCX_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_PCX_WRITER_ +#undef _IRR_COMPILE_WITH_PCX_WRITER_ +#endif +//! Define _IRR_COMPILE_WITH_PNG_WRITER_ if you want to write .png files +#define _IRR_COMPILE_WITH_PNG_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_PNG_WRITER_ +#undef _IRR_COMPILE_WITH_PNG_WRITER_ +#endif +//! Define _IRR_COMPILE_WITH_PPM_WRITER_ if you want to write .ppm files +#define _IRR_COMPILE_WITH_PPM_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_PPM_WRITER_ +#undef _IRR_COMPILE_WITH_PPM_WRITER_ +#endif +//! Define _IRR_COMPILE_WITH_PSD_WRITER_ if you want to write .psd files +#define _IRR_COMPILE_WITH_PSD_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_PSD_WRITER_ +#undef _IRR_COMPILE_WITH_PSD_WRITER_ +#endif +//! Define _IRR_COMPILE_WITH_TGA_WRITER_ if you want to write .tga files +#define _IRR_COMPILE_WITH_TGA_WRITER_ +#ifdef NO_IRR_COMPILE_WITH_TGA_WRITER_ +#undef _IRR_COMPILE_WITH_TGA_WRITER_ +#endif + +//! Define __IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_ if you want to open ZIP and GZIP archives +/** ZIP reading has several more options below to configure. */ +#define __IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_ +#ifdef NO__IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_ +#undef __IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_ +#endif +#ifdef __IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_ +//! Define _IRR_COMPILE_WITH_ZLIB_ to enable compiling the engine using zlib. +/** This enables the engine to read from compressed .zip archives. If you +disable this feature, the engine can still read archives, but only uncompressed +ones. */ +#define _IRR_COMPILE_WITH_ZLIB_ +#ifdef NO_IRR_COMPILE_WITH_ZLIB_ +#undef _IRR_COMPILE_WITH_ZLIB_ +#endif +//! Define _IRR_USE_NON_SYSTEM_ZLIB_ to let irrlicht use the zlib which comes with irrlicht. +/** If this is commented out, Irrlicht will try to compile using the zlib +installed on the system. This is only used when _IRR_COMPILE_WITH_ZLIB_ is +defined. */ +#define _IRR_USE_NON_SYSTEM_ZLIB_ +#ifdef NO_IRR_USE_NON_SYSTEM_ZLIB_ +#undef _IRR_USE_NON_SYSTEM_ZLIB_ +#endif +//! Define _IRR_COMPILE_WITH_ZIP_ENCRYPTION_ if you want to read AES-encrypted ZIP archives +#define _IRR_COMPILE_WITH_ZIP_ENCRYPTION_ +#ifdef NO_IRR_COMPILE_WITH_ZIP_ENCRYPTION_ +#undef _IRR_COMPILE_WITH_ZIP_ENCRYPTION_ +#endif +//! Define _IRR_COMPILE_WITH_BZIP2_ if you want to support bzip2 compressed zip archives +/** bzip2 is superior to the original zip file compression modes, but requires +a certain amount of memory for decompression and adds several files to the +library. */ +#define _IRR_COMPILE_WITH_BZIP2_ +#ifdef NO_IRR_COMPILE_WITH_BZIP2_ +#undef _IRR_COMPILE_WITH_BZIP2_ +#endif +//! Define _IRR_USE_NON_SYSTEM_BZLIB_ to let irrlicht use the bzlib which comes with irrlicht. +/** If this is commented out, Irrlicht will try to compile using the bzlib +installed on the system. This is only used when _IRR_COMPILE_WITH_BZLIB_ is +defined. */ +#define _IRR_USE_NON_SYSTEM_BZLIB_ +#ifdef NO_IRR_USE_NON_SYSTEM_BZLIB_ +#undef _IRR_USE_NON_SYSTEM_BZLIB_ +#endif +//! Define _IRR_COMPILE_WITH_LZMA_ if you want to use LZMA compressed zip files. +/** LZMA is a very efficient compression code, known from 7zip. Irrlicht +currently only supports zip archives, though. */ +#define _IRR_COMPILE_WITH_LZMA_ +#ifdef NO_IRR_COMPILE_WITH_LZMA_ +#undef _IRR_COMPILE_WITH_LZMA_ +#endif +#endif + +//! Define __IRR_COMPILE_WITH_MOUNT_ARCHIVE_LOADER_ if you want to mount folders as archives +#define __IRR_COMPILE_WITH_MOUNT_ARCHIVE_LOADER_ +#ifdef NO__IRR_COMPILE_WITH_MOUNT_ARCHIVE_LOADER_ +#undef __IRR_COMPILE_WITH_MOUNT_ARCHIVE_LOADER_ +#endif +//! Define __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_ if you want to open ID software PAK archives +#define __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_ +#ifdef NO__IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_ +#undef __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_ +#endif +//! Define __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ if you want to open Nebula Device NPK archives +#define __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ +#ifdef NO__IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ +#undef __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ +#endif +//! Define __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_ if you want to open TAR archives +#define __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_ +#ifdef NO__IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_ +#undef __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_ +#endif +//! Define __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_ if you want to open WAD archives +#define __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_ +#ifdef NO__IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_ +#undef __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_ +#endif + +//! Set FPU settings +/** Irrlicht should use approximate float and integer fpu techniques +precision will be lower but speed higher. currently X86 only +*/ +#if !defined(_IRR_OSX_PLATFORM_) && !defined(_IRR_SOLARIS_PLATFORM_) + //#define IRRLICHT_FAST_MATH + #ifdef NO_IRRLICHT_FAST_MATH + #undef IRRLICHT_FAST_MATH + #endif +#endif + +// Some cleanup and standard stuff + +#ifdef _IRR_WINDOWS_API_ + +// To build Irrlicht as a static library, you must define _IRR_STATIC_LIB_ in both the +// Irrlicht build, *and* in the user application, before #including <irrlicht.h> +#ifndef _IRR_STATIC_LIB_ +#ifdef IRRLICHT_EXPORTS +#define IRRLICHT_API __declspec(dllexport) +#else +#define IRRLICHT_API __declspec(dllimport) +#endif // IRRLICHT_EXPORT +#else +#define IRRLICHT_API +#endif // _IRR_STATIC_LIB_ + +// Declare the calling convention. +#if defined(_STDCALL_SUPPORTED) +#define IRRCALLCONV __stdcall +#else +#define IRRCALLCONV __cdecl +#endif // STDCALL_SUPPORTED + +#else // _IRR_WINDOWS_API_ + +// Force symbol export in shared libraries built with gcc. +#if (__GNUC__ >= 4) && !defined(_IRR_STATIC_LIB_) && defined(IRRLICHT_EXPORTS) +#define IRRLICHT_API __attribute__ ((visibility("default"))) +#else +#define IRRLICHT_API +#endif + +#define IRRCALLCONV + +#endif // _IRR_WINDOWS_API_ + +// We need to disable DIRECT3D9 support for Visual Studio 6.0 because +// those $%&$!! disabled support for it since Dec. 2004 and users are complaining +// about linker errors. Comment this out only if you are knowing what you are +// doing. (Which means you have an old DX9 SDK and VisualStudio6). +#ifdef _MSC_VER +#if (_MSC_VER < 1300 && !defined(__GNUC__)) +#undef _IRR_COMPILE_WITH_DIRECT3D_9_ +#pragma message("Compiling Irrlicht with Visual Studio 6.0, support for DX9 is disabled.") +#endif +#endif + +// XBox does not have OpenGL or DirectX9 +#if defined(_IRR_XBOX_PLATFORM_) + #undef _IRR_COMPILE_WITH_OPENGL_ + #undef _IRR_COMPILE_WITH_DIRECT3D_9_ +#endif + +//! WinCE does not have OpenGL or DirectX9. use minimal loaders +#if defined(_WIN32_WCE) + #undef _IRR_COMPILE_WITH_OPENGL_ + #undef _IRR_COMPILE_WITH_DIRECT3D_8_ + #undef _IRR_COMPILE_WITH_DIRECT3D_9_ + + #undef BURNINGVIDEO_RENDERER_BEAUTIFUL + #undef BURNINGVIDEO_RENDERER_FAST + #undef BURNINGVIDEO_RENDERER_ULTRA_FAST + #define BURNINGVIDEO_RENDERER_CE + + #undef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + #define _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_ + //#define _IRR_WCHAR_FILESYSTEM + + #undef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ + //#undef _IRR_COMPILE_WITH_MD2_LOADER_ + #undef _IRR_COMPILE_WITH_MD3_LOADER_ + #undef _IRR_COMPILE_WITH_3DS_LOADER_ + #undef _IRR_COMPILE_WITH_COLLADA_LOADER_ + #undef _IRR_COMPILE_WITH_CSM_LOADER_ + #undef _IRR_COMPILE_WITH_BSP_LOADER_ + #undef _IRR_COMPILE_WITH_DMF_LOADER_ + #undef _IRR_COMPILE_WITH_LMTS_LOADER_ + #undef _IRR_COMPILE_WITH_MY3D_LOADER_ + #undef _IRR_COMPILE_WITH_OBJ_LOADER_ + #undef _IRR_COMPILE_WITH_OCT_LOADER_ + #undef _IRR_COMPILE_WITH_OGRE_LOADER_ + #undef _IRR_COMPILE_WITH_LWO_LOADER_ + #undef _IRR_COMPILE_WITH_STL_LOADER_ + #undef _IRR_COMPILE_WITH_IRR_WRITER_ + #undef _IRR_COMPILE_WITH_COLLADA_WRITER_ + #undef _IRR_COMPILE_WITH_STL_WRITER_ + #undef _IRR_COMPILE_WITH_OBJ_WRITER_ + //#undef _IRR_COMPILE_WITH_BMP_LOADER_ + //#undef _IRR_COMPILE_WITH_JPG_LOADER_ + #undef _IRR_COMPILE_WITH_PCX_LOADER_ + //#undef _IRR_COMPILE_WITH_PNG_LOADER_ + #undef _IRR_COMPILE_WITH_PPM_LOADER_ + #undef _IRR_COMPILE_WITH_PSD_LOADER_ + //#undef _IRR_COMPILE_WITH_TGA_LOADER_ + #undef _IRR_COMPILE_WITH_WAL_LOADER_ + #undef _IRR_COMPILE_WITH_BMP_WRITER_ + #undef _IRR_COMPILE_WITH_JPG_WRITER_ + #undef _IRR_COMPILE_WITH_PCX_WRITER_ + #undef _IRR_COMPILE_WITH_PNG_WRITER_ + #undef _IRR_COMPILE_WITH_PPM_WRITER_ + #undef _IRR_COMPILE_WITH_PSD_WRITER_ + #undef _IRR_COMPILE_WITH_TGA_WRITER_ + +#endif + +#ifndef _IRR_WINDOWS_API_ + #undef _IRR_WCHAR_FILESYSTEM +#endif + +#if defined(__sparc__) || defined(__sun__) +#define __BIG_ENDIAN__ +#endif + +#if defined(_IRR_SOLARIS_PLATFORM_) + #undef _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +#endif + +//! Define __IRR_HAS_S64 if the irr::s64 type should be enable (needs long long, available on most platforms, but not part of ISO C++ 98) +#define __IRR_HAS_S64 +#ifdef NO__IRR_HAS_S64 +#undef __IRR_HAS_S64 +#endif + +#if defined(__BORLANDC__) + #include <tchar.h> + + // Borland 5.5.1 does not have _strcmpi defined + #if __BORLANDC__ == 0x551 + // #define _strcmpi strcmpi + #undef _tfinddata_t + #undef _tfindfirst + #undef _tfindnext + + #define _tfinddata_t __tfinddata_t + #define _tfindfirst __tfindfirst + #define _tfindnext __tfindnext + typedef long intptr_t; + #endif + +#endif + +#ifdef _DEBUG + //! A few attributes are written in CSceneManager when _IRR_SCENEMANAGER_DEBUG is enabled + // NOTE: Those attributes were used always until 1.8.0 and became a global define for 1.8.1 + // which is only enabled in debug because it had a large (sometimes >5%) impact on speed. + // A better solution in the long run is to break the interface and remove _all_ attribute + // access in functions like CSceneManager::drawAll and instead put that information in some + // own struct/class or in CSceneManager. + // See http://irrlicht.sourceforge.net/forum/viewtopic.php?f=2&t=48211 for the discussion. + #define _IRR_SCENEMANAGER_DEBUG + #ifdef NO_IRR_SCENEMANAGER_DEBUG + #undef _IRR_SCENEMANAGER_DEBUG + #endif +#endif + +#endif // __IRR_COMPILE_CONFIG_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/IrrlichtDevice.h b/builddir/irrlicht-1.8.1/include/IrrlichtDevice.h new file mode 100644 index 0000000..536e10b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/IrrlichtDevice.h @@ -0,0 +1,322 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_IRRLICHT_DEVICE_H_INCLUDED__ +#define __I_IRRLICHT_DEVICE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "dimension2d.h" +#include "IVideoDriver.h" +#include "EDriverTypes.h" +#include "EDeviceTypes.h" +#include "IEventReceiver.h" +#include "ICursorControl.h" +#include "IVideoModeList.h" +#include "ITimer.h" +#include "IOSOperator.h" + +namespace irr +{ + class ILogger; + class IEventReceiver; + class IRandomizer; + + namespace io { + class IFileSystem; + } // end namespace io + + namespace gui { + class IGUIEnvironment; + } // end namespace gui + + namespace scene { + class ISceneManager; + } // end namespace scene + + //! The Irrlicht device. You can create it with createDevice() or createDeviceEx(). + /** This is the most important class of the Irrlicht Engine. You can + access everything in the engine if you have a pointer to an instance of + this class. There should be only one instance of this class at any + time. + */ + class IrrlichtDevice : public virtual IReferenceCounted + { + public: + + //! Runs the device. + /** Also increments the virtual timer by calling + ITimer::tick();. You can prevent this + by calling ITimer::stop(); before and ITimer::start() after + calling IrrlichtDevice::run(). Returns false if device wants + to be deleted. Use it in this way: + \code + while(device->run()) + { + // draw everything here + } + \endcode + If you want the device to do nothing if the window is inactive + (recommended), use the slightly enhanced code shown at isWindowActive(). + + Note if you are running Irrlicht inside an external, custom + created window: Calling Device->run() will cause Irrlicht to + dispatch windows messages internally. + If you are running Irrlicht in your own custom window, you can + also simply use your own message loop using GetMessage, + DispatchMessage and whatever and simply don't use this method. + But note that Irrlicht will not be able to fetch user input + then. See irr::SIrrlichtCreationParameters::WindowId for more + informations and example code. + */ + virtual bool run() = 0; + + //! Cause the device to temporarily pause execution and let other processes run. + /** This should bring down processor usage without major + performance loss for Irrlicht */ + virtual void yield() = 0; + + //! Pause execution and let other processes to run for a specified amount of time. + /** It may not wait the full given time, as sleep may be interrupted + \param timeMs: Time to sleep for in milisecs. + \param pauseTimer: If true, pauses the device timer while sleeping + */ + virtual void sleep(u32 timeMs, bool pauseTimer=false) = 0; + + //! Provides access to the video driver for drawing 3d and 2d geometry. + /** \return Pointer the video driver. */ + virtual video::IVideoDriver* getVideoDriver() = 0; + + //! Provides access to the virtual file system. + /** \return Pointer to the file system. */ + virtual io::IFileSystem* getFileSystem() = 0; + + //! Provides access to the 2d user interface environment. + /** \return Pointer to the gui environment. */ + virtual gui::IGUIEnvironment* getGUIEnvironment() = 0; + + //! Provides access to the scene manager. + /** \return Pointer to the scene manager. */ + virtual scene::ISceneManager* getSceneManager() = 0; + + //! Provides access to the cursor control. + /** \return Pointer to the mouse cursor control interface. */ + virtual gui::ICursorControl* getCursorControl() = 0; + + //! Provides access to the message logger. + /** \return Pointer to the logger. */ + virtual ILogger* getLogger() = 0; + + //! Gets a list with all video modes available. + /** If you are confused now, because you think you have to + create an Irrlicht Device with a video mode before being able + to get the video mode list, let me tell you that there is no + need to start up an Irrlicht Device with EDT_DIRECT3D8, + EDT_OPENGL or EDT_SOFTWARE: For this (and for lots of other + reasons) the null driver, EDT_NULL exists. + \return Pointer to a list with all video modes supported + by the gfx adapter. */ + virtual video::IVideoModeList* getVideoModeList() = 0; + + //! Provides access to the operation system operator object. + /** The OS operator provides methods for + getting system specific informations and doing system + specific operations, such as exchanging data with the clipboard + or reading the operation system version. + \return Pointer to the OS operator. */ + virtual IOSOperator* getOSOperator() = 0; + + //! Provides access to the engine's timer. + /** The system time can be retrieved by it as + well as the virtual time, which also can be manipulated. + \return Pointer to the ITimer object. */ + virtual ITimer* getTimer() = 0; + + //! Provides access to the engine's currently set randomizer. + /** \return Pointer to the IRandomizer object. */ + virtual IRandomizer* getRandomizer() const =0; + + //! Sets a new randomizer. + /** \param r Pointer to the new IRandomizer object. This object is + grab()'ed by the engine and will be released upon the next setRandomizer + call or upon device destruction. */ + virtual void setRandomizer(IRandomizer* r) =0; + + //! Creates a new default randomizer. + /** The default randomizer provides the random sequence known from previous + Irrlicht versions and is the initial randomizer set on device creation. + \return Pointer to the default IRandomizer object. */ + virtual IRandomizer* createDefaultRandomizer() const =0; + + //! Sets the caption of the window. + /** \param text: New text of the window caption. */ + virtual void setWindowCaption(const wchar_t* text) = 0; + + //! Returns if the window is active. + /** If the window is inactive, + nothing needs to be drawn. So if you don't want to draw anything + when the window is inactive, create your drawing loop this way: + \code + while(device->run()) + { + if (device->isWindowActive()) + { + // draw everything here + } + else + device->yield(); + } + \endcode + \return True if window is active. */ + virtual bool isWindowActive() const = 0; + + //! Checks if the Irrlicht window has focus + /** \return True if window has focus. */ + virtual bool isWindowFocused() const = 0; + + //! Checks if the Irrlicht window is minimized + /** \return True if window is minimized. */ + virtual bool isWindowMinimized() const = 0; + + //! Checks if the Irrlicht window is running in fullscreen mode + /** \return True if window is fullscreen. */ + virtual bool isFullscreen() const = 0; + + //! Get the current color format of the window + /** \return Color format of the window. */ + virtual video::ECOLOR_FORMAT getColorFormat() const = 0; + + //! Notifies the device that it should close itself. + /** IrrlichtDevice::run() will always return false after closeDevice() was called. */ + virtual void closeDevice() = 0; + + //! Get the version of the engine. + /** The returned string + will look like this: "1.2.3" or this: "1.2". + \return String which contains the version. */ + virtual const c8* getVersion() const = 0; + + //! Sets a new user event receiver which will receive events from the engine. + /** Return true in IEventReceiver::OnEvent to prevent the event from continuing along + the chain of event receivers. The path that an event takes through the system depends + on its type. See irr::EEVENT_TYPE for details. + \param receiver New receiver to be used. */ + virtual void setEventReceiver(IEventReceiver* receiver) = 0; + + //! Provides access to the current event receiver. + /** \return Pointer to the current event receiver. Returns 0 if there is none. */ + virtual IEventReceiver* getEventReceiver() = 0; + + //! Sends a user created event to the engine. + /** Is is usually not necessary to use this. However, if you + are using an own input library for example for doing joystick + input, you can use this to post key or mouse input events to + the engine. Internally, this method only delegates the events + further to the scene manager and the GUI environment. */ + virtual bool postEventFromUser(const SEvent& event) = 0; + + //! Sets the input receiving scene manager. + /** If set to null, the main scene manager (returned by + GetSceneManager()) will receive the input + \param sceneManager New scene manager to be used. */ + virtual void setInputReceivingSceneManager(scene::ISceneManager* sceneManager) = 0; + + //! Sets if the window should be resizable in windowed mode. + /** The default is false. This method only works in windowed + mode. + \param resize Flag whether the window should be resizable. */ + virtual void setResizable(bool resize=false) = 0; + + //! Minimizes the window if possible. + virtual void minimizeWindow() =0; + + //! Maximizes the window if possible. + virtual void maximizeWindow() =0; + + //! Restore the window to normal size if possible. + virtual void restoreWindow() =0; + + //! Activate any joysticks, and generate events for them. + /** Irrlicht contains support for joysticks, but does not generate joystick events by default, + as this would consume joystick info that 3rd party libraries might rely on. Call this method to + activate joystick support in Irrlicht and to receive irr::SJoystickEvent events. + \param joystickInfo On return, this will contain an array of each joystick that was found and activated. + \return true if joysticks are supported on this device and _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ + is defined, false if joysticks are not supported or support is compiled out. + */ + virtual bool activateJoysticks(core::array<SJoystickInfo>& joystickInfo) =0; + + //! Set the current Gamma Value for the Display + virtual bool setGammaRamp(f32 red, f32 green, f32 blue, + f32 relativebrightness, f32 relativecontrast) =0; + + //! Get the current Gamma Value for the Display + virtual bool getGammaRamp(f32 &red, f32 &green, f32 &blue, + f32 &brightness, f32 &contrast) =0; + + //! Remove messages pending in the system message loop + /** This function is usually used after messages have been buffered for a longer time, for example + when loading a large scene. Clearing the message loop prevents that mouse- or buttonclicks which users + have pressed in the meantime will now trigger unexpected actions in the gui. <br> + So far the following messages are cleared:<br> + Win32: All keyboard and mouse messages<br> + Linux: All keyboard and mouse messages<br> + All other devices are not yet supported here.<br> + The function is still somewhat experimental, as the kind of messages we clear is based on just a few use-cases. + If you think further messages should be cleared, or some messages should not be cleared here, then please tell us. */ + virtual void clearSystemMessages() = 0; + + //! Get the type of the device. + /** This allows the user to check which windowing system is currently being + used. */ + virtual E_DEVICE_TYPE getType() const = 0; + + //! Check if a driver type is supported by the engine. + /** Even if true is returned the driver may not be available + for a configuration requested when creating the device. */ + static bool isDriverSupported(video::E_DRIVER_TYPE driver) + { + switch (driver) + { + case video::EDT_NULL: + return true; + case video::EDT_SOFTWARE: +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return true; +#else + return false; +#endif + case video::EDT_BURNINGSVIDEO: +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return true; +#else + return false; +#endif + case video::EDT_DIRECT3D8: +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + return true; +#else + return false; +#endif + case video::EDT_DIRECT3D9: +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + return true; +#else + return false; +#endif + case video::EDT_OPENGL: +#ifdef _IRR_COMPILE_WITH_OPENGL_ + return true; +#else + return false; +#endif + default: + return false; + } + } + }; + +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/Keycodes.h b/builddir/irrlicht-1.8.1/include/Keycodes.h new file mode 100644 index 0000000..e56eca1 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/Keycodes.h @@ -0,0 +1,173 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_KEY_CODES_H_INCLUDED__ +#define __IRR_KEY_CODES_H_INCLUDED__ + +namespace irr +{ + + enum EKEY_CODE + { + KEY_LBUTTON = 0x01, // Left mouse button + KEY_RBUTTON = 0x02, // Right mouse button + KEY_CANCEL = 0x03, // Control-break processing + KEY_MBUTTON = 0x04, // Middle mouse button (three-button mouse) + KEY_XBUTTON1 = 0x05, // Windows 2000/XP: X1 mouse button + KEY_XBUTTON2 = 0x06, // Windows 2000/XP: X2 mouse button + KEY_BACK = 0x08, // BACKSPACE key + KEY_TAB = 0x09, // TAB key + KEY_CLEAR = 0x0C, // CLEAR key + KEY_RETURN = 0x0D, // ENTER key + KEY_SHIFT = 0x10, // SHIFT key + KEY_CONTROL = 0x11, // CTRL key + KEY_MENU = 0x12, // ALT key + KEY_PAUSE = 0x13, // PAUSE key + KEY_CAPITAL = 0x14, // CAPS LOCK key + KEY_KANA = 0x15, // IME Kana mode + KEY_HANGUEL = 0x15, // IME Hanguel mode (maintained for compatibility use KEY_HANGUL) + KEY_HANGUL = 0x15, // IME Hangul mode + KEY_JUNJA = 0x17, // IME Junja mode + KEY_FINAL = 0x18, // IME final mode + KEY_HANJA = 0x19, // IME Hanja mode + KEY_KANJI = 0x19, // IME Kanji mode + KEY_ESCAPE = 0x1B, // ESC key + KEY_CONVERT = 0x1C, // IME convert + KEY_NONCONVERT = 0x1D, // IME nonconvert + KEY_ACCEPT = 0x1E, // IME accept + KEY_MODECHANGE = 0x1F, // IME mode change request + KEY_SPACE = 0x20, // SPACEBAR + KEY_PRIOR = 0x21, // PAGE UP key + KEY_NEXT = 0x22, // PAGE DOWN key + KEY_END = 0x23, // END key + KEY_HOME = 0x24, // HOME key + KEY_LEFT = 0x25, // LEFT ARROW key + KEY_UP = 0x26, // UP ARROW key + KEY_RIGHT = 0x27, // RIGHT ARROW key + KEY_DOWN = 0x28, // DOWN ARROW key + KEY_SELECT = 0x29, // SELECT key + KEY_PRINT = 0x2A, // PRINT key + KEY_EXECUT = 0x2B, // EXECUTE key + KEY_SNAPSHOT = 0x2C, // PRINT SCREEN key + KEY_INSERT = 0x2D, // INS key + KEY_DELETE = 0x2E, // DEL key + KEY_HELP = 0x2F, // HELP key + KEY_KEY_0 = 0x30, // 0 key + KEY_KEY_1 = 0x31, // 1 key + KEY_KEY_2 = 0x32, // 2 key + KEY_KEY_3 = 0x33, // 3 key + KEY_KEY_4 = 0x34, // 4 key + KEY_KEY_5 = 0x35, // 5 key + KEY_KEY_6 = 0x36, // 6 key + KEY_KEY_7 = 0x37, // 7 key + KEY_KEY_8 = 0x38, // 8 key + KEY_KEY_9 = 0x39, // 9 key + KEY_KEY_A = 0x41, // A key + KEY_KEY_B = 0x42, // B key + KEY_KEY_C = 0x43, // C key + KEY_KEY_D = 0x44, // D key + KEY_KEY_E = 0x45, // E key + KEY_KEY_F = 0x46, // F key + KEY_KEY_G = 0x47, // G key + KEY_KEY_H = 0x48, // H key + KEY_KEY_I = 0x49, // I key + KEY_KEY_J = 0x4A, // J key + KEY_KEY_K = 0x4B, // K key + KEY_KEY_L = 0x4C, // L key + KEY_KEY_M = 0x4D, // M key + KEY_KEY_N = 0x4E, // N key + KEY_KEY_O = 0x4F, // O key + KEY_KEY_P = 0x50, // P key + KEY_KEY_Q = 0x51, // Q key + KEY_KEY_R = 0x52, // R key + KEY_KEY_S = 0x53, // S key + KEY_KEY_T = 0x54, // T key + KEY_KEY_U = 0x55, // U key + KEY_KEY_V = 0x56, // V key + KEY_KEY_W = 0x57, // W key + KEY_KEY_X = 0x58, // X key + KEY_KEY_Y = 0x59, // Y key + KEY_KEY_Z = 0x5A, // Z key + KEY_LWIN = 0x5B, // Left Windows key (Microsoft Natural keyboard) + KEY_RWIN = 0x5C, // Right Windows key (Natural keyboard) + KEY_APPS = 0x5D, // Applications key (Natural keyboard) + KEY_SLEEP = 0x5F, // Computer Sleep key + KEY_NUMPAD0 = 0x60, // Numeric keypad 0 key + KEY_NUMPAD1 = 0x61, // Numeric keypad 1 key + KEY_NUMPAD2 = 0x62, // Numeric keypad 2 key + KEY_NUMPAD3 = 0x63, // Numeric keypad 3 key + KEY_NUMPAD4 = 0x64, // Numeric keypad 4 key + KEY_NUMPAD5 = 0x65, // Numeric keypad 5 key + KEY_NUMPAD6 = 0x66, // Numeric keypad 6 key + KEY_NUMPAD7 = 0x67, // Numeric keypad 7 key + KEY_NUMPAD8 = 0x68, // Numeric keypad 8 key + KEY_NUMPAD9 = 0x69, // Numeric keypad 9 key + KEY_MULTIPLY = 0x6A, // Multiply key + KEY_ADD = 0x6B, // Add key + KEY_SEPARATOR = 0x6C, // Separator key + KEY_SUBTRACT = 0x6D, // Subtract key + KEY_DECIMAL = 0x6E, // Decimal key + KEY_DIVIDE = 0x6F, // Divide key + KEY_F1 = 0x70, // F1 key + KEY_F2 = 0x71, // F2 key + KEY_F3 = 0x72, // F3 key + KEY_F4 = 0x73, // F4 key + KEY_F5 = 0x74, // F5 key + KEY_F6 = 0x75, // F6 key + KEY_F7 = 0x76, // F7 key + KEY_F8 = 0x77, // F8 key + KEY_F9 = 0x78, // F9 key + KEY_F10 = 0x79, // F10 key + KEY_F11 = 0x7A, // F11 key + KEY_F12 = 0x7B, // F12 key + KEY_F13 = 0x7C, // F13 key + KEY_F14 = 0x7D, // F14 key + KEY_F15 = 0x7E, // F15 key + KEY_F16 = 0x7F, // F16 key + KEY_F17 = 0x80, // F17 key + KEY_F18 = 0x81, // F18 key + KEY_F19 = 0x82, // F19 key + KEY_F20 = 0x83, // F20 key + KEY_F21 = 0x84, // F21 key + KEY_F22 = 0x85, // F22 key + KEY_F23 = 0x86, // F23 key + KEY_F24 = 0x87, // F24 key + KEY_NUMLOCK = 0x90, // NUM LOCK key + KEY_SCROLL = 0x91, // SCROLL LOCK key + KEY_LSHIFT = 0xA0, // Left SHIFT key + KEY_RSHIFT = 0xA1, // Right SHIFT key + KEY_LCONTROL = 0xA2, // Left CONTROL key + KEY_RCONTROL = 0xA3, // Right CONTROL key + KEY_LMENU = 0xA4, // Left MENU key + KEY_RMENU = 0xA5, // Right MENU key + KEY_OEM_1 = 0xBA, // for US ";:" + KEY_PLUS = 0xBB, // Plus Key "+" + KEY_COMMA = 0xBC, // Comma Key "," + KEY_MINUS = 0xBD, // Minus Key "-" + KEY_PERIOD = 0xBE, // Period Key "." + KEY_OEM_2 = 0xBF, // for US "/?" + KEY_OEM_3 = 0xC0, // for US "`~" + KEY_OEM_4 = 0xDB, // for US "[{" + KEY_OEM_5 = 0xDC, // for US "\|" + KEY_OEM_6 = 0xDD, // for US "]}" + KEY_OEM_7 = 0xDE, // for US "'"" + KEY_OEM_8 = 0xDF, // None + KEY_OEM_AX = 0xE1, // for Japan "AX" + KEY_OEM_102 = 0xE2, // "<>" or "\|" + KEY_ATTN = 0xF6, // Attn key + KEY_CRSEL = 0xF7, // CrSel key + KEY_EXSEL = 0xF8, // ExSel key + KEY_EREOF = 0xF9, // Erase EOF key + KEY_PLAY = 0xFA, // Play key + KEY_ZOOM = 0xFB, // Zoom key + KEY_PA1 = 0xFD, // PA1 key + KEY_OEM_CLEAR = 0xFE, // Clear key + + KEY_KEY_CODES_COUNT = 0xFF // this is not a key, but the amount of keycodes there are. + }; + +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/S3DVertex.h b/builddir/irrlicht-1.8.1/include/S3DVertex.h new file mode 100644 index 0000000..706cf4b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/S3DVertex.h @@ -0,0 +1,274 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_3D_VERTEX_H_INCLUDED__ +#define __S_3D_VERTEX_H_INCLUDED__ + +#include "vector3d.h" +#include "vector2d.h" +#include "SColor.h" + +namespace irr +{ +namespace video +{ + +//! Enumeration for all vertex types there are. +enum E_VERTEX_TYPE +{ + //! Standard vertex type used by the Irrlicht engine, video::S3DVertex. + EVT_STANDARD = 0, + + //! Vertex with two texture coordinates, video::S3DVertex2TCoords. + /** Usually used for geometry with lightmaps or other special materials. */ + EVT_2TCOORDS, + + //! Vertex with a tangent and binormal vector, video::S3DVertexTangents. + /** Usually used for tangent space normal mapping. */ + EVT_TANGENTS +}; + +//! Array holding the built in vertex type names +const char* const sBuiltInVertexTypeNames[] = +{ + "standard", + "2tcoords", + "tangents", + 0 +}; + +//! standard vertex used by the Irrlicht engine. +struct S3DVertex +{ + //! default constructor + S3DVertex() {} + + //! constructor + S3DVertex(f32 x, f32 y, f32 z, f32 nx, f32 ny, f32 nz, SColor c, f32 tu, f32 tv) + : Pos(x,y,z), Normal(nx,ny,nz), Color(c), TCoords(tu,tv) {} + + //! constructor + S3DVertex(const core::vector3df& pos, const core::vector3df& normal, + SColor color, const core::vector2d<f32>& tcoords) + : Pos(pos), Normal(normal), Color(color), TCoords(tcoords) {} + + //! Position + core::vector3df Pos; + + //! Normal vector + core::vector3df Normal; + + //! Color + SColor Color; + + //! Texture coordinates + core::vector2d<f32> TCoords; + + bool operator==(const S3DVertex& other) const + { + return ((Pos == other.Pos) && (Normal == other.Normal) && + (Color == other.Color) && (TCoords == other.TCoords)); + } + + bool operator!=(const S3DVertex& other) const + { + return ((Pos != other.Pos) || (Normal != other.Normal) || + (Color != other.Color) || (TCoords != other.TCoords)); + } + + bool operator<(const S3DVertex& other) const + { + return ((Pos < other.Pos) || + ((Pos == other.Pos) && (Normal < other.Normal)) || + ((Pos == other.Pos) && (Normal == other.Normal) && (Color < other.Color)) || + ((Pos == other.Pos) && (Normal == other.Normal) && (Color == other.Color) && (TCoords < other.TCoords))); + } + + E_VERTEX_TYPE getType() const + { + return EVT_STANDARD; + } + + S3DVertex getInterpolated(const S3DVertex& other, f32 d) + { + d = core::clamp(d, 0.0f, 1.0f); + return S3DVertex(Pos.getInterpolated(other.Pos, d), + Normal.getInterpolated(other.Normal, d), + Color.getInterpolated(other.Color, d), + TCoords.getInterpolated(other.TCoords, d)); + } +}; + + +//! Vertex with two texture coordinates. +/** Usually used for geometry with lightmaps +or other special materials. +*/ +struct S3DVertex2TCoords : public S3DVertex +{ + //! default constructor + S3DVertex2TCoords() : S3DVertex() {} + + //! constructor with two different texture coords, but no normal + S3DVertex2TCoords(f32 x, f32 y, f32 z, SColor c, f32 tu, f32 tv, f32 tu2, f32 tv2) + : S3DVertex(x,y,z, 0.0f, 0.0f, 0.0f, c, tu,tv), TCoords2(tu2,tv2) {} + + //! constructor with two different texture coords, but no normal + S3DVertex2TCoords(const core::vector3df& pos, SColor color, + const core::vector2d<f32>& tcoords, const core::vector2d<f32>& tcoords2) + : S3DVertex(pos, core::vector3df(), color, tcoords), TCoords2(tcoords2) {} + + //! constructor with all values + S3DVertex2TCoords(const core::vector3df& pos, const core::vector3df& normal, const SColor& color, + const core::vector2d<f32>& tcoords, const core::vector2d<f32>& tcoords2) + : S3DVertex(pos, normal, color, tcoords), TCoords2(tcoords2) {} + + //! constructor with all values + S3DVertex2TCoords(f32 x, f32 y, f32 z, f32 nx, f32 ny, f32 nz, SColor c, f32 tu, f32 tv, f32 tu2, f32 tv2) + : S3DVertex(x,y,z, nx,ny,nz, c, tu,tv), TCoords2(tu2,tv2) {} + + //! constructor with the same texture coords and normal + S3DVertex2TCoords(f32 x, f32 y, f32 z, f32 nx, f32 ny, f32 nz, SColor c, f32 tu, f32 tv) + : S3DVertex(x,y,z, nx,ny,nz, c, tu,tv), TCoords2(tu,tv) {} + + //! constructor with the same texture coords and normal + S3DVertex2TCoords(const core::vector3df& pos, const core::vector3df& normal, + SColor color, const core::vector2d<f32>& tcoords) + : S3DVertex(pos, normal, color, tcoords), TCoords2(tcoords) {} + + //! constructor from S3DVertex + S3DVertex2TCoords(S3DVertex& o) : S3DVertex(o) {} + + //! Second set of texture coordinates + core::vector2d<f32> TCoords2; + + //! Equality operator + bool operator==(const S3DVertex2TCoords& other) const + { + return ((static_cast<S3DVertex>(*this)==other) && + (TCoords2 == other.TCoords2)); + } + + //! Inequality operator + bool operator!=(const S3DVertex2TCoords& other) const + { + return ((static_cast<S3DVertex>(*this)!=other) || + (TCoords2 != other.TCoords2)); + } + + bool operator<(const S3DVertex2TCoords& other) const + { + return ((static_cast<S3DVertex>(*this) < other) || + ((static_cast<S3DVertex>(*this) == other) && (TCoords2 < other.TCoords2))); + } + + E_VERTEX_TYPE getType() const + { + return EVT_2TCOORDS; + } + + S3DVertex2TCoords getInterpolated(const S3DVertex2TCoords& other, f32 d) + { + d = core::clamp(d, 0.0f, 1.0f); + return S3DVertex2TCoords(Pos.getInterpolated(other.Pos, d), + Normal.getInterpolated(other.Normal, d), + Color.getInterpolated(other.Color, d), + TCoords.getInterpolated(other.TCoords, d), + TCoords2.getInterpolated(other.TCoords2, d)); + } +}; + + +//! Vertex with a tangent and binormal vector. +/** Usually used for tangent space normal mapping. */ +struct S3DVertexTangents : public S3DVertex +{ + //! default constructor + S3DVertexTangents() : S3DVertex() { } + + //! constructor + S3DVertexTangents(f32 x, f32 y, f32 z, f32 nx=0.0f, f32 ny=0.0f, f32 nz=0.0f, + SColor c = 0xFFFFFFFF, f32 tu=0.0f, f32 tv=0.0f, + f32 tanx=0.0f, f32 tany=0.0f, f32 tanz=0.0f, + f32 bx=0.0f, f32 by=0.0f, f32 bz=0.0f) + : S3DVertex(x,y,z, nx,ny,nz, c, tu,tv), Tangent(tanx,tany,tanz), Binormal(bx,by,bz) { } + + //! constructor + S3DVertexTangents(const core::vector3df& pos, SColor c, + const core::vector2df& tcoords) + : S3DVertex(pos, core::vector3df(), c, tcoords) { } + + //! constructor + S3DVertexTangents(const core::vector3df& pos, + const core::vector3df& normal, SColor c, + const core::vector2df& tcoords, + const core::vector3df& tangent=core::vector3df(), + const core::vector3df& binormal=core::vector3df()) + : S3DVertex(pos, normal, c, tcoords), Tangent(tangent), Binormal(binormal) { } + + //! Tangent vector along the x-axis of the texture + core::vector3df Tangent; + + //! Binormal vector (tangent x normal) + core::vector3df Binormal; + + bool operator==(const S3DVertexTangents& other) const + { + return ((static_cast<S3DVertex>(*this)==other) && + (Tangent == other.Tangent) && + (Binormal == other.Binormal)); + } + + bool operator!=(const S3DVertexTangents& other) const + { + return ((static_cast<S3DVertex>(*this)!=other) || + (Tangent != other.Tangent) || + (Binormal != other.Binormal)); + } + + bool operator<(const S3DVertexTangents& other) const + { + return ((static_cast<S3DVertex>(*this) < other) || + ((static_cast<S3DVertex>(*this) == other) && (Tangent < other.Tangent)) || + ((static_cast<S3DVertex>(*this) == other) && (Tangent == other.Tangent) && (Binormal < other.Binormal))); + } + + E_VERTEX_TYPE getType() const + { + return EVT_TANGENTS; + } + + S3DVertexTangents getInterpolated(const S3DVertexTangents& other, f32 d) + { + d = core::clamp(d, 0.0f, 1.0f); + return S3DVertexTangents(Pos.getInterpolated(other.Pos, d), + Normal.getInterpolated(other.Normal, d), + Color.getInterpolated(other.Color, d), + TCoords.getInterpolated(other.TCoords, d), + Tangent.getInterpolated(other.Tangent, d), + Binormal.getInterpolated(other.Binormal, d)); + } +}; + + + +inline u32 getVertexPitchFromType(E_VERTEX_TYPE vertexType) +{ + switch (vertexType) + { + case video::EVT_2TCOORDS: + return sizeof(video::S3DVertex2TCoords); + case video::EVT_TANGENTS: + return sizeof(video::S3DVertexTangents); + default: + return sizeof(video::S3DVertex); + } +} + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SAnimatedMesh.h b/builddir/irrlicht-1.8.1/include/SAnimatedMesh.h new file mode 100644 index 0000000..f962f30 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SAnimatedMesh.h @@ -0,0 +1,189 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_ANIMATED_MESH_H_INCLUDED__ +#define __S_ANIMATED_MESH_H_INCLUDED__ + +#include "IAnimatedMesh.h" +#include "IMesh.h" +#include "aabbox3d.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + + //! Simple implementation of the IAnimatedMesh interface. + struct SAnimatedMesh : public IAnimatedMesh + { + //! constructor + SAnimatedMesh(scene::IMesh* mesh=0, scene::E_ANIMATED_MESH_TYPE type=scene::EAMT_UNKNOWN) : IAnimatedMesh(), FramesPerSecond(25.f), Type(type) + { + #ifdef _DEBUG + setDebugName("SAnimatedMesh"); + #endif + addMesh(mesh); + recalculateBoundingBox(); + } + + //! destructor + virtual ~SAnimatedMesh() + { + // drop meshes + for (u32 i=0; i<Meshes.size(); ++i) + Meshes[i]->drop(); + } + + //! Gets the frame count of the animated mesh. + /** \return Amount of frames. If the amount is 1, it is a static, non animated mesh. */ + virtual u32 getFrameCount() const + { + return Meshes.size(); + } + + //! Gets the default animation speed of the animated mesh. + /** \return Amount of frames per second. If the amount is 0, it is a static, non animated mesh. */ + virtual f32 getAnimationSpeed() const + { + return FramesPerSecond; + } + + //! Gets the frame count of the animated mesh. + /** \param fps Frames per second to play the animation with. If the amount is 0, it is not animated. + The actual speed is set in the scene node the mesh is instantiated in.*/ + virtual void setAnimationSpeed(f32 fps) + { + FramesPerSecond=fps; + } + + //! Returns the IMesh interface for a frame. + /** \param frame: Frame number as zero based index. The maximum frame number is + getFrameCount() - 1; + \param detailLevel: Level of detail. 0 is the lowest, + 255 the highest level of detail. Most meshes will ignore the detail level. + \param startFrameLoop: start frame + \param endFrameLoop: end frame + \return The animated mesh based on a detail level. */ + virtual IMesh* getMesh(s32 frame, s32 detailLevel=255, s32 startFrameLoop=-1, s32 endFrameLoop=-1) + { + if (Meshes.empty()) + return 0; + + return Meshes[frame]; + } + + //! adds a Mesh + void addMesh(IMesh* mesh) + { + if (mesh) + { + mesh->grab(); + Meshes.push_back(mesh); + } + } + + //! Returns an axis aligned bounding box of the mesh. + /** \return A bounding box of this mesh is returned. */ + virtual const core::aabbox3d<f32>& getBoundingBox() const + { + return Box; + } + + //! set user axis aligned bounding box + virtual void setBoundingBox(const core::aabbox3df& box) + { + Box = box; + } + + //! Recalculates the bounding box. + void recalculateBoundingBox() + { + Box.reset(0,0,0); + + if (Meshes.empty()) + return; + + Box = Meshes[0]->getBoundingBox(); + + for (u32 i=1; i<Meshes.size(); ++i) + Box.addInternalBox(Meshes[i]->getBoundingBox()); + } + + //! Returns the type of the animated mesh. + virtual E_ANIMATED_MESH_TYPE getMeshType() const + { + return Type; + } + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const + { + if (Meshes.empty()) + return 0; + + return Meshes[0]->getMeshBufferCount(); + } + + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const + { + if (Meshes.empty()) + return 0; + + return Meshes[0]->getMeshBuffer(nr); + } + + //! Returns pointer to a mesh buffer which fits a material + /** \param material: material to search for + \return Returns the pointer to the mesh buffer or + NULL if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const + { + if (Meshes.empty()) + return 0; + + return Meshes[0]->getMeshBuffer(material); + } + + //! Set a material flag for all meshbuffers of this mesh. + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) + { + for (u32 i=0; i<Meshes.size(); ++i) + Meshes[i]->setMaterialFlag(flag, newvalue); + } + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint( E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX ) + { + for (u32 i=0; i<Meshes.size(); ++i) + Meshes[i]->setHardwareMappingHint(newMappingHint, buffer); + } + + //! flags the meshbuffer as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) + { + for (u32 i=0; i<Meshes.size(); ++i) + Meshes[i]->setDirty(buffer); + } + + //! All meshes defining the animated mesh + core::array<IMesh*> Meshes; + + //! The bounding box of this mesh + core::aabbox3d<f32> Box; + + //! Default animation speed of this mesh. + f32 FramesPerSecond; + + //! The type of the mesh. + E_ANIMATED_MESH_TYPE Type; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SColor.h b/builddir/irrlicht-1.8.1/include/SColor.h new file mode 100644 index 0000000..f57b4a9 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SColor.h @@ -0,0 +1,697 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __COLOR_H_INCLUDED__ +#define __COLOR_H_INCLUDED__ + +#include "irrTypes.h" +#include "irrMath.h" + +namespace irr +{ +namespace video +{ + //! An enum for the color format of textures used by the Irrlicht Engine. + /** A color format specifies how color information is stored. */ + enum ECOLOR_FORMAT + { + //! 16 bit color format used by the software driver. + /** It is thus preferred by all other irrlicht engine video drivers. + There are 5 bits for every color component, and a single bit is left + for alpha information. */ + ECF_A1R5G5B5 = 0, + + //! Standard 16 bit color format. + ECF_R5G6B5, + + //! 24 bit color, no alpha channel, but 8 bit for red, green and blue. + ECF_R8G8B8, + + //! Default 32 bit color format. 8 bits are used for every component: red, green, blue and alpha. + ECF_A8R8G8B8, + + /** Floating Point formats. The following formats may only be used for render target textures. */ + + //! 16 bit floating point format using 16 bits for the red channel. + ECF_R16F, + + //! 32 bit floating point format using 16 bits for the red channel and 16 bits for the green channel. + ECF_G16R16F, + + //! 64 bit floating point format 16 bits are used for the red, green, blue and alpha channels. + ECF_A16B16G16R16F, + + //! 32 bit floating point format using 32 bits for the red channel. + ECF_R32F, + + //! 64 bit floating point format using 32 bits for the red channel and 32 bits for the green channel. + ECF_G32R32F, + + //! 128 bit floating point format. 32 bits are used for the red, green, blue and alpha channels. + ECF_A32B32G32R32F, + + //! Unknown color format: + ECF_UNKNOWN + }; + + + //! Creates a 16 bit A1R5G5B5 color + inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a=0xFF) + { + return (u16)((a & 0x80) << 8 | + (r & 0xF8) << 7 | + (g & 0xF8) << 2 | + (b & 0xF8) >> 3); + } + + + //! Creates a 16 bit A1R5G5B5 color + inline u16 RGB16(u32 r, u32 g, u32 b) + { + return RGBA16(r,g,b); + } + + + //! Creates a 16bit A1R5G5B5 color, based on 16bit input values + inline u16 RGB16from16(u16 r, u16 g, u16 b) + { + return (0x8000 | + (r & 0x1F) << 10 | + (g & 0x1F) << 5 | + (b & 0x1F)); + } + + + //! Converts a 32bit (X8R8G8B8) color to a 16bit A1R5G5B5 color + inline u16 X8R8G8B8toA1R5G5B5(u32 color) + { + return (u16)(0x8000 | + ( color & 0x00F80000) >> 9 | + ( color & 0x0000F800) >> 6 | + ( color & 0x000000F8) >> 3); + } + + + //! Converts a 32bit (A8R8G8B8) color to a 16bit A1R5G5B5 color + inline u16 A8R8G8B8toA1R5G5B5(u32 color) + { + return (u16)(( color & 0x80000000) >> 16| + ( color & 0x00F80000) >> 9 | + ( color & 0x0000F800) >> 6 | + ( color & 0x000000F8) >> 3); + } + + + //! Converts a 32bit (A8R8G8B8) color to a 16bit R5G6B5 color + inline u16 A8R8G8B8toR5G6B5(u32 color) + { + return (u16)(( color & 0x00F80000) >> 8 | + ( color & 0x0000FC00) >> 5 | + ( color & 0x000000F8) >> 3); + } + + + //! Convert A8R8G8B8 Color from A1R5G5B5 color + /** build a nicer 32bit Color by extending dest lower bits with source high bits. */ + inline u32 A1R5G5B5toA8R8G8B8(u16 color) + { + return ( (( -( (s32) color & 0x00008000 ) >> (s32) 31 ) & 0xFF000000 ) | + (( color & 0x00007C00 ) << 9) | (( color & 0x00007000 ) << 4) | + (( color & 0x000003E0 ) << 6) | (( color & 0x00000380 ) << 1) | + (( color & 0x0000001F ) << 3) | (( color & 0x0000001C ) >> 2) + ); + } + + + //! Returns A8R8G8B8 Color from R5G6B5 color + inline u32 R5G6B5toA8R8G8B8(u16 color) + { + return 0xFF000000 | + ((color & 0xF800) << 8)| + ((color & 0x07E0) << 5)| + ((color & 0x001F) << 3); + } + + + //! Returns A1R5G5B5 Color from R5G6B5 color + inline u16 R5G6B5toA1R5G5B5(u16 color) + { + return 0x8000 | (((color & 0xFFC0) >> 1) | (color & 0x1F)); + } + + + //! Returns R5G6B5 Color from A1R5G5B5 color + inline u16 A1R5G5B5toR5G6B5(u16 color) + { + return (((color & 0x7FE0) << 1) | (color & 0x1F)); + } + + + + //! Returns the alpha component from A1R5G5B5 color + /** In Irrlicht, alpha refers to opacity. + \return The alpha value of the color. 0 is transparent, 1 is opaque. */ + inline u32 getAlpha(u16 color) + { + return ((color >> 15)&0x1); + } + + + //! Returns the red component from A1R5G5B5 color. + /** Shift left by 3 to get 8 bit value. */ + inline u32 getRed(u16 color) + { + return ((color >> 10)&0x1F); + } + + + //! Returns the green component from A1R5G5B5 color + /** Shift left by 3 to get 8 bit value. */ + inline u32 getGreen(u16 color) + { + return ((color >> 5)&0x1F); + } + + + //! Returns the blue component from A1R5G5B5 color + /** Shift left by 3 to get 8 bit value. */ + inline u32 getBlue(u16 color) + { + return (color & 0x1F); + } + + + //! Returns the average from a 16 bit A1R5G5B5 color + inline s32 getAverage(s16 color) + { + return ((getRed(color)<<3) + (getGreen(color)<<3) + (getBlue(color)<<3)) / 3; + } + + + //! Class representing a 32 bit ARGB color. + /** The color values for alpha, red, green, and blue are + stored in a single u32. So all four values may be between 0 and 255. + Alpha in Irrlicht is opacity, so 0 is fully transparent, 255 is fully opaque (solid). + This class is used by most parts of the Irrlicht Engine + to specify a color. Another way is using the class SColorf, which + stores the color values in 4 floats. + This class must consist of only one u32 and must not use virtual functions. + */ + class SColor + { + public: + + //! Constructor of the Color. Does nothing. + /** The color value is not initialized to save time. */ + SColor() {} + + //! Constructs the color from 4 values representing the alpha, red, green and blue component. + /** Must be values between 0 and 255. */ + SColor (u32 a, u32 r, u32 g, u32 b) + : color(((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff)) {} + + //! Constructs the color from a 32 bit value. Could be another color. + SColor(u32 clr) + : color(clr) {} + + //! Returns the alpha component of the color. + /** The alpha component defines how opaque a color is. + \return The alpha value of the color. 0 is fully transparent, 255 is fully opaque. */ + u32 getAlpha() const { return color>>24; } + + //! Returns the red component of the color. + /** \return Value between 0 and 255, specifying how red the color is. + 0 means no red, 255 means full red. */ + u32 getRed() const { return (color>>16) & 0xff; } + + //! Returns the green component of the color. + /** \return Value between 0 and 255, specifying how green the color is. + 0 means no green, 255 means full green. */ + u32 getGreen() const { return (color>>8) & 0xff; } + + //! Returns the blue component of the color. + /** \return Value between 0 and 255, specifying how blue the color is. + 0 means no blue, 255 means full blue. */ + u32 getBlue() const { return color & 0xff; } + + //! Get lightness of the color in the range [0,255] + f32 getLightness() const + { + return 0.5f*(core::max_(core::max_(getRed(),getGreen()),getBlue())+core::min_(core::min_(getRed(),getGreen()),getBlue())); + } + + //! Get luminance of the color in the range [0,255]. + f32 getLuminance() const + { + return 0.3f*getRed() + 0.59f*getGreen() + 0.11f*getBlue(); + } + + //! Get average intensity of the color in the range [0,255]. + u32 getAverage() const + { + return ( getRed() + getGreen() + getBlue() ) / 3; + } + + //! Sets the alpha component of the Color. + /** The alpha component defines how transparent a color should be. + \param a The alpha value of the color. 0 is fully transparent, 255 is fully opaque. */ + void setAlpha(u32 a) { color = ((a & 0xff)<<24) | (color & 0x00ffffff); } + + //! Sets the red component of the Color. + /** \param r: Has to be a value between 0 and 255. + 0 means no red, 255 means full red. */ + void setRed(u32 r) { color = ((r & 0xff)<<16) | (color & 0xff00ffff); } + + //! Sets the green component of the Color. + /** \param g: Has to be a value between 0 and 255. + 0 means no green, 255 means full green. */ + void setGreen(u32 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); } + + //! Sets the blue component of the Color. + /** \param b: Has to be a value between 0 and 255. + 0 means no blue, 255 means full blue. */ + void setBlue(u32 b) { color = (b & 0xff) | (color & 0xffffff00); } + + //! Calculates a 16 bit A1R5G5B5 value of this color. + /** \return 16 bit A1R5G5B5 value of this color. */ + u16 toA1R5G5B5() const { return A8R8G8B8toA1R5G5B5(color); } + + //! Converts color to OpenGL color format + /** From ARGB to RGBA in 4 byte components for endian aware + passing to OpenGL + \param dest: address where the 4x8 bit OpenGL color is stored. */ + void toOpenGLColor(u8* dest) const + { + *dest = (u8)getRed(); + *++dest = (u8)getGreen(); + *++dest = (u8)getBlue(); + *++dest = (u8)getAlpha(); + } + + //! Sets all four components of the color at once. + /** Constructs the color from 4 values representing the alpha, + red, green and blue components of the color. Must be values + between 0 and 255. + \param a: Alpha component of the color. The alpha component + defines how transparent a color should be. Has to be a value + between 0 and 255. 255 means not transparent (opaque), 0 means + fully transparent. + \param r: Sets the red component of the Color. Has to be a + value between 0 and 255. 0 means no red, 255 means full red. + \param g: Sets the green component of the Color. Has to be a + value between 0 and 255. 0 means no green, 255 means full + green. + \param b: Sets the blue component of the Color. Has to be a + value between 0 and 255. 0 means no blue, 255 means full blue. */ + void set(u32 a, u32 r, u32 g, u32 b) + { + color = (((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff)); + } + void set(u32 col) { color = col; } + + //! Compares the color to another color. + /** \return True if the colors are the same, and false if not. */ + bool operator==(const SColor& other) const { return other.color == color; } + + //! Compares the color to another color. + /** \return True if the colors are different, and false if they are the same. */ + bool operator!=(const SColor& other) const { return other.color != color; } + + //! comparison operator + /** \return True if this color is smaller than the other one */ + bool operator<(const SColor& other) const { return (color < other.color); } + + //! Adds two colors, result is clamped to 0..255 values + /** \param other Color to add to this color + \return Addition of the two colors, clamped to 0..255 values */ + SColor operator+(const SColor& other) const + { + return SColor(core::min_(getAlpha() + other.getAlpha(), 255u), + core::min_(getRed() + other.getRed(), 255u), + core::min_(getGreen() + other.getGreen(), 255u), + core::min_(getBlue() + other.getBlue(), 255u)); + } + + //! Interpolates the color with a f32 value to another color + /** \param other: Other color + \param d: value between 0.0f and 1.0f + \return Interpolated color. */ + SColor getInterpolated(const SColor &other, f32 d) const + { + d = core::clamp(d, 0.f, 1.f); + const f32 inv = 1.0f - d; + return SColor((u32)core::round32(other.getAlpha()*inv + getAlpha()*d), + (u32)core::round32(other.getRed()*inv + getRed()*d), + (u32)core::round32(other.getGreen()*inv + getGreen()*d), + (u32)core::round32(other.getBlue()*inv + getBlue()*d)); + } + + //! Returns interpolated color. ( quadratic ) + /** \param c1: first color to interpolate with + \param c2: second color to interpolate with + \param d: value between 0.0f and 1.0f. */ + SColor getInterpolated_quadratic(const SColor& c1, const SColor& c2, f32 d) const + { + // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d; + d = core::clamp(d, 0.f, 1.f); + const f32 inv = 1.f - d; + const f32 mul0 = inv * inv; + const f32 mul1 = 2.f * d * inv; + const f32 mul2 = d * d; + + return SColor( + core::clamp( core::floor32( + getAlpha() * mul0 + c1.getAlpha() * mul1 + c2.getAlpha() * mul2 ), 0, 255 ), + core::clamp( core::floor32( + getRed() * mul0 + c1.getRed() * mul1 + c2.getRed() * mul2 ), 0, 255 ), + core::clamp ( core::floor32( + getGreen() * mul0 + c1.getGreen() * mul1 + c2.getGreen() * mul2 ), 0, 255 ), + core::clamp ( core::floor32( + getBlue() * mul0 + c1.getBlue() * mul1 + c2.getBlue() * mul2 ), 0, 255 )); + } + + //! set the color by expecting data in the given format + /** \param data: must point to valid memory containing color information in the given format + \param format: tells the format in which data is available + */ + void setData(const void *data, ECOLOR_FORMAT format) + { + switch (format) + { + case ECF_A1R5G5B5: + color = A1R5G5B5toA8R8G8B8(*(u16*)data); + break; + case ECF_R5G6B5: + color = R5G6B5toA8R8G8B8(*(u16*)data); + break; + case ECF_A8R8G8B8: + color = *(u32*)data; + break; + case ECF_R8G8B8: + { + u8* p = (u8*)data; + set(255, p[0],p[1],p[2]); + } + break; + default: + color = 0xffffffff; + break; + } + } + + //! Write the color to data in the defined format + /** \param data: target to write the color. Must contain sufficiently large memory to receive the number of bytes neede for format + \param format: tells the format used to write the color into data + */ + void getData(void *data, ECOLOR_FORMAT format) + { + switch(format) + { + case ECF_A1R5G5B5: + { + u16 * dest = (u16*)data; + *dest = video::A8R8G8B8toA1R5G5B5( color ); + } + break; + + case ECF_R5G6B5: + { + u16 * dest = (u16*)data; + *dest = video::A8R8G8B8toR5G6B5( color ); + } + break; + + case ECF_R8G8B8: + { + u8* dest = (u8*)data; + dest[0] = (u8)getRed(); + dest[1] = (u8)getGreen(); + dest[2] = (u8)getBlue(); + } + break; + + case ECF_A8R8G8B8: + { + u32 * dest = (u32*)data; + *dest = color; + } + break; + + default: + break; + } + } + + //! color in A8R8G8B8 Format + u32 color; + }; + + + //! Class representing a color with four floats. + /** The color values for red, green, blue + and alpha are each stored in a 32 bit floating point variable. + So all four values may be between 0.0f and 1.0f. + Another, faster way to define colors is using the class SColor, which + stores the color values in a single 32 bit integer. + */ + class SColorf + { + public: + //! Default constructor for SColorf. + /** Sets red, green and blue to 0.0f and alpha to 1.0f. */ + SColorf() : r(0.0f), g(0.0f), b(0.0f), a(1.0f) {} + + //! Constructs a color from up to four color values: red, green, blue, and alpha. + /** \param r: Red color component. Should be a value between + 0.0f meaning no red and 1.0f, meaning full red. + \param g: Green color component. Should be a value between 0.0f + meaning no green and 1.0f, meaning full green. + \param b: Blue color component. Should be a value between 0.0f + meaning no blue and 1.0f, meaning full blue. + \param a: Alpha color component of the color. The alpha + component defines how transparent a color should be. Has to be + a value between 0.0f and 1.0f, 1.0f means not transparent + (opaque), 0.0f means fully transparent. */ + SColorf(f32 r, f32 g, f32 b, f32 a = 1.0f) : r(r), g(g), b(b), a(a) {} + + //! Constructs a color from 32 bit Color. + /** \param c: 32 bit color from which this SColorf class is + constructed from. */ + SColorf(SColor c) + { + const f32 inv = 1.0f / 255.0f; + r = c.getRed() * inv; + g = c.getGreen() * inv; + b = c.getBlue() * inv; + a = c.getAlpha() * inv; + } + + //! Converts this color to a SColor without floats. + SColor toSColor() const + { + return SColor((u32)core::round32(a*255.0f), (u32)core::round32(r*255.0f), (u32)core::round32(g*255.0f), (u32)core::round32(b*255.0f)); + } + + //! Sets three color components to new values at once. + /** \param rr: Red color component. Should be a value between 0.0f meaning + no red (=black) and 1.0f, meaning full red. + \param gg: Green color component. Should be a value between 0.0f meaning + no green (=black) and 1.0f, meaning full green. + \param bb: Blue color component. Should be a value between 0.0f meaning + no blue (=black) and 1.0f, meaning full blue. */ + void set(f32 rr, f32 gg, f32 bb) {r = rr; g =gg; b = bb; } + + //! Sets all four color components to new values at once. + /** \param aa: Alpha component. Should be a value between 0.0f meaning + fully transparent and 1.0f, meaning opaque. + \param rr: Red color component. Should be a value between 0.0f meaning + no red and 1.0f, meaning full red. + \param gg: Green color component. Should be a value between 0.0f meaning + no green and 1.0f, meaning full green. + \param bb: Blue color component. Should be a value between 0.0f meaning + no blue and 1.0f, meaning full blue. */ + void set(f32 aa, f32 rr, f32 gg, f32 bb) {a = aa; r = rr; g =gg; b = bb; } + + //! Interpolates the color with a f32 value to another color + /** \param other: Other color + \param d: value between 0.0f and 1.0f + \return Interpolated color. */ + SColorf getInterpolated(const SColorf &other, f32 d) const + { + d = core::clamp(d, 0.f, 1.f); + const f32 inv = 1.0f - d; + return SColorf(other.r*inv + r*d, + other.g*inv + g*d, other.b*inv + b*d, other.a*inv + a*d); + } + + //! Returns interpolated color. ( quadratic ) + /** \param c1: first color to interpolate with + \param c2: second color to interpolate with + \param d: value between 0.0f and 1.0f. */ + inline SColorf getInterpolated_quadratic(const SColorf& c1, const SColorf& c2, + f32 d) const + { + d = core::clamp(d, 0.f, 1.f); + // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d; + const f32 inv = 1.f - d; + const f32 mul0 = inv * inv; + const f32 mul1 = 2.f * d * inv; + const f32 mul2 = d * d; + + return SColorf (r * mul0 + c1.r * mul1 + c2.r * mul2, + g * mul0 + c1.g * mul1 + c2.g * mul2, + b * mul0 + c1.b * mul1 + c2.b * mul2, + a * mul0 + c1.a * mul1 + c2.a * mul2); + } + + + //! Sets a color component by index. R=0, G=1, B=2, A=3 + void setColorComponentValue(s32 index, f32 value) + { + switch(index) + { + case 0: r = value; break; + case 1: g = value; break; + case 2: b = value; break; + case 3: a = value; break; + } + } + + //! Returns the alpha component of the color in the range 0.0 (transparent) to 1.0 (opaque) + f32 getAlpha() const { return a; } + + //! Returns the red component of the color in the range 0.0 to 1.0 + f32 getRed() const { return r; } + + //! Returns the green component of the color in the range 0.0 to 1.0 + f32 getGreen() const { return g; } + + //! Returns the blue component of the color in the range 0.0 to 1.0 + f32 getBlue() const { return b; } + + //! red color component + f32 r; + + //! green color component + f32 g; + + //! blue component + f32 b; + + //! alpha color component + f32 a; + }; + + + //! Class representing a color in HSL format + /** The color values for hue, saturation, luminance + are stored in 32bit floating point variables. Hue is in range [0,360], + Luminance and Saturation are in percent [0,100] + */ + class SColorHSL + { + public: + SColorHSL ( f32 h = 0.f, f32 s = 0.f, f32 l = 0.f ) + : Hue ( h ), Saturation ( s ), Luminance ( l ) {} + + void fromRGB(const SColorf &color); + void toRGB(SColorf &color) const; + + f32 Hue; + f32 Saturation; + f32 Luminance; + + private: + inline f32 toRGB1(f32 rm1, f32 rm2, f32 rh) const; + + }; + + inline void SColorHSL::fromRGB(const SColorf &color) + { + const f32 maxVal = core::max_(color.getRed(), color.getGreen(), color.getBlue()); + const f32 minVal = (f32)core::min_(color.getRed(), color.getGreen(), color.getBlue()); + Luminance = (maxVal+minVal)*50; + if (core::equals(maxVal, minVal)) + { + Hue=0.f; + Saturation=0.f; + return; + } + + const f32 delta = maxVal-minVal; + if ( Luminance <= 50 ) + { + Saturation = (delta)/(maxVal+minVal); + } + else + { + Saturation = (delta)/(2-maxVal-minVal); + } + Saturation *= 100; + + if (core::equals(maxVal, color.getRed())) + Hue = (color.getGreen()-color.getBlue())/delta; + else if (core::equals(maxVal, color.getGreen())) + Hue = 2+((color.getBlue()-color.getRed())/delta); + else // blue is max + Hue = 4+((color.getRed()-color.getGreen())/delta); + + Hue *= 60.0f; + while ( Hue < 0.f ) + Hue += 360; + } + + + inline void SColorHSL::toRGB(SColorf &color) const + { + const f32 l = Luminance/100; + if (core::iszero(Saturation)) // grey + { + color.set(l, l, l); + return; + } + + f32 rm2; + + if ( Luminance <= 50 ) + { + rm2 = l + l * (Saturation/100); + } + else + { + rm2 = l + (1 - l) * (Saturation/100); + } + + const f32 rm1 = 2.0f * l - rm2; + + const f32 h = Hue / 360.0f; + color.set( toRGB1(rm1, rm2, h + 1.f/3.f), + toRGB1(rm1, rm2, h), + toRGB1(rm1, rm2, h - 1.f/3.f) + ); + } + + + // algorithm from Foley/Van-Dam + inline f32 SColorHSL::toRGB1(f32 rm1, f32 rm2, f32 rh) const + { + if (rh<0) + rh += 1; + if (rh>1) + rh -= 1; + + if (rh < 1.f/6.f) + rm1 = rm1 + (rm2 - rm1) * rh*6.f; + else if (rh < 0.5f) + rm1 = rm2; + else if (rh < 2.f/3.f) + rm1 = rm1 + (rm2 - rm1) * ((2.f/3.f)-rh)*6.f; + + return rm1; + } + +} // end namespace video +} // end namespace irr + +#endif diff --git a/builddir/irrlicht-1.8.1/include/SExposedVideoData.h b/builddir/irrlicht-1.8.1/include/SExposedVideoData.h new file mode 100644 index 0000000..2415d55 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SExposedVideoData.h @@ -0,0 +1,90 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_EXPOSED_VIDEO_DATA_H_INCLUDED__ +#define __S_EXPOSED_VIDEO_DATA_H_INCLUDED__ + +// forward declarations for internal pointers +struct IDirect3D9; +struct IDirect3DDevice9; +struct IDirect3D8; +struct IDirect3DDevice8; + +namespace irr +{ +namespace video +{ + +//! structure for holding data describing a driver and operating system specific data. +/** This data can be retrived by IVideoDriver::getExposedVideoData(). Use this with caution. +This only should be used to make it possible to extend the engine easily without +modification of its source. Note that this structure does not contain any valid data, if +you are using the software or the null device. +*/ +struct SExposedVideoData +{ + SExposedVideoData() {OpenGLWin32.HDc=0; OpenGLWin32.HRc=0; OpenGLWin32.HWnd=0;} + explicit SExposedVideoData(void* Window) {OpenGLWin32.HDc=0; OpenGLWin32.HRc=0; OpenGLWin32.HWnd=Window;} + + union + { + struct + { + //! Pointer to the IDirect3D9 interface + IDirect3D9* D3D9; + + //! Pointer to the IDirect3DDevice9 interface + IDirect3DDevice9* D3DDev9; + + //! Window handle. + /** Get with for example HWND h = reinterpret_cast<HWND>(exposedData.D3D9.HWnd) */ + void* HWnd; + + } D3D9; + + struct + { + //! Pointer to the IDirect3D8 interface + IDirect3D8* D3D8; + + //! Pointer to the IDirect3DDevice8 interface + IDirect3DDevice8* D3DDev8; + + //! Window handle. + /** Get with for example with: HWND h = reinterpret_cast<HWND>(exposedData.D3D8.HWnd) */ + void* HWnd; + + } D3D8; + + struct + { + //! Private GDI Device Context. + /** Get if for example with: HDC h = reinterpret_cast<HDC>(exposedData.OpenGLWin32.HDc) */ + void* HDc; + + //! Permanent Rendering Context. + /** Get if for example with: HGLRC h = reinterpret_cast<HGLRC>(exposedData.OpenGLWin32.HRc) */ + void* HRc; + + //! Window handle. + /** Get with for example with: HWND h = reinterpret_cast<HWND>(exposedData.OpenGLWin32.HWnd) */ + void* HWnd; + } OpenGLWin32; + + struct + { + // XWindow handles + void* X11Display; + void* X11Context; + unsigned long X11Window; + } OpenGLLinux; + }; +}; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SIrrCreationParameters.h b/builddir/irrlicht-1.8.1/include/SIrrCreationParameters.h new file mode 100644 index 0000000..0c30b74 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SIrrCreationParameters.h @@ -0,0 +1,296 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_IRRLICHT_CREATION_PARAMETERS_H_INCLUDED__ +#define __I_IRRLICHT_CREATION_PARAMETERS_H_INCLUDED__ + +#include "EDriverTypes.h" +#include "EDeviceTypes.h" +#include "dimension2d.h" +#include "ILogger.h" + +namespace irr +{ + class IEventReceiver; + + //! Structure for holding Irrlicht Device creation parameters. + /** This structure is used in the createDeviceEx() function. */ + struct SIrrlichtCreationParameters + { + //! Constructs a SIrrlichtCreationParameters structure with default values. + SIrrlichtCreationParameters() : + DeviceType(EIDT_BEST), + DriverType(video::EDT_BURNINGSVIDEO), + WindowSize(core::dimension2d<u32>(800, 600)), + Bits(16), + ZBufferBits(16), + Fullscreen(false), + Stencilbuffer(false), + Vsync(false), + AntiAlias(0), + HandleSRGB(false), + WithAlphaChannel(false), + Doublebuffer(true), + IgnoreInput(false), + Stereobuffer(false), + HighPrecisionFPU(false), + EventReceiver(0), + WindowId(0), +#ifdef _DEBUG + LoggingLevel(ELL_DEBUG), +#else + LoggingLevel(ELL_INFORMATION), +#endif + DisplayAdapter(0), + DriverMultithreaded(false), + UsePerformanceTimer(true), + SDK_version_do_not_use(IRRLICHT_SDK_VERSION) + { + } + + SIrrlichtCreationParameters(const SIrrlichtCreationParameters& other) : + SDK_version_do_not_use(IRRLICHT_SDK_VERSION) + {*this = other;} + + SIrrlichtCreationParameters& operator=(const SIrrlichtCreationParameters& other) + { + DeviceType = other.DeviceType; + DriverType = other.DriverType; + WindowSize = other.WindowSize; + Bits = other.Bits; + ZBufferBits = other.ZBufferBits; + Fullscreen = other.Fullscreen; + Stencilbuffer = other.Stencilbuffer; + Vsync = other.Vsync; + AntiAlias = other.AntiAlias; + HandleSRGB = other.HandleSRGB; + WithAlphaChannel = other.WithAlphaChannel; + Doublebuffer = other.Doublebuffer; + IgnoreInput = other.IgnoreInput; + Stereobuffer = other.Stereobuffer; + HighPrecisionFPU = other.HighPrecisionFPU; + EventReceiver = other.EventReceiver; + WindowId = other.WindowId; + LoggingLevel = other.LoggingLevel; + DriverMultithreaded = other.DriverMultithreaded; + DisplayAdapter = other.DisplayAdapter; + UsePerformanceTimer = other.UsePerformanceTimer; + return *this; + } + + //! Type of the device. + /** This setting decides the windowing system used by the device, most device types are native + to a specific operating system and so may not be available. + EIDT_WIN32 is only available on Windows desktops, + EIDT_WINCE is only available on Windows mobile devices, + EIDT_COCOA is only available on Mac OSX, + EIDT_X11 is available on Linux, Solaris, BSD and other operating systems which use X11, + EIDT_SDL is available on most systems if compiled in, + EIDT_CONSOLE is usually available but can only render to text, + EIDT_BEST will select the best available device for your operating system. + Default: EIDT_BEST. */ + E_DEVICE_TYPE DeviceType; + + //! Type of video driver used to render graphics. + /** This can currently be video::EDT_NULL, video::EDT_SOFTWARE, + video::EDT_BURNINGSVIDEO, video::EDT_DIRECT3D8, + video::EDT_DIRECT3D9, and video::EDT_OPENGL. + Default: Software. */ + video::E_DRIVER_TYPE DriverType; + + //! Size of the window or the video mode in fullscreen mode. Default: 800x600 + core::dimension2d<u32> WindowSize; + + //! Minimum Bits per pixel of the color buffer in fullscreen mode. Ignored if windowed mode. Default: 16. + u8 Bits; + + //! Minimum Bits per pixel of the depth buffer. Default: 16. + u8 ZBufferBits; + + //! Should be set to true if the device should run in fullscreen. + /** Otherwise the device runs in windowed mode. Default: false. */ + bool Fullscreen; + + //! Specifies if the stencil buffer should be enabled. + /** Set this to true, if you want the engine be able to draw + stencil buffer shadows. Note that not all drivers are able to + use the stencil buffer, hence it can be ignored during device + creation. Without the stencil buffer no shadows will be drawn. + Default: false. */ + bool Stencilbuffer; + + //! Specifies vertical syncronisation. + /** If set to true, the driver will wait for the vertical + retrace period, otherwise not. May be silently ignored. + Default: false */ + bool Vsync; + + //! Specifies if the device should use fullscreen anti aliasing + /** Makes sharp/pixelated edges softer, but requires more + performance. Also, 2D elements might look blurred with this + switched on. The resulting rendering quality also depends on + the hardware and driver you are using, your program might look + different on different hardware with this. So if you are + writing a game/application with AntiAlias switched on, it would + be a good idea to make it possible to switch this option off + again by the user. + The value is the maximal antialiasing factor requested for + the device. The cretion method will automatically try smaller + values if no window can be created with the given value. + Value one is usually the same as 0 (disabled), but might be a + special value on some platforms. On D3D devices it maps to + NONMASKABLE. + Default value: 0 - disabled */ + u8 AntiAlias; + + //! Flag to enable proper sRGB and linear color handling + /** In most situations, it is desireable to have the color handling in + non-linear sRGB color space, and only do the intermediate color + calculations in linear RGB space. If this flag is enabled, the device and + driver try to assure that all color input and output are color corrected + and only the internal color representation is linear. This means, that + the color output is properly gamma-adjusted to provide the brighter + colors for monitor display. And that blending and lighting give a more + natural look, due to proper conversion from non-linear colors into linear + color space for blend operations. If this flag is enabled, all texture colors + (which are usually in sRGB space) are correctly displayed. However vertex colors + and other explicitly set values have to be manually encoded in linear color space. + Default value: false. */ + bool HandleSRGB; + + //! Whether the main framebuffer uses an alpha channel. + /** In some situations it might be desireable to get a color + buffer with an alpha channel, e.g. when rendering into a + transparent window or overlay. If this flag is set the device + tries to create a framebuffer with alpha channel. + If this flag is set, only color buffers with alpha channel + are considered. Otherwise, it depends on the actual hardware + if the colorbuffer has an alpha channel or not. + Default value: false */ + bool WithAlphaChannel; + + //! Whether the main framebuffer uses doublebuffering. + /** This should be usually enabled, in order to avoid render + artifacts on the visible framebuffer. However, it might be + useful to use only one buffer on very small devices. If no + doublebuffering is available, the drivers will fall back to + single buffers. Default value: true */ + bool Doublebuffer; + + //! Specifies if the device should ignore input events + /** This is only relevant when using external I/O handlers. + External windows need to take care of this themselves. + Currently only supported by X11. + Default value: false */ + bool IgnoreInput; + + //! Specifies if the device should use stereo buffers + /** Some high-end gfx cards support two framebuffers for direct + support of stereoscopic output devices. If this flag is set the + device tries to create a stereo context. + Currently only supported by OpenGL. + Default value: false */ + bool Stereobuffer; + + //! Specifies if the device should use high precision FPU setting + /** This is only relevant for DirectX Devices, which switch to + low FPU precision by default for performance reasons. However, + this may lead to problems with the other computations of the + application. In this case setting this flag to true should help + - on the expense of performance loss, though. + Default value: false */ + bool HighPrecisionFPU; + + //! A user created event receiver. + IEventReceiver* EventReceiver; + + //! Window Id. + /** If this is set to a value other than 0, the Irrlicht Engine + will be created in an already existing window. For windows, set + this to the HWND of the window you want. The windowSize and + FullScreen options will be ignored when using the WindowId + parameter. Default this is set to 0. + To make Irrlicht run inside the custom window, you still will + have to draw Irrlicht on your own. You can use this loop, as + usual: + \code + while (device->run()) + { + driver->beginScene(true, true, 0); + smgr->drawAll(); + driver->endScene(); + } + \endcode + Instead of this, you can also simply use your own message loop + using GetMessage, DispatchMessage and whatever. Calling + IrrlichtDevice::run() will cause Irrlicht to dispatch messages + internally too. You need not call Device->run() if you want to + do your own message dispatching loop, but Irrlicht will not be + able to fetch user input then and you have to do it on your own + using the window messages, DirectInput, or whatever. Also, + you'll have to increment the Irrlicht timer. + An alternative, own message dispatching loop without + device->run() would look like this: + \code + MSG msg; + while (true) + { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + + if (msg.message == WM_QUIT) + break; + } + + // increase virtual timer time + device->getTimer()->tick(); + + // draw engine picture + driver->beginScene(true, true, 0); + smgr->drawAll(); + driver->endScene(); + } + \endcode + However, there is no need to draw the picture this often. Just + do it how you like. */ + void* WindowId; + + //! Specifies the logging level used in the logging interface. + /** The default value is ELL_INFORMATION. You can access the ILogger interface + later on from the IrrlichtDevice with getLogger() and set another level. + But if you need more or less logging information already from device creation, + then you have to change it here. + */ + ELOG_LEVEL LoggingLevel; + + //! Allows to select which graphic card is used for rendering when more than one card is in the system. + /** So far only supported on D3D */ + u32 DisplayAdapter; + + //! Create the driver multithreaded. + /** Default is false. Enabling this can slow down your application. + Note that this does _not_ make Irrlicht threadsafe, but only the underlying driver-API for the graphiccard. + So far only supported on D3D. */ + bool DriverMultithreaded; + + //! Enables use of high performance timers on Windows platform. + /** When performance timers are not used, standard GetTickCount() + is used instead which usually has worse resolution, but also less + problems with speed stepping and other techniques. + */ + bool UsePerformanceTimer; + + //! Don't use or change this parameter. + /** Always set it to IRRLICHT_SDK_VERSION, which is done by default. + This is needed for sdk version checks. */ + const c8* const SDK_version_do_not_use; + }; + + +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SKeyMap.h b/builddir/irrlicht-1.8.1/include/SKeyMap.h new file mode 100644 index 0000000..55aa5f9 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SKeyMap.h @@ -0,0 +1,41 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_KEY_MAP_H_INCLUDED__ +#define __S_KEY_MAP_H_INCLUDED__ + +#include "Keycodes.h" + +namespace irr +{ + + //! enumeration for key actions. Used for example in the FPS Camera. + enum EKEY_ACTION + { + EKA_MOVE_FORWARD = 0, + EKA_MOVE_BACKWARD, + EKA_STRAFE_LEFT, + EKA_STRAFE_RIGHT, + EKA_JUMP_UP, + EKA_CROUCH, + EKA_COUNT, + + //! This value is not used. It only forces this enumeration to compile in 32 bit. + EKA_FORCE_32BIT = 0x7fffffff + }; + + //! Struct storing which key belongs to which action. + struct SKeyMap + { + SKeyMap() {} + SKeyMap(EKEY_ACTION action, EKEY_CODE keyCode) : Action(action), KeyCode(keyCode) {} + + EKEY_ACTION Action; + EKEY_CODE KeyCode; + }; + +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SLight.h b/builddir/irrlicht-1.8.1/include/SLight.h new file mode 100644 index 0000000..022c40a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SLight.h @@ -0,0 +1,98 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_LIGHT_H_INCLUDED__ +#define __S_LIGHT_H_INCLUDED__ + +#include "SColor.h" + +namespace irr +{ +namespace video +{ + +//! Enumeration for different types of lights +enum E_LIGHT_TYPE +{ + //! point light, it has a position in space and radiates light in all directions + ELT_POINT, + //! spot light, it has a position in space, a direction, and a limited cone of influence + ELT_SPOT, + //! directional light, coming from a direction from an infinite distance + ELT_DIRECTIONAL, + + //! Only used for counting the elements of this enum + ELT_COUNT +}; + +//! Names for light types +const c8* const LightTypeNames[] = +{ + "Point", + "Spot", + "Directional", + 0 +}; + +//! structure for holding data describing a dynamic point light. +/** Irrlicht supports point lights, spot lights, and directional lights. +*/ +struct SLight +{ + SLight() : AmbientColor(0.f,0.f,0.f), DiffuseColor(1.f,1.f,1.f), + SpecularColor(1.f,1.f,1.f), Attenuation(1.f,0.f,0.f), + OuterCone(45.f), InnerCone(0.f), Falloff(2.f), + Position(0.f,0.f,0.f), Direction(0.f,0.f,1.f), + Radius(100.f), Type(ELT_POINT), CastShadows(true) + {} + + //! Ambient color emitted by the light + SColorf AmbientColor; + + //! Diffuse color emitted by the light. + /** This is the primary color you want to set. */ + SColorf DiffuseColor; + + //! Specular color emitted by the light. + /** For details how to use specular highlights, see SMaterial::Shininess */ + SColorf SpecularColor; + + //! Attenuation factors (constant, linear, quadratic) + /** Changes the light strength fading over distance. + Can also be altered by setting the radius, Attenuation will change to + (0,1.f/radius,0). Can be overridden after radius was set. */ + core::vector3df Attenuation; + + //! The angle of the spot's outer cone. Ignored for other lights. + f32 OuterCone; + + //! The angle of the spot's inner cone. Ignored for other lights. + f32 InnerCone; + + //! The light strength's decrease between Outer and Inner cone. + f32 Falloff; + + //! Read-ONLY! Position of the light. + /** If Type is ELT_DIRECTIONAL, it is ignored. Changed via light scene node's position. */ + core::vector3df Position; + + //! Read-ONLY! Direction of the light. + /** If Type is ELT_POINT, it is ignored. Changed via light scene node's rotation. */ + core::vector3df Direction; + + //! Read-ONLY! Radius of light. Everything within this radius will be lighted. + f32 Radius; + + //! Read-ONLY! Type of the light. Default: ELT_POINT + E_LIGHT_TYPE Type; + + //! Read-ONLY! Does the light cast shadows? + bool CastShadows:1; +}; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SMaterial.h b/builddir/irrlicht-1.8.1/include/SMaterial.h new file mode 100644 index 0000000..a1c3ff4 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SMaterial.h @@ -0,0 +1,685 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_MATERIAL_H_INCLUDED__ +#define __S_MATERIAL_H_INCLUDED__ + +#include "SColor.h" +#include "matrix4.h" +#include "irrArray.h" +#include "irrMath.h" +#include "EMaterialTypes.h" +#include "EMaterialFlags.h" +#include "SMaterialLayer.h" + +namespace irr +{ +namespace video +{ + class ITexture; + + //! Flag for EMT_ONETEXTURE_BLEND, ( BlendFactor ) BlendFunc = source * sourceFactor + dest * destFactor + enum E_BLEND_FACTOR + { + EBF_ZERO = 0, //!< src & dest (0, 0, 0, 0) + EBF_ONE, //!< src & dest (1, 1, 1, 1) + EBF_DST_COLOR, //!< src (destR, destG, destB, destA) + EBF_ONE_MINUS_DST_COLOR, //!< src (1-destR, 1-destG, 1-destB, 1-destA) + EBF_SRC_COLOR, //!< dest (srcR, srcG, srcB, srcA) + EBF_ONE_MINUS_SRC_COLOR, //!< dest (1-srcR, 1-srcG, 1-srcB, 1-srcA) + EBF_SRC_ALPHA, //!< src & dest (srcA, srcA, srcA, srcA) + EBF_ONE_MINUS_SRC_ALPHA, //!< src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA) + EBF_DST_ALPHA, //!< src & dest (destA, destA, destA, destA) + EBF_ONE_MINUS_DST_ALPHA, //!< src & dest (1-destA, 1-destA, 1-destA, 1-destA) + EBF_SRC_ALPHA_SATURATE //!< src (min(srcA, 1-destA), idem, ...) + }; + + //! Values defining the blend operation used when blend is enabled + enum E_BLEND_OPERATION + { + EBO_NONE = 0, //!< No blending happens + EBO_ADD, //!< Default blending adds the color values + EBO_SUBTRACT, //!< This mode subtracts the color values + EBO_REVSUBTRACT,//!< This modes subtracts destination from source + EBO_MIN, //!< Choose minimum value of each color channel + EBO_MAX, //!< Choose maximum value of each color channel + EBO_MIN_FACTOR, //!< Choose minimum value of each color channel after applying blend factors, not widely supported + EBO_MAX_FACTOR, //!< Choose maximum value of each color channel after applying blend factors, not widely supported + EBO_MIN_ALPHA, //!< Choose minimum value of each color channel based on alpha value, not widely supported + EBO_MAX_ALPHA //!< Choose maximum value of each color channel based on alpha value, not widely supported + }; + + //! MaterialTypeParam: e.g. DirectX: D3DTOP_MODULATE, D3DTOP_MODULATE2X, D3DTOP_MODULATE4X + enum E_MODULATE_FUNC + { + EMFN_MODULATE_1X = 1, + EMFN_MODULATE_2X = 2, + EMFN_MODULATE_4X = 4 + }; + + //! Comparison function, e.g. for depth buffer test + enum E_COMPARISON_FUNC + { + //! Test never succeeds, this equals disable + ECFN_NEVER=0, + //! <= test, default for e.g. depth test + ECFN_LESSEQUAL=1, + //! Exact equality + ECFN_EQUAL=2, + //! exclusive less comparison, i.e. < + ECFN_LESS, + //! Succeeds almost always, except for exact equality + ECFN_NOTEQUAL, + //! >= test + ECFN_GREATEREQUAL, + //! inverse of <= + ECFN_GREATER, + //! test succeeds always + ECFN_ALWAYS + }; + + //! Enum values for enabling/disabling color planes for rendering + enum E_COLOR_PLANE + { + //! No color enabled + ECP_NONE=0, + //! Alpha enabled + ECP_ALPHA=1, + //! Red enabled + ECP_RED=2, + //! Green enabled + ECP_GREEN=4, + //! Blue enabled + ECP_BLUE=8, + //! All colors, no alpha + ECP_RGB=14, + //! All planes enabled + ECP_ALL=15 + }; + + //! Source of the alpha value to take + /** This is currently only supported in EMT_ONETEXTURE_BLEND. You can use an + or'ed combination of values. Alpha values are modulated (multiplicated). */ + enum E_ALPHA_SOURCE + { + //! Use no alpha, somewhat redundant with other settings + EAS_NONE=0, + //! Use vertex color alpha + EAS_VERTEX_COLOR, + //! Use texture alpha channel + EAS_TEXTURE + }; + + //! EMT_ONETEXTURE_BLEND: pack srcFact, dstFact, Modulate and alpha source to MaterialTypeParam + /** alpha source can be an OR'ed combination of E_ALPHA_SOURCE values. */ + inline f32 pack_textureBlendFunc ( const E_BLEND_FACTOR srcFact, const E_BLEND_FACTOR dstFact, const E_MODULATE_FUNC modulate=EMFN_MODULATE_1X, const u32 alphaSource=EAS_TEXTURE ) + { + const u32 tmp = (alphaSource << 12) | (modulate << 8) | (srcFact << 4) | dstFact; + return FR(tmp); + } + + //! EMT_ONETEXTURE_BLEND: unpack srcFact & dstFact and Modulo to MaterialTypeParam + /** The fields don't use the full byte range, so we could pack even more... */ + inline void unpack_textureBlendFunc ( E_BLEND_FACTOR &srcFact, E_BLEND_FACTOR &dstFact, + E_MODULATE_FUNC &modulo, u32& alphaSource, const f32 param ) + { + const u32 state = IR(param); + alphaSource = (state & 0x0000F000) >> 12; + modulo = E_MODULATE_FUNC( ( state & 0x00000F00 ) >> 8 ); + srcFact = E_BLEND_FACTOR ( ( state & 0x000000F0 ) >> 4 ); + dstFact = E_BLEND_FACTOR ( ( state & 0x0000000F ) ); + } + + //! EMT_ONETEXTURE_BLEND: has BlendFactor Alphablending + inline bool textureBlendFunc_hasAlpha ( const E_BLEND_FACTOR factor ) + { + switch ( factor ) + { + case EBF_SRC_ALPHA: + case EBF_ONE_MINUS_SRC_ALPHA: + case EBF_DST_ALPHA: + case EBF_ONE_MINUS_DST_ALPHA: + case EBF_SRC_ALPHA_SATURATE: + return true; + default: + return false; + } + } + + + //! These flags are used to specify the anti-aliasing and smoothing modes + /** Techniques supported are multisampling, geometry smoothing, and alpha + to coverage. + Some drivers don't support a per-material setting of the anti-aliasing + modes. In those cases, FSAA/multisampling is defined by the device mode + chosen upon creation via irr::SIrrCreationParameters. + */ + enum E_ANTI_ALIASING_MODE + { + //! Use to turn off anti-aliasing for this material + EAAM_OFF=0, + //! Default anti-aliasing mode + EAAM_SIMPLE=1, + //! High-quality anti-aliasing, not always supported, automatically enables SIMPLE mode + EAAM_QUALITY=3, + //! Line smoothing + EAAM_LINE_SMOOTH=4, + //! point smoothing, often in software and slow, only with OpenGL + EAAM_POINT_SMOOTH=8, + //! All typical anti-alias and smooth modes + EAAM_FULL_BASIC=15, + //! Enhanced anti-aliasing for transparent materials + /** Usually used with EMT_TRANSPARENT_ALPHA_REF and multisampling. */ + EAAM_ALPHA_TO_COVERAGE=16 + }; + + //! These flags allow to define the interpretation of vertex color when lighting is enabled + /** Without lighting being enabled the vertex color is the only value defining the fragment color. + Once lighting is enabled, the four values for diffuse, ambient, emissive, and specular take over. + With these flags it is possible to define which lighting factor shall be defined by the vertex color + instead of the lighting factor which is the same for all faces of that material. + The default is to use vertex color for the diffuse value, another pretty common value is to use + vertex color for both diffuse and ambient factor. */ + enum E_COLOR_MATERIAL + { + //! Don't use vertex color for lighting + ECM_NONE=0, + //! Use vertex color for diffuse light, this is default + ECM_DIFFUSE, + //! Use vertex color for ambient light + ECM_AMBIENT, + //! Use vertex color for emissive light + ECM_EMISSIVE, + //! Use vertex color for specular light + ECM_SPECULAR, + //! Use vertex color for both diffuse and ambient light + ECM_DIFFUSE_AND_AMBIENT + }; + + //! Flags for the definition of the polygon offset feature + /** These flags define whether the offset should be into the screen, or towards the eye. */ + enum E_POLYGON_OFFSET + { + //! Push pixel towards the far plane, away from the eye + /** This is typically used for rendering inner areas. */ + EPO_BACK=0, + //! Pull pixels towards the camera. + /** This is typically used for polygons which should appear on top + of other elements, such as decals. */ + EPO_FRONT=1 + }; + + //! Names for polygon offset direction + const c8* const PolygonOffsetDirectionNames[] = + { + "Back", + "Front", + 0 + }; + + + //! Maximum number of texture an SMaterial can have. + const u32 MATERIAL_MAX_TEXTURES = _IRR_MATERIAL_MAX_TEXTURES_; + + //! Struct for holding parameters for a material renderer + class SMaterial + { + public: + //! Default constructor. Creates a solid, lit material with white colors + SMaterial() + : MaterialType(EMT_SOLID), AmbientColor(255,255,255,255), DiffuseColor(255,255,255,255), + EmissiveColor(0,0,0,0), SpecularColor(255,255,255,255), + Shininess(0.0f), MaterialTypeParam(0.0f), MaterialTypeParam2(0.0f), Thickness(1.0f), + ZBuffer(ECFN_LESSEQUAL), AntiAliasing(EAAM_SIMPLE), ColorMask(ECP_ALL), + ColorMaterial(ECM_DIFFUSE), BlendOperation(EBO_NONE), + PolygonOffsetFactor(0), PolygonOffsetDirection(EPO_FRONT), + Wireframe(false), PointCloud(false), GouraudShading(true), + Lighting(true), ZWriteEnable(true), BackfaceCulling(true), FrontfaceCulling(false), + FogEnable(false), NormalizeNormals(false), UseMipMaps(true) + { } + + //! Copy constructor + /** \param other Material to copy from. */ + SMaterial(const SMaterial& other) + { + // These pointers are checked during assignment + for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) + TextureLayer[i].TextureMatrix = 0; + *this = other; + } + + //! Assignment operator + /** \param other Material to copy from. */ + SMaterial& operator=(const SMaterial& other) + { + // Check for self-assignment! + if (this == &other) + return *this; + + MaterialType = other.MaterialType; + + AmbientColor = other.AmbientColor; + DiffuseColor = other.DiffuseColor; + EmissiveColor = other.EmissiveColor; + SpecularColor = other.SpecularColor; + Shininess = other.Shininess; + MaterialTypeParam = other.MaterialTypeParam; + MaterialTypeParam2 = other.MaterialTypeParam2; + Thickness = other.Thickness; + for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) + { + TextureLayer[i] = other.TextureLayer[i]; + } + + Wireframe = other.Wireframe; + PointCloud = other.PointCloud; + GouraudShading = other.GouraudShading; + Lighting = other.Lighting; + ZWriteEnable = other.ZWriteEnable; + BackfaceCulling = other.BackfaceCulling; + FrontfaceCulling = other.FrontfaceCulling; + FogEnable = other.FogEnable; + NormalizeNormals = other.NormalizeNormals; + ZBuffer = other.ZBuffer; + AntiAliasing = other.AntiAliasing; + ColorMask = other.ColorMask; + ColorMaterial = other.ColorMaterial; + BlendOperation = other.BlendOperation; + PolygonOffsetFactor = other.PolygonOffsetFactor; + PolygonOffsetDirection = other.PolygonOffsetDirection; + UseMipMaps = other.UseMipMaps; + + return *this; + } + + //! Texture layer array. + SMaterialLayer TextureLayer[MATERIAL_MAX_TEXTURES]; + + //! Type of the material. Specifies how everything is blended together + E_MATERIAL_TYPE MaterialType; + + //! How much ambient light (a global light) is reflected by this material. + /** The default is full white, meaning objects are completely + globally illuminated. Reduce this if you want to see diffuse + or specular light effects. */ + SColor AmbientColor; + + //! How much diffuse light coming from a light source is reflected by this material. + /** The default is full white. */ + SColor DiffuseColor; + + //! Light emitted by this material. Default is to emit no light. + SColor EmissiveColor; + + //! How much specular light (highlights from a light) is reflected. + /** The default is to reflect white specular light. See + SMaterial::Shininess on how to enable specular lights. */ + SColor SpecularColor; + + //! Value affecting the size of specular highlights. + /** A value of 20 is common. If set to 0, no specular + highlights are being used. To activate, simply set the + shininess of a material to a value in the range [0.5;128]: + \code + sceneNode->getMaterial(0).Shininess = 20.0f; + \endcode + + You can change the color of the highlights using + \code + sceneNode->getMaterial(0).SpecularColor.set(255,255,255,255); + \endcode + + The specular color of the dynamic lights + (SLight::SpecularColor) will influence the the highlight color + too, but they are set to a useful value by default when + creating the light scene node. Here is a simple example on how + to use specular highlights: + \code + // load and display mesh + scene::IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( + smgr->getMesh("data/faerie.md2")); + node->setMaterialTexture(0, driver->getTexture("data/Faerie2.pcx")); // set diffuse texture + node->setMaterialFlag(video::EMF_LIGHTING, true); // enable dynamic lighting + node->getMaterial(0).Shininess = 20.0f; // set size of specular highlights + + // add white light + scene::ILightSceneNode* light = smgr->addLightSceneNode(0, + core::vector3df(5,5,5), video::SColorf(1.0f, 1.0f, 1.0f)); + \endcode */ + f32 Shininess; + + //! Free parameter, dependent on the material type. + /** Mostly ignored, used for example in EMT_PARALLAX_MAP_SOLID + and EMT_TRANSPARENT_ALPHA_CHANNEL. */ + f32 MaterialTypeParam; + + //! Second free parameter, dependent on the material type. + /** Mostly ignored. */ + f32 MaterialTypeParam2; + + //! Thickness of non-3dimensional elements such as lines and points. + f32 Thickness; + + //! Is the ZBuffer enabled? Default: ECFN_LESSEQUAL + /** Values are from E_COMPARISON_FUNC. */ + u8 ZBuffer; + + //! Sets the antialiasing mode + /** Values are chosen from E_ANTI_ALIASING_MODE. Default is + EAAM_SIMPLE|EAAM_LINE_SMOOTH, i.e. simple multi-sample + anti-aliasing and lime smoothing is enabled. */ + u8 AntiAliasing; + + //! Defines the enabled color planes + /** Values are defined as or'ed values of the E_COLOR_PLANE enum. + Only enabled color planes will be rendered to the current render + target. Typical use is to disable all colors when rendering only to + depth or stencil buffer, or using Red and Green for Stereo rendering. */ + u8 ColorMask:4; + + //! Defines the interpretation of vertex color in the lighting equation + /** Values should be chosen from E_COLOR_MATERIAL. + When lighting is enabled, vertex color can be used instead of the + material values for light modulation. This allows to easily change e.g. the + diffuse light behavior of each face. The default, ECM_DIFFUSE, will result in + a very similar rendering as with lighting turned off, just with light shading. */ + u8 ColorMaterial:3; + + //! Store the blend operation of choice + /** Values to be chosen from E_BLEND_OPERATION. The actual way to use this value + is not yet determined, so ignore it for now. */ + E_BLEND_OPERATION BlendOperation:4; + + //! Factor specifying how far the polygon offset should be made + /** Specifying 0 disables the polygon offset. The direction is specified spearately. + The factor can be from 0 to 7.*/ + u8 PolygonOffsetFactor:3; + + //! Flag defining the direction the polygon offset is applied to. + /** Can be to front or to back, specififed by values from E_POLYGON_OFFSET. */ + E_POLYGON_OFFSET PolygonOffsetDirection:1; + + //! Draw as wireframe or filled triangles? Default: false + /** The user can access a material flag using + \code material.Wireframe=true \endcode + or \code material.setFlag(EMF_WIREFRAME, true); \endcode */ + bool Wireframe:1; + + //! Draw as point cloud or filled triangles? Default: false + bool PointCloud:1; + + //! Flat or Gouraud shading? Default: true + bool GouraudShading:1; + + //! Will this material be lighted? Default: true + bool Lighting:1; + + //! Is the zbuffer writeable or is it read-only. Default: true. + /** This flag is forced to false if the MaterialType is a + transparent type and the scene parameter + ALLOW_ZWRITE_ON_TRANSPARENT is not set. */ + bool ZWriteEnable:1; + + //! Is backface culling enabled? Default: true + bool BackfaceCulling:1; + + //! Is frontface culling enabled? Default: false + bool FrontfaceCulling:1; + + //! Is fog enabled? Default: false + bool FogEnable:1; + + //! Should normals be normalized? + /** Always use this if the mesh lit and scaled. Default: false */ + bool NormalizeNormals:1; + + //! Shall mipmaps be used if available + /** Sometimes, disabling mipmap usage can be useful. Default: true */ + bool UseMipMaps:1; + + //! Gets the texture transformation matrix for level i + /** \param i The desired level. Must not be larger than MATERIAL_MAX_TEXTURES. + \return Texture matrix for texture level i. */ + core::matrix4& getTextureMatrix(u32 i) + { + return TextureLayer[i].getTextureMatrix(); + } + + //! Gets the immutable texture transformation matrix for level i + /** \param i The desired level. + \return Texture matrix for texture level i, or identity matrix for levels larger than MATERIAL_MAX_TEXTURES. */ + const core::matrix4& getTextureMatrix(u32 i) const + { + if (i<MATERIAL_MAX_TEXTURES) + return TextureLayer[i].getTextureMatrix(); + else + return core::IdentityMatrix; + } + + //! Sets the i-th texture transformation matrix + /** \param i The desired level. + \param mat Texture matrix for texture level i. */ + void setTextureMatrix(u32 i, const core::matrix4& mat) + { + if (i>=MATERIAL_MAX_TEXTURES) + return; + TextureLayer[i].setTextureMatrix(mat); + } + + //! Gets the i-th texture + /** \param i The desired level. + \return Texture for texture level i, if defined, else 0. */ + ITexture* getTexture(u32 i) const + { + return i < MATERIAL_MAX_TEXTURES ? TextureLayer[i].Texture : 0; + } + + //! Sets the i-th texture + /** If i>=MATERIAL_MAX_TEXTURES this setting will be ignored. + \param i The desired level. + \param tex Texture for texture level i. */ + void setTexture(u32 i, ITexture* tex) + { + if (i>=MATERIAL_MAX_TEXTURES) + return; + TextureLayer[i].Texture = tex; + } + + //! Sets the Material flag to the given value + /** \param flag The flag to be set. + \param value The new value for the flag. */ + void setFlag(E_MATERIAL_FLAG flag, bool value) + { + switch (flag) + { + case EMF_WIREFRAME: + Wireframe = value; break; + case EMF_POINTCLOUD: + PointCloud = value; break; + case EMF_GOURAUD_SHADING: + GouraudShading = value; break; + case EMF_LIGHTING: + Lighting = value; break; + case EMF_ZBUFFER: + ZBuffer = value; break; + case EMF_ZWRITE_ENABLE: + ZWriteEnable = value; break; + case EMF_BACK_FACE_CULLING: + BackfaceCulling = value; break; + case EMF_FRONT_FACE_CULLING: + FrontfaceCulling = value; break; + case EMF_BILINEAR_FILTER: + { + for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) + TextureLayer[i].BilinearFilter = value; + } + break; + case EMF_TRILINEAR_FILTER: + { + for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) + TextureLayer[i].TrilinearFilter = value; + } + break; + case EMF_ANISOTROPIC_FILTER: + { + if (value) + for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) + TextureLayer[i].AnisotropicFilter = 0xFF; + else + for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) + TextureLayer[i].AnisotropicFilter = 0; + } + break; + case EMF_FOG_ENABLE: + FogEnable = value; break; + case EMF_NORMALIZE_NORMALS: + NormalizeNormals = value; break; + case EMF_TEXTURE_WRAP: + { + for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) + { + TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)value; + TextureLayer[i].TextureWrapV = (E_TEXTURE_CLAMP)value; + } + } + break; + case EMF_ANTI_ALIASING: + AntiAliasing = value?EAAM_SIMPLE:EAAM_OFF; break; + case EMF_COLOR_MASK: + ColorMask = value?ECP_ALL:ECP_NONE; break; + case EMF_COLOR_MATERIAL: + ColorMaterial = value?ECM_DIFFUSE:ECM_NONE; break; + case EMF_USE_MIP_MAPS: + UseMipMaps = value; break; + case EMF_BLEND_OPERATION: + BlendOperation = value?EBO_ADD:EBO_NONE; break; + case EMF_POLYGON_OFFSET: + PolygonOffsetFactor = value?1:0; + PolygonOffsetDirection = EPO_BACK; + break; + default: + break; + } + } + + //! Gets the Material flag + /** \param flag The flag to query. + \return The current value of the flag. */ + bool getFlag(E_MATERIAL_FLAG flag) const + { + switch (flag) + { + case EMF_WIREFRAME: + return Wireframe; + case EMF_POINTCLOUD: + return PointCloud; + case EMF_GOURAUD_SHADING: + return GouraudShading; + case EMF_LIGHTING: + return Lighting; + case EMF_ZBUFFER: + return ZBuffer!=ECFN_NEVER; + case EMF_ZWRITE_ENABLE: + return ZWriteEnable; + case EMF_BACK_FACE_CULLING: + return BackfaceCulling; + case EMF_FRONT_FACE_CULLING: + return FrontfaceCulling; + case EMF_BILINEAR_FILTER: + return TextureLayer[0].BilinearFilter; + case EMF_TRILINEAR_FILTER: + return TextureLayer[0].TrilinearFilter; + case EMF_ANISOTROPIC_FILTER: + return TextureLayer[0].AnisotropicFilter!=0; + case EMF_FOG_ENABLE: + return FogEnable; + case EMF_NORMALIZE_NORMALS: + return NormalizeNormals; + case EMF_TEXTURE_WRAP: + return !(TextureLayer[0].TextureWrapU || + TextureLayer[0].TextureWrapV || + TextureLayer[1].TextureWrapU || + TextureLayer[1].TextureWrapV || + TextureLayer[2].TextureWrapU || + TextureLayer[2].TextureWrapV || + TextureLayer[3].TextureWrapU || + TextureLayer[3].TextureWrapV); + case EMF_ANTI_ALIASING: + return (AntiAliasing==1); + case EMF_COLOR_MASK: + return (ColorMask!=ECP_NONE); + case EMF_COLOR_MATERIAL: + return (ColorMaterial != ECM_NONE); + case EMF_USE_MIP_MAPS: + return UseMipMaps; + case EMF_BLEND_OPERATION: + return BlendOperation != EBO_NONE; + case EMF_POLYGON_OFFSET: + return PolygonOffsetFactor != 0; + } + + return false; + } + + //! Inequality operator + /** \param b Material to compare to. + \return True if the materials differ, else false. */ + inline bool operator!=(const SMaterial& b) const + { + bool different = + MaterialType != b.MaterialType || + AmbientColor != b.AmbientColor || + DiffuseColor != b.DiffuseColor || + EmissiveColor != b.EmissiveColor || + SpecularColor != b.SpecularColor || + Shininess != b.Shininess || + MaterialTypeParam != b.MaterialTypeParam || + MaterialTypeParam2 != b.MaterialTypeParam2 || + Thickness != b.Thickness || + Wireframe != b.Wireframe || + PointCloud != b.PointCloud || + GouraudShading != b.GouraudShading || + Lighting != b.Lighting || + ZBuffer != b.ZBuffer || + ZWriteEnable != b.ZWriteEnable || + BackfaceCulling != b.BackfaceCulling || + FrontfaceCulling != b.FrontfaceCulling || + FogEnable != b.FogEnable || + NormalizeNormals != b.NormalizeNormals || + AntiAliasing != b.AntiAliasing || + ColorMask != b.ColorMask || + ColorMaterial != b.ColorMaterial || + BlendOperation != b.BlendOperation || + PolygonOffsetFactor != b.PolygonOffsetFactor || + PolygonOffsetDirection != b.PolygonOffsetDirection || + UseMipMaps != b.UseMipMaps; + for (u32 i=0; (i<MATERIAL_MAX_TEXTURES) && !different; ++i) + { + different |= (TextureLayer[i] != b.TextureLayer[i]); + } + return different; + } + + //! Equality operator + /** \param b Material to compare to. + \return True if the materials are equal, else false. */ + inline bool operator==(const SMaterial& b) const + { return !(b!=*this); } + + bool isTransparent() const + { + return MaterialType==EMT_TRANSPARENT_ADD_COLOR || + MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL || + MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA || + MaterialType==EMT_TRANSPARENT_REFLECTION_2_LAYER; + } + }; + + //! global const identity Material + IRRLICHT_API extern SMaterial IdentityMaterial; + +} // end namespace video +} // end namespace irr + +#endif diff --git a/builddir/irrlicht-1.8.1/include/SMaterialLayer.h b/builddir/irrlicht-1.8.1/include/SMaterialLayer.h new file mode 100644 index 0000000..30e8cd9 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SMaterialLayer.h @@ -0,0 +1,228 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_MATERIAL_LAYER_H_INCLUDED__ +#define __S_MATERIAL_LAYER_H_INCLUDED__ + +#include "matrix4.h" +#include "irrAllocator.h" + +namespace irr +{ +namespace video +{ + class ITexture; + + //! Texture coord clamp mode outside [0.0, 1.0] + enum E_TEXTURE_CLAMP + { + //! Texture repeats + ETC_REPEAT = 0, + //! Texture is clamped to the last pixel + ETC_CLAMP, + //! Texture is clamped to the edge pixel + ETC_CLAMP_TO_EDGE, + //! Texture is clamped to the border pixel (if exists) + ETC_CLAMP_TO_BORDER, + //! Texture is alternatingly mirrored (0..1..0..1..0..) + ETC_MIRROR, + //! Texture is mirrored once and then clamped (0..1..0) + ETC_MIRROR_CLAMP, + //! Texture is mirrored once and then clamped to edge + ETC_MIRROR_CLAMP_TO_EDGE, + //! Texture is mirrored once and then clamped to border + ETC_MIRROR_CLAMP_TO_BORDER + }; + static const char* const aTextureClampNames[] = { + "texture_clamp_repeat", + "texture_clamp_clamp", + "texture_clamp_clamp_to_edge", + "texture_clamp_clamp_to_border", + "texture_clamp_mirror", + "texture_clamp_mirror_clamp", + "texture_clamp_mirror_clamp_to_edge", + "texture_clamp_mirror_clamp_to_border", 0}; + + //! Struct for holding material parameters which exist per texture layer + class SMaterialLayer + { + public: + //! Default constructor + SMaterialLayer() + : Texture(0), + TextureWrapU(ETC_REPEAT), + TextureWrapV(ETC_REPEAT), + BilinearFilter(true), + TrilinearFilter(false), + AnisotropicFilter(0), + LODBias(0), + TextureMatrix(0) + {} + + //! Copy constructor + /** \param other Material layer to copy from. */ + SMaterialLayer(const SMaterialLayer& other) + { + // This pointer is checked during assignment + TextureMatrix = 0; + *this = other; + } + + //! Destructor + ~SMaterialLayer() + { + MatrixAllocator.destruct(TextureMatrix); + MatrixAllocator.deallocate(TextureMatrix); + } + + //! Assignment operator + /** \param other Material layer to copy from. + \return This material layer, updated. */ + SMaterialLayer& operator=(const SMaterialLayer& other) + { + // Check for self-assignment! + if (this == &other) + return *this; + + Texture = other.Texture; + if (TextureMatrix) + { + if (other.TextureMatrix) + *TextureMatrix = *other.TextureMatrix; + else + { + MatrixAllocator.destruct(TextureMatrix); + MatrixAllocator.deallocate(TextureMatrix); + TextureMatrix = 0; + } + } + else + { + if (other.TextureMatrix) + { + TextureMatrix = MatrixAllocator.allocate(1); + MatrixAllocator.construct(TextureMatrix,*other.TextureMatrix); + } + else + TextureMatrix = 0; + } + TextureWrapU = other.TextureWrapU; + TextureWrapV = other.TextureWrapV; + BilinearFilter = other.BilinearFilter; + TrilinearFilter = other.TrilinearFilter; + AnisotropicFilter = other.AnisotropicFilter; + LODBias = other.LODBias; + + return *this; + } + + //! Gets the texture transformation matrix + /** \return Texture matrix of this layer. */ + core::matrix4& getTextureMatrix() + { + if (!TextureMatrix) + { + TextureMatrix = MatrixAllocator.allocate(1); + MatrixAllocator.construct(TextureMatrix,core::IdentityMatrix); + } + return *TextureMatrix; + } + + //! Gets the immutable texture transformation matrix + /** \return Texture matrix of this layer. */ + const core::matrix4& getTextureMatrix() const + { + if (TextureMatrix) + return *TextureMatrix; + else + return core::IdentityMatrix; + } + + //! Sets the texture transformation matrix to mat + /** \param mat New texture matrix for this layer. */ + void setTextureMatrix(const core::matrix4& mat) + { + if (!TextureMatrix) + { + TextureMatrix = MatrixAllocator.allocate(1); + MatrixAllocator.construct(TextureMatrix,mat); + } + else + *TextureMatrix = mat; + } + + //! Inequality operator + /** \param b Layer to compare to. + \return True if layers are different, else false. */ + inline bool operator!=(const SMaterialLayer& b) const + { + bool different = + Texture != b.Texture || + TextureWrapU != b.TextureWrapU || + TextureWrapV != b.TextureWrapV || + BilinearFilter != b.BilinearFilter || + TrilinearFilter != b.TrilinearFilter || + AnisotropicFilter != b.AnisotropicFilter || + LODBias != b.LODBias; + if (different) + return true; + else + different |= (TextureMatrix != b.TextureMatrix) && + TextureMatrix && b.TextureMatrix && + (*TextureMatrix != *(b.TextureMatrix)); + return different; + } + + //! Equality operator + /** \param b Layer to compare to. + \return True if layers are equal, else false. */ + inline bool operator==(const SMaterialLayer& b) const + { return !(b!=*this); } + + //! Texture + ITexture* Texture; + + //! Texture Clamp Mode + /** Values are taken from E_TEXTURE_CLAMP. */ + u8 TextureWrapU:4; + u8 TextureWrapV:4; + + //! Is bilinear filtering enabled? Default: true + bool BilinearFilter:1; + + //! Is trilinear filtering enabled? Default: false + /** If the trilinear filter flag is enabled, + the bilinear filtering flag is ignored. */ + bool TrilinearFilter:1; + + //! Is anisotropic filtering enabled? Default: 0, disabled + /** In Irrlicht you can use anisotropic texture filtering + in conjunction with bilinear or trilinear texture + filtering to improve rendering results. Primitives + will look less blurry with this flag switched on. The number gives + the maximal anisotropy degree, and is often in the range 2-16. + Value 1 is equivalent to 0, but should be avoided. */ + u8 AnisotropicFilter; + + //! Bias for the mipmap choosing decision. + /** This value can make the textures more or less blurry than with the + default value of 0. The value (divided by 8.f) is added to the mipmap level + chosen initially, and thus takes a smaller mipmap for a region + if the value is positive. */ + s8 LODBias; + + private: + friend class SMaterial; + irr::core::irrAllocator<irr::core::matrix4> MatrixAllocator; + + //! Texture Matrix + /** Do not access this element directly as the internal + ressource management has to cope with Null pointers etc. */ + core::matrix4* TextureMatrix; + }; + +} // end namespace video +} // end namespace irr + +#endif // __S_MATERIAL_LAYER_H_INCLUDED__ diff --git a/builddir/irrlicht-1.8.1/include/SMesh.h b/builddir/irrlicht-1.8.1/include/SMesh.h new file mode 100644 index 0000000..efac56e --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SMesh.h @@ -0,0 +1,140 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_MESH_H_INCLUDED__ +#define __S_MESH_H_INCLUDED__ + +#include "IMesh.h" +#include "IMeshBuffer.h" +#include "aabbox3d.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + //! Simple implementation of the IMesh interface. + struct SMesh : public IMesh + { + //! constructor + SMesh() + { + #ifdef _DEBUG + setDebugName("SMesh"); + #endif + } + + //! destructor + virtual ~SMesh() + { + // drop buffers + for (u32 i=0; i<MeshBuffers.size(); ++i) + MeshBuffers[i]->drop(); + } + + //! clean mesh + virtual void clear() + { + for (u32 i=0; i<MeshBuffers.size(); ++i) + MeshBuffers[i]->drop(); + MeshBuffers.clear(); + BoundingBox.reset ( 0.f, 0.f, 0.f ); + } + + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const + { + return MeshBuffers.size(); + } + + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const + { + return MeshBuffers[nr]; + } + + //! returns a meshbuffer which fits a material + /** reverse search */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial & material) const + { + for (s32 i = (s32)MeshBuffers.size()-1; i >= 0; --i) + { + if ( material == MeshBuffers[i]->getMaterial()) + return MeshBuffers[i]; + } + + return 0; + } + + //! returns an axis aligned bounding box + virtual const core::aabbox3d<f32>& getBoundingBox() const + { + return BoundingBox; + } + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box) + { + BoundingBox = box; + } + + //! recalculates the bounding box + void recalculateBoundingBox() + { + if (MeshBuffers.size()) + { + BoundingBox = MeshBuffers[0]->getBoundingBox(); + for (u32 i=1; i<MeshBuffers.size(); ++i) + BoundingBox.addInternalBox(MeshBuffers[i]->getBoundingBox()); + } + else + BoundingBox.reset(0.0f, 0.0f, 0.0f); + } + + //! adds a MeshBuffer + /** The bounding box is not updated automatically. */ + void addMeshBuffer(IMeshBuffer* buf) + { + if (buf) + { + buf->grab(); + MeshBuffers.push_back(buf); + } + } + + //! sets a flag of all contained materials to a new value + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) + { + for (u32 i=0; i<MeshBuffers.size(); ++i) + MeshBuffers[i]->getMaterial().setFlag(flag, newvalue); + } + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint( E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX ) + { + for (u32 i=0; i<MeshBuffers.size(); ++i) + MeshBuffers[i]->setHardwareMappingHint(newMappingHint, buffer); + } + + //! flags the meshbuffer as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) + { + for (u32 i=0; i<MeshBuffers.size(); ++i) + MeshBuffers[i]->setDirty(buffer); + } + + //! The meshbuffers of this mesh + core::array<IMeshBuffer*> MeshBuffers; + + //! The bounding box of this mesh + core::aabbox3d<f32> BoundingBox; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SMeshBuffer.h b/builddir/irrlicht-1.8.1/include/SMeshBuffer.h new file mode 100644 index 0000000..2c3b7e2 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SMeshBuffer.h @@ -0,0 +1,7 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// replaced by template +#include "CMeshBuffer.h" + diff --git a/builddir/irrlicht-1.8.1/include/SMeshBufferLightMap.h b/builddir/irrlicht-1.8.1/include/SMeshBufferLightMap.h new file mode 100644 index 0000000..2c3b7e2 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SMeshBufferLightMap.h @@ -0,0 +1,7 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// replaced by template +#include "CMeshBuffer.h" + diff --git a/builddir/irrlicht-1.8.1/include/SMeshBufferTangents.h b/builddir/irrlicht-1.8.1/include/SMeshBufferTangents.h new file mode 100644 index 0000000..2c3b7e2 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SMeshBufferTangents.h @@ -0,0 +1,7 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// replaced by template +#include "CMeshBuffer.h" + diff --git a/builddir/irrlicht-1.8.1/include/SParticle.h b/builddir/irrlicht-1.8.1/include/SParticle.h new file mode 100644 index 0000000..c69c483 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SParticle.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_PARTICLE_H_INCLUDED__ +#define __S_PARTICLE_H_INCLUDED__ + +#include "vector3d.h" +#include "dimension2d.h" +#include "SColor.h" + +namespace irr +{ +namespace scene +{ + //! Struct for holding particle data + struct SParticle + { + //! Position of the particle + core::vector3df pos; + + //! Direction and speed of the particle + core::vector3df vector; + + //! Start life time of the particle + u32 startTime; + + //! End life time of the particle + u32 endTime; + + //! Current color of the particle + video::SColor color; + + //! Original color of the particle. + /** That's the color of the particle it had when it was emitted. */ + video::SColor startColor; + + //! Original direction and speed of the particle. + /** The direction and speed the particle had when it was emitted. */ + core::vector3df startVector; + + //! Scale of the particle. + /** The current scale of the particle. */ + core::dimension2df size; + + //! Original scale of the particle. + /** The scale of the particle when it was emitted. */ + core::dimension2df startSize; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SSharedMeshBuffer.h b/builddir/irrlicht-1.8.1/include/SSharedMeshBuffer.h new file mode 100644 index 0000000..016b796 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SSharedMeshBuffer.h @@ -0,0 +1,242 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_SHARED_MESH_BUFFER_H_INCLUDED__ +#define __S_SHARED_MESH_BUFFER_H_INCLUDED__ + +#include "irrArray.h" +#include "IMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + //! Implementation of the IMeshBuffer interface with shared vertex list + struct SSharedMeshBuffer : public IMeshBuffer + { + //! constructor + SSharedMeshBuffer() : IMeshBuffer(), Vertices(0), ChangedID_Vertex(1), ChangedID_Index(1), MappingHintVertex(EHM_NEVER), MappingHintIndex(EHM_NEVER) + { + #ifdef _DEBUG + setDebugName("SSharedMeshBuffer"); + #endif + } + + //! constructor + SSharedMeshBuffer(core::array<video::S3DVertex> *vertices) : IMeshBuffer(), Vertices(vertices) + { + #ifdef _DEBUG + setDebugName("SSharedMeshBuffer"); + #endif + } + + //! returns the material of this meshbuffer + virtual const video::SMaterial& getMaterial() const + { + return Material; + } + + //! returns the material of this meshbuffer + virtual video::SMaterial& getMaterial() + { + return Material; + } + + //! returns pointer to vertices + virtual const void* getVertices() const + { + if (Vertices) + return Vertices->const_pointer(); + else + return 0; + } + + //! returns pointer to vertices + virtual void* getVertices() + { + if (Vertices) + return Vertices->pointer(); + else + return 0; + } + + //! returns amount of vertices + virtual u32 getVertexCount() const + { + if (Vertices) + return Vertices->size(); + else + return 0; + } + + //! returns pointer to Indices + virtual const u16* getIndices() const + { + return Indices.const_pointer(); + } + + //! returns pointer to Indices + virtual u16* getIndices() + { + return Indices.pointer(); + } + + //! returns amount of indices + virtual u32 getIndexCount() const + { + return Indices.size(); + } + + //! Get type of index data which is stored in this meshbuffer. + virtual video::E_INDEX_TYPE getIndexType() const + { + return video::EIT_16BIT; + } + + //! returns an axis aligned bounding box + virtual const core::aabbox3d<f32>& getBoundingBox() const + { + return BoundingBox; + } + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box) + { + BoundingBox = box; + } + + //! returns which type of vertex data is stored. + virtual video::E_VERTEX_TYPE getVertexType() const + { + return video::EVT_STANDARD; + } + + //! recalculates the bounding box. should be called if the mesh changed. + virtual void recalculateBoundingBox() + { + if (!Vertices || Vertices->empty() || Indices.empty()) + BoundingBox.reset(0,0,0); + else + { + BoundingBox.reset((*Vertices)[Indices[0]].Pos); + for (u32 i=1; i<Indices.size(); ++i) + BoundingBox.addInternalPoint((*Vertices)[Indices[i]].Pos); + } + } + + //! returns position of vertex i + virtual const core::vector3df& getPosition(u32 i) const + { + _IRR_DEBUG_BREAK_IF(!Vertices); + return (*Vertices)[Indices[i]].Pos; + } + + //! returns position of vertex i + virtual core::vector3df& getPosition(u32 i) + { + _IRR_DEBUG_BREAK_IF(!Vertices); + return (*Vertices)[Indices[i]].Pos; + } + + //! returns normal of vertex i + virtual const core::vector3df& getNormal(u32 i) const + { + _IRR_DEBUG_BREAK_IF(!Vertices); + return (*Vertices)[Indices[i]].Normal; + } + + //! returns normal of vertex i + virtual core::vector3df& getNormal(u32 i) + { + _IRR_DEBUG_BREAK_IF(!Vertices); + return (*Vertices)[Indices[i]].Normal; + } + + //! returns texture coord of vertex i + virtual const core::vector2df& getTCoords(u32 i) const + { + _IRR_DEBUG_BREAK_IF(!Vertices); + return (*Vertices)[Indices[i]].TCoords; + } + + //! returns texture coord of vertex i + virtual core::vector2df& getTCoords(u32 i) + { + _IRR_DEBUG_BREAK_IF(!Vertices); + return (*Vertices)[Indices[i]].TCoords; + } + + //! append the vertices and indices to the current buffer + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) {} + + //! append the meshbuffer to the current buffer + virtual void append(const IMeshBuffer* const other) {} + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const + { + return MappingHintVertex; + } + + //! get the current hardware mapping hint + virtual E_HARDWARE_MAPPING getHardwareMappingHint_Index() const + { + return MappingHintIndex; + } + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX ) + { + if (buffer==EBT_VERTEX_AND_INDEX || buffer==EBT_VERTEX) + MappingHintVertex=NewMappingHint; + if (buffer==EBT_VERTEX_AND_INDEX || buffer==EBT_INDEX) + MappingHintIndex=NewMappingHint; + } + + //! flags the mesh as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) + { + if (buffer==EBT_VERTEX_AND_INDEX || buffer==EBT_VERTEX) + ++ChangedID_Vertex; + if (buffer==EBT_VERTEX_AND_INDEX || buffer==EBT_INDEX) + ++ChangedID_Index; + } + + //! Get the currently used ID for identification of changes. + /** This shouldn't be used for anything outside the VideoDriver. */ + virtual u32 getChangedID_Vertex() const {return ChangedID_Vertex;} + + //! Get the currently used ID for identification of changes. + /** This shouldn't be used for anything outside the VideoDriver. */ + virtual u32 getChangedID_Index() const {return ChangedID_Index;} + + //! Material of this meshBuffer + video::SMaterial Material; + + //! Shared Array of vertices + core::array<video::S3DVertex> *Vertices; + + //! Array of Indices + core::array<u16> Indices; + + //! ID used for hardware buffer management + u32 ChangedID_Vertex; + + //! ID used for hardware buffer management + u32 ChangedID_Index; + + //! Bounding box + core::aabbox3df BoundingBox; + + //! hardware mapping hint + E_HARDWARE_MAPPING MappingHintVertex; + E_HARDWARE_MAPPING MappingHintIndex; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SSkinMeshBuffer.h b/builddir/irrlicht-1.8.1/include/SSkinMeshBuffer.h new file mode 100644 index 0000000..d47de19 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SSkinMeshBuffer.h @@ -0,0 +1,404 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SKIN_MESH_BUFFER_H_INCLUDED__ +#define __I_SKIN_MESH_BUFFER_H_INCLUDED__ + +#include "IMeshBuffer.h" +#include "S3DVertex.h" + + +namespace irr +{ +namespace scene +{ + + +//! A mesh buffer able to choose between S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime +struct SSkinMeshBuffer : public IMeshBuffer +{ + //! Default constructor + SSkinMeshBuffer(video::E_VERTEX_TYPE vt=video::EVT_STANDARD) : + ChangedID_Vertex(1), ChangedID_Index(1), VertexType(vt), + MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER), + BoundingBoxNeedsRecalculated(true) + { + #ifdef _DEBUG + setDebugName("SSkinMeshBuffer"); + #endif + } + + //! Get Material of this buffer. + virtual const video::SMaterial& getMaterial() const + { + return Material; + } + + //! Get Material of this buffer. + virtual video::SMaterial& getMaterial() + { + return Material; + } + + //! Get standard vertex at given index + virtual video::S3DVertex *getVertex(u32 index) + { + switch (VertexType) + { + case video::EVT_2TCOORDS: + return (video::S3DVertex*)&Vertices_2TCoords[index]; + case video::EVT_TANGENTS: + return (video::S3DVertex*)&Vertices_Tangents[index]; + default: + return &Vertices_Standard[index]; + } + } + + //! Get pointer to vertex array + virtual const void* getVertices() const + { + switch (VertexType) + { + case video::EVT_2TCOORDS: + return Vertices_2TCoords.const_pointer(); + case video::EVT_TANGENTS: + return Vertices_Tangents.const_pointer(); + default: + return Vertices_Standard.const_pointer(); + } + } + + //! Get pointer to vertex array + virtual void* getVertices() + { + switch (VertexType) + { + case video::EVT_2TCOORDS: + return Vertices_2TCoords.pointer(); + case video::EVT_TANGENTS: + return Vertices_Tangents.pointer(); + default: + return Vertices_Standard.pointer(); + } + } + + //! Get vertex count + virtual u32 getVertexCount() const + { + switch (VertexType) + { + case video::EVT_2TCOORDS: + return Vertices_2TCoords.size(); + case video::EVT_TANGENTS: + return Vertices_Tangents.size(); + default: + return Vertices_Standard.size(); + } + } + + //! Get type of index data which is stored in this meshbuffer. + /** \return Index type of this buffer. */ + virtual video::E_INDEX_TYPE getIndexType() const + { + return video::EIT_16BIT; + } + + //! Get pointer to index array + virtual const u16* getIndices() const + { + return Indices.const_pointer(); + } + + //! Get pointer to index array + virtual u16* getIndices() + { + return Indices.pointer(); + } + + //! Get index count + virtual u32 getIndexCount() const + { + return Indices.size(); + } + + //! Get bounding box + virtual const core::aabbox3d<f32>& getBoundingBox() const + { + return BoundingBox; + } + + //! Set bounding box + virtual void setBoundingBox( const core::aabbox3df& box) + { + BoundingBox = box; + } + + //! Recalculate bounding box + virtual void recalculateBoundingBox() + { + if(!BoundingBoxNeedsRecalculated) + return; + + BoundingBoxNeedsRecalculated = false; + + switch (VertexType) + { + case video::EVT_STANDARD: + { + if (Vertices_Standard.empty()) + BoundingBox.reset(0,0,0); + else + { + BoundingBox.reset(Vertices_Standard[0].Pos); + for (u32 i=1; i<Vertices_Standard.size(); ++i) + BoundingBox.addInternalPoint(Vertices_Standard[i].Pos); + } + break; + } + case video::EVT_2TCOORDS: + { + if (Vertices_2TCoords.empty()) + BoundingBox.reset(0,0,0); + else + { + BoundingBox.reset(Vertices_2TCoords[0].Pos); + for (u32 i=1; i<Vertices_2TCoords.size(); ++i) + BoundingBox.addInternalPoint(Vertices_2TCoords[i].Pos); + } + break; + } + case video::EVT_TANGENTS: + { + if (Vertices_Tangents.empty()) + BoundingBox.reset(0,0,0); + else + { + BoundingBox.reset(Vertices_Tangents[0].Pos); + for (u32 i=1; i<Vertices_Tangents.size(); ++i) + BoundingBox.addInternalPoint(Vertices_Tangents[i].Pos); + } + break; + } + } + } + + //! Get vertex type + virtual video::E_VERTEX_TYPE getVertexType() const + { + return VertexType; + } + + //! Convert to 2tcoords vertex type + virtual void convertTo2TCoords() + { + if (VertexType==video::EVT_STANDARD) + { + for(u32 n=0;n<Vertices_Standard.size();++n) + { + video::S3DVertex2TCoords Vertex; + Vertex.Color=Vertices_Standard[n].Color; + Vertex.Pos=Vertices_Standard[n].Pos; + Vertex.Normal=Vertices_Standard[n].Normal; + Vertex.TCoords=Vertices_Standard[n].TCoords; + Vertices_2TCoords.push_back(Vertex); + } + Vertices_Standard.clear(); + VertexType=video::EVT_2TCOORDS; + } + } + + //! Convert to tangents vertex type + virtual void convertToTangents() + { + if (VertexType==video::EVT_STANDARD) + { + for(u32 n=0;n<Vertices_Standard.size();++n) + { + video::S3DVertexTangents Vertex; + Vertex.Color=Vertices_Standard[n].Color; + Vertex.Pos=Vertices_Standard[n].Pos; + Vertex.Normal=Vertices_Standard[n].Normal; + Vertex.TCoords=Vertices_Standard[n].TCoords; + Vertices_Tangents.push_back(Vertex); + } + Vertices_Standard.clear(); + VertexType=video::EVT_TANGENTS; + } + else if (VertexType==video::EVT_2TCOORDS) + { + for(u32 n=0;n<Vertices_2TCoords.size();++n) + { + video::S3DVertexTangents Vertex; + Vertex.Color=Vertices_2TCoords[n].Color; + Vertex.Pos=Vertices_2TCoords[n].Pos; + Vertex.Normal=Vertices_2TCoords[n].Normal; + Vertex.TCoords=Vertices_2TCoords[n].TCoords; + Vertices_Tangents.push_back(Vertex); + } + Vertices_2TCoords.clear(); + VertexType=video::EVT_TANGENTS; + } + } + + //! returns position of vertex i + virtual const core::vector3df& getPosition(u32 i) const + { + switch (VertexType) + { + case video::EVT_2TCOORDS: + return Vertices_2TCoords[i].Pos; + case video::EVT_TANGENTS: + return Vertices_Tangents[i].Pos; + default: + return Vertices_Standard[i].Pos; + } + } + + //! returns position of vertex i + virtual core::vector3df& getPosition(u32 i) + { + switch (VertexType) + { + case video::EVT_2TCOORDS: + return Vertices_2TCoords[i].Pos; + case video::EVT_TANGENTS: + return Vertices_Tangents[i].Pos; + default: + return Vertices_Standard[i].Pos; + } + } + + //! returns normal of vertex i + virtual const core::vector3df& getNormal(u32 i) const + { + switch (VertexType) + { + case video::EVT_2TCOORDS: + return Vertices_2TCoords[i].Normal; + case video::EVT_TANGENTS: + return Vertices_Tangents[i].Normal; + default: + return Vertices_Standard[i].Normal; + } + } + + //! returns normal of vertex i + virtual core::vector3df& getNormal(u32 i) + { + switch (VertexType) + { + case video::EVT_2TCOORDS: + return Vertices_2TCoords[i].Normal; + case video::EVT_TANGENTS: + return Vertices_Tangents[i].Normal; + default: + return Vertices_Standard[i].Normal; + } + } + + //! returns texture coords of vertex i + virtual const core::vector2df& getTCoords(u32 i) const + { + switch (VertexType) + { + case video::EVT_2TCOORDS: + return Vertices_2TCoords[i].TCoords; + case video::EVT_TANGENTS: + return Vertices_Tangents[i].TCoords; + default: + return Vertices_Standard[i].TCoords; + } + } + + //! returns texture coords of vertex i + virtual core::vector2df& getTCoords(u32 i) + { + switch (VertexType) + { + case video::EVT_2TCOORDS: + return Vertices_2TCoords[i].TCoords; + case video::EVT_TANGENTS: + return Vertices_Tangents[i].TCoords; + default: + return Vertices_Standard[i].TCoords; + } + } + + //! append the vertices and indices to the current buffer + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) {} + + //! append the meshbuffer to the current buffer + virtual void append(const IMeshBuffer* const other) {} + + //! get the current hardware mapping hint for vertex buffers + virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const + { + return MappingHint_Vertex; + } + + //! get the current hardware mapping hint for index buffers + virtual E_HARDWARE_MAPPING getHardwareMappingHint_Index() const + { + return MappingHint_Index; + } + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX ) + { + if (Buffer==EBT_VERTEX) + MappingHint_Vertex=NewMappingHint; + else if (Buffer==EBT_INDEX) + MappingHint_Index=NewMappingHint; + else if (Buffer==EBT_VERTEX_AND_INDEX) + { + MappingHint_Vertex=NewMappingHint; + MappingHint_Index=NewMappingHint; + } + } + + //! flags the mesh as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX) + { + if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_VERTEX) + ++ChangedID_Vertex; + if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_INDEX) + ++ChangedID_Index; + } + + virtual u32 getChangedID_Vertex() const {return ChangedID_Vertex;} + + virtual u32 getChangedID_Index() const {return ChangedID_Index;} + + //! Call this after changing the positions of any vertex. + void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; } + + core::array<video::S3DVertexTangents> Vertices_Tangents; + core::array<video::S3DVertex2TCoords> Vertices_2TCoords; + core::array<video::S3DVertex> Vertices_Standard; + core::array<u16> Indices; + + u32 ChangedID_Vertex; + u32 ChangedID_Index; + + //ISkinnedMesh::SJoint *AttachedJoint; + core::matrix4 Transformation; + + video::SMaterial Material; + video::E_VERTEX_TYPE VertexType; + + core::aabbox3d<f32> BoundingBox; + + // hardware mapping hint + E_HARDWARE_MAPPING MappingHint_Vertex:3; + E_HARDWARE_MAPPING MappingHint_Index:3; + + bool BoundingBoxNeedsRecalculated:1; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SVertexIndex.h b/builddir/irrlicht-1.8.1/include/SVertexIndex.h new file mode 100644 index 0000000..bc775ec --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SVertexIndex.h @@ -0,0 +1,79 @@ +// Copyright (C) 2008-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_VERTEX_INDEX_H_INCLUDED__ +#define __S_VERTEX_INDEX_H_INCLUDED__ + +#include "irrTypes.h" + + +namespace irr +{ +namespace video +{ +enum E_INDEX_TYPE +{ + EIT_16BIT = 0, + EIT_32BIT +}; + + +/* +//! vertex index used by the Irrlicht engine. +template <class T> +struct SSpecificVertexIndex +{ + T Index; + + //! default constructor + SSpecificVertexIndex() {} + + //! constructor + SSpecificVertexIndex(u32 _index) :Index(_index) {} + + bool operator==(const SSpecificVertexIndex& other) const + { + return (Index == other.Index); + } + + bool operator!=(const SSpecificVertexIndex& other) const + { + return (Index != other.Index); + } + + bool operator<(const SSpecificVertexIndex& other) const + { + return (Index < other.Index); + } + + SSpecificVertexIndex operator+(const u32& other) const + { + return SSpecificVertexIndex(Index + other); + } + + operator const u32() const + { + return (const u32)Index; + } + + E_INDEX_TYPE getType() const + { + if (sizeof(T)==sizeof(u16)) + return video::EIT_16BIT; + return video::EIT_32BIT; + } + +}; + +//typedef SSpecificVertexIndex<u16> SVertexIndex; + +typedef u32 SVertexIndex; +*/ + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SVertexManipulator.h b/builddir/irrlicht-1.8.1/include/SVertexManipulator.h new file mode 100644 index 0000000..592544b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SVertexManipulator.h @@ -0,0 +1,292 @@ +// Copyright (C) 2009-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_VERTEX_MANIPULATOR_H_INCLUDED__ +#define __S_VERTEX_MANIPULATOR_H_INCLUDED__ + +#include "S3DVertex.h" +#include "SColor.h" + +namespace irr +{ +namespace scene +{ + + class IMesh; + class IMeshBuffer; + struct SMesh; + + //! Interface for vertex manipulators. + /** You should derive your manipulator from this class if it shall be called for every vertex, getting as parameter just the vertex. + */ + struct IVertexManipulator + { + }; + //! Vertex manipulator to set color to a fixed color for all vertices + class SVertexColorSetManipulator : public IVertexManipulator + { + public: + SVertexColorSetManipulator(video::SColor color) : Color(color) {} + void operator()(video::S3DVertex& vertex) const + { + vertex.Color=Color; + } + private: + video::SColor Color; + }; + //! Vertex manipulator to set the alpha value of the vertex color to a fixed value + class SVertexColorSetAlphaManipulator : public IVertexManipulator + { + public: + SVertexColorSetAlphaManipulator(u32 alpha) : Alpha(alpha) {} + void operator()(video::S3DVertex& vertex) const + { + vertex.Color.setAlpha(Alpha); + } + private: + u32 Alpha; + }; + //! Vertex manipulator which invertes the RGB values + class SVertexColorInvertManipulator : public IVertexManipulator + { + public: + void operator()(video::S3DVertex& vertex) const + { + vertex.Color.setRed(255-vertex.Color.getRed()); + vertex.Color.setGreen(255-vertex.Color.getGreen()); + vertex.Color.setBlue(255-vertex.Color.getBlue()); + } + }; + //! Vertex manipulator to set vertex color to one of two values depending on a given threshold + /** If average of the color value is >Threshold the High color is chosen, else Low. */ + class SVertexColorThresholdManipulator : public IVertexManipulator + { + public: + SVertexColorThresholdManipulator(u8 threshold, video::SColor low, + video::SColor high) : Threshold(threshold), Low(low), High(high) {} + void operator()(video::S3DVertex& vertex) const + { + vertex.Color = ((u8)vertex.Color.getAverage()>Threshold)?High:Low; + } + private: + u8 Threshold; + video::SColor Low; + video::SColor High; + }; + //! Vertex manipulator which adjusts the brightness by the given amount + /** A positive value increases brightness, a negative value darkens the colors. */ + class SVertexColorBrightnessManipulator : public IVertexManipulator + { + public: + SVertexColorBrightnessManipulator(s32 amount) : Amount(amount) {} + void operator()(video::S3DVertex& vertex) const + { + vertex.Color.setRed(core::clamp(vertex.Color.getRed()+Amount, 0u, 255u)); + vertex.Color.setGreen(core::clamp(vertex.Color.getGreen()+Amount, 0u, 255u)); + vertex.Color.setBlue(core::clamp(vertex.Color.getBlue()+Amount, 0u, 255u)); + } + private: + s32 Amount; + }; + //! Vertex manipulator which adjusts the contrast by the given factor + /** Factors over 1 increase contrast, below 1 reduce it. */ + class SVertexColorContrastManipulator : public IVertexManipulator + { + public: + SVertexColorContrastManipulator(f32 factor) : Factor(factor) {} + void operator()(video::S3DVertex& vertex) const + { + vertex.Color.setRed(core::clamp(core::round32((vertex.Color.getRed()-128)*Factor)+128, 0, 255)); + vertex.Color.setGreen(core::clamp(core::round32((vertex.Color.getGreen()-128)*Factor)+128, 0, 255)); + vertex.Color.setBlue(core::clamp(core::round32((vertex.Color.getBlue()-128)*Factor)+128, 0, 255)); + } + private: + f32 Factor; + }; + //! Vertex manipulator which adjusts the contrast by the given factor and brightness by a signed amount. + /** Factors over 1 increase contrast, below 1 reduce it. + A positive amount increases brightness, a negative one darkens the colors. */ + class SVertexColorContrastBrightnessManipulator : public IVertexManipulator + { + public: + SVertexColorContrastBrightnessManipulator(f32 factor, s32 amount) : Factor(factor), Amount(amount+128) {} + void operator()(video::S3DVertex& vertex) const + { + vertex.Color.setRed(core::clamp(core::round32((vertex.Color.getRed()-128)*Factor)+Amount, 0, 255)); + vertex.Color.setGreen(core::clamp(core::round32((vertex.Color.getGreen()-128)*Factor)+Amount, 0, 255)); + vertex.Color.setBlue(core::clamp(core::round32((vertex.Color.getBlue()-128)*Factor)+Amount, 0, 255)); + } + private: + f32 Factor; + s32 Amount; + }; + //! Vertex manipulator which adjusts the brightness by a gamma operation + /** A value over one increases brightness, one below darkens the colors. */ + class SVertexColorGammaManipulator : public IVertexManipulator + { + public: + SVertexColorGammaManipulator(f32 gamma) : Gamma(1.f) + { + if (gamma != 0.f) + Gamma = 1.f/gamma; + } + void operator()(video::S3DVertex& vertex) const + { + vertex.Color.setRed(core::clamp(core::round32(powf((f32)(vertex.Color.getRed()),Gamma)), 0, 255)); + vertex.Color.setGreen(core::clamp(core::round32(powf((f32)(vertex.Color.getGreen()),Gamma)), 0, 255)); + vertex.Color.setBlue(core::clamp(core::round32(powf((f32)(vertex.Color.getBlue()),Gamma)), 0, 255)); + } + private: + f32 Gamma; + }; + //! Vertex manipulator which scales the color values + /** Can e.g be used for white balance, factor would be 255.f/brightest color. */ + class SVertexColorScaleManipulator : public IVertexManipulator + { + public: + SVertexColorScaleManipulator(f32 factor) : Factor(factor) {} + void operator()(video::S3DVertex& vertex) const + { + vertex.Color.setRed(core::clamp(core::round32(vertex.Color.getRed()*Factor), 0, 255)); + vertex.Color.setGreen(core::clamp(core::round32(vertex.Color.getGreen()*Factor), 0, 255)); + vertex.Color.setBlue(core::clamp(core::round32(vertex.Color.getBlue()*Factor), 0, 255)); + } + private: + f32 Factor; + }; + //! Vertex manipulator which desaturates the color values + /** Uses the lightness value of the color. */ + class SVertexColorDesaturateToLightnessManipulator : public IVertexManipulator + { + public: + void operator()(video::S3DVertex& vertex) const + { + vertex.Color=core::round32(vertex.Color.getLightness()); + } + }; + //! Vertex manipulator which desaturates the color values + /** Uses the average value of the color. */ + class SVertexColorDesaturateToAverageManipulator : public IVertexManipulator + { + public: + void operator()(video::S3DVertex& vertex) const + { + vertex.Color=vertex.Color.getAverage(); + } + }; + //! Vertex manipulator which desaturates the color values + /** Uses the luminance value of the color. */ + class SVertexColorDesaturateToLuminanceManipulator : public IVertexManipulator + { + public: + void operator()(video::S3DVertex& vertex) const + { + vertex.Color=core::round32(vertex.Color.getLuminance()); + } + }; + //! Vertex manipulator which interpolates the color values + /** Uses linear interpolation. */ + class SVertexColorInterpolateLinearManipulator : public IVertexManipulator + { + public: + SVertexColorInterpolateLinearManipulator(video::SColor color, f32 factor) : + Color(color), Factor(factor) {} + void operator()(video::S3DVertex& vertex) const + { + vertex.Color=vertex.Color.getInterpolated(Color, Factor); + } + private: + video::SColor Color; + f32 Factor; + }; + //! Vertex manipulator which interpolates the color values + /** Uses linear interpolation. */ + class SVertexColorInterpolateQuadraticManipulator : public IVertexManipulator + { + public: + SVertexColorInterpolateQuadraticManipulator(video::SColor color1, video::SColor color2, f32 factor) : + Color1(color1), Color2(color2), Factor(factor) {} + void operator()(video::S3DVertex& vertex) const + { + vertex.Color=vertex.Color.getInterpolated_quadratic(Color1, Color2, Factor); + } + private: + video::SColor Color1; + video::SColor Color2; + f32 Factor; + }; + + //! Vertex manipulator which scales the position of the vertex + class SVertexPositionScaleManipulator : public IVertexManipulator + { + public: + SVertexPositionScaleManipulator(const core::vector3df& factor) : Factor(factor) {} + template <typename VType> + void operator()(VType& vertex) const + { + vertex.Pos *= Factor; + } + private: + core::vector3df Factor; + }; + + //! Vertex manipulator which scales the position of the vertex along the normals + /** This can look more pleasing than the usual Scale operator, but + depends on the mesh geometry. + */ + class SVertexPositionScaleAlongNormalsManipulator : public IVertexManipulator + { + public: + SVertexPositionScaleAlongNormalsManipulator(const core::vector3df& factor) : Factor(factor) {} + template <typename VType> + void operator()(VType& vertex) const + { + vertex.Pos += vertex.Normal*Factor; + } + private: + core::vector3df Factor; + }; + + //! Vertex manipulator which transforms the position of the vertex + class SVertexPositionTransformManipulator : public IVertexManipulator + { + public: + SVertexPositionTransformManipulator(const core::matrix4& m) : Transformation(m) {} + template <typename VType> + void operator()(VType& vertex) const + { + Transformation.transformVect(vertex.Pos); + } + private: + core::matrix4 Transformation; + }; + + //! Vertex manipulator which scales the TCoords of the vertex + class SVertexTCoordsScaleManipulator : public IVertexManipulator + { + public: + SVertexTCoordsScaleManipulator(const core::vector2df& factor, u32 uvSet=1) : Factor(factor), UVSet(uvSet) {} + void operator()(video::S3DVertex2TCoords& vertex) const + { + if (1==UVSet) + vertex.TCoords *= Factor; + else if (2==UVSet) + vertex.TCoords2 *= Factor; + } + template <typename VType> + void operator()(VType& vertex) const + { + if (1==UVSet) + vertex.TCoords *= Factor; + } + private: + core::vector2df Factor; + u32 UVSet; + }; + +} // end namespace scene +} // end namespace irr + + +#endif diff --git a/builddir/irrlicht-1.8.1/include/SViewFrustum.h b/builddir/irrlicht-1.8.1/include/SViewFrustum.h new file mode 100644 index 0000000..d2b5b9a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SViewFrustum.h @@ -0,0 +1,370 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_VIEW_FRUSTUM_H_INCLUDED__ +#define __S_VIEW_FRUSTUM_H_INCLUDED__ + +#include "plane3d.h" +#include "vector3d.h" +#include "line3d.h" +#include "aabbox3d.h" +#include "matrix4.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace scene +{ + + //! Defines the view frustum. That's the space visible by the camera. + /** The view frustum is enclosed by 6 planes. These six planes share + eight points. A bounding box around these eight points is also stored in + this structure. + */ + struct SViewFrustum + { + enum VFPLANES + { + //! Far plane of the frustum. That is the plane farest away from the eye. + VF_FAR_PLANE = 0, + //! Near plane of the frustum. That is the plane nearest to the eye. + VF_NEAR_PLANE, + //! Left plane of the frustum. + VF_LEFT_PLANE, + //! Right plane of the frustum. + VF_RIGHT_PLANE, + //! Bottom plane of the frustum. + VF_BOTTOM_PLANE, + //! Top plane of the frustum. + VF_TOP_PLANE, + + //! Amount of planes enclosing the view frustum. Should be 6. + VF_PLANE_COUNT + }; + + + //! Default Constructor + SViewFrustum() {} + + //! Copy Constructor + SViewFrustum(const SViewFrustum& other); + + //! This constructor creates a view frustum based on a projection and/or view matrix. + SViewFrustum(const core::matrix4& mat); + + //! This constructor creates a view frustum based on a projection and/or view matrix. + inline void setFrom(const core::matrix4& mat); + + //! transforms the frustum by the matrix + /** \param mat: Matrix by which the view frustum is transformed.*/ + void transform(const core::matrix4& mat); + + //! returns the point which is on the far left upper corner inside the the view frustum. + core::vector3df getFarLeftUp() const; + + //! returns the point which is on the far left bottom corner inside the the view frustum. + core::vector3df getFarLeftDown() const; + + //! returns the point which is on the far right top corner inside the the view frustum. + core::vector3df getFarRightUp() const; + + //! returns the point which is on the far right bottom corner inside the the view frustum. + core::vector3df getFarRightDown() const; + + //! returns the point which is on the near left upper corner inside the the view frustum. + core::vector3df getNearLeftUp() const; + + //! returns the point which is on the near left bottom corner inside the the view frustum. + core::vector3df getNearLeftDown() const; + + //! returns the point which is on the near right top corner inside the the view frustum. + core::vector3df getNearRightUp() const; + + //! returns the point which is on the near right bottom corner inside the the view frustum. + core::vector3df getNearRightDown() const; + + //! returns a bounding box enclosing the whole view frustum + const core::aabbox3d<f32> &getBoundingBox() const; + + //! recalculates the bounding box member based on the planes + inline void recalculateBoundingBox(); + + //! get the given state's matrix based on frustum E_TRANSFORMATION_STATE + core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state); + + //! get the given state's matrix based on frustum E_TRANSFORMATION_STATE + const core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state) const; + + //! clips a line to the view frustum. + /** \return True if the line was clipped, false if not */ + bool clipLine(core::line3d<f32>& line) const; + + //! the position of the camera + core::vector3df cameraPosition; + + //! all planes enclosing the view frustum. + core::plane3d<f32> planes[VF_PLANE_COUNT]; + + //! bounding box around the view frustum + core::aabbox3d<f32> boundingBox; + + private: + //! Hold a copy of important transform matrices + enum E_TRANSFORMATION_STATE_FRUSTUM + { + ETS_VIEW = 0, + ETS_PROJECTION = 1, + ETS_COUNT_FRUSTUM + }; + + //! Hold a copy of important transform matrices + core::matrix4 Matrices[ETS_COUNT_FRUSTUM]; + }; + + + /*! + Copy constructor ViewFrustum + */ + inline SViewFrustum::SViewFrustum(const SViewFrustum& other) + { + cameraPosition=other.cameraPosition; + boundingBox=other.boundingBox; + + u32 i; + for (i=0; i<VF_PLANE_COUNT; ++i) + planes[i]=other.planes[i]; + + for (i=0; i<ETS_COUNT_FRUSTUM; ++i) + Matrices[i]=other.Matrices[i]; + } + + inline SViewFrustum::SViewFrustum(const core::matrix4& mat) + { + setFrom ( mat ); + } + + + inline void SViewFrustum::transform(const core::matrix4& mat) + { + for (u32 i=0; i<VF_PLANE_COUNT; ++i) + mat.transformPlane(planes[i]); + + mat.transformVect(cameraPosition); + recalculateBoundingBox(); + } + + + inline core::vector3df SViewFrustum::getFarLeftUp() const + { + core::vector3df p; + planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes( + planes[scene::SViewFrustum::VF_TOP_PLANE], + planes[scene::SViewFrustum::VF_LEFT_PLANE], p); + + return p; + } + + inline core::vector3df SViewFrustum::getFarLeftDown() const + { + core::vector3df p; + planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes( + planes[scene::SViewFrustum::VF_BOTTOM_PLANE], + planes[scene::SViewFrustum::VF_LEFT_PLANE], p); + + return p; + } + + inline core::vector3df SViewFrustum::getFarRightUp() const + { + core::vector3df p; + planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes( + planes[scene::SViewFrustum::VF_TOP_PLANE], + planes[scene::SViewFrustum::VF_RIGHT_PLANE], p); + + return p; + } + + inline core::vector3df SViewFrustum::getFarRightDown() const + { + core::vector3df p; + planes[scene::SViewFrustum::VF_FAR_PLANE].getIntersectionWithPlanes( + planes[scene::SViewFrustum::VF_BOTTOM_PLANE], + planes[scene::SViewFrustum::VF_RIGHT_PLANE], p); + + return p; + } + + inline core::vector3df SViewFrustum::getNearLeftUp() const + { + core::vector3df p; + planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes( + planes[scene::SViewFrustum::VF_TOP_PLANE], + planes[scene::SViewFrustum::VF_LEFT_PLANE], p); + + return p; + } + + inline core::vector3df SViewFrustum::getNearLeftDown() const + { + core::vector3df p; + planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes( + planes[scene::SViewFrustum::VF_BOTTOM_PLANE], + planes[scene::SViewFrustum::VF_LEFT_PLANE], p); + + return p; + } + + inline core::vector3df SViewFrustum::getNearRightUp() const + { + core::vector3df p; + planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes( + planes[scene::SViewFrustum::VF_TOP_PLANE], + planes[scene::SViewFrustum::VF_RIGHT_PLANE], p); + + return p; + } + + inline core::vector3df SViewFrustum::getNearRightDown() const + { + core::vector3df p; + planes[scene::SViewFrustum::VF_NEAR_PLANE].getIntersectionWithPlanes( + planes[scene::SViewFrustum::VF_BOTTOM_PLANE], + planes[scene::SViewFrustum::VF_RIGHT_PLANE], p); + + return p; + } + + inline const core::aabbox3d<f32> &SViewFrustum::getBoundingBox() const + { + return boundingBox; + } + + inline void SViewFrustum::recalculateBoundingBox() + { + boundingBox.reset ( cameraPosition ); + + boundingBox.addInternalPoint(getFarLeftUp()); + boundingBox.addInternalPoint(getFarRightUp()); + boundingBox.addInternalPoint(getFarLeftDown()); + boundingBox.addInternalPoint(getFarRightDown()); + } + + //! This constructor creates a view frustum based on a projection + //! and/or view matrix. + inline void SViewFrustum::setFrom(const core::matrix4& mat) + { + // left clipping plane + planes[VF_LEFT_PLANE].Normal.X = mat[3 ] + mat[0]; + planes[VF_LEFT_PLANE].Normal.Y = mat[7 ] + mat[4]; + planes[VF_LEFT_PLANE].Normal.Z = mat[11] + mat[8]; + planes[VF_LEFT_PLANE].D = mat[15] + mat[12]; + + // right clipping plane + planes[VF_RIGHT_PLANE].Normal.X = mat[3 ] - mat[0]; + planes[VF_RIGHT_PLANE].Normal.Y = mat[7 ] - mat[4]; + planes[VF_RIGHT_PLANE].Normal.Z = mat[11] - mat[8]; + planes[VF_RIGHT_PLANE].D = mat[15] - mat[12]; + + // top clipping plane + planes[VF_TOP_PLANE].Normal.X = mat[3 ] - mat[1]; + planes[VF_TOP_PLANE].Normal.Y = mat[7 ] - mat[5]; + planes[VF_TOP_PLANE].Normal.Z = mat[11] - mat[9]; + planes[VF_TOP_PLANE].D = mat[15] - mat[13]; + + // bottom clipping plane + planes[VF_BOTTOM_PLANE].Normal.X = mat[3 ] + mat[1]; + planes[VF_BOTTOM_PLANE].Normal.Y = mat[7 ] + mat[5]; + planes[VF_BOTTOM_PLANE].Normal.Z = mat[11] + mat[9]; + planes[VF_BOTTOM_PLANE].D = mat[15] + mat[13]; + + // far clipping plane + planes[VF_FAR_PLANE].Normal.X = mat[3 ] - mat[2]; + planes[VF_FAR_PLANE].Normal.Y = mat[7 ] - mat[6]; + planes[VF_FAR_PLANE].Normal.Z = mat[11] - mat[10]; + planes[VF_FAR_PLANE].D = mat[15] - mat[14]; + + // near clipping plane + planes[VF_NEAR_PLANE].Normal.X = mat[2]; + planes[VF_NEAR_PLANE].Normal.Y = mat[6]; + planes[VF_NEAR_PLANE].Normal.Z = mat[10]; + planes[VF_NEAR_PLANE].D = mat[14]; + + // normalize normals + u32 i; + for ( i=0; i != VF_PLANE_COUNT; ++i) + { + const f32 len = -core::reciprocal_squareroot( + planes[i].Normal.getLengthSQ()); + planes[i].Normal *= len; + planes[i].D *= len; + } + + // make bounding box + recalculateBoundingBox(); + } + + /*! + View Frustum depends on Projection & View Matrix + */ + inline core::matrix4& SViewFrustum::getTransform(video::E_TRANSFORMATION_STATE state ) + { + u32 index = 0; + switch ( state ) + { + case video::ETS_PROJECTION: + index = SViewFrustum::ETS_PROJECTION; break; + case video::ETS_VIEW: + index = SViewFrustum::ETS_VIEW; break; + default: + break; + } + return Matrices [ index ]; + } + + /*! + View Frustum depends on Projection & View Matrix + */ + inline const core::matrix4& SViewFrustum::getTransform(video::E_TRANSFORMATION_STATE state ) const + { + u32 index = 0; + switch ( state ) + { + case video::ETS_PROJECTION: + index = SViewFrustum::ETS_PROJECTION; break; + case video::ETS_VIEW: + index = SViewFrustum::ETS_VIEW; break; + default: + break; + } + return Matrices [ index ]; + } + + //! Clips a line to the frustum + inline bool SViewFrustum::clipLine(core::line3d<f32>& line) const + { + bool wasClipped = false; + for (u32 i=0; i < VF_PLANE_COUNT; ++i) + { + if (planes[i].classifyPointRelation(line.start) == core::ISREL3D_FRONT) + { + line.start = line.start.getInterpolated(line.end, + planes[i].getKnownIntersectionWithLine(line.start, line.end)); + wasClipped = true; + } + if (planes[i].classifyPointRelation(line.end) == core::ISREL3D_FRONT) + { + line.end = line.start.getInterpolated(line.end, + planes[i].getKnownIntersectionWithLine(line.start, line.end)); + wasClipped = true; + } + } + return wasClipped; + } + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/SceneParameters.h b/builddir/irrlicht-1.8.1/include/SceneParameters.h new file mode 100644 index 0000000..827ae42 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/SceneParameters.h @@ -0,0 +1,182 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_PARAMETERS_H_INCLUDED__ +#define __I_SCENE_PARAMETERS_H_INCLUDED__ + +/*! \file SceneParameters.h + \brief Header file containing all scene parameters for modifying mesh loading etc. + + This file includes all parameter names which can be set using ISceneManager::getParameters() + to modify the behavior of plugins and mesh loaders. +*/ + +namespace irr +{ +namespace scene +{ + //! Name of the parameter for changing how Irrlicht handles the ZWrite flag for transparent (blending) materials + /** The default behavior in Irrlicht is to disable writing to the + z-buffer for all really transparent, i.e. blending materials. This + avoids problems with intersecting faces, but can also break renderings. + If transparent materials should use the SMaterial flag for ZWriteEnable + just as other material types use this attribute. + Use it like this: + \code + SceneManager->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); + \endcode + **/ + const c8* const ALLOW_ZWRITE_ON_TRANSPARENT = "Allow_ZWrite_On_Transparent"; + + //! Name of the parameter for changing the texture path of the built-in csm loader. + /** Use it like this: + \code + SceneManager->getParameters()->setAttribute(scene::CSM_TEXTURE_PATH, "path/to/your/textures"); + \endcode + **/ + const c8* const CSM_TEXTURE_PATH = "CSM_TexturePath"; + + //! Name of the parameter for changing the texture path of the built-in lmts loader. + /** Use it like this: + \code + SceneManager->getParameters()->setAttribute(scene::LMTS_TEXTURE_PATH, "path/to/your/textures"); + \endcode + **/ + const c8* const LMTS_TEXTURE_PATH = "LMTS_TexturePath"; + + //! Name of the parameter for changing the texture path of the built-in my3d loader. + /** Use it like this: + \code + SceneManager->getParameters()->setAttribute(scene::MY3D_TEXTURE_PATH, "path/to/your/textures"); + \endcode + **/ + const c8* const MY3D_TEXTURE_PATH = "MY3D_TexturePath"; + + //! Name of the parameter specifying the COLLADA mesh loading mode + /** + Specifies if the COLLADA loader should create instances of the models, lights and + cameras when loading COLLADA meshes. By default, this is set to false. If this is + set to true, the ISceneManager::getMesh() method will only return a pointer to a + dummy mesh and create instances of all meshes and lights and cameras in the collada + file by itself. Example: + \code + SceneManager->getParameters()->setAttribute(scene::COLLADA_CREATE_SCENE_INSTANCES, true); + \endcode + */ + const c8* const COLLADA_CREATE_SCENE_INSTANCES = "COLLADA_CreateSceneInstances"; + + //! Name of the parameter for changing the texture path of the built-in DMF loader. + /** This path is prefixed to the file names defined in the Deled file when loading + textures. This allows to alter the paths for a specific project setting. + Use it like this: + \code + SceneManager->getStringParameters()->setAttribute(scene::DMF_TEXTURE_PATH, "path/to/your/textures"); + \endcode + **/ + const c8* const DMF_TEXTURE_PATH = "DMF_TexturePath"; + + //! Name of the parameter for preserving DMF textures dir structure with built-in DMF loader. + /** If this parameter is set to true, the texture directory defined in the Deled file + is ignored, and only the texture name is used to find the proper file. Otherwise, the + texture path is also used, which allows to use a nicer media layout. + Use it like this: + \code + //this way you won't use this setting (default) + SceneManager->getParameters()->setAttribute(scene::DMF_IGNORE_MATERIALS_DIRS, false); + \endcode + \code + //this way you'll use this setting + SceneManager->getParameters()->setAttribute(scene::DMF_IGNORE_MATERIALS_DIRS, true); + \endcode + **/ + const c8* const DMF_IGNORE_MATERIALS_DIRS = "DMF_IgnoreMaterialsDir"; + + //! Name of the parameter for setting reference value of alpha in transparent materials. + /** Use it like this: + \code + //this way you'll set alpha ref to 0.1 + SceneManager->getParameters()->setAttribute(scene::DMF_ALPHA_CHANNEL_REF, 0.1); + \endcode + **/ + const c8* const DMF_ALPHA_CHANNEL_REF = "DMF_AlphaRef"; + + //! Name of the parameter for choose to flip or not tga files. + /** Use it like this: + \code + //this way you'll choose to flip alpha textures + SceneManager->getParameters()->setAttribute(scene::DMF_FLIP_ALPHA_TEXTURES, true); + \endcode + **/ + const c8* const DMF_FLIP_ALPHA_TEXTURES = "DMF_FlipAlpha"; + + + //! Name of the parameter for changing the texture path of the built-in obj loader. + /** Use it like this: + \code + SceneManager->getParameters()->setAttribute(scene::OBJ_TEXTURE_PATH, "path/to/your/textures"); + \endcode + **/ + const c8* const OBJ_TEXTURE_PATH = "OBJ_TexturePath"; + + //! Flag to avoid loading group structures in .obj files + /** Use it like this: + \code + SceneManager->getParameters()->setAttribute(scene::OBJ_LOADER_IGNORE_GROUPS, true); + \endcode + **/ + const c8* const OBJ_LOADER_IGNORE_GROUPS = "OBJ_IgnoreGroups"; + + + //! Flag to avoid loading material .mtl file for .obj files + /** Use it like this: + \code + SceneManager->getParameters()->setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true); + \endcode + **/ + const c8* const OBJ_LOADER_IGNORE_MATERIAL_FILES = "OBJ_IgnoreMaterialFiles"; + + + //! Flag to ignore the b3d file's mipmapping flag + /** Instead Irrlicht's texture creation flag is used. Use it like this: + \code + SceneManager->getParameters()->setAttribute(scene::B3D_LOADER_IGNORE_MIPMAP_FLAG, true); + \endcode + **/ + const c8* const B3D_LOADER_IGNORE_MIPMAP_FLAG = "B3D_IgnoreMipmapFlag"; + + //! Name of the parameter for changing the texture path of the built-in b3d loader. + /** Use it like this: + \code + SceneManager->getParameters()->setAttribute(scene::B3D_TEXTURE_PATH, "path/to/your/textures"); + \endcode + **/ + const c8* const B3D_TEXTURE_PATH = "B3D_TexturePath"; + + //! Flag set as parameter when the scene manager is used as editor + /** In this way special animators like deletion animators can be stopped from + deleting scene nodes for example */ + const c8* const IRR_SCENE_MANAGER_IS_EDITOR = "IRR_Editor"; + + //! Name of the parameter for setting the length of debug normals. + /** Use it like this: + \code + SceneManager->getParameters()->setAttribute(scene::DEBUG_NORMAL_LENGTH, 1.5f); + \endcode + **/ + const c8* const DEBUG_NORMAL_LENGTH = "DEBUG_Normal_Length"; + + //! Name of the parameter for setting the color of debug normals. + /** Use it like this: + \code + SceneManager->getParameters()->setAttributeAsColor(scene::DEBUG_NORMAL_COLOR, video::SColor(255, 255, 255, 255)); + \endcode + **/ + const c8* const DEBUG_NORMAL_COLOR = "DEBUG_Normal_Color"; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/aabbox3d.h b/builddir/irrlicht-1.8.1/include/aabbox3d.h new file mode 100644 index 0000000..ae4e3ae --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/aabbox3d.h @@ -0,0 +1,332 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_AABBOX_3D_H_INCLUDED__ +#define __IRR_AABBOX_3D_H_INCLUDED__ + +#include "irrMath.h" +#include "plane3d.h" +#include "line3d.h" + +namespace irr +{ +namespace core +{ + +//! Axis aligned bounding box in 3d dimensional space. +/** Has some useful methods used with occlusion culling or clipping. +*/ +template <class T> +class aabbox3d +{ + public: + + //! Default Constructor. + aabbox3d(): MinEdge(-1,-1,-1), MaxEdge(1,1,1) {} + //! Constructor with min edge and max edge. + aabbox3d(const vector3d<T>& min, const vector3d<T>& max): MinEdge(min), MaxEdge(max) {} + //! Constructor with only one point. + aabbox3d(const vector3d<T>& init): MinEdge(init), MaxEdge(init) {} + //! Constructor with min edge and max edge as single values, not vectors. + aabbox3d(T minx, T miny, T minz, T maxx, T maxy, T maxz): MinEdge(minx, miny, minz), MaxEdge(maxx, maxy, maxz) {} + + // operators + //! Equality operator + /** \param other box to compare with. + \return True if both boxes are equal, else false. */ + inline bool operator==(const aabbox3d<T>& other) const { return (MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);} + //! Inequality operator + /** \param other box to compare with. + \return True if both boxes are different, else false. */ + inline bool operator!=(const aabbox3d<T>& other) const { return !(MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);} + + // functions + + //! Resets the bounding box to a one-point box. + /** \param x X coord of the point. + \param y Y coord of the point. + \param z Z coord of the point. */ + void reset(T x, T y, T z) + { + MaxEdge.set(x,y,z); + MinEdge = MaxEdge; + } + + //! Resets the bounding box. + /** \param initValue New box to set this one to. */ + void reset(const aabbox3d<T>& initValue) + { + *this = initValue; + } + + //! Resets the bounding box to a one-point box. + /** \param initValue New point. */ + void reset(const vector3d<T>& initValue) + { + MaxEdge = initValue; + MinEdge = initValue; + } + + //! Adds a point to the bounding box + /** The box grows bigger, if point was outside of the box. + \param p: Point to add into the box. */ + void addInternalPoint(const vector3d<T>& p) + { + addInternalPoint(p.X, p.Y, p.Z); + } + + //! Adds another bounding box + /** The box grows bigger, if the new box was outside of the box. + \param b: Other bounding box to add into this box. */ + void addInternalBox(const aabbox3d<T>& b) + { + addInternalPoint(b.MaxEdge); + addInternalPoint(b.MinEdge); + } + + //! Adds a point to the bounding box + /** The box grows bigger, if point is outside of the box. + \param x X coordinate of the point to add to this box. + \param y Y coordinate of the point to add to this box. + \param z Z coordinate of the point to add to this box. */ + void addInternalPoint(T x, T y, T z) + { + if (x>MaxEdge.X) MaxEdge.X = x; + if (y>MaxEdge.Y) MaxEdge.Y = y; + if (z>MaxEdge.Z) MaxEdge.Z = z; + + if (x<MinEdge.X) MinEdge.X = x; + if (y<MinEdge.Y) MinEdge.Y = y; + if (z<MinEdge.Z) MinEdge.Z = z; + } + + //! Get center of the bounding box + /** \return Center of the bounding box. */ + vector3d<T> getCenter() const + { + return (MinEdge + MaxEdge) / 2; + } + + //! Get extent of the box (maximal distance of two points in the box) + /** \return Extent of the bounding box. */ + vector3d<T> getExtent() const + { + return MaxEdge - MinEdge; + } + + //! Check if the box is empty. + /** This means that there is no space between the min and max edge. + \return True if box is empty, else false. */ + bool isEmpty() const + { + return MinEdge.equals ( MaxEdge ); + } + + //! Get the volume enclosed by the box in cubed units + T getVolume() const + { + const vector3d<T> e = getExtent(); + return e.X * e.Y * e.Z; + } + + //! Get the surface area of the box in squared units + T getArea() const + { + const vector3d<T> e = getExtent(); + return 2*(e.X*e.Y + e.X*e.Z + e.Y*e.Z); + } + + //! Stores all 8 edges of the box into an array + /** \param edges: Pointer to array of 8 edges. */ + void getEdges(vector3d<T> *edges) const + { + const core::vector3d<T> middle = getCenter(); + const core::vector3d<T> diag = middle - MaxEdge; + + /* + Edges are stored in this way: + Hey, am I an ascii artist, or what? :) niko. + /3--------/7 + / | / | + / | / | + 1---------5 | + | /2- - -|- -6 + | / | / + |/ | / + 0---------4/ + */ + + edges[0].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z + diag.Z); + edges[1].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z + diag.Z); + edges[2].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z - diag.Z); + edges[3].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z - diag.Z); + edges[4].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z + diag.Z); + edges[5].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z + diag.Z); + edges[6].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z - diag.Z); + edges[7].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z - diag.Z); + } + + //! Repairs the box. + /** Necessary if for example MinEdge and MaxEdge are swapped. */ + void repair() + { + T t; + + if (MinEdge.X > MaxEdge.X) + { t=MinEdge.X; MinEdge.X = MaxEdge.X; MaxEdge.X=t; } + if (MinEdge.Y > MaxEdge.Y) + { t=MinEdge.Y; MinEdge.Y = MaxEdge.Y; MaxEdge.Y=t; } + if (MinEdge.Z > MaxEdge.Z) + { t=MinEdge.Z; MinEdge.Z = MaxEdge.Z; MaxEdge.Z=t; } + } + + //! Calculates a new interpolated bounding box. + /** d=0 returns other, d=1 returns this, all other values blend between + the two boxes. + \param other Other box to interpolate between + \param d Value between 0.0f and 1.0f. + \return Interpolated box. */ + aabbox3d<T> getInterpolated(const aabbox3d<T>& other, f32 d) const + { + f32 inv = 1.0f - d; + return aabbox3d<T>((other.MinEdge*inv) + (MinEdge*d), + (other.MaxEdge*inv) + (MaxEdge*d)); + } + + //! Determines if a point is within this box. + /** Border is included (IS part of the box)! + \param p: Point to check. + \return True if the point is within the box and false if not */ + bool isPointInside(const vector3d<T>& p) const + { + return (p.X >= MinEdge.X && p.X <= MaxEdge.X && + p.Y >= MinEdge.Y && p.Y <= MaxEdge.Y && + p.Z >= MinEdge.Z && p.Z <= MaxEdge.Z); + } + + //! Determines if a point is within this box and not its borders. + /** Border is excluded (NOT part of the box)! + \param p: Point to check. + \return True if the point is within the box and false if not. */ + bool isPointTotalInside(const vector3d<T>& p) const + { + return (p.X > MinEdge.X && p.X < MaxEdge.X && + p.Y > MinEdge.Y && p.Y < MaxEdge.Y && + p.Z > MinEdge.Z && p.Z < MaxEdge.Z); + } + + //! Check if this box is completely inside the 'other' box. + /** \param other: Other box to check against. + \return True if this box is completly inside the other box, + otherwise false. */ + bool isFullInside(const aabbox3d<T>& other) const + { + return (MinEdge.X >= other.MinEdge.X && MinEdge.Y >= other.MinEdge.Y && MinEdge.Z >= other.MinEdge.Z && + MaxEdge.X <= other.MaxEdge.X && MaxEdge.Y <= other.MaxEdge.Y && MaxEdge.Z <= other.MaxEdge.Z); + } + + //! Determines if the axis-aligned box intersects with another axis-aligned box. + /** \param other: Other box to check a intersection with. + \return True if there is an intersection with the other box, + otherwise false. */ + bool intersectsWithBox(const aabbox3d<T>& other) const + { + return (MinEdge.X <= other.MaxEdge.X && MinEdge.Y <= other.MaxEdge.Y && MinEdge.Z <= other.MaxEdge.Z && + MaxEdge.X >= other.MinEdge.X && MaxEdge.Y >= other.MinEdge.Y && MaxEdge.Z >= other.MinEdge.Z); + } + + //! Tests if the box intersects with a line + /** \param line: Line to test intersection with. + \return True if there is an intersection , else false. */ + bool intersectsWithLine(const line3d<T>& line) const + { + return intersectsWithLine(line.getMiddle(), line.getVector().normalize(), + (T)(line.getLength() * 0.5)); + } + + //! Tests if the box intersects with a line + /** \param linemiddle Center of the line. + \param linevect Vector of the line. + \param halflength Half length of the line. + \return True if there is an intersection, else false. */ + bool intersectsWithLine(const vector3d<T>& linemiddle, + const vector3d<T>& linevect, T halflength) const + { + const vector3d<T> e = getExtent() * (T)0.5; + const vector3d<T> t = getCenter() - linemiddle; + + if ((fabs(t.X) > e.X + halflength * fabs(linevect.X)) || + (fabs(t.Y) > e.Y + halflength * fabs(linevect.Y)) || + (fabs(t.Z) > e.Z + halflength * fabs(linevect.Z)) ) + return false; + + T r = e.Y * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.Y); + if (fabs(t.Y*linevect.Z - t.Z*linevect.Y) > r ) + return false; + + r = e.X * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.X); + if (fabs(t.Z*linevect.X - t.X*linevect.Z) > r ) + return false; + + r = e.X * (T)fabs(linevect.Y) + e.Y * (T)fabs(linevect.X); + if (fabs(t.X*linevect.Y - t.Y*linevect.X) > r) + return false; + + return true; + } + + //! Classifies a relation with a plane. + /** \param plane Plane to classify relation to. + \return Returns ISREL3D_FRONT if the box is in front of the plane, + ISREL3D_BACK if the box is behind the plane, and + ISREL3D_CLIPPED if it is on both sides of the plane. */ + EIntersectionRelation3D classifyPlaneRelation(const plane3d<T>& plane) const + { + vector3d<T> nearPoint(MaxEdge); + vector3d<T> farPoint(MinEdge); + + if (plane.Normal.X > (T)0) + { + nearPoint.X = MinEdge.X; + farPoint.X = MaxEdge.X; + } + + if (plane.Normal.Y > (T)0) + { + nearPoint.Y = MinEdge.Y; + farPoint.Y = MaxEdge.Y; + } + + if (plane.Normal.Z > (T)0) + { + nearPoint.Z = MinEdge.Z; + farPoint.Z = MaxEdge.Z; + } + + if (plane.Normal.dotProduct(nearPoint) + plane.D > (T)0) + return ISREL3D_FRONT; + + if (plane.Normal.dotProduct(farPoint) + plane.D > (T)0) + return ISREL3D_CLIPPED; + + return ISREL3D_BACK; + } + + //! The near edge + vector3d<T> MinEdge; + + //! The far edge + vector3d<T> MaxEdge; +}; + + //! Typedef for a f32 3d bounding box. + typedef aabbox3d<f32> aabbox3df; + //! Typedef for an integer 3d bounding box. + typedef aabbox3d<s32> aabbox3di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/coreutil.h b/builddir/irrlicht-1.8.1/include/coreutil.h new file mode 100644 index 0000000..eaf0097 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/coreutil.h @@ -0,0 +1,188 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_CORE_UTIL_H_INCLUDED__ +#define __IRR_CORE_UTIL_H_INCLUDED__ + +#include "irrString.h" +#include "path.h" + +namespace irr +{ +namespace core +{ + +/*! \file coreutil.h + \brief File containing useful basic utility functions +*/ + +// ----------- some basic quite often used string functions ----------------- + +//! search if a filename has a proper extension +inline s32 isFileExtension ( const io::path& filename, + const io::path& ext0, + const io::path& ext1, + const io::path& ext2) +{ + s32 extPos = filename.findLast ( '.' ); + if ( extPos < 0 ) + return 0; + + extPos += 1; + if ( filename.equals_substring_ignore_case ( ext0, extPos ) ) return 1; + if ( filename.equals_substring_ignore_case ( ext1, extPos ) ) return 2; + if ( filename.equals_substring_ignore_case ( ext2, extPos ) ) return 3; + return 0; +} + +//! search if a filename has a proper extension +inline bool hasFileExtension ( const io::path& filename, + const io::path& ext0, + const io::path& ext1 = "", + const io::path& ext2 = "") +{ + return isFileExtension ( filename, ext0, ext1, ext2 ) > 0; +} + +//! cut the filename extension from a source file path and store it in a dest file path +inline io::path& cutFilenameExtension ( io::path &dest, const io::path &source ) +{ + s32 endPos = source.findLast ( '.' ); + dest = source.subString ( 0, endPos < 0 ? source.size () : endPos ); + return dest; +} + +//! get the filename extension from a file path +inline io::path& getFileNameExtension ( io::path &dest, const io::path &source ) +{ + s32 endPos = source.findLast ( '.' ); + if ( endPos < 0 ) + dest = ""; + else + dest = source.subString ( endPos, source.size () ); + return dest; +} + +//! delete path from filename +inline io::path& deletePathFromFilename(io::path& filename) +{ + // delete path from filename + const fschar_t* s = filename.c_str(); + const fschar_t* p = s + filename.size(); + + // search for path separator or beginning + while ( *p != '/' && *p != '\\' && p != s ) + p--; + + if ( p != s ) + { + ++p; + filename = p; + } + return filename; +} + +//! trim paths +inline io::path& deletePathFromPath(io::path& filename, s32 pathCount) +{ + // delete path from filename + s32 i = filename.size(); + + // search for path separator or beginning + while ( i>=0 ) + { + if ( filename[i] == '/' || filename[i] == '\\' ) + { + if ( --pathCount <= 0 ) + break; + } + --i; + } + + if ( i>0 ) + { + filename [ i + 1 ] = 0; + filename.validate(); + } + else + filename=""; + return filename; +} + +//! looks if file is in the same directory of path. returns offset of directory. +//! 0 means in same directory. 1 means file is direct child of path +inline s32 isInSameDirectory ( const io::path& path, const io::path& file ) +{ + s32 subA = 0; + s32 subB = 0; + s32 pos; + + if ( path.size() && !path.equalsn ( file, path.size() ) ) + return -1; + + pos = 0; + while ( (pos = path.findNext ( '/', pos )) >= 0 ) + { + subA += 1; + pos += 1; + } + + pos = 0; + while ( (pos = file.findNext ( '/', pos )) >= 0 ) + { + subB += 1; + pos += 1; + } + + return subB - subA; +} + +// splits a path into components +static inline void splitFilename(const io::path &name, io::path* path=0, + io::path* filename=0, io::path* extension=0, bool make_lower=false) +{ + s32 i = name.size(); + s32 extpos = i; + + // search for path separator or beginning + while ( i >= 0 ) + { + if ( name[i] == '.' ) + { + extpos = i; + if ( extension ) + *extension = name.subString ( extpos + 1, name.size() - (extpos + 1), make_lower ); + } + else + if ( name[i] == '/' || name[i] == '\\' ) + { + if ( filename ) + *filename = name.subString ( i + 1, extpos - (i + 1), make_lower ); + if ( path ) + { + *path = name.subString ( 0, i + 1, make_lower ); + path->replace ( '\\', '/' ); + } + return; + } + i -= 1; + } + if ( filename ) + *filename = name.subString ( 0, extpos, make_lower ); +} + + +//! some standard function ( to remove dependencies ) +#undef isdigit +#undef isspace +#undef isupper +inline s32 isdigit(s32 c) { return c >= '0' && c <= '9'; } +inline s32 isspace(s32 c) { return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'; } +inline s32 isupper(s32 c) { return c >= 'A' && c <= 'Z'; } + + +} // end namespace core +} // end namespace irr + +#endif diff --git a/builddir/irrlicht-1.8.1/include/d3d8.h b/builddir/irrlicht-1.8.1/include/d3d8.h new file mode 100644 index 0000000..f651135 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3d8.h @@ -0,0 +1,1276 @@ +/*==========================================================================; + * + * + * File: d3d8.h + * Content: Direct3D include file + * + ****************************************************************************/ + +#ifndef _D3D8_H_ +#define _D3D8_H_ + +#ifndef DIRECT3D_VERSION +#define DIRECT3D_VERSION 0x0800 +#endif //DIRECT3D_VERSION + +// include this file content only if compiling for DX8 interfaces +#if(DIRECT3D_VERSION >= 0x0800) + + +/* This identifier is passed to Direct3DCreate8 in order to ensure that an + * application was built against the correct header files. This number is + * incremented whenever a header (or other) change would require applications + * to be rebuilt. If the version doesn't match, Direct3DCreate8 will fail. + * (The number itself has no meaning.)*/ + +#define D3D_SDK_VERSION 120 + + +#include <stdlib.h> + +#define COM_NO_WINDOWS_H +#include <objbase.h> + +#include <windows.h> + +#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500) + #define HMONITOR_DECLARED + DECLARE_HANDLE(HMONITOR); +#endif + +#define D3DAPI WINAPI + +/* + * Interface IID's + */ +#if defined( _WIN32 ) && !defined( _NO_COM) + +/* IID_IDirect3D8 */ +/* {1DD9E8DA-1C77-4d40-B0CF-98FEFDFF9512} */ +DEFINE_GUID(IID_IDirect3D8, 0x1dd9e8da, 0x1c77, 0x4d40, 0xb0, 0xcf, 0x98, 0xfe, 0xfd, 0xff, 0x95, 0x12); + +/* IID_IDirect3DDevice8 */ +/* {7385E5DF-8FE8-41D5-86B6-D7B48547B6CF} */ +DEFINE_GUID(IID_IDirect3DDevice8, 0x7385e5df, 0x8fe8, 0x41d5, 0x86, 0xb6, 0xd7, 0xb4, 0x85, 0x47, 0xb6, 0xcf); + +/* IID_IDirect3DResource8 */ +/* {1B36BB7B-09B7-410a-B445-7D1430D7B33F} */ +DEFINE_GUID(IID_IDirect3DResource8, 0x1b36bb7b, 0x9b7, 0x410a, 0xb4, 0x45, 0x7d, 0x14, 0x30, 0xd7, 0xb3, 0x3f); + +/* IID_IDirect3DBaseTexture8 */ +/* {B4211CFA-51B9-4a9f-AB78-DB99B2BB678E} */ +DEFINE_GUID(IID_IDirect3DBaseTexture8, 0xb4211cfa, 0x51b9, 0x4a9f, 0xab, 0x78, 0xdb, 0x99, 0xb2, 0xbb, 0x67, 0x8e); + +/* IID_IDirect3DTexture8 */ +/* {E4CDD575-2866-4f01-B12E-7EECE1EC9358} */ +DEFINE_GUID(IID_IDirect3DTexture8, 0xe4cdd575, 0x2866, 0x4f01, 0xb1, 0x2e, 0x7e, 0xec, 0xe1, 0xec, 0x93, 0x58); + +/* IID_IDirect3DCubeTexture8 */ +/* {3EE5B968-2ACA-4c34-8BB5-7E0C3D19B750} */ +DEFINE_GUID(IID_IDirect3DCubeTexture8, 0x3ee5b968, 0x2aca, 0x4c34, 0x8b, 0xb5, 0x7e, 0x0c, 0x3d, 0x19, 0xb7, 0x50); + +/* IID_IDirect3DVolumeTexture8 */ +/* {4B8AAAFA-140F-42ba-9131-597EAFAA2EAD} */ +DEFINE_GUID(IID_IDirect3DVolumeTexture8, 0x4b8aaafa, 0x140f, 0x42ba, 0x91, 0x31, 0x59, 0x7e, 0xaf, 0xaa, 0x2e, 0xad); + +/* IID_IDirect3DVertexBuffer8 */ +/* {8AEEEAC7-05F9-44d4-B591-000B0DF1CB95} */ +DEFINE_GUID(IID_IDirect3DVertexBuffer8, 0x8aeeeac7, 0x05f9, 0x44d4, 0xb5, 0x91, 0x00, 0x0b, 0x0d, 0xf1, 0xcb, 0x95); + +/* IID_IDirect3DIndexBuffer8 */ +/* {0E689C9A-053D-44a0-9D92-DB0E3D750F86} */ +DEFINE_GUID(IID_IDirect3DIndexBuffer8, 0x0e689c9a, 0x053d, 0x44a0, 0x9d, 0x92, 0xdb, 0x0e, 0x3d, 0x75, 0x0f, 0x86); + +/* IID_IDirect3DSurface8 */ +/* {B96EEBCA-B326-4ea5-882F-2FF5BAE021DD} */ +DEFINE_GUID(IID_IDirect3DSurface8, 0xb96eebca, 0xb326, 0x4ea5, 0x88, 0x2f, 0x2f, 0xf5, 0xba, 0xe0, 0x21, 0xdd); + +/* IID_IDirect3DVolume8 */ +/* {BD7349F5-14F1-42e4-9C79-972380DB40C0} */ +DEFINE_GUID(IID_IDirect3DVolume8, 0xbd7349f5, 0x14f1, 0x42e4, 0x9c, 0x79, 0x97, 0x23, 0x80, 0xdb, 0x40, 0xc0); + +/* IID_IDirect3DSwapChain8 */ +/* {928C088B-76B9-4C6B-A536-A590853876CD} */ +DEFINE_GUID(IID_IDirect3DSwapChain8, 0x928c088b, 0x76b9, 0x4c6b, 0xa5, 0x36, 0xa5, 0x90, 0x85, 0x38, 0x76, 0xcd); + +#endif + +#ifdef __cplusplus + +interface IDirect3D8; +interface IDirect3DDevice8; + +interface IDirect3DResource8; +interface IDirect3DBaseTexture8; +interface IDirect3DTexture8; +interface IDirect3DVolumeTexture8; +interface IDirect3DCubeTexture8; + +interface IDirect3DVertexBuffer8; +interface IDirect3DIndexBuffer8; + +interface IDirect3DSurface8; +interface IDirect3DVolume8; + +interface IDirect3DSwapChain8; + +#endif + + +typedef interface IDirect3D8 IDirect3D8; +typedef interface IDirect3DDevice8 IDirect3DDevice8; +typedef interface IDirect3DResource8 IDirect3DResource8; +typedef interface IDirect3DBaseTexture8 IDirect3DBaseTexture8; +typedef interface IDirect3DTexture8 IDirect3DTexture8; +typedef interface IDirect3DVolumeTexture8 IDirect3DVolumeTexture8; +typedef interface IDirect3DCubeTexture8 IDirect3DCubeTexture8; +typedef interface IDirect3DVertexBuffer8 IDirect3DVertexBuffer8; +typedef interface IDirect3DIndexBuffer8 IDirect3DIndexBuffer8; +typedef interface IDirect3DSurface8 IDirect3DSurface8; +typedef interface IDirect3DVolume8 IDirect3DVolume8; +typedef interface IDirect3DSwapChain8 IDirect3DSwapChain8; + +#include "d3d8types.h" +#include "d3d8caps.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * DLL Function for creating a Direct3D8 object. This object supports + * enumeration and allows the creation of Direct3DDevice8 objects. + * Pass the value of the constant D3D_SDK_VERSION to this function, so + * that the run-time can validate that your application was compiled + * against the right headers. + */ + +IDirect3D8 * WINAPI Direct3DCreate8(UINT SDKVersion); + + +/* + * Direct3D interfaces + */ + + + + + + +#undef INTERFACE +#define INTERFACE IDirect3D8 + +DECLARE_INTERFACE_(IDirect3D8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3D8 methods ***/ + STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE; + STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE; + STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER8* pIdentifier) PURE; + STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter) PURE; + STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,UINT Mode,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE CheckType,D3DFORMAT DisplayFormat,D3DFORMAT BackBufferFormat,BOOL Windowed) PURE; + STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE; + STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType) PURE; + STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS8* pCaps) PURE; + STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE; + STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice8** ppReturnedDeviceInterface) PURE; +}; + +typedef struct IDirect3D8 *LPDIRECT3D8, *PDIRECT3D8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3D8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3D8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3D8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3D8_RegisterSoftwareDevice(p,a) (p)->lpVtbl->RegisterSoftwareDevice(p,a) +#define IDirect3D8_GetAdapterCount(p) (p)->lpVtbl->GetAdapterCount(p) +#define IDirect3D8_GetAdapterIdentifier(p,a,b,c) (p)->lpVtbl->GetAdapterIdentifier(p,a,b,c) +#define IDirect3D8_GetAdapterModeCount(p,a) (p)->lpVtbl->GetAdapterModeCount(p,a) +#define IDirect3D8_EnumAdapterModes(p,a,b,c) (p)->lpVtbl->EnumAdapterModes(p,a,b,c) +#define IDirect3D8_GetAdapterDisplayMode(p,a,b) (p)->lpVtbl->GetAdapterDisplayMode(p,a,b) +#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e) +#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f) +#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e) +#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e) +#define IDirect3D8_GetDeviceCaps(p,a,b,c) (p)->lpVtbl->GetDeviceCaps(p,a,b,c) +#define IDirect3D8_GetAdapterMonitor(p,a) (p)->lpVtbl->GetAdapterMonitor(p,a) +#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f) (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f) +#else +#define IDirect3D8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3D8_AddRef(p) (p)->AddRef() +#define IDirect3D8_Release(p) (p)->Release() +#define IDirect3D8_RegisterSoftwareDevice(p,a) (p)->RegisterSoftwareDevice(a) +#define IDirect3D8_GetAdapterCount(p) (p)->GetAdapterCount() +#define IDirect3D8_GetAdapterIdentifier(p,a,b,c) (p)->GetAdapterIdentifier(a,b,c) +#define IDirect3D8_GetAdapterModeCount(p,a) (p)->GetAdapterModeCount(a) +#define IDirect3D8_EnumAdapterModes(p,a,b,c) (p)->EnumAdapterModes(a,b,c) +#define IDirect3D8_GetAdapterDisplayMode(p,a,b) (p)->GetAdapterDisplayMode(a,b) +#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e) (p)->CheckDeviceType(a,b,c,d,e) +#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->CheckDeviceFormat(a,b,c,d,e,f) +#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e) (p)->CheckDeviceMultiSampleType(a,b,c,d,e) +#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->CheckDepthStencilMatch(a,b,c,d,e) +#define IDirect3D8_GetDeviceCaps(p,a,b,c) (p)->GetDeviceCaps(a,b,c) +#define IDirect3D8_GetAdapterMonitor(p,a) (p)->GetAdapterMonitor(a) +#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f) (p)->CreateDevice(a,b,c,d,e,f) +#endif + + + + + + + + + + + + + + + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DDevice8 + +DECLARE_INTERFACE_(IDirect3DDevice8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DDevice8 methods ***/ + STDMETHOD(TestCooperativeLevel)(THIS) PURE; + STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE; + STDMETHOD(ResourceManagerDiscardBytes)(THIS_ DWORD Bytes) PURE; + STDMETHOD(GetDirect3D)(THIS_ IDirect3D8** ppD3D8) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS8* pCaps) PURE; + STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters) PURE; + STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot,UINT YHotSpot,IDirect3DSurface8* pCursorBitmap) PURE; + STDMETHOD_(void, SetCursorPosition)(THIS_ UINT XScreenSpace,UINT YScreenSpace,DWORD Flags) PURE; + STDMETHOD_(BOOL, ShowCursor)(THIS_ BOOL bShow) PURE; + STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain8** pSwapChain) PURE; + STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE; + STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) PURE; + STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS* pRasterStatus) PURE; + STDMETHOD_(void, SetGammaRamp)(THIS_ DWORD Flags,CONST D3DGAMMARAMP* pRamp) PURE; + STDMETHOD_(void, GetGammaRamp)(THIS_ D3DGAMMARAMP* pRamp) PURE; + STDMETHOD(CreateTexture)(THIS_ UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) PURE; + STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) PURE; + STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) PURE; + STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer8** ppVertexBuffer) PURE; + STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) PURE; + STDMETHOD(CreateRenderTarget)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) PURE; + STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) PURE; + STDMETHOD(CreateImageSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) PURE; + STDMETHOD(CopyRects)(THIS_ IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) PURE; + STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) PURE; + STDMETHOD(GetFrontBuffer)(THIS_ IDirect3DSurface8* pDestSurface) PURE; + STDMETHOD(SetRenderTarget)(THIS_ IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) PURE; + STDMETHOD(GetRenderTarget)(THIS_ IDirect3DSurface8** ppRenderTarget) PURE; + STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface8** ppZStencilSurface) PURE; + STDMETHOD(BeginScene)(THIS) PURE; + STDMETHOD(EndScene)(THIS) PURE; + STDMETHOD(Clear)(THIS_ DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) PURE; + STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix) PURE; + STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) PURE; + STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE,CONST D3DMATRIX*) PURE; + STDMETHOD(SetViewport)(THIS_ CONST D3DVIEWPORT8* pViewport) PURE; + STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT8* pViewport) PURE; + STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL8* pMaterial) PURE; + STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL8* pMaterial) PURE; + STDMETHOD(SetLight)(THIS_ DWORD Index,CONST D3DLIGHT8*) PURE; + STDMETHOD(GetLight)(THIS_ DWORD Index,D3DLIGHT8*) PURE; + STDMETHOD(LightEnable)(THIS_ DWORD Index,BOOL Enable) PURE; + STDMETHOD(GetLightEnable)(THIS_ DWORD Index,BOOL* pEnable) PURE; + STDMETHOD(SetClipPlane)(THIS_ DWORD Index,CONST float* pPlane) PURE; + STDMETHOD(GetClipPlane)(THIS_ DWORD Index,float* pPlane) PURE; + STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD Value) PURE; + STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD* pValue) PURE; + STDMETHOD(BeginStateBlock)(THIS) PURE; + STDMETHOD(EndStateBlock)(THIS_ DWORD* pToken) PURE; + STDMETHOD(ApplyStateBlock)(THIS_ DWORD Token) PURE; + STDMETHOD(CaptureStateBlock)(THIS_ DWORD Token) PURE; + STDMETHOD(DeleteStateBlock)(THIS_ DWORD Token) PURE; + STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type,DWORD* pToken) PURE; + STDMETHOD(SetClipStatus)(THIS_ CONST D3DCLIPSTATUS8* pClipStatus) PURE; + STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS8* pClipStatus) PURE; + STDMETHOD(GetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture8** ppTexture) PURE; + STDMETHOD(SetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture8* pTexture) PURE; + STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) PURE; + STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) PURE; + STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE; + STDMETHOD(GetInfo)(THIS_ DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) PURE; + STDMETHOD(SetPaletteEntries)(THIS_ UINT PaletteNumber,CONST PALETTEENTRY* pEntries) PURE; + STDMETHOD(GetPaletteEntries)(THIS_ UINT PaletteNumber,PALETTEENTRY* pEntries) PURE; + STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT PaletteNumber) PURE; + STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT *PaletteNumber) PURE; + STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) PURE; + STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE,UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) PURE; + STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) PURE; + STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD* pDeclaration,CONST DWORD* pFunction,DWORD* pHandle,DWORD Usage) PURE; + STDMETHOD(SetVertexShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(GetVertexShader)(THIS_ DWORD* pHandle) PURE; + STDMETHOD(DeleteVertexShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(SetVertexShaderConstant)(THIS_ DWORD Register,CONST void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetVertexShaderConstant)(THIS_ DWORD Register,void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetVertexShaderDeclaration)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(GetVertexShaderFunction)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(SetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) PURE; + STDMETHOD(GetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer8** ppStreamData,UINT* pStride) PURE; + STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) PURE; + STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) PURE; + STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction,DWORD* pHandle) PURE; + STDMETHOD(SetPixelShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(GetPixelShader)(THIS_ DWORD* pHandle) PURE; + STDMETHOD(DeletePixelShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(SetPixelShaderConstant)(THIS_ DWORD Register,CONST void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetPixelShaderConstant)(THIS_ DWORD Register,void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetPixelShaderFunction)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(DrawRectPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) PURE; + STDMETHOD(DrawTriPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) PURE; + STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE; +}; + +typedef struct IDirect3DDevice8 *LPDIRECT3DDEVICE8, *PDIRECT3DDEVICE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DDevice8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DDevice8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DDevice8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DDevice8_TestCooperativeLevel(p) (p)->lpVtbl->TestCooperativeLevel(p) +#define IDirect3DDevice8_GetAvailableTextureMem(p) (p)->lpVtbl->GetAvailableTextureMem(p) +#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a) (p)->lpVtbl->ResourceManagerDiscardBytes(p,a) +#define IDirect3DDevice8_GetDirect3D(p,a) (p)->lpVtbl->GetDirect3D(p,a) +#define IDirect3DDevice8_GetDeviceCaps(p,a) (p)->lpVtbl->GetDeviceCaps(p,a) +#define IDirect3DDevice8_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a) +#define IDirect3DDevice8_GetCreationParameters(p,a) (p)->lpVtbl->GetCreationParameters(p,a) +#define IDirect3DDevice8_SetCursorProperties(p,a,b,c) (p)->lpVtbl->SetCursorProperties(p,a,b,c) +#define IDirect3DDevice8_SetCursorPosition(p,a,b,c) (p)->lpVtbl->SetCursorPosition(p,a,b,c) +#define IDirect3DDevice8_ShowCursor(p,a) (p)->lpVtbl->ShowCursor(p,a) +#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b) +#define IDirect3DDevice8_Reset(p,a) (p)->lpVtbl->Reset(p,a) +#define IDirect3DDevice8_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d) +#define IDirect3DDevice8_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) +#define IDirect3DDevice8_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a) +#define IDirect3DDevice8_SetGammaRamp(p,a,b) (p)->lpVtbl->SetGammaRamp(p,a,b) +#define IDirect3DDevice8_GetGammaRamp(p,a) (p)->lpVtbl->GetGammaRamp(p,a) +#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateTexture(p,a,b,c,d,e,f,g) +#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateVolumeTexture(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f) (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f) +#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e) (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e) (p)->lpVtbl->CreateIndexBuffer(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f) (p)->lpVtbl->CreateRenderTarget(p,a,b,c,d,e,f) +#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e) (p)->lpVtbl->CreateDepthStencilSurface(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d) (p)->lpVtbl->CreateImageSurface(p,a,b,c,d) +#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e) (p)->lpVtbl->CopyRects(p,a,b,c,d,e) +#define IDirect3DDevice8_UpdateTexture(p,a,b) (p)->lpVtbl->UpdateTexture(p,a,b) +#define IDirect3DDevice8_GetFrontBuffer(p,a) (p)->lpVtbl->GetFrontBuffer(p,a) +#define IDirect3DDevice8_SetRenderTarget(p,a,b) (p)->lpVtbl->SetRenderTarget(p,a,b) +#define IDirect3DDevice8_GetRenderTarget(p,a) (p)->lpVtbl->GetRenderTarget(p,a) +#define IDirect3DDevice8_GetDepthStencilSurface(p,a) (p)->lpVtbl->GetDepthStencilSurface(p,a) +#define IDirect3DDevice8_BeginScene(p) (p)->lpVtbl->BeginScene(p) +#define IDirect3DDevice8_EndScene(p) (p)->lpVtbl->EndScene(p) +#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f) (p)->lpVtbl->Clear(p,a,b,c,d,e,f) +#define IDirect3DDevice8_SetTransform(p,a,b) (p)->lpVtbl->SetTransform(p,a,b) +#define IDirect3DDevice8_GetTransform(p,a,b) (p)->lpVtbl->GetTransform(p,a,b) +#define IDirect3DDevice8_MultiplyTransform(p,a,b) (p)->lpVtbl->MultiplyTransform(p,a,b) +#define IDirect3DDevice8_SetViewport(p,a) (p)->lpVtbl->SetViewport(p,a) +#define IDirect3DDevice8_GetViewport(p,a) (p)->lpVtbl->GetViewport(p,a) +#define IDirect3DDevice8_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a) +#define IDirect3DDevice8_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a) +#define IDirect3DDevice8_SetLight(p,a,b) (p)->lpVtbl->SetLight(p,a,b) +#define IDirect3DDevice8_GetLight(p,a,b) (p)->lpVtbl->GetLight(p,a,b) +#define IDirect3DDevice8_LightEnable(p,a,b) (p)->lpVtbl->LightEnable(p,a,b) +#define IDirect3DDevice8_GetLightEnable(p,a,b) (p)->lpVtbl->GetLightEnable(p,a,b) +#define IDirect3DDevice8_SetClipPlane(p,a,b) (p)->lpVtbl->SetClipPlane(p,a,b) +#define IDirect3DDevice8_GetClipPlane(p,a,b) (p)->lpVtbl->GetClipPlane(p,a,b) +#define IDirect3DDevice8_SetRenderState(p,a,b) (p)->lpVtbl->SetRenderState(p,a,b) +#define IDirect3DDevice8_GetRenderState(p,a,b) (p)->lpVtbl->GetRenderState(p,a,b) +#define IDirect3DDevice8_BeginStateBlock(p) (p)->lpVtbl->BeginStateBlock(p) +#define IDirect3DDevice8_EndStateBlock(p,a) (p)->lpVtbl->EndStateBlock(p,a) +#define IDirect3DDevice8_ApplyStateBlock(p,a) (p)->lpVtbl->ApplyStateBlock(p,a) +#define IDirect3DDevice8_CaptureStateBlock(p,a) (p)->lpVtbl->CaptureStateBlock(p,a) +#define IDirect3DDevice8_DeleteStateBlock(p,a) (p)->lpVtbl->DeleteStateBlock(p,a) +#define IDirect3DDevice8_CreateStateBlock(p,a,b) (p)->lpVtbl->CreateStateBlock(p,a,b) +#define IDirect3DDevice8_SetClipStatus(p,a) (p)->lpVtbl->SetClipStatus(p,a) +#define IDirect3DDevice8_GetClipStatus(p,a) (p)->lpVtbl->GetClipStatus(p,a) +#define IDirect3DDevice8_GetTexture(p,a,b) (p)->lpVtbl->GetTexture(p,a,b) +#define IDirect3DDevice8_SetTexture(p,a,b) (p)->lpVtbl->SetTexture(p,a,b) +#define IDirect3DDevice8_GetTextureStageState(p,a,b,c) (p)->lpVtbl->GetTextureStageState(p,a,b,c) +#define IDirect3DDevice8_SetTextureStageState(p,a,b,c) (p)->lpVtbl->SetTextureStageState(p,a,b,c) +#define IDirect3DDevice8_ValidateDevice(p,a) (p)->lpVtbl->ValidateDevice(p,a) +#define IDirect3DDevice8_GetInfo(p,a,b,c) (p)->lpVtbl->GetInfo(p,a,b,c) +#define IDirect3DDevice8_SetPaletteEntries(p,a,b) (p)->lpVtbl->SetPaletteEntries(p,a,b) +#define IDirect3DDevice8_GetPaletteEntries(p,a,b) (p)->lpVtbl->GetPaletteEntries(p,a,b) +#define IDirect3DDevice8_SetCurrentTexturePalette(p,a) (p)->lpVtbl->SetCurrentTexturePalette(p,a) +#define IDirect3DDevice8_GetCurrentTexturePalette(p,a) (p)->lpVtbl->GetCurrentTexturePalette(p,a) +#define IDirect3DDevice8_DrawPrimitive(p,a,b,c) (p)->lpVtbl->DrawPrimitive(p,a,b,c) +#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e) +#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d) +#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d) (p)->lpVtbl->CreateVertexShader(p,a,b,c,d) +#define IDirect3DDevice8_SetVertexShader(p,a) (p)->lpVtbl->SetVertexShader(p,a) +#define IDirect3DDevice8_GetVertexShader(p,a) (p)->lpVtbl->GetVertexShader(p,a) +#define IDirect3DDevice8_DeleteVertexShader(p,a) (p)->lpVtbl->DeleteVertexShader(p,a) +#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c) (p)->lpVtbl->GetVertexShaderDeclaration(p,a,b,c) +#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c) (p)->lpVtbl->GetVertexShaderFunction(p,a,b,c) +#define IDirect3DDevice8_SetStreamSource(p,a,b,c) (p)->lpVtbl->SetStreamSource(p,a,b,c) +#define IDirect3DDevice8_GetStreamSource(p,a,b,c) (p)->lpVtbl->GetStreamSource(p,a,b,c) +#define IDirect3DDevice8_SetIndices(p,a,b) (p)->lpVtbl->SetIndices(p,a,b) +#define IDirect3DDevice8_GetIndices(p,a,b) (p)->lpVtbl->GetIndices(p,a,b) +#define IDirect3DDevice8_CreatePixelShader(p,a,b) (p)->lpVtbl->CreatePixelShader(p,a,b) +#define IDirect3DDevice8_SetPixelShader(p,a) (p)->lpVtbl->SetPixelShader(p,a) +#define IDirect3DDevice8_GetPixelShader(p,a) (p)->lpVtbl->GetPixelShader(p,a) +#define IDirect3DDevice8_DeletePixelShader(p,a) (p)->lpVtbl->DeletePixelShader(p,a) +#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c) (p)->lpVtbl->GetPixelShaderFunction(p,a,b,c) +#define IDirect3DDevice8_DrawRectPatch(p,a,b,c) (p)->lpVtbl->DrawRectPatch(p,a,b,c) +#define IDirect3DDevice8_DrawTriPatch(p,a,b,c) (p)->lpVtbl->DrawTriPatch(p,a,b,c) +#define IDirect3DDevice8_DeletePatch(p,a) (p)->lpVtbl->DeletePatch(p,a) +#else +#define IDirect3DDevice8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DDevice8_AddRef(p) (p)->AddRef() +#define IDirect3DDevice8_Release(p) (p)->Release() +#define IDirect3DDevice8_TestCooperativeLevel(p) (p)->TestCooperativeLevel() +#define IDirect3DDevice8_GetAvailableTextureMem(p) (p)->GetAvailableTextureMem() +#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a) (p)->ResourceManagerDiscardBytes(a) +#define IDirect3DDevice8_GetDirect3D(p,a) (p)->GetDirect3D(a) +#define IDirect3DDevice8_GetDeviceCaps(p,a) (p)->GetDeviceCaps(a) +#define IDirect3DDevice8_GetDisplayMode(p,a) (p)->GetDisplayMode(a) +#define IDirect3DDevice8_GetCreationParameters(p,a) (p)->GetCreationParameters(a) +#define IDirect3DDevice8_SetCursorProperties(p,a,b,c) (p)->SetCursorProperties(a,b,c) +#define IDirect3DDevice8_SetCursorPosition(p,a,b,c) (p)->SetCursorPosition(a,b,c) +#define IDirect3DDevice8_ShowCursor(p,a) (p)->ShowCursor(a) +#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b) (p)->CreateAdditionalSwapChain(a,b) +#define IDirect3DDevice8_Reset(p,a) (p)->Reset(a) +#define IDirect3DDevice8_Present(p,a,b,c,d) (p)->Present(a,b,c,d) +#define IDirect3DDevice8_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c) +#define IDirect3DDevice8_GetRasterStatus(p,a) (p)->GetRasterStatus(a) +#define IDirect3DDevice8_SetGammaRamp(p,a,b) (p)->SetGammaRamp(a,b) +#define IDirect3DDevice8_GetGammaRamp(p,a) (p)->GetGammaRamp(a) +#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g) (p)->CreateTexture(a,b,c,d,e,f,g) +#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h) (p)->CreateVolumeTexture(a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f) (p)->CreateCubeTexture(a,b,c,d,e,f) +#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e) (p)->CreateVertexBuffer(a,b,c,d,e) +#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e) (p)->CreateIndexBuffer(a,b,c,d,e) +#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f) (p)->CreateRenderTarget(a,b,c,d,e,f) +#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e) (p)->CreateDepthStencilSurface(a,b,c,d,e) +#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d) (p)->CreateImageSurface(a,b,c,d) +#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e) (p)->CopyRects(a,b,c,d,e) +#define IDirect3DDevice8_UpdateTexture(p,a,b) (p)->UpdateTexture(a,b) +#define IDirect3DDevice8_GetFrontBuffer(p,a) (p)->GetFrontBuffer(a) +#define IDirect3DDevice8_SetRenderTarget(p,a,b) (p)->SetRenderTarget(a,b) +#define IDirect3DDevice8_GetRenderTarget(p,a) (p)->GetRenderTarget(a) +#define IDirect3DDevice8_GetDepthStencilSurface(p,a) (p)->GetDepthStencilSurface(a) +#define IDirect3DDevice8_BeginScene(p) (p)->BeginScene() +#define IDirect3DDevice8_EndScene(p) (p)->EndScene() +#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f) (p)->Clear(a,b,c,d,e,f) +#define IDirect3DDevice8_SetTransform(p,a,b) (p)->SetTransform(a,b) +#define IDirect3DDevice8_GetTransform(p,a,b) (p)->GetTransform(a,b) +#define IDirect3DDevice8_MultiplyTransform(p,a,b) (p)->MultiplyTransform(a,b) +#define IDirect3DDevice8_SetViewport(p,a) (p)->SetViewport(a) +#define IDirect3DDevice8_GetViewport(p,a) (p)->GetViewport(a) +#define IDirect3DDevice8_SetMaterial(p,a) (p)->SetMaterial(a) +#define IDirect3DDevice8_GetMaterial(p,a) (p)->GetMaterial(a) +#define IDirect3DDevice8_SetLight(p,a,b) (p)->SetLight(a,b) +#define IDirect3DDevice8_GetLight(p,a,b) (p)->GetLight(a,b) +#define IDirect3DDevice8_LightEnable(p,a,b) (p)->LightEnable(a,b) +#define IDirect3DDevice8_GetLightEnable(p,a,b) (p)->GetLightEnable(a,b) +#define IDirect3DDevice8_SetClipPlane(p,a,b) (p)->SetClipPlane(a,b) +#define IDirect3DDevice8_GetClipPlane(p,a,b) (p)->GetClipPlane(a,b) +#define IDirect3DDevice8_SetRenderState(p,a,b) (p)->SetRenderState(a,b) +#define IDirect3DDevice8_GetRenderState(p,a,b) (p)->GetRenderState(a,b) +#define IDirect3DDevice8_BeginStateBlock(p) (p)->BeginStateBlock() +#define IDirect3DDevice8_EndStateBlock(p,a) (p)->EndStateBlock(a) +#define IDirect3DDevice8_ApplyStateBlock(p,a) (p)->ApplyStateBlock(a) +#define IDirect3DDevice8_CaptureStateBlock(p,a) (p)->CaptureStateBlock(a) +#define IDirect3DDevice8_DeleteStateBlock(p,a) (p)->DeleteStateBlock(a) +#define IDirect3DDevice8_CreateStateBlock(p,a,b) (p)->CreateStateBlock(a,b) +#define IDirect3DDevice8_SetClipStatus(p,a) (p)->SetClipStatus(a) +#define IDirect3DDevice8_GetClipStatus(p,a) (p)->GetClipStatus(a) +#define IDirect3DDevice8_GetTexture(p,a,b) (p)->GetTexture(a,b) +#define IDirect3DDevice8_SetTexture(p,a,b) (p)->SetTexture(a,b) +#define IDirect3DDevice8_GetTextureStageState(p,a,b,c) (p)->GetTextureStageState(a,b,c) +#define IDirect3DDevice8_SetTextureStageState(p,a,b,c) (p)->SetTextureStageState(a,b,c) +#define IDirect3DDevice8_ValidateDevice(p,a) (p)->ValidateDevice(a) +#define IDirect3DDevice8_GetInfo(p,a,b,c) (p)->GetInfo(a,b,c) +#define IDirect3DDevice8_SetPaletteEntries(p,a,b) (p)->SetPaletteEntries(a,b) +#define IDirect3DDevice8_GetPaletteEntries(p,a,b) (p)->GetPaletteEntries(a,b) +#define IDirect3DDevice8_SetCurrentTexturePalette(p,a) (p)->SetCurrentTexturePalette(a) +#define IDirect3DDevice8_GetCurrentTexturePalette(p,a) (p)->GetCurrentTexturePalette(a) +#define IDirect3DDevice8_DrawPrimitive(p,a,b,c) (p)->DrawPrimitive(a,b,c) +#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->DrawIndexedPrimitive(a,b,c,d,e) +#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d) (p)->DrawPrimitiveUP(a,b,c,d) +#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->DrawIndexedPrimitiveUP(a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->ProcessVertices(a,b,c,d,e) +#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d) (p)->CreateVertexShader(a,b,c,d) +#define IDirect3DDevice8_SetVertexShader(p,a) (p)->SetVertexShader(a) +#define IDirect3DDevice8_GetVertexShader(p,a) (p)->GetVertexShader(a) +#define IDirect3DDevice8_DeleteVertexShader(p,a) (p)->DeleteVertexShader(a) +#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c) (p)->SetVertexShaderConstant(a,b,c) +#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c) (p)->GetVertexShaderConstant(a,b,c) +#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c) (p)->GetVertexShaderDeclaration(a,b,c) +#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c) (p)->GetVertexShaderFunction(a,b,c) +#define IDirect3DDevice8_SetStreamSource(p,a,b,c) (p)->SetStreamSource(a,b,c) +#define IDirect3DDevice8_GetStreamSource(p,a,b,c) (p)->GetStreamSource(a,b,c) +#define IDirect3DDevice8_SetIndices(p,a,b) (p)->SetIndices(a,b) +#define IDirect3DDevice8_GetIndices(p,a,b) (p)->GetIndices(a,b) +#define IDirect3DDevice8_CreatePixelShader(p,a,b) (p)->CreatePixelShader(a,b) +#define IDirect3DDevice8_SetPixelShader(p,a) (p)->SetPixelShader(a) +#define IDirect3DDevice8_GetPixelShader(p,a) (p)->GetPixelShader(a) +#define IDirect3DDevice8_DeletePixelShader(p,a) (p)->DeletePixelShader(a) +#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c) (p)->SetPixelShaderConstant(a,b,c) +#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c) (p)->GetPixelShaderConstant(a,b,c) +#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c) (p)->GetPixelShaderFunction(a,b,c) +#define IDirect3DDevice8_DrawRectPatch(p,a,b,c) (p)->DrawRectPatch(a,b,c) +#define IDirect3DDevice8_DrawTriPatch(p,a,b,c) (p)->DrawTriPatch(a,b,c) +#define IDirect3DDevice8_DeletePatch(p,a) (p)->DeletePatch(a) +#endif + + + +#undef INTERFACE +#define INTERFACE IDirect3DSwapChain8 + +DECLARE_INTERFACE_(IDirect3DSwapChain8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DSwapChain8 methods ***/ + STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) PURE; +}; + +typedef struct IDirect3DSwapChain8 *LPDIRECT3DSWAPCHAIN8, *PDIRECT3DSWAPCHAIN8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DSwapChain8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DSwapChain8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DSwapChain8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DSwapChain8_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d) +#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) +#else +#define IDirect3DSwapChain8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DSwapChain8_AddRef(p) (p)->AddRef() +#define IDirect3DSwapChain8_Release(p) (p)->Release() +#define IDirect3DSwapChain8_Present(p,a,b,c,d) (p)->Present(a,b,c,d) +#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c) +#endif + + + +#undef INTERFACE +#define INTERFACE IDirect3DResource8 + +DECLARE_INTERFACE_(IDirect3DResource8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; +}; + +typedef struct IDirect3DResource8 *LPDIRECT3DRESOURCE8, *PDIRECT3DRESOURCE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DResource8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DResource8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DResource8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DResource8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DResource8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DResource8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DResource8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DResource8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DResource8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DResource8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DResource8_GetType(p) (p)->lpVtbl->GetType(p) +#else +#define IDirect3DResource8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DResource8_AddRef(p) (p)->AddRef() +#define IDirect3DResource8_Release(p) (p)->Release() +#define IDirect3DResource8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DResource8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DResource8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DResource8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DResource8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DResource8_GetPriority(p) (p)->GetPriority() +#define IDirect3DResource8_PreLoad(p) (p)->PreLoad() +#define IDirect3DResource8_GetType(p) (p)->GetType() +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DBaseTexture8 + +DECLARE_INTERFACE_(IDirect3DBaseTexture8, IDirect3DResource8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; +}; + +typedef struct IDirect3DBaseTexture8 *LPDIRECT3DBASETEXTURE8, *PDIRECT3DBASETEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DBaseTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DBaseTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DBaseTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DBaseTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DBaseTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DBaseTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DBaseTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DBaseTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DBaseTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DBaseTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DBaseTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DBaseTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#else +#define IDirect3DBaseTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DBaseTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DBaseTexture8_Release(p) (p)->Release() +#define IDirect3DBaseTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DBaseTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DBaseTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DBaseTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DBaseTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DBaseTexture8_GetType(p) (p)->GetType() +#define IDirect3DBaseTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DBaseTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DBaseTexture8_GetLevelCount(p) (p)->GetLevelCount() +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DTexture8 + +DECLARE_INTERFACE_(IDirect3DTexture8, IDirect3DBaseTexture8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level,IDirect3DSurface8** ppSurfaceLevel) PURE; + STDMETHOD(LockRect)(THIS_ UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS_ UINT Level) PURE; + STDMETHOD(AddDirtyRect)(THIS_ CONST RECT* pDirtyRect) PURE; +}; + +typedef struct IDirect3DTexture8 *LPDIRECT3DTEXTURE8, *PDIRECT3DTEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DTexture8_GetSurfaceLevel(p,a,b) (p)->lpVtbl->GetSurfaceLevel(p,a,b) +#define IDirect3DTexture8_LockRect(p,a,b,c,d) (p)->lpVtbl->LockRect(p,a,b,c,d) +#define IDirect3DTexture8_UnlockRect(p,a) (p)->lpVtbl->UnlockRect(p,a) +#define IDirect3DTexture8_AddDirtyRect(p,a) (p)->lpVtbl->AddDirtyRect(p,a) +#else +#define IDirect3DTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DTexture8_Release(p) (p)->Release() +#define IDirect3DTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DTexture8_GetType(p) (p)->GetType() +#define IDirect3DTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DTexture8_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DTexture8_GetSurfaceLevel(p,a,b) (p)->GetSurfaceLevel(a,b) +#define IDirect3DTexture8_LockRect(p,a,b,c,d) (p)->LockRect(a,b,c,d) +#define IDirect3DTexture8_UnlockRect(p,a) (p)->UnlockRect(a) +#define IDirect3DTexture8_AddDirtyRect(p,a) (p)->AddDirtyRect(a) +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVolumeTexture8 + +DECLARE_INTERFACE_(IDirect3DVolumeTexture8, IDirect3DBaseTexture8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DVOLUME_DESC *pDesc) PURE; + STDMETHOD(GetVolumeLevel)(THIS_ UINT Level,IDirect3DVolume8** ppVolumeLevel) PURE; + STDMETHOD(LockBox)(THIS_ UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) PURE; + STDMETHOD(UnlockBox)(THIS_ UINT Level) PURE; + STDMETHOD(AddDirtyBox)(THIS_ CONST D3DBOX* pDirtyBox) PURE; +}; + +typedef struct IDirect3DVolumeTexture8 *LPDIRECT3DVOLUMETEXTURE8, *PDIRECT3DVOLUMETEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVolumeTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVolumeTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVolumeTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVolumeTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVolumeTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVolumeTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DVolumeTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DVolumeTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DVolumeTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DVolumeTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DVolumeTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DVolumeTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b) (p)->lpVtbl->GetVolumeLevel(p,a,b) +#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d) (p)->lpVtbl->LockBox(p,a,b,c,d) +#define IDirect3DVolumeTexture8_UnlockBox(p,a) (p)->lpVtbl->UnlockBox(p,a) +#define IDirect3DVolumeTexture8_AddDirtyBox(p,a) (p)->lpVtbl->AddDirtyBox(p,a) +#else +#define IDirect3DVolumeTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVolumeTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DVolumeTexture8_Release(p) (p)->Release() +#define IDirect3DVolumeTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVolumeTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVolumeTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DVolumeTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DVolumeTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DVolumeTexture8_GetType(p) (p)->GetType() +#define IDirect3DVolumeTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DVolumeTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DVolumeTexture8_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b) (p)->GetVolumeLevel(a,b) +#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d) (p)->LockBox(a,b,c,d) +#define IDirect3DVolumeTexture8_UnlockBox(p,a) (p)->UnlockBox(a) +#define IDirect3DVolumeTexture8_AddDirtyBox(p,a) (p)->AddDirtyBox(a) +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DCubeTexture8 + +DECLARE_INTERFACE_(IDirect3DCubeTexture8, IDirect3DBaseTexture8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface8** ppCubeMapSurface) PURE; + STDMETHOD(LockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level) PURE; + STDMETHOD(AddDirtyRect)(THIS_ D3DCUBEMAP_FACES FaceType,CONST RECT* pDirtyRect) PURE; +}; + +typedef struct IDirect3DCubeTexture8 *LPDIRECT3DCUBETEXTURE8, *PDIRECT3DCUBETEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DCubeTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DCubeTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DCubeTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DCubeTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DCubeTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DCubeTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DCubeTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DCubeTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DCubeTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DCubeTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DCubeTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DCubeTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c) (p)->lpVtbl->GetCubeMapSurface(p,a,b,c) +#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e) (p)->lpVtbl->LockRect(p,a,b,c,d,e) +#define IDirect3DCubeTexture8_UnlockRect(p,a,b) (p)->lpVtbl->UnlockRect(p,a,b) +#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b) (p)->lpVtbl->AddDirtyRect(p,a,b) +#else +#define IDirect3DCubeTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DCubeTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DCubeTexture8_Release(p) (p)->Release() +#define IDirect3DCubeTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DCubeTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DCubeTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DCubeTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DCubeTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DCubeTexture8_GetType(p) (p)->GetType() +#define IDirect3DCubeTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DCubeTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DCubeTexture8_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c) (p)->GetCubeMapSurface(a,b,c) +#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e) (p)->LockRect(a,b,c,d,e) +#define IDirect3DCubeTexture8_UnlockRect(p,a,b) (p)->UnlockRect(a,b) +#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b) (p)->AddDirtyRect(a,b) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVertexBuffer8 + +DECLARE_INTERFACE_(IDirect3DVertexBuffer8, IDirect3DResource8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,BYTE** ppbData,DWORD Flags) PURE; + STDMETHOD(Unlock)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3DVERTEXBUFFER_DESC *pDesc) PURE; +}; + +typedef struct IDirect3DVertexBuffer8 *LPDIRECT3DVERTEXBUFFER8, *PDIRECT3DVERTEXBUFFER8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVertexBuffer8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVertexBuffer8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVertexBuffer8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVertexBuffer8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVertexBuffer8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVertexBuffer8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DVertexBuffer8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DVertexBuffer8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DVertexBuffer8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) +#define IDirect3DVertexBuffer8_Unlock(p) (p)->lpVtbl->Unlock(p) +#define IDirect3DVertexBuffer8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#else +#define IDirect3DVertexBuffer8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVertexBuffer8_AddRef(p) (p)->AddRef() +#define IDirect3DVertexBuffer8_Release(p) (p)->Release() +#define IDirect3DVertexBuffer8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVertexBuffer8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVertexBuffer8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DVertexBuffer8_GetPriority(p) (p)->GetPriority() +#define IDirect3DVertexBuffer8_PreLoad(p) (p)->PreLoad() +#define IDirect3DVertexBuffer8_GetType(p) (p)->GetType() +#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d) +#define IDirect3DVertexBuffer8_Unlock(p) (p)->Unlock() +#define IDirect3DVertexBuffer8_GetDesc(p,a) (p)->GetDesc(a) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DIndexBuffer8 + +DECLARE_INTERFACE_(IDirect3DIndexBuffer8, IDirect3DResource8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,BYTE** ppbData,DWORD Flags) PURE; + STDMETHOD(Unlock)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3DINDEXBUFFER_DESC *pDesc) PURE; +}; + +typedef struct IDirect3DIndexBuffer8 *LPDIRECT3DINDEXBUFFER8, *PDIRECT3DINDEXBUFFER8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DIndexBuffer8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DIndexBuffer8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DIndexBuffer8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DIndexBuffer8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DIndexBuffer8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DIndexBuffer8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DIndexBuffer8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DIndexBuffer8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DIndexBuffer8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) +#define IDirect3DIndexBuffer8_Unlock(p) (p)->lpVtbl->Unlock(p) +#define IDirect3DIndexBuffer8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#else +#define IDirect3DIndexBuffer8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DIndexBuffer8_AddRef(p) (p)->AddRef() +#define IDirect3DIndexBuffer8_Release(p) (p)->Release() +#define IDirect3DIndexBuffer8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DIndexBuffer8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DIndexBuffer8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DIndexBuffer8_GetPriority(p) (p)->GetPriority() +#define IDirect3DIndexBuffer8_PreLoad(p) (p)->PreLoad() +#define IDirect3DIndexBuffer8_GetType(p) (p)->GetType() +#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d) +#define IDirect3DIndexBuffer8_Unlock(p) (p)->Unlock() +#define IDirect3DIndexBuffer8_GetDesc(p,a) (p)->GetDesc(a) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DSurface8 + +DECLARE_INTERFACE_(IDirect3DSurface8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DSurface8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD(GetContainer)(THIS_ REFIID riid,void** ppContainer) PURE; + STDMETHOD(GetDesc)(THIS_ D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(LockRect)(THIS_ D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS) PURE; +}; + +typedef struct IDirect3DSurface8 *LPDIRECT3DSURFACE8, *PDIRECT3DSURFACE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DSurface8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DSurface8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DSurface8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DSurface8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DSurface8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DSurface8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DSurface8_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b) +#define IDirect3DSurface8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#define IDirect3DSurface8_LockRect(p,a,b,c) (p)->lpVtbl->LockRect(p,a,b,c) +#define IDirect3DSurface8_UnlockRect(p) (p)->lpVtbl->UnlockRect(p) +#else +#define IDirect3DSurface8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DSurface8_AddRef(p) (p)->AddRef() +#define IDirect3DSurface8_Release(p) (p)->Release() +#define IDirect3DSurface8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DSurface8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DSurface8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DSurface8_GetContainer(p,a,b) (p)->GetContainer(a,b) +#define IDirect3DSurface8_GetDesc(p,a) (p)->GetDesc(a) +#define IDirect3DSurface8_LockRect(p,a,b,c) (p)->LockRect(a,b,c) +#define IDirect3DSurface8_UnlockRect(p) (p)->UnlockRect() +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVolume8 + +DECLARE_INTERFACE_(IDirect3DVolume8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DVolume8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD(GetContainer)(THIS_ REFIID riid,void** ppContainer) PURE; + STDMETHOD(GetDesc)(THIS_ D3DVOLUME_DESC *pDesc) PURE; + STDMETHOD(LockBox)(THIS_ D3DLOCKED_BOX * pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) PURE; + STDMETHOD(UnlockBox)(THIS) PURE; +}; + +typedef struct IDirect3DVolume8 *LPDIRECT3DVOLUME8, *PDIRECT3DVOLUME8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVolume8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVolume8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVolume8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVolume8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVolume8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVolume8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVolume8_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b) +#define IDirect3DVolume8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#define IDirect3DVolume8_LockBox(p,a,b,c) (p)->lpVtbl->LockBox(p,a,b,c) +#define IDirect3DVolume8_UnlockBox(p) (p)->lpVtbl->UnlockBox(p) +#else +#define IDirect3DVolume8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVolume8_AddRef(p) (p)->AddRef() +#define IDirect3DVolume8_Release(p) (p)->Release() +#define IDirect3DVolume8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVolume8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVolume8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVolume8_GetContainer(p,a,b) (p)->GetContainer(a,b) +#define IDirect3DVolume8_GetDesc(p,a) (p)->GetDesc(a) +#define IDirect3DVolume8_LockBox(p,a,b,c) (p)->LockBox(a,b,c) +#define IDirect3DVolume8_UnlockBox(p) (p)->UnlockBox() +#endif + +/**************************************************************************** + * Flags for SetPrivateData method on all D3D8 interfaces + * + * The passed pointer is an IUnknown ptr. The SizeOfData argument to SetPrivateData + * must be set to sizeof(IUnknown*). Direct3D will call AddRef through this + * pointer and Release when the private data is destroyed. The data will be + * destroyed when another SetPrivateData with the same GUID is set, when + * FreePrivateData is called, or when the D3D8 object is freed. + ****************************************************************************/ +#define D3DSPD_IUNKNOWN 0x00000001L + +/**************************************************************************** + * + * Parameter for IDirect3D8 Enum and GetCaps8 functions to get the info for + * the current mode only. + * + ****************************************************************************/ + +#define D3DCURRENT_DISPLAY_MODE 0x00EFFFFFL + +/**************************************************************************** + * + * Flags for IDirect3D8::CreateDevice's BehaviorFlags + * + ****************************************************************************/ + +#define D3DCREATE_FPU_PRESERVE 0x00000002L +#define D3DCREATE_MULTITHREADED 0x00000004L + +#define D3DCREATE_PUREDEVICE 0x00000010L +#define D3DCREATE_SOFTWARE_VERTEXPROCESSING 0x00000020L +#define D3DCREATE_HARDWARE_VERTEXPROCESSING 0x00000040L +#define D3DCREATE_MIXED_VERTEXPROCESSING 0x00000080L + + +/**************************************************************************** + * + * Parameter for IDirect3D8::CreateDevice's iAdapter + * + ****************************************************************************/ + +#define D3DADAPTER_DEFAULT 0 + +/**************************************************************************** + * + * Flags for IDirect3D8::EnumAdapters + * + ****************************************************************************/ + +#define D3DENUM_NO_WHQL_LEVEL 0x00000002L + +/**************************************************************************** + * + * Maximum number of back-buffers supported in DX8 + * + ****************************************************************************/ + +#define D3DPRESENT_BACK_BUFFERS_MAX 3L + +/**************************************************************************** + * + * Flags for IDirect3DDevice8::SetGammaRamp + * + ****************************************************************************/ + +#define D3DSGR_NO_CALIBRATION 0x00000000L +#define D3DSGR_CALIBRATE 0x00000001L + +/**************************************************************************** + * + * Flags for IDirect3DDevice8::SetCursorPosition + * + ****************************************************************************/ + +#define D3DCURSOR_IMMEDIATE_UPDATE 0x00000001L + +/**************************************************************************** + * + * Flags for DrawPrimitive/DrawIndexedPrimitive + * Also valid for Begin/BeginIndexed + * Also valid for VertexBuffer::CreateVertexBuffer + ****************************************************************************/ + + +/* + * DirectDraw error codes + */ +#define _FACD3D 0x876 +#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code ) + +/* + * Direct3D Errors + */ +#define D3D_OK S_OK + +#define D3DERR_WRONGTEXTUREFORMAT MAKE_D3DHRESULT(2072) +#define D3DERR_UNSUPPORTEDCOLOROPERATION MAKE_D3DHRESULT(2073) +#define D3DERR_UNSUPPORTEDCOLORARG MAKE_D3DHRESULT(2074) +#define D3DERR_UNSUPPORTEDALPHAOPERATION MAKE_D3DHRESULT(2075) +#define D3DERR_UNSUPPORTEDALPHAARG MAKE_D3DHRESULT(2076) +#define D3DERR_TOOMANYOPERATIONS MAKE_D3DHRESULT(2077) +#define D3DERR_CONFLICTINGTEXTUREFILTER MAKE_D3DHRESULT(2078) +#define D3DERR_UNSUPPORTEDFACTORVALUE MAKE_D3DHRESULT(2079) +#define D3DERR_CONFLICTINGRENDERSTATE MAKE_D3DHRESULT(2081) +#define D3DERR_UNSUPPORTEDTEXTUREFILTER MAKE_D3DHRESULT(2082) +#define D3DERR_CONFLICTINGTEXTUREPALETTE MAKE_D3DHRESULT(2086) +#define D3DERR_DRIVERINTERNALERROR MAKE_D3DHRESULT(2087) + +#define D3DERR_NOTFOUND MAKE_D3DHRESULT(2150) +#define D3DERR_MOREDATA MAKE_D3DHRESULT(2151) +#define D3DERR_DEVICELOST MAKE_D3DHRESULT(2152) +#define D3DERR_DEVICENOTRESET MAKE_D3DHRESULT(2153) +#define D3DERR_NOTAVAILABLE MAKE_D3DHRESULT(2154) +#define D3DERR_OUTOFVIDEOMEMORY MAKE_D3DHRESULT(380) +#define D3DERR_INVALIDDEVICE MAKE_D3DHRESULT(2155) +#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156) +#define D3DERR_DRIVERINVALIDCALL MAKE_D3DHRESULT(2157) + +#ifdef __cplusplus +}; +#endif + +#endif /* (DIRECT3D_VERSION >= 0x0800) */ +#endif /* _D3D_H_ */ + diff --git a/builddir/irrlicht-1.8.1/include/d3d8caps.h b/builddir/irrlicht-1.8.1/include/d3d8caps.h new file mode 100644 index 0000000..6699893 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3d8caps.h @@ -0,0 +1,354 @@ +/*==========================================================================; + * + * Copyright (C) 1995-2000 Microsoft Corporation. All Rights Reserved. + * + * File: d3d8caps.h + * Content: Direct3D capabilities include file + * + ***************************************************************************/ + +#ifndef _D3D8CAPS_H +#define _D3D8CAPS_H + +#ifndef DIRECT3D_VERSION +#define DIRECT3D_VERSION 0x0800 +#endif //DIRECT3D_VERSION + +// include this file content only if compiling for DX8 interfaces +#if(DIRECT3D_VERSION >= 0x0800) + +#pragma pack(4) + +typedef struct _D3DCAPS8 +{ + /* Device Info */ + D3DDEVTYPE DeviceType; + UINT AdapterOrdinal; + + /* Caps from DX7 Draw */ + DWORD Caps; + DWORD Caps2; + DWORD Caps3; + DWORD PresentationIntervals; + + /* Cursor Caps */ + DWORD CursorCaps; + + /* 3D Device Caps */ + DWORD DevCaps; + + DWORD PrimitiveMiscCaps; + DWORD RasterCaps; + DWORD ZCmpCaps; + DWORD SrcBlendCaps; + DWORD DestBlendCaps; + DWORD AlphaCmpCaps; + DWORD ShadeCaps; + DWORD TextureCaps; + DWORD TextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture8's + DWORD CubeTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DCubeTexture8's + DWORD VolumeTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DVolumeTexture8's + DWORD TextureAddressCaps; // D3DPTADDRESSCAPS for IDirect3DTexture8's + DWORD VolumeTextureAddressCaps; // D3DPTADDRESSCAPS for IDirect3DVolumeTexture8's + + DWORD LineCaps; // D3DLINECAPS + + DWORD MaxTextureWidth, MaxTextureHeight; + DWORD MaxVolumeExtent; + + DWORD MaxTextureRepeat; + DWORD MaxTextureAspectRatio; + DWORD MaxAnisotropy; + float MaxVertexW; + + float GuardBandLeft; + float GuardBandTop; + float GuardBandRight; + float GuardBandBottom; + + float ExtentsAdjust; + DWORD StencilCaps; + + DWORD FVFCaps; + DWORD TextureOpCaps; + DWORD MaxTextureBlendStages; + DWORD MaxSimultaneousTextures; + + DWORD VertexProcessingCaps; + DWORD MaxActiveLights; + DWORD MaxUserClipPlanes; + DWORD MaxVertexBlendMatrices; + DWORD MaxVertexBlendMatrixIndex; + + float MaxPointSize; + + DWORD MaxPrimitiveCount; // max number of primitives per DrawPrimitive call + DWORD MaxVertexIndex; + DWORD MaxStreams; + DWORD MaxStreamStride; // max stride for SetStreamSource + + DWORD VertexShaderVersion; + DWORD MaxVertexShaderConst; // number of vertex shader constant registers + + DWORD PixelShaderVersion; + float MaxPixelShaderValue; // max value of pixel shader arithmetic component + +} D3DCAPS8; + +// +// BIT DEFINES FOR D3DCAPS8 DWORD MEMBERS +// + +// +// Caps +// +#define D3DCAPS_READ_SCANLINE 0x00020000L + +// +// Caps2 +// +#define D3DCAPS2_NO2DDURING3DSCENE 0x00000002L +#define D3DCAPS2_FULLSCREENGAMMA 0x00020000L +#define D3DCAPS2_CANRENDERWINDOWED 0x00080000L +#define D3DCAPS2_CANCALIBRATEGAMMA 0x00100000L +#define D3DCAPS2_RESERVED 0x02000000L + +// +// Caps3 +// +#define D3DCAPS3_RESERVED 0x8000001fL + +// +// PresentationIntervals +// +#define D3DPRESENT_INTERVAL_DEFAULT 0x00000000L +#define D3DPRESENT_INTERVAL_ONE 0x00000001L +#define D3DPRESENT_INTERVAL_TWO 0x00000002L +#define D3DPRESENT_INTERVAL_THREE 0x00000004L +#define D3DPRESENT_INTERVAL_FOUR 0x00000008L +#define D3DPRESENT_INTERVAL_IMMEDIATE 0x80000000L + +// +// CursorCaps +// +// Driver supports HW color cursor in at least hi-res modes(height >=400) +#define D3DCURSORCAPS_COLOR 0x00000001L +// Driver supports HW cursor also in low-res modes(height < 400) +#define D3DCURSORCAPS_LOWRES 0x00000002L + +// +// DevCaps +// +#define D3DDEVCAPS_EXECUTESYSTEMMEMORY 0x00000010L /* Device can use execute buffers from system memory */ +#define D3DDEVCAPS_EXECUTEVIDEOMEMORY 0x00000020L /* Device can use execute buffers from video memory */ +#define D3DDEVCAPS_TLVERTEXSYSTEMMEMORY 0x00000040L /* Device can use TL buffers from system memory */ +#define D3DDEVCAPS_TLVERTEXVIDEOMEMORY 0x00000080L /* Device can use TL buffers from video memory */ +#define D3DDEVCAPS_TEXTURESYSTEMMEMORY 0x00000100L /* Device can texture from system memory */ +#define D3DDEVCAPS_TEXTUREVIDEOMEMORY 0x00000200L /* Device can texture from device memory */ +#define D3DDEVCAPS_DRAWPRIMTLVERTEX 0x00000400L /* Device can draw TLVERTEX primitives */ +#define D3DDEVCAPS_CANRENDERAFTERFLIP 0x00000800L /* Device can render without waiting for flip to complete */ +#define D3DDEVCAPS_TEXTURENONLOCALVIDMEM 0x00001000L /* Device can texture from nonlocal video memory */ +#define D3DDEVCAPS_DRAWPRIMITIVES2 0x00002000L /* Device can support DrawPrimitives2 */ +#define D3DDEVCAPS_SEPARATETEXTUREMEMORIES 0x00004000L /* Device is texturing from separate memory pools */ +#define D3DDEVCAPS_DRAWPRIMITIVES2EX 0x00008000L /* Device can support Extended DrawPrimitives2 i.e. DX7 compliant driver*/ +#define D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000L /* Device can support transformation and lighting in hardware and DRAWPRIMITIVES2EX must be also */ +#define D3DDEVCAPS_CANBLTSYSTONONLOCAL 0x00020000L /* Device supports a Tex Blt from system memory to non-local vidmem */ +#define D3DDEVCAPS_HWRASTERIZATION 0x00080000L /* Device has HW acceleration for rasterization */ +#define D3DDEVCAPS_PUREDEVICE 0x00100000L /* Device supports D3DCREATE_PUREDEVICE */ +#define D3DDEVCAPS_QUINTICRTPATCHES 0x00200000L /* Device supports quintic Beziers and BSplines */ +#define D3DDEVCAPS_RTPATCHES 0x00400000L /* Device supports Rect and Tri patches */ +#define D3DDEVCAPS_RTPATCHHANDLEZERO 0x00800000L /* Indicates that RT Patches may be drawn efficiently using handle 0 */ +#define D3DDEVCAPS_NPATCHES 0x01000000L /* Device supports N-Patches */ + +// +// PrimitiveMiscCaps +// +#define D3DPMISCCAPS_MASKZ 0x00000002L +#define D3DPMISCCAPS_LINEPATTERNREP 0x00000004L +#define D3DPMISCCAPS_CULLNONE 0x00000010L +#define D3DPMISCCAPS_CULLCW 0x00000020L +#define D3DPMISCCAPS_CULLCCW 0x00000040L +#define D3DPMISCCAPS_COLORWRITEENABLE 0x00000080L +#define D3DPMISCCAPS_CLIPPLANESCALEDPOINTS 0x00000100L /* Device correctly clips scaled points to clip planes */ +#define D3DPMISCCAPS_CLIPTLVERTS 0x00000200L /* device will clip post-transformed vertex primitives */ +#define D3DPMISCCAPS_TSSARGTEMP 0x00000400L /* device supports D3DTA_TEMP for temporary register */ +#define D3DPMISCCAPS_BLENDOP 0x00000800L /* device supports D3DRS_BLENDOP */ + +// +// LineCaps +// +#define D3DLINECAPS_TEXTURE 0x00000001L +#define D3DLINECAPS_ZTEST 0x00000002L +#define D3DLINECAPS_BLEND 0x00000004L +#define D3DLINECAPS_ALPHACMP 0x00000008L +#define D3DLINECAPS_FOG 0x00000010L + +// +// RasterCaps +// +#define D3DPRASTERCAPS_DITHER 0x00000001L +#define D3DPRASTERCAPS_PAT 0x00000008L +#define D3DPRASTERCAPS_ZTEST 0x00000010L +#define D3DPRASTERCAPS_FOGVERTEX 0x00000080L +#define D3DPRASTERCAPS_FOGTABLE 0x00000100L +#define D3DPRASTERCAPS_ANTIALIASEDGES 0x00001000L +#define D3DPRASTERCAPS_MIPMAPLODBIAS 0x00002000L +#define D3DPRASTERCAPS_ZBIAS 0x00004000L +#define D3DPRASTERCAPS_ZBUFFERLESSHSR 0x00008000L +#define D3DPRASTERCAPS_FOGRANGE 0x00010000L +#define D3DPRASTERCAPS_ANISOTROPY 0x00020000L +#define D3DPRASTERCAPS_WBUFFER 0x00040000L +#define D3DPRASTERCAPS_WFOG 0x00100000L +#define D3DPRASTERCAPS_ZFOG 0x00200000L +#define D3DPRASTERCAPS_COLORPERSPECTIVE 0x00400000L /* Device iterates colors perspective correct */ +#define D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE 0x00800000L + +// +// ZCmpCaps, AlphaCmpCaps +// +#define D3DPCMPCAPS_NEVER 0x00000001L +#define D3DPCMPCAPS_LESS 0x00000002L +#define D3DPCMPCAPS_EQUAL 0x00000004L +#define D3DPCMPCAPS_LESSEQUAL 0x00000008L +#define D3DPCMPCAPS_GREATER 0x00000010L +#define D3DPCMPCAPS_NOTEQUAL 0x00000020L +#define D3DPCMPCAPS_GREATEREQUAL 0x00000040L +#define D3DPCMPCAPS_ALWAYS 0x00000080L + +// +// SourceBlendCaps, DestBlendCaps +// +#define D3DPBLENDCAPS_ZERO 0x00000001L +#define D3DPBLENDCAPS_ONE 0x00000002L +#define D3DPBLENDCAPS_SRCCOLOR 0x00000004L +#define D3DPBLENDCAPS_INVSRCCOLOR 0x00000008L +#define D3DPBLENDCAPS_SRCALPHA 0x00000010L +#define D3DPBLENDCAPS_INVSRCALPHA 0x00000020L +#define D3DPBLENDCAPS_DESTALPHA 0x00000040L +#define D3DPBLENDCAPS_INVDESTALPHA 0x00000080L +#define D3DPBLENDCAPS_DESTCOLOR 0x00000100L +#define D3DPBLENDCAPS_INVDESTCOLOR 0x00000200L +#define D3DPBLENDCAPS_SRCALPHASAT 0x00000400L +#define D3DPBLENDCAPS_BOTHSRCALPHA 0x00000800L +#define D3DPBLENDCAPS_BOTHINVSRCALPHA 0x00001000L + +// +// ShadeCaps +// +#define D3DPSHADECAPS_COLORGOURAUDRGB 0x00000008L +#define D3DPSHADECAPS_SPECULARGOURAUDRGB 0x00000200L +#define D3DPSHADECAPS_ALPHAGOURAUDBLEND 0x00004000L +#define D3DPSHADECAPS_FOGGOURAUD 0x00080000L + +// +// TextureCaps +// +#define D3DPTEXTURECAPS_PERSPECTIVE 0x00000001L /* Perspective-correct texturing is supported */ +#define D3DPTEXTURECAPS_POW2 0x00000002L /* Power-of-2 texture dimensions are required - applies to non-Cube/Volume textures only. */ +#define D3DPTEXTURECAPS_ALPHA 0x00000004L /* Alpha in texture pixels is supported */ +#define D3DPTEXTURECAPS_SQUAREONLY 0x00000020L /* Only square textures are supported */ +#define D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE 0x00000040L /* Texture indices are not scaled by the texture size prior to interpolation */ +#define D3DPTEXTURECAPS_ALPHAPALETTE 0x00000080L /* Device can draw alpha from texture palettes */ +// Device can use non-POW2 textures if: +// 1) D3DTEXTURE_ADDRESS is set to CLAMP for this texture's stage +// 2) D3DRS_WRAP(N) is zero for this texture's coordinates +// 3) mip mapping is not enabled (use magnification filter only) +#define D3DPTEXTURECAPS_NONPOW2CONDITIONAL 0x00000100L +#define D3DPTEXTURECAPS_PROJECTED 0x00000400L /* Device can do D3DTTFF_PROJECTED */ +#define D3DPTEXTURECAPS_CUBEMAP 0x00000800L /* Device can do cubemap textures */ +#define D3DPTEXTURECAPS_VOLUMEMAP 0x00002000L /* Device can do volume textures */ +#define D3DPTEXTURECAPS_MIPMAP 0x00004000L /* Device can do mipmapped textures */ +#define D3DPTEXTURECAPS_MIPVOLUMEMAP 0x00008000L /* Device can do mipmapped volume textures */ +#define D3DPTEXTURECAPS_MIPCUBEMAP 0x00010000L /* Device can do mipmapped cube maps */ +#define D3DPTEXTURECAPS_CUBEMAP_POW2 0x00020000L /* Device requires that cubemaps be power-of-2 dimension */ +#define D3DPTEXTURECAPS_VOLUMEMAP_POW2 0x00040000L /* Device requires that volume maps be power-of-2 dimension */ + +// +// TextureFilterCaps +// +#define D3DPTFILTERCAPS_MINFPOINT 0x00000100L /* Min Filter */ +#define D3DPTFILTERCAPS_MINFLINEAR 0x00000200L +#define D3DPTFILTERCAPS_MINFANISOTROPIC 0x00000400L +#define D3DPTFILTERCAPS_MIPFPOINT 0x00010000L /* Mip Filter */ +#define D3DPTFILTERCAPS_MIPFLINEAR 0x00020000L +#define D3DPTFILTERCAPS_MAGFPOINT 0x01000000L /* Mag Filter */ +#define D3DPTFILTERCAPS_MAGFLINEAR 0x02000000L +#define D3DPTFILTERCAPS_MAGFANISOTROPIC 0x04000000L +#define D3DPTFILTERCAPS_MAGFAFLATCUBIC 0x08000000L +#define D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC 0x10000000L + +// +// TextureAddressCaps +// +#define D3DPTADDRESSCAPS_WRAP 0x00000001L +#define D3DPTADDRESSCAPS_MIRROR 0x00000002L +#define D3DPTADDRESSCAPS_CLAMP 0x00000004L +#define D3DPTADDRESSCAPS_BORDER 0x00000008L +#define D3DPTADDRESSCAPS_INDEPENDENTUV 0x00000010L +#define D3DPTADDRESSCAPS_MIRRORONCE 0x00000020L + +// +// StencilCaps +// +#define D3DSTENCILCAPS_KEEP 0x00000001L +#define D3DSTENCILCAPS_ZERO 0x00000002L +#define D3DSTENCILCAPS_REPLACE 0x00000004L +#define D3DSTENCILCAPS_INCRSAT 0x00000008L +#define D3DSTENCILCAPS_DECRSAT 0x00000010L +#define D3DSTENCILCAPS_INVERT 0x00000020L +#define D3DSTENCILCAPS_INCR 0x00000040L +#define D3DSTENCILCAPS_DECR 0x00000080L + +// +// TextureOpCaps +// +#define D3DTEXOPCAPS_DISABLE 0x00000001L +#define D3DTEXOPCAPS_SELECTARG1 0x00000002L +#define D3DTEXOPCAPS_SELECTARG2 0x00000004L +#define D3DTEXOPCAPS_MODULATE 0x00000008L +#define D3DTEXOPCAPS_MODULATE2X 0x00000010L +#define D3DTEXOPCAPS_MODULATE4X 0x00000020L +#define D3DTEXOPCAPS_ADD 0x00000040L +#define D3DTEXOPCAPS_ADDSIGNED 0x00000080L +#define D3DTEXOPCAPS_ADDSIGNED2X 0x00000100L +#define D3DTEXOPCAPS_SUBTRACT 0x00000200L +#define D3DTEXOPCAPS_ADDSMOOTH 0x00000400L +#define D3DTEXOPCAPS_BLENDDIFFUSEALPHA 0x00000800L +#define D3DTEXOPCAPS_BLENDTEXTUREALPHA 0x00001000L +#define D3DTEXOPCAPS_BLENDFACTORALPHA 0x00002000L +#define D3DTEXOPCAPS_BLENDTEXTUREALPHAPM 0x00004000L +#define D3DTEXOPCAPS_BLENDCURRENTALPHA 0x00008000L +#define D3DTEXOPCAPS_PREMODULATE 0x00010000L +#define D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR 0x00020000L +#define D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA 0x00040000L +#define D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR 0x00080000L +#define D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA 0x00100000L +#define D3DTEXOPCAPS_BUMPENVMAP 0x00200000L +#define D3DTEXOPCAPS_BUMPENVMAPLUMINANCE 0x00400000L +#define D3DTEXOPCAPS_DOTPRODUCT3 0x00800000L +#define D3DTEXOPCAPS_MULTIPLYADD 0x01000000L +#define D3DTEXOPCAPS_LERP 0x02000000L + +// +// FVFCaps +// +#define D3DFVFCAPS_TEXCOORDCOUNTMASK 0x0000ffffL /* mask for texture coordinate count field */ +#define D3DFVFCAPS_DONOTSTRIPELEMENTS 0x00080000L /* Device prefers that vertex elements not be stripped */ +#define D3DFVFCAPS_PSIZE 0x00100000L /* Device can receive point size */ + +// +// VertexProcessingCaps +// +#define D3DVTXPCAPS_TEXGEN 0x00000001L /* device can do texgen */ +#define D3DVTXPCAPS_MATERIALSOURCE7 0x00000002L /* device can do DX7-level colormaterialsource ops */ +#define D3DVTXPCAPS_DIRECTIONALLIGHTS 0x00000008L /* device can do directional lights */ +#define D3DVTXPCAPS_POSITIONALLIGHTS 0x00000010L /* device can do positional lights (includes point and spot) */ +#define D3DVTXPCAPS_LOCALVIEWER 0x00000020L /* device can do local viewer */ +#define D3DVTXPCAPS_TWEENING 0x00000040L /* device can do vertex tweening */ +#define D3DVTXPCAPS_NO_VSDT_UBYTE4 0x00000080L /* device does not support D3DVSDT_UBYTE4 */ + +#pragma pack() + +#endif /* (DIRECT3D_VERSION >= 0x0800) */ +#endif /* _D3D8CAPS_H_ */ + diff --git a/builddir/irrlicht-1.8.1/include/d3d8types.h b/builddir/irrlicht-1.8.1/include/d3d8types.h new file mode 100644 index 0000000..6837d6e --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3d8types.h @@ -0,0 +1,1600 @@ +/*==========================================================================; + * + * Copyright (C) 1995-2000 Microsoft Corporation. All Rights Reserved. + * + * File: d3d8types.h + * Content: Direct3D capabilities include file + * + ***************************************************************************/ + +#ifndef _D3D8TYPES_H_ +#define _D3D8TYPES_H_ + +#ifndef DIRECT3D_VERSION +#define DIRECT3D_VERSION 0x0800 +#endif //DIRECT3D_VERSION + +// include this file content only if compiling for DX8 interfaces +#if(DIRECT3D_VERSION >= 0x0800) + +#include <float.h> + +#pragma warning(disable:4201) // anonymous unions warning +#pragma pack(4) + +// D3DCOLOR is equivalent to D3DFMT_A8R8G8B8 +#ifndef D3DCOLOR_DEFINED +typedef DWORD D3DCOLOR; +#define D3DCOLOR_DEFINED +#endif + +// maps unsigned 8 bits/channel to D3DCOLOR +#define D3DCOLOR_ARGB(a,r,g,b) \ + ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) +#define D3DCOLOR_RGBA(r,g,b,a) D3DCOLOR_ARGB(a,r,g,b) +#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b) + +// maps floating point channels (0.f to 1.f range) to D3DCOLOR +#define D3DCOLOR_COLORVALUE(r,g,b,a) \ + D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f)) + + +#ifndef D3DVECTOR_DEFINED +typedef struct _D3DVECTOR { + float x; + float y; + float z; +} D3DVECTOR; +#define D3DVECTOR_DEFINED +#endif + +#ifndef D3DCOLORVALUE_DEFINED +typedef struct _D3DCOLORVALUE { + float r; + float g; + float b; + float a; +} D3DCOLORVALUE; +#define D3DCOLORVALUE_DEFINED +#endif + +#ifndef D3DRECT_DEFINED +typedef struct _D3DRECT { + LONG x1; + LONG y1; + LONG x2; + LONG y2; +} D3DRECT; +#define D3DRECT_DEFINED +#endif + +#ifndef D3DMATRIX_DEFINED +typedef struct _D3DMATRIX { + union { + struct { + float _11, _12, _13, _14; + float _21, _22, _23, _24; + float _31, _32, _33, _34; + float _41, _42, _43, _44; + + }; + float m[4][4]; + }; +} D3DMATRIX; +#define D3DMATRIX_DEFINED +#endif + +typedef struct _D3DVIEWPORT8 { + DWORD X; + DWORD Y; /* Viewport Top left */ + DWORD Width; + DWORD Height; /* Viewport Dimensions */ + float MinZ; /* Min/max of clip Volume */ + float MaxZ; +} D3DVIEWPORT8; + +/* + * Values for clip fields. + */ + +// Max number of user clipping planes, supported in D3D. +#define D3DMAXUSERCLIPPLANES 32 + +// These bits could be ORed together to use with D3DRS_CLIPPLANEENABLE +// +#define D3DCLIPPLANE0 (1 << 0) +#define D3DCLIPPLANE1 (1 << 1) +#define D3DCLIPPLANE2 (1 << 2) +#define D3DCLIPPLANE3 (1 << 3) +#define D3DCLIPPLANE4 (1 << 4) +#define D3DCLIPPLANE5 (1 << 5) + +// The following bits are used in the ClipUnion and ClipIntersection +// members of the D3DCLIPSTATUS8 +// + +#define D3DCS_LEFT 0x00000001L +#define D3DCS_RIGHT 0x00000002L +#define D3DCS_TOP 0x00000004L +#define D3DCS_BOTTOM 0x00000008L +#define D3DCS_FRONT 0x00000010L +#define D3DCS_BACK 0x00000020L +#define D3DCS_PLANE0 0x00000040L +#define D3DCS_PLANE1 0x00000080L +#define D3DCS_PLANE2 0x00000100L +#define D3DCS_PLANE3 0x00000200L +#define D3DCS_PLANE4 0x00000400L +#define D3DCS_PLANE5 0x00000800L + +#define D3DCS_ALL D3DCS_LEFT | \ + D3DCS_RIGHT | \ + D3DCS_TOP | \ + D3DCS_BOTTOM | \ + D3DCS_FRONT | \ + D3DCS_BACK | \ + D3DCS_PLANE0 | \ + D3DCS_PLANE1 | \ + D3DCS_PLANE2 | \ + D3DCS_PLANE3 | \ + D3DCS_PLANE4 | \ + D3DCS_PLANE5; + +typedef struct _D3DCLIPSTATUS8 { + DWORD ClipUnion; + DWORD ClipIntersection; +} D3DCLIPSTATUS8; + +typedef struct _D3DMATERIAL8 { + D3DCOLORVALUE Diffuse; /* Diffuse color RGBA */ + D3DCOLORVALUE Ambient; /* Ambient color RGB */ + D3DCOLORVALUE Specular; /* Specular 'shininess' */ + D3DCOLORVALUE Emissive; /* Emissive color RGB */ + float Power; /* Sharpness if specular highlight */ +} D3DMATERIAL8; + +typedef enum _D3DLIGHTTYPE { + D3DLIGHT_POINT = 1, + D3DLIGHT_SPOT = 2, + D3DLIGHT_DIRECTIONAL = 3, + D3DLIGHT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DLIGHTTYPE; + +typedef struct _D3DLIGHT8 { + D3DLIGHTTYPE Type; /* Type of light source */ + D3DCOLORVALUE Diffuse; /* Diffuse color of light */ + D3DCOLORVALUE Specular; /* Specular color of light */ + D3DCOLORVALUE Ambient; /* Ambient color of light */ + D3DVECTOR Position; /* Position in world space */ + D3DVECTOR Direction; /* Direction in world space */ + float Range; /* Cutoff range */ + float Falloff; /* Falloff */ + float Attenuation0; /* Constant attenuation */ + float Attenuation1; /* Linear attenuation */ + float Attenuation2; /* Quadratic attenuation */ + float Theta; /* Inner angle of spotlight cone */ + float Phi; /* Outer angle of spotlight cone */ +} D3DLIGHT8; + +/* + * Options for clearing + */ +#define D3DCLEAR_TARGET 0x00000001l /* Clear target surface */ +#define D3DCLEAR_ZBUFFER 0x00000002l /* Clear target z buffer */ +#define D3DCLEAR_STENCIL 0x00000004l /* Clear stencil planes */ + +/* + * The following defines the rendering states + */ + +typedef enum _D3DSHADEMODE { + D3DSHADE_FLAT = 1, + D3DSHADE_GOURAUD = 2, + D3DSHADE_PHONG = 3, + D3DSHADE_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DSHADEMODE; + +typedef enum _D3DFILLMODE { + D3DFILL_POINT = 1, + D3DFILL_WIREFRAME = 2, + D3DFILL_SOLID = 3, + D3DFILL_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DFILLMODE; + +typedef struct _D3DLINEPATTERN { + WORD wRepeatFactor; + WORD wLinePattern; +} D3DLINEPATTERN; + +typedef enum _D3DBLEND { + D3DBLEND_ZERO = 1, + D3DBLEND_ONE = 2, + D3DBLEND_SRCCOLOR = 3, + D3DBLEND_INVSRCCOLOR = 4, + D3DBLEND_SRCALPHA = 5, + D3DBLEND_INVSRCALPHA = 6, + D3DBLEND_DESTALPHA = 7, + D3DBLEND_INVDESTALPHA = 8, + D3DBLEND_DESTCOLOR = 9, + D3DBLEND_INVDESTCOLOR = 10, + D3DBLEND_SRCALPHASAT = 11, + D3DBLEND_BOTHSRCALPHA = 12, + D3DBLEND_BOTHINVSRCALPHA = 13, + D3DBLEND_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DBLEND; + +typedef enum _D3DBLENDOP { + D3DBLENDOP_ADD = 1, + D3DBLENDOP_SUBTRACT = 2, + D3DBLENDOP_REVSUBTRACT = 3, + D3DBLENDOP_MIN = 4, + D3DBLENDOP_MAX = 5, + D3DBLENDOP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DBLENDOP; + +typedef enum _D3DTEXTUREADDRESS { + D3DTADDRESS_WRAP = 1, + D3DTADDRESS_MIRROR = 2, + D3DTADDRESS_CLAMP = 3, + D3DTADDRESS_BORDER = 4, + D3DTADDRESS_MIRRORONCE = 5, + D3DTADDRESS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTEXTUREADDRESS; + +typedef enum _D3DCULL { + D3DCULL_NONE = 1, + D3DCULL_CW = 2, + D3DCULL_CCW = 3, + D3DCULL_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DCULL; + +typedef enum _D3DCMPFUNC { + D3DCMP_NEVER = 1, + D3DCMP_LESS = 2, + D3DCMP_EQUAL = 3, + D3DCMP_LESSEQUAL = 4, + D3DCMP_GREATER = 5, + D3DCMP_NOTEQUAL = 6, + D3DCMP_GREATEREQUAL = 7, + D3DCMP_ALWAYS = 8, + D3DCMP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DCMPFUNC; + +typedef enum _D3DSTENCILOP { + D3DSTENCILOP_KEEP = 1, + D3DSTENCILOP_ZERO = 2, + D3DSTENCILOP_REPLACE = 3, + D3DSTENCILOP_INCRSAT = 4, + D3DSTENCILOP_DECRSAT = 5, + D3DSTENCILOP_INVERT = 6, + D3DSTENCILOP_INCR = 7, + D3DSTENCILOP_DECR = 8, + D3DSTENCILOP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DSTENCILOP; + +typedef enum _D3DFOGMODE { + D3DFOG_NONE = 0, + D3DFOG_EXP = 1, + D3DFOG_EXP2 = 2, + D3DFOG_LINEAR = 3, + D3DFOG_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DFOGMODE; + +typedef enum _D3DZBUFFERTYPE { + D3DZB_FALSE = 0, + D3DZB_TRUE = 1, // Z buffering + D3DZB_USEW = 2, // W buffering + D3DZB_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DZBUFFERTYPE; + +// Primitives supported by draw-primitive API +typedef enum _D3DPRIMITIVETYPE { + D3DPT_POINTLIST = 1, + D3DPT_LINELIST = 2, + D3DPT_LINESTRIP = 3, + D3DPT_TRIANGLELIST = 4, + D3DPT_TRIANGLESTRIP = 5, + D3DPT_TRIANGLEFAN = 6, + D3DPT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DPRIMITIVETYPE; + +typedef enum _D3DTRANSFORMSTATETYPE { + D3DTS_VIEW = 2, + D3DTS_PROJECTION = 3, + D3DTS_TEXTURE0 = 16, + D3DTS_TEXTURE1 = 17, + D3DTS_TEXTURE2 = 18, + D3DTS_TEXTURE3 = 19, + D3DTS_TEXTURE4 = 20, + D3DTS_TEXTURE5 = 21, + D3DTS_TEXTURE6 = 22, + D3DTS_TEXTURE7 = 23, + D3DTS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTRANSFORMSTATETYPE; + +#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256) +#define D3DTS_WORLD D3DTS_WORLDMATRIX(0) +#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1) +#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2) +#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3) + +typedef enum _D3DRENDERSTATETYPE { + D3DRS_ZENABLE = 7, /* D3DZBUFFERTYPE (or TRUE/FALSE for legacy) */ + D3DRS_FILLMODE = 8, /* D3DFILL_MODE */ + D3DRS_SHADEMODE = 9, /* D3DSHADEMODE */ + D3DRS_LINEPATTERN = 10, /* D3DLINEPATTERN */ + D3DRS_ZWRITEENABLE = 14, /* TRUE to enable z writes */ + D3DRS_ALPHATESTENABLE = 15, /* TRUE to enable alpha tests */ + D3DRS_LASTPIXEL = 16, /* TRUE for last-pixel on lines */ + D3DRS_SRCBLEND = 19, /* D3DBLEND */ + D3DRS_DESTBLEND = 20, /* D3DBLEND */ + D3DRS_CULLMODE = 22, /* D3DCULL */ + D3DRS_ZFUNC = 23, /* D3DCMPFUNC */ + D3DRS_ALPHAREF = 24, /* D3DFIXED */ + D3DRS_ALPHAFUNC = 25, /* D3DCMPFUNC */ + D3DRS_DITHERENABLE = 26, /* TRUE to enable dithering */ + D3DRS_ALPHABLENDENABLE = 27, /* TRUE to enable alpha blending */ + D3DRS_FOGENABLE = 28, /* TRUE to enable fog blending */ + D3DRS_SPECULARENABLE = 29, /* TRUE to enable specular */ + D3DRS_ZVISIBLE = 30, /* TRUE to enable z checking */ + D3DRS_FOGCOLOR = 34, /* D3DCOLOR */ + D3DRS_FOGTABLEMODE = 35, /* D3DFOGMODE */ + D3DRS_FOGSTART = 36, /* Fog start (for both vertex and pixel fog) */ + D3DRS_FOGEND = 37, /* Fog end */ + D3DRS_FOGDENSITY = 38, /* Fog density */ + D3DRS_EDGEANTIALIAS = 40, /* TRUE to enable edge antialiasing */ + D3DRS_ZBIAS = 47, /* LONG Z bias */ + D3DRS_RANGEFOGENABLE = 48, /* Enables range-based fog */ + D3DRS_STENCILENABLE = 52, /* BOOL enable/disable stenciling */ + D3DRS_STENCILFAIL = 53, /* D3DSTENCILOP to do if stencil test fails */ + D3DRS_STENCILZFAIL = 54, /* D3DSTENCILOP to do if stencil test passes and Z test fails */ + D3DRS_STENCILPASS = 55, /* D3DSTENCILOP to do if both stencil and Z tests pass */ + D3DRS_STENCILFUNC = 56, /* D3DCMPFUNC fn. Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */ + D3DRS_STENCILREF = 57, /* Reference value used in stencil test */ + D3DRS_STENCILMASK = 58, /* Mask value used in stencil test */ + D3DRS_STENCILWRITEMASK = 59, /* Write mask applied to values written to stencil buffer */ + D3DRS_TEXTUREFACTOR = 60, /* D3DCOLOR used for multi-texture blend */ + D3DRS_WRAP0 = 128, /* wrap for 1st texture coord. set */ + D3DRS_WRAP1 = 129, /* wrap for 2nd texture coord. set */ + D3DRS_WRAP2 = 130, /* wrap for 3rd texture coord. set */ + D3DRS_WRAP3 = 131, /* wrap for 4th texture coord. set */ + D3DRS_WRAP4 = 132, /* wrap for 5th texture coord. set */ + D3DRS_WRAP5 = 133, /* wrap for 6th texture coord. set */ + D3DRS_WRAP6 = 134, /* wrap for 7th texture coord. set */ + D3DRS_WRAP7 = 135, /* wrap for 8th texture coord. set */ + D3DRS_CLIPPING = 136, + D3DRS_LIGHTING = 137, + D3DRS_AMBIENT = 139, + D3DRS_FOGVERTEXMODE = 140, + D3DRS_COLORVERTEX = 141, + D3DRS_LOCALVIEWER = 142, + D3DRS_NORMALIZENORMALS = 143, + D3DRS_DIFFUSEMATERIALSOURCE = 145, + D3DRS_SPECULARMATERIALSOURCE = 146, + D3DRS_AMBIENTMATERIALSOURCE = 147, + D3DRS_EMISSIVEMATERIALSOURCE = 148, + D3DRS_VERTEXBLEND = 151, + D3DRS_CLIPPLANEENABLE = 152, + D3DRS_SOFTWAREVERTEXPROCESSING = 153, + D3DRS_POINTSIZE = 154, /* float point size */ + D3DRS_POINTSIZE_MIN = 155, /* float point size min threshold */ + D3DRS_POINTSPRITEENABLE = 156, /* BOOL point texture coord control */ + D3DRS_POINTSCALEENABLE = 157, /* BOOL point size scale enable */ + D3DRS_POINTSCALE_A = 158, /* float point attenuation A value */ + D3DRS_POINTSCALE_B = 159, /* float point attenuation B value */ + D3DRS_POINTSCALE_C = 160, /* float point attenuation C value */ + D3DRS_MULTISAMPLEANTIALIAS = 161, // BOOL - set to do FSAA with multisample buffer + D3DRS_MULTISAMPLEMASK = 162, // DWORD - per-sample enable/disable + D3DRS_PATCHEDGESTYLE = 163, // Sets whether patch edges will use float style tessellation + D3DRS_PATCHSEGMENTS = 164, // Number of segments per edge when drawing patches + D3DRS_DEBUGMONITORTOKEN = 165, // DEBUG ONLY - token to debug monitor + D3DRS_POINTSIZE_MAX = 166, /* float point size max threshold */ + D3DRS_INDEXEDVERTEXBLENDENABLE = 167, + D3DRS_COLORWRITEENABLE = 168, // per-channel write enable + D3DRS_TWEENFACTOR = 170, // float tween factor + D3DRS_BLENDOP = 171, // D3DBLENDOP setting + + D3DRS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DRENDERSTATETYPE; + +// Values for material source +typedef enum _D3DMATERIALCOLORSOURCE +{ + D3DMCS_MATERIAL = 0, // Color from material is used + D3DMCS_COLOR1 = 1, // Diffuse vertex color is used + D3DMCS_COLOR2 = 2, // Specular vertex color is used + D3DMCS_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DMATERIALCOLORSOURCE; + +// Bias to apply to the texture coordinate set to apply a wrap to. +#define D3DRENDERSTATE_WRAPBIAS 128UL + +/* Flags to construct the WRAP render states */ +#define D3DWRAP_U 0x00000001L +#define D3DWRAP_V 0x00000002L +#define D3DWRAP_W 0x00000004L + +/* Flags to construct the WRAP render states for 1D thru 4D texture coordinates */ +#define D3DWRAPCOORD_0 0x00000001L // same as D3DWRAP_U +#define D3DWRAPCOORD_1 0x00000002L // same as D3DWRAP_V +#define D3DWRAPCOORD_2 0x00000004L // same as D3DWRAP_W +#define D3DWRAPCOORD_3 0x00000008L + +/* Flags to construct D3DRS_COLORWRITEENABLE */ +#define D3DCOLORWRITEENABLE_RED (1L<<0) +#define D3DCOLORWRITEENABLE_GREEN (1L<<1) +#define D3DCOLORWRITEENABLE_BLUE (1L<<2) +#define D3DCOLORWRITEENABLE_ALPHA (1L<<3) + +/* + * State enumerants for per-stage texture processing. + */ +typedef enum _D3DTEXTURESTAGESTATETYPE +{ + D3DTSS_COLOROP = 1, /* D3DTEXTUREOP - per-stage blending controls for color channels */ + D3DTSS_COLORARG1 = 2, /* D3DTA_* (texture arg) */ + D3DTSS_COLORARG2 = 3, /* D3DTA_* (texture arg) */ + D3DTSS_ALPHAOP = 4, /* D3DTEXTUREOP - per-stage blending controls for alpha channel */ + D3DTSS_ALPHAARG1 = 5, /* D3DTA_* (texture arg) */ + D3DTSS_ALPHAARG2 = 6, /* D3DTA_* (texture arg) */ + D3DTSS_BUMPENVMAT00 = 7, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT01 = 8, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT10 = 9, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT11 = 10, /* float (bump mapping matrix) */ + D3DTSS_TEXCOORDINDEX = 11, /* identifies which set of texture coordinates index this texture */ + D3DTSS_ADDRESSU = 13, /* D3DTEXTUREADDRESS for U coordinate */ + D3DTSS_ADDRESSV = 14, /* D3DTEXTUREADDRESS for V coordinate */ + D3DTSS_BORDERCOLOR = 15, /* D3DCOLOR */ + D3DTSS_MAGFILTER = 16, /* D3DTEXTUREFILTER filter to use for magnification */ + D3DTSS_MINFILTER = 17, /* D3DTEXTUREFILTER filter to use for minification */ + D3DTSS_MIPFILTER = 18, /* D3DTEXTUREFILTER filter to use between mipmaps during minification */ + D3DTSS_MIPMAPLODBIAS = 19, /* float Mipmap LOD bias */ + D3DTSS_MAXMIPLEVEL = 20, /* DWORD 0..(n-1) LOD index of largest map to use (0 == largest) */ + D3DTSS_MAXANISOTROPY = 21, /* DWORD maximum anisotropy */ + D3DTSS_BUMPENVLSCALE = 22, /* float scale for bump map luminance */ + D3DTSS_BUMPENVLOFFSET = 23, /* float offset for bump map luminance */ + D3DTSS_TEXTURETRANSFORMFLAGS = 24, /* D3DTEXTURETRANSFORMFLAGS controls texture transform */ + D3DTSS_ADDRESSW = 25, /* D3DTEXTUREADDRESS for W coordinate */ + D3DTSS_COLORARG0 = 26, /* D3DTA_* third arg for triadic ops */ + D3DTSS_ALPHAARG0 = 27, /* D3DTA_* third arg for triadic ops */ + D3DTSS_RESULTARG = 28, /* D3DTA_* arg for result (CURRENT or TEMP) */ + D3DTSS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTEXTURESTAGESTATETYPE; + +// Values, used with D3DTSS_TEXCOORDINDEX, to specify that the vertex data(position +// and normal in the camera space) should be taken as texture coordinates +// Low 16 bits are used to specify texture coordinate index, to take the WRAP mode from +// +#define D3DTSS_TCI_PASSTHRU 0x00000000 +#define D3DTSS_TCI_CAMERASPACENORMAL 0x00010000 +#define D3DTSS_TCI_CAMERASPACEPOSITION 0x00020000 +#define D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR 0x00030000 + +/* + * Enumerations for COLOROP and ALPHAOP texture blending operations set in + * texture processing stage controls in D3DRENDERSTATE. + */ +typedef enum _D3DTEXTUREOP +{ + // Control + D3DTOP_DISABLE = 1, // disables stage + D3DTOP_SELECTARG1 = 2, // the default + D3DTOP_SELECTARG2 = 3, + + // Modulate + D3DTOP_MODULATE = 4, // multiply args together + D3DTOP_MODULATE2X = 5, // multiply and 1 bit + D3DTOP_MODULATE4X = 6, // multiply and 2 bits + + // Add + D3DTOP_ADD = 7, // add arguments together + D3DTOP_ADDSIGNED = 8, // add with -0.5 bias + D3DTOP_ADDSIGNED2X = 9, // as above but left 1 bit + D3DTOP_SUBTRACT = 10, // Arg1 - Arg2, with no saturation + D3DTOP_ADDSMOOTH = 11, // add 2 args, subtract product + // Arg1 + Arg2 - Arg1*Arg2 + // = Arg1 + (1-Arg1)*Arg2 + + // Linear alpha blend: Arg1*(Alpha) + Arg2*(1-Alpha) + D3DTOP_BLENDDIFFUSEALPHA = 12, // iterated alpha + D3DTOP_BLENDTEXTUREALPHA = 13, // texture alpha + D3DTOP_BLENDFACTORALPHA = 14, // alpha from D3DRENDERSTATE_TEXTUREFACTOR + + // Linear alpha blend with pre-multiplied arg1 input: Arg1 + Arg2*(1-Alpha) + D3DTOP_BLENDTEXTUREALPHAPM = 15, // texture alpha + D3DTOP_BLENDCURRENTALPHA = 16, // by alpha of current color + + // Specular mapping + D3DTOP_PREMODULATE = 17, // modulate with next texture before use + D3DTOP_MODULATEALPHA_ADDCOLOR = 18, // Arg1.RGB + Arg1.A*Arg2.RGB + // COLOROP only + D3DTOP_MODULATECOLOR_ADDALPHA = 19, // Arg1.RGB*Arg2.RGB + Arg1.A + // COLOROP only + D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, // (1-Arg1.A)*Arg2.RGB + Arg1.RGB + // COLOROP only + D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, // (1-Arg1.RGB)*Arg2.RGB + Arg1.A + // COLOROP only + + // Bump mapping + D3DTOP_BUMPENVMAP = 22, // per pixel env map perturbation + D3DTOP_BUMPENVMAPLUMINANCE = 23, // with luminance channel + + // This can do either diffuse or specular bump mapping with correct input. + // Performs the function (Arg1.R*Arg2.R + Arg1.G*Arg2.G + Arg1.B*Arg2.B) + // where each component has been scaled and offset to make it signed. + // The result is replicated into all four (including alpha) channels. + // This is a valid COLOROP only. + D3DTOP_DOTPRODUCT3 = 24, + + // Triadic ops + D3DTOP_MULTIPLYADD = 25, // Arg0 + Arg1*Arg2 + D3DTOP_LERP = 26, // (Arg0)*Arg1 + (1-Arg0)*Arg2 + + D3DTOP_FORCE_DWORD = 0x7fffffff, +} D3DTEXTUREOP; + +/* + * Values for COLORARG0,1,2, ALPHAARG0,1,2, and RESULTARG texture blending + * operations set in texture processing stage controls in D3DRENDERSTATE. + */ +#define D3DTA_SELECTMASK 0x0000000f // mask for arg selector +#define D3DTA_DIFFUSE 0x00000000 // select diffuse color (read only) +#define D3DTA_CURRENT 0x00000001 // select stage destination register (read/write) +#define D3DTA_TEXTURE 0x00000002 // select texture color (read only) +#define D3DTA_TFACTOR 0x00000003 // select RENDERSTATE_TEXTUREFACTOR (read only) +#define D3DTA_SPECULAR 0x00000004 // select specular color (read only) +#define D3DTA_TEMP 0x00000005 // select temporary register color (read/write) +#define D3DTA_COMPLEMENT 0x00000010 // take 1.0 - x (read modifier) +#define D3DTA_ALPHAREPLICATE 0x00000020 // replicate alpha to color components (read modifier) + +// +// Values for D3DTSS_***FILTER texture stage states +// +typedef enum _D3DTEXTUREFILTERTYPE +{ + D3DTEXF_NONE = 0, // filtering disabled (valid for mip filter only) + D3DTEXF_POINT = 1, // nearest + D3DTEXF_LINEAR = 2, // linear interpolation + D3DTEXF_ANISOTROPIC = 3, // anisotropic + D3DTEXF_FLATCUBIC = 4, // cubic + D3DTEXF_GAUSSIANCUBIC = 5, // different cubic kernel + D3DTEXF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DTEXTUREFILTERTYPE; + +/* Bits for Flags in ProcessVertices call */ + +#define D3DPV_DONOTCOPYDATA (1 << 0) + +//------------------------------------------------------------------- + +// Flexible vertex format bits +// +#define D3DFVF_RESERVED0 0x001 +#define D3DFVF_POSITION_MASK 0x00E +#define D3DFVF_XYZ 0x002 +#define D3DFVF_XYZRHW 0x004 +#define D3DFVF_XYZB1 0x006 +#define D3DFVF_XYZB2 0x008 +#define D3DFVF_XYZB3 0x00a +#define D3DFVF_XYZB4 0x00c +#define D3DFVF_XYZB5 0x00e + +#define D3DFVF_NORMAL 0x010 +#define D3DFVF_PSIZE 0x020 +#define D3DFVF_DIFFUSE 0x040 +#define D3DFVF_SPECULAR 0x080 + +#define D3DFVF_TEXCOUNT_MASK 0xf00 +#define D3DFVF_TEXCOUNT_SHIFT 8 +#define D3DFVF_TEX0 0x000 +#define D3DFVF_TEX1 0x100 +#define D3DFVF_TEX2 0x200 +#define D3DFVF_TEX3 0x300 +#define D3DFVF_TEX4 0x400 +#define D3DFVF_TEX5 0x500 +#define D3DFVF_TEX6 0x600 +#define D3DFVF_TEX7 0x700 +#define D3DFVF_TEX8 0x800 + +#define D3DFVF_LASTBETA_UBYTE4 0x1000 + +#define D3DFVF_RESERVED2 0xE000 // 4 reserved bits + +//--------------------------------------------------------------------- +// Vertex Shaders +// + +/* + +Vertex Shader Declaration + +The declaration portion of a vertex shader defines the static external +interface of the shader. The information in the declaration includes: + +- Assignments of vertex shader input registers to data streams. These +assignments bind a specific vertex register to a single component within a +vertex stream. A vertex stream element is identified by a byte offset +within the stream and a type. The type specifies the arithmetic data type +plus the dimensionality (1, 2, 3, or 4 values). Stream data which is +less than 4 values are always expanded out to 4 values with zero or more +0.F values and one 1.F value. + +- Assignment of vertex shader input registers to implicit data from the +primitive tessellator. This controls the loading of vertex data which is +not loaded from a stream, but rather is generated during primitive +tessellation prior to the vertex shader. + +- Loading data into the constant memory at the time a shader is set as the +current shader. Each token specifies values for one or more contiguous 4 +DWORD constant registers. This allows the shader to update an arbitrary +subset of the constant memory, overwriting the device state (which +contains the current values of the constant memory). Note that these +values can be subsequently overwritten (between DrawPrimitive calls) +during the time a shader is bound to a device via the +SetVertexShaderConstant method. + + +Declaration arrays are single-dimensional arrays of DWORDs composed of +multiple tokens each of which is one or more DWORDs. The single-DWORD +token value 0xFFFFFFFF is a special token used to indicate the end of the +declaration array. The single DWORD token value 0x00000000 is a NOP token +with is ignored during the declaration parsing. Note that 0x00000000 is a +valid value for DWORDs following the first DWORD for multiple word tokens. + +[31:29] TokenType + 0x0 - NOP (requires all DWORD bits to be zero) + 0x1 - stream selector + 0x2 - stream data definition (map to vertex input memory) + 0x3 - vertex input memory from tessellator + 0x4 - constant memory from shader + 0x5 - extension + 0x6 - reserved + 0x7 - end-of-array (requires all DWORD bits to be 1) + +NOP Token (single DWORD token) + [31:29] 0x0 + [28:00] 0x0 + +Stream Selector (single DWORD token) + [31:29] 0x1 + [28] indicates whether this is a tessellator stream + [27:04] 0x0 + [03:00] stream selector (0..15) + +Stream Data Definition (single DWORD token) + Vertex Input Register Load + [31:29] 0x2 + [28] 0x0 + [27:20] 0x0 + [19:16] type (dimensionality and data type) + [15:04] 0x0 + [03:00] vertex register address (0..15) + Data Skip (no register load) + [31:29] 0x2 + [28] 0x1 + [27:20] 0x0 + [19:16] count of DWORDS to skip over (0..15) + [15:00] 0x0 + Vertex Input Memory from Tessellator Data (single DWORD token) + [31:29] 0x3 + [28] indicates whether data is normals or u/v + [27:24] 0x0 + [23:20] vertex register address (0..15) + [19:16] type (dimensionality) + [15:04] 0x0 + [03:00] vertex register address (0..15) + +Constant Memory from Shader (multiple DWORD token) + [31:29] 0x4 + [28:25] count of 4*DWORD constants to load (0..15) + [24:07] 0x0 + [06:00] constant memory address (0..95) + +Extension Token (single or multiple DWORD token) + [31:29] 0x5 + [28:24] count of additional DWORDs in token (0..31) + [23:00] extension-specific information + +End-of-array token (single DWORD token) + [31:29] 0x7 + [28:00] 0x1fffffff + +The stream selector token must be immediately followed by a contiguous set of stream data definition tokens. This token sequence fully defines that stream, including the set of elements within the stream, the order in which the elements appear, the type of each element, and the vertex register into which to load an element. +Streams are allowed to include data which is not loaded into a vertex register, thus allowing data which is not used for this shader to exist in the vertex stream. This skipped data is defined only by a count of DWORDs to skip over, since the type information is irrelevant. +The token sequence: +Stream Select: stream=0 +Stream Data Definition (Load): type=FLOAT3; register=3 +Stream Data Definition (Load): type=FLOAT3; register=4 +Stream Data Definition (Skip): count=2 +Stream Data Definition (Load): type=FLOAT2; register=7 + +defines stream zero to consist of 4 elements, 3 of which are loaded into registers and the fourth skipped over. Register 3 is loaded with the first three DWORDs in each vertex interpreted as FLOAT data. Register 4 is loaded with the 4th, 5th, and 6th DWORDs interpreted as FLOAT data. The next two DWORDs (7th and 8th) are skipped over and not loaded into any vertex input register. Register 7 is loaded with the 9th and 10th DWORDS interpreted as FLOAT data. +Placing of tokens other than NOPs between the Stream Selector and Stream Data Definition tokens is disallowed. + +*/ + +typedef enum _D3DVSD_TOKENTYPE +{ + D3DVSD_TOKEN_NOP = 0, // NOP or extension + D3DVSD_TOKEN_STREAM, // stream selector + D3DVSD_TOKEN_STREAMDATA, // stream data definition (map to vertex input memory) + D3DVSD_TOKEN_TESSELLATOR, // vertex input memory from tessellator + D3DVSD_TOKEN_CONSTMEM, // constant memory from shader + D3DVSD_TOKEN_EXT, // extension + D3DVSD_TOKEN_END = 7, // end-of-array (requires all DWORD bits to be 1) + D3DVSD_FORCE_DWORD = 0x7fffffff,// force 32-bit size enum +} D3DVSD_TOKENTYPE; + +#define D3DVSD_TOKENTYPESHIFT 29 +#define D3DVSD_TOKENTYPEMASK (7 << D3DVSD_TOKENTYPESHIFT) + +#define D3DVSD_STREAMNUMBERSHIFT 0 +#define D3DVSD_STREAMNUMBERMASK (0xF << D3DVSD_STREAMNUMBERSHIFT) + +#define D3DVSD_DATALOADTYPESHIFT 28 +#define D3DVSD_DATALOADTYPEMASK (0x1 << D3DVSD_DATALOADTYPESHIFT) + +#define D3DVSD_DATATYPESHIFT 16 +#define D3DVSD_DATATYPEMASK (0xF << D3DVSD_DATATYPESHIFT) + +#define D3DVSD_SKIPCOUNTSHIFT 16 +#define D3DVSD_SKIPCOUNTMASK (0xF << D3DVSD_SKIPCOUNTSHIFT) + +#define D3DVSD_VERTEXREGSHIFT 0 +#define D3DVSD_VERTEXREGMASK (0x1F << D3DVSD_VERTEXREGSHIFT) + +#define D3DVSD_VERTEXREGINSHIFT 20 +#define D3DVSD_VERTEXREGINMASK (0xF << D3DVSD_VERTEXREGINSHIFT) + +#define D3DVSD_CONSTCOUNTSHIFT 25 +#define D3DVSD_CONSTCOUNTMASK (0xF << D3DVSD_CONSTCOUNTSHIFT) + +#define D3DVSD_CONSTADDRESSSHIFT 0 +#define D3DVSD_CONSTADDRESSMASK (0x7F << D3DVSD_CONSTADDRESSSHIFT) + +#define D3DVSD_CONSTRSSHIFT 16 +#define D3DVSD_CONSTRSMASK (0x1FFF << D3DVSD_CONSTRSSHIFT) + +#define D3DVSD_EXTCOUNTSHIFT 24 +#define D3DVSD_EXTCOUNTMASK (0x1F << D3DVSD_EXTCOUNTSHIFT) + +#define D3DVSD_EXTINFOSHIFT 0 +#define D3DVSD_EXTINFOMASK (0xFFFFFF << D3DVSD_EXTINFOSHIFT) + +#define D3DVSD_MAKETOKENTYPE(tokenType) ((tokenType << D3DVSD_TOKENTYPESHIFT) & D3DVSD_TOKENTYPEMASK) + +// macros for generation of CreateVertexShader Declaration token array + +// Set current stream +// _StreamNumber [0..(MaxStreams-1)] stream to get data from +// +#define D3DVSD_STREAM( _StreamNumber ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAM) | (_StreamNumber)) + +// Set tessellator stream +// +#define D3DVSD_STREAMTESSSHIFT 28 +#define D3DVSD_STREAMTESSMASK (1 << D3DVSD_STREAMTESSSHIFT) +#define D3DVSD_STREAM_TESS( ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAM) | (D3DVSD_STREAMTESSMASK)) + +// bind single vertex register to vertex element from vertex stream +// +// _VertexRegister [0..15] address of the vertex register +// _Type [D3DVSDT_*] dimensionality and arithmetic data type + +#define D3DVSD_REG( _VertexRegister, _Type ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAMDATA) | \ + ((_Type) << D3DVSD_DATATYPESHIFT) | (_VertexRegister)) + +// Skip _DWORDCount DWORDs in vertex +// +#define D3DVSD_SKIP( _DWORDCount ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAMDATA) | 0x10000000 | \ + ((_DWORDCount) << D3DVSD_SKIPCOUNTSHIFT)) + +// load data into vertex shader constant memory +// +// _ConstantAddress [0..95] - address of constant array to begin filling data +// _Count [0..15] - number of constant vectors to load (4 DWORDs each) +// followed by 4*_Count DWORDS of data +// +#define D3DVSD_CONST( _ConstantAddress, _Count ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_CONSTMEM) | \ + ((_Count) << D3DVSD_CONSTCOUNTSHIFT) | (_ConstantAddress)) + +// enable tessellator generated normals +// +// _VertexRegisterIn [0..15] address of vertex register whose input stream +// will be used in normal computation +// _VertexRegisterOut [0..15] address of vertex register to output the normal to +// +#define D3DVSD_TESSNORMAL( _VertexRegisterIn, _VertexRegisterOut ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_TESSELLATOR) | \ + ((_VertexRegisterIn) << D3DVSD_VERTEXREGINSHIFT) | \ + ((0x02) << D3DVSD_DATATYPESHIFT) | (_VertexRegisterOut)) + +// enable tessellator generated surface parameters +// +// _VertexRegister [0..15] address of vertex register to output parameters +// +#define D3DVSD_TESSUV( _VertexRegister ) \ + (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_TESSELLATOR) | 0x10000000 | \ + ((0x01) << D3DVSD_DATATYPESHIFT) | (_VertexRegister)) + +// Generates END token +// +#define D3DVSD_END() 0xFFFFFFFF + +// Generates NOP token +#define D3DVSD_NOP() 0x00000000 + +// bit declarations for _Type fields +#define D3DVSDT_FLOAT1 0x00 // 1D float expanded to (value, 0., 0., 1.) +#define D3DVSDT_FLOAT2 0x01 // 2D float expanded to (value, value, 0., 1.) +#define D3DVSDT_FLOAT3 0x02 // 3D float expanded to (value, value, value, 1.) +#define D3DVSDT_FLOAT4 0x03 // 4D float +#define D3DVSDT_D3DCOLOR 0x04 // 4D packed unsigned bytes mapped to 0. to 1. range + // Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A) +#define D3DVSDT_UBYTE4 0x05 // 4D unsigned byte +#define D3DVSDT_SHORT2 0x06 // 2D signed short expanded to (value, value, 0., 1.) +#define D3DVSDT_SHORT4 0x07 // 4D signed short + +// assignments of vertex input registers for fixed function vertex shader +// +#define D3DVSDE_POSITION 0 +#define D3DVSDE_BLENDWEIGHT 1 +#define D3DVSDE_BLENDINDICES 2 +#define D3DVSDE_NORMAL 3 +#define D3DVSDE_PSIZE 4 +#define D3DVSDE_DIFFUSE 5 +#define D3DVSDE_SPECULAR 6 +#define D3DVSDE_TEXCOORD0 7 +#define D3DVSDE_TEXCOORD1 8 +#define D3DVSDE_TEXCOORD2 9 +#define D3DVSDE_TEXCOORD3 10 +#define D3DVSDE_TEXCOORD4 11 +#define D3DVSDE_TEXCOORD5 12 +#define D3DVSDE_TEXCOORD6 13 +#define D3DVSDE_TEXCOORD7 14 +#define D3DVSDE_POSITION2 15 +#define D3DVSDE_NORMAL2 16 + +// Maximum supported number of texture coordinate sets +#define D3DDP_MAXTEXCOORD 8 + + +// +// Instruction Token Bit Definitions +// +#define D3DSI_OPCODE_MASK 0x0000FFFF + +typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE +{ + D3DSIO_NOP = 0, // PS/VS + D3DSIO_MOV , // PS/VS + D3DSIO_ADD , // PS/VS + D3DSIO_SUB , // PS + D3DSIO_MAD , // PS/VS + D3DSIO_MUL , // PS/VS + D3DSIO_RCP , // VS + D3DSIO_RSQ , // VS + D3DSIO_DP3 , // PS/VS + D3DSIO_DP4 , // PS/VS + D3DSIO_MIN , // VS + D3DSIO_MAX , // VS + D3DSIO_SLT , // VS + D3DSIO_SGE , // VS + D3DSIO_EXP , // VS + D3DSIO_LOG , // VS + D3DSIO_LIT , // VS + D3DSIO_DST , // VS + D3DSIO_LRP , // PS + D3DSIO_FRC , // VS + D3DSIO_M4x4 , // VS + D3DSIO_M4x3 , // VS + D3DSIO_M3x4 , // VS + D3DSIO_M3x3 , // VS + D3DSIO_M3x2 , // VS + + D3DSIO_TEXCOORD = 64, // PS + D3DSIO_TEXKILL , // PS + D3DSIO_TEX , // PS + D3DSIO_TEXBEM , // PS + D3DSIO_TEXBEML , // PS + D3DSIO_TEXREG2AR , // PS + D3DSIO_TEXREG2GB , // PS + D3DSIO_TEXM3x2PAD , // PS + D3DSIO_TEXM3x2TEX , // PS + D3DSIO_TEXM3x3PAD , // PS + D3DSIO_TEXM3x3TEX , // PS + D3DSIO_TEXM3x3DIFF , // PS + D3DSIO_TEXM3x3SPEC , // PS + D3DSIO_TEXM3x3VSPEC , // PS + D3DSIO_EXPP , // VS + D3DSIO_LOGP , // VS + D3DSIO_CND , // PS + D3DSIO_DEF , // PS + D3DSIO_COMMENT = 0xFFFE, + D3DSIO_END = 0xFFFF, + + D3DSIO_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DSHADER_INSTRUCTION_OPCODE_TYPE; + +// +// Co-Issue Instruction Modifier - if set then this instruction is to be +// issued in parallel with the previous instruction(s) for which this bit +// is not set. +// +#define D3DSI_COISSUE 0x40000000 + +// +// Parameter Token Bit Definitions +// +#define D3DSP_REGNUM_MASK 0x00000FFF + +// destination parameter write mask +#define D3DSP_WRITEMASK_0 0x00010000 // Component 0 (X;Red) +#define D3DSP_WRITEMASK_1 0x00020000 // Component 1 (Y;Green) +#define D3DSP_WRITEMASK_2 0x00040000 // Component 2 (Z;Blue) +#define D3DSP_WRITEMASK_3 0x00080000 // Component 3 (W;Alpha) +#define D3DSP_WRITEMASK_ALL 0x000F0000 // All Components + +// destination parameter modifiers +#define D3DSP_DSTMOD_SHIFT 20 +#define D3DSP_DSTMOD_MASK 0x00F00000 + +typedef enum _D3DSHADER_PARAM_DSTMOD_TYPE +{ + D3DSPDM_NONE = 0<<D3DSP_DSTMOD_SHIFT, // nop + D3DSPDM_SATURATE= 1<<D3DSP_DSTMOD_SHIFT, // clamp to 0. to 1. range + D3DSPDM_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DSHADER_PARAM_DSTMOD_TYPE; + +// destination parameter +#define D3DSP_DSTSHIFT_SHIFT 24 +#define D3DSP_DSTSHIFT_MASK 0x0F000000 + +// destination/source parameter register type +#define D3DSP_REGTYPE_SHIFT 28 +#define D3DSP_REGTYPE_MASK 0x70000000 + +typedef enum _D3DSHADER_PARAM_REGISTER_TYPE +{ + D3DSPR_TEMP = 0<<D3DSP_REGTYPE_SHIFT, // Temporary Register File + D3DSPR_INPUT = 1<<D3DSP_REGTYPE_SHIFT, // Input Register File + D3DSPR_CONST = 2<<D3DSP_REGTYPE_SHIFT, // Constant Register File + D3DSPR_ADDR = 3<<D3DSP_REGTYPE_SHIFT, // Address Register (VS) + D3DSPR_TEXTURE = 3<<D3DSP_REGTYPE_SHIFT, // Texture Register File (PS) + D3DSPR_RASTOUT = 4<<D3DSP_REGTYPE_SHIFT, // Rasterizer Register File + D3DSPR_ATTROUT = 5<<D3DSP_REGTYPE_SHIFT, // Attribute Output Register File + D3DSPR_TEXCRDOUT= 6<<D3DSP_REGTYPE_SHIFT, // Texture Coordinate Output Register File + D3DSPR_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DSHADER_PARAM_REGISTER_TYPE; + +// Register offsets in the Rasterizer Register File +// +typedef enum _D3DVS_RASTOUT_OFFSETS +{ + D3DSRO_POSITION = 0, + D3DSRO_FOG, + D3DSRO_POINT_SIZE, + D3DSRO_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DVS_RASTOUT_OFFSETS; + +// Source operand addressing modes + +#define D3DVS_ADDRESSMODE_SHIFT 13 +#define D3DVS_ADDRESSMODE_MASK (1 << D3DVS_ADDRESSMODE_SHIFT) + +typedef enum _D3DVS_ADDRESSMODE_TYPE +{ + D3DVS_ADDRMODE_ABSOLUTE = (0 << D3DVS_ADDRESSMODE_SHIFT), + D3DVS_ADDRMODE_RELATIVE = (1 << D3DVS_ADDRESSMODE_SHIFT), // Relative to register A0 + D3DVS_ADDRMODE_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DVS_ADDRESSMODE_TYPE; + +// Source operand swizzle definitions +// +#define D3DVS_SWIZZLE_SHIFT 16 +#define D3DVS_SWIZZLE_MASK 0x00FF0000 + +// The following bits define where to take component X: + +#define D3DVS_X_X (0 << D3DVS_SWIZZLE_SHIFT) +#define D3DVS_X_Y (1 << D3DVS_SWIZZLE_SHIFT) +#define D3DVS_X_Z (2 << D3DVS_SWIZZLE_SHIFT) +#define D3DVS_X_W (3 << D3DVS_SWIZZLE_SHIFT) + +// The following bits define where to take component Y: + +#define D3DVS_Y_X (0 << (D3DVS_SWIZZLE_SHIFT + 2)) +#define D3DVS_Y_Y (1 << (D3DVS_SWIZZLE_SHIFT + 2)) +#define D3DVS_Y_Z (2 << (D3DVS_SWIZZLE_SHIFT + 2)) +#define D3DVS_Y_W (3 << (D3DVS_SWIZZLE_SHIFT + 2)) + +// The following bits define where to take component Z: + +#define D3DVS_Z_X (0 << (D3DVS_SWIZZLE_SHIFT + 4)) +#define D3DVS_Z_Y (1 << (D3DVS_SWIZZLE_SHIFT + 4)) +#define D3DVS_Z_Z (2 << (D3DVS_SWIZZLE_SHIFT + 4)) +#define D3DVS_Z_W (3 << (D3DVS_SWIZZLE_SHIFT + 4)) + +// The following bits define where to take component W: + +#define D3DVS_W_X (0 << (D3DVS_SWIZZLE_SHIFT + 6)) +#define D3DVS_W_Y (1 << (D3DVS_SWIZZLE_SHIFT + 6)) +#define D3DVS_W_Z (2 << (D3DVS_SWIZZLE_SHIFT + 6)) +#define D3DVS_W_W (3 << (D3DVS_SWIZZLE_SHIFT + 6)) + +// Value when there is no swizzle (X is taken from X, Y is taken from Y, +// Z is taken from Z, W is taken from W +// +#define D3DVS_NOSWIZZLE (D3DVS_X_X | D3DVS_Y_Y | D3DVS_Z_Z | D3DVS_W_W) + +// source parameter swizzle +#define D3DSP_SWIZZLE_SHIFT 16 +#define D3DSP_SWIZZLE_MASK 0x00FF0000 + +#define D3DSP_NOSWIZZLE \ + ( (0 << (D3DSP_SWIZZLE_SHIFT + 0)) | \ + (1 << (D3DSP_SWIZZLE_SHIFT + 2)) | \ + (2 << (D3DSP_SWIZZLE_SHIFT + 4)) | \ + (3 << (D3DSP_SWIZZLE_SHIFT + 6)) ) + +// pixel-shader swizzle ops +#define D3DSP_REPLICATEALPHA \ + ( (3 << (D3DSP_SWIZZLE_SHIFT + 0)) | \ + (3 << (D3DSP_SWIZZLE_SHIFT + 2)) | \ + (3 << (D3DSP_SWIZZLE_SHIFT + 4)) | \ + (3 << (D3DSP_SWIZZLE_SHIFT + 6)) ) + +// source parameter modifiers +#define D3DSP_SRCMOD_SHIFT 24 +#define D3DSP_SRCMOD_MASK 0x0F000000 + +typedef enum _D3DSHADER_PARAM_SRCMOD_TYPE +{ + D3DSPSM_NONE = 0<<D3DSP_SRCMOD_SHIFT, // nop + D3DSPSM_NEG = 1<<D3DSP_SRCMOD_SHIFT, // negate + D3DSPSM_BIAS = 2<<D3DSP_SRCMOD_SHIFT, // bias + D3DSPSM_BIASNEG = 3<<D3DSP_SRCMOD_SHIFT, // bias and negate + D3DSPSM_SIGN = 4<<D3DSP_SRCMOD_SHIFT, // sign + D3DSPSM_SIGNNEG = 5<<D3DSP_SRCMOD_SHIFT, // sign and negate + D3DSPSM_COMP = 6<<D3DSP_SRCMOD_SHIFT, // complement + D3DSPSM_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DSHADER_PARAM_SRCMOD_TYPE; + +// pixel shader version token +#define D3DPS_VERSION(_Major,_Minor) (0xFFFF0000|((_Major)<<8)|(_Minor)) + +// vertex shader version token +#define D3DVS_VERSION(_Major,_Minor) (0xFFFE0000|((_Major)<<8)|(_Minor)) + +// extract major/minor from version cap +#define D3DSHADER_VERSION_MAJOR(_Version) (((_Version)>>8)&0xFF) +#define D3DSHADER_VERSION_MINOR(_Version) (((_Version)>>0)&0xFF) + +// destination/source parameter register type +#define D3DSI_COMMENTSIZE_SHIFT 16 +#define D3DSI_COMMENTSIZE_MASK 0x7FFF0000 +#define D3DSHADER_COMMENT(_DWordSize) \ + ((((_DWordSize)<<D3DSI_COMMENTSIZE_SHIFT)&D3DSI_COMMENTSIZE_MASK)|D3DSIO_COMMENT) + +// pixel/vertex shader end token +#define D3DPS_END() 0x0000FFFF +#define D3DVS_END() 0x0000FFFF + +//--------------------------------------------------------------------- + +// High order surfaces +// +typedef enum _D3DBASISTYPE +{ + D3DBASIS_BEZIER = 0, + D3DBASIS_BSPLINE = 1, + D3DBASIS_INTERPOLATE = 2, + D3DBASIS_FORCE_DWORD = 0x7fffffff, +} D3DBASISTYPE; + +typedef enum _D3DORDERTYPE +{ + D3DORDER_LINEAR = 1, + D3DORDER_CUBIC = 3, + D3DORDER_QUINTIC = 5, + D3DORDER_FORCE_DWORD = 0x7fffffff, +} D3DORDERTYPE; + +typedef enum _D3DPATCHEDGESTYLE +{ + D3DPATCHEDGE_DISCRETE = 0, + D3DPATCHEDGE_CONTINUOUS = 1, + D3DPATCHEDGE_FORCE_DWORD = 0x7fffffff, +} D3DPATCHEDGESTYLE; + +typedef enum _D3DSTATEBLOCKTYPE +{ + D3DSBT_ALL = 1, // capture all state + D3DSBT_PIXELSTATE = 2, // capture pixel state + D3DSBT_VERTEXSTATE = 3, // capture vertex state + D3DSBT_FORCE_DWORD = 0x7fffffff, +} D3DSTATEBLOCKTYPE; + +// The D3DVERTEXBLENDFLAGS type is used with D3DRS_VERTEXBLEND state. +// +typedef enum _D3DVERTEXBLENDFLAGS +{ + D3DVBF_DISABLE = 0, // Disable vertex blending + D3DVBF_1WEIGHTS = 1, // 2 matrix blending + D3DVBF_2WEIGHTS = 2, // 3 matrix blending + D3DVBF_3WEIGHTS = 3, // 4 matrix blending + D3DVBF_TWEENING = 255, // blending using D3DRS_TWEENFACTOR + D3DVBF_0WEIGHTS = 256, // one matrix is used with weight 1.0 + D3DVBF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DVERTEXBLENDFLAGS; + +typedef enum _D3DTEXTURETRANSFORMFLAGS { + D3DTTFF_DISABLE = 0, // texture coordinates are passed directly + D3DTTFF_COUNT1 = 1, // rasterizer should expect 1-D texture coords + D3DTTFF_COUNT2 = 2, // rasterizer should expect 2-D texture coords + D3DTTFF_COUNT3 = 3, // rasterizer should expect 3-D texture coords + D3DTTFF_COUNT4 = 4, // rasterizer should expect 4-D texture coords + D3DTTFF_PROJECTED = 256, // texcoords to be divided by COUNTth element + D3DTTFF_FORCE_DWORD = 0x7fffffff, +} D3DTEXTURETRANSFORMFLAGS; + +// Macros to set texture coordinate format bits in the FVF id + +#define D3DFVF_TEXTUREFORMAT2 0 // Two floating point values +#define D3DFVF_TEXTUREFORMAT1 3 // One floating point value +#define D3DFVF_TEXTUREFORMAT3 1 // Three floating point values +#define D3DFVF_TEXTUREFORMAT4 2 // Four floating point values + +#define D3DFVF_TEXCOORDSIZE3(CoordIndex) (D3DFVF_TEXTUREFORMAT3 << (CoordIndex*2 + 16)) +#define D3DFVF_TEXCOORDSIZE2(CoordIndex) (D3DFVF_TEXTUREFORMAT2) +#define D3DFVF_TEXCOORDSIZE4(CoordIndex) (D3DFVF_TEXTUREFORMAT4 << (CoordIndex*2 + 16)) +#define D3DFVF_TEXCOORDSIZE1(CoordIndex) (D3DFVF_TEXTUREFORMAT1 << (CoordIndex*2 + 16)) + + +//--------------------------------------------------------------------- + +/* Direct3D8 Device types */ +typedef enum _D3DDEVTYPE +{ + D3DDEVTYPE_HAL = 1, + D3DDEVTYPE_REF = 2, + D3DDEVTYPE_SW = 3, + + D3DDEVTYPE_FORCE_DWORD = 0x7fffffff +} D3DDEVTYPE; + +/* Multi-Sample buffer types */ +typedef enum _D3DMULTISAMPLE_TYPE +{ + D3DMULTISAMPLE_NONE = 0, + D3DMULTISAMPLE_2_SAMPLES = 2, + D3DMULTISAMPLE_3_SAMPLES = 3, + D3DMULTISAMPLE_4_SAMPLES = 4, + D3DMULTISAMPLE_5_SAMPLES = 5, + D3DMULTISAMPLE_6_SAMPLES = 6, + D3DMULTISAMPLE_7_SAMPLES = 7, + D3DMULTISAMPLE_8_SAMPLES = 8, + D3DMULTISAMPLE_9_SAMPLES = 9, + D3DMULTISAMPLE_10_SAMPLES = 10, + D3DMULTISAMPLE_11_SAMPLES = 11, + D3DMULTISAMPLE_12_SAMPLES = 12, + D3DMULTISAMPLE_13_SAMPLES = 13, + D3DMULTISAMPLE_14_SAMPLES = 14, + D3DMULTISAMPLE_15_SAMPLES = 15, + D3DMULTISAMPLE_16_SAMPLES = 16, + + D3DMULTISAMPLE_FORCE_DWORD = 0x7fffffff +} D3DMULTISAMPLE_TYPE; + +/* Formats + * Most of these names have the following convention: + * A = Alpha + * R = Red + * G = Green + * B = Blue + * X = Unused Bits + * P = Palette + * L = Luminance + * U = dU coordinate for BumpMap + * V = dV coordinate for BumpMap + * S = Stencil + * D = Depth (e.g. Z or W buffer) + * + * Further, the order of the pieces are from MSB first; hence + * D3DFMT_A8L8 indicates that the high byte of this two byte + * format is alpha. + * + * D16 indicates: + * - An integer 16-bit value. + * - An app-lockable surface. + * + * All Depth/Stencil formats except D3DFMT_D16_LOCKABLE indicate: + * - no particular bit ordering per pixel, and + * - are not app lockable, and + * - the driver is allowed to consume more than the indicated + * number of bits per Depth channel (but not Stencil channel). + */ +#ifndef MAKEFOURCC + #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ + ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) +#endif /* defined(MAKEFOURCC) */ + + +typedef enum _D3DFORMAT +{ + D3DFMT_UNKNOWN = 0, + + D3DFMT_R8G8B8 = 20, + D3DFMT_A8R8G8B8 = 21, + D3DFMT_X8R8G8B8 = 22, + D3DFMT_R5G6B5 = 23, + D3DFMT_X1R5G5B5 = 24, + D3DFMT_A1R5G5B5 = 25, + D3DFMT_A4R4G4B4 = 26, + D3DFMT_R3G3B2 = 27, + D3DFMT_A8 = 28, + D3DFMT_A8R3G3B2 = 29, + D3DFMT_X4R4G4B4 = 30, + + D3DFMT_A8P8 = 40, + D3DFMT_P8 = 41, + + D3DFMT_L8 = 50, + D3DFMT_A8L8 = 51, + D3DFMT_A4L4 = 52, + + D3DFMT_V8U8 = 60, + D3DFMT_L6V5U5 = 61, + D3DFMT_X8L8V8U8 = 62, + D3DFMT_Q8W8V8U8 = 63, + D3DFMT_V16U16 = 64, + D3DFMT_W11V11U10 = 65, + + D3DFMT_UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'), + D3DFMT_YUY2 = MAKEFOURCC('Y', 'U', 'Y', '2'), + D3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'), + D3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'), + D3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'), + D3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'), + D3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'), + + D3DFMT_D16_LOCKABLE = 70, + D3DFMT_D32 = 71, + D3DFMT_D15S1 = 73, + D3DFMT_D24S8 = 75, + D3DFMT_D16 = 80, + D3DFMT_D24X8 = 77, + D3DFMT_D24X4S4 = 79, + + + D3DFMT_VERTEXDATA =100, + D3DFMT_INDEX16 =101, + D3DFMT_INDEX32 =102, + + D3DFMT_FORCE_DWORD =0x7fffffff +} D3DFORMAT; + +/* Display Modes */ +typedef struct _D3DDISPLAYMODE +{ + UINT Width; + UINT Height; + UINT RefreshRate; + D3DFORMAT Format; +} D3DDISPLAYMODE; + +/* Creation Parameters */ +typedef struct _D3DDEVICE_CREATION_PARAMETERS +{ + UINT AdapterOrdinal; + D3DDEVTYPE DeviceType; + HWND hFocusWindow; + DWORD BehaviorFlags; +} D3DDEVICE_CREATION_PARAMETERS; + + +/* SwapEffects */ +typedef enum _D3DSWAPEFFECT +{ + D3DSWAPEFFECT_DISCARD = 1, + D3DSWAPEFFECT_FLIP = 2, + D3DSWAPEFFECT_COPY = 3, + D3DSWAPEFFECT_COPY_VSYNC = 4, + + D3DSWAPEFFECT_FORCE_DWORD = 0x7fffffff +} D3DSWAPEFFECT; + +/* Pool types */ +typedef enum _D3DPOOL { + D3DPOOL_DEFAULT = 0, + D3DPOOL_MANAGED = 1, + D3DPOOL_SYSTEMMEM = 2, + + D3DPOOL_FORCE_DWORD = 0x7fffffff +} D3DPOOL; + + +/* RefreshRate pre-defines */ +#define D3DPRESENT_RATE_DEFAULT 0x00000000 +#define D3DPRESENT_RATE_UNLIMITED 0x7fffffff + + +/* Resize Optional Parameters */ +typedef struct _D3DPRESENT_PARAMETERS_ +{ + UINT BackBufferWidth; + UINT BackBufferHeight; + D3DFORMAT BackBufferFormat; + UINT BackBufferCount; + + D3DMULTISAMPLE_TYPE MultiSampleType; + + D3DSWAPEFFECT SwapEffect; + HWND hDeviceWindow; + BOOL Windowed; + BOOL EnableAutoDepthStencil; + D3DFORMAT AutoDepthStencilFormat; + DWORD Flags; + + /* Following elements must be zero for Windowed mode */ + UINT FullScreen_RefreshRateInHz; + UINT FullScreen_PresentationInterval; + +} D3DPRESENT_PARAMETERS; + +// Values for D3DPRESENT_PARAMETERS.Flags + +#define D3DPRESENTFLAG_LOCKABLE_BACKBUFFER 0x00000001 + + +/* Gamma Ramp: Same as DX7 */ + +typedef struct _D3DGAMMARAMP +{ + WORD red [256]; + WORD green[256]; + WORD blue [256]; +} D3DGAMMARAMP; + +/* Back buffer types */ +typedef enum _D3DBACKBUFFER_TYPE +{ + D3DBACKBUFFER_TYPE_MONO = 0, + D3DBACKBUFFER_TYPE_LEFT = 1, + D3DBACKBUFFER_TYPE_RIGHT = 2, + + D3DBACKBUFFER_TYPE_FORCE_DWORD = 0x7fffffff +} D3DBACKBUFFER_TYPE; + + +/* Types */ +typedef enum _D3DRESOURCETYPE { + D3DRTYPE_SURFACE = 1, + D3DRTYPE_VOLUME = 2, + D3DRTYPE_TEXTURE = 3, + D3DRTYPE_VOLUMETEXTURE = 4, + D3DRTYPE_CUBETEXTURE = 5, + D3DRTYPE_VERTEXBUFFER = 6, + D3DRTYPE_INDEXBUFFER = 7, + + + D3DRTYPE_FORCE_DWORD = 0x7fffffff +} D3DRESOURCETYPE; + +/* Usages */ +#define D3DUSAGE_RENDERTARGET (0x00000001L) +#define D3DUSAGE_DEPTHSTENCIL (0x00000002L) + +/* Usages for Vertex/Index buffers */ +#define D3DUSAGE_WRITEONLY (0x00000008L) +#define D3DUSAGE_SOFTWAREPROCESSING (0x00000010L) +#define D3DUSAGE_DONOTCLIP (0x00000020L) +#define D3DUSAGE_POINTS (0x00000040L) +#define D3DUSAGE_RTPATCHES (0x00000080L) +#define D3DUSAGE_NPATCHES (0x00000100L) +#define D3DUSAGE_DYNAMIC (0x00000200L) + + + + + + + + + +/* CubeMap Face identifiers */ +typedef enum _D3DCUBEMAP_FACES +{ + D3DCUBEMAP_FACE_POSITIVE_X = 0, + D3DCUBEMAP_FACE_NEGATIVE_X = 1, + D3DCUBEMAP_FACE_POSITIVE_Y = 2, + D3DCUBEMAP_FACE_NEGATIVE_Y = 3, + D3DCUBEMAP_FACE_POSITIVE_Z = 4, + D3DCUBEMAP_FACE_NEGATIVE_Z = 5, + + D3DCUBEMAP_FACE_FORCE_DWORD = 0x7fffffff +} D3DCUBEMAP_FACES; + + +/* Lock flags */ + +#define D3DLOCK_READONLY 0x00000010L +#define D3DLOCK_DISCARD 0x00002000L +#define D3DLOCK_NOOVERWRITE 0x00001000L +#define D3DLOCK_NOSYSLOCK 0x00000800L + +#define D3DLOCK_NO_DIRTY_UPDATE 0x00008000L + + + + + + +/* Vertex Buffer Description */ +typedef struct _D3DVERTEXBUFFER_DESC +{ + D3DFORMAT Format; + D3DRESOURCETYPE Type; + DWORD Usage; + D3DPOOL Pool; + UINT Size; + + DWORD FVF; + +} D3DVERTEXBUFFER_DESC; + +/* Index Buffer Description */ +typedef struct _D3DINDEXBUFFER_DESC +{ + D3DFORMAT Format; + D3DRESOURCETYPE Type; + DWORD Usage; + D3DPOOL Pool; + UINT Size; +} D3DINDEXBUFFER_DESC; + + +/* Surface Description */ +typedef struct _D3DSURFACE_DESC +{ + D3DFORMAT Format; + D3DRESOURCETYPE Type; + DWORD Usage; + D3DPOOL Pool; + UINT Size; + + D3DMULTISAMPLE_TYPE MultiSampleType; + UINT Width; + UINT Height; +} D3DSURFACE_DESC; + +typedef struct _D3DVOLUME_DESC +{ + D3DFORMAT Format; + D3DRESOURCETYPE Type; + DWORD Usage; + D3DPOOL Pool; + UINT Size; + + UINT Width; + UINT Height; + UINT Depth; +} D3DVOLUME_DESC; + +/* Structure for LockRect */ +typedef struct _D3DLOCKED_RECT +{ + INT Pitch; + void* pBits; +} D3DLOCKED_RECT; + +/* Structures for LockBox */ +typedef struct _D3DBOX +{ + UINT Left; + UINT Top; + UINT Right; + UINT Bottom; + UINT Front; + UINT Back; +} D3DBOX; + +typedef struct _D3DLOCKED_BOX +{ + INT RowPitch; + INT SlicePitch; + void* pBits; +} D3DLOCKED_BOX; + +/* Structures for LockRange */ +typedef struct _D3DRANGE +{ + UINT Offset; + UINT Size; +} D3DRANGE; + +/* Structures for high order primitives */ +typedef struct _D3DRECTPATCH_INFO +{ + UINT StartVertexOffsetWidth; + UINT StartVertexOffsetHeight; + UINT Width; + UINT Height; + UINT Stride; + D3DBASISTYPE Basis; + D3DORDERTYPE Order; +} D3DRECTPATCH_INFO; + +typedef struct _D3DTRIPATCH_INFO +{ + UINT StartVertexOffset; + UINT NumVertices; + D3DBASISTYPE Basis; + D3DORDERTYPE Order; +} D3DTRIPATCH_INFO; + +/* Adapter Identifier */ + +#define MAX_DEVICE_IDENTIFIER_STRING 512 +typedef struct _D3DADAPTER_IDENTIFIER8 +{ + char Driver[MAX_DEVICE_IDENTIFIER_STRING]; + char Description[MAX_DEVICE_IDENTIFIER_STRING]; + +#ifdef _WIN32 + LARGE_INTEGER DriverVersion; /* Defined for 32 bit components */ +#else + DWORD DriverVersionLowPart; /* Defined for 16 bit driver components */ + DWORD DriverVersionHighPart; +#endif + + DWORD VendorId; + DWORD DeviceId; + DWORD SubSysId; + DWORD Revision; + + GUID DeviceIdentifier; + + DWORD WHQLLevel; + +} D3DADAPTER_IDENTIFIER8; + + +/* Raster Status structure returned by GetRasterStatus */ +typedef struct _D3DRASTER_STATUS +{ + BOOL InVBlank; + UINT ScanLine; +} D3DRASTER_STATUS; + + + +/* Debug monitor tokens (DEBUG only) + + Note that if D3DRS_DEBUGMONITORTOKEN is set, the call is treated as + passing a token to the debug monitor. For example, if, after passing + D3DDMT_ENABLE/DISABLE to D3DRS_DEBUGMONITORTOKEN other token values + are passed in, the enabled/disabled state of the debug + monitor will still persist. + + The debug monitor defaults to enabled. + + Calling GetRenderState on D3DRS_DEBUGMONITORTOKEN is not of any use. +*/ +typedef enum _D3DDEBUGMONITORTOKENS { + D3DDMT_ENABLE = 0, // enable debug monitor + D3DDMT_DISABLE = 1, // disable debug monitor + D3DDMT_FORCE_DWORD = 0x7fffffff, +} D3DDEBUGMONITORTOKENS; + +#pragma pack() +#pragma warning(default:4201) + +#endif /* (DIRECT3D_VERSION >= 0x0800) */ +#endif /* _D3D8TYPES(P)_H_ */ + diff --git a/builddir/irrlicht-1.8.1/include/d3dx8.h b/builddir/irrlicht-1.8.1/include/d3dx8.h new file mode 100644 index 0000000..66af5e2 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx8.h @@ -0,0 +1,36 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 1999 Microsoft Corporation. All Rights Reserved. +// +// File: d3dx8.h +// Content: D3DX utility library +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX8_H__ +#define __D3DX8_H__ + +#include <d3d8.h> +#include <limits.h> + +#ifndef D3DXINLINE +#ifdef __cplusplus +#define D3DXINLINE inline +#else +#define D3DXINLINE _inline +#endif +#endif + +#define D3DX_DEFAULT ULONG_MAX +#define D3DX_DEFAULT_FLOAT FLT_MAX + +#include "d3dx8math.h" +#include "d3dx8core.h" +#include "d3dx8tex.h" +#include "d3dx8mesh.h" +#include "d3dx8shape.h" +#include "d3dx8effect.h" + + +#endif //__D3DX8_H__ + diff --git a/builddir/irrlicht-1.8.1/include/d3dx9.h b/builddir/irrlicht-1.8.1/include/d3dx9.h new file mode 100644 index 0000000..43f9e62 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx9.h @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9.h +// Content: D3DX utility library +// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __D3DX_INTERNAL__ +#error Incorrect D3DX header used +#endif + +#ifndef __D3DX9_H__ +#define __D3DX9_H__ + + +// Defines +#include <limits.h> + +#define D3DX_DEFAULT ((UINT) -1) +#define D3DX_DEFAULT_NONPOW2 ((UINT) -2) +#define D3DX_DEFAULT_FLOAT FLT_MAX +#define D3DX_FROM_FILE ((UINT) -3) +#define D3DFMT_FROM_FILE ((D3DFORMAT) -3) + +#ifndef D3DXINLINE +#ifdef _MSC_VER + #if (_MSC_VER >= 1200) + #define D3DXINLINE __forceinline + #else + #define D3DXINLINE __inline + #endif +#else + #ifdef __cplusplus + #define D3DXINLINE inline + #else + #define D3DXINLINE + #endif +#endif +#endif + + + +// Includes +#include "d3d9.h" +#include "d3dx9math.h" +#include "d3dx9core.h" +#include "d3dx9xof.h" +#include "d3dx9mesh.h" +#include "d3dx9shader.h" +#include "d3dx9effect.h" + +#include "d3dx9tex.h" +#include "d3dx9shape.h" +#include "d3dx9anim.h" + + + +// Errors +#define _FACDD 0x876 +#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) + +enum _D3DXERR { + D3DXERR_CANNOTMODIFYINDEXBUFFER = MAKE_DDHRESULT(2900), + D3DXERR_INVALIDMESH = MAKE_DDHRESULT(2901), + D3DXERR_CANNOTATTRSORT = MAKE_DDHRESULT(2902), + D3DXERR_SKINNINGNOTSUPPORTED = MAKE_DDHRESULT(2903), + D3DXERR_TOOMANYINFLUENCES = MAKE_DDHRESULT(2904), + D3DXERR_INVALIDDATA = MAKE_DDHRESULT(2905), + D3DXERR_LOADEDMESHASNODATA = MAKE_DDHRESULT(2906), + D3DXERR_DUPLICATENAMEDFRAGMENT = MAKE_DDHRESULT(2907), + D3DXERR_CANNOTREMOVELASTITEM = MAKE_DDHRESULT(2908), +}; + + +#endif //__D3DX9_H__ + diff --git a/builddir/irrlicht-1.8.1/include/d3dx9anim.h b/builddir/irrlicht-1.8.1/include/d3dx9anim.h new file mode 100644 index 0000000..fedb1db --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx9anim.h @@ -0,0 +1,1114 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9anim.h +// Content: D3DX mesh types and functions +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX9ANIM_H__ +#define __D3DX9ANIM_H__ + +// {698CFB3F-9289-4d95-9A57-33A94B5A65F9} +DEFINE_GUID(IID_ID3DXAnimationSet, +0x698cfb3f, 0x9289, 0x4d95, 0x9a, 0x57, 0x33, 0xa9, 0x4b, 0x5a, 0x65, 0xf9); + +// {FA4E8E3A-9786-407d-8B4C-5995893764AF} +DEFINE_GUID(IID_ID3DXKeyframedAnimationSet, +0xfa4e8e3a, 0x9786, 0x407d, 0x8b, 0x4c, 0x59, 0x95, 0x89, 0x37, 0x64, 0xaf); + +// {6CC2480D-3808-4739-9F88-DE49FACD8D4C} +DEFINE_GUID(IID_ID3DXCompressedAnimationSet, +0x6cc2480d, 0x3808, 0x4739, 0x9f, 0x88, 0xde, 0x49, 0xfa, 0xcd, 0x8d, 0x4c); + +// {AC8948EC-F86D-43e2-96DE-31FC35F96D9E} +DEFINE_GUID(IID_ID3DXAnimationController, +0xac8948ec, 0xf86d, 0x43e2, 0x96, 0xde, 0x31, 0xfc, 0x35, 0xf9, 0x6d, 0x9e); + + +//---------------------------------------------------------------------------- +// D3DXMESHDATATYPE: +// ----------------- +// This enum defines the type of mesh data present in a MeshData structure. +//---------------------------------------------------------------------------- +typedef enum _D3DXMESHDATATYPE { + D3DXMESHTYPE_MESH = 0x001, // Normal ID3DXMesh data + D3DXMESHTYPE_PMESH = 0x002, // Progressive Mesh - ID3DXPMesh + D3DXMESHTYPE_PATCHMESH = 0x003, // Patch Mesh - ID3DXPatchMesh + + D3DXMESHTYPE_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXMESHDATATYPE; + +//---------------------------------------------------------------------------- +// D3DXMESHDATA: +// ------------- +// This struct encapsulates a the mesh data that can be present in a mesh +// container. The supported mesh types are pMesh, pPMesh, pPatchMesh. +// The valid way to access this is determined by the Type enum. +//---------------------------------------------------------------------------- +typedef struct _D3DXMESHDATA +{ + D3DXMESHDATATYPE Type; + + // current mesh data interface + union + { + LPD3DXMESH pMesh; + LPD3DXPMESH pPMesh; + LPD3DXPATCHMESH pPatchMesh; + }; +} D3DXMESHDATA, *LPD3DXMESHDATA; + +//---------------------------------------------------------------------------- +// D3DXMESHCONTAINER: +// ------------------ +// This struct encapsulates a mesh object in a transformation frame +// hierarchy. The app can derive from this structure to add other app specific +// data to this. +//---------------------------------------------------------------------------- +typedef struct _D3DXMESHCONTAINER +{ + LPSTR Name; + + D3DXMESHDATA MeshData; + + LPD3DXMATERIAL pMaterials; + LPD3DXEFFECTINSTANCE pEffects; + DWORD NumMaterials; + DWORD *pAdjacency; + + LPD3DXSKININFO pSkinInfo; + + struct _D3DXMESHCONTAINER *pNextMeshContainer; +} D3DXMESHCONTAINER, *LPD3DXMESHCONTAINER; + +//---------------------------------------------------------------------------- +// D3DXFRAME: +// ---------- +// This struct is the encapsulates a transform frame in a transformation frame +// hierarchy. The app can derive from this structure to add other app specific +// data to this +//---------------------------------------------------------------------------- +typedef struct _D3DXFRAME +{ + LPSTR Name; + D3DXMATRIX TransformationMatrix; + + LPD3DXMESHCONTAINER pMeshContainer; + + struct _D3DXFRAME *pFrameSibling; + struct _D3DXFRAME *pFrameFirstChild; +} D3DXFRAME, *LPD3DXFRAME; + + +//---------------------------------------------------------------------------- +// ID3DXAllocateHierarchy: +// ----------------------- +// This interface is implemented by the application to allocate/free frame and +// mesh container objects. Methods on this are called during loading and +// destroying frame hierarchies +//---------------------------------------------------------------------------- +typedef interface ID3DXAllocateHierarchy ID3DXAllocateHierarchy; +typedef interface ID3DXAllocateHierarchy *LPD3DXALLOCATEHIERARCHY; + +#undef INTERFACE +#define INTERFACE ID3DXAllocateHierarchy + +DECLARE_INTERFACE(ID3DXAllocateHierarchy) +{ + // ID3DXAllocateHierarchy + + //------------------------------------------------------------------------ + // CreateFrame: + // ------------ + // Requests allocation of a frame object. + // + // Parameters: + // Name + // Name of the frame to be created + // ppNewFrame + // Returns the created frame object + // + //------------------------------------------------------------------------ + STDMETHOD(CreateFrame)(THIS_ LPCSTR Name, + LPD3DXFRAME *ppNewFrame) PURE; + + //------------------------------------------------------------------------ + // CreateMeshContainer: + // -------------------- + // Requests allocation of a mesh container object. + // + // Parameters: + // Name + // Name of the mesh + // pMesh + // Pointer to the mesh object if basic polygon data found + // pPMesh + // Pointer to the progressive mesh object if progressive mesh data found + // pPatchMesh + // Pointer to the patch mesh object if patch data found + // pMaterials + // Array of materials used in the mesh + // pEffectInstances + // Array of effect instances used in the mesh + // NumMaterials + // Num elements in the pMaterials array + // pAdjacency + // Adjacency array for the mesh + // pSkinInfo + // Pointer to the skininfo object if the mesh is skinned + // pBoneNames + // Array of names, one for each bone in the skinned mesh. + // The numberof bones can be found from the pSkinMesh object + // pBoneOffsetMatrices + // Array of matrices, one for each bone in the skinned mesh. + // + //------------------------------------------------------------------------ + STDMETHOD(CreateMeshContainer)(THIS_ + LPCSTR Name, + CONST D3DXMESHDATA *pMeshData, + CONST D3DXMATERIAL *pMaterials, + CONST D3DXEFFECTINSTANCE *pEffectInstances, + DWORD NumMaterials, + CONST DWORD *pAdjacency, + LPD3DXSKININFO pSkinInfo, + LPD3DXMESHCONTAINER *ppNewMeshContainer) PURE; + + //------------------------------------------------------------------------ + // DestroyFrame: + // ------------- + // Requests de-allocation of a frame object. + // + // Parameters: + // pFrameToFree + // Pointer to the frame to be de-allocated + // + //------------------------------------------------------------------------ + STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME pFrameToFree) PURE; + + //------------------------------------------------------------------------ + // DestroyMeshContainer: + // --------------------- + // Requests de-allocation of a mesh container object. + // + // Parameters: + // pMeshContainerToFree + // Pointer to the mesh container object to be de-allocated + // + //------------------------------------------------------------------------ + STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerToFree) PURE; +}; + +//---------------------------------------------------------------------------- +// ID3DXLoadUserData: +// ------------------ +// This interface is implemented by the application to load user data in a .X file +// When user data is found, these callbacks will be used to allow the application +// to load the data. +//---------------------------------------------------------------------------- +typedef interface ID3DXLoadUserData ID3DXLoadUserData; +typedef interface ID3DXLoadUserData *LPD3DXLOADUSERDATA; + +#undef INTERFACE +#define INTERFACE ID3DXLoadUserData + +DECLARE_INTERFACE(ID3DXLoadUserData) +{ + STDMETHOD(LoadTopLevelData)(LPD3DXFILEDATA pXofChildData) PURE; + + STDMETHOD(LoadFrameChildData)(LPD3DXFRAME pFrame, + LPD3DXFILEDATA pXofChildData) PURE; + + STDMETHOD(LoadMeshChildData)(LPD3DXMESHCONTAINER pMeshContainer, + LPD3DXFILEDATA pXofChildData) PURE; +}; + +//---------------------------------------------------------------------------- +// ID3DXSaveUserData: +// ------------------ +// This interface is implemented by the application to save user data in a .X file +// The callbacks are called for all data saved. The user can then add any +// child data objects to the object provided to the callback. +//---------------------------------------------------------------------------- +typedef interface ID3DXSaveUserData ID3DXSaveUserData; +typedef interface ID3DXSaveUserData *LPD3DXSAVEUSERDATA; + +#undef INTERFACE +#define INTERFACE ID3DXSaveUserData + +DECLARE_INTERFACE(ID3DXSaveUserData) +{ + STDMETHOD(AddFrameChildData)(CONST D3DXFRAME *pFrame, + LPD3DXFILESAVEOBJECT pXofSave, + LPD3DXFILESAVEDATA pXofFrameData) PURE; + + STDMETHOD(AddMeshChildData)(CONST D3DXMESHCONTAINER *pMeshContainer, + LPD3DXFILESAVEOBJECT pXofSave, + LPD3DXFILESAVEDATA pXofMeshData) PURE; + + // NOTE: this is called once per Save. All top level objects should be added using the + // provided interface. One call adds objects before the frame hierarchy, the other after + STDMETHOD(AddTopLevelDataObjectsPre)(LPD3DXFILESAVEOBJECT pXofSave) PURE; + STDMETHOD(AddTopLevelDataObjectsPost)(LPD3DXFILESAVEOBJECT pXofSave) PURE; + + // callbacks for the user to register and then save templates to the XFile + STDMETHOD(RegisterTemplates)(LPD3DXFILE pXFileApi) PURE; + STDMETHOD(SaveTemplates)(LPD3DXFILESAVEOBJECT pXofSave) PURE; +}; + + +//---------------------------------------------------------------------------- +// D3DXCALLBACK_SEARCH_FLAGS: +// -------------------------- +// Flags that can be passed into ID3DXAnimationSet::GetCallback. +//---------------------------------------------------------------------------- +typedef enum _D3DXCALLBACK_SEARCH_FLAGS +{ + D3DXCALLBACK_SEARCH_EXCLUDING_INITIAL_POSITION = 0x01, // exclude callbacks at the initial position from the search + D3DXCALLBACK_SEARCH_BEHIND_INITIAL_POSITION = 0x02, // reverse the callback search direction + + D3DXCALLBACK_SEARCH_FORCE_DWORD = 0x7fffffff, +} D3DXCALLBACK_SEARCH_FLAGS; + +//---------------------------------------------------------------------------- +// ID3DXAnimationSet: +// ------------------ +// This interface implements an animation set. +//---------------------------------------------------------------------------- +typedef interface ID3DXAnimationSet ID3DXAnimationSet; +typedef interface ID3DXAnimationSet *LPD3DXANIMATIONSET; + +#undef INTERFACE +#define INTERFACE ID3DXAnimationSet + +DECLARE_INTERFACE_(ID3DXAnimationSet, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Name + STDMETHOD_(LPCSTR, GetName)(THIS) PURE; + + // Period + STDMETHOD_(DOUBLE, GetPeriod)(THIS) PURE; + STDMETHOD_(DOUBLE, GetPeriodicPosition)(THIS_ DOUBLE Position) PURE; // Maps position into animation period + + // Animation names + STDMETHOD_(UINT, GetNumAnimations)(THIS) PURE; + STDMETHOD(GetAnimationNameByIndex)(THIS_ UINT Index, LPCSTR *ppName) PURE; + STDMETHOD(GetAnimationIndexByName)(THIS_ LPCSTR pName, UINT *pIndex) PURE; + + // SRT + STDMETHOD(GetSRT)(THIS_ + DOUBLE PeriodicPosition, // Position mapped to period (use GetPeriodicPosition) + UINT Animation, // Animation index + D3DXVECTOR3 *pScale, // Returns the scale + D3DXQUATERNION *pRotation, // Returns the rotation as a quaternion + D3DXVECTOR3 *pTranslation) PURE; // Returns the translation + + // Callbacks + STDMETHOD(GetCallback)(THIS_ + DOUBLE Position, // Position from which to find callbacks + DWORD Flags, // Callback search flags + DOUBLE *pCallbackPosition, // Returns the position of the callback + LPVOID *ppCallbackData) PURE; // Returns the callback data pointer +}; + + +//---------------------------------------------------------------------------- +// D3DXPLAYBACK_TYPE: +// ------------------ +// This enum defines the type of animation set loop modes. +//---------------------------------------------------------------------------- +typedef enum _D3DXPLAYBACK_TYPE +{ + D3DXPLAY_LOOP = 0, + D3DXPLAY_ONCE = 1, + D3DXPLAY_PINGPONG = 2, + + D3DXPLAY_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXPLAYBACK_TYPE; + + +//---------------------------------------------------------------------------- +// D3DXKEY_VECTOR3: +// ---------------- +// This structure describes a vector key for use in keyframe animation. +// It specifies a vector Value at a given Time. This is used for scale and +// translation keys. +//---------------------------------------------------------------------------- +typedef struct _D3DXKEY_VECTOR3 +{ + FLOAT Time; + D3DXVECTOR3 Value; +} D3DXKEY_VECTOR3, *LPD3DXKEY_VECTOR3; + + +//---------------------------------------------------------------------------- +// D3DXKEY_QUATERNION: +// ------------------- +// This structure describes a quaternion key for use in keyframe animation. +// It specifies a quaternion Value at a given Time. This is used for rotation +// keys. +//---------------------------------------------------------------------------- +typedef struct _D3DXKEY_QUATERNION +{ + FLOAT Time; + D3DXQUATERNION Value; +} D3DXKEY_QUATERNION, *LPD3DXKEY_QUATERNION; + + +//---------------------------------------------------------------------------- +// D3DXKEY_CALLBACK: +// ----------------- +// This structure describes an callback key for use in keyframe animation. +// It specifies a pointer to user data at a given Time. +//---------------------------------------------------------------------------- +typedef struct _D3DXKEY_CALLBACK +{ + FLOAT Time; + LPVOID pCallbackData; +} D3DXKEY_CALLBACK, *LPD3DXKEY_CALLBACK; + + +//---------------------------------------------------------------------------- +// D3DXCOMPRESSION_FLAGS: +// ---------------------- +// Flags that can be passed into ID3DXKeyframedAnimationSet::Compress. +//---------------------------------------------------------------------------- +typedef enum _D3DXCOMPRESSION_FLAGS +{ + D3DXCOMPRESS_DEFAULT = 0x00, + + D3DXCOMPRESS_FORCE_DWORD = 0x7fffffff, +} D3DXCOMPRESSION_FLAGS; + + +//---------------------------------------------------------------------------- +// ID3DXKeyframedAnimationSet: +// --------------------------- +// This interface implements a compressable keyframed animation set. +//---------------------------------------------------------------------------- +typedef interface ID3DXKeyframedAnimationSet ID3DXKeyframedAnimationSet; +typedef interface ID3DXKeyframedAnimationSet *LPD3DXKEYFRAMEDANIMATIONSET; + +#undef INTERFACE +#define INTERFACE ID3DXKeyframedAnimationSet + +DECLARE_INTERFACE_(ID3DXKeyframedAnimationSet, ID3DXAnimationSet) +{ + // ID3DXAnimationSet + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Name + STDMETHOD_(LPCSTR, GetName)(THIS) PURE; + + // Period + STDMETHOD_(DOUBLE, GetPeriod)(THIS) PURE; + STDMETHOD_(DOUBLE, GetPeriodicPosition)(THIS_ DOUBLE Position) PURE; // Maps position into animation period + + // Animation names + STDMETHOD_(UINT, GetNumAnimations)(THIS) PURE; + STDMETHOD(GetAnimationNameByIndex)(THIS_ UINT Index, LPCSTR *ppName) PURE; + STDMETHOD(GetAnimationIndexByName)(THIS_ LPCSTR pName, UINT *pIndex) PURE; + + // SRT + STDMETHOD(GetSRT)(THIS_ + DOUBLE PeriodicPosition, // Position mapped to period (use GetPeriodicPosition) + UINT Animation, // Animation index + D3DXVECTOR3 *pScale, // Returns the scale + D3DXQUATERNION *pRotation, // Returns the rotation as a quaternion + D3DXVECTOR3 *pTranslation) PURE; // Returns the translation + + // Callbacks + STDMETHOD(GetCallback)(THIS_ + DOUBLE Position, // Position from which to find callbacks + DWORD Flags, // Callback search flags + DOUBLE *pCallbackPosition, // Returns the position of the callback + LPVOID *ppCallbackData) PURE; // Returns the callback data pointer + + // Playback + STDMETHOD_(D3DXPLAYBACK_TYPE, GetPlaybackType)(THIS) PURE; + STDMETHOD_(DOUBLE, GetSourceTicksPerSecond)(THIS) PURE; + + // Scale keys + STDMETHOD_(UINT, GetNumScaleKeys)(THIS_ UINT Animation) PURE; + STDMETHOD(GetScaleKeys)(THIS_ UINT Animation, LPD3DXKEY_VECTOR3 pScaleKeys) PURE; + STDMETHOD(GetScaleKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_VECTOR3 pScaleKey) PURE; + STDMETHOD(SetScaleKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_VECTOR3 pScaleKey) PURE; + + // Rotation keys + STDMETHOD_(UINT, GetNumRotationKeys)(THIS_ UINT Animation) PURE; + STDMETHOD(GetRotationKeys)(THIS_ UINT Animation, LPD3DXKEY_QUATERNION pRotationKeys) PURE; + STDMETHOD(GetRotationKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_QUATERNION pRotationKey) PURE; + STDMETHOD(SetRotationKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_QUATERNION pRotationKey) PURE; + + // Translation keys + STDMETHOD_(UINT, GetNumTranslationKeys)(THIS_ UINT Animation) PURE; + STDMETHOD(GetTranslationKeys)(THIS_ UINT Animation, LPD3DXKEY_VECTOR3 pTranslationKeys) PURE; + STDMETHOD(GetTranslationKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_VECTOR3 pTranslationKey) PURE; + STDMETHOD(SetTranslationKey)(THIS_ UINT Animation, UINT Key, LPD3DXKEY_VECTOR3 pTranslationKey) PURE; + + // Callback keys + STDMETHOD_(UINT, GetNumCallbackKeys)(THIS) PURE; + STDMETHOD(GetCallbackKeys)(THIS_ LPD3DXKEY_CALLBACK pCallbackKeys) PURE; + STDMETHOD(GetCallbackKey)(THIS_ UINT Key, LPD3DXKEY_CALLBACK pCallbackKey) PURE; + STDMETHOD(SetCallbackKey)(THIS_ UINT Key, LPD3DXKEY_CALLBACK pCallbackKey) PURE; + + // Key removal methods. These are slow, and should not be used once the animation starts playing + STDMETHOD(UnregisterScaleKey)(THIS_ UINT Animation, UINT Key) PURE; + STDMETHOD(UnregisterRotationKey)(THIS_ UINT Animation, UINT Key) PURE; + STDMETHOD(UnregisterTranslationKey)(THIS_ UINT Animation, UINT Key) PURE; + + // One-time animaton SRT keyframe registration + STDMETHOD(RegisterAnimationSRTKeys)(THIS_ + LPCSTR pName, // Animation name + UINT NumScaleKeys, // Number of scale keys + UINT NumRotationKeys, // Number of rotation keys + UINT NumTranslationKeys, // Number of translation keys + CONST D3DXKEY_VECTOR3 *pScaleKeys, // Array of scale keys + CONST D3DXKEY_QUATERNION *pRotationKeys, // Array of rotation keys + CONST D3DXKEY_VECTOR3 *pTranslationKeys, // Array of translation keys + DWORD *pAnimationIndex) PURE; // Returns the animation index + + // Compression + STDMETHOD(Compress)(THIS_ + DWORD Flags, // Compression flags (use D3DXCOMPRESS_STRONG for better results) + FLOAT Lossiness, // Compression loss ratio in the [0, 1] range + LPD3DXFRAME pHierarchy, // Frame hierarchy (optional) + LPD3DXBUFFER *ppCompressedData) PURE; // Returns the compressed animation set + + STDMETHOD(UnregisterAnimation)(THIS_ UINT Index) PURE; +}; + + +//---------------------------------------------------------------------------- +// ID3DXCompressedAnimationSet: +// ---------------------------- +// This interface implements a compressed keyframed animation set. +//---------------------------------------------------------------------------- +typedef interface ID3DXCompressedAnimationSet ID3DXCompressedAnimationSet; +typedef interface ID3DXCompressedAnimationSet *LPD3DXCOMPRESSEDANIMATIONSET; + +#undef INTERFACE +#define INTERFACE ID3DXCompressedAnimationSet + +DECLARE_INTERFACE_(ID3DXCompressedAnimationSet, ID3DXAnimationSet) +{ + // ID3DXAnimationSet + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Name + STDMETHOD_(LPCSTR, GetName)(THIS) PURE; + + // Period + STDMETHOD_(DOUBLE, GetPeriod)(THIS) PURE; + STDMETHOD_(DOUBLE, GetPeriodicPosition)(THIS_ DOUBLE Position) PURE; // Maps position into animation period + + // Animation names + STDMETHOD_(UINT, GetNumAnimations)(THIS) PURE; + STDMETHOD(GetAnimationNameByIndex)(THIS_ UINT Index, LPCSTR *ppName) PURE; + STDMETHOD(GetAnimationIndexByName)(THIS_ LPCSTR pName, UINT *pIndex) PURE; + + // SRT + STDMETHOD(GetSRT)(THIS_ + DOUBLE PeriodicPosition, // Position mapped to period (use GetPeriodicPosition) + UINT Animation, // Animation index + D3DXVECTOR3 *pScale, // Returns the scale + D3DXQUATERNION *pRotation, // Returns the rotation as a quaternion + D3DXVECTOR3 *pTranslation) PURE; // Returns the translation + + // Callbacks + STDMETHOD(GetCallback)(THIS_ + DOUBLE Position, // Position from which to find callbacks + DWORD Flags, // Callback search flags + DOUBLE *pCallbackPosition, // Returns the position of the callback + LPVOID *ppCallbackData) PURE; // Returns the callback data pointer + + // Playback + STDMETHOD_(D3DXPLAYBACK_TYPE, GetPlaybackType)(THIS) PURE; + STDMETHOD_(DOUBLE, GetSourceTicksPerSecond)(THIS) PURE; + + // Scale keys + STDMETHOD(GetCompressedData)(THIS_ LPD3DXBUFFER *ppCompressedData) PURE; + + // Callback keys + STDMETHOD_(UINT, GetNumCallbackKeys)(THIS) PURE; + STDMETHOD(GetCallbackKeys)(THIS_ LPD3DXKEY_CALLBACK pCallbackKeys) PURE; +}; + + +//---------------------------------------------------------------------------- +// D3DXPRIORITY_TYPE: +// ------------------ +// This enum defines the type of priority group that a track can be assigned to. +//---------------------------------------------------------------------------- +typedef enum _D3DXPRIORITY_TYPE { + D3DXPRIORITY_LOW = 0, // This track should be blended with all low priority tracks before mixed with the high priority result + D3DXPRIORITY_HIGH = 1, // This track should be blended with all high priority tracks before mixed with the low priority result + + D3DXPRIORITY_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXPRIORITY_TYPE; + +//---------------------------------------------------------------------------- +// D3DXTRACK_DESC: +// --------------- +// This structure describes the mixing information of an animation track. +// The mixing information consists of the current position, speed, and blending +// weight for the track. The Flags field also specifies whether the track is +// low or high priority. Tracks with the same priority are blended together +// and then the two resulting values are blended using the priority blend factor. +// A track also has an animation set (stored separately) associated with it. +//---------------------------------------------------------------------------- +typedef struct _D3DXTRACK_DESC +{ + D3DXPRIORITY_TYPE Priority; + FLOAT Weight; + FLOAT Speed; + DOUBLE Position; + BOOL Enable; +} D3DXTRACK_DESC, *LPD3DXTRACK_DESC; + +//---------------------------------------------------------------------------- +// D3DXEVENT_TYPE: +// --------------- +// This enum defines the type of events keyable via the animation controller. +//---------------------------------------------------------------------------- +typedef enum _D3DXEVENT_TYPE +{ + D3DXEVENT_TRACKSPEED = 0, + D3DXEVENT_TRACKWEIGHT = 1, + D3DXEVENT_TRACKPOSITION = 2, + D3DXEVENT_TRACKENABLE = 3, + D3DXEVENT_PRIORITYBLEND = 4, + + D3DXEVENT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXEVENT_TYPE; + +//---------------------------------------------------------------------------- +// D3DXTRANSITION_TYPE: +// -------------------- +// This enum defines the type of transtion performed on a event that +// transitions from one value to another. +//---------------------------------------------------------------------------- +typedef enum _D3DXTRANSITION_TYPE { + D3DXTRANSITION_LINEAR = 0x000, // Linear transition from one value to the next + D3DXTRANSITION_EASEINEASEOUT = 0x001, // Ease-In Ease-Out spline transtion from one value to the next + + D3DXTRANSITION_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXTRANSITION_TYPE; + +//---------------------------------------------------------------------------- +// D3DXEVENT_DESC: +// --------------- +// This structure describes a animation controller event. +// It gives the event's type, track (if the event is a track event), global +// start time, duration, transition method, and target value. +//---------------------------------------------------------------------------- +typedef struct _D3DXEVENT_DESC +{ + D3DXEVENT_TYPE Type; + UINT Track; + DOUBLE StartTime; + DOUBLE Duration; + D3DXTRANSITION_TYPE Transition; + union + { + FLOAT Weight; + FLOAT Speed; + DOUBLE Position; + BOOL Enable; + }; +} D3DXEVENT_DESC, *LPD3DXEVENT_DESC; + +//---------------------------------------------------------------------------- +// D3DXEVENTHANDLE: +// ---------------- +// Handle values used to efficiently reference animation controller events. +//---------------------------------------------------------------------------- +typedef DWORD D3DXEVENTHANDLE; +typedef D3DXEVENTHANDLE *LPD3DXEVENTHANDLE; + + +//---------------------------------------------------------------------------- +// ID3DXAnimationCallbackHandler: +// ------------------------------ +// This interface is intended to be implemented by the application, and can +// be used to handle callbacks in animation sets generated when +// ID3DXAnimationController::AdvanceTime() is called. +//---------------------------------------------------------------------------- +typedef interface ID3DXAnimationCallbackHandler ID3DXAnimationCallbackHandler; +typedef interface ID3DXAnimationCallbackHandler *LPD3DXANIMATIONCALLBACKHANDLER; + +#undef INTERFACE +#define INTERFACE ID3DXAnimationCallbackHandler + +DECLARE_INTERFACE(ID3DXAnimationCallbackHandler) +{ + //---------------------------------------------------------------------------- + // ID3DXAnimationCallbackHandler::HandleCallback: + // ---------------------------------------------- + // This method gets called when a callback occurs for an animation set in one + // of the tracks during the ID3DXAnimationController::AdvanceTime() call. + // + // Parameters: + // Track + // Index of the track on which the callback occured. + // pCallbackData + // Pointer to user owned callback data. + // + //---------------------------------------------------------------------------- + STDMETHOD(HandleCallback)(THIS_ UINT Track, LPVOID pCallbackData) PURE; +}; + + +//---------------------------------------------------------------------------- +// ID3DXAnimationController: +// ------------------------- +// This interface implements the main animation functionality. It connects +// animation sets with the transform frames that are being animated. Allows +// mixing multiple animations for blended animations or for transistions +// It adds also has methods to modify blending parameters over time to +// enable smooth transistions and other effects. +//---------------------------------------------------------------------------- +typedef interface ID3DXAnimationController ID3DXAnimationController; +typedef interface ID3DXAnimationController *LPD3DXANIMATIONCONTROLLER; + +#undef INTERFACE +#define INTERFACE ID3DXAnimationController + +DECLARE_INTERFACE_(ID3DXAnimationController, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Max sizes + STDMETHOD_(UINT, GetMaxNumAnimationOutputs)(THIS) PURE; + STDMETHOD_(UINT, GetMaxNumAnimationSets)(THIS) PURE; + STDMETHOD_(UINT, GetMaxNumTracks)(THIS) PURE; + STDMETHOD_(UINT, GetMaxNumEvents)(THIS) PURE; + + // Animation output registration + STDMETHOD(RegisterAnimationOutput)(THIS_ + LPCSTR pName, + D3DXMATRIX *pMatrix, + D3DXVECTOR3 *pScale, + D3DXQUATERNION *pRotation, + D3DXVECTOR3 *pTranslation) PURE; + + // Animation set registration + STDMETHOD(RegisterAnimationSet)(THIS_ LPD3DXANIMATIONSET pAnimSet) PURE; + STDMETHOD(UnregisterAnimationSet)(THIS_ LPD3DXANIMATIONSET pAnimSet) PURE; + + STDMETHOD_(UINT, GetNumAnimationSets)(THIS) PURE; + STDMETHOD(GetAnimationSet)(THIS_ UINT Index, LPD3DXANIMATIONSET *ppAnimationSet) PURE; + STDMETHOD(GetAnimationSetByName)(THIS_ LPCSTR szName, LPD3DXANIMATIONSET *ppAnimationSet) PURE; + + // Global time + STDMETHOD(AdvanceTime)(THIS_ DOUBLE TimeDelta, LPD3DXANIMATIONCALLBACKHANDLER pCallbackHandler) PURE; + STDMETHOD(ResetTime)(THIS) PURE; + STDMETHOD_(DOUBLE, GetTime)(THIS) PURE; + + // Tracks + STDMETHOD(SetTrackAnimationSet)(THIS_ UINT Track, LPD3DXANIMATIONSET pAnimSet) PURE; + STDMETHOD(GetTrackAnimationSet)(THIS_ UINT Track, LPD3DXANIMATIONSET *ppAnimSet) PURE; + + STDMETHOD(SetTrackPriority)(THIS_ UINT Track, D3DXPRIORITY_TYPE Priority) PURE; + + STDMETHOD(SetTrackSpeed)(THIS_ UINT Track, FLOAT Speed) PURE; + STDMETHOD(SetTrackWeight)(THIS_ UINT Track, FLOAT Weight) PURE; + STDMETHOD(SetTrackPosition)(THIS_ UINT Track, DOUBLE Position) PURE; + STDMETHOD(SetTrackEnable)(THIS_ UINT Track, BOOL Enable) PURE; + + STDMETHOD(SetTrackDesc)(THIS_ UINT Track, LPD3DXTRACK_DESC pDesc) PURE; + STDMETHOD(GetTrackDesc)(THIS_ UINT Track, LPD3DXTRACK_DESC pDesc) PURE; + + // Priority blending + STDMETHOD(SetPriorityBlend)(THIS_ FLOAT BlendWeight) PURE; + STDMETHOD_(FLOAT, GetPriorityBlend)(THIS) PURE; + + // Event keying + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackSpeed)(THIS_ UINT Track, FLOAT NewSpeed, DOUBLE StartTime, DOUBLE Duration, D3DXTRANSITION_TYPE Transition) PURE; + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackWeight)(THIS_ UINT Track, FLOAT NewWeight, DOUBLE StartTime, DOUBLE Duration, D3DXTRANSITION_TYPE Transition) PURE; + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackPosition)(THIS_ UINT Track, DOUBLE NewPosition, DOUBLE StartTime) PURE; + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackEnable)(THIS_ UINT Track, BOOL NewEnable, DOUBLE StartTime) PURE; + + STDMETHOD_(D3DXEVENTHANDLE, KeyPriorityBlend)(THIS_ FLOAT NewBlendWeight, DOUBLE StartTime, DOUBLE Duration, D3DXTRANSITION_TYPE Transition) PURE; + + // Event unkeying + STDMETHOD(UnkeyEvent)(THIS_ D3DXEVENTHANDLE hEvent) PURE; + + STDMETHOD(UnkeyAllTrackEvents)(THIS_ UINT Track) PURE; + STDMETHOD(UnkeyAllPriorityBlends)(THIS) PURE; + + // Event enumeration + STDMETHOD_(D3DXEVENTHANDLE, GetCurrentTrackEvent)(THIS_ UINT Track, D3DXEVENT_TYPE EventType) PURE; + STDMETHOD_(D3DXEVENTHANDLE, GetCurrentPriorityBlend)(THIS) PURE; + + STDMETHOD_(D3DXEVENTHANDLE, GetUpcomingTrackEvent)(THIS_ UINT Track, D3DXEVENTHANDLE hEvent) PURE; + STDMETHOD_(D3DXEVENTHANDLE, GetUpcomingPriorityBlend)(THIS_ D3DXEVENTHANDLE hEvent) PURE; + + STDMETHOD(ValidateEvent)(THIS_ D3DXEVENTHANDLE hEvent) PURE; + + STDMETHOD(GetEventDesc)(THIS_ D3DXEVENTHANDLE hEvent, LPD3DXEVENT_DESC pDesc) PURE; + + // Cloning + STDMETHOD(CloneAnimationController)(THIS_ + UINT MaxNumAnimationOutputs, + UINT MaxNumAnimationSets, + UINT MaxNumTracks, + UINT MaxNumEvents, + LPD3DXANIMATIONCONTROLLER *ppAnimController) PURE; +}; + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +//---------------------------------------------------------------------------- +// D3DXLoadMeshHierarchyFromX: +// --------------------------- +// Loads the first frame hierarchy in a .X file. +// +// Parameters: +// Filename +// Name of the .X file +// MeshOptions +// Mesh creation options for meshes in the file (see d3dx9mesh.h) +// pD3DDevice +// D3D9 device on which meshes in the file are created in +// pAlloc +// Allocation interface used to allocate nodes of the frame hierarchy +// pUserDataLoader +// Application provided interface to allow loading of user data +// ppFrameHierarchy +// Returns root node pointer of the loaded frame hierarchy +// ppAnimController +// Returns pointer to an animation controller corresponding to animation +// in the .X file. This is created with default max tracks and events +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXLoadMeshHierarchyFromXA + ( + LPCSTR Filename, + DWORD MeshOptions, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXALLOCATEHIERARCHY pAlloc, + LPD3DXLOADUSERDATA pUserDataLoader, + LPD3DXFRAME *ppFrameHierarchy, + LPD3DXANIMATIONCONTROLLER *ppAnimController + ); + +HRESULT WINAPI +D3DXLoadMeshHierarchyFromXW + ( + LPCWSTR Filename, + DWORD MeshOptions, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXALLOCATEHIERARCHY pAlloc, + LPD3DXLOADUSERDATA pUserDataLoader, + LPD3DXFRAME *ppFrameHierarchy, + LPD3DXANIMATIONCONTROLLER *ppAnimController + ); + +#ifdef UNICODE +#define D3DXLoadMeshHierarchyFromX D3DXLoadMeshHierarchyFromXW +#else +#define D3DXLoadMeshHierarchyFromX D3DXLoadMeshHierarchyFromXA +#endif + +HRESULT WINAPI +D3DXLoadMeshHierarchyFromXInMemory + ( + LPCVOID Memory, + DWORD SizeOfMemory, + DWORD MeshOptions, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXALLOCATEHIERARCHY pAlloc, + LPD3DXLOADUSERDATA pUserDataLoader, + LPD3DXFRAME *ppFrameHierarchy, + LPD3DXANIMATIONCONTROLLER *ppAnimController + ); + +//---------------------------------------------------------------------------- +// D3DXSaveMeshHierarchyToFile: +// ---------------------------- +// Creates a .X file and saves the mesh hierarchy and corresponding animations +// in it +// +// Parameters: +// Filename +// Name of the .X file +// XFormat +// Format of the .X file (text or binary, compressed or not, etc) +// pFrameRoot +// Root node of the hierarchy to be saved +// pAnimController +// The animation controller whose animation sets are to be stored +// pUserDataSaver +// Application provided interface to allow adding of user data to +// data objects saved to .X file +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXSaveMeshHierarchyToFileA + ( + LPCSTR Filename, + DWORD XFormat, + CONST D3DXFRAME *pFrameRoot, + LPD3DXANIMATIONCONTROLLER pAnimcontroller, + LPD3DXSAVEUSERDATA pUserDataSaver + ); + +HRESULT WINAPI +D3DXSaveMeshHierarchyToFileW + ( + LPCWSTR Filename, + DWORD XFormat, + CONST D3DXFRAME *pFrameRoot, + LPD3DXANIMATIONCONTROLLER pAnimController, + LPD3DXSAVEUSERDATA pUserDataSaver + ); + +#ifdef UNICODE +#define D3DXSaveMeshHierarchyToFile D3DXSaveMeshHierarchyToFileW +#else +#define D3DXSaveMeshHierarchyToFile D3DXSaveMeshHierarchyToFileA +#endif + +//---------------------------------------------------------------------------- +// D3DXFrameDestroy: +// ----------------- +// Destroys the subtree of frames under the root, including the root +// +// Parameters: +// pFrameRoot +// Pointer to the root node +// pAlloc +// Allocation interface used to de-allocate nodes of the frame hierarchy +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXFrameDestroy + ( + LPD3DXFRAME pFrameRoot, + LPD3DXALLOCATEHIERARCHY pAlloc + ); + +//---------------------------------------------------------------------------- +// D3DXFrameAppendChild: +// --------------------- +// Add a child frame to a frame +// +// Parameters: +// pFrameParent +// Pointer to the parent node +// pFrameChild +// Pointer to the child node +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXFrameAppendChild + ( + LPD3DXFRAME pFrameParent, + CONST D3DXFRAME *pFrameChild + ); + +//---------------------------------------------------------------------------- +// D3DXFrameFind: +// -------------- +// Finds a frame with the given name. Returns NULL if no frame found. +// +// Parameters: +// pFrameRoot +// Pointer to the root node +// Name +// Name of frame to find +// +//---------------------------------------------------------------------------- +LPD3DXFRAME WINAPI +D3DXFrameFind + ( + CONST D3DXFRAME *pFrameRoot, + LPCSTR Name + ); + +//---------------------------------------------------------------------------- +// D3DXFrameRegisterNamedMatrices: +// ------------------------------- +// Finds all frames that have non-null names and registers each of those frame +// matrices to the given animation controller +// +// Parameters: +// pFrameRoot +// Pointer to the root node +// pAnimController +// Pointer to the animation controller where the matrices are registered +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXFrameRegisterNamedMatrices + ( + LPD3DXFRAME pFrameRoot, + LPD3DXANIMATIONCONTROLLER pAnimController + ); + +//---------------------------------------------------------------------------- +// D3DXFrameNumNamedMatrices: +// -------------------------- +// Counts number of frames in a subtree that have non-null names +// +// Parameters: +// pFrameRoot +// Pointer to the root node of the subtree +// Return Value: +// Count of frames +// +//---------------------------------------------------------------------------- +UINT WINAPI +D3DXFrameNumNamedMatrices + ( + CONST D3DXFRAME *pFrameRoot + ); + +//---------------------------------------------------------------------------- +// D3DXFrameCalculateBoundingSphere: +// --------------------------------- +// Computes the bounding sphere of all the meshes in the frame hierarchy. +// +// Parameters: +// pFrameRoot +// Pointer to the root node +// pObjectCenter +// Returns the center of the bounding sphere +// pObjectRadius +// Returns the radius of the bounding sphere +// +//---------------------------------------------------------------------------- +HRESULT WINAPI +D3DXFrameCalculateBoundingSphere + ( + CONST D3DXFRAME *pFrameRoot, + LPD3DXVECTOR3 pObjectCenter, + FLOAT *pObjectRadius + ); + + +//---------------------------------------------------------------------------- +// D3DXCreateKeyframedAnimationSet: +// -------------------------------- +// This function creates a compressable keyframed animations set interface. +// +// Parameters: +// pName +// Name of the animation set +// TicksPerSecond +// Number of keyframe ticks that elapse per second +// Playback +// Playback mode of keyframe looping +// NumAnimations +// Number of SRT animations +// NumCallbackKeys +// Number of callback keys +// pCallbackKeys +// Array of callback keys +// ppAnimationSet +// Returns the animation set interface +// +//----------------------------------------------------------------------------- +HRESULT WINAPI +D3DXCreateKeyframedAnimationSet + ( + LPCSTR pName, + DOUBLE TicksPerSecond, + D3DXPLAYBACK_TYPE Playback, + UINT NumAnimations, + UINT NumCallbackKeys, + CONST D3DXKEY_CALLBACK *pCallbackKeys, + LPD3DXKEYFRAMEDANIMATIONSET *ppAnimationSet + ); + + +//---------------------------------------------------------------------------- +// D3DXCreateCompressedAnimationSet: +// -------------------------------- +// This function creates a compressed animations set interface from +// compressed data. +// +// Parameters: +// pName +// Name of the animation set +// TicksPerSecond +// Number of keyframe ticks that elapse per second +// Playback +// Playback mode of keyframe looping +// pCompressedData +// Compressed animation SRT data +// NumCallbackKeys +// Number of callback keys +// pCallbackKeys +// Array of callback keys +// ppAnimationSet +// Returns the animation set interface +// +//----------------------------------------------------------------------------- +HRESULT WINAPI +D3DXCreateCompressedAnimationSet + ( + LPCSTR pName, + DOUBLE TicksPerSecond, + D3DXPLAYBACK_TYPE Playback, + LPD3DXBUFFER pCompressedData, + UINT NumCallbackKeys, + CONST D3DXKEY_CALLBACK *pCallbackKeys, + LPD3DXCOMPRESSEDANIMATIONSET *ppAnimationSet + ); + + +//---------------------------------------------------------------------------- +// D3DXCreateAnimationController: +// ------------------------------ +// This function creates an animation controller object. +// +// Parameters: +// MaxNumMatrices +// Maximum number of matrices that can be animated +// MaxNumAnimationSets +// Maximum number of animation sets that can be played +// MaxNumTracks +// Maximum number of animation sets that can be blended +// MaxNumEvents +// Maximum number of outstanding events that can be scheduled at any given time +// ppAnimController +// Returns the animation controller interface +// +//----------------------------------------------------------------------------- +HRESULT WINAPI +D3DXCreateAnimationController + ( + UINT MaxNumMatrices, + UINT MaxNumAnimationSets, + UINT MaxNumTracks, + UINT MaxNumEvents, + LPD3DXANIMATIONCONTROLLER *ppAnimController + ); + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX9ANIM_H__ + + diff --git a/builddir/irrlicht-1.8.1/include/d3dx9core.h b/builddir/irrlicht-1.8.1/include/d3dx9core.h new file mode 100644 index 0000000..45243f4 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx9core.h @@ -0,0 +1,753 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9core.h +// Content: D3DX core types and functions +// +/////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9CORE_H__ +#define __D3DX9CORE_H__ + + +/////////////////////////////////////////////////////////////////////////// +// D3DX_SDK_VERSION: +// ----------------- +// This identifier is passed to D3DXCheckVersion in order to ensure that an +// application was built against the correct header files and lib files. +// This number is incremented whenever a header (or other) change would +// require applications to be rebuilt. If the version doesn't match, +// D3DXCheckVersion will return FALSE. (The number itself has no meaning.) +/////////////////////////////////////////////////////////////////////////// + +#define D3DX_VERSION 0x0902 + +#define D3DX_SDK_VERSION 43 + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +BOOL WINAPI + D3DXCheckVersion(UINT D3DSdkVersion, UINT D3DXSdkVersion); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +/////////////////////////////////////////////////////////////////////////// +// D3DXDebugMute +// Mutes D3DX and D3D debug spew (TRUE - mute, FALSE - not mute) +// +// returns previous mute value +// +/////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +BOOL WINAPI + D3DXDebugMute(BOOL Mute); + +#ifdef __cplusplus +} +#endif //__cplusplus + + +/////////////////////////////////////////////////////////////////////////// +// D3DXGetDriverLevel: +// Returns driver version information: +// +// 700 - DX7 level driver +// 800 - DX8 level driver +// 900 - DX9 level driver +/////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +UINT WINAPI + D3DXGetDriverLevel(LPDIRECT3DDEVICE9 pDevice); + +#ifdef __cplusplus +} +#endif //__cplusplus + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXBuffer: +// ------------ +// The buffer object is used by D3DX to return arbitrary size data. +// +// GetBufferPointer - +// Returns a pointer to the beginning of the buffer. +// +// GetBufferSize - +// Returns the size of the buffer, in bytes. +/////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXBuffer ID3DXBuffer; +typedef interface ID3DXBuffer *LPD3DXBUFFER; + +// {8BA5FB08-5195-40e2-AC58-0D989C3A0102} +DEFINE_GUID(IID_ID3DXBuffer, +0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58, 0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2); + +#undef INTERFACE +#define INTERFACE ID3DXBuffer + +DECLARE_INTERFACE_(ID3DXBuffer, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBuffer + STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE; + STDMETHOD_(DWORD, GetBufferSize)(THIS) PURE; +}; + + + +////////////////////////////////////////////////////////////////////////////// +// D3DXSPRITE flags: +// ----------------- +// D3DXSPRITE_DONOTSAVESTATE +// Specifies device state is not to be saved and restored in Begin/End. +// D3DXSPRITE_DONOTMODIFY_RENDERSTATE +// Specifies device render state is not to be changed in Begin. The device +// is assumed to be in a valid state to draw vertices containing POSITION0, +// TEXCOORD0, and COLOR0 data. +// D3DXSPRITE_OBJECTSPACE +// The WORLD, VIEW, and PROJECTION transforms are NOT modified. The +// transforms currently set to the device are used to transform the sprites +// when the batch is drawn (at Flush or End). If this is not specified, +// WORLD, VIEW, and PROJECTION transforms are modified so that sprites are +// drawn in screenspace coordinates. +// D3DXSPRITE_BILLBOARD +// Rotates each sprite about its center so that it is facing the viewer. +// D3DXSPRITE_ALPHABLEND +// Enables ALPHABLEND(SRCALPHA, INVSRCALPHA) and ALPHATEST(alpha > 0). +// ID3DXFont expects this to be set when drawing text. +// D3DXSPRITE_SORT_TEXTURE +// Sprites are sorted by texture prior to drawing. This is recommended when +// drawing non-overlapping sprites of uniform depth. For example, drawing +// screen-aligned text with ID3DXFont. +// D3DXSPRITE_SORT_DEPTH_FRONTTOBACK +// Sprites are sorted by depth front-to-back prior to drawing. This is +// recommended when drawing opaque sprites of varying depths. +// D3DXSPRITE_SORT_DEPTH_BACKTOFRONT +// Sprites are sorted by depth back-to-front prior to drawing. This is +// recommended when drawing transparent sprites of varying depths. +// D3DXSPRITE_DO_NOT_ADDREF_TEXTURE +// Disables calling AddRef() on every draw, and Release() on Flush() for +// better performance. +////////////////////////////////////////////////////////////////////////////// + +#define D3DXSPRITE_DONOTSAVESTATE (1 << 0) +#define D3DXSPRITE_DONOTMODIFY_RENDERSTATE (1 << 1) +#define D3DXSPRITE_OBJECTSPACE (1 << 2) +#define D3DXSPRITE_BILLBOARD (1 << 3) +#define D3DXSPRITE_ALPHABLEND (1 << 4) +#define D3DXSPRITE_SORT_TEXTURE (1 << 5) +#define D3DXSPRITE_SORT_DEPTH_FRONTTOBACK (1 << 6) +#define D3DXSPRITE_SORT_DEPTH_BACKTOFRONT (1 << 7) +#define D3DXSPRITE_DO_NOT_ADDREF_TEXTURE (1 << 8) + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXSprite: +// ------------ +// This object intends to provide an easy way to drawing sprites using D3D. +// +// Begin - +// Prepares device for drawing sprites. +// +// Draw - +// Draws a sprite. Before transformation, the sprite is the size of +// SrcRect, with its top-left corner specified by Position. The color +// and alpha channels are modulated by Color. +// +// Flush - +// Forces all batched sprites to submitted to the device. +// +// End - +// Restores device state to how it was when Begin was called. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXSprite ID3DXSprite; +typedef interface ID3DXSprite *LPD3DXSPRITE; + + +// {BA0B762D-7D28-43ec-B9DC-2F84443B0614} +DEFINE_GUID(IID_ID3DXSprite, +0xba0b762d, 0x7d28, 0x43ec, 0xb9, 0xdc, 0x2f, 0x84, 0x44, 0x3b, 0x6, 0x14); + + +#undef INTERFACE +#define INTERFACE ID3DXSprite + +DECLARE_INTERFACE_(ID3DXSprite, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXSprite + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + + STDMETHOD(GetTransform)(THIS_ D3DXMATRIX *pTransform) PURE; + STDMETHOD(SetTransform)(THIS_ CONST D3DXMATRIX *pTransform) PURE; + + STDMETHOD(SetWorldViewRH)(THIS_ CONST D3DXMATRIX *pWorld, CONST D3DXMATRIX *pView) PURE; + STDMETHOD(SetWorldViewLH)(THIS_ CONST D3DXMATRIX *pWorld, CONST D3DXMATRIX *pView) PURE; + + STDMETHOD(Begin)(THIS_ DWORD Flags) PURE; + STDMETHOD(Draw)(THIS_ LPDIRECT3DTEXTURE9 pTexture, CONST RECT *pSrcRect, CONST D3DXVECTOR3 *pCenter, CONST D3DXVECTOR3 *pPosition, D3DCOLOR Color) PURE; + STDMETHOD(Flush)(THIS) PURE; + STDMETHOD(End)(THIS) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXCreateSprite( + LPDIRECT3DDEVICE9 pDevice, + LPD3DXSPRITE* ppSprite); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFont: +// ---------- +// Font objects contain the textures and resources needed to render a specific +// font on a specific device. +// +// GetGlyphData - +// Returns glyph cache data, for a given glyph. +// +// PreloadCharacters/PreloadGlyphs/PreloadText - +// Preloads glyphs into the glyph cache textures. +// +// DrawText - +// Draws formatted text on a D3D device. Some parameters are +// surprisingly similar to those of GDI's DrawText function. See GDI +// documentation for a detailed description of these parameters. +// If pSprite is NULL, an internal sprite object will be used. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +////////////////////////////////////////////////////////////////////////////// + +typedef struct _D3DXFONT_DESCA +{ + INT Height; + UINT Width; + UINT Weight; + UINT MipLevels; + BOOL Italic; + BYTE CharSet; + BYTE OutputPrecision; + BYTE Quality; + BYTE PitchAndFamily; + CHAR FaceName[LF_FACESIZE]; + +} D3DXFONT_DESCA, *LPD3DXFONT_DESCA; + +typedef struct _D3DXFONT_DESCW +{ + INT Height; + UINT Width; + UINT Weight; + UINT MipLevels; + BOOL Italic; + BYTE CharSet; + BYTE OutputPrecision; + BYTE Quality; + BYTE PitchAndFamily; + WCHAR FaceName[LF_FACESIZE]; + +} D3DXFONT_DESCW, *LPD3DXFONT_DESCW; + +#ifdef UNICODE +typedef D3DXFONT_DESCW D3DXFONT_DESC; +typedef LPD3DXFONT_DESCW LPD3DXFONT_DESC; +#else +typedef D3DXFONT_DESCA D3DXFONT_DESC; +typedef LPD3DXFONT_DESCA LPD3DXFONT_DESC; +#endif + + +typedef interface ID3DXFont ID3DXFont; +typedef interface ID3DXFont *LPD3DXFONT; + + +// {D79DBB70-5F21-4d36-BBC2-FF525C213CDC} +DEFINE_GUID(IID_ID3DXFont, +0xd79dbb70, 0x5f21, 0x4d36, 0xbb, 0xc2, 0xff, 0x52, 0x5c, 0x21, 0x3c, 0xdc); + + +#undef INTERFACE +#define INTERFACE ID3DXFont + +DECLARE_INTERFACE_(ID3DXFont, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXFont + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9 *ppDevice) PURE; + STDMETHOD(GetDescA)(THIS_ D3DXFONT_DESCA *pDesc) PURE; + STDMETHOD(GetDescW)(THIS_ D3DXFONT_DESCW *pDesc) PURE; + STDMETHOD_(BOOL, GetTextMetricsA)(THIS_ TEXTMETRICA *pTextMetrics) PURE; + STDMETHOD_(BOOL, GetTextMetricsW)(THIS_ TEXTMETRICW *pTextMetrics) PURE; + + STDMETHOD_(HDC, GetDC)(THIS) PURE; + STDMETHOD(GetGlyphData)(THIS_ UINT Glyph, LPDIRECT3DTEXTURE9 *ppTexture, RECT *pBlackBox, POINT *pCellInc) PURE; + + STDMETHOD(PreloadCharacters)(THIS_ UINT First, UINT Last) PURE; + STDMETHOD(PreloadGlyphs)(THIS_ UINT First, UINT Last) PURE; + STDMETHOD(PreloadTextA)(THIS_ LPCSTR pString, INT Count) PURE; + STDMETHOD(PreloadTextW)(THIS_ LPCWSTR pString, INT Count) PURE; + + STDMETHOD_(INT, DrawTextA)(THIS_ LPD3DXSPRITE pSprite, LPCSTR pString, INT Count, LPRECT pRect, DWORD Format, D3DCOLOR Color) PURE; + STDMETHOD_(INT, DrawTextW)(THIS_ LPD3DXSPRITE pSprite, LPCWSTR pString, INT Count, LPRECT pRect, DWORD Format, D3DCOLOR Color) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; + +#ifdef __cplusplus +#ifdef UNICODE + HRESULT GetDesc(D3DXFONT_DESCW *pDesc) { return GetDescW(pDesc); } + HRESULT PreloadText(LPCWSTR pString, INT Count) { return PreloadTextW(pString, Count); } +#else + HRESULT GetDesc(D3DXFONT_DESCA *pDesc) { return GetDescA(pDesc); } + HRESULT PreloadText(LPCSTR pString, INT Count) { return PreloadTextA(pString, Count); } +#endif +#endif //__cplusplus +}; + +#ifndef GetTextMetrics +#ifdef UNICODE +#define GetTextMetrics GetTextMetricsW +#else +#define GetTextMetrics GetTextMetricsA +#endif +#endif + +#ifndef DrawText +#ifdef UNICODE +#define DrawText DrawTextW +#else +#define DrawText DrawTextA +#endif +#endif + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +HRESULT WINAPI + D3DXCreateFontA( + LPDIRECT3DDEVICE9 pDevice, + INT Height, + UINT Width, + UINT Weight, + UINT MipLevels, + BOOL Italic, + DWORD CharSet, + DWORD OutputPrecision, + DWORD Quality, + DWORD PitchAndFamily, + LPCSTR pFaceName, + LPD3DXFONT* ppFont); + +HRESULT WINAPI + D3DXCreateFontW( + LPDIRECT3DDEVICE9 pDevice, + INT Height, + UINT Width, + UINT Weight, + UINT MipLevels, + BOOL Italic, + DWORD CharSet, + DWORD OutputPrecision, + DWORD Quality, + DWORD PitchAndFamily, + LPCWSTR pFaceName, + LPD3DXFONT* ppFont); + +#ifdef UNICODE +#define D3DXCreateFont D3DXCreateFontW +#else +#define D3DXCreateFont D3DXCreateFontA +#endif + + +HRESULT WINAPI + D3DXCreateFontIndirectA( + LPDIRECT3DDEVICE9 pDevice, + CONST D3DXFONT_DESCA* pDesc, + LPD3DXFONT* ppFont); + +HRESULT WINAPI + D3DXCreateFontIndirectW( + LPDIRECT3DDEVICE9 pDevice, + CONST D3DXFONT_DESCW* pDesc, + LPD3DXFONT* ppFont); + +#ifdef UNICODE +#define D3DXCreateFontIndirect D3DXCreateFontIndirectW +#else +#define D3DXCreateFontIndirect D3DXCreateFontIndirectA +#endif + + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXRenderToSurface: +// --------------------- +// This object abstracts rendering to surfaces. These surfaces do not +// necessarily need to be render targets. If they are not, a compatible +// render target is used, and the result copied into surface at end scene. +// +// BeginScene, EndScene - +// Call BeginScene() and EndScene() at the beginning and ending of your +// scene. These calls will setup and restore render targets, viewports, +// etc.. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +/////////////////////////////////////////////////////////////////////////// + +typedef struct _D3DXRTS_DESC +{ + UINT Width; + UINT Height; + D3DFORMAT Format; + BOOL DepthStencil; + D3DFORMAT DepthStencilFormat; + +} D3DXRTS_DESC, *LPD3DXRTS_DESC; + + +typedef interface ID3DXRenderToSurface ID3DXRenderToSurface; +typedef interface ID3DXRenderToSurface *LPD3DXRENDERTOSURFACE; + + +// {6985F346-2C3D-43b3-BE8B-DAAE8A03D894} +DEFINE_GUID(IID_ID3DXRenderToSurface, +0x6985f346, 0x2c3d, 0x43b3, 0xbe, 0x8b, 0xda, 0xae, 0x8a, 0x3, 0xd8, 0x94); + + +#undef INTERFACE +#define INTERFACE ID3DXRenderToSurface + +DECLARE_INTERFACE_(ID3DXRenderToSurface, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXRenderToSurface + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(GetDesc)(THIS_ D3DXRTS_DESC* pDesc) PURE; + + STDMETHOD(BeginScene)(THIS_ LPDIRECT3DSURFACE9 pSurface, CONST D3DVIEWPORT9* pViewport) PURE; + STDMETHOD(EndScene)(THIS_ DWORD MipFilter) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXCreateRenderToSurface( + LPDIRECT3DDEVICE9 pDevice, + UINT Width, + UINT Height, + D3DFORMAT Format, + BOOL DepthStencil, + D3DFORMAT DepthStencilFormat, + LPD3DXRENDERTOSURFACE* ppRenderToSurface); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXRenderToEnvMap: +// -------------------- +// This object abstracts rendering to environment maps. These surfaces +// do not necessarily need to be render targets. If they are not, a +// compatible render target is used, and the result copied into the +// environment map at end scene. +// +// BeginCube, BeginSphere, BeginHemisphere, BeginParabolic - +// This function initiates the rendering of the environment map. As +// parameters, you pass the textures in which will get filled in with +// the resulting environment map. +// +// Face - +// Call this function to initiate the drawing of each face. For each +// environment map, you will call this six times.. once for each face +// in D3DCUBEMAP_FACES. +// +// End - +// This will restore all render targets, and if needed compose all the +// rendered faces into the environment map surfaces. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +/////////////////////////////////////////////////////////////////////////// + +typedef struct _D3DXRTE_DESC +{ + UINT Size; + UINT MipLevels; + D3DFORMAT Format; + BOOL DepthStencil; + D3DFORMAT DepthStencilFormat; + +} D3DXRTE_DESC, *LPD3DXRTE_DESC; + + +typedef interface ID3DXRenderToEnvMap ID3DXRenderToEnvMap; +typedef interface ID3DXRenderToEnvMap *LPD3DXRenderToEnvMap; + + +// {313F1B4B-C7B0-4fa2-9D9D-8D380B64385E} +DEFINE_GUID(IID_ID3DXRenderToEnvMap, +0x313f1b4b, 0xc7b0, 0x4fa2, 0x9d, 0x9d, 0x8d, 0x38, 0xb, 0x64, 0x38, 0x5e); + + +#undef INTERFACE +#define INTERFACE ID3DXRenderToEnvMap + +DECLARE_INTERFACE_(ID3DXRenderToEnvMap, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXRenderToEnvMap + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(GetDesc)(THIS_ D3DXRTE_DESC* pDesc) PURE; + + STDMETHOD(BeginCube)(THIS_ + LPDIRECT3DCUBETEXTURE9 pCubeTex) PURE; + + STDMETHOD(BeginSphere)(THIS_ + LPDIRECT3DTEXTURE9 pTex) PURE; + + STDMETHOD(BeginHemisphere)(THIS_ + LPDIRECT3DTEXTURE9 pTexZPos, + LPDIRECT3DTEXTURE9 pTexZNeg) PURE; + + STDMETHOD(BeginParabolic)(THIS_ + LPDIRECT3DTEXTURE9 pTexZPos, + LPDIRECT3DTEXTURE9 pTexZNeg) PURE; + + STDMETHOD(Face)(THIS_ D3DCUBEMAP_FACES Face, DWORD MipFilter) PURE; + STDMETHOD(End)(THIS_ DWORD MipFilter) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXCreateRenderToEnvMap( + LPDIRECT3DDEVICE9 pDevice, + UINT Size, + UINT MipLevels, + D3DFORMAT Format, + BOOL DepthStencil, + D3DFORMAT DepthStencilFormat, + LPD3DXRenderToEnvMap* ppRenderToEnvMap); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXLine: +// ------------ +// This object intends to provide an easy way to draw lines using D3D. +// +// Begin - +// Prepares device for drawing lines +// +// Draw - +// Draws a line strip in screen-space. +// Input is in the form of a array defining points on the line strip. of D3DXVECTOR2 +// +// DrawTransform - +// Draws a line in screen-space with a specified input transformation matrix. +// +// End - +// Restores device state to how it was when Begin was called. +// +// SetPattern - +// Applies a stipple pattern to the line. Input is one 32-bit +// DWORD which describes the stipple pattern. 1 is opaque, 0 is +// transparent. +// +// SetPatternScale - +// Stretches the stipple pattern in the u direction. Input is one +// floating-point value. 0.0f is no scaling, whereas 1.0f doubles +// the length of the stipple pattern. +// +// SetWidth - +// Specifies the thickness of the line in the v direction. Input is +// one floating-point value. +// +// SetAntialias - +// Toggles line antialiasing. Input is a BOOL. +// TRUE = Antialiasing on. +// FALSE = Antialiasing off. +// +// SetGLLines - +// Toggles non-antialiased OpenGL line emulation. Input is a BOOL. +// TRUE = OpenGL line emulation on. +// FALSE = OpenGL line emulation off. +// +// OpenGL line: Regular line: +// *\ *\ +// | \ / \ +// | \ *\ \ +// *\ \ \ \ +// \ \ \ \ +// \ * \ * +// \ | \ / +// \| * +// * +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +/////////////////////////////////////////////////////////////////////////// + + +typedef interface ID3DXLine ID3DXLine; +typedef interface ID3DXLine *LPD3DXLINE; + + +// {D379BA7F-9042-4ac4-9F5E-58192A4C6BD8} +DEFINE_GUID(IID_ID3DXLine, +0xd379ba7f, 0x9042, 0x4ac4, 0x9f, 0x5e, 0x58, 0x19, 0x2a, 0x4c, 0x6b, 0xd8); + +#undef INTERFACE +#define INTERFACE ID3DXLine + +DECLARE_INTERFACE_(ID3DXLine, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXLine + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + + STDMETHOD(Begin)(THIS) PURE; + + STDMETHOD(Draw)(THIS_ CONST D3DXVECTOR2 *pVertexList, + DWORD dwVertexListCount, D3DCOLOR Color) PURE; + + STDMETHOD(DrawTransform)(THIS_ CONST D3DXVECTOR3 *pVertexList, + DWORD dwVertexListCount, CONST D3DXMATRIX* pTransform, + D3DCOLOR Color) PURE; + + STDMETHOD(SetPattern)(THIS_ DWORD dwPattern) PURE; + STDMETHOD_(DWORD, GetPattern)(THIS) PURE; + + STDMETHOD(SetPatternScale)(THIS_ FLOAT fPatternScale) PURE; + STDMETHOD_(FLOAT, GetPatternScale)(THIS) PURE; + + STDMETHOD(SetWidth)(THIS_ FLOAT fWidth) PURE; + STDMETHOD_(FLOAT, GetWidth)(THIS) PURE; + + STDMETHOD(SetAntialias)(THIS_ BOOL bAntialias) PURE; + STDMETHOD_(BOOL, GetAntialias)(THIS) PURE; + + STDMETHOD(SetGLLines)(THIS_ BOOL bGLLines) PURE; + STDMETHOD_(BOOL, GetGLLines)(THIS) PURE; + + STDMETHOD(End)(THIS) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +HRESULT WINAPI + D3DXCreateLine( + LPDIRECT3DDEVICE9 pDevice, + LPD3DXLINE* ppLine); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX9CORE_H__ + diff --git a/builddir/irrlicht-1.8.1/include/d3dx9effect.h b/builddir/irrlicht-1.8.1/include/d3dx9effect.h new file mode 100644 index 0000000..a3bcd30 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx9effect.h @@ -0,0 +1,873 @@ + +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: d3dx9effect.h +// Content: D3DX effect types and Shaders +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9EFFECT_H__ +#define __D3DX9EFFECT_H__ + + +//---------------------------------------------------------------------------- +// D3DXFX_DONOTSAVESTATE +// This flag is used as a parameter to ID3DXEffect::Begin(). When this flag +// is specified, device state is not saved or restored in Begin/End. +// D3DXFX_DONOTSAVESHADERSTATE +// This flag is used as a parameter to ID3DXEffect::Begin(). When this flag +// is specified, shader device state is not saved or restored in Begin/End. +// This includes pixel/vertex shaders and shader constants +// D3DXFX_DONOTSAVESAMPLERSTATE +// This flag is used as a parameter to ID3DXEffect::Begin(). When this flag +// is specified, sampler device state is not saved or restored in Begin/End. +// D3DXFX_NOT_CLONEABLE +// This flag is used as a parameter to the D3DXCreateEffect family of APIs. +// When this flag is specified, the effect will be non-cloneable and will not +// contain any shader binary data. +// Furthermore, GetPassDesc will not return shader function pointers. +// Setting this flag reduces effect memory usage by about 50%. +//---------------------------------------------------------------------------- + +#define D3DXFX_DONOTSAVESTATE (1 << 0) +#define D3DXFX_DONOTSAVESHADERSTATE (1 << 1) +#define D3DXFX_DONOTSAVESAMPLERSTATE (1 << 2) + +#define D3DXFX_NOT_CLONEABLE (1 << 11) +#define D3DXFX_LARGEADDRESSAWARE (1 << 17) + +//---------------------------------------------------------------------------- +// D3DX_PARAMETER_SHARED +// Indicates that the value of a parameter will be shared with all effects +// which share the same namespace. Changing the value in one effect will +// change it in all. +// +// D3DX_PARAMETER_LITERAL +// Indicates that the value of this parameter can be treated as literal. +// Literal parameters can be marked when the effect is compiled, and their +// cannot be changed after the effect is compiled. Shared parameters cannot +// be literal. +//---------------------------------------------------------------------------- + +#define D3DX_PARAMETER_SHARED (1 << 0) +#define D3DX_PARAMETER_LITERAL (1 << 1) +#define D3DX_PARAMETER_ANNOTATION (1 << 2) + +//---------------------------------------------------------------------------- +// D3DXEFFECT_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXEFFECT_DESC +{ + LPCSTR Creator; // Creator string + UINT Parameters; // Number of parameters + UINT Techniques; // Number of techniques + UINT Functions; // Number of function entrypoints + +} D3DXEFFECT_DESC; + + +//---------------------------------------------------------------------------- +// D3DXPARAMETER_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXPARAMETER_DESC +{ + LPCSTR Name; // Parameter name + LPCSTR Semantic; // Parameter semantic + D3DXPARAMETER_CLASS Class; // Class + D3DXPARAMETER_TYPE Type; // Component type + UINT Rows; // Number of rows + UINT Columns; // Number of columns + UINT Elements; // Number of array elements + UINT Annotations; // Number of annotations + UINT StructMembers; // Number of structure member sub-parameters + DWORD Flags; // D3DX_PARAMETER_* flags + UINT Bytes; // Parameter size, in bytes + +} D3DXPARAMETER_DESC; + + +//---------------------------------------------------------------------------- +// D3DXTECHNIQUE_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXTECHNIQUE_DESC +{ + LPCSTR Name; // Technique name + UINT Passes; // Number of passes + UINT Annotations; // Number of annotations + +} D3DXTECHNIQUE_DESC; + + +//---------------------------------------------------------------------------- +// D3DXPASS_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXPASS_DESC +{ + LPCSTR Name; // Pass name + UINT Annotations; // Number of annotations + + CONST DWORD *pVertexShaderFunction; // Vertex shader function + CONST DWORD *pPixelShaderFunction; // Pixel shader function + +} D3DXPASS_DESC; + + +//---------------------------------------------------------------------------- +// D3DXFUNCTION_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXFUNCTION_DESC +{ + LPCSTR Name; // Function name + UINT Annotations; // Number of annotations + +} D3DXFUNCTION_DESC; + + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXEffectPool /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXEffectPool ID3DXEffectPool; +typedef interface ID3DXEffectPool *LPD3DXEFFECTPOOL; + +// {9537AB04-3250-412e-8213-FCD2F8677933} +DEFINE_GUID(IID_ID3DXEffectPool, +0x9537ab04, 0x3250, 0x412e, 0x82, 0x13, 0xfc, 0xd2, 0xf8, 0x67, 0x79, 0x33); + + +#undef INTERFACE +#define INTERFACE ID3DXEffectPool + +DECLARE_INTERFACE_(ID3DXEffectPool, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // No public methods +}; + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXBaseEffect /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXBaseEffect ID3DXBaseEffect; +typedef interface ID3DXBaseEffect *LPD3DXBASEEFFECT; + +// {017C18AC-103F-4417-8C51-6BF6EF1E56BE} +DEFINE_GUID(IID_ID3DXBaseEffect, +0x17c18ac, 0x103f, 0x4417, 0x8c, 0x51, 0x6b, 0xf6, 0xef, 0x1e, 0x56, 0xbe); + + +#undef INTERFACE +#define INTERFACE ID3DXBaseEffect + +DECLARE_INTERFACE_(ID3DXBaseEffect, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Descs + STDMETHOD(GetDesc)(THIS_ D3DXEFFECT_DESC* pDesc) PURE; + STDMETHOD(GetParameterDesc)(THIS_ D3DXHANDLE hParameter, D3DXPARAMETER_DESC* pDesc) PURE; + STDMETHOD(GetTechniqueDesc)(THIS_ D3DXHANDLE hTechnique, D3DXTECHNIQUE_DESC* pDesc) PURE; + STDMETHOD(GetPassDesc)(THIS_ D3DXHANDLE hPass, D3DXPASS_DESC* pDesc) PURE; + STDMETHOD(GetFunctionDesc)(THIS_ D3DXHANDLE hShader, D3DXFUNCTION_DESC* pDesc) PURE; + + // Handle operations + STDMETHOD_(D3DXHANDLE, GetParameter)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterByName)(THIS_ D3DXHANDLE hParameter, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterBySemantic)(THIS_ D3DXHANDLE hParameter, LPCSTR pSemantic) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterElement)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechnique)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechniqueByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetPass)(THIS_ D3DXHANDLE hTechnique, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetPassByName)(THIS_ D3DXHANDLE hTechnique, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetFunction)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetFunctionByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotation)(THIS_ D3DXHANDLE hObject, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotationByName)(THIS_ D3DXHANDLE hObject, LPCSTR pName) PURE; + + // Get/Set Parameters + STDMETHOD(SetValue)(THIS_ D3DXHANDLE hParameter, LPCVOID pData, UINT Bytes) PURE; + STDMETHOD(GetValue)(THIS_ D3DXHANDLE hParameter, LPVOID pData, UINT Bytes) PURE; + STDMETHOD(SetBool)(THIS_ D3DXHANDLE hParameter, BOOL b) PURE; + STDMETHOD(GetBool)(THIS_ D3DXHANDLE hParameter, BOOL* pb) PURE; + STDMETHOD(SetBoolArray)(THIS_ D3DXHANDLE hParameter, CONST BOOL* pb, UINT Count) PURE; + STDMETHOD(GetBoolArray)(THIS_ D3DXHANDLE hParameter, BOOL* pb, UINT Count) PURE; + STDMETHOD(SetInt)(THIS_ D3DXHANDLE hParameter, INT n) PURE; + STDMETHOD(GetInt)(THIS_ D3DXHANDLE hParameter, INT* pn) PURE; + STDMETHOD(SetIntArray)(THIS_ D3DXHANDLE hParameter, CONST INT* pn, UINT Count) PURE; + STDMETHOD(GetIntArray)(THIS_ D3DXHANDLE hParameter, INT* pn, UINT Count) PURE; + STDMETHOD(SetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT f) PURE; + STDMETHOD(GetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT* pf) PURE; + STDMETHOD(SetFloatArray)(THIS_ D3DXHANDLE hParameter, CONST FLOAT* pf, UINT Count) PURE; + STDMETHOD(GetFloatArray)(THIS_ D3DXHANDLE hParameter, FLOAT* pf, UINT Count) PURE; + STDMETHOD(SetVector)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector) PURE; + STDMETHOD(GetVector)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector) PURE; + STDMETHOD(SetVectorArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(GetVectorArray)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(SetMatrix)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrix)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetString)(THIS_ D3DXHANDLE hParameter, LPCSTR pString) PURE; + STDMETHOD(GetString)(THIS_ D3DXHANDLE hParameter, LPCSTR* ppString) PURE; + STDMETHOD(SetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 pTexture) PURE; + STDMETHOD(GetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 *ppTexture) PURE; + STDMETHOD(GetPixelShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DPIXELSHADER9 *ppPShader) PURE; + STDMETHOD(GetVertexShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DVERTEXSHADER9 *ppVShader) PURE; + + //Set Range of an Array to pass to device + //Useful for sending only a subrange of an array down to the device + STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; + +}; + + +//---------------------------------------------------------------------------- +// ID3DXEffectStateManager: +// ------------------------ +// This is a user implemented interface that can be used to manage device +// state changes made by an Effect. +//---------------------------------------------------------------------------- + +typedef interface ID3DXEffectStateManager ID3DXEffectStateManager; +typedef interface ID3DXEffectStateManager *LPD3DXEFFECTSTATEMANAGER; + +// {79AAB587-6DBC-4fa7-82DE-37FA1781C5CE} +DEFINE_GUID(IID_ID3DXEffectStateManager, +0x79aab587, 0x6dbc, 0x4fa7, 0x82, 0xde, 0x37, 0xfa, 0x17, 0x81, 0xc5, 0xce); + +#undef INTERFACE +#define INTERFACE ID3DXEffectStateManager + +DECLARE_INTERFACE_(ID3DXEffectStateManager, IUnknown) +{ + // The user must correctly implement QueryInterface, AddRef, and Release. + + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // The following methods are called by the Effect when it wants to make + // the corresponding device call. Note that: + // 1. Users manage the state and are therefore responsible for making the + // the corresponding device calls themselves inside their callbacks. + // 2. Effects pay attention to the return values of the callbacks, and so + // users must pay attention to what they return in their callbacks. + + STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix) PURE; + STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL9 *pMaterial) PURE; + STDMETHOD(SetLight)(THIS_ DWORD Index, CONST D3DLIGHT9 *pLight) PURE; + STDMETHOD(LightEnable)(THIS_ DWORD Index, BOOL Enable) PURE; + STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State, DWORD Value) PURE; + STDMETHOD(SetTexture)(THIS_ DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture) PURE; + STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) PURE; + STDMETHOD(SetSamplerState)(THIS_ DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) PURE; + STDMETHOD(SetNPatchMode)(THIS_ FLOAT NumSegments) PURE; + STDMETHOD(SetFVF)(THIS_ DWORD FVF) PURE; + STDMETHOD(SetVertexShader)(THIS_ LPDIRECT3DVERTEXSHADER9 pShader) PURE; + STDMETHOD(SetVertexShaderConstantF)(THIS_ UINT RegisterIndex, CONST FLOAT *pConstantData, UINT RegisterCount) PURE; + STDMETHOD(SetVertexShaderConstantI)(THIS_ UINT RegisterIndex, CONST INT *pConstantData, UINT RegisterCount) PURE; + STDMETHOD(SetVertexShaderConstantB)(THIS_ UINT RegisterIndex, CONST BOOL *pConstantData, UINT RegisterCount) PURE; + STDMETHOD(SetPixelShader)(THIS_ LPDIRECT3DPIXELSHADER9 pShader) PURE; + STDMETHOD(SetPixelShaderConstantF)(THIS_ UINT RegisterIndex, CONST FLOAT *pConstantData, UINT RegisterCount) PURE; + STDMETHOD(SetPixelShaderConstantI)(THIS_ UINT RegisterIndex, CONST INT *pConstantData, UINT RegisterCount) PURE; + STDMETHOD(SetPixelShaderConstantB)(THIS_ UINT RegisterIndex, CONST BOOL *pConstantData, UINT RegisterCount) PURE; +}; + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXEffect /////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXEffect ID3DXEffect; +typedef interface ID3DXEffect *LPD3DXEFFECT; + +// {F6CEB4B3-4E4C-40dd-B883-8D8DE5EA0CD5} +DEFINE_GUID(IID_ID3DXEffect, +0xf6ceb4b3, 0x4e4c, 0x40dd, 0xb8, 0x83, 0x8d, 0x8d, 0xe5, 0xea, 0xc, 0xd5); + +#undef INTERFACE +#define INTERFACE ID3DXEffect + +DECLARE_INTERFACE_(ID3DXEffect, ID3DXBaseEffect) +{ + // ID3DXBaseEffect + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Descs + STDMETHOD(GetDesc)(THIS_ D3DXEFFECT_DESC* pDesc) PURE; + STDMETHOD(GetParameterDesc)(THIS_ D3DXHANDLE hParameter, D3DXPARAMETER_DESC* pDesc) PURE; + STDMETHOD(GetTechniqueDesc)(THIS_ D3DXHANDLE hTechnique, D3DXTECHNIQUE_DESC* pDesc) PURE; + STDMETHOD(GetPassDesc)(THIS_ D3DXHANDLE hPass, D3DXPASS_DESC* pDesc) PURE; + STDMETHOD(GetFunctionDesc)(THIS_ D3DXHANDLE hShader, D3DXFUNCTION_DESC* pDesc) PURE; + + // Handle operations + STDMETHOD_(D3DXHANDLE, GetParameter)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterByName)(THIS_ D3DXHANDLE hParameter, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterBySemantic)(THIS_ D3DXHANDLE hParameter, LPCSTR pSemantic) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterElement)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechnique)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechniqueByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetPass)(THIS_ D3DXHANDLE hTechnique, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetPassByName)(THIS_ D3DXHANDLE hTechnique, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetFunction)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetFunctionByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotation)(THIS_ D3DXHANDLE hObject, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotationByName)(THIS_ D3DXHANDLE hObject, LPCSTR pName) PURE; + + // Get/Set Parameters + STDMETHOD(SetValue)(THIS_ D3DXHANDLE hParameter, LPCVOID pData, UINT Bytes) PURE; + STDMETHOD(GetValue)(THIS_ D3DXHANDLE hParameter, LPVOID pData, UINT Bytes) PURE; + STDMETHOD(SetBool)(THIS_ D3DXHANDLE hParameter, BOOL b) PURE; + STDMETHOD(GetBool)(THIS_ D3DXHANDLE hParameter, BOOL* pb) PURE; + STDMETHOD(SetBoolArray)(THIS_ D3DXHANDLE hParameter, CONST BOOL* pb, UINT Count) PURE; + STDMETHOD(GetBoolArray)(THIS_ D3DXHANDLE hParameter, BOOL* pb, UINT Count) PURE; + STDMETHOD(SetInt)(THIS_ D3DXHANDLE hParameter, INT n) PURE; + STDMETHOD(GetInt)(THIS_ D3DXHANDLE hParameter, INT* pn) PURE; + STDMETHOD(SetIntArray)(THIS_ D3DXHANDLE hParameter, CONST INT* pn, UINT Count) PURE; + STDMETHOD(GetIntArray)(THIS_ D3DXHANDLE hParameter, INT* pn, UINT Count) PURE; + STDMETHOD(SetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT f) PURE; + STDMETHOD(GetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT* pf) PURE; + STDMETHOD(SetFloatArray)(THIS_ D3DXHANDLE hParameter, CONST FLOAT* pf, UINT Count) PURE; + STDMETHOD(GetFloatArray)(THIS_ D3DXHANDLE hParameter, FLOAT* pf, UINT Count) PURE; + STDMETHOD(SetVector)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector) PURE; + STDMETHOD(GetVector)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector) PURE; + STDMETHOD(SetVectorArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(GetVectorArray)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(SetMatrix)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrix)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetString)(THIS_ D3DXHANDLE hParameter, LPCSTR pString) PURE; + STDMETHOD(GetString)(THIS_ D3DXHANDLE hParameter, LPCSTR* ppString) PURE; + STDMETHOD(SetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 pTexture) PURE; + STDMETHOD(GetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 *ppTexture) PURE; + STDMETHOD(GetPixelShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DPIXELSHADER9 *ppPShader) PURE; + STDMETHOD(GetVertexShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DVERTEXSHADER9 *ppVShader) PURE; + + //Set Range of an Array to pass to device + //Usefull for sending only a subrange of an array down to the device + STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; + // ID3DXBaseEffect + + + // Pool + STDMETHOD(GetPool)(THIS_ LPD3DXEFFECTPOOL* ppPool) PURE; + + // Selecting and setting a technique + STDMETHOD(SetTechnique)(THIS_ D3DXHANDLE hTechnique) PURE; + STDMETHOD_(D3DXHANDLE, GetCurrentTechnique)(THIS) PURE; + STDMETHOD(ValidateTechnique)(THIS_ D3DXHANDLE hTechnique) PURE; + STDMETHOD(FindNextValidTechnique)(THIS_ D3DXHANDLE hTechnique, D3DXHANDLE *pTechnique) PURE; + STDMETHOD_(BOOL, IsParameterUsed)(THIS_ D3DXHANDLE hParameter, D3DXHANDLE hTechnique) PURE; + + // Using current technique + // Begin starts active technique + // BeginPass begins a pass + // CommitChanges updates changes to any set calls in the pass. This should be called before + // any DrawPrimitive call to d3d + // EndPass ends a pass + // End ends active technique + STDMETHOD(Begin)(THIS_ UINT *pPasses, DWORD Flags) PURE; + STDMETHOD(BeginPass)(THIS_ UINT Pass) PURE; + STDMETHOD(CommitChanges)(THIS) PURE; + STDMETHOD(EndPass)(THIS) PURE; + STDMETHOD(End)(THIS) PURE; + + // Managing D3D Device + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; + + // Logging device calls + STDMETHOD(SetStateManager)(THIS_ LPD3DXEFFECTSTATEMANAGER pManager) PURE; + STDMETHOD(GetStateManager)(THIS_ LPD3DXEFFECTSTATEMANAGER *ppManager) PURE; + + // Parameter blocks + STDMETHOD(BeginParameterBlock)(THIS) PURE; + STDMETHOD_(D3DXHANDLE, EndParameterBlock)(THIS) PURE; + STDMETHOD(ApplyParameterBlock)(THIS_ D3DXHANDLE hParameterBlock) PURE; + STDMETHOD(DeleteParameterBlock)(THIS_ D3DXHANDLE hParameterBlock) PURE; + + // Cloning + STDMETHOD(CloneEffect)(THIS_ LPDIRECT3DDEVICE9 pDevice, LPD3DXEFFECT* ppEffect) PURE; + + // Fast path for setting variables directly in ID3DXEffect + STDMETHOD(SetRawValue)(THIS_ D3DXHANDLE hParameter, LPCVOID pData, UINT ByteOffset, UINT Bytes) PURE; +}; + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXEffectCompiler /////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXEffectCompiler ID3DXEffectCompiler; +typedef interface ID3DXEffectCompiler *LPD3DXEFFECTCOMPILER; + +// {51B8A949-1A31-47e6-BEA0-4B30DB53F1E0} +DEFINE_GUID(IID_ID3DXEffectCompiler, +0x51b8a949, 0x1a31, 0x47e6, 0xbe, 0xa0, 0x4b, 0x30, 0xdb, 0x53, 0xf1, 0xe0); + + +#undef INTERFACE +#define INTERFACE ID3DXEffectCompiler + +DECLARE_INTERFACE_(ID3DXEffectCompiler, ID3DXBaseEffect) +{ + // ID3DXBaseEffect + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Descs + STDMETHOD(GetDesc)(THIS_ D3DXEFFECT_DESC* pDesc) PURE; + STDMETHOD(GetParameterDesc)(THIS_ D3DXHANDLE hParameter, D3DXPARAMETER_DESC* pDesc) PURE; + STDMETHOD(GetTechniqueDesc)(THIS_ D3DXHANDLE hTechnique, D3DXTECHNIQUE_DESC* pDesc) PURE; + STDMETHOD(GetPassDesc)(THIS_ D3DXHANDLE hPass, D3DXPASS_DESC* pDesc) PURE; + STDMETHOD(GetFunctionDesc)(THIS_ D3DXHANDLE hShader, D3DXFUNCTION_DESC* pDesc) PURE; + + // Handle operations + STDMETHOD_(D3DXHANDLE, GetParameter)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterByName)(THIS_ D3DXHANDLE hParameter, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterBySemantic)(THIS_ D3DXHANDLE hParameter, LPCSTR pSemantic) PURE; + STDMETHOD_(D3DXHANDLE, GetParameterElement)(THIS_ D3DXHANDLE hParameter, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechnique)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetTechniqueByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetPass)(THIS_ D3DXHANDLE hTechnique, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetPassByName)(THIS_ D3DXHANDLE hTechnique, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetFunction)(THIS_ UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetFunctionByName)(THIS_ LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotation)(THIS_ D3DXHANDLE hObject, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetAnnotationByName)(THIS_ D3DXHANDLE hObject, LPCSTR pName) PURE; + + // Get/Set Parameters + STDMETHOD(SetValue)(THIS_ D3DXHANDLE hParameter, LPCVOID pData, UINT Bytes) PURE; + STDMETHOD(GetValue)(THIS_ D3DXHANDLE hParameter, LPVOID pData, UINT Bytes) PURE; + STDMETHOD(SetBool)(THIS_ D3DXHANDLE hParameter, BOOL b) PURE; + STDMETHOD(GetBool)(THIS_ D3DXHANDLE hParameter, BOOL* pb) PURE; + STDMETHOD(SetBoolArray)(THIS_ D3DXHANDLE hParameter, CONST BOOL* pb, UINT Count) PURE; + STDMETHOD(GetBoolArray)(THIS_ D3DXHANDLE hParameter, BOOL* pb, UINT Count) PURE; + STDMETHOD(SetInt)(THIS_ D3DXHANDLE hParameter, INT n) PURE; + STDMETHOD(GetInt)(THIS_ D3DXHANDLE hParameter, INT* pn) PURE; + STDMETHOD(SetIntArray)(THIS_ D3DXHANDLE hParameter, CONST INT* pn, UINT Count) PURE; + STDMETHOD(GetIntArray)(THIS_ D3DXHANDLE hParameter, INT* pn, UINT Count) PURE; + STDMETHOD(SetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT f) PURE; + STDMETHOD(GetFloat)(THIS_ D3DXHANDLE hParameter, FLOAT* pf) PURE; + STDMETHOD(SetFloatArray)(THIS_ D3DXHANDLE hParameter, CONST FLOAT* pf, UINT Count) PURE; + STDMETHOD(GetFloatArray)(THIS_ D3DXHANDLE hParameter, FLOAT* pf, UINT Count) PURE; + STDMETHOD(SetVector)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector) PURE; + STDMETHOD(GetVector)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector) PURE; + STDMETHOD(SetVectorArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(GetVectorArray)(THIS_ D3DXHANDLE hParameter, D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(SetMatrix)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrix)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixPointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrixTranspose)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposeArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(GetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hParameter, D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetString)(THIS_ D3DXHANDLE hParameter, LPCSTR pString) PURE; + STDMETHOD(GetString)(THIS_ D3DXHANDLE hParameter, LPCSTR* ppString) PURE; + STDMETHOD(SetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 pTexture) PURE; + STDMETHOD(GetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 *ppTexture) PURE; + STDMETHOD(GetPixelShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DPIXELSHADER9 *ppPShader) PURE; + STDMETHOD(GetVertexShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DVERTEXSHADER9 *ppVShader) PURE; + + //Set Range of an Array to pass to device + //Usefull for sending only a subrange of an array down to the device + STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; + // ID3DXBaseEffect + + // Parameter sharing, specialization, and information + STDMETHOD(SetLiteral)(THIS_ D3DXHANDLE hParameter, BOOL Literal) PURE; + STDMETHOD(GetLiteral)(THIS_ D3DXHANDLE hParameter, BOOL *pLiteral) PURE; + + // Compilation + STDMETHOD(CompileEffect)(THIS_ DWORD Flags, + LPD3DXBUFFER* ppEffect, LPD3DXBUFFER* ppErrorMsgs) PURE; + + STDMETHOD(CompileShader)(THIS_ D3DXHANDLE hFunction, LPCSTR pTarget, DWORD Flags, + LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable) PURE; +}; + + +////////////////////////////////////////////////////////////////////////////// +// APIs ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//---------------------------------------------------------------------------- +// D3DXCreateEffectPool: +// --------------------- +// Creates an effect pool. Pools are used for sharing parameters between +// multiple effects. For all effects within a pool, shared parameters of the +// same name all share the same value. +// +// Parameters: +// ppPool +// Returns the created pool. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateEffectPool( + LPD3DXEFFECTPOOL* ppPool); + + +//---------------------------------------------------------------------------- +// D3DXCreateEffect: +// ----------------- +// Creates an effect from an ascii or binary effect description. +// +// Parameters: +// pDevice +// Pointer of the device on which to create the effect +// pSrcFile +// Name of the file containing the effect description +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module +// pSrcData +// Pointer to effect description +// SrcDataSize +// Size of the effect description in bytes +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// Flags +// See D3DXSHADER_xxx flags. +// pSkipConstants +// A list of semi-colon delimited variable names. The effect will +// not set these variables to the device when they are referenced +// by a shader. NOTE: the variables specified here must be +// register bound in the file and must not be used in expressions +// in passes or samplers or the file will not load. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when compiling +// from file, and will error when compiling from resource or memory. +// pPool +// Pointer to ID3DXEffectPool object to use for shared parameters. +// If NULL, no parameters will be shared. +// ppEffect +// Returns a buffer containing created effect. +// ppCompilationErrors +// Returns a buffer containing any error messages which occurred during +// compile. Or NULL if you do not care about the error messages. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateEffectFromFileA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXCreateEffectFromFileW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXCreateEffectFromFile D3DXCreateEffectFromFileW +#else +#define D3DXCreateEffectFromFile D3DXCreateEffectFromFileA +#endif + + +HRESULT WINAPI + D3DXCreateEffectFromResourceA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXCreateEffectFromResourceW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXCreateEffectFromResource D3DXCreateEffectFromResourceW +#else +#define D3DXCreateEffectFromResource D3DXCreateEffectFromResourceA +#endif + + +HRESULT WINAPI + D3DXCreateEffect( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +// +// Ex functions that accept pSkipConstants in addition to other parameters +// + +HRESULT WINAPI + D3DXCreateEffectFromFileExA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pSkipConstants, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXCreateEffectFromFileExW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pSkipConstants, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXCreateEffectFromFileEx D3DXCreateEffectFromFileExW +#else +#define D3DXCreateEffectFromFileEx D3DXCreateEffectFromFileExA +#endif + + +HRESULT WINAPI + D3DXCreateEffectFromResourceExA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pSkipConstants, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXCreateEffectFromResourceExW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pSkipConstants, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXCreateEffectFromResourceEx D3DXCreateEffectFromResourceExW +#else +#define D3DXCreateEffectFromResourceEx D3DXCreateEffectFromResourceExA +#endif + + +HRESULT WINAPI + D3DXCreateEffectEx( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pSkipConstants, + DWORD Flags, + LPD3DXEFFECTPOOL pPool, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +//---------------------------------------------------------------------------- +// D3DXCreateEffectCompiler: +// ------------------------- +// Creates an effect from an ascii or binary effect description. +// +// Parameters: +// pSrcFile +// Name of the file containing the effect description +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module +// pSrcData +// Pointer to effect description +// SrcDataSize +// Size of the effect description in bytes +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when compiling +// from file, and will error when compiling from resource or memory. +// pPool +// Pointer to ID3DXEffectPool object to use for shared parameters. +// If NULL, no parameters will be shared. +// ppCompiler +// Returns a buffer containing created effect compiler. +// ppParseErrors +// Returns a buffer containing any error messages which occurred during +// parse. Or NULL if you do not care about the error messages. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateEffectCompilerFromFileA( + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTCOMPILER* ppCompiler, + LPD3DXBUFFER* ppParseErrors); + +HRESULT WINAPI + D3DXCreateEffectCompilerFromFileW( + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTCOMPILER* ppCompiler, + LPD3DXBUFFER* ppParseErrors); + +#ifdef UNICODE +#define D3DXCreateEffectCompilerFromFile D3DXCreateEffectCompilerFromFileW +#else +#define D3DXCreateEffectCompilerFromFile D3DXCreateEffectCompilerFromFileA +#endif + + +HRESULT WINAPI + D3DXCreateEffectCompilerFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTCOMPILER* ppCompiler, + LPD3DXBUFFER* ppParseErrors); + +HRESULT WINAPI + D3DXCreateEffectCompilerFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTCOMPILER* ppCompiler, + LPD3DXBUFFER* ppParseErrors); + +#ifdef UNICODE +#define D3DXCreateEffectCompilerFromResource D3DXCreateEffectCompilerFromResourceW +#else +#define D3DXCreateEffectCompilerFromResource D3DXCreateEffectCompilerFromResourceA +#endif + + +HRESULT WINAPI + D3DXCreateEffectCompiler( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXEFFECTCOMPILER* ppCompiler, + LPD3DXBUFFER* ppParseErrors); + +//---------------------------------------------------------------------------- +// D3DXDisassembleEffect: +// ----------------------- +// +// Parameters: +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXDisassembleEffect( + LPD3DXEFFECT pEffect, + BOOL EnableColorCode, + LPD3DXBUFFER *ppDisassembly); + + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX9EFFECT_H__ + + diff --git a/builddir/irrlicht-1.8.1/include/d3dx9math.h b/builddir/irrlicht-1.8.1/include/d3dx9math.h new file mode 100644 index 0000000..3fda053 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx9math.h @@ -0,0 +1,1796 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9math.h +// Content: D3DX math types and functions +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9MATH_H__ +#define __D3DX9MATH_H__ + +#include <math.h> +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning(disable:4201) // anonymous unions warning + + + +//=========================================================================== +// +// General purpose utilities +// +//=========================================================================== +#define D3DX_PI ((FLOAT) 3.141592654f) +#define D3DX_1BYPI ((FLOAT) 0.318309886f) + +#define D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0f)) +#define D3DXToDegree( radian ) ((radian) * (180.0f / D3DX_PI)) + + + +//=========================================================================== +// +// 16 bit floating point numbers +// +//=========================================================================== + +#define D3DX_16F_DIG 3 // # of decimal digits of precision +#define D3DX_16F_EPSILON 4.8875809e-4f // smallest such that 1.0 + epsilon != 1.0 +#define D3DX_16F_MANT_DIG 11 // # of bits in mantissa +#define D3DX_16F_MAX 6.550400e+004 // max value +#define D3DX_16F_MAX_10_EXP 4 // max decimal exponent +#define D3DX_16F_MAX_EXP 15 // max binary exponent +#define D3DX_16F_MIN 6.1035156e-5f // min positive value +#define D3DX_16F_MIN_10_EXP (-4) // min decimal exponent +#define D3DX_16F_MIN_EXP (-14) // min binary exponent +#define D3DX_16F_RADIX 2 // exponent radix +#define D3DX_16F_ROUNDS 1 // addition rounding: near + + +typedef struct D3DXFLOAT16 +{ +#ifdef __cplusplus +public: + D3DXFLOAT16() {}; + D3DXFLOAT16( FLOAT ); + D3DXFLOAT16( CONST D3DXFLOAT16& ); + + // casting + operator FLOAT (); + + // binary operators + BOOL operator == ( CONST D3DXFLOAT16& ) const; + BOOL operator != ( CONST D3DXFLOAT16& ) const; + +protected: +#endif //__cplusplus + WORD value; +} D3DXFLOAT16, *LPD3DXFLOAT16; + + + +//=========================================================================== +// +// Vectors +// +//=========================================================================== + + +//-------------------------- +// 2D Vector +//-------------------------- +typedef struct D3DXVECTOR2 +{ +#ifdef __cplusplus +public: + D3DXVECTOR2() {}; + D3DXVECTOR2( CONST FLOAT * ); + D3DXVECTOR2( CONST D3DXFLOAT16 * ); + D3DXVECTOR2( FLOAT x, FLOAT y ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR2& operator += ( CONST D3DXVECTOR2& ); + D3DXVECTOR2& operator -= ( CONST D3DXVECTOR2& ); + D3DXVECTOR2& operator *= ( FLOAT ); + D3DXVECTOR2& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR2 operator + () const; + D3DXVECTOR2 operator - () const; + + // binary operators + D3DXVECTOR2 operator + ( CONST D3DXVECTOR2& ) const; + D3DXVECTOR2 operator - ( CONST D3DXVECTOR2& ) const; + D3DXVECTOR2 operator * ( FLOAT ) const; + D3DXVECTOR2 operator / ( FLOAT ) const; + + friend D3DXVECTOR2 operator * ( FLOAT, CONST D3DXVECTOR2& ); + + BOOL operator == ( CONST D3DXVECTOR2& ) const; + BOOL operator != ( CONST D3DXVECTOR2& ) const; + + +public: +#endif //__cplusplus + FLOAT x, y; +} D3DXVECTOR2, *LPD3DXVECTOR2; + + + +//-------------------------- +// 2D Vector (16 bit) +//-------------------------- + +typedef struct D3DXVECTOR2_16F +{ +#ifdef __cplusplus +public: + D3DXVECTOR2_16F() {}; + D3DXVECTOR2_16F( CONST FLOAT * ); + D3DXVECTOR2_16F( CONST D3DXFLOAT16 * ); + D3DXVECTOR2_16F( CONST D3DXFLOAT16 &x, CONST D3DXFLOAT16 &y ); + + // casting + operator D3DXFLOAT16* (); + operator CONST D3DXFLOAT16* () const; + + // binary operators + BOOL operator == ( CONST D3DXVECTOR2_16F& ) const; + BOOL operator != ( CONST D3DXVECTOR2_16F& ) const; + +public: +#endif //__cplusplus + D3DXFLOAT16 x, y; + +} D3DXVECTOR2_16F, *LPD3DXVECTOR2_16F; + + + +//-------------------------- +// 3D Vector +//-------------------------- +#ifdef __cplusplus +typedef struct D3DXVECTOR3 : public D3DVECTOR +{ +public: + D3DXVECTOR3() {}; + D3DXVECTOR3( CONST FLOAT * ); + D3DXVECTOR3( CONST D3DVECTOR& ); + D3DXVECTOR3( CONST D3DXFLOAT16 * ); + D3DXVECTOR3( FLOAT x, FLOAT y, FLOAT z ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR3& operator += ( CONST D3DXVECTOR3& ); + D3DXVECTOR3& operator -= ( CONST D3DXVECTOR3& ); + D3DXVECTOR3& operator *= ( FLOAT ); + D3DXVECTOR3& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR3 operator + () const; + D3DXVECTOR3 operator - () const; + + // binary operators + D3DXVECTOR3 operator + ( CONST D3DXVECTOR3& ) const; + D3DXVECTOR3 operator - ( CONST D3DXVECTOR3& ) const; + D3DXVECTOR3 operator * ( FLOAT ) const; + D3DXVECTOR3 operator / ( FLOAT ) const; + + friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3& ); + + BOOL operator == ( CONST D3DXVECTOR3& ) const; + BOOL operator != ( CONST D3DXVECTOR3& ) const; + +} D3DXVECTOR3, *LPD3DXVECTOR3; + +#else //!__cplusplus +typedef struct _D3DVECTOR D3DXVECTOR3, *LPD3DXVECTOR3; +#endif //!__cplusplus + + + +//-------------------------- +// 3D Vector (16 bit) +//-------------------------- +typedef struct D3DXVECTOR3_16F +{ +#ifdef __cplusplus +public: + D3DXVECTOR3_16F() {}; + D3DXVECTOR3_16F( CONST FLOAT * ); + D3DXVECTOR3_16F( CONST D3DVECTOR& ); + D3DXVECTOR3_16F( CONST D3DXFLOAT16 * ); + D3DXVECTOR3_16F( CONST D3DXFLOAT16 &x, CONST D3DXFLOAT16 &y, CONST D3DXFLOAT16 &z ); + + // casting + operator D3DXFLOAT16* (); + operator CONST D3DXFLOAT16* () const; + + // binary operators + BOOL operator == ( CONST D3DXVECTOR3_16F& ) const; + BOOL operator != ( CONST D3DXVECTOR3_16F& ) const; + +public: +#endif //__cplusplus + D3DXFLOAT16 x, y, z; + +} D3DXVECTOR3_16F, *LPD3DXVECTOR3_16F; + + + +//-------------------------- +// 4D Vector +//-------------------------- +typedef struct D3DXVECTOR4 +{ +#ifdef __cplusplus +public: + D3DXVECTOR4() {}; + D3DXVECTOR4( CONST FLOAT* ); + D3DXVECTOR4( CONST D3DXFLOAT16* ); + D3DXVECTOR4( CONST D3DVECTOR& xyz, FLOAT w ); + D3DXVECTOR4( FLOAT x, FLOAT y, FLOAT z, FLOAT w ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR4& operator += ( CONST D3DXVECTOR4& ); + D3DXVECTOR4& operator -= ( CONST D3DXVECTOR4& ); + D3DXVECTOR4& operator *= ( FLOAT ); + D3DXVECTOR4& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR4 operator + () const; + D3DXVECTOR4 operator - () const; + + // binary operators + D3DXVECTOR4 operator + ( CONST D3DXVECTOR4& ) const; + D3DXVECTOR4 operator - ( CONST D3DXVECTOR4& ) const; + D3DXVECTOR4 operator * ( FLOAT ) const; + D3DXVECTOR4 operator / ( FLOAT ) const; + + friend D3DXVECTOR4 operator * ( FLOAT, CONST D3DXVECTOR4& ); + + BOOL operator == ( CONST D3DXVECTOR4& ) const; + BOOL operator != ( CONST D3DXVECTOR4& ) const; + +public: +#endif //__cplusplus + FLOAT x, y, z, w; +} D3DXVECTOR4, *LPD3DXVECTOR4; + + +//-------------------------- +// 4D Vector (16 bit) +//-------------------------- +typedef struct D3DXVECTOR4_16F +{ +#ifdef __cplusplus +public: + D3DXVECTOR4_16F() {}; + D3DXVECTOR4_16F( CONST FLOAT * ); + D3DXVECTOR4_16F( CONST D3DXFLOAT16* ); + D3DXVECTOR4_16F( CONST D3DXVECTOR3_16F& xyz, CONST D3DXFLOAT16& w ); + D3DXVECTOR4_16F( CONST D3DXFLOAT16& x, CONST D3DXFLOAT16& y, CONST D3DXFLOAT16& z, CONST D3DXFLOAT16& w ); + + // casting + operator D3DXFLOAT16* (); + operator CONST D3DXFLOAT16* () const; + + // binary operators + BOOL operator == ( CONST D3DXVECTOR4_16F& ) const; + BOOL operator != ( CONST D3DXVECTOR4_16F& ) const; + +public: +#endif //__cplusplus + D3DXFLOAT16 x, y, z, w; + +} D3DXVECTOR4_16F, *LPD3DXVECTOR4_16F; + + + +//=========================================================================== +// +// Matrices +// +//=========================================================================== +#ifdef __cplusplus +typedef struct D3DXMATRIX : public D3DMATRIX +{ +public: + D3DXMATRIX() {}; + D3DXMATRIX( CONST FLOAT * ); + D3DXMATRIX( CONST D3DMATRIX& ); + D3DXMATRIX( CONST D3DXFLOAT16 * ); + D3DXMATRIX( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, + FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, + FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, + FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ); + + + // access grants + FLOAT& operator () ( UINT Row, UINT Col ); + FLOAT operator () ( UINT Row, UINT Col ) const; + + // casting operators + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXMATRIX& operator *= ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator += ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator -= ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator *= ( FLOAT ); + D3DXMATRIX& operator /= ( FLOAT ); + + // unary operators + D3DXMATRIX operator + () const; + D3DXMATRIX operator - () const; + + // binary operators + D3DXMATRIX operator * ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator + ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator - ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator * ( FLOAT ) const; + D3DXMATRIX operator / ( FLOAT ) const; + + friend D3DXMATRIX operator * ( FLOAT, CONST D3DXMATRIX& ); + + BOOL operator == ( CONST D3DXMATRIX& ) const; + BOOL operator != ( CONST D3DXMATRIX& ) const; + +} D3DXMATRIX, *LPD3DXMATRIX; + +#else //!__cplusplus +typedef struct _D3DMATRIX D3DXMATRIX, *LPD3DXMATRIX; +#endif //!__cplusplus + + +//--------------------------------------------------------------------------- +// Aligned Matrices +// +// This class helps keep matrices 16-byte aligned as preferred by P4 cpus. +// It aligns matrices on the stack and on the heap or in global scope. +// It does this using __declspec(align(16)) which works on VC7 and on VC 6 +// with the processor pack. Unfortunately there is no way to detect the +// latter so this is turned on only on VC7. On other compilers this is the +// the same as D3DXMATRIX. +// +// Using this class on a compiler that does not actually do the alignment +// can be dangerous since it will not expose bugs that ignore alignment. +// E.g if an object of this class in inside a struct or class, and some code +// memcopys data in it assuming tight packing. This could break on a compiler +// that eventually start aligning the matrix. +//--------------------------------------------------------------------------- +#ifdef __cplusplus +typedef struct _D3DXMATRIXA16 : public D3DXMATRIX +{ + _D3DXMATRIXA16() {} + _D3DXMATRIXA16( CONST FLOAT * ); + _D3DXMATRIXA16( CONST D3DMATRIX& ); + _D3DXMATRIXA16( CONST D3DXFLOAT16 * ); + _D3DXMATRIXA16( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, + FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, + FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, + FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ); + + // new operators + void* operator new ( size_t ); + void* operator new[] ( size_t ); + + // delete operators + void operator delete ( void* ); // These are NOT virtual; Do not + void operator delete[] ( void* ); // cast to D3DXMATRIX and delete. + + // assignment operators + _D3DXMATRIXA16& operator = ( CONST D3DXMATRIX& ); + +} _D3DXMATRIXA16; + +#else //!__cplusplus +typedef D3DXMATRIX _D3DXMATRIXA16; +#endif //!__cplusplus + + + +#if _MSC_VER >= 1300 // VC7 +#define D3DX_ALIGN16 __declspec(align(16)) +#else +#define D3DX_ALIGN16 // Earlier compiler may not understand this, do nothing. +#endif + +typedef D3DX_ALIGN16 _D3DXMATRIXA16 D3DXMATRIXA16, *LPD3DXMATRIXA16; + + + +//=========================================================================== +// +// Quaternions +// +//=========================================================================== +typedef struct D3DXQUATERNION +{ +#ifdef __cplusplus +public: + D3DXQUATERNION() {} + D3DXQUATERNION( CONST FLOAT * ); + D3DXQUATERNION( CONST D3DXFLOAT16 * ); + D3DXQUATERNION( FLOAT x, FLOAT y, FLOAT z, FLOAT w ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXQUATERNION& operator += ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator -= ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator *= ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator *= ( FLOAT ); + D3DXQUATERNION& operator /= ( FLOAT ); + + // unary operators + D3DXQUATERNION operator + () const; + D3DXQUATERNION operator - () const; + + // binary operators + D3DXQUATERNION operator + ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator - ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator * ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator * ( FLOAT ) const; + D3DXQUATERNION operator / ( FLOAT ) const; + + friend D3DXQUATERNION operator * (FLOAT, CONST D3DXQUATERNION& ); + + BOOL operator == ( CONST D3DXQUATERNION& ) const; + BOOL operator != ( CONST D3DXQUATERNION& ) const; + +#endif //__cplusplus + FLOAT x, y, z, w; +} D3DXQUATERNION, *LPD3DXQUATERNION; + + +//=========================================================================== +// +// Planes +// +//=========================================================================== +typedef struct D3DXPLANE +{ +#ifdef __cplusplus +public: + D3DXPLANE() {} + D3DXPLANE( CONST FLOAT* ); + D3DXPLANE( CONST D3DXFLOAT16* ); + D3DXPLANE( FLOAT a, FLOAT b, FLOAT c, FLOAT d ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXPLANE& operator *= ( FLOAT ); + D3DXPLANE& operator /= ( FLOAT ); + + // unary operators + D3DXPLANE operator + () const; + D3DXPLANE operator - () const; + + // binary operators + D3DXPLANE operator * ( FLOAT ) const; + D3DXPLANE operator / ( FLOAT ) const; + + friend D3DXPLANE operator * ( FLOAT, CONST D3DXPLANE& ); + + BOOL operator == ( CONST D3DXPLANE& ) const; + BOOL operator != ( CONST D3DXPLANE& ) const; + +#endif //__cplusplus + FLOAT a, b, c, d; +} D3DXPLANE, *LPD3DXPLANE; + + +//=========================================================================== +// +// Colors +// +//=========================================================================== + +typedef struct D3DXCOLOR +{ +#ifdef __cplusplus +public: + D3DXCOLOR() {} + D3DXCOLOR( DWORD argb ); + D3DXCOLOR( CONST FLOAT * ); + D3DXCOLOR( CONST D3DXFLOAT16 * ); + D3DXCOLOR( CONST D3DCOLORVALUE& ); + D3DXCOLOR( FLOAT r, FLOAT g, FLOAT b, FLOAT a ); + + // casting + operator DWORD () const; + + operator FLOAT* (); + operator CONST FLOAT* () const; + + operator D3DCOLORVALUE* (); + operator CONST D3DCOLORVALUE* () const; + + operator D3DCOLORVALUE& (); + operator CONST D3DCOLORVALUE& () const; + + // assignment operators + D3DXCOLOR& operator += ( CONST D3DXCOLOR& ); + D3DXCOLOR& operator -= ( CONST D3DXCOLOR& ); + D3DXCOLOR& operator *= ( FLOAT ); + D3DXCOLOR& operator /= ( FLOAT ); + + // unary operators + D3DXCOLOR operator + () const; + D3DXCOLOR operator - () const; + + // binary operators + D3DXCOLOR operator + ( CONST D3DXCOLOR& ) const; + D3DXCOLOR operator - ( CONST D3DXCOLOR& ) const; + D3DXCOLOR operator * ( FLOAT ) const; + D3DXCOLOR operator / ( FLOAT ) const; + + friend D3DXCOLOR operator * ( FLOAT, CONST D3DXCOLOR& ); + + BOOL operator == ( CONST D3DXCOLOR& ) const; + BOOL operator != ( CONST D3DXCOLOR& ) const; + +#endif //__cplusplus + FLOAT r, g, b, a; +} D3DXCOLOR, *LPD3DXCOLOR; + + + +//=========================================================================== +// +// D3DX math functions: +// +// NOTE: +// * All these functions can take the same object as in and out parameters. +// +// * Out parameters are typically also returned as return values, so that +// the output of one function may be used as a parameter to another. +// +//=========================================================================== + +//-------------------------- +// Float16 +//-------------------------- + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Converts an array 32-bit floats to 16-bit floats +D3DXFLOAT16* WINAPI D3DXFloat32To16Array + ( D3DXFLOAT16 *pOut, CONST FLOAT *pIn, UINT n ); + +// Converts an array 16-bit floats to 32-bit floats +FLOAT* WINAPI D3DXFloat16To32Array + ( FLOAT *pOut, CONST D3DXFLOAT16 *pIn, UINT n ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// 2D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec2Length + ( CONST D3DXVECTOR2 *pV ); + +FLOAT D3DXVec2LengthSq + ( CONST D3DXVECTOR2 *pV ); + +FLOAT D3DXVec2Dot + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Z component of ((x1,y1,0) cross (x2,y2,0)) +FLOAT D3DXVec2CCW + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Add + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Subtract + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2) +D3DXVECTOR2* D3DXVec2Minimize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2) +D3DXVECTOR2* D3DXVec2Maximize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Scale + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, FLOAT s ); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR2* D3DXVec2Lerp + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +D3DXVECTOR2* WINAPI D3DXVec2Normalize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR2* WINAPI D3DXVec2Hermite + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pT1, + CONST D3DXVECTOR2 *pV2, CONST D3DXVECTOR2 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR2* WINAPI D3DXVec2CatmullRom + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV0, CONST D3DXVECTOR2 *pV1, + CONST D3DXVECTOR2 *pV2, CONST D3DXVECTOR2 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR2* WINAPI D3DXVec2BaryCentric + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, + CONST D3DXVECTOR2 *pV3, FLOAT f, FLOAT g); + +// Transform (x, y, 0, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec2Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, 0, 1) by matrix, project result back into w=1. +D3DXVECTOR2* WINAPI D3DXVec2TransformCoord + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, 0, 0) by matrix. +D3DXVECTOR2* WINAPI D3DXVec2TransformNormal + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +// Transform Array (x, y, 0, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec2TransformArray + ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR2 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n); + +// Transform Array (x, y, 0, 1) by matrix, project result back into w=1. +D3DXVECTOR2* WINAPI D3DXVec2TransformCoordArray + ( D3DXVECTOR2 *pOut, UINT OutStride, CONST D3DXVECTOR2 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Transform Array (x, y, 0, 0) by matrix. +D3DXVECTOR2* WINAPI D3DXVec2TransformNormalArray + ( D3DXVECTOR2 *pOut, UINT OutStride, CONST D3DXVECTOR2 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + + + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// 3D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec3Length + ( CONST D3DXVECTOR3 *pV ); + +FLOAT D3DXVec3LengthSq + ( CONST D3DXVECTOR3 *pV ); + +FLOAT D3DXVec3Dot + ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Cross + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Add + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Subtract + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2), ... +D3DXVECTOR3* D3DXVec3Minimize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2), ... +D3DXVECTOR3* D3DXVec3Maximize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Scale + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, FLOAT s); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR3* D3DXVec3Lerp + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +D3DXVECTOR3* WINAPI D3DXVec3Normalize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR3* WINAPI D3DXVec3Hermite + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pT1, + CONST D3DXVECTOR3 *pV2, CONST D3DXVECTOR3 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR3* WINAPI D3DXVec3CatmullRom + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV0, CONST D3DXVECTOR3 *pV1, + CONST D3DXVECTOR3 *pV2, CONST D3DXVECTOR3 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR3* WINAPI D3DXVec3BaryCentric + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + CONST D3DXVECTOR3 *pV3, FLOAT f, FLOAT g); + +// Transform (x, y, z, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec3Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, z, 1) by matrix, project result back into w=1. +D3DXVECTOR3* WINAPI D3DXVec3TransformCoord + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, z, 0) by matrix. If you transforming a normal by a +// non-affine matrix, the matrix you pass to this function should be the +// transpose of the inverse of the matrix you would use to transform a coord. +D3DXVECTOR3* WINAPI D3DXVec3TransformNormal + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + + +// Transform Array (x, y, z, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec3TransformArray + ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Transform Array (x, y, z, 1) by matrix, project result back into w=1. +D3DXVECTOR3* WINAPI D3DXVec3TransformCoordArray + ( D3DXVECTOR3 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Transform (x, y, z, 0) by matrix. If you transforming a normal by a +// non-affine matrix, the matrix you pass to this function should be the +// transpose of the inverse of the matrix you would use to transform a coord. +D3DXVECTOR3* WINAPI D3DXVec3TransformNormalArray + ( D3DXVECTOR3 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +// Project vector from object space into screen space +D3DXVECTOR3* WINAPI D3DXVec3Project + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DVIEWPORT9 *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld); + +// Project vector from screen space into object space +D3DXVECTOR3* WINAPI D3DXVec3Unproject + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DVIEWPORT9 *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld); + +// Project vector Array from object space into screen space +D3DXVECTOR3* WINAPI D3DXVec3ProjectArray + ( D3DXVECTOR3 *pOut, UINT OutStride,CONST D3DXVECTOR3 *pV, UINT VStride,CONST D3DVIEWPORT9 *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld, UINT n); + +// Project vector Array from screen space into object space +D3DXVECTOR3* WINAPI D3DXVec3UnprojectArray + ( D3DXVECTOR3 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DVIEWPORT9 *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld, UINT n); + + +#ifdef __cplusplus +} +#endif + + + +//-------------------------- +// 4D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec4Length + ( CONST D3DXVECTOR4 *pV ); + +FLOAT D3DXVec4LengthSq + ( CONST D3DXVECTOR4 *pV ); + +FLOAT D3DXVec4Dot + ( CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2 ); + +D3DXVECTOR4* D3DXVec4Add + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +D3DXVECTOR4* D3DXVec4Subtract + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2), ... +D3DXVECTOR4* D3DXVec4Minimize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2), ... +D3DXVECTOR4* D3DXVec4Maximize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +D3DXVECTOR4* D3DXVec4Scale + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, FLOAT s); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR4* D3DXVec4Lerp + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Cross-product in 4 dimensions. +D3DXVECTOR4* WINAPI D3DXVec4Cross + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + CONST D3DXVECTOR4 *pV3); + +D3DXVECTOR4* WINAPI D3DXVec4Normalize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR4* WINAPI D3DXVec4Hermite + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pT1, + CONST D3DXVECTOR4 *pV2, CONST D3DXVECTOR4 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR4* WINAPI D3DXVec4CatmullRom + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV0, CONST D3DXVECTOR4 *pV1, + CONST D3DXVECTOR4 *pV2, CONST D3DXVECTOR4 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR4* WINAPI D3DXVec4BaryCentric + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + CONST D3DXVECTOR4 *pV3, FLOAT f, FLOAT g); + +// Transform vector by matrix. +D3DXVECTOR4* WINAPI D3DXVec4Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM ); + +// Transform vector array by matrix. +D3DXVECTOR4* WINAPI D3DXVec4TransformArray + ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR4 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// 4D Matrix +//-------------------------- + +// inline + +D3DXMATRIX* D3DXMatrixIdentity + ( D3DXMATRIX *pOut ); + +BOOL D3DXMatrixIsIdentity + ( CONST D3DXMATRIX *pM ); + + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +FLOAT WINAPI D3DXMatrixDeterminant + ( CONST D3DXMATRIX *pM ); + +HRESULT WINAPI D3DXMatrixDecompose + ( D3DXVECTOR3 *pOutScale, D3DXQUATERNION *pOutRotation, + D3DXVECTOR3 *pOutTranslation, CONST D3DXMATRIX *pM ); + +D3DXMATRIX* WINAPI D3DXMatrixTranspose + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM ); + +// Matrix multiplication. The result represents the transformation M2 +// followed by the transformation M1. (Out = M1 * M2) +D3DXMATRIX* WINAPI D3DXMatrixMultiply + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); + +// Matrix multiplication, followed by a transpose. (Out = T(M1 * M2)) +D3DXMATRIX* WINAPI D3DXMatrixMultiplyTranspose + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); + +// Calculate inverse of matrix. Inversion my fail, in which case NULL will +// be returned. The determinant of pM is also returned it pfDeterminant +// is non-NULL. +D3DXMATRIX* WINAPI D3DXMatrixInverse + ( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM ); + +// Build a matrix which scales by (sx, sy, sz) +D3DXMATRIX* WINAPI D3DXMatrixScaling + ( D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz ); + +// Build a matrix which translates by (x, y, z) +D3DXMATRIX* WINAPI D3DXMatrixTranslation + ( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z ); + +// Build a matrix which rotates around the X axis +D3DXMATRIX* WINAPI D3DXMatrixRotationX + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around the Y axis +D3DXMATRIX* WINAPI D3DXMatrixRotationY + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around the Z axis +D3DXMATRIX* WINAPI D3DXMatrixRotationZ + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around an arbitrary axis +D3DXMATRIX* WINAPI D3DXMatrixRotationAxis + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle ); + +// Build a matrix from a quaternion +D3DXMATRIX* WINAPI D3DXMatrixRotationQuaternion + ( D3DXMATRIX *pOut, CONST D3DXQUATERNION *pQ); + +// Yaw around the Y axis, a pitch around the X axis, +// and a roll around the Z axis. +D3DXMATRIX* WINAPI D3DXMatrixRotationYawPitchRoll + ( D3DXMATRIX *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); + +// Build transformation matrix. NULL arguments are treated as identity. +// Mout = Msc-1 * Msr-1 * Ms * Msr * Msc * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixTransformation + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pScalingCenter, + CONST D3DXQUATERNION *pScalingRotation, CONST D3DXVECTOR3 *pScaling, + CONST D3DXVECTOR3 *pRotationCenter, CONST D3DXQUATERNION *pRotation, + CONST D3DXVECTOR3 *pTranslation); + +// Build 2D transformation matrix in XY plane. NULL arguments are treated as identity. +// Mout = Msc-1 * Msr-1 * Ms * Msr * Msc * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixTransformation2D + ( D3DXMATRIX *pOut, CONST D3DXVECTOR2* pScalingCenter, + FLOAT ScalingRotation, CONST D3DXVECTOR2* pScaling, + CONST D3DXVECTOR2* pRotationCenter, FLOAT Rotation, + CONST D3DXVECTOR2* pTranslation); + +// Build affine transformation matrix. NULL arguments are treated as identity. +// Mout = Ms * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation + ( D3DXMATRIX *pOut, FLOAT Scaling, CONST D3DXVECTOR3 *pRotationCenter, + CONST D3DXQUATERNION *pRotation, CONST D3DXVECTOR3 *pTranslation); + +// Build 2D affine transformation matrix in XY plane. NULL arguments are treated as identity. +// Mout = Ms * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation2D + ( D3DXMATRIX *pOut, FLOAT Scaling, CONST D3DXVECTOR2* pRotationCenter, + FLOAT Rotation, CONST D3DXVECTOR2* pTranslation); + +// Build a lookat matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixLookAtRH + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, + CONST D3DXVECTOR3 *pUp ); + +// Build a lookat matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixLookAtLH + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, + CONST D3DXVECTOR3 *pUp ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveRH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveLH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovRH + ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovLH + ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterRH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterLH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build an ortho projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoRH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build an ortho projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoLH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build an ortho projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterRH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build an ortho projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterLH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build a matrix which flattens geometry into a plane, as if casting +// a shadow from a light. +D3DXMATRIX* WINAPI D3DXMatrixShadow + ( D3DXMATRIX *pOut, CONST D3DXVECTOR4 *pLight, + CONST D3DXPLANE *pPlane ); + +// Build a matrix which reflects the coordinate system about a plane +D3DXMATRIX* WINAPI D3DXMatrixReflect + ( D3DXMATRIX *pOut, CONST D3DXPLANE *pPlane ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Quaternion +//-------------------------- + +// inline + +FLOAT D3DXQuaternionLength + ( CONST D3DXQUATERNION *pQ ); + +// Length squared, or "norm" +FLOAT D3DXQuaternionLengthSq + ( CONST D3DXQUATERNION *pQ ); + +FLOAT D3DXQuaternionDot + ( CONST D3DXQUATERNION *pQ1, CONST D3DXQUATERNION *pQ2 ); + +// (0, 0, 0, 1) +D3DXQUATERNION* D3DXQuaternionIdentity + ( D3DXQUATERNION *pOut ); + +BOOL D3DXQuaternionIsIdentity + ( CONST D3DXQUATERNION *pQ ); + +// (-x, -y, -z, w) +D3DXQUATERNION* D3DXQuaternionConjugate + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Compute a quaternin's axis and angle of rotation. Expects unit quaternions. +void WINAPI D3DXQuaternionToAxisAngle + ( CONST D3DXQUATERNION *pQ, D3DXVECTOR3 *pAxis, FLOAT *pAngle ); + +// Build a quaternion from a rotation matrix. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationMatrix + ( D3DXQUATERNION *pOut, CONST D3DXMATRIX *pM); + +// Rotation about arbitrary axis. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis + ( D3DXQUATERNION *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle ); + +// Yaw around the Y axis, a pitch around the X axis, +// and a roll around the Z axis. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationYawPitchRoll + ( D3DXQUATERNION *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); + +// Quaternion multiplication. The result represents the rotation Q2 +// followed by the rotation Q1. (Out = Q2 * Q1) +D3DXQUATERNION* WINAPI D3DXQuaternionMultiply + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2 ); + +D3DXQUATERNION* WINAPI D3DXQuaternionNormalize + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Conjugate and re-norm +D3DXQUATERNION* WINAPI D3DXQuaternionInverse + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Expects unit quaternions. +// if q = (cos(theta), sin(theta) * v); ln(q) = (0, theta * v) +D3DXQUATERNION* WINAPI D3DXQuaternionLn + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Expects pure quaternions. (w == 0) w is ignored in calculation. +// if q = (0, theta * v); exp(q) = (cos(theta), sin(theta) * v) +D3DXQUATERNION* WINAPI D3DXQuaternionExp + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Spherical linear interpolation between Q1 (t == 0) and Q2 (t == 1). +// Expects unit quaternions. +D3DXQUATERNION* WINAPI D3DXQuaternionSlerp + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, FLOAT t ); + +// Spherical quadrangle interpolation. +// Slerp(Slerp(Q1, C, t), Slerp(A, B, t), 2t(1-t)) +D3DXQUATERNION* WINAPI D3DXQuaternionSquad + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pA, CONST D3DXQUATERNION *pB, + CONST D3DXQUATERNION *pC, FLOAT t ); + +// Setup control points for spherical quadrangle interpolation +// from Q1 to Q2. The control points are chosen in such a way +// to ensure the continuity of tangents with adjacent segments. +void WINAPI D3DXQuaternionSquadSetup + ( D3DXQUATERNION *pAOut, D3DXQUATERNION *pBOut, D3DXQUATERNION *pCOut, + CONST D3DXQUATERNION *pQ0, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, CONST D3DXQUATERNION *pQ3 ); + +// Barycentric interpolation. +// Slerp(Slerp(Q1, Q2, f+g), Slerp(Q1, Q3, f+g), g/(f+g)) +D3DXQUATERNION* WINAPI D3DXQuaternionBaryCentric + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, CONST D3DXQUATERNION *pQ3, + FLOAT f, FLOAT g ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Plane +//-------------------------- + +// inline + +// ax + by + cz + dw +FLOAT D3DXPlaneDot + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR4 *pV); + +// ax + by + cz + d +FLOAT D3DXPlaneDotCoord + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV); + +// ax + by + cz +FLOAT D3DXPlaneDotNormal + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV); + +D3DXPLANE* D3DXPlaneScale + (D3DXPLANE *pOut, CONST D3DXPLANE *pP, FLOAT s); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Normalize plane (so that |a,b,c| == 1) +D3DXPLANE* WINAPI D3DXPlaneNormalize + ( D3DXPLANE *pOut, CONST D3DXPLANE *pP); + +// Find the intersection between a plane and a line. If the line is +// parallel to the plane, NULL is returned. +D3DXVECTOR3* WINAPI D3DXPlaneIntersectLine + ( D3DXVECTOR3 *pOut, CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV1, + CONST D3DXVECTOR3 *pV2); + +// Construct a plane from a point and a normal +D3DXPLANE* WINAPI D3DXPlaneFromPointNormal + ( D3DXPLANE *pOut, CONST D3DXVECTOR3 *pPoint, CONST D3DXVECTOR3 *pNormal); + +// Construct a plane from 3 points +D3DXPLANE* WINAPI D3DXPlaneFromPoints + ( D3DXPLANE *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + CONST D3DXVECTOR3 *pV3); + +// Transform a plane by a matrix. The vector (a,b,c) must be normal. +// M should be the inverse transpose of the transformation desired. +D3DXPLANE* WINAPI D3DXPlaneTransform + ( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM ); + +// Transform an array of planes by a matrix. The vectors (a,b,c) must be normal. +// M should be the inverse transpose of the transformation desired. +D3DXPLANE* WINAPI D3DXPlaneTransformArray + ( D3DXPLANE *pOut, UINT OutStride, CONST D3DXPLANE *pP, UINT PStride, CONST D3DXMATRIX *pM, UINT n ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Color +//-------------------------- + +// inline + +// (1-r, 1-g, 1-b, a) +D3DXCOLOR* D3DXColorNegative + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC); + +D3DXCOLOR* D3DXColorAdd + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +D3DXCOLOR* D3DXColorSubtract + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +D3DXCOLOR* D3DXColorScale + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s); + +// (r1*r2, g1*g2, b1*b2, a1*a2) +D3DXCOLOR* D3DXColorModulate + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +// Linear interpolation of r,g,b, and a. C1 + s(C2-C1) +D3DXCOLOR* D3DXColorLerp + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2, FLOAT s); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Interpolate r,g,b between desaturated color and color. +// DesaturatedColor + s(Color - DesaturatedColor) +D3DXCOLOR* WINAPI D3DXColorAdjustSaturation + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s); + +// Interpolate r,g,b between 50% grey and color. Grey + s(Color - Grey) +D3DXCOLOR* WINAPI D3DXColorAdjustContrast + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT c); + +#ifdef __cplusplus +} +#endif + + + + +//-------------------------- +// Misc +//-------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +// Calculate Fresnel term given the cosine of theta (likely obtained by +// taking the dot of two normals), and the refraction index of the material. +FLOAT WINAPI D3DXFresnelTerm + (FLOAT CosTheta, FLOAT RefractionIndex); + +#ifdef __cplusplus +} +#endif + + + +//=========================================================================== +// +// Matrix Stack +// +//=========================================================================== + +typedef interface ID3DXMatrixStack ID3DXMatrixStack; +typedef interface ID3DXMatrixStack *LPD3DXMATRIXSTACK; + +// {C7885BA7-F990-4fe7-922D-8515E477DD85} +DEFINE_GUID(IID_ID3DXMatrixStack, +0xc7885ba7, 0xf990, 0x4fe7, 0x92, 0x2d, 0x85, 0x15, 0xe4, 0x77, 0xdd, 0x85); + + +#undef INTERFACE +#define INTERFACE ID3DXMatrixStack + +DECLARE_INTERFACE_(ID3DXMatrixStack, IUnknown) +{ + // + // IUnknown methods + // + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + // + // ID3DXMatrixStack methods + // + + // Pops the top of the stack, returns the current top + // *after* popping the top. + STDMETHOD(Pop)(THIS) PURE; + + // Pushes the stack by one, duplicating the current matrix. + STDMETHOD(Push)(THIS) PURE; + + // Loads identity in the current matrix. + STDMETHOD(LoadIdentity)(THIS) PURE; + + // Loads the given matrix into the current matrix + STDMETHOD(LoadMatrix)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Right-Multiplies the given matrix to the current matrix. + // (transformation is about the current world origin) + STDMETHOD(MultMatrix)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Left-Multiplies the given matrix to the current matrix + // (transformation is about the local origin of the object) + STDMETHOD(MultMatrixLocal)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Right multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the current world origin) + STDMETHOD(RotateAxis) + (THIS_ CONST D3DXVECTOR3* pV, FLOAT Angle) PURE; + + // Left multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the local origin of the object) + STDMETHOD(RotateAxisLocal) + (THIS_ CONST D3DXVECTOR3* pV, FLOAT Angle) PURE; + + // Right multiply the current matrix with the computed rotation + // matrix. All angles are counterclockwise. (rotation is about the + // current world origin) + + // The rotation is composed of a yaw around the Y axis, a pitch around + // the X axis, and a roll around the Z axis. + STDMETHOD(RotateYawPitchRoll) + (THIS_ FLOAT Yaw, FLOAT Pitch, FLOAT Roll) PURE; + + // Left multiply the current matrix with the computed rotation + // matrix. All angles are counterclockwise. (rotation is about the + // local origin of the object) + + // The rotation is composed of a yaw around the Y axis, a pitch around + // the X axis, and a roll around the Z axis. + STDMETHOD(RotateYawPitchRollLocal) + (THIS_ FLOAT Yaw, FLOAT Pitch, FLOAT Roll) PURE; + + // Right multiply the current matrix with the computed scale + // matrix. (transformation is about the current world origin) + STDMETHOD(Scale)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + // Left multiply the current matrix with the computed scale + // matrix. (transformation is about the local origin of the object) + STDMETHOD(ScaleLocal)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + // Right multiply the current matrix with the computed translation + // matrix. (transformation is about the current world origin) + STDMETHOD(Translate)(THIS_ FLOAT x, FLOAT y, FLOAT z ) PURE; + + // Left multiply the current matrix with the computed translation + // matrix. (transformation is about the local origin of the object) + STDMETHOD(TranslateLocal)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + // Obtain the current matrix at the top of the stack + STDMETHOD_(D3DXMATRIX*, GetTop)(THIS) PURE; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT WINAPI + D3DXCreateMatrixStack( + DWORD Flags, + LPD3DXMATRIXSTACK* ppStack); + +#ifdef __cplusplus +} +#endif + +//=========================================================================== +// +// Spherical Harmonic Runtime Routines +// +// NOTE: +// * Most of these functions can take the same object as in and out parameters. +// The exceptions are the rotation functions. +// +// * Out parameters are typically also returned as return values, so that +// the output of one function may be used as a parameter to another. +// +//============================================================================ + + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================ +// +// Basic Spherical Harmonic math routines +// +//============================================================================ + +#define D3DXSH_MINORDER 2 +#define D3DXSH_MAXORDER 6 + +//============================================================================ +// +// D3DXSHEvalDirection: +// -------------------- +// Evaluates the Spherical Harmonic basis functions +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Direction to evaluate in - assumed to be normalized +// +//============================================================================ + +FLOAT* WINAPI D3DXSHEvalDirection + ( FLOAT *pOut, UINT Order, CONST D3DXVECTOR3 *pDir ); + +//============================================================================ +// +// D3DXSHRotate: +// -------------------- +// Rotates SH vector by a rotation matrix +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned (should not alias with pIn.) +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pMatrix +// Matrix used for rotation - rotation sub matrix should be orthogonal +// and have a unit determinant. +// pIn +// Input SH coeffs (rotated), incorect results if this is also output. +// +//============================================================================ + +FLOAT* WINAPI D3DXSHRotate + ( FLOAT *pOut, UINT Order, CONST D3DXMATRIX *pMatrix, CONST FLOAT *pIn ); + +//============================================================================ +// +// D3DXSHRotateZ: +// -------------------- +// Rotates the SH vector in the Z axis by an angle +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned (should not alias with pIn.) +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// Angle +// Angle in radians to rotate around the Z axis. +// pIn +// Input SH coeffs (rotated), incorect results if this is also output. +// +//============================================================================ + + +FLOAT* WINAPI D3DXSHRotateZ + ( FLOAT *pOut, UINT Order, FLOAT Angle, CONST FLOAT *pIn ); + +//============================================================================ +// +// D3DXSHAdd: +// -------------------- +// Adds two SH vectors, pOut[i] = pA[i] + pB[i]; +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pA +// Input SH coeffs. +// pB +// Input SH coeffs (second vector.) +// +//============================================================================ + +FLOAT* WINAPI D3DXSHAdd + ( FLOAT *pOut, UINT Order, CONST FLOAT *pA, CONST FLOAT *pB ); + +//============================================================================ +// +// D3DXSHScale: +// -------------------- +// Adds two SH vectors, pOut[i] = pA[i]*Scale; +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pIn +// Input SH coeffs. +// Scale +// Scale factor. +// +//============================================================================ + +FLOAT* WINAPI D3DXSHScale + ( FLOAT *pOut, UINT Order, CONST FLOAT *pIn, CONST FLOAT Scale ); + +//============================================================================ +// +// D3DXSHDot: +// -------------------- +// Computes the dot product of two SH vectors +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pA +// Input SH coeffs. +// pB +// Second set of input SH coeffs. +// +//============================================================================ + +FLOAT WINAPI D3DXSHDot + ( UINT Order, CONST FLOAT *pA, CONST FLOAT *pB ); + +//============================================================================ +// +// D3DXSHMultiply[O]: +// -------------------- +// Computes the product of two functions represented using SH (f and g), where: +// pOut[i] = int(y_i(s) * f(s) * g(s)), where y_i(s) is the ith SH basis +// function, f(s) and g(s) are SH functions (sum_i(y_i(s)*c_i)). The order O +// determines the lengths of the arrays, where there should always be O^2 +// coefficients. In general the product of two SH functions of order O generates +// and SH function of order 2*O - 1, but we truncate the result. This means +// that the product commutes (f*g == g*f) but doesn't associate +// (f*(g*h) != (f*g)*h. +// +// Parameters: +// pOut +// Output SH coefficients - basis function Ylm is stored at l*l + m+l +// This is the pointer that is returned. +// pF +// Input SH coeffs for first function. +// pG +// Second set of input SH coeffs. +// +//============================================================================ + +FLOAT* WINAPI D3DXSHMultiply2( FLOAT *pOut, CONST FLOAT *pF, CONST FLOAT *pG); +FLOAT* WINAPI D3DXSHMultiply3( FLOAT *pOut, CONST FLOAT *pF, CONST FLOAT *pG); +FLOAT* WINAPI D3DXSHMultiply4( FLOAT *pOut, CONST FLOAT *pF, CONST FLOAT *pG); +FLOAT* WINAPI D3DXSHMultiply5( FLOAT *pOut, CONST FLOAT *pF, CONST FLOAT *pG); +FLOAT* WINAPI D3DXSHMultiply6( FLOAT *pOut, CONST FLOAT *pF, CONST FLOAT *pG); + + +//============================================================================ +// +// Basic Spherical Harmonic lighting routines +// +//============================================================================ + +//============================================================================ +// +// D3DXSHEvalDirectionalLight: +// -------------------- +// Evaluates a directional light and returns spectral SH data. The output +// vector is computed so that if the intensity of R/G/B is unit the resulting +// exit radiance of a point directly under the light on a diffuse object with +// an albedo of 1 would be 1.0. This will compute 3 spectral samples, pROut +// has to be specified, while pGout and pBout are optional. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Direction light is coming from (assumed to be normalized.) +// RIntensity +// Red intensity of light. +// GIntensity +// Green intensity of light. +// BIntensity +// Blue intensity of light. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green (optional.) +// pBOut +// Output SH vector for Blue (optional.) +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalDirectionalLight + ( UINT Order, CONST D3DXVECTOR3 *pDir, + FLOAT RIntensity, FLOAT GIntensity, FLOAT BIntensity, + FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); + +//============================================================================ +// +// D3DXSHEvalSphericalLight: +// -------------------- +// Evaluates a spherical light and returns spectral SH data. There is no +// normalization of the intensity of the light like there is for directional +// lights, care has to be taken when specifiying the intensities. This will +// compute 3 spectral samples, pROut has to be specified, while pGout and +// pBout are optional. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pPos +// Position of light - reciever is assumed to be at the origin. +// Radius +// Radius of the spherical light source. +// RIntensity +// Red intensity of light. +// GIntensity +// Green intensity of light. +// BIntensity +// Blue intensity of light. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green (optional.) +// pBOut +// Output SH vector for Blue (optional.) +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalSphericalLight + ( UINT Order, CONST D3DXVECTOR3 *pPos, FLOAT Radius, + FLOAT RIntensity, FLOAT GIntensity, FLOAT BIntensity, + FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); + +//============================================================================ +// +// D3DXSHEvalConeLight: +// -------------------- +// Evaluates a light that is a cone of constant intensity and returns spectral +// SH data. The output vector is computed so that if the intensity of R/G/B is +// unit the resulting exit radiance of a point directly under the light oriented +// in the cone direction on a diffuse object with an albedo of 1 would be 1.0. +// This will compute 3 spectral samples, pROut has to be specified, while pGout +// and pBout are optional. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Direction light is coming from (assumed to be normalized.) +// Radius +// Radius of cone in radians. +// RIntensity +// Red intensity of light. +// GIntensity +// Green intensity of light. +// BIntensity +// Blue intensity of light. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green (optional.) +// pBOut +// Output SH vector for Blue (optional.) +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalConeLight + ( UINT Order, CONST D3DXVECTOR3 *pDir, FLOAT Radius, + FLOAT RIntensity, FLOAT GIntensity, FLOAT BIntensity, + FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); + +//============================================================================ +// +// D3DXSHEvalHemisphereLight: +// -------------------- +// Evaluates a light that is a linear interpolant between two colors over the +// sphere. The interpolant is linear along the axis of the two points, not +// over the surface of the sphere (ie: if the axis was (0,0,1) it is linear in +// Z, not in the azimuthal angle.) The resulting spherical lighting function +// is normalized so that a point on a perfectly diffuse surface with no +// shadowing and a normal pointed in the direction pDir would result in exit +// radiance with a value of 1 if the top color was white and the bottom color +// was black. This is a very simple model where Top represents the intensity +// of the "sky" and Bottom represents the intensity of the "ground". +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pDir +// Axis of the hemisphere. +// Top +// Color of the upper hemisphere. +// Bottom +// Color of the lower hemisphere. +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green +// pBOut +// Output SH vector for Blue +// +//============================================================================ + +HRESULT WINAPI D3DXSHEvalHemisphereLight + ( UINT Order, CONST D3DXVECTOR3 *pDir, D3DXCOLOR Top, D3DXCOLOR Bottom, + FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); + +//============================================================================ +// +// Basic Spherical Harmonic projection routines +// +//============================================================================ + +//============================================================================ +// +// D3DXSHProjectCubeMap: +// -------------------- +// Projects a function represented on a cube map into spherical harmonics. +// +// Parameters: +// Order +// Order of the SH evaluation, generates Order^2 coefs, degree is Order-1 +// pCubeMap +// CubeMap that is going to be projected into spherical harmonics +// pROut +// Output SH vector for Red. +// pGOut +// Output SH vector for Green +// pBOut +// Output SH vector for Blue +// +//============================================================================ + +HRESULT WINAPI D3DXSHProjectCubeMap + ( UINT uOrder, LPDIRECT3DCUBETEXTURE9 pCubeMap, + FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); + + +#ifdef __cplusplus +} +#endif + + +#include "d3dx9math.inl" + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#else +#pragma warning(default:4201) +#endif + +#endif // __D3DX9MATH_H__ + diff --git a/builddir/irrlicht-1.8.1/include/d3dx9math.inl b/builddir/irrlicht-1.8.1/include/d3dx9math.inl new file mode 100644 index 0000000..a3652ed --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx9math.inl @@ -0,0 +1,2251 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9math.inl +// Content: D3DX math inline functions +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX9MATH_INL__ +#define __D3DX9MATH_INL__ + +//=========================================================================== +// +// Inline Class Methods +// +//=========================================================================== + +#ifdef __cplusplus + +//-------------------------- +// Float16 +//-------------------------- + +D3DXINLINE +D3DXFLOAT16::D3DXFLOAT16( FLOAT f ) +{ + D3DXFloat32To16Array(this, &f, 1); +} + +D3DXINLINE +D3DXFLOAT16::D3DXFLOAT16( CONST D3DXFLOAT16& f ) +{ + value = f.value; +} + +// casting +D3DXINLINE +D3DXFLOAT16::operator FLOAT () +{ + FLOAT f; + D3DXFloat16To32Array(&f, this, 1); + return f; +} + +// binary operators +D3DXINLINE BOOL +D3DXFLOAT16::operator == ( CONST D3DXFLOAT16& f ) const +{ + return value == f.value; +} + +D3DXINLINE BOOL +D3DXFLOAT16::operator != ( CONST D3DXFLOAT16& f ) const +{ + return value != f.value; +} + + +//-------------------------- +// 2D Vector +//-------------------------- + +D3DXINLINE +D3DXVECTOR2::D3DXVECTOR2( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; +} + +D3DXINLINE +D3DXVECTOR2::D3DXVECTOR2( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 2); +} + +D3DXINLINE +D3DXVECTOR2::D3DXVECTOR2( FLOAT fx, FLOAT fy ) +{ + x = fx; + y = fy; +} + + +// casting +D3DXINLINE +D3DXVECTOR2::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DXINLINE +D3DXVECTOR2::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DXINLINE D3DXVECTOR2& +D3DXVECTOR2::operator += ( CONST D3DXVECTOR2& v ) +{ + x += v.x; + y += v.y; + return *this; +} + +D3DXINLINE D3DXVECTOR2& +D3DXVECTOR2::operator -= ( CONST D3DXVECTOR2& v ) +{ + x -= v.x; + y -= v.y; + return *this; +} + +D3DXINLINE D3DXVECTOR2& +D3DXVECTOR2::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + return *this; +} + +D3DXINLINE D3DXVECTOR2& +D3DXVECTOR2::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator - () const +{ + return D3DXVECTOR2(-x, -y); +} + + +// binary operators +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator + ( CONST D3DXVECTOR2& v ) const +{ + return D3DXVECTOR2(x + v.x, y + v.y); +} + +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator - ( CONST D3DXVECTOR2& v ) const +{ + return D3DXVECTOR2(x - v.x, y - v.y); +} + +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator * ( FLOAT f ) const +{ + return D3DXVECTOR2(x * f, y * f); +} + +D3DXINLINE D3DXVECTOR2 +D3DXVECTOR2::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXVECTOR2(x * fInv, y * fInv); +} + +D3DXINLINE D3DXVECTOR2 +operator * ( FLOAT f, CONST D3DXVECTOR2& v ) +{ + return D3DXVECTOR2(f * v.x, f * v.y); +} + +D3DXINLINE BOOL +D3DXVECTOR2::operator == ( CONST D3DXVECTOR2& v ) const +{ + return x == v.x && y == v.y; +} + +D3DXINLINE BOOL +D3DXVECTOR2::operator != ( CONST D3DXVECTOR2& v ) const +{ + return x != v.x || y != v.y; +} + + + +//-------------------------- +// 2D Vector (16 bit) +//-------------------------- + +D3DXINLINE +D3DXVECTOR2_16F::D3DXVECTOR2_16F( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat32To16Array(&x, pf, 2); +} + +D3DXINLINE +D3DXVECTOR2_16F::D3DXVECTOR2_16F( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + *((DWORD *) &x) = *((DWORD *) &pf[0]); +} + +D3DXINLINE +D3DXVECTOR2_16F::D3DXVECTOR2_16F( CONST D3DXFLOAT16 &fx, CONST D3DXFLOAT16 &fy ) +{ + x = fx; + y = fy; +} + + +// casting +D3DXINLINE +D3DXVECTOR2_16F::operator D3DXFLOAT16* () +{ + return (D3DXFLOAT16*) &x; +} + +D3DXINLINE +D3DXVECTOR2_16F::operator CONST D3DXFLOAT16* () const +{ + return (CONST D3DXFLOAT16*) &x; +} + + +// binary operators +D3DXINLINE BOOL +D3DXVECTOR2_16F::operator == ( CONST D3DXVECTOR2_16F &v ) const +{ + return *((DWORD *) &x) == *((DWORD *) &v.x); +} + +D3DXINLINE BOOL +D3DXVECTOR2_16F::operator != ( CONST D3DXVECTOR2_16F &v ) const +{ + return *((DWORD *) &x) != *((DWORD *) &v.x); +} + + +//-------------------------- +// 3D Vector +//-------------------------- +D3DXINLINE +D3DXVECTOR3::D3DXVECTOR3( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; + z = pf[2]; +} + +D3DXINLINE +D3DXVECTOR3::D3DXVECTOR3( CONST D3DVECTOR& v ) +{ + x = v.x; + y = v.y; + z = v.z; +} + +D3DXINLINE +D3DXVECTOR3::D3DXVECTOR3( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 3); +} + +D3DXINLINE +D3DXVECTOR3::D3DXVECTOR3( FLOAT fx, FLOAT fy, FLOAT fz ) +{ + x = fx; + y = fy; + z = fz; +} + + +// casting +D3DXINLINE +D3DXVECTOR3::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DXINLINE +D3DXVECTOR3::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DXINLINE D3DXVECTOR3& +D3DXVECTOR3::operator += ( CONST D3DXVECTOR3& v ) +{ + x += v.x; + y += v.y; + z += v.z; + return *this; +} + +D3DXINLINE D3DXVECTOR3& +D3DXVECTOR3::operator -= ( CONST D3DXVECTOR3& v ) +{ + x -= v.x; + y -= v.y; + z -= v.z; + return *this; +} + +D3DXINLINE D3DXVECTOR3& +D3DXVECTOR3::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + z *= f; + return *this; +} + +D3DXINLINE D3DXVECTOR3& +D3DXVECTOR3::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + z *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator - () const +{ + return D3DXVECTOR3(-x, -y, -z); +} + + +// binary operators +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator + ( CONST D3DXVECTOR3& v ) const +{ + return D3DXVECTOR3(x + v.x, y + v.y, z + v.z); +} + +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator - ( CONST D3DXVECTOR3& v ) const +{ + return D3DXVECTOR3(x - v.x, y - v.y, z - v.z); +} + +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator * ( FLOAT f ) const +{ + return D3DXVECTOR3(x * f, y * f, z * f); +} + +D3DXINLINE D3DXVECTOR3 +D3DXVECTOR3::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXVECTOR3(x * fInv, y * fInv, z * fInv); +} + + +D3DXINLINE D3DXVECTOR3 +operator * ( FLOAT f, CONST struct D3DXVECTOR3& v ) +{ + return D3DXVECTOR3(f * v.x, f * v.y, f * v.z); +} + + +D3DXINLINE BOOL +D3DXVECTOR3::operator == ( CONST D3DXVECTOR3& v ) const +{ + return x == v.x && y == v.y && z == v.z; +} + +D3DXINLINE BOOL +D3DXVECTOR3::operator != ( CONST D3DXVECTOR3& v ) const +{ + return x != v.x || y != v.y || z != v.z; +} + + + +//-------------------------- +// 3D Vector (16 bit) +//-------------------------- + +D3DXINLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat32To16Array(&x, pf, 3); +} + +D3DXINLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST D3DVECTOR& v ) +{ + D3DXFloat32To16Array(&x, &v.x, 1); + D3DXFloat32To16Array(&y, &v.y, 1); + D3DXFloat32To16Array(&z, &v.z, 1); +} + +D3DXINLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + *((DWORD *) &x) = *((DWORD *) &pf[0]); + *((WORD *) &z) = *((WORD *) &pf[2]); +} + +D3DXINLINE +D3DXVECTOR3_16F::D3DXVECTOR3_16F( CONST D3DXFLOAT16 &fx, CONST D3DXFLOAT16 &fy, CONST D3DXFLOAT16 &fz ) +{ + x = fx; + y = fy; + z = fz; +} + + +// casting +D3DXINLINE +D3DXVECTOR3_16F::operator D3DXFLOAT16* () +{ + return (D3DXFLOAT16*) &x; +} + +D3DXINLINE +D3DXVECTOR3_16F::operator CONST D3DXFLOAT16* () const +{ + return (CONST D3DXFLOAT16*) &x; +} + + +// binary operators +D3DXINLINE BOOL +D3DXVECTOR3_16F::operator == ( CONST D3DXVECTOR3_16F &v ) const +{ + return *((DWORD *) &x) == *((DWORD *) &v.x) && + *((WORD *) &z) == *((WORD *) &v.z); +} + +D3DXINLINE BOOL +D3DXVECTOR3_16F::operator != ( CONST D3DXVECTOR3_16F &v ) const +{ + return *((DWORD *) &x) != *((DWORD *) &v.x) || + *((WORD *) &z) != *((WORD *) &v.z); +} + + +//-------------------------- +// 4D Vector +//-------------------------- +D3DXINLINE +D3DXVECTOR4::D3DXVECTOR4( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; + z = pf[2]; + w = pf[3]; +} + +D3DXINLINE +D3DXVECTOR4::D3DXVECTOR4( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 4); +} + +D3DXINLINE +D3DXVECTOR4::D3DXVECTOR4( CONST D3DVECTOR& v, FLOAT f ) +{ + x = v.x; + y = v.y; + z = v.z; + w = f; +} + +D3DXINLINE +D3DXVECTOR4::D3DXVECTOR4( FLOAT fx, FLOAT fy, FLOAT fz, FLOAT fw ) +{ + x = fx; + y = fy; + z = fz; + w = fw; +} + + +// casting +D3DXINLINE +D3DXVECTOR4::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DXINLINE +D3DXVECTOR4::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DXINLINE D3DXVECTOR4& +D3DXVECTOR4::operator += ( CONST D3DXVECTOR4& v ) +{ + x += v.x; + y += v.y; + z += v.z; + w += v.w; + return *this; +} + +D3DXINLINE D3DXVECTOR4& +D3DXVECTOR4::operator -= ( CONST D3DXVECTOR4& v ) +{ + x -= v.x; + y -= v.y; + z -= v.z; + w -= v.w; + return *this; +} + +D3DXINLINE D3DXVECTOR4& +D3DXVECTOR4::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + z *= f; + w *= f; + return *this; +} + +D3DXINLINE D3DXVECTOR4& +D3DXVECTOR4::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + z *= fInv; + w *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator - () const +{ + return D3DXVECTOR4(-x, -y, -z, -w); +} + + +// binary operators +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator + ( CONST D3DXVECTOR4& v ) const +{ + return D3DXVECTOR4(x + v.x, y + v.y, z + v.z, w + v.w); +} + +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator - ( CONST D3DXVECTOR4& v ) const +{ + return D3DXVECTOR4(x - v.x, y - v.y, z - v.z, w - v.w); +} + +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator * ( FLOAT f ) const +{ + return D3DXVECTOR4(x * f, y * f, z * f, w * f); +} + +D3DXINLINE D3DXVECTOR4 +D3DXVECTOR4::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXVECTOR4(x * fInv, y * fInv, z * fInv, w * fInv); +} + +D3DXINLINE D3DXVECTOR4 +operator * ( FLOAT f, CONST D3DXVECTOR4& v ) +{ + return D3DXVECTOR4(f * v.x, f * v.y, f * v.z, f * v.w); +} + + +D3DXINLINE BOOL +D3DXVECTOR4::operator == ( CONST D3DXVECTOR4& v ) const +{ + return x == v.x && y == v.y && z == v.z && w == v.w; +} + +D3DXINLINE BOOL +D3DXVECTOR4::operator != ( CONST D3DXVECTOR4& v ) const +{ + return x != v.x || y != v.y || z != v.z || w != v.w; +} + + + +//-------------------------- +// 4D Vector (16 bit) +//-------------------------- + +D3DXINLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST FLOAT *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat32To16Array(&x, pf, 4); +} + +D3DXINLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST D3DXFLOAT16 *pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + *((DWORD *) &x) = *((DWORD *) &pf[0]); + *((DWORD *) &z) = *((DWORD *) &pf[2]); +} + +D3DXINLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST D3DXVECTOR3_16F& v, CONST D3DXFLOAT16& f ) +{ + x = v.x; + y = v.y; + z = v.z; + w = f; +} + +D3DXINLINE +D3DXVECTOR4_16F::D3DXVECTOR4_16F( CONST D3DXFLOAT16 &fx, CONST D3DXFLOAT16 &fy, CONST D3DXFLOAT16 &fz, CONST D3DXFLOAT16 &fw ) +{ + x = fx; + y = fy; + z = fz; + w = fw; +} + + +// casting +D3DXINLINE +D3DXVECTOR4_16F::operator D3DXFLOAT16* () +{ + return (D3DXFLOAT16*) &x; +} + +D3DXINLINE +D3DXVECTOR4_16F::operator CONST D3DXFLOAT16* () const +{ + return (CONST D3DXFLOAT16*) &x; +} + + +// binary operators +D3DXINLINE BOOL +D3DXVECTOR4_16F::operator == ( CONST D3DXVECTOR4_16F &v ) const +{ + return *((DWORD *) &x) == *((DWORD *) &v.x) && + *((DWORD *) &z) == *((DWORD *) &v.z); +} + +D3DXINLINE BOOL +D3DXVECTOR4_16F::operator != ( CONST D3DXVECTOR4_16F &v ) const +{ + return *((DWORD *) &x) != *((DWORD *) &v.x) || + *((DWORD *) &z) != *((DWORD *) &v.z); +} + + +//-------------------------- +// Matrix +//-------------------------- +D3DXINLINE +D3DXMATRIX::D3DXMATRIX( CONST FLOAT* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + memcpy(&_11, pf, sizeof(D3DXMATRIX)); +} + +D3DXINLINE +D3DXMATRIX::D3DXMATRIX( CONST D3DMATRIX& mat ) +{ + memcpy(&_11, &mat, sizeof(D3DXMATRIX)); +} + +D3DXINLINE +D3DXMATRIX::D3DXMATRIX( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&_11, pf, 16); +} + +D3DXINLINE +D3DXMATRIX::D3DXMATRIX( FLOAT f11, FLOAT f12, FLOAT f13, FLOAT f14, + FLOAT f21, FLOAT f22, FLOAT f23, FLOAT f24, + FLOAT f31, FLOAT f32, FLOAT f33, FLOAT f34, + FLOAT f41, FLOAT f42, FLOAT f43, FLOAT f44 ) +{ + _11 = f11; _12 = f12; _13 = f13; _14 = f14; + _21 = f21; _22 = f22; _23 = f23; _24 = f24; + _31 = f31; _32 = f32; _33 = f33; _34 = f34; + _41 = f41; _42 = f42; _43 = f43; _44 = f44; +} + + + +// access grants +D3DXINLINE FLOAT& +D3DXMATRIX::operator () ( UINT iRow, UINT iCol ) +{ + return m[iRow][iCol]; +} + +D3DXINLINE FLOAT +D3DXMATRIX::operator () ( UINT iRow, UINT iCol ) const +{ + return m[iRow][iCol]; +} + + +// casting operators +D3DXINLINE +D3DXMATRIX::operator FLOAT* () +{ + return (FLOAT *) &_11; +} + +D3DXINLINE +D3DXMATRIX::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &_11; +} + + +// assignment operators +D3DXINLINE D3DXMATRIX& +D3DXMATRIX::operator *= ( CONST D3DXMATRIX& mat ) +{ + D3DXMatrixMultiply(this, this, &mat); + return *this; +} + +D3DXINLINE D3DXMATRIX& +D3DXMATRIX::operator += ( CONST D3DXMATRIX& mat ) +{ + _11 += mat._11; _12 += mat._12; _13 += mat._13; _14 += mat._14; + _21 += mat._21; _22 += mat._22; _23 += mat._23; _24 += mat._24; + _31 += mat._31; _32 += mat._32; _33 += mat._33; _34 += mat._34; + _41 += mat._41; _42 += mat._42; _43 += mat._43; _44 += mat._44; + return *this; +} + +D3DXINLINE D3DXMATRIX& +D3DXMATRIX::operator -= ( CONST D3DXMATRIX& mat ) +{ + _11 -= mat._11; _12 -= mat._12; _13 -= mat._13; _14 -= mat._14; + _21 -= mat._21; _22 -= mat._22; _23 -= mat._23; _24 -= mat._24; + _31 -= mat._31; _32 -= mat._32; _33 -= mat._33; _34 -= mat._34; + _41 -= mat._41; _42 -= mat._42; _43 -= mat._43; _44 -= mat._44; + return *this; +} + +D3DXINLINE D3DXMATRIX& +D3DXMATRIX::operator *= ( FLOAT f ) +{ + _11 *= f; _12 *= f; _13 *= f; _14 *= f; + _21 *= f; _22 *= f; _23 *= f; _24 *= f; + _31 *= f; _32 *= f; _33 *= f; _34 *= f; + _41 *= f; _42 *= f; _43 *= f; _44 *= f; + return *this; +} + +D3DXINLINE D3DXMATRIX& +D3DXMATRIX::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + _11 *= fInv; _12 *= fInv; _13 *= fInv; _14 *= fInv; + _21 *= fInv; _22 *= fInv; _23 *= fInv; _24 *= fInv; + _31 *= fInv; _32 *= fInv; _33 *= fInv; _34 *= fInv; + _41 *= fInv; _42 *= fInv; _43 *= fInv; _44 *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator - () const +{ + return D3DXMATRIX(-_11, -_12, -_13, -_14, + -_21, -_22, -_23, -_24, + -_31, -_32, -_33, -_34, + -_41, -_42, -_43, -_44); +} + + +// binary operators +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator * ( CONST D3DXMATRIX& mat ) const +{ + D3DXMATRIX matT; + D3DXMatrixMultiply(&matT, this, &mat); + return matT; +} + +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator + ( CONST D3DXMATRIX& mat ) const +{ + return D3DXMATRIX(_11 + mat._11, _12 + mat._12, _13 + mat._13, _14 + mat._14, + _21 + mat._21, _22 + mat._22, _23 + mat._23, _24 + mat._24, + _31 + mat._31, _32 + mat._32, _33 + mat._33, _34 + mat._34, + _41 + mat._41, _42 + mat._42, _43 + mat._43, _44 + mat._44); +} + +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator - ( CONST D3DXMATRIX& mat ) const +{ + return D3DXMATRIX(_11 - mat._11, _12 - mat._12, _13 - mat._13, _14 - mat._14, + _21 - mat._21, _22 - mat._22, _23 - mat._23, _24 - mat._24, + _31 - mat._31, _32 - mat._32, _33 - mat._33, _34 - mat._34, + _41 - mat._41, _42 - mat._42, _43 - mat._43, _44 - mat._44); +} + +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator * ( FLOAT f ) const +{ + return D3DXMATRIX(_11 * f, _12 * f, _13 * f, _14 * f, + _21 * f, _22 * f, _23 * f, _24 * f, + _31 * f, _32 * f, _33 * f, _34 * f, + _41 * f, _42 * f, _43 * f, _44 * f); +} + +D3DXINLINE D3DXMATRIX +D3DXMATRIX::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXMATRIX(_11 * fInv, _12 * fInv, _13 * fInv, _14 * fInv, + _21 * fInv, _22 * fInv, _23 * fInv, _24 * fInv, + _31 * fInv, _32 * fInv, _33 * fInv, _34 * fInv, + _41 * fInv, _42 * fInv, _43 * fInv, _44 * fInv); +} + + +D3DXINLINE D3DXMATRIX +operator * ( FLOAT f, CONST D3DXMATRIX& mat ) +{ + return D3DXMATRIX(f * mat._11, f * mat._12, f * mat._13, f * mat._14, + f * mat._21, f * mat._22, f * mat._23, f * mat._24, + f * mat._31, f * mat._32, f * mat._33, f * mat._34, + f * mat._41, f * mat._42, f * mat._43, f * mat._44); +} + + +D3DXINLINE BOOL +D3DXMATRIX::operator == ( CONST D3DXMATRIX& mat ) const +{ + return 0 == memcmp(this, &mat, sizeof(D3DXMATRIX)); +} + +D3DXINLINE BOOL +D3DXMATRIX::operator != ( CONST D3DXMATRIX& mat ) const +{ + return 0 != memcmp(this, &mat, sizeof(D3DXMATRIX)); +} + + + +//-------------------------- +// Aligned Matrices +//-------------------------- + +D3DXINLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( CONST FLOAT* f ) : + D3DXMATRIX( f ) +{ +} + +D3DXINLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( CONST D3DMATRIX& m ) : + D3DXMATRIX( m ) +{ +} + +D3DXINLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( CONST D3DXFLOAT16* f ) : + D3DXMATRIX( f ) +{ +} + +D3DXINLINE +_D3DXMATRIXA16::_D3DXMATRIXA16( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, + FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, + FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, + FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ) : + D3DXMATRIX(_11, _12, _13, _14, + _21, _22, _23, _24, + _31, _32, _33, _34, + _41, _42, _43, _44) +{ +} + +#ifndef SIZE_MAX +#define SIZE_MAX ((SIZE_T)-1) +#endif + +D3DXINLINE void* +_D3DXMATRIXA16::operator new( size_t s ) +{ + if (s > (SIZE_MAX-16)) + return NULL; + LPBYTE p = ::new BYTE[s + 16]; + if (p) + { + BYTE offset = (BYTE)(16 - ((UINT_PTR)p & 15)); + p += offset; + p[-1] = offset; + } + return p; +} + +D3DXINLINE void* +_D3DXMATRIXA16::operator new[]( size_t s ) +{ + if (s > (SIZE_MAX-16)) + return NULL; + LPBYTE p = ::new BYTE[s + 16]; + if (p) + { + BYTE offset = (BYTE)(16 - ((UINT_PTR)p & 15)); + p += offset; + p[-1] = offset; + } + return p; +} + +D3DXINLINE void +_D3DXMATRIXA16::operator delete(void* p) +{ + if(p) + { + BYTE* pb = static_cast<BYTE*>(p); + pb -= pb[-1]; + ::delete [] pb; + } +} + +D3DXINLINE void +_D3DXMATRIXA16::operator delete[](void* p) +{ + if(p) + { + BYTE* pb = static_cast<BYTE*>(p); + pb -= pb[-1]; + ::delete [] pb; + } +} + +D3DXINLINE _D3DXMATRIXA16& +_D3DXMATRIXA16::operator=(CONST D3DXMATRIX& rhs) +{ + memcpy(&_11, &rhs, sizeof(D3DXMATRIX)); + return *this; +} + + +//-------------------------- +// Quaternion +//-------------------------- + +D3DXINLINE +D3DXQUATERNION::D3DXQUATERNION( CONST FLOAT* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + x = pf[0]; + y = pf[1]; + z = pf[2]; + w = pf[3]; +} + +D3DXINLINE +D3DXQUATERNION::D3DXQUATERNION( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&x, pf, 4); +} + +D3DXINLINE +D3DXQUATERNION::D3DXQUATERNION( FLOAT fx, FLOAT fy, FLOAT fz, FLOAT fw ) +{ + x = fx; + y = fy; + z = fz; + w = fw; +} + + +// casting +D3DXINLINE +D3DXQUATERNION::operator FLOAT* () +{ + return (FLOAT *) &x; +} + +D3DXINLINE +D3DXQUATERNION::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &x; +} + + +// assignment operators +D3DXINLINE D3DXQUATERNION& +D3DXQUATERNION::operator += ( CONST D3DXQUATERNION& q ) +{ + x += q.x; + y += q.y; + z += q.z; + w += q.w; + return *this; +} + +D3DXINLINE D3DXQUATERNION& +D3DXQUATERNION::operator -= ( CONST D3DXQUATERNION& q ) +{ + x -= q.x; + y -= q.y; + z -= q.z; + w -= q.w; + return *this; +} + +D3DXINLINE D3DXQUATERNION& +D3DXQUATERNION::operator *= ( CONST D3DXQUATERNION& q ) +{ + D3DXQuaternionMultiply(this, this, &q); + return *this; +} + +D3DXINLINE D3DXQUATERNION& +D3DXQUATERNION::operator *= ( FLOAT f ) +{ + x *= f; + y *= f; + z *= f; + w *= f; + return *this; +} + +D3DXINLINE D3DXQUATERNION& +D3DXQUATERNION::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + x *= fInv; + y *= fInv; + z *= fInv; + w *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator - () const +{ + return D3DXQUATERNION(-x, -y, -z, -w); +} + + +// binary operators +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator + ( CONST D3DXQUATERNION& q ) const +{ + return D3DXQUATERNION(x + q.x, y + q.y, z + q.z, w + q.w); +} + +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator - ( CONST D3DXQUATERNION& q ) const +{ + return D3DXQUATERNION(x - q.x, y - q.y, z - q.z, w - q.w); +} + +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator * ( CONST D3DXQUATERNION& q ) const +{ + D3DXQUATERNION qT; + D3DXQuaternionMultiply(&qT, this, &q); + return qT; +} + +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator * ( FLOAT f ) const +{ + return D3DXQUATERNION(x * f, y * f, z * f, w * f); +} + +D3DXINLINE D3DXQUATERNION +D3DXQUATERNION::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXQUATERNION(x * fInv, y * fInv, z * fInv, w * fInv); +} + + +D3DXINLINE D3DXQUATERNION +operator * (FLOAT f, CONST D3DXQUATERNION& q ) +{ + return D3DXQUATERNION(f * q.x, f * q.y, f * q.z, f * q.w); +} + + +D3DXINLINE BOOL +D3DXQUATERNION::operator == ( CONST D3DXQUATERNION& q ) const +{ + return x == q.x && y == q.y && z == q.z && w == q.w; +} + +D3DXINLINE BOOL +D3DXQUATERNION::operator != ( CONST D3DXQUATERNION& q ) const +{ + return x != q.x || y != q.y || z != q.z || w != q.w; +} + + + +//-------------------------- +// Plane +//-------------------------- + +D3DXINLINE +D3DXPLANE::D3DXPLANE( CONST FLOAT* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + a = pf[0]; + b = pf[1]; + c = pf[2]; + d = pf[3]; +} + +D3DXINLINE +D3DXPLANE::D3DXPLANE( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&a, pf, 4); +} + +D3DXINLINE +D3DXPLANE::D3DXPLANE( FLOAT fa, FLOAT fb, FLOAT fc, FLOAT fd ) +{ + a = fa; + b = fb; + c = fc; + d = fd; +} + + +// casting +D3DXINLINE +D3DXPLANE::operator FLOAT* () +{ + return (FLOAT *) &a; +} + +D3DXINLINE +D3DXPLANE::operator CONST FLOAT* () const +{ + return (CONST FLOAT *) &a; +} + + +// assignment operators +D3DXINLINE D3DXPLANE& +D3DXPLANE::operator *= ( FLOAT f ) +{ + a *= f; + b *= f; + c *= f; + d *= f; + return *this; +} + +D3DXINLINE D3DXPLANE& +D3DXPLANE::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + a *= fInv; + b *= fInv; + c *= fInv; + d *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXPLANE +D3DXPLANE::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXPLANE +D3DXPLANE::operator - () const +{ + return D3DXPLANE(-a, -b, -c, -d); +} + + +// binary operators +D3DXINLINE D3DXPLANE +D3DXPLANE::operator * ( FLOAT f ) const +{ + return D3DXPLANE(a * f, b * f, c * f, d * f); +} + +D3DXINLINE D3DXPLANE +D3DXPLANE::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXPLANE(a * fInv, b * fInv, c * fInv, d * fInv); +} + +D3DXINLINE D3DXPLANE +operator * (FLOAT f, CONST D3DXPLANE& p ) +{ + return D3DXPLANE(f * p.a, f * p.b, f * p.c, f * p.d); +} + +D3DXINLINE BOOL +D3DXPLANE::operator == ( CONST D3DXPLANE& p ) const +{ + return a == p.a && b == p.b && c == p.c && d == p.d; +} + +D3DXINLINE BOOL +D3DXPLANE::operator != ( CONST D3DXPLANE& p ) const +{ + return a != p.a || b != p.b || c != p.c || d != p.d; +} + + + + +//-------------------------- +// Color +//-------------------------- + +D3DXINLINE +D3DXCOLOR::D3DXCOLOR( DWORD dw ) +{ + CONST FLOAT f = 1.0f / 255.0f; + r = f * (FLOAT) (unsigned char) (dw >> 16); + g = f * (FLOAT) (unsigned char) (dw >> 8); + b = f * (FLOAT) (unsigned char) (dw >> 0); + a = f * (FLOAT) (unsigned char) (dw >> 24); +} + +D3DXINLINE +D3DXCOLOR::D3DXCOLOR( CONST FLOAT* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + r = pf[0]; + g = pf[1]; + b = pf[2]; + a = pf[3]; +} + +D3DXINLINE +D3DXCOLOR::D3DXCOLOR( CONST D3DXFLOAT16* pf ) +{ +#ifdef D3DX_DEBUG + if(!pf) + return; +#endif + + D3DXFloat16To32Array(&r, pf, 4); +} + +D3DXINLINE +D3DXCOLOR::D3DXCOLOR( CONST D3DCOLORVALUE& c ) +{ + r = c.r; + g = c.g; + b = c.b; + a = c.a; +} + +D3DXINLINE +D3DXCOLOR::D3DXCOLOR( FLOAT fr, FLOAT fg, FLOAT fb, FLOAT fa ) +{ + r = fr; + g = fg; + b = fb; + a = fa; +} + + +// casting +D3DXINLINE +D3DXCOLOR::operator DWORD () const +{ + DWORD dwR = r >= 1.0f ? 0xff : r <= 0.0f ? 0x00 : (DWORD) (r * 255.0f + 0.5f); + DWORD dwG = g >= 1.0f ? 0xff : g <= 0.0f ? 0x00 : (DWORD) (g * 255.0f + 0.5f); + DWORD dwB = b >= 1.0f ? 0xff : b <= 0.0f ? 0x00 : (DWORD) (b * 255.0f + 0.5f); + DWORD dwA = a >= 1.0f ? 0xff : a <= 0.0f ? 0x00 : (DWORD) (a * 255.0f + 0.5f); + + return (dwA << 24) | (dwR << 16) | (dwG << 8) | dwB; +} + + +D3DXINLINE +D3DXCOLOR::operator FLOAT * () +{ + return (FLOAT *) &r; +} + +D3DXINLINE +D3DXCOLOR::operator CONST FLOAT * () const +{ + return (CONST FLOAT *) &r; +} + + +D3DXINLINE +D3DXCOLOR::operator D3DCOLORVALUE * () +{ + return (D3DCOLORVALUE *) &r; +} + +D3DXINLINE +D3DXCOLOR::operator CONST D3DCOLORVALUE * () const +{ + return (CONST D3DCOLORVALUE *) &r; +} + + +D3DXINLINE +D3DXCOLOR::operator D3DCOLORVALUE& () +{ + return *((D3DCOLORVALUE *) &r); +} + +D3DXINLINE +D3DXCOLOR::operator CONST D3DCOLORVALUE& () const +{ + return *((CONST D3DCOLORVALUE *) &r); +} + + +// assignment operators +D3DXINLINE D3DXCOLOR& +D3DXCOLOR::operator += ( CONST D3DXCOLOR& c ) +{ + r += c.r; + g += c.g; + b += c.b; + a += c.a; + return *this; +} + +D3DXINLINE D3DXCOLOR& +D3DXCOLOR::operator -= ( CONST D3DXCOLOR& c ) +{ + r -= c.r; + g -= c.g; + b -= c.b; + a -= c.a; + return *this; +} + +D3DXINLINE D3DXCOLOR& +D3DXCOLOR::operator *= ( FLOAT f ) +{ + r *= f; + g *= f; + b *= f; + a *= f; + return *this; +} + +D3DXINLINE D3DXCOLOR& +D3DXCOLOR::operator /= ( FLOAT f ) +{ + FLOAT fInv = 1.0f / f; + r *= fInv; + g *= fInv; + b *= fInv; + a *= fInv; + return *this; +} + + +// unary operators +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator + () const +{ + return *this; +} + +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator - () const +{ + return D3DXCOLOR(-r, -g, -b, -a); +} + + +// binary operators +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator + ( CONST D3DXCOLOR& c ) const +{ + return D3DXCOLOR(r + c.r, g + c.g, b + c.b, a + c.a); +} + +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator - ( CONST D3DXCOLOR& c ) const +{ + return D3DXCOLOR(r - c.r, g - c.g, b - c.b, a - c.a); +} + +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator * ( FLOAT f ) const +{ + return D3DXCOLOR(r * f, g * f, b * f, a * f); +} + +D3DXINLINE D3DXCOLOR +D3DXCOLOR::operator / ( FLOAT f ) const +{ + FLOAT fInv = 1.0f / f; + return D3DXCOLOR(r * fInv, g * fInv, b * fInv, a * fInv); +} + + +D3DXINLINE D3DXCOLOR +operator * (FLOAT f, CONST D3DXCOLOR& c ) +{ + return D3DXCOLOR(f * c.r, f * c.g, f * c.b, f * c.a); +} + + +D3DXINLINE BOOL +D3DXCOLOR::operator == ( CONST D3DXCOLOR& c ) const +{ + return r == c.r && g == c.g && b == c.b && a == c.a; +} + +D3DXINLINE BOOL +D3DXCOLOR::operator != ( CONST D3DXCOLOR& c ) const +{ + return r != c.r || g != c.g || b != c.b || a != c.a; +} + + +#endif //__cplusplus + + + +//=========================================================================== +// +// Inline functions +// +//=========================================================================== + + +//-------------------------- +// 2D Vector +//-------------------------- + +D3DXINLINE FLOAT D3DXVec2Length + ( CONST D3DXVECTOR2 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pV->x * pV->x + pV->y * pV->y); +#else + return (FLOAT) sqrt(pV->x * pV->x + pV->y * pV->y); +#endif +} + +D3DXINLINE FLOAT D3DXVec2LengthSq + ( CONST D3DXVECTOR2 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + + return pV->x * pV->x + pV->y * pV->y; +} + +D3DXINLINE FLOAT D3DXVec2Dot + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->x + pV1->y * pV2->y; +} + +D3DXINLINE FLOAT D3DXVec2CCW + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->y - pV1->y * pV2->x; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Add + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + pV2->x; + pOut->y = pV1->y + pV2->y; + return pOut; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Subtract + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + return pOut; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Minimize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x < pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y < pV2->y ? pV1->y : pV2->y; + return pOut; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Maximize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x > pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y > pV2->y ? pV1->y : pV2->y; + return pOut; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Scale + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, FLOAT s ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV) + return NULL; +#endif + + pOut->x = pV->x * s; + pOut->y = pV->y * s; + return pOut; +} + +D3DXINLINE D3DXVECTOR2* D3DXVec2Lerp + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, + FLOAT s ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + s * (pV2->x - pV1->x); + pOut->y = pV1->y + s * (pV2->y - pV1->y); + return pOut; +} + + +//-------------------------- +// 3D Vector +//-------------------------- + +D3DXINLINE FLOAT D3DXVec3Length + ( CONST D3DXVECTOR3 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z); +#else + return (FLOAT) sqrt(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z); +#endif +} + +D3DXINLINE FLOAT D3DXVec3LengthSq + ( CONST D3DXVECTOR3 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + + return pV->x * pV->x + pV->y * pV->y + pV->z * pV->z; +} + +D3DXINLINE FLOAT D3DXVec3Dot + ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Cross + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + D3DXVECTOR3 v; + +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + v.x = pV1->y * pV2->z - pV1->z * pV2->y; + v.y = pV1->z * pV2->x - pV1->x * pV2->z; + v.z = pV1->x * pV2->y - pV1->y * pV2->x; + + *pOut = v; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Add + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + pV2->x; + pOut->y = pV1->y + pV2->y; + pOut->z = pV1->z + pV2->z; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Subtract + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + pOut->z = pV1->z - pV2->z; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Minimize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x < pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y < pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z < pV2->z ? pV1->z : pV2->z; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Maximize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x > pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y > pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z > pV2->z ? pV1->z : pV2->z; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Scale + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, FLOAT s) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV) + return NULL; +#endif + + pOut->x = pV->x * s; + pOut->y = pV->y * s; + pOut->z = pV->z * s; + return pOut; +} + +D3DXINLINE D3DXVECTOR3* D3DXVec3Lerp + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + FLOAT s ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + s * (pV2->x - pV1->x); + pOut->y = pV1->y + s * (pV2->y - pV1->y); + pOut->z = pV1->z + s * (pV2->z - pV1->z); + return pOut; +} + + +//-------------------------- +// 4D Vector +//-------------------------- + +D3DXINLINE FLOAT D3DXVec4Length + ( CONST D3DXVECTOR4 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z + pV->w * pV->w); +#else + return (FLOAT) sqrt(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z + pV->w * pV->w); +#endif +} + +D3DXINLINE FLOAT D3DXVec4LengthSq + ( CONST D3DXVECTOR4 *pV ) +{ +#ifdef D3DX_DEBUG + if(!pV) + return 0.0f; +#endif + + return pV->x * pV->x + pV->y * pV->y + pV->z * pV->z + pV->w * pV->w; +} + +D3DXINLINE FLOAT D3DXVec4Dot + ( CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2 ) +{ +#ifdef D3DX_DEBUG + if(!pV1 || !pV2) + return 0.0f; +#endif + + return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z + pV1->w * pV2->w; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Add + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + pV2->x; + pOut->y = pV1->y + pV2->y; + pOut->z = pV1->z + pV2->z; + pOut->w = pV1->w + pV2->w; + return pOut; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Subtract + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + pOut->z = pV1->z - pV2->z; + pOut->w = pV1->w - pV2->w; + return pOut; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Minimize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x < pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y < pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z < pV2->z ? pV1->z : pV2->z; + pOut->w = pV1->w < pV2->w ? pV1->w : pV2->w; + return pOut; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Maximize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x > pV2->x ? pV1->x : pV2->x; + pOut->y = pV1->y > pV2->y ? pV1->y : pV2->y; + pOut->z = pV1->z > pV2->z ? pV1->z : pV2->z; + pOut->w = pV1->w > pV2->w ? pV1->w : pV2->w; + return pOut; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Scale + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, FLOAT s) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV) + return NULL; +#endif + + pOut->x = pV->x * s; + pOut->y = pV->y * s; + pOut->z = pV->z * s; + pOut->w = pV->w * s; + return pOut; +} + +D3DXINLINE D3DXVECTOR4* D3DXVec4Lerp + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + FLOAT s ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pV1 || !pV2) + return NULL; +#endif + + pOut->x = pV1->x + s * (pV2->x - pV1->x); + pOut->y = pV1->y + s * (pV2->y - pV1->y); + pOut->z = pV1->z + s * (pV2->z - pV1->z); + pOut->w = pV1->w + s * (pV2->w - pV1->w); + return pOut; +} + + +//-------------------------- +// 4D Matrix +//-------------------------- + +D3DXINLINE D3DXMATRIX* D3DXMatrixIdentity + ( D3DXMATRIX *pOut ) +{ +#ifdef D3DX_DEBUG + if(!pOut) + return NULL; +#endif + + pOut->m[0][1] = pOut->m[0][2] = pOut->m[0][3] = + pOut->m[1][0] = pOut->m[1][2] = pOut->m[1][3] = + pOut->m[2][0] = pOut->m[2][1] = pOut->m[2][3] = + pOut->m[3][0] = pOut->m[3][1] = pOut->m[3][2] = 0.0f; + + pOut->m[0][0] = pOut->m[1][1] = pOut->m[2][2] = pOut->m[3][3] = 1.0f; + return pOut; +} + + +D3DXINLINE BOOL D3DXMatrixIsIdentity + ( CONST D3DXMATRIX *pM ) +{ +#ifdef D3DX_DEBUG + if(!pM) + return FALSE; +#endif + + return pM->m[0][0] == 1.0f && pM->m[0][1] == 0.0f && pM->m[0][2] == 0.0f && pM->m[0][3] == 0.0f && + pM->m[1][0] == 0.0f && pM->m[1][1] == 1.0f && pM->m[1][2] == 0.0f && pM->m[1][3] == 0.0f && + pM->m[2][0] == 0.0f && pM->m[2][1] == 0.0f && pM->m[2][2] == 1.0f && pM->m[2][3] == 0.0f && + pM->m[3][0] == 0.0f && pM->m[3][1] == 0.0f && pM->m[3][2] == 0.0f && pM->m[3][3] == 1.0f; +} + + +//-------------------------- +// Quaternion +//-------------------------- + +D3DXINLINE FLOAT D3DXQuaternionLength + ( CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX_DEBUG + if(!pQ) + return 0.0f; +#endif + +#ifdef __cplusplus + return sqrtf(pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z + pQ->w * pQ->w); +#else + return (FLOAT) sqrt(pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z + pQ->w * pQ->w); +#endif +} + +D3DXINLINE FLOAT D3DXQuaternionLengthSq + ( CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX_DEBUG + if(!pQ) + return 0.0f; +#endif + + return pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z + pQ->w * pQ->w; +} + +D3DXINLINE FLOAT D3DXQuaternionDot + ( CONST D3DXQUATERNION *pQ1, CONST D3DXQUATERNION *pQ2 ) +{ +#ifdef D3DX_DEBUG + if(!pQ1 || !pQ2) + return 0.0f; +#endif + + return pQ1->x * pQ2->x + pQ1->y * pQ2->y + pQ1->z * pQ2->z + pQ1->w * pQ2->w; +} + + +D3DXINLINE D3DXQUATERNION* D3DXQuaternionIdentity + ( D3DXQUATERNION *pOut ) +{ +#ifdef D3DX_DEBUG + if(!pOut) + return NULL; +#endif + + pOut->x = pOut->y = pOut->z = 0.0f; + pOut->w = 1.0f; + return pOut; +} + +D3DXINLINE BOOL D3DXQuaternionIsIdentity + ( CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX_DEBUG + if(!pQ) + return FALSE; +#endif + + return pQ->x == 0.0f && pQ->y == 0.0f && pQ->z == 0.0f && pQ->w == 1.0f; +} + + +D3DXINLINE D3DXQUATERNION* D3DXQuaternionConjugate + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pQ) + return NULL; +#endif + + pOut->x = -pQ->x; + pOut->y = -pQ->y; + pOut->z = -pQ->z; + pOut->w = pQ->w; + return pOut; +} + + +//-------------------------- +// Plane +//-------------------------- + +D3DXINLINE FLOAT D3DXPlaneDot + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR4 *pV) +{ +#ifdef D3DX_DEBUG + if(!pP || !pV) + return 0.0f; +#endif + + return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z + pP->d * pV->w; +} + +D3DXINLINE FLOAT D3DXPlaneDotCoord + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV) +{ +#ifdef D3DX_DEBUG + if(!pP || !pV) + return 0.0f; +#endif + + return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z + pP->d; +} + +D3DXINLINE FLOAT D3DXPlaneDotNormal + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV) +{ +#ifdef D3DX_DEBUG + if(!pP || !pV) + return 0.0f; +#endif + + return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z; +} + +D3DXINLINE D3DXPLANE* D3DXPlaneScale + (D3DXPLANE *pOut, CONST D3DXPLANE *pP, FLOAT s) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pP) + return NULL; +#endif + + pOut->a = pP->a * s; + pOut->b = pP->b * s; + pOut->c = pP->c * s; + pOut->d = pP->d * s; + return pOut; +} + + +//-------------------------- +// Color +//-------------------------- + +D3DXINLINE D3DXCOLOR* D3DXColorNegative + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC) + return NULL; +#endif + + pOut->r = 1.0f - pC->r; + pOut->g = 1.0f - pC->g; + pOut->b = 1.0f - pC->b; + pOut->a = pC->a; + return pOut; +} + +D3DXINLINE D3DXCOLOR* D3DXColorAdd + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r + pC2->r; + pOut->g = pC1->g + pC2->g; + pOut->b = pC1->b + pC2->b; + pOut->a = pC1->a + pC2->a; + return pOut; +} + +D3DXINLINE D3DXCOLOR* D3DXColorSubtract + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r - pC2->r; + pOut->g = pC1->g - pC2->g; + pOut->b = pC1->b - pC2->b; + pOut->a = pC1->a - pC2->a; + return pOut; +} + +D3DXINLINE D3DXCOLOR* D3DXColorScale + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC) + return NULL; +#endif + + pOut->r = pC->r * s; + pOut->g = pC->g * s; + pOut->b = pC->b * s; + pOut->a = pC->a * s; + return pOut; +} + +D3DXINLINE D3DXCOLOR* D3DXColorModulate + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r * pC2->r; + pOut->g = pC1->g * pC2->g; + pOut->b = pC1->b * pC2->b; + pOut->a = pC1->a * pC2->a; + return pOut; +} + +D3DXINLINE D3DXCOLOR* D3DXColorLerp + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2, FLOAT s) +{ +#ifdef D3DX_DEBUG + if(!pOut || !pC1 || !pC2) + return NULL; +#endif + + pOut->r = pC1->r + s * (pC2->r - pC1->r); + pOut->g = pC1->g + s * (pC2->g - pC1->g); + pOut->b = pC1->b + s * (pC2->b - pC1->b); + pOut->a = pC1->a + s * (pC2->a - pC1->a); + return pOut; +} + + +#endif // __D3DX9MATH_INL__ + diff --git a/builddir/irrlicht-1.8.1/include/d3dx9mesh.h b/builddir/irrlicht-1.8.1/include/d3dx9mesh.h new file mode 100644 index 0000000..a009d9a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx9mesh.h @@ -0,0 +1,3007 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9mesh.h +// Content: D3DX mesh types and functions +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9MESH_H__ +#define __D3DX9MESH_H__ + +// {7ED943DD-52E8-40b5-A8D8-76685C406330} +DEFINE_GUID(IID_ID3DXBaseMesh, +0x7ed943dd, 0x52e8, 0x40b5, 0xa8, 0xd8, 0x76, 0x68, 0x5c, 0x40, 0x63, 0x30); + +// {4020E5C2-1403-4929-883F-E2E849FAC195} +DEFINE_GUID(IID_ID3DXMesh, +0x4020e5c2, 0x1403, 0x4929, 0x88, 0x3f, 0xe2, 0xe8, 0x49, 0xfa, 0xc1, 0x95); + +// {8875769A-D579-4088-AAEB-534D1AD84E96} +DEFINE_GUID(IID_ID3DXPMesh, +0x8875769a, 0xd579, 0x4088, 0xaa, 0xeb, 0x53, 0x4d, 0x1a, 0xd8, 0x4e, 0x96); + +// {667EA4C7-F1CD-4386-B523-7C0290B83CC5} +DEFINE_GUID(IID_ID3DXSPMesh, +0x667ea4c7, 0xf1cd, 0x4386, 0xb5, 0x23, 0x7c, 0x2, 0x90, 0xb8, 0x3c, 0xc5); + +// {11EAA540-F9A6-4d49-AE6A-E19221F70CC4} +DEFINE_GUID(IID_ID3DXSkinInfo, +0x11eaa540, 0xf9a6, 0x4d49, 0xae, 0x6a, 0xe1, 0x92, 0x21, 0xf7, 0xc, 0xc4); + +// {3CE6CC22-DBF2-44f4-894D-F9C34A337139} +DEFINE_GUID(IID_ID3DXPatchMesh, +0x3ce6cc22, 0xdbf2, 0x44f4, 0x89, 0x4d, 0xf9, 0xc3, 0x4a, 0x33, 0x71, 0x39); + +//patch mesh can be quads or tris +typedef enum _D3DXPATCHMESHTYPE { + D3DXPATCHMESH_RECT = 0x001, + D3DXPATCHMESH_TRI = 0x002, + D3DXPATCHMESH_NPATCH = 0x003, + + D3DXPATCHMESH_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DXPATCHMESHTYPE; + +// Mesh options - lower 3 bytes only, upper byte used by _D3DXMESHOPT option flags +enum _D3DXMESH { + D3DXMESH_32BIT = 0x001, // If set, then use 32 bit indices, if not set use 16 bit indices. + D3DXMESH_DONOTCLIP = 0x002, // Use D3DUSAGE_DONOTCLIP for VB & IB. + D3DXMESH_POINTS = 0x004, // Use D3DUSAGE_POINTS for VB & IB. + D3DXMESH_RTPATCHES = 0x008, // Use D3DUSAGE_RTPATCHES for VB & IB. + D3DXMESH_NPATCHES = 0x4000,// Use D3DUSAGE_NPATCHES for VB & IB. + D3DXMESH_VB_SYSTEMMEM = 0x010, // Use D3DPOOL_SYSTEMMEM for VB. Overrides D3DXMESH_MANAGEDVERTEXBUFFER + D3DXMESH_VB_MANAGED = 0x020, // Use D3DPOOL_MANAGED for VB. + D3DXMESH_VB_WRITEONLY = 0x040, // Use D3DUSAGE_WRITEONLY for VB. + D3DXMESH_VB_DYNAMIC = 0x080, // Use D3DUSAGE_DYNAMIC for VB. + D3DXMESH_VB_SOFTWAREPROCESSING = 0x8000, // Use D3DUSAGE_SOFTWAREPROCESSING for VB. + D3DXMESH_IB_SYSTEMMEM = 0x100, // Use D3DPOOL_SYSTEMMEM for IB. Overrides D3DXMESH_MANAGEDINDEXBUFFER + D3DXMESH_IB_MANAGED = 0x200, // Use D3DPOOL_MANAGED for IB. + D3DXMESH_IB_WRITEONLY = 0x400, // Use D3DUSAGE_WRITEONLY for IB. + D3DXMESH_IB_DYNAMIC = 0x800, // Use D3DUSAGE_DYNAMIC for IB. + D3DXMESH_IB_SOFTWAREPROCESSING= 0x10000, // Use D3DUSAGE_SOFTWAREPROCESSING for IB. + + D3DXMESH_VB_SHARE = 0x1000, // Valid for Clone* calls only, forces cloned mesh/pmesh to share vertex buffer + + D3DXMESH_USEHWONLY = 0x2000, // Valid for ID3DXSkinInfo::ConvertToBlendedMesh + + // Helper options + D3DXMESH_SYSTEMMEM = 0x110, // D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM + D3DXMESH_MANAGED = 0x220, // D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED + D3DXMESH_WRITEONLY = 0x440, // D3DXMESH_VB_WRITEONLY | D3DXMESH_IB_WRITEONLY + D3DXMESH_DYNAMIC = 0x880, // D3DXMESH_VB_DYNAMIC | D3DXMESH_IB_DYNAMIC + D3DXMESH_SOFTWAREPROCESSING = 0x18000, // D3DXMESH_VB_SOFTWAREPROCESSING | D3DXMESH_IB_SOFTWAREPROCESSING + +}; + +//patch mesh options +enum _D3DXPATCHMESH { + D3DXPATCHMESH_DEFAULT = 000, +}; +// option field values for specifying min value in D3DXGeneratePMesh and D3DXSimplifyMesh +enum _D3DXMESHSIMP +{ + D3DXMESHSIMP_VERTEX = 0x1, + D3DXMESHSIMP_FACE = 0x2, + +}; + +typedef enum _D3DXCLEANTYPE { + D3DXCLEAN_BACKFACING = 0x00000001, + D3DXCLEAN_BOWTIES = 0x00000002, + + // Helper options + D3DXCLEAN_SKINNING = D3DXCLEAN_BACKFACING, // Bowtie cleaning modifies geometry and breaks skinning + D3DXCLEAN_OPTIMIZATION = D3DXCLEAN_BACKFACING, + D3DXCLEAN_SIMPLIFICATION= D3DXCLEAN_BACKFACING | D3DXCLEAN_BOWTIES, +} D3DXCLEANTYPE; + +enum _MAX_FVF_DECL_SIZE +{ + MAX_FVF_DECL_SIZE = MAXD3DDECLLENGTH + 1 // +1 for END +}; + +typedef enum _D3DXTANGENT +{ + D3DXTANGENT_WRAP_U = 0x01, + D3DXTANGENT_WRAP_V = 0x02, + D3DXTANGENT_WRAP_UV = 0x03, + D3DXTANGENT_DONT_NORMALIZE_PARTIALS = 0x04, + D3DXTANGENT_DONT_ORTHOGONALIZE = 0x08, + D3DXTANGENT_ORTHOGONALIZE_FROM_V = 0x010, + D3DXTANGENT_ORTHOGONALIZE_FROM_U = 0x020, + D3DXTANGENT_WEIGHT_BY_AREA = 0x040, + D3DXTANGENT_WEIGHT_EQUAL = 0x080, + D3DXTANGENT_WIND_CW = 0x0100, + D3DXTANGENT_CALCULATE_NORMALS = 0x0200, + D3DXTANGENT_GENERATE_IN_PLACE = 0x0400, +} D3DXTANGENT; + +// D3DXIMT_WRAP_U means the texture wraps in the U direction +// D3DXIMT_WRAP_V means the texture wraps in the V direction +// D3DXIMT_WRAP_UV means the texture wraps in both directions +typedef enum _D3DXIMT +{ + D3DXIMT_WRAP_U = 0x01, + D3DXIMT_WRAP_V = 0x02, + D3DXIMT_WRAP_UV = 0x03, +} D3DXIMT; + +// These options are only valid for UVAtlasCreate and UVAtlasPartition, we may add more for UVAtlasPack if necessary +// D3DXUVATLAS_DEFAULT - Meshes with more than 25k faces go through fast, meshes with fewer than 25k faces go through quality +// D3DXUVATLAS_GEODESIC_FAST - Uses approximations to improve charting speed at the cost of added stretch or more charts. +// D3DXUVATLAS_GEODESIC_QUALITY - Provides better quality charts, but requires more time and memory than fast. +typedef enum _D3DXUVATLAS +{ + D3DXUVATLAS_DEFAULT = 0x00, + D3DXUVATLAS_GEODESIC_FAST = 0x01, + D3DXUVATLAS_GEODESIC_QUALITY = 0x02, +} D3DXUVATLAS; + +typedef struct ID3DXBaseMesh *LPD3DXBASEMESH; +typedef struct ID3DXMesh *LPD3DXMESH; +typedef struct ID3DXPMesh *LPD3DXPMESH; +typedef struct ID3DXSPMesh *LPD3DXSPMESH; +typedef struct ID3DXSkinInfo *LPD3DXSKININFO; +typedef struct ID3DXPatchMesh *LPD3DXPATCHMESH; +typedef interface ID3DXTextureGutterHelper *LPD3DXTEXTUREGUTTERHELPER; +typedef interface ID3DXPRTBuffer *LPD3DXPRTBUFFER; + + +typedef struct _D3DXATTRIBUTERANGE +{ + DWORD AttribId; + DWORD FaceStart; + DWORD FaceCount; + DWORD VertexStart; + DWORD VertexCount; +} D3DXATTRIBUTERANGE; + +typedef D3DXATTRIBUTERANGE* LPD3DXATTRIBUTERANGE; + +typedef struct _D3DXMATERIAL +{ + D3DMATERIAL9 MatD3D; + LPSTR pTextureFilename; +} D3DXMATERIAL; +typedef D3DXMATERIAL *LPD3DXMATERIAL; + +typedef enum _D3DXEFFECTDEFAULTTYPE +{ + D3DXEDT_STRING = 0x1, // pValue points to a null terminated ASCII string + D3DXEDT_FLOATS = 0x2, // pValue points to an array of floats - number of floats is NumBytes / sizeof(float) + D3DXEDT_DWORD = 0x3, // pValue points to a DWORD + + D3DXEDT_FORCEDWORD = 0x7fffffff +} D3DXEFFECTDEFAULTTYPE; + +typedef struct _D3DXEFFECTDEFAULT +{ + LPSTR pParamName; + D3DXEFFECTDEFAULTTYPE Type; // type of the data pointed to by pValue + DWORD NumBytes; // size in bytes of the data pointed to by pValue + LPVOID pValue; // data for the default of the effect +} D3DXEFFECTDEFAULT, *LPD3DXEFFECTDEFAULT; + +typedef struct _D3DXEFFECTINSTANCE +{ + LPSTR pEffectFilename; + DWORD NumDefaults; + LPD3DXEFFECTDEFAULT pDefaults; +} D3DXEFFECTINSTANCE, *LPD3DXEFFECTINSTANCE; + +typedef struct _D3DXATTRIBUTEWEIGHTS +{ + FLOAT Position; + FLOAT Boundary; + FLOAT Normal; + FLOAT Diffuse; + FLOAT Specular; + FLOAT Texcoord[8]; + FLOAT Tangent; + FLOAT Binormal; +} D3DXATTRIBUTEWEIGHTS, *LPD3DXATTRIBUTEWEIGHTS; + +enum _D3DXWELDEPSILONSFLAGS +{ + D3DXWELDEPSILONS_WELDALL = 0x1, // weld all vertices marked by adjacency as being overlapping + + D3DXWELDEPSILONS_WELDPARTIALMATCHES = 0x2, // if a given vertex component is within epsilon, modify partial matched + // vertices so that both components identical AND if all components "equal" + // remove one of the vertices + D3DXWELDEPSILONS_DONOTREMOVEVERTICES = 0x4, // instructs weld to only allow modifications to vertices and not removal + // ONLY valid if D3DXWELDEPSILONS_WELDPARTIALMATCHES is set + // useful to modify vertices to be equal, but not allow vertices to be removed + + D3DXWELDEPSILONS_DONOTSPLIT = 0x8, // instructs weld to specify the D3DXMESHOPT_DONOTSPLIT flag when doing an Optimize(ATTR_SORT) + // if this flag is not set, all vertices that are in separate attribute groups + // will remain split and not welded. Setting this flag can slow down software vertex processing + +}; + +typedef struct _D3DXWELDEPSILONS +{ + FLOAT Position; // NOTE: This does NOT replace the epsilon in GenerateAdjacency + // in general, it should be the same value or greater than the one passed to GeneratedAdjacency + FLOAT BlendWeights; + FLOAT Normal; + FLOAT PSize; + FLOAT Specular; + FLOAT Diffuse; + FLOAT Texcoord[8]; + FLOAT Tangent; + FLOAT Binormal; + FLOAT TessFactor; +} D3DXWELDEPSILONS; + +typedef D3DXWELDEPSILONS* LPD3DXWELDEPSILONS; + + +#undef INTERFACE +#define INTERFACE ID3DXBaseMesh + +DECLARE_INTERFACE_(ID3DXBaseMesh, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBaseMesh + STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetNumBytesPerVertex)(THIS) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(GetAttributeTable)( + THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; + + STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; + STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; + STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; + + STDMETHOD(UpdateSemantics)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; +}; + + +#undef INTERFACE +#define INTERFACE ID3DXMesh + +DECLARE_INTERFACE_(ID3DXMesh, ID3DXBaseMesh) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBaseMesh + STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetNumBytesPerVertex)(THIS) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(GetAttributeTable)( + THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; + + STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; + STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; + STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; + + STDMETHOD(UpdateSemantics)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + + // ID3DXMesh + STDMETHOD(LockAttributeBuffer)(THIS_ DWORD Flags, DWORD** ppData) PURE; + STDMETHOD(UnlockAttributeBuffer)(THIS) PURE; + STDMETHOD(Optimize)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, + DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, + LPD3DXMESH* ppOptMesh) PURE; + STDMETHOD(OptimizeInplace)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, + DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap) PURE; + STDMETHOD(SetAttributeTable)(THIS_ CONST D3DXATTRIBUTERANGE *pAttribTable, DWORD cAttribTableSize) PURE; +}; + + +#undef INTERFACE +#define INTERFACE ID3DXPMesh + +DECLARE_INTERFACE_(ID3DXPMesh, ID3DXBaseMesh) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBaseMesh + STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetNumBytesPerVertex)(THIS) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(GetAttributeTable)( + THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; + + STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; + STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; + STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; + + STDMETHOD(UpdateSemantics)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + + // ID3DXPMesh + STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(ClonePMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(SetNumFaces)(THIS_ DWORD Faces) PURE; + STDMETHOD(SetNumVertices)(THIS_ DWORD Vertices) PURE; + STDMETHOD_(DWORD, GetMaxFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetMinFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetMaxVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetMinVertices)(THIS) PURE; + STDMETHOD(Save)(THIS_ IStream *pStream, CONST D3DXMATERIAL* pMaterials, CONST D3DXEFFECTINSTANCE* pEffectInstances, DWORD NumMaterials) PURE; + + STDMETHOD(Optimize)(THIS_ DWORD Flags, DWORD* pAdjacencyOut, + DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, + LPD3DXMESH* ppOptMesh) PURE; + + STDMETHOD(OptimizeBaseLOD)(THIS_ DWORD Flags, DWORD* pFaceRemap) PURE; + STDMETHOD(TrimByFaces)(THIS_ DWORD NewFacesMin, DWORD NewFacesMax, DWORD *rgiFaceRemap, DWORD *rgiVertRemap) PURE; + STDMETHOD(TrimByVertices)(THIS_ DWORD NewVerticesMin, DWORD NewVerticesMax, DWORD *rgiFaceRemap, DWORD *rgiVertRemap) PURE; + + STDMETHOD(GetAdjacency)(THIS_ DWORD* pAdjacency) PURE; + + // Used to generate the immediate "ancestor" for each vertex when it is removed by a vsplit. Allows generation of geomorphs + // Vertex buffer must be equal to or greater than the maximum number of vertices in the pmesh + STDMETHOD(GenerateVertexHistory)(THIS_ DWORD* pVertexHistory) PURE; +}; + + +#undef INTERFACE +#define INTERFACE ID3DXSPMesh + +DECLARE_INTERFACE_(ID3DXSPMesh, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXSPMesh + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pAdjacencyOut, DWORD *pVertexRemapOut, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pAdjacencyOut, DWORD *pVertexRemapOut, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pVertexRemapOut, FLOAT *pErrorsByFace, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(ClonePMesh)(THIS_ DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pVertexRemapOut, FLOAT *pErrorsbyFace, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(ReduceFaces)(THIS_ DWORD Faces) PURE; + STDMETHOD(ReduceVertices)(THIS_ DWORD Vertices) PURE; + STDMETHOD_(DWORD, GetMaxFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetMaxVertices)(THIS) PURE; + STDMETHOD(GetVertexAttributeWeights)(THIS_ LPD3DXATTRIBUTEWEIGHTS pVertexAttributeWeights) PURE; + STDMETHOD(GetVertexWeights)(THIS_ FLOAT *pVertexWeights) PURE; +}; + +#define UNUSED16 (0xffff) +#define UNUSED32 (0xffffffff) + +// ID3DXMesh::Optimize options - upper byte only, lower 3 bytes used from _D3DXMESH option flags +enum _D3DXMESHOPT { + D3DXMESHOPT_COMPACT = 0x01000000, + D3DXMESHOPT_ATTRSORT = 0x02000000, + D3DXMESHOPT_VERTEXCACHE = 0x04000000, + D3DXMESHOPT_STRIPREORDER = 0x08000000, + D3DXMESHOPT_IGNOREVERTS = 0x10000000, // optimize faces only, don't touch vertices + D3DXMESHOPT_DONOTSPLIT = 0x20000000, // do not split vertices shared between attribute groups when attribute sorting + D3DXMESHOPT_DEVICEINDEPENDENT = 0x00400000, // Only affects VCache. uses a static known good cache size for all cards + + // D3DXMESHOPT_SHAREVB has been removed, please use D3DXMESH_VB_SHARE instead + +}; + +// Subset of the mesh that has the same attribute and bone combination. +// This subset can be rendered in a single draw call +typedef struct _D3DXBONECOMBINATION +{ + DWORD AttribId; + DWORD FaceStart; + DWORD FaceCount; + DWORD VertexStart; + DWORD VertexCount; + DWORD* BoneId; +} D3DXBONECOMBINATION, *LPD3DXBONECOMBINATION; + +// The following types of patch combinations are supported: +// Patch type Basis Degree +// Rect Bezier 2,3,5 +// Rect B-Spline 2,3,5 +// Rect Catmull-Rom 3 +// Tri Bezier 2,3,5 +// N-Patch N/A 3 + +typedef struct _D3DXPATCHINFO +{ + D3DXPATCHMESHTYPE PatchType; + D3DDEGREETYPE Degree; + D3DBASISTYPE Basis; +} D3DXPATCHINFO, *LPD3DXPATCHINFO; + +#undef INTERFACE +#define INTERFACE ID3DXPatchMesh + +DECLARE_INTERFACE_(ID3DXPatchMesh, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXPatchMesh + + // Return creation parameters + STDMETHOD_(DWORD, GetNumPatches)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetControlVerticesPerPatch)(THIS) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9 *ppDevice) PURE; + STDMETHOD(GetPatchInfo)(THIS_ LPD3DXPATCHINFO PatchInfo) PURE; + + // Control mesh access + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD flags, LPVOID *ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(LockAttributeBuffer)(THIS_ DWORD flags, DWORD** ppData) PURE; + STDMETHOD(UnlockAttributeBuffer)(THIS) PURE; + + // This function returns the size of the tessellated mesh given a tessellation level. + // This assumes uniform tessellation. For adaptive tessellation the Adaptive parameter must + // be set to TRUE and TessellationLevel should be the max tessellation. + // This will result in the max mesh size necessary for adaptive tessellation. + STDMETHOD(GetTessSize)(THIS_ FLOAT fTessLevel,DWORD Adaptive, DWORD *NumTriangles,DWORD *NumVertices) PURE; + + //GenerateAdjacency determines which patches are adjacent with provided tolerance + //this information is used internally to optimize tessellation + STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Tolerance) PURE; + + //CloneMesh Creates a new patchmesh with the specified decl, and converts the vertex buffer + //to the new decl. Entries in the new decl which are new are set to 0. If the current mesh + //has adjacency, the new mesh will also have adjacency + STDMETHOD(CloneMesh)(THIS_ DWORD Options, CONST D3DVERTEXELEMENT9 *pDecl, LPD3DXPATCHMESH *pMesh) PURE; + + // Optimizes the patchmesh for efficient tessellation. This function is designed + // to perform one time optimization for patch meshes that need to be tessellated + // repeatedly by calling the Tessellate() method. The optimization performed is + // independent of the actual tessellation level used. + // Currently Flags is unused. + // If vertices are changed, Optimize must be called again + STDMETHOD(Optimize)(THIS_ DWORD flags) PURE; + + //gets and sets displacement parameters + //displacement maps can only be 2D textures MIP-MAPPING is ignored for non adapative tessellation + STDMETHOD(SetDisplaceParam)(THIS_ LPDIRECT3DBASETEXTURE9 Texture, + D3DTEXTUREFILTERTYPE MinFilter, + D3DTEXTUREFILTERTYPE MagFilter, + D3DTEXTUREFILTERTYPE MipFilter, + D3DTEXTUREADDRESS Wrap, + DWORD dwLODBias) PURE; + + STDMETHOD(GetDisplaceParam)(THIS_ LPDIRECT3DBASETEXTURE9 *Texture, + D3DTEXTUREFILTERTYPE *MinFilter, + D3DTEXTUREFILTERTYPE *MagFilter, + D3DTEXTUREFILTERTYPE *MipFilter, + D3DTEXTUREADDRESS *Wrap, + DWORD *dwLODBias) PURE; + + // Performs the uniform tessellation based on the tessellation level. + // This function will perform more efficiently if the patch mesh has been optimized using the Optimize() call. + STDMETHOD(Tessellate)(THIS_ FLOAT fTessLevel,LPD3DXMESH pMesh) PURE; + + // Performs adaptive tessellation based on the Z based adaptive tessellation criterion. + // pTrans specifies a 4D vector that is dotted with the vertices to get the per vertex + // adaptive tessellation amount. Each edge is tessellated to the average of the criterion + // at the 2 vertices it connects. + // MaxTessLevel specifies the upper limit for adaptive tesselation. + // This function will perform more efficiently if the patch mesh has been optimized using the Optimize() call. + STDMETHOD(TessellateAdaptive)(THIS_ + CONST D3DXVECTOR4 *pTrans, + DWORD dwMaxTessLevel, + DWORD dwMinTessLevel, + LPD3DXMESH pMesh) PURE; + +}; + +#undef INTERFACE +#define INTERFACE ID3DXSkinInfo + +DECLARE_INTERFACE_(ID3DXSkinInfo, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Specify the which vertices do each bones influence and by how much + STDMETHOD(SetBoneInfluence)(THIS_ DWORD bone, DWORD numInfluences, CONST DWORD* vertices, CONST FLOAT* weights) PURE; + STDMETHOD(SetBoneVertexInfluence)(THIS_ DWORD boneNum, DWORD influenceNum, float weight) PURE; + STDMETHOD_(DWORD, GetNumBoneInfluences)(THIS_ DWORD bone) PURE; + STDMETHOD(GetBoneInfluence)(THIS_ DWORD bone, DWORD* vertices, FLOAT* weights) PURE; + STDMETHOD(GetBoneVertexInfluence)(THIS_ DWORD boneNum, DWORD influenceNum, float *pWeight, DWORD *pVertexNum) PURE; + STDMETHOD(GetMaxVertexInfluences)(THIS_ DWORD* maxVertexInfluences) PURE; + STDMETHOD_(DWORD, GetNumBones)(THIS) PURE; + STDMETHOD(FindBoneVertexInfluenceIndex)(THIS_ DWORD boneNum, DWORD vertexNum, DWORD *pInfluenceIndex) PURE; + + // This gets the max face influences based on a triangle mesh with the specified index buffer + STDMETHOD(GetMaxFaceInfluences)(THIS_ LPDIRECT3DINDEXBUFFER9 pIB, DWORD NumFaces, DWORD* maxFaceInfluences) PURE; + + // Set min bone influence. Bone influences that are smaller than this are ignored + STDMETHOD(SetMinBoneInfluence)(THIS_ FLOAT MinInfl) PURE; + // Get min bone influence. + STDMETHOD_(FLOAT, GetMinBoneInfluence)(THIS) PURE; + + // Bone names are returned by D3DXLoadSkinMeshFromXof. They are not used by any other method of this object + STDMETHOD(SetBoneName)(THIS_ DWORD Bone, LPCSTR pName) PURE; // pName is copied to an internal string buffer + STDMETHOD_(LPCSTR, GetBoneName)(THIS_ DWORD Bone) PURE; // A pointer to an internal string buffer is returned. Do not free this. + + // Bone offset matrices are returned by D3DXLoadSkinMeshFromXof. They are not used by any other method of this object + STDMETHOD(SetBoneOffsetMatrix)(THIS_ DWORD Bone, CONST D3DXMATRIX *pBoneTransform) PURE; // pBoneTransform is copied to an internal buffer + STDMETHOD_(LPD3DXMATRIX, GetBoneOffsetMatrix)(THIS_ DWORD Bone) PURE; // A pointer to an internal matrix is returned. Do not free this. + + // Clone a skin info object + STDMETHOD(Clone)(THIS_ LPD3DXSKININFO* ppSkinInfo) PURE; + + // Update bone influence information to match vertices after they are reordered. This should be called + // if the target vertex buffer has been reordered externally. + STDMETHOD(Remap)(THIS_ DWORD NumVertices, DWORD* pVertexRemap) PURE; + + // These methods enable the modification of the vertex layout of the vertices that will be skinned + STDMETHOD(SetFVF)(THIS_ DWORD FVF) PURE; + STDMETHOD(SetDeclaration)(THIS_ CONST D3DVERTEXELEMENT9 *pDeclaration) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; + + // Apply SW skinning based on current pose matrices to the target vertices. + STDMETHOD(UpdateSkinnedMesh)(THIS_ + CONST D3DXMATRIX* pBoneTransforms, + CONST D3DXMATRIX* pBoneInvTransposeTransforms, + LPCVOID pVerticesSrc, + PVOID pVerticesDst) PURE; + + // Takes a mesh and returns a new mesh with per vertex blend weights and a bone combination + // table that describes which bones affect which subsets of the mesh + STDMETHOD(ConvertToBlendedMesh)(THIS_ + LPD3DXMESH pMesh, + DWORD Options, + CONST DWORD *pAdjacencyIn, + LPDWORD pAdjacencyOut, + DWORD* pFaceRemap, + LPD3DXBUFFER *ppVertexRemap, + DWORD* pMaxFaceInfl, + DWORD* pNumBoneCombinations, + LPD3DXBUFFER* ppBoneCombinationTable, + LPD3DXMESH* ppMesh) PURE; + + // Takes a mesh and returns a new mesh with per vertex blend weights and indices + // and a bone combination table that describes which bones palettes affect which subsets of the mesh + STDMETHOD(ConvertToIndexedBlendedMesh)(THIS_ + LPD3DXMESH pMesh, + DWORD Options, + DWORD paletteSize, + CONST DWORD *pAdjacencyIn, + LPDWORD pAdjacencyOut, + DWORD* pFaceRemap, + LPD3DXBUFFER *ppVertexRemap, + DWORD* pMaxVertexInfl, + DWORD* pNumBoneCombinations, + LPD3DXBUFFER* ppBoneCombinationTable, + LPD3DXMESH* ppMesh) PURE; +}; + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +HRESULT WINAPI + D3DXCreateMesh( + DWORD NumFaces, + DWORD NumVertices, + DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXMESH* ppMesh); + +HRESULT WINAPI + D3DXCreateMeshFVF( + DWORD NumFaces, + DWORD NumVertices, + DWORD Options, + DWORD FVF, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXMESH* ppMesh); + +HRESULT WINAPI + D3DXCreateSPMesh( + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights, + CONST FLOAT *pVertexWeights, + LPD3DXSPMESH* ppSMesh); + +// clean a mesh up for simplification, try to make manifold +HRESULT WINAPI + D3DXCleanMesh( + D3DXCLEANTYPE CleanType, + LPD3DXMESH pMeshIn, + CONST DWORD* pAdjacencyIn, + LPD3DXMESH* ppMeshOut, + DWORD* pAdjacencyOut, + LPD3DXBUFFER* ppErrorsAndWarnings); + +HRESULT WINAPI + D3DXValidMesh( + LPD3DXMESH pMeshIn, + CONST DWORD* pAdjacency, + LPD3DXBUFFER* ppErrorsAndWarnings); + +HRESULT WINAPI + D3DXGeneratePMesh( + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights, + CONST FLOAT *pVertexWeights, + DWORD MinValue, + DWORD Options, + LPD3DXPMESH* ppPMesh); + +HRESULT WINAPI + D3DXSimplifyMesh( + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights, + CONST FLOAT *pVertexWeights, + DWORD MinValue, + DWORD Options, + LPD3DXMESH* ppMesh); + +HRESULT WINAPI + D3DXComputeBoundingSphere( + CONST D3DXVECTOR3 *pFirstPosition, // pointer to first position + DWORD NumVertices, + DWORD dwStride, // count in bytes to subsequent position vectors + D3DXVECTOR3 *pCenter, + FLOAT *pRadius); + +HRESULT WINAPI + D3DXComputeBoundingBox( + CONST D3DXVECTOR3 *pFirstPosition, // pointer to first position + DWORD NumVertices, + DWORD dwStride, // count in bytes to subsequent position vectors + D3DXVECTOR3 *pMin, + D3DXVECTOR3 *pMax); + +HRESULT WINAPI + D3DXComputeNormals( + LPD3DXBASEMESH pMesh, + CONST DWORD *pAdjacency); + +HRESULT WINAPI + D3DXCreateBuffer( + DWORD NumBytes, + LPD3DXBUFFER *ppBuffer); + + +HRESULT WINAPI + D3DXLoadMeshFromXA( + LPCSTR pFilename, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +HRESULT WINAPI + D3DXLoadMeshFromXW( + LPCWSTR pFilename, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +#ifdef UNICODE +#define D3DXLoadMeshFromX D3DXLoadMeshFromXW +#else +#define D3DXLoadMeshFromX D3DXLoadMeshFromXA +#endif + +HRESULT WINAPI + D3DXLoadMeshFromXInMemory( + LPCVOID Memory, + DWORD SizeOfMemory, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +HRESULT WINAPI + D3DXLoadMeshFromXResource( + HMODULE Module, + LPCSTR Name, + LPCSTR Type, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +HRESULT WINAPI + D3DXSaveMeshToXA( + LPCSTR pFilename, + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST D3DXMATERIAL* pMaterials, + CONST D3DXEFFECTINSTANCE* pEffectInstances, + DWORD NumMaterials, + DWORD Format + ); + +HRESULT WINAPI + D3DXSaveMeshToXW( + LPCWSTR pFilename, + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST D3DXMATERIAL* pMaterials, + CONST D3DXEFFECTINSTANCE* pEffectInstances, + DWORD NumMaterials, + DWORD Format + ); + +#ifdef UNICODE +#define D3DXSaveMeshToX D3DXSaveMeshToXW +#else +#define D3DXSaveMeshToX D3DXSaveMeshToXA +#endif + + +HRESULT WINAPI + D3DXCreatePMeshFromStream( + IStream *pStream, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD* pNumMaterials, + LPD3DXPMESH *ppPMesh); + +// Creates a skin info object based on the number of vertices, number of bones, and a declaration describing the vertex layout of the target vertices +// The bone names and initial bone transforms are not filled in the skin info object by this method. +HRESULT WINAPI + D3DXCreateSkinInfo( + DWORD NumVertices, + CONST D3DVERTEXELEMENT9 *pDeclaration, + DWORD NumBones, + LPD3DXSKININFO* ppSkinInfo); + +// Creates a skin info object based on the number of vertices, number of bones, and a FVF describing the vertex layout of the target vertices +// The bone names and initial bone transforms are not filled in the skin info object by this method. +HRESULT WINAPI + D3DXCreateSkinInfoFVF( + DWORD NumVertices, + DWORD FVF, + DWORD NumBones, + LPD3DXSKININFO* ppSkinInfo); + +#ifdef __cplusplus +} + +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXLoadMeshFromXof( + LPD3DXFILEDATA pxofMesh, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +// This similar to D3DXLoadMeshFromXof, except also returns skinning info if present in the file +// If skinning info is not present, ppSkinInfo will be NULL +HRESULT WINAPI + D3DXLoadSkinMeshFromXof( + LPD3DXFILEDATA pxofMesh, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER* ppAdjacency, + LPD3DXBUFFER* ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + DWORD *pMatOut, + LPD3DXSKININFO* ppSkinInfo, + LPD3DXMESH* ppMesh); + + +// The inverse of D3DXConvertTo{Indexed}BlendedMesh() functions. It figures out the skinning info from +// the mesh and the bone combination table and populates a skin info object with that data. The bone +// names and initial bone transforms are not filled in the skin info object by this method. This works +// with either a non-indexed or indexed blended mesh. It examines the FVF or declarator of the mesh to +// determine what type it is. +HRESULT WINAPI + D3DXCreateSkinInfoFromBlendedMesh( + LPD3DXBASEMESH pMesh, + DWORD NumBones, + CONST D3DXBONECOMBINATION *pBoneCombinationTable, + LPD3DXSKININFO* ppSkinInfo); + +HRESULT WINAPI + D3DXTessellateNPatches( + LPD3DXMESH pMeshIn, + CONST DWORD* pAdjacencyIn, + FLOAT NumSegs, + BOOL QuadraticInterpNormals, // if false use linear intrep for normals, if true use quadratic + LPD3DXMESH *ppMeshOut, + LPD3DXBUFFER *ppAdjacencyOut); + + +//generates implied outputdecl from input decl +//the decl generated from this should be used to generate the output decl for +//the tessellator subroutines. + +HRESULT WINAPI + D3DXGenerateOutputDecl( + D3DVERTEXELEMENT9 *pOutput, + CONST D3DVERTEXELEMENT9 *pInput); + +//loads patches from an XFileData +//since an X file can have up to 6 different patch meshes in it, +//returns them in an array - pNumPatches will contain the number of +//meshes in the actual file. +HRESULT WINAPI + D3DXLoadPatchMeshFromXof( + LPD3DXFILEDATA pXofObjMesh, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, + PDWORD pNumMaterials, + LPD3DXPATCHMESH *ppMesh); + +//computes the size a single rect patch. +HRESULT WINAPI + D3DXRectPatchSize( + CONST FLOAT *pfNumSegs, //segments for each edge (4) + DWORD *pdwTriangles, //output number of triangles + DWORD *pdwVertices); //output number of vertices + +//computes the size of a single triangle patch +HRESULT WINAPI + D3DXTriPatchSize( + CONST FLOAT *pfNumSegs, //segments for each edge (3) + DWORD *pdwTriangles, //output number of triangles + DWORD *pdwVertices); //output number of vertices + + +//tessellates a patch into a created mesh +//similar to D3D RT patch +HRESULT WINAPI + D3DXTessellateRectPatch( + LPDIRECT3DVERTEXBUFFER9 pVB, + CONST FLOAT *pNumSegs, + CONST D3DVERTEXELEMENT9 *pdwInDecl, + CONST D3DRECTPATCH_INFO *pRectPatchInfo, + LPD3DXMESH pMesh); + + +HRESULT WINAPI + D3DXTessellateTriPatch( + LPDIRECT3DVERTEXBUFFER9 pVB, + CONST FLOAT *pNumSegs, + CONST D3DVERTEXELEMENT9 *pInDecl, + CONST D3DTRIPATCH_INFO *pTriPatchInfo, + LPD3DXMESH pMesh); + + + +//creates an NPatch PatchMesh from a D3DXMESH +HRESULT WINAPI + D3DXCreateNPatchMesh( + LPD3DXMESH pMeshSysMem, + LPD3DXPATCHMESH *pPatchMesh); + + +//creates a patch mesh +HRESULT WINAPI + D3DXCreatePatchMesh( + CONST D3DXPATCHINFO *pInfo, //patch type + DWORD dwNumPatches, //number of patches + DWORD dwNumVertices, //number of control vertices + DWORD dwOptions, //options + CONST D3DVERTEXELEMENT9 *pDecl, //format of control vertices + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXPATCHMESH *pPatchMesh); + + +//returns the number of degenerates in a patch mesh - +//text output put in string. +HRESULT WINAPI + D3DXValidPatchMesh(LPD3DXPATCHMESH pMesh, + DWORD *dwcDegenerateVertices, + DWORD *dwcDegeneratePatches, + LPD3DXBUFFER *ppErrorsAndWarnings); + +UINT WINAPI + D3DXGetFVFVertexSize(DWORD FVF); + +UINT WINAPI + D3DXGetDeclVertexSize(CONST D3DVERTEXELEMENT9 *pDecl,DWORD Stream); + +UINT WINAPI + D3DXGetDeclLength(CONST D3DVERTEXELEMENT9 *pDecl); + +HRESULT WINAPI + D3DXDeclaratorFromFVF( + DWORD FVF, + D3DVERTEXELEMENT9 pDeclarator[MAX_FVF_DECL_SIZE]); + +HRESULT WINAPI + D3DXFVFFromDeclarator( + CONST D3DVERTEXELEMENT9 *pDeclarator, + DWORD *pFVF); + +HRESULT WINAPI + D3DXWeldVertices( + LPD3DXMESH pMesh, + DWORD Flags, + CONST D3DXWELDEPSILONS *pEpsilons, + CONST DWORD *pAdjacencyIn, + DWORD *pAdjacencyOut, + DWORD *pFaceRemap, + LPD3DXBUFFER *ppVertexRemap); + +typedef struct _D3DXINTERSECTINFO +{ + DWORD FaceIndex; // index of face intersected + FLOAT U; // Barycentric Hit Coordinates + FLOAT V; // Barycentric Hit Coordinates + FLOAT Dist; // Ray-Intersection Parameter Distance +} D3DXINTERSECTINFO, *LPD3DXINTERSECTINFO; + + +HRESULT WINAPI + D3DXIntersect( + LPD3DXBASEMESH pMesh, + CONST D3DXVECTOR3 *pRayPos, + CONST D3DXVECTOR3 *pRayDir, + BOOL *pHit, // True if any faces were intersected + DWORD *pFaceIndex, // index of closest face intersected + FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pV, // Barycentric Hit Coordinates + FLOAT *pDist, // Ray-Intersection Parameter Distance + LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) + DWORD *pCountOfHits); // Number of entries in AllHits array + +HRESULT WINAPI + D3DXIntersectSubset( + LPD3DXBASEMESH pMesh, + DWORD AttribId, + CONST D3DXVECTOR3 *pRayPos, + CONST D3DXVECTOR3 *pRayDir, + BOOL *pHit, // True if any faces were intersected + DWORD *pFaceIndex, // index of closest face intersected + FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pV, // Barycentric Hit Coordinates + FLOAT *pDist, // Ray-Intersection Parameter Distance + LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) + DWORD *pCountOfHits); // Number of entries in AllHits array + + +HRESULT WINAPI D3DXSplitMesh + ( + LPD3DXMESH pMeshIn, + CONST DWORD *pAdjacencyIn, + CONST DWORD MaxSize, + CONST DWORD Options, + DWORD *pMeshesOut, + LPD3DXBUFFER *ppMeshArrayOut, + LPD3DXBUFFER *ppAdjacencyArrayOut, + LPD3DXBUFFER *ppFaceRemapArrayOut, + LPD3DXBUFFER *ppVertRemapArrayOut + ); + +BOOL WINAPI D3DXIntersectTri +( + CONST D3DXVECTOR3 *p0, // Triangle vertex 0 position + CONST D3DXVECTOR3 *p1, // Triangle vertex 1 position + CONST D3DXVECTOR3 *p2, // Triangle vertex 2 position + CONST D3DXVECTOR3 *pRayPos, // Ray origin + CONST D3DXVECTOR3 *pRayDir, // Ray direction + FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pV, // Barycentric Hit Coordinates + FLOAT *pDist); // Ray-Intersection Parameter Distance + +BOOL WINAPI + D3DXSphereBoundProbe( + CONST D3DXVECTOR3 *pCenter, + FLOAT Radius, + CONST D3DXVECTOR3 *pRayPosition, + CONST D3DXVECTOR3 *pRayDirection); + +BOOL WINAPI + D3DXBoxBoundProbe( + CONST D3DXVECTOR3 *pMin, + CONST D3DXVECTOR3 *pMax, + CONST D3DXVECTOR3 *pRayPosition, + CONST D3DXVECTOR3 *pRayDirection); + + +HRESULT WINAPI D3DXComputeTangentFrame(ID3DXMesh *pMesh, + DWORD dwOptions); + +HRESULT WINAPI D3DXComputeTangentFrameEx(ID3DXMesh *pMesh, + DWORD dwTextureInSemantic, + DWORD dwTextureInIndex, + DWORD dwUPartialOutSemantic, + DWORD dwUPartialOutIndex, + DWORD dwVPartialOutSemantic, + DWORD dwVPartialOutIndex, + DWORD dwNormalOutSemantic, + DWORD dwNormalOutIndex, + DWORD dwOptions, + CONST DWORD *pdwAdjacency, + FLOAT fPartialEdgeThreshold, + FLOAT fSingularPointThreshold, + FLOAT fNormalEdgeThreshold, + ID3DXMesh **ppMeshOut, + ID3DXBuffer **ppVertexMapping); + + +//D3DXComputeTangent +// +//Computes the Tangent vectors for the TexStage texture coordinates +//and places the results in the TANGENT[TangentIndex] specified in the meshes' DECL +//puts the binorm in BINORM[BinormIndex] also specified in the decl. +// +//If neither the binorm or the tangnet are in the meshes declaration, +//the function will fail. +// +//If a tangent or Binorm field is in the Decl, but the user does not +//wish D3DXComputeTangent to replace them, then D3DX_DEFAULT specified +//in the TangentIndex or BinormIndex will cause it to ignore the specified +//semantic. +// +//Wrap should be specified if the texture coordinates wrap. + +HRESULT WINAPI D3DXComputeTangent(LPD3DXMESH Mesh, + DWORD TexStage, + DWORD TangentIndex, + DWORD BinormIndex, + DWORD Wrap, + CONST DWORD *pAdjacency); + +//============================================================================ +// +// UVAtlas apis +// +//============================================================================ +typedef HRESULT (WINAPI *LPD3DXUVATLASCB)(FLOAT fPercentDone, LPVOID lpUserContext); + +// This function creates atlases for meshes. There are two modes of operation, +// either based on the number of charts, or the maximum allowed stretch. If the +// maximum allowed stretch is 0, then each triangle will likely be in its own +// chart. + +// +// The parameters are as follows: +// pMesh - Input mesh to calculate an atlas for. This must have a position +// channel and at least a 2-d texture channel. +// uMaxChartNumber - The maximum number of charts required for the atlas. +// If this is 0, it will be parameterized based solely on +// stretch. +// fMaxStretch - The maximum amount of stretch, if 0, no stretching is allowed, +// if 1, then any amount of stretching is allowed. +// uWidth - The width of the texture the atlas will be used on. +// uHeight - The height of the texture the atlas will be used on. +// fGutter - The minimum distance, in texels between two charts on the atlas. +// this gets scaled by the width, so if fGutter is 2.5, and it is +// used on a 512x512 texture, then the minimum distance will be +// 2.5 / 512 in u-v space. +// dwTextureIndex - Specifies which texture coordinate to write to in the +// output mesh (which is cloned from the input mesh). Useful +// if your vertex has multiple texture coordinates. +// pdwAdjacency - a pointer to an array with 3 DWORDs per face, indicating +// which triangles are adjacent to each other. +// pdwFalseEdgeAdjacency - a pointer to an array with 3 DWORDS per face, indicating +// at each face, whether an edge is a false edge or not (using +// the same ordering as the adjacency data structure). If this +// is NULL, then it is assumed that there are no false edges. If +// not NULL, then a non-false edge is indicated by -1 and a false +// edge is indicated by any other value (it is not required, but +// it may be useful for the caller to use the original adjacency +// value). This allows you to parameterize a mesh of quads, and +// the edges down the middle of each quad will not be cut when +// parameterizing the mesh. +// pfIMTArray - a pointer to an array with 3 FLOATs per face, describing the +// integrated metric tensor for that face. This lets you control +// the way this triangle may be stretched in the atlas. The IMT +// passed in will be 3 floats (a,b,c) and specify a symmetric +// matrix (a b) that, given a vector (s,t), specifies the +// (b c) +// distance between a vector v1 and a vector v2 = v1 + (s,t) as +// sqrt((s, t) * M * (s, t)^T). +// In other words, this lets one specify the magnitude of the +// stretch in an arbitrary direction in u-v space. For example +// if a = b = c = 1, then this scales the vector (1,1) by 2, and +// the vector (1,-1) by 0. Note that this is multiplying the edge +// length by the square of the matrix, so if you want the face to +// stretch to twice its +// size with no shearing, the IMT value should be (2, 0, 2), which +// is just the identity matrix times 2. +// Note that this assumes you have an orientation for the triangle +// in some 2-D space. For D3DXUVAtlas, this space is created by +// letting S be the direction from the first to the second +// vertex, and T be the cross product between the normal and S. +// +// pStatusCallback - Since the atlas creation process can be very CPU intensive, +// this allows the programmer to specify a function to be called +// periodically, similarly to how it is done in the PRT simulation +// engine. +// fCallbackFrequency - This lets you specify how often the callback will be +// called. A decent default should be 0.0001f. +// pUserContext - a void pointer to be passed back to the callback function +// dwOptions - A combination of flags in the D3DXUVATLAS enum +// ppMeshOut - A pointer to a location to store a pointer for the newly created +// mesh. +// ppFacePartitioning - A pointer to a location to store a pointer for an array, +// one DWORD per face, giving the final partitioning +// created by the atlasing algorithm. +// ppVertexRemapArray - A pointer to a location to store a pointer for an array, +// one DWORD per vertex, giving the vertex it was copied +// from, if any vertices needed to be split. +// pfMaxStretchOut - A location to store the maximum stretch resulting from the +// atlasing algorithm. +// puNumChartsOut - A location to store the number of charts created, or if the +// maximum number of charts was too low, this gives the minimum +// number of charts needed to create an atlas. + +HRESULT WINAPI D3DXUVAtlasCreate(LPD3DXMESH pMesh, + UINT uMaxChartNumber, + FLOAT fMaxStretch, + UINT uWidth, + UINT uHeight, + FLOAT fGutter, + DWORD dwTextureIndex, + CONST DWORD *pdwAdjacency, + CONST DWORD *pdwFalseEdgeAdjacency, + CONST FLOAT *pfIMTArray, + LPD3DXUVATLASCB pStatusCallback, + FLOAT fCallbackFrequency, + LPVOID pUserContext, + DWORD dwOptions, + LPD3DXMESH *ppMeshOut, + LPD3DXBUFFER *ppFacePartitioning, + LPD3DXBUFFER *ppVertexRemapArray, + FLOAT *pfMaxStretchOut, + UINT *puNumChartsOut); + +// This has the same exact arguments as Create, except that it does not perform the +// final packing step. This method allows one to get a partitioning out, and possibly +// modify it before sending it to be repacked. Note that if you change the +// partitioning, you'll also need to calculate new texture coordinates for any faces +// that have switched charts. +// +// The partition result adjacency output parameter is meant to be passed to the +// UVAtlasPack function, this adjacency cuts edges that are between adjacent +// charts, and also can include cuts inside of a chart in order to make it +// equivalent to a disc. For example: +// +// _______ +// | ___ | +// | |_| | +// |_____| +// +// In order to make this equivalent to a disc, we would need to add a cut, and it +// Would end up looking like: +// _______ +// | ___ | +// | |_|_| +// |_____| +// +// The resulting partition adjacency parameter cannot be NULL, because it is +// required for the packing step. + + + +HRESULT WINAPI D3DXUVAtlasPartition(LPD3DXMESH pMesh, + UINT uMaxChartNumber, + FLOAT fMaxStretch, + DWORD dwTextureIndex, + CONST DWORD *pdwAdjacency, + CONST DWORD *pdwFalseEdgeAdjacency, + CONST FLOAT *pfIMTArray, + LPD3DXUVATLASCB pStatusCallback, + FLOAT fCallbackFrequency, + LPVOID pUserContext, + DWORD dwOptions, + LPD3DXMESH *ppMeshOut, + LPD3DXBUFFER *ppFacePartitioning, + LPD3DXBUFFER *ppVertexRemapArray, + LPD3DXBUFFER *ppPartitionResultAdjacency, + FLOAT *pfMaxStretchOut, + UINT *puNumChartsOut); + +// This takes the face partitioning result from Partition and packs it into an +// atlas of the given size. pdwPartitionResultAdjacency should be derived from +// the adjacency returned from the partition step. This value cannot be NULL +// because Pack needs to know where charts were cut in the partition step in +// order to find the edges of each chart. +// The options parameter is currently reserved. +HRESULT WINAPI D3DXUVAtlasPack(ID3DXMesh *pMesh, + UINT uWidth, + UINT uHeight, + FLOAT fGutter, + DWORD dwTextureIndex, + CONST DWORD *pdwPartitionResultAdjacency, + LPD3DXUVATLASCB pStatusCallback, + FLOAT fCallbackFrequency, + LPVOID pUserContext, + DWORD dwOptions, + LPD3DXBUFFER pFacePartitioning); + + +//============================================================================ +// +// IMT Calculation apis +// +// These functions all compute the Integrated Metric Tensor for use in the +// UVAtlas API. They all calculate the IMT with respect to the canonical +// triangle, where the coordinate system is set up so that the u axis goes +// from vertex 0 to 1 and the v axis is N x u. So, for example, the second +// vertex's canonical uv coordinates are (d,0) where d is the distance between +// vertices 0 and 1. This way the IMT does not depend on the parameterization +// of the mesh, and if the signal over the surface doesn't change, then +// the IMT doesn't need to be recalculated. +//============================================================================ + +// This callback is used by D3DXComputeIMTFromSignal. +// +// uv - The texture coordinate for the vertex. +// uPrimitiveID - Face ID of the triangle on which to compute the signal. +// uSignalDimension - The number of floats to store in pfSignalOut. +// pUserData - The pUserData pointer passed in to ComputeIMTFromSignal. +// pfSignalOut - A pointer to where to store the signal data. +typedef HRESULT (WINAPI* LPD3DXIMTSIGNALCALLBACK) + (CONST D3DXVECTOR2 *uv, + UINT uPrimitiveID, + UINT uSignalDimension, + VOID *pUserData, + FLOAT *pfSignalOut); + +// This function is used to calculate the IMT from per vertex data. It sets +// up a linear system over the triangle, solves for the jacobian J, then +// constructs the IMT from that (J^TJ). +// This function allows you to calculate the IMT based off of any value in a +// mesh (color, normal, etc) by specifying the correct stride of the array. +// The IMT computed will cause areas of the mesh that have similar values to +// take up less space in the texture. +// +// pMesh - The mesh to calculate the IMT for. +// pVertexSignal - A float array of size uSignalStride * v, where v is the +// number of vertices in the mesh. +// uSignalDimension - How many floats per vertex to use in calculating the IMT. +// uSignalStride - The number of bytes per vertex in the array. This must be +// a multiple of sizeof(float) +// ppIMTData - Where to store the buffer holding the IMT data + +HRESULT WINAPI D3DXComputeIMTFromPerVertexSignal ( + LPD3DXMESH pMesh, + CONST FLOAT *pfVertexSignal, // uSignalDimension floats per vertex + UINT uSignalDimension, + UINT uSignalStride, // stride of signal in bytes + DWORD dwOptions, // reserved for future use + LPD3DXUVATLASCB pStatusCallback, + LPVOID pUserContext, + LPD3DXBUFFER *ppIMTData); + +// This function is used to calculate the IMT from data that varies over the +// surface of the mesh (generally at a higher frequency than vertex data). +// This function requires the mesh to already be parameterized (so it already +// has texture coordinates). It allows the user to define a signal arbitrarily +// over the surface of the mesh. +// +// pMesh - The mesh to calculate the IMT for. +// dwTextureIndex - This describes which set of texture coordinates in the +// mesh to use. +// uSignalDimension - How many components there are in the signal. +// fMaxUVDistance - The subdivision will continue until the distance between +// all vertices is at most fMaxUVDistance. +// dwOptions - reserved for future use +// pSignalCallback - The callback to use to get the signal. +// pUserData - A pointer that will be passed in to the callback. +// ppIMTData - Where to store the buffer holding the IMT data +HRESULT WINAPI D3DXComputeIMTFromSignal( + LPD3DXMESH pMesh, + DWORD dwTextureIndex, + UINT uSignalDimension, + FLOAT fMaxUVDistance, + DWORD dwOptions, // reserved for future use + LPD3DXIMTSIGNALCALLBACK pSignalCallback, + VOID *pUserData, + LPD3DXUVATLASCB pStatusCallback, + LPVOID pUserContext, + LPD3DXBUFFER *ppIMTData); + +// This function is used to calculate the IMT from texture data. Given a texture +// that maps over the surface of the mesh, the algorithm computes the IMT for +// each face. This will cause large areas that are very similar to take up less +// room when parameterized with UVAtlas. The texture is assumed to be +// interpolated over the mesh bilinearly. +// +// pMesh - The mesh to calculate the IMT for. +// pTexture - The texture to load data from. +// dwTextureIndex - This describes which set of texture coordinates in the +// mesh to use. +// dwOptions - Combination of one or more D3DXIMT flags. +// ppIMTData - Where to store the buffer holding the IMT data +HRESULT WINAPI D3DXComputeIMTFromTexture ( + LPD3DXMESH pMesh, + LPDIRECT3DTEXTURE9 pTexture, + DWORD dwTextureIndex, + DWORD dwOptions, + LPD3DXUVATLASCB pStatusCallback, + LPVOID pUserContext, + LPD3DXBUFFER *ppIMTData); + +// This function is very similar to ComputeIMTFromTexture, but it uses a +// float array to pass in the data, and it can calculate higher dimensional +// values than 4. +// +// pMesh - The mesh to calculate the IMT for. +// dwTextureIndex - This describes which set of texture coordinates in the +// mesh to use. +// pfFloatArray - a pointer to a float array of size +// uWidth*uHeight*uComponents +// uWidth - The width of the texture +// uHeight - The height of the texture +// uSignalDimension - The number of floats per texel in the signal +// uComponents - The number of floats in each texel +// dwOptions - Combination of one or more D3DXIMT flags +// ppIMTData - Where to store the buffer holding the IMT data +HRESULT WINAPI D3DXComputeIMTFromPerTexelSignal( + LPD3DXMESH pMesh, + DWORD dwTextureIndex, + FLOAT *pfTexelSignal, + UINT uWidth, + UINT uHeight, + UINT uSignalDimension, + UINT uComponents, + DWORD dwOptions, + LPD3DXUVATLASCB pStatusCallback, + LPVOID pUserContext, + LPD3DXBUFFER *ppIMTData); + +HRESULT WINAPI + D3DXConvertMeshSubsetToSingleStrip( + LPD3DXBASEMESH MeshIn, + DWORD AttribId, + DWORD IBOptions, + LPDIRECT3DINDEXBUFFER9 *ppIndexBuffer, + DWORD *pNumIndices); + +HRESULT WINAPI + D3DXConvertMeshSubsetToStrips( + LPD3DXBASEMESH MeshIn, + DWORD AttribId, + DWORD IBOptions, + LPDIRECT3DINDEXBUFFER9 *ppIndexBuffer, + DWORD *pNumIndices, + LPD3DXBUFFER *ppStripLengths, + DWORD *pNumStrips); + + +//============================================================================ +// +// D3DXOptimizeFaces: +// -------------------- +// Generate a face remapping for a triangle list that more effectively utilizes +// vertex caches. This optimization is identical to the one provided +// by ID3DXMesh::Optimize with the hardware independent option enabled. +// +// Parameters: +// pbIndices +// Triangle list indices to use for generating a vertex ordering +// NumFaces +// Number of faces in the triangle list +// NumVertices +// Number of vertices referenced by the triangle list +// b32BitIndices +// TRUE if indices are 32 bit, FALSE if indices are 16 bit +// pFaceRemap +// Destination buffer to store face ordering +// The number stored for a given element is where in the new ordering +// the face will have come from. See ID3DXMesh::Optimize for more info. +// +//============================================================================ +HRESULT WINAPI + D3DXOptimizeFaces( + LPCVOID pbIndices, + UINT cFaces, + UINT cVertices, + BOOL b32BitIndices, + DWORD* pFaceRemap); + +//============================================================================ +// +// D3DXOptimizeVertices: +// -------------------- +// Generate a vertex remapping to optimize for in order use of vertices for +// a given set of indices. This is commonly used after applying the face +// remap generated by D3DXOptimizeFaces +// +// Parameters: +// pbIndices +// Triangle list indices to use for generating a vertex ordering +// NumFaces +// Number of faces in the triangle list +// NumVertices +// Number of vertices referenced by the triangle list +// b32BitIndices +// TRUE if indices are 32 bit, FALSE if indices are 16 bit +// pVertexRemap +// Destination buffer to store vertex ordering +// The number stored for a given element is where in the new ordering +// the vertex will have come from. See ID3DXMesh::Optimize for more info. +// +//============================================================================ +HRESULT WINAPI + D3DXOptimizeVertices( + LPCVOID pbIndices, + UINT cFaces, + UINT cVertices, + BOOL b32BitIndices, + DWORD* pVertexRemap); + +#ifdef __cplusplus +} +#endif //__cplusplus + + +//=========================================================================== +// +// Data structures for Spherical Harmonic Precomputation +// +// +//============================================================================ + +typedef enum _D3DXSHCOMPRESSQUALITYTYPE { + D3DXSHCQUAL_FASTLOWQUALITY = 1, + D3DXSHCQUAL_SLOWHIGHQUALITY = 2, + D3DXSHCQUAL_FORCE_DWORD = 0x7fffffff +} D3DXSHCOMPRESSQUALITYTYPE; + +typedef enum _D3DXSHGPUSIMOPT { + D3DXSHGPUSIMOPT_SHADOWRES256 = 1, + D3DXSHGPUSIMOPT_SHADOWRES512 = 0, + D3DXSHGPUSIMOPT_SHADOWRES1024 = 2, + D3DXSHGPUSIMOPT_SHADOWRES2048 = 3, + + D3DXSHGPUSIMOPT_HIGHQUALITY = 4, + + D3DXSHGPUSIMOPT_FORCE_DWORD = 0x7fffffff +} D3DXSHGPUSIMOPT; + +// for all properties that are colors the luminance is computed +// if the simulator is run with a single channel using the following +// formula: R * 0.2125 + G * 0.7154 + B * 0.0721 + +typedef struct _D3DXSHMATERIAL { + D3DCOLORVALUE Diffuse; // Diffuse albedo of the surface. (Ignored if object is a Mirror) + BOOL bMirror; // Must be set to FALSE. bMirror == TRUE not currently supported + BOOL bSubSurf; // true if the object does subsurface scattering - can't do this and be a mirror + + // subsurface scattering parameters + FLOAT RelativeIndexOfRefraction; + D3DCOLORVALUE Absorption; + D3DCOLORVALUE ReducedScattering; + +} D3DXSHMATERIAL; + +// allocated in D3DXSHPRTCompSplitMeshSC +// vertices are duplicated into multiple super clusters but +// only have a valid status in one super cluster (fill in the rest) + +typedef struct _D3DXSHPRTSPLITMESHVERTDATA { + UINT uVertRemap; // vertex in original mesh this corresponds to + UINT uSubCluster; // cluster index relative to super cluster + UCHAR ucVertStatus; // 1 if vertex has valid data, 0 if it is "fill" +} D3DXSHPRTSPLITMESHVERTDATA; + +// used in D3DXSHPRTCompSplitMeshSC +// information for each super cluster that maps into face/vert arrays + +typedef struct _D3DXSHPRTSPLITMESHCLUSTERDATA { + UINT uVertStart; // initial index into remapped vertex array + UINT uVertLength; // number of vertices in this super cluster + + UINT uFaceStart; // initial index into face array + UINT uFaceLength; // number of faces in this super cluster + + UINT uClusterStart; // initial index into cluster array + UINT uClusterLength; // number of clusters in this super cluster +} D3DXSHPRTSPLITMESHCLUSTERDATA; + +// call back function for simulator +// return S_OK to keep running the simulator - anything else represents +// failure and the simulator will abort. + +typedef HRESULT (WINAPI *LPD3DXSHPRTSIMCB)(float fPercentDone, LPVOID lpUserContext); + +// interfaces for PRT buffers/simulator + +// GUIDs +// {F1827E47-00A8-49cd-908C-9D11955F8728} +DEFINE_GUID(IID_ID3DXPRTBuffer, +0xf1827e47, 0xa8, 0x49cd, 0x90, 0x8c, 0x9d, 0x11, 0x95, 0x5f, 0x87, 0x28); + +// {A758D465-FE8D-45ad-9CF0-D01E56266A07} +DEFINE_GUID(IID_ID3DXPRTCompBuffer, +0xa758d465, 0xfe8d, 0x45ad, 0x9c, 0xf0, 0xd0, 0x1e, 0x56, 0x26, 0x6a, 0x7); + +// {838F01EC-9729-4527-AADB-DF70ADE7FEA9} +DEFINE_GUID(IID_ID3DXTextureGutterHelper, +0x838f01ec, 0x9729, 0x4527, 0xaa, 0xdb, 0xdf, 0x70, 0xad, 0xe7, 0xfe, 0xa9); + +// {683A4278-CD5F-4d24-90AD-C4E1B6855D53} +DEFINE_GUID(IID_ID3DXPRTEngine, +0x683a4278, 0xcd5f, 0x4d24, 0x90, 0xad, 0xc4, 0xe1, 0xb6, 0x85, 0x5d, 0x53); + +// interface defenitions + +typedef interface ID3DXTextureGutterHelper ID3DXTextureGutterHelper; +typedef interface ID3DXPRTBuffer ID3DXPRTBuffer; + +#undef INTERFACE +#define INTERFACE ID3DXPRTBuffer + +// Buffer interface - contains "NumSamples" samples +// each sample in memory is stored as NumCoeffs scalars per channel (1 or 3) +// Same interface is used for both Vertex and Pixel PRT buffers + +DECLARE_INTERFACE_(ID3DXPRTBuffer, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXPRTBuffer + STDMETHOD_(UINT, GetNumSamples)(THIS) PURE; + STDMETHOD_(UINT, GetNumCoeffs)(THIS) PURE; + STDMETHOD_(UINT, GetNumChannels)(THIS) PURE; + + STDMETHOD_(BOOL, IsTexture)(THIS) PURE; + STDMETHOD_(UINT, GetWidth)(THIS) PURE; + STDMETHOD_(UINT, GetHeight)(THIS) PURE; + + // changes the number of samples allocated in the buffer + STDMETHOD(Resize)(THIS_ UINT NewSize) PURE; + + // ppData will point to the memory location where sample Start begins + // pointer is valid for at least NumSamples samples + STDMETHOD(LockBuffer)(THIS_ UINT Start, UINT NumSamples, FLOAT **ppData) PURE; + STDMETHOD(UnlockBuffer)(THIS) PURE; + + // every scalar in buffer is multiplied by Scale + STDMETHOD(ScaleBuffer)(THIS_ FLOAT Scale) PURE; + + // every scalar contains the sum of this and pBuffers values + // pBuffer must have the same storage class/dimensions + STDMETHOD(AddBuffer)(THIS_ LPD3DXPRTBUFFER pBuffer) PURE; + + // GutterHelper (described below) will fill in the gutter + // regions of a texture by interpolating "internal" values + STDMETHOD(AttachGH)(THIS_ LPD3DXTEXTUREGUTTERHELPER) PURE; + STDMETHOD(ReleaseGH)(THIS) PURE; + + // Evaluates attached gutter helper on the contents of this buffer + STDMETHOD(EvalGH)(THIS) PURE; + + // extracts a given channel into texture pTexture + // NumCoefficients starting from StartCoefficient are copied + STDMETHOD(ExtractTexture)(THIS_ UINT Channel, UINT StartCoefficient, + UINT NumCoefficients, LPDIRECT3DTEXTURE9 pTexture) PURE; + + // extracts NumCoefficients coefficients into mesh - only applicable on single channel + // buffers, otherwise just lockbuffer and copy data. With SHPRT data NumCoefficients + // should be Order^2 + STDMETHOD(ExtractToMesh)(THIS_ UINT NumCoefficients, D3DDECLUSAGE Usage, UINT UsageIndexStart, + LPD3DXMESH pScene) PURE; + +}; + +typedef interface ID3DXPRTCompBuffer ID3DXPRTCompBuffer; +typedef interface ID3DXPRTCompBuffer *LPD3DXPRTCOMPBUFFER; + +#undef INTERFACE +#define INTERFACE ID3DXPRTCompBuffer + +// compressed buffers stored a compressed version of a PRTBuffer + +DECLARE_INTERFACE_(ID3DXPRTCompBuffer, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DPRTCompBuffer + + // NumCoeffs and NumChannels are properties of input buffer + STDMETHOD_(UINT, GetNumSamples)(THIS) PURE; + STDMETHOD_(UINT, GetNumCoeffs)(THIS) PURE; + STDMETHOD_(UINT, GetNumChannels)(THIS) PURE; + + STDMETHOD_(BOOL, IsTexture)(THIS) PURE; + STDMETHOD_(UINT, GetWidth)(THIS) PURE; + STDMETHOD_(UINT, GetHeight)(THIS) PURE; + + // number of clusters, and PCA vectors per-cluster + STDMETHOD_(UINT, GetNumClusters)(THIS) PURE; + STDMETHOD_(UINT, GetNumPCA)(THIS) PURE; + + // normalizes PCA weights so that they are between [-1,1] + // basis vectors are modified to reflect this + STDMETHOD(NormalizeData)(THIS) PURE; + + // copies basis vectors for cluster "Cluster" into pClusterBasis + // (NumPCA+1)*NumCoeffs*NumChannels floats + STDMETHOD(ExtractBasis)(THIS_ UINT Cluster, FLOAT *pClusterBasis) PURE; + + // UINT per sample - which cluster it belongs to + STDMETHOD(ExtractClusterIDs)(THIS_ UINT *pClusterIDs) PURE; + + // copies NumExtract PCA projection coefficients starting at StartPCA + // into pPCACoefficients - NumSamples*NumExtract floats copied + STDMETHOD(ExtractPCA)(THIS_ UINT StartPCA, UINT NumExtract, FLOAT *pPCACoefficients) PURE; + + // copies NumPCA projection coefficients starting at StartPCA + // into pTexture - should be able to cope with signed formats + STDMETHOD(ExtractTexture)(THIS_ UINT StartPCA, UINT NumpPCA, + LPDIRECT3DTEXTURE9 pTexture) PURE; + + // copies NumPCA projection coefficients into mesh pScene + // Usage is D3DDECLUSAGE where coefficients are to be stored + // UsageIndexStart is starting index + STDMETHOD(ExtractToMesh)(THIS_ UINT NumPCA, D3DDECLUSAGE Usage, UINT UsageIndexStart, + LPD3DXMESH pScene) PURE; +}; + + +#undef INTERFACE +#define INTERFACE ID3DXTextureGutterHelper + +// ID3DXTextureGutterHelper will build and manage +// "gutter" regions in a texture - this will allow for +// bi-linear interpolation to not have artifacts when rendering +// It generates a map (in texture space) where each texel +// is in one of 3 states: +// 0 Invalid - not used at all +// 1 Inside triangle +// 2 Gutter texel +// 4 represents a gutter texel that will be computed during PRT +// For each Inside/Gutter texel it stores the face it +// belongs to and barycentric coordinates for the 1st two +// vertices of that face. Gutter vertices are assigned to +// the closest edge in texture space. +// +// When used with PRT this requires a unique parameterization +// of the model - every texel must correspond to a single point +// on the surface of the model and vice versa + +DECLARE_INTERFACE_(ID3DXTextureGutterHelper, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXTextureGutterHelper + + // dimensions of texture this is bound too + STDMETHOD_(UINT, GetWidth)(THIS) PURE; + STDMETHOD_(UINT, GetHeight)(THIS) PURE; + + + // Applying gutters recomputes all of the gutter texels of class "2" + // based on texels of class "1" or "4" + + // Applies gutters to a raw float buffer - each texel is NumCoeffs floats + // Width and Height must match GutterHelper + STDMETHOD(ApplyGuttersFloat)(THIS_ FLOAT *pDataIn, UINT NumCoeffs, UINT Width, UINT Height); + + // Applies gutters to pTexture + // Dimensions must match GutterHelper + STDMETHOD(ApplyGuttersTex)(THIS_ LPDIRECT3DTEXTURE9 pTexture); + + // Applies gutters to a D3DXPRTBuffer + // Dimensions must match GutterHelper + STDMETHOD(ApplyGuttersPRT)(THIS_ LPD3DXPRTBUFFER pBuffer); + + // Resamples a texture from a mesh onto this gutterhelpers + // parameterization. It is assumed that the UV coordinates + // for this gutter helper are in TEXTURE 0 (usage/usage index) + // and the texture coordinates should all be within [0,1] for + // both sets. + // + // pTextureIn - texture represented using parameterization in pMeshIn + // pMeshIn - Mesh with texture coordinates that represent pTextureIn + // pTextureOut texture coordinates are assumed to be in + // TEXTURE 0 + // Usage - field in DECL for pMeshIn that stores texture coordinates + // for pTextureIn + // UsageIndex - which index for Usage above for pTextureIn + // pTextureOut- Resampled texture + // + // Usage would generally be D3DDECLUSAGE_TEXCOORD and UsageIndex other than zero + STDMETHOD(ResampleTex)(THIS_ LPDIRECT3DTEXTURE9 pTextureIn, + LPD3DXMESH pMeshIn, + D3DDECLUSAGE Usage, UINT UsageIndex, + LPDIRECT3DTEXTURE9 pTextureOut); + + // the routines below provide access to the data structures + // used by the Apply functions + + // face map is a UINT per texel that represents the + // face of the mesh that texel belongs too - + // only valid if same texel is valid in pGutterData + // pFaceData must be allocated by the user + STDMETHOD(GetFaceMap)(THIS_ UINT *pFaceData) PURE; + + // BaryMap is a D3DXVECTOR2 per texel + // the 1st two barycentric coordinates for the corresponding + // face (3rd weight is always 1-sum of first two) + // only valid if same texel is valid in pGutterData + // pBaryData must be allocated by the user + STDMETHOD(GetBaryMap)(THIS_ D3DXVECTOR2 *pBaryData) PURE; + + // TexelMap is a D3DXVECTOR2 per texel that + // stores the location in pixel coordinates where the + // corresponding texel is mapped + // pTexelData must be allocated by the user + STDMETHOD(GetTexelMap)(THIS_ D3DXVECTOR2 *pTexelData) PURE; + + // GutterMap is a BYTE per texel + // 0/1/2 for Invalid/Internal/Gutter texels + // 4 represents a gutter texel that will be computed + // during PRT + // pGutterData must be allocated by the user + STDMETHOD(GetGutterMap)(THIS_ BYTE *pGutterData) PURE; + + // face map is a UINT per texel that represents the + // face of the mesh that texel belongs too - + // only valid if same texel is valid in pGutterData + STDMETHOD(SetFaceMap)(THIS_ UINT *pFaceData) PURE; + + // BaryMap is a D3DXVECTOR2 per texel + // the 1st two barycentric coordinates for the corresponding + // face (3rd weight is always 1-sum of first two) + // only valid if same texel is valid in pGutterData + STDMETHOD(SetBaryMap)(THIS_ D3DXVECTOR2 *pBaryData) PURE; + + // TexelMap is a D3DXVECTOR2 per texel that + // stores the location in pixel coordinates where the + // corresponding texel is mapped + STDMETHOD(SetTexelMap)(THIS_ D3DXVECTOR2 *pTexelData) PURE; + + // GutterMap is a BYTE per texel + // 0/1/2 for Invalid/Internal/Gutter texels + // 4 represents a gutter texel that will be computed + // during PRT + STDMETHOD(SetGutterMap)(THIS_ BYTE *pGutterData) PURE; +}; + + +typedef interface ID3DXPRTEngine ID3DXPRTEngine; +typedef interface ID3DXPRTEngine *LPD3DXPRTENGINE; + +#undef INTERFACE +#define INTERFACE ID3DXPRTEngine + +// ID3DXPRTEngine is used to compute a PRT simulation +// Use the following steps to compute PRT for SH +// (1) create an interface (which includes a scene) +// (2) call SetSamplingInfo +// (3) [optional] Set MeshMaterials/albedo's (required if doing bounces) +// (4) call ComputeDirectLightingSH +// (5) [optional] call ComputeBounce +// repeat step 5 for as many bounces as wanted. +// if you want to model subsurface scattering you +// need to call ComputeSS after direct lighting and +// each bounce. +// If you want to bake the albedo into the PRT signal, you +// must call MutliplyAlbedo, otherwise the user has to multiply +// the albedo themselves. Not multiplying the albedo allows you +// to model albedo variation at a finer scale then illumination, and +// can result in better compression results. +// Luminance values are computed from RGB values using the following +// formula: R * 0.2125 + G * 0.7154 + B * 0.0721 + +DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXPRTEngine + + // This sets a material per attribute in the scene mesh and it is + // the only way to specify subsurface scattering parameters. if + // bSetAlbedo is FALSE, NumChannels must match the current + // configuration of the PRTEngine. If you intend to change + // NumChannels (through some other SetAlbedo function) it must + // happen before SetMeshMaterials is called. + // + // NumChannels 1 implies "grayscale" materials, set this to 3 to enable + // color bleeding effects + // bSetAlbedo sets albedo from material if TRUE - which clobbers per texel/vertex + // albedo that might have been set before. FALSE won't clobber. + // fLengthScale is used for subsurface scattering - scene is mapped into a 1mm unit cube + // and scaled by this amount + STDMETHOD(SetMeshMaterials)(THIS_ CONST D3DXSHMATERIAL **ppMaterials, UINT NumMeshes, + UINT NumChannels, BOOL bSetAlbedo, FLOAT fLengthScale) PURE; + + // setting albedo per-vertex or per-texel over rides the albedos stored per mesh + // but it does not over ride any other settings + + // sets an albedo to be used per vertex - the albedo is represented as a float + // pDataIn input pointer (pointint to albedo of 1st sample) + // NumChannels 1 implies "grayscale" materials, set this to 3 to enable + // color bleeding effects + // Stride - stride in bytes to get to next samples albedo + STDMETHOD(SetPerVertexAlbedo)(THIS_ CONST VOID *pDataIn, UINT NumChannels, UINT Stride) PURE; + + // represents the albedo per-texel instead of per-vertex (even if per-vertex PRT is used) + // pAlbedoTexture - texture that stores the albedo (dimension arbitrary) + // NumChannels 1 implies "grayscale" materials, set this to 3 to enable + // color bleeding effects + // pGH - optional gutter helper, otherwise one is constructed in computation routines and + // destroyed (if not attached to buffers) + STDMETHOD(SetPerTexelAlbedo)(THIS_ LPDIRECT3DTEXTURE9 pAlbedoTexture, + UINT NumChannels, + LPD3DXTEXTUREGUTTERHELPER pGH) PURE; + + // gets the per-vertex albedo + STDMETHOD(GetVertexAlbedo)(THIS_ D3DXCOLOR *pVertColors, UINT NumVerts) PURE; + + // If pixel PRT is being computed normals default to ones that are interpolated + // from the vertex normals. This specifies a texture that stores an object + // space normal map instead (must use a texture format that can represent signed values) + // pNormalTexture - normal map, must be same dimensions as PRTBuffers, signed + STDMETHOD(SetPerTexelNormal)(THIS_ LPDIRECT3DTEXTURE9 pNormalTexture) PURE; + + // Copies per-vertex albedo from mesh + // pMesh - mesh that represents the scene. It must have the same + // properties as the mesh used to create the PRTEngine + // Usage - D3DDECLUSAGE to extract albedos from + // NumChannels 1 implies "grayscale" materials, set this to 3 to enable + // color bleeding effects + STDMETHOD(ExtractPerVertexAlbedo)(THIS_ LPD3DXMESH pMesh, + D3DDECLUSAGE Usage, + UINT NumChannels) PURE; + + // Resamples the input buffer into the output buffer + // can be used to move between per-vertex and per-texel buffers. This can also be used + // to convert single channel buffers to 3-channel buffers and vice-versa. + STDMETHOD(ResampleBuffer)(THIS_ LPD3DXPRTBUFFER pBufferIn, LPD3DXPRTBUFFER pBufferOut) PURE; + + // Returns the scene mesh - including modifications from adaptive spatial sampling + // The returned mesh only has positions, normals and texture coordinates (if defined) + // pD3DDevice - d3d device that will be used to allocate the mesh + // pFaceRemap - each face has a pointer back to the face on the original mesh that it comes from + // if the face hasn't been subdivided this will be an identity mapping + // pVertRemap - each vertex contains 3 vertices that this is a linear combination of + // pVertWeights - weights for each of above indices (sum to 1.0f) + // ppMesh - mesh that will be allocated and filled + STDMETHOD(GetAdaptedMesh)(THIS_ LPDIRECT3DDEVICE9 pD3DDevice,UINT *pFaceRemap, UINT *pVertRemap, FLOAT *pfVertWeights, LPD3DXMESH *ppMesh) PURE; + + // Number of vertices currently allocated (includes new vertices from adaptive sampling) + STDMETHOD_(UINT, GetNumVerts)(THIS) PURE; + // Number of faces currently allocated (includes new faces) + STDMETHOD_(UINT, GetNumFaces)(THIS) PURE; + + // Sets the Minimum/Maximum intersection distances, this can be used to control + // maximum distance that objects can shadow/reflect light, and help with "bad" + // art that might have near features that you don't want to shadow. This does not + // apply for GPU simulations. + // fMin - minimum intersection distance, must be positive and less than fMax + // fMax - maximum intersection distance, if 0.0f use the previous value, otherwise + // must be strictly greater than fMin + STDMETHOD(SetMinMaxIntersection)(THIS_ FLOAT fMin, FLOAT fMax) PURE; + + // This will subdivide faces on a mesh so that adaptively simulations can + // use a more conservative threshold (it won't miss features.) + // MinEdgeLength - minimum edge length that will be generated, if 0.0f a + // reasonable default will be used + // MaxSubdiv - maximum level of subdivision, if 0 is specified a default + // value will be used (5) + STDMETHOD(RobustMeshRefine)(THIS_ FLOAT MinEdgeLength, UINT MaxSubdiv) PURE; + + // This sets to sampling information used by the simulator. Adaptive sampling + // parameters are currently ignored. + // NumRays - number of rays to shoot per sample + // UseSphere - if TRUE uses spherical samples, otherwise samples over + // the hemisphere. Should only be used with GPU and Vol computations + // UseCosine - if TRUE uses a cosine weighting - not used for Vol computations + // or if only the visiblity function is desired + // Adaptive - if TRUE adaptive sampling (angular) is used + // AdaptiveThresh - threshold used to terminate adaptive angular sampling + // ignored if adaptive sampling is not set + STDMETHOD(SetSamplingInfo)(THIS_ UINT NumRays, + BOOL UseSphere, + BOOL UseCosine, + BOOL Adaptive, + FLOAT AdaptiveThresh) PURE; + + // Methods that compute the direct lighting contribution for objects + // always represente light using spherical harmonics (SH) + // the albedo is not multiplied by the signal - it just integrates + // incoming light. If NumChannels is not 1 the vector is replicated + // + // SHOrder - order of SH to use + // pDataOut - PRT buffer that is generated. Can be single channel + STDMETHOD(ComputeDirectLightingSH)(THIS_ UINT SHOrder, + LPD3DXPRTBUFFER pDataOut) PURE; + + // Adaptive variant of above function. This will refine the mesh + // generating new vertices/faces to approximate the PRT signal + // more faithfully. + // SHOrder - order of SH to use + // AdaptiveThresh - threshold for adaptive subdivision (in PRT vector error) + // if value is less then 1e-6f, 1e-6f is specified + // MinEdgeLength - minimum edge length that will be generated + // if value is too small a fairly conservative model dependent value + // is used + // MaxSubdiv - maximum subdivision level, if 0 is specified it + // will default to 4 + // pDataOut - PRT buffer that is generated. Can be single channel. + STDMETHOD(ComputeDirectLightingSHAdaptive)(THIS_ UINT SHOrder, + FLOAT AdaptiveThresh, + FLOAT MinEdgeLength, + UINT MaxSubdiv, + LPD3DXPRTBUFFER pDataOut) PURE; + + // Function that computes the direct lighting contribution for objects + // light is always represented using spherical harmonics (SH) + // This is done on the GPU and is much faster then using the CPU. + // The albedo is not multiplied by the signal - it just integrates + // incoming light. If NumChannels is not 1 the vector is replicated. + // ZBias/ZAngleBias are akin to parameters used with shadow zbuffers. + // A reasonable default for both values is 0.005, but the user should + // experiment (ZAngleBias can be zero, ZBias should not be.) + // Callbacks should not use the Direct3D9Device the simulator is using. + // SetSamplingInfo must be called with TRUE for UseSphere and + // FALSE for UseCosine before this method is called. + // + // pD3DDevice - device used to run GPU simulator - must support PS2.0 + // and FP render targets + // Flags - parameters for the GPU simulator, combination of one or more + // D3DXSHGPUSIMOPT flags. Only one SHADOWRES setting should be set and + // the defaults is 512 + // SHOrder - order of SH to use + // ZBias - bias in normal direction (for depth test) + // ZAngleBias - scaled by one minus cosine of angle with light (offset in depth) + // pDataOut - PRT buffer that is filled in. Can be single channel + STDMETHOD(ComputeDirectLightingSHGPU)(THIS_ LPDIRECT3DDEVICE9 pD3DDevice, + UINT Flags, + UINT SHOrder, + FLOAT ZBias, + FLOAT ZAngleBias, + LPD3DXPRTBUFFER pDataOut) PURE; + + + // Functions that computes subsurface scattering (using material properties) + // Albedo is not multiplied by result. This only works for per-vertex data + // use ResampleBuffer to move per-vertex data into a texture and back. + // + // pDataIn - input data (previous bounce) + // pDataOut - result of subsurface scattering simulation + // pDataTotal - [optional] results can be summed into this buffer + STDMETHOD(ComputeSS)(THIS_ LPD3DXPRTBUFFER pDataIn, + LPD3DXPRTBUFFER pDataOut, LPD3DXPRTBUFFER pDataTotal) PURE; + + // Adaptive version of ComputeSS. + // + // pDataIn - input data (previous bounce) + // AdaptiveThresh - threshold for adaptive subdivision (in PRT vector error) + // if value is less then 1e-6f, 1e-6f is specified + // MinEdgeLength - minimum edge length that will be generated + // if value is too small a fairly conservative model dependent value + // is used + // MaxSubdiv - maximum subdivision level, if 0 is specified it + // will default to 4 + // pDataOut - result of subsurface scattering simulation + // pDataTotal - [optional] results can be summed into this buffer + STDMETHOD(ComputeSSAdaptive)(THIS_ LPD3DXPRTBUFFER pDataIn, + FLOAT AdaptiveThresh, + FLOAT MinEdgeLength, + UINT MaxSubdiv, + LPD3DXPRTBUFFER pDataOut, LPD3DXPRTBUFFER pDataTotal) PURE; + + // computes a single bounce of inter-reflected light + // works for SH based PRT or generic lighting + // Albedo is not multiplied by result + // + // pDataIn - previous bounces data + // pDataOut - PRT buffer that is generated + // pDataTotal - [optional] can be used to keep a running sum + STDMETHOD(ComputeBounce)(THIS_ LPD3DXPRTBUFFER pDataIn, + LPD3DXPRTBUFFER pDataOut, + LPD3DXPRTBUFFER pDataTotal) PURE; + + // Adaptive version of above function. + // + // pDataIn - previous bounces data, can be single channel + // AdaptiveThresh - threshold for adaptive subdivision (in PRT vector error) + // if value is less then 1e-6f, 1e-6f is specified + // MinEdgeLength - minimum edge length that will be generated + // if value is too small a fairly conservative model dependent value + // is used + // MaxSubdiv - maximum subdivision level, if 0 is specified it + // will default to 4 + // pDataOut - PRT buffer that is generated + // pDataTotal - [optional] can be used to keep a running sum + STDMETHOD(ComputeBounceAdaptive)(THIS_ LPD3DXPRTBUFFER pDataIn, + FLOAT AdaptiveThresh, + FLOAT MinEdgeLength, + UINT MaxSubdiv, + LPD3DXPRTBUFFER pDataOut, + LPD3DXPRTBUFFER pDataTotal) PURE; + + // Computes projection of distant SH radiance into a local SH radiance + // function. This models how direct lighting is attenuated by the + // scene and is a form of "neighborhood transfer." The result is + // a linear operator (matrix) at every sample point, if you multiply + // this matrix by the distant SH lighting coefficients you get an + // approximation of the local incident radiance function from + // direct lighting. These resulting lighting coefficients can + // than be projected into another basis or used with any rendering + // technique that uses spherical harmonics as input. + // SetSamplingInfo must be called with TRUE for UseSphere and + // FALSE for UseCosine before this method is called. + // Generates SHOrderIn*SHOrderIn*SHOrderOut*SHOrderOut scalars + // per channel at each sample location. + // + // SHOrderIn - Order of the SH representation of distant lighting + // SHOrderOut - Order of the SH representation of local lighting + // NumVolSamples - Number of sample locations + // pSampleLocs - position of sample locations + // pDataOut - PRT Buffer that will store output results + STDMETHOD(ComputeVolumeSamplesDirectSH)(THIS_ UINT SHOrderIn, + UINT SHOrderOut, + UINT NumVolSamples, + CONST D3DXVECTOR3 *pSampleLocs, + LPD3DXPRTBUFFER pDataOut) PURE; + + // At each sample location computes a linear operator (matrix) that maps + // the representation of source radiance (NumCoeffs in pSurfDataIn) + // into a local incident radiance function approximated with spherical + // harmonics. For example if a light map data is specified in pSurfDataIn + // the result is an SH representation of the flow of light at each sample + // point. If PRT data for an outdoor scene is used, each sample point + // contains a matrix that models how distant lighting bounces of the objects + // in the scene and arrives at the given sample point. Combined with + // ComputeVolumeSamplesDirectSH this gives the complete representation for + // how light arrives at each sample point parameterized by distant lighting. + // SetSamplingInfo must be called with TRUE for UseSphere and + // FALSE for UseCosine before this method is called. + // Generates pSurfDataIn->NumCoeffs()*SHOrder*SHOrder scalars + // per channel at each sample location. + // + // pSurfDataIn - previous bounce data + // SHOrder - order of SH to generate projection with + // NumVolSamples - Number of sample locations + // pSampleLocs - position of sample locations + // pDataOut - PRT Buffer that will store output results + STDMETHOD(ComputeVolumeSamples)(THIS_ LPD3DXPRTBUFFER pSurfDataIn, + UINT SHOrder, + UINT NumVolSamples, + CONST D3DXVECTOR3 *pSampleLocs, + LPD3DXPRTBUFFER pDataOut) PURE; + + // Computes direct lighting (SH) for a point not on the mesh + // with a given normal - cannot use texture buffers. + // + // SHOrder - order of SH to use + // NumSamples - number of sample locations + // pSampleLocs - position for each sample + // pSampleNorms - normal for each sample + // pDataOut - PRT Buffer that will store output results + STDMETHOD(ComputeSurfSamplesDirectSH)(THIS_ UINT SHOrder, + UINT NumSamples, + CONST D3DXVECTOR3 *pSampleLocs, + CONST D3DXVECTOR3 *pSampleNorms, + LPD3DXPRTBUFFER pDataOut) PURE; + + + // given the solution for PRT or light maps, computes transfer vector at arbitrary + // position/normal pairs in space + // + // pSurfDataIn - input data + // NumSamples - number of sample locations + // pSampleLocs - position for each sample + // pSampleNorms - normal for each sample + // pDataOut - PRT Buffer that will store output results + // pDataTotal - optional buffer to sum results into - can be NULL + STDMETHOD(ComputeSurfSamplesBounce)(THIS_ LPD3DXPRTBUFFER pSurfDataIn, + UINT NumSamples, + CONST D3DXVECTOR3 *pSampleLocs, + CONST D3DXVECTOR3 *pSampleNorms, + LPD3DXPRTBUFFER pDataOut, + LPD3DXPRTBUFFER pDataTotal) PURE; + + // Frees temporary data structures that can be created for subsurface scattering + // this data is freed when the PRTComputeEngine is freed and is lazily created + STDMETHOD(FreeSSData)(THIS) PURE; + + // Frees temporary data structures that can be created for bounce simulations + // this data is freed when the PRTComputeEngine is freed and is lazily created + STDMETHOD(FreeBounceData)(THIS) PURE; + + // This computes the Local Deformable PRT (LDPRT) coefficients relative to the + // per sample normals that minimize error in a least squares sense with respect + // to the input PRT data set. These coefficients can be used with skinned/transformed + // normals to model global effects with dynamic objects. Shading normals can + // optionally be solved for - these normals (along with the LDPRT coefficients) can + // more accurately represent the PRT signal. The coefficients are for zonal + // harmonics oriented in the normal/shading normal direction. + // + // pDataIn - SH PRT dataset that is input + // SHOrder - Order of SH to compute conv coefficients for + // pNormOut - Optional array of vectors (passed in) that will be filled with + // "shading normals", LDPRT coefficients are optimized for + // these normals. This array must be the same size as the number of + // samples in pDataIn + // pDataOut - Output buffer (SHOrder zonal harmonic coefficients per channel per sample) + STDMETHOD(ComputeLDPRTCoeffs)(THIS_ LPD3DXPRTBUFFER pDataIn, + UINT SHOrder, + D3DXVECTOR3 *pNormOut, + LPD3DXPRTBUFFER pDataOut) PURE; + + // scales all the samples associated with a given sub mesh + // can be useful when using subsurface scattering + // fScale - value to scale each vector in submesh by + STDMETHOD(ScaleMeshChunk)(THIS_ UINT uMeshChunk, FLOAT fScale, LPD3DXPRTBUFFER pDataOut) PURE; + + // mutliplies each PRT vector by the albedo - can be used if you want to have the albedo + // burned into the dataset, often better not to do this. If this is not done the user + // must mutliply the albedo themselves when rendering - just multiply the albedo times + // the result of the PRT dot product. + // If pDataOut is a texture simulation result and there is an albedo texture it + // must be represented at the same resolution as the simulation buffer. You can use + // LoadSurfaceFromSurface and set a new albedo texture if this is an issue - but must + // be careful about how the gutters are handled. + // + // pDataOut - dataset that will get albedo pushed into it + STDMETHOD(MultiplyAlbedo)(THIS_ LPD3DXPRTBUFFER pDataOut) PURE; + + // Sets a pointer to an optional call back function that reports back to the + // user percentage done and gives them the option of quitting + // pCB - pointer to call back function, return S_OK for the simulation + // to continue + // Frequency - 1/Frequency is roughly the number of times the call back + // will be invoked + // lpUserContext - will be passed back to the users call back + STDMETHOD(SetCallBack)(THIS_ LPD3DXSHPRTSIMCB pCB, FLOAT Frequency, LPVOID lpUserContext) PURE; + + // Returns TRUE if the ray intersects the mesh, FALSE if it does not. This function + // takes into account settings from SetMinMaxIntersection. If the closest intersection + // is not needed this function is more efficient compared to the ClosestRayIntersection + // method. + // pRayPos - origin of ray + // pRayDir - normalized ray direction (normalization required for SetMinMax to be meaningful) + + STDMETHOD_(BOOL, ShadowRayIntersects)(THIS_ CONST D3DXVECTOR3 *pRayPos, CONST D3DXVECTOR3 *pRayDir) PURE; + + // Returns TRUE if the ray intersects the mesh, FALSE if it does not. If there is an + // intersection the closest face that was intersected and its first two barycentric coordinates + // are returned. This function takes into account settings from SetMinMaxIntersection. + // This is a slower function compared to ShadowRayIntersects and should only be used where + // needed. The third vertices barycentric coordinates will be 1 - pU - pV. + // pRayPos - origin of ray + // pRayDir - normalized ray direction (normalization required for SetMinMax to be meaningful) + // pFaceIndex - Closest face that intersects. This index is based on stacking the pBlockerMesh + // faces before the faces from pMesh + // pU - Barycentric coordinate for vertex 0 + // pV - Barycentric coordinate for vertex 1 + // pDist - Distance along ray where the intersection occured + + STDMETHOD_(BOOL, ClosestRayIntersects)(THIS_ CONST D3DXVECTOR3 *pRayPos, CONST D3DXVECTOR3 *pRayDir, + DWORD *pFaceIndex, FLOAT *pU, FLOAT *pV, FLOAT *pDist) PURE; +}; + + +// API functions for creating interfaces + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//============================================================================ +// +// D3DXCreatePRTBuffer: +// -------------------- +// Generates a PRT Buffer that can be compressed or filled by a simulator +// This function should be used to create per-vertex or volume buffers. +// When buffers are created all values are initialized to zero. +// +// Parameters: +// NumSamples +// Number of sample locations represented +// NumCoeffs +// Number of coefficients per sample location (order^2 for SH) +// NumChannels +// Number of color channels to represent (1 or 3) +// ppBuffer +// Buffer that will be allocated +// +//============================================================================ + +HRESULT WINAPI + D3DXCreatePRTBuffer( + UINT NumSamples, + UINT NumCoeffs, + UINT NumChannels, + LPD3DXPRTBUFFER* ppBuffer); + +//============================================================================ +// +// D3DXCreatePRTBufferTex: +// -------------------- +// Generates a PRT Buffer that can be compressed or filled by a simulator +// This function should be used to create per-pixel buffers. +// When buffers are created all values are initialized to zero. +// +// Parameters: +// Width +// Width of texture +// Height +// Height of texture +// NumCoeffs +// Number of coefficients per sample location (order^2 for SH) +// NumChannels +// Number of color channels to represent (1 or 3) +// ppBuffer +// Buffer that will be allocated +// +//============================================================================ + +HRESULT WINAPI + D3DXCreatePRTBufferTex( + UINT Width, + UINT Height, + UINT NumCoeffs, + UINT NumChannels, + LPD3DXPRTBUFFER* ppBuffer); + +//============================================================================ +// +// D3DXLoadPRTBufferFromFile: +// -------------------- +// Loads a PRT buffer that has been saved to disk. +// +// Parameters: +// pFilename +// Name of the file to load +// ppBuffer +// Buffer that will be allocated +// +//============================================================================ + +HRESULT WINAPI + D3DXLoadPRTBufferFromFileA( + LPCSTR pFilename, + LPD3DXPRTBUFFER* ppBuffer); + +HRESULT WINAPI + D3DXLoadPRTBufferFromFileW( + LPCWSTR pFilename, + LPD3DXPRTBUFFER* ppBuffer); + +#ifdef UNICODE +#define D3DXLoadPRTBufferFromFile D3DXLoadPRTBufferFromFileW +#else +#define D3DXLoadPRTBufferFromFile D3DXLoadPRTBufferFromFileA +#endif + + +//============================================================================ +// +// D3DXSavePRTBufferToFile: +// -------------------- +// Saves a PRTBuffer to disk. +// +// Parameters: +// pFilename +// Name of the file to save +// pBuffer +// Buffer that will be saved +// +//============================================================================ + +HRESULT WINAPI + D3DXSavePRTBufferToFileA( + LPCSTR pFileName, + LPD3DXPRTBUFFER pBuffer); + +HRESULT WINAPI + D3DXSavePRTBufferToFileW( + LPCWSTR pFileName, + LPD3DXPRTBUFFER pBuffer); + +#ifdef UNICODE +#define D3DXSavePRTBufferToFile D3DXSavePRTBufferToFileW +#else +#define D3DXSavePRTBufferToFile D3DXSavePRTBufferToFileA +#endif + + +//============================================================================ +// +// D3DXLoadPRTCompBufferFromFile: +// -------------------- +// Loads a PRTComp buffer that has been saved to disk. +// +// Parameters: +// pFilename +// Name of the file to load +// ppBuffer +// Buffer that will be allocated +// +//============================================================================ + +HRESULT WINAPI + D3DXLoadPRTCompBufferFromFileA( + LPCSTR pFilename, + LPD3DXPRTCOMPBUFFER* ppBuffer); + +HRESULT WINAPI + D3DXLoadPRTCompBufferFromFileW( + LPCWSTR pFilename, + LPD3DXPRTCOMPBUFFER* ppBuffer); + +#ifdef UNICODE +#define D3DXLoadPRTCompBufferFromFile D3DXLoadPRTCompBufferFromFileW +#else +#define D3DXLoadPRTCompBufferFromFile D3DXLoadPRTCompBufferFromFileA +#endif + +//============================================================================ +// +// D3DXSavePRTCompBufferToFile: +// -------------------- +// Saves a PRTCompBuffer to disk. +// +// Parameters: +// pFilename +// Name of the file to save +// pBuffer +// Buffer that will be saved +// +//============================================================================ + +HRESULT WINAPI + D3DXSavePRTCompBufferToFileA( + LPCSTR pFileName, + LPD3DXPRTCOMPBUFFER pBuffer); + +HRESULT WINAPI + D3DXSavePRTCompBufferToFileW( + LPCWSTR pFileName, + LPD3DXPRTCOMPBUFFER pBuffer); + +#ifdef UNICODE +#define D3DXSavePRTCompBufferToFile D3DXSavePRTCompBufferToFileW +#else +#define D3DXSavePRTCompBufferToFile D3DXSavePRTCompBufferToFileA +#endif + +//============================================================================ +// +// D3DXCreatePRTCompBuffer: +// -------------------- +// Compresses a PRT buffer (vertex or texel) +// +// Parameters: +// D3DXSHCOMPRESSQUALITYTYPE +// Quality of compression - low is faster (computes PCA per voronoi cluster) +// high is slower but better quality (clusters based on distance to affine subspace) +// NumClusters +// Number of clusters to compute +// NumPCA +// Number of basis vectors to compute +// pCB +// Optional Callback function +// lpUserContext +// Optional user context +// pBufferIn +// Buffer that will be compressed +// ppBufferOut +// Compressed buffer that will be created +// +//============================================================================ + + +HRESULT WINAPI + D3DXCreatePRTCompBuffer( + D3DXSHCOMPRESSQUALITYTYPE Quality, + UINT NumClusters, + UINT NumPCA, + LPD3DXSHPRTSIMCB pCB, + LPVOID lpUserContext, + LPD3DXPRTBUFFER pBufferIn, + LPD3DXPRTCOMPBUFFER *ppBufferOut + ); + +//============================================================================ +// +// D3DXCreateTextureGutterHelper: +// -------------------- +// Generates a "GutterHelper" for a given set of meshes and texture +// resolution +// +// Parameters: +// Width +// Width of texture +// Height +// Height of texture +// pMesh +// Mesh that represents the scene +// GutterSize +// Number of texels to over rasterize in texture space +// this should be at least 1.0 +// ppBuffer +// GutterHelper that will be created +// +//============================================================================ + + +HRESULT WINAPI + D3DXCreateTextureGutterHelper( + UINT Width, + UINT Height, + LPD3DXMESH pMesh, + FLOAT GutterSize, + LPD3DXTEXTUREGUTTERHELPER* ppBuffer); + + +//============================================================================ +// +// D3DXCreatePRTEngine: +// -------------------- +// Computes a PRTEngine which can efficiently generate PRT simulations +// of a scene +// +// Parameters: +// pMesh +// Mesh that represents the scene - must have an AttributeTable +// where vertices are in a unique attribute. +// pAdjacency +// Optional adjacency information +// ExtractUVs +// Set this to true if textures are going to be used for albedos +// or to store PRT vectors +// pBlockerMesh +// Optional mesh that just blocks the scene +// ppEngine +// PRTEngine that will be created +// +//============================================================================ + + +HRESULT WINAPI + D3DXCreatePRTEngine( + LPD3DXMESH pMesh, + DWORD *pAdjacency, + BOOL ExtractUVs, + LPD3DXMESH pBlockerMesh, + LPD3DXPRTENGINE* ppEngine); + +//============================================================================ +// +// D3DXConcatenateMeshes: +// -------------------- +// Concatenates a group of meshes into one common mesh. This can optionaly transform +// each sub mesh or its texture coordinates. If no DECL is given it will +// generate a union of all of the DECL's of the sub meshes, promoting channels +// and types if neccesary. It will create an AttributeTable if possible, one can +// call OptimizeMesh with attribute sort and compacting enabled to ensure this. +// +// Parameters: +// ppMeshes +// Array of pointers to meshes that can store PRT vectors +// NumMeshes +// Number of meshes +// Options +// Passed through to D3DXCreateMesh +// pGeomXForms +// [optional] Each sub mesh is transformed by the corresponding +// matrix if this array is supplied +// pTextureXForms +// [optional] UV coordinates for each sub mesh are transformed +// by corresponding matrix if supplied +// pDecl +// [optional] Only information in this DECL is used when merging +// data +// pD3DDevice +// D3D device that is used to create the new mesh +// ppMeshOut +// Mesh that will be created +// +//============================================================================ + + +HRESULT WINAPI + D3DXConcatenateMeshes( + LPD3DXMESH *ppMeshes, + UINT NumMeshes, + DWORD Options, + CONST D3DXMATRIX *pGeomXForms, + CONST D3DXMATRIX *pTextureXForms, + CONST D3DVERTEXELEMENT9 *pDecl, + LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXMESH *ppMeshOut); + +//============================================================================ +// +// D3DXSHPRTCompSuperCluster: +// -------------------------- +// Used with compressed results of D3DXSHPRTSimulation. +// Generates "super clusters" - groups of clusters that can be drawn in +// the same draw call. A greedy algorithm that minimizes overdraw is used +// to group the clusters. +// +// Parameters: +// pClusterIDs +// NumVerts cluster ID's (extracted from a compressed buffer) +// pScene +// Mesh that represents composite scene passed to the simulator +// MaxNumClusters +// Maximum number of clusters allocated per super cluster +// NumClusters +// Number of clusters computed in the simulator +// pSuperClusterIDs +// Array of length NumClusters, contains index of super cluster +// that corresponding cluster was assigned to +// pNumSuperClusters +// Returns the number of super clusters allocated +// +//============================================================================ + +HRESULT WINAPI + D3DXSHPRTCompSuperCluster( + UINT *pClusterIDs, + LPD3DXMESH pScene, + UINT MaxNumClusters, + UINT NumClusters, + UINT *pSuperClusterIDs, + UINT *pNumSuperClusters); + +//============================================================================ +// +// D3DXSHPRTCompSplitMeshSC: +// ------------------------- +// Used with compressed results of the vertex version of the PRT simulator. +// After D3DXSHRTCompSuperCluster has been called this function can be used +// to split the mesh into a group of faces/vertices per super cluster. +// Each super cluster contains all of the faces that contain any vertex +// classified in one of its clusters. All of the vertices connected to this +// set of faces are also included with the returned array ppVertStatus +// indicating whether or not the vertex belongs to the supercluster. +// +// Parameters: +// pClusterIDs +// NumVerts cluster ID's (extracted from a compressed buffer) +// NumVertices +// Number of vertices in original mesh +// NumClusters +// Number of clusters (input parameter to compression) +// pSuperClusterIDs +// Array of size NumClusters that will contain super cluster ID's (from +// D3DXSHCompSuerCluster) +// NumSuperClusters +// Number of superclusters allocated in D3DXSHCompSuerCluster +// pInputIB +// Raw index buffer for mesh - format depends on bInputIBIs32Bit +// InputIBIs32Bit +// Indicates whether the input index buffer is 32-bit (otherwise 16-bit +// is assumed) +// NumFaces +// Number of faces in the original mesh (pInputIB is 3 times this length) +// ppIBData +// LPD3DXBUFFER holds raw index buffer that will contain the resulting split faces. +// Format determined by bIBIs32Bit. Allocated by function +// pIBDataLength +// Length of ppIBData, assigned in function +// OutputIBIs32Bit +// Indicates whether the output index buffer is to be 32-bit (otherwise +// 16-bit is assumed) +// ppFaceRemap +// LPD3DXBUFFER mapping of each face in ppIBData to original faces. Length is +// *pIBDataLength/3. Optional paramter, allocated in function +// ppVertData +// LPD3DXBUFFER contains new vertex data structure. Size of pVertDataLength +// pVertDataLength +// Number of new vertices in split mesh. Assigned in function +// pSCClusterList +// Array of length NumClusters which pSCData indexes into (Cluster* fields) +// for each SC, contains clusters sorted by super cluster +// pSCData +// Structure per super cluster - contains indices into ppIBData, +// pSCClusterList and ppVertData +// +//============================================================================ + +HRESULT WINAPI + D3DXSHPRTCompSplitMeshSC( + UINT *pClusterIDs, + UINT NumVertices, + UINT NumClusters, + UINT *pSuperClusterIDs, + UINT NumSuperClusters, + LPVOID pInputIB, + BOOL InputIBIs32Bit, + UINT NumFaces, + LPD3DXBUFFER *ppIBData, + UINT *pIBDataLength, + BOOL OutputIBIs32Bit, + LPD3DXBUFFER *ppFaceRemap, + LPD3DXBUFFER *ppVertData, + UINT *pVertDataLength, + UINT *pSCClusterList, + D3DXSHPRTSPLITMESHCLUSTERDATA *pSCData); + + +#ifdef __cplusplus +} +#endif //__cplusplus + +////////////////////////////////////////////////////////////////////////////// +// +// Definitions of .X file templates used by mesh load/save functions +// that are not RM standard +// +////////////////////////////////////////////////////////////////////////////// + +// {3CF169CE-FF7C-44ab-93C0-F78F62D172E2} +DEFINE_GUID(DXFILEOBJ_XSkinMeshHeader, +0x3cf169ce, 0xff7c, 0x44ab, 0x93, 0xc0, 0xf7, 0x8f, 0x62, 0xd1, 0x72, 0xe2); + +// {B8D65549-D7C9-4995-89CF-53A9A8B031E3} +DEFINE_GUID(DXFILEOBJ_VertexDuplicationIndices, +0xb8d65549, 0xd7c9, 0x4995, 0x89, 0xcf, 0x53, 0xa9, 0xa8, 0xb0, 0x31, 0xe3); + +// {A64C844A-E282-4756-8B80-250CDE04398C} +DEFINE_GUID(DXFILEOBJ_FaceAdjacency, +0xa64c844a, 0xe282, 0x4756, 0x8b, 0x80, 0x25, 0xc, 0xde, 0x4, 0x39, 0x8c); + +// {6F0D123B-BAD2-4167-A0D0-80224F25FABB} +DEFINE_GUID(DXFILEOBJ_SkinWeights, +0x6f0d123b, 0xbad2, 0x4167, 0xa0, 0xd0, 0x80, 0x22, 0x4f, 0x25, 0xfa, 0xbb); + +// {A3EB5D44-FC22-429d-9AFB-3221CB9719A6} +DEFINE_GUID(DXFILEOBJ_Patch, +0xa3eb5d44, 0xfc22, 0x429d, 0x9a, 0xfb, 0x32, 0x21, 0xcb, 0x97, 0x19, 0xa6); + +// {D02C95CC-EDBA-4305-9B5D-1820D7704BBF} +DEFINE_GUID(DXFILEOBJ_PatchMesh, +0xd02c95cc, 0xedba, 0x4305, 0x9b, 0x5d, 0x18, 0x20, 0xd7, 0x70, 0x4b, 0xbf); + +// {B9EC94E1-B9A6-4251-BA18-94893F02C0EA} +DEFINE_GUID(DXFILEOBJ_PatchMesh9, +0xb9ec94e1, 0xb9a6, 0x4251, 0xba, 0x18, 0x94, 0x89, 0x3f, 0x2, 0xc0, 0xea); + +// {B6C3E656-EC8B-4b92-9B62-681659522947} +DEFINE_GUID(DXFILEOBJ_PMInfo, +0xb6c3e656, 0xec8b, 0x4b92, 0x9b, 0x62, 0x68, 0x16, 0x59, 0x52, 0x29, 0x47); + +// {917E0427-C61E-4a14-9C64-AFE65F9E9844} +DEFINE_GUID(DXFILEOBJ_PMAttributeRange, +0x917e0427, 0xc61e, 0x4a14, 0x9c, 0x64, 0xaf, 0xe6, 0x5f, 0x9e, 0x98, 0x44); + +// {574CCC14-F0B3-4333-822D-93E8A8A08E4C} +DEFINE_GUID(DXFILEOBJ_PMVSplitRecord, +0x574ccc14, 0xf0b3, 0x4333, 0x82, 0x2d, 0x93, 0xe8, 0xa8, 0xa0, 0x8e, 0x4c); + +// {B6E70A0E-8EF9-4e83-94AD-ECC8B0C04897} +DEFINE_GUID(DXFILEOBJ_FVFData, +0xb6e70a0e, 0x8ef9, 0x4e83, 0x94, 0xad, 0xec, 0xc8, 0xb0, 0xc0, 0x48, 0x97); + +// {F752461C-1E23-48f6-B9F8-8350850F336F} +DEFINE_GUID(DXFILEOBJ_VertexElement, +0xf752461c, 0x1e23, 0x48f6, 0xb9, 0xf8, 0x83, 0x50, 0x85, 0xf, 0x33, 0x6f); + +// {BF22E553-292C-4781-9FEA-62BD554BDD93} +DEFINE_GUID(DXFILEOBJ_DeclData, +0xbf22e553, 0x292c, 0x4781, 0x9f, 0xea, 0x62, 0xbd, 0x55, 0x4b, 0xdd, 0x93); + +// {F1CFE2B3-0DE3-4e28-AFA1-155A750A282D} +DEFINE_GUID(DXFILEOBJ_EffectFloats, +0xf1cfe2b3, 0xde3, 0x4e28, 0xaf, 0xa1, 0x15, 0x5a, 0x75, 0xa, 0x28, 0x2d); + +// {D55B097E-BDB6-4c52-B03D-6051C89D0E42} +DEFINE_GUID(DXFILEOBJ_EffectString, +0xd55b097e, 0xbdb6, 0x4c52, 0xb0, 0x3d, 0x60, 0x51, 0xc8, 0x9d, 0xe, 0x42); + +// {622C0ED0-956E-4da9-908A-2AF94F3CE716} +DEFINE_GUID(DXFILEOBJ_EffectDWord, +0x622c0ed0, 0x956e, 0x4da9, 0x90, 0x8a, 0x2a, 0xf9, 0x4f, 0x3c, 0xe7, 0x16); + +// {3014B9A0-62F5-478c-9B86-E4AC9F4E418B} +DEFINE_GUID(DXFILEOBJ_EffectParamFloats, +0x3014b9a0, 0x62f5, 0x478c, 0x9b, 0x86, 0xe4, 0xac, 0x9f, 0x4e, 0x41, 0x8b); + +// {1DBC4C88-94C1-46ee-9076-2C28818C9481} +DEFINE_GUID(DXFILEOBJ_EffectParamString, +0x1dbc4c88, 0x94c1, 0x46ee, 0x90, 0x76, 0x2c, 0x28, 0x81, 0x8c, 0x94, 0x81); + +// {E13963BC-AE51-4c5d-B00F-CFA3A9D97CE5} +DEFINE_GUID(DXFILEOBJ_EffectParamDWord, +0xe13963bc, 0xae51, 0x4c5d, 0xb0, 0xf, 0xcf, 0xa3, 0xa9, 0xd9, 0x7c, 0xe5); + +// {E331F7E4-0559-4cc2-8E99-1CEC1657928F} +DEFINE_GUID(DXFILEOBJ_EffectInstance, +0xe331f7e4, 0x559, 0x4cc2, 0x8e, 0x99, 0x1c, 0xec, 0x16, 0x57, 0x92, 0x8f); + +// {9E415A43-7BA6-4a73-8743-B73D47E88476} +DEFINE_GUID(DXFILEOBJ_AnimTicksPerSecond, +0x9e415a43, 0x7ba6, 0x4a73, 0x87, 0x43, 0xb7, 0x3d, 0x47, 0xe8, 0x84, 0x76); + +// {7F9B00B3-F125-4890-876E-1CFFBF697C4D} +DEFINE_GUID(DXFILEOBJ_CompressedAnimationSet, +0x7f9b00b3, 0xf125, 0x4890, 0x87, 0x6e, 0x1c, 0x42, 0xbf, 0x69, 0x7c, 0x4d); + +#pragma pack(push, 1) +typedef struct _XFILECOMPRESSEDANIMATIONSET +{ + DWORD CompressedBlockSize; + FLOAT TicksPerSec; + DWORD PlaybackType; + DWORD BufferLength; +} XFILECOMPRESSEDANIMATIONSET; +#pragma pack(pop) + +#define XSKINEXP_TEMPLATES \ + "xof 0303txt 0032\ + template XSkinMeshHeader \ + { \ + <3CF169CE-FF7C-44ab-93C0-F78F62D172E2> \ + WORD nMaxSkinWeightsPerVertex; \ + WORD nMaxSkinWeightsPerFace; \ + WORD nBones; \ + } \ + template VertexDuplicationIndices \ + { \ + <B8D65549-D7C9-4995-89CF-53A9A8B031E3> \ + DWORD nIndices; \ + DWORD nOriginalVertices; \ + array DWORD indices[nIndices]; \ + } \ + template FaceAdjacency \ + { \ + <A64C844A-E282-4756-8B80-250CDE04398C> \ + DWORD nIndices; \ + array DWORD indices[nIndices]; \ + } \ + template SkinWeights \ + { \ + <6F0D123B-BAD2-4167-A0D0-80224F25FABB> \ + STRING transformNodeName; \ + DWORD nWeights; \ + array DWORD vertexIndices[nWeights]; \ + array float weights[nWeights]; \ + Matrix4x4 matrixOffset; \ + } \ + template Patch \ + { \ + <A3EB5D44-FC22-429D-9AFB-3221CB9719A6> \ + DWORD nControlIndices; \ + array DWORD controlIndices[nControlIndices]; \ + } \ + template PatchMesh \ + { \ + <D02C95CC-EDBA-4305-9B5D-1820D7704BBF> \ + DWORD nVertices; \ + array Vector vertices[nVertices]; \ + DWORD nPatches; \ + array Patch patches[nPatches]; \ + [ ... ] \ + } \ + template PatchMesh9 \ + { \ + <B9EC94E1-B9A6-4251-BA18-94893F02C0EA> \ + DWORD Type; \ + DWORD Degree; \ + DWORD Basis; \ + DWORD nVertices; \ + array Vector vertices[nVertices]; \ + DWORD nPatches; \ + array Patch patches[nPatches]; \ + [ ... ] \ + } " \ + "template EffectFloats \ + { \ + <F1CFE2B3-0DE3-4e28-AFA1-155A750A282D> \ + DWORD nFloats; \ + array float Floats[nFloats]; \ + } \ + template EffectString \ + { \ + <D55B097E-BDB6-4c52-B03D-6051C89D0E42> \ + STRING Value; \ + } \ + template EffectDWord \ + { \ + <622C0ED0-956E-4da9-908A-2AF94F3CE716> \ + DWORD Value; \ + } " \ + "template EffectParamFloats \ + { \ + <3014B9A0-62F5-478c-9B86-E4AC9F4E418B> \ + STRING ParamName; \ + DWORD nFloats; \ + array float Floats[nFloats]; \ + } " \ + "template EffectParamString \ + { \ + <1DBC4C88-94C1-46ee-9076-2C28818C9481> \ + STRING ParamName; \ + STRING Value; \ + } \ + template EffectParamDWord \ + { \ + <E13963BC-AE51-4c5d-B00F-CFA3A9D97CE5> \ + STRING ParamName; \ + DWORD Value; \ + } \ + template EffectInstance \ + { \ + <E331F7E4-0559-4cc2-8E99-1CEC1657928F> \ + STRING EffectFilename; \ + [ ... ] \ + } " \ + "template AnimTicksPerSecond \ + { \ + <9E415A43-7BA6-4a73-8743-B73D47E88476> \ + DWORD AnimTicksPerSecond; \ + } \ + template CompressedAnimationSet \ + { \ + <7F9B00B3-F125-4890-876E-1C42BF697C4D> \ + DWORD CompressedBlockSize; \ + FLOAT TicksPerSec; \ + DWORD PlaybackType; \ + DWORD BufferLength; \ + array DWORD CompressedData[BufferLength]; \ + } " + +#define XEXTENSIONS_TEMPLATES \ + "xof 0303txt 0032\ + template FVFData \ + { \ + <B6E70A0E-8EF9-4e83-94AD-ECC8B0C04897> \ + DWORD dwFVF; \ + DWORD nDWords; \ + array DWORD data[nDWords]; \ + } \ + template VertexElement \ + { \ + <F752461C-1E23-48f6-B9F8-8350850F336F> \ + DWORD Type; \ + DWORD Method; \ + DWORD Usage; \ + DWORD UsageIndex; \ + } \ + template DeclData \ + { \ + <BF22E553-292C-4781-9FEA-62BD554BDD93> \ + DWORD nElements; \ + array VertexElement Elements[nElements]; \ + DWORD nDWords; \ + array DWORD data[nDWords]; \ + } \ + template PMAttributeRange \ + { \ + <917E0427-C61E-4a14-9C64-AFE65F9E9844> \ + DWORD iFaceOffset; \ + DWORD nFacesMin; \ + DWORD nFacesMax; \ + DWORD iVertexOffset; \ + DWORD nVerticesMin; \ + DWORD nVerticesMax; \ + } \ + template PMVSplitRecord \ + { \ + <574CCC14-F0B3-4333-822D-93E8A8A08E4C> \ + DWORD iFaceCLW; \ + DWORD iVlrOffset; \ + DWORD iCode; \ + } \ + template PMInfo \ + { \ + <B6C3E656-EC8B-4b92-9B62-681659522947> \ + DWORD nAttributes; \ + array PMAttributeRange attributeRanges[nAttributes]; \ + DWORD nMaxValence; \ + DWORD nMinLogicalVertices; \ + DWORD nMaxLogicalVertices; \ + DWORD nVSplits; \ + array PMVSplitRecord splitRecords[nVSplits]; \ + DWORD nAttributeMispredicts; \ + array DWORD attributeMispredicts[nAttributeMispredicts]; \ + } " + +#endif //__D3DX9MESH_H__ + + diff --git a/builddir/irrlicht-1.8.1/include/d3dx9shader.h b/builddir/irrlicht-1.8.1/include/d3dx9shader.h new file mode 100644 index 0000000..5ed3f01 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx9shader.h @@ -0,0 +1,1010 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// File: d3dx9shader.h +// Content: D3DX Shader APIs +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9SHADER_H__ +#define __D3DX9SHADER_H__ + + +//--------------------------------------------------------------------------- +// D3DXTX_VERSION: +// -------------- +// Version token used to create a procedural texture filler in effects +// Used by D3DXFill[]TX functions +//--------------------------------------------------------------------------- +#define D3DXTX_VERSION(_Major,_Minor) (('T' << 24) | ('X' << 16) | ((_Major) << 8) | (_Minor)) + + + +//---------------------------------------------------------------------------- +// D3DXSHADER flags: +// ----------------- +// D3DXSHADER_DEBUG +// Insert debug file/line/type/symbol information. +// +// D3DXSHADER_SKIPVALIDATION +// Do not validate the generated code against known capabilities and +// constraints. This option is only recommended when compiling shaders +// you KNOW will work. (ie. have compiled before without this option.) +// Shaders are always validated by D3D before they are set to the device. +// +// D3DXSHADER_SKIPOPTIMIZATION +// Instructs the compiler to skip optimization steps during code generation. +// Unless you are trying to isolate a problem in your code using this option +// is not recommended. +// +// D3DXSHADER_PACKMATRIX_ROWMAJOR +// Unless explicitly specified, matrices will be packed in row-major order +// on input and output from the shader. +// +// D3DXSHADER_PACKMATRIX_COLUMNMAJOR +// Unless explicitly specified, matrices will be packed in column-major +// order on input and output from the shader. This is generally more +// efficient, since it allows vector-matrix multiplication to be performed +// using a series of dot-products. +// +// D3DXSHADER_PARTIALPRECISION +// Force all computations in resulting shader to occur at partial precision. +// This may result in faster evaluation of shaders on some hardware. +// +// D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT +// Force compiler to compile against the next highest available software +// target for vertex shaders. This flag also turns optimizations off, +// and debugging on. +// +// D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT +// Force compiler to compile against the next highest available software +// target for pixel shaders. This flag also turns optimizations off, +// and debugging on. +// +// D3DXSHADER_NO_PRESHADER +// Disables Preshaders. Using this flag will cause the compiler to not +// pull out static expression for evaluation on the host cpu +// +// D3DXSHADER_AVOID_FLOW_CONTROL +// Hint compiler to avoid flow-control constructs where possible. +// +// D3DXSHADER_PREFER_FLOW_CONTROL +// Hint compiler to prefer flow-control constructs where possible. +// +//---------------------------------------------------------------------------- + +#define D3DXSHADER_DEBUG (1 << 0) +#define D3DXSHADER_SKIPVALIDATION (1 << 1) +#define D3DXSHADER_SKIPOPTIMIZATION (1 << 2) +#define D3DXSHADER_PACKMATRIX_ROWMAJOR (1 << 3) +#define D3DXSHADER_PACKMATRIX_COLUMNMAJOR (1 << 4) +#define D3DXSHADER_PARTIALPRECISION (1 << 5) +#define D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT (1 << 6) +#define D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT (1 << 7) +#define D3DXSHADER_NO_PRESHADER (1 << 8) +#define D3DXSHADER_AVOID_FLOW_CONTROL (1 << 9) +#define D3DXSHADER_PREFER_FLOW_CONTROL (1 << 10) +#define D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY (1 << 12) +#define D3DXSHADER_IEEE_STRICTNESS (1 << 13) +#define D3DXSHADER_USE_LEGACY_D3DX9_31_DLL (1 << 16) + + +// optimization level flags +#define D3DXSHADER_OPTIMIZATION_LEVEL0 (1 << 14) +#define D3DXSHADER_OPTIMIZATION_LEVEL1 0 +#define D3DXSHADER_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15)) +#define D3DXSHADER_OPTIMIZATION_LEVEL3 (1 << 15) + + + +//---------------------------------------------------------------------------- +// D3DXCONSTTABLE flags: +// ------------------- + +#define D3DXCONSTTABLE_LARGEADDRESSAWARE (1 << 17) + + + +//---------------------------------------------------------------------------- +// D3DXHANDLE: +// ----------- +// Handle values used to efficiently reference shader and effect parameters. +// Strings can be used as handles. However, handles are not always strings. +//---------------------------------------------------------------------------- + +#ifndef D3DXFX_LARGEADDRESS_HANDLE +typedef LPCSTR D3DXHANDLE; +#else +typedef UINT_PTR D3DXHANDLE; +#endif +typedef D3DXHANDLE *LPD3DXHANDLE; + + +//---------------------------------------------------------------------------- +// D3DXMACRO: +// ---------- +// Preprocessor macro definition. The application pass in a NULL-terminated +// array of this structure to various D3DX APIs. This enables the application +// to #define tokens at runtime, before the file is parsed. +//---------------------------------------------------------------------------- + +typedef struct _D3DXMACRO +{ + LPCSTR Name; + LPCSTR Definition; + +} D3DXMACRO, *LPD3DXMACRO; + + +//---------------------------------------------------------------------------- +// D3DXSEMANTIC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXSEMANTIC +{ + UINT Usage; + UINT UsageIndex; + +} D3DXSEMANTIC, *LPD3DXSEMANTIC; + + + +//---------------------------------------------------------------------------- +// D3DXREGISTER_SET: +//---------------------------------------------------------------------------- + +typedef enum _D3DXREGISTER_SET +{ + D3DXRS_BOOL, + D3DXRS_INT4, + D3DXRS_FLOAT4, + D3DXRS_SAMPLER, + + // force 32-bit size enum + D3DXRS_FORCE_DWORD = 0x7fffffff + +} D3DXREGISTER_SET, *LPD3DXREGISTER_SET; + + +//---------------------------------------------------------------------------- +// D3DXPARAMETER_CLASS: +//---------------------------------------------------------------------------- + +typedef enum _D3DXPARAMETER_CLASS +{ + D3DXPC_SCALAR, + D3DXPC_VECTOR, + D3DXPC_MATRIX_ROWS, + D3DXPC_MATRIX_COLUMNS, + D3DXPC_OBJECT, + D3DXPC_STRUCT, + + // force 32-bit size enum + D3DXPC_FORCE_DWORD = 0x7fffffff + +} D3DXPARAMETER_CLASS, *LPD3DXPARAMETER_CLASS; + + +//---------------------------------------------------------------------------- +// D3DXPARAMETER_TYPE: +//---------------------------------------------------------------------------- + +typedef enum _D3DXPARAMETER_TYPE +{ + D3DXPT_VOID, + D3DXPT_BOOL, + D3DXPT_INT, + D3DXPT_FLOAT, + D3DXPT_STRING, + D3DXPT_TEXTURE, + D3DXPT_TEXTURE1D, + D3DXPT_TEXTURE2D, + D3DXPT_TEXTURE3D, + D3DXPT_TEXTURECUBE, + D3DXPT_SAMPLER, + D3DXPT_SAMPLER1D, + D3DXPT_SAMPLER2D, + D3DXPT_SAMPLER3D, + D3DXPT_SAMPLERCUBE, + D3DXPT_PIXELSHADER, + D3DXPT_VERTEXSHADER, + D3DXPT_PIXELFRAGMENT, + D3DXPT_VERTEXFRAGMENT, + D3DXPT_UNSUPPORTED, + + // force 32-bit size enum + D3DXPT_FORCE_DWORD = 0x7fffffff + +} D3DXPARAMETER_TYPE, *LPD3DXPARAMETER_TYPE; + + +//---------------------------------------------------------------------------- +// D3DXCONSTANTTABLE_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXCONSTANTTABLE_DESC +{ + LPCSTR Creator; // Creator string + DWORD Version; // Shader version + UINT Constants; // Number of constants + +} D3DXCONSTANTTABLE_DESC, *LPD3DXCONSTANTTABLE_DESC; + + +//---------------------------------------------------------------------------- +// D3DXCONSTANT_DESC: +//---------------------------------------------------------------------------- + +typedef struct _D3DXCONSTANT_DESC +{ + LPCSTR Name; // Constant name + + D3DXREGISTER_SET RegisterSet; // Register set + UINT RegisterIndex; // Register index + UINT RegisterCount; // Number of registers occupied + + D3DXPARAMETER_CLASS Class; // Class + D3DXPARAMETER_TYPE Type; // Component type + + UINT Rows; // Number of rows + UINT Columns; // Number of columns + UINT Elements; // Number of array elements + UINT StructMembers; // Number of structure member sub-parameters + + UINT Bytes; // Data size, in bytes + LPCVOID DefaultValue; // Pointer to default value + +} D3DXCONSTANT_DESC, *LPD3DXCONSTANT_DESC; + + + +//---------------------------------------------------------------------------- +// ID3DXConstantTable: +//---------------------------------------------------------------------------- + +typedef interface ID3DXConstantTable ID3DXConstantTable; +typedef interface ID3DXConstantTable *LPD3DXCONSTANTTABLE; + +// {AB3C758F-093E-4356-B762-4DB18F1B3A01} +DEFINE_GUID(IID_ID3DXConstantTable, +0xab3c758f, 0x93e, 0x4356, 0xb7, 0x62, 0x4d, 0xb1, 0x8f, 0x1b, 0x3a, 0x1); + + +#undef INTERFACE +#define INTERFACE ID3DXConstantTable + +DECLARE_INTERFACE_(ID3DXConstantTable, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Buffer + STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE; + STDMETHOD_(DWORD, GetBufferSize)(THIS) PURE; + + // Descs + STDMETHOD(GetDesc)(THIS_ D3DXCONSTANTTABLE_DESC *pDesc) PURE; + STDMETHOD(GetConstantDesc)(THIS_ D3DXHANDLE hConstant, D3DXCONSTANT_DESC *pConstantDesc, UINT *pCount) PURE; + STDMETHOD_(UINT, GetSamplerIndex)(THIS_ D3DXHANDLE hConstant) PURE; + + // Handle operations + STDMETHOD_(D3DXHANDLE, GetConstant)(THIS_ D3DXHANDLE hConstant, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetConstantByName)(THIS_ D3DXHANDLE hConstant, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetConstantElement)(THIS_ D3DXHANDLE hConstant, UINT Index) PURE; + + // Set Constants + STDMETHOD(SetDefaults)(THIS_ LPDIRECT3DDEVICE9 pDevice) PURE; + STDMETHOD(SetValue)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, LPCVOID pData, UINT Bytes) PURE; + STDMETHOD(SetBool)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, BOOL b) PURE; + STDMETHOD(SetBoolArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST BOOL* pb, UINT Count) PURE; + STDMETHOD(SetInt)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, INT n) PURE; + STDMETHOD(SetIntArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST INT* pn, UINT Count) PURE; + STDMETHOD(SetFloat)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, FLOAT f) PURE; + STDMETHOD(SetFloatArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST FLOAT* pf, UINT Count) PURE; + STDMETHOD(SetVector)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXVECTOR4* pVector) PURE; + STDMETHOD(SetVectorArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(SetMatrix)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixPointerArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTranspose)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixTransposeArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTransposePointerArray)(THIS_ LPDIRECT3DDEVICE9 pDevice, D3DXHANDLE hConstant, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; +}; + + +//---------------------------------------------------------------------------- +// ID3DXTextureShader: +//---------------------------------------------------------------------------- + +typedef interface ID3DXTextureShader ID3DXTextureShader; +typedef interface ID3DXTextureShader *LPD3DXTEXTURESHADER; + +// {3E3D67F8-AA7A-405d-A857-BA01D4758426} +DEFINE_GUID(IID_ID3DXTextureShader, +0x3e3d67f8, 0xaa7a, 0x405d, 0xa8, 0x57, 0xba, 0x1, 0xd4, 0x75, 0x84, 0x26); + +#undef INTERFACE +#define INTERFACE ID3DXTextureShader + +DECLARE_INTERFACE_(ID3DXTextureShader, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // Gets + STDMETHOD(GetFunction)(THIS_ LPD3DXBUFFER *ppFunction) PURE; + STDMETHOD(GetConstantBuffer)(THIS_ LPD3DXBUFFER *ppConstantBuffer) PURE; + + // Descs + STDMETHOD(GetDesc)(THIS_ D3DXCONSTANTTABLE_DESC *pDesc) PURE; + STDMETHOD(GetConstantDesc)(THIS_ D3DXHANDLE hConstant, D3DXCONSTANT_DESC *pConstantDesc, UINT *pCount) PURE; + + // Handle operations + STDMETHOD_(D3DXHANDLE, GetConstant)(THIS_ D3DXHANDLE hConstant, UINT Index) PURE; + STDMETHOD_(D3DXHANDLE, GetConstantByName)(THIS_ D3DXHANDLE hConstant, LPCSTR pName) PURE; + STDMETHOD_(D3DXHANDLE, GetConstantElement)(THIS_ D3DXHANDLE hConstant, UINT Index) PURE; + + // Set Constants + STDMETHOD(SetDefaults)(THIS) PURE; + STDMETHOD(SetValue)(THIS_ D3DXHANDLE hConstant, LPCVOID pData, UINT Bytes) PURE; + STDMETHOD(SetBool)(THIS_ D3DXHANDLE hConstant, BOOL b) PURE; + STDMETHOD(SetBoolArray)(THIS_ D3DXHANDLE hConstant, CONST BOOL* pb, UINT Count) PURE; + STDMETHOD(SetInt)(THIS_ D3DXHANDLE hConstant, INT n) PURE; + STDMETHOD(SetIntArray)(THIS_ D3DXHANDLE hConstant, CONST INT* pn, UINT Count) PURE; + STDMETHOD(SetFloat)(THIS_ D3DXHANDLE hConstant, FLOAT f) PURE; + STDMETHOD(SetFloatArray)(THIS_ D3DXHANDLE hConstant, CONST FLOAT* pf, UINT Count) PURE; + STDMETHOD(SetVector)(THIS_ D3DXHANDLE hConstant, CONST D3DXVECTOR4* pVector) PURE; + STDMETHOD(SetVectorArray)(THIS_ D3DXHANDLE hConstant, CONST D3DXVECTOR4* pVector, UINT Count) PURE; + STDMETHOD(SetMatrix)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixArray)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixPointerArray)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTranspose)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetMatrixTransposeArray)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX* pMatrix, UINT Count) PURE; + STDMETHOD(SetMatrixTransposePointerArray)(THIS_ D3DXHANDLE hConstant, CONST D3DXMATRIX** ppMatrix, UINT Count) PURE; +}; + + +//---------------------------------------------------------------------------- +// D3DXINCLUDE_TYPE: +//---------------------------------------------------------------------------- + +typedef enum _D3DXINCLUDE_TYPE +{ + D3DXINC_LOCAL, + D3DXINC_SYSTEM, + + // force 32-bit size enum + D3DXINC_FORCE_DWORD = 0x7fffffff + +} D3DXINCLUDE_TYPE, *LPD3DXINCLUDE_TYPE; + + +//---------------------------------------------------------------------------- +// ID3DXInclude: +// ------------- +// This interface is intended to be implemented by the application, and can +// be used by various D3DX APIs. This enables application-specific handling +// of #include directives in source files. +// +// Open() +// Opens an include file. If successful, it should fill in ppData and +// pBytes. The data pointer returned must remain valid until Close is +// subsequently called. The name of the file is encoded in UTF-8 format. +// Close() +// Closes an include file. If Open was successful, Close is guaranteed +// to be called before the API using this interface returns. +//---------------------------------------------------------------------------- + +typedef interface ID3DXInclude ID3DXInclude; +typedef interface ID3DXInclude *LPD3DXINCLUDE; + +#undef INTERFACE +#define INTERFACE ID3DXInclude + +DECLARE_INTERFACE(ID3DXInclude) +{ + STDMETHOD(Open)(THIS_ D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) PURE; + STDMETHOD(Close)(THIS_ LPCVOID pData) PURE; +}; + + +////////////////////////////////////////////////////////////////////////////// +// APIs ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +//---------------------------------------------------------------------------- +// D3DXAssembleShader: +// ------------------- +// Assembles a shader. +// +// Parameters: +// pSrcFile +// Source file name +// hSrcModule +// Module handle. if NULL, current module will be used +// pSrcResource +// Resource name in module +// pSrcData +// Pointer to source code +// SrcDataLen +// Size of source code, in bytes +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when assembling +// from file, and will error when assembling from resource or memory. +// Flags +// See D3DXSHADER_xxx flags +// ppShader +// Returns a buffer containing the created shader. This buffer contains +// the assembled shader code, as well as any embedded debug info. +// ppErrorMsgs +// Returns a buffer containing a listing of errors and warnings that were +// encountered during assembly. If you are running in a debugger, +// these are the same messages you will see in your debug output. +//---------------------------------------------------------------------------- + + +HRESULT WINAPI + D3DXAssembleShaderFromFileA( + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + +HRESULT WINAPI + D3DXAssembleShaderFromFileW( + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + +#ifdef UNICODE +#define D3DXAssembleShaderFromFile D3DXAssembleShaderFromFileW +#else +#define D3DXAssembleShaderFromFile D3DXAssembleShaderFromFileA +#endif + + +HRESULT WINAPI + D3DXAssembleShaderFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + +HRESULT WINAPI + D3DXAssembleShaderFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + +#ifdef UNICODE +#define D3DXAssembleShaderFromResource D3DXAssembleShaderFromResourceW +#else +#define D3DXAssembleShaderFromResource D3DXAssembleShaderFromResourceA +#endif + + +HRESULT WINAPI + D3DXAssembleShader( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + + + +//---------------------------------------------------------------------------- +// D3DXCompileShader: +// ------------------ +// Compiles a shader. +// +// Parameters: +// pSrcFile +// Source file name. +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module. +// pSrcData +// Pointer to source code. +// SrcDataLen +// Size of source code, in bytes. +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when compiling +// from file, and will error when compiling from resource or memory. +// pFunctionName +// Name of the entrypoint function where execution should begin. +// pProfile +// Instruction set to be used when generating code. Currently supported +// profiles are "vs_1_1", "vs_2_0", "vs_2_a", "vs_2_sw", "ps_1_1", +// "ps_1_2", "ps_1_3", "ps_1_4", "ps_2_0", "ps_2_a", "ps_2_sw", "tx_1_0" +// Flags +// See D3DXSHADER_xxx flags. +// ppShader +// Returns a buffer containing the created shader. This buffer contains +// the compiled shader code, as well as any embedded debug and symbol +// table info. (See D3DXGetShaderConstantTable) +// ppErrorMsgs +// Returns a buffer containing a listing of errors and warnings that were +// encountered during the compile. If you are running in a debugger, +// these are the same messages you will see in your debug output. +// ppConstantTable +// Returns a ID3DXConstantTable object which can be used to set +// shader constants to the device. Alternatively, an application can +// parse the D3DXSHADER_CONSTANTTABLE block embedded as a comment within +// the shader. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCompileShaderFromFileA( + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + +HRESULT WINAPI + D3DXCompileShaderFromFileW( + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + +#ifdef UNICODE +#define D3DXCompileShaderFromFile D3DXCompileShaderFromFileW +#else +#define D3DXCompileShaderFromFile D3DXCompileShaderFromFileA +#endif + + +HRESULT WINAPI + D3DXCompileShaderFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + +HRESULT WINAPI + D3DXCompileShaderFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + +#ifdef UNICODE +#define D3DXCompileShaderFromResource D3DXCompileShaderFromResourceW +#else +#define D3DXCompileShaderFromResource D3DXCompileShaderFromResourceA +#endif + + +HRESULT WINAPI + D3DXCompileShader( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + + +//---------------------------------------------------------------------------- +// D3DXDisassembleShader: +// ---------------------- +// Takes a binary shader, and returns a buffer containing text assembly. +// +// Parameters: +// pShader +// Pointer to the shader byte code. +// ShaderSizeInBytes +// Size of the shader byte code in bytes. +// EnableColorCode +// Emit HTML tags for color coding the output? +// pComments +// Pointer to a comment string to include at the top of the shader. +// ppDisassembly +// Returns a buffer containing the disassembled shader. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXDisassembleShader( + CONST DWORD* pShader, + BOOL EnableColorCode, + LPCSTR pComments, + LPD3DXBUFFER* ppDisassembly); + + +//---------------------------------------------------------------------------- +// D3DXGetPixelShaderProfile/D3DXGetVertexShaderProfile: +// ----------------------------------------------------- +// Returns the name of the HLSL profile best suited to a given device. +// +// Parameters: +// pDevice +// Pointer to the device in question +//---------------------------------------------------------------------------- + +LPCSTR WINAPI + D3DXGetPixelShaderProfile( + LPDIRECT3DDEVICE9 pDevice); + +LPCSTR WINAPI + D3DXGetVertexShaderProfile( + LPDIRECT3DDEVICE9 pDevice); + + +//---------------------------------------------------------------------------- +// D3DXFindShaderComment: +// ---------------------- +// Searches through a shader for a particular comment, denoted by a FourCC in +// the first DWORD of the comment. If the comment is not found, and no other +// error has occurred, S_FALSE is returned. +// +// Parameters: +// pFunction +// Pointer to the function DWORD stream +// FourCC +// FourCC used to identify the desired comment block. +// ppData +// Returns a pointer to the comment data (not including comment token +// and FourCC). Can be NULL. +// pSizeInBytes +// Returns the size of the comment data in bytes. Can be NULL. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXFindShaderComment( + CONST DWORD* pFunction, + DWORD FourCC, + LPCVOID* ppData, + UINT* pSizeInBytes); + + +//---------------------------------------------------------------------------- +// D3DXGetShaderSize: +// ------------------ +// Returns the size of the shader byte-code, in bytes. +// +// Parameters: +// pFunction +// Pointer to the function DWORD stream +//---------------------------------------------------------------------------- + +UINT WINAPI + D3DXGetShaderSize( + CONST DWORD* pFunction); + + +//---------------------------------------------------------------------------- +// D3DXGetShaderVersion: +// ----------------------- +// Returns the shader version of a given shader. Returns zero if the shader +// function is NULL. +// +// Parameters: +// pFunction +// Pointer to the function DWORD stream +//---------------------------------------------------------------------------- + +DWORD WINAPI + D3DXGetShaderVersion( + CONST DWORD* pFunction); + +//---------------------------------------------------------------------------- +// D3DXGetShaderSemantics: +// ----------------------- +// Gets semantics for all input elements referenced inside a given shader. +// +// Parameters: +// pFunction +// Pointer to the function DWORD stream +// pSemantics +// Pointer to an array of D3DXSEMANTIC structures. The function will +// fill this array with the semantics for each input element referenced +// inside the shader. This array is assumed to contain at least +// MAXD3DDECLLENGTH elements. +// pCount +// Returns the number of elements referenced by the shader +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXGetShaderInputSemantics( + CONST DWORD* pFunction, + D3DXSEMANTIC* pSemantics, + UINT* pCount); + +HRESULT WINAPI + D3DXGetShaderOutputSemantics( + CONST DWORD* pFunction, + D3DXSEMANTIC* pSemantics, + UINT* pCount); + + +//---------------------------------------------------------------------------- +// D3DXGetShaderSamplers: +// ---------------------- +// Gets semantics for all input elements referenced inside a given shader. +// +// pFunction +// Pointer to the function DWORD stream +// pSamplers +// Pointer to an array of LPCSTRs. The function will fill this array +// with pointers to the sampler names contained within pFunction, for +// each sampler referenced inside the shader. This array is assumed to +// contain at least 16 elements. +// pCount +// Returns the number of samplers referenced by the shader +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXGetShaderSamplers( + CONST DWORD* pFunction, + LPCSTR* pSamplers, + UINT* pCount); + + +//---------------------------------------------------------------------------- +// D3DXGetShaderConstantTable: +// --------------------------- +// Gets shader constant table embedded inside shader. A constant table is +// generated by D3DXAssembleShader and D3DXCompileShader, and is embedded in +// the body of the shader. +// +// Parameters: +// pFunction +// Pointer to the function DWORD stream +// Flags +// See D3DXCONSTTABLE_xxx +// ppConstantTable +// Returns a ID3DXConstantTable object which can be used to set +// shader constants to the device. Alternatively, an application can +// parse the D3DXSHADER_CONSTANTTABLE block embedded as a comment within +// the shader. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXGetShaderConstantTable( + CONST DWORD* pFunction, + LPD3DXCONSTANTTABLE* ppConstantTable); + +HRESULT WINAPI + D3DXGetShaderConstantTableEx( + CONST DWORD* pFunction, + DWORD Flags, + LPD3DXCONSTANTTABLE* ppConstantTable); + + + +//---------------------------------------------------------------------------- +// D3DXCreateTextureShader: +// ------------------------ +// Creates a texture shader object, given the compiled shader. +// +// Parameters +// pFunction +// Pointer to the function DWORD stream +// ppTextureShader +// Returns a ID3DXTextureShader object which can be used to procedurally +// fill the contents of a texture using the D3DXFillTextureTX functions. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateTextureShader( + CONST DWORD* pFunction, + LPD3DXTEXTURESHADER* ppTextureShader); + + +//---------------------------------------------------------------------------- +// D3DXPreprocessShader: +// --------------------- +// Runs the preprocessor on the specified shader or effect, but does +// not actually compile it. This is useful for evaluating the #includes +// and #defines in a shader and then emitting a reformatted token stream +// for debugging purposes or for generating a self-contained shader. +// +// Parameters: +// pSrcFile +// Source file name +// hSrcModule +// Module handle. if NULL, current module will be used +// pSrcResource +// Resource name in module +// pSrcData +// Pointer to source code +// SrcDataLen +// Size of source code, in bytes +// pDefines +// Optional NULL-terminated array of preprocessor macro definitions. +// pInclude +// Optional interface pointer to use for handling #include directives. +// If this parameter is NULL, #includes will be honored when assembling +// from file, and will error when assembling from resource or memory. +// ppShaderText +// Returns a buffer containing a single large string that represents +// the resulting formatted token stream +// ppErrorMsgs +// Returns a buffer containing a listing of errors and warnings that were +// encountered during assembly. If you are running in a debugger, +// these are the same messages you will see in your debug output. +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXPreprocessShaderFromFileA( + LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPD3DXBUFFER* ppShaderText, + LPD3DXBUFFER* ppErrorMsgs); + +HRESULT WINAPI + D3DXPreprocessShaderFromFileW( + LPCWSTR pSrcFile, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPD3DXBUFFER* ppShaderText, + LPD3DXBUFFER* ppErrorMsgs); + +#ifdef UNICODE +#define D3DXPreprocessShaderFromFile D3DXPreprocessShaderFromFileW +#else +#define D3DXPreprocessShaderFromFile D3DXPreprocessShaderFromFileA +#endif + +HRESULT WINAPI + D3DXPreprocessShaderFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPD3DXBUFFER* ppShaderText, + LPD3DXBUFFER* ppErrorMsgs); + +HRESULT WINAPI + D3DXPreprocessShaderFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPD3DXBUFFER* ppShaderText, + LPD3DXBUFFER* ppErrorMsgs); + +#ifdef UNICODE +#define D3DXPreprocessShaderFromResource D3DXPreprocessShaderFromResourceW +#else +#define D3DXPreprocessShaderFromResource D3DXPreprocessShaderFromResourceA +#endif + +HRESULT WINAPI + D3DXPreprocessShader( + LPCSTR pSrcData, + UINT SrcDataSize, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPD3DXBUFFER* ppShaderText, + LPD3DXBUFFER* ppErrorMsgs); + + +#ifdef __cplusplus +} +#endif //__cplusplus + + +////////////////////////////////////////////////////////////////////////////// +// Shader comment block layouts ////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXSHADER_CONSTANTTABLE: +// ------------------------- +// Shader constant information; included as an CTAB comment block inside +// shaders. All offsets are BYTE offsets from start of CONSTANTTABLE struct. +// Entries in the table are sorted by Name in ascending order. +//---------------------------------------------------------------------------- + +typedef struct _D3DXSHADER_CONSTANTTABLE +{ + DWORD Size; // sizeof(D3DXSHADER_CONSTANTTABLE) + DWORD Creator; // LPCSTR offset + DWORD Version; // shader version + DWORD Constants; // number of constants + DWORD ConstantInfo; // D3DXSHADER_CONSTANTINFO[Constants] offset + DWORD Flags; // flags shader was compiled with + DWORD Target; // LPCSTR offset + +} D3DXSHADER_CONSTANTTABLE, *LPD3DXSHADER_CONSTANTTABLE; + + +typedef struct _D3DXSHADER_CONSTANTINFO +{ + DWORD Name; // LPCSTR offset + WORD RegisterSet; // D3DXREGISTER_SET + WORD RegisterIndex; // register number + WORD RegisterCount; // number of registers + WORD Reserved; // reserved + DWORD TypeInfo; // D3DXSHADER_TYPEINFO offset + DWORD DefaultValue; // offset of default value + +} D3DXSHADER_CONSTANTINFO, *LPD3DXSHADER_CONSTANTINFO; + + +typedef struct _D3DXSHADER_TYPEINFO +{ + WORD Class; // D3DXPARAMETER_CLASS + WORD Type; // D3DXPARAMETER_TYPE + WORD Rows; // number of rows (matrices) + WORD Columns; // number of columns (vectors and matrices) + WORD Elements; // array dimension + WORD StructMembers; // number of struct members + DWORD StructMemberInfo; // D3DXSHADER_STRUCTMEMBERINFO[Members] offset + +} D3DXSHADER_TYPEINFO, *LPD3DXSHADER_TYPEINFO; + + +typedef struct _D3DXSHADER_STRUCTMEMBERINFO +{ + DWORD Name; // LPCSTR offset + DWORD TypeInfo; // D3DXSHADER_TYPEINFO offset + +} D3DXSHADER_STRUCTMEMBERINFO, *LPD3DXSHADER_STRUCTMEMBERINFO; + + + +#endif //__D3DX9SHADER_H__ + diff --git a/builddir/irrlicht-1.8.1/include/d3dx9shape.h b/builddir/irrlicht-1.8.1/include/d3dx9shape.h new file mode 100644 index 0000000..4c23091 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx9shape.h @@ -0,0 +1,221 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9shapes.h +// Content: D3DX simple shapes +// +/////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9SHAPES_H__ +#define __D3DX9SHAPES_H__ + +/////////////////////////////////////////////////////////////////////////// +// Functions: +/////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +//------------------------------------------------------------------------- +// D3DXCreatePolygon: +// ------------------ +// Creates a mesh containing an n-sided polygon. The polygon is centered +// at the origin. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Length Length of each side. +// Sides Number of sides the polygon has. (Must be >= 3) +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreatePolygon( + LPDIRECT3DDEVICE9 pDevice, + FLOAT Length, + UINT Sides, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateBox: +// -------------- +// Creates a mesh containing an axis-aligned box. The box is centered at +// the origin. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Width Width of box (along X-axis) +// Height Height of box (along Y-axis) +// Depth Depth of box (along Z-axis) +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateBox( + LPDIRECT3DDEVICE9 pDevice, + FLOAT Width, + FLOAT Height, + FLOAT Depth, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateCylinder: +// ------------------- +// Creates a mesh containing a cylinder. The generated cylinder is +// centered at the origin, and its axis is aligned with the Z-axis. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Radius1 Radius at -Z end (should be >= 0.0f) +// Radius2 Radius at +Z end (should be >= 0.0f) +// Length Length of cylinder (along Z-axis) +// Slices Number of slices about the main axis +// Stacks Number of stacks along the main axis +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateCylinder( + LPDIRECT3DDEVICE9 pDevice, + FLOAT Radius1, + FLOAT Radius2, + FLOAT Length, + UINT Slices, + UINT Stacks, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateSphere: +// ----------------- +// Creates a mesh containing a sphere. The sphere is centered at the +// origin. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Radius Radius of the sphere (should be >= 0.0f) +// Slices Number of slices about the main axis +// Stacks Number of stacks along the main axis +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateSphere( + LPDIRECT3DDEVICE9 pDevice, + FLOAT Radius, + UINT Slices, + UINT Stacks, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateTorus: +// ---------------- +// Creates a mesh containing a torus. The generated torus is centered at +// the origin, and its axis is aligned with the Z-axis. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// InnerRadius Inner radius of the torus (should be >= 0.0f) +// OuterRadius Outer radius of the torue (should be >= 0.0f) +// Sides Number of sides in a cross-section (must be >= 3) +// Rings Number of rings making up the torus (must be >= 3) +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateTorus( + LPDIRECT3DDEVICE9 pDevice, + FLOAT InnerRadius, + FLOAT OuterRadius, + UINT Sides, + UINT Rings, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateTeapot: +// ----------------- +// Creates a mesh containing a teapot. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateTeapot( + LPDIRECT3DDEVICE9 pDevice, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateText: +// --------------- +// Creates a mesh containing the specified text using the font associated +// with the device context. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// hDC Device context, with desired font selected +// pText Text to generate +// Deviation Maximum chordal deviation from true font outlines +// Extrusion Amount to extrude text in -Z direction +// ppMesh The mesh object which will be created +// pGlyphMetrics Address of buffer to receive glyph metric data (or NULL) +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateTextA( + LPDIRECT3DDEVICE9 pDevice, + HDC hDC, + LPCSTR pText, + FLOAT Deviation, + FLOAT Extrusion, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency, + LPGLYPHMETRICSFLOAT pGlyphMetrics); + +HRESULT WINAPI + D3DXCreateTextW( + LPDIRECT3DDEVICE9 pDevice, + HDC hDC, + LPCWSTR pText, + FLOAT Deviation, + FLOAT Extrusion, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency, + LPGLYPHMETRICSFLOAT pGlyphMetrics); + +#ifdef UNICODE +#define D3DXCreateText D3DXCreateTextW +#else +#define D3DXCreateText D3DXCreateTextA +#endif + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX9SHAPES_H__ + diff --git a/builddir/irrlicht-1.8.1/include/d3dx9tex.h b/builddir/irrlicht-1.8.1/include/d3dx9tex.h new file mode 100644 index 0000000..c4b6510 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx9tex.h @@ -0,0 +1,1735 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9tex.h +// Content: D3DX texturing APIs +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#ifndef __D3DX9TEX_H__ +#define __D3DX9TEX_H__ + + +//---------------------------------------------------------------------------- +// D3DX_FILTER flags: +// ------------------ +// +// A valid filter must contain one of these values: +// +// D3DX_FILTER_NONE +// No scaling or filtering will take place. Pixels outside the bounds +// of the source image are assumed to be transparent black. +// D3DX_FILTER_POINT +// Each destination pixel is computed by sampling the nearest pixel +// from the source image. +// D3DX_FILTER_LINEAR +// Each destination pixel is computed by linearly interpolating between +// the nearest pixels in the source image. This filter works best +// when the scale on each axis is less than 2. +// D3DX_FILTER_TRIANGLE +// Every pixel in the source image contributes equally to the +// destination image. This is the slowest of all the filters. +// D3DX_FILTER_BOX +// Each pixel is computed by averaging a 2x2(x2) box pixels from +// the source image. Only works when the dimensions of the +// destination are half those of the source. (as with mip maps) +// +// And can be OR'd with any of these optional flags: +// +// D3DX_FILTER_MIRROR_U +// Indicates that pixels off the edge of the texture on the U-axis +// should be mirrored, not wraped. +// D3DX_FILTER_MIRROR_V +// Indicates that pixels off the edge of the texture on the V-axis +// should be mirrored, not wraped. +// D3DX_FILTER_MIRROR_W +// Indicates that pixels off the edge of the texture on the W-axis +// should be mirrored, not wraped. +// D3DX_FILTER_MIRROR +// Same as specifying D3DX_FILTER_MIRROR_U | D3DX_FILTER_MIRROR_V | +// D3DX_FILTER_MIRROR_V +// D3DX_FILTER_DITHER +// Dithers the resulting image using a 4x4 order dither pattern. +// D3DX_FILTER_SRGB_IN +// Denotes that the input data is in sRGB (gamma 2.2) colorspace. +// D3DX_FILTER_SRGB_OUT +// Denotes that the output data is in sRGB (gamma 2.2) colorspace. +// D3DX_FILTER_SRGB +// Same as specifying D3DX_FILTER_SRGB_IN | D3DX_FILTER_SRGB_OUT +// +//---------------------------------------------------------------------------- + +#define D3DX_FILTER_NONE (1 << 0) +#define D3DX_FILTER_POINT (2 << 0) +#define D3DX_FILTER_LINEAR (3 << 0) +#define D3DX_FILTER_TRIANGLE (4 << 0) +#define D3DX_FILTER_BOX (5 << 0) + +#define D3DX_FILTER_MIRROR_U (1 << 16) +#define D3DX_FILTER_MIRROR_V (2 << 16) +#define D3DX_FILTER_MIRROR_W (4 << 16) +#define D3DX_FILTER_MIRROR (7 << 16) + +#define D3DX_FILTER_DITHER (1 << 19) +#define D3DX_FILTER_DITHER_DIFFUSION (2 << 19) + +#define D3DX_FILTER_SRGB_IN (1 << 21) +#define D3DX_FILTER_SRGB_OUT (2 << 21) +#define D3DX_FILTER_SRGB (3 << 21) + + +//----------------------------------------------------------------------------- +// D3DX_SKIP_DDS_MIP_LEVELS is used to skip mip levels when loading a DDS file: +//----------------------------------------------------------------------------- + +#define D3DX_SKIP_DDS_MIP_LEVELS_MASK 0x1F +#define D3DX_SKIP_DDS_MIP_LEVELS_SHIFT 26 +#define D3DX_SKIP_DDS_MIP_LEVELS(levels, filter) ((((levels) & D3DX_SKIP_DDS_MIP_LEVELS_MASK) << D3DX_SKIP_DDS_MIP_LEVELS_SHIFT) | ((filter) == D3DX_DEFAULT ? D3DX_FILTER_BOX : (filter))) + + + + +//---------------------------------------------------------------------------- +// D3DX_NORMALMAP flags: +// --------------------- +// These flags are used to control how D3DXComputeNormalMap generates normal +// maps. Any number of these flags may be OR'd together in any combination. +// +// D3DX_NORMALMAP_MIRROR_U +// Indicates that pixels off the edge of the texture on the U-axis +// should be mirrored, not wraped. +// D3DX_NORMALMAP_MIRROR_V +// Indicates that pixels off the edge of the texture on the V-axis +// should be mirrored, not wraped. +// D3DX_NORMALMAP_MIRROR +// Same as specifying D3DX_NORMALMAP_MIRROR_U | D3DX_NORMALMAP_MIRROR_V +// D3DX_NORMALMAP_INVERTSIGN +// Inverts the direction of each normal +// D3DX_NORMALMAP_COMPUTE_OCCLUSION +// Compute the per pixel Occlusion term and encodes it into the alpha. +// An Alpha of 1 means that the pixel is not obscured in anyway, and +// an alpha of 0 would mean that the pixel is completly obscured. +// +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +#define D3DX_NORMALMAP_MIRROR_U (1 << 16) +#define D3DX_NORMALMAP_MIRROR_V (2 << 16) +#define D3DX_NORMALMAP_MIRROR (3 << 16) +#define D3DX_NORMALMAP_INVERTSIGN (8 << 16) +#define D3DX_NORMALMAP_COMPUTE_OCCLUSION (16 << 16) + + + + +//---------------------------------------------------------------------------- +// D3DX_CHANNEL flags: +// ------------------- +// These flags are used by functions which operate on or more channels +// in a texture. +// +// D3DX_CHANNEL_RED +// Indicates the red channel should be used +// D3DX_CHANNEL_BLUE +// Indicates the blue channel should be used +// D3DX_CHANNEL_GREEN +// Indicates the green channel should be used +// D3DX_CHANNEL_ALPHA +// Indicates the alpha channel should be used +// D3DX_CHANNEL_LUMINANCE +// Indicates the luminaces of the red green and blue channels should be +// used. +// +//---------------------------------------------------------------------------- + +#define D3DX_CHANNEL_RED (1 << 0) +#define D3DX_CHANNEL_BLUE (1 << 1) +#define D3DX_CHANNEL_GREEN (1 << 2) +#define D3DX_CHANNEL_ALPHA (1 << 3) +#define D3DX_CHANNEL_LUMINANCE (1 << 4) + + + + +//---------------------------------------------------------------------------- +// D3DXIMAGE_FILEFORMAT: +// --------------------- +// This enum is used to describe supported image file formats. +// +//---------------------------------------------------------------------------- + +typedef enum _D3DXIMAGE_FILEFORMAT +{ + D3DXIFF_BMP = 0, + D3DXIFF_JPG = 1, + D3DXIFF_TGA = 2, + D3DXIFF_PNG = 3, + D3DXIFF_DDS = 4, + D3DXIFF_PPM = 5, + D3DXIFF_DIB = 6, + D3DXIFF_HDR = 7, //high dynamic range formats + D3DXIFF_PFM = 8, // + D3DXIFF_FORCE_DWORD = 0x7fffffff + +} D3DXIMAGE_FILEFORMAT; + + +//---------------------------------------------------------------------------- +// LPD3DXFILL2D and LPD3DXFILL3D: +// ------------------------------ +// Function types used by the texture fill functions. +// +// Parameters: +// pOut +// Pointer to a vector which the function uses to return its result. +// X,Y,Z,W will be mapped to R,G,B,A respectivly. +// pTexCoord +// Pointer to a vector containing the coordinates of the texel currently +// being evaluated. Textures and VolumeTexture texcoord components +// range from 0 to 1. CubeTexture texcoord component range from -1 to 1. +// pTexelSize +// Pointer to a vector containing the dimensions of the current texel. +// pData +// Pointer to user data. +// +//---------------------------------------------------------------------------- + +typedef VOID (WINAPI *LPD3DXFILL2D)(D3DXVECTOR4 *pOut, + CONST D3DXVECTOR2 *pTexCoord, CONST D3DXVECTOR2 *pTexelSize, LPVOID pData); + +typedef VOID (WINAPI *LPD3DXFILL3D)(D3DXVECTOR4 *pOut, + CONST D3DXVECTOR3 *pTexCoord, CONST D3DXVECTOR3 *pTexelSize, LPVOID pData); + + + +//---------------------------------------------------------------------------- +// D3DXIMAGE_INFO: +// --------------- +// This structure is used to return a rough description of what the +// the original contents of an image file looked like. +// +// Width +// Width of original image in pixels +// Height +// Height of original image in pixels +// Depth +// Depth of original image in pixels +// MipLevels +// Number of mip levels in original image +// Format +// D3D format which most closely describes the data in original image +// ResourceType +// D3DRESOURCETYPE representing the type of texture stored in the file. +// D3DRTYPE_TEXTURE, D3DRTYPE_VOLUMETEXTURE, or D3DRTYPE_CUBETEXTURE. +// ImageFileFormat +// D3DXIMAGE_FILEFORMAT representing the format of the image file. +// +//---------------------------------------------------------------------------- + +typedef struct _D3DXIMAGE_INFO +{ + UINT Width; + UINT Height; + UINT Depth; + UINT MipLevels; + D3DFORMAT Format; + D3DRESOURCETYPE ResourceType; + D3DXIMAGE_FILEFORMAT ImageFileFormat; + +} D3DXIMAGE_INFO; + + + + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + + +////////////////////////////////////////////////////////////////////////////// +// Image File APIs /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +; +//---------------------------------------------------------------------------- +// GetImageInfoFromFile/Resource: +// ------------------------------ +// Fills in a D3DXIMAGE_INFO struct with information about an image file. +// +// Parameters: +// pSrcFile +// File name of the source image. +// pSrcModule +// Module where resource is located, or NULL for module associated +// with image the os used to create the current process. +// pSrcResource +// Resource name +// pSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXGetImageInfoFromFileA( + LPCSTR pSrcFile, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXGetImageInfoFromFileW( + LPCWSTR pSrcFile, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXGetImageInfoFromFile D3DXGetImageInfoFromFileW +#else +#define D3DXGetImageInfoFromFile D3DXGetImageInfoFromFileA +#endif + + +HRESULT WINAPI + D3DXGetImageInfoFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXGetImageInfoFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXGetImageInfoFromResource D3DXGetImageInfoFromResourceW +#else +#define D3DXGetImageInfoFromResource D3DXGetImageInfoFromResourceA +#endif + + +HRESULT WINAPI + D3DXGetImageInfoFromFileInMemory( + LPCVOID pSrcData, + UINT SrcDataSize, + D3DXIMAGE_INFO* pSrcInfo); + + + + +////////////////////////////////////////////////////////////////////////////// +// Load/Save Surface APIs //////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXLoadSurfaceFromFile/Resource: +// --------------------------------- +// Load surface from a file or resource +// +// Parameters: +// pDestSurface +// Destination surface, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestRect +// Destination rectangle, or NULL for entire surface +// pSrcFile +// File name of the source image. +// pSrcModule +// Module where resource is located, or NULL for module associated +// with image the os used to create the current process. +// pSrcResource +// Resource name +// pSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pSrcRect +// Source rectangle, or NULL for entire image +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file, or NULL. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadSurfaceFromFileA( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCSTR pSrcFile, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadSurfaceFromFileW( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCWSTR pSrcFile, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXLoadSurfaceFromFile D3DXLoadSurfaceFromFileW +#else +#define D3DXLoadSurfaceFromFile D3DXLoadSurfaceFromFileA +#endif + + + +HRESULT WINAPI + D3DXLoadSurfaceFromResourceA( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadSurfaceFromResourceW( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + + +#ifdef UNICODE +#define D3DXLoadSurfaceFromResource D3DXLoadSurfaceFromResourceW +#else +#define D3DXLoadSurfaceFromResource D3DXLoadSurfaceFromResourceA +#endif + + + +HRESULT WINAPI + D3DXLoadSurfaceFromFileInMemory( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCVOID pSrcData, + UINT SrcDataSize, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + + + +//---------------------------------------------------------------------------- +// D3DXLoadSurfaceFromSurface: +// --------------------------- +// Load surface from another surface (with color conversion) +// +// Parameters: +// pDestSurface +// Destination surface, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestRect +// Destination rectangle, or NULL for entire surface +// pSrcSurface +// Source surface +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcRect +// Source rectangle, or NULL for entire surface +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadSurfaceFromSurface( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPDIRECT3DSURFACE9 pSrcSurface, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey); + + +//---------------------------------------------------------------------------- +// D3DXLoadSurfaceFromMemory: +// -------------------------- +// Load surface from memory. +// +// Parameters: +// pDestSurface +// Destination surface, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestRect +// Destination rectangle, or NULL for entire surface +// pSrcMemory +// Pointer to the top-left corner of the source image in memory +// SrcFormat +// Pixel format of the source image. +// SrcPitch +// Pitch of source image, in bytes. For DXT formats, this number +// should represent the width of one row of cells, in bytes. +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcRect +// Source rectangle. +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadSurfaceFromMemory( + LPDIRECT3DSURFACE9 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCVOID pSrcMemory, + D3DFORMAT SrcFormat, + UINT SrcPitch, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey); + + +//---------------------------------------------------------------------------- +// D3DXSaveSurfaceToFile: +// ---------------------- +// Save a surface to a image file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcSurface +// Source surface, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcRect +// Source rectangle, or NULL for the entire image +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveSurfaceToFileA( + LPCSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DSURFACE9 pSrcSurface, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect); + +HRESULT WINAPI + D3DXSaveSurfaceToFileW( + LPCWSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DSURFACE9 pSrcSurface, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect); + +#ifdef UNICODE +#define D3DXSaveSurfaceToFile D3DXSaveSurfaceToFileW +#else +#define D3DXSaveSurfaceToFile D3DXSaveSurfaceToFileA +#endif + +//---------------------------------------------------------------------------- +// D3DXSaveSurfaceToFileInMemory: +// ---------------------- +// Save a surface to a image file. +// +// Parameters: +// ppDestBuf +// address of pointer to d3dxbuffer for returning data bits +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcSurface +// Source surface, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcRect +// Source rectangle, or NULL for the entire image +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveSurfaceToFileInMemory( + LPD3DXBUFFER* ppDestBuf, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DSURFACE9 pSrcSurface, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect); + + +////////////////////////////////////////////////////////////////////////////// +// Load/Save Volume APIs ///////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXLoadVolumeFromFile/Resource: +// -------------------------------- +// Load volume from a file or resource +// +// Parameters: +// pDestVolume +// Destination volume, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestBox +// Destination box, or NULL for entire volume +// pSrcFile +// File name of the source image. +// pSrcModule +// Module where resource is located, or NULL for module associated +// with image the os used to create the current process. +// pSrcResource +// Resource name +// pSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pSrcBox +// Source box, or NULL for entire image +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file, or NULL. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadVolumeFromFileA( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCSTR pSrcFile, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadVolumeFromFileW( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCWSTR pSrcFile, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXLoadVolumeFromFile D3DXLoadVolumeFromFileW +#else +#define D3DXLoadVolumeFromFile D3DXLoadVolumeFromFileA +#endif + + +HRESULT WINAPI + D3DXLoadVolumeFromResourceA( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadVolumeFromResourceW( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXLoadVolumeFromResource D3DXLoadVolumeFromResourceW +#else +#define D3DXLoadVolumeFromResource D3DXLoadVolumeFromResourceA +#endif + + + +HRESULT WINAPI + D3DXLoadVolumeFromFileInMemory( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCVOID pSrcData, + UINT SrcDataSize, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + + + +//---------------------------------------------------------------------------- +// D3DXLoadVolumeFromVolume: +// ------------------------- +// Load volume from another volume (with color conversion) +// +// Parameters: +// pDestVolume +// Destination volume, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestBox +// Destination box, or NULL for entire volume +// pSrcVolume +// Source volume +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcBox +// Source box, or NULL for entire volume +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadVolumeFromVolume( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPDIRECT3DVOLUME9 pSrcVolume, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey); + + + +//---------------------------------------------------------------------------- +// D3DXLoadVolumeFromMemory: +// ------------------------- +// Load volume from memory. +// +// Parameters: +// pDestVolume +// Destination volume, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestBox +// Destination box, or NULL for entire volume +// pSrcMemory +// Pointer to the top-left corner of the source volume in memory +// SrcFormat +// Pixel format of the source volume. +// SrcRowPitch +// Pitch of source image, in bytes. For DXT formats, this number +// should represent the size of one row of cells, in bytes. +// SrcSlicePitch +// Pitch of source image, in bytes. For DXT formats, this number +// should represent the size of one slice of cells, in bytes. +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcBox +// Source box. +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadVolumeFromMemory( + LPDIRECT3DVOLUME9 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCVOID pSrcMemory, + D3DFORMAT SrcFormat, + UINT SrcRowPitch, + UINT SrcSlicePitch, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey); + + + +//---------------------------------------------------------------------------- +// D3DXSaveVolumeToFile: +// --------------------- +// Save a volume to a image file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcVolume +// Source volume, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcBox +// Source box, or NULL for the entire volume +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveVolumeToFileA( + LPCSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DVOLUME9 pSrcVolume, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox); + +HRESULT WINAPI + D3DXSaveVolumeToFileW( + LPCWSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DVOLUME9 pSrcVolume, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox); + +#ifdef UNICODE +#define D3DXSaveVolumeToFile D3DXSaveVolumeToFileW +#else +#define D3DXSaveVolumeToFile D3DXSaveVolumeToFileA +#endif + + +//---------------------------------------------------------------------------- +// D3DXSaveVolumeToFileInMemory: +// --------------------- +// Save a volume to a image file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcVolume +// Source volume, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcBox +// Source box, or NULL for the entire volume +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveVolumeToFileInMemory( + LPD3DXBUFFER* ppDestBuf, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DVOLUME9 pSrcVolume, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox); + +////////////////////////////////////////////////////////////////////////////// +// Create/Save Texture APIs ////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXCheckTextureRequirements: +// ----------------------------- +// Checks texture creation parameters. If parameters are invalid, this +// function returns corrected parameters. +// +// Parameters: +// +// pDevice +// The D3D device to be used +// pWidth, pHeight, pDepth, pSize +// Desired size in pixels, or NULL. Returns corrected size. +// pNumMipLevels +// Number of desired mipmap levels, or NULL. Returns corrected number. +// Usage +// Texture usage flags +// pFormat +// Desired pixel format, or NULL. Returns corrected format. +// Pool +// Memory pool to be used to create texture +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCheckTextureRequirements( + LPDIRECT3DDEVICE9 pDevice, + UINT* pWidth, + UINT* pHeight, + UINT* pNumMipLevels, + DWORD Usage, + D3DFORMAT* pFormat, + D3DPOOL Pool); + +HRESULT WINAPI + D3DXCheckCubeTextureRequirements( + LPDIRECT3DDEVICE9 pDevice, + UINT* pSize, + UINT* pNumMipLevels, + DWORD Usage, + D3DFORMAT* pFormat, + D3DPOOL Pool); + +HRESULT WINAPI + D3DXCheckVolumeTextureRequirements( + LPDIRECT3DDEVICE9 pDevice, + UINT* pWidth, + UINT* pHeight, + UINT* pDepth, + UINT* pNumMipLevels, + DWORD Usage, + D3DFORMAT* pFormat, + D3DPOOL Pool); + + +//---------------------------------------------------------------------------- +// D3DXCreateTexture: +// ------------------ +// Create an empty texture +// +// Parameters: +// +// pDevice +// The D3D device with which the texture is going to be used. +// Width, Height, Depth, Size +// size in pixels. these must be non-zero +// MipLevels +// number of mip levels desired. if zero or D3DX_DEFAULT, a complete +// mipmap chain will be created. +// Usage +// Texture usage flags +// Format +// Pixel format. +// Pool +// Memory pool to be used to create texture +// ppTexture, ppCubeTexture, ppVolumeTexture +// The texture object that will be created +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateTexture( + LPDIRECT3DDEVICE9 pDevice, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateCubeTexture( + LPDIRECT3DDEVICE9 pDevice, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTexture( + LPDIRECT3DDEVICE9 pDevice, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + + + +//---------------------------------------------------------------------------- +// D3DXCreateTextureFromFile/Resource: +// ----------------------------------- +// Create a texture object from a file or resource. +// +// Parameters: +// +// pDevice +// The D3D device with which the texture is going to be used. +// pSrcFile +// File name. +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module +// pvSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// Width, Height, Depth, Size +// Size in pixels. If zero or D3DX_DEFAULT, the size will be taken from +// the file and rounded up to a power of two. If D3DX_DEFAULT_NONPOW2, +// and the device supports NONPOW2 textures, the size will not be rounded. +// If D3DX_FROM_FILE, the size will be taken exactly as it is in the file, +// and the call will fail if this violates device capabilities. +// MipLevels +// Number of mip levels. If zero or D3DX_DEFAULT, a complete mipmap +// chain will be created. If D3DX_FROM_FILE, the size will be taken +// exactly as it is in the file, and the call will fail if this violates +// device capabilities. +// Usage +// Texture usage flags +// Format +// Desired pixel format. If D3DFMT_UNKNOWN, the format will be +// taken from the file. If D3DFMT_FROM_FILE, the format will be taken +// exactly as it is in the file, and the call will fail if the device does +// not support the given format. +// Pool +// Memory pool to be used to create texture +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// MipFilter +// D3DX_FILTER flags controlling how each miplevel is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_BOX. +// Use the D3DX_SKIP_DDS_MIP_LEVELS macro to specify both a filter and the +// number of mip levels to skip when loading DDS files. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file, or NULL. +// pPalette +// 256 color palette to be filled in, or NULL +// ppTexture, ppCubeTexture, ppVolumeTexture +// The texture object that will be created +// +//---------------------------------------------------------------------------- + +// FromFile + +HRESULT WINAPI + D3DXCreateTextureFromFileA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromFileW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + LPDIRECT3DTEXTURE9* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromFile D3DXCreateTextureFromFileW +#else +#define D3DXCreateTextureFromFile D3DXCreateTextureFromFileA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromFile D3DXCreateCubeTextureFromFileW +#else +#define D3DXCreateCubeTextureFromFile D3DXCreateCubeTextureFromFileA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromFile D3DXCreateVolumeTextureFromFileW +#else +#define D3DXCreateVolumeTextureFromFile D3DXCreateVolumeTextureFromFileA +#endif + + +// FromResource + +HRESULT WINAPI + D3DXCreateTextureFromResourceA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromResourceW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + LPDIRECT3DTEXTURE9* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromResource D3DXCreateTextureFromResourceW +#else +#define D3DXCreateTextureFromResource D3DXCreateTextureFromResourceA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromResource D3DXCreateCubeTextureFromResourceW +#else +#define D3DXCreateCubeTextureFromResource D3DXCreateCubeTextureFromResourceA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromResource D3DXCreateVolumeTextureFromResourceW +#else +#define D3DXCreateVolumeTextureFromResource D3DXCreateVolumeTextureFromResourceA +#endif + + +// FromFileEx + +HRESULT WINAPI + D3DXCreateTextureFromFileExA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromFileExW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromFileEx D3DXCreateTextureFromFileExW +#else +#define D3DXCreateTextureFromFileEx D3DXCreateTextureFromFileExA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileExA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileExW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromFileEx D3DXCreateCubeTextureFromFileExW +#else +#define D3DXCreateCubeTextureFromFileEx D3DXCreateCubeTextureFromFileExA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileExA( + LPDIRECT3DDEVICE9 pDevice, + LPCSTR pSrcFile, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileExW( + LPDIRECT3DDEVICE9 pDevice, + LPCWSTR pSrcFile, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromFileEx D3DXCreateVolumeTextureFromFileExW +#else +#define D3DXCreateVolumeTextureFromFileEx D3DXCreateVolumeTextureFromFileExA +#endif + + +// FromResourceEx + +HRESULT WINAPI + D3DXCreateTextureFromResourceExA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromResourceExW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromResourceEx D3DXCreateTextureFromResourceExW +#else +#define D3DXCreateTextureFromResourceEx D3DXCreateTextureFromResourceExA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceExA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceExW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromResourceEx D3DXCreateCubeTextureFromResourceExW +#else +#define D3DXCreateCubeTextureFromResourceEx D3DXCreateCubeTextureFromResourceExA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceExA( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceExW( + LPDIRECT3DDEVICE9 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromResourceEx D3DXCreateVolumeTextureFromResourceExW +#else +#define D3DXCreateVolumeTextureFromResourceEx D3DXCreateVolumeTextureFromResourceExA +#endif + + +// FromFileInMemory + +HRESULT WINAPI + D3DXCreateTextureFromFileInMemory( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileInMemory( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileInMemory( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + + +// FromFileInMemoryEx + +HRESULT WINAPI + D3DXCreateTextureFromFileInMemoryEx( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE9* ppTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileInMemoryEx( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE9* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileInMemoryEx( + LPDIRECT3DDEVICE9 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture); + + + +//---------------------------------------------------------------------------- +// D3DXSaveTextureToFile: +// ---------------------- +// Save a texture to a file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcTexture +// Source texture, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// +//---------------------------------------------------------------------------- + + +HRESULT WINAPI + D3DXSaveTextureToFileA( + LPCSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DBASETEXTURE9 pSrcTexture, + CONST PALETTEENTRY* pSrcPalette); + +HRESULT WINAPI + D3DXSaveTextureToFileW( + LPCWSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DBASETEXTURE9 pSrcTexture, + CONST PALETTEENTRY* pSrcPalette); + +#ifdef UNICODE +#define D3DXSaveTextureToFile D3DXSaveTextureToFileW +#else +#define D3DXSaveTextureToFile D3DXSaveTextureToFileA +#endif + + +//---------------------------------------------------------------------------- +// D3DXSaveTextureToFileInMemory: +// ---------------------- +// Save a texture to a file. +// +// Parameters: +// ppDestBuf +// address of a d3dxbuffer pointer to return the image data +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcTexture +// Source texture, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveTextureToFileInMemory( + LPD3DXBUFFER* ppDestBuf, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DBASETEXTURE9 pSrcTexture, + CONST PALETTEENTRY* pSrcPalette); + + + + +////////////////////////////////////////////////////////////////////////////// +// Misc Texture APIs ///////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXFilterTexture: +// ------------------ +// Filters mipmaps levels of a texture. +// +// Parameters: +// pBaseTexture +// The texture object to be filtered +// pPalette +// 256 color palette to be used, or NULL for non-palettized formats +// SrcLevel +// The level whose image is used to generate the subsequent levels. +// Filter +// D3DX_FILTER flags controlling how each miplevel is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_BOX, +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXFilterTexture( + LPDIRECT3DBASETEXTURE9 pBaseTexture, + CONST PALETTEENTRY* pPalette, + UINT SrcLevel, + DWORD Filter); + +#define D3DXFilterCubeTexture D3DXFilterTexture +#define D3DXFilterVolumeTexture D3DXFilterTexture + + + +//---------------------------------------------------------------------------- +// D3DXFillTexture: +// ---------------- +// Uses a user provided function to fill each texel of each mip level of a +// given texture. +// +// Paramters: +// pTexture, pCubeTexture, pVolumeTexture +// Pointer to the texture to be filled. +// pFunction +// Pointer to user provided evalutor function which will be used to +// compute the value of each texel. +// pData +// Pointer to an arbitrary block of user defined data. This pointer +// will be passed to the function provided in pFunction +//----------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXFillTexture( + LPDIRECT3DTEXTURE9 pTexture, + LPD3DXFILL2D pFunction, + LPVOID pData); + +HRESULT WINAPI + D3DXFillCubeTexture( + LPDIRECT3DCUBETEXTURE9 pCubeTexture, + LPD3DXFILL3D pFunction, + LPVOID pData); + +HRESULT WINAPI + D3DXFillVolumeTexture( + LPDIRECT3DVOLUMETEXTURE9 pVolumeTexture, + LPD3DXFILL3D pFunction, + LPVOID pData); + +//--------------------------------------------------------------------------- +// D3DXFillTextureTX: +// ------------------ +// Uses a TX Shader target to function to fill each texel of each mip level +// of a given texture. The TX Shader target should be a compiled function +// taking 2 paramters and returning a float4 color. +// +// Paramters: +// pTexture, pCubeTexture, pVolumeTexture +// Pointer to the texture to be filled. +// pTextureShader +// Pointer to the texture shader to be used to fill in the texture +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXFillTextureTX( + LPDIRECT3DTEXTURE9 pTexture, + LPD3DXTEXTURESHADER pTextureShader); + + +HRESULT WINAPI + D3DXFillCubeTextureTX( + LPDIRECT3DCUBETEXTURE9 pCubeTexture, + LPD3DXTEXTURESHADER pTextureShader); + + +HRESULT WINAPI + D3DXFillVolumeTextureTX( + LPDIRECT3DVOLUMETEXTURE9 pVolumeTexture, + LPD3DXTEXTURESHADER pTextureShader); + + + +//---------------------------------------------------------------------------- +// D3DXComputeNormalMap: +// --------------------- +// Converts a height map into a normal map. The (x,y,z) components of each +// normal are mapped to the (r,g,b) channels of the output texture. +// +// Parameters +// pTexture +// Pointer to the destination texture +// pSrcTexture +// Pointer to the source heightmap texture +// pSrcPalette +// Source palette of 256 colors, or NULL +// Flags +// D3DX_NORMALMAP flags +// Channel +// D3DX_CHANNEL specifying source of height information +// Amplitude +// The constant value which the height information is multiplied by. +//--------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXComputeNormalMap( + LPDIRECT3DTEXTURE9 pTexture, + LPDIRECT3DTEXTURE9 pSrcTexture, + CONST PALETTEENTRY* pSrcPalette, + DWORD Flags, + DWORD Channel, + FLOAT Amplitude); + + + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX9TEX_H__ + diff --git a/builddir/irrlicht-1.8.1/include/d3dx9xof.h b/builddir/irrlicht-1.8.1/include/d3dx9xof.h new file mode 100644 index 0000000..c513f0f --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/d3dx9xof.h @@ -0,0 +1,299 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx9xof.h +// Content: D3DX .X File types and functions +// +/////////////////////////////////////////////////////////////////////////// + +#include "d3dx9.h" + +#if !defined( __D3DX9XOF_H__ ) +#define __D3DX9XOF_H__ + +#if defined( __cplusplus ) +extern "C" { +#endif // defined( __cplusplus ) + +//---------------------------------------------------------------------------- +// D3DXF_FILEFORMAT +// This flag is used to specify what file type to use when saving to disk. +// _BINARY, and _TEXT are mutually exclusive, while +// _COMPRESSED is an optional setting that works with all file types. +//---------------------------------------------------------------------------- +typedef DWORD D3DXF_FILEFORMAT; + +#define D3DXF_FILEFORMAT_BINARY 0 +#define D3DXF_FILEFORMAT_TEXT 1 +#define D3DXF_FILEFORMAT_COMPRESSED 2 + +//---------------------------------------------------------------------------- +// D3DXF_FILESAVEOPTIONS +// This flag is used to specify where to save the file to. Each flag is +// mutually exclusive, indicates the data location of the file, and also +// chooses which additional data will specify the location. +// _TOFILE is paired with a filename (LPCSTR) +// _TOWFILE is paired with a filename (LPWSTR) +//---------------------------------------------------------------------------- +typedef DWORD D3DXF_FILESAVEOPTIONS; + +#define D3DXF_FILESAVE_TOFILE 0x00L +#define D3DXF_FILESAVE_TOWFILE 0x01L + +//---------------------------------------------------------------------------- +// D3DXF_FILELOADOPTIONS +// This flag is used to specify where to load the file from. Each flag is +// mutually exclusive, indicates the data location of the file, and also +// chooses which additional data will specify the location. +// _FROMFILE is paired with a filename (LPCSTR) +// _FROMWFILE is paired with a filename (LPWSTR) +// _FROMRESOURCE is paired with a (D3DXF_FILELOADRESOUCE*) description. +// _FROMMEMORY is paired with a (D3DXF_FILELOADMEMORY*) description. +//---------------------------------------------------------------------------- +typedef DWORD D3DXF_FILELOADOPTIONS; + +#define D3DXF_FILELOAD_FROMFILE 0x00L +#define D3DXF_FILELOAD_FROMWFILE 0x01L +#define D3DXF_FILELOAD_FROMRESOURCE 0x02L +#define D3DXF_FILELOAD_FROMMEMORY 0x03L + +//---------------------------------------------------------------------------- +// D3DXF_FILELOADRESOURCE: +//---------------------------------------------------------------------------- + +typedef struct _D3DXF_FILELOADRESOURCE +{ + HMODULE hModule; // Desc + LPCSTR lpName; // Desc + LPCSTR lpType; // Desc +} D3DXF_FILELOADRESOURCE; + +//---------------------------------------------------------------------------- +// D3DXF_FILELOADMEMORY: +//---------------------------------------------------------------------------- + +typedef struct _D3DXF_FILELOADMEMORY +{ + LPCVOID lpMemory; // Desc + SIZE_T dSize; // Desc +} D3DXF_FILELOADMEMORY; + +#if defined( _WIN32 ) && !defined( _NO_COM ) + +// {cef08cf9-7b4f-4429-9624-2a690a933201} +DEFINE_GUID( IID_ID3DXFile, +0xcef08cf9, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); + +// {cef08cfa-7b4f-4429-9624-2a690a933201} +DEFINE_GUID( IID_ID3DXFileSaveObject, +0xcef08cfa, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); + +// {cef08cfb-7b4f-4429-9624-2a690a933201} +DEFINE_GUID( IID_ID3DXFileSaveData, +0xcef08cfb, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); + +// {cef08cfc-7b4f-4429-9624-2a690a933201} +DEFINE_GUID( IID_ID3DXFileEnumObject, +0xcef08cfc, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); + +// {cef08cfd-7b4f-4429-9624-2a690a933201} +DEFINE_GUID( IID_ID3DXFileData, +0xcef08cfd, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); + +#endif // defined( _WIN32 ) && !defined( _NO_COM ) + +#if defined( __cplusplus ) +#if !defined( DECLSPEC_UUID ) +#if _MSC_VER >= 1100 +#define DECLSPEC_UUID( x ) __declspec( uuid( x ) ) +#else // !( _MSC_VER >= 1100 ) +#define DECLSPEC_UUID( x ) +#endif // !( _MSC_VER >= 1100 ) +#endif // !defined( DECLSPEC_UUID ) + +interface DECLSPEC_UUID( "cef08cf9-7b4f-4429-9624-2a690a933201" ) + ID3DXFile; +interface DECLSPEC_UUID( "cef08cfa-7b4f-4429-9624-2a690a933201" ) + ID3DXFileSaveObject; +interface DECLSPEC_UUID( "cef08cfb-7b4f-4429-9624-2a690a933201" ) + ID3DXFileSaveData; +interface DECLSPEC_UUID( "cef08cfc-7b4f-4429-9624-2a690a933201" ) + ID3DXFileEnumObject; +interface DECLSPEC_UUID( "cef08cfd-7b4f-4429-9624-2a690a933201" ) + ID3DXFileData; + +#if defined( _COM_SMARTPTR_TYPEDEF ) +_COM_SMARTPTR_TYPEDEF( ID3DXFile, + __uuidof( ID3DXFile ) ); +_COM_SMARTPTR_TYPEDEF( ID3DXFileSaveObject, + __uuidof( ID3DXFileSaveObject ) ); +_COM_SMARTPTR_TYPEDEF( ID3DXFileSaveData, + __uuidof( ID3DXFileSaveData ) ); +_COM_SMARTPTR_TYPEDEF( ID3DXFileEnumObject, + __uuidof( ID3DXFileEnumObject ) ); +_COM_SMARTPTR_TYPEDEF( ID3DXFileData, + __uuidof( ID3DXFileData ) ); +#endif // defined( _COM_SMARTPTR_TYPEDEF ) +#endif // defined( __cplusplus ) + +typedef interface ID3DXFile ID3DXFile; +typedef interface ID3DXFileSaveObject ID3DXFileSaveObject; +typedef interface ID3DXFileSaveData ID3DXFileSaveData; +typedef interface ID3DXFileEnumObject ID3DXFileEnumObject; +typedef interface ID3DXFileData ID3DXFileData; + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFile ///////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DXFile + +DECLARE_INTERFACE_( ID3DXFile, IUnknown ) +{ + STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; + STDMETHOD_( ULONG, AddRef )( THIS ) PURE; + STDMETHOD_( ULONG, Release )( THIS ) PURE; + + STDMETHOD( CreateEnumObject )( THIS_ LPCVOID, D3DXF_FILELOADOPTIONS, + ID3DXFileEnumObject** ) PURE; + STDMETHOD( CreateSaveObject )( THIS_ LPCVOID, D3DXF_FILESAVEOPTIONS, + D3DXF_FILEFORMAT, ID3DXFileSaveObject** ) PURE; + STDMETHOD( RegisterTemplates )( THIS_ LPCVOID, SIZE_T ) PURE; + STDMETHOD( RegisterEnumTemplates )( THIS_ ID3DXFileEnumObject* ) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFileSaveObject /////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DXFileSaveObject + +DECLARE_INTERFACE_( ID3DXFileSaveObject, IUnknown ) +{ + STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; + STDMETHOD_( ULONG, AddRef )( THIS ) PURE; + STDMETHOD_( ULONG, Release )( THIS ) PURE; + + STDMETHOD( GetFile )( THIS_ ID3DXFile** ) PURE; + STDMETHOD( AddDataObject )( THIS_ REFGUID, LPCSTR, CONST GUID*, + SIZE_T, LPCVOID, ID3DXFileSaveData** ) PURE; + STDMETHOD( Save )( THIS ) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFileSaveData ///////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DXFileSaveData + +DECLARE_INTERFACE_( ID3DXFileSaveData, IUnknown ) +{ + STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; + STDMETHOD_( ULONG, AddRef )( THIS ) PURE; + STDMETHOD_( ULONG, Release )( THIS ) PURE; + + STDMETHOD( GetSave )( THIS_ ID3DXFileSaveObject** ) PURE; + STDMETHOD( GetName )( THIS_ LPSTR, SIZE_T* ) PURE; + STDMETHOD( GetId )( THIS_ LPGUID ) PURE; + STDMETHOD( GetType )( THIS_ GUID* ) PURE; + STDMETHOD( AddDataObject )( THIS_ REFGUID, LPCSTR, CONST GUID*, + SIZE_T, LPCVOID, ID3DXFileSaveData** ) PURE; + STDMETHOD( AddDataReference )( THIS_ LPCSTR, CONST GUID* ) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFileEnumObject /////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DXFileEnumObject + +DECLARE_INTERFACE_( ID3DXFileEnumObject, IUnknown ) +{ + STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; + STDMETHOD_( ULONG, AddRef )( THIS ) PURE; + STDMETHOD_( ULONG, Release )( THIS ) PURE; + + STDMETHOD( GetFile )( THIS_ ID3DXFile** ) PURE; + STDMETHOD( GetChildren )( THIS_ SIZE_T* ) PURE; + STDMETHOD( GetChild )( THIS_ SIZE_T, ID3DXFileData** ) PURE; + STDMETHOD( GetDataObjectById )( THIS_ REFGUID, ID3DXFileData** ) PURE; + STDMETHOD( GetDataObjectByName )( THIS_ LPCSTR, ID3DXFileData** ) PURE; +}; + +////////////////////////////////////////////////////////////////////////////// +// ID3DXFileData ///////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#undef INTERFACE +#define INTERFACE ID3DXFileData + +DECLARE_INTERFACE_( ID3DXFileData, IUnknown ) +{ + STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; + STDMETHOD_( ULONG, AddRef )( THIS ) PURE; + STDMETHOD_( ULONG, Release )( THIS ) PURE; + + STDMETHOD( GetEnum )( THIS_ ID3DXFileEnumObject** ) PURE; + STDMETHOD( GetName )( THIS_ LPSTR, SIZE_T* ) PURE; + STDMETHOD( GetId )( THIS_ LPGUID ) PURE; + STDMETHOD( Lock )( THIS_ SIZE_T*, LPCVOID* ) PURE; + STDMETHOD( Unlock )( THIS ) PURE; + STDMETHOD( GetType )( THIS_ GUID* ) PURE; + STDMETHOD_( BOOL, IsReference )( THIS ) PURE; + STDMETHOD( GetChildren )( THIS_ SIZE_T* ) PURE; + STDMETHOD( GetChild )( THIS_ SIZE_T, ID3DXFileData** ) PURE; +}; + +STDAPI D3DXFileCreate( ID3DXFile** lplpDirectXFile ); + +/* + * DirectX File errors. + */ + +#define _FACD3DXF 0x876 + +#define D3DXFERR_BADOBJECT MAKE_HRESULT( 1, _FACD3DXF, 900 ) +#define D3DXFERR_BADVALUE MAKE_HRESULT( 1, _FACD3DXF, 901 ) +#define D3DXFERR_BADTYPE MAKE_HRESULT( 1, _FACD3DXF, 902 ) +#define D3DXFERR_NOTFOUND MAKE_HRESULT( 1, _FACD3DXF, 903 ) +#define D3DXFERR_NOTDONEYET MAKE_HRESULT( 1, _FACD3DXF, 904 ) +#define D3DXFERR_FILENOTFOUND MAKE_HRESULT( 1, _FACD3DXF, 905 ) +#define D3DXFERR_RESOURCENOTFOUND MAKE_HRESULT( 1, _FACD3DXF, 906 ) +#define D3DXFERR_BADRESOURCE MAKE_HRESULT( 1, _FACD3DXF, 907 ) +#define D3DXFERR_BADFILETYPE MAKE_HRESULT( 1, _FACD3DXF, 908 ) +#define D3DXFERR_BADFILEVERSION MAKE_HRESULT( 1, _FACD3DXF, 909 ) +#define D3DXFERR_BADFILEFLOATSIZE MAKE_HRESULT( 1, _FACD3DXF, 910 ) +#define D3DXFERR_BADFILE MAKE_HRESULT( 1, _FACD3DXF, 911 ) +#define D3DXFERR_PARSEERROR MAKE_HRESULT( 1, _FACD3DXF, 912 ) +#define D3DXFERR_BADARRAYSIZE MAKE_HRESULT( 1, _FACD3DXF, 913 ) +#define D3DXFERR_BADDATAREFERENCE MAKE_HRESULT( 1, _FACD3DXF, 914 ) +#define D3DXFERR_NOMOREOBJECTS MAKE_HRESULT( 1, _FACD3DXF, 915 ) +#define D3DXFERR_NOMOREDATA MAKE_HRESULT( 1, _FACD3DXF, 916 ) +#define D3DXFERR_BADCACHEFILE MAKE_HRESULT( 1, _FACD3DXF, 917 ) + +/* + * DirectX File object types. + */ + +#ifndef WIN_TYPES +#define WIN_TYPES(itype, ptype) typedef interface itype *LP##ptype, **LPLP##ptype +#endif + +WIN_TYPES(ID3DXFile, D3DXFILE); +WIN_TYPES(ID3DXFileEnumObject, D3DXFILEENUMOBJECT); +WIN_TYPES(ID3DXFileSaveObject, D3DXFILESAVEOBJECT); +WIN_TYPES(ID3DXFileData, D3DXFILEDATA); +WIN_TYPES(ID3DXFileSaveData, D3DXFILESAVEDATA); + +#if defined( __cplusplus ) +} // extern "C" +#endif // defined( __cplusplus ) + +#endif // !defined( __D3DX9XOF_H__ ) + + diff --git a/builddir/irrlicht-1.8.1/include/dimension2d.h b/builddir/irrlicht-1.8.1/include/dimension2d.h new file mode 100644 index 0000000..c9d0652 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/dimension2d.h @@ -0,0 +1,224 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_DIMENSION2D_H_INCLUDED__ +#define __IRR_DIMENSION2D_H_INCLUDED__ + +#include "irrTypes.h" +#include "irrMath.h" // for irr::core::equals() + +namespace irr +{ +namespace core +{ + template <class T> + class vector2d; + + //! Specifies a 2 dimensional size. + template <class T> + class dimension2d + { + public: + //! Default constructor for empty dimension + dimension2d() : Width(0), Height(0) {} + //! Constructor with width and height + dimension2d(const T& width, const T& height) + : Width(width), Height(height) {} + + dimension2d(const vector2d<T>& other); // Defined in vector2d.h + + //! Use this constructor only where you are sure that the conversion is valid. + template <class U> + explicit dimension2d(const dimension2d<U>& other) : + Width((T)other.Width), Height((T)other.Height) { } + + template <class U> + dimension2d<T>& operator=(const dimension2d<U>& other) + { + Width = (T) other.Width; + Height = (T) other.Height; + return *this; + } + + + //! Equality operator + bool operator==(const dimension2d<T>& other) const + { + return core::equals(Width, other.Width) && + core::equals(Height, other.Height); + } + + //! Inequality operator + bool operator!=(const dimension2d<T>& other) const + { + return ! (*this == other); + } + + bool operator==(const vector2d<T>& other) const; // Defined in vector2d.h + + bool operator!=(const vector2d<T>& other) const + { + return !(*this == other); + } + + //! Set to new values + dimension2d<T>& set(const T& width, const T& height) + { + Width = width; + Height = height; + return *this; + } + + //! Divide width and height by scalar + dimension2d<T>& operator/=(const T& scale) + { + Width /= scale; + Height /= scale; + return *this; + } + + //! Divide width and height by scalar + dimension2d<T> operator/(const T& scale) const + { + return dimension2d<T>(Width/scale, Height/scale); + } + + //! Multiply width and height by scalar + dimension2d<T>& operator*=(const T& scale) + { + Width *= scale; + Height *= scale; + return *this; + } + + //! Multiply width and height by scalar + dimension2d<T> operator*(const T& scale) const + { + return dimension2d<T>(Width*scale, Height*scale); + } + + //! Add another dimension to this one. + dimension2d<T>& operator+=(const dimension2d<T>& other) + { + Width += other.Width; + Height += other.Height; + return *this; + } + + //! Add two dimensions + dimension2d<T> operator+(const dimension2d<T>& other) const + { + return dimension2d<T>(Width+other.Width, Height+other.Height); + } + + //! Subtract a dimension from this one + dimension2d<T>& operator-=(const dimension2d<T>& other) + { + Width -= other.Width; + Height -= other.Height; + return *this; + } + + //! Subtract one dimension from another + dimension2d<T> operator-(const dimension2d<T>& other) const + { + return dimension2d<T>(Width-other.Width, Height-other.Height); + } + + //! Get area + T getArea() const + { + return Width*Height; + } + + //! Get the optimal size according to some properties + /** This is a function often used for texture dimension + calculations. The function returns the next larger or + smaller dimension which is a power-of-two dimension + (2^n,2^m) and/or square (Width=Height). + \param requirePowerOfTwo Forces the result to use only + powers of two as values. + \param requireSquare Makes width==height in the result + \param larger Choose whether the result is larger or + smaller than the current dimension. If one dimension + need not be changed it is kept with any value of larger. + \param maxValue Maximum texturesize. if value > 0 size is + clamped to maxValue + \return The optimal dimension under the given + constraints. */ + dimension2d<T> getOptimalSize( + bool requirePowerOfTwo=true, + bool requireSquare=false, + bool larger=true, + u32 maxValue = 0) const + { + u32 i=1; + u32 j=1; + if (requirePowerOfTwo) + { + while (i<(u32)Width) + i<<=1; + if (!larger && i!=1 && i!=(u32)Width) + i>>=1; + while (j<(u32)Height) + j<<=1; + if (!larger && j!=1 && j!=(u32)Height) + j>>=1; + } + else + { + i=(u32)Width; + j=(u32)Height; + } + + if (requireSquare) + { + if ((larger && (i>j)) || (!larger && (i<j))) + j=i; + else + i=j; + } + + if ( maxValue > 0 && i > maxValue) + i = maxValue; + + if ( maxValue > 0 && j > maxValue) + j = maxValue; + + return dimension2d<T>((T)i,(T)j); + } + + //! Get the interpolated dimension + /** \param other Other dimension to interpolate with. + \param d Value between 0.0f and 1.0f. + \return Interpolated dimension. */ + dimension2d<T> getInterpolated(const dimension2d<T>& other, f32 d) const + { + f32 inv = (1.0f - d); + return dimension2d<T>( (T)(other.Width*inv + Width*d), (T)(other.Height*inv + Height*d)); + } + + + //! Width of the dimension. + T Width; + //! Height of the dimension. + T Height; + }; + + //! Typedef for an f32 dimension. + typedef dimension2d<f32> dimension2df; + //! Typedef for an unsigned integer dimension. + typedef dimension2d<u32> dimension2du; + + //! Typedef for an integer dimension. + /** There are few cases where negative dimensions make sense. Please consider using + dimension2du instead. */ + typedef dimension2d<s32> dimension2di; + + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/driverChoice.h b/builddir/irrlicht-1.8.1/include/driverChoice.h new file mode 100644 index 0000000..8f17c38 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/driverChoice.h @@ -0,0 +1,45 @@ +// Copyright (C) 2009-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_DRIVER_CHOICE_H_INCLUDED__ +#define __E_DRIVER_CHOICE_H_INCLUDED__ + +#include <iostream> +#include <cstdio> +#include "EDriverTypes.h" +#include "irrTypes.h" +#include "IrrlichtDevice.h" + +namespace irr +{ + +//! ask user for driver +static irr::video::E_DRIVER_TYPE driverChoiceConsole(bool allDrivers=true) +{ + const char* const names[] = {"NullDriver","Software Renderer","Burning's Video","Direct3D 8.1","Direct3D 9.0c","OpenGL 1.x/2.x/3.x"}; + printf("Please select the driver you want:\n"); + irr::u32 i=0; + for (i=irr::video::EDT_COUNT; i>0; --i) + { + if (allDrivers || (irr::IrrlichtDevice::isDriverSupported(irr::video::E_DRIVER_TYPE(i-1)))) + printf(" (%c) %s\n", 'a'+irr::video::EDT_COUNT-i, names[i-1]); + } + + char c; + std::cin >> c; + c = irr::video::EDT_COUNT+'a'-c; + + for (i=irr::video::EDT_COUNT; i>0; --i) + { + if (!(allDrivers || (irr::IrrlichtDevice::isDriverSupported(irr::video::E_DRIVER_TYPE(i-1))))) + --c; + if ((char)i==c) + return irr::video::E_DRIVER_TYPE(i-1); + } + return irr::video::EDT_COUNT; +} + +} // end namespace irr + +#endif diff --git a/builddir/irrlicht-1.8.1/include/dxfile.h b/builddir/irrlicht-1.8.1/include/dxfile.h new file mode 100644 index 0000000..8b5995a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/dxfile.h @@ -0,0 +1,240 @@ +/*************************************************************************** + * + * Copyright (C) 1998-1999 Microsoft Corporation. All Rights Reserved. + * + * File: dxfile.h + * + * Content: DirectX File public header file + * + ***************************************************************************/ + +#ifndef __DXFILE_H__ +#define __DXFILE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef DWORD DXFILEFORMAT; + +#define DXFILEFORMAT_BINARY 0 +#define DXFILEFORMAT_TEXT 1 +#define DXFILEFORMAT_COMPRESSED 2 + +typedef DWORD DXFILELOADOPTIONS; + +#define DXFILELOAD_FROMFILE 0x00L +#define DXFILELOAD_FROMRESOURCE 0x01L +#define DXFILELOAD_FROMMEMORY 0x02L +#define DXFILELOAD_FROMSTREAM 0x04L +#define DXFILELOAD_FROMURL 0x08L + +typedef struct _DXFILELOADRESOURCE { + HMODULE hModule; + LPCTSTR lpName; + LPCTSTR lpType; +}DXFILELOADRESOURCE, *LPDXFILELOADRESOURCE; + +typedef struct _DXFILELOADMEMORY { + LPVOID lpMemory; + DWORD dSize; +}DXFILELOADMEMORY, *LPDXFILELOADMEMORY; + +/* + * DirectX File object types. + */ + +#ifndef WIN_TYPES +#define WIN_TYPES(itype, ptype) typedef interface itype *LP##ptype, **LPLP##ptype +#endif + +WIN_TYPES(IDirectXFile, DIRECTXFILE); +WIN_TYPES(IDirectXFileEnumObject, DIRECTXFILEENUMOBJECT); +WIN_TYPES(IDirectXFileSaveObject, DIRECTXFILESAVEOBJECT); +WIN_TYPES(IDirectXFileObject, DIRECTXFILEOBJECT); +WIN_TYPES(IDirectXFileData, DIRECTXFILEDATA); +WIN_TYPES(IDirectXFileDataReference, DIRECTXFILEDATAREFERENCE); +WIN_TYPES(IDirectXFileBinary, DIRECTXFILEBINARY); + +/* + * API for creating IDirectXFile interface. + */ + +STDAPI DirectXFileCreate(LPDIRECTXFILE *lplpDirectXFile); + +/* + * The methods for IUnknown + */ + +#define IUNKNOWN_METHODS(kind) \ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObj) kind; \ + STDMETHOD_(ULONG, AddRef) (THIS) kind; \ + STDMETHOD_(ULONG, Release) (THIS) kind + +/* + * The methods for IDirectXFileObject + */ + +#define IDIRECTXFILEOBJECT_METHODS(kind) \ + STDMETHOD(GetName) (THIS_ LPSTR, LPDWORD) kind; \ + STDMETHOD(GetId) (THIS_ LPGUID) kind + +/* + * DirectX File interfaces. + */ + +#undef INTERFACE +#define INTERFACE IDirectXFile + +DECLARE_INTERFACE_(IDirectXFile, IUnknown) +{ + IUNKNOWN_METHODS(PURE); + STDMETHOD(CreateEnumObject) (THIS_ LPVOID, DXFILELOADOPTIONS, + LPDIRECTXFILEENUMOBJECT *) PURE; + STDMETHOD(CreateSaveObject) (THIS_ LPCSTR, DXFILEFORMAT, + LPDIRECTXFILESAVEOBJECT *) PURE; + STDMETHOD(RegisterTemplates) (THIS_ LPVOID, DWORD) PURE; +}; + +#undef INTERFACE +#define INTERFACE IDirectXFileEnumObject + +DECLARE_INTERFACE_(IDirectXFileEnumObject, IUnknown) +{ + IUNKNOWN_METHODS(PURE); + STDMETHOD(GetNextDataObject) (THIS_ LPDIRECTXFILEDATA *) PURE; + STDMETHOD(GetDataObjectById) (THIS_ REFGUID, LPDIRECTXFILEDATA *) PURE; + STDMETHOD(GetDataObjectByName) (THIS_ LPCSTR, LPDIRECTXFILEDATA *) PURE; +}; + +#undef INTERFACE +#define INTERFACE IDirectXFileSaveObject + +DECLARE_INTERFACE_(IDirectXFileSaveObject, IUnknown) +{ + IUNKNOWN_METHODS(PURE); + STDMETHOD(SaveTemplates) (THIS_ DWORD, const GUID **) PURE; + STDMETHOD(CreateDataObject) (THIS_ REFGUID, LPCSTR, const GUID *, + DWORD, LPVOID, LPDIRECTXFILEDATA *) PURE; + STDMETHOD(SaveData) (THIS_ LPDIRECTXFILEDATA) PURE; +}; + + +#undef INTERFACE +#define INTERFACE IDirectXFileObject + +DECLARE_INTERFACE_(IDirectXFileObject, IUnknown) +{ + IUNKNOWN_METHODS(PURE); + IDIRECTXFILEOBJECT_METHODS(PURE); +}; + +#undef INTERFACE +#define INTERFACE IDirectXFileData + +DECLARE_INTERFACE_(IDirectXFileData, IDirectXFileObject) +{ + IUNKNOWN_METHODS(PURE); + IDIRECTXFILEOBJECT_METHODS(PURE); + + STDMETHOD(GetData) (THIS_ LPCSTR, DWORD *, void **) PURE; + STDMETHOD(GetType) (THIS_ const GUID **) PURE; + STDMETHOD(GetNextObject) (THIS_ LPDIRECTXFILEOBJECT *) PURE; + STDMETHOD(AddDataObject) (THIS_ LPDIRECTXFILEDATA) PURE; + STDMETHOD(AddDataReference) (THIS_ LPCSTR, const GUID *) PURE; + STDMETHOD(AddBinaryObject) (THIS_ LPCSTR, const GUID *, LPCSTR, LPVOID, DWORD) PURE; +}; + +#undef INTERFACE +#define INTERFACE IDirectXFileDataReference + +DECLARE_INTERFACE_(IDirectXFileDataReference, IDirectXFileObject) +{ + IUNKNOWN_METHODS(PURE); + IDIRECTXFILEOBJECT_METHODS(PURE); + + STDMETHOD(Resolve) (THIS_ LPDIRECTXFILEDATA *) PURE; +}; + +#undef INTERFACE +#define INTERFACE IDirectXFileBinary + +DECLARE_INTERFACE_(IDirectXFileBinary, IDirectXFileObject) +{ + IUNKNOWN_METHODS(PURE); + IDIRECTXFILEOBJECT_METHODS(PURE); + + STDMETHOD(GetSize) (THIS_ DWORD *) PURE; + STDMETHOD(GetMimeType) (THIS_ LPCSTR *) PURE; + STDMETHOD(Read) (THIS_ LPVOID, DWORD, LPDWORD) PURE; +}; + +/* + * DirectXFile Object Class Id (for CoCreateInstance()) + */ + +DEFINE_GUID(CLSID_CDirectXFile, 0x4516ec43, 0x8f20, 0x11d0, 0x9b, 0x6d, 0x00, 0x00, 0xc0, 0x78, 0x1b, 0xc3); + +/* + * DirectX File Interface GUIDs. + */ + +DEFINE_GUID(IID_IDirectXFile, 0x3d82ab40, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileEnumObject, 0x3d82ab41, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileSaveObject, 0x3d82ab42, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileObject, 0x3d82ab43, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileData, 0x3d82ab44, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileDataReference, 0x3d82ab45, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); +DEFINE_GUID(IID_IDirectXFileBinary, 0x3d82ab46, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + +/* + * DirectX File Header template's GUID. + */ + +DEFINE_GUID(TID_DXFILEHeader, 0x3d82ab43, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33); + + +/* + * DirectX File errors. + */ + +#define _FACDD 0x876 +#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) + +#define DXFILE_OK 0 + +#define DXFILEERR_BADOBJECT MAKE_DDHRESULT(850) +#define DXFILEERR_BADVALUE MAKE_DDHRESULT(851) +#define DXFILEERR_BADTYPE MAKE_DDHRESULT(852) +#define DXFILEERR_BADSTREAMHANDLE MAKE_DDHRESULT(853) +#define DXFILEERR_BADALLOC MAKE_DDHRESULT(854) +#define DXFILEERR_NOTFOUND MAKE_DDHRESULT(855) +#define DXFILEERR_NOTDONEYET MAKE_DDHRESULT(856) +#define DXFILEERR_FILENOTFOUND MAKE_DDHRESULT(857) +#define DXFILEERR_RESOURCENOTFOUND MAKE_DDHRESULT(858) +#define DXFILEERR_URLNOTFOUND MAKE_DDHRESULT(859) +#define DXFILEERR_BADRESOURCE MAKE_DDHRESULT(860) +#define DXFILEERR_BADFILETYPE MAKE_DDHRESULT(861) +#define DXFILEERR_BADFILEVERSION MAKE_DDHRESULT(862) +#define DXFILEERR_BADFILEFLOATSIZE MAKE_DDHRESULT(863) +#define DXFILEERR_BADFILECOMPRESSIONTYPE MAKE_DDHRESULT(864) +#define DXFILEERR_BADFILE MAKE_DDHRESULT(865) +#define DXFILEERR_PARSEERROR MAKE_DDHRESULT(866) +#define DXFILEERR_NOTEMPLATE MAKE_DDHRESULT(867) +#define DXFILEERR_BADARRAYSIZE MAKE_DDHRESULT(868) +#define DXFILEERR_BADDATAREFERENCE MAKE_DDHRESULT(869) +#define DXFILEERR_INTERNALERROR MAKE_DDHRESULT(870) +#define DXFILEERR_NOMOREOBJECTS MAKE_DDHRESULT(871) +#define DXFILEERR_BADINTRINSICS MAKE_DDHRESULT(872) +#define DXFILEERR_NOMORESTREAMHANDLES MAKE_DDHRESULT(873) +#define DXFILEERR_NOMOREDATA MAKE_DDHRESULT(874) +#define DXFILEERR_BADCACHEFILE MAKE_DDHRESULT(875) +#define DXFILEERR_NOINTERNET MAKE_DDHRESULT(876) + + +#ifdef __cplusplus +}; +#endif + +#endif /* _DXFILE_H_ */ + \ No newline at end of file diff --git a/builddir/irrlicht-1.8.1/include/fast_atof.h b/builddir/irrlicht-1.8.1/include/fast_atof.h new file mode 100644 index 0000000..d11f7b4 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/fast_atof.h @@ -0,0 +1,364 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __FAST_ATOF_H_INCLUDED__ +#define __FAST_ATOF_H_INCLUDED__ + +#include "irrMath.h" +#include "irrString.h" + +namespace irr +{ +namespace core +{ + //! Selection of characters which count as decimal point in fast_atof + // TODO: This should probably also be used in irr::core::string, but the float-to-string code + // used there has to be rewritten first. + IRRLICHT_API extern irr::core::stringc LOCALE_DECIMAL_POINTS; + +// we write [17] here instead of [] to work around a swig bug +const float fast_atof_table[17] = { + 0.f, + 0.1f, + 0.01f, + 0.001f, + 0.0001f, + 0.00001f, + 0.000001f, + 0.0000001f, + 0.00000001f, + 0.000000001f, + 0.0000000001f, + 0.00000000001f, + 0.000000000001f, + 0.0000000000001f, + 0.00000000000001f, + 0.000000000000001f, + 0.0000000000000001f +}; + +//! Convert a simple string of base 10 digits into an unsigned 32 bit integer. +/** \param[in] in: The string of digits to convert. No leading chars are + allowed, only digits 0 to 9. Parsing stops at the first non-digit. + \param[out] out: (optional) If provided, it will be set to point at the + first character not used in the calculation. + \return The unsigned integer value of the digits. If the string specifies + too many digits to encode in an u32 then INT_MAX will be returned. +*/ +inline u32 strtoul10(const char* in, const char** out=0) +{ + if (!in) + { + if (out) + *out = in; + return 0; + } + + bool overflow=false; + u32 unsignedValue = 0; + while ( ( *in >= '0') && ( *in <= '9' )) + { + const u32 tmp = ( unsignedValue * 10 ) + ( *in - '0' ); + if (tmp<unsignedValue) + { + unsignedValue=(u32)0xffffffff; + overflow=true; + } + if (!overflow) + unsignedValue = tmp; + ++in; + } + + if (out) + *out = in; + + return unsignedValue; +} + +//! Convert a simple string of base 10 digits into a signed 32 bit integer. +/** \param[in] in: The string of digits to convert. Only a leading - or + + followed by digits 0 to 9 will be considered. Parsing stops at the first + non-digit. + \param[out] out: (optional) If provided, it will be set to point at the + first character not used in the calculation. + \return The signed integer value of the digits. If the string specifies + too many digits to encode in an s32 then +INT_MAX or -INT_MAX will be + returned. +*/ +inline s32 strtol10(const char* in, const char** out=0) +{ + if (!in) + { + if (out) + *out = in; + return 0; + } + + const bool negative = ('-' == *in); + if (negative || ('+' == *in)) + ++in; + + const u32 unsignedValue = strtoul10(in,out); + if (unsignedValue > (u32)INT_MAX) + { + if (negative) + return (s32)INT_MIN; + else + return (s32)INT_MAX; + } + else + { + if (negative) + return -((s32)unsignedValue); + else + return (s32)unsignedValue; + } +} + +//! Convert a hex-encoded character to an unsigned integer. +/** \param[in] in The digit to convert. Only digits 0 to 9 and chars A-F,a-f + will be considered. + \return The unsigned integer value of the digit. 0xffffffff if the input is + not hex +*/ +inline u32 ctoul16(char in) +{ + if (in >= '0' && in <= '9') + return in - '0'; + else if (in >= 'a' && in <= 'f') + return 10u + in - 'a'; + else if (in >= 'A' && in <= 'F') + return 10u + in - 'A'; + else + return 0xffffffff; +} + +//! Convert a simple string of base 16 digits into an unsigned 32 bit integer. +/** \param[in] in: The string of digits to convert. No leading chars are + allowed, only digits 0 to 9 and chars A-F,a-f are allowed. Parsing stops + at the first illegal char. + \param[out] out: (optional) If provided, it will be set to point at the + first character not used in the calculation. + \return The unsigned integer value of the digits. If the string specifies + too many digits to encode in an u32 then INT_MAX will be returned. +*/ +inline u32 strtoul16(const char* in, const char** out=0) +{ + if (!in) + { + if (out) + *out = in; + return 0; + } + + bool overflow=false; + u32 unsignedValue = 0; + while (true) + { + u32 tmp = 0; + if ((*in >= '0') && (*in <= '9')) + tmp = (unsignedValue << 4u) + (*in - '0'); + else if ((*in >= 'A') && (*in <= 'F')) + tmp = (unsignedValue << 4u) + (*in - 'A') + 10; + else if ((*in >= 'a') && (*in <= 'f')) + tmp = (unsignedValue << 4u) + (*in - 'a') + 10; + else + break; + if (tmp<unsignedValue) + { + unsignedValue=(u32)INT_MAX; + overflow=true; + } + if (!overflow) + unsignedValue = tmp; + ++in; + } + + if (out) + *out = in; + + return unsignedValue; +} + +//! Convert a simple string of base 8 digits into an unsigned 32 bit integer. +/** \param[in] in The string of digits to convert. No leading chars are + allowed, only digits 0 to 7 are allowed. Parsing stops at the first illegal + char. + \param[out] out (optional) If provided, it will be set to point at the + first character not used in the calculation. + \return The unsigned integer value of the digits. If the string specifies + too many digits to encode in an u32 then INT_MAX will be returned. +*/ +inline u32 strtoul8(const char* in, const char** out=0) +{ + if (!in) + { + if (out) + *out = in; + return 0; + } + + bool overflow=false; + u32 unsignedValue = 0; + while (true) + { + u32 tmp = 0; + if ((*in >= '0') && (*in <= '7')) + tmp = (unsignedValue << 3u) + (*in - '0'); + else + break; + if (tmp<unsignedValue) + { + unsignedValue=(u32)INT_MAX; + overflow=true; + } + if (!overflow) + unsignedValue = tmp; + ++in; + } + + if (out) + *out = in; + + return unsignedValue; +} + +//! Convert a C-style prefixed string (hex, oct, integer) into an unsigned 32 bit integer. +/** \param[in] in The string of digits to convert. If string starts with 0x the + hex parser is used, if only leading 0 is used, oct parser is used. In all + other cases, the usual unsigned parser is used. + \param[out] out (optional) If provided, it will be set to point at the + first character not used in the calculation. + \return The unsigned integer value of the digits. If the string specifies + too many digits to encode in an u32 then INT_MAX will be returned. +*/ +inline u32 strtoul_prefix(const char* in, const char** out=0) +{ + if (!in) + { + if (out) + *out = in; + return 0; + } + if ('0'==in[0]) + return ('x'==in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out)); + return strtoul10(in,out); +} + +//! Converts a sequence of digits into a whole positive floating point value. +/** Only digits 0 to 9 are parsed. Parsing stops at any other character, + including sign characters or a decimal point. + \param in: the sequence of digits to convert. + \param out: (optional) will be set to point at the first non-converted + character. + \return The whole positive floating point representation of the digit + sequence. +*/ +inline f32 strtof10(const char* in, const char** out = 0) +{ + if (!in) + { + if (out) + *out = in; + return 0.f; + } + + const u32 MAX_SAFE_U32_VALUE = UINT_MAX / 10 - 10; + u32 intValue = 0; + + // Use integer arithmetic for as long as possible, for speed + // and precision. + while ( ( *in >= '0') && ( *in <= '9' ) ) + { + // If it looks like we're going to overflow, bail out + // now and start using floating point. + if (intValue >= MAX_SAFE_U32_VALUE) + break; + + intValue = (intValue * 10) + (*in - '0'); + ++in; + } + + f32 floatValue = (f32)intValue; + + // If there are any digits left to parse, then we need to use + // floating point arithmetic from here. + while ( ( *in >= '0') && ( *in <= '9' ) ) + { + floatValue = (floatValue * 10.f) + (f32)(*in - '0'); + ++in; + if (floatValue > FLT_MAX) // Just give up. + break; + } + + if (out) + *out = in; + + return floatValue; +} + +//! Provides a fast function for converting a string into a float. +/** This is not guaranteed to be as accurate as atof(), but is + approximately 6 to 8 times as fast. + \param[in] in The string to convert. + \param[out] result The resultant float will be written here. + \return Pointer to the first character in the string that wasn't used + to create the float value. +*/ +inline const char* fast_atof_move(const char* in, f32& result) +{ + // Please run the regression test when making any modifications to this function. + + result = 0.f; + if (!in) + return 0; + + const bool negative = ('-' == *in); + if (negative || ('+'==*in)) + ++in; + + f32 value = strtof10(in, &in); + + if ( LOCALE_DECIMAL_POINTS.findFirst(*in) >= 0 ) + { + const char* afterDecimal = ++in; + const f32 decimal = strtof10(in, &afterDecimal); + value += decimal * fast_atof_table[afterDecimal - in]; + in = afterDecimal; + } + + if ('e' == *in || 'E' == *in) + { + ++in; + // Assume that the exponent is a whole number. + // strtol10() will deal with both + and - signs, + // but calculate as f32 to prevent overflow at FLT_MAX + value *= powf(10.f, (f32)strtol10(in, &in)); + } + + result = negative?-value:value; + return in; +} + +//! Convert a string to a floating point number +/** \param floatAsString The string to convert. + \param out Optional pointer to the first character in the string that + wasn't used to create the float value. + \result Float value parsed from the input string +*/ +inline float fast_atof(const char* floatAsString, const char** out=0) +{ + float ret; + if (out) + *out=fast_atof_move(floatAsString, ret); + else + fast_atof_move(floatAsString, ret); + return ret; +} + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/heapsort.h b/builddir/irrlicht-1.8.1/include/heapsort.h new file mode 100644 index 0000000..a2e2c38 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/heapsort.h @@ -0,0 +1,70 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_HEAPSORT_H_INCLUDED__ +#define __IRR_HEAPSORT_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace core +{ + +//! Sinks an element into the heap. +template<class T> +inline void heapsink(T*array, s32 element, s32 max) +{ + while ((element<<1) < max) // there is a left child + { + s32 j = (element<<1); + + if (j+1 < max && array[j] < array[j+1]) + j = j+1; // take right child + + if (array[element] < array[j]) + { + T t = array[j]; // swap elements + array[j] = array[element]; + array[element] = t; + element = j; + } + else + return; + } +} + + +//! Sorts an array with size 'size' using heapsort. +template<class T> +inline void heapsort(T* array_, s32 size) +{ + // for heapsink we pretent this is not c++, where + // arrays start with index 0. So we decrease the array pointer, + // the maximum always +2 and the element always +1 + + T* virtualArray = array_ - 1; + s32 virtualSize = size + 2; + s32 i; + + // build heap + + for (i=((size-1)/2); i>=0; --i) + heapsink(virtualArray, i+1, virtualSize-1); + + // sort array, leave out the last element (0) + for (i=size-1; i>0; --i) + { + T t = array_[0]; + array_[0] = array_[i]; + array_[i] = t; + heapsink(virtualArray, 1, i + 1); + } +} + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/irrAllocator.h b/builddir/irrlicht-1.8.1/include/irrAllocator.h new file mode 100644 index 0000000..8a80359 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/irrAllocator.h @@ -0,0 +1,124 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __IRR_ALLOCATOR_H_INCLUDED__ +#define __IRR_ALLOCATOR_H_INCLUDED__ + +#include "irrTypes.h" +#include <new> +// necessary for older compilers +#include <memory.h> + +namespace irr +{ +namespace core +{ + +#ifdef DEBUG_CLIENTBLOCK +#undef DEBUG_CLIENTBLOCK +#define DEBUG_CLIENTBLOCK new +#endif + +//! Very simple allocator implementation, containers using it can be used across dll boundaries +template<typename T> +class irrAllocator +{ +public: + + //! Destructor + virtual ~irrAllocator() {} + + //! Allocate memory for an array of objects + T* allocate(size_t cnt) + { + return (T*)internal_new(cnt* sizeof(T)); + } + + //! Deallocate memory for an array of objects + void deallocate(T* ptr) + { + internal_delete(ptr); + } + + //! Construct an element + void construct(T* ptr, const T&e) + { + new ((void*)ptr) T(e); + } + + //! Destruct an element + void destruct(T* ptr) + { + ptr->~T(); + } + +protected: + + virtual void* internal_new(size_t cnt) + { + return operator new(cnt); + } + + virtual void internal_delete(void* ptr) + { + operator delete(ptr); + } + +}; + + +//! Fast allocator, only to be used in containers inside the same memory heap. +/** Containers using it are NOT able to be used it across dll boundaries. Use this +when using in an internal class or function or when compiled into a static lib */ +template<typename T> +class irrAllocatorFast +{ +public: + + //! Allocate memory for an array of objects + T* allocate(size_t cnt) + { + return (T*)operator new(cnt* sizeof(T)); + } + + //! Deallocate memory for an array of objects + void deallocate(T* ptr) + { + operator delete(ptr); + } + + //! Construct an element + void construct(T* ptr, const T&e) + { + new ((void*)ptr) T(e); + } + + //! Destruct an element + void destruct(T* ptr) + { + ptr->~T(); + } +}; + + + +#ifdef DEBUG_CLIENTBLOCK +#undef DEBUG_CLIENTBLOCK +#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) +#endif + +//! defines an allocation strategy +enum eAllocStrategy +{ + ALLOC_STRATEGY_SAFE = 0, + ALLOC_STRATEGY_DOUBLE = 1, + ALLOC_STRATEGY_SQRT = 2 +}; + + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/irrArray.h b/builddir/irrlicht-1.8.1/include/irrArray.h new file mode 100644 index 0000000..f9d338d --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/irrArray.h @@ -0,0 +1,627 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __IRR_ARRAY_H_INCLUDED__ +#define __IRR_ARRAY_H_INCLUDED__ + +#include "irrTypes.h" +#include "heapsort.h" +#include "irrAllocator.h" +#include "irrMath.h" + +namespace irr +{ +namespace core +{ + +//! Self reallocating template array (like stl vector) with additional features. +/** Some features are: Heap sorting, binary search methods, easier debugging. +*/ +template <class T, typename TAlloc = irrAllocator<T> > +class array +{ + +public: + + //! Default constructor for empty array. + array() + : data(0), allocated(0), used(0), + strategy(ALLOC_STRATEGY_DOUBLE), free_when_destroyed(true), is_sorted(true) + { + } + + + //! Constructs an array and allocates an initial chunk of memory. + /** \param start_count Amount of elements to pre-allocate. */ + array(u32 start_count) + : data(0), allocated(0), used(0), + strategy(ALLOC_STRATEGY_DOUBLE), free_when_destroyed(true), is_sorted(true) + { + reallocate(start_count); + } + + + //! Copy constructor + array(const array<T, TAlloc>& other) : data(0) + { + *this = other; + } + + + //! Destructor. + /** Frees allocated memory, if set_free_when_destroyed was not set to + false by the user before. */ + ~array() + { + clear(); + } + + + //! Reallocates the array, make it bigger or smaller. + /** \param new_size New size of array. + \param canShrink Specifies whether the array is reallocated even if + enough space is available. Setting this flag to false can speed up + array usage, but may use more memory than required by the data. + */ + void reallocate(u32 new_size, bool canShrink=true) + { + if (allocated==new_size) + return; + if (!canShrink && (new_size < allocated)) + return; + + T* old_data = data; + + data = allocator.allocate(new_size); //new T[new_size]; + allocated = new_size; + + // copy old data + s32 end = used < new_size ? used : new_size; + + for (s32 i=0; i<end; ++i) + { + // data[i] = old_data[i]; + allocator.construct(&data[i], old_data[i]); + } + + // destruct old data + for (u32 j=0; j<used; ++j) + allocator.destruct(&old_data[j]); + + if (allocated < used) + used = allocated; + + allocator.deallocate(old_data); //delete [] old_data; + } + + + //! set a new allocation strategy + /** if the maximum size of the array is unknown, you can define how big the + allocation should happen. + \param newStrategy New strategy to apply to this array. */ + void setAllocStrategy ( eAllocStrategy newStrategy = ALLOC_STRATEGY_DOUBLE ) + { + strategy = newStrategy; + } + + + //! Adds an element at back of array. + /** If the array is too small to add this new element it is made bigger. + \param element: Element to add at the back of the array. */ + void push_back(const T& element) + { + insert(element, used); + } + + + //! Adds an element at the front of the array. + /** If the array is to small to add this new element, the array is + made bigger. Please note that this is slow, because the whole array + needs to be copied for this. + \param element Element to add at the back of the array. */ + void push_front(const T& element) + { + insert(element); + } + + + //! Insert item into array at specified position. + /** Please use this only if you know what you are doing (possible + performance loss). The preferred method of adding elements should be + push_back(). + \param element: Element to be inserted + \param index: Where position to insert the new element. */ + void insert(const T& element, u32 index=0) + { + _IRR_DEBUG_BREAK_IF(index>used) // access violation + + if (used + 1 > allocated) + { + // this doesn't work if the element is in the same + // array. So we'll copy the element first to be sure + // we'll get no data corruption + const T e(element); + + // increase data block + u32 newAlloc; + switch ( strategy ) + { + case ALLOC_STRATEGY_DOUBLE: + newAlloc = used + 1 + (allocated < 500 ? + (allocated < 5 ? 5 : used) : used >> 2); + break; + default: + case ALLOC_STRATEGY_SAFE: + newAlloc = used + 1; + break; + } + reallocate( newAlloc); + + // move array content and construct new element + // first move end one up + for (u32 i=used; i>index; --i) + { + if (i<used) + allocator.destruct(&data[i]); + allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1]; + } + // then add new element + if (used > index) + allocator.destruct(&data[index]); + allocator.construct(&data[index], e); // data[index] = e; + } + else + { + // element inserted not at end + if ( used > index ) + { + // create one new element at the end + allocator.construct(&data[used], data[used-1]); + + // move the rest of the array content + for (u32 i=used-1; i>index; --i) + { + data[i] = data[i-1]; + } + // insert the new element + data[index] = element; + } + else + { + // insert the new element to the end + allocator.construct(&data[index], element); + } + } + // set to false as we don't know if we have the comparison operators + is_sorted = false; + ++used; + } + + + //! Clears the array and deletes all allocated memory. + void clear() + { + if (free_when_destroyed) + { + for (u32 i=0; i<used; ++i) + allocator.destruct(&data[i]); + + allocator.deallocate(data); // delete [] data; + } + data = 0; + used = 0; + allocated = 0; + is_sorted = true; + } + + + //! Sets pointer to new array, using this as new workspace. + /** Make sure that set_free_when_destroyed is used properly. + \param newPointer: Pointer to new array of elements. + \param size: Size of the new array. + \param _is_sorted Flag which tells whether the new array is already + sorted. + \param _free_when_destroyed Sets whether the new memory area shall be + freed by the array upon destruction, or if this will be up to the user + application. */ + void set_pointer(T* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true) + { + clear(); + data = newPointer; + allocated = size; + used = size; + is_sorted = _is_sorted; + free_when_destroyed=_free_when_destroyed; + } + + + //! Sets if the array should delete the memory it uses upon destruction. + /** Also clear and set_pointer will only delete the (original) memory + area if this flag is set to true, which is also the default. The + methods reallocate, set_used, push_back, push_front, insert, and erase + will still try to deallocate the original memory, which might cause + troubles depending on the intended use of the memory area. + \param f If true, the array frees the allocated memory in its + destructor, otherwise not. The default is true. */ + void set_free_when_destroyed(bool f) + { + free_when_destroyed = f; + } + + + //! Sets the size of the array and allocates new elements if necessary. + /** Please note: This is only secure when using it with simple types, + because no default constructor will be called for the added elements. + \param usedNow Amount of elements now used. */ + void set_used(u32 usedNow) + { + if (allocated < usedNow) + reallocate(usedNow); + + used = usedNow; + } + + + //! Assignment operator + const array<T, TAlloc>& operator=(const array<T, TAlloc>& other) + { + if (this == &other) + return *this; + strategy = other.strategy; + + if (data) + clear(); + + //if (allocated < other.allocated) + if (other.allocated == 0) + data = 0; + else + data = allocator.allocate(other.allocated); // new T[other.allocated]; + + used = other.used; + free_when_destroyed = true; + is_sorted = other.is_sorted; + allocated = other.allocated; + + for (u32 i=0; i<other.used; ++i) + allocator.construct(&data[i], other.data[i]); // data[i] = other.data[i]; + + return *this; + } + + + //! Equality operator + bool operator == (const array<T, TAlloc>& other) const + { + if (used != other.used) + return false; + + for (u32 i=0; i<other.used; ++i) + if (data[i] != other[i]) + return false; + return true; + } + + + //! Inequality operator + bool operator != (const array<T, TAlloc>& other) const + { + return !(*this==other); + } + + + //! Direct access operator + T& operator [](u32 index) + { + _IRR_DEBUG_BREAK_IF(index>=used) // access violation + + return data[index]; + } + + + //! Direct const access operator + const T& operator [](u32 index) const + { + _IRR_DEBUG_BREAK_IF(index>=used) // access violation + + return data[index]; + } + + + //! Gets last element. + T& getLast() + { + _IRR_DEBUG_BREAK_IF(!used) // access violation + + return data[used-1]; + } + + + //! Gets last element + const T& getLast() const + { + _IRR_DEBUG_BREAK_IF(!used) // access violation + + return data[used-1]; + } + + + //! Gets a pointer to the array. + /** \return Pointer to the array. */ + T* pointer() + { + return data; + } + + + //! Gets a const pointer to the array. + /** \return Pointer to the array. */ + const T* const_pointer() const + { + return data; + } + + + //! Get number of occupied elements of the array. + /** \return Size of elements in the array which are actually occupied. */ + u32 size() const + { + return used; + } + + + //! Get amount of memory allocated. + /** \return Amount of memory allocated. The amount of bytes + allocated would be allocated_size() * sizeof(ElementTypeUsed); */ + u32 allocated_size() const + { + return allocated; + } + + + //! Check if array is empty. + /** \return True if the array is empty false if not. */ + bool empty() const + { + return used == 0; + } + + + //! Sorts the array using heapsort. + /** There is no additional memory waste and the algorithm performs + O(n*log n) in worst case. */ + void sort() + { + if (!is_sorted && used>1) + heapsort(data, used); + is_sorted = true; + } + + + //! Performs a binary search for an element, returns -1 if not found. + /** The array will be sorted before the binary search if it is not + already sorted. Caution is advised! Be careful not to call this on + unsorted const arrays, or the slower method will be used. + \param element Element to search for. + \return Position of the searched element if it was found, + otherwise -1 is returned. */ + s32 binary_search(const T& element) + { + sort(); + return binary_search(element, 0, used-1); + } + + + //! Performs a binary search for an element if possible, returns -1 if not found. + /** This method is for const arrays and so cannot call sort(), if the array is + not sorted then linear_search will be used instead. Potentially very slow! + \param element Element to search for. + \return Position of the searched element if it was found, + otherwise -1 is returned. */ + s32 binary_search(const T& element) const + { + if (is_sorted) + return binary_search(element, 0, used-1); + else + return linear_search(element); + } + + + //! Performs a binary search for an element, returns -1 if not found. + /** \param element: Element to search for. + \param left First left index + \param right Last right index. + \return Position of the searched element if it was found, otherwise -1 + is returned. */ + s32 binary_search(const T& element, s32 left, s32 right) const + { + if (!used) + return -1; + + s32 m; + + do + { + m = (left+right)>>1; + + if (element < data[m]) + right = m - 1; + else + left = m + 1; + + } while((element < data[m] || data[m] < element) && left<=right); + // this last line equals to: + // " while((element != array[m]) && left<=right);" + // but we only want to use the '<' operator. + // the same in next line, it is "(element == array[m])" + + + if (!(element < data[m]) && !(data[m] < element)) + return m; + + return -1; + } + + + //! Performs a binary search for an element, returns -1 if not found. + //! it is used for searching a multiset + /** The array will be sorted before the binary search if it is not + already sorted. + \param element Element to search for. + \param &last return lastIndex of equal elements + \return Position of the first searched element if it was found, + otherwise -1 is returned. */ + s32 binary_search_multi(const T& element, s32 &last) + { + sort(); + s32 index = binary_search(element, 0, used-1); + if ( index < 0 ) + return index; + + // The search can be somewhere in the middle of the set + // look linear previous and past the index + last = index; + + while ( index > 0 && !(element < data[index - 1]) && !(data[index - 1] < element) ) + { + index -= 1; + } + // look linear up + while ( last < (s32) used - 1 && !(element < data[last + 1]) && !(data[last + 1] < element) ) + { + last += 1; + } + + return index; + } + + + //! Finds an element in linear time, which is very slow. + /** Use binary_search for faster finding. Only works if ==operator is + implemented. + \param element Element to search for. + \return Position of the searched element if it was found, otherwise -1 + is returned. */ + s32 linear_search(const T& element) const + { + for (u32 i=0; i<used; ++i) + if (element == data[i]) + return (s32)i; + + return -1; + } + + + //! Finds an element in linear time, which is very slow. + /** Use binary_search for faster finding. Only works if ==operator is + implemented. + \param element: Element to search for. + \return Position of the searched element if it was found, otherwise -1 + is returned. */ + s32 linear_reverse_search(const T& element) const + { + for (s32 i=used-1; i>=0; --i) + if (data[i] == element) + return i; + + return -1; + } + + + //! Erases an element from the array. + /** May be slow, because all elements following after the erased + element have to be copied. + \param index: Index of element to be erased. */ + void erase(u32 index) + { + _IRR_DEBUG_BREAK_IF(index>=used) // access violation + + for (u32 i=index+1; i<used; ++i) + { + allocator.destruct(&data[i-1]); + allocator.construct(&data[i-1], data[i]); // data[i-1] = data[i]; + } + + allocator.destruct(&data[used-1]); + + --used; + } + + + //! Erases some elements from the array. + /** May be slow, because all elements following after the erased + element have to be copied. + \param index: Index of the first element to be erased. + \param count: Amount of elements to be erased. */ + void erase(u32 index, s32 count) + { + if (index>=used || count<1) + return; + if (index+count>used) + count = used-index; + + u32 i; + for (i=index; i<index+count; ++i) + allocator.destruct(&data[i]); + + for (i=index+count; i<used; ++i) + { + if (i-count >= index+count) // not already destructed before loop + allocator.destruct(&data[i-count]); + + allocator.construct(&data[i-count], data[i]); // data[i-count] = data[i]; + + if (i >= used-count) // those which are not overwritten + allocator.destruct(&data[i]); + } + + used-= count; + } + + + //! Sets if the array is sorted + void set_sorted(bool _is_sorted) + { + is_sorted = _is_sorted; + } + + + //! Swap the content of this array container with the content of another array + /** Afterwards this object will contain the content of the other object and the other + object will contain the content of this object. + \param other Swap content with this object */ + void swap(array<T, TAlloc>& other) + { + core::swap(data, other.data); + core::swap(allocated, other.allocated); + core::swap(used, other.used); + core::swap(allocator, other.allocator); // memory is still released by the same allocator used for allocation + eAllocStrategy helper_strategy(strategy); // can't use core::swap with bitfields + strategy = other.strategy; + other.strategy = helper_strategy; + bool helper_free_when_destroyed(free_when_destroyed); + free_when_destroyed = other.free_when_destroyed; + other.free_when_destroyed = helper_free_when_destroyed; + bool helper_is_sorted(is_sorted); + is_sorted = other.is_sorted; + other.is_sorted = helper_is_sorted; + } + + +private: + T* data; + u32 allocated; + u32 used; + TAlloc allocator; + eAllocStrategy strategy:4; + bool free_when_destroyed:1; + bool is_sorted:1; +}; + + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/irrList.h b/builddir/irrlicht-1.8.1/include/irrList.h new file mode 100644 index 0000000..a84afd5 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/irrList.h @@ -0,0 +1,416 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_LIST_H_INCLUDED__ +#define __IRR_LIST_H_INCLUDED__ + +#include "irrTypes.h" +#include "irrAllocator.h" +#include "irrMath.h" + +namespace irr +{ +namespace core +{ + + +//! Doubly linked list template. +template <class T> +class list +{ +private: + + //! List element node with pointer to previous and next element in the list. + struct SKListNode + { + SKListNode(const T& e) : Next(0), Prev(0), Element(e) {} + + SKListNode* Next; + SKListNode* Prev; + T Element; + }; + +public: + class ConstIterator; + + //! List iterator. + class Iterator + { + public: + Iterator() : Current(0) {} + + Iterator& operator ++() { Current = Current->Next; return *this; } + Iterator& operator --() { Current = Current->Prev; return *this; } + Iterator operator ++(s32) { Iterator tmp = *this; Current = Current->Next; return tmp; } + Iterator operator --(s32) { Iterator tmp = *this; Current = Current->Prev; return tmp; } + + Iterator& operator +=(s32 num) + { + if(num > 0) + { + while (num-- && this->Current != 0) ++(*this); + } + else + { + while(num++ && this->Current != 0) --(*this); + } + return *this; + } + + Iterator operator + (s32 num) const { Iterator tmp = *this; return tmp += num; } + Iterator& operator -=(s32 num) { return (*this)+=(-num); } + Iterator operator - (s32 num) const { return (*this)+ (-num); } + + bool operator ==(const Iterator& other) const { return Current == other.Current; } + bool operator !=(const Iterator& other) const { return Current != other.Current; } + bool operator ==(const ConstIterator& other) const { return Current == other.Current; } + bool operator !=(const ConstIterator& other) const { return Current != other.Current; } + + #if defined (_MSC_VER) && (_MSC_VER < 1300) + #pragma warning(disable:4284) // infix notation problem when using iterator operator -> + #endif + + T & operator * () { return Current->Element; } + T * operator ->() { return &Current->Element; } + + private: + explicit Iterator(SKListNode* begin) : Current(begin) {} + + SKListNode* Current; + + friend class list<T>; + friend class ConstIterator; + }; + + //! List iterator for const access. + class ConstIterator + { + public: + + ConstIterator() : Current(0) {} + ConstIterator(const Iterator& iter) : Current(iter.Current) {} + + ConstIterator& operator ++() { Current = Current->Next; return *this; } + ConstIterator& operator --() { Current = Current->Prev; return *this; } + ConstIterator operator ++(s32) { ConstIterator tmp = *this; Current = Current->Next; return tmp; } + ConstIterator operator --(s32) { ConstIterator tmp = *this; Current = Current->Prev; return tmp; } + + ConstIterator& operator +=(s32 num) + { + if(num > 0) + { + while(num-- && this->Current != 0) ++(*this); + } + else + { + while(num++ && this->Current != 0) --(*this); + } + return *this; + } + + ConstIterator operator + (s32 num) const { ConstIterator tmp = *this; return tmp += num; } + ConstIterator& operator -=(s32 num) { return (*this)+=(-num); } + ConstIterator operator - (s32 num) const { return (*this)+ (-num); } + + bool operator ==(const ConstIterator& other) const { return Current == other.Current; } + bool operator !=(const ConstIterator& other) const { return Current != other.Current; } + bool operator ==(const Iterator& other) const { return Current == other.Current; } + bool operator !=(const Iterator& other) const { return Current != other.Current; } + + const T & operator * () { return Current->Element; } + const T * operator ->() { return &Current->Element; } + + ConstIterator & operator =(const Iterator & iterator) { Current = iterator.Current; return *this; } + + private: + explicit ConstIterator(SKListNode* begin) : Current(begin) {} + + SKListNode* Current; + + friend class Iterator; + friend class list<T>; + }; + + //! Default constructor for empty list. + list() + : First(0), Last(0), Size(0) {} + + + //! Copy constructor. + list(const list<T>& other) : First(0), Last(0), Size(0) + { + *this = other; + } + + + //! Destructor + ~list() + { + clear(); + } + + + //! Assignment operator + void operator=(const list<T>& other) + { + if(&other == this) + { + return; + } + + clear(); + + SKListNode* node = other.First; + while(node) + { + push_back(node->Element); + node = node->Next; + } + } + + + //! Returns amount of elements in list. + /** \return Amount of elements in the list. */ + u32 size() const + { + return Size; + } + u32 getSize() const + { + return Size; + } + + + //! Clears the list, deletes all elements in the list. + /** All existing iterators of this list will be invalid. */ + void clear() + { + while(First) + { + SKListNode * next = First->Next; + allocator.destruct(First); + allocator.deallocate(First); + First = next; + } + + //First = 0; handled by loop + Last = 0; + Size = 0; + } + + + //! Checks for empty list. + /** \return True if the list is empty and false if not. */ + bool empty() const + { + return (First == 0); + } + + + //! Adds an element at the end of the list. + /** \param element Element to add to the list. */ + void push_back(const T& element) + { + SKListNode* node = allocator.allocate(1); + allocator.construct(node, element); + + ++Size; + + if (First == 0) + First = node; + + node->Prev = Last; + + if (Last != 0) + Last->Next = node; + + Last = node; + } + + + //! Adds an element at the begin of the list. + /** \param element: Element to add to the list. */ + void push_front(const T& element) + { + SKListNode* node = allocator.allocate(1); + allocator.construct(node, element); + + ++Size; + + if (First == 0) + { + Last = node; + First = node; + } + else + { + node->Next = First; + First->Prev = node; + First = node; + } + } + + + //! Gets first node. + /** \return A list iterator pointing to the beginning of the list. */ + Iterator begin() + { + return Iterator(First); + } + + + //! Gets first node. + /** \return A const list iterator pointing to the beginning of the list. */ + ConstIterator begin() const + { + return ConstIterator(First); + } + + + //! Gets end node. + /** \return List iterator pointing to null. */ + Iterator end() + { + return Iterator(0); + } + + + //! Gets end node. + /** \return Const list iterator pointing to null. */ + ConstIterator end() const + { + return ConstIterator(0); + } + + + //! Gets last element. + /** \return List iterator pointing to the last element of the list. */ + Iterator getLast() + { + return Iterator(Last); + } + + + //! Gets last element. + /** \return Const list iterator pointing to the last element of the list. */ + ConstIterator getLast() const + { + return ConstIterator(Last); + } + + + //! Inserts an element after an element. + /** \param it Iterator pointing to element after which the new element + should be inserted. + \param element The new element to be inserted into the list. + */ + void insert_after(const Iterator& it, const T& element) + { + SKListNode* node = allocator.allocate(1); + allocator.construct(node, element); + + node->Next = it.Current->Next; + + if (it.Current->Next) + it.Current->Next->Prev = node; + + node->Prev = it.Current; + it.Current->Next = node; + ++Size; + + if (it.Current == Last) + Last = node; + } + + + //! Inserts an element before an element. + /** \param it Iterator pointing to element before which the new element + should be inserted. + \param element The new element to be inserted into the list. + */ + void insert_before(const Iterator& it, const T& element) + { + SKListNode* node = allocator.allocate(1); + allocator.construct(node, element); + + node->Prev = it.Current->Prev; + + if (it.Current->Prev) + it.Current->Prev->Next = node; + + node->Next = it.Current; + it.Current->Prev = node; + ++Size; + + if (it.Current == First) + First = node; + } + + + //! Erases an element. + /** \param it Iterator pointing to the element which shall be erased. + \return Iterator pointing to next element. */ + Iterator erase(Iterator& it) + { + // suggest changing this to a const Iterator& and + // working around line: it.Current = 0 (possibly with a mutable, or just let it be garbage?) + + Iterator returnIterator(it); + ++returnIterator; + + if(it.Current == First) + { + First = it.Current->Next; + } + else + { + it.Current->Prev->Next = it.Current->Next; + } + + if(it.Current == Last) + { + Last = it.Current->Prev; + } + else + { + it.Current->Next->Prev = it.Current->Prev; + } + + allocator.destruct(it.Current); + allocator.deallocate(it.Current); + it.Current = 0; + --Size; + + return returnIterator; + } + + //! Swap the content of this list container with the content of another list + /** Afterwards this object will contain the content of the other object and the other + object will contain the content of this object. Iterators will afterwards be valid for + the swapped object. + \param other Swap content with this object */ + void swap(list<T>& other) + { + core::swap(First, other.First); + core::swap(Last, other.Last); + core::swap(Size, other.Size); + core::swap(allocator, other.allocator); // memory is still released by the same allocator used for allocation + } + + +private: + + SKListNode* First; + SKListNode* Last; + u32 Size; + irrAllocator<SKListNode> allocator; + +}; + + +} // end namespace core +}// end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/irrMap.h b/builddir/irrlicht-1.8.1/include/irrMap.h new file mode 100644 index 0000000..6e15174 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/irrMap.h @@ -0,0 +1,1127 @@ +// Copyright (C) 2006-2012 by Kat'Oun +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_MAP_H_INCLUDED__ +#define __IRR_MAP_H_INCLUDED__ + +#include "irrTypes.h" +#include "irrMath.h" + +namespace irr +{ +namespace core +{ + +//! map template for associative arrays using a red-black tree +template <class KeyType, class ValueType> +class map +{ + //! red/black tree for map + template <class KeyTypeRB, class ValueTypeRB> + class RBTree + { + public: + + RBTree(const KeyTypeRB& k, const ValueTypeRB& v) + : LeftChild(0), RightChild(0), Parent(0), Key(k), + Value(v), IsRed(true) {} + + void setLeftChild(RBTree* p) + { + LeftChild=p; + if (p) + p->setParent(this); + } + + void setRightChild(RBTree* p) + { + RightChild=p; + if (p) + p->setParent(this); + } + + void setParent(RBTree* p) { Parent=p; } + + void setValue(const ValueTypeRB& v) { Value = v; } + + void setRed() { IsRed = true; } + void setBlack() { IsRed = false; } + + RBTree* getLeftChild() const { return LeftChild; } + RBTree* getRightChild() const { return RightChild; } + RBTree* getParent() const { return Parent; } + + const ValueTypeRB& getValue() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Value; + } + + ValueTypeRB& getValue() + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Value; + } + + const KeyTypeRB& getKey() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Key; + } + + bool isRoot() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Parent==0; + } + + bool isLeftChild() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return (Parent != 0) && (Parent->getLeftChild()==this); + } + + bool isRightChild() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return (Parent!=0) && (Parent->getRightChild()==this); + } + + bool isLeaf() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return (LeftChild==0) && (RightChild==0); + } + + unsigned int getLevel() const + { + if (isRoot()) + return 1; + else + return getParent()->getLevel() + 1; + } + + + bool isRed() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsRed; + } + + bool isBlack() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return !IsRed; + } + + private: + RBTree(); + + RBTree* LeftChild; + RBTree* RightChild; + + RBTree* Parent; + + KeyTypeRB Key; + ValueTypeRB Value; + + bool IsRed; + }; // RBTree + + public: + + typedef RBTree<KeyType,ValueType> Node; + // We need the forwad declaration for the friend declaration + class ConstIterator; + + //! Normal Iterator + class Iterator + { + friend class ConstIterator; + public: + + Iterator() : Root(0), Cur(0) {} + + // Constructor(Node*) + Iterator(Node* root) : Root(root) + { + reset(); + } + + // Copy constructor + Iterator(const Iterator& src) : Root(src.Root), Cur(src.Cur) {} + + void reset(bool atLowest=true) + { + if (atLowest) + Cur = getMin(Root); + else + Cur = getMax(Root); + } + + bool atEnd() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Cur==0; + } + + Node* getNode() const + { + return Cur; + } + + Iterator& operator=(const Iterator& src) + { + Root = src.Root; + Cur = src.Cur; + return (*this); + } + + void operator++(int) + { + inc(); + } + + void operator--(int) + { + dec(); + } + + Node* operator->() + { + return getNode(); + } + + Node& operator*() + { + _IRR_DEBUG_BREAK_IF(atEnd()) // access violation + + return *Cur; + } + + private: + + Node* getMin(Node* n) const + { + while(n && n->getLeftChild()) + n = n->getLeftChild(); + return n; + } + + Node* getMax(Node* n) const + { + while(n && n->getRightChild()) + n = n->getRightChild(); + return n; + } + + void inc() + { + // Already at end? + if (Cur==0) + return; + + if (Cur->getRightChild()) + { + // If current node has a right child, the next higher node is the + // node with lowest key beneath the right child. + Cur = getMin(Cur->getRightChild()); + } + else if (Cur->isLeftChild()) + { + // No right child? Well if current node is a left child then + // the next higher node is the parent + Cur = Cur->getParent(); + } + else + { + // Current node neither is left child nor has a right child. + // Ie it is either right child or root + // The next higher node is the parent of the first non-right + // child (ie either a left child or the root) up in the + // hierarchy. Root's parent is 0. + while(Cur->isRightChild()) + Cur = Cur->getParent(); + Cur = Cur->getParent(); + } + } + + void dec() + { + // Already at end? + if (Cur==0) + return; + + if (Cur->getLeftChild()) + { + // If current node has a left child, the next lower node is the + // node with highest key beneath the left child. + Cur = getMax(Cur->getLeftChild()); + } + else if (Cur->isRightChild()) + { + // No left child? Well if current node is a right child then + // the next lower node is the parent + Cur = Cur->getParent(); + } + else + { + // Current node neither is right child nor has a left child. + // Ie it is either left child or root + // The next higher node is the parent of the first non-left + // child (ie either a right child or the root) up in the + // hierarchy. Root's parent is 0. + + while(Cur->isLeftChild()) + Cur = Cur->getParent(); + Cur = Cur->getParent(); + } + } + + Node* Root; + Node* Cur; + }; // Iterator + + //! Const Iterator + class ConstIterator + { + friend class Iterator; + public: + + ConstIterator() : Root(0), Cur(0) {} + + // Constructor(Node*) + ConstIterator(const Node* root) : Root(root) + { + reset(); + } + + // Copy constructor + ConstIterator(const ConstIterator& src) : Root(src.Root), Cur(src.Cur) {} + ConstIterator(const Iterator& src) : Root(src.Root), Cur(src.Cur) {} + + void reset(bool atLowest=true) + { + if (atLowest) + Cur = getMin(Root); + else + Cur = getMax(Root); + } + + bool atEnd() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Cur==0; + } + + const Node* getNode() const + { + return Cur; + } + + ConstIterator& operator=(const ConstIterator& src) + { + Root = src.Root; + Cur = src.Cur; + return (*this); + } + + void operator++(int) + { + inc(); + } + + void operator--(int) + { + dec(); + } + + const Node* operator->() + { + return getNode(); + } + + const Node& operator*() + { + _IRR_DEBUG_BREAK_IF(atEnd()) // access violation + + return *Cur; + } + + private: + + const Node* getMin(const Node* n) const + { + while(n && n->getLeftChild()) + n = n->getLeftChild(); + return n; + } + + const Node* getMax(const Node* n) const + { + while(n && n->getRightChild()) + n = n->getRightChild(); + return n; + } + + void inc() + { + // Already at end? + if (Cur==0) + return; + + if (Cur->getRightChild()) + { + // If current node has a right child, the next higher node is the + // node with lowest key beneath the right child. + Cur = getMin(Cur->getRightChild()); + } + else if (Cur->isLeftChild()) + { + // No right child? Well if current node is a left child then + // the next higher node is the parent + Cur = Cur->getParent(); + } + else + { + // Current node neither is left child nor has a right child. + // Ie it is either right child or root + // The next higher node is the parent of the first non-right + // child (ie either a left child or the root) up in the + // hierarchy. Root's parent is 0. + while(Cur->isRightChild()) + Cur = Cur->getParent(); + Cur = Cur->getParent(); + } + } + + void dec() + { + // Already at end? + if (Cur==0) + return; + + if (Cur->getLeftChild()) + { + // If current node has a left child, the next lower node is the + // node with highest key beneath the left child. + Cur = getMax(Cur->getLeftChild()); + } + else if (Cur->isRightChild()) + { + // No left child? Well if current node is a right child then + // the next lower node is the parent + Cur = Cur->getParent(); + } + else + { + // Current node neither is right child nor has a left child. + // Ie it is either left child or root + // The next higher node is the parent of the first non-left + // child (ie either a right child or the root) up in the + // hierarchy. Root's parent is 0. + + while(Cur->isLeftChild()) + Cur = Cur->getParent(); + Cur = Cur->getParent(); + } + } + + const Node* Root; + const Node* Cur; + }; // ConstIterator + + + //! Parent First Iterator. + /** Traverses the tree from top to bottom. Typical usage is + when storing the tree structure, because when reading it + later (and inserting elements) the tree structure will + be the same. */ + class ParentFirstIterator + { + public: + + ParentFirstIterator() : Root(0), Cur(0) {} + + explicit ParentFirstIterator(Node* root) : Root(root), Cur(0) + { + reset(); + } + + void reset() + { + Cur = Root; + } + + bool atEnd() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Cur==0; + } + + Node* getNode() + { + return Cur; + } + + ParentFirstIterator& operator=(const ParentFirstIterator& src) + { + Root = src.Root; + Cur = src.Cur; + return (*this); + } + + void operator++(int) + { + inc(); + } + + Node* operator -> () + { + return getNode(); + } + + Node& operator* () + { + _IRR_DEBUG_BREAK_IF(atEnd()) // access violation + + return *getNode(); + } + + private: + + void inc() + { + // Already at end? + if (Cur==0) + return; + + // First we try down to the left + if (Cur->getLeftChild()) + { + Cur = Cur->getLeftChild(); + } + else if (Cur->getRightChild()) + { + // No left child? The we go down to the right. + Cur = Cur->getRightChild(); + } + else + { + // No children? Move up in the hierarcy until + // we either reach 0 (and are finished) or + // find a right uncle. + while (Cur!=0) + { + // But if parent is left child and has a right "uncle" the parent + // has already been processed but the uncle hasn't. Move to + // the uncle. + if (Cur->isLeftChild() && Cur->getParent()->getRightChild()) + { + Cur = Cur->getParent()->getRightChild(); + return; + } + Cur = Cur->getParent(); + } + } + } + + Node* Root; + Node* Cur; + + }; // ParentFirstIterator + + + //! Parent Last Iterator + /** Traverse the tree from bottom to top. + Typical usage is when deleting all elements in the tree + because you must delete the children before you delete + their parent. */ + class ParentLastIterator + { + public: + + ParentLastIterator() : Root(0), Cur(0) {} + + explicit ParentLastIterator(Node* root) : Root(root), Cur(0) + { + reset(); + } + + void reset() + { + Cur = getMin(Root); + } + + bool atEnd() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Cur==0; + } + + Node* getNode() + { + return Cur; + } + + ParentLastIterator& operator=(const ParentLastIterator& src) + { + Root = src.Root; + Cur = src.Cur; + return (*this); + } + + void operator++(int) + { + inc(); + } + + Node* operator -> () + { + return getNode(); + } + + Node& operator* () + { + _IRR_DEBUG_BREAK_IF(atEnd()) // access violation + + return *getNode(); + } + private: + + Node* getMin(Node* n) + { + while(n!=0 && (n->getLeftChild()!=0 || n->getRightChild()!=0)) + { + if (n->getLeftChild()) + n = n->getLeftChild(); + else + n = n->getRightChild(); + } + return n; + } + + void inc() + { + // Already at end? + if (Cur==0) + return; + + // Note: Starting point is the node as far down to the left as possible. + + // If current node has an uncle to the right, go to the + // node as far down to the left from the uncle as possible + // else just go up a level to the parent. + if (Cur->isLeftChild() && Cur->getParent()->getRightChild()) + { + Cur = getMin(Cur->getParent()->getRightChild()); + } + else + Cur = Cur->getParent(); + } + + Node* Root; + Node* Cur; + }; // ParentLastIterator + + + // AccessClass is a temporary class used with the [] operator. + // It makes it possible to have different behavior in situations like: + // myTree["Foo"] = 32; + // If "Foo" already exists update its value else insert a new element. + // int i = myTree["Foo"] + // If "Foo" exists return its value. + class AccessClass + { + // Let map be the only one who can instantiate this class. + friend class map<KeyType, ValueType>; + + public: + + // Assignment operator. Handles the myTree["Foo"] = 32; situation + void operator=(const ValueType& value) + { + // Just use the Set method, it handles already exist/not exist situation + Tree.set(Key,value); + } + + // ValueType operator + operator ValueType() + { + Node* node = Tree.find(Key); + + // Not found + _IRR_DEBUG_BREAK_IF(node==0) // access violation + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return node->getValue(); + } + + private: + + AccessClass(map& tree, const KeyType& key) : Tree(tree), Key(key) {} + + AccessClass(); + + map& Tree; + const KeyType& Key; + }; // AccessClass + + + // Constructor. + map() : Root(0), Size(0) {} + + // Destructor + ~map() + { + clear(); + } + + //------------------------------ + // Public Commands + //------------------------------ + + //! Inserts a new node into the tree + /** \param keyNew: the index for this value + \param v: the value to insert + \return True if successful, false if it fails (already exists) */ + bool insert(const KeyType& keyNew, const ValueType& v) + { + // First insert node the "usual" way (no fancy balance logic yet) + Node* newNode = new Node(keyNew,v); + if (!insert(newNode)) + { + delete newNode; + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + // Then attend a balancing party + while (!newNode->isRoot() && (newNode->getParent()->isRed())) + { + if (newNode->getParent()->isLeftChild()) + { + // If newNode is a left child, get its right 'uncle' + Node* newNodesUncle = newNode->getParent()->getParent()->getRightChild(); + if ( newNodesUncle!=0 && newNodesUncle->isRed()) + { + // case 1 - change the colors + newNode->getParent()->setBlack(); + newNodesUncle->setBlack(); + newNode->getParent()->getParent()->setRed(); + // Move newNode up the tree + newNode = newNode->getParent()->getParent(); + } + else + { + // newNodesUncle is a black node + if ( newNode->isRightChild()) + { + // and newNode is to the right + // case 2 - move newNode up and rotate + newNode = newNode->getParent(); + rotateLeft(newNode); + } + // case 3 + newNode->getParent()->setBlack(); + newNode->getParent()->getParent()->setRed(); + rotateRight(newNode->getParent()->getParent()); + } + } + else + { + // If newNode is a right child, get its left 'uncle' + Node* newNodesUncle = newNode->getParent()->getParent()->getLeftChild(); + if ( newNodesUncle!=0 && newNodesUncle->isRed()) + { + // case 1 - change the colors + newNode->getParent()->setBlack(); + newNodesUncle->setBlack(); + newNode->getParent()->getParent()->setRed(); + // Move newNode up the tree + newNode = newNode->getParent()->getParent(); + } + else + { + // newNodesUncle is a black node + if (newNode->isLeftChild()) + { + // and newNode is to the left + // case 2 - move newNode up and rotate + newNode = newNode->getParent(); + rotateRight(newNode); + } + // case 3 + newNode->getParent()->setBlack(); + newNode->getParent()->getParent()->setRed(); + rotateLeft(newNode->getParent()->getParent()); + } + + } + } + // Color the root black + Root->setBlack(); + return true; + } + + //! Replaces the value if the key already exists, otherwise inserts a new element. + /** \param k The index for this value + \param v The new value of */ + void set(const KeyType& k, const ValueType& v) + { + Node* p = find(k); + if (p) + p->setValue(v); + else + insert(k,v); + } + + //! Removes a node from the tree and returns it. + /** The returned node must be deleted by the user + \param k the key to remove + \return A pointer to the node, or 0 if not found */ + Node* delink(const KeyType& k) + { + Node* p = find(k); + if (p == 0) + return 0; + + // Rotate p down to the left until it has no right child, will get there + // sooner or later. + while(p->getRightChild()) + { + // "Pull up my right child and let it knock me down to the left" + rotateLeft(p); + } + // p now has no right child but might have a left child + Node* left = p->getLeftChild(); + + // Let p's parent point to p's child instead of point to p + if (p->isLeftChild()) + p->getParent()->setLeftChild(left); + + else if (p->isRightChild()) + p->getParent()->setRightChild(left); + + else + { + // p has no parent => p is the root. + // Let the left child be the new root. + setRoot(left); + } + + // p is now gone from the tree in the sense that + // no one is pointing at it, so return it. + + --Size; + return p; + } + + //! Removes a node from the tree and deletes it. + /** \return True if the node was found and deleted */ + bool remove(const KeyType& k) + { + Node* p = find(k); + return remove(p); + } + + //! Removes a node from the tree and deletes it. + /** \return True if the node was found and deleted */ + bool remove(Node* p) + { + if (p == 0) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + // Rotate p down to the left until it has no right child, will get there + // sooner or later. + while(p->getRightChild()) + { + // "Pull up my right child and let it knock me down to the left" + rotateLeft(p); + } + // p now has no right child but might have a left child + Node* left = p->getLeftChild(); + + // Let p's parent point to p's child instead of point to p + if (p->isLeftChild()) + p->getParent()->setLeftChild(left); + + else if (p->isRightChild()) + p->getParent()->setRightChild(left); + + else + { + // p has no parent => p is the root. + // Let the left child be the new root. + setRoot(left); + } + + // p is now gone from the tree in the sense that + // no one is pointing at it. Let's get rid of it. + delete p; + + --Size; + return true; + } + + //! Clear the entire tree + void clear() + { + ParentLastIterator i(getParentLastIterator()); + + while(!i.atEnd()) + { + Node* p = i.getNode(); + i++; // Increment it before it is deleted + // else iterator will get quite confused. + delete p; + } + Root = 0; + Size= 0; + } + + //! Is the tree empty? + //! \return Returns true if empty, false if not + bool empty() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Root == 0; + } + + //! \deprecated Use empty() instead. This method may be removed by Irrlicht 1.9 + _IRR_DEPRECATED_ bool isEmpty() const + { + return empty(); + } + + //! Search for a node with the specified key. + //! \param keyToFind: The key to find + //! \return Returns 0 if node couldn't be found. + Node* find(const KeyType& keyToFind) const + { + Node* pNode = Root; + + while(pNode!=0) + { + const KeyType& key=pNode->getKey(); + + if (keyToFind == key) + return pNode; + else if (keyToFind < key) + pNode = pNode->getLeftChild(); + else //keyToFind > key + pNode = pNode->getRightChild(); + } + + return 0; + } + + //! Gets the root element. + //! \return Returns a pointer to the root node, or + //! 0 if the tree is empty. + Node* getRoot() const + { + return Root; + } + + //! Returns the number of nodes in the tree. + u32 size() const + { + return Size; + } + + //! Swap the content of this map container with the content of another map + /** Afterwards this object will contain the content of the other object and the other + object will contain the content of this object. Iterators will afterwards be valid for + the swapped object. + \param other Swap content with this object */ + void swap(map<KeyType, ValueType>& other) + { + core::swap(Root, other.Root); + core::swap(Size, other.Size); + } + + //------------------------------ + // Public Iterators + //------------------------------ + + //! Returns an iterator + Iterator getIterator() const + { + Iterator it(getRoot()); + return it; + } + + //! Returns a Constiterator + ConstIterator getConstIterator() const + { + Iterator it(getRoot()); + return it; + } + + //! Returns a ParentFirstIterator. + //! Traverses the tree from top to bottom. Typical usage is + //! when storing the tree structure, because when reading it + //! later (and inserting elements) the tree structure will + //! be the same. + ParentFirstIterator getParentFirstIterator() const + { + ParentFirstIterator it(getRoot()); + return it; + } + + //! Returns a ParentLastIterator to traverse the tree from + //! bottom to top. + //! Typical usage is when deleting all elements in the tree + //! because you must delete the children before you delete + //! their parent. + ParentLastIterator getParentLastIterator() const + { + ParentLastIterator it(getRoot()); + return it; + } + + //------------------------------ + // Public Operators + //------------------------------ + + //! operator [] for access to elements + /** for example myMap["key"] */ + AccessClass operator[](const KeyType& k) + { + return AccessClass(*this, k); + } + private: + + //------------------------------ + // Disabled methods + //------------------------------ + // Copy constructor and assignment operator deliberately + // defined but not implemented. The tree should never be + // copied, pass along references to it instead. + explicit map(const map& src); + map& operator = (const map& src); + + //! Set node as new root. + /** The node will be set to black, otherwise core dumps may arise + (patch provided by rogerborg). + \param newRoot Node which will be the new root + */ + void setRoot(Node* newRoot) + { + Root = newRoot; + if (Root != 0) + { + Root->setParent(0); + Root->setBlack(); + } + } + + //! Insert a node into the tree without using any fancy balancing logic. + /** \return false if that key already exist in the tree. */ + bool insert(Node* newNode) + { + bool result=true; // Assume success + + if (Root==0) + { + setRoot(newNode); + Size = 1; + } + else + { + Node* pNode = Root; + const KeyType& keyNew = newNode->getKey(); + while (pNode) + { + const KeyType& key=pNode->getKey(); + + if (keyNew == key) + { + result = false; + pNode = 0; + } + else if (keyNew < key) + { + if (pNode->getLeftChild() == 0) + { + pNode->setLeftChild(newNode); + pNode = 0; + } + else + pNode = pNode->getLeftChild(); + } + else // keyNew > key + { + if (pNode->getRightChild()==0) + { + pNode->setRightChild(newNode); + pNode = 0; + } + else + { + pNode = pNode->getRightChild(); + } + } + } + + if (result) + ++Size; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return result; + } + + //! Rotate left. + //! Pull up node's right child and let it knock node down to the left + void rotateLeft(Node* p) + { + Node* right = p->getRightChild(); + + p->setRightChild(right->getLeftChild()); + + if (p->isLeftChild()) + p->getParent()->setLeftChild(right); + else if (p->isRightChild()) + p->getParent()->setRightChild(right); + else + setRoot(right); + + right->setLeftChild(p); + } + + //! Rotate right. + //! Pull up node's left child and let it knock node down to the right + void rotateRight(Node* p) + { + Node* left = p->getLeftChild(); + + p->setLeftChild(left->getRightChild()); + + if (p->isLeftChild()) + p->getParent()->setLeftChild(left); + else if (p->isRightChild()) + p->getParent()->setRightChild(left); + else + setRoot(left); + + left->setRightChild(p); + } + + //------------------------------ + // Private Members + //------------------------------ + Node* Root; // The top node. 0 if empty. + u32 Size; // Number of nodes in the tree +}; + +} // end namespace core +} // end namespace irr + +#endif // __IRR_MAP_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/irrMath.h b/builddir/irrlicht-1.8.1/include/irrMath.h new file mode 100644 index 0000000..4351027 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/irrMath.h @@ -0,0 +1,732 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_MATH_H_INCLUDED__ +#define __IRR_MATH_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#include "irrTypes.h" +#include <math.h> +#include <float.h> +#include <stdlib.h> // for abs() etc. +#include <limits.h> // For INT_MAX / UINT_MAX + +#if defined(_IRR_SOLARIS_PLATFORM_) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) || defined (_WIN32_WCE) + #define sqrtf(X) (irr::f32)sqrt((irr::f64)(X)) + #define sinf(X) (irr::f32)sin((irr::f64)(X)) + #define cosf(X) (irr::f32)cos((irr::f64)(X)) + #define asinf(X) (irr::f32)asin((irr::f64)(X)) + #define acosf(X) (irr::f32)acos((irr::f64)(X)) + #define atan2f(X,Y) (irr::f32)atan2((irr::f64)(X),(irr::f64)(Y)) + #define ceilf(X) (irr::f32)ceil((irr::f64)(X)) + #define floorf(X) (irr::f32)floor((irr::f64)(X)) + #define powf(X,Y) (irr::f32)pow((irr::f64)(X),(irr::f64)(Y)) + #define fmodf(X,Y) (irr::f32)fmod((irr::f64)(X),(irr::f64)(Y)) + #define fabsf(X) (irr::f32)fabs((irr::f64)(X)) + #define logf(X) (irr::f32)log((irr::f64)(X)) +#endif + +#ifndef FLT_MAX +#define FLT_MAX 3.402823466E+38F +#endif + +#ifndef FLT_MIN +#define FLT_MIN 1.17549435e-38F +#endif + +namespace irr +{ +namespace core +{ + + //! Rounding error constant often used when comparing f32 values. + + const s32 ROUNDING_ERROR_S32 = 0; +#ifdef __IRR_HAS_S64 + const s64 ROUNDING_ERROR_S64 = 0; +#endif + const f32 ROUNDING_ERROR_f32 = 0.000001f; + const f64 ROUNDING_ERROR_f64 = 0.00000001; + +#ifdef PI // make sure we don't collide with a define +#undef PI +#endif + //! Constant for PI. + const f32 PI = 3.14159265359f; + + //! Constant for reciprocal of PI. + const f32 RECIPROCAL_PI = 1.0f/PI; + + //! Constant for half of PI. + const f32 HALF_PI = PI/2.0f; + +#ifdef PI64 // make sure we don't collide with a define +#undef PI64 +#endif + //! Constant for 64bit PI. + const f64 PI64 = 3.1415926535897932384626433832795028841971693993751; + + //! Constant for 64bit reciprocal of PI. + const f64 RECIPROCAL_PI64 = 1.0/PI64; + + //! 32bit Constant for converting from degrees to radians + const f32 DEGTORAD = PI / 180.0f; + + //! 32bit constant for converting from radians to degrees (formally known as GRAD_PI) + const f32 RADTODEG = 180.0f / PI; + + //! 64bit constant for converting from degrees to radians (formally known as GRAD_PI2) + const f64 DEGTORAD64 = PI64 / 180.0; + + //! 64bit constant for converting from radians to degrees + const f64 RADTODEG64 = 180.0 / PI64; + + //! Utility function to convert a radian value to degrees + /** Provided as it can be clearer to write radToDeg(X) than RADTODEG * X + \param radians The radians value to convert to degrees. + */ + inline f32 radToDeg(f32 radians) + { + return RADTODEG * radians; + } + + //! Utility function to convert a radian value to degrees + /** Provided as it can be clearer to write radToDeg(X) than RADTODEG * X + \param radians The radians value to convert to degrees. + */ + inline f64 radToDeg(f64 radians) + { + return RADTODEG64 * radians; + } + + //! Utility function to convert a degrees value to radians + /** Provided as it can be clearer to write degToRad(X) than DEGTORAD * X + \param degrees The degrees value to convert to radians. + */ + inline f32 degToRad(f32 degrees) + { + return DEGTORAD * degrees; + } + + //! Utility function to convert a degrees value to radians + /** Provided as it can be clearer to write degToRad(X) than DEGTORAD * X + \param degrees The degrees value to convert to radians. + */ + inline f64 degToRad(f64 degrees) + { + return DEGTORAD64 * degrees; + } + + //! returns minimum of two values. Own implementation to get rid of the STL (VS6 problems) + template<class T> + inline const T& min_(const T& a, const T& b) + { + return a < b ? a : b; + } + + //! returns minimum of three values. Own implementation to get rid of the STL (VS6 problems) + template<class T> + inline const T& min_(const T& a, const T& b, const T& c) + { + return a < b ? min_(a, c) : min_(b, c); + } + + //! returns maximum of two values. Own implementation to get rid of the STL (VS6 problems) + template<class T> + inline const T& max_(const T& a, const T& b) + { + return a < b ? b : a; + } + + //! returns maximum of three values. Own implementation to get rid of the STL (VS6 problems) + template<class T> + inline const T& max_(const T& a, const T& b, const T& c) + { + return a < b ? max_(b, c) : max_(a, c); + } + + //! returns abs of two values. Own implementation to get rid of STL (VS6 problems) + template<class T> + inline T abs_(const T& a) + { + return a < (T)0 ? -a : a; + } + + //! returns linear interpolation of a and b with ratio t + //! \return: a if t==0, b if t==1, and the linear interpolation else + template<class T> + inline T lerp(const T& a, const T& b, const f32 t) + { + return (T)(a*(1.f-t)) + (b*t); + } + + //! clamps a value between low and high + template <class T> + inline const T clamp (const T& value, const T& low, const T& high) + { + return min_ (max_(value,low), high); + } + + //! swaps the content of the passed parameters + // Note: We use the same trick as boost and use two template arguments to + // avoid ambiguity when swapping objects of an Irrlicht type that has not + // it's own swap overload. Otherwise we get conflicts with some compilers + // in combination with stl. + template <class T1, class T2> + inline void swap(T1& a, T2& b) + { + T1 c(a); + a = b; + b = c; + } + + //! returns if a equals b, taking possible rounding errors into account + inline bool equals(const f64 a, const f64 b, const f64 tolerance = ROUNDING_ERROR_f64) + { + return (a + tolerance >= b) && (a - tolerance <= b); + } + + //! returns if a equals b, taking possible rounding errors into account + inline bool equals(const f32 a, const f32 b, const f32 tolerance = ROUNDING_ERROR_f32) + { + return (a + tolerance >= b) && (a - tolerance <= b); + } + + union FloatIntUnion32 + { + FloatIntUnion32(float f1 = 0.0f) : f(f1) {} + // Portable sign-extraction + bool sign() const { return (i >> 31) != 0; } + + irr::s32 i; + irr::f32 f; + }; + + //! We compare the difference in ULP's (spacing between floating-point numbers, aka ULP=1 means there exists no float between). + //\result true when numbers have a ULP <= maxUlpDiff AND have the same sign. + inline bool equalsByUlp(f32 a, f32 b, int maxUlpDiff) + { + // Based on the ideas and code from Bruce Dawson on + // http://www.altdevblogaday.com/2012/02/22/comparing-floating-point-numbers-2012-edition/ + // When floats are interpreted as integers the two nearest possible float numbers differ just + // by one integer number. Also works the other way round, an integer of 1 interpreted as float + // is for example the smallest possible float number. + + FloatIntUnion32 fa(a); + FloatIntUnion32 fb(b); + + // Different signs, we could maybe get difference to 0, but so close to 0 using epsilons is better. + if ( fa.sign() != fb.sign() ) + { + // Check for equality to make sure +0==-0 + if (fa.i == fb.i) + return true; + return false; + } + + // Find the difference in ULPs. + int ulpsDiff = abs_(fa.i- fb.i); + if (ulpsDiff <= maxUlpDiff) + return true; + + return false; + } + +#if 0 + //! returns if a equals b, not using any rounding tolerance + inline bool equals(const s32 a, const s32 b) + { + return (a == b); + } + + //! returns if a equals b, not using any rounding tolerance + inline bool equals(const u32 a, const u32 b) + { + return (a == b); + } +#endif + //! returns if a equals b, taking an explicit rounding tolerance into account + inline bool equals(const s32 a, const s32 b, const s32 tolerance = ROUNDING_ERROR_S32) + { + return (a + tolerance >= b) && (a - tolerance <= b); + } + + //! returns if a equals b, taking an explicit rounding tolerance into account + inline bool equals(const u32 a, const u32 b, const s32 tolerance = ROUNDING_ERROR_S32) + { + return (a + tolerance >= b) && (a - tolerance <= b); + } + +#ifdef __IRR_HAS_S64 + //! returns if a equals b, taking an explicit rounding tolerance into account + inline bool equals(const s64 a, const s64 b, const s64 tolerance = ROUNDING_ERROR_S64) + { + return (a + tolerance >= b) && (a - tolerance <= b); + } +#endif + + //! returns if a equals zero, taking rounding errors into account + inline bool iszero(const f64 a, const f64 tolerance = ROUNDING_ERROR_f64) + { + return fabs(a) <= tolerance; + } + + //! returns if a equals zero, taking rounding errors into account + inline bool iszero(const f32 a, const f32 tolerance = ROUNDING_ERROR_f32) + { + return fabsf(a) <= tolerance; + } + + //! returns if a equals not zero, taking rounding errors into account + inline bool isnotzero(const f32 a, const f32 tolerance = ROUNDING_ERROR_f32) + { + return fabsf(a) > tolerance; + } + + //! returns if a equals zero, taking rounding errors into account + inline bool iszero(const s32 a, const s32 tolerance = 0) + { + return ( a & 0x7ffffff ) <= tolerance; + } + + //! returns if a equals zero, taking rounding errors into account + inline bool iszero(const u32 a, const u32 tolerance = 0) + { + return a <= tolerance; + } + +#ifdef __IRR_HAS_S64 + //! returns if a equals zero, taking rounding errors into account + inline bool iszero(const s64 a, const s64 tolerance = 0) + { + return abs_(a) <= tolerance; + } +#endif + + inline s32 s32_min(s32 a, s32 b) + { + const s32 mask = (a - b) >> 31; + return (a & mask) | (b & ~mask); + } + + inline s32 s32_max(s32 a, s32 b) + { + const s32 mask = (a - b) >> 31; + return (b & mask) | (a & ~mask); + } + + inline s32 s32_clamp (s32 value, s32 low, s32 high) + { + return s32_min(s32_max(value,low), high); + } + + /* + float IEEE-754 bit represenation + + 0 0x00000000 + 1.0 0x3f800000 + 0.5 0x3f000000 + 3 0x40400000 + +inf 0x7f800000 + -inf 0xff800000 + +NaN 0x7fc00000 or 0x7ff00000 + in general: number = (sign ? -1:1) * 2^(exponent) * 1.(mantissa bits) + */ + + typedef union { u32 u; s32 s; f32 f; } inttofloat; + + #define F32_AS_S32(f) (*((s32 *) &(f))) + #define F32_AS_U32(f) (*((u32 *) &(f))) + #define F32_AS_U32_POINTER(f) ( ((u32 *) &(f))) + + #define F32_VALUE_0 0x00000000 + #define F32_VALUE_1 0x3f800000 + #define F32_SIGN_BIT 0x80000000U + #define F32_EXPON_MANTISSA 0x7FFFFFFFU + + //! code is taken from IceFPU + //! Integer representation of a floating-point value. +#ifdef IRRLICHT_FAST_MATH + #define IR(x) ((u32&)(x)) +#else + inline u32 IR(f32 x) {inttofloat tmp; tmp.f=x; return tmp.u;} +#endif + + //! Absolute integer representation of a floating-point value + #define AIR(x) (IR(x)&0x7fffffff) + + //! Floating-point representation of an integer value. +#ifdef IRRLICHT_FAST_MATH + #define FR(x) ((f32&)(x)) +#else + inline f32 FR(u32 x) {inttofloat tmp; tmp.u=x; return tmp.f;} + inline f32 FR(s32 x) {inttofloat tmp; tmp.s=x; return tmp.f;} +#endif + + //! integer representation of 1.0 + #define IEEE_1_0 0x3f800000 + //! integer representation of 255.0 + #define IEEE_255_0 0x437f0000 + +#ifdef IRRLICHT_FAST_MATH + #define F32_LOWER_0(f) (F32_AS_U32(f) > F32_SIGN_BIT) + #define F32_LOWER_EQUAL_0(f) (F32_AS_S32(f) <= F32_VALUE_0) + #define F32_GREATER_0(f) (F32_AS_S32(f) > F32_VALUE_0) + #define F32_GREATER_EQUAL_0(f) (F32_AS_U32(f) <= F32_SIGN_BIT) + #define F32_EQUAL_1(f) (F32_AS_U32(f) == F32_VALUE_1) + #define F32_EQUAL_0(f) ( (F32_AS_U32(f) & F32_EXPON_MANTISSA ) == F32_VALUE_0) + + // only same sign + #define F32_A_GREATER_B(a,b) (F32_AS_S32((a)) > F32_AS_S32((b))) + +#else + + #define F32_LOWER_0(n) ((n) < 0.0f) + #define F32_LOWER_EQUAL_0(n) ((n) <= 0.0f) + #define F32_GREATER_0(n) ((n) > 0.0f) + #define F32_GREATER_EQUAL_0(n) ((n) >= 0.0f) + #define F32_EQUAL_1(n) ((n) == 1.0f) + #define F32_EQUAL_0(n) ((n) == 0.0f) + #define F32_A_GREATER_B(a,b) ((a) > (b)) +#endif + + +#ifndef REALINLINE + #ifdef _MSC_VER + #define REALINLINE __forceinline + #else + #define REALINLINE inline + #endif +#endif + +#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) + + // 8-bit bools in borland builder + + //! conditional set based on mask and arithmetic shift + REALINLINE u32 if_c_a_else_b ( const c8 condition, const u32 a, const u32 b ) + { + return ( ( -condition >> 7 ) & ( a ^ b ) ) ^ b; + } + + //! conditional set based on mask and arithmetic shift + REALINLINE u32 if_c_a_else_0 ( const c8 condition, const u32 a ) + { + return ( -condition >> 31 ) & a; + } +#else + + //! conditional set based on mask and arithmetic shift + REALINLINE u32 if_c_a_else_b ( const s32 condition, const u32 a, const u32 b ) + { + return ( ( -condition >> 31 ) & ( a ^ b ) ) ^ b; + } + + //! conditional set based on mask and arithmetic shift + REALINLINE u16 if_c_a_else_b ( const s16 condition, const u16 a, const u16 b ) + { + return ( ( -condition >> 15 ) & ( a ^ b ) ) ^ b; + } + + //! conditional set based on mask and arithmetic shift + REALINLINE u32 if_c_a_else_0 ( const s32 condition, const u32 a ) + { + return ( -condition >> 31 ) & a; + } +#endif + + /* + if (condition) state |= m; else state &= ~m; + */ + REALINLINE void setbit_cond ( u32 &state, s32 condition, u32 mask ) + { + // 0, or any postive to mask + //s32 conmask = -condition >> 31; + state ^= ( ( -condition >> 31 ) ^ state ) & mask; + } + + inline f32 round_( f32 x ) + { + return floorf( x + 0.5f ); + } + + REALINLINE void clearFPUException () + { +#ifdef IRRLICHT_FAST_MATH + return; +#ifdef feclearexcept + feclearexcept(FE_ALL_EXCEPT); +#elif defined(_MSC_VER) + __asm fnclex; +#elif defined(__GNUC__) && defined(__x86__) + __asm__ __volatile__ ("fclex \n\t"); +#else +# warn clearFPUException not supported. +#endif +#endif + } + + // calculate: sqrt ( x ) + REALINLINE f32 squareroot(const f32 f) + { + return sqrtf(f); + } + + // calculate: sqrt ( x ) + REALINLINE f64 squareroot(const f64 f) + { + return sqrt(f); + } + + // calculate: sqrt ( x ) + REALINLINE s32 squareroot(const s32 f) + { + return static_cast<s32>(squareroot(static_cast<f32>(f))); + } + +#ifdef __IRR_HAS_S64 + // calculate: sqrt ( x ) + REALINLINE s64 squareroot(const s64 f) + { + return static_cast<s64>(squareroot(static_cast<f64>(f))); + } +#endif + + // calculate: 1 / sqrt ( x ) + REALINLINE f64 reciprocal_squareroot(const f64 x) + { + return 1.0 / sqrt(x); + } + + // calculate: 1 / sqrtf ( x ) + REALINLINE f32 reciprocal_squareroot(const f32 f) + { +#if defined ( IRRLICHT_FAST_MATH ) + #if defined(_MSC_VER) + // SSE reciprocal square root estimate, accurate to 12 significant + // bits of the mantissa + f32 recsqrt; + __asm rsqrtss xmm0, f // xmm0 = rsqrtss(f) + __asm movss recsqrt, xmm0 // return xmm0 + return recsqrt; + +/* + // comes from Nvidia + u32 tmp = (u32(IEEE_1_0 << 1) + IEEE_1_0 - *(u32*)&x) >> 1; + f32 y = *(f32*)&tmp; + return y * (1.47f - 0.47f * x * y * y); +*/ + #else + return 1.f / sqrtf(f); + #endif +#else // no fast math + return 1.f / sqrtf(f); +#endif + } + + // calculate: 1 / sqrtf( x ) + REALINLINE s32 reciprocal_squareroot(const s32 x) + { + return static_cast<s32>(reciprocal_squareroot(static_cast<f32>(x))); + } + + // calculate: 1 / x + REALINLINE f32 reciprocal( const f32 f ) + { +#if defined (IRRLICHT_FAST_MATH) + + // SSE Newton-Raphson reciprocal estimate, accurate to 23 significant + // bi ts of the mantissa + // One Newtown-Raphson Iteration: + // f(i+1) = 2 * rcpss(f) - f * rcpss(f) * rcpss(f) + f32 rec; + __asm rcpss xmm0, f // xmm0 = rcpss(f) + __asm movss xmm1, f // xmm1 = f + __asm mulss xmm1, xmm0 // xmm1 = f * rcpss(f) + __asm mulss xmm1, xmm0 // xmm2 = f * rcpss(f) * rcpss(f) + __asm addss xmm0, xmm0 // xmm0 = 2 * rcpss(f) + __asm subss xmm0, xmm1 // xmm0 = 2 * rcpss(f) + // - f * rcpss(f) * rcpss(f) + __asm movss rec, xmm0 // return xmm0 + return rec; + + + //! i do not divide through 0.. (fpu expection) + // instead set f to a high value to get a return value near zero.. + // -1000000000000.f.. is use minus to stay negative.. + // must test's here (plane.normal dot anything ) checks on <= 0.f + //u32 x = (-(AIR(f) != 0 ) >> 31 ) & ( IR(f) ^ 0xd368d4a5 ) ^ 0xd368d4a5; + //return 1.f / FR ( x ); + +#else // no fast math + return 1.f / f; +#endif + } + + // calculate: 1 / x + REALINLINE f64 reciprocal ( const f64 f ) + { + return 1.0 / f; + } + + + // calculate: 1 / x, low precision allowed + REALINLINE f32 reciprocal_approxim ( const f32 f ) + { +#if defined( IRRLICHT_FAST_MATH) + + // SSE Newton-Raphson reciprocal estimate, accurate to 23 significant + // bi ts of the mantissa + // One Newtown-Raphson Iteration: + // f(i+1) = 2 * rcpss(f) - f * rcpss(f) * rcpss(f) + f32 rec; + __asm rcpss xmm0, f // xmm0 = rcpss(f) + __asm movss xmm1, f // xmm1 = f + __asm mulss xmm1, xmm0 // xmm1 = f * rcpss(f) + __asm mulss xmm1, xmm0 // xmm2 = f * rcpss(f) * rcpss(f) + __asm addss xmm0, xmm0 // xmm0 = 2 * rcpss(f) + __asm subss xmm0, xmm1 // xmm0 = 2 * rcpss(f) + // - f * rcpss(f) * rcpss(f) + __asm movss rec, xmm0 // return xmm0 + return rec; + + +/* + // SSE reciprocal estimate, accurate to 12 significant bits of + f32 rec; + __asm rcpss xmm0, f // xmm0 = rcpss(f) + __asm movss rec , xmm0 // return xmm0 + return rec; +*/ +/* + register u32 x = 0x7F000000 - IR ( p ); + const f32 r = FR ( x ); + return r * (2.0f - p * r); +*/ +#else // no fast math + return 1.f / f; +#endif + } + + + REALINLINE s32 floor32(f32 x) + { +#ifdef IRRLICHT_FAST_MATH + const f32 h = 0.5f; + + s32 t; + +#if defined(_MSC_VER) + __asm + { + fld x + fsub h + fistp t + } +#elif defined(__GNUC__) + __asm__ __volatile__ ( + "fsub %2 \n\t" + "fistpl %0" + : "=m" (t) + : "t" (x), "f" (h) + : "st" + ); +#else +# warn IRRLICHT_FAST_MATH not supported. + return (s32) floorf ( x ); +#endif + return t; +#else // no fast math + return (s32) floorf ( x ); +#endif + } + + + REALINLINE s32 ceil32 ( f32 x ) + { +#ifdef IRRLICHT_FAST_MATH + const f32 h = 0.5f; + + s32 t; + +#if defined(_MSC_VER) + __asm + { + fld x + fadd h + fistp t + } +#elif defined(__GNUC__) + __asm__ __volatile__ ( + "fadd %2 \n\t" + "fistpl %0 \n\t" + : "=m"(t) + : "t"(x), "f"(h) + : "st" + ); +#else +# warn IRRLICHT_FAST_MATH not supported. + return (s32) ceilf ( x ); +#endif + return t; +#else // not fast math + return (s32) ceilf ( x ); +#endif + } + + + + REALINLINE s32 round32(f32 x) + { +#if defined(IRRLICHT_FAST_MATH) + s32 t; + +#if defined(_MSC_VER) + __asm + { + fld x + fistp t + } +#elif defined(__GNUC__) + __asm__ __volatile__ ( + "fistpl %0 \n\t" + : "=m"(t) + : "t"(x) + : "st" + ); +#else +# warn IRRLICHT_FAST_MATH not supported. + return (s32) round_(x); +#endif + return t; +#else // no fast math + return (s32) round_(x); +#endif + } + + inline f32 f32_max3(const f32 a, const f32 b, const f32 c) + { + return a > b ? (a > c ? a : c) : (b > c ? b : c); + } + + inline f32 f32_min3(const f32 a, const f32 b, const f32 c) + { + return a < b ? (a < c ? a : c) : (b < c ? b : c); + } + + inline f32 fract ( f32 x ) + { + return x - floorf ( x ); + } + +} // end namespace core +} // end namespace irr + +#ifndef IRRLICHT_FAST_MATH + using irr::core::IR; + using irr::core::FR; +#endif + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/irrString.h b/builddir/irrlicht-1.8.1/include/irrString.h new file mode 100644 index 0000000..752ea1a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/irrString.h @@ -0,0 +1,1368 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __IRR_STRING_H_INCLUDED__ +#define __IRR_STRING_H_INCLUDED__ + +#include "irrTypes.h" +#include "irrAllocator.h" +#include "irrMath.h" +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +namespace irr +{ +namespace core +{ + +//! Very simple string class with some useful features. +/** string<c8> and string<wchar_t> both accept Unicode AND ASCII/Latin-1, +so you can assign Unicode to string<c8> and ASCII/Latin-1 to string<wchar_t> +(and the other way round) if you want to. + +However, note that the conversation between both is not done using any encoding. +This means that c8 strings are treated as ASCII/Latin-1, not UTF-8, and +are simply expanded to the equivalent wchar_t, while Unicode/wchar_t +characters are truncated to 8-bit ASCII/Latin-1 characters, discarding all +other information in the wchar_t. +*/ + +enum eLocaleID +{ + IRR_LOCALE_ANSI = 0, + IRR_LOCALE_GERMAN = 1 +}; + +static eLocaleID locale_current = IRR_LOCALE_ANSI; +static inline void locale_set ( eLocaleID id ) +{ + locale_current = id; +} + +//! Returns a character converted to lower case +static inline u32 locale_lower ( u32 x ) +{ + switch ( locale_current ) + { + case IRR_LOCALE_GERMAN: + case IRR_LOCALE_ANSI: + break; + } + // ansi + return x >= 'A' && x <= 'Z' ? x + 0x20 : x; +} + +//! Returns a character converted to upper case +static inline u32 locale_upper ( u32 x ) +{ + switch ( locale_current ) + { + case IRR_LOCALE_GERMAN: + case IRR_LOCALE_ANSI: + break; + } + + // ansi + return x >= 'a' && x <= 'z' ? x + ( 'A' - 'a' ) : x; +} + + +template <typename T, typename TAlloc = irrAllocator<T> > +class string +{ +public: + + typedef T char_type; + + //! Default constructor + string() + : array(0), allocated(1), used(1) + { + array = allocator.allocate(1); // new T[1]; + array[0] = 0; + } + + + //! Constructor + string(const string<T,TAlloc>& other) + : array(0), allocated(0), used(0) + { + *this = other; + } + + //! Constructor from other string types + template <class B, class A> + string(const string<B, A>& other) + : array(0), allocated(0), used(0) + { + *this = other; + } + + + //! Constructs a string from a float + explicit string(const double number) + : array(0), allocated(0), used(0) + { + c8 tmpbuf[255]; + snprintf(tmpbuf, 255, "%0.6f", number); + *this = tmpbuf; + } + + + //! Constructs a string from an int + explicit string(int number) + : array(0), allocated(0), used(0) + { + // store if negative and make positive + + bool negative = false; + if (number < 0) + { + number *= -1; + negative = true; + } + + // temporary buffer for 16 numbers + + c8 tmpbuf[16]={0}; + u32 idx = 15; + + // special case '0' + + if (!number) + { + tmpbuf[14] = '0'; + *this = &tmpbuf[14]; + return; + } + + // add numbers + + while(number && idx) + { + --idx; + tmpbuf[idx] = (c8)('0' + (number % 10)); + number /= 10; + } + + // add sign + + if (negative) + { + --idx; + tmpbuf[idx] = '-'; + } + + *this = &tmpbuf[idx]; + } + + + //! Constructs a string from an unsigned int + explicit string(unsigned int number) + : array(0), allocated(0), used(0) + { + // temporary buffer for 16 numbers + + c8 tmpbuf[16]={0}; + u32 idx = 15; + + // special case '0' + + if (!number) + { + tmpbuf[14] = '0'; + *this = &tmpbuf[14]; + return; + } + + // add numbers + + while(number && idx) + { + --idx; + tmpbuf[idx] = (c8)('0' + (number % 10)); + number /= 10; + } + + *this = &tmpbuf[idx]; + } + + + //! Constructs a string from a long + explicit string(long number) + : array(0), allocated(0), used(0) + { + // store if negative and make positive + + bool negative = false; + if (number < 0) + { + number *= -1; + negative = true; + } + + // temporary buffer for 16 numbers + + c8 tmpbuf[16]={0}; + u32 idx = 15; + + // special case '0' + + if (!number) + { + tmpbuf[14] = '0'; + *this = &tmpbuf[14]; + return; + } + + // add numbers + + while(number && idx) + { + --idx; + tmpbuf[idx] = (c8)('0' + (number % 10)); + number /= 10; + } + + // add sign + + if (negative) + { + --idx; + tmpbuf[idx] = '-'; + } + + *this = &tmpbuf[idx]; + } + + + //! Constructs a string from an unsigned long + explicit string(unsigned long number) + : array(0), allocated(0), used(0) + { + // temporary buffer for 16 numbers + + c8 tmpbuf[16]={0}; + u32 idx = 15; + + // special case '0' + + if (!number) + { + tmpbuf[14] = '0'; + *this = &tmpbuf[14]; + return; + } + + // add numbers + + while(number && idx) + { + --idx; + tmpbuf[idx] = (c8)('0' + (number % 10)); + number /= 10; + } + + *this = &tmpbuf[idx]; + } + + + //! Constructor for copying a string from a pointer with a given length + template <class B> + string(const B* const c, u32 length) + : array(0), allocated(0), used(0) + { + if (!c) + { + // correctly init the string to an empty one + *this=""; + return; + } + + allocated = used = length+1; + array = allocator.allocate(used); // new T[used]; + + for (u32 l = 0; l<length; ++l) + array[l] = (T)c[l]; + + array[length] = 0; + } + + + //! Constructor for unicode and ascii strings + template <class B> + string(const B* const c) + : array(0), allocated(0), used(0) + { + *this = c; + } + + + //! Destructor + ~string() + { + allocator.deallocate(array); // delete [] array; + } + + + //! Assignment operator + string<T,TAlloc>& operator=(const string<T,TAlloc>& other) + { + if (this == &other) + return *this; + + used = other.size()+1; + if (used>allocated) + { + allocator.deallocate(array); // delete [] array; + allocated = used; + array = allocator.allocate(used); //new T[used]; + } + + const T* p = other.c_str(); + for (u32 i=0; i<used; ++i, ++p) + array[i] = *p; + + return *this; + } + + //! Assignment operator for other string types + template <class B, class A> + string<T,TAlloc>& operator=(const string<B,A>& other) + { + *this = other.c_str(); + return *this; + } + + + //! Assignment operator for strings, ascii and unicode + template <class B> + string<T,TAlloc>& operator=(const B* const c) + { + if (!c) + { + if (!array) + { + array = allocator.allocate(1); //new T[1]; + allocated = 1; + } + used = 1; + array[0] = 0x0; + return *this; + } + + if ((void*)c == (void*)array) + return *this; + + u32 len = 0; + const B* p = c; + do + { + ++len; + } while(*p++); + + // we'll keep the old string for a while, because the new + // string could be a part of the current string. + T* oldArray = array; + + used = len; + if (used>allocated) + { + allocated = used; + array = allocator.allocate(used); //new T[used]; + } + + for (u32 l = 0; l<len; ++l) + array[l] = (T)c[l]; + + if (oldArray != array) + allocator.deallocate(oldArray); // delete [] oldArray; + + return *this; + } + + + //! Append operator for other strings + string<T,TAlloc> operator+(const string<T,TAlloc>& other) const + { + string<T,TAlloc> str(*this); + str.append(other); + + return str; + } + + + //! Append operator for strings, ascii and unicode + template <class B> + string<T,TAlloc> operator+(const B* const c) const + { + string<T,TAlloc> str(*this); + str.append(c); + + return str; + } + + + //! Direct access operator + T& operator [](const u32 index) + { + _IRR_DEBUG_BREAK_IF(index>=used) // bad index + return array[index]; + } + + + //! Direct access operator + const T& operator [](const u32 index) const + { + _IRR_DEBUG_BREAK_IF(index>=used) // bad index + return array[index]; + } + + + //! Equality operator + bool operator==(const T* const str) const + { + if (!str) + return false; + + u32 i; + for (i=0; array[i] && str[i]; ++i) + if (array[i] != str[i]) + return false; + + return (!array[i] && !str[i]); + } + + + //! Equality operator + bool operator==(const string<T,TAlloc>& other) const + { + for (u32 i=0; array[i] && other.array[i]; ++i) + if (array[i] != other.array[i]) + return false; + + return used == other.used; + } + + + //! Is smaller comparator + bool operator<(const string<T,TAlloc>& other) const + { + for (u32 i=0; array[i] && other.array[i]; ++i) + { + const s32 diff = array[i] - other.array[i]; + if (diff) + return (diff < 0); + } + + return (used < other.used); + } + + + //! Inequality operator + bool operator!=(const T* const str) const + { + return !(*this == str); + } + + + //! Inequality operator + bool operator!=(const string<T,TAlloc>& other) const + { + return !(*this == other); + } + + + //! Returns length of the string's content + /** \return Length of the string's content in characters, excluding + the trailing NUL. */ + u32 size() const + { + return used-1; + } + + //! Informs if the string is empty or not. + //! \return True if the string is empty, false if not. + bool empty() const + { + return (size() == 0); + } + + //! Returns character string + /** \return pointer to C-style NUL terminated string. */ + const T* c_str() const + { + return array; + } + + + //! Makes the string lower case. + string<T,TAlloc>& make_lower() + { + for (u32 i=0; array[i]; ++i) + array[i] = locale_lower ( array[i] ); + return *this; + } + + + //! Makes the string upper case. + string<T,TAlloc>& make_upper() + { + for (u32 i=0; array[i]; ++i) + array[i] = locale_upper ( array[i] ); + return *this; + } + + + //! Compares the strings ignoring case. + /** \param other: Other string to compare. + \return True if the strings are equal ignoring case. */ + bool equals_ignore_case(const string<T,TAlloc>& other) const + { + for(u32 i=0; array[i] && other[i]; ++i) + if (locale_lower( array[i]) != locale_lower(other[i])) + return false; + + return used == other.used; + } + + //! Compares the strings ignoring case. + /** \param other: Other string to compare. + \param sourcePos: where to start to compare in the string + \return True if the strings are equal ignoring case. */ + bool equals_substring_ignore_case(const string<T,TAlloc>&other, const s32 sourcePos = 0 ) const + { + if ( (u32) sourcePos >= used ) + return false; + + u32 i; + for( i=0; array[sourcePos + i] && other[i]; ++i) + if (locale_lower( array[sourcePos + i]) != locale_lower(other[i])) + return false; + + return array[sourcePos + i] == 0 && other[i] == 0; + } + + + //! Compares the strings ignoring case. + /** \param other: Other string to compare. + \return True if this string is smaller ignoring case. */ + bool lower_ignore_case(const string<T,TAlloc>& other) const + { + for(u32 i=0; array[i] && other.array[i]; ++i) + { + s32 diff = (s32) locale_lower ( array[i] ) - (s32) locale_lower ( other.array[i] ); + if ( diff ) + return diff < 0; + } + + return used < other.used; + } + + + //! compares the first n characters of the strings + /** \param other Other string to compare. + \param n Number of characters to compare + \return True if the n first characters of both strings are equal. */ + bool equalsn(const string<T,TAlloc>& other, u32 n) const + { + u32 i; + for(i=0; array[i] && other[i] && i < n; ++i) + if (array[i] != other[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same length + return (i == n) || (used == other.used); + } + + + //! compares the first n characters of the strings + /** \param str Other string to compare. + \param n Number of characters to compare + \return True if the n first characters of both strings are equal. */ + bool equalsn(const T* const str, u32 n) const + { + if (!str) + return false; + u32 i; + for(i=0; array[i] && str[i] && i < n; ++i) + if (array[i] != str[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same length + return (i == n) || (array[i] == 0 && str[i] == 0); + } + + + //! Appends a character to this string + /** \param character: Character to append. */ + string<T,TAlloc>& append(T character) + { + if (used + 1 > allocated) + reallocate(used + 1); + + ++used; + + array[used-2] = character; + array[used-1] = 0; + + return *this; + } + + + //! Appends a char string to this string + /** \param other: Char string to append. */ + /** \param length: The length of the string to append. */ + string<T,TAlloc>& append(const T* const other, u32 length=0xffffffff) + { + if (!other) + return *this; + + u32 len = 0; + const T* p = other; + while(*p) + { + ++len; + ++p; + } + if (len > length) + len = length; + + if (used + len > allocated) + reallocate(used + len); + + --used; + ++len; + + for (u32 l=0; l<len; ++l) + array[l+used] = *(other+l); + + used += len; + + return *this; + } + + + //! Appends a string to this string + /** \param other: String to append. */ + string<T,TAlloc>& append(const string<T,TAlloc>& other) + { + if (other.size() == 0) + return *this; + + --used; + u32 len = other.size()+1; + + if (used + len > allocated) + reallocate(used + len); + + for (u32 l=0; l<len; ++l) + array[used+l] = other[l]; + + used += len; + + return *this; + } + + + //! Appends a string of the length l to this string. + /** \param other: other String to append to this string. + \param length: How much characters of the other string to add to this one. */ + string<T,TAlloc>& append(const string<T,TAlloc>& other, u32 length) + { + if (other.size() == 0) + return *this; + + if (other.size() < length) + { + append(other); + return *this; + } + + if (used + length > allocated) + reallocate(used + length); + + --used; + + for (u32 l=0; l<length; ++l) + array[l+used] = other[l]; + used += length; + + // ensure proper termination + array[used]=0; + ++used; + + return *this; + } + + + //! Reserves some memory. + /** \param count: Amount of characters to reserve. */ + void reserve(u32 count) + { + if (count < allocated) + return; + + reallocate(count); + } + + + //! finds first occurrence of character in string + /** \param c: Character to search for. + \return Position where the character has been found, + or -1 if not found. */ + s32 findFirst(T c) const + { + for (u32 i=0; i<used-1; ++i) + if (array[i] == c) + return i; + + return -1; + } + + //! finds first occurrence of a character of a list in string + /** \param c: List of characters to find. For example if the method + should find the first occurrence of 'a' or 'b', this parameter should be "ab". + \param count: Amount of characters in the list. Usually, + this should be strlen(c) + \return Position where one of the characters has been found, + or -1 if not found. */ + s32 findFirstChar(const T* const c, u32 count=1) const + { + if (!c || !count) + return -1; + + for (u32 i=0; i<used-1; ++i) + for (u32 j=0; j<count; ++j) + if (array[i] == c[j]) + return i; + + return -1; + } + + + //! Finds first position of a character not in a given list. + /** \param c: List of characters not to find. For example if the method + should find the first occurrence of a character not 'a' or 'b', this parameter should be "ab". + \param count: Amount of characters in the list. Usually, + this should be strlen(c) + \return Position where the character has been found, + or -1 if not found. */ + template <class B> + s32 findFirstCharNotInList(const B* const c, u32 count=1) const + { + if (!c || !count) + return -1; + + for (u32 i=0; i<used-1; ++i) + { + u32 j; + for (j=0; j<count; ++j) + if (array[i] == c[j]) + break; + + if (j==count) + return i; + } + + return -1; + } + + //! Finds last position of a character not in a given list. + /** \param c: List of characters not to find. For example if the method + should find the first occurrence of a character not 'a' or 'b', this parameter should be "ab". + \param count: Amount of characters in the list. Usually, + this should be strlen(c) + \return Position where the character has been found, + or -1 if not found. */ + template <class B> + s32 findLastCharNotInList(const B* const c, u32 count=1) const + { + if (!c || !count) + return -1; + + for (s32 i=(s32)(used-2); i>=0; --i) + { + u32 j; + for (j=0; j<count; ++j) + if (array[i] == c[j]) + break; + + if (j==count) + return i; + } + + return -1; + } + + //! finds next occurrence of character in string + /** \param c: Character to search for. + \param startPos: Position in string to start searching. + \return Position where the character has been found, + or -1 if not found. */ + s32 findNext(T c, u32 startPos) const + { + for (u32 i=startPos; i<used-1; ++i) + if (array[i] == c) + return i; + + return -1; + } + + + //! finds last occurrence of character in string + /** \param c: Character to search for. + \param start: start to search reverse ( default = -1, on end ) + \return Position where the character has been found, + or -1 if not found. */ + s32 findLast(T c, s32 start = -1) const + { + start = core::clamp ( start < 0 ? (s32)(used) - 2 : start, 0, (s32)(used) - 2 ); + for (s32 i=start; i>=0; --i) + if (array[i] == c) + return i; + + return -1; + } + + //! finds last occurrence of a character of a list in string + /** \param c: List of strings to find. For example if the method + should find the last occurrence of 'a' or 'b', this parameter should be "ab". + \param count: Amount of characters in the list. Usually, + this should be strlen(c) + \return Position where one of the characters has been found, + or -1 if not found. */ + s32 findLastChar(const T* const c, u32 count=1) const + { + if (!c || !count) + return -1; + + for (s32 i=(s32)used-2; i>=0; --i) + for (u32 j=0; j<count; ++j) + if (array[i] == c[j]) + return i; + + return -1; + } + + + //! finds another string in this string + /** \param str: Another string + \param start: Start position of the search + \return Positions where the string has been found, + or -1 if not found. */ + template <class B> + s32 find(const B* const str, const u32 start = 0) const + { + if (str && *str) + { + u32 len = 0; + + while (str[len]) + ++len; + + if (len > used-1) + return -1; + + for (u32 i=start; i<used-len; ++i) + { + u32 j=0; + + while(str[j] && array[i+j] == str[j]) + ++j; + + if (!str[j]) + return i; + } + } + + return -1; + } + + + //! Returns a substring + /** \param begin Start of substring. + \param length Length of substring. + \param make_lower copy only lower case */ + string<T> subString(u32 begin, s32 length, bool make_lower = false ) const + { + // if start after string + // or no proper substring length + if ((length <= 0) || (begin>=size())) + return string<T>(""); + // clamp length to maximal value + if ((length+begin) > size()) + length = size()-begin; + + string<T> o; + o.reserve(length+1); + + s32 i; + if ( !make_lower ) + { + for (i=0; i<length; ++i) + o.array[i] = array[i+begin]; + } + else + { + for (i=0; i<length; ++i) + o.array[i] = locale_lower ( array[i+begin] ); + } + + o.array[length] = 0; + o.used = length + 1; + + return o; + } + + + //! Appends a character to this string + /** \param c Character to append. */ + string<T,TAlloc>& operator += (T c) + { + append(c); + return *this; + } + + + //! Appends a char string to this string + /** \param c Char string to append. */ + string<T,TAlloc>& operator += (const T* const c) + { + append(c); + return *this; + } + + + //! Appends a string to this string + /** \param other String to append. */ + string<T,TAlloc>& operator += (const string<T,TAlloc>& other) + { + append(other); + return *this; + } + + + //! Appends a string representation of a number to this string + /** \param i Number to append. */ + string<T,TAlloc>& operator += (const int i) + { + append(string<T,TAlloc>(i)); + return *this; + } + + + //! Appends a string representation of a number to this string + /** \param i Number to append. */ + string<T,TAlloc>& operator += (const unsigned int i) + { + append(string<T,TAlloc>(i)); + return *this; + } + + + //! Appends a string representation of a number to this string + /** \param i Number to append. */ + string<T,TAlloc>& operator += (const long i) + { + append(string<T,TAlloc>(i)); + return *this; + } + + + //! Appends a string representation of a number to this string + /** \param i Number to append. */ + string<T,TAlloc>& operator += (const unsigned long i) + { + append(string<T,TAlloc>(i)); + return *this; + } + + + //! Appends a string representation of a number to this string + /** \param i Number to append. */ + string<T,TAlloc>& operator += (const double i) + { + append(string<T,TAlloc>(i)); + return *this; + } + + + //! Appends a string representation of a number to this string + /** \param i Number to append. */ + string<T,TAlloc>& operator += (const float i) + { + append(string<T,TAlloc>(i)); + return *this; + } + + + //! Replaces all characters of a special type with another one + /** \param toReplace Character to replace. + \param replaceWith Character replacing the old one. */ + string<T,TAlloc>& replace(T toReplace, T replaceWith) + { + for (u32 i=0; i<used-1; ++i) + if (array[i] == toReplace) + array[i] = replaceWith; + return *this; + } + + + //! Replaces all instances of a string with another one. + /** \param toReplace The string to replace. + \param replaceWith The string replacing the old one. */ + string<T,TAlloc>& replace(const string<T,TAlloc>& toReplace, const string<T,TAlloc>& replaceWith) + { + if (toReplace.size() == 0) + return *this; + + const T* other = toReplace.c_str(); + const T* replace = replaceWith.c_str(); + const u32 other_size = toReplace.size(); + const u32 replace_size = replaceWith.size(); + + // Determine the delta. The algorithm will change depending on the delta. + s32 delta = replace_size - other_size; + + // A character for character replace. The string will not shrink or grow. + if (delta == 0) + { + s32 pos = 0; + while ((pos = find(other, pos)) != -1) + { + for (u32 i = 0; i < replace_size; ++i) + array[pos + i] = replace[i]; + ++pos; + } + return *this; + } + + // We are going to be removing some characters. The string will shrink. + if (delta < 0) + { + u32 i = 0; + for (u32 pos = 0; pos < used; ++i, ++pos) + { + // Is this potentially a match? + if (array[pos] == *other) + { + // Check to see if we have a match. + u32 j; + for (j = 0; j < other_size; ++j) + { + if (array[pos + j] != other[j]) + break; + } + + // If we have a match, replace characters. + if (j == other_size) + { + for (j = 0; j < replace_size; ++j) + array[i + j] = replace[j]; + i += replace_size - 1; + pos += other_size - 1; + continue; + } + } + + // No match found, just copy characters. + array[i] = array[pos]; + } + array[i-1] = 0; + used = i; + + return *this; + } + + // We are going to be adding characters, so the string size will increase. + // Count the number of times toReplace exists in the string so we can allocate the new size. + u32 find_count = 0; + s32 pos = 0; + while ((pos = find(other, pos)) != -1) + { + ++find_count; + ++pos; + } + + // Re-allocate the string now, if needed. + u32 len = delta * find_count; + if (used + len > allocated) + reallocate(used + len); + + // Start replacing. + pos = 0; + while ((pos = find(other, pos)) != -1) + { + T* start = array + pos + other_size - 1; + T* ptr = array + used - 1; + T* end = array + delta + used -1; + + // Shift characters to make room for the string. + while (ptr != start) + { + *end = *ptr; + --ptr; + --end; + } + + // Add the new string now. + for (u32 i = 0; i < replace_size; ++i) + array[pos + i] = replace[i]; + + pos += replace_size; + used += delta; + } + + return *this; + } + + + //! Removes characters from a string. + /** \param c: Character to remove. */ + string<T,TAlloc>& remove(T c) + { + u32 pos = 0; + u32 found = 0; + for (u32 i=0; i<used-1; ++i) + { + if (array[i] == c) + { + ++found; + continue; + } + + array[pos++] = array[i]; + } + used -= found; + array[used-1] = 0; + return *this; + } + + + //! Removes a string from the string. + /** \param toRemove: String to remove. */ + string<T,TAlloc>& remove(const string<T,TAlloc>& toRemove) + { + u32 size = toRemove.size(); + if ( size == 0 ) + return *this; + u32 pos = 0; + u32 found = 0; + for (u32 i=0; i<used-1; ++i) + { + u32 j = 0; + while (j < size) + { + if (array[i + j] != toRemove[j]) + break; + ++j; + } + if (j == size) + { + found += size; + i += size - 1; + continue; + } + + array[pos++] = array[i]; + } + used -= found; + array[used-1] = 0; + return *this; + } + + + //! Removes characters from a string. + /** \param characters: Characters to remove. */ + string<T,TAlloc>& removeChars(const string<T,TAlloc> & characters) + { + if (characters.size() == 0) + return *this; + + u32 pos = 0; + u32 found = 0; + for (u32 i=0; i<used-1; ++i) + { + // Don't use characters.findFirst as it finds the \0, + // causing used to become incorrect. + bool docontinue = false; + for (u32 j=0; j<characters.size(); ++j) + { + if (characters[j] == array[i]) + { + ++found; + docontinue = true; + break; + } + } + if (docontinue) + continue; + + array[pos++] = array[i]; + } + used -= found; + array[used-1] = 0; + + return *this; + } + + + //! Trims the string. + /** Removes the specified characters (by default, Latin-1 whitespace) + from the begining and the end of the string. */ + string<T,TAlloc>& trim(const string<T,TAlloc> & whitespace = " \t\n\r") + { + // find start and end of the substring without the specified characters + const s32 begin = findFirstCharNotInList(whitespace.c_str(), whitespace.used); + if (begin == -1) + return (*this=""); + + const s32 end = findLastCharNotInList(whitespace.c_str(), whitespace.used); + + return (*this = subString(begin, (end +1) - begin)); + } + + + //! Erases a character from the string. + /** May be slow, because all elements + following after the erased element have to be copied. + \param index: Index of element to be erased. */ + string<T,TAlloc>& erase(u32 index) + { + _IRR_DEBUG_BREAK_IF(index>=used) // access violation + + for (u32 i=index+1; i<used; ++i) + array[i-1] = array[i]; + + --used; + return *this; + } + + //! verify the existing string. + string<T,TAlloc>& validate() + { + // terminate on existing null + for (u32 i=0; i<allocated; ++i) + { + if (array[i] == 0) + { + used = i + 1; + return *this; + } + } + + // terminate + if ( allocated > 0 ) + { + used = allocated; + array[used-1] = 0; + } + else + { + used = 0; + } + + return *this; + } + + //! gets the last char of a string or null + T lastChar() const + { + return used > 1 ? array[used-2] : 0; + } + + //! split string into parts. + /** This method will split a string at certain delimiter characters + into the container passed in as reference. The type of the container + has to be given as template parameter. It must provide a push_back and + a size method. + \param ret The result container + \param c C-style string of delimiter characters + \param count Number of delimiter characters + \param ignoreEmptyTokens Flag to avoid empty substrings in the result + container. If two delimiters occur without a character in between, an + empty substring would be placed in the result. If this flag is set, + only non-empty strings are stored. + \param keepSeparators Flag which allows to add the separator to the + result string. If this flag is true, the concatenation of the + substrings results in the original string. Otherwise, only the + characters between the delimiters are returned. + \return The number of resulting substrings + */ + template<class container> + u32 split(container& ret, const T* const c, u32 count=1, bool ignoreEmptyTokens=true, bool keepSeparators=false) const + { + if (!c) + return 0; + + const u32 oldSize=ret.size(); + u32 lastpos = 0; + bool lastWasSeparator = false; + for (u32 i=0; i<used; ++i) + { + bool foundSeparator = false; + for (u32 j=0; j<count; ++j) + { + if (array[i] == c[j]) + { + if ((!ignoreEmptyTokens || i - lastpos != 0) && + !lastWasSeparator) + ret.push_back(string<T,TAlloc>(&array[lastpos], i - lastpos)); + foundSeparator = true; + lastpos = (keepSeparators ? i : i + 1); + break; + } + } + lastWasSeparator = foundSeparator; + } + if ((used - 1) > lastpos) + ret.push_back(string<T,TAlloc>(&array[lastpos], (used - 1) - lastpos)); + return ret.size()-oldSize; + } + +private: + + //! Reallocate the array, make it bigger or smaller + void reallocate(u32 new_size) + { + T* old_array = array; + + array = allocator.allocate(new_size); //new T[new_size]; + allocated = new_size; + + u32 amount = used < new_size ? used : new_size; + for (u32 i=0; i<amount; ++i) + array[i] = old_array[i]; + + if (allocated < used) + used = allocated; + + allocator.deallocate(old_array); // delete [] old_array; + } + + //--- member variables + + T* array; + u32 allocated; + u32 used; + TAlloc allocator; +}; + + +//! Typedef for character strings +typedef string<c8> stringc; + +//! Typedef for wide character strings +typedef string<wchar_t> stringw; + + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/irrTypes.h b/builddir/irrlicht-1.8.1/include/irrTypes.h new file mode 100644 index 0000000..cfeaf84 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/irrTypes.h @@ -0,0 +1,250 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_TYPES_H_INCLUDED__ +#define __IRR_TYPES_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +namespace irr +{ + +//! 8 bit unsigned variable. +/** This is a typedef for unsigned char, it ensures portability of the engine. */ +#if defined(_MSC_VER) || ((__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__)) +typedef unsigned __int8 u8; +#else +typedef unsigned char u8; +#endif + +//! 8 bit signed variable. +/** This is a typedef for signed char, it ensures portability of the engine. */ +#if defined(_MSC_VER) || ((__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__)) +typedef __int8 s8; +#else +typedef signed char s8; +#endif + +//! 8 bit character variable. +/** This is a typedef for char, it ensures portability of the engine. */ +typedef char c8; + + + +//! 16 bit unsigned variable. +/** This is a typedef for unsigned short, it ensures portability of the engine. */ +#if defined(_MSC_VER) || ((__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__)) +typedef unsigned __int16 u16; +#else +typedef unsigned short u16; +#endif + +//! 16 bit signed variable. +/** This is a typedef for signed short, it ensures portability of the engine. */ +#if defined(_MSC_VER) || ((__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__)) +typedef __int16 s16; +#else +typedef signed short s16; +#endif + + + +//! 32 bit unsigned variable. +/** This is a typedef for unsigned int, it ensures portability of the engine. */ +#if defined(_MSC_VER) || ((__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__)) +typedef unsigned __int32 u32; +#else +typedef unsigned int u32; +#endif + +//! 32 bit signed variable. +/** This is a typedef for signed int, it ensures portability of the engine. */ +#if defined(_MSC_VER) || ((__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__)) +typedef __int32 s32; +#else +typedef signed int s32; +#endif + + +#ifdef __IRR_HAS_S64 +//! 64 bit unsigned variable. +/** This is a typedef for 64bit uint, it ensures portability of the engine. */ +#if defined(_MSC_VER) || ((__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__)) +typedef unsigned __int64 u64; +#elif __GNUC__ +#if __WORDSIZE == 64 +typedef unsigned long int u64; +#else +__extension__ typedef unsigned long long u64; +#endif +#else +typedef unsigned long long u64; +#endif + +//! 64 bit signed variable. +/** This is a typedef for 64bit int, it ensures portability of the engine. */ +#if defined(_MSC_VER) || ((__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__)) +typedef __int64 s64; +#elif __GNUC__ +#if __WORDSIZE == 64 +typedef long int s64; +#else +__extension__ typedef long long s64; +#endif +#else +typedef long long s64; +#endif +#endif // __IRR_HAS_S64 + + + +//! 32 bit floating point variable. +/** This is a typedef for float, it ensures portability of the engine. */ +typedef float f32; + +//! 64 bit floating point variable. +/** This is a typedef for double, it ensures portability of the engine. */ +typedef double f64; + + +} // end namespace irr + + +#include <wchar.h> +#ifdef _IRR_WINDOWS_API_ +//! Defines for s{w,n}printf because these methods do not match the ISO C +//! standard on Windows platforms, but it does on all others. +//! These should be int snprintf(char *str, size_t size, const char *format, ...); +//! and int swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...); +#if defined(_MSC_VER) && _MSC_VER > 1310 && !defined (_WIN32_WCE) +#define swprintf swprintf_s +#define snprintf sprintf_s +#elif !defined(__CYGWIN__) +#define swprintf _snwprintf +#define snprintf _snprintf +#endif + +// define the wchar_t type if not already built in. +#ifdef _MSC_VER +#ifndef _WCHAR_T_DEFINED +//! A 16 bit wide character type. +/** + Defines the wchar_t-type. + In VS6, its not possible to tell + the standard compiler to treat wchar_t as a built-in type, and + sometimes we just don't want to include the huge stdlib.h or wchar.h, + so we'll use this. +*/ +typedef unsigned short wchar_t; +#define _WCHAR_T_DEFINED +#endif // wchar is not defined +#endif // microsoft compiler +#endif // _IRR_WINDOWS_API_ + +namespace irr +{ + +//! Type name for character type used by the file system. +/** Should the wide character version of the FileSystem be used it is a +16 bit character variable. Used for unicode Filesystem and unicode strings. +Else it is a 8 bit character variable. Used for ansi Filesystem and non-unicode +strings +*/ +#if defined(_IRR_WCHAR_FILESYSTEM) + typedef wchar_t fschar_t; + #define _IRR_TEXT(X) L##X +#else + typedef char fschar_t; + #define _IRR_TEXT(X) X +#endif + +} // end namespace irr + +//! define a break macro for debugging. +#if defined(_DEBUG) +#if defined(_IRR_WINDOWS_API_) && defined(_MSC_VER) && !defined (_WIN32_WCE) + #if defined(WIN64) || defined(_WIN64) // using portable common solution for x64 configuration + #include <crtdbg.h> + #define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) if (_CONDITION_) {_CrtDbgBreak();} + #else + #define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) if (_CONDITION_) {_asm int 3} + #endif +#else +#include "assert.h" +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) assert( !(_CONDITION_) ); +#endif +#else +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) +#endif + +//! Defines a deprecated macro which generates a warning at compile time +/** The usage is simple +For typedef: typedef _IRR_DEPRECATED_ int test1; +For classes/structs: class _IRR_DEPRECATED_ test2 { ... }; +For methods: class test3 { _IRR_DEPRECATED_ virtual void foo() {} }; +For functions: template<class T> _IRR_DEPRECATED_ void test4(void) {} +**/ +#if defined(IGNORE_DEPRECATED_WARNING) +#define _IRR_DEPRECATED_ +#elif _MSC_VER >= 1310 //vs 2003 or higher +#define _IRR_DEPRECATED_ __declspec(deprecated) +#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) // all versions above 3.0 should support this feature +#define _IRR_DEPRECATED_ __attribute__ ((deprecated)) +#else +#define _IRR_DEPRECATED_ +#endif + +//! Defines a small statement to work around a microsoft compiler bug. +/** The microsoft compiler 7.0 - 7.1 has a bug: +When you call unmanaged code that returns a bool type value of false from managed code, +the return value may appear as true. See +http://support.microsoft.com/default.aspx?kbid=823071 for details. +Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400*/ +#if defined(_IRR_WINDOWS_API_) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400) +#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX __asm mov eax,100 +#else +#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX +#endif // _IRR_MANAGED_MARSHALLING_BUGFIX + + +// memory debugging +#if defined(_DEBUG) && defined(IRRLICHT_EXPORTS) && defined(_MSC_VER) && \ + (_MSC_VER > 1299) && !defined(_IRR_DONT_DO_MEMORY_DEBUGGING_HERE) && !defined(_WIN32_WCE) + + #define CRTDBG_MAP_ALLOC + #define _CRTDBG_MAP_ALLOC + #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) + #include <stdlib.h> + #include <crtdbg.h> + #define new DEBUG_CLIENTBLOCK +#endif + +// disable truncated debug information warning in visual studio 6 by default +#if defined(_MSC_VER) && (_MSC_VER < 1300 ) +#pragma warning( disable: 4786) +#endif // _MSC + + +//! ignore VC8 warning deprecated +/** The microsoft compiler */ +#if defined(_IRR_WINDOWS_API_) && defined(_MSC_VER) && (_MSC_VER >= 1400) + //#pragma warning( disable: 4996) + //#define _CRT_SECURE_NO_DEPRECATE 1 + //#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif + + +//! creates four CC codes used in Irrlicht for simple ids +/** some compilers can create those by directly writing the +code like 'code', but some generate warnings so we use this macro here */ +#define MAKE_IRR_ID(c0, c1, c2, c3) \ + ((irr::u32)(irr::u8)(c0) | ((irr::u32)(irr::u8)(c1) << 8) | \ + ((irr::u32)(irr::u8)(c2) << 16) | ((irr::u32)(irr::u8)(c3) << 24 )) + +#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +#define _strcmpi(a,b) strcmpi(a,b) +#endif + +#endif // __IRR_TYPES_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/irrXML.h b/builddir/irrlicht-1.8.1/include/irrXML.h new file mode 100644 index 0000000..2ca2d31 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/irrXML.h @@ -0,0 +1,575 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h + +#ifndef __IRR_XML_H_INCLUDED__ +#define __IRR_XML_H_INCLUDED__ + +#include <stdio.h> +#include "IrrCompileConfig.h" + +/** \mainpage irrXML 1.2 API documentation + <div align="center"><img src="logobig.png" ></div> + + \section intro Introduction + + Welcome to the irrXML API documentation. + Here you'll find any information you'll need to develop applications with + irrXML. If you look for a tutorial on how to start, take a look at the \ref irrxmlexample, + at the homepage of irrXML at <A HREF="http://www.ambiera.com/irrxml/">www.ambiera.com/irrxml/</A> + or into the SDK in the directory example. + + irrXML is intended to be a high speed and easy-to-use XML Parser for C++, and + this documentation is an important part of it. If you have any questions or + suggestions, just send a email to the author of the engine, Nikolaus Gebhardt + (niko (at) irrlicht3d.org). For more informations about this parser, see \ref history. + + \section features Features + + irrXML provides forward-only, read-only + access to a stream of non validated XML data. It was fully implemented by + Nikolaus Gebhardt. Its current features are: + + - It it fast as lighting and has very low memory usage. It was + developed with the intention of being used in 3D games, as it already has been. + - irrXML is very small: It only consists of 60 KB of code and can be added easily + to your existing project. + - Of course, it is platform independent and works with lots of compilers. + - It is able to parse ASCII, UTF-8, UTF-16 and UTF-32 text files, both in + little and big endian format. + - Independent of the input file format, the parser can return all strings in ASCII, UTF-8, + UTF-16 and UTF-32 format. + - With its optional file access abstraction it has the advantage that it can read not + only from files but from any type of data (memory, network, ...). For example when + used with the Irrlicht Engine, it directly reads from compressed .zip files. + - Just like the Irrlicht Engine for which it was originally created, it is extremely easy + to use. + - It has no external dependencies, it does not even need the STL. + + Although irrXML has some strenghts, it currently also has the following limitations: + + - The input xml file is not validated and assumed to be correct. + + \section irrxmlexample Example + + The following code demonstrates the basic usage of irrXML. A simple xml + file like this is parsed: + \code + <?xml version="1.0"?> + <config> + <!-- This is a config file for the mesh viewer --> + <model file="dwarf.dea" /> + <messageText caption="Irrlicht Engine Mesh Viewer"> + Welcome to the Mesh Viewer of the "Irrlicht Engine". + </messageText> + </config> + \endcode + + The code for parsing this file would look like this: + \code + #include <irrXML.h> + using namespace irr; // irrXML is located in the namespace irr::io + using namespace io; + + #include <string> // we use STL strings to store data in this example + + void main() + { + // create the reader using one of the factory functions + + IrrXMLReader* xml = createIrrXMLReader("config.xml"); + + // strings for storing the data we want to get out of the file + std::string modelFile; + std::string messageText; + std::string caption; + + // parse the file until end reached + + while(xml && xml->read()) + { + switch(xml->getNodeType()) + { + case EXN_TEXT: + // in this xml file, the only text which occurs is the messageText + messageText = xml->getNodeData(); + break; + case EXN_ELEMENT: + { + if (!strcmp("model", xml->getNodeName())) + modelFile = xml->getAttributeValue("file"); + else + if (!strcmp("messageText", xml->getNodeName())) + caption = xml->getAttributeValue("caption"); + } + break; + } + } + + // delete the xml parser after usage + delete xml; + } + \endcode + + \section howto How to use + + Simply add the source files in the /src directory of irrXML to your project. Done. + + \section license License + + The irrXML license is based on the zlib license. Basicly, this means you can do with + irrXML whatever you want: + + Copyright (C) 2002-2012 Nikolaus Gebhardt + + 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. + + \section history History + + As lots of references in this documentation and the source show, this xml + parser has originally been a part of the + <A HREF="http://irrlicht.sourceforge.net" >Irrlicht Engine</A>. But because + the parser has become very useful with the latest release, people asked for a + separate version of it, to be able to use it in non Irrlicht projects. With + irrXML 1.0, this has now been done. +*/ + +namespace irr +{ +namespace io +{ + //! Enumeration of all supported source text file formats + enum ETEXT_FORMAT + { + //! ASCII, file without byte order mark, or not a text file + ETF_ASCII, + + //! UTF-8 format + ETF_UTF8, + + //! UTF-16 format, big endian + ETF_UTF16_BE, + + //! UTF-16 format, little endian + ETF_UTF16_LE, + + //! UTF-32 format, big endian + ETF_UTF32_BE, + + //! UTF-32 format, little endian + ETF_UTF32_LE + }; + + + //! Enumeration for all xml nodes which are parsed by IrrXMLReader + enum EXML_NODE + { + //! No xml node. This is usually the node if you did not read anything yet. + EXN_NONE, + + //! An xml element such as <foo> + EXN_ELEMENT, + + //! End of an xml element such as </foo> + EXN_ELEMENT_END, + + //! Text within an xml element: <foo> this is the text. </foo> + //! Also text between 2 xml elements: </foo> this is the text. <foo> + EXN_TEXT, + + //! An xml comment like <!-- I am a comment --> or a DTD definition. + EXN_COMMENT, + + //! An xml cdata section like <![CDATA[ this is some CDATA ]]> + EXN_CDATA, + + //! Unknown element. + EXN_UNKNOWN + }; + + //! Callback class for file read abstraction. + /** With this, it is possible to make the xml parser read in other + things than just files. The Irrlicht engine is using this for example to + read xml from compressed .zip files. To make the parser read in + any other data, derive a class from this interface, implement the + two methods to read your data and give a pointer to an instance of + your implementation when calling createIrrXMLReader(), + createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */ + class IFileReadCallBack + { + public: + + //! Destructor + virtual ~IFileReadCallBack() {} + + //! Reads an amount of bytes from the file. + /** \param buffer: Pointer to buffer where to read bytes will be written to. + \param sizeToRead: Amount of bytes to read from the file. + \return Returns how much bytes were read. */ + virtual int read(void* buffer, int sizeToRead) = 0; + + //! Returns size of file in bytes + virtual long getSize() const = 0; + }; + + //! Empty class to be used as parent class for IrrXMLReader. + /** If you need another class as base class for the xml reader, you can do this by creating + the reader using for example new CXMLReaderImpl<char, YourBaseClass>(yourcallback); + The Irrlicht Engine for example needs IReferenceCounted as base class for every object to + let it automaticly reference countend, hence it replaces IXMLBase with IReferenceCounted. + See irrXML.cpp on how this can be done in detail. */ + class IXMLBase + { + }; + + //! Interface providing easy read access to a XML file. + /** You can create an instance of this reader using one of the factory functions + createIrrXMLReader(), createIrrXMLReaderUTF16() and createIrrXMLReaderUTF32(). + If using the parser from the Irrlicht Engine, please use IFileSystem::createXMLReader() + instead. + For a detailed intro how to use the parser, see \ref irrxmlexample and \ref features. + + The typical usage of this parser looks like this: + \code + #include <irrXML.h> + using namespace irr; // irrXML is located in the namespace irr::io + using namespace io; + + void main() + { + // create the reader using one of the factory functions + IrrXMLReader* xml = createIrrXMLReader("config.xml"); + + if (xml == 0) + return; // file could not be opened + + // parse the file until end reached + while(xml->read()) + { + // based on xml->getNodeType(), do something. + } + + // delete the xml parser after usage + delete xml; + } + \endcode + See \ref irrxmlexample for a more detailed example. + */ + template<class char_type, class super_class> + class IIrrXMLReader : public super_class + { + public: + + //! Destructor + virtual ~IIrrXMLReader() {} + + //! Reads forward to the next xml node. + /** \return Returns false, if there was no further node. */ + virtual bool read() = 0; + + //! Returns the type of the current XML node. + virtual EXML_NODE getNodeType() const = 0; + + //! Returns attribute count of the current XML node. + /** This is usually + non null if the current node is EXN_ELEMENT, and the element has attributes. + \return Returns amount of attributes of this xml node. */ + virtual unsigned int getAttributeCount() const = 0; + + //! Returns name of an attribute. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Name of the attribute, 0 if an attribute with this index does not exist. */ + virtual const char_type* getAttributeName(int idx) const = 0; + + //! Returns the value of an attribute. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute, 0 if an attribute with this index does not exist. */ + virtual const char_type* getAttributeValue(int idx) const = 0; + + //! Returns the value of an attribute. + /** \param name: Name of the attribute. + \return Value of the attribute, 0 if an attribute with this name does not exist. */ + virtual const char_type* getAttributeValue(const char_type* name) const = 0; + + //! Returns the value of an attribute in a safe way. + /** Like getAttributeValue(), but does not + return 0 if the attribute does not exist. An empty string ("") is returned then. + \param name: Name of the attribute. + \return Value of the attribute, and "" if an attribute with this name does not exist */ + virtual const char_type* getAttributeValueSafe(const char_type* name) const = 0; + + //! Returns the value of an attribute as integer. + /** \param name Name of the attribute. + \return Value of the attribute as integer, and 0 if an attribute with this name does not exist or + the value could not be interpreted as integer. */ + virtual int getAttributeValueAsInt(const char_type* name) const = 0; + + //! Returns the value of an attribute as integer. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute as integer, and 0 if an attribute with this index does not exist or + the value could not be interpreted as integer. */ + virtual int getAttributeValueAsInt(int idx) const = 0; + + //! Returns the value of an attribute as float. + /** \param name: Name of the attribute. + \return Value of the attribute as float, and 0 if an attribute with this name does not exist or + the value could not be interpreted as float. */ + virtual float getAttributeValueAsFloat(const char_type* name) const = 0; + + //! Returns the value of an attribute as float. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute as float, and 0 if an attribute with this index does not exist or + the value could not be interpreted as float. */ + virtual float getAttributeValueAsFloat(int idx) const = 0; + + //! Returns the name of the current node. + /** Only valid, if the node type is EXN_ELEMENT. + \return Name of the current node or 0 if the node has no name. */ + virtual const char_type* getNodeName() const = 0; + + //! Returns data of the current node. + /** Only valid if the node has some + data and it is of type EXN_TEXT, EXN_COMMENT, EXN_CDATA or EXN_UNKNOWN. */ + virtual const char_type* getNodeData() const = 0; + + //! Returns if an element is an empty element, like <foo /> + virtual bool isEmptyElement() const = 0; + + //! Returns format of the source xml file. + /** It is not necessary to use + this method because the parser will convert the input file format + to the format wanted by the user when creating the parser. This + method is useful to get/display additional informations. */ + virtual ETEXT_FORMAT getSourceFormat() const = 0; + + //! Returns format of the strings returned by the parser. + /** This will be UTF8 for example when you created a parser with + IrrXMLReaderUTF8() and UTF32 when it has been created using + IrrXMLReaderUTF32. It should not be necessary to call this + method and only exists for informational purposes. */ + virtual ETEXT_FORMAT getParserFormat() const = 0; + }; + + + template <typename T> + struct xmlChar + { + T c; + xmlChar<T>() {} + xmlChar<T>(char in) : c(static_cast<T>(in)) {} + xmlChar<T>(wchar_t in) : c(static_cast<T>(in)) {} +#if defined(__BORLANDC__) + // Note - removing explicit for borland was to get it to even compile. + // There haven't been any kind of tests for that besides that. + xmlChar<T>(unsigned char in) : c(static_cast<T>(in)) {} + xmlChar<T>(unsigned short in) : c(static_cast<T>(in)) {} + xmlChar<T>(unsigned int in) : c(static_cast<T>(in)) {} + xmlChar<T>(unsigned long in) : c(static_cast<T>(in)) {} +#else + explicit xmlChar<T>(unsigned char in) : c(static_cast<T>(in)) {} + explicit xmlChar<T>(unsigned short in) : c(static_cast<T>(in)) {} + explicit xmlChar<T>(unsigned int in) : c(static_cast<T>(in)) {} + explicit xmlChar<T>(unsigned long in) : c(static_cast<T>(in)) {} +#endif + operator T() const { return c; } + void operator=(int t) { c=static_cast<T>(t); } + }; + + //! defines the utf-16 type. + /** Not using wchar_t for this because + wchar_t has 16 bit on windows and 32 bit on other operating systems. */ + typedef xmlChar<unsigned short> char16; + + //! defines the utf-32 type. + /** Not using wchar_t for this because + wchar_t has 16 bit on windows and 32 bit on other operating systems. */ + typedef xmlChar<unsigned int> char32; + + //! A UTF-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8 by this parser. + The file to read can be in any format, it will be converted to UTF-8 if it is not + in this format. + Create an instance of this with createIrrXMLReader(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader<char, IXMLBase> IrrXMLReader; + + //! A UTF-16 xml parser. + /** This means that all character data will be returned in UTF-16 by this parser. + The file to read can be in any format, it will be converted to UTF-16 if it is not + in this format. + Create an instance of this with createIrrXMLReaderUTF16(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader<char16, IXMLBase> IrrXMLReaderUTF16; + + //! A UTF-32 xml parser. + /** This means that all character data will be returned in UTF-32 by this parser. + The file to read can be in any format, it will be converted to UTF-32 if it is not + in this format. + Create an instance of this with createIrrXMLReaderUTF32(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader<char32, IXMLBase> IrrXMLReaderUTF32; + + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. + The file to read can be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(const char* filename); + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can + be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(FILE* file); + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can + be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \param deleteCallback: if true, the callback will be deleted after the file + has been read. Otherwise the caller si responsible for cleaning it up. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(IFileReadCallBack* callback, + bool deleteCallback = false); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that + all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(const char* filename); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(FILE* file); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \param deleteCallback: if true, the callback will be deleted after the file + has been read. Otherwise the caller si responsible for cleaning it up. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(IFileReadCallBack* callback, + bool deleteCallback = false); + + + //! Creates an instance of an UFT-32 xml parser. + /** This means that all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(const char* filename); + + //! Creates an instance of an UFT-32 xml parser. + /** This means that all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + if you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(FILE* file); + + //! Creates an instance of an UFT-32 xml parser. + /** This means that + all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \param deleteCallback: if true, the callback will be deleted after the file + has been read. Otherwise the caller si responsible for cleaning it up. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(IFileReadCallBack* callback, + bool deleteCallback = false); + + + /*! \file irrXML.h + \brief Header file of the irrXML, the Irrlicht XML parser. + + This file includes everything needed for using irrXML, + the XML parser of the Irrlicht Engine. To use irrXML, + you only need to include this file in your project: + + \code + #include <irrXML.h> + \endcode + + It is also common to use the two namespaces in which irrXML is included, + directly after including irrXML.h: + + \code + #include <irrXML.h> + using namespace irr; + using namespace io; + \endcode + */ + +} // end namespace io +} // end namespace irr + +#endif // __IRR_XML_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/irrlicht.h b/builddir/irrlicht-1.8.1/include/irrlicht.h new file mode 100644 index 0000000..184c896 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/irrlicht.h @@ -0,0 +1,394 @@ +/* irrlicht.h -- interface of the 'Irrlicht Engine' + + Copyright (C) 2002-2012 Nikolaus Gebhardt + + 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. + + Please note that the Irrlicht Engine is based in part on the work of the + Independent JPEG Group, the zlib and the libPng. This means that if you use + the Irrlicht Engine in your product, you must acknowledge somewhere in your + documentation that you've used the IJG code. It would also be nice to mention + that you use the Irrlicht Engine, the zlib and libPng. See the README files + in the jpeglib, the zlib and libPng for further informations. +*/ + +#ifndef __IRRLICHT_H_INCLUDED__ +#define __IRRLICHT_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#include "aabbox3d.h" +#include "CDynamicMeshBuffer.h" +#include "CIndexBuffer.h" +#include "CMeshBuffer.h" +#include "coreutil.h" +#include "CVertexBuffer.h" +#include "dimension2d.h" +#include "ECullingTypes.h" +#include "EDebugSceneTypes.h" +#include "EDriverFeatures.h" +#include "EDriverTypes.h" +#include "EGUIAlignment.h" +#include "EGUIElementTypes.h" +#include "EHardwareBufferFlags.h" +#include "EMaterialFlags.h" +#include "EMaterialTypes.h" +#include "EMeshWriterEnums.h" +#include "EMessageBoxFlags.h" +#include "ESceneNodeAnimatorTypes.h" +#include "ESceneNodeTypes.h" +#include "ETerrainElements.h" +#include "fast_atof.h" +#include "heapsort.h" +#include "IAnimatedMesh.h" +#include "IAnimatedMeshMD2.h" +#include "IAnimatedMeshMD3.h" +#include "IAnimatedMeshSceneNode.h" +#include "IAttributeExchangingObject.h" +#include "IAttributes.h" +#include "IBillboardSceneNode.h" +#include "IBillboardTextSceneNode.h" +#include "IBoneSceneNode.h" +#include "ICameraSceneNode.h" +#include "ICursorControl.h" +#include "IDummyTransformationSceneNode.h" +#include "IDynamicMeshBuffer.h" +#include "IEventReceiver.h" +#include "IFileList.h" +#include "IFileSystem.h" +#include "IGeometryCreator.h" +#include "IGPUProgrammingServices.h" +#include "IGUIButton.h" +#include "IGUICheckBox.h" +#include "IGUIColorSelectDialog.h" +#include "IGUIComboBox.h" +#include "IGUIContextMenu.h" +#include "IGUIEditBox.h" +#include "IGUIElement.h" +#include "IGUIElementFactory.h" +#include "IGUIEnvironment.h" +#include "IGUIFileOpenDialog.h" +#include "IGUIFont.h" +#include "IGUIFontBitmap.h" +#include "IGUIImage.h" +#include "IGUIInOutFader.h" +#include "IGUIListBox.h" +#include "IGUIMeshViewer.h" +#include "IGUIScrollBar.h" +#include "IGUISkin.h" +#include "IGUISpinBox.h" +#include "IGUISpriteBank.h" +#include "IGUIStaticText.h" +#include "IGUITabControl.h" +#include "IGUITable.h" +#include "IGUIToolbar.h" +#include "IGUIWindow.h" +#include "IGUITreeView.h" +#include "IImage.h" +#include "IImageLoader.h" +#include "IImageWriter.h" +#include "IIndexBuffer.h" +#include "ILightSceneNode.h" +#include "ILogger.h" +#include "IMaterialRenderer.h" +#include "IMaterialRendererServices.h" +#include "IMesh.h" +#include "IMeshBuffer.h" +#include "IMeshCache.h" +#include "IMeshLoader.h" +#include "IMeshManipulator.h" +#include "IMeshSceneNode.h" +#include "IMeshWriter.h" +#include "IColladaMeshWriter.h" +#include "IMetaTriangleSelector.h" +#include "IOSOperator.h" +#include "IParticleSystemSceneNode.h" // also includes all emitters and attractors +#include "IQ3LevelMesh.h" +#include "IQ3Shader.h" +#include "IReadFile.h" +#include "IReferenceCounted.h" +#include "irrArray.h" +#include "IRandomizer.h" +#include "IrrlichtDevice.h" +#include "irrList.h" +#include "irrMap.h" +#include "irrMath.h" +#include "irrString.h" +#include "irrTypes.h" +#include "path.h" +#include "irrXML.h" +#include "ISceneCollisionManager.h" +#include "ISceneLoader.h" +#include "ISceneManager.h" +#include "ISceneNode.h" +#include "ISceneNodeAnimator.h" +#include "ISceneNodeAnimatorCameraFPS.h" +#include "ISceneNodeAnimatorCameraMaya.h" +#include "ISceneNodeAnimatorCollisionResponse.h" +#include "ISceneNodeAnimatorFactory.h" +#include "ISceneNodeFactory.h" +#include "ISceneUserDataSerializer.h" +#include "IShaderConstantSetCallBack.h" +#include "IShadowVolumeSceneNode.h" +#include "ISkinnedMesh.h" +#include "ITerrainSceneNode.h" +#include "ITextSceneNode.h" +#include "ITexture.h" +#include "ITimer.h" +#include "ITriangleSelector.h" +#include "IVertexBuffer.h" +#include "IVideoDriver.h" +#include "IVideoModeList.h" +#include "IVolumeLightSceneNode.h" +#include "IWriteFile.h" +#include "IXMLReader.h" +#include "IXMLWriter.h" +#include "ILightManager.h" +#include "Keycodes.h" +#include "line2d.h" +#include "line3d.h" +#include "matrix4.h" +#include "plane3d.h" +#include "position2d.h" +#include "quaternion.h" +#include "rect.h" +#include "S3DVertex.h" +#include "SAnimatedMesh.h" +#include "SceneParameters.h" +#include "SColor.h" +#include "SExposedVideoData.h" +#include "SIrrCreationParameters.h" +#include "SKeyMap.h" +#include "SLight.h" +#include "SMaterial.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "SMeshBufferLightMap.h" +#include "SMeshBufferTangents.h" +#include "SParticle.h" +#include "SSharedMeshBuffer.h" +#include "SSkinMeshBuffer.h" +#include "SVertexIndex.h" +#include "SViewFrustum.h" +#include "triangle3d.h" +#include "vector2d.h" +#include "vector3d.h" + +/*! \mainpage Irrlicht Engine 1.8 API documentation + * + * <div align="center"><img src="logobig.png" ></div> + * + * \section intro Introduction + * + * Welcome to the Irrlicht Engine API documentation. + * Here you'll find any information you'll need to develop applications with + * the Irrlicht Engine. If you are looking for a tutorial on how to start, you'll + * find some on the homepage of the Irrlicht Engine at + * <A HREF="http://irrlicht.sourceforge.net" >irrlicht.sourceforge.net</A> + * or inside the SDK in the examples directory. + * + * The Irrlicht Engine is intended to be an easy-to-use 3d engine, so + * this documentation is an important part of it. If you have any questions or + * suggestions, just send a email to the author of the engine, Nikolaus Gebhardt + * (niko (at) irrlicht3d.org). + * + * + * \section links Links + * + * <A HREF="namespaces.html">Namespaces</A>: A very good place to start reading + * the documentation.<BR> + * <A HREF="annotated.html">Class list</A>: List of all classes with descriptions.<BR> + * <A HREF="functions.html">Class members</A>: Good place to find forgotten features.<BR> + * + * \section irrexample Short example + * + * A simple application, starting up the engine, loading a Quake 2 animated + * model file and the corresponding texture, animating and displaying it + * in front of a blue background and placing a user controlable 3d camera + * would look like the following code. I think this example shows the usage + * of the engine quite well: + * + * \code + * #include <irrlicht.h> + * using namespace irr; + * + * int main() + * { + * // start up the engine + * IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D8, + * core::dimension2d<u32>(640,480)); + * + * video::IVideoDriver* driver = device->getVideoDriver(); + * scene::ISceneManager* scenemgr = device->getSceneManager(); + * + * device->setWindowCaption(L"Hello World!"); + * + * // load and show quake2 .md2 model + * scene::ISceneNode* node = scenemgr->addAnimatedMeshSceneNode( + * scenemgr->getMesh("quake2model.md2")); + * + * // if everything worked, add a texture and disable lighting + * if (node) + * { + * node->setMaterialTexture(0, driver->getTexture("texture.bmp")); + * node->setMaterialFlag(video::EMF_LIGHTING, false); + * } + * + * // add a first person shooter style user controlled camera + * scenemgr->addCameraSceneNodeFPS(); + * + * // draw everything + * while(device->run() && driver) + * { + * driver->beginScene(true, true, video::SColor(255,0,0,255)); + * scenemgr->drawAll(); + * driver->endScene(); + * } + * + * // delete device + * device->drop(); + * return 0; + * } + * \endcode + * + * Irrlicht can load a lot of file formats automaticly, see irr::scene::ISceneManager::getMesh() + * for a detailed list. So if you would like to replace the simple blue screen background by + * a cool Quake 3 Map, optimized by an octree, just insert this code + * somewhere before the while loop: + * + * \code + * // add .pk3 archive to the file system + * device->getFileSystem()->addZipFileArchive("quake3map.pk3"); + * + * // load .bsp file and show it using an octree + * scenemgr->addOctreeSceneNode( + * scenemgr->getMesh("quake3map.bsp")); + * \endcode + * + * As you can see, the engine uses namespaces. Everything in the engine is + * placed into the namespace 'irr', but there are also 5 sub namespaces. + * You can find a list of all namespaces with descriptions at the + * <A HREF="namespaces.html"> namespaces page</A>. + * This is also a good place to start reading the documentation. If you + * don't want to write the namespace names all the time, just use all namespaces like + * this: + * \code + * using namespace core; + * using namespace scene; + * using namespace video; + * using namespace io; + * using namespace gui; + * \endcode + * + * There is a lot more the engine can do, but I hope this gave a short + * overview over the basic features of the engine. For more examples, please take + * a look into the examples directory of the SDK. + */ + +#include "SIrrCreationParameters.h" + +//! Everything in the Irrlicht Engine can be found in this namespace. +namespace irr +{ + //! Creates an Irrlicht device. The Irrlicht device is the root object for using the engine. + /** If you need more parameters to be passed to the creation of the Irrlicht Engine device, + use the createDeviceEx() function. + \param deviceType: Type of the device. This can currently be video::EDT_NULL, + video::EDT_SOFTWARE, video::EDT_BURNINGSVIDEO, video::EDT_DIRECT3D8, video::EDT_DIRECT3D9 and video::EDT_OPENGL. + \param windowSize: Size of the window or the video mode in fullscreen mode. + \param bits: Bits per pixel in fullscreen mode. Ignored if windowed mode. + \param fullscreen: Should be set to true if the device should run in fullscreen. Otherwise + the device runs in windowed mode. + \param stencilbuffer: Specifies if the stencil buffer should be enabled. Set this to true, + if you want the engine be able to draw stencil buffer shadows. Note that not all + devices are able to use the stencil buffer. If they don't no shadows will be drawn. + \param vsync: Specifies vertical syncronisation: If set to true, the driver will wait + for the vertical retrace period, otherwise not. + \param receiver: A user created event receiver. + \return Returns pointer to the created IrrlichtDevice or null if the + device could not be created. + */ + extern "C" IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDevice( + video::E_DRIVER_TYPE deviceType = video::EDT_SOFTWARE, + // parantheses are necessary for some compilers + const core::dimension2d<u32>& windowSize = (core::dimension2d<u32>(640,480)), + u32 bits = 16, + bool fullscreen = false, + bool stencilbuffer = false, + bool vsync = false, + IEventReceiver* receiver = 0); + + //! typedef for Function Pointer + typedef IrrlichtDevice* (IRRCALLCONV *funcptr_createDevice )( + video::E_DRIVER_TYPE deviceType, + const core::dimension2d<u32>& windowSize, + u32 bits, + bool fullscreen, + bool stencilbuffer, + bool vsync, + IEventReceiver* receiver); + + + //! Creates an Irrlicht device with the option to specify advanced parameters. + /** Usually you should used createDevice() for creating an Irrlicht Engine device. + Use this function only if you wish to specify advanced parameters like a window + handle in which the device should be created. + \param parameters: Structure containing advanced parameters for the creation of the device. + See irr::SIrrlichtCreationParameters for details. + \return Returns pointer to the created IrrlichtDevice or null if the + device could not be created. */ + extern "C" IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx( + const SIrrlichtCreationParameters& parameters); + + //! typedef for Function Pointer + typedef IrrlichtDevice* (IRRCALLCONV *funcptr_createDeviceEx )( const SIrrlichtCreationParameters& parameters ); + + + // THE FOLLOWING IS AN EMPTY LIST OF ALL SUB NAMESPACES + // EXISTING ONLY FOR THE DOCUMENTATION SOFTWARE DOXYGEN. + + //! Basic classes such as vectors, planes, arrays, lists, and so on can be found in this namespace. + namespace core + { + } + + //! The gui namespace contains useful classes for easy creation of a graphical user interface. + namespace gui + { + } + + //! This namespace provides interfaces for input/output: Reading and writing files, accessing zip archives, xml files, ... + namespace io + { + } + + //! All scene management can be found in this namespace: Mesh loading, special scene nodes like octrees and billboards, ... + namespace scene + { + } + + //! The video namespace contains classes for accessing the video driver. All 2d and 3d rendering is done here. + namespace video + { + } +} + +/*! \file irrlicht.h + \brief Main header file of the irrlicht, the only file needed to include. +*/ + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/irrpack.h b/builddir/irrlicht-1.8.1/include/irrpack.h new file mode 100644 index 0000000..29a16fe --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/irrpack.h @@ -0,0 +1,39 @@ +// Copyright (C) 2007-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// include this file right before the data structures to be 1-aligned +// and add to each structure the PACK_STRUCT define just like this: +// struct mystruct +// { +// ... +// } PACK_STRUCT; +// Always include the irrunpack.h file right after the last type declared +// like this, and do not put any other types with different alignment +// in between! + +// byte-align structures +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma warning(disable: 4103) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +#elif defined( __DMC__ ) +# pragma pack( push, 1 ) +# define PACK_STRUCT +#elif defined( __GNUC__ ) + // Using pragma pack might work with earlier gcc versions already, but + // it started to be necessary with gcc 4.7 on mingw unless compiled with -mno-ms-bitfields. + // And I found some hints on the web that older gcc versions on the other hand had sometimes + // trouble with pragma pack while they worked with __attribute__((packed)). +# if (__GNUC__ >= 4 ) && (__GNUC_MINOR__ >= 7) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +# else +# define PACK_STRUCT __attribute__((packed)) + #endif +#else +# error compiler not supported +#endif + diff --git a/builddir/irrlicht-1.8.1/include/irrunpack.h b/builddir/irrlicht-1.8.1/include/irrunpack.h new file mode 100644 index 0000000..80a5a69 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/irrunpack.h @@ -0,0 +1,20 @@ +// Copyright (C) 2007-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// include this file to switch back to default alignment +// file belongs to irrpack.h, see there for more info + +// Default alignment +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop, packing ) +#elif defined (__DMC__) +# pragma pack( pop ) +#elif defined( __GNUC__ ) +# if (__GNUC__ >= 4 ) && (__GNUC_MINOR__ >= 7) +# pragma pack( pop, packing ) +# endif +#endif + +#undef PACK_STRUCT + diff --git a/builddir/irrlicht-1.8.1/include/line2d.h b/builddir/irrlicht-1.8.1/include/line2d.h new file mode 100644 index 0000000..22590dc --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/line2d.h @@ -0,0 +1,274 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_LINE_2D_H_INCLUDED__ +#define __IRR_LINE_2D_H_INCLUDED__ + +#include "irrTypes.h" +#include "vector2d.h" + +namespace irr +{ +namespace core +{ + +//! 2D line between two points with intersection methods. +template <class T> +class line2d +{ + public: + //! Default constructor for line going from (0,0) to (1,1). + line2d() : start(0,0), end(1,1) {} + //! Constructor for line between the two points. + line2d(T xa, T ya, T xb, T yb) : start(xa, ya), end(xb, yb) {} + //! Constructor for line between the two points given as vectors. + line2d(const vector2d<T>& start, const vector2d<T>& end) : start(start), end(end) {} + //! Copy constructor. + line2d(const line2d<T>& other) : start(other.start), end(other.end) {} + + // operators + + line2d<T> operator+(const vector2d<T>& point) const { return line2d<T>(start + point, end + point); } + line2d<T>& operator+=(const vector2d<T>& point) { start += point; end += point; return *this; } + + line2d<T> operator-(const vector2d<T>& point) const { return line2d<T>(start - point, end - point); } + line2d<T>& operator-=(const vector2d<T>& point) { start -= point; end -= point; return *this; } + + bool operator==(const line2d<T>& other) const + { return (start==other.start && end==other.end) || (end==other.start && start==other.end);} + bool operator!=(const line2d<T>& other) const + { return !(start==other.start && end==other.end) || (end==other.start && start==other.end);} + + // functions + //! Set this line to new line going through the two points. + void setLine(const T& xa, const T& ya, const T& xb, const T& yb){start.set(xa, ya); end.set(xb, yb);} + //! Set this line to new line going through the two points. + void setLine(const vector2d<T>& nstart, const vector2d<T>& nend){start.set(nstart); end.set(nend);} + //! Set this line to new line given as parameter. + void setLine(const line2d<T>& line){start.set(line.start); end.set(line.end);} + + //! Get length of line + /** \return Length of the line. */ + T getLength() const { return start.getDistanceFrom(end); } + + //! Get squared length of the line + /** \return Squared length of line. */ + T getLengthSQ() const { return start.getDistanceFromSQ(end); } + + //! Get middle of the line + /** \return center of the line. */ + vector2d<T> getMiddle() const + { + return (start + end)/(T)2; + } + + //! Get the vector of the line. + /** \return The vector of the line. */ + vector2d<T> getVector() const { return vector2d<T>(end.X - start.X, end.Y - start.Y); } + + //! Tests if this line intersects with another line. + /** \param l: Other line to test intersection with. + \param checkOnlySegments: Default is to check intersection between the begin and endpoints. + When set to false the function will check for the first intersection point when extending the lines. + \param out: If there is an intersection, the location of the + intersection will be stored in this vector. + \return True if there is an intersection, false if not. */ + bool intersectWith(const line2d<T>& l, vector2d<T>& out, bool checkOnlySegments=true) const + { + // Uses the method given at: + // http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ + const f32 commonDenominator = (f32)(l.end.Y - l.start.Y)*(end.X - start.X) - + (l.end.X - l.start.X)*(end.Y - start.Y); + + const f32 numeratorA = (f32)(l.end.X - l.start.X)*(start.Y - l.start.Y) - + (l.end.Y - l.start.Y)*(start.X -l.start.X); + + const f32 numeratorB = (f32)(end.X - start.X)*(start.Y - l.start.Y) - + (end.Y - start.Y)*(start.X -l.start.X); + + if(equals(commonDenominator, 0.f)) + { + // The lines are either coincident or parallel + // if both numerators are 0, the lines are coincident + if(equals(numeratorA, 0.f) && equals(numeratorB, 0.f)) + { + // Try and find a common endpoint + if(l.start == start || l.end == start) + out = start; + else if(l.end == end || l.start == end) + out = end; + // now check if the two segments are disjunct + else if (l.start.X>start.X && l.end.X>start.X && l.start.X>end.X && l.end.X>end.X) + return false; + else if (l.start.Y>start.Y && l.end.Y>start.Y && l.start.Y>end.Y && l.end.Y>end.Y) + return false; + else if (l.start.X<start.X && l.end.X<start.X && l.start.X<end.X && l.end.X<end.X) + return false; + else if (l.start.Y<start.Y && l.end.Y<start.Y && l.start.Y<end.Y && l.end.Y<end.Y) + return false; + // else the lines are overlapping to some extent + else + { + // find the points which are not contributing to the + // common part + vector2d<T> maxp; + vector2d<T> minp; + if ((start.X>l.start.X && start.X>l.end.X && start.X>end.X) || (start.Y>l.start.Y && start.Y>l.end.Y && start.Y>end.Y)) + maxp=start; + else if ((end.X>l.start.X && end.X>l.end.X && end.X>start.X) || (end.Y>l.start.Y && end.Y>l.end.Y && end.Y>start.Y)) + maxp=end; + else if ((l.start.X>start.X && l.start.X>l.end.X && l.start.X>end.X) || (l.start.Y>start.Y && l.start.Y>l.end.Y && l.start.Y>end.Y)) + maxp=l.start; + else + maxp=l.end; + if (maxp != start && ((start.X<l.start.X && start.X<l.end.X && start.X<end.X) || (start.Y<l.start.Y && start.Y<l.end.Y && start.Y<end.Y))) + minp=start; + else if (maxp != end && ((end.X<l.start.X && end.X<l.end.X && end.X<start.X) || (end.Y<l.start.Y && end.Y<l.end.Y && end.Y<start.Y))) + minp=end; + else if (maxp != l.start && ((l.start.X<start.X && l.start.X<l.end.X && l.start.X<end.X) || (l.start.Y<start.Y && l.start.Y<l.end.Y && l.start.Y<end.Y))) + minp=l.start; + else + minp=l.end; + + // one line is contained in the other. Pick the center + // of the remaining points, which overlap for sure + out = core::vector2d<T>(); + if (start != maxp && start != minp) + out += start; + if (end != maxp && end != minp) + out += end; + if (l.start != maxp && l.start != minp) + out += l.start; + if (l.end != maxp && l.end != minp) + out += l.end; + out.X = (T)(out.X/2); + out.Y = (T)(out.Y/2); + } + + return true; // coincident + } + + return false; // parallel + } + + // Get the point of intersection on this line, checking that + // it is within the line segment. + const f32 uA = numeratorA / commonDenominator; + if(checkOnlySegments && (uA < 0.f || uA > 1.f) ) + return false; // Outside the line segment + + const f32 uB = numeratorB / commonDenominator; + if(checkOnlySegments && (uB < 0.f || uB > 1.f)) + return false; // Outside the line segment + + // Calculate the intersection point. + out.X = (T)(start.X + uA * (end.X - start.X)); + out.Y = (T)(start.Y + uA * (end.Y - start.Y)); + return true; + } + + //! Get unit vector of the line. + /** \return Unit vector of this line. */ + vector2d<T> getUnitVector() const + { + T len = (T)(1.0 / getLength()); + return vector2d<T>((end.X - start.X) * len, (end.Y - start.Y) * len); + } + + //! Get angle between this line and given line. + /** \param l Other line for test. + \return Angle in degrees. */ + f64 getAngleWith(const line2d<T>& l) const + { + vector2d<T> vect = getVector(); + vector2d<T> vect2 = l.getVector(); + return vect.getAngleWith(vect2); + } + + //! Tells us if the given point lies to the left, right, or on the line. + /** \return 0 if the point is on the line + <0 if to the left, or >0 if to the right. */ + T getPointOrientation(const vector2d<T>& point) const + { + return ( (end.X - start.X) * (point.Y - start.Y) - + (point.X - start.X) * (end.Y - start.Y) ); + } + + //! Check if the given point is a member of the line + /** \return True if point is between start and end, else false. */ + bool isPointOnLine(const vector2d<T>& point) const + { + T d = getPointOrientation(point); + return (d == 0 && point.isBetweenPoints(start, end)); + } + + //! Check if the given point is between start and end of the line. + /** Assumes that the point is already somewhere on the line. */ + bool isPointBetweenStartAndEnd(const vector2d<T>& point) const + { + return point.isBetweenPoints(start, end); + } + + //! Get the closest point on this line to a point + /** \param checkOnlySegments: Default (true) is to return a point on the line-segment (between begin and end) of the line. + When set to false the function will check for the first the closest point on the the line even when outside the segment. */ + vector2d<T> getClosestPoint(const vector2d<T>& point, bool checkOnlySegments=true) const + { + vector2d<f64> c((f64)(point.X-start.X), (f64)(point.Y- start.Y)); + vector2d<f64> v((f64)(end.X-start.X), (f64)(end.Y-start.Y)); + f64 d = v.getLength(); + if ( d == 0 ) // can't tell much when the line is just a single point + return start; + v /= d; + f64 t = v.dotProduct(c); + + if ( checkOnlySegments ) + { + if (t < 0) return vector2d<T>((T)start.X, (T)start.Y); + if (t > d) return vector2d<T>((T)end.X, (T)end.Y); + } + + v *= t; + return vector2d<T>((T)(start.X + v.X), (T)(start.Y + v.Y)); + } + + //! Start point of the line. + vector2d<T> start; + //! End point of the line. + vector2d<T> end; +}; + + // partial specialization to optimize <f32> lines (avoiding casts) + template <> + inline vector2df line2d<irr::f32>::getClosestPoint(const vector2df& point, bool checkOnlySegments) const + { + vector2df c = point - start; + vector2df v = end - start; + f32 d = (f32)v.getLength(); + if ( d == 0 ) // can't tell much when the line is just a single point + return start; + v /= d; + f32 t = v.dotProduct(c); + + if ( checkOnlySegments ) + { + if (t < 0) return start; + if (t > d) return end; + } + + v *= t; + return start + v; + } + + + //! Typedef for an f32 line. + typedef line2d<f32> line2df; + //! Typedef for an integer line. + typedef line2d<s32> line2di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/line3d.h b/builddir/irrlicht-1.8.1/include/line3d.h new file mode 100644 index 0000000..5e1437a --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/line3d.h @@ -0,0 +1,144 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_LINE_3D_H_INCLUDED__ +#define __IRR_LINE_3D_H_INCLUDED__ + +#include "irrTypes.h" +#include "vector3d.h" + +namespace irr +{ +namespace core +{ + +//! 3D line between two points with intersection methods. +template <class T> +class line3d +{ + public: + + //! Default constructor + /** line from (0,0,0) to (1,1,1) */ + line3d() : start(0,0,0), end(1,1,1) {} + //! Constructor with two points + line3d(T xa, T ya, T za, T xb, T yb, T zb) : start(xa, ya, za), end(xb, yb, zb) {} + //! Constructor with two points as vectors + line3d(const vector3d<T>& start, const vector3d<T>& end) : start(start), end(end) {} + + // operators + + line3d<T> operator+(const vector3d<T>& point) const { return line3d<T>(start + point, end + point); } + line3d<T>& operator+=(const vector3d<T>& point) { start += point; end += point; return *this; } + + line3d<T> operator-(const vector3d<T>& point) const { return line3d<T>(start - point, end - point); } + line3d<T>& operator-=(const vector3d<T>& point) { start -= point; end -= point; return *this; } + + bool operator==(const line3d<T>& other) const + { return (start==other.start && end==other.end) || (end==other.start && start==other.end);} + bool operator!=(const line3d<T>& other) const + { return !(start==other.start && end==other.end) || (end==other.start && start==other.end);} + + // functions + //! Set this line to a new line going through the two points. + void setLine(const T& xa, const T& ya, const T& za, const T& xb, const T& yb, const T& zb) + {start.set(xa, ya, za); end.set(xb, yb, zb);} + //! Set this line to a new line going through the two points. + void setLine(const vector3d<T>& nstart, const vector3d<T>& nend) + {start.set(nstart); end.set(nend);} + //! Set this line to new line given as parameter. + void setLine(const line3d<T>& line) + {start.set(line.start); end.set(line.end);} + + //! Get length of line + /** \return Length of line. */ + T getLength() const { return start.getDistanceFrom(end); } + + //! Get squared length of line + /** \return Squared length of line. */ + T getLengthSQ() const { return start.getDistanceFromSQ(end); } + + //! Get middle of line + /** \return Center of line. */ + vector3d<T> getMiddle() const + { + return (start + end)/(T)2; + } + + //! Get vector of line + /** \return vector of line. */ + vector3d<T> getVector() const + { + return end - start; + } + + //! Check if the given point is between start and end of the line. + /** Assumes that the point is already somewhere on the line. + \param point The point to test. + \return True if point is on the line between start and end, else false. + */ + bool isPointBetweenStartAndEnd(const vector3d<T>& point) const + { + return point.isBetweenPoints(start, end); + } + + //! Get the closest point on this line to a point + /** \param point The point to compare to. + \return The nearest point which is part of the line. */ + vector3d<T> getClosestPoint(const vector3d<T>& point) const + { + vector3d<T> c = point - start; + vector3d<T> v = end - start; + T d = (T)v.getLength(); + v /= d; + T t = v.dotProduct(c); + + if (t < (T)0.0) + return start; + if (t > d) + return end; + + v *= t; + return start + v; + } + + //! Check if the line intersects with a shpere + /** \param sorigin: Origin of the shpere. + \param sradius: Radius of the sphere. + \param outdistance: The distance to the first intersection point. + \return True if there is an intersection. + If there is one, the distance to the first intersection point + is stored in outdistance. */ + bool getIntersectionWithSphere(vector3d<T> sorigin, T sradius, f64& outdistance) const + { + const vector3d<T> q = sorigin - start; + T c = q.getLength(); + T v = q.dotProduct(getVector().normalize()); + T d = sradius * sradius - (c*c - v*v); + + if (d < 0.0) + return false; + + outdistance = v - core::squareroot ( d ); + return true; + } + + // member variables + + //! Start point of line + vector3d<T> start; + //! End point of line + vector3d<T> end; +}; + + //! Typedef for an f32 line. + typedef line3d<f32> line3df; + //! Typedef for an integer line. + typedef line3d<s32> line3di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/matrix4.h b/builddir/irrlicht-1.8.1/include/matrix4.h new file mode 100644 index 0000000..b04827f --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/matrix4.h @@ -0,0 +1,2242 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_MATRIX_H_INCLUDED__ +#define __IRR_MATRIX_H_INCLUDED__ + +#include "irrMath.h" +#include "vector3d.h" +#include "vector2d.h" +#include "plane3d.h" +#include "aabbox3d.h" +#include "rect.h" +#include "irrString.h" + +// enable this to keep track of changes to the matrix +// and make simpler identity check for seldomly changing matrices +// otherwise identity check will always compare the elements +//#define USE_MATRIX_TEST + +// this is only for debugging purposes +//#define USE_MATRIX_TEST_DEBUG + +#if defined( USE_MATRIX_TEST_DEBUG ) + +struct MatrixTest +{ + MatrixTest () : ID(0), Calls(0) {} + char buf[256]; + int Calls; + int ID; +}; +static MatrixTest MTest; + +#endif + +namespace irr +{ +namespace core +{ + + //! 4x4 matrix. Mostly used as transformation matrix for 3d calculations. + /** The matrix is a D3D style matrix, row major with translations in the 4th row. */ + template <class T> + class CMatrix4 + { + public: + + //! Constructor Flags + enum eConstructor + { + EM4CONST_NOTHING = 0, + EM4CONST_COPY, + EM4CONST_IDENTITY, + EM4CONST_TRANSPOSED, + EM4CONST_INVERSE, + EM4CONST_INVERSE_TRANSPOSED + }; + + //! Default constructor + /** \param constructor Choose the initialization style */ + CMatrix4( eConstructor constructor = EM4CONST_IDENTITY ); + //! Copy constructor + /** \param other Other matrix to copy from + \param constructor Choose the initialization style */ + CMatrix4(const CMatrix4<T>& other, eConstructor constructor = EM4CONST_COPY); + + //! Simple operator for directly accessing every element of the matrix. + T& operator()(const s32 row, const s32 col) + { +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return M[ row * 4 + col ]; + } + + //! Simple operator for directly accessing every element of the matrix. + const T& operator()(const s32 row, const s32 col) const { return M[row * 4 + col]; } + + //! Simple operator for linearly accessing every element of the matrix. + T& operator[](u32 index) + { +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return M[index]; + } + + //! Simple operator for linearly accessing every element of the matrix. + const T& operator[](u32 index) const { return M[index]; } + + //! Sets this matrix equal to the other matrix. + inline CMatrix4<T>& operator=(const CMatrix4<T> &other); + + //! Sets all elements of this matrix to the value. + inline CMatrix4<T>& operator=(const T& scalar); + + //! Returns pointer to internal array + const T* pointer() const { return M; } + T* pointer() + { +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return M; + } + + //! Returns true if other matrix is equal to this matrix. + bool operator==(const CMatrix4<T> &other) const; + + //! Returns true if other matrix is not equal to this matrix. + bool operator!=(const CMatrix4<T> &other) const; + + //! Add another matrix. + CMatrix4<T> operator+(const CMatrix4<T>& other) const; + + //! Add another matrix. + CMatrix4<T>& operator+=(const CMatrix4<T>& other); + + //! Subtract another matrix. + CMatrix4<T> operator-(const CMatrix4<T>& other) const; + + //! Subtract another matrix. + CMatrix4<T>& operator-=(const CMatrix4<T>& other); + + //! set this matrix to the product of two matrices + /** Calculate b*a */ + inline CMatrix4<T>& setbyproduct(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b ); + + //! Set this matrix to the product of two matrices + /** Calculate b*a, no optimization used, + use it if you know you never have a identity matrix */ + CMatrix4<T>& setbyproduct_nocheck(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b ); + + //! Multiply by another matrix. + /** Calculate other*this */ + CMatrix4<T> operator*(const CMatrix4<T>& other) const; + + //! Multiply by another matrix. + /** Calculate and return other*this */ + CMatrix4<T>& operator*=(const CMatrix4<T>& other); + + //! Multiply by scalar. + CMatrix4<T> operator*(const T& scalar) const; + + //! Multiply by scalar. + CMatrix4<T>& operator*=(const T& scalar); + + //! Set matrix to identity. + inline CMatrix4<T>& makeIdentity(); + + //! Returns true if the matrix is the identity matrix + inline bool isIdentity() const; + + //! Returns true if the matrix is orthogonal + inline bool isOrthogonal() const; + + //! Returns true if the matrix is the identity matrix + bool isIdentity_integer_base () const; + + //! Set the translation of the current matrix. Will erase any previous values. + CMatrix4<T>& setTranslation( const vector3d<T>& translation ); + + //! Gets the current translation + vector3d<T> getTranslation() const; + + //! Set the inverse translation of the current matrix. Will erase any previous values. + CMatrix4<T>& setInverseTranslation( const vector3d<T>& translation ); + + //! Make a rotation matrix from Euler angles. The 4th row and column are unmodified. + inline CMatrix4<T>& setRotationRadians( const vector3d<T>& rotation ); + + //! Make a rotation matrix from Euler angles. The 4th row and column are unmodified. + CMatrix4<T>& setRotationDegrees( const vector3d<T>& rotation ); + + //! Returns the rotation, as set by setRotation(). + /** This code was orginally written by by Chev. */ + core::vector3d<T> getRotationDegrees() const; + + //! Make an inverted rotation matrix from Euler angles. + /** The 4th row and column are unmodified. */ + inline CMatrix4<T>& setInverseRotationRadians( const vector3d<T>& rotation ); + + //! Make an inverted rotation matrix from Euler angles. + /** The 4th row and column are unmodified. */ + inline CMatrix4<T>& setInverseRotationDegrees( const vector3d<T>& rotation ); + + //! Make a rotation matrix from angle and axis, assuming left handed rotation. + /** The 4th row and column are unmodified. */ + inline CMatrix4<T>& setRotationAxisRadians(const T& angle, const vector3d<T>& axis); + + //! Set Scale + CMatrix4<T>& setScale( const vector3d<T>& scale ); + + //! Set Scale + CMatrix4<T>& setScale( const T scale ) { return setScale(core::vector3d<T>(scale,scale,scale)); } + + //! Get Scale + core::vector3d<T> getScale() const; + + //! Translate a vector by the inverse of the translation part of this matrix. + void inverseTranslateVect( vector3df& vect ) const; + + //! Rotate a vector by the inverse of the rotation part of this matrix. + void inverseRotateVect( vector3df& vect ) const; + + //! Rotate a vector by the rotation part of this matrix. + void rotateVect( vector3df& vect ) const; + + //! An alternate transform vector method, writing into a second vector + void rotateVect(core::vector3df& out, const core::vector3df& in) const; + + //! An alternate transform vector method, writing into an array of 3 floats + void rotateVect(T *out,const core::vector3df &in) const; + + //! Transforms the vector by this matrix + void transformVect( vector3df& vect) const; + + //! Transforms input vector by this matrix and stores result in output vector + void transformVect( vector3df& out, const vector3df& in ) const; + + //! An alternate transform vector method, writing into an array of 4 floats + void transformVect(T *out,const core::vector3df &in) const; + + //! An alternate transform vector method, reading from and writing to an array of 3 floats + void transformVec3(T *out, const T * in) const; + + //! Translate a vector by the translation part of this matrix. + void translateVect( vector3df& vect ) const; + + //! Transforms a plane by this matrix + void transformPlane( core::plane3d<f32> &plane) const; + + //! Transforms a plane by this matrix + void transformPlane( const core::plane3d<f32> &in, core::plane3d<f32> &out) const; + + //! Transforms a axis aligned bounding box + /** The result box of this operation may not be accurate at all. For + correct results, use transformBoxEx() */ + void transformBox(core::aabbox3d<f32>& box) const; + + //! Transforms a axis aligned bounding box + /** The result box of this operation should by accurate, but this operation + is slower than transformBox(). */ + void transformBoxEx(core::aabbox3d<f32>& box) const; + + //! Multiplies this matrix by a 1x4 matrix + void multiplyWith1x4Matrix(T* matrix) const; + + //! Calculates inverse of matrix. Slow. + /** \return Returns false if there is no inverse matrix.*/ + bool makeInverse(); + + + //! Inverts a primitive matrix which only contains a translation and a rotation + /** \param out: where result matrix is written to. */ + bool getInversePrimitive ( CMatrix4<T>& out ) const; + + //! Gets the inversed matrix of this one + /** \param out: where result matrix is written to. + \return Returns false if there is no inverse matrix. */ + bool getInverse(CMatrix4<T>& out) const; + + //! Builds a right-handed perspective projection matrix based on a field of view + CMatrix4<T>& buildProjectionMatrixPerspectiveFovRH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar); + + //! Builds a left-handed perspective projection matrix based on a field of view + CMatrix4<T>& buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar); + + //! Builds a left-handed perspective projection matrix based on a field of view, with far plane at infinity + CMatrix4<T>& buildProjectionMatrixPerspectiveFovInfinityLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 epsilon=0); + + //! Builds a right-handed perspective projection matrix. + CMatrix4<T>& buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar); + + //! Builds a left-handed perspective projection matrix. + CMatrix4<T>& buildProjectionMatrixPerspectiveLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar); + + //! Builds a left-handed orthogonal projection matrix. + CMatrix4<T>& buildProjectionMatrixOrthoLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar); + + //! Builds a right-handed orthogonal projection matrix. + CMatrix4<T>& buildProjectionMatrixOrthoRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar); + + //! Builds a left-handed look-at matrix. + CMatrix4<T>& buildCameraLookAtMatrixLH( + const vector3df& position, + const vector3df& target, + const vector3df& upVector); + + //! Builds a right-handed look-at matrix. + CMatrix4<T>& buildCameraLookAtMatrixRH( + const vector3df& position, + const vector3df& target, + const vector3df& upVector); + + //! Builds a matrix that flattens geometry into a plane. + /** \param light: light source + \param plane: plane into which the geometry if flattened into + \param point: value between 0 and 1, describing the light source. + If this is 1, it is a point light, if it is 0, it is a directional light. */ + CMatrix4<T>& buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point=1.0f); + + //! Builds a matrix which transforms a normalized Device Coordinate to Device Coordinates. + /** Used to scale <-1,-1><1,1> to viewport, for example from <-1,-1> <1,1> to the viewport <0,0><0,640> */ + CMatrix4<T>& buildNDCToDCMatrix( const core::rect<s32>& area, f32 zScale); + + //! Creates a new matrix as interpolated matrix from two other ones. + /** \param b: other matrix to interpolate with + \param time: Must be a value between 0 and 1. */ + CMatrix4<T> interpolate(const core::CMatrix4<T>& b, f32 time) const; + + //! Gets transposed matrix + CMatrix4<T> getTransposed() const; + + //! Gets transposed matrix + inline void getTransposed( CMatrix4<T>& dest ) const; + + //! Builds a matrix that rotates from one vector to another + /** \param from: vector to rotate from + \param to: vector to rotate to + */ + CMatrix4<T>& buildRotateFromTo(const core::vector3df& from, const core::vector3df& to); + + //! Builds a combined matrix which translates to a center before rotation and translates from origin afterwards + /** \param center Position to rotate around + \param translate Translation applied after the rotation + */ + void setRotationCenter(const core::vector3df& center, const core::vector3df& translate); + + //! Builds a matrix which rotates a source vector to a look vector over an arbitrary axis + /** \param camPos: viewer position in world coo + \param center: object position in world-coo and rotation pivot + \param translation: object final translation from center + \param axis: axis to rotate about + \param from: source vector to rotate from + */ + void buildAxisAlignedBillboard(const core::vector3df& camPos, + const core::vector3df& center, + const core::vector3df& translation, + const core::vector3df& axis, + const core::vector3df& from); + + /* + construct 2D Texture transformations + rotate about center, scale, and transform. + */ + //! Set to a texture transformation matrix with the given parameters. + CMatrix4<T>& buildTextureTransform( f32 rotateRad, + const core::vector2df &rotatecenter, + const core::vector2df &translate, + const core::vector2df &scale); + + //! Set texture transformation rotation + /** Rotate about z axis, recenter at (0.5,0.5). + Doesn't clear other elements than those affected + \param radAngle Angle in radians + \return Altered matrix */ + CMatrix4<T>& setTextureRotationCenter( f32 radAngle ); + + //! Set texture transformation translation + /** Doesn't clear other elements than those affected. + \param x Offset on x axis + \param y Offset on y axis + \return Altered matrix */ + CMatrix4<T>& setTextureTranslate( f32 x, f32 y ); + + //! Set texture transformation translation, using a transposed representation + /** Doesn't clear other elements than those affected. + \param x Offset on x axis + \param y Offset on y axis + \return Altered matrix */ + CMatrix4<T>& setTextureTranslateTransposed( f32 x, f32 y ); + + //! Set texture transformation scale + /** Doesn't clear other elements than those affected. + \param sx Scale factor on x axis + \param sy Scale factor on y axis + \return Altered matrix. */ + CMatrix4<T>& setTextureScale( f32 sx, f32 sy ); + + //! Set texture transformation scale, and recenter at (0.5,0.5) + /** Doesn't clear other elements than those affected. + \param sx Scale factor on x axis + \param sy Scale factor on y axis + \return Altered matrix. */ + CMatrix4<T>& setTextureScaleCenter( f32 sx, f32 sy ); + + //! Sets all matrix data members at once + CMatrix4<T>& setM(const T* data); + + //! Sets if the matrix is definitely identity matrix + void setDefinitelyIdentityMatrix( bool isDefinitelyIdentityMatrix); + + //! Gets if the matrix is definitely identity matrix + bool getDefinitelyIdentityMatrix() const; + + //! Compare two matrices using the equal method + bool equals(const core::CMatrix4<T>& other, const T tolerance=(T)ROUNDING_ERROR_f64) const; + + private: + //! Matrix data, stored in row-major order + T M[16]; +#if defined ( USE_MATRIX_TEST ) + //! Flag is this matrix is identity matrix + mutable u32 definitelyIdentityMatrix; +#endif +#if defined ( USE_MATRIX_TEST_DEBUG ) + u32 id; + mutable u32 calls; +#endif + + }; + + // Default constructor + template <class T> + inline CMatrix4<T>::CMatrix4( eConstructor constructor ) +#if defined ( USE_MATRIX_TEST ) + : definitelyIdentityMatrix(BIT_UNTESTED) +#endif +#if defined ( USE_MATRIX_TEST_DEBUG ) + ,id ( MTest.ID++), calls ( 0 ) +#endif + { + switch ( constructor ) + { + case EM4CONST_NOTHING: + case EM4CONST_COPY: + break; + case EM4CONST_IDENTITY: + case EM4CONST_INVERSE: + default: + makeIdentity(); + break; + } + } + + // Copy constructor + template <class T> + inline CMatrix4<T>::CMatrix4( const CMatrix4<T>& other, eConstructor constructor) +#if defined ( USE_MATRIX_TEST ) + : definitelyIdentityMatrix(BIT_UNTESTED) +#endif +#if defined ( USE_MATRIX_TEST_DEBUG ) + ,id ( MTest.ID++), calls ( 0 ) +#endif + { + switch ( constructor ) + { + case EM4CONST_IDENTITY: + makeIdentity(); + break; + case EM4CONST_NOTHING: + break; + case EM4CONST_COPY: + *this = other; + break; + case EM4CONST_TRANSPOSED: + other.getTransposed(*this); + break; + case EM4CONST_INVERSE: + if (!other.getInverse(*this)) + memset(M, 0, 16*sizeof(T)); + break; + case EM4CONST_INVERSE_TRANSPOSED: + if (!other.getInverse(*this)) + memset(M, 0, 16*sizeof(T)); + else + *this=getTransposed(); + break; + } + } + + //! Add another matrix. + template <class T> + inline CMatrix4<T> CMatrix4<T>::operator+(const CMatrix4<T>& other) const + { + CMatrix4<T> temp ( EM4CONST_NOTHING ); + + temp[0] = M[0]+other[0]; + temp[1] = M[1]+other[1]; + temp[2] = M[2]+other[2]; + temp[3] = M[3]+other[3]; + temp[4] = M[4]+other[4]; + temp[5] = M[5]+other[5]; + temp[6] = M[6]+other[6]; + temp[7] = M[7]+other[7]; + temp[8] = M[8]+other[8]; + temp[9] = M[9]+other[9]; + temp[10] = M[10]+other[10]; + temp[11] = M[11]+other[11]; + temp[12] = M[12]+other[12]; + temp[13] = M[13]+other[13]; + temp[14] = M[14]+other[14]; + temp[15] = M[15]+other[15]; + + return temp; + } + + //! Add another matrix. + template <class T> + inline CMatrix4<T>& CMatrix4<T>::operator+=(const CMatrix4<T>& other) + { + M[0]+=other[0]; + M[1]+=other[1]; + M[2]+=other[2]; + M[3]+=other[3]; + M[4]+=other[4]; + M[5]+=other[5]; + M[6]+=other[6]; + M[7]+=other[7]; + M[8]+=other[8]; + M[9]+=other[9]; + M[10]+=other[10]; + M[11]+=other[11]; + M[12]+=other[12]; + M[13]+=other[13]; + M[14]+=other[14]; + M[15]+=other[15]; + + return *this; + } + + //! Subtract another matrix. + template <class T> + inline CMatrix4<T> CMatrix4<T>::operator-(const CMatrix4<T>& other) const + { + CMatrix4<T> temp ( EM4CONST_NOTHING ); + + temp[0] = M[0]-other[0]; + temp[1] = M[1]-other[1]; + temp[2] = M[2]-other[2]; + temp[3] = M[3]-other[3]; + temp[4] = M[4]-other[4]; + temp[5] = M[5]-other[5]; + temp[6] = M[6]-other[6]; + temp[7] = M[7]-other[7]; + temp[8] = M[8]-other[8]; + temp[9] = M[9]-other[9]; + temp[10] = M[10]-other[10]; + temp[11] = M[11]-other[11]; + temp[12] = M[12]-other[12]; + temp[13] = M[13]-other[13]; + temp[14] = M[14]-other[14]; + temp[15] = M[15]-other[15]; + + return temp; + } + + //! Subtract another matrix. + template <class T> + inline CMatrix4<T>& CMatrix4<T>::operator-=(const CMatrix4<T>& other) + { + M[0]-=other[0]; + M[1]-=other[1]; + M[2]-=other[2]; + M[3]-=other[3]; + M[4]-=other[4]; + M[5]-=other[5]; + M[6]-=other[6]; + M[7]-=other[7]; + M[8]-=other[8]; + M[9]-=other[9]; + M[10]-=other[10]; + M[11]-=other[11]; + M[12]-=other[12]; + M[13]-=other[13]; + M[14]-=other[14]; + M[15]-=other[15]; + + return *this; + } + + //! Multiply by scalar. + template <class T> + inline CMatrix4<T> CMatrix4<T>::operator*(const T& scalar) const + { + CMatrix4<T> temp ( EM4CONST_NOTHING ); + + temp[0] = M[0]*scalar; + temp[1] = M[1]*scalar; + temp[2] = M[2]*scalar; + temp[3] = M[3]*scalar; + temp[4] = M[4]*scalar; + temp[5] = M[5]*scalar; + temp[6] = M[6]*scalar; + temp[7] = M[7]*scalar; + temp[8] = M[8]*scalar; + temp[9] = M[9]*scalar; + temp[10] = M[10]*scalar; + temp[11] = M[11]*scalar; + temp[12] = M[12]*scalar; + temp[13] = M[13]*scalar; + temp[14] = M[14]*scalar; + temp[15] = M[15]*scalar; + + return temp; + } + + //! Multiply by scalar. + template <class T> + inline CMatrix4<T>& CMatrix4<T>::operator*=(const T& scalar) + { + M[0]*=scalar; + M[1]*=scalar; + M[2]*=scalar; + M[3]*=scalar; + M[4]*=scalar; + M[5]*=scalar; + M[6]*=scalar; + M[7]*=scalar; + M[8]*=scalar; + M[9]*=scalar; + M[10]*=scalar; + M[11]*=scalar; + M[12]*=scalar; + M[13]*=scalar; + M[14]*=scalar; + M[15]*=scalar; + + return *this; + } + + //! Multiply by another matrix. + template <class T> + inline CMatrix4<T>& CMatrix4<T>::operator*=(const CMatrix4<T>& other) + { +#if defined ( USE_MATRIX_TEST ) + // do checks on your own in order to avoid copy creation + if ( !other.isIdentity() ) + { + if ( this->isIdentity() ) + { + return (*this = other); + } + else + { + CMatrix4<T> temp ( *this ); + return setbyproduct_nocheck( temp, other ); + } + } + return *this; +#else + CMatrix4<T> temp ( *this ); + return setbyproduct_nocheck( temp, other ); +#endif + } + + //! multiply by another matrix + // set this matrix to the product of two other matrices + // goal is to reduce stack use and copy + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setbyproduct_nocheck(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b ) + { + const T *m1 = other_a.M; + const T *m2 = other_b.M; + + M[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3]; + M[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3]; + M[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3]; + M[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3]; + + M[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7]; + M[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7]; + M[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7]; + M[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7]; + + M[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11]; + M[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11]; + M[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11]; + M[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11]; + + M[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15]; + M[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15]; + M[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15]; + M[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15]; +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + //! multiply by another matrix + // set this matrix to the product of two other matrices + // goal is to reduce stack use and copy + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setbyproduct(const CMatrix4<T>& other_a, const CMatrix4<T>& other_b ) + { +#if defined ( USE_MATRIX_TEST ) + if ( other_a.isIdentity () ) + return (*this = other_b); + else + if ( other_b.isIdentity () ) + return (*this = other_a); + else + return setbyproduct_nocheck(other_a,other_b); +#else + return setbyproduct_nocheck(other_a,other_b); +#endif + } + + //! multiply by another matrix + template <class T> + inline CMatrix4<T> CMatrix4<T>::operator*(const CMatrix4<T>& m2) const + { +#if defined ( USE_MATRIX_TEST ) + // Testing purpose.. + if ( this->isIdentity() ) + return m2; + if ( m2.isIdentity() ) + return *this; +#endif + + CMatrix4<T> m3 ( EM4CONST_NOTHING ); + + const T *m1 = M; + + m3[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3]; + m3[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3]; + m3[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3]; + m3[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3]; + + m3[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7]; + m3[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7]; + m3[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7]; + m3[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7]; + + m3[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11]; + m3[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11]; + m3[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11]; + m3[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11]; + + m3[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15]; + m3[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15]; + m3[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15]; + m3[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15]; + return m3; + } + + + + template <class T> + inline vector3d<T> CMatrix4<T>::getTranslation() const + { + return vector3d<T>(M[12], M[13], M[14]); + } + + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setTranslation( const vector3d<T>& translation ) + { + M[12] = translation.X; + M[13] = translation.Y; + M[14] = translation.Z; +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setInverseTranslation( const vector3d<T>& translation ) + { + M[12] = -translation.X; + M[13] = -translation.Y; + M[14] = -translation.Z; +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setScale( const vector3d<T>& scale ) + { + M[0] = scale.X; + M[5] = scale.Y; + M[10] = scale.Z; +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + //! Returns the absolute values of the scales of the matrix. + /** + Note that this returns the absolute (positive) values unless only scale is set. + Unfortunately it does not appear to be possible to extract any original negative + values. The best that we could do would be to arbitrarily make one scale + negative if one or three of them were negative. + FIXME - return the original values. + */ + template <class T> + inline vector3d<T> CMatrix4<T>::getScale() const + { + // See http://www.robertblum.com/articles/2005/02/14/decomposing-matrices + + // Deal with the 0 rotation case first + // Prior to Irrlicht 1.6, we always returned this value. + if(core::iszero(M[1]) && core::iszero(M[2]) && + core::iszero(M[4]) && core::iszero(M[6]) && + core::iszero(M[8]) && core::iszero(M[9])) + return vector3d<T>(M[0], M[5], M[10]); + + // We have to do the full calculation. + return vector3d<T>(sqrtf(M[0] * M[0] + M[1] * M[1] + M[2] * M[2]), + sqrtf(M[4] * M[4] + M[5] * M[5] + M[6] * M[6]), + sqrtf(M[8] * M[8] + M[9] * M[9] + M[10] * M[10])); + } + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setRotationDegrees( const vector3d<T>& rotation ) + { + return setRotationRadians( rotation * core::DEGTORAD ); + } + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setInverseRotationDegrees( const vector3d<T>& rotation ) + { + return setInverseRotationRadians( rotation * core::DEGTORAD ); + } + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setRotationRadians( const vector3d<T>& rotation ) + { + const f64 cr = cos( rotation.X ); + const f64 sr = sin( rotation.X ); + const f64 cp = cos( rotation.Y ); + const f64 sp = sin( rotation.Y ); + const f64 cy = cos( rotation.Z ); + const f64 sy = sin( rotation.Z ); + + M[0] = (T)( cp*cy ); + M[1] = (T)( cp*sy ); + M[2] = (T)( -sp ); + + const f64 srsp = sr*sp; + const f64 crsp = cr*sp; + + M[4] = (T)( srsp*cy-cr*sy ); + M[5] = (T)( srsp*sy+cr*cy ); + M[6] = (T)( sr*cp ); + + M[8] = (T)( crsp*cy+sr*sy ); + M[9] = (T)( crsp*sy-sr*cy ); + M[10] = (T)( cr*cp ); +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + //! Returns a rotation that is equivalent to that set by setRotationDegrees(). + /** This code was sent in by Chev. Note that it does not necessarily return + the *same* Euler angles as those set by setRotationDegrees(), but the rotation will + be equivalent, i.e. will have the same result when used to rotate a vector or node. */ + template <class T> + inline core::vector3d<T> CMatrix4<T>::getRotationDegrees() const + { + const CMatrix4<T> &mat = *this; + core::vector3d<T> scale = getScale(); + // we need to check for negative scale on to axes, which would bring up wrong results + if (scale.Y<0 && scale.Z<0) + { + scale.Y =-scale.Y; + scale.Z =-scale.Z; + } + else if (scale.X<0 && scale.Z<0) + { + scale.X =-scale.X; + scale.Z =-scale.Z; + } + else if (scale.X<0 && scale.Y<0) + { + scale.X =-scale.X; + scale.Y =-scale.Y; + } + const core::vector3d<f64> invScale(core::reciprocal(scale.X),core::reciprocal(scale.Y),core::reciprocal(scale.Z)); + + f64 Y = -asin(core::clamp(mat[2]*invScale.X, -1.0, 1.0)); + const f64 C = cos(Y); + Y *= RADTODEG64; + + f64 rotx, roty, X, Z; + + if (!core::iszero(C)) + { + const f64 invC = core::reciprocal(C); + rotx = mat[10] * invC * invScale.Z; + roty = mat[6] * invC * invScale.Y; + X = atan2( roty, rotx ) * RADTODEG64; + rotx = mat[0] * invC * invScale.X; + roty = mat[1] * invC * invScale.X; + Z = atan2( roty, rotx ) * RADTODEG64; + } + else + { + X = 0.0; + rotx = mat[5] * invScale.Y; + roty = -mat[4] * invScale.Y; + Z = atan2( roty, rotx ) * RADTODEG64; + } + + // fix values that get below zero + if (X < 0.0) X += 360.0; + if (Y < 0.0) Y += 360.0; + if (Z < 0.0) Z += 360.0; + + return vector3d<T>((T)X,(T)Y,(T)Z); + } + + + //! Sets matrix to rotation matrix of inverse angles given as parameters + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setInverseRotationRadians( const vector3d<T>& rotation ) + { + f64 cr = cos( rotation.X ); + f64 sr = sin( rotation.X ); + f64 cp = cos( rotation.Y ); + f64 sp = sin( rotation.Y ); + f64 cy = cos( rotation.Z ); + f64 sy = sin( rotation.Z ); + + M[0] = (T)( cp*cy ); + M[4] = (T)( cp*sy ); + M[8] = (T)( -sp ); + + f64 srsp = sr*sp; + f64 crsp = cr*sp; + + M[1] = (T)( srsp*cy-cr*sy ); + M[5] = (T)( srsp*sy+cr*cy ); + M[9] = (T)( sr*cp ); + + M[2] = (T)( crsp*cy+sr*sy ); + M[6] = (T)( crsp*sy-sr*cy ); + M[10] = (T)( cr*cp ); +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + //! Sets matrix to rotation matrix defined by axis and angle, assuming LH rotation + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setRotationAxisRadians( const T& angle, const vector3d<T>& axis ) + { + const f64 c = cos(angle); + const f64 s = sin(angle); + const f64 t = 1.0 - c; + + const f64 tx = t * axis.X; + const f64 ty = t * axis.Y; + const f64 tz = t * axis.Z; + + const f64 sx = s * axis.X; + const f64 sy = s * axis.Y; + const f64 sz = s * axis.Z; + + M[0] = (T)(tx * axis.X + c); + M[1] = (T)(tx * axis.Y + sz); + M[2] = (T)(tx * axis.Z - sy); + + M[4] = (T)(ty * axis.X - sz); + M[5] = (T)(ty * axis.Y + c); + M[6] = (T)(ty * axis.Z + sx); + + M[8] = (T)(tz * axis.X + sy); + M[9] = (T)(tz * axis.Y - sx); + M[10] = (T)(tz * axis.Z + c); + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + /*! + */ + template <class T> + inline CMatrix4<T>& CMatrix4<T>::makeIdentity() + { + memset(M, 0, 16*sizeof(T)); + M[0] = M[5] = M[10] = M[15] = (T)1; +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=true; +#endif + return *this; + } + + + /* + check identity with epsilon + solve floating range problems.. + */ + template <class T> + inline bool CMatrix4<T>::isIdentity() const + { +#if defined ( USE_MATRIX_TEST ) + if (definitelyIdentityMatrix) + return true; +#endif + if (!core::equals( M[12], (T)0 ) || !core::equals( M[13], (T)0 ) || !core::equals( M[14], (T)0 ) || !core::equals( M[15], (T)1 )) + return false; + + if (!core::equals( M[ 0], (T)1 ) || !core::equals( M[ 1], (T)0 ) || !core::equals( M[ 2], (T)0 ) || !core::equals( M[ 3], (T)0 )) + return false; + + if (!core::equals( M[ 4], (T)0 ) || !core::equals( M[ 5], (T)1 ) || !core::equals( M[ 6], (T)0 ) || !core::equals( M[ 7], (T)0 )) + return false; + + if (!core::equals( M[ 8], (T)0 ) || !core::equals( M[ 9], (T)0 ) || !core::equals( M[10], (T)1 ) || !core::equals( M[11], (T)0 )) + return false; +/* + if (!core::equals( M[ 0], (T)1 ) || + !core::equals( M[ 5], (T)1 ) || + !core::equals( M[10], (T)1 ) || + !core::equals( M[15], (T)1 )) + return false; + + for (s32 i=0; i<4; ++i) + for (s32 j=0; j<4; ++j) + if ((j != i) && (!iszero((*this)(i,j)))) + return false; +*/ +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=true; +#endif + return true; + } + + + /* Check orthogonality of matrix. */ + template <class T> + inline bool CMatrix4<T>::isOrthogonal() const + { + T dp=M[0] * M[4 ] + M[1] * M[5 ] + M[2 ] * M[6 ] + M[3 ] * M[7 ]; + if (!iszero(dp)) + return false; + dp = M[0] * M[8 ] + M[1] * M[9 ] + M[2 ] * M[10] + M[3 ] * M[11]; + if (!iszero(dp)) + return false; + dp = M[0] * M[12] + M[1] * M[13] + M[2 ] * M[14] + M[3 ] * M[15]; + if (!iszero(dp)) + return false; + dp = M[4] * M[8 ] + M[5] * M[9 ] + M[6 ] * M[10] + M[7 ] * M[11]; + if (!iszero(dp)) + return false; + dp = M[4] * M[12] + M[5] * M[13] + M[6 ] * M[14] + M[7 ] * M[15]; + if (!iszero(dp)) + return false; + dp = M[8] * M[12] + M[9] * M[13] + M[10] * M[14] + M[11] * M[15]; + return (iszero(dp)); + } + + + /* + doesn't solve floating range problems.. + but takes care on +/- 0 on translation because we are changing it.. + reducing floating point branches + but it needs the floats in memory.. + */ + template <class T> + inline bool CMatrix4<T>::isIdentity_integer_base() const + { +#if defined ( USE_MATRIX_TEST ) + if (definitelyIdentityMatrix) + return true; +#endif + if(IR(M[0])!=F32_VALUE_1) return false; + if(IR(M[1])!=0) return false; + if(IR(M[2])!=0) return false; + if(IR(M[3])!=0) return false; + + if(IR(M[4])!=0) return false; + if(IR(M[5])!=F32_VALUE_1) return false; + if(IR(M[6])!=0) return false; + if(IR(M[7])!=0) return false; + + if(IR(M[8])!=0) return false; + if(IR(M[9])!=0) return false; + if(IR(M[10])!=F32_VALUE_1) return false; + if(IR(M[11])!=0) return false; + + if(IR(M[12])!=0) return false; + if(IR(M[13])!=0) return false; + if(IR(M[13])!=0) return false; + if(IR(M[15])!=F32_VALUE_1) return false; + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=true; +#endif + return true; + } + + + template <class T> + inline void CMatrix4<T>::rotateVect( vector3df& vect ) const + { + vector3df tmp = vect; + vect.X = tmp.X*M[0] + tmp.Y*M[4] + tmp.Z*M[8]; + vect.Y = tmp.X*M[1] + tmp.Y*M[5] + tmp.Z*M[9]; + vect.Z = tmp.X*M[2] + tmp.Y*M[6] + tmp.Z*M[10]; + } + + //! An alternate transform vector method, writing into a second vector + template <class T> + inline void CMatrix4<T>::rotateVect(core::vector3df& out, const core::vector3df& in) const + { + out.X = in.X*M[0] + in.Y*M[4] + in.Z*M[8]; + out.Y = in.X*M[1] + in.Y*M[5] + in.Z*M[9]; + out.Z = in.X*M[2] + in.Y*M[6] + in.Z*M[10]; + } + + //! An alternate transform vector method, writing into an array of 3 floats + template <class T> + inline void CMatrix4<T>::rotateVect(T *out, const core::vector3df& in) const + { + out[0] = in.X*M[0] + in.Y*M[4] + in.Z*M[8]; + out[1] = in.X*M[1] + in.Y*M[5] + in.Z*M[9]; + out[2] = in.X*M[2] + in.Y*M[6] + in.Z*M[10]; + } + + template <class T> + inline void CMatrix4<T>::inverseRotateVect( vector3df& vect ) const + { + vector3df tmp = vect; + vect.X = tmp.X*M[0] + tmp.Y*M[1] + tmp.Z*M[2]; + vect.Y = tmp.X*M[4] + tmp.Y*M[5] + tmp.Z*M[6]; + vect.Z = tmp.X*M[8] + tmp.Y*M[9] + tmp.Z*M[10]; + } + + template <class T> + inline void CMatrix4<T>::transformVect( vector3df& vect) const + { + f32 vector[3]; + + vector[0] = vect.X*M[0] + vect.Y*M[4] + vect.Z*M[8] + M[12]; + vector[1] = vect.X*M[1] + vect.Y*M[5] + vect.Z*M[9] + M[13]; + vector[2] = vect.X*M[2] + vect.Y*M[6] + vect.Z*M[10] + M[14]; + + vect.X = vector[0]; + vect.Y = vector[1]; + vect.Z = vector[2]; + } + + template <class T> + inline void CMatrix4<T>::transformVect( vector3df& out, const vector3df& in) const + { + out.X = in.X*M[0] + in.Y*M[4] + in.Z*M[8] + M[12]; + out.Y = in.X*M[1] + in.Y*M[5] + in.Z*M[9] + M[13]; + out.Z = in.X*M[2] + in.Y*M[6] + in.Z*M[10] + M[14]; + } + + + template <class T> + inline void CMatrix4<T>::transformVect(T *out, const core::vector3df &in) const + { + out[0] = in.X*M[0] + in.Y*M[4] + in.Z*M[8] + M[12]; + out[1] = in.X*M[1] + in.Y*M[5] + in.Z*M[9] + M[13]; + out[2] = in.X*M[2] + in.Y*M[6] + in.Z*M[10] + M[14]; + out[3] = in.X*M[3] + in.Y*M[7] + in.Z*M[11] + M[15]; + } + + template <class T> + inline void CMatrix4<T>::transformVec3(T *out, const T * in) const + { + out[0] = in[0]*M[0] + in[1]*M[4] + in[2]*M[8] + M[12]; + out[1] = in[0]*M[1] + in[1]*M[5] + in[2]*M[9] + M[13]; + out[2] = in[0]*M[2] + in[1]*M[6] + in[2]*M[10] + M[14]; + } + + + //! Transforms a plane by this matrix + template <class T> + inline void CMatrix4<T>::transformPlane( core::plane3d<f32> &plane) const + { + vector3df member; + // Transform the plane member point, i.e. rotate, translate and scale it. + transformVect(member, plane.getMemberPoint()); + + // Transform the normal by the transposed inverse of the matrix + CMatrix4<T> transposedInverse(*this, EM4CONST_INVERSE_TRANSPOSED); + vector3df normal = plane.Normal; + transposedInverse.transformVect(normal); + + plane.setPlane(member, normal); + } + + //! Transforms a plane by this matrix + template <class T> + inline void CMatrix4<T>::transformPlane( const core::plane3d<f32> &in, core::plane3d<f32> &out) const + { + out = in; + transformPlane( out ); + } + + //! Transforms a axis aligned bounding box + template <class T> + inline void CMatrix4<T>::transformBox(core::aabbox3d<f32>& box) const + { +#if defined ( USE_MATRIX_TEST ) + if (isIdentity()) + return; +#endif + + transformVect(box.MinEdge); + transformVect(box.MaxEdge); + box.repair(); + } + + //! Transforms a axis aligned bounding box more accurately than transformBox() + template <class T> + inline void CMatrix4<T>::transformBoxEx(core::aabbox3d<f32>& box) const + { +#if defined ( USE_MATRIX_TEST ) + if (isIdentity()) + return; +#endif + + const f32 Amin[3] = {box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z}; + const f32 Amax[3] = {box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z}; + + f32 Bmin[3]; + f32 Bmax[3]; + + Bmin[0] = Bmax[0] = M[12]; + Bmin[1] = Bmax[1] = M[13]; + Bmin[2] = Bmax[2] = M[14]; + + const CMatrix4<T> &m = *this; + + for (u32 i = 0; i < 3; ++i) + { + for (u32 j = 0; j < 3; ++j) + { + const f32 a = m(j,i) * Amin[j]; + const f32 b = m(j,i) * Amax[j]; + + if (a < b) + { + Bmin[i] += a; + Bmax[i] += b; + } + else + { + Bmin[i] += b; + Bmax[i] += a; + } + } + } + + box.MinEdge.X = Bmin[0]; + box.MinEdge.Y = Bmin[1]; + box.MinEdge.Z = Bmin[2]; + + box.MaxEdge.X = Bmax[0]; + box.MaxEdge.Y = Bmax[1]; + box.MaxEdge.Z = Bmax[2]; + } + + + //! Multiplies this matrix by a 1x4 matrix + template <class T> + inline void CMatrix4<T>::multiplyWith1x4Matrix(T* matrix) const + { + /* + 0 1 2 3 + 4 5 6 7 + 8 9 10 11 + 12 13 14 15 + */ + + T mat[4]; + mat[0] = matrix[0]; + mat[1] = matrix[1]; + mat[2] = matrix[2]; + mat[3] = matrix[3]; + + matrix[0] = M[0]*mat[0] + M[4]*mat[1] + M[8]*mat[2] + M[12]*mat[3]; + matrix[1] = M[1]*mat[0] + M[5]*mat[1] + M[9]*mat[2] + M[13]*mat[3]; + matrix[2] = M[2]*mat[0] + M[6]*mat[1] + M[10]*mat[2] + M[14]*mat[3]; + matrix[3] = M[3]*mat[0] + M[7]*mat[1] + M[11]*mat[2] + M[15]*mat[3]; + } + + template <class T> + inline void CMatrix4<T>::inverseTranslateVect( vector3df& vect ) const + { + vect.X = vect.X-M[12]; + vect.Y = vect.Y-M[13]; + vect.Z = vect.Z-M[14]; + } + + template <class T> + inline void CMatrix4<T>::translateVect( vector3df& vect ) const + { + vect.X = vect.X+M[12]; + vect.Y = vect.Y+M[13]; + vect.Z = vect.Z+M[14]; + } + + + template <class T> + inline bool CMatrix4<T>::getInverse(CMatrix4<T>& out) const + { + /// Calculates the inverse of this Matrix + /// The inverse is calculated using Cramers rule. + /// If no inverse exists then 'false' is returned. + +#if defined ( USE_MATRIX_TEST ) + if ( this->isIdentity() ) + { + out=*this; + return true; + } +#endif + const CMatrix4<T> &m = *this; + + f32 d = (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) - + (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) + + (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1)) + + (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) - + (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) + + (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0)); + + if( core::iszero ( d, FLT_MIN ) ) + return false; + + d = core::reciprocal ( d ); + + out(0, 0) = d * (m(1, 1) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) + + m(1, 2) * (m(2, 3) * m(3, 1) - m(2, 1) * m(3, 3)) + + m(1, 3) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1))); + out(0, 1) = d * (m(2, 1) * (m(0, 2) * m(3, 3) - m(0, 3) * m(3, 2)) + + m(2, 2) * (m(0, 3) * m(3, 1) - m(0, 1) * m(3, 3)) + + m(2, 3) * (m(0, 1) * m(3, 2) - m(0, 2) * m(3, 1))); + out(0, 2) = d * (m(3, 1) * (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) + + m(3, 2) * (m(0, 3) * m(1, 1) - m(0, 1) * m(1, 3)) + + m(3, 3) * (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1))); + out(0, 3) = d * (m(0, 1) * (m(1, 3) * m(2, 2) - m(1, 2) * m(2, 3)) + + m(0, 2) * (m(1, 1) * m(2, 3) - m(1, 3) * m(2, 1)) + + m(0, 3) * (m(1, 2) * m(2, 1) - m(1, 1) * m(2, 2))); + out(1, 0) = d * (m(1, 2) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) + + m(1, 3) * (m(2, 2) * m(3, 0) - m(2, 0) * m(3, 2)) + + m(1, 0) * (m(2, 3) * m(3, 2) - m(2, 2) * m(3, 3))); + out(1, 1) = d * (m(2, 2) * (m(0, 0) * m(3, 3) - m(0, 3) * m(3, 0)) + + m(2, 3) * (m(0, 2) * m(3, 0) - m(0, 0) * m(3, 2)) + + m(2, 0) * (m(0, 3) * m(3, 2) - m(0, 2) * m(3, 3))); + out(1, 2) = d * (m(3, 2) * (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) + + m(3, 3) * (m(0, 2) * m(1, 0) - m(0, 0) * m(1, 2)) + + m(3, 0) * (m(0, 3) * m(1, 2) - m(0, 2) * m(1, 3))); + out(1, 3) = d * (m(0, 2) * (m(1, 3) * m(2, 0) - m(1, 0) * m(2, 3)) + + m(0, 3) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) + + m(0, 0) * (m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2))); + out(2, 0) = d * (m(1, 3) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0)) + + m(1, 0) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) + + m(1, 1) * (m(2, 3) * m(3, 0) - m(2, 0) * m(3, 3))); + out(2, 1) = d * (m(2, 3) * (m(0, 0) * m(3, 1) - m(0, 1) * m(3, 0)) + + m(2, 0) * (m(0, 1) * m(3, 3) - m(0, 3) * m(3, 1)) + + m(2, 1) * (m(0, 3) * m(3, 0) - m(0, 0) * m(3, 3))); + out(2, 2) = d * (m(3, 3) * (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) + + m(3, 0) * (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) + + m(3, 1) * (m(0, 3) * m(1, 0) - m(0, 0) * m(1, 3))); + out(2, 3) = d * (m(0, 3) * (m(1, 1) * m(2, 0) - m(1, 0) * m(2, 1)) + + m(0, 0) * (m(1, 3) * m(2, 1) - m(1, 1) * m(2, 3)) + + m(0, 1) * (m(1, 0) * m(2, 3) - m(1, 3) * m(2, 0))); + out(3, 0) = d * (m(1, 0) * (m(2, 2) * m(3, 1) - m(2, 1) * m(3, 2)) + + m(1, 1) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) + + m(1, 2) * (m(2, 1) * m(3, 0) - m(2, 0) * m(3, 1))); + out(3, 1) = d * (m(2, 0) * (m(0, 2) * m(3, 1) - m(0, 1) * m(3, 2)) + + m(2, 1) * (m(0, 0) * m(3, 2) - m(0, 2) * m(3, 0)) + + m(2, 2) * (m(0, 1) * m(3, 0) - m(0, 0) * m(3, 1))); + out(3, 2) = d * (m(3, 0) * (m(0, 2) * m(1, 1) - m(0, 1) * m(1, 2)) + + m(3, 1) * (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) + + m(3, 2) * (m(0, 1) * m(1, 0) - m(0, 0) * m(1, 1))); + out(3, 3) = d * (m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)) + + m(0, 1) * (m(1, 2) * m(2, 0) - m(1, 0) * m(2, 2)) + + m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0))); + +#if defined ( USE_MATRIX_TEST ) + out.definitelyIdentityMatrix = definitelyIdentityMatrix; +#endif + return true; + } + + + //! Inverts a primitive matrix which only contains a translation and a rotation + //! \param out: where result matrix is written to. + template <class T> + inline bool CMatrix4<T>::getInversePrimitive ( CMatrix4<T>& out ) const + { + out.M[0 ] = M[0]; + out.M[1 ] = M[4]; + out.M[2 ] = M[8]; + out.M[3 ] = 0; + + out.M[4 ] = M[1]; + out.M[5 ] = M[5]; + out.M[6 ] = M[9]; + out.M[7 ] = 0; + + out.M[8 ] = M[2]; + out.M[9 ] = M[6]; + out.M[10] = M[10]; + out.M[11] = 0; + + out.M[12] = (T)-(M[12]*M[0] + M[13]*M[1] + M[14]*M[2]); + out.M[13] = (T)-(M[12]*M[4] + M[13]*M[5] + M[14]*M[6]); + out.M[14] = (T)-(M[12]*M[8] + M[13]*M[9] + M[14]*M[10]); + out.M[15] = 1; + +#if defined ( USE_MATRIX_TEST ) + out.definitelyIdentityMatrix = definitelyIdentityMatrix; +#endif + return true; + } + + /*! + */ + template <class T> + inline bool CMatrix4<T>::makeInverse() + { +#if defined ( USE_MATRIX_TEST ) + if (definitelyIdentityMatrix) + return true; +#endif + CMatrix4<T> temp ( EM4CONST_NOTHING ); + + if (getInverse(temp)) + { + *this = temp; + return true; + } + + return false; + } + + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::operator=(const CMatrix4<T> &other) + { + if (this==&other) + return *this; + memcpy(M, other.M, 16*sizeof(T)); +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=other.definitelyIdentityMatrix; +#endif + return *this; + } + + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::operator=(const T& scalar) + { + for (s32 i = 0; i < 16; ++i) + M[i]=scalar; + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + template <class T> + inline bool CMatrix4<T>::operator==(const CMatrix4<T> &other) const + { +#if defined ( USE_MATRIX_TEST ) + if (definitelyIdentityMatrix && other.definitelyIdentityMatrix) + return true; +#endif + for (s32 i = 0; i < 16; ++i) + if (M[i] != other.M[i]) + return false; + + return true; + } + + + template <class T> + inline bool CMatrix4<T>::operator!=(const CMatrix4<T> &other) const + { + return !(*this == other); + } + + + // Builds a right-handed perspective projection matrix based on a field of view + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveFovRH( + f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar) + { + const f64 h = reciprocal(tan(fieldOfViewRadians*0.5)); + _IRR_DEBUG_BREAK_IF(aspectRatio==0.f); //divide by zero + const T w = static_cast<T>(h / aspectRatio); + + _IRR_DEBUG_BREAK_IF(zNear==zFar); //divide by zero + M[0] = w; + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)h; + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(zFar/(zNear-zFar)); // DirectX version +// M[10] = (T)(zFar+zNear/(zNear-zFar)); // OpenGL version + M[11] = -1; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(zNear*zFar/(zNear-zFar)); // DirectX version +// M[14] = (T)(2.0f*zNear*zFar/(zNear-zFar)); // OpenGL version + M[15] = 0; + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + // Builds a left-handed perspective projection matrix based on a field of view + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveFovLH( + f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar) + { + const f64 h = reciprocal(tan(fieldOfViewRadians*0.5)); + _IRR_DEBUG_BREAK_IF(aspectRatio==0.f); //divide by zero + const T w = static_cast<T>(h / aspectRatio); + + _IRR_DEBUG_BREAK_IF(zNear==zFar); //divide by zero + M[0] = w; + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)h; + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(zFar/(zFar-zNear)); + M[11] = 1; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(-zNear*zFar/(zFar-zNear)); + M[15] = 0; + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + // Builds a left-handed perspective projection matrix based on a field of view, with far plane culling at infinity + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveFovInfinityLH( + f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 epsilon) + { + const f64 h = reciprocal(tan(fieldOfViewRadians*0.5)); + _IRR_DEBUG_BREAK_IF(aspectRatio==0.f); //divide by zero + const T w = static_cast<T>(h / aspectRatio); + + M[0] = w; + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)h; + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(1.f-epsilon); + M[11] = 1; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(zNear*(epsilon-1.f)); + M[15] = 0; + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + // Builds a left-handed orthogonal projection matrix. + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoLH( + f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar) + { + _IRR_DEBUG_BREAK_IF(widthOfViewVolume==0.f); //divide by zero + _IRR_DEBUG_BREAK_IF(heightOfViewVolume==0.f); //divide by zero + _IRR_DEBUG_BREAK_IF(zNear==zFar); //divide by zero + M[0] = (T)(2/widthOfViewVolume); + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)(2/heightOfViewVolume); + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(1/(zFar-zNear)); + M[11] = 0; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(zNear/(zNear-zFar)); + M[15] = 1; + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + // Builds a right-handed orthogonal projection matrix. + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoRH( + f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar) + { + _IRR_DEBUG_BREAK_IF(widthOfViewVolume==0.f); //divide by zero + _IRR_DEBUG_BREAK_IF(heightOfViewVolume==0.f); //divide by zero + _IRR_DEBUG_BREAK_IF(zNear==zFar); //divide by zero + M[0] = (T)(2/widthOfViewVolume); + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)(2/heightOfViewVolume); + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(1/(zNear-zFar)); + M[11] = 0; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(zNear/(zNear-zFar)); + M[15] = 1; + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + // Builds a right-handed perspective projection matrix. + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveRH( + f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar) + { + _IRR_DEBUG_BREAK_IF(widthOfViewVolume==0.f); //divide by zero + _IRR_DEBUG_BREAK_IF(heightOfViewVolume==0.f); //divide by zero + _IRR_DEBUG_BREAK_IF(zNear==zFar); //divide by zero + M[0] = (T)(2*zNear/widthOfViewVolume); + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)(2*zNear/heightOfViewVolume); + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(zFar/(zNear-zFar)); + M[11] = -1; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(zNear*zFar/(zNear-zFar)); + M[15] = 0; + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + // Builds a left-handed perspective projection matrix. + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveLH( + f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar) + { + _IRR_DEBUG_BREAK_IF(widthOfViewVolume==0.f); //divide by zero + _IRR_DEBUG_BREAK_IF(heightOfViewVolume==0.f); //divide by zero + _IRR_DEBUG_BREAK_IF(zNear==zFar); //divide by zero + M[0] = (T)(2*zNear/widthOfViewVolume); + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)(2*zNear/heightOfViewVolume); + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(zFar/(zFar-zNear)); + M[11] = 1; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(zNear*zFar/(zNear-zFar)); + M[15] = 0; +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + // Builds a matrix that flattens geometry into a plane. + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point) + { + plane.Normal.normalize(); + const f32 d = plane.Normal.dotProduct(light); + + M[ 0] = (T)(-plane.Normal.X * light.X + d); + M[ 1] = (T)(-plane.Normal.X * light.Y); + M[ 2] = (T)(-plane.Normal.X * light.Z); + M[ 3] = (T)(-plane.Normal.X * point); + + M[ 4] = (T)(-plane.Normal.Y * light.X); + M[ 5] = (T)(-plane.Normal.Y * light.Y + d); + M[ 6] = (T)(-plane.Normal.Y * light.Z); + M[ 7] = (T)(-plane.Normal.Y * point); + + M[ 8] = (T)(-plane.Normal.Z * light.X); + M[ 9] = (T)(-plane.Normal.Z * light.Y); + M[10] = (T)(-plane.Normal.Z * light.Z + d); + M[11] = (T)(-plane.Normal.Z * point); + + M[12] = (T)(-plane.D * light.X); + M[13] = (T)(-plane.D * light.Y); + M[14] = (T)(-plane.D * light.Z); + M[15] = (T)(-plane.D * point + d); +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + // Builds a left-handed look-at matrix. + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildCameraLookAtMatrixLH( + const vector3df& position, + const vector3df& target, + const vector3df& upVector) + { + vector3df zaxis = target - position; + zaxis.normalize(); + + vector3df xaxis = upVector.crossProduct(zaxis); + xaxis.normalize(); + + vector3df yaxis = zaxis.crossProduct(xaxis); + + M[0] = (T)xaxis.X; + M[1] = (T)yaxis.X; + M[2] = (T)zaxis.X; + M[3] = 0; + + M[4] = (T)xaxis.Y; + M[5] = (T)yaxis.Y; + M[6] = (T)zaxis.Y; + M[7] = 0; + + M[8] = (T)xaxis.Z; + M[9] = (T)yaxis.Z; + M[10] = (T)zaxis.Z; + M[11] = 0; + + M[12] = (T)-xaxis.dotProduct(position); + M[13] = (T)-yaxis.dotProduct(position); + M[14] = (T)-zaxis.dotProduct(position); + M[15] = 1; +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + // Builds a right-handed look-at matrix. + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildCameraLookAtMatrixRH( + const vector3df& position, + const vector3df& target, + const vector3df& upVector) + { + vector3df zaxis = position - target; + zaxis.normalize(); + + vector3df xaxis = upVector.crossProduct(zaxis); + xaxis.normalize(); + + vector3df yaxis = zaxis.crossProduct(xaxis); + + M[0] = (T)xaxis.X; + M[1] = (T)yaxis.X; + M[2] = (T)zaxis.X; + M[3] = 0; + + M[4] = (T)xaxis.Y; + M[5] = (T)yaxis.Y; + M[6] = (T)zaxis.Y; + M[7] = 0; + + M[8] = (T)xaxis.Z; + M[9] = (T)yaxis.Z; + M[10] = (T)zaxis.Z; + M[11] = 0; + + M[12] = (T)-xaxis.dotProduct(position); + M[13] = (T)-yaxis.dotProduct(position); + M[14] = (T)-zaxis.dotProduct(position); + M[15] = 1; +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + // creates a new matrix as interpolated matrix from this and the passed one. + template <class T> + inline CMatrix4<T> CMatrix4<T>::interpolate(const core::CMatrix4<T>& b, f32 time) const + { + CMatrix4<T> mat ( EM4CONST_NOTHING ); + + for (u32 i=0; i < 16; i += 4) + { + mat.M[i+0] = (T)(M[i+0] + ( b.M[i+0] - M[i+0] ) * time); + mat.M[i+1] = (T)(M[i+1] + ( b.M[i+1] - M[i+1] ) * time); + mat.M[i+2] = (T)(M[i+2] + ( b.M[i+2] - M[i+2] ) * time); + mat.M[i+3] = (T)(M[i+3] + ( b.M[i+3] - M[i+3] ) * time); + } + return mat; + } + + + // returns transposed matrix + template <class T> + inline CMatrix4<T> CMatrix4<T>::getTransposed() const + { + CMatrix4<T> t ( EM4CONST_NOTHING ); + getTransposed ( t ); + return t; + } + + + // returns transposed matrix + template <class T> + inline void CMatrix4<T>::getTransposed( CMatrix4<T>& o ) const + { + o[ 0] = M[ 0]; + o[ 1] = M[ 4]; + o[ 2] = M[ 8]; + o[ 3] = M[12]; + + o[ 4] = M[ 1]; + o[ 5] = M[ 5]; + o[ 6] = M[ 9]; + o[ 7] = M[13]; + + o[ 8] = M[ 2]; + o[ 9] = M[ 6]; + o[10] = M[10]; + o[11] = M[14]; + + o[12] = M[ 3]; + o[13] = M[ 7]; + o[14] = M[11]; + o[15] = M[15]; +#if defined ( USE_MATRIX_TEST ) + o.definitelyIdentityMatrix=definitelyIdentityMatrix; +#endif + } + + + // used to scale <-1,-1><1,1> to viewport + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildNDCToDCMatrix( const core::rect<s32>& viewport, f32 zScale) + { + const f32 scaleX = (viewport.getWidth() - 0.75f ) * 0.5f; + const f32 scaleY = -(viewport.getHeight() - 0.75f ) * 0.5f; + + const f32 dx = -0.5f + ( (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X ) * 0.5f ); + const f32 dy = -0.5f + ( (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y ) * 0.5f ); + + makeIdentity(); + M[12] = (T)dx; + M[13] = (T)dy; + return setScale(core::vector3d<T>((T)scaleX, (T)scaleY, (T)zScale)); + } + + //! Builds a matrix that rotates from one vector to another + /** \param from: vector to rotate from + \param to: vector to rotate to + + http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/index.htm + */ + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildRotateFromTo(const core::vector3df& from, const core::vector3df& to) + { + // unit vectors + core::vector3df f(from); + core::vector3df t(to); + f.normalize(); + t.normalize(); + + // axis multiplication by sin + core::vector3df vs(t.crossProduct(f)); + + // axis of rotation + core::vector3df v(vs); + v.normalize(); + + // cosinus angle + T ca = f.dotProduct(t); + + core::vector3df vt(v * (1 - ca)); + + M[0] = vt.X * v.X + ca; + M[5] = vt.Y * v.Y + ca; + M[10] = vt.Z * v.Z + ca; + + vt.X *= v.Y; + vt.Z *= v.X; + vt.Y *= v.Z; + + M[1] = vt.X - vs.Z; + M[2] = vt.Z + vs.Y; + M[3] = 0; + + M[4] = vt.X + vs.Z; + M[6] = vt.Y - vs.X; + M[7] = 0; + + M[8] = vt.Z - vs.Y; + M[9] = vt.Y + vs.X; + M[11] = 0; + + M[12] = 0; + M[13] = 0; + M[14] = 0; + M[15] = 1; + + return *this; + } + + //! Builds a matrix which rotates a source vector to a look vector over an arbitrary axis + /** \param camPos: viewer position in world coord + \param center: object position in world-coord, rotation pivot + \param translation: object final translation from center + \param axis: axis to rotate about + \param from: source vector to rotate from + */ + template <class T> + inline void CMatrix4<T>::buildAxisAlignedBillboard( + const core::vector3df& camPos, + const core::vector3df& center, + const core::vector3df& translation, + const core::vector3df& axis, + const core::vector3df& from) + { + // axis of rotation + core::vector3df up = axis; + up.normalize(); + const core::vector3df forward = (camPos - center).normalize(); + const core::vector3df right = up.crossProduct(forward).normalize(); + + // correct look vector + const core::vector3df look = right.crossProduct(up); + + // rotate from to + // axis multiplication by sin + const core::vector3df vs = look.crossProduct(from); + + // cosinus angle + const f32 ca = from.dotProduct(look); + + core::vector3df vt(up * (1.f - ca)); + + M[0] = static_cast<T>(vt.X * up.X + ca); + M[5] = static_cast<T>(vt.Y * up.Y + ca); + M[10] = static_cast<T>(vt.Z * up.Z + ca); + + vt.X *= up.Y; + vt.Z *= up.X; + vt.Y *= up.Z; + + M[1] = static_cast<T>(vt.X - vs.Z); + M[2] = static_cast<T>(vt.Z + vs.Y); + M[3] = 0; + + M[4] = static_cast<T>(vt.X + vs.Z); + M[6] = static_cast<T>(vt.Y - vs.X); + M[7] = 0; + + M[8] = static_cast<T>(vt.Z - vs.Y); + M[9] = static_cast<T>(vt.Y + vs.X); + M[11] = 0; + + setRotationCenter(center, translation); + } + + + //! Builds a combined matrix which translate to a center before rotation and translate afterwards + template <class T> + inline void CMatrix4<T>::setRotationCenter(const core::vector3df& center, const core::vector3df& translation) + { + M[12] = -M[0]*center.X - M[4]*center.Y - M[8]*center.Z + (center.X - translation.X ); + M[13] = -M[1]*center.X - M[5]*center.Y - M[9]*center.Z + (center.Y - translation.Y ); + M[14] = -M[2]*center.X - M[6]*center.Y - M[10]*center.Z + (center.Z - translation.Z ); + M[15] = (T) 1.0; +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + } + + /*! + Generate texture coordinates as linear functions so that: + u = Ux*x + Uy*y + Uz*z + Uw + v = Vx*x + Vy*y + Vz*z + Vw + The matrix M for this case is: + Ux Vx 0 0 + Uy Vy 0 0 + Uz Vz 0 0 + Uw Vw 0 0 + */ + + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::buildTextureTransform( f32 rotateRad, + const core::vector2df &rotatecenter, + const core::vector2df &translate, + const core::vector2df &scale) + { + const f32 c = cosf(rotateRad); + const f32 s = sinf(rotateRad); + + M[0] = (T)(c * scale.X); + M[1] = (T)(s * scale.Y); + M[2] = 0; + M[3] = 0; + + M[4] = (T)(-s * scale.X); + M[5] = (T)(c * scale.Y); + M[6] = 0; + M[7] = 0; + + M[8] = (T)(c * scale.X * rotatecenter.X + -s * rotatecenter.Y + translate.X); + M[9] = (T)(s * scale.Y * rotatecenter.X + c * rotatecenter.Y + translate.Y); + M[10] = 1; + M[11] = 0; + + M[12] = 0; + M[13] = 0; + M[14] = 0; + M[15] = 1; +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + // rotate about z axis, center ( 0.5, 0.5 ) + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setTextureRotationCenter( f32 rotateRad ) + { + const f32 c = cosf(rotateRad); + const f32 s = sinf(rotateRad); + M[0] = (T)c; + M[1] = (T)s; + + M[4] = (T)-s; + M[5] = (T)c; + + M[8] = (T)(0.5f * ( s - c) + 0.5f); + M[9] = (T)(-0.5f * ( s + c) + 0.5f); + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix = definitelyIdentityMatrix && (rotateRad==0.0f); +#endif + return *this; + } + + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setTextureTranslate ( f32 x, f32 y ) + { + M[8] = (T)x; + M[9] = (T)y; + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix = definitelyIdentityMatrix && (x==0.0f) && (y==0.0f); +#endif + return *this; + } + + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setTextureTranslateTransposed ( f32 x, f32 y ) + { + M[2] = (T)x; + M[6] = (T)y; + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix = definitelyIdentityMatrix && (x==0.0f) && (y==0.0f) ; +#endif + return *this; + } + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setTextureScale ( f32 sx, f32 sy ) + { + M[0] = (T)sx; + M[5] = (T)sy; +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f); +#endif + return *this; + } + + + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setTextureScaleCenter( f32 sx, f32 sy ) + { + M[0] = (T)sx; + M[5] = (T)sy; + M[8] = (T)(0.5f - 0.5f * sx); + M[9] = (T)(0.5f - 0.5f * sy); + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f); +#endif + return *this; + } + + + // sets all matrix data members at once + template <class T> + inline CMatrix4<T>& CMatrix4<T>::setM(const T* data) + { + memcpy(M,data, 16*sizeof(T)); + +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix=false; +#endif + return *this; + } + + + // sets if the matrix is definitely identity matrix + template <class T> + inline void CMatrix4<T>::setDefinitelyIdentityMatrix( bool isDefinitelyIdentityMatrix) + { +#if defined ( USE_MATRIX_TEST ) + definitelyIdentityMatrix = isDefinitelyIdentityMatrix; +#endif + } + + + // gets if the matrix is definitely identity matrix + template <class T> + inline bool CMatrix4<T>::getDefinitelyIdentityMatrix() const + { +#if defined ( USE_MATRIX_TEST ) + return definitelyIdentityMatrix; +#else + return false; +#endif + } + + + //! Compare two matrices using the equal method + template <class T> + inline bool CMatrix4<T>::equals(const core::CMatrix4<T>& other, const T tolerance) const + { +#if defined ( USE_MATRIX_TEST ) + if (definitelyIdentityMatrix && other.definitelyIdentityMatrix) + return true; +#endif + for (s32 i = 0; i < 16; ++i) + if (!core::equals(M[i],other.M[i], tolerance)) + return false; + + return true; + } + + + // Multiply by scalar. + template <class T> + inline CMatrix4<T> operator*(const T scalar, const CMatrix4<T>& mat) + { + return mat*scalar; + } + + + //! Typedef for f32 matrix + typedef CMatrix4<f32> matrix4; + + //! global const identity matrix + IRRLICHT_API extern const matrix4 IdentityMatrix; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/path.h b/builddir/irrlicht-1.8.1/include/path.h new file mode 100644 index 0000000..ed7661c --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/path.h @@ -0,0 +1,88 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_PATH_H_INCLUDED__ +#define __IRR_PATH_H_INCLUDED__ + +#include "irrString.h" + +namespace irr +{ +namespace io +{ + +//! Type used for all file system related strings. +/** This type will transparently handle different file system encodings. */ +typedef core::string<fschar_t> path; + +//! Used in places where we identify objects by a filename, but don't actually work with the real filename +/** Irrlicht is internally not case-sensitive when it comes to names. + Also this class is a first step towards support for correctly serializing renamed objects. +*/ +struct SNamedPath +{ + //! Constructor + SNamedPath() {} + + //! Constructor + SNamedPath(const path& p) : Path(p), InternalName( PathToName(p) ) + { + } + + //! Is smaller comparator + bool operator <(const SNamedPath& other) const + { + return InternalName < other.InternalName; + } + + //! Set the path. + void setPath(const path& p) + { + Path = p; + InternalName = PathToName(p); + } + + //! Get the path. + const path& getPath() const + { + return Path; + }; + + //! Get the name which is used to identify the file. + //! This string is similar to the names and filenames used before Irrlicht 1.7 + const path& getInternalName() const + { + return InternalName; + } + + //! Implicit cast to io::path + operator core::stringc() const + { + return core::stringc(getPath()); + } + //! Implicit cast to io::path + operator core::stringw() const + { + return core::stringw(getPath()); + } + +protected: + // convert the given path string to a name string. + path PathToName(const path& p) const + { + path name(p); + name.replace( '\\', '/' ); + name.make_lower(); + return name; + } + +private: + path Path; + path InternalName; +}; + +} // io +} // irr + +#endif // __IRR_PATH_H_INCLUDED__ diff --git a/builddir/irrlicht-1.8.1/include/plane3d.h b/builddir/irrlicht-1.8.1/include/plane3d.h new file mode 100644 index 0000000..02c6bf9 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/plane3d.h @@ -0,0 +1,245 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_PLANE_3D_H_INCLUDED__ +#define __IRR_PLANE_3D_H_INCLUDED__ + +#include "irrMath.h" +#include "vector3d.h" + +namespace irr +{ +namespace core +{ + +//! Enumeration for intersection relations of 3d objects +enum EIntersectionRelation3D +{ + ISREL3D_FRONT = 0, + ISREL3D_BACK, + ISREL3D_PLANAR, + ISREL3D_SPANNING, + ISREL3D_CLIPPED +}; + +//! Template plane class with some intersection testing methods. +/** It has to be ensured, that the normal is always normalized. The constructors + and setters of this class will not ensure this automatically. So any normal + passed in has to be normalized in advance. No change to the normal will be + made by any of the class methods. +*/ +template <class T> +class plane3d +{ + public: + + // Constructors + + plane3d(): Normal(0,1,0) { recalculateD(vector3d<T>(0,0,0)); } + + plane3d(const vector3d<T>& MPoint, const vector3d<T>& Normal) : Normal(Normal) { recalculateD(MPoint); } + + plane3d(T px, T py, T pz, T nx, T ny, T nz) : Normal(nx, ny, nz) { recalculateD(vector3d<T>(px, py, pz)); } + + plane3d(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3) + { setPlane(point1, point2, point3); } + + plane3d(const vector3d<T> & normal, const T d) : Normal(normal), D(d) { } + + // operators + + inline bool operator==(const plane3d<T>& other) const { return (equals(D, other.D) && Normal==other.Normal);} + + inline bool operator!=(const plane3d<T>& other) const { return !(*this == other);} + + // functions + + void setPlane(const vector3d<T>& point, const vector3d<T>& nvector) + { + Normal = nvector; + recalculateD(point); + } + + void setPlane(const vector3d<T>& nvect, T d) + { + Normal = nvect; + D = d; + } + + void setPlane(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3) + { + // creates the plane from 3 memberpoints + Normal = (point2 - point1).crossProduct(point3 - point1); + Normal.normalize(); + + recalculateD(point1); + } + + + //! Get an intersection with a 3d line. + /** \param lineVect Vector of the line to intersect with. + \param linePoint Point of the line to intersect with. + \param outIntersection Place to store the intersection point, if there is one. + \return True if there was an intersection, false if there was not. + */ + bool getIntersectionWithLine(const vector3d<T>& linePoint, + const vector3d<T>& lineVect, + vector3d<T>& outIntersection) const + { + T t2 = Normal.dotProduct(lineVect); + + if (t2 == 0) + return false; + + T t =- (Normal.dotProduct(linePoint) + D) / t2; + outIntersection = linePoint + (lineVect * t); + return true; + } + + //! Get percentage of line between two points where an intersection with this plane happens. + /** Only useful if known that there is an intersection. + \param linePoint1 Point1 of the line to intersect with. + \param linePoint2 Point2 of the line to intersect with. + \return Where on a line between two points an intersection with this plane happened. + For example, 0.5 is returned if the intersection happened exactly in the middle of the two points. + */ + f32 getKnownIntersectionWithLine(const vector3d<T>& linePoint1, + const vector3d<T>& linePoint2) const + { + vector3d<T> vect = linePoint2 - linePoint1; + T t2 = (f32)Normal.dotProduct(vect); + return (f32)-((Normal.dotProduct(linePoint1) + D) / t2); + } + + //! Get an intersection with a 3d line, limited between two 3d points. + /** \param linePoint1 Point 1 of the line. + \param linePoint2 Point 2 of the line. + \param outIntersection Place to store the intersection point, if there is one. + \return True if there was an intersection, false if there was not. + */ + bool getIntersectionWithLimitedLine( + const vector3d<T>& linePoint1, + const vector3d<T>& linePoint2, + vector3d<T>& outIntersection) const + { + return (getIntersectionWithLine(linePoint1, linePoint2 - linePoint1, outIntersection) && + outIntersection.isBetweenPoints(linePoint1, linePoint2)); + } + + //! Classifies the relation of a point to this plane. + /** \param point Point to classify its relation. + \return ISREL3D_FRONT if the point is in front of the plane, + ISREL3D_BACK if the point is behind of the plane, and + ISREL3D_PLANAR if the point is within the plane. */ + EIntersectionRelation3D classifyPointRelation(const vector3d<T>& point) const + { + const T d = Normal.dotProduct(point) + D; + + if (d < -ROUNDING_ERROR_f32) + return ISREL3D_BACK; + + if (d > ROUNDING_ERROR_f32) + return ISREL3D_FRONT; + + return ISREL3D_PLANAR; + } + + //! Recalculates the distance from origin by applying a new member point to the plane. + void recalculateD(const vector3d<T>& MPoint) + { + D = - MPoint.dotProduct(Normal); + } + + //! Gets a member point of the plane. + vector3d<T> getMemberPoint() const + { + return Normal * -D; + } + + //! Tests if there is an intersection with the other plane + /** \return True if there is a intersection. */ + bool existsIntersection(const plane3d<T>& other) const + { + vector3d<T> cross = other.Normal.crossProduct(Normal); + return cross.getLength() > core::ROUNDING_ERROR_f32; + } + + //! Intersects this plane with another. + /** \param other Other plane to intersect with. + \param outLinePoint Base point of intersection line. + \param outLineVect Vector of intersection. + \return True if there is a intersection, false if not. */ + bool getIntersectionWithPlane(const plane3d<T>& other, + vector3d<T>& outLinePoint, + vector3d<T>& outLineVect) const + { + const T fn00 = Normal.getLength(); + const T fn01 = Normal.dotProduct(other.Normal); + const T fn11 = other.Normal.getLength(); + const f64 det = fn00*fn11 - fn01*fn01; + + if (fabs(det) < ROUNDING_ERROR_f64 ) + return false; + + const f64 invdet = 1.0 / det; + const f64 fc0 = (fn11*-D + fn01*other.D) * invdet; + const f64 fc1 = (fn00*-other.D + fn01*D) * invdet; + + outLineVect = Normal.crossProduct(other.Normal); + outLinePoint = Normal*(T)fc0 + other.Normal*(T)fc1; + return true; + } + + //! Get the intersection point with two other planes if there is one. + bool getIntersectionWithPlanes(const plane3d<T>& o1, + const plane3d<T>& o2, vector3d<T>& outPoint) const + { + vector3d<T> linePoint, lineVect; + if (getIntersectionWithPlane(o1, linePoint, lineVect)) + return o2.getIntersectionWithLine(linePoint, lineVect, outPoint); + + return false; + } + + //! Test if the triangle would be front or backfacing from any point. + /** Thus, this method assumes a camera position from + which the triangle is definitely visible when looking into + the given direction. + Note that this only works if the normal is Normalized. + Do not use this method with points as it will give wrong results! + \param lookDirection: Look direction. + \return True if the plane is front facing and + false if it is backfacing. */ + bool isFrontFacing(const vector3d<T>& lookDirection) const + { + const f32 d = Normal.dotProduct(lookDirection); + return F32_LOWER_EQUAL_0 ( d ); + } + + //! Get the distance to a point. + /** Note that this only works if the normal is normalized. */ + T getDistanceTo(const vector3d<T>& point) const + { + return point.dotProduct(Normal) + D; + } + + //! Normal vector of the plane. + vector3d<T> Normal; + + //! Distance from origin. + T D; +}; + + +//! Typedef for a f32 3d plane. +typedef plane3d<f32> plane3df; + +//! Typedef for an integer 3d plane. +typedef plane3d<s32> plane3di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/position2d.h b/builddir/irrlicht-1.8.1/include/position2d.h new file mode 100644 index 0000000..05a27c6 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/position2d.h @@ -0,0 +1,32 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +//! As of Irrlicht 1.6, position2d is a synonym for vector2d. +/** You should consider position2d to be deprecated, and use vector2d by preference. */ + +#ifndef __IRR_POSITION_H_INCLUDED__ +#define __IRR_POSITION_H_INCLUDED__ + +#include "vector2d.h" + +namespace irr +{ +namespace core +{ + +// Use typedefs where possible as they are more explicit... + +//! \deprecated position2d is now a synonym for vector2d, but vector2d should be used directly. +typedef vector2d<f32> position2df; + +//! \deprecated position2d is now a synonym for vector2d, but vector2d should be used directly. +typedef vector2d<s32> position2di; +} // namespace core +} // namespace irr + +// ...and use a #define to catch the rest, for (e.g.) position2d<f64> +#define position2d vector2d + +#endif // __IRR_POSITION_H_INCLUDED__ + diff --git a/builddir/irrlicht-1.8.1/include/quaternion.h b/builddir/irrlicht-1.8.1/include/quaternion.h new file mode 100644 index 0000000..130ba8c --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/quaternion.h @@ -0,0 +1,696 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_QUATERNION_H_INCLUDED__ +#define __IRR_QUATERNION_H_INCLUDED__ + +#include "irrTypes.h" +#include "irrMath.h" +#include "matrix4.h" +#include "vector3d.h" + +// Between Irrlicht 1.7 and Irrlicht 1.8 the quaternion-matrix conversions got fixed. +// This define disables all involved functions completely to allow finding all places +// where the wrong conversions had been in use. +#define IRR_TEST_BROKEN_QUATERNION_USE 0 + +namespace irr +{ +namespace core +{ + +//! Quaternion class for representing rotations. +/** It provides cheap combinations and avoids gimbal locks. +Also useful for interpolations. */ +class quaternion +{ + public: + + //! Default Constructor + quaternion() : X(0.0f), Y(0.0f), Z(0.0f), W(1.0f) {} + + //! Constructor + quaternion(f32 x, f32 y, f32 z, f32 w) : X(x), Y(y), Z(z), W(w) { } + + //! Constructor which converts euler angles (radians) to a quaternion + quaternion(f32 x, f32 y, f32 z); + + //! Constructor which converts euler angles (radians) to a quaternion + quaternion(const vector3df& vec); + +#if !IRR_TEST_BROKEN_QUATERNION_USE + //! Constructor which converts a matrix to a quaternion + quaternion(const matrix4& mat); +#endif + + //! Equalilty operator + bool operator==(const quaternion& other) const; + + //! inequality operator + bool operator!=(const quaternion& other) const; + + //! Assignment operator + inline quaternion& operator=(const quaternion& other); + +#if !IRR_TEST_BROKEN_QUATERNION_USE + //! Matrix assignment operator + inline quaternion& operator=(const matrix4& other); +#endif + + //! Add operator + quaternion operator+(const quaternion& other) const; + + //! Multiplication operator + quaternion operator*(const quaternion& other) const; + + //! Multiplication operator with scalar + quaternion operator*(f32 s) const; + + //! Multiplication operator with scalar + quaternion& operator*=(f32 s); + + //! Multiplication operator + vector3df operator*(const vector3df& v) const; + + //! Multiplication operator + quaternion& operator*=(const quaternion& other); + + //! Calculates the dot product + inline f32 dotProduct(const quaternion& other) const; + + //! Sets new quaternion + inline quaternion& set(f32 x, f32 y, f32 z, f32 w); + + //! Sets new quaternion based on euler angles (radians) + inline quaternion& set(f32 x, f32 y, f32 z); + + //! Sets new quaternion based on euler angles (radians) + inline quaternion& set(const core::vector3df& vec); + + //! Sets new quaternion from other quaternion + inline quaternion& set(const core::quaternion& quat); + + //! returns if this quaternion equals the other one, taking floating point rounding errors into account + inline bool equals(const quaternion& other, + const f32 tolerance = ROUNDING_ERROR_f32 ) const; + + //! Normalizes the quaternion + inline quaternion& normalize(); + +#if !IRR_TEST_BROKEN_QUATERNION_USE + //! Creates a matrix from this quaternion + matrix4 getMatrix() const; +#endif + + //! Creates a matrix from this quaternion + void getMatrix( matrix4 &dest, const core::vector3df &translation=core::vector3df() ) const; + + /*! + Creates a matrix from this quaternion + Rotate about a center point + shortcut for + core::quaternion q; + q.rotationFromTo ( vin[i].Normal, forward ); + q.getMatrixCenter ( lookat, center, newPos ); + + core::matrix4 m2; + m2.setInverseTranslation ( center ); + lookat *= m2; + + core::matrix4 m3; + m2.setTranslation ( newPos ); + lookat *= m3; + + */ + void getMatrixCenter( matrix4 &dest, const core::vector3df ¢er, const core::vector3df &translation ) const; + + //! Creates a matrix from this quaternion + inline void getMatrix_transposed( matrix4 &dest ) const; + + //! Inverts this quaternion + quaternion& makeInverse(); + + //! Set this quaternion to the linear interpolation between two quaternions + /** \param q1 First quaternion to be interpolated. + \param q2 Second quaternion to be interpolated. + \param time Progress of interpolation. For time=0 the result is + q1, for time=1 the result is q2. Otherwise interpolation + between q1 and q2. + */ + quaternion& lerp(quaternion q1, quaternion q2, f32 time); + + //! Set this quaternion to the result of the spherical interpolation between two quaternions + /** \param q1 First quaternion to be interpolated. + \param q2 Second quaternion to be interpolated. + \param time Progress of interpolation. For time=0 the result is + q1, for time=1 the result is q2. Otherwise interpolation + between q1 and q2. + \param threshold To avoid inaccuracies at the end (time=1) the + interpolation switches to linear interpolation at some point. + This value defines how much of the remaining interpolation will + be calculated with lerp. Everything from 1-threshold up will be + linear interpolation. + */ + quaternion& slerp(quaternion q1, quaternion q2, + f32 time, f32 threshold=.05f); + + //! Create quaternion from rotation angle and rotation axis. + /** Axis must be unit length. + The quaternion representing the rotation is + q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k). + \param angle Rotation Angle in radians. + \param axis Rotation axis. */ + quaternion& fromAngleAxis (f32 angle, const vector3df& axis); + + //! Fills an angle (radians) around an axis (unit vector) + void toAngleAxis (f32 &angle, core::vector3df& axis) const; + + //! Output this quaternion to an euler angle (radians) + void toEuler(vector3df& euler) const; + + //! Set quaternion to identity + quaternion& makeIdentity(); + + //! Set quaternion to represent a rotation from one vector to another. + quaternion& rotationFromTo(const vector3df& from, const vector3df& to); + + //! Quaternion elements. + f32 X; // vectorial (imaginary) part + f32 Y; + f32 Z; + f32 W; // real part +}; + + +// Constructor which converts euler angles to a quaternion +inline quaternion::quaternion(f32 x, f32 y, f32 z) +{ + set(x,y,z); +} + + +// Constructor which converts euler angles to a quaternion +inline quaternion::quaternion(const vector3df& vec) +{ + set(vec.X,vec.Y,vec.Z); +} + +#if !IRR_TEST_BROKEN_QUATERNION_USE +// Constructor which converts a matrix to a quaternion +inline quaternion::quaternion(const matrix4& mat) +{ + (*this) = mat; +} +#endif + +// equal operator +inline bool quaternion::operator==(const quaternion& other) const +{ + return ((X == other.X) && + (Y == other.Y) && + (Z == other.Z) && + (W == other.W)); +} + +// inequality operator +inline bool quaternion::operator!=(const quaternion& other) const +{ + return !(*this == other); +} + +// assignment operator +inline quaternion& quaternion::operator=(const quaternion& other) +{ + X = other.X; + Y = other.Y; + Z = other.Z; + W = other.W; + return *this; +} + +#if !IRR_TEST_BROKEN_QUATERNION_USE +// matrix assignment operator +inline quaternion& quaternion::operator=(const matrix4& m) +{ + const f32 diag = m[0] + m[5] + m[10] + 1; + + if( diag > 0.0f ) + { + const f32 scale = sqrtf(diag) * 2.0f; // get scale from diagonal + + // TODO: speed this up + X = (m[6] - m[9]) / scale; + Y = (m[8] - m[2]) / scale; + Z = (m[1] - m[4]) / scale; + W = 0.25f * scale; + } + else + { + if (m[0]>m[5] && m[0]>m[10]) + { + // 1st element of diag is greatest value + // find scale according to 1st element, and double it + const f32 scale = sqrtf(1.0f + m[0] - m[5] - m[10]) * 2.0f; + + // TODO: speed this up + X = 0.25f * scale; + Y = (m[4] + m[1]) / scale; + Z = (m[2] + m[8]) / scale; + W = (m[6] - m[9]) / scale; + } + else if (m[5]>m[10]) + { + // 2nd element of diag is greatest value + // find scale according to 2nd element, and double it + const f32 scale = sqrtf(1.0f + m[5] - m[0] - m[10]) * 2.0f; + + // TODO: speed this up + X = (m[4] + m[1]) / scale; + Y = 0.25f * scale; + Z = (m[9] + m[6]) / scale; + W = (m[8] - m[2]) / scale; + } + else + { + // 3rd element of diag is greatest value + // find scale according to 3rd element, and double it + const f32 scale = sqrtf(1.0f + m[10] - m[0] - m[5]) * 2.0f; + + // TODO: speed this up + X = (m[8] + m[2]) / scale; + Y = (m[9] + m[6]) / scale; + Z = 0.25f * scale; + W = (m[1] - m[4]) / scale; + } + } + + return normalize(); +} +#endif + + +// multiplication operator +inline quaternion quaternion::operator*(const quaternion& other) const +{ + quaternion tmp; + + tmp.W = (other.W * W) - (other.X * X) - (other.Y * Y) - (other.Z * Z); + tmp.X = (other.W * X) + (other.X * W) + (other.Y * Z) - (other.Z * Y); + tmp.Y = (other.W * Y) + (other.Y * W) + (other.Z * X) - (other.X * Z); + tmp.Z = (other.W * Z) + (other.Z * W) + (other.X * Y) - (other.Y * X); + + return tmp; +} + + +// multiplication operator +inline quaternion quaternion::operator*(f32 s) const +{ + return quaternion(s*X, s*Y, s*Z, s*W); +} + + +// multiplication operator +inline quaternion& quaternion::operator*=(f32 s) +{ + X*=s; + Y*=s; + Z*=s; + W*=s; + return *this; +} + +// multiplication operator +inline quaternion& quaternion::operator*=(const quaternion& other) +{ + return (*this = other * (*this)); +} + +// add operator +inline quaternion quaternion::operator+(const quaternion& b) const +{ + return quaternion(X+b.X, Y+b.Y, Z+b.Z, W+b.W); +} + +#if !IRR_TEST_BROKEN_QUATERNION_USE +// Creates a matrix from this quaternion +inline matrix4 quaternion::getMatrix() const +{ + core::matrix4 m; + getMatrix(m); + return m; +} +#endif + +/*! + Creates a matrix from this quaternion +*/ +inline void quaternion::getMatrix(matrix4 &dest, + const core::vector3df ¢er) const +{ + dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z; + dest[1] = 2.0f*X*Y + 2.0f*Z*W; + dest[2] = 2.0f*X*Z - 2.0f*Y*W; + dest[3] = 0.0f; + + dest[4] = 2.0f*X*Y - 2.0f*Z*W; + dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z; + dest[6] = 2.0f*Z*Y + 2.0f*X*W; + dest[7] = 0.0f; + + dest[8] = 2.0f*X*Z + 2.0f*Y*W; + dest[9] = 2.0f*Z*Y - 2.0f*X*W; + dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y; + dest[11] = 0.0f; + + dest[12] = center.X; + dest[13] = center.Y; + dest[14] = center.Z; + dest[15] = 1.f; + + dest.setDefinitelyIdentityMatrix ( false ); +} + + +/*! + Creates a matrix from this quaternion + Rotate about a center point + shortcut for + core::quaternion q; + q.rotationFromTo(vin[i].Normal, forward); + q.getMatrix(lookat, center); + + core::matrix4 m2; + m2.setInverseTranslation(center); + lookat *= m2; +*/ +inline void quaternion::getMatrixCenter(matrix4 &dest, + const core::vector3df ¢er, + const core::vector3df &translation) const +{ + dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z; + dest[1] = 2.0f*X*Y + 2.0f*Z*W; + dest[2] = 2.0f*X*Z - 2.0f*Y*W; + dest[3] = 0.0f; + + dest[4] = 2.0f*X*Y - 2.0f*Z*W; + dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z; + dest[6] = 2.0f*Z*Y + 2.0f*X*W; + dest[7] = 0.0f; + + dest[8] = 2.0f*X*Z + 2.0f*Y*W; + dest[9] = 2.0f*Z*Y - 2.0f*X*W; + dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y; + dest[11] = 0.0f; + + dest.setRotationCenter ( center, translation ); +} + +// Creates a matrix from this quaternion +inline void quaternion::getMatrix_transposed(matrix4 &dest) const +{ + dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z; + dest[4] = 2.0f*X*Y + 2.0f*Z*W; + dest[8] = 2.0f*X*Z - 2.0f*Y*W; + dest[12] = 0.0f; + + dest[1] = 2.0f*X*Y - 2.0f*Z*W; + dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z; + dest[9] = 2.0f*Z*Y + 2.0f*X*W; + dest[13] = 0.0f; + + dest[2] = 2.0f*X*Z + 2.0f*Y*W; + dest[6] = 2.0f*Z*Y - 2.0f*X*W; + dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y; + dest[14] = 0.0f; + + dest[3] = 0.f; + dest[7] = 0.f; + dest[11] = 0.f; + dest[15] = 1.f; + + dest.setDefinitelyIdentityMatrix(false); +} + + +// Inverts this quaternion +inline quaternion& quaternion::makeInverse() +{ + X = -X; Y = -Y; Z = -Z; + return *this; +} + + +// sets new quaternion +inline quaternion& quaternion::set(f32 x, f32 y, f32 z, f32 w) +{ + X = x; + Y = y; + Z = z; + W = w; + return *this; +} + + +// sets new quaternion based on euler angles +inline quaternion& quaternion::set(f32 x, f32 y, f32 z) +{ + f64 angle; + + angle = x * 0.5; + const f64 sr = sin(angle); + const f64 cr = cos(angle); + + angle = y * 0.5; + const f64 sp = sin(angle); + const f64 cp = cos(angle); + + angle = z * 0.5; + const f64 sy = sin(angle); + const f64 cy = cos(angle); + + const f64 cpcy = cp * cy; + const f64 spcy = sp * cy; + const f64 cpsy = cp * sy; + const f64 spsy = sp * sy; + + X = (f32)(sr * cpcy - cr * spsy); + Y = (f32)(cr * spcy + sr * cpsy); + Z = (f32)(cr * cpsy - sr * spcy); + W = (f32)(cr * cpcy + sr * spsy); + + return normalize(); +} + +// sets new quaternion based on euler angles +inline quaternion& quaternion::set(const core::vector3df& vec) +{ + return set(vec.X, vec.Y, vec.Z); +} + +// sets new quaternion based on other quaternion +inline quaternion& quaternion::set(const core::quaternion& quat) +{ + return (*this=quat); +} + + +//! returns if this quaternion equals the other one, taking floating point rounding errors into account +inline bool quaternion::equals(const quaternion& other, const f32 tolerance) const +{ + return core::equals(X, other.X, tolerance) && + core::equals(Y, other.Y, tolerance) && + core::equals(Z, other.Z, tolerance) && + core::equals(W, other.W, tolerance); +} + + +// normalizes the quaternion +inline quaternion& quaternion::normalize() +{ + const f32 n = X*X + Y*Y + Z*Z + W*W; + + if (n == 1) + return *this; + + //n = 1.0f / sqrtf(n); + return (*this *= reciprocal_squareroot ( n )); +} + + +// set this quaternion to the result of the linear interpolation between two quaternions +inline quaternion& quaternion::lerp(quaternion q1, quaternion q2, f32 time) +{ + const f32 scale = 1.0f - time; + return (*this = (q1*scale) + (q2*time)); +} + + +// set this quaternion to the result of the interpolation between two quaternions +inline quaternion& quaternion::slerp(quaternion q1, quaternion q2, f32 time, f32 threshold) +{ + f32 angle = q1.dotProduct(q2); + + // make sure we use the short rotation + if (angle < 0.0f) + { + q1 *= -1.0f; + angle *= -1.0f; + } + + if (angle <= (1-threshold)) // spherical interpolation + { + const f32 theta = acosf(angle); + const f32 invsintheta = reciprocal(sinf(theta)); + const f32 scale = sinf(theta * (1.0f-time)) * invsintheta; + const f32 invscale = sinf(theta * time) * invsintheta; + return (*this = (q1*scale) + (q2*invscale)); + } + else // linear interploation + return lerp(q1,q2,time); +} + + +// calculates the dot product +inline f32 quaternion::dotProduct(const quaternion& q2) const +{ + return (X * q2.X) + (Y * q2.Y) + (Z * q2.Z) + (W * q2.W); +} + + +//! axis must be unit length, angle in radians +inline quaternion& quaternion::fromAngleAxis(f32 angle, const vector3df& axis) +{ + const f32 fHalfAngle = 0.5f*angle; + const f32 fSin = sinf(fHalfAngle); + W = cosf(fHalfAngle); + X = fSin*axis.X; + Y = fSin*axis.Y; + Z = fSin*axis.Z; + return *this; +} + + +inline void quaternion::toAngleAxis(f32 &angle, core::vector3df &axis) const +{ + const f32 scale = sqrtf(X*X + Y*Y + Z*Z); + + if (core::iszero(scale) || W > 1.0f || W < -1.0f) + { + angle = 0.0f; + axis.X = 0.0f; + axis.Y = 1.0f; + axis.Z = 0.0f; + } + else + { + const f32 invscale = reciprocal(scale); + angle = 2.0f * acosf(W); + axis.X = X * invscale; + axis.Y = Y * invscale; + axis.Z = Z * invscale; + } +} + +inline void quaternion::toEuler(vector3df& euler) const +{ + const f64 sqw = W*W; + const f64 sqx = X*X; + const f64 sqy = Y*Y; + const f64 sqz = Z*Z; + const f64 test = 2.0 * (Y*W - X*Z); + + if (core::equals(test, 1.0, 0.000001)) + { + // heading = rotation about z-axis + euler.Z = (f32) (-2.0*atan2(X, W)); + // bank = rotation about x-axis + euler.X = 0; + // attitude = rotation about y-axis + euler.Y = (f32) (core::PI64/2.0); + } + else if (core::equals(test, -1.0, 0.000001)) + { + // heading = rotation about z-axis + euler.Z = (f32) (2.0*atan2(X, W)); + // bank = rotation about x-axis + euler.X = 0; + // attitude = rotation about y-axis + euler.Y = (f32) (core::PI64/-2.0); + } + else + { + // heading = rotation about z-axis + euler.Z = (f32) atan2(2.0 * (X*Y +Z*W),(sqx - sqy - sqz + sqw)); + // bank = rotation about x-axis + euler.X = (f32) atan2(2.0 * (Y*Z +X*W),(-sqx - sqy + sqz + sqw)); + // attitude = rotation about y-axis + euler.Y = (f32) asin( clamp(test, -1.0, 1.0) ); + } +} + + +inline vector3df quaternion::operator* (const vector3df& v) const +{ + // nVidia SDK implementation + + vector3df uv, uuv; + vector3df qvec(X, Y, Z); + uv = qvec.crossProduct(v); + uuv = qvec.crossProduct(uv); + uv *= (2.0f * W); + uuv *= 2.0f; + + return v + uv + uuv; +} + +// set quaternion to identity +inline core::quaternion& quaternion::makeIdentity() +{ + W = 1.f; + X = 0.f; + Y = 0.f; + Z = 0.f; + return *this; +} + +inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const vector3df& to) +{ + // Based on Stan Melax's article in Game Programming Gems + // Copy, since cannot modify local + vector3df v0 = from; + vector3df v1 = to; + v0.normalize(); + v1.normalize(); + + const f32 d = v0.dotProduct(v1); + if (d >= 1.0f) // If dot == 1, vectors are the same + { + return makeIdentity(); + } + else if (d <= -1.0f) // exactly opposite + { + core::vector3df axis(1.0f, 0.f, 0.f); + axis = axis.crossProduct(v0); + if (axis.getLength()==0) + { + axis.set(0.f,1.f,0.f); + axis = axis.crossProduct(v0); + } + // same as fromAngleAxis(core::PI, axis).normalize(); + return set(axis.X, axis.Y, axis.Z, 0).normalize(); + } + + const f32 s = sqrtf( (1+d)*2 ); // optimize inv_sqrt + const f32 invs = 1.f / s; + const vector3df c = v0.crossProduct(v1)*invs; + return set(c.X, c.Y, c.Z, s * 0.5f).normalize(); +} + + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/rect.h b/builddir/irrlicht-1.8.1/include/rect.h new file mode 100644 index 0000000..1e2572c --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/rect.h @@ -0,0 +1,279 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_RECT_H_INCLUDED__ +#define __IRR_RECT_H_INCLUDED__ + +#include "irrTypes.h" +#include "dimension2d.h" +#include "position2d.h" + +namespace irr +{ +namespace core +{ + + //! Rectangle template. + /** Mostly used by 2D GUI elements and for 2D drawing methods. + It has 2 positions instead of position and dimension and a fast + method for collision detection with other rectangles and points. + + Coordinates are (0,0) for top-left corner, and increasing to the right + and to the bottom. + */ + template <class T> + class rect + { + public: + + //! Default constructor creating empty rectangle at (0,0) + rect() : UpperLeftCorner(0,0), LowerRightCorner(0,0) {} + + //! Constructor with two corners + rect(T x, T y, T x2, T y2) + : UpperLeftCorner(x,y), LowerRightCorner(x2,y2) {} + + //! Constructor with two corners + rect(const position2d<T>& upperLeft, const position2d<T>& lowerRight) + : UpperLeftCorner(upperLeft), LowerRightCorner(lowerRight) {} + + //! Constructor with upper left corner and dimension + template <class U> + rect(const position2d<T>& pos, const dimension2d<U>& size) + : UpperLeftCorner(pos), LowerRightCorner(pos.X + size.Width, pos.Y + size.Height) {} + + //! move right by given numbers + rect<T> operator+(const position2d<T>& pos) const + { + rect<T> ret(*this); + return ret+=pos; + } + + //! move right by given numbers + rect<T>& operator+=(const position2d<T>& pos) + { + UpperLeftCorner += pos; + LowerRightCorner += pos; + return *this; + } + + //! move left by given numbers + rect<T> operator-(const position2d<T>& pos) const + { + rect<T> ret(*this); + return ret-=pos; + } + + //! move left by given numbers + rect<T>& operator-=(const position2d<T>& pos) + { + UpperLeftCorner -= pos; + LowerRightCorner -= pos; + return *this; + } + + //! equality operator + bool operator==(const rect<T>& other) const + { + return (UpperLeftCorner == other.UpperLeftCorner && + LowerRightCorner == other.LowerRightCorner); + } + + //! inequality operator + bool operator!=(const rect<T>& other) const + { + return (UpperLeftCorner != other.UpperLeftCorner || + LowerRightCorner != other.LowerRightCorner); + } + + //! compares size of rectangles + bool operator<(const rect<T>& other) const + { + return getArea() < other.getArea(); + } + + //! Returns size of rectangle + T getArea() const + { + return getWidth() * getHeight(); + } + + //! Returns if a 2d point is within this rectangle. + /** \param pos Position to test if it lies within this rectangle. + \return True if the position is within the rectangle, false if not. */ + bool isPointInside(const position2d<T>& pos) const + { + return (UpperLeftCorner.X <= pos.X && + UpperLeftCorner.Y <= pos.Y && + LowerRightCorner.X >= pos.X && + LowerRightCorner.Y >= pos.Y); + } + + //! Check if the rectangle collides with another rectangle. + /** \param other Rectangle to test collision with + \return True if the rectangles collide. */ + bool isRectCollided(const rect<T>& other) const + { + return (LowerRightCorner.Y > other.UpperLeftCorner.Y && + UpperLeftCorner.Y < other.LowerRightCorner.Y && + LowerRightCorner.X > other.UpperLeftCorner.X && + UpperLeftCorner.X < other.LowerRightCorner.X); + } + + //! Clips this rectangle with another one. + /** \param other Rectangle to clip with */ + void clipAgainst(const rect<T>& other) + { + if (other.LowerRightCorner.X < LowerRightCorner.X) + LowerRightCorner.X = other.LowerRightCorner.X; + if (other.LowerRightCorner.Y < LowerRightCorner.Y) + LowerRightCorner.Y = other.LowerRightCorner.Y; + + if (other.UpperLeftCorner.X > UpperLeftCorner.X) + UpperLeftCorner.X = other.UpperLeftCorner.X; + if (other.UpperLeftCorner.Y > UpperLeftCorner.Y) + UpperLeftCorner.Y = other.UpperLeftCorner.Y; + + // correct possible invalid rect resulting from clipping + if (UpperLeftCorner.Y > LowerRightCorner.Y) + UpperLeftCorner.Y = LowerRightCorner.Y; + if (UpperLeftCorner.X > LowerRightCorner.X) + UpperLeftCorner.X = LowerRightCorner.X; + } + + //! Moves this rectangle to fit inside another one. + /** \return True on success, false if not possible */ + bool constrainTo(const rect<T>& other) + { + if (other.getWidth() < getWidth() || other.getHeight() < getHeight()) + return false; + + T diff = other.LowerRightCorner.X - LowerRightCorner.X; + if (diff < 0) + { + LowerRightCorner.X += diff; + UpperLeftCorner.X += diff; + } + + diff = other.LowerRightCorner.Y - LowerRightCorner.Y; + if (diff < 0) + { + LowerRightCorner.Y += diff; + UpperLeftCorner.Y += diff; + } + + diff = UpperLeftCorner.X - other.UpperLeftCorner.X; + if (diff < 0) + { + UpperLeftCorner.X -= diff; + LowerRightCorner.X -= diff; + } + + diff = UpperLeftCorner.Y - other.UpperLeftCorner.Y; + if (diff < 0) + { + UpperLeftCorner.Y -= diff; + LowerRightCorner.Y -= diff; + } + + return true; + } + + //! Get width of rectangle. + T getWidth() const + { + return LowerRightCorner.X - UpperLeftCorner.X; + } + + //! Get height of rectangle. + T getHeight() const + { + return LowerRightCorner.Y - UpperLeftCorner.Y; + } + + //! If the lower right corner of the rect is smaller then the upper left, the points are swapped. + void repair() + { + if (LowerRightCorner.X < UpperLeftCorner.X) + { + T t = LowerRightCorner.X; + LowerRightCorner.X = UpperLeftCorner.X; + UpperLeftCorner.X = t; + } + + if (LowerRightCorner.Y < UpperLeftCorner.Y) + { + T t = LowerRightCorner.Y; + LowerRightCorner.Y = UpperLeftCorner.Y; + UpperLeftCorner.Y = t; + } + } + + //! Returns if the rect is valid to draw. + /** It would be invalid if the UpperLeftCorner is lower or more + right than the LowerRightCorner. */ + bool isValid() const + { + return ((LowerRightCorner.X >= UpperLeftCorner.X) && + (LowerRightCorner.Y >= UpperLeftCorner.Y)); + } + + //! Get the center of the rectangle + position2d<T> getCenter() const + { + return position2d<T>( + (UpperLeftCorner.X + LowerRightCorner.X) / 2, + (UpperLeftCorner.Y + LowerRightCorner.Y) / 2); + } + + //! Get the dimensions of the rectangle + dimension2d<T> getSize() const + { + return dimension2d<T>(getWidth(), getHeight()); + } + + + //! Adds a point to the rectangle + /** Causes the rectangle to grow bigger if point is outside of + the box + \param p Point to add to the box. */ + void addInternalPoint(const position2d<T>& p) + { + addInternalPoint(p.X, p.Y); + } + + //! Adds a point to the bounding rectangle + /** Causes the rectangle to grow bigger if point is outside of + the box + \param x X-Coordinate of the point to add to this box. + \param y Y-Coordinate of the point to add to this box. */ + void addInternalPoint(T x, T y) + { + if (x>LowerRightCorner.X) + LowerRightCorner.X = x; + if (y>LowerRightCorner.Y) + LowerRightCorner.Y = y; + + if (x<UpperLeftCorner.X) + UpperLeftCorner.X = x; + if (y<UpperLeftCorner.Y) + UpperLeftCorner.Y = y; + } + + //! Upper left corner + position2d<T> UpperLeftCorner; + //! Lower right corner + position2d<T> LowerRightCorner; + }; + + //! Rectangle with float values + typedef rect<f32> rectf; + //! Rectangle with int values + typedef rect<s32> recti; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/triangle3d.h b/builddir/irrlicht-1.8.1/include/triangle3d.h new file mode 100644 index 0000000..dbf8a8b --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/triangle3d.h @@ -0,0 +1,279 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_TRIANGLE_3D_H_INCLUDED__ +#define __IRR_TRIANGLE_3D_H_INCLUDED__ + +#include "vector3d.h" +#include "line3d.h" +#include "plane3d.h" +#include "aabbox3d.h" + +namespace irr +{ +namespace core +{ + + //! 3d triangle template class for doing collision detection and other things. + template <class T> + class triangle3d + { + public: + + //! Constructor for an all 0 triangle + triangle3d() {} + //! Constructor for triangle with given three vertices + triangle3d(vector3d<T> v1, vector3d<T> v2, vector3d<T> v3) : pointA(v1), pointB(v2), pointC(v3) {} + + //! Equality operator + bool operator==(const triangle3d<T>& other) const + { + return other.pointA==pointA && other.pointB==pointB && other.pointC==pointC; + } + + //! Inequality operator + bool operator!=(const triangle3d<T>& other) const + { + return !(*this==other); + } + + //! Determines if the triangle is totally inside a bounding box. + /** \param box Box to check. + \return True if triangle is within the box, otherwise false. */ + bool isTotalInsideBox(const aabbox3d<T>& box) const + { + return (box.isPointInside(pointA) && + box.isPointInside(pointB) && + box.isPointInside(pointC)); + } + + //! Determines if the triangle is totally outside a bounding box. + /** \param box Box to check. + \return True if triangle is outside the box, otherwise false. */ + bool isTotalOutsideBox(const aabbox3d<T>& box) const + { + return ((pointA.X > box.MaxEdge.X && pointB.X > box.MaxEdge.X && pointC.X > box.MaxEdge.X) || + + (pointA.Y > box.MaxEdge.Y && pointB.Y > box.MaxEdge.Y && pointC.Y > box.MaxEdge.Y) || + (pointA.Z > box.MaxEdge.Z && pointB.Z > box.MaxEdge.Z && pointC.Z > box.MaxEdge.Z) || + (pointA.X < box.MinEdge.X && pointB.X < box.MinEdge.X && pointC.X < box.MinEdge.X) || + (pointA.Y < box.MinEdge.Y && pointB.Y < box.MinEdge.Y && pointC.Y < box.MinEdge.Y) || + (pointA.Z < box.MinEdge.Z && pointB.Z < box.MinEdge.Z && pointC.Z < box.MinEdge.Z)); + } + + //! Get the closest point on a triangle to a point on the same plane. + /** \param p Point which must be on the same plane as the triangle. + \return The closest point of the triangle */ + core::vector3d<T> closestPointOnTriangle(const core::vector3d<T>& p) const + { + const core::vector3d<T> rab = line3d<T>(pointA, pointB).getClosestPoint(p); + const core::vector3d<T> rbc = line3d<T>(pointB, pointC).getClosestPoint(p); + const core::vector3d<T> rca = line3d<T>(pointC, pointA).getClosestPoint(p); + + const T d1 = rab.getDistanceFrom(p); + const T d2 = rbc.getDistanceFrom(p); + const T d3 = rca.getDistanceFrom(p); + + if (d1 < d2) + return d1 < d3 ? rab : rca; + + return d2 < d3 ? rbc : rca; + } + + //! Check if a point is inside the triangle (border-points count also as inside) + /* + \param p Point to test. Assumes that this point is already + on the plane of the triangle. + \return True if the point is inside the triangle, otherwise false. */ + bool isPointInside(const vector3d<T>& p) const + { + vector3d<f64> af64((f64)pointA.X, (f64)pointA.Y, (f64)pointA.Z); + vector3d<f64> bf64((f64)pointB.X, (f64)pointB.Y, (f64)pointB.Z); + vector3d<f64> cf64((f64)pointC.X, (f64)pointC.Y, (f64)pointC.Z); + vector3d<f64> pf64((f64)p.X, (f64)p.Y, (f64)p.Z); + return (isOnSameSide(pf64, af64, bf64, cf64) && + isOnSameSide(pf64, bf64, af64, cf64) && + isOnSameSide(pf64, cf64, af64, bf64)); + } + + //! Check if a point is inside the triangle (border-points count also as inside) + /** This method uses a barycentric coordinate system. + It is faster than isPointInside but is more susceptible to floating point rounding + errors. This will especially be noticable when the FPU is in single precision mode + (which is for example set on default by Direct3D). + \param p Point to test. Assumes that this point is already + on the plane of the triangle. + \return True if point is inside the triangle, otherwise false. */ + bool isPointInsideFast(const vector3d<T>& p) const + { + const vector3d<T> a = pointC - pointA; + const vector3d<T> b = pointB - pointA; + const vector3d<T> c = p - pointA; + + const f64 dotAA = a.dotProduct( a); + const f64 dotAB = a.dotProduct( b); + const f64 dotAC = a.dotProduct( c); + const f64 dotBB = b.dotProduct( b); + const f64 dotBC = b.dotProduct( c); + + // get coordinates in barycentric coordinate system + const f64 invDenom = 1/(dotAA * dotBB - dotAB * dotAB); + const f64 u = (dotBB * dotAC - dotAB * dotBC) * invDenom; + const f64 v = (dotAA * dotBC - dotAB * dotAC ) * invDenom; + + // We count border-points as inside to keep downward compatibility. + // Rounding-error also needed for some test-cases. + return (u > -ROUNDING_ERROR_f32) && (v >= 0) && (u + v < 1+ROUNDING_ERROR_f32); + + } + + + //! Get an intersection with a 3d line. + /** \param line Line to intersect with. + \param outIntersection Place to store the intersection point, if there is one. + \return True if there was an intersection, false if not. */ + bool getIntersectionWithLimitedLine(const line3d<T>& line, + vector3d<T>& outIntersection) const + { + return getIntersectionWithLine(line.start, + line.getVector(), outIntersection) && + outIntersection.isBetweenPoints(line.start, line.end); + } + + + //! Get an intersection with a 3d line. + /** Please note that also points are returned as intersection which + are on the line, but not between the start and end point of the line. + If you want the returned point be between start and end + use getIntersectionWithLimitedLine(). + \param linePoint Point of the line to intersect with. + \param lineVect Vector of the line to intersect with. + \param outIntersection Place to store the intersection point, if there is one. + \return True if there was an intersection, false if there was not. */ + bool getIntersectionWithLine(const vector3d<T>& linePoint, + const vector3d<T>& lineVect, vector3d<T>& outIntersection) const + { + if (getIntersectionOfPlaneWithLine(linePoint, lineVect, outIntersection)) + return isPointInside(outIntersection); + + return false; + } + + + //! Calculates the intersection between a 3d line and the plane the triangle is on. + /** \param lineVect Vector of the line to intersect with. + \param linePoint Point of the line to intersect with. + \param outIntersection Place to store the intersection point, if there is one. + \return True if there was an intersection, else false. */ + bool getIntersectionOfPlaneWithLine(const vector3d<T>& linePoint, + const vector3d<T>& lineVect, vector3d<T>& outIntersection) const + { + // Work with f64 to get more precise results (makes enough difference to be worth the casts). + const vector3d<f64> linePointf64(linePoint.X, linePoint.Y, linePoint.Z); + const vector3d<f64> lineVectf64(lineVect.X, lineVect.Y, lineVect.Z); + vector3d<f64> outIntersectionf64; + + core::triangle3d<irr::f64> trianglef64(vector3d<f64>((f64)pointA.X, (f64)pointA.Y, (f64)pointA.Z) + ,vector3d<f64>((f64)pointB.X, (f64)pointB.Y, (f64)pointB.Z) + , vector3d<f64>((f64)pointC.X, (f64)pointC.Y, (f64)pointC.Z)); + const vector3d<irr::f64> normalf64 = trianglef64.getNormal().normalize(); + f64 t2; + + if ( core::iszero ( t2 = normalf64.dotProduct(lineVectf64) ) ) + return false; + + f64 d = trianglef64.pointA.dotProduct(normalf64); + f64 t = -(normalf64.dotProduct(linePointf64) - d) / t2; + outIntersectionf64 = linePointf64 + (lineVectf64 * t); + + outIntersection.X = (T)outIntersectionf64.X; + outIntersection.Y = (T)outIntersectionf64.Y; + outIntersection.Z = (T)outIntersectionf64.Z; + return true; + } + + + //! Get the normal of the triangle. + /** Please note: The normal is not always normalized. */ + vector3d<T> getNormal() const + { + return (pointB - pointA).crossProduct(pointC - pointA); + } + + //! Test if the triangle would be front or backfacing from any point. + /** Thus, this method assumes a camera position from which the + triangle is definitely visible when looking at the given direction. + Do not use this method with points as it will give wrong results! + \param lookDirection Look direction. + \return True if the plane is front facing and false if it is backfacing. */ + bool isFrontFacing(const vector3d<T>& lookDirection) const + { + const vector3d<T> n = getNormal().normalize(); + const f32 d = (f32)n.dotProduct(lookDirection); + return F32_LOWER_EQUAL_0(d); + } + + //! Get the plane of this triangle. + plane3d<T> getPlane() const + { + return plane3d<T>(pointA, pointB, pointC); + } + + //! Get the area of the triangle + T getArea() const + { + return (pointB - pointA).crossProduct(pointC - pointA).getLength() * 0.5f; + + } + + //! sets the triangle's points + void set(const core::vector3d<T>& a, const core::vector3d<T>& b, const core::vector3d<T>& c) + { + pointA = a; + pointB = b; + pointC = c; + } + + //! the three points of the triangle + vector3d<T> pointA; + vector3d<T> pointB; + vector3d<T> pointC; + + private: + // Using f64 instead of <T> to avoid integer overflows when T=int (maybe also less floating point troubles). + bool isOnSameSide(const vector3d<f64>& p1, const vector3d<f64>& p2, + const vector3d<f64>& a, const vector3d<f64>& b) const + { + vector3d<f64> bminusa = b - a; + vector3d<f64> cp1 = bminusa.crossProduct(p1 - a); + vector3d<f64> cp2 = bminusa.crossProduct(p2 - a); + f64 res = cp1.dotProduct(cp2); + if ( res < 0 ) + { + // This catches some floating point troubles. + // Unfortunately slightly expensive and we don't really know the best epsilon for iszero. + vector3d<f64> cp1 = bminusa.normalize().crossProduct((p1 - a).normalize()); + if ( core::iszero(cp1.X, (f64)ROUNDING_ERROR_f32) + && core::iszero(cp1.Y, (f64)ROUNDING_ERROR_f32) + && core::iszero(cp1.Z, (f64)ROUNDING_ERROR_f32) ) + { + res = 0.f; + } + } + return (res >= 0.0f); + } + }; + + + //! Typedef for a f32 3d triangle. + typedef triangle3d<f32> triangle3df; + + //! Typedef for an integer 3d triangle. + typedef triangle3d<s32> triangle3di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/vector2d.h b/builddir/irrlicht-1.8.1/include/vector2d.h new file mode 100644 index 0000000..0927dfc --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/vector2d.h @@ -0,0 +1,342 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_POINT_2D_H_INCLUDED__ +#define __IRR_POINT_2D_H_INCLUDED__ + +#include "irrMath.h" +#include "dimension2d.h" + +namespace irr +{ +namespace core +{ + + +//! 2d vector template class with lots of operators and methods. +/** As of Irrlicht 1.6, this class supercedes position2d, which should + be considered deprecated. */ +template <class T> +class vector2d +{ +public: + //! Default constructor (null vector) + vector2d() : X(0), Y(0) {} + //! Constructor with two different values + vector2d(T nx, T ny) : X(nx), Y(ny) {} + //! Constructor with the same value for both members + explicit vector2d(T n) : X(n), Y(n) {} + //! Copy constructor + vector2d(const vector2d<T>& other) : X(other.X), Y(other.Y) {} + + vector2d(const dimension2d<T>& other) : X(other.Width), Y(other.Height) {} + + // operators + + vector2d<T> operator-() const { return vector2d<T>(-X, -Y); } + + vector2d<T>& operator=(const vector2d<T>& other) { X = other.X; Y = other.Y; return *this; } + + vector2d<T>& operator=(const dimension2d<T>& other) { X = other.Width; Y = other.Height; return *this; } + + vector2d<T> operator+(const vector2d<T>& other) const { return vector2d<T>(X + other.X, Y + other.Y); } + vector2d<T> operator+(const dimension2d<T>& other) const { return vector2d<T>(X + other.Width, Y + other.Height); } + vector2d<T>& operator+=(const vector2d<T>& other) { X+=other.X; Y+=other.Y; return *this; } + vector2d<T> operator+(const T v) const { return vector2d<T>(X + v, Y + v); } + vector2d<T>& operator+=(const T v) { X+=v; Y+=v; return *this; } + vector2d<T>& operator+=(const dimension2d<T>& other) { X += other.Width; Y += other.Height; return *this; } + + vector2d<T> operator-(const vector2d<T>& other) const { return vector2d<T>(X - other.X, Y - other.Y); } + vector2d<T> operator-(const dimension2d<T>& other) const { return vector2d<T>(X - other.Width, Y - other.Height); } + vector2d<T>& operator-=(const vector2d<T>& other) { X-=other.X; Y-=other.Y; return *this; } + vector2d<T> operator-(const T v) const { return vector2d<T>(X - v, Y - v); } + vector2d<T>& operator-=(const T v) { X-=v; Y-=v; return *this; } + vector2d<T>& operator-=(const dimension2d<T>& other) { X -= other.Width; Y -= other.Height; return *this; } + + vector2d<T> operator*(const vector2d<T>& other) const { return vector2d<T>(X * other.X, Y * other.Y); } + vector2d<T>& operator*=(const vector2d<T>& other) { X*=other.X; Y*=other.Y; return *this; } + vector2d<T> operator*(const T v) const { return vector2d<T>(X * v, Y * v); } + vector2d<T>& operator*=(const T v) { X*=v; Y*=v; return *this; } + + vector2d<T> operator/(const vector2d<T>& other) const { return vector2d<T>(X / other.X, Y / other.Y); } + vector2d<T>& operator/=(const vector2d<T>& other) { X/=other.X; Y/=other.Y; return *this; } + vector2d<T> operator/(const T v) const { return vector2d<T>(X / v, Y / v); } + vector2d<T>& operator/=(const T v) { X/=v; Y/=v; return *this; } + + //! sort in order X, Y. Equality with rounding tolerance. + bool operator<=(const vector2d<T>&other) const + { + return (X<other.X || core::equals(X, other.X)) || + (core::equals(X, other.X) && (Y<other.Y || core::equals(Y, other.Y))); + } + + //! sort in order X, Y. Equality with rounding tolerance. + bool operator>=(const vector2d<T>&other) const + { + return (X>other.X || core::equals(X, other.X)) || + (core::equals(X, other.X) && (Y>other.Y || core::equals(Y, other.Y))); + } + + //! sort in order X, Y. Difference must be above rounding tolerance. + bool operator<(const vector2d<T>&other) const + { + return (X<other.X && !core::equals(X, other.X)) || + (core::equals(X, other.X) && Y<other.Y && !core::equals(Y, other.Y)); + } + + //! sort in order X, Y. Difference must be above rounding tolerance. + bool operator>(const vector2d<T>&other) const + { + return (X>other.X && !core::equals(X, other.X)) || + (core::equals(X, other.X) && Y>other.Y && !core::equals(Y, other.Y)); + } + + bool operator==(const vector2d<T>& other) const { return equals(other); } + bool operator!=(const vector2d<T>& other) const { return !equals(other); } + + // functions + + //! Checks if this vector equals the other one. + /** Takes floating point rounding errors into account. + \param other Vector to compare with. + \return True if the two vector are (almost) equal, else false. */ + bool equals(const vector2d<T>& other) const + { + return core::equals(X, other.X) && core::equals(Y, other.Y); + } + + vector2d<T>& set(T nx, T ny) {X=nx; Y=ny; return *this; } + vector2d<T>& set(const vector2d<T>& p) { X=p.X; Y=p.Y; return *this; } + + //! Gets the length of the vector. + /** \return The length of the vector. */ + T getLength() const { return core::squareroot( X*X + Y*Y ); } + + //! Get the squared length of this vector + /** This is useful because it is much faster than getLength(). + \return The squared length of the vector. */ + T getLengthSQ() const { return X*X + Y*Y; } + + //! Get the dot product of this vector with another. + /** \param other Other vector to take dot product with. + \return The dot product of the two vectors. */ + T dotProduct(const vector2d<T>& other) const + { + return X*other.X + Y*other.Y; + } + + //! Gets distance from another point. + /** Here, the vector is interpreted as a point in 2-dimensional space. + \param other Other vector to measure from. + \return Distance from other point. */ + T getDistanceFrom(const vector2d<T>& other) const + { + return vector2d<T>(X - other.X, Y - other.Y).getLength(); + } + + //! Returns squared distance from another point. + /** Here, the vector is interpreted as a point in 2-dimensional space. + \param other Other vector to measure from. + \return Squared distance from other point. */ + T getDistanceFromSQ(const vector2d<T>& other) const + { + return vector2d<T>(X - other.X, Y - other.Y).getLengthSQ(); + } + + //! rotates the point anticlockwise around a center by an amount of degrees. + /** \param degrees Amount of degrees to rotate by, anticlockwise. + \param center Rotation center. + \return This vector after transformation. */ + vector2d<T>& rotateBy(f64 degrees, const vector2d<T>& center=vector2d<T>()) + { + degrees *= DEGTORAD64; + const f64 cs = cos(degrees); + const f64 sn = sin(degrees); + + X -= center.X; + Y -= center.Y; + + set((T)(X*cs - Y*sn), (T)(X*sn + Y*cs)); + + X += center.X; + Y += center.Y; + return *this; + } + + //! Normalize the vector. + /** The null vector is left untouched. + \return Reference to this vector, after normalization. */ + vector2d<T>& normalize() + { + f32 length = (f32)(X*X + Y*Y); + if ( length == 0 ) + return *this; + length = core::reciprocal_squareroot ( length ); + X = (T)(X * length); + Y = (T)(Y * length); + return *this; + } + + //! Calculates the angle of this vector in degrees in the trigonometric sense. + /** 0 is to the right (3 o'clock), values increase counter-clockwise. + This method has been suggested by Pr3t3nd3r. + \return Returns a value between 0 and 360. */ + f64 getAngleTrig() const + { + if (Y == 0) + return X < 0 ? 180 : 0; + else + if (X == 0) + return Y < 0 ? 270 : 90; + + if ( Y > 0) + if (X > 0) + return atan((irr::f64)Y/(irr::f64)X) * RADTODEG64; + else + return 180.0-atan((irr::f64)Y/-(irr::f64)X) * RADTODEG64; + else + if (X > 0) + return 360.0-atan(-(irr::f64)Y/(irr::f64)X) * RADTODEG64; + else + return 180.0+atan(-(irr::f64)Y/-(irr::f64)X) * RADTODEG64; + } + + //! Calculates the angle of this vector in degrees in the counter trigonometric sense. + /** 0 is to the right (3 o'clock), values increase clockwise. + \return Returns a value between 0 and 360. */ + inline f64 getAngle() const + { + if (Y == 0) // corrected thanks to a suggestion by Jox + return X < 0 ? 180 : 0; + else if (X == 0) + return Y < 0 ? 90 : 270; + + // don't use getLength here to avoid precision loss with s32 vectors + // avoid floating-point trouble as sqrt(y*y) is occasionally larger than y, so clamp + const f64 tmp = core::clamp(Y / sqrt((f64)(X*X + Y*Y)), -1.0, 1.0); + const f64 angle = atan( core::squareroot(1 - tmp*tmp) / tmp) * RADTODEG64; + + if (X>0 && Y>0) + return angle + 270; + else + if (X>0 && Y<0) + return angle + 90; + else + if (X<0 && Y<0) + return 90 - angle; + else + if (X<0 && Y>0) + return 270 - angle; + + return angle; + } + + //! Calculates the angle between this vector and another one in degree. + /** \param b Other vector to test with. + \return Returns a value between 0 and 90. */ + inline f64 getAngleWith(const vector2d<T>& b) const + { + f64 tmp = (f64)(X*b.X + Y*b.Y); + + if (tmp == 0.0) + return 90.0; + + tmp = tmp / core::squareroot((f64)((X*X + Y*Y) * (b.X*b.X + b.Y*b.Y))); + if (tmp < 0.0) + tmp = -tmp; + if ( tmp > 1.0 ) // avoid floating-point trouble + tmp = 1.0; + + return atan(sqrt(1 - tmp*tmp) / tmp) * RADTODEG64; + } + + //! Returns if this vector interpreted as a point is on a line between two other points. + /** It is assumed that the point is on the line. + \param begin Beginning vector to compare between. + \param end Ending vector to compare between. + \return True if this vector is between begin and end, false if not. */ + bool isBetweenPoints(const vector2d<T>& begin, const vector2d<T>& end) const + { + if (begin.X != end.X) + { + return ((begin.X <= X && X <= end.X) || + (begin.X >= X && X >= end.X)); + } + else + { + return ((begin.Y <= Y && Y <= end.Y) || + (begin.Y >= Y && Y >= end.Y)); + } + } + + //! Creates an interpolated vector between this vector and another vector. + /** \param other The other vector to interpolate with. + \param d Interpolation value between 0.0f (all the other vector) and 1.0f (all this vector). + Note that this is the opposite direction of interpolation to getInterpolated_quadratic() + \return An interpolated vector. This vector is not modified. */ + vector2d<T> getInterpolated(const vector2d<T>& other, f64 d) const + { + f64 inv = 1.0f - d; + return vector2d<T>((T)(other.X*inv + X*d), (T)(other.Y*inv + Y*d)); + } + + //! Creates a quadratically interpolated vector between this and two other vectors. + /** \param v2 Second vector to interpolate with. + \param v3 Third vector to interpolate with (maximum at 1.0f) + \param d Interpolation value between 0.0f (all this vector) and 1.0f (all the 3rd vector). + Note that this is the opposite direction of interpolation to getInterpolated() and interpolate() + \return An interpolated vector. This vector is not modified. */ + vector2d<T> getInterpolated_quadratic(const vector2d<T>& v2, const vector2d<T>& v3, f64 d) const + { + // this*(1-d)*(1-d) + 2 * v2 * (1-d) + v3 * d * d; + const f64 inv = 1.0f - d; + const f64 mul0 = inv * inv; + const f64 mul1 = 2.0f * d * inv; + const f64 mul2 = d * d; + + return vector2d<T> ( (T)(X * mul0 + v2.X * mul1 + v3.X * mul2), + (T)(Y * mul0 + v2.Y * mul1 + v3.Y * mul2)); + } + + //! Sets this vector to the linearly interpolated vector between a and b. + /** \param a first vector to interpolate with, maximum at 1.0f + \param b second vector to interpolate with, maximum at 0.0f + \param d Interpolation value between 0.0f (all vector b) and 1.0f (all vector a) + Note that this is the opposite direction of interpolation to getInterpolated_quadratic() + */ + vector2d<T>& interpolate(const vector2d<T>& a, const vector2d<T>& b, f64 d) + { + X = (T)((f64)b.X + ( ( a.X - b.X ) * d )); + Y = (T)((f64)b.Y + ( ( a.Y - b.Y ) * d )); + return *this; + } + + //! X coordinate of vector. + T X; + + //! Y coordinate of vector. + T Y; +}; + + //! Typedef for f32 2d vector. + typedef vector2d<f32> vector2df; + + //! Typedef for integer 2d vector. + typedef vector2d<s32> vector2di; + + template<class S, class T> + vector2d<T> operator*(const S scalar, const vector2d<T>& vector) { return vector*scalar; } + + // These methods are declared in dimension2d, but need definitions of vector2d + template<class T> + dimension2d<T>::dimension2d(const vector2d<T>& other) : Width(other.X), Height(other.Y) { } + + template<class T> + bool dimension2d<T>::operator==(const vector2d<T>& other) const { return Width == other.X && Height == other.Y; } + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/include/vector3d.h b/builddir/irrlicht-1.8.1/include/vector3d.h new file mode 100644 index 0000000..d582978 --- /dev/null +++ b/builddir/irrlicht-1.8.1/include/vector3d.h @@ -0,0 +1,458 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_POINT_3D_H_INCLUDED__ +#define __IRR_POINT_3D_H_INCLUDED__ + +#include "irrMath.h" + +namespace irr +{ +namespace core +{ + + //! 3d vector template class with lots of operators and methods. + /** The vector3d class is used in Irrlicht for three main purposes: + 1) As a direction vector (most of the methods assume this). + 2) As a position in 3d space (which is synonymous with a direction vector from the origin to this position). + 3) To hold three Euler rotations, where X is pitch, Y is yaw and Z is roll. + */ + template <class T> + class vector3d + { + public: + //! Default constructor (null vector). + vector3d() : X(0), Y(0), Z(0) {} + //! Constructor with three different values + vector3d(T nx, T ny, T nz) : X(nx), Y(ny), Z(nz) {} + //! Constructor with the same value for all elements + explicit vector3d(T n) : X(n), Y(n), Z(n) {} + //! Copy constructor + vector3d(const vector3d<T>& other) : X(other.X), Y(other.Y), Z(other.Z) {} + + // operators + + vector3d<T> operator-() const { return vector3d<T>(-X, -Y, -Z); } + + vector3d<T>& operator=(const vector3d<T>& other) { X = other.X; Y = other.Y; Z = other.Z; return *this; } + + vector3d<T> operator+(const vector3d<T>& other) const { return vector3d<T>(X + other.X, Y + other.Y, Z + other.Z); } + vector3d<T>& operator+=(const vector3d<T>& other) { X+=other.X; Y+=other.Y; Z+=other.Z; return *this; } + vector3d<T> operator+(const T val) const { return vector3d<T>(X + val, Y + val, Z + val); } + vector3d<T>& operator+=(const T val) { X+=val; Y+=val; Z+=val; return *this; } + + vector3d<T> operator-(const vector3d<T>& other) const { return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z); } + vector3d<T>& operator-=(const vector3d<T>& other) { X-=other.X; Y-=other.Y; Z-=other.Z; return *this; } + vector3d<T> operator-(const T val) const { return vector3d<T>(X - val, Y - val, Z - val); } + vector3d<T>& operator-=(const T val) { X-=val; Y-=val; Z-=val; return *this; } + + vector3d<T> operator*(const vector3d<T>& other) const { return vector3d<T>(X * other.X, Y * other.Y, Z * other.Z); } + vector3d<T>& operator*=(const vector3d<T>& other) { X*=other.X; Y*=other.Y; Z*=other.Z; return *this; } + vector3d<T> operator*(const T v) const { return vector3d<T>(X * v, Y * v, Z * v); } + vector3d<T>& operator*=(const T v) { X*=v; Y*=v; Z*=v; return *this; } + + vector3d<T> operator/(const vector3d<T>& other) const { return vector3d<T>(X / other.X, Y / other.Y, Z / other.Z); } + vector3d<T>& operator/=(const vector3d<T>& other) { X/=other.X; Y/=other.Y; Z/=other.Z; return *this; } + vector3d<T> operator/(const T v) const { T i=(T)1.0/v; return vector3d<T>(X * i, Y * i, Z * i); } + vector3d<T>& operator/=(const T v) { T i=(T)1.0/v; X*=i; Y*=i; Z*=i; return *this; } + + //! sort in order X, Y, Z. Equality with rounding tolerance. + bool operator<=(const vector3d<T>&other) const + { + return (X<other.X || core::equals(X, other.X)) || + (core::equals(X, other.X) && (Y<other.Y || core::equals(Y, other.Y))) || + (core::equals(X, other.X) && core::equals(Y, other.Y) && (Z<other.Z || core::equals(Z, other.Z))); + } + + //! sort in order X, Y, Z. Equality with rounding tolerance. + bool operator>=(const vector3d<T>&other) const + { + return (X>other.X || core::equals(X, other.X)) || + (core::equals(X, other.X) && (Y>other.Y || core::equals(Y, other.Y))) || + (core::equals(X, other.X) && core::equals(Y, other.Y) && (Z>other.Z || core::equals(Z, other.Z))); + } + + //! sort in order X, Y, Z. Difference must be above rounding tolerance. + bool operator<(const vector3d<T>&other) const + { + return (X<other.X && !core::equals(X, other.X)) || + (core::equals(X, other.X) && Y<other.Y && !core::equals(Y, other.Y)) || + (core::equals(X, other.X) && core::equals(Y, other.Y) && Z<other.Z && !core::equals(Z, other.Z)); + } + + //! sort in order X, Y, Z. Difference must be above rounding tolerance. + bool operator>(const vector3d<T>&other) const + { + return (X>other.X && !core::equals(X, other.X)) || + (core::equals(X, other.X) && Y>other.Y && !core::equals(Y, other.Y)) || + (core::equals(X, other.X) && core::equals(Y, other.Y) && Z>other.Z && !core::equals(Z, other.Z)); + } + + //! use weak float compare + bool operator==(const vector3d<T>& other) const + { + return this->equals(other); + } + + bool operator!=(const vector3d<T>& other) const + { + return !this->equals(other); + } + + // functions + + //! returns if this vector equals the other one, taking floating point rounding errors into account + bool equals(const vector3d<T>& other, const T tolerance = (T)ROUNDING_ERROR_f32 ) const + { + return core::equals(X, other.X, tolerance) && + core::equals(Y, other.Y, tolerance) && + core::equals(Z, other.Z, tolerance); + } + + vector3d<T>& set(const T nx, const T ny, const T nz) {X=nx; Y=ny; Z=nz; return *this;} + vector3d<T>& set(const vector3d<T>& p) {X=p.X; Y=p.Y; Z=p.Z;return *this;} + + //! Get length of the vector. + T getLength() const { return core::squareroot( X*X + Y*Y + Z*Z ); } + + //! Get squared length of the vector. + /** This is useful because it is much faster than getLength(). + \return Squared length of the vector. */ + T getLengthSQ() const { return X*X + Y*Y + Z*Z; } + + //! Get the dot product with another vector. + T dotProduct(const vector3d<T>& other) const + { + return X*other.X + Y*other.Y + Z*other.Z; + } + + //! Get distance from another point. + /** Here, the vector is interpreted as point in 3 dimensional space. */ + T getDistanceFrom(const vector3d<T>& other) const + { + return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z).getLength(); + } + + //! Returns squared distance from another point. + /** Here, the vector is interpreted as point in 3 dimensional space. */ + T getDistanceFromSQ(const vector3d<T>& other) const + { + return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z).getLengthSQ(); + } + + //! Calculates the cross product with another vector. + /** \param p Vector to multiply with. + \return Crossproduct of this vector with p. */ + vector3d<T> crossProduct(const vector3d<T>& p) const + { + return vector3d<T>(Y * p.Z - Z * p.Y, Z * p.X - X * p.Z, X * p.Y - Y * p.X); + } + + //! Returns if this vector interpreted as a point is on a line between two other points. + /** It is assumed that the point is on the line. + \param begin Beginning vector to compare between. + \param end Ending vector to compare between. + \return True if this vector is between begin and end, false if not. */ + bool isBetweenPoints(const vector3d<T>& begin, const vector3d<T>& end) const + { + const T f = (end - begin).getLengthSQ(); + return getDistanceFromSQ(begin) <= f && + getDistanceFromSQ(end) <= f; + } + + //! Normalizes the vector. + /** In case of the 0 vector the result is still 0, otherwise + the length of the vector will be 1. + \return Reference to this vector after normalization. */ + vector3d<T>& normalize() + { + f64 length = X*X + Y*Y + Z*Z; + if (length == 0 ) // this check isn't an optimization but prevents getting NAN in the sqrt. + return *this; + length = core::reciprocal_squareroot(length); + + X = (T)(X * length); + Y = (T)(Y * length); + Z = (T)(Z * length); + return *this; + } + + //! Sets the length of the vector to a new value + vector3d<T>& setLength(T newlength) + { + normalize(); + return (*this *= newlength); + } + + //! Inverts the vector. + vector3d<T>& invert() + { + X *= -1; + Y *= -1; + Z *= -1; + return *this; + } + + //! Rotates the vector by a specified number of degrees around the Y axis and the specified center. + /** \param degrees Number of degrees to rotate around the Y axis. + \param center The center of the rotation. */ + void rotateXZBy(f64 degrees, const vector3d<T>& center=vector3d<T>()) + { + degrees *= DEGTORAD64; + f64 cs = cos(degrees); + f64 sn = sin(degrees); + X -= center.X; + Z -= center.Z; + set((T)(X*cs - Z*sn), Y, (T)(X*sn + Z*cs)); + X += center.X; + Z += center.Z; + } + + //! Rotates the vector by a specified number of degrees around the Z axis and the specified center. + /** \param degrees: Number of degrees to rotate around the Z axis. + \param center: The center of the rotation. */ + void rotateXYBy(f64 degrees, const vector3d<T>& center=vector3d<T>()) + { + degrees *= DEGTORAD64; + f64 cs = cos(degrees); + f64 sn = sin(degrees); + X -= center.X; + Y -= center.Y; + set((T)(X*cs - Y*sn), (T)(X*sn + Y*cs), Z); + X += center.X; + Y += center.Y; + } + + //! Rotates the vector by a specified number of degrees around the X axis and the specified center. + /** \param degrees: Number of degrees to rotate around the X axis. + \param center: The center of the rotation. */ + void rotateYZBy(f64 degrees, const vector3d<T>& center=vector3d<T>()) + { + degrees *= DEGTORAD64; + f64 cs = cos(degrees); + f64 sn = sin(degrees); + Z -= center.Z; + Y -= center.Y; + set(X, (T)(Y*cs - Z*sn), (T)(Y*sn + Z*cs)); + Z += center.Z; + Y += center.Y; + } + + //! Creates an interpolated vector between this vector and another vector. + /** \param other The other vector to interpolate with. + \param d Interpolation value between 0.0f (all the other vector) and 1.0f (all this vector). + Note that this is the opposite direction of interpolation to getInterpolated_quadratic() + \return An interpolated vector. This vector is not modified. */ + vector3d<T> getInterpolated(const vector3d<T>& other, f64 d) const + { + const f64 inv = 1.0 - d; + return vector3d<T>((T)(other.X*inv + X*d), (T)(other.Y*inv + Y*d), (T)(other.Z*inv + Z*d)); + } + + //! Creates a quadratically interpolated vector between this and two other vectors. + /** \param v2 Second vector to interpolate with. + \param v3 Third vector to interpolate with (maximum at 1.0f) + \param d Interpolation value between 0.0f (all this vector) and 1.0f (all the 3rd vector). + Note that this is the opposite direction of interpolation to getInterpolated() and interpolate() + \return An interpolated vector. This vector is not modified. */ + vector3d<T> getInterpolated_quadratic(const vector3d<T>& v2, const vector3d<T>& v3, f64 d) const + { + // this*(1-d)*(1-d) + 2 * v2 * (1-d) + v3 * d * d; + const f64 inv = (T) 1.0 - d; + const f64 mul0 = inv * inv; + const f64 mul1 = (T) 2.0 * d * inv; + const f64 mul2 = d * d; + + return vector3d<T> ((T)(X * mul0 + v2.X * mul1 + v3.X * mul2), + (T)(Y * mul0 + v2.Y * mul1 + v3.Y * mul2), + (T)(Z * mul0 + v2.Z * mul1 + v3.Z * mul2)); + } + + //! Sets this vector to the linearly interpolated vector between a and b. + /** \param a first vector to interpolate with, maximum at 1.0f + \param b second vector to interpolate with, maximum at 0.0f + \param d Interpolation value between 0.0f (all vector b) and 1.0f (all vector a) + Note that this is the opposite direction of interpolation to getInterpolated_quadratic() + */ + vector3d<T>& interpolate(const vector3d<T>& a, const vector3d<T>& b, f64 d) + { + X = (T)((f64)b.X + ( ( a.X - b.X ) * d )); + Y = (T)((f64)b.Y + ( ( a.Y - b.Y ) * d )); + Z = (T)((f64)b.Z + ( ( a.Z - b.Z ) * d )); + return *this; + } + + + //! Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector. + /** Thanks to Arras on the Irrlicht forums for this method. This utility method is very useful for + orienting scene nodes towards specific targets. For example, if this vector represents the difference + between two scene nodes, then applying the result of getHorizontalAngle() to one scene node will point + it at the other one. + Example code: + // Where target and seeker are of type ISceneNode* + const vector3df toTarget(target->getAbsolutePosition() - seeker->getAbsolutePosition()); + const vector3df requiredRotation = toTarget.getHorizontalAngle(); + seeker->setRotation(requiredRotation); + + \return A rotation vector containing the X (pitch) and Y (raw) rotations (in degrees) that when applied to a + +Z (e.g. 0, 0, 1) direction vector would make it point in the same direction as this vector. The Z (roll) rotation + is always 0, since two Euler rotations are sufficient to point in any given direction. */ + vector3d<T> getHorizontalAngle() const + { + vector3d<T> angle; + + const f64 tmp = (atan2((f64)X, (f64)Z) * RADTODEG64); + angle.Y = (T)tmp; + + if (angle.Y < 0) + angle.Y += 360; + if (angle.Y >= 360) + angle.Y -= 360; + + const f64 z1 = core::squareroot(X*X + Z*Z); + + angle.X = (T)(atan2((f64)z1, (f64)Y) * RADTODEG64 - 90.0); + + if (angle.X < 0) + angle.X += 360; + if (angle.X >= 360) + angle.X -= 360; + + return angle; + } + + //! Get the spherical coordinate angles + /** This returns Euler degrees for the point represented by + this vector. The calculation assumes the pole at (0,1,0) and + returns the angles in X and Y. + */ + vector3d<T> getSphericalCoordinateAngles() const + { + vector3d<T> angle; + const f64 length = X*X + Y*Y + Z*Z; + + if (length) + { + if (X!=0) + { + angle.Y = (T)(atan2((f64)Z,(f64)X) * RADTODEG64); + } + else if (Z<0) + angle.Y=180; + + angle.X = (T)(acos(Y * core::reciprocal_squareroot(length)) * RADTODEG64); + } + return angle; + } + + //! Builds a direction vector from (this) rotation vector. + /** This vector is assumed to be a rotation vector composed of 3 Euler angle rotations, in degrees. + The implementation performs the same calculations as using a matrix to do the rotation. + + \param[in] forwards The direction representing "forwards" which will be rotated by this vector. + If you do not provide a direction, then the +Z axis (0, 0, 1) will be assumed to be forwards. + \return A direction vector calculated by rotating the forwards direction by the 3 Euler angles + (in degrees) represented by this vector. */ + vector3d<T> rotationToDirection(const vector3d<T> & forwards = vector3d<T>(0, 0, 1)) const + { + const f64 cr = cos( core::DEGTORAD64 * X ); + const f64 sr = sin( core::DEGTORAD64 * X ); + const f64 cp = cos( core::DEGTORAD64 * Y ); + const f64 sp = sin( core::DEGTORAD64 * Y ); + const f64 cy = cos( core::DEGTORAD64 * Z ); + const f64 sy = sin( core::DEGTORAD64 * Z ); + + const f64 srsp = sr*sp; + const f64 crsp = cr*sp; + + const f64 pseudoMatrix[] = { + ( cp*cy ), ( cp*sy ), ( -sp ), + ( srsp*cy-cr*sy ), ( srsp*sy+cr*cy ), ( sr*cp ), + ( crsp*cy+sr*sy ), ( crsp*sy-sr*cy ), ( cr*cp )}; + + return vector3d<T>( + (T)(forwards.X * pseudoMatrix[0] + + forwards.Y * pseudoMatrix[3] + + forwards.Z * pseudoMatrix[6]), + (T)(forwards.X * pseudoMatrix[1] + + forwards.Y * pseudoMatrix[4] + + forwards.Z * pseudoMatrix[7]), + (T)(forwards.X * pseudoMatrix[2] + + forwards.Y * pseudoMatrix[5] + + forwards.Z * pseudoMatrix[8])); + } + + //! Fills an array of 4 values with the vector data (usually floats). + /** Useful for setting in shader constants for example. The fourth value + will always be 0. */ + void getAs4Values(T* array) const + { + array[0] = X; + array[1] = Y; + array[2] = Z; + array[3] = 0; + } + + //! Fills an array of 3 values with the vector data (usually floats). + /** Useful for setting in shader constants for example.*/ + void getAs3Values(T* array) const + { + array[0] = X; + array[1] = Y; + array[2] = Z; + } + + + //! X coordinate of the vector + T X; + + //! Y coordinate of the vector + T Y; + + //! Z coordinate of the vector + T Z; + }; + + //! partial specialization for integer vectors + // Implementor note: inline keyword needed due to template specialization for s32. Otherwise put specialization into a .cpp + template <> + inline vector3d<s32> vector3d<s32>::operator /(s32 val) const {return core::vector3d<s32>(X/val,Y/val,Z/val);} + template <> + inline vector3d<s32>& vector3d<s32>::operator /=(s32 val) {X/=val;Y/=val;Z/=val; return *this;} + + template <> + inline vector3d<s32> vector3d<s32>::getSphericalCoordinateAngles() const + { + vector3d<s32> angle; + const f64 length = X*X + Y*Y + Z*Z; + + if (length) + { + if (X!=0) + { + angle.Y = round32((f32)(atan2((f64)Z,(f64)X) * RADTODEG64)); + } + else if (Z<0) + angle.Y=180; + + angle.X = round32((f32)(acos(Y * core::reciprocal_squareroot(length)) * RADTODEG64)); + } + return angle; + } + + //! Typedef for a f32 3d vector. + typedef vector3d<f32> vector3df; + + //! Typedef for an integer 3d vector. + typedef vector3d<s32> vector3di; + + //! Function multiplying a scalar and a vector component-wise. + template<class S, class T> + vector3d<T> operator*(const S scalar, const vector3d<T>& vector) { return vector*scalar; } + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/builddir/irrlicht-1.8.1/irrlicht-license.txt b/builddir/irrlicht-1.8.1/irrlicht-license.txt new file mode 100644 index 0000000..1f2be55 --- /dev/null +++ b/builddir/irrlicht-1.8.1/irrlicht-license.txt @@ -0,0 +1,26 @@ +Copyright (C) 2002-2012 Nikolaus Gebhardt + + 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. + + Please note that the Irrlicht Engine is based in part on the work of the + Independent JPEG Group, the zlib, libPng and aesGladman. This means that if you use + the Irrlicht Engine in your product, you must acknowledge somewhere in your + documentation that you've used the IJPG code. It would also be nice to mention + that you use the Irrlicht Engine, the zlib, libPng and aesGladman. See the + corresponding license files for further informations. It is also possible to disable + usage of those additional libraries by defines in the IrrCompileConfig.h header and + recompiling the engine. diff --git a/builddir/libogg-1.3.1/COPYING b/builddir/libogg-1.3.1/COPYING new file mode 100644 index 0000000..6111c6c --- /dev/null +++ b/builddir/libogg-1.3.1/COPYING @@ -0,0 +1,28 @@ +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/builddir/libogg-1.3.1/bin/libogg.dll b/builddir/libogg-1.3.1/bin/libogg.dll new file mode 100644 index 0000000..3b77e2c Binary files /dev/null and b/builddir/libogg-1.3.1/bin/libogg.dll differ diff --git a/builddir/libogg-1.3.1/bin/libogg.exp b/builddir/libogg-1.3.1/bin/libogg.exp new file mode 100644 index 0000000..f9c1c51 Binary files /dev/null and b/builddir/libogg-1.3.1/bin/libogg.exp differ diff --git a/builddir/libogg-1.3.1/bin/libogg.lib b/builddir/libogg-1.3.1/bin/libogg.lib new file mode 100644 index 0000000..ad9dca0 Binary files /dev/null and b/builddir/libogg-1.3.1/bin/libogg.lib differ diff --git a/builddir/libogg-1.3.1/bin/libogg_static.lib b/builddir/libogg-1.3.1/bin/libogg_static.lib new file mode 100644 index 0000000..a6a2677 Binary files /dev/null and b/builddir/libogg-1.3.1/bin/libogg_static.lib differ diff --git a/builddir/libogg-1.3.1/include/ogg/ogg.h b/builddir/libogg-1.3.1/include/ogg/ogg.h new file mode 100644 index 0000000..cea4ebe --- /dev/null +++ b/builddir/libogg-1.3.1/include/ogg/ogg.h @@ -0,0 +1,210 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE 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 SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel libogg include + last mod: $Id: ogg.h 18044 2011-08-01 17:55:20Z gmaxwell $ + + ********************************************************************/ +#ifndef _OGG_H +#define _OGG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stddef.h> +#include <ogg/os_types.h> + +typedef struct { + void *iov_base; + size_t iov_len; +} ogg_iovec_t; + +typedef struct { + long endbyte; + int endbit; + + unsigned char *buffer; + unsigned char *ptr; + long storage; +} oggpack_buffer; + +/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ + +typedef struct { + unsigned char *header; + long header_len; + unsigned char *body; + long body_len; +} ogg_page; + +/* ogg_stream_state contains the current encode/decode state of a logical + Ogg bitstream **********************************************************/ + +typedef struct { + unsigned char *body_data; /* bytes from packet bodies */ + long body_storage; /* storage elements allocated */ + long body_fill; /* elements stored; fill mark */ + long body_returned; /* elements of fill returned */ + + + int *lacing_vals; /* The values that will go to the segment table */ + ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact + this way, but it is simple coupled to the + lacing fifo */ + long lacing_storage; + long lacing_fill; + long lacing_packet; + long lacing_returned; + + unsigned char header[282]; /* working space for header encode */ + int header_fill; + + int e_o_s; /* set when we have buffered the last packet in the + logical bitstream */ + int b_o_s; /* set after we've written the initial page + of a logical bitstream */ + long serialno; + long pageno; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a separate abstraction + layer) also knows about the gap */ + ogg_int64_t granulepos; + +} ogg_stream_state; + +/* ogg_packet is used to encapsulate the data and metadata belonging + to a single raw Ogg/Vorbis packet *************************************/ + +typedef struct { + unsigned char *packet; + long bytes; + long b_o_s; + long e_o_s; + + ogg_int64_t granulepos; + + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a separate abstraction + layer) also knows about the gap */ +} ogg_packet; + +typedef struct { + unsigned char *data; + int storage; + int fill; + int returned; + + int unsynced; + int headerbytes; + int bodybytes; +} ogg_sync_state; + +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ + +extern void oggpack_writeinit(oggpack_buffer *b); +extern int oggpack_writecheck(oggpack_buffer *b); +extern void oggpack_writetrunc(oggpack_buffer *b,long bits); +extern void oggpack_writealign(oggpack_buffer *b); +extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpack_reset(oggpack_buffer *b); +extern void oggpack_writeclear(oggpack_buffer *b); +extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpack_look(oggpack_buffer *b,int bits); +extern long oggpack_look1(oggpack_buffer *b); +extern void oggpack_adv(oggpack_buffer *b,int bits); +extern void oggpack_adv1(oggpack_buffer *b); +extern long oggpack_read(oggpack_buffer *b,int bits); +extern long oggpack_read1(oggpack_buffer *b); +extern long oggpack_bytes(oggpack_buffer *b); +extern long oggpack_bits(oggpack_buffer *b); +extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); + +extern void oggpackB_writeinit(oggpack_buffer *b); +extern int oggpackB_writecheck(oggpack_buffer *b); +extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); +extern void oggpackB_writealign(oggpack_buffer *b); +extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpackB_reset(oggpack_buffer *b); +extern void oggpackB_writeclear(oggpack_buffer *b); +extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpackB_look(oggpack_buffer *b,int bits); +extern long oggpackB_look1(oggpack_buffer *b); +extern void oggpackB_adv(oggpack_buffer *b,int bits); +extern void oggpackB_adv1(oggpack_buffer *b); +extern long oggpackB_read(oggpack_buffer *b,int bits); +extern long oggpackB_read1(oggpack_buffer *b); +extern long oggpackB_bytes(oggpack_buffer *b); +extern long oggpackB_bits(oggpack_buffer *b); +extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); + +/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ + +extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, + int count, long e_o_s, ogg_int64_t granulepos); +extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill); +extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill); + +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ + +extern int ogg_sync_init(ogg_sync_state *oy); +extern int ogg_sync_clear(ogg_sync_state *oy); +extern int ogg_sync_reset(ogg_sync_state *oy); +extern int ogg_sync_destroy(ogg_sync_state *oy); +extern int ogg_sync_check(ogg_sync_state *oy); + +extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); +extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); + +/* Ogg BITSTREAM PRIMITIVES: general ***************************/ + +extern int ogg_stream_init(ogg_stream_state *os,int serialno); +extern int ogg_stream_clear(ogg_stream_state *os); +extern int ogg_stream_reset(ogg_stream_state *os); +extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); +extern int ogg_stream_destroy(ogg_stream_state *os); +extern int ogg_stream_check(ogg_stream_state *os); +extern int ogg_stream_eos(ogg_stream_state *os); + +extern void ogg_page_checksum_set(ogg_page *og); + +extern int ogg_page_version(const ogg_page *og); +extern int ogg_page_continued(const ogg_page *og); +extern int ogg_page_bos(const ogg_page *og); +extern int ogg_page_eos(const ogg_page *og); +extern ogg_int64_t ogg_page_granulepos(const ogg_page *og); +extern int ogg_page_serialno(const ogg_page *og); +extern long ogg_page_pageno(const ogg_page *og); +extern int ogg_page_packets(const ogg_page *og); + +extern void ogg_packet_clear(ogg_packet *op); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OGG_H */ diff --git a/builddir/libogg-1.3.1/include/ogg/os_types.h b/builddir/libogg-1.3.1/include/ogg/os_types.h new file mode 100644 index 0000000..d6691b7 --- /dev/null +++ b/builddir/libogg-1.3.1/include/ogg/os_types.h @@ -0,0 +1,147 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE 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 SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os_types.h 17712 2010-12-03 17:10:02Z xiphmont $ + + ********************************************************************/ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +/* make it easy on the folks that want to compile the libs with a + different malloc than stdlib */ +#define _ogg_malloc malloc +#define _ogg_calloc calloc +#define _ogg_realloc realloc +#define _ogg_free free + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include <stdint.h> + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; +# elif defined(__MINGW32__) +# include <sys/types.h> + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; +# elif defined(__MWERKS__) + typedef long long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; +# else + /* MSVC/Borland */ + typedef __int64 ogg_int64_t; + typedef __int32 ogg_int32_t; + typedef unsigned __int32 ogg_uint32_t; + typedef __int16 ogg_int16_t; + typedef unsigned __int16 ogg_uint16_t; +# endif + +#elif defined(__MACOS__) + +# include <sys/types.h> + typedef SInt16 ogg_int16_t; + typedef UInt16 ogg_uint16_t; + typedef SInt32 ogg_int32_t; + typedef UInt32 ogg_uint32_t; + typedef SInt64 ogg_int64_t; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include <inttypes.h> + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined(__HAIKU__) + + /* Haiku */ +# include <sys/types.h> + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(__BEOS__) + + /* Be */ +# include <inttypes.h> + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short ogg_int16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned ogg_uint32_t; + typedef short ogg_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + +#elif defined(__TMS320C6X__) + + /* TI C64x compiler */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + +#else + +# include <ogg/config_types.h> + +#endif + +#endif /* _OS_TYPES_H */ diff --git a/builddir/libvorbis-1.3.3/COPYING b/builddir/libvorbis-1.3.3/COPYING new file mode 100644 index 0000000..28de72a --- /dev/null +++ b/builddir/libvorbis-1.3.3/COPYING @@ -0,0 +1,28 @@ +Copyright (c) 2002-2008 Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/builddir/libvorbis-1.3.3/bin/libvorbis.dll b/builddir/libvorbis-1.3.3/bin/libvorbis.dll new file mode 100644 index 0000000..89b237e Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/libvorbis.dll differ diff --git a/builddir/libvorbis-1.3.3/bin/libvorbis.exp b/builddir/libvorbis-1.3.3/bin/libvorbis.exp new file mode 100644 index 0000000..d1ddf36 Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/libvorbis.exp differ diff --git a/builddir/libvorbis-1.3.3/bin/libvorbis.lib b/builddir/libvorbis-1.3.3/bin/libvorbis.lib new file mode 100644 index 0000000..9bc8691 Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/libvorbis.lib differ diff --git a/builddir/libvorbis-1.3.3/bin/libvorbis_static.lib b/builddir/libvorbis-1.3.3/bin/libvorbis_static.lib new file mode 100644 index 0000000..3217050 Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/libvorbis_static.lib differ diff --git a/builddir/libvorbis-1.3.3/bin/libvorbisfile.dll b/builddir/libvorbis-1.3.3/bin/libvorbisfile.dll new file mode 100644 index 0000000..bf1d7e9 Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/libvorbisfile.dll differ diff --git a/builddir/libvorbis-1.3.3/bin/libvorbisfile.exp b/builddir/libvorbis-1.3.3/bin/libvorbisfile.exp new file mode 100644 index 0000000..a52b13f Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/libvorbisfile.exp differ diff --git a/builddir/libvorbis-1.3.3/bin/libvorbisfile.lib b/builddir/libvorbis-1.3.3/bin/libvorbisfile.lib new file mode 100644 index 0000000..7fa68e5 Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/libvorbisfile.lib differ diff --git a/builddir/libvorbis-1.3.3/bin/libvorbisfile_static.lib b/builddir/libvorbis-1.3.3/bin/libvorbisfile_static.lib new file mode 100644 index 0000000..d014ec1 Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/libvorbisfile_static.lib differ diff --git a/builddir/libvorbis-1.3.3/bin/vorbisdec.exe b/builddir/libvorbis-1.3.3/bin/vorbisdec.exe new file mode 100644 index 0000000..d2a3b5c Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/vorbisdec.exe differ diff --git a/builddir/libvorbis-1.3.3/bin/vorbisdec_static.exe b/builddir/libvorbis-1.3.3/bin/vorbisdec_static.exe new file mode 100644 index 0000000..b1243b8 Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/vorbisdec_static.exe differ diff --git a/builddir/libvorbis-1.3.3/bin/vorbisenc.exe b/builddir/libvorbis-1.3.3/bin/vorbisenc.exe new file mode 100644 index 0000000..06f97b8 Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/vorbisenc.exe differ diff --git a/builddir/libvorbis-1.3.3/bin/vorbisenc_static.exe b/builddir/libvorbis-1.3.3/bin/vorbisenc_static.exe new file mode 100644 index 0000000..cc2918d Binary files /dev/null and b/builddir/libvorbis-1.3.3/bin/vorbisenc_static.exe differ diff --git a/builddir/libvorbis-1.3.3/include/ogg/ogg.h b/builddir/libvorbis-1.3.3/include/ogg/ogg.h new file mode 100644 index 0000000..cea4ebe --- /dev/null +++ b/builddir/libvorbis-1.3.3/include/ogg/ogg.h @@ -0,0 +1,210 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE 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 SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel libogg include + last mod: $Id: ogg.h 18044 2011-08-01 17:55:20Z gmaxwell $ + + ********************************************************************/ +#ifndef _OGG_H +#define _OGG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stddef.h> +#include <ogg/os_types.h> + +typedef struct { + void *iov_base; + size_t iov_len; +} ogg_iovec_t; + +typedef struct { + long endbyte; + int endbit; + + unsigned char *buffer; + unsigned char *ptr; + long storage; +} oggpack_buffer; + +/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ + +typedef struct { + unsigned char *header; + long header_len; + unsigned char *body; + long body_len; +} ogg_page; + +/* ogg_stream_state contains the current encode/decode state of a logical + Ogg bitstream **********************************************************/ + +typedef struct { + unsigned char *body_data; /* bytes from packet bodies */ + long body_storage; /* storage elements allocated */ + long body_fill; /* elements stored; fill mark */ + long body_returned; /* elements of fill returned */ + + + int *lacing_vals; /* The values that will go to the segment table */ + ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact + this way, but it is simple coupled to the + lacing fifo */ + long lacing_storage; + long lacing_fill; + long lacing_packet; + long lacing_returned; + + unsigned char header[282]; /* working space for header encode */ + int header_fill; + + int e_o_s; /* set when we have buffered the last packet in the + logical bitstream */ + int b_o_s; /* set after we've written the initial page + of a logical bitstream */ + long serialno; + long pageno; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a separate abstraction + layer) also knows about the gap */ + ogg_int64_t granulepos; + +} ogg_stream_state; + +/* ogg_packet is used to encapsulate the data and metadata belonging + to a single raw Ogg/Vorbis packet *************************************/ + +typedef struct { + unsigned char *packet; + long bytes; + long b_o_s; + long e_o_s; + + ogg_int64_t granulepos; + + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a separate abstraction + layer) also knows about the gap */ +} ogg_packet; + +typedef struct { + unsigned char *data; + int storage; + int fill; + int returned; + + int unsynced; + int headerbytes; + int bodybytes; +} ogg_sync_state; + +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ + +extern void oggpack_writeinit(oggpack_buffer *b); +extern int oggpack_writecheck(oggpack_buffer *b); +extern void oggpack_writetrunc(oggpack_buffer *b,long bits); +extern void oggpack_writealign(oggpack_buffer *b); +extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpack_reset(oggpack_buffer *b); +extern void oggpack_writeclear(oggpack_buffer *b); +extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpack_look(oggpack_buffer *b,int bits); +extern long oggpack_look1(oggpack_buffer *b); +extern void oggpack_adv(oggpack_buffer *b,int bits); +extern void oggpack_adv1(oggpack_buffer *b); +extern long oggpack_read(oggpack_buffer *b,int bits); +extern long oggpack_read1(oggpack_buffer *b); +extern long oggpack_bytes(oggpack_buffer *b); +extern long oggpack_bits(oggpack_buffer *b); +extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); + +extern void oggpackB_writeinit(oggpack_buffer *b); +extern int oggpackB_writecheck(oggpack_buffer *b); +extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); +extern void oggpackB_writealign(oggpack_buffer *b); +extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpackB_reset(oggpack_buffer *b); +extern void oggpackB_writeclear(oggpack_buffer *b); +extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpackB_look(oggpack_buffer *b,int bits); +extern long oggpackB_look1(oggpack_buffer *b); +extern void oggpackB_adv(oggpack_buffer *b,int bits); +extern void oggpackB_adv1(oggpack_buffer *b); +extern long oggpackB_read(oggpack_buffer *b,int bits); +extern long oggpackB_read1(oggpack_buffer *b); +extern long oggpackB_bytes(oggpack_buffer *b); +extern long oggpackB_bits(oggpack_buffer *b); +extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); + +/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ + +extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, + int count, long e_o_s, ogg_int64_t granulepos); +extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill); +extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill); + +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ + +extern int ogg_sync_init(ogg_sync_state *oy); +extern int ogg_sync_clear(ogg_sync_state *oy); +extern int ogg_sync_reset(ogg_sync_state *oy); +extern int ogg_sync_destroy(ogg_sync_state *oy); +extern int ogg_sync_check(ogg_sync_state *oy); + +extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); +extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); + +/* Ogg BITSTREAM PRIMITIVES: general ***************************/ + +extern int ogg_stream_init(ogg_stream_state *os,int serialno); +extern int ogg_stream_clear(ogg_stream_state *os); +extern int ogg_stream_reset(ogg_stream_state *os); +extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); +extern int ogg_stream_destroy(ogg_stream_state *os); +extern int ogg_stream_check(ogg_stream_state *os); +extern int ogg_stream_eos(ogg_stream_state *os); + +extern void ogg_page_checksum_set(ogg_page *og); + +extern int ogg_page_version(const ogg_page *og); +extern int ogg_page_continued(const ogg_page *og); +extern int ogg_page_bos(const ogg_page *og); +extern int ogg_page_eos(const ogg_page *og); +extern ogg_int64_t ogg_page_granulepos(const ogg_page *og); +extern int ogg_page_serialno(const ogg_page *og); +extern long ogg_page_pageno(const ogg_page *og); +extern int ogg_page_packets(const ogg_page *og); + +extern void ogg_packet_clear(ogg_packet *op); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OGG_H */ diff --git a/builddir/libvorbis-1.3.3/include/ogg/os_types.h b/builddir/libvorbis-1.3.3/include/ogg/os_types.h new file mode 100644 index 0000000..d6691b7 --- /dev/null +++ b/builddir/libvorbis-1.3.3/include/ogg/os_types.h @@ -0,0 +1,147 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE 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 SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os_types.h 17712 2010-12-03 17:10:02Z xiphmont $ + + ********************************************************************/ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +/* make it easy on the folks that want to compile the libs with a + different malloc than stdlib */ +#define _ogg_malloc malloc +#define _ogg_calloc calloc +#define _ogg_realloc realloc +#define _ogg_free free + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include <stdint.h> + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; +# elif defined(__MINGW32__) +# include <sys/types.h> + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; +# elif defined(__MWERKS__) + typedef long long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; +# else + /* MSVC/Borland */ + typedef __int64 ogg_int64_t; + typedef __int32 ogg_int32_t; + typedef unsigned __int32 ogg_uint32_t; + typedef __int16 ogg_int16_t; + typedef unsigned __int16 ogg_uint16_t; +# endif + +#elif defined(__MACOS__) + +# include <sys/types.h> + typedef SInt16 ogg_int16_t; + typedef UInt16 ogg_uint16_t; + typedef SInt32 ogg_int32_t; + typedef UInt32 ogg_uint32_t; + typedef SInt64 ogg_int64_t; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include <inttypes.h> + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined(__HAIKU__) + + /* Haiku */ +# include <sys/types.h> + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(__BEOS__) + + /* Be */ +# include <inttypes.h> + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short ogg_int16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned ogg_uint32_t; + typedef short ogg_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + +#elif defined(__TMS320C6X__) + + /* TI C64x compiler */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + +#else + +# include <ogg/config_types.h> + +#endif + +#endif /* _OS_TYPES_H */ diff --git a/builddir/libvorbis-1.3.3/include/vorbis/codec.h b/builddir/libvorbis-1.3.3/include/vorbis/codec.h new file mode 100644 index 0000000..999aa33 --- /dev/null +++ b/builddir/libvorbis-1.3.3/include/vorbis/codec.h @@ -0,0 +1,243 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE 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 SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + + ******************************************************************** + + function: libvorbis codec headers + last mod: $Id: codec.h 17021 2010-03-24 09:29:41Z xiphmont $ + + ********************************************************************/ + +#ifndef _vorbis_codec_h_ +#define _vorbis_codec_h_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include <ogg/ogg.h> + +typedef struct vorbis_info{ + int version; + int channels; + long rate; + + /* The below bitrate declarations are *hints*. + Combinations of the three values carry the following implications: + + all three set to the same value: + implies a fixed rate bitstream + only nominal set: + implies a VBR stream that averages the nominal bitrate. No hard + upper/lower limit + upper and or lower set: + implies a VBR bitstream that obeys the bitrate limits. nominal + may also be set to give a nominal rate. + none set: + the coder does not care to speculate. + */ + + long bitrate_upper; + long bitrate_nominal; + long bitrate_lower; + long bitrate_window; + + void *codec_setup; +} vorbis_info; + +/* vorbis_dsp_state buffers the current vorbis audio + analysis/synthesis state. The DSP state belongs to a specific + logical bitstream ****************************************************/ +typedef struct vorbis_dsp_state{ + int analysisp; + vorbis_info *vi; + + float **pcm; + float **pcmret; + int pcm_storage; + int pcm_current; + int pcm_returned; + + int preextrapolate; + int eofflag; + + long lW; + long W; + long nW; + long centerW; + + ogg_int64_t granulepos; + ogg_int64_t sequence; + + ogg_int64_t glue_bits; + ogg_int64_t time_bits; + ogg_int64_t floor_bits; + ogg_int64_t res_bits; + + void *backend_state; +} vorbis_dsp_state; + +typedef struct vorbis_block{ + /* necessary stream state for linking to the framing abstraction */ + float **pcm; /* this is a pointer into local storage */ + oggpack_buffer opb; + + long lW; + long W; + long nW; + int pcmend; + int mode; + + int eofflag; + ogg_int64_t granulepos; + ogg_int64_t sequence; + vorbis_dsp_state *vd; /* For read-only access of configuration */ + + /* local storage to avoid remallocing; it's up to the mapping to + structure it */ + void *localstore; + long localtop; + long localalloc; + long totaluse; + struct alloc_chain *reap; + + /* bitmetrics for the frame */ + long glue_bits; + long time_bits; + long floor_bits; + long res_bits; + + void *internal; + +} vorbis_block; + +/* vorbis_block is a single block of data to be processed as part of +the analysis/synthesis stream; it belongs to a specific logical +bitstream, but is independent from other vorbis_blocks belonging to +that logical bitstream. *************************************************/ + +struct alloc_chain{ + void *ptr; + struct alloc_chain *next; +}; + +/* vorbis_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). vorbis_info and substructures are in backends.h. +*********************************************************************/ + +/* the comments are not part of vorbis_info so that vorbis_info can be + static storage */ +typedef struct vorbis_comment{ + /* unlimited user comment fields. libvorbis writes 'libvorbis' + whatever vendor is set to in encode */ + char **user_comments; + int *comment_lengths; + int comments; + char *vendor; + +} vorbis_comment; + + +/* libvorbis encodes in two abstraction layers; first we perform DSP + and produce a packet (see docs/analysis.txt). The packet is then + coded into a framed OggSquish bitstream by the second layer (see + docs/framing.txt). Decode is the reverse process; we sync/frame + the bitstream and extract individual packets, then decode the + packet back into PCM audio. + + The extra framing/packetizing is used in streaming formats, such as + files. Over the net (such as with UDP), the framing and + packetization aren't necessary as they're provided by the transport + and the streaming layer is not used */ + +/* Vorbis PRIMITIVES: general ***************************************/ + +extern void vorbis_info_init(vorbis_info *vi); +extern void vorbis_info_clear(vorbis_info *vi); +extern int vorbis_info_blocksize(vorbis_info *vi,int zo); +extern void vorbis_comment_init(vorbis_comment *vc); +extern void vorbis_comment_add(vorbis_comment *vc, const char *comment); +extern void vorbis_comment_add_tag(vorbis_comment *vc, + const char *tag, const char *contents); +extern char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count); +extern int vorbis_comment_query_count(vorbis_comment *vc, const char *tag); +extern void vorbis_comment_clear(vorbis_comment *vc); + +extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); +extern int vorbis_block_clear(vorbis_block *vb); +extern void vorbis_dsp_clear(vorbis_dsp_state *v); +extern double vorbis_granule_time(vorbis_dsp_state *v, + ogg_int64_t granulepos); + +extern const char *vorbis_version_string(void); + +/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ + +extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); +extern int vorbis_analysis_headerout(vorbis_dsp_state *v, + vorbis_comment *vc, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code); +extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); + +extern int vorbis_bitrate_addblock(vorbis_block *vb); +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, + ogg_packet *op); + +/* Vorbis PRIMITIVES: synthesis layer *******************************/ +extern int vorbis_synthesis_idheader(ogg_packet *op); +extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, + ogg_packet *op); + +extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_synthesis_restart(vorbis_dsp_state *v); +extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); +extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); + +extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag); +extern int vorbis_synthesis_halfrate_p(vorbis_info *v); + +/* Vorbis ERRORS and return codes ***********************************/ + +#define OV_FALSE -1 +#define OV_EOF -2 +#define OV_HOLE -3 + +#define OV_EREAD -128 +#define OV_EFAULT -129 +#define OV_EIMPL -130 +#define OV_EINVAL -131 +#define OV_ENOTVORBIS -132 +#define OV_EBADHEADER -133 +#define OV_EVERSION -134 +#define OV_ENOTAUDIO -135 +#define OV_EBADPACKET -136 +#define OV_EBADLINK -137 +#define OV_ENOSEEK -138 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/builddir/libvorbis-1.3.3/include/vorbis/vorbisenc.h b/builddir/libvorbis-1.3.3/include/vorbis/vorbisenc.h new file mode 100644 index 0000000..02332b5 --- /dev/null +++ b/builddir/libvorbis-1.3.3/include/vorbis/vorbisenc.h @@ -0,0 +1,436 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE 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 SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: vorbis encode-engine setup + last mod: $Id: vorbisenc.h 17021 2010-03-24 09:29:41Z xiphmont $ + + ********************************************************************/ + +/** \file + * Libvorbisenc is a convenient API for setting up an encoding + * environment using libvorbis. Libvorbisenc encapsulates the + * actions needed to set up the encoder properly. + */ + +#ifndef _OV_ENC_H_ +#define _OV_ENC_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "codec.h" + +/** + * This is the primary function within libvorbisenc for setting up managed + * bitrate modes. + * + * Before this function is called, the \ref vorbis_info + * struct should be initialized by using vorbis_info_init() from the libvorbis + * API. After encoding, vorbis_info_clear() should be called. + * + * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set + * constraints for the encoded file. This function uses these settings to + * select the appropriate encoding mode and set it up. + * + * \param vi Pointer to an initialized \ref vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset. + * \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset. + * \param min_bitrate Desired minimum bitrate. -1 indicates unset. + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success. + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request. + */ +extern int vorbis_encode_init(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +/** + * This function performs step-one of a three-step bitrate-managed encode + * setup. It functions similarly to the one-step setup performed by \ref + * vorbis_encode_init but allows an application to make further encode setup + * tweaks using \ref vorbis_encode_ctl before finally calling \ref + * vorbis_encode_setup_init to complete the setup process. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set + * constraints for the encoded file. This function uses these settings to + * select the appropriate encoding mode and set it up. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset. + * \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset. + * \param min_bitrate Desired minimum bitrate. -1 indicates unset. + * + * \return Zero for success, and negative for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request. + */ +extern int vorbis_encode_setup_managed(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +/** + * This function performs step-one of a three-step variable bitrate + * (quality-based) encode setup. It functions similarly to the one-step setup + * performed by \ref vorbis_encode_init_vbr() but allows an application to + * make further encode setup tweaks using \ref vorbis_encode_ctl() before + * finally calling \ref vorbis_encode_setup_init to complete the setup + * process. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using \ref vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param quality Desired quality level, currently from -0.1 to 1.0 (lo to hi). + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request. + */ +extern int vorbis_encode_setup_vbr(vorbis_info *vi, + long channels, + long rate, + + float quality + ); + +/** + * This is the primary function within libvorbisenc for setting up variable + * bitrate ("quality" based) modes. + * + * + * Before this function is called, the vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param base_quality Desired quality level, currently from -0.1 to 1.0 (lo to hi). + * + * + * \return Zero for success, or a negative number for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request. + */ +extern int vorbis_encode_init_vbr(vorbis_info *vi, + long channels, + long rate, + + float base_quality + ); + +/** + * This function performs the last stage of three-step encoding setup, as + * described in the API overview under managed bitrate modes. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API, one of + * \ref vorbis_encode_setup_managed() or \ref vorbis_encode_setup_vbr() called to + * initialize the high-level encoding setup, and \ref vorbis_encode_ctl() + * called if necessary to make encoding setup changes. + * vorbis_encode_setup_init() finalizes the highlevel encoding structure into + * a complete encoding setup after which the application may make no further + * setup changes. + * + * After encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized \ref vorbis_info struct. + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success. + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * + * \retval OV_EINVAL Attempt to use vorbis_encode_setup_init() without first + * calling one of vorbis_encode_setup_managed() or vorbis_encode_setup_vbr() to + * initialize the high-level encoding setup + * + */ +extern int vorbis_encode_setup_init(vorbis_info *vi); + +/** + * This function implements a generic interface to miscellaneous encoder + * settings similar to the classic UNIX 'ioctl()' system call. Applications + * may use vorbis_encode_ctl() to query or set bitrate management or quality + * mode details by using one of several \e request arguments detailed below. + * vorbis_encode_ctl() must be called after one of + * vorbis_encode_setup_managed() or vorbis_encode_setup_vbr(). When used + * to modify settings, \ref vorbis_encode_ctl() must be called before \ref + * vorbis_encode_setup_init(). + * + * \param vi Pointer to an initialized vorbis_info struct. + * + * \param number Specifies the desired action; See \ref encctlcodes "the list + * of available requests". + * + * \param arg void * pointing to a data structure matching the request + * argument. + * + * \retval 0 Success. Any further return information (such as the result of a + * query) is placed into the storage pointed to by *arg. + * + * \retval OV_EINVAL Invalid argument, or an attempt to modify a setting after + * calling vorbis_encode_setup_init(). + * + * \retval OV_EIMPL Unimplemented or unknown request + */ +extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg); + +/** + * \deprecated This is a deprecated interface. Please use vorbis_encode_ctl() + * with the \ref ovectl_ratemanage2_arg struct and \ref + * OV_ECTL_RATEMANAGE2_GET and \ref OV_ECTL_RATEMANAGE2_SET calls in new code. + * + * The \ref ovectl_ratemanage_arg structure is used with vorbis_encode_ctl() + * and the \ref OV_ECTL_RATEMANAGE_GET, \ref OV_ECTL_RATEMANAGE_SET, \ref + * OV_ECTL_RATEMANAGE_AVG, \ref OV_ECTL_RATEMANAGE_HARD calls in order to + * query and modify specifics of the encoder's bitrate management + * configuration. +*/ +struct ovectl_ratemanage_arg { + int management_active; /**< nonzero if bitrate management is active*/ +/** hard lower limit (in kilobits per second) below which the stream bitrate + will never be allowed for any given bitrate_hard_window seconds of time.*/ + long bitrate_hard_min; +/** hard upper limit (in kilobits per second) above which the stream bitrate + will never be allowed for any given bitrate_hard_window seconds of time.*/ + long bitrate_hard_max; +/** the window period (in seconds) used to regulate the hard bitrate minimum + and maximum*/ + double bitrate_hard_window; +/** soft lower limit (in kilobits per second) below which the average bitrate + tracker will start nudging the bitrate higher.*/ + long bitrate_av_lo; +/** soft upper limit (in kilobits per second) above which the average bitrate + tracker will start nudging the bitrate lower.*/ + long bitrate_av_hi; +/** the window period (in seconds) used to regulate the average bitrate + minimum and maximum.*/ + double bitrate_av_window; +/** Regulates the relative centering of the average and hard windows; in + libvorbis 1.0 and 1.0.1, the hard window regulation overlapped but + followed the average window regulation. In libvorbis 1.1 a bit-reservoir + interface replaces the old windowing interface; the older windowing + interface is simulated and this field has no effect.*/ + double bitrate_av_window_center; +}; + +/** + * \name struct ovectl_ratemanage2_arg + * + * The ovectl_ratemanage2_arg structure is used with vorbis_encode_ctl() and + * the OV_ECTL_RATEMANAGE2_GET and OV_ECTL_RATEMANAGE2_SET calls in order to + * query and modify specifics of the encoder's bitrate management + * configuration. + * +*/ +struct ovectl_ratemanage2_arg { + int management_active; /**< nonzero if bitrate management is active */ +/** Lower allowed bitrate limit in kilobits per second */ + long bitrate_limit_min_kbps; +/** Upper allowed bitrate limit in kilobits per second */ + long bitrate_limit_max_kbps; + long bitrate_limit_reservoir_bits; /**<Size of the bitrate reservoir in bits */ +/** Regulates the bitrate reservoir's preferred fill level in a range from 0.0 + * to 1.0; 0.0 tries to bank bits to buffer against future bitrate spikes, 1.0 + * buffers against future sudden drops in instantaneous bitrate. Default is + * 0.1 + */ + double bitrate_limit_reservoir_bias; +/** Average bitrate setting in kilobits per second */ + long bitrate_average_kbps; +/** Slew rate limit setting for average bitrate adjustment; sets the minimum + * time in seconds the bitrate tracker may swing from one extreme to the + * other when boosting or damping average bitrate. + */ + double bitrate_average_damping; +}; + + +/** + * \name vorbis_encode_ctl() codes + * + * \anchor encctlcodes + * + * These values are passed as the \c number parameter of vorbis_encode_ctl(). + * The type of the referent of that function's \c arg pointer depends on these + * codes. + */ +/*@{*/ + +/** + * Query the current encoder bitrate management setting. + * + *Argument: <tt>struct ovectl_ratemanage2_arg *</tt> + * + * Used to query the current encoder bitrate management setting. Also used to + * initialize fields of an ovectl_ratemanage2_arg structure for use with + * \ref OV_ECTL_RATEMANAGE2_SET. + */ +#define OV_ECTL_RATEMANAGE2_GET 0x14 + +/** + * Set the current encoder bitrate management settings. + * + * Argument: <tt>struct ovectl_ratemanage2_arg *</tt> + * + * Used to set the current encoder bitrate management settings to the values + * listed in the ovectl_ratemanage2_arg. Passing a NULL pointer will disable + * bitrate management. +*/ +#define OV_ECTL_RATEMANAGE2_SET 0x15 + +/** + * Returns the current encoder hard-lowpass setting (kHz) in the double + * pointed to by arg. + * + * Argument: <tt>double *</tt> +*/ +#define OV_ECTL_LOWPASS_GET 0x20 + +/** + * Sets the encoder hard-lowpass to the value (kHz) pointed to by arg. Valid + * lowpass settings range from 2 to 99. + * + * Argument: <tt>double *</tt> +*/ +#define OV_ECTL_LOWPASS_SET 0x21 + +/** + * Returns the current encoder impulse block setting in the double pointed + * to by arg. + * + * Argument: <tt>double *</tt> +*/ +#define OV_ECTL_IBLOCK_GET 0x30 + +/** + * Sets the impulse block bias to the the value pointed to by arg. + * + * Argument: <tt>double *</tt> + * + * Valid range is -15.0 to 0.0 [default]. A negative impulse block bias will + * direct to encoder to use more bits when incoding short blocks that contain + * strong impulses, thus improving the accuracy of impulse encoding. + */ +#define OV_ECTL_IBLOCK_SET 0x31 + +/** + * Returns the current encoder coupling setting in the int pointed + * to by arg. + * + * Argument: <tt>int *</tt> +*/ +#define OV_ECTL_COUPLING_GET 0x40 + +/** + * Enables/disables channel coupling in multichannel encoding according to arg. + * + * Argument: <tt>int *</tt> + * + * Zero disables channel coupling for multichannel inputs, nonzer enables + * channel coupling. Setting has no effect on monophonic encoding or + * multichannel counts that do not offer coupling. At present, coupling is + * available for stereo and 5.1 encoding. + */ +#define OV_ECTL_COUPLING_SET 0x41 + + /* deprecated rate management supported only for compatibility */ + +/** + * Old interface to querying bitrate management settings. + * + * Deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_GET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_GET 0x10 +/** + * Old interface to modifying bitrate management settings. + * + * deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_SET 0x11 +/** + * Old interface to setting average-bitrate encoding mode. + * + * Deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_AVG 0x12 +/** + * Old interface to setting bounded-bitrate encoding modes. + * + * deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_HARD 0x13 + +/*@}*/ + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/builddir/libvorbis-1.3.3/include/vorbis/vorbisfile.h b/builddir/libvorbis-1.3.3/include/vorbis/vorbisfile.h new file mode 100644 index 0000000..9271331 --- /dev/null +++ b/builddir/libvorbis-1.3.3/include/vorbis/vorbisfile.h @@ -0,0 +1,206 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE 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 SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id: vorbisfile.h 17182 2010-04-29 03:48:32Z xiphmont $ + + ********************************************************************/ + +#ifndef _OV_FILE_H_ +#define _OV_FILE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include <stdio.h> +#include "codec.h" + +/* The function prototypes for the callbacks are basically the same as for + * the stdio functions fread, fseek, fclose, ftell. + * The one difference is that the FILE * arguments have been replaced with + * a void * - this is to be used as a pointer to whatever internal data these + * functions might need. In the stdio case, it's just a FILE * cast to a void * + * + * If you use other functions, check the docs for these functions and return + * the right values. For seek_func(), you *MUST* return -1 if the stream is + * unseekable + */ +typedef struct { + size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); + int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); + int (*close_func) (void *datasource); + long (*tell_func) (void *datasource); +} ov_callbacks; + +#ifndef OV_EXCLUDE_STATIC_CALLBACKS + +/* a few sets of convenient callbacks, especially for use under + * Windows where ov_open_callbacks() should always be used instead of + * ov_open() to avoid problems with incompatible crt.o version linking + * issues. */ + +static int _ov_header_fseek_wrap(FILE *f,ogg_int64_t off,int whence){ + if(f==NULL)return(-1); + +#ifdef __MINGW32__ + return fseeko64(f,off,whence); +#elif defined (_WIN32) + return _fseeki64(f,off,whence); +#else + return fseek(f,off,whence); +#endif +} + +/* These structs below (OV_CALLBACKS_DEFAULT etc) are defined here as + * static data. That means that every file which includes this header + * will get its own copy of these structs whether it uses them or + * not unless it #defines OV_EXCLUDE_STATIC_CALLBACKS. + * These static symbols are essential on platforms such as Windows on + * which several different versions of stdio support may be linked to + * by different DLLs, and we need to be certain we know which one + * we're using (the same one as the main application). + */ + +static ov_callbacks OV_CALLBACKS_DEFAULT = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) NULL, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) fclose, + (long (*)(void *)) NULL +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) NULL, + (long (*)(void *)) NULL +}; + +#endif + +#define NOTOPEN 0 +#define PARTOPEN 1 +#define OPENED 2 +#define STREAMSET 3 +#define INITSET 4 + +typedef struct OggVorbis_File { + void *datasource; /* Pointer to a FILE *, etc. */ + int seekable; + ogg_int64_t offset; + ogg_int64_t end; + ogg_sync_state oy; + + /* If the FILE handle isn't seekable (eg, a pipe), only the current + stream appears */ + int links; + ogg_int64_t *offsets; + ogg_int64_t *dataoffsets; + long *serialnos; + ogg_int64_t *pcmlengths; /* overloaded to maintain binary + compatibility; x2 size, stores both + beginning and end values */ + vorbis_info *vi; + vorbis_comment *vc; + + /* Decoding working state local storage */ + ogg_int64_t pcm_offset; + int ready_state; + long current_serialno; + int current_link; + + double bittrack; + double samptrack; + + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + ov_callbacks callbacks; + +} OggVorbis_File; + + +extern int ov_clear(OggVorbis_File *vf); +extern int ov_fopen(const char *path,OggVorbis_File *vf); +extern int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes); +extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf, + const char *initial, long ibytes, ov_callbacks callbacks); + +extern int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes); +extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf, + const char *initial, long ibytes, ov_callbacks callbacks); +extern int ov_test_open(OggVorbis_File *vf); + +extern long ov_bitrate(OggVorbis_File *vf,int i); +extern long ov_bitrate_instant(OggVorbis_File *vf); +extern long ov_streams(OggVorbis_File *vf); +extern long ov_seekable(OggVorbis_File *vf); +extern long ov_serialnumber(OggVorbis_File *vf,int i); + +extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i); +extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); +extern double ov_time_total(OggVorbis_File *vf,int i); + +extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page(OggVorbis_File *vf,double pos); + +extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek_lap(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos); + +extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf); +extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf); +extern double ov_time_tell(OggVorbis_File *vf); + +extern vorbis_info *ov_info(OggVorbis_File *vf,int link); +extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); + +extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples, + int *bitstream); +extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream, + void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param); +extern long ov_read(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream); +extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2); + +extern int ov_halfrate(OggVorbis_File *vf,int flag); +extern int ov_halfrate_p(OggVorbis_File *vf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/builddir/openal-soft-1.15.1/COPYING b/builddir/openal-soft-1.15.1/COPYING new file mode 100644 index 0000000..d0c8978 --- /dev/null +++ b/builddir/openal-soft-1.15.1/COPYING @@ -0,0 +1,484 @@ + + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + diff --git a/builddir/openal-soft-1.15.1/bin/OpenAL32.dll b/builddir/openal-soft-1.15.1/bin/OpenAL32.dll new file mode 100644 index 0000000..8def6ba Binary files /dev/null and b/builddir/openal-soft-1.15.1/bin/OpenAL32.dll differ diff --git a/builddir/openal-soft-1.15.1/bin/OpenAL32.exp b/builddir/openal-soft-1.15.1/bin/OpenAL32.exp new file mode 100644 index 0000000..1c40963 Binary files /dev/null and b/builddir/openal-soft-1.15.1/bin/OpenAL32.exp differ diff --git a/builddir/openal-soft-1.15.1/bin/OpenAL32.lib b/builddir/openal-soft-1.15.1/bin/OpenAL32.lib new file mode 100644 index 0000000..3edce8c Binary files /dev/null and b/builddir/openal-soft-1.15.1/bin/OpenAL32.lib differ diff --git a/builddir/openal-soft-1.15.1/bin/makehrtf.exe b/builddir/openal-soft-1.15.1/bin/makehrtf.exe new file mode 100644 index 0000000..9b8f502 Binary files /dev/null and b/builddir/openal-soft-1.15.1/bin/makehrtf.exe differ diff --git a/builddir/openal-soft-1.15.1/bin/openal-info.exe b/builddir/openal-soft-1.15.1/bin/openal-info.exe new file mode 100644 index 0000000..1521286 Binary files /dev/null and b/builddir/openal-soft-1.15.1/bin/openal-info.exe differ diff --git a/builddir/openal-soft-1.15.1/include/AL/al.h b/builddir/openal-soft-1.15.1/include/AL/al.h new file mode 100644 index 0000000..413b383 --- /dev/null +++ b/builddir/openal-soft-1.15.1/include/AL/al.h @@ -0,0 +1,656 @@ +#ifndef AL_AL_H +#define AL_AL_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#ifndef AL_API + #if defined(AL_LIBTYPE_STATIC) + #define AL_API + #elif defined(_WIN32) + #define AL_API __declspec(dllimport) + #else + #define AL_API extern + #endif +#endif + +#if defined(_WIN32) + #define AL_APIENTRY __cdecl +#else + #define AL_APIENTRY +#endif + + +/** Deprecated macro. */ +#define OPENAL +#define ALAPI AL_API +#define ALAPIENTRY AL_APIENTRY +#define AL_INVALID (-1) +#define AL_ILLEGAL_ENUM AL_INVALID_ENUM +#define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION + +/** Supported AL version. */ +#define AL_VERSION_1_0 +#define AL_VERSION_1_1 + +/** 8-bit boolean */ +typedef char ALboolean; + +/** character */ +typedef char ALchar; + +/** signed 8-bit 2's complement integer */ +typedef signed char ALbyte; + +/** unsigned 8-bit integer */ +typedef unsigned char ALubyte; + +/** signed 16-bit 2's complement integer */ +typedef short ALshort; + +/** unsigned 16-bit integer */ +typedef unsigned short ALushort; + +/** signed 32-bit 2's complement integer */ +typedef int ALint; + +/** unsigned 32-bit integer */ +typedef unsigned int ALuint; + +/** non-negative 32-bit binary integer size */ +typedef int ALsizei; + +/** enumerated 32-bit value */ +typedef int ALenum; + +/** 32-bit IEEE754 floating-point */ +typedef float ALfloat; + +/** 64-bit IEEE754 floating-point */ +typedef double ALdouble; + +/** void type (for opaque pointers only) */ +typedef void ALvoid; + + +/* Enumerant values begin at column 50. No tabs. */ + +/** "no distance model" or "no buffer" */ +#define AL_NONE 0 + +/** Boolean False. */ +#define AL_FALSE 0 + +/** Boolean True. */ +#define AL_TRUE 1 + + +/** + * Relative source. + * Type: ALboolean + * Range: [AL_TRUE, AL_FALSE] + * Default: AL_FALSE + * + * Specifies if the Source has relative coordinates. + */ +#define AL_SOURCE_RELATIVE 0x202 + + +/** + * Inner cone angle, in degrees. + * Type: ALint, ALfloat + * Range: [0 - 360] + * Default: 360 + * + * The angle covered by the inner cone, where the source will not attenuate. + */ +#define AL_CONE_INNER_ANGLE 0x1001 + +/** + * Outer cone angle, in degrees. + * Range: [0 - 360] + * Default: 360 + * + * The angle covered by the outer cone, where the source will be fully + * attenuated. + */ +#define AL_CONE_OUTER_ANGLE 0x1002 + +/** + * Source pitch. + * Type: ALfloat + * Range: [0.5 - 2.0] + * Default: 1.0 + * + * A multiplier for the frequency (sample rate) of the source's buffer. + */ +#define AL_PITCH 0x1003 + +/** + * Source or listener position. + * Type: ALfloat[3], ALint[3] + * Default: {0, 0, 0} + * + * The source or listener location in three dimensional space. + * + * OpenAL, like OpenGL, uses a right handed coordinate system, where in a + * frontal default view X (thumb) points right, Y points up (index finger), and + * Z points towards the viewer/camera (middle finger). + * + * To switch from a left handed coordinate system, flip the sign on the Z + * coordinate. + */ +#define AL_POSITION 0x1004 + +/** + * Source direction. + * Type: ALfloat[3], ALint[3] + * Default: {0, 0, 0} + * + * Specifies the current direction in local space. + * A zero-length vector specifies an omni-directional source (cone is ignored). + */ +#define AL_DIRECTION 0x1005 + +/** + * Source or listener velocity. + * Type: ALfloat[3], ALint[3] + * Default: {0, 0, 0} + * + * Specifies the current velocity in local space. + */ +#define AL_VELOCITY 0x1006 + +/** + * Source looping. + * Type: ALboolean + * Range: [AL_TRUE, AL_FALSE] + * Default: AL_FALSE + * + * Specifies whether source is looping. + */ +#define AL_LOOPING 0x1007 + +/** + * Source buffer. + * Type: ALuint + * Range: any valid Buffer. + * + * Specifies the buffer to provide sound samples. + */ +#define AL_BUFFER 0x1009 + +/** + * Source or listener gain. + * Type: ALfloat + * Range: [0.0 - ] + * + * A value of 1.0 means unattenuated. Each division by 2 equals an attenuation + * of about -6dB. Each multiplicaton by 2 equals an amplification of about + * +6dB. + * + * A value of 0.0 is meaningless with respect to a logarithmic scale; it is + * silent. + */ +#define AL_GAIN 0x100A + +/** + * Minimum source gain. + * Type: ALfloat + * Range: [0.0 - 1.0] + * + * The minimum gain allowed for a source, after distance and cone attenation is + * applied (if applicable). + */ +#define AL_MIN_GAIN 0x100D + +/** + * Maximum source gain. + * Type: ALfloat + * Range: [0.0 - 1.0] + * + * The maximum gain allowed for a source, after distance and cone attenation is + * applied (if applicable). + */ +#define AL_MAX_GAIN 0x100E + +/** + * Listener orientation. + * Type: ALfloat[6] + * Default: {0.0, 0.0, -1.0, 0.0, 1.0, 0.0} + * + * Effectively two three dimensional vectors. The first vector is the front (or + * "at") and the second is the top (or "up"). + * + * Both vectors are in local space. + */ +#define AL_ORIENTATION 0x100F + +/** + * Source state (query only). + * Type: ALint + * Range: [AL_INITIAL, AL_PLAYING, AL_PAUSED, AL_STOPPED] + */ +#define AL_SOURCE_STATE 0x1010 + +/** Source state value. */ +#define AL_INITIAL 0x1011 +#define AL_PLAYING 0x1012 +#define AL_PAUSED 0x1013 +#define AL_STOPPED 0x1014 + +/** + * Source Buffer Queue size (query only). + * Type: ALint + * + * The number of buffers queued using alSourceQueueBuffers, minus the buffers + * removed with alSourceUnqueueBuffers. + */ +#define AL_BUFFERS_QUEUED 0x1015 + +/** + * Source Buffer Queue processed count (query only). + * Type: ALint + * + * The number of queued buffers that have been fully processed, and can be + * removed with alSourceUnqueueBuffers. + * + * Looping sources will never fully process buffers because they will be set to + * play again for when the source loops. + */ +#define AL_BUFFERS_PROCESSED 0x1016 + +/** + * Source reference distance. + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 + * + * The distance in units that no attenuation occurs. + * + * At 0.0, no distance attenuation ever occurs on non-linear attenuation models. + */ +#define AL_REFERENCE_DISTANCE 0x1020 + +/** + * Source rolloff factor. + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 + * + * Multiplier to exaggerate or diminish distance attenuation. + * + * At 0.0, no distance attenuation ever occurs. + */ +#define AL_ROLLOFF_FACTOR 0x1021 + +/** + * Outer cone gain. + * Type: ALfloat + * Range: [0.0 - 1.0] + * Default: 0.0 + * + * The gain attenuation applied when the listener is outside of the source's + * outer cone. + */ +#define AL_CONE_OUTER_GAIN 0x1022 + +/** + * Source maximum distance. + * Type: ALfloat + * Range: [0.0 - ] + * Default: +inf + * + * The distance above which the source is not attenuated any further with a + * clamped distance model, or where attenuation reaches 0.0 gain for linear + * distance models with a default rolloff factor. + */ +#define AL_MAX_DISTANCE 0x1023 + +/** Source buffer position, in seconds */ +#define AL_SEC_OFFSET 0x1024 +/** Source buffer position, in sample frames */ +#define AL_SAMPLE_OFFSET 0x1025 +/** Source buffer position, in bytes */ +#define AL_BYTE_OFFSET 0x1026 + +/** + * Source type (query only). + * Type: ALint + * Range: [AL_STATIC, AL_STREAMING, AL_UNDETERMINED] + * + * A Source is Static if a Buffer has been attached using AL_BUFFER. + * + * A Source is Streaming if one or more Buffers have been attached using + * alSourceQueueBuffers. + * + * A Source is Undetermined when it has the NULL buffer attached using + * AL_BUFFER. + */ +#define AL_SOURCE_TYPE 0x1027 + +/** Source type value. */ +#define AL_STATIC 0x1028 +#define AL_STREAMING 0x1029 +#define AL_UNDETERMINED 0x1030 + +/** Buffer format specifier. */ +#define AL_FORMAT_MONO8 0x1100 +#define AL_FORMAT_MONO16 0x1101 +#define AL_FORMAT_STEREO8 0x1102 +#define AL_FORMAT_STEREO16 0x1103 + +/** Buffer frequency (query only). */ +#define AL_FREQUENCY 0x2001 +/** Buffer bits per sample (query only). */ +#define AL_BITS 0x2002 +/** Buffer channel count (query only). */ +#define AL_CHANNELS 0x2003 +/** Buffer data size (query only). */ +#define AL_SIZE 0x2004 + +/** + * Buffer state. + * + * Not for public use. + */ +#define AL_UNUSED 0x2010 +#define AL_PENDING 0x2011 +#define AL_PROCESSED 0x2012 + + +/** No error. */ +#define AL_NO_ERROR 0 + +/** Invalid name paramater passed to AL call. */ +#define AL_INVALID_NAME 0xA001 + +/** Invalid enum parameter passed to AL call. */ +#define AL_INVALID_ENUM 0xA002 + +/** Invalid value parameter passed to AL call. */ +#define AL_INVALID_VALUE 0xA003 + +/** Illegal AL call. */ +#define AL_INVALID_OPERATION 0xA004 + +/** Not enough memory. */ +#define AL_OUT_OF_MEMORY 0xA005 + + +/** Context string: Vendor ID. */ +#define AL_VENDOR 0xB001 +/** Context string: Version. */ +#define AL_VERSION 0xB002 +/** Context string: Renderer ID. */ +#define AL_RENDERER 0xB003 +/** Context string: Space-separated extension list. */ +#define AL_EXTENSIONS 0xB004 + + +/** + * Doppler scale. + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 + * + * Scale for source and listener velocities. + */ +#define AL_DOPPLER_FACTOR 0xC000 +AL_API void AL_APIENTRY alDopplerFactor(ALfloat value); + +/** + * Doppler velocity (deprecated). + * + * A multiplier applied to the Speed of Sound. + */ +#define AL_DOPPLER_VELOCITY 0xC001 +AL_API void AL_APIENTRY alDopplerVelocity(ALfloat value); + +/** + * Speed of Sound, in units per second. + * Type: ALfloat + * Range: [0.0001 - ] + * Default: 343.3 + * + * The speed at which sound waves are assumed to travel, when calculating the + * doppler effect. + */ +#define AL_SPEED_OF_SOUND 0xC003 +AL_API void AL_APIENTRY alSpeedOfSound(ALfloat value); + +/** + * Distance attenuation model. + * Type: ALint + * Range: [AL_NONE, AL_INVERSE_DISTANCE, AL_INVERSE_DISTANCE_CLAMPED, + * AL_LINEAR_DISTANCE, AL_LINEAR_DISTANCE_CLAMPED, + * AL_EXPONENT_DISTANCE, AL_EXPONENT_DISTANCE_CLAMPED] + * Default: AL_INVERSE_DISTANCE_CLAMPED + * + * The model by which sources attenuate with distance. + * + * None - No distance attenuation. + * Inverse - Doubling the distance halves the source gain. + * Linear - Linear gain scaling between the reference and max distances. + * Exponent - Exponential gain dropoff. + * + * Clamped variations work like the non-clamped counterparts, except the + * distance calculated is clamped between the reference and max distances. + */ +#define AL_DISTANCE_MODEL 0xD000 +AL_API void AL_APIENTRY alDistanceModel(ALenum distanceModel); + +/** Distance model value. */ +#define AL_INVERSE_DISTANCE 0xD001 +#define AL_INVERSE_DISTANCE_CLAMPED 0xD002 +#define AL_LINEAR_DISTANCE 0xD003 +#define AL_LINEAR_DISTANCE_CLAMPED 0xD004 +#define AL_EXPONENT_DISTANCE 0xD005 +#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006 + +/** Renderer State management. */ +AL_API void AL_APIENTRY alEnable(ALenum capability); +AL_API void AL_APIENTRY alDisable(ALenum capability); +AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability); + +/** State retrieval. */ +AL_API const ALchar* AL_APIENTRY alGetString(ALenum param); +AL_API void AL_APIENTRY alGetBooleanv(ALenum param, ALboolean *values); +AL_API void AL_APIENTRY alGetIntegerv(ALenum param, ALint *values); +AL_API void AL_APIENTRY alGetFloatv(ALenum param, ALfloat *values); +AL_API void AL_APIENTRY alGetDoublev(ALenum param, ALdouble *values); +AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum param); +AL_API ALint AL_APIENTRY alGetInteger(ALenum param); +AL_API ALfloat AL_APIENTRY alGetFloat(ALenum param); +AL_API ALdouble AL_APIENTRY alGetDouble(ALenum param); + +/** + * Error retrieval. + * + * Obtain the first error generated in the AL context since the last check. + */ +AL_API ALenum AL_APIENTRY alGetError(void); + +/** + * Extension support. + * + * Query for the presence of an extension, and obtain any appropriate function + * pointers and enum values. + */ +AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extname); +AL_API void* AL_APIENTRY alGetProcAddress(const ALchar *fname); +AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *ename); + + +/** Set Listener parameters */ +AL_API void AL_APIENTRY alListenerf(ALenum param, ALfloat value); +AL_API void AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +AL_API void AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values); +AL_API void AL_APIENTRY alListeneri(ALenum param, ALint value); +AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3); +AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values); + +/** Get Listener parameters */ +AL_API void AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value); +AL_API void AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +AL_API void AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values); +AL_API void AL_APIENTRY alGetListeneri(ALenum param, ALint *value); +AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3); +AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint *values); + + +/** Create Source objects. */ +AL_API void AL_APIENTRY alGenSources(ALsizei n, ALuint *sources); +/** Delete Source objects. */ +AL_API void AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources); +/** Verify a handle is a valid Source. */ +AL_API ALboolean AL_APIENTRY alIsSource(ALuint source); + +/** Set Source parameters. */ +AL_API void AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value); +AL_API void AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +AL_API void AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat *values); +AL_API void AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value); +AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3); +AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *values); + +/** Get Source parameters. */ +AL_API void AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *value); +AL_API void AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +AL_API void AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *values); +AL_API void AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value); +AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3); +AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values); + + +/** Play, replay, or resume (if paused) a list of Sources */ +AL_API void AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources); +/** Stop a list of Sources */ +AL_API void AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources); +/** Rewind a list of Sources */ +AL_API void AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources); +/** Pause a list of Sources */ +AL_API void AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources); + +/** Play, replay, or resume a Source */ +AL_API void AL_APIENTRY alSourcePlay(ALuint source); +/** Stop a Source */ +AL_API void AL_APIENTRY alSourceStop(ALuint source); +/** Rewind a Source (set playback postiton to beginning) */ +AL_API void AL_APIENTRY alSourceRewind(ALuint source); +/** Pause a Source */ +AL_API void AL_APIENTRY alSourcePause(ALuint source); + +/** Queue buffers onto a source */ +AL_API void AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei nb, const ALuint *buffers); +/** Unqueue processed buffers from a source */ +AL_API void AL_APIENTRY alSourceUnqueueBuffers(ALuint source, ALsizei nb, ALuint *buffers); + + +/** Create Buffer objects */ +AL_API void AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers); +/** Delete Buffer objects */ +AL_API void AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers); +/** Verify a handle is a valid Buffer */ +AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer); + +/** Specifies the data to be copied into a buffer */ +AL_API void AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq); + +/** Set Buffer parameters, */ +AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat value); +AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values); +AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value); +AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3); +AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values); + +/** Get Buffer parameters. */ +AL_API void AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value); +AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *values); +AL_API void AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value); +AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3); +AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values); + +/** Pointer-to-function type, useful for dynamically getting AL entry points. */ +typedef void (AL_APIENTRY *LPALENABLE)(ALenum capability); +typedef void (AL_APIENTRY *LPALDISABLE)(ALenum capability); +typedef ALboolean (AL_APIENTRY *LPALISENABLED)(ALenum capability); +typedef const ALchar* (AL_APIENTRY *LPALGETSTRING)(ALenum param); +typedef void (AL_APIENTRY *LPALGETBOOLEANV)(ALenum param, ALboolean *values); +typedef void (AL_APIENTRY *LPALGETINTEGERV)(ALenum param, ALint *values); +typedef void (AL_APIENTRY *LPALGETFLOATV)(ALenum param, ALfloat *values); +typedef void (AL_APIENTRY *LPALGETDOUBLEV)(ALenum param, ALdouble *values); +typedef ALboolean (AL_APIENTRY *LPALGETBOOLEAN)(ALenum param); +typedef ALint (AL_APIENTRY *LPALGETINTEGER)(ALenum param); +typedef ALfloat (AL_APIENTRY *LPALGETFLOAT)(ALenum param); +typedef ALdouble (AL_APIENTRY *LPALGETDOUBLE)(ALenum param); +typedef ALenum (AL_APIENTRY *LPALGETERROR)(void); +typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENT)(const ALchar *extname); +typedef void* (AL_APIENTRY *LPALGETPROCADDRESS)(const ALchar *fname); +typedef ALenum (AL_APIENTRY *LPALGETENUMVALUE)(const ALchar *ename); +typedef void (AL_APIENTRY *LPALLISTENERF)(ALenum param, ALfloat value); +typedef void (AL_APIENTRY *LPALLISTENER3F)(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +typedef void (AL_APIENTRY *LPALLISTENERFV)(ALenum param, const ALfloat *values); +typedef void (AL_APIENTRY *LPALLISTENERI)(ALenum param, ALint value); +typedef void (AL_APIENTRY *LPALLISTENER3I)(ALenum param, ALint value1, ALint value2, ALint value3); +typedef void (AL_APIENTRY *LPALLISTENERIV)(ALenum param, const ALint *values); +typedef void (AL_APIENTRY *LPALGETLISTENERF)(ALenum param, ALfloat *value); +typedef void (AL_APIENTRY *LPALGETLISTENER3F)(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +typedef void (AL_APIENTRY *LPALGETLISTENERFV)(ALenum param, ALfloat *values); +typedef void (AL_APIENTRY *LPALGETLISTENERI)(ALenum param, ALint *value); +typedef void (AL_APIENTRY *LPALGETLISTENER3I)(ALenum param, ALint *value1, ALint *value2, ALint *value3); +typedef void (AL_APIENTRY *LPALGETLISTENERIV)(ALenum param, ALint *values); +typedef void (AL_APIENTRY *LPALGENSOURCES)(ALsizei n, ALuint *sources); +typedef void (AL_APIENTRY *LPALDELETESOURCES)(ALsizei n, const ALuint *sources); +typedef ALboolean (AL_APIENTRY *LPALISSOURCE)(ALuint source); +typedef void (AL_APIENTRY *LPALSOURCEF)(ALuint source, ALenum param, ALfloat value); +typedef void (AL_APIENTRY *LPALSOURCE3F)(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +typedef void (AL_APIENTRY *LPALSOURCEFV)(ALuint source, ALenum param, const ALfloat *values); +typedef void (AL_APIENTRY *LPALSOURCEI)(ALuint source, ALenum param, ALint value); +typedef void (AL_APIENTRY *LPALSOURCE3I)(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3); +typedef void (AL_APIENTRY *LPALSOURCEIV)(ALuint source, ALenum param, const ALint *values); +typedef void (AL_APIENTRY *LPALGETSOURCEF)(ALuint source, ALenum param, ALfloat *value); +typedef void (AL_APIENTRY *LPALGETSOURCE3F)(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +typedef void (AL_APIENTRY *LPALGETSOURCEFV)(ALuint source, ALenum param, ALfloat *values); +typedef void (AL_APIENTRY *LPALGETSOURCEI)(ALuint source, ALenum param, ALint *value); +typedef void (AL_APIENTRY *LPALGETSOURCE3I)(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3); +typedef void (AL_APIENTRY *LPALGETSOURCEIV)(ALuint source, ALenum param, ALint *values); +typedef void (AL_APIENTRY *LPALSOURCEPLAYV)(ALsizei n, const ALuint *sources); +typedef void (AL_APIENTRY *LPALSOURCESTOPV)(ALsizei n, const ALuint *sources); +typedef void (AL_APIENTRY *LPALSOURCEREWINDV)(ALsizei n, const ALuint *sources); +typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)(ALsizei n, const ALuint *sources); +typedef void (AL_APIENTRY *LPALSOURCEPLAY)(ALuint source); +typedef void (AL_APIENTRY *LPALSOURCESTOP)(ALuint source); +typedef void (AL_APIENTRY *LPALSOURCEREWIND)(ALuint source); +typedef void (AL_APIENTRY *LPALSOURCEPAUSE)(ALuint source); +typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint source, ALsizei nb, const ALuint *buffers); +typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint source, ALsizei nb, ALuint *buffers); +typedef void (AL_APIENTRY *LPALGENBUFFERS)(ALsizei n, ALuint *buffers); +typedef void (AL_APIENTRY *LPALDELETEBUFFERS)(ALsizei n, const ALuint *buffers); +typedef ALboolean (AL_APIENTRY *LPALISBUFFER)(ALuint buffer); +typedef void (AL_APIENTRY *LPALBUFFERDATA)(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq); +typedef void (AL_APIENTRY *LPALBUFFERF)(ALuint buffer, ALenum param, ALfloat value); +typedef void (AL_APIENTRY *LPALBUFFER3F)(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +typedef void (AL_APIENTRY *LPALBUFFERFV)(ALuint buffer, ALenum param, const ALfloat *values); +typedef void (AL_APIENTRY *LPALBUFFERI)(ALuint buffer, ALenum param, ALint value); +typedef void (AL_APIENTRY *LPALBUFFER3I)(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3); +typedef void (AL_APIENTRY *LPALBUFFERIV)(ALuint buffer, ALenum param, const ALint *values); +typedef void (AL_APIENTRY *LPALGETBUFFERF)(ALuint buffer, ALenum param, ALfloat *value); +typedef void (AL_APIENTRY *LPALGETBUFFER3F)(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +typedef void (AL_APIENTRY *LPALGETBUFFERFV)(ALuint buffer, ALenum param, ALfloat *values); +typedef void (AL_APIENTRY *LPALGETBUFFERI)(ALuint buffer, ALenum param, ALint *value); +typedef void (AL_APIENTRY *LPALGETBUFFER3I)(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3); +typedef void (AL_APIENTRY *LPALGETBUFFERIV)(ALuint buffer, ALenum param, ALint *values); +typedef void (AL_APIENTRY *LPALDOPPLERFACTOR)(ALfloat value); +typedef void (AL_APIENTRY *LPALDOPPLERVELOCITY)(ALfloat value); +typedef void (AL_APIENTRY *LPALSPEEDOFSOUND)(ALfloat value); +typedef void (AL_APIENTRY *LPALDISTANCEMODEL)(ALenum distanceModel); + +#if defined(__cplusplus) +} /* extern "C" */ +#endif + +#endif /* AL_AL_H */ diff --git a/builddir/openal-soft-1.15.1/include/AL/alc.h b/builddir/openal-soft-1.15.1/include/AL/alc.h new file mode 100644 index 0000000..294e8b3 --- /dev/null +++ b/builddir/openal-soft-1.15.1/include/AL/alc.h @@ -0,0 +1,237 @@ +#ifndef AL_ALC_H +#define AL_ALC_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#ifndef ALC_API + #if defined(AL_LIBTYPE_STATIC) + #define ALC_API + #elif defined(_WIN32) + #define ALC_API __declspec(dllimport) + #else + #define ALC_API extern + #endif +#endif + +#if defined(_WIN32) + #define ALC_APIENTRY __cdecl +#else + #define ALC_APIENTRY +#endif + + +/** Deprecated macro. */ +#define ALCAPI ALC_API +#define ALCAPIENTRY ALC_APIENTRY +#define ALC_INVALID 0 + +/** Supported ALC version? */ +#define ALC_VERSION_0_1 1 + +/** Opaque device handle */ +typedef struct ALCdevice_struct ALCdevice; +/** Opaque context handle */ +typedef struct ALCcontext_struct ALCcontext; + +/** 8-bit boolean */ +typedef char ALCboolean; + +/** character */ +typedef char ALCchar; + +/** signed 8-bit 2's complement integer */ +typedef signed char ALCbyte; + +/** unsigned 8-bit integer */ +typedef unsigned char ALCubyte; + +/** signed 16-bit 2's complement integer */ +typedef short ALCshort; + +/** unsigned 16-bit integer */ +typedef unsigned short ALCushort; + +/** signed 32-bit 2's complement integer */ +typedef int ALCint; + +/** unsigned 32-bit integer */ +typedef unsigned int ALCuint; + +/** non-negative 32-bit binary integer size */ +typedef int ALCsizei; + +/** enumerated 32-bit value */ +typedef int ALCenum; + +/** 32-bit IEEE754 floating-point */ +typedef float ALCfloat; + +/** 64-bit IEEE754 floating-point */ +typedef double ALCdouble; + +/** void type (for opaque pointers only) */ +typedef void ALCvoid; + + +/* Enumerant values begin at column 50. No tabs. */ + +/** Boolean False. */ +#define ALC_FALSE 0 + +/** Boolean True. */ +#define ALC_TRUE 1 + +/** Context attribute: <int> Hz. */ +#define ALC_FREQUENCY 0x1007 + +/** Context attribute: <int> Hz. */ +#define ALC_REFRESH 0x1008 + +/** Context attribute: AL_TRUE or AL_FALSE. */ +#define ALC_SYNC 0x1009 + +/** Context attribute: <int> requested Mono (3D) Sources. */ +#define ALC_MONO_SOURCES 0x1010 + +/** Context attribute: <int> requested Stereo Sources. */ +#define ALC_STEREO_SOURCES 0x1011 + +/** No error. */ +#define ALC_NO_ERROR 0 + +/** Invalid device handle. */ +#define ALC_INVALID_DEVICE 0xA001 + +/** Invalid context handle. */ +#define ALC_INVALID_CONTEXT 0xA002 + +/** Invalid enum parameter passed to an ALC call. */ +#define ALC_INVALID_ENUM 0xA003 + +/** Invalid value parameter passed to an ALC call. */ +#define ALC_INVALID_VALUE 0xA004 + +/** Out of memory. */ +#define ALC_OUT_OF_MEMORY 0xA005 + + +/** Runtime ALC version. */ +#define ALC_MAJOR_VERSION 0x1000 +#define ALC_MINOR_VERSION 0x1001 + +/** Context attribute list properties. */ +#define ALC_ATTRIBUTES_SIZE 0x1002 +#define ALC_ALL_ATTRIBUTES 0x1003 + +/** String for the default device specifier. */ +#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004 +/** + * String for the given device's specifier. + * + * If device handle is NULL, it is instead a null-char separated list of + * strings of known device specifiers (list ends with an empty string). + */ +#define ALC_DEVICE_SPECIFIER 0x1005 +/** String for space-separated list of ALC extensions. */ +#define ALC_EXTENSIONS 0x1006 + + +/** Capture extension */ +#define ALC_EXT_CAPTURE 1 +/** + * String for the given capture device's specifier. + * + * If device handle is NULL, it is instead a null-char separated list of + * strings of known capture device specifiers (list ends with an empty string). + */ +#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310 +/** String for the default capture device specifier. */ +#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311 +/** Number of sample frames available for capture. */ +#define ALC_CAPTURE_SAMPLES 0x312 + + +/** Enumerate All extension */ +#define ALC_ENUMERATE_ALL_EXT 1 +/** String for the default extended device specifier. */ +#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012 +/** + * String for the given extended device's specifier. + * + * If device handle is NULL, it is instead a null-char separated list of + * strings of known extended device specifiers (list ends with an empty string). + */ +#define ALC_ALL_DEVICES_SPECIFIER 0x1013 + + +/** Context management. */ +ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint* attrlist); +ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context); +ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context); +ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context); +ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context); +ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void); +ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *context); + +/** Device management. */ +ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename); +ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device); + + +/** + * Error support. + * + * Obtain the most recent Device error. + */ +ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device); + +/** + * Extension support. + * + * Query for the presence of an extension, and obtain any appropriate + * function pointers and enum values. + */ +ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extname); +ALC_API void* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcname); +ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumname); + +/** Query function. */ +ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param); +ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values); + +/** Capture function. */ +ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize); +ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device); +ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device); +ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device); +ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples); + +/** Pointer-to-function type, useful for dynamically getting ALC entry points. */ +typedef ALCcontext* (ALC_APIENTRY *LPALCCREATECONTEXT)(ALCdevice *device, const ALCint *attrlist); +typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)(ALCcontext *context); +typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)(ALCcontext *context); +typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)(ALCcontext *context); +typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)(ALCcontext *context); +typedef ALCcontext* (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)(void); +typedef ALCdevice* (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)(ALCcontext *context); +typedef ALCdevice* (ALC_APIENTRY *LPALCOPENDEVICE)(const ALCchar *devicename); +typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)(ALCdevice *device); +typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)(ALCdevice *device); +typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)(ALCdevice *device, const ALCchar *extname); +typedef void* (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname); +typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname); +typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)(ALCdevice *device, ALCenum param); +typedef void (ALC_APIENTRY *LPALCGETINTEGERV)(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values); +typedef ALCdevice* (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize); +typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)(ALCdevice *device); +typedef void (ALC_APIENTRY *LPALCCAPTURESTART)(ALCdevice *device); +typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)(ALCdevice *device); +typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)(ALCdevice *device, ALCvoid *buffer, ALCsizei samples); + +#if defined(__cplusplus) +} +#endif + +#endif /* AL_ALC_H */ diff --git a/builddir/openal-soft-1.15.1/include/AL/alext.h b/builddir/openal-soft-1.15.1/include/AL/alext.h new file mode 100644 index 0000000..0447f2b --- /dev/null +++ b/builddir/openal-soft-1.15.1/include/AL/alext.h @@ -0,0 +1,355 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2008 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#ifndef AL_ALEXT_H +#define AL_ALEXT_H + +#include <stddef.h> +/* Define int64_t and uint64_t types */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include <inttypes.h> +#elif defined(_WIN32) && defined(__GNUC__) +#include <stdint.h> +#elif defined(_WIN32) +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include <inttypes.h> +#endif + +#include "alc.h" +#include "al.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef AL_LOKI_IMA_ADPCM_format +#define AL_LOKI_IMA_ADPCM_format 1 +#define AL_FORMAT_IMA_ADPCM_MONO16_EXT 0x10000 +#define AL_FORMAT_IMA_ADPCM_STEREO16_EXT 0x10001 +#endif + +#ifndef AL_LOKI_WAVE_format +#define AL_LOKI_WAVE_format 1 +#define AL_FORMAT_WAVE_EXT 0x10002 +#endif + +#ifndef AL_EXT_vorbis +#define AL_EXT_vorbis 1 +#define AL_FORMAT_VORBIS_EXT 0x10003 +#endif + +#ifndef AL_LOKI_quadriphonic +#define AL_LOKI_quadriphonic 1 +#define AL_FORMAT_QUAD8_LOKI 0x10004 +#define AL_FORMAT_QUAD16_LOKI 0x10005 +#endif + +#ifndef AL_EXT_float32 +#define AL_EXT_float32 1 +#define AL_FORMAT_MONO_FLOAT32 0x10010 +#define AL_FORMAT_STEREO_FLOAT32 0x10011 +#endif + +#ifndef AL_EXT_double +#define AL_EXT_double 1 +#define AL_FORMAT_MONO_DOUBLE_EXT 0x10012 +#define AL_FORMAT_STEREO_DOUBLE_EXT 0x10013 +#endif + +#ifndef AL_EXT_MULAW +#define AL_EXT_MULAW 1 +#define AL_FORMAT_MONO_MULAW_EXT 0x10014 +#define AL_FORMAT_STEREO_MULAW_EXT 0x10015 +#endif + +#ifndef AL_EXT_ALAW +#define AL_EXT_ALAW 1 +#define AL_FORMAT_MONO_ALAW_EXT 0x10016 +#define AL_FORMAT_STEREO_ALAW_EXT 0x10017 +#endif + +#ifndef ALC_LOKI_audio_channel +#define ALC_LOKI_audio_channel 1 +#define ALC_CHAN_MAIN_LOKI 0x500001 +#define ALC_CHAN_PCM_LOKI 0x500002 +#define ALC_CHAN_CD_LOKI 0x500003 +#endif + +#ifndef AL_EXT_MCFORMATS +#define AL_EXT_MCFORMATS 1 +#define AL_FORMAT_QUAD8 0x1204 +#define AL_FORMAT_QUAD16 0x1205 +#define AL_FORMAT_QUAD32 0x1206 +#define AL_FORMAT_REAR8 0x1207 +#define AL_FORMAT_REAR16 0x1208 +#define AL_FORMAT_REAR32 0x1209 +#define AL_FORMAT_51CHN8 0x120A +#define AL_FORMAT_51CHN16 0x120B +#define AL_FORMAT_51CHN32 0x120C +#define AL_FORMAT_61CHN8 0x120D +#define AL_FORMAT_61CHN16 0x120E +#define AL_FORMAT_61CHN32 0x120F +#define AL_FORMAT_71CHN8 0x1210 +#define AL_FORMAT_71CHN16 0x1211 +#define AL_FORMAT_71CHN32 0x1212 +#endif + +#ifndef AL_EXT_MULAW_MCFORMATS +#define AL_EXT_MULAW_MCFORMATS 1 +#define AL_FORMAT_MONO_MULAW 0x10014 +#define AL_FORMAT_STEREO_MULAW 0x10015 +#define AL_FORMAT_QUAD_MULAW 0x10021 +#define AL_FORMAT_REAR_MULAW 0x10022 +#define AL_FORMAT_51CHN_MULAW 0x10023 +#define AL_FORMAT_61CHN_MULAW 0x10024 +#define AL_FORMAT_71CHN_MULAW 0x10025 +#endif + +#ifndef AL_EXT_IMA4 +#define AL_EXT_IMA4 1 +#define AL_FORMAT_MONO_IMA4 0x1300 +#define AL_FORMAT_STEREO_IMA4 0x1301 +#endif + +#ifndef AL_EXT_STATIC_BUFFER +#define AL_EXT_STATIC_BUFFER 1 +typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei); +#ifdef AL_ALEXT_PROTOTYPES +AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq); +#endif +#endif + +#ifndef ALC_EXT_EFX +#define ALC_EXT_EFX 1 +#include "efx.h" +#endif + +#ifndef ALC_EXT_disconnect +#define ALC_EXT_disconnect 1 +#define ALC_CONNECTED 0x313 +#endif + +#ifndef ALC_EXT_thread_local_context +#define ALC_EXT_thread_local_context 1 +typedef ALCboolean (ALC_APIENTRY*PFNALCSETTHREADCONTEXTPROC)(ALCcontext *context); +typedef ALCcontext* (ALC_APIENTRY*PFNALCGETTHREADCONTEXTPROC)(void); +#ifdef AL_ALEXT_PROTOTYPES +ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context); +ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void); +#endif +#endif + +#ifndef AL_EXT_source_distance_model +#define AL_EXT_source_distance_model 1 +#define AL_SOURCE_DISTANCE_MODEL 0x200 +#endif + +#ifndef AL_SOFT_buffer_sub_data +#define AL_SOFT_buffer_sub_data 1 +#define AL_BYTE_RW_OFFSETS_SOFT 0x1031 +#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032 +typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei); +#ifdef AL_ALEXT_PROTOTYPES +AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length); +#endif +#endif + +#ifndef AL_SOFT_loop_points +#define AL_SOFT_loop_points 1 +#define AL_LOOP_POINTS_SOFT 0x2015 +#endif + +#ifndef AL_EXT_FOLDBACK +#define AL_EXT_FOLDBACK 1 +#define AL_EXT_FOLDBACK_NAME "AL_EXT_FOLDBACK" +#define AL_FOLDBACK_EVENT_BLOCK 0x4112 +#define AL_FOLDBACK_EVENT_START 0x4111 +#define AL_FOLDBACK_EVENT_STOP 0x4113 +#define AL_FOLDBACK_MODE_MONO 0x4101 +#define AL_FOLDBACK_MODE_STEREO 0x4102 +typedef void (AL_APIENTRY*LPALFOLDBACKCALLBACK)(ALenum,ALsizei); +typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTART)(ALenum,ALsizei,ALsizei,ALfloat*,LPALFOLDBACKCALLBACK); +typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTOP)(void); +#ifdef AL_ALEXT_PROTOTYPES +AL_API void AL_APIENTRY alRequestFoldbackStart(ALenum mode,ALsizei count,ALsizei length,ALfloat *mem,LPALFOLDBACKCALLBACK callback); +AL_API void AL_APIENTRY alRequestFoldbackStop(void); +#endif +#endif + +#ifndef ALC_EXT_DEDICATED +#define ALC_EXT_DEDICATED 1 +#define AL_DEDICATED_GAIN 0x0001 +#define AL_EFFECT_DEDICATED_DIALOGUE 0x9001 +#define AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT 0x9000 +#endif + +#ifndef AL_SOFT_buffer_samples +#define AL_SOFT_buffer_samples 1 +/* Channel configurations */ +#define AL_MONO_SOFT 0x1500 +#define AL_STEREO_SOFT 0x1501 +#define AL_REAR_SOFT 0x1502 +#define AL_QUAD_SOFT 0x1503 +#define AL_5POINT1_SOFT 0x1504 +#define AL_6POINT1_SOFT 0x1505 +#define AL_7POINT1_SOFT 0x1506 + +/* Sample types */ +#define AL_BYTE_SOFT 0x1400 +#define AL_UNSIGNED_BYTE_SOFT 0x1401 +#define AL_SHORT_SOFT 0x1402 +#define AL_UNSIGNED_SHORT_SOFT 0x1403 +#define AL_INT_SOFT 0x1404 +#define AL_UNSIGNED_INT_SOFT 0x1405 +#define AL_FLOAT_SOFT 0x1406 +#define AL_DOUBLE_SOFT 0x1407 +#define AL_BYTE3_SOFT 0x1408 +#define AL_UNSIGNED_BYTE3_SOFT 0x1409 + +/* Storage formats */ +#define AL_MONO8_SOFT 0x1100 +#define AL_MONO16_SOFT 0x1101 +#define AL_MONO32F_SOFT 0x10010 +#define AL_STEREO8_SOFT 0x1102 +#define AL_STEREO16_SOFT 0x1103 +#define AL_STEREO32F_SOFT 0x10011 +#define AL_QUAD8_SOFT 0x1204 +#define AL_QUAD16_SOFT 0x1205 +#define AL_QUAD32F_SOFT 0x1206 +#define AL_REAR8_SOFT 0x1207 +#define AL_REAR16_SOFT 0x1208 +#define AL_REAR32F_SOFT 0x1209 +#define AL_5POINT1_8_SOFT 0x120A +#define AL_5POINT1_16_SOFT 0x120B +#define AL_5POINT1_32F_SOFT 0x120C +#define AL_6POINT1_8_SOFT 0x120D +#define AL_6POINT1_16_SOFT 0x120E +#define AL_6POINT1_32F_SOFT 0x120F +#define AL_7POINT1_8_SOFT 0x1210 +#define AL_7POINT1_16_SOFT 0x1211 +#define AL_7POINT1_32F_SOFT 0x1212 + +/* Buffer attributes */ +#define AL_INTERNAL_FORMAT_SOFT 0x2008 +#define AL_BYTE_LENGTH_SOFT 0x2009 +#define AL_SAMPLE_LENGTH_SOFT 0x200A +#define AL_SEC_LENGTH_SOFT 0x200B + +typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*); +typedef void (AL_APIENTRY*LPALBUFFERSUBSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*); +typedef void (AL_APIENTRY*LPALGETBUFFERSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*); +typedef ALboolean (AL_APIENTRY*LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum); +#ifdef AL_ALEXT_PROTOTYPES +AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data); +AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data); +AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data); +AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format); +#endif +#endif + +#ifndef AL_SOFT_direct_channels +#define AL_SOFT_direct_channels 1 +#define AL_DIRECT_CHANNELS_SOFT 0x1033 +#endif + +#ifndef ALC_SOFT_loopback +#define ALC_SOFT_loopback 1 +#define ALC_FORMAT_CHANNELS_SOFT 0x1990 +#define ALC_FORMAT_TYPE_SOFT 0x1991 + +/* Sample types */ +#define ALC_BYTE_SOFT 0x1400 +#define ALC_UNSIGNED_BYTE_SOFT 0x1401 +#define ALC_SHORT_SOFT 0x1402 +#define ALC_UNSIGNED_SHORT_SOFT 0x1403 +#define ALC_INT_SOFT 0x1404 +#define ALC_UNSIGNED_INT_SOFT 0x1405 +#define ALC_FLOAT_SOFT 0x1406 + +/* Channel configurations */ +#define ALC_MONO_SOFT 0x1500 +#define ALC_STEREO_SOFT 0x1501 +#define ALC_QUAD_SOFT 0x1503 +#define ALC_5POINT1_SOFT 0x1504 +#define ALC_6POINT1_SOFT 0x1505 +#define ALC_7POINT1_SOFT 0x1506 + +typedef ALCdevice* (ALC_APIENTRY*LPALCLOOPBACKOPENDEVICESOFT)(const ALCchar*); +typedef ALCboolean (ALC_APIENTRY*LPALCISRENDERFORMATSUPPORTEDSOFT)(ALCdevice*,ALCsizei,ALCenum,ALCenum); +typedef void (ALC_APIENTRY*LPALCRENDERSAMPLESSOFT)(ALCdevice*,ALCvoid*,ALCsizei); +#ifdef AL_ALEXT_PROTOTYPES +ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName); +ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type); +ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples); +#endif +#endif + +#ifndef AL_EXT_STEREO_ANGLES +#define AL_EXT_STEREO_ANGLES 1 +#define AL_STEREO_ANGLES 0x1030 +#endif + +#ifndef AL_EXT_SOURCE_RADIUS +#define AL_EXT_SOURCE_RADIUS 1 +#define AL_SOURCE_RADIUS 0x1031 +#endif + +#ifndef AL_SOFT_source_latency +#define AL_SOFT_source_latency 1 +#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200 +#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201 +typedef int64_t ALint64SOFT; +typedef uint64_t ALuint64SOFT; +typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble); +typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble); +typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*); +typedef void (AL_APIENTRY*LPALGETSOURCEDSOFT)(ALuint,ALenum,ALdouble*); +typedef void (AL_APIENTRY*LPALGETSOURCE3DSOFT)(ALuint,ALenum,ALdouble*,ALdouble*,ALdouble*); +typedef void (AL_APIENTRY*LPALGETSOURCEDVSOFT)(ALuint,ALenum,ALdouble*); +typedef void (AL_APIENTRY*LPALSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT); +typedef void (AL_APIENTRY*LPALSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT,ALint64SOFT,ALint64SOFT); +typedef void (AL_APIENTRY*LPALSOURCEI64VSOFT)(ALuint,ALenum,const ALint64SOFT*); +typedef void (AL_APIENTRY*LPALGETSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT*); +typedef void (AL_APIENTRY*LPALGETSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT*,ALint64SOFT*,ALint64SOFT*); +typedef void (AL_APIENTRY*LPALGETSOURCEI64VSOFT)(ALuint,ALenum,ALint64SOFT*); +#ifdef AL_ALEXT_PROTOTYPES +AL_API void AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value); +AL_API void AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3); +AL_API void AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values); +AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value); +AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3); +AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values); +AL_API void AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value); +AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3); +AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values); +AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value); +AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3); +AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values); +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/builddir/openal-soft-1.15.1/include/AL/efx-creative.h b/builddir/openal-soft-1.15.1/include/AL/efx-creative.h new file mode 100644 index 0000000..0a04c98 --- /dev/null +++ b/builddir/openal-soft-1.15.1/include/AL/efx-creative.h @@ -0,0 +1,3 @@ +/* The tokens that would be defined here are already defined in efx.h. This + * empty file is here to provide compatibility with Windows-based projects + * that would include it. */ diff --git a/builddir/openal-soft-1.15.1/include/AL/efx-presets.h b/builddir/openal-soft-1.15.1/include/AL/efx-presets.h new file mode 100644 index 0000000..86dcbda --- /dev/null +++ b/builddir/openal-soft-1.15.1/include/AL/efx-presets.h @@ -0,0 +1,402 @@ +/* Reverb presets for EFX */ + +#ifndef EFX_PRESETS_H +#define EFX_PRESETS_H + +#ifndef EFXEAXREVERBPROPERTIES_DEFINED +#define EFXEAXREVERBPROPERTIES_DEFINED +typedef struct { + float flDensity; + float flDiffusion; + float flGain; + float flGainHF; + float flGainLF; + float flDecayTime; + float flDecayHFRatio; + float flDecayLFRatio; + float flReflectionsGain; + float flReflectionsDelay; + float flReflectionsPan[3]; + float flLateReverbGain; + float flLateReverbDelay; + float flLateReverbPan[3]; + float flEchoTime; + float flEchoDepth; + float flModulationTime; + float flModulationDepth; + float flAirAbsorptionGainHF; + float flHFReference; + float flLFReference; + float flRoomRolloffFactor; + int iDecayHFLimit; +} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES; +#endif + +/* Default Presets */ + +#define EFX_REVERB_PRESET_GENERIC \ + { 1.0000f, 1.0000f, 0.3162f, 0.8913f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PADDEDCELL \ + { 0.1715f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.1700f, 0.1000f, 1.0000f, 0.2500f, 0.0010f, { 0.0000f, 0.0000f, 0.0000f }, 1.2691f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ROOM \ + { 0.4287f, 1.0000f, 0.3162f, 0.5929f, 1.0000f, 0.4000f, 0.8300f, 1.0000f, 0.1503f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.0629f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_BATHROOM \ + { 0.1715f, 1.0000f, 0.3162f, 0.2512f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.6531f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 3.2734f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_LIVINGROOM \ + { 0.9766f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.5000f, 0.1000f, 1.0000f, 0.2051f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2805f, 0.0040f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_STONEROOM \ + { 1.0000f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 2.3100f, 0.6400f, 1.0000f, 0.4411f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1003f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_AUDITORIUM \ + { 1.0000f, 1.0000f, 0.3162f, 0.5781f, 1.0000f, 4.3200f, 0.5900f, 1.0000f, 0.4032f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7170f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CONCERTHALL \ + { 1.0000f, 1.0000f, 0.3162f, 0.5623f, 1.0000f, 3.9200f, 0.7000f, 1.0000f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.9977f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CAVE \ + { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 2.9100f, 1.3000f, 1.0000f, 0.5000f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.7063f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_ARENA \ + { 1.0000f, 1.0000f, 0.3162f, 0.4477f, 1.0000f, 7.2400f, 0.3300f, 1.0000f, 0.2612f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.0186f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_HANGAR \ + { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 10.0500f, 0.2300f, 1.0000f, 0.5000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2560f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CARPETEDHALLWAY \ + { 0.4287f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 0.3000f, 0.1000f, 1.0000f, 0.1215f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.1531f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_HALLWAY \ + { 0.3645f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 1.4900f, 0.5900f, 1.0000f, 0.2458f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.6615f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_STONECORRIDOR \ + { 1.0000f, 1.0000f, 0.3162f, 0.7612f, 1.0000f, 2.7000f, 0.7900f, 1.0000f, 0.2472f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 1.5758f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ALLEY \ + { 1.0000f, 0.3000f, 0.3162f, 0.7328f, 1.0000f, 1.4900f, 0.8600f, 1.0000f, 0.2500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.9954f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.9500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FOREST \ + { 1.0000f, 0.3000f, 0.3162f, 0.0224f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.0525f, 0.1620f, { 0.0000f, 0.0000f, 0.0000f }, 0.7682f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CITY \ + { 1.0000f, 0.5000f, 0.3162f, 0.3981f, 1.0000f, 1.4900f, 0.6700f, 1.0000f, 0.0730f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1427f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_MOUNTAINS \ + { 1.0000f, 0.2700f, 0.3162f, 0.0562f, 1.0000f, 1.4900f, 0.2100f, 1.0000f, 0.0407f, 0.3000f, { 0.0000f, 0.0000f, 0.0000f }, 0.1919f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_QUARRY \ + { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0000f, 0.0610f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.7000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PLAIN \ + { 1.0000f, 0.2100f, 0.3162f, 0.1000f, 1.0000f, 1.4900f, 0.5000f, 1.0000f, 0.0585f, 0.1790f, { 0.0000f, 0.0000f, 0.0000f }, 0.1089f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PARKINGLOT \ + { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 1.6500f, 1.5000f, 1.0000f, 0.2082f, 0.0080f, { 0.0000f, 0.0000f, 0.0000f }, 0.2652f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_SEWERPIPE \ + { 0.3071f, 0.8000f, 0.3162f, 0.3162f, 1.0000f, 2.8100f, 0.1400f, 1.0000f, 1.6387f, 0.0140f, { 0.0000f, 0.0000f, 0.0000f }, 3.2471f, 0.0210f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_UNDERWATER \ + { 0.3645f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 1.4900f, 0.1000f, 1.0000f, 0.5963f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 7.0795f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 1.1800f, 0.3480f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DRUGGED \ + { 0.4287f, 0.5000f, 0.3162f, 1.0000f, 1.0000f, 8.3900f, 1.3900f, 1.0000f, 0.8760f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 3.1081f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_DIZZY \ + { 0.3645f, 0.6000f, 0.3162f, 0.6310f, 1.0000f, 17.2300f, 0.5600f, 1.0000f, 0.1392f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4937f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.8100f, 0.3100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_PSYCHOTIC \ + { 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +/* Castle Presets */ + +#define EFX_REVERB_PRESET_CASTLE_SMALLROOM \ + { 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 1.2200f, 0.8300f, 0.3100f, 0.8913f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_SHORTPASSAGE \ + { 1.0000f, 0.8900f, 0.3162f, 0.3162f, 0.1000f, 2.3200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_MEDIUMROOM \ + { 1.0000f, 0.9300f, 0.3162f, 0.2818f, 0.1000f, 2.0400f, 0.8300f, 0.4600f, 0.6310f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1550f, 0.0300f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_LARGEROOM \ + { 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.1259f, 2.5300f, 0.8300f, 0.5000f, 0.4467f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1850f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_LONGPASSAGE \ + { 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 3.4200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_HALL \ + { 1.0000f, 0.8100f, 0.3162f, 0.2818f, 0.1778f, 3.1400f, 0.7900f, 0.6200f, 0.1778f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_CUPBOARD \ + { 1.0000f, 0.8900f, 0.3162f, 0.2818f, 0.1000f, 0.6700f, 0.8700f, 0.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 3.5481f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_COURTYARD \ + { 1.0000f, 0.4200f, 0.3162f, 0.4467f, 0.1995f, 2.1300f, 0.6100f, 0.2300f, 0.2239f, 0.1600f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3700f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_CASTLE_ALCOVE \ + { 1.0000f, 0.8900f, 0.3162f, 0.5012f, 0.1000f, 1.6400f, 0.8700f, 0.3100f, 1.0000f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +/* Factory Presets */ + +#define EFX_REVERB_PRESET_FACTORY_SMALLROOM \ + { 0.3645f, 0.8200f, 0.3162f, 0.7943f, 0.5012f, 1.7200f, 0.6500f, 1.3100f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.1190f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_SHORTPASSAGE \ + { 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 2.5300f, 0.6500f, 1.3100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_MEDIUMROOM \ + { 0.4287f, 0.8200f, 0.2512f, 0.7943f, 0.5012f, 2.7600f, 0.6500f, 1.3100f, 0.2818f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1740f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_LARGEROOM \ + { 0.4287f, 0.7500f, 0.2512f, 0.7079f, 0.6310f, 4.2400f, 0.5100f, 1.3100f, 0.1778f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2310f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_LONGPASSAGE \ + { 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 4.0600f, 0.6500f, 1.3100f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_HALL \ + { 0.4287f, 0.7500f, 0.3162f, 0.7079f, 0.6310f, 7.4300f, 0.5100f, 1.3100f, 0.0631f, 0.0730f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_CUPBOARD \ + { 0.3071f, 0.6300f, 0.2512f, 0.7943f, 0.5012f, 0.4900f, 0.6500f, 1.3100f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.1070f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_COURTYARD \ + { 0.3071f, 0.5700f, 0.3162f, 0.3162f, 0.6310f, 2.3200f, 0.2900f, 0.5600f, 0.2239f, 0.1400f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2900f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_ALCOVE \ + { 0.3645f, 0.5900f, 0.2512f, 0.7943f, 0.5012f, 3.1400f, 0.6500f, 1.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1140f, 0.1000f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +/* Ice Palace Presets */ + +#define EFX_REVERB_PRESET_ICEPALACE_SMALLROOM \ + { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 1.5100f, 1.5300f, 0.2700f, 0.8913f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1640f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_SHORTPASSAGE \ + { 1.0000f, 0.7500f, 0.3162f, 0.5623f, 0.2818f, 1.7900f, 1.4600f, 0.2800f, 0.5012f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_MEDIUMROOM \ + { 1.0000f, 0.8700f, 0.3162f, 0.5623f, 0.4467f, 2.2200f, 1.5300f, 0.3200f, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_LARGEROOM \ + { 1.0000f, 0.8100f, 0.3162f, 0.5623f, 0.4467f, 3.1400f, 1.5300f, 0.3200f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_LONGPASSAGE \ + { 1.0000f, 0.7700f, 0.3162f, 0.5623f, 0.3981f, 3.0100f, 1.4600f, 0.2800f, 0.7943f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.0400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_HALL \ + { 1.0000f, 0.7600f, 0.3162f, 0.4467f, 0.5623f, 5.4900f, 1.5300f, 0.3800f, 0.1122f, 0.0540f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0520f, { 0.0000f, 0.0000f, 0.0000f }, 0.2260f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_CUPBOARD \ + { 1.0000f, 0.8300f, 0.3162f, 0.5012f, 0.2239f, 0.7600f, 1.5300f, 0.2600f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1430f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_COURTYARD \ + { 1.0000f, 0.5900f, 0.3162f, 0.2818f, 0.3162f, 2.0400f, 1.2000f, 0.3800f, 0.3162f, 0.1730f, { 0.0000f, 0.0000f, 0.0000f }, 0.3162f, 0.0430f, { 0.0000f, 0.0000f, 0.0000f }, 0.2350f, 0.4800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_ALCOVE \ + { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 2.7600f, 1.4600f, 0.2800f, 1.1220f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1610f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +/* Space Station Presets */ + +#define EFX_REVERB_PRESET_SPACESTATION_SMALLROOM \ + { 0.2109f, 0.7000f, 0.3162f, 0.7079f, 0.8913f, 1.7200f, 0.8200f, 0.5500f, 0.7943f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 0.1880f, 0.2600f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_SHORTPASSAGE \ + { 0.2109f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 3.5700f, 0.5000f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1720f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_MEDIUMROOM \ + { 0.2109f, 0.7500f, 0.3162f, 0.6310f, 0.8913f, 3.0100f, 0.5000f, 0.5500f, 0.3981f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2090f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_LARGEROOM \ + { 0.3645f, 0.8100f, 0.3162f, 0.6310f, 0.8913f, 3.8900f, 0.3800f, 0.6100f, 0.3162f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2330f, 0.2800f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_LONGPASSAGE \ + { 0.4287f, 0.8200f, 0.3162f, 0.6310f, 0.8913f, 4.6200f, 0.6200f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_HALL \ + { 0.4287f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 7.1100f, 0.3800f, 0.6100f, 0.1778f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2500f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_CUPBOARD \ + { 0.1715f, 0.5600f, 0.3162f, 0.7079f, 0.8913f, 0.7900f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1810f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_ALCOVE \ + { 0.2109f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.1600f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1920f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +/* Wooden Galleon Presets */ + +#define EFX_REVERB_PRESET_WOODEN_SMALLROOM \ + { 1.0000f, 1.0000f, 0.3162f, 0.1122f, 0.3162f, 0.7900f, 0.3200f, 0.8700f, 1.0000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_SHORTPASSAGE \ + { 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.7500f, 0.5000f, 0.8700f, 0.8913f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_MEDIUMROOM \ + { 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.2818f, 1.4700f, 0.4200f, 0.8200f, 0.8913f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_LARGEROOM \ + { 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.2818f, 2.6500f, 0.3300f, 0.8200f, 0.8913f, 0.0660f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_LONGPASSAGE \ + { 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.3162f, 1.9900f, 0.4000f, 0.7900f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4467f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_HALL \ + { 1.0000f, 1.0000f, 0.3162f, 0.0794f, 0.2818f, 3.4500f, 0.3000f, 0.8200f, 0.8913f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_CUPBOARD \ + { 1.0000f, 1.0000f, 0.3162f, 0.1413f, 0.3162f, 0.5600f, 0.4600f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_COURTYARD \ + { 1.0000f, 0.6500f, 0.3162f, 0.0794f, 0.3162f, 1.7900f, 0.3500f, 0.7900f, 0.5623f, 0.1230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_ALCOVE \ + { 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.2200f, 0.6200f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +/* Sports Presets */ + +#define EFX_REVERB_PRESET_SPORT_EMPTYSTADIUM \ + { 1.0000f, 1.0000f, 0.3162f, 0.4467f, 0.7943f, 6.2600f, 0.5100f, 1.1000f, 0.0631f, 0.1830f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPORT_SQUASHCOURT \ + { 1.0000f, 0.7500f, 0.3162f, 0.3162f, 0.7943f, 2.2200f, 0.9100f, 1.1600f, 0.4467f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1260f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPORT_SMALLSWIMMINGPOOL \ + { 1.0000f, 0.7000f, 0.3162f, 0.7943f, 0.8913f, 2.7600f, 1.2500f, 1.1400f, 0.6310f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_SPORT_LARGESWIMMINGPOOL \ + { 1.0000f, 0.8200f, 0.3162f, 0.7943f, 1.0000f, 5.4900f, 1.3100f, 1.1400f, 0.4467f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2220f, 0.5500f, 1.1590f, 0.2100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_SPORT_GYMNASIUM \ + { 1.0000f, 0.8100f, 0.3162f, 0.4467f, 0.8913f, 3.1400f, 1.0600f, 1.3500f, 0.3981f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0450f, { 0.0000f, 0.0000f, 0.0000f }, 0.1460f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPORT_FULLSTADIUM \ + { 1.0000f, 1.0000f, 0.3162f, 0.0708f, 0.7943f, 5.2500f, 0.1700f, 0.8000f, 0.1000f, 0.1880f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPORT_STADIUMTANNOY \ + { 1.0000f, 0.7800f, 0.3162f, 0.5623f, 0.5012f, 2.5300f, 0.8800f, 0.6800f, 0.2818f, 0.2300f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +/* Prefab Presets */ + +#define EFX_REVERB_PRESET_PREFAB_WORKSHOP \ + { 0.4287f, 1.0000f, 0.3162f, 0.1413f, 0.3981f, 0.7600f, 1.0000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_PREFAB_SCHOOLROOM \ + { 0.4022f, 0.6900f, 0.3162f, 0.6310f, 0.5012f, 0.9800f, 0.4500f, 0.1800f, 1.4125f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PREFAB_PRACTISEROOM \ + { 0.4022f, 0.8700f, 0.3162f, 0.3981f, 0.5012f, 1.1200f, 0.5600f, 0.1800f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PREFAB_OUTHOUSE \ + { 1.0000f, 0.8200f, 0.3162f, 0.1122f, 0.1585f, 1.3800f, 0.3800f, 0.3500f, 0.8913f, 0.0240f, { 0.0000f, 0.0000f, -0.0000f }, 0.6310f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.1210f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_PREFAB_CARAVAN \ + { 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.1259f, 0.4300f, 1.5000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +/* Dome and Pipe Presets */ + +#define EFX_REVERB_PRESET_DOME_TOMB \ + { 1.0000f, 0.7900f, 0.3162f, 0.3548f, 0.2239f, 4.1800f, 0.2100f, 0.1000f, 0.3868f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 1.6788f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_PIPE_SMALL \ + { 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 5.0400f, 0.1000f, 0.1000f, 0.5012f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 2.5119f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DOME_SAINTPAULS \ + { 1.0000f, 0.8700f, 0.3162f, 0.3548f, 0.2239f, 10.4800f, 0.1900f, 0.1000f, 0.1778f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0420f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PIPE_LONGTHIN \ + { 0.2560f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 9.2100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_PIPE_LARGE \ + { 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 8.4500f, 0.1000f, 0.1000f, 0.3981f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PIPE_RESONANT \ + { 0.1373f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 6.8100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 } + +/* Outdoors Presets */ + +#define EFX_REVERB_PRESET_OUTDOORS_BACKYARD \ + { 1.0000f, 0.4500f, 0.3162f, 0.2512f, 0.5012f, 1.1200f, 0.3400f, 0.4600f, 0.4467f, 0.0690f, { 0.0000f, 0.0000f, -0.0000f }, 0.7079f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_OUTDOORS_ROLLINGPLAINS \ + { 1.0000f, 0.0000f, 0.3162f, 0.0112f, 0.6310f, 2.1300f, 0.2100f, 0.4600f, 0.1778f, 0.3000f, { 0.0000f, 0.0000f, -0.0000f }, 0.4467f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_OUTDOORS_DEEPCANYON \ + { 1.0000f, 0.7400f, 0.3162f, 0.1778f, 0.6310f, 3.8900f, 0.2100f, 0.4600f, 0.3162f, 0.2230f, { 0.0000f, 0.0000f, -0.0000f }, 0.3548f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_OUTDOORS_CREEK \ + { 1.0000f, 0.3500f, 0.3162f, 0.1778f, 0.5012f, 2.1300f, 0.2100f, 0.4600f, 0.3981f, 0.1150f, { 0.0000f, 0.0000f, -0.0000f }, 0.1995f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_OUTDOORS_VALLEY \ + { 1.0000f, 0.2800f, 0.3162f, 0.0282f, 0.1585f, 2.8800f, 0.2600f, 0.3500f, 0.1413f, 0.2630f, { 0.0000f, 0.0000f, -0.0000f }, 0.3981f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } + +/* Mood Presets */ + +#define EFX_REVERB_PRESET_MOOD_HEAVEN \ + { 1.0000f, 0.9400f, 0.3162f, 0.7943f, 0.4467f, 5.0400f, 1.1200f, 0.5600f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0800f, 2.7420f, 0.0500f, 0.9977f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_MOOD_HELL \ + { 1.0000f, 0.5700f, 0.3162f, 0.3548f, 0.4467f, 3.5700f, 0.4900f, 2.0000f, 0.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1100f, 0.0400f, 2.1090f, 0.5200f, 0.9943f, 5000.0000f, 139.5000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_MOOD_MEMORY \ + { 1.0000f, 0.8500f, 0.3162f, 0.6310f, 0.3548f, 4.0600f, 0.8200f, 0.5600f, 0.0398f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.4740f, 0.4500f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +/* Driving Presets */ + +#define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \ + { 1.0000f, 0.0000f, 3.1623f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DRIVING_PITGARAGE \ + { 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_DRIVING_INCAR_RACER \ + { 0.0832f, 0.8000f, 0.3162f, 1.0000f, 0.7943f, 0.1700f, 2.0000f, 0.4100f, 1.7783f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DRIVING_INCAR_SPORTS \ + { 0.0832f, 0.8000f, 0.3162f, 0.6310f, 1.0000f, 0.1700f, 0.7500f, 0.4100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DRIVING_INCAR_LUXURY \ + { 0.2560f, 1.0000f, 0.3162f, 0.1000f, 0.5012f, 0.1300f, 0.4100f, 0.4600f, 0.7943f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DRIVING_FULLGRANDSTAND \ + { 1.0000f, 1.0000f, 0.3162f, 0.2818f, 0.6310f, 3.0100f, 1.3700f, 1.2800f, 0.3548f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.1778f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_DRIVING_EMPTYGRANDSTAND \ + { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 0.7943f, 4.6200f, 1.7500f, 1.4000f, 0.2082f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_DRIVING_TUNNEL \ + { 1.0000f, 0.8100f, 0.3162f, 0.3981f, 0.8913f, 3.4200f, 0.9400f, 1.3100f, 0.7079f, 0.0510f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.0500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 155.3000f, 0.0000f, 0x1 } + +/* City Presets */ + +#define EFX_REVERB_PRESET_CITY_STREETS \ + { 1.0000f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.7900f, 1.1200f, 0.9100f, 0.2818f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 0.1995f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CITY_SUBWAY \ + { 1.0000f, 0.7400f, 0.3162f, 0.7079f, 0.8913f, 3.0100f, 1.2300f, 0.9100f, 0.7079f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CITY_MUSEUM \ + { 1.0000f, 0.8200f, 0.3162f, 0.1778f, 0.1778f, 3.2800f, 1.4000f, 0.5700f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_CITY_LIBRARY \ + { 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.0891f, 2.7600f, 0.8900f, 0.4100f, 0.3548f, 0.0290f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_CITY_UNDERPASS \ + { 1.0000f, 0.8200f, 0.3162f, 0.4467f, 0.8913f, 3.5700f, 1.1200f, 0.9100f, 0.3981f, 0.0590f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1400f, 0.2500f, 0.0000f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CITY_ABANDONED \ + { 1.0000f, 0.6900f, 0.3162f, 0.7943f, 0.8913f, 3.2800f, 1.1700f, 0.9100f, 0.4467f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9966f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +/* Misc. Presets */ + +#define EFX_REVERB_PRESET_DUSTYROOM \ + { 0.3645f, 0.5600f, 0.3162f, 0.7943f, 0.7079f, 1.7900f, 0.3800f, 0.2100f, 0.5012f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0060f, { 0.0000f, 0.0000f, 0.0000f }, 0.2020f, 0.0500f, 0.2500f, 0.0000f, 0.9886f, 13046.0000f, 163.3000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CHAPEL \ + { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 1.0000f, 4.6200f, 0.6400f, 1.2300f, 0.4467f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.1100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SMALLWATERROOM \ + { 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#endif /* EFX_PRESETS_H */ diff --git a/builddir/openal-soft-1.15.1/include/AL/efx.h b/builddir/openal-soft-1.15.1/include/AL/efx.h new file mode 100644 index 0000000..5776698 --- /dev/null +++ b/builddir/openal-soft-1.15.1/include/AL/efx.h @@ -0,0 +1,761 @@ +#ifndef AL_EFX_H +#define AL_EFX_H + + +#include "alc.h" +#include "al.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ALC_EXT_EFX_NAME "ALC_EXT_EFX" + +#define ALC_EFX_MAJOR_VERSION 0x20001 +#define ALC_EFX_MINOR_VERSION 0x20002 +#define ALC_MAX_AUXILIARY_SENDS 0x20003 + + +/* Listener properties. */ +#define AL_METERS_PER_UNIT 0x20004 + +/* Source properties. */ +#define AL_DIRECT_FILTER 0x20005 +#define AL_AUXILIARY_SEND_FILTER 0x20006 +#define AL_AIR_ABSORPTION_FACTOR 0x20007 +#define AL_ROOM_ROLLOFF_FACTOR 0x20008 +#define AL_CONE_OUTER_GAINHF 0x20009 +#define AL_DIRECT_FILTER_GAINHF_AUTO 0x2000A +#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO 0x2000B +#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO 0x2000C + + +/* Effect properties. */ + +/* Reverb effect parameters */ +#define AL_REVERB_DENSITY 0x0001 +#define AL_REVERB_DIFFUSION 0x0002 +#define AL_REVERB_GAIN 0x0003 +#define AL_REVERB_GAINHF 0x0004 +#define AL_REVERB_DECAY_TIME 0x0005 +#define AL_REVERB_DECAY_HFRATIO 0x0006 +#define AL_REVERB_REFLECTIONS_GAIN 0x0007 +#define AL_REVERB_REFLECTIONS_DELAY 0x0008 +#define AL_REVERB_LATE_REVERB_GAIN 0x0009 +#define AL_REVERB_LATE_REVERB_DELAY 0x000A +#define AL_REVERB_AIR_ABSORPTION_GAINHF 0x000B +#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C +#define AL_REVERB_DECAY_HFLIMIT 0x000D + +/* EAX Reverb effect parameters */ +#define AL_EAXREVERB_DENSITY 0x0001 +#define AL_EAXREVERB_DIFFUSION 0x0002 +#define AL_EAXREVERB_GAIN 0x0003 +#define AL_EAXREVERB_GAINHF 0x0004 +#define AL_EAXREVERB_GAINLF 0x0005 +#define AL_EAXREVERB_DECAY_TIME 0x0006 +#define AL_EAXREVERB_DECAY_HFRATIO 0x0007 +#define AL_EAXREVERB_DECAY_LFRATIO 0x0008 +#define AL_EAXREVERB_REFLECTIONS_GAIN 0x0009 +#define AL_EAXREVERB_REFLECTIONS_DELAY 0x000A +#define AL_EAXREVERB_REFLECTIONS_PAN 0x000B +#define AL_EAXREVERB_LATE_REVERB_GAIN 0x000C +#define AL_EAXREVERB_LATE_REVERB_DELAY 0x000D +#define AL_EAXREVERB_LATE_REVERB_PAN 0x000E +#define AL_EAXREVERB_ECHO_TIME 0x000F +#define AL_EAXREVERB_ECHO_DEPTH 0x0010 +#define AL_EAXREVERB_MODULATION_TIME 0x0011 +#define AL_EAXREVERB_MODULATION_DEPTH 0x0012 +#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF 0x0013 +#define AL_EAXREVERB_HFREFERENCE 0x0014 +#define AL_EAXREVERB_LFREFERENCE 0x0015 +#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR 0x0016 +#define AL_EAXREVERB_DECAY_HFLIMIT 0x0017 + +/* Chorus effect parameters */ +#define AL_CHORUS_WAVEFORM 0x0001 +#define AL_CHORUS_PHASE 0x0002 +#define AL_CHORUS_RATE 0x0003 +#define AL_CHORUS_DEPTH 0x0004 +#define AL_CHORUS_FEEDBACK 0x0005 +#define AL_CHORUS_DELAY 0x0006 + +/* Distortion effect parameters */ +#define AL_DISTORTION_EDGE 0x0001 +#define AL_DISTORTION_GAIN 0x0002 +#define AL_DISTORTION_LOWPASS_CUTOFF 0x0003 +#define AL_DISTORTION_EQCENTER 0x0004 +#define AL_DISTORTION_EQBANDWIDTH 0x0005 + +/* Echo effect parameters */ +#define AL_ECHO_DELAY 0x0001 +#define AL_ECHO_LRDELAY 0x0002 +#define AL_ECHO_DAMPING 0x0003 +#define AL_ECHO_FEEDBACK 0x0004 +#define AL_ECHO_SPREAD 0x0005 + +/* Flanger effect parameters */ +#define AL_FLANGER_WAVEFORM 0x0001 +#define AL_FLANGER_PHASE 0x0002 +#define AL_FLANGER_RATE 0x0003 +#define AL_FLANGER_DEPTH 0x0004 +#define AL_FLANGER_FEEDBACK 0x0005 +#define AL_FLANGER_DELAY 0x0006 + +/* Frequency shifter effect parameters */ +#define AL_FREQUENCY_SHIFTER_FREQUENCY 0x0001 +#define AL_FREQUENCY_SHIFTER_LEFT_DIRECTION 0x0002 +#define AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION 0x0003 + +/* Vocal morpher effect parameters */ +#define AL_VOCAL_MORPHER_PHONEMEA 0x0001 +#define AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING 0x0002 +#define AL_VOCAL_MORPHER_PHONEMEB 0x0003 +#define AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING 0x0004 +#define AL_VOCAL_MORPHER_WAVEFORM 0x0005 +#define AL_VOCAL_MORPHER_RATE 0x0006 + +/* Pitchshifter effect parameters */ +#define AL_PITCH_SHIFTER_COARSE_TUNE 0x0001 +#define AL_PITCH_SHIFTER_FINE_TUNE 0x0002 + +/* Ringmodulator effect parameters */ +#define AL_RING_MODULATOR_FREQUENCY 0x0001 +#define AL_RING_MODULATOR_HIGHPASS_CUTOFF 0x0002 +#define AL_RING_MODULATOR_WAVEFORM 0x0003 + +/* Autowah effect parameters */ +#define AL_AUTOWAH_ATTACK_TIME 0x0001 +#define AL_AUTOWAH_RELEASE_TIME 0x0002 +#define AL_AUTOWAH_RESONANCE 0x0003 +#define AL_AUTOWAH_PEAK_GAIN 0x0004 + +/* Compressor effect parameters */ +#define AL_COMPRESSOR_ONOFF 0x0001 + +/* Equalizer effect parameters */ +#define AL_EQUALIZER_LOW_GAIN 0x0001 +#define AL_EQUALIZER_LOW_CUTOFF 0x0002 +#define AL_EQUALIZER_MID1_GAIN 0x0003 +#define AL_EQUALIZER_MID1_CENTER 0x0004 +#define AL_EQUALIZER_MID1_WIDTH 0x0005 +#define AL_EQUALIZER_MID2_GAIN 0x0006 +#define AL_EQUALIZER_MID2_CENTER 0x0007 +#define AL_EQUALIZER_MID2_WIDTH 0x0008 +#define AL_EQUALIZER_HIGH_GAIN 0x0009 +#define AL_EQUALIZER_HIGH_CUTOFF 0x000A + +/* Effect type */ +#define AL_EFFECT_FIRST_PARAMETER 0x0000 +#define AL_EFFECT_LAST_PARAMETER 0x8000 +#define AL_EFFECT_TYPE 0x8001 + +/* Effect types, used with the AL_EFFECT_TYPE property */ +#define AL_EFFECT_NULL 0x0000 +#define AL_EFFECT_REVERB 0x0001 +#define AL_EFFECT_CHORUS 0x0002 +#define AL_EFFECT_DISTORTION 0x0003 +#define AL_EFFECT_ECHO 0x0004 +#define AL_EFFECT_FLANGER 0x0005 +#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006 +#define AL_EFFECT_VOCAL_MORPHER 0x0007 +#define AL_EFFECT_PITCH_SHIFTER 0x0008 +#define AL_EFFECT_RING_MODULATOR 0x0009 +#define AL_EFFECT_AUTOWAH 0x000A +#define AL_EFFECT_COMPRESSOR 0x000B +#define AL_EFFECT_EQUALIZER 0x000C +#define AL_EFFECT_EAXREVERB 0x8000 + +/* Auxiliary Effect Slot properties. */ +#define AL_EFFECTSLOT_EFFECT 0x0001 +#define AL_EFFECTSLOT_GAIN 0x0002 +#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003 + +/* NULL Auxiliary Slot ID to disable a source send. */ +#define AL_EFFECTSLOT_NULL 0x0000 + + +/* Filter properties. */ + +/* Lowpass filter parameters */ +#define AL_LOWPASS_GAIN 0x0001 +#define AL_LOWPASS_GAINHF 0x0002 + +/* Highpass filter parameters */ +#define AL_HIGHPASS_GAIN 0x0001 +#define AL_HIGHPASS_GAINLF 0x0002 + +/* Bandpass filter parameters */ +#define AL_BANDPASS_GAIN 0x0001 +#define AL_BANDPASS_GAINLF 0x0002 +#define AL_BANDPASS_GAINHF 0x0003 + +/* Filter type */ +#define AL_FILTER_FIRST_PARAMETER 0x0000 +#define AL_FILTER_LAST_PARAMETER 0x8000 +#define AL_FILTER_TYPE 0x8001 + +/* Filter types, used with the AL_FILTER_TYPE property */ +#define AL_FILTER_NULL 0x0000 +#define AL_FILTER_LOWPASS 0x0001 +#define AL_FILTER_HIGHPASS 0x0002 +#define AL_FILTER_BANDPASS 0x0003 + + +/* Effect object function types. */ +typedef void (AL_APIENTRY *LPALGENEFFECTS)(ALsizei, ALuint*); +typedef void (AL_APIENTRY *LPALDELETEEFFECTS)(ALsizei, const ALuint*); +typedef ALboolean (AL_APIENTRY *LPALISEFFECT)(ALuint); +typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint); +typedef void (AL_APIENTRY *LPALEFFECTIV)(ALuint, ALenum, const ALint*); +typedef void (AL_APIENTRY *LPALEFFECTF)(ALuint, ALenum, ALfloat); +typedef void (AL_APIENTRY *LPALEFFECTFV)(ALuint, ALenum, const ALfloat*); +typedef void (AL_APIENTRY *LPALGETEFFECTI)(ALuint, ALenum, ALint*); +typedef void (AL_APIENTRY *LPALGETEFFECTIV)(ALuint, ALenum, ALint*); +typedef void (AL_APIENTRY *LPALGETEFFECTF)(ALuint, ALenum, ALfloat*); +typedef void (AL_APIENTRY *LPALGETEFFECTFV)(ALuint, ALenum, ALfloat*); + +/* Filter object function types. */ +typedef void (AL_APIENTRY *LPALGENFILTERS)(ALsizei, ALuint*); +typedef void (AL_APIENTRY *LPALDELETEFILTERS)(ALsizei, const ALuint*); +typedef ALboolean (AL_APIENTRY *LPALISFILTER)(ALuint); +typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint); +typedef void (AL_APIENTRY *LPALFILTERIV)(ALuint, ALenum, const ALint*); +typedef void (AL_APIENTRY *LPALFILTERF)(ALuint, ALenum, ALfloat); +typedef void (AL_APIENTRY *LPALFILTERFV)(ALuint, ALenum, const ALfloat*); +typedef void (AL_APIENTRY *LPALGETFILTERI)(ALuint, ALenum, ALint*); +typedef void (AL_APIENTRY *LPALGETFILTERIV)(ALuint, ALenum, ALint*); +typedef void (AL_APIENTRY *LPALGETFILTERF)(ALuint, ALenum, ALfloat*); +typedef void (AL_APIENTRY *LPALGETFILTERFV)(ALuint, ALenum, ALfloat*); + +/* Auxiliary Effect Slot object function types. */ +typedef void (AL_APIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei, ALuint*); +typedef void (AL_APIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei, const ALuint*); +typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint); +typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint); +typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, const ALint*); +typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat); +typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, const ALfloat*); +typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint*); +typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*); +typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat*); +typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*); + +#ifdef AL_ALEXT_PROTOTYPES +AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects); +AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects); +AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect); +AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue); +AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues); +AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue); +AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues); +AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue); +AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues); +AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue); +AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues); + +AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters); +AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters); +AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter); +AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue); +AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues); +AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue); +AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues); +AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue); +AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues); +AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue); +AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues); + +AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots); +AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots); +AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot); +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue); +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues); +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue); +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues); +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue); +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues); +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue); +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues); +#endif + +/* Filter ranges and defaults. */ + +/* Lowpass filter */ +#define AL_LOWPASS_MIN_GAIN (0.0f) +#define AL_LOWPASS_MAX_GAIN (1.0f) +#define AL_LOWPASS_DEFAULT_GAIN (1.0f) + +#define AL_LOWPASS_MIN_GAINHF (0.0f) +#define AL_LOWPASS_MAX_GAINHF (1.0f) +#define AL_LOWPASS_DEFAULT_GAINHF (1.0f) + +/* Highpass filter */ +#define AL_HIGHPASS_MIN_GAIN (0.0f) +#define AL_HIGHPASS_MAX_GAIN (1.0f) +#define AL_HIGHPASS_DEFAULT_GAIN (1.0f) + +#define AL_HIGHPASS_MIN_GAINLF (0.0f) +#define AL_HIGHPASS_MAX_GAINLF (1.0f) +#define AL_HIGHPASS_DEFAULT_GAINLF (1.0f) + +/* Bandpass filter */ +#define AL_BANDPASS_MIN_GAIN (0.0f) +#define AL_BANDPASS_MAX_GAIN (1.0f) +#define AL_BANDPASS_DEFAULT_GAIN (1.0f) + +#define AL_BANDPASS_MIN_GAINHF (0.0f) +#define AL_BANDPASS_MAX_GAINHF (1.0f) +#define AL_BANDPASS_DEFAULT_GAINHF (1.0f) + +#define AL_BANDPASS_MIN_GAINLF (0.0f) +#define AL_BANDPASS_MAX_GAINLF (1.0f) +#define AL_BANDPASS_DEFAULT_GAINLF (1.0f) + + +/* Effect parameter ranges and defaults. */ + +/* Standard reverb effect */ +#define AL_REVERB_MIN_DENSITY (0.0f) +#define AL_REVERB_MAX_DENSITY (1.0f) +#define AL_REVERB_DEFAULT_DENSITY (1.0f) + +#define AL_REVERB_MIN_DIFFUSION (0.0f) +#define AL_REVERB_MAX_DIFFUSION (1.0f) +#define AL_REVERB_DEFAULT_DIFFUSION (1.0f) + +#define AL_REVERB_MIN_GAIN (0.0f) +#define AL_REVERB_MAX_GAIN (1.0f) +#define AL_REVERB_DEFAULT_GAIN (0.32f) + +#define AL_REVERB_MIN_GAINHF (0.0f) +#define AL_REVERB_MAX_GAINHF (1.0f) +#define AL_REVERB_DEFAULT_GAINHF (0.89f) + +#define AL_REVERB_MIN_DECAY_TIME (0.1f) +#define AL_REVERB_MAX_DECAY_TIME (20.0f) +#define AL_REVERB_DEFAULT_DECAY_TIME (1.49f) + +#define AL_REVERB_MIN_DECAY_HFRATIO (0.1f) +#define AL_REVERB_MAX_DECAY_HFRATIO (2.0f) +#define AL_REVERB_DEFAULT_DECAY_HFRATIO (0.83f) + +#define AL_REVERB_MIN_REFLECTIONS_GAIN (0.0f) +#define AL_REVERB_MAX_REFLECTIONS_GAIN (3.16f) +#define AL_REVERB_DEFAULT_REFLECTIONS_GAIN (0.05f) + +#define AL_REVERB_MIN_REFLECTIONS_DELAY (0.0f) +#define AL_REVERB_MAX_REFLECTIONS_DELAY (0.3f) +#define AL_REVERB_DEFAULT_REFLECTIONS_DELAY (0.007f) + +#define AL_REVERB_MIN_LATE_REVERB_GAIN (0.0f) +#define AL_REVERB_MAX_LATE_REVERB_GAIN (10.0f) +#define AL_REVERB_DEFAULT_LATE_REVERB_GAIN (1.26f) + +#define AL_REVERB_MIN_LATE_REVERB_DELAY (0.0f) +#define AL_REVERB_MAX_LATE_REVERB_DELAY (0.1f) +#define AL_REVERB_DEFAULT_LATE_REVERB_DELAY (0.011f) + +#define AL_REVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f) +#define AL_REVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f) +#define AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f) + +#define AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f) +#define AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f) +#define AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f) + +#define AL_REVERB_MIN_DECAY_HFLIMIT AL_FALSE +#define AL_REVERB_MAX_DECAY_HFLIMIT AL_TRUE +#define AL_REVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE + +/* EAX reverb effect */ +#define AL_EAXREVERB_MIN_DENSITY (0.0f) +#define AL_EAXREVERB_MAX_DENSITY (1.0f) +#define AL_EAXREVERB_DEFAULT_DENSITY (1.0f) + +#define AL_EAXREVERB_MIN_DIFFUSION (0.0f) +#define AL_EAXREVERB_MAX_DIFFUSION (1.0f) +#define AL_EAXREVERB_DEFAULT_DIFFUSION (1.0f) + +#define AL_EAXREVERB_MIN_GAIN (0.0f) +#define AL_EAXREVERB_MAX_GAIN (1.0f) +#define AL_EAXREVERB_DEFAULT_GAIN (0.32f) + +#define AL_EAXREVERB_MIN_GAINHF (0.0f) +#define AL_EAXREVERB_MAX_GAINHF (1.0f) +#define AL_EAXREVERB_DEFAULT_GAINHF (0.89f) + +#define AL_EAXREVERB_MIN_GAINLF (0.0f) +#define AL_EAXREVERB_MAX_GAINLF (1.0f) +#define AL_EAXREVERB_DEFAULT_GAINLF (1.0f) + +#define AL_EAXREVERB_MIN_DECAY_TIME (0.1f) +#define AL_EAXREVERB_MAX_DECAY_TIME (20.0f) +#define AL_EAXREVERB_DEFAULT_DECAY_TIME (1.49f) + +#define AL_EAXREVERB_MIN_DECAY_HFRATIO (0.1f) +#define AL_EAXREVERB_MAX_DECAY_HFRATIO (2.0f) +#define AL_EAXREVERB_DEFAULT_DECAY_HFRATIO (0.83f) + +#define AL_EAXREVERB_MIN_DECAY_LFRATIO (0.1f) +#define AL_EAXREVERB_MAX_DECAY_LFRATIO (2.0f) +#define AL_EAXREVERB_DEFAULT_DECAY_LFRATIO (1.0f) + +#define AL_EAXREVERB_MIN_REFLECTIONS_GAIN (0.0f) +#define AL_EAXREVERB_MAX_REFLECTIONS_GAIN (3.16f) +#define AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN (0.05f) + +#define AL_EAXREVERB_MIN_REFLECTIONS_DELAY (0.0f) +#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY (0.3f) +#define AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY (0.007f) + +#define AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ (0.0f) + +#define AL_EAXREVERB_MIN_LATE_REVERB_GAIN (0.0f) +#define AL_EAXREVERB_MAX_LATE_REVERB_GAIN (10.0f) +#define AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN (1.26f) + +#define AL_EAXREVERB_MIN_LATE_REVERB_DELAY (0.0f) +#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY (0.1f) +#define AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY (0.011f) + +#define AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ (0.0f) + +#define AL_EAXREVERB_MIN_ECHO_TIME (0.075f) +#define AL_EAXREVERB_MAX_ECHO_TIME (0.25f) +#define AL_EAXREVERB_DEFAULT_ECHO_TIME (0.25f) + +#define AL_EAXREVERB_MIN_ECHO_DEPTH (0.0f) +#define AL_EAXREVERB_MAX_ECHO_DEPTH (1.0f) +#define AL_EAXREVERB_DEFAULT_ECHO_DEPTH (0.0f) + +#define AL_EAXREVERB_MIN_MODULATION_TIME (0.04f) +#define AL_EAXREVERB_MAX_MODULATION_TIME (4.0f) +#define AL_EAXREVERB_DEFAULT_MODULATION_TIME (0.25f) + +#define AL_EAXREVERB_MIN_MODULATION_DEPTH (0.0f) +#define AL_EAXREVERB_MAX_MODULATION_DEPTH (1.0f) +#define AL_EAXREVERB_DEFAULT_MODULATION_DEPTH (0.0f) + +#define AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f) +#define AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f) +#define AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f) + +#define AL_EAXREVERB_MIN_HFREFERENCE (1000.0f) +#define AL_EAXREVERB_MAX_HFREFERENCE (20000.0f) +#define AL_EAXREVERB_DEFAULT_HFREFERENCE (5000.0f) + +#define AL_EAXREVERB_MIN_LFREFERENCE (20.0f) +#define AL_EAXREVERB_MAX_LFREFERENCE (1000.0f) +#define AL_EAXREVERB_DEFAULT_LFREFERENCE (250.0f) + +#define AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f) +#define AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f) +#define AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f) + +#define AL_EAXREVERB_MIN_DECAY_HFLIMIT AL_FALSE +#define AL_EAXREVERB_MAX_DECAY_HFLIMIT AL_TRUE +#define AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE + +/* Chorus effect */ +#define AL_CHORUS_WAVEFORM_SINUSOID (0) +#define AL_CHORUS_WAVEFORM_TRIANGLE (1) + +#define AL_CHORUS_MIN_WAVEFORM (0) +#define AL_CHORUS_MAX_WAVEFORM (1) +#define AL_CHORUS_DEFAULT_WAVEFORM (1) + +#define AL_CHORUS_MIN_PHASE (-180) +#define AL_CHORUS_MAX_PHASE (180) +#define AL_CHORUS_DEFAULT_PHASE (90) + +#define AL_CHORUS_MIN_RATE (0.0f) +#define AL_CHORUS_MAX_RATE (10.0f) +#define AL_CHORUS_DEFAULT_RATE (1.1f) + +#define AL_CHORUS_MIN_DEPTH (0.0f) +#define AL_CHORUS_MAX_DEPTH (1.0f) +#define AL_CHORUS_DEFAULT_DEPTH (0.1f) + +#define AL_CHORUS_MIN_FEEDBACK (-1.0f) +#define AL_CHORUS_MAX_FEEDBACK (1.0f) +#define AL_CHORUS_DEFAULT_FEEDBACK (0.25f) + +#define AL_CHORUS_MIN_DELAY (0.0f) +#define AL_CHORUS_MAX_DELAY (0.016f) +#define AL_CHORUS_DEFAULT_DELAY (0.016f) + +/* Distortion effect */ +#define AL_DISTORTION_MIN_EDGE (0.0f) +#define AL_DISTORTION_MAX_EDGE (1.0f) +#define AL_DISTORTION_DEFAULT_EDGE (0.2f) + +#define AL_DISTORTION_MIN_GAIN (0.01f) +#define AL_DISTORTION_MAX_GAIN (1.0f) +#define AL_DISTORTION_DEFAULT_GAIN (0.05f) + +#define AL_DISTORTION_MIN_LOWPASS_CUTOFF (80.0f) +#define AL_DISTORTION_MAX_LOWPASS_CUTOFF (24000.0f) +#define AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF (8000.0f) + +#define AL_DISTORTION_MIN_EQCENTER (80.0f) +#define AL_DISTORTION_MAX_EQCENTER (24000.0f) +#define AL_DISTORTION_DEFAULT_EQCENTER (3600.0f) + +#define AL_DISTORTION_MIN_EQBANDWIDTH (80.0f) +#define AL_DISTORTION_MAX_EQBANDWIDTH (24000.0f) +#define AL_DISTORTION_DEFAULT_EQBANDWIDTH (3600.0f) + +/* Echo effect */ +#define AL_ECHO_MIN_DELAY (0.0f) +#define AL_ECHO_MAX_DELAY (0.207f) +#define AL_ECHO_DEFAULT_DELAY (0.1f) + +#define AL_ECHO_MIN_LRDELAY (0.0f) +#define AL_ECHO_MAX_LRDELAY (0.404f) +#define AL_ECHO_DEFAULT_LRDELAY (0.1f) + +#define AL_ECHO_MIN_DAMPING (0.0f) +#define AL_ECHO_MAX_DAMPING (0.99f) +#define AL_ECHO_DEFAULT_DAMPING (0.5f) + +#define AL_ECHO_MIN_FEEDBACK (0.0f) +#define AL_ECHO_MAX_FEEDBACK (1.0f) +#define AL_ECHO_DEFAULT_FEEDBACK (0.5f) + +#define AL_ECHO_MIN_SPREAD (-1.0f) +#define AL_ECHO_MAX_SPREAD (1.0f) +#define AL_ECHO_DEFAULT_SPREAD (-1.0f) + +/* Flanger effect */ +#define AL_FLANGER_WAVEFORM_SINUSOID (0) +#define AL_FLANGER_WAVEFORM_TRIANGLE (1) + +#define AL_FLANGER_MIN_WAVEFORM (0) +#define AL_FLANGER_MAX_WAVEFORM (1) +#define AL_FLANGER_DEFAULT_WAVEFORM (1) + +#define AL_FLANGER_MIN_PHASE (-180) +#define AL_FLANGER_MAX_PHASE (180) +#define AL_FLANGER_DEFAULT_PHASE (0) + +#define AL_FLANGER_MIN_RATE (0.0f) +#define AL_FLANGER_MAX_RATE (10.0f) +#define AL_FLANGER_DEFAULT_RATE (0.27f) + +#define AL_FLANGER_MIN_DEPTH (0.0f) +#define AL_FLANGER_MAX_DEPTH (1.0f) +#define AL_FLANGER_DEFAULT_DEPTH (1.0f) + +#define AL_FLANGER_MIN_FEEDBACK (-1.0f) +#define AL_FLANGER_MAX_FEEDBACK (1.0f) +#define AL_FLANGER_DEFAULT_FEEDBACK (-0.5f) + +#define AL_FLANGER_MIN_DELAY (0.0f) +#define AL_FLANGER_MAX_DELAY (0.004f) +#define AL_FLANGER_DEFAULT_DELAY (0.002f) + +/* Frequency shifter effect */ +#define AL_FREQUENCY_SHIFTER_MIN_FREQUENCY (0.0f) +#define AL_FREQUENCY_SHIFTER_MAX_FREQUENCY (24000.0f) +#define AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY (0.0f) + +#define AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION (0) +#define AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION (2) +#define AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION (0) + +#define AL_FREQUENCY_SHIFTER_DIRECTION_DOWN (0) +#define AL_FREQUENCY_SHIFTER_DIRECTION_UP (1) +#define AL_FREQUENCY_SHIFTER_DIRECTION_OFF (2) + +#define AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION (0) +#define AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION (2) +#define AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION (0) + +/* Vocal morpher effect */ +#define AL_VOCAL_MORPHER_MIN_PHONEMEA (0) +#define AL_VOCAL_MORPHER_MAX_PHONEMEA (29) +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA (0) + +#define AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING (-24) +#define AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING (24) +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING (0) + +#define AL_VOCAL_MORPHER_MIN_PHONEMEB (0) +#define AL_VOCAL_MORPHER_MAX_PHONEMEB (29) +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB (10) + +#define AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING (-24) +#define AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING (24) +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING (0) + +#define AL_VOCAL_MORPHER_PHONEME_A (0) +#define AL_VOCAL_MORPHER_PHONEME_E (1) +#define AL_VOCAL_MORPHER_PHONEME_I (2) +#define AL_VOCAL_MORPHER_PHONEME_O (3) +#define AL_VOCAL_MORPHER_PHONEME_U (4) +#define AL_VOCAL_MORPHER_PHONEME_AA (5) +#define AL_VOCAL_MORPHER_PHONEME_AE (6) +#define AL_VOCAL_MORPHER_PHONEME_AH (7) +#define AL_VOCAL_MORPHER_PHONEME_AO (8) +#define AL_VOCAL_MORPHER_PHONEME_EH (9) +#define AL_VOCAL_MORPHER_PHONEME_ER (10) +#define AL_VOCAL_MORPHER_PHONEME_IH (11) +#define AL_VOCAL_MORPHER_PHONEME_IY (12) +#define AL_VOCAL_MORPHER_PHONEME_UH (13) +#define AL_VOCAL_MORPHER_PHONEME_UW (14) +#define AL_VOCAL_MORPHER_PHONEME_B (15) +#define AL_VOCAL_MORPHER_PHONEME_D (16) +#define AL_VOCAL_MORPHER_PHONEME_F (17) +#define AL_VOCAL_MORPHER_PHONEME_G (18) +#define AL_VOCAL_MORPHER_PHONEME_J (19) +#define AL_VOCAL_MORPHER_PHONEME_K (20) +#define AL_VOCAL_MORPHER_PHONEME_L (21) +#define AL_VOCAL_MORPHER_PHONEME_M (22) +#define AL_VOCAL_MORPHER_PHONEME_N (23) +#define AL_VOCAL_MORPHER_PHONEME_P (24) +#define AL_VOCAL_MORPHER_PHONEME_R (25) +#define AL_VOCAL_MORPHER_PHONEME_S (26) +#define AL_VOCAL_MORPHER_PHONEME_T (27) +#define AL_VOCAL_MORPHER_PHONEME_V (28) +#define AL_VOCAL_MORPHER_PHONEME_Z (29) + +#define AL_VOCAL_MORPHER_WAVEFORM_SINUSOID (0) +#define AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE (1) +#define AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH (2) + +#define AL_VOCAL_MORPHER_MIN_WAVEFORM (0) +#define AL_VOCAL_MORPHER_MAX_WAVEFORM (2) +#define AL_VOCAL_MORPHER_DEFAULT_WAVEFORM (0) + +#define AL_VOCAL_MORPHER_MIN_RATE (0.0f) +#define AL_VOCAL_MORPHER_MAX_RATE (10.0f) +#define AL_VOCAL_MORPHER_DEFAULT_RATE (1.41f) + +/* Pitch shifter effect */ +#define AL_PITCH_SHIFTER_MIN_COARSE_TUNE (-12) +#define AL_PITCH_SHIFTER_MAX_COARSE_TUNE (12) +#define AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE (12) + +#define AL_PITCH_SHIFTER_MIN_FINE_TUNE (-50) +#define AL_PITCH_SHIFTER_MAX_FINE_TUNE (50) +#define AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE (0) + +/* Ring modulator effect */ +#define AL_RING_MODULATOR_MIN_FREQUENCY (0.0f) +#define AL_RING_MODULATOR_MAX_FREQUENCY (8000.0f) +#define AL_RING_MODULATOR_DEFAULT_FREQUENCY (440.0f) + +#define AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF (0.0f) +#define AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF (24000.0f) +#define AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF (800.0f) + +#define AL_RING_MODULATOR_SINUSOID (0) +#define AL_RING_MODULATOR_SAWTOOTH (1) +#define AL_RING_MODULATOR_SQUARE (2) + +#define AL_RING_MODULATOR_MIN_WAVEFORM (0) +#define AL_RING_MODULATOR_MAX_WAVEFORM (2) +#define AL_RING_MODULATOR_DEFAULT_WAVEFORM (0) + +/* Autowah effect */ +#define AL_AUTOWAH_MIN_ATTACK_TIME (0.0001f) +#define AL_AUTOWAH_MAX_ATTACK_TIME (1.0f) +#define AL_AUTOWAH_DEFAULT_ATTACK_TIME (0.06f) + +#define AL_AUTOWAH_MIN_RELEASE_TIME (0.0001f) +#define AL_AUTOWAH_MAX_RELEASE_TIME (1.0f) +#define AL_AUTOWAH_DEFAULT_RELEASE_TIME (0.06f) + +#define AL_AUTOWAH_MIN_RESONANCE (2.0f) +#define AL_AUTOWAH_MAX_RESONANCE (1000.0f) +#define AL_AUTOWAH_DEFAULT_RESONANCE (1000.0f) + +#define AL_AUTOWAH_MIN_PEAK_GAIN (0.00003f) +#define AL_AUTOWAH_MAX_PEAK_GAIN (31621.0f) +#define AL_AUTOWAH_DEFAULT_PEAK_GAIN (11.22f) + +/* Compressor effect */ +#define AL_COMPRESSOR_MIN_ONOFF (0) +#define AL_COMPRESSOR_MAX_ONOFF (1) +#define AL_COMPRESSOR_DEFAULT_ONOFF (1) + +/* Equalizer effect */ +#define AL_EQUALIZER_MIN_LOW_GAIN (0.126f) +#define AL_EQUALIZER_MAX_LOW_GAIN (7.943f) +#define AL_EQUALIZER_DEFAULT_LOW_GAIN (1.0f) + +#define AL_EQUALIZER_MIN_LOW_CUTOFF (50.0f) +#define AL_EQUALIZER_MAX_LOW_CUTOFF (800.0f) +#define AL_EQUALIZER_DEFAULT_LOW_CUTOFF (200.0f) + +#define AL_EQUALIZER_MIN_MID1_GAIN (0.126f) +#define AL_EQUALIZER_MAX_MID1_GAIN (7.943f) +#define AL_EQUALIZER_DEFAULT_MID1_GAIN (1.0f) + +#define AL_EQUALIZER_MIN_MID1_CENTER (200.0f) +#define AL_EQUALIZER_MAX_MID1_CENTER (3000.0f) +#define AL_EQUALIZER_DEFAULT_MID1_CENTER (500.0f) + +#define AL_EQUALIZER_MIN_MID1_WIDTH (0.01f) +#define AL_EQUALIZER_MAX_MID1_WIDTH (1.0f) +#define AL_EQUALIZER_DEFAULT_MID1_WIDTH (1.0f) + +#define AL_EQUALIZER_MIN_MID2_GAIN (0.126f) +#define AL_EQUALIZER_MAX_MID2_GAIN (7.943f) +#define AL_EQUALIZER_DEFAULT_MID2_GAIN (1.0f) + +#define AL_EQUALIZER_MIN_MID2_CENTER (1000.0f) +#define AL_EQUALIZER_MAX_MID2_CENTER (8000.0f) +#define AL_EQUALIZER_DEFAULT_MID2_CENTER (3000.0f) + +#define AL_EQUALIZER_MIN_MID2_WIDTH (0.01f) +#define AL_EQUALIZER_MAX_MID2_WIDTH (1.0f) +#define AL_EQUALIZER_DEFAULT_MID2_WIDTH (1.0f) + +#define AL_EQUALIZER_MIN_HIGH_GAIN (0.126f) +#define AL_EQUALIZER_MAX_HIGH_GAIN (7.943f) +#define AL_EQUALIZER_DEFAULT_HIGH_GAIN (1.0f) + +#define AL_EQUALIZER_MIN_HIGH_CUTOFF (4000.0f) +#define AL_EQUALIZER_MAX_HIGH_CUTOFF (16000.0f) +#define AL_EQUALIZER_DEFAULT_HIGH_CUTOFF (6000.0f) + + +/* Source parameter value ranges and defaults. */ +#define AL_MIN_AIR_ABSORPTION_FACTOR (0.0f) +#define AL_MAX_AIR_ABSORPTION_FACTOR (10.0f) +#define AL_DEFAULT_AIR_ABSORPTION_FACTOR (0.0f) + +#define AL_MIN_ROOM_ROLLOFF_FACTOR (0.0f) +#define AL_MAX_ROOM_ROLLOFF_FACTOR (10.0f) +#define AL_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f) + +#define AL_MIN_CONE_OUTER_GAINHF (0.0f) +#define AL_MAX_CONE_OUTER_GAINHF (1.0f) +#define AL_DEFAULT_CONE_OUTER_GAINHF (1.0f) + +#define AL_MIN_DIRECT_FILTER_GAINHF_AUTO AL_FALSE +#define AL_MAX_DIRECT_FILTER_GAINHF_AUTO AL_TRUE +#define AL_DEFAULT_DIRECT_FILTER_GAINHF_AUTO AL_TRUE + +#define AL_MIN_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_FALSE +#define AL_MAX_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE +#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE + +#define AL_MIN_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_FALSE +#define AL_MAX_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE +#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE + + +/* Listener parameter value ranges and defaults. */ +#define AL_MIN_METERS_PER_UNIT FLT_MIN +#define AL_MAX_METERS_PER_UNIT FLT_MAX +#define AL_DEFAULT_METERS_PER_UNIT (1.0f) + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* AL_EFX_H */ diff --git a/builddir/postgresql-9.5.3/COPYRIGHT b/builddir/postgresql-9.5.3/COPYRIGHT new file mode 100644 index 0000000..01b6e36 --- /dev/null +++ b/builddir/postgresql-9.5.3/COPYRIGHT @@ -0,0 +1,23 @@ +PostgreSQL Database Management System +(formerly known as Postgres, then as Postgres95) + +Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group + +Portions Copyright (c) 1994, The Regents of the University of California + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this +paragraph and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING +LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO +PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. diff --git a/builddir/postgresql-9.5.3/bin/libpq.lib b/builddir/postgresql-9.5.3/bin/libpq.lib new file mode 100644 index 0000000..556b5dd Binary files /dev/null and b/builddir/postgresql-9.5.3/bin/libpq.lib differ diff --git a/builddir/postgresql-9.5.3/include/libpq-fe.h b/builddir/postgresql-9.5.3/include/libpq-fe.h new file mode 100644 index 0000000..bcd14ac --- /dev/null +++ b/builddir/postgresql-9.5.3/include/libpq-fe.h @@ -0,0 +1,593 @@ +/*------------------------------------------------------------------------- + * + * libpq-fe.h + * This file contains definitions for structures and + * externs for functions used by frontend postgres applications. + * + * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/interfaces/libpq/libpq-fe.h + * + *------------------------------------------------------------------------- + */ + +#ifndef LIBPQ_FE_H +#define LIBPQ_FE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stdio.h> + +/* + * postgres_ext.h defines the backend's externally visible types, + * such as Oid. + */ +#include "postgres_ext.h" + +/* + * Option flags for PQcopyResult + */ +#define PG_COPYRES_ATTRS 0x01 +#define PG_COPYRES_TUPLES 0x02 /* Implies PG_COPYRES_ATTRS */ +#define PG_COPYRES_EVENTS 0x04 +#define PG_COPYRES_NOTICEHOOKS 0x08 + +/* Application-visible enum types */ + +/* + * Although it is okay to add to these lists, values which become unused + * should never be removed, nor should constants be redefined - that would + * break compatibility with existing code. + */ + +typedef enum +{ + CONNECTION_OK, + CONNECTION_BAD, + /* Non-blocking mode only below here */ + + /* + * The existence of these should never be relied upon - they should only + * be used for user feedback or similar purposes. + */ + CONNECTION_STARTED, /* Waiting for connection to be made. */ + CONNECTION_MADE, /* Connection OK; waiting to send. */ + CONNECTION_AWAITING_RESPONSE, /* Waiting for a response from the + * postmaster. */ + CONNECTION_AUTH_OK, /* Received authentication; waiting for + * backend startup. */ + CONNECTION_SETENV, /* Negotiating environment. */ + CONNECTION_SSL_STARTUP, /* Negotiating SSL. */ + CONNECTION_NEEDED /* Internal state: connect() needed */ +} ConnStatusType; + +typedef enum +{ + PGRES_POLLING_FAILED = 0, + PGRES_POLLING_READING, /* These two indicate that one may */ + PGRES_POLLING_WRITING, /* use select before polling again. */ + PGRES_POLLING_OK, + PGRES_POLLING_ACTIVE /* unused; keep for awhile for backwards + * compatibility */ +} PostgresPollingStatusType; + +typedef enum +{ + PGRES_EMPTY_QUERY = 0, /* empty query string was executed */ + PGRES_COMMAND_OK, /* a query command that doesn't return + * anything was executed properly by the + * backend */ + PGRES_TUPLES_OK, /* a query command that returns tuples was + * executed properly by the backend, PGresult + * contains the result tuples */ + PGRES_COPY_OUT, /* Copy Out data transfer in progress */ + PGRES_COPY_IN, /* Copy In data transfer in progress */ + PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the + * backend */ + PGRES_NONFATAL_ERROR, /* notice or warning message */ + PGRES_FATAL_ERROR, /* query failed */ + PGRES_COPY_BOTH, /* Copy In/Out data transfer in progress */ + PGRES_SINGLE_TUPLE /* single tuple from larger resultset */ +} ExecStatusType; + +typedef enum +{ + PQTRANS_IDLE, /* connection idle */ + PQTRANS_ACTIVE, /* command in progress */ + PQTRANS_INTRANS, /* idle, within transaction block */ + PQTRANS_INERROR, /* idle, within failed transaction */ + PQTRANS_UNKNOWN /* cannot determine status */ +} PGTransactionStatusType; + +typedef enum +{ + PQERRORS_TERSE, /* single-line error messages */ + PQERRORS_DEFAULT, /* recommended style */ + PQERRORS_VERBOSE /* all the facts, ma'am */ +} PGVerbosity; + +/* + * PGPing - The ordering of this enum should not be altered because the + * values are exposed externally via pg_isready. + */ + +typedef enum +{ + PQPING_OK, /* server is accepting connections */ + PQPING_REJECT, /* server is alive but rejecting connections */ + PQPING_NO_RESPONSE, /* could not establish connection */ + PQPING_NO_ATTEMPT /* connection not attempted (bad params) */ +} PGPing; + +/* PGconn encapsulates a connection to the backend. + * The contents of this struct are not supposed to be known to applications. + */ +typedef struct pg_conn PGconn; + +/* PGresult encapsulates the result of a query (or more precisely, of a single + * SQL command --- a query string given to PQsendQuery can contain multiple + * commands and thus return multiple PGresult objects). + * The contents of this struct are not supposed to be known to applications. + */ +typedef struct pg_result PGresult; + +/* PGcancel encapsulates the information needed to cancel a running + * query on an existing connection. + * The contents of this struct are not supposed to be known to applications. + */ +typedef struct pg_cancel PGcancel; + +/* PGnotify represents the occurrence of a NOTIFY message. + * Ideally this would be an opaque typedef, but it's so simple that it's + * unlikely to change. + * NOTE: in Postgres 6.4 and later, the be_pid is the notifying backend's, + * whereas in earlier versions it was always your own backend's PID. + */ +typedef struct pgNotify +{ + char *relname; /* notification condition name */ + int be_pid; /* process ID of notifying server process */ + char *extra; /* notification parameter */ + /* Fields below here are private to libpq; apps should not use 'em */ + struct pgNotify *next; /* list link */ +} PGnotify; + +/* Function types for notice-handling callbacks */ +typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res); +typedef void (*PQnoticeProcessor) (void *arg, const char *message); + +/* Print options for PQprint() */ +typedef char pqbool; + +typedef struct _PQprintOpt +{ + pqbool header; /* print output field headings and row count */ + pqbool align; /* fill align the fields */ + pqbool standard; /* old brain dead format */ + pqbool html3; /* output html tables */ + pqbool expanded; /* expand tables */ + pqbool pager; /* use pager for output if needed */ + char *fieldSep; /* field separator */ + char *tableOpt; /* insert to HTML <table ...> */ + char *caption; /* HTML <caption> */ + char **fieldName; /* null terminated array of replacement field + * names */ +} PQprintOpt; + +/* ---------------- + * Structure for the conninfo parameter definitions returned by PQconndefaults + * or PQconninfoParse. + * + * All fields except "val" point at static strings which must not be altered. + * "val" is either NULL or a malloc'd current-value string. PQconninfoFree() + * will release both the val strings and the PQconninfoOption array itself. + * ---------------- + */ +typedef struct _PQconninfoOption +{ + char *keyword; /* The keyword of the option */ + char *envvar; /* Fallback environment variable name */ + char *compiled; /* Fallback compiled in default value */ + char *val; /* Option's current value, or NULL */ + char *label; /* Label for field in connect dialog */ + char *dispchar; /* Indicates how to display this field in a + * connect dialog. Values are: "" Display + * entered value as is "*" Password field - + * hide value "D" Debug option - don't show + * by default */ + int dispsize; /* Field size in characters for dialog */ +} PQconninfoOption; + +/* ---------------- + * PQArgBlock -- structure for PQfn() arguments + * ---------------- + */ +typedef struct +{ + int len; + int isint; + union + { + int *ptr; /* can't use void (dec compiler barfs) */ + int integer; + } u; +} PQArgBlock; + +/* ---------------- + * PGresAttDesc -- Data about a single attribute (column) of a query result + * ---------------- + */ +typedef struct pgresAttDesc +{ + char *name; /* column name */ + Oid tableid; /* source table, if known */ + int columnid; /* source column, if known */ + int format; /* format code for value (text/binary) */ + Oid typid; /* type id */ + int typlen; /* type size */ + int atttypmod; /* type-specific modifier info */ +} PGresAttDesc; + +/* ---------------- + * Exported functions of libpq + * ---------------- + */ + +/* === in fe-connect.c === */ + +/* make a new client connection to the backend */ +/* Asynchronous (non-blocking) */ +extern PGconn *PQconnectStart(const char *conninfo); +extern PGconn *PQconnectStartParams(const char *const * keywords, + const char *const * values, int expand_dbname); +extern PostgresPollingStatusType PQconnectPoll(PGconn *conn); + +/* Synchronous (blocking) */ +extern PGconn *PQconnectdb(const char *conninfo); +extern PGconn *PQconnectdbParams(const char *const * keywords, + const char *const * values, int expand_dbname); +extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport, + const char *pgoptions, const char *pgtty, + const char *dbName, + const char *login, const char *pwd); + +#define PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME) \ + PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL) + +/* close the current connection and free the PGconn data structure */ +extern void PQfinish(PGconn *conn); + +/* get info about connection options known to PQconnectdb */ +extern PQconninfoOption *PQconndefaults(void); + +/* parse connection options in same way as PQconnectdb */ +extern PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg); + +/* return the connection options used by a live connection */ +extern PQconninfoOption *PQconninfo(PGconn *conn); + +/* free the data structure returned by PQconndefaults() or PQconninfoParse() */ +extern void PQconninfoFree(PQconninfoOption *connOptions); + +/* + * close the current connection and restablish a new one with the same + * parameters + */ +/* Asynchronous (non-blocking) */ +extern int PQresetStart(PGconn *conn); +extern PostgresPollingStatusType PQresetPoll(PGconn *conn); + +/* Synchronous (blocking) */ +extern void PQreset(PGconn *conn); + +/* request a cancel structure */ +extern PGcancel *PQgetCancel(PGconn *conn); + +/* free a cancel structure */ +extern void PQfreeCancel(PGcancel *cancel); + +/* issue a cancel request */ +extern int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); + +/* backwards compatible version of PQcancel; not thread-safe */ +extern int PQrequestCancel(PGconn *conn); + +/* Accessor functions for PGconn objects */ +extern char *PQdb(const PGconn *conn); +extern char *PQuser(const PGconn *conn); +extern char *PQpass(const PGconn *conn); +extern char *PQhost(const PGconn *conn); +extern char *PQport(const PGconn *conn); +extern char *PQtty(const PGconn *conn); +extern char *PQoptions(const PGconn *conn); +extern ConnStatusType PQstatus(const PGconn *conn); +extern PGTransactionStatusType PQtransactionStatus(const PGconn *conn); +extern const char *PQparameterStatus(const PGconn *conn, + const char *paramName); +extern int PQprotocolVersion(const PGconn *conn); +extern int PQserverVersion(const PGconn *conn); +extern char *PQerrorMessage(const PGconn *conn); +extern int PQsocket(const PGconn *conn); +extern int PQbackendPID(const PGconn *conn); +extern int PQconnectionNeedsPassword(const PGconn *conn); +extern int PQconnectionUsedPassword(const PGconn *conn); +extern int PQclientEncoding(const PGconn *conn); +extern int PQsetClientEncoding(PGconn *conn, const char *encoding); + +/* SSL information functions */ +extern int PQsslInUse(PGconn *conn); +extern void *PQsslStruct(PGconn *conn, const char *struct_name); +extern const char *PQsslAttribute(PGconn *conn, const char *attribute_name); +extern const char *const * PQsslAttributeNames(PGconn *conn); + +/* Get the OpenSSL structure associated with a connection. Returns NULL for + * unencrypted connections or if any other TLS library is in use. */ +extern void *PQgetssl(PGconn *conn); + +/* Tell libpq whether it needs to initialize OpenSSL */ +extern void PQinitSSL(int do_init); + +/* More detailed way to tell libpq whether it needs to initialize OpenSSL */ +extern void PQinitOpenSSL(int do_ssl, int do_crypto); + +/* Set verbosity for PQerrorMessage and PQresultErrorMessage */ +extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity); + +/* Enable/disable tracing */ +extern void PQtrace(PGconn *conn, FILE *debug_port); +extern void PQuntrace(PGconn *conn); + +/* Override default notice handling routines */ +extern PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, + PQnoticeReceiver proc, + void *arg); +extern PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, + PQnoticeProcessor proc, + void *arg); + +/* + * Used to set callback that prevents concurrent access to + * non-thread safe functions that libpq needs. + * The default implementation uses a libpq internal mutex. + * Only required for multithreaded apps that use kerberos + * both within their app and for postgresql connections. + */ +typedef void (*pgthreadlock_t) (int acquire); + +extern pgthreadlock_t PQregisterThreadLock(pgthreadlock_t newhandler); + +/* === in fe-exec.c === */ + +/* Simple synchronous query */ +extern PGresult *PQexec(PGconn *conn, const char *query); +extern PGresult *PQexecParams(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern PGresult *PQprepare(PGconn *conn, const char *stmtName, + const char *query, int nParams, + const Oid *paramTypes); +extern PGresult *PQexecPrepared(PGconn *conn, + const char *stmtName, + int nParams, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); + +/* Interface for multiple-result or asynchronous queries */ +extern int PQsendQuery(PGconn *conn, const char *query); +extern int PQsendQueryParams(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern int PQsendPrepare(PGconn *conn, const char *stmtName, + const char *query, int nParams, + const Oid *paramTypes); +extern int PQsendQueryPrepared(PGconn *conn, + const char *stmtName, + int nParams, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern int PQsetSingleRowMode(PGconn *conn); +extern PGresult *PQgetResult(PGconn *conn); + +/* Routines for managing an asynchronous query */ +extern int PQisBusy(PGconn *conn); +extern int PQconsumeInput(PGconn *conn); + +/* LISTEN/NOTIFY support */ +extern PGnotify *PQnotifies(PGconn *conn); + +/* Routines for copy in/out */ +extern int PQputCopyData(PGconn *conn, const char *buffer, int nbytes); +extern int PQputCopyEnd(PGconn *conn, const char *errormsg); +extern int PQgetCopyData(PGconn *conn, char **buffer, int async); + +/* Deprecated routines for copy in/out */ +extern int PQgetline(PGconn *conn, char *string, int length); +extern int PQputline(PGconn *conn, const char *string); +extern int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize); +extern int PQputnbytes(PGconn *conn, const char *buffer, int nbytes); +extern int PQendcopy(PGconn *conn); + +/* Set blocking/nonblocking connection to the backend */ +extern int PQsetnonblocking(PGconn *conn, int arg); +extern int PQisnonblocking(const PGconn *conn); +extern int PQisthreadsafe(void); +extern PGPing PQping(const char *conninfo); +extern PGPing PQpingParams(const char *const * keywords, + const char *const * values, int expand_dbname); + +/* Force the write buffer to be written (or at least try) */ +extern int PQflush(PGconn *conn); + +/* + * "Fast path" interface --- not really recommended for application + * use + */ +extern PGresult *PQfn(PGconn *conn, + int fnid, + int *result_buf, + int *result_len, + int result_is_int, + const PQArgBlock *args, + int nargs); + +/* Accessor functions for PGresult objects */ +extern ExecStatusType PQresultStatus(const PGresult *res); +extern char *PQresStatus(ExecStatusType status); +extern char *PQresultErrorMessage(const PGresult *res); +extern char *PQresultErrorField(const PGresult *res, int fieldcode); +extern int PQntuples(const PGresult *res); +extern int PQnfields(const PGresult *res); +extern int PQbinaryTuples(const PGresult *res); +extern char *PQfname(const PGresult *res, int field_num); +extern int PQfnumber(const PGresult *res, const char *field_name); +extern Oid PQftable(const PGresult *res, int field_num); +extern int PQftablecol(const PGresult *res, int field_num); +extern int PQfformat(const PGresult *res, int field_num); +extern Oid PQftype(const PGresult *res, int field_num); +extern int PQfsize(const PGresult *res, int field_num); +extern int PQfmod(const PGresult *res, int field_num); +extern char *PQcmdStatus(PGresult *res); +extern char *PQoidStatus(const PGresult *res); /* old and ugly */ +extern Oid PQoidValue(const PGresult *res); /* new and improved */ +extern char *PQcmdTuples(PGresult *res); +extern char *PQgetvalue(const PGresult *res, int tup_num, int field_num); +extern int PQgetlength(const PGresult *res, int tup_num, int field_num); +extern int PQgetisnull(const PGresult *res, int tup_num, int field_num); +extern int PQnparams(const PGresult *res); +extern Oid PQparamtype(const PGresult *res, int param_num); + +/* Describe prepared statements and portals */ +extern PGresult *PQdescribePrepared(PGconn *conn, const char *stmt); +extern PGresult *PQdescribePortal(PGconn *conn, const char *portal); +extern int PQsendDescribePrepared(PGconn *conn, const char *stmt); +extern int PQsendDescribePortal(PGconn *conn, const char *portal); + +/* Delete a PGresult */ +extern void PQclear(PGresult *res); + +/* For freeing other alloc'd results, such as PGnotify structs */ +extern void PQfreemem(void *ptr); + +/* Exists for backward compatibility. bjm 2003-03-24 */ +#define PQfreeNotify(ptr) PQfreemem(ptr) + +/* Error when no password was given. */ +/* Note: depending on this is deprecated; use PQconnectionNeedsPassword(). */ +#define PQnoPasswordSupplied "fe_sendauth: no password supplied\n" + +/* Create and manipulate PGresults */ +extern PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); +extern PGresult *PQcopyResult(const PGresult *src, int flags); +extern int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs); +extern void *PQresultAlloc(PGresult *res, size_t nBytes); +extern int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len); + +/* Quoting strings before inclusion in queries. */ +extern size_t PQescapeStringConn(PGconn *conn, + char *to, const char *from, size_t length, + int *error); +extern char *PQescapeLiteral(PGconn *conn, const char *str, size_t len); +extern char *PQescapeIdentifier(PGconn *conn, const char *str, size_t len); +extern unsigned char *PQescapeByteaConn(PGconn *conn, + const unsigned char *from, size_t from_length, + size_t *to_length); +extern unsigned char *PQunescapeBytea(const unsigned char *strtext, + size_t *retbuflen); + +/* These forms are deprecated! */ +extern size_t PQescapeString(char *to, const char *from, size_t length); +extern unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, + size_t *to_length); + + + +/* === in fe-print.c === */ + +extern void PQprint(FILE *fout, /* output stream */ + const PGresult *res, + const PQprintOpt *ps); /* option structure */ + +/* + * really old printing routines + */ +extern void PQdisplayTuples(const PGresult *res, + FILE *fp, /* where to send the output */ + int fillAlign, /* pad the fields with spaces */ + const char *fieldSep, /* field separator */ + int printHeader, /* display headers? */ + int quiet); + +extern void PQprintTuples(const PGresult *res, + FILE *fout, /* output stream */ + int printAttName, /* print attribute names */ + int terseOutput, /* delimiter bars */ + int width); /* width of column, if 0, use variable width */ + + +/* === in fe-lobj.c === */ + +/* Large-object access routines */ +extern int lo_open(PGconn *conn, Oid lobjId, int mode); +extern int lo_close(PGconn *conn, int fd); +extern int lo_read(PGconn *conn, int fd, char *buf, size_t len); +extern int lo_write(PGconn *conn, int fd, const char *buf, size_t len); +extern int lo_lseek(PGconn *conn, int fd, int offset, int whence); +extern pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence); +extern Oid lo_creat(PGconn *conn, int mode); +extern Oid lo_create(PGconn *conn, Oid lobjId); +extern int lo_tell(PGconn *conn, int fd); +extern pg_int64 lo_tell64(PGconn *conn, int fd); +extern int lo_truncate(PGconn *conn, int fd, size_t len); +extern int lo_truncate64(PGconn *conn, int fd, pg_int64 len); +extern int lo_unlink(PGconn *conn, Oid lobjId); +extern Oid lo_import(PGconn *conn, const char *filename); +extern Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId); +extern int lo_export(PGconn *conn, Oid lobjId, const char *filename); + +/* === in fe-misc.c === */ + +/* Get the version of the libpq library in use */ +extern int PQlibVersion(void); + +/* Determine length of multibyte encoded char at *s */ +extern int PQmblen(const char *s, int encoding); + +/* Determine display length of multibyte encoded char at *s */ +extern int PQdsplen(const char *s, int encoding); + +/* Get encoding id from environment variable PGCLIENTENCODING */ +extern int PQenv2encoding(void); + +/* === in fe-auth.c === */ + +extern char *PQencryptPassword(const char *passwd, const char *user); + +/* === in encnames.c === */ + +extern int pg_char_to_encoding(const char *name); +extern const char *pg_encoding_to_char(int encoding); +extern int pg_valid_server_encoding_id(int encoding); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBPQ_FE_H */ diff --git a/builddir/postgresql-9.5.3/include/pg_config_ext.h b/builddir/postgresql-9.5.3/include/pg_config_ext.h new file mode 100644 index 0000000..65bbb5d --- /dev/null +++ b/builddir/postgresql-9.5.3/include/pg_config_ext.h @@ -0,0 +1,7 @@ +/* + * src/include/pg_config_ext.h.win32. This is generated manually, not by + * autoheader, since we want to limit which symbols get defined here. + */ + +/* Define to the name of a signed 64-bit integer type. */ +#define PG_INT64_TYPE long long int diff --git a/builddir/postgresql-9.5.3/include/postgres_ext.h b/builddir/postgresql-9.5.3/include/postgres_ext.h new file mode 100644 index 0000000..74c344c --- /dev/null +++ b/builddir/postgresql-9.5.3/include/postgres_ext.h @@ -0,0 +1,69 @@ +/*------------------------------------------------------------------------- + * + * postgres_ext.h + * + * This file contains declarations of things that are visible everywhere + * in PostgreSQL *and* are visible to clients of frontend interface libraries. + * For example, the Oid type is part of the API of libpq and other libraries. + * + * Declarations which are specific to a particular interface should + * go in the header file for that interface (such as libpq-fe.h). This + * file is only for fundamental Postgres declarations. + * + * User-written C functions don't count as "external to Postgres." + * Those function much as local modifications to the backend itself, and + * use header files that are otherwise internal to Postgres to interface + * with the backend. + * + * src/include/postgres_ext.h + * + *------------------------------------------------------------------------- + */ + +#ifndef POSTGRES_EXT_H +#define POSTGRES_EXT_H + +#include "pg_config_ext.h" + +/* + * Object ID is a fundamental type in Postgres. + */ +typedef unsigned int Oid; + +#ifdef __cplusplus +#define InvalidOid (Oid(0)) +#else +#define InvalidOid ((Oid) 0) +#endif + +#define OID_MAX UINT_MAX +/* you will need to include <limits.h> to use the above #define */ + +/* Define a signed 64-bit integer type for use in client API declarations. */ +typedef PG_INT64_TYPE pg_int64; + + +/* + * Identifiers of error message fields. Kept here to keep common + * between frontend and backend, and also to export them to libpq + * applications. + */ +#define PG_DIAG_SEVERITY 'S' +#define PG_DIAG_SQLSTATE 'C' +#define PG_DIAG_MESSAGE_PRIMARY 'M' +#define PG_DIAG_MESSAGE_DETAIL 'D' +#define PG_DIAG_MESSAGE_HINT 'H' +#define PG_DIAG_STATEMENT_POSITION 'P' +#define PG_DIAG_INTERNAL_POSITION 'p' +#define PG_DIAG_INTERNAL_QUERY 'q' +#define PG_DIAG_CONTEXT 'W' +#define PG_DIAG_SCHEMA_NAME 's' +#define PG_DIAG_TABLE_NAME 't' +#define PG_DIAG_COLUMN_NAME 'c' +#define PG_DIAG_DATATYPE_NAME 'd' +#define PG_DIAG_CONSTRAINT_NAME 'n' +#define PG_DIAG_SOURCE_FILE 'F' +#define PG_DIAG_SOURCE_LINE 'L' +#define PG_DIAG_SOURCE_FUNCTION 'R' + +#endif /* POSTGRES_EXT_H */ diff --git a/builddir/spatialindex-1.8.5/COPYING b/builddir/spatialindex-1.8.5/COPYING new file mode 100644 index 0000000..9fae459 --- /dev/null +++ b/builddir/spatialindex-1.8.5/COPYING @@ -0,0 +1,48 @@ +Licensing History +------------------------------------------------------------------------------ + + +.. note:: + libspatialindex changed from a `LGPL`_ to a `MIT`_ license as of the 1.8.0 + release. For most situations, this should have no impact on the library's + use, but it should open it up for usage in situations that otherwise might + have been problematic. Versions of libspatialindex prior to 1.8.0 were + licensed LGPL 2.0, with the license description on this file. The codebase + has been been updated, with licensing information replaced in headers and + source files, to use the MIT license as of the 1.8.0+ release. + + This change was made to support the inclusion of software depending on + libspatialindex in static linking-only environments such as embedded systems + and Apple's iOS. libspatialindex versions prior to 1.8.0 will continue to + live on as LGPL software, and developers can continue to contribute to them + under terms of that license, but the main development effort, and ongoing + maintenance, releases, and bug applications, will move forward using the + new MIT license at http://github.com/libspatialindex/libspatialindex + +.. _`LGPL`: http://opensource.org/licenses/lgpl-2.1.php +.. _`MIT`: http://opensource.org/licenses/MIT + + + +License (MIT) +------------------------------------------------------------------------------ + +:: + + 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. diff --git a/builddir/spatialindex-1.8.5/bin/spatialindex-32.dll b/builddir/spatialindex-1.8.5/bin/spatialindex-32.dll new file mode 100644 index 0000000..fea6d71 Binary files /dev/null and b/builddir/spatialindex-1.8.5/bin/spatialindex-32.dll differ diff --git a/builddir/spatialindex-1.8.5/bin/spatialindex-32.exp b/builddir/spatialindex-1.8.5/bin/spatialindex-32.exp new file mode 100644 index 0000000..47af58f Binary files /dev/null and b/builddir/spatialindex-1.8.5/bin/spatialindex-32.exp differ diff --git a/builddir/spatialindex-1.8.5/bin/spatialindex-32.lib b/builddir/spatialindex-1.8.5/bin/spatialindex-32.lib new file mode 100644 index 0000000..97416c8 Binary files /dev/null and b/builddir/spatialindex-1.8.5/bin/spatialindex-32.lib differ diff --git a/builddir/spatialindex-1.8.5/bin/spatialindex_c-32.dll b/builddir/spatialindex-1.8.5/bin/spatialindex_c-32.dll new file mode 100644 index 0000000..726ddd2 Binary files /dev/null and b/builddir/spatialindex-1.8.5/bin/spatialindex_c-32.dll differ diff --git a/builddir/spatialindex-1.8.5/bin/spatialindex_c-32.exp b/builddir/spatialindex-1.8.5/bin/spatialindex_c-32.exp new file mode 100644 index 0000000..d5e660c Binary files /dev/null and b/builddir/spatialindex-1.8.5/bin/spatialindex_c-32.exp differ diff --git a/builddir/spatialindex-1.8.5/bin/spatialindex_c-32.lib b/builddir/spatialindex-1.8.5/bin/spatialindex_c-32.lib new file mode 100644 index 0000000..26ee5eb Binary files /dev/null and b/builddir/spatialindex-1.8.5/bin/spatialindex_c-32.lib differ diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/LineSegment.h b/builddir/spatialindex-1.8.5/include/spatialindex/LineSegment.h new file mode 100644 index 0000000..c10e798 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/LineSegment.h @@ -0,0 +1,103 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2004, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +namespace SpatialIndex +{ + class SIDX_DLL LineSegment : public Tools::IObject, public virtual IShape + { + public: + LineSegment(); + LineSegment(const double* startPoint, const double* endPoint, uint32_t dimension); + LineSegment(const Point& startPoint, const Point& endPoint); + LineSegment(const LineSegment& l); + virtual ~LineSegment(); + + virtual LineSegment& operator=(const LineSegment& p); + virtual bool operator==(const LineSegment& p) const; + + // + // IObject interface + // + virtual LineSegment* clone(); + + // + // ISerializable interface + // + virtual uint32_t getByteArraySize(); + virtual void loadFromByteArray(const byte* data); + virtual void storeToByteArray(byte** data, uint32_t& length); + + // + // IShape interface + // + virtual bool intersectsShape(const IShape& in) const; + virtual bool containsShape(const IShape& in) const; + virtual bool touchesShape(const IShape& in) const; + virtual void getCenter(Point& out) const; + virtual uint32_t getDimension() const; + virtual void getMBR(Region& out) const; + virtual double getArea() const; + virtual double getMinimumDistance(const IShape& in) const; + + virtual bool intersectsLineSegment(const LineSegment& l) const; + virtual bool intersectsRegion(const Region& p) const; + virtual double getMinimumDistance(const Point& p) const; + //virtual double getMinimumDistance(const Region& r) const; + virtual double getRelativeMinimumDistance(const Point& p) const; + virtual double getRelativeMaximumDistance(const Region& r) const; + virtual double getAngleOfPerpendicularRay(); + + virtual void makeInfinite(uint32_t dimension); + virtual void makeDimension(uint32_t dimension); + + public: + uint32_t m_dimension; + double* m_pStartPoint; + double* m_pEndPoint; + + friend class Region; + friend class Point; + friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const LineSegment& pt); + + protected: + + //some helpers for intersects methods + static double doubleAreaTriangle(const Point& a, const Point& b, const Point& c); + static bool leftOf(const Point& a, const Point& b, const Point& c); + static bool collinear(const Point& a, const Point& b, const Point& c); + static bool between(const Point& a, const Point& b, const Point& c); + static bool between(double a, double b, double c); + static bool intersectsProper(const Point& a, const Point& b, const Point& c, const Point& d); + static bool intersects(const Point& a, const Point& b, const Point& c, const Point& d); + + }; // LineSegment + + SIDX_DLL std::ostream& operator<<(std::ostream& os, const LineSegment& pt); +} + diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/MVRTree.h b/builddir/spatialindex-1.8.5/include/spatialindex/MVRTree.h new file mode 100644 index 0000000..770efd1 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/MVRTree.h @@ -0,0 +1,89 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2004, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +namespace SpatialIndex +{ + namespace MVRTree + { + SIDX_DLL enum MVRTreeVariant + { + RV_LINEAR = 0x0, + RV_QUADRATIC, + RV_RSTAR + }; + + SIDX_DLL enum PersistenObjectIdentifier + { + PersistentIndex = 0x1, + PersistentLeaf = 0x2 + }; + + SIDX_DLL enum RangeQueryType + { + ContainmentQuery = 0x1, + IntersectionQuery = 0x2 + }; + + class SIDX_DLL Data : public IData, public Tools::ISerializable + { + public: + Data(uint32_t len, byte* pData, TimeRegion& r, id_type id); + virtual ~Data(); + + virtual Data* clone(); + virtual id_type getIdentifier() const; + virtual void getShape(IShape** out) const; + virtual void getData(uint32_t& len, byte** data) const; + virtual uint32_t getByteArraySize(); + virtual void loadFromByteArray(const byte* data); + virtual void storeToByteArray(byte** data, uint32_t& len); + + id_type m_id; + TimeRegion m_region; + byte* m_pData; + uint32_t m_dataLength; + }; // Data + + SIDX_DLL ISpatialIndex* returnMVRTree(IStorageManager& ind, Tools::PropertySet& in); + SIDX_DLL ISpatialIndex* createNewMVRTree( + IStorageManager& in, + double fillFactor, + uint32_t indexCapacity, + uint32_t leafCapacity, + uint32_t dimension, + MVRTreeVariant rv, + id_type& out_indexIdentifier + ); + SIDX_DLL ISpatialIndex* loadMVRTree( + IStorageManager& in, + id_type indexIdentifier + ); + } +} + diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/MovingPoint.h b/builddir/spatialindex-1.8.5/include/spatialindex/MovingPoint.h new file mode 100644 index 0000000..5323d2b --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/MovingPoint.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2003, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +namespace SpatialIndex +{ + class SIDX_DLL MovingPoint : public TimePoint, public IEvolvingShape + { + public: + MovingPoint(); + MovingPoint(const double* pCoords, const double* pVCoords, const Tools::IInterval& ti, uint32_t dimension); + MovingPoint(const double* pCoords, const double* pVCoords, double tStart, double tEnd, uint32_t dimension); + MovingPoint(const Point& p, const Point& vp, const Tools::IInterval& ti); + MovingPoint(const Point& p, const Point& vp, double tStart, double tEnd); + MovingPoint(const MovingPoint& p); + virtual ~MovingPoint(); + + virtual MovingPoint& operator=(const MovingPoint& p); + virtual bool operator==(const MovingPoint& p) const; + + virtual double getCoord(uint32_t index, double t) const; + virtual double getProjectedCoord(uint32_t index, double t) const; + virtual double getVCoord(uint32_t index) const; + virtual void getPointAtTime(double t, Point& out) const; + + // + // IObject interface + // + virtual MovingPoint* clone(); + + // + // ISerializable interface + // + virtual uint32_t getByteArraySize(); + virtual void loadFromByteArray(const byte* data); + virtual void storeToByteArray(byte** data, uint32_t& len); + + // + // IEvolvingShape interface + // + virtual void getVMBR(Region& out) const; + virtual void getMBRAtTime(double t, Region& out) const; + + virtual void makeInfinite(uint32_t dimension); + virtual void makeDimension(uint32_t dimension); + + private: + void initialize( + const double* pCoords, const double* pVCoords, + double tStart, double tEnd, uint32_t dimension); + + public: + double* m_pVCoords; + + friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingPoint& pt); + }; // MovingPoint + + SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingPoint& pt); +} + diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/MovingRegion.h b/builddir/spatialindex-1.8.5/include/spatialindex/MovingRegion.h new file mode 100644 index 0000000..2e21954 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/MovingRegion.h @@ -0,0 +1,170 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2003, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +namespace SpatialIndex +{ + class SIDX_DLL MovingRegion : public TimeRegion, public IEvolvingShape + { + using Region::getLow; + using Region::getHigh; + using TimeRegion::intersectsRegionInTime; + using TimeRegion::containsRegionInTime; + using TimeRegion::combineRegionInTime; + using TimeRegion::getCombinedRegionInTime; + using TimeRegion::containsPointInTime; + + public: + MovingRegion(); + MovingRegion( + const double* pLow, const double* pHigh, + const double* pVLow, const double* pVHigh, + const Tools::IInterval& ti, uint32_t dimension); + MovingRegion( + const double* pLow, const double* pHigh, + const double* pVLow, const double* pVHigh, + double tStart, double tEnd, uint32_t dimension); + MovingRegion( + const Point& low, const Point& high, + const Point& vlow, const Point& vhigh, + const Tools::IInterval& ti); + MovingRegion( + const Point& low, const Point& high, + const Point& vlow, const Point& vhigh, + double tStart, double tEnd); + MovingRegion(const Region& mbr, const Region& vbr, const Tools::IInterval& ivI); + MovingRegion(const Region& mbr, const Region& vbr, double tStart, double tEnd); + MovingRegion(const MovingPoint& low, const MovingPoint& high); + MovingRegion(const MovingRegion& in); + virtual ~MovingRegion(); + + virtual MovingRegion& operator=(const MovingRegion& r); + virtual bool operator==(const MovingRegion&) const; + + bool isShrinking() const; + + virtual double getLow(uint32_t index, double t) const; + virtual double getHigh(uint32_t index, double t) const; + virtual double getExtrapolatedLow(uint32_t index, double t) const; + virtual double getExtrapolatedHigh(uint32_t index, double t) const; + virtual double getVLow(uint32_t index) const; + virtual double getVHigh(uint32_t index) const; + + virtual bool intersectsRegionInTime(const MovingRegion& r) const; + virtual bool intersectsRegionInTime(const MovingRegion& r, Tools::IInterval& out) const; + virtual bool intersectsRegionInTime(const Tools::IInterval& ivI, const MovingRegion& r, Tools::IInterval& ret) const; + virtual bool containsRegionInTime(const MovingRegion& r) const; + virtual bool containsRegionInTime(const Tools::IInterval& ivI, const MovingRegion& r) const; + virtual bool containsRegionAfterTime(double t, const MovingRegion& r) const; + + virtual double getProjectedSurfaceAreaInTime() const; + virtual double getProjectedSurfaceAreaInTime(const Tools::IInterval& ivI) const; + + virtual double getCenterDistanceInTime(const MovingRegion& r) const; + virtual double getCenterDistanceInTime(const Tools::IInterval& ivI, const MovingRegion& r) const; + + virtual bool intersectsRegionAtTime(double t, const MovingRegion& r) const; + virtual bool containsRegionAtTime(double t, const MovingRegion& r) const; + + virtual bool intersectsPointInTime(const MovingPoint& p) const; + virtual bool intersectsPointInTime(const MovingPoint& p, Tools::IInterval& out) const; + virtual bool intersectsPointInTime(const Tools::IInterval& ivI, const MovingPoint& p, Tools::IInterval& out) const; + virtual bool containsPointInTime(const MovingPoint& p) const; + virtual bool containsPointInTime(const Tools::IInterval& ivI, const MovingPoint& p) const; + + //virtual bool intersectsPointAtTime(double t, const MovingRegion& in) const; + //virtual bool containsPointAtTime(double t, const MovingRegion& in) const; + + virtual void combineRegionInTime(const MovingRegion& r); + virtual void combineRegionAfterTime(double t, const MovingRegion& r); + virtual void getCombinedRegionInTime(MovingRegion& out, const MovingRegion& in) const; + virtual void getCombinedRegionAfterTime(double t, MovingRegion& out, const MovingRegion& in) const; + + virtual double getIntersectingAreaInTime(const MovingRegion& r) const; + virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const MovingRegion& r) const; + + // + // IObject interface + // + virtual MovingRegion* clone(); + + // + // ISerializable interface + // + virtual uint32_t getByteArraySize(); + virtual void loadFromByteArray(const byte* data); + virtual void storeToByteArray(byte** data, uint32_t& len); + + // + // IEvolvingShape interface + // + virtual void getVMBR(Region& out) const; + virtual void getMBRAtTime(double t, Region& out) const; + + // + // ITimeShape interface + // + virtual double getAreaInTime() const; + virtual double getAreaInTime(const Tools::IInterval& ivI) const; + virtual double getIntersectingAreaInTime(const ITimeShape& r) const; + virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const; + + virtual void makeInfinite(uint32_t dimension); + virtual void makeDimension(uint32_t dimension); + + private: + void initialize( + const double* pLow, const double* pHigh, + const double* pVLow, const double* pVHigh, + double tStart, double tEnd, uint32_t dimension); + + public: + class CrossPoint + { + public: + double m_t; + uint32_t m_dimension; + uint32_t m_boundary; + const MovingRegion* m_to; + + struct ascending: public std::binary_function<CrossPoint&, CrossPoint&, bool> + { + bool operator()(const CrossPoint& __x, const CrossPoint& __y) const { return __x.m_t > __y.m_t; } + }; + }; // CrossPoint + + public: + double* m_pVLow; + double* m_pVHigh; + + friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingRegion& r); + }; // MovingRegion + + typedef Tools::PoolPointer<MovingRegion> MovingRegionPtr; + SIDX_DLL std::ostream& operator<<(std::ostream& os, const MovingRegion& r); +} diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/Point.h b/builddir/spatialindex-1.8.5/include/spatialindex/Point.h new file mode 100644 index 0000000..bbfde20 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/Point.h @@ -0,0 +1,87 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2004, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +#include "tools/Tools.h" + +namespace SpatialIndex +{ + class SIDX_DLL Point : public Tools::IObject, public virtual IShape + { + public: + Point(); + Point(const double* pCoords, uint32_t dimension); + Point(const Point& p); + virtual ~Point(); + + virtual Point& operator=(const Point& p); + virtual bool operator==(const Point& p) const; + + // + // IObject interface + // + virtual Point* clone(); + + // + // ISerializable interface + // + virtual uint32_t getByteArraySize(); + virtual void loadFromByteArray(const byte* data); + virtual void storeToByteArray(byte** data, uint32_t& length); + + // + // IShape interface + // + virtual bool intersectsShape(const IShape& in) const; + virtual bool containsShape(const IShape& in) const; + virtual bool touchesShape(const IShape& in) const; + virtual void getCenter(Point& out) const; + virtual uint32_t getDimension() const; + virtual void getMBR(Region& out) const; + virtual double getArea() const; + virtual double getMinimumDistance(const IShape& in) const; + + virtual double getMinimumDistance(const Point& p) const; + + virtual double getCoordinate(uint32_t index) const; + + virtual void makeInfinite(uint32_t dimension); + virtual void makeDimension(uint32_t dimension); + + public: + uint32_t m_dimension; + double* m_pCoords; + + friend class Region; + friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const Point& pt); + }; // Point + + typedef Tools::PoolPointer<Point> PointPtr; + + SIDX_DLL std::ostream& operator<<(std::ostream& os, const Point& pt); +} diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/RTree.h b/builddir/spatialindex-1.8.5/include/spatialindex/RTree.h new file mode 100644 index 0000000..5aed0c5 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/RTree.h @@ -0,0 +1,108 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2004, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +namespace SpatialIndex +{ + namespace RTree + { + SIDX_DLL enum RTreeVariant + { + RV_LINEAR = 0x0, + RV_QUADRATIC, + RV_RSTAR + }; + + SIDX_DLL enum BulkLoadMethod + { + BLM_STR = 0x0 + }; + + SIDX_DLL enum PersistenObjectIdentifier + { + PersistentIndex = 0x1, + PersistentLeaf = 0x2 + }; + + SIDX_DLL enum RangeQueryType + { + ContainmentQuery = 0x1, + IntersectionQuery = 0x2 + }; + + class SIDX_DLL Data : public IData, public Tools::ISerializable + { + public: + Data(uint32_t len, byte* pData, Region& r, id_type id); + virtual ~Data(); + + virtual Data* clone(); + virtual id_type getIdentifier() const; + virtual void getShape(IShape** out) const; + virtual void getData(uint32_t& len, byte** data) const; + virtual uint32_t getByteArraySize(); + virtual void loadFromByteArray(const byte* data); + virtual void storeToByteArray(byte** data, uint32_t& len); + + id_type m_id; + Region m_region; + byte* m_pData; + uint32_t m_dataLength; + }; // Data + + SIDX_DLL ISpatialIndex* returnRTree(IStorageManager& ind, Tools::PropertySet& in); + SIDX_DLL ISpatialIndex* createNewRTree( + IStorageManager& sm, + double fillFactor, + uint32_t indexCapacity, + uint32_t leafCapacity, + uint32_t dimension, + RTreeVariant rv, + id_type& indexIdentifier + ); + SIDX_DLL ISpatialIndex* createAndBulkLoadNewRTree( + BulkLoadMethod m, + IDataStream& stream, + IStorageManager& sm, + double fillFactor, + uint32_t indexCapacity, + uint32_t leafCapacity, + uint32_t dimension, + RTreeVariant rv, + id_type& indexIdentifier + ); + SIDX_DLL ISpatialIndex* createAndBulkLoadNewRTree( + BulkLoadMethod m, + IDataStream& stream, + IStorageManager& sm, + Tools::PropertySet& ps, + id_type& indexIdentifier + ); + SIDX_DLL ISpatialIndex* loadRTree(IStorageManager& in, id_type indexIdentifier); + } +} diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/Region.h b/builddir/spatialindex-1.8.5/include/spatialindex/Region.h new file mode 100644 index 0000000..4cd459c --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/Region.h @@ -0,0 +1,106 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2004, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +namespace SpatialIndex +{ + class SIDX_DLL Region : public Tools::IObject, public virtual IShape + { + public: + Region(); + Region(const double* pLow, const double* pHigh, uint32_t dimension); + Region(const Point& low, const Point& high); + Region(const Region& in); + virtual ~Region(); + + virtual Region& operator=(const Region& r); + virtual bool operator==(const Region&) const; + + // + // IObject interface + // + virtual Region* clone(); + + // + // ISerializable interface + // + virtual uint32_t getByteArraySize(); + virtual void loadFromByteArray(const byte* data); + virtual void storeToByteArray(byte** data, uint32_t& length); + + // + // IShape interface + // + virtual bool intersectsShape(const IShape& in) const; + virtual bool containsShape(const IShape& in) const; + virtual bool touchesShape(const IShape& in) const; + virtual void getCenter(Point& out) const; + virtual uint32_t getDimension() const; + virtual void getMBR(Region& out) const; + virtual double getArea() const; + virtual double getMinimumDistance(const IShape& in) const; + + virtual bool intersectsRegion(const Region& in) const; + virtual bool containsRegion(const Region& in) const; + virtual bool touchesRegion(const Region& in) const; + virtual double getMinimumDistance(const Region& in) const; + + virtual bool intersectsLineSegment(const LineSegment& in) const; + + virtual bool containsPoint(const Point& in) const; + virtual bool touchesPoint(const Point& in) const; + virtual double getMinimumDistance(const Point& in) const; + + virtual Region getIntersectingRegion(const Region& r) const; + virtual double getIntersectingArea(const Region& in) const; + virtual double getMargin() const; + + virtual void combineRegion(const Region& in); + virtual void combinePoint(const Point& in); + virtual void getCombinedRegion(Region& out, const Region& in) const; + + virtual double getLow(uint32_t index) const; + virtual double getHigh(uint32_t index) const; + + virtual void makeInfinite(uint32_t dimension); + virtual void makeDimension(uint32_t dimension); + + private: + void initialize(const double* pLow, const double* pHigh, uint32_t dimension); + + public: + uint32_t m_dimension; + double* m_pLow; + double* m_pHigh; + + friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const Region& r); + }; // Region + + typedef Tools::PoolPointer<Region> RegionPtr; + SIDX_DLL std::ostream& operator<<(std::ostream& os, const Region& r); +} diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/SpatialIndex.h b/builddir/spatialindex-1.8.5/include/spatialindex/SpatialIndex.h new file mode 100644 index 0000000..5054ac4 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/SpatialIndex.h @@ -0,0 +1,261 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2003, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +#include "tools/Tools.h" + +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661922 +#endif + +namespace SpatialIndex +{ + class Point; + class LineSegment; + class Region; + + + typedef int64_t id_type; + + SIDX_DLL enum CommandType + { + CT_NODEREAD = 0x0, + CT_NODEDELETE, + CT_NODEWRITE + }; + + class SIDX_DLL InvalidPageException : public Tools::Exception + { + public: + InvalidPageException(id_type id); + virtual ~InvalidPageException() {} + virtual std::string what(); + + private: + std::string m_error; + }; // InvalidPageException + + // + // Interfaces + // + + class SIDX_DLL IShape : public Tools::ISerializable + { + public: + virtual bool intersectsShape(const IShape& in) const = 0; + virtual bool containsShape(const IShape& in) const = 0; + virtual bool touchesShape(const IShape& in) const = 0; + virtual void getCenter(Point& out) const = 0; + virtual uint32_t getDimension() const = 0; + virtual void getMBR(Region& out) const = 0; + virtual double getArea() const = 0; + virtual double getMinimumDistance(const IShape& in) const = 0; + virtual ~IShape() {} + }; // IShape + + class SIDX_DLL ITimeShape : public Tools::IInterval + { + public: + virtual bool intersectsShapeInTime(const ITimeShape& in) const = 0; + virtual bool intersectsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const = 0; + virtual bool containsShapeInTime(const ITimeShape& in) const = 0; + virtual bool containsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const = 0; + virtual bool touchesShapeInTime(const ITimeShape& in) const = 0; + virtual bool touchesShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const = 0; + virtual double getAreaInTime() const = 0; + virtual double getAreaInTime(const Tools::IInterval& ivI) const = 0; + virtual double getIntersectingAreaInTime(const ITimeShape& r) const = 0; + virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const = 0; + virtual ~ITimeShape() {} + }; // ITimeShape + + class SIDX_DLL IEvolvingShape + { + public: + virtual void getVMBR(Region& out) const = 0; + virtual void getMBRAtTime(double t, Region& out) const = 0; + virtual ~IEvolvingShape() {} + }; // IEvolvingShape + + class SIDX_DLL IEntry : public Tools::IObject + { + public: + virtual id_type getIdentifier() const = 0; + virtual void getShape(IShape** out) const = 0; + virtual ~IEntry() {} + }; // IEntry + + class SIDX_DLL INode : public IEntry, public Tools::ISerializable + { + public: + virtual uint32_t getChildrenCount() const = 0; + virtual id_type getChildIdentifier(uint32_t index) const = 0; + virtual void getChildData(uint32_t index, uint32_t& len, byte** data) const = 0; + virtual void getChildShape(uint32_t index, IShape** out) const = 0; + virtual uint32_t getLevel() const = 0; + virtual bool isIndex() const = 0; + virtual bool isLeaf() const = 0; + virtual ~INode() {} + }; // INode + + class SIDX_DLL IData : public IEntry + { + public: + virtual void getData(uint32_t& len, byte** data) const = 0; + virtual ~IData() {} + }; // IData + + class SIDX_DLL IDataStream : public Tools::IObjectStream + { + public: + virtual IData* getNext() = 0; + virtual ~IDataStream() {} + }; // IDataStream + + class SIDX_DLL ICommand + { + public: + virtual void execute(const INode& in) = 0; + virtual ~ICommand() {} + }; // ICommand + + class SIDX_DLL INearestNeighborComparator + { + public: + virtual double getMinimumDistance(const IShape& query, const IShape& entry) = 0; + virtual double getMinimumDistance(const IShape& query, const IData& data) = 0; + virtual ~INearestNeighborComparator() {} + }; // INearestNeighborComparator + + class SIDX_DLL IStorageManager + { + public: + virtual void loadByteArray(const id_type id, uint32_t& len, byte** data) = 0; + virtual void storeByteArray(id_type& id, const uint32_t len, const byte* const data) = 0; + virtual void deleteByteArray(const id_type id) = 0; + virtual void flush() = 0; + virtual ~IStorageManager() {} + }; // IStorageManager + + class SIDX_DLL IVisitor + { + public: + virtual void visitNode(const INode& in) = 0; + virtual void visitData(const IData& in) = 0; + virtual void visitData(std::vector<const IData*>& v) = 0; + virtual ~IVisitor() {} + }; // IVisitor + + class SIDX_DLL IQueryStrategy + { + public: + virtual void getNextEntry(const IEntry& previouslyFetched, id_type& nextEntryToFetch, bool& bFetchNextEntry) = 0; + virtual ~IQueryStrategy() {} + }; // IQueryStrategy + + class SIDX_DLL IStatistics + { + public: + virtual uint64_t getReads() const = 0; + virtual uint64_t getWrites() const = 0; + virtual uint32_t getNumberOfNodes() const = 0; + virtual uint64_t getNumberOfData() const = 0; + virtual ~IStatistics() {} + }; // IStatistics + + class SIDX_DLL ISpatialIndex + { + public: + virtual void insertData(uint32_t len, const byte* pData, const IShape& shape, id_type shapeIdentifier) = 0; + virtual bool deleteData(const IShape& shape, id_type shapeIdentifier) = 0; + virtual void containsWhatQuery(const IShape& query, IVisitor& v) = 0; + virtual void intersectsWithQuery(const IShape& query, IVisitor& v) = 0; + virtual void pointLocationQuery(const Point& query, IVisitor& v) = 0; + virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v, INearestNeighborComparator& nnc) = 0; + virtual void nearestNeighborQuery(uint32_t k, const IShape& query, IVisitor& v) = 0; + virtual void selfJoinQuery(const IShape& s, IVisitor& v) = 0; + virtual void queryStrategy(IQueryStrategy& qs) = 0; + virtual void getIndexProperties(Tools::PropertySet& out) const = 0; + virtual void addCommand(ICommand* in, CommandType ct) = 0; + virtual bool isIndexValid() = 0; + virtual void getStatistics(IStatistics** out) const = 0; + virtual ~ISpatialIndex() {} + + }; // ISpatialIndex + + namespace StorageManager + { + SIDX_DLL enum StorageManagerConstants + { + EmptyPage = -0x1, + NewPage = -0x1 + }; + + class SIDX_DLL IBuffer : public IStorageManager + { + public: + virtual uint64_t getHits() = 0; + virtual void clear() = 0; + virtual ~IBuffer() {} + }; // IBuffer + + SIDX_DLL IStorageManager* returnMemoryStorageManager(Tools::PropertySet& in); + SIDX_DLL IStorageManager* createNewMemoryStorageManager(); + + SIDX_DLL IStorageManager* returnDiskStorageManager(Tools::PropertySet& in); + SIDX_DLL IStorageManager* createNewDiskStorageManager(std::string& baseName, uint32_t pageSize); + SIDX_DLL IStorageManager* loadDiskStorageManager(std::string& baseName); + + SIDX_DLL IBuffer* returnRandomEvictionsBuffer(IStorageManager& ind, Tools::PropertySet& in); + SIDX_DLL IBuffer* createNewRandomEvictionsBuffer(IStorageManager& in, uint32_t capacity, bool bWriteThrough); + } + + // + // Global functions + // + SIDX_DLL std::ostream& operator<<(std::ostream&, const ISpatialIndex&); + SIDX_DLL std::ostream& operator<<(std::ostream&, const IStatistics&); +} + +#include "Point.h" +#include "Region.h" +#include "LineSegment.h" +#include "TimePoint.h" +#include "TimeRegion.h" +#include "MovingPoint.h" +#include "MovingRegion.h" +#include "RTree.h" +#include "MVRTree.h" +#include "TPRTree.h" +#include "Version.h" + + +// typedef SpatialIndex::Tools::PoolPointer<Region> RegionPtr; +// typedef SpatialIndex::Tools::PoolPointer<Point> PointPtr; +// typedef SpatialIndex::Tools::PoolPointer<TimeRegion> TimeRegionPtr; +// typedef SpatialIndex::Tools::PoolPointer<MovingRegion> MovingRegionPtr; diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/TPRTree.h b/builddir/spatialindex-1.8.5/include/spatialindex/TPRTree.h new file mode 100644 index 0000000..1f1b46b --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/TPRTree.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2003, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + + +#pragma once + +namespace SpatialIndex +{ + namespace TPRTree + { + SIDX_DLL enum TPRTreeVariant + { + TPRV_RSTAR = 0x2 + }; + + SIDX_DLL enum PersistenObjectIdentifier + { + PersistentIndex = 0x1, + PersistentLeaf = 0x2 + }; + + SIDX_DLL enum RangeQueryType + { + ContainmentQuery = 0x1, + IntersectionQuery = 0x2 + }; + + class SIDX_DLL Data : public IData, public Tools::ISerializable + { + public: + Data(uint32_t len, byte* pData, MovingRegion& r, id_type id); + virtual ~Data(); + + virtual Data* clone(); + virtual id_type getIdentifier() const; + virtual void getShape(IShape** out) const; + virtual void getData(uint32_t& len, byte** data) const; + virtual uint32_t getByteArraySize(); + virtual void loadFromByteArray(const byte* data); + virtual void storeToByteArray(byte** data, uint32_t& len); + + id_type m_id; + MovingRegion m_region; + byte* m_pData; + uint32_t m_dataLength; + }; // Data + + SIDX_DLL ISpatialIndex* returnTPRTree(IStorageManager& ind, Tools::PropertySet& in); + SIDX_DLL ISpatialIndex* createNewTPRTree( + IStorageManager& sm, + double fillFactor, + uint32_t indexCapacity, + uint32_t leafCapacity, + uint32_t dimension, + TPRTreeVariant rv, + double horizon, + id_type& indexIdentifier + ); + SIDX_DLL ISpatialIndex* loadTPRTree(IStorageManager& in, id_type indexIdentifier); + } +} diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/TimePoint.h b/builddir/spatialindex-1.8.5/include/spatialindex/TimePoint.h new file mode 100644 index 0000000..8332251 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/TimePoint.h @@ -0,0 +1,95 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2004, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +namespace SpatialIndex +{ + class SIDX_DLL TimePoint : public Point, public ITimeShape + { + public: + TimePoint(); + TimePoint(const double* pCoords, const Tools::IInterval& ti, uint32_t dimension); + TimePoint(const double* pCoords, double tStart, double tEnd, uint32_t dimension); + TimePoint(const Point& p, const Tools::IInterval& ti); + TimePoint(const Point& p, double tStart, double tEnd); + TimePoint(const TimePoint& p); + virtual ~TimePoint(); + + virtual TimePoint& operator=(const TimePoint& p); + virtual bool operator==(const TimePoint& p) const; + + // + // IObject interface + // + virtual TimePoint* clone(); + + // + // ISerializable interface + // + virtual uint32_t getByteArraySize(); + virtual void loadFromByteArray(const byte* data); + virtual void storeToByteArray(byte** data, uint32_t& len); + + // + // ITimeShape interface + // + virtual bool intersectsShapeInTime(const ITimeShape& in) const; + virtual bool intersectsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const; + virtual bool containsShapeInTime(const ITimeShape& in) const; + virtual bool containsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const; + virtual bool touchesShapeInTime(const ITimeShape& in) const; + virtual bool touchesShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const; + virtual double getAreaInTime() const; + virtual double getAreaInTime(const Tools::IInterval& ivI) const; + virtual double getIntersectingAreaInTime(const ITimeShape& r) const; + virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const; + + // + // IInterval interface + // + virtual Tools::IInterval& operator=(const Tools::IInterval&); + virtual double getLowerBound() const; + virtual double getUpperBound() const; + virtual void setBounds(double, double); + virtual bool intersectsInterval(const Tools::IInterval& ti) const; + virtual bool intersectsInterval(Tools::IntervalType t, const double start, const double end) const; + virtual bool containsInterval(const Tools::IInterval& ti) const; + virtual Tools::IntervalType getIntervalType() const; + + virtual void makeInfinite(uint32_t dimension); + virtual void makeDimension(uint32_t dimension); + + public: + double m_startTime; + double m_endTime; + + friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimePoint& pt); + }; // TimePoint + + SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimePoint& pt); +} diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/TimeRegion.h b/builddir/spatialindex-1.8.5/include/spatialindex/TimeRegion.h new file mode 100644 index 0000000..588b255 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/TimeRegion.h @@ -0,0 +1,109 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2003, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +namespace SpatialIndex +{ + class SIDX_DLL TimeRegion : public Region, public ITimeShape + { + public: + TimeRegion(); + TimeRegion(const double* pLow, const double* pHigh, const Tools::IInterval& ti, uint32_t dimension); + TimeRegion(const double* pLow, const double* pHigh, double tStart, double tEnd, uint32_t dimension); + TimeRegion(const Point& low, const Point& high, const Tools::IInterval& ti); + TimeRegion(const Point& low, const Point& high, double tStart, double tEnd); + TimeRegion(const Region& in, const Tools::IInterval& ti); + TimeRegion(const Region& in, double tStart, double tEnd); + TimeRegion(const TimePoint& low, const TimePoint& high); + TimeRegion(const TimeRegion& in); + virtual ~TimeRegion(); + + virtual TimeRegion& operator=(const TimeRegion& r); + virtual bool operator==(const TimeRegion&) const; + + virtual bool intersectsRegionInTime(const TimeRegion& in) const; + virtual bool containsRegionInTime(const TimeRegion& in) const; + virtual bool touchesRegionInTime(const TimeRegion& in) const; + + virtual bool containsPointInTime(const TimePoint& in) const; + virtual bool touchesPointInTime(const TimePoint& in) const; + + virtual void combineRegionInTime(const TimeRegion& in); + virtual void getCombinedRegionInTime(TimeRegion& out, const TimeRegion& in) const; + + // + // IObject interface + // + virtual TimeRegion* clone(); + + // + // ISerializable interface + // + virtual uint32_t getByteArraySize(); + virtual void loadFromByteArray(const byte* data); + virtual void storeToByteArray(byte** data, uint32_t& len); + + // + // ITimeShape interface + // + virtual bool intersectsShapeInTime(const ITimeShape& in) const; + virtual bool intersectsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const; + virtual bool containsShapeInTime(const ITimeShape& in) const; + virtual bool containsShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const; + virtual bool touchesShapeInTime(const ITimeShape& in) const; + virtual bool touchesShapeInTime(const Tools::IInterval& ivI, const ITimeShape& in) const; + virtual double getAreaInTime() const; + virtual double getAreaInTime(const Tools::IInterval& ivI) const; + virtual double getIntersectingAreaInTime(const ITimeShape& r) const; + virtual double getIntersectingAreaInTime(const Tools::IInterval& ivI, const ITimeShape& r) const; + + // + // IInterval interface + // + virtual Tools::IInterval& operator=(const Tools::IInterval&); + virtual double getLowerBound() const; + virtual double getUpperBound() const; + virtual void setBounds(double, double); + virtual bool intersectsInterval(const Tools::IInterval& ti) const; + virtual bool intersectsInterval(Tools::IntervalType t, const double start, const double end) const; + virtual bool containsInterval(const Tools::IInterval& ti) const; + virtual Tools::IntervalType getIntervalType() const; + + virtual void makeInfinite(uint32_t dimension); + virtual void makeDimension(uint32_t dimension); + + public: + double m_startTime; + double m_endTime; + + friend SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimeRegion& r); + }; // TimeRegion + + typedef Tools::PoolPointer<TimeRegion> TimeRegionPtr; + SIDX_DLL std::ostream& operator<<(std::ostream& os, const TimeRegion& r); +} diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/Version.h b/builddir/spatialindex-1.8.5/include/spatialindex/Version.h new file mode 100644 index 0000000..b937e65 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/Version.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2003, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +#ifndef SIDX_VERSION_MAJOR +#define SIDX_VERSION_MAJOR 1 +#define SIDX_VERSION_MINOR 8 +#define SIDX_VERSION_REV 5 +#define SIDX_VERSION_BUILD 0 +#endif + +#ifndef SIDX_VERSION_NUM +#define SIDX_VERSION_NUM (SIDX_VERSION_MAJOR*1000+SIDX_VERSION_MINOR*100+SIDX_VERSION_REV*10+SIDX_VERSION_BUILD) +#endif + +#ifndef SIDX_RELEASE_DATE +#define SIDX_RELEASE_DATE 20141101 +#endif + +#ifndef SIDX_RELEASE_NAME +#define SIDX_RELEASE_NAME "1.8.5" +#endif + diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/BoundsQuery.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/BoundsQuery.h new file mode 100644 index 0000000..79fdcb8 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/BoundsQuery.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C++ object declarations to implement the bounds query. + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2009, Howard Butler + * + * 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. +******************************************************************************/ + +#pragma once + +#include "sidx_export.h" + +class SIDX_DLL BoundsQuery : public SpatialIndex::IQueryStrategy +{ +private: + SpatialIndex::Region* m_bounds; + +public: + + BoundsQuery(); + ~BoundsQuery() { if (m_bounds != 0) delete m_bounds; } + void getNextEntry( const SpatialIndex::IEntry& entry, + SpatialIndex::id_type& nextEntry, + bool& hasNext); + + SpatialIndex::Region* GetBounds() const { return m_bounds; } +}; + diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/CountVisitor.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/CountVisitor.h new file mode 100644 index 0000000..eaaee8d --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/CountVisitor.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C++ objects to implement the count visitor. + * Author: Leonard Norrgård, leonard.norrgard@refactor.fi + ****************************************************************************** + * Copyright (c) 2010, Leonard Norrgård + * + * 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. +******************************************************************************/ + +#pragma once + +#include "sidx_export.h" + +class SIDX_DLL CountVisitor : public SpatialIndex::IVisitor +{ +private: + uint64_t nResults; + +public: + + CountVisitor(); + ~CountVisitor(); + + uint64_t GetResultCount() const { return nResults; } + + void visitNode(const SpatialIndex::INode& n); + void visitData(const SpatialIndex::IData& d); + void visitData(std::vector<const SpatialIndex::IData*>& v); +}; diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/CustomStorage.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/CustomStorage.h new file mode 100644 index 0000000..e54d12a --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/CustomStorage.h @@ -0,0 +1,84 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C++ object declarations to implement the custom storage manager. + * Author: Matthias (nitro), nitro@dr-code.org + ****************************************************************************** + * Copyright (c) 2010, Matthias (nitro) + * + * 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. +******************************************************************************/ + +#pragma once + +#include "sidx_export.h" + +namespace SpatialIndex +{ + namespace StorageManager + { + struct SIDX_DLL CustomStorageManagerCallbacks + { + CustomStorageManagerCallbacks() + : context(0) + , createCallback(0) + , destroyCallback(0) + , loadByteArrayCallback(0) + , storeByteArrayCallback(0) + , deleteByteArrayCallback(0) + {} + + void* context; + void (*createCallback)( const void* context, int* errorCode ); + void (*destroyCallback)( const void* context, int* errorCode ); + void (*flushCallback)( const void* context, int* errorCode ); + void (*loadByteArrayCallback)( const void* context, const id_type page, uint32_t* len, byte** data, int* errorCode ); + void (*storeByteArrayCallback)( const void* context, id_type* page, const uint32_t len, const byte* const data, int* errorCode ); + void (*deleteByteArrayCallback)( const void* context, const id_type page, int* errorCode ); + }; + + class SIDX_DLL CustomStorageManager : public SpatialIndex::IStorageManager + { + public: + // I'd like this to be an enum, but casting between enums and ints is not nice + static const int NoError = 0; + static const int InvalidPageError = 1; + static const int IllegalStateError = 2; + + CustomStorageManager(Tools::PropertySet&); + + virtual ~CustomStorageManager(); + + virtual void flush(); + virtual void loadByteArray(const id_type page, uint32_t& len, byte** data); + virtual void storeByteArray(id_type& page, const uint32_t len, const byte* const data); + virtual void deleteByteArray(const id_type page); + + private: + CustomStorageManagerCallbacks callbacks; + + inline void processErrorCode(int errorCode, const id_type page); + }; // CustomStorageManager + + // factory function + IStorageManager* returnCustomStorageManager(Tools::PropertySet& in); + } +} + diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/DataStream.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/DataStream.h new file mode 100644 index 0000000..f1ab0f2 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/DataStream.h @@ -0,0 +1,56 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: Declarations to support stream loading via C API + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2009, Howard Butler + * + * 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. +******************************************************************************/ + +#pragma once + +#include "sidx_export.h" + +class SIDX_DLL DataStream : public SpatialIndex::IDataStream +{ +public: + DataStream(int (*readNext)(SpatialIndex::id_type* id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, uint32_t *nDataLength)); + ~DataStream(); + + SpatialIndex::IData* getNext(); + bool hasNext(); + + uint32_t size(); + void rewind(); + +protected: + SpatialIndex::RTree::Data* m_pNext; + SpatialIndex::id_type m_id; + +private: + int (*iterfunct)(SpatialIndex::id_type *id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, uint32_t *nDataLength); + + bool readData(); + bool m_bDoneReading; + +}; + diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/Error.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/Error.h new file mode 100644 index 0000000..e8cc647 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/Error.h @@ -0,0 +1,54 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C++ object declarations to implement the error object. + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2009, Howard Butler + * + * 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. +******************************************************************************/ + +#pragma once + +#include "sidx_export.h" + +class SIDX_DLL Error +{ +public: + + Error(int code, std::string const& message, std::string const& method); + + /// Copy constructor. + Error(Error const& other); + + /// Assignment operator. + Error& operator=(Error const& rhs); + + int GetCode() const { return m_code; } + const char* GetMessage() const { return m_message.c_str(); } + const char* GetMethod() const { return m_method.c_str(); } + +private: + + int m_code; + std::string m_message; + std::string m_method; +}; diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/IdVisitor.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/IdVisitor.h new file mode 100644 index 0000000..9596805 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/IdVisitor.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C++ object declarations to implement a query ids only. + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2009, Howard Butler + * + * 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. +******************************************************************************/ + +#pragma once + +#include "sidx_export.h" + +class SIDX_DLL IdVisitor : public SpatialIndex::IVisitor +{ +private: + std::vector<uint64_t> m_vector; + uint64_t nResults; + +public: + + IdVisitor(); + ~IdVisitor(); + + uint64_t GetResultCount() const { return nResults; } + std::vector<uint64_t>& GetResults() { return m_vector; } + + void visitNode(const SpatialIndex::INode& n); + void visitData(const SpatialIndex::IData& d); + void visitData(std::vector<const SpatialIndex::IData*>& v); +}; diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/Index.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/Index.h new file mode 100644 index 0000000..879ec6e --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/Index.h @@ -0,0 +1,81 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C++ object declarations to implement the wrapper. + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2009, Howard Butler + * + * 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. +******************************************************************************/ + +#pragma once + +#include "sidx_export.h" + +class SIDX_DLL Index +{ + +public: + Index(const Tools::PropertySet& poProperties); + Index(const Tools::PropertySet& poProperties, int (*readNext)(SpatialIndex::id_type *id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, uint32_t *nDataLength)); + ~Index(); + + const Tools::PropertySet GetProperties() { index().getIndexProperties(m_properties); return m_properties;} + + bool insertFeature(uint64_t id, double *min, double *max); + + RTIndexType GetIndexType(); + void SetIndexType(RTIndexType v); + + RTStorageType GetIndexStorage(); + void SetIndexStorage(RTStorageType v); + + RTIndexVariant GetIndexVariant(); + void SetIndexVariant(RTStorageType v); + + int64_t GetResultSetOffset(); + void SetResultSetOffset(int64_t v); + + int64_t GetResultSetLimit(); + void SetResultSetLimit(int64_t v); + + void flush(); + + SpatialIndex::ISpatialIndex& index() {return *m_rtree;} + SpatialIndex::StorageManager::IBuffer& buffer() {return *m_buffer;} + +private: + + Index& operator=(const Index&); + Index(); + + void Initialize(); + SpatialIndex::IStorageManager* m_storage; + SpatialIndex::StorageManager::IBuffer* m_buffer; + SpatialIndex::ISpatialIndex* m_rtree; + + Tools::PropertySet m_properties; + + void Setup(); + SpatialIndex::IStorageManager* CreateStorage(); + SpatialIndex::StorageManager::IBuffer* CreateIndexBuffer(SpatialIndex::IStorageManager& storage); + SpatialIndex::ISpatialIndex* CreateIndex(); +}; diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/LeafQuery.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/LeafQuery.h new file mode 100644 index 0000000..9f30a0f --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/LeafQuery.h @@ -0,0 +1,73 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C++ object declarations to implement a query of the index's leaves. + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2009, Howard Butler + * + * 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. +******************************************************************************/ + +#pragma once + +#include "sidx_export.h" + +class LeafQueryResult; + +class SIDX_DLL LeafQuery : public SpatialIndex::IQueryStrategy +{ +private: + std::queue<SpatialIndex::id_type> m_ids; + std::vector<LeafQueryResult> m_results; +public: + + LeafQuery(); + ~LeafQuery() { } + void getNextEntry( const SpatialIndex::IEntry& entry, + SpatialIndex::id_type& nextEntry, + bool& hasNext); + std::vector<LeafQueryResult> const& GetResults() const {return m_results;} +}; + +class SIDX_DLL LeafQueryResult +{ +private: + std::vector<SpatialIndex::id_type> ids; + SpatialIndex::Region* bounds; + SpatialIndex::id_type m_id; + LeafQueryResult(); +public: + LeafQueryResult(SpatialIndex::id_type id) : bounds(0), m_id(id){} + ~LeafQueryResult() {if (bounds!=0) delete bounds;} + + /// Copy constructor. + LeafQueryResult(LeafQueryResult const& other); + + /// Assignment operator. + LeafQueryResult& operator=(LeafQueryResult const& rhs); + + std::vector<SpatialIndex::id_type> const& GetIDs() const; + void SetIDs(std::vector<SpatialIndex::id_type>& v); + const SpatialIndex::Region* GetBounds() const; + void SetBounds(const SpatialIndex::Region* b); + SpatialIndex::id_type getIdentifier() const {return m_id;} + void setIdentifier(uint32_t v) {m_id = v;} +}; diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/ObjVisitor.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/ObjVisitor.h new file mode 100644 index 0000000..2c27d5a --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/ObjVisitor.h @@ -0,0 +1,51 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C++ object declarations to implement the object visitor. + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2009, Howard Butler + * + * 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. +******************************************************************************/ + +#pragma once + +#include "sidx_export.h" + +class SIDX_DLL ObjVisitor : public SpatialIndex::IVisitor +{ +private: + std::vector<SpatialIndex::IData*> m_vector; + uint64_t nResults; + +public: + + ObjVisitor(); + ~ObjVisitor(); + + uint64_t GetResultCount() const { return nResults; } + std::vector<SpatialIndex::IData*>& GetResults() { return m_vector; } + + void visitNode(const SpatialIndex::INode& n); + void visitData(const SpatialIndex::IData& d); + void visitData(std::vector<const SpatialIndex::IData*>& v); +}; + diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/Utility.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/Utility.h new file mode 100644 index 0000000..9962ceb --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/Utility.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C++ object declarations to implement utilities. + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2009, Howard Butler + * + * 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. +******************************************************************************/ + +#include "ObjVisitor.h" +#include "IdVisitor.h" +#include "sidx_export.h" + +#pragma once + +SIDX_DLL Tools::PropertySet* GetDefaults(); + +SIDX_DLL void Page_ResultSet_Ids(IdVisitor& visitor, int64_t** ids, int64_t nStart, int64_t nResultLimit, uint64_t* nResults); +SIDX_DLL void Page_ResultSet_Obj(ObjVisitor& visitor, IndexItemH** items, int64_t nStart, int64_t nResultLimit, uint64_t* nResults); diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_api.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_api.h new file mode 100644 index 0000000..a912a9e --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_api.h @@ -0,0 +1,366 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C API. + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2009, Howard Butler + * + * 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. +******************************************************************************/ + +#ifndef SIDX_API_H_INCLUDED +#define SIDX_API_H_INCLUDED + +#define SIDX_C_API 1 + +#include "sidx_config.h" + +IDX_C_START + +SIDX_DLL IndexH Index_Create(IndexPropertyH properties); + +SIDX_DLL IndexH Index_CreateWithStream( IndexPropertyH properties, + int (*readNext)(int64_t *id, double **pMin, double **pMax, uint32_t *nDimension, const uint8_t **pData, size_t *nDataLength) + ); + +SIDX_DLL void Index_Destroy(IndexH index); +SIDX_DLL IndexPropertyH Index_GetProperties(IndexH index); + +SIDX_DLL RTError Index_DeleteData( IndexH index, + int64_t id, + double* pdMin, + double* pdMax, + uint32_t nDimension); + +SIDX_C_DLL RTError Index_DeleteTPData( IndexH index, + int64_t id, + double* pdMin, + double* pdMax, + double* pdVMin, + double* pdVMax, + double tStart, + double tEnd, + uint32_t nDimension + ); + +SIDX_C_DLL RTError Index_DeleteMVRData( IndexH index, + int64_t id, + double* pdMin, + double* pdMax, + double tStart, + double tEnd, + uint32_t nDimension + ); + +SIDX_DLL RTError Index_InsertData( IndexH index, + int64_t id, + double* pdMin, + double* pdMax, + uint32_t nDimension, + const uint8_t* pData, + size_t nDataLength); + +SIDX_C_DLL RTError Index_InsertTPData( IndexH index, + int64_t id, + double* pdMin, + double* pdMax, + double* pdVMin, + double* pdVMax, + double tStart, + double tEnd, + uint32_t nDimension, + const uint8_t* pData, + size_t nDataLength); + +SIDX_C_DLL RTError Index_InsertMVRData( IndexH index, + int64_t id, + double* pdMin, + double* pdMax, + double tStart, + double tEnd, + uint32_t nDimension, + const uint8_t* pData, + size_t nDataLength); + +SIDX_DLL uint32_t Index_IsValid(IndexH index); + +SIDX_C_DLL RTError Index_TPIntersects_obj( IndexH index, + double* pdMin, + double* pdMax, + double* pdVMin, + double* pdVMax, + double tStart, + double tEnd, + uint32_t nDimension, + IndexItemH** items, + uint64_t* nResults); + +SIDX_C_DLL RTError Index_MVRIntersects_obj( IndexH index, + double* pdMin, + double* pdMax, + double tStart, + double tEnd, + uint32_t nDimension, + IndexItemH** items, + uint64_t* nResults); + +SIDX_DLL RTError Index_Intersects_obj( IndexH index, + double* pdMin, + double* pdMax, + uint32_t nDimension, + IndexItemH** items, + uint64_t* nResults); + +SIDX_C_DLL RTError Index_TPIntersects_id( IndexH index, + double* pdMin, + double* pdMax, + double* pdVMin, + double* pdVMax, + double tStart, + double tEnd, + uint32_t nDimension, + int64_t** ids, + uint64_t* nResults); + +SIDX_C_DLL RTError Index_MVRIntersects_id( IndexH index, + double* pdMin, + double* pdMax, + double tStart, + double tEnd, + uint32_t nDimension, + int64_t** ids, + uint64_t* nResults); + +SIDX_DLL RTError Index_Intersects_id( IndexH index, + double* pdMin, + double* pdMax, + uint32_t nDimension, + int64_t** items, + uint64_t* nResults); + +SIDX_C_DLL RTError Index_TPIntersects_count( IndexH index, + double* pdMin, + double* pdMax, + double* pdVMin, + double* pdVMax, + double tStart, + double tEnd, + uint32_t nDimension, + uint64_t* nResults); + +SIDX_C_DLL RTError Index_MVRIntersects_count( IndexH index, + double* pdMin, + double* pdMax, + double tStart, + double tEnd, + uint32_t nDimension, + uint64_t* nResults); + +SIDX_DLL RTError Index_Intersects_count( IndexH index, + double* pdMin, + double* pdMax, + uint32_t nDimension, + uint64_t* nResults); + +SIDX_C_DLL RTError Index_TPNearestNeighbors_obj(IndexH index, + double* pdMin, + double* pdMax, + double* pdVMin, + double* pdVMax, + double tStart, + double tEnd, + uint32_t nDimension, + IndexItemH** items, + uint64_t* nResults); + +SIDX_C_DLL RTError Index_MVRNearestNeighbors_obj(IndexH index, + double* pdMin, + double* pdMax, + double tStart, + double tEnd, + uint32_t nDimension, + IndexItemH** items, + uint64_t* nResults); + +SIDX_DLL RTError Index_NearestNeighbors_obj(IndexH index, + double* pdMin, + double* pdMax, + uint32_t nDimension, + IndexItemH** items, + uint64_t* nResults); + +SIDX_C_DLL RTError Index_TPNearestNeighbors_id(IndexH index, + double* pdMin, + double* pdMax, + double* pdVMin, + double* pdVMax, + double tStart, + double tEnd, + uint32_t nDimension, + int64_t** ids, + uint64_t* nResults); + +SIDX_C_DLL RTError Index_MVRNearestNeighbors_id(IndexH index, + double* pdMin, + double* pdMax, + double tStart, + double tEnd, + uint32_t nDimension, + int64_t** ids, + uint64_t* nResults); + +SIDX_DLL RTError Index_NearestNeighbors_id( IndexH index, + double* pdMin, + double* pdMax, + uint32_t nDimension, + int64_t** items, + uint64_t* nResults); + +SIDX_DLL RTError Index_GetBounds( IndexH index, + double** ppdMin, + double** ppdMax, + uint32_t* nDimension); + + +SIDX_C_DLL RTError Index_GetLeaves( IndexH index, + uint32_t* nLeafNodes, + uint32_t** nLeafSizes, + int64_t** nLeafIDs, + int64_t*** nLeafChildIDs, + double*** pppdMin, + double*** pppdMax, + uint32_t* nDimension); + +SIDX_DLL RTError Index_SetResultSetOffset(IndexH index, int64_t value); +SIDX_DLL int64_t Index_GetResultSetOffset(IndexH index); + +SIDX_DLL RTError Index_SetResultSetLimit(IndexH index, int64_t value); +SIDX_DLL int64_t Index_GetResultSetLimit(IndexH index); + +SIDX_DLL void Index_DestroyObjResults(IndexItemH* results, uint32_t nResults); +SIDX_DLL void Index_ClearBuffer(IndexH index); +SIDX_DLL void Index_Free(void* object); +SIDX_DLL void Index_Flush(IndexH index); + +SIDX_DLL void IndexItem_Destroy(IndexItemH item); +SIDX_DLL int64_t IndexItem_GetID(IndexItemH item); + +SIDX_DLL RTError IndexItem_GetData(IndexItemH item, uint8_t** data, uint64_t* length); + +SIDX_DLL RTError IndexItem_GetBounds( IndexItemH item, + double** ppdMin, + double** ppdMax, + uint32_t* nDimension); + +SIDX_DLL IndexPropertyH IndexProperty_Create(); +SIDX_DLL void IndexProperty_Destroy(IndexPropertyH hProp); + +SIDX_DLL RTError IndexProperty_SetIndexType(IndexPropertyH iprop, RTIndexType value); +SIDX_DLL RTIndexType IndexProperty_GetIndexType(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetDimension(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetDimension(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetIndexVariant(IndexPropertyH iprop, RTIndexVariant value); +SIDX_DLL RTIndexVariant IndexProperty_GetIndexVariant(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetIndexStorage(IndexPropertyH iprop, RTStorageType value); +SIDX_DLL RTStorageType IndexProperty_GetIndexStorage(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetPagesize(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetPagesize(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetIndexCapacity(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetIndexCapacity(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetLeafCapacity(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetLeafCapacity(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetLeafPoolCapacity(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetLeafPoolCapacity(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetIndexPoolCapacity(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetIndexPoolCapacity(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetRegionPoolCapacity(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetRegionPoolCapacity(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetPointPoolCapacity(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetPointPoolCapacity(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetBufferingCapacity(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetBufferingCapacity(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetEnsureTightMBRs(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetEnsureTightMBRs(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetOverwrite(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetOverwrite(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetNearMinimumOverlapFactor(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetNearMinimumOverlapFactor(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetWriteThrough(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetWriteThrough(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetFillFactor(IndexPropertyH iprop, double value); +SIDX_DLL double IndexProperty_GetFillFactor(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetSplitDistributionFactor(IndexPropertyH iprop, double value); +SIDX_DLL double IndexProperty_GetSplitDistributionFactor(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetTPRHorizon(IndexPropertyH iprop, double value); +SIDX_DLL double IndexProperty_GetTPRHorizon(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetReinsertFactor(IndexPropertyH iprop, double value); +SIDX_DLL double IndexProperty_GetReinsertFactor(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetFileName(IndexPropertyH iprop, const char* value); +SIDX_DLL char* IndexProperty_GetFileName(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetFileNameExtensionDat(IndexPropertyH iprop, const char* value); +SIDX_DLL char* IndexProperty_GetFileNameExtensionDat(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetFileNameExtensionIdx(IndexPropertyH iprop, const char* value); +SIDX_DLL char* IndexProperty_GetFileNameExtensionIdx(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetCustomStorageCallbacksSize(IndexPropertyH iprop, uint32_t value); +SIDX_DLL uint32_t IndexProperty_GetCustomStorageCallbacksSize(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetCustomStorageCallbacks(IndexPropertyH iprop, const void* value); +SIDX_DLL void* IndexProperty_GetCustomStorageCallbacks(IndexPropertyH iprop); + +SIDX_DLL RTError IndexProperty_SetIndexID(IndexPropertyH iprop, int64_t value); +SIDX_DLL int64_t IndexProperty_GetIndexID(IndexPropertyH iprop); + +SIDX_C_DLL void* SIDX_NewBuffer(size_t bytes); +SIDX_C_DLL void SIDX_DeleteBuffer(void* buffer); + +SIDX_DLL RTError IndexProperty_SetResultSetLimit(IndexPropertyH iprop, uint64_t value); +SIDX_DLL uint64_t IndexProperty_GetResultSetLimit(IndexPropertyH iprop); + +SIDX_C_DLL char* SIDX_Version(); + +SIDX_C_DLL char* Error_GetLastErrorMsg(void); + +IDX_C_END + +#endif diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_config.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_config.h new file mode 100644 index 0000000..8f3764c --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_config.h @@ -0,0 +1,115 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C API configuration + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2009, Howard Butler + * + * 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. +******************************************************************************/ + +#ifndef SIDX_CONFIG_H_INCLUDED +#define SIDX_CONFIG_H_INCLUDED + + + +#ifdef _MSC_VER + +#if _MSC_VER <= 1500 + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; +#endif + + #include <windows.h> + #define STRDUP _strdup + #include <spatialindex/SpatialIndex.h> + #include <windows.h> + +#else + + #include <stdint.h> + #define SIDX_THREAD __thread + #include <spatialindex/SpatialIndex.h> + #define STRDUP strdup +#endif + +#include <sys/stat.h> + +#include "sidx_export.h" + +class Item; +class Index; + +typedef enum +{ + RT_None = 0, + RT_Debug = 1, + RT_Warning = 2, + RT_Failure = 3, + RT_Fatal = 4 +} RTError; + +typedef enum +{ + RT_RTree = 0, + RT_MVRTree = 1, + RT_TPRTree = 2, + RT_InvalidIndexType = -99 +} RTIndexType; + +typedef enum +{ + RT_Memory = 0, + RT_Disk = 1, + RT_Custom = 2, + RT_InvalidStorageType = -99 +} RTStorageType; + +typedef enum +{ + RT_Linear = 0, + RT_Quadratic = 1, + RT_Star = 2, + RT_InvalidIndexVariant = -99 +} RTIndexVariant; + + +#ifdef __cplusplus +# define IDX_C_START extern "C" { +# define IDX_C_END } +#else +# define IDX_C_START +# define IDX_C_END +#endif + +typedef Index *IndexH; +typedef SpatialIndex::IData *IndexItemH; +typedef Tools::PropertySet *IndexPropertyH; + + + +#endif diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_export.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_export.h new file mode 100644 index 0000000..b6c84f1 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_export.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C++ object declarations to implement utilities. + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2014, Howard Butler + * + * 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. +******************************************************************************/ + +#pragma once + +#ifndef SIDX_C_DLL +#if defined(_MSC_VER) +# define SIDX_C_DLL __declspec(dllexport) +# define SIDX_DLL __declspec(dllexport) +#else +# if defined(USE_GCC_VISIBILITY_FLAG) +# define SIDX_C_DLL __attribute__ ((visibility("default"))) +# define SIDX_DLL __attribute__ ((visibility("default"))) +# else +# define SIDX_C_DLL +# define SIDX_DLL +# endif +#endif +#endif diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_impl.h b/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_impl.h new file mode 100644 index 0000000..a52c565 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/capi/sidx_impl.h @@ -0,0 +1,46 @@ +/****************************************************************************** + * Project: libsidx - A C API wrapper around libspatialindex + * Purpose: C++ object declarations to implement utilities. + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2009, Howard Butler + * + * 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. +******************************************************************************/ + +#include <stack> +#include <string> +#include <vector> +#include <stdexcept> +#include <sstream> +#include <cstring> + +#include "sidx_config.h" +#include "Utility.h" +#include "ObjVisitor.h" +#include "IdVisitor.h" +#include "CountVisitor.h" +#include "BoundsQuery.h" +#include "LeafQuery.h" +#include "Error.h" +#include "DataStream.h" +#include "Index.h" +#include "CustomStorage.h" diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/tools/PointerPool.h b/builddir/spatialindex-1.8.5/include/spatialindex/tools/PointerPool.h new file mode 100644 index 0000000..fde44bc --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/tools/PointerPool.h @@ -0,0 +1,123 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2004, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +#include "PoolPointer.h" + +namespace Tools +{ + template <class X> class PointerPool + { + public: + explicit PointerPool(uint32_t capacity) : m_capacity(capacity) + { + #ifndef NDEBUG + m_hits = 0; + m_misses = 0; + m_pointerCount = 0; + #endif + } + + ~PointerPool() + { + assert(m_pool.size() <= m_capacity); + + while (! m_pool.empty()) + { + X* x = m_pool.top(); m_pool.pop(); + #ifndef NDEBUG + --m_pointerCount; + #endif + delete x; + } + + #ifndef NDEBUG + std::cerr << "Lost pointers: " << m_pointerCount << std::endl; + #endif + } + + PoolPointer<X> acquire() + { + X* p = 0; + + if (! m_pool.empty()) + { + p = m_pool.top(); m_pool.pop(); + #ifndef NDEBUG + m_hits++; + #endif + } + else + { + p = new X(); + #ifndef NDEBUG + m_pointerCount++; + m_misses++; + #endif + } + + return PoolPointer<X>(p, this); + } + + void release(X* p) + { + if (m_pool.size() < m_capacity) + { + m_pool.push(p); + } + else + { + #ifndef NDEBUG + --m_pointerCount; + #endif + delete p; + } + + assert(m_pool.size() <= m_capacity); + } + + uint32_t getCapacity() const { return m_capacity; } + void setCapacity(uint32_t c) + { + assert (c >= 0); + m_capacity = c; + } + + private: + uint32_t m_capacity; + std::stack<X*> m_pool; + + #ifndef NDEBUG + public: + uint64_t m_hits; + uint64_t m_misses; + uint64_t m_pointerCount; + #endif + }; +} + diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/tools/PoolPointer.h b/builddir/spatialindex-1.8.5/include/spatialindex/tools/PoolPointer.h new file mode 100644 index 0000000..c7c2caf --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/tools/PoolPointer.h @@ -0,0 +1,102 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2004, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +#include "PointerPool.h" + +namespace Tools +{ + template <class X> class PointerPool; + + template <class X> class PoolPointer + { + public: + explicit PoolPointer(X* p = 0) : m_pointer(p), m_pPool(0) { m_prev = m_next = this; } + explicit PoolPointer(X* p, PointerPool<X>* pPool) throw() : m_pointer(p), m_pPool(pPool) { m_prev = m_next = this; } + ~PoolPointer() { release(); } + PoolPointer(const PoolPointer& p) throw() { acquire(p); } + PoolPointer& operator=(const PoolPointer& p) + { + if (this != &p) + { + release(); + acquire(p); + } + return *this; + } + + X& operator*() const throw() { return *m_pointer; } + X* operator->() const throw() { return m_pointer; } + X* get() const throw() { return m_pointer; } + bool unique() const throw() { return m_prev ? m_prev == this : true; } + void relinquish() throw() + { + m_pPool = 0; + m_pointer = 0; + release(); + } + + private: + X* m_pointer; + mutable const PoolPointer* m_prev; + mutable const PoolPointer* m_next; + PointerPool<X>* m_pPool; + + void acquire(const PoolPointer& p) throw() + { + m_pPool = p.m_pPool; + m_pointer = p.m_pointer; + m_next = p.m_next; + m_next->m_prev = this; + m_prev = &p; + #ifndef mutable + p.m_next = this; + #else + (const_cast<linked_ptr<X>*>(&p))->m_next = this; + #endif + } + + void release() + { + if (unique()) + { + if (m_pPool != 0) m_pPool->release(m_pointer); + else delete m_pointer; + } + else + { + m_prev->m_next = m_next; + m_next->m_prev = m_prev; + m_prev = m_next = 0; + } + m_pointer = 0; + m_pPool = 0; + } + }; +} + diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/tools/SmartPointer.h b/builddir/spatialindex-1.8.5/include/spatialindex/tools/SmartPointer.h new file mode 100644 index 0000000..9a5c2cc --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/tools/SmartPointer.h @@ -0,0 +1,84 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2004, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + +namespace Tools +{ + template <class X> class SmartPointer + { + public: + explicit SmartPointer(X* p = 0) throw() : m_pointer(p) { m_prev = m_next = this; } + ~SmartPointer() { release(); } + SmartPointer(const SmartPointer& p) throw() { acquire(p); } + SmartPointer& operator=(const SmartPointer& p) + { + if (this != &p) + { + release(); + acquire(p); + } + return *this; + } + + X& operator*() const throw() { return *m_pointer; } + X* operator->() const throw() { return m_pointer; } + X* get() const throw() { return m_pointer; } + bool unique() const throw() { return m_prev ? m_prev == this : true; } + + private: + X* m_pointer; + mutable const SmartPointer* m_prev; + mutable const SmartPointer* m_next; + + void acquire(const SmartPointer& p) throw() + { + m_pointer = p.m_pointer; + m_next = p.m_next; + m_next->m_prev = this; + m_prev = &p; + #ifndef mutable + p.m_next = this; + #else + (const_cast<linked_ptr<X>*>(&p))->m_next = this; + #endif + } + + void release() + { + if (unique()) delete m_pointer; + else + { + m_prev->m_next = m_next; + m_next->m_prev = m_prev; + m_prev = m_next = 0; + } + m_pointer = 0; + } + }; +} + diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/tools/Tools.h b/builddir/spatialindex-1.8.5/include/spatialindex/tools/Tools.h new file mode 100644 index 0000000..cd18d12 --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/tools/Tools.h @@ -0,0 +1,507 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Marios Hadjieleftheriou, mhadji@gmail.com + ****************************************************************************** + * Copyright (c) 2004, Marios Hadjieleftheriou + * + * 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. +******************************************************************************/ + +#pragma once + + +#if (defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64) && !defined __GNUC__ + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + +// Nuke this annoying warning. See http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html +#pragma warning( disable: 4251 ) + +#else + #include <stdint.h> +#endif + +#if (defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64) && !defined __GNUC__ + #ifdef SPATIALINDEX_CREATE_DLL + #define SIDX_DLL __declspec(dllexport) + #else + #define SIDX_DLL __declspec(dllimport) + #endif +#else + #define SIDX_DLL +#endif + +#include <assert.h> +#include <iostream> +#include <iomanip> +#include <iterator> +#include <string> +#include <sstream> +#include <fstream> +#include <queue> +#include <vector> +#include <map> +#include <set> +#include <stack> +#include <list> +#include <algorithm> +#include <cwchar> + +#if HAVE_PTHREAD_H + #include <pthread.h> +#endif + +#include "SmartPointer.h" +#include "PointerPool.h" +#include "PoolPointer.h" + +typedef uint8_t byte; + +namespace Tools +{ + SIDX_DLL enum IntervalType + { + IT_RIGHTOPEN = 0x0, + IT_LEFTOPEN, + IT_OPEN, + IT_CLOSED + }; + + SIDX_DLL enum VariantType + { + VT_LONG = 0x0, + VT_BYTE, + VT_SHORT, + VT_FLOAT, + VT_DOUBLE, + VT_CHAR, + VT_USHORT, + VT_ULONG, + VT_INT, + VT_UINT, + VT_BOOL, + VT_PCHAR, + VT_PVOID, + VT_EMPTY, + VT_LONGLONG, + VT_ULONGLONG, + VT_PWCHAR + }; + + SIDX_DLL enum FileMode + { + APPEND = 0x0, + CREATE + }; + + // + // Exceptions + // + class SIDX_DLL Exception + { + public: + virtual std::string what() = 0; + virtual ~Exception() {} + }; + + class SIDX_DLL IndexOutOfBoundsException : public Exception + { + public: + IndexOutOfBoundsException(size_t i); + virtual ~IndexOutOfBoundsException() {} + virtual std::string what(); + + private: + std::string m_error; + }; // IndexOutOfBoundsException + + class SIDX_DLL IllegalArgumentException : public Exception + { + public: + IllegalArgumentException(std::string s); + virtual ~IllegalArgumentException() {} + virtual std::string what(); + + private: + std::string m_error; + }; // IllegalArgumentException + + class SIDX_DLL IllegalStateException : public Exception + { + public: + IllegalStateException(std::string s); + virtual ~IllegalStateException() {} + virtual std::string what(); + + private: + std::string m_error; + }; // IllegalStateException + + class SIDX_DLL EndOfStreamException : public Exception + { + public: + EndOfStreamException(std::string s); + virtual ~EndOfStreamException() {} + virtual std::string what(); + + private: + std::string m_error; + }; // EndOfStreamException + + class SIDX_DLL ResourceLockedException : public Exception + { + public: + ResourceLockedException(std::string s); + virtual ~ResourceLockedException() {} + virtual std::string what(); + + private: + std::string m_error; + }; // ResourceLockedException + + class SIDX_DLL NotSupportedException : public Exception + { + public: + NotSupportedException(std::string s); + virtual ~NotSupportedException() {} + virtual std::string what(); + + private: + std::string m_error; + }; // NotSupportedException + + // + // Interfaces + // + class SIDX_DLL IInterval + { + public: + virtual ~IInterval() {} + + virtual double getLowerBound() const = 0; + virtual double getUpperBound() const = 0; + virtual void setBounds(double, double) = 0; + virtual bool intersectsInterval(const IInterval&) const = 0; + virtual bool intersectsInterval(IntervalType type, const double start, const double end) const = 0; + virtual bool containsInterval(const IInterval&) const = 0; + virtual IntervalType getIntervalType() const = 0; + }; // IInterval + + class SIDX_DLL IObject + { + public: + virtual ~IObject() {} + + virtual IObject* clone() = 0; + // return a new object that is an exact copy of this one. + // IMPORTANT: do not return the this pointer! + }; // IObject + + class SIDX_DLL ISerializable + { + public: + virtual ~ISerializable() {} + + virtual uint32_t getByteArraySize() = 0; + // returns the size of the required byte array. + virtual void loadFromByteArray(const byte* data) = 0; + // load this object using the byte array. + virtual void storeToByteArray(byte** data, uint32_t& length) = 0; + // store this object in the byte array. + }; + + class SIDX_DLL IComparable + { + public: + virtual ~IComparable() {} + + virtual bool operator<(const IComparable& o) const = 0; + virtual bool operator>(const IComparable& o) const = 0; + virtual bool operator==(const IComparable& o) const = 0; + }; //IComparable + + class SIDX_DLL IObjectComparator + { + public: + virtual ~IObjectComparator() {} + + virtual int compare(IObject* o1, IObject* o2) = 0; + }; // IObjectComparator + + class SIDX_DLL IObjectStream + { + public: + virtual ~IObjectStream() {} + + virtual IObject* getNext() = 0; + // returns a pointer to the next entry in the + // stream or 0 at the end of the stream. + + virtual bool hasNext() = 0; + // returns true if there are more items in the stream. + + virtual uint32_t size() = 0; + // returns the total number of entries available in the stream. + + virtual void rewind() = 0; + // sets the stream pointer to the first entry, if possible. + }; // IObjectStream + + // + // Classes & Functions + // + + class SIDX_DLL Variant + { + public: + Variant(); + + VariantType m_varType; + + union + { + int16_t iVal; // VT_SHORT + int32_t lVal; // VT_LONG + int64_t llVal; // VT_LONGLONG + byte bVal; // VT_BYTE + float fltVal; // VT_FLOAT + double dblVal; // VT_DOUBLE + char cVal; // VT_CHAR + uint16_t uiVal; // VT_USHORT + uint32_t ulVal; // VT_ULONG + uint64_t ullVal; // VT_ULONGLONG + bool blVal; // VT_BOOL + char* pcVal; // VT_PCHAR + void* pvVal; // VT_PVOID + wchar_t* pwcVal; + } m_val; + }; // Variant + + class SIDX_DLL PropertySet; + SIDX_DLL std::ostream& operator<<(std::ostream& os, const Tools::PropertySet& p); + + class SIDX_DLL PropertySet : public ISerializable + { + public: + PropertySet(); + PropertySet(const byte* data); + virtual ~PropertySet(); + + Variant getProperty(std::string property) const; + void setProperty(std::string property, Variant const& v); + void removeProperty(std::string property); + + virtual uint32_t getByteArraySize(); + virtual void loadFromByteArray(const byte* data); + virtual void storeToByteArray(byte** data, uint32_t& length); + + private: + std::map<std::string, Variant> m_propertySet; +// #ifdef HAVE_PTHREAD_H +// pthread_rwlock_t m_rwLock; +// #else +// bool m_rwLock; +// #endif + friend SIDX_DLL std::ostream& Tools::operator<<(std::ostream& os, const Tools::PropertySet& p); + }; // PropertySet + + // does not support degenerate intervals. + class SIDX_DLL Interval : public IInterval + { + public: + Interval(); + Interval(IntervalType, double, double); + Interval(double, double); + Interval(const Interval&); + virtual ~Interval() {} + virtual IInterval& operator=(const IInterval&); + + virtual bool operator==(const Interval&) const; + virtual bool operator!=(const Interval&) const; + virtual double getLowerBound() const; + virtual double getUpperBound() const; + virtual void setBounds(double, double); + virtual bool intersectsInterval(const IInterval&) const; + virtual bool intersectsInterval(IntervalType type, const double start, const double end) const; + virtual bool containsInterval(const IInterval&) const; + virtual IntervalType getIntervalType() const; + + IntervalType m_type; + double m_low; + double m_high; + }; // Interval + + SIDX_DLL std::ostream& operator<<(std::ostream& os, const Tools::Interval& iv); + + class SIDX_DLL Random + { + public: + Random(); + Random(uint32_t seed, uint16_t xsubi0); + virtual ~Random(); + + int32_t nextUniformLong(); + // returns a uniformly distributed long. + uint32_t nextUniformUnsignedLong(); + // returns a uniformly distributed unsigned long. + int32_t nextUniformLong(int32_t low, int32_t high); + // returns a uniformly distributed long in the range [low, high). + uint32_t nextUniformUnsignedLong(uint32_t low, uint32_t high); + // returns a uniformly distributed unsigned long in the range [low, high). + int64_t nextUniformLongLong(); + // returns a uniformly distributed long long. + uint64_t nextUniformUnsignedLongLong(); + // returns a uniformly distributed unsigned long long. + int64_t nextUniformLongLong(int64_t low, int64_t high); + // returns a uniformly distributed unsigned long long in the range [low, high). + uint64_t nextUniformUnsignedLongLong(uint64_t low, uint64_t high); + // returns a uniformly distributed unsigned long long in the range [low, high). + int16_t nextUniformShort(); + // returns a uniformly distributed short. + uint16_t nextUniformUnsignedShort(); + // returns a uniformly distributed unsigned short. + double nextUniformDouble(); + // returns a uniformly distributed double in the range [0, 1). + double nextUniformDouble(double low, double high); + // returns a uniformly distributed double in the range [low, high). + + bool flipCoin(); + + private: + void initDrand(uint32_t seed, uint16_t xsubi0); + + uint16_t* m_pBuffer; + }; // Random + + #if HAVE_PTHREAD_H + class SIDX_DLL LockGuard + { + public: + LockGuard(pthread_mutex_t* pLock); + ~LockGuard(); + + private: + pthread_mutex_t* m_pLock; + }; // LockGuard + #endif + + class SIDX_DLL BufferedFile + { + public: + BufferedFile(uint32_t u32BufferSize = 16384); + virtual ~BufferedFile(); + + virtual void close(); + virtual bool eof(); + virtual void rewind() = 0; + virtual void seek(std::fstream::off_type offset) = 0; + + protected: + std::fstream m_file; + char* m_buffer; + uint32_t m_u32BufferSize; + bool m_bEOF; + }; + + class SIDX_DLL BufferedFileReader : public BufferedFile + { + public: + BufferedFileReader(); + BufferedFileReader(const std::string& sFileName, uint32_t u32BufferSize = 32768); + virtual ~BufferedFileReader(); + + virtual void open(const std::string& sFileName); + virtual void rewind(); + virtual void seek(std::fstream::off_type offset); + + virtual uint8_t readUInt8(); + virtual uint16_t readUInt16(); + virtual uint32_t readUInt32(); + virtual uint64_t readUInt64(); + virtual float readFloat(); + virtual double readDouble(); + virtual bool readBoolean(); + virtual std::string readString(); + virtual void readBytes(uint32_t u32Len, byte** pData); + }; + + class SIDX_DLL BufferedFileWriter : public BufferedFile + { + public: + BufferedFileWriter(); + BufferedFileWriter(const std::string& sFileName, FileMode mode = CREATE, uint32_t u32BufferSize = 32768); + virtual ~BufferedFileWriter(); + + virtual void open(const std::string& sFileName, FileMode mode = CREATE); + virtual void rewind(); + virtual void seek(std::fstream::off_type offset); + + virtual void write(uint8_t i); + virtual void write(uint16_t i); + virtual void write(uint32_t i); + virtual void write(uint64_t i); + virtual void write(float i); + virtual void write(double i); + virtual void write(bool b); + virtual void write(const std::string& s); + virtual void write(uint32_t u32Len, byte* pData); + }; + + class SIDX_DLL TemporaryFile + { + public: + TemporaryFile(); + virtual ~TemporaryFile(); + + void rewindForReading(); + void rewindForWriting(); + bool eof(); + std::string getFileName() const; + + uint8_t readUInt8(); + uint16_t readUInt16(); + uint32_t readUInt32(); + uint64_t readUInt64(); + float readFloat(); + double readDouble(); + std::string readString(); + void readBytes(uint32_t u32Len, byte** pData); + + void write(uint8_t i); + void write(uint16_t i); + void write(uint32_t i); + void write(uint64_t i); + void write(float i); + void write(double i); + void write(const std::string& s); + void write(uint32_t u32Len, byte* pData); + + private: + std::string m_sFile; + BufferedFile* m_pFile; + }; +} diff --git a/builddir/spatialindex-1.8.5/include/spatialindex/tools/rand48.h b/builddir/spatialindex-1.8.5/include/spatialindex/tools/rand48.h new file mode 100644 index 0000000..f9cf2bb --- /dev/null +++ b/builddir/spatialindex-1.8.5/include/spatialindex/tools/rand48.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * Project: libspatialindex - A C++ library for spatial indexing + * Author: Howard Butler, hobu.inc@gmail.com + ****************************************************************************** + * Copyright (c) 2011, Howard Butler + * + * 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. +******************************************************************************/ + + +#pragma once + +/* Only define this stuff if we're not ANDROID */ +#ifndef ANDROID + +#ifndef HAVE_SRAND48 + +#if HAVE_FEATURES_H +#include <features.h> +#ifndef __THROW +/* copy-pasted from sys/cdefs.h */ +/* GCC can always grok prototypes. For C++ programs we add throw() +to help it optimize the function calls. But this works only with +gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions +as non-throwing using a function attribute since programs can use +the -fexceptions options for C code as well. */ +# if !defined __cplusplus && __GNUC_PREREQ (3, 3) +# define __THROW __attribute__ ((__nothrow__)) +# define __NTH(fct) __attribute__ ((__nothrow__)) fct +# else +# if defined __cplusplus && __GNUC_PREREQ (2,8) +# define __THROW throw () +# define __NTH(fct) fct throw () +# else +# define __THROW +# define __NTH(fct) fct +# endif +# endif + +#endif +#else +# define __THROW +# define __NTH(fct) fct +#endif + +extern void srand48(long int seed) __THROW; + +extern unsigned short *seed48(unsigned short xseed[3]) __THROW; + +extern long nrand48(unsigned short xseed[3]) __THROW; + +extern long mrand48(void) __THROW; + +extern long lrand48(void) __THROW; + +extern void lcong48(unsigned short p[7]) __THROW; + +extern long jrand48(unsigned short xseed[3]) __THROW; + +extern double erand48(unsigned short xseed[3]) __THROW; + +extern double drand48(void) __THROW; + +#endif + +/* Only define this stuff if we're not ANDROID */ +#endif \ No newline at end of file diff --git a/builddir/sqlite-3.15.2/bin/sqlite3.lib b/builddir/sqlite-3.15.2/bin/sqlite3.lib new file mode 100644 index 0000000..df3bde4 Binary files /dev/null and b/builddir/sqlite-3.15.2/bin/sqlite3.lib differ diff --git a/builddir/sqlite-3.15.2/include/sqlite3.h b/builddir/sqlite-3.15.2/include/sqlite3.h new file mode 100644 index 0000000..8222b79 --- /dev/null +++ b/builddir/sqlite-3.15.2/include/sqlite3.h @@ -0,0 +1,10371 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve the right to make minor changes +** if experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are supposed to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +*/ +#ifndef SQLITE3_H +#define SQLITE3_H +#include <stdarg.h> /* Needed for the definition of va_list */ + +/* +** Make sure we can call this stuff from C++. +*/ +#ifdef __cplusplus +extern "C" { +#endif + + +/* +** Provide the ability to override linkage features of the interface. +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif +#ifndef SQLITE_API +# define SQLITE_API +#endif +#ifndef SQLITE_CDECL +# define SQLITE_CDECL +#endif +#ifndef SQLITE_APICALL +# define SQLITE_APICALL +#endif +#ifndef SQLITE_STDCALL +# define SQLITE_STDCALL SQLITE_APICALL +#endif +#ifndef SQLITE_CALLBACK +# define SQLITE_CALLBACK +#endif +#ifndef SQLITE_SYSAPI +# define SQLITE_SYSAPI +#endif + +/* +** These no-op macros are used in front of interfaces to mark those +** interfaces as either deprecated or experimental. New applications +** should not use deprecated interfaces - they are supported for backwards +** compatibility only. Application writers should be aware that +** experimental interfaces are subject to change in point releases. +** +** These macros used to resolve to various kinds of compiler magic that +** would generate warning messages when they were used. But that +** compiler magic ended up generating such a flurry of bug reports +** that we have taken it all out and gone back to using simple +** noop macros. +*/ +#define SQLITE_DEPRECATED +#define SQLITE_EXPERIMENTAL + +/* +** Ensure these symbols were not defined by some previous header file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header +** evaluates to a string literal that is the SQLite version in the +** format "X.Y.Z" where X is the major version number (always 3 for +** SQLite3) and Y is the minor version number and Z is the release number.)^ +** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer +** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same +** numbers used in [SQLITE_VERSION].)^ +** The SQLITE_VERSION_NUMBER for any given release of SQLite will also +** be larger than the release from which it is derived. Either Y will +** be held constant and Z will be incremented or else Y will be incremented +** and Z will be reset to zero. +** +** Since [version 3.6.18] ([dateof:3.6.18]), +** SQLite source code has been stored in the +** <a href="http://www.fossil-scm.org/">Fossil configuration management +** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to +** a string which identifies a particular check-in of SQLite +** within its configuration management system. ^The SQLITE_SOURCE_ID +** string contains the date and time of the check-in (UTC) and an SHA1 +** hash of the entire source tree. +** +** See also: [sqlite3_libversion()], +** [sqlite3_libversion_number()], [sqlite3_sourceid()], +** [sqlite_version()] and [sqlite_source_id()]. +*/ +#define SQLITE_VERSION "3.15.2" +#define SQLITE_VERSION_NUMBER 3015002 +#define SQLITE_SOURCE_ID "2016-11-28 19:13:37 bbd85d235f7037c6a033a9690534391ffeacecc8" + +/* +** CAPI3REF: Run-Time Library Version Numbers +** KEYWORDS: sqlite3_version, sqlite3_sourceid +** +** These interfaces provide the same information as the [SQLITE_VERSION], +** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros +** but are associated with the library instead of the header file. ^(Cautious +** programmers might include assert() statements in their application to +** verify that values returned by these interfaces match the macros in +** the header, and thus ensure that the application is +** compiled with matching library and header files. +** +** <blockquote><pre> +** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER ); +** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 ); +** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 ); +** </pre></blockquote>)^ +** +** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION] +** macro. ^The sqlite3_libversion() function returns a pointer to the +** to the sqlite3_version[] string constant. The sqlite3_libversion() +** function is provided for use in DLLs since DLL users usually do not have +** direct access to string constants within the DLL. ^The +** sqlite3_libversion_number() function returns an integer equal to +** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns +** a pointer to a string constant whose value is the same as the +** [SQLITE_SOURCE_ID] C preprocessor macro. +** +** See also: [sqlite_version()] and [sqlite_source_id()]. +*/ +SQLITE_API SQLITE_EXTERN const char sqlite3_version[]; +SQLITE_API const char *sqlite3_libversion(void); +SQLITE_API const char *sqlite3_sourceid(void); +SQLITE_API int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Run-Time Library Compilation Options Diagnostics +** +** ^The sqlite3_compileoption_used() function returns 0 or 1 +** indicating whether the specified option was defined at +** compile time. ^The SQLITE_ prefix may be omitted from the +** option name passed to sqlite3_compileoption_used(). +** +** ^The sqlite3_compileoption_get() function allows iterating +** over the list of options that were defined at compile time by +** returning the N-th compile time option string. ^If N is out of range, +** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ +** prefix is omitted from any strings returned by +** sqlite3_compileoption_get(). +** +** ^Support for the diagnostic functions sqlite3_compileoption_used() +** and sqlite3_compileoption_get() may be omitted by specifying the +** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. +** +** See also: SQL functions [sqlite_compileoption_used()] and +** [sqlite_compileoption_get()] and the [compile_options pragma]. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +SQLITE_API int sqlite3_compileoption_used(const char *zOptName); +SQLITE_API const char *sqlite3_compileoption_get(int N); +#endif + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** ^The sqlite3_threadsafe() function returns zero if and only if +** SQLite was compiled with mutexing code omitted due to the +** [SQLITE_THREADSAFE] compile-time option being set to 0. +** +** SQLite can be compiled with or without mutexes. When +** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes +** are enabled and SQLite is threadsafe. When the +** [SQLITE_THREADSAFE] macro is 0, +** the mutexes are omitted. Without the mutexes, it is not safe +** to use SQLite concurrently from more than one thread. +** +** Enabling mutexes incurs a measurable performance penalty. +** So if speed is of utmost importance, it makes sense to disable +** the mutexes. But for maximum safety, mutexes should be enabled. +** ^The default behavior is for mutexes to be enabled. +** +** This interface can be used by an application to make sure that the +** version of SQLite that it is linking against was compiled with +** the desired setting of the [SQLITE_THREADSAFE] macro. +** +** This interface only reports on the compile-time mutex setting +** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with +** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but +** can be fully or partially disabled using a call to [sqlite3_config()] +** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD], +** or [SQLITE_CONFIG_SERIALIZED]. ^(The return value of the +** sqlite3_threadsafe() function shows only the compile-time setting of +** thread safety, not any run-time changes to that setting made by +** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() +** is unchanged by calls to sqlite3_config().)^ +** +** See the [threading mode] documentation for additional information. +*/ +SQLITE_API int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** KEYWORDS: {database connection} {database connections} +** +** Each open SQLite database is represented by a pointer to an instance of +** the opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] +** and [sqlite3_close_v2()] are its destructors. There are many other +** interfaces (such as +** [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on an +** sqlite3 object. +*/ +typedef struct sqlite3 sqlite3; + +/* +** CAPI3REF: 64-Bit Integer Types +** KEYWORDS: sqlite_int64 sqlite_uint64 +** +** Because there is no cross-platform way to specify 64-bit integer types +** SQLite includes typedefs for 64-bit signed and unsigned integers. +** +** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions. +** The sqlite_int64 and sqlite_uint64 types are supported for backwards +** compatibility only. +** +** ^The sqlite3_int64 and sqlite_int64 types can store integer values +** between -9223372036854775808 and +9223372036854775807 inclusive. ^The +** sqlite3_uint64 and sqlite_uint64 types can store integer values +** between 0 and +18446744073709551615 inclusive. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** DESTRUCTOR: sqlite3 +** +** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors +** for the [sqlite3] object. +** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if +** the [sqlite3] object is successfully destroyed and all associated +** resources are deallocated. +** +** ^If the database connection is associated with unfinalized prepared +** statements or unfinished sqlite3_backup objects then sqlite3_close() +** will leave the database connection open and return [SQLITE_BUSY]. +** ^If sqlite3_close_v2() is called with unfinalized prepared statements +** and/or unfinished sqlite3_backups, then the database connection becomes +** an unusable "zombie" which will automatically be deallocated when the +** last prepared statement is finalized or the last sqlite3_backup is +** finished. The sqlite3_close_v2() interface is intended for use with +** host languages that are garbage collected, and where the order in which +** destructors are called is arbitrary. +** +** Applications should [sqlite3_finalize | finalize] all [prepared statements], +** [sqlite3_blob_close | close] all [BLOB handles], and +** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated +** with the [sqlite3] object prior to attempting to close the object. ^If +** sqlite3_close_v2() is called on a [database connection] that still has +** outstanding [prepared statements], [BLOB handles], and/or +** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation +** of resources is deferred until all [prepared statements], [BLOB handles], +** and [sqlite3_backup] objects are also destroyed. +** +** ^If an [sqlite3] object is destroyed while a transaction is open, +** the transaction is automatically rolled back. +** +** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] +** must be either a NULL +** pointer or an [sqlite3] object pointer obtained +** from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()], and not previously closed. +** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer +** argument is a harmless no-op. +*/ +SQLITE_API int sqlite3_close(sqlite3*); +SQLITE_API int sqlite3_close_v2(sqlite3*); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** METHOD: sqlite3 +** +** The sqlite3_exec() interface is a convenience wrapper around +** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], +** that allows an application to run multiple statements of SQL +** without having to use a lot of C code. +** +** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, +** semicolon-separate SQL statements passed into its 2nd argument, +** in the context of the [database connection] passed in as its 1st +** argument. ^If the callback function of the 3rd argument to +** sqlite3_exec() is not NULL, then it is invoked for each result row +** coming out of the evaluated SQL statements. ^The 4th argument to +** sqlite3_exec() is relayed through to the 1st argument of each +** callback invocation. ^If the callback pointer to sqlite3_exec() +** is NULL, then no callback is ever invoked and result rows are +** ignored. +** +** ^If an error occurs while evaluating the SQL statements passed into +** sqlite3_exec(), then execution of the current statement stops and +** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec() +** is not NULL then any error message is written into memory obtained +** from [sqlite3_malloc()] and passed back through the 5th parameter. +** To avoid memory leaks, the application should invoke [sqlite3_free()] +** on error message strings returned through the 5th parameter of +** sqlite3_exec() after the error message string is no longer needed. +** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors +** occur, then sqlite3_exec() sets the pointer in its 5th parameter to +** NULL before returning. +** +** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() +** routine returns SQLITE_ABORT without invoking the callback again and +** without running any subsequent SQL statements. +** +** ^The 2nd argument to the sqlite3_exec() callback function is the +** number of columns in the result. ^The 3rd argument to the sqlite3_exec() +** callback is an array of pointers to strings obtained as if from +** [sqlite3_column_text()], one for each column. ^If an element of a +** result row is NULL then the corresponding string pointer for the +** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the +** sqlite3_exec() callback is an array of pointers to strings where each +** entry represents the name of corresponding result column as obtained +** from [sqlite3_column_name()]. +** +** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer +** to an empty string, or a pointer that contains only whitespace and/or +** SQL comments, then no SQL statements are evaluated and the database +** is not changed. +** +** Restrictions: +** +** <ul> +** <li> The application must ensure that the 1st parameter to sqlite3_exec() +** is a valid and open [database connection]. +** <li> The application must not close the [database connection] specified by +** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. +** <li> The application must not modify the SQL statement text passed into +** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. +** </ul> +*/ +SQLITE_API int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluated */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: {result code definitions} +** +** Many SQLite functions return an integer result code from the set shown +** here in order to indicate success or failure. +** +** New error codes may be added in future versions of SQLite. +** +** See also: [extended result code definitions] +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */ +#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** KEYWORDS: {extended result code definitions} +** +** In its default configuration, SQLite API routines return one of 30 integer +** [result codes]. However, experience has shown that many of +** these result codes are too coarse-grained. They do not provide as +** much information about problems as programmers might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8] +** and later) include +** support for additional result codes that provide more detailed information +** about errors. These [extended result codes] are enabled or disabled +** on a per database connection basis using the +** [sqlite3_extended_result_codes()] API. Or, the extended code for +** the most recent error can be obtained using +** [sqlite3_extended_errcode()]. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) +#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8)) +#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8)) +#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8)) +#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8)) +#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8)) +#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) +#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) +#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) +#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) +#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) +#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) +#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) +#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) +#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) +#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) +#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) +#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) +#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) +#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) +#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) +#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) +#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) +#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) +#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) +#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) +#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) +#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) +#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) +#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) +#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8)) +#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8)) +#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8)) +#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8)) +#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8)) +#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8)) +#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) +#define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) +#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) +#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) +#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) +#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) +#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** These bit values are intended for use in the +** 3rd parameter to the [sqlite3_open_v2()] interface and +** in the 4th parameter to the [sqlite3_vfs.xOpen] method. +*/ +#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ +#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ +#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ +#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ +#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ + +/* Reserved: 0x00F00000 */ + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCharacteristics method of the [sqlite3_io_methods] +** object returns an integer which is a vector of these +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that +** after reboot following a crash or power loss, the only bytes in a +** file that were written at the application level might have changed +** and that adjacent bytes, even bytes within the same sector are +** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN +** flag indicate that a file cannot be deleted when open. The +** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on +** read-only media and cannot be changed even by processes with +** elevated privileges. +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 +#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 +#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 +#define SQLITE_IOCAP_IMMUTABLE 0x00002000 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of these integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an +** [sqlite3_io_methods] object it uses a combination of +** these integer values as the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. If the lower four bits of the flag +** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics. +** If the lower four bits equal SQLITE_SYNC_FULL, that means +** to use Mac OS X style fullsync instead of fsync(). +** +** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags +** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL +** settings. The [synchronous pragma] determines when calls to the +** xSync VFS method occur and applies uniformly across all platforms. +** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how +** energetic or rigorous or forceful the sync operations are and +** only make a difference on Mac OSX for the default SQLite code. +** (Third-party VFS implementations might also make the distinction +** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the +** operating systems natively supported by SQLite, only Mac OSX +** cares about the difference.) +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the +** [sqlite3_vfs | OS interface layer]. Individual OS interface +** implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs.xOpen] method populates an +** [sqlite3_file] object (or, more commonly, a subclass of the +** [sqlite3_file] object) with a pointer to an instance of this object. +** This object defines the methods used to perform various operations +** against the open file represented by the [sqlite3_file] object. +** +** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The +** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] +** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element +** to NULL. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] +** flag may be ORed in to indicate that only the data of the file +** and not its inode needs to be synced. +** +** The integer values to xLock() and xUnlock() are one of +** <ul> +** <li> [SQLITE_LOCK_NONE], +** <li> [SQLITE_LOCK_SHARED], +** <li> [SQLITE_LOCK_RESERVED], +** <li> [SQLITE_LOCK_PENDING], or +** <li> [SQLITE_LOCK_EXCLUSIVE]. +** </ul> +** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method checks whether any database connection, +** either in this process or in some other process, is holding a RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false otherwise. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument is an +** integer opcode. The third argument is a generic pointer intended to +** point to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves all opcodes less than 100 for its own use. +** A [file control opcodes | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. VFS implementations should +** return [SQLITE_NOTFOUND] for file control opcodes that they do not +** recognize. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +** <ul> +** <li> [SQLITE_IOCAP_ATOMIC] +** <li> [SQLITE_IOCAP_ATOMIC512] +** <li> [SQLITE_IOCAP_ATOMIC1K] +** <li> [SQLITE_IOCAP_ATOMIC2K] +** <li> [SQLITE_IOCAP_ATOMIC4K] +** <li> [SQLITE_IOCAP_ATOMIC8K] +** <li> [SQLITE_IOCAP_ATOMIC16K] +** <li> [SQLITE_IOCAP_ATOMIC32K] +** <li> [SQLITE_IOCAP_ATOMIC64K] +** <li> [SQLITE_IOCAP_SAFE_APPEND] +** <li> [SQLITE_IOCAP_SEQUENTIAL] +** </ul> +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +** +** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill +** in the unread portions of the buffer with zeros. A VFS that +** fails to zero-fill short reads might seem to work. However, +** failure to zero-fill short reads will eventually lead to +** database corruption. +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Methods above are valid for version 1 */ + int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); + int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (*xShmBarrier)(sqlite3_file*); + int (*xShmUnmap)(sqlite3_file*, int deleteFlag); + /* Methods above are valid for version 2 */ + int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); + int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); + /* Methods above are valid for version 3 */ + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** KEYWORDS: {file control opcodes} {file control opcode} +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] +** interface. +** +** <ul> +** <li>[[SQLITE_FCNTL_LOCKSTATE]] +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode causes the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and is only available when the SQLITE_TEST +** compile-time option is used. +** +** <li>[[SQLITE_FCNTL_SIZE_HINT]] +** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS +** layer a hint of how large the database file will grow to be during the +** current transaction. This hint is not guaranteed to be accurate but it +** is often close. The underlying VFS might choose to preallocate database +** file space based on this hint in order to help writes to the database +** file run faster. +** +** <li>[[SQLITE_FCNTL_CHUNK_SIZE]] +** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS +** extends and truncates the database file in chunks of a size specified +** by the user. The fourth argument to [sqlite3_file_control()] should +** point to an integer (type int) containing the new chunk-size to use +** for the nominated database. Allocating database file space in large +** chunks (say 1MB at a time), may reduce file-system fragmentation and +** improve performance on some systems. +** +** <li>[[SQLITE_FCNTL_FILE_POINTER]] +** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer +** to the [sqlite3_file] object associated with a particular database +** connection. See also [SQLITE_FCNTL_JOURNAL_POINTER]. +** +** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]] +** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer +** to the [sqlite3_file] object associated with the journal file (either +** the [rollback journal] or the [write-ahead log]) for a particular database +** connection. See also [SQLITE_FCNTL_FILE_POINTER]. +** +** <li>[[SQLITE_FCNTL_SYNC_OMITTED]] +** No longer in use. +** +** <li>[[SQLITE_FCNTL_SYNC]] +** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and +** sent to the VFS immediately before the xSync method is invoked on a +** database file descriptor. Or, if the xSync method is not invoked +** because the user has configured SQLite with +** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place +** of the xSync method. In most cases, the pointer argument passed with +** this file-control is NULL. However, if the database file is being synced +** as part of a multi-database commit, the argument points to a nul-terminated +** string containing the transactions master-journal file name. VFSes that +** do not need this signal should silently ignore this opcode. Applications +** should not call [sqlite3_file_control()] with this opcode as doing so may +** disrupt the operation of the specialized VFSes that do require it. +** +** <li>[[SQLITE_FCNTL_COMMIT_PHASETWO]] +** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite +** and sent to the VFS after a transaction has been committed immediately +** but before the database is unlocked. VFSes that do not need this signal +** should silently ignore this opcode. Applications should not call +** [sqlite3_file_control()] with this opcode as doing so may disrupt the +** operation of the specialized VFSes that do require it. +** +** <li>[[SQLITE_FCNTL_WIN32_AV_RETRY]] +** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic +** retry counts and intervals for certain disk I/O operations for the +** windows [VFS] in order to provide robustness in the presence of +** anti-virus programs. By default, the windows VFS will retry file read, +** file write, and file delete operations up to 10 times, with a delay +** of 25 milliseconds before the first retry and with the delay increasing +** by an additional 25 milliseconds with each subsequent retry. This +** opcode allows these two values (10 retries and 25 milliseconds of delay) +** to be adjusted. The values are changed for all database connections +** within the same process. The argument is a pointer to an array of two +** integers where the first integer i the new retry count and the second +** integer is the delay. If either integer is negative, then the setting +** is not changed but instead the prior value of that setting is written +** into the array entry, allowing the current retry settings to be +** interrogated. The zDbName parameter is ignored. +** +** <li>[[SQLITE_FCNTL_PERSIST_WAL]] +** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the +** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary +** write ahead log and shared memory files used for transaction control +** are automatically deleted when the latest connection to the database +** closes. Setting persistent WAL mode causes those files to persist after +** close. Persisting the files is useful when other processes that do not +** have write permission on the directory containing the database file want +** to read the database file, as the WAL and shared memory files must exist +** in order for the database to be readable. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable persistent WAL mode or 1 to enable persistent +** WAL mode. If the integer is -1, then it is overwritten with the current +** WAL persistence setting. +** +** <li>[[SQLITE_FCNTL_POWERSAFE_OVERWRITE]] +** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the +** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting +** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the +** xDeviceCharacteristics methods. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage +** mode. If the integer is -1, then it is overwritten with the current +** zero-damage mode setting. +** +** <li>[[SQLITE_FCNTL_OVERWRITE]] +** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening +** a write transaction to indicate that, unless it is rolled back for some +** reason, the entire database file will be overwritten by the current +** transaction. This is used by VACUUM operations. +** +** <li>[[SQLITE_FCNTL_VFSNAME]] +** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of +** all [VFSes] in the VFS stack. The names are of all VFS shims and the +** final bottom-level VFS are written into memory obtained from +** [sqlite3_malloc()] and the result is stored in the char* variable +** that the fourth parameter of [sqlite3_file_control()] points to. +** The caller is responsible for freeing the memory when done. As with +** all file-control actions, there is no guarantee that this will actually +** do anything. Callers should initialize the char* variable to a NULL +** pointer in case this file-control is not implemented. This file-control +** is intended for diagnostic use only. +** +** <li>[[SQLITE_FCNTL_VFS_POINTER]] +** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level +** [VFSes] currently in use. ^(The argument X in +** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be +** of type "[sqlite3_vfs] **". This opcodes will set *X +** to a pointer to the top-level VFS.)^ +** ^When there are multiple VFS shims in the stack, this opcode finds the +** upper-most shim only. +** +** <li>[[SQLITE_FCNTL_PRAGMA]] +** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] +** file control is sent to the open [sqlite3_file] object corresponding +** to the database file to which the pragma statement refers. ^The argument +** to the [SQLITE_FCNTL_PRAGMA] file control is an array of +** pointers to strings (char**) in which the second element of the array +** is the name of the pragma and the third element is the argument to the +** pragma or NULL if the pragma has no argument. ^The handler for an +** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element +** of the char** argument point to a string obtained from [sqlite3_mprintf()] +** or the equivalent and that string will become the result of the pragma or +** the error message if the pragma fails. ^If the +** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal +** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] +** file control returns [SQLITE_OK], then the parser assumes that the +** VFS has handled the PRAGMA itself and the parser generates a no-op +** prepared statement if result string is NULL, or that returns a copy +** of the result string if the string is non-NULL. +** ^If the [SQLITE_FCNTL_PRAGMA] file control returns +** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means +** that the VFS encountered an error while handling the [PRAGMA] and the +** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] +** file control occurs at the beginning of pragma statement analysis and so +** it is able to override built-in [PRAGMA] statements. +** +** <li>[[SQLITE_FCNTL_BUSYHANDLER]] +** ^The [SQLITE_FCNTL_BUSYHANDLER] +** file-control may be invoked by SQLite on the database file handle +** shortly after it is opened in order to provide a custom VFS with access +** to the connections busy-handler callback. The argument is of type (void **) +** - an array of two (void *) values. The first (void *) actually points +** to a function of type (int (*)(void *)). In order to invoke the connections +** busy-handler, this function should be invoked with the second (void *) in +** the array as the only argument. If it returns non-zero, then the operation +** should be retried. If it returns zero, the custom VFS should abandon the +** current operation. +** +** <li>[[SQLITE_FCNTL_TEMPFILENAME]] +** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control +** to have SQLite generate a +** temporary filename using the same algorithm that is followed to generate +** temporary filenames for TEMP tables and other internal uses. The +** argument should be a char** which will be filled with the filename +** written into memory obtained from [sqlite3_malloc()]. The caller should +** invoke [sqlite3_free()] on the result to avoid a memory leak. +** +** <li>[[SQLITE_FCNTL_MMAP_SIZE]] +** The [SQLITE_FCNTL_MMAP_SIZE] file control is used to query or set the +** maximum number of bytes that will be used for memory-mapped I/O. +** The argument is a pointer to a value of type sqlite3_int64 that +** is an advisory maximum number of bytes in the file to memory map. The +** pointer is overwritten with the old value. The limit is not changed if +** the value originally pointed to is negative, and so the current limit +** can be queried by passing in a pointer to a negative number. This +** file-control is used internally to implement [PRAGMA mmap_size]. +** +** <li>[[SQLITE_FCNTL_TRACE]] +** The [SQLITE_FCNTL_TRACE] file control provides advisory information +** to the VFS about what the higher layers of the SQLite stack are doing. +** This file control is used by some VFS activity tracing [shims]. +** The argument is a zero-terminated string. Higher layers in the +** SQLite stack may generate instances of this file control if +** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled. +** +** <li>[[SQLITE_FCNTL_HAS_MOVED]] +** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a +** pointer to an integer and it writes a boolean into that integer depending +** on whether or not the file has been renamed, moved, or deleted since it +** was first opened. +** +** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]] +** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the +** underlying native file handle associated with a file handle. This file +** control interprets its argument as a pointer to a native file handle and +** writes the resulting value there. +** +** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]] +** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This +** opcode causes the xFileControl method to swap the file handle with the one +** pointed to by the pArg argument. This capability is used during testing +** and only needs to be supported when SQLITE_TEST is defined. +** +** <li>[[SQLITE_FCNTL_WAL_BLOCK]] +** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might +** be advantageous to block on the next WAL lock if the lock is not immediately +** available. The WAL subsystem issues this signal during rare +** circumstances in order to fix a problem with priority inversion. +** Applications should <em>not</em> use this file-control. +** +** <li>[[SQLITE_FCNTL_ZIPVFS]] +** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other +** VFS should return SQLITE_NOTFOUND for this opcode. +** +** <li>[[SQLITE_FCNTL_RBU]] +** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by +** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for +** this opcode. +** </ul> +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 +#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 +#define SQLITE_FCNTL_LAST_ERRNO 4 +#define SQLITE_FCNTL_SIZE_HINT 5 +#define SQLITE_FCNTL_CHUNK_SIZE 6 +#define SQLITE_FCNTL_FILE_POINTER 7 +#define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 +#define SQLITE_FCNTL_VFSNAME 12 +#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 +#define SQLITE_FCNTL_PRAGMA 14 +#define SQLITE_FCNTL_BUSYHANDLER 15 +#define SQLITE_FCNTL_TEMPFILENAME 16 +#define SQLITE_FCNTL_MMAP_SIZE 18 +#define SQLITE_FCNTL_TRACE 19 +#define SQLITE_FCNTL_HAS_MOVED 20 +#define SQLITE_FCNTL_SYNC 21 +#define SQLITE_FCNTL_COMMIT_PHASETWO 22 +#define SQLITE_FCNTL_WIN32_SET_HANDLE 23 +#define SQLITE_FCNTL_WAL_BLOCK 24 +#define SQLITE_FCNTL_ZIPVFS 25 +#define SQLITE_FCNTL_RBU 26 +#define SQLITE_FCNTL_VFS_POINTER 27 +#define SQLITE_FCNTL_JOURNAL_POINTER 28 +#define SQLITE_FCNTL_WIN32_GET_HANDLE 29 + +/* deprecated names */ +#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE +#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE +#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO + + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: Loadable Extension Thunk +** +** A pointer to the opaque sqlite3_api_routines structure is passed as +** the third parameter to entry points of [loadable extensions]. This +** structure must be typedefed in order to work around compiler warnings +** on some platforms. +*/ +typedef struct sqlite3_api_routines sqlite3_api_routines; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of the sqlite3_vfs object defines the interface between +** the SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". See +** the [VFS | VFS documentation] for further information. +** +** The value of the iVersion field is initially 1 but may be larger in +** future versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. Note that the structure +** of the sqlite3_vfs object changes in the transaction between +** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not +** modified. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered sqlite3_vfs objects are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. Neither the application code nor the VFS +** implementation should use the pNext pointer. +** +** The pNext field is the only field in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** [[sqlite3_vfs.xOpen]] +** ^SQLite guarantees that the zFilename parameter to xOpen +** is either a NULL pointer or string obtained +** from xFullPathname() with an optional suffix added. +** ^If a suffix is added to the zFilename parameter, it will +** consist of a single "-" character followed by no more than +** 11 alphanumeric and/or "-" characters. +** ^SQLite further guarantees that +** the string will be valid and unchanged until xClose() is +** called. Because of the previous sentence, +** the [sqlite3_file] can safely store a pointer to the +** filename if it needs to remember the filename for some reason. +** If the zFilename parameter to xOpen is a NULL pointer then xOpen +** must invent its own temporary name for the file. ^Whenever the +** xFilename parameter is NULL it will also be the case that the +** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. +** +** The flags argument to xOpen() includes all bits set in +** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] +** or [sqlite3_open16()] is used, then flags includes at least +** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. +** +** ^(SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +** <ul> +** <li> [SQLITE_OPEN_MAIN_DB] +** <li> [SQLITE_OPEN_MAIN_JOURNAL] +** <li> [SQLITE_OPEN_TEMP_DB] +** <li> [SQLITE_OPEN_TEMP_JOURNAL] +** <li> [SQLITE_OPEN_TRANSIENT_DB] +** <li> [SQLITE_OPEN_SUBJOURNAL] +** <li> [SQLITE_OPEN_MASTER_JOURNAL] +** <li> [SQLITE_OPEN_WAL] +** </ul>)^ +** +** The file I/O implementation can use the object type flags to +** change the way it deals with files. For example, an application +** that does not care about crash recovery or rollback might make +** the open of a journal file a no-op. Writes to this journal would +** also be no-ops, and any attempt to read the journal would return +** SQLITE_IOERR. Or the implementation might recognize that a database +** file will be doing page-aligned sector reads and writes in a random +** order and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen method: +** +** <ul> +** <li> [SQLITE_OPEN_DELETEONCLOSE] +** <li> [SQLITE_OPEN_EXCLUSIVE] +** </ul> +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. ^The [SQLITE_OPEN_DELETEONCLOSE] +** will be set for TEMP databases and their journals, transient +** databases, and subjournals. +** +** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction +** with the [SQLITE_OPEN_CREATE] flag, which are both directly +** analogous to the O_EXCL and O_CREAT flags of the POSIX open() +** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the +** SQLITE_OPEN_CREATE, is used to indicate that file should always +** be created, and that it is an error if it already exists. +** It is <i>not</i> used to indicate the file should be opened +** for exclusive access. +** +** ^At least szOsFile bytes of memory are allocated by SQLite +** to hold the [sqlite3_file] structure passed as the third +** argument to xOpen. The xOpen method does not have to +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. +** +** [[sqlite3_vfs.xAccess]] +** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to +** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test whether a file is at least readable. The file can be a +** directory. +** +** ^SQLite will always allocate at least mxPathname+1 bytes for the +** output buffer xFullPathname. The exact size of the output buffer +** is also passed as a parameter to both methods. If the output buffer +** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is +** handled as a fatal error by SQLite, vfs implementations should endeavor +** to prevent this by setting mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() +** interfaces are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. +** The xSleep() method causes the calling thread to sleep for at +** least the number of microseconds given. ^The xCurrentTime() +** method returns a Julian Day Number for the current date and time as +** a floating point value. +** ^The xCurrentTimeInt64() method returns, as an integer, the Julian +** Day Number multiplied by 86400000 (the number of milliseconds in +** a 24-hour day). +** ^SQLite will use the xCurrentTimeInt64() method to get the current +** date and time if that method is available (if iVersion is 2 or +** greater and the function pointer is not NULL) and will fall back +** to xCurrentTime() if xCurrentTimeInt64() is unavailable. +** +** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces +** are not used by the SQLite core. These optional interfaces are provided +** by some VFSes to facilitate testing of the VFS code. By overriding +** system calls with functions under its control, a test program can +** simulate faults and error conditions that would otherwise be difficult +** or impossible to induce. The set of system calls that can be overridden +** varies from one VFS to another, and from one version of the same VFS to the +** next. Applications that use these interfaces must be prepared for any +** or all of these interfaces to be NULL or for their behavior to change +** from one release to the next. Applications must not attempt to access +** any of these methods if the iVersion of the VFS is less than 3. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +typedef void (*sqlite3_syscall_ptr)(void); +struct sqlite3_vfs { + int iVersion; /* Structure version number (currently 3) */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + int (*xGetLastError)(sqlite3_vfs*, int, char *); + /* + ** The methods above are in version 1 of the sqlite_vfs object + ** definition. Those that follow are added in version 2 or later + */ + int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); + /* + ** The methods above are in versions 1 and 2 of the sqlite_vfs object. + ** Those below are for version 3 and greater. + */ + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); + /* + ** The methods above are in versions 1 through 3 of the sqlite_vfs object. + ** New fields may be appended in future versions. The iVersion + ** value will increment whenever this happens. + */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** what kind of permissions the xAccess method is looking for. +** With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks whether the file exists. +** With SQLITE_ACCESS_READWRITE, the xAccess method +** checks whether the named directory is both readable and writable +** (in other words, if files can be added, removed, and renamed within +** the directory). +** The SQLITE_ACCESS_READWRITE constant is currently used only by the +** [temp_store_directory pragma], though this could change in a future +** release of SQLite. +** With SQLITE_ACCESS_READ, the xAccess method +** checks whether the file is readable. The SQLITE_ACCESS_READ constant is +** currently unused, though it might be used in a future release of +** SQLite. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */ +#define SQLITE_ACCESS_READ 2 /* Unused */ + +/* +** CAPI3REF: Flags for the xShmLock VFS method +** +** These integer constants define the various locking operations +** allowed by the xShmLock method of [sqlite3_io_methods]. The +** following are the only legal combinations of flags to the +** xShmLock method: +** +** <ul> +** <li> SQLITE_SHM_LOCK | SQLITE_SHM_SHARED +** <li> SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE +** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED +** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE +** </ul> +** +** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as +** was given on the corresponding lock. +** +** The xShmLock method can transition between unlocked and SHARED or +** between unlocked and EXCLUSIVE. It cannot transition between SHARED +** and EXCLUSIVE. +*/ +#define SQLITE_SHM_UNLOCK 1 +#define SQLITE_SHM_LOCK 2 +#define SQLITE_SHM_SHARED 4 +#define SQLITE_SHM_EXCLUSIVE 8 + +/* +** CAPI3REF: Maximum xShmLock index +** +** The xShmLock method on [sqlite3_io_methods] may use values +** between 0 and this upper bound as its "offset" argument. +** The SQLite core will never attempt to acquire or release a +** lock outside of this range +*/ +#define SQLITE_SHM_NLOCK 8 + + +/* +** CAPI3REF: Initialize The SQLite Library +** +** ^The sqlite3_initialize() routine initializes the +** SQLite library. ^The sqlite3_shutdown() routine +** deallocates any resources that were allocated by sqlite3_initialize(). +** These routines are designed to aid in process initialization and +** shutdown on embedded systems. Workstation applications using +** SQLite normally do not need to invoke either of these routines. +** +** A call to sqlite3_initialize() is an "effective" call if it is +** the first time sqlite3_initialize() is invoked during the lifetime of +** the process, or if it is the first time sqlite3_initialize() is invoked +** following a call to sqlite3_shutdown(). ^(Only an effective call +** of sqlite3_initialize() does any initialization. All other calls +** are harmless no-ops.)^ +** +** A call to sqlite3_shutdown() is an "effective" call if it is the first +** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only +** an effective call to sqlite3_shutdown() does any deinitialization. +** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^ +** +** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown() +** is not. The sqlite3_shutdown() interface must only be called from a +** single thread. All open [database connections] must be closed and all +** other SQLite resources must be deallocated prior to invoking +** sqlite3_shutdown(). +** +** Among other things, ^sqlite3_initialize() will invoke +** sqlite3_os_init(). Similarly, ^sqlite3_shutdown() +** will invoke sqlite3_os_end(). +** +** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success. +** ^If for some reason, sqlite3_initialize() is unable to initialize +** the library (perhaps it is unable to allocate a needed resource such +** as a mutex) it returns an [error code] other than [SQLITE_OK]. +** +** ^The sqlite3_initialize() routine is called internally by many other +** SQLite interfaces so that an application usually does not need to +** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] +** calls sqlite3_initialize() so the SQLite library will be automatically +** initialized when [sqlite3_open()] is called if it has not be initialized +** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] +** compile-time option, then the automatic calls to sqlite3_initialize() +** are omitted and the application must call sqlite3_initialize() directly +** prior to using any other SQLite interface. For maximum portability, +** it is recommended that applications always invoke sqlite3_initialize() +** directly prior to using any other SQLite interface. Future releases +** of SQLite may require this. In other words, the behavior exhibited +** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the +** default behavior in some future release of SQLite. +** +** The sqlite3_os_init() routine does operating-system specific +** initialization of the SQLite library. The sqlite3_os_end() +** routine undoes the effect of sqlite3_os_init(). Typical tasks +** performed by these routines include allocation or deallocation +** of static resources, initialization of global variables, +** setting up a default [sqlite3_vfs] module, or setting up +** a default configuration using [sqlite3_config()]. +** +** The application should never invoke either sqlite3_os_init() +** or sqlite3_os_end() directly. The application should only invoke +** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init() +** interface is called automatically by sqlite3_initialize() and +** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate +** implementations for sqlite3_os_init() and sqlite3_os_end() +** are built into SQLite when it is compiled for Unix, Windows, or OS/2. +** When [custom builds | built for other platforms] +** (using the [SQLITE_OS_OTHER=1] compile-time +** option) the application must supply a suitable implementation for +** sqlite3_os_init() and sqlite3_os_end(). An application-supplied +** implementation of sqlite3_os_init() or sqlite3_os_end() +** must return [SQLITE_OK] on success and some other [error code] upon +** failure. +*/ +SQLITE_API int sqlite3_initialize(void); +SQLITE_API int sqlite3_shutdown(void); +SQLITE_API int sqlite3_os_init(void); +SQLITE_API int sqlite3_os_end(void); + +/* +** CAPI3REF: Configuring The SQLite Library +** +** The sqlite3_config() interface is used to make global configuration +** changes to SQLite in order to tune SQLite to the specific needs of +** the application. The default configuration is recommended for most +** applications and so this routine is usually not necessary. It is +** provided to support rare applications with unusual needs. +** +** <b>The sqlite3_config() interface is not threadsafe. The application +** must ensure that no other SQLite interfaces are invoked by other +** threads while sqlite3_config() is running.</b> +** +** The sqlite3_config() interface +** may only be invoked prior to library initialization using +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. +** +** The first argument to sqlite3_config() is an integer +** [configuration option] that determines +** what property of SQLite is to be configured. Subsequent arguments +** vary depending on the [configuration option] +** in the first argument. +** +** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. +** ^If the option is unknown or SQLite is unable to set the option +** then this routine returns a non-zero [error code]. +*/ +SQLITE_API int sqlite3_config(int, ...); + +/* +** CAPI3REF: Configure database connections +** METHOD: sqlite3 +** +** The sqlite3_db_config() interface is used to make configuration +** changes to a [database connection]. The interface is similar to +** [sqlite3_config()] except that the changes apply to a single +** [database connection] (specified in the first argument). +** +** The second argument to sqlite3_db_config(D,V,...) is the +** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code +** that indicates what aspect of the [database connection] is being configured. +** Subsequent arguments vary depending on the configuration verb. +** +** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if +** the call is considered successful. +*/ +SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Memory Allocation Routines +** +** An instance of this object defines the interface between SQLite +** and low-level memory allocation routines. +** +** This object is used in only one place in the SQLite interface. +** A pointer to an instance of this object is the argument to +** [sqlite3_config()] when the configuration option is +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** By creating an instance of this object +** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) +** during configuration, an application can specify an alternative +** memory allocation subsystem for SQLite to use for all of its +** dynamic memory needs. +** +** Note that SQLite comes with several [built-in memory allocators] +** that are perfectly adequate for the overwhelming majority of applications +** and that this object is only useful to a tiny minority of applications +** with specialized memory allocation requirements. This object is +** also used during testing of SQLite in order to specify an alternative +** memory allocator that simulates memory out-of-memory conditions in +** order to verify that SQLite recovers gracefully from such +** conditions. +** +** The xMalloc, xRealloc, and xFree methods must work like the +** malloc(), realloc() and free() functions from the standard C library. +** ^SQLite guarantees that the second argument to +** xRealloc is always a value returned by a prior call to xRoundup. +** +** xSize should return the allocated size of a memory allocation +** previously obtained from xMalloc or xRealloc. The allocated size +** is always at least as big as the requested size but may be larger. +** +** The xRoundup method returns what would be the allocated size of +** a memory allocation given a particular requested size. Most memory +** allocators round up memory allocations at least to the next multiple +** of 8. Some allocators round up to a larger multiple or to a power of 2. +** Every memory allocation request coming in through [sqlite3_malloc()] +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** that causes the corresponding memory allocation to fail. +** +** The xInit method initializes the memory allocator. For example, +** it might allocate any require mutexes or initialize internal data +** structures. The xShutdown method is invoked (indirectly) by +** [sqlite3_shutdown()] and should deallocate any resources acquired +** by xInit. The pAppData pointer is used as the only parameter to +** xInit and xShutdown. +** +** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. For all other methods, SQLite +** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the +** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which +** it is by default) and so the methods are automatically serialized. +** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other +** methods must be threadsafe or else make their own arrangements for +** serialization. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +*/ +typedef struct sqlite3_mem_methods sqlite3_mem_methods; +struct sqlite3_mem_methods { + void *(*xMalloc)(int); /* Memory allocation function */ + void (*xFree)(void*); /* Free a prior allocation */ + void *(*xRealloc)(void*,int); /* Resize an allocation */ + int (*xSize)(void*); /* Return the size of an allocation */ + int (*xRoundup)(int); /* Round up request size to allocation size */ + int (*xInit)(void*); /* Initialize the memory allocator */ + void (*xShutdown)(void*); /* Deinitialize the memory allocator */ + void *pAppData; /* Argument to xInit() and xShutdown() */ +}; + +/* +** CAPI3REF: Configuration Options +** KEYWORDS: {configuration option} +** +** These constants are the available integer configuration options that +** can be passed as the first argument to the [sqlite3_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_config()] to make sure that +** the call worked. The [sqlite3_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +** <dl> +** [[SQLITE_CONFIG_SINGLETHREAD]] <dt>SQLITE_CONFIG_SINGLETHREAD</dt> +** <dd>There are no arguments to this option. ^This option sets the +** [threading mode] to Single-thread. In other words, it disables +** all mutexing and puts SQLite into a mode where it can only be used +** by a single thread. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to change the [threading mode] from its default +** value of Single-thread and so [sqlite3_config()] will return +** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD +** configuration option.</dd> +** +** [[SQLITE_CONFIG_MULTITHREAD]] <dt>SQLITE_CONFIG_MULTITHREAD</dt> +** <dd>There are no arguments to this option. ^This option sets the +** [threading mode] to Multi-thread. In other words, it disables +** mutexing on [database connection] and [prepared statement] objects. +** The application is responsible for serializing access to +** [database connections] and [prepared statements]. But other mutexes +** are enabled so that SQLite will be safe to use in a multi-threaded +** environment as long as no two threads attempt to use the same +** [database connection] at the same time. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Multi-thread [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_MULTITHREAD configuration option.</dd> +** +** [[SQLITE_CONFIG_SERIALIZED]] <dt>SQLITE_CONFIG_SERIALIZED</dt> +** <dd>There are no arguments to this option. ^This option sets the +** [threading mode] to Serialized. In other words, this option enables +** all mutexes including the recursive +** mutexes on [database connection] and [prepared statement] objects. +** In this mode (which is the default when SQLite is compiled with +** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access +** to [database connections] and [prepared statements] so that the +** application is free to use the same [database connection] or the +** same [prepared statement] in different threads at the same time. +** ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Serialized [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_SERIALIZED configuration option.</dd> +** +** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt> +** <dd> ^(The SQLITE_CONFIG_MALLOC option takes a single argument which is +** a pointer to an instance of the [sqlite3_mem_methods] structure. +** The argument specifies +** alternative low-level memory allocation routines to be used in place of +** the memory allocation routines built into SQLite.)^ ^SQLite makes +** its own private copy of the content of the [sqlite3_mem_methods] structure +** before the [sqlite3_config()] call returns.</dd> +** +** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt> +** <dd> ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which +** is a pointer to an instance of the [sqlite3_mem_methods] structure. +** The [sqlite3_mem_methods] +** structure is filled with the currently defined memory allocation routines.)^ +** This option can be used to overload the default memory allocation +** routines with a wrapper that simulations memory allocation failure or +** tracks memory usage, for example. </dd> +** +** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> +** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, +** interpreted as a boolean, which enables or disables the collection of +** memory allocation statistics. ^(When memory allocation statistics are +** disabled, the following SQLite interfaces become non-operational: +** <ul> +** <li> [sqlite3_memory_used()] +** <li> [sqlite3_memory_highwater()] +** <li> [sqlite3_soft_heap_limit64()] +** <li> [sqlite3_status64()] +** </ul>)^ +** ^Memory allocation statistics are enabled by default unless SQLite is +** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory +** allocation statistics are disabled by default. +** </dd> +** +** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt> +** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer +** that SQLite can use for scratch memory. ^(There are three arguments +** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte +** aligned memory buffer from which the scratch allocations will be +** drawn, the size of each scratch allocation (sz), +** and the maximum number of scratch allocations (N).)^ +** The first argument must be a pointer to an 8-byte aligned buffer +** of at least sz*N bytes of memory. +** ^SQLite will not use more than one scratch buffers per thread. +** ^SQLite will never request a scratch buffer that is more than 6 +** times the database page size. +** ^If SQLite needs needs additional +** scratch memory beyond what is provided by this configuration option, then +** [sqlite3_malloc()] will be used to obtain the memory needed.<p> +** ^When the application provides any amount of scratch memory using +** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large +** [sqlite3_malloc|heap allocations]. +** This can help [Robson proof|prevent memory allocation failures] due to heap +** fragmentation in low-memory embedded systems. +** </dd> +** +** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt> +** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool +** that SQLite can use for the database page cache with the default page +** cache implementation. +** This configuration option is a no-op if an application-define page +** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]. +** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to +** 8-byte aligned memory (pMem), the size of each page cache line (sz), +** and the number of cache lines (N). +** The sz argument should be the size of the largest database page +** (a power of two between 512 and 65536) plus some extra bytes for each +** page header. ^The number of extra bytes needed by the page header +** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ]. +** ^It is harmless, apart from the wasted memory, +** for the sz parameter to be larger than necessary. The pMem +** argument must be either a NULL pointer or a pointer to an 8-byte +** aligned block of memory of at least sz*N bytes, otherwise +** subsequent behavior is undefined. +** ^When pMem is not NULL, SQLite will strive to use the memory provided +** to satisfy page cache needs, falling back to [sqlite3_malloc()] if +** a page cache line is larger than sz bytes or if all of the pMem buffer +** is exhausted. +** ^If pMem is NULL and N is non-zero, then each database connection +** does an initial bulk allocation for page cache memory +** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or +** of -1024*N bytes if N is negative, . ^If additional +** page cache memory is needed beyond what is provided by the initial +** allocation, then SQLite goes to [sqlite3_malloc()] separately for each +** additional cache line. </dd> +** +** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> +** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer +** that SQLite will use for all of its dynamic memory allocation needs +** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and +** [SQLITE_CONFIG_PAGECACHE]. +** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled +** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns +** [SQLITE_ERROR] if invoked otherwise. +** ^There are three arguments to SQLITE_CONFIG_HEAP: +** An 8-byte aligned pointer to the memory, +** the number of bytes in the memory buffer, and the minimum allocation size. +** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts +** to using its default memory allocator (the system malloc() implementation), +** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the +** memory pointer is not NULL then the alternative memory +** allocator is engaged to handle all of SQLites memory allocation needs. +** The first pointer (the memory pointer) must be aligned to an 8-byte +** boundary or subsequent behavior of SQLite will be undefined. +** The minimum allocation size is capped at 2**12. Reasonable values +** for the minimum allocation size are 2**5 through 2**8.</dd> +** +** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> +** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a +** pointer to an instance of the [sqlite3_mutex_methods] structure. +** The argument specifies alternative low-level mutex routines to be used +** in place the mutex routines built into SQLite.)^ ^SQLite makes a copy of +** the content of the [sqlite3_mutex_methods] structure before the call to +** [sqlite3_config()] returns. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will +** return [SQLITE_ERROR].</dd> +** +** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt> +** <dd> ^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which +** is a pointer to an instance of the [sqlite3_mutex_methods] structure. The +** [sqlite3_mutex_methods] +** structure is filled with the currently defined mutex routines.)^ +** This option can be used to overload the default mutex allocation +** routines with a wrapper used to track mutex usage for performance +** profiling or testing, for example. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will +** return [SQLITE_ERROR].</dd> +** +** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt> +** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine +** the default size of lookaside memory on each [database connection]. +** The first argument is the +** size of each lookaside buffer slot and the second is the number of +** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE +** sets the <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] +** option to [sqlite3_db_config()] can be used to change the lookaside +** configuration on individual connections.)^ </dd> +** +** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt> +** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is +** a pointer to an [sqlite3_pcache_methods2] object. This object specifies +** the interface to a custom page cache implementation.)^ +** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd> +** +** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt> +** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which +** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of +** the current page cache implementation into that object.)^ </dd> +** +** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt> +** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite +** global [error log]. +** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a +** function with a call signature of void(*)(void*,int,const char*), +** and a pointer to void. ^If the function pointer is not NULL, it is +** invoked by [sqlite3_log()] to process each logging event. ^If the +** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. +** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is +** passed through as the first parameter to the application-defined logger +** function whenever that function is invoked. ^The second parameter to +** the logger function is a copy of the first parameter to the corresponding +** [sqlite3_log()] call and is intended to be a [result code] or an +** [extended result code]. ^The third parameter passed to the logger is +** log message after formatting via [sqlite3_snprintf()]. +** The SQLite logging interface is not reentrant; the logger function +** supplied by the application must not invoke any SQLite interface. +** In a multi-threaded application, the application-defined logger +** function must be threadsafe. </dd> +** +** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI +** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int. +** If non-zero, then URI handling is globally enabled. If the parameter is zero, +** then URI handling is globally disabled.)^ ^If URI handling is globally +** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], +** [sqlite3_open16()] or +** specified as part of [ATTACH] commands are interpreted as URIs, regardless +** of whether or not the [SQLITE_OPEN_URI] flag is set when the database +** connection is opened. ^If it is globally disabled, filenames are +** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the +** database connection is opened. ^(By default, URI handling is globally +** disabled. The default value may be changed by compiling with the +** [SQLITE_USE_URI] symbol defined.)^ +** +** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN +** <dd>^The SQLITE_CONFIG_COVERING_INDEX_SCAN option takes a single integer +** argument which is interpreted as a boolean in order to enable or disable +** the use of covering indices for full table scans in the query optimizer. +** ^The default setting is determined +** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on" +** if that compile-time option is omitted. +** The ability to disable the use of covering indices for full table scans +** is because some incorrectly coded legacy applications might malfunction +** when the optimization is enabled. Providing the ability to +** disable the optimization allows the older, buggy application code to work +** without change even with newer versions of SQLite. +** +** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] +** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE +** <dd> These options are obsolete and should not be used by new code. +** They are retained for backwards compatibility but are now no-ops. +** </dd> +** +** [[SQLITE_CONFIG_SQLLOG]] +** <dt>SQLITE_CONFIG_SQLLOG +** <dd>This option is only available if sqlite is compiled with the +** [SQLITE_ENABLE_SQLLOG] pre-processor macro defined. The first argument should +** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int). +** The second should be of type (void*). The callback is invoked by the library +** in three separate circumstances, identified by the value passed as the +** fourth parameter. If the fourth parameter is 0, then the database connection +** passed as the second argument has just been opened. The third argument +** points to a buffer containing the name of the main database file. If the +** fourth parameter is 1, then the SQL statement that the third parameter +** points to has just been executed. Or, if the fourth parameter is 2, then +** the connection being passed as the second parameter is being closed. The +** third parameter is passed NULL In this case. An example of using this +** configuration option can be seen in the "test_sqllog.c" source file in +** the canonical SQLite source tree.</dd> +** +** [[SQLITE_CONFIG_MMAP_SIZE]] +** <dt>SQLITE_CONFIG_MMAP_SIZE +** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values +** that are the default mmap size limit (the default setting for +** [PRAGMA mmap_size]) and the maximum allowed mmap size limit. +** ^The default setting can be overridden by each database connection using +** either the [PRAGMA mmap_size] command, or by using the +** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size +** will be silently truncated if necessary so that it does not exceed the +** compile-time maximum mmap size set by the +** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^ +** ^If either argument to this option is negative, then that argument is +** changed to its compile-time default. +** +** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] +** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE +** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is +** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro +** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value +** that specifies the maximum size of the created heap. +** +** [[SQLITE_CONFIG_PCACHE_HDRSZ]] +** <dt>SQLITE_CONFIG_PCACHE_HDRSZ +** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which +** is a pointer to an integer and writes into that integer the number of extra +** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. +** The amount of extra space required can change depending on the compiler, +** target platform, and SQLite version. +** +** [[SQLITE_CONFIG_PMASZ]] +** <dt>SQLITE_CONFIG_PMASZ +** <dd>^The SQLITE_CONFIG_PMASZ option takes a single parameter which +** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded +** sorter to that integer. The default minimum PMA Size is set by the +** [SQLITE_SORTER_PMASZ] compile-time option. New threads are launched +** to help with sort operations when multithreaded sorting +** is enabled (using the [PRAGMA threads] command) and the amount of content +** to be sorted exceeds the page size times the minimum of the +** [PRAGMA cache_size] setting and this value. +** +** [[SQLITE_CONFIG_STMTJRNL_SPILL]] +** <dt>SQLITE_CONFIG_STMTJRNL_SPILL +** <dd>^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which +** becomes the [statement journal] spill-to-disk threshold. +** [Statement journals] are held in memory until their size (in bytes) +** exceeds this threshold, at which point they are written to disk. +** Or if the threshold is -1, statement journals are always held +** exclusively in memory. +** Since many statement journals never become large, setting the spill +** threshold to a value such as 64KiB can greatly reduce the amount of +** I/O required to support statement rollback. +** The default value for this setting is controlled by the +** [SQLITE_STMTJRNL_SPILL] compile-time option. +** </dl> +*/ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ +#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ +#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ +#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ +#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ +#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ +#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ + +/* +** CAPI3REF: Database Connection Configuration Options +** +** These constants are the available integer configuration options that +** can be passed as the second argument to the [sqlite3_db_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_db_config()] to make sure that +** the call worked. ^The [sqlite3_db_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +** <dl> +** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt> +** <dd> ^This option takes three additional arguments that determine the +** [lookaside memory allocator] configuration for the [database connection]. +** ^The first argument (the third parameter to [sqlite3_db_config()] is a +** pointer to a memory buffer to use for lookaside memory. +** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb +** may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the +** size of each lookaside buffer slot. ^The third argument is the number of +** slots. The size of the buffer in the first argument must be greater than +** or equal to the product of the second and third arguments. The buffer +** must be aligned to an 8-byte boundary. ^If the second argument to +** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally +** rounded down to the next smaller multiple of 8. ^(The lookaside memory +** configuration for a database connection can only be changed when that +** connection is not currently using lookaside memory, or in other words +** when the "current value" returned by +** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. +** Any attempt to change the lookaside memory configuration when lookaside +** memory is in use leaves the configuration unchanged and returns +** [SQLITE_BUSY].)^</dd> +** +** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt> +** <dd> ^This option is used to enable or disable the enforcement of +** [foreign key constraints]. There should be two additional arguments. +** The first argument is an integer which is 0 to disable FK enforcement, +** positive to enable FK enforcement or negative to leave FK enforcement +** unchanged. The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether FK enforcement is off or on +** following this call. The second parameter may be a NULL pointer, in +** which case the FK enforcement setting is not reported back. </dd> +** +** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt> +** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers]. +** There should be two additional arguments. +** The first argument is an integer which is 0 to disable triggers, +** positive to enable triggers or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether triggers are disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the trigger setting is not reported back. </dd> +** +** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> +** <dd> ^This option is used to enable or disable the two-argument +** version of the [fts3_tokenizer()] function which is part of the +** [FTS3] full-text search engine extension. +** There should be two additional arguments. +** The first argument is an integer which is 0 to disable fts3_tokenizer() or +** positive to enable fts3_tokenizer() or negative to leave the setting +** unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the new setting is not reported back. </dd> +** +** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt> +** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()] +** interface independently of the [load_extension()] SQL function. +** The [sqlite3_enable_load_extension()] API enables or disables both the +** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. +** There should be two additional arguments. +** When the first argument to this interface is 1, then only the C-API is +** enabled and the SQL function remains disabled. If the first argument to +** this interface is 0, then both the C-API and the SQL function are disabled. +** If the first argument is -1, then no changes are made to state of either the +** C-API or the SQL function. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface +** is disabled or enabled following this call. The second parameter may +** be a NULL pointer, in which case the new setting is not reported back. +** </dd> +** +** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt> +** <dd> ^This option is used to change the name of the "main" database +** schema. ^The sole argument is a pointer to a constant UTF8 string +** which will become the new schema name in place of "main". ^SQLite +** does not make a copy of the new main schema name string, so the application +** must ensure that the argument passed into this DBCONFIG option is unchanged +** until after the database connection closes. +** </dd> +** +** </dl> +*/ +#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ +#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ +#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ + + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** METHOD: sqlite3 +** +** ^The sqlite3_extended_result_codes() routine enables or disables the +** [extended result codes] feature of SQLite. ^The extended result +** codes are disabled by default for historical compatibility. +*/ +SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** METHOD: sqlite3 +** +** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables) +** has a unique 64-bit signed +** integer key called the [ROWID | "rowid"]. ^The rowid is always available +** as an undeclared column named ROWID, OID, or _ROWID_ as long as those +** names are not also used by explicitly declared columns. ^If +** the table has a column of type [INTEGER PRIMARY KEY] then that column +** is another alias for the rowid. +** +** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the +** most recent successful [INSERT] into a rowid table or [virtual table] +** on database connection D. +** ^Inserts into [WITHOUT ROWID] tables are not recorded. +** ^If no successful [INSERT]s into rowid tables +** have ever occurred on the database connection D, +** then sqlite3_last_insert_rowid(D) returns zero. +** +** ^(If an [INSERT] occurs within a trigger or within a [virtual table] +** method, then this routine will return the [rowid] of the inserted +** row as long as the trigger or virtual table method is running. +** But once the trigger or virtual table method ends, the value returned +** by this routine reverts to what it was before the trigger or virtual +** table method began.)^ +** +** ^An [INSERT] that fails due to a constraint violation is not a +** successful [INSERT] and does not change the value returned by this +** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. ^(When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface.)^ +** +** ^For the purposes of this routine, an [INSERT] is considered to +** be successful even if it is subsequently rolled back. +** +** This function is accessible to SQL statements via the +** [last_insert_rowid() SQL function]. +** +** If a separate thread performs a new [INSERT] on the same +** database connection while the [sqlite3_last_insert_rowid()] +** function is running and thus changes the last insert [rowid], +** then the value returned by [sqlite3_last_insert_rowid()] is +** unpredictable and might not equal either the old or the new +** last insert [rowid]. +*/ +SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** METHOD: sqlite3 +** +** ^This function returns the number of rows modified, inserted or +** deleted by the most recently completed INSERT, UPDATE or DELETE +** statement on the database connection specified by the only parameter. +** ^Executing any other type of SQL statement does not modify the value +** returned by this function. +** +** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are +** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], +** [foreign key actions] or [REPLACE] constraint resolution are not counted. +** +** Changes to a view that are intercepted by +** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value +** returned by sqlite3_changes() immediately after an INSERT, UPDATE or +** DELETE statement run on a view is always zero. Only changes made to real +** tables are counted. +** +** Things are more complicated if the sqlite3_changes() function is +** executed while a trigger program is running. This may happen if the +** program uses the [changes() SQL function], or if some other callback +** function invokes sqlite3_changes() directly. Essentially: +** +** <ul> +** <li> ^(Before entering a trigger program the value returned by +** sqlite3_changes() function is saved. After the trigger program +** has finished, the original value is restored.)^ +** +** <li> ^(Within a trigger program each INSERT, UPDATE and DELETE +** statement sets the value returned by sqlite3_changes() +** upon completion as normal. Of course, this value will not include +** any changes performed by sub-triggers, as the sqlite3_changes() +** value will be saved and restored after each sub-trigger has run.)^ +** </ul> +** +** ^This means that if the changes() SQL function (or similar) is used +** by the first INSERT, UPDATE or DELETE statement within a trigger, it +** returns the value as set when the calling statement began executing. +** ^If it is used by the second or subsequent such statement within a trigger +** program, the value returned reflects the number of rows modified by the +** previous INSERT, UPDATE or DELETE statement within the same trigger. +** +** See also the [sqlite3_total_changes()] interface, the +** [count_changes pragma], and the [changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_changes()] is running then the value returned +** is unpredictable and not meaningful. +*/ +SQLITE_API int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +** METHOD: sqlite3 +** +** ^This function returns the total number of rows inserted, modified or +** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed +** since the database connection was opened, including those executed as +** part of trigger programs. ^Executing any other type of SQL statement +** does not affect the value returned by sqlite3_total_changes(). +** +** ^Changes made as part of [foreign key actions] are included in the +** count, but those made as part of REPLACE constraint resolution are +** not. ^Changes to a view that are intercepted by INSTEAD OF triggers +** are not counted. +** +** See also the [sqlite3_changes()] interface, the +** [count_changes pragma], and the [total_changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_total_changes()] is running then the value +** returned is unpredictable and not meaningful. +*/ +SQLITE_API int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** METHOD: sqlite3 +** +** ^This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** ^It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a [database connection] that +** is closed or might close before sqlite3_interrupt() returns. +** +** ^If an SQL operation is very nearly finished at the time when +** sqlite3_interrupt() is called, then it might not have an opportunity +** to be interrupted and might continue to completion. +** +** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE +** that is inside an explicit transaction, then the entire transaction +** will be rolled back automatically. +** +** ^The sqlite3_interrupt(D) call is in effect until all currently running +** SQL statements on [database connection] D complete. ^Any new SQL statements +** that are started after the sqlite3_interrupt() call and before the +** running statements reaches zero are interrupted as if they had been +** running prior to the sqlite3_interrupt() call. ^New SQL statements +** that are started after the running statement count reaches zero are +** not effected by the sqlite3_interrupt(). +** ^A call to sqlite3_interrupt(D) that occurs when there are no running +** SQL statements is a no-op and has no effect on SQL statements +** that are started after the sqlite3_interrupt() call returns. +** +** If the database connection closes while [sqlite3_interrupt()] +** is running then bad things will likely happen. +*/ +SQLITE_API void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These routines are useful during command-line input to determine if the +** currently entered text seems to form a complete SQL statement or +** if additional input is needed before sending the text into +** SQLite for parsing. ^These routines return 1 if the input string +** appears to be a complete SQL statement. ^A statement is judged to be +** complete if it ends with a semicolon token and is not a prefix of a +** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within +** string literals or quoted identifier names or comments are not +** independent tokens (they are part of the token in which they are +** embedded) and thus do not count as a statement terminator. ^Whitespace +** and comments that follow the final semicolon are ignored. +** +** ^These routines return 0 if the statement is incomplete. ^If a +** memory allocation fails, then SQLITE_NOMEM is returned. +** +** ^These routines do not parse the SQL statements thus +** will not detect syntactically incorrect SQL. +** +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked +** automatically by sqlite3_complete16(). If that initialization fails, +** then the return value from sqlite3_complete16() will be non-zero +** regardless of whether or not the input SQL is complete.)^ +** +** The input to [sqlite3_complete()] must be a zero-terminated +** UTF-8 string. +** +** The input to [sqlite3_complete16()] must be a zero-terminated +** UTF-16 string in native byte order. +*/ +SQLITE_API int sqlite3_complete(const char *sql); +SQLITE_API int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** KEYWORDS: {busy-handler callback} {busy handler} +** METHOD: sqlite3 +** +** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X +** that might be invoked with argument P whenever +** an attempt is made to access a database table associated with +** [database connection] D when another thread +** or process has the table locked. +** The sqlite3_busy_handler() interface is used to implement +** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. +** +** ^If the busy callback is NULL, then [SQLITE_BUSY] +** is returned immediately upon encountering the lock. ^If the busy callback +** is not NULL, then the callback might be invoked with two arguments. +** +** ^The first argument to the busy handler is a copy of the void* pointer which +** is the third argument to sqlite3_busy_handler(). ^The second argument to +** the busy handler callback is the number of times that the busy handler has +** been invoked previously for the same locking event. ^If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] is returned +** to the application. +** ^If the callback returns non-zero, then another attempt +** is made to access the database and the cycle repeats. +** +** The presence of a busy handler does not guarantee that it will be invoked +** when there is lock contention. ^If SQLite determines that invoking the busy +** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] +** to the application instead of invoking the +** busy handler. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** ^The default busy callback is NULL. +** +** ^(There can only be a single busy handler defined for each +** [database connection]. Setting a new busy handler clears any +** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] +** or evaluating [PRAGMA busy_timeout=N] will change the +** busy handler and thus clear any previously set busy handler. +** +** The busy callback should not take any actions which modify the +** database connection that invoked the busy handler. In other words, +** the busy handler is not reentrant. Any such actions +** result in undefined behavior. +** +** A busy handler must not close the database connection +** or [prepared statement] that invoked the busy handler. +*/ +SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*); + +/* +** CAPI3REF: Set A Busy Timeout +** METHOD: sqlite3 +** +** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps +** for a specified amount of time when a table is locked. ^The handler +** will sleep multiple times until at least "ms" milliseconds of sleeping +** have accumulated. ^After at least "ms" milliseconds of sleeping, +** the handler returns 0 which causes [sqlite3_step()] to return +** [SQLITE_BUSY]. +** +** ^Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** ^(There can only be a single busy handler for a particular +** [database connection] at any given moment. If another busy handler +** was defined (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared.)^ +** +** See also: [PRAGMA busy_timeout] +*/ +SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** METHOD: sqlite3 +** +** This is a legacy interface that is preserved for backwards compatibility. +** Use of this interface is not recommended. +** +** Definition: A <b>result table</b> is memory data structure created by the +** [sqlite3_get_table()] interface. A result table records the +** complete query results from one or more queries. +** +** The table conceptually has a number of rows and columns. But +** these numbers are not part of the result table itself. These +** numbers are obtained separately. Let N be the number of rows +** and M be the number of columns. +** +** A result table is an array of pointers to zero-terminated UTF-8 strings. +** There are (N+1)*M elements in the array. The first M pointers point +** to zero-terminated strings that contain the names of the columns. +** The remaining entries all point to query results. NULL values result +** in NULL pointers. All other values are in their UTF-8 zero-terminated +** string representation as returned by [sqlite3_column_text()]. +** +** A result table might consist of one or more memory allocations. +** It is not safe to pass a result table directly to [sqlite3_free()]. +** A result table should be deallocated using [sqlite3_free_table()]. +** +** ^(As an example of the result table format, suppose a query result +** is as follows: +** +** <blockquote><pre> +** Name | Age +** ----------------------- +** Alice | 43 +** Bob | 28 +** Cindy | 21 +** </pre></blockquote> +** +** There are two column (M==2) and three rows (N==3). Thus the +** result table has 8 entries. Suppose the result table is stored +** in an array names azResult. Then azResult holds this content: +** +** <blockquote><pre> +** azResult[0] = "Name"; +** azResult[1] = "Age"; +** azResult[2] = "Alice"; +** azResult[3] = "43"; +** azResult[4] = "Bob"; +** azResult[5] = "28"; +** azResult[6] = "Cindy"; +** azResult[7] = "21"; +** </pre></blockquote>)^ +** +** ^The sqlite3_get_table() function evaluates one or more +** semicolon-separated SQL statements in the zero-terminated UTF-8 +** string of its 2nd parameter and returns a result table to the +** pointer given in its 3rd parameter. +** +** After the application has finished with the result from sqlite3_get_table(), +** it must pass the result table pointer to sqlite3_free_table() in order to +** release the memory that was malloced. Because of the way the +** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling +** function must not try to call [sqlite3_free()] directly. Only +** [sqlite3_free_table()] is able to release the memory properly and safely. +** +** The sqlite3_get_table() interface is implemented as a wrapper around +** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access +** to any internal data structures of SQLite. It uses only the public +** interface defined here. As a consequence, errors that occur in the +** wrapper layer outside of the internal [sqlite3_exec()] call are not +** reflected in subsequent calls to [sqlite3_errcode()] or +** [sqlite3_errmsg()]. +*/ +SQLITE_API int sqlite3_get_table( + sqlite3 *db, /* An open database */ + const char *zSql, /* SQL to be evaluated */ + char ***pazResult, /* Results of the query */ + int *pnRow, /* Number of result rows written here */ + int *pnColumn, /* Number of result columns written here */ + char **pzErrmsg /* Error msg written here */ +); +SQLITE_API void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are work-alikes of the "printf()" family of functions +** from the standard C library. +** These routines understand most of the common K&R formatting options, +** plus some additional non-standard formats, detailed below. +** Note that some of the more obscure formatting options from recent +** C-library standards are omitted from this implementation. +** +** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. ^Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf().)^ This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. ^(Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer.)^ We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** ^As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. ^The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf() formatting options apply. In addition, there +** is are "%q", "%Q", "%w" and "%z" options. +** +** ^(The %q option works like %s in that it substitutes a nul-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal.)^ By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, assume the string variable zText contains text as follows: +** +** <blockquote><pre> +** char *zText = "It's a happy day!"; +** </pre></blockquote> +** +** One can use this text in an SQL statement as follows: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It''s a happy day!') +** </pre></blockquote> +** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +** <blockquote><pre> +** INSERT INTO table1 VALUES('It's a happy day!'); +** </pre></blockquote> +** +** This second example is an SQL syntax error. As a general rule you should +** always use %q instead of %s when inserting text into a string literal. +** +** ^(The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Additionally, if the parameter in the +** argument list is a NULL pointer, %Q substitutes the text "NULL" (without +** single quotes).)^ So, for example, one could say: +** +** <blockquote><pre> +** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); +** sqlite3_exec(db, zSQL, 0, 0, 0); +** sqlite3_free(zSQL); +** </pre></blockquote> +** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** ^(The "%w" formatting option is like "%q" except that it expects to +** be contained within double-quotes instead of single quotes, and it +** escapes the double-quote character instead of the single-quote +** character.)^ The "%w" formatting option is intended for safely inserting +** table and column names into a constructed SQL statement. +** +** ^(The "%z" formatting option works like "%s" but with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string.)^ +*/ +SQLITE_API char *sqlite3_mprintf(const char*,...); +SQLITE_API char *sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. "Core" in the previous sentence +** does not include operating-system specific VFS implementation. The +** Windows VFS uses native malloc() and free() for some operations. +** +** ^The sqlite3_malloc() routine returns a pointer to a block +** of memory at least N bytes in length, where N is the parameter. +** ^If sqlite3_malloc() is unable to obtain sufficient free +** memory, it returns a NULL pointer. ^If the parameter N to +** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns +** a NULL pointer. +** +** ^The sqlite3_malloc64(N) routine works just like +** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead +** of a signed 32-bit integer. +** +** ^Calling sqlite3_free() with a pointer previously returned +** by sqlite3_malloc() or sqlite3_realloc() releases that memory so +** that it might be reused. ^The sqlite3_free() routine is +** a no-op if is called with a NULL pointer. Passing a NULL pointer +** to sqlite3_free() is harmless. After being freed, memory +** should neither be read nor written. Even reading previously freed +** memory might result in a segmentation fault or other severe error. +** Memory corruption, a segmentation fault, or other severe error +** might result if sqlite3_free() is called with a non-NULL pointer that +** was not obtained from sqlite3_malloc() or sqlite3_realloc(). +** +** ^The sqlite3_realloc(X,N) interface attempts to resize a +** prior memory allocation X to be at least N bytes. +** ^If the X parameter to sqlite3_realloc(X,N) +** is a NULL pointer then its behavior is identical to calling +** sqlite3_malloc(N). +** ^If the N parameter to sqlite3_realloc(X,N) is zero or +** negative then the behavior is exactly the same as calling +** sqlite3_free(X). +** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation +** of at least N bytes in size or NULL if insufficient memory is available. +** ^If M is the size of the prior allocation, then min(N,M) bytes +** of the prior allocation are copied into the beginning of buffer returned +** by sqlite3_realloc(X,N) and the prior allocation is freed. +** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the +** prior allocation is not freed. +** +** ^The sqlite3_realloc64(X,N) interfaces works the same as +** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead +** of a 32-bit signed integer. +** +** ^If X is a memory allocation previously obtained from sqlite3_malloc(), +** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then +** sqlite3_msize(X) returns the size of that memory allocation in bytes. +** ^The value returned by sqlite3_msize(X) might be larger than the number +** of bytes requested when X was allocated. ^If X is a NULL pointer then +** sqlite3_msize(X) returns zero. If X points to something that is not +** the beginning of memory allocation, or if it points to a formerly +** valid memory allocation that has now been freed, then the behavior +** of sqlite3_msize(X) is undefined and possibly harmful. +** +** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(), +** sqlite3_malloc64(), and sqlite3_realloc64() +** is always aligned to at least an 8 byte boundary, or to a +** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time +** option is used. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be used. +** +** Prior to SQLite version 3.7.10, the Windows OS interface layer called +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular Windows +** installation. Memory allocation errors were detected, but +** they were reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +** +** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] +** must be either NULL or else pointers obtained from a prior +** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have +** not yet been released. +** +** The application must not read or write any part of +** a block of memory after it has been released using +** [sqlite3_free()] or [sqlite3_realloc()]. +*/ +SQLITE_API void *sqlite3_malloc(int); +SQLITE_API void *sqlite3_malloc64(sqlite3_uint64); +SQLITE_API void *sqlite3_realloc(void*, int); +SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64); +SQLITE_API void sqlite3_free(void*); +SQLITE_API sqlite3_uint64 sqlite3_msize(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** SQLite provides these two interfaces for reporting on the status +** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] +** routines, which form the built-in memory allocation subsystem. +** +** ^The [sqlite3_memory_used()] routine returns the number of bytes +** of memory currently outstanding (malloced but not freed). +** ^The [sqlite3_memory_highwater()] routine returns the maximum +** value of [sqlite3_memory_used()] since the high-water mark +** was last reset. ^The values returned by [sqlite3_memory_used()] and +** [sqlite3_memory_highwater()] include any overhead +** added by SQLite in its implementation of [sqlite3_malloc()], +** but not overhead added by the any underlying system library +** routines that [sqlite3_malloc()] may call. +** +** ^The memory high-water mark is reset to the current value of +** [sqlite3_memory_used()] if and only if the parameter to +** [sqlite3_memory_highwater()] is true. ^The value returned +** by [sqlite3_memory_highwater(1)] is the high-water mark +** prior to the reset. +*/ +SQLITE_API sqlite3_int64 sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Pseudo-Random Number Generator +** +** SQLite contains a high-quality pseudo-random number generator (PRNG) used to +** select random [ROWID | ROWIDs] when inserting new records into a table that +** already uses the largest possible [ROWID]. The PRNG is also used for +** the build-in random() and randomblob() SQL functions. This interface allows +** applications to access the same PRNG for other purposes. +** +** ^A call to this routine stores N bytes of randomness into buffer P. +** ^The P parameter can be a NULL pointer. +** +** ^If this routine has not been previously called or if the previous +** call had N less than one or a NULL pointer for P, then the PRNG is +** seeded using randomness obtained from the xRandomness method of +** the default [sqlite3_vfs] object. +** ^If the previous call to this routine had an N of 1 or more and a +** non-NULL P then the pseudo-randomness is generated +** internally and without recourse to the [sqlite3_vfs] xRandomness +** method. +*/ +SQLITE_API void sqlite3_randomness(int N, void *P); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +** METHOD: sqlite3 +** +** ^This routine registers an authorizer callback with a particular +** [database connection], supplied in the first argument. +** ^The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. ^The authorizer callback should +** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. ^If the authorizer callback returns +** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] +** then the [sqlite3_prepare_v2()] or equivalent call that triggered +** the authorizer will fail with an error message. +** +** When the callback returns [SQLITE_OK], that means the operation +** requested is ok. ^When the callback returns [SQLITE_DENY], the +** [sqlite3_prepare_v2()] or equivalent call that triggered the +** authorizer will fail with an error message explaining that +** access is denied. +** +** ^The first parameter to the authorizer callback is a copy of the third +** parameter to the sqlite3_set_authorizer() interface. ^The second parameter +** to the callback is an integer [SQLITE_COPY | action code] that specifies +** the particular action to be authorized. ^The third through sixth parameters +** to the callback are zero-terminated strings that contain additional +** details about the action to be authorized. +** +** ^If the action code is [SQLITE_READ] +** and the callback returns [SQLITE_IGNORE] then the +** [prepared statement] statement is constructed to substitute +** a NULL value in place of the table column that would have +** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] +** return can be used to deny an untrusted user access to individual +** columns of a table. +** ^If the action code is [SQLITE_DELETE] and the callback returns +** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the +** [truncate optimization] is disabled and all rows are deleted individually. +** +** An authorizer is used when [sqlite3_prepare | preparing] +** SQL statements from an untrusted source, to ensure that the SQL statements +** do not try to access data they are not allowed to see, or that they do not +** try to execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being [sqlite3_prepare | prepared] that +** disallows everything except [SELECT] statements. +** +** Applications that need to process SQL from untrusted sources +** might also consider lowering resource limits using [sqlite3_limit()] +** and limiting database size using the [max_page_count] [PRAGMA] +** in addition to using an authorizer. +** +** ^(Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call.)^ ^Disable the authorizer by installing a NULL callback. +** The authorizer is disabled by default. +** +** The authorizer callback must not do anything that will modify +** the database connection that invoked the authorizer callback. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the +** statement might be re-prepared during [sqlite3_step()] due to a +** schema change. Hence, the application should ensure that the +** correct authorizer callback remains in place during the [sqlite3_step()]. +** +** ^Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()], unless +** as stated in the previous paragraph, sqlite3_step() invokes +** sqlite3_prepare_v2() to reprepare a statement after a schema change. +*/ +SQLITE_API int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +** +** Note that SQLITE_IGNORE is also used as a [conflict resolution mode] +** returned from the [sqlite3_vtab_on_conflict()] interface. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorize certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization +** callback function will be parameters or NULL depending on which of these +** codes is used as the second parameter. ^(The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* Operation NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* NULL Function Name */ +#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ +#define SQLITE_COPY 0 /* No longer used */ +#define SQLITE_RECURSIVE 33 /* NULL NULL */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** METHOD: sqlite3 +** +** These routines are deprecated. Use the [sqlite3_trace_v2()] interface +** instead of the routines described here. +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** +** ^The callback function registered by sqlite3_trace() is invoked at +** various times when an SQL statement is being run by [sqlite3_step()]. +** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the +** SQL statement text as the statement first begins executing. +** ^(Additional sqlite3_trace() callbacks might occur +** as each triggered subprogram is entered. The callbacks for triggers +** contain a UTF-8 SQL comment that identifies the trigger.)^ +** +** The [SQLITE_TRACE_SIZE_LIMIT] compile-time option can be used to limit +** the length of [bound parameter] expansion in the output of sqlite3_trace(). +** +** ^The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes. ^The profile callback contains +** the original statement text and an estimate of wall-clock time +** of how long that statement took to run. ^The profile callback +** time is in units of nanoseconds, however the current implementation +** is only capable of millisecond resolution so the six least significant +** digits in the time are meaningless. Future versions of SQLite +** might provide greater resolution on the profiler callback. The +** sqlite3_profile() function is considered experimental and is +** subject to change in future versions of SQLite. +*/ +SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*, + void(*xTrace)(void*,const char*), void*); +SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: SQL Trace Event Codes +** KEYWORDS: SQLITE_TRACE +** +** These constants identify classes of events that can be monitored +** using the [sqlite3_trace_v2()] tracing logic. The third argument +** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of +** the following constants. ^The first argument to the trace callback +** is one of the following constants. +** +** New tracing constants may be added in future releases. +** +** ^A trace callback has four arguments: xCallback(T,C,P,X). +** ^The T argument is one of the integer type codes above. +** ^The C argument is a copy of the context pointer passed in as the +** fourth argument to [sqlite3_trace_v2()]. +** The P and X arguments are pointers whose meanings depend on T. +** +** <dl> +** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt> +** <dd>^An SQLITE_TRACE_STMT callback is invoked when a prepared statement +** first begins running and possibly at other times during the +** execution of the prepared statement, such as at the start of each +** trigger subprogram. ^The P argument is a pointer to the +** [prepared statement]. ^The X argument is a pointer to a string which +** is the unexpanded SQL text of the prepared statement or an SQL comment +** that indicates the invocation of a trigger. ^The callback can compute +** the same text that would have been returned by the legacy [sqlite3_trace()] +** interface by using the X argument when X begins with "--" and invoking +** [sqlite3_expanded_sql(P)] otherwise. +** +** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt> +** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same +** information as is provided by the [sqlite3_profile()] callback. +** ^The P argument is a pointer to the [prepared statement] and the +** X argument points to a 64-bit integer which is the estimated of +** the number of nanosecond that the prepared statement took to run. +** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. +** +** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt> +** <dd>^An SQLITE_TRACE_ROW callback is invoked whenever a prepared +** statement generates a single row of result. +** ^The P argument is a pointer to the [prepared statement] and the +** X argument is unused. +** +** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt> +** <dd>^An SQLITE_TRACE_CLOSE callback is invoked when a database +** connection closes. +** ^The P argument is a pointer to the [database connection] object +** and the X argument is unused. +** </dl> +*/ +#define SQLITE_TRACE_STMT 0x01 +#define SQLITE_TRACE_PROFILE 0x02 +#define SQLITE_TRACE_ROW 0x04 +#define SQLITE_TRACE_CLOSE 0x08 + +/* +** CAPI3REF: SQL Trace Hook +** METHOD: sqlite3 +** +** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback +** function X against [database connection] D, using property mask M +** and context pointer P. ^If the X callback is +** NULL or if the M mask is zero, then tracing is disabled. The +** M argument should be the bitwise OR-ed combination of +** zero or more [SQLITE_TRACE] constants. +** +** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides +** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). +** +** ^The X callback is invoked whenever any of the events identified by +** mask M occur. ^The integer return value from the callback is currently +** ignored, though this may change in future releases. Callback +** implementations should return zero to ensure future compatibility. +** +** ^A trace callback is invoked with four arguments: callback(T,C,P,X). +** ^The T argument is one of the [SQLITE_TRACE] +** constants to indicate why the callback was invoked. +** ^The C argument is a copy of the context pointer. +** The P and X arguments are pointers whose meanings depend on T. +** +** The sqlite3_trace_v2() interface is intended to replace the legacy +** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which +** are deprecated. +*/ +SQLITE_API int sqlite3_trace_v2( + sqlite3*, + unsigned uMask, + int(*xCallback)(unsigned,void*,void*,void*), + void *pCtx +); + +/* +** CAPI3REF: Query Progress Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback +** function X to be invoked periodically during long running calls to +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for +** database connection D. An example use for this +** interface is to keep a GUI updated during a large query. +** +** ^The parameter P is passed through as the only parameter to the +** callback function X. ^The parameter N is the approximate number of +** [virtual machine instructions] that are evaluated between successive +** invocations of the callback X. ^If N is less than one then the progress +** handler is disabled. +** +** ^Only a single progress handler may be defined at one time per +** [database connection]; setting a new progress handler cancels the +** old one. ^Setting parameter X to NULL disables the progress handler. +** ^The progress handler is also disabled by setting N to a value less +** than 1. +** +** ^If the progress callback returns non-zero, the operation is +** interrupted. This feature can be used to implement a +** "Cancel" button on a GUI progress dialog box. +** +** The progress handler callback must not do anything that will modify +** the database connection that invoked the progress handler. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +*/ +SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** CONSTRUCTOR: sqlite3 +** +** ^These routines open an SQLite database file as specified by the +** filename argument. ^The filename argument is interpreted as UTF-8 for +** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte +** order for sqlite3_open16(). ^(A [database connection] handle is usually +** returned in *ppDb, even if an error occurs. The only exception is that +** if SQLite is unable to allocate memory to hold the [sqlite3] object, +** a NULL will be written into *ppDb instead of a pointer to the [sqlite3] +** object.)^ ^(If the database is opened (and/or created) successfully, then +** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error following a failure of any +** of the sqlite3_open() routines. +** +** ^The default encoding will be UTF-8 for databases created using +** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases +** created using sqlite3_open16() will be UTF-16 in the native byte order. +** +** Whether or not an error occurs when it is opened, resources +** associated with the [database connection] handle should be released by +** passing it to [sqlite3_close()] when it is no longer required. +** +** The sqlite3_open_v2() interface works like sqlite3_open() +** except that it accepts two additional parameters for additional control +** over the new database connection. ^(The flags parameter to +** sqlite3_open_v2() can take one of +** the following three values, optionally combined with the +** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE], +** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^ +** +** <dl> +** ^(<dt>[SQLITE_OPEN_READONLY]</dt> +** <dd>The database is opened in read-only mode. If the database does not +** already exist, an error is returned.</dd>)^ +** +** ^(<dt>[SQLITE_OPEN_READWRITE]</dt> +** <dd>The database is opened for reading and writing if possible, or reading +** only if the file is write protected by the operating system. In either +** case the database must already exist, otherwise an error is returned.</dd>)^ +** +** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt> +** <dd>The database is opened for reading and writing, and is created if +** it does not already exist. This is the behavior that is always used for +** sqlite3_open() and sqlite3_open16().</dd>)^ +** </dl> +** +** If the 3rd parameter to sqlite3_open_v2() is not one of the +** combinations shown above optionally combined with other +** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] +** then the behavior is undefined. +** +** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection +** opens in the multi-thread [threading mode] as long as the single-thread +** mode has not been set at compile-time or start-time. ^If the +** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens +** in the serialized [threading mode] unless single-thread was +** previously selected at compile-time or start-time. +** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be +** eligible to use [shared cache mode], regardless of whether or not shared +** cache is enabled using [sqlite3_enable_shared_cache()]. ^The +** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not +** participate in [shared cache mode] even if it is enabled. +** +** ^The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system interface that +** the new database connection should use. ^If the fourth parameter is +** a NULL pointer then the default [sqlite3_vfs] object is used. +** +** ^If the filename is ":memory:", then a private, temporary in-memory database +** is created for the connection. ^This in-memory database will vanish when +** the database connection is closed. Future versions of SQLite might +** make use of additional special filenames that begin with the ":" character. +** It is recommended that when a database filename actually does begin with +** a ":" character you should prefix the filename with a pathname such as +** "./" to avoid ambiguity. +** +** ^If the filename is an empty string, then a private, temporary +** on-disk database will be created. ^This private database will be +** automatically deleted as soon as the database connection is closed. +** +** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3> +** +** ^If [URI filename] interpretation is enabled, and the filename argument +** begins with "file:", then the filename is interpreted as a URI. ^URI +** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is +** set in the fourth argument to sqlite3_open_v2(), or if it has +** been enabled globally using the [SQLITE_CONFIG_URI] option with the +** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. +** As of SQLite version 3.7.7, URI filename interpretation is turned off +** by default, but future releases of SQLite might enable URI filename +** interpretation by default. See "[URI filenames]" for additional +** information. +** +** URI filenames are parsed according to RFC 3986. ^If the URI contains an +** authority, then it must be either an empty string or the string +** "localhost". ^If the authority is not an empty string or "localhost", an +** error is returned to the caller. ^The fragment component of a URI, if +** present, is ignored. +** +** ^SQLite uses the path component of the URI as the name of the disk file +** which contains the database. ^If the path begins with a '/' character, +** then it is interpreted as an absolute path. ^If the path does not begin +** with a '/' (meaning that the authority section is omitted from the URI) +** then the path is interpreted as a relative path. +** ^(On windows, the first component of an absolute path +** is a drive specification (e.g. "C:").)^ +** +** [[core URI query parameters]] +** The query component of a URI may contain parameters that are interpreted +** either by SQLite itself, or by a [VFS | custom VFS implementation]. +** SQLite and its built-in [VFSes] interpret the +** following query parameters: +** +** <ul> +** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of +** a VFS object that provides the operating system interface that should +** be used to access the database file on disk. ^If this option is set to +** an empty string the default VFS object is used. ^Specifying an unknown +** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is +** present, then the VFS specified by the option takes precedence over +** the value passed as the fourth parameter to sqlite3_open_v2(). +** +** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw", +** "rwc", or "memory". Attempting to set it to any other value is +** an error)^. +** ^If "ro" is specified, then the database is opened for read-only +** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the +** third argument to sqlite3_open_v2(). ^If the mode option is set to +** "rw", then the database is opened for read-write (but not create) +** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had +** been set. ^Value "rwc" is equivalent to setting both +** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is +** set to "memory" then a pure [in-memory database] that never reads +** or writes from disk is used. ^It is an error to specify a value for +** the mode parameter that is less restrictive than that specified by +** the flags passed in the third parameter to sqlite3_open_v2(). +** +** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or +** "private". ^Setting it to "shared" is equivalent to setting the +** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to +** sqlite3_open_v2(). ^Setting the cache parameter to "private" is +** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. +** ^If sqlite3_open_v2() is used and the "cache" parameter is present in +** a URI filename, its value overrides any behavior requested by setting +** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. +** +** <li> <b>psow</b>: ^The psow parameter indicates whether or not the +** [powersafe overwrite] property does or does not apply to the +** storage media on which the database file resides. +** +** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter +** which if set disables file locking in rollback journal modes. This +** is useful for accessing a database on a filesystem that does not +** support locking. Caution: Database corruption might result if two +** or more processes write to the same database and any one of those +** processes uses nolock=1. +** +** <li> <b>immutable</b>: ^The immutable parameter is a boolean query +** parameter that indicates that the database file is stored on +** read-only media. ^When immutable is set, SQLite assumes that the +** database file cannot be changed, even by a process with higher +** privilege, and so the database is opened read-only and all locking +** and change detection is disabled. Caution: Setting the immutable +** property on a database file that does in fact change can result +** in incorrect query results and/or [SQLITE_CORRUPT] errors. +** See also: [SQLITE_IOCAP_IMMUTABLE]. +** +** </ul> +** +** ^Specifying an unknown parameter in the query component of a URI is not an +** error. Future versions of SQLite might understand additional query +** parameters. See "[query parameters with special meaning to SQLite]" for +** additional information. +** +** [[URI filename examples]] <h3>URI filename examples</h3> +** +** <table border="1" align=center cellpadding=5> +** <tr><th> URI filenames <th> Results +** <tr><td> file:data.db <td> +** Open the file "data.db" in the current directory. +** <tr><td> file:/home/fred/data.db<br> +** file:///home/fred/data.db <br> +** file://localhost/home/fred/data.db <br> <td> +** Open the database file "/home/fred/data.db". +** <tr><td> file://darkstar/home/fred/data.db <td> +** An error. "darkstar" is not a recognized authority. +** <tr><td style="white-space:nowrap"> +** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db +** <td> Windows only: Open the file "data.db" on fred's desktop on drive +** C:. Note that the %20 escaping in this example is not strictly +** necessary - space characters can be used literally +** in URI filenames. +** <tr><td> file:data.db?mode=ro&cache=private <td> +** Open file "data.db" in the current directory for read-only access. +** Regardless of whether or not shared-cache mode is enabled by +** default, use a private cache. +** <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td> +** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" +** that uses dot-files in place of posix advisory locking. +** <tr><td> file:data.db?mode=readonly <td> +** An error. "readonly" is not a valid option for the "mode" parameter. +** </table> +** +** ^URI hexadecimal escape sequences (%HH) are supported within the path and +** query components of a URI. A hexadecimal escape sequence consists of a +** percent sign - "%" - followed by exactly two hexadecimal digits +** specifying an octet value. ^Before the path or query components of a +** URI filename are interpreted, they are encoded using UTF-8 and all +** hexadecimal escape sequences replaced by a single byte containing the +** corresponding octet. If this process generates an invalid UTF-8 encoding, +** the results are undefined. +** +** <b>Note to Windows users:</b> The encoding used for the filename argument +** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** sqlite3_open() or sqlite3_open_v2(). +** +** <b>Note to Windows Runtime users:</b> The temporary directory must be set +** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various +** features that require the use of temporary files may fail. +** +** See also: [sqlite3_temp_directory] +*/ +SQLITE_API int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Obtain Values For URI Parameters +** +** These are utility routines, useful to VFS implementations, that check +** to see if a database file was a URI that contained a specific query +** parameter, and if so obtains the value of that query parameter. +** +** If F is the database filename pointer passed into the xOpen() method of +** a VFS implementation when the flags parameter to xOpen() has one or +** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and +** P is the name of the query parameter, then +** sqlite3_uri_parameter(F,P) returns the value of the P +** parameter if it exists or a NULL pointer if P does not appear as a +** query parameter on F. If P is a query parameter of F +** has no explicit value, then sqlite3_uri_parameter(F,P) returns +** a pointer to an empty string. +** +** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean +** parameter and returns true (1) or false (0) according to the value +** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the +** value of query parameter P is one of "yes", "true", or "on" in any +** case or if the value begins with a non-zero number. The +** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of +** query parameter P is one of "no", "false", or "off" in any case or +** if the value begins with a numeric zero. If P is not a query +** parameter on F or if the value of P is does not match any of the +** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0). +** +** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a +** 64-bit signed integer and returns that integer, or D if P does not +** exist. If the value of P is something other than an integer, then +** zero is returned. +** +** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and +** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and +** is not a database file pathname pointer that SQLite passed into the xOpen +** VFS method, then the behavior of this routine is undefined and probably +** undesirable. +*/ +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); + + +/* +** CAPI3REF: Error Codes And Messages +** METHOD: sqlite3 +** +** ^If the most recent sqlite3_* API call associated with +** [database connection] D failed, then the sqlite3_errcode(D) interface +** returns the numeric [result code] or [extended result code] for that +** API call. +** If the most recent API call was successful, +** then the return value from sqlite3_errcode() is undefined. +** ^The sqlite3_extended_errcode() +** interface is the same except that it always returns the +** [extended result code] even when extended result codes are +** disabled. +** +** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF-8 or UTF-16 respectively. +** ^(Memory to hold the error message string is managed internally. +** The application does not need to worry about freeing the result. +** However, the error string might be overwritten or deallocated by +** subsequent calls to other SQLite interface functions.)^ +** +** ^The sqlite3_errstr() interface returns the English-language text +** that describes the [result code], as UTF-8. +** ^(Memory to hold the error message string is managed internally +** and must not be freed by the application)^. +** +** When the serialized [threading mode] is in use, it might be the +** case that a second error occurs on a separate thread in between +** the time of the first error and the call to these interfaces. +** When that happens, the second error will be reported since these +** interfaces always report the most recent result. To avoid +** this, each thread can obtain exclusive use of the [database connection] D +** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning +** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after +** all calls to the interfaces listed here are completed. +** +** If an interface fails with SQLITE_MISUSE, that means the interface +** was invoked incorrectly by the application. In that case, the +** error code and message may or may not be set. +*/ +SQLITE_API int sqlite3_errcode(sqlite3 *db); +SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *sqlite3_errmsg(sqlite3*); +SQLITE_API const void *sqlite3_errmsg16(sqlite3*); +SQLITE_API const char *sqlite3_errstr(int); + +/* +** CAPI3REF: Prepared Statement Object +** KEYWORDS: {prepared statement} {prepared statements} +** +** An instance of this object represents a single SQL statement that +** has been compiled into binary form and is ready to be evaluated. +** +** Think of each SQL statement as a separate computer program. The +** original SQL text is source code. A prepared statement object +** is the compiled object code. All SQL must be converted into a +** prepared statement before it can be run. +** +** The life-cycle of a prepared statement object usually goes like this: +** +** <ol> +** <li> Create the prepared statement object using [sqlite3_prepare_v2()]. +** <li> Bind values to [parameters] using the sqlite3_bind_*() +** interfaces. +** <li> Run the SQL by calling [sqlite3_step()] one or more times. +** <li> Reset the prepared statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +** <li> Destroy the object using [sqlite3_finalize()]. +** </ol> +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Run-time Limits +** METHOD: sqlite3 +** +** ^(This interface allows the size of various constructs to be limited +** on a connection by connection basis. The first parameter is the +** [database connection] whose limit is to be set or queried. The +** second parameter is one of the [limit categories] that define a +** class of constructs to be size limited. The third parameter is the +** new limit for that construct.)^ +** +** ^If the new limit is a negative number, the limit is unchanged. +** ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a +** [limits | hard upper bound] +** set at compile-time by a C preprocessor macro called +** [limits | SQLITE_MAX_<i>NAME</i>]. +** (The "_LIMIT_" in the name is changed to "_MAX_".))^ +** ^Attempts to increase a limit above its hard upper bound are +** silently truncated to the hard upper bound. +** +** ^Regardless of whether or not the limit was changed, the +** [sqlite3_limit()] interface returns the prior value of the limit. +** ^Hence, to find the current value of a limit without changing it, +** simply invoke this interface with the third parameter set to -1. +** +** Run-time limits are intended for use in applications that manage +** both their own internal database and also databases that are controlled +** by untrusted external sources. An example application might be a +** web browser that has its own databases for storing history and +** separate databases controlled by JavaScript applications downloaded +** off the Internet. The internal databases can be given the +** large, default limits. Databases managed by external sources can +** be given much smaller limits designed to prevent a denial of service +** attack. Developers might also want to use the [sqlite3_set_authorizer()] +** interface to further control untrusted SQL. The size of the database +** created by an untrusted script can be contained using the +** [max_page_count] [PRAGMA]. +** +** New run-time limit categories may be added in future releases. +*/ +SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + +/* +** CAPI3REF: Run-Time Limit Categories +** KEYWORDS: {limit category} {*limit categories} +** +** These constants define various performance limits +** that can be lowered at run-time using [sqlite3_limit()]. +** The synopsis of the meanings of the various limits is shown below. +** Additional information is available at [limits | Limits in SQLite]. +** +** <dl> +** [[SQLITE_LIMIT_LENGTH]] ^(<dt>SQLITE_LIMIT_LENGTH</dt> +** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^ +** +** [[SQLITE_LIMIT_SQL_LENGTH]] ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt> +** <dd>The maximum length of an SQL statement, in bytes.</dd>)^ +** +** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt> +** <dd>The maximum number of columns in a table definition or in the +** result set of a [SELECT] or the maximum number of columns in an index +** or in an ORDER BY or GROUP BY clause.</dd>)^ +** +** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt> +** <dd>The maximum depth of the parse tree on any expression.</dd>)^ +** +** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt> +** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^ +** +** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt> +** <dd>The maximum number of instructions in a virtual machine program +** used to implement an SQL statement. This limit is not currently +** enforced, though that might be added in some future release of +** SQLite.</dd>)^ +** +** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt> +** <dd>The maximum number of arguments on a function.</dd>)^ +** +** [[SQLITE_LIMIT_ATTACHED]] ^(<dt>SQLITE_LIMIT_ATTACHED</dt> +** <dd>The maximum number of [ATTACH | attached databases].)^</dd> +** +** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]] +** ^(<dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt> +** <dd>The maximum length of the pattern argument to the [LIKE] or +** [GLOB] operators.</dd>)^ +** +** [[SQLITE_LIMIT_VARIABLE_NUMBER]] +** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt> +** <dd>The maximum index number of any [parameter] in an SQL statement.)^ +** +** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt> +** <dd>The maximum depth of recursion for triggers.</dd>)^ +** +** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt> +** <dd>The maximum number of auxiliary worker threads that a single +** [prepared statement] may start.</dd>)^ +** </dl> +*/ +#define SQLITE_LIMIT_LENGTH 0 +#define SQLITE_LIMIT_SQL_LENGTH 1 +#define SQLITE_LIMIT_COLUMN 2 +#define SQLITE_LIMIT_EXPR_DEPTH 3 +#define SQLITE_LIMIT_COMPOUND_SELECT 4 +#define SQLITE_LIMIT_VDBE_OP 5 +#define SQLITE_LIMIT_FUNCTION_ARG 6 +#define SQLITE_LIMIT_ATTACHED 7 +#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 +#define SQLITE_LIMIT_VARIABLE_NUMBER 9 +#define SQLITE_LIMIT_TRIGGER_DEPTH 10 +#define SQLITE_LIMIT_WORKER_THREADS 11 + +/* +** CAPI3REF: Compiling An SQL Statement +** KEYWORDS: {SQL statement compiler} +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_stmt +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument, "db", is a [database connection] obtained from a +** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or +** [sqlite3_open16()]. The database connection must not have been closed. +** +** The second argument, "zSql", is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** ^If the nByte argument is negative, then zSql is read up to the +** first zero terminator. ^If nByte is positive, then it is the +** number of bytes read from zSql. ^If nByte is zero, then no prepared +** statement is generated. +** If the caller knows that the supplied string is nul-terminated, then +** there is a small performance advantage to passing an nByte parameter that +** is the number of bytes in the input string <i>including</i> +** the nul-terminator. +** +** ^If pzTail is not NULL then *pzTail is made to point to the first byte +** past the end of the first SQL statement in zSql. These routines only +** compile the first statement in zSql, so *pzTail is left pointing to +** what remains uncompiled. +** +** ^*ppStmt is left pointing to a compiled [prepared statement] that can be +** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set +** to NULL. ^If the input text contains no SQL (if the input is an empty +** string or a comment) then *ppStmt is set to NULL. +** The calling procedure is responsible for deleting the compiled +** SQL statement using [sqlite3_finalize()] after it has finished with it. +** ppStmt may not be NULL. +** +** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; +** otherwise an [error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** ^In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave differently in three ways: +** +** <ol> +** <li> +** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. As many as [SQLITE_MAX_SCHEMA_RETRY] +** retries will occur before sqlite3_step() gives up and returns an error. +** </li> +** +** <li> +** ^When an error occurs, [sqlite3_step()] will return one of the detailed +** [error codes] or [extended error codes]. ^The legacy behavior was that +** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code +** and the application would have to make a second call to [sqlite3_reset()] +** in order to find the underlying cause of the problem. With the "v2" prepare +** interfaces, the underlying reason for the error is returned immediately. +** </li> +** +** <li> +** ^If the specific value bound to [parameter | host parameter] in the +** WHERE clause might influence the choice of query plan for a statement, +** then the statement will be automatically recompiled, as if there had been +** a schema change, on the first [sqlite3_step()] call following any change +** to the [sqlite3_bind_text | bindings] of that [parameter]. +** ^The specific value of WHERE-clause [parameter] might influence the +** choice of query plan if the parameter is the left-hand side of a [LIKE] +** or [GLOB] operator or if the parameter is compared to an indexed column +** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. +** </li> +** </ol> +*/ +SQLITE_API int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** CAPI3REF: Retrieving Statement SQL +** METHOD: sqlite3_stmt +** +** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8 +** SQL text used to create [prepared statement] P if P was +** created by either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. +** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 +** string containing the SQL text of prepared statement P with +** [bound parameters] expanded. +** +** ^(For example, if a prepared statement is created using the SQL +** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 +** and parameter :xyz is unbound, then sqlite3_sql() will return +** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() +** will return "SELECT 2345,NULL".)^ +** +** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory +** is available to hold the result, or if the result would exceed the +** the maximum string length determined by the [SQLITE_LIMIT_LENGTH]. +** +** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of +** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time +** option causes sqlite3_expanded_sql() to always return NULL. +** +** ^The string returned by sqlite3_sql(P) is managed by SQLite and is +** automatically freed when the prepared statement is finalized. +** ^The string returned by sqlite3_expanded_sql(P), on the other hand, +** is obtained from [sqlite3_malloc()] and must be free by the application +** by passing it to [sqlite3_free()]. +*/ +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); +SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Determine If An SQL Statement Writes The Database +** METHOD: sqlite3_stmt +** +** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if +** and only if the [prepared statement] X makes no direct changes to +** the content of the database file. +** +** Note that [application-defined SQL functions] or +** [virtual tables] might change the database indirectly as a side effect. +** ^(For example, if an application defines a function "eval()" that +** calls [sqlite3_exec()], then the following SQL statement would +** change the database file through side-effects: +** +** <blockquote><pre> +** SELECT eval('DELETE FROM t1') FROM t2; +** </pre></blockquote> +** +** But because the [SELECT] statement does not change the database file +** directly, sqlite3_stmt_readonly() would still return true.)^ +** +** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], +** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, +** since the statements themselves do not actually modify the database but +** rather they control the timing of when other statements modify the +** database. ^The [ATTACH] and [DETACH] statements also cause +** sqlite3_stmt_readonly() to return true since, while those statements +** change the configuration of a database connection, they do not make +** changes to the content of the database files on disk. +*/ +SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Determine If A Prepared Statement Has Been Reset +** METHOD: sqlite3_stmt +** +** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the +** [prepared statement] S has been stepped at least once using +** [sqlite3_step(S)] but has neither run to completion (returned +** [SQLITE_DONE] from [sqlite3_step(S)]) nor +** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) +** interface returns false if S is a NULL pointer. If S is not a +** NULL pointer and is not a pointer to a valid [prepared statement] +** object, then the behavior is undefined and probably undesirable. +** +** This interface can be used in combination [sqlite3_next_stmt()] +** to locate all prepared statements associated with a database +** connection that are in need of being reset. This can be used, +** for example, in diagnostic routines to search for prepared +** statements that are holding a transaction open. +*/ +SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); + +/* +** CAPI3REF: Dynamically Typed Value Object +** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} +** +** SQLite uses the sqlite3_value object to represent all values +** that can be stored in a database table. SQLite uses dynamic typing +** for the values it stores. ^Values stored in sqlite3_value objects +** can be integers, floating point values, strings, BLOBs, or NULL. +** +** An sqlite3_value object may be either "protected" or "unprotected". +** Some interfaces require a protected sqlite3_value. Other interfaces +** will accept either a protected or an unprotected sqlite3_value. +** Every interface that accepts sqlite3_value arguments specifies +** whether or not it requires a protected sqlite3_value. The +** [sqlite3_value_dup()] interface can be used to construct a new +** protected sqlite3_value from an unprotected sqlite3_value. +** +** The terms "protected" and "unprotected" refer to whether or not +** a mutex is held. An internal mutex is held for a protected +** sqlite3_value object but no mutex is held for an unprotected +** sqlite3_value object. If SQLite is compiled to be single-threaded +** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) +** or if SQLite is run in one of reduced mutex modes +** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] +** then there is no distinction between protected and unprotected +** sqlite3_value objects and they can be used interchangeably. However, +** for maximum code portability it is recommended that applications +** still make the distinction between protected and unprotected +** sqlite3_value objects even when not strictly required. +** +** ^The sqlite3_value objects that are passed as parameters into the +** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value object returned by +** [sqlite3_column_value()] is unprotected. +** Unprotected sqlite3_value objects may only be used with +** [sqlite3_result_value()] and [sqlite3_bind_value()]. +** The [sqlite3_value_blob | sqlite3_value_type()] family of +** interfaces require protected sqlite3_value objects. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. ^A pointer to an sqlite3_context object +** is always first parameter to [application-defined SQL functions]. +** The application-defined SQL function implementation will pass this +** pointer through into calls to [sqlite3_result_int | sqlite3_result()], +** [sqlite3_aggregate_context()], [sqlite3_user_data()], +** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()], +** and/or [sqlite3_set_auxdata()]. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** KEYWORDS: {host parameter} {host parameters} {host parameter name} +** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} +** METHOD: sqlite3_stmt +** +** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, +** literals may be replaced by a [parameter] that matches one of following +** templates: +** +** <ul> +** <li> ? +** <li> ?NNN +** <li> :VVV +** <li> @VVV +** <li> $VVV +** </ul> +** +** In the templates above, NNN represents an integer literal, +** and VVV represents an alphanumeric identifier.)^ ^The values of these +** parameters (also called "host parameter names" or "SQL parameters") +** can be set using the sqlite3_bind_*() routines defined here. +** +** ^The first argument to the sqlite3_bind_*() routines is always +** a pointer to the [sqlite3_stmt] object returned from +** [sqlite3_prepare_v2()] or its variants. +** +** ^The second argument is the index of the SQL parameter to be set. +** ^The leftmost SQL parameter has an index of 1. ^When the same named +** SQL parameter is used more than once, second and subsequent +** occurrences have the same index as the first occurrence. +** ^The index for named parameters can be looked up using the +** [sqlite3_bind_parameter_index()] API if desired. ^The index +** for "?NNN" parameters is the value of NNN. +** ^The NNN value must be between 1 and the [sqlite3_limit()] +** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999). +** +** ^The third argument is the value to bind to the parameter. +** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16() +** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter +** is ignored and the end result is the same as sqlite3_bind_null(). +** +** ^(In those routines that have a fourth argument, its value is the +** number of bytes in the parameter. To be clear: the value is the +** number of <u>bytes</u> in the value, not the number of characters.)^ +** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16() +** is negative, then the length of the string is +** the number of bytes up to the first zero terminator. +** If the fourth parameter to sqlite3_bind_blob() is negative, then +** the behavior is undefined. +** If a non-negative fourth parameter is provided to sqlite3_bind_text() +** or sqlite3_bind_text16() or sqlite3_bind_text64() then +** that parameter must be the byte offset +** where the NUL terminator would occur assuming the string were NUL +** terminated. If any NUL characters occur at byte offsets less than +** the value of the fourth parameter then the resulting string value will +** contain embedded NULs. The result of expressions involving strings +** with embedded NULs is undefined. +** +** ^The fifth argument to the BLOB and string binding interfaces +** is a destructor used to dispose of the BLOB or +** string after SQLite has finished with it. ^The destructor is called +** to dispose of the BLOB or string even if the call to bind API fails. +** ^If the fifth argument is +** the special value [SQLITE_STATIC], then SQLite assumes that the +** information is in static, unmanaged space and does not need to be freed. +** ^If the fifth argument has the value [SQLITE_TRANSIENT], then +** SQLite makes its own private copy of the data immediately, before +** the sqlite3_bind_*() routine returns. +** +** ^The sixth argument to sqlite3_bind_text64() must be one of +** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] +** to specify the encoding of the text in the third parameter. If +** the sixth argument to sqlite3_bind_text64() is not one of the +** allowed values shown above, or if the text encoding is different +** from the encoding specified by the sixth parameter, then the behavior +** is undefined. +** +** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that +** is filled with zeroes. ^A zeroblob uses a fixed amount of memory +** (just an integer to hold its size) while it is being processed. +** Zeroblobs are intended to serve as placeholders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | incremental BLOB I/O] routines. +** ^A negative value for the zeroblob results in a zero-length BLOB. +** +** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer +** for the [prepared statement] or with a prepared statement for which +** [sqlite3_step()] has been called more recently than [sqlite3_reset()], +** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() +** routine is passed a [prepared statement] that has been finalized, the +** result is undefined and probably harmful. +** +** ^Bindings are not cleared by the [sqlite3_reset()] routine. +** ^Unbound parameters are interpreted as NULL. +** +** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an +** [error code] if anything goes wrong. +** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB +** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or +** [SQLITE_MAX_LENGTH]. +** ^[SQLITE_RANGE] is returned if the parameter +** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. +** +** See also: [sqlite3_bind_parameter_count()], +** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, + void(*)(void*)); +SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); +SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, + void(*)(void*), unsigned char encoding); +SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); +SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); + +/* +** CAPI3REF: Number Of SQL Parameters +** METHOD: sqlite3_stmt +** +** ^This routine can be used to find the number of [SQL parameters] +** in a [prepared statement]. SQL parameters are tokens of the +** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as +** placeholders for values that are [sqlite3_bind_blob | bound] +** to the parameters at a later time. +** +** ^(This routine actually returns the index of the largest (rightmost) +** parameter. For all forms except ?NNN, this will correspond to the +** number of unique parameters. If parameters of the ?NNN form are used, +** there may be gaps in the list.)^ +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_name()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** METHOD: sqlite3_stmt +** +** ^The sqlite3_bind_parameter_name(P,N) interface returns +** the name of the N-th [SQL parameter] in the [prepared statement] P. +** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA" +** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA" +** respectively. +** In other words, the initial ":" or "$" or "@" or "?" +** is included as part of the name.)^ +** ^Parameters of the form "?" without a following integer have no name +** and are referred to as "nameless" or "anonymous parameters". +** +** ^The first host parameter has an index of 1, not 0. +** +** ^If the value N is out of range or if the N-th parameter is +** nameless, then NULL is returned. ^The returned string is +** always in UTF-8 encoding even if the named parameter was +** originally specified as UTF-16 in [sqlite3_prepare16()] or +** [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** METHOD: sqlite3_stmt +** +** ^Return the index of an SQL parameter given its name. ^The +** index value returned is suitable for use as the second +** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero +** is returned if no matching parameter is found. ^The parameter +** name must be given in UTF-8 even if the original statement +** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_name()]. +*/ +SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** METHOD: sqlite3_stmt +** +** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset +** the [sqlite3_bind_blob | bindings] on a [prepared statement]. +** ^Use this routine to reset all host parameters to NULL. +*/ +SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** METHOD: sqlite3_stmt +** +** ^Return the number of columns in the result set returned by the +** [prepared statement]. ^This routine returns 0 if pStmt is an SQL +** statement that does not return data (for example an [UPDATE]). +** +** See also: [sqlite3_data_count()] +*/ +SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** METHOD: sqlite3_stmt +** +** ^These routines return the name assigned to a particular column +** in the result set of a [SELECT] statement. ^The sqlite3_column_name() +** interface returns a pointer to a zero-terminated UTF-8 string +** and sqlite3_column_name16() returns a pointer to a zero-terminated +** UTF-16 string. ^The first parameter is the [prepared statement] +** that implements the [SELECT] statement. ^The second parameter is the +** column number. ^The leftmost column is number 0. +** +** ^The returned string pointer is valid until either the [prepared statement] +** is destroyed by [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the next call to +** sqlite3_column_name() or sqlite3_column_name16() on the same column. +** +** ^If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +** +** ^The name of a result column is the value of the "AS" clause for +** that column, if there is an AS clause. If there is no AS clause +** then the name of the column is unspecified and may change from +** one release of SQLite to the next. +*/ +SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** METHOD: sqlite3_stmt +** +** ^These routines provide a means to determine the database, table, and +** table column that is the origin of a particular result column in +** [SELECT] statement. +** ^The name of the database or table or column can be returned as +** either a UTF-8 or UTF-16 string. ^The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** ^The returned string is valid until the [prepared statement] is destroyed +** using [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the same information is requested +** again in a different encoding. +** +** ^The names returned are the original un-aliased names of the +** database, table, and column. +** +** ^The first argument to these interfaces is a [prepared statement]. +** ^These functions return information about the Nth result column returned by +** the statement, where N is the second function argument. +** ^The left-most column is column 0 for these routines. +** +** ^If the Nth column returned by the statement is an expression or +** subquery and is not a column value, then all of these functions return +** NULL. ^These routine might also return NULL if a memory allocation error +** occurs. ^Otherwise, they return the name of the attached database, table, +** or column that query result column was extracted from. +** +** ^As with all other SQLite APIs, those whose names end with "16" return +** UTF-16 encoded strings and the other functions return UTF-8. +** +** ^These APIs are only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +** +** If two or more threads call one or more +** [sqlite3_column_database_name | column metadata interfaces] +** for the same [prepared statement] and result column +** at the same time then the results are undefined. +*/ +SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** METHOD: sqlite3_stmt +** +** ^(The first parameter is a [prepared statement]. +** If this statement is a [SELECT] statement and the Nth column of the +** returned result set of that [SELECT] is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned.)^ ^If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** ^The returned string is always UTF-8 encoded. +** +** ^(For example, given the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** and the following statement to be compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** this routine would return the string "VARIANT" for the second result +** column (i==1), and a NULL pointer for the first result column (i==0).)^ +** +** ^SQLite uses dynamic run-time typing. ^So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. ^Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** METHOD: sqlite3_stmt +** +** After a [prepared statement] has been prepared using either +** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy +** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function +** must be called one or more times to evaluate the statement. +** +** The details of the behavior of the sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** ^In the legacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** ^With the "v2" interface, any of the other [result codes] or +** [extended result codes] might be returned as well. +** +** ^[SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. ^If the statement is a [COMMIT] +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a [COMMIT] and occurs within an +** explicit transaction then you should rollback the transaction before +** continuing. +** +** ^[SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** ^If the SQL statement being executed returns any data, then [SQLITE_ROW] +** is returned each time a new row of data is ready for processing by the +** caller. The values may be accessed using the [column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** ^[SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** ^With the legacy interface, a more specific error code (for example, +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [prepared statement]. ^In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** For all versions of SQLite up to and including 3.6.23.1, a call to +** [sqlite3_reset()] was required after sqlite3_step() returned anything +** other than [SQLITE_ROW] before any subsequent invocation of +** sqlite3_step(). Failure to reset the prepared statement using +** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from +** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], +** sqlite3_step() began +** calling [sqlite3_reset()] automatically in this circumstance rather +** than returning [SQLITE_MISUSE]. This is not considered a compatibility +** break because any application that ever receives an SQLITE_MISUSE error +** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option +** can be used to restore the legacy behavior. +** +** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step() +** API always returns a generic error code, [SQLITE_ERROR], following any +** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call +** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the +** specific [error codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, +** then the more specific [error codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +SQLITE_API int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: Number of columns in a result set +** METHOD: sqlite3_stmt +** +** ^The sqlite3_data_count(P) interface returns the number of columns in the +** current row of the result set of [prepared statement] P. +** ^If prepared statement P does not have results ready to return +** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of +** interfaces) then sqlite3_data_count(P) returns 0. +** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. +** ^The sqlite3_data_count(P) routine returns 0 if the previous call to +** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) +** will return non-zero if previous call to [sqlite3_step](P) returned +** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] +** where it always returns zero since each step of that multi-step +** pragma returns 0 columns of data. +** +** See also: [sqlite3_column_count()] +*/ +SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** KEYWORDS: SQLITE_TEXT +** +** ^(Every value in SQLite has one of five fundamental datatypes: +** +** <ul> +** <li> 64-bit signed integer +** <li> 64-bit IEEE floating point number +** <li> string +** <li> BLOB +** <li> NULL +** </ul>)^ +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Result Values From A Query +** KEYWORDS: {column access functions} +** METHOD: sqlite3_stmt +** +** ^These routines return information about a single column of the current +** result row of a query. ^In every case the first argument is a pointer +** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] +** that was returned from [sqlite3_prepare_v2()] or one of its variants) +** and the second argument is the index of the column for which information +** should be returned. ^The leftmost column of the result set has the index 0. +** ^The number of columns in the result can be determined using +** [sqlite3_column_count()]. +** +** If the SQL statement does not currently point to a valid row, or if the +** column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** ^The sqlite3_column_type() routine returns the +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. ^The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes() returns zero. +** +** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts +** the string to UTF-16 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes16() uses +** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. +** +** ^The values returned by [sqlite3_column_bytes()] and +** [sqlite3_column_bytes16()] do not include the zero terminators at the end +** of the string. ^For clarity: the values returned by +** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of +** bytes in the string, not the number of characters. +** +** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even empty strings, are always zero-terminated. ^The return +** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. +** +** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an +** [unprotected sqlite3_value] object. In a multithreaded environment, +** an unprotected sqlite3_value object may only be used safely with +** [sqlite3_bind_value()] and [sqlite3_result_value()]. +** If the [unprotected sqlite3_value] object returned by +** [sqlite3_column_value()] is used in any other way, including calls +** to routines like [sqlite3_value_int()], [sqlite3_value_text()], +** or [sqlite3_value_bytes()], the behavior is not threadsafe. +** +** These routines attempt to convert the value where appropriate. ^For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to perform the +** conversion automatically. ^(The following table details the conversions +** that are applied: +** +** <blockquote> +** <table border="1"> +** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion +** +** <tr><td> NULL <td> INTEGER <td> Result is 0 +** <tr><td> NULL <td> FLOAT <td> Result is 0.0 +** <tr><td> NULL <td> TEXT <td> Result is a NULL pointer +** <tr><td> NULL <td> BLOB <td> Result is a NULL pointer +** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float +** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer +** <tr><td> INTEGER <td> BLOB <td> Same as INTEGER->TEXT +** <tr><td> FLOAT <td> INTEGER <td> [CAST] to INTEGER +** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float +** <tr><td> FLOAT <td> BLOB <td> [CAST] to BLOB +** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER +** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL +** <tr><td> TEXT <td> BLOB <td> No change +** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER +** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL +** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed +** </table> +** </blockquote>)^ +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +** <ul> +** <li> The initial content is a BLOB and sqlite3_column_text() or +** sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.</li> +** <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.</li> +** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.</li> +** </ul> +** +** ^Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer references will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometimes they +** are not possible and in those cases prior pointers are invalidated. +** +** The safest policy is to invoke these routines +** in one of the following ways: +** +** <ul> +** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li> +** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li> +** </ul> +** +** In other words, you should call sqlite3_column_text(), +** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result +** into the desired format, then invoke sqlite3_column_bytes() or +** sqlite3_column_bytes16() to find the size of the result. Do not mix calls +** to sqlite3_column_text() or sqlite3_column_blob() with calls to +** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() +** with calls to sqlite3_column_bytes(). +** +** ^The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. ^The memory space used to hold strings +** and BLOBs is freed automatically. Do <em>not</em> pass the pointers returned +** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** ^(If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM].)^ +*/ +SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** DESTRUCTOR: sqlite3_stmt +** +** ^The sqlite3_finalize() function is called to delete a [prepared statement]. +** ^If the most recent evaluation of the statement encountered no errors +** or if the statement is never been evaluated, then sqlite3_finalize() returns +** SQLITE_OK. ^If the most recent evaluation of statement S failed, then +** sqlite3_finalize(S) returns the appropriate [error code] or +** [extended error code]. +** +** ^The sqlite3_finalize(S) routine can be called at any point during +** the life cycle of [prepared statement] S: +** before statement S is ever evaluated, after +** one or more calls to [sqlite3_reset()], or after any call +** to [sqlite3_step()] regardless of whether or not the statement has +** completed execution. +** +** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op. +** +** The application must finalize every [prepared statement] in order to avoid +** resource leaks. It is a grievous error for the application to try to use +** a prepared statement after it has been finalized. Any use of a prepared +** statement after it has been finalized can result in undefined and +** undesirable behavior such as segfaults and heap corruption. +*/ +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** METHOD: sqlite3_stmt +** +** The sqlite3_reset() function is called to reset a [prepared statement] +** object back to its initial state, ready to be re-executed. +** ^Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +** +** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S +** back to the beginning of its program. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], +** or if [sqlite3_step(S)] has never before been called on S, +** then [sqlite3_reset(S)] returns [SQLITE_OK]. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S indicated an error, then +** [sqlite3_reset(S)] returns an appropriate [error code]. +** +** ^The [sqlite3_reset(S)] interface does not change the values +** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. +*/ +SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** KEYWORDS: {function creation routines} +** KEYWORDS: {application-defined SQL function} +** KEYWORDS: {application-defined SQL functions} +** METHOD: sqlite3 +** +** ^These functions (collectively known as "function creation routines") +** are used to add SQL functions or aggregates or to redefine the behavior +** of existing SQL functions or aggregates. The only differences between +** these routines are the text encoding expected for +** the second parameter (the name of the function being created) +** and the presence or absence of a destructor callback for +** the application data pointer. +** +** ^The first parameter is the [database connection] to which the SQL +** function is to be added. ^If an application uses more than one database +** connection then application-defined SQL functions must be added +** to each database connection separately. +** +** ^The second parameter is the name of the SQL function to be created or +** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 +** representation, exclusive of the zero-terminator. ^Note that the name +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +** ^Any attempt to create a function with a longer name +** will result in [SQLITE_MISUSE] being returned. +** +** ^The third parameter (nArg) +** is the number of arguments that the SQL function or +** aggregate takes. ^If this parameter is -1, then the SQL function or +** aggregate may take any number of arguments between 0 and the limit +** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third +** parameter is less than -1 or greater than 127 then the behavior is +** undefined. +** +** ^The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. The application should set this parameter to +** [SQLITE_UTF16LE] if the function implementation invokes +** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the +** implementation invokes [sqlite3_value_text16be()] on an input, or +** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8] +** otherwise. ^The same SQL function may be registered multiple times using +** different preferred text encodings, with different implementations for +** each encoding. +** ^When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** +** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC] +** to signal that the function will always return the same result given +** the same inputs within a single SQL statement. Most SQL functions are +** deterministic. The built-in [random()] SQL function is an example of a +** function that is not deterministic. The SQLite query planner is able to +** perform additional optimizations on deterministic functions, so use +** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. +** +** ^(The fifth parameter is an arbitrary pointer. The implementation of the +** function can gain access to this pointer using [sqlite3_user_data()].)^ +** +** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL function or +** aggregate. ^A scalar SQL function requires an implementation of the xFunc +** callback only; NULL pointers must be passed as the xStep and xFinal +** parameters. ^An aggregate SQL function requires an implementation of xStep +** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing +** SQL function or aggregate, pass NULL pointers for all three function +** callbacks. +** +** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, +** then it is destructor for the application data pointer. +** The destructor is invoked when the function is deleted, either by being +** overloaded or when the database connection closes.)^ +** ^The destructor is also invoked if the call to +** sqlite3_create_function_v2() fails. +** ^When the destructor callback of the tenth parameter is invoked, it +** is passed a single argument which is a copy of the application data +** pointer which was the fifth parameter to sqlite3_create_function_v2(). +** +** ^It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing preferred text encodings. ^SQLite will use +** the implementation that most closely matches the way in which the +** SQL function is used. ^A function implementation with a non-negative +** nArg parameter is a better match than a function implementation with +** a negative nArg. ^A function where the preferred text encoding +** matches the database encoding is a better +** match than a function where the encoding is different. +** ^A function where the encoding difference is between UTF16le and UTF16be +** is a closer match than a function where the encoding difference is +** between UTF8 and UTF16. +** +** ^Built-in functions may be overloaded by new application-defined functions. +** +** ^An application-defined function is permitted to call other +** SQLite interfaces. However, such calls must not +** close the database connection nor finalize or reset the prepared +** statement in which the function is running. +*/ +SQLITE_API int sqlite3_create_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ +#define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ +#define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */ +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* Deprecated */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Function Flags +** +** These constants may be ORed together with the +** [SQLITE_UTF8 | preferred text encoding] as the fourth argument +** to [sqlite3_create_function()], [sqlite3_create_function16()], or +** [sqlite3_create_function_v2()]. +*/ +#define SQLITE_DETERMINISTIC 0x800 + +/* +** CAPI3REF: Deprecated Functions +** DEPRECATED +** +** These functions are [deprecated]. In order to maintain +** backwards compatibility with older code, these functions continue +** to be supported. However, new applications should avoid +** the use of these functions. To encourage programmers to avoid +** these functions, we will not explain what they do. +*/ +#ifndef SQLITE_OMIT_DEPRECATED +SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), + void*,sqlite3_int64); +#endif + +/* +** CAPI3REF: Obtaining SQL Values +** METHOD: sqlite3_value +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 3rd parameter to these callbacks is an array of pointers to +** [protected sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work only with [protected sqlite3_value] objects. +** Any attempt to use these routines on an [unprotected sqlite3_value] +** object results in undefined behavior. +** +** ^These routines work just like the corresponding [column access functions] +** except that these routines take a single [protected sqlite3_value] object +** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. +** +** ^The sqlite3_value_text16() interface extracts a UTF-16 string +** in the native byte-order of the host machine. ^The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF-16 strings as big-endian and little-endian respectively. +** +** ^(The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in other +** words, if the value is a string that looks like a number) +** then the conversion is performed. Otherwise no conversion occurs. +** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ +** +** Please pay particular attention to the fact that the pointer returned +** from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the [sqlite3_value*] parameters. +*/ +SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API double sqlite3_value_double(sqlite3_value*); +SQLITE_API int sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int sqlite3_value_type(sqlite3_value*); +SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Finding The Subtype Of SQL Values +** METHOD: sqlite3_value +** +** The sqlite3_value_subtype(V) function returns the subtype for +** an [application-defined SQL function] argument V. The subtype +** information can be used to pass a limited amount of context from +** one SQL function to another. Use the [sqlite3_result_subtype()] +** routine to set the subtype for the return value of an SQL function. +** +** SQLite makes no use of subtype itself. It merely passes the subtype +** from the result of one [application-defined SQL function] into the +** input of another. +*/ +SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); + +/* +** CAPI3REF: Copy And Free SQL Values +** METHOD: sqlite3_value +** +** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] +** object D and returns a pointer to that copy. ^The [sqlite3_value] returned +** is a [protected sqlite3_value] object even if the input is not. +** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a +** memory allocation fails. +** +** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object +** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer +** then sqlite3_value_free(V) is a harmless no-op. +*/ +SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*); +SQLITE_API void sqlite3_value_free(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** METHOD: sqlite3_context +** +** Implementations of aggregate SQL functions use this +** routine to allocate memory for storing their state. +** +** ^The first time the sqlite3_aggregate_context(C,N) routine is called +** for a particular aggregate function, SQLite +** allocates N of memory, zeroes out that memory, and returns a pointer +** to the new memory. ^On second and subsequent calls to +** sqlite3_aggregate_context() for the same aggregate function instance, +** the same buffer is returned. Sqlite3_aggregate_context() is normally +** called once for each invocation of the xStep callback and then one +** last time when the xFinal callback is invoked. ^(When no rows match +** an aggregate query, the xStep() callback of the aggregate function +** implementation is never called and xFinal() is called exactly once. +** In those cases, sqlite3_aggregate_context() might be called for the +** first time from within xFinal().)^ +** +** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer +** when first called if N is less than or equal to zero or if a memory +** allocate error occurs. +** +** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is +** determined by the N parameter on first successful call. Changing the +** value of N in subsequent call to sqlite3_aggregate_context() within +** the same aggregate function instance will not resize the memory +** allocation.)^ Within the xFinal callback, it is customary to set +** N=0 in calls to sqlite3_aggregate_context(C,N) so that no +** pointless memory allocations occur. +** +** ^SQLite automatically frees the memory allocated by +** sqlite3_aggregate_context() when the aggregate query concludes. +** +** The first parameter must be a copy of the +** [sqlite3_context | SQL function context] that is the first parameter +** to the xStep or xFinal callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** METHOD: sqlite3_context +** +** ^The sqlite3_user_data() interface returns a copy of +** the pointer that was the pUserData parameter (the 5th parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +** +** This routine must be called from the same thread in which +** the application-defined function is running. +*/ +SQLITE_API void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Database Connection For Functions +** METHOD: sqlite3_context +** +** ^The sqlite3_context_db_handle() interface returns a copy of +** the pointer to the [database connection] (the 1st parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +*/ +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** METHOD: sqlite3_context +** +** These functions may be used by (non-aggregate) SQL functions to +** associate metadata with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated metadata may be preserved. An example +** of where this might be useful is in a regular-expression matching +** function. The compiled version of the regular expression can be stored as +** metadata associated with the pattern string. +** Then as long as the pattern string remains the same, +** the compiled regular expression can be reused on multiple +** invocations of the same function. +** +** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata +** associated by the sqlite3_set_auxdata() function with the Nth argument +** value to the application-defined function. ^If there is no metadata +** associated with the function argument, this sqlite3_get_auxdata() interface +** returns a NULL pointer. +** +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th +** argument of the application-defined function. ^Subsequent +** calls to sqlite3_get_auxdata(C,N) return P from the most recent +** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or +** NULL if the metadata has been discarded. +** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, +** SQLite will invoke the destructor function X with parameter P exactly +** once, when the metadata is discarded. +** SQLite is free to discard the metadata at any time, including: <ul> +** <li> ^(when the corresponding function parameter changes)^, or +** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the +** SQL statement)^, or +** <li> ^(when sqlite3_set_auxdata() is invoked again on the same +** parameter)^, or +** <li> ^(during the original sqlite3_set_auxdata() call when a memory +** allocation error occurs.)^ </ul> +** +** Note the last bullet in particular. The destructor X in +** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the +** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() +** should be called near the end of the function implementation and the +** function implementation should not make any use of P after +** sqlite3_set_auxdata() has been called. +** +** ^(In practice, metadata is preserved between function calls for +** function parameters that are compile-time constants, including literal +** values and [parameters] and expressions composed from the same.)^ +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special values for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. ^If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. ^The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** METHOD: sqlite3_context +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the [parameter binding] family of +** functions used to bind values to host parameters in prepared statements. +** Refer to the [SQL parameter] documentation for additional information. +** +** ^The sqlite3_result_blob() interface sets the result from +** an application-defined function to be the BLOB whose content is pointed +** to by the second parameter and which is N bytes long where N is the +** third parameter. +** +** ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N) +** interfaces set the result of the application-defined function to be +** a BLOB containing all zero bytes and N bytes in size. +** +** ^The sqlite3_result_double() interface sets the result from +** an application-defined function to be a floating point value specified +** by its 2nd argument. +** +** ^The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. +** ^SQLite uses the string pointed to by the +** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() +** as the text of an error message. ^SQLite interprets the error +** message string from sqlite3_result_error() as UTF-8. ^SQLite +** interprets the string from sqlite3_result_error16() as UTF-16 in native +** byte order. ^If the third parameter to sqlite3_result_error() +** or sqlite3_result_error16() is negative then SQLite takes as the error +** message all text up through the first zero character. +** ^If the third parameter to sqlite3_result_error() or +** sqlite3_result_error16() is non-negative then SQLite takes that many +** bytes (not characters) from the 2nd parameter as the error message. +** ^The sqlite3_result_error() and sqlite3_result_error16() +** routines make a private copy of the error message text before +** they return. Hence, the calling function can deallocate or +** modify the text after they return without harm. +** ^The sqlite3_result_error_code() function changes the error code +** returned by SQLite as a result of an error in a function. ^By default, +** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() +** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. +** +** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an +** error indicating that a string or BLOB is too long to represent. +** +** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an +** error indicating that a memory allocation failed. +** +** ^The sqlite3_result_int() interface sets the return value +** of the application-defined function to be the 32-bit signed integer +** value given in the 2nd argument. +** ^The sqlite3_result_int64() interface sets the return value +** of the application-defined function to be the 64-bit signed integer +** value given in the 2nd argument. +** +** ^The sqlite3_result_null() interface sets the return value +** of the application-defined function to be NULL. +** +** ^The sqlite3_result_text(), sqlite3_result_text16(), +** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces +** set the return value of the application-defined function to be +** a text string which is represented as UTF-8, UTF-16 native byte order, +** UTF-16 little endian, or UTF-16 big endian, respectively. +** ^The sqlite3_result_text64() interface sets the return value of an +** application-defined function to be a text string in an encoding +** specified by the fifth (and last) parameter, which must be one +** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. +** ^SQLite takes the text result from the application from +** the 2nd parameter of the sqlite3_result_text* interfaces. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is negative, then SQLite takes result text from the 2nd parameter +** through the first zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is non-negative, then as many bytes (not characters) of the text +** pointed to by the 2nd parameter are taken as the application-defined +** function result. If the 3rd parameter is non-negative, then it +** must be the byte offset into the string where the NUL terminator would +** appear if the string where NUL terminated. If any NUL characters occur +** in the string at a byte offset that is less than the value of the 3rd +** parameter, then the resulting string will contain embedded NULs and the +** result of expressions operating on strings with embedded NULs is undefined. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that +** function as the destructor on the text or BLOB result when it has +** finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces or to +** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite +** assumes that the text or BLOB result is in constant space and does not +** copy the content of the parameter nor call a destructor on the content +** when it has finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT +** then SQLite makes a copy of the result into space obtained from +** from [sqlite3_malloc()] before it returns. +** +** ^The sqlite3_result_value() interface sets the result of +** the application-defined function to be a copy of the +** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The +** sqlite3_result_value() interface makes a copy of the [sqlite3_value] +** so that the [sqlite3_value] specified in the parameter may change or +** be deallocated after sqlite3_result_value() returns without harm. +** ^A [protected sqlite3_value] object may always be used where an +** [unprotected sqlite3_value] object is required, so either +** kind of [sqlite3_value] object can be used with this interface. +** +** If these routines are called from within the different thread +** than the one containing the application-defined function that received +** the [sqlite3_context] pointer, the results are undefined. +*/ +SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, + sqlite3_uint64,void(*)(void*)); +SQLITE_API void sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void sqlite3_result_null(sqlite3_context*); +SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, + void(*)(void*), unsigned char encoding); +SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); +SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); + + +/* +** CAPI3REF: Setting The Subtype Of An SQL Function +** METHOD: sqlite3_context +** +** The sqlite3_result_subtype(C,T) function causes the subtype of +** the result from the [application-defined SQL function] with +** [sqlite3_context] C to be the value T. Only the lower 8 bits +** of the subtype T are preserved in current versions of SQLite; +** higher order bits are discarded. +** The number of subtype bytes preserved by SQLite might increase +** in future releases of SQLite. +*/ +SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); + +/* +** CAPI3REF: Define New Collating Sequences +** METHOD: sqlite3 +** +** ^These functions add, remove, or modify a [collation] associated +** with the [database connection] specified as the first argument. +** +** ^The name of the collation is a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string in native byte order for sqlite3_create_collation16(). +** ^Collation names that compare equal according to [sqlite3_strnicmp()] are +** considered to be the same name. +** +** ^(The third argument (eTextRep) must be one of the constants: +** <ul> +** <li> [SQLITE_UTF8], +** <li> [SQLITE_UTF16LE], +** <li> [SQLITE_UTF16BE], +** <li> [SQLITE_UTF16], or +** <li> [SQLITE_UTF16_ALIGNED]. +** </ul>)^ +** ^The eTextRep argument determines the encoding of strings passed +** to the collating function callback, xCallback. +** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep +** force strings to be UTF16 with native byte order. +** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin +** on an even byte address. +** +** ^The fourth argument, pArg, is an application data pointer that is passed +** through as the first argument to the collating function callback. +** +** ^The fifth argument, xCallback, is a pointer to the collating function. +** ^Multiple collating functions can be registered using the same name but +** with different eTextRep parameters and SQLite will use whichever +** function requires the least amount of data transformation. +** ^If the xCallback argument is NULL then the collating function is +** deleted. ^When all collating functions having the same name are deleted, +** that collation is no longer usable. +** +** ^The collating function callback is invoked with a copy of the pArg +** application data pointer and with two strings in the encoding specified +** by the eTextRep argument. The collating function must return an +** integer that is negative, zero, or positive +** if the first string is less than, equal to, or greater than the second, +** respectively. A collating function must always return the same answer +** given the same inputs. If two or more collating functions are registered +** to the same collation name (using different eTextRep values) then all +** must give an equivalent answer when invoked with equivalent strings. +** The collating function must obey the following properties for all +** strings A, B, and C: +** +** <ol> +** <li> If A==B then B==A. +** <li> If A==B and B==C then A==C. +** <li> If A<B THEN B>A. +** <li> If A<B and B<C then A<C. +** </ol> +** +** If a collating function fails any of the above constraints and that +** collating function is registered and used, then the behavior of SQLite +** is undefined. +** +** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** with the addition that the xDestroy callback is invoked on pArg when +** the collating function is deleted. +** ^Collating functions are deleted when they are overridden by later +** calls to the collation creation functions or when the +** [database connection] is closed using [sqlite3_close()]. +** +** ^The xDestroy callback is <u>not</u> called if the +** sqlite3_create_collation_v2() function fails. Applications that invoke +** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should +** check the return code and dispose of the application data pointer +** themselves rather than expecting SQLite to deal with it for them. +** This is different from every other SQLite interface. The inconsistency +** is unfortunate but cannot be changed without breaking backwards +** compatibility. +** +** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. +*/ +SQLITE_API int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); +SQLITE_API int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +SQLITE_API int sqlite3_create_collation16( + sqlite3*, + const void *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: Collation Needed Callbacks +** METHOD: sqlite3 +** +** ^To avoid having to register all collation sequences before a database +** can be used, a single callback function may be registered with the +** [database connection] to be invoked whenever an undefined collation +** sequence is required. +** +** ^If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. ^If sqlite3_collation_needed16() is used, +** the names are passed as UTF-16 in machine native byte order. +** ^A call to either function replaces the existing collation-needed callback. +** +** ^(When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE], indicating the most desirable form of the collation +** sequence function required. The fourth parameter is the name of the +** required collation sequence.)^ +** +** The callback function should register the desired collation using +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +SQLITE_API int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +SQLITE_API int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +#ifdef SQLITE_HAS_CODEC +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); +SQLITE_API int sqlite3_key_v2( + sqlite3 *db, /* Database to be rekeyed */ + const char *zDbName, /* Name of the database */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); +SQLITE_API int sqlite3_rekey_v2( + sqlite3 *db, /* Database to be rekeyed */ + const char *zDbName, /* Name of the database */ + const void *pKey, int nKey /* The new key */ +); + +/* +** Specify the activation key for a SEE database. Unless +** activated, none of the SEE routines will work. +*/ +SQLITE_API void sqlite3_activate_see( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +#ifdef SQLITE_ENABLE_CEROD +/* +** Specify the activation key for a CEROD database. Unless +** activated, none of the CEROD routines will work. +*/ +SQLITE_API void sqlite3_activate_cerod( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** The sqlite3_sleep() function causes the current thread to suspend execution +** for at least a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** ^SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. If the xSleep() method +** of the default VFS is not implemented correctly, or not implemented at +** all, then the behavior of sqlite3_sleep() may deviate from the description +** in the previous paragraphs. +*/ +SQLITE_API int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all temporary files +** created by SQLite when using a built-in [sqlite3_vfs | VFS] +** will be placed in that directory.)^ ^If this variable +** is a NULL pointer, then SQLite performs a search for an appropriate +** temporary file directory. +** +** Applications are strongly discouraged from using this global variable. +** It is required to set a temporary folder on Windows Runtime (WinRT). +** But for all other platforms, it is highly recommended that applications +** neither read nor write this variable. This global variable is a relic +** that exists for backwards compatibility of legacy applications and should +** be avoided in new projects. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [temp_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [temp_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [temp_store_directory pragma] should be avoided. +** Except when requested by the [temp_store_directory pragma], SQLite +** does not free the memory that sqlite3_temp_directory points to. If +** the application wants that memory to be freed, it must do +** so itself, taking care to only do so after all [database connection] +** objects have been destroyed. +** +** <b>Note to Windows Runtime users:</b> The temporary directory must be set +** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various +** features that require the use of temporary files may fail. Here is an +** example of how to do this using C++ with the Windows Runtime: +** +** <blockquote><pre> +** LPCWSTR zPath = Windows::Storage::ApplicationData::Current-> +**   TemporaryFolder->Path->Data(); +** char zPathBuf[MAX_PATH + 1]; +** memset(zPathBuf, 0, sizeof(zPathBuf)); +** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf), +**   NULL, NULL); +** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf); +** </pre></blockquote> +*/ +SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Name Of The Folder Holding Database Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all database files +** specified with a relative pathname and created or accessed by +** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed +** to be relative to that directory.)^ ^If this variable is a NULL +** pointer, then SQLite assumes that all database files specified +** with a relative pathname are relative to the current directory +** for the process. Only the windows VFS makes use of this global +** variable; it is ignored by the unix VFS. +** +** Changing the value of this variable while a database connection is +** open can result in a corrupt database. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [data_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [data_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [data_store_directory pragma] should be avoided. +*/ +SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory; + +/* +** CAPI3REF: Test For Auto-Commit Mode +** KEYWORDS: {autocommit mode} +** METHOD: sqlite3 +** +** ^The sqlite3_get_autocommit() interface returns non-zero or +** zero if the given database connection is or is not in autocommit mode, +** respectively. ^Autocommit mode is on by default. +** ^Autocommit mode is disabled by a [BEGIN] statement. +** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK]. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out whether SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +SQLITE_API int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Of A Prepared Statement +** METHOD: sqlite3_stmt +** +** ^The sqlite3_db_handle interface returns the [database connection] handle +** to which a [prepared statement] belongs. ^The [database connection] +** returned by sqlite3_db_handle is the same [database connection] +** that was the first argument +** to the [sqlite3_prepare_v2()] call (or its variants) that was used to +** create the statement in the first place. +*/ +SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + +/* +** CAPI3REF: Return The Filename For A Database Connection +** METHOD: sqlite3 +** +** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename +** associated with database N of connection D. ^The main database file +** has the name "main". If there is no attached database N on the database +** connection D, or if database N is a temporary or in-memory database, then +** a NULL pointer is returned. +** +** ^The filename returned by this function is the output of the +** xFullPathname method of the [VFS]. ^In other words, the filename +** will be an absolute pathname, even if the filename used +** to open the database originally was a URI or relative pathname. +*/ +SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); + +/* +** CAPI3REF: Determine if a database is read-only +** METHOD: sqlite3 +** +** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N +** of connection D is read-only, 0 if it is read/write, or -1 if N is not +** the name of a database on connection D. +*/ +SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); + +/* +** CAPI3REF: Find the next prepared statement +** METHOD: sqlite3 +** +** ^This interface returns a pointer to the next [prepared statement] after +** pStmt associated with the [database connection] pDb. ^If pStmt is NULL +** then this interface returns a pointer to the first prepared statement +** associated with the database connection pDb. ^If no prepared statement +** satisfies the conditions of this routine, it returns NULL. +** +** The [database connection] pointer D in a call to +** [sqlite3_next_stmt(D,S)] must refer to an open database +** connection and in particular must not be a NULL pointer. +*/ +SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_commit_hook() interface registers a callback +** function to be invoked whenever a transaction is [COMMIT | committed]. +** ^Any callback set by a previous call to sqlite3_commit_hook() +** for the same database connection is overridden. +** ^The sqlite3_rollback_hook() interface registers a callback +** function to be invoked whenever a transaction is [ROLLBACK | rolled back]. +** ^Any callback set by a previous call to sqlite3_rollback_hook() +** for the same database connection is overridden. +** ^The pArg argument is passed through to the callback. +** ^If the callback on a commit hook function returns non-zero, +** then the commit is converted into a rollback. +** +** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions +** return the P argument from the previous call of the same function +** on the same [database connection] D, or NULL for +** the first call for each function on D. +** +** The commit and rollback hook callbacks are not reentrant. +** The callback implementation must not do anything that will modify +** the database connection that invoked the callback. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the commit +** or rollback hook in the first place. +** Note that running any other SQL statements, including SELECT statements, +** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify +** the database connections for the meaning of "modify" in this paragraph. +** +** ^Registering a NULL function disables the callback. +** +** ^When the commit hook callback routine returns zero, the [COMMIT] +** operation is allowed to continue normally. ^If the commit hook +** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK]. +** ^The rollback hook is invoked on a rollback that results from a commit +** hook returning non-zero, just as it would be with any other rollback. +** +** ^For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. +** ^The rollback callback is not invoked if a transaction is +** automatically rolled back because the database connection is closed. +** +** See also the [sqlite3_update_hook()] interface. +*/ +SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_update_hook() interface registers a callback function +** with the [database connection] identified by the first argument +** to be invoked whenever a row is updated, inserted or deleted in +** a [rowid table]. +** ^Any callback set by a previous call to this function +** for the same database connection is overridden. +** +** ^The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted in a rowid table. +** ^The first argument to the callback is a copy of the third argument +** to sqlite3_update_hook(). +** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], +** or [SQLITE_UPDATE], depending on the operation that caused the callback +** to be invoked. +** ^The third and fourth arguments to the callback contain pointers to the +** database and table name containing the affected row. +** ^The final callback parameter is the [rowid] of the row. +** ^In the case of an update, this is the [rowid] after the update takes place. +** +** ^(The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence).)^ +** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified. +** +** ^In the current implementation, the update hook +** is not invoked when duplication rows are deleted because of an +** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook +** invoked when rows are deleted using the [truncate optimization]. +** The exceptions defined in this paragraph might change in a future +** release of SQLite. +** +** The update hook implementation must not do anything that will modify +** the database connection that invoked the update hook. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the update hook. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^The sqlite3_update_hook(D,C,P) function +** returns the P argument from the previous call +** on the same [database connection] D, or NULL for +** the first call on D. +** +** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()], +** and [sqlite3_preupdate_hook()] interfaces. +*/ +SQLITE_API void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** ^(This routine enables or disables the sharing of the database cache +** and schema data structures between [database connection | connections] +** to the same database. Sharing is enabled if the argument is true +** and disabled if the argument is false.)^ +** +** ^Cache sharing is enabled and disabled for an entire process. +** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). +** In prior versions of SQLite, +** sharing was enabled or disabled for each thread separately. +** +** ^(The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode +** that was in effect at the time they were opened.)^ +** +** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled +** successfully. An [error code] is returned otherwise.)^ +** +** ^Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +** +** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0 +** and will always return SQLITE_MISUSE. On those systems, +** shared cache mode should be enabled per-database connection via +** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. +** +** This interface is threadsafe on processors where writing a +** 32-bit integer is atomic. +** +** See Also: [SQLite Shared-Cache Mode] +*/ +SQLITE_API int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** ^The sqlite3_release_memory() interface attempts to free N bytes +** of heap memory by deallocating non-essential memory allocations +** held by the database library. Memory used to cache database +** pages to improve performance is an example of non-essential memory. +** ^sqlite3_release_memory() returns the number of bytes actually freed, +** which might be more or less than the amount requested. +** ^The sqlite3_release_memory() routine is a no-op returning zero +** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** See also: [sqlite3_db_release_memory()] +*/ +SQLITE_API int sqlite3_release_memory(int); + +/* +** CAPI3REF: Free Memory Used By A Database Connection +** METHOD: sqlite3 +** +** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap +** memory as possible from database connection D. Unlike the +** [sqlite3_release_memory()] interface, this interface is in effect even +** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is +** omitted. +** +** See also: [sqlite3_release_memory()] +*/ +SQLITE_API int sqlite3_db_release_memory(sqlite3*); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the +** soft limit on the amount of heap memory that may be allocated by SQLite. +** ^SQLite strives to keep heap memory utilization below the soft heap +** limit by reducing the number of pages held in the page cache +** as heap memory usages approaches the limit. +** ^The soft heap limit is "soft" because even though SQLite strives to stay +** below the limit, it will exceed the limit rather than generate +** an [SQLITE_NOMEM] error. In other words, the soft heap limit +** is advisory only. +** +** ^The return value from sqlite3_soft_heap_limit64() is the size of +** the soft heap limit prior to the call, or negative in the case of an +** error. ^If the argument N is negative +** then no change is made to the soft heap limit. Hence, the current +** size of the soft heap limit can be determined by invoking +** sqlite3_soft_heap_limit64() with a negative argument. +** +** ^If the argument N is zero then the soft heap limit is disabled. +** +** ^(The soft heap limit is not enforced in the current implementation +** if one or more of following conditions are true: +** +** <ul> +** <li> The soft heap limit is set to zero. +** <li> Memory accounting is disabled using a combination of the +** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and +** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. +** <li> An alternative page cache implementation is specified using +** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). +** <li> The page cache allocates from its own memory pool supplied +** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than +** from the heap. +** </ul>)^ +** +** Beginning with SQLite [version 3.7.3] ([dateof:3.7.3]), +** the soft heap limit is enforced +** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT] +** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT], +** the soft heap limit is enforced on every memory allocation. Without +** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced +** when memory is allocated by the page cache. Testing suggests that because +** the page cache is the predominate memory user in SQLite, most +** applications will achieve adequate soft heap limit enforcement without +** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** The circumstances under which SQLite will enforce the soft heap limit may +** changes in future releases of SQLite. +*/ +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); + +/* +** CAPI3REF: Deprecated Soft Heap Limit Interface +** DEPRECATED +** +** This is a deprecated version of the [sqlite3_soft_heap_limit64()] +** interface. This routine is provided for historical compatibility +** only. All new applications should use the +** [sqlite3_soft_heap_limit64()] interface rather than this one. +*/ +SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); + + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** METHOD: sqlite3 +** +** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns +** information about column C of table T in database D +** on [database connection] X.)^ ^The sqlite3_table_column_metadata() +** interface returns SQLITE_OK and fills in the non-NULL pointers in +** the final five arguments with appropriate values if the specified +** column exists. ^The sqlite3_table_column_metadata() interface returns +** SQLITE_ERROR and if the specified column does not exist. +** ^If the column-name parameter to sqlite3_table_column_metadata() is a +** NULL pointer, then this routine simply checks for the existence of the +** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it +** does not. +** +** ^The column is identified by the second, third and fourth parameters to +** this function. ^(The second parameter is either the name of the database +** (i.e. "main", "temp", or an attached database) containing the specified +** table or NULL.)^ ^If it is NULL, then all attached databases are searched +** for the table using the same algorithm used by the database engine to +** resolve unqualified table references. +** +** ^The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. +** +** ^Metadata is returned by writing to the memory locations passed as the 5th +** and subsequent parameters to this function. ^Any of these arguments may be +** NULL, in which case the corresponding element of metadata is omitted. +** +** ^(<blockquote> +** <table border="1"> +** <tr><th> Parameter <th> Output<br>Type <th> Description +** +** <tr><td> 5th <td> const char* <td> Data type +** <tr><td> 6th <td> const char* <td> Name of default collation sequence +** <tr><td> 7th <td> int <td> True if column has a NOT NULL constraint +** <tr><td> 8th <td> int <td> True if column is part of the PRIMARY KEY +** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT] +** </table> +** </blockquote>)^ +** +** ^The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid until the next +** call to any SQLite API function. +** +** ^If the specified table is actually a view, an [error code] is returned. +** +** ^If the specified column is "rowid", "oid" or "_rowid_" and the table +** is not a [WITHOUT ROWID] table and an +** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. ^(If there is no +** [INTEGER PRIMARY KEY] column, then the outputs +** for the [rowid] are set as follows: +** +** <pre> +** data type: "INTEGER" +** collation sequence: "BINARY" +** not null: 0 +** primary key: 1 +** auto increment: 0 +** </pre>)^ +** +** ^This function causes all database schemas to be read from disk and +** parsed, if that has not already been done, and returns an error if +** any errors are encountered while loading the schema. +*/ +SQLITE_API int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** METHOD: sqlite3 +** +** ^This interface loads an SQLite extension library from the named file. +** +** ^The sqlite3_load_extension() interface attempts to load an +** [SQLite extension] library contained in the file zFile. If +** the file cannot be loaded directly, attempts are made to load +** with various operating-system specific extensions added. +** So for example, if "samplelib" cannot be loaded, then names like +** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might +** be tried also. +** +** ^The entry point is zProc. +** ^(zProc may be 0, in which case SQLite will try to come up with an +** entry point name on its own. It first tries "sqlite3_extension_init". +** If that does not work, it constructs a name "sqlite3_X_init" where the +** X is consists of the lower-case equivalent of all ASCII alphabetic +** characters in the filename from the last "/" to the first following +** "." and omitting any initial "lib".)^ +** ^The sqlite3_load_extension() interface returns +** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** ^If an error occurs and pzErrMsg is not 0, then the +** [sqlite3_load_extension()] interface shall attempt to +** fill *pzErrMsg with error message text stored in memory +** obtained from [sqlite3_malloc()]. The calling function +** should free this memory by calling [sqlite3_free()]. +** +** ^Extension loading must be enabled using +** [sqlite3_enable_load_extension()] or +** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL) +** prior to calling this API, +** otherwise an error will be returned. +** +** <b>Security warning:</b> It is recommended that the +** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this +** interface. The use of the [sqlite3_enable_load_extension()] interface +** should be avoided. This will keep the SQL function [load_extension()] +** disabled and prevent SQL injections from giving attackers +** access to extension loading capabilities. +** +** See also the [load_extension() SQL function]. +*/ +SQLITE_API int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** METHOD: sqlite3 +** +** ^So as not to open security holes in older applications that are +** unprepared to deal with [extension loading], and as a means of disabling +** [extension loading] while evaluating user-entered SQL, the following API +** is provided to turn the [sqlite3_load_extension()] mechanism on and off. +** +** ^Extension loading is off by default. +** ^Call the sqlite3_enable_load_extension() routine with onoff==1 +** to turn extension loading on and call it with onoff==0 to turn +** it back off again. +** +** ^This interface enables or disables both the C-API +** [sqlite3_load_extension()] and the SQL function [load_extension()]. +** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..) +** to enable or disable only the C-API.)^ +** +** <b>Security warning:</b> It is recommended that extension loading +** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method +** rather than this interface, so the [load_extension()] SQL function +** remains disabled. This will prevent SQL injections from giving attackers +** access to extension loading capabilities. +*/ +SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Automatically Load Statically Linked Extensions +** +** ^This interface causes the xEntryPoint() function to be invoked for +** each new [database connection] that is created. The idea here is that +** xEntryPoint() is the entry point for a statically linked [SQLite extension] +** that is to be automatically loaded into all new database connections. +** +** ^(Even though the function prototype shows that xEntryPoint() takes +** no arguments and returns void, SQLite invokes xEntryPoint() with three +** arguments and expects an integer result as if the signature of the +** entry point where as follows: +** +** <blockquote><pre> +**   int xEntryPoint( +**   sqlite3 *db, +**   const char **pzErrMsg, +**   const struct sqlite3_api_routines *pThunk +**   ); +** </pre></blockquote>)^ +** +** If the xEntryPoint routine encounters an error, it should make *pzErrMsg +** point to an appropriate error message (obtained from [sqlite3_mprintf()]) +** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg +** is NULL before calling the xEntryPoint(). ^SQLite will invoke +** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any +** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()], +** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail. +** +** ^Calling sqlite3_auto_extension(X) with an entry point X that is already +** on the list of automatic extensions is a harmless no-op. ^No entry point +** will be called more than once for each database connection that is opened. +** +** See also: [sqlite3_reset_auto_extension()] +** and [sqlite3_cancel_auto_extension()] +*/ +SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void)); + +/* +** CAPI3REF: Cancel Automatic Extension Loading +** +** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the +** initialization routine X that was registered using a prior call to +** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)] +** routine returns 1 if initialization routine X was successfully +** unregistered and it returns 0 if X was not on the list of initialization +** routines. +*/ +SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void)); + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** ^This interface disables all automatic extensions previously +** registered using [sqlite3_auto_extension()]. +*/ +SQLITE_API void sqlite3_reset_auto_extension(void); + +/* +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** CAPI3REF: Virtual Table Object +** KEYWORDS: sqlite3_module {virtual table module} +** +** This structure, sometimes called a "virtual table module", +** defines the implementation of a [virtual tables]. +** This structure consists mostly of methods for the module. +** +** ^A virtual table module is created by filling in a persistent +** instance of this structure and passing a pointer to that instance +** to [sqlite3_create_module()] or [sqlite3_create_module_v2()]. +** ^The registration remains valid until it is replaced by a different +** module or until the [database connection] closes. The content +** of this structure must not change while it is registered with +** any database connection. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + /* The methods above are in version 1 of the sqlite_module object. Those + ** below are for version 2 and greater. */ + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); +}; + +/* +** CAPI3REF: Virtual Table Indexing Information +** KEYWORDS: sqlite3_index_info +** +** The sqlite3_index_info structure and its substructures is used as part +** of the [virtual table] interface to +** pass information into and receive the reply from the [xBestIndex] +** method of a [virtual table module]. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** ^(The aConstraint[] array records WHERE clause constraints of the form: +** +** <blockquote>column OP expr</blockquote> +** +** where OP is =, <, <=, >, or >=.)^ ^(The particular operator is +** stored in aConstraint[].op using one of the +** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^ +** ^(The index of the column is stored in +** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot.)^ +** +** ^The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** ^The aConstraint[] array only reports WHERE clause terms that are +** relevant to the particular virtual table being queried. +** +** ^Information about the ORDER BY clause is stored in aOrderBy[]. +** ^Each term of aOrderBy records a column of the ORDER BY clause. +** +** The colUsed field indicates which columns of the virtual table may be +** required by the current scan. Virtual table columns are numbered from +** zero in the order in which they appear within the CREATE TABLE statement +** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62), +** the corresponding bit is set within the colUsed mask if the column may be +** required by SQLite. If the table has at least 64 columns and any column +** to the right of the first 63 is required, then bit 63 of colUsed is also +** set. In other words, column iCol may be required if the expression +** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to +** non-zero. +** +** The [xBestIndex] method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. ^If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite.)^ +** +** ^The idxNum and idxPtr values are recorded and passed into the +** [xFilter] method. +** ^[sqlite3_free()] is used to free idxPtr if and only if +** needToFreeIdxPtr is true. +** +** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** ^The estimatedCost value is an estimate of the cost of a particular +** strategy. A cost of N indicates that the cost of the strategy is similar +** to a linear scan of an SQLite table with N rows. A cost of log(N) +** indicates that the expense of the operation is similar to that of a +** binary search on a unique indexed field of an SQLite table with N rows. +** +** ^The estimatedRows value is an estimate of the number of rows that +** will be returned by the strategy. +** +** The xBestIndex method may optionally populate the idxFlags field with a +** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag - +** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite +** assumes that the strategy may visit at most one row. +** +** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then +** SQLite also assumes that if a call to the xUpdate() method is made as +** part of the same statement to delete or update a virtual table row and the +** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback +** any database changes. In other words, if the xUpdate() returns +** SQLITE_CONSTRAINT, the database contents must be exactly as they were +** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not +** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by +** the xUpdate method are automatically rolled back by SQLite. +** +** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info +** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). +** If a virtual table extension is +** used with an SQLite version earlier than 3.8.2, the results of attempting +** to read or write the estimatedRows field are undefined (but are likely +** to included crashing the application). The estimatedRows field should +** therefore only be used if [sqlite3_libversion_number()] returns a +** value greater than or equal to 3008002. Similarly, the idxFlags field +** was added for [version 3.9.0] ([dateof:3.9.0]). +** It may therefore only be used if +** sqlite3_libversion_number() returns a value greater than or equal to +** 3009000. +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column constrained. -1 for ROWID */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ + /* Fields below are only available in SQLite 3.8.2 and later */ + sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ + /* Fields below are only available in SQLite 3.9.0 and later */ + int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */ + /* Fields below are only available in SQLite 3.10.0 and later */ + sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */ +}; + +/* +** CAPI3REF: Virtual Table Scan Flags +*/ +#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ + +/* +** CAPI3REF: Virtual Table Constraint Operator Codes +** +** These macros defined the allowed values for the +** [sqlite3_index_info].aConstraint[].op field. Each value represents +** an operator that is part of a constraint term in the wHERE clause of +** a query that uses a [virtual table]. +*/ +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 +#define SQLITE_INDEX_CONSTRAINT_LIKE 65 +#define SQLITE_INDEX_CONSTRAINT_GLOB 66 +#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 + +/* +** CAPI3REF: Register A Virtual Table Implementation +** METHOD: sqlite3 +** +** ^These routines are used to register a new [virtual table module] name. +** ^Module names must be registered before +** creating a new [virtual table] using the module and before using a +** preexisting [virtual table] for the module. +** +** ^The module name is registered on the [database connection] specified +** by the first parameter. ^The name of the module is given by the +** second parameter. ^The third parameter is a pointer to +** the implementation of the [virtual table module]. ^The fourth +** parameter is an arbitrary client data pointer that is passed through +** into the [xCreate] and [xConnect] methods of the virtual table module +** when a new virtual table is be being created or reinitialized. +** +** ^The sqlite3_create_module_v2() interface has a fifth parameter which +** is a pointer to a destructor for the pClientData. ^SQLite will +** invoke the destructor function (if it is not NULL) when SQLite +** no longer needs the pClientData pointer. ^The destructor will also +** be invoked if the call to sqlite3_create_module_v2() fails. +** ^The sqlite3_create_module() +** interface is equivalent to sqlite3_create_module_v2() with a NULL +** destructor. +*/ +SQLITE_API int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData /* Client data for xCreate/xConnect */ +); +SQLITE_API int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** CAPI3REF: Virtual Table Instance Object +** KEYWORDS: sqlite3_vtab +** +** Every [virtual table module] implementation uses a subclass +** of this object to describe a particular instance +** of the [virtual table]. Each subclass will +** be tailored to the specific needs of the module implementation. +** The purpose of this superclass is to define certain fields that are +** common to all module implementations. +** +** ^Virtual tables methods can set an error message by assigning a +** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should +** take care that any prior string is freed by a call to [sqlite3_free()] +** prior to assigning a new string to zErrMsg. ^After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Number of open cursors */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Virtual Table Cursor Object +** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor} +** +** Every [virtual table module] implementation uses a subclass of the +** following structure to describe cursors that point into the +** [virtual table] and are used +** to loop through the virtual table. Cursors are created using the +** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed +** by the [sqlite3_module.xClose | xClose] method. Cursors are used +** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods +** of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Declare The Schema Of A Virtual Table +** +** ^The [xCreate] and [xConnect] methods of a +** [virtual table module] call this interface +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); + +/* +** CAPI3REF: Overload A Function For A Virtual Table +** METHOD: sqlite3 +** +** ^(Virtual tables can provide alternative implementations of functions +** using the [xFindFunction] method of the [virtual table module]. +** But global versions of those functions +** must exist in order to be overloaded.)^ +** +** ^(This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created.)^ ^The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a placeholder function that can be overloaded +** by a [virtual table]. +*/ +SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** KEYWORDS: {BLOB handle} {BLOB handles} +** +** An instance of this object represents an open BLOB on which +** [sqlite3_blob_open | incremental BLOB I/O] can be performed. +** ^Objects of this type are created by [sqlite3_blob_open()] +** and destroyed by [sqlite3_blob_close()]. +** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the BLOB. +** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_blob +** +** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located +** in row iRow, column zColumn, table zTable in database zDb; +** in other words, the same BLOB that would be selected by: +** +** <pre> +** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow; +** </pre>)^ +** +** ^(Parameter zDb is not the filename that contains the database, but +** rather the symbolic name of the database. For attached databases, this is +** the name that appears after the AS keyword in the [ATTACH] statement. +** For the main database file, the database name is "main". For TEMP +** tables, the database name is "temp".)^ +** +** ^If the flags parameter is non-zero, then the BLOB is opened for read +** and write access. ^If the flags parameter is zero, the BLOB is opened for +** read-only access. +** +** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored +** in *ppBlob. Otherwise an [error code] is returned and, unless the error +** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided +** the API is not misused, it is always safe to call [sqlite3_blob_close()] +** on *ppBlob after this function it returns. +** +** This function fails with SQLITE_ERROR if any of the following are true: +** <ul> +** <li> ^(Database zDb does not exist)^, +** <li> ^(Table zTable does not exist within database zDb)^, +** <li> ^(Table zTable is a WITHOUT ROWID table)^, +** <li> ^(Column zColumn does not exist)^, +** <li> ^(Row iRow is not present in the table)^, +** <li> ^(The specified column of row iRow contains a value that is not +** a TEXT or BLOB value)^, +** <li> ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE +** constraint and the blob is being opened for read/write access)^, +** <li> ^([foreign key constraints | Foreign key constraints] are enabled, +** column zColumn is part of a [child key] definition and the blob is +** being opened for read/write access)^. +** </ul> +** +** ^Unless it returns SQLITE_MISUSE, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** +** +** ^(If the row that a BLOB handle points to is modified by an +** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects +** then the BLOB handle is marked as "expired". +** This is true if any column of the row is changed, even a column +** other than the one the BLOB handle is open on.)^ +** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for +** an expired BLOB handle fail with a return code of [SQLITE_ABORT]. +** ^(Changes written into a BLOB prior to the BLOB expiring are not +** rolled back by the expiration of the BLOB. Such changes will eventually +** commit if the transaction continues to completion.)^ +** +** ^Use the [sqlite3_blob_bytes()] interface to determine the size of +** the opened blob. ^The size of a blob may not be changed by this +** interface. Use the [UPDATE] SQL command to change the size of a +** blob. +** +** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces +** and the built-in [zeroblob] SQL function may be used to create a +** zero-filled blob to read or write using the incremental-blob interface. +** +** To avoid a resource leak, every open [BLOB handle] should eventually +** be released by a call to [sqlite3_blob_close()]. +*/ +SQLITE_API int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Move a BLOB Handle to a New Row +** METHOD: sqlite3_blob +** +** ^This function is used to move an existing blob handle so that it points +** to a different row of the same database table. ^The new row is identified +** by the rowid value passed as the second argument. Only the row can be +** changed. ^The database, table and column on which the blob handle is open +** remain the same. Moving an existing blob handle to a new row can be +** faster than closing the existing handle and opening a new one. +** +** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - +** it must exist and there must be either a blob or text value stored in +** the nominated column.)^ ^If the new row is not present in the table, or if +** it does not contain a blob or text value, or if another error occurs, an +** SQLite error code is returned and the blob handle is considered aborted. +** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or +** [sqlite3_blob_reopen()] on an aborted blob handle immediately return +** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle +** always returns zero. +** +** ^This function sets the database handle error code and message. +*/ +SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); + +/* +** CAPI3REF: Close A BLOB Handle +** DESTRUCTOR: sqlite3_blob +** +** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed +** unconditionally. Even if this routine returns an error code, the +** handle is still closed.)^ +** +** ^If the blob handle being closed was opened for read-write access, and if +** the database is in auto-commit mode and there are no other open read-write +** blob handles or active write statements, the current transaction is +** committed. ^If an error occurs while committing the transaction, an error +** code is returned and the transaction rolled back. +** +** Calling this function with an argument that is not a NULL pointer or an +** open blob handle results in undefined behaviour. ^Calling this routine +** with a null pointer (such as would be returned by a failed call to +** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function +** is passed a valid open blob handle, the values returned by the +** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. +*/ +SQLITE_API int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** METHOD: sqlite3_blob +** +** ^Returns the size in bytes of the BLOB accessible via the +** successfully opened [BLOB handle] in its only argument. ^The +** incremental blob I/O routines can only read or overwriting existing +** blob content; they cannot change the size of a blob. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +*/ +SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** METHOD: sqlite3_blob +** +** ^(This function is used to read data from an open [BLOB handle] into a +** caller-supplied buffer. N bytes of data are copied into buffer Z +** from the open BLOB, starting at offset iOffset.)^ +** +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is +** less than zero, [SQLITE_ERROR] is returned and no data is read. +** ^The size of the blob (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to read from an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. +** +** ^(On success, sqlite3_blob_read() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_write()]. +*/ +SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** METHOD: sqlite3_blob +** +** ^(This function is used to write data into an open [BLOB handle] from a +** caller-supplied buffer. N bytes of data are copied from the buffer Z +** into the open BLOB, starting at offset iOffset.)^ +** +** ^(On success, sqlite3_blob_write() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** ^Unless SQLITE_MISUSE is returned, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** +** ^If the [BLOB handle] passed as the first argument was not opened for +** writing (the flags parameter to [sqlite3_blob_open()] was zero), +** this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the BLOB; it is +** not possible to increase the size of a BLOB using this API. +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is written. The size of the +** BLOB (and hence the maximum value of N+iOffset) can be determined +** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less +** than zero [SQLITE_ERROR] is returned and no data is written. +** +** ^An attempt to write to an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred +** before the [BLOB handle] expired are not rolled back by the +** expiration of the handle, though of course those changes might +** have been overwritten by the statement that expired the BLOB handle +** or by other independent statements. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_read()]. +*/ +SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most SQLite builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name. +** ^Names are case sensitive. +** ^Names are zero-terminated UTF-8 strings. +** ^If there is no match, a NULL pointer is returned. +** ^If zVfsName is NULL then the default VFS is returned. +** +** ^New VFSes are registered with sqlite3_vfs_register(). +** ^Each new VFS becomes the default VFS if the makeDflt flag is set. +** ^The same VFS can be registered multiple times without injury. +** ^To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. +** ^(If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary.)^ +*/ +SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +** <ul> +** <li> SQLITE_MUTEX_PTHREADS +** <li> SQLITE_MUTEX_W32 +** <li> SQLITE_MUTEX_NOOP +** </ul> +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_PTHREADS and +** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix +** and Windows. +** +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. In this case the +** application must supply a custom mutex implementation using the +** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function +** before calling sqlite3_initialize() or any other public sqlite3_ +** function that calls sqlite3_initialize(). +** +** ^The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() +** routine returns NULL if it is unable to allocate the requested +** mutex. The argument to sqlite3_mutex_alloc() must one of these +** integer constants: +** +** <ul> +** <li> SQLITE_MUTEX_FAST +** <li> SQLITE_MUTEX_RECURSIVE +** <li> SQLITE_MUTEX_STATIC_MASTER +** <li> SQLITE_MUTEX_STATIC_MEM +** <li> SQLITE_MUTEX_STATIC_OPEN +** <li> SQLITE_MUTEX_STATIC_PRNG +** <li> SQLITE_MUTEX_STATIC_LRU +** <li> SQLITE_MUTEX_STATIC_PMEM +** <li> SQLITE_MUTEX_STATIC_APP1 +** <li> SQLITE_MUTEX_STATIC_APP2 +** <li> SQLITE_MUTEX_STATIC_APP3 +** <li> SQLITE_MUTEX_STATIC_VFS1 +** <li> SQLITE_MUTEX_STATIC_VFS2 +** <li> SQLITE_MUTEX_STATIC_VFS3 +** </ul> +** +** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) +** cause sqlite3_mutex_alloc() to create +** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other +** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return +** a pointer to a static preexisting mutex. ^Nine static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. ^For the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** ^The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. Attempting to deallocate a static +** mutex results in undefined behavior. +** +** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. ^If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK] +** upon successful entry. ^(Mutexes created using +** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. +** In such cases, the +** mutex must be exited an equal number of times before another thread +** can enter.)^ If the same thread tries to enter any mutex other +** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined. +** +** ^(Some systems (for example, Windows 95) do not support the operation +** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() +** will always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable +** behavior.)^ +** +** ^The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. +** +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +** sqlite3_mutex_leave() is a NULL pointer, then all three routines +** behave as no-ops. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); +SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Methods Object +** +** An instance of this structure defines the low-level routines +** used to allocate and use mutexes. +** +** Usually, the default mutex implementations provided by SQLite are +** sufficient, however the application has the option of substituting a custom +** implementation for specialized deployments or systems for which SQLite +** does not provide a suitable implementation. In this case, the application +** creates and populates an instance of this structure to pass +** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. +** Additionally, an instance of this structure can be used as an +** output variable when querying the system for the current mutex +** implementation, using the [SQLITE_CONFIG_GETMUTEX] option. +** +** ^The xMutexInit method defined by this structure is invoked as +** part of system initialization by the sqlite3_initialize() function. +** ^The xMutexInit routine is called by SQLite exactly once for each +** effective call to [sqlite3_initialize()]. +** +** ^The xMutexEnd method defined by this structure is invoked as +** part of system shutdown by the sqlite3_shutdown() function. The +** implementation of this method is expected to release all outstanding +** resources obtained by the mutex methods implementation, especially +** those obtained by the xMutexInit method. ^The xMutexEnd() +** interface is invoked exactly once for each call to [sqlite3_shutdown()]. +** +** ^(The remaining seven methods defined by this structure (xMutexAlloc, +** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and +** xMutexNotheld) implement the following interfaces (respectively): +** +** <ul> +** <li> [sqlite3_mutex_alloc()] </li> +** <li> [sqlite3_mutex_free()] </li> +** <li> [sqlite3_mutex_enter()] </li> +** <li> [sqlite3_mutex_try()] </li> +** <li> [sqlite3_mutex_leave()] </li> +** <li> [sqlite3_mutex_held()] </li> +** <li> [sqlite3_mutex_notheld()] </li> +** </ul>)^ +** +** The only difference is that the public sqlite3_XXX functions enumerated +** above silently ignore any invocations that pass a NULL pointer instead +** of a valid mutex handle. The implementations of the methods defined +** by this structure are not required to handle this case, the results +** of passing a NULL pointer instead of a valid mutex handle are undefined +** (i.e. it is acceptable to provide an implementation that segfaults if +** it is passed a NULL pointer). +** +** The xMutexInit() method must be threadsafe. It must be harmless to +** invoke xMutexInit() multiple times within the same process and without +** intervening calls to xMutexEnd(). Second and subsequent calls to +** xMutexInit() must be no-ops. +** +** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] +** and its associates). Similarly, xMutexAlloc() must not use SQLite memory +** allocation for a static mutex. ^However xMutexAlloc() may use SQLite +** memory allocation for a fast or recursive mutex. +** +** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is +** called, but only if the prior call to xMutexInit returned SQLITE_OK. +** If xMutexInit fails in any way, it is expected to clean up after itself +** prior to returning. +*/ +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; +struct sqlite3_mutex_methods { + int (*xMutexInit)(void); + int (*xMutexEnd)(void); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); +}; + +/* +** CAPI3REF: Mutex Verification Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The SQLite core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provide versions of these +** routines that actually work. If the implementation does not provide working +** versions of these routines, it should at least provide stubs that always +** return true so that one does not get spurious assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +#ifndef NDEBUG +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); +#endif + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +** +** The set of static mutexes may change from one SQLite release to the +** next. Applications that override the built-in mutex logic must be +** prepared to accommodate additional static mutexes. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ +#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ +#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ +#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ +#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ +#define SQLITE_MUTEX_STATIC_VFS1 11 /* For use by built-in VFS */ +#define SQLITE_MUTEX_STATIC_VFS2 12 /* For use by extension VFS */ +#define SQLITE_MUTEX_STATIC_VFS3 13 /* For use by application VFS */ + +/* +** CAPI3REF: Retrieve the mutex for a database connection +** METHOD: sqlite3 +** +** ^This interface returns a pointer the [sqlite3_mutex] object that +** serializes access to the [database connection] given in the argument +** when the [threading mode] is Serialized. +** ^If the [threading mode] is Single-thread or Multi-thread then this +** routine returns a NULL pointer. +*/ +SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); + +/* +** CAPI3REF: Low-Level Control Of Database Files +** METHOD: sqlite3 +** +** ^The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. ^The +** name of the database is "main" for the main database or "temp" for the +** TEMP database, or the name that appears after the AS keyword for +** databases that are added using the [ATTACH] SQL command. +** ^A NULL pointer can be used in place of "main" to refer to the +** main database file. +** ^The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. ^The return value of the xFileControl +** method becomes the return value of this routine. +** +** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes +** a pointer to the underlying [sqlite3_file] object to be written into +** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER +** case is a short-circuit path which does not actually invoke the +** underlying sqlite3_io_methods.xFileControl method. +** +** ^If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. ^This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** CAPI3REF: Testing Interface +** +** ^The sqlite3_test_control() interface is used to read out internal +** state of SQLite and to inject faults into SQLite for testing +** purposes. ^The first parameter is an operation code that determines +** the number, meaning, and operation of all subsequent parameters. +** +** This interface is not for use by applications. It exists solely +** for verifying the correct operation of the SQLite library. Depending +** on how the SQLite library is compiled, this interface might not exist. +** +** The details of the operation codes, their meanings, the parameters +** they take, and what they do are all subject to change without notice. +** Unlike most of the SQLite API, this function is not guaranteed to +** operate consistently from one release to the next. +*/ +SQLITE_API int sqlite3_test_control(int op, ...); + +/* +** CAPI3REF: Testing Interface Operation Codes +** +** These constants are the valid operation code parameters used +** as the first argument to [sqlite3_test_control()]. +** +** These parameters and their meanings are subject to change +** without notice. These values are for testing purposes only. +** Applications should not use any of these parameters or the +** [sqlite3_test_control()] interface. +*/ +#define SQLITE_TESTCTRL_FIRST 5 +#define SQLITE_TESTCTRL_PRNG_SAVE 5 +#define SQLITE_TESTCTRL_PRNG_RESTORE 6 +#define SQLITE_TESTCTRL_PRNG_RESET 7 +#define SQLITE_TESTCTRL_BITVEC_TEST 8 +#define SQLITE_TESTCTRL_FAULT_INSTALL 9 +#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 +#define SQLITE_TESTCTRL_PENDING_BYTE 11 +#define SQLITE_TESTCTRL_ASSERT 12 +#define SQLITE_TESTCTRL_ALWAYS 13 +#define SQLITE_TESTCTRL_RESERVE 14 +#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 +#define SQLITE_TESTCTRL_ISKEYWORD 16 +#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 +#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ +#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 +#define SQLITE_TESTCTRL_NEVER_CORRUPT 20 +#define SQLITE_TESTCTRL_VDBE_COVERAGE 21 +#define SQLITE_TESTCTRL_BYTEORDER 22 +#define SQLITE_TESTCTRL_ISINIT 23 +#define SQLITE_TESTCTRL_SORTER_MMAP 24 +#define SQLITE_TESTCTRL_IMPOSTER 25 +#define SQLITE_TESTCTRL_LAST 25 + +/* +** CAPI3REF: SQLite Runtime Status +** +** ^These interfaces are used to retrieve runtime status information +** about the performance of SQLite, and optionally to reset various +** highwater marks. ^The first argument is an integer code for +** the specific parameter to measure. ^(Recognized integer codes +** are of the form [status parameters | SQLITE_STATUS_...].)^ +** ^The current value of the parameter is returned into *pCurrent. +** ^The highest recorded value is returned in *pHighwater. ^If the +** resetFlag is true, then the highest record value is reset after +** *pHighwater is written. ^(Some parameters do not record the highest +** value. For those parameters +** nothing is written into *pHighwater and the resetFlag is ignored.)^ +** ^(Other parameters record only the highwater mark and not the current +** value. For these latter parameters nothing is written into *pCurrent.)^ +** +** ^The sqlite3_status() and sqlite3_status64() routines return +** SQLITE_OK on success and a non-zero [error code] on failure. +** +** If either the current value or the highwater mark is too large to +** be represented by a 32-bit integer, then the values returned by +** sqlite3_status() are undefined. +** +** See also: [sqlite3_db_status()] +*/ +SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLITE_API int sqlite3_status64( + int op, + sqlite3_int64 *pCurrent, + sqlite3_int64 *pHighwater, + int resetFlag +); + + +/* +** CAPI3REF: Status Parameters +** KEYWORDS: {status parameters} +** +** These integer constants designate various run-time status parameters +** that can be returned by [sqlite3_status()]. +** +** <dl> +** [[SQLITE_STATUS_MEMORY_USED]] ^(<dt>SQLITE_STATUS_MEMORY_USED</dt> +** <dd>This parameter is the current amount of memory checked out +** using [sqlite3_malloc()], either directly or indirectly. The +** figure includes calls made to [sqlite3_malloc()] by the application +** and internal memory usage by the SQLite library. Scratch memory +** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache +** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in +** this parameter. The amount returned is the sum of the allocation +** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^ +** +** [[SQLITE_STATUS_MALLOC_SIZE]] ^(<dt>SQLITE_STATUS_MALLOC_SIZE</dt> +** <dd>This parameter records the largest memory allocation request +** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their +** internal equivalents). Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.</dd>)^ +** +** [[SQLITE_STATUS_MALLOC_COUNT]] ^(<dt>SQLITE_STATUS_MALLOC_COUNT</dt> +** <dd>This parameter records the number of separate memory allocations +** currently checked out.</dd>)^ +** +** [[SQLITE_STATUS_PAGECACHE_USED]] ^(<dt>SQLITE_STATUS_PAGECACHE_USED</dt> +** <dd>This parameter returns the number of pages used out of the +** [pagecache memory allocator] that was configured using +** [SQLITE_CONFIG_PAGECACHE]. The +** value returned is in pages, not in bytes.</dd>)^ +** +** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] +** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt> +** <dd>This parameter returns the number of bytes of page cache +** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] +** buffer and where forced to overflow to [sqlite3_malloc()]. The +** returned value includes allocations that overflowed because they +** where too large (they were larger than the "sz" parameter to +** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because +** no space was left in the page cache.</dd>)^ +** +** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt> +** <dd>This parameter records the largest memory allocation request +** handed to [pagecache memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.</dd>)^ +** +** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt> +** <dd>This parameter returns the number of allocations used out of the +** [scratch memory allocator] configured using +** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not +** in bytes. Since a single thread may only have one scratch allocation +** outstanding at time, this parameter also reports the number of threads +** using scratch memory at the same time.</dd>)^ +** +** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt> +** <dd>This parameter returns the number of bytes of scratch memory +** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] +** buffer and where forced to overflow to [sqlite3_malloc()]. The values +** returned include overflows because the requested allocation was too +** larger (that is, because the requested allocation was larger than the +** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer +** slots were available. +** </dd>)^ +** +** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt> +** <dd>This parameter records the largest memory allocation request +** handed to [scratch memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.</dd>)^ +** +** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt> +** <dd>The *pHighwater parameter records the deepest parser stack. +** The *pCurrent value is undefined. The *pHighwater value is only +** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^ +** </dl> +** +** New status parameters may be added from time to time. +*/ +#define SQLITE_STATUS_MEMORY_USED 0 +#define SQLITE_STATUS_PAGECACHE_USED 1 +#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 +#define SQLITE_STATUS_SCRATCH_USED 3 +#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 +#define SQLITE_STATUS_MALLOC_SIZE 5 +#define SQLITE_STATUS_PARSER_STACK 6 +#define SQLITE_STATUS_PAGECACHE_SIZE 7 +#define SQLITE_STATUS_SCRATCH_SIZE 8 +#define SQLITE_STATUS_MALLOC_COUNT 9 + +/* +** CAPI3REF: Database Connection Status +** METHOD: sqlite3 +** +** ^This interface is used to retrieve runtime status information +** about a single [database connection]. ^The first argument is the +** database connection object to be interrogated. ^The second argument +** is an integer constant, taken from the set of +** [SQLITE_DBSTATUS options], that +** determines the parameter to interrogate. The set of +** [SQLITE_DBSTATUS options] is likely +** to grow in future releases of SQLite. +** +** ^The current value of the requested parameter is written into *pCur +** and the highest instantaneous value is written into *pHiwtr. ^If +** the resetFlg is true, then the highest instantaneous value is +** reset back down to the current value. +** +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** +** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. +*/ +SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); + +/* +** CAPI3REF: Status Parameters for database connections +** KEYWORDS: {SQLITE_DBSTATUS options} +** +** These constants are the available integer "verbs" that can be passed as +** the second argument to the [sqlite3_db_status()] interface. +** +** New verbs may be added in future releases of SQLite. Existing verbs +** might be discontinued. Applications should check the return code from +** [sqlite3_db_status()] to make sure that the call worked. +** The [sqlite3_db_status()] interface will return a non-zero error code +** if a discontinued or unsupported verb is invoked. +** +** <dl> +** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt> +** <dd>This parameter returns the number of lookaside memory slots currently +** checked out.</dd>)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt> +** <dd>This parameter returns the number malloc attempts that were +** satisfied using lookaside memory. Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] +** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt> +** <dd>This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to the amount of +** memory requested being larger than the lookaside slot size. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] +** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt> +** <dd>This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to all lookaside +** memory already being in use. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt> +** <dd>This parameter returns the approximate number of bytes of heap +** memory used by all pager caches associated with the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. +** +** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] +** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt> +** <dd>This parameter is similar to DBSTATUS_CACHE_USED, except that if a +** pager cache is shared between two or more connections the bytes of heap +** memory used by that pager cache is divided evenly between the attached +** connections.)^ In other words, if none of the pager caches associated +** with the database connection are shared, this request returns the same +** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are +** shared, the value returned by this call will be smaller than that returned +** by DBSTATUS_CACHE_USED. ^The highwater mark associated with +** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. +** +** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt> +** <dd>This parameter returns the approximate number of bytes of heap +** memory used to store the schema for all databases associated +** with the connection - main, temp, and any [ATTACH]-ed databases.)^ +** ^The full amount of memory used by the schemas is reported, even if the +** schema memory is shared with other database connections due to +** [shared cache mode] being enabled. +** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. +** +** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt> +** <dd>This parameter returns the approximate number of bytes of heap +** and lookaside memory used by all prepared statements associated with +** the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. +** </dd> +** +** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt> +** <dd>This parameter returns the number of pager cache hits that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT +** is always 0. +** </dd> +** +** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt> +** <dd>This parameter returns the number of pager cache misses that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS +** is always 0. +** </dd> +** +** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt> +** <dd>This parameter returns the number of dirty cache entries that have +** been written to disk. Specifically, the number of pages written to the +** wal file in wal mode databases, or the number of pages written to the +** database file in rollback mode databases. Any pages written as part of +** transaction rollback or database recovery operations are not included. +** If an IO or other error occurs while writing a page to disk, the effect +** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The +** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. +** </dd> +** +** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> +** <dd>This parameter returns zero for the current value if and only if +** all foreign key constraints (deferred or immediate) have been +** resolved.)^ ^The highwater mark is always 0. +** </dd> +** </dl> +*/ +#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 +#define SQLITE_DBSTATUS_CACHE_USED 1 +#define SQLITE_DBSTATUS_SCHEMA_USED 2 +#define SQLITE_DBSTATUS_STMT_USED 3 +#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 +#define SQLITE_DBSTATUS_CACHE_HIT 7 +#define SQLITE_DBSTATUS_CACHE_MISS 8 +#define SQLITE_DBSTATUS_CACHE_WRITE 9 +#define SQLITE_DBSTATUS_DEFERRED_FKS 10 +#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 +#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */ + + +/* +** CAPI3REF: Prepared Statement Status +** METHOD: sqlite3_stmt +** +** ^(Each prepared statement maintains various +** [SQLITE_STMTSTATUS counters] that measure the number +** of times it has performed specific operations.)^ These counters can +** be used to monitor the performance characteristics of the prepared +** statements. For example, if the number of table steps greatly exceeds +** the number of table searches or result rows, that would tend to indicate +** that the prepared statement is using a full table scan rather than +** an index. +** +** ^(This interface is used to retrieve and reset counter values from +** a [prepared statement]. The first argument is the prepared statement +** object to be interrogated. The second argument +** is an integer code for a specific [SQLITE_STMTSTATUS counter] +** to be interrogated.)^ +** ^The current value of the requested counter is returned. +** ^If the resetFlg is true, then the counter is reset to zero after this +** interface call returns. +** +** See also: [sqlite3_status()] and [sqlite3_db_status()]. +*/ +SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); + +/* +** CAPI3REF: Status Parameters for prepared statements +** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters} +** +** These preprocessor macros define integer codes that name counter +** values associated with the [sqlite3_stmt_status()] interface. +** The meanings of the various counters are as follows: +** +** <dl> +** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]] <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt> +** <dd>^This is the number of times that SQLite has stepped forward in +** a table as part of a full table scan. Large numbers for this counter +** may indicate opportunities for performance improvement through +** careful use of indices.</dd> +** +** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt> +** <dd>^This is the number of sort operations that have occurred. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance through careful use of indices.</dd> +** +** [[SQLITE_STMTSTATUS_AUTOINDEX]] <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt> +** <dd>^This is the number of rows inserted into transient indices that +** were created automatically in order to help joins run faster. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance by adding permanent indices that do not +** need to be reinitialized each time the statement is run.</dd> +** +** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt> +** <dd>^This is the number of virtual machine operations executed +** by the prepared statement if that number is less than or equal +** to 2147483647. The number of virtual machine operations can be +** used as a proxy for the total work done by the prepared statement. +** If the number of virtual machine operations exceeds 2147483647 +** then the value returned by this statement status code is undefined. +** </dd> +** </dl> +*/ +#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 +#define SQLITE_STMTSTATUS_SORT 2 +#define SQLITE_STMTSTATUS_AUTOINDEX 3 +#define SQLITE_STMTSTATUS_VM_STEP 4 + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache type is opaque. It is implemented by +** the pluggable module. The SQLite core has no knowledge of +** its size or internal structure and never deals with the +** sqlite3_pcache object except by holding and passing pointers +** to the object. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache sqlite3_pcache; + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache_page object represents a single page in the +** page cache. The page cache will allocate instances of this +** object. Various methods of the page cache use pointers to instances +** of this object as parameters or as their return value. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { + void *pBuf; /* The content of the page */ + void *pExtra; /* Extra information associated with the page */ +}; + +/* +** CAPI3REF: Application Defined Page Cache. +** KEYWORDS: {page cache} +** +** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can +** register an alternative page cache implementation by passing in an +** instance of the sqlite3_pcache_methods2 structure.)^ +** In many applications, most of the heap memory allocated by +** SQLite is used for the page cache. +** By implementing a +** custom page cache using this API, an application can better control +** the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for +** how long. +** +** The alternative page cache mechanism is an +** extreme measure that is only needed by the most demanding applications. +** The built-in page cache is recommended for most uses. +** +** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an +** internal buffer by SQLite within the call to [sqlite3_config]. Hence +** the application may discard the parameter after the call to +** [sqlite3_config()] returns.)^ +** +** [[the xInit() page cache method]] +** ^(The xInit() method is called once for each effective +** call to [sqlite3_initialize()])^ +** (usually only once during the lifetime of the process). ^(The xInit() +** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ +** The intent of the xInit() method is to set up global data structures +** required by the custom page cache implementation. +** ^(If the xInit() method is NULL, then the +** built-in default page cache is used instead of the application defined +** page cache.)^ +** +** [[the xShutdown() page cache method]] +** ^The xShutdown() method is called by [sqlite3_shutdown()]. +** It can be used to clean up +** any outstanding resources before process shutdown, if required. +** ^The xShutdown() method may be NULL. +** +** ^SQLite automatically serializes calls to the xInit method, +** so the xInit method need not be threadsafe. ^The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. All other methods must be threadsafe +** in multithreaded applications. +** +** ^SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +** +** [[the xCreate() page cache methods]] +** ^SQLite invokes the xCreate() method to construct a new cache instance. +** SQLite will typically create one cache instance for each open database file, +** though this is not guaranteed. ^The +** first parameter, szPage, is the size in bytes of the pages that must +** be allocated by the cache. ^szPage will always a power of two. ^The +** second parameter szExtra is a number of bytes of extra storage +** associated with each page cache entry. ^The szExtra parameter will +** a number less than 250. SQLite will use the +** extra szExtra bytes on each page to store metadata about the underlying +** database page on disk. The value passed into szExtra depends +** on the SQLite version, the target platform, and how SQLite was compiled. +** ^The third argument to xCreate(), bPurgeable, is true if the cache being +** created will be used to cache database pages of a file stored on disk, or +** false if it is used for an in-memory database. The cache implementation +** does not have to do anything special based with the value of bPurgeable; +** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will +** never invoke xUnpin() except to deliberately delete a page. +** ^In other words, calls to xUnpin() on a cache with bPurgeable set to +** false will always have the "discard" flag set to true. +** ^Hence, a cache created with bPurgeable false will +** never contain any unpinned pages. +** +** [[the xCachesize() page cache method]] +** ^(The xCachesize() method may be called at any time by SQLite to set the +** suggested maximum cache-size (number of pages stored by) the cache +** instance passed as the first argument. This is the value configured using +** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable +** parameter, the implementation is not required to do anything with this +** value; it is advisory only. +** +** [[the xPagecount() page cache methods]] +** The xPagecount() method must return the number of pages currently +** stored in the cache, both pinned and unpinned. +** +** [[the xFetch() page cache methods]] +** The xFetch() method locates a page in the cache and returns a pointer to +** an sqlite3_pcache_page object associated with that page, or a NULL pointer. +** The pBuf element of the returned sqlite3_pcache_page object will be a +** pointer to a buffer of szPage bytes used to store the content of a +** single database page. The pExtra element of sqlite3_pcache_page will be +** a pointer to the szExtra bytes of extra storage that SQLite has requested +** for each entry in the page cache. +** +** The page to be fetched is determined by the key. ^The minimum key value +** is 1. After it has been retrieved using xFetch, the page is considered +** to be "pinned". +** +** If the requested page is already in the page cache, then the page cache +** implementation must return a pointer to the page buffer with its content +** intact. If the requested page is not already in the cache, then the +** cache implementation should use the value of the createFlag +** parameter to help it determined what action to take: +** +** <table border=1 width=85% align=center> +** <tr><th> createFlag <th> Behavior when page is not already in cache +** <tr><td> 0 <td> Do not allocate a new page. Return NULL. +** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so. +** Otherwise return NULL. +** <tr><td> 2 <td> Make every effort to allocate a new page. Only return +** NULL if allocating a new page is effectively impossible. +** </table> +** +** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite +** will only use a createFlag of 2 after a prior call with a createFlag of 1 +** failed.)^ In between the to xFetch() calls, SQLite may +** attempt to unpin one or more cache pages by spilling the content of +** pinned pages to disk and synching the operating system disk cache. +** +** [[the xUnpin() page cache method]] +** ^xUnpin() is called by SQLite with a pointer to a currently pinned page +** as its second argument. If the third parameter, discard, is non-zero, +** then the page must be evicted from the cache. +** ^If the discard parameter is +** zero, then the page may be discarded or retained at the discretion of +** page cache implementation. ^The page cache implementation +** may choose to evict unpinned pages at any time. +** +** The cache must not perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls +** to xFetch(). +** +** [[the xRekey() page cache methods]] +** The xRekey() method is used to change the key value associated with the +** page passed as the second argument. If the cache +** previously contains an entry associated with newKey, it must be +** discarded. ^Any prior cache entry associated with newKey is guaranteed not +** to be pinned. +** +** When SQLite calls the xTruncate() method, the cache must discard all +** existing cache entries with page numbers (keys) greater than or equal +** to the value of the iLimit parameter passed to xTruncate(). If any +** of these pages are pinned, they are implicitly unpinned, meaning that +** they can be safely discarded. +** +** [[the xDestroy() page cache method]] +** ^The xDestroy() method is used to delete a cache allocated by xCreate(). +** All resources associated with the specified cache should be freed. ^After +** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] +** handle invalid, and will not use it with any other sqlite3_pcache_methods2 +** functions. +** +** [[the xShrink() page cache method]] +** ^SQLite invokes the xShrink() method when it wants the page cache to +** free up as much of heap memory as possible. The page cache implementation +** is not obligated to free any memory, but well-behaved implementations should +** do their best. +*/ +typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; +struct sqlite3_pcache_methods2 { + int iVersion; + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); + void (*xShrink)(sqlite3_pcache*); +}; + +/* +** This is the obsolete pcache_methods object that has now been replaced +** by sqlite3_pcache_methods2. This object is not used by SQLite. It is +** retained in the header file for backwards compatibility only. +*/ +typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; +struct sqlite3_pcache_methods { + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, void*, int discard); + void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); +}; + + +/* +** CAPI3REF: Online Backup Object +** +** The sqlite3_backup object records state information about an ongoing +** online backup operation. ^The sqlite3_backup object is created by +** a call to [sqlite3_backup_init()] and is destroyed by a call to +** [sqlite3_backup_finish()]. +** +** See Also: [Using the SQLite Online Backup API] +*/ +typedef struct sqlite3_backup sqlite3_backup; + +/* +** CAPI3REF: Online Backup API. +** +** The backup API copies the content of one database into another. +** It is useful either for creating backups of databases or +** for copying in-memory databases to or from persistent files. +** +** See Also: [Using the SQLite Online Backup API] +** +** ^SQLite holds a write transaction open on the destination database file +** for the duration of the backup operation. +** ^The source database is read-locked only while it is being read; +** it is not locked continuously for the entire backup operation. +** ^Thus, the backup may be performed on a live source database without +** preventing other database connections from +** reading or writing to the source database while the backup is underway. +** +** ^(To perform a backup operation: +** <ol> +** <li><b>sqlite3_backup_init()</b> is called once to initialize the +** backup, +** <li><b>sqlite3_backup_step()</b> is called one or more times to transfer +** the data between the two databases, and finally +** <li><b>sqlite3_backup_finish()</b> is called to release all resources +** associated with the backup operation. +** </ol>)^ +** There should be exactly one call to sqlite3_backup_finish() for each +** successful call to sqlite3_backup_init(). +** +** [[sqlite3_backup_init()]] <b>sqlite3_backup_init()</b> +** +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database +** and the database name, respectively. +** ^The database name is "main" for the main database, "temp" for the +** temporary database, or the name specified after the AS keyword in +** an [ATTACH] statement for an attached database. +** ^The S and M arguments passed to +** sqlite3_backup_init(D,N,S,M) identify the [database connection] +** and database name of the source database, respectively. +** ^The source and destination [database connections] (parameters S and D) +** must be different or else sqlite3_backup_init(D,N,S,M) will fail with +** an error. +** +** ^A call to sqlite3_backup_init() will fail, returning NULL, if +** there is already a read or read-write transaction open on the +** destination database. +** +** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is +** returned and an error code and error message are stored in the +** destination [database connection] D. +** ^The error code and message for the failed call to sqlite3_backup_init() +** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or +** [sqlite3_errmsg16()] functions. +** ^A successful call to sqlite3_backup_init() returns a pointer to an +** [sqlite3_backup] object. +** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and +** sqlite3_backup_finish() functions to perform the specified backup +** operation. +** +** [[sqlite3_backup_step()]] <b>sqlite3_backup_step()</b> +** +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** the source and destination databases specified by [sqlite3_backup] object B. +** ^If N is negative, all remaining source pages are copied. +** ^If sqlite3_backup_step(B,N) successfully copies N pages and there +** are still more pages to be copied, then the function returns [SQLITE_OK]. +** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages +** from source to destination, then it returns [SQLITE_DONE]. +** ^If an error occurs while running sqlite3_backup_step(B,N), +** then an [error code] is returned. ^As well as [SQLITE_OK] and +** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY], +** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. +** +** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if +** <ol> +** <li> the destination database was opened read-only, or +** <li> the destination database is using write-ahead-log journaling +** and the destination and source page sizes differ, or +** <li> the destination database is an in-memory database and the +** destination and source page sizes differ. +** </ol>)^ +** +** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then +** the [sqlite3_busy_handler | busy-handler function] +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then +** [SQLITE_BUSY] is returned to the caller. ^In this case the call to +** sqlite3_backup_step() can be retried later. ^If the source +** [database connection] +** is being used to write to the source database when sqlite3_backup_step() +** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this +** case the call to sqlite3_backup_step() can be retried later on. ^(If +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or +** [SQLITE_READONLY] is returned, then +** there is no point in retrying the call to sqlite3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle +** to the sqlite3_backup_finish() to release associated resources. +** +** ^The first call to sqlite3_backup_step() obtains an exclusive lock +** on the destination file. ^The exclusive lock is not released until either +** sqlite3_backup_finish() is called or the backup operation is complete +** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to +** sqlite3_backup_step() obtains a [shared lock] on the source database that +** lasts for the duration of the sqlite3_backup_step() call. +** ^Because the source database is not locked between calls to +** sqlite3_backup_step(), the source database may be modified mid-way +** through the backup process. ^If the source database is modified by an +** external process or via a database connection other than the one being +** used by the backup operation, then the backup will be automatically +** restarted by the next call to sqlite3_backup_step(). ^If the source +** database is modified by the using the same database connection as is used +** by the backup operation, then the backup database is automatically +** updated at the same time. +** +** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b> +** +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the +** application wishes to abandon the backup operation, the application +** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). +** ^The sqlite3_backup_finish() interfaces releases all +** resources associated with the [sqlite3_backup] object. +** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any +** active write-transaction on the destination database is rolled back. +** The [sqlite3_backup] object is invalid +** and may not be used following a call to sqlite3_backup_finish(). +** +** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no +** sqlite3_backup_step() errors occurred, regardless or whether or not +** sqlite3_backup_step() completed. +** ^If an out-of-memory condition or IO error occurred during any prior +** sqlite3_backup_step() call on the same [sqlite3_backup] object, then +** sqlite3_backup_finish() returns the corresponding [error code]. +** +** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() +** is not a permanent error and does not affect the return value of +** sqlite3_backup_finish(). +** +** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]] +** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b> +** +** ^The sqlite3_backup_remaining() routine returns the number of pages still +** to be backed up at the conclusion of the most recent sqlite3_backup_step(). +** ^The sqlite3_backup_pagecount() routine returns the total number of pages +** in the source database at the conclusion of the most recent +** sqlite3_backup_step(). +** ^(The values returned by these functions are only updated by +** sqlite3_backup_step(). If the source database is modified in a way that +** changes the size of the source database or the number of pages remaining, +** those changes are not reflected in the output of sqlite3_backup_pagecount() +** and sqlite3_backup_remaining() until after the next +** sqlite3_backup_step().)^ +** +** <b>Concurrent Usage of Database Handles</b> +** +** ^The source [database connection] may be used by the application for other +** purposes while a backup operation is underway or being initialized. +** ^If SQLite is compiled and configured to support threadsafe database +** connections, then the source database connection may be used concurrently +** from within other threads. +** +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after +** sqlite3_backup_init() is called and before the corresponding call to +** sqlite3_backup_finish(). SQLite does not currently check to see +** if the application incorrectly accesses the destination [database connection] +** and so no error code is reported, but the operations may malfunction +** nevertheless. Use of the destination database connection while a +** backup is in progress might also also cause a mutex deadlock. +** +** If running in [shared cache mode], the application must +** guarantee that the shared cache used by the destination database +** is not accessed while the backup is running. In practice this means +** that the application must guarantee that the disk file being +** backed up to is not accessed by any connection within the process, +** not just the specific connection that was passed to sqlite3_backup_init(). +** +** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** threads may safely make multiple concurrent calls to sqlite3_backup_step(). +** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** APIs are not strictly speaking threadsafe. If they are invoked at the +** same time as another thread is invoking sqlite3_backup_step() it is +** possible that they return invalid values. +*/ +SQLITE_API sqlite3_backup *sqlite3_backup_init( + sqlite3 *pDest, /* Destination database handle */ + const char *zDestName, /* Destination database name */ + sqlite3 *pSource, /* Source database handle */ + const char *zSourceName /* Source database name */ +); +SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); + +/* +** CAPI3REF: Unlock Notification +** METHOD: sqlite3 +** +** ^When running in shared-cache mode, a database operation may fail with +** an [SQLITE_LOCKED] error if the required locks on the shared-cache or +** individual tables within the shared-cache cannot be obtained. See +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke +** when the connection currently holding the required lock relinquishes it. +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. +** +** See Also: [Using the SQLite Unlock Notification Feature]. +** +** ^Shared-cache locks are released when a database connection concludes +** its current transaction, either by committing it or rolling it back. +** +** ^When a connection (known as the blocked connection) fails to obtain a +** shared-cache lock and SQLITE_LOCKED is returned to the caller, the +** identity of the database connection (the blocking connection) that +** has locked the required resource is stored internally. ^After an +** application receives an SQLITE_LOCKED error, it may call the +** sqlite3_unlock_notify() method with the blocked connection handle as +** the first argument to register for a callback that will be invoked +** when the blocking connections current transaction is concluded. ^The +** callback is invoked from within the [sqlite3_step] or [sqlite3_close] +** call that concludes the blocking connections transaction. +** +** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, +** there is a chance that the blocking connection will have already +** concluded its transaction by the time sqlite3_unlock_notify() is invoked. +** If this happens, then the specified callback is invoked immediately, +** from within the call to sqlite3_unlock_notify().)^ +** +** ^If the blocked connection is attempting to obtain a write-lock on a +** shared-cache table, and more than one other connection currently holds +** a read-lock on the same table, then SQLite arbitrarily selects one of +** the other connections to use as the blocking connection. +** +** ^(There may be at most one unlock-notify callback registered by a +** blocked connection. If sqlite3_unlock_notify() is called when the +** blocked connection already has a registered unlock-notify callback, +** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is +** called with a NULL pointer as its second argument, then any existing +** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback may also be canceled by closing the blocked +** connection using [sqlite3_close()]. +** +** The unlock-notify callback is not reentrant. If an application invokes +** any sqlite3_xxx API functions from within an unlock-notify callback, a +** crash or deadlock may be the result. +** +** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always +** returns SQLITE_OK. +** +** <b>Callback Invocation Details</b> +** +** When an unlock-notify callback is registered, the application provides a +** single void* pointer that is passed to the callback when it is invoked. +** However, the signature of the callback function allows SQLite to pass +** it an array of void* context pointers. The first argument passed to +** an unlock-notify callback is a pointer to an array of void* pointers, +** and the second is the number of entries in the array. +** +** When a blocking connections transaction is concluded, there may be +** more than one blocked connection that has registered for an unlock-notify +** callback. ^If two or more such blocked connections have specified the +** same callback function, then instead of invoking the callback function +** multiple times, it is invoked once with the set of void* context pointers +** specified by the blocked connections bundled together into an array. +** This gives the application an opportunity to prioritize any actions +** related to the set of unblocked database connections. +** +** <b>Deadlock Detection</b> +** +** Assuming that after registering for an unlock-notify callback a +** database waits for the callback to be issued before taking any further +** action (a reasonable assumption), then using this API may cause the +** application to deadlock. For example, if connection X is waiting for +** connection Y's transaction to be concluded, and similarly connection +** Y is waiting on connection X's transaction, then neither connection +** will proceed and the system may remain deadlocked indefinitely. +** +** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock +** detection. ^If a given call to sqlite3_unlock_notify() would put the +** system in a deadlocked state, then SQLITE_LOCKED is returned and no +** unlock-notify callback is registered. The system is said to be in +** a deadlocked state if connection A has registered for an unlock-notify +** callback on the conclusion of connection B's transaction, and connection +** B has itself registered for an unlock-notify callback when connection +** A's transaction is concluded. ^Indirect deadlock is also detected, so +** the system is also considered to be deadlocked if connection B has +** registered for an unlock-notify callback on the conclusion of connection +** C's transaction, where connection C is waiting on connection A. ^Any +** number of levels of indirection are allowed. +** +** <b>The "DROP TABLE" Exception</b> +** +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** always appropriate to call sqlite3_unlock_notify(). There is however, +** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, +** SQLite checks if there are any currently executing SELECT statements +** that belong to the same connection. If there are, SQLITE_LOCKED is +** returned. In this case there is no "blocking connection", so invoking +** sqlite3_unlock_notify() results in the unlock-notify callback being +** invoked immediately. If the application then re-attempts the "DROP TABLE" +** or "DROP INDEX" query, an infinite loop might be the result. +** +** One way around this problem is to check the extended error code returned +** by an sqlite3_step() call. ^(If there is a blocking connection, then the +** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in +** the special "DROP TABLE/INDEX" case, the extended error code is just +** SQLITE_LOCKED.)^ +*/ +SQLITE_API int sqlite3_unlock_notify( + sqlite3 *pBlocked, /* Waiting connection */ + void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ + void *pNotifyArg /* Argument to pass to xNotify */ +); + + +/* +** CAPI3REF: String Comparison +** +** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications +** and extensions to compare the contents of two buffers containing UTF-8 +** strings in a case-independent fashion, using the same definition of "case +** independence" that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int sqlite3_stricmp(const char *, const char *); +SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); + +/* +** CAPI3REF: String Globbing +* +** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if +** string X matches the [GLOB] pattern P. +** ^The definition of [GLOB] pattern matching used in +** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the +** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function +** is case sensitive. +** +** Note that this routine returns zero on a match and non-zero if the strings +** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. +** +** See also: [sqlite3_strlike()]. +*/ +SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr); + +/* +** CAPI3REF: String LIKE Matching +* +** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if +** string X matches the [LIKE] pattern P with escape character E. +** ^The definition of [LIKE] pattern matching used in +** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E" +** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without +** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0. +** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case +** insensitive - equivalent upper and lower case ASCII characters match +** one another. +** +** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though +** only ASCII characters are case folded. +** +** Note that this routine returns zero on a match and non-zero if the strings +** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. +** +** See also: [sqlite3_strglob()]. +*/ +SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc); + +/* +** CAPI3REF: Error Logging Interface +** +** ^The [sqlite3_log()] interface writes a message into the [error log] +** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. +** ^If logging is enabled, the zFormat string and subsequent arguments are +** used with [sqlite3_snprintf()] to generate the final output string. +** +** The sqlite3_log() interface is intended for use by extensions such as +** virtual tables, collating functions, and SQL functions. While there is +** nothing to prevent an application from calling sqlite3_log(), doing so +** is considered bad form. +** +** The zFormat string must not be NULL. +** +** To avoid deadlocks and other threading problems, the sqlite3_log() routine +** will not use dynamically allocated memory. The log message is stored in +** a fixed-length buffer on the stack. If the log message is longer than +** a few hundred characters, it will be truncated to the length of the +** buffer. +*/ +SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); + +/* +** CAPI3REF: Write-Ahead Log Commit Hook +** METHOD: sqlite3 +** +** ^The [sqlite3_wal_hook()] function is used to register a callback that +** is invoked each time data is committed to a database in wal mode. +** +** ^(The callback is invoked by SQLite after the commit has taken place and +** the associated write-lock on the database released)^, so the implementation +** may read, write or [checkpoint] the database as required. +** +** ^The first parameter passed to the callback function when it is invoked +** is a copy of the third parameter passed to sqlite3_wal_hook() when +** registering the callback. ^The second is a copy of the database handle. +** ^The third parameter is the name of the database that was written to - +** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter +** is the number of pages currently in the write-ahead log file, +** including those that were just committed. +** +** The callback function should normally return [SQLITE_OK]. ^If an error +** code is returned, that error will propagate back up through the +** SQLite code base to cause the statement that provoked the callback +** to report an error, though the commit will have still occurred. If the +** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value +** that does not correspond to any valid SQLite error code, the results +** are undefined. +** +** A single database handle may have at most a single write-ahead log callback +** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any +** previously registered write-ahead log callback. ^Note that the +** [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will +** overwrite any prior [sqlite3_wal_hook()] settings. +*/ +SQLITE_API void *sqlite3_wal_hook( + sqlite3*, + int(*)(void *,sqlite3*,const char*,int), + void* +); + +/* +** CAPI3REF: Configure an auto-checkpoint +** METHOD: sqlite3 +** +** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around +** [sqlite3_wal_hook()] that causes any database on [database connection] D +** to automatically [checkpoint] +** after committing a transaction if there are N or +** more frames in the [write-ahead log] file. ^Passing zero or +** a negative value as the nFrame parameter disables automatic +** checkpoints entirely. +** +** ^The callback registered by this function replaces any existing callback +** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback +** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism +** configured by this function. +** +** ^The [wal_autocheckpoint pragma] can be used to invoke this interface +** from SQL. +** +** ^Checkpoints initiated by this mechanism are +** [sqlite3_wal_checkpoint_v2|PASSIVE]. +** +** ^Every new [database connection] defaults to having the auto-checkpoint +** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] +** pages. The use of this interface +** is only necessary if the default setting is found to be suboptimal +** for a particular application. +*/ +SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); + +/* +** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 +** +** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to +** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ +** +** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the +** [write-ahead log] for database X on [database connection] D to be +** transferred into the database file and for the write-ahead log to +** be reset. See the [checkpointing] documentation for addition +** information. +** +** This interface used to be the only way to cause a checkpoint to +** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] +** interface was added. This interface is retained for backwards +** compatibility and as a convenience for applications that need to manually +** start a callback but which do not need the full power (and corresponding +** complication) of [sqlite3_wal_checkpoint_v2()]. +*/ +SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); + +/* +** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 +** +** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint +** operation on database X of [database connection] D in mode M. Status +** information is written back into integers pointed to by L and C.)^ +** ^(The M parameter must be a valid [checkpoint mode]:)^ +** +** <dl> +** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> +** ^Checkpoint as many frames as possible without waiting for any database +** readers or writers to finish, then sync the database file if all frames +** in the log were checkpointed. ^The [busy-handler callback] +** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. +** ^On the other hand, passive mode might leave the checkpoint unfinished +** if there are concurrent readers or writers. +** +** <dt>SQLITE_CHECKPOINT_FULL<dd> +** ^This mode blocks (it invokes the +** [sqlite3_busy_handler|busy-handler callback]) until there is no +** database writer and all readers are reading from the most recent database +** snapshot. ^It then checkpoints all frames in the log file and syncs the +** database file. ^This mode blocks new database writers while it is pending, +** but new database readers are allowed to continue unimpeded. +** +** <dt>SQLITE_CHECKPOINT_RESTART<dd> +** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition +** that after checkpointing the log file it blocks (calls the +** [busy-handler callback]) +** until all readers are reading from the database file only. ^This ensures +** that the next writer will restart the log file from the beginning. +** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new +** database writer attempts while it is pending, but does not impede readers. +** +** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd> +** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the +** addition that it also truncates the log file to zero bytes just prior +** to a successful return. +** </dl> +** +** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in +** the log file or to -1 if the checkpoint could not run because +** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not +** NULL,then *pnCkpt is set to the total number of checkpointed frames in the +** log file (including any that were already checkpointed before the function +** was called) or to -1 if the checkpoint could not run due to an error or +** because the database is not in WAL mode. ^Note that upon successful +** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been +** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. +** +** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If +** any other process is running a checkpoint operation at the same time, the +** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a +** busy-handler configured, it will not be invoked in this case. +** +** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the +** exclusive "writer" lock on the database file. ^If the writer lock cannot be +** obtained immediately, and a busy-handler is configured, it is invoked and +** the writer lock retried until either the busy-handler returns 0 or the lock +** is successfully obtained. ^The busy-handler is also invoked while waiting for +** database readers as described above. ^If the busy-handler returns 0 before +** the writer lock is obtained or while waiting for database readers, the +** checkpoint operation proceeds from that point in the same way as +** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible +** without blocking any further. ^SQLITE_BUSY is returned in this case. +** +** ^If parameter zDb is NULL or points to a zero length string, then the +** specified operation is attempted on all WAL databases [attached] to +** [database connection] db. In this case the +** values written to output parameters *pnLog and *pnCkpt are undefined. ^If +** an SQLITE_BUSY error is encountered when processing one or more of the +** attached WAL databases, the operation is still attempted on any remaining +** attached databases and SQLITE_BUSY is returned at the end. ^If any other +** error occurs while processing an attached database, processing is abandoned +** and the error code is returned to the caller immediately. ^If no error +** (SQLITE_BUSY or otherwise) is encountered while processing the attached +** databases, SQLITE_OK is returned. +** +** ^If database zDb is the name of an attached database that is not in WAL +** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If +** zDb is not NULL (or a zero length string) and is not the name of any +** attached database, SQLITE_ERROR is returned to the caller. +** +** ^Unless it returns SQLITE_MISUSE, +** the sqlite3_wal_checkpoint_v2() interface +** sets the error information that is queried by +** [sqlite3_errcode()] and [sqlite3_errmsg()]. +** +** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface +** from SQL. +*/ +SQLITE_API int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +); + +/* +** CAPI3REF: Checkpoint Mode Values +** KEYWORDS: {checkpoint mode} +** +** These constants define all valid values for the "checkpoint mode" passed +** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface. +** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the +** meaning of each of these checkpoint modes. +*/ +#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ +#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ +#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ +#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ + +/* +** CAPI3REF: Virtual Table Interface Configuration +** +** This function may be called by either the [xConnect] or [xCreate] method +** of a [virtual table] implementation to configure +** various facets of the virtual table interface. +** +** If this interface is invoked outside the context of an xConnect or +** xCreate virtual table method then the behavior is undefined. +** +** At present, there is only one option that may be configured using +** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options +** may be added in the future. +*/ +SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Virtual Table Configuration Options +** +** These macros define the various options to the +** [sqlite3_vtab_config()] interface that [virtual table] implementations +** can use to customize and optimize their behavior. +** +** <dl> +** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT +** <dd>Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, +** where X is an integer. If X is zero, then the [virtual table] whose +** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not +** support constraints. In this configuration (which is the default) if +** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire +** statement is rolled back as if [ON CONFLICT | OR ABORT] had been +** specified as part of the users SQL statement, regardless of the actual +** ON CONFLICT mode specified. +** +** If X is non-zero, then the virtual table implementation guarantees +** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before +** any modifications to internal or persistent data structures have been made. +** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite +** is able to roll back a statement or database transaction, and abandon +** or continue processing the current SQL statement as appropriate. +** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns +** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode +** had been ABORT. +** +** Virtual table implementations that are required to handle OR REPLACE +** must do so within the [xUpdate] method. If a call to the +** [sqlite3_vtab_on_conflict()] function indicates that the current ON +** CONFLICT policy is REPLACE, the virtual table implementation should +** silently replace the appropriate rows within the xUpdate callback and +** return SQLITE_OK. Or, if this is not possible, it may return +** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT +** constraint handling. +** </dl> +*/ +#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 + +/* +** CAPI3REF: Determine The Virtual Table Conflict Policy +** +** This function may only be called from within a call to the [xUpdate] method +** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The +** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL], +** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode +** of the SQL statement that triggered the call to the [xUpdate] method of the +** [virtual table]. +*/ +SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); + +/* +** CAPI3REF: Conflict resolution modes +** KEYWORDS: {conflict resolution mode} +** +** These constants are returned by [sqlite3_vtab_on_conflict()] to +** inform a [virtual table] implementation what the [ON CONFLICT] mode +** is for the SQL statement being evaluated. +** +** Note that the [SQLITE_IGNORE] constant is also used as a potential +** return value from the [sqlite3_set_authorizer()] callback and that +** [SQLITE_ABORT] is also a [result code]. +*/ +#define SQLITE_ROLLBACK 1 +/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */ +#define SQLITE_FAIL 3 +/* #define SQLITE_ABORT 4 // Also an error code */ +#define SQLITE_REPLACE 5 + +/* +** CAPI3REF: Prepared Statement Scan Status Opcodes +** KEYWORDS: {scanstatus options} +** +** The following constants can be used for the T parameter to the +** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a +** different metric for sqlite3_stmt_scanstatus() to return. +** +** When the value returned to V is a string, space to hold that string is +** managed by the prepared statement S and will be automatically freed when +** S is finalized. +** +** <dl> +** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> +** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be +** set to the total number of times that the X-th loop has run.</dd> +** +** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt> +** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set +** to the total number of rows examined by all iterations of the X-th loop.</dd> +** +** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt> +** <dd>^The "double" variable pointed to by the T parameter will be set to the +** query planner's estimate for the average number of rows output from each +** iteration of the X-th loop. If the query planner's estimates was accurate, +** then this value will approximate the quotient NVISIT/NLOOP and the +** product of this value for all prior loops with the same SELECTID will +** be the NLOOP value for the current loop. +** +** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt> +** <dd>^The "const char *" variable pointed to by the T parameter will be set +** to a zero-terminated UTF-8 string containing the name of the index or table +** used for the X-th loop. +** +** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt> +** <dd>^The "const char *" variable pointed to by the T parameter will be set +** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] +** description for the X-th loop. +** +** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt> +** <dd>^The "int" variable pointed to by the T parameter will be set to the +** "select-id" for the X-th loop. The select-id identifies which query or +** subquery the loop is part of. The main query has a select-id of zero. +** The select-id is the same value as is output in the first column +** of an [EXPLAIN QUERY PLAN] query. +** </dl> +*/ +#define SQLITE_SCANSTAT_NLOOP 0 +#define SQLITE_SCANSTAT_NVISIT 1 +#define SQLITE_SCANSTAT_EST 2 +#define SQLITE_SCANSTAT_NAME 3 +#define SQLITE_SCANSTAT_EXPLAIN 4 +#define SQLITE_SCANSTAT_SELECTID 5 + +/* +** CAPI3REF: Prepared Statement Scan Status +** METHOD: sqlite3_stmt +** +** This interface returns information about the predicted and measured +** performance for pStmt. Advanced applications can use this +** interface to compare the predicted and the measured performance and +** issue warnings and/or rerun [ANALYZE] if discrepancies are found. +** +** Since this interface is expected to be rarely used, it is only +** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] +** compile-time option. +** +** The "iScanStatusOp" parameter determines which status information to return. +** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior +** of this interface is undefined. +** ^The requested measurement is written into a variable pointed to by +** the "pOut" parameter. +** Parameter "idx" identifies the specific loop to retrieve statistics for. +** Loops are numbered starting from zero. ^If idx is out of range - less than +** zero or greater than or equal to the total number of loops used to implement +** the statement - a non-zero value is returned and the variable that pOut +** points to is unchanged. +** +** ^Statistics might not be available for all loops in all statements. ^In cases +** where there exist loops with no available statistics, this function behaves +** as if the loop did not exist - it returns non-zero and leave the variable +** that pOut points to unchanged. +** +** See also: [sqlite3_stmt_scanstatus_reset()] +*/ +SQLITE_API int sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ + int idx, /* Index of loop to report on */ + int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ + void *pOut /* Result written here */ +); + +/* +** CAPI3REF: Zero Scan-Status Counters +** METHOD: sqlite3_stmt +** +** ^Zero all [sqlite3_stmt_scanstatus()] related event counters. +** +** This API is only available if the library is built with pre-processor +** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. +*/ +SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); + +/* +** CAPI3REF: Flush caches to disk mid-transaction +** +** ^If a write-transaction is open on [database connection] D when the +** [sqlite3_db_cacheflush(D)] interface invoked, any dirty +** pages in the pager-cache that are not currently in use are written out +** to disk. A dirty page may be in use if a database cursor created by an +** active SQL statement is reading from it, or if it is page 1 of a database +** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] +** interface flushes caches for all schemas - "main", "temp", and +** any [attached] databases. +** +** ^If this function needs to obtain extra database locks before dirty pages +** can be flushed to disk, it does so. ^If those locks cannot be obtained +** immediately and there is a busy-handler callback configured, it is invoked +** in the usual manner. ^If the required lock still cannot be obtained, then +** the database is skipped and an attempt made to flush any dirty pages +** belonging to the next (if any) database. ^If any databases are skipped +** because locks cannot be obtained, but no other error occurs, this +** function returns SQLITE_BUSY. +** +** ^If any other error occurs while flushing dirty pages to disk (for +** example an IO error or out-of-memory condition), then processing is +** abandoned and an SQLite [error code] is returned to the caller immediately. +** +** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK. +** +** ^This function does not set the database handle error code or message +** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions. +*/ +SQLITE_API int sqlite3_db_cacheflush(sqlite3*); + +/* +** CAPI3REF: The pre-update hook. +** +** ^These interfaces are only available if SQLite is compiled using the +** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option. +** +** ^The [sqlite3_preupdate_hook()] interface registers a callback function +** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation +** on a [rowid table]. +** ^At most one preupdate hook may be registered at a time on a single +** [database connection]; each call to [sqlite3_preupdate_hook()] overrides +** the previous setting. +** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()] +** with a NULL pointer as the second parameter. +** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as +** the first parameter to callbacks. +** +** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate +** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID] +** tables. +** +** ^The second parameter to the preupdate callback is a pointer to +** the [database connection] that registered the preupdate hook. +** ^The third parameter to the preupdate callback is one of the constants +** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the +** kind of update operation that is about to occur. +** ^(The fourth parameter to the preupdate callback is the name of the +** database within the database connection that is being modified. This +** will be "main" for the main database or "temp" for TEMP tables or +** the name given after the AS keyword in the [ATTACH] statement for attached +** databases.)^ +** ^The fifth parameter to the preupdate callback is the name of the +** table that is being modified. +** ^The sixth parameter to the preupdate callback is the initial [rowid] of the +** row being changes for SQLITE_UPDATE and SQLITE_DELETE changes and is +** undefined for SQLITE_INSERT changes. +** ^The seventh parameter to the preupdate callback is the final [rowid] of +** the row being changed for SQLITE_UPDATE and SQLITE_INSERT changes and is +** undefined for SQLITE_DELETE changes. +** +** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], +** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces +** provide additional information about a preupdate event. These routines +** may only be called from within a preupdate callback. Invoking any of +** these routines from outside of a preupdate callback or with a +** [database connection] pointer that is different from the one supplied +** to the preupdate callback results in undefined and probably undesirable +** behavior. +** +** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns +** in the row that is being inserted, updated, or deleted. +** +** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to +** a [protected sqlite3_value] that contains the value of the Nth column of +** the table row before it is updated. The N parameter must be between 0 +** and one less than the number of columns or the behavior will be +** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE +** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the +** behavior is undefined. The [sqlite3_value] that P points to +** will be destroyed when the preupdate callback returns. +** +** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to +** a [protected sqlite3_value] that contains the value of the Nth column of +** the table row after it is updated. The N parameter must be between 0 +** and one less than the number of columns or the behavior will be +** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE +** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the +** behavior is undefined. The [sqlite3_value] that P points to +** will be destroyed when the preupdate callback returns. +** +** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate +** callback was invoked as a result of a direct insert, update, or delete +** operation; or 1 for inserts, updates, or deletes invoked by top-level +** triggers; or 2 for changes resulting from triggers called by top-level +** triggers; and so forth. +** +** See also: [sqlite3_update_hook()] +*/ +SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( + sqlite3 *db, + void(*xPreUpdate)( + void *pCtx, /* Copy of third arg to preupdate_hook() */ + sqlite3 *db, /* Database handle */ + int op, /* SQLITE_UPDATE, DELETE or INSERT */ + char const *zDb, /* Database name */ + char const *zName, /* Table name */ + sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */ + sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */ + ), + void* +); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_count(sqlite3 *); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_depth(sqlite3 *); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); + +/* +** CAPI3REF: Low-level system error code +** +** ^Attempt to return the underlying operating system error code or error +** number that caused the most recent I/O error or failure to open a file. +** The return value is OS-dependent. For example, on unix systems, after +** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be +** called to get back the underlying "errno" that caused the problem, such +** as ENOSPC, EAUTH, EISDIR, and so forth. +*/ +SQLITE_API int sqlite3_system_errno(sqlite3*); + +/* +** CAPI3REF: Database Snapshot +** KEYWORDS: {snapshot} +** EXPERIMENTAL +** +** An instance of the snapshot object records the state of a [WAL mode] +** database for some specific point in history. +** +** In [WAL mode], multiple [database connections] that are open on the +** same database file can each be reading a different historical version +** of the database file. When a [database connection] begins a read +** transaction, that connection sees an unchanging copy of the database +** as it existed for the point in time when the transaction first started. +** Subsequent changes to the database from other connections are not seen +** by the reader until a new read transaction is started. +** +** The sqlite3_snapshot object records state information about an historical +** version of the database file so that it is possible to later open a new read +** transaction that sees that historical version of the database rather than +** the most recent version. +** +** The constructor for this object is [sqlite3_snapshot_get()]. The +** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer +** to an historical snapshot (if possible). The destructor for +** sqlite3_snapshot objects is [sqlite3_snapshot_free()]. +*/ +typedef struct sqlite3_snapshot sqlite3_snapshot; + +/* +** CAPI3REF: Record A Database Snapshot +** EXPERIMENTAL +** +** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a +** new [sqlite3_snapshot] object that records the current state of +** schema S in database connection D. ^On success, the +** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly +** created [sqlite3_snapshot] object into *P and returns SQLITE_OK. +** ^If schema S of [database connection] D is not a [WAL mode] database +** that is in a read transaction, then [sqlite3_snapshot_get(D,S,P)] +** leaves the *P value unchanged and returns an appropriate [error code]. +** +** The [sqlite3_snapshot] object returned from a successful call to +** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()] +** to avoid a memory leak. +** +** The [sqlite3_snapshot_get()] interface is only available when the +** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( + sqlite3 *db, + const char *zSchema, + sqlite3_snapshot **ppSnapshot +); + +/* +** CAPI3REF: Start a read transaction on an historical snapshot +** EXPERIMENTAL +** +** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a +** read transaction for schema S of +** [database connection] D such that the read transaction +** refers to historical [snapshot] P, rather than the most +** recent change to the database. +** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success +** or an appropriate [error code] if it fails. +** +** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be +** the first operation following the [BEGIN] that takes the schema S +** out of [autocommit mode]. +** ^In other words, schema S must not currently be in +** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the +** database connection D must be out of [autocommit mode]. +** ^A [snapshot] will fail to open if it has been overwritten by a +** [checkpoint]. +** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the +** database connection D does not know that the database file for +** schema S is in [WAL mode]. A database connection might not know +** that the database file is in [WAL mode] if there has been no prior +** I/O on that database connection, or if the database entered [WAL mode] +** after the most recent I/O on the database connection.)^ +** (Hint: Run "[PRAGMA application_id]" against a newly opened +** database connection in order to make it ready to use snapshots.) +** +** The [sqlite3_snapshot_open()] interface is only available when the +** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( + sqlite3 *db, + const char *zSchema, + sqlite3_snapshot *pSnapshot +); + +/* +** CAPI3REF: Destroy a snapshot +** EXPERIMENTAL +** +** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P. +** The application must eventually free every [sqlite3_snapshot] object +** using this routine to avoid a memory leak. +** +** The [sqlite3_snapshot_free()] interface is only available when the +** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +*/ +SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); + +/* +** CAPI3REF: Compare the ages of two snapshot handles. +** EXPERIMENTAL +** +** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages +** of two valid snapshot handles. +** +** If the two snapshot handles are not associated with the same database +** file, the result of the comparison is undefined. +** +** Additionally, the result of the comparison is only valid if both of the +** snapshot handles were obtained by calling sqlite3_snapshot_get() since the +** last time the wal file was deleted. The wal file is deleted when the +** database is changed back to rollback mode or when the number of database +** clients drops to zero. If either snapshot handle was obtained before the +** wal file was last deleted, the value returned by this function +** is undefined. +** +** Otherwise, this API returns a negative value if P1 refers to an older +** snapshot than P2, zero if the two handles refer to the same database +** snapshot, and a positive value if P1 is a newer snapshot than P2. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( + sqlite3_snapshot *p1, + sqlite3_snapshot *p2 +); + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#ifdef __cplusplus +} /* End of the 'extern "C"' block */ +#endif +#endif /* SQLITE3_H */ + +/******** Begin file sqlite3rtree.h *********/ +/* +** 2010 August 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + +#ifndef _SQLITE3RTREE_H_ +#define _SQLITE3RTREE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; +typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; + +/* The double-precision datatype used by RTree depends on the +** SQLITE_RTREE_INT_ONLY compile-time option. +*/ +#ifdef SQLITE_RTREE_INT_ONLY + typedef sqlite3_int64 sqlite3_rtree_dbl; +#else + typedef double sqlite3_rtree_dbl; +#endif + +/* +** Register a geometry callback named zGeom that can be used as part of an +** R-Tree geometry query as follows: +** +** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) +*/ +SQLITE_API int sqlite3_rtree_geometry_callback( + sqlite3 *db, + const char *zGeom, + int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), + void *pContext +); + + +/* +** A pointer to a structure of the following type is passed as the first +** argument to callbacks registered using rtree_geometry_callback(). +*/ +struct sqlite3_rtree_geometry { + void *pContext; /* Copy of pContext passed to s_r_g_c() */ + int nParam; /* Size of array aParam[] */ + sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ + void *pUser; /* Callback implementation user data */ + void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ +}; + +/* +** Register a 2nd-generation geometry callback named zScore that can be +** used as part of an R-Tree geometry query as follows: +** +** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...) +*/ +SQLITE_API int sqlite3_rtree_query_callback( + sqlite3 *db, + const char *zQueryFunc, + int (*xQueryFunc)(sqlite3_rtree_query_info*), + void *pContext, + void (*xDestructor)(void*) +); + + +/* +** A pointer to a structure of the following type is passed as the +** argument to scored geometry callback registered using +** sqlite3_rtree_query_callback(). +** +** Note that the first 5 fields of this structure are identical to +** sqlite3_rtree_geometry. This structure is a subclass of +** sqlite3_rtree_geometry. +*/ +struct sqlite3_rtree_query_info { + void *pContext; /* pContext from when function registered */ + int nParam; /* Number of function parameters */ + sqlite3_rtree_dbl *aParam; /* value of function parameters */ + void *pUser; /* callback can use this, if desired */ + void (*xDelUser)(void*); /* function to free pUser */ + sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ + unsigned int *anQueue; /* Number of pending entries in the queue */ + int nCoord; /* Number of coordinates */ + int iLevel; /* Level of current node or entry */ + int mxLevel; /* The largest iLevel value in the tree */ + sqlite3_int64 iRowid; /* Rowid for current entry */ + sqlite3_rtree_dbl rParentScore; /* Score of parent node */ + int eParentWithin; /* Visibility of parent node */ + int eWithin; /* OUT: Visiblity */ + sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ + /* The following fields are only available in 3.8.11 and later */ + sqlite3_value **apSqlParam; /* Original SQL values of parameters */ +}; + +/* +** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin. +*/ +#define NOT_WITHIN 0 /* Object completely outside of query region */ +#define PARTLY_WITHIN 1 /* Object partially overlaps query region */ +#define FULLY_WITHIN 2 /* Object fully contained within query region */ + + +#ifdef __cplusplus +} /* end of the 'extern "C"' block */ +#endif + +#endif /* ifndef _SQLITE3RTREE_H_ */ + +/******** End of sqlite3rtree.h *********/ +/******** Begin file sqlite3session.h *********/ + +#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) +#define __SQLITESESSION_H_ 1 + +/* +** Make sure we can call this stuff from C++. +*/ +#ifdef __cplusplus +extern "C" { +#endif + + +/* +** CAPI3REF: Session Object Handle +*/ +typedef struct sqlite3_session sqlite3_session; + +/* +** CAPI3REF: Changeset Iterator Handle +*/ +typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; + +/* +** CAPI3REF: Create A New Session Object +** +** Create a new session object attached to database handle db. If successful, +** a pointer to the new object is written to *ppSession and SQLITE_OK is +** returned. If an error occurs, *ppSession is set to NULL and an SQLite +** error code (e.g. SQLITE_NOMEM) is returned. +** +** It is possible to create multiple session objects attached to a single +** database handle. +** +** Session objects created using this function should be deleted using the +** [sqlite3session_delete()] function before the database handle that they +** are attached to is itself closed. If the database handle is closed before +** the session object is deleted, then the results of calling any session +** module function, including [sqlite3session_delete()] on the session object +** are undefined. +** +** Because the session module uses the [sqlite3_preupdate_hook()] API, it +** is not possible for an application to register a pre-update hook on a +** database handle that has one or more session objects attached. Nor is +** it possible to create a session object attached to a database handle for +** which a pre-update hook is already defined. The results of attempting +** either of these things are undefined. +** +** The session object will be used to create changesets for tables in +** database zDb, where zDb is either "main", or "temp", or the name of an +** attached database. It is not an error if database zDb is not attached +** to the database when the session object is created. +*/ +int sqlite3session_create( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of db (e.g. "main") */ + sqlite3_session **ppSession /* OUT: New session object */ +); + +/* +** CAPI3REF: Delete A Session Object +** +** Delete a session object previously allocated using +** [sqlite3session_create()]. Once a session object has been deleted, the +** results of attempting to use pSession with any other session module +** function are undefined. +** +** Session objects must be deleted before the database handle to which they +** are attached is closed. Refer to the documentation for +** [sqlite3session_create()] for details. +*/ +void sqlite3session_delete(sqlite3_session *pSession); + + +/* +** CAPI3REF: Enable Or Disable A Session Object +** +** Enable or disable the recording of changes by a session object. When +** enabled, a session object records changes made to the database. When +** disabled - it does not. A newly created session object is enabled. +** Refer to the documentation for [sqlite3session_changeset()] for further +** details regarding how enabling and disabling a session object affects +** the eventual changesets. +** +** Passing zero to this function disables the session. Passing a value +** greater than zero enables it. Passing a value less than zero is a +** no-op, and may be used to query the current state of the session. +** +** The return value indicates the final state of the session object: 0 if +** the session is disabled, or 1 if it is enabled. +*/ +int sqlite3session_enable(sqlite3_session *pSession, int bEnable); + +/* +** CAPI3REF: Set Or Clear the Indirect Change Flag +** +** Each change recorded by a session object is marked as either direct or +** indirect. A change is marked as indirect if either: +** +** <ul> +** <li> The session object "indirect" flag is set when the change is +** made, or +** <li> The change is made by an SQL trigger or foreign key action +** instead of directly as a result of a users SQL statement. +** </ul> +** +** If a single row is affected by more than one operation within a session, +** then the change is considered indirect if all operations meet the criteria +** for an indirect change above, or direct otherwise. +** +** This function is used to set, clear or query the session object indirect +** flag. If the second argument passed to this function is zero, then the +** indirect flag is cleared. If it is greater than zero, the indirect flag +** is set. Passing a value less than zero does not modify the current value +** of the indirect flag, and may be used to query the current state of the +** indirect flag for the specified session object. +** +** The return value indicates the final state of the indirect flag: 0 if +** it is clear, or 1 if it is set. +*/ +int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); + +/* +** CAPI3REF: Attach A Table To A Session Object +** +** If argument zTab is not NULL, then it is the name of a table to attach +** to the session object passed as the first argument. All subsequent changes +** made to the table while the session object is enabled will be recorded. See +** documentation for [sqlite3session_changeset()] for further details. +** +** Or, if argument zTab is NULL, then changes are recorded for all tables +** in the database. If additional tables are added to the database (by +** executing "CREATE TABLE" statements) after this call is made, changes for +** the new tables are also recorded. +** +** Changes can only be recorded for tables that have a PRIMARY KEY explicitly +** defined as part of their CREATE TABLE statement. It does not matter if the +** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY +** KEY may consist of a single column, or may be a composite key. +** +** It is not an error if the named table does not exist in the database. Nor +** is it an error if the named table does not have a PRIMARY KEY. However, +** no changes will be recorded in either of these scenarios. +** +** Changes are not recorded for individual rows that have NULL values stored +** in one or more of their PRIMARY KEY columns. +** +** SQLITE_OK is returned if the call completes without error. Or, if an error +** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. +*/ +int sqlite3session_attach( + sqlite3_session *pSession, /* Session object */ + const char *zTab /* Table name */ +); + +/* +** CAPI3REF: Set a table filter on a Session Object. +** +** The second argument (xFilter) is the "filter callback". For changes to rows +** in tables that are not attached to the Session object, the filter is called +** to determine whether changes to the table's rows should be tracked or not. +** If xFilter returns 0, changes is not tracked. Note that once a table is +** attached, xFilter will not be called again. +*/ +void sqlite3session_table_filter( + sqlite3_session *pSession, /* Session object */ + int(*xFilter)( + void *pCtx, /* Copy of third arg to _filter_table() */ + const char *zTab /* Table name */ + ), + void *pCtx /* First argument passed to xFilter */ +); + +/* +** CAPI3REF: Generate A Changeset From A Session Object +** +** Obtain a changeset containing changes to the tables attached to the +** session object passed as the first argument. If successful, +** set *ppChangeset to point to a buffer containing the changeset +** and *pnChangeset to the size of the changeset in bytes before returning +** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to +** zero and return an SQLite error code. +** +** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes, +** each representing a change to a single row of an attached table. An INSERT +** change contains the values of each field of a new database row. A DELETE +** contains the original values of each field of a deleted database row. An +** UPDATE change contains the original values of each field of an updated +** database row along with the updated values for each updated non-primary-key +** column. It is not possible for an UPDATE change to represent a change that +** modifies the values of primary key columns. If such a change is made, it +** is represented in a changeset as a DELETE followed by an INSERT. +** +** Changes are not recorded for rows that have NULL values stored in one or +** more of their PRIMARY KEY columns. If such a row is inserted or deleted, +** no corresponding change is present in the changesets returned by this +** function. If an existing row with one or more NULL values stored in +** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL, +** only an INSERT is appears in the changeset. Similarly, if an existing row +** with non-NULL PRIMARY KEY values is updated so that one or more of its +** PRIMARY KEY columns are set to NULL, the resulting changeset contains a +** DELETE change only. +** +** The contents of a changeset may be traversed using an iterator created +** using the [sqlite3changeset_start()] API. A changeset may be applied to +** a database with a compatible schema using the [sqlite3changeset_apply()] +** API. +** +** Within a changeset generated by this function, all changes related to a +** single table are grouped together. In other words, when iterating through +** a changeset or when applying a changeset to a database, all changes related +** to a single table are processed before moving on to the next table. Tables +** are sorted in the same order in which they were attached (or auto-attached) +** to the sqlite3_session object. The order in which the changes related to +** a single table are stored is undefined. +** +** Following a successful call to this function, it is the responsibility of +** the caller to eventually free the buffer that *ppChangeset points to using +** [sqlite3_free()]. +** +** <h3>Changeset Generation</h3> +** +** Once a table has been attached to a session object, the session object +** records the primary key values of all new rows inserted into the table. +** It also records the original primary key and other column values of any +** deleted or updated rows. For each unique primary key value, data is only +** recorded once - the first time a row with said primary key is inserted, +** updated or deleted in the lifetime of the session. +** +** There is one exception to the previous paragraph: when a row is inserted, +** updated or deleted, if one or more of its primary key columns contain a +** NULL value, no record of the change is made. +** +** The session object therefore accumulates two types of records - those +** that consist of primary key values only (created when the user inserts +** a new record) and those that consist of the primary key values and the +** original values of other table columns (created when the users deletes +** or updates a record). +** +** When this function is called, the requested changeset is created using +** both the accumulated records and the current contents of the database +** file. Specifically: +** +** <ul> +** <li> For each record generated by an insert, the database is queried +** for a row with a matching primary key. If one is found, an INSERT +** change is added to the changeset. If no such row is found, no change +** is added to the changeset. +** +** <li> For each record generated by an update or delete, the database is +** queried for a row with a matching primary key. If such a row is +** found and one or more of the non-primary key fields have been +** modified from their original values, an UPDATE change is added to +** the changeset. Or, if no such row is found in the table, a DELETE +** change is added to the changeset. If there is a row with a matching +** primary key in the database, but all fields contain their original +** values, no change is added to the changeset. +** </ul> +** +** This means, amongst other things, that if a row is inserted and then later +** deleted while a session object is active, neither the insert nor the delete +** will be present in the changeset. Or if a row is deleted and then later a +** row with the same primary key values inserted while a session object is +** active, the resulting changeset will contain an UPDATE change instead of +** a DELETE and an INSERT. +** +** When a session object is disabled (see the [sqlite3session_enable()] API), +** it does not accumulate records when rows are inserted, updated or deleted. +** This may appear to have some counter-intuitive effects if a single row +** is written to more than once during a session. For example, if a row +** is inserted while a session object is enabled, then later deleted while +** the same session object is disabled, no INSERT record will appear in the +** changeset, even though the delete took place while the session was disabled. +** Or, if one field of a row is updated while a session is disabled, and +** another field of the same row is updated while the session is enabled, the +** resulting changeset will contain an UPDATE change that updates both fields. +*/ +int sqlite3session_changeset( + sqlite3_session *pSession, /* Session object */ + int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ + void **ppChangeset /* OUT: Buffer containing changeset */ +); + +/* +** CAPI3REF: Load The Difference Between Tables Into A Session +** +** If it is not already attached to the session object passed as the first +** argument, this function attaches table zTbl in the same manner as the +** [sqlite3session_attach()] function. If zTbl does not exist, or if it +** does not have a primary key, this function is a no-op (but does not return +** an error). +** +** Argument zFromDb must be the name of a database ("main", "temp" etc.) +** attached to the same database handle as the session object that contains +** a table compatible with the table attached to the session by this function. +** A table is considered compatible if it: +** +** <ul> +** <li> Has the same name, +** <li> Has the same set of columns declared in the same order, and +** <li> Has the same PRIMARY KEY definition. +** </ul> +** +** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables +** are compatible but do not have any PRIMARY KEY columns, it is not an error +** but no changes are added to the session object. As with other session +** APIs, tables without PRIMARY KEYs are simply ignored. +** +** This function adds a set of changes to the session object that could be +** used to update the table in database zFrom (call this the "from-table") +** so that its content is the same as the table attached to the session +** object (call this the "to-table"). Specifically: +** +** <ul> +** <li> For each row (primary key) that exists in the to-table but not in +** the from-table, an INSERT record is added to the session object. +** +** <li> For each row (primary key) that exists in the to-table but not in +** the from-table, a DELETE record is added to the session object. +** +** <li> For each row (primary key) that exists in both tables, but features +** different in each, an UPDATE record is added to the session. +** </ul> +** +** To clarify, if this function is called and then a changeset constructed +** using [sqlite3session_changeset()], then after applying that changeset to +** database zFrom the contents of the two compatible tables would be +** identical. +** +** It an error if database zFrom does not exist or does not contain the +** required compatible table. +** +** If the operation successful, SQLITE_OK is returned. Otherwise, an SQLite +** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg +** may be set to point to a buffer containing an English language error +** message. It is the responsibility of the caller to free this buffer using +** sqlite3_free(). +*/ +int sqlite3session_diff( + sqlite3_session *pSession, + const char *zFromDb, + const char *zTbl, + char **pzErrMsg +); + + +/* +** CAPI3REF: Generate A Patchset From A Session Object +** +** The differences between a patchset and a changeset are that: +** +** <ul> +** <li> DELETE records consist of the primary key fields only. The +** original values of other fields are omitted. +** <li> The original values of any modified fields are omitted from +** UPDATE records. +** </ul> +** +** A patchset blob may be used with up to date versions of all +** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(), +** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly, +** attempting to use a patchset blob with old versions of the +** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error. +** +** Because the non-primary key "old.*" fields are omitted, no +** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset +** is passed to the sqlite3changeset_apply() API. Other conflict types work +** in the same way as for changesets. +** +** Changes within a patchset are ordered in the same way as for changesets +** generated by the sqlite3session_changeset() function (i.e. all changes for +** a single table are grouped together, tables appear in the order in which +** they were attached to the session object). +*/ +int sqlite3session_patchset( + sqlite3_session *pSession, /* Session object */ + int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ + void **ppPatchset /* OUT: Buffer containing changeset */ +); + +/* +** CAPI3REF: Test if a changeset has recorded any changes. +** +** Return non-zero if no changes to attached tables have been recorded by +** the session object passed as the first argument. Otherwise, if one or +** more changes have been recorded, return zero. +** +** Even if this function returns zero, it is possible that calling +** [sqlite3session_changeset()] on the session handle may still return a +** changeset that contains no changes. This can happen when a row in +** an attached table is modified and then later on the original values +** are restored. However, if this function returns non-zero, then it is +** guaranteed that a call to sqlite3session_changeset() will return a +** changeset containing zero changes. +*/ +int sqlite3session_isempty(sqlite3_session *pSession); + +/* +** CAPI3REF: Create An Iterator To Traverse A Changeset +** +** Create an iterator used to iterate through the contents of a changeset. +** If successful, *pp is set to point to the iterator handle and SQLITE_OK +** is returned. Otherwise, if an error occurs, *pp is set to zero and an +** SQLite error code is returned. +** +** The following functions can be used to advance and query a changeset +** iterator created by this function: +** +** <ul> +** <li> [sqlite3changeset_next()] +** <li> [sqlite3changeset_op()] +** <li> [sqlite3changeset_new()] +** <li> [sqlite3changeset_old()] +** </ul> +** +** It is the responsibility of the caller to eventually destroy the iterator +** by passing it to [sqlite3changeset_finalize()]. The buffer containing the +** changeset (pChangeset) must remain valid until after the iterator is +** destroyed. +** +** Assuming the changeset blob was created by one of the +** [sqlite3session_changeset()], [sqlite3changeset_concat()] or +** [sqlite3changeset_invert()] functions, all changes within the changeset +** that apply to a single table are grouped together. This means that when +** an application iterates through a changeset using an iterator created by +** this function, all changes that relate to a single table are visited +** consecutively. There is no chance that the iterator will visit a change +** the applies to table X, then one for table Y, and then later on visit +** another change for table X. +*/ +int sqlite3changeset_start( + sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ + int nChangeset, /* Size of changeset blob in bytes */ + void *pChangeset /* Pointer to blob containing changeset */ +); + + +/* +** CAPI3REF: Advance A Changeset Iterator +** +** This function may only be used with iterators created by function +** [sqlite3changeset_start()]. If it is called on an iterator passed to +** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE +** is returned and the call has no effect. +** +** Immediately after an iterator is created by sqlite3changeset_start(), it +** does not point to any change in the changeset. Assuming the changeset +** is not empty, the first call to this function advances the iterator to +** point to the first change in the changeset. Each subsequent call advances +** the iterator to point to the next change in the changeset (if any). If +** no error occurs and the iterator points to a valid change after a call +** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned. +** Otherwise, if all changes in the changeset have already been visited, +** SQLITE_DONE is returned. +** +** If an error occurs, an SQLite error code is returned. Possible error +** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or +** SQLITE_NOMEM. +*/ +int sqlite3changeset_next(sqlite3_changeset_iter *pIter); + +/* +** CAPI3REF: Obtain The Current Operation From A Changeset Iterator +** +** The pIter argument passed to this function may either be an iterator +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this +** is not the case, this function returns [SQLITE_MISUSE]. +** +** If argument pzTab is not NULL, then *pzTab is set to point to a +** nul-terminated utf-8 encoded string containing the name of the table +** affected by the current change. The buffer remains valid until either +** sqlite3changeset_next() is called on the iterator or until the +** conflict-handler function returns. If pnCol is not NULL, then *pnCol is +** set to the number of columns in the table affected by the change. If +** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change +** is an indirect change, or false (0) otherwise. See the documentation for +** [sqlite3session_indirect()] for a description of direct and indirect +** changes. Finally, if pOp is not NULL, then *pOp is set to one of +** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the +** type of change that the iterator currently points to. +** +** If no error occurs, SQLITE_OK is returned. If an error does occur, an +** SQLite error code is returned. The values of the output variables may not +** be trusted in this case. +*/ +int sqlite3changeset_op( + sqlite3_changeset_iter *pIter, /* Iterator object */ + const char **pzTab, /* OUT: Pointer to table name */ + int *pnCol, /* OUT: Number of columns in table */ + int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */ + int *pbIndirect /* OUT: True for an 'indirect' change */ +); + +/* +** CAPI3REF: Obtain The Primary Key Definition Of A Table +** +** For each modified table, a changeset includes the following: +** +** <ul> +** <li> The number of columns in the table, and +** <li> Which of those columns make up the tables PRIMARY KEY. +** </ul> +** +** This function is used to find which columns comprise the PRIMARY KEY of +** the table modified by the change that iterator pIter currently points to. +** If successful, *pabPK is set to point to an array of nCol entries, where +** nCol is the number of columns in the table. Elements of *pabPK are set to +** 0x01 if the corresponding column is part of the tables primary key, or +** 0x00 if it is not. +** +** If argument pnCol is not NULL, then *pnCol is set to the number of columns +** in the table. +** +** If this function is called when the iterator does not point to a valid +** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise, +** SQLITE_OK is returned and the output variables populated as described +** above. +*/ +int sqlite3changeset_pk( + sqlite3_changeset_iter *pIter, /* Iterator object */ + unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */ + int *pnCol /* OUT: Number of entries in output array */ +); + +/* +** CAPI3REF: Obtain old.* Values From A Changeset Iterator +** +** The pIter argument passed to this function may either be an iterator +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. +** Furthermore, it may only be called if the type of change that the iterator +** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise, +** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL. +** +** Argument iVal must be greater than or equal to 0, and less than the number +** of columns in the table affected by the current change. Otherwise, +** [SQLITE_RANGE] is returned and *ppValue is set to NULL. +** +** If successful, this function sets *ppValue to point to a protected +** sqlite3_value object containing the iVal'th value from the vector of +** original row values stored as part of the UPDATE or DELETE change and +** returns SQLITE_OK. The name of the function comes from the fact that this +** is similar to the "old.*" columns available to update or delete triggers. +** +** If some other error occurs (e.g. an OOM condition), an SQLite error code +** is returned and *ppValue is set to NULL. +*/ +int sqlite3changeset_old( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Column number */ + sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ +); + +/* +** CAPI3REF: Obtain new.* Values From A Changeset Iterator +** +** The pIter argument passed to this function may either be an iterator +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. +** Furthermore, it may only be called if the type of change that the iterator +** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise, +** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL. +** +** Argument iVal must be greater than or equal to 0, and less than the number +** of columns in the table affected by the current change. Otherwise, +** [SQLITE_RANGE] is returned and *ppValue is set to NULL. +** +** If successful, this function sets *ppValue to point to a protected +** sqlite3_value object containing the iVal'th value from the vector of +** new row values stored as part of the UPDATE or INSERT change and +** returns SQLITE_OK. If the change is an UPDATE and does not include +** a new value for the requested column, *ppValue is set to NULL and +** SQLITE_OK returned. The name of the function comes from the fact that +** this is similar to the "new.*" columns available to update or delete +** triggers. +** +** If some other error occurs (e.g. an OOM condition), an SQLite error code +** is returned and *ppValue is set to NULL. +*/ +int sqlite3changeset_new( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Column number */ + sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ +); + +/* +** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator +** +** This function should only be used with iterator objects passed to a +** conflict-handler callback by [sqlite3changeset_apply()] with either +** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function +** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue +** is set to NULL. +** +** Argument iVal must be greater than or equal to 0, and less than the number +** of columns in the table affected by the current change. Otherwise, +** [SQLITE_RANGE] is returned and *ppValue is set to NULL. +** +** If successful, this function sets *ppValue to point to a protected +** sqlite3_value object containing the iVal'th value from the +** "conflicting row" associated with the current conflict-handler callback +** and returns SQLITE_OK. +** +** If some other error occurs (e.g. an OOM condition), an SQLite error code +** is returned and *ppValue is set to NULL. +*/ +int sqlite3changeset_conflict( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Column number */ + sqlite3_value **ppValue /* OUT: Value from conflicting row */ +); + +/* +** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations +** +** This function may only be called with an iterator passed to an +** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case +** it sets the output variable to the total number of known foreign key +** violations in the destination database and returns SQLITE_OK. +** +** In all other cases this function returns SQLITE_MISUSE. +*/ +int sqlite3changeset_fk_conflicts( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int *pnOut /* OUT: Number of FK violations */ +); + + +/* +** CAPI3REF: Finalize A Changeset Iterator +** +** This function is used to finalize an iterator allocated with +** [sqlite3changeset_start()]. +** +** This function should only be called on iterators created using the +** [sqlite3changeset_start()] function. If an application calls this +** function with an iterator passed to a conflict-handler by +** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the +** call has no effect. +** +** If an error was encountered within a call to an sqlite3changeset_xxx() +** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an +** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding +** to that error is returned by this function. Otherwise, SQLITE_OK is +** returned. This is to allow the following pattern (pseudo-code): +** +** sqlite3changeset_start(); +** while( SQLITE_ROW==sqlite3changeset_next() ){ +** // Do something with change. +** } +** rc = sqlite3changeset_finalize(); +** if( rc!=SQLITE_OK ){ +** // An error has occurred +** } +*/ +int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); + +/* +** CAPI3REF: Invert A Changeset +** +** This function is used to "invert" a changeset object. Applying an inverted +** changeset to a database reverses the effects of applying the uninverted +** changeset. Specifically: +** +** <ul> +** <li> Each DELETE change is changed to an INSERT, and +** <li> Each INSERT change is changed to a DELETE, and +** <li> For each UPDATE change, the old.* and new.* values are exchanged. +** </ul> +** +** This function does not change the order in which changes appear within +** the changeset. It merely reverses the sense of each individual change. +** +** If successful, a pointer to a buffer containing the inverted changeset +** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and +** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are +** zeroed and an SQLite error code returned. +** +** It is the responsibility of the caller to eventually call sqlite3_free() +** on the *ppOut pointer to free the buffer allocation following a successful +** call to this function. +** +** WARNING/TODO: This function currently assumes that the input is a valid +** changeset. If it is not, the results are undefined. +*/ +int sqlite3changeset_invert( + int nIn, const void *pIn, /* Input changeset */ + int *pnOut, void **ppOut /* OUT: Inverse of input */ +); + +/* +** CAPI3REF: Concatenate Two Changeset Objects +** +** This function is used to concatenate two changesets, A and B, into a +** single changeset. The result is a changeset equivalent to applying +** changeset A followed by changeset B. +** +** This function combines the two input changesets using an +** sqlite3_changegroup object. Calling it produces similar results as the +** following code fragment: +** +** sqlite3_changegroup *pGrp; +** rc = sqlite3_changegroup_new(&pGrp); +** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA); +** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB); +** if( rc==SQLITE_OK ){ +** rc = sqlite3changegroup_output(pGrp, pnOut, ppOut); +** }else{ +** *ppOut = 0; +** *pnOut = 0; +** } +** +** Refer to the sqlite3_changegroup documentation below for details. +*/ +int sqlite3changeset_concat( + int nA, /* Number of bytes in buffer pA */ + void *pA, /* Pointer to buffer containing changeset A */ + int nB, /* Number of bytes in buffer pB */ + void *pB, /* Pointer to buffer containing changeset B */ + int *pnOut, /* OUT: Number of bytes in output changeset */ + void **ppOut /* OUT: Buffer containing output changeset */ +); + + +/* +** CAPI3REF: Changegroup Handle +*/ +typedef struct sqlite3_changegroup sqlite3_changegroup; + +/* +** CAPI3REF: Create A New Changegroup Object +** +** An sqlite3_changegroup object is used to combine two or more changesets +** (or patchsets) into a single changeset (or patchset). A single changegroup +** object may combine changesets or patchsets, but not both. The output is +** always in the same format as the input. +** +** If successful, this function returns SQLITE_OK and populates (*pp) with +** a pointer to a new sqlite3_changegroup object before returning. The caller +** should eventually free the returned object using a call to +** sqlite3changegroup_delete(). If an error occurs, an SQLite error code +** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL. +** +** The usual usage pattern for an sqlite3_changegroup object is as follows: +** +** <ul> +** <li> It is created using a call to sqlite3changegroup_new(). +** +** <li> Zero or more changesets (or patchsets) are added to the object +** by calling sqlite3changegroup_add(). +** +** <li> The result of combining all input changesets together is obtained +** by the application via a call to sqlite3changegroup_output(). +** +** <li> The object is deleted using a call to sqlite3changegroup_delete(). +** </ul> +** +** Any number of calls to add() and output() may be made between the calls to +** new() and delete(), and in any order. +** +** As well as the regular sqlite3changegroup_add() and +** sqlite3changegroup_output() functions, also available are the streaming +** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm(). +*/ +int sqlite3changegroup_new(sqlite3_changegroup **pp); + +/* +** CAPI3REF: Add A Changeset To A Changegroup +** +** Add all changes within the changeset (or patchset) in buffer pData (size +** nData bytes) to the changegroup. +** +** If the buffer contains a patchset, then all prior calls to this function +** on the same changegroup object must also have specified patchsets. Or, if +** the buffer contains a changeset, so must have the earlier calls to this +** function. Otherwise, SQLITE_ERROR is returned and no changes are added +** to the changegroup. +** +** Rows within the changeset and changegroup are identified by the values in +** their PRIMARY KEY columns. A change in the changeset is considered to +** apply to the same row as a change already present in the changegroup if +** the two rows have the same primary key. +** +** Changes to rows that do not already appear in the changegroup are +** simply copied into it. Or, if both the new changeset and the changegroup +** contain changes that apply to a single row, the final contents of the +** changegroup depends on the type of each change, as follows: +** +** <table border=1 style="margin-left:8ex;margin-right:8ex"> +** <tr><th style="white-space:pre">Existing Change </th> +** <th style="white-space:pre">New Change </th> +** <th>Output Change +** <tr><td>INSERT <td>INSERT <td> +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +** <tr><td>INSERT <td>UPDATE <td> +** The INSERT change remains in the changegroup. The values in the +** INSERT change are modified as if the row was inserted by the +** existing change and then updated according to the new change. +** <tr><td>INSERT <td>DELETE <td> +** The existing INSERT is removed from the changegroup. The DELETE is +** not added. +** <tr><td>UPDATE <td>INSERT <td> +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +** <tr><td>UPDATE <td>UPDATE <td> +** The existing UPDATE remains within the changegroup. It is amended +** so that the accompanying values are as if the row was updated once +** by the existing change and then again by the new change. +** <tr><td>UPDATE <td>DELETE <td> +** The existing UPDATE is replaced by the new DELETE within the +** changegroup. +** <tr><td>DELETE <td>INSERT <td> +** If one or more of the column values in the row inserted by the +** new change differ from those in the row deleted by the existing +** change, the existing DELETE is replaced by an UPDATE within the +** changegroup. Otherwise, if the inserted row is exactly the same +** as the deleted row, the existing DELETE is simply discarded. +** <tr><td>DELETE <td>UPDATE <td> +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +** <tr><td>DELETE <td>DELETE <td> +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +** </table> +** +** If the new changeset contains changes to a table that is already present +** in the changegroup, then the number of columns and the position of the +** primary key columns for the table must be consistent. If this is not the +** case, this function fails with SQLITE_SCHEMA. If the input changeset +** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is +** returned. Or, if an out-of-memory condition occurs during processing, this +** function returns SQLITE_NOMEM. In all cases, if an error occurs the +** final contents of the changegroup is undefined. +** +** If no error occurs, SQLITE_OK is returned. +*/ +int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); + +/* +** CAPI3REF: Obtain A Composite Changeset From A Changegroup +** +** Obtain a buffer containing a changeset (or patchset) representing the +** current contents of the changegroup. If the inputs to the changegroup +** were themselves changesets, the output is a changeset. Or, if the +** inputs were patchsets, the output is also a patchset. +** +** As with the output of the sqlite3session_changeset() and +** sqlite3session_patchset() functions, all changes related to a single +** table are grouped together in the output of this function. Tables appear +** in the same order as for the very first changeset added to the changegroup. +** If the second or subsequent changesets added to the changegroup contain +** changes for tables that do not appear in the first changeset, they are +** appended onto the end of the output changeset, again in the order in +** which they are first encountered. +** +** If an error occurs, an SQLite error code is returned and the output +** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK +** is returned and the output variables are set to the size of and a +** pointer to the output buffer, respectively. In this case it is the +** responsibility of the caller to eventually free the buffer using a +** call to sqlite3_free(). +*/ +int sqlite3changegroup_output( + sqlite3_changegroup*, + int *pnData, /* OUT: Size of output buffer in bytes */ + void **ppData /* OUT: Pointer to output buffer */ +); + +/* +** CAPI3REF: Delete A Changegroup Object +*/ +void sqlite3changegroup_delete(sqlite3_changegroup*); + +/* +** CAPI3REF: Apply A Changeset To A Database +** +** Apply a changeset to a database. This function attempts to update the +** "main" database attached to handle db with the changes found in the +** changeset passed via the second and third arguments. +** +** The fourth argument (xFilter) passed to this function is the "filter +** callback". If it is not NULL, then for each table affected by at least one +** change in the changeset, the filter callback is invoked with +** the table name as the second argument, and a copy of the context pointer +** passed as the sixth argument to this function as the first. If the "filter +** callback" returns zero, then no attempt is made to apply any changes to +** the table. Otherwise, if the return value is non-zero or the xFilter +** argument to this function is NULL, all changes related to the table are +** attempted. +** +** For each table that is not excluded by the filter callback, this function +** tests that the target database contains a compatible table. A table is +** considered compatible if all of the following are true: +** +** <ul> +** <li> The table has the same name as the name recorded in the +** changeset, and +** <li> The table has the same number of columns as recorded in the +** changeset, and +** <li> The table has primary key columns in the same position as +** recorded in the changeset. +** </ul> +** +** If there is no compatible table, it is not an error, but none of the +** changes associated with the table are applied. A warning message is issued +** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most +** one such warning is issued for each table in the changeset. +** +** For each change for which there is a compatible table, an attempt is made +** to modify the table contents according to the UPDATE, INSERT or DELETE +** change. If a change cannot be applied cleanly, the conflict handler +** function passed as the fifth argument to sqlite3changeset_apply() may be +** invoked. A description of exactly when the conflict handler is invoked for +** each type of change is below. +** +** Unlike the xFilter argument, xConflict may not be passed NULL. The results +** of passing anything other than a valid function pointer as the xConflict +** argument are undefined. +** +** Each time the conflict handler function is invoked, it must return one +** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or +** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned +** if the second argument passed to the conflict handler is either +** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler +** returns an illegal value, any changes already made are rolled back and +** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different +** actions are taken by sqlite3changeset_apply() depending on the value +** returned by each invocation of the conflict-handler function. Refer to +** the documentation for the three +** [SQLITE_CHANGESET_OMIT|available return values] for details. +** +** <dl> +** <dt>DELETE Changes<dd> +** For each DELETE change, this function checks if the target database +** contains a row with the same primary key value (or values) as the +** original row values stored in the changeset. If it does, and the values +** stored in all non-primary key columns also match the values stored in +** the changeset the row is deleted from the target database. +** +** If a row with matching primary key values is found, but one or more of +** the non-primary key fields contains a value different from the original +** row value stored in the changeset, the conflict-handler function is +** invoked with [SQLITE_CHANGESET_DATA] as the second argument. +** +** If no row with matching primary key values is found in the database, +** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND] +** passed as the second argument. +** +** If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT +** (which can only happen if a foreign key constraint is violated), the +** conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT] +** passed as the second argument. This includes the case where the DELETE +** operation is attempted because an earlier call to the conflict handler +** function returned [SQLITE_CHANGESET_REPLACE]. +** +** <dt>INSERT Changes<dd> +** For each INSERT change, an attempt is made to insert the new row into +** the database. +** +** If the attempt to insert the row fails because the database already +** contains a row with the same primary key values, the conflict handler +** function is invoked with the second argument set to +** [SQLITE_CHANGESET_CONFLICT]. +** +** If the attempt to insert the row fails because of some other constraint +** violation (e.g. NOT NULL or UNIQUE), the conflict handler function is +** invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT]. +** This includes the case where the INSERT operation is re-attempted because +** an earlier call to the conflict handler function returned +** [SQLITE_CHANGESET_REPLACE]. +** +** <dt>UPDATE Changes<dd> +** For each UPDATE change, this function checks if the target database +** contains a row with the same primary key value (or values) as the +** original row values stored in the changeset. If it does, and the values +** stored in all non-primary key columns also match the values stored in +** the changeset the row is updated within the target database. +** +** If a row with matching primary key values is found, but one or more of +** the non-primary key fields contains a value different from an original +** row value stored in the changeset, the conflict-handler function is +** invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since +** UPDATE changes only contain values for non-primary key fields that are +** to be modified, only those fields need to match the original values to +** avoid the SQLITE_CHANGESET_DATA conflict-handler callback. +** +** If no row with matching primary key values is found in the database, +** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND] +** passed as the second argument. +** +** If the UPDATE operation is attempted, but SQLite returns +** SQLITE_CONSTRAINT, the conflict-handler function is invoked with +** [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument. +** This includes the case where the UPDATE operation is attempted after +** an earlier call to the conflict handler function returned +** [SQLITE_CHANGESET_REPLACE]. +** </dl> +** +** It is safe to execute SQL statements, including those that write to the +** table that the callback related to, from within the xConflict callback. +** This can be used to further customize the applications conflict +** resolution strategy. +** +** All changes made by this function are enclosed in a savepoint transaction. +** If any other error (aside from a constraint failure when attempting to +** write to the target database) occurs, then the savepoint transaction is +** rolled back, restoring the target database to its original state, and an +** SQLite error code returned. +*/ +int sqlite3changeset_apply( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int nChangeset, /* Size of changeset in bytes */ + void *pChangeset, /* Changeset blob */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx /* First argument passed to xConflict */ +); + +/* +** CAPI3REF: Constants Passed To The Conflict Handler +** +** Values that may be passed as the second argument to a conflict-handler. +** +** <dl> +** <dt>SQLITE_CHANGESET_DATA<dd> +** The conflict handler is invoked with CHANGESET_DATA as the second argument +** when processing a DELETE or UPDATE change if a row with the required +** PRIMARY KEY fields is present in the database, but one or more other +** (non primary-key) fields modified by the update do not contain the +** expected "before" values. +** +** The conflicting row, in this case, is the database row with the matching +** primary key. +** +** <dt>SQLITE_CHANGESET_NOTFOUND<dd> +** The conflict handler is invoked with CHANGESET_NOTFOUND as the second +** argument when processing a DELETE or UPDATE change if a row with the +** required PRIMARY KEY fields is not present in the database. +** +** There is no conflicting row in this case. The results of invoking the +** sqlite3changeset_conflict() API are undefined. +** +** <dt>SQLITE_CHANGESET_CONFLICT<dd> +** CHANGESET_CONFLICT is passed as the second argument to the conflict +** handler while processing an INSERT change if the operation would result +** in duplicate primary key values. +** +** The conflicting row in this case is the database row with the matching +** primary key. +** +** <dt>SQLITE_CHANGESET_FOREIGN_KEY<dd> +** If foreign key handling is enabled, and applying a changeset leaves the +** database in a state containing foreign key violations, the conflict +** handler is invoked with CHANGESET_FOREIGN_KEY as the second argument +** exactly once before the changeset is committed. If the conflict handler +** returns CHANGESET_OMIT, the changes, including those that caused the +** foreign key constraint violation, are committed. Or, if it returns +** CHANGESET_ABORT, the changeset is rolled back. +** +** No current or conflicting row information is provided. The only function +** it is possible to call on the supplied sqlite3_changeset_iter handle +** is sqlite3changeset_fk_conflicts(). +** +** <dt>SQLITE_CHANGESET_CONSTRAINT<dd> +** If any other constraint violation occurs while applying a change (i.e. +** a UNIQUE, CHECK or NOT NULL constraint), the conflict handler is +** invoked with CHANGESET_CONSTRAINT as the second argument. +** +** There is no conflicting row in this case. The results of invoking the +** sqlite3changeset_conflict() API are undefined. +** +** </dl> +*/ +#define SQLITE_CHANGESET_DATA 1 +#define SQLITE_CHANGESET_NOTFOUND 2 +#define SQLITE_CHANGESET_CONFLICT 3 +#define SQLITE_CHANGESET_CONSTRAINT 4 +#define SQLITE_CHANGESET_FOREIGN_KEY 5 + +/* +** CAPI3REF: Constants Returned By The Conflict Handler +** +** A conflict handler callback must return one of the following three values. +** +** <dl> +** <dt>SQLITE_CHANGESET_OMIT<dd> +** If a conflict handler returns this value no special action is taken. The +** change that caused the conflict is not applied. The session module +** continues to the next change in the changeset. +** +** <dt>SQLITE_CHANGESET_REPLACE<dd> +** This value may only be returned if the second argument to the conflict +** handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this +** is not the case, any changes applied so far are rolled back and the +** call to sqlite3changeset_apply() returns SQLITE_MISUSE. +** +** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict +** handler, then the conflicting row is either updated or deleted, depending +** on the type of change. +** +** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict +** handler, then the conflicting row is removed from the database and a +** second attempt to apply the change is made. If this second attempt fails, +** the original row is restored to the database before continuing. +** +** <dt>SQLITE_CHANGESET_ABORT<dd> +** If this value is returned, any changes applied so far are rolled back +** and the call to sqlite3changeset_apply() returns SQLITE_ABORT. +** </dl> +*/ +#define SQLITE_CHANGESET_OMIT 0 +#define SQLITE_CHANGESET_REPLACE 1 +#define SQLITE_CHANGESET_ABORT 2 + +/* +** CAPI3REF: Streaming Versions of API functions. +** +** The six streaming API xxx_strm() functions serve similar purposes to the +** corresponding non-streaming API functions: +** +** <table border=1 style="margin-left:8ex;margin-right:8ex"> +** <tr><th>Streaming function<th>Non-streaming equivalent</th> +** <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply] +** <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat] +** <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert] +** <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start] +** <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset] +** <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset] +** </table> +** +** Non-streaming functions that accept changesets (or patchsets) as input +** require that the entire changeset be stored in a single buffer in memory. +** Similarly, those that return a changeset or patchset do so by returning +** a pointer to a single large buffer allocated using sqlite3_malloc(). +** Normally this is convenient. However, if an application running in a +** low-memory environment is required to handle very large changesets, the +** large contiguous memory allocations required can become onerous. +** +** In order to avoid this problem, instead of a single large buffer, input +** is passed to a streaming API functions by way of a callback function that +** the sessions module invokes to incrementally request input data as it is +** required. In all cases, a pair of API function parameters such as +** +** <pre> +**   int nChangeset, +**   void *pChangeset, +** </pre> +** +** Is replaced by: +** +** <pre> +**   int (*xInput)(void *pIn, void *pData, int *pnData), +**   void *pIn, +** </pre> +** +** Each time the xInput callback is invoked by the sessions module, the first +** argument passed is a copy of the supplied pIn context pointer. The second +** argument, pData, points to a buffer (*pnData) bytes in size. Assuming no +** error occurs the xInput method should copy up to (*pnData) bytes of data +** into the buffer and set (*pnData) to the actual number of bytes copied +** before returning SQLITE_OK. If the input is completely exhausted, (*pnData) +** should be set to zero to indicate this. Or, if an error occurs, an SQLite +** error code should be returned. In all cases, if an xInput callback returns +** an error, all processing is abandoned and the streaming API function +** returns a copy of the error code to the caller. +** +** In the case of sqlite3changeset_start_strm(), the xInput callback may be +** invoked by the sessions module at any point during the lifetime of the +** iterator. If such an xInput callback returns an error, the iterator enters +** an error state, whereby all subsequent calls to iterator functions +** immediately fail with the same error code as returned by xInput. +** +** Similarly, streaming API functions that return changesets (or patchsets) +** return them in chunks by way of a callback function instead of via a +** pointer to a single large buffer. In this case, a pair of parameters such +** as: +** +** <pre> +**   int *pnChangeset, +**   void **ppChangeset, +** </pre> +** +** Is replaced by: +** +** <pre> +**   int (*xOutput)(void *pOut, const void *pData, int nData), +**   void *pOut +** </pre> +** +** The xOutput callback is invoked zero or more times to return data to +** the application. The first parameter passed to each call is a copy of the +** pOut pointer supplied by the application. The second parameter, pData, +** points to a buffer nData bytes in size containing the chunk of output +** data being returned. If the xOutput callback successfully processes the +** supplied data, it should return SQLITE_OK to indicate success. Otherwise, +** it should return some other SQLite error code. In this case processing +** is immediately abandoned and the streaming API function returns a copy +** of the xOutput error code to the application. +** +** The sessions module never invokes an xOutput callback with the third +** parameter set to a value less than or equal to zero. Other than this, +** no guarantees are made as to the size of the chunks of data returned. +*/ +int sqlite3changeset_apply_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ + void *pIn, /* First arg for xInput */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx /* First argument passed to xConflict */ +); +int sqlite3changeset_concat_strm( + int (*xInputA)(void *pIn, void *pData, int *pnData), + void *pInA, + int (*xInputB)(void *pIn, void *pData, int *pnData), + void *pInB, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +int sqlite3changeset_invert_strm( + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +int sqlite3changeset_start_strm( + sqlite3_changeset_iter **pp, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn +); +int sqlite3session_changeset_strm( + sqlite3_session *pSession, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +int sqlite3session_patchset_strm( + sqlite3_session *pSession, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +int sqlite3changegroup_add_strm(sqlite3_changegroup*, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn +); +int sqlite3changegroup_output_strm(sqlite3_changegroup*, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); + + +/* +** Make sure we can call this stuff from C++. +*/ +#ifdef __cplusplus +} +#endif + +#endif /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */ + +/******** End of sqlite3session.h *********/ +/******** Begin file fts5.h *********/ +/* +** 2014 May 31 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** Interfaces to extend FTS5. Using the interfaces defined in this file, +** FTS5 may be extended with: +** +** * custom tokenizers, and +** * custom auxiliary functions. +*/ + + +#ifndef _FTS5_H +#define _FTS5_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************* +** CUSTOM AUXILIARY FUNCTIONS +** +** Virtual table implementations may overload SQL functions by implementing +** the sqlite3_module.xFindFunction() method. +*/ + +typedef struct Fts5ExtensionApi Fts5ExtensionApi; +typedef struct Fts5Context Fts5Context; +typedef struct Fts5PhraseIter Fts5PhraseIter; + +typedef void (*fts5_extension_function)( + const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ + Fts5Context *pFts, /* First arg to pass to pApi functions */ + sqlite3_context *pCtx, /* Context for returning result/error */ + int nVal, /* Number of values in apVal[] array */ + sqlite3_value **apVal /* Array of trailing arguments */ +); + +struct Fts5PhraseIter { + const unsigned char *a; + const unsigned char *b; +}; + +/* +** EXTENSION API FUNCTIONS +** +** xUserData(pFts): +** Return a copy of the context pointer the extension function was +** registered with. +** +** xColumnTotalSize(pFts, iCol, pnToken): +** If parameter iCol is less than zero, set output variable *pnToken +** to the total number of tokens in the FTS5 table. Or, if iCol is +** non-negative but less than the number of columns in the table, return +** the total number of tokens in column iCol, considering all rows in +** the FTS5 table. +** +** If parameter iCol is greater than or equal to the number of columns +** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g. +** an OOM condition or IO error), an appropriate SQLite error code is +** returned. +** +** xColumnCount(pFts): +** Return the number of columns in the table. +** +** xColumnSize(pFts, iCol, pnToken): +** If parameter iCol is less than zero, set output variable *pnToken +** to the total number of tokens in the current row. Or, if iCol is +** non-negative but less than the number of columns in the table, set +** *pnToken to the number of tokens in column iCol of the current row. +** +** If parameter iCol is greater than or equal to the number of columns +** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g. +** an OOM condition or IO error), an appropriate SQLite error code is +** returned. +** +** This function may be quite inefficient if used with an FTS5 table +** created with the "columnsize=0" option. +** +** xColumnText: +** This function attempts to retrieve the text of column iCol of the +** current document. If successful, (*pz) is set to point to a buffer +** containing the text in utf-8 encoding, (*pn) is set to the size in bytes +** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, +** if an error occurs, an SQLite error code is returned and the final values +** of (*pz) and (*pn) are undefined. +** +** xPhraseCount: +** Returns the number of phrases in the current query expression. +** +** xPhraseSize: +** Returns the number of tokens in phrase iPhrase of the query. Phrases +** are numbered starting from zero. +** +** xInstCount: +** Set *pnInst to the total number of occurrences of all phrases within +** the query within the current row. Return SQLITE_OK if successful, or +** an error code (i.e. SQLITE_NOMEM) if an error occurs. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. If the FTS5 table is created +** with either "detail=none" or "detail=column" and "content=" option +** (i.e. if it is a contentless table), then this API always returns 0. +** +** xInst: +** Query for the details of phrase match iIdx within the current row. +** Phrase matches are numbered starting from zero, so the iIdx argument +** should be greater than or equal to zero and smaller than the value +** output by xInstCount(). +** +** Usually, output parameter *piPhrase is set to the phrase number, *piCol +** to the column in which it occurs and *piOff the token offset of the +** first token of the phrase. The exception is if the table was created +** with the offsets=0 option specified. In this case *piOff is always +** set to -1. +** +** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM) +** if an error occurs. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. +** +** xRowid: +** Returns the rowid of the current row. +** +** xTokenize: +** Tokenize text using the tokenizer belonging to the FTS5 table. +** +** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback): +** This API function is used to query the FTS table for phrase iPhrase +** of the current query. Specifically, a query equivalent to: +** +** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid +** +** with $p set to a phrase equivalent to the phrase iPhrase of the +** current query is executed. Any column filter that applies to +** phrase iPhrase of the current query is included in $p. For each +** row visited, the callback function passed as the fourth argument +** is invoked. The context and API objects passed to the callback +** function may be used to access the properties of each matched row. +** Invoking Api.xUserData() returns a copy of the pointer passed as +** the third argument to pUserData. +** +** If the callback function returns any value other than SQLITE_OK, the +** query is abandoned and the xQueryPhrase function returns immediately. +** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. +** Otherwise, the error code is propagated upwards. +** +** If the query runs to completion without incident, SQLITE_OK is returned. +** Or, if some error occurs before the query completes or is aborted by +** the callback, an SQLite error code is returned. +** +** +** xSetAuxdata(pFts5, pAux, xDelete) +** +** Save the pointer passed as the second argument as the extension functions +** "auxiliary data". The pointer may then be retrieved by the current or any +** future invocation of the same fts5 extension function made as part of +** of the same MATCH query using the xGetAuxdata() API. +** +** Each extension function is allocated a single auxiliary data slot for +** each FTS query (MATCH expression). If the extension function is invoked +** more than once for a single FTS query, then all invocations share a +** single auxiliary data context. +** +** If there is already an auxiliary data pointer when this function is +** invoked, then it is replaced by the new pointer. If an xDelete callback +** was specified along with the original pointer, it is invoked at this +** point. +** +** The xDelete callback, if one is specified, is also invoked on the +** auxiliary data pointer after the FTS5 query has finished. +** +** If an error (e.g. an OOM condition) occurs within this function, an +** the auxiliary data is set to NULL and an error code returned. If the +** xDelete parameter was not NULL, it is invoked on the auxiliary data +** pointer before returning. +** +** +** xGetAuxdata(pFts5, bClear) +** +** Returns the current auxiliary data pointer for the fts5 extension +** function. See the xSetAuxdata() method for details. +** +** If the bClear argument is non-zero, then the auxiliary data is cleared +** (set to NULL) before this function returns. In this case the xDelete, +** if any, is not invoked. +** +** +** xRowCount(pFts5, pnRow) +** +** This function is used to retrieve the total number of rows in the table. +** In other words, the same value that would be returned by: +** +** SELECT count(*) FROM ftstable; +** +** xPhraseFirst() +** This function is used, along with type Fts5PhraseIter and the xPhraseNext +** method, to iterate through all instances of a single query phrase within +** the current row. This is the same information as is accessible via the +** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient +** to use, this API may be faster under some circumstances. To iterate +** through instances of phrase iPhrase, use the following code: +** +** Fts5PhraseIter iter; +** int iCol, iOff; +** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff); +** iCol>=0; +** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff) +** ){ +** // An instance of phrase iPhrase at offset iOff of column iCol +** } +** +** The Fts5PhraseIter structure is defined above. Applications should not +** modify this structure directly - it should only be used as shown above +** with the xPhraseFirst() and xPhraseNext() API methods (and by +** xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below). +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. If the FTS5 table is created +** with either "detail=none" or "detail=column" and "content=" option +** (i.e. if it is a contentless table), then this API always iterates +** through an empty set (all calls to xPhraseFirst() set iCol to -1). +** +** xPhraseNext() +** See xPhraseFirst above. +** +** xPhraseFirstColumn() +** This function and xPhraseNextColumn() are similar to the xPhraseFirst() +** and xPhraseNext() APIs described above. The difference is that instead +** of iterating through all instances of a phrase in the current row, these +** APIs are used to iterate through the set of columns in the current row +** that contain one or more instances of a specified phrase. For example: +** +** Fts5PhraseIter iter; +** int iCol; +** for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol); +** iCol>=0; +** pApi->xPhraseNextColumn(pFts, &iter, &iCol) +** ){ +** // Column iCol contains at least one instance of phrase iPhrase +** } +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" option. If the FTS5 table is created with either +** "detail=none" "content=" option (i.e. if it is a contentless table), +** then this API always iterates through an empty set (all calls to +** xPhraseFirstColumn() set iCol to -1). +** +** The information accessed using this API and its companion +** xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext +** (or xInst/xInstCount). The chief advantage of this API is that it is +** significantly more efficient than those alternatives when used with +** "detail=column" tables. +** +** xPhraseNextColumn() +** See xPhraseFirstColumn above. +*/ +struct Fts5ExtensionApi { + int iVersion; /* Currently always set to 3 */ + + void *(*xUserData)(Fts5Context*); + + int (*xColumnCount)(Fts5Context*); + int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow); + int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken); + + int (*xTokenize)(Fts5Context*, + const char *pText, int nText, /* Text to tokenize */ + void *pCtx, /* Context passed to xToken() */ + int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ + ); + + int (*xPhraseCount)(Fts5Context*); + int (*xPhraseSize)(Fts5Context*, int iPhrase); + + int (*xInstCount)(Fts5Context*, int *pnInst); + int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff); + + sqlite3_int64 (*xRowid)(Fts5Context*); + int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn); + int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken); + + int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData, + int(*)(const Fts5ExtensionApi*,Fts5Context*,void*) + ); + int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*)); + void *(*xGetAuxdata)(Fts5Context*, int bClear); + + int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*); + void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff); + + int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); + void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); +}; + +/* +** CUSTOM AUXILIARY FUNCTIONS +*************************************************************************/ + +/************************************************************************* +** CUSTOM TOKENIZERS +** +** Applications may also register custom tokenizer types. A tokenizer +** is registered by providing fts5 with a populated instance of the +** following structure. All structure methods must be defined, setting +** any member of the fts5_tokenizer struct to NULL leads to undefined +** behaviour. The structure methods are expected to function as follows: +** +** xCreate: +** This function is used to allocate and initialize a tokenizer instance. +** A tokenizer instance is required to actually tokenize text. +** +** The first argument passed to this function is a copy of the (void*) +** pointer provided by the application when the fts5_tokenizer object +** was registered with FTS5 (the third argument to xCreateTokenizer()). +** The second and third arguments are an array of nul-terminated strings +** containing the tokenizer arguments, if any, specified following the +** tokenizer name as part of the CREATE VIRTUAL TABLE statement used +** to create the FTS5 table. +** +** The final argument is an output variable. If successful, (*ppOut) +** should be set to point to the new tokenizer handle and SQLITE_OK +** returned. If an error occurs, some value other than SQLITE_OK should +** be returned. In this case, fts5 assumes that the final value of *ppOut +** is undefined. +** +** xDelete: +** This function is invoked to delete a tokenizer handle previously +** allocated using xCreate(). Fts5 guarantees that this function will +** be invoked exactly once for each successful call to xCreate(). +** +** xTokenize: +** This function is expected to tokenize the nText byte string indicated +** by argument pText. pText may or may not be nul-terminated. The first +** argument passed to this function is a pointer to an Fts5Tokenizer object +** returned by an earlier call to xCreate(). +** +** The second argument indicates the reason that FTS5 is requesting +** tokenization of the supplied text. This is always one of the following +** four values: +** +** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into +** or removed from the FTS table. The tokenizer is being invoked to +** determine the set of tokens to add to (or delete from) the +** FTS index. +** +** <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed +** against the FTS index. The tokenizer is being called to tokenize +** a bareword or quoted string specified as part of the query. +** +** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as +** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is +** followed by a "*" character, indicating that the last token +** returned by the tokenizer will be treated as a token prefix. +** +** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to +** satisfy an fts5_api.xTokenize() request made by an auxiliary +** function. Or an fts5_api.xColumnSize() request made by the same +** on a columnsize=0 database. +** </ul> +** +** For each token in the input string, the supplied callback xToken() must +** be invoked. The first argument to it should be a copy of the pointer +** passed as the second argument to xTokenize(). The third and fourth +** arguments are a pointer to a buffer containing the token text, and the +** size of the token in bytes. The 4th and 5th arguments are the byte offsets +** of the first byte of and first byte immediately following the text from +** which the token is derived within the input. +** +** The second argument passed to the xToken() callback ("tflags") should +** normally be set to 0. The exception is if the tokenizer supports +** synonyms. In this case see the discussion below for details. +** +** FTS5 assumes the xToken() callback is invoked for each token in the +** order that they occur within the input text. +** +** If an xToken() callback returns any value other than SQLITE_OK, then +** the tokenization should be abandoned and the xTokenize() method should +** immediately return a copy of the xToken() return value. Or, if the +** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally, +** if an error occurs with the xTokenize() implementation itself, it +** may abandon the tokenization and return any error code other than +** SQLITE_OK or SQLITE_DONE. +** +** SYNONYM SUPPORT +** +** Custom tokenizers may also support synonyms. Consider a case in which a +** user wishes to query for a phrase such as "first place". Using the +** built-in tokenizers, the FTS5 query 'first + place' will match instances +** of "first place" within the document set, but not alternative forms +** such as "1st place". In some applications, it would be better to match +** all instances of "first place" or "1st place" regardless of which form +** the user specified in the MATCH query text. +** +** There are several ways to approach this in FTS5: +** +** <ol><li> By mapping all synonyms to a single token. In this case, the +** In the above example, this means that the tokenizer returns the +** same token for inputs "first" and "1st". Say that token is in +** fact "first", so that when the user inserts the document "I won +** 1st place" entries are added to the index for tokens "i", "won", +** "first" and "place". If the user then queries for '1st + place', +** the tokenizer substitutes "first" for "1st" and the query works +** as expected. +** +** <li> By adding multiple synonyms for a single term to the FTS index. +** In this case, when tokenizing query text, the tokenizer may +** provide multiple synonyms for a single term within the document. +** FTS5 then queries the index for each synonym individually. For +** example, faced with the query: +** +** <codeblock> +** ... MATCH 'first place'</codeblock> +** +** the tokenizer offers both "1st" and "first" as synonyms for the +** first token in the MATCH query and FTS5 effectively runs a query +** similar to: +** +** <codeblock> +** ... MATCH '(first OR 1st) place'</codeblock> +** +** except that, for the purposes of auxiliary functions, the query +** still appears to contain just two phrases - "(first OR 1st)" +** being treated as a single phrase. +** +** <li> By adding multiple synonyms for a single term to the FTS index. +** Using this method, when tokenizing document text, the tokenizer +** provides multiple synonyms for each token. So that when a +** document such as "I won first place" is tokenized, entries are +** added to the FTS index for "i", "won", "first", "1st" and +** "place". +** +** This way, even if the tokenizer does not provide synonyms +** when tokenizing query text (it should not - to do would be +** inefficient), it doesn't matter if the user queries for +** 'first + place' or '1st + place', as there are entires in the +** FTS index corresponding to both forms of the first token. +** </ol> +** +** Whether it is parsing document or query text, any call to xToken that +** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit +** is considered to supply a synonym for the previous token. For example, +** when parsing the document "I won first place", a tokenizer that supports +** synonyms would call xToken() 5 times, as follows: +** +** <codeblock> +** xToken(pCtx, 0, "i", 1, 0, 1); +** xToken(pCtx, 0, "won", 3, 2, 5); +** xToken(pCtx, 0, "first", 5, 6, 11); +** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11); +** xToken(pCtx, 0, "place", 5, 12, 17); +**</codeblock> +** +** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time +** xToken() is called. Multiple synonyms may be specified for a single token +** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence. +** There is no limit to the number of synonyms that may be provided for a +** single token. +** +** In many cases, method (1) above is the best approach. It does not add +** extra data to the FTS index or require FTS5 to query for multiple terms, +** so it is efficient in terms of disk space and query speed. However, it +** does not support prefix queries very well. If, as suggested above, the +** token "first" is subsituted for "1st" by the tokenizer, then the query: +** +** <codeblock> +** ... MATCH '1s*'</codeblock> +** +** will not match documents that contain the token "1st" (as the tokenizer +** will probably not map "1s" to any prefix of "first"). +** +** For full prefix support, method (3) may be preferred. In this case, +** because the index contains entries for both "first" and "1st", prefix +** queries such as 'fi*' or '1s*' will match correctly. However, because +** extra entries are added to the FTS index, this method uses more space +** within the database. +** +** Method (2) offers a midpoint between (1) and (3). Using this method, +** a query such as '1s*' will match documents that contain the literal +** token "1st", but not "first" (assuming the tokenizer is not able to +** provide synonyms for prefixes). However, a non-prefix query like '1st' +** will match against "1st" and "first". This method does not require +** extra disk space, as no extra entries are added to the FTS index. +** On the other hand, it may require more CPU cycles to run MATCH queries, +** as separate queries of the FTS index are required for each synonym. +** +** When using methods (2) or (3), it is important that the tokenizer only +** provide synonyms when tokenizing document text (method (2)) or query +** text (method (3)), not both. Doing so will not cause any errors, but is +** inefficient. +*/ +typedef struct Fts5Tokenizer Fts5Tokenizer; +typedef struct fts5_tokenizer fts5_tokenizer; +struct fts5_tokenizer { + int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + void (*xDelete)(Fts5Tokenizer*); + int (*xTokenize)(Fts5Tokenizer*, + void *pCtx, + int flags, /* Mask of FTS5_TOKENIZE_* flags */ + const char *pText, int nText, + int (*xToken)( + void *pCtx, /* Copy of 2nd argument to xTokenize() */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Pointer to buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStart, /* Byte offset of token within input text */ + int iEnd /* Byte offset of end of token within input text */ + ) + ); +}; + +/* Flags that may be passed as the third argument to xTokenize() */ +#define FTS5_TOKENIZE_QUERY 0x0001 +#define FTS5_TOKENIZE_PREFIX 0x0002 +#define FTS5_TOKENIZE_DOCUMENT 0x0004 +#define FTS5_TOKENIZE_AUX 0x0008 + +/* Flags that may be passed by the tokenizer implementation back to FTS5 +** as the third argument to the supplied xToken callback. */ +#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */ + +/* +** END OF CUSTOM TOKENIZERS +*************************************************************************/ + +/************************************************************************* +** FTS5 EXTENSION REGISTRATION API +*/ +typedef struct fts5_api fts5_api; +struct fts5_api { + int iVersion; /* Currently always set to 2 */ + + /* Create a new tokenizer */ + int (*xCreateTokenizer)( + fts5_api *pApi, + const char *zName, + void *pContext, + fts5_tokenizer *pTokenizer, + void (*xDestroy)(void*) + ); + + /* Find an existing tokenizer */ + int (*xFindTokenizer)( + fts5_api *pApi, + const char *zName, + void **ppContext, + fts5_tokenizer *pTokenizer + ); + + /* Create a new auxiliary function */ + int (*xCreateFunction)( + fts5_api *pApi, + const char *zName, + void *pContext, + fts5_extension_function xFunction, + void (*xDestroy)(void*) + ); +}; + +/* +** END OF REGISTRATION API +*************************************************************************/ + +#ifdef __cplusplus +} /* end of the 'extern "C"' block */ +#endif + +#endif /* _FTS5_H */ + +/******** End of fts5.h *********/ diff --git a/builddir/zlib-1.2.8/README b/builddir/zlib-1.2.8/README new file mode 100644 index 0000000..5ca9d12 --- /dev/null +++ b/builddir/zlib-1.2.8/README @@ -0,0 +1,115 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.8 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and +rfc1952 (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. + +Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant +<info@winimage.com> for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. + +Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +http://marknelson.us/1997/01/01/zlib-engine/ . + +The changes made in version 1.2.8 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory contrib/ . + +zlib is available in Java using the java.util.zip package, documented at +http://java.sun.com/developer/technicalArticles/Programming/compression/ . + +A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available +at CPAN (Comprehensive Perl Archive Network) sites, including +http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . + +A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is +available in Python 1.5 and later versions, see +http://docs.python.org/library/zlib.html . + +zlib is built into tcl: http://wiki.tcl.tk/4610 . + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant <info@winimage.com>, is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS or BEOS. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. + +Copyright notice: + + (C) 1995-2013 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@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/builddir/zlib-1.2.8/bin/ZlibDllRelease/vc100.pdb b/builddir/zlib-1.2.8/bin/ZlibDllRelease/vc100.pdb new file mode 100644 index 0000000..b8b4e00 Binary files /dev/null and b/builddir/zlib-1.2.8/bin/ZlibDllRelease/vc100.pdb differ diff --git a/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.dll b/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.dll new file mode 100644 index 0000000..d25aa55 Binary files /dev/null and b/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.dll differ diff --git a/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.exp b/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.exp new file mode 100644 index 0000000..2483fd6 Binary files /dev/null and b/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.exp differ diff --git a/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.lib b/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.lib new file mode 100644 index 0000000..a170d3f Binary files /dev/null and b/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.lib differ diff --git a/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.map b/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.map new file mode 100644 index 0000000..1069c2d --- /dev/null +++ b/builddir/zlib-1.2.8/bin/ZlibDllRelease/zlibwapi.map @@ -0,0 +1,948 @@ + zlibwapi + + Timestamp is 54eb6f2b (Mon Feb 23 19:19:23 2015) + + Preferred load address is 10000000 + + Start Length Name Class + 0001:00000000 00018b8aH .text CODE + 0002:00000000 00000110H .idata$5 DATA + 0002:00000110 00000004H .CRT$XCA DATA + 0002:00000114 00000004H .CRT$XCZ DATA + 0002:00000118 00000004H .CRT$XIA DATA + 0002:0000011c 00000010H .CRT$XIC DATA + 0002:0000012c 00000004H .CRT$XIZ DATA + 0002:00000130 00000004H .CRT$XPA DATA + 0002:00000134 00000004H .CRT$XPX DATA + 0002:00000138 00000004H .CRT$XPXA DATA + 0002:0000013c 00000004H .CRT$XPZ DATA + 0002:00000140 00000004H .CRT$XTA DATA + 0002:00000144 00000004H .CRT$XTZ DATA + 0002:00000148 00005da8H .rdata DATA + 0002:00005ef0 00000004H .rtc$IAA DATA + 0002:00005ef4 00000004H .rtc$IZZ DATA + 0002:00005ef8 00000004H .rtc$TAA DATA + 0002:00005efc 00000004H .rtc$TZZ DATA + 0002:00005f00 0000041cH .xdata$x DATA + 0002:0000631c 00000014H .idata$2 DATA + 0002:00006330 00000014H .idata$3 DATA + 0002:00006344 00000110H .idata$4 DATA + 0002:00006454 000004caH .idata$6 DATA + 0002:00006920 00000c44H .edata DATA + 0003:00000000 00000fb0H .data DATA + 0003:00000fc0 00001de4H .bss DATA + 0004:00000000 00000058H .rsrc$01 DATA + 0004:00000060 00000338H .rsrc$02 DATA + + Address Publics by Value Rva+Base Lib:Object + + 0000:00000000 ___safe_se_handler_count 00000000 <absolute> + 0000:00000000 ___safe_se_handler_table 00000000 <absolute> + 0000:00000000 __except_list 00000000 <absolute> + 0000:00000000 ___ImageBase 10000000 <linker-defined> + 0001:00000000 _adler32@12 10001000 f adler32.obj + 0001:00000330 _adler32_combine@12 10001330 f adler32.obj + 0001:00000350 _compress2@20 10001350 f compress.obj + 0001:00000400 _compress@16 10001400 f compress.obj + 0001:00000420 _compressBound@4 10001420 f compress.obj + 0001:00000440 _get_crc_table@0 10001440 f crc32.obj + 0001:00000450 _crc32@12 10001450 f crc32.obj + 0001:00000860 _crc32_combine@12 10001860 f crc32.obj + 0001:00000880 _deflateInit_@16 10001880 f deflate.obj + 0001:000008b0 _deflateInit2_@32 100018b0 f deflate.obj + 0001:00000af0 _deflateSetDictionary@12 10001af0 f deflate.obj + 0001:00000c80 _deflateResetKeep@4 10001c80 f deflate.obj + 0001:00000d30 _deflateReset@4 10001d30 f deflate.obj + 0001:00000d60 _deflateSetHeader@8 10001d60 f deflate.obj + 0001:00000d90 _deflatePending@12 10001d90 f deflate.obj + 0001:00000dd0 _deflatePrime@12 10001dd0 f deflate.obj + 0001:00000e60 _deflateParams@12 10001e60 f deflate.obj + 0001:00000f60 _deflateTune@20 10001f60 f deflate.obj + 0001:00000fb0 _deflateBound@8 10001fb0 f deflate.obj + 0001:00001110 _deflate@8 10002110 f deflate.obj + 0001:00001970 _deflateEnd@4 10002970 f deflate.obj + 0001:00001a50 _deflateCopy@8 10002a50 f deflate.obj + 0001:00002ba0 _gzclose@4 10003ba0 f gzclose.obj + 0001:00002ef0 _gzopen@8 10003ef0 f gzlib.obj + 0001:00002f10 _gzdopen@8 10003f10 f gzlib.obj + 0001:00002f60 _gzopen_w@8 10003f60 f gzlib.obj + 0001:00002f80 _gzbuffer@8 10003f80 f gzlib.obj + 0001:00002fc0 _gzrewind@4 10003fc0 f gzlib.obj + 0001:00003020 _gzseek64@16 10004020 f gzlib.obj + 0001:000031a0 _gzseek@12 100041a0 f gzlib.obj + 0001:000031e0 _gztell64@4 100041e0 f gzlib.obj + 0001:00003230 _gztell@4 10004230 f gzlib.obj + 0001:00003260 _gzoffset64@4 10004260 f gzlib.obj + 0001:000032b0 _gzoffset@4 100042b0 f gzlib.obj + 0001:000032e0 _gzeof@4 100042e0 f gzlib.obj + 0001:00003310 _gzerror@8 10004310 f gzlib.obj + 0001:00003360 _gzclearerr@4 10004360 f gzlib.obj + 0001:000033a0 _gz_error 100043a0 f gzlib.obj + 0001:000038b0 _gzread@12 100048b0 f gzread.obj + 0001:00003a30 _gzgetc@4 10004a30 f gzread.obj + 0001:00003a90 _gzgetc_@4 10004a90 f gzread.obj + 0001:00003aa0 _gzungetc@8 10004aa0 f gzread.obj + 0001:00003b80 _gzgets@12 10004b80 f gzread.obj + 0001:00003c90 _gzdirect@4 10004c90 f gzread.obj + 0001:00003cd0 _gzclose_r@4 10004cd0 f gzread.obj + 0001:00004020 _gzwrite@12 10005020 f gzwrite.obj + 0001:00004140 _gzputc@8 10005140 f gzwrite.obj + 0001:00004200 _gzputs@8 10005200 f gzwrite.obj + 0001:00004240 _gzvprintf 10005240 f gzwrite.obj + 0001:00004310 _gzprintf 10005310 f gzwrite.obj + 0001:00004330 _gzflush@8 10005330 f gzwrite.obj + 0001:000043b0 _gzsetparams@12 100053b0 f gzwrite.obj + 0001:00004460 _gzclose_w@4 10005460 f gzwrite.obj + 0001:00004520 _inflateBackInit_@20 10005520 f infback.obj + 0001:00004610 _inflateBack@20 10005610 f infback.obj + 0001:00005310 _inflateBackEnd@4 10006310 f infback.obj + 0001:00005350 _inflateResetKeep@4 10006350 f inflate.obj + 0001:000053d0 _inflateReset@4 100063d0 f inflate.obj + 0001:00005400 _inflateReset2@8 10006400 f inflate.obj + 0001:00005490 _inflateInit2_@16 10006490 f inflate.obj + 0001:00005550 _inflateInit_@12 10006550 f inflate.obj + 0001:00005570 _inflatePrime@12 10006570 f inflate.obj + 0001:000056f0 _inflate@8 100066f0 f inflate.obj + 0001:00006bf0 _inflateEnd@4 10007bf0 f inflate.obj + 0001:00006c50 _inflateGetDictionary@12 10007c50 f inflate.obj + 0001:00006cc0 _inflateSetDictionary@12 10007cc0 f inflate.obj + 0001:00006d60 _inflateGetHeader@8 10007d60 f inflate.obj + 0001:00006e00 _inflateSync@4 10007e00 f inflate.obj + 0001:00006ef0 _inflateSyncPoint@4 10007ef0 f inflate.obj + 0001:00006f30 _inflateCopy@8 10007f30 f inflate.obj + 0001:00007090 _inflateUndermine@8 10008090 f inflate.obj + 0001:000070c0 _inflateMark@4 100080c0 f inflate.obj + 0001:00007130 _inflate_table 10008130 f inftrees.obj + 0001:00007520 _call_zopen64 10008520 f ioapi.obj + 0001:00007540 _call_zseek64 10008540 f ioapi.obj + 0001:000075a0 _call_ztell64 100085a0 f ioapi.obj + 0001:000075d0 _fill_zlib_filefunc64_32_def_from_filefunc32 100085d0 f ioapi.obj + 0001:00007750 _fill_fopen64_filefunc 10008750 f ioapi.obj + 0001:00007840 _win32_open64_file_func 10008840 f iowin32.obj + 0001:00007840 _win32_open64_file_funcA 10008840 f iowin32.obj + 0001:00007840 _win32_open_file_func 10008840 f iowin32.obj + 0001:000078a0 _win32_open64_file_funcW 100088a0 f iowin32.obj + 0001:00007900 _win32_read_file_func 10008900 f iowin32.obj + 0001:00007950 _win32_write_file_func 10008950 f iowin32.obj + 0001:000079f0 _win32_tell_file_func 100089f0 f iowin32.obj + 0001:00007a40 _win32_tell64_file_func 10008a40 f iowin32.obj + 0001:00007aa0 _win32_seek_file_func 10008aa0 f iowin32.obj + 0001:00007af0 _win32_seek64_file_func 10008af0 f iowin32.obj + 0001:00007b50 _win32_close_file_func 10008b50 f iowin32.obj + 0001:00007b80 _win32_error_file_func 10008b80 f iowin32.obj + 0001:00007ba0 _fill_win32_filefunc 10008ba0 f iowin32.obj + 0001:00007be0 _fill_win32_filefunc64 10008be0 f iowin32.obj + 0001:00007be0 _fill_win32_filefunc64A 10008be0 f iowin32.obj + 0001:00007c20 _fill_win32_filefunc64W 10008c20 f iowin32.obj + 0001:00007c60 __tr_init 10008c60 f trees.obj + 0001:00008c00 __tr_stored_block 10009c00 f trees.obj + 0001:00008c90 __tr_flush_bits 10009c90 f trees.obj + 0001:00008ca0 __tr_align 10009ca0 f trees.obj + 0001:00008d90 __tr_flush_block 10009d90 f trees.obj + 0001:00009560 _uncompress@16 1000a560 f uncompr.obj + 0001:00009890 _unzStringFileNameCompare@12 1000a890 f unzip.obj + 0001:0000a130 _unzOpen2@8 1000b130 f unzip.obj + 0001:0000a180 _unzOpen2_64@8 1000b180 f unzip.obj + 0001:0000a1e0 _unzOpen@4 1000b1e0 f unzip.obj + 0001:0000a200 _unzOpen64@4 1000b200 f unzip.obj + 0001:0000a220 _unzClose@4 1000b220 f unzip.obj + 0001:0000a260 _unzGetGlobalInfo64@8 1000b260 f unzip.obj + 0001:0000a2a0 _unzGetGlobalInfo@8 1000b2a0 f unzip.obj + 0001:0000a890 _unzGetCurrentFileInfo64@32 1000b890 f unzip.obj + 0001:0000a8c0 _unzGetCurrentFileInfo@32 1000b8c0 f unzip.obj + 0001:0000a9a0 _unzGoToFirstFile@4 1000b9a0 f unzip.obj + 0001:0000aa10 _unzGoToNextFile@4 1000ba10 f unzip.obj + 0001:0000aac0 _unzLocateFile@12 1000bac0 f unzip.obj + 0001:0000ac00 _unzGetFilePos64@8 1000bc00 f unzip.obj + 0001:0000ac50 _unzGetFilePos@8 1000bc50 f unzip.obj + 0001:0000ac80 _unzGoToFilePos64@8 1000bc80 f unzip.obj + 0001:0000acf0 _unzGoToFilePos@8 1000bcf0 f unzip.obj + 0001:0000af70 _unzOpenCurrentFile3@20 1000bf70 f unzip.obj + 0001:0000b1b0 _unzOpenCurrentFile@4 1000c1b0 f unzip.obj + 0001:0000b1d0 _unzOpenCurrentFilePassword@8 1000c1d0 f unzip.obj + 0001:0000b1f0 _unzOpenCurrentFile2@16 1000c1f0 f unzip.obj + 0001:0000b210 _unzGetCurrentFileZStreamPos64@4 1000c210 f unzip.obj + 0001:0000b250 _unzReadCurrentFile@12 1000c250 f unzip.obj + 0001:0000b4f0 _unztell@4 1000c4f0 f unzip.obj + 0001:0000b520 _unztell64@4 1000c520 f unzip.obj + 0001:0000b550 _unzeof@4 1000c550 f unzip.obj + 0001:0000b590 _unzGetLocalExtrafield@12 1000c590 f unzip.obj + 0001:0000b650 _unzCloseCurrentFile@4 1000c650 f unzip.obj + 0001:0000b700 _unzGetGlobalComment@12 1000c700 f unzip.obj + 0001:0000c060 _LoadCentralDirectoryRecord 1000d060 f zip.obj + 0001:0000c500 _zipOpen3@16 1000d500 f zip.obj + 0001:0000c660 _zipOpen2@16 1000d660 f zip.obj + 0001:0000c6b0 _zipOpen2_64@16 1000d6b0 f zip.obj + 0001:0000c710 _zipOpen64@8 1000d710 f zip.obj + 0001:0000c710 _zipOpen@8 1000d710 f zip.obj + 0001:0000c730 _Write_LocalFileHeader 1000d730 f zip.obj + 0001:0000c950 _zipOpenNewFileInZip4_64@76 1000d950 f zip.obj + 0001:0000ce20 _zipOpenNewFileInZip3@64 1000de20 f zip.obj + 0001:0000ce80 _zipOpenNewFileInZip3_64@68 1000de80 f zip.obj + 0001:0000cee0 _zipOpenNewFileInZip2@44 1000dee0 f zip.obj + 0001:0000cf30 _zipOpenNewFileInZip2_64@48 1000df30 f zip.obj + 0001:0000cf80 _zipOpenNewFileInZip64@44 1000df80 f zip.obj + 0001:0000cfd0 _zipOpenNewFileInZip@40 1000dfd0 f zip.obj + 0001:0000d0e0 _zipWriteInFileInZip@12 1000e0e0 f zip.obj + 0001:0000d1e0 _zipCloseFileInZipRaw@12 1000e1e0 f zip.obj + 0001:0000d200 _zipCloseFileInZipRaw64@16 1000e200 f zip.obj + 0001:0000d710 _zipCloseFileInZip@4 1000e710 f zip.obj + 0001:0000d730 _Write_Zip64EndOfCentralDirectoryLocator 1000e730 f zip.obj + 0001:0000d7b0 _Write_Zip64EndOfCentralDirectoryRecord 1000e7b0 f zip.obj + 0001:0000d8d0 _Write_EndOfCentralDirectoryRecord 1000e8d0 f zip.obj + 0001:0000da10 _Write_GlobalComment 1000ea10 f zip.obj + 0001:0000da80 _zipClose@8 1000ea80 f zip.obj + 0001:0000dc00 _zlibVersion@0 1000ec00 f zutil.obj + 0001:0000dc10 _zlibCompileFlags@0 1000ec10 f zutil.obj + 0001:0000dc20 _zError@4 1000ec20 f zutil.obj + 0001:0000dc40 _zcalloc 1000ec40 f zutil.obj + 0001:0000dc60 _zcfree 1000ec60 f zutil.obj + 0001:0000dc80 _longest_match 1000ec80 f match686.obj + 0001:0000de68 _match_init 1000ee68 f match686.obj + 0001:0000df70 _inflate_fast 1000ef70 f inffas32.obj + 0001:0000e603 __lseeki64_nolock 1000f603 f LIBCMT:lseeki64.obj + 0001:0000e688 __lseeki64 1000f688 f LIBCMT:lseeki64.obj + 0001:0000eea7 __wopen 1000fea7 f LIBCMT:wopen.obj + 0001:0000ef55 _free 1000ff55 f LIBCMT:free.obj + 0001:0000ef8f _malloc 1000ff8f f LIBCMT:malloc.obj + 0001:0000f023 __snprintf 10010023 f LIBCMT:snprintf.obj + 0001:0000f0cf ??0_LocaleUpdate@@QAE@PAUlocaleinfo_struct@@@Z 100100cf f i LIBCMT:wcstombs.obj + 0001:0000f156 __wcstombs_l_helper 10010156 f LIBCMT:wcstombs.obj + 0001:0000f3bd _wcstombs 100103bd f LIBCMT:wcstombs.obj + 0001:0000f3d7 __get_sys_err_msg 100103d7 f i LIBCMT:strerror.obj + 0001:0000f3ff _strerror 100103ff f LIBCMT:strerror.obj + 0001:0000f470 _memchr 10010470 f LIBCMT:memchr.obj + 0001:0000f51d __get_errno_from_oserr 1001051d f LIBCMT:dosmap.obj + 0001:0000f55f __errno 1001055f f LIBCMT:dosmap.obj + 0001:0000f572 ___doserrno 10010572 f LIBCMT:dosmap.obj + 0001:0000f585 __dosmaperr 10010585 f LIBCMT:dosmap.obj + 0001:0000f5a8 __ftelli64_nolock 100105a8 f LIBCMT:ftelli64.obj + 0001:0000f8f2 __ftelli64 100108f2 f LIBCMT:ftelli64.obj + 0001:0000f95f __fseeki64_nolock 1001095f f LIBCMT:fseeki64.obj + 0001:0000f9fb __fseeki64 100109fb f LIBCMT:fseeki64.obj + 0001:0000fa7a __fsopen 10010a7a f LIBCMT:fopen.obj + 0001:0000fb36 _fopen 10010b36 f LIBCMT:fopen.obj + 0001:0000fb4d __fread_nolock_s 10010b4d f LIBCMT:fread.obj + 0001:0000fd09 _fread_s 10010d09 f LIBCMT:fread.obj + 0001:0000fd97 _fread 10010d97 f LIBCMT:fread.obj + 0001:0000fdb4 _ferror 10010db4 f LIBCMT:feoferr.obj + 0001:0000fddc __fwrite_nolock 10010ddc f LIBCMT:fwrite.obj + 0001:0000ff33 _fwrite 10010f33 f LIBCMT:fwrite.obj + 0001:0000ffad __fclose_nolock 10010fad f LIBCMT:fclose.obj + 0001:0001001a _fclose 1001101a f LIBCMT:fclose.obj + 0001:0001008e _srand 1001108e f LIBCMT:rand.obj + 0001:000100a0 _rand 100110a0 f LIBCMT:rand.obj + 0001:000100c1 __time64 100110c1 f LIBCMT:time64.obj + 0001:00010112 __CRT_INIT@12 10011112 f LIBCMT:dllcrt0.obj + 0001:0001036c __DllMainCRTStartup@12 1001136c f LIBCMT:dllcrt0.obj + 0001:0001038f __ioinit 1001138f f LIBCMT:ioinit.obj + 0001:000105d4 __ioterm 100115d4 f LIBCMT:ioinit.obj + 0001:00010627 __set_osfhnd 10011627 f LIBCMT:osfinfo.obj + 0001:000106a8 __free_osfhnd 100116a8 f LIBCMT:osfinfo.obj + 0001:0001072e __get_osfhandle 1001172e f LIBCMT:osfinfo.obj + 0001:00010797 ___lock_fhandle 10011797 f LIBCMT:osfinfo.obj + 0001:00010836 __unlock_fhandle 10011836 f LIBCMT:osfinfo.obj + 0001:0001085d __alloc_osfhnd 1001185d f LIBCMT:osfinfo.obj + 0001:000109f6 __initp_misc_invarg 100119f6 f LIBCMT:invarg.obj + 0001:00010a05 __call_reportfault 10011a05 f LIBCMT:invarg.obj + 0001:00010b2e __invoke_watson 10011b2e f LIBCMT:invarg.obj + 0001:00010b53 __invalid_parameter 10011b53 f LIBCMT:invarg.obj + 0001:00010b80 __invalid_parameter_noinfo 10011b80 f LIBCMT:invarg.obj + 0001:00010b90 __SEH_prolog4 10011b90 f LIBCMT:sehprolg4.obj + 0001:00010bd5 __SEH_epilog4 10011bd5 f LIBCMT:sehprolg4.obj + 0001:00010bf0 __except_handler4 10011bf0 f LIBCMT:chandler4.obj + 0001:00010d7f __write_nolock 10011d7f f LIBCMT:write.obj + 0001:0001147c _write 1001247c f LIBCMT:write.obj + 0001:0001147c __write 1001247c f LIBCMT:write.obj + 0001:00011550 __chsize_nolock 10012550 f LIBCMT:chsize.obj + 0001:00011706 __read_nolock 10012706 f LIBCMT:read.obj + 0001:00011cbd _read 10012cbd f LIBCMT:read.obj + 0001:00011cbd __read 10012cbd f LIBCMT:read.obj + 0001:00011db3 __close_nolock 10012db3 f LIBCMT:close.obj + 0001:00011e4f _close 10012e4f f LIBCMT:close.obj + 0001:00011e4f __close 10012e4f f LIBCMT:close.obj + 0001:00011f13 __lseek_nolock 10012f13 f LIBCMT:lseek.obj + 0001:00011f88 ___crtCorExitProcess 10012f88 f LIBCMT:crt0dat.obj + 0001:00011fb3 ___crtExitProcess 10012fb3 f LIBCMT:crt0dat.obj + 0001:00011fcb __lockexit 10012fcb f LIBCMT:crt0dat.obj + 0001:00011fd4 __unlockexit 10012fd4 f LIBCMT:crt0dat.obj + 0001:00011fdd __init_pointers 10012fdd f LIBCMT:crt0dat.obj + 0001:00012010 __initterm_e 10013010 f LIBCMT:crt0dat.obj + 0001:00012034 __cinit 10013034 f LIBCMT:crt0dat.obj + 0001:0001220b __exit 1001320b f LIBCMT:crt0dat.obj + 0001:00012221 __cexit 10013221 f LIBCMT:crt0dat.obj + 0001:00012230 __amsg_exit 10013230 f LIBCMT:crt0dat.obj + 0001:0001224e __setmode_nolock 1001324e f LIBCMT:setmode.obj + 0001:00012309 __get_fmode 10013309 f LIBCMT:setmode.obj + 0001:00012336 __heap_init 10013336 f LIBCMT:heapinit.obj + 0001:00012354 __heap_term 10013354 f LIBCMT:heapinit.obj + 0001:00012368 __GET_RTERRMSG 10013368 f LIBCMT:crt0msg.obj + 0001:0001238e __NMSG_WRITE 1001338e f LIBCMT:crt0msg.obj + 0001:0001253d __FF_MSGBANNER 1001353d f LIBCMT:crt0msg.obj + 0001:00012576 __initp_heap_handler 10013576 f LIBCMT:handler.obj + 0001:00012585 __callnewh 10013585 f LIBCMT:handler.obj + 0001:000125ad __flsbuf 100135ad f LIBCMT:_flsbuf.obj + 0001:00012791 __output_l 10013791 f LIBCMT:output.obj + 0001:0001333d __vsnprintf_l 1001433d f LIBCMT:vsnprint.obj + 0001:000133e9 _vsnprintf 100143e9 f LIBCMT:vsnprint.obj + 0001:000133e9 __vsnprintf 100143e9 f LIBCMT:vsnprint.obj + 0001:00013629 ___updatetmbcinfo 10014629 f LIBCMT:mbctype.obj + 0001:00013749 __setmbcp_nolock 10014749 f LIBCMT:mbctype.obj + 0001:00013932 __setmbcp 10014932 f LIBCMT:mbctype.obj + 0001:00013acc ___initmbctable 10014acc f LIBCMT:mbctype.obj + 0001:00013aea ___addlocaleref 10014aea f LIBCMT:localref.obj + 0001:00013b79 ___removelocaleref 10014b79 f LIBCMT:localref.obj + 0001:00013c12 ___freetlocinfo 10014c12 f LIBCMT:localref.obj + 0001:00013d5d __updatetlocinfoEx_nolock 10014d5d f LIBCMT:localref.obj + 0001:00013daa ___updatetlocinfo 10014daa f LIBCMT:localref.obj + 0001:00013e23 __encoded_null 10014e23 f LIBCMT:tidtable.obj + 0001:00013e2c ___crtTlsAlloc@4 10014e2c f LIBCMT:tidtable.obj + 0001:00013e35 ___set_flsgetvalue 10014e35 f LIBCMT:tidtable.obj + 0001:00013e69 __mtterm 10014e69 f LIBCMT:tidtable.obj + 0001:00013ea6 __initptd 10014ea6 f LIBCMT:tidtable.obj + 0001:00013f5a __getptd_noexit 10014f5a f LIBCMT:tidtable.obj + 0001:00013fd3 __getptd 10014fd3 f LIBCMT:tidtable.obj + 0001:00013fed __freefls@4 10014fed f LIBCMT:tidtable.obj + 0001:0001411c __freeptd 1001511c f LIBCMT:tidtable.obj + 0001:0001418a __mtinit 1001518a f LIBCMT:tidtable.obj + 0001:00014305 @__security_check_cookie@4 10015305 f LIBCMT:secchk.obj + 0001:00014314 ___sys_nerr 10015314 f LIBCMT:syserr.obj + 0001:0001431a ___sys_errlist 1001531a f LIBCMT:syserr.obj + 0001:00014320 _strcpy_s 10015320 f LIBCMT:strcpy_s.obj + 0001:0001437f __malloc_crt 1001537f f LIBCMT:crtheap.obj + 0001:000143c4 __calloc_crt 100153c4 f LIBCMT:crtheap.obj + 0001:00014410 __realloc_crt 10015410 f LIBCMT:crtheap.obj + 0001:0001445e __fileno 1001545e f LIBCMT:fileno.obj + 0001:00014490 __chkstk 10015490 f LIBCMT:chkstk.obj + 0001:00014490 __alloca_probe 10015490 LIBCMT:chkstk.obj + 0001:000144bb ___iob_func 100154bb f LIBCMT:_file.obj + 0001:000144c1 ___initstdio 100154c1 f LIBCMT:_file.obj + 0001:00014572 ___endstdio 10015572 f LIBCMT:_file.obj + 0001:00014592 __lock_file 10015592 f LIBCMT:_file.obj + 0001:000145d3 __lock_file2 100155d3 f LIBCMT:_file.obj + 0001:00014605 __unlock_file 10015605 f LIBCMT:_file.obj + 0001:00014641 __unlock_file2 10015641 f LIBCMT:_file.obj + 0001:00014670 __flush 10015670 f LIBCMT:fflush.obj + 0001:000146d8 __fflush_nolock 100156d8 f LIBCMT:fflush.obj + 0001:000147fa __flushall 100157fa f LIBCMT:fflush.obj + 0001:00014803 __openfile 10015803 f LIBCMT:_open.obj + 0001:00014a9a __getstream 10015a9a f LIBCMT:stream.obj + 0001:00014bd0 __local_unwind4 10015bd0 f LIBCMT:exsup4.obj + 0001:00014ca6 __seh_longjmp_unwind4@4 10015ca6 f LIBCMT:exsup4.obj + 0001:00014cc2 @_EH4_CallFilterFunc@8 10015cc2 f LIBCMT:exsup4.obj + 0001:00014cd9 @_EH4_TransferToHandler@8 10015cd9 f LIBCMT:exsup4.obj + 0001:00014cf2 @_EH4_GlobalUnwind2@8 10015cf2 f LIBCMT:exsup4.obj + 0001:00014d0b @_EH4_LocalUnwind@16 10015d0b f LIBCMT:exsup4.obj + 0001:00014d22 __filbuf 10015d22 f LIBCMT:_filbuf.obj + 0001:00014e44 _memcpy_s 10015e44 f LIBCMT:memcpy_s.obj + 0001:00014ec0 _memset 10015ec0 f LIBCMT:memset.obj + 0001:00014f40 _memcpy 10015f40 f LIBCMT:memcpy.obj + 0001:000152a1 __freebuf 100162a1 f LIBCMT:_freebuf.obj + 0001:000152e0 __aulldiv 100162e0 f LIBCMT:ulldiv.obj + 0001:00015348 __setenvp 10016348 f LIBCMT:stdenvp.obj + 0001:000155be __setargv 100165be f LIBCMT:stdargv.obj + 0001:00015679 ___crtGetEnvironmentStringsA 10016679 f LIBCMT:a_env.obj + 0001:00015710 __RTC_Initialize 10016710 f LIBCMT:_initsect_.obj + 0001:00015736 __RTC_Terminate 10016736 f LIBCMT:_initsect_.obj + 0001:0001575c __XcptFilter 1001675c f LIBCMT:winxfltr.obj + 0001:000158a6 ___CppXcptFilter 100168a6 f LIBCMT:winxfltr.obj + 0001:000158c6 _DllMain@12 100168c6 f LIBCMT:dllmain.obj + 0001:000158cc ___security_init_cookie 100168cc f LIBCMT:gs_support.obj + 0001:00015967 __mtinitlocks 10016967 f LIBCMT:mlock.obj + 0001:000159b1 __mtdeletelocks 100169b1 f LIBCMT:mlock.obj + 0001:00015a08 __unlock 10016a08 f LIBCMT:mlock.obj + 0001:00015a1f __mtinitlocknum 10016a1f f LIBCMT:mlock.obj + 0001:00015ae1 __lock 10016ae1 f LIBCMT:mlock.obj + 0001:00015b14 __crt_debugger_hook 10016b14 f LIBCMT:dbghook.obj + 0001:00015b20 __ValidateImageBase 10016b20 f LIBCMT:pesect.obj + 0001:00015b60 __FindPESection 10016b60 f LIBCMT:pesect.obj + 0001:00015bb0 __IsNonwritableInCurrentImage 10016bb0 f LIBCMT:pesect.obj + 0001:00015c6c __putwch_nolock 10016c6c f LIBCMT:putwch.obj + 0001:00015cae __mbtowc_l 10016cae f LIBCMT:mbtowc.obj + 0001:00015dc4 _mbtowc 10016dc4 f LIBCMT:mbtowc.obj + 0001:00015dde __isleadbyte_l 10016dde f i LIBCMT:_wctype.obj + 0001:00015e16 _isleadbyte 10016e16 f i LIBCMT:_wctype.obj + 0001:00015e29 __isatty 10016e29 f LIBCMT:isatty.obj + 0001:00015e7f ?terminate@@YAXXZ 10016e7f f LIBCMT:hooks.obj + 0001:00015eb8 __initp_eh_hooks 10016eb8 f LIBCMT:hooks.obj + 0001:00015ec9 __initp_misc_winsig 10016ec9 f LIBCMT:winsig.obj + 0001:00015f1e ___get_sigabrt 10016f1e f LIBCMT:winsig.obj + 0001:00015f2b _raise 10016f2b f LIBCMT:winsig.obj + 0001:000160ce __initp_misc_rand_s 100170ce f LIBCMT:rand_s.obj + 0001:000160dd __initp_misc_purevirt 100170dd f LIBCMT:inithelp.obj + 0001:000161a2 ___onexitinit 100171a2 f LIBCMT:onexit.obj + 0001:000161d3 __onexit 100171d3 f LIBCMT:onexit.obj + 0001:0001620f _atexit 1001720f f LIBCMT:onexit.obj + 0001:00016226 __initp_misc_cfltcvt_tab 10017226 f LIBCMT:cmiscdat.obj + 0001:00016250 _strlen 10017250 f LIBCMT:strlen.obj + 0001:000162db ___crtMessageBoxW 100172db f LIBCMT:crtmboxw.obj + 0001:00016447 _wcscat_s 10017447 f LIBCMT:wcscat_s.obj + 0001:000164bc _wcsncpy_s 100174bc f LIBCMT:wcsncpy_s.obj + 0001:00016589 _wcslen 10017589 f LIBCMT:wcslen.obj + 0001:000165a4 _wcscpy_s 100175a4 f LIBCMT:wcscpy_s.obj + 0001:00016607 __set_error_mode 10017607 f LIBCMT:errmode.obj + 0001:00016646 __getbuf 10017646 f LIBCMT:_getbuf.obj + 0001:0001668f __get_printf_count_output 1001768f f LIBCMT:printf.obj + 0001:000166a5 __wctomb_s_l 100176a5 f LIBCMT:wctomb.obj + 0001:000167fa _wctomb_s 100177fa f LIBCMT:wctomb.obj + 0001:00016820 __aulldvrm 10017820 f LIBCMT:ulldvrm.obj + 0001:000168b5 __freea 100178b5 f i LIBCMT:a_map.obj + 0001:00016abc ___crtLCMapStringA 10017abc f LIBCMT:a_map.obj + 0001:00016be9 ___crtGetStringTypeA 10017be9 f LIBCMT:a_str.obj + 0001:00016c29 ___free_lc_time 10017c29 f LIBCMT:inittime.obj + 0001:00016fa0 ___free_lconv_num 10017fa0 f LIBCMT:initnum.obj + 0001:00017009 ___free_lconv_mon 10018009 f LIBCMT:initmon.obj + 0001:00017107 ___report_gsfailure 10018107 f LIBCMT:gs_report.obj + 0001:0001720d __calloc_impl 1001820d f LIBCMT:calloc_impl.obj + 0001:0001728f _realloc 1001828f f LIBCMT:realloc.obj + 0001:0001733c __fcloseall 1001833c f LIBCMT:closeall.obj + 0001:000173d8 __commit 100183d8 f LIBCMT:commit.obj + 0001:00017be5 __open 10018be5 f LIBCMT:open.obj + 0001:00017be5 _open 10018be5 f LIBCMT:open.obj + 0001:00017c93 __sopen_helper 10018c93 f LIBCMT:open.obj + 0001:00017d57 __sopen_s 10018d57 f LIBCMT:open.obj + 0001:00017d77 __mbsnbicmp_l 10018d77 f LIBCMT:mbsnbicm.obj + 0001:00017f7b __mbsnbicmp 10018f7b f LIBCMT:mbsnbicm.obj + 0001:00017f95 __mbsnbcmp_l 10018f95 f LIBCMT:mbsnbcmp.obj + 0001:000180e1 __mbsnbcmp 100190e1 f LIBCMT:mbsnbcmp.obj + 0001:00018100 __global_unwind2 10019100 f LIBCMT:exsup.obj + 0001:00018165 __local_unwind2 10019165 f LIBCMT:exsup.obj + 0001:000181e9 __abnormal_termination 100191e9 f LIBCMT:exsup.obj + 0001:0001820c __NLG_Notify1 1001920c f LIBCMT:exsup.obj + 0001:00018215 __NLG_Notify 10019215 f LIBCMT:exsup.obj + 0001:0001822c __NLG_Dispatch 1001922c LIBCMT:exsup.obj + 0001:0001822c __NLG_Dispatch2 1001922c LIBCMT:exsup.obj + 0001:00018234 __NLG_Call 10019234 f LIBCMT:exsup.obj + 0001:00018236 __NLG_Return2 10019236 LIBCMT:exsup.obj + 0001:00018237 __VEC_memzero 10019237 f LIBCMT:p4_memset.obj + 0001:000182f1 ___sse2_available_init 100192f1 f LIBCMT:cpu_disp.obj + 0001:00018301 __VEC_memcpy 10019301 f LIBCMT:p4_memcpy.obj + 0001:00018457 __ismbblead 10019457 f LIBCMT:ismbbyte.obj + 0001:0001846f ___initconout 1001946f f LIBCMT:initcon.obj + 0001:0001848e ___termconout 1001948e f LIBCMT:initcon.obj + 0001:000184a5 _abort 100194a5 f LIBCMT:abort.obj + 0001:000184d8 __msize 100194d8 f LIBCMT:msize.obj + 0001:0001850b __fptrap 1001950b f LIBCMT:crt0fp.obj + 0001:00018520 __alloca_probe_16 10019520 f LIBCMT:alloca16.obj + 0001:00018536 __alloca_probe_8 10019536 LIBCMT:alloca16.obj + 0001:0001854c __strnicmp_l 1001954c f LIBCMT:strnicmp.obj + 0001:0001862e __strnicmp 1001962e f LIBCMT:strnicmp.obj + 0001:00018681 _strncmp 10019681 f LIBCMT:strncmp.obj + 0001:00018741 __tolower_l 10019741 f LIBCMT:tolower.obj + 0001:00018860 ___ascii_strnicmp 10019860 f LIBCMT:_strnicm.obj + 0001:000188c1 __isctype_l 100198c1 f LIBCMT:isctype.obj + 0001:00018980 _strcspn 10019980 f LIBCMT:strcspn.obj + 0001:000189d0 _strcmp 100199d0 f LIBCMT:strcmp.obj + 0001:00018a60 _strpbrk 10019a60 f LIBCMT:strpbrk.obj + 0001:00018aa0 __allmul 10019aa0 f LIBCMT:llmul.obj + 0001:00018ad4 _RtlUnwind@16 10019ad4 f kernel32:KERNEL32.dll + 0001:00018ae0 __alldiv 10019ae0 f LIBCMT:lldiv.obj + 0002:00000000 __imp__CreateFileA@28 1001a000 kernel32:KERNEL32.dll + 0002:00000004 __imp__SetFilePointer@16 1001a004 kernel32:KERNEL32.dll + 0002:00000008 __imp__WriteFile@20 1001a008 kernel32:KERNEL32.dll + 0002:0000000c __imp__ReadFile@20 1001a00c kernel32:KERNEL32.dll + 0002:00000010 __imp__CreateFileW@28 1001a010 kernel32:KERNEL32.dll + 0002:00000014 __imp__GetLastError@0 1001a014 kernel32:KERNEL32.dll + 0002:00000018 __imp__CloseHandle@4 1001a018 kernel32:KERNEL32.dll + 0002:0000001c __imp__GetFileType@4 1001a01c kernel32:KERNEL32.dll + 0002:00000020 __imp__HeapFree@12 1001a020 kernel32:KERNEL32.dll + 0002:00000024 __imp__HeapAlloc@12 1001a024 kernel32:KERNEL32.dll + 0002:00000028 __imp__WideCharToMultiByte@32 1001a028 kernel32:KERNEL32.dll + 0002:0000002c __imp__GetSystemTimeAsFileTime@4 1001a02c kernel32:KERNEL32.dll + 0002:00000030 __imp__GetCurrentThreadId@0 1001a030 kernel32:KERNEL32.dll + 0002:00000034 __imp__DecodePointer@4 1001a034 kernel32:KERNEL32.dll + 0002:00000038 __imp__GetCommandLineA@0 1001a038 kernel32:KERNEL32.dll + 0002:0000003c __imp__SetHandleCount@4 1001a03c kernel32:KERNEL32.dll + 0002:00000040 __imp__GetStdHandle@4 1001a040 kernel32:KERNEL32.dll + 0002:00000044 __imp__InitializeCriticalSectionAndSpinCount@8 1001a044 kernel32:KERNEL32.dll + 0002:00000048 __imp__GetStartupInfoW@4 1001a048 kernel32:KERNEL32.dll + 0002:0000004c __imp__DeleteCriticalSection@4 1001a04c kernel32:KERNEL32.dll + 0002:00000050 __imp__SetStdHandle@8 1001a050 kernel32:KERNEL32.dll + 0002:00000054 __imp__EnterCriticalSection@4 1001a054 kernel32:KERNEL32.dll + 0002:00000058 __imp__LeaveCriticalSection@4 1001a058 kernel32:KERNEL32.dll + 0002:0000005c __imp__UnhandledExceptionFilter@4 1001a05c kernel32:KERNEL32.dll + 0002:00000060 __imp__SetUnhandledExceptionFilter@4 1001a060 kernel32:KERNEL32.dll + 0002:00000064 __imp__IsDebuggerPresent@0 1001a064 kernel32:KERNEL32.dll + 0002:00000068 __imp__EncodePointer@4 1001a068 kernel32:KERNEL32.dll + 0002:0000006c __imp__TerminateProcess@8 1001a06c kernel32:KERNEL32.dll + 0002:00000070 __imp__GetCurrentProcess@0 1001a070 kernel32:KERNEL32.dll + 0002:00000074 __imp__GetConsoleCP@0 1001a074 kernel32:KERNEL32.dll + 0002:00000078 __imp__GetConsoleMode@8 1001a078 kernel32:KERNEL32.dll + 0002:0000007c __imp__SetEndOfFile@4 1001a07c kernel32:KERNEL32.dll + 0002:00000080 __imp__GetProcessHeap@0 1001a080 kernel32:KERNEL32.dll + 0002:00000084 __imp__MultiByteToWideChar@24 1001a084 kernel32:KERNEL32.dll + 0002:00000088 __imp__GetProcAddress@8 1001a088 kernel32:KERNEL32.dll + 0002:0000008c __imp__GetModuleHandleW@4 1001a08c kernel32:KERNEL32.dll + 0002:00000090 __imp__ExitProcess@4 1001a090 kernel32:KERNEL32.dll + 0002:00000094 __imp__HeapCreate@12 1001a094 kernel32:KERNEL32.dll + 0002:00000098 __imp__HeapDestroy@4 1001a098 kernel32:KERNEL32.dll + 0002:0000009c __imp__GetModuleFileNameW@12 1001a09c kernel32:KERNEL32.dll + 0002:000000a0 __imp__GetCPInfo@8 1001a0a0 kernel32:KERNEL32.dll + 0002:000000a4 __imp__InterlockedIncrement@4 1001a0a4 kernel32:KERNEL32.dll + 0002:000000a8 __imp__InterlockedDecrement@4 1001a0a8 kernel32:KERNEL32.dll + 0002:000000ac __imp__GetACP@0 1001a0ac kernel32:KERNEL32.dll + 0002:000000b0 __imp__GetOEMCP@0 1001a0b0 kernel32:KERNEL32.dll + 0002:000000b4 __imp__IsValidCodePage@4 1001a0b4 kernel32:KERNEL32.dll + 0002:000000b8 __imp__TlsAlloc@0 1001a0b8 kernel32:KERNEL32.dll + 0002:000000bc __imp__TlsGetValue@4 1001a0bc kernel32:KERNEL32.dll + 0002:000000c0 __imp__TlsSetValue@8 1001a0c0 kernel32:KERNEL32.dll + 0002:000000c4 __imp__TlsFree@4 1001a0c4 kernel32:KERNEL32.dll + 0002:000000c8 __imp__SetLastError@4 1001a0c8 kernel32:KERNEL32.dll + 0002:000000cc __imp__Sleep@4 1001a0cc kernel32:KERNEL32.dll + 0002:000000d0 __imp__RtlUnwind@16 1001a0d0 kernel32:KERNEL32.dll + 0002:000000d4 __imp__GetModuleFileNameA@12 1001a0d4 kernel32:KERNEL32.dll + 0002:000000d8 __imp__FreeEnvironmentStringsW@4 1001a0d8 kernel32:KERNEL32.dll + 0002:000000dc __imp__GetEnvironmentStringsW@0 1001a0dc kernel32:KERNEL32.dll + 0002:000000e0 __imp__QueryPerformanceCounter@4 1001a0e0 kernel32:KERNEL32.dll + 0002:000000e4 __imp__GetTickCount@0 1001a0e4 kernel32:KERNEL32.dll + 0002:000000e8 __imp__GetCurrentProcessId@0 1001a0e8 kernel32:KERNEL32.dll + 0002:000000ec __imp__WriteConsoleW@20 1001a0ec kernel32:KERNEL32.dll + 0002:000000f0 __imp__LoadLibraryW@4 1001a0f0 kernel32:KERNEL32.dll + 0002:000000f4 __imp__LCMapStringW@24 1001a0f4 kernel32:KERNEL32.dll + 0002:000000f8 __imp__GetStringTypeW@16 1001a0f8 kernel32:KERNEL32.dll + 0002:000000fc __imp__HeapReAlloc@16 1001a0fc kernel32:KERNEL32.dll + 0002:00000100 __imp__FlushFileBuffers@4 1001a100 kernel32:KERNEL32.dll + 0002:00000104 __imp__IsProcessorFeaturePresent@4 1001a104 kernel32:KERNEL32.dll + 0002:00000108 __imp__HeapSize@12 1001a108 kernel32:KERNEL32.dll + 0002:0000010c \177KERNEL32_NULL_THUNK_DATA 1001a10c kernel32:KERNEL32.dll + 0002:00000110 ___xc_a 1001a110 LIBCMT:crt0init.obj + 0002:00000114 ___xc_z 1001a114 LIBCMT:crt0init.obj + 0002:00000118 ___xi_a 1001a118 LIBCMT:crt0init.obj + 0002:0000012c ___xi_z 1001a12c LIBCMT:crt0init.obj + 0002:00000130 ___xp_a 1001a130 LIBCMT:crt0init.obj + 0002:0000013c ___xp_z 1001a13c LIBCMT:crt0init.obj + 0002:00000140 ___xt_a 1001a140 LIBCMT:crt0init.obj + 0002:00000144 ___xt_z 1001a144 LIBCMT:crt0init.obj + 0002:00000148 ??_C@_0EA@FCLIIPNN@Visual?5C?$CL?$CL?5CRT?3?5Not?5enough?5memor@ 1001a148 LIBCMT:strerror.obj + 0002:00000188 __pDefaultRawDllMain 1001a188 LIBCMT:dllcrt0.obj + 0002:00000188 __pRawDllMain 1001a188 LIBCMT:dllcrt0.obj + 0002:0000018c ??_C@_0P@MIGLKIOC@CorExitProcess?$AA@ 1001a18c LIBCMT:crt0dat.obj + 0002:0000019c ??_C@_1BI@BGOHAHKC@?$AAm?$AAs?$AAc?$AAo?$AAr?$AAe?$AAe?$AA?4?$AAd?$AAl?$AAl?$AA?$AA@ 1001a19c LIBCMT:crt0dat.obj + 0002:000001b4 ??_C@_1BO@BKOMIGKJ@?$AAr?$AAu?$AAn?$AAt?$AAi?$AAm?$AAe?$AA?5?$AAe?$AAr?$AAr?$AAo?$AAr?$AA?5?$AA?$AA@ 1001a1b4 LIBCMT:crt0msg.obj + 0002:000001d4 ??_C@_15JNBOKNOG@?$AA?$AN?$AA?6?$AA?$AA@ 1001a1d4 LIBCMT:crt0msg.obj + 0002:000001dc ??_C@_1BM@JBBEPPHI@?$AAT?$AAL?$AAO?$AAS?$AAS?$AA?5?$AAe?$AAr?$AAr?$AAo?$AAr?$AA?$AN?$AA?6?$AA?$AA@ 1001a1dc LIBCMT:crt0msg.obj + 0002:000001f8 ??_C@_1BK@KMOMNAAI@?$AAS?$AAI?$AAN?$AAG?$AA?5?$AAe?$AAr?$AAr?$AAo?$AAr?$AA?$AN?$AA?6?$AA?$AA@ 1001a1f8 LIBCMT:crt0msg.obj + 0002:00000214 ??_C@_1BO@BFCDCGC@?$AAD?$AAO?$AAM?$AAA?$AAI?$AAN?$AA?5?$AAe?$AAr?$AAr?$AAo?$AAr?$AA?$AN?$AA?6?$AA?$AA@ 1001a214 LIBCMT:crt0msg.obj + 0002:00000238 ??_C@_1BOO@KGEDBGAJ@?$AAR?$AA6?$AA0?$AA3?$AA3?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAA?$AAt?$AAt?$AAe?$AAm?$AAp?$AAt?$AA?5?$AAt?$AAo?$AA?5?$AAu?$AAs?$AAe?$AA?5?$AAM?$AAS?$AAI?$AAL?$AA?5?$AAc?$AAo?$AAd@ 1001a238 LIBCMT:crt0msg.obj + 0002:00000428 ??_C@_1GG@GOPILAJP@?$AAR?$AA6?$AA0?$AA3?$AA2?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAn?$AAo?$AAt?$AA?5?$AAe?$AAn?$AAo?$AAu?$AAg?$AAh?$AA?5?$AAs?$AAp?$AAa?$AAc?$AAe?$AA?5?$AAf?$AAo?$AAr?$AA?5?$AAl?$AAo@ 1001a428 LIBCMT:crt0msg.obj + 0002:00000490 ??_C@_1MG@ENCOOIDF@?$AAR?$AA6?$AA0?$AA3?$AA1?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAA?$AAt?$AAt?$AAe?$AAm?$AAp?$AAt?$AA?5?$AAt?$AAo?$AA?5?$AAi?$AAn?$AAi?$AAt?$AAi?$AAa?$AAl?$AAi?$AAz?$AAe?$AA?5?$AAt@ 1001a490 LIBCMT:crt0msg.obj + 0002:00000558 ??_C@_1DO@BMFCDCD@?$AAR?$AA6?$AA0?$AA3?$AA0?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAC?$AAR?$AAT?$AA?5?$AAn?$AAo?$AAt?$AA?5?$AAi?$AAn?$AAi?$AAt?$AAi?$AAa?$AAl?$AAi?$AAz?$AAe?$AAd?$AA?$AN?$AA?6?$AA?$AA@ 1001a558 LIBCMT:crt0msg.obj + 0002:00000598 ??_C@_1EK@HHFLMAOL@?$AAR?$AA6?$AA0?$AA2?$AA8?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAu?$AAn?$AAa?$AAb?$AAl?$AAe?$AA?5?$AAt?$AAo?$AA?5?$AAi?$AAn?$AAi?$AAt?$AAi?$AAa?$AAl?$AAi?$AAz?$AAe?$AA?5?$AAh?$AAe@ 1001a598 LIBCMT:crt0msg.obj + 0002:000005e8 ??_C@_1GK@MFGOKLAG@?$AAR?$AA6?$AA0?$AA2?$AA7?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAn?$AAo?$AAt?$AA?5?$AAe?$AAn?$AAo?$AAu?$AAg?$AAh?$AA?5?$AAs?$AAp?$AAa?$AAc?$AAe?$AA?5?$AAf?$AAo?$AAr?$AA?5?$AAl?$AAo@ 1001a5e8 LIBCMT:crt0msg.obj + 0002:00000658 ??_C@_1GK@MCAAGJMO@?$AAR?$AA6?$AA0?$AA2?$AA6?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAn?$AAo?$AAt?$AA?5?$AAe?$AAn?$AAo?$AAu?$AAg?$AAh?$AA?5?$AAs?$AAp?$AAa?$AAc?$AAe?$AA?5?$AAf?$AAo?$AAr?$AA?5?$AAs?$AAt@ 1001a658 LIBCMT:crt0msg.obj + 0002:000006c8 ??_C@_1EM@MAADIHMB@?$AAR?$AA6?$AA0?$AA2?$AA5?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAp?$AAu?$AAr?$AAe?$AA?5?$AAv?$AAi?$AAr?$AAt?$AAu?$AAa?$AAl?$AA?5?$AAf?$AAu?$AAn?$AAc?$AAt?$AAi?$AAo?$AAn?$AA?5?$AAc@ 1001a6c8 LIBCMT:crt0msg.obj + 0002:00000718 ??_C@_1GK@FHCKBEFA@?$AAR?$AA6?$AA0?$AA2?$AA4?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAn?$AAo?$AAt?$AA?5?$AAe?$AAn?$AAo?$AAu?$AAg?$AAh?$AA?5?$AAs?$AAp?$AAa?$AAc?$AAe?$AA?5?$AAf?$AAo?$AAr?$AA?5?$AA_?$AAo@ 1001a718 LIBCMT:crt0msg.obj + 0002:00000788 ??_C@_1FC@ECHBIFBC@?$AAR?$AA6?$AA0?$AA1?$AA9?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAu?$AAn?$AAa?$AAb?$AAl?$AAe?$AA?5?$AAt?$AAo?$AA?5?$AAo?$AAp?$AAe?$AAn?$AA?5?$AAc?$AAo?$AAn?$AAs?$AAo?$AAl?$AAe?$AA?5@ 1001a788 LIBCMT:crt0msg.obj + 0002:000007e0 ??_C@_1EC@JIBHAOPH@?$AAR?$AA6?$AA0?$AA1?$AA8?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAu?$AAn?$AAe?$AAx?$AAp?$AAe?$AAc?$AAt?$AAe?$AAd?$AA?5?$AAh?$AAe?$AAa?$AAp?$AA?5?$AAe?$AAr?$AAr?$AAo?$AAr?$AA?$AN?$AA?6@ 1001a7e0 LIBCMT:crt0msg.obj + 0002:00000828 ??_C@_1FK@BEOGODMC@?$AAR?$AA6?$AA0?$AA1?$AA7?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAu?$AAn?$AAe?$AAx?$AAp?$AAe?$AAc?$AAt?$AAe?$AAd?$AA?5?$AAm?$AAu?$AAl?$AAt?$AAi?$AAt?$AAh?$AAr?$AAe?$AAa?$AAd?$AA?5@ 1001a828 LIBCMT:crt0msg.obj + 0002:00000888 ??_C@_1FI@LOGNIKDM@?$AAR?$AA6?$AA0?$AA1?$AA6?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAn?$AAo?$AAt?$AA?5?$AAe?$AAn?$AAo?$AAu?$AAg?$AAh?$AA?5?$AAs?$AAp?$AAa?$AAc?$AAe?$AA?5?$AAf?$AAo?$AAr?$AA?5?$AAt?$AAh@ 1001a888 LIBCMT:crt0msg.obj + 0002:000008e0 ??_C@_1EG@BEHAGFJD@?$AAR?$AA6?$AA0?$AA1?$AA0?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAa?$AAb?$AAo?$AAr?$AAt?$AA?$CI?$AA?$CJ?$AA?5?$AAh?$AAa?$AAs?$AA?5?$AAb?$AAe?$AAe?$AAn?$AA?5?$AAc?$AAa?$AAl?$AAl?$AAe?$AAd@ 1001a8e0 LIBCMT:crt0msg.obj + 0002:00000928 ??_C@_1FI@HONFMGBI@?$AAR?$AA6?$AA0?$AA0?$AA9?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAn?$AAo?$AAt?$AA?5?$AAe?$AAn?$AAo?$AAu?$AAg?$AAh?$AA?5?$AAs?$AAp?$AAa?$AAc?$AAe?$AA?5?$AAf?$AAo?$AAr?$AA?5?$AAe?$AAn@ 1001a928 LIBCMT:crt0msg.obj + 0002:00000980 ??_C@_1FE@LLNEDJMD@?$AAR?$AA6?$AA0?$AA0?$AA8?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAn?$AAo?$AAt?$AA?5?$AAe?$AAn?$AAo?$AAu?$AAg?$AAh?$AA?5?$AAs?$AAp?$AAa?$AAc?$AAe?$AA?5?$AAf?$AAo?$AAr?$AA?5?$AAa?$AAr@ 1001a980 LIBCMT:crt0msg.obj + 0002:000009d8 ??_C@_1FK@PGACCAFB@?$AAR?$AA6?$AA0?$AA0?$AA2?$AA?$AN?$AA?6?$AA?9?$AA?5?$AAf?$AAl?$AAo?$AAa?$AAt?$AAi?$AAn?$AAg?$AA?5?$AAp?$AAo?$AAi?$AAn?$AAt?$AA?5?$AAs?$AAu?$AAp?$AAp?$AAo?$AAr?$AAt?$AA?5@ 1001a9d8 LIBCMT:crt0msg.obj + 0002:00000ae8 ??_C@_1EK@MBDPDCGA@?$AAM?$AAi?$AAc?$AAr?$AAo?$AAs?$AAo?$AAf?$AAt?$AA?5?$AAV?$AAi?$AAs?$AAu?$AAa?$AAl?$AA?5?$AAC?$AA?$CL?$AA?$CL?$AA?5?$AAR?$AAu?$AAn?$AAt?$AAi?$AAm?$AAe?$AA?5?$AAL?$AAi?$AAb@ 1001aae8 LIBCMT:crt0msg.obj + 0002:00000b34 ??_C@_15IABLJNFO@?$AA?6?$AA?6?$AA?$AA@ 1001ab34 LIBCMT:crt0msg.obj + 0002:00000b3c ??_C@_17LGKOMLJ@?$AA?4?$AA?4?$AA?4?$AA?$AA@ 1001ab3c LIBCMT:crt0msg.obj + 0002:00000b44 ??_C@_1CO@EAEJAADC@?$AA?$DM?$AAp?$AAr?$AAo?$AAg?$AAr?$AAa?$AAm?$AA?5?$AAn?$AAa?$AAm?$AAe?$AA?5?$AAu?$AAn?$AAk?$AAn?$AAo?$AAw?$AAn?$AA?$DO?$AA?$AA@ 1001ab44 LIBCMT:crt0msg.obj + 0002:00000b74 ??_C@_1DE@JNGNBFGO@?$AAR?$AAu?$AAn?$AAt?$AAi?$AAm?$AAe?$AA?5?$AAE?$AAr?$AAr?$AAo?$AAr?$AA?$CB?$AA?6?$AA?6?$AAP?$AAr?$AAo?$AAg?$AAr?$AAa?$AAm?$AA?3?$AA?5?$AA?$AA@ 1001ab74 LIBCMT:crt0msg.obj + 0002:00000ba8 ??_C@_1O@CEDCILHN@?$AA?$CI?$AAn?$AAu?$AAl?$AAl?$AA?$CJ?$AA?$AA@ 1001aba8 LIBCMT:output.obj + 0002:00000bb8 ??_C@_06OJHGLDPL@?$CInull?$CJ?$AA@ 1001abb8 LIBCMT:output.obj + 0002:00000bc0 ___lookuptable 1001abc0 LIBCMT:output.obj + 0002:00000c1c ??_C@_1BC@GDGBMEMK@?$AAH?$AAH?$AA?3?$AAm?$AAm?$AA?3?$AAs?$AAs?$AA?$AA@ 1001ac1c LIBCMT:nlsdata2.obj + 0002:00000c30 ??_C@_1CI@KNAKOEBC@?$AAd?$AAd?$AAd?$AAd?$AA?0?$AA?5?$AAM?$AAM?$AAM?$AAM?$AA?5?$AAd?$AAd?$AA?0?$AA?5?$AAy?$AAy?$AAy?$AAy?$AA?$AA@ 1001ac30 LIBCMT:nlsdata2.obj + 0002:00000c58 ??_C@_1BC@IEBCMHCM@?$AAM?$AAM?$AA?1?$AAd?$AAd?$AA?1?$AAy?$AAy?$AA?$AA@ 1001ac58 LIBCMT:nlsdata2.obj + 0002:00000c6c ??_C@_15CLMNNGEL@?$AAP?$AAM?$AA?$AA@ 1001ac6c LIBCMT:nlsdata2.obj + 0002:00000c74 ??_C@_15ODEHAHHF@?$AAA?$AAM?$AA?$AA@ 1001ac74 LIBCMT:nlsdata2.obj + 0002:00000c7c ??_C@_1BC@FEMKIFH@?$AAD?$AAe?$AAc?$AAe?$AAm?$AAb?$AAe?$AAr?$AA?$AA@ 1001ac7c LIBCMT:nlsdata2.obj + 0002:00000c90 ??_C@_1BC@BGLIFPF@?$AAN?$AAo?$AAv?$AAe?$AAm?$AAb?$AAe?$AAr?$AA?$AA@ 1001ac90 LIBCMT:nlsdata2.obj + 0002:00000ca4 ??_C@_1BA@EPANDLNG@?$AAO?$AAc?$AAt?$AAo?$AAb?$AAe?$AAr?$AA?$AA@ 1001aca4 LIBCMT:nlsdata2.obj + 0002:00000cb4 ??_C@_1BE@DKAAMBJL@?$AAS?$AAe?$AAp?$AAt?$AAe?$AAm?$AAb?$AAe?$AAr?$AA?$AA@ 1001acb4 LIBCMT:nlsdata2.obj + 0002:00000cc8 ??_C@_1O@PAHLKOAC@?$AAA?$AAu?$AAg?$AAu?$AAs?$AAt?$AA?$AA@ 1001acc8 LIBCMT:nlsdata2.obj + 0002:00000cd8 ??_C@_19BIFMLPCD@?$AAJ?$AAu?$AAl?$AAy?$AA?$AA@ 1001acd8 LIBCMT:nlsdata2.obj + 0002:00000ce4 ??_C@_19EPFLPGAP@?$AAJ?$AAu?$AAn?$AAe?$AA?$AA@ 1001ace4 LIBCMT:nlsdata2.obj + 0002:00000cf0 ??_C@_1M@GJNLMHFD@?$AAA?$AAp?$AAr?$AAi?$AAl?$AA?$AA@ 1001acf0 LIBCMT:nlsdata2.obj + 0002:00000cfc ??_C@_1M@IKEENEDF@?$AAM?$AAa?$AAr?$AAc?$AAh?$AA?$AA@ 1001acfc LIBCMT:nlsdata2.obj + 0002:00000d08 ??_C@_1BC@JGDDFFAM@?$AAF?$AAe?$AAb?$AAr?$AAu?$AAa?$AAr?$AAy?$AA?$AA@ 1001ad08 LIBCMT:nlsdata2.obj + 0002:00000d1c ??_C@_1BA@EFMEIEBA@?$AAJ?$AAa?$AAn?$AAu?$AAa?$AAr?$AAy?$AA?$AA@ 1001ad1c LIBCMT:nlsdata2.obj + 0002:00000d2c ??_C@_17EGKACKIF@?$AAD?$AAe?$AAc?$AA?$AA@ 1001ad2c LIBCMT:nlsdata2.obj + 0002:00000d34 ??_C@_17BBDMLCIG@?$AAN?$AAo?$AAv?$AA?$AA@ 1001ad34 LIBCMT:nlsdata2.obj + 0002:00000d3c ??_C@_17FNLKOI@?$AAO?$AAc?$AAt?$AA?$AA@ 1001ad3c LIBCMT:nlsdata2.obj + 0002:00000d44 ??_C@_17HCHCOKMG@?$AAS?$AAe?$AAp?$AA?$AA@ 1001ad44 LIBCMT:nlsdata2.obj + 0002:00000d4c ??_C@_17ICPELBCN@?$AAA?$AAu?$AAg?$AA?$AA@ 1001ad4c LIBCMT:nlsdata2.obj + 0002:00000d54 ??_C@_17IJPCKHK@?$AAJ?$AAu?$AAl?$AA?$AA@ 1001ad54 LIBCMT:nlsdata2.obj + 0002:00000d5c ??_C@_17KCJGOCPB@?$AAJ?$AAu?$AAn?$AA?$AA@ 1001ad5c LIBCMT:nlsdata2.obj + 0002:00000d64 ??_C@_17PNNKMEED@?$AAM?$AAa?$AAy?$AA?$AA@ 1001ad64 LIBCMT:nlsdata2.obj + 0002:00000d6c ??_C@_17LFPOIHDD@?$AAA?$AAp?$AAr?$AA?$AA@ 1001ad6c LIBCMT:nlsdata2.obj + 0002:00000d74 ??_C@_17CKNLEDEC@?$AAM?$AAa?$AAr?$AA?$AA@ 1001ad74 LIBCMT:nlsdata2.obj + 0002:00000d7c ??_C@_17LMDJEKJN@?$AAF?$AAe?$AAb?$AA?$AA@ 1001ad7c LIBCMT:nlsdata2.obj + 0002:00000d84 ??_C@_17DKNBKCHM@?$AAJ?$AAa?$AAn?$AA?$AA@ 1001ad84 LIBCMT:nlsdata2.obj + 0002:00000d8c ??_C@_1BC@ENMNNPAJ@?$AAS?$AAa?$AAt?$AAu?$AAr?$AAd?$AAa?$AAy?$AA?$AA@ 1001ad8c LIBCMT:nlsdata2.obj + 0002:00000da0 ??_C@_1O@PDICJHAG@?$AAF?$AAr?$AAi?$AAd?$AAa?$AAy?$AA?$AA@ 1001ada0 LIBCMT:nlsdata2.obj + 0002:00000db0 ??_C@_1BC@HHMNLIHE@?$AAT?$AAh?$AAu?$AAr?$AAs?$AAd?$AAa?$AAy?$AA?$AA@ 1001adb0 LIBCMT:nlsdata2.obj + 0002:00000dc4 ??_C@_1BE@EBOGMDOH@?$AAW?$AAe?$AAd?$AAn?$AAe?$AAs?$AAd?$AAa?$AAy?$AA?$AA@ 1001adc4 LIBCMT:nlsdata2.obj + 0002:00000dd8 ??_C@_1BA@ENFBFFEK@?$AAT?$AAu?$AAe?$AAs?$AAd?$AAa?$AAy?$AA?$AA@ 1001add8 LIBCMT:nlsdata2.obj + 0002:00000de8 ??_C@_1O@MMNBFLIA@?$AAM?$AAo?$AAn?$AAd?$AAa?$AAy?$AA?$AA@ 1001ade8 LIBCMT:nlsdata2.obj + 0002:00000df8 ??_C@_1O@IHNHDHPB@?$AAS?$AAu?$AAn?$AAd?$AAa?$AAy?$AA?$AA@ 1001adf8 LIBCMT:nlsdata2.obj + 0002:00000e08 ??_C@_17GGIBDPIH@?$AAS?$AAa?$AAt?$AA?$AA@ 1001ae08 LIBCMT:nlsdata2.obj + 0002:00000e10 ??_C@_17HFOLPPLP@?$AAF?$AAr?$AAi?$AA?$AA@ 1001ae10 LIBCMT:nlsdata2.obj + 0002:00000e18 ??_C@_17PDPHAADD@?$AAT?$AAh?$AAu?$AA?$AA@ 1001ae18 LIBCMT:nlsdata2.obj + 0002:00000e20 ??_C@_17CJEDCEPE@?$AAW?$AAe?$AAd?$AA?$AA@ 1001ae20 LIBCMT:nlsdata2.obj + 0002:00000e28 ??_C@_17BMKGEGOJ@?$AAT?$AAu?$AAe?$AA?$AA@ 1001ae28 LIBCMT:nlsdata2.obj + 0002:00000e30 ??_C@_17KBOMKBF@?$AAM?$AAo?$AAn?$AA?$AA@ 1001ae30 LIBCMT:nlsdata2.obj + 0002:00000e38 ??_C@_17MBGCMIPB@?$AAS?$AAu?$AAn?$AA?$AA@ 1001ae38 LIBCMT:nlsdata2.obj + 0002:00000e40 ??_C@_08JCCMCCIL@HH?3mm?3ss?$AA@ 1001ae40 LIBCMT:nlsdata2.obj + 0002:00000e4c ??_C@_0BE@CKGJFCPC@dddd?0?5MMMM?5dd?0?5yyyy?$AA@ 1001ae4c LIBCMT:nlsdata2.obj + 0002:00000e60 ??_C@_08BPBNCDIB@MM?1dd?1yy?$AA@ 1001ae60 LIBCMT:nlsdata2.obj + 0002:00000e6c ??_C@_02CJNFDJBF@PM?$AA@ 1001ae6c LIBCMT:nlsdata2.obj + 0002:00000e70 ??_C@_02DEDBPAFC@AM?$AA@ 1001ae70 LIBCMT:nlsdata2.obj + 0002:00000e74 ??_C@_08EDHMEBNP@December?$AA@ 1001ae74 LIBCMT:nlsdata2.obj + 0002:00000e80 ??_C@_08HCHEGEOA@November?$AA@ 1001ae80 LIBCMT:nlsdata2.obj + 0002:00000e8c ??_C@_07JJNFCEND@October?$AA@ 1001ae8c LIBCMT:nlsdata2.obj + 0002:00000e94 ??_C@_09BHHEALKD@September?$AA@ 1001ae94 LIBCMT:nlsdata2.obj + 0002:00000ea0 ??_C@_06LBBHFDDG@August?$AA@ 1001aea0 LIBCMT:nlsdata2.obj + 0002:00000ea8 ??_C@_04MIEPOIFP@July?$AA@ 1001aea8 LIBCMT:nlsdata2.obj + 0002:00000eb0 ??_C@_04CNLMGBGM@June?$AA@ 1001aeb0 LIBCMT:nlsdata2.obj + 0002:00000eb8 ??_C@_05DMJDNLEJ@April?$AA@ 1001aeb8 LIBCMT:nlsdata2.obj + 0002:00000ec0 ??_C@_05HPCKOFNC@March?$AA@ 1001aec0 LIBCMT:nlsdata2.obj + 0002:00000ec8 ??_C@_08GNJGEPFN@February?$AA@ 1001aec8 LIBCMT:nlsdata2.obj + 0002:00000ed4 ??_C@_07CGJPFGJA@January?$AA@ 1001aed4 LIBCMT:nlsdata2.obj + 0002:00000edc ??_C@_03MKABNOCG@Dec?$AA@ 1001aedc LIBCMT:nlsdata2.obj + 0002:00000ee0 ??_C@_03JPJOFNIA@Nov?$AA@ 1001aee0 LIBCMT:nlsdata2.obj + 0002:00000ee4 ??_C@_03BMAOKBAD@Oct?$AA@ 1001aee4 LIBCMT:nlsdata2.obj + 0002:00000ee8 ??_C@_03GGCAPAJC@Sep?$AA@ 1001aee8 LIBCMT:nlsdata2.obj + 0002:00000eec ??_C@_03IFJFEIGA@Aug?$AA@ 1001aeec LIBCMT:nlsdata2.obj + 0002:00000ef0 ??_C@_03LBGABGKK@Jul?$AA@ 1001aef0 LIBCMT:nlsdata2.obj + 0002:00000ef4 ??_C@_03IDFGHECI@Jun?$AA@ 1001aef4 LIBCMT:nlsdata2.obj + 0002:00000ef8 ??_C@_03CNMDKL@May?$AA@ 1001aef8 LIBCMT:nlsdata2.obj + 0002:00000efc ??_C@_03LEOLGMJP@Apr?$AA@ 1001aefc LIBCMT:nlsdata2.obj + 0002:00000f00 ??_C@_03ODNJBKGA@Mar?$AA@ 1001af00 LIBCMT:nlsdata2.obj + 0002:00000f04 ??_C@_03HJBDCHOM@Feb?$AA@ 1001af04 LIBCMT:nlsdata2.obj + 0002:00000f08 ??_C@_03JIHJHPIE@Jan?$AA@ 1001af08 LIBCMT:nlsdata2.obj + 0002:00000f0c ??_C@_08INBOOONO@Saturday?$AA@ 1001af0c LIBCMT:nlsdata2.obj + 0002:00000f18 ??_C@_06JECMNKMI@Friday?$AA@ 1001af18 LIBCMT:nlsdata2.obj + 0002:00000f20 ??_C@_08HACCIKIA@Thursday?$AA@ 1001af20 LIBCMT:nlsdata2.obj + 0002:00000f2c ??_C@_09DLIGFAKA@Wednesday?$AA@ 1001af2c LIBCMT:nlsdata2.obj + 0002:00000f38 ??_C@_07BAAGCFCM@Tuesday?$AA@ 1001af38 LIBCMT:nlsdata2.obj + 0002:00000f40 ??_C@_06JLEDEDGH@Monday?$AA@ 1001af40 LIBCMT:nlsdata2.obj + 0002:00000f48 ??_C@_06OOPIFAJ@Sunday?$AA@ 1001af48 LIBCMT:nlsdata2.obj + 0002:00000f50 ??_C@_03FEFJNEK@Sat?$AA@ 1001af50 LIBCMT:nlsdata2.obj + 0002:00000f54 ??_C@_03IDIOELNC@Fri?$AA@ 1001af54 LIBCMT:nlsdata2.obj + 0002:00000f58 ??_C@_03IOFIKPDN@Thu?$AA@ 1001af58 LIBCMT:nlsdata2.obj + 0002:00000f5c ??_C@_03MHOMLAJA@Wed?$AA@ 1001af5c LIBCMT:nlsdata2.obj + 0002:00000f60 ??_C@_03NAGEINEP@Tue?$AA@ 1001af60 LIBCMT:nlsdata2.obj + 0002:00000f64 ??_C@_03PDAGKDH@Mon?$AA@ 1001af64 LIBCMT:nlsdata2.obj + 0002:00000f68 ??_C@_03KOEHGMDN@Sun?$AA@ 1001af68 LIBCMT:nlsdata2.obj + 0002:00000f6c ??_C@_1BK@DBDEIDLH@?$AAK?$AAE?$AAR?$AAN?$AAE?$AAL?$AA3?$AA2?$AA?4?$AAD?$AAL?$AAL?$AA?$AA@ 1001af6c LIBCMT:tidtable.obj + 0002:00000f88 ??_C@_07PEJMOBNF@FlsFree?$AA@ 1001af88 LIBCMT:tidtable.obj + 0002:00000f90 ??_C@_0M@JCPCPOEF@FlsSetValue?$AA@ 1001af90 LIBCMT:tidtable.obj + 0002:00000f9c ??_C@_0M@GDNOONDI@FlsGetValue?$AA@ 1001af9c LIBCMT:tidtable.obj + 0002:00000fa8 ??_C@_08KNHFBNJ@FlsAlloc?$AA@ 1001afa8 LIBCMT:tidtable.obj + 0002:00000fb4 ??_C@_0BG@KLEAJEFJ@Illegal?5byte?5sequence?$AA@ 1001afb4 LIBCMT:syserr.obj + 0002:00000fcc ??_C@_0BE@ICMCHPHH@Directory?5not?5empty?$AA@ 1001afcc LIBCMT:syserr.obj + 0002:00000fe0 ??_C@_0BJ@IHEHINLI@Function?5not?5implemented?$AA@ 1001afe0 LIBCMT:syserr.obj + 0002:00000ffc ??_C@_0BD@CLHBCGPB@No?5locks?5available?$AA@ 1001affc LIBCMT:syserr.obj + 0002:00001010 ??_C@_0BC@BEDIHIDK@Filename?5too?5long?$AA@ 1001b010 LIBCMT:syserr.obj + 0002:00001024 ??_C@_0BK@JAEBMJJM@Resource?5deadlock?5avoided?$AA@ 1001b024 LIBCMT:syserr.obj + 0002:00001040 ??_C@_0BB@FCBJFCAJ@Result?5too?5large?$AA@ 1001b040 LIBCMT:syserr.obj + 0002:00001054 ??_C@_0N@MMJPGLJK@Domain?5error?$AA@ 1001b054 LIBCMT:syserr.obj + 0002:00001064 ??_C@_0M@LHEPIIOM@Broken?5pipe?$AA@ 1001b064 LIBCMT:syserr.obj + 0002:00001070 ??_C@_0P@PKCJJLLM@Too?5many?5links?$AA@ 1001b070 LIBCMT:syserr.obj + 0002:00001080 ??_C@_0BG@DDBFNKBH@Read?9only?5file?5system?$AA@ 1001b080 LIBCMT:syserr.obj + 0002:00001098 ??_C@_0N@FEHLOILP@Invalid?5seek?$AA@ 1001b098 LIBCMT:syserr.obj + 0002:000010a8 ??_C@_0BI@FEALHKLD@No?5space?5left?5on?5device?$AA@ 1001b0a8 LIBCMT:syserr.obj + 0002:000010c0 ??_C@_0P@LFMMIPAE@File?5too?5large?$AA@ 1001b0c0 LIBCMT:syserr.obj + 0002:000010d0 ??_C@_0CE@ONOKNLPF@Inappropriate?5I?1O?5control?5operat@ 1001b0d0 LIBCMT:syserr.obj + 0002:000010f4 ??_C@_0BE@INBJMKGG@Too?5many?5open?5files?$AA@ 1001b0f4 LIBCMT:syserr.obj + 0002:00001108 ??_C@_0BO@IIFBODJE@Too?5many?5open?5files?5in?5system?$AA@ 1001b108 LIBCMT:syserr.obj + 0002:00001128 ??_C@_0BB@HMGGCEBG@Invalid?5argument?$AA@ 1001b128 LIBCMT:syserr.obj + 0002:0000113c ??_C@_0P@NDHGCGKE@Is?5a?5directory?$AA@ 1001b13c LIBCMT:syserr.obj + 0002:0000114c ??_C@_0BA@CJBACOOL@Not?5a?5directory?$AA@ 1001b14c LIBCMT:syserr.obj + 0002:0000115c ??_C@_0P@NLEIANHE@No?5such?5device?$AA@ 1001b15c LIBCMT:syserr.obj + 0002:0000116c ??_C@_0O@OAMDNOCP@Improper?5link?$AA@ 1001b16c LIBCMT:syserr.obj + 0002:0000117c ??_C@_0M@NAAJNNGH@File?5exists?$AA@ 1001b17c LIBCMT:syserr.obj + 0002:00001188 ??_C@_0BA@BIBLIOEK@Resource?5device?$AA@ 1001b188 LIBCMT:syserr.obj + 0002:00001198 ??_C@_0O@NIPGCINC@Unknown?5error?$AA@ 1001b198 LIBCMT:syserr.obj + 0002:000011a8 ??_C@_0M@LOEHLCJD@Bad?5address?$AA@ 1001b1a8 LIBCMT:syserr.obj + 0002:000011b4 ??_C@_0BC@HFNFNKAI@Permission?5denied?$AA@ 1001b1b4 LIBCMT:syserr.obj + 0002:000011c8 ??_C@_0BB@IMDKMPFB@Not?5enough?5space?$AA@ 1001b1c8 LIBCMT:syserr.obj + 0002:000011dc ??_C@_0CB@EPFKGNAK@Resource?5temporarily?5unavailable@ 1001b1dc LIBCMT:syserr.obj + 0002:00001200 ??_C@_0BD@LOHELEP@No?5child?5processes?$AA@ 1001b200 LIBCMT:syserr.obj + 0002:00001214 ??_C@_0BE@NFGDDCEF@Bad?5file?5descriptor?$AA@ 1001b214 LIBCMT:syserr.obj + 0002:00001228 ??_C@_0BC@HKPNECK@Exec?5format?5error?$AA@ 1001b228 LIBCMT:syserr.obj + 0002:0000123c ??_C@_0BC@MFFGCDFL@Arg?5list?5too?5long?$AA@ 1001b23c LIBCMT:syserr.obj + 0002:00001250 ??_C@_0BK@DPKMCKJ@No?5such?5device?5or?5address?$AA@ 1001b250 LIBCMT:syserr.obj + 0002:0000126c ??_C@_0BD@KKNFOBBD@Input?1output?5error?$AA@ 1001b26c LIBCMT:syserr.obj + 0002:00001280 ??_C@_0BK@FJBOAFDK@Interrupted?5function?5call?$AA@ 1001b280 LIBCMT:syserr.obj + 0002:0000129c ??_C@_0BA@FKIAIBGA@No?5such?5process?$AA@ 1001b29c LIBCMT:syserr.obj + 0002:000012ac ??_C@_0BK@FMDHKPNF@No?5such?5file?5or?5directory?$AA@ 1001b2ac LIBCMT:syserr.obj + 0002:000012c8 ??_C@_0BI@BJFCGOHL@Operation?5not?5permitted?$AA@ 1001b2c8 LIBCMT:syserr.obj + 0002:000012e0 ??_C@_08INEPGKHH@No?5error?$AA@ 1001b2e0 LIBCMT:syserr.obj + 0002:00001310 __XcptActTab 1001b310 LIBCMT:winxfltr.obj + 0002:000013a0 __First_FPE_Indx 1001b3a0 LIBCMT:winxfltr.obj + 0002:000013a4 __Num_FPE 1001b3a4 LIBCMT:winxfltr.obj + 0002:000013a8 __XcptActTabSize 1001b3a8 LIBCMT:winxfltr.obj + 0002:000013ac __XcptActTabCount 1001b3ac LIBCMT:winxfltr.obj + 0002:000013b0 ??_C@_0BI@DFKBFLJE@GetProcessWindowStation?$AA@ 1001b3b0 LIBCMT:crtmboxw.obj + 0002:000013c8 ??_C@_0BK@DEKFELLI@GetUserObjectInformationW?$AA@ 1001b3c8 LIBCMT:crtmboxw.obj + 0002:000013e4 ??_C@_0BD@HHGDFDBJ@GetLastActivePopup?$AA@ 1001b3e4 LIBCMT:crtmboxw.obj + 0002:000013f8 ??_C@_0BA@HNOPNCHB@GetActiveWindow?$AA@ 1001b3f8 LIBCMT:crtmboxw.obj + 0002:00001408 ??_C@_0M@DLDCCGNP@MessageBoxW?$AA@ 1001b408 LIBCMT:crtmboxw.obj + 0002:00001414 ??_C@_1BG@GOEBHBDC@?$AAU?$AAS?$AAE?$AAR?$AA3?$AA2?$AA?4?$AAD?$AAL?$AAL?$AA?$AA@ 1001b414 LIBCMT:crtmboxw.obj + 0002:00001430 ___newctype 1001b430 LIBCMT:ctype.obj + 0002:00001730 __wctype 1001b730 LIBCMT:ctype.obj + 0002:00001938 ___newclmap 1001b938 LIBCMT:ctype.obj + 0002:00001ab8 ___newcumap 1001bab8 LIBCMT:ctype.obj + 0002:00001c40 ??_C@_1BA@BALFACEM@?$AAC?$AAO?$AAN?$AAO?$AAU?$AAT?$AA$?$AA?$AA@ 1001bc40 LIBCMT:initcon.obj + 0002:00001c50 ___lookuptable_s 1001bc50 LIBCMT:outputs.obj + 0002:00001d30 ??_C@_05IAIEPMAK@1?42?48?$AA@ 1001bd30 compress.obj + 0002:00001d38 _z_errmsg 1001bd38 zutil.obj + 0002:00001d60 _zip_copyright 1001bd60 zip.obj + 0002:00001db0 _unz_copyright 1001bdb0 unzip.obj + 0002:00002450 __dist_code 1001c450 trees.obj + 0002:00002650 __length_code 1001c650 trees.obj + 0002:00002840 _inflate_copyright 1001c840 inftrees.obj + 0002:00003ac0 _deflate_copyright 1001dac0 deflate.obj + 0002:00005b88 ??_C@_02DKCKIIND@?$CFs?$AA@ 1001fb88 gzlib.obj + 0002:00005b8c ??_C@_07EBNKNFJN@?$DMfd?3?$CFd?$DO?$AA@ 1001fb8c gzlib.obj + 0002:00005b94 ??_C@_0O@BNNCBLEN@out?5of?5memory?$AA@ 1001fb94 gzlib.obj + 0002:00005ba2 ??_C@_00CNPNBAHC@?$AA@ 1001fba2 gzlib.obj + 0002:00005ba4 ??_C@_02LMMGGCAJ@?3?5?$AA@ 1001fba4 gzlib.obj + 0002:00005ba8 ??_C@_06DIJPEION@?$CFs?$CFs?$CFs?$AA@ 1001fba8 gzlib.obj + 0002:00005bb0 ??_C@_0BH@CFIIDOJD@unexpected?5end?5of?5file?$AA@ 1001fbb0 gzread.obj + 0002:00005bc8 ??_C@_0CH@CPOLIEKA@internal?5error?3?5inflate?5stream?5c@ 1001fbc8 gzread.obj + 0002:00005bf0 ??_C@_0BG@HCKBMIHF@compressed?5data?5error?$AA@ 1001fbf0 gzread.obj + 0002:00005c08 ??_C@_0CF@MLPJFDMM@requested?5length?5does?5not?5fit?5in@ 1001fc08 gzread.obj + 0002:00005c30 ??_C@_0BP@IIKIGMCC@out?5of?5room?5to?5push?5characters?$AA@ 1001fc30 gzread.obj + 0002:00005c50 ??_C@_0CH@DEEGAHIB@internal?5error?3?5deflate?5stream?5c@ 1001fc50 gzwrite.obj + 0002:00005c78 ??_C@_0BD@PJCBIDD@invalid?5block?5type?$AA@ 1001fc78 infback.obj + 0002:00005c8c ??_C@_0BN@LGAADGOK@invalid?5stored?5block?5lengths?$AA@ 1001fc8c infback.obj + 0002:00005cac ??_C@_0CE@GMIGFPBB@too?5many?5length?5or?5distance?5symb@ 1001fcac infback.obj + 0002:00005cd0 ??_C@_0BJ@HDEPPGOH@invalid?5code?5lengths?5set?$AA@ 1001fcd0 infback.obj + 0002:00005cec ??_C@_0BK@BMMPFBBH@invalid?5bit?5length?5repeat?$AA@ 1001fcec infback.obj + 0002:00005d08 ??_C@_0CF@DGDMADCD@invalid?5code?5?9?9?5missing?5end?9of?9b@ 1001fd08 infback.obj + 0002:00005d30 ??_C@_0BM@IIMGAINC@invalid?5literal?1lengths?5set?$AA@ 1001fd30 infback.obj + 0002:00005d4c ??_C@_0BG@GMDFCBGP@invalid?5distances?5set?$AA@ 1001fd4c infback.obj + 0002:00005d64 ??_C@_0BM@FFFLPBBC@invalid?5literal?1length?5code?$AA@ 1001fd64 infback.obj + 0002:00005d80 ??_C@_0BG@LBKINIKP@invalid?5distance?5code?$AA@ 1001fd80 infback.obj + 0002:00005d98 ??_C@_0BO@ECPMAOGG@invalid?5distance?5too?5far?5back?$AA@ 1001fd98 infback.obj + 0002:00005db8 ??_C@_0BH@LIBMMIGA@incorrect?5header?5check?$AA@ 1001fdb8 inflate.obj + 0002:00005dd0 ??_C@_0BL@IHKGDAEE@unknown?5compression?5method?$AA@ 1001fdd0 inflate.obj + 0002:00005dec ??_C@_0BE@EMOGCLGO@invalid?5window?5size?$AA@ 1001fdec inflate.obj + 0002:00005e00 ??_C@_0BJ@BLBBCOMO@unknown?5header?5flags?5set?$AA@ 1001fe00 inflate.obj + 0002:00005e1c ??_C@_0BE@GONKLEPM@header?5crc?5mismatch?$AA@ 1001fe1c inflate.obj + 0002:00005e30 ??_C@_0BF@MEIGEHBE@incorrect?5data?5check?$AA@ 1001fe30 inflate.obj + 0002:00005e48 ??_C@_0BH@FGKKJGOC@incorrect?5length?5check?$AA@ 1001fe48 inflate.obj + 0002:00005e60 ??_C@_02JDPG@rb?$AA@ 1001fe60 ioapi.obj + 0002:00005e64 ??_C@_03HMFOOINA@r?$CLb?$AA@ 1001fe64 ioapi.obj + 0002:00005e68 ??_C@_02GMLFBBN@wb?$AA@ 1001fe68 ioapi.obj + 0002:00005e6c ??_C@_01JOAMLHOP@?9?$AA@ 1001fe6c zip.obj + 0002:00005e70 ??_C@_0BF@CJFPCCEG@incompatible?5version?$AA@ 1001fe70 zutil.obj + 0002:00005e88 ??_C@_0N@DFPGLBGC@buffer?5error?$AA@ 1001fe88 zutil.obj + 0002:00005e98 ??_C@_0BE@OGGJBMCE@insufficient?5memory?$AA@ 1001fe98 zutil.obj + 0002:00005eac ??_C@_0L@HAHMBNLP@data?5error?$AA@ 1001feac zutil.obj + 0002:00005eb8 ??_C@_0N@MKKNPMJD@stream?5error?$AA@ 1001feb8 zutil.obj + 0002:00005ec8 ??_C@_0L@KIJFAKBJ@file?5error?$AA@ 1001fec8 zutil.obj + 0002:00005ed4 ??_C@_0L@FNAOCBOG@stream?5end?$AA@ 1001fed4 zutil.obj + 0002:00005ee0 ??_C@_0BA@MOKMMFOD@need?5dictionary?$AA@ 1001fee0 zutil.obj + 0002:00005ef0 ___rtc_iaa 1001fef0 LIBCMT:_initsect_.obj + 0002:00005ef4 ___rtc_izz 1001fef4 LIBCMT:_initsect_.obj + 0002:00005ef8 ___rtc_taa 1001fef8 LIBCMT:_initsect_.obj + 0002:00005efc ___rtc_tzz 1001fefc LIBCMT:_initsect_.obj + 0002:0000631c __IMPORT_DESCRIPTOR_KERNEL32 1002031c kernel32:KERNEL32.dll + 0002:00006330 __NULL_IMPORT_DESCRIPTOR 10020330 kernel32:KERNEL32.dll + 0003:00000180 ___badioinfo 10022180 LIBCMT:ioinit.obj + 0003:000001c0 __lookuptrailbytes 100221c0 LIBCMT:read.obj + 0003:000002c0 ___nullstring 100222c0 LIBCMT:output.obj + 0003:000002c4 ___wnullstring 100222c4 LIBCMT:output.obj + 0003:000002c8 ___initialmbcinfo 100222c8 LIBCMT:mbctype.obj + 0003:000004e8 __mbctype 100224e8 LIBCMT:mbctype.obj + 0003:000005f0 __mbcasemap 100225f0 LIBCMT:mbctype.obj + 0003:000006f0 ___ptmbcinfo 100226f0 LIBCMT:mbctype.obj + 0003:000007e8 ___globallocalestatus 100227e8 LIBCMT:glstatus.obj + 0003:000007ec ___clocalestr 100227ec LIBCMT:nlsdata2.obj + 0003:000007f0 ___lc_time_c 100227f0 LIBCMT:nlsdata2.obj + 0003:00000958 ___initiallocinfo 10022958 LIBCMT:nlsdata2.obj + 0003:00000a30 ___ptlocinfo 10022a30 LIBCMT:nlsdata2.obj + 0003:00000a34 ___flsindex 10022a34 LIBCMT:tidtable.obj + 0003:00000a38 ___getvalueindex 10022a38 LIBCMT:tidtable.obj + 0003:00000a3c ___security_cookie 10022a3c LIBCMT:gs_cookie.obj + 0003:00000a40 ___security_cookie_complement 10022a40 LIBCMT:gs_cookie.obj + 0003:00000a48 __sys_errlist 10022a48 LIBCMT:syserr.obj + 0003:00000af8 __sys_nerr 10022af8 LIBCMT:syserr.obj + 0003:00000b00 __iob 10022b00 LIBCMT:_file.obj + 0003:00000ea0 __cfltcvt_tab 10022ea0 LIBCMT:cmiscdat.obj + 0003:00000ed0 ___lconv_static_decimal 10022ed0 LIBCMT:lconv.obj + 0003:00000ed4 ___lconv_static_W_decimal 10022ed4 LIBCMT:lconv.obj + 0003:00000ed8 ___lconv_c 10022ed8 LIBCMT:lconv.obj + 0003:00000f28 ___lconv 10022f28 LIBCMT:lconv.obj + 0003:00000f2c __pctype 10022f2c LIBCMT:ctype.obj + 0003:00000f30 __pwctype 10022f30 LIBCMT:ctype.obj + 0003:00000f40 __NLG_Destination 10022f40 LIBCMT:exsup.obj + 0003:00000f50 __confh 10022f50 LIBCMT:initcon.obj + 0003:00000f54 ___abort_behavior 10022f54 LIBCMT:abort.obj + 0003:00000f64 ___mb_cur_max 10022f64 LIBCMT:nlsdata1.obj + 0003:00000f68 ___decimal_point 10022f68 LIBCMT:nlsdata1.obj + 0003:00000f6c ___decimal_point_length 10022f6c LIBCMT:nlsdata1.obj + 0003:00000fc4 __aenvptr 10022fc4 LIBCMT:dllcrt0.obj + 0003:00000fc8 __wenvptr 10022fc8 LIBCMT:dllcrt0.obj + 0003:00000fcc ___error_mode 10022fcc LIBCMT:dllcrt0.obj + 0003:00000fd0 ___app_type 10022fd0 LIBCMT:dllcrt0.obj + 0003:00000fd4 ___pInvalidArgHandler 10022fd4 LIBCMT:invarg.obj + 0003:00000fd8 __umaskval 10022fd8 LIBCMT:crt0dat.obj + 0003:00000fdc ___argc 10022fdc LIBCMT:crt0dat.obj + 0003:00000fe0 ___argv 10022fe0 LIBCMT:crt0dat.obj + 0003:00000fe4 ___wargv 10022fe4 LIBCMT:crt0dat.obj + 0003:00000fe8 __environ 10022fe8 LIBCMT:crt0dat.obj + 0003:00000fec ___initenv 10022fec LIBCMT:crt0dat.obj + 0003:00000ff0 __wenviron 10022ff0 LIBCMT:crt0dat.obj + 0003:00000ff4 ___winitenv 10022ff4 LIBCMT:crt0dat.obj + 0003:00000ff8 __pgmptr 10022ff8 LIBCMT:crt0dat.obj + 0003:00000ffc __wpgmptr 10022ffc LIBCMT:crt0dat.obj + 0003:00001000 __exitflag 10023000 LIBCMT:crt0dat.obj + 0003:00001004 __C_Termination_Done 10023004 LIBCMT:crt0dat.obj + 0003:00001008 __C_Exit_Done 10023008 LIBCMT:crt0dat.obj + 0003:0000100c __crtheap 1002300c LIBCMT:heapinit.obj + 0003:00001638 ?_pnhHeap@@3P6AHI@ZA 10023638 LIBCMT:handler.obj + 0003:0000163c __newmode 1002363c LIBCMT:_newmode.obj + 0003:00001644 ___mbulinfo 10023644 LIBCMT:mbctype.obj + 0003:00001650 ___mbcodepage 10023650 LIBCMT:mbctype.obj + 0003:00001654 ___ismbcodepage 10023654 LIBCMT:mbctype.obj + 0003:00001658 ___mblcid 10023658 LIBCMT:mbctype.obj + 0003:0000165c _gpFlsAlloc 1002365c LIBCMT:tidtable.obj + 0003:00001660 _gpFlsGetValue 10023660 LIBCMT:tidtable.obj + 0003:00001664 _gpFlsSetValue 10023664 LIBCMT:tidtable.obj + 0003:00001668 _gpFlsFree 10023668 LIBCMT:tidtable.obj + 0003:0000166c __maxwait 1002366c LIBCMT:crtheap.obj + 0003:00001670 __cflush 10023670 LIBCMT:_file.obj + 0003:000018d0 ?__pInconsistency@@3P6AXXZA 100238d0 LIBCMT:hooks.obj + 0003:000018ec ___pPurecall 100238ec LIBCMT:inithelp.obj + 0003:000018f0 __fmode 100238f0 LIBCMT:txtmode.obj + 0003:0000190c ___lconv_static_null 1002390c LIBCMT:lconv.obj + 0003:00001910 ___lconv_static_W_null 10023910 LIBCMT:lconv.obj + 0003:00001c3c __commode 10023c3c LIBCMT:ncommode.obj + 0003:00001c40 __stdbuf 10023c40 LIBCMT:_sftbuf.obj + 0003:00001c48 ___locale_changed 10023c48 LIBCMT:setlocal.obj + 0003:00001c50 ___sse2_available 10023c50 <common> + 0003:00001c54 __debugger_hook_dummy 10023c54 <common> + 0003:00001c58 ___piob 10023c58 <common> + 0003:00001c60 __bufin 10023c60 <common> + 0003:00002c60 __nstream 10024c60 <common> + 0003:00002c64 ___env_initialized 10024c64 <common> + 0003:00002c68 ___onexitend 10024c68 <common> + 0003:00002c6c ___onexitbegin 10024c6c <common> + 0003:00002c70 ___mbctype_initialized 10024c70 <common> + 0003:00002c74 __FPinit 10024c74 <common> + 0003:00002c78 ___dyn_tls_init_callback 10024c78 <common> + 0003:00002c7c __pDestructExceptionObject 10024c7c <common> + 0003:00002c80 __nhandle 10024c80 <common> + 0003:00002ca0 ___pioinfo 10024ca0 <common> + 0003:00002da0 __acmdln 10024da0 <common> + + entry point at 0001:0001036c + + Static symbols + + 0001:00000270 _adler32_combine_ 10001270 f CIL library: CIL module + 0001:00000470 _crc32_little 10001470 f CIL library: CIL module + 0001:00000730 _gf2_matrix_times 10001730 f CIL library: CIL module + 0001:00000750 _gf2_matrix_square 10001750 f CIL library: CIL module + 0001:00000780 _crc32_combine_ 10001780 f CIL library: CIL module + 0001:00001090 _putShortMSB 10002090 f CIL library: CIL module + 0001:000010c0 _flush_pending 100020c0 f CIL library: CIL module + 0001:00001bf0 _read_buf 10002bf0 f CIL library: CIL module + 0001:00001c60 _lm_init 10002c60 f CIL library: CIL module + 0001:00001d00 _fill_window 10002d00 f CIL library: CIL module + 0001:00001ed0 _deflate_stored 10002ed0 f CIL library: CIL module + 0001:00002060 _deflate_fast 10003060 f CIL library: CIL module + 0001:00002390 _deflate_slow 10003390 f CIL library: CIL module + 0001:00002790 _deflate_rle 10003790 f CIL library: CIL module + 0001:00002a40 _deflate_huff 10003a40 f CIL library: CIL module + 0001:00002bd0 _gz_reset 10003bd0 f CIL library: CIL module + 0001:00002c10 _gz_open 10003c10 f CIL library: CIL module + 0001:00003470 _gz_load 10004470 f CIL library: CIL module + 0001:000034e0 _gz_avail 100044e0 f CIL library: CIL module + 0001:00003550 _gz_look 10004550 f CIL library: CIL module + 0001:000036c0 _gz_decomp 100046c0 f CIL library: CIL module + 0001:000037c0 _gz_fetch 100047c0 f CIL library: CIL module + 0001:00003840 _gz_skip 10004840 f CIL library: CIL module + 0001:00003d70 _gz_init 10004d70 f CIL library: CIL module + 0001:00003e40 _gz_comp 10004e40 f CIL library: CIL module + 0001:00003f70 _gz_zero 10004f70 f CIL library: CIL module + 0001:000045f0 _fixedtables 100055f0 f CIL library: CIL module + 0001:000055e0 _fixedtables 100065e0 f CIL library: CIL module + 0001:00005600 _updatewindow 10006600 f CIL library: CIL module + 0001:00006da0 _syncsearch 10007da0 f CIL library: CIL module + 0001:00007610 _fopen64_file_func 10008610 f CIL library: CIL module + 0001:00007660 _fread_file_func 10008660 f CIL library: CIL module + 0001:00007680 _fwrite_file_func 10008680 f CIL library: CIL module + 0001:000076a0 _ftell64_file_func 100086a0 f CIL library: CIL module + 0001:000076c0 _fseek64_file_func 100086c0 f CIL library: CIL module + 0001:00007710 _fclose_file_func 10008710 f CIL library: CIL module + 0001:00007730 _ferror_file_func 10008730 f CIL library: CIL module + 0001:00007790 _win32_translate_open_mode 10008790 f CIL library: CIL module + 0001:00007800 _win32_build_iowin 10008800 f CIL library: CIL module + 0001:000079a0 _MySetFilePointerEx 100089a0 f CIL library: CIL module + 0001:00007cc0 _init_block 10008cc0 f CIL library: CIL module + 0001:00007d40 _pqdownheap 10008d40 f CIL library: CIL module + 0001:00007e20 _gen_bitlen 10008e20 f CIL library: CIL module + 0001:00008020 _gen_codes 10009020 f CIL library: CIL module + 0001:00008080 _build_tree 10009080 f CIL library: CIL module + 0001:00008280 _scan_tree 10009280 f CIL library: CIL module + 0001:00008360 _send_tree 10009360 f CIL library: CIL module + 0001:000088e0 _build_bl_tree 100098e0 f CIL library: CIL module + 0001:000089b0 _send_all_trees 100099b0 f CIL library: CIL module + 0001:00008fa0 _compress_block 10009fa0 f CIL library: CIL module + 0001:00009380 _detect_data_type 1000a380 f CIL library: CIL module + 0001:000093f0 _bi_reverse 1000a3f0 f CIL library: CIL module + 0001:00009410 _bi_flush 1000a410 f CIL library: CIL module + 0001:00009490 _bi_windup 1000a490 f CIL library: CIL module + 0001:000094f0 _copy_block 1000a4f0 f CIL library: CIL module + 0001:00009610 _unz64local_getShort 1000a610 f CIL library: CIL module + 0001:00009670 _unz64local_getLong 1000a670 f CIL library: CIL module + 0001:00009700 _unz64local_getLong64 1000a700 f CIL library: CIL module + 0001:00009840 _strcmpcasenosensitive_internal 1000a840 f CIL library: CIL module + 0001:000098e0 _zip64local_SearchCentralDir 1000a8e0 f CIL library: CIL module + 0001:000098e0 _unz64local_SearchCentralDir 1000a8e0 f CIL library: CIL module + 0001:00009a90 _unz64local_SearchCentralDir64 1000aa90 f CIL library: CIL module + 0001:00009d20 _unzOpenInternal 1000ad20 f CIL library: CIL module + 0001:0000a2d0 _unz64local_DosDateToTmuDate 1000b2d0 f CIL library: CIL module + 0001:0000a350 _unz64local_GetCurrentFileInfoInternal 1000b350 f CIL library: CIL module + 0001:0000ad40 _unz64local_CheckCurrentFileCoherencyHeader 1000bd40 f CIL library: CIL module + 0001:0000b790 _decrypt_byte 1000c790 f CIL library: CIL module + 0001:0000b7b0 _update_keys 1000c7b0 f CIL library: CIL module + 0001:0000b7f0 _init_keys 1000c7f0 f CIL library: CIL module + 0001:0000b830 _crypthead 1000c830 f CIL library: CIL module + 0001:0000b940 _allocate_new_datablock 1000c940 f CIL library: CIL module + 0001:0000b970 _free_datablock 1000c970 f CIL library: CIL module + 0001:0000b990 _init_linkedlist 1000c990 f CIL library: CIL module + 0001:0000b9a0 _free_linkedlist 1000c9a0 f CIL library: CIL module + 0001:0000b9c0 _add_data_in_datablock 1000c9c0 f CIL library: CIL module + 0001:0000ba70 _zip64local_putValue 1000ca70 f CIL library: CIL module + 0001:0000bad0 _zip64local_putValue_inmemory 1000cad0 f CIL library: CIL module + 0001:0000bb10 _zip64local_TmzDateToDosDate 1000cb10 f CIL library: CIL module + 0001:0000bb60 _unz64local_getByte 1000cb60 f CIL library: CIL module + 0001:0000bb60 _zip64local_getByte 1000cb60 f CIL library: CIL module + 0001:0000bba0 _zip64local_getShort 1000cba0 f CIL library: CIL module + 0001:0000bc00 _zip64local_getLong 1000cc00 f CIL library: CIL module + 0001:0000bc90 _zip64local_getLong64 1000cc90 f CIL library: CIL module + 0001:0000bdd0 _zip64local_SearchCentralDir64 1000cdd0 f CIL library: CIL module + 0001:0000d020 _zip64FlushWriteBuffer 1000e020 f CIL library: CIL module + 0001:0000e772 __tsopen_nolock 1000f772 f LIBCMT:wopen.obj + 0001:00010276 ___DllMainCRTStartup 10011276 f LIBCMT:dllcrt0.obj + 0001:000120cb _doexit 100130cb f LIBCMT:crt0dat.obj + 0001:00012711 _write_char 10013711 f LIBCMT:output.obj + 0001:00012744 _write_string 10013744 f LIBCMT:output.obj + 0001:00013406 ?CPtoLCID@@YAHH@Z 10014406 f LIBCMT:mbctype.obj + 0001:00013435 ?setSBCS@@YAXPAUthreadmbcinfostruct@@@Z 10014435 f LIBCMT:mbctype.obj + 0001:00013499 ?setSBUpLow@@YAXPAUthreadmbcinfostruct@@@Z 10014499 f LIBCMT:mbctype.obj + 0001:000136cd ?getSystemCP@@YAHH@Z 100146cd f LIBCMT:mbctype.obj + 0001:00014720 _flsall 10015720 f LIBCMT:fflush.obj + 0001:00014c60 __unwind_handler4 10015c60 f LIBCMT:exsup4.obj + 0001:00015424 _parse_cmdline 10016424 f LIBCMT:stdargv.obj + 0001:00015ee7 _siglookup 10016ee7 f LIBCMT:winsig.obj + 0001:000160ec __onexit_nolock 100170ec f LIBCMT:onexit.obj + 0001:000168d5 ?__crtLCMapStringA_stat@@YAHPAUlocaleinfo_struct@@KKPBDHPADHHH@Z 100178d5 f LIBCMT:a_map.obj + 0001:00016b02 ?__crtGetStringTypeA_stat@@YAHPAUlocaleinfo_struct@@KPBDHPAGHHH@Z 10017b02 f LIBCMT:a_str.obj + 0001:000174b1 __tsopen_nolock 100184b1 f LIBCMT:open.obj + 0001:00018120 __unwind_handler 10019120 f LIBCMT:exsup.obj + 0001:00018404 ?x_ismbbtype_l@@YAHPAUlocaleinfo_struct@@IHH@Z 10019404 f LIBCMT:ismbbyte.obj diff --git a/builddir/zlib-1.2.8/bin/ZlibStatRelease/vc100.pdb b/builddir/zlib-1.2.8/bin/ZlibStatRelease/vc100.pdb new file mode 100644 index 0000000..7891fdb Binary files /dev/null and b/builddir/zlib-1.2.8/bin/ZlibStatRelease/vc100.pdb differ diff --git a/builddir/zlib-1.2.8/bin/ZlibStatRelease/zlibstat.lib b/builddir/zlib-1.2.8/bin/ZlibStatRelease/zlibstat.lib new file mode 100644 index 0000000..0162623 Binary files /dev/null and b/builddir/zlib-1.2.8/bin/ZlibStatRelease/zlibstat.lib differ diff --git a/builddir/zlib-1.2.8/bin/zlib.exp b/builddir/zlib-1.2.8/bin/zlib.exp new file mode 100644 index 0000000..72033f5 Binary files /dev/null and b/builddir/zlib-1.2.8/bin/zlib.exp differ diff --git a/builddir/zlib-1.2.8/bin/zlib.lib b/builddir/zlib-1.2.8/bin/zlib.lib new file mode 100644 index 0000000..8c6f220 Binary files /dev/null and b/builddir/zlib-1.2.8/bin/zlib.lib differ diff --git a/builddir/zlib-1.2.8/bin/zlib1.dll b/builddir/zlib-1.2.8/bin/zlib1.dll new file mode 100644 index 0000000..d76b64c Binary files /dev/null and b/builddir/zlib-1.2.8/bin/zlib1.dll differ diff --git a/builddir/zlib-1.2.8/include/deflate.h b/builddir/zlib-1.2.8/include/deflate.h new file mode 100644 index 0000000..ce0299e --- /dev/null +++ b/builddir/zlib-1.2.8/include/deflate.h @@ -0,0 +1,346 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2012 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* can only be DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/builddir/zlib-1.2.8/include/gzguts.h b/builddir/zlib-1.2.8/include/gzguts.h new file mode 100644 index 0000000..d87659d --- /dev/null +++ b/builddir/zlib-1.2.8/include/gzguts.h @@ -0,0 +1,209 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include <stdio.h> +#include "zlib.h" +#ifdef STDC +# include <string.h> +# include <stdlib.h> +# include <limits.h> +#endif +#include <fcntl.h> + +#ifdef _WIN32 +# include <stddef.h> +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include <io.h> +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99, yet still not supported by + Microsoft more than a decade later!), _snprintf does not guarantee null + termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include <windows.h> +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include <errno.h> +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/builddir/zlib-1.2.8/include/inffast.h b/builddir/zlib-1.2.8/include/inffast.h new file mode 100644 index 0000000..e5c1aa4 --- /dev/null +++ b/builddir/zlib-1.2.8/include/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/builddir/zlib-1.2.8/include/inffixed.h b/builddir/zlib-1.2.8/include/inffixed.h new file mode 100644 index 0000000..d628327 --- /dev/null +++ b/builddir/zlib-1.2.8/include/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/builddir/zlib-1.2.8/include/inflate.h b/builddir/zlib-1.2.8/include/inflate.h new file mode 100644 index 0000000..95f4986 --- /dev/null +++ b/builddir/zlib-1.2.8/include/inflate.h @@ -0,0 +1,122 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2009 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 10K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/builddir/zlib-1.2.8/include/inftrees.h b/builddir/zlib-1.2.8/include/inftrees.h new file mode 100644 index 0000000..baa53a0 --- /dev/null +++ b/builddir/zlib-1.2.8/include/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/builddir/zlib-1.2.8/include/trees.h b/builddir/zlib-1.2.8/include/trees.h new file mode 100644 index 0000000..d35639d --- /dev/null +++ b/builddir/zlib-1.2.8/include/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/builddir/zlib-1.2.8/include/zconf.h b/builddir/zlib-1.2.8/include/zconf.h new file mode 100644 index 0000000..9ccbb0a --- /dev/null +++ b/builddir/zlib-1.2.8/include/zconf.h @@ -0,0 +1,513 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2013 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H +/* #undef Z_PREFIX */ +/* #undef Z_HAVE_UNISTD_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. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#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 + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#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 + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(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 !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include <limits.h> +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include <sys/types.h> /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include <stdarg.h> /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include <stddef.h> /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include <unixio.h> /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# 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(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# 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/builddir/zlib-1.2.8/include/zlib.h b/builddir/zlib-1.2.8/include/zlib.h new file mode 100644 index 0000000..3e0c767 --- /dev/null +++ b/builddir/zlib-1.2.8/include/zlib.h @@ -0,0 +1,1768 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.8, April 28th, 2013 + + Copyright (C) 1995-2013 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@gzip.org madler@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://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.8" +#define ZLIB_VERNUM 0x1280 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 8 +#define ZLIB_VER_SUBREVISION 0 + +/* + 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, + 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 { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number 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 number of bytes output so far */ + + z_const 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 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* 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 const char * ZEXPORT 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, or + 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 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 accumulate 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. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + 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). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and 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 Z_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 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, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int 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, + Z_BLOCK, or Z_TREES. 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. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + 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 of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + 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 effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 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() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). 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. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip 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 + next_in or next_out was Z_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 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_STRATEGY 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 any parameter is invalid (such as an invalid + method), or 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. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int 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. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. 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 + provided in deflateInit or deflateInit2. 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 (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int 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 Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int 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 Z_NULL). +*/ + +ZEXTERN int 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(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +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, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, 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 zero to request that inflate use the window size in + the zlib header of the compressed stream. + + 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_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int 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 at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. 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 (e.g. dictionary being Z_NULL) 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 ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible 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 Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int 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 Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +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. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + 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 or Z_TREES 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 parameters 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 *, + z_const 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 potentially 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. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() 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_in 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) + */ + +#ifndef Z_SOLO + + /* 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 be modified if + you need special options. +*/ + +ZEXTERN int 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. + + 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 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 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 uncompressed buffer. + + 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. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + /* gzip file access functions */ + +/* + This library 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. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile 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", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + 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. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile 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 (if 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 fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int 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 ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int 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 written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will 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. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int 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 char * ZEXPORT 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. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int 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 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. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int 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 is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t 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 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 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, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT 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. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +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. +*/ + +#endif /* !Z_SOLO */ + + /* 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 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 Z_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. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong 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 Z_NULL, this function returns the required + initial value 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 ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int 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, (int)sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/builddir/zlib-1.2.8/include/zutil.h b/builddir/zlib-1.2.8/include/zutil.h new file mode 100644 index 0000000..24ab06b --- /dev/null +++ b/builddir/zlib-1.2.8/include/zutil.h @@ -0,0 +1,253 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2013 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include <stddef.h> +# endif +# include <string.h> +# include <stdlib.h> +#endif + +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include <alloc.h> +# endif +# else /* MSC or DJGPP */ +# include <malloc.h> +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# if defined(M_I86) && !defined(Z_SOLO) +# include <malloc.h> +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include <unix.h> /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include <stdio.h> + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +#endif /* ZUTIL_H */ diff --git a/builtin/async/game.lua b/builtin/async/game.lua new file mode 100644 index 0000000..6512f07 --- /dev/null +++ b/builtin/async/game.lua @@ -0,0 +1,59 @@ +core.log("info", "Initializing asynchronous environment (game)") + +local function pack2(...) + return {n=select('#', ...), ...} +end + +-- Entrypoint to run async jobs, called by C++ +function core.job_processor(func, params) + local retval = pack2(func(unpack(params, 1, params.n))) + + return retval +end + +-- Import a bunch of individual files from builtin/game/ +local gamepath = core.get_builtin_path() .. "game" .. DIR_DELIM + +dofile(gamepath .. "constants.lua") +dofile(gamepath .. "item_s.lua") +dofile(gamepath .. "misc_s.lua") +dofile(gamepath .. "features.lua") +dofile(gamepath .. "voxelarea.lua") + +-- Transfer of globals +do + local all = assert(core.transferred_globals) + core.transferred_globals = nil + + all.registered_nodes = {} + all.registered_craftitems = {} + all.registered_tools = {} + for k, v in pairs(all.registered_items) do + -- Disable further modification + setmetatable(v, {__newindex = {}}) + -- Reassemble the other tables + if v.type == "node" then + all.registered_nodes[k] = v + elseif v.type == "craftitem" then + all.registered_craftitems[k] = v + elseif v.type == "tool" then + all.registered_tools[k] = v + end + end + + for k, v in pairs(all) do + core[k] = v + end +end + +-- For tables that are indexed by item name: +-- If table[X] does not exist, default to table[core.registered_aliases[X]] +local alias_metatable = { + __index = function(t, name) + return rawget(t, core.registered_aliases[name]) + end +} +setmetatable(core.registered_items, alias_metatable) +setmetatable(core.registered_nodes, alias_metatable) +setmetatable(core.registered_craftitems, alias_metatable) +setmetatable(core.registered_tools, alias_metatable) diff --git a/builtin/async/mainmenu.lua b/builtin/async/mainmenu.lua new file mode 100644 index 0000000..0e9c222 --- /dev/null +++ b/builtin/async/mainmenu.lua @@ -0,0 +1,9 @@ +core.log("info", "Initializing asynchronous environment") + +function core.job_processor(func, serialized_param) + local param = core.deserialize(serialized_param) + + local retval = core.serialize(func(param)) + + return retval or core.serialize(nil) +end diff --git a/builtin/client/chatcommands.lua b/builtin/client/chatcommands.lua new file mode 100644 index 0000000..a563a66 --- /dev/null +++ b/builtin/client/chatcommands.lua @@ -0,0 +1,74 @@ +-- Minetest: builtin/client/chatcommands.lua + +core.register_on_sending_chat_message(function(message) + if message:sub(1,2) == ".." then + return false + end + + local first_char = message:sub(1,1) + if first_char == "/" or first_char == "." then + core.display_chat_message(core.gettext("Issued command: ") .. message) + end + + if first_char ~= "." then + return false + end + + local cmd, param = string.match(message, "^%.([^ ]+) *(.*)") + param = param or "" + + if not cmd then + core.display_chat_message("-!- " .. core.gettext("Empty command.")) + return true + end + + -- Run core.registered_on_chatcommand callbacks. + if core.run_callbacks(core.registered_on_chatcommand, 5, cmd, param) then + return true + end + + local cmd_def = core.registered_chatcommands[cmd] + if cmd_def then + core.set_last_run_mod(cmd_def.mod_origin) + local _, result = cmd_def.func(param) + if result then + core.display_chat_message(result) + end + else + core.display_chat_message("-!- " .. core.gettext("Invalid command: ") .. cmd) + end + + return true +end) + +core.register_chatcommand("list_players", { + description = core.gettext("List online players"), + func = function(param) + local player_names = core.get_player_names() + if not player_names then + return false, core.gettext("This command is disabled by server.") + end + + local players = table.concat(player_names, ", ") + return true, core.gettext("Online players: ") .. players + end +}) + +core.register_chatcommand("disconnect", { + description = core.gettext("Exit to main menu"), + func = function(param) + core.disconnect() + end, +}) + +core.register_chatcommand("clear_chat_queue", { + description = core.gettext("Clear the out chat queue"), + func = function(param) + core.clear_out_chat_queue() + return true, core.gettext("The out chat queue is now empty.") + end, +}) + +function core.run_server_chatcommand(cmd, param) + core.send_chat_message("/" .. cmd .. " " .. param) +end diff --git a/builtin/client/death_formspec.lua b/builtin/client/death_formspec.lua new file mode 100644 index 0000000..c25c799 --- /dev/null +++ b/builtin/client/death_formspec.lua @@ -0,0 +1,15 @@ +-- CSM death formspec. Only used when clientside modding is enabled, otherwise +-- handled by the engine. + +core.register_on_death(function() + local formspec = "size[11,5.5]bgcolor[#320000b4;true]" .. + "label[4.85,1.35;" .. fgettext("You died") .. + "]button_exit[4,3;3,0.5;btn_respawn;".. fgettext("Respawn") .."]" + core.show_formspec("bultin:death", formspec) +end) + +core.register_on_formspec_input(function(formname, fields) + if formname == "bultin:death" then + core.send_respawn() + end +end) diff --git a/builtin/client/init.lua b/builtin/client/init.lua new file mode 100644 index 0000000..3719a90 --- /dev/null +++ b/builtin/client/init.lua @@ -0,0 +1,12 @@ +-- Minetest: builtin/client/init.lua +local scriptpath = core.get_builtin_path() +local clientpath = scriptpath.."client"..DIR_DELIM +local commonpath = scriptpath.."common"..DIR_DELIM + +dofile(clientpath .. "register.lua") +dofile(commonpath .. "after.lua") +dofile(commonpath .. "mod_storage.lua") +dofile(commonpath .. "chatcommands.lua") +dofile(clientpath .. "chatcommands.lua") +dofile(clientpath .. "death_formspec.lua") +dofile(clientpath .. "misc.lua") diff --git a/builtin/client/misc.lua b/builtin/client/misc.lua new file mode 100644 index 0000000..80e0f29 --- /dev/null +++ b/builtin/client/misc.lua @@ -0,0 +1,7 @@ +function core.setting_get_pos(name) + local value = core.settings:get(name) + if not value then + return nil + end + return core.string_to_pos(value) +end diff --git a/builtin/client/register.lua b/builtin/client/register.lua new file mode 100644 index 0000000..61db4a3 --- /dev/null +++ b/builtin/client/register.lua @@ -0,0 +1,83 @@ +core.callback_origins = {} + +local getinfo = debug.getinfo +debug.getinfo = nil + +--- Runs given callbacks. +-- +-- Note: this function is also called from C++ +-- @tparam table callbacks a table with registered callbacks, like `core.registered_on_*` +-- @tparam number mode a RunCallbacksMode, as defined in src/script/common/c_internal.h +-- @param ... arguments for the callback +-- @return depends on mode +function core.run_callbacks(callbacks, mode, ...) + assert(type(callbacks) == "table") + local cb_len = #callbacks + if cb_len == 0 then + if mode == 2 or mode == 3 then + return true + elseif mode == 4 or mode == 5 then + return false + end + end + local ret + for i = 1, cb_len do + local cb_ret = callbacks[i](...) + + if mode == 0 and i == 1 or mode == 1 and i == cb_len then + ret = cb_ret + elseif mode == 2 then + if not cb_ret or i == 1 then + ret = cb_ret + end + elseif mode == 3 then + if cb_ret then + return cb_ret + end + ret = cb_ret + elseif mode == 4 then + if (cb_ret and not ret) or i == 1 then + ret = cb_ret + end + elseif mode == 5 and cb_ret then + return cb_ret + end + end + return ret +end + +-- +-- Callback registration +-- + +local function make_registration() + local t = {} + local registerfunc = function(func) + t[#t + 1] = func + core.callback_origins[func] = { + mod = core.get_current_modname() or "??", + name = getinfo(1, "n").name or "??" + } + --local origin = core.callback_origins[func] + --print(origin.name .. ": " .. origin.mod .. " registering cbk " .. tostring(func)) + end + return t, registerfunc +end + +core.registered_globalsteps, core.register_globalstep = make_registration() +core.registered_on_mods_loaded, core.register_on_mods_loaded = make_registration() +core.registered_on_shutdown, core.register_on_shutdown = make_registration() +core.registered_on_receiving_chat_message, core.register_on_receiving_chat_message = make_registration() +core.registered_on_sending_chat_message, core.register_on_sending_chat_message = make_registration() +core.registered_on_chatcommand, core.register_on_chatcommand = make_registration() +core.registered_on_death, core.register_on_death = make_registration() +core.registered_on_hp_modification, core.register_on_hp_modification = make_registration() +core.registered_on_damage_taken, core.register_on_damage_taken = make_registration() +core.registered_on_formspec_input, core.register_on_formspec_input = make_registration() +core.registered_on_dignode, core.register_on_dignode = make_registration() +core.registered_on_punchnode, core.register_on_punchnode = make_registration() +core.registered_on_placenode, core.register_on_placenode = make_registration() +core.registered_on_item_use, core.register_on_item_use = make_registration() +core.registered_on_modchannel_message, core.register_on_modchannel_message = make_registration() +core.registered_on_modchannel_signal, core.register_on_modchannel_signal = make_registration() +core.registered_on_inventory_open, core.register_on_inventory_open = make_registration() diff --git a/builtin/common/after.lua b/builtin/common/after.lua new file mode 100644 index 0000000..bce2625 --- /dev/null +++ b/builtin/common/after.lua @@ -0,0 +1,50 @@ +local jobs = {} +local time = 0.0 +local time_next = math.huge + +core.register_globalstep(function(dtime) + time = time + dtime + + if time < time_next then + return + end + + time_next = math.huge + + -- Iterate backwards so that we miss any new timers added by + -- a timer callback. + for i = #jobs, 1, -1 do + local job = jobs[i] + if time >= job.expire then + core.set_last_run_mod(job.mod_origin) + job.func(unpack(job.arg)) + local jobs_l = #jobs + jobs[i] = jobs[jobs_l] + jobs[jobs_l] = nil + elseif job.expire < time_next then + time_next = job.expire + end + end +end) + +function core.after(after, func, ...) + assert(tonumber(after) and type(func) == "function", + "Invalid minetest.after invocation") + local expire = time + after + local new_job = { + func = func, + expire = expire, + arg = {...}, + mod_origin = core.get_last_run_mod(), + } + + jobs[#jobs + 1] = new_job + time_next = math.min(time_next, expire) + + return { + cancel = function() + new_job.func = function() end + new_job.args = {} + end + } +end diff --git a/builtin/common/chatcommands.lua b/builtin/common/chatcommands.lua new file mode 100644 index 0000000..7c3da06 --- /dev/null +++ b/builtin/common/chatcommands.lua @@ -0,0 +1,178 @@ +-- Minetest: builtin/common/chatcommands.lua + +-- For server-side translations (if INIT == "game") +-- Otherwise, use core.gettext +local S = core.get_translator("__builtin") + +core.registered_chatcommands = {} + +-- Interpret the parameters of a command, separating options and arguments. +-- Input: command, param +-- command: name of command +-- param: parameters of command +-- Returns: opts, args +-- opts is a string of option letters, or false on error +-- args is an array with the non-option arguments in order, or an error message +-- Example: for this command line: +-- /command a b -cd e f -g +-- the function would receive: +-- a b -cd e f -g +-- and it would return: +-- "cdg", {"a", "b", "e", "f"} +-- Negative numbers are taken as arguments. Long options (--option) are +-- currently rejected as reserved. +local function getopts(command, param) + local opts = "" + local args = {} + for match in param:gmatch("%S+") do + if match:byte(1) == 45 then -- 45 = '-' + local second = match:byte(2) + if second == 45 then + return false, S("Invalid parameters (see /help @1).", command) + elseif second and (second < 48 or second > 57) then -- 48 = '0', 57 = '9' + opts = opts .. match:sub(2) + else + -- numeric, add it to args + args[#args + 1] = match + end + else + args[#args + 1] = match + end + end + return opts, args +end + +function core.register_chatcommand(cmd, def) + def = def or {} + def.params = def.params or "" + def.description = def.description or "" + def.privs = def.privs or {} + def.mod_origin = core.get_current_modname() or "??" + core.registered_chatcommands[cmd] = def +end + +function core.unregister_chatcommand(name) + if core.registered_chatcommands[name] then + core.registered_chatcommands[name] = nil + else + core.log("warning", "Not unregistering chatcommand " ..name.. + " because it doesn't exist.") + end +end + +function core.override_chatcommand(name, redefinition) + local chatcommand = core.registered_chatcommands[name] + assert(chatcommand, "Attempt to override non-existent chatcommand "..name) + for k, v in pairs(redefinition) do + rawset(chatcommand, k, v) + end + core.registered_chatcommands[name] = chatcommand +end + +local function format_help_line(cmd, def) + local cmd_marker = INIT == "client" and "." or "/" + local msg = core.colorize("#00ffff", cmd_marker .. cmd) + if def.params and def.params ~= "" then + msg = msg .. " " .. def.params + end + if def.description and def.description ~= "" then + msg = msg .. ": " .. def.description + end + return msg +end + +local function do_help_cmd(name, param) + local opts, args = getopts("help", param) + if not opts then + return false, args + end + if #args > 1 then + return false, S("Too many arguments, try using just /help <command>") + end + local use_gui = INIT ~= "client" and core.get_player_by_name(name) + use_gui = use_gui and not opts:find("t") + + if #args == 0 and not use_gui then + local cmds = {} + for cmd, def in pairs(core.registered_chatcommands) do + if INIT == "client" or core.check_player_privs(name, def.privs) then + cmds[#cmds + 1] = cmd + end + end + table.sort(cmds) + local msg + if INIT == "game" then + msg = S("Available commands: @1", + table.concat(cmds, " ")) .. "\n" + .. S("Use '/help <cmd>' to get more " + .. "information, or '/help all' to list " + .. "everything.") + else + msg = core.gettext("Available commands: ") + .. table.concat(cmds, " ") .. "\n" + .. core.gettext("Use '.help <cmd>' to get more " + .. "information, or '.help all' to list " + .. "everything.") + end + return true, msg + elseif #args == 0 or (args[1] == "all" and use_gui) then + core.show_general_help_formspec(name) + return true + elseif args[1] == "all" then + local cmds = {} + for cmd, def in pairs(core.registered_chatcommands) do + if INIT == "client" or core.check_player_privs(name, def.privs) then + cmds[#cmds + 1] = format_help_line(cmd, def) + end + end + table.sort(cmds) + local msg + if INIT == "game" then + msg = S("Available commands:") + else + msg = core.gettext("Available commands:") + end + return true, msg.."\n"..table.concat(cmds, "\n") + elseif INIT == "game" and args[1] == "privs" then + if use_gui then + core.show_privs_help_formspec(name) + return true + end + local privs = {} + for priv, def in pairs(core.registered_privileges) do + privs[#privs + 1] = priv .. ": " .. def.description + end + table.sort(privs) + return true, S("Available privileges:").."\n"..table.concat(privs, "\n") + else + local cmd = args[1] + local def = core.registered_chatcommands[cmd] + if not def then + local msg + if INIT == "game" then + msg = S("Command not available: @1", cmd) + else + msg = core.gettext("Command not available: ") .. cmd + end + return false, msg + else + return true, format_help_line(cmd, def) + end + end +end + +if INIT == "client" then + core.register_chatcommand("help", { + params = core.gettext("[all | <cmd>]"), + description = core.gettext("Get help for commands"), + func = function(param) + return do_help_cmd(nil, param) + end, + }) +else + core.register_chatcommand("help", { + params = S("[all | privs | <cmd>] [-t]"), + description = S("Get help for commands or list privileges (-t: output in chat)"), + func = do_help_cmd, + }) +end diff --git a/builtin/common/filterlist.lua b/builtin/common/filterlist.lua new file mode 100644 index 0000000..e30379f --- /dev/null +++ b/builtin/common/filterlist.lua @@ -0,0 +1,319 @@ +--Minetest +--Copyright (C) 2013 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-------------------------------------------------------------------------------- +-- TODO improve doc -- +-- TODO code cleanup -- +-- Generic implementation of a filter/sortable list -- +-- Usage: -- +-- Filterlist needs to be initialized on creation. To achieve this you need to -- +-- pass following functions: -- +-- raw_fct() (mandatory): -- +-- function returning a table containing the elements to be filtered -- +-- compare_fct(element1,element2) (mandatory): -- +-- function returning true/false if element1 is same element as element2 -- +-- uid_match_fct(element1,uid) (optional) -- +-- function telling if uid is attached to element1 -- +-- filter_fct(element,filtercriteria) (optional) -- +-- function returning true/false if filtercriteria met to element -- +-- fetch_param (optional) -- +-- parameter passed to raw_fct to aquire correct raw data -- +-- -- +-------------------------------------------------------------------------------- +filterlist = {} + +-------------------------------------------------------------------------------- +function filterlist.refresh(self) + self.m_raw_list = self.m_raw_list_fct(self.m_fetch_param) + filterlist.process(self) +end + +-------------------------------------------------------------------------------- +function filterlist.create(raw_fct,compare_fct,uid_match_fct,filter_fct,fetch_param) + + assert((raw_fct ~= nil) and (type(raw_fct) == "function")) + assert((compare_fct ~= nil) and (type(compare_fct) == "function")) + + local self = {} + + self.m_raw_list_fct = raw_fct + self.m_compare_fct = compare_fct + self.m_filter_fct = filter_fct + self.m_uid_match_fct = uid_match_fct + + self.m_filtercriteria = nil + self.m_fetch_param = fetch_param + + self.m_sortmode = "none" + self.m_sort_list = {} + + self.m_processed_list = nil + self.m_raw_list = self.m_raw_list_fct(self.m_fetch_param) + + self.add_sort_mechanism = filterlist.add_sort_mechanism + self.set_filtercriteria = filterlist.set_filtercriteria + self.get_filtercriteria = filterlist.get_filtercriteria + self.set_sortmode = filterlist.set_sortmode + self.get_list = filterlist.get_list + self.get_raw_list = filterlist.get_raw_list + self.get_raw_element = filterlist.get_raw_element + self.get_raw_index = filterlist.get_raw_index + self.get_current_index = filterlist.get_current_index + self.size = filterlist.size + self.uid_exists_raw = filterlist.uid_exists_raw + self.raw_index_by_uid = filterlist.raw_index_by_uid + self.refresh = filterlist.refresh + + filterlist.process(self) + + return self +end + +-------------------------------------------------------------------------------- +function filterlist.add_sort_mechanism(self,name,fct) + self.m_sort_list[name] = fct +end + +-------------------------------------------------------------------------------- +function filterlist.set_filtercriteria(self,criteria) + if criteria == self.m_filtercriteria and + type(criteria) ~= "table" then + return + end + self.m_filtercriteria = criteria + filterlist.process(self) +end + +-------------------------------------------------------------------------------- +function filterlist.get_filtercriteria(self) + return self.m_filtercriteria +end + +-------------------------------------------------------------------------------- +--supported sort mode "alphabetic|none" +function filterlist.set_sortmode(self,mode) + if (mode == self.m_sortmode) then + return + end + self.m_sortmode = mode + filterlist.process(self) +end + +-------------------------------------------------------------------------------- +function filterlist.get_list(self) + return self.m_processed_list +end + +-------------------------------------------------------------------------------- +function filterlist.get_raw_list(self) + return self.m_raw_list +end + +-------------------------------------------------------------------------------- +function filterlist.get_raw_element(self,idx) + if type(idx) ~= "number" then + idx = tonumber(idx) + end + + if idx ~= nil and idx > 0 and idx <= #self.m_raw_list then + return self.m_raw_list[idx] + end + + return nil +end + +-------------------------------------------------------------------------------- +function filterlist.get_raw_index(self,listindex) + assert(self.m_processed_list ~= nil) + + if listindex ~= nil and listindex > 0 and + listindex <= #self.m_processed_list then + local entry = self.m_processed_list[listindex] + + for i,v in ipairs(self.m_raw_list) do + + if self.m_compare_fct(v,entry) then + return i + end + end + end + + return 0 +end + +-------------------------------------------------------------------------------- +function filterlist.get_current_index(self,listindex) + assert(self.m_processed_list ~= nil) + + if listindex ~= nil and listindex > 0 and + listindex <= #self.m_raw_list then + local entry = self.m_raw_list[listindex] + + for i,v in ipairs(self.m_processed_list) do + + if self.m_compare_fct(v,entry) then + return i + end + end + end + + return 0 +end + +-------------------------------------------------------------------------------- +function filterlist.process(self) + assert(self.m_raw_list ~= nil) + + if self.m_sortmode == "none" and + self.m_filtercriteria == nil then + self.m_processed_list = self.m_raw_list + return + end + + self.m_processed_list = {} + + for k,v in pairs(self.m_raw_list) do + if self.m_filtercriteria == nil or + self.m_filter_fct(v,self.m_filtercriteria) then + self.m_processed_list[#self.m_processed_list + 1] = v + end + end + + if self.m_sortmode == "none" then + return + end + + if self.m_sort_list[self.m_sortmode] ~= nil and + type(self.m_sort_list[self.m_sortmode]) == "function" then + + self.m_sort_list[self.m_sortmode](self) + end +end + +-------------------------------------------------------------------------------- +function filterlist.size(self) + if self.m_processed_list == nil then + return 0 + end + + return #self.m_processed_list +end + +-------------------------------------------------------------------------------- +function filterlist.uid_exists_raw(self,uid) + for i,v in ipairs(self.m_raw_list) do + if self.m_uid_match_fct(v,uid) then + return true + end + end + return false +end + +-------------------------------------------------------------------------------- +function filterlist.raw_index_by_uid(self, uid) + local elementcount = 0 + local elementidx = 0 + for i,v in ipairs(self.m_raw_list) do + if self.m_uid_match_fct(v,uid) then + elementcount = elementcount +1 + elementidx = i + end + end + + + -- If there are more elements than one with same name uid can't decide which + -- one is meant. self shouldn't be possible but just for sure. + if elementcount > 1 then + elementidx=0 + end + + return elementidx +end + +-------------------------------------------------------------------------------- +-- COMMON helper functions -- +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- +function compare_worlds(world1,world2) + if world1.path ~= world2.path then + return false + end + + if world1.name ~= world2.name then + return false + end + + if world1.gameid ~= world2.gameid then + return false + end + + return true +end + +-------------------------------------------------------------------------------- +function sort_worlds_alphabetic(self) + + table.sort(self.m_processed_list, function(a, b) + --fixes issue #857 (crash due to sorting nil in worldlist) + if a == nil or b == nil then + if a == nil and b ~= nil then return false end + if b == nil and a ~= nil then return true end + return false + end + if a.name:lower() == b.name:lower() then + return a.name < b.name + end + return a.name:lower() < b.name:lower() + end) +end + +-------------------------------------------------------------------------------- +function sort_mod_list(self) + + table.sort(self.m_processed_list, function(a, b) + -- Show game mods at bottom + if a.type ~= b.type or a.loc ~= b.loc then + if b.type == "game" then + return a.loc ~= "game" + end + return b.loc == "game" + end + -- If in same or no modpack, sort by name + if a.modpack == b.modpack then + if a.name:lower() == b.name:lower() then + return a.name < b.name + end + return a.name:lower() < b.name:lower() + -- Else compare name to modpack name + else + -- Always show modpack pseudo-mod on top of modpack mod list + if a.name == b.modpack then + return true + elseif b.name == a.modpack then + return false + end + + local name_a = a.modpack or a.name + local name_b = b.modpack or b.name + if name_a:lower() == name_b:lower() then + return name_a < name_b + end + return name_a:lower() < name_b:lower() + end + end) +end diff --git a/builtin/common/information_formspecs.lua b/builtin/common/information_formspecs.lua new file mode 100644 index 0000000..1445a01 --- /dev/null +++ b/builtin/common/information_formspecs.lua @@ -0,0 +1,136 @@ +local COLOR_BLUE = "#7AF" +local COLOR_GREEN = "#7F7" +local COLOR_GRAY = "#BBB" + +local LIST_FORMSPEC = [[ + size[13,6.5] + label[0,-0.1;%s] + tablecolumns[color;tree;text;text] + table[0,0.5;12.8,5.5;list;%s;0] + button_exit[5,6;3,1;quit;%s] + ]] + +local LIST_FORMSPEC_DESCRIPTION = [[ + size[13,7.5] + label[0,-0.1;%s] + tablecolumns[color;tree;text;text] + table[0,0.5;12.8,4.8;list;%s;%i] + box[0,5.5;12.8,1.5;#000] + textarea[0.3,5.5;13.05,1.9;;;%s] + button_exit[5,7;3,1;quit;%s] + ]] + +local F = core.formspec_escape +local S = core.get_translator("__builtin") + + +-- CHAT COMMANDS FORMSPEC + +local mod_cmds = {} + +local function load_mod_command_tree() + mod_cmds = {} + + for name, def in pairs(core.registered_chatcommands) do + mod_cmds[def.mod_origin] = mod_cmds[def.mod_origin] or {} + local cmds = mod_cmds[def.mod_origin] + + -- Could be simplified, but avoid the priv checks whenever possible + cmds[#cmds + 1] = { name, def } + end + local sorted_mod_cmds = {} + for modname, cmds in pairs(mod_cmds) do + table.sort(cmds, function(a, b) return a[1] < b[1] end) + sorted_mod_cmds[#sorted_mod_cmds + 1] = { modname, cmds } + end + table.sort(sorted_mod_cmds, function(a, b) return a[1] < b[1] end) + mod_cmds = sorted_mod_cmds +end + +core.after(0, load_mod_command_tree) + +local function build_chatcommands_formspec(name, sel, copy) + local rows = {} + rows[1] = "#FFF,0,"..F(S("Command"))..","..F(S("Parameters")) + + local description = S("For more information, click on " + .. "any entry in the list.").. "\n" .. + S("Double-click to copy the entry to the chat history.") + + local privs = core.get_player_privs(name) + for i, data in ipairs(mod_cmds) do + rows[#rows + 1] = COLOR_BLUE .. ",0," .. F(data[1]) .. "," + for j, cmds in ipairs(data[2]) do + local has_priv = privs[cmds[2].privs] + rows[#rows + 1] = ("%s,1,%s,%s"):format( + has_priv and COLOR_GREEN or COLOR_GRAY, + cmds[1], F(cmds[2].params)) + if sel == #rows then + description = cmds[2].description + if copy then + core.chat_send_player(name, S("Command: @1 @2", + core.colorize("#0FF", "/" .. cmds[1]), cmds[2].params)) + end + end + end + end + + return LIST_FORMSPEC_DESCRIPTION:format( + F(S("Available commands: (see also: /help <cmd>)")), + table.concat(rows, ","), sel or 0, + F(description), F(S("Close")) + ) +end + + +-- PRIVILEGES FORMSPEC + +local function build_privs_formspec(name) + local privs = {} + for priv_name, def in pairs(core.registered_privileges) do + privs[#privs + 1] = { priv_name, def } + end + table.sort(privs, function(a, b) return a[1] < b[1] end) + + local rows = {} + rows[1] = "#FFF,0,"..F(S("Privilege"))..","..F(S("Description")) + + local player_privs = core.get_player_privs(name) + for i, data in ipairs(privs) do + rows[#rows + 1] = ("%s,0,%s,%s"):format( + player_privs[data[1]] and COLOR_GREEN or COLOR_GRAY, + data[1], F(data[2].description)) + end + + return LIST_FORMSPEC:format( + F(S("Available privileges:")), + table.concat(rows, ","), + F(S("Close")) + ) +end + + +-- DETAILED CHAT COMMAND INFORMATION + +core.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "__builtin:help_cmds" or fields.quit then + return + end + + local event = core.explode_table_event(fields.list) + if event.type ~= "INV" then + local name = player:get_player_name() + core.show_formspec(name, "__builtin:help_cmds", + build_chatcommands_formspec(name, event.row, event.type == "DCL")) + end +end) + +function core.show_general_help_formspec(name) + core.show_formspec(name, "__builtin:help_cmds", + build_chatcommands_formspec(name)) +end + +function core.show_privs_help_formspec(name) + core.show_formspec(name, "__builtin:help_privs", + build_privs_formspec(name)) +end diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua new file mode 100644 index 0000000..467f188 --- /dev/null +++ b/builtin/common/misc_helpers.lua @@ -0,0 +1,770 @@ +-- Minetest: builtin/misc_helpers.lua + +-------------------------------------------------------------------------------- +-- Localize functions to avoid table lookups (better performance). +local string_sub, string_find = string.sub, string.find + +-------------------------------------------------------------------------------- +local function basic_dump(o) + local tp = type(o) + if tp == "number" then + return tostring(o) + elseif tp == "string" then + return string.format("%q", o) + elseif tp == "boolean" then + return tostring(o) + elseif tp == "nil" then + return "nil" + -- Uncomment for full function dumping support. + -- Not currently enabled because bytecode isn't very human-readable and + -- dump's output is intended for humans. + --elseif tp == "function" then + -- return string.format("loadstring(%q)", string.dump(o)) + elseif tp == "userdata" then + return tostring(o) + else + return string.format("<%s>", tp) + end +end + +local keywords = { + ["and"] = true, + ["break"] = true, + ["do"] = true, + ["else"] = true, + ["elseif"] = true, + ["end"] = true, + ["false"] = true, + ["for"] = true, + ["function"] = true, + ["goto"] = true, -- Lua 5.2 + ["if"] = true, + ["in"] = true, + ["local"] = true, + ["nil"] = true, + ["not"] = true, + ["or"] = true, + ["repeat"] = true, + ["return"] = true, + ["then"] = true, + ["true"] = true, + ["until"] = true, + ["while"] = true, +} +local function is_valid_identifier(str) + if not str:find("^[a-zA-Z_][a-zA-Z0-9_]*$") or keywords[str] then + return false + end + return true +end + +-------------------------------------------------------------------------------- +-- Dumps values in a line-per-value format. +-- For example, {test = {"Testing..."}} becomes: +-- _["test"] = {} +-- _["test"][1] = "Testing..." +-- This handles tables as keys and circular references properly. +-- It also handles multiple references well, writing the table only once. +-- The dumped argument is internal-only. + +function dump2(o, name, dumped) + name = name or "_" + -- "dumped" is used to keep track of serialized tables to handle + -- multiple references and circular tables properly. + -- It only contains tables as keys. The value is the name that + -- the table has in the dump, eg: + -- {x = {"y"}} -> dumped[{"y"}] = '_["x"]' + dumped = dumped or {} + if type(o) ~= "table" then + return string.format("%s = %s\n", name, basic_dump(o)) + end + if dumped[o] then + return string.format("%s = %s\n", name, dumped[o]) + end + dumped[o] = name + -- This contains a list of strings to be concatenated later (because + -- Lua is slow at individual concatenation). + local t = {} + for k, v in pairs(o) do + local keyStr + if type(k) == "table" then + if dumped[k] then + keyStr = dumped[k] + else + -- Key tables don't have a name, so use one of + -- the form _G["table: 0xFFFFFFF"] + keyStr = string.format("_G[%q]", tostring(k)) + -- Dump key table + t[#t + 1] = dump2(k, keyStr, dumped) + end + else + keyStr = basic_dump(k) + end + local vname = string.format("%s[%s]", name, keyStr) + t[#t + 1] = dump2(v, vname, dumped) + end + return string.format("%s = {}\n%s", name, table.concat(t)) +end + +-------------------------------------------------------------------------------- +-- This dumps values in a one-statement format. +-- For example, {test = {"Testing..."}} becomes: +-- [[{ +-- test = { +-- "Testing..." +-- } +-- }]] +-- This supports tables as keys, but not circular references. +-- It performs poorly with multiple references as it writes out the full +-- table each time. +-- The indent field specifies a indentation string, it defaults to a tab. +-- Use the empty string to disable indentation. +-- The dumped and level arguments are internal-only. + +function dump(o, indent, nested, level) + local t = type(o) + if not level and t == "userdata" then + -- when userdata (e.g. player) is passed directly, print its metatable: + return "userdata metatable: " .. dump(getmetatable(o)) + end + if t ~= "table" then + return basic_dump(o) + end + + -- Contains table -> true/nil of currently nested tables + nested = nested or {} + if nested[o] then + return "<circular reference>" + end + nested[o] = true + indent = indent or "\t" + level = level or 1 + + local ret = {} + local dumped_indexes = {} + for i, v in ipairs(o) do + ret[#ret + 1] = dump(v, indent, nested, level + 1) + dumped_indexes[i] = true + end + for k, v in pairs(o) do + if not dumped_indexes[k] then + if type(k) ~= "string" or not is_valid_identifier(k) then + k = "["..dump(k, indent, nested, level + 1).."]" + end + v = dump(v, indent, nested, level + 1) + ret[#ret + 1] = k.." = "..v + end + end + nested[o] = nil + if indent ~= "" then + local indent_str = "\n"..string.rep(indent, level) + local end_indent_str = "\n"..string.rep(indent, level - 1) + return string.format("{%s%s%s}", + indent_str, + table.concat(ret, ","..indent_str), + end_indent_str) + end + return "{"..table.concat(ret, ", ").."}" +end + +-------------------------------------------------------------------------------- +function string.split(str, delim, include_empty, max_splits, sep_is_pattern) + delim = delim or "," + max_splits = max_splits or -2 + local items = {} + local pos, len = 1, #str + local plain = not sep_is_pattern + max_splits = max_splits + 1 + repeat + local np, npe = string_find(str, delim, pos, plain) + np, npe = (np or (len+1)), (npe or (len+1)) + if (not np) or (max_splits == 1) then + np = len + 1 + npe = np + end + local s = string_sub(str, pos, np - 1) + if include_empty or (s ~= "") then + max_splits = max_splits - 1 + items[#items + 1] = s + end + pos = npe + 1 + until (max_splits == 0) or (pos > (len + 1)) + return items +end + +-------------------------------------------------------------------------------- +function table.indexof(list, val) + for i, v in ipairs(list) do + if v == val then + return i + end + end + return -1 +end + +-------------------------------------------------------------------------------- +function string:trim() + return self:match("^%s*(.-)%s*$") +end + +-------------------------------------------------------------------------------- +function math.hypot(x, y) + return math.sqrt(x * x + y * y) +end + +-------------------------------------------------------------------------------- +function math.sign(x, tolerance) + tolerance = tolerance or 0 + if x > tolerance then + return 1 + elseif x < -tolerance then + return -1 + end + return 0 +end + +-------------------------------------------------------------------------------- +function math.factorial(x) + assert(x % 1 == 0 and x >= 0, "factorial expects a non-negative integer") + if x >= 171 then + -- 171! is greater than the biggest double, no need to calculate + return math.huge + end + local v = 1 + for k = 2, x do + v = v * k + end + return v +end + + +function math.round(x) + if x >= 0 then + return math.floor(x + 0.5) + end + return math.ceil(x - 0.5) +end + +local formspec_escapes = { + ["\\"] = "\\\\", + ["["] = "\\[", + ["]"] = "\\]", + [";"] = "\\;", + [","] = "\\," +} +function core.formspec_escape(text) + -- Use explicit character set instead of dot here because it doubles the performance + return text and string.gsub(text, "[\\%[%];,]", formspec_escapes) +end + + +function core.wrap_text(text, max_length, as_table) + local result = {} + local line = {} + if #text <= max_length then + return as_table and {text} or text + end + + local line_length = 0 + for word in text:gmatch("%S+") do + if line_length > 0 and line_length + #word + 1 >= max_length then + -- word wouldn't fit on current line, move to next line + table.insert(result, table.concat(line, " ")) + line = {word} + line_length = #word + else + table.insert(line, word) + line_length = line_length + 1 + #word + end + end + + table.insert(result, table.concat(line, " ")) + return as_table and result or table.concat(result, "\n") +end + +-------------------------------------------------------------------------------- + +if INIT == "game" then + local dirs1 = {9, 18, 7, 12} + local dirs2 = {20, 23, 22, 21} + + function core.rotate_and_place(itemstack, placer, pointed_thing, + infinitestacks, orient_flags, prevent_after_place) + orient_flags = orient_flags or {} + + local unode = core.get_node_or_nil(pointed_thing.under) + if not unode then + return + end + local undef = core.registered_nodes[unode.name] + local sneaking = placer and placer:get_player_control().sneak + if undef and undef.on_rightclick and not sneaking then + return undef.on_rightclick(pointed_thing.under, unode, placer, + itemstack, pointed_thing) + end + local fdir = placer and core.dir_to_facedir(placer:get_look_dir()) or 0 + + local above = pointed_thing.above + local under = pointed_thing.under + local iswall = (above.y == under.y) + local isceiling = not iswall and (above.y < under.y) + + if undef and undef.buildable_to then + iswall = false + end + + if orient_flags.force_floor then + iswall = false + isceiling = false + elseif orient_flags.force_ceiling then + iswall = false + isceiling = true + elseif orient_flags.force_wall then + iswall = true + isceiling = false + elseif orient_flags.invert_wall then + iswall = not iswall + end + + local param2 = fdir + if iswall then + param2 = dirs1[fdir + 1] + elseif isceiling then + if orient_flags.force_facedir then + param2 = 20 + else + param2 = dirs2[fdir + 1] + end + else -- place right side up + if orient_flags.force_facedir then + param2 = 0 + end + end + + local old_itemstack = ItemStack(itemstack) + local new_itemstack = core.item_place_node(itemstack, placer, + pointed_thing, param2, prevent_after_place) + return infinitestacks and old_itemstack or new_itemstack + end + + +-------------------------------------------------------------------------------- +--Wrapper for rotate_and_place() to check for sneak and assume Creative mode +--implies infinite stacks when performing a 6d rotation. +-------------------------------------------------------------------------------- + core.rotate_node = function(itemstack, placer, pointed_thing) + local name = placer and placer:get_player_name() or "" + local invert_wall = placer and placer:get_player_control().sneak or false + return core.rotate_and_place(itemstack, placer, pointed_thing, + core.is_creative_enabled(name), + {invert_wall = invert_wall}, true) + end +end + +-------------------------------------------------------------------------------- +function core.explode_table_event(evt) + if evt ~= nil then + local parts = evt:split(":") + if #parts == 3 then + local t = parts[1]:trim() + local r = tonumber(parts[2]:trim()) + local c = tonumber(parts[3]:trim()) + if type(r) == "number" and type(c) == "number" + and t ~= "INV" then + return {type=t, row=r, column=c} + end + end + end + return {type="INV", row=0, column=0} +end + +-------------------------------------------------------------------------------- +function core.explode_textlist_event(evt) + if evt ~= nil then + local parts = evt:split(":") + if #parts == 2 then + local t = parts[1]:trim() + local r = tonumber(parts[2]:trim()) + if type(r) == "number" and t ~= "INV" then + return {type=t, index=r} + end + end + end + return {type="INV", index=0} +end + +-------------------------------------------------------------------------------- +function core.explode_scrollbar_event(evt) + local retval = core.explode_textlist_event(evt) + + retval.value = retval.index + retval.index = nil + + return retval +end + +-------------------------------------------------------------------------------- +function core.rgba(r, g, b, a) + return a and string.format("#%02X%02X%02X%02X", r, g, b, a) or + string.format("#%02X%02X%02X", r, g, b) +end + +-------------------------------------------------------------------------------- +function core.pos_to_string(pos, decimal_places) + local x = pos.x + local y = pos.y + local z = pos.z + if decimal_places ~= nil then + x = string.format("%." .. decimal_places .. "f", x) + y = string.format("%." .. decimal_places .. "f", y) + z = string.format("%." .. decimal_places .. "f", z) + end + return "(" .. x .. "," .. y .. "," .. z .. ")" +end + +-------------------------------------------------------------------------------- +function core.string_to_pos(value) + if value == nil then + return nil + end + + value = value:match("^%((.-)%)$") or value -- strip parentheses + + local x, y, z = value:trim():match("^([%d.-]+)[,%s]%s*([%d.-]+)[,%s]%s*([%d.-]+)$") + if x and y and z then + x = tonumber(x) + y = tonumber(y) + z = tonumber(z) + return vector.new(x, y, z) + end + + return nil +end + + +-------------------------------------------------------------------------------- + +do + local rel_num_cap = "(~?-?%d*%.?%d*)" -- may be overly permissive as this will be tonumber'ed anyways + local num_delim = "[,%s]%s*" + local pattern = "^" .. table.concat({rel_num_cap, rel_num_cap, rel_num_cap}, num_delim) .. "$" + + local function parse_area_string(pos, relative_to) + local pp = {} + pp.x, pp.y, pp.z = pos:trim():match(pattern) + return core.parse_coordinates(pp.x, pp.y, pp.z, relative_to) + end + + function core.string_to_area(value, relative_to) + local p1, p2 = value:match("^%((.-)%)%s*%((.-)%)$") + if not p1 then + return + end + + p1 = parse_area_string(p1, relative_to) + p2 = parse_area_string(p2, relative_to) + + if p1 == nil or p2 == nil then + return + end + + return p1, p2 + end +end + +-------------------------------------------------------------------------------- +function table.copy(t, seen) + local n = {} + seen = seen or {} + seen[t] = n + for k, v in pairs(t) do + n[(type(k) == "table" and (seen[k] or table.copy(k, seen))) or k] = + (type(v) == "table" and (seen[v] or table.copy(v, seen))) or v + end + return n +end + + +function table.insert_all(t, other) + for i=1, #other do + t[#t + 1] = other[i] + end + return t +end + + +function table.key_value_swap(t) + local ti = {} + for k,v in pairs(t) do + ti[v] = k + end + return ti +end + + +function table.shuffle(t, from, to, random) + from = from or 1 + to = to or #t + random = random or math.random + local n = to - from + 1 + while n > 1 do + local r = from + n-1 + local l = from + random(0, n-1) + t[l], t[r] = t[r], t[l] + n = n-1 + end +end + + +-------------------------------------------------------------------------------- +-- mainmenu only functions +-------------------------------------------------------------------------------- +if INIT == "mainmenu" then + function core.get_game(index) + local games = core.get_games() + + if index > 0 and index <= #games then + return games[index] + end + + return nil + end +end + +if core.gettext then -- for client and mainmenu + function fgettext_ne(text, ...) + text = core.gettext(text) + local arg = {n=select('#', ...), ...} + if arg.n >= 1 then + -- Insert positional parameters ($1, $2, ...) + local result = '' + local pos = 1 + while pos <= text:len() do + local newpos = text:find('[$]', pos) + if newpos == nil then + result = result .. text:sub(pos) + pos = text:len() + 1 + else + local paramindex = + tonumber(text:sub(newpos+1, newpos+1)) + result = result .. text:sub(pos, newpos-1) + .. tostring(arg[paramindex]) + pos = newpos + 2 + end + end + text = result + end + return text + end + + function fgettext(text, ...) + return core.formspec_escape(fgettext_ne(text, ...)) + end +end + +local ESCAPE_CHAR = string.char(0x1b) + +function core.get_color_escape_sequence(color) + return ESCAPE_CHAR .. "(c@" .. color .. ")" +end + +function core.get_background_escape_sequence(color) + return ESCAPE_CHAR .. "(b@" .. color .. ")" +end + +function core.colorize(color, message) + local lines = tostring(message):split("\n", true) + local color_code = core.get_color_escape_sequence(color) + + for i, line in ipairs(lines) do + lines[i] = color_code .. line + end + + return table.concat(lines, "\n") .. core.get_color_escape_sequence("#ffffff") +end + + +function core.strip_foreground_colors(str) + return (str:gsub(ESCAPE_CHAR .. "%(c@[^)]+%)", "")) +end + +function core.strip_background_colors(str) + return (str:gsub(ESCAPE_CHAR .. "%(b@[^)]+%)", "")) +end + +function core.strip_colors(str) + return (str:gsub(ESCAPE_CHAR .. "%([bc]@[^)]+%)", "")) +end + +function core.translate(textdomain, str, ...) + local start_seq + if textdomain == "" then + start_seq = ESCAPE_CHAR .. "T" + else + start_seq = ESCAPE_CHAR .. "(T@" .. textdomain .. ")" + end + local arg = {n=select('#', ...), ...} + local end_seq = ESCAPE_CHAR .. "E" + local arg_index = 1 + local translated = str:gsub("@(.)", function(matched) + local c = string.byte(matched) + if string.byte("1") <= c and c <= string.byte("9") then + local a = c - string.byte("0") + if a ~= arg_index then + error("Escape sequences in string given to core.translate " .. + "are not in the correct order: got @" .. matched .. + "but expected @" .. tostring(arg_index)) + end + if a > arg.n then + error("Not enough arguments provided to core.translate") + end + arg_index = arg_index + 1 + return ESCAPE_CHAR .. "F" .. arg[a] .. ESCAPE_CHAR .. "E" + elseif matched == "n" then + return "\n" + else + return matched + end + end) + if arg_index < arg.n + 1 then + error("Too many arguments provided to core.translate") + end + return start_seq .. translated .. end_seq +end + +function core.get_translator(textdomain) + return function(str, ...) return core.translate(textdomain or "", str, ...) end +end + +-------------------------------------------------------------------------------- +-- Returns the exact coordinate of a pointed surface +-------------------------------------------------------------------------------- +function core.pointed_thing_to_face_pos(placer, pointed_thing) + -- Avoid crash in some situations when player is inside a node, causing + -- 'above' to equal 'under'. + if vector.equals(pointed_thing.above, pointed_thing.under) then + return pointed_thing.under + end + + local eye_height = placer:get_properties().eye_height + local eye_offset_first = placer:get_eye_offset() + local node_pos = pointed_thing.under + local camera_pos = placer:get_pos() + local pos_off = vector.multiply( + vector.subtract(pointed_thing.above, node_pos), 0.5) + local look_dir = placer:get_look_dir() + local offset, nc + local oc = {} + + for c, v in pairs(pos_off) do + if nc or v == 0 then + oc[#oc + 1] = c + else + offset = v + nc = c + end + end + + local fine_pos = {[nc] = node_pos[nc] + offset} + camera_pos.y = camera_pos.y + eye_height + eye_offset_first.y / 10 + local f = (node_pos[nc] + offset - camera_pos[nc]) / look_dir[nc] + + for i = 1, #oc do + fine_pos[oc[i]] = camera_pos[oc[i]] + look_dir[oc[i]] * f + end + return fine_pos +end + +function core.string_to_privs(str, delim) + assert(type(str) == "string") + delim = delim or ',' + local privs = {} + for _, priv in pairs(string.split(str, delim)) do + privs[priv:trim()] = true + end + return privs +end + +function core.privs_to_string(privs, delim) + assert(type(privs) == "table") + delim = delim or ',' + local list = {} + for priv, bool in pairs(privs) do + if bool then + list[#list + 1] = priv + end + end + return table.concat(list, delim) +end + +function core.is_nan(number) + return number ~= number +end + +--[[ Helper function for parsing an optionally relative number +of a chat command parameter, using the chat command tilde notation. + +Parameters: +* arg: String snippet containing the number; possible values: + * "<number>": return as number + * "~<number>": return relative_to + <number> + * "~": return relative_to + * Anything else will return `nil` +* relative_to: Number to which the `arg` number might be relative to + +Returns: +A number or `nil`, depending on `arg. + +Examples: +* `core.parse_relative_number("5", 10)` returns 5 +* `core.parse_relative_number("~5", 10)` returns 15 +* `core.parse_relative_number("~", 10)` returns 10 +]] +function core.parse_relative_number(arg, relative_to) + if not arg then + return nil + elseif arg == "~" then + return relative_to + elseif string.sub(arg, 1, 1) == "~" then + local number = tonumber(string.sub(arg, 2)) + if not number then + return nil + end + if core.is_nan(number) or number == math.huge or number == -math.huge then + return nil + end + return relative_to + number + else + local number = tonumber(arg) + if core.is_nan(number) or number == math.huge or number == -math.huge then + return nil + end + return number + end +end + +--[[ Helper function to parse coordinates that might be relative +to another position; supports chat command tilde notation. +Intended to be used in chat command parameter parsing. + +Parameters: +* x, y, z: Parsed x, y, and z coordinates as strings +* relative_to: Position to which to compare the position + +Syntax of x, y and z: +* "<number>": return as number +* "~<number>": return <number> + player position on this axis +* "~": return player position on this axis + +Returns: a vector or nil for invalid input or if player does not exist +]] +function core.parse_coordinates(x, y, z, relative_to) + if not relative_to then + x, y, z = tonumber(x), tonumber(y), tonumber(z) + return x and y and z and { x = x, y = y, z = z } + end + local rx = core.parse_relative_number(x, relative_to.x) + local ry = core.parse_relative_number(y, relative_to.y) + local rz = core.parse_relative_number(z, relative_to.z) + return rx and ry and rz and { x = rx, y = ry, z = rz } +end diff --git a/builtin/common/mod_storage.lua b/builtin/common/mod_storage.lua new file mode 100644 index 0000000..7ccf629 --- /dev/null +++ b/builtin/common/mod_storage.lua @@ -0,0 +1,19 @@ +-- Modify core.get_mod_storage to return the storage for the current mod. + +local get_current_modname = core.get_current_modname + +local old_get_mod_storage = core.get_mod_storage + +local storages = setmetatable({}, { + __mode = "v", -- values are weak references (can be garbage-collected) + __index = function(self, modname) + local storage = old_get_mod_storage(modname) + self[modname] = storage + return storage + end, +}) + +function core.get_mod_storage() + local modname = get_current_modname() + return modname and storages[modname] +end diff --git a/builtin/common/serialize.lua b/builtin/common/serialize.lua new file mode 100644 index 0000000..afa63b3 --- /dev/null +++ b/builtin/common/serialize.lua @@ -0,0 +1,238 @@ +--- Lua module to serialize values as Lua code. +-- From: https://github.com/appgurueu/modlib/blob/master/luon.lua +-- License: MIT + +local next, rawget, pairs, pcall, error, type, setfenv, loadstring + = next, rawget, pairs, pcall, error, type, setfenv, loadstring + +local table_concat, string_dump, string_format, string_match, math_huge + = table.concat, string.dump, string.format, string.match, math.huge + +-- Recursively counts occurences of objects (non-primitives including strings) in a table. +local function count_objects(value) + local counts = {} + if value == nil then + -- Early return for nil; tables can't contain nil + return counts + end + local function count_values(val) + local type_ = type(val) + if type_ == "boolean" or type_ == "number" then + return + end + local count = counts[val] + counts[val] = (count or 0) + 1 + if type_ == "table" then + if not count then + for k, v in pairs(val) do + count_values(k) + count_values(v) + end + end + elseif type_ ~= "string" and type_ ~= "function" then + error("unsupported type: " .. type_) + end + end + count_values(value) + return counts +end + +-- Build a "set" of Lua keywords. These can't be used as short key names. +-- See https://www.lua.org/manual/5.1/manual.html#2.1 +local keywords = {} +for _, keyword in pairs({ + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "if", + "in", "local", "nil", "not", "or", + "repeat", "return", "then", "true", "until", "while", + "goto" -- LuaJIT, Lua 5.2+ +}) do + keywords[keyword] = true +end + +local function quote(string) + return string_format("%q", string) +end + +local function dump_func(func) + return string_format("loadstring(%q)", string_dump(func)) +end + +-- Serializes Lua nil, booleans, numbers, strings, tables and even functions +-- Tables are referenced by reference, strings are referenced by value. Supports circular tables. +local function serialize(value, write) + local reference, refnum = "1", 1 + -- [object] = reference + local references = {} + -- Circular tables that must be filled using `table[key] = value` statements + local to_fill = {} + for object, count in pairs(count_objects(value)) do + local type_ = type(object) + -- Object must appear more than once. If it is a string, the reference has to be shorter than the string. + if count >= 2 and (type_ ~= "string" or #reference + 5 < #object) then + if refnum == 1 then + write"local _={};" -- initialize reference table + end + write"_[" + write(reference) + write("]=") + if type_ == "table" then + write("{}") + elseif type_ == "function" then + write(dump_func(object)) + elseif type_ == "string" then + write(quote(object)) + end + write(";") + references[object] = reference + if type_ == "table" then + to_fill[object] = reference + end + refnum = refnum + 1 + reference = ("%d"):format(refnum) + end + end + -- Used to decide whether we should do "key=..." + local function use_short_key(key) + return not references[key] and type(key) == "string" and (not keywords[key]) and string_match(key, "^[%a_][%a%d_]*$") + end + local function dump(value) + -- Primitive types + if value == nil then + return write("nil") + end + if value == true then + return write("true") + end + if value == false then + return write("false") + end + local type_ = type(value) + if type_ == "number" then + if value ~= value then -- nan + return write"0/0" + elseif value == math_huge then + return write"1/0" + elseif value == -math_huge then + return write"-1/0" + else + return write(string_format("%.17g", value)) + end + end + -- Reference types: table, function and string + local ref = references[value] + if ref then + write"_[" + write(ref) + return write"]" + end + if type_ == "string" then + return write(quote(value)) + end + if type_ == "function" then + return write(dump_func(value)) + end + if type_ == "table" then + write("{") + -- First write list keys: + -- Don't use the table length #value here as it may horribly fail + -- for tables which use large integers as keys in the hash part; + -- stop at the first "hole" (nil value) instead + local len = 0 + local first = true -- whether this is the first entry, which may not have a leading comma + while true do + local v = rawget(value, len + 1) -- use rawget to avoid metatables like the vector metatable + if v == nil then break end + if first then first = false else write(",") end + dump(v) + len = len + 1 + end + -- Now write map keys ([key] = value) + for k, v in next, value do + -- We have written all non-float keys in [1, len] already + if type(k) ~= "number" or k % 1 ~= 0 or k < 1 or k > len then + if first then first = false else write(",") end + if use_short_key(k) then + write(k) + else + write("[") + dump(k) + write("]") + end + write("=") + dump(v) + end + end + write("}") + return + end + end + -- Write the statements to fill circular tables + for table, ref in pairs(to_fill) do + for k, v in pairs(table) do + write("_[") + write(ref) + write("]") + if use_short_key(k) then + write(".") + write(k) + else + write("[") + dump(k) + write("]") + end + write("=") + dump(v) + write(";") + end + end + write("return ") + dump(value) +end + +function core.serialize(value) + local rope = {} + serialize(value, function(text) + -- Faster than table.insert(rope, text) on PUC Lua 5.1 + rope[#rope + 1] = text + end) + return table_concat(rope) +end + +local function dummy_func() end + +function core.deserialize(str, safe) + -- Backwards compatibility + if str == nil then + core.log("deprecated", "minetest.deserialize called with nil (expected string).") + return nil, "Invalid type: Expected a string, got nil" + end + local t = type(str) + if t ~= "string" then + error(("minetest.deserialize called with %s (expected string)."):format(t)) + end + + local func, err = loadstring(str) + if not func then return nil, err end + + -- math.huge was serialized to inf and NaNs to nan by Lua in Minetest 5.6, so we have to support this here + local env = {inf = math_huge, nan = 0/0} + if safe then + env.loadstring = dummy_func + else + env.loadstring = function(str, ...) + local func, err = loadstring(str, ...) + if func then + setfenv(func, env) + return func + end + return nil, err + end + end + setfenv(func, env) + local success, value_or_err = pcall(func) + if success then + return value_or_err + end + return nil, value_or_err +end diff --git a/builtin/common/strict.lua b/builtin/common/strict.lua new file mode 100644 index 0000000..936ebb3 --- /dev/null +++ b/builtin/common/strict.lua @@ -0,0 +1,46 @@ +local getinfo, rawget, rawset = debug.getinfo, rawget, rawset + +function core.global_exists(name) + if type(name) ~= "string" then + error("core.global_exists: " .. tostring(name) .. " is not a string") + end + return rawget(_G, name) ~= nil +end + + +local meta = {} +local declared = {} +-- Key is source file, line, and variable name; seperated by NULs +local warned = {} + +function meta:__newindex(name, value) + if declared[name] then + return + end + local info = getinfo(2, "Sl") + local desc = ("%s:%d"):format(info.short_src, info.currentline) + local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name) + if not warned[warn_key] and info.what ~= "main" and info.what ~= "C" then + core.log("warning", ("Assignment to undeclared global %q inside a function at %s.") + :format(name, desc)) + warned[warn_key] = true + end + rawset(self, name, value) + declared[name] = true +end + + +function meta:__index(name) + if declared[name] then + return + end + local info = getinfo(2, "Sl") + local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name) + if not warned[warn_key] and info.what ~= "C" then + core.log("warning", ("Undeclared global variable %q accessed at %s:%s") + :format(name, info.short_src, info.currentline)) + warned[warn_key] = true + end +end + +setmetatable(_G, meta) diff --git a/builtin/common/tests/misc_helpers_spec.lua b/builtin/common/tests/misc_helpers_spec.lua new file mode 100644 index 0000000..7d046d5 --- /dev/null +++ b/builtin/common/tests/misc_helpers_spec.lua @@ -0,0 +1,173 @@ +_G.core = {} +_G.vector = {metatable = {}} +dofile("builtin/common/vector.lua") +dofile("builtin/common/misc_helpers.lua") + +describe("string", function() + it("trim()", function() + assert.equal("foo bar", string.trim("\n \t\tfoo bar\t ")) + end) + + describe("split()", function() + it("removes empty", function() + assert.same({ "hello" }, string.split("hello")) + assert.same({ "hello", "world" }, string.split("hello,world")) + assert.same({ "hello", "world" }, string.split("hello,world,,,")) + assert.same({ "hello", "world" }, string.split(",,,hello,world")) + assert.same({ "hello", "world", "2" }, string.split("hello,,,world,2")) + assert.same({ "hello ", " world" }, string.split("hello :| world", ":|")) + end) + + it("keeps empty", function() + assert.same({ "hello" }, string.split("hello", ",", true)) + assert.same({ "hello", "world" }, string.split("hello,world", ",", true)) + assert.same({ "hello", "world", "" }, string.split("hello,world,", ",", true)) + assert.same({ "hello", "", "", "world", "2" }, string.split("hello,,,world,2", ",", true)) + assert.same({ "", "", "hello", "world", "2" }, string.split(",,hello,world,2", ",", true)) + assert.same({ "hello ", " world | :" }, string.split("hello :| world | :", ":|")) + end) + + it("max_splits", function() + assert.same({ "one" }, string.split("one", ",", true, 2)) + assert.same({ "one,two,three,four" }, string.split("one,two,three,four", ",", true, 0)) + assert.same({ "one", "two", "three,four" }, string.split("one,two,three,four", ",", true, 2)) + assert.same({ "one", "", "two,three,four" }, string.split("one,,two,three,four", ",", true, 2)) + assert.same({ "one", "two", "three,four" }, string.split("one,,,,,,two,three,four", ",", false, 2)) + end) + + it("pattern", function() + assert.same({ "one", "two" }, string.split("one,two", ",", false, -1, true)) + assert.same({ "one", "two", "three" }, string.split("one2two3three", "%d", false, -1, true)) + end) + end) +end) + +describe("privs", function() + it("from string", function() + assert.same({ a = true, b = true }, core.string_to_privs("a,b")) + end) + + it("to string", function() + assert.equal("one", core.privs_to_string({ one=true })) + + local ret = core.privs_to_string({ a=true, b=true }) + assert(ret == "a,b" or ret == "b,a") + end) +end) + +describe("pos", function() + it("from string", function() + assert.equal(vector.new(10, 5.1, -2), core.string_to_pos("10.0, 5.1, -2")) + assert.equal(vector.new(10, 5.1, -2), core.string_to_pos("( 10.0, 5.1, -2)")) + assert.is_nil(core.string_to_pos("asd, 5, -2)")) + end) + + it("to string", function() + assert.equal("(10.1,5.2,-2.3)", core.pos_to_string({ x = 10.1, y = 5.2, z = -2.3})) + end) +end) + +describe("area parsing", function() + describe("valid inputs", function() + it("accepts absolute numbers", function() + local p1, p2 = core.string_to_area("(10.0, 5, -2) ( 30.2 4 -12.53)") + assert(p1.x == 10 and p1.y == 5 and p1.z == -2) + assert(p2.x == 30.2 and p2.y == 4 and p2.z == -12.53) + end) + + it("accepts relative numbers", function() + local p1, p2 = core.string_to_area("(1,2,3) (~5,~-5,~)", {x=10,y=10,z=10}) + assert(type(p1) == "table" and type(p2) == "table") + assert(p1.x == 1 and p1.y == 2 and p1.z == 3) + assert(p2.x == 15 and p2.y == 5 and p2.z == 10) + + p1, p2 = core.string_to_area("(1 2 3) (~5 ~-5 ~)", {x=10,y=10,z=10}) + assert(type(p1) == "table" and type(p2) == "table") + assert(p1.x == 1 and p1.y == 2 and p1.z == 3) + assert(p2.x == 15 and p2.y == 5 and p2.z == 10) + end) + end) + describe("invalid inputs", function() + it("rejects too few numbers", function() + local p1, p2 = core.string_to_area("(1,1) (1,1,1,1)", {x=1,y=1,z=1}) + assert(p1 == nil and p2 == nil) + end) + + it("rejects too many numbers", function() + local p1, p2 = core.string_to_area("(1,1,1,1) (1,1,1,1)", {x=1,y=1,z=1}) + assert(p1 == nil and p2 == nil) + end) + + it("rejects nan & inf", function() + local p1, p2 = core.string_to_area("(1,1,1) (1,1,nan)", {x=1,y=1,z=1}) + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(1,1,1) (1,1,~nan)", {x=1,y=1,z=1}) + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(1,1,1) (1,~nan,1)", {x=1,y=1,z=1}) + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(1,1,1) (1,1,inf)", {x=1,y=1,z=1}) + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(1,1,1) (1,1,~inf)", {x=1,y=1,z=1}) + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(1,1,1) (1,~inf,1)", {x=1,y=1,z=1}) + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(nan,nan,nan) (nan,nan,nan)", {x=1,y=1,z=1}) + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(nan,nan,nan) (nan,nan,nan)") + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(inf,inf,inf) (-inf,-inf,-inf)", {x=1,y=1,z=1}) + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(inf,inf,inf) (-inf,-inf,-inf)") + assert(p1 == nil and p2 == nil) + end) + + it("rejects words", function() + local p1, p2 = core.string_to_area("bananas", {x=1,y=1,z=1}) + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("bananas", "foobar") + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("bananas") + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(bananas,bananas,bananas)") + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(bananas,bananas,bananas) (bananas,bananas,bananas)") + assert(p1 == nil and p2 == nil) + end) + + it("requires parenthesis & valid numbers", function() + local p1, p2 = core.string_to_area("(10.0, 5, -2 30.2, 4, -12.53") + assert(p1 == nil and p2 == nil) + + p1, p2 = core.string_to_area("(10.0, 5,) -2 fgdf2, 4, -12.53") + assert(p1 == nil and p2 == nil) + end) + end) +end) + +describe("table", function() + it("indexof()", function() + assert.equal(1, table.indexof({"foo", "bar"}, "foo")) + assert.equal(-1, table.indexof({"foo", "bar"}, "baz")) + end) +end) + +describe("formspec_escape", function() + it("escapes", function() + assert.equal(nil, core.formspec_escape(nil)) + assert.equal("", core.formspec_escape("")) + assert.equal("\\[Hello\\\\\\[", core.formspec_escape("[Hello\\[")) + end) +end) diff --git a/builtin/common/tests/serialize_spec.lua b/builtin/common/tests/serialize_spec.lua new file mode 100644 index 0000000..340e226 --- /dev/null +++ b/builtin/common/tests/serialize_spec.lua @@ -0,0 +1,189 @@ +_G.core = {} +_G.vector = {metatable = {}} + +_G.setfenv = require 'busted.compatibility'.setfenv + +dofile("builtin/common/serialize.lua") +dofile("builtin/common/vector.lua") + +-- Supports circular tables; does not support table keys +-- Correctly checks whether a mapping of references ("same") exists +-- Is significantly more efficient than assert.same +local function assert_same(a, b, same) + same = same or {} + if same[a] or same[b] then + assert(same[a] == b and same[b] == a) + return + end + if a == b then + return + end + if type(a) ~= "table" or type(b) ~= "table" then + assert(a == b) + return + end + same[a] = b + same[b] = a + local count = 0 + for k, v in pairs(a) do + count = count + 1 + assert(type(k) ~= "table") + assert_same(v, b[k], same) + end + for _ in pairs(b) do + count = count - 1 + end + assert(count == 0) +end + +local x, y = {}, {} +local t1, t2 = {x, x, y, y}, {x, y, x, y} +assert.same(t1, t2) -- will succeed because it only checks whether the depths match +assert(not pcall(assert_same, t1, t2)) -- will correctly fail because it checks whether the refs match + +describe("serialize", function() + local function assert_preserves(value) + local preserved_value = core.deserialize(core.serialize(value)) + assert_same(value, preserved_value) + end + it("works", function() + assert_preserves({cat={sound="nyan", speed=400}, dog={sound="woof"}}) + end) + + it("handles characters", function() + assert_preserves({escape_chars="\n\r\t\v\\\"\'", non_european="θשׁ٩∂"}) + end) + + it("handles NaN & infinities", function() + local nan = core.deserialize(core.serialize(0/0)) + assert(nan ~= nan) + assert_preserves(math.huge) + assert_preserves(-math.huge) + end) + + it("handles precise numbers", function() + assert_preserves(0.2695949158945771) + end) + + it("handles big integers", function() + assert_preserves(269594915894577) + end) + + it("handles recursive structures", function() + local test_in = { hello = "world" } + test_in.foo = test_in + assert_preserves(test_in) + end) + + it("handles cross-referencing structures", function() + local test_in = { + foo = { + baz = { + {} + }, + }, + bar = { + baz = {}, + }, + } + + test_in.foo.baz[1].foo = test_in.foo + test_in.foo.baz[1].bar = test_in.bar + test_in.bar.baz[1] = test_in.foo.baz[1] + + assert_preserves(test_in) + end) + + it("strips functions in safe mode", function() + local test_in = { + func = function(a, b) + error("test") + end, + foo = "bar" + } + setfenv(test_in.func, _G) + + local str = core.serialize(test_in) + assert.not_nil(str:find("loadstring")) + + local test_out = core.deserialize(str, true) + assert.is_nil(test_out.func) + assert.equals(test_out.foo, "bar") + end) + + it("vectors work", function() + local v = vector.new(1, 2, 3) + assert_preserves({v}) + assert_preserves(v) + + -- abuse + v = vector.new(1, 2, 3) + v.a = "bla" + assert_preserves(v) + end) + + it("handles keywords as keys", function() + assert_preserves({["and"] = "keyword", ["for"] = "keyword"}) + end) + + describe("fuzzing", function() + local atomics = {true, false, math.huge, -math.huge} -- no NaN or nil + local function atomic() + return atomics[math.random(1, #atomics)] + end + local function num() + local sign = math.random() < 0.5 and -1 or 1 + -- HACK math.random(a, b) requires a, b & b - a to fit within a 32-bit int + -- Use two random calls to generate a random number from 0 - 2^50 as lower & upper 25 bits + local val = math.random(0, 2^25) * 2^25 + math.random(0, 2^25 - 1) + local exp = math.random() < 0.5 and 1 or 2^(math.random(-120, 120)) + return sign * val * exp + end + local function charcodes(count) + if count == 0 then return end + return math.random(0, 0xFF), charcodes(count - 1) + end + local function str() + return string.char(charcodes(math.random(0, 100))) + end + local primitives = {atomic, num, str} + local function primitive() + return primitives[math.random(1, #primitives)]() + end + local function tab(max_actions) + local root = {} + local tables = {root} + local function random_table() + return tables[math.random(1, #tables)] + end + for _ = 1, math.random(1, max_actions) do + local tab = random_table() + local value + if math.random() < 0.5 then + if math.random() < 0.5 then + value = random_table() + else + value = {} + table.insert(tables, value) + end + else + value = primitive() + end + tab[math.random() < 0.5 and (#tab + 1) or primitive()] = value + end + return root + end + it("primitives work", function() + for _ = 1, 1e3 do + assert_preserves(primitive()) + end + end) + it("tables work", function() + for _ = 1, 100 do + local fuzzed_table = tab(1e3) + assert_same(fuzzed_table, table.copy(fuzzed_table)) + assert_preserves(fuzzed_table) + end + end) + end) +end) diff --git a/builtin/common/tests/vector_spec.lua b/builtin/common/tests/vector_spec.lua new file mode 100644 index 0000000..6a0b81a --- /dev/null +++ b/builtin/common/tests/vector_spec.lua @@ -0,0 +1,465 @@ +_G.vector = {metatable = {}} +dofile("builtin/common/vector.lua") + +describe("vector", function() + describe("new()", function() + it("constructs", function() + assert.same({x = 0, y = 0, z = 0}, vector.new()) + assert.same({x = 1, y = 2, z = 3}, vector.new(1, 2, 3)) + assert.same({x = 3, y = 2, z = 1}, vector.new({x = 3, y = 2, z = 1})) + + assert.is_true(vector.check(vector.new())) + assert.is_true(vector.check(vector.new(1, 2, 3))) + assert.is_true(vector.check(vector.new({x = 3, y = 2, z = 1}))) + + local input = vector.new({ x = 3, y = 2, z = 1 }) + local output = vector.new(input) + assert.same(input, output) + assert.equal(input, output) + assert.is_false(rawequal(input, output)) + assert.equal(input, input:new()) + end) + + it("throws on invalid input", function() + assert.has.errors(function() + vector.new({ x = 3 }) + end) + + assert.has.errors(function() + vector.new({ d = 3 }) + end) + end) + end) + + it("zero()", function() + assert.same({x = 0, y = 0, z = 0}, vector.zero()) + assert.same(vector.new(), vector.zero()) + assert.equal(vector.new(), vector.zero()) + assert.is_true(vector.check(vector.zero())) + end) + + it("copy()", function() + local v = vector.new(1, 2, 3) + assert.same(v, vector.copy(v)) + assert.same(vector.new(v), vector.copy(v)) + assert.equal(vector.new(v), vector.copy(v)) + assert.is_true(vector.check(vector.copy(v))) + end) + + it("indexes", function() + local some_vector = vector.new(24, 42, 13) + assert.equal(24, some_vector[1]) + assert.equal(24, some_vector.x) + assert.equal(42, some_vector[2]) + assert.equal(42, some_vector.y) + assert.equal(13, some_vector[3]) + assert.equal(13, some_vector.z) + + some_vector[1] = 100 + assert.equal(100, some_vector.x) + some_vector.x = 101 + assert.equal(101, some_vector[1]) + + some_vector[2] = 100 + assert.equal(100, some_vector.y) + some_vector.y = 102 + assert.equal(102, some_vector[2]) + + some_vector[3] = 100 + assert.equal(100, some_vector.z) + some_vector.z = 103 + assert.equal(103, some_vector[3]) + end) + + it("direction()", function() + local a = vector.new(1, 0, 0) + local b = vector.new(1, 42, 0) + assert.equal(vector.new(0, 1, 0), vector.direction(a, b)) + assert.equal(vector.new(0, 1, 0), a:direction(b)) + end) + + it("distance()", function() + local a = vector.new(1, 0, 0) + local b = vector.new(3, 42, 9) + assert.is_true(math.abs(43 - vector.distance(a, b)) < 1.0e-12) + assert.is_true(math.abs(43 - a:distance(b)) < 1.0e-12) + assert.equal(0, vector.distance(a, a)) + assert.equal(0, b:distance(b)) + end) + + it("length()", function() + local a = vector.new(0, 0, -23) + assert.equal(0, vector.length(vector.new())) + assert.equal(23, vector.length(a)) + assert.equal(23, a:length()) + end) + + it("normalize()", function() + local a = vector.new(0, 0, -23) + assert.equal(vector.new(0, 0, -1), vector.normalize(a)) + assert.equal(vector.new(0, 0, -1), a:normalize()) + assert.equal(vector.new(), vector.normalize(vector.new())) + end) + + it("floor()", function() + local a = vector.new(0.1, 0.9, -0.5) + assert.equal(vector.new(0, 0, -1), vector.floor(a)) + assert.equal(vector.new(0, 0, -1), a:floor()) + end) + + it("round()", function() + local a = vector.new(0.1, 0.9, -0.5) + assert.equal(vector.new(0, 1, -1), vector.round(a)) + assert.equal(vector.new(0, 1, -1), a:round()) + end) + + it("apply()", function() + local i = 0 + local f = function(x) + i = i + 1 + return x + i + end + local a = vector.new(0.1, 0.9, -0.5) + assert.equal(vector.new(1, 1, 0), vector.apply(a, math.ceil)) + assert.equal(vector.new(1, 1, 0), a:apply(math.ceil)) + assert.equal(vector.new(0.1, 0.9, 0.5), vector.apply(a, math.abs)) + assert.equal(vector.new(0.1, 0.9, 0.5), a:apply(math.abs)) + assert.equal(vector.new(1.1, 2.9, 2.5), vector.apply(a, f)) + assert.equal(vector.new(4.1, 5.9, 5.5), a:apply(f)) + end) + + it("combine()", function() + local a = vector.new(1, 2, 3) + local b = vector.new(3, 2, 1) + assert.equal(vector.add(a, b), vector.combine(a, b, function(x, y) return x + y end)) + assert.equal(vector.new(3, 2, 3), vector.combine(a, b, math.max)) + assert.equal(vector.new(1, 2, 1), vector.combine(a, b, math.min)) + end) + + it("equals()", function() + local function assertE(a, b) + assert.is_true(vector.equals(a, b)) + end + local function assertNE(a, b) + assert.is_false(vector.equals(a, b)) + end + + assertE({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0}) + assertE({x = -1, y = 0, z = 1}, {x = -1, y = 0, z = 1}) + assertE({x = -1, y = 0, z = 1}, vector.new(-1, 0, 1)) + local a = {x = 2, y = 4, z = -10} + assertE(a, a) + assertNE({x = -1, y = 0, z = 1}, a) + + assert.equal(vector.new(1, 2, 3), vector.new(1, 2, 3)) + assert.is_true(vector.new(1, 2, 3):equals(vector.new(1, 2, 3))) + assert.not_equal(vector.new(1, 2, 3), vector.new(1, 2, 4)) + assert.is_true(vector.new(1, 2, 3) == vector.new(1, 2, 3)) + assert.is_false(vector.new(1, 2, 3) == vector.new(1, 3, 3)) + end) + + it("metatable is same", function() + local a = vector.new() + local b = vector.new(1, 2, 3) + + assert.equal(true, vector.check(a)) + assert.equal(true, vector.check(b)) + + assert.equal(vector.metatable, getmetatable(a)) + assert.equal(vector.metatable, getmetatable(b)) + assert.equal(vector.metatable, a.metatable) + end) + + it("sort()", function() + local a = vector.new(1, 2, 3) + local b = vector.new(0.5, 232, -2) + local sorted = {vector.new(0.5, 2, -2), vector.new(1, 232, 3)} + assert.same(sorted, {vector.sort(a, b)}) + assert.same(sorted, {a:sort(b)}) + end) + + it("angle()", function() + assert.equal(math.pi, vector.angle(vector.new(-1, -2, -3), vector.new(1, 2, 3))) + assert.equal(math.pi/2, vector.new(0, 1, 0):angle(vector.new(1, 0, 0))) + end) + + it("dot()", function() + assert.equal(-14, vector.dot(vector.new(-1, -2, -3), vector.new(1, 2, 3))) + assert.equal(0, vector.new():dot(vector.new(1, 2, 3))) + end) + + it("cross()", function() + local a = vector.new(-1, -2, 0) + local b = vector.new(1, 2, 3) + assert.equal(vector.new(-6, 3, 0), vector.cross(a, b)) + assert.equal(vector.new(-6, 3, 0), a:cross(b)) + end) + + it("offset()", function() + assert.same({x = 41, y = 52, z = 63}, vector.offset(vector.new(1, 2, 3), 40, 50, 60)) + assert.equal(vector.new(41, 52, 63), vector.offset(vector.new(1, 2, 3), 40, 50, 60)) + assert.equal(vector.new(41, 52, 63), vector.new(1, 2, 3):offset(40, 50, 60)) + end) + + it("is()", function() + local some_table1 = {foo = 13, [42] = 1, "bar", 2} + local some_table2 = {1, 2, 3} + local some_table3 = {x = 1, 2, 3} + local some_table4 = {1, 2, z = 3} + local old = {x = 1, y = 2, z = 3} + local real = vector.new(1, 2, 3) + + assert.is_false(vector.check(nil)) + assert.is_false(vector.check(1)) + assert.is_false(vector.check(true)) + assert.is_false(vector.check("foo")) + assert.is_false(vector.check(some_table1)) + assert.is_false(vector.check(some_table2)) + assert.is_false(vector.check(some_table3)) + assert.is_false(vector.check(some_table4)) + assert.is_false(vector.check(old)) + assert.is_true(vector.check(real)) + assert.is_true(real:check()) + end) + + it("global pairs", function() + local out = {} + local vec = vector.new(10, 20, 30) + for k, v in pairs(vec) do + out[k] = v + end + assert.same({x = 10, y = 20, z = 30}, out) + end) + + it("abusing works", function() + local v = vector.new(1, 2, 3) + v.a = 1 + assert.equal(1, v.a) + + local a_is_there = false + for key, value in pairs(v) do + if key == "a" then + a_is_there = true + assert.equal(value, 1) + break + end + end + assert.is_true(a_is_there) + end) + + it("add()", function() + local a = vector.new(1, 2, 3) + local b = vector.new(1, 4, 3) + local c = vector.new(2, 6, 6) + assert.equal(c, vector.add(a, {x = 1, y = 4, z = 3})) + assert.equal(c, vector.add(a, b)) + assert.equal(c, a:add(b)) + assert.equal(c, a + b) + assert.equal(c, b + a) + end) + + it("subtract()", function() + local a = vector.new(1, 2, 3) + local b = vector.new(2, 4, 3) + local c = vector.new(-1, -2, 0) + assert.equal(c, vector.subtract(a, {x = 2, y = 4, z = 3})) + assert.equal(c, vector.subtract(a, b)) + assert.equal(c, a:subtract(b)) + assert.equal(c, a - b) + assert.equal(c, -b + a) + end) + + it("multiply()", function() + local a = vector.new(1, 2, 3) + local b = vector.new(2, 4, 3) + local c = vector.new(2, 8, 9) + local s = 2 + local d = vector.new(2, 4, 6) + assert.equal(c, vector.multiply(a, {x = 2, y = 4, z = 3})) + assert.equal(c, vector.multiply(a, b)) + assert.equal(d, vector.multiply(a, s)) + assert.equal(d, a:multiply(s)) + assert.equal(d, a * s) + assert.equal(d, s * a) + assert.equal(-a, -1 * a) + end) + + it("divide()", function() + local a = vector.new(1, 2, 3) + local b = vector.new(2, 4, 3) + local c = vector.new(0.5, 0.5, 1) + local s = 2 + local d = vector.new(0.5, 1, 1.5) + assert.equal(c, vector.divide(a, {x = 2, y = 4, z = 3})) + assert.equal(c, vector.divide(a, b)) + assert.equal(d, vector.divide(a, s)) + assert.equal(d, a:divide(s)) + assert.equal(d, a / s) + assert.equal(d, 1/s * a) + assert.equal(-a, a / -1) + end) + + it("to_string()", function() + local v = vector.new(1, 2, 3.14) + assert.same("(1, 2, 3.14)", vector.to_string(v)) + assert.same("(1, 2, 3.14)", v:to_string()) + assert.same("(1, 2, 3.14)", tostring(v)) + end) + + it("from_string()", function() + local v = vector.new(1, 2, 3.14) + assert.is_true(vector.check(vector.from_string("(1, 2, 3.14)"))) + assert.same({v, 13}, {vector.from_string("(1, 2, 3.14)")}) + assert.same({v, 12}, {vector.from_string("(1,2 ,3.14)")}) + assert.same({v, 12}, {vector.from_string("(1,2,3.14,)")}) + assert.same({v, 11}, {vector.from_string("(1 2 3.14)")}) + assert.same({v, 15}, {vector.from_string("( 1, 2, 3.14 )")}) + assert.same({v, 15}, {vector.from_string(" ( 1, 2, 3.14) ")}) + assert.same({vector.new(), 8}, {vector.from_string("(0,0,0) ( 1, 2, 3.14) ")}) + assert.same({v, 22}, {vector.from_string("(0,0,0) ( 1, 2, 3.14) ", 8)}) + assert.same({v, 22}, {vector.from_string("(0,0,0) ( 1, 2, 3.14) ", 9)}) + assert.same(nil, vector.from_string("nothing")) + end) + + -- This function is needed because of floating point imprecision. + local function almost_equal(a, b) + if type(a) == "number" then + return math.abs(a - b) < 0.00000000001 + end + return vector.distance(a, b) < 0.000000000001 + end + + describe("rotate_around_axis()", function() + it("rotates", function() + assert.True(almost_equal({x = -1, y = 0, z = 0}, + vector.rotate_around_axis({x = 1, y = 0, z = 0}, {x = 0, y = 1, z = 0}, math.pi))) + assert.True(almost_equal({x = 0, y = 1, z = 0}, + vector.rotate_around_axis({x = 0, y = 0, z = 1}, {x = 1, y = 0, z = 0}, math.pi / 2))) + assert.True(almost_equal({x = 4, y = 1, z = 1}, + vector.rotate_around_axis({x = 4, y = 1, z = 1}, {x = 4, y = 1, z = 1}, math.pi / 6))) + end) + it("keeps distance to axis", function() + local rotate1 = {x = 1, y = 3, z = 1} + local axis1 = {x = 1, y = 3, z = 2} + local rotated1 = vector.rotate_around_axis(rotate1, axis1, math.pi / 13) + assert.True(almost_equal(vector.distance(axis1, rotate1), vector.distance(axis1, rotated1))) + local rotate2 = {x = 1, y = 1, z = 3} + local axis2 = {x = 2, y = 6, z = 100} + local rotated2 = vector.rotate_around_axis(rotate2, axis2, math.pi / 23) + assert.True(almost_equal(vector.distance(axis2, rotate2), vector.distance(axis2, rotated2))) + local rotate3 = {x = 1, y = -1, z = 3} + local axis3 = {x = 2, y = 6, z = 100} + local rotated3 = vector.rotate_around_axis(rotate3, axis3, math.pi / 2) + assert.True(almost_equal(vector.distance(axis3, rotate3), vector.distance(axis3, rotated3))) + end) + it("rotates back", function() + local rotate1 = {x = 1, y = 3, z = 1} + local axis1 = {x = 1, y = 3, z = 2} + local rotated1 = vector.rotate_around_axis(rotate1, axis1, math.pi / 13) + rotated1 = vector.rotate_around_axis(rotated1, axis1, -math.pi / 13) + assert.True(almost_equal(rotate1, rotated1)) + local rotate2 = {x = 1, y = 1, z = 3} + local axis2 = {x = 2, y = 6, z = 100} + local rotated2 = vector.rotate_around_axis(rotate2, axis2, math.pi / 23) + rotated2 = vector.rotate_around_axis(rotated2, axis2, -math.pi / 23) + assert.True(almost_equal(rotate2, rotated2)) + local rotate3 = {x = 1, y = -1, z = 3} + local axis3 = {x = 2, y = 6, z = 100} + local rotated3 = vector.rotate_around_axis(rotate3, axis3, math.pi / 2) + rotated3 = vector.rotate_around_axis(rotated3, axis3, -math.pi / 2) + assert.True(almost_equal(rotate3, rotated3)) + end) + it("is right handed", function() + local v_before1 = {x = 0, y = 1, z = -1} + local v_after1 = vector.rotate_around_axis(v_before1, {x = 1, y = 0, z = 0}, math.pi / 4) + assert.True(almost_equal(vector.normalize(vector.cross(v_after1, v_before1)), {x = 1, y = 0, z = 0})) + + local v_before2 = {x = 0, y = 3, z = 4} + local v_after2 = vector.rotate_around_axis(v_before2, {x = 1, y = 0, z = 0}, 2 * math.pi / 5) + assert.True(almost_equal(vector.normalize(vector.cross(v_after2, v_before2)), {x = 1, y = 0, z = 0})) + + local v_before3 = {x = 1, y = 0, z = -1} + local v_after3 = vector.rotate_around_axis(v_before3, {x = 0, y = 1, z = 0}, math.pi / 4) + assert.True(almost_equal(vector.normalize(vector.cross(v_after3, v_before3)), {x = 0, y = 1, z = 0})) + + local v_before4 = {x = 3, y = 0, z = 4} + local v_after4 = vector.rotate_around_axis(v_before4, {x = 0, y = 1, z = 0}, 2 * math.pi / 5) + assert.True(almost_equal(vector.normalize(vector.cross(v_after4, v_before4)), {x = 0, y = 1, z = 0})) + + local v_before5 = {x = 1, y = -1, z = 0} + local v_after5 = vector.rotate_around_axis(v_before5, {x = 0, y = 0, z = 1}, math.pi / 4) + assert.True(almost_equal(vector.normalize(vector.cross(v_after5, v_before5)), {x = 0, y = 0, z = 1})) + + local v_before6 = {x = 3, y = 4, z = 0} + local v_after6 = vector.rotate_around_axis(v_before6, {x = 0, y = 0, z = 1}, 2 * math.pi / 5) + assert.True(almost_equal(vector.normalize(vector.cross(v_after6, v_before6)), {x = 0, y = 0, z = 1})) + end) + end) + + describe("rotate()", function() + it("rotates", function() + assert.True(almost_equal({x = -1, y = 0, z = 0}, + vector.rotate({x = 1, y = 0, z = 0}, {x = 0, y = math.pi, z = 0}))) + assert.True(almost_equal({x = 0, y = -1, z = 0}, + vector.rotate({x = 1, y = 0, z = 0}, {x = 0, y = 0, z = math.pi / 2}))) + assert.True(almost_equal({x = 1, y = 0, z = 0}, + vector.rotate({x = 1, y = 0, z = 0}, {x = math.pi / 123, y = 0, z = 0}))) + end) + it("is counterclockwise", function() + local v_before1 = {x = 0, y = 1, z = -1} + local v_after1 = vector.rotate(v_before1, {x = math.pi / 4, y = 0, z = 0}) + assert.True(almost_equal(vector.normalize(vector.cross(v_after1, v_before1)), {x = 1, y = 0, z = 0})) + + local v_before2 = {x = 0, y = 3, z = 4} + local v_after2 = vector.rotate(v_before2, {x = 2 * math.pi / 5, y = 0, z = 0}) + assert.True(almost_equal(vector.normalize(vector.cross(v_after2, v_before2)), {x = 1, y = 0, z = 0})) + + local v_before3 = {x = 1, y = 0, z = -1} + local v_after3 = vector.rotate(v_before3, {x = 0, y = math.pi / 4, z = 0}) + assert.True(almost_equal(vector.normalize(vector.cross(v_after3, v_before3)), {x = 0, y = 1, z = 0})) + + local v_before4 = {x = 3, y = 0, z = 4} + local v_after4 = vector.rotate(v_before4, {x = 0, y = 2 * math.pi / 5, z = 0}) + assert.True(almost_equal(vector.normalize(vector.cross(v_after4, v_before4)), {x = 0, y = 1, z = 0})) + + local v_before5 = {x = 1, y = -1, z = 0} + local v_after5 = vector.rotate(v_before5, {x = 0, y = 0, z = math.pi / 4}) + assert.True(almost_equal(vector.normalize(vector.cross(v_after5, v_before5)), {x = 0, y = 0, z = 1})) + + local v_before6 = {x = 3, y = 4, z = 0} + local v_after6 = vector.rotate(v_before6, {x = 0, y = 0, z = 2 * math.pi / 5}) + assert.True(almost_equal(vector.normalize(vector.cross(v_after6, v_before6)), {x = 0, y = 0, z = 1})) + end) + end) + + it("dir_to_rotation()", function() + -- Comparing rotations (pitch, yaw, roll) is hard because of certain ambiguities, + -- e.g. (pi, 0, pi) looks exactly the same as (0, pi, 0) + -- So instead we convert the rotation back to vectors and compare these. + local function forward_at_rot(rot) + return vector.rotate(vector.new(0, 0, 1), rot) + end + local function up_at_rot(rot) + return vector.rotate(vector.new(0, 1, 0), rot) + end + local rot1 = vector.dir_to_rotation({x = 1, y = 0, z = 0}, {x = 0, y = 1, z = 0}) + assert.True(almost_equal({x = 1, y = 0, z = 0}, forward_at_rot(rot1))) + assert.True(almost_equal({x = 0, y = 1, z = 0}, up_at_rot(rot1))) + local rot2 = vector.dir_to_rotation({x = 1, y = 1, z = 0}, {x = 0, y = 0, z = 1}) + assert.True(almost_equal({x = 1/math.sqrt(2), y = 1/math.sqrt(2), z = 0}, forward_at_rot(rot2))) + assert.True(almost_equal({x = 0, y = 0, z = 1}, up_at_rot(rot2))) + for i = 1, 1000 do + local rand_vec = vector.new(math.random(), math.random(), math.random()) + if vector.length(rand_vec) ~= 0 then + local rot_1 = vector.dir_to_rotation(rand_vec) + local rot_2 = { + x = math.atan2(rand_vec.y, math.sqrt(rand_vec.z * rand_vec.z + rand_vec.x * rand_vec.x)), + y = -math.atan2(rand_vec.x, rand_vec.z), + z = 0 + } + assert.True(almost_equal(rot_1, rot_2)) + end + end + + end) +end) diff --git a/builtin/common/vector.lua b/builtin/common/vector.lua new file mode 100644 index 0000000..a08472e --- /dev/null +++ b/builtin/common/vector.lua @@ -0,0 +1,368 @@ +--[[ +Vector helpers +Note: The vector.*-functions must be able to accept old vectors that had no metatables +]] + +-- localize functions +local setmetatable = setmetatable + +-- vector.metatable is set by C++. +local metatable = vector.metatable + +local xyz = {"x", "y", "z"} + +-- only called when rawget(v, key) returns nil +function metatable.__index(v, key) + return rawget(v, xyz[key]) or vector[key] +end + +-- only called when rawget(v, key) returns nil +function metatable.__newindex(v, key, value) + rawset(v, xyz[key] or key, value) +end + +-- constructors + +local function fast_new(x, y, z) + return setmetatable({x = x, y = y, z = z}, metatable) +end + +function vector.new(a, b, c) + if a and b and c then + return fast_new(a, b, c) + end + + -- deprecated, use vector.copy and vector.zero directly + if type(a) == "table" then + return vector.copy(a) + else + assert(not a, "Invalid arguments for vector.new()") + return vector.zero() + end +end + +function vector.zero() + return fast_new(0, 0, 0) +end + +function vector.copy(v) + assert(v.x and v.y and v.z, "Invalid vector passed to vector.copy()") + return fast_new(v.x, v.y, v.z) +end + +function vector.from_string(s, init) + local x, y, z, np = string.match(s, "^%s*%(%s*([^%s,]+)%s*[,%s]%s*([^%s,]+)%s*[,%s]" .. + "%s*([^%s,]+)%s*[,%s]?%s*%)()", init) + x = tonumber(x) + y = tonumber(y) + z = tonumber(z) + if not (x and y and z) then + return nil + end + return fast_new(x, y, z), np +end + +function vector.to_string(v) + return string.format("(%g, %g, %g)", v.x, v.y, v.z) +end +metatable.__tostring = vector.to_string + +function vector.equals(a, b) + return a.x == b.x and + a.y == b.y and + a.z == b.z +end +metatable.__eq = vector.equals + +-- unary operations + +function vector.length(v) + return math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z) +end +-- Note: we can not use __len because it is already used for primitive table length + +function vector.normalize(v) + local len = vector.length(v) + if len == 0 then + return fast_new(0, 0, 0) + else + return vector.divide(v, len) + end +end + +function vector.floor(v) + return vector.apply(v, math.floor) +end + +function vector.round(v) + return fast_new( + math.round(v.x), + math.round(v.y), + math.round(v.z) + ) +end + +function vector.apply(v, func) + return fast_new( + func(v.x), + func(v.y), + func(v.z) + ) +end + +function vector.combine(a, b, func) + return fast_new( + func(a.x, b.x), + func(a.y, b.y), + func(a.z, b.z) + ) +end + +function vector.distance(a, b) + local x = a.x - b.x + local y = a.y - b.y + local z = a.z - b.z + return math.sqrt(x * x + y * y + z * z) +end + +function vector.direction(pos1, pos2) + return vector.subtract(pos2, pos1):normalize() +end + +function vector.angle(a, b) + local dotp = vector.dot(a, b) + local cp = vector.cross(a, b) + local crossplen = vector.length(cp) + return math.atan2(crossplen, dotp) +end + +function vector.dot(a, b) + return a.x * b.x + a.y * b.y + a.z * b.z +end + +function vector.cross(a, b) + return fast_new( + a.y * b.z - a.z * b.y, + a.z * b.x - a.x * b.z, + a.x * b.y - a.y * b.x + ) +end + +function metatable.__unm(v) + return fast_new(-v.x, -v.y, -v.z) +end + +-- add, sub, mul, div operations + +function vector.add(a, b) + if type(b) == "table" then + return fast_new( + a.x + b.x, + a.y + b.y, + a.z + b.z + ) + else + return fast_new( + a.x + b, + a.y + b, + a.z + b + ) + end +end +function metatable.__add(a, b) + return fast_new( + a.x + b.x, + a.y + b.y, + a.z + b.z + ) +end + +function vector.subtract(a, b) + if type(b) == "table" then + return fast_new( + a.x - b.x, + a.y - b.y, + a.z - b.z + ) + else + return fast_new( + a.x - b, + a.y - b, + a.z - b + ) + end +end +function metatable.__sub(a, b) + return fast_new( + a.x - b.x, + a.y - b.y, + a.z - b.z + ) +end + +function vector.multiply(a, b) + if type(b) == "table" then + return fast_new( + a.x * b.x, + a.y * b.y, + a.z * b.z + ) + else + return fast_new( + a.x * b, + a.y * b, + a.z * b + ) + end +end +function metatable.__mul(a, b) + if type(a) == "table" then + return fast_new( + a.x * b, + a.y * b, + a.z * b + ) + else + return fast_new( + a * b.x, + a * b.y, + a * b.z + ) + end +end + +function vector.divide(a, b) + if type(b) == "table" then + return fast_new( + a.x / b.x, + a.y / b.y, + a.z / b.z + ) + else + return fast_new( + a.x / b, + a.y / b, + a.z / b + ) + end +end +function metatable.__div(a, b) + -- scalar/vector makes no sense + return fast_new( + a.x / b, + a.y / b, + a.z / b + ) +end + +-- misc stuff + +function vector.offset(v, x, y, z) + return fast_new( + v.x + x, + v.y + y, + v.z + z + ) +end + +function vector.sort(a, b) + return fast_new(math.min(a.x, b.x), math.min(a.y, b.y), math.min(a.z, b.z)), + fast_new(math.max(a.x, b.x), math.max(a.y, b.y), math.max(a.z, b.z)) +end + +function vector.check(v) + return getmetatable(v) == metatable +end + +local function sin(x) + if x % math.pi == 0 then + return 0 + else + return math.sin(x) + end +end + +local function cos(x) + if x % math.pi == math.pi / 2 then + return 0 + else + return math.cos(x) + end +end + +function vector.rotate_around_axis(v, axis, angle) + local cosangle = cos(angle) + local sinangle = sin(angle) + axis = vector.normalize(axis) + -- https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula + local dot_axis = vector.multiply(axis, vector.dot(axis, v)) + local cross = vector.cross(v, axis) + return vector.new( + cross.x * sinangle + (v.x - dot_axis.x) * cosangle + dot_axis.x, + cross.y * sinangle + (v.y - dot_axis.y) * cosangle + dot_axis.y, + cross.z * sinangle + (v.z - dot_axis.z) * cosangle + dot_axis.z + ) +end + +function vector.rotate(v, rot) + local sinpitch = sin(-rot.x) + local sinyaw = sin(-rot.y) + local sinroll = sin(-rot.z) + local cospitch = cos(rot.x) + local cosyaw = cos(rot.y) + local cosroll = math.cos(rot.z) + -- Rotation matrix that applies yaw, pitch and roll + local matrix = { + { + sinyaw * sinpitch * sinroll + cosyaw * cosroll, + sinyaw * sinpitch * cosroll - cosyaw * sinroll, + sinyaw * cospitch, + }, + { + cospitch * sinroll, + cospitch * cosroll, + -sinpitch, + }, + { + cosyaw * sinpitch * sinroll - sinyaw * cosroll, + cosyaw * sinpitch * cosroll + sinyaw * sinroll, + cosyaw * cospitch, + }, + } + -- Compute matrix multiplication: `matrix` * `v` + return vector.new( + matrix[1][1] * v.x + matrix[1][2] * v.y + matrix[1][3] * v.z, + matrix[2][1] * v.x + matrix[2][2] * v.y + matrix[2][3] * v.z, + matrix[3][1] * v.x + matrix[3][2] * v.y + matrix[3][3] * v.z + ) +end + +function vector.dir_to_rotation(forward, up) + forward = vector.normalize(forward) + local rot = vector.new(math.asin(forward.y), -math.atan2(forward.x, forward.z), 0) + if not up then + return rot + end + assert(vector.dot(forward, up) < 0.000001, + "Invalid vectors passed to vector.dir_to_rotation().") + up = vector.normalize(up) + -- Calculate vector pointing up with roll = 0, just based on forward vector. + local forwup = vector.rotate(vector.new(0, 1, 0), rot) + -- 'forwup' and 'up' are now in a plane with 'forward' as normal. + -- The angle between them is the absolute of the roll value we're looking for. + rot.z = vector.angle(forwup, up) + + -- Since vector.angle never returns a negative value or a value greater + -- than math.pi, rot.z has to be inverted sometimes. + -- To determine wether this is the case, we rotate the up vector back around + -- the forward vector and check if it worked out. + local back = vector.rotate_around_axis(up, forward, -rot.z) + + -- We don't use vector.equals for this because of floating point imprecision. + if (back.x - forwup.x) * (back.x - forwup.x) + + (back.y - forwup.y) * (back.y - forwup.y) + + (back.z - forwup.z) * (back.z - forwup.z) > 0.0000001 then + rot.z = -rot.z + end + return rot +end diff --git a/builtin/fstk/buttonbar.lua b/builtin/fstk/buttonbar.lua new file mode 100644 index 0000000..4655883 --- /dev/null +++ b/builtin/fstk/buttonbar.lua @@ -0,0 +1,215 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +local function buttonbar_formspec(self) + + if self.hidden then + return "" + end + + local formspec = string.format("box[%f,%f;%f,%f;%s]", + self.pos.x,self.pos.y ,self.size.x,self.size.y,self.bgcolor) + + for i=self.startbutton,#self.buttons,1 do + local btn_name = self.buttons[i].name + local btn_pos = {} + + if self.orientation == "horizontal" then + btn_pos.x = self.pos.x + --base pos + (i - self.startbutton) * self.btn_size + --button offset + self.btn_initial_offset + else + btn_pos.x = self.pos.x + (self.btn_size * 0.05) + end + + if self.orientation == "vertical" then + btn_pos.y = self.pos.y + --base pos + (i - self.startbutton) * self.btn_size + --button offset + self.btn_initial_offset + else + btn_pos.y = self.pos.y + (self.btn_size * 0.05) + end + + if (self.orientation == "vertical" and + (btn_pos.y + self.btn_size <= self.pos.y + self.size.y)) or + (self.orientation == "horizontal" and + (btn_pos.x + self.btn_size <= self.pos.x + self.size.x)) then + + local borders="true" + + if self.buttons[i].image ~= nil then + borders="false" + end + + formspec = formspec .. + string.format("image_button[%f,%f;%f,%f;%s;%s;%s;true;%s]tooltip[%s;%s]", + btn_pos.x, btn_pos.y, self.btn_size, self.btn_size, + self.buttons[i].image, btn_name, self.buttons[i].caption, + borders, btn_name, self.buttons[i].tooltip) + else + --print("end of displayable buttons: orientation: " .. self.orientation) + --print( "button_end: " .. (btn_pos.y + self.btn_size - (self.btn_size * 0.05))) + --print( "bar_end: " .. (self.pos.x + self.size.x)) + break + end + end + + if (self.have_move_buttons) then + local btn_dec_pos = {} + btn_dec_pos.x = self.pos.x + (self.btn_size * 0.05) + btn_dec_pos.y = self.pos.y + (self.btn_size * 0.05) + local btn_inc_pos = {} + local btn_size = {} + + if self.orientation == "horizontal" then + btn_size.x = 0.5 + btn_size.y = self.btn_size + btn_inc_pos.x = self.pos.x + self.size.x - 0.5 + btn_inc_pos.y = self.pos.y + (self.btn_size * 0.05) + else + btn_size.x = self.btn_size + btn_size.y = 0.5 + btn_inc_pos.x = self.pos.x + (self.btn_size * 0.05) + btn_inc_pos.y = self.pos.y + self.size.y - 0.5 + end + + local text_dec = "<" + local text_inc = ">" + if self.orientation == "vertical" then + text_dec = "^" + text_inc = "v" + end + + formspec = formspec .. + string.format("image_button[%f,%f;%f,%f;;btnbar_dec_%s;%s;true;true]", + btn_dec_pos.x, btn_dec_pos.y, btn_size.x, btn_size.y, + self.name, text_dec) + + formspec = formspec .. + string.format("image_button[%f,%f;%f,%f;;btnbar_inc_%s;%s;true;true]", + btn_inc_pos.x, btn_inc_pos.y, btn_size.x, btn_size.y, + self.name, text_inc) + end + + return formspec +end + +local function buttonbar_buttonhandler(self, fields) + + if fields["btnbar_inc_" .. self.name] ~= nil and + self.startbutton < #self.buttons then + + self.startbutton = self.startbutton + 1 + return true + end + + if fields["btnbar_dec_" .. self.name] ~= nil and self.startbutton > 1 then + self.startbutton = self.startbutton - 1 + return true + end + + for i=1,#self.buttons,1 do + if fields[self.buttons[i].name] ~= nil then + return self.userbuttonhandler(fields) + end + end +end + +local buttonbar_metatable = { + handle_buttons = buttonbar_buttonhandler, + handle_events = function(self, event) end, + get_formspec = buttonbar_formspec, + + hide = function(self) self.hidden = true end, + show = function(self) self.hidden = false end, + + delete = function(self) ui.delete(self) end, + + add_button = function(self, name, caption, image, tooltip) + if caption == nil then caption = "" end + if image == nil then image = "" end + if tooltip == nil then tooltip = "" end + + self.buttons[#self.buttons + 1] = { + name = name, + caption = caption, + image = image, + tooltip = tooltip + } + if self.orientation == "horizontal" then + if ( (self.btn_size * #self.buttons) + (self.btn_size * 0.05 *2) + > self.size.x ) then + + self.btn_initial_offset = self.btn_size * 0.05 + 0.5 + self.have_move_buttons = true + end + else + if ((self.btn_size * #self.buttons) + (self.btn_size * 0.05 *2) + > self.size.y ) then + + self.btn_initial_offset = self.btn_size * 0.05 + 0.5 + self.have_move_buttons = true + end + end + end, + + set_bgparams = function(self, bgcolor) + if (type(bgcolor) == "string") then + self.bgcolor = bgcolor + end + end, +} + +buttonbar_metatable.__index = buttonbar_metatable + +function buttonbar_create(name, cbf_buttonhandler, pos, orientation, size) + assert(name ~= nil) + assert(cbf_buttonhandler ~= nil) + assert(orientation == "vertical" or orientation == "horizontal") + assert(pos ~= nil and type(pos) == "table") + assert(size ~= nil and type(size) == "table") + + local self = {} + self.name = name + self.type = "addon" + self.bgcolor = "#000000" + self.pos = pos + self.size = size + self.orientation = orientation + self.startbutton = 1 + self.have_move_buttons = false + self.hidden = false + + if self.orientation == "horizontal" then + self.btn_size = self.size.y + else + self.btn_size = self.size.x + end + + if (self.btn_initial_offset == nil) then + self.btn_initial_offset = self.btn_size * 0.05 + end + + self.userbuttonhandler = cbf_buttonhandler + self.buttons = {} + + setmetatable(self,buttonbar_metatable) + + ui.add(self) + return self +end diff --git a/builtin/fstk/dialog.lua b/builtin/fstk/dialog.lua new file mode 100644 index 0000000..ea57df1 --- /dev/null +++ b/builtin/fstk/dialog.lua @@ -0,0 +1,88 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +local function dialog_event_handler(self,event) + if self.user_eventhandler == nil or + self.user_eventhandler(event) == false then + + --close dialog on esc + if event == "MenuQuit" then + self:delete() + return true + end + end +end + +local dialog_metatable = { + eventhandler = dialog_event_handler, + get_formspec = function(self) + if not self.hidden then return self.formspec(self.data) end + end, + handle_buttons = function(self,fields) + if not self.hidden then return self.buttonhandler(self,fields) end + end, + handle_events = function(self,event) + if not self.hidden then return self.eventhandler(self,event) end + end, + hide = function(self) self.hidden = true end, + show = function(self) self.hidden = false end, + delete = function(self) + if self.parent ~= nil then + self.parent:show() + end + ui.delete(self) + end, + set_parent = function(self,parent) self.parent = parent end +} +dialog_metatable.__index = dialog_metatable + +function dialog_create(name,get_formspec,buttonhandler,eventhandler) + local self = {} + + self.name = name + self.type = "toplevel" + self.hidden = true + self.data = {} + + self.formspec = get_formspec + self.buttonhandler = buttonhandler + self.user_eventhandler = eventhandler + + setmetatable(self,dialog_metatable) + + ui.add(self) + return self +end + +function messagebox(name, message) + return dialog_create(name, + function() + return ([[ + formspec_version[3] + size[8,3] + textarea[0.375,0.375;7.25,1.2;;;%s] + button[3,1.825;2,0.8;ok;%s] + ]]):format(message, fgettext("OK")) + end, + function(this, fields) + if fields.ok then + this:delete() + return true + end + end, + nil) +end diff --git a/builtin/fstk/tabview.lua b/builtin/fstk/tabview.lua new file mode 100644 index 0000000..424d329 --- /dev/null +++ b/builtin/fstk/tabview.lua @@ -0,0 +1,257 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +-------------------------------------------------------------------------------- +-- A tabview implementation -- +-- Usage: -- +-- tabview.create: returns initialized tabview raw element -- +-- element.add(tab): add a tab declaration -- +-- element.handle_buttons() -- +-- element.handle_events() -- +-- element.getFormspec() returns formspec of tabview -- +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- +local function add_tab(self,tab) + assert(tab.size == nil or (type(tab.size) == table and + tab.size.x ~= nil and tab.size.y ~= nil)) + assert(tab.cbf_formspec ~= nil and type(tab.cbf_formspec) == "function") + assert(tab.cbf_button_handler == nil or + type(tab.cbf_button_handler) == "function") + assert(tab.cbf_events == nil or type(tab.cbf_events) == "function") + + local newtab = { + name = tab.name, + caption = tab.caption, + button_handler = tab.cbf_button_handler, + event_handler = tab.cbf_events, + get_formspec = tab.cbf_formspec, + tabsize = tab.tabsize, + on_change = tab.on_change, + tabdata = {}, + } + + self.tablist[#self.tablist + 1] = newtab + + if self.last_tab_index == #self.tablist then + self.current_tab = tab.name + if tab.on_activate ~= nil then + tab.on_activate(nil,tab.name) + end + end +end + +-------------------------------------------------------------------------------- +local function get_formspec(self) + if self.hidden or (self.parent ~= nil and self.parent.hidden) then + return "" + end + local tab = self.tablist[self.last_tab_index] + + local content, prepend = tab.get_formspec(self, tab.name, tab.tabdata, tab.tabsize) + + if self.parent == nil and not prepend then + local tsize = tab.tabsize or {width=self.width, height=self.height} + prepend = string.format("size[%f,%f,%s]", tsize.width, tsize.height, + dump(self.fixed_size)) + end + + local formspec = (prepend or "") .. self:tab_header() .. content + return formspec +end + +-------------------------------------------------------------------------------- +local function handle_buttons(self,fields) + + if self.hidden then + return false + end + + if self:handle_tab_buttons(fields) then + return true + end + + if self.glb_btn_handler ~= nil and + self.glb_btn_handler(self,fields) then + return true + end + + local tab = self.tablist[self.last_tab_index] + if tab.button_handler ~= nil then + return tab.button_handler(self, fields, tab.name, tab.tabdata) + end + + return false +end + +-------------------------------------------------------------------------------- +local function handle_events(self,event) + + if self.hidden then + return false + end + + if self.glb_evt_handler ~= nil and + self.glb_evt_handler(self,event) then + return true + end + + local tab = self.tablist[self.last_tab_index] + if tab.evt_handler ~= nil then + return tab.evt_handler(self, event, tab.name, tab.tabdata) + end + + return false +end + + +-------------------------------------------------------------------------------- +local function tab_header(self) + + local toadd = "" + + for i=1,#self.tablist,1 do + + if toadd ~= "" then + toadd = toadd .. "," + end + + toadd = toadd .. self.tablist[i].caption + end + return string.format("tabheader[%f,%f;%s;%s;%i;true;false]", + self.header_x, self.header_y, self.name, toadd, self.last_tab_index); +end + +-------------------------------------------------------------------------------- +local function switch_to_tab(self, index) + --first call on_change for tab to leave + if self.tablist[self.last_tab_index].on_change ~= nil then + self.tablist[self.last_tab_index].on_change("LEAVE", + self.current_tab, self.tablist[index].name) + end + + --update tabview data + self.last_tab_index = index + local old_tab = self.current_tab + self.current_tab = self.tablist[index].name + + if (self.autosave_tab) then + core.settings:set(self.name .. "_LAST",self.current_tab) + end + + -- call for tab to enter + if self.tablist[index].on_change ~= nil then + self.tablist[index].on_change("ENTER", + old_tab,self.current_tab) + end +end + +-------------------------------------------------------------------------------- +local function handle_tab_buttons(self,fields) + --save tab selection to config file + if fields[self.name] then + local index = tonumber(fields[self.name]) + switch_to_tab(self, index) + return true + end + + return false +end + +-------------------------------------------------------------------------------- +local function set_tab_by_name(self, name) + for i=1,#self.tablist,1 do + if self.tablist[i].name == name then + switch_to_tab(self, i) + return true + end + end + + return false +end + +-------------------------------------------------------------------------------- +local function hide_tabview(self) + self.hidden=true + + --call on_change as we're not gonna show self tab any longer + if self.tablist[self.last_tab_index].on_change ~= nil then + self.tablist[self.last_tab_index].on_change("LEAVE", + self.current_tab, nil) + end +end + +-------------------------------------------------------------------------------- +local function show_tabview(self) + self.hidden=false + + -- call for tab to enter + if self.tablist[self.last_tab_index].on_change ~= nil then + self.tablist[self.last_tab_index].on_change("ENTER", + nil,self.current_tab) + end +end + +local tabview_metatable = { + add = add_tab, + handle_buttons = handle_buttons, + handle_events = handle_events, + get_formspec = get_formspec, + show = show_tabview, + hide = hide_tabview, + delete = function(self) ui.delete(self) end, + set_parent = function(self,parent) self.parent = parent end, + set_autosave_tab = + function(self,value) self.autosave_tab = value end, + set_tab = set_tab_by_name, + set_global_button_handler = + function(self,handler) self.glb_btn_handler = handler end, + set_global_event_handler = + function(self,handler) self.glb_evt_handler = handler end, + set_fixed_size = + function(self,state) self.fixed_size = state end, + tab_header = tab_header, + handle_tab_buttons = handle_tab_buttons +} + +tabview_metatable.__index = tabview_metatable + +-------------------------------------------------------------------------------- +function tabview_create(name, size, tabheaderpos) + local self = {} + + self.name = name + self.type = "toplevel" + self.width = size.x + self.height = size.y + self.header_x = tabheaderpos.x + self.header_y = tabheaderpos.y + + setmetatable(self, tabview_metatable) + + self.fixed_size = true + self.hidden = true + self.current_tab = nil + self.last_tab_index = 1 + self.tablist = {} + + self.autosave_tab = false + + ui.add(self) + return self +end diff --git a/builtin/fstk/ui.lua b/builtin/fstk/ui.lua new file mode 100644 index 0000000..13f9cbe --- /dev/null +++ b/builtin/fstk/ui.lua @@ -0,0 +1,212 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +ui = {} +ui.childlist = {} +ui.default = nil +-- Whether fstk is currently showing its own formspec instead of active ui elements. +ui.overridden = false + +-------------------------------------------------------------------------------- +function ui.add(child) + --TODO check child + ui.childlist[child.name] = child + + return child.name +end + +-------------------------------------------------------------------------------- +function ui.delete(child) + + if ui.childlist[child.name] == nil then + return false + end + + ui.childlist[child.name] = nil + return true +end + +-------------------------------------------------------------------------------- +function ui.set_default(name) + ui.default = name +end + +-------------------------------------------------------------------------------- +function ui.find_by_name(name) + return ui.childlist[name] +end + +-------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- +-- Internal functions not to be called from user +-------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- + +function ui.update() + ui.overridden = false + local formspec = {} + + -- handle errors + if gamedata ~= nil and gamedata.reconnect_requested then + local error_message = core.formspec_escape( + gamedata.errormessage or fgettext("<none available>")) + formspec = { + "size[14,8]", + "real_coordinates[true]", + "set_focus[btn_reconnect_yes;true]", + "box[0.5,1.2;13,5;#000]", + ("textarea[0.5,1.2;13,5;;%s;%s]"):format( + fgettext("The server has requested a reconnect:"), error_message), + "button[2,6.6;4,1;btn_reconnect_yes;" .. fgettext("Reconnect") .. "]", + "button[8,6.6;4,1;btn_reconnect_no;" .. fgettext("Main menu") .. "]" + } + ui.overridden = true + elseif gamedata ~= nil and gamedata.errormessage ~= nil then + local error_message = core.formspec_escape(gamedata.errormessage) + + local error_title + if string.find(gamedata.errormessage, "ModError") then + error_title = fgettext("An error occurred in a Lua script:") + else + error_title = fgettext("An error occurred:") + end + formspec = { + "size[14,8]", + "real_coordinates[true]", + "set_focus[btn_error_confirm;true]", + "box[0.5,1.2;13,5;#000]", + ("textarea[0.5,1.2;13,5;;%s;%s]"):format( + error_title, error_message), + "button[5,6.6;4,1;btn_error_confirm;" .. fgettext("OK") .. "]" + } + ui.overridden = true + else + local active_toplevel_ui_elements = 0 + for key,value in pairs(ui.childlist) do + if (value.type == "toplevel") then + local retval = value:get_formspec() + + if retval ~= nil and retval ~= "" then + active_toplevel_ui_elements = active_toplevel_ui_elements + 1 + table.insert(formspec, retval) + end + end + end + + -- no need to show addons if there ain't a toplevel element + if (active_toplevel_ui_elements > 0) then + for key,value in pairs(ui.childlist) do + if (value.type == "addon") then + local retval = value:get_formspec() + + if retval ~= nil and retval ~= "" then + table.insert(formspec, retval) + end + end + end + end + + if (active_toplevel_ui_elements > 1) then + core.log("warning", "more than one active ui ".. + "element, self most likely isn't intended") + end + + if (active_toplevel_ui_elements == 0) then + core.log("warning", "no toplevel ui element ".. + "active; switching to default") + ui.childlist[ui.default]:show() + formspec = {ui.childlist[ui.default]:get_formspec()} + end + end + core.update_formspec(table.concat(formspec)) +end + +-------------------------------------------------------------------------------- +function ui.handle_buttons(fields) + for key,value in pairs(ui.childlist) do + + local retval = value:handle_buttons(fields) + + if retval then + ui.update() + return + end + end +end + + +-------------------------------------------------------------------------------- +function ui.handle_events(event) + + for key,value in pairs(ui.childlist) do + + if value.handle_events ~= nil then + local retval = value:handle_events(event) + + if retval then + return retval + end + end + end +end + +-------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- +-- initialize callbacks +-------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- +core.button_handler = function(fields) + if fields["btn_reconnect_yes"] then + gamedata.reconnect_requested = false + gamedata.errormessage = nil + gamedata.do_reconnect = true + core.start() + return + elseif fields["btn_reconnect_no"] or fields["btn_error_confirm"] then + gamedata.errormessage = nil + gamedata.reconnect_requested = false + ui.update() + return + end + + if ui.handle_buttons(fields) then + ui.update() + end +end + +-------------------------------------------------------------------------------- +core.event_handler = function(event) + -- Handle error messages + if ui.overridden then + if event == "MenuQuit" then + gamedata.errormessage = nil + gamedata.reconnect_requested = false + ui.update() + end + return + end + + if ui.handle_events(event) then + ui.update() + return + end + + if event == "Refresh" then + ui.update() + return + end +end diff --git a/builtin/game/async.lua b/builtin/game/async.lua new file mode 100644 index 0000000..469f179 --- /dev/null +++ b/builtin/game/async.lua @@ -0,0 +1,22 @@ + +core.async_jobs = {} + +function core.async_event_handler(jobid, retval) + local callback = core.async_jobs[jobid] + assert(type(callback) == "function") + callback(unpack(retval, 1, retval.n)) + core.async_jobs[jobid] = nil +end + +function core.handle_async(func, callback, ...) + assert(type(func) == "function" and type(callback) == "function", + "Invalid minetest.handle_async invocation") + local args = {n = select("#", ...), ...} + local mod_origin = core.get_last_run_mod() + + local jobid = core.do_async_callback(func, args, mod_origin) + core.async_jobs[jobid] = callback + + return true +end + diff --git a/builtin/game/auth.lua b/builtin/game/auth.lua new file mode 100644 index 0000000..e7d502b --- /dev/null +++ b/builtin/game/auth.lua @@ -0,0 +1,185 @@ +-- Minetest: builtin/auth.lua + +-- +-- Builtin authentication handler +-- + +-- Make the auth object private, deny access to mods +local core_auth = core.auth +core.auth = nil + +core.builtin_auth_handler = { + get_auth = function(name) + assert(type(name) == "string") + local auth_entry = core_auth.read(name) + -- If no such auth found, return nil + if not auth_entry then + return nil + end + -- Figure out what privileges the player should have. + -- Take a copy of the privilege table + local privileges = {} + for priv, _ in pairs(auth_entry.privileges) do + privileges[priv] = true + end + -- If singleplayer, give all privileges except those marked as give_to_singleplayer = false + if core.is_singleplayer() then + for priv, def in pairs(core.registered_privileges) do + if def.give_to_singleplayer then + privileges[priv] = true + end + end + -- For the admin, give everything + elseif name == core.settings:get("name") then + for priv, def in pairs(core.registered_privileges) do + if def.give_to_admin then + privileges[priv] = true + end + end + end + -- All done + return { + password = auth_entry.password, + privileges = privileges, + last_login = auth_entry.last_login, + } + end, + create_auth = function(name, password) + assert(type(name) == "string") + assert(type(password) == "string") + core.log('info', "Built-in authentication handler adding player '"..name.."'") + return core_auth.create({ + name = name, + password = password, + privileges = core.string_to_privs(core.settings:get("default_privs")), + last_login = -1, -- Defer login time calculation until record_login (called by on_joinplayer) + }) + end, + delete_auth = function(name) + assert(type(name) == "string") + local auth_entry = core_auth.read(name) + if not auth_entry then + return false + end + core.log('info', "Built-in authentication handler deleting player '"..name.."'") + return core_auth.delete(name) + end, + set_password = function(name, password) + assert(type(name) == "string") + assert(type(password) == "string") + local auth_entry = core_auth.read(name) + if not auth_entry then + core.builtin_auth_handler.create_auth(name, password) + else + core.log('info', "Built-in authentication handler setting password of player '"..name.."'") + auth_entry.password = password + core_auth.save(auth_entry) + end + return true + end, + set_privileges = function(name, privileges) + assert(type(name) == "string") + assert(type(privileges) == "table") + local auth_entry = core_auth.read(name) + if not auth_entry then + auth_entry = core.builtin_auth_handler.create_auth(name, + core.get_password_hash(name, + core.settings:get("default_password"))) + end + + auth_entry.privileges = privileges + + core_auth.save(auth_entry) + + -- Run grant callbacks + for priv, _ in pairs(privileges) do + if not auth_entry.privileges[priv] then + core.run_priv_callbacks(name, priv, nil, "grant") + end + end + + -- Run revoke callbacks + for priv, _ in pairs(auth_entry.privileges) do + if not privileges[priv] then + core.run_priv_callbacks(name, priv, nil, "revoke") + end + end + core.notify_authentication_modified(name) + end, + reload = function() + core_auth.reload() + return true + end, + record_login = function(name) + assert(type(name) == "string") + local auth_entry = core_auth.read(name) + assert(auth_entry) + auth_entry.last_login = os.time() + core_auth.save(auth_entry) + end, + iterate = function() + local names = {} + local nameslist = core_auth.list_names() + for k,v in pairs(nameslist) do + names[v] = true + end + return pairs(names) + end, +} + +core.register_on_prejoinplayer(function(name, ip) + if core.registered_auth_handler ~= nil then + return -- Don't do anything if custom auth handler registered + end + local auth_entry = core_auth.read(name) + if auth_entry ~= nil then + return + end + + local name_lower = name:lower() + for k in core.builtin_auth_handler.iterate() do + if k:lower() == name_lower then + return string.format("\nCannot create new player called '%s'. ".. + "Another account called '%s' is already registered. ".. + "Please check the spelling if it's your account ".. + "or use a different nickname.", name, k) + end + end +end) + +-- +-- Authentication API +-- + +function core.register_authentication_handler(handler) + if core.registered_auth_handler then + error("Add-on authentication handler already registered by "..core.registered_auth_handler_modname) + end + core.registered_auth_handler = handler + core.registered_auth_handler_modname = core.get_current_modname() + handler.mod_origin = core.registered_auth_handler_modname +end + +function core.get_auth_handler() + return core.registered_auth_handler or core.builtin_auth_handler +end + +local function auth_pass(name) + return function(...) + local auth_handler = core.get_auth_handler() + if auth_handler[name] then + return auth_handler[name](...) + end + return false + end +end + +core.set_player_password = auth_pass("set_password") +core.set_player_privs = auth_pass("set_privileges") +core.remove_player_auth = auth_pass("delete_auth") +core.auth_reload = auth_pass("reload") + +local record_login = auth_pass("record_login") +core.register_on_joinplayer(function(player) + record_login(player:get_player_name()) +end) diff --git a/builtin/game/chat.lua b/builtin/game/chat.lua new file mode 100644 index 0000000..bbcdcf2 --- /dev/null +++ b/builtin/game/chat.lua @@ -0,0 +1,1359 @@ +-- Minetest: builtin/game/chat.lua + +local S = core.get_translator("__builtin") + +-- Helper function that implements search and replace without pattern matching +-- Returns the string and a boolean indicating whether or not the string was modified +local function safe_gsub(s, replace, with) + local i1, i2 = s:find(replace, 1, true) + if not i1 then + return s, false + end + + return s:sub(1, i1 - 1) .. with .. s:sub(i2 + 1), true +end + +-- +-- Chat message formatter +-- + +-- Implemented in Lua to allow redefinition +function core.format_chat_message(name, message) + local error_str = "Invalid chat message format - missing %s" + local str = core.settings:get("chat_message_format") + local replaced + + -- Name + str, replaced = safe_gsub(str, "@name", name) + if not replaced then + error(error_str:format("@name"), 2) + end + + -- Timestamp + str = safe_gsub(str, "@timestamp", os.date("%H:%M:%S", os.time())) + + -- Insert the message into the string only after finishing all other processing + str, replaced = safe_gsub(str, "@message", message) + if not replaced then + error(error_str:format("@message"), 2) + end + + return str +end + +-- +-- Chat command handler +-- + +core.chatcommands = core.registered_chatcommands -- BACKWARDS COMPATIBILITY + +local msg_time_threshold = + tonumber(core.settings:get("chatcommand_msg_time_threshold")) or 0.1 +core.register_on_chat_message(function(name, message) + if message:sub(1,1) ~= "/" then + return + end + + local cmd, param = string.match(message, "^/([^ ]+) *(.*)") + if not cmd then + core.chat_send_player(name, "-!- "..S("Empty command.")) + return true + end + + param = param or "" + + -- Run core.registered_on_chatcommands callbacks. + if core.run_callbacks(core.registered_on_chatcommands, 5, name, cmd, param) then + return true + end + + local cmd_def = core.registered_chatcommands[cmd] + if not cmd_def then + core.chat_send_player(name, "-!- "..S("Invalid command: @1", cmd)) + return true + end + local has_privs, missing_privs = core.check_player_privs(name, cmd_def.privs) + if has_privs then + core.set_last_run_mod(cmd_def.mod_origin) + local t_before = core.get_us_time() + local success, result = cmd_def.func(name, param) + local delay = (core.get_us_time() - t_before) / 1000000 + if success == false and result == nil then + core.chat_send_player(name, "-!- "..S("Invalid command usage.")) + local help_def = core.registered_chatcommands["help"] + if help_def then + local _, helpmsg = help_def.func(name, cmd) + if helpmsg then + core.chat_send_player(name, helpmsg) + end + end + else + if delay > msg_time_threshold then + -- Show how much time it took to execute the command + if result then + result = result .. core.colorize("#f3d2ff", S(" (@1 s)", + string.format("%.5f", delay))) + else + result = core.colorize("#f3d2ff", S( + "Command execution took @1 s", + string.format("%.5f", delay))) + end + end + if result then + core.chat_send_player(name, result) + end + end + else + core.chat_send_player(name, + S("You don't have permission to run this command " + .. "(missing privileges: @1).", + table.concat(missing_privs, ", "))) + end + return true -- Handled chat message +end) + +if core.settings:get_bool("profiler.load") then + -- Run after register_chatcommand and its register_on_chat_message + -- Before any chatcommands that should be profiled + profiler.init_chatcommand() +end + +-- Parses a "range" string in the format of "here (number)" or +-- "(x1, y1, z1) (x2, y2, z2)", returning two position vectors +local function parse_range_str(player_name, str) + local p1, p2 + local args = str:split(" ") + + if args[1] == "here" then + p1, p2 = core.get_player_radius_area(player_name, tonumber(args[2])) + if p1 == nil then + return false, S("Unable to get position of player @1.", player_name) + end + else + local player = core.get_player_by_name(player_name) + local relpos + if player then + relpos = player:get_pos() + end + p1, p2 = core.string_to_area(str, relpos) + if p1 == nil or p2 == nil then + return false, S("Incorrect area format. " + .. "Expected: (x1,y1,z1) (x2,y2,z2)") + end + end + + return p1, p2 +end + +-- +-- Chat commands +-- +core.register_chatcommand("me", { + params = S("<action>"), + description = S("Show chat action (e.g., '/me orders a pizza' " + .. "displays '<player name> orders a pizza')"), + privs = {shout=true}, + func = function(name, param) + core.chat_send_all("* " .. name .. " " .. param) + return true + end, +}) + +core.register_chatcommand("admin", { + description = S("Show the name of the server owner"), + func = function(name) + local admin = core.settings:get("name") + if admin then + return true, S("The administrator of this server is @1.", admin) + else + return false, S("There's no administrator named " + .. "in the config file.") + end + end, +}) + +local function privileges_of(name, privs) + if not privs then + privs = core.get_player_privs(name) + end + local privstr = core.privs_to_string(privs, ", ") + if privstr == "" then + return S("@1 does not have any privileges.", name) + else + return S("Privileges of @1: @2", name, privstr) + end +end + +core.register_chatcommand("privs", { + params = S("[<name>]"), + description = S("Show privileges of yourself or another player"), + func = function(caller, param) + param = param:trim() + local name = (param ~= "" and param or caller) + if not core.player_exists(name) then + return false, S("Player @1 does not exist.", name) + end + return true, privileges_of(name) + end, +}) + +core.register_chatcommand("haspriv", { + params = S("<privilege>"), + description = S("Return list of all online players with privilege"), + privs = {basic_privs = true}, + func = function(caller, param) + param = param:trim() + if param == "" then + return false, S("Invalid parameters (see /help haspriv).") + end + if not core.registered_privileges[param] then + return false, S("Unknown privilege!") + end + local privs = core.string_to_privs(param) + local players_with_priv = {} + for _, player in pairs(core.get_connected_players()) do + local player_name = player:get_player_name() + if core.check_player_privs(player_name, privs) then + table.insert(players_with_priv, player_name) + end + end + if #players_with_priv == 0 then + return true, S("No online player has the \"@1\" privilege.", + param) + else + return true, S("Players online with the \"@1\" privilege: @2", + param, + table.concat(players_with_priv, ", ")) + end + end +}) + +local function handle_grant_command(caller, grantname, grantprivstr) + local caller_privs = core.get_player_privs(caller) + if not (caller_privs.privs or caller_privs.basic_privs) then + return false, S("Your privileges are insufficient.") + end + + if not core.get_auth_handler().get_auth(grantname) then + return false, S("Player @1 does not exist.", grantname) + end + local grantprivs = core.string_to_privs(grantprivstr) + if grantprivstr == "all" then + grantprivs = core.registered_privileges + end + local privs = core.get_player_privs(grantname) + local privs_unknown = "" + local basic_privs = + core.string_to_privs(core.settings:get("basic_privs") or "interact,shout") + for priv, _ in pairs(grantprivs) do + if not basic_privs[priv] and not caller_privs.privs then + return false, S("Your privileges are insufficient. ".. + "'@1' only allows you to grant: @2", + "basic_privs", + core.privs_to_string(basic_privs, ', ')) + end + if not core.registered_privileges[priv] then + privs_unknown = privs_unknown .. S("Unknown privilege: @1", priv) .. "\n" + end + privs[priv] = true + end + if privs_unknown ~= "" then + return false, privs_unknown + end + core.set_player_privs(grantname, privs) + for priv, _ in pairs(grantprivs) do + -- call the on_grant callbacks + core.run_priv_callbacks(grantname, priv, caller, "grant") + end + core.log("action", caller..' granted ('..core.privs_to_string(grantprivs, ', ')..') privileges to '..grantname) + if grantname ~= caller then + core.chat_send_player(grantname, + S("@1 granted you privileges: @2", caller, + core.privs_to_string(grantprivs, ', '))) + end + return true, privileges_of(grantname) +end + +core.register_chatcommand("grant", { + params = S("<name> (<privilege> [, <privilege2> [<...>]] | all)"), + description = S("Give privileges to player"), + func = function(name, param) + local grantname, grantprivstr = string.match(param, "([^ ]+) (.+)") + if not grantname or not grantprivstr then + return false, S("Invalid parameters (see /help grant).") + end + return handle_grant_command(name, grantname, grantprivstr) + end, +}) + +core.register_chatcommand("grantme", { + params = S("<privilege> [, <privilege2> [<...>]] | all"), + description = S("Grant privileges to yourself"), + func = function(name, param) + if param == "" then + return false, S("Invalid parameters (see /help grantme).") + end + return handle_grant_command(name, name, param) + end, +}) + +local function handle_revoke_command(caller, revokename, revokeprivstr) + local caller_privs = core.get_player_privs(caller) + if not (caller_privs.privs or caller_privs.basic_privs) then + return false, S("Your privileges are insufficient.") + end + + if not core.get_auth_handler().get_auth(revokename) then + return false, S("Player @1 does not exist.", revokename) + end + + local privs = core.get_player_privs(revokename) + + local revokeprivs = core.string_to_privs(revokeprivstr) + local is_singleplayer = core.is_singleplayer() + local is_admin = not is_singleplayer + and revokename == core.settings:get("name") + and revokename ~= "" + if revokeprivstr == "all" then + revokeprivs = table.copy(privs) + end + + local privs_unknown = "" + local basic_privs = + core.string_to_privs(core.settings:get("basic_privs") or "interact,shout") + local irrevokable = {} + local has_irrevokable_priv = false + for priv, _ in pairs(revokeprivs) do + if not basic_privs[priv] and not caller_privs.privs then + return false, S("Your privileges are insufficient. ".. + "'@1' only allows you to revoke: @2", + "basic_privs", + core.privs_to_string(basic_privs, ', ')) + end + local def = core.registered_privileges[priv] + if not def then + -- Old/removed privileges might still be granted to certain players + if not privs[priv] then + privs_unknown = privs_unknown .. S("Unknown privilege: @1", priv) .. "\n" + end + elseif is_singleplayer and def.give_to_singleplayer then + irrevokable[priv] = true + elseif is_admin and def.give_to_admin then + irrevokable[priv] = true + end + end + for priv, _ in pairs(irrevokable) do + revokeprivs[priv] = nil + has_irrevokable_priv = true + end + if privs_unknown ~= "" then + return false, privs_unknown + end + if has_irrevokable_priv then + if is_singleplayer then + core.chat_send_player(caller, + S("Note: Cannot revoke in singleplayer: @1", + core.privs_to_string(irrevokable, ', '))) + elseif is_admin then + core.chat_send_player(caller, + S("Note: Cannot revoke from admin: @1", + core.privs_to_string(irrevokable, ', '))) + end + end + + local revokecount = 0 + for priv, _ in pairs(revokeprivs) do + privs[priv] = nil + revokecount = revokecount + 1 + end + + if revokecount == 0 then + return false, S("No privileges were revoked.") + end + + core.set_player_privs(revokename, privs) + for priv, _ in pairs(revokeprivs) do + -- call the on_revoke callbacks + core.run_priv_callbacks(revokename, priv, caller, "revoke") + end + local new_privs = core.get_player_privs(revokename) + + core.log("action", caller..' revoked (' + ..core.privs_to_string(revokeprivs, ', ') + ..') privileges from '..revokename) + if revokename ~= caller then + core.chat_send_player(revokename, + S("@1 revoked privileges from you: @2", caller, + core.privs_to_string(revokeprivs, ', '))) + end + return true, privileges_of(revokename, new_privs) +end + +core.register_chatcommand("revoke", { + params = S("<name> (<privilege> [, <privilege2> [<...>]] | all)"), + description = S("Remove privileges from player"), + privs = {}, + func = function(name, param) + local revokename, revokeprivstr = string.match(param, "([^ ]+) (.+)") + if not revokename or not revokeprivstr then + return false, S("Invalid parameters (see /help revoke).") + end + return handle_revoke_command(name, revokename, revokeprivstr) + end, +}) + +core.register_chatcommand("revokeme", { + params = S("<privilege> [, <privilege2> [<...>]] | all"), + description = S("Revoke privileges from yourself"), + privs = {}, + func = function(name, param) + if param == "" then + return false, S("Invalid parameters (see /help revokeme).") + end + return handle_revoke_command(name, name, param) + end, +}) + +core.register_chatcommand("setpassword", { + params = S("<name> <password>"), + description = S("Set player's password"), + privs = {password=true}, + func = function(name, param) + local toname, raw_password = string.match(param, "^([^ ]+) +(.+)$") + if not toname then + toname = param:match("^([^ ]+) *$") + raw_password = nil + end + + if not toname then + return false, S("Name field required.") + end + + local msg_chat, msg_log, msg_ret + if not raw_password then + core.set_player_password(toname, "") + msg_chat = S("Your password was cleared by @1.", name) + msg_log = name .. " clears password of " .. toname .. "." + msg_ret = S("Password of player \"@1\" cleared.", toname) + else + core.set_player_password(toname, + core.get_password_hash(toname, + raw_password)) + msg_chat = S("Your password was set by @1.", name) + msg_log = name .. " sets password of " .. toname .. "." + msg_ret = S("Password of player \"@1\" set.", toname) + end + + if toname ~= name then + core.chat_send_player(toname, msg_chat) + end + + core.log("action", msg_log) + + return true, msg_ret + end, +}) + +core.register_chatcommand("clearpassword", { + params = S("<name>"), + description = S("Set empty password for a player"), + privs = {password=true}, + func = function(name, param) + local toname = param + if toname == "" then + return false, S("Name field required.") + end + core.set_player_password(toname, '') + + core.log("action", name .. " clears password of " .. toname .. ".") + + return true, S("Password of player \"@1\" cleared.", toname) + end, +}) + +core.register_chatcommand("auth_reload", { + params = "", + description = S("Reload authentication data"), + privs = {server=true}, + func = function(name, param) + local done = core.auth_reload() + return done, (done and S("Done.") or S("Failed.")) + end, +}) + +core.register_chatcommand("remove_player", { + params = S("<name>"), + description = S("Remove a player's data"), + privs = {server=true}, + func = function(name, param) + local toname = param + if toname == "" then + return false, S("Name field required.") + end + + local rc = core.remove_player(toname) + + if rc == 0 then + core.log("action", name .. " removed player data of " .. toname .. ".") + return true, S("Player \"@1\" removed.", toname) + elseif rc == 1 then + return true, S("No such player \"@1\" to remove.", toname) + elseif rc == 2 then + return true, S("Player \"@1\" is connected, cannot remove.", toname) + end + + return false, S("Unhandled remove_player return code @1.", tostring(rc)) + end, +}) + + +-- pos may be a non-integer position +local function find_free_position_near(pos) + local tries = { + vector.new( 1, 0, 0), + vector.new(-1, 0, 0), + vector.new( 0, 0, 1), + vector.new( 0, 0, -1), + } + for _, d in ipairs(tries) do + local p = vector.add(pos, d) + local n = core.get_node_or_nil(p) + if n then + local def = core.registered_nodes[n.name] + if def and not def.walkable then + return p + end + end + end + return pos +end + +-- Teleports player <name> to <p> if possible +local function teleport_to_pos(name, p) + local lm = 31007 -- equals MAX_MAP_GENERATION_LIMIT in C++ + if p.x < -lm or p.x > lm or p.y < -lm or p.y > lm + or p.z < -lm or p.z > lm then + return false, S("Cannot teleport out of map bounds!") + end + local teleportee = core.get_player_by_name(name) + if not teleportee then + return false, S("Cannot get player with name @1.", name) + end + if teleportee:get_attach() then + return false, S("Cannot teleport, @1 " .. + "is attached to an object!", name) + end + teleportee:set_pos(p) + return true, S("Teleporting @1 to @2.", name, core.pos_to_string(p, 1)) +end + +-- Teleports player <name> next to player <target_name> if possible +local function teleport_to_player(name, target_name) + if name == target_name then + return false, S("One does not teleport to oneself.") + end + local teleportee = core.get_player_by_name(name) + if not teleportee then + return false, S("Cannot get teleportee with name @1.", name) + end + if teleportee:get_attach() then + return false, S("Cannot teleport, @1 " .. + "is attached to an object!", name) + end + local target = core.get_player_by_name(target_name) + if not target then + return false, S("Cannot get target player with name @1.", target_name) + end + local p = find_free_position_near(target:get_pos()) + teleportee:set_pos(p) + return true, S("Teleporting @1 to @2 at @3.", name, target_name, + core.pos_to_string(p, 1)) +end + +core.register_chatcommand("teleport", { + params = S("<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>"), + description = S("Teleport to position or player"), + privs = {teleport=true}, + func = function(name, param) + local player = core.get_player_by_name(name) + local relpos + if player then + relpos = player:get_pos() + end + local p = {} + p.x, p.y, p.z = string.match(param, "^([%d.~-]+)[, ] *([%d.~-]+)[, ] *([%d.~-]+)$") + p = core.parse_coordinates(p.x, p.y, p.z, relpos) + if p and p.x and p.y and p.z then + return teleport_to_pos(name, p) + end + + local target_name = param:match("^([^ ]+)$") + if target_name then + return teleport_to_player(name, target_name) + end + + local has_bring_priv = core.check_player_privs(name, {bring=true}) + local missing_bring_msg = S("You don't have permission to teleport " .. + "other players (missing privilege: @1).", "bring") + + local teleportee_name + p = {} + teleportee_name, p.x, p.y, p.z = param:match( + "^([^ ]+) +([%d.~-]+)[, ] *([%d.~-]+)[, ] *([%d.~-]+)$") + if teleportee_name then + local teleportee = core.get_player_by_name(teleportee_name) + if not teleportee then + return + end + relpos = teleportee:get_pos() + p = core.parse_coordinates(p.x, p.y, p.z, relpos) + end + p = vector.apply(p, tonumber) + + if teleportee_name and p.x and p.y and p.z then + if not has_bring_priv then + return false, missing_bring_msg + end + return teleport_to_pos(teleportee_name, p) + end + + teleportee_name, target_name = string.match(param, "^([^ ]+) +([^ ]+)$") + if teleportee_name and target_name then + if not has_bring_priv then + return false, missing_bring_msg + end + return teleport_to_player(teleportee_name, target_name) + end + + return false + end, +}) + +core.register_chatcommand("set", { + params = S("([-n] <name> <value>) | <name>"), + description = S("Set or read server configuration setting"), + privs = {server=true}, + func = function(name, param) + local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)") + if arg and arg == "-n" and setname and setvalue then + core.settings:set(setname, setvalue) + return true, setname .. " = " .. setvalue + end + + setname, setvalue = string.match(param, "([^ ]+) (.+)") + if setname and setvalue then + if setname:sub(1, 7) == "secure." then + return false, S("Failed. Cannot modify secure settings. " + .. "Edit the settings file manually.") + end + if not core.settings:get(setname) then + return false, S("Failed. Use '/set -n <name> <value>' " + .. "to create a new setting.") + end + core.settings:set(setname, setvalue) + return true, S("@1 = @2", setname, setvalue) + end + + setname = string.match(param, "([^ ]+)") + if setname then + setvalue = core.settings:get(setname) + if not setvalue then + setvalue = S("<not set>") + end + return true, S("@1 = @2", setname, setvalue) + end + + return false, S("Invalid parameters (see /help set).") + end, +}) + +local function emergeblocks_callback(pos, action, num_calls_remaining, ctx) + if ctx.total_blocks == 0 then + ctx.total_blocks = num_calls_remaining + 1 + ctx.current_blocks = 0 + end + ctx.current_blocks = ctx.current_blocks + 1 + + if ctx.current_blocks == ctx.total_blocks then + core.chat_send_player(ctx.requestor_name, + S("Finished emerging @1 blocks in @2ms.", + ctx.total_blocks, + string.format("%.2f", (os.clock() - ctx.start_time) * 1000))) + end +end + +local function emergeblocks_progress_update(ctx) + if ctx.current_blocks ~= ctx.total_blocks then + core.chat_send_player(ctx.requestor_name, + S("emergeblocks update: @1/@2 blocks emerged (@3%)", + ctx.current_blocks, ctx.total_blocks, + string.format("%.1f", (ctx.current_blocks / ctx.total_blocks) * 100))) + + core.after(2, emergeblocks_progress_update, ctx) + end +end + +core.register_chatcommand("emergeblocks", { + params = S("(here [<radius>]) | (<pos1> <pos2>)"), + description = S("Load (or, if nonexistent, generate) map blocks contained in " + .. "area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)"), + privs = {server=true}, + func = function(name, param) + local p1, p2 = parse_range_str(name, param) + if p1 == false then + return false, p2 + end + + local context = { + current_blocks = 0, + total_blocks = 0, + start_time = os.clock(), + requestor_name = name + } + + core.emerge_area(p1, p2, emergeblocks_callback, context) + core.after(2, emergeblocks_progress_update, context) + + return true, S("Started emerge of area ranging from @1 to @2.", + core.pos_to_string(p1, 1), core.pos_to_string(p2, 1)) + end, +}) + +core.register_chatcommand("deleteblocks", { + params = S("(here [<radius>]) | (<pos1> <pos2>)"), + description = S("Delete map blocks contained in area pos1 to pos2 " + .. "(<pos1> and <pos2> must be in parentheses)"), + privs = {server=true}, + func = function(name, param) + local p1, p2 = parse_range_str(name, param) + if p1 == false then + return false, p2 + end + + if core.delete_area(p1, p2) then + return true, S("Successfully cleared area " + .. "ranging from @1 to @2.", + core.pos_to_string(p1, 1), core.pos_to_string(p2, 1)) + else + return false, S("Failed to clear one or more " + .. "blocks in area.") + end + end, +}) + +core.register_chatcommand("fixlight", { + params = S("(here [<radius>]) | (<pos1> <pos2>)"), + description = S("Resets lighting in the area between pos1 and pos2 " + .. "(<pos1> and <pos2> must be in parentheses)"), + privs = {server = true}, + func = function(name, param) + local p1, p2 = parse_range_str(name, param) + if p1 == false then + return false, p2 + end + + if core.fix_light(p1, p2) then + return true, S("Successfully reset light in the area " + .. "ranging from @1 to @2.", + core.pos_to_string(p1, 1), core.pos_to_string(p2, 1)) + else + return false, S("Failed to load one or more blocks in area.") + end + end, +}) + +core.register_chatcommand("mods", { + params = "", + description = S("List mods installed on the server"), + privs = {}, + func = function(name, param) + local mods = core.get_modnames() + if #mods == 0 then + return true, S("No mods installed.") + else + return true, table.concat(core.get_modnames(), ", ") + end + end, +}) + +local function handle_give_command(cmd, giver, receiver, stackstring) + core.log("action", giver .. " invoked " .. cmd + .. ', stackstring="' .. stackstring .. '"') + local itemstack = ItemStack(stackstring) + if itemstack:is_empty() then + return false, S("Cannot give an empty item.") + elseif (not itemstack:is_known()) or (itemstack:get_name() == "unknown") then + return false, S("Cannot give an unknown item.") + -- Forbid giving 'ignore' due to unwanted side effects + elseif itemstack:get_name() == "ignore" then + return false, S("Giving 'ignore' is not allowed.") + end + local receiverref = core.get_player_by_name(receiver) + if receiverref == nil then + return false, S("@1 is not a known player.", receiver) + end + local leftover = receiverref:get_inventory():add_item("main", itemstack) + local partiality + if leftover:is_empty() then + partiality = nil + elseif leftover:get_count() == itemstack:get_count() then + partiality = false + else + partiality = true + end + -- The actual item stack string may be different from what the "giver" + -- entered (e.g. big numbers are always interpreted as 2^16-1). + stackstring = itemstack:to_string() + local msg + if partiality == true then + msg = S("@1 partially added to inventory.", stackstring) + elseif partiality == false then + msg = S("@1 could not be added to inventory.", stackstring) + else + msg = S("@1 added to inventory.", stackstring) + end + if giver == receiver then + return true, msg + else + core.chat_send_player(receiver, msg) + local msg_other + if partiality == true then + msg_other = S("@1 partially added to inventory of @2.", + stackstring, receiver) + elseif partiality == false then + msg_other = S("@1 could not be added to inventory of @2.", + stackstring, receiver) + else + msg_other = S("@1 added to inventory of @2.", + stackstring, receiver) + end + return true, msg_other + end +end + +core.register_chatcommand("give", { + params = S("<name> <ItemString> [<count> [<wear>]]"), + description = S("Give item to player"), + privs = {give=true}, + func = function(name, param) + local toname, itemstring = string.match(param, "^([^ ]+) +(.+)$") + if not toname or not itemstring then + return false, S("Name and ItemString required.") + end + return handle_give_command("/give", name, toname, itemstring) + end, +}) + +core.register_chatcommand("giveme", { + params = S("<ItemString> [<count> [<wear>]]"), + description = S("Give item to yourself"), + privs = {give=true}, + func = function(name, param) + local itemstring = string.match(param, "(.+)$") + if not itemstring then + return false, S("ItemString required.") + end + return handle_give_command("/giveme", name, name, itemstring) + end, +}) + +core.register_chatcommand("spawnentity", { + params = S("<EntityName> [<X>,<Y>,<Z>]"), + description = S("Spawn entity at given (or your) position"), + privs = {give=true, interact=true}, + func = function(name, param) + local entityname, pstr = string.match(param, "^([^ ]+) *(.*)$") + if not entityname then + return false, S("EntityName required.") + end + core.log("action", ("%s invokes /spawnentity, entityname=%q") + :format(name, entityname)) + local player = core.get_player_by_name(name) + if player == nil then + core.log("error", "Unable to spawn entity, player is nil") + return false, S("Unable to spawn entity, player is nil.") + end + if not core.registered_entities[entityname] then + return false, S("Cannot spawn an unknown entity.") + end + local p + if pstr == "" then + p = player:get_pos() + else + p = {} + p.x, p.y, p.z = string.match(pstr, "^([%d.~-]+)[, ] *([%d.~-]+)[, ] *([%d.~-]+)$") + local relpos = player:get_pos() + p = core.parse_coordinates(p.x, p.y, p.z, relpos) + if not (p and p.x and p.y and p.z) then + return false, S("Invalid parameters (@1).", param) + end + end + p.y = p.y + 1 + local obj = core.add_entity(p, entityname) + if obj then + return true, S("@1 spawned.", entityname) + else + return true, S("@1 failed to spawn.", entityname) + end + end, +}) + +core.register_chatcommand("pulverize", { + params = "", + description = S("Destroy item in hand"), + func = function(name, param) + local player = core.get_player_by_name(name) + if not player then + core.log("error", "Unable to pulverize, no player.") + return false, S("Unable to pulverize, no player.") + end + local wielded_item = player:get_wielded_item() + if wielded_item:is_empty() then + return false, S("Unable to pulverize, no item in hand.") + end + core.log("action", name .. " pulverized \"" .. + wielded_item:get_name() .. " " .. wielded_item:get_count() .. "\"") + player:set_wielded_item(nil) + return true, S("An item was pulverized.") + end, +}) + +-- Key = player name +core.rollback_punch_callbacks = {} + +core.register_on_punchnode(function(pos, node, puncher) + local name = puncher and puncher:get_player_name() + if name and core.rollback_punch_callbacks[name] then + core.rollback_punch_callbacks[name](pos, node, puncher) + core.rollback_punch_callbacks[name] = nil + end +end) + +core.register_chatcommand("rollback_check", { + params = S("[<range>] [<seconds>] [<limit>]"), + description = S("Check who last touched a node or a node near it " + .. "within the time specified by <seconds>. " + .. "Default: range = 0, seconds = 86400 = 24h, limit = 5. " + .. "Set <seconds> to inf for no time limit"), + privs = {rollback=true}, + func = function(name, param) + if not core.settings:get_bool("enable_rollback_recording") then + return false, S("Rollback functions are disabled.") + end + local range, seconds, limit = + param:match("(%d+) *(%d*) *(%d*)") + range = tonumber(range) or 0 + seconds = tonumber(seconds) or 86400 + limit = tonumber(limit) or 5 + if limit > 100 then + return false, S("That limit is too high!") + end + + core.rollback_punch_callbacks[name] = function(pos, node, puncher) + local name = puncher:get_player_name() + core.chat_send_player(name, S("Checking @1 ...", core.pos_to_string(pos))) + local actions = core.rollback_get_node_actions(pos, range, seconds, limit) + if not actions then + core.chat_send_player(name, S("Rollback functions are disabled.")) + return + end + local num_actions = #actions + if num_actions == 0 then + core.chat_send_player(name, + S("Nobody has touched the specified " + .. "location in @1 seconds.", + seconds)) + return + end + local time = os.time() + for i = num_actions, 1, -1 do + local action = actions[i] + core.chat_send_player(name, + S("@1 @2 @3 -> @4 @5 seconds ago.", + core.pos_to_string(action.pos), + action.actor, + action.oldnode.name, + action.newnode.name, + time - action.time)) + end + end + + return true, S("Punch a node (range=@1, seconds=@2, limit=@3).", + range, seconds, limit) + end, +}) + +core.register_chatcommand("rollback", { + params = S("(<name> [<seconds>]) | (:<actor> [<seconds>])"), + description = S("Revert actions of a player. " + .. "Default for <seconds> is 60. " + .. "Set <seconds> to inf for no time limit"), + privs = {rollback=true}, + func = function(name, param) + if not core.settings:get_bool("enable_rollback_recording") then + return false, S("Rollback functions are disabled.") + end + local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)") + local rev_msg + if not target_name then + local player_name + player_name, seconds = string.match(param, "([^ ]+) *(%d*)") + if not player_name then + return false, S("Invalid parameters. " + .. "See /help rollback and " + .. "/help rollback_check.") + end + seconds = tonumber(seconds) or 60 + target_name = "player:"..player_name + rev_msg = S("Reverting actions of player '@1' since @2 seconds.", + player_name, seconds) + else + seconds = tonumber(seconds) or 60 + rev_msg = S("Reverting actions of @1 since @2 seconds.", + target_name, seconds) + end + core.chat_send_player(name, rev_msg) + local success, log = core.rollback_revert_actions_by( + target_name, seconds) + local response = "" + if #log > 100 then + response = S("(log is too long to show)").."\n" + else + for _, line in pairs(log) do + response = response .. line .. "\n" + end + end + if success then + response = response .. S("Reverting actions succeeded.") + else + response = response .. S("Reverting actions FAILED.") + end + return success, response + end, +}) + +core.register_chatcommand("status", { + description = S("Show server status"), + func = function(name, param) + local status = core.get_server_status(name, false) + if status and status ~= "" then + return true, status + end + return false, S("This command was disabled by a mod or game.") + end, +}) + +local function get_time(timeofday) + local time = math.floor(timeofday * 1440) + local minute = time % 60 + local hour = (time - minute) / 60 + return time, hour, minute +end + +core.register_chatcommand("time", { + params = S("[<0..23>:<0..59> | <0..24000>]"), + description = S("Show or set time of day"), + privs = {}, + func = function(name, param) + if param == "" then + local current_time = math.floor(core.get_timeofday() * 1440) + local minutes = current_time % 60 + local hour = (current_time - minutes) / 60 + return true, S("Current time is @1:@2.", + string.format("%d", hour), + string.format("%02d", minutes)) + end + local player_privs = core.get_player_privs(name) + if not player_privs.settime then + return false, S("You don't have permission to run " + .. "this command (missing privilege: @1).", "settime") + end + local relative, negative, hour, minute = param:match("^(~?)(%-?)(%d+):(%d+)$") + if not relative then -- checking the first capture against nil suffices + local new_time = core.parse_relative_number(param, core.get_timeofday() * 24000) + if not new_time then + new_time = tonumber(param) or -1 + else + new_time = new_time % 24000 + end + if new_time ~= new_time or new_time < 0 or new_time > 24000 then + return false, S("Invalid time (must be between 0 and 24000).") + end + core.set_timeofday(new_time / 24000) + core.log("action", name .. " sets time to " .. new_time) + return true, S("Time of day changed.") + end + local new_time + hour = tonumber(hour) + minute = tonumber(minute) + if relative == "" then + if hour < 0 or hour > 23 then + return false, S("Invalid hour (must be between 0 and 23 inclusive).") + elseif minute < 0 or minute > 59 then + return false, S("Invalid minute (must be between 0 and 59 inclusive).") + end + new_time = (hour * 60 + minute) / 1440 + else + if minute < 0 or minute > 59 then + return false, S("Invalid minute (must be between 0 and 59 inclusive).") + end + local current_time = core.get_timeofday() + if negative == "-" then -- negative time + hour, minute = -hour, -minute + end + new_time = (current_time + (hour * 60 + minute) / 1440) % 1 + local _ + _, hour, minute = get_time(new_time) + end + core.set_timeofday(new_time) + core.log("action", ("%s sets time to %d:%02d"):format(name, hour, minute)) + return true, S("Time of day changed.") + end, +}) + +core.register_chatcommand("days", { + description = S("Show day count since world creation"), + func = function(name, param) + return true, S("Current day is @1.", core.get_day_count()) + end +}) + +local function parse_shutdown_param(param) + local delay, reconnect, message + local one, two, three + one, two, three = param:match("^(%S+) +(%-r) +(.*)") + if one and two and three then + -- 3 arguments: delay, reconnect and message + return one, two, three + end + -- 2 arguments + one, two = param:match("^(%S+) +(.*)") + if one and two then + if tonumber(one) then + delay = one + if two == "-r" then + reconnect = two + else + message = two + end + elseif one == "-r" then + reconnect, message = one, two + end + return delay, reconnect, message + end + -- 1 argument + one = param:match("(.*)") + if tonumber(one) then + delay = one + elseif one == "-r" then + reconnect = one + else + message = one + end + return delay, reconnect, message +end + +core.register_chatcommand("shutdown", { + params = S("[<delay_in_seconds> | -1] [-r] [<message>]"), + description = S("Shutdown server (-1 cancels a delayed shutdown, -r allows players to reconnect)"), + privs = {server=true}, + func = function(name, param) + local delay, reconnect, message = parse_shutdown_param(param) + local bool_reconnect = reconnect == "-r" + if not message then + message = "" + end + delay = tonumber(delay) or 0 + + if delay == 0 then + core.log("action", name .. " shuts down server") + core.chat_send_all("*** "..S("Server shutting down (operator request).")) + end + core.request_shutdown(message:trim(), bool_reconnect, delay) + return true + end, +}) + +core.register_chatcommand("ban", { + params = S("[<name>]"), + description = S("Ban the IP of a player or show the ban list"), + privs = {ban=true}, + func = function(name, param) + if param == "" then + local ban_list = core.get_ban_list() + if ban_list == "" then + return true, S("The ban list is empty.") + else + return true, S("Ban list: @1", ban_list) + end + end + if core.is_singleplayer() then + return false, S("You cannot ban players in singleplayer!") + end + if not core.get_player_by_name(param) then + return false, S("Player is not online.") + end + if not core.ban_player(param) then + return false, S("Failed to ban player.") + end + local desc = core.get_ban_description(param) + core.log("action", name .. " bans " .. desc .. ".") + return true, S("Banned @1.", desc) + end, +}) + +core.register_chatcommand("unban", { + params = S("<name> | <IP_address>"), + description = S("Remove IP ban belonging to a player/IP"), + privs = {ban=true}, + func = function(name, param) + if not core.unban_player_or_ip(param) then + return false, S("Failed to unban player/IP.") + end + core.log("action", name .. " unbans " .. param) + return true, S("Unbanned @1.", param) + end, +}) + +core.register_chatcommand("kick", { + params = S("<name> [<reason>]"), + description = S("Kick a player"), + privs = {kick=true}, + func = function(name, param) + local tokick, reason = param:match("([^ ]+) (.+)") + tokick = tokick or param + if not core.kick_player(tokick, reason) then + return false, S("Failed to kick player @1.", tokick) + end + local log_reason = "" + if reason then + log_reason = " with reason \"" .. reason .. "\"" + end + core.log("action", name .. " kicks " .. tokick .. log_reason) + return true, S("Kicked @1.", tokick) + end, +}) + +core.register_chatcommand("clearobjects", { + params = S("[full | quick]"), + description = S("Clear all objects in world"), + privs = {server=true}, + func = function(name, param) + local options = {} + if param == "" or param == "quick" then + options.mode = "quick" + elseif param == "full" then + options.mode = "full" + else + return false, S("Invalid usage, see /help clearobjects.") + end + + core.log("action", name .. " clears objects (" + .. options.mode .. " mode).") + if options.mode == "full" then + core.chat_send_all(S("Clearing all objects. This may take a long time. " + .. "You may experience a timeout. (by @1)", name)) + end + core.clear_objects(options) + core.log("action", "Object clearing done.") + core.chat_send_all("*** "..S("Cleared all objects.")) + return true + end, +}) + +core.register_chatcommand("msg", { + params = S("<name> <message>"), + description = S("Send a direct message to a player"), + privs = {shout=true}, + func = function(name, param) + local sendto, message = param:match("^(%S+)%s(.+)$") + if not sendto then + return false, S("Invalid usage, see /help msg.") + end + if not core.get_player_by_name(sendto) then + return false, S("The player @1 is not online.", sendto) + end + core.log("action", "DM from " .. name .. " to " .. sendto + .. ": " .. message) + core.chat_send_player(sendto, S("DM from @1: @2", name, message)) + return true, S("Message sent.") + end, +}) + +core.register_chatcommand("last-login", { + params = S("[<name>]"), + description = S("Get the last login time of a player or yourself"), + func = function(name, param) + if param == "" then + param = name + end + local pauth = core.get_auth_handler().get_auth(param) + if pauth and pauth.last_login and pauth.last_login ~= -1 then + -- Time in UTC, ISO 8601 format + return true, S("@1's last login time was @2.", + param, + os.date("!%Y-%m-%dT%H:%M:%SZ", pauth.last_login)) + end + return false, S("@1's last login time is unknown.", param) + end, +}) + +core.register_chatcommand("clearinv", { + params = S("[<name>]"), + description = S("Clear the inventory of yourself or another player"), + func = function(name, param) + local player + if param and param ~= "" and param ~= name then + if not core.check_player_privs(name, {server=true}) then + return false, S("You don't have permission to " + .. "clear another player's inventory " + .. "(missing privilege: @1).", "server") + end + player = core.get_player_by_name(param) + core.chat_send_player(param, S("@1 cleared your inventory.", name)) + else + player = core.get_player_by_name(name) + end + + if player then + player:get_inventory():set_list("main", {}) + player:get_inventory():set_list("craft", {}) + player:get_inventory():set_list("craftpreview", {}) + core.log("action", name.." clears "..player:get_player_name().."'s inventory") + return true, S("Cleared @1's inventory.", player:get_player_name()) + else + return false, S("Player must be online to clear inventory!") + end + end, +}) + +local function handle_kill_command(killer, victim) + if core.settings:get_bool("enable_damage") == false then + return false, S("Players can't be killed, damage has been disabled.") + end + local victimref = core.get_player_by_name(victim) + if victimref == nil then + return false, S("Player @1 is not online.", victim) + elseif victimref:get_hp() <= 0 then + if killer == victim then + return false, S("You are already dead.") + else + return false, S("@1 is already dead.", victim) + end + end + if killer ~= victim then + core.log("action", string.format("%s killed %s", killer, victim)) + end + -- Kill victim + victimref:set_hp(0) + return true, S("@1 has been killed.", victim) +end + +core.register_chatcommand("kill", { + params = S("[<name>]"), + description = S("Kill player or yourself"), + privs = {server=true}, + func = function(name, param) + return handle_kill_command(name, param == "" and name or param) + end, +}) diff --git a/builtin/game/constants.lua b/builtin/game/constants.lua new file mode 100644 index 0000000..54eeea5 --- /dev/null +++ b/builtin/game/constants.lua @@ -0,0 +1,31 @@ +-- Minetest: builtin/constants.lua + +-- +-- Constants values for use with the Lua API +-- + +-- mapnode.h +-- Built-in Content IDs (for use with VoxelManip API) +core.CONTENT_UNKNOWN = 125 +core.CONTENT_AIR = 126 +core.CONTENT_IGNORE = 127 + +-- emerge.h +-- Block emerge status constants (for use with core.emerge_area) +core.EMERGE_CANCELLED = 0 +core.EMERGE_ERRORED = 1 +core.EMERGE_FROM_MEMORY = 2 +core.EMERGE_FROM_DISK = 3 +core.EMERGE_GENERATED = 4 + +-- constants.h +-- Size of mapblocks in nodes +core.MAP_BLOCKSIZE = 16 +-- Default maximal HP of a player +core.PLAYER_MAX_HP_DEFAULT = 20 +-- Default maximal breath of a player +core.PLAYER_MAX_BREATH_DEFAULT = 10 + +-- light.h +-- Maximum value for node 'light_source' parameter +core.LIGHT_MAX = 14 diff --git a/builtin/game/deprecated.lua b/builtin/game/deprecated.lua new file mode 100644 index 0000000..c5c7848 --- /dev/null +++ b/builtin/game/deprecated.lua @@ -0,0 +1,65 @@ +-- Minetest: builtin/deprecated.lua + +-- +-- EnvRef +-- +core.env = {} +local envref_deprecation_message_printed = false +setmetatable(core.env, { + __index = function(table, key) + if not envref_deprecation_message_printed then + core.log("deprecated", "core.env:[...] is deprecated and should be replaced with core.[...]") + envref_deprecation_message_printed = true + end + local func = core[key] + if type(func) == "function" then + rawset(table, key, function(self, ...) + return func(...) + end) + else + rawset(table, key, nil) + end + return rawget(table, key) + end +}) + +function core.rollback_get_last_node_actor(pos, range, seconds) + return core.rollback_get_node_actions(pos, range, seconds, 1)[1] +end + +-- +-- core.setting_* +-- + +local settings = core.settings + +local function setting_proxy(name) + return function(...) + core.log("deprecated", "WARNING: minetest.setting_* ".. + "functions are deprecated. ".. + "Use methods on the minetest.settings object.") + return settings[name](settings, ...) + end +end + +core.setting_set = setting_proxy("set") +core.setting_get = setting_proxy("get") +core.setting_setbool = setting_proxy("set_bool") +core.setting_getbool = setting_proxy("get_bool") +core.setting_save = setting_proxy("write") + +-- +-- core.register_on_auth_fail +-- + +function core.register_on_auth_fail(func) + core.log("deprecated", "core.register_on_auth_fail " .. + "is deprecated and should be replaced by " .. + "core.register_on_authplayer instead.") + + core.register_on_authplayer(function (player_name, ip, is_success) + if not is_success then + func(player_name, ip) + end + end) +end diff --git a/builtin/game/detached_inventory.lua b/builtin/game/detached_inventory.lua new file mode 100644 index 0000000..2e27168 --- /dev/null +++ b/builtin/game/detached_inventory.lua @@ -0,0 +1,24 @@ +-- Minetest: builtin/detached_inventory.lua + +core.detached_inventories = {} + +function core.create_detached_inventory(name, callbacks, player_name) + local stuff = {} + stuff.name = name + if callbacks then + stuff.allow_move = callbacks.allow_move + stuff.allow_put = callbacks.allow_put + stuff.allow_take = callbacks.allow_take + stuff.on_move = callbacks.on_move + stuff.on_put = callbacks.on_put + stuff.on_take = callbacks.on_take + end + stuff.mod_origin = core.get_current_modname() or "??" + core.detached_inventories[name] = stuff + return core.create_detached_inventory_raw(name, player_name) +end + +function core.remove_detached_inventory(name) + core.detached_inventories[name] = nil + return core.remove_detached_inventory_raw(name) +end diff --git a/builtin/game/falling.lua b/builtin/game/falling.lua new file mode 100644 index 0000000..d5727f2 --- /dev/null +++ b/builtin/game/falling.lua @@ -0,0 +1,608 @@ +-- Minetest: builtin/item.lua + +local builtin_shared = ... +local SCALE = 0.667 + +local facedir_to_euler = { + {y = 0, x = 0, z = 0}, + {y = -math.pi/2, x = 0, z = 0}, + {y = math.pi, x = 0, z = 0}, + {y = math.pi/2, x = 0, z = 0}, + {y = math.pi/2, x = -math.pi/2, z = math.pi/2}, + {y = math.pi/2, x = math.pi, z = math.pi/2}, + {y = math.pi/2, x = math.pi/2, z = math.pi/2}, + {y = math.pi/2, x = 0, z = math.pi/2}, + {y = -math.pi/2, x = math.pi/2, z = math.pi/2}, + {y = -math.pi/2, x = 0, z = math.pi/2}, + {y = -math.pi/2, x = -math.pi/2, z = math.pi/2}, + {y = -math.pi/2, x = math.pi, z = math.pi/2}, + {y = 0, x = 0, z = math.pi/2}, + {y = 0, x = -math.pi/2, z = math.pi/2}, + {y = 0, x = math.pi, z = math.pi/2}, + {y = 0, x = math.pi/2, z = math.pi/2}, + {y = math.pi, x = math.pi, z = math.pi/2}, + {y = math.pi, x = math.pi/2, z = math.pi/2}, + {y = math.pi, x = 0, z = math.pi/2}, + {y = math.pi, x = -math.pi/2, z = math.pi/2}, + {y = math.pi, x = math.pi, z = 0}, + {y = -math.pi/2, x = math.pi, z = 0}, + {y = 0, x = math.pi, z = 0}, + {y = math.pi/2, x = math.pi, z = 0} +} + +local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81 + +-- +-- Falling stuff +-- + +core.register_entity(":__builtin:falling_node", { + initial_properties = { + visual = "item", + visual_size = vector.new(SCALE, SCALE, SCALE), + textures = {}, + physical = true, + is_visible = false, + collide_with_objects = true, + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + + node = {}, + meta = {}, + floats = false, + + set_node = function(self, node, meta) + node.param2 = node.param2 or 0 + self.node = node + meta = meta or {} + if type(meta.to_table) == "function" then + meta = meta:to_table() + end + for _, list in pairs(meta.inventory or {}) do + for i, stack in pairs(list) do + if type(stack) == "userdata" then + list[i] = stack:to_string() + end + end + end + local def = core.registered_nodes[node.name] + if not def then + -- Don't allow unknown nodes to fall + core.log("info", + "Unknown falling node removed at ".. + core.pos_to_string(self.object:get_pos())) + self.object:remove() + return + end + self.meta = meta + + -- Cache whether we're supposed to float on water + self.floats = core.get_item_group(node.name, "float") ~= 0 + + -- Set entity visuals + if def.drawtype == "torchlike" or def.drawtype == "signlike" then + local textures + if def.tiles and def.tiles[1] then + local tile = def.tiles[1] + if type(tile) == "table" then + tile = tile.name + end + if def.drawtype == "torchlike" then + textures = { "("..tile..")^[transformFX", tile } + else + textures = { tile, "("..tile..")^[transformFX" } + end + end + local vsize + if def.visual_scale then + local s = def.visual_scale + vsize = vector.new(s, s, s) + end + self.object:set_properties({ + is_visible = true, + visual = "upright_sprite", + visual_size = vsize, + textures = textures, + glow = def.light_source, + }) + elseif def.drawtype ~= "airlike" then + local itemstring = node.name + if core.is_colored_paramtype(def.paramtype2) then + itemstring = core.itemstring_with_palette(itemstring, node.param2) + end + -- FIXME: solution needed for paramtype2 == "leveled" + -- Calculate size of falling node + local s = {} + s.x = (def.visual_scale or 1) * SCALE + s.y = s.x + s.z = s.x + -- Compensate for wield_scale + if def.wield_scale then + s.x = s.x / def.wield_scale.x + s.y = s.y / def.wield_scale.y + s.z = s.z / def.wield_scale.z + end + self.object:set_properties({ + is_visible = true, + wield_item = itemstring, + visual_size = s, + glow = def.light_source, + }) + end + + -- Set collision box (certain nodeboxes only for now) + local nb_types = {fixed=true, leveled=true, connected=true} + if def.drawtype == "nodebox" and def.node_box and + nb_types[def.node_box.type] and def.node_box.fixed then + local box = table.copy(def.node_box.fixed) + if type(box[1]) == "table" then + box = #box == 1 and box[1] or nil -- We can only use a single box + end + if box then + if def.paramtype2 == "leveled" and (self.node.level or 0) > 0 then + box[5] = -0.5 + self.node.level / 64 + end + self.object:set_properties({ + collisionbox = box + }) + end + end + + -- Rotate entity + if def.drawtype == "torchlike" then + self.object:set_yaw(math.pi*0.25) + elseif ((node.param2 ~= 0 or def.drawtype == "nodebox" or def.drawtype == "mesh") + and (def.wield_image == "" or def.wield_image == nil)) + or def.drawtype == "signlike" + or def.drawtype == "mesh" + or def.drawtype == "normal" + or def.drawtype == "nodebox" then + if (def.paramtype2 == "facedir" or def.paramtype2 == "colorfacedir") then + local fdir = node.param2 % 32 % 24 + -- Get rotation from a precalculated lookup table + local euler = facedir_to_euler[fdir + 1] + self.object:set_rotation(euler) + elseif (def.drawtype ~= "plantlike" and def.drawtype ~= "plantlike_rooted" and + (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted" or def.drawtype == "signlike")) then + local rot = node.param2 % 8 + if (def.drawtype == "signlike" and def.paramtype2 ~= "wallmounted" and def.paramtype2 ~= "colorwallmounted") then + -- Change rotation to "floor" by default for non-wallmounted paramtype2 + rot = 1 + end + local pitch, yaw, roll = 0, 0, 0 + if def.drawtype == "nodebox" or def.drawtype == "mesh" then + if rot == 0 then + pitch, yaw = math.pi/2, 0 + elseif rot == 1 then + pitch, yaw = -math.pi/2, math.pi + elseif rot == 2 then + pitch, yaw = 0, math.pi/2 + elseif rot == 3 then + pitch, yaw = 0, -math.pi/2 + elseif rot == 4 then + pitch, yaw = 0, math.pi + end + else + if rot == 1 then + pitch, yaw = math.pi, math.pi + elseif rot == 2 then + pitch, yaw = math.pi/2, math.pi/2 + elseif rot == 3 then + pitch, yaw = math.pi/2, -math.pi/2 + elseif rot == 4 then + pitch, yaw = math.pi/2, math.pi + elseif rot == 5 then + pitch, yaw = math.pi/2, 0 + end + end + if def.drawtype == "signlike" then + pitch = pitch - math.pi/2 + if rot == 0 then + yaw = yaw + math.pi/2 + elseif rot == 1 then + yaw = yaw - math.pi/2 + end + elseif def.drawtype == "mesh" or def.drawtype == "normal" or def.drawtype == "nodebox" then + if rot >= 0 and rot <= 1 then + roll = roll + math.pi + else + yaw = yaw + math.pi + end + end + self.object:set_rotation({x=pitch, y=yaw, z=roll}) + elseif (def.drawtype == "mesh" and def.paramtype2 == "degrotate") then + local p2 = (node.param2 - (def.place_param2 or 0)) % 240 + local yaw = (p2 / 240) * (math.pi * 2) + self.object:set_yaw(yaw) + elseif (def.drawtype == "mesh" and def.paramtype2 == "colordegrotate") then + local p2 = (node.param2 % 32 - (def.place_param2 or 0) % 32) % 24 + local yaw = (p2 / 24) * (math.pi * 2) + self.object:set_yaw(yaw) + end + end + end, + + get_staticdata = function(self) + local ds = { + node = self.node, + meta = self.meta, + } + return core.serialize(ds) + end, + + on_activate = function(self, staticdata) + self.object:set_armor_groups({immortal = 1}) + self.object:set_acceleration(vector.new(0, -gravity, 0)) + + local ds = core.deserialize(staticdata) + if ds and ds.node then + self:set_node(ds.node, ds.meta) + elseif ds then + self:set_node(ds) + elseif staticdata ~= "" then + self:set_node({name = staticdata}) + end + end, + + try_place = function(self, bcp, bcn) + local bcd = core.registered_nodes[bcn.name] + -- Add levels if dropped on same leveled node + if bcd and bcd.paramtype2 == "leveled" and + bcn.name == self.node.name then + local addlevel = self.node.level + if (addlevel or 0) <= 0 then + addlevel = bcd.leveled + end + if core.add_node_level(bcp, addlevel) < addlevel then + return true + elseif bcd.buildable_to then + -- Node level has already reached max, don't place anything + return true + end + end + + -- Decide if we're replacing the node or placing on top + local np = vector.copy(bcp) + if bcd and bcd.buildable_to and + (not self.floats or bcd.liquidtype == "none") then + core.remove_node(bcp) + else + np.y = np.y + 1 + end + + -- Check what's here + local n2 = core.get_node(np) + local nd = core.registered_nodes[n2.name] + -- If it's not air or liquid, remove node and replace it with + -- it's drops + if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then + if nd and nd.buildable_to == false then + nd.on_dig(np, n2, nil) + -- If it's still there, it might be protected + if core.get_node(np).name == n2.name then + return false + end + else + core.remove_node(np) + end + end + + -- Create node + local def = core.registered_nodes[self.node.name] + if def then + core.add_node(np, self.node) + if self.meta then + core.get_meta(np):from_table(self.meta) + end + if def.sounds and def.sounds.place then + core.sound_play(def.sounds.place, {pos = np}, true) + end + end + core.check_for_falling(np) + return true + end, + + on_step = function(self, dtime, moveresult) + -- Fallback code since collision detection can't tell us + -- about liquids (which do not collide) + if self.floats then + local pos = self.object:get_pos() + + local bcp = pos:offset(0, -0.7, 0):round() + local bcn = core.get_node(bcp) + + local bcd = core.registered_nodes[bcn.name] + if bcd and bcd.liquidtype ~= "none" then + if self:try_place(bcp, bcn) then + self.object:remove() + return + end + end + end + + assert(moveresult) + if not moveresult.collides then + return -- Nothing to do :) + end + + local bcp, bcn + local player_collision + if moveresult.touching_ground then + for _, info in ipairs(moveresult.collisions) do + if info.type == "object" then + if info.axis == "y" and info.object:is_player() then + player_collision = info + end + elseif info.axis == "y" then + bcp = info.node_pos + bcn = core.get_node(bcp) + break + end + end + end + + if not bcp then + -- We're colliding with something, but not the ground. Irrelevant to us. + if player_collision then + -- Continue falling through players by moving a little into + -- their collision box + -- TODO: this hack could be avoided in the future if objects + -- could choose who to collide with + local vel = self.object:get_velocity() + self.object:set_velocity(vector.new( + vel.x, + player_collision.old_velocity.y, + vel.z + )) + self.object:set_pos(self.object:get_pos():offset(0, -0.5, 0)) + end + return + elseif bcn.name == "ignore" then + -- Delete on contact with ignore at world edges + self.object:remove() + return + end + + local failure = false + + local pos = self.object:get_pos() + local distance = vector.apply(vector.subtract(pos, bcp), math.abs) + if distance.x >= 1 or distance.z >= 1 then + -- We're colliding with some part of a node that's sticking out + -- Since we don't want to visually teleport, drop as item + failure = true + elseif distance.y >= 2 then + -- Doors consist of a hidden top node and a bottom node that is + -- the actual door. Despite the top node being solid, the moveresult + -- almost always indicates collision with the bottom node. + -- Compensate for this by checking the top node + bcp.y = bcp.y + 1 + bcn = core.get_node(bcp) + local def = core.registered_nodes[bcn.name] + if not (def and def.walkable) then + failure = true -- This is unexpected, fail + end + end + + -- Try to actually place ourselves + if not failure then + failure = not self:try_place(bcp, bcn) + end + + if failure then + local drops = core.get_node_drops(self.node, "") + for _, item in pairs(drops) do + core.add_item(pos, item) + end + end + self.object:remove() + end +}) + +local function convert_to_falling_node(pos, node) + local obj = core.add_entity(pos, "__builtin:falling_node") + if not obj then + return false + end + -- remember node level, the entities' set_node() uses this + node.level = core.get_node_level(pos) + local meta = core.get_meta(pos) + local metatable = meta and meta:to_table() or {} + + local def = core.registered_nodes[node.name] + if def and def.sounds and def.sounds.fall then + core.sound_play(def.sounds.fall, {pos = pos}, true) + end + + obj:get_luaentity():set_node(node, metatable) + core.remove_node(pos) + return true, obj +end + +function core.spawn_falling_node(pos) + local node = core.get_node(pos) + if node.name == "air" or node.name == "ignore" then + return false + end + return convert_to_falling_node(pos, node) +end + +local function drop_attached_node(p) + local n = core.get_node(p) + local drops = core.get_node_drops(n, "") + local def = core.registered_items[n.name] + if def and def.preserve_metadata then + local oldmeta = core.get_meta(p):to_table().fields + -- Copy pos and node because the callback can modify them. + local pos_copy = vector.copy(p) + local node_copy = {name=n.name, param1=n.param1, param2=n.param2} + local drop_stacks = {} + for k, v in pairs(drops) do + drop_stacks[k] = ItemStack(v) + end + drops = drop_stacks + def.preserve_metadata(pos_copy, node_copy, oldmeta, drops) + end + if def and def.sounds and def.sounds.fall then + core.sound_play(def.sounds.fall, {pos = p}, true) + end + core.remove_node(p) + for _, item in pairs(drops) do + local pos = { + x = p.x + math.random()/2 - 0.25, + y = p.y + math.random()/2 - 0.25, + z = p.z + math.random()/2 - 0.25, + } + core.add_item(pos, item) + end +end + +function builtin_shared.check_attached_node(p, n) + local def = core.registered_nodes[n.name] + local d = vector.zero() + if def.paramtype2 == "wallmounted" or + def.paramtype2 == "colorwallmounted" then + -- The fallback vector here is in case 'wallmounted to dir' is nil due + -- to voxelmanip placing a wallmounted node without resetting a + -- pre-existing param2 value that is out-of-range for wallmounted. + -- The fallback vector corresponds to param2 = 0. + d = core.wallmounted_to_dir(n.param2) or vector.new(0, 1, 0) + else + d.y = -1 + end + local p2 = vector.add(p, d) + local nn = core.get_node(p2).name + local def2 = core.registered_nodes[nn] + if def2 and not def2.walkable then + return false + end + return true +end + +-- +-- Some common functions +-- + +function core.check_single_for_falling(p) + local n = core.get_node(p) + if core.get_item_group(n.name, "falling_node") ~= 0 then + local p_bottom = vector.offset(p, 0, -1, 0) + -- Only spawn falling node if node below is loaded + local n_bottom = core.get_node_or_nil(p_bottom) + local d_bottom = n_bottom and core.registered_nodes[n_bottom.name] + if d_bottom then + local same = n.name == n_bottom.name + -- Let leveled nodes fall if it can merge with the bottom node + if same and d_bottom.paramtype2 == "leveled" and + core.get_node_level(p_bottom) < + core.get_node_max_level(p_bottom) then + convert_to_falling_node(p, n) + return true + end + -- Otherwise only if the bottom node is considered "fall through" + if not same and + (not d_bottom.walkable or d_bottom.buildable_to) and + (core.get_item_group(n.name, "float") == 0 or + d_bottom.liquidtype == "none") then + convert_to_falling_node(p, n) + return true + end + end + end + + if core.get_item_group(n.name, "attached_node") ~= 0 then + if not builtin_shared.check_attached_node(p, n) then + drop_attached_node(p) + return true + end + end + + return false +end + +-- This table is specifically ordered. +-- We don't walk diagonals, only our direct neighbors, and self. +-- Down first as likely case, but always before self. The same with sides. +-- Up must come last, so that things above self will also fall all at once. +local check_for_falling_neighbors = { + vector.new(-1, -1, 0), + vector.new( 1, -1, 0), + vector.new( 0, -1, -1), + vector.new( 0, -1, 1), + vector.new( 0, -1, 0), + vector.new(-1, 0, 0), + vector.new( 1, 0, 0), + vector.new( 0, 0, 1), + vector.new( 0, 0, -1), + vector.new( 0, 0, 0), + vector.new( 0, 1, 0), +} + +function core.check_for_falling(p) + -- Round p to prevent falling entities to get stuck. + p = vector.round(p) + + -- We make a stack, and manually maintain size for performance. + -- Stored in the stack, we will maintain tables with pos, and + -- last neighbor visited. This way, when we get back to each + -- node, we know which directions we have already walked, and + -- which direction is the next to walk. + local s = {} + local n = 0 + -- The neighbor order we will visit from our table. + local v = 1 + + while true do + -- Push current pos onto the stack. + n = n + 1 + s[n] = {p = p, v = v} + -- Select next node from neighbor list. + p = vector.add(p, check_for_falling_neighbors[v]) + -- Now we check out the node. If it is in need of an update, + -- it will let us know in the return value (true = updated). + if not core.check_single_for_falling(p) then + -- If we don't need to "recurse" (walk) to it then pop + -- our previous pos off the stack and continue from there, + -- with the v value we were at when we last were at that + -- node + repeat + local pop = s[n] + p = pop.p + v = pop.v + s[n] = nil + n = n - 1 + -- If there's nothing left on the stack, and no + -- more sides to walk to, we're done and can exit + if n == 0 and v == 11 then + return + end + until v < 11 + -- The next round walk the next neighbor in list. + v = v + 1 + else + -- If we did need to walk the neighbor, then + -- start walking it from the walk order start (1), + -- and not the order we just pushed up the stack. + v = 1 + end + end +end + +-- +-- Global callbacks +-- + +local function on_placenode(p, node) + core.check_for_falling(p) +end +core.register_on_placenode(on_placenode) + +local function on_dignode(p, node) + core.check_for_falling(p) +end +core.register_on_dignode(on_dignode) + +local function on_punchnode(p, node) + core.check_for_falling(p) +end +core.register_on_punchnode(on_punchnode) diff --git a/builtin/game/features.lua b/builtin/game/features.lua new file mode 100644 index 0000000..73b1636 --- /dev/null +++ b/builtin/game/features.lua @@ -0,0 +1,46 @@ +-- Minetest: builtin/features.lua + +core.features = { + glasslike_framed = true, + nodebox_as_selectionbox = true, + get_all_craft_recipes_works = true, + use_texture_alpha = true, + no_legacy_abms = true, + texture_names_parens = true, + area_store_custom_ids = true, + add_entity_with_staticdata = true, + no_chat_message_prediction = true, + object_use_texture_alpha = true, + object_independent_selectionbox = true, + httpfetch_binary_data = true, + formspec_version_element = true, + area_store_persistent_ids = true, + pathfinder_works = true, + object_step_has_moveresult = true, + direct_velocity_on_players = true, + use_texture_alpha_string_modes = true, + degrotate_240_steps = true, + abm_min_max_y = true, + particlespawner_tweenable = true, + dynamic_add_media_table = true, + get_sky_as_table = true, +} + +function core.has_feature(arg) + if type(arg) == "table" then + local missing_features = {} + local result = true + for ftr in pairs(arg) do + if not core.features[ftr] then + missing_features[ftr] = true + result = false + end + end + return result, missing_features + elseif type(arg) == "string" then + if not core.features[arg] then + return false, {[arg]=true} + end + return true, {} + end +end diff --git a/builtin/game/forceloading.lua b/builtin/game/forceloading.lua new file mode 100644 index 0000000..8043e5d --- /dev/null +++ b/builtin/game/forceloading.lua @@ -0,0 +1,126 @@ +-- Prevent anyone else accessing those functions +local forceload_block = core.forceload_block +local forceload_free_block = core.forceload_free_block +core.forceload_block = nil +core.forceload_free_block = nil + +local blocks_forceloaded +local blocks_temploaded = {} +local total_forceloaded = 0 + +-- true, if the forceloaded blocks got changed (flag for persistence on-disk) +local forceload_blocks_changed = false + +local BLOCKSIZE = core.MAP_BLOCKSIZE +local function get_blockpos(pos) + return { + x = math.floor(pos.x/BLOCKSIZE), + y = math.floor(pos.y/BLOCKSIZE), + z = math.floor(pos.z/BLOCKSIZE)} +end + +-- When we create/free a forceload, it's either transient or persistent. We want +-- to add to/remove from the table that corresponds to the type of forceload, but +-- we also need the other table because whether we forceload a block depends on +-- both tables. +-- This function returns the "primary" table we are adding to/removing from, and +-- the other table. +local function get_relevant_tables(transient) + if transient then + return blocks_temploaded, blocks_forceloaded + else + return blocks_forceloaded, blocks_temploaded + end +end + +function core.forceload_block(pos, transient) + -- set changed flag + forceload_blocks_changed = true + + local blockpos = get_blockpos(pos) + local hash = core.hash_node_position(blockpos) + local relevant_table, other_table = get_relevant_tables(transient) + if relevant_table[hash] ~= nil then + relevant_table[hash] = relevant_table[hash] + 1 + return true + elseif other_table[hash] ~= nil then + relevant_table[hash] = 1 + else + if total_forceloaded >= (tonumber(core.settings:get("max_forceloaded_blocks")) or 16) then + return false + end + total_forceloaded = total_forceloaded+1 + relevant_table[hash] = 1 + forceload_block(blockpos) + return true + end +end + +function core.forceload_free_block(pos, transient) + -- set changed flag + forceload_blocks_changed = true + + local blockpos = get_blockpos(pos) + local hash = core.hash_node_position(blockpos) + local relevant_table, other_table = get_relevant_tables(transient) + if relevant_table[hash] == nil then return end + if relevant_table[hash] > 1 then + relevant_table[hash] = relevant_table[hash] - 1 + elseif other_table[hash] ~= nil then + relevant_table[hash] = nil + else + total_forceloaded = total_forceloaded-1 + relevant_table[hash] = nil + forceload_free_block(blockpos) + end +end + +-- Keep the forceloaded areas after restart +local wpath = core.get_worldpath() +local function read_file(filename) + local f = io.open(filename, "r") + if f==nil then return {} end + local t = f:read("*all") + f:close() + if t=="" or t==nil then return {} end + return core.deserialize(t) or {} +end + +blocks_forceloaded = read_file(wpath.."/force_loaded.txt") +for _, __ in pairs(blocks_forceloaded) do + total_forceloaded = total_forceloaded + 1 +end + +core.after(5, function() + for hash, _ in pairs(blocks_forceloaded) do + local blockpos = core.get_position_from_hash(hash) + forceload_block(blockpos) + end +end) + +-- persists the currently forceloaded blocks to disk +local function persist_forceloaded_blocks() + local data = core.serialize(blocks_forceloaded) + core.safe_file_write(wpath.."/force_loaded.txt", data) +end + +-- periodical forceload persistence +local function periodically_persist_forceloaded_blocks() + + -- only persist if the blocks actually changed + if forceload_blocks_changed then + persist_forceloaded_blocks() + + -- reset changed flag + forceload_blocks_changed = false + end + + -- recheck after some time + core.after(10, periodically_persist_forceloaded_blocks) +end + +-- persist periodically +core.after(5, periodically_persist_forceloaded_blocks) + +-- persist on shutdown +core.register_on_shutdown(persist_forceloaded_blocks) diff --git a/builtin/game/init.lua b/builtin/game/init.lua new file mode 100644 index 0000000..d7606f3 --- /dev/null +++ b/builtin/game/init.lua @@ -0,0 +1,40 @@ + +local scriptpath = core.get_builtin_path() +local commonpath = scriptpath .. "common" .. DIR_DELIM +local gamepath = scriptpath .. "game".. DIR_DELIM + +-- Shared between builtin files, but +-- not exposed to outer context +local builtin_shared = {} + +dofile(gamepath .. "constants.lua") +dofile(gamepath .. "item_s.lua") +assert(loadfile(gamepath .. "item.lua"))(builtin_shared) +dofile(gamepath .. "register.lua") + +if core.settings:get_bool("profiler.load") then + profiler = dofile(scriptpath .. "profiler" .. DIR_DELIM .. "init.lua") +end + +dofile(commonpath .. "after.lua") +dofile(commonpath .. "mod_storage.lua") +dofile(gamepath .. "item_entity.lua") +dofile(gamepath .. "deprecated.lua") +dofile(gamepath .. "misc_s.lua") +dofile(gamepath .. "misc.lua") +dofile(gamepath .. "privileges.lua") +dofile(gamepath .. "auth.lua") +dofile(commonpath .. "chatcommands.lua") +dofile(gamepath .. "chat.lua") +dofile(commonpath .. "information_formspecs.lua") +dofile(gamepath .. "static_spawn.lua") +dofile(gamepath .. "detached_inventory.lua") +assert(loadfile(gamepath .. "falling.lua"))(builtin_shared) +dofile(gamepath .. "features.lua") +dofile(gamepath .. "voxelarea.lua") +dofile(gamepath .. "forceloading.lua") +dofile(gamepath .. "statbars.lua") +dofile(gamepath .. "knockback.lua") +dofile(gamepath .. "async.lua") + +profiler = nil diff --git a/builtin/game/item.lua b/builtin/game/item.lua new file mode 100644 index 0000000..00601c6 --- /dev/null +++ b/builtin/game/item.lua @@ -0,0 +1,680 @@ +-- Minetest: builtin/item.lua + +local builtin_shared = ... + +local function copy_pointed_thing(pointed_thing) + return { + type = pointed_thing.type, + above = pointed_thing.above and vector.copy(pointed_thing.above), + under = pointed_thing.under and vector.copy(pointed_thing.under), + ref = pointed_thing.ref, + } +end + +-- +-- Item definition helpers +-- + +function core.get_pointed_thing_position(pointed_thing, above) + if pointed_thing.type == "node" then + if above then + -- The position where a node would be placed + return pointed_thing.above + end + -- The position where a node would be dug + return pointed_thing.under + elseif pointed_thing.type == "object" then + return pointed_thing.ref and pointed_thing.ref:get_pos() + end +end + +local function has_all_groups(tbl, required_groups) + if type(required_groups) == "string" then + return (tbl[required_groups] or 0) ~= 0 + end + for _, group in ipairs(required_groups) do + if (tbl[group] or 0) == 0 then + return false + end + end + return true +end + +function core.get_node_drops(node, toolname) + -- Compatibility, if node is string + local nodename = node + local param2 = 0 + -- New format, if node is table + if (type(node) == "table") then + nodename = node.name + param2 = node.param2 + end + local def = core.registered_nodes[nodename] + local drop = def and def.drop + local ptype = def and def.paramtype2 + -- get color, if there is color (otherwise nil) + local palette_index = core.strip_param2_color(param2, ptype) + if drop == nil then + -- default drop + if palette_index then + local stack = ItemStack(nodename) + stack:get_meta():set_int("palette_index", palette_index) + return {stack:to_string()} + end + return {nodename} + elseif type(drop) == "string" then + -- itemstring drop + return drop ~= "" and {drop} or {} + elseif drop.items == nil then + -- drop = {} to disable default drop + return {} + end + + -- Extended drop table + local got_items = {} + local got_count = 0 + for _, item in ipairs(drop.items) do + local good_rarity = true + local good_tool = true + if item.rarity ~= nil then + good_rarity = item.rarity < 1 or math.random(item.rarity) == 1 + end + if item.tools ~= nil or item.tool_groups ~= nil then + good_tool = false + end + if item.tools ~= nil and toolname then + for _, tool in ipairs(item.tools) do + if tool:sub(1, 1) == '~' then + good_tool = toolname:find(tool:sub(2)) ~= nil + else + good_tool = toolname == tool + end + if good_tool then + break + end + end + end + if item.tool_groups ~= nil and toolname then + local tooldef = core.registered_items[toolname] + if tooldef ~= nil and type(tooldef.groups) == "table" then + if type(item.tool_groups) == "string" then + -- tool_groups can be a string which specifies the required group + good_tool = core.get_item_group(toolname, item.tool_groups) ~= 0 + else + -- tool_groups can be a list of sufficient requirements. + -- i.e. if any item in the list can be satisfied then the tool is good + assert(type(item.tool_groups) == "table") + for _, required_groups in ipairs(item.tool_groups) do + -- required_groups can be either a string (a single group), + -- or an array of strings where all must be in tooldef.groups + good_tool = has_all_groups(tooldef.groups, required_groups) + if good_tool then + break + end + end + end + end + end + if good_rarity and good_tool then + got_count = got_count + 1 + for _, add_item in ipairs(item.items) do + -- add color, if necessary + if item.inherit_color and palette_index then + local stack = ItemStack(add_item) + stack:get_meta():set_int("palette_index", palette_index) + add_item = stack:to_string() + end + got_items[#got_items+1] = add_item + end + if drop.max_items ~= nil and got_count == drop.max_items then + break + end + end + end + return got_items +end + +local function user_name(user) + return user and user:get_player_name() or "" +end + +-- Returns a logging function. For empty names, does not log. +local function make_log(name) + return name ~= "" and core.log or function() end +end + +function core.item_place_node(itemstack, placer, pointed_thing, param2, + prevent_after_place) + local def = itemstack:get_definition() + if def.type ~= "node" or pointed_thing.type ~= "node" then + return itemstack, nil + end + + local under = pointed_thing.under + local oldnode_under = core.get_node_or_nil(under) + local above = pointed_thing.above + local oldnode_above = core.get_node_or_nil(above) + local playername = user_name(placer) + local log = make_log(playername) + + if not oldnode_under or not oldnode_above then + log("info", playername .. " tried to place" + .. " node in unloaded position " .. core.pos_to_string(above)) + return itemstack, nil + end + + local olddef_under = core.registered_nodes[oldnode_under.name] + olddef_under = olddef_under or core.nodedef_default + local olddef_above = core.registered_nodes[oldnode_above.name] + olddef_above = olddef_above or core.nodedef_default + + if not olddef_above.buildable_to and not olddef_under.buildable_to then + log("info", playername .. " tried to place" + .. " node in invalid position " .. core.pos_to_string(above) + .. ", replacing " .. oldnode_above.name) + return itemstack, nil + end + + -- Place above pointed node + local place_to = vector.copy(above) + + -- If node under is buildable_to, place into it instead (eg. snow) + if olddef_under.buildable_to then + log("info", "node under is buildable to") + place_to = vector.copy(under) + end + + if core.is_protected(place_to, playername) then + log("action", playername + .. " tried to place " .. def.name + .. " at protected position " + .. core.pos_to_string(place_to)) + core.record_protection_violation(place_to, playername) + return itemstack, nil + end + + local oldnode = core.get_node(place_to) + local newnode = {name = def.name, param1 = 0, param2 = param2 or 0} + + -- Calculate direction for wall mounted stuff like torches and signs + if def.place_param2 ~= nil then + newnode.param2 = def.place_param2 + elseif (def.paramtype2 == "wallmounted" or + def.paramtype2 == "colorwallmounted") and not param2 then + local dir = vector.subtract(under, above) + newnode.param2 = core.dir_to_wallmounted(dir) + -- Calculate the direction for furnaces and chests and stuff + elseif (def.paramtype2 == "facedir" or + def.paramtype2 == "colorfacedir") and not param2 then + local placer_pos = placer and placer:get_pos() + if placer_pos then + local dir = vector.subtract(above, placer_pos) + newnode.param2 = core.dir_to_facedir(dir) + log("info", "facedir: " .. newnode.param2) + end + end + + local metatable = itemstack:get_meta():to_table().fields + + -- Transfer color information + if metatable.palette_index and not def.place_param2 then + local color_divisor = nil + if def.paramtype2 == "color" then + color_divisor = 1 + elseif def.paramtype2 == "colorwallmounted" then + color_divisor = 8 + elseif def.paramtype2 == "colorfacedir" then + color_divisor = 32 + elseif def.paramtype2 == "colordegrotate" then + color_divisor = 32 + end + if color_divisor then + local color = math.floor(metatable.palette_index / color_divisor) + local other = newnode.param2 % color_divisor + newnode.param2 = color * color_divisor + other + end + end + + -- Check if the node is attached and if it can be placed there + if core.get_item_group(def.name, "attached_node") ~= 0 and + not builtin_shared.check_attached_node(place_to, newnode) then + log("action", "attached node " .. def.name .. + " can not be placed at " .. core.pos_to_string(place_to)) + return itemstack, nil + end + + log("action", playername .. " places node " + .. def.name .. " at " .. core.pos_to_string(place_to)) + + -- Add node and update + core.add_node(place_to, newnode) + + -- Play sound if it was done by a player + if playername ~= "" and def.sounds and def.sounds.place then + core.sound_play(def.sounds.place, { + pos = place_to, + exclude_player = playername, + }, true) + end + + local take_item = true + + -- Run callback + if def.after_place_node and not prevent_after_place then + -- Deepcopy place_to and pointed_thing because callback can modify it + local place_to_copy = vector.copy(place_to) + local pointed_thing_copy = copy_pointed_thing(pointed_thing) + if def.after_place_node(place_to_copy, placer, itemstack, + pointed_thing_copy) then + take_item = false + end + end + + -- Run script hook + for _, callback in ipairs(core.registered_on_placenodes) do + -- Deepcopy pos, node and pointed_thing because callback can modify them + local place_to_copy = vector.copy(place_to) + local newnode_copy = {name=newnode.name, param1=newnode.param1, param2=newnode.param2} + local oldnode_copy = {name=oldnode.name, param1=oldnode.param1, param2=oldnode.param2} + local pointed_thing_copy = copy_pointed_thing(pointed_thing) + if callback(place_to_copy, newnode_copy, placer, oldnode_copy, itemstack, pointed_thing_copy) then + take_item = false + end + end + + if take_item then + itemstack:take_item() + end + return itemstack, place_to +end + +-- deprecated, item_place does not call this +function core.item_place_object(itemstack, placer, pointed_thing) + local pos = core.get_pointed_thing_position(pointed_thing, true) + if pos ~= nil then + local item = itemstack:take_item() + core.add_item(pos, item) + end + return itemstack +end + +function core.item_place(itemstack, placer, pointed_thing, param2) + -- Call on_rightclick if the pointed node defines it + if pointed_thing.type == "node" and placer and + not placer:get_player_control().sneak then + local n = core.get_node(pointed_thing.under) + local nn = n.name + if core.registered_nodes[nn] and core.registered_nodes[nn].on_rightclick then + return core.registered_nodes[nn].on_rightclick(pointed_thing.under, n, + placer, itemstack, pointed_thing) or itemstack, nil + end + end + + -- Place if node, otherwise do nothing + if itemstack:get_definition().type == "node" then + return core.item_place_node(itemstack, placer, pointed_thing, param2) + end + return itemstack, nil +end + +function core.item_secondary_use(itemstack, placer) + return itemstack +end + +function core.item_drop(itemstack, dropper, pos) + local dropper_is_player = dropper and dropper:is_player() + local p = table.copy(pos) + local cnt = itemstack:get_count() + if dropper_is_player then + p.y = p.y + 1.2 + end + local item = itemstack:take_item(cnt) + local obj = core.add_item(p, item) + if obj then + if dropper_is_player then + local dir = dropper:get_look_dir() + dir.x = dir.x * 2.9 + dir.y = dir.y * 2.9 + 2 + dir.z = dir.z * 2.9 + obj:set_velocity(dir) + obj:get_luaentity().dropped_by = dropper:get_player_name() + end + return itemstack + end + -- If we reach this, adding the object to the + -- environment failed +end + +function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing) + for _, callback in pairs(core.registered_on_item_eats) do + local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing) + if result then + return result + end + end + -- read definition before potentially emptying the stack + local def = itemstack:get_definition() + if itemstack:take_item():is_empty() then + return itemstack + end + + if def and def.sound and def.sound.eat then + core.sound_play(def.sound.eat, { + pos = user:get_pos(), + max_hear_distance = 16 + }, true) + end + + -- Changing hp might kill the player causing mods to do who-knows-what to the + -- inventory, so do this before set_hp(). + if replace_with_item then + if itemstack:is_empty() then + itemstack:add_item(replace_with_item) + else + local inv = user:get_inventory() + -- Check if inv is null, since non-players don't have one + if inv and inv:room_for_item("main", {name=replace_with_item}) then + inv:add_item("main", replace_with_item) + else + local pos = user:get_pos() + pos.y = math.floor(pos.y + 0.5) + core.add_item(pos, replace_with_item) + end + end + end + user:set_wielded_item(itemstack) + + user:set_hp(user:get_hp() + hp_change) + + return nil -- don't overwrite wield item a second time +end + +function core.item_eat(hp_change, replace_with_item) + return function(itemstack, user, pointed_thing) -- closure + if user then + return core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing) + end + end +end + +function core.node_punch(pos, node, puncher, pointed_thing) + -- Run script hook + for _, callback in ipairs(core.registered_on_punchnodes) do + -- Copy pos and node because callback can modify them + local pos_copy = vector.copy(pos) + local node_copy = {name=node.name, param1=node.param1, param2=node.param2} + local pointed_thing_copy = pointed_thing and copy_pointed_thing(pointed_thing) or nil + callback(pos_copy, node_copy, puncher, pointed_thing_copy) + end +end + +function core.handle_node_drops(pos, drops, digger) + -- Add dropped items to object's inventory + local inv = digger and digger:get_inventory() + local give_item + if inv then + give_item = function(item) + return inv:add_item("main", item) + end + else + give_item = function(item) + -- itemstring to ItemStack for left:is_empty() + return ItemStack(item) + end + end + + for _, dropped_item in pairs(drops) do + local left = give_item(dropped_item) + if not left:is_empty() then + local p = vector.offset(pos, + math.random()/2-0.25, + math.random()/2-0.25, + math.random()/2-0.25 + ) + core.add_item(p, left) + end + end +end + +function core.node_dig(pos, node, digger) + local diggername = user_name(digger) + local log = make_log(diggername) + local def = core.registered_nodes[node.name] + -- Copy pos because the callback could modify it + if def and (not def.diggable or + (def.can_dig and not def.can_dig(vector.copy(pos), digger))) then + log("info", diggername .. " tried to dig " + .. node.name .. " which is not diggable " + .. core.pos_to_string(pos)) + return false + end + + if core.is_protected(pos, diggername) then + log("action", diggername + .. " tried to dig " .. node.name + .. " at protected position " + .. core.pos_to_string(pos)) + core.record_protection_violation(pos, diggername) + return false + end + + log('action', diggername .. " digs " + .. node.name .. " at " .. core.pos_to_string(pos)) + + local wielded = digger and digger:get_wielded_item() + local drops = core.get_node_drops(node, wielded and wielded:get_name()) + + if wielded then + local wdef = wielded:get_definition() + local tp = wielded:get_tool_capabilities() + local dp = core.get_dig_params(def and def.groups, tp, wielded:get_wear()) + if wdef and wdef.after_use then + wielded = wdef.after_use(wielded, digger, node, dp) or wielded + else + -- Wear out tool + if not core.is_creative_enabled(diggername) then + wielded:add_wear(dp.wear) + if wielded:get_count() == 0 and wdef.sound and wdef.sound.breaks then + core.sound_play(wdef.sound.breaks, { + pos = pos, + gain = 0.5 + }, true) + end + end + end + digger:set_wielded_item(wielded) + end + + -- Check to see if metadata should be preserved. + if def and def.preserve_metadata then + local oldmeta = core.get_meta(pos):to_table().fields + -- Copy pos and node because the callback can modify them. + local pos_copy = vector.copy(pos) + local node_copy = {name=node.name, param1=node.param1, param2=node.param2} + local drop_stacks = {} + for k, v in pairs(drops) do + drop_stacks[k] = ItemStack(v) + end + drops = drop_stacks + def.preserve_metadata(pos_copy, node_copy, oldmeta, drops) + end + + -- Handle drops + core.handle_node_drops(pos, drops, digger) + + local oldmetadata = nil + if def and def.after_dig_node then + oldmetadata = core.get_meta(pos):to_table() + end + + -- Remove node and update + core.remove_node(pos) + + -- Play sound if it was done by a player + if diggername ~= "" and def and def.sounds and def.sounds.dug then + core.sound_play(def.sounds.dug, { + pos = pos, + exclude_player = diggername, + }, true) + end + + -- Run callback + if def and def.after_dig_node then + -- Copy pos and node because callback can modify them + local pos_copy = vector.copy(pos) + local node_copy = {name=node.name, param1=node.param1, param2=node.param2} + def.after_dig_node(pos_copy, node_copy, oldmetadata, digger) + end + + -- Run script hook + for _, callback in ipairs(core.registered_on_dignodes) do + local origin = core.callback_origins[callback] + core.set_last_run_mod(origin.mod) + + -- Copy pos and node because callback can modify them + local pos_copy = vector.copy(pos) + local node_copy = {name=node.name, param1=node.param1, param2=node.param2} + callback(pos_copy, node_copy, digger) + end + + return true +end + +function core.itemstring_with_palette(item, palette_index) + local stack = ItemStack(item) -- convert to ItemStack + stack:get_meta():set_int("palette_index", palette_index) + return stack:to_string() +end + +function core.itemstring_with_color(item, colorstring) + local stack = ItemStack(item) -- convert to ItemStack + stack:get_meta():set_string("color", colorstring) + return stack:to_string() +end + +-- This is used to allow mods to redefine core.item_place and so on +-- NOTE: This is not the preferred way. Preferred way is to provide enough +-- callbacks to not require redefining global functions. -celeron55 +local function redef_wrapper(table, name) + return function(...) + return table[name](...) + end +end + +-- +-- Item definition defaults +-- + +local default_stack_max = tonumber(core.settings:get("default_stack_max")) or 99 + +core.nodedef_default = { + -- Item properties + type="node", + -- name intentionally not defined here + description = "", + groups = {}, + inventory_image = "", + wield_image = "", + wield_scale = vector.new(1, 1, 1), + stack_max = default_stack_max, + usable = false, + liquids_pointable = false, + tool_capabilities = nil, + node_placement_prediction = nil, + + -- Interaction callbacks + on_place = redef_wrapper(core, 'item_place'), -- core.item_place + on_drop = redef_wrapper(core, 'item_drop'), -- core.item_drop + on_use = nil, + can_dig = nil, + + on_punch = redef_wrapper(core, 'node_punch'), -- core.node_punch + on_rightclick = nil, + on_dig = redef_wrapper(core, 'node_dig'), -- core.node_dig + + on_receive_fields = nil, + + -- Node properties + drawtype = "normal", + visual_scale = 1.0, + tiles = nil, + special_tiles = nil, + post_effect_color = {a=0, r=0, g=0, b=0}, + paramtype = "none", + paramtype2 = "none", + is_ground_content = true, + sunlight_propagates = false, + walkable = true, + pointable = true, + diggable = true, + climbable = false, + buildable_to = false, + floodable = false, + liquidtype = "none", + liquid_alternative_flowing = "", + liquid_alternative_source = "", + liquid_viscosity = 0, + drowning = 0, + light_source = 0, + damage_per_second = 0, + selection_box = {type="regular"}, + legacy_facedir_simple = false, + legacy_wallmounted = false, +} + +core.craftitemdef_default = { + type="craft", + -- name intentionally not defined here + description = "", + groups = {}, + inventory_image = "", + wield_image = "", + wield_scale = vector.new(1, 1, 1), + stack_max = default_stack_max, + liquids_pointable = false, + tool_capabilities = nil, + + -- Interaction callbacks + on_place = redef_wrapper(core, 'item_place'), -- core.item_place + on_drop = redef_wrapper(core, 'item_drop'), -- core.item_drop + on_secondary_use = redef_wrapper(core, 'item_secondary_use'), + on_use = nil, +} + +core.tooldef_default = { + type="tool", + -- name intentionally not defined here + description = "", + groups = {}, + inventory_image = "", + wield_image = "", + wield_scale = vector.new(1, 1, 1), + stack_max = 1, + liquids_pointable = false, + tool_capabilities = nil, + + -- Interaction callbacks + on_place = redef_wrapper(core, 'item_place'), -- core.item_place + on_secondary_use = redef_wrapper(core, 'item_secondary_use'), + on_drop = redef_wrapper(core, 'item_drop'), -- core.item_drop + on_use = nil, +} + +core.noneitemdef_default = { -- This is used for the hand and unknown items + type="none", + -- name intentionally not defined here + description = "", + groups = {}, + inventory_image = "", + wield_image = "", + wield_scale = vector.new(1, 1, 1), + stack_max = default_stack_max, + liquids_pointable = false, + tool_capabilities = nil, + + -- Interaction callbacks + on_place = redef_wrapper(core, 'item_place'), + on_secondary_use = redef_wrapper(core, 'item_secondary_use'), + on_drop = nil, + on_use = nil, +} diff --git a/builtin/game/item_entity.lua b/builtin/game/item_entity.lua new file mode 100644 index 0000000..53f98a7 --- /dev/null +++ b/builtin/game/item_entity.lua @@ -0,0 +1,333 @@ +-- Minetest: builtin/item_entity.lua + +function core.spawn_item(pos, item) + -- Take item in any format + local stack = ItemStack(item) + local obj = core.add_entity(pos, "__builtin:item") + -- Don't use obj if it couldn't be added to the map. + if obj then + obj:get_luaentity():set_item(stack:to_string()) + end + return obj +end + +-- If item_entity_ttl is not set, enity will have default life time +-- Setting it to -1 disables the feature + +local time_to_live = tonumber(core.settings:get("item_entity_ttl")) or 900 +local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81 + + +core.register_entity(":__builtin:item", { + initial_properties = { + hp_max = 1, + physical = true, + collide_with_objects = false, + collisionbox = {-0.3, -0.3, -0.3, 0.3, 0.3, 0.3}, + visual = "wielditem", + visual_size = {x = 0.4, y = 0.4}, + textures = {""}, + is_visible = false, + }, + + itemstring = "", + moving_state = true, + physical_state = true, + -- Item expiry + age = 0, + -- Pushing item out of solid nodes + force_out = nil, + force_out_start = nil, + + set_item = function(self, item) + local stack = ItemStack(item or self.itemstring) + self.itemstring = stack:to_string() + if self.itemstring == "" then + -- item not yet known + return + end + + -- Backwards compatibility: old clients use the texture + -- to get the type of the item + local itemname = stack:is_known() and stack:get_name() or "unknown" + + local max_count = stack:get_stack_max() + local count = math.min(stack:get_count(), max_count) + local size = 0.2 + 0.1 * (count / max_count) ^ (1 / 3) + local def = core.registered_items[itemname] + local glow = def and def.light_source and + math.floor(def.light_source / 2 + 0.5) + + local size_bias = 1e-3 * math.random() -- small random bias to counter Z-fighting + local c = {-size, -size, -size, size, size, size} + self.object:set_properties({ + is_visible = true, + visual = "wielditem", + textures = {itemname}, + visual_size = {x = size + size_bias, y = size + size_bias}, + collisionbox = c, + automatic_rotate = math.pi * 0.5 * 0.2 / size, + wield_item = self.itemstring, + glow = glow, + }) + + -- cache for usage in on_step + self._collisionbox = c + end, + + get_staticdata = function(self) + return core.serialize({ + itemstring = self.itemstring, + age = self.age, + dropped_by = self.dropped_by + }) + end, + + on_activate = function(self, staticdata, dtime_s) + if string.sub(staticdata, 1, string.len("return")) == "return" then + local data = core.deserialize(staticdata) + if data and type(data) == "table" then + self.itemstring = data.itemstring + self.age = (data.age or 0) + dtime_s + self.dropped_by = data.dropped_by + end + else + self.itemstring = staticdata + end + self.object:set_armor_groups({immortal = 1}) + self.object:set_velocity({x = 0, y = 2, z = 0}) + self.object:set_acceleration({x = 0, y = -gravity, z = 0}) + self._collisionbox = self.initial_properties.collisionbox + self:set_item() + end, + + try_merge_with = function(self, own_stack, object, entity) + if self.age == entity.age then + -- Can not merge with itself + return false + end + + local stack = ItemStack(entity.itemstring) + local name = stack:get_name() + if own_stack:get_name() ~= name or + own_stack:get_meta() ~= stack:get_meta() or + own_stack:get_wear() ~= stack:get_wear() or + own_stack:get_free_space() == 0 then + -- Can not merge different or full stack + return false + end + + local count = own_stack:get_count() + local total_count = stack:get_count() + count + local max_count = stack:get_stack_max() + + if total_count > max_count then + return false + end + -- Merge the remote stack into this one + + local pos = object:get_pos() + pos.y = pos.y + ((total_count - count) / max_count) * 0.15 + self.object:move_to(pos) + + self.age = 0 -- Handle as new entity + own_stack:set_count(total_count) + self:set_item(own_stack) + + entity.itemstring = "" + object:remove() + return true + end, + + enable_physics = function(self) + if not self.physical_state then + self.physical_state = true + self.object:set_properties({physical = true}) + self.object:set_velocity({x=0, y=0, z=0}) + self.object:set_acceleration({x=0, y=-gravity, z=0}) + end + end, + + disable_physics = function(self) + if self.physical_state then + self.physical_state = false + self.object:set_properties({physical = false}) + self.object:set_velocity({x=0, y=0, z=0}) + self.object:set_acceleration({x=0, y=0, z=0}) + end + end, + + on_step = function(self, dtime, moveresult) + self.age = self.age + dtime + if time_to_live > 0 and self.age > time_to_live then + self.itemstring = "" + self.object:remove() + return + end + + local pos = self.object:get_pos() + local node = core.get_node_or_nil({ + x = pos.x, + y = pos.y + self._collisionbox[2] - 0.05, + z = pos.z + }) + -- Delete in 'ignore' nodes + if node and node.name == "ignore" then + self.itemstring = "" + self.object:remove() + return + end + + if self.force_out then + -- This code runs after the entity got a push from the is_stuck code. + -- It makes sure the entity is entirely outside the solid node + local c = self._collisionbox + local s = self.force_out_start + local f = self.force_out + local ok = (f.x > 0 and pos.x + c[1] > s.x + 0.5) or + (f.y > 0 and pos.y + c[2] > s.y + 0.5) or + (f.z > 0 and pos.z + c[3] > s.z + 0.5) or + (f.x < 0 and pos.x + c[4] < s.x - 0.5) or + (f.z < 0 and pos.z + c[6] < s.z - 0.5) + if ok then + -- Item was successfully forced out + self.force_out = nil + self:enable_physics() + return + end + end + + if not self.physical_state then + return -- Don't do anything + end + + assert(moveresult, + "Collision info missing, this is caused by an out-of-date/buggy mod or game") + + if not moveresult.collides then + -- future TODO: items should probably decelerate in air + return + end + + -- Push item out when stuck inside solid node + local is_stuck = false + local snode = core.get_node_or_nil(pos) + if snode then + local sdef = core.registered_nodes[snode.name] or {} + is_stuck = (sdef.walkable == nil or sdef.walkable == true) + and (sdef.collision_box == nil or sdef.collision_box.type == "regular") + and (sdef.node_box == nil or sdef.node_box.type == "regular") + end + + if is_stuck then + local shootdir + local order = { + {x=1, y=0, z=0}, {x=-1, y=0, z= 0}, + {x=0, y=0, z=1}, {x= 0, y=0, z=-1}, + } + + -- Check which one of the 4 sides is free + for o = 1, #order do + local cnode = core.get_node(vector.add(pos, order[o])).name + local cdef = core.registered_nodes[cnode] or {} + if cnode ~= "ignore" and cdef.walkable == false then + shootdir = order[o] + break + end + end + -- If none of the 4 sides is free, check upwards + if not shootdir then + shootdir = {x=0, y=1, z=0} + local cnode = core.get_node(vector.add(pos, shootdir)).name + if cnode == "ignore" then + shootdir = nil -- Do not push into ignore + end + end + + if shootdir then + -- Set new item moving speed accordingly + local newv = vector.multiply(shootdir, 3) + self:disable_physics() + self.object:set_velocity(newv) + + self.force_out = newv + self.force_out_start = vector.round(pos) + return + end + end + + node = nil -- ground node we're colliding with + if moveresult.touching_ground then + for _, info in ipairs(moveresult.collisions) do + if info.axis == "y" then + node = core.get_node(info.node_pos) + break + end + end + end + + -- Slide on slippery nodes + local def = node and core.registered_nodes[node.name] + local keep_movement = false + + if def then + local slippery = core.get_item_group(node.name, "slippery") + local vel = self.object:get_velocity() + if slippery ~= 0 and (math.abs(vel.x) > 0.1 or math.abs(vel.z) > 0.1) then + -- Horizontal deceleration + local factor = math.min(4 / (slippery + 4) * dtime, 1) + self.object:set_velocity({ + x = vel.x * (1 - factor), + y = 0, + z = vel.z * (1 - factor) + }) + keep_movement = true + end + end + + if not keep_movement then + self.object:set_velocity({x=0, y=0, z=0}) + end + + if self.moving_state == keep_movement then + -- Do not update anything until the moving state changes + return + end + self.moving_state = keep_movement + + -- Only collect items if not moving + if self.moving_state then + return + end + -- Collect the items around to merge with + local own_stack = ItemStack(self.itemstring) + if own_stack:get_free_space() == 0 then + return + end + local objects = core.get_objects_inside_radius(pos, 1.0) + for k, obj in pairs(objects) do + local entity = obj:get_luaentity() + if entity and entity.name == "__builtin:item" then + if self:try_merge_with(own_stack, obj, entity) then + own_stack = ItemStack(self.itemstring) + if own_stack:get_free_space() == 0 then + return + end + end + end + end + end, + + on_punch = function(self, hitter) + local inv = hitter:get_inventory() + if inv and self.itemstring ~= "" then + local left = inv:add_item("main", self.itemstring) + if left and not left:is_empty() then + self:set_item(left) + return + end + end + self.itemstring = "" + self.object:remove() + end, +}) diff --git a/builtin/game/item_s.lua b/builtin/game/item_s.lua new file mode 100644 index 0000000..a51cd0a --- /dev/null +++ b/builtin/game/item_s.lua @@ -0,0 +1,156 @@ +-- Minetest: builtin/item_s.lua +-- The distinction of what goes here is a bit tricky, basically it's everything +-- that does not (directly or indirectly) need access to ServerEnvironment, +-- Server or writable access to IGameDef on the engine side. +-- (The '_s' stands for standalone.) + +-- +-- Item definition helpers +-- + +function core.inventorycube(img1, img2, img3) + img2 = img2 or img1 + img3 = img3 or img1 + return "[inventorycube" + .. "{" .. img1:gsub("%^", "&") + .. "{" .. img2:gsub("%^", "&") + .. "{" .. img3:gsub("%^", "&") +end + +function core.dir_to_facedir(dir, is6d) + --account for y if requested + if is6d and math.abs(dir.y) > math.abs(dir.x) and math.abs(dir.y) > math.abs(dir.z) then + + --from above + if dir.y < 0 then + if math.abs(dir.x) > math.abs(dir.z) then + if dir.x < 0 then + return 19 + else + return 13 + end + else + if dir.z < 0 then + return 10 + else + return 4 + end + end + + --from below + else + if math.abs(dir.x) > math.abs(dir.z) then + if dir.x < 0 then + return 15 + else + return 17 + end + else + if dir.z < 0 then + return 6 + else + return 8 + end + end + end + + --otherwise, place horizontally + elseif math.abs(dir.x) > math.abs(dir.z) then + if dir.x < 0 then + return 3 + else + return 1 + end + else + if dir.z < 0 then + return 2 + else + return 0 + end + end +end + +-- Table of possible dirs +local facedir_to_dir = { + vector.new( 0, 0, 1), + vector.new( 1, 0, 0), + vector.new( 0, 0, -1), + vector.new(-1, 0, 0), + vector.new( 0, -1, 0), + vector.new( 0, 1, 0), +} +-- Mapping from facedir value to index in facedir_to_dir. +local facedir_to_dir_map = { + [0]=1, 2, 3, 4, + 5, 2, 6, 4, + 6, 2, 5, 4, + 1, 5, 3, 6, + 1, 6, 3, 5, + 1, 4, 3, 2, +} +function core.facedir_to_dir(facedir) + return facedir_to_dir[facedir_to_dir_map[facedir % 32]] +end + +function core.dir_to_wallmounted(dir) + if math.abs(dir.y) > math.max(math.abs(dir.x), math.abs(dir.z)) then + if dir.y < 0 then + return 1 + else + return 0 + end + elseif math.abs(dir.x) > math.abs(dir.z) then + if dir.x < 0 then + return 3 + else + return 2 + end + else + if dir.z < 0 then + return 5 + else + return 4 + end + end +end + +-- table of dirs in wallmounted order +local wallmounted_to_dir = { + [0] = vector.new( 0, 1, 0), + vector.new( 0, -1, 0), + vector.new( 1, 0, 0), + vector.new(-1, 0, 0), + vector.new( 0, 0, 1), + vector.new( 0, 0, -1), +} +function core.wallmounted_to_dir(wallmounted) + return wallmounted_to_dir[wallmounted % 8] +end + +function core.dir_to_yaw(dir) + return -math.atan2(dir.x, dir.z) +end + +function core.yaw_to_dir(yaw) + return vector.new(-math.sin(yaw), 0, math.cos(yaw)) +end + +function core.is_colored_paramtype(ptype) + return (ptype == "color") or (ptype == "colorfacedir") or + (ptype == "colorwallmounted") or (ptype == "colordegrotate") +end + +function core.strip_param2_color(param2, paramtype2) + if not core.is_colored_paramtype(paramtype2) then + return nil + end + if paramtype2 == "colorfacedir" then + param2 = math.floor(param2 / 32) * 32 + elseif paramtype2 == "colorwallmounted" then + param2 = math.floor(param2 / 8) * 8 + elseif paramtype2 == "colordegrotate" then + param2 = math.floor(param2 / 32) * 32 + end + -- paramtype2 == "color" requires no modification. + return param2 +end diff --git a/builtin/game/knockback.lua b/builtin/game/knockback.lua new file mode 100644 index 0000000..a937aa1 --- /dev/null +++ b/builtin/game/knockback.lua @@ -0,0 +1,46 @@ +-- can be overriden by mods +function core.calculate_knockback(player, hitter, time_from_last_punch, tool_capabilities, dir, distance, damage) + if damage == 0 or player:get_armor_groups().immortal then + return 0.0 + end + + local m = 8 + -- solve m - m*e^(k*4) = 4 for k + local k = -0.17328 + local res = m - m * math.exp(k * damage) + + if distance < 2.0 then + res = res * 1.1 -- more knockback when closer + elseif distance > 4.0 then + res = res * 0.9 -- less when far away + end + return res +end + +local function vector_absmax(v) + local max, abs = math.max, math.abs + return max(max(abs(v.x), abs(v.y)), abs(v.z)) +end + +core.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, unused_dir, damage) + if player:get_hp() == 0 then + return -- RIP + end + + -- Server::handleCommand_Interact() adds eye offset to one but not the other + -- so the direction is slightly off, calculate it ourselves + local dir = vector.subtract(player:get_pos(), hitter:get_pos()) + local d = vector.length(dir) + if d ~= 0.0 then + dir = vector.divide(dir, d) + end + + local k = core.calculate_knockback(player, hitter, time_from_last_punch, tool_capabilities, dir, d, damage) + + local kdir = vector.multiply(dir, k) + if vector_absmax(kdir) < 1.0 then + return -- barely noticeable, so don't even send + end + + player:add_velocity(kdir) +end) diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua new file mode 100644 index 0000000..997b189 --- /dev/null +++ b/builtin/game/misc.lua @@ -0,0 +1,266 @@ +-- Minetest: builtin/misc.lua + +local S = core.get_translator("__builtin") + +-- +-- Misc. API functions +-- + +-- @spec core.kick_player(String, String) :: Boolean +function core.kick_player(player_name, reason) + if type(reason) == "string" then + reason = "Kicked: " .. reason + else + reason = "Kicked." + end + return core.disconnect_player(player_name, reason) +end + +function core.check_player_privs(name, ...) + if core.is_player(name) then + name = name:get_player_name() + elseif type(name) ~= "string" then + error("core.check_player_privs expects a player or playername as " .. + "argument.", 2) + end + + local requested_privs = {...} + local player_privs = core.get_player_privs(name) + local missing_privileges = {} + + if type(requested_privs[1]) == "table" then + -- We were provided with a table like { privA = true, privB = true }. + for priv, value in pairs(requested_privs[1]) do + if value and not player_privs[priv] then + missing_privileges[#missing_privileges + 1] = priv + end + end + else + -- Only a list, we can process it directly. + for key, priv in pairs(requested_privs) do + if not player_privs[priv] then + missing_privileges[#missing_privileges + 1] = priv + end + end + end + + if #missing_privileges > 0 then + return false, missing_privileges + end + + return true, "" +end + + +function core.send_join_message(player_name) + if not core.is_singleplayer() then + core.chat_send_all("*** " .. S("@1 joined the game.", player_name)) + end +end + + +function core.send_leave_message(player_name, timed_out) + local announcement = "*** " .. S("@1 left the game.", player_name) + if timed_out then + announcement = "*** " .. S("@1 left the game (timed out).", player_name) + end + core.chat_send_all(announcement) +end + + +core.register_on_joinplayer(function(player) + local player_name = player:get_player_name() + if not core.is_singleplayer() then + local status = core.get_server_status(player_name, true) + if status and status ~= "" then + core.chat_send_player(player_name, status) + end + end + core.send_join_message(player_name) +end) + + +core.register_on_leaveplayer(function(player, timed_out) + local player_name = player:get_player_name() + core.send_leave_message(player_name, timed_out) +end) + + +function core.is_player(player) + -- a table being a player is also supported because it quacks sufficiently + -- like a player if it has the is_player function + local t = type(player) + return (t == "userdata" or t == "table") and + type(player.is_player) == "function" and player:is_player() +end + + +function core.player_exists(name) + return core.get_auth_handler().get_auth(name) ~= nil +end + + +-- Returns two position vectors representing a box of `radius` in each +-- direction centered around the player corresponding to `player_name` + +function core.get_player_radius_area(player_name, radius) + local player = core.get_player_by_name(player_name) + if player == nil then + return nil + end + + local p1 = player:get_pos() + local p2 = p1 + + if radius then + p1 = vector.subtract(p1, radius) + p2 = vector.add(p2, radius) + end + + return p1, p2 +end + + +-- To be overriden by protection mods + +function core.is_protected(pos, name) + return false +end + + +function core.record_protection_violation(pos, name) + for _, func in pairs(core.registered_on_protection_violation) do + func(pos, name) + end +end + +-- To be overridden by Creative mods + +local creative_mode_cache = core.settings:get_bool("creative_mode") +function core.is_creative_enabled(name) + return creative_mode_cache +end + +-- Checks if specified volume intersects a protected volume + +function core.is_area_protected(minp, maxp, player_name, interval) + -- 'interval' is the largest allowed interval for the 3D lattice of checks. + + -- Compute the optimal float step 'd' for each axis so that all corners and + -- borders are checked. 'd' will be smaller or equal to 'interval'. + -- Subtracting 1e-4 ensures that the max co-ordinate will be reached by the + -- for loop (which might otherwise not be the case due to rounding errors). + + -- Default to 4 + interval = interval or 4 + local d = {} + + for _, c in pairs({"x", "y", "z"}) do + if minp[c] > maxp[c] then + -- Repair positions: 'minp' > 'maxp' + local tmp = maxp[c] + maxp[c] = minp[c] + minp[c] = tmp + end + + if maxp[c] > minp[c] then + d[c] = (maxp[c] - minp[c]) / + math.ceil((maxp[c] - minp[c]) / interval) - 1e-4 + else + d[c] = 1 -- Any value larger than 0 to avoid division by zero + end + end + + for zf = minp.z, maxp.z, d.z do + local z = math.floor(zf + 0.5) + for yf = minp.y, maxp.y, d.y do + local y = math.floor(yf + 0.5) + for xf = minp.x, maxp.x, d.x do + local x = math.floor(xf + 0.5) + local pos = vector.new(x, y, z) + if core.is_protected(pos, player_name) then + return pos + end + end + end + end + return false +end + + +local raillike_ids = {} +local raillike_cur_id = 0 +function core.raillike_group(name) + local id = raillike_ids[name] + if not id then + raillike_cur_id = raillike_cur_id + 1 + raillike_ids[name] = raillike_cur_id + id = raillike_cur_id + end + return id +end + + +-- HTTP callback interface + +core.set_http_api_lua(function(httpenv) + httpenv.fetch = function(req, callback) + local handle = httpenv.fetch_async(req) + + local function update_http_status() + local res = httpenv.fetch_async_get(handle) + if res.completed then + callback(res) + else + core.after(0, update_http_status) + end + end + core.after(0, update_http_status) + end + + return httpenv +end) +core.set_http_api_lua = nil + + +function core.close_formspec(player_name, formname) + return core.show_formspec(player_name, formname, "") +end + + +function core.cancel_shutdown_requests() + core.request_shutdown("", false, -1) +end + + +-- Used for callback handling with dynamic_add_media +core.dynamic_media_callbacks = {} + + +-- Transfer of certain globals into async environment +-- see builtin/async/game.lua for the other side + +local function copy_filtering(t, seen) + if type(t) == "userdata" or type(t) == "function" then + return true -- don't use nil so presence can still be detected + elseif type(t) ~= "table" then + return t + end + local n = {} + seen = seen or {} + seen[t] = n + for k, v in pairs(t) do + local k_ = seen[k] or copy_filtering(k, seen) + local v_ = seen[v] or copy_filtering(v, seen) + n[k_] = v_ + end + return n +end + +function core.get_globals_to_transfer() + local all = { + registered_items = copy_filtering(core.registered_items), + registered_aliases = core.registered_aliases, + } + return all +end diff --git a/builtin/game/misc_s.lua b/builtin/game/misc_s.lua new file mode 100644 index 0000000..67a0ec6 --- /dev/null +++ b/builtin/game/misc_s.lua @@ -0,0 +1,93 @@ +-- Minetest: builtin/misc_s.lua +-- The distinction of what goes here is a bit tricky, basically it's everything +-- that does not (directly or indirectly) need access to ServerEnvironment, +-- Server or writable access to IGameDef on the engine side. +-- (The '_s' stands for standalone.) + +-- +-- Misc. API functions +-- + +function core.hash_node_position(pos) + return (pos.z + 32768) * 65536 * 65536 + + (pos.y + 32768) * 65536 + + pos.x + 32768 +end + + +function core.get_position_from_hash(hash) + local x = (hash % 65536) - 32768 + hash = math.floor(hash / 65536) + local y = (hash % 65536) - 32768 + hash = math.floor(hash / 65536) + local z = (hash % 65536) - 32768 + return vector.new(x, y, z) +end + + +function core.get_item_group(name, group) + if not core.registered_items[name] or not + core.registered_items[name].groups[group] then + return 0 + end + return core.registered_items[name].groups[group] +end + + +function core.get_node_group(name, group) + core.log("deprecated", "Deprecated usage of get_node_group, use get_item_group instead") + return core.get_item_group(name, group) +end + + +function core.setting_get_pos(name) + local value = core.settings:get(name) + if not value then + return nil + end + return core.string_to_pos(value) +end + + +-- See l_env.cpp for the other functions +function core.get_artificial_light(param1) + return math.floor(param1 / 16) +end + +-- PNG encoder safety wrapper + +local o_encode_png = core.encode_png +function core.encode_png(width, height, data, compression) + if type(width) ~= "number" then + error("Incorrect type for 'width', expected number, got " .. type(width)) + end + if type(height) ~= "number" then + error("Incorrect type for 'height', expected number, got " .. type(height)) + end + + local expected_byte_count = width * height * 4 + + if type(data) ~= "table" and type(data) ~= "string" then + error("Incorrect type for 'data', expected table or string, got " .. type(data)) + end + + local data_length = type(data) == "table" and #data * 4 or string.len(data) + + if data_length ~= expected_byte_count then + error(string.format( + "Incorrect length of 'data', width and height imply %d bytes but %d were provided", + expected_byte_count, + data_length + )) + end + + if type(data) == "table" then + local dataBuf = {} + for i = 1, #data do + dataBuf[i] = core.colorspec_to_bytes(data[i]) + end + data = table.concat(dataBuf) + end + + return o_encode_png(width, height, data, compression or 6) +end diff --git a/builtin/game/privileges.lua b/builtin/game/privileges.lua new file mode 100644 index 0000000..2ff4c09 --- /dev/null +++ b/builtin/game/privileges.lua @@ -0,0 +1,108 @@ +-- Minetest: builtin/privileges.lua + +local S = core.get_translator("__builtin") + +-- +-- Privileges +-- + +core.registered_privileges = {} + +function core.register_privilege(name, param) + local function fill_defaults(def) + if def.give_to_singleplayer == nil then + def.give_to_singleplayer = true + end + if def.give_to_admin == nil then + def.give_to_admin = def.give_to_singleplayer + end + if def.description == nil then + def.description = S("(no description)") + end + end + local def + if type(param) == "table" then + def = param + else + def = {description = param} + end + fill_defaults(def) + core.registered_privileges[name] = def +end + +core.register_privilege("interact", S("Can interact with things and modify the world")) +core.register_privilege("shout", S("Can speak in chat")) + +local basic_privs = + core.string_to_privs((core.settings:get("basic_privs") or "shout,interact")) +local basic_privs_desc = S("Can modify basic privileges (@1)", + core.privs_to_string(basic_privs, ', ')) +core.register_privilege("basic_privs", basic_privs_desc) + +core.register_privilege("privs", S("Can modify privileges")) + +core.register_privilege("teleport", { + description = S("Can teleport self"), + give_to_singleplayer = false, +}) +core.register_privilege("bring", { + description = S("Can teleport other players"), + give_to_singleplayer = false, +}) +core.register_privilege("settime", { + description = S("Can set the time of day using /time"), + give_to_singleplayer = false, +}) +core.register_privilege("server", { + description = S("Can do server maintenance stuff"), + give_to_singleplayer = false, + give_to_admin = true, +}) +core.register_privilege("protection_bypass", { + description = S("Can bypass node protection in the world"), + give_to_singleplayer = false, +}) +core.register_privilege("ban", { + description = S("Can ban and unban players"), + give_to_singleplayer = false, + give_to_admin = true, +}) +core.register_privilege("kick", { + description = S("Can kick players"), + give_to_singleplayer = false, + give_to_admin = true, +}) +core.register_privilege("give", { + description = S("Can use /give and /giveme"), + give_to_singleplayer = false, +}) +core.register_privilege("password", { + description = S("Can use /setpassword and /clearpassword"), + give_to_singleplayer = false, + give_to_admin = true, +}) +core.register_privilege("fly", { + description = S("Can use fly mode"), + give_to_singleplayer = false, +}) +core.register_privilege("fast", { + description = S("Can use fast mode"), + give_to_singleplayer = false, +}) +core.register_privilege("noclip", { + description = S("Can fly through solid nodes using noclip mode"), + give_to_singleplayer = false, +}) +core.register_privilege("rollback", { + description = S("Can use the rollback functionality"), + give_to_singleplayer = false, +}) +core.register_privilege("debug", { + description = S("Can enable wireframe"), + give_to_singleplayer = false, +}) + +core.register_can_bypass_userlimit(function(name, ip) + local privs = core.get_player_privs(name) + return privs["server"] or privs["ban"] or privs["privs"] or privs["password"] +end) diff --git a/builtin/game/register.lua b/builtin/game/register.lua new file mode 100644 index 0000000..8b6f5b9 --- /dev/null +++ b/builtin/game/register.lua @@ -0,0 +1,625 @@ +-- Minetest: builtin/register.lua + +local S = core.get_translator("__builtin") + +-- +-- Make raw registration functions inaccessible to anyone except this file +-- + +local register_item_raw = core.register_item_raw +core.register_item_raw = nil + +local unregister_item_raw = core.unregister_item_raw +core.unregister_item_raw = nil + +local register_alias_raw = core.register_alias_raw +core.register_alias_raw = nil + +-- +-- Item / entity / ABM / LBM registration functions +-- + +core.registered_abms = {} +core.registered_lbms = {} +core.registered_entities = {} +core.registered_items = {} +core.registered_nodes = {} +core.registered_craftitems = {} +core.registered_tools = {} +core.registered_aliases = {} + +-- For tables that are indexed by item name: +-- If table[X] does not exist, default to table[core.registered_aliases[X]] +local alias_metatable = { + __index = function(t, name) + return rawget(t, core.registered_aliases[name]) + end +} +setmetatable(core.registered_items, alias_metatable) +setmetatable(core.registered_nodes, alias_metatable) +setmetatable(core.registered_craftitems, alias_metatable) +setmetatable(core.registered_tools, alias_metatable) + +-- These item names may not be used because they would interfere +-- with legacy itemstrings +local forbidden_item_names = { + MaterialItem = true, + MaterialItem2 = true, + MaterialItem3 = true, + NodeItem = true, + node = true, + CraftItem = true, + craft = true, + MBOItem = true, + ToolItem = true, + tool = true, +} + +local function check_modname_prefix(name) + if name:sub(1,1) == ":" then + -- If the name starts with a colon, we can skip the modname prefix + -- mechanism. + return name:sub(2) + else + -- Enforce that the name starts with the correct mod name. + local expected_prefix = core.get_current_modname() .. ":" + if name:sub(1, #expected_prefix) ~= expected_prefix then + error("Name " .. name .. " does not follow naming conventions: " .. + "\"" .. expected_prefix .. "\" or \":\" prefix required") + end + + -- Enforce that the name only contains letters, numbers and underscores. + local subname = name:sub(#expected_prefix+1) + if subname:find("[^%w_]") then + error("Name " .. name .. " does not follow naming conventions: " .. + "contains unallowed characters") + end + + return name + end +end + +function core.register_abm(spec) + -- Add to core.registered_abms + assert(type(spec.action) == "function", "Required field 'action' of type function") + core.registered_abms[#core.registered_abms + 1] = spec + spec.mod_origin = core.get_current_modname() or "??" +end + +function core.register_lbm(spec) + -- Add to core.registered_lbms + check_modname_prefix(spec.name) + assert(type(spec.action) == "function", "Required field 'action' of type function") + core.registered_lbms[#core.registered_lbms + 1] = spec + spec.mod_origin = core.get_current_modname() or "??" +end + +function core.register_entity(name, prototype) + -- Check name + if name == nil then + error("Unable to register entity: Name is nil") + end + name = check_modname_prefix(tostring(name)) + + prototype.name = name + prototype.__index = prototype -- so that it can be used as a metatable + + -- Add to core.registered_entities + core.registered_entities[name] = prototype + prototype.mod_origin = core.get_current_modname() or "??" +end + +function core.register_item(name, itemdef) + -- Check name + if name == nil then + error("Unable to register item: Name is nil") + end + name = check_modname_prefix(tostring(name)) + if forbidden_item_names[name] then + error("Unable to register item: Name is forbidden: " .. name) + end + itemdef.name = name + + -- Apply defaults and add to registered_* table + if itemdef.type == "node" then + -- Use the nodebox as selection box if it's not set manually + if itemdef.drawtype == "nodebox" and not itemdef.selection_box then + itemdef.selection_box = itemdef.node_box + elseif itemdef.drawtype == "fencelike" and not itemdef.selection_box then + itemdef.selection_box = { + type = "fixed", + fixed = {-1/8, -1/2, -1/8, 1/8, 1/2, 1/8}, + } + end + if itemdef.light_source and itemdef.light_source > core.LIGHT_MAX then + itemdef.light_source = core.LIGHT_MAX + core.log("warning", "Node 'light_source' value exceeds maximum," .. + " limiting to maximum: " ..name) + end + setmetatable(itemdef, {__index = core.nodedef_default}) + core.registered_nodes[itemdef.name] = itemdef + elseif itemdef.type == "craft" then + setmetatable(itemdef, {__index = core.craftitemdef_default}) + core.registered_craftitems[itemdef.name] = itemdef + elseif itemdef.type == "tool" then + setmetatable(itemdef, {__index = core.tooldef_default}) + core.registered_tools[itemdef.name] = itemdef + elseif itemdef.type == "none" then + setmetatable(itemdef, {__index = core.noneitemdef_default}) + else + error("Unable to register item: Type is invalid: " .. dump(itemdef)) + end + + -- Flowing liquid uses param2 + if itemdef.type == "node" and itemdef.liquidtype == "flowing" then + itemdef.paramtype2 = "flowingliquid" + end + + -- BEGIN Legacy stuff + if itemdef.cookresult_itemstring ~= nil and itemdef.cookresult_itemstring ~= "" then + core.register_craft({ + type="cooking", + output=itemdef.cookresult_itemstring, + recipe=itemdef.name, + cooktime=itemdef.furnace_cooktime + }) + end + if itemdef.furnace_burntime ~= nil and itemdef.furnace_burntime >= 0 then + core.register_craft({ + type="fuel", + recipe=itemdef.name, + burntime=itemdef.furnace_burntime + }) + end + -- END Legacy stuff + + itemdef.mod_origin = core.get_current_modname() or "??" + + -- Disable all further modifications + getmetatable(itemdef).__newindex = {} + + --core.log("Registering item: " .. itemdef.name) + core.registered_items[itemdef.name] = itemdef + core.registered_aliases[itemdef.name] = nil + register_item_raw(itemdef) +end + +function core.unregister_item(name) + if not core.registered_items[name] then + core.log("warning", "Not unregistering item " ..name.. + " because it doesn't exist.") + return + end + -- Erase from registered_* table + local type = core.registered_items[name].type + if type == "node" then + core.registered_nodes[name] = nil + elseif type == "craft" then + core.registered_craftitems[name] = nil + elseif type == "tool" then + core.registered_tools[name] = nil + end + core.registered_items[name] = nil + + + unregister_item_raw(name) +end + +function core.register_node(name, nodedef) + nodedef.type = "node" + core.register_item(name, nodedef) +end + +function core.register_craftitem(name, craftitemdef) + craftitemdef.type = "craft" + + -- BEGIN Legacy stuff + if craftitemdef.inventory_image == nil and craftitemdef.image ~= nil then + craftitemdef.inventory_image = craftitemdef.image + end + -- END Legacy stuff + + core.register_item(name, craftitemdef) +end + +function core.register_tool(name, tooldef) + tooldef.type = "tool" + tooldef.stack_max = 1 + + -- BEGIN Legacy stuff + if tooldef.inventory_image == nil and tooldef.image ~= nil then + tooldef.inventory_image = tooldef.image + end + if tooldef.tool_capabilities == nil and + (tooldef.full_punch_interval ~= nil or + tooldef.basetime ~= nil or + tooldef.dt_weight ~= nil or + tooldef.dt_crackiness ~= nil or + tooldef.dt_crumbliness ~= nil or + tooldef.dt_cuttability ~= nil or + tooldef.basedurability ~= nil or + tooldef.dd_weight ~= nil or + tooldef.dd_crackiness ~= nil or + tooldef.dd_crumbliness ~= nil or + tooldef.dd_cuttability ~= nil) then + tooldef.tool_capabilities = { + full_punch_interval = tooldef.full_punch_interval, + basetime = tooldef.basetime, + dt_weight = tooldef.dt_weight, + dt_crackiness = tooldef.dt_crackiness, + dt_crumbliness = tooldef.dt_crumbliness, + dt_cuttability = tooldef.dt_cuttability, + basedurability = tooldef.basedurability, + dd_weight = tooldef.dd_weight, + dd_crackiness = tooldef.dd_crackiness, + dd_crumbliness = tooldef.dd_crumbliness, + dd_cuttability = tooldef.dd_cuttability, + } + end + -- END Legacy stuff + + -- This isn't just legacy, but more of a convenience feature + local toolcaps = tooldef.tool_capabilities + if toolcaps and toolcaps.punch_attack_uses == nil then + for _, cap in pairs(toolcaps.groupcaps or {}) do + local level = (cap.maxlevel or 0) - 1 + if (cap.uses or 0) ~= 0 and level >= 0 then + toolcaps.punch_attack_uses = cap.uses * (3 ^ level) + break + end + end + end + + core.register_item(name, tooldef) +end + +function core.register_alias(name, convert_to) + if forbidden_item_names[name] then + error("Unable to register alias: Name is forbidden: " .. name) + end + if core.registered_items[name] ~= nil then + core.log("warning", "Not registering alias, item with same name" .. + " is already defined: " .. name .. " -> " .. convert_to) + else + --core.log("Registering alias: " .. name .. " -> " .. convert_to) + core.registered_aliases[name] = convert_to + register_alias_raw(name, convert_to) + end +end + +function core.register_alias_force(name, convert_to) + if forbidden_item_names[name] then + error("Unable to register alias: Name is forbidden: " .. name) + end + if core.registered_items[name] ~= nil then + core.unregister_item(name) + core.log("info", "Removed item " ..name.. + " while attempting to force add an alias") + end + --core.log("Registering alias: " .. name .. " -> " .. convert_to) + core.registered_aliases[name] = convert_to + register_alias_raw(name, convert_to) +end + +function core.on_craft(itemstack, player, old_craft_list, craft_inv) + for _, func in ipairs(core.registered_on_crafts) do + -- cast to ItemStack since func() could return a string + itemstack = ItemStack(func(itemstack, player, old_craft_list, craft_inv) or itemstack) + end + return itemstack +end + +function core.craft_predict(itemstack, player, old_craft_list, craft_inv) + for _, func in ipairs(core.registered_craft_predicts) do + -- cast to ItemStack since func() could return a string + itemstack = ItemStack(func(itemstack, player, old_craft_list, craft_inv) or itemstack) + end + return itemstack +end + +-- Alias the forbidden item names to "" so they can't be +-- created via itemstrings (e.g. /give) +for name in pairs(forbidden_item_names) do + core.registered_aliases[name] = "" + register_alias_raw(name, "") +end + +-- +-- Built-in node definitions. Also defined in C. +-- + +core.register_item(":unknown", { + type = "none", + description = S("Unknown Item"), + inventory_image = "unknown_item.png", + on_place = core.item_place, + on_secondary_use = core.item_secondary_use, + on_drop = core.item_drop, + groups = {not_in_creative_inventory=1}, + diggable = true, +}) + +core.register_node(":air", { + description = S("Air"), + inventory_image = "air.png", + wield_image = "air.png", + drawtype = "airlike", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + floodable = true, + air_equivalent = true, + drop = "", + groups = {not_in_creative_inventory=1}, +}) + +core.register_node(":ignore", { + description = S("Ignore"), + inventory_image = "ignore.png", + wield_image = "ignore.png", + drawtype = "airlike", + paramtype = "none", + sunlight_propagates = false, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, -- A way to remove accidentally placed ignores + air_equivalent = true, + drop = "", + groups = {not_in_creative_inventory=1}, + node_placement_prediction = "", + on_place = function(itemstack, placer, pointed_thing) + core.chat_send_player( + placer:get_player_name(), + core.colorize("#FF0000", + S("You can't place 'ignore' nodes!"))) + return "" + end, +}) + +-- The hand (bare definition) +core.register_item(":", { + type = "none", + wield_image = "wieldhand.png", + groups = {not_in_creative_inventory=1}, +}) + + +function core.override_item(name, redefinition) + if redefinition.name ~= nil then + error("Attempt to redefine name of "..name.." to "..dump(redefinition.name), 2) + end + if redefinition.type ~= nil then + error("Attempt to redefine type of "..name.." to "..dump(redefinition.type), 2) + end + local item = core.registered_items[name] + if not item then + error("Attempt to override non-existent item "..name, 2) + end + for k, v in pairs(redefinition) do + rawset(item, k, v) + end + register_item_raw(item) +end + +do + local default = {mod = "??", name = "??"} + core.callback_origins = setmetatable({}, { + __index = function() + return default + end + }) +end + +function core.run_callbacks(callbacks, mode, ...) + assert(type(callbacks) == "table") + local cb_len = #callbacks + if cb_len == 0 then + if mode == 2 or mode == 3 then + return true + elseif mode == 4 or mode == 5 then + return false + end + end + local ret = nil + for i = 1, cb_len do + local origin = core.callback_origins[callbacks[i]] + core.set_last_run_mod(origin.mod) + local cb_ret = callbacks[i](...) + + if mode == 0 and i == 1 then + ret = cb_ret + elseif mode == 1 and i == cb_len then + ret = cb_ret + elseif mode == 2 then + if not cb_ret or i == 1 then + ret = cb_ret + end + elseif mode == 3 then + if cb_ret then + return cb_ret + end + ret = cb_ret + elseif mode == 4 then + if (cb_ret and not ret) or i == 1 then + ret = cb_ret + end + elseif mode == 5 and cb_ret then + return cb_ret + end + end + return ret +end + +function core.run_priv_callbacks(name, priv, caller, method) + local def = core.registered_privileges[priv] + if not def or not def["on_" .. method] or + not def["on_" .. method](name, caller) then + for _, func in ipairs(core["registered_on_priv_" .. method]) do + if not func(name, caller, priv) then + break + end + end + end +end + +-- +-- Callback registration +-- + +local function make_registration() + local t = {} + local registerfunc = function(func) + t[#t + 1] = func + core.callback_origins[func] = { + mod = core.get_current_modname() or "??", + name = debug.getinfo(1, "n").name or "??" + } + --local origin = core.callback_origins[func] + --print(origin.name .. ": " .. origin.mod .. " registering cbk " .. tostring(func)) + end + return t, registerfunc +end + +local function make_registration_reverse() + local t = {} + local registerfunc = function(func) + table.insert(t, 1, func) + core.callback_origins[func] = { + mod = core.get_current_modname() or "??", + name = debug.getinfo(1, "n").name or "??" + } + --local origin = core.callback_origins[func] + --print(origin.name .. ": " .. origin.mod .. " registering cbk " .. tostring(func)) + end + return t, registerfunc +end + +local function make_registration_wrap(reg_fn_name, clear_fn_name) + local list = {} + + local orig_reg_fn = core[reg_fn_name] + core[reg_fn_name] = function(def) + local retval = orig_reg_fn(def) + if retval ~= nil then + if def.name ~= nil then + list[def.name] = def + else + list[retval] = def + end + end + return retval + end + + local orig_clear_fn = core[clear_fn_name] + core[clear_fn_name] = function() + for k in pairs(list) do + list[k] = nil + end + return orig_clear_fn() + end + + return list +end + +local function make_wrap_deregistration(reg_fn, clear_fn, list) + local unregister = function (key) + if type(key) ~= "string" then + error("key is not a string", 2) + end + if not list[key] then + error("Attempt to unregister non-existent element - '" .. key .. "'", 2) + end + local temporary_list = table.copy(list) + clear_fn() + for k,v in pairs(temporary_list) do + if key ~= k then + reg_fn(v) + end + end + end + return unregister +end + +core.registered_on_player_hpchanges = { modifiers = { }, loggers = { } } + +function core.registered_on_player_hpchange(player, hp_change, reason) + local last + for i = #core.registered_on_player_hpchanges.modifiers, 1, -1 do + local func = core.registered_on_player_hpchanges.modifiers[i] + hp_change, last = func(player, hp_change, reason) + if type(hp_change) ~= "number" then + local debuginfo = debug.getinfo(func) + error("The register_on_hp_changes function has to return a number at " .. + debuginfo.short_src .. " line " .. debuginfo.linedefined) + end + if last then + break + end + end + for i, func in ipairs(core.registered_on_player_hpchanges.loggers) do + func(player, hp_change, reason) + end + return hp_change +end + +function core.register_on_player_hpchange(func, modifier) + if modifier then + core.registered_on_player_hpchanges.modifiers[#core.registered_on_player_hpchanges.modifiers + 1] = func + else + core.registered_on_player_hpchanges.loggers[#core.registered_on_player_hpchanges.loggers + 1] = func + end + core.callback_origins[func] = { + mod = core.get_current_modname() or "??", + name = debug.getinfo(1, "n").name or "??" + } +end + +core.registered_biomes = make_registration_wrap("register_biome", "clear_registered_biomes") +core.registered_ores = make_registration_wrap("register_ore", "clear_registered_ores") +core.registered_decorations = make_registration_wrap("register_decoration", "clear_registered_decorations") + +core.unregister_biome = make_wrap_deregistration(core.register_biome, + core.clear_registered_biomes, core.registered_biomes) + +core.registered_on_chat_messages, core.register_on_chat_message = make_registration() +core.registered_on_chatcommands, core.register_on_chatcommand = make_registration() +core.registered_globalsteps, core.register_globalstep = make_registration() +core.registered_playerevents, core.register_playerevent = make_registration() +core.registered_on_mods_loaded, core.register_on_mods_loaded = make_registration() +core.registered_on_shutdown, core.register_on_shutdown = make_registration() +core.registered_on_punchnodes, core.register_on_punchnode = make_registration() +core.registered_on_placenodes, core.register_on_placenode = make_registration() +core.registered_on_dignodes, core.register_on_dignode = make_registration() +core.registered_on_generateds, core.register_on_generated = make_registration() +core.registered_on_newplayers, core.register_on_newplayer = make_registration() +core.registered_on_dieplayers, core.register_on_dieplayer = make_registration() +core.registered_on_respawnplayers, core.register_on_respawnplayer = make_registration() +core.registered_on_prejoinplayers, core.register_on_prejoinplayer = make_registration() +core.registered_on_joinplayers, core.register_on_joinplayer = make_registration() +core.registered_on_leaveplayers, core.register_on_leaveplayer = make_registration() +core.registered_on_player_receive_fields, core.register_on_player_receive_fields = make_registration_reverse() +core.registered_on_cheats, core.register_on_cheat = make_registration() +core.registered_on_crafts, core.register_on_craft = make_registration() +core.registered_craft_predicts, core.register_craft_predict = make_registration() +core.registered_on_protection_violation, core.register_on_protection_violation = make_registration() +core.registered_on_item_eats, core.register_on_item_eat = make_registration() +core.registered_on_punchplayers, core.register_on_punchplayer = make_registration() +core.registered_on_priv_grant, core.register_on_priv_grant = make_registration() +core.registered_on_priv_revoke, core.register_on_priv_revoke = make_registration() +core.registered_on_authplayers, core.register_on_authplayer = make_registration() +core.registered_can_bypass_userlimit, core.register_can_bypass_userlimit = make_registration() +core.registered_on_modchannel_message, core.register_on_modchannel_message = make_registration() +core.registered_on_player_inventory_actions, core.register_on_player_inventory_action = make_registration() +core.registered_allow_player_inventory_actions, core.register_allow_player_inventory_action = make_registration() +core.registered_on_rightclickplayers, core.register_on_rightclickplayer = make_registration() +core.registered_on_liquid_transformed, core.register_on_liquid_transformed = make_registration() + +-- +-- Compatibility for on_mapgen_init() +-- + +core.register_on_mapgen_init = function(func) func(core.get_mapgen_params()) end diff --git a/builtin/game/statbars.lua b/builtin/game/statbars.lua new file mode 100644 index 0000000..78d1d27 --- /dev/null +++ b/builtin/game/statbars.lua @@ -0,0 +1,187 @@ +-- cache setting +local enable_damage = core.settings:get_bool("enable_damage") + +local bar_definitions = { + hp = { + hud_elem_type = "statbar", + position = {x = 0.5, y = 1}, + text = "heart.png", + text2 = "heart_gone.png", + number = core.PLAYER_MAX_HP_DEFAULT, + item = core.PLAYER_MAX_HP_DEFAULT, + direction = 0, + size = {x = 24, y = 24}, + offset = {x = (-10 * 24) - 25, y = -(48 + 24 + 16)}, + }, + breath = { + hud_elem_type = "statbar", + position = {x = 0.5, y = 1}, + text = "bubble.png", + text2 = "bubble_gone.png", + number = core.PLAYER_MAX_BREATH_DEFAULT * 2, + item = core.PLAYER_MAX_BREATH_DEFAULT * 2, + direction = 0, + size = {x = 24, y = 24}, + offset = {x = 25, y= -(48 + 24 + 16)}, + }, +} + +local hud_ids = {} + +local function scaleToHudMax(player, field) + -- Scale "hp" or "breath" to the hud maximum dimensions + local current = player["get_" .. field](player) + local nominal = bar_definitions[field].item + local max_display = math.max(player:get_properties()[field .. "_max"], current) + return math.ceil(current / max_display * nominal) +end + +local function update_builtin_statbars(player) + local name = player:get_player_name() + + if name == "" then + return + end + + local flags = player:hud_get_flags() + if not hud_ids[name] then + hud_ids[name] = {} + -- flags are not transmitted to client on connect, we need to make sure + -- our current flags are transmitted by sending them actively + player:hud_set_flags(flags) + end + local hud = hud_ids[name] + + local immortal = player:get_armor_groups().immortal == 1 + + if flags.healthbar and enable_damage and not immortal then + local number = scaleToHudMax(player, "hp") + if hud.id_healthbar == nil then + local hud_def = table.copy(bar_definitions.hp) + hud_def.number = number + hud.id_healthbar = player:hud_add(hud_def) + else + player:hud_change(hud.id_healthbar, "number", number) + end + elseif hud.id_healthbar then + player:hud_remove(hud.id_healthbar) + hud.id_healthbar = nil + end + + local show_breathbar = flags.breathbar and enable_damage and not immortal + + local breath = player:get_breath() + local breath_max = player:get_properties().breath_max + if show_breathbar and breath <= breath_max then + local number = scaleToHudMax(player, "breath") + if not hud.id_breathbar and breath < breath_max then + local hud_def = table.copy(bar_definitions.breath) + hud_def.number = number + hud.id_breathbar = player:hud_add(hud_def) + elseif hud.id_breathbar then + player:hud_change(hud.id_breathbar, "number", number) + end + end + + if hud.id_breathbar and (not show_breathbar or breath == breath_max) then + core.after(1, function(player_name, breath_bar) + local player = core.get_player_by_name(player_name) + if player then + player:hud_remove(breath_bar) + end + end, name, hud.id_breathbar) + hud.id_breathbar = nil + end +end + +local function cleanup_builtin_statbars(player) + local name = player:get_player_name() + + if name == "" then + return + end + + hud_ids[name] = nil +end + +local function player_event_handler(player,eventname) + assert(player:is_player()) + + local name = player:get_player_name() + + if name == "" or not hud_ids[name] then + return + end + + if eventname == "health_changed" then + update_builtin_statbars(player) + + if hud_ids[name].id_healthbar then + return true + end + end + + if eventname == "breath_changed" then + update_builtin_statbars(player) + + if hud_ids[name].id_breathbar then + return true + end + end + + if eventname == "hud_changed" or eventname == "properties_changed" then + update_builtin_statbars(player) + return true + end + + return false +end + +function core.hud_replace_builtin(hud_name, definition) + if type(definition) ~= "table" or + definition.hud_elem_type ~= "statbar" then + return false + end + + definition = table.copy(definition) + + if hud_name == "health" then + definition.item = definition.item or definition.number or core.PLAYER_MAX_HP_DEFAULT + bar_definitions.hp = definition + + for name, ids in pairs(hud_ids) do + local player = core.get_player_by_name(name) + if player and ids.id_healthbar then + player:hud_remove(ids.id_healthbar) + ids.id_healthbar = nil + update_builtin_statbars(player) + end + end + return true + end + + if hud_name == "breath" then + definition.item = definition.item or definition.number or core.PLAYER_MAX_BREATH_DEFAULT + bar_definitions.breath = definition + + for name, ids in pairs(hud_ids) do + local player = core.get_player_by_name(name) + if player and ids.id_breathbar then + player:hud_remove(ids.id_breathbar) + ids.id_breathbar = nil + update_builtin_statbars(player) + end + end + return true + end + + return false +end + +-- Append "update_builtin_statbars" as late as possible +-- This ensures that the HUD is hidden when the flags are updated in this callback +core.register_on_mods_loaded(function() + core.register_on_joinplayer(update_builtin_statbars) +end) +core.register_on_leaveplayer(cleanup_builtin_statbars) +core.register_playerevent(player_event_handler) diff --git a/builtin/game/static_spawn.lua b/builtin/game/static_spawn.lua new file mode 100644 index 0000000..fae23ea --- /dev/null +++ b/builtin/game/static_spawn.lua @@ -0,0 +1,23 @@ +-- Minetest: builtin/static_spawn.lua + +local static_spawnpoint_string = core.settings:get("static_spawnpoint") +if static_spawnpoint_string and + static_spawnpoint_string ~= "" and + not core.setting_get_pos("static_spawnpoint") then + error('The static_spawnpoint setting is invalid: "' .. + static_spawnpoint_string .. '"') +end + +local function put_player_in_spawn(player_obj) + local static_spawnpoint = core.setting_get_pos("static_spawnpoint") + if not static_spawnpoint then + return false + end + core.log("action", "Moving " .. player_obj:get_player_name() .. + " to static spawnpoint at " .. core.pos_to_string(static_spawnpoint)) + player_obj:set_pos(static_spawnpoint) + return true +end + +core.register_on_newplayer(put_player_in_spawn) +core.register_on_respawnplayer(put_player_in_spawn) diff --git a/builtin/game/voxelarea.lua b/builtin/game/voxelarea.lua new file mode 100644 index 0000000..62f07d9 --- /dev/null +++ b/builtin/game/voxelarea.lua @@ -0,0 +1,134 @@ +local math_floor = math.floor +local vector_new = vector.new + +VoxelArea = { + MinEdge = vector_new(1, 1, 1), + MaxEdge = vector_new(0, 0, 0), + ystride = 0, + zstride = 0, +} + +function VoxelArea:new(o) + o = o or {} + setmetatable(o, self) + self.__index = self + + local e = o:getExtent() + o.ystride = e.x + o.zstride = e.x * e.y + + return o +end + +function VoxelArea:getExtent() + local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge + return vector_new( + MaxEdge.x - MinEdge.x + 1, + MaxEdge.y - MinEdge.y + 1, + MaxEdge.z - MinEdge.z + 1 + ) +end + +function VoxelArea:getVolume() + local e = self:getExtent() + return e.x * e.y * e.z +end + +function VoxelArea:index(x, y, z) + local MinEdge = self.MinEdge + local i = (z - MinEdge.z) * self.zstride + + (y - MinEdge.y) * self.ystride + + (x - MinEdge.x) + 1 + return math_floor(i) +end + +function VoxelArea:indexp(p) + local MinEdge = self.MinEdge + local i = (p.z - MinEdge.z) * self.zstride + + (p.y - MinEdge.y) * self.ystride + + (p.x - MinEdge.x) + 1 + return math_floor(i) +end + +function VoxelArea:position(i) + local MinEdge = self.MinEdge + + i = i - 1 + + local z = math_floor(i / self.zstride) + MinEdge.z + i = i % self.zstride + + local y = math_floor(i / self.ystride) + MinEdge.y + i = i % self.ystride + + local x = math_floor(i) + MinEdge.x + + return vector_new(x, y, z) +end + +function VoxelArea:contains(x, y, z) + local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge + return (x >= MinEdge.x) and (x <= MaxEdge.x) and + (y >= MinEdge.y) and (y <= MaxEdge.y) and + (z >= MinEdge.z) and (z <= MaxEdge.z) +end + +function VoxelArea:containsp(p) + local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge + return (p.x >= MinEdge.x) and (p.x <= MaxEdge.x) and + (p.y >= MinEdge.y) and (p.y <= MaxEdge.y) and + (p.z >= MinEdge.z) and (p.z <= MaxEdge.z) +end + +function VoxelArea:containsi(i) + return (i >= 1) and (i <= self:getVolume()) +end + +function VoxelArea:iter(minx, miny, minz, maxx, maxy, maxz) + local i = self:index(minx, miny, minz) - 1 + local xrange = maxx - minx + 1 + local nextaction = i + 1 + xrange + + local y = 0 + local yrange = maxy - miny + 1 + local yreqstride = self.ystride - xrange + + local z = 0 + local zrange = maxz - minz + 1 + local multistride = self.zstride - ((yrange - 1) * self.ystride + xrange) + + return function() + -- continue i until it needs to jump + i = i + 1 + if i ~= nextaction then + return i + end + + -- continue y until maxy is exceeded + y = y + 1 + if y ~= yrange then + -- set i to index(minx, miny + y, minz + z) - 1 + i = i + yreqstride + nextaction = i + xrange + return i + end + + -- continue z until maxz is exceeded + z = z + 1 + if z == zrange then + -- cuboid finished, return nil + return + end + + -- set i to index(minx, miny, minz + z) - 1 + i = i + multistride + + y = 0 + nextaction = i + xrange + return i + end +end + +function VoxelArea:iterp(minp, maxp) + return self:iter(minp.x, minp.y, minp.z, maxp.x, maxp.y, maxp.z) +end diff --git a/builtin/init.lua b/builtin/init.lua new file mode 100644 index 0000000..8691360 --- /dev/null +++ b/builtin/init.lua @@ -0,0 +1,67 @@ +-- +-- This file contains built-in stuff in Minetest implemented in Lua. +-- +-- It is always loaded and executed after registration of the C API, +-- before loading and running any mods. +-- + +-- Initialize some very basic things +function core.debug(...) core.log(table.concat({...}, "\t")) end +if core.print then + local core_print = core.print + -- Override native print and use + -- terminal if that's turned on + function print(...) + local n, t = select("#", ...), {...} + for i = 1, n do + t[i] = tostring(t[i]) + end + core_print(table.concat(t, "\t")) + end + core.print = nil -- don't pollute our namespace +end +math.randomseed(os.time()) +minetest = core + +-- Load other files +local scriptdir = core.get_builtin_path() +local gamepath = scriptdir .. "game" .. DIR_DELIM +local clientpath = scriptdir .. "client" .. DIR_DELIM +local commonpath = scriptdir .. "common" .. DIR_DELIM +local asyncpath = scriptdir .. "async" .. DIR_DELIM + +dofile(commonpath .. "vector.lua") +dofile(commonpath .. "strict.lua") +dofile(commonpath .. "serialize.lua") +dofile(commonpath .. "misc_helpers.lua") + +if INIT == "game" then + dofile(gamepath .. "init.lua") + assert(not core.get_http_api) +elseif INIT == "mainmenu" then + local mm_script = core.settings:get("main_menu_script") + local custom_loaded = false + if mm_script and mm_script ~= "" then + local testfile = io.open(mm_script, "r") + if testfile then + testfile:close() + dofile(mm_script) + custom_loaded = true + core.log("info", "Loaded custom main menu script: "..mm_script) + else + core.log("error", "Failed to load custom main menu script: "..mm_script) + core.log("info", "Falling back to default main menu script") + end + end + if not custom_loaded then + dofile(core.get_mainmenu_path() .. DIR_DELIM .. "init.lua") + end +elseif INIT == "async" then + dofile(asyncpath .. "mainmenu.lua") +elseif INIT == "async_game" then + dofile(asyncpath .. "game.lua") +elseif INIT == "client" then + dofile(clientpath .. "init.lua") +else + error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT))) +end diff --git a/builtin/locale/__builtin.de.tr b/builtin/locale/__builtin.de.tr new file mode 100644 index 0000000..4a17f7a --- /dev/null +++ b/builtin/locale/__builtin.de.tr @@ -0,0 +1,246 @@ +# textdomain: __builtin +Empty command.=Leerer Befehl. +Invalid command: @1=Ungültiger Befehl: @1 +Invalid command usage.=Ungültige Befehlsverwendung. + (@1 s)= (@1 s) +Command execution took @1 s=Befehlsausführung brauchte @1 s +You don't have permission to run this command (missing privileges: @1).=Sie haben keine Erlaubnis, diesen Befehl auszuführen (fehlende Privilegien: @1). +Unable to get position of player @1.=Konnte Position vom Spieler @1 nicht ermitteln. +Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)=Ungültiges Gebietsformat. Erwartet: (x1,y1,z1) (x2,y2,z2) +<action>=<Aktion> +Show chat action (e.g., '/me orders a pizza' displays '<player name> orders a pizza')=Chataktion zeigen (z.B. wird „/me isst Pizza“ zu „<Spielername> isst Pizza“) +Show the name of the server owner=Den Namen des Servereigentümers zeigen +The administrator of this server is @1.=Der Administrator dieses Servers ist @1. +There's no administrator named in the config file.=In der Konfigurationsdatei wurde kein Administrator angegeben. +@1 does not have any privileges.=@1 hat keine Privilegien. +Privileges of @1: @2=Privilegien von @1: @2 +[<name>]=[<Name>] +Show privileges of yourself or another player=Ihre eigenen Privilegien oder die eines anderen Spielers anzeigen +Player @1 does not exist.=Spieler @1 existiert nicht. +<privilege>=<Privileg> +Return list of all online players with privilege=Liste aller Spieler mit einem Privileg ausgeben +Invalid parameters (see /help haspriv).=Ungültige Parameter (siehe „/help haspriv“). +Unknown privilege!=Unbekanntes Privileg! +No online player has the "@1" privilege.=Kein online spielender Spieler hat das „@1“-Privileg. +Players online with the "@1" privilege: @2=Derzeit online spielende Spieler mit dem „@1“-Privileg: @2 +Your privileges are insufficient.=Ihre Privilegien sind unzureichend. +Your privileges are insufficient. '@1' only allows you to grant: @2=Ihre Privilegien sind unzureichend. Mit „@1“ können Sie nur folgendes gewähren: @2 +Unknown privilege: @1=Unbekanntes Privileg: @1 +@1 granted you privileges: @2=@1 gewährte Ihnen Privilegien: @2 +<name> (<privilege> [, <privilege2> [<...>]] | all)=<Name> (<Privileg> [, <Privileg2> [<...>]] | all) +Give privileges to player=Privileg an Spieler vergeben +Invalid parameters (see /help grant).=Ungültige Parameter (siehe „/help grant“). +<privilege> [, <privilege2> [<...>]] | all=<Privileg> [, <Privileg2> [<...>]] | all +Grant privileges to yourself=Privilegien an Ihnen selbst vergeben +Invalid parameters (see /help grantme).=Ungültige Parameter (siehe „/help grantme“). +Your privileges are insufficient. '@1' only allows you to revoke: @2=Ihre Privilegien sind unzureichend. Mit „@1“ können Sie nur folgendes entziehen: @2 +Note: Cannot revoke in singleplayer: @1=Anmerkung: Im Einzelspielermodus kann man folgendes nicht entziehen: @1 +Note: Cannot revoke from admin: @1=Anmerkung: Vom Admin kann man folgendes nicht entziehen: @1 +No privileges were revoked.=Es wurden keine Privilegien entzogen. +@1 revoked privileges from you: @2=@1 entfernte Privilegien von Ihnen: @2 +Remove privileges from player=Privilegien von Spieler entfernen +Invalid parameters (see /help revoke).=Ungültige Parameter (siehe „/help revoke“). +Revoke privileges from yourself=Privilegien von Ihnen selbst entfernen +Invalid parameters (see /help revokeme).=Ungültige Parameter (siehe „/help revokeme“). +<name> <password>=<Name> <Passwort> +Set player's password=Passwort von Spieler setzen +Name field required.=Namensfeld benötigt. +Your password was cleared by @1.=Ihr Passwort wurde von @1 geleert. +Password of player "@1" cleared.=Passwort von Spieler „@1“ geleert. +Your password was set by @1.=Ihr Passwort wurde von @1 gesetzt. +Password of player "@1" set.=Passwort von Spieler „@1“ gesetzt. +<name>=<Name> +Set empty password for a player=Leeres Passwort für einen Spieler setzen +Reload authentication data=Authentifizierungsdaten erneut laden +Done.=Fertig. +Failed.=Fehlgeschlagen. +Remove a player's data=Daten eines Spielers löschen +Player "@1" removed.=Spieler „@1“ gelöscht. +No such player "@1" to remove.=Es gibt keinen Spieler „@1“, der gelöscht werden könnte. +Player "@1" is connected, cannot remove.=Spieler „@1“ ist verbunden, er kann nicht gelöscht werden. +Unhandled remove_player return code @1.=Nicht berücksichtigter remove_player-Rückgabewert @1. +Cannot teleport out of map bounds!=Eine Teleportation außerhalb der Kartengrenzen ist nicht möglich! +Cannot get player with name @1.=Spieler mit Namen @1 kann nicht gefunden werden. +Cannot teleport, @1 is attached to an object!=Teleportation nicht möglich, @1 ist an einem Objekt befestigt! +Teleporting @1 to @2.=Teleportation von @1 nach @2 +One does not teleport to oneself.=Man teleportiert sich doch nicht zu sich selbst. +Cannot get teleportee with name @1.=Der zu teleportierende Spieler mit Namen @1 kann nicht gefunden werden. +Cannot get target player with name @1.=Zielspieler mit Namen @1 kann nicht gefunden werden. +Teleporting @1 to @2 at @3.=Teleportation von @1 zu @2 bei @3 +<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>=<X>,<Y>,<Z> | <zu_Name> | <Name> <X>,<Y>,<Z> | <Name> <zu_Name> +Teleport to position or player=Zu Position oder Spieler teleportieren +You don't have permission to teleport other players (missing privilege: @1).=Sie haben nicht die Erlaubnis, andere Spieler zu teleportieren (fehlendes Privileg: @1). +([-n] <name> <value>) | <name>=([-n] <Name> <Wert>) | <Name> +Set or read server configuration setting=Serverkonfigurationseinstellung setzen oder lesen +Failed. Cannot modify secure settings. Edit the settings file manually.=Fehlgeschlagen. Sicherheitseinstellungen können nicht modifiziert werden. Bearbeiten Sie die Einstellungsdatei manuell. +Failed. Use '/set -n <name> <value>' to create a new setting.=Fehlgeschlagen. Benutzen Sie „/set -n <Name> <Wert>“, um eine neue Einstellung zu erstellen. +@1 @= @2=@1 @= @2 +<not set>=<nicht gesetzt> +Invalid parameters (see /help set).=Ungültige Parameter (siehe „/help set“). +Finished emerging @1 blocks in @2ms.=Fertig mit Erzeugung von @1 Blöcken in @2 ms. +emergeblocks update: @1/@2 blocks emerged (@3%)=emergeblocks-Update: @1/@2 Kartenblöcke geladen (@3%) +(here [<radius>]) | (<pos1> <pos2>)=(here [<Radius>]) | (<Pos1> <Pos2>) +Load (or, if nonexistent, generate) map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Lade (oder, wenn nicht existent, generiere) Kartenblöcke im Gebiet zwischen Pos1 und Pos2 (<Pos1> und <Pos2> müssen in Klammern stehen) +Started emerge of area ranging from @1 to @2.=Start des Ladevorgangs des Gebiets zwischen @1 und @2. +Delete map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Kartenblöcke innerhalb des Gebiets zwischen Pos1 und Pos2 löschen (<Pos1> und <Pos2> müssen in Klammern stehen) +Successfully cleared area ranging from @1 to @2.=Gebiet zwischen @1 und @2 erfolgreich geleert. +Failed to clear one or more blocks in area.=Fehlgeschlagen: Ein oder mehrere Kartenblöcke im Gebiet konnten nicht geleert werden. +Resets lighting in the area between pos1 and pos2 (<pos1> and <pos2> must be in parentheses)=Setzt das Licht im Gebiet zwischen Pos1 und Pos2 zurück (<Pos1> und <Pos2> müssen in Klammern stehen) +Successfully reset light in the area ranging from @1 to @2.=Das Licht im Gebiet zwischen @1 und @2 wurde erfolgreich zurückgesetzt. +Failed to load one or more blocks in area.=Fehlgeschlagen: Ein oder mehrere Kartenblöcke im Gebiet konnten nicht geladen werden. +List mods installed on the server=Installierte Mods auf dem Server auflisten +No mods installed.=Es sind keine Mods installiert. +Cannot give an empty item.=Ein leerer Gegenstand kann nicht gegeben werden. +Cannot give an unknown item.=Ein unbekannter Gegenstand kann nicht gegeben werden. +Giving 'ignore' is not allowed.=„ignore“ darf nicht gegeben werden. +@1 is not a known player.=@1 ist kein bekannter Spieler. +@1 partially added to inventory.=@1 teilweise ins Inventar eingefügt. +@1 could not be added to inventory.=@1 konnte nicht ins Inventar eingefügt werden. +@1 added to inventory.=@1 zum Inventar hinzugefügt. +@1 partially added to inventory of @2.=@1 teilweise ins Inventar von @2 eingefügt. +@1 could not be added to inventory of @2.=@1 konnte nicht ins Inventar von @2 eingefügt werden. +@1 added to inventory of @2.=@1 ins Inventar von @2 eingefügt. +<name> <ItemString> [<count> [<wear>]]=<Name> <ItemString> [<Anzahl> [<Abnutzung>]] +Give item to player=Gegenstand an Spieler geben +Name and ItemString required.=Name und ItemString benötigt. +<ItemString> [<count> [<wear>]]=<ItemString> [<Anzahl> [<Abnutzung>]] +Give item to yourself=Gegenstand Ihnen selbst geben +ItemString required.=ItemString benötigt. +<EntityName> [<X>,<Y>,<Z>]=<EntityName> [<X>,<Y>,<Z>] +Spawn entity at given (or your) position=Entity an angegebener (oder Ihrer eigenen) Position spawnen +EntityName required.=EntityName benötigt. +Unable to spawn entity, player is nil.=Entity konnte nicht gespawnt werden, Spieler ist nil. +Cannot spawn an unknown entity.=Ein unbekanntes Entity kann nicht gespawnt werden. +Invalid parameters (@1).=Ungültige Parameter (@1). +@1 spawned.=@1 gespawnt. +@1 failed to spawn.=@1 konnte nicht gespawnt werden. +Destroy item in hand=Gegenstand in der Hand zerstören +Unable to pulverize, no player.=Konnte nicht pulverisieren, kein Spieler. +Unable to pulverize, no item in hand.=Konnte nicht pulverisieren, kein Gegenstand in der Hand. +An item was pulverized.=Ein Gegenstand wurde pulverisiert. +[<range>] [<seconds>] [<limit>]=[<Reichweite>] [<Sekunden>] [<Limit>] +Check who last touched a node or a node near it within the time specified by <seconds>. Default: range @= 0, seconds @= 86400 @= 24h, limit @= 5. Set <seconds> to inf for no time limit=Überprüfen, wer als letztes einen Node oder einen Node in der Nähe innerhalb der in <Sekunden> angegebenen Zeitspanne angefasst hat. Standard: Reichweite @= 0, Sekunden @= 86400 @= 24h, Limit @= 5. <Sekunden> auf „inf“ setzen, um Zeitlimit zu deaktivieren. +Rollback functions are disabled.=Rollback-Funktionen sind deaktiviert. +That limit is too high!=Dieses Limit ist zu hoch! +Checking @1 ...=Überprüfe @1 ... +Nobody has touched the specified location in @1 seconds.=Niemand hat die angegebene Position seit @1 Sekunden angefasst. +@1 @2 @3 -> @4 @5 seconds ago.=@1 @2 @3 -> @4 vor @5 Sekunden. +Punch a node (range@=@1, seconds@=@2, limit@=@3).=Hauen Sie einen Node (Reichweite@=@1, Sekunden@=@2, Limit@=@3). +(<name> [<seconds>]) | (:<actor> [<seconds>])=(<Name> [<Sekunden>]) | (:<Akteur> [<Sekunden>]) +Revert actions of a player. Default for <seconds> is 60. Set <seconds> to inf for no time limit=Aktionen eines Spielers zurückrollen. Standard für <Sekunden> ist 60. <Sekunden> auf „inf“ setzen, um Zeitlimit zu deaktivieren +Invalid parameters. See /help rollback and /help rollback_check.=Ungültige Parameter. Siehe /help rollback und /help rollback_check. +Reverting actions of player '@1' since @2 seconds.=Die Aktionen des Spielers „@1“ seit @2 Sekunden werden rückgängig gemacht. +Reverting actions of @1 since @2 seconds.=Die Aktionen von @1 seit @2 Sekunden werden rückgängig gemacht. +(log is too long to show)=(Protokoll ist zu lang für die Anzeige) +Reverting actions succeeded.=Die Aktionen wurden erfolgreich rückgängig gemacht. +Reverting actions FAILED.=FEHLGESCHLAGEN: Die Aktionen konnten nicht rückgängig gemacht werden. +Show server status=Serverstatus anzeigen +This command was disabled by a mod or game.=Dieser Befehl wurde von einer Mod oder einem Spiel deaktiviert. +[<0..23>:<0..59> | <0..24000>]=[<0..23>:<0..59> | <0..24000>] +Show or set time of day=Tageszeit anzeigen oder setzen +Current time is @1:@2.=Es ist jetzt @1:@2 Uhr. +You don't have permission to run this command (missing privilege: @1).=Sie haben nicht die Erlaubnis, diesen Befehl auszuführen (fehlendes Privileg: @1). +Invalid time (must be between 0 and 24000).=Ungültige Zeit (muss zwischen 0 und 24000 liegen). +Time of day changed.=Tageszeit geändert. +Invalid hour (must be between 0 and 23 inclusive).=Ungültige Stunde (muss zwischen 0 und 23 inklusive liegen). +Invalid minute (must be between 0 and 59 inclusive).=Ungültige Minute (muss zwischen 0 und 59 inklusive liegen). +Show day count since world creation=Anzahl Tage seit der Erschaffung der Welt anzeigen +Current day is @1.=Aktueller Tag ist @1. +[<delay_in_seconds> | -1] [-r] [<message>]=[<Verzögerung_in_Sekunden> | -1] [-r] [<Nachricht>] +Shutdown server (-1 cancels a delayed shutdown, -r allows players to reconnect)=Server herunterfahren (-1 bricht einen verzögerten Abschaltvorgang ab, -r erlaubt Spielern, sich wiederzuverbinden) +Server shutting down (operator request).=Server wird heruntergefahren (Betreiberanfrage). +Ban the IP of a player or show the ban list=Die IP eines Spielers verbannen oder die Bannliste anzeigen +The ban list is empty.=Die Bannliste ist leer. +Ban list: @1=Bannliste: @1 +You cannot ban players in singleplayer!=Im Einzelspielermodus können Sie keine Spieler verbannen! +Player is not online.=Spieler ist nicht online. +Failed to ban player.=Konnte Spieler nicht verbannen. +Banned @1.=@1 verbannt. +<name> | <IP_address>=<Name> | <IP_Adresse> +Remove IP ban belonging to a player/IP=Einen IP-Bann auf einen Spieler zurücknehmen +Failed to unban player/IP.=Konnte Bann auf Spieler/IP nicht zurücknehmen. +Unbanned @1.=Bann auf @1 zurückgenommen. +<name> [<reason>]=<Name> [<Grund>] +Kick a player=Spieler hinauswerfen +Failed to kick player @1.=Spieler @1 konnte nicht hinausgeworfen werden. +Kicked @1.=@1 hinausgeworfen. +[full | quick]=[full | quick] +Clear all objects in world=Alle Objekte in der Welt löschen +Invalid usage, see /help clearobjects.=Ungültige Verwendung, siehe /help clearobjects. +Clearing all objects. This may take a long time. You may experience a timeout. (by @1)=Lösche alle Objekte. Dies kann eine lange Zeit dauern. Eine Netzwerkzeitüberschreitung könnte für Sie auftreten. (von @1) +Cleared all objects.=Alle Objekte gelöscht. +<name> <message>=<Name> <Nachricht> +Send a direct message to a player=Eine Direktnachricht an einen Spieler senden +Invalid usage, see /help msg.=Ungültige Verwendung, siehe /help msg. +The player @1 is not online.=Der Spieler @1 ist nicht online. +DM from @1: @2=DN von @1: @2 +Message sent.=Nachricht gesendet. +Get the last login time of a player or yourself=Den letzten Loginzeitpunkt eines Spielers oder Ihren eigenen anfragen +@1's last login time was @2.=Letzter Loginzeitpunkt von @1 war @2. +@1's last login time is unknown.=Letzter Loginzeitpunkt von @1 ist unbekannt. +Clear the inventory of yourself or another player=Das Inventar von Ihnen oder einem anderen Spieler leeren +You don't have permission to clear another player's inventory (missing privilege: @1).=Sie haben nicht die Erlaubnis, das Inventar eines anderen Spielers zu leeren (fehlendes Privileg: @1). +@1 cleared your inventory.=@1 hat Ihr Inventar geleert. +Cleared @1's inventory.=Inventar von @1 geleert. +Player must be online to clear inventory!=Spieler muss online sein, um das Inventar leeren zu können! +Players can't be killed, damage has been disabled.=Spieler können nicht getötet werden, Schaden ist deaktiviert. +Player @1 is not online.=Spieler @1 ist nicht online. +You are already dead.=Sie sind schon tot. +@1 is already dead.=@1 ist bereits tot. +@1 has been killed.=@1 wurde getötet. +Kill player or yourself=Einen Spieler oder Sie selbst töten +Invalid parameters (see /help @1).=Ungültige Parameter (siehe „/help @1“). +Too many arguments, try using just /help <command>=Zu viele Argumente. Probieren Sie es mit „/help <Befehl>“ +Available commands: @1=Verfügbare Befehle: @1 +Use '/help <cmd>' to get more information, or '/help all' to list everything.=„/help <Befehl>“ benutzen, um mehr Informationen zu erhalten, oder „/help all“, um alles aufzulisten. +Available commands:=Verfügbare Befehle: +Command not available: @1=Befehl nicht verfügbar: @1 +[all | privs | <cmd>] [-t]=[all | privs | <Befehl>] [-t] +Get help for commands or list privileges (-t: output in chat)=Hilfe für Befehle erhalten oder Privilegien auflisten (-t: Ausgabe im Chat) +Command=Befehl +Parameters=Parameter +For more information, click on any entry in the list.=Für mehr Informationen klicken Sie auf einen beliebigen Eintrag in der Liste. +Double-click to copy the entry to the chat history.=Doppelklicken, um den Eintrag in die Chathistorie einzufügen. +Command: @1 @2=Befehl: @1 @2 +Available commands: (see also: /help <cmd>)=Verfügbare Befehle: (siehe auch: /help <Befehl>) +Close=Schließen +Privilege=Privileg +Description=Beschreibung +Available privileges:=Verfügbare Privilegien: +print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset=print [<Filter>] | dump [<Filter>] | save [<Format> [<Filter>]] +Handle the profiler and profiling data=Den Profiler und Profilingdaten verwalten +Statistics written to action log.=Statistiken zum Aktionsprotokoll geschrieben. +Statistics were reset.=Statistiken wurden zurückgesetzt. +Usage: @1=Verwendung: @1 +Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).=Format kann entweder „txt“, „csv“, „lua“, „json“ oder „json_pretty“ sein (die Struktur kann sich in Zukunft ändern). +@1 joined the game.=@1 ist dem Spiel beigetreten. +@1 left the game.=@1 hat das Spiel verlassen. +@1 left the game (timed out).=@1 hat das Spiel verlassen (Netzwerkzeitüberschreitung). +(no description)=(keine Beschreibung) +Can interact with things and modify the world=Kann mit Dingen interagieren und die Welt verändern +Can speak in chat=Kann im Chat sprechen +Can modify basic privileges (@1)=Kann grundlegende Privilegien anpassen (@1) +Can modify privileges=Kann Privilegien anpassen +Can teleport self=Kann sich selbst teleportieren +Can teleport other players=Kann andere Spieler teleportieren +Can set the time of day using /time=Kann die Tageszeit mit /time setzen +Can do server maintenance stuff=Kann Serverwartungsdinge machen +Can bypass node protection in the world=Kann den Schutz auf Blöcken in der Welt umgehen +Can ban and unban players=Kann Spieler verbannen und entbannen +Can kick players=Kann Spieler hinauswerfen +Can use /give and /giveme=Kann /give und /giveme benutzen +Can use /setpassword and /clearpassword=Kann /setpassword und /clearpassword benutzen +Can use fly mode=Kann den Flugmodus benutzen +Can use fast mode=Kann den Schnellmodus benutzen +Can fly through solid nodes using noclip mode=Kann durch feste Blöcke mit dem Geistmodus fliegen +Can use the rollback functionality=Kann die Rollback-Funktionalität benutzen +Can enable wireframe=Kann Drahtmodell aktivieren +Unknown Item=Unbekannter Gegenstand +Air=Luft +Ignore=Ignorieren +You can't place 'ignore' nodes!=Sie können keine „ignore“-Blöcke platzieren! +Values below show absolute/relative times spend per server step by the instrumented function.=Die unten angegebenen Werte zeigen absolute/relative Zeitspannen, die je Server-Step von der instrumentierten Funktion in Anspruch genommen wurden. +A total of @1 sample(s) were taken.=Es wurden insgesamt @1 Datenpunkt(e) aufgezeichnet. +The output is limited to '@1'.=Die Ausgabe ist beschränkt auf „@1“. +Saving of profile failed: @1=Speichern des Profils fehlgeschlagen: @1 +Profile saved to @1=Profil abgespeichert nach @1 diff --git a/builtin/locale/__builtin.it.tr b/builtin/locale/__builtin.it.tr new file mode 100644 index 0000000..b04b489 --- /dev/null +++ b/builtin/locale/__builtin.it.tr @@ -0,0 +1,259 @@ +# textdomain: __builtin +Empty command.=Comando vuoto. +Invalid command: @1=Comando non valido: @1 +Invalid command usage.=Utilizzo del comando non valido. + (@1 s)= +Command execution took @1 s= +You don't have permission to run this command (missing privileges: @1).=Non hai il permesso di eseguire questo comando (privilegi mancanti: @1). +Unable to get position of player @1.=Impossibile ottenere la posizione del giocatore @1. +Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)=Formato dell'area non corretto. Richiesto: (x1,y1,z1) (x2,y2,z2) +<action>=<azione> +Show chat action (e.g., '/me orders a pizza' displays '<player name> orders a pizza')=Mostra un'azione in chat (es. `/me ordina una pizza` mostra `<nome giocatore> ordina una pizza`) +Show the name of the server owner=Mostra il nome del proprietario del server +The administrator of this server is @1.=L'amministratore di questo server è @1. +There's no administrator named in the config file.=Non c'è nessun amministratore nel file di configurazione. +@1 does not have any privileges.= +Privileges of @1: @2=Privilegi di @1: @2 +[<name>]=[<nome>] +Show privileges of yourself or another player=Mostra i privilegi propri o di un altro giocatore +Player @1 does not exist.=Il giocatore @1 non esiste. +<privilege>=<privilegio> +Return list of all online players with privilege=Ritorna una lista di tutti i giocatori connessi col tale privilegio +Invalid parameters (see /help haspriv).=Parametri non validi (vedi /help haspriv). +Unknown privilege!=Privilegio sconosciuto! +No online player has the "@1" privilege.= +Players online with the "@1" privilege: @2=Giocatori connessi con il privilegio "@1": @2 +Your privileges are insufficient.=I tuoi privilegi sono insufficienti. +Your privileges are insufficient. '@1' only allows you to grant: @2= +Unknown privilege: @1=Privilegio sconosciuto: @1 +@1 granted you privileges: @2=@1 ti ha assegnato i seguenti privilegi: @2 +<name> (<privilege> [, <privilege2> [<...>]] | all)= +Give privileges to player=Dà privilegi al giocatore +Invalid parameters (see /help grant).=Parametri non validi (vedi /help grant). +<privilege> [, <privilege2> [<...>]] | all= +Grant privileges to yourself=Assegna dei privilegi a te stessǝ +Invalid parameters (see /help grantme).=Parametri non validi (vedi /help grantme). +Your privileges are insufficient. '@1' only allows you to revoke: @2= +Note: Cannot revoke in singleplayer: @1= +Note: Cannot revoke from admin: @1= +No privileges were revoked.= +@1 revoked privileges from you: @2=@1 ti ha revocato i seguenti privilegi: @2 +Remove privileges from player=Rimuove privilegi dal giocatore +Invalid parameters (see /help revoke).=Parametri non validi (vedi /help revoke). +Revoke privileges from yourself=Revoca privilegi a te stessǝ +Invalid parameters (see /help revokeme).=Parametri non validi (vedi /help revokeme). +<name> <password>=<nome> <password> +Set player's password=Imposta la password del giocatore +Name field required.=Campo "nome" richiesto. +Your password was cleared by @1.=La tua password è stata resettata da @1. +Password of player "@1" cleared.=Password del giocatore "@1" resettata. +Your password was set by @1.=La tua password è stata impostata da @1. +Password of player "@1" set.=Password del giocatore "@1" impostata. +<name>=<nome> +Set empty password for a player=Imposta una password vuota a un giocatore +Reload authentication data=Ricarica i dati d'autenticazione +Done.=Fatto. +Failed.=Errore. +Remove a player's data=Rimuove i dati di un giocatore +Player "@1" removed.=Giocatore "@1" rimosso. +No such player "@1" to remove.=Non è presente nessun giocatore "@1" da rimuovere. +Player "@1" is connected, cannot remove.=Il giocatore "@1" è connesso, non può essere rimosso. +Unhandled remove_player return code @1.=Codice ritornato da remove_player non gestito (@1). +Cannot teleport out of map bounds!=Non ci si può teletrasportare fuori dai limiti della mappa! +Cannot get player with name @1.=Impossibile trovare il giocatore chiamato @1. +Cannot teleport, @1 is attached to an object!=Impossibile teletrasportare, @1 è attaccato a un oggetto! +Teleporting @1 to @2.=Teletrasportando @1 da @2. +One does not teleport to oneself.=Non ci si può teletrasportare su se stessi. +Cannot get teleportee with name @1.=Impossibile trovare il giocatore chiamato @1 per il teletrasporto +Cannot get target player with name @1.=Impossibile trovare il giocatore chiamato @1 per il teletrasporto +Teleporting @1 to @2 at @3.=Teletrasportando @1 da @2 a @3 +<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>=<X>,<Y>,<Z> | <da_nome> | <nome> <X>,<Y>,<Z> | <nome> <da_nome> +Teleport to position or player=Teletrasporta a una posizione o da un giocatore +You don't have permission to teleport other players (missing privilege: @1).=Non hai il permesso di teletrasportare altri giocatori (privilegio mancante: @1). +([-n] <name> <value>) | <name>=([-n] <nome> <valore>) | <nome> +Set or read server configuration setting=Imposta o ottieni le configurazioni del server +Failed. Cannot modify secure settings. Edit the settings file manually.= +Failed. Use '/set -n <name> <value>' to create a new setting.=Errore. Usa 'set -n <nome> <valore>' per creare una nuova impostazione +@1 @= @2=@1 @= @2 +<not set>=<non impostato> +Invalid parameters (see /help set).=Parametri non validi (vedi /help set). +Finished emerging @1 blocks in @2ms.=Finito di emergere @1 blocchi in @2ms +emergeblocks update: @1/@2 blocks emerged (@3%)=aggiornamento emergeblocks: @1/@2 blocchi emersi (@3%) +(here [<radius>]) | (<pos1> <pos2>)=(here [<raggio>]) | (<pos1> <pos2>) +Load (or, if nonexistent, generate) map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Carica (o, se non esiste, genera) blocchi mappa contenuti nell'area tra pos1 e pos2 (<pos1> e <pos2> vanno tra parentesi) +Started emerge of area ranging from @1 to @2.=Iniziata emersione dell'area tra @1 e @2. +Delete map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Cancella i blocchi mappa contenuti nell'area tra pos1 e pos2 (<pos1> e <pos2> vanno tra parentesi) +Successfully cleared area ranging from @1 to @2.=Area tra @1 e @2 ripulita con successo. +Failed to clear one or more blocks in area.=Errore nel ripulire uno o più blocchi mappa nell'area +Resets lighting in the area between pos1 and pos2 (<pos1> and <pos2> must be in parentheses)=Reimposta l'illuminazione nell'area tra pos1 e po2 (<pos1> e <pos2> vanno tra parentesi) +Successfully reset light in the area ranging from @1 to @2.=Luce nell'area tra @1 e @2 reimpostata con successo. +Failed to load one or more blocks in area.=Errore nel caricare uno o più blocchi mappa nell'area. +List mods installed on the server=Elenca le mod installate nel server +No mods installed.= +Cannot give an empty item.=Impossibile dare un oggetto vuoto. +Cannot give an unknown item.=Impossibile dare un oggetto sconosciuto. +Giving 'ignore' is not allowed.=Non è permesso dare 'ignore'. +@1 is not a known player.=@1 non è un giocatore conosciuto. +@1 partially added to inventory.=@1 parzialmente aggiunto all'inventario. +@1 could not be added to inventory.=@1 non può essere aggiunto all'inventario. +@1 added to inventory.=@1 aggiunto all'inventario. +@1 partially added to inventory of @2.=@1 parzialmente aggiunto all'inventario di @2. +@1 could not be added to inventory of @2.=Non è stato possibile aggiungere @1 all'inventario di @2. +@1 added to inventory of @2.=@1 aggiunto all'inventario di @2. +<name> <ItemString> [<count> [<wear>]]=<nome> <NomeOggetto> [<quantità> [<usura>]] +Give item to player=Dà oggetti ai giocatori +Name and ItemString required.=Richiesti nome e NomeOggetto. +<ItemString> [<count> [<wear>]]=<NomeOggetto> [<quantità> [<usura>]] +Give item to yourself=Dà oggetti a te stessǝ +ItemString required.=Richiesto NomeOggetto. +<EntityName> [<X>,<Y>,<Z>]=<NomeEntità> [<X>,<Y>,<Z>] +Spawn entity at given (or your) position=Genera un'entità alla data coordinata (o la tua) +EntityName required.=Richiesto NomeEntità +Unable to spawn entity, player is nil.=Impossibile generare l'entità, il giocatore è nil. +Cannot spawn an unknown entity.=Impossibile generare un'entità sconosciuta. +Invalid parameters (@1).=Parametri non validi (@1). +@1 spawned.=Generata entità @1. +@1 failed to spawn.=Errore nel generare @1 +Destroy item in hand=Distrugge l'oggetto in mano +Unable to pulverize, no player.=Impossibile polverizzare, nessun giocatore. +Unable to pulverize, no item in hand.=Impossibile polverizzare, nessun oggetto in mano. +An item was pulverized.=Un oggetto è stato polverizzato. +[<range>] [<seconds>] [<limit>]=[<raggio>] [<secondi>] [<limite>] +Check who last touched a node or a node near it within the time specified by <seconds>. Default: range @= 0, seconds @= 86400 @= 24h, limit @= 5. Set <seconds> to inf for no time limit=Controlla chi è l'ultimo giocatore che ha toccato un nodo o un nodo nelle sue vicinanze, negli ultimi secondi indicati. Di base: raggio @= 0, secondi @= 86400 @= 24h, limite @= 5. +Rollback functions are disabled.=Le funzioni di rollback sono disabilitate. +That limit is too high!=Il limite è troppo alto! +Checking @1 ...=Controllando @1 ... +Nobody has touched the specified location in @1 seconds.=Nessuno ha toccato il punto specificato negli ultimi @1 secondi. +@1 @2 @3 -> @4 @5 seconds ago.=@1 @2 @3 -> @4 @5 secondi fa. +Punch a node (range@=@1, seconds@=@2, limit@=@3).=Colpisce un nodo (raggio@=@1, secondi@=@2, limite@=@3) +(<name> [<seconds>]) | (:<actor> [<seconds>])=(<nome> [<secondi>]) | (:<attore> [<secondi>]) +Revert actions of a player. Default for <seconds> is 60. Set <seconds> to inf for no time limit=Riavvolge le azioni di un giocatore. Di base, <secondi> è 60. Imposta <secondi> a inf per nessun limite di tempo +Invalid parameters. See /help rollback and /help rollback_check.=Parametri non validi. Vedi /help rollback e /help rollback_check. +Reverting actions of player '@1' since @2 seconds.=Riavvolge le azioni del giocatore '@1' avvenute negli ultimi @2 secondi. +Reverting actions of @1 since @2 seconds.=Riavvolge le azioni di @1 avvenute negli ultimi @2 secondi. +(log is too long to show)=(il log è troppo lungo per essere mostrato) +Reverting actions succeeded.=Riavvolgimento azioni avvenuto con successo. +Reverting actions FAILED.=Errore nel riavvolgere le azioni. +Show server status=Mostra lo stato del server +This command was disabled by a mod or game.=Questo comando è stato disabilitato da una mod o dal gioco. +[<0..23>:<0..59> | <0..24000>]=[<0..23>:<0..59> | <0..24000>] +Show or set time of day=Mostra o imposta l'orario della giornata +Current time is @1:@2.=Orario corrente: @1:@2. +You don't have permission to run this command (missing privilege: @1).=Non hai il permesso di eseguire questo comando (privilegio mancante: @1) +Invalid time (must be between 0 and 24000).= +Time of day changed.=Orario della giornata cambiato. +Invalid hour (must be between 0 and 23 inclusive).=Ora non valida (deve essere tra 0 e 23 inclusi) +Invalid minute (must be between 0 and 59 inclusive).=Minuto non valido (deve essere tra 0 e 59 inclusi) +Show day count since world creation=Mostra il conteggio dei giorni da quando il mondo è stato creato +Current day is @1.=Giorno attuale: @1. +[<delay_in_seconds> | -1] [-r] [<message>]= +Shutdown server (-1 cancels a delayed shutdown, -r allows players to reconnect)= +Server shutting down (operator request).=Arresto del server in corso (per richiesta dell'operatore) +Ban the IP of a player or show the ban list=Bandisce l'IP del giocatore o mostra la lista di quelli banditi +The ban list is empty.=La lista banditi è vuota. +Ban list: @1=Lista banditi: @1 +You cannot ban players in singleplayer!= +Player is not online.=Il giocatore non è connesso. +Failed to ban player.=Errore nel bandire il giocatore. +Banned @1.=@1 banditǝ. +<name> | <IP_address>=<nome> | <indirizzo_IP> +Remove IP ban belonging to a player/IP=Perdona l'IP appartenente a un giocatore/IP +Failed to unban player/IP.=Errore nel perdonare il giocatore/IP +Unbanned @1.=@1 perdonatǝ +<name> [<reason>]=<nome> [<ragione>] +Kick a player=Caccia un giocatore +Failed to kick player @1.=Errore nel cacciare il giocatore @1. +Kicked @1.=@1 cacciatǝ. +[full | quick]=[full | quick] +Clear all objects in world=Elimina tutti gli oggetti/entità nel mondo +Invalid usage, see /help clearobjects.=Uso incorretto, vedi /help clearobjects. +Clearing all objects. This may take a long time. You may experience a timeout. (by @1)=Eliminando tutti gli oggetti/entità. Questo potrebbe richiedere molto tempo e farti eventualmente crashare. (di @1) +Cleared all objects.=Tutti gli oggetti sono stati eliminati. +<name> <message>=<nome> <messaggio> +Send a direct message to a player=Invia un messaggio privato al giocatore +Invalid usage, see /help msg.=Uso incorretto, vedi /help msg +The player @1 is not online.=Il giocatore @1 non è connesso. +DM from @1: @2=Messaggio privato da @1: @2 +Message sent.=Messaggio inviato. +Get the last login time of a player or yourself=Ritorna l'ultimo accesso di un giocatore o di te stessǝ +@1's last login time was @2.=L'ultimo accesso di @1 è avvenuto il @2 +@1's last login time is unknown.=L'ultimo accesso di @1 non è conosciuto +Clear the inventory of yourself or another player=Svuota l'inventario tuo o di un altro giocatore +You don't have permission to clear another player's inventory (missing privilege: @1).=Non hai il permesso di svuotare l'inventario di un altro giocatore (privilegio mancante: @1). +@1 cleared your inventory.=@1 ha svuotato il tuo inventario. +Cleared @1's inventory.=L'inventario di @1 è stato svuotato. +Player must be online to clear inventory!=Il giocatore deve essere connesso per svuotarne l'inventario! +Players can't be killed, damage has been disabled.=I giocatori non possono essere uccisi, il danno è disabilitato. +Player @1 is not online.=Il giocatore @1 non è connesso. +You are already dead.=Sei già mortǝ. +@1 is already dead.=@1 è già mortǝ. +@1 has been killed.=@1 è stato uccisǝ. +Kill player or yourself=Uccide un giocatore o te stessǝ +Invalid parameters (see /help @1).= +Too many arguments, try using just /help <command>= +Available commands: @1=Comandi disponibili: @1 +Use '/help <cmd>' to get more information, or '/help all' to list everything.=Usa '/help <comando>' per ottenere più informazioni, o '/help all' per elencare tutti i comandi. +Available commands:=Comandi disponibili: +Command not available: @1=Comando non disponibile: @1 +[all | privs | <cmd>] [-t]= +Get help for commands or list privileges (-t: output in chat)= +Command=Comando +Parameters=Parametri +For more information, click on any entry in the list.=Per più informazioni, clicca su una qualsiasi voce dell'elenco. +Double-click to copy the entry to the chat history.=Doppio click per copiare la voce nella cronologia della chat. +Command: @1 @2=Comando: @1 @2 +Available commands: (see also: /help <cmd>)=Comandi disponibili: (vedi anche /help <comando>) +Close=Chiudi +Privilege=Privilegio +Description=Descrizione +Available privileges:=Privilegi disponibili: +print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset=print [<filtro>] | dump [<filtro>] | save [<formato> [<filtro>]] | reset +Handle the profiler and profiling data=Gestisce il profiler e i dati da esso elaborati +Statistics written to action log.=Statistiche scritte nel log delle azioni. +Statistics were reset.=Le statistiche sono state resettate. +Usage: @1=Utilizzo: @1 +Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).=I formati supportati sono txt, csv, lua, json e json_pretty (le strutture potrebbero essere soggetti a cambiamenti). +@1 joined the game.= +@1 left the game.= +@1 left the game (timed out).= +(no description)=(nessuna descrizione) +Can interact with things and modify the world=Si può interagire con le cose e modificare il mondo +Can speak in chat=Si può parlare in chat +Can modify basic privileges (@1)= +Can modify privileges=Si possono modificare i privilegi +Can teleport self=Si può teletrasportare se stessз +Can teleport other players=Si possono teletrasportare gli altri giocatori +Can set the time of day using /time=Si può impostate l'orario della giornata tramite /time +Can do server maintenance stuff=Si possono eseguire operazioni di manutenzione del server +Can bypass node protection in the world=Si può aggirare la protezione dei nodi nel mondo +Can ban and unban players=Si possono bandire e perdonare i giocatori +Can kick players=Si possono cacciare i giocatori +Can use /give and /giveme=Si possono usare /give e /give me +Can use /setpassword and /clearpassword=Si possono usare /setpassword e /clearpassword +Can use fly mode=Si può usare la modalità volo +Can use fast mode=Si può usare la modalità rapida +Can fly through solid nodes using noclip mode=Si può volare attraverso i nodi solidi con la modalità incorporea +Can use the rollback functionality=Si può usare la funzione di rollback +Can enable wireframe= +Unknown Item=Oggetto sconosciuto +Air=Aria +Ignore=Ignora +You can't place 'ignore' nodes!=Non puoi piazzare nodi 'ignore'! +Values below show absolute/relative times spend per server step by the instrumented function.= +A total of @1 sample(s) were taken.= +The output is limited to '@1'.= +Saving of profile failed: @1= +Profile saved to @1= + + +##### not used anymore ##### + +Invalid time.=Orario non valido. +[all | privs | <cmd>]=[all | privs | <comando>] +Get help for commands or list privileges=Richiama la finestra d'aiuto dei comandi o dei privilegi +Allows enabling various debug options that may affect gameplay=Permette di abilitare varie opzioni di debug che potrebbero influenzare l'esperienza di gioco +[<delay_in_seconds> | -1] [reconnect] [<message>]=[<ritardo_in_secondi> | -1] [reconnect] [<messaggio>] +Shutdown server (-1 cancels a delayed shutdown)=Arresta il server (-1 annulla un arresto programmato) +<name> (<privilege> | all)=<nome> (<privilegio> | all) +<privilege> | all=<privilegio> | all +Can modify 'shout' and 'interact' privileges=Si possono modificare i privilegi 'shout' e 'interact' diff --git a/builtin/locale/template.txt b/builtin/locale/template.txt new file mode 100644 index 0000000..fa73523 --- /dev/null +++ b/builtin/locale/template.txt @@ -0,0 +1,246 @@ +# textdomain: __builtin +Empty command.= +Invalid command: @1= +Invalid command usage.= + (@1 s)= +Command execution took @1 s= +You don't have permission to run this command (missing privileges: @1).= +Unable to get position of player @1.= +Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)= +<action>= +Show chat action (e.g., '/me orders a pizza' displays '<player name> orders a pizza')= +Show the name of the server owner= +The administrator of this server is @1.= +There's no administrator named in the config file.= +@1 does not have any privileges.= +Privileges of @1: @2= +[<name>]= +Show privileges of yourself or another player= +Player @1 does not exist.= +<privilege>= +Return list of all online players with privilege= +Invalid parameters (see /help haspriv).= +Unknown privilege!= +No online player has the "@1" privilege.= +Players online with the "@1" privilege: @2= +Your privileges are insufficient.= +Your privileges are insufficient. '@1' only allows you to grant: @2= +Unknown privilege: @1= +@1 granted you privileges: @2= +<name> (<privilege> [, <privilege2> [<...>]] | all)= +Give privileges to player= +Invalid parameters (see /help grant).= +<privilege> [, <privilege2> [<...>]] | all= +Grant privileges to yourself= +Invalid parameters (see /help grantme).= +Your privileges are insufficient. '@1' only allows you to revoke: @2= +Note: Cannot revoke in singleplayer: @1= +Note: Cannot revoke from admin: @1= +No privileges were revoked.= +@1 revoked privileges from you: @2= +Remove privileges from player= +Invalid parameters (see /help revoke).= +Revoke privileges from yourself= +Invalid parameters (see /help revokeme).= +<name> <password>= +Set player's password= +Name field required.= +Your password was cleared by @1.= +Password of player "@1" cleared.= +Your password was set by @1.= +Password of player "@1" set.= +<name>= +Set empty password for a player= +Reload authentication data= +Done.= +Failed.= +Remove a player's data= +Player "@1" removed.= +No such player "@1" to remove.= +Player "@1" is connected, cannot remove.= +Unhandled remove_player return code @1.= +Cannot teleport out of map bounds!= +Cannot get player with name @1.= +Cannot teleport, @1 is attached to an object!= +Teleporting @1 to @2.= +One does not teleport to oneself.= +Cannot get teleportee with name @1.= +Cannot get target player with name @1.= +Teleporting @1 to @2 at @3.= +<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>= +Teleport to position or player= +You don't have permission to teleport other players (missing privilege: @1).= +([-n] <name> <value>) | <name>= +Set or read server configuration setting= +Failed. Cannot modify secure settings. Edit the settings file manually.= +Failed. Use '/set -n <name> <value>' to create a new setting.= +@1 @= @2= +<not set>= +Invalid parameters (see /help set).= +Finished emerging @1 blocks in @2ms.= +emergeblocks update: @1/@2 blocks emerged (@3%)= +(here [<radius>]) | (<pos1> <pos2>)= +Load (or, if nonexistent, generate) map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)= +Started emerge of area ranging from @1 to @2.= +Delete map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)= +Successfully cleared area ranging from @1 to @2.= +Failed to clear one or more blocks in area.= +Resets lighting in the area between pos1 and pos2 (<pos1> and <pos2> must be in parentheses)= +Successfully reset light in the area ranging from @1 to @2.= +Failed to load one or more blocks in area.= +List mods installed on the server= +No mods installed.= +Cannot give an empty item.= +Cannot give an unknown item.= +Giving 'ignore' is not allowed.= +@1 is not a known player.= +@1 partially added to inventory.= +@1 could not be added to inventory.= +@1 added to inventory.= +@1 partially added to inventory of @2.= +@1 could not be added to inventory of @2.= +@1 added to inventory of @2.= +<name> <ItemString> [<count> [<wear>]]= +Give item to player= +Name and ItemString required.= +<ItemString> [<count> [<wear>]]= +Give item to yourself= +ItemString required.= +<EntityName> [<X>,<Y>,<Z>]= +Spawn entity at given (or your) position= +EntityName required.= +Unable to spawn entity, player is nil.= +Cannot spawn an unknown entity.= +Invalid parameters (@1).= +@1 spawned.= +@1 failed to spawn.= +Destroy item in hand= +Unable to pulverize, no player.= +Unable to pulverize, no item in hand.= +An item was pulverized.= +[<range>] [<seconds>] [<limit>]= +Check who last touched a node or a node near it within the time specified by <seconds>. Default: range @= 0, seconds @= 86400 @= 24h, limit @= 5. Set <seconds> to inf for no time limit= +Rollback functions are disabled.= +That limit is too high!= +Checking @1 ...= +Nobody has touched the specified location in @1 seconds.= +@1 @2 @3 -> @4 @5 seconds ago.= +Punch a node (range@=@1, seconds@=@2, limit@=@3).= +(<name> [<seconds>]) | (:<actor> [<seconds>])= +Revert actions of a player. Default for <seconds> is 60. Set <seconds> to inf for no time limit= +Invalid parameters. See /help rollback and /help rollback_check.= +Reverting actions of player '@1' since @2 seconds.= +Reverting actions of @1 since @2 seconds.= +(log is too long to show)= +Reverting actions succeeded.= +Reverting actions FAILED.= +Show server status= +This command was disabled by a mod or game.= +[<0..23>:<0..59> | <0..24000>]= +Show or set time of day= +Current time is @1:@2.= +You don't have permission to run this command (missing privilege: @1).= +Invalid time (must be between 0 and 24000).= +Time of day changed.= +Invalid hour (must be between 0 and 23 inclusive).= +Invalid minute (must be between 0 and 59 inclusive).= +Show day count since world creation= +Current day is @1.= +[<delay_in_seconds> | -1] [-r] [<message>]= +Shutdown server (-1 cancels a delayed shutdown, -r allows players to reconnect)= +Server shutting down (operator request).= +Ban the IP of a player or show the ban list= +The ban list is empty.= +Ban list: @1= +You cannot ban players in singleplayer!= +Player is not online.= +Failed to ban player.= +Banned @1.= +<name> | <IP_address>= +Remove IP ban belonging to a player/IP= +Failed to unban player/IP.= +Unbanned @1.= +<name> [<reason>]= +Kick a player= +Failed to kick player @1.= +Kicked @1.= +[full | quick]= +Clear all objects in world= +Invalid usage, see /help clearobjects.= +Clearing all objects. This may take a long time. You may experience a timeout. (by @1)= +Cleared all objects.= +<name> <message>= +Send a direct message to a player= +Invalid usage, see /help msg.= +The player @1 is not online.= +DM from @1: @2= +Message sent.= +Get the last login time of a player or yourself= +@1's last login time was @2.= +@1's last login time is unknown.= +Clear the inventory of yourself or another player= +You don't have permission to clear another player's inventory (missing privilege: @1).= +@1 cleared your inventory.= +Cleared @1's inventory.= +Player must be online to clear inventory!= +Players can't be killed, damage has been disabled.= +Player @1 is not online.= +You are already dead.= +@1 is already dead.= +@1 has been killed.= +Kill player or yourself= +Invalid parameters (see /help @1).= +Too many arguments, try using just /help <command>= +Available commands: @1= +Use '/help <cmd>' to get more information, or '/help all' to list everything.= +Available commands:= +Command not available: @1= +[all | privs | <cmd>] [-t]= +Get help for commands or list privileges (-t: output in chat)= +Command= +Parameters= +For more information, click on any entry in the list.= +Double-click to copy the entry to the chat history.= +Command: @1 @2= +Available commands: (see also: /help <cmd>)= +Close= +Privilege= +Description= +Available privileges:= +print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset= +Handle the profiler and profiling data= +Statistics written to action log.= +Statistics were reset.= +Usage: @1= +Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).= +@1 joined the game.= +@1 left the game.= +@1 left the game (timed out).= +(no description)= +Can interact with things and modify the world= +Can speak in chat= +Can modify basic privileges (@1)= +Can modify privileges= +Can teleport self= +Can teleport other players= +Can set the time of day using /time= +Can do server maintenance stuff= +Can bypass node protection in the world= +Can ban and unban players= +Can kick players= +Can use /give and /giveme= +Can use /setpassword and /clearpassword= +Can use fly mode= +Can use fast mode= +Can fly through solid nodes using noclip mode= +Can use the rollback functionality= +Can enable wireframe= +Unknown Item= +Air= +Ignore= +You can't place 'ignore' nodes!= +Values below show absolute/relative times spend per server step by the instrumented function.= +A total of @1 sample(s) were taken.= +The output is limited to '@1'.= +Saving of profile failed: @1= +Profile saved to @1= diff --git a/builtin/mainmenu/async_event.lua b/builtin/mainmenu/async_event.lua new file mode 100644 index 0000000..04bfb78 --- /dev/null +++ b/builtin/mainmenu/async_event.lua @@ -0,0 +1,32 @@ + +core.async_jobs = {} + +local function handle_job(jobid, serialized_retval) + local retval = core.deserialize(serialized_retval) + assert(type(core.async_jobs[jobid]) == "function") + core.async_jobs[jobid](retval) + core.async_jobs[jobid] = nil +end + +core.async_event_handler = handle_job + +function core.handle_async(func, parameter, callback) + -- Serialize function + local serialized_func = string.dump(func) + + assert(serialized_func ~= nil) + + -- Serialize parameters + local serialized_param = core.serialize(parameter) + + if serialized_param == nil then + return false + end + + local jobid = core.do_async_callback(serialized_func, serialized_param) + + core.async_jobs[jobid] = callback + + return true +end + diff --git a/builtin/mainmenu/common.lua b/builtin/mainmenu/common.lua new file mode 100644 index 0000000..81e28f2 --- /dev/null +++ b/builtin/mainmenu/common.lua @@ -0,0 +1,246 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-- Global menu data +menudata = {} + +-- Local cached values +local min_supp_proto, max_supp_proto + +function common_update_cached_supp_proto() + min_supp_proto = core.get_min_supp_proto() + max_supp_proto = core.get_max_supp_proto() +end +common_update_cached_supp_proto() + +-- Menu helper functions + +local function render_client_count(n) + if n > 999 then return '99+' + elseif n >= 0 then return tostring(n) + else return '?' end +end + +local function configure_selected_world_params(idx) + local worldconfig = pkgmgr.get_worldconfig(menudata.worldlist:get_list()[idx].path) + if worldconfig.creative_mode then + core.settings:set("creative_mode", worldconfig.creative_mode) + end + if worldconfig.enable_damage then + core.settings:set("enable_damage", worldconfig.enable_damage) + end +end + +function render_serverlist_row(spec) + local text = "" + if spec.name then + text = text .. core.formspec_escape(spec.name:trim()) + elseif spec.address then + text = text .. core.formspec_escape(spec.address:trim()) + if spec.port then + text = text .. ":" .. spec.port + end + end + + local grey_out = not spec.is_compatible + + local details = {} + + if spec.lag or spec.ping then + local lag = (spec.lag or 0) * 1000 + (spec.ping or 0) * 250 + if lag <= 125 then + table.insert(details, "1") + elseif lag <= 175 then + table.insert(details, "2") + elseif lag <= 250 then + table.insert(details, "3") + else + table.insert(details, "4") + end + else + table.insert(details, "0") + end + + table.insert(details, ",") + + local color = (grey_out and "#aaaaaa") or ((spec.is_favorite and "#ddddaa") or "#ffffff") + if spec.clients and (spec.clients_max or 0) > 0 then + local clients_percent = 100 * spec.clients / spec.clients_max + + -- Choose a color depending on how many clients are connected + -- (relatively to clients_max) + local clients_color + if grey_out then clients_color = '#aaaaaa' + elseif spec.clients == 0 then clients_color = '' -- 0 players: default/white + elseif clients_percent <= 60 then clients_color = '#a1e587' -- 0-60%: green + elseif clients_percent <= 90 then clients_color = '#ffdc97' -- 60-90%: yellow + elseif clients_percent == 100 then clients_color = '#dd5b5b' -- full server: red (darker) + else clients_color = '#ffba97' -- 90-100%: orange + end + + table.insert(details, clients_color) + table.insert(details, render_client_count(spec.clients) .. " / " .. + render_client_count(spec.clients_max)) + else + table.insert(details, color) + table.insert(details, "?") + end + + if spec.creative then + table.insert(details, "1") -- creative icon + else + table.insert(details, "0") + end + + if spec.pvp then + table.insert(details, "2") -- pvp icon + elseif spec.damage then + table.insert(details, "1") -- heart icon + else + table.insert(details, "0") + end + + table.insert(details, color) + table.insert(details, text) + + return table.concat(details, ",") +end +--------------------------------------------------------------------------------- +os.tmpname = function() + error('do not use') -- instead use core.get_temp_path() +end +-------------------------------------------------------------------------------- + +function menu_render_worldlist() + local retval = {} + local current_worldlist = menudata.worldlist:get_list() + + for i, v in ipairs(current_worldlist) do + retval[#retval+1] = core.formspec_escape(v.name) + end + + return table.concat(retval, ",") +end + +function menu_handle_key_up_down(fields, textlist, settingname) + local oldidx, newidx = core.get_textlist_index(textlist), 1 + if fields.key_up or fields.key_down then + if fields.key_up and oldidx and oldidx > 1 then + newidx = oldidx - 1 + elseif fields.key_down and oldidx and + oldidx < menudata.worldlist:size() then + newidx = oldidx + 1 + end + core.settings:set(settingname, menudata.worldlist:get_raw_index(newidx)) + configure_selected_world_params(newidx) + return true + end + return false +end + +function text2textlist(xpos, ypos, width, height, tl_name, textlen, text, transparency) + local textlines = core.wrap_text(text, textlen, true) + local retval = "textlist[" .. xpos .. "," .. ypos .. ";" .. width .. + "," .. height .. ";" .. tl_name .. ";" + + for i = 1, #textlines do + textlines[i] = textlines[i]:gsub("\r", "") + retval = retval .. core.formspec_escape(textlines[i]) .. "," + end + + retval = retval .. ";0;" + if transparency then retval = retval .. "true" end + retval = retval .. "]" + + return retval +end + +function is_server_protocol_compat(server_proto_min, server_proto_max) + if (not server_proto_min) or (not server_proto_max) then + -- There is no info. Assume the best and act as if we would be compatible. + return true + end + return min_supp_proto <= server_proto_max and max_supp_proto >= server_proto_min +end + +function is_server_protocol_compat_or_error(server_proto_min, server_proto_max) + if not is_server_protocol_compat(server_proto_min, server_proto_max) then + local server_prot_ver_info, client_prot_ver_info + local s_p_min = server_proto_min + local s_p_max = server_proto_max + + if s_p_min ~= s_p_max then + server_prot_ver_info = fgettext_ne("Server supports protocol versions between $1 and $2. ", + s_p_min, s_p_max) + else + server_prot_ver_info = fgettext_ne("Server enforces protocol version $1. ", + s_p_min) + end + if min_supp_proto ~= max_supp_proto then + client_prot_ver_info= fgettext_ne("We support protocol versions between version $1 and $2.", + min_supp_proto, max_supp_proto) + else + client_prot_ver_info = fgettext_ne("We only support protocol version $1.", min_supp_proto) + end + gamedata.errormessage = fgettext_ne("Protocol version mismatch. ") + .. server_prot_ver_info + .. client_prot_ver_info + return false + end + + return true +end + +function menu_worldmt(selected, setting, value) + local world = menudata.worldlist:get_list()[selected] + if world then + local filename = world.path .. DIR_DELIM .. "world.mt" + local world_conf = Settings(filename) + + if value then + if not world_conf:write() then + core.log("error", "Failed to write world config file") + end + world_conf:set(setting, value) + world_conf:write() + else + return world_conf:get(setting) + end + else + return nil + end +end + +function menu_worldmt_legacy(selected) + local modes_names = {"creative_mode", "enable_damage", "server_announce"} + for _, mode_name in pairs(modes_names) do + local mode_val = menu_worldmt(selected, mode_name) + if mode_val then + core.settings:set(mode_name, mode_val) + else + menu_worldmt(selected, mode_name, core.settings:get(mode_name)) + end + end +end + +function confirmation_formspec(message, confirm_id, confirm_label, cancel_id, cancel_label) + return "size[10,2.5,true]" .. + "label[0.5,0.5;" .. message .. "]" .. + "style[" .. confirm_id .. ";bgcolor=red]" .. + "button[0.5,1.5;2.5,0.5;" .. confirm_id .. ";" .. confirm_label .. "]" .. + "button[7.0,1.5;2.5,0.5;" .. cancel_id .. ";" .. cancel_label .. "]" +end diff --git a/builtin/mainmenu/dlg_config_world.lua b/builtin/mainmenu/dlg_config_world.lua new file mode 100644 index 0000000..e76e10e --- /dev/null +++ b/builtin/mainmenu/dlg_config_world.lua @@ -0,0 +1,409 @@ +--Minetest +--Copyright (C) 2013 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-------------------------------------------------------------------------------- + +local enabled_all = false + +local function modname_valid(name) + return not name:find("[^a-z0-9_]") +end + +local function init_data(data) + data.list = filterlist.create( + pkgmgr.preparemodlist, + pkgmgr.comparemod, + function(element, uid) + if element.name == uid then + return true + end + end, + function(element, criteria) + if criteria.hide_game and + element.is_game_content then + return false + end + + if criteria.hide_modpackcontents and + element.modpack ~= nil then + return false + end + return true + end, + { + worldpath = data.worldspec.path, + gameid = data.worldspec.gameid + }) + + if data.selected_mod > data.list:size() then + data.selected_mod = 0 + end + + data.list:set_filtercriteria({ + hide_game = data.hide_gamemods, + hide_modpackcontents = data.hide_modpackcontents + }) + data.list:add_sort_mechanism("alphabetic", sort_mod_list) + data.list:set_sortmode("alphabetic") +end + + +-- Returns errors errors and a list of all enabled mods (inc. game and world mods) +-- +-- `with_errors` is a table from mod virtual path to `{ type = "error" | "warning" }`. +-- `enabled_mods_by_name` is a table from mod virtual path to `true`. +-- +-- @param world_path Path to the world +-- @param all_mods List of mods, with `enabled` property. +-- @returns with_errors, enabled_mods_by_name +local function check_mod_configuration(world_path, all_mods) + -- Build up lookup tables for enabled mods and all mods by vpath + local enabled_mod_paths = {} + local all_mods_by_vpath = {} + for _, mod in ipairs(all_mods) do + if mod.type == "mod" then + all_mods_by_vpath[mod.virtual_path] = mod + end + if mod.enabled then + enabled_mod_paths[mod.virtual_path] = mod.path + end + end + + -- Use the engine's mod configuration code to resolve dependencies and return any errors + local config_status = core.check_mod_configuration(world_path, enabled_mod_paths) + + -- Build the list of enabled mod virtual paths + local enabled_mods_by_name = {} + for _, mod in ipairs(config_status.satisfied_mods) do + assert(mod.virtual_path ~= "") + enabled_mods_by_name[mod.name] = all_mods_by_vpath[mod.virtual_path] or mod + end + for _, mod in ipairs(config_status.unsatisfied_mods) do + assert(mod.virtual_path ~= "") + enabled_mods_by_name[mod.name] = all_mods_by_vpath[mod.virtual_path] or mod + end + + -- Build the table of errors + local with_error = {} + for _, mod in ipairs(config_status.unsatisfied_mods) do + local error = { type = "warning" } + with_error[mod.virtual_path] = error + + for _, depname in ipairs(mod.unsatisfied_depends) do + if not enabled_mods_by_name[depname] then + error.type = "error" + break + end + end + end + + return with_error, enabled_mods_by_name +end + +local function get_formspec(data) + if not data.list then + init_data(data) + end + + local all_mods = data.list:get_list() + local with_error, enabled_mods_by_name = check_mod_configuration(data.worldspec.path, all_mods) + + local mod = all_mods[data.selected_mod] or {name = ""} + + local retval = + "size[11.5,7.5,true]" .. + "label[0.5,0;" .. fgettext("World:") .. "]" .. + "label[1.75,0;" .. data.worldspec.name .. "]" + + if mod.is_modpack or mod.type == "game" then + local info = core.formspec_escape( + core.get_content_info(mod.path).description) + if info == "" then + if mod.is_modpack then + info = fgettext("No modpack description provided.") + else + info = fgettext("No game description provided.") + end + end + retval = retval .. + "textarea[0.25,0.7;5.75,7.2;;" .. info .. ";]" + else + local hard_deps, soft_deps = pkgmgr.get_dependencies(mod.path) + + -- Add error messages to dep lists + if mod.enabled or mod.is_game_content then + for i, dep_name in ipairs(hard_deps) do + local dep = enabled_mods_by_name[dep_name] + if not dep then + hard_deps[i] = mt_color_red .. dep_name .. " " .. fgettext("(Unsatisfied)") + elseif with_error[dep.virtual_path] then + hard_deps[i] = mt_color_orange .. dep_name .. " " .. fgettext("(Enabled, has error)") + else + hard_deps[i] = mt_color_green .. dep_name + end + end + for i, dep_name in ipairs(soft_deps) do + local dep = enabled_mods_by_name[dep_name] + if dep and with_error[dep.virtual_path] then + soft_deps[i] = mt_color_orange .. dep_name .. " " .. fgettext("(Enabled, has error)") + elseif dep then + soft_deps[i] = mt_color_green .. dep_name + end + end + end + + local hard_deps_str = table.concat(hard_deps, ",") + local soft_deps_str = table.concat(soft_deps, ",") + + retval = retval .. + "label[0,0.7;" .. fgettext("Mod:") .. "]" .. + "label[0.75,0.7;" .. mod.name .. "]" + + if hard_deps_str == "" then + if soft_deps_str == "" then + retval = retval .. + "label[0,1.25;" .. + fgettext("No (optional) dependencies") .. "]" + else + retval = retval .. + "label[0,1.25;" .. fgettext("No hard dependencies") .. + "]" .. + "label[0,1.75;" .. fgettext("Optional dependencies:") .. + "]" .. + "textlist[0,2.25;5,4;world_config_optdepends;" .. + soft_deps_str .. ";0]" + end + else + if soft_deps_str == "" then + retval = retval .. + "label[0,1.25;" .. fgettext("Dependencies:") .. "]" .. + "textlist[0,1.75;5,4;world_config_depends;" .. + hard_deps_str .. ";0]" .. + "label[0,6;" .. fgettext("No optional dependencies") .. "]" + else + retval = retval .. + "label[0,1.25;" .. fgettext("Dependencies:") .. "]" .. + "textlist[0,1.75;5,2.125;world_config_depends;" .. + hard_deps_str .. ";0]" .. + "label[0,3.9;" .. fgettext("Optional dependencies:") .. + "]" .. + "textlist[0,4.375;5,1.8;world_config_optdepends;" .. + soft_deps_str .. ";0]" + end + end + end + + retval = retval .. + "button[3.25,7;2.5,0.5;btn_config_world_save;" .. + fgettext("Save") .. "]" .. + "button[5.75,7;2.5,0.5;btn_config_world_cancel;" .. + fgettext("Cancel") .. "]" .. + "button[9,7;2.5,0.5;btn_config_world_cdb;" .. + fgettext("Find More Mods") .. "]" + + if mod.name ~= "" and not mod.is_game_content then + if mod.is_modpack then + if pkgmgr.is_modpack_entirely_enabled(data, mod.name) then + retval = retval .. + "button[5.5,0.125;3,0.5;btn_mp_disable;" .. + fgettext("Disable modpack") .. "]" + else + retval = retval .. + "button[5.5,0.125;3,0.5;btn_mp_enable;" .. + fgettext("Enable modpack") .. "]" + end + else + retval = retval .. + "checkbox[5.5,-0.125;cb_mod_enable;" .. fgettext("enabled") .. + ";" .. tostring(mod.enabled) .. "]" + end + end + if enabled_all then + retval = retval .. + "button[8.95,0.125;2.5,0.5;btn_disable_all_mods;" .. + fgettext("Disable all") .. "]" + else + retval = retval .. + "button[8.95,0.125;2.5,0.5;btn_enable_all_mods;" .. + fgettext("Enable all") .. "]" + end + + local use_technical_names = core.settings:get_bool("show_technical_names") + + return retval .. + "tablecolumns[color;tree;image,align=inline,width=1.5,0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. + ",1=" .. core.formspec_escape(defaulttexturedir .. "checkbox_16_white.png") .. + ",2=" .. core.formspec_escape(defaulttexturedir .. "error_icon_orange.png") .. + ",3=" .. core.formspec_escape(defaulttexturedir .. "error_icon_red.png") .. ";text]" .. + "table[5.5,0.75;5.75,6;world_config_modlist;" .. + pkgmgr.render_packagelist(data.list, use_technical_names, with_error) .. ";" .. data.selected_mod .."]" +end + +local function handle_buttons(this, fields) + if fields.world_config_modlist then + local event = core.explode_table_event(fields.world_config_modlist) + this.data.selected_mod = event.row + core.settings:set("world_config_selected_mod", event.row) + + if event.type == "DCL" then + pkgmgr.enable_mod(this) + end + + return true + end + + if fields.key_enter then + pkgmgr.enable_mod(this) + return true + end + + if fields.cb_mod_enable ~= nil then + pkgmgr.enable_mod(this, core.is_yes(fields.cb_mod_enable)) + return true + end + + if fields.btn_mp_enable ~= nil or + fields.btn_mp_disable then + pkgmgr.enable_mod(this, fields.btn_mp_enable ~= nil) + return true + end + + if fields.btn_config_world_save then + local filename = this.data.worldspec.path .. DIR_DELIM .. "world.mt" + + local worldfile = Settings(filename) + local mods = worldfile:to_table() + + local rawlist = this.data.list:get_raw_list() + local was_set = {} + + for i = 1, #rawlist do + local mod = rawlist[i] + if not mod.is_modpack and + not mod.is_game_content then + if modname_valid(mod.name) then + if mod.enabled then + worldfile:set("load_mod_" .. mod.name, mod.virtual_path) + was_set[mod.name] = true + elseif not was_set[mod.name] then + worldfile:set("load_mod_" .. mod.name, "false") + end + elseif mod.enabled then + gamedata.errormessage = fgettext_ne("Failed to enable mo" .. + "d \"$1\" as it contains disallowed characters. " .. + "Only characters [a-z0-9_] are allowed.", + mod.name) + end + mods["load_mod_" .. mod.name] = nil + end + end + + -- Remove mods that are not present anymore + for key in pairs(mods) do + if key:sub(1, 9) == "load_mod_" then + worldfile:remove(key) + end + end + + if not worldfile:write() then + core.log("error", "Failed to write world config file") + end + + this:delete() + return true + end + + if fields.btn_config_world_cancel then + this:delete() + return true + end + + if fields.btn_config_world_cdb then + this.data.list = nil + + local dlg = create_store_dlg("mod") + dlg:set_parent(this) + this:hide() + dlg:show() + return true + end + + if fields.btn_enable_all_mods then + local list = this.data.list:get_raw_list() + + -- When multiple copies of a mod are installed, we need to avoid enabling multiple of them + -- at a time. So lets first collect all the enabled mods, and then use this to exclude + -- multiple enables. + + local was_enabled = {} + for i = 1, #list do + if not list[i].is_game_content + and not list[i].is_modpack and list[i].enabled then + was_enabled[list[i].name] = true + end + end + + for i = 1, #list do + if not list[i].is_game_content and not list[i].is_modpack and + not was_enabled[list[i].name] then + list[i].enabled = true + was_enabled[list[i].name] = true + end + end + + enabled_all = true + return true + end + + if fields.btn_disable_all_mods then + local list = this.data.list:get_raw_list() + + for i = 1, #list do + if not list[i].is_game_content + and not list[i].is_modpack then + list[i].enabled = false + end + end + enabled_all = false + return true + end + + return false +end + +function create_configure_world_dlg(worldidx) + local dlg = dialog_create("sp_config_world", get_formspec, handle_buttons) + + dlg.data.selected_mod = tonumber( + core.settings:get("world_config_selected_mod")) or 0 + + dlg.data.worldspec = core.get_worlds()[worldidx] + if not dlg.data.worldspec then + dlg:delete() + return + end + + dlg.data.worldconfig = pkgmgr.get_worldconfig(dlg.data.worldspec.path) + + if not dlg.data.worldconfig or not dlg.data.worldconfig.id or + dlg.data.worldconfig.id == "" then + dlg:delete() + return + end + + return dlg +end diff --git a/builtin/mainmenu/dlg_contentstore.lua b/builtin/mainmenu/dlg_contentstore.lua new file mode 100644 index 0000000..2152b8a --- /dev/null +++ b/builtin/mainmenu/dlg_contentstore.lua @@ -0,0 +1,1062 @@ +--Minetest +--Copyright (C) 2018-20 rubenwardy +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +if not core.get_http_api then + function create_store_dlg() + return messagebox("store", + fgettext("ContentDB is not available when Minetest was compiled without cURL")) + end + return +end + +-- Unordered preserves the original order of the ContentDB API, +-- before the package list is ordered based on installed state. +local store = { packages = {}, packages_full = {}, packages_full_unordered = {}, aliases = {} } + +local http = core.get_http_api() + +-- Screenshot +local screenshot_dir = core.get_cache_path() .. DIR_DELIM .. "cdb" +assert(core.create_dir(screenshot_dir)) +local screenshot_downloading = {} +local screenshot_downloaded = {} + +-- Filter +local search_string = "" +local cur_page = 1 +local num_per_page = 5 +local filter_type = 1 +local filter_types_titles = { + fgettext("All packages"), + fgettext("Games"), + fgettext("Mods"), + fgettext("Texture packs"), +} + +local number_downloading = 0 +local download_queue = {} + +local filter_types_type = { + nil, + "game", + "mod", + "txp", +} + +local REASON_NEW = "new" +local REASON_UPDATE = "update" +local REASON_DEPENDENCY = "dependency" + + +-- encodes for use as URL parameter or path component +local function urlencode(str) + return str:gsub("[^%a%d()._~-]", function(char) + return string.format("%%%02X", string.byte(char)) + end) +end +assert(urlencode("sample text?") == "sample%20text%3F") + + +local function get_download_url(package, reason) + local base_url = core.settings:get("contentdb_url") + local ret = base_url .. ("/packages/%s/releases/%d/download/"):format( + package.url_part, package.release) + if reason then + ret = ret .. "?reason=" .. reason + end + return ret +end + + +local function download_and_extract(param) + local package = param.package + + local filename = core.get_temp_path(true) + if filename == "" or not core.download_file(param.url, filename) then + core.log("error", "Downloading " .. dump(param.url) .. " failed") + return { + msg = fgettext("Failed to download $1", package.name) + } + end + + local tempfolder = core.get_temp_path() + if tempfolder ~= "" then + tempfolder = tempfolder .. DIR_DELIM .. "MT_" .. math.random(1, 1024000) + if not core.extract_zip(filename, tempfolder) then + tempfolder = nil + end + else + tempfolder = nil + end + os.remove(filename) + if not tempfolder then + return { + msg = fgettext("Install: Unsupported file type or broken archive"), + } + end + + return { + path = tempfolder + } +end + +local function start_install(package, reason) + local params = { + package = package, + url = get_download_url(package, reason), + } + + number_downloading = number_downloading + 1 + + local function callback(result) + if result.msg then + gamedata.errormessage = result.msg + else + local path, msg = pkgmgr.install_dir(package.type, result.path, package.name, package.path) + core.delete_dir(result.path) + if not path then + gamedata.errormessage = msg + else + core.log("action", "Installed package to " .. path) + + local conf_path + local name_is_title = false + if package.type == "mod" then + local actual_type = pkgmgr.get_folder_type(path) + if actual_type.type == "modpack" then + conf_path = path .. DIR_DELIM .. "modpack.conf" + else + conf_path = path .. DIR_DELIM .. "mod.conf" + end + elseif package.type == "game" then + conf_path = path .. DIR_DELIM .. "game.conf" + name_is_title = true + elseif package.type == "txp" then + conf_path = path .. DIR_DELIM .. "texture_pack.conf" + end + + if conf_path then + local conf = Settings(conf_path) + conf:set("title", package.title) + if not name_is_title then + conf:set("name", package.name) + end + if not conf:get("description") then + conf:set("description", package.short_description) + end + conf:set("author", package.author) + conf:set("release", package.release) + conf:write() + end + end + end + + package.downloading = false + + number_downloading = number_downloading - 1 + + local next = download_queue[1] + if next then + table.remove(download_queue, 1) + + start_install(next.package, next.reason) + end + + ui.update() + end + + package.queued = false + package.downloading = true + + if not core.handle_async(download_and_extract, params, callback) then + core.log("error", "ERROR: async event failed") + gamedata.errormessage = fgettext("Failed to download $1", package.name) + return + end +end + +local function queue_download(package, reason) + local max_concurrent_downloads = tonumber(core.settings:get("contentdb_max_concurrent_downloads")) + if number_downloading < math.max(max_concurrent_downloads, 1) then + start_install(package, reason) + else + table.insert(download_queue, { package = package, reason = reason }) + package.queued = true + end +end + +local function get_raw_dependencies(package) + if package.raw_deps then + return package.raw_deps + end + + local url_fmt = "/api/packages/%s/dependencies/?only_hard=1&protocol_version=%s&engine_version=%s" + local version = core.get_version() + local base_url = core.settings:get("contentdb_url") + local url = base_url .. url_fmt:format(package.url_part, core.get_max_supp_proto(), urlencode(version.string)) + + local response = http.fetch_sync({ url = url }) + if not response.succeeded then + return + end + + local data = core.parse_json(response.data) or {} + + local content_lookup = {} + for _, pkg in pairs(store.packages_full) do + content_lookup[pkg.id] = pkg + end + + for id, raw_deps in pairs(data) do + local package2 = content_lookup[id:lower()] + if package2 and not package2.raw_deps then + package2.raw_deps = raw_deps + + for _, dep in pairs(raw_deps) do + local packages = {} + for i=1, #dep.packages do + packages[#packages + 1] = content_lookup[dep.packages[i]:lower()] + end + dep.packages = packages + end + end + end + + return package.raw_deps +end + +local function has_hard_deps(raw_deps) + for i=1, #raw_deps do + if not raw_deps[i].is_optional then + return true + end + end + + return false +end + +-- Recursively resolve dependencies, given the installed mods +local function resolve_dependencies_2(raw_deps, installed_mods, out) + local function resolve_dep(dep) + -- Check whether it's already installed + if installed_mods[dep.name] then + return { + is_optional = dep.is_optional, + name = dep.name, + installed = true, + } + end + + -- Find exact name matches + local fallback + for _, package in pairs(dep.packages) do + if package.type ~= "game" then + if package.name == dep.name then + return { + is_optional = dep.is_optional, + name = dep.name, + installed = false, + package = package, + } + elseif not fallback then + fallback = package + end + end + end + + -- Otherwise, find the first mod that fulfils it + if fallback then + return { + is_optional = dep.is_optional, + name = dep.name, + installed = false, + package = fallback, + } + end + + return { + is_optional = dep.is_optional, + name = dep.name, + installed = false, + } + end + + for _, dep in pairs(raw_deps) do + if not dep.is_optional and not out[dep.name] then + local result = resolve_dep(dep) + out[dep.name] = result + if result and result.package and not result.installed then + local raw_deps2 = get_raw_dependencies(result.package) + if raw_deps2 then + resolve_dependencies_2(raw_deps2, installed_mods, out) + end + end + end + end + + return true +end + +-- Resolve dependencies for a package, calls the recursive version. +local function resolve_dependencies(raw_deps, game) + assert(game) + + local installed_mods = {} + + local mods = {} + pkgmgr.get_game_mods(game, mods) + for _, mod in pairs(mods) do + installed_mods[mod.name] = true + end + + for _, mod in pairs(pkgmgr.global_mods:get_list()) do + installed_mods[mod.name] = true + end + + local out = {} + if not resolve_dependencies_2(raw_deps, installed_mods, out) then + return nil + end + + local retval = {} + for _, dep in pairs(out) do + retval[#retval + 1] = dep + end + + table.sort(retval, function(a, b) + return a.name < b.name + end) + + return retval +end + +local install_dialog = {} +function install_dialog.get_formspec() + local package = install_dialog.package + local raw_deps = install_dialog.raw_deps + local will_install_deps = install_dialog.will_install_deps + + local selected_game_idx = 1 + local selected_gameid = core.settings:get("menu_last_game") + local games = table.copy(pkgmgr.games) + for i=1, #games do + if selected_gameid and games[i].id == selected_gameid then + selected_game_idx = i + end + + games[i] = core.formspec_escape(games[i].title) + end + + local selected_game = pkgmgr.games[selected_game_idx] + local deps_to_install = 0 + local deps_not_found = 0 + + install_dialog.dependencies = resolve_dependencies(raw_deps, selected_game) + local formatted_deps = {} + for _, dep in pairs(install_dialog.dependencies) do + formatted_deps[#formatted_deps + 1] = "#fff" + formatted_deps[#formatted_deps + 1] = core.formspec_escape(dep.name) + if dep.installed then + formatted_deps[#formatted_deps + 1] = "#ccf" + formatted_deps[#formatted_deps + 1] = fgettext("Already installed") + elseif dep.package then + formatted_deps[#formatted_deps + 1] = "#cfc" + formatted_deps[#formatted_deps + 1] = fgettext("$1 by $2", dep.package.title, dep.package.author) + deps_to_install = deps_to_install + 1 + else + formatted_deps[#formatted_deps + 1] = "#f00" + formatted_deps[#formatted_deps + 1] = fgettext("Not found") + deps_not_found = deps_not_found + 1 + end + end + + local message_bg = "#3333" + local message + if will_install_deps then + message = fgettext("$1 and $2 dependencies will be installed.", package.title, deps_to_install) + else + message = fgettext("$1 will be installed, and $2 dependencies will be skipped.", package.title, deps_to_install) + end + if deps_not_found > 0 then + message = fgettext("$1 required dependencies could not be found.", deps_not_found) .. + " " .. fgettext("Please check that the base game is correct.", deps_not_found) .. + "\n" .. message + message_bg = mt_color_orange + end + + local formspec = { + "formspec_version[3]", + "size[7,7.85]", + "style[title;border=false]", + "box[0,0;7,0.5;#3333]", + "button[0,0;7,0.5;title;", fgettext("Install $1", package.title) , "]", + + "container[0.375,0.70]", + + "label[0,0.25;", fgettext("Base Game:"), "]", + "dropdown[2,0;4.25,0.5;selected_game;", table.concat(games, ","), ";", selected_game_idx, "]", + + "label[0,0.8;", fgettext("Dependencies:"), "]", + + "tablecolumns[color;text;color;text]", + "table[0,1.1;6.25,3;packages;", table.concat(formatted_deps, ","), "]", + + "container_end[]", + + "checkbox[0.375,5.1;will_install_deps;", + fgettext("Install missing dependencies"), ";", + will_install_deps and "true" or "false", "]", + + "box[0,5.4;7,1.2;", message_bg, "]", + "textarea[0.375,5.5;6.25,1;;;", message, "]", + + "container[1.375,6.85]", + "button[0,0;2,0.8;install_all;", fgettext("Install"), "]", + "button[2.25,0;2,0.8;cancel;", fgettext("Cancel"), "]", + "container_end[]", + } + + return table.concat(formspec, "") +end + +function install_dialog.handle_submit(this, fields) + if fields.cancel then + this:delete() + return true + end + + if fields.will_install_deps ~= nil then + install_dialog.will_install_deps = core.is_yes(fields.will_install_deps) + return true + end + + if fields.install_all then + queue_download(install_dialog.package, REASON_NEW) + + if install_dialog.will_install_deps then + for _, dep in pairs(install_dialog.dependencies) do + if not dep.is_optional and not dep.installed and dep.package then + queue_download(dep.package, REASON_DEPENDENCY) + end + end + end + + this:delete() + return true + end + + if fields.selected_game then + for _, game in pairs(pkgmgr.games) do + if game.title == fields.selected_game then + core.settings:set("menu_last_game", game.id) + break + end + end + return true + end + + return false +end + +function install_dialog.create(package, raw_deps) + install_dialog.dependencies = nil + install_dialog.package = package + install_dialog.raw_deps = raw_deps + install_dialog.will_install_deps = true + return dialog_create("install_dialog", + install_dialog.get_formspec, + install_dialog.handle_submit, + nil) +end + + +local confirm_overwrite = {} +function confirm_overwrite.get_formspec() + local package = confirm_overwrite.package + + return confirmation_formspec( + fgettext("\"$1\" already exists. Would you like to overwrite it?", package.name), + 'install', fgettext("Overwrite"), + 'cancel', fgettext("Cancel")) +end + +function confirm_overwrite.handle_submit(this, fields) + if fields.cancel then + this:delete() + return true + end + + if fields.install then + this:delete() + confirm_overwrite.callback() + return true + end + + return false +end + +function confirm_overwrite.create(package, callback) + assert(type(package) == "table") + assert(type(callback) == "function") + + confirm_overwrite.package = package + confirm_overwrite.callback = callback + return dialog_create("confirm_overwrite", + confirm_overwrite.get_formspec, + confirm_overwrite.handle_submit, + nil) +end + + +local function get_file_extension(path) + local parts = path:split(".") + return parts[#parts] +end + +local function get_screenshot(package) + if not package.thumbnail then + return defaulttexturedir .. "no_screenshot.png" + elseif screenshot_downloading[package.thumbnail] then + return defaulttexturedir .. "loading_screenshot.png" + end + + -- Get tmp screenshot path + local ext = get_file_extension(package.thumbnail) + local filepath = screenshot_dir .. DIR_DELIM .. + ("%s-%s-%s.%s"):format(package.type, package.author, package.name, ext) + + -- Return if already downloaded + local file = io.open(filepath, "r") + if file then + file:close() + return filepath + end + + -- Show error if we've failed to download before + if screenshot_downloaded[package.thumbnail] then + return defaulttexturedir .. "error_screenshot.png" + end + + -- Download + + local function download_screenshot(params) + return core.download_file(params.url, params.dest) + end + local function callback(success) + screenshot_downloading[package.thumbnail] = nil + screenshot_downloaded[package.thumbnail] = true + if not success then + core.log("warning", "Screenshot download failed for some reason") + end + ui.update() + end + if core.handle_async(download_screenshot, + { dest = filepath, url = package.thumbnail }, callback) then + screenshot_downloading[package.thumbnail] = true + else + core.log("error", "ERROR: async event failed") + return defaulttexturedir .. "error_screenshot.png" + end + + return defaulttexturedir .. "loading_screenshot.png" +end + +function store.load() + local version = core.get_version() + local base_url = core.settings:get("contentdb_url") + local url = base_url .. + "/api/packages/?type=mod&type=game&type=txp&protocol_version=" .. + core.get_max_supp_proto() .. "&engine_version=" .. urlencode(version.string) + + for _, item in pairs(core.settings:get("contentdb_flag_blacklist"):split(",")) do + item = item:trim() + if item ~= "" then + url = url .. "&hide=" .. urlencode(item) + end + end + + local response = http.fetch_sync({ url = url }) + if not response.succeeded then + return + end + + store.packages_full = core.parse_json(response.data) or {} + store.aliases = {} + + for _, package in pairs(store.packages_full) do + local name_len = #package.name + -- This must match what store.update_paths() does! + package.id = package.author:lower() .. "/" + if package.type == "game" and name_len > 5 and package.name:sub(name_len - 4) == "_game" then + package.id = package.id .. package.name:sub(1, name_len - 5) + else + package.id = package.id .. package.name + end + + package.url_part = urlencode(package.author) .. "/" .. urlencode(package.name) + + if package.aliases then + for _, alias in ipairs(package.aliases) do + -- We currently don't support name changing + local suffix = "/" .. package.name + if alias:sub(-#suffix) == suffix then + store.aliases[alias:lower()] = package.id + end + end + end + end + + store.packages_full_unordered = store.packages_full + store.packages = store.packages_full + store.loaded = true +end + +function store.update_paths() + local mod_hash = {} + pkgmgr.refresh_globals() + for _, mod in pairs(pkgmgr.global_mods:get_list()) do + if mod.author and mod.release > 0 then + local id = mod.author:lower() .. "/" .. mod.name + mod_hash[store.aliases[id] or id] = mod + end + end + + local game_hash = {} + pkgmgr.update_gamelist() + for _, game in pairs(pkgmgr.games) do + if game.author ~= "" and game.release > 0 then + local id = game.author:lower() .. "/" .. game.id + game_hash[store.aliases[id] or id] = game + end + end + + local txp_hash = {} + for _, txp in pairs(pkgmgr.get_texture_packs()) do + if txp.author and txp.release > 0 then + local id = txp.author:lower() .. "/" .. txp.name + txp_hash[store.aliases[id] or id] = txp + end + end + + for _, package in pairs(store.packages_full) do + local content + if package.type == "mod" then + content = mod_hash[package.id] + elseif package.type == "game" then + content = game_hash[package.id] + elseif package.type == "txp" then + content = txp_hash[package.id] + end + + if content then + package.path = content.path + package.installed_release = content.release or 0 + else + package.path = nil + end + end +end + +function store.sort_packages() + local ret = {} + + -- Add installed content + for i=1, #store.packages_full_unordered do + local package = store.packages_full_unordered[i] + if package.path then + ret[#ret + 1] = package + end + end + + -- Sort installed content by title + table.sort(ret, function(a, b) + return a.title < b.title + end) + + -- Add uninstalled content + for i=1, #store.packages_full_unordered do + local package = store.packages_full_unordered[i] + if not package.path then + ret[#ret + 1] = package + end + end + + store.packages_full = ret +end + +function store.filter_packages(query) + if query == "" and filter_type == 1 then + store.packages = store.packages_full + return + end + + local keywords = {} + for word in query:lower():gmatch("%S+") do + table.insert(keywords, word) + end + + local function matches_keywords(package) + for k = 1, #keywords do + local keyword = keywords[k] + + if string.find(package.name:lower(), keyword, 1, true) or + string.find(package.title:lower(), keyword, 1, true) or + string.find(package.author:lower(), keyword, 1, true) or + string.find(package.short_description:lower(), keyword, 1, true) then + return true + end + end + + return false + end + + store.packages = {} + for _, package in pairs(store.packages_full) do + if (query == "" or matches_keywords(package)) and + (filter_type == 1 or package.type == filter_types_type[filter_type]) then + store.packages[#store.packages + 1] = package + end + end +end + +function store.get_formspec(dlgdata) + store.update_paths() + + dlgdata.pagemax = math.max(math.ceil(#store.packages / num_per_page), 1) + if cur_page > dlgdata.pagemax then + cur_page = 1 + end + + local W = 15.75 + local H = 9.5 + local formspec + if #store.packages_full > 0 then + formspec = { + "formspec_version[3]", + "size[15.75,9.5]", + "position[0.5,0.55]", + + "style[status,downloading,queued;border=false]", + + "container[0.375,0.375]", + "field[0,0;7.225,0.8;search_string;;", core.formspec_escape(search_string), "]", + "field_close_on_enter[search_string;false]", + "image_button[7.3,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "search.png"), ";search;]", + "image_button[8.125,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "clear.png"), ";clear;]", + "dropdown[9.6,0;2.4,0.8;type;", table.concat(filter_types_titles, ","), ";", filter_type, "]", + "container_end[]", + + -- Page nav buttons + "container[0,", H - 0.8 - 0.375, "]", + "button[0.375,0;4,0.8;back;", fgettext("Back to Main Menu"), "]", + + "container[", W - 0.375 - 0.8*4 - 2, ",0]", + "image_button[0,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "start_icon.png;pstart;]", + "image_button[0.8,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "prev_icon.png;pback;]", + "style[pagenum;border=false]", + "button[1.6,0;2,0.8;pagenum;", tonumber(cur_page), " / ", tonumber(dlgdata.pagemax), "]", + "image_button[3.6,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "next_icon.png;pnext;]", + "image_button[4.4,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "end_icon.png;pend;]", + "container_end[]", + + "container_end[]", + } + + if number_downloading > 0 then + formspec[#formspec + 1] = "button[12.75,0.375;2.625,0.8;downloading;" + if #download_queue > 0 then + formspec[#formspec + 1] = fgettext("$1 downloading,\n$2 queued", number_downloading, #download_queue) + else + formspec[#formspec + 1] = fgettext("$1 downloading...", number_downloading) + end + formspec[#formspec + 1] = "]" + else + local num_avail_updates = 0 + for i=1, #store.packages_full do + local package = store.packages_full[i] + if package.path and package.installed_release < package.release and + not (package.downloading or package.queued) then + num_avail_updates = num_avail_updates + 1 + end + end + + if num_avail_updates == 0 then + formspec[#formspec + 1] = "button[12.75,0.375;2.625,0.8;status;" + formspec[#formspec + 1] = fgettext("No updates") + formspec[#formspec + 1] = "]" + else + formspec[#formspec + 1] = "button[12.75,0.375;2.625,0.8;update_all;" + formspec[#formspec + 1] = fgettext("Update All [$1]", num_avail_updates) + formspec[#formspec + 1] = "]" + end + end + + if #store.packages == 0 then + formspec[#formspec + 1] = "label[4,3;" + formspec[#formspec + 1] = fgettext("No results") + formspec[#formspec + 1] = "]" + end + else + formspec = { + "size[12,7]", + "position[0.5,0.55]", + "label[4,3;", fgettext("No packages could be retrieved"), "]", + "container[0,", H - 0.8 - 0.375, "]", + "button[0,0;4,0.8;back;", fgettext("Back to Main Menu"), "]", + "container_end[]", + } + end + + -- download/queued tooltips always have the same message + local tooltip_colors = ";#dff6f5;#302c2e]" + formspec[#formspec + 1] = "tooltip[downloading;" .. fgettext("Downloading...") .. tooltip_colors + formspec[#formspec + 1] = "tooltip[queued;" .. fgettext("Queued") .. tooltip_colors + + local start_idx = (cur_page - 1) * num_per_page + 1 + for i=start_idx, math.min(#store.packages, start_idx+num_per_page-1) do + local package = store.packages[i] + local container_y = (i - start_idx) * 1.375 + (2*0.375 + 0.8) + formspec[#formspec + 1] = "container[0.375," + formspec[#formspec + 1] = container_y + formspec[#formspec + 1] = "]" + + -- image + formspec[#formspec + 1] = "image[0,0;1.5,1;" + formspec[#formspec + 1] = core.formspec_escape(get_screenshot(package)) + formspec[#formspec + 1] = "]" + + -- title + formspec[#formspec + 1] = "label[1.875,0.1;" + formspec[#formspec + 1] = core.formspec_escape( + core.colorize(mt_color_green, package.title) .. + core.colorize("#BFBFBF", " by " .. package.author)) + formspec[#formspec + 1] = "]" + + -- buttons + local left_base = "image_button[-1.55,0;0.7,0.7;" .. core.formspec_escape(defaulttexturedir) + formspec[#formspec + 1] = "container[" + formspec[#formspec + 1] = W - 0.375*2 + formspec[#formspec + 1] = ",0.1]" + + if package.downloading then + formspec[#formspec + 1] = "animated_image[-1.7,-0.15;1,1;downloading;" + formspec[#formspec + 1] = core.formspec_escape(defaulttexturedir) + formspec[#formspec + 1] = "cdb_downloading.png;3;400;]" + elseif package.queued then + formspec[#formspec + 1] = left_base + formspec[#formspec + 1] = "cdb_queued.png;queued;]" + elseif not package.path then + local elem_name = "install_" .. i .. ";" + formspec[#formspec + 1] = "style[" .. elem_name .. "bgcolor=#71aa34]" + formspec[#formspec + 1] = left_base .. "cdb_add.png;" .. elem_name .. "]" + formspec[#formspec + 1] = "tooltip[" .. elem_name .. fgettext("Install") .. tooltip_colors + else + if package.installed_release < package.release then + + -- The install_ action also handles updating + local elem_name = "install_" .. i .. ";" + formspec[#formspec + 1] = "style[" .. elem_name .. "bgcolor=#28ccdf]" + formspec[#formspec + 1] = left_base .. "cdb_update.png;" .. elem_name .. "]" + formspec[#formspec + 1] = "tooltip[" .. elem_name .. fgettext("Update") .. tooltip_colors + else + + local elem_name = "uninstall_" .. i .. ";" + formspec[#formspec + 1] = "style[" .. elem_name .. "bgcolor=#a93b3b]" + formspec[#formspec + 1] = left_base .. "cdb_clear.png;" .. elem_name .. "]" + formspec[#formspec + 1] = "tooltip[" .. elem_name .. fgettext("Uninstall") .. tooltip_colors + end + end + + local web_elem_name = "view_" .. i .. ";" + formspec[#formspec + 1] = "image_button[-0.7,0;0.7,0.7;" .. + core.formspec_escape(defaulttexturedir) .. "cdb_viewonline.png;" .. web_elem_name .. "]" + formspec[#formspec + 1] = "tooltip[" .. web_elem_name .. + fgettext("View more information in a web browser") .. tooltip_colors + formspec[#formspec + 1] = "container_end[]" + + -- description + local description_width = W - 0.375*5 - 0.85 - 2*0.7 + formspec[#formspec + 1] = "textarea[1.855,0.3;" + formspec[#formspec + 1] = tostring(description_width) + formspec[#formspec + 1] = ",0.8;;;" + formspec[#formspec + 1] = core.formspec_escape(package.short_description) + formspec[#formspec + 1] = "]" + + formspec[#formspec + 1] = "container_end[]" + end + + return table.concat(formspec, "") +end + +function store.handle_submit(this, fields) + if fields.search or fields.key_enter_field == "search_string" then + search_string = fields.search_string:trim() + cur_page = 1 + store.filter_packages(search_string) + return true + end + + if fields.clear then + search_string = "" + cur_page = 1 + store.filter_packages("") + return true + end + + if fields.back then + this:delete() + return true + end + + if fields.pstart then + cur_page = 1 + return true + end + + if fields.pend then + cur_page = this.data.pagemax + return true + end + + if fields.pnext then + cur_page = cur_page + 1 + if cur_page > this.data.pagemax then + cur_page = 1 + end + return true + end + + if fields.pback then + if cur_page == 1 then + cur_page = this.data.pagemax + else + cur_page = cur_page - 1 + end + return true + end + + if fields.type then + local new_type = table.indexof(filter_types_titles, fields.type) + if new_type ~= filter_type then + filter_type = new_type + store.filter_packages(search_string) + return true + end + end + + if fields.update_all then + for i=1, #store.packages_full do + local package = store.packages_full[i] + if package.path and package.installed_release < package.release and + not (package.downloading or package.queued) then + queue_download(package, REASON_UPDATE) + end + end + return true + end + + local start_idx = (cur_page - 1) * num_per_page + 1 + assert(start_idx ~= nil) + for i=start_idx, math.min(#store.packages, start_idx+num_per_page-1) do + local package = store.packages[i] + assert(package) + + if fields["install_" .. i] then + local install_parent + if package.type == "mod" then + install_parent = core.get_modpath() + elseif package.type == "game" then + install_parent = core.get_gamepath() + elseif package.type == "txp" then + install_parent = core.get_texturepath() + else + error("Unknown package type: " .. package.type) + end + + + local function on_confirm() + local deps = get_raw_dependencies(package) + if deps and has_hard_deps(deps) then + local dlg = install_dialog.create(package, deps) + dlg:set_parent(this) + this:hide() + dlg:show() + else + queue_download(package, package.path and REASON_UPDATE or REASON_NEW) + end + end + + if not package.path and core.is_dir(install_parent .. DIR_DELIM .. package.name) then + local dlg = confirm_overwrite.create(package, on_confirm) + dlg:set_parent(this) + this:hide() + dlg:show() + else + on_confirm() + end + + return true + end + + if fields["uninstall_" .. i] then + local dlg = create_delete_content_dlg(package) + dlg:set_parent(this) + this:hide() + dlg:show() + return true + end + + if fields["view_" .. i] then + local url = ("%s/packages/%s?protocol_version=%d"):format( + core.settings:get("contentdb_url"), package.url_part, + core.get_max_supp_proto()) + core.open_url(url) + return true + end + end + + return false +end + +function create_store_dlg(type) + if not store.loaded or #store.packages_full == 0 then + store.load() + end + + store.update_paths() + store.sort_packages() + + search_string = "" + cur_page = 1 + + if type then + -- table.indexof does not work on tables that contain `nil` + for i, v in pairs(filter_types_type) do + if v == type then + filter_type = i + break + end + end + end + + store.filter_packages(search_string) + + return dialog_create("store", + store.get_formspec, + store.handle_submit, + nil) +end diff --git a/builtin/mainmenu/dlg_create_world.lua b/builtin/mainmenu/dlg_create_world.lua new file mode 100644 index 0000000..806e019 --- /dev/null +++ b/builtin/mainmenu/dlg_create_world.lua @@ -0,0 +1,488 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +local function table_to_flags(ftable) + -- Convert e.g. { jungles = true, caves = false } to "jungles,nocaves" + local str = {} + for flag, is_set in pairs(ftable) do + str[#str + 1] = is_set and flag or ("no" .. flag) + end + return table.concat(str, ",") +end + +-- Same as check_flag but returns a string +local function strflag(flags, flag) + return (flags[flag] == true) and "true" or "false" +end + +local cb_caverns = { "caverns", fgettext("Caverns"), + fgettext("Very large caverns deep in the underground") } + +local flag_checkboxes = { + v5 = { + cb_caverns, + }, + v7 = { + cb_caverns, + { "ridges", fgettext("Rivers"), fgettext("Sea level rivers") }, + { "mountains", fgettext("Mountains") }, + { "floatlands", fgettext("Floatlands (experimental)"), + fgettext("Floating landmasses in the sky") }, + }, + carpathian = { + cb_caverns, + { "rivers", fgettext("Rivers"), fgettext("Sea level rivers") }, + }, + valleys = { + { "altitude_chill", fgettext("Altitude chill"), + fgettext("Reduces heat with altitude") }, + { "altitude_dry", fgettext("Altitude dry"), + fgettext("Reduces humidity with altitude") }, + { "humid_rivers", fgettext("Humid rivers"), + fgettext("Increases humidity around rivers") }, + { "vary_river_depth", fgettext("Vary river depth"), + fgettext("Low humidity and high heat causes shallow or dry rivers") }, + }, + flat = { + cb_caverns, + { "hills", fgettext("Hills") }, + { "lakes", fgettext("Lakes") }, + }, + fractal = { + { "terrain", fgettext("Additional terrain"), + fgettext("Generate non-fractal terrain: Oceans and underground") }, + }, + v6 = { + { "trees", fgettext("Trees and jungle grass") }, + { "flat", fgettext("Flat terrain") }, + { "mudflow", fgettext("Mud flow"), fgettext("Terrain surface erosion") }, + -- Biome settings are in mgv6_biomes below + }, +} + +local mgv6_biomes = { + { + fgettext("Temperate, Desert, Jungle, Tundra, Taiga"), + {jungles = true, snowbiomes = true} + }, + { + fgettext("Temperate, Desert, Jungle"), + {jungles = true, snowbiomes = false} + }, + { + fgettext("Temperate, Desert"), + {jungles = false, snowbiomes = false} + }, +} + +local function create_world_formspec(dialogdata) + + -- Point the player to ContentDB when no games are found + if #pkgmgr.games == 0 then + return "size[8,2.5,true]" .. + "style[label_button;border=false]" .. + "button[0.5,0.5;7,0.5;label_button;" .. + fgettext("You have no games installed.") .. "]" .. + "button[0.5,1.5;2.5,0.5;world_create_open_cdb;" .. fgettext("Install a game") .. "]" .. + "button[5.0,1.5;2.5,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]" + end + + local current_mg = dialogdata.mg + local mapgens = core.get_mapgen_names() + + local gameid = core.settings:get("menu_last_game") + + local flags = dialogdata.flags + + local game = pkgmgr.find_by_gameid(gameid) + if game == nil then + -- should never happen but just pick the first game + game = pkgmgr.get_game(1) + core.settings:set("menu_last_game", game.id) + end + + local disallowed_mapgen_settings = {} + if game ~= nil then + local gameconfig = Settings(game.path.."/game.conf") + + local allowed_mapgens = (gameconfig:get("allowed_mapgens") or ""):split() + for key, value in pairs(allowed_mapgens) do + allowed_mapgens[key] = value:trim() + end + + local disallowed_mapgens = (gameconfig:get("disallowed_mapgens") or ""):split() + for key, value in pairs(disallowed_mapgens) do + disallowed_mapgens[key] = value:trim() + end + + if #allowed_mapgens > 0 then + for i = #mapgens, 1, -1 do + if table.indexof(allowed_mapgens, mapgens[i]) == -1 then + table.remove(mapgens, i) + end + end + end + + if #disallowed_mapgens > 0 then + for i = #mapgens, 1, -1 do + if table.indexof(disallowed_mapgens, mapgens[i]) > 0 then + table.remove(mapgens, i) + end + end + end + + local ds = (gameconfig:get("disallowed_mapgen_settings") or ""):split() + for _, value in pairs(ds) do + disallowed_mapgen_settings[value:trim()] = true + end + end + + local mglist = "" + local selindex + do -- build the list of mapgens + local i = 1 + local first_mg + for k, v in pairs(mapgens) do + if not first_mg then + first_mg = v + end + if current_mg == v then + selindex = i + end + i = i + 1 + mglist = mglist .. core.formspec_escape(v) .. "," + end + if not selindex then + selindex = 1 + current_mg = first_mg + end + mglist = mglist:sub(1, -2) + end + + -- The logic of the flag element IDs is as follows: + -- "flag_main_foo-bar-baz" controls dialogdata.flags["main"]["foo_bar_baz"] + -- see the buttonhandler for the implementation of this + + local mg_main_flags = function(mapgen, y) + if mapgen == "singlenode" then + return "", y + end + if disallowed_mapgen_settings["mg_flags"] then + return "", y + end + + local form = "checkbox[0," .. y .. ";flag_main_caves;" .. + fgettext("Caves") .. ";"..strflag(flags.main, "caves").."]" + y = y + 0.5 + + form = form .. "checkbox[0,"..y..";flag_main_dungeons;" .. + fgettext("Dungeons") .. ";"..strflag(flags.main, "dungeons").."]" + y = y + 0.5 + + local d_name = fgettext("Decorations") + local d_tt + if mapgen == "v6" then + d_tt = fgettext("Structures appearing on the terrain (no effect on trees and jungle grass created by v6)") + else + d_tt = fgettext("Structures appearing on the terrain, typically trees and plants") + end + form = form .. "checkbox[0,"..y..";flag_main_decorations;" .. + d_name .. ";" .. + strflag(flags.main, "decorations").."]" .. + "tooltip[flag_mg_decorations;" .. + d_tt .. + "]" + y = y + 0.5 + + form = form .. "tooltip[flag_main_caves;" .. + fgettext("Network of tunnels and caves") + .. "]" + return form, y + end + + local mg_specific_flags = function(mapgen, y) + if not flag_checkboxes[mapgen] then + return "", y + end + if disallowed_mapgen_settings["mg"..mapgen.."_spflags"] then + return "", y + end + local form = "" + for _, tab in pairs(flag_checkboxes[mapgen]) do + local id = "flag_"..mapgen.."_"..tab[1]:gsub("_", "-") + form = form .. ("checkbox[0,%f;%s;%s;%s]"): + format(y, id, tab[2], strflag(flags[mapgen], tab[1])) + + if tab[3] then + form = form .. "tooltip["..id..";"..tab[3].."]" + end + y = y + 0.5 + end + + if mapgen ~= "v6" then + -- No special treatment + return form, y + end + -- Special treatment for v6 (add biome widgets) + + -- Biome type (jungles, snowbiomes) + local biometype + if flags.v6.snowbiomes == true then + biometype = 1 + elseif flags.v6.jungles == true then + biometype = 2 + else + biometype = 3 + end + y = y + 0.3 + + form = form .. "label[0,"..(y+0.1)..";" .. fgettext("Biomes") .. "]" + y = y + 0.6 + + form = form .. "dropdown[0,"..y..";6.3;mgv6_biomes;" + for b=1, #mgv6_biomes do + form = form .. mgv6_biomes[b][1] + if b < #mgv6_biomes then + form = form .. "," + end + end + form = form .. ";" .. biometype.. "]" + + -- biomeblend + y = y + 0.55 + form = form .. "checkbox[0,"..y..";flag_v6_biomeblend;" .. + fgettext("Biome blending") .. ";"..strflag(flags.v6, "biomeblend").."]" .. + "tooltip[flag_v6_biomeblend;" .. + fgettext("Smooth transition between biomes") .. "]" + + return form, y + end + + local y_start = 0.0 + local y = y_start + local str_flags, str_spflags + local label_flags, label_spflags = "", "" + y = y + 0.3 + str_flags, y = mg_main_flags(current_mg, y) + if str_flags ~= "" then + label_flags = "label[0,"..y_start..";" .. fgettext("Mapgen flags") .. "]" + y_start = y + 0.4 + else + y_start = 0.0 + end + y = y_start + 0.3 + str_spflags = mg_specific_flags(current_mg, y) + if str_spflags ~= "" then + label_spflags = "label[0,"..y_start..";" .. fgettext("Mapgen-specific flags") .. "]" + end + + local retval = + "size[12.25,7,true]" .. + + -- Left side + "container[0,0]".. + "field[0.3,0.6;6,0.5;te_world_name;" .. + fgettext("World name") .. + ";" .. core.formspec_escape(dialogdata.worldname) .. "]" .. + "set_focus[te_world_name;false]" + + if not disallowed_mapgen_settings["seed"] then + + retval = retval .. "field[0.3,1.7;6,0.5;te_seed;" .. + fgettext("Seed") .. + ";".. core.formspec_escape(dialogdata.seed) .. "]" + + end + + retval = retval .. + "label[0,2;" .. fgettext("Mapgen") .. "]".. + "dropdown[0,2.5;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" + + -- Warning if only devtest is installed + if #pkgmgr.games == 1 and pkgmgr.games[1].id == "devtest" then + retval = retval .. + "container[0,3.5]" .. + "box[0,0;5.8,1.7;#ff8800]" .. + "textarea[0.4,0.1;6,1.8;;;".. + fgettext("Development Test is meant for developers.") .. "]" .. + "button[1,1;4,0.5;world_create_open_cdb;" .. fgettext("Install another game") .. "]" .. + "container_end[]" + end + + retval = retval .. + "container_end[]" .. + + -- Right side + "container[6.2,0]".. + label_flags .. str_flags .. + label_spflags .. str_spflags .. + "container_end[]".. + + -- Menu buttons + "button[3.25,6.5;3,0.5;world_create_confirm;" .. fgettext("Create") .. "]" .. + "button[6.25,6.5;3,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]" + + return retval + +end + +local function create_world_buttonhandler(this, fields) + + if fields["world_create_open_cdb"] then + local dlg = create_store_dlg("game") + dlg:set_parent(this.parent) + this:delete() + this.parent:hide() + dlg:show() + return true + end + + if fields["world_create_confirm"] or + fields["key_enter"] then + + local worldname = fields["te_world_name"] + local game, gameindex = pkgmgr.find_by_gameid(core.settings:get("menu_last_game")) + + local message + if game == nil then + message = fgettext("No game selected") + end + + if message == nil then + -- For unnamed worlds use the generated name 'world<number>', + -- where the number increments: it is set to 1 larger than the largest + -- generated name number found. + if worldname == "" then + local worldnum_max = 0 + for _, world in ipairs(menudata.worldlist:get_list()) do + if world.name:match("^world%d+$") then + local worldnum = tonumber(world.name:sub(6)) + worldnum_max = math.max(worldnum_max, worldnum) + end + end + worldname = "world" .. worldnum_max + 1 + end + + if menudata.worldlist:uid_exists_raw(worldname) then + message = fgettext("A world named \"$1\" already exists", worldname) + end + end + + if message == nil then + this.data.seed = fields["te_seed"] or "" + this.data.mg = fields["dd_mapgen"] + + -- actual names as used by engine + local settings = { + fixed_map_seed = this.data.seed, + mg_name = this.data.mg, + mg_flags = table_to_flags(this.data.flags.main), + mgv5_spflags = table_to_flags(this.data.flags.v5), + mgv6_spflags = table_to_flags(this.data.flags.v6), + mgv7_spflags = table_to_flags(this.data.flags.v7), + mgfractal_spflags = table_to_flags(this.data.flags.fractal), + mgcarpathian_spflags = table_to_flags(this.data.flags.carpathian), + mgvalleys_spflags = table_to_flags(this.data.flags.valleys), + mgflat_spflags = table_to_flags(this.data.flags.flat), + } + message = core.create_world(worldname, gameindex, settings) + end + + if message == nil then + core.settings:set("menu_last_game", game.id) + menudata.worldlist:set_filtercriteria(game.id) + menudata.worldlist:refresh() + core.settings:set("mainmenu_last_selected_world", + menudata.worldlist:raw_index_by_uid(worldname)) + end + + gamedata.errormessage = message + this:delete() + return true + end + + this.data.worldname = fields["te_world_name"] + this.data.seed = fields["te_seed"] or "" + + if fields["games"] then + local gameindex = core.get_textlist_index("games") + core.settings:set("menu_last_game", pkgmgr.games[gameindex].id) + return true + end + + for k,v in pairs(fields) do + local split = string.split(k, "_", nil, 3) + if split and split[1] == "flag" then + -- We replaced the underscore of flag names with a dash. + local flag = string.gsub(split[3], "-", "_") + local ftable = this.data.flags[split[2]] + assert(ftable) + ftable[flag] = v == "true" + return true + end + end + + if fields["world_create_cancel"] then + this:delete() + return true + end + + if fields["mgv6_biomes"] then + local entry = core.formspec_escape(fields["mgv6_biomes"]) + for b=1, #mgv6_biomes do + if entry == mgv6_biomes[b][1] then + local ftable = this.data.flags.v6 + ftable.jungles = mgv6_biomes[b][2].jungles + ftable.snowbiomes = mgv6_biomes[b][2].snowbiomes + return true + end + end + end + + if fields["dd_mapgen"] then + this.data.mg = fields["dd_mapgen"] + return true + end + + return false +end + + +function create_create_world_dlg() + local retval = dialog_create("sp_create_world", + create_world_formspec, + create_world_buttonhandler, + nil) + retval.data = { + worldname = "", + -- settings the world is created with: + seed = core.settings:get("fixed_map_seed") or "", + mg = core.settings:get("mg_name"), + flags = { + main = core.settings:get_flags("mg_flags"), + v5 = core.settings:get_flags("mgv5_spflags"), + v6 = core.settings:get_flags("mgv6_spflags"), + v7 = core.settings:get_flags("mgv7_spflags"), + fractal = core.settings:get_flags("mgfractal_spflags"), + carpathian = core.settings:get_flags("mgcarpathian_spflags"), + valleys = core.settings:get_flags("mgvalleys_spflags"), + flat = core.settings:get_flags("mgflat_spflags"), + } + } + + return retval +end diff --git a/builtin/mainmenu/dlg_delete_content.lua b/builtin/mainmenu/dlg_delete_content.lua new file mode 100644 index 0000000..4463825 --- /dev/null +++ b/builtin/mainmenu/dlg_delete_content.lua @@ -0,0 +1,70 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-------------------------------------------------------------------------------- + +local function delete_content_formspec(dialogdata) + return confirmation_formspec( + fgettext("Are you sure you want to delete \"$1\"?", dialogdata.content.name), + 'dlg_delete_content_confirm', fgettext("Delete"), + 'dlg_delete_content_cancel', fgettext("Cancel")) +end + +-------------------------------------------------------------------------------- +local function delete_content_buttonhandler(this, fields) + if fields["dlg_delete_content_confirm"] ~= nil then + + if this.data.content.path ~= nil and + this.data.content.path ~= "" and + this.data.content.path ~= core.get_modpath() and + this.data.content.path ~= core.get_gamepath() and + this.data.content.path ~= core.get_texturepath() then + if not core.delete_dir(this.data.content.path) then + gamedata.errormessage = fgettext("pkgmgr: failed to delete \"$1\"", this.data.content.path) + end + + if this.data.content.type == "game" then + pkgmgr.update_gamelist() + else + pkgmgr.refresh_globals() + end + else + gamedata.errormessage = fgettext("pkgmgr: invalid path \"$1\"", this.data.content.path) + end + this:delete() + return true + end + + if fields["dlg_delete_content_cancel"] then + this:delete() + return true + end + + return false +end + +-------------------------------------------------------------------------------- +function create_delete_content_dlg(content) + assert(content.name) + + local retval = dialog_create("dlg_delete_content", + delete_content_formspec, + delete_content_buttonhandler, + nil) + retval.data.content = content + return retval +end diff --git a/builtin/mainmenu/dlg_delete_world.lua b/builtin/mainmenu/dlg_delete_world.lua new file mode 100644 index 0000000..67c0612 --- /dev/null +++ b/builtin/mainmenu/dlg_delete_world.lua @@ -0,0 +1,58 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +local function delete_world_formspec(dialogdata) + return confirmation_formspec( + fgettext("Delete World \"$1\"?", dialogdata.delete_name), + 'world_delete_confirm', fgettext("Delete"), + 'world_delete_cancel', fgettext("Cancel")) +end + +local function delete_world_buttonhandler(this, fields) + if fields["world_delete_confirm"] then + if this.data.delete_index > 0 and + this.data.delete_index <= #menudata.worldlist:get_raw_list() then + core.delete_world(this.data.delete_index) + menudata.worldlist:refresh() + end + this:delete() + return true + end + + if fields["world_delete_cancel"] then + this:delete() + return true + end + + return false +end + + +function create_delete_world_dlg(name_to_del, index_to_del) + assert(name_to_del ~= nil and type(name_to_del) == "string" and name_to_del ~= "") + assert(index_to_del ~= nil and type(index_to_del) == "number") + + local retval = dialog_create("delete_world", + delete_world_formspec, + delete_world_buttonhandler, + nil) + retval.data.delete_name = name_to_del + retval.data.delete_index = index_to_del + + return retval +end diff --git a/builtin/mainmenu/dlg_register.lua b/builtin/mainmenu/dlg_register.lua new file mode 100644 index 0000000..a765824 --- /dev/null +++ b/builtin/mainmenu/dlg_register.lua @@ -0,0 +1,123 @@ +--Minetest +--Copyright (C) 2022 rubenwardy +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-------------------------------------------------------------------------------- + +local function register_formspec(dialogdata) + local title = fgettext("Joining $1", dialogdata.server and dialogdata.server.name or dialogdata.address) + local buttons_y = 4 + 1.3 + if dialogdata.error then + buttons_y = buttons_y + 0.8 + end + + local retval = { + "formspec_version[4]", + "size[8,", tostring(buttons_y + 1.175), "]", + "set_focus[", (dialogdata.name ~= "" and "password" or "name"), "]", + "label[0.375,0.8;", title, "]", + "field[0.375,1.575;7.25,0.8;name;", core.formspec_escape(fgettext("Name")), ";", + core.formspec_escape(dialogdata.name), "]", + "pwdfield[0.375,2.875;7.25,0.8;password;", core.formspec_escape(fgettext("Password")), "]", + "pwdfield[0.375,4.175;7.25,0.8;password_2;", core.formspec_escape(fgettext("Confirm Password")), "]" + } + + if dialogdata.error then + table.insert_all(retval, { + "box[0.375,", tostring(buttons_y - 0.9), ";7.25,0.6;darkred]", + "label[0.625,", tostring(buttons_y - 0.6), ";", core.formspec_escape(dialogdata.error), "]", + }) + end + + table.insert_all(retval, { + "container[0.375,", tostring(buttons_y), "]", + "button[0,0;2.5,0.8;dlg_register_confirm;", fgettext("Register"), "]", + "button[4.75,0;2.5,0.8;dlg_register_cancel;", fgettext("Cancel"), "]", + "container_end[]", + }) + + return table.concat(retval, "") +end + +-------------------------------------------------------------------------------- +local function register_buttonhandler(this, fields) + this.data.name = fields.name + this.data.error = nil + + if fields.dlg_register_confirm or fields.key_enter then + if fields.name == "" then + this.data.error = fgettext("Missing name") + return true + end + if fields.password ~= fields.password_2 then + this.data.error = fgettext("Passwords do not match") + return true + end + + gamedata.playername = fields.name + gamedata.password = fields.password + gamedata.address = this.data.address + gamedata.port = this.data.port + gamedata.allow_login_or_register = "register" + gamedata.selected_world = 0 + + assert(gamedata.address and gamedata.port) + + local server = this.data.server + if server then + serverlistmgr.add_favorite(server) + gamedata.servername = server.name + gamedata.serverdescription = server.description + else + gamedata.servername = "" + gamedata.serverdescription = "" + + serverlistmgr.add_favorite({ + address = gamedata.address, + port = gamedata.port, + }) + end + + core.settings:set("name", fields.name) + core.settings:set("address", gamedata.address) + core.settings:set("remote_port", gamedata.port) + + core.start() + end + + if fields["dlg_register_cancel"] then + this:delete() + return true + end + + return false +end + +-------------------------------------------------------------------------------- +function create_register_dialog(address, port, server) + assert(address) + assert(type(port) == "number") + + local retval = dialog_create("dlg_register", + register_formspec, + register_buttonhandler, + nil) + retval.data.address = address + retval.data.port = port + retval.data.server = server + retval.data.name = core.settings:get("name") or "" + return retval +end diff --git a/builtin/mainmenu/dlg_rename_modpack.lua b/builtin/mainmenu/dlg_rename_modpack.lua new file mode 100644 index 0000000..ca76a8c --- /dev/null +++ b/builtin/mainmenu/dlg_rename_modpack.lua @@ -0,0 +1,73 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-------------------------------------------------------------------------------- + +local function rename_modpack_formspec(dialogdata) + local retval = + "size[11.5,4.5,true]" .. + "button[3.25,3.5;2.5,0.5;dlg_rename_modpack_confirm;".. + fgettext("Accept") .. "]" .. + "button[5.75,3.5;2.5,0.5;dlg_rename_modpack_cancel;".. + fgettext("Cancel") .. "]" + + local input_y = 2 + if dialogdata.mod.is_name_explicit then + retval = retval .. "textarea[1,0.2;10,2;;;" .. + fgettext("This modpack has an explicit name given in its modpack.conf " .. + "which will override any renaming here.") .. "]" + input_y = 2.5 + end + retval = retval .. + "field[2.5," .. input_y .. ";7,0.5;te_modpack_name;" .. + fgettext("Rename Modpack:") .. ";" .. dialogdata.mod.dir_name .. "]" + + return retval +end + +-------------------------------------------------------------------------------- +local function rename_modpack_buttonhandler(this, fields) + if fields["dlg_rename_modpack_confirm"] ~= nil then + local oldpath = this.data.mod.path + local targetpath = this.data.mod.parent_dir .. DIR_DELIM .. fields["te_modpack_name"] + os.rename(oldpath, targetpath) + pkgmgr.refresh_globals() + pkgmgr.selected_mod = pkgmgr.global_mods:get_current_index( + pkgmgr.global_mods:raw_index_by_uid(fields["te_modpack_name"])) + + this:delete() + return true + end + + if fields["dlg_rename_modpack_cancel"] then + this:delete() + return true + end + + return false +end + +-------------------------------------------------------------------------------- +function create_rename_modpack_dlg(modpack) + + local retval = dialog_create("dlg_delete_mod", + rename_modpack_formspec, + rename_modpack_buttonhandler, + nil) + retval.data.mod = modpack + return retval +end diff --git a/builtin/mainmenu/dlg_settings_advanced.lua b/builtin/mainmenu/dlg_settings_advanced.lua new file mode 100644 index 0000000..69562e6 --- /dev/null +++ b/builtin/mainmenu/dlg_settings_advanced.lua @@ -0,0 +1,1137 @@ +--Minetest +--Copyright (C) 2015 PilzAdam +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +local FILENAME = "settingtypes.txt" + +local CHAR_CLASSES = { + SPACE = "[%s]", + VARIABLE = "[%w_%-%.]", + INTEGER = "[+-]?[%d]", + FLOAT = "[+-]?[%d%.]", + FLAGS = "[%w_%-%.,]", +} + +local function flags_to_table(flags) + return flags:gsub("%s+", ""):split(",", true) -- Remove all spaces and split +end + +-- returns error message, or nil +local function parse_setting_line(settings, line, read_all, base_level, allow_secure) + + -- strip carriage returns (CR, /r) + line = line:gsub("\r", "") + + -- comment + local comment = line:match("^#" .. CHAR_CLASSES.SPACE .. "*(.*)$") + if comment then + if settings.current_comment == "" then + settings.current_comment = comment + else + settings.current_comment = settings.current_comment .. "\n" .. comment + end + return + end + + -- clear current_comment so only comments directly above a setting are bound to it + -- but keep a local reference to it for variables in the current line + local current_comment = settings.current_comment + settings.current_comment = "" + + -- empty lines + if line:match("^" .. CHAR_CLASSES.SPACE .. "*$") then + return + end + + -- category + local stars, category = line:match("^%[([%*]*)([^%]]+)%]$") + if category then + table.insert(settings, { + name = category, + level = stars:len() + base_level, + type = "category", + }) + return + end + + -- settings + local first_part, name, readable_name, setting_type = line:match("^" + -- this first capture group matches the whole first part, + -- so we can later strip it from the rest of the line + .. "(" + .. "([" .. CHAR_CLASSES.VARIABLE .. "+)" -- variable name + .. CHAR_CLASSES.SPACE .. "*" + .. "%(([^%)]*)%)" -- readable name + .. CHAR_CLASSES.SPACE .. "*" + .. "(" .. CHAR_CLASSES.VARIABLE .. "+)" -- type + .. CHAR_CLASSES.SPACE .. "*" + .. ")") + + if not first_part then + return "Invalid line" + end + + if name:match("secure%.[.]*") and not allow_secure then + return "Tried to add \"secure.\" setting" + end + + if readable_name == "" then + readable_name = nil + end + local remaining_line = line:sub(first_part:len() + 1) + + if setting_type == "int" then + local default, min, max = remaining_line:match("^" + -- first int is required, the last 2 are optional + .. "(" .. CHAR_CLASSES.INTEGER .. "+)" .. CHAR_CLASSES.SPACE .. "*" + .. "(" .. CHAR_CLASSES.INTEGER .. "*)" .. CHAR_CLASSES.SPACE .. "*" + .. "(" .. CHAR_CLASSES.INTEGER .. "*)" + .. "$") + + if not default or not tonumber(default) then + return "Invalid integer setting" + end + + min = tonumber(min) + max = tonumber(max) + table.insert(settings, { + name = name, + readable_name = readable_name, + type = "int", + default = default, + min = min, + max = max, + comment = current_comment, + }) + return + end + + if setting_type == "string" + or setting_type == "key" or setting_type == "v3f" then + local default = remaining_line:match("^(.*)$") + + if not default then + return "Invalid string setting" + end + if setting_type == "key" and not read_all then + -- ignore key type if read_all is false + return + end + + table.insert(settings, { + name = name, + readable_name = readable_name, + type = setting_type, + default = default, + comment = current_comment, + }) + return + end + + if setting_type == "noise_params_2d" + or setting_type == "noise_params_3d" then + local default = remaining_line:match("^(.*)$") + + if not default then + return "Invalid string setting" + end + + local values = {} + local ti = 1 + local index = 1 + for match in default:gmatch("[+-]?[%d.-e]+") do -- All numeric characters + index = default:find("[+-]?[%d.-e]+", index) + match:len() + table.insert(values, match) + ti = ti + 1 + if ti > 9 then + break + end + end + index = default:find("[^, ]", index) + local flags = "" + if index then + flags = default:sub(index) + default = default:sub(1, index - 3) -- Make sure no flags in single-line format + end + table.insert(values, flags) + + table.insert(settings, { + name = name, + readable_name = readable_name, + type = setting_type, + default = default, + default_table = { + offset = values[1], + scale = values[2], + spread = { + x = values[3], + y = values[4], + z = values[5] + }, + seed = values[6], + octaves = values[7], + persistence = values[8], + lacunarity = values[9], + flags = values[10] + }, + values = values, + comment = current_comment, + noise_params = true, + flags = flags_to_table("defaults,eased,absvalue") + }) + return + end + + if setting_type == "bool" then + if remaining_line ~= "false" and remaining_line ~= "true" then + return "Invalid boolean setting" + end + + table.insert(settings, { + name = name, + readable_name = readable_name, + type = "bool", + default = remaining_line, + comment = current_comment, + }) + return + end + + if setting_type == "float" then + local default, min, max = remaining_line:match("^" + -- first float is required, the last 2 are optional + .. "(" .. CHAR_CLASSES.FLOAT .. "+)" .. CHAR_CLASSES.SPACE .. "*" + .. "(" .. CHAR_CLASSES.FLOAT .. "*)" .. CHAR_CLASSES.SPACE .. "*" + .. "(" .. CHAR_CLASSES.FLOAT .. "*)" + .."$") + + if not default or not tonumber(default) then + return "Invalid float setting" + end + + min = tonumber(min) + max = tonumber(max) + table.insert(settings, { + name = name, + readable_name = readable_name, + type = "float", + default = default, + min = min, + max = max, + comment = current_comment, + }) + return + end + + if setting_type == "enum" then + local default, values = remaining_line:match("^" + -- first value (default) may be empty (i.e. is optional) + .. "(" .. CHAR_CLASSES.VARIABLE .. "*)" .. CHAR_CLASSES.SPACE .. "*" + .. "(" .. CHAR_CLASSES.FLAGS .. "+)" + .. "$") + + if not default or values == "" then + return "Invalid enum setting" + end + + table.insert(settings, { + name = name, + readable_name = readable_name, + type = "enum", + default = default, + values = values:split(",", true), + comment = current_comment, + }) + return + end + + if setting_type == "path" or setting_type == "filepath" then + local default = remaining_line:match("^(.*)$") + + if not default then + return "Invalid path setting" + end + + table.insert(settings, { + name = name, + readable_name = readable_name, + type = setting_type, + default = default, + comment = current_comment, + }) + return + end + + if setting_type == "flags" then + local default, possible = remaining_line:match("^" + -- first value (default) may be empty (i.e. is optional) + -- this is implemented by making the last value optional, and + -- swapping them around if it turns out empty. + .. "(" .. CHAR_CLASSES.FLAGS .. "+)" .. CHAR_CLASSES.SPACE .. "*" + .. "(" .. CHAR_CLASSES.FLAGS .. "*)" + .. "$") + + if not default or not possible then + return "Invalid flags setting" + end + + if possible == "" then + possible = default + default = "" + end + + table.insert(settings, { + name = name, + readable_name = readable_name, + type = "flags", + default = default, + possible = flags_to_table(possible), + comment = current_comment, + }) + return + end + + return "Invalid setting type \"" .. setting_type .. "\"" +end + +local function parse_single_file(file, filepath, read_all, result, base_level, allow_secure) + -- store this helper variable in the table so it's easier to pass to parse_setting_line() + result.current_comment = "" + + local line = file:read("*line") + while line do + local error_msg = parse_setting_line(result, line, read_all, base_level, allow_secure) + if error_msg then + core.log("error", error_msg .. " in " .. filepath .. " \"" .. line .. "\"") + end + line = file:read("*line") + end + + result.current_comment = nil +end + +-- read_all: whether to ignore certain setting types for GUI or not +-- parse_mods: whether to parse settingtypes.txt in mods and games +local function parse_config_file(read_all, parse_mods) + local settings = {} + + do + local builtin_path = core.get_builtin_path() .. FILENAME + local file = io.open(builtin_path, "r") + if not file then + core.log("error", "Can't load " .. FILENAME) + return settings + end + + parse_single_file(file, builtin_path, read_all, settings, 0, true) + + file:close() + end + + if parse_mods then + -- Parse games + local games_category_initialized = false + local index = 1 + local game = pkgmgr.get_game(index) + while game do + local path = game.path .. DIR_DELIM .. FILENAME + local file = io.open(path, "r") + if file then + if not games_category_initialized then + fgettext_ne("Content: Games") -- not used, but needed for xgettext + table.insert(settings, { + name = "Content: Games", + level = 0, + type = "category", + }) + games_category_initialized = true + end + + table.insert(settings, { + name = game.name, + level = 1, + type = "category", + }) + + parse_single_file(file, path, read_all, settings, 2, false) + + file:close() + end + + index = index + 1 + game = pkgmgr.get_game(index) + end + + -- Parse mods + local mods_category_initialized = false + local mods = {} + get_mods(core.get_modpath(), "mods", mods) + for _, mod in ipairs(mods) do + local path = mod.path .. DIR_DELIM .. FILENAME + local file = io.open(path, "r") + if file then + if not mods_category_initialized then + fgettext_ne("Content: Mods") -- not used, but needed for xgettext + table.insert(settings, { + name = "Content: Mods", + level = 0, + type = "category", + }) + mods_category_initialized = true + end + + table.insert(settings, { + name = mod.name, + readable_name = mod.title, + level = 1, + type = "category", + }) + + parse_single_file(file, path, read_all, settings, 2, false) + + file:close() + end + end + + -- Parse client mods + local clientmods_category_initialized = false + local clientmods = {} + get_mods(core.get_clientmodpath(), "clientmods", clientmods) + for _, mod in ipairs(clientmods) do + local path = mod.path .. DIR_DELIM .. FILENAME + local file = io.open(path, "r") + if file then + if not clientmods_category_initialized then + fgettext_ne("Client Mods") -- not used, but needed for xgettext + table.insert(settings, { + name = "Client Mods", + level = 0, + type = "category", + }) + clientmods_category_initialized = true + end + + table.insert(settings, { + name = mod.name, + level = 1, + type = "category", + }) + + parse_single_file(file, path, read_all, settings, 2, false) + + file:close() + end + end + end + + return settings +end + +local function filter_settings(settings, searchstring) + if not searchstring or searchstring == "" then + return settings, -1 + end + + -- Setup the keyword list + local keywords = {} + for word in searchstring:lower():gmatch("%S+") do + table.insert(keywords, word) + end + + local result = {} + local category_stack = {} + local current_level = 0 + local best_setting = nil + for _, entry in pairs(settings) do + if entry.type == "category" then + -- Remove all settingless categories + while #category_stack > 0 and entry.level <= current_level do + table.remove(category_stack, #category_stack) + if #category_stack > 0 then + current_level = category_stack[#category_stack].level + else + current_level = 0 + end + end + + -- Push category onto stack + category_stack[#category_stack + 1] = entry + current_level = entry.level + else + -- See if setting matches keywords + local setting_score = 0 + for k = 1, #keywords do + local keyword = keywords[k] + + if string.find(entry.name:lower(), keyword, 1, true) then + setting_score = setting_score + 1 + end + + if entry.readable_name and + string.find(fgettext(entry.readable_name):lower(), keyword, 1, true) then + setting_score = setting_score + 1 + end + + if entry.comment and + string.find(fgettext_ne(entry.comment):lower(), keyword, 1, true) then + setting_score = setting_score + 1 + end + end + + -- Add setting to results if match + if setting_score > 0 then + -- Add parent categories + for _, category in pairs(category_stack) do + result[#result + 1] = category + end + category_stack = {} + + -- Add setting + result[#result + 1] = entry + entry.score = setting_score + + if not best_setting or + setting_score > result[best_setting].score then + best_setting = #result + end + end + end + end + return result, best_setting or -1 +end + +local full_settings = parse_config_file(false, true) +local search_string = "" +local settings = full_settings +local selected_setting = 1 + +local function get_current_value(setting) + local value = core.settings:get(setting.name) + if value == nil then + value = setting.default + end + return value +end + +local function get_current_np_group(setting) + local value = core.settings:get_np_group(setting.name) + if value == nil then + return setting.values + end + local p = "%g" + return { + p:format(value.offset), + p:format(value.scale), + p:format(value.spread.x), + p:format(value.spread.y), + p:format(value.spread.z), + p:format(value.seed), + p:format(value.octaves), + p:format(value.persistence), + p:format(value.lacunarity), + value.flags + } +end + +local function get_current_np_group_as_string(setting) + local value = core.settings:get_np_group(setting.name) + if value == nil then + return setting.default + end + return ("%g, %g, (%g, %g, %g), %g, %g, %g, %g"):format( + value.offset, + value.scale, + value.spread.x, + value.spread.y, + value.spread.z, + value.seed, + value.octaves, + value.persistence, + value.lacunarity + ) .. (value.flags ~= "" and (", " .. value.flags) or "") +end + +local checkboxes = {} -- handle checkboxes events + +local function create_change_setting_formspec(dialogdata) + local setting = settings[selected_setting] + -- Final formspec will be created at the end of this function + -- Default values below, may be changed depending on setting type + local width = 10 + local height = 3.5 + local description_height = 3 + local formspec = "" + + -- Setting-specific formspec elements + if setting.type == "bool" then + local selected_index = 1 + if core.is_yes(get_current_value(setting)) then + selected_index = 2 + end + formspec = "dropdown[3," .. height .. ";4,1;dd_setting_value;" + .. fgettext("Disabled") .. "," .. fgettext("Enabled") .. ";" + .. selected_index .. "]" + height = height + 1.25 + + elseif setting.type == "enum" then + local selected_index = 0 + formspec = "dropdown[3," .. height .. ";4,1;dd_setting_value;" + for index, value in ipairs(setting.values) do + -- translating value is not possible, since it's the value + -- that we set the setting to + formspec = formspec .. core.formspec_escape(value) .. "," + if get_current_value(setting) == value then + selected_index = index + end + end + if #setting.values > 0 then + formspec = formspec:sub(1, -2) -- remove trailing comma + end + formspec = formspec .. ";" .. selected_index .. "]" + height = height + 1.25 + + elseif setting.type == "path" or setting.type == "filepath" then + local current_value = dialogdata.selected_path + if not current_value then + current_value = get_current_value(setting) + end + formspec = "field[0.28," .. height + 0.15 .. ";8,1;te_setting_value;;" + .. core.formspec_escape(current_value) .. "]" + .. "button[8," .. height - 0.15 .. ";2,1;btn_browser_" + .. setting.type .. ";" .. fgettext("Browse") .. "]" + height = height + 1.15 + + elseif setting.type == "noise_params_2d" or setting.type == "noise_params_3d" then + local t = get_current_np_group(setting) + local dimension = 3 + if setting.type == "noise_params_2d" then + dimension = 2 + end + + -- More space for 3x3 fields + description_height = description_height - 1.5 + height = height - 1.5 + + local fields = {} + local function add_field(x, name, label, value) + fields[#fields + 1] = ("field[%f,%f;3.3,1;%s;%s;%s]"):format( + x, height, name, label, core.formspec_escape(value or "") + ) + end + -- First row + height = height + 0.3 + add_field(0.3, "te_offset", fgettext("Offset"), t[1]) + add_field(3.6, "te_scale", fgettext("Scale"), t[2]) + add_field(6.9, "te_seed", fgettext("Seed"), t[6]) + height = height + 1.1 + + -- Second row + add_field(0.3, "te_spreadx", fgettext("X spread"), t[3]) + if dimension == 3 then + add_field(3.6, "te_spready", fgettext("Y spread"), t[4]) + else + fields[#fields + 1] = "label[4," .. height - 0.2 .. ";" .. + fgettext("2D Noise") .. "]" + end + add_field(6.9, "te_spreadz", fgettext("Z spread"), t[5]) + height = height + 1.1 + + -- Third row + add_field(0.3, "te_octaves", fgettext("Octaves"), t[7]) + add_field(3.6, "te_persist", fgettext("Persistence"), t[8]) + add_field(6.9, "te_lacun", fgettext("Lacunarity"), t[9]) + height = height + 1.1 + + + local enabled_flags = flags_to_table(t[10]) + local flags = {} + for _, name in ipairs(enabled_flags) do + -- Index by name, to avoid iterating over all enabled_flags for every possible flag. + flags[name] = true + end + for _, name in ipairs(setting.flags) do + local checkbox_name = "cb_" .. name + local is_enabled = flags[name] == true -- to get false if nil + checkboxes[checkbox_name] = is_enabled + end + -- Flags + formspec = table.concat(fields) + .. "checkbox[0.5," .. height - 0.6 .. ";cb_defaults;" + --[[~ "defaults" is a noise parameter flag. + It describes the default processing options + for noise settings in main menu -> "All Settings". ]] + .. fgettext("defaults") .. ";" -- defaults + .. tostring(flags["defaults"] == true) .. "]" -- to get false if nil + .. "checkbox[5," .. height - 0.6 .. ";cb_eased;" + --[[~ "eased" is a noise parameter flag. + It is used to make the map smoother and + can be enabled in noise settings in + main menu -> "All Settings". ]] + .. fgettext("eased") .. ";" -- eased + .. tostring(flags["eased"] == true) .. "]" + .. "checkbox[5," .. height - 0.15 .. ";cb_absvalue;" + --[[~ "absvalue" is a noise parameter flag. + It is short for "absolute value". + It can be enabled in noise settings in + main menu -> "All Settings". ]] + .. fgettext("absvalue") .. ";" -- absvalue + .. tostring(flags["absvalue"] == true) .. "]" + height = height + 1 + + elseif setting.type == "v3f" then + local val = get_current_value(setting) + local v3f = {} + for line in val:gmatch("[+-]?[%d.+-eE]+") do -- All numeric characters + table.insert(v3f, line) + end + + height = height + 0.3 + formspec = formspec + .. "field[0.3," .. height .. ";3.3,1;te_x;" + .. fgettext("X") .. ";" -- X + .. core.formspec_escape(v3f[1] or "") .. "]" + .. "field[3.6," .. height .. ";3.3,1;te_y;" + .. fgettext("Y") .. ";" -- Y + .. core.formspec_escape(v3f[2] or "") .. "]" + .. "field[6.9," .. height .. ";3.3,1;te_z;" + .. fgettext("Z") .. ";" -- Z + .. core.formspec_escape(v3f[3] or "") .. "]" + height = height + 1.1 + + elseif setting.type == "flags" then + local current_flags = flags_to_table(get_current_value(setting)) + local flags = {} + for _, name in ipairs(current_flags) do + -- Index by name, to avoid iterating over all enabled_flags for every possible flag. + if name:sub(1, 2) == "no" then + flags[name:sub(3)] = false + else + flags[name] = true + end + end + local flags_count = #setting.possible / 2 + local max_height = math.ceil(flags_count / 2) / 2 + + -- More space for flags + description_height = description_height - 1 + height = height - 1 + + local fields = {} -- To build formspec + local j = 1 + for _, name in ipairs(setting.possible) do + if name:sub(1, 2) ~= "no" then + local x = 0.5 + local y = height + j / 2 - 0.75 + if j - 1 >= flags_count / 2 then -- 2nd column + x = 5 + y = y - max_height + end + j = j + 1; + local checkbox_name = "cb_" .. name + local is_enabled = flags[name] == true -- to get false if nil + checkboxes[checkbox_name] = is_enabled + + fields[#fields + 1] = ("checkbox[%f,%f;%s;%s;%s]"):format( + x, y, checkbox_name, name, tostring(is_enabled) + ) + end + end + formspec = table.concat(fields) + height = height + max_height + 0.25 + + else + -- TODO: fancy input for float, int + local text = get_current_value(setting) + if dialogdata.error_message and dialogdata.entered_text then + text = dialogdata.entered_text + end + formspec = "field[0.28," .. height + 0.15 .. ";" .. width .. ",1;te_setting_value;;" + .. core.formspec_escape(text) .. "]" + height = height + 1.15 + end + + -- Box good, textarea bad. Calculate textarea size from box. + local function create_textfield(size, label, text, bg_color) + local textarea = { + x = size.x + 0.3, + y = size.y, + w = size.w + 0.25, + h = size.h * 1.16 + 0.12 + } + return ("box[%f,%f;%f,%f;%s]textarea[%f,%f;%f,%f;;%s;%s]"):format( + size.x, size.y, size.w, size.h, bg_color or "#000", + textarea.x, textarea.y, textarea.w, textarea.h, + core.formspec_escape(label), core.formspec_escape(text) + ) + + end + + -- When there's an error: Shrink description textarea and add error below + if dialogdata.error_message then + local error_box = { + x = 0, + y = description_height - 0.4, + w = width - 0.25, + h = 0.5 + } + formspec = formspec .. + create_textfield(error_box, "", dialogdata.error_message, "#600") + description_height = description_height - 0.75 + end + + -- Get description field + local description_box = { + x = 0, + y = 0.2, + w = width - 0.25, + h = description_height + } + + local setting_name = setting.name + if setting.readable_name then + setting_name = fgettext_ne(setting.readable_name) .. + " (" .. setting.name .. ")" + end + + local comment_text + if setting.comment == "" then + comment_text = fgettext_ne("(No description of setting given)") + else + comment_text = fgettext_ne(setting.comment) + end + + return ( + "size[" .. width .. "," .. height + 0.25 .. ",true]" .. + create_textfield(description_box, setting_name, comment_text) .. + formspec .. + "button[" .. width / 2 - 2.5 .. "," .. height - 0.4 .. ";2.5,1;btn_done;" .. + fgettext("Save") .. "]" .. + "button[" .. width / 2 .. "," .. height - 0.4 .. ";2.5,1;btn_cancel;" .. + fgettext("Cancel") .. "]" + ) +end + +local function handle_change_setting_buttons(this, fields) + local setting = settings[selected_setting] + if fields["btn_done"] or fields["key_enter"] then + if setting.type == "bool" then + local new_value = fields["dd_setting_value"] + -- Note: new_value is the actual (translated) value shown in the dropdown + core.settings:set_bool(setting.name, new_value == fgettext("Enabled")) + + elseif setting.type == "enum" then + local new_value = fields["dd_setting_value"] + core.settings:set(setting.name, new_value) + + elseif setting.type == "int" then + local new_value = tonumber(fields["te_setting_value"]) + if not new_value or math.floor(new_value) ~= new_value then + this.data.error_message = fgettext_ne("Please enter a valid integer.") + this.data.entered_text = fields["te_setting_value"] + core.update_formspec(this:get_formspec()) + return true + end + if setting.min and new_value < setting.min then + this.data.error_message = fgettext_ne("The value must be at least $1.", setting.min) + this.data.entered_text = fields["te_setting_value"] + core.update_formspec(this:get_formspec()) + return true + end + if setting.max and new_value > setting.max then + this.data.error_message = fgettext_ne("The value must not be larger than $1.", setting.max) + this.data.entered_text = fields["te_setting_value"] + core.update_formspec(this:get_formspec()) + return true + end + core.settings:set(setting.name, new_value) + + elseif setting.type == "float" then + local new_value = tonumber(fields["te_setting_value"]) + if not new_value then + this.data.error_message = fgettext_ne("Please enter a valid number.") + this.data.entered_text = fields["te_setting_value"] + core.update_formspec(this:get_formspec()) + return true + end + if setting.min and new_value < setting.min then + this.data.error_message = fgettext_ne("The value must be at least $1.", setting.min) + this.data.entered_text = fields["te_setting_value"] + core.update_formspec(this:get_formspec()) + return true + end + if setting.max and new_value > setting.max then + this.data.error_message = fgettext_ne("The value must not be larger than $1.", setting.max) + this.data.entered_text = fields["te_setting_value"] + core.update_formspec(this:get_formspec()) + return true + end + core.settings:set(setting.name, new_value) + + elseif setting.type == "flags" then + local values = {} + for _, name in ipairs(setting.possible) do + if name:sub(1, 2) ~= "no" then + if checkboxes["cb_" .. name] then + table.insert(values, name) + else + table.insert(values, "no" .. name) + end + end + end + + checkboxes = {} + + local new_value = table.concat(values, ", ") + core.settings:set(setting.name, new_value) + + elseif setting.type == "noise_params_2d" or setting.type == "noise_params_3d" then + local np_flags = {} + for _, name in ipairs(setting.flags) do + if checkboxes["cb_" .. name] then + table.insert(np_flags, name) + end + end + + checkboxes = {} + + if setting.type == "noise_params_2d" then + fields["te_spready"] = fields["te_spreadz"] + end + local new_value = { + offset = fields["te_offset"], + scale = fields["te_scale"], + spread = { + x = fields["te_spreadx"], + y = fields["te_spready"], + z = fields["te_spreadz"] + }, + seed = fields["te_seed"], + octaves = fields["te_octaves"], + persistence = fields["te_persist"], + lacunarity = fields["te_lacun"], + flags = table.concat(np_flags, ", ") + } + core.settings:set_np_group(setting.name, new_value) + + elseif setting.type == "v3f" then + local new_value = "(" + .. fields["te_x"] .. ", " + .. fields["te_y"] .. ", " + .. fields["te_z"] .. ")" + core.settings:set(setting.name, new_value) + + else + local new_value = fields["te_setting_value"] + core.settings:set(setting.name, new_value) + end + core.settings:write() + this:delete() + return true + end + + if fields["btn_cancel"] then + this:delete() + return true + end + + if fields["btn_browser_path"] then + core.show_path_select_dialog("dlg_browse_path", + fgettext_ne("Select directory"), false) + end + + if fields["btn_browser_filepath"] then + core.show_path_select_dialog("dlg_browse_path", + fgettext_ne("Select file"), true) + end + + if fields["dlg_browse_path_accepted"] then + this.data.selected_path = fields["dlg_browse_path_accepted"] + core.update_formspec(this:get_formspec()) + end + + if setting.type == "flags" + or setting.type == "noise_params_2d" + or setting.type == "noise_params_3d" then + for name, value in pairs(fields) do + if name:sub(1, 3) == "cb_" then + checkboxes[name] = value == "true" + end + end + end + + return false +end + +local function create_settings_formspec(tabview, _, tabdata) + local formspec = "size[12,5.4;true]" .. + "tablecolumns[color;tree;text,width=28;text]" .. + "tableoptions[background=#00000000;border=false]" .. + "field[0.3,0.1;10.2,1;search_string;;" .. core.formspec_escape(search_string) .. "]" .. + "field_close_on_enter[search_string;false]" .. + "button[10.2,-0.2;2,1;search;" .. fgettext("Search") .. "]" .. + "table[0,0.8;12,3.5;list_settings;" + + local current_level = 0 + for _, entry in ipairs(settings) do + local name + if not core.settings:get_bool("show_technical_names") and entry.readable_name then + name = fgettext_ne(entry.readable_name) + else + name = entry.name + end + + if entry.type == "category" then + current_level = entry.level + formspec = formspec .. "#FFFF00," .. current_level .. "," .. fgettext(name) .. ",," + + elseif entry.type == "bool" then + local value = get_current_value(entry) + if core.is_yes(value) then + value = fgettext("Enabled") + else + value = fgettext("Disabled") + end + formspec = formspec .. "," .. (current_level + 1) .. "," .. core.formspec_escape(name) .. "," + .. value .. "," + + elseif entry.type == "key" then --luacheck: ignore + -- ignore key settings, since we have a special dialog for them + + elseif entry.type == "noise_params_2d" or entry.type == "noise_params_3d" then + formspec = formspec .. "," .. (current_level + 1) .. "," .. core.formspec_escape(name) .. "," + .. core.formspec_escape(get_current_np_group_as_string(entry)) .. "," + + else + formspec = formspec .. "," .. (current_level + 1) .. "," .. core.formspec_escape(name) .. "," + .. core.formspec_escape(get_current_value(entry)) .. "," + end + end + + if #settings > 0 then + formspec = formspec:sub(1, -2) -- remove trailing comma + end + formspec = formspec .. ";" .. selected_setting .. "]" .. + "button[0,4.9;4,1;btn_back;".. fgettext("< Back to Settings page") .. "]" .. + "button[10,4.9;2,1;btn_edit;" .. fgettext("Edit") .. "]" .. + "button[7,4.9;3,1;btn_restore;" .. fgettext("Restore Default") .. "]" .. + "checkbox[0,4.3;cb_tech_settings;" .. fgettext("Show technical names") .. ";" + .. dump(core.settings:get_bool("show_technical_names")) .. "]" + + return formspec +end + +local function handle_settings_buttons(this, fields, tabname, tabdata) + local list_enter = false + if fields["list_settings"] then + selected_setting = core.get_table_index("list_settings") + if core.explode_table_event(fields["list_settings"]).type == "DCL" then + -- Directly toggle booleans + local setting = settings[selected_setting] + if setting and setting.type == "bool" then + local current_value = get_current_value(setting) + core.settings:set_bool(setting.name, not core.is_yes(current_value)) + core.settings:write() + return true + else + list_enter = true + end + else + return true + end + end + + if fields.search or fields.key_enter_field == "search_string" then + if search_string == fields.search_string then + if selected_setting > 0 then + -- Go to next result on enter press + local i = selected_setting + 1 + local looped = false + while i > #settings or settings[i].type == "category" do + i = i + 1 + if i > #settings then + -- Stop infinte looping + if looped then + return false + end + i = 1 + looped = true + end + end + selected_setting = i + core.update_formspec(this:get_formspec()) + return true + end + else + -- Search for setting + search_string = fields.search_string + settings, selected_setting = filter_settings(full_settings, search_string) + core.update_formspec(this:get_formspec()) + end + return true + end + + if fields["btn_edit"] or list_enter then + local setting = settings[selected_setting] + if setting and setting.type ~= "category" then + local edit_dialog = dialog_create("change_setting", + create_change_setting_formspec, handle_change_setting_buttons) + edit_dialog:set_parent(this) + this:hide() + edit_dialog:show() + end + return true + end + + if fields["btn_restore"] then + local setting = settings[selected_setting] + if setting and setting.type ~= "category" then + core.settings:remove(setting.name) + core.settings:write() + core.update_formspec(this:get_formspec()) + end + return true + end + + if fields["btn_back"] then + this:delete() + return true + end + + if fields["cb_tech_settings"] then + core.settings:set("show_technical_names", fields["cb_tech_settings"]) + core.settings:write() + core.update_formspec(this:get_formspec()) + return true + end + + return false +end + +function create_adv_settings_dlg() + local dlg = dialog_create("settings_advanced", + create_settings_formspec, + handle_settings_buttons, + nil) + + return dlg +end + +-- Uncomment to generate 'minetest.conf.example' and 'settings_translation_file.cpp'. +-- For RUN_IN_PLACE the generated files may appear in the 'bin' folder. +-- See comment and alternative line at the end of 'generate_from_settingtypes.lua'. + +--assert(loadfile(core.get_builtin_path().."mainmenu"..DIR_DELIM.. +-- "generate_from_settingtypes.lua"))(parse_config_file(true, false)) diff --git a/builtin/mainmenu/dlg_version_info.lua b/builtin/mainmenu/dlg_version_info.lua new file mode 100644 index 0000000..568fca3 --- /dev/null +++ b/builtin/mainmenu/dlg_version_info.lua @@ -0,0 +1,172 @@ +--[[ +Minetest +Copyright (C) 2018-2020 SmallJoker, 2022 rubenwardy + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +]] + +if not core.get_http_api then + function check_new_version() + end + return +end + +local function version_info_formspec(data) + local cur_ver = core.get_version() + local title = fgettext("A new $1 version is available", cur_ver.project) + local message = + fgettext("Installed version: $1\nNew version: $2\n" .. + "Visit $3 to find out how to get the newest version and stay up to date" .. + " with features and bugfixes.", + cur_ver.string, data.new_version or "", data.url or "") + + local fs = { + "formspec_version[3]", + "size[12.8,7]", + "style_type[label;textcolor=#0E0]", + "label[0.5,0.8;", core.formspec_escape(title), "]", + "textarea[0.4,1.6;12,3.4;;;", + core.formspec_escape(message), "]", + "container[0.4,5.8]", + "button[0.0,0;4.0,0.8;version_check_visit;", fgettext("Visit website"), "]", + "button[4.5,0;3.5,0.8;version_check_remind;", fgettext("Later"), "]", + "button[8.5.5,0;3.5,0.8;version_check_never;", fgettext("Never"), "]", + "container_end[]", + } + + return table.concat(fs, "") +end + +local function version_info_buttonhandler(this, fields) + if fields.version_check_remind then + -- Erase last known, user will be reminded again at next check + core.settings:set("update_last_known", "") + this:delete() + return true + end + if fields.version_check_never then + core.settings:set("update_last_checked", "disabled") + this:delete() + return true + end + if fields.version_check_visit then + if type(this.data.url) == "string" then + core.open_url(this.data.url) + end + this:delete() + return true + end + + return false +end + +local function create_version_info_dlg(new_version, url) + assert(type(new_version) == "string") + assert(type(url) == "string") + + local retval = dialog_create("version_info", + version_info_formspec, + version_info_buttonhandler, + nil) + + retval.data.new_version = new_version + retval.data.url = url + + return retval +end + +local function get_current_version_code() + -- Format: Major.Minor.Patch + -- Convert to MMMNNNPPP + local cur_string = core.get_version().string + local cur_major, cur_minor, cur_patch = cur_string:match("^(%d+).(%d+).(%d+)") + + if not cur_patch then + core.log("error", "Failed to parse version numbers (invalid tag format?)") + return + end + + return (cur_major * 1000 + cur_minor) * 1000 + cur_patch +end + +local function on_version_info_received(json) + local maintab = ui.find_by_name("maintab") + if maintab.hidden then + -- Another dialog is open, abort. + return + end + + local known_update = tonumber(core.settings:get("update_last_known")) or 0 + + -- Format: MMNNPPP (Major, Minor, Patch) + local new_number = type(json.latest) == "table" and json.latest.version_code + if type(new_number) ~= "number" then + core.log("error", "Failed to read version number (invalid response?)") + return + end + + local cur_number = get_current_version_code() + if new_number <= known_update or new_number < cur_number then + return + end + + -- Also consider updating from 1.2.3-dev to 1.2.3 + if new_number == cur_number and not core.get_version().is_dev then + return + end + + core.settings:set("update_last_known", tostring(new_number)) + + -- Show version info dialog (once) + maintab:hide() + + local version_info_dlg = create_version_info_dlg(json.latest.version, json.latest.url) + version_info_dlg:set_parent(maintab) + version_info_dlg:show() + + ui.update() +end + +function check_new_version() + local url = core.settings:get("update_information_url") + if core.settings:get("update_last_checked") == "disabled" or + url == "" then + -- Never show any updates + return + end + + local time_now = os.time() + local time_checked = tonumber(core.settings:get("update_last_checked")) or 0 + if time_now - time_checked < 2 * 24 * 3600 then + -- Check interval of 2 entire days + return + end + + core.settings:set("update_last_checked", tostring(time_now)) + + core.handle_async(function(params) + local http = core.get_http_api() + return http.fetch_sync(params) + end, { url = url }, function(result) + local json = result.succeeded and core.parse_json(result.data) + if type(json) ~= "table" or not json.latest then + core.log("error", "Failed to read JSON output from " .. url .. + ", status code = " .. result.code) + return + end + + on_version_info_received(json) + end) +end diff --git a/builtin/mainmenu/game_theme.lua b/builtin/mainmenu/game_theme.lua new file mode 100644 index 0000000..89e1b66 --- /dev/null +++ b/builtin/mainmenu/game_theme.lua @@ -0,0 +1,203 @@ +--Minetest +--Copyright (C) 2013 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +mm_game_theme = {} + +-------------------------------------------------------------------------------- +function mm_game_theme.init() + mm_game_theme.defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" .. + DIR_DELIM .. "pack" .. DIR_DELIM + mm_game_theme.basetexturedir = mm_game_theme.defaulttexturedir + + mm_game_theme.texturepack = core.settings:get("texture_path") + + mm_game_theme.gameid = nil + + mm_game_theme.music_handle = nil +end + +-------------------------------------------------------------------------------- +function mm_game_theme.update(tab,gamedetails) + if tab ~= "singleplayer" then + mm_game_theme.reset() + return + end + + if gamedetails == nil then + return + end + + mm_game_theme.update_game(gamedetails) +end + +-------------------------------------------------------------------------------- +function mm_game_theme.reset() + mm_game_theme.gameid = nil + local have_bg = false + local have_overlay = mm_game_theme.set_generic("overlay") + + if not have_overlay then + have_bg = mm_game_theme.set_generic("background") + end + + mm_game_theme.clear("header") + mm_game_theme.clear("footer") + core.set_clouds(false) + + mm_game_theme.set_generic("footer") + mm_game_theme.set_generic("header") + + if not have_bg then + if core.settings:get_bool("menu_clouds") then + core.set_clouds(true) + else + mm_game_theme.set_dirt_bg() + end + end + + if mm_game_theme.music_handle ~= nil then + core.sound_stop(mm_game_theme.music_handle) + end +end + +-------------------------------------------------------------------------------- +function mm_game_theme.update_game(gamedetails) + if mm_game_theme.gameid == gamedetails.id then + return + end + + local have_bg = false + local have_overlay = mm_game_theme.set_game("overlay",gamedetails) + + if not have_overlay then + have_bg = mm_game_theme.set_game("background",gamedetails) + end + + mm_game_theme.clear("header") + mm_game_theme.clear("footer") + core.set_clouds(false) + + if not have_bg then + + if core.settings:get_bool("menu_clouds") then + core.set_clouds(true) + else + mm_game_theme.set_dirt_bg() + end + end + + mm_game_theme.set_game("footer",gamedetails) + mm_game_theme.set_game("header",gamedetails) + + mm_game_theme.gameid = gamedetails.id +end + +-------------------------------------------------------------------------------- +function mm_game_theme.clear(identifier) + core.set_background(identifier,"") +end + +-------------------------------------------------------------------------------- +function mm_game_theme.set_generic(identifier) + --try texture pack first + if mm_game_theme.texturepack ~= nil then + local path = mm_game_theme.texturepack .. DIR_DELIM .."menu_" .. + identifier .. ".png" + if core.set_background(identifier,path) then + return true + end + end + + if mm_game_theme.defaulttexturedir ~= nil then + local path = mm_game_theme.defaulttexturedir .. DIR_DELIM .."menu_" .. + identifier .. ".png" + if core.set_background(identifier,path) then + return true + end + end + + return false +end + +-------------------------------------------------------------------------------- +function mm_game_theme.set_game(identifier, gamedetails) + + if gamedetails == nil then + return false + end + + mm_game_theme.set_music(gamedetails) + + if mm_game_theme.texturepack ~= nil then + local path = mm_game_theme.texturepack .. DIR_DELIM .. + gamedetails.id .. "_menu_" .. identifier .. ".png" + if core.set_background(identifier, path) then + return true + end + end + + -- Find out how many randomized textures the game provides + local n = 0 + local filename + local menu_files = core.get_dir_list(gamedetails.path .. DIR_DELIM .. "menu", false) + for i = 1, #menu_files do + filename = identifier .. "." .. i .. ".png" + if table.indexof(menu_files, filename) == -1 then + n = i - 1 + break + end + end + -- Select random texture, 0 means standard texture + n = math.random(0, n) + if n == 0 then + filename = identifier .. ".png" + else + filename = identifier .. "." .. n .. ".png" + end + + local path = gamedetails.path .. DIR_DELIM .. "menu" .. + DIR_DELIM .. filename + if core.set_background(identifier, path) then + return true + end + + return false +end + +-------------------------------------------------------------------------------- +function mm_game_theme.set_dirt_bg() + if mm_game_theme.texturepack ~= nil then + local path = mm_game_theme.texturepack .. DIR_DELIM .."default_dirt.png" + if core.set_background("background", path, true, 128) then + return true + end + end + + -- Use universal fallback texture in textures/base/pack + local minimalpath = defaulttexturedir .. "menu_bg.png" + core.set_background("background", minimalpath, true, 128) +end + +-------------------------------------------------------------------------------- +function mm_game_theme.set_music(gamedetails) + if mm_game_theme.music_handle ~= nil then + core.sound_stop(mm_game_theme.music_handle) + end + local music_path = gamedetails.path .. DIR_DELIM .. "menu" .. DIR_DELIM .. "theme" + mm_game_theme.music_handle = core.sound_play(music_path, true) +end diff --git a/builtin/mainmenu/generate_from_settingtypes.lua b/builtin/mainmenu/generate_from_settingtypes.lua new file mode 100644 index 0000000..0f551fb --- /dev/null +++ b/builtin/mainmenu/generate_from_settingtypes.lua @@ -0,0 +1,136 @@ +local settings = ... + +local concat = table.concat +local insert = table.insert +local sprintf = string.format +local rep = string.rep + +local minetest_example_header = [[ +# This file contains a list of all available settings and their default value for minetest.conf + +# By default, all the settings are commented and not functional. +# Uncomment settings by removing the preceding #. + +# minetest.conf is read by default from: +# ../minetest.conf +# ../../minetest.conf +# Any other path can be chosen by passing the path as a parameter +# to the program, eg. "minetest.exe --config ../minetest.conf.example". + +# Further documentation: +# http://wiki.minetest.net/ + +]] + +local group_format_template = [[ +# %s = { +# offset = %s, +# scale = %s, +# spread = (%s, %s, %s), +# seed = %s, +# octaves = %s, +# persistence = %s, +# lacunarity = %s, +# flags =%s +# } + +]] + +local function create_minetest_conf_example() + local result = { minetest_example_header } + for _, entry in ipairs(settings) do + if entry.type == "category" then + if entry.level == 0 then + insert(result, "#\n# " .. entry.name .. "\n#\n\n") + else + insert(result, rep("#", entry.level)) + insert(result, "# " .. entry.name .. "\n\n") + end + else + local group_format = false + if entry.noise_params and entry.values then + if entry.type == "noise_params_2d" or entry.type == "noise_params_3d" then + group_format = true + end + end + if entry.comment ~= "" then + for _, comment_line in ipairs(entry.comment:split("\n", true)) do + if comment_line == "" then + insert(result, "#\n") + else + insert(result, "# " .. comment_line .. "\n") + end + end + end + insert(result, "# type: " .. entry.type) + if entry.min then + insert(result, " min: " .. entry.min) + end + if entry.max then + insert(result, " max: " .. entry.max) + end + if entry.values and entry.noise_params == nil then + insert(result, " values: " .. concat(entry.values, ", ")) + end + if entry.possible then + insert(result, " possible values: " .. concat(entry.possible, ", ")) + end + insert(result, "\n") + if group_format == true then + local flags = entry.values[10] + if flags ~= "" then + flags = " "..flags + end + insert(result, sprintf(group_format_template, entry.name, entry.values[1], + entry.values[2], entry.values[3], entry.values[4], entry.values[5], + entry.values[6], entry.values[7], entry.values[8], entry.values[9], + flags)) + else + local append + if entry.default ~= "" then + append = " " .. entry.default + end + insert(result, sprintf("# %s =%s\n\n", entry.name, append or "")) + end + end + end + return concat(result) +end + +local translation_file_header = [[ +// This file is automatically generated +// It contains a bunch of fake gettext calls, to tell xgettext about the strings in config files +// To update it, refer to the bottom of builtin/mainmenu/dlg_settings_advanced.lua + +fake_function() {]] + +local function create_translation_file() + local result = { translation_file_header } + for _, entry in ipairs(settings) do + if entry.type == "category" then + insert(result, sprintf("\tgettext(%q);", entry.name)) + else + if entry.readable_name then + insert(result, sprintf("\tgettext(%q);", entry.readable_name)) + end + if entry.comment ~= "" then + local comment_escaped = entry.comment:gsub("\n", "\\n") + comment_escaped = comment_escaped:gsub("\"", "\\\"") + insert(result, "\tgettext(\"" .. comment_escaped .. "\");") + end + end + end + insert(result, "}\n") + return concat(result, "\n") +end + +local file = assert(io.open("minetest.conf.example", "w")) +file:write(create_minetest_conf_example()) +file:close() + +file = assert(io.open("src/settings_translation_file.cpp", "w")) +-- If 'minetest.conf.example' appears in the 'bin' folder, the line below may have to be +-- used instead. The file will also appear in the 'bin' folder. +--file = assert(io.open("settings_translation_file.cpp", "w")) +file:write(create_translation_file()) +file:close() diff --git a/builtin/mainmenu/init.lua b/builtin/mainmenu/init.lua new file mode 100644 index 0000000..c3a28a5 --- /dev/null +++ b/builtin/mainmenu/init.lua @@ -0,0 +1,131 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +mt_color_grey = "#AAAAAA" +mt_color_blue = "#6389FF" +mt_color_lightblue = "#99CCFF" +mt_color_green = "#72FF63" +mt_color_dark_green = "#25C191" +mt_color_orange = "#FF8800" +mt_color_red = "#FF3300" + +local menupath = core.get_mainmenu_path() +local basepath = core.get_builtin_path() +defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" .. + DIR_DELIM .. "pack" .. DIR_DELIM + +dofile(basepath .. "common" .. DIR_DELIM .. "filterlist.lua") +dofile(basepath .. "fstk" .. DIR_DELIM .. "buttonbar.lua") +dofile(basepath .. "fstk" .. DIR_DELIM .. "dialog.lua") +dofile(basepath .. "fstk" .. DIR_DELIM .. "tabview.lua") +dofile(basepath .. "fstk" .. DIR_DELIM .. "ui.lua") +dofile(menupath .. DIR_DELIM .. "async_event.lua") +dofile(menupath .. DIR_DELIM .. "common.lua") +dofile(menupath .. DIR_DELIM .. "pkgmgr.lua") +dofile(menupath .. DIR_DELIM .. "serverlistmgr.lua") +dofile(menupath .. DIR_DELIM .. "game_theme.lua") + +dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua") +dofile(menupath .. DIR_DELIM .. "dlg_settings_advanced.lua") +dofile(menupath .. DIR_DELIM .. "dlg_contentstore.lua") +dofile(menupath .. DIR_DELIM .. "dlg_create_world.lua") +dofile(menupath .. DIR_DELIM .. "dlg_delete_content.lua") +dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua") +dofile(menupath .. DIR_DELIM .. "dlg_register.lua") +dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua") +dofile(menupath .. DIR_DELIM .. "dlg_version_info.lua") + +local tabs = {} + +tabs.settings = dofile(menupath .. DIR_DELIM .. "tab_settings.lua") +tabs.content = dofile(menupath .. DIR_DELIM .. "tab_content.lua") +tabs.about = dofile(menupath .. DIR_DELIM .. "tab_about.lua") +tabs.local_game = dofile(menupath .. DIR_DELIM .. "tab_local.lua") +tabs.play_online = dofile(menupath .. DIR_DELIM .. "tab_online.lua") + +-------------------------------------------------------------------------------- +local function main_event_handler(tabview, event) + if event == "MenuQuit" then + core.close() + end + return true +end + +-------------------------------------------------------------------------------- +local function init_globals() + -- Init gamedata + gamedata.worldindex = 0 + + menudata.worldlist = filterlist.create( + core.get_worlds, + compare_worlds, + -- Unique id comparison function + function(element, uid) + return element.name == uid + end, + -- Filter function + function(element, gameid) + return element.gameid == gameid + end + ) + + menudata.worldlist:add_sort_mechanism("alphabetic", sort_worlds_alphabetic) + menudata.worldlist:set_sortmode("alphabetic") + + if not core.settings:get("menu_last_game") then + local default_game = core.settings:get("default_game") or "minetest" + core.settings:set("menu_last_game", default_game) + end + + mm_game_theme.init() + + -- Create main tabview + local tv_main = tabview_create("maintab", {x = 12, y = 5.4}, {x = 0, y = 0}) + -- note: size would be 15.5,7.1 in real coordinates mode + + tv_main:set_autosave_tab(true) + tv_main:add(tabs.local_game) + tv_main:add(tabs.play_online) + + tv_main:add(tabs.content) + tv_main:add(tabs.settings) + tv_main:add(tabs.about) + + tv_main:set_global_event_handler(main_event_handler) + tv_main:set_fixed_size(false) + + local last_tab = core.settings:get("maintab_LAST") + if last_tab and tv_main.current_tab ~= last_tab then + tv_main:set_tab(last_tab) + end + + -- In case the folder of the last selected game has been deleted, + -- display "Minetest" as a header + if tv_main.current_tab == "local" then + local game = pkgmgr.find_by_gameid(core.settings:get("menu_last_game")) + if game == nil then + mm_game_theme.reset() + end + end + + ui.set_default("maintab") + check_new_version() + tv_main:show() + ui.update() +end + +init_globals() diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua new file mode 100644 index 0000000..853509b --- /dev/null +++ b/builtin/mainmenu/pkgmgr.lua @@ -0,0 +1,929 @@ +--Minetest +--Copyright (C) 2013 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-------------------------------------------------------------------------------- +local function get_last_folder(text,count) + local parts = text:split(DIR_DELIM) + + if count == nil then + return parts[#parts] + end + + local retval = "" + for i=1,count,1 do + retval = retval .. parts[#parts - (count-i)] .. DIR_DELIM + end + + return retval +end + +local function cleanup_path(temppath) + + local parts = temppath:split("-") + temppath = "" + for i=1,#parts,1 do + if temppath ~= "" then + temppath = temppath .. "_" + end + temppath = temppath .. parts[i] + end + + parts = temppath:split(".") + temppath = "" + for i=1,#parts,1 do + if temppath ~= "" then + temppath = temppath .. "_" + end + temppath = temppath .. parts[i] + end + + parts = temppath:split("'") + temppath = "" + for i=1,#parts,1 do + if temppath ~= "" then + temppath = temppath .. "" + end + temppath = temppath .. parts[i] + end + + parts = temppath:split(" ") + temppath = "" + for i=1,#parts,1 do + if temppath ~= "" then + temppath = temppath + end + temppath = temppath .. parts[i] + end + + return temppath +end + +local function load_texture_packs(txtpath, retval) + local list = core.get_dir_list(txtpath, true) + local current_texture_path = core.settings:get("texture_path") + + for _, item in ipairs(list) do + if item ~= "base" then + local path = txtpath .. DIR_DELIM .. item .. DIR_DELIM + local conf = Settings(path .. "texture_pack.conf") + local enabled = path == current_texture_path + + local title = conf:get("title") or item + + -- list_* is only used if non-nil, else the regular versions are used. + retval[#retval + 1] = { + name = item, + title = title, + list_name = enabled and fgettext("$1 (Enabled)", item) or nil, + list_title = enabled and fgettext("$1 (Enabled)", title) or nil, + author = conf:get("author"), + release = tonumber(conf:get("release")) or 0, + type = "txp", + path = path, + enabled = enabled, + } + end + end +end + +function get_mods(path, virtual_path, retval, modpack) + local mods = core.get_dir_list(path, true) + + for _, name in ipairs(mods) do + if name:sub(1, 1) ~= "." then + local mod_path = path .. DIR_DELIM .. name + local mod_virtual_path = virtual_path .. "/" .. name + local toadd = { + dir_name = name, + parent_dir = path, + } + retval[#retval + 1] = toadd + + -- Get config file + local mod_conf + local modpack_conf = io.open(mod_path .. DIR_DELIM .. "modpack.conf") + if modpack_conf then + toadd.is_modpack = true + modpack_conf:close() + + mod_conf = Settings(mod_path .. DIR_DELIM .. "modpack.conf"):to_table() + if mod_conf.name then + name = mod_conf.name + toadd.is_name_explicit = true + end + else + mod_conf = Settings(mod_path .. DIR_DELIM .. "mod.conf"):to_table() + if mod_conf.name then + name = mod_conf.name + toadd.is_name_explicit = true + end + end + + -- Read from config + toadd.name = name + toadd.title = mod_conf.title + toadd.author = mod_conf.author + toadd.release = tonumber(mod_conf.release) or 0 + toadd.path = mod_path + toadd.virtual_path = mod_virtual_path + toadd.type = "mod" + + -- Check modpack.txt + -- Note: modpack.conf is already checked above + local modpackfile = io.open(mod_path .. DIR_DELIM .. "modpack.txt") + if modpackfile then + modpackfile:close() + toadd.is_modpack = true + end + + -- Deal with modpack contents + if modpack and modpack ~= "" then + toadd.modpack = modpack + elseif toadd.is_modpack then + toadd.type = "modpack" + toadd.is_modpack = true + get_mods(mod_path, mod_virtual_path, retval, name) + end + end + end +end + +--modmanager implementation +pkgmgr = {} + +function pkgmgr.get_texture_packs() + local txtpath = core.get_texturepath() + local txtpath_system = core.get_texturepath_share() + local retval = {} + + load_texture_packs(txtpath, retval) + -- on portable versions these two paths coincide. It avoids loading the path twice + if txtpath ~= txtpath_system then + load_texture_packs(txtpath_system, retval) + end + + table.sort(retval, function(a, b) + return a.name > b.name + end) + + return retval +end + +-------------------------------------------------------------------------------- +function pkgmgr.get_folder_type(path) + local testfile = io.open(path .. DIR_DELIM .. "init.lua","r") + if testfile ~= nil then + testfile:close() + return { type = "mod", path = path } + end + + testfile = io.open(path .. DIR_DELIM .. "modpack.conf","r") + if testfile ~= nil then + testfile:close() + return { type = "modpack", path = path } + end + + testfile = io.open(path .. DIR_DELIM .. "modpack.txt","r") + if testfile ~= nil then + testfile:close() + return { type = "modpack", path = path } + end + + testfile = io.open(path .. DIR_DELIM .. "game.conf","r") + if testfile ~= nil then + testfile:close() + return { type = "game", path = path } + end + + testfile = io.open(path .. DIR_DELIM .. "texture_pack.conf","r") + if testfile ~= nil then + testfile:close() + return { type = "txp", path = path } + end + + return nil +end + +------------------------------------------------------------------------------- +function pkgmgr.get_base_folder(temppath) + if temppath == nil then + return { type = "invalid", path = "" } + end + + local ret = pkgmgr.get_folder_type(temppath) + if ret then + return ret + end + + local subdirs = core.get_dir_list(temppath, true) + if #subdirs == 1 then + ret = pkgmgr.get_folder_type(temppath .. DIR_DELIM .. subdirs[1]) + if ret then + return ret + else + return { type = "invalid", path = temppath .. DIR_DELIM .. subdirs[1] } + end + end + + return nil +end + +-------------------------------------------------------------------------------- +function pkgmgr.isValidModname(modpath) + if modpath:find("-") ~= nil then + return false + end + + return true +end + +-------------------------------------------------------------------------------- +function pkgmgr.parse_register_line(line) + local pos1 = line:find("\"") + local pos2 = nil + if pos1 ~= nil then + pos2 = line:find("\"",pos1+1) + end + + if pos1 ~= nil and pos2 ~= nil then + local item = line:sub(pos1+1,pos2-1) + + if item ~= nil and + item ~= "" then + local pos3 = item:find(":") + + if pos3 ~= nil then + local retval = item:sub(1,pos3-1) + if retval ~= nil and + retval ~= "" then + return retval + end + end + end + end + return nil +end + +-------------------------------------------------------------------------------- +function pkgmgr.parse_dofile_line(modpath,line) + local pos1 = line:find("\"") + local pos2 = nil + if pos1 ~= nil then + pos2 = line:find("\"",pos1+1) + end + + if pos1 ~= nil and pos2 ~= nil then + local filename = line:sub(pos1+1,pos2-1) + + if filename ~= nil and + filename ~= "" and + filename:find(".lua") then + return pkgmgr.identify_modname(modpath,filename) + end + end + return nil +end + +-------------------------------------------------------------------------------- +function pkgmgr.identify_modname(modpath,filename) + local testfile = io.open(modpath .. DIR_DELIM .. filename,"r") + if testfile ~= nil then + local line = testfile:read() + + while line~= nil do + local modname = nil + + if line:find("minetest.register_tool") then + modname = pkgmgr.parse_register_line(line) + end + + if line:find("minetest.register_craftitem") then + modname = pkgmgr.parse_register_line(line) + end + + + if line:find("minetest.register_node") then + modname = pkgmgr.parse_register_line(line) + end + + if line:find("dofile") then + modname = pkgmgr.parse_dofile_line(modpath,line) + end + + if modname ~= nil then + testfile:close() + return modname + end + + line = testfile:read() + end + testfile:close() + end + + return nil +end +-------------------------------------------------------------------------------- +function pkgmgr.render_packagelist(render_list, use_technical_names, with_error) + if not render_list then + if not pkgmgr.global_mods then + pkgmgr.refresh_globals() + end + render_list = pkgmgr.global_mods + end + + local list = render_list:get_list() + local retval = {} + for i, v in ipairs(list) do + local color = "" + local icon = 0 + local error = with_error and with_error[v.virtual_path] + local function update_error(val) + if val and (not error or (error.type == "warning" and val.type == "error")) then + error = val + end + end + + if v.is_modpack then + local rawlist = render_list:get_raw_list() + color = mt_color_dark_green + + for j = 1, #rawlist do + if rawlist[j].modpack == list[i].name then + if with_error then + update_error(with_error[rawlist[j].virtual_path]) + end + + if rawlist[j].enabled then + icon = 1 + else + -- Modpack not entirely enabled so showing as grey + color = mt_color_grey + end + end + end + elseif v.is_game_content or v.type == "game" then + icon = 1 + color = mt_color_blue + + local rawlist = render_list:get_raw_list() + if v.type == "game" and with_error then + for j = 1, #rawlist do + if rawlist[j].is_game_content then + update_error(with_error[rawlist[j].virtual_path]) + end + end + end + elseif v.enabled or v.type == "txp" then + icon = 1 + color = mt_color_green + end + + if error then + if error.type == "warning" then + color = mt_color_orange + icon = 2 + else + color = mt_color_red + icon = 3 + end + end + + retval[#retval + 1] = color + if v.modpack ~= nil or v.loc == "game" then + retval[#retval + 1] = "1" + else + retval[#retval + 1] = "0" + end + + if with_error then + retval[#retval + 1] = icon + end + + if use_technical_names then + retval[#retval + 1] = core.formspec_escape(v.list_name or v.name) + else + retval[#retval + 1] = core.formspec_escape(v.list_title or v.list_name or v.title or v.name) + end + end + + return table.concat(retval, ",") +end + +-------------------------------------------------------------------------------- +function pkgmgr.get_dependencies(path) + if path == nil then + return {}, {} + end + + local info = core.get_content_info(path) + return info.depends or {}, info.optional_depends or {} +end + +----------- tests whether all of the mods in the modpack are enabled ----------- +function pkgmgr.is_modpack_entirely_enabled(data, name) + local rawlist = data.list:get_raw_list() + for j = 1, #rawlist do + if rawlist[j].modpack == name and not rawlist[j].enabled then + return false + end + end + return true +end + +local function disable_all_by_name(list, name, except) + for i=1, #list do + if list[i].name == name and list[i] ~= except then + list[i].enabled = false + end + end +end + +---------- toggles or en/disables a mod or modpack and its dependencies -------- +local function toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mod) + if not mod.is_modpack then + -- Toggle or en/disable the mod + if toset == nil then + toset = not mod.enabled + end + if mod.enabled ~= toset then + toggled_mods[#toggled_mods+1] = mod.name + end + if toset then + -- Mark this mod for recursive dependency traversal + enabled_mods[mod.name] = true + + -- Disable other mods with the same name + disable_all_by_name(list, mod.name, mod) + end + mod.enabled = toset + else + -- Toggle or en/disable every mod in the modpack, + -- interleaved unsupported + for i = 1, #list do + if list[i].modpack == mod.name then + toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, list[i]) + end + end + end +end + +function pkgmgr.enable_mod(this, toset) + local list = this.data.list:get_list() + local mod = list[this.data.selected_mod] + + -- Game mods can't be enabled or disabled + if mod.is_game_content then + return + end + + local toggled_mods = {} + local enabled_mods = {} + toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mod) + + if next(enabled_mods) == nil then + -- Mod(s) were disabled, so no dependencies need to be enabled + table.sort(toggled_mods) + core.log("info", "Following mods were disabled: " .. + table.concat(toggled_mods, ", ")) + return + end + + -- Enable mods' depends after activation + + -- Make a list of mod ids indexed by their names. Among mods with the + -- same name, enabled mods take precedence, after which game mods take + -- precedence, being last in the mod list. + local mod_ids = {} + for id, mod2 in pairs(list) do + if mod2.type == "mod" and not mod2.is_modpack then + local prev_id = mod_ids[mod2.name] + if not prev_id or not list[prev_id].enabled then + mod_ids[mod2.name] = id + end + end + end + + -- to_enable is used as a DFS stack with sp as stack pointer + local to_enable = {} + local sp = 0 + for name in pairs(enabled_mods) do + local depends = pkgmgr.get_dependencies(list[mod_ids[name]].path) + for i = 1, #depends do + local dependency_name = depends[i] + if not enabled_mods[dependency_name] then + sp = sp+1 + to_enable[sp] = dependency_name + end + end + end + + -- If sp is 0, every dependency is already activated + while sp > 0 do + local name = to_enable[sp] + sp = sp-1 + + if not enabled_mods[name] then + enabled_mods[name] = true + local mod_to_enable = list[mod_ids[name]] + if not mod_to_enable then + core.log("warning", "Mod dependency \"" .. name .. + "\" not found!") + elseif not mod_to_enable.is_game_content then + if not mod_to_enable.enabled then + mod_to_enable.enabled = true + toggled_mods[#toggled_mods+1] = mod_to_enable.name + end + -- Push the dependencies of the dependency onto the stack + local depends = pkgmgr.get_dependencies(mod_to_enable.path) + for i = 1, #depends do + if not enabled_mods[depends[i]] then + sp = sp+1 + to_enable[sp] = depends[i] + end + end + end + end + end + + -- Log the list of enabled mods + table.sort(toggled_mods) + core.log("info", "Following mods were enabled: " .. + table.concat(toggled_mods, ", ")) +end + +-------------------------------------------------------------------------------- +function pkgmgr.get_worldconfig(worldpath) + local filename = worldpath .. + DIR_DELIM .. "world.mt" + + local worldfile = Settings(filename) + + local worldconfig = {} + worldconfig.global_mods = {} + worldconfig.game_mods = {} + + for key,value in pairs(worldfile:to_table()) do + if key == "gameid" then + worldconfig.id = value + elseif key:sub(0, 9) == "load_mod_" then + -- Compatibility: Check against "nil" which was erroneously used + -- as value for fresh configured worlds + worldconfig.global_mods[key] = value ~= "false" and value ~= "nil" + and value + else + worldconfig[key] = value + end + end + + --read gamemods + local gamespec = pkgmgr.find_by_gameid(worldconfig.id) + pkgmgr.get_game_mods(gamespec, worldconfig.game_mods) + + return worldconfig +end + +-------------------------------------------------------------------------------- +function pkgmgr.install_dir(type, path, basename, targetpath) + local basefolder = pkgmgr.get_base_folder(path) + + -- There's no good way to detect a texture pack, so let's just assume + -- it's correct for now. + if type == "txp" then + if basefolder and basefolder.type ~= "invalid" and basefolder.type ~= "txp" then + return nil, fgettext("Unable to install a $1 as a texture pack", basefolder.type) + end + + local from = basefolder and basefolder.path or path + if not targetpath then + targetpath = core.get_texturepath() .. DIR_DELIM .. basename + end + core.delete_dir(targetpath) + if not core.copy_dir(from, targetpath, false) then + return nil, + fgettext("Failed to install $1 to $2", basename, targetpath) + end + return targetpath, nil + + elseif not basefolder then + return nil, fgettext("Unable to find a valid mod or modpack") + end + + -- + -- Get destination + -- + if basefolder.type == "modpack" then + if type ~= "mod" then + return nil, fgettext("Unable to install a modpack as a $1", type) + end + + -- Get destination name for modpack + if targetpath then + core.delete_dir(targetpath) + else + local clean_path = nil + if basename ~= nil then + clean_path = basename + end + if not clean_path then + clean_path = get_last_folder(cleanup_path(basefolder.path)) + end + if clean_path then + targetpath = core.get_modpath() .. DIR_DELIM .. clean_path + else + return nil, + fgettext("Install Mod: Unable to find suitable folder name for modpack $1", + path) + end + end + elseif basefolder.type == "mod" then + if type ~= "mod" then + return nil, fgettext("Unable to install a mod as a $1", type) + end + + if targetpath then + core.delete_dir(targetpath) + else + local targetfolder = basename + if targetfolder == nil then + targetfolder = pkgmgr.identify_modname(basefolder.path, "init.lua") + end + + -- If heuristic failed try to use current foldername + if targetfolder == nil then + targetfolder = get_last_folder(basefolder.path) + end + + if targetfolder ~= nil and pkgmgr.isValidModname(targetfolder) then + targetpath = core.get_modpath() .. DIR_DELIM .. targetfolder + else + return nil, fgettext("Install Mod: Unable to find real mod name for: $1", path) + end + end + + elseif basefolder.type == "game" then + if type ~= "game" then + return nil, fgettext("Unable to install a game as a $1", type) + end + + if targetpath then + core.delete_dir(targetpath) + else + targetpath = core.get_gamepath() .. DIR_DELIM .. basename + end + else + error("basefolder didn't return a recognised type, this shouldn't happen") + end + + -- Copy it + core.delete_dir(targetpath) + if not core.copy_dir(basefolder.path, targetpath, false) then + return nil, + fgettext("Failed to install $1 to $2", basename, targetpath) + end + + if basefolder.type == "game" then + pkgmgr.update_gamelist() + else + pkgmgr.refresh_globals() + end + + return targetpath, nil +end + +-------------------------------------------------------------------------------- +function pkgmgr.preparemodlist(data) + local retval = {} + + local global_mods = {} + local game_mods = {} + + --read global mods + local modpaths = core.get_modpaths() + for key, modpath in pairs(modpaths) do + get_mods(modpath, key, global_mods) + end + + for i=1,#global_mods,1 do + global_mods[i].type = "mod" + global_mods[i].loc = "global" + global_mods[i].enabled = false + retval[#retval + 1] = global_mods[i] + end + + --read game mods + local gamespec = pkgmgr.find_by_gameid(data.gameid) + pkgmgr.get_game_mods(gamespec, game_mods) + + if #game_mods > 0 then + -- Add title + retval[#retval + 1] = { + type = "game", + is_game_content = true, + name = fgettext("$1 mods", gamespec.title), + path = gamespec.path + } + end + + for i=1,#game_mods,1 do + game_mods[i].type = "mod" + game_mods[i].loc = "game" + game_mods[i].is_game_content = true + retval[#retval + 1] = game_mods[i] + end + + if data.worldpath == nil then + return retval + end + + --read world mod configuration + local filename = data.worldpath .. + DIR_DELIM .. "world.mt" + + local worldfile = Settings(filename) + for key, value in pairs(worldfile:to_table()) do + if key:sub(1, 9) == "load_mod_" then + key = key:sub(10) + local mod_found = false + + local fallback_found = false + local fallback_mod = nil + + for i=1, #retval do + if retval[i].name == key and + not retval[i].is_modpack then + if core.is_yes(value) or retval[i].virtual_path == value then + retval[i].enabled = true + mod_found = true + break + elseif fallback_found then + -- Only allow fallback if only one mod matches + fallback_mod = nil + else + fallback_found = true + fallback_mod = retval[i] + end + end + end + + if not mod_found then + if fallback_mod and value:find("/") then + fallback_mod.enabled = true + else + core.log("info", "Mod: " .. key .. " " .. dump(value) .. " but not found") + end + end + end + end + + return retval +end + +function pkgmgr.compare_package(a, b) + return a and b and a.name == b.name and a.path == b.path +end + +-------------------------------------------------------------------------------- +function pkgmgr.comparemod(elem1,elem2) + if elem1 == nil or elem2 == nil then + return false + end + if elem1.name ~= elem2.name then + return false + end + if elem1.is_modpack ~= elem2.is_modpack then + return false + end + if elem1.type ~= elem2.type then + return false + end + if elem1.modpack ~= elem2.modpack then + return false + end + + if elem1.path ~= elem2.path then + return false + end + + return true +end + +-------------------------------------------------------------------------------- +function pkgmgr.mod_exists(basename) + + if pkgmgr.global_mods == nil then + pkgmgr.refresh_globals() + end + + if pkgmgr.global_mods:raw_index_by_uid(basename) > 0 then + return true + end + + return false +end + +-------------------------------------------------------------------------------- +function pkgmgr.get_global_mod(idx) + + if pkgmgr.global_mods == nil then + return nil + end + + if idx == nil or idx < 1 or + idx > pkgmgr.global_mods:size() then + return nil + end + + return pkgmgr.global_mods:get_list()[idx] +end + +-------------------------------------------------------------------------------- +function pkgmgr.refresh_globals() + local function is_equal(element,uid) --uid match + if element.name == uid then + return true + end + end + pkgmgr.global_mods = filterlist.create(pkgmgr.preparemodlist, + pkgmgr.comparemod, is_equal, nil, {}) + pkgmgr.global_mods:add_sort_mechanism("alphabetic", sort_mod_list) + pkgmgr.global_mods:set_sortmode("alphabetic") +end + +-------------------------------------------------------------------------------- +function pkgmgr.find_by_gameid(gameid) + for i=1,#pkgmgr.games,1 do + if pkgmgr.games[i].id == gameid then + return pkgmgr.games[i], i + end + end + return nil, nil +end + +-------------------------------------------------------------------------------- +function pkgmgr.get_game_mods(gamespec, retval) + if gamespec ~= nil and + gamespec.gamemods_path ~= nil and + gamespec.gamemods_path ~= "" then + get_mods(gamespec.gamemods_path, ("games/%s/mods"):format(gamespec.id), retval) + end +end + +-------------------------------------------------------------------------------- +function pkgmgr.get_game_modlist(gamespec) + local retval = "" + local game_mods = {} + pkgmgr.get_game_mods(gamespec, game_mods) + for i=1,#game_mods,1 do + if retval ~= "" then + retval = retval.."," + end + retval = retval .. game_mods[i].name + end + return retval +end + +-------------------------------------------------------------------------------- +function pkgmgr.get_game(index) + if index > 0 and index <= #pkgmgr.games then + return pkgmgr.games[index] + end + + return nil +end + +-------------------------------------------------------------------------------- +function pkgmgr.update_gamelist() + pkgmgr.games = core.get_games() +end + +-------------------------------------------------------------------------------- +function pkgmgr.gamelist() + local retval = "" + if #pkgmgr.games > 0 then + retval = retval .. core.formspec_escape(pkgmgr.games[1].title) + + for i=2,#pkgmgr.games,1 do + retval = retval .. "," .. core.formspec_escape(pkgmgr.games[i].title) + end + end + return retval +end + +-------------------------------------------------------------------------------- +-- read initial data +-------------------------------------------------------------------------------- +pkgmgr.update_gamelist() diff --git a/builtin/mainmenu/serverlistmgr.lua b/builtin/mainmenu/serverlistmgr.lua new file mode 100644 index 0000000..964d0c5 --- /dev/null +++ b/builtin/mainmenu/serverlistmgr.lua @@ -0,0 +1,252 @@ +--Minetest +--Copyright (C) 2020 rubenwardy +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +serverlistmgr = {} + +-------------------------------------------------------------------------------- +local function order_server_list(list) + local res = {} + --orders the favorite list after support + for i = 1, #list do + local fav = list[i] + if is_server_protocol_compat(fav.proto_min, fav.proto_max) then + res[#res + 1] = fav + end + end + for i = 1, #list do + local fav = list[i] + if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then + res[#res + 1] = fav + end + end + return res +end + +local public_downloading = false + +-------------------------------------------------------------------------------- +function serverlistmgr.sync() + if not serverlistmgr.servers then + serverlistmgr.servers = {{ + name = fgettext("Loading..."), + description = fgettext_ne("Try reenabling public serverlist and check your internet connection.") + }} + end + + local serverlist_url = core.settings:get("serverlist_url") or "" + if not core.get_http_api or serverlist_url == "" then + serverlistmgr.servers = {{ + name = fgettext("Public server list is disabled"), + description = "" + }} + return + end + + if public_downloading then + return + end + public_downloading = true + + core.handle_async( + function(param) + local http = core.get_http_api() + local url = ("%s/list?proto_version_min=%d&proto_version_max=%d"):format( + core.settings:get("serverlist_url"), + core.get_min_supp_proto(), + core.get_max_supp_proto()) + + local response = http.fetch_sync({ url = url }) + if not response.succeeded then + return {} + end + + local retval = core.parse_json(response.data) + return retval and retval.list or {} + end, + nil, + function(result) + public_downloading = nil + local favs = order_server_list(result) + if favs[1] then + serverlistmgr.servers = favs + end + core.event_handler("Refresh") + end + ) +end + +-------------------------------------------------------------------------------- +local function get_favorites_path(folder) + local base = core.get_user_path() .. DIR_DELIM .. "client" .. DIR_DELIM .. "serverlist" .. DIR_DELIM + if folder then + return base + end + return base .. core.settings:get("serverlist_file") +end + +-------------------------------------------------------------------------------- +local function save_favorites(favorites) + local filename = core.settings:get("serverlist_file") + -- If setting specifies legacy format change the filename to the new one + if filename:sub(#filename - 3):lower() == ".txt" then + core.settings:set("serverlist_file", filename:sub(1, #filename - 4) .. ".json") + end + + assert(core.create_dir(get_favorites_path(true))) + core.safe_file_write(get_favorites_path(), core.write_json(favorites)) +end + +-------------------------------------------------------------------------------- +function serverlistmgr.read_legacy_favorites(path) + local file = io.open(path, "r") + if not file then + return nil + end + + local lines = {} + for line in file:lines() do + lines[#lines + 1] = line + end + file:close() + + local favorites = {} + + local i = 1 + while i < #lines do + local function pop() + local line = lines[i] + i = i + 1 + return line and line:trim() + end + + if pop():lower() == "[server]" then + local name = pop() + local address = pop() + local port = tonumber(pop()) + local description = pop() + + if name == "" then + name = nil + end + + if description == "" then + description = nil + end + + if not address or #address < 3 then + core.log("warning", "Malformed favorites file, missing address at line " .. i) + elseif not port or port < 1 or port > 65535 then + core.log("warning", "Malformed favorites file, missing port at line " .. i) + elseif (name and name:upper() == "[SERVER]") or + (address and address:upper() == "[SERVER]") or + (description and description:upper() == "[SERVER]") then + core.log("warning", "Potentially malformed favorites file, overran at line " .. i) + else + favorites[#favorites + 1] = { + name = name, + address = address, + port = port, + description = description + } + end + end + end + + return favorites +end + +-------------------------------------------------------------------------------- +local function read_favorites() + local path = get_favorites_path() + + -- If new format configured fall back to reading the legacy file + if path:sub(#path - 4):lower() == ".json" then + local file = io.open(path, "r") + if file then + local json = file:read("*all") + file:close() + return core.parse_json(json) + end + + path = path:sub(1, #path - 5) .. ".txt" + end + + local favs = serverlistmgr.read_legacy_favorites(path) + if favs then + save_favorites(favs) + os.remove(path) + end + return favs +end + +-------------------------------------------------------------------------------- +local function delete_favorite(favorites, del_favorite) + for i=1, #favorites do + local fav = favorites[i] + + if fav.address == del_favorite.address and fav.port == del_favorite.port then + table.remove(favorites, i) + return + end + end +end + +-------------------------------------------------------------------------------- +function serverlistmgr.get_favorites() + if serverlistmgr.favorites then + return serverlistmgr.favorites + end + + serverlistmgr.favorites = {} + + -- Add favorites, removing duplicates + local seen = {} + for _, fav in ipairs(read_favorites() or {}) do + local key = ("%s:%d"):format(fav.address:lower(), fav.port) + if not seen[key] then + seen[key] = true + serverlistmgr.favorites[#serverlistmgr.favorites + 1] = fav + end + end + + return serverlistmgr.favorites +end + +-------------------------------------------------------------------------------- +function serverlistmgr.add_favorite(new_favorite) + assert(type(new_favorite.port) == "number") + + -- Whitelist favorite keys + new_favorite = { + name = new_favorite.name, + address = new_favorite.address, + port = new_favorite.port, + description = new_favorite.description, + } + + local favorites = serverlistmgr.get_favorites() + delete_favorite(favorites, new_favorite) + table.insert(favorites, 1, new_favorite) + save_favorites(favorites) +end + +-------------------------------------------------------------------------------- +function serverlistmgr.delete_favorite(del_favorite) + local favorites = serverlistmgr.get_favorites() + delete_favorite(favorites, del_favorite) + save_favorites(favorites) +end diff --git a/builtin/mainmenu/tab_about.lua b/builtin/mainmenu/tab_about.lua new file mode 100644 index 0000000..a84ebce --- /dev/null +++ b/builtin/mainmenu/tab_about.lua @@ -0,0 +1,195 @@ +--Minetest +--Copyright (C) 2013 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-- https://github.com/orgs/minetest/teams/engine/members + +local core_developers = { + "Perttu Ahola (celeron55) <celeron55@gmail.com> [Project founder]", + "sfan5 <sfan5@live.de>", + "ShadowNinja <shadowninja@minetest.net>", + "Nathanaëlle Courant (Nore/Ekdohibs) <nore@mesecons.net>", + "Loic Blot (nerzhul/nrz) <loic.blot@unix-experience.fr>", + "Andrew Ward (rubenwardy) <rw@rubenwardy.com>", + "Krock/SmallJoker <mk939@ymail.com>", + "Lars Hofhansl <larsh@apache.org>", + "v-rob <robinsonvincent89@gmail.com>", + "hecks", + "Hugues Ross <hugues.ross@gmail.com>", + "Dmitry Kostenko (x2048) <codeforsmile@gmail.com>", +} + +local core_team = { + "Zughy [Issue triager]", +} + +-- For updating active/previous contributors, see the script in ./util/gather_git_credits.py + +local active_contributors = { + "Wuzzy [Features, translations, devtest]", + "Lars Müller [Lua optimizations and fixes]", + "Jude Melton-Houghton [Optimizations, bugfixes]", + "paradust7 [Performance, fixes, Irrlicht refactoring]", + "Desour [Fixes]", + "ROllerozxa [Main menu]", + "savilli [Bugfixes]", + "Lexi Hale [Particlespawner animation]", + "Liso [Shadow Mapping]", + "JosiahWI [Fixes, build system]", + "numzero [Graphics and rendering]", + "HybridDog [Fixes]", + "NeroBurner [Joystick]", + "pecksin [Clickable web links]", + "Daroc Alden [Fixes]", + "Jean-Patrick Guerrero (kilbith) [Fixes]", +} + +local previous_core_developers = { + "BlockMen", + "Maciej Kasatkin (RealBadAngel) [RIP]", + "Lisa Milne (darkrose) <lisa@ltmnet.com>", + "proller", + "Ilya Zhuravlev (xyz) <xyz@minetest.net>", + "PilzAdam <pilzadam@minetest.net>", + "est31 <MTest31@outlook.com>", + "kahrl <kahrl@gmx.net>", + "Ryan Kwolek (kwolekr) <kwolekr@minetest.net>", + "sapier", + "Zeno", + "Auke Kok (sofar) <sofar@foo-projects.org>", + "Aaron Suen <warr1024@gmail.com>", + "paramat", + "Pierre-Yves Rollo <dev@pyrollo.com>", +} + +local previous_contributors = { + "Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net> [Minetest logo]", + "red-001 <red-001@outlook.ie>", + "Giuseppe Bilotta", + "ClobberXD", + "Dániel Juhász (juhdanad) <juhdanad@gmail.com>", + "MirceaKitsune <mirceakitsune@gmail.com>", + "MoNTE48", + "Constantin Wenger (SpeedProg)", + "Ciaran Gultnieks (CiaranG)", + "Paul Ouellette (pauloue)", + "stujones11", + "srifqi", + "Rogier <rogier777@gmail.com>", + "Gregory Currie (gregorycu)", + "JacobF", + "Jeija <jeija@mesecons.net>", +} + +local function prepare_credits(dest, source) + for _, s in ipairs(source) do + -- if there's text inside brackets make it gray-ish + s = s:gsub("%[.-%]", core.colorize("#aaa", "%1")) + dest[#dest+1] = s + end +end + +local function build_hacky_list(items, spacing) + spacing = spacing or 0.5 + local y = spacing / 2 + local ret = {} + for _, item in ipairs(items) do + if item ~= "" then + ret[#ret+1] = ("label[0,%f;%s]"):format(y, core.formspec_escape(item)) + end + y = y + spacing + end + return table.concat(ret, ""), y +end + +return { + name = "about", + caption = fgettext("About"), + cbf_formspec = function(tabview, name, tabdata) + local logofile = defaulttexturedir .. "logo.png" + local version = core.get_version() + + local credit_list = {} + table.insert_all(credit_list, { + core.colorize("#ff0", fgettext("Core Developers")) + }) + prepare_credits(credit_list, core_developers) + table.insert_all(credit_list, { + "", + core.colorize("#ff0", fgettext("Core Team")) + }) + prepare_credits(credit_list, core_team) + table.insert_all(credit_list, { + "", + core.colorize("#ff0", fgettext("Active Contributors")) + }) + prepare_credits(credit_list, active_contributors) + table.insert_all(credit_list, { + "", + core.colorize("#ff0", fgettext("Previous Core Developers")) + }) + prepare_credits(credit_list, previous_core_developers) + table.insert_all(credit_list, { + "", + core.colorize("#ff0", fgettext("Previous Contributors")) + }) + prepare_credits(credit_list, previous_contributors) + local credit_fs, scroll_height = build_hacky_list(credit_list) + -- account for the visible portion + scroll_height = math.max(0, scroll_height - 6.9) + + local fs = "image[1.5,0.6;2.5,2.5;" .. core.formspec_escape(logofile) .. "]" .. + "style[label_button;border=false]" .. + "button[0.1,3.4;5.3,0.5;label_button;" .. + core.formspec_escape(version.project .. " " .. version.string) .. "]" .. + "button[1.5,4.1;2.5,0.8;homepage;minetest.net]" .. + "scroll_container[5.5,0.1;9.5,6.9;scroll_credits;vertical;" .. + tostring(scroll_height / 1000) .. "]" .. credit_fs .. + "scroll_container_end[]".. + "scrollbar[15,0.1;0.4,6.9;vertical;scroll_credits;0]" + + -- Render information + fs = fs .. "style[label_button2;border=false]" .. + "button[0.1,6;5.3,1;label_button2;" .. + fgettext("Active renderer:") .. "\n" .. + core.formspec_escape(core.get_screen_info().render_info) .. "]" + + if PLATFORM == "Android" then + fs = fs .. "button[0.5,5.1;4.5,0.8;share_debug;" .. fgettext("Share debug log") .. "]" + else + fs = fs .. "tooltip[userdata;" .. + fgettext("Opens the directory that contains user-provided worlds, games, mods,\n" .. + "and texture packs in a file manager / explorer.") .. "]" + fs = fs .. "button[0.5,5.1;4.5,0.8;userdata;" .. fgettext("Open User Data Directory") .. "]" + end + + return fs, "size[15.5,7.1,false]real_coordinates[true]" + end, + cbf_button_handler = function(this, fields, name, tabdata) + if fields.homepage then + core.open_url("https://www.minetest.net") + end + + if fields.share_debug then + local path = core.get_user_path() .. DIR_DELIM .. "debug.txt" + core.share_file(path) + end + + if fields.userdata then + core.open_dir(core.get_user_path()) + end + end, +} diff --git a/builtin/mainmenu/tab_content.lua b/builtin/mainmenu/tab_content.lua new file mode 100644 index 0000000..5e14d19 --- /dev/null +++ b/builtin/mainmenu/tab_content.lua @@ -0,0 +1,237 @@ +--Minetest +--Copyright (C) 2014 sapier +--Copyright (C) 2018 rubenwardy <rw@rubenwardy.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; either version 2.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +local packages_raw +local packages + +-------------------------------------------------------------------------------- +local function get_formspec(tabview, name, tabdata) + if pkgmgr.global_mods == nil then + pkgmgr.refresh_globals() + end + if pkgmgr.games == nil then + pkgmgr.update_gamelist() + end + + if packages == nil then + packages_raw = {} + table.insert_all(packages_raw, pkgmgr.games) + table.insert_all(packages_raw, pkgmgr.get_texture_packs()) + table.insert_all(packages_raw, pkgmgr.global_mods:get_list()) + + local function get_data() + return packages_raw + end + + local function is_equal(element, uid) --uid match + return (element.type == "game" and element.id == uid) or + element.name == uid + end + + packages = filterlist.create(get_data, pkgmgr.compare_package, + is_equal, nil, {}) + end + + if tabdata.selected_pkg == nil then + tabdata.selected_pkg = 1 + end + + local use_technical_names = core.settings:get_bool("show_technical_names") + + + local retval = + "label[0.05,-0.25;".. fgettext("Installed Packages:") .. "]" .. + "tablecolumns[color;tree;text]" .. + "table[0,0.25;5.1,4.3;pkglist;" .. + pkgmgr.render_packagelist(packages, use_technical_names) .. + ";" .. tabdata.selected_pkg .. "]" .. + "button[0,4.85;5.25,0.5;btn_contentdb;".. fgettext("Browse online content") .. "]" + + + local selected_pkg + if filterlist.size(packages) >= tabdata.selected_pkg then + selected_pkg = packages:get_list()[tabdata.selected_pkg] + end + + if selected_pkg ~= nil then + --check for screenshot beeing available + local screenshotfilename = selected_pkg.path .. DIR_DELIM .. "screenshot.png" + local screenshotfile, error = io.open(screenshotfilename, "r") + + local modscreenshot + if error == nil then + screenshotfile:close() + modscreenshot = screenshotfilename + end + + if modscreenshot == nil then + modscreenshot = defaulttexturedir .. "no_screenshot.png" + end + + local info = core.get_content_info(selected_pkg.path) + local desc = fgettext("No package description available") + if info.description and info.description:trim() ~= "" then + desc = info.description + end + + local title_and_name + if selected_pkg.type == "game" then + title_and_name = selected_pkg.name + else + title_and_name = (selected_pkg.title or selected_pkg.name) .. "\n" .. + core.colorize("#BFBFBF", selected_pkg.name) + end + + retval = retval .. + "image[5.5,0;3,2;" .. core.formspec_escape(modscreenshot) .. "]" .. + "label[8.25,0.6;" .. core.formspec_escape(title_and_name) .. "]" .. + "box[5.5,2.2;6.15,2.35;#000]" + + if selected_pkg.type == "mod" then + if selected_pkg.is_modpack then + retval = retval .. + "button[8.65,4.65;3.25,1;btn_mod_mgr_rename_modpack;" .. + fgettext("Rename") .. "]" + else + --show dependencies + desc = desc .. "\n\n" + local toadd_hard = table.concat(info.depends or {}, "\n") + local toadd_soft = table.concat(info.optional_depends or {}, "\n") + if toadd_hard == "" and toadd_soft == "" then + desc = desc .. fgettext("No dependencies.") + else + if toadd_hard ~= "" then + desc = desc ..fgettext("Dependencies:") .. + "\n" .. toadd_hard + end + if toadd_soft ~= "" then + if toadd_hard ~= "" then + desc = desc .. "\n\n" + end + desc = desc .. fgettext("Optional dependencies:") .. + "\n" .. toadd_soft + end + end + end + + else + if selected_pkg.type == "txp" then + if selected_pkg.enabled then + retval = retval .. + "button[8.65,4.65;3.25,1;btn_mod_mgr_disable_txp;" .. + fgettext("Disable Texture Pack") .. "]" + else + retval = retval .. + "button[8.65,4.65;3.25,1;btn_mod_mgr_use_txp;" .. + fgettext("Use Texture Pack") .. "]" + end + end + end + + retval = retval .. "textarea[5.85,2.2;6.35,2.9;;" .. + fgettext("Information:") .. ";" .. desc .. "]" + + if core.may_modify_path(selected_pkg.path) then + retval = retval .. + "button[5.5,4.65;3.25,1;btn_mod_mgr_delete_mod;" .. + fgettext("Uninstall Package") .. "]" + end + end + return retval +end + +-------------------------------------------------------------------------------- +local function handle_doubleclick(pkg) + if pkg.type == "txp" then + if core.settings:get("texture_path") == pkg.path then + core.settings:set("texture_path", "") + else + core.settings:set("texture_path", pkg.path) + end + packages = nil + + mm_game_theme.init() + mm_game_theme.reset() + end +end + +-------------------------------------------------------------------------------- +local function handle_buttons(tabview, fields, tabname, tabdata) + if fields["pkglist"] ~= nil then + local event = core.explode_table_event(fields["pkglist"]) + tabdata.selected_pkg = event.row + if event.type == "DCL" then + handle_doubleclick(packages:get_list()[tabdata.selected_pkg]) + end + return true + end + + if fields["btn_contentdb"] ~= nil then + local dlg = create_store_dlg() + dlg:set_parent(tabview) + tabview:hide() + dlg:show() + packages = nil + return true + end + + if fields["btn_mod_mgr_rename_modpack"] ~= nil then + local mod = packages:get_list()[tabdata.selected_pkg] + local dlg_renamemp = create_rename_modpack_dlg(mod) + dlg_renamemp:set_parent(tabview) + tabview:hide() + dlg_renamemp:show() + packages = nil + return true + end + + if fields["btn_mod_mgr_delete_mod"] ~= nil then + local mod = packages:get_list()[tabdata.selected_pkg] + local dlg_delmod = create_delete_content_dlg(mod) + dlg_delmod:set_parent(tabview) + tabview:hide() + dlg_delmod:show() + packages = nil + return true + end + + if fields.btn_mod_mgr_use_txp or fields.btn_mod_mgr_disable_txp then + local txp_path = "" + if fields.btn_mod_mgr_use_txp then + txp_path = packages:get_list()[tabdata.selected_pkg].path + end + + core.settings:set("texture_path", txp_path) + packages = nil + + mm_game_theme.init() + mm_game_theme.reset() + return true + end + + return false +end + +-------------------------------------------------------------------------------- +return { + name = "content", + caption = fgettext("Content"), + cbf_formspec = get_formspec, + cbf_button_handler = handle_buttons, + on_change = pkgmgr.update_gamelist +} diff --git a/builtin/mainmenu/tab_local.lua b/builtin/mainmenu/tab_local.lua new file mode 100644 index 0000000..f8de10d --- /dev/null +++ b/builtin/mainmenu/tab_local.lua @@ -0,0 +1,393 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +local current_game, singleplayer_refresh_gamebar +local valid_disabled_settings = { + ["enable_damage"]=true, + ["creative_mode"]=true, + ["enable_server"]=true, +} + +-- Currently chosen game in gamebar for theming and filtering +function current_game() + local last_game_id = core.settings:get("menu_last_game") + local game = pkgmgr.find_by_gameid(last_game_id) + + return game +end + +-- Apply menu changes from given game +function apply_game(game) + core.set_topleft_text(game.name) + core.settings:set("menu_last_game", game.id) + menudata.worldlist:set_filtercriteria(game.id) + + mm_game_theme.update("singleplayer", game) -- this refreshes the formspec + + local index = filterlist.get_current_index(menudata.worldlist, + tonumber(core.settings:get("mainmenu_last_selected_world"))) + if not index or index < 1 then + local selected = core.get_textlist_index("sp_worlds") + if selected ~= nil and selected < #menudata.worldlist:get_list() then + index = selected + else + index = #menudata.worldlist:get_list() + end + end + menu_worldmt_legacy(index) +end + +function singleplayer_refresh_gamebar() + + local old_bar = ui.find_by_name("game_button_bar") + if old_bar ~= nil then + old_bar:delete() + end + + local function game_buttonbar_button_handler(fields) + if fields.game_open_cdb then + local maintab = ui.find_by_name("maintab") + local dlg = create_store_dlg("game") + dlg:set_parent(maintab) + maintab:hide() + dlg:show() + return true + end + + for _, game in ipairs(pkgmgr.games) do + if fields["game_btnbar_" .. game.id] then + apply_game(game) + return true + end + end + end + + local btnbar = buttonbar_create("game_button_bar", + game_buttonbar_button_handler, + {x=-0.3,y=5.9}, "horizontal", {x=12.4,y=1.15}) + + for _, game in ipairs(pkgmgr.games) do + local btn_name = "game_btnbar_" .. game.id + + local image = nil + local text = nil + local tooltip = core.formspec_escape(game.title) + + if (game.menuicon_path or "") ~= "" then + image = core.formspec_escape(game.menuicon_path) + else + local part1 = game.id:sub(1,5) + local part2 = game.id:sub(6,10) + local part3 = game.id:sub(11) + + text = part1 .. "\n" .. part2 + if part3 ~= "" then + text = text .. "\n" .. part3 + end + end + btnbar:add_button(btn_name, text, image, tooltip) + end + + local plus_image = core.formspec_escape(defaulttexturedir .. "plus.png") + btnbar:add_button("game_open_cdb", "", plus_image, fgettext("Install games from ContentDB")) +end + +local function get_disabled_settings(game) + if not game then + return {} + end + + local gameconfig = Settings(game.path .. "/game.conf") + local disabled_settings = {} + if gameconfig then + local disabled_settings_str = (gameconfig:get("disabled_settings") or ""):split() + for _, value in pairs(disabled_settings_str) do + local state = false + value = value:trim() + if string.sub(value, 1, 1) == "!" then + state = true + value = string.sub(value, 2) + end + if valid_disabled_settings[value] then + disabled_settings[value] = state + else + core.log("error", "Invalid disabled setting in game.conf: "..tostring(value)) + end + end + end + return disabled_settings +end + +local function get_formspec(tabview, name, tabdata) + local retval = "" + + local index = filterlist.get_current_index(menudata.worldlist, + tonumber(core.settings:get("mainmenu_last_selected_world"))) + local list = menudata.worldlist:get_list() + local world = list and index and list[index] + local game + if world then + game = pkgmgr.find_by_gameid(world.gameid) + else + game = current_game() + end + local disabled_settings = get_disabled_settings(game) + + local creative, damage, host = "", "", "" + + -- Y offsets for game settings checkboxes + local y = -0.2 + local yo = 0.45 + + if disabled_settings["creative_mode"] == nil then + creative = "checkbox[0,"..y..";cb_creative_mode;".. fgettext("Creative Mode") .. ";" .. + dump(core.settings:get_bool("creative_mode")) .. "]" + y = y + yo + end + if disabled_settings["enable_damage"] == nil then + damage = "checkbox[0,"..y..";cb_enable_damage;".. fgettext("Enable Damage") .. ";" .. + dump(core.settings:get_bool("enable_damage")) .. "]" + y = y + yo + end + if disabled_settings["enable_server"] == nil then + host = "checkbox[0,"..y..";cb_server;".. fgettext("Host Server") ..";" .. + dump(core.settings:get_bool("enable_server")) .. "]" + y = y + yo + end + + retval = retval .. + "button[3.9,3.8;2.8,1;world_delete;".. fgettext("Delete") .. "]" .. + "button[6.55,3.8;2.8,1;world_configure;".. fgettext("Select Mods") .. "]" .. + "button[9.2,3.8;2.8,1;world_create;".. fgettext("New") .. "]" .. + "label[3.9,-0.05;".. fgettext("Select World:") .. "]".. + creative .. + damage .. + host .. + "textlist[3.9,0.4;7.9,3.45;sp_worlds;" .. + menu_render_worldlist() .. + ";" .. index .. "]" + + if core.settings:get_bool("enable_server") and disabled_settings["enable_server"] == nil then + retval = retval .. + "button[7.9,4.75;4.1,1;play;".. fgettext("Host Game") .. "]" .. + "checkbox[0,"..y..";cb_server_announce;" .. fgettext("Announce Server") .. ";" .. + dump(core.settings:get_bool("server_announce")) .. "]" .. + "field[0.3,2.85;3.8,0.5;te_playername;" .. fgettext("Name") .. ";" .. + core.formspec_escape(core.settings:get("name")) .. "]" .. + "pwdfield[0.3,4.05;3.8,0.5;te_passwd;" .. fgettext("Password") .. "]" + + local bind_addr = core.settings:get("bind_address") + if bind_addr ~= nil and bind_addr ~= "" then + retval = retval .. + "field[0.3,5.25;2.5,0.5;te_serveraddr;" .. fgettext("Bind Address") .. ";" .. + core.formspec_escape(core.settings:get("bind_address")) .. "]" .. + "field[2.85,5.25;1.25,0.5;te_serverport;" .. fgettext("Port") .. ";" .. + core.formspec_escape(core.settings:get("port")) .. "]" + else + retval = retval .. + "field[0.3,5.25;3.8,0.5;te_serverport;" .. fgettext("Server Port") .. ";" .. + core.formspec_escape(core.settings:get("port")) .. "]" + end + else + retval = retval .. + "button[7.9,4.75;4.1,1;play;" .. fgettext("Play Game") .. "]" + end + + return retval +end + +local function main_button_handler(this, fields, name, tabdata) + + assert(name == "local") + + local world_doubleclick = false + + if fields["sp_worlds"] ~= nil then + local event = core.explode_textlist_event(fields["sp_worlds"]) + local selected = core.get_textlist_index("sp_worlds") + + menu_worldmt_legacy(selected) + + if event.type == "DCL" then + world_doubleclick = true + end + + if event.type == "CHG" and selected ~= nil then + core.settings:set("mainmenu_last_selected_world", + menudata.worldlist:get_raw_index(selected)) + return true + end + end + + if menu_handle_key_up_down(fields,"sp_worlds","mainmenu_last_selected_world") then + return true + end + + if fields["cb_creative_mode"] then + core.settings:set("creative_mode", fields["cb_creative_mode"]) + local selected = core.get_textlist_index("sp_worlds") + menu_worldmt(selected, "creative_mode", fields["cb_creative_mode"]) + + return true + end + + if fields["cb_enable_damage"] then + core.settings:set("enable_damage", fields["cb_enable_damage"]) + local selected = core.get_textlist_index("sp_worlds") + menu_worldmt(selected, "enable_damage", fields["cb_enable_damage"]) + + return true + end + + if fields["cb_server"] then + core.settings:set("enable_server", fields["cb_server"]) + + return true + end + + if fields["cb_server_announce"] then + core.settings:set("server_announce", fields["cb_server_announce"]) + local selected = core.get_textlist_index("srv_worlds") + menu_worldmt(selected, "server_announce", fields["cb_server_announce"]) + + return true + end + + if fields["play"] ~= nil or world_doubleclick or fields["key_enter"] then + local selected = core.get_textlist_index("sp_worlds") + gamedata.selected_world = menudata.worldlist:get_raw_index(selected) + + if selected == nil or gamedata.selected_world == 0 then + gamedata.errormessage = + fgettext("No world created or selected!") + return true + end + + -- Update last game + local world = menudata.worldlist:get_raw_element(gamedata.selected_world) + local game_obj + if world then + game_obj = pkgmgr.find_by_gameid(world.gameid) + core.settings:set("menu_last_game", game_obj.id) + end + + local disabled_settings = get_disabled_settings(game_obj) + for k, _ in pairs(valid_disabled_settings) do + local v = disabled_settings[k] + if v ~= nil then + if k == "enable_server" and v == true then + error("Setting 'enable_server' cannot be force-enabled! The game.conf needs to be fixed.") + end + core.settings:set_bool(k, disabled_settings[k]) + end + end + + if core.settings:get_bool("enable_server") then + gamedata.playername = fields["te_playername"] + gamedata.password = fields["te_passwd"] + gamedata.port = fields["te_serverport"] + gamedata.address = "" + + core.settings:set("port",gamedata.port) + if fields["te_serveraddr"] ~= nil then + core.settings:set("bind_address",fields["te_serveraddr"]) + end + else + gamedata.singleplayer = true + end + + core.start() + return true + end + + if fields["world_create"] ~= nil then + local create_world_dlg = create_create_world_dlg() + create_world_dlg:set_parent(this) + this:hide() + create_world_dlg:show() + mm_game_theme.update("singleplayer", current_game()) + return true + end + + if fields["world_delete"] ~= nil then + local selected = core.get_textlist_index("sp_worlds") + if selected ~= nil and + selected <= menudata.worldlist:size() then + local world = menudata.worldlist:get_list()[selected] + if world ~= nil and + world.name ~= nil and + world.name ~= "" then + local index = menudata.worldlist:get_raw_index(selected) + local delete_world_dlg = create_delete_world_dlg(world.name,index) + delete_world_dlg:set_parent(this) + this:hide() + delete_world_dlg:show() + mm_game_theme.update("singleplayer",current_game()) + end + end + + return true + end + + if fields["world_configure"] ~= nil then + local selected = core.get_textlist_index("sp_worlds") + if selected ~= nil then + local configdialog = + create_configure_world_dlg( + menudata.worldlist:get_raw_index(selected)) + + if (configdialog ~= nil) then + configdialog:set_parent(this) + this:hide() + configdialog:show() + mm_game_theme.update("singleplayer",current_game()) + end + end + + return true + end +end + +local function on_change(type, old_tab, new_tab) + if (type == "ENTER") then + local game = current_game() + if game then + apply_game(game) + end + + singleplayer_refresh_gamebar() + ui.find_by_name("game_button_bar"):show() + else + menudata.worldlist:set_filtercriteria(nil) + local gamebar = ui.find_by_name("game_button_bar") + if gamebar then + gamebar:hide() + end + core.set_topleft_text("") + mm_game_theme.update(new_tab,nil) + end +end + +-------------------------------------------------------------------------------- +return { + name = "local", + caption = fgettext("Start Game"), + cbf_formspec = get_formspec, + cbf_button_handler = main_button_handler, + on_change = on_change +} diff --git a/builtin/mainmenu/tab_online.lua b/builtin/mainmenu/tab_online.lua new file mode 100644 index 0000000..ad5f79e --- /dev/null +++ b/builtin/mainmenu/tab_online.lua @@ -0,0 +1,427 @@ +--Minetest +--Copyright (C) 2014 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +local function get_sorted_servers() + local servers = { + fav = {}, + public = {}, + incompatible = {} + } + + local favs = serverlistmgr.get_favorites() + local taken_favs = {} + local result = menudata.search_result or serverlistmgr.servers + for _, server in ipairs(result) do + server.is_favorite = false + for index, fav in ipairs(favs) do + if server.address == fav.address and server.port == fav.port then + taken_favs[index] = true + server.is_favorite = true + break + end + end + server.is_compatible = is_server_protocol_compat(server.proto_min, server.proto_max) + if server.is_favorite then + table.insert(servers.fav, server) + elseif server.is_compatible then + table.insert(servers.public, server) + else + table.insert(servers.incompatible, server) + end + end + + if not menudata.search_result then + for index, fav in ipairs(favs) do + if not taken_favs[index] then + table.insert(servers.fav, fav) + end + end + end + + return servers +end + +local function get_formspec(tabview, name, tabdata) + -- Update the cached supported proto info, + -- it may have changed after a change by the settings menu. + common_update_cached_supp_proto() + + if not tabdata.search_for then + tabdata.search_for = "" + end + + local retval = + -- Search + "field[0.25,0.25;7,0.75;te_search;;" .. core.formspec_escape(tabdata.search_for) .. "]" .. + "container[7.25,0.25]" .. + "image_button[0,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "search.png") .. ";btn_mp_search;]" .. + "image_button[0.75,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "clear.png") .. ";btn_mp_clear;]" .. + "image_button[1.5,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "refresh.png") .. ";btn_mp_refresh;]" .. + "tooltip[btn_mp_clear;" .. fgettext("Clear") .. "]" .. + "tooltip[btn_mp_search;" .. fgettext("Search") .. "]" .. + "tooltip[btn_mp_refresh;" .. fgettext("Refresh") .. "]" .. + "container_end[]" .. + + "container[9.75,0]" .. + "box[0,0;5.75,7;#666666]" .. + + -- Address / Port + "label[0.25,0.35;" .. fgettext("Address") .. "]" .. + "label[4.25,0.35;" .. fgettext("Port") .. "]" .. + "field[0.25,0.5;4,0.75;te_address;;" .. + core.formspec_escape(core.settings:get("address")) .. "]" .. + "field[4.25,0.5;1.25,0.75;te_port;;" .. + core.formspec_escape(core.settings:get("remote_port")) .. "]" .. + + -- Description Background + "label[0.25,1.6;" .. fgettext("Server Description") .. "]" .. + "box[0.25,1.85;5.25,2.7;#999999]".. + + -- Name / Password + "container[0,4.8]" .. + "label[0.25,0;" .. fgettext("Name") .. "]" .. + "label[2.875,0;" .. fgettext("Password") .. "]" .. + "field[0.25,0.2;2.625,0.75;te_name;;" .. core.formspec_escape(core.settings:get("name")) .. "]" .. + "pwdfield[2.875,0.2;2.625,0.75;te_pwd;]" .. + "container_end[]" .. + + -- Connect + "button[3,6;2.5,0.75;btn_mp_login;" .. fgettext("Login") .. "]" + + if core.settings:get_bool("enable_split_login_register") then + retval = retval .. "button[0.25,6;2.5,0.75;btn_mp_register;" .. fgettext("Register") .. "]" + end + + if tabdata.selected then + if gamedata.fav then + retval = retval .. "tooltip[btn_delete_favorite;" .. fgettext("Remove favorite") .. "]" + retval = retval .. "style[btn_delete_favorite;padding=6]" + retval = retval .. "image_button[5,1.3;0.5,0.5;" .. core.formspec_escape(defaulttexturedir .. + "server_favorite_delete.png") .. ";btn_delete_favorite;]" + end + if gamedata.serverdescription then + retval = retval .. "textarea[0.25,1.85;5.2,2.75;;;" .. + core.formspec_escape(gamedata.serverdescription) .. "]" + end + end + + retval = retval .. "container_end[]" + + -- Table + retval = retval .. "tablecolumns[" .. + "image,tooltip=" .. fgettext("Ping") .. "," .. + "0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," .. + "1=" .. core.formspec_escape(defaulttexturedir .. "server_ping_4.png") .. "," .. + "2=" .. core.formspec_escape(defaulttexturedir .. "server_ping_3.png") .. "," .. + "3=" .. core.formspec_escape(defaulttexturedir .. "server_ping_2.png") .. "," .. + "4=" .. core.formspec_escape(defaulttexturedir .. "server_ping_1.png") .. "," .. + "5=" .. core.formspec_escape(defaulttexturedir .. "server_favorite.png") .. "," .. + "6=" .. core.formspec_escape(defaulttexturedir .. "server_public.png") .. "," .. + "7=" .. core.formspec_escape(defaulttexturedir .. "server_incompatible.png") .. ";" .. + "color,span=1;" .. + "text,align=inline;".. + "color,span=1;" .. + "text,align=inline,width=4.25;" .. + "image,tooltip=" .. fgettext("Creative mode") .. "," .. + "0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," .. + "1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_creative.png") .. "," .. + "align=inline,padding=0.25,width=1.5;" .. + --~ PvP = Player versus Player + "image,tooltip=" .. fgettext("Damage / PvP") .. "," .. + "0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," .. + "1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_damage.png") .. "," .. + "2=" .. core.formspec_escape(defaulttexturedir .. "server_flags_pvp.png") .. "," .. + "align=inline,padding=0.25,width=1.5;" .. + "color,align=inline,span=1;" .. + "text,align=inline,padding=1]" .. + "table[0.25,1;9.25,5.75;servers;" + + local servers = get_sorted_servers() + + local dividers = { + fav = "5,#ffff00," .. fgettext("Favorites") .. ",,,0,0,,", + public = "6,#4bdd42," .. fgettext("Public Servers") .. ",,,0,0,,", + incompatible = "7,"..mt_color_grey.."," .. fgettext("Incompatible Servers") .. ",,,0,0,," + } + local order = {"fav", "public", "incompatible"} + + tabdata.lookup = {} -- maps row number to server + local rows = {} + for _, section in ipairs(order) do + local section_servers = servers[section] + if next(section_servers) ~= nil then + rows[#rows + 1] = dividers[section] + for _, server in ipairs(section_servers) do + tabdata.lookup[#rows + 1] = server + rows[#rows + 1] = render_serverlist_row(server) + end + end + end + + retval = retval .. table.concat(rows, ",") + + if tabdata.selected then + retval = retval .. ";" .. tabdata.selected .. "]" + else + retval = retval .. ";0]" + end + + return retval, "size[15.5,7,false]real_coordinates[true]" +end + +-------------------------------------------------------------------------------- + +local function search_server_list(input) + menudata.search_result = nil + if #serverlistmgr.servers < 2 then + return + end + + -- setup the keyword list + local keywords = {} + for word in input:gmatch("%S+") do + word = word:gsub("(%W)", "%%%1") + table.insert(keywords, word) + end + + if #keywords == 0 then + return + end + + menudata.search_result = {} + + -- Search the serverlist + local search_result = {} + for i = 1, #serverlistmgr.servers do + local server = serverlistmgr.servers[i] + local found = 0 + for k = 1, #keywords do + local keyword = keywords[k] + if server.name then + local sername = server.name:lower() + local _, count = sername:gsub(keyword, keyword) + found = found + count * 4 + end + + if server.description then + local desc = server.description:lower() + local _, count = desc:gsub(keyword, keyword) + found = found + count * 2 + end + end + if found > 0 then + local points = (#serverlistmgr.servers - i) / 5 + found + server.points = points + table.insert(search_result, server) + end + end + + if #search_result == 0 then + return + end + + table.sort(search_result, function(a, b) + return a.points > b.points + end) + menudata.search_result = search_result +end + +local function set_selected_server(tabdata, idx, server) + -- reset selection + if idx == nil or server == nil then + tabdata.selected = nil + + core.settings:set("address", "") + core.settings:set("remote_port", "30000") + return + end + + local address = server.address + local port = server.port + gamedata.serverdescription = server.description + + gamedata.fav = false + for _, fav in ipairs(serverlistmgr.get_favorites()) do + if address == fav.address and port == fav.port then + gamedata.fav = true + break + end + end + + if address and port then + core.settings:set("address", address) + core.settings:set("remote_port", port) + end + tabdata.selected = idx +end + +local function main_button_handler(tabview, fields, name, tabdata) + if fields.te_name then + gamedata.playername = fields.te_name + core.settings:set("name", fields.te_name) + end + + if fields.servers then + local event = core.explode_table_event(fields.servers) + local server = tabdata.lookup[event.row] + + if server then + if event.type == "DCL" then + if not is_server_protocol_compat_or_error( + server.proto_min, server.proto_max) then + return true + end + + gamedata.address = server.address + gamedata.port = server.port + gamedata.playername = fields.te_name + gamedata.selected_world = 0 + + if fields.te_pwd then + gamedata.password = fields.te_pwd + end + + gamedata.servername = server.name + gamedata.serverdescription = server.description + + if gamedata.address and gamedata.port then + core.settings:set("address", gamedata.address) + core.settings:set("remote_port", gamedata.port) + core.start() + end + return true + end + if event.type == "CHG" then + set_selected_server(tabdata, event.row, server) + return true + end + end + end + + if fields.btn_delete_favorite then + local idx = core.get_table_index("servers") + if not idx then return end + local server = tabdata.lookup[idx] + if not server then return end + + serverlistmgr.delete_favorite(server) + -- the server at [idx+1] will be at idx once list is refreshed + set_selected_server(tabdata, idx, tabdata.lookup[idx+1]) + return true + end + + if fields.btn_mp_clear then + tabdata.search_for = "" + menudata.search_result = nil + return true + end + + if fields.btn_mp_search or fields.key_enter_field == "te_search" then + tabdata.search_for = fields.te_search + search_server_list(fields.te_search:lower()) + if menudata.search_result then + -- first server in row 2 due to header + set_selected_server(tabdata, 2, menudata.search_result[1]) + end + + return true + end + + if fields.btn_mp_refresh then + serverlistmgr.sync() + return true + end + + if (fields.btn_mp_login or fields.key_enter) + and fields.te_address ~= "" and fields.te_port then + gamedata.playername = fields.te_name + gamedata.password = fields.te_pwd + gamedata.address = fields.te_address + gamedata.port = tonumber(fields.te_port) + + local enable_split_login_register = core.settings:get_bool("enable_split_login_register") + gamedata.allow_login_or_register = enable_split_login_register and "login" or "any" + gamedata.selected_world = 0 + + local idx = core.get_table_index("servers") + local server = idx and tabdata.lookup[idx] + + set_selected_server(tabdata) + + if server and server.address == gamedata.address and + server.port == gamedata.port then + + serverlistmgr.add_favorite(server) + + gamedata.servername = server.name + gamedata.serverdescription = server.description + + if not is_server_protocol_compat_or_error( + server.proto_min, server.proto_max) then + return true + end + else + gamedata.servername = "" + gamedata.serverdescription = "" + + serverlistmgr.add_favorite({ + address = gamedata.address, + port = gamedata.port, + }) + end + + core.settings:set("address", gamedata.address) + core.settings:set("remote_port", gamedata.port) + + core.start() + return true + end + + if fields.btn_mp_register and fields.te_address ~= "" and fields.te_port then + local idx = core.get_table_index("servers") + local server = idx and tabdata.lookup[idx] + if server and (server.address ~= fields.te_address or server.port ~= tonumber(fields.te_port)) then + server = nil + end + + if server and not is_server_protocol_compat_or_error( + server.proto_min, server.proto_max) then + return true + end + + local dlg = create_register_dialog(fields.te_address, tonumber(fields.te_port), server) + dlg:set_parent(tabview) + tabview:hide() + dlg:show() + return true + end + + return false +end + +local function on_change(type, old_tab, new_tab) + if type == "LEAVE" then return end + serverlistmgr.sync() +end + +return { + name = "online", + caption = fgettext("Join Game"), + cbf_formspec = get_formspec, + cbf_button_handler = main_button_handler, + on_change = on_change +} diff --git a/builtin/mainmenu/tab_settings.lua b/builtin/mainmenu/tab_settings.lua new file mode 100644 index 0000000..21c77aa --- /dev/null +++ b/builtin/mainmenu/tab_settings.lua @@ -0,0 +1,403 @@ +--Minetest +--Copyright (C) 2013 sapier +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-------------------------------------------------------------------------------- + +local labels = { + leaves = { + fgettext("Opaque Leaves"), + fgettext("Simple Leaves"), + fgettext("Fancy Leaves") + }, + node_highlighting = { + fgettext("Node Outlining"), + fgettext("Node Highlighting"), + fgettext("None") + }, + filters = { + fgettext("No Filter"), + fgettext("Bilinear Filter"), + fgettext("Trilinear Filter") + }, + mipmap = { + fgettext("No Mipmap"), + fgettext("Mipmap"), + fgettext("Mipmap + Aniso. Filter") + }, + antialiasing = { + fgettext("None"), + fgettext("2x"), + fgettext("4x"), + fgettext("8x") + }, + shadow_levels = { + fgettext("Disabled"), + fgettext("Very Low"), + fgettext("Low"), + fgettext("Medium"), + fgettext("High"), + fgettext("Very High") + } +} + +local dd_options = { + leaves = { + table.concat(labels.leaves, ","), + {"opaque", "simple", "fancy"} + }, + node_highlighting = { + table.concat(labels.node_highlighting, ","), + {"box", "halo", "none"} + }, + filters = { + table.concat(labels.filters, ","), + {"", "bilinear_filter", "trilinear_filter"} + }, + mipmap = { + table.concat(labels.mipmap, ","), + {"", "mip_map", "anisotropic_filter"} + }, + antialiasing = { + table.concat(labels.antialiasing, ","), + {"0", "2", "4", "8"} + }, + shadow_levels = { + table.concat(labels.shadow_levels, ","), + { "0", "1", "2", "3", "4", "5" } + } +} + +local getSettingIndex = { + Leaves = function() + local style = core.settings:get("leaves_style") + for idx, name in pairs(dd_options.leaves[2]) do + if style == name then return idx end + end + return 1 + end, + NodeHighlighting = function() + local style = core.settings:get("node_highlighting") + for idx, name in pairs(dd_options.node_highlighting[2]) do + if style == name then return idx end + end + return 1 + end, + Filter = function() + if core.settings:get(dd_options.filters[2][3]) == "true" then + return 3 + elseif core.settings:get(dd_options.filters[2][3]) == "false" and + core.settings:get(dd_options.filters[2][2]) == "true" then + return 2 + end + return 1 + end, + Mipmap = function() + if core.settings:get(dd_options.mipmap[2][3]) == "true" then + return 3 + elseif core.settings:get(dd_options.mipmap[2][3]) == "false" and + core.settings:get(dd_options.mipmap[2][2]) == "true" then + return 2 + end + return 1 + end, + Antialiasing = function() + local antialiasing_setting = core.settings:get("fsaa") + for i = 1, #dd_options.antialiasing[2] do + if antialiasing_setting == dd_options.antialiasing[2][i] then + return i + end + end + return 1 + end, + ShadowMapping = function() + local shadow_setting = core.settings:get("shadow_levels") + for i = 1, #dd_options.shadow_levels[2] do + if shadow_setting == dd_options.shadow_levels[2][i] then + return i + end + end + return 1 + end +} + +local function antialiasing_fname_to_name(fname) + for i = 1, #labels.antialiasing do + if fname == labels.antialiasing[i] then + return dd_options.antialiasing[2][i] + end + end + return 0 +end + +local function formspec(tabview, name, tabdata) + local tab_string = + "box[0,0;3.75,4.5;#999999]" .. + "checkbox[0.25,0;cb_smooth_lighting;" .. fgettext("Smooth Lighting") .. ";" + .. dump(core.settings:get_bool("smooth_lighting")) .. "]" .. + "checkbox[0.25,0.5;cb_particles;" .. fgettext("Particles") .. ";" + .. dump(core.settings:get_bool("enable_particles")) .. "]" .. + "checkbox[0.25,1;cb_3d_clouds;" .. fgettext("3D Clouds") .. ";" + .. dump(core.settings:get_bool("enable_3d_clouds")) .. "]" .. + "checkbox[0.25,1.5;cb_opaque_water;" .. fgettext("Opaque Water") .. ";" + .. dump(core.settings:get_bool("opaque_water")) .. "]" .. + "checkbox[0.25,2.0;cb_connected_glass;" .. fgettext("Connected Glass") .. ";" + .. dump(core.settings:get_bool("connected_glass")) .. "]" .. + "dropdown[0.25,2.8;3.5;dd_node_highlighting;" .. dd_options.node_highlighting[1] .. ";" + .. getSettingIndex.NodeHighlighting() .. "]" .. + "dropdown[0.25,3.6;3.5;dd_leaves_style;" .. dd_options.leaves[1] .. ";" + .. getSettingIndex.Leaves() .. "]" .. + "box[4,0;3.75,4.9;#999999]" .. + "label[4.25,0.1;" .. fgettext("Texturing:") .. "]" .. + "dropdown[4.25,0.55;3.5;dd_filters;" .. dd_options.filters[1] .. ";" + .. getSettingIndex.Filter() .. "]" .. + "dropdown[4.25,1.35;3.5;dd_mipmap;" .. dd_options.mipmap[1] .. ";" + .. getSettingIndex.Mipmap() .. "]" .. + "label[4.25,2.15;" .. fgettext("Antialiasing:") .. "]" .. + "dropdown[4.25,2.6;3.5;dd_antialiasing;" .. dd_options.antialiasing[1] .. ";" + .. getSettingIndex.Antialiasing() .. "]" .. + "box[8,0;3.75,4.5;#999999]" + + local video_driver = core.settings:get("video_driver") + local shaders_enabled = core.settings:get_bool("enable_shaders") + if video_driver == "opengl" then + tab_string = tab_string .. + "checkbox[8.25,0;cb_shaders;" .. fgettext("Shaders") .. ";" + .. tostring(shaders_enabled) .. "]" + elseif video_driver == "ogles2" then + tab_string = tab_string .. + "checkbox[8.25,0;cb_shaders;" .. fgettext("Shaders (experimental)") .. ";" + .. tostring(shaders_enabled) .. "]" + else + core.settings:set_bool("enable_shaders", false) + shaders_enabled = false + tab_string = tab_string .. + "label[8.38,0.2;" .. core.colorize("#888888", + fgettext("Shaders (unavailable)")) .. "]" + end + + tab_string = tab_string .. + "button[8,4.75;3.95,1;btn_change_keys;" + .. fgettext("Change Keys") .. "]" + + tab_string = tab_string .. + "button[0,4.75;3.95,1;btn_advanced_settings;" + .. fgettext("All Settings") .. "]" + + + if core.settings:get("touchscreen_threshold") ~= nil then + tab_string = tab_string .. + "label[4.25,3.5;" .. fgettext("Touch threshold (px):") .. "]" .. + "dropdown[4.25,3.95;3.5;dd_touchthreshold;0,10,20,30,40,50;" .. + ((tonumber(core.settings:get("touchscreen_threshold")) / 10) + 1) .. + "]" + else + tab_string = tab_string .. + "label[4.25,3.65;" .. fgettext("Screen:") .. "]" .. + "checkbox[4.25,3.9;cb_autosave_screensize;" .. fgettext("Autosave Screen Size") .. ";" + .. dump(core.settings:get_bool("autosave_screensize")) .. "]" + end + + if shaders_enabled then + tab_string = tab_string .. + "checkbox[8.25,0.5;cb_tonemapping;" .. fgettext("Tone Mapping") .. ";" + .. dump(core.settings:get_bool("tone_mapping")) .. "]" .. + "checkbox[8.25,1;cb_waving_water;" .. fgettext("Waving Liquids") .. ";" + .. dump(core.settings:get_bool("enable_waving_water")) .. "]" .. + "checkbox[8.25,1.5;cb_waving_leaves;" .. fgettext("Waving Leaves") .. ";" + .. dump(core.settings:get_bool("enable_waving_leaves")) .. "]" .. + "checkbox[8.25,2;cb_waving_plants;" .. fgettext("Waving Plants") .. ";" + .. dump(core.settings:get_bool("enable_waving_plants")) .. "]" + + if video_driver == "opengl" then + tab_string = tab_string .. + "label[8.25,2.8;" .. fgettext("Dynamic shadows:") .. "]" .. + "label[8.25,3.2;" .. fgettext("(game support required)") .. "]" .. + "dropdown[8.25,3.7;3.5;dd_shadows;" .. dd_options.shadow_levels[1] .. ";" + .. getSettingIndex.ShadowMapping() .. "]" + else + tab_string = tab_string .. + "label[8.38,2.7;" .. core.colorize("#888888", + fgettext("Dynamic shadows")) .. "]" + end + else + tab_string = tab_string .. + "label[8.38,0.7;" .. core.colorize("#888888", + fgettext("Tone Mapping")) .. "]" .. + "label[8.38,1.2;" .. core.colorize("#888888", + fgettext("Waving Liquids")) .. "]" .. + "label[8.38,1.7;" .. core.colorize("#888888", + fgettext("Waving Leaves")) .. "]" .. + "label[8.38,2.2;" .. core.colorize("#888888", + fgettext("Waving Plants")) .. "]".. + "label[8.38,2.7;" .. core.colorize("#888888", + fgettext("Dynamic shadows")) .. "]" + end + + return tab_string +end + +-------------------------------------------------------------------------------- +local function handle_settings_buttons(this, fields, tabname, tabdata) + + if fields["btn_advanced_settings"] ~= nil then + local adv_settings_dlg = create_adv_settings_dlg() + adv_settings_dlg:set_parent(this) + this:hide() + adv_settings_dlg:show() + --mm_game_theme.update("singleplayer", current_game()) + return true + end + if fields["cb_smooth_lighting"] then + core.settings:set("smooth_lighting", fields["cb_smooth_lighting"]) + return true + end + if fields["cb_particles"] then + core.settings:set("enable_particles", fields["cb_particles"]) + return true + end + if fields["cb_3d_clouds"] then + core.settings:set("enable_3d_clouds", fields["cb_3d_clouds"]) + return true + end + if fields["cb_opaque_water"] then + core.settings:set("opaque_water", fields["cb_opaque_water"]) + return true + end + if fields["cb_connected_glass"] then + core.settings:set("connected_glass", fields["cb_connected_glass"]) + return true + end + if fields["cb_autosave_screensize"] then + core.settings:set("autosave_screensize", fields["cb_autosave_screensize"]) + return true + end + if fields["cb_shaders"] then + core.settings:set("enable_shaders", fields["cb_shaders"]) + return true + end + if fields["cb_tonemapping"] then + core.settings:set("tone_mapping", fields["cb_tonemapping"]) + return true + end + if fields["cb_waving_water"] then + core.settings:set("enable_waving_water", fields["cb_waving_water"]) + return true + end + if fields["cb_waving_leaves"] then + core.settings:set("enable_waving_leaves", fields["cb_waving_leaves"]) + end + if fields["cb_waving_plants"] then + core.settings:set("enable_waving_plants", fields["cb_waving_plants"]) + return true + end + if fields["btn_change_keys"] then + core.show_keys_menu() + return true + end + if fields["cb_touchscreen_target"] then + core.settings:set("touchtarget", fields["cb_touchscreen_target"]) + return true + end + + --Note dropdowns have to be handled LAST! + local ddhandled = false + + for i = 1, #labels.leaves do + if fields["dd_leaves_style"] == labels.leaves[i] then + core.settings:set("leaves_style", dd_options.leaves[2][i]) + ddhandled = true + end + end + for i = 1, #labels.node_highlighting do + if fields["dd_node_highlighting"] == labels.node_highlighting[i] then + core.settings:set("node_highlighting", dd_options.node_highlighting[2][i]) + ddhandled = true + end + end + if fields["dd_filters"] == labels.filters[1] then + core.settings:set("bilinear_filter", "false") + core.settings:set("trilinear_filter", "false") + ddhandled = true + elseif fields["dd_filters"] == labels.filters[2] then + core.settings:set("bilinear_filter", "true") + core.settings:set("trilinear_filter", "false") + ddhandled = true + elseif fields["dd_filters"] == labels.filters[3] then + core.settings:set("bilinear_filter", "false") + core.settings:set("trilinear_filter", "true") + ddhandled = true + end + if fields["dd_mipmap"] == labels.mipmap[1] then + core.settings:set("mip_map", "false") + core.settings:set("anisotropic_filter", "false") + ddhandled = true + elseif fields["dd_mipmap"] == labels.mipmap[2] then + core.settings:set("mip_map", "true") + core.settings:set("anisotropic_filter", "false") + ddhandled = true + elseif fields["dd_mipmap"] == labels.mipmap[3] then + core.settings:set("mip_map", "true") + core.settings:set("anisotropic_filter", "true") + ddhandled = true + end + if fields["dd_antialiasing"] then + core.settings:set("fsaa", + antialiasing_fname_to_name(fields["dd_antialiasing"])) + ddhandled = true + end + if fields["dd_touchthreshold"] then + core.settings:set("touchscreen_threshold", fields["dd_touchthreshold"]) + ddhandled = true + end + + for i = 1, #labels.shadow_levels do + if fields["dd_shadows"] == labels.shadow_levels[i] then + core.settings:set("shadow_levels", dd_options.shadow_levels[2][i]) + ddhandled = true + end + end + + if fields["dd_shadows"] == labels.shadow_levels[1] then + core.settings:set("enable_dynamic_shadows", "false") + else + local shadow_presets = { + [2] = { 62, 512, "true", 0, "false" }, + [3] = { 93, 1024, "true", 0, "false" }, + [4] = { 140, 2048, "true", 1, "false" }, + [5] = { 210, 4096, "true", 2, "true" }, + [6] = { 300, 8192, "true", 2, "true" }, + } + local s = shadow_presets[table.indexof(labels.shadow_levels, fields["dd_shadows"])] + if s then + core.settings:set("enable_dynamic_shadows", "true") + core.settings:set("shadow_map_max_distance", s[1]) + core.settings:set("shadow_map_texture_size", s[2]) + core.settings:set("shadow_map_texture_32bit", s[3]) + core.settings:set("shadow_filters", s[4]) + core.settings:set("shadow_map_color", s[5]) + end + end + + return ddhandled +end + +return { + name = "settings", + caption = fgettext("Settings"), + cbf_formspec = formspec, + cbf_button_handler = handle_settings_buttons +} diff --git a/builtin/mainmenu/tests/favorites_wellformed.txt b/builtin/mainmenu/tests/favorites_wellformed.txt new file mode 100644 index 0000000..8b87b43 --- /dev/null +++ b/builtin/mainmenu/tests/favorites_wellformed.txt @@ -0,0 +1,29 @@ +[server] + +127.0.0.1 +30000 + + +[server] + +localhost +30000 + + +[server] + +vps.rubenwardy.com +30001 + + +[server] + +gundul.ddnss.de +39155 + + +[server] +VanessaE's Dreambuilder creative Server +daconcepts.com +30000 +VanessaE's Dreambuilder creative-mode server. Lots of mods, whitelisted buckets. diff --git a/builtin/mainmenu/tests/serverlistmgr_spec.lua b/builtin/mainmenu/tests/serverlistmgr_spec.lua new file mode 100644 index 0000000..ab7a6c6 --- /dev/null +++ b/builtin/mainmenu/tests/serverlistmgr_spec.lua @@ -0,0 +1,38 @@ +_G.core = {} +_G.vector = {metatable = {}} +_G.unpack = table.unpack +_G.serverlistmgr = {} + +dofile("builtin/common/vector.lua") +dofile("builtin/common/misc_helpers.lua") +dofile("builtin/mainmenu/serverlistmgr.lua") + +local base = "builtin/mainmenu/tests/" + +describe("legacy favorites", function() + it("loads well-formed correctly", function() + local favs = serverlistmgr.read_legacy_favorites(base .. "favorites_wellformed.txt") + + local expected = { + { + address = "127.0.0.1", + port = 30000, + }, + + { address = "localhost", port = 30000 }, + + { address = "vps.rubenwardy.com", port = 30001 }, + + { address = "gundul.ddnss.de", port = 39155 }, + + { + address = "daconcepts.com", + port = 30000, + name = "VanessaE's Dreambuilder creative Server", + description = "VanessaE's Dreambuilder creative-mode server. Lots of mods, whitelisted buckets." + }, + } + + assert.same(expected, favs) + end) +end) diff --git a/builtin/profiler/init.lua b/builtin/profiler/init.lua new file mode 100644 index 0000000..7f63dfa --- /dev/null +++ b/builtin/profiler/init.lua @@ -0,0 +1,80 @@ +--Minetest +--Copyright (C) 2016 T4im +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +local S = core.get_translator("__builtin") + +local function get_bool_default(name, default) + local val = core.settings:get_bool(name) + if val == nil then + return default + end + return val +end + +local profiler_path = core.get_builtin_path().."profiler"..DIR_DELIM +local profiler = {} +local sampler = assert(loadfile(profiler_path .. "sampling.lua"))(profiler) +local instrumentation = assert(loadfile(profiler_path .. "instrumentation.lua"))(profiler, sampler, get_bool_default) +local reporter = dofile(profiler_path .. "reporter.lua") +profiler.instrument = instrumentation.instrument + +--- +-- Delayed registration of the /profiler chat command +-- Is called later, after `core.register_chatcommand` was set up. +-- +function profiler.init_chatcommand() + local instrument_profiler = get_bool_default("instrument.profiler", false) + if instrument_profiler then + instrumentation.init_chatcommand() + end + + local param_usage = S("print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset") + core.register_chatcommand("profiler", { + description = S("Handle the profiler and profiling data"), + params = param_usage, + privs = { server=true }, + func = function(name, param) + local command, arg0 = string.match(param, "([^ ]+) ?(.*)") + local args = arg0 and string.split(arg0, " ") + + if command == "dump" then + core.log("action", reporter.print(sampler.profile, arg0)) + return true, S("Statistics written to action log.") + elseif command == "print" then + return true, reporter.print(sampler.profile, arg0) + elseif command == "save" then + return reporter.save(sampler.profile, args[1] or "txt", args[2]) + elseif command == "reset" then + sampler.reset() + return true, S("Statistics were reset.") + end + + return false, + S("Usage: @1", param_usage) .. "\n" .. + S("Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).") + end + }) + + if not instrument_profiler then + instrumentation.init_chatcommand() + end +end + +sampler.init() +instrumentation.init() + +return profiler diff --git a/builtin/profiler/instrumentation.lua b/builtin/profiler/instrumentation.lua new file mode 100644 index 0000000..f80314b --- /dev/null +++ b/builtin/profiler/instrumentation.lua @@ -0,0 +1,235 @@ +--Minetest +--Copyright (C) 2016 T4im +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +local format, pairs, type = string.format, pairs, type +local core, get_current_modname = core, core.get_current_modname +local profiler, sampler, get_bool_default = ... + +local instrument_builtin = get_bool_default("instrument.builtin", false) + +local register_functions = { + register_globalstep = 0, + register_playerevent = 0, + register_on_placenode = 0, + register_on_dignode = 0, + register_on_punchnode = 0, + register_on_generated = 0, + register_on_newplayer = 0, + register_on_dieplayer = 0, + register_on_respawnplayer = 0, + register_on_prejoinplayer = 0, + register_on_joinplayer = 0, + register_on_leaveplayer = 0, + register_on_cheat = 0, + register_on_chat_message = 0, + register_on_player_receive_fields = 0, + register_on_craft = 0, + register_craft_predict = 0, + register_on_protection_violation = 0, + register_on_item_eat = 0, + register_on_punchplayer = 0, + register_on_player_hpchange = 0, +} + +--- +-- Create an unique instrument name. +-- Generate a missing label with a running index number. +-- +local counts = {} +local function generate_name(def) + local class, label, func_name = def.class, def.label, def.func_name + if label then + if class or func_name then + return format("%s '%s' %s", class or "", label, func_name or ""):trim() + end + return format("%s", label):trim() + elseif label == false then + return format("%s", class or func_name):trim() + end + + local index_id = def.mod .. (class or func_name) + local index = counts[index_id] or 1 + counts[index_id] = index + 1 + return format("%s[%d] %s", class or func_name, index, class and func_name or ""):trim() +end + +--- +-- Keep `measure` and the closure in `instrument` lean, as these, and their +-- directly called functions are the overhead that is caused by instrumentation. +-- +local time, log = core.get_us_time, sampler.log +local function measure(modname, instrument_name, start, ...) + log(modname, instrument_name, time() - start) + return ... +end +--- Automatically instrument a function to measure and log to the sampler. +-- def = { +-- mod = "", +-- class = "", +-- func_name = "", +-- -- if nil, will create a label based on registration order +-- label = "" | false, +-- } +local function instrument(def) + if not def or not def.func then + return + end + def.mod = def.mod or get_current_modname() or "??" + local modname = def.mod + local instrument_name = generate_name(def) + local func = def.func + + if not instrument_builtin and modname == "*builtin*" then + return func + end + + return function(...) + -- This tail-call allows passing all return values of `func` + -- also called https://en.wikipedia.org/wiki/Continuation_passing_style + -- Compared to table creation and unpacking it won't lose `nil` returns + -- and is expected to be faster + -- `measure` will be executed after func(...) + local start = time() + return measure(modname, instrument_name, start, func(...)) + end +end + +local function can_be_called(func) + -- It has to be a function or callable table + return type(func) == "function" or + ((type(func) == "table" or type(func) == "userdata") and + getmetatable(func) and getmetatable(func).__call) +end + +local function assert_can_be_called(func, func_name, level) + if not can_be_called(func) then + -- Then throw an *helpful* error, by pointing on our caller instead of us. + error(format("Invalid argument to %s. Expected function-like type instead of '%s'.", + func_name, type(func)), level + 1) + end +end + +--- +-- Wraps a registration function `func` in such a way, +-- that it will automatically instrument any callback function passed as first argument. +-- +local function instrument_register(func, func_name) + local register_name = func_name:gsub("^register_", "", 1) + return function(callback, ...) + assert_can_be_called(callback, func_name, 2) + register_functions[func_name] = register_functions[func_name] + 1 + return func(instrument { + func = callback, + func_name = register_name + }, ...) + end +end + +local function init_chatcommand() + if get_bool_default("instrument.chatcommand", true) then + local orig_register_chatcommand = core.register_chatcommand + core.register_chatcommand = function(cmd, def) + def.func = instrument { + func = def.func, + label = "/" .. cmd, + } + orig_register_chatcommand(cmd, def) + end + end +end + +--- +-- Start instrumenting selected functions +-- +local function init() + if get_bool_default("instrument.entity", true) then + -- Explicitly declare entity api-methods. + -- Simple iteration would ignore lookup via __index. + local entity_instrumentation = { + "on_activate", + "on_deactivate", + "on_step", + "on_punch", + "on_rightclick", + "get_staticdata", + } + -- Wrap register_entity() to instrument them on registration. + local orig_register_entity = core.register_entity + core.register_entity = function(name, prototype) + local modname = get_current_modname() + for _, func_name in pairs(entity_instrumentation) do + prototype[func_name] = instrument { + func = prototype[func_name], + mod = modname, + func_name = func_name, + label = prototype.label, + } + end + orig_register_entity(name,prototype) + end + end + + if get_bool_default("instrument.abm", true) then + -- Wrap register_abm() to automatically instrument abms. + local orig_register_abm = core.register_abm + core.register_abm = function(spec) + spec.action = instrument { + func = spec.action, + class = "ABM", + label = spec.label, + } + orig_register_abm(spec) + end + end + + if get_bool_default("instrument.lbm", true) then + -- Wrap register_lbm() to automatically instrument lbms. + local orig_register_lbm = core.register_lbm + core.register_lbm = function(spec) + spec.action = instrument { + func = spec.action, + class = "LBM", + label = spec.label or spec.name, + } + orig_register_lbm(spec) + end + end + + if get_bool_default("instrument.global_callback", true) then + for func_name, _ in pairs(register_functions) do + core[func_name] = instrument_register(core[func_name], func_name) + end + end + + if get_bool_default("instrument.profiler", false) then + -- Measure overhead of instrumentation, but keep it down for functions + -- So keep the `return` for better optimization. + profiler.empty_instrument = instrument { + func = function() return end, + mod = "*profiler*", + class = "Instrumentation overhead", + label = false, + } + end +end + +return { + register_functions = register_functions, + instrument = instrument, + init = init, + init_chatcommand = init_chatcommand, +} diff --git a/builtin/profiler/reporter.lua b/builtin/profiler/reporter.lua new file mode 100644 index 0000000..5928a37 --- /dev/null +++ b/builtin/profiler/reporter.lua @@ -0,0 +1,280 @@ +--Minetest +--Copyright (C) 2016 T4im +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +local S = core.get_translator("__builtin") +-- Note: In this file, only messages are translated +-- but not the table itself, to keep it simple. + +local DIR_DELIM, LINE_DELIM = DIR_DELIM, "\n" +local table, unpack, string, pairs, io, os = table, unpack, string, pairs, io, os +local rep, sprintf, tonumber = string.rep, string.format, tonumber +local core, settings = core, core.settings +local reporter = {} + +--- +-- Shorten a string. End on an ellipsis if shortened. +-- +local function shorten(str, length) + if str and str:len() > length then + return "..." .. str:sub(-(length-3)) + end + return str +end + +local function filter_matches(filter, text) + return not filter or string.match(text, filter) +end + +local function format_number(number, fmt) + number = tonumber(number) + if not number then + return "N/A" + end + return sprintf(fmt or "%d", number) +end + +local Formatter = { + new = function(self, object) + object = object or {} + object.out = {} -- output buffer + self.__index = self + return setmetatable(object, self) + end, + __tostring = function (self) + return table.concat(self.out, LINE_DELIM) + end, + print = function(self, text, ...) + if (...) then + text = sprintf(text, ...) + end + + if text then + -- Avoid format unicode issues. + text = text:gsub("Ms", "µs") + end + + table.insert(self.out, text or LINE_DELIM) + end, + flush = function(self) + table.insert(self.out, LINE_DELIM) + local text = table.concat(self.out, LINE_DELIM) + self.out = {} + return text + end +} + +local widths = { 55, 9, 9, 9, 5, 5, 5 } +local txt_row_format = sprintf(" %%-%ds | %%%ds | %%%ds | %%%ds | %%%ds | %%%ds | %%%ds", unpack(widths)) + +local HR = {} +for i=1, #widths do + HR[i]= rep("-", widths[i]) +end +-- ' | ' should break less with github than '-+-', when people are pasting there +HR = sprintf("-%s-", table.concat(HR, " | ")) + +local TxtFormatter = Formatter:new { + format_row = function(self, modname, instrument_name, statistics) + local label + if instrument_name then + label = shorten(instrument_name, widths[1] - 5) + label = sprintf(" - %s %s", label, rep(".", widths[1] - 5 - label:len())) + else -- Print mod_stats + label = shorten(modname, widths[1] - 2) .. ":" + end + + self:print(txt_row_format, label, + format_number(statistics.time_min), + format_number(statistics.time_max), + format_number(statistics:get_time_avg()), + format_number(statistics.part_min, "%.1f"), + format_number(statistics.part_max, "%.1f"), + format_number(statistics:get_part_avg(), "%.1f") + ) + end, + format = function(self, filter) + local profile = self.profile + self:print(S("Values below show absolute/relative times spend per server step by the instrumented function.")) + self:print(S("A total of @1 sample(s) were taken.", profile.stats_total.samples)) + + if filter then + self:print(S("The output is limited to '@1'.", filter)) + end + + self:print() + self:print( + txt_row_format, + "instrumentation", "min Ms", "max Ms", "avg Ms", "min %", "max %", "avg %" + ) + self:print(HR) + for modname,mod_stats in pairs(profile.stats) do + if filter_matches(filter, modname) then + self:format_row(modname, nil, mod_stats) + + if mod_stats.instruments ~= nil then + for instrument_name, instrument_stats in pairs(mod_stats.instruments) do + self:format_row(nil, instrument_name, instrument_stats) + end + end + end + end + self:print(HR) + if not filter then + self:format_row("total", nil, profile.stats_total) + end + end +} + +local CsvFormatter = Formatter:new { + format_row = function(self, modname, instrument_name, statistics) + self:print( + "%q,%q,%d,%d,%d,%d,%d,%f,%f,%f", + modname, instrument_name, + statistics.samples, + statistics.time_min, + statistics.time_max, + statistics:get_time_avg(), + statistics.time_all, + statistics.part_min, + statistics.part_max, + statistics:get_part_avg() + ) + end, + format = function(self, filter) + self:print( + "%q,%q,%q,%q,%q,%q,%q,%q,%q,%q", + "modname", "instrumentation", + "samples", + "time min µs", + "time max µs", + "time avg µs", + "time all µs", + "part min %", + "part max %", + "part avg %" + ) + for modname, mod_stats in pairs(self.profile.stats) do + if filter_matches(filter, modname) then + self:format_row(modname, "*", mod_stats) + + if mod_stats.instruments ~= nil then + for instrument_name, instrument_stats in pairs(mod_stats.instruments) do + self:format_row(modname, instrument_name, instrument_stats) + end + end + end + end + end +} + +local function format_statistics(profile, format, filter) + local formatter + if format == "csv" then + formatter = CsvFormatter:new { + profile = profile + } + else + formatter = TxtFormatter:new { + profile = profile + } + end + formatter:format(filter) + return formatter:flush() +end + +--- +-- Format the profile ready for display and +-- @return string to be printed to the console +-- +function reporter.print(profile, filter) + if filter == "" then filter = nil end + return format_statistics(profile, "txt", filter) +end + +--- +-- Serialize the profile data and +-- @return serialized data to be saved to a file +-- +local function serialize_profile(profile, format, filter) + if format == "lua" or format == "json" or format == "json_pretty" then + local stats = filter and {} or profile.stats + if filter then + for modname, mod_stats in pairs(profile.stats) do + if filter_matches(filter, modname) then + stats[modname] = mod_stats + end + end + end + if format == "lua" then + return core.serialize(stats) + elseif format == "json" then + return core.write_json(stats) + elseif format == "json_pretty" then + return core.write_json(stats, true) + end + end + -- Fall back to textual formats. + return format_statistics(profile, format, filter) +end + +local worldpath = core.get_worldpath() +local function get_save_path(format, filter) + local report_path = settings:get("profiler.report_path") or "" + if report_path ~= "" then + core.mkdir(sprintf("%s%s%s", worldpath, DIR_DELIM, report_path)) + end + return (sprintf( + "%s/%s/profile-%s%s.%s", + worldpath, + report_path, + os.date("%Y%m%dT%H%M%S"), + filter and ("-" .. filter) or "", + format + ):gsub("[/\\]+", DIR_DELIM))-- Clean up delims +end + +--- +-- Save the profile to the world path. +-- @return success, log message +-- +function reporter.save(profile, format, filter) + if not format or format == "" then + format = settings:get("profiler.default_report_format") or "txt" + end + if filter == "" then + filter = nil + end + + local path = get_save_path(format, filter) + + local output, io_err = io.open(path, "w") + if not output then + return false, S("Saving of profile failed: @1", io_err) + end + local content, err = serialize_profile(profile, format, filter) + if not content then + output:close() + return false, S("Saving of profile failed: @1", err) + end + output:write(content) + output:close() + + core.log("action", "Profile saved to " .. path) + return true, S("Profile saved to @1", path) +end + +return reporter diff --git a/builtin/profiler/sampling.lua b/builtin/profiler/sampling.lua new file mode 100644 index 0000000..4b53399 --- /dev/null +++ b/builtin/profiler/sampling.lua @@ -0,0 +1,206 @@ +--Minetest +--Copyright (C) 2016 T4im +-- +--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.1 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., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +local setmetatable = setmetatable +local pairs, format = pairs, string.format +local min, max, huge = math.min, math.max, math.huge +local core = core + +local profiler = ... +-- Split sampler and profile up, to possibly allow for rotation later. +local sampler = {} +local profile +local stats_total +local logged_time, logged_data + +local _stat_mt = { + get_time_avg = function(self) + return self.time_all/self.samples + end, + get_part_avg = function(self) + if not self.part_all then + return 100 -- Extra handling for "total" + end + return self.part_all/self.samples + end, +} +_stat_mt.__index = _stat_mt + +function sampler.reset() + -- Accumulated logged time since last sample. + -- This helps determining, the relative time a mod used up. + logged_time = 0 + -- The measurements taken through instrumentation since last sample. + logged_data = {} + + profile = { + -- Current mod statistics (max/min over the entire mod lifespan) + -- Mod specific instrumentation statistics are nested within. + stats = {}, + -- Current stats over all mods. + stats_total = setmetatable({ + samples = 0, + time_min = huge, + time_max = 0, + time_all = 0, + part_min = 100, + part_max = 100 + }, _stat_mt) + } + stats_total = profile.stats_total + + -- Provide access to the most recent profile. + sampler.profile = profile +end + +--- +-- Log a measurement for the sampler to pick up later. +-- Keep `log` and its often called functions lean. +-- It will directly add to the instrumentation overhead. +-- +function sampler.log(modname, instrument_name, time_diff) + if time_diff <= 0 then + if time_diff < 0 then + -- This **might** have happened on a semi-regular basis with huge mods, + -- resulting in negative statistics (perhaps midnight time jumps or ntp corrections?). + core.log("warning", format( + "Time travel of %s::%s by %dµs.", + modname, instrument_name, time_diff + )) + end + -- Throwing these away is better, than having them mess with the overall result. + return + end + + local mod_data = logged_data[modname] + if mod_data == nil then + mod_data = {} + logged_data[modname] = mod_data + end + + mod_data[instrument_name] = (mod_data[instrument_name] or 0) + time_diff + -- Update logged time since last sample. + logged_time = logged_time + time_diff +end + +--- +-- Return a requested statistic. +-- Initialize if necessary. +-- +local function get_statistic(stats_table, name) + local statistic = stats_table[name] + if statistic == nil then + statistic = setmetatable({ + samples = 0, + time_min = huge, + time_max = 0, + time_all = 0, + part_min = 100, + part_max = 0, + part_all = 0, + }, _stat_mt) + stats_table[name] = statistic + end + return statistic +end + +--- +-- Update a statistic table +-- +local function update_statistic(stats_table, time) + stats_table.samples = stats_table.samples + 1 + + -- Update absolute time (µs) spend by the subject + stats_table.time_min = min(stats_table.time_min, time) + stats_table.time_max = max(stats_table.time_max, time) + stats_table.time_all = stats_table.time_all + time + + -- Update relative time (%) of this sample spend by the subject + local current_part = (time/logged_time) * 100 + stats_table.part_min = min(stats_table.part_min, current_part) + stats_table.part_max = max(stats_table.part_max, current_part) + stats_table.part_all = stats_table.part_all + current_part +end + +--- +-- Sample all logged measurements each server step. +-- Like any globalstep function, this should not be too heavy, +-- but does not add to the instrumentation overhead. +-- +local function sample(dtime) + -- Rare, but happens and is currently of no informational value. + if logged_time == 0 then + return + end + + for modname, instruments in pairs(logged_data) do + local mod_stats = get_statistic(profile.stats, modname) + if mod_stats.instruments == nil then + -- Current statistics for each instrumentation component + mod_stats.instruments = {} + end + + local mod_time = 0 + for instrument_name, time in pairs(instruments) do + if time > 0 then + mod_time = mod_time + time + local instrument_stats = get_statistic(mod_stats.instruments, instrument_name) + + -- Update time of this sample spend by the instrumented function. + update_statistic(instrument_stats, time) + -- Reset logged data for the next sample. + instruments[instrument_name] = 0 + end + end + + -- Update time of this sample spend by this mod. + update_statistic(mod_stats, mod_time) + end + + -- Update the total time spend over all mods. + stats_total.time_min = min(stats_total.time_min, logged_time) + stats_total.time_max = max(stats_total.time_max, logged_time) + stats_total.time_all = stats_total.time_all + logged_time + + stats_total.samples = stats_total.samples + 1 + logged_time = 0 +end + +--- +-- Setup empty profile and register the sampling function +-- +function sampler.init() + sampler.reset() + + if core.settings:get_bool("instrument.profiler") then + core.register_globalstep(function() + if logged_time == 0 then + return + end + return profiler.empty_instrument() + end) + core.register_globalstep(profiler.instrument { + func = sample, + mod = "*profiler*", + class = "Sampler (update stats)", + label = false, + }) + else + core.register_globalstep(sample) + end +end + +return sampler diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt new file mode 100644 index 0000000..52b4b4d --- /dev/null +++ b/builtin/settingtypes.txt @@ -0,0 +1,2353 @@ +# This file contains all settings displayed in the settings menu. +# +# General format: +# name (Readable name) type type_args +# +# Note that the parts are separated by exactly one space +# +# `type` can be: +# - int +# - string +# - bool +# - float +# - enum +# - path +# - filepath +# - key (will be ignored in GUI, since a special key change dialog exists) +# - flags +# - noise_params_2d +# - noise_params_3d +# - v3f +# +# `type_args` can be: +# * int: +# - default +# - default min max +# * string: +# - default (if default is not specified then "" is set) +# * bool: +# - default +# * float: +# - default +# - default min max +# * enum: +# - default value1,value2,... +# * path: +# - default (if default is not specified then "" is set) +# * filepath: +# - default (if default is not specified then "" is set) +# * key: +# - default +# * flags: +# Flags are always separated by comma without spaces. +# - default possible_flags +# * noise_params_2d: +# Format is <offset>, <scale>, (<spreadX>, <spreadY>, <spreadZ>), <seed>, <octaves>, <persistence>, <lacunarity>[, <default flags>] +# - default +# * noise_params_3d: +# Format is <offset>, <scale>, (<spreadX>, <spreadY>, <spreadZ>), <seed>, <octaves>, <persistence>, <lacunarity>[, <default flags>] +# - default +# * v3f: +# Format is (<X>, <Y>, <Z>) +# - default +# +# Comments directly above a setting are bound to this setting. +# All other comments are ignored. +# +# Comments and (Readable name) are handled by gettext. +# Comments should be complete sentences that describe the setting and possibly +# give the user additional useful insight. +# Sections are marked by a single line in the format: [Section Name] +# Sub-section are marked by adding * in front of the section name: [*Sub-section] +# Sub-sub-sections have two * etc. +# There shouldn't be too much settings per category; settings that shouldn't be +# modified by the "average user" should be in (sub-)categories called "Advanced". + + +[Controls] + +[*General] + +# If enabled, you can place blocks at the position (feet + eye level) where you stand. +# This is helpful when working with nodeboxes in small areas. +enable_build_where_you_stand (Build inside player) bool false + +# Smooths camera when looking around. Also called look or mouse smoothing. +# Useful for recording videos. +cinematic (Cinematic mode) bool false + +# Smooths rotation of camera. 0 to disable. +camera_smoothing (Camera smoothing) float 0.0 0.0 0.99 + +# Smooths rotation of camera in cinematic mode. 0 to disable. +cinematic_camera_smoothing (Camera smoothing in cinematic mode) float 0.7 0.0 0.99 + +# If enabled, "Aux1" key instead of "Sneak" key is used for climbing down and +# descending. +aux1_descends (Aux1 key for climbing/descending) bool false + +# Double-tapping the jump key toggles fly mode. +doubletap_jump (Double tap jump for fly) bool false + +# If disabled, "Aux1" key is used to fly fast if both fly and fast mode are +# enabled. +always_fly_fast (Always fly fast) bool true + +# The time in seconds it takes between repeated node placements when holding +# the place button. +repeat_place_time (Place repetition interval) float 0.25 0.25 2 + +# Automatically jump up single-node obstacles. +autojump (Automatic jumping) bool false + +# Prevent digging and placing from repeating when holding the mouse buttons. +# Enable this when you dig or place too often by accident. +safe_dig_and_place (Safe digging and placing) bool false + +[*Keyboard and Mouse] + +# Invert vertical mouse movement. +invert_mouse (Invert mouse) bool false + +# Mouse sensitivity multiplier. +mouse_sensitivity (Mouse sensitivity) float 0.2 0.001 10.0 + +[*Touchscreen] + +# The length in pixels it takes for touch screen interaction to start. +touchscreen_threshold (Touch screen threshold) int 20 0 100 + +# (Android) Fixes the position of virtual joystick. +# If disabled, virtual joystick will center to first-touch's position. +fixed_virtual_joystick (Fixed virtual joystick) bool false + +# (Android) Use virtual joystick to trigger "Aux1" button. +# If enabled, virtual joystick will also tap "Aux1" button when out of main circle. +virtual_joystick_triggers_aux1 (Virtual joystick triggers Aux1 button) bool false + + +[Graphics and Audio] + +[*Graphics] + +[**Screen] + +# Width component of the initial window size. Ignored in fullscreen mode. +screen_w (Screen width) int 1024 1 65535 + +# Height component of the initial window size. Ignored in fullscreen mode. +screen_h (Screen height) int 600 1 65535 + +# Save window size automatically when modified. +autosave_screensize (Autosave screen size) bool true + +# Fullscreen mode. +fullscreen (Full screen) bool false + +# Open the pause menu when the window's focus is lost. Does not pause if a formspec is +# open. +pause_on_lost_focus (Pause on lost window focus) bool false + +[**FPS] + +# If FPS would go higher than this, limit it by sleeping +# to not waste CPU power for no benefit. +fps_max (Maximum FPS) int 60 1 4294967295 + +# Vertical screen synchronization. +vsync (VSync) bool false + +# Maximum FPS when the window is not focused, or when the game is paused. +fps_max_unfocused (FPS when unfocused or paused) int 20 1 4294967295 + +# View distance in nodes. +viewing_range (Viewing range) int 190 20 4000 + +# Undersampling is similar to using a lower screen resolution, but it applies +# to the game world only, keeping the GUI intact. +# It should give a significant performance boost at the cost of less detailed image. +# Higher values result in a less detailed image. +undersampling (Undersampling) int 1 1 8 + +[**Graphics Effects] + +# Makes all liquids opaque +opaque_water (Opaque liquids) bool false + +# Leaves style: +# - Fancy: all faces visible +# - Simple: only outer faces, if defined special_tiles are used +# - Opaque: disable transparency +leaves_style (Leaves style) enum fancy fancy,simple,opaque + +# Connects glass if supported by node. +connected_glass (Connect glass) bool false + +# Enable smooth lighting with simple ambient occlusion. +# Disable for speed or for different looks. +smooth_lighting (Smooth lighting) bool true + +# Enables tradeoffs that reduce CPU load or increase rendering performance +# at the expense of minor visual glitches that do not impact game playability. +performance_tradeoffs (Tradeoffs for performance) bool false + +# Adds particles when digging a node. +enable_particles (Digging particles) bool true + +[**3d] + +# 3D support. +# Currently supported: +# - none: no 3d output. +# - anaglyph: cyan/magenta color 3d. +# - interlaced: odd/even line based polarisation screen support. +# - topbottom: split screen top/bottom. +# - sidebyside: split screen side by side. +# - crossview: Cross-eyed 3d +# - pageflip: quadbuffer based 3d. +# Note that the interlaced mode requires shaders to be enabled. +3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside,crossview,pageflip + +# Strength of 3D mode parallax. +3d_paralax_strength (3D mode parallax strength) float 0.025 -0.087 0.087 + +[**Bobbing] + +# Arm inertia, gives a more realistic movement of +# the arm when the camera moves. +arm_inertia (Arm inertia) bool true + +# Enable view bobbing and amount of view bobbing. +# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double. +view_bobbing_amount (View bobbing factor) float 1.0 0.0 7.9 + +# Multiplier for fall bobbing. +# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double. +fall_bobbing_amount (Fall bobbing factor) float 0.03 0.0 100.0 + +[**Camera] + +# Camera 'near clipping plane' distance in nodes, between 0 and 0.25 +# Only works on GLES platforms. Most users will not need to change this. +# Increasing can reduce artifacting on weaker GPUs. +# 0.1 = Default, 0.25 = Good value for weaker tablets. +near_plane (Near plane) float 0.1 0 0.25 + +# Field of view in degrees. +fov (Field of view) int 72 45 160 + +# Alters the light curve by applying 'gamma correction' to it. +# Higher values make middle and lower light levels brighter. +# Value '1.0' leaves the light curve unaltered. +# This only has significant effect on daylight and artificial +# light, it has very little effect on natural night light. +display_gamma (Light curve gamma) float 1.0 0.33 3.0 + +# The strength (darkness) of node ambient-occlusion shading. +# Lower is darker, Higher is lighter. The valid range of values for this +# setting is 0.25 to 4.0 inclusive. If the value is out of range it will be +# set to the nearest valid value. +ambient_occlusion_gamma (Ambient occlusion gamma) float 2.2 0.25 4.0 + +[**Screenshots] + +# Path to save screenshots at. Can be an absolute or relative path. +# The folder will be created if it doesn't already exist. +screenshot_path (Screenshot folder) path screenshots + +# Format of screenshots. +screenshot_format (Screenshot format) enum png png,jpg + +# Screenshot quality. Only used for JPEG format. +# 1 means worst quality; 100 means best quality. +# Use 0 for default quality. +screenshot_quality (Screenshot quality) int 0 0 100 + +[**Node and Entity Highlighting] + +# Method used to highlight selected object. +node_highlighting (Node highlighting) enum box box,halo,none + +# Show entity selection boxes +# A restart is required after changing this. +show_entity_selectionbox (Show entity selection boxes) bool false + +# Selection box border color (R,G,B). +selectionbox_color (Selection box color) string (0,0,0) + +# Width of the selection box lines around nodes. +selectionbox_width (Selection box width) int 2 1 5 + +# Crosshair color (R,G,B). +# Also controls the object crosshair color +crosshair_color (Crosshair color) string (255,255,255) + +# Crosshair alpha (opaqueness, between 0 and 255). +# This also applies to the object crosshair. +crosshair_alpha (Crosshair alpha) int 255 0 255 + +[**Fog] + +# Whether to fog out the end of the visible area. +enable_fog (Fog) bool true + +# Make fog and sky colors depend on daytime (dawn/sunset) and view direction. +directional_colored_fog (Colored fog) bool true + +# Fraction of the visible distance at which fog starts to be rendered +fog_start (Fog start) float 0.4 0.0 0.99 + +[**Clouds] + +# Clouds are a client side effect. +enable_clouds (Clouds) bool true + +# Use 3D cloud look instead of flat. +enable_3d_clouds (3D clouds) bool true + +[**Filtering and Antialiasing] + +# Use mipmapping to scale textures. May slightly increase performance, +# especially when using a high resolution texture pack. +# Gamma correct downscaling is not supported. +mip_map (Mipmapping) bool false + +# Use anisotropic filtering when viewing at textures from an angle. +anisotropic_filter (Anisotropic filtering) bool false + +# Use bilinear filtering when scaling textures. +bilinear_filter (Bilinear filtering) bool false + +# Use trilinear filtering when scaling textures. +trilinear_filter (Trilinear filtering) bool false + +# Filtered textures can blend RGB values with fully-transparent neighbors, +# which PNG optimizers usually discard, often resulting in dark or +# light edges to transparent textures. Apply a filter to clean that up +# at texture load time. This is automatically enabled if mipmapping is enabled. +texture_clean_transparent (Clean transparent textures) bool false + +# When using bilinear/trilinear/anisotropic filters, low-resolution textures +# can be blurred, so automatically upscale them with nearest-neighbor +# interpolation to preserve crisp pixels. This sets the minimum texture size +# for the upscaled textures; higher values look sharper, but require more +# memory. Powers of 2 are recommended. This setting is ONLY applied if +# bilinear/trilinear/anisotropic filtering is enabled. +# This is also used as the base node texture size for world-aligned +# texture autoscaling. +texture_min_size (Minimum texture size) int 64 1 32768 + +# Use multi-sample antialiasing (MSAA) to smooth out block edges. +# This algorithm smooths out the 3D viewport while keeping the image sharp, +# but it doesn't affect the insides of textures +# (which is especially noticeable with transparent textures). +# Visible spaces appear between nodes when shaders are disabled. +# If set to 0, MSAA is disabled. +# A restart is required after changing this option. +fsaa (FSAA) enum 0 0,1,2,4,8,16 + + +[*Shaders] + +# Shaders allow advanced visual effects and may increase performance on some video +# cards. +# This only works with the OpenGL video backend. +enable_shaders (Shaders) bool true + +[**Tone Mapping] + +# Enables Hable's 'Uncharted 2' filmic tone mapping. +# Simulates the tone curve of photographic film and how this approximates the +# appearance of high dynamic range images. Mid-range contrast is slightly +# enhanced, highlights and shadows are gradually compressed. +tone_mapping (Filmic tone mapping) bool false + +[**Waving Nodes] + +# Set to true to enable waving leaves. +# Requires shaders to be enabled. +enable_waving_leaves (Waving leaves) bool false + +# Set to true to enable waving plants. +# Requires shaders to be enabled. +enable_waving_plants (Waving plants) bool false + +# Set to true to enable waving liquids (like water). +# Requires shaders to be enabled. +enable_waving_water (Waving liquids) bool false + +# The maximum height of the surface of waving liquids. +# 4.0 = Wave height is two nodes. +# 0.0 = Wave doesn't move at all. +# Default is 1.0 (1/2 node). +# Requires waving liquids to be enabled. +water_wave_height (Waving liquids wave height) float 1.0 0.0 4.0 + +# Length of liquid waves. +# Requires waving liquids to be enabled. +water_wave_length (Waving liquids wavelength) float 20.0 0.1 + +# How fast liquid waves will move. Higher = faster. +# If negative, liquid waves will move backwards. +# Requires waving liquids to be enabled. +water_wave_speed (Waving liquids wave speed) float 5.0 + +[**Dynamic shadows] + +# Set to true to enable Shadow Mapping. +# Requires shaders to be enabled. +enable_dynamic_shadows (Dynamic shadows) bool false + +# Set the shadow strength gamma. +# Adjusts the intensity of in-game dynamic shadows. +# Lower value means lighter shadows, higher value means darker shadows. +shadow_strength_gamma (Shadow strength gamma) float 1.0 0.1 10.0 + +# Maximum distance to render shadows. +shadow_map_max_distance (Shadow map max distance in nodes to render shadows) float 120.0 10.0 1000.0 + +# Texture size to render the shadow map on. +# This must be a power of two. +# Bigger numbers create better shadows but it is also more expensive. +shadow_map_texture_size (Shadow map texture size) int 1024 128 8192 + +# Sets shadow texture quality to 32 bits. +# On false, 16 bits texture will be used. +# This can cause much more artifacts in the shadow. +shadow_map_texture_32bit (Shadow map texture in 32 bits) bool true + +# Enable Poisson disk filtering. +# On true uses Poisson disk to make "soft shadows". Otherwise uses PCF filtering. +shadow_poisson_filter (Poisson filtering) bool true + +# Define shadow filtering quality. +# This simulates the soft shadows effect by applying a PCF or Poisson disk +# but also uses more resources. +shadow_filters (Shadow filter quality) enum 1 0,1,2 + +# Enable colored shadows. +# On true translucent nodes cast colored shadows. This is expensive. +shadow_map_color (Colored shadows) bool false + +# Spread a complete update of shadow map over given amount of frames. +# Higher values might make shadows laggy, lower values +# will consume more resources. +# Minimum value: 1; maximum value: 16 +shadow_update_frames (Map shadows update frames) int 8 1 16 + +# Set the soft shadow radius size. +# Lower values mean sharper shadows, bigger values mean softer shadows. +# Minimum value: 1.0; maximum value: 15.0 +shadow_soft_radius (Soft shadow radius) float 5.0 1.0 15.0 + +# Set the tilt of Sun/Moon orbit in degrees. +# Value of 0 means no tilt / vertical orbit. +# Minimum value: 0.0; maximum value: 60.0 +shadow_sky_body_orbit_tilt (Sky Body Orbit Tilt) float 0.0 0.0 60.0 + +[*Audio] + +# Volume of all sounds. +# Requires the sound system to be enabled. +sound_volume (Volume) float 0.7 0.0 1.0 + +# Whether to mute sounds. You can unmute sounds at any time, unless the +# sound system is disabled (enable_sound=false). +# In-game, you can toggle the mute state with the mute key or by using the +# pause menu. +mute_sound (Mute sound) bool false + +[*User Interfaces] + +# Set the language. Leave empty to use the system language. +# A restart is required after changing this. +language (Language) enum ,be,bg,ca,cs,da,de,el,en,eo,es,et,eu,fi,fr,gd,gl,hu,id,it,ja,jbo,kk,ko,lt,lv,ms,nb,nl,nn,pl,pt,pt_BR,ro,ru,sk,sl,sr_Cyrl,sr_Latn,sv,sw,tr,uk,vi,zh_CN,zh_TW + +[**GUIs] + +# Scale GUI by a user specified value. +# Use a nearest-neighbor-anti-alias filter to scale the GUI. +# This will smooth over some of the rough edges, and blend +# pixels when scaling down, at the cost of blurring some +# edge pixels when images are scaled by non-integer sizes. +gui_scaling (GUI scaling) float 1.0 0.5 20 + +# Enables animation of inventory items. +inventory_items_animations (Inventory items animations) bool false + +# Formspec full-screen background opacity (between 0 and 255). +formspec_fullscreen_bg_opacity (Formspec Full-Screen Background Opacity) int 140 0 255 + +# Formspec full-screen background color (R,G,B). +formspec_fullscreen_bg_color (Formspec Full-Screen Background Color) string (0,0,0) + +# When gui_scaling_filter is true, all GUI images need to be +# filtered in software, but some images are generated directly +# to hardware (e.g. render-to-texture for nodes in inventory). +gui_scaling_filter (GUI scaling filter) bool false + +# When gui_scaling_filter_txr2img is true, copy those images +# from hardware to software for scaling. When false, fall back +# to the old scaling method, for video drivers that don't +# properly support downloading textures back from hardware. +gui_scaling_filter_txr2img (GUI scaling filter txr2img) bool true + +# Delay showing tooltips, stated in milliseconds. +tooltip_show_delay (Tooltip delay) int 400 0 18446744073709551615 + +# Append item name to tooltip. +tooltip_append_itemname (Append item name) bool false + +# Use a cloud animation for the main menu background. +menu_clouds (Clouds in menu) bool true + +[**HUD] + +# Modifies the size of the HUD elements. +hud_scaling (HUD scaling) float 1.0 0.5 20 + +# Whether name tag backgrounds should be shown by default. +# Mods may still set a background. +show_nametag_backgrounds (Show name tag backgrounds by default) bool true + +[**Chat] + +# Maximum number of recent chat messages to show +recent_chat_messages (Recent Chat Messages) int 6 2 20 + +# In-game chat console height, between 0.1 (10%) and 1.0 (100%). +console_height (Console height) float 0.6 0.1 1.0 + +# In-game chat console background color (R,G,B). +console_color (Console color) string (0,0,0) + +# In-game chat console background alpha (opaqueness, between 0 and 255). +console_alpha (Console alpha) int 200 0 255 + +# Maximum proportion of current window to be used for hotbar. +# Useful if there's something to be displayed right or left of hotbar. +hud_hotbar_max_width (Maximum hotbar width) float 1.0 0.001 1.0 + +# Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output. +clickable_chat_weblinks (Chat weblinks) bool true + +# Optional override for chat weblink color. +chat_weblink_color (Weblink color) string + +# Font size of the recent chat text and chat prompt in point (pt). +# Value 0 will use the default font size. +chat_font_size (Chat font size) int 0 0 72 + + +[**Content Repository] + +# The URL for the content repository +contentdb_url (ContentDB URL) string https://content.minetest.net + +# Comma-separated list of flags to hide in the content repository. +# "nonfree" can be used to hide packages which do not qualify as 'free software', +# as defined by the Free Software Foundation. +# You can also specify content ratings. +# These flags are independent from Minetest versions, +# so see a full list at https://content.minetest.net/help/content_flags/ +contentdb_flag_blacklist (ContentDB Flag Blacklist) string nonfree, desktop_default + +# Maximum number of concurrent downloads. Downloads exceeding this limit will be queued. +# This should be lower than curl_parallel_limit. +contentdb_max_concurrent_downloads (ContentDB Max Concurrent Downloads) int 3 1 + + +[Client and Server] + +[*Client] + +# Save the map received by the client on disk. +enable_local_map_saving (Saving map received from server) bool false + +# URL to the server list displayed in the Multiplayer Tab. +serverlist_url (Serverlist URL) string servers.minetest.net + +# If enabled, account registration is separate from login in the UI. +# If disabled, new accounts will be registered automatically when logging in. +enable_split_login_register (Enable split login/register) bool true + +# URL to JSON file which provides information about the newest Minetest release +update_information_url (Update information URL) string https://www.minetest.net/release_info.json + +# Unix timestamp (integer) of when the client last checked for an update +# Set this value to "disabled" to never check for updates. +update_last_checked (Last update check) string + +# Version number which was last seen during an update check. +# +# Representation: MMMIIIPPP, where M=Major, I=Minor, P=Patch +# Ex: 5.5.0 is 005005000 +update_last_known (Last known version update) int 0 + +[*Server] + +# Name of the player. +# When running a server, clients connecting with this name are admins. +# When starting from the main menu, this is overridden. +name (Admin name) string + +[**Serverlist and MOTD] + +# Name of the server, to be displayed when players join and in the serverlist. +server_name (Server name) string Minetest server + +# Description of server, to be displayed when players join and in the serverlist. +server_description (Server description) string mine here + +# Domain name of server, to be displayed in the serverlist. +server_address (Server address) string game.minetest.net + +# Homepage of server, to be displayed in the serverlist. +server_url (Server URL) string https://minetest.net + +# Automatically report to the serverlist. +server_announce (Announce server) bool false + +# Announce to this serverlist. +serverlist_url (Serverlist URL) string servers.minetest.net + +# Message of the day displayed to players connecting. +motd (Message of the day) string + +# Maximum number of players that can be connected simultaneously. +max_users (Maximum users) int 15 0 65535 + +# If this is set, players will always (re)spawn at the given position. +static_spawnpoint (Static spawnpoint) string + +[**Networking] + +# Network port to listen (UDP). +# This value will be overridden when starting from the main menu. +port (Server port) int 30000 1 65535 + +# The network interface that the server listens on. +bind_address (Bind address) string + +# Enable to disallow old clients from connecting. +# Older clients are compatible in the sense that they will not crash when connecting +# to new servers, but they may not support all new features that you are expecting. +strict_protocol_version_checking (Strict protocol checking) bool false + +# Specifies URL from which client fetches media instead of using UDP. +# $filename should be accessible from $remote_media$filename via cURL +# (obviously, remote_media should end with a slash). +# Files that are not present will be fetched the usual way. +remote_media (Remote media) string + +# Enable/disable running an IPv6 server. +# Ignored if bind_address is set. +# Needs enable_ipv6 to be enabled. +ipv6_server (IPv6 server) bool false + +[*Server Security] + +# New users need to input this password. +default_password (Default password) string + +# If enabled, players cannot join without a password or change theirs to an empty password. +disallow_empty_password (Disallow empty passwords) bool false + +# The privileges that new users automatically get. +# See /privs in game for a full list on your server and mod configuration. +default_privs (Default privileges) string interact, shout + +# Privileges that players with basic_privs can grant +basic_privs (Basic privileges) string interact, shout + +# If enabled, disable cheat prevention in multiplayer. +disable_anticheat (Disable anticheat) bool false + +# If enabled, actions are recorded for rollback. +# This option is only read when server starts. +enable_rollback_recording (Rollback recording) bool false + +[**Client-side Modding] + +# Restricts the access of certain client-side functions on servers. +# Combine the byteflags below to restrict client-side features, or set to 0 +# for no restrictions: +# LOAD_CLIENT_MODS: 1 (disable loading client-provided mods) +# CHAT_MESSAGES: 2 (disable send_chat_message call client-side) +# READ_ITEMDEFS: 4 (disable get_item_def call client-side) +# READ_NODEDEFS: 8 (disable get_node_def call client-side) +# LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to +# csm_restriction_noderange) +# READ_PLAYERINFO: 32 (disable get_player_names call client-side) +csm_restriction_flags (Client side modding restrictions) int 62 0 63 + +# If the CSM restriction for node range is enabled, get_node calls are limited +# to this distance from the player to the node. +csm_restriction_noderange (Client side node lookup range restriction) int 0 0 4294967295 + +[**Chat] + +# Remove color codes from incoming chat messages +# Use this to stop players from being able to use color in their messages +strip_color_codes (Strip color codes) bool false + +# Set the maximum length of a chat message (in characters) sent by clients. +chat_message_max_size (Chat message max length) int 500 10 65535 + +# Amount of messages a player may send per 10 seconds. +chat_message_limit_per_10sec (Chat message count limit) float 10.0 1.0 + +# Kick players who sent more than X messages per 10 seconds. +chat_message_limit_trigger_kick (Chat message kick threshold) int 50 1 65535 + +[*Server Gameplay] + +# Controls length of day/night cycle. +# Examples: +# 72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged. +time_speed (Time speed) int 72 0 + +# Time of day when a new world is started, in millihours (0-23999). +world_start_time (World start time) int 6125 0 23999 + +# Time in seconds for item entity (dropped items) to live. +# Setting it to -1 disables the feature. +item_entity_ttl (Item entity TTL) int 900 -1 + +# Specifies the default stack size of nodes, items and tools. +# Note that mods or games may explicitly set a stack for certain (or all) items. +default_stack_max (Default stack size) int 99 1 65535 + +[**Physics] + +# Horizontal and vertical acceleration on ground or when climbing, +# in nodes per second per second. +movement_acceleration_default (Default acceleration) float 3.0 0.0 + +# Horizontal acceleration in air when jumping or falling, +# in nodes per second per second. +movement_acceleration_air (Acceleration in air) float 2.0 0.0 + +# Horizontal and vertical acceleration in fast mode, +# in nodes per second per second. +movement_acceleration_fast (Fast mode acceleration) float 10.0 0.0 + +# Walking and flying speed, in nodes per second. +movement_speed_walk (Walking speed) float 4.0 0.0 + +# Sneaking speed, in nodes per second. +movement_speed_crouch (Sneaking speed) float 1.35 0.0 + +# Walking, flying and climbing speed in fast mode, in nodes per second. +movement_speed_fast (Fast mode speed) float 20.0 0.0 + +# Vertical climbing speed, in nodes per second. +movement_speed_climb (Climbing speed) float 3.0 0.0 + +# Initial vertical speed when jumping, in nodes per second. +movement_speed_jump (Jumping speed) float 6.5 0.0 + +# How much you are slowed down when moving inside a liquid. +# Decrease this to increase liquid resistance to movement. +movement_liquid_fluidity (Liquid fluidity) float 1.0 0.001 + +# Maximum liquid resistance. Controls deceleration when entering liquid at +# high speed. +movement_liquid_fluidity_smooth (Liquid fluidity smoothing) float 0.5 + +# Controls sinking speed in liquid when idling. Negative values will cause +# you to rise instead. +movement_liquid_sink (Liquid sinking) float 10.0 + +# Acceleration of gravity, in nodes per second per second. +movement_gravity (Gravity) float 9.81 + + +[Mapgen] + +# A chosen map seed for a new map, leave empty for random. +# Will be overridden when creating a new world in the main menu. +fixed_map_seed (Fixed map seed) string + +# Name of map generator to be used when creating a new world. +# Creating a world in the main menu will override this. +# Current mapgens in a highly unstable state: +# - The optional floatlands of v7 (disabled by default). +mg_name (Mapgen name) enum v7 v7,valleys,carpathian,v5,flat,fractal,singlenode,v6 + +# Water surface level of the world. +water_level (Water level) int 1 -31000 31000 + +# From how far blocks are generated for clients, stated in mapblocks (16 nodes). +max_block_generate_distance (Max block generate distance) int 10 1 32767 + +# Limit of map generation, in nodes, in all 6 directions from (0, 0, 0). +# Only mapchunks completely within the mapgen limit are generated. +# Value is stored per-world. +mapgen_limit (Map generation limit) int 31007 0 31007 + +# Global map generation attributes. +# In Mapgen v6 the 'decorations' flag controls all decorations except trees +# and jungle grass, in all other mapgens this flag controls all decorations. +mg_flags (Mapgen flags) flags caves,dungeons,light,decorations,biomes,ores caves,dungeons,light,decorations,biomes,ores,nocaves,nodungeons,nolight,nodecorations,nobiomes,noores + +[*Biome API noise parameters] + +# Temperature variation for biomes. +mg_biome_np_heat (Heat noise) noise_params_2d 50, 50, (1000, 1000, 1000), 5349, 3, 0.5, 2.0, eased + +# Small-scale temperature variation for blending biomes on borders. +mg_biome_np_heat_blend (Heat blend noise) noise_params_2d 0, 1.5, (8, 8, 8), 13, 2, 1.0, 2.0, eased + +# Humidity variation for biomes. +mg_biome_np_humidity (Humidity noise) noise_params_2d 50, 50, (1000, 1000, 1000), 842, 3, 0.5, 2.0, eased + +# Small-scale humidity variation for blending biomes on borders. +mg_biome_np_humidity_blend (Humidity blend noise) noise_params_2d 0, 1.5, (8, 8, 8), 90003, 2, 1.0, 2.0, eased + +[*Mapgen V5] + +# Map generation attributes specific to Mapgen v5. +mgv5_spflags (Mapgen V5 specific flags) flags caverns caverns,nocaverns + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +mgv5_cave_width (Cave width) float 0.09 + +# Y of upper limit of large caves. +mgv5_large_cave_depth (Large cave depth) int -256 -31000 31000 + +# Minimum limit of random number of small caves per mapchunk. +mgv5_small_cave_num_min (Small cave minimum number) int 0 0 256 + +# Maximum limit of random number of small caves per mapchunk. +mgv5_small_cave_num_max (Small cave maximum number) int 0 0 256 + +# Minimum limit of random number of large caves per mapchunk. +mgv5_large_cave_num_min (Large cave minimum number) int 0 0 64 + +# Maximum limit of random number of large caves per mapchunk. +mgv5_large_cave_num_max (Large cave maximum number) int 2 0 64 + +# Proportion of large caves that contain liquid. +mgv5_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 + +# Y-level of cavern upper limit. +mgv5_cavern_limit (Cavern limit) int -256 -31000 31000 + +# Y-distance over which caverns expand to full size. +mgv5_cavern_taper (Cavern taper) int 256 0 32767 + +# Defines full size of caverns, smaller values create larger caverns. +mgv5_cavern_threshold (Cavern threshold) float 0.7 + +# Lower Y limit of dungeons. +mgv5_dungeon_ymin (Dungeon minimum Y) int -31000 -31000 31000 + +# Upper Y limit of dungeons. +mgv5_dungeon_ymax (Dungeon maximum Y) int 31000 -31000 31000 + +[**Noises] + +# Variation of biome filler depth. +mgv5_np_filler_depth (Filler depth noise) noise_params_2d 0, 1, (150, 150, 150), 261, 4, 0.7, 2.0, eased + +# Variation of terrain vertical scale. +# When noise is < -0.55 terrain is near-flat. +mgv5_np_factor (Factor noise) noise_params_2d 0, 1, (250, 250, 250), 920381, 3, 0.45, 2.0, eased + +# Y-level of average terrain surface. +mgv5_np_height (Height noise) noise_params_2d 0, 10, (250, 250, 250), 84174, 4, 0.5, 2.0, eased + +# First of two 3D noises that together define tunnels. +mgv5_np_cave1 (Cave1 noise) noise_params_3d 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0 + +# Second of two 3D noises that together define tunnels. +mgv5_np_cave2 (Cave2 noise) noise_params_3d 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0 + +# 3D noise defining giant caverns. +mgv5_np_cavern (Cavern noise) noise_params_3d 0, 1, (384, 128, 384), 723, 5, 0.63, 2.0 + +# 3D noise defining terrain. +mgv5_np_ground (Ground noise) noise_params_3d 0, 40, (80, 80, 80), 983240, 4, 0.55, 2.0, eased + +# 3D noise that determines number of dungeons per mapchunk. +mgv5_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 500), 0, 2, 0.8, 2.0 + +[*Mapgen V6] + +# Map generation attributes specific to Mapgen v6. +# The 'snowbiomes' flag enables the new 5 biome system. +# When the 'snowbiomes' flag is enabled jungles are automatically enabled and +# the 'jungles' flag is ignored. +mgv6_spflags (Mapgen V6 specific flags) flags jungles,biomeblend,mudflow,snowbiomes,noflat,trees jungles,biomeblend,mudflow,snowbiomes,flat,trees,nojungles,nobiomeblend,nomudflow,nosnowbiomes,noflat,notrees + +# Deserts occur when np_biome exceeds this value. +# When the 'snowbiomes' flag is enabled, this is ignored. +mgv6_freq_desert (Desert noise threshold) float 0.45 + +# Sandy beaches occur when np_beach exceeds this value. +mgv6_freq_beach (Beach noise threshold) float 0.15 + +# Lower Y limit of dungeons. +mgv6_dungeon_ymin (Dungeon minimum Y) int -31000 -31000 31000 + +# Upper Y limit of dungeons. +mgv6_dungeon_ymax (Dungeon maximum Y) int 31000 -31000 31000 + +[**Noises] + +# Y-level of lower terrain and seabed. +mgv6_np_terrain_base (Terrain base noise) noise_params_2d -4, 20, (250, 250, 250), 82341, 5, 0.6, 2.0, eased + +# Y-level of higher terrain that creates cliffs. +mgv6_np_terrain_higher (Terrain higher noise) noise_params_2d 20, 16, (500, 500, 500), 85039, 5, 0.6, 2.0, eased + +# Varies steepness of cliffs. +mgv6_np_steepness (Steepness noise) noise_params_2d 0.85, 0.5, (125, 125, 125), -932, 5, 0.7, 2.0, eased + +# Defines distribution of higher terrain. +mgv6_np_height_select (Height select noise) noise_params_2d 0.5, 1, (250, 250, 250), 4213, 5, 0.69, 2.0, eased + +# Varies depth of biome surface nodes. +mgv6_np_mud (Mud noise) noise_params_2d 4, 2, (200, 200, 200), 91013, 3, 0.55, 2.0, eased + +# Defines areas with sandy beaches. +mgv6_np_beach (Beach noise) noise_params_2d 0, 1, (250, 250, 250), 59420, 3, 0.50, 2.0, eased + +# Temperature variation for biomes. +mgv6_np_biome (Biome noise) noise_params_2d 0, 1, (500, 500, 500), 9130, 3, 0.50, 2.0, eased + +# Variation of number of caves. +mgv6_np_cave (Cave noise) noise_params_2d 6, 6, (250, 250, 250), 34329, 3, 0.50, 2.0, eased + +# Humidity variation for biomes. +mgv6_np_humidity (Humidity noise) noise_params_2d 0.5, 0.5, (500, 500, 500), 72384, 3, 0.50, 2.0, eased + +# Defines tree areas and tree density. +mgv6_np_trees (Trees noise) noise_params_2d 0, 1, (125, 125, 125), 2, 4, 0.66, 2.0, eased + +# Defines areas where trees have apples. +mgv6_np_apple_trees (Apple trees noise) noise_params_2d 0, 1, (100, 100, 100), 342902, 3, 0.45, 2.0, eased + +[*Mapgen V7] + +# Map generation attributes specific to Mapgen v7. +# 'ridges': Rivers. +# 'floatlands': Floating land masses in the atmosphere. +# 'caverns': Giant caves deep underground. +mgv7_spflags (Mapgen V7 specific flags) flags mountains,ridges,nofloatlands,caverns mountains,ridges,floatlands,caverns,nomountains,noridges,nofloatlands,nocaverns + +# Y of mountain density gradient zero level. Used to shift mountains vertically. +mgv7_mount_zero_level (Mountain zero level) int 0 -31000 31000 + +# Lower Y limit of floatlands. +mgv7_floatland_ymin (Floatland minimum Y) int 1024 -31000 31000 + +# Upper Y limit of floatlands. +mgv7_floatland_ymax (Floatland maximum Y) int 4096 -31000 31000 + +# Y-distance over which floatlands taper from full density to nothing. +# Tapering starts at this distance from the Y limit. +# For a solid floatland layer, this controls the height of hills/mountains. +# Must be less than or equal to half the distance between the Y limits. +mgv7_floatland_taper (Floatland tapering distance) int 256 0 32767 + +# Exponent of the floatland tapering. Alters the tapering behaviour. +# Value = 1.0 creates a uniform, linear tapering. +# Values > 1.0 create a smooth tapering suitable for the default separated +# floatlands. +# Values < 1.0 (for example 0.25) create a more defined surface level with +# flatter lowlands, suitable for a solid floatland layer. +mgv7_float_taper_exp (Floatland taper exponent) float 2.0 + +# Adjusts the density of the floatland layer. +# Increase value to increase density. Can be positive or negative. +# Value = 0.0: 50% of volume is floatland. +# Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test +# to be sure) creates a solid floatland layer. +mgv7_floatland_density (Floatland density) float -0.6 + +# Surface level of optional water placed on a solid floatland layer. +# Water is disabled by default and will only be placed if this value is set +# to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the +# upper tapering). +# ***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***: +# When enabling water placement the floatlands must be configured and tested +# to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other +# required value depending on 'mgv7_np_floatland'), to avoid +# server-intensive extreme water flow and to avoid vast flooding of the +# world surface below. +mgv7_floatland_ywater (Floatland water level) int -31000 -31000 31000 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +mgv7_cave_width (Cave width) float 0.09 + +# Y of upper limit of large caves. +mgv7_large_cave_depth (Large cave depth) int -33 -31000 31000 + +# Minimum limit of random number of small caves per mapchunk. +mgv7_small_cave_num_min (Small cave minimum number) int 0 0 256 + +# Maximum limit of random number of small caves per mapchunk. +mgv7_small_cave_num_max (Small cave maximum number) int 0 0 256 + +# Minimum limit of random number of large caves per mapchunk. +mgv7_large_cave_num_min (Large cave minimum number) int 0 0 64 + +# Maximum limit of random number of large caves per mapchunk. +mgv7_large_cave_num_max (Large cave maximum number) int 2 0 64 + +# Proportion of large caves that contain liquid. +mgv7_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 + +# Y-level of cavern upper limit. +mgv7_cavern_limit (Cavern limit) int -256 -31000 31000 + +# Y-distance over which caverns expand to full size. +mgv7_cavern_taper (Cavern taper) int 256 0 32767 + +# Defines full size of caverns, smaller values create larger caverns. +mgv7_cavern_threshold (Cavern threshold) float 0.7 + +# Lower Y limit of dungeons. +mgv7_dungeon_ymin (Dungeon minimum Y) int -31000 -31000 31000 + +# Upper Y limit of dungeons. +mgv7_dungeon_ymax (Dungeon maximum Y) int 31000 -31000 31000 + +[**Noises] + +# Y-level of higher terrain that creates cliffs. +mgv7_np_terrain_base (Terrain base noise) noise_params_2d 4, 70, (600, 600, 600), 82341, 5, 0.6, 2.0, eased + +# Y-level of lower terrain and seabed. +mgv7_np_terrain_alt (Terrain alternative noise) noise_params_2d 4, 25, (600, 600, 600), 5934, 5, 0.6, 2.0, eased + +# Varies roughness of terrain. +# Defines the 'persistence' value for terrain_base and terrain_alt noises. +mgv7_np_terrain_persist (Terrain persistence noise) noise_params_2d 0.6, 0.1, (2000, 2000, 2000), 539, 3, 0.6, 2.0, eased + +# Defines distribution of higher terrain and steepness of cliffs. +mgv7_np_height_select (Height select noise) noise_params_2d -8, 16, (500, 500, 500), 4213, 6, 0.7, 2.0, eased + +# Variation of biome filler depth. +mgv7_np_filler_depth (Filler depth noise) noise_params_2d 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0, eased + +# Variation of maximum mountain height (in nodes). +mgv7_np_mount_height (Mountain height noise) noise_params_2d 256, 112, (1000, 1000, 1000), 72449, 3, 0.6, 2.0, eased + +# Defines large-scale river channel structure. +mgv7_np_ridge_uwater (Ridge underwater noise) noise_params_2d 0, 1, (1000, 1000, 1000), 85039, 5, 0.6, 2.0, eased + +# 3D noise defining mountain structure and height. +# Also defines structure of floatland mountain terrain. +mgv7_np_mountain (Mountain noise) noise_params_3d -0.6, 1, (250, 350, 250), 5333, 5, 0.63, 2.0 + +# 3D noise defining structure of river canyon walls. +mgv7_np_ridge (Ridge noise) noise_params_3d 0, 1, (100, 100, 100), 6467, 4, 0.75, 2.0 + +# 3D noise defining structure of floatlands. +# If altered from the default, the noise 'scale' (0.7 by default) may need +# to be adjusted, as floatland tapering functions best when this noise has +# a value range of approximately -2.0 to 2.0. +mgv7_np_floatland (Floatland noise) noise_params_3d 0, 0.7, (384, 96, 384), 1009, 4, 0.75, 1.618 + +# 3D noise defining giant caverns. +mgv7_np_cavern (Cavern noise) noise_params_3d 0, 1, (384, 128, 384), 723, 5, 0.63, 2.0 + +# First of two 3D noises that together define tunnels. +mgv7_np_cave1 (Cave1 noise) noise_params_3d 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0 + +# Second of two 3D noises that together define tunnels. +mgv7_np_cave2 (Cave2 noise) noise_params_3d 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0 + +# 3D noise that determines number of dungeons per mapchunk. +mgv7_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 500), 0, 2, 0.8, 2.0 + +[*Mapgen Carpathian] + +# Map generation attributes specific to Mapgen Carpathian. +mgcarpathian_spflags (Mapgen Carpathian specific flags) flags caverns,norivers caverns,rivers,nocaverns,norivers + +# Defines the base ground level. +mgcarpathian_base_level (Base ground level) float 12.0 + +# Defines the width of the river channel. +mgcarpathian_river_width (River channel width) float 0.05 + +# Defines the depth of the river channel. +mgcarpathian_river_depth (River channel depth) float 24.0 + +# Defines the width of the river valley. +mgcarpathian_valley_width (River valley width) float 0.25 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +mgcarpathian_cave_width (Cave width) float 0.09 + +# Y of upper limit of large caves. +mgcarpathian_large_cave_depth (Large cave depth) int -33 -31000 31000 + +# Minimum limit of random number of small caves per mapchunk. +mgcarpathian_small_cave_num_min (Small cave minimum number) int 0 0 256 + +# Maximum limit of random number of small caves per mapchunk. +mgcarpathian_small_cave_num_max (Small cave maximum number) int 0 0 256 + +# Minimum limit of random number of large caves per mapchunk. +mgcarpathian_large_cave_num_min (Large cave minimum number) int 0 0 64 + +# Maximum limit of random number of large caves per mapchunk. +mgcarpathian_large_cave_num_max (Large cave maximum number) int 2 0 64 + +# Proportion of large caves that contain liquid. +mgcarpathian_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 + +# Y-level of cavern upper limit. +mgcarpathian_cavern_limit (Cavern limit) int -256 -31000 31000 + +# Y-distance over which caverns expand to full size. +mgcarpathian_cavern_taper (Cavern taper) int 256 0 32767 + +# Defines full size of caverns, smaller values create larger caverns. +mgcarpathian_cavern_threshold (Cavern threshold) float 0.7 + +# Lower Y limit of dungeons. +mgcarpathian_dungeon_ymin (Dungeon minimum Y) int -31000 -31000 31000 + +# Upper Y limit of dungeons. +mgcarpathian_dungeon_ymax (Dungeon maximum Y) int 31000 -31000 31000 + +[**Noises] + +# Variation of biome filler depth. +mgcarpathian_np_filler_depth (Filler depth noise) noise_params_2d 0, 1, (128, 128, 128), 261, 3, 0.7, 2.0, eased + +# First of 4 2D noises that together define hill/mountain range height. +mgcarpathian_np_height1 (Hilliness1 noise) noise_params_2d 0, 5, (251, 251, 251), 9613, 5, 0.5, 2.0, eased + +# Second of 4 2D noises that together define hill/mountain range height. +mgcarpathian_np_height2 (Hilliness2 noise) noise_params_2d 0, 5, (383, 383, 383), 1949, 5, 0.5, 2.0, eased + +# Third of 4 2D noises that together define hill/mountain range height. +mgcarpathian_np_height3 (Hilliness3 noise) noise_params_2d 0, 5, (509, 509, 509), 3211, 5, 0.5, 2.0, eased + +# Fourth of 4 2D noises that together define hill/mountain range height. +mgcarpathian_np_height4 (Hilliness4 noise) noise_params_2d 0, 5, (631, 631, 631), 1583, 5, 0.5, 2.0, eased + +# 2D noise that controls the size/occurrence of rolling hills. +mgcarpathian_np_hills_terrain (Rolling hills spread noise) noise_params_2d 1, 1, (1301, 1301, 1301), 1692, 3, 0.5, 2.0, eased + +# 2D noise that controls the size/occurrence of ridged mountain ranges. +mgcarpathian_np_ridge_terrain (Ridge mountain spread noise) noise_params_2d 1, 1, (1889, 1889, 1889), 3568, 3, 0.5, 2.0, eased + +# 2D noise that controls the size/occurrence of step mountain ranges. +mgcarpathian_np_step_terrain (Step mountain spread noise) noise_params_2d 1, 1, (1889, 1889, 1889), 4157, 3, 0.5, 2.0, eased + +# 2D noise that controls the shape/size of rolling hills. +mgcarpathian_np_hills (Rolling hill size noise) noise_params_2d 0, 3, (257, 257, 257), 6604, 6, 0.5, 2.0, eased + +# 2D noise that controls the shape/size of ridged mountains. +mgcarpathian_np_ridge_mnt (Ridged mountain size noise) noise_params_2d 0, 12, (743, 743, 743), 5520, 6, 0.7, 2.0, eased + +# 2D noise that controls the shape/size of step mountains. +mgcarpathian_np_step_mnt (Step mountain size noise) noise_params_2d 0, 8, (509, 509, 509), 2590, 6, 0.6, 2.0, eased + +# 2D noise that locates the river valleys and channels. +mgcarpathian_np_rivers (River noise) noise_params_2d 0, 1, (1000, 1000, 1000), 85039, 5, 0.6, 2.0, eased + +# 3D noise for mountain overhangs, cliffs, etc. Usually small variations. +mgcarpathian_np_mnt_var (Mountain variation noise) noise_params_3d 0, 1, (499, 499, 499), 2490, 5, 0.55, 2.0 + +# First of two 3D noises that together define tunnels. +mgcarpathian_np_cave1 (Cave1 noise) noise_params_3d 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0 + +# Second of two 3D noises that together define tunnels. +mgcarpathian_np_cave2 (Cave2 noise) noise_params_3d 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0 + +# 3D noise defining giant caverns. +mgcarpathian_np_cavern (Cavern noise) noise_params_3d 0, 1, (384, 128, 384), 723, 5, 0.63, 2.0 + +# 3D noise that determines number of dungeons per mapchunk. +mgcarpathian_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 500), 0, 2, 0.8, 2.0 + +[*Mapgen Flat] + +# Map generation attributes specific to Mapgen Flat. +# Occasional lakes and hills can be added to the flat world. +mgflat_spflags (Mapgen Flat specific flags) flags nolakes,nohills,nocaverns lakes,hills,caverns,nolakes,nohills,nocaverns + +# Y of flat ground. +mgflat_ground_level (Ground level) int 8 -31000 31000 + +# Y of upper limit of large caves. +mgflat_large_cave_depth (Large cave depth) int -33 -31000 31000 + +# Minimum limit of random number of small caves per mapchunk. +mgflat_small_cave_num_min (Small cave minimum number) int 0 0 256 + +# Maximum limit of random number of small caves per mapchunk. +mgflat_small_cave_num_max (Small cave maximum number) int 0 0 256 + +# Minimum limit of random number of large caves per mapchunk. +mgflat_large_cave_num_min (Large cave minimum number) int 0 0 64 + +# Maximum limit of random number of large caves per mapchunk. +mgflat_large_cave_num_max (Large cave maximum number) int 2 0 64 + +# Proportion of large caves that contain liquid. +mgflat_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +mgflat_cave_width (Cave width) float 0.09 + +# Terrain noise threshold for lakes. +# Controls proportion of world area covered by lakes. +# Adjust towards 0.0 for a larger proportion. +mgflat_lake_threshold (Lake threshold) float -0.45 + +# Controls steepness/depth of lake depressions. +mgflat_lake_steepness (Lake steepness) float 48.0 + +# Terrain noise threshold for hills. +# Controls proportion of world area covered by hills. +# Adjust towards 0.0 for a larger proportion. +mgflat_hill_threshold (Hill threshold) float 0.45 + +# Controls steepness/height of hills. +mgflat_hill_steepness (Hill steepness) float 64.0 + +# Y-level of cavern upper limit. +mgflat_cavern_limit (Cavern limit) int -256 -31000 31000 + +# Y-distance over which caverns expand to full size. +mgflat_cavern_taper (Cavern taper) int 256 0 32767 + +# Defines full size of caverns, smaller values create larger caverns. +mgflat_cavern_threshold (Cavern threshold) float 0.7 + +# Lower Y limit of dungeons. +mgflat_dungeon_ymin (Dungeon minimum Y) int -31000 -31000 31000 + +# Upper Y limit of dungeons. +mgflat_dungeon_ymax (Dungeon maximum Y) int 31000 -31000 31000 + +[**Noises] + +# Defines location and terrain of optional hills and lakes. +mgflat_np_terrain (Terrain noise) noise_params_2d 0, 1, (600, 600, 600), 7244, 5, 0.6, 2.0, eased + +# Variation of biome filler depth. +mgflat_np_filler_depth (Filler depth noise) noise_params_2d 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0, eased + +# First of two 3D noises that together define tunnels. +mgflat_np_cave1 (Cave1 noise) noise_params_3d 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0 + +# Second of two 3D noises that together define tunnels. +mgflat_np_cave2 (Cave2 noise) noise_params_3d 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0 + +# 3D noise defining giant caverns. +mgflat_np_cavern (Cavern noise) noise_params_3d 0, 1, (384, 128, 384), 723, 5, 0.63, 2.0 + +# 3D noise that determines number of dungeons per mapchunk. +mgflat_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 500), 0, 2, 0.8, 2.0 + +[*Mapgen Fractal] + +# Map generation attributes specific to Mapgen Fractal. +# 'terrain' enables the generation of non-fractal terrain: +# ocean, islands and underground. +mgfractal_spflags (Mapgen Fractal specific flags) flags terrain terrain,noterrain + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +mgfractal_cave_width (Cave width) float 0.09 + +# Y of upper limit of large caves. +mgfractal_large_cave_depth (Large cave depth) int -33 -31000 31000 + +# Minimum limit of random number of small caves per mapchunk. +mgfractal_small_cave_num_min (Small cave minimum number) int 0 0 256 + +# Maximum limit of random number of small caves per mapchunk. +mgfractal_small_cave_num_max (Small cave maximum number) int 0 0 256 + +# Minimum limit of random number of large caves per mapchunk. +mgfractal_large_cave_num_min (Large cave minimum number) int 0 0 64 + +# Maximum limit of random number of large caves per mapchunk. +mgfractal_large_cave_num_max (Large cave maximum number) int 2 0 64 + +# Proportion of large caves that contain liquid. +mgfractal_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 + +# Lower Y limit of dungeons. +mgfractal_dungeon_ymin (Dungeon minimum Y) int -31000 -31000 31000 + +# Upper Y limit of dungeons. +mgfractal_dungeon_ymax (Dungeon maximum Y) int 31000 -31000 31000 + +# Selects one of 18 fractal types. +# 1 = 4D "Roundy" Mandelbrot set. +# 2 = 4D "Roundy" Julia set. +# 3 = 4D "Squarry" Mandelbrot set. +# 4 = 4D "Squarry" Julia set. +# 5 = 4D "Mandy Cousin" Mandelbrot set. +# 6 = 4D "Mandy Cousin" Julia set. +# 7 = 4D "Variation" Mandelbrot set. +# 8 = 4D "Variation" Julia set. +# 9 = 3D "Mandelbrot/Mandelbar" Mandelbrot set. +# 10 = 3D "Mandelbrot/Mandelbar" Julia set. +# 11 = 3D "Christmas Tree" Mandelbrot set. +# 12 = 3D "Christmas Tree" Julia set. +# 13 = 3D "Mandelbulb" Mandelbrot set. +# 14 = 3D "Mandelbulb" Julia set. +# 15 = 3D "Cosine Mandelbulb" Mandelbrot set. +# 16 = 3D "Cosine Mandelbulb" Julia set. +# 17 = 4D "Mandelbulb" Mandelbrot set. +# 18 = 4D "Mandelbulb" Julia set. +mgfractal_fractal (Fractal type) int 1 1 18 + +# Iterations of the recursive function. +# Increasing this increases the amount of fine detail, but also +# increases processing load. +# At iterations = 20 this mapgen has a similar load to mapgen V7. +mgfractal_iterations (Iterations) int 11 1 65535 + +# (X,Y,Z) scale of fractal in nodes. +# Actual fractal size will be 2 to 3 times larger. +# These numbers can be made very large, the fractal does +# not have to fit inside the world. +# Increase these to 'zoom' into the detail of the fractal. +# Default is for a vertically-squashed shape suitable for +# an island, set all 3 numbers equal for the raw shape. +mgfractal_scale (Scale) v3f (4096.0, 1024.0, 4096.0) + +# (X,Y,Z) offset of fractal from world center in units of 'scale'. +# Can be used to move a desired point to (0, 0) to create a +# suitable spawn point, or to allow 'zooming in' on a desired +# point by increasing 'scale'. +# The default is tuned for a suitable spawn point for Mandelbrot +# sets with default parameters, it may need altering in other +# situations. +# Range roughly -2 to 2. Multiply by 'scale' for offset in nodes. +mgfractal_offset (Offset) v3f (1.79, 0.0, 0.0) + +# W coordinate of the generated 3D slice of a 4D fractal. +# Determines which 3D slice of the 4D shape is generated. +# Alters the shape of the fractal. +# Has no effect on 3D fractals. +# Range roughly -2 to 2. +mgfractal_slice_w (Slice w) float 0.0 + +# Julia set only. +# X component of hypercomplex constant. +# Alters the shape of the fractal. +# Range roughly -2 to 2. +mgfractal_julia_x (Julia x) float 0.33 + +# Julia set only. +# Y component of hypercomplex constant. +# Alters the shape of the fractal. +# Range roughly -2 to 2. +mgfractal_julia_y (Julia y) float 0.33 + +# Julia set only. +# Z component of hypercomplex constant. +# Alters the shape of the fractal. +# Range roughly -2 to 2. +mgfractal_julia_z (Julia z) float 0.33 + +# Julia set only. +# W component of hypercomplex constant. +# Alters the shape of the fractal. +# Has no effect on 3D fractals. +# Range roughly -2 to 2. +mgfractal_julia_w (Julia w) float 0.33 + +[**Noises] + +# Y-level of seabed. +mgfractal_np_seabed (Seabed noise) noise_params_2d -14, 9, (600, 600, 600), 41900, 5, 0.6, 2.0, eased + +# Variation of biome filler depth. +mgfractal_np_filler_depth (Filler depth noise) noise_params_2d 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0, eased + +# First of two 3D noises that together define tunnels. +mgfractal_np_cave1 (Cave1 noise) noise_params_3d 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0 + +# Second of two 3D noises that together define tunnels. +mgfractal_np_cave2 (Cave2 noise) noise_params_3d 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0 + +# 3D noise that determines number of dungeons per mapchunk. +mgfractal_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 500), 0, 2, 0.8, 2.0 + +[*Mapgen Valleys] + +# Map generation attributes specific to Mapgen Valleys. +# 'altitude_chill': Reduces heat with altitude. +# 'humid_rivers': Increases humidity around rivers. +# 'vary_river_depth': If enabled, low humidity and high heat causes rivers +# to become shallower and occasionally dry. +# 'altitude_dry': Reduces humidity with altitude. +mgvalleys_spflags (Mapgen Valleys specific flags) flags altitude_chill,humid_rivers,vary_river_depth,altitude_dry altitude_chill,humid_rivers,vary_river_depth,altitude_dry,noaltitude_chill,nohumid_rivers,novary_river_depth,noaltitude_dry + +# The vertical distance over which heat drops by 20 if 'altitude_chill' is +# enabled. Also the vertical distance over which humidity drops by 10 if +# 'altitude_dry' is enabled. +mgvalleys_altitude_chill (Altitude chill) int 90 0 65535 + +# Depth below which you'll find large caves. +mgvalleys_large_cave_depth (Large cave depth) int -33 -31000 31000 + +# Minimum limit of random number of small caves per mapchunk. +mgvalleys_small_cave_num_min (Small cave minimum number) int 0 0 256 + +# Maximum limit of random number of small caves per mapchunk. +mgvalleys_small_cave_num_max (Small cave maximum number) int 0 0 256 + +# Minimum limit of random number of large caves per mapchunk. +mgvalleys_large_cave_num_min (Large cave minimum number) int 0 0 64 + +# Maximum limit of random number of large caves per mapchunk. +mgvalleys_large_cave_num_max (Large cave maximum number) int 2 0 64 + +# Proportion of large caves that contain liquid. +mgvalleys_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 + +# Depth below which you'll find giant caverns. +mgvalleys_cavern_limit (Cavern upper limit) int -256 -31000 31000 + +# Y-distance over which caverns expand to full size. +mgvalleys_cavern_taper (Cavern taper) int 192 0 32767 + +# Defines full size of caverns, smaller values create larger caverns. +mgvalleys_cavern_threshold (Cavern threshold) float 0.6 + +# How deep to make rivers. +mgvalleys_river_depth (River depth) int 4 0 65535 + +# How wide to make rivers. +mgvalleys_river_size (River size) int 5 0 65535 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +mgvalleys_cave_width (Cave width) float 0.09 + +# Lower Y limit of dungeons. +mgvalleys_dungeon_ymin (Dungeon minimum Y) int -31000 -31000 31000 + +# Upper Y limit of dungeons. +mgvalleys_dungeon_ymax (Dungeon maximum Y) int 63 -31000 31000 + +[**Noises] + +# First of two 3D noises that together define tunnels. +mgvalleys_np_cave1 (Cave noise #1) noise_params_3d 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0 + +# Second of two 3D noises that together define tunnels. +mgvalleys_np_cave2 (Cave noise #2) noise_params_3d 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0 + +# The depth of dirt or other biome filler node. +mgvalleys_np_filler_depth (Filler depth) noise_params_2d 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0, eased + +# 3D noise defining giant caverns. +mgvalleys_np_cavern (Cavern noise) noise_params_3d 0, 1, (768, 256, 768), 59033, 6, 0.63, 2.0 + +# Defines large-scale river channel structure. +mgvalleys_np_rivers (River noise) noise_params_2d 0, 1, (256, 256, 256), -6050, 5, 0.6, 2.0, eased + +# Base terrain height. +mgvalleys_np_terrain_height (Terrain height) noise_params_2d -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0, eased + +# Raises terrain to make valleys around the rivers. +mgvalleys_np_valley_depth (Valley depth) noise_params_2d 5, 4, (512, 512, 512), -1914, 1, 1.0, 2.0, eased + +# Slope and fill work together to modify the heights. +mgvalleys_np_inter_valley_fill (Valley fill) noise_params_3d 0, 1, (256, 512, 256), 1993, 6, 0.8, 2.0 + +# Amplifies the valleys. +mgvalleys_np_valley_profile (Valley profile) noise_params_2d 0.6, 0.5, (512, 512, 512), 777, 1, 1.0, 2.0, eased + +# Slope and fill work together to modify the heights. +mgvalleys_np_inter_valley_slope (Valley slope) noise_params_2d 0.5, 0.5, (128, 128, 128), 746, 1, 1.0, 2.0, eased + +# 3D noise that determines number of dungeons per mapchunk. +mgvalleys_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 500), 0, 2, 0.8, 2.0 + + +[Advanced] + +[*Developer Options] + +# Enable Lua modding support on client. +# This support is experimental and API can change. +enable_client_modding (Client modding) bool false + +# Replaces the default main menu with a custom one. +main_menu_script (Main menu script) string + +[**Mod Security] + +# Prevent mods from doing insecure things like running shell commands. +secure.enable_security (Enable mod security) bool true + +# Comma-separated list of trusted mods that are allowed to access insecure +# functions even when mod security is on (via request_insecure_environment()). +secure.trusted_mods (Trusted mods) string + +# Comma-separated list of mods that are allowed to access HTTP APIs, which +# allow them to upload and download data to/from the internet. +secure.http_mods (HTTP mods) string + +[**Debugging] + +# Level of logging to be written to debug.txt: +# - <nothing> (no logging) +# - none (messages with no level) +# - error +# - warning +# - action +# - info +# - verbose +# - trace +debug_log_level (Debug log level) enum action ,none,error,warning,action,info,verbose,trace + +# If the file size of debug.txt exceeds the number of megabytes specified in +# this setting when it is opened, the file is moved to debug.txt.1, +# deleting an older debug.txt.1 if it exists. +# debug.txt is only moved if this setting is positive. +debug_log_size_max (Debug log file size threshold) int 50 1 + +# Minimal level of logging to be written to chat. +chat_log_level (Chat log level) enum error ,none,error,warning,action,info,verbose,trace + +# Handling for deprecated Lua API calls: +# - none: Do not log deprecated calls +# - log: mimic and log backtrace of deprecated call (default). +# - error: abort on usage of deprecated call (suggested for mod developers). +deprecated_lua_api_handling (Deprecated Lua API handling) enum log none,log,error + +# Enable random user input (only used for testing). +random_input (Random input) bool false + +# Enable mod channels support. +enable_mod_channels (Mod channels) bool false + +[**Mod Profiler] + +# Load the game profiler to collect game profiling data. +# Provides a /profiler command to access the compiled profile. +# Useful for mod developers and server operators. +profiler.load (Load the game profiler) bool false + +# The default format in which profiles are being saved, +# when calling `/profiler save [format]` without format. +profiler.default_report_format (Default report format) enum txt txt,csv,lua,json,json_pretty + +# The file path relative to your worldpath in which profiles will be saved to. +profiler.report_path (Report path) string "" + +# Instrument the methods of entities on registration. +instrument.entity (Entity methods) bool true + +# Instrument the action function of Active Block Modifiers on registration. +instrument.abm (Active Block Modifiers) bool true + +# Instrument the action function of Loading Block Modifiers on registration. +instrument.lbm (Loading Block Modifiers) bool true + +# Instrument chat commands on registration. +instrument.chatcommand (Chat commands) bool true + +# Instrument global callback functions on registration. +# (anything you pass to a minetest.register_*() function) +instrument.global_callback (Global callbacks) bool true + +# Instrument builtin. +# This is usually only needed by core/builtin contributors +instrument.builtin (Builtin) bool false + +# Have the profiler instrument itself: +# * Instrument an empty function. +# This estimates the overhead, that instrumentation is adding (+1 function call). +# * Instrument the sampler being used to update the statistics. +instrument.profiler (Profiler) bool false + +[**Engine profiler] + +# Print the engine's profiling data in regular intervals (in seconds). +# 0 = disable. Useful for developers. +profiler_print_interval (Engine profiling data print interval) int 0 0 + + +[*Advanced] + +# Enable IPv6 support (for both client and server). +# Required for IPv6 connections to work at all. +enable_ipv6 (IPv6) bool true + +# If enabled, invalid world data won't cause the server to shut down. +# Only enable this if you know what you are doing. +ignore_world_load_errors (Ignore world errors) bool false + +[**Graphics] + +# Path to shader directory. If no path is defined, default location will be used. +shader_path (Shader path) path + +# The rendering back-end. +# A restart is required after changing this. +# Note: On Android, stick with OGLES1 if unsure! App may fail to start otherwise. +# On other platforms, OpenGL is recommended. +# Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental) +video_driver (Video driver) enum opengl opengl,ogles1,ogles2 + +# Distance in nodes at which transparency depth sorting is enabled +# Use this to limit the performance impact of transparency depth sorting +transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128 + +# Enable vertex buffer objects. +# This should greatly improve graphics performance. +enable_vbo (VBO) bool true + +# Radius of cloud area stated in number of 64 node cloud squares. +# Values larger than 26 will start to produce sharp cutoffs at cloud area corners. +cloud_radius (Cloud radius) int 12 1 62 + +# Whether node texture animations should be desynchronized per mapblock. +desynchronize_mapblock_texture_animation (Desynchronize block animation) bool true + +# Enables caching of facedir rotated meshes. +enable_mesh_cache (Mesh cache) bool false + +# Delay between mesh updates on the client in ms. Increasing this will slow +# down the rate of mesh updates, thus reducing jitter on slower clients. +mesh_generation_interval (Mapblock mesh generation delay) int 0 0 50 + +# Size of the MapBlock cache of the mesh generator. Increasing this will +# increase the cache hit %, reducing the data being copied from the main +# thread, thus reducing jitter. +meshgen_block_cache_size (Mapblock mesh generator's MapBlock cache size in MB) int 20 0 1000 + +# True = 256 +# False = 128 +# Usable to make minimap smoother on slower machines. +minimap_double_scan_height (Minimap scan height) bool true + +# Textures on a node may be aligned either to the node or to the world. +# The former mode suits better things like machines, furniture, etc., while +# the latter makes stairs and microblocks fit surroundings better. +# However, as this possibility is new, thus may not be used by older servers, +# this option allows enforcing it for certain node types. Note though that +# that is considered EXPERIMENTAL and may not work properly. +world_aligned_mode (World-aligned textures mode) enum enable disable,enable,force_solid,force_nodebox + +# World-aligned textures may be scaled to span several nodes. However, +# the server may not send the scale you want, especially if you use +# a specially-designed texture pack; with this option, the client tries +# to determine the scale automatically basing on the texture size. +# See also texture_min_size. +# Warning: This option is EXPERIMENTAL! +autoscale_mode (Autoscaling mode) enum disable disable,enable,force + +[**Font] + +font_bold (Font bold by default) bool false + +font_italic (Font italic by default) bool false + +# Shadow offset (in pixels) of the default font. If 0, then shadow will not be drawn. +font_shadow (Font shadow) int 1 0 65535 + +# Opaqueness (alpha) of the shadow behind the default font, between 0 and 255. +font_shadow_alpha (Font shadow alpha) int 127 0 255 + +# Font size of the default font where 1 unit = 1 pixel at 96 DPI +font_size (Font size) int 16 5 72 + +# For pixel-style fonts that do not scale well, this ensures that font sizes used +# with this font will always be divisible by this value, in pixels. For instance, +# a pixel font 16 pixels tall should have this set to 16, so it will only ever be +# sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32. +font_size_divisible_by (Font size divisible by) int 1 1 + +# Path to the default font. Must be a TrueType font. +# The fallback font will be used if the font cannot be loaded. +font_path (Regular font path) filepath fonts/Arimo-Regular.ttf + +font_path_bold (Bold font path) filepath fonts/Arimo-Bold.ttf +font_path_italic (Italic font path) filepath fonts/Arimo-Italic.ttf +font_path_bold_italic (Bold and italic font path) filepath fonts/Arimo-BoldItalic.ttf + +# Font size of the monospace font where 1 unit = 1 pixel at 96 DPI +mono_font_size (Monospace font size) int 16 5 72 + +# For pixel-style fonts that do not scale well, this ensures that font sizes used +# with this font will always be divisible by this value, in pixels. For instance, +# a pixel font 16 pixels tall should have this set to 16, so it will only ever be +# sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32. +mono_font_size_divisible_by (Monospace font size divisible by) int 1 1 + +# Path to the monospace font. Must be a TrueType font. +# This font is used for e.g. the console and profiler screen. +mono_font_path (Monospace font path) filepath fonts/Cousine-Regular.ttf + +mono_font_path_bold (Bold monospace font path) filepath fonts/Cousine-Bold.ttf +mono_font_path_italic (Italic monospace font path) filepath fonts/Cousine-Italic.ttf +mono_font_path_bold_italic (Bold and italic monospace font path) filepath fonts/Cousine-BoldItalic.ttf + +# Path of the fallback font. Must be a TrueType font. +# This font will be used for certain languages or if the default font is unavailable. +fallback_font_path (Fallback font path) filepath fonts/DroidSansFallbackFull.ttf + +[**Lighting] + +# Gradient of light curve at minimum light level. +# Controls the contrast of the lowest light levels. +lighting_alpha (Light curve low gradient) float 0.0 0.0 3.0 + +# Gradient of light curve at maximum light level. +# Controls the contrast of the highest light levels. +lighting_beta (Light curve high gradient) float 1.5 0.0 3.0 + +# Strength of light curve boost. +# The 3 'boost' parameters define a range of the light +# curve that is boosted in brightness. +lighting_boost (Light curve boost) float 0.2 0.0 0.4 + +# Center of light curve boost range. +# Where 0.0 is minimum light level, 1.0 is maximum light level. +lighting_boost_center (Light curve boost center) float 0.5 0.0 1.0 + +# Spread of light curve boost range. +# Controls the width of the range to be boosted. +# Standard deviation of the light curve boost Gaussian. +lighting_boost_spread (Light curve boost spread) float 0.2 0.0 0.4 + +[**Networking] + +# Prometheus listener address. +# If Minetest is compiled with ENABLE_PROMETHEUS option enabled, +# enable metrics listener for Prometheus on that address. +# Metrics can be fetched on http://127.0.0.1:30000/metrics +prometheus_listener_address (Prometheus listener address) string 127.0.0.1:30000 + +# Maximum size of the out chat queue. +# 0 to disable queueing and -1 to make the queue size unlimited. +max_out_chat_queue_size (Maximum size of the out chat queue) int 20 -1 32767 + +# Timeout for client to remove unused map data from memory, in seconds. +client_unload_unused_data_timeout (Mapblock unload timeout) float 600.0 0.0 + +# Maximum number of mapblocks for client to be kept in memory. +# Set to -1 for unlimited amount. +client_mapblock_limit (Mapblock limit) int 7500 -1 2147483647 + +# Whether to show the client debug info (has the same effect as hitting F5). +show_debug (Show debug info) bool false + +# Maximum number of blocks that are simultaneously sent per client. +# The maximum total count is calculated dynamically: +# max_total = ceil((#clients + max_users) * per_client / 4) +max_simultaneous_block_sends_per_client (Maximum simultaneous block sends per client) int 40 1 4294967295 + +# To reduce lag, block transfers are slowed down when a player is building something. +# This determines how long they are slowed down after placing or removing a node. +full_block_send_enable_min_time_from_building (Delay in sending blocks after building) float 2.0 0.0 + +# Maximum number of packets sent per send step, if you have a slow connection +# try reducing it, but don't reduce it to a number below double of targeted +# client number. +max_packets_per_iteration (Max. packets per iteration) int 1024 1 65535 + +# Compression level to use when sending mapblocks to the client. +# -1 - use default compression level +# 0 - least compression, fastest +# 9 - best compression, slowest +map_compression_level_net (Map Compression Level for Network Transfer) int -1 -1 9 + +[**Server] + +# Format of player chat messages. The following strings are valid placeholders: +# @name, @message, @timestamp (optional) +chat_message_format (Chat message format) string <@name> @message + +# If the execution of a chat command takes longer than this specified time in +# seconds, add the time information to the chat command message +chatcommand_msg_time_threshold (Chat command time message threshold) float 0.1 0.0 + +# A message to be displayed to all clients when the server shuts down. +kick_msg_shutdown (Shutdown message) string Server shutting down. + +# A message to be displayed to all clients when the server crashes. +kick_msg_crash (Crash message) string This server has experienced an internal error. You will now be disconnected. + +# Whether to ask clients to reconnect after a (Lua) crash. +# Set this to true if your server is set up to restart automatically. +ask_reconnect_on_crash (Ask to reconnect after crash) bool false + +[**Server/Env Performance] + +# Length of a server tick and the interval at which objects are generally updated over +# network, stated in seconds. +dedicated_server_step (Dedicated server step) float 0.09 0.0 + +# Whether players are shown to clients without any range limit. +# Deprecated, use the setting player_transfer_distance instead. +unlimited_player_transfer_distance (Unlimited player transfer distance) bool true + +# Defines the maximal player transfer distance in blocks (0 = unlimited). +player_transfer_distance (Player transfer distance) int 0 0 65535 + +# From how far clients know about objects, stated in mapblocks (16 nodes). +# +# Setting this larger than active_block_range will also cause the server +# to maintain active objects up to this distance in the direction the +# player is looking. (This can avoid mobs suddenly disappearing from view) +active_object_send_range_blocks (Active object send range) int 8 1 65535 + +# The radius of the volume of blocks around every player that is subject to the +# active block stuff, stated in mapblocks (16 nodes). +# In active blocks objects are loaded and ABMs run. +# This is also the minimum range in which active objects (mobs) are maintained. +# This should be configured together with active_object_send_range_blocks. +active_block_range (Active block range) int 4 1 65535 + +# From how far blocks are sent to clients, stated in mapblocks (16 nodes). +max_block_send_distance (Max block send distance) int 12 1 65535 + +# Maximum number of forceloaded mapblocks. +max_forceloaded_blocks (Maximum forceloaded blocks) int 16 0 + +# Interval of sending time of day to clients, stated in seconds. +time_send_interval (Time send interval) float 5.0 0.001 + +# Interval of saving important changes in the world, stated in seconds. +server_map_save_interval (Map save interval) float 5.3 0.001 + +# How long the server will wait before unloading unused mapblocks, stated in seconds. +# Higher value is smoother, but will use more RAM. +server_unload_unused_data_timeout (Unload unused server data) int 29 0 4294967295 + +# Maximum number of statically stored objects in a block. +max_objects_per_block (Maximum objects per block) int 256 1 65535 + +# Length of time between active block management cycles, stated in seconds. +active_block_mgmt_interval (Active block management interval) float 2.0 0.0 + +# Length of time between Active Block Modifier (ABM) execution cycles, stated in seconds. +abm_interval (ABM interval) float 1.0 0.0 + +# The time budget allowed for ABMs to execute on each step +# (as a fraction of the ABM Interval) +abm_time_budget (ABM time budget) float 0.2 0.1 0.9 + +# Length of time between NodeTimer execution cycles, stated in seconds. +nodetimer_interval (NodeTimer interval) float 0.2 0.0 + +# Max liquids processed per step. +liquid_loop_max (Liquid loop max) int 100000 1 4294967295 + +# The time (in seconds) that the liquids queue may grow beyond processing +# capacity until an attempt is made to decrease its size by dumping old queue +# items. A value of 0 disables the functionality. +liquid_queue_purge_time (Liquid queue purge time) int 0 0 65535 + +# Liquid update interval in seconds. +liquid_update (Liquid update tick) float 1.0 0.001 + +# At this distance the server will aggressively optimize which blocks are sent to +# clients. +# Small values potentially improve performance a lot, at the expense of visible +# rendering glitches (some blocks will not be rendered under water and in caves, +# as well as sometimes on land). +# Setting this to a value greater than max_block_send_distance disables this +# optimization. +# Stated in mapblocks (16 nodes). +block_send_optimize_distance (Block send optimize distance) int 4 2 32767 + +# If enabled the server will perform map block occlusion culling based on +# on the eye position of the player. This can reduce the number of blocks +# sent to the client 50-80%. The client will not longer receive most invisible +# so that the utility of noclip mode is reduced. +server_side_occlusion_culling (Server side occlusion culling) bool true + +[**Mapgen] + +# Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes). +# WARNING!: There is no benefit, and there are several dangers, in +# increasing this value above 5. +# Reducing this value increases cave and dungeon density. +# Altering this value is for special usage, leaving it unchanged is +# recommended. +chunksize (Chunk size) int 5 1 10 + +# Dump the mapgen debug information. +enable_mapgen_debug_info (Mapgen debug) bool false + +# Maximum number of blocks that can be queued for loading. +emergequeue_limit_total (Absolute limit of queued blocks to emerge) int 1024 1 1000000 + +# Maximum number of blocks to be queued that are to be loaded from file. +# This limit is enforced per player. +emergequeue_limit_diskonly (Per-player limit of queued blocks load from disk) int 128 1 1000000 + +# Maximum number of blocks to be queued that are to be generated. +# This limit is enforced per player. +emergequeue_limit_generate (Per-player limit of queued blocks to generate) int 128 1 1000000 + +# Number of emerge threads to use. +# Value 0: +# - Automatic selection. The number of emerge threads will be +# - 'number of processors - 2', with a lower limit of 1. +# Any other value: +# - Specifies the number of emerge threads, with a lower limit of 1. +# WARNING: Increasing the number of emerge threads increases engine mapgen +# speed, but this may harm game performance by interfering with other +# processes, especially in singleplayer and/or when running Lua code in +# 'on_generated'. For many users the optimum setting may be '1'. +num_emerge_threads (Number of emerge threads) int 1 0 32767 + +[**cURL] + +# Maximum time an interactive request (e.g. server list fetch) may take, stated in milliseconds. +curl_timeout (cURL interactive timeout) int 20000 100 2147483647 + +# Limits number of parallel HTTP requests. Affects: +# - Media fetch if server uses remote_media setting. +# - Serverlist download and server announcement. +# - Downloads performed by main menu (e.g. mod manager). +# Only has an effect if compiled with cURL. +curl_parallel_limit (cURL parallel limit) int 8 1 2147483647 + +# Maximum time a file download (e.g. a mod download) may take, stated in milliseconds. +curl_file_download_timeout (cURL file download timeout) int 300000 100 2147483647 + +[**Misc] + +# Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens. +screen_dpi (DPI) int 72 1 + +# Adjust the detected display density, used for scaling UI elements. +display_density_factor (Display Density Scaling Factor) float 1 0.5 5.0 + +# Windows systems only: Start Minetest with the command line window in the background. +# Contains the same information as the file debug.txt (default name). +enable_console (Enable console window) bool false + +# Number of extra blocks that can be loaded by /clearobjects at once. +# This is a trade-off between SQLite transaction overhead and +# memory consumption (4096=100MB, as a rule of thumb). +max_clearobjects_extra_loaded_blocks (Max. clearobjects extra blocks) int 4096 0 4294967295 + +# World directory (everything in the world is stored here). +# Not needed if starting from the main menu. +map-dir (Map directory) path + +# See https://www.sqlite.org/pragma.html#pragma_synchronous +sqlite_synchronous (Synchronous SQLite) enum 2 0,1,2 + +# Compression level to use when saving mapblocks to disk. +# -1 - use default compression level +# 0 - least compression, fastest +# 9 - best compression, slowest +map_compression_level_disk (Map Compression Level for Disk Storage) int -1 -1 9 + +# Enable usage of remote media server (if provided by server). +# Remote servers offer a significantly faster way to download media (e.g. textures) +# when connecting to the server. +enable_remote_media_server (Connect to external media server) bool true + +# File in client/serverlist/ that contains your favorite servers displayed in the +# Multiplayer Tab. +serverlist_file (Serverlist file) string favoriteservers.json + + +[*Gamepads] + +# Enable joysticks. Requires a restart to take effect +enable_joysticks (Enable joysticks) bool false + +# The identifier of the joystick to use +joystick_id (Joystick ID) int 0 0 255 + +# The type of joystick +joystick_type (Joystick type) enum auto auto,generic,xbox,dragonrise_gamecube + +# The time in seconds it takes between repeated events +# when holding down a joystick button combination. +repeat_joystick_button_time (Joystick button repetition interval) float 0.17 0.001 + +# The dead zone of the joystick +joystick_deadzone (Joystick dead zone) int 2048 0 65535 + +# The sensitivity of the joystick axes for moving the +# in-game view frustum around. +joystick_frustum_sensitivity (Joystick frustum sensitivity) float 170.0 0.001 + + +[*Temporary Settings] + +# Path to texture directory. All textures are first searched from here. +texture_path (Texture path) path + +# Enables minimap. +enable_minimap (Minimap) bool true + +# Shape of the minimap. Enabled = round, disabled = square. +minimap_shape_round (Round minimap) bool true + +# Address to connect to. +# Leave this blank to start a local server. +# Note that the address field in the main menu overrides this setting. +address (Server address) string + +# Port to connect to (UDP). +# Note that the port field in the main menu overrides this setting. +remote_port (Remote port) int 30000 1 65535 + +# Default game when creating a new world. +# This will be overridden when creating a world from the main menu. +default_game (Default game) string minetest + +# Enable players getting damage and dying. +enable_damage (Damage) bool false + +# Enable creative mode for all players +creative_mode (Creative) bool false + +# Whether to allow players to damage and kill each other. +enable_pvp (Player versus player) bool true + +# Player is able to fly without being affected by gravity. +# This requires the "fly" privilege on the server. +free_move (Flying) bool false + +# If enabled, makes move directions relative to the player's pitch when flying or swimming. +pitch_move (Pitch move mode) bool false + +# Fast movement (via the "Aux1" key). +# This requires the "fast" privilege on the server. +fast_move (Fast movement) bool false + +# If enabled together with fly mode, player is able to fly through solid nodes. +# This requires the "noclip" privilege on the server. +noclip (Noclip) bool false + +# Continuous forward movement, toggled by autoforward key. +# Press the autoforward key again or the backwards movement to disable. +continuous_forward (Continuous forward) bool false + +# Formspec default background opacity (between 0 and 255). +formspec_default_bg_opacity (Formspec Default Background Opacity) int 140 0 255 + +# Formspec default background color (R,G,B). +formspec_default_bg_color (Formspec Default Background Color) string (0,0,0) + +# Whether to show technical names. +# Affects mods and texture packs in the Content and Select Mods menus, as well as +# setting names in All Settings. +# Controlled by the checkbox in the "All settings" menu. +show_technical_names (Show technical names) bool false + +# Enables the sound system. +# If disabled, this completely disables all sounds everywhere and the in-game +# sound controls will be non-functional. +# Changing this setting requires a restart. +enable_sound (Sound) bool true + +# Key for moving the player forward. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_forward (Forward key) key KEY_KEY_W + +# Key for moving the player backward. +# Will also disable autoforward, when active. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_backward (Backward key) key KEY_KEY_S + +# Key for moving the player left. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_left (Left key) key KEY_KEY_A + +# Key for moving the player right. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_right (Right key) key KEY_KEY_D + +# Key for jumping. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_jump (Jump key) key KEY_SPACE + +# Key for sneaking. +# Also used for climbing down and descending in water if aux1_descends is disabled. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_sneak (Sneak key) key KEY_LSHIFT + +# Key for digging. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_dig (Dig key) key KEY_LBUTTON + +# Key for placing. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_place (Place key) key KEY_RBUTTON + +# Key for opening the inventory. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_inventory (Inventory key) key KEY_KEY_I + +# Key for moving fast in fast mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_aux1 (Aux1 key) key KEY_KEY_E + +# Key for opening the chat window. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_chat (Chat key) key KEY_KEY_T + +# Key for opening the chat window to type commands. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_cmd (Command key) key / + +# Key for opening the chat window to type local commands. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_cmd_local (Command key) key . + +# Key for toggling unlimited view range. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_rangeselect (Range select key) key KEY_KEY_R + +# Key for toggling flying. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_freemove (Fly key) key KEY_KEY_K + +# Key for toggling pitch move mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_pitchmove (Pitch move key) key KEY_KEY_P + +# Key for toggling fast mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_fastmove (Fast key) key KEY_KEY_J + +# Key for toggling noclip mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_noclip (Noclip key) key KEY_KEY_H + +# Key for selecting the next item in the hotbar. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_hotbar_next (Hotbar next key) key KEY_KEY_N + +# Key for selecting the previous item in the hotbar. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_hotbar_previous (Hotbar previous key) key KEY_KEY_B + +# Key for muting the game. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_mute (Mute key) key KEY_KEY_M + +# Key for increasing the volume. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_increase_volume (Inc. volume key) key + +# Key for decreasing the volume. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_decrease_volume (Dec. volume key) key + +# Key for toggling autoforward. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_autoforward (Automatic forward key) key + +# Key for toggling cinematic mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_cinematic (Cinematic mode key) key + +# Key for toggling display of minimap. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_minimap (Minimap key) key KEY_KEY_V + +# Key for taking screenshots. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_screenshot (Screenshot) key KEY_F12 + +# Key for dropping the currently selected item. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_drop (Drop item key) key KEY_KEY_Q + +# Key to use view zoom when possible. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_zoom (View zoom key) key KEY_KEY_Z + +# Key for selecting the first hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot1 (Hotbar slot 1 key) key KEY_KEY_1 + +# Key for selecting the second hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot2 (Hotbar slot 2 key) key KEY_KEY_2 + +# Key for selecting the third hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot3 (Hotbar slot 3 key) key KEY_KEY_3 + +# Key for selecting the fourth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot4 (Hotbar slot 4 key) key KEY_KEY_4 + +# Key for selecting the fifth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot5 (Hotbar slot 5 key) key KEY_KEY_5 + +# Key for selecting the sixth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot6 (Hotbar slot 6 key) key KEY_KEY_6 + +# Key for selecting the seventh hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot7 (Hotbar slot 7 key) key KEY_KEY_7 + +# Key for selecting the eighth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot8 (Hotbar slot 8 key) key KEY_KEY_8 + +# Key for selecting the ninth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot9 (Hotbar slot 9 key) key KEY_KEY_9 + +# Key for selecting the tenth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot10 (Hotbar slot 10 key) key KEY_KEY_0 + +# Key for selecting the 11th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot11 (Hotbar slot 11 key) key + +# Key for selecting the 12th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot12 (Hotbar slot 12 key) key + +# Key for selecting the 13th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot13 (Hotbar slot 13 key) key + +# Key for selecting the 14th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot14 (Hotbar slot 14 key) key + +# Key for selecting the 15th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot15 (Hotbar slot 15 key) key + +# Key for selecting the 16th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot16 (Hotbar slot 16 key) key + +# Key for selecting the 17th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot17 (Hotbar slot 17 key) key + +# Key for selecting the 18th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot18 (Hotbar slot 18 key) key + +# Key for selecting the 19th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot19 (Hotbar slot 19 key) key + +# Key for selecting the 20th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot20 (Hotbar slot 20 key) key + +# Key for selecting the 21st hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot21 (Hotbar slot 21 key) key + +# Key for selecting the 22nd hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot22 (Hotbar slot 22 key) key + +# Key for selecting the 23rd hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot23 (Hotbar slot 23 key) key + +# Key for selecting the 24th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot24 (Hotbar slot 24 key) key + +# Key for selecting the 25th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot25 (Hotbar slot 25 key) key + +# Key for selecting the 26th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot26 (Hotbar slot 26 key) key + +# Key for selecting the 27th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot27 (Hotbar slot 27 key) key + +# Key for selecting the 28th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot28 (Hotbar slot 28 key) key + +# Key for selecting the 29th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot29 (Hotbar slot 29 key) key + +# Key for selecting the 30th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot30 (Hotbar slot 30 key) key + +# Key for selecting the 31st hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot31 (Hotbar slot 31 key) key + +# Key for selecting the 32nd hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_slot32 (Hotbar slot 32 key) key + +# Key for toggling the display of the HUD. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_toggle_hud (HUD toggle key) key KEY_F1 + +# Key for toggling the display of chat. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_toggle_chat (Chat toggle key) key KEY_F2 + +# Key for toggling the display of the large chat console. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_console (Large chat console key) key KEY_F10 + +# Key for toggling the display of fog. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_toggle_force_fog_off (Fog toggle key) key KEY_F3 + +# Key for toggling the camera update. Only used for development +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_toggle_update_camera (Camera update toggle key) key + +# Key for toggling the display of debug info. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_toggle_debug (Debug info toggle key) key KEY_F5 + +# Key for toggling the display of the profiler. Used for development. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_toggle_profiler (Profiler toggle key) key KEY_F6 + +# Key for switching between first- and third-person camera. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_camera_mode (Toggle camera mode key) key KEY_KEY_C + +# Key for increasing the viewing range. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_increase_viewing_range_min (View range increase key) key + + +# Key for decreasing the viewing range. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_decrease_viewing_range_min (View range decrease key) key - diff --git a/client/serverlist/.gitignore b/client/serverlist/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/client/serverlist/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/client/shaders/3d_interlaced_merge/opengl_fragment.glsl b/client/shaders/3d_interlaced_merge/opengl_fragment.glsl new file mode 100644 index 0000000..6d3ae50 --- /dev/null +++ b/client/shaders/3d_interlaced_merge/opengl_fragment.glsl @@ -0,0 +1,23 @@ +uniform sampler2D baseTexture; +uniform sampler2D normalTexture; +uniform sampler2D textureFlags; + +#define leftImage baseTexture +#define rightImage normalTexture +#define maskImage textureFlags + +varying mediump vec4 varTexCoord; + +void main(void) +{ + vec2 uv = varTexCoord.st; + vec4 left = texture2D(leftImage, uv).rgba; + vec4 right = texture2D(rightImage, uv).rgba; + vec4 mask = texture2D(maskImage, uv).rgba; + vec4 color; + if (mask.r > 0.5) + color = right; + else + color = left; + gl_FragColor = color; +} diff --git a/client/shaders/3d_interlaced_merge/opengl_vertex.glsl b/client/shaders/3d_interlaced_merge/opengl_vertex.glsl new file mode 100644 index 0000000..224b7d1 --- /dev/null +++ b/client/shaders/3d_interlaced_merge/opengl_vertex.glsl @@ -0,0 +1,7 @@ +varying mediump vec4 varTexCoord; + +void main(void) +{ + varTexCoord = inTexCoord0; + gl_Position = inVertexPosition; +} diff --git a/client/shaders/default_shader/opengl_fragment.glsl b/client/shaders/default_shader/opengl_fragment.glsl new file mode 100644 index 0000000..5018ac6 --- /dev/null +++ b/client/shaders/default_shader/opengl_fragment.glsl @@ -0,0 +1,6 @@ +varying lowp vec4 varColor; + +void main(void) +{ + gl_FragColor = varColor; +} diff --git a/client/shaders/default_shader/opengl_vertex.glsl b/client/shaders/default_shader/opengl_vertex.glsl new file mode 100644 index 0000000..a908ac9 --- /dev/null +++ b/client/shaders/default_shader/opengl_vertex.glsl @@ -0,0 +1,11 @@ +varying lowp vec4 varColor; + +void main(void) +{ + gl_Position = mWorldViewProj * inVertexPosition; +#ifdef GL_ES + varColor = inVertexColor.bgra; +#else + varColor = inVertexColor; +#endif +} diff --git a/client/shaders/minimap_shader/opengl_fragment.glsl b/client/shaders/minimap_shader/opengl_fragment.glsl new file mode 100644 index 0000000..cef359e --- /dev/null +++ b/client/shaders/minimap_shader/opengl_fragment.glsl @@ -0,0 +1,35 @@ +uniform sampler2D baseTexture; +uniform sampler2D normalTexture; +uniform vec3 yawVec; + +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; + +void main (void) +{ + vec2 uv = varTexCoord.st; + + //texture sampling rate + const float step = 1.0 / 256.0; + float tl = texture2D(normalTexture, vec2(uv.x - step, uv.y + step)).r; + float t = texture2D(normalTexture, vec2(uv.x - step, uv.y - step)).r; + float tr = texture2D(normalTexture, vec2(uv.x + step, uv.y + step)).r; + float r = texture2D(normalTexture, vec2(uv.x + step, uv.y)).r; + float br = texture2D(normalTexture, vec2(uv.x + step, uv.y - step)).r; + float b = texture2D(normalTexture, vec2(uv.x, uv.y - step)).r; + float bl = texture2D(normalTexture, vec2(uv.x - step, uv.y - step)).r; + float l = texture2D(normalTexture, vec2(uv.x - step, uv.y)).r; + float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl); + float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr); + vec4 bump = vec4 (normalize(vec3 (dX, dY, 0.1)),1.0); + float height = 2.0 * texture2D(normalTexture, vec2(uv.x, uv.y)).r - 1.0; + vec4 base = texture2D(baseTexture, uv).rgba; + vec3 L = normalize(vec3(0.0, 0.75, 1.0)); + float specular = pow(clamp(dot(reflect(L, bump.xyz), yawVec), 0.0, 1.0), 1.0); + float diffuse = dot(yawVec, bump.xyz); + + vec3 color = (1.1 * diffuse + 0.05 * height + 0.5 * specular) * base.rgb; + vec4 col = vec4(color.rgb, base.a); + col *= varColor; + gl_FragColor = vec4(col.rgb, base.a); +} diff --git a/client/shaders/minimap_shader/opengl_vertex.glsl b/client/shaders/minimap_shader/opengl_vertex.glsl new file mode 100644 index 0000000..b23d271 --- /dev/null +++ b/client/shaders/minimap_shader/opengl_vertex.glsl @@ -0,0 +1,15 @@ +uniform mat4 mWorld; + +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; + +void main(void) +{ + varTexCoord = inTexCoord0.st; + gl_Position = mWorldViewProj * inVertexPosition; +#ifdef GL_ES + varColor = inVertexColor.bgra; +#else + varColor = inVertexColor; +#endif +} diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl new file mode 100644 index 0000000..c4b947e --- /dev/null +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -0,0 +1,492 @@ +uniform sampler2D baseTexture; + +uniform vec3 dayLight; +uniform vec4 skyBgColor; +uniform float fogDistance; +uniform vec3 eyePosition; + +// The cameraOffset is the current center of the visible world. +uniform vec3 cameraOffset; +uniform float animationTimer; +#ifdef ENABLE_DYNAMIC_SHADOWS + // shadow texture + uniform sampler2D ShadowMapSampler; + // shadow uniforms + uniform vec3 v_LightDirection; + uniform float f_textureresolution; + uniform mat4 m_ShadowViewProj; + uniform float f_shadowfar; + uniform float f_shadow_strength; + uniform vec4 CameraPos; + uniform float xyPerspectiveBias0; + uniform float xyPerspectiveBias1; + + varying float adj_shadow_strength; + varying float cosLight; + varying float f_normal_length; + varying vec3 shadow_position; + varying float perspective_factor; +#endif + + +varying vec3 vNormal; +varying vec3 vPosition; +// World position in the visible world (i.e. relative to the cameraOffset.) +// This can be used for many shader effects without loss of precision. +// If the absolute position is required it can be calculated with +// cameraOffset + worldPosition (for large coordinates the limits of float +// precision must be considered). +varying vec3 worldPosition; +varying lowp vec4 varColor; +#ifdef GL_ES +varying mediump vec2 varTexCoord; +#else +centroid varying vec2 varTexCoord; +#endif +varying vec3 eyeVec; +varying float nightRatio; + +const float fogStart = FOG_START; +const float fogShadingParameter = 1.0 / ( 1.0 - fogStart); + +#ifdef ENABLE_DYNAMIC_SHADOWS + +// assuming near is always 1.0 +float getLinearDepth() +{ + return 2.0 * f_shadowfar / (f_shadowfar + 1.0 - (2.0 * gl_FragCoord.z - 1.0) * (f_shadowfar - 1.0)); +} + +vec3 getLightSpacePosition() +{ + return shadow_position * 0.5 + 0.5; +} +// custom smoothstep implementation because it's not defined in glsl1.2 +// https://docs.gl/sl4/smoothstep +float mtsmoothstep(in float edge0, in float edge1, in float x) +{ + float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); +} + +#ifdef COLORED_SHADOWS + +// c_precision of 128 fits within 7 base-10 digits +const float c_precision = 128.0; +const float c_precisionp1 = c_precision + 1.0; + +float packColor(vec3 color) +{ + return floor(color.b * c_precision + 0.5) + + floor(color.g * c_precision + 0.5) * c_precisionp1 + + floor(color.r * c_precision + 0.5) * c_precisionp1 * c_precisionp1; +} + +vec3 unpackColor(float value) +{ + vec3 color; + color.b = mod(value, c_precisionp1) / c_precision; + color.g = mod(floor(value / c_precisionp1), c_precisionp1) / c_precision; + color.r = floor(value / (c_precisionp1 * c_precisionp1)) / c_precision; + return color; +} + +vec4 getHardShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + vec4 texDepth = texture2D(shadowsampler, smTexCoord.xy).rgba; + + float visibility = step(0.0, realDistance - texDepth.r); + vec4 result = vec4(visibility, vec3(0.0,0.0,0.0));//unpackColor(texDepth.g)); + if (visibility < 0.1) { + visibility = step(0.0, realDistance - texDepth.b); + result = vec4(visibility, unpackColor(texDepth.a)); + } + return result; +} + +#else + +float getHardShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float texDepth = texture2D(shadowsampler, smTexCoord.xy).r; + float visibility = step(0.0, realDistance - texDepth); + return visibility; +} + +#endif + + +#if SHADOW_FILTER == 2 + #define PCFBOUND 2.0 // 5x5 + #define PCFSAMPLES 25 +#elif SHADOW_FILTER == 1 + #define PCFBOUND 1.0 // 3x3 + #define PCFSAMPLES 9 +#else + #define PCFBOUND 0.0 + #define PCFSAMPLES 1 +#endif + +#ifdef COLORED_SHADOWS +float getHardShadowDepth(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + vec4 texDepth = texture2D(shadowsampler, smTexCoord.xy); + float depth = max(realDistance - texDepth.r, realDistance - texDepth.b); + return depth; +} +#else +float getHardShadowDepth(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float texDepth = texture2D(shadowsampler, smTexCoord.xy).r; + float depth = realDistance - texDepth; + return depth; +} +#endif + +#define BASEFILTERRADIUS 1.0 + +float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + // Return fast if sharp shadows are requested + if (PCFBOUND == 0.0 || SOFTSHADOWRADIUS <= 0.0) + return 0.0; + + vec2 clampedpos; + float y, x; + float depth = getHardShadowDepth(shadowsampler, smTexCoord.xy, realDistance); + // A factor from 0 to 1 to reduce blurring of short shadows + float sharpness_factor = 1.0; + // conversion factor from shadow depth to blur radius + float depth_to_blur = f_shadowfar / SOFTSHADOWRADIUS / xyPerspectiveBias0; + if (depth > 0.0 && f_normal_length > 0.0) + // 5 is empirical factor that controls how fast shadow loses sharpness + sharpness_factor = clamp(5 * depth * depth_to_blur, 0.0, 1.0); + depth = 0.0; + + float world_to_texture = xyPerspectiveBias1 / perspective_factor / perspective_factor + * f_textureresolution / 2.0 / f_shadowfar; + float world_radius = 0.2; // shadow blur radius in world float coordinates, e.g. 0.2 = 0.02 of one node + + return max(BASEFILTERRADIUS * f_textureresolution / 4096.0, sharpness_factor * world_radius * world_to_texture * SOFTSHADOWRADIUS); +} + +#ifdef POISSON_FILTER +const vec2[64] poissonDisk = vec2[64]( + vec2(0.170019, -0.040254), + vec2(-0.299417, 0.791925), + vec2(0.645680, 0.493210), + vec2(-0.651784, 0.717887), + vec2(0.421003, 0.027070), + vec2(-0.817194, -0.271096), + vec2(-0.705374, -0.668203), + vec2(0.977050, -0.108615), + vec2(0.063326, 0.142369), + vec2(0.203528, 0.214331), + vec2(-0.667531, 0.326090), + vec2(-0.098422, -0.295755), + vec2(-0.885922, 0.215369), + vec2(0.566637, 0.605213), + vec2(0.039766, -0.396100), + vec2(0.751946, 0.453352), + vec2(0.078707, -0.715323), + vec2(-0.075838, -0.529344), + vec2(0.724479, -0.580798), + vec2(0.222999, -0.215125), + vec2(-0.467574, -0.405438), + vec2(-0.248268, -0.814753), + vec2(0.354411, -0.887570), + vec2(0.175817, 0.382366), + vec2(0.487472, -0.063082), + vec2(0.355476, 0.025357), + vec2(-0.084078, 0.898312), + vec2(0.488876, -0.783441), + vec2(0.470016, 0.217933), + vec2(-0.696890, -0.549791), + vec2(-0.149693, 0.605762), + vec2(0.034211, 0.979980), + vec2(0.503098, -0.308878), + vec2(-0.016205, -0.872921), + vec2(0.385784, -0.393902), + vec2(-0.146886, -0.859249), + vec2(0.643361, 0.164098), + vec2(0.634388, -0.049471), + vec2(-0.688894, 0.007843), + vec2(0.464034, -0.188818), + vec2(-0.440840, 0.137486), + vec2(0.364483, 0.511704), + vec2(0.034028, 0.325968), + vec2(0.099094, -0.308023), + vec2(0.693960, -0.366253), + vec2(0.678884, -0.204688), + vec2(0.001801, 0.780328), + vec2(0.145177, -0.898984), + vec2(0.062655, -0.611866), + vec2(0.315226, -0.604297), + vec2(-0.780145, 0.486251), + vec2(-0.371868, 0.882138), + vec2(0.200476, 0.494430), + vec2(-0.494552, -0.711051), + vec2(0.612476, 0.705252), + vec2(-0.578845, -0.768792), + vec2(-0.772454, -0.090976), + vec2(0.504440, 0.372295), + vec2(0.155736, 0.065157), + vec2(0.391522, 0.849605), + vec2(-0.620106, -0.328104), + vec2(0.789239, -0.419965), + vec2(-0.545396, 0.538133), + vec2(-0.178564, -0.596057) +); + +#ifdef COLORED_SHADOWS + +vec4 getShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance); + if (radius < 0.1) { + // we are in the middle of even brightness, no need for filtering + return getHardShadowColor(shadowsampler, smTexCoord.xy, realDistance); + } + + vec2 clampedpos; + vec4 visibility = vec4(0.0); + float scale_factor = radius / f_textureresolution; + + int samples = (1 + 1 * int(SOFTSHADOWRADIUS > 1.0)) * PCFSAMPLES; // scale max samples for the soft shadows + samples = int(clamp(pow(4.0 * radius + 1.0, 2.0), 1.0, float(samples))); + int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-samples))); + int end_offset = int(samples) + init_offset; + + for (int x = init_offset; x < end_offset; x++) { + clampedpos = poissonDisk[x] * scale_factor + smTexCoord.xy; + visibility += getHardShadowColor(shadowsampler, clampedpos.xy, realDistance); + } + + return visibility / samples; +} + +#else + +float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance); + if (radius < 0.1) { + // we are in the middle of even brightness, no need for filtering + return getHardShadow(shadowsampler, smTexCoord.xy, realDistance); + } + + vec2 clampedpos; + float visibility = 0.0; + float scale_factor = radius / f_textureresolution; + + int samples = (1 + 1 * int(SOFTSHADOWRADIUS > 1.0)) * PCFSAMPLES; // scale max samples for the soft shadows + samples = int(clamp(pow(4.0 * radius + 1.0, 2.0), 1.0, float(samples))); + int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-samples))); + int end_offset = int(samples) + init_offset; + + for (int x = init_offset; x < end_offset; x++) { + clampedpos = poissonDisk[x] * scale_factor + smTexCoord.xy; + visibility += getHardShadow(shadowsampler, clampedpos.xy, realDistance); + } + + return visibility / samples; +} + +#endif + +#else +/* poisson filter disabled */ + +#ifdef COLORED_SHADOWS + +vec4 getShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance); + if (radius < 0.1) { + // we are in the middle of even brightness, no need for filtering + return getHardShadowColor(shadowsampler, smTexCoord.xy, realDistance); + } + + vec2 clampedpos; + vec4 visibility = vec4(0.0); + float x, y; + float bound = (1 + 0.5 * int(SOFTSHADOWRADIUS > 1.0)) * PCFBOUND; // scale max bound for soft shadows + bound = clamp(0.5 * (4.0 * radius - 1.0), 0.5, bound); + float scale_factor = radius / bound / f_textureresolution; + float n = 0.0; + + // basic PCF filter + for (y = -bound; y <= bound; y += 1.0) + for (x = -bound; x <= bound; x += 1.0) { + clampedpos = vec2(x,y) * scale_factor + smTexCoord.xy; + visibility += getHardShadowColor(shadowsampler, clampedpos.xy, realDistance); + n += 1.0; + } + + return visibility / max(n, 1.0); +} + +#else +float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance); + if (radius < 0.1) { + // we are in the middle of even brightness, no need for filtering + return getHardShadow(shadowsampler, smTexCoord.xy, realDistance); + } + + vec2 clampedpos; + float visibility = 0.0; + float x, y; + float bound = (1 + 0.5 * int(SOFTSHADOWRADIUS > 1.0)) * PCFBOUND; // scale max bound for soft shadows + bound = clamp(0.5 * (4.0 * radius - 1.0), 0.5, bound); + float scale_factor = radius / bound / f_textureresolution; + float n = 0.0; + + // basic PCF filter + for (y = -bound; y <= bound; y += 1.0) + for (x = -bound; x <= bound; x += 1.0) { + clampedpos = vec2(x,y) * scale_factor + smTexCoord.xy; + visibility += getHardShadow(shadowsampler, clampedpos.xy, realDistance); + n += 1.0; + } + + return visibility / max(n, 1.0); +} + +#endif + +#endif +#endif + +#if ENABLE_TONE_MAPPING + +/* Hable's UC2 Tone mapping parameters + A = 0.22; + B = 0.30; + C = 0.10; + D = 0.20; + E = 0.01; + F = 0.30; + W = 11.2; + equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F +*/ + +vec3 uncharted2Tonemap(vec3 x) +{ + return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333; +} + +vec4 applyToneMapping(vec4 color) +{ + color = vec4(pow(color.rgb, vec3(2.2)), color.a); + const float gamma = 1.6; + const float exposureBias = 5.5; + color.rgb = uncharted2Tonemap(exposureBias * color.rgb); + // Precalculated white_scale from + //vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W)); + vec3 whiteScale = vec3(1.036015346); + color.rgb *= whiteScale; + return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a); +} +#endif + + + +void main(void) +{ + vec3 color; + vec2 uv = varTexCoord.st; + + vec4 base = texture2D(baseTexture, uv).rgba; + // If alpha is zero, we can just discard the pixel. This fixes transparency + // on GPUs like GC7000L, where GL_ALPHA_TEST is not implemented in mesa, + // and also on GLES 2, where GL_ALPHA_TEST is missing entirely. +#ifdef USE_DISCARD + if (base.a == 0.0) + discard; +#endif +#ifdef USE_DISCARD_REF + if (base.a < 0.5) + discard; +#endif + + color = base.rgb; + vec4 col = vec4(color.rgb * varColor.rgb, 1.0); + +#ifdef ENABLE_DYNAMIC_SHADOWS + if (f_shadow_strength > 0.0) { + float shadow_int = 0.0; + vec3 shadow_color = vec3(0.0, 0.0, 0.0); + vec3 posLightSpace = getLightSpacePosition(); + + float distance_rate = (1.0 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 10.0)); + if (max(abs(posLightSpace.x - 0.5), abs(posLightSpace.y - 0.5)) > 0.5) + distance_rate = 0.0; + float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z),0.0); + + if (distance_rate > 1e-7) { + +#ifdef COLORED_SHADOWS + vec4 visibility; + if (cosLight > 0.0 || f_normal_length < 1e-3) + visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z); + else + visibility = vec4(1.0, 0.0, 0.0, 0.0); + shadow_int = visibility.r; + shadow_color = visibility.gba; +#else + if (cosLight > 0.0 || f_normal_length < 1e-3) + shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z); + else + shadow_int = 1.0; +#endif + shadow_int *= distance_rate; + shadow_int = clamp(shadow_int, 0.0, 1.0); + + } + + // turns out that nightRatio falls off much faster than + // actual brightness of artificial light in relation to natual light. + // Power ratio was measured on torches in MTG (brightness = 14). + float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6); + + // Apply self-shadowing when light falls at a narrow angle to the surface + // Cosine of the cut-off angle. + const float self_shadow_cutoff_cosine = 0.035; + if (f_normal_length != 0 && cosLight < self_shadow_cutoff_cosine) { + shadow_int = max(shadow_int, 1 - clamp(cosLight, 0.0, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine); + shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine); + } + + shadow_int *= f_adj_shadow_strength; + + // calculate fragment color from components: + col.rgb = + adjusted_night_ratio * col.rgb + // artificial light + (1.0 - adjusted_night_ratio) * ( // natural light + col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color + dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight + } +#endif + +#if ENABLE_TONE_MAPPING + col = applyToneMapping(col); +#endif + + // Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?), + // the fog will only be rendered correctly if the last operation before the + // clamp() is an addition. Else, the clamp() seems to be ignored. + // E.g. the following won't work: + // float clarity = clamp(fogShadingParameter + // * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0); + // As additions usually come for free following a multiplication, the new formula + // should be more efficient as well. + // Note: clarity = (1 - fogginess) + float clarity = clamp(fogShadingParameter + - fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0); + col = mix(skyBgColor, col, clarity); + col = vec4(col.rgb, base.a); + + gl_FragColor = col; +} diff --git a/client/shaders/nodes_shader/opengl_vertex.glsl b/client/shaders/nodes_shader/opengl_vertex.glsl new file mode 100644 index 0000000..d1fba28 --- /dev/null +++ b/client/shaders/nodes_shader/opengl_vertex.glsl @@ -0,0 +1,272 @@ +uniform mat4 mWorld; +// Color of the light emitted by the sun. +uniform vec3 dayLight; +uniform vec3 eyePosition; + +// The cameraOffset is the current center of the visible world. +uniform vec3 cameraOffset; +uniform float animationTimer; + +varying vec3 vNormal; +varying vec3 vPosition; +// World position in the visible world (i.e. relative to the cameraOffset.) +// This can be used for many shader effects without loss of precision. +// If the absolute position is required it can be calculated with +// cameraOffset + worldPosition (for large coordinates the limits of float +// precision must be considered). +varying vec3 worldPosition; +varying lowp vec4 varColor; +// The centroid keyword ensures that after interpolation the texture coordinates +// lie within the same bounds when MSAA is en- and disabled. +// This fixes the stripes problem with nearest-neighbour textures and MSAA. +#ifdef GL_ES +varying mediump vec2 varTexCoord; +#else +centroid varying vec2 varTexCoord; +#endif +#ifdef ENABLE_DYNAMIC_SHADOWS + // shadow uniforms + uniform vec3 v_LightDirection; + uniform float f_textureresolution; + uniform mat4 m_ShadowViewProj; + uniform float f_shadowfar; + uniform float f_shadow_strength; + uniform float f_timeofday; + uniform vec4 CameraPos; + + varying float cosLight; + varying float normalOffsetScale; + varying float adj_shadow_strength; + varying float f_normal_length; + varying vec3 shadow_position; + varying float perspective_factor; +#endif + + +varying vec3 eyeVec; +varying float nightRatio; +// Color of the light emitted by the light sources. +const vec3 artificialLight = vec3(1.04, 1.04, 1.04); +const float e = 2.718281828459; +const float BS = 10.0; +uniform float xyPerspectiveBias0; +uniform float xyPerspectiveBias1; +uniform float zPerspectiveBias; + +#ifdef ENABLE_DYNAMIC_SHADOWS + +vec4 getRelativePosition(in vec4 position) +{ + vec2 l = position.xy - CameraPos.xy; + vec2 s = l / abs(l); + s = (1.0 - s * CameraPos.xy); + l /= s; + return vec4(l, s); +} + +float getPerspectiveFactor(in vec4 relativePosition) +{ + float pDistance = length(relativePosition.xy); + float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1; + return pFactor; +} + +vec4 applyPerspectiveDistortion(in vec4 position) +{ + vec4 l = getRelativePosition(position); + float pFactor = getPerspectiveFactor(l); + l.xy /= pFactor; + position.xy = l.xy * l.zw + CameraPos.xy; + position.z *= zPerspectiveBias; + return position; +} + +// custom smoothstep implementation because it's not defined in glsl1.2 +// https://docs.gl/sl4/smoothstep +float mtsmoothstep(in float edge0, in float edge1, in float x) +{ + float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); +} +#endif + + +float smoothCurve(float x) +{ + return x * x * (3.0 - 2.0 * x); +} + + +float triangleWave(float x) +{ + return abs(fract(x + 0.5) * 2.0 - 1.0); +} + + +float smoothTriangleWave(float x) +{ + return smoothCurve(triangleWave(x)) * 2.0 - 1.0; +} + +// OpenGL < 4.3 does not support continued preprocessor lines +#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER + +// +// Simple, fast noise function. +// See: https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 +// +vec4 perm(vec4 x) +{ + return mod(((x * 34.0) + 1.0) * x, 289.0); +} + +float snoise(vec3 p) +{ + vec3 a = floor(p); + vec3 d = p - a; + d = d * d * (3.0 - 2.0 * d); + + vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0); + vec4 k1 = perm(b.xyxy); + vec4 k2 = perm(k1.xyxy + b.zzww); + + vec4 c = k2 + a.zzzz; + vec4 k3 = perm(c); + vec4 k4 = perm(c + 1.0); + + vec4 o1 = fract(k3 * (1.0 / 41.0)); + vec4 o2 = fract(k4 * (1.0 / 41.0)); + + vec4 o3 = o2 * d.z + o1 * (1.0 - d.z); + vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x); + + return o4.y * d.y + o4.x * (1.0 - d.y); +} + +#endif + + + + +void main(void) +{ + varTexCoord = inTexCoord0.st; + + float disp_x; + float disp_z; +// OpenGL < 4.3 does not support continued preprocessor lines +#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES) || (MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS) + vec4 pos2 = mWorld * inVertexPosition; + float tOffset = (pos2.x + pos2.y) * 0.001 + pos2.z * 0.002; + disp_x = (smoothTriangleWave(animationTimer * 23.0 + tOffset) + + smoothTriangleWave(animationTimer * 11.0 + tOffset)) * 0.4; + disp_z = (smoothTriangleWave(animationTimer * 31.0 + tOffset) + + smoothTriangleWave(animationTimer * 29.0 + tOffset) + + smoothTriangleWave(animationTimer * 13.0 + tOffset)) * 0.5; +#endif + + worldPosition = (mWorld * inVertexPosition).xyz; + +// OpenGL < 4.3 does not support continued preprocessor lines +#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER + // Generate waves with Perlin-type noise. + // The constants are calibrated such that they roughly + // correspond to the old sine waves. + vec4 pos = inVertexPosition; + vec3 wavePos = worldPosition + cameraOffset; + // The waves are slightly compressed along the z-axis to get + // wave-fronts along the x-axis. + wavePos.x /= WATER_WAVE_LENGTH * 3.0; + wavePos.z /= WATER_WAVE_LENGTH * 2.0; + wavePos.z += animationTimer * WATER_WAVE_SPEED * 10.0; + pos.y += (snoise(wavePos) - 1.0) * WATER_WAVE_HEIGHT * 5.0; + gl_Position = mWorldViewProj * pos; +#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES + vec4 pos = inVertexPosition; + pos.x += disp_x; + pos.y += disp_z * 0.1; + pos.z += disp_z; + gl_Position = mWorldViewProj * pos; +#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS + vec4 pos = inVertexPosition; + if (varTexCoord.y < 0.05) { + pos.x += disp_x; + pos.z += disp_z; + } + gl_Position = mWorldViewProj * pos; +#else + gl_Position = mWorldViewProj * inVertexPosition; +#endif + + vPosition = gl_Position.xyz; + eyeVec = -(mWorldView * inVertexPosition).xyz; + vNormal = inVertexNormal; + + // Calculate color. + // Red, green and blue components are pre-multiplied with + // the brightness, so now we have to multiply these + // colors with the color of the incoming light. + // The pre-baked colors are halved to prevent overflow. +#ifdef GL_ES + vec4 color = inVertexColor.bgra; +#else + vec4 color = inVertexColor; +#endif + // The alpha gives the ratio of sunlight in the incoming light. + nightRatio = 1.0 - color.a; + color.rgb = color.rgb * (color.a * dayLight.rgb + + nightRatio * artificialLight.rgb) * 2.0; + color.a = 1.0; + + // Emphase blue a bit in darker places + // See C++ implementation in mapblock_mesh.cpp final_color_blend() + float brightness = (color.r + color.g + color.b) / 3.0; + color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) + + 0.07 * brightness); + + varColor = clamp(color, 0.0, 1.0); + +#ifdef ENABLE_DYNAMIC_SHADOWS + if (f_shadow_strength > 0.0) { + vec3 nNormal; + f_normal_length = length(vNormal); + + /* normalOffsetScale is in world coordinates (1/10th of a meter) + z_bias is in light space coordinates */ + float normalOffsetScale, z_bias; + float pFactor = getPerspectiveFactor(getRelativePosition(m_ShadowViewProj * mWorld * inVertexPosition)); + if (f_normal_length > 0.0) { + nNormal = normalize(vNormal); + cosLight = dot(nNormal, -v_LightDirection); + float sinLight = pow(1 - pow(cosLight, 2.0), 0.5); + normalOffsetScale = 2.0 * pFactor * pFactor * sinLight * min(f_shadowfar, 500.0) / + xyPerspectiveBias1 / f_textureresolution; + z_bias = 1.0 * sinLight / cosLight; + } + else { + nNormal = vec3(0.0); + cosLight = clamp(dot(v_LightDirection, normalize(vec3(v_LightDirection.x, 0.0, v_LightDirection.z))), 1e-2, 1.0); + float sinLight = pow(1 - pow(cosLight, 2.0), 0.5); + normalOffsetScale = 0.0; + z_bias = 3.6e3 * sinLight / cosLight; + } + z_bias *= pFactor * pFactor / f_textureresolution / f_shadowfar; + + shadow_position = applyPerspectiveDistortion(m_ShadowViewProj * mWorld * (inVertexPosition + vec4(normalOffsetScale * nNormal, 0.0))).xyz; + shadow_position.z -= z_bias; + perspective_factor = pFactor; + + if (f_timeofday < 0.2) { + adj_shadow_strength = f_shadow_strength * 0.5 * + (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday)); + } else if (f_timeofday >= 0.8) { + adj_shadow_strength = f_shadow_strength * 0.5 * + mtsmoothstep(0.8, 0.83, f_timeofday); + } else { + adj_shadow_strength = f_shadow_strength * + mtsmoothstep(0.20, 0.25, f_timeofday) * + (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday)); + } + } +#endif +} diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl new file mode 100644 index 0000000..1fefc76 --- /dev/null +++ b/client/shaders/object_shader/opengl_fragment.glsl @@ -0,0 +1,495 @@ +uniform sampler2D baseTexture; + +uniform vec3 dayLight; +uniform vec4 skyBgColor; +uniform float fogDistance; +uniform vec3 eyePosition; + +// The cameraOffset is the current center of the visible world. +uniform vec3 cameraOffset; +uniform float animationTimer; +#ifdef ENABLE_DYNAMIC_SHADOWS + // shadow texture + uniform sampler2D ShadowMapSampler; + // shadow uniforms + uniform vec3 v_LightDirection; + uniform float f_textureresolution; + uniform mat4 m_ShadowViewProj; + uniform float f_shadowfar; + uniform float f_shadow_strength; + uniform vec4 CameraPos; + uniform float xyPerspectiveBias0; + uniform float xyPerspectiveBias1; + + varying float adj_shadow_strength; + varying float cosLight; + varying float f_normal_length; + varying vec3 shadow_position; + varying float perspective_factor; +#endif + + +varying vec3 vNormal; +varying vec3 vPosition; +// World position in the visible world (i.e. relative to the cameraOffset.) +// This can be used for many shader effects without loss of precision. +// If the absolute position is required it can be calculated with +// cameraOffset + worldPosition (for large coordinates the limits of float +// precision must be considered). +varying vec3 worldPosition; +varying lowp vec4 varColor; +#ifdef GL_ES +varying mediump vec2 varTexCoord; +#else +centroid varying vec2 varTexCoord; +#endif +varying vec3 eyeVec; +varying float nightRatio; + +varying float vIDiff; + +const float fogStart = FOG_START; +const float fogShadingParameter = 1.0 / (1.0 - fogStart); + +#ifdef ENABLE_DYNAMIC_SHADOWS + +// assuming near is always 1.0 +float getLinearDepth() +{ + return 2.0 * f_shadowfar / (f_shadowfar + 1.0 - (2.0 * gl_FragCoord.z - 1.0) * (f_shadowfar - 1.0)); +} + +vec3 getLightSpacePosition() +{ + return shadow_position * 0.5 + 0.5; +} +// custom smoothstep implementation because it's not defined in glsl1.2 +// https://docs.gl/sl4/smoothstep +float mtsmoothstep(in float edge0, in float edge1, in float x) +{ + float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); +} + +#ifdef COLORED_SHADOWS + +// c_precision of 128 fits within 7 base-10 digits +const float c_precision = 128.0; +const float c_precisionp1 = c_precision + 1.0; + +float packColor(vec3 color) +{ + return floor(color.b * c_precision + 0.5) + + floor(color.g * c_precision + 0.5) * c_precisionp1 + + floor(color.r * c_precision + 0.5) * c_precisionp1 * c_precisionp1; +} + +vec3 unpackColor(float value) +{ + vec3 color; + color.b = mod(value, c_precisionp1) / c_precision; + color.g = mod(floor(value / c_precisionp1), c_precisionp1) / c_precision; + color.r = floor(value / (c_precisionp1 * c_precisionp1)) / c_precision; + return color; +} + +vec4 getHardShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + vec4 texDepth = texture2D(shadowsampler, smTexCoord.xy).rgba; + + float visibility = step(0.0, realDistance - texDepth.r); + vec4 result = vec4(visibility, vec3(0.0,0.0,0.0));//unpackColor(texDepth.g)); + if (visibility < 0.1) { + visibility = step(0.0, realDistance - texDepth.b); + result = vec4(visibility, unpackColor(texDepth.a)); + } + return result; +} + +#else + +float getHardShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float texDepth = texture2D(shadowsampler, smTexCoord.xy).r; + float visibility = step(0.0, realDistance - texDepth); + return visibility; +} + +#endif + + +#if SHADOW_FILTER == 2 + #define PCFBOUND 2.0 // 5x5 + #define PCFSAMPLES 25 +#elif SHADOW_FILTER == 1 + #define PCFBOUND 1.0 // 3x3 + #define PCFSAMPLES 9 +#else + #define PCFBOUND 0.0 + #define PCFSAMPLES 1 +#endif + +#ifdef COLORED_SHADOWS +float getHardShadowDepth(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + vec4 texDepth = texture2D(shadowsampler, smTexCoord.xy); + float depth = max(realDistance - texDepth.r, realDistance - texDepth.b); + return depth; +} +#else +float getHardShadowDepth(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float texDepth = texture2D(shadowsampler, smTexCoord.xy).r; + float depth = realDistance - texDepth; + return depth; +} +#endif + +#define BASEFILTERRADIUS 1.0 + +float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + // Return fast if sharp shadows are requested + if (PCFBOUND == 0.0 || SOFTSHADOWRADIUS <= 0.0) + return 0.0; + + vec2 clampedpos; + float y, x; + float depth = getHardShadowDepth(shadowsampler, smTexCoord.xy, realDistance); + // A factor from 0 to 1 to reduce blurring of short shadows + float sharpness_factor = 1.0; + // conversion factor from shadow depth to blur radius + float depth_to_blur = f_shadowfar / SOFTSHADOWRADIUS / xyPerspectiveBias0; + if (depth > 0.0 && f_normal_length > 0.0) + // 5 is empirical factor that controls how fast shadow loses sharpness + sharpness_factor = clamp(5 * depth * depth_to_blur, 0.0, 1.0); + depth = 0.0; + + float world_to_texture = xyPerspectiveBias1 / perspective_factor / perspective_factor + * f_textureresolution / 2.0 / f_shadowfar; + float world_radius = 0.2; // shadow blur radius in world float coordinates, e.g. 0.2 = 0.02 of one node + + return max(BASEFILTERRADIUS * f_textureresolution / 4096.0, sharpness_factor * world_radius * world_to_texture * SOFTSHADOWRADIUS); +} + +#ifdef POISSON_FILTER +const vec2[64] poissonDisk = vec2[64]( + vec2(0.170019, -0.040254), + vec2(-0.299417, 0.791925), + vec2(0.645680, 0.493210), + vec2(-0.651784, 0.717887), + vec2(0.421003, 0.027070), + vec2(-0.817194, -0.271096), + vec2(-0.705374, -0.668203), + vec2(0.977050, -0.108615), + vec2(0.063326, 0.142369), + vec2(0.203528, 0.214331), + vec2(-0.667531, 0.326090), + vec2(-0.098422, -0.295755), + vec2(-0.885922, 0.215369), + vec2(0.566637, 0.605213), + vec2(0.039766, -0.396100), + vec2(0.751946, 0.453352), + vec2(0.078707, -0.715323), + vec2(-0.075838, -0.529344), + vec2(0.724479, -0.580798), + vec2(0.222999, -0.215125), + vec2(-0.467574, -0.405438), + vec2(-0.248268, -0.814753), + vec2(0.354411, -0.887570), + vec2(0.175817, 0.382366), + vec2(0.487472, -0.063082), + vec2(0.355476, 0.025357), + vec2(-0.084078, 0.898312), + vec2(0.488876, -0.783441), + vec2(0.470016, 0.217933), + vec2(-0.696890, -0.549791), + vec2(-0.149693, 0.605762), + vec2(0.034211, 0.979980), + vec2(0.503098, -0.308878), + vec2(-0.016205, -0.872921), + vec2(0.385784, -0.393902), + vec2(-0.146886, -0.859249), + vec2(0.643361, 0.164098), + vec2(0.634388, -0.049471), + vec2(-0.688894, 0.007843), + vec2(0.464034, -0.188818), + vec2(-0.440840, 0.137486), + vec2(0.364483, 0.511704), + vec2(0.034028, 0.325968), + vec2(0.099094, -0.308023), + vec2(0.693960, -0.366253), + vec2(0.678884, -0.204688), + vec2(0.001801, 0.780328), + vec2(0.145177, -0.898984), + vec2(0.062655, -0.611866), + vec2(0.315226, -0.604297), + vec2(-0.780145, 0.486251), + vec2(-0.371868, 0.882138), + vec2(0.200476, 0.494430), + vec2(-0.494552, -0.711051), + vec2(0.612476, 0.705252), + vec2(-0.578845, -0.768792), + vec2(-0.772454, -0.090976), + vec2(0.504440, 0.372295), + vec2(0.155736, 0.065157), + vec2(0.391522, 0.849605), + vec2(-0.620106, -0.328104), + vec2(0.789239, -0.419965), + vec2(-0.545396, 0.538133), + vec2(-0.178564, -0.596057) +); + +#ifdef COLORED_SHADOWS + +vec4 getShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance); + if (radius < 0.1) { + // we are in the middle of even brightness, no need for filtering + return getHardShadowColor(shadowsampler, smTexCoord.xy, realDistance); + } + + vec2 clampedpos; + vec4 visibility = vec4(0.0); + float scale_factor = radius / f_textureresolution; + + int samples = (1 + 1 * int(SOFTSHADOWRADIUS > 1.0)) * PCFSAMPLES; // scale max samples for the soft shadows + samples = int(clamp(pow(4.0 * radius + 1.0, 2.0), 1.0, float(samples))); + int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-samples))); + int end_offset = int(samples) + init_offset; + + for (int x = init_offset; x < end_offset; x++) { + clampedpos = poissonDisk[x] * scale_factor + smTexCoord.xy; + visibility += getHardShadowColor(shadowsampler, clampedpos.xy, realDistance); + } + + return visibility / samples; +} + +#else + +float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance); + if (radius < 0.1) { + // we are in the middle of even brightness, no need for filtering + return getHardShadow(shadowsampler, smTexCoord.xy, realDistance); + } + + vec2 clampedpos; + float visibility = 0.0; + float scale_factor = radius / f_textureresolution; + + int samples = (1 + 1 * int(SOFTSHADOWRADIUS > 1.0)) * PCFSAMPLES; // scale max samples for the soft shadows + samples = int(clamp(pow(4.0 * radius + 1.0, 2.0), 1.0, float(samples))); + int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-samples))); + int end_offset = int(samples) + init_offset; + + for (int x = init_offset; x < end_offset; x++) { + clampedpos = poissonDisk[x] * scale_factor + smTexCoord.xy; + visibility += getHardShadow(shadowsampler, clampedpos.xy, realDistance); + } + + return visibility / samples; +} + +#endif + +#else +/* poisson filter disabled */ + +#ifdef COLORED_SHADOWS + +vec4 getShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance); + if (radius < 0.1) { + // we are in the middle of even brightness, no need for filtering + return getHardShadowColor(shadowsampler, smTexCoord.xy, realDistance); + } + + vec2 clampedpos; + vec4 visibility = vec4(0.0); + float x, y; + float bound = (1 + 0.5 * int(SOFTSHADOWRADIUS > 1.0)) * PCFBOUND; // scale max bound for soft shadows + bound = clamp(0.5 * (4.0 * radius - 1.0), 0.5, bound); + float scale_factor = radius / bound / f_textureresolution; + float n = 0.0; + + // basic PCF filter + for (y = -bound; y <= bound; y += 1.0) + for (x = -bound; x <= bound; x += 1.0) { + clampedpos = vec2(x,y) * scale_factor + smTexCoord.xy; + visibility += getHardShadowColor(shadowsampler, clampedpos.xy, realDistance); + n += 1.0; + } + + return visibility / max(n, 1.0); +} + +#else +float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) +{ + float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance); + if (radius < 0.1) { + // we are in the middle of even brightness, no need for filtering + return getHardShadow(shadowsampler, smTexCoord.xy, realDistance); + } + + vec2 clampedpos; + float visibility = 0.0; + float x, y; + float bound = (1 + 0.5 * int(SOFTSHADOWRADIUS > 1.0)) * PCFBOUND; // scale max bound for soft shadows + bound = clamp(0.5 * (4.0 * radius - 1.0), 0.5, bound); + float scale_factor = radius / bound / f_textureresolution; + float n = 0.0; + + // basic PCF filter + for (y = -bound; y <= bound; y += 1.0) + for (x = -bound; x <= bound; x += 1.0) { + clampedpos = vec2(x,y) * scale_factor + smTexCoord.xy; + visibility += getHardShadow(shadowsampler, clampedpos.xy, realDistance); + n += 1.0; + } + + return visibility / max(n, 1.0); +} + +#endif + +#endif +#endif + +#if ENABLE_TONE_MAPPING + +/* Hable's UC2 Tone mapping parameters + A = 0.22; + B = 0.30; + C = 0.10; + D = 0.20; + E = 0.01; + F = 0.30; + W = 11.2; + equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F +*/ + +vec3 uncharted2Tonemap(vec3 x) +{ + return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333; +} + +vec4 applyToneMapping(vec4 color) +{ + color = vec4(pow(color.rgb, vec3(2.2)), color.a); + const float gamma = 1.6; + const float exposureBias = 5.5; + color.rgb = uncharted2Tonemap(exposureBias * color.rgb); + // Precalculated white_scale from + //vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W)); + vec3 whiteScale = vec3(1.036015346); + color.rgb *= whiteScale; + return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a); +} +#endif + + + +void main(void) +{ + vec3 color; + vec2 uv = varTexCoord.st; + + vec4 base = texture2D(baseTexture, uv).rgba; + // If alpha is zero, we can just discard the pixel. This fixes transparency + // on GPUs like GC7000L, where GL_ALPHA_TEST is not implemented in mesa, + // and also on GLES 2, where GL_ALPHA_TEST is missing entirely. +#ifdef USE_DISCARD + if (base.a == 0.0) + discard; +#endif +#ifdef USE_DISCARD_REF + if (base.a < 0.5) + discard; +#endif + + color = base.rgb; + vec4 col = vec4(color.rgb * varColor.rgb, 1.0); + col.rgb *= vIDiff; + +#ifdef ENABLE_DYNAMIC_SHADOWS + if (f_shadow_strength > 0.0) { + float shadow_int = 0.0; + vec3 shadow_color = vec3(0.0, 0.0, 0.0); + vec3 posLightSpace = getLightSpacePosition(); + + float distance_rate = (1.0 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 10.0)); + if (max(abs(posLightSpace.x - 0.5), abs(posLightSpace.y - 0.5)) > 0.5) + distance_rate = 0.0; + float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z),0.0); + + if (distance_rate > 1e-7) { + +#ifdef COLORED_SHADOWS + vec4 visibility; + if (cosLight > 0.0 || f_normal_length < 1e-3) + visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z); + else + visibility = vec4(1.0, 0.0, 0.0, 0.0); + shadow_int = visibility.r; + shadow_color = visibility.gba; +#else + if (cosLight > 0.0 || f_normal_length < 1e-3) + shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z); + else + shadow_int = 1.0; +#endif + shadow_int *= distance_rate; + shadow_int = clamp(shadow_int, 0.0, 1.0); + + } + + // turns out that nightRatio falls off much faster than + // actual brightness of artificial light in relation to natual light. + // Power ratio was measured on torches in MTG (brightness = 14). + float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6); + + // Apply self-shadowing when light falls at a narrow angle to the surface + // Cosine of the cut-off angle. + const float self_shadow_cutoff_cosine = 0.14; + if (f_normal_length != 0 && cosLight < self_shadow_cutoff_cosine) { + shadow_int = max(shadow_int, 1 - clamp(cosLight, 0.0, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine); + shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine); + } + + shadow_int *= f_adj_shadow_strength; + + // calculate fragment color from components: + col.rgb = + adjusted_night_ratio * col.rgb + // artificial light + (1.0 - adjusted_night_ratio) * ( // natural light + col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color + dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight + } +#endif + +#if ENABLE_TONE_MAPPING + col = applyToneMapping(col); +#endif + + // Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?), + // the fog will only be rendered correctly if the last operation before the + // clamp() is an addition. Else, the clamp() seems to be ignored. + // E.g. the following won't work: + // float clarity = clamp(fogShadingParameter + // * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0); + // As additions usually come for free following a multiplication, the new formula + // should be more efficient as well. + // Note: clarity = (1 - fogginess) + float clarity = clamp(fogShadingParameter + - fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0); + col = mix(skyBgColor, col, clarity); + col = vec4(col.rgb, base.a); + + gl_FragColor = col; +} diff --git a/client/shaders/object_shader/opengl_vertex.glsl b/client/shaders/object_shader/opengl_vertex.glsl new file mode 100644 index 0000000..dc9c70c --- /dev/null +++ b/client/shaders/object_shader/opengl_vertex.glsl @@ -0,0 +1,181 @@ +uniform mat4 mWorld; +uniform vec3 dayLight; +uniform vec3 eyePosition; +uniform float animationTimer; +uniform vec4 emissiveColor; +uniform vec3 cameraOffset; + + +varying vec3 vNormal; +varying vec3 vPosition; +varying vec3 worldPosition; +varying lowp vec4 varColor; +#ifdef GL_ES +varying mediump vec2 varTexCoord; +#else +centroid varying vec2 varTexCoord; +#endif + +#ifdef ENABLE_DYNAMIC_SHADOWS + // shadow uniforms + uniform vec3 v_LightDirection; + uniform float f_textureresolution; + uniform mat4 m_ShadowViewProj; + uniform float f_shadowfar; + uniform float f_shadow_strength; + uniform float f_timeofday; + uniform vec4 CameraPos; + + varying float cosLight; + varying float adj_shadow_strength; + varying float f_normal_length; + varying vec3 shadow_position; + varying float perspective_factor; +#endif + +varying vec3 eyeVec; +varying float nightRatio; +// Color of the light emitted by the light sources. +const vec3 artificialLight = vec3(1.04, 1.04, 1.04); +varying float vIDiff; +const float e = 2.718281828459; +const float BS = 10.0; +uniform float xyPerspectiveBias0; +uniform float xyPerspectiveBias1; +uniform float zPerspectiveBias; + +#ifdef ENABLE_DYNAMIC_SHADOWS + +vec4 getRelativePosition(in vec4 position) +{ + vec2 l = position.xy - CameraPos.xy; + vec2 s = l / abs(l); + s = (1.0 - s * CameraPos.xy); + l /= s; + return vec4(l, s); +} + +float getPerspectiveFactor(in vec4 relativePosition) +{ + float pDistance = length(relativePosition.xy); + float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1; + return pFactor; +} + +vec4 applyPerspectiveDistortion(in vec4 position) +{ + vec4 l = getRelativePosition(position); + float pFactor = getPerspectiveFactor(l); + l.xy /= pFactor; + position.xy = l.xy * l.zw + CameraPos.xy; + position.z *= zPerspectiveBias; + return position; +} + +// custom smoothstep implementation because it's not defined in glsl1.2 +// https://docs.gl/sl4/smoothstep +float mtsmoothstep(in float edge0, in float edge1, in float x) +{ + float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); +} +#endif + + +float directional_ambient(vec3 normal) +{ + vec3 v = normal * normal; + + if (normal.y < 0.0) + return dot(v, vec3(0.670820, 0.447213, 0.836660)); + + return dot(v, vec3(0.670820, 1.000000, 0.836660)); +} + +void main(void) +{ + varTexCoord = (mTexture * inTexCoord0).st; + gl_Position = mWorldViewProj * inVertexPosition; + + vPosition = gl_Position.xyz; + vNormal = (mWorld * vec4(inVertexNormal, 0.0)).xyz; + worldPosition = (mWorld * inVertexPosition).xyz; + eyeVec = -(mWorldView * inVertexPosition).xyz; + +#if (MATERIAL_TYPE == TILE_MATERIAL_PLAIN) || (MATERIAL_TYPE == TILE_MATERIAL_PLAIN_ALPHA) + vIDiff = 1.0; +#else + // This is intentional comparison with zero without any margin. + // If normal is not equal to zero exactly, then we assume it's a valid, just not normalized vector + vIDiff = length(inVertexNormal) == 0.0 + ? 1.0 + : directional_ambient(normalize(inVertexNormal)); +#endif + +#ifdef GL_ES + vec4 color = inVertexColor.bgra; +#else + vec4 color = inVertexColor; +#endif + + color *= emissiveColor; + + // The alpha gives the ratio of sunlight in the incoming light. + nightRatio = 1.0 - color.a; + color.rgb = color.rgb * (color.a * dayLight.rgb + + nightRatio * artificialLight.rgb) * 2.0; + color.a = 1.0; + + // Emphase blue a bit in darker places + // See C++ implementation in mapblock_mesh.cpp final_color_blend() + float brightness = (color.r + color.g + color.b) / 3.0; + color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) + + 0.07 * brightness); + + varColor = clamp(color, 0.0, 1.0); + + +#ifdef ENABLE_DYNAMIC_SHADOWS + if (f_shadow_strength > 0.0) { + vec3 nNormal = normalize(vNormal); + f_normal_length = length(vNormal); + + /* normalOffsetScale is in world coordinates (1/10th of a meter) + z_bias is in light space coordinates */ + float normalOffsetScale, z_bias; + float pFactor = getPerspectiveFactor(getRelativePosition(m_ShadowViewProj * mWorld * inVertexPosition)); + if (f_normal_length > 0.0) { + nNormal = normalize(vNormal); + cosLight = dot(nNormal, -v_LightDirection); + float sinLight = pow(1 - pow(cosLight, 2.0), 0.5); + normalOffsetScale = 0.1 * pFactor * pFactor * sinLight * min(f_shadowfar, 500.0) / + xyPerspectiveBias1 / f_textureresolution; + z_bias = 1e3 * sinLight / cosLight * (0.5 + f_textureresolution / 1024.0); + } + else { + nNormal = vec3(0.0); + cosLight = clamp(dot(v_LightDirection, normalize(vec3(v_LightDirection.x, 0.0, v_LightDirection.z))), 1e-2, 1.0); + float sinLight = pow(1 - pow(cosLight, 2.0), 0.5); + normalOffsetScale = 0.0; + z_bias = 3.6e3 * sinLight / cosLight; + } + z_bias *= pFactor * pFactor / f_textureresolution / f_shadowfar; + + shadow_position = applyPerspectiveDistortion(m_ShadowViewProj * mWorld * (inVertexPosition + vec4(normalOffsetScale * nNormal, 0.0))).xyz; + shadow_position.z -= z_bias; + perspective_factor = pFactor; + + if (f_timeofday < 0.2) { + adj_shadow_strength = f_shadow_strength * 0.5 * + (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday)); + } else if (f_timeofday >= 0.8) { + adj_shadow_strength = f_shadow_strength * 0.5 * + mtsmoothstep(0.8, 0.83, f_timeofday); + } else { + adj_shadow_strength = f_shadow_strength * + mtsmoothstep(0.20, 0.25, f_timeofday) * + (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday)); + } + } +#endif +} diff --git a/client/shaders/selection_shader/opengl_fragment.glsl b/client/shaders/selection_shader/opengl_fragment.glsl new file mode 100644 index 0000000..35b1f89 --- /dev/null +++ b/client/shaders/selection_shader/opengl_fragment.glsl @@ -0,0 +1,12 @@ +uniform sampler2D baseTexture; + +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; + +void main(void) +{ + vec2 uv = varTexCoord.st; + vec4 color = texture2D(baseTexture, uv); + color.rgb *= varColor.rgb; + gl_FragColor = color; +} diff --git a/client/shaders/selection_shader/opengl_vertex.glsl b/client/shaders/selection_shader/opengl_vertex.glsl new file mode 100644 index 0000000..39dde30 --- /dev/null +++ b/client/shaders/selection_shader/opengl_vertex.glsl @@ -0,0 +1,14 @@ +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; + +void main(void) +{ + varTexCoord = inTexCoord0.st; + gl_Position = mWorldViewProj * inVertexPosition; + +#ifdef GL_ES + varColor = inVertexColor.bgra; +#else + varColor = inVertexColor; +#endif +} diff --git a/client/shaders/shadow_shaders/pass1_fragment.glsl b/client/shaders/shadow_shaders/pass1_fragment.glsl new file mode 100644 index 0000000..2105def --- /dev/null +++ b/client/shaders/shadow_shaders/pass1_fragment.glsl @@ -0,0 +1,13 @@ +uniform sampler2D ColorMapSampler; +varying vec4 tPos; + +void main() +{ + vec4 col = texture2D(ColorMapSampler, gl_TexCoord[0].st); + + if (col.a < 0.70) + discard; + + float depth = 0.5 + tPos.z * 0.5; + gl_FragColor = vec4(depth, 0.0, 0.0, 1.0); +} diff --git a/client/shaders/shadow_shaders/pass1_trans_fragment.glsl b/client/shaders/shadow_shaders/pass1_trans_fragment.glsl new file mode 100644 index 0000000..b267c22 --- /dev/null +++ b/client/shaders/shadow_shaders/pass1_trans_fragment.glsl @@ -0,0 +1,42 @@ +uniform sampler2D ColorMapSampler; +varying vec4 tPos; + +#ifdef COLORED_SHADOWS +varying vec3 varColor; + +// c_precision of 128 fits within 7 base-10 digits +const float c_precision = 128.0; +const float c_precisionp1 = c_precision + 1.0; + +float packColor(vec3 color) +{ + return floor(color.b * c_precision + 0.5) + + floor(color.g * c_precision + 0.5) * c_precisionp1 + + floor(color.r * c_precision + 0.5) * c_precisionp1 * c_precisionp1; +} + +const vec3 black = vec3(0.0); +#endif + +void main() +{ + vec4 col = texture2D(ColorMapSampler, gl_TexCoord[0].st); +#ifndef COLORED_SHADOWS + if (col.a < 0.5) + discard; +#endif + + float depth = 0.5 + tPos.z * 0.5; + // ToDo: Liso: Apply movement on waving plants + // depth in [0, 1] for texture + + //col.rgb = col.a == 1.0 ? vec3(1.0) : col.rgb; +#ifdef COLORED_SHADOWS + col.rgb *= varColor.rgb; + // premultiply color alpha (see-through side) + float packedColor = packColor(col.rgb * (1.0 - col.a)); + gl_FragColor = vec4(depth, packedColor, 0.0,1.0); +#else + gl_FragColor = vec4(depth, 0.0, 0.0, 1.0); +#endif +} diff --git a/client/shaders/shadow_shaders/pass1_trans_vertex.glsl b/client/shaders/shadow_shaders/pass1_trans_vertex.glsl new file mode 100644 index 0000000..244d256 --- /dev/null +++ b/client/shaders/shadow_shaders/pass1_trans_vertex.glsl @@ -0,0 +1,50 @@ +uniform mat4 LightMVP; // world matrix +uniform vec4 CameraPos; +varying vec4 tPos; +#ifdef COLORED_SHADOWS +varying vec3 varColor; +#endif + +uniform float xyPerspectiveBias0; +uniform float xyPerspectiveBias1; +uniform float zPerspectiveBias; + +vec4 getRelativePosition(in vec4 position) +{ + vec2 l = position.xy - CameraPos.xy; + vec2 s = l / abs(l); + s = (1.0 - s * CameraPos.xy); + l /= s; + return vec4(l, s); +} + +float getPerspectiveFactor(in vec4 relativePosition) +{ + float pDistance = length(relativePosition.xy); + float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1; + return pFactor; +} + +vec4 applyPerspectiveDistortion(in vec4 position) +{ + vec4 l = getRelativePosition(position); + float pFactor = getPerspectiveFactor(l); + l.xy /= pFactor; + position.xy = l.xy * l.zw + CameraPos.xy; + position.z *= zPerspectiveBias; + return position; +} + +void main() +{ + vec4 pos = LightMVP * gl_Vertex; + + tPos = applyPerspectiveDistortion(LightMVP * gl_Vertex); + + gl_Position = vec4(tPos.xyz, 1.0); + gl_TexCoord[0].st = gl_MultiTexCoord0.st; + +#ifdef COLORED_SHADOWS + varColor = gl_Color.rgb; +#endif +} diff --git a/client/shaders/shadow_shaders/pass1_vertex.glsl b/client/shaders/shadow_shaders/pass1_vertex.glsl new file mode 100644 index 0000000..1dceb93 --- /dev/null +++ b/client/shaders/shadow_shaders/pass1_vertex.glsl @@ -0,0 +1,43 @@ +uniform mat4 LightMVP; // world matrix +uniform vec4 CameraPos; // camera position +varying vec4 tPos; + +uniform float xyPerspectiveBias0; +uniform float xyPerspectiveBias1; +uniform float zPerspectiveBias; + +vec4 getRelativePosition(in vec4 position) +{ + vec2 l = position.xy - CameraPos.xy; + vec2 s = l / abs(l); + s = (1.0 - s * CameraPos.xy); + l /= s; + return vec4(l, s); +} + +float getPerspectiveFactor(in vec4 relativePosition) +{ + float pDistance = length(relativePosition.xy); + float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1; + return pFactor; +} + +vec4 applyPerspectiveDistortion(in vec4 position) +{ + vec4 l = getRelativePosition(position); + float pFactor = getPerspectiveFactor(l); + l.xy /= pFactor; + position.xy = l.xy * l.zw + CameraPos.xy; + position.z *= zPerspectiveBias; + return position; +} + +void main() +{ + vec4 pos = LightMVP * gl_Vertex; + + tPos = applyPerspectiveDistortion(pos); + + gl_Position = vec4(tPos.xyz, 1.0); + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +} diff --git a/client/shaders/shadow_shaders/pass2_fragment.glsl b/client/shaders/shadow_shaders/pass2_fragment.glsl new file mode 100644 index 0000000..00b4f9f --- /dev/null +++ b/client/shaders/shadow_shaders/pass2_fragment.glsl @@ -0,0 +1,23 @@ +uniform sampler2D ShadowMapClientMap; +#ifdef COLORED_SHADOWS +uniform sampler2D ShadowMapClientMapTraslucent; +#endif +uniform sampler2D ShadowMapSamplerdynamic; + +void main() { + +#ifdef COLORED_SHADOWS + vec2 first_depth = texture2D(ShadowMapClientMap, gl_TexCoord[0].st).rg; + vec2 depth_splitdynamics = vec2(texture2D(ShadowMapSamplerdynamic, gl_TexCoord[2].st).r, 0.0); + if (first_depth.r > depth_splitdynamics.r) + first_depth = depth_splitdynamics; + vec2 depth_color = texture2D(ShadowMapClientMapTraslucent, gl_TexCoord[1].st).rg; + gl_FragColor = vec4(first_depth.r, first_depth.g, depth_color.r, depth_color.g); +#else + float first_depth = texture2D(ShadowMapClientMap, gl_TexCoord[0].st).r; + float depth_splitdynamics = texture2D(ShadowMapSamplerdynamic, gl_TexCoord[2].st).r; + first_depth = min(first_depth, depth_splitdynamics); + gl_FragColor = vec4(first_depth, 0.0, 0.0, 1.0); +#endif + +} diff --git a/client/shaders/shadow_shaders/pass2_vertex.glsl b/client/shaders/shadow_shaders/pass2_vertex.glsl new file mode 100644 index 0000000..ac445c9 --- /dev/null +++ b/client/shaders/shadow_shaders/pass2_vertex.glsl @@ -0,0 +1,9 @@ + +void main() +{ + vec4 uv = vec4(gl_Vertex.xyz, 1.0) * 0.5 + 0.5; + gl_TexCoord[0] = uv; + gl_TexCoord[1] = uv; + gl_TexCoord[2] = uv; + gl_Position = vec4(gl_Vertex.xyz, 1.0); +} diff --git a/client/shaders/stars_shader/opengl_fragment.glsl b/client/shaders/stars_shader/opengl_fragment.glsl new file mode 100644 index 0000000..a9ed741 --- /dev/null +++ b/client/shaders/stars_shader/opengl_fragment.glsl @@ -0,0 +1,6 @@ +uniform vec4 starColor; + +void main(void) +{ + gl_FragColor = starColor; +} diff --git a/client/shaders/stars_shader/opengl_vertex.glsl b/client/shaders/stars_shader/opengl_vertex.glsl new file mode 100644 index 0000000..77c401f --- /dev/null +++ b/client/shaders/stars_shader/opengl_vertex.glsl @@ -0,0 +1,4 @@ +void main(void) +{ + gl_Position = mWorldViewProj * inVertexPosition; +} diff --git a/clientmods/preview/example.lua b/clientmods/preview/example.lua new file mode 100644 index 0000000..2f42eef --- /dev/null +++ b/clientmods/preview/example.lua @@ -0,0 +1,2 @@ +print("Loaded example file!, loading more examples") +dofile(core.get_modpath(core.get_current_modname()) .. "/examples/first.lua") diff --git a/clientmods/preview/examples/first.lua b/clientmods/preview/examples/first.lua new file mode 100644 index 0000000..c24f461 --- /dev/null +++ b/clientmods/preview/examples/first.lua @@ -0,0 +1 @@ +print("loaded first.lua example file") diff --git a/clientmods/preview/init.lua b/clientmods/preview/init.lua new file mode 100644 index 0000000..46d59ec --- /dev/null +++ b/clientmods/preview/init.lua @@ -0,0 +1,206 @@ +local modname = assert(core.get_current_modname()) +local modstorage = core.get_mod_storage() +local mod_channel + +dofile(core.get_modpath(modname) .. "example.lua") + +core.register_on_shutdown(function() + print("[PREVIEW] shutdown client") +end) +local id = nil + +do + local server_info = core.get_server_info() + print("Server version: " .. server_info.protocol_version) + print("Server ip: " .. server_info.ip) + print("Server address: " .. server_info.address) + print("Server port: " .. server_info.port) + + print("CSM restrictions: " .. dump(core.get_csm_restrictions())) + + local l1, l2 = core.get_language() + print("Configured language: " .. l1 .. " / " .. l2) +end + +mod_channel = core.mod_channel_join("experimental_preview") + +core.after(4, function() + if mod_channel:is_writeable() then + mod_channel:send_all("preview talk to experimental") + end +end) + +core.after(1, function() + print("armor: " .. dump(core.localplayer:get_armor_groups())) + id = core.localplayer:hud_add({ + hud_elem_type = "text", + name = "example", + number = 0xff0000, + position = {x=0, y=1}, + offset = {x=8, y=-8}, + text = "You are using the preview mod", + scale = {x=200, y=60}, + alignment = {x=1, y=-1}, + }) +end) + +core.register_on_modchannel_message(function(channel, sender, message) + print("[PREVIEW][modchannels] Received message `" .. message .. "` on channel `" + .. channel .. "` from sender `" .. sender .. "`") + core.after(1, function() + mod_channel:send_all("CSM preview received " .. message) + end) +end) + +core.register_on_modchannel_signal(function(channel, signal) + print("[PREVIEW][modchannels] Received signal id `" .. signal .. "` on channel `" + .. channel) +end) + +core.register_on_inventory_open(function(inventory) + print("INVENTORY OPEN") + print(dump(inventory)) + return false +end) + +core.register_on_placenode(function(pointed_thing, node) + print("The local player place a node!") + print("pointed_thing :" .. dump(pointed_thing)) + print("node placed :" .. dump(node)) + return false +end) + +core.register_on_item_use(function(itemstack, pointed_thing) + print("The local player used an item!") + print("pointed_thing :" .. dump(pointed_thing)) + print("item = " .. itemstack:get_name()) + + if not itemstack:is_empty() then + return false + end + + local pos = core.camera:get_pos() + local pos2 = vector.add(pos, vector.multiply(core.camera:get_look_dir(), 100)) + + local rc = core.raycast(pos, pos2) + local i = rc:next() + print("[PREVIEW] raycast next: " .. dump(i)) + if i then + print("[PREVIEW] line of sight: " .. (core.line_of_sight(pos, i.above) and "yes" or "no")) + + local n1 = core.find_nodes_in_area(pos, i.under, {"default:stone"}) + local n2 = core.find_nodes_in_area_under_air(pos, i.under, {"default:stone"}) + print(("[PREVIEW] found %s nodes, %s nodes under air"):format( + n1 and #n1 or "?", n2 and #n2 or "?")) + end + + return false +end) + +-- This is an example function to ensure it's working properly, should be removed before merge +core.register_on_receiving_chat_message(function(message) + print("[PREVIEW] Received message " .. message) + return false +end) + +-- This is an example function to ensure it's working properly, should be removed before merge +core.register_on_sending_chat_message(function(message) + print("[PREVIEW] Sending message " .. message) + return false +end) + +core.register_on_chatcommand(function(command, params) + print("[PREVIEW] caught command '"..command.."'. Parameters: '"..params.."'") +end) + +-- This is an example function to ensure it's working properly, should be removed before merge +core.register_on_hp_modification(function(hp) + print("[PREVIEW] HP modified " .. hp) +end) + +-- This is an example function to ensure it's working properly, should be removed before merge +core.register_on_damage_taken(function(hp) + print("[PREVIEW] Damage taken " .. hp) +end) + +-- This is an example function to ensure it's working properly, should be removed before merge +core.register_chatcommand("dump", { + func = function(param) + return true, dump(_G) + end, +}) + +local function preview_minimap() + local minimap = core.ui.minimap + if not minimap then + print("[PREVIEW] Minimap is disabled. Skipping.") + return + end + minimap:set_mode(4) + minimap:show() + minimap:set_pos({x=5, y=50, z=5}) + minimap:set_shape(math.random(0, 1)) + + print("[PREVIEW] Minimap: mode => " .. dump(minimap:get_mode()) .. + " position => " .. dump(minimap:get_pos()) .. + " angle => " .. dump(minimap:get_angle())) +end + +core.after(2, function() + print("[PREVIEW] loaded " .. modname .. " mod") + modstorage:set_string("current_mod", modname) + assert(modstorage:get_string("current_mod") == modname) + preview_minimap() +end) + +core.after(5, function() + if core.ui.minimap then + core.ui.minimap:show() + end + + print("[PREVIEW] Time of day " .. core.get_timeofday()) + + print("[PREVIEW] Node level: " .. core.get_node_level({x=0, y=20, z=0}) .. + " max level " .. core.get_node_max_level({x=0, y=20, z=0})) + + print("[PREVIEW] Find node near: " .. dump(core.find_node_near({x=0, y=20, z=0}, 10, + {"group:tree", "default:dirt", "default:stone"}))) + + print("[PREVIEW] Settings: preview_csm_test_setting = " .. + tostring(core.settings:get_bool("preview_csm_test_setting", false))) +end) + +core.register_on_dignode(function(pos, node) + print("The local player dug a node!") + print("pos:" .. dump(pos)) + print("node:" .. dump(node)) + return false +end) + +core.register_on_punchnode(function(pos, node) + print("The local player punched a node!") + local itemstack = core.localplayer:get_wielded_item() + print(dump(itemstack:to_table())) + print("pos:" .. dump(pos)) + print("node:" .. dump(node)) + local meta = core.get_meta(pos) + print("punched meta: " .. (meta and dump(meta:to_table()) or "(missing)")) + return false +end) + +core.register_chatcommand("privs", { + func = function(param) + return true, core.privs_to_string(minetest.get_privilege_list()) + end, +}) + +core.register_chatcommand("text", { + func = function(param) + return core.localplayer:hud_change(id, "text", param) + end, +}) + + +core.register_on_mods_loaded(function() + core.log("Yeah preview mod is loaded with other CSM mods.") +end) diff --git a/clientmods/preview/mod.conf b/clientmods/preview/mod.conf new file mode 100644 index 0000000..23a5c3e --- /dev/null +++ b/clientmods/preview/mod.conf @@ -0,0 +1 @@ +name = preview diff --git a/clientmods/preview/settingtypes.txt b/clientmods/preview/settingtypes.txt new file mode 100644 index 0000000..fea9e71 --- /dev/null +++ b/clientmods/preview/settingtypes.txt @@ -0,0 +1 @@ +preview_csm_test_setting (Test CSM setting) bool false \ No newline at end of file diff --git a/cmake/Modules/FindCURL.cmake b/cmake/Modules/FindCURL.cmake new file mode 100644 index 0000000..43aaf3e --- /dev/null +++ b/cmake/Modules/FindCURL.cmake @@ -0,0 +1,16 @@ +mark_as_advanced(CURL_LIBRARY CURL_INCLUDE_DIR) + +find_library(CURL_LIBRARY NAMES curl libcurl) +find_path(CURL_INCLUDE_DIR NAMES curl/curl.h) + +if(WIN32) + # If VCPKG_APPLOCAL_DEPS is ON, dll's are automatically handled by VCPKG + if(NOT VCPKG_APPLOCAL_DEPS) + find_file(CURL_DLL NAMES libcurl-4.dll libcurl.dll + DOC "Path to the cURL DLL (for installation)") + mark_as_advanced(CURL_DLL) + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CURL DEFAULT_MSG CURL_LIBRARY CURL_INCLUDE_DIR) diff --git a/cmake/Modules/FindGMP.cmake b/cmake/Modules/FindGMP.cmake new file mode 100644 index 0000000..190b7c5 --- /dev/null +++ b/cmake/Modules/FindGMP.cmake @@ -0,0 +1,25 @@ +option(ENABLE_SYSTEM_GMP "Use GMP from system" TRUE) +mark_as_advanced(GMP_LIBRARY GMP_INCLUDE_DIR) +set(USE_SYSTEM_GMP FALSE) + +if(ENABLE_SYSTEM_GMP) + find_library(GMP_LIBRARY NAMES gmp) + find_path(GMP_INCLUDE_DIR NAMES gmp.h) + + if(GMP_LIBRARY AND GMP_INCLUDE_DIR) + message (STATUS "Using GMP provided by system.") + set(USE_SYSTEM_GMP TRUE) + else() + message (STATUS "Detecting GMP from system failed.") + endif() +endif() + +if(NOT USE_SYSTEM_GMP) + message(STATUS "Using bundled mini-gmp library.") + set(GMP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/gmp) + set(GMP_LIBRARY gmp) + add_subdirectory(lib/gmp) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GMP DEFAULT_MSG GMP_LIBRARY GMP_INCLUDE_DIR) diff --git a/cmake/Modules/FindGettextLib.cmake b/cmake/Modules/FindGettextLib.cmake new file mode 100644 index 0000000..b768182 --- /dev/null +++ b/cmake/Modules/FindGettextLib.cmake @@ -0,0 +1,69 @@ + +set(CUSTOM_GETTEXT_PATH "${PROJECT_SOURCE_DIR}/../../gettext" + CACHE FILEPATH "path to custom gettext") + +find_path(GETTEXT_INCLUDE_DIR + NAMES libintl.h + PATHS "${CUSTOM_GETTEXT_PATH}/include" + DOC "GetText include directory") + +find_program(GETTEXT_MSGFMT + NAMES msgfmt + PATHS "${CUSTOM_GETTEXT_PATH}/bin" + DOC "Path to msgfmt") + +set(GETTEXT_REQUIRED_VARS GETTEXT_INCLUDE_DIR GETTEXT_MSGFMT) + +if(APPLE) + find_library(GETTEXT_LIBRARY + NAMES libintl.a + PATHS "${CUSTOM_GETTEXT_PATH}/lib" + DOC "GetText library") + + find_library(ICONV_LIBRARY + NAMES libiconv.dylib + PATHS "/usr/lib" + DOC "IConv library") + set(GETTEXT_REQUIRED_VARS ${GETTEXT_REQUIRED_VARS} GETTEXT_LIBRARY ICONV_LIBRARY) +endif(APPLE) + +# Modern Linux, as well as OSX, does not require special linking because +# GetText is part of glibc. +# TODO: check the requirements on other BSDs and older Linux +if(WIN32) + if(MSVC) + set(GETTEXT_LIB_NAMES + libintl.lib intl.lib libintl3.lib intl3.lib) + else() + set(GETTEXT_LIB_NAMES + libintl.dll.a intl.dll.a libintl3.dll.a intl3.dll.a) + endif() + find_library(GETTEXT_LIBRARY + NAMES ${GETTEXT_LIB_NAMES} + PATHS "${CUSTOM_GETTEXT_PATH}/lib" + DOC "GetText library") +endif(WIN32) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GettextLib DEFAULT_MSG ${GETTEXT_REQUIRED_VARS}) + + +if(GETTEXTLIB_FOUND) + # BSD variants require special linkage as they don't use glibc + if(${CMAKE_SYSTEM_NAME} MATCHES "BSD|DragonFly") + set(GETTEXT_LIBRARY "intl") + endif() + + set(GETTEXT_PO_PATH ${CMAKE_SOURCE_DIR}/po) + set(GETTEXT_MO_BUILD_PATH ${CMAKE_BINARY_DIR}/locale/<locale>/LC_MESSAGES) + set(GETTEXT_MO_DEST_PATH ${LOCALEDIR}/<locale>/LC_MESSAGES) + file(GLOB GETTEXT_AVAILABLE_LOCALES RELATIVE ${GETTEXT_PO_PATH} "${GETTEXT_PO_PATH}/*") + list(REMOVE_ITEM GETTEXT_AVAILABLE_LOCALES minetest.pot) + list(REMOVE_ITEM GETTEXT_AVAILABLE_LOCALES timestamp) + macro(SET_MO_PATHS _buildvar _destvar _locale) + string(REPLACE "<locale>" ${_locale} ${_buildvar} ${GETTEXT_MO_BUILD_PATH}) + string(REPLACE "<locale>" ${_locale} ${_destvar} ${GETTEXT_MO_DEST_PATH}) + endmacro() +endif() + diff --git a/cmake/Modules/FindJson.cmake b/cmake/Modules/FindJson.cmake new file mode 100644 index 0000000..cce2d38 --- /dev/null +++ b/cmake/Modules/FindJson.cmake @@ -0,0 +1,25 @@ +# Look for JsonCpp, with fallback to bundeled version + +mark_as_advanced(JSON_LIBRARY JSON_INCLUDE_DIR) +option(ENABLE_SYSTEM_JSONCPP "Enable using a system-wide JsonCpp" TRUE) +set(USE_SYSTEM_JSONCPP FALSE) + +if(ENABLE_SYSTEM_JSONCPP) + find_library(JSON_LIBRARY NAMES jsoncpp) + find_path(JSON_INCLUDE_DIR json/allocator.h PATH_SUFFIXES jsoncpp) + + if(JSON_LIBRARY AND JSON_INCLUDE_DIR) + message(STATUS "Using JsonCpp provided by system.") + set(USE_SYSTEM_JSONCPP TRUE) + endif() +endif() + +if(NOT USE_SYSTEM_JSONCPP) + message(STATUS "Using bundled JsonCpp library.") + set(JSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/jsoncpp) + set(JSON_LIBRARY jsoncpp) + add_subdirectory(lib/jsoncpp) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Json DEFAULT_MSG JSON_LIBRARY JSON_INCLUDE_DIR) diff --git a/cmake/Modules/FindLua.cmake b/cmake/Modules/FindLua.cmake new file mode 100644 index 0000000..be5d92d --- /dev/null +++ b/cmake/Modules/FindLua.cmake @@ -0,0 +1,28 @@ +# Look for Lua library to use +# This selects LuaJIT by default + +option(ENABLE_LUAJIT "Enable LuaJIT support" TRUE) +set(USE_LUAJIT FALSE) +option(REQUIRE_LUAJIT "Require LuaJIT support" FALSE) +if(REQUIRE_LUAJIT) + set(ENABLE_LUAJIT TRUE) +endif() +if(ENABLE_LUAJIT) + find_package(LuaJIT) + if(LUAJIT_FOUND) + set(USE_LUAJIT TRUE) + message (STATUS "Using LuaJIT provided by system.") + elseif(REQUIRE_LUAJIT) + message(FATAL_ERROR "LuaJIT not found whereas REQUIRE_LUAJIT=\"TRUE\" is used.\n" + "To continue, either install LuaJIT or do not use REQUIRE_LUAJIT=\"TRUE\".") + endif() +else() + message (STATUS "LuaJIT detection disabled! (ENABLE_LUAJIT=0)") +endif() + +if(NOT USE_LUAJIT) + message(STATUS "LuaJIT not found, using bundled Lua.") + set(LUA_LIBRARY lua) + set(LUA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/src) + add_subdirectory(lib/lua) +endif() diff --git a/cmake/Modules/FindLuaJIT.cmake b/cmake/Modules/FindLuaJIT.cmake new file mode 100644 index 0000000..217415d --- /dev/null +++ b/cmake/Modules/FindLuaJIT.cmake @@ -0,0 +1,53 @@ +# Locate LuaJIT library +# This module defines +# LUAJIT_FOUND, if false, do not try to link to Lua +# LUA_LIBRARY, where to find the lua library +# LUA_INCLUDE_DIR, where to find lua.h +# +# This module is similar to FindLua51.cmake except that it finds LuaJit instead. + +FIND_PATH(LUA_INCLUDE_DIR luajit.h + HINTS + $ENV{LUA_DIR} + PATH_SUFFIXES include/luajit-2.1 include/luajit-2.0 include/luajit-5_1-2.1 include/luajit-5_1-2.0 include luajit + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) + +# Test if running on vcpkg toolchain +if(DEFINED VCPKG_TARGET_TRIPLET AND DEFINED VCPKG_APPLOCAL_DEPS) + # On vcpkg luajit is 'lua51' and normal lua is 'lua' + FIND_LIBRARY(LUA_LIBRARY + NAMES lua51 + HINTS + $ENV{LUA_DIR} + PATH_SUFFIXES lib + ) +else() + FIND_LIBRARY(LUA_LIBRARY + NAMES luajit-5.1 + HINTS + $ENV{LUA_DIR} + PATH_SUFFIXES lib64 lib + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw + /opt/local + /opt/csw + /opt + ) +endif() + +INCLUDE(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if +# all listed variables exist +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJIT + REQUIRED_VARS LUA_LIBRARY LUA_INCLUDE_DIR) + +MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARY) diff --git a/cmake/Modules/FindNcursesw.cmake b/cmake/Modules/FindNcursesw.cmake new file mode 100644 index 0000000..e572c70 --- /dev/null +++ b/cmake/Modules/FindNcursesw.cmake @@ -0,0 +1,204 @@ +#.rst: +# FindNcursesw +# ------------ +# +# Find the ncursesw (wide ncurses) include file and library. +# +# Based on FindCurses.cmake which comes with CMake. +# +# Checks for ncursesw first. If not found, it then executes the +# regular old FindCurses.cmake to look for for ncurses (or curses). +# +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following variables: +# +# ``CURSES_FOUND`` +# True if curses is found. +# ``NCURSESW_FOUND`` +# True if ncursesw is found. +# ``CURSES_INCLUDE_DIRS`` +# The include directories needed to use Curses. +# ``CURSES_LIBRARIES`` +# The libraries needed to use Curses. +# ``CURSES_HAVE_CURSES_H`` +# True if curses.h is available. +# ``CURSES_HAVE_NCURSES_H`` +# True if ncurses.h is available. +# ``CURSES_HAVE_NCURSES_NCURSES_H`` +# True if ``ncurses/ncurses.h`` is available. +# ``CURSES_HAVE_NCURSES_CURSES_H`` +# True if ``ncurses/curses.h`` is available. +# ``CURSES_HAVE_NCURSESW_NCURSES_H`` +# True if ``ncursesw/ncurses.h`` is available. +# ``CURSES_HAVE_NCURSESW_CURSES_H`` +# True if ``ncursesw/curses.h`` is available. +# +# Set ``CURSES_NEED_NCURSES`` to ``TRUE`` before the +# ``find_package(Ncursesw)`` call if NCurses functionality is required. +# +#============================================================================= +# Copyright 2001-2014 Kitware, Inc. +# modifications: Copyright 2015 kahrl <kahrl@gmx.net> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# ------------------------------------------------------------------------------ +# +# The above copyright and license notice applies to distributions of +# CMake in source and binary form. Some source files contain additional +# notices of original copyright by their contributors; see each source +# for details. Third-party software packages supplied with CMake under +# compatible licenses provide their own copyright notices documented in +# corresponding subdirectories. +# +# ------------------------------------------------------------------------------ +# +# CMake was initially developed by Kitware with the following sponsorship: +# +# * National Library of Medicine at the National Institutes of Health +# as part of the Insight Segmentation and Registration Toolkit (ITK). +# +# * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel +# Visualization Initiative. +# +# * National Alliance for Medical Image Computing (NAMIC) is funded by the +# National Institutes of Health through the NIH Roadmap for Medical Research, +# Grant U54 EB005149. +# +# * Kitware, Inc. +#============================================================================= + +include(CheckLibraryExists) + +find_library(CURSES_NCURSESW_LIBRARY NAMES ncursesw + DOC "Path to libncursesw.so or .lib or .a") + +set(CURSES_USE_NCURSES FALSE) +set(CURSES_USE_NCURSESW FALSE) + +if(CURSES_NCURSESW_LIBRARY) + set(CURSES_USE_NCURSES TRUE) + set(CURSES_USE_NCURSESW TRUE) +endif() + +if(CURSES_USE_NCURSESW) + get_filename_component(_cursesLibDir "${CURSES_NCURSESW_LIBRARY}" PATH) + get_filename_component(_cursesParentDir "${_cursesLibDir}" PATH) + + find_path(CURSES_INCLUDE_PATH + NAMES ncursesw/ncurses.h ncursesw/curses.h ncurses.h curses.h + HINTS "${_cursesParentDir}/include" + ) + + # Previous versions of FindCurses provided these values. + if(NOT DEFINED CURSES_LIBRARY) + set(CURSES_LIBRARY "${CURSES_NCURSESW_LIBRARY}") + endif() + + CHECK_LIBRARY_EXISTS("${CURSES_NCURSESW_LIBRARY}" + cbreak "" CURSES_NCURSESW_HAS_CBREAK) + if(NOT CURSES_NCURSESW_HAS_CBREAK) + find_library(CURSES_EXTRA_LIBRARY tinfo HINTS "${_cursesLibDir}" + DOC "Path to libtinfo.so or .lib or .a") + find_library(CURSES_EXTRA_LIBRARY tinfo ) + endif() + + # Report whether each possible header name exists in the include directory. + if(NOT DEFINED CURSES_HAVE_NCURSESW_NCURSES_H) + if(EXISTS "${CURSES_INCLUDE_PATH}/ncursesw/ncurses.h") + set(CURSES_HAVE_NCURSESW_NCURSES_H "${CURSES_INCLUDE_PATH}/ncursesw/ncurses.h") + else() + set(CURSES_HAVE_NCURSESW_NCURSES_H "CURSES_HAVE_NCURSESW_NCURSES_H-NOTFOUND") + endif() + endif() + if(NOT DEFINED CURSES_HAVE_NCURSESW_CURSES_H) + if(EXISTS "${CURSES_INCLUDE_PATH}/ncursesw/curses.h") + set(CURSES_HAVE_NCURSESW_CURSES_H "${CURSES_INCLUDE_PATH}/ncursesw/curses.h") + else() + set(CURSES_HAVE_NCURSESW_CURSES_H "CURSES_HAVE_NCURSESW_CURSES_H-NOTFOUND") + endif() + endif() + if(NOT DEFINED CURSES_HAVE_NCURSES_H) + if(EXISTS "${CURSES_INCLUDE_PATH}/ncurses.h") + set(CURSES_HAVE_NCURSES_H "${CURSES_INCLUDE_PATH}/ncurses.h") + else() + set(CURSES_HAVE_NCURSES_H "CURSES_HAVE_NCURSES_H-NOTFOUND") + endif() + endif() + if(NOT DEFINED CURSES_HAVE_CURSES_H) + if(EXISTS "${CURSES_INCLUDE_PATH}/curses.h") + set(CURSES_HAVE_CURSES_H "${CURSES_INCLUDE_PATH}/curses.h") + else() + set(CURSES_HAVE_CURSES_H "CURSES_HAVE_CURSES_H-NOTFOUND") + endif() + endif() + + + find_library(CURSES_FORM_LIBRARY form HINTS "${_cursesLibDir}" + DOC "Path to libform.so or .lib or .a") + find_library(CURSES_FORM_LIBRARY form ) + + # Need to provide the *_LIBRARIES + set(CURSES_LIBRARIES ${CURSES_LIBRARY}) + + if(CURSES_EXTRA_LIBRARY) + set(CURSES_LIBRARIES ${CURSES_LIBRARIES} ${CURSES_EXTRA_LIBRARY}) + endif() + + if(CURSES_FORM_LIBRARY) + set(CURSES_LIBRARIES ${CURSES_LIBRARIES} ${CURSES_FORM_LIBRARY}) + endif() + + # Provide the *_INCLUDE_DIRS result. + set(CURSES_INCLUDE_DIRS ${CURSES_INCLUDE_PATH}) + set(CURSES_INCLUDE_DIR ${CURSES_INCLUDE_PATH}) # compatibility + + # handle the QUIETLY and REQUIRED arguments and set CURSES_FOUND to TRUE if + # all listed variables are TRUE + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ncursesw DEFAULT_MSG + CURSES_LIBRARY CURSES_INCLUDE_PATH) + set(CURSES_FOUND ${NCURSESW_FOUND}) + +else() + find_package(Curses) + set(NCURSESW_FOUND FALSE) +endif() + +mark_as_advanced( + CURSES_INCLUDE_PATH + CURSES_CURSES_LIBRARY + CURSES_NCURSES_LIBRARY + CURSES_NCURSESW_LIBRARY + CURSES_EXTRA_LIBRARY + CURSES_FORM_LIBRARY + ) diff --git a/cmake/Modules/FindSQLite3.cmake b/cmake/Modules/FindSQLite3.cmake new file mode 100644 index 0000000..8a66cb2 --- /dev/null +++ b/cmake/Modules/FindSQLite3.cmake @@ -0,0 +1,9 @@ +mark_as_advanced(SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR) + +find_path(SQLITE3_INCLUDE_DIR sqlite3.h) + +find_library(SQLITE3_LIBRARY NAMES sqlite3) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(SQLite3 DEFAULT_MSG SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR) + diff --git a/cmake/Modules/FindVorbis.cmake b/cmake/Modules/FindVorbis.cmake new file mode 100644 index 0000000..222ddd9 --- /dev/null +++ b/cmake/Modules/FindVorbis.cmake @@ -0,0 +1,45 @@ +# - Find vorbis +# Find the native vorbis includes and libraries +# +# VORBIS_INCLUDE_DIR - where to find vorbis.h, etc. +# OGG_INCLUDE_DIR - where to find ogg/ogg.h, etc. +# VORBIS_LIBRARIES - List of libraries when using vorbis(file). +# VORBIS_FOUND - True if vorbis found. + +if(NOT GP2XWIZ) + if(VORBIS_INCLUDE_DIR) + # Already in cache, be silent + set(VORBIS_FIND_QUIETLY TRUE) + endif(VORBIS_INCLUDE_DIR) + find_path(OGG_INCLUDE_DIR ogg/ogg.h) + find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h) + # MSVC built ogg/vorbis may be named ogg_static and vorbis_static + find_library(OGG_LIBRARY NAMES ogg ogg_static) + find_library(VORBIS_LIBRARY NAMES vorbis vorbis_static) + find_library(VORBISFILE_LIBRARY NAMES vorbisfile vorbisfile_static) + # Handle the QUIETLY and REQUIRED arguments and set VORBIS_FOUND + # to TRUE if all listed variables are TRUE. + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Vorbis DEFAULT_MSG + OGG_INCLUDE_DIR VORBIS_INCLUDE_DIR + OGG_LIBRARY VORBIS_LIBRARY VORBISFILE_LIBRARY) +else(NOT GP2XWIZ) + find_path(VORBIS_INCLUDE_DIR tremor/ivorbisfile.h) + find_library(VORBIS_LIBRARY NAMES vorbis_dec) + find_package_handle_standard_args(Vorbis DEFAULT_MSG + VORBIS_INCLUDE_DIR VORBIS_LIBRARY) +endif(NOT GP2XWIZ) + +if(VORBIS_FOUND) + if(NOT GP2XWIZ) + set(VORBIS_LIBRARIES ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} + ${OGG_LIBRARY}) + else(NOT GP2XWIZ) + set(VORBIS_LIBRARIES ${VORBIS_LIBRARY}) + endif(NOT GP2XWIZ) +else(VORBIS_FOUND) + set(VORBIS_LIBRARIES) +endif(VORBIS_FOUND) + +mark_as_advanced(OGG_INCLUDE_DIR VORBIS_INCLUDE_DIR) +mark_as_advanced(OGG_LIBRARY VORBIS_LIBRARY VORBISFILE_LIBRARY) diff --git a/cmake/Modules/FindZstd.cmake b/cmake/Modules/FindZstd.cmake new file mode 100644 index 0000000..e28e133 --- /dev/null +++ b/cmake/Modules/FindZstd.cmake @@ -0,0 +1,25 @@ +mark_as_advanced(ZSTD_LIBRARY ZSTD_INCLUDE_DIR) + +find_path(ZSTD_INCLUDE_DIR NAMES zstd.h) + +find_library(ZSTD_LIBRARY NAMES zstd) + +if(ZSTD_INCLUDE_DIR AND ZSTD_LIBRARY) + # Check that the API we use exists + include(CheckSymbolExists) + unset(HAVE_ZSTD_INITCSTREAM CACHE) + set(CMAKE_REQUIRED_INCLUDES ${ZSTD_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${ZSTD_LIBRARY}) + check_symbol_exists(ZSTD_initCStream zstd.h HAVE_ZSTD_INITCSTREAM) + unset(CMAKE_REQUIRED_INCLUDES) + unset(CMAKE_REQUIRED_LIBRARIES) + + if(NOT HAVE_ZSTD_INITCSTREAM) + unset(ZSTD_INCLUDE_DIR CACHE) + unset(ZSTD_LIBRARY CACHE) + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Zstd DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR) + diff --git a/cmake/Modules/GenerateVersion.cmake b/cmake/Modules/GenerateVersion.cmake new file mode 100644 index 0000000..ad0e382 --- /dev/null +++ b/cmake/Modules/GenerateVersion.cmake @@ -0,0 +1,26 @@ +# Always run during 'make' + +if(DEVELOPMENT_BUILD) + execute_process(COMMAND git rev-parse --short HEAD + WORKING_DIRECTORY "${GENERATE_VERSION_SOURCE_DIR}" + OUTPUT_VARIABLE VERSION_GITHASH OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + if(VERSION_GITHASH) + set(VERSION_GITHASH "${VERSION_STRING}-${VERSION_GITHASH}") + execute_process(COMMAND git diff-index --quiet HEAD + WORKING_DIRECTORY "${GENERATE_VERSION_SOURCE_DIR}" + RESULT_VARIABLE IS_DIRTY) + if(IS_DIRTY) + set(VERSION_GITHASH "${VERSION_GITHASH}-dirty") + endif() + message(STATUS "*** Detected Git version ${VERSION_GITHASH} ***") + endif() +endif() +if(NOT VERSION_GITHASH) + set(VERSION_GITHASH "${VERSION_STRING}") +endif() + +configure_file( + ${GENERATE_VERSION_SOURCE_DIR}/cmake_config_githash.h.in + ${GENERATE_VERSION_BINARY_DIR}/cmake_config_githash.h) + diff --git a/cmake/Modules/MinetestFindIrrlichtHeaders.cmake b/cmake/Modules/MinetestFindIrrlichtHeaders.cmake new file mode 100644 index 0000000..e434b58 --- /dev/null +++ b/cmake/Modules/MinetestFindIrrlichtHeaders.cmake @@ -0,0 +1,18 @@ +# Locate IrrlichtMt headers on system. + +find_path(IRRLICHT_INCLUDE_DIR NAMES irrlicht.h + DOC "Path to the directory with IrrlichtMt includes" + PATHS + /usr/local/include/irrlichtmt + /usr/include/irrlichtmt + /system/develop/headers/irrlichtmt #Haiku + PATH_SUFFIXES "include/irrlichtmt" +) + +# Handholding for users +if(IRRLICHT_INCLUDE_DIR AND (NOT IS_DIRECTORY "${IRRLICHT_INCLUDE_DIR}" OR + NOT EXISTS "${IRRLICHT_INCLUDE_DIR}/irrlicht.h")) + message(WARNING "IRRLICHT_INCLUDE_DIR was set to ${IRRLICHT_INCLUDE_DIR} " + "but irrlicht.h does not exist inside. The path will not be used.") + unset(IRRLICHT_INCLUDE_DIR CACHE) +endif() diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in new file mode 100644 index 0000000..ae36fd6 --- /dev/null +++ b/doc/Doxyfile.in @@ -0,0 +1,44 @@ +# Project properties +PROJECT_NAME = @PROJECT_NAME_CAPITALIZED@ +PROJECT_NUMBER = @VERSION_STRING@ +PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/misc/minetest.svg + +# Parsing +JAVADOC_AUTOBRIEF = YES +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +SORT_MEMBERS_CTORS_1ST = YES +WARN_IF_UNDOCUMENTED = NO +BUILTIN_STL_SUPPORT = YES +PREDEFINED = "USE_SPATIAL=1" \ + "USE_LEVELDB=1" \ + "USE_REDIS=1" \ + "USE_SOUND=1" \ + "USE_CURL=1" \ + "USE_GETTEXT=1" + +# Input +RECURSIVE = YES +STRIP_FROM_PATH = @CMAKE_CURRENT_SOURCE_DIR@/src +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/doc/main_page.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/ + +# Dot graphs +HAVE_DOT = @DOXYGEN_DOT_FOUND@ +CALL_GRAPH = YES +CALLER_GRAPH = YES +MAX_DOT_GRAPH_DEPTH = 3 +DOT_MULTI_TARGETS = YES +DOT_IMAGE_FORMAT = svg + +# Output +GENERATE_LATEX = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +SEARCHENGINE = YES +DISABLE_INDEX = YES +GENERATE_TREEVIEW = YES +HTML_DYNAMIC_SECTIONS = YES +HTML_TIMESTAMP = YES + diff --git a/doc/README.android b/doc/README.android new file mode 100644 index 0000000..3833688 --- /dev/null +++ b/doc/README.android @@ -0,0 +1,81 @@ +Minetest: Android version +========================= + +Controls +-------- +The Android port doesn't support everything you can do on PC due to the +limited capabilities of common devices. What can be done is described +below: + +While you're playing the game normally (that is, no menu or inventory is +shown), the following controls are available: +* Look around: touch screen and slide finger +* double tap: place a node or use selected item +* long tap: dig node +* touch shown buttons: press button +* Buttons: +** left upper corner: chat +** right lower corner: jump +** right lower corner: crouch +** left lower corner: walk/step... + left up right + down +** left lower corner: display inventory + +When a menu or inventory is displayed: +* double tap outside menu area: close menu +* tap on an item stack: select that stack +* tap on an empty slot: if you selected a stack already, that stack is placed here +* drag and drop: touch stack and hold finger down, move the stack to another + slot, tap another finger while keeping first finger on screen + --> places a single item from dragged stack into current (first touched) slot + +Special settings +---------------- +There are some settings especially useful for Android users. Minetest's config +file can usually be found at /mnt/sdcard/Minetest. + +* gui_scaling: this is a user-specified scaling factor for the GUI- In case + main menu is too big or small on your device, try changing this + value. + +Requirements +------------ + +In order to build, your PC has to be set up to build Minetest in the usual +manner (see the regular Minetest documentation for how to get this done). +In addition to what is required for Minetest in general, you will need the +following software packages. The version number in parenthesis denotes the +version that was tested at the time this README was drafted; newer/older +versions may or may not work. + +* Android SDK 29 +* Android NDK r21 +* Android Studio 3 [optional] + +Additionally, you'll need to have an Internet connection available on the +build system, as the Android build will download some source packages. + +Build +----- + +The new build system Minetest Android is fully functional and is designed to +speed up and simplify the work, as well as adding the possibility of +cross-platform build. +You can use `./gradlew assemblerelease` or `./gradlew assembledebug` from the +command line or use Android Studio and click the build button. + +When using gradlew, the newest NDK will be downloaded and installed +automatically. Or you can create a `local.properties` file and specify +`sdk.dir` and `ndk.dir` yourself. + +* In order to make a release build you'll have to have a keystore setup to sign + the resulting apk package. How this is done is not part of this README. There + are different tutorials on the web explaining how to do it + - choose one yourself. + +* Once your keystore is setup, enter the android subdirectory and create a new + file "ant.properties" there. Add following lines to that file: + + > key.store=<path to your keystore> + > key.alias=Minetest diff --git a/doc/breakages.md b/doc/breakages.md new file mode 100644 index 0000000..f7078f1 --- /dev/null +++ b/doc/breakages.md @@ -0,0 +1,8 @@ +# Minetest Major Breakages List + +This document contains a list of breaking changes to be made in the next major version. + +* Remove attachment space multiplier (*10) +* `get_sky()` returns a table (without arg) +* `game.conf` name/id mess +* remove `depends.txt` / `description.txt` (would simplify ContentDB and Minetest code a little) diff --git a/doc/builtin_entities.txt b/doc/builtin_entities.txt new file mode 100644 index 0000000..be3f733 --- /dev/null +++ b/doc/builtin_entities.txt @@ -0,0 +1,101 @@ +# Builtin Entities +Minetest registers two entities by default: Falling nodes and dropped items. +This document describes how they behave and what you can do with them. + +## Falling node (`__builtin:falling_node`) + +This entity is created by `minetest.check_for_falling` in place of a node +with the special group `falling_node=1`. Falling nodes can also be created +artificially with `minetest.spawn_falling_node`. + +Needs manual initialization when spawned using `/spawnentity`. + +Default behaviour: + +* Falls down in a straight line (gravity = `movement_gravity` setting) +* Collides with `walkable` node +* Collides with all physical objects except players +* If the node group `float=1` is set, it also collides with liquid nodes +* When it hits a solid (=`walkable`) node, it will try to place itself as a + node, replacing the node above. + * If the falling node cannot replace the destination node, it is dropped. + * If the destination node is a leveled node (`paramtype2="leveled"`) of the + same node name, the levels of both are summed. + +### Entity fields + +* `set_node(self, node[, meta])` + * Function to initialize the falling node + * `node` and `meta` are explained below. + * The `meta` argument is optional. +* `node`: Node table of the node (`name`, `param1`, `param2`) that this + entity represents. Read-only. +* `meta`: Node metadata of the falling node. Will be used when the falling + nodes tries to place itself as a node. Read-only. + +### Rendering / supported nodes + +Falling nodes have visuals to look as close as possible to the original node. +This works for most drawtypes, but there are limitations. + +Supported drawtypes: + +* `normal` +* `signlike` +* `torchlike` +* `nodebox` +* `raillike` +* `glasslike` +* `glasslike_framed` +* `glasslike_framed_optional` +* `allfaces` +* `allfaces_optional` +* `firelike` +* `mesh` +* `fencelike` +* `liquid` +* `airlike` (not pointable) + +Other drawtypes still kinda work, but they might look weird. + +Supported `paramtype2` values: + +* `wallmounted` +* `facedir` +* `colorwallmounted` +* `colorfacedir` +* `color` + +## Dropped item stack (`__builtin:item`) + +This is an item stack in a collectable form. + +Common cases that spawn a dropped item: + +* Item dropped by player +* The root node of a node with the group `attached_node=1` is removed +* `minetest.add_item` is called + +Needs manual initialization when spawned using `/spawnentity`. + +### Behavior + +* Players can collect it by punching +* Lifespan is defined by the setting `item_entity_ttl` +* Slides on `slippery` nodes +* Subject to gravity (uses `movement_gravity` setting) +* Collides with `walkable` nodes +* Does not collide physical objects +* When it's inside a solid (`walkable=true`) node, it tries to escape to a + neighboring non-solid (`walkable=false`) node + +### Entity fields + +* `set_item(self, item)`: + * Function to initialize the dropped item + * `item` (type `ItemStack`) specifies the item to represent +* `age`: Age in seconds. Behaviour according to the setting `item_entity_ttl` +* `itemstring`: Itemstring of the item that this item entity represents. + Read-only. + +Other fields are for internal use only. diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt new file mode 100644 index 0000000..8a450ba --- /dev/null +++ b/doc/client_lua_api.txt @@ -0,0 +1,1527 @@ +Minetest Lua Client Modding API Reference 5.6.0 +================================================ +* More information at <http://www.minetest.net/> +* Developer Wiki: <http://dev.minetest.net/> + +Introduction +------------ + +** WARNING: The client API is currently unstable, and may break/change without warning. ** + +Content and functionality can be added to Minetest 0.4.15-dev+ by using Lua +scripting in run-time loaded mods. + +A mod is a self-contained bunch of scripts, textures and other related +things that is loaded by and interfaces with Minetest. + +Transferring client-sided mods from the server to the client is planned, but not implemented yet. + +If you see a deficiency in the API, feel free to attempt to add the +functionality in the engine and API. You can send such improvements as +source code patches on GitHub (https://github.com/minetest/minetest). + +Programming in Lua +------------------ +If you have any difficulty in understanding this, please read +[Programming in Lua](http://www.lua.org/pil/). + +Startup +------- +Mods are loaded during client startup from the mod load paths by running +the `init.lua` scripts in a shared environment. + +In order to load client-side mods, the following conditions need to be satisfied: + +1) `$path_user/minetest.conf` contains the setting `enable_client_modding = true` + +2) The client-side mod located in `$path_user/clientmods/<modname>` is added to + `$path_user/clientmods/mods.conf` as `load_mod_<modname> = true`. + +Note: Depending on the remote server's settings, client-side mods might not +be loaded or have limited functionality. See setting `csm_restriction_flags` for reference. + +Paths +----- +* `RUN_IN_PLACE=1` (Windows release, local build) + * `$path_user`: `<build directory>` + * `$path_share`: `<build directory>` +* `RUN_IN_PLACE=0`: (Linux release) + * `$path_share`: + * Linux: `/usr/share/minetest` + * Windows: `<install directory>/minetest-0.4.x` + * `$path_user`: + * Linux: `$HOME/.minetest` + * Windows: `C:/users/<user>/AppData/minetest` (maybe) + +Mod load path +------------- +Generic: + +* `$path_share/clientmods/` +* `$path_user/clientmods/` (User-installed mods) + +In a run-in-place version (e.g. the distributed windows version): + +* `minetest-0.4.x/clientmods/` (User-installed mods) + +On an installed version on Linux: + +* `/usr/share/minetest/clientmods/` +* `$HOME/.minetest/clientmods/` (User-installed mods) + +Modpack support +---------------- + +Mods can be put in a subdirectory, if the parent directory, which otherwise +should be a mod, contains a file named `modpack.conf`. +The file is a key-value store of modpack details. + +* `name`: The modpack name. +* `description`: Description of mod to be shown in the Mods tab of the main + menu. + +Mod directory structure +------------------------ + + clientmods + ├── modname + │   ├── mod.conf + │   ├── init.lua + └── another + +### modname + +The location of this directory. + +### mod.conf + +An (optional) settings file that provides meta information about the mod. + +* `name`: The mod name. Allows Minetest to determine the mod name even if the + folder is wrongly named. +* `description`: Description of mod to be shown in the Mods tab of the main + menu. +* `depends`: A comma separated list of dependencies. These are mods that must be + loaded before this mod. +* `optional_depends`: A comma separated list of optional dependencies. + Like a dependency, but no error if the mod doesn't exist. + +### `init.lua` + +The main Lua script. Running this script should register everything it +wants to register. Subsequent execution depends on minetest calling the +registered callbacks. + +**NOTE**: Client mods currently can't provide textures, sounds, or models by +themselves. Any media referenced in function calls must already be loaded +(provided by mods that exist on the server). + +Naming convention for registered textual names +---------------------------------------------- +Registered names should generally be in this format: + + "modname:<whatever>" (<whatever> can have characters a-zA-Z0-9_) + +This is to prevent conflicting names from corrupting maps and is +enforced by the mod loader. + +### Example +In the mod `experimental`, there is the ideal item/node/entity name `tnt`. +So the name should be `experimental:tnt`. + +Enforcement can be overridden by prefixing the name with `:`. This can +be used for overriding the registrations of some other mod. + +Example: Any mod can redefine `experimental:tnt` by using the name + + :experimental:tnt + +when registering it. +(also that mod is required to have `experimental` as a dependency) + +The `:` prefix can also be used for maintaining backwards compatibility. + +Sounds +------ +**NOTE: Connecting sounds to objects is not implemented.** + +Only Ogg Vorbis files are supported. + +For positional playing of sounds, only single-channel (mono) files are +supported. Otherwise OpenAL will play them non-positionally. + +Mods should generally prefix their sounds with `modname_`, e.g. given +the mod name "`foomod`", a sound could be called: + + foomod_foosound.ogg + +Sounds are referred to by their name with a dot, a single digit and the +file extension stripped out. When a sound is played, the actual sound file +is chosen randomly from the matching sounds. + +When playing the sound `foomod_foosound`, the sound is chosen randomly +from the available ones of the following files: + +* `foomod_foosound.ogg` +* `foomod_foosound.0.ogg` +* `foomod_foosound.1.ogg` +* (...) +* `foomod_foosound.9.ogg` + +Examples of sound parameter tables: + + -- Play locationless + { + gain = 1.0, -- default + } + -- Play locationless, looped + { + gain = 1.0, -- default + loop = true, + } + -- Play in a location + { + pos = {x = 1, y = 2, z = 3}, + gain = 1.0, -- default + } + -- Play connected to an object, looped + { + object = <an ObjectRef>, + gain = 1.0, -- default + loop = true, + } + +Looped sounds must either be connected to an object or played locationless. + +### SimpleSoundSpec +* e.g. `""` +* e.g. `"default_place_node"` +* e.g. `{}` +* e.g. `{name = "default_place_node"}` +* e.g. `{name = "default_place_node", gain = 1.0}` + +Representations of simple things +-------------------------------- + +### Position/vector + + {x=num, y=num, z=num} + +For helper functions see "Vector helpers". + +### pointed_thing +* `{type="nothing"}` +* `{type="node", under=pos, above=pos}` +* `{type="object", id=ObjectID}` + +Flag Specifier Format +--------------------- +Flags using the standardized flag specifier format can be specified in either of +two ways, by string or table. + +The string format is a comma-delimited set of flag names; whitespace and +unrecognized flag fields are ignored. Specifying a flag in the string sets the +flag, and specifying a flag prefixed by the string `"no"` explicitly +clears the flag from whatever the default may be. + +In addition to the standard string flag format, the schematic flags field can +also be a table of flag names to boolean values representing whether or not the +flag is set. Additionally, if a field with the flag name prefixed with `"no"` +is present, mapped to a boolean of any value, the specified flag is unset. + +E.g. A flag field of value + + {place_center_x = true, place_center_y=false, place_center_z=true} + +is equivalent to + + {place_center_x = true, noplace_center_y=true, place_center_z=true} + +which is equivalent to + + "place_center_x, noplace_center_y, place_center_z" + +or even + + "place_center_x, place_center_z" + +since, by default, no schematic attributes are set. + +Formspec +-------- +Formspec defines a menu. It is a string, with a somewhat strange format. + +Spaces and newlines can be inserted between the blocks, as is used in the +examples. + +### Examples + +#### Chest + + size[8,9] + list[context;main;0,0;8,4;] + list[current_player;main;0,5;8,4;] + +#### Furnace + + size[8,9] + list[context;fuel;2,3;1,1;] + list[context;src;2,1;1,1;] + list[context;dst;5,1;2,2;] + list[current_player;main;0,5;8,4;] + +#### Minecraft-like player inventory + + size[8,7.5] + image[1,0.6;1,2;player.png] + list[current_player;main;0,3.5;8,4;] + list[current_player;craft;3,0;3,3;] + list[current_player;craftpreview;7,1;1,1;] + +### Elements + +#### `size[<W>,<H>,<fixed_size>]` +* Define the size of the menu in inventory slots +* `fixed_size`: `true`/`false` (optional) +* deprecated: `invsize[<W>,<H>;]` + +#### `container[<X>,<Y>]` +* Start of a container block, moves all physical elements in the container by (X, Y) +* Must have matching container_end +* Containers can be nested, in which case the offsets are added + (child containers are relative to parent containers) + +#### `container_end[]` +* End of a container, following elements are no longer relative to this container + +#### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;]` +* Show an inventory list + +#### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]` +* Show an inventory list + +#### `listring[<inventory location>;<list name>]` +* Allows to create a ring of inventory lists +* Shift-clicking on items in one element of the ring + will send them to the next inventory list inside the ring +* The first occurrence of an element inside the ring will + determine the inventory where items will be sent to + +#### `listring[]` +* Shorthand for doing `listring[<inventory location>;<list name>]` + for the last two inventory lists added by list[...] + +#### `listcolors[<slot_bg_normal>;<slot_bg_hover>]` +* Sets background color of slots as `ColorString` +* Sets background color of slots on mouse hovering + +#### `listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>]` +* Sets background color of slots as `ColorString` +* Sets background color of slots on mouse hovering +* Sets color of slots border + +#### `listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>;<tooltip_bgcolor>;<tooltip_fontcolor>]` +* Sets background color of slots as `ColorString` +* Sets background color of slots on mouse hovering +* Sets color of slots border +* Sets default background color of tooltips +* Sets default font color of tooltips + +#### `tooltip[<gui_element_name>;<tooltip_text>;<bgcolor>,<fontcolor>]` +* Adds tooltip for an element +* `<bgcolor>` tooltip background color as `ColorString` (optional) +* `<fontcolor>` tooltip font color as `ColorString` (optional) + +#### `image[<X>,<Y>;<W>,<H>;<texture name>]` +* Show an image +* Position and size units are inventory slots + +#### `item_image[<X>,<Y>;<W>,<H>;<item name>]` +* Show an inventory image of registered item/node +* Position and size units are inventory slots + +#### `bgcolor[<color>;<fullscreen>]` +* Sets background color of formspec as `ColorString` +* If `true`, the background color is drawn fullscreen (does not effect the size of the formspec) + +#### `background[<X>,<Y>;<W>,<H>;<texture name>]` +* Use a background. Inventory rectangles are not drawn then. +* Position and size units are inventory slots +* Example for formspec 8x4 in 16x resolution: image shall be sized + 8 times 16px times 4 times 16px. + +#### `background[<X>,<Y>;<W>,<H>;<texture name>;<auto_clip>]` +* Use a background. Inventory rectangles are not drawn then. +* Position and size units are inventory slots +* Example for formspec 8x4 in 16x resolution: + image shall be sized 8 times 16px times 4 times 16px +* If `true` the background is clipped to formspec size + (`x` and `y` are used as offset values, `w` and `h` are ignored) + +#### `pwdfield[<X>,<Y>;<W>,<H>;<name>;<label>]` +* Textual password style field; will be sent to server when a button is clicked +* When enter is pressed in field, fields.key_enter_field will be sent with the name + of this field. +* `x` and `y` position the field relative to the top left of the menu +* `w` and `h` are the size of the field +* Fields are a set height, but will be vertically centred on `h` +* Position and size units are inventory slots +* `name` is the name of the field as returned in fields to `on_receive_fields` +* `label`, if not blank, will be text printed on the top left above the field +* See field_close_on_enter to stop enter closing the formspec + +#### `field[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]` +* Textual field; will be sent to server when a button is clicked +* When enter is pressed in field, fields.key_enter_field will be sent with the name + of this field. +* `x` and `y` position the field relative to the top left of the menu +* `w` and `h` are the size of the field +* Fields are a set height, but will be vertically centred on `h` +* Position and size units are inventory slots +* `name` is the name of the field as returned in fields to `on_receive_fields` +* `label`, if not blank, will be text printed on the top left above the field +* `default` is the default value of the field + * `default` may contain variable references such as `${text}'` which + will fill the value from the metadata value `text` + * **Note**: no extra text or more than a single variable is supported ATM. +* See field_close_on_enter to stop enter closing the formspec + +#### `field[<name>;<label>;<default>]` +* As above, but without position/size units +* When enter is pressed in field, fields.key_enter_field will be sent with the name + of this field. +* Special field for creating simple forms, such as sign text input +* Must be used without a `size[]` element +* A "Proceed" button will be added automatically +* See field_close_on_enter to stop enter closing the formspec + +#### `field_close_on_enter[<name>;<close_on_enter>]` +* <name> is the name of the field +* if <close_on_enter> is false, pressing enter in the field will submit the form but not close it +* defaults to true when not specified (ie: no tag for a field) + +#### `textarea[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]` +* Same as fields above, but with multi-line input + +#### `label[<X>,<Y>;<label>]` +* `x` and `y` work as per field +* `label` is the text on the label +* Position and size units are inventory slots + +#### `vertlabel[<X>,<Y>;<label>]` +* Textual label drawn vertically +* `x` and `y` work as per field +* `label` is the text on the label +* Position and size units are inventory slots + +#### `button[<X>,<Y>;<W>,<H>;<name>;<label>]` +* Clickable button. When clicked, fields will be sent. +* `x`, `y` and `name` work as per field +* `w` and `h` are the size of the button +* Fixed button height. It will be vertically centred on `h` +* `label` is the text on the button +* Position and size units are inventory slots + +#### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]` +* `x`, `y`, `w`, `h`, and `name` work as per button +* `texture name` is the filename of an image +* Position and size units are inventory slots + +#### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>;<noclip>;<drawborder>;<pressed texture name>]` +* `x`, `y`, `w`, `h`, and `name` work as per button +* `texture name` is the filename of an image +* Position and size units are inventory slots +* `noclip=true` means the image button doesn't need to be within specified formsize +* `drawborder`: draw button border or not +* `pressed texture name` is the filename of an image on pressed state + +#### `item_image_button[<X>,<Y>;<W>,<H>;<item name>;<name>;<label>]` +* `x`, `y`, `w`, `h`, `name` and `label` work as per button +* `item name` is the registered name of an item/node, + tooltip will be made out of its description + to override it use tooltip element +* Position and size units are inventory slots + +#### `button_exit[<X>,<Y>;<W>,<H>;<name>;<label>]` +* When clicked, fields will be sent and the form will quit. + +#### `image_button_exit[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]` +* When clicked, fields will be sent and the form will quit. + +#### `textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>]` +* Scrollable item list showing arbitrary text elements +* `x` and `y` position the itemlist relative to the top left of the menu +* `w` and `h` are the size of the itemlist +* `name` fieldname sent to server on doubleclick value is current selected element +* `listelements` can be prepended by #color in hexadecimal format RRGGBB (only), + * if you want a listelement to start with "#" write "##". + +#### `textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>;<selected idx>;<transparent>]` +* Scrollable itemlist showing arbitrary text elements +* `x` and `y` position the item list relative to the top left of the menu +* `w` and `h` are the size of the item list +* `name` fieldname sent to server on doubleclick value is current selected element +* `listelements` can be prepended by #RRGGBB (only) in hexadecimal format + * if you want a listelement to start with "#" write "##" +* Index to be selected within textlist +* `true`/`false`: draw transparent background +* See also `minetest.explode_textlist_event` (main menu: `engine.explode_textlist_event`) + +#### `tabheader[<X>,<Y>;<name>;<caption 1>,<caption 2>,...,<caption n>;<current_tab>;<transparent>;<draw_border>]` +* Show a tab**header** at specific position (ignores formsize) +* `x` and `y` position the itemlist relative to the top left of the menu +* `name` fieldname data is transferred to Lua +* `caption 1`...: name shown on top of tab +* `current_tab`: index of selected tab 1... +* `transparent` (optional): show transparent +* `draw_border` (optional): draw border + +#### `box[<X>,<Y>;<W>,<H>;<color>]` +* Simple colored semitransparent box +* `x` and `y` position the box relative to the top left of the menu +* `w` and `h` are the size of box +* `color` is color specified as a `ColorString` + +#### `dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]` +* Show a dropdown field +* **Important note**: There are two different operation modes: + 1. handle directly on change (only changed dropdown is submitted) + 2. read the value on pressing a button (all dropdown values are available) +* `x` and `y` position of dropdown +* Width of dropdown +* Fieldname data is transferred to Lua +* Items to be shown in dropdown +* Index of currently selected dropdown item + +#### `checkbox[<X>,<Y>;<name>;<label>;<selected>]` +* Show a checkbox +* `x` and `y`: position of checkbox +* `name` fieldname data is transferred to Lua +* `label` to be shown left of checkbox +* `selected` (optional): `true`/`false` + +#### `scrollbar[<X>,<Y>;<W>,<H>;<orientation>;<name>;<value>]` +* Show a scrollbar +* There are two ways to use it: + 1. handle the changed event (only changed scrollbar is available) + 2. read the value on pressing a button (all scrollbars are available) +* `x` and `y`: position of trackbar +* `w` and `h`: width and height +* `orientation`: `vertical`/`horizontal` +* Fieldname data is transferred to Lua +* Value this trackbar is set to (`0`-`1000`) +* See also `minetest.explode_scrollbar_event` (main menu: `engine.explode_scrollbar_event`) + +#### `table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]` +* Show scrollable table using options defined by the previous `tableoptions[]` +* Displays cells as defined by the previous `tablecolumns[]` +* `x` and `y`: position the itemlist relative to the top left of the menu +* `w` and `h` are the size of the itemlist +* `name`: fieldname sent to server on row select or doubleclick +* `cell 1`...`cell n`: cell contents given in row-major order +* `selected idx`: index of row to be selected within table (first row = `1`) +* See also `minetest.explode_table_event` (main menu: `engine.explode_table_event`) + +#### `tableoptions[<opt 1>;<opt 2>;...]` +* Sets options for `table[]` +* `color=#RRGGBB` + * default text color (`ColorString`), defaults to `#FFFFFF` +* `background=#RRGGBB` + * table background color (`ColorString`), defaults to `#000000` +* `border=<true/false>` + * should the table be drawn with a border? (default: `true`) +* `highlight=#RRGGBB` + * highlight background color (`ColorString`), defaults to `#466432` +* `highlight_text=#RRGGBB` + * highlight text color (`ColorString`), defaults to `#FFFFFF` +* `opendepth=<value>` + * all subtrees up to `depth < value` are open (default value = `0`) + * only useful when there is a column of type "tree" + +#### `tablecolumns[<type 1>,<opt 1a>,<opt 1b>,...;<type 2>,<opt 2a>,<opt 2b>;...]` +* Sets columns for `table[]` +* Types: `text`, `image`, `color`, `indent`, `tree` + * `text`: show cell contents as text + * `image`: cell contents are an image index, use column options to define images + * `color`: cell contents are a ColorString and define color of following cell + * `indent`: cell contents are a number and define indentation of following cell + * `tree`: same as indent, but user can open and close subtrees (treeview-like) +* Column options: + * `align=<value>` + * for `text` and `image`: content alignment within cells. + Available values: `left` (default), `center`, `right`, `inline` + * `width=<value>` + * for `text` and `image`: minimum width in em (default: `0`) + * for `indent` and `tree`: indent width in em (default: `1.5`) + * `padding=<value>`: padding left of the column, in em (default `0.5`). + Exception: defaults to 0 for indent columns + * `tooltip=<value>`: tooltip text (default: empty) + * `image` column options: + * `0=<value>` sets image for image index 0 + * `1=<value>` sets image for image index 1 + * `2=<value>` sets image for image index 2 + * and so on; defined indices need not be contiguous empty or + non-numeric cells are treated as `0`. + * `color` column options: + * `span=<value>`: number of following columns to affect (default: infinite) + +**Note**: do _not_ use a element name starting with `key_`; those names are reserved to +pass key press events to formspec! + +Spatial Vectors +--------------- +* `vector.new(a[, b, c])`: returns a vector: + * A copy of `a` if `a` is a vector. + * `{x = a, y = b, z = c}`, if all `a, b, c` are defined +* `vector.direction(p1, p2)`: returns a vector +* `vector.distance(p1, p2)`: returns a number +* `vector.length(v)`: returns a number +* `vector.normalize(v)`: returns a vector +* `vector.floor(v)`: returns a vector, each dimension rounded down +* `vector.round(v)`: returns a vector, each dimension rounded to nearest int +* `vector.apply(v, func)`: returns a vector +* `vector.combine(v, w, func)`: returns a vector +* `vector.equals(v1, v2)`: returns a boolean + +For the following functions `x` can be either a vector or a number: + +* `vector.add(v, x)`: returns a vector +* `vector.subtract(v, x)`: returns a vector +* `vector.multiply(v, x)`: returns a scaled vector or Schur product +* `vector.divide(v, x)`: returns a scaled vector or Schur quotient + +Helper functions +---------------- +* `dump2(obj, name="_", dumped={})` + * Return object serialized as a string, handles reference loops +* `dump(obj, dumped={})` + * Return object serialized as a string +* `math.hypot(x, y)` + * Get the hypotenuse of a triangle with legs x and y. + Useful for distance calculation. +* `math.sign(x, tolerance)` + * Get the sign of a number. + Optional: Also returns `0` when the absolute value is within the tolerance (default: `0`) +* `string.split(str, separator=",", include_empty=false, max_splits=-1, sep_is_pattern=false)` + * If `max_splits` is negative, do not limit splits. + * `sep_is_pattern` specifies if separator is a plain string or a pattern (regex). + * e.g. `string:split("a,b", ",") == {"a","b"}` +* `string:trim()` + * e.g. `string.trim("\n \t\tfoo bar\t ") == "foo bar"` +* `minetest.wrap_text(str, limit)`: returns a string + * Adds new lines to the string to keep it within the specified character limit + * limit: Maximal amount of characters in one line +* `minetest.pos_to_string({x=X,y=Y,z=Z}, decimal_places))`: returns string `"(X,Y,Z)"` + * Convert position to a printable string + Optional: 'decimal_places' will round the x, y and z of the pos to the given decimal place. +* `minetest.string_to_pos(string)`: returns a position + * Same but in reverse. Returns `nil` if the string can't be parsed to a position. +* `minetest.string_to_area("(X1, Y1, Z1) (X2, Y2, Z2)")`: returns two positions + * Converts a string representing an area box into two positions +* `minetest.is_yes(arg)` + * returns whether `arg` can be interpreted as yes +* `minetest.is_nan(arg)` + * returns true when the passed number represents NaN. +* `table.copy(table)`: returns a table + * returns a deep copy of `table` + +Minetest namespace reference +------------------------------ + +### Utilities + +* `minetest.get_current_modname()`: returns the currently loading mod's name, when we are loading a mod +* `minetest.get_modpath(modname)`: returns virtual path of given mod including + the trailing separator. This is useful to load additional Lua files + contained in your mod: + e.g. `dofile(minetest.get_modpath(minetest.get_current_modname()) .. "stuff.lua")` +* `minetest.get_language()`: returns two strings + * the current gettext locale + * the current language code (the same as used for client-side translations) +* `minetest.get_version()`: returns a table containing components of the + engine version. Components: + * `project`: Name of the project, eg, "Minetest" + * `string`: Simple version, eg, "1.2.3-dev" + * `hash`: Full git version (only set if available), eg, "1.2.3-dev-01234567-dirty" + Use this for informational purposes only. The information in the returned + table does not represent the capabilities of the engine, nor is it + reliable or verifiable. Compatible forks will have a different name and + version entirely. To check for the presence of engine features, test + whether the functions exported by the wanted features exist. For example: + `if minetest.check_for_falling then ... end`. +* `minetest.sha1(data, [raw])`: returns the sha1 hash of data + * `data`: string of data to hash + * `raw`: return raw bytes instead of hex digits, default: false +* `minetest.colorspec_to_colorstring(colorspec)`: Converts a ColorSpec to a + ColorString. If the ColorSpec is invalid, returns `nil`. + * `colorspec`: The ColorSpec to convert +* `minetest.get_csm_restrictions()`: returns a table of `Flags` indicating the + restrictions applied to the current mod. + * If a flag in this table is set to true, the feature is RESTRICTED. + * Possible flags: `load_client_mods`, `chat_messages`, `read_itemdefs`, + `read_nodedefs`, `lookup_nodes`, `read_playerinfo` + +### Logging +* `minetest.debug(...)` + * Equivalent to `minetest.log(table.concat({...}, "\t"))` +* `minetest.log([level,] text)` + * `level` is one of `"none"`, `"error"`, `"warning"`, `"action"`, + `"info"`, or `"verbose"`. Default is `"none"`. + +### Global callback registration functions +Call these functions only at load time! + +* `minetest.register_globalstep(function(dtime))` + * Called every client environment step, usually interval of 0.1s +* `minetest.register_on_mods_loaded(function())` + * Called just after mods have finished loading. +* `minetest.register_on_shutdown(function())` + * Called before client shutdown + * **Warning**: If the client terminates abnormally (i.e. crashes), the registered + callbacks **will likely not be run**. Data should be saved at + semi-frequent intervals as well as on server shutdown. +* `minetest.register_on_receiving_chat_message(function(message))` + * Called always when a client receive a message + * Return `true` to mark the message as handled, which means that it will not be shown to chat +* `minetest.register_on_sending_chat_message(function(message))` + * Called always when a client send a message from chat + * Return `true` to mark the message as handled, which means that it will not be sent to server +* `minetest.register_chatcommand(cmd, chatcommand definition)` + * Adds definition to minetest.registered_chatcommands +* `minetest.unregister_chatcommand(name)` + * Unregisters a chatcommands registered with register_chatcommand. +* `minetest.register_on_chatcommand(function(command, params))` + * Called always when a chatcommand is triggered, before `minetest.registered_chatcommands` + is checked to see if that the command exists, but after the input is parsed. + * Return `true` to mark the command as handled, which means that the default + handlers will be prevented. +* `minetest.register_on_death(function())` + * Called when the local player dies +* `minetest.register_on_hp_modification(function(hp))` + * Called when server modified player's HP +* `minetest.register_on_damage_taken(function(hp))` + * Called when the local player take damages +* `minetest.register_on_formspec_input(function(formname, fields))` + * Called when a button is pressed in the local player's inventory form + * Newest functions are called first + * If function returns `true`, remaining functions are not called +* `minetest.register_on_dignode(function(pos, node))` + * Called when the local player digs a node + * Newest functions are called first + * If any function returns true, the node isn't dug +* `minetest.register_on_punchnode(function(pos, node))` + * Called when the local player punches a node + * Newest functions are called first + * If any function returns true, the punch is ignored +* `minetest.register_on_placenode(function(pointed_thing, node))` + * Called when a node has been placed +* `minetest.register_on_item_use(function(item, pointed_thing))` + * Called when the local player uses an item. + * Newest functions are called first. + * If any function returns true, the item use is not sent to server. +* `minetest.register_on_modchannel_message(function(channel_name, sender, message))` + * Called when an incoming mod channel message is received + * You must have joined some channels before, and server must acknowledge the + join request. + * If message comes from a server mod, `sender` field is an empty string. +* `minetest.register_on_modchannel_signal(function(channel_name, signal))` + * Called when a valid incoming mod channel signal is received + * Signal id permit to react to server mod channel events + * Possible values are: + 0: join_ok + 1: join_failed + 2: leave_ok + 3: leave_failed + 4: event_on_not_joined_channel + 5: state_changed +* `minetest.register_on_inventory_open(function(inventory))` + * Called when the local player open inventory + * Newest functions are called first + * If any function returns true, inventory doesn't open +### Sounds +* `minetest.sound_play(spec, parameters)`: returns a handle + * `spec` is a `SimpleSoundSpec` + * `parameters` is a sound parameter table +* `minetest.sound_stop(handle)` + * `handle` is a handle returned by `minetest.sound_play` +* `minetest.sound_fade(handle, step, gain)` + * `handle` is a handle returned by `minetest.sound_play` + * `step` determines how fast a sound will fade. + Negative step will lower the sound volume, positive step will increase + the sound volume. + * `gain` the target gain for the fade. + +### Timing +* `minetest.after(time, func, ...)` + * Call the function `func` after `time` seconds, may be fractional + * Optional: Variable number of arguments that are passed to `func` +* `minetest.get_us_time()` + * Returns time with microsecond precision. May not return wall time. +* `minetest.get_timeofday()` + * Returns the time of day: `0` for midnight, `0.5` for midday + +### Map +* `minetest.get_node_or_nil(pos)` + * Returns the node at the given position as table in the format + `{name="node_name", param1=0, param2=0}`, returns `nil` + for unloaded areas or flavor limited areas. +* `minetest.get_node_light(pos, timeofday)` + * Gets the light value at the given position. Note that the light value + "inside" the node at the given position is returned, so you usually want + to get the light value of a neighbor. + * `pos`: The position where to measure the light. + * `timeofday`: `nil` for current time, `0` for night, `0.5` for day + * Returns a number between `0` and `15` or `nil` +* `minetest.find_node_near(pos, radius, nodenames, [search_center])`: returns pos or `nil` + * `radius`: using a maximum metric + * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` + * `search_center` is an optional boolean (default: `false`) + If true `pos` is also checked for the nodes +* `minetest.find_nodes_in_area(pos1, pos2, nodenames, [grouped])` + * `pos1` and `pos2` are the min and max positions of the area to search. + * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` + * If `grouped` is true the return value is a table indexed by node name + which contains lists of positions. + * If `grouped` is false or absent the return values are as follows: + first value: Table with all node positions + second value: Table with the count of each node with the node name + as index + * Area volume is limited to 4,096,000 nodes +* `minetest.find_nodes_in_area_under_air(pos1, pos2, nodenames)`: returns a + list of positions. + * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` + * Return value: Table with all node positions with a node air above + * Area volume is limited to 4,096,000 nodes +* `minetest.line_of_sight(pos1, pos2)`: returns `boolean, pos` + * Checks if there is anything other than air between pos1 and pos2. + * Returns false if something is blocking the sight. + * Returns the position of the blocking node when `false` + * `pos1`: First position + * `pos2`: Second position +* `minetest.raycast(pos1, pos2, objects, liquids)`: returns `Raycast` + * Creates a `Raycast` object. + * `pos1`: start of the ray + * `pos2`: end of the ray + * `objects`: if false, only nodes will be returned. Default is `true`. + * `liquids`: if false, liquid nodes won't be returned. Default is `false`. + +* `minetest.find_nodes_with_meta(pos1, pos2)` + * Get a table of positions of nodes that have metadata within a region + {pos1, pos2}. +* `minetest.get_meta(pos)` + * Get a `NodeMetaRef` at that position +* `minetest.get_node_level(pos)` + * get level of leveled node (water, snow) +* `minetest.get_node_max_level(pos)` + * get max available level for leveled node + +### Player +* `minetest.send_chat_message(message)` + * Act as if `message` was typed by the player into the terminal. +* `minetest.run_server_chatcommand(cmd, param)` + * Alias for `minetest.send_chat_message("/" .. cmd .. " " .. param)` +* `minetest.clear_out_chat_queue()` + * Clears the out chat queue +* `minetest.localplayer` + * Reference to the LocalPlayer object. See [`LocalPlayer`](#localplayer) class reference for methods. + +### Privileges +* `minetest.get_privilege_list()` + * Returns a list of privileges the current player has in the format `{priv1=true,...}` +* `minetest.string_to_privs(str)`: returns `{priv1=true,...}` +* `minetest.privs_to_string(privs)`: returns `"priv1,priv2,..."` + * Convert between two privilege representations + +### Client Environment +* `minetest.get_player_names()` + * Returns list of player names on server (nil if CSM_RF_READ_PLAYERINFO is enabled by server) +* `minetest.disconnect()` + * Disconnect from the server and exit to main menu. + * Returns `false` if the client is already disconnecting otherwise returns `true`. +* `minetest.get_server_info()` + * Returns [server info](#server-info). +* `minetest.send_respawn()` + * Sends a respawn request to the server. + +### Storage API +* `minetest.get_mod_storage()`: + * returns reference to mod private `StorageRef` + * must be called during mod load time + +### Mod channels +![Mod channels communication scheme](docs/mod channels.png) + +* `minetest.mod_channel_join(channel_name)` + * Client joins channel `channel_name`, and creates it, if necessary. You + should listen from incoming messages with `minetest.register_on_modchannel_message` + call to receive incoming messages. Warning, this function is asynchronous. + +### Particles +* `minetest.add_particle(particle definition)` + +* `minetest.add_particlespawner(particlespawner definition)` + * Add a `ParticleSpawner`, an object that spawns an amount of particles over `time` seconds + * Returns an `id`, and -1 if adding didn't succeed + +* `minetest.delete_particlespawner(id)` + * Delete `ParticleSpawner` with `id` (return value from `minetest.add_particlespawner`) + +### Misc. +* `minetest.parse_json(string[, nullvalue])`: returns something + * Convert a string containing JSON data into the Lua equivalent + * `nullvalue`: returned in place of the JSON null; defaults to `nil` + * On success returns a table, a string, a number, a boolean or `nullvalue` + * On failure outputs an error message and returns `nil` + * Example: `parse_json("[10, {\"a\":false}]")`, returns `{10, {a = false}}` +* `minetest.write_json(data[, styled])`: returns a string or `nil` and an error message + * Convert a Lua table into a JSON string + * styled: Outputs in a human-readable format if this is set, defaults to false + * Unserializable things like functions and userdata are saved as null. + * **Warning**: JSON is more strict than the Lua table format. + 1. You can only use strings and positive integers of at least one as keys. + 2. You can not mix string and integer keys. + This is due to the fact that JSON has two distinct array and object values. + * Example: `write_json({10, {a = false}})`, returns `"[10, {\"a\": false}]"` +* `minetest.serialize(table)`: returns a string + * Convert a table containing tables, strings, numbers, booleans and `nil`s + into string form readable by `minetest.deserialize` + * Example: `serialize({foo='bar'})`, returns `'return { ["foo"] = "bar" }'` +* `minetest.deserialize(string)`: returns a table + * Convert a string returned by `minetest.deserialize` into a table + * `string` is loaded in an empty sandbox environment. + * Will load functions, but they cannot access the global environment. + * Example: `deserialize('return { ["foo"] = "bar" }')`, returns `{foo='bar'}` + * Example: `deserialize('print("foo")')`, returns `nil` (function call fails) + * `error:[string "print("foo")"]:1: attempt to call global 'print' (a nil value)` +* `minetest.compress(data, method, ...)`: returns `compressed_data` + * Compress a string of data. + * `method` is a string identifying the compression method to be used. + * Supported compression methods: + * Deflate (zlib): `"deflate"` + * `...` indicates method-specific arguments. Currently defined arguments are: + * Deflate: `level` - Compression level, `0`-`9` or `nil`. +* `minetest.decompress(compressed_data, method, ...)`: returns data + * Decompress a string of data (using ZLib). + * See documentation on `minetest.compress()` for supported compression methods. + * currently supported. + * `...` indicates method-specific arguments. Currently, no methods use this. +* `minetest.rgba(red, green, blue[, alpha])`: returns a string + * Each argument is a 8 Bit unsigned integer + * Returns the ColorString from rgb or rgba values + * Example: `minetest.rgba(10, 20, 30, 40)`, returns `"#0A141E28"` +* `minetest.encode_base64(string)`: returns string encoded in base64 + * Encodes a string in base64. +* `minetest.decode_base64(string)`: returns string or nil on failure + * Padding characters are only supported starting at version 5.4.0, where + 5.5.0 and newer perform proper checks. + * Decodes a string encoded in base64. +* `minetest.gettext(string)` : returns string + * look up the translation of a string in the gettext message catalog +* `fgettext_ne(string, ...)` + * call minetest.gettext(string), replace "$1"..."$9" with the given + extra arguments and return the result +* `fgettext(string, ...)` : returns string + * same as fgettext_ne(), but calls minetest.formspec_escape before returning result +* `minetest.pointed_thing_to_face_pos(placer, pointed_thing)`: returns a position + * returns the exact position on the surface of a pointed node +* `minetest.global_exists(name)` + * Checks if a global variable has been set, without triggering a warning. + +### UI +* `minetest.ui.minimap` + * Reference to the minimap object. See [`Minimap`](#minimap) class reference for methods. + * If client disabled minimap (using enable_minimap setting) this reference will be nil. +* `minetest.camera` + * Reference to the camera object. See [`Camera`](#camera) class reference for methods. +* `minetest.show_formspec(formname, formspec)` : returns true on success + * Shows a formspec to the player +* `minetest.display_chat_message(message)` returns true on success + * Shows a chat message to the current player. + +Setting-related +--------------- + +* `minetest.settings`: Settings object containing all of the settings from the + main config file (`minetest.conf`). Check lua_api.txt for class reference. +* `minetest.setting_get_pos(name)`: Loads a setting from the main settings and + parses it as a position (in the format `(1,2,3)`). Returns a position or nil. + +Class reference +--------------- + +### ModChannel + +An interface to use mod channels on client and server + +#### Methods +* `leave()`: leave the mod channel. + * Client leaves channel `channel_name`. + * No more incoming or outgoing messages can be sent to this channel from client mods. + * This invalidate all future object usage + * Ensure your set mod_channel to nil after that to free Lua resources +* `is_writeable()`: returns true if channel is writable and mod can send over it. +* `send_all(message)`: Send `message` though the mod channel. + * If mod channel is not writable or invalid, message will be dropped. + * Message size is limited to 65535 characters by protocol. + +### Minimap +An interface to manipulate minimap on client UI + +#### Methods +* `show()`: shows the minimap (if not disabled by server) +* `hide()`: hides the minimap +* `set_pos(pos)`: sets the minimap position on screen +* `get_pos()`: returns the minimap current position +* `set_angle(deg)`: sets the minimap angle in degrees +* `get_angle()`: returns the current minimap angle in degrees +* `set_mode(mode)`: sets the minimap mode (0 to 6) +* `get_mode()`: returns the current minimap mode +* `set_shape(shape)`: Sets the minimap shape. (0 = square, 1 = round) +* `get_shape()`: Gets the minimap shape. (0 = square, 1 = round) + +### Camera +An interface to get or set information about the camera and camera-node. +Please do not try to access the reference until the camera is initialized, otherwise the reference will be nil. + +#### Methods +* `set_camera_mode(mode)` + * Pass `0` for first-person, `1` for third person, and `2` for third person front +* `get_camera_mode()` + * Returns 0, 1, or 2 as described above +* `get_fov()` + * Returns a table with X, Y, maximum and actual FOV in degrees: + +```lua + { + x = number, + y = number, + max = number, + actual = number + } +``` + +* `get_pos()` + * Returns position of camera with view bobbing +* `get_offset()` + * Returns eye offset vector +* `get_look_dir()` + * Returns eye direction unit vector +* `get_look_vertical()` + * Returns pitch in radians +* `get_look_horizontal()` + * Returns yaw in radians +* `get_aspect_ratio()` + * Returns aspect ratio of screen + +### LocalPlayer +An interface to retrieve information about the player. +This object will only be available after the client is initialized. Earlier accesses will yield a `nil` value. + +Methods: + +* `get_pos()` + * returns current player current position +* `get_velocity()` + * returns player speed vector +* `get_hp()` + * returns player HP +* `get_name()` + * returns player name +* `get_wield_index()` + * returns the index of the wielded item +* `get_wielded_item()` + * returns the itemstack the player is holding +* `is_attached()` + * returns true if player is attached +* `is_touching_ground()` + * returns true if player touching ground +* `is_in_liquid()` + * returns true if player is in a liquid (This oscillates so that the player jumps a bit above the surface) +* `is_in_liquid_stable()` + * returns true if player is in a stable liquid (This is more stable and defines the maximum speed of the player) +* `get_move_resistance()` + * returns move resistance of current node, the higher the slower the player moves +* `is_climbing()` + * returns true if player is climbing +* `swimming_vertical()` + * returns true if player is swimming in vertical +* `get_physics_override()` + * returns: + +```lua + { + speed = float, + jump = float, + gravity = float, + sneak = boolean, + sneak_glitch = boolean, + new_move = boolean, + } +``` + +* `get_override_pos()` + * returns override position +* `get_last_pos()` + * returns last player position before the current client step +* `get_last_velocity()` + * returns last player speed +* `get_breath()` + * returns the player's breath +* `get_movement_acceleration()` + * returns acceleration of the player in different environments: + +```lua + { + fast = float, + air = float, + default = float, + } +``` + +* `get_movement_speed()` + * returns player's speed in different environments: + +```lua + { + walk = float, + jump = float, + crouch = float, + fast = float, + climb = float, + } +``` + +* `get_movement()` + * returns player's movement in different environments: + +```lua + { + liquid_fluidity = float, + liquid_sink = float, + liquid_fluidity_smooth = float, + gravity = float, + } +``` + +* `get_last_look_horizontal()`: + * returns last look horizontal angle +* `get_last_look_vertical()`: + * returns last look vertical angle +* `get_control()`: + * returns pressed player controls + +```lua + { + up = boolean, + down = boolean, + left = boolean, + right = boolean, + jump = boolean, + aux1 = boolean, + sneak = boolean, + zoom = boolean, + dig = boolean, + place = boolean, + } +``` + +* `get_armor_groups()` + * returns a table with the armor group ratings +* `hud_add(definition)` + * add a HUD element described by HUD def, returns ID number on success and `nil` on failure. + * See [`HUD definition`](#hud-definition-hud_add-hud_get) +* `hud_get(id)` + * returns the [`definition`](#hud-definition-hud_add-hud_get) of the HUD with that ID number or `nil`, if non-existent. +* `hud_remove(id)` + * remove the HUD element of the specified id, returns `true` on success +* `hud_change(id, stat, value)` + * change a value of a previously added HUD element + * element `stat` values: `position`, `name`, `scale`, `text`, `number`, `item`, `dir` + * Returns `true` on success, otherwise returns `nil` + +### Settings +An interface to read config files in the format of `minetest.conf`. + +It can be created via `Settings(filename)`. + +#### Methods +* `get(key)`: returns a value +* `get_bool(key)`: returns a boolean +* `set(key, value)` +* `remove(key)`: returns a boolean (`true` for success) +* `get_names()`: returns `{key1,...}` +* `write()`: returns a boolean (`true` for success) + * write changes to file +* `to_table()`: returns `{[key1]=value1,...}` + +### NodeMetaRef +Node metadata: reference extra data and functionality stored in a node. +Can be obtained via `minetest.get_meta(pos)`. + +#### Methods +* `get_string(name)` +* `get_int(name)` +* `get_float(name)` +* `to_table()`: returns `nil` or a table with keys: + * `fields`: key-value storage + * `inventory`: `{list1 = {}, ...}}` + +### `Raycast` + +A raycast on the map. It works with selection boxes. +Can be used as an iterator in a for loop as: + + local ray = Raycast(...) + for pointed_thing in ray do + ... + end + +The map is loaded as the ray advances. If the map is modified after the +`Raycast` is created, the changes may or may not have an effect on the object. + +It can be created via `Raycast(pos1, pos2, objects, liquids)` or +`minetest.raycast(pos1, pos2, objects, liquids)` where: + +* `pos1`: start of the ray +* `pos2`: end of the ray +* `objects`: if false, only nodes will be returned. Default is true. +* `liquids`: if false, liquid nodes won't be returned. Default is false. + +#### Methods + +* `next()`: returns a `pointed_thing` with exact pointing location + * Returns the next thing pointed by the ray or nil. + +----------------- +### Definitions +* `minetest.get_node_def(nodename)` + * Returns [node definition](#node-definition) table of `nodename` +* `minetest.get_item_def(itemstring)` + * Returns item definition table of `itemstring` + +#### Node Definition + +```lua + { + has_on_construct = bool, -- Whether the node has the on_construct callback defined + has_on_destruct = bool, -- Whether the node has the on_destruct callback defined + has_after_destruct = bool, -- Whether the node has the after_destruct callback defined + name = string, -- The name of the node e.g. "air", "default:dirt" + groups = table, -- The groups of the node + paramtype = string, -- Paramtype of the node + paramtype2 = string, -- ParamType2 of the node + drawtype = string, -- Drawtype of the node + mesh = <string>, -- Mesh name if existant + minimap_color = <Color>, -- Color of node on minimap *May not exist* + visual_scale = number, -- Visual scale of node + alpha = number, -- Alpha of the node. Only used for liquids + color = <Color>, -- Color of node *May not exist* + palette_name = <string>, -- Filename of palette *May not exist* + palette = <{ -- List of colors + Color, + Color + }>, + waving = number, -- 0 of not waving, 1 if waving + connect_sides = number, -- Used for connected nodes + connects_to = { -- List of nodes to connect to + "node1", + "node2" + }, + post_effect_color = Color, -- Color overlayed on the screen when the player is in the node + leveled = number, -- Max level for node + sunlight_propogates = bool, -- Whether light passes through the block + light_source = number, -- Light emitted by the block + is_ground_content = bool, -- Whether caves should cut through the node + walkable = bool, -- Whether the player collides with the node + pointable = bool, -- Whether the player can select the node + diggable = bool, -- Whether the player can dig the node + climbable = bool, -- Whether the player can climb up the node + buildable_to = bool, -- Whether the player can replace the node by placing a node on it + rightclickable = bool, -- Whether the player can place nodes pointing at this node + damage_per_second = number, -- HP of damage per second when the player is in the node + liquid_type = <string>, -- A string containing "none", "flowing", or "source" *May not exist* + liquid_alternative_flowing = <string>, -- Alternative node for liquid *May not exist* + liquid_alternative_source = <string>, -- Alternative node for liquid *May not exist* + liquid_viscosity = <number>, -- How slow the liquid flows *May not exist* + liquid_renewable = <boolean>, -- Whether the liquid makes an infinite source *May not exist* + liquid_range = <number>, -- How far the liquid flows *May not exist* + drowning = bool, -- Whether the player will drown in the node + floodable = bool, -- Whether nodes will be replaced by liquids (flooded) + node_box = table, -- Nodebox to draw the node with + collision_box = table, -- Nodebox to set the collision area + selection_box = table, -- Nodebox to set the area selected by the player + sounds = { -- Table of sounds that the block makes + sound_footstep = SimpleSoundSpec, + sound_dig = SimpleSoundSpec, + sound_dug = SimpleSoundSpec + }, + legacy_facedir_simple = bool, -- Whether to use old facedir + legacy_wallmounted = bool -- Whether to use old wallmounted + move_resistance = <number>, -- How slow players can move through the node *May not exist* + } +``` + +#### Item Definition + +```lua + { + name = string, -- Name of the item e.g. "default:stone" + description = string, -- Description of the item e.g. "Stone" + type = string, -- Item type: "none", "node", "craftitem", "tool" + inventory_image = string, -- Image in the inventory + wield_image = string, -- Image in wieldmesh + palette_image = string, -- Image for palette + color = Color, -- Color for item + wield_scale = Vector, -- Wieldmesh scale + stack_max = number, -- Number of items stackable together + usable = bool, -- Has on_use callback defined + liquids_pointable = bool, -- Whether you can point at liquids with the item + tool_capabilities = <table>, -- If the item is a tool, tool capabilities of the item + groups = table, -- Groups of the item + sound_place = SimpleSoundSpec, -- Sound played when placed + sound_place_failed = SimpleSoundSpec, -- Sound played when placement failed + node_placement_prediction = string -- Node placed in client until server catches up + } +``` +----------------- + +### Chat command definition (`register_chatcommand`) + + { + params = "<name> <privilege>", -- Short parameter description + description = "Remove privilege from player", -- Full description + func = function(param), -- Called when command is run. + -- Returns boolean success and text output. + } +### Server info +```lua +{ + address = "minetest.example.org", -- The domain name/IP address of a remote server or "" for a local server. + ip = "203.0.113.156", -- The IP address of the server. + port = 30000, -- The port the client is connected to. + protocol_version = 30 -- Will not be accurate at start up as the client might not be connected to the server yet, in that case it will be 0. +} +``` + +### HUD Definition (`hud_add`, `hud_get`) +```lua + { + hud_elem_type = "image", -- see HUD element types, default "text" + -- ^ type of HUD element, can be either of "image", "text", "statbar", or "inventory" + position = {x=0.5, y=0.5}, + -- ^ Left corner position of element, default `{x=0,y=0}`. + name = "<name>", -- default "" + scale = {x=2, y=2}, -- default {x=0,y=0} + text = "<text>", -- default "" + number = 2, -- default 0 + item = 3, -- default 0 + -- ^ Selected item in inventory. 0 for no item selected. + direction = 0, -- default 0 + -- ^ Direction: 0: left-right, 1: right-left, 2: top-bottom, 3: bottom-top + alignment = {x=0, y=0}, -- default {x=0, y=0} + -- ^ See "HUD Element Types" + offset = {x=0, y=0}, -- default {x=0, y=0} + -- ^ See "HUD Element Types" + size = { x=100, y=100 }, -- default {x=0, y=0} + -- ^ Size of element in pixels + style = 0, + -- ^ For "text" elements sets font style: bitfield with 1 = bold, 2 = italic, 4 = monospace + } +``` + +Escape sequences +---------------- +Most text can contain escape sequences, that can for example color the text. +There are a few exceptions: tab headers, dropdowns and vertical labels can't. +The following functions provide escape sequences: +* `minetest.get_color_escape_sequence(color)`: + * `color` is a [ColorString](#colorstring) + * The escape sequence sets the text color to `color` +* `minetest.colorize(color, message)`: + * Equivalent to: + `minetest.get_color_escape_sequence(color) .. + message .. + minetest.get_color_escape_sequence("#ffffff")` +* `minetest.get_background_escape_sequence(color)` + * `color` is a [ColorString](#colorstring) + * The escape sequence sets the background of the whole text element to + `color`. Only defined for item descriptions and tooltips. +* `minetest.strip_foreground_colors(str)` + * Removes foreground colors added by `get_color_escape_sequence`. +* `minetest.strip_background_colors(str)` + * Removes background colors added by `get_background_escape_sequence`. +* `minetest.strip_colors(str)` + * Removes all color escape sequences. + +`ColorString` +------------- +`#RGB` defines a color in hexadecimal format. + +`#RGBA` defines a color in hexadecimal format and alpha channel. + +`#RRGGBB` defines a color in hexadecimal format. + +`#RRGGBBAA` defines a color in hexadecimal format and alpha channel. + +Named colors are also supported and are equivalent to +[CSS Color Module Level 4](http://dev.w3.org/csswg/css-color/#named-colors). +To specify the value of the alpha channel, append `#A` or `#AA` to the end of +the color name (e.g. `colorname#08`). + +`Color` +------------- +`{a = alpha, r = red, g = green, b = blue}` defines an ARGB8 color. + +HUD element types +----------------- +The position field is used for all element types. + +To account for differing resolutions, the position coordinates are the percentage +of the screen, ranging in value from `0` to `1`. + +The name field is not yet used, but should contain a description of what the +HUD element represents. The direction field is the direction in which something +is drawn. + +`0` draws from left to right, `1` draws from right to left, `2` draws from +top to bottom, and `3` draws from bottom to top. + +The `alignment` field specifies how the item will be aligned. It ranges from `-1` to `1`, +with `0` being the center, `-1` is moved to the left/up, and `1` is to the right/down. +Fractional values can be used. + +The `offset` field specifies a pixel offset from the position. Contrary to position, +the offset is not scaled to screen size. This allows for some precisely-positioned +items in the HUD. + +**Note**: `offset` _will_ adapt to screen DPI as well as user defined scaling factor! + +Below are the specific uses for fields in each type; fields not listed for that type are ignored. + +**Note**: Future revisions to the HUD API may be incompatible; the HUD API is still +in the experimental stages. + +### `image` +Displays an image on the HUD. + +* `scale`: The scale of the image, with 1 being the original texture size. + Only the X coordinate scale is used (positive values). + Negative values represent that percentage of the screen it + should take; e.g. `x=-100` means 100% (width). +* `text`: The name of the texture that is displayed. +* `alignment`: The alignment of the image. +* `offset`: offset in pixels from position. + +### `text` +Displays text on the HUD. + +* `scale`: Defines the bounding rectangle of the text. + A value such as `{x=100, y=100}` should work. +* `text`: The text to be displayed in the HUD element. +* `number`: An integer containing the RGB value of the color used to draw the text. + Specify `0xFFFFFF` for white text, `0xFF0000` for red, and so on. +* `alignment`: The alignment of the text. +* `offset`: offset in pixels from position. + +### `statbar` +Displays a horizontal bar made up of half-images. + +* `text`: The name of the texture that is used. +* `number`: The number of half-textures that are displayed. + If odd, will end with a vertically center-split texture. +* `direction` +* `offset`: offset in pixels from position. +* `size`: If used, will force full-image size to this value (override texture pack image size) + +### `inventory` +* `text`: The name of the inventory list to be displayed. +* `number`: Number of items in the inventory to be displayed. +* `item`: Position of item that is selected. +* `direction` +* `offset`: offset in pixels from position. + +### `waypoint` + +Displays distance to selected world position. + +* `name`: The name of the waypoint. +* `text`: Distance suffix. Can be blank. +* `precision`: Waypoint precision, integer >= 0. Defaults to 10. + If set to 0, distance is not shown. Shown value is `floor(distance*precision)/precision`. + When the precision is an integer multiple of 10, there will be `log_10(precision)` digits after the decimal point. + `precision = 1000`, for example, will show 3 decimal places (eg: `0.999`). + `precision = 2` will show multiples of `0.5`; precision = 5 will show multiples of `0.2` and so on: + `precision = n` will show multiples of `1/n` +* `number:` An integer containing the RGB value of the color used to draw the + text. +* `world_pos`: World position of the waypoint. +* `offset`: offset in pixels from position. +* `alignment`: The alignment of the waypoint. + +### `image_waypoint` + +Same as `image`, but does not accept a `position`; the position is instead determined by `world_pos`, the world position of the waypoint. + +* `scale`: The scale of the image, with 1 being the original texture size. + Only the X coordinate scale is used (positive values). + Negative values represent that percentage of the screen it + should take; e.g. `x=-100` means 100% (width). +* `text`: The name of the texture that is displayed. +* `alignment`: The alignment of the image. +* `world_pos`: World position of the waypoint. +* `offset`: offset in pixels from position. + +### Particle definition (`add_particle`) + + { + pos = {x=0, y=0, z=0}, + velocity = {x=0, y=0, z=0}, + acceleration = {x=0, y=0, z=0}, + -- ^ Spawn particle at pos with velocity and acceleration + expirationtime = 1, + -- ^ Disappears after expirationtime seconds + size = 1, + collisiondetection = false, + -- ^ collisiondetection: if true collides with physical objects + collision_removal = false, + -- ^ collision_removal: if true then particle is removed when it collides, + -- ^ requires collisiondetection = true to have any effect + vertical = false, + -- ^ vertical: if true faces player using y axis only + texture = "image.png", + -- ^ Uses texture (string) + animation = {Tile Animation definition}, + -- ^ optional, specifies how to animate the particle texture + glow = 0 + -- ^ optional, specify particle self-luminescence in darkness + } + +### `ParticleSpawner` definition (`add_particlespawner`) + + { + amount = 1, + time = 1, + -- ^ If time is 0 has infinite lifespan and spawns the amount on a per-second base + minpos = {x=0, y=0, z=0}, + maxpos = {x=0, y=0, z=0}, + minvel = {x=0, y=0, z=0}, + maxvel = {x=0, y=0, z=0}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 1, + maxexptime = 1, + minsize = 1, + maxsize = 1, + -- ^ The particle's properties are random values in between the bounds: + -- ^ minpos/maxpos, minvel/maxvel (velocity), minacc/maxacc (acceleration), + -- ^ minsize/maxsize, minexptime/maxexptime (expirationtime) + collisiondetection = false, + -- ^ collisiondetection: if true uses collision detection + collision_removal = false, + -- ^ collision_removal: if true then particle is removed when it collides, + -- ^ requires collisiondetection = true to have any effect + vertical = false, + -- ^ vertical: if true faces player using y axis only + texture = "image.png", + -- ^ Uses texture (string) + } diff --git a/doc/direction.md b/doc/direction.md new file mode 100644 index 0000000..826dd47 --- /dev/null +++ b/doc/direction.md @@ -0,0 +1,69 @@ +# Minetest Direction Document + +## 1. Long-term Roadmap + +The long-term roadmaps, aims, and guiding philosophies are set out using the +following documents: + +* [What is Minetest?](http://c55.me/blog/?p=1491) +* [celeron55's roadmap](https://forum.minetest.net/viewtopic.php?t=9177) +* [celeron55's comment in "A clear mission statement for Minetest is missing"](https://github.com/minetest/minetest/issues/3476#issuecomment-167399287) +* [Core developer to-do/wish lists](https://forum.minetest.net/viewforum.php?f=7) + +## 2. Medium-term Roadmap + +These are the current medium-term goals for Minetest development, in no +particular order. + +These goals were created from the top points in a +[roadmap brainstorm](https://github.com/minetest/minetest/issues/10461). +This should be reviewed approximately yearly, or when goals are achieved. + +Pull requests that address one of these goals will be labelled as "Roadmap". +PRs that are not on the roadmap will be closed unless they receive a concept +approval within a week, issues can be used for preapproval. +Bug fixes are exempt for this, and are always accepted and prioritised. +See [CONTRIBUTING.md](../.github/CONTRIBUTING.md) for more info. + +### 2.1 Rendering/Graphics improvements + +The priority is fixing the issues, performance, and general correctness. +Once that is done, fancier features can be worked on, such as water shaders, +shadows, and improved lighting. + +Examples include +[transparency sorting](https://github.com/minetest/minetest/issues/95), +[particle performance](https://github.com/minetest/minetest/issues/1414), +[general view distance](https://github.com/minetest/minetest/issues/7222). + +This includes work on maintaining +[our Irrlicht fork](https://github.com/minetest/irrlicht), and switching to +alternative libraries to replace Irrlicht functionality as needed + +### 2.2 Internal code refactoring + +To ensure sustainable development, Minetest's code needs to be +[refactored and improved](https://github.com/minetest/minetest/pulls?q=is%3Aopen+sort%3Aupdated-desc+label%3A%22Code+quality%22+). +This will remove code rot and allow for more efficient development. + +### 2.3 UI Improvements + +A [formspec replacement](https://github.com/minetest/minetest/issues/6527) is +needed to make GUIs better and easier to create. This replacement could also +be a replacement for HUDs, allowing for a unified API. + +A [new mainmenu](https://github.com/minetest/minetest/issues/6733) is needed to +improve user experience. First impressions matter, and the current main menu +doesn't do a very good job at selling Minetest or explaining what it is. +A new main menu should promote games to users, allowing Minetest Game to no +longer be bundled by default. + +The UI code is undergoing rapid changes, so it is especially important to make +an issue for any large changes before spending lots of time. + +### 2.4 Object and entity improvements + +There are still a significant number of issues with objects. +Collisions, +[performance](https://github.com/minetest/minetest/issues/6453), +API convenience, and discrepancies between players and entities. diff --git a/doc/fst_api.txt b/doc/fst_api.txt new file mode 100644 index 0000000..6f9aa14 --- /dev/null +++ b/doc/fst_api.txt @@ -0,0 +1,174 @@ +Formspec toolkit api 0.0.3 +========================== + +Formspec toolkit is a set of functions to create basic ui elements. + + +File: fst/ui.lua +---------------- + +ui.lua adds base ui interface to add additional components to. + +ui.add(component) -> returns name of added component +^ add component to ui +^ component: component to add + +ui.delete(component) -> true/false if a component was deleted or not +^ remove a component from ui +^ component: component to delete + +ui.set_default(name) +^ set component to show if not a single component is set visible +^ name: name of component to set as default + +ui.find_by_name(name) --> returns component or nil +^ find a component within ui +^ name: name of component to look for + +File: fst/tabview.lua +--------------------- + +tabview_create(name, size, tabheaderpos) --> returns tabview component +^ create a new tabview component +^ name: name of tabview (has to be unique per ui) +^ size: size of tabview + { + x, + y + } +^ tabheaderpos: upper left position of tabheader (relative to upper left fs corner) + { + x, + y + } + +Class reference tabview: + +methods: +- add_tab(tab) + ^ add a tab to this tabview + ^ tab: + { + name = "tabname", -- name of tab to create + caption = "tab caption", -- text to show for tab header + cbf_button_handler = function(tabview, fields, tabname, tabdata), -- callback for button events + --TODO cbf_events = function(tabview, event, tabname), -- callback for events + cbf_formspec = function(tabview, name, tabdata), -- get formspec + tabsize = + { + x, -- x width + y -- y height + }, -- special size for this tab (only relevant if no parent for tabview set) + on_change = function(type,old_tab,new_tab) -- called on tab chang, type is "ENTER" or "LEAVE" + } +- set_autosave_tab(value) + ^ tell tabview to automatically save current tabname as "tabview_name"_LAST + ^ value: true/false +- set_tab(name) + ^ set's tab to tab named "name", returns true/false on success + ^ name: name of tab to set +- set_global_event_handler(handler) + ^ set a handler to be called prior calling tab specific event handler + ^ handler: function(tabview,event) --> returns true to finish event processing false to continue +- set_global_button_handler(handler) + ^ set a handler to be called prior calling tab specific button handler + ^ handler: function(tabview,fields) --> returns true to finish button processing false to continue +- set_parent(parent) + ^ set parent to attach tabview to. TV's with parent are hidden if their parent + is hidden and they don't set their specified size. + ^ parent: component to attach to +- show() + ^ show tabview +- hide() + ^ hide tabview +- delete() + ^ delete tabview +- set_fixed_size(state) + ^ true/false set to fixed size, variable size + +File: fst/dialog.lua +--------------------- +Only one dialog can be shown at a time. If a dialog is closed it's parent is +gonna be activated and shown again. + +dialog_create(name, cbf_formspec, cbf_button_handler, cbf_events) +^ create a dialog component +^ name: name of component (unique per ui) +^ cbf_formspec: function to be called to get formspec + function(dialogdata) +^ cbf_button_handler: function to handle buttons + function(dialog, fields) +^ cbf_events: function to handle events + function(dialog, event) + +messagebox(name, message) +^ creates a message dialog + +Class reference dialog: + +methods: +- set_parent(parent) + ^ set parent to attach a dialog to + ^ parent: component to attach to +- show() + ^ show dialog +- hide() + ^ hide dialog +- delete() + ^ delete dialog from ui + +members: +- data + ^ variable data attached to this dialog +- parent + ^ parent component to return to on exit + +File: fst/buttonbar.lua +----------------------- + +buttonbar_create(name, cbf_buttonhandler, pos, orientation, size) +^ create a buttonbar +^ name: name of component (unique per ui) +^ cbf_buttonhandler: function to be called on button pressed + function(buttonbar,buttonname,buttondata) +^ pos: position relative to upper left of current shown formspec + { + x, + y + } +^ orientation: "vertical" or "horizontal" +^ size: size of bar + { + width, + height + } + +Class reference buttonbar: + +methods: +- add_button(btn_id, caption, button_image) +- set_parent(parent) + ^ set parent to attach a buttonbar to + ^ parent: component to attach to +- show() + ^ show buttonbar +- hide() + ^ hide buttonbar +- delete() + ^ delete buttonbar from ui + +Developer doc: +============== +Skeleton for any component: +{ + name = "some id", -- unique id + type = "toplevel", -- type of component + -- toplevel: component can be show without additional components + -- addon: component is an addon to be shown along toplevel component + hide = function(this) end, -- called to hide the component + show = function(this) end, -- called to show the component + delete = function(this) end, -- called to delete component from ui + handle_buttons = function(this,fields) -- called upon button press + handle_events = function(this,event) -- called upon event reception + get_formspec = function(this) -- has to return formspec to be displayed +} diff --git a/doc/lgpl-2.1.txt b/doc/lgpl-2.1.txt new file mode 100644 index 0000000..e5ab03e --- /dev/null +++ b/doc/lgpl-2.1.txt @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library 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.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that 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 library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/doc/lua_api.txt b/doc/lua_api.txt new file mode 100644 index 0000000..9e1633a --- /dev/null +++ b/doc/lua_api.txt @@ -0,0 +1,9521 @@ +Minetest Lua Modding API Reference +================================== + +* More information at <http://www.minetest.net/> +* Developer Wiki: <http://dev.minetest.net/> +* (Unofficial) Minetest Modding Book by rubenwardy: <https://rubenwardy.com/minetest_modding_book/> + +Introduction +------------ + +Content and functionality can be added to Minetest using Lua scripting +in run-time loaded mods. + +A mod is a self-contained bunch of scripts, textures and other related +things, which is loaded by and interfaces with Minetest. + +Mods are contained and ran solely on the server side. Definitions and media +files are automatically transferred to the client. + +If you see a deficiency in the API, feel free to attempt to add the +functionality in the engine and API, and to document it here. + +Programming in Lua +------------------ + +If you have any difficulty in understanding this, please read +[Programming in Lua](http://www.lua.org/pil/). + +Startup +------- + +Mods are loaded during server startup from the mod load paths by running +the `init.lua` scripts in a shared environment. + +Paths +----- + +Minetest keeps and looks for files mostly in two paths. `path_share` or `path_user`. + +`path_share` contains possibly read-only content for the engine (incl. games and mods). +`path_user` contains mods or games installed by the user but also the users +worlds or settings. + +With a local build (`RUN_IN_PLACE=1`) `path_share` and `path_user` both point to +the build directory. For system-wide builds on Linux the share path is usually at +`/usr/share/minetest` while the user path resides in `.minetest` in the home directory. +Paths on other operating systems will differ. + +Games +===== + +Games are looked up from: + +* `$path_share/games/<gameid>/` +* `$path_user/games/<gameid>/` + +Where `<gameid>` is unique to each game. + +The game directory can contain the following files: + +* `game.conf`, with the following keys: + * `title`: Required, a human-readable title to address the game, e.g. `title = Minetest Game`. + * `name`: (Deprecated) same as title. + * `description`: Short description to be shown in the content tab + * `allowed_mapgens = <comma-separated mapgens>` + e.g. `allowed_mapgens = v5,v6,flat` + Mapgens not in this list are removed from the list of mapgens for the + game. + If not specified, all mapgens are allowed. + * `disallowed_mapgens = <comma-separated mapgens>` + e.g. `disallowed_mapgens = v5,v6,flat` + These mapgens are removed from the list of mapgens for the game. + When both `allowed_mapgens` and `disallowed_mapgens` are + specified, `allowed_mapgens` is applied before + `disallowed_mapgens`. + * `disallowed_mapgen_settings= <comma-separated mapgen settings>` + e.g. `disallowed_mapgen_settings = mgv5_spflags` + These mapgen settings are hidden for this game in the world creation + dialog and game start menu. Add `seed` to hide the seed input field. + * `disabled_settings = <comma-separated settings>` + e.g. `disabled_settings = enable_damage, creative_mode` + These settings are hidden for this game in the "Start game" tab + and will be initialized as `false` when the game is started. + Prepend a setting name with an exclamation mark to initialize it to `true` + (this does not work for `enable_server`). + Only these settings are supported: + `enable_damage`, `creative_mode`, `enable_server`. + * `author`: The author of the game. It only appears when downloaded from + ContentDB. + * `release`: Ignore this: Should only ever be set by ContentDB, as it is + an internal ID used to track versions. +* `minetest.conf`: + Used to set default settings when running this game. +* `settingtypes.txt`: + In the same format as the one in builtin. + This settingtypes.txt will be parsed by the menu and the settings will be + displayed in the "Games" category in the advanced settings tab. +* If the game contains a folder called `textures` the server will load it as a + texturepack, overriding mod textures. + Any server texturepack will override mod textures and the game texturepack. + +Menu images +----------- + +Games can provide custom main menu images. They are put inside a `menu` +directory inside the game directory. + +The images are named `$identifier.png`, where `$identifier` is one of +`overlay`, `background`, `footer`, `header`. +If you want to specify multiple images for one identifier, add additional +images named like `$identifier.$n.png`, with an ascending number $n starting +with 1, and a random image will be chosen from the provided ones. + +Menu music +----------- + +Games can provide custom main menu music. They are put inside a `menu` +directory inside the game directory. + +The music files are named `theme.ogg`. +If you want to specify multiple music files for one game, add additional +images named like `theme.$n.ogg`, with an ascending number $n starting +with 1 (max 10), and a random music file will be chosen from the provided ones. + +Mods +==== + +Mod load path +------------- + +Paths are relative to the directories listed in the [Paths] section above. + +* `games/<gameid>/mods/` +* `mods/` +* `worlds/<worldname>/worldmods/` + +World-specific games +-------------------- + +It is possible to include a game in a world; in this case, no mods or +games are loaded or checked from anywhere else. + +This is useful for e.g. adventure worlds and happens if the `<worldname>/game/` +directory exists. + +Mods should then be placed in `<worldname>/game/mods/`. + +Modpacks +-------- + +Mods can be put in a subdirectory, if the parent directory, which otherwise +should be a mod, contains a file named `modpack.conf`. +The file is a key-value store of modpack details. + +* `name`: The modpack name. Allows Minetest to determine the modpack name even + if the folder is wrongly named. +* `description`: Description of mod to be shown in the Mods tab of the main + menu. +* `author`: The author of the modpack. It only appears when downloaded from + ContentDB. +* `release`: Ignore this: Should only ever be set by ContentDB, as it is an + internal ID used to track versions. +* `title`: A human-readable title to address the modpack. + +Note: to support 0.4.x, please also create an empty modpack.txt file. + +Mod directory structure +----------------------- + + mods + ├── modname + │   ├── mod.conf + │   ├── screenshot.png + │   ├── settingtypes.txt + │   ├── init.lua + │   ├── models + │   ├── textures + │   │   ├── modname_stuff.png + │   │   ├── modname_stuff_normal.png + │   │   ├── modname_something_else.png + │   │   ├── subfolder_foo + │   │   │ ├── modname_more_stuff.png + │   │   │ └── another_subfolder + │   │   └── bar_subfolder + │   ├── sounds + │   ├── media + │   ├── locale + │   └── <custom data> + └── another + +### modname + +The location of this directory can be fetched by using +`minetest.get_modpath(modname)`. + +### mod.conf + +A `Settings` file that provides meta information about the mod. + +* `name`: The mod name. Allows Minetest to determine the mod name even if the + folder is wrongly named. +* `description`: Description of mod to be shown in the Mods tab of the main + menu. +* `depends`: A comma separated list of dependencies. These are mods that must be + loaded before this mod. +* `optional_depends`: A comma separated list of optional dependencies. + Like a dependency, but no error if the mod doesn't exist. +* `author`: The author of the mod. It only appears when downloaded from + ContentDB. +* `release`: Ignore this: Should only ever be set by ContentDB, as it is an + internal ID used to track versions. +* `title`: A human-readable title to address the mod. + +### `screenshot.png` + +A screenshot shown in the mod manager within the main menu. It should +have an aspect ratio of 3:2 and a minimum size of 300×200 pixels. + +### `depends.txt` + +**Deprecated:** you should use mod.conf instead. + +This file is used if there are no dependencies in mod.conf. + +List of mods that have to be loaded before loading this mod. + +A single line contains a single modname. + +Optional dependencies can be defined by appending a question mark +to a single modname. This means that if the specified mod +is missing, it does not prevent this mod from being loaded. + +### `description.txt` + +**Deprecated:** you should use mod.conf instead. + +This file is used if there is no description in mod.conf. + +A file containing a description to be shown in the Mods tab of the main menu. + +### `settingtypes.txt` + +The format is documented in `builtin/settingtypes.txt`. +It is parsed by the main menu settings dialogue to list mod-specific +settings in the "Mods" category. + +### `init.lua` + +The main Lua script. Running this script should register everything it +wants to register. Subsequent execution depends on minetest calling the +registered callbacks. + +`minetest.settings` can be used to read custom or existing settings at load +time, if necessary. (See [`Settings`]) + +### `textures`, `sounds`, `media`, `models`, `locale` + +Media files (textures, sounds, whatever) that will be transferred to the +client and will be available for use by the mod and translation files for +the clients (see [Translations]). + +It is suggested to use the folders for the purpose they are thought for, +eg. put textures into `textures`, translation files into `locale`, +models for entities or meshnodes into `models` et cetera. + +These folders and subfolders can contain subfolders. +Subfolders with names starting with `_` or `.` are ignored. +If a subfolder contains a media file with the same name as a media file +in one of its parents, the parent's file is used. + +Although it is discouraged, a mod can overwrite a media file of any mod that it +depends on by supplying a file with an equal name. + +Naming conventions +------------------ + +Registered names should generally be in this format: + + modname:<whatever> + +`<whatever>` can have these characters: + + a-zA-Z0-9_ + +This is to prevent conflicting names from corrupting maps and is +enforced by the mod loader. + +Registered names can be overridden by prefixing the name with `:`. This can +be used for overriding the registrations of some other mod. + +The `:` prefix can also be used for maintaining backwards compatibility. + +### Example + +In the mod `experimental`, there is the ideal item/node/entity name `tnt`. +So the name should be `experimental:tnt`. + +Any mod can redefine `experimental:tnt` by using the name + + :experimental:tnt + +when registering it. For this to work correctly, that mod must have +`experimental` as a dependency. + + + + +Aliases +======= + +Aliases of itemnames can be added by using +`minetest.register_alias(alias, original_name)` or +`minetest.register_alias_force(alias, original_name)`. + +This adds an alias `alias` for the item called `original_name`. +From now on, you can use `alias` to refer to the item `original_name`. + +The only difference between `minetest.register_alias` and +`minetest.register_alias_force` is that if an item named `alias` already exists, +`minetest.register_alias` will do nothing while +`minetest.register_alias_force` will unregister it. + +This can be used for maintaining backwards compatibility. + +This can also set quick access names for things, e.g. if +you have an item called `epiclylongmodname:stuff`, you could do + + minetest.register_alias("stuff", "epiclylongmodname:stuff") + +and be able to use `/giveme stuff`. + +Mapgen aliases +-------------- + +In a game, a certain number of these must be set to tell core mapgens which +of the game's nodes are to be used for core mapgen generation. For example: + + minetest.register_alias("mapgen_stone", "default:stone") + +### Aliases for non-V6 mapgens + +#### Essential aliases + +* `mapgen_stone` +* `mapgen_water_source` +* `mapgen_river_water_source` + +`mapgen_river_water_source` is required for mapgens with sloping rivers where +it is necessary to have a river liquid node with a short `liquid_range` and +`liquid_renewable = false` to avoid flooding. + +#### Optional aliases + +* `mapgen_lava_source` + +Fallback lava node used if cave liquids are not defined in biome definitions. +Deprecated, define cave liquids in biome definitions instead. + +* `mapgen_cobble` + +Fallback node used if dungeon nodes are not defined in biome definitions. +Deprecated, define dungeon nodes in biome definitions instead. + +### Aliases for Mapgen V6 + +#### Essential + +* `mapgen_stone` +* `mapgen_water_source` +* `mapgen_lava_source` +* `mapgen_dirt` +* `mapgen_dirt_with_grass` +* `mapgen_sand` + +* `mapgen_tree` +* `mapgen_leaves` +* `mapgen_apple` + +* `mapgen_cobble` + +#### Optional + +* `mapgen_gravel` (falls back to stone) +* `mapgen_desert_stone` (falls back to stone) +* `mapgen_desert_sand` (falls back to sand) +* `mapgen_dirt_with_snow` (falls back to dirt_with_grass) +* `mapgen_snowblock` (falls back to dirt_with_grass) +* `mapgen_snow` (not placed if missing) +* `mapgen_ice` (falls back to water_source) + +* `mapgen_jungletree` (falls back to tree) +* `mapgen_jungleleaves` (falls back to leaves) +* `mapgen_junglegrass` (not placed if missing) +* `mapgen_pine_tree` (falls back to tree) +* `mapgen_pine_needles` (falls back to leaves) + +* `mapgen_stair_cobble` (falls back to cobble) +* `mapgen_mossycobble` (falls back to cobble) +* `mapgen_stair_desert_stone` (falls backto desert_stone) + +### Setting the node used in Mapgen Singlenode + +By default the world is filled with air nodes. To set a different node use e.g.: + + minetest.register_alias("mapgen_singlenode", "default:stone") + + + + +Textures +======== + +Mods should generally prefix their textures with `modname_`, e.g. given +the mod name `foomod`, a texture could be called: + + foomod_foothing.png + +Textures are referred to by their complete name, or alternatively by +stripping out the file extension: + +* e.g. `foomod_foothing.png` +* e.g. `foomod_foothing` + +Supported texture formats are PNG (`.png`), JPEG (`.jpg`), Bitmap (`.bmp`) +and Targa (`.tga`). +Since better alternatives exist, the latter two may be removed in the future. + +Texture modifiers +----------------- + +There are various texture modifiers that can be used +to let the client generate textures on-the-fly. +The modifiers are applied directly in sRGB colorspace, +i.e. without gamma-correction. + +### Texture overlaying + +Textures can be overlaid by putting a `^` between them. + +Example: + + default_dirt.png^default_grass_side.png + +`default_grass_side.png` is overlaid over `default_dirt.png`. +The texture with the lower resolution will be automatically upscaled to +the higher resolution texture. + +### Texture grouping + +Textures can be grouped together by enclosing them in `(` and `)`. + +Example: `cobble.png^(thing1.png^thing2.png)` + +A texture for `thing1.png^thing2.png` is created and the resulting +texture is overlaid on top of `cobble.png`. + +### Escaping + +Modifiers that accept texture names (e.g. `[combine`) accept escaping to allow +passing complex texture names as arguments. Escaping is done with backslash and +is required for `^` and `:`. + +Example: `cobble.png^[lowpart:50:color.png\^[mask\:trans.png` + +The lower 50 percent of `color.png^[mask:trans.png` are overlaid +on top of `cobble.png`. + +### Advanced texture modifiers + +#### Crack + +* `[crack:<n>:<p>` +* `[cracko:<n>:<p>` +* `[crack:<t>:<n>:<p>` +* `[cracko:<t>:<n>:<p>` + +Parameters: + +* `<t>`: tile count (in each direction) +* `<n>`: animation frame count +* `<p>`: current animation frame + +Draw a step of the crack animation on the texture. +`crack` draws it normally, while `cracko` lays it over, keeping transparent +pixels intact. + +Example: + + default_cobble.png^[crack:10:1 + +#### `[combine:<w>x<h>:<x1>,<y1>=<file1>:<x2>,<y2>=<file2>:...` + +* `<w>`: width +* `<h>`: height +* `<x>`: x position +* `<y>`: y position +* `<file>`: texture to combine + +Creates a texture of size `<w>` times `<h>` and blits the listed files to their +specified coordinates. + +Example: + + [combine:16x32:0,0=default_cobble.png:0,16=default_wood.png + +#### `[resize:<w>x<h>` + +Resizes the texture to the given dimensions. + +Example: + + default_sandstone.png^[resize:16x16 + +#### `[opacity:<r>` + +Makes the base image transparent according to the given ratio. + +`r` must be between 0 (transparent) and 255 (opaque). + +Example: + + default_sandstone.png^[opacity:127 + +#### `[invert:<mode>` + +Inverts the given channels of the base image. +Mode may contain the characters "r", "g", "b", "a". +Only the channels that are mentioned in the mode string will be inverted. + +Example: + + default_apple.png^[invert:rgb + +#### `[brighten` + +Brightens the texture. + +Example: + + tnt_tnt_side.png^[brighten + +#### `[noalpha` + +Makes the texture completely opaque. + +Example: + + default_leaves.png^[noalpha + +#### `[makealpha:<r>,<g>,<b>` + +Convert one color to transparency. + +Example: + + default_cobble.png^[makealpha:128,128,128 + +#### `[transform<t>` + +* `<t>`: transformation(s) to apply + +Rotates and/or flips the image. + +`<t>` can be a number (between 0 and 7) or a transform name. +Rotations are counter-clockwise. + + 0 I identity + 1 R90 rotate by 90 degrees + 2 R180 rotate by 180 degrees + 3 R270 rotate by 270 degrees + 4 FX flip X + 5 FXR90 flip X then rotate by 90 degrees + 6 FY flip Y + 7 FYR90 flip Y then rotate by 90 degrees + +Example: + + default_stone.png^[transformFXR90 + +#### `[inventorycube{<top>{<left>{<right>` + +Escaping does not apply here and `^` is replaced by `&` in texture names +instead. + +Create an inventory cube texture using the side textures. + +Example: + + [inventorycube{grass.png{dirt.png&grass_side.png{dirt.png&grass_side.png + +Creates an inventorycube with `grass.png`, `dirt.png^grass_side.png` and +`dirt.png^grass_side.png` textures + +#### `[lowpart:<percent>:<file>` + +Blit the lower `<percent>`% part of `<file>` on the texture. + +Example: + + base.png^[lowpart:25:overlay.png + +#### `[verticalframe:<t>:<n>` + +* `<t>`: animation frame count +* `<n>`: current animation frame + +Crops the texture to a frame of a vertical animation. + +Example: + + default_torch_animated.png^[verticalframe:16:8 + +#### `[mask:<file>` + +Apply a mask to the base image. + +The mask is applied using binary AND. + +#### `[sheet:<w>x<h>:<x>,<y>` + +Retrieves a tile at position x,y from the base image +which it assumes to be a tilesheet with dimensions w,h. + +#### `[colorize:<color>:<ratio>` + +Colorize the textures with the given color. +`<color>` is specified as a `ColorString`. +`<ratio>` is an int ranging from 0 to 255 or the word "`alpha`". If +it is an int, then it specifies how far to interpolate between the +colors where 0 is only the texture color and 255 is only `<color>`. If +omitted, the alpha of `<color>` will be used as the ratio. If it is +the word "`alpha`", then each texture pixel will contain the RGB of +`<color>` and the alpha of `<color>` multiplied by the alpha of the +texture pixel. + +#### `[multiply:<color>` + +Multiplies texture colors with the given color. +`<color>` is specified as a `ColorString`. +Result is more like what you'd expect if you put a color on top of another +color, meaning white surfaces get a lot of your new color while black parts +don't change very much. + +#### `[png:<base64>` + +Embed a base64 encoded PNG image in the texture string. +You can produce a valid string for this by calling +`minetest.encode_base64(minetest.encode_png(tex))`, +refer to the documentation of these functions for details. +You can use this to send disposable images such as captchas +to individual clients, or render things that would be too +expensive to compose with `[combine:`. + +IMPORTANT: Avoid sending large images this way. +This is not a replacement for asset files, do not use it to do anything +that you could instead achieve by just using a file. +In particular consider `minetest.dynamic_add_media` and test whether +using other texture modifiers could result in a shorter string than +embedding a whole image, this may vary by use case. + +Hardware coloring +----------------- + +The goal of hardware coloring is to simplify the creation of +colorful nodes. If your textures use the same pattern, and they only +differ in their color (like colored wool blocks), you can use hardware +coloring instead of creating and managing many texture files. +All of these methods use color multiplication (so a white-black texture +with red coloring will result in red-black color). + +### Static coloring + +This method is useful if you wish to create nodes/items with +the same texture, in different colors, each in a new node/item definition. + +#### Global color + +When you register an item or node, set its `color` field (which accepts a +`ColorSpec`) to the desired color. + +An `ItemStack`'s static color can be overwritten by the `color` metadata +field. If you set that field to a `ColorString`, that color will be used. + +#### Tile color + +Each tile may have an individual static color, which overwrites every +other coloring method. To disable the coloring of a face, +set its color to white (because multiplying with white does nothing). +You can set the `color` property of the tiles in the node's definition +if the tile is in table format. + +### Palettes + +For nodes and items which can have many colors, a palette is more +suitable. A palette is a texture, which can contain up to 256 pixels. +Each pixel is one possible color for the node/item. +You can register one node/item, which can have up to 256 colors. + +#### Palette indexing + +When using palettes, you always provide a pixel index for the given +node or `ItemStack`. The palette is read from left to right and from +top to bottom. If the palette has less than 256 pixels, then it is +stretched to contain exactly 256 pixels (after arranging the pixels +to one line). The indexing starts from 0. + +Examples: + +* 16x16 palette, index = 0: the top left corner +* 16x16 palette, index = 4: the fifth pixel in the first row +* 16x16 palette, index = 16: the pixel below the top left corner +* 16x16 palette, index = 255: the bottom right corner +* 2 (width) x 4 (height) palette, index = 31: the top left corner. + The palette has 8 pixels, so each pixel is stretched to 32 pixels, + to ensure the total 256 pixels. +* 2x4 palette, index = 32: the top right corner +* 2x4 palette, index = 63: the top right corner +* 2x4 palette, index = 64: the pixel below the top left corner + +#### Using palettes with items + +When registering an item, set the item definition's `palette` field to +a texture. You can also use texture modifiers. + +The `ItemStack`'s color depends on the `palette_index` field of the +stack's metadata. `palette_index` is an integer, which specifies the +index of the pixel to use. + +#### Linking palettes with nodes + +When registering a node, set the item definition's `palette` field to +a texture. You can also use texture modifiers. +The node's color depends on its `param2`, so you also must set an +appropriate `paramtype2`: + +* `paramtype2 = "color"` for nodes which use their full `param2` for + palette indexing. These nodes can have 256 different colors. + The palette should contain 256 pixels. +* `paramtype2 = "colorwallmounted"` for nodes which use the first + five bits (most significant) of `param2` for palette indexing. + The remaining three bits are describing rotation, as in `wallmounted` + paramtype2. Division by 8 yields the palette index (without stretching the + palette). These nodes can have 32 different colors, and the palette + should contain 32 pixels. + Examples: + * `param2 = 17` is 2 * 8 + 1, so the rotation is 1 and the third (= 2 + 1) + pixel will be picked from the palette. + * `param2 = 35` is 4 * 8 + 3, so the rotation is 3 and the fifth (= 4 + 1) + pixel will be picked from the palette. +* `paramtype2 = "colorfacedir"` for nodes which use the first + three bits of `param2` for palette indexing. The remaining + five bits are describing rotation, as in `facedir` paramtype2. + Division by 32 yields the palette index (without stretching the + palette). These nodes can have 8 different colors, and the + palette should contain 8 pixels. + Examples: + * `param2 = 17` is 0 * 32 + 17, so the rotation is 17 and the + first (= 0 + 1) pixel will be picked from the palette. + * `param2 = 35` is 1 * 32 + 3, so the rotation is 3 and the + second (= 1 + 1) pixel will be picked from the palette. + +To colorize a node on the map, set its `param2` value (according +to the node's paramtype2). + +### Conversion between nodes in the inventory and on the map + +Static coloring is the same for both cases, there is no need +for conversion. + +If the `ItemStack`'s metadata contains the `color` field, it will be +lost on placement, because nodes on the map can only use palettes. + +If the `ItemStack`'s metadata contains the `palette_index` field, it is +automatically transferred between node and item forms by the engine, +when a player digs or places a colored node. +You can disable this feature by setting the `drop` field of the node +to itself (without metadata). +To transfer the color to a special drop, you need a drop table. + +Example: + + minetest.register_node("mod:stone", { + description = "Stone", + tiles = {"default_stone.png"}, + paramtype2 = "color", + palette = "palette.png", + drop = { + items = { + -- assume that mod:cobblestone also has the same palette + {items = {"mod:cobblestone"}, inherit_color = true }, + } + } + }) + +### Colored items in craft recipes + +Craft recipes only support item strings, but fortunately item strings +can also contain metadata. Example craft recipe registration: + + minetest.register_craft({ + output = minetest.itemstring_with_palette("wool:block", 3), + type = "shapeless", + recipe = { + "wool:block", + "dye:red", + }, + }) + +To set the `color` field, you can use `minetest.itemstring_with_color`. + +Metadata field filtering in the `recipe` field are not supported yet, +so the craft output is independent of the color of the ingredients. + +Soft texture overlay +-------------------- + +Sometimes hardware coloring is not enough, because it affects the +whole tile. Soft texture overlays were added to Minetest to allow +the dynamic coloring of only specific parts of the node's texture. +For example a grass block may have colored grass, while keeping the +dirt brown. + +These overlays are 'soft', because unlike texture modifiers, the layers +are not merged in the memory, but they are simply drawn on top of each +other. This allows different hardware coloring, but also means that +tiles with overlays are drawn slower. Using too much overlays might +cause FPS loss. + +For inventory and wield images you can specify overlays which +hardware coloring does not modify. You have to set `inventory_overlay` +and `wield_overlay` fields to an image name. + +To define a node overlay, simply set the `overlay_tiles` field of the node +definition. These tiles are defined in the same way as plain tiles: +they can have a texture name, color etc. +To skip one face, set that overlay tile to an empty string. + +Example (colored grass block): + + minetest.register_node("default:dirt_with_grass", { + description = "Dirt with Grass", + -- Regular tiles, as usual + -- The dirt tile disables palette coloring + tiles = {{name = "default_grass.png"}, + {name = "default_dirt.png", color = "white"}}, + -- Overlay tiles: define them in the same style + -- The top and bottom tile does not have overlay + overlay_tiles = {"", "", + {name = "default_grass_side.png"}}, + -- Global color, used in inventory + color = "green", + -- Palette in the world + paramtype2 = "color", + palette = "default_foilage.png", + }) + + + + +Sounds +====== + +Only Ogg Vorbis files are supported. + +For positional playing of sounds, only single-channel (mono) files are +supported. Otherwise OpenAL will play them non-positionally. + +Mods should generally prefix their sounds with `modname_`, e.g. given +the mod name "`foomod`", a sound could be called: + + foomod_foosound.ogg + +Sounds are referred to by their name with a dot, a single digit and the +file extension stripped out. When a sound is played, the actual sound file +is chosen randomly from the matching sounds. + +When playing the sound `foomod_foosound`, the sound is chosen randomly +from the available ones of the following files: + +* `foomod_foosound.ogg` +* `foomod_foosound.0.ogg` +* `foomod_foosound.1.ogg` +* (...) +* `foomod_foosound.9.ogg` + +Examples of sound parameter tables: + + -- Play locationless on all clients + { + gain = 1.0, -- default + fade = 0.0, -- default, change to a value > 0 to fade the sound in + pitch = 1.0, -- default + } + -- Play locationless to one player + { + to_player = name, + gain = 1.0, -- default + fade = 0.0, -- default, change to a value > 0 to fade the sound in + pitch = 1.0, -- default + } + -- Play locationless to one player, looped + { + to_player = name, + gain = 1.0, -- default + loop = true, + } + -- Play at a location + { + pos = {x = 1, y = 2, z = 3}, + gain = 1.0, -- default + max_hear_distance = 32, -- default, uses an euclidean metric + } + -- Play connected to an object, looped + { + object = <an ObjectRef>, + gain = 1.0, -- default + max_hear_distance = 32, -- default, uses an euclidean metric + loop = true, + } + -- Play at a location, heard by anyone *but* the given player + { + pos = {x = 32, y = 0, z = 100}, + max_hear_distance = 40, + exclude_player = name, + } + +Looped sounds must either be connected to an object or played locationless to +one player using `to_player = name`. + +A positional sound will only be heard by players that are within +`max_hear_distance` of the sound position, at the start of the sound. + +`exclude_player = name` can be applied to locationless, positional and object- +bound sounds to exclude a single player from hearing them. + +`SimpleSoundSpec` +----------------- + +Specifies a sound name, gain (=volume) and pitch. +This is either a string or a table. + +In string form, you just specify the sound name or +the empty string for no sound. + +Table form has the following fields: + +* `name`: Sound name +* `gain`: Volume (`1.0` = 100%) +* `pitch`: Pitch (`1.0` = 100%) + +`gain` and `pitch` are optional and default to `1.0`. + +Examples: + +* `""`: No sound +* `{}`: No sound +* `"default_place_node"`: Play e.g. `default_place_node.ogg` +* `{name = "default_place_node"}`: Same as above +* `{name = "default_place_node", gain = 0.5}`: 50% volume +* `{name = "default_place_node", gain = 0.9, pitch = 1.1}`: 90% volume, 110% pitch + +Special sound files +------------------- + +These sound files are played back by the engine if provided. + + * `player_damage`: Played when the local player takes damage (gain = 0.5) + * `player_falling_damage`: Played when the local player takes + damage by falling (gain = 0.5) + * `player_jump`: Played when the local player jumps + * `default_dig_<groupname>`: Default node digging sound + (see node sound definition for details) + +Registered definitions +====================== + +Anything added using certain [Registration functions] gets added to one or more +of the global [Registered definition tables]. + +Note that in some cases you will stumble upon things that are not contained +in these tables (e.g. when a mod has been removed). Always check for +existence before trying to access the fields. + +Example: + +All nodes register with `minetest.register_node` get added to the table +`minetest.registered_nodes`. + +If you want to check the drawtype of a node, you could do it like this: + + local def = minetest.registered_nodes[nodename] + local drawtype = def and def.drawtype + + + + +Nodes +===== + +Nodes are the bulk data of the world: cubes and other things that take the +space of a cube. Huge amounts of them are handled efficiently, but they +are quite static. + +The definition of a node is stored and can be accessed by using + + minetest.registered_nodes[node.name] + +See [Registered definitions]. + +Nodes are passed by value between Lua and the engine. +They are represented by a table: + + {name="name", param1=num, param2=num} + +`param1` and `param2` are 8-bit integers ranging from 0 to 255. The engine uses +them for certain automated functions. If you don't use these functions, you can +use them to store arbitrary values. + +Node paramtypes +--------------- + +The functions of `param1` and `param2` are determined by certain fields in the +node definition. + +The function of `param1` is determined by `paramtype` in node definition. +`param1` is reserved for the engine when `paramtype != "none"`. + +* `paramtype = "light"` + * The value stores light with and without sun in its lower and upper 4 bits + respectively. + * Required by a light source node to enable spreading its light. + * Required by the following drawtypes as they determine their visual + brightness from their internal light value: + * torchlike + * signlike + * firelike + * fencelike + * raillike + * nodebox + * mesh + * plantlike + * plantlike_rooted +* `paramtype = "none"` + * `param1` will not be used by the engine and can be used to store + an arbitrary value + +The function of `param2` is determined by `paramtype2` in node definition. +`param2` is reserved for the engine when `paramtype2 != "none"`. + +* `paramtype2 = "flowingliquid"` + * Used by `drawtype = "flowingliquid"` and `liquidtype = "flowing"` + * The liquid level and a flag of the liquid are stored in `param2` + * Bits 0-2: Liquid level (0-7). The higher, the more liquid is in this node; + see `minetest.get_node_level`, `minetest.set_node_level` and `minetest.add_node_level` + to access/manipulate the content of this field + * Bit 3: If set, liquid is flowing downwards (no graphical effect) +* `paramtype2 = "wallmounted"` + * Supported drawtypes: "torchlike", "signlike", "plantlike", + "plantlike_rooted", "normal", "nodebox", "mesh" + * The rotation of the node is stored in `param2` + * You can make this value by using `minetest.dir_to_wallmounted()` + * Values range 0 - 5 + * The value denotes at which direction the node is "mounted": + 0 = y+, 1 = y-, 2 = x+, 3 = x-, 4 = z+, 5 = z- +* `paramtype2 = "facedir"` + * Supported drawtypes: "normal", "nodebox", "mesh" + * The rotation of the node is stored in `param2`. Furnaces and chests are + rotated this way. Can be made by using `minetest.dir_to_facedir()`. + * Values range 0 - 23 + * facedir / 4 = axis direction: + 0 = y+, 1 = z+, 2 = z-, 3 = x+, 4 = x-, 5 = y- + * facedir modulo 4 = rotation around that axis +* `paramtype2 = "leveled"` + * Only valid for "nodebox" with 'type = "leveled"', and "plantlike_rooted". + * Leveled nodebox: + * The level of the top face of the nodebox is stored in `param2`. + * The other faces are defined by 'fixed = {}' like 'type = "fixed"' + nodeboxes. + * The nodebox height is (`param2` / 64) nodes. + * The maximum accepted value of `param2` is 127. + * Rooted plantlike: + * The height of the 'plantlike' section is stored in `param2`. + * The height is (`param2` / 16) nodes. +* `paramtype2 = "degrotate"` + * Valid for `plantlike` and `mesh` drawtypes. The rotation of the node is + stored in `param2`. + * Values range 0–239. The value stored in `param2` is multiplied by 1.5 to + get the actual rotation in degrees of the node. +* `paramtype2 = "meshoptions"` + * Only valid for "plantlike" drawtype. `param2` encodes the shape and + optional modifiers of the "plant". `param2` is a bitfield. + * Bits 0 to 2 select the shape. + Use only one of the values below: + * 0 = a "x" shaped plant (ordinary plant) + * 1 = a "+" shaped plant (just rotated 45 degrees) + * 2 = a "*" shaped plant with 3 faces instead of 2 + * 3 = a "#" shaped plant with 4 faces instead of 2 + * 4 = a "#" shaped plant with 4 faces that lean outwards + * 5-7 are unused and reserved for future meshes. + * Bits 3 to 7 are used to enable any number of optional modifiers. + Just add the corresponding value(s) below to `param2`: + * 8 - Makes the plant slightly vary placement horizontally + * 16 - Makes the plant mesh 1.4x larger + * 32 - Moves each face randomly a small bit down (1/8 max) + * values 64 and 128 (bits 6-7) are reserved for future use. + * Example: `param2 = 0` selects a normal "x" shaped plant + * Example: `param2 = 17` selects a "+" shaped plant, 1.4x larger (1+16) +* `paramtype2 = "color"` + * `param2` tells which color is picked from the palette. + The palette should have 256 pixels. +* `paramtype2 = "colorfacedir"` + * Same as `facedir`, but with colors. + * The first three bits of `param2` tells which color is picked from the + palette. The palette should have 8 pixels. +* `paramtype2 = "colorwallmounted"` + * Same as `wallmounted`, but with colors. + * The first five bits of `param2` tells which color is picked from the + palette. The palette should have 32 pixels. +* `paramtype2 = "glasslikeliquidlevel"` + * Only valid for "glasslike_framed" or "glasslike_framed_optional" + drawtypes. "glasslike_framed_optional" nodes are only affected if the + "Connected Glass" setting is enabled. + * Bits 0-5 define 64 levels of internal liquid, 0 being empty and 63 being + full. + * Bits 6 and 7 modify the appearance of the frame and node faces. One or + both of these values may be added to `param2`: + * 64 - Makes the node not connect with neighbors above or below it. + * 128 - Makes the node not connect with neighbors to its sides. + * Liquid texture is defined using `special_tiles = {"modname_tilename.png"}` +* `paramtype2 = "colordegrotate"` + * Same as `degrotate`, but with colors. + * The first (most-significant) three bits of `param2` tells which color + is picked from the palette. The palette should have 8 pixels. + * Remaining 5 bits store rotation in range 0–23 (i.e. in 15° steps) +* `paramtype2 = "none"` + * `param2` will not be used by the engine and can be used to store + an arbitrary value + +Nodes can also contain extra data. See [Node Metadata]. + +Node drawtypes +-------------- + +There are a bunch of different looking node types. + +Look for examples in `games/devtest` or `games/minetest_game`. + +* `normal` + * A node-sized cube. +* `airlike` + * Invisible, uses no texture. +* `liquid` + * The cubic source node for a liquid. + * Faces bordering to the same node are never rendered. + * Connects to node specified in `liquid_alternative_flowing`. + * Use `backface_culling = false` for the tiles you want to make + visible when inside the node. +* `flowingliquid` + * The flowing version of a liquid, appears with various heights and slopes. + * Faces bordering to the same node are never rendered. + * Connects to node specified in `liquid_alternative_source`. + * Node textures are defined with `special_tiles` where the first tile + is for the top and bottom faces and the second tile is for the side + faces. + * `tiles` is used for the item/inventory/wield image rendering. + * Use `backface_culling = false` for the special tiles you want to make + visible when inside the node +* `glasslike` + * Often used for partially-transparent nodes. + * Only external sides of textures are visible. +* `glasslike_framed` + * All face-connected nodes are drawn as one volume within a surrounding + frame. + * The frame appearance is generated from the edges of the first texture + specified in `tiles`. The width of the edges used are 1/16th of texture + size: 1 pixel for 16x16, 2 pixels for 32x32 etc. + * The glass 'shine' (or other desired detail) on each node face is supplied + by the second texture specified in `tiles`. +* `glasslike_framed_optional` + * This switches between the above 2 drawtypes according to the menu setting + 'Connected Glass'. +* `allfaces` + * Often used for partially-transparent nodes. + * External and internal sides of textures are visible. +* `allfaces_optional` + * Often used for leaves nodes. + * This switches between `normal`, `glasslike` and `allfaces` according to + the menu setting: Opaque Leaves / Simple Leaves / Fancy Leaves. + * With 'Simple Leaves' selected, the texture specified in `special_tiles` + is used instead, if present. This allows a visually thicker texture to be + used to compensate for how `glasslike` reduces visual thickness. +* `torchlike` + * A single vertical texture. + * If `paramtype2="[color]wallmounted"`: + * If placed on top of a node, uses the first texture specified in `tiles`. + * If placed against the underside of a node, uses the second texture + specified in `tiles`. + * If placed on the side of a node, uses the third texture specified in + `tiles` and is perpendicular to that node. + * If `paramtype2="none"`: + * Will be rendered as if placed on top of a node (see + above) and only the first texture is used. +* `signlike` + * A single texture parallel to, and mounted against, the top, underside or + side of a node. + * If `paramtype2="[color]wallmounted"`, it rotates according to `param2` + * If `paramtype2="none"`, it will always be on the floor. +* `plantlike` + * Two vertical and diagonal textures at right-angles to each other. + * See `paramtype2 = "meshoptions"` above for other options. +* `firelike` + * When above a flat surface, appears as 6 textures, the central 2 as + `plantlike` plus 4 more surrounding those. + * If not above a surface the central 2 do not appear, but the texture + appears against the faces of surrounding nodes if they are present. +* `fencelike` + * A 3D model suitable for a wooden fence. + * One placed node appears as a single vertical post. + * Adjacently-placed nodes cause horizontal bars to appear between them. +* `raillike` + * Often used for tracks for mining carts. + * Requires 4 textures to be specified in `tiles`, in order: Straight, + curved, t-junction, crossing. + * Each placed node automatically switches to a suitable rotated texture + determined by the adjacent `raillike` nodes, in order to create a + continuous track network. + * Becomes a sloping node if placed against stepped nodes. +* `nodebox` + * Often used for stairs and slabs. + * Allows defining nodes consisting of an arbitrary number of boxes. + * See [Node boxes] below for more information. +* `mesh` + * Uses models for nodes. + * Tiles should hold model materials textures. + * Only static meshes are implemented. + * For supported model formats see Irrlicht engine documentation. +* `plantlike_rooted` + * Enables underwater `plantlike` without air bubbles around the nodes. + * Consists of a base cube at the co-ordinates of the node plus a + `plantlike` extension above + * If `paramtype2="leveled", the `plantlike` extension has a height + of `param2 / 16` nodes, otherwise it's the height of 1 node + * If `paramtype2="wallmounted"`, the `plantlike` extension + will be at one of the corresponding 6 sides of the base cube. + Also, the base cube rotates like a `normal` cube would + * The `plantlike` extension visually passes through any nodes above the + base cube without affecting them. + * The base cube texture tiles are defined as normal, the `plantlike` + extension uses the defined special tile, for example: + `special_tiles = {{name = "default_papyrus.png"}},` + +`*_optional` drawtypes need less rendering time if deactivated +(always client-side). + +Node boxes +---------- + +Node selection boxes are defined using "node boxes". + +A nodebox is defined as any of: + + { + -- A normal cube; the default in most things + type = "regular" + } + { + -- A fixed box (or boxes) (facedir param2 is used, if applicable) + type = "fixed", + fixed = box OR {box1, box2, ...} + } + { + -- A variable height box (or boxes) with the top face position defined + -- by the node parameter 'leveled = ', or if 'paramtype2 == "leveled"' + -- by param2. + -- Other faces are defined by 'fixed = {}' as with 'type = "fixed"'. + type = "leveled", + fixed = box OR {box1, box2, ...} + } + { + -- A box like the selection box for torches + -- (wallmounted param2 is used, if applicable) + type = "wallmounted", + wall_top = box, + wall_bottom = box, + wall_side = box + } + { + -- A node that has optional boxes depending on neighbouring nodes' + -- presence and type. See also `connects_to`. + type = "connected", + fixed = box OR {box1, box2, ...} + connect_top = box OR {box1, box2, ...} + connect_bottom = box OR {box1, box2, ...} + connect_front = box OR {box1, box2, ...} + connect_left = box OR {box1, box2, ...} + connect_back = box OR {box1, box2, ...} + connect_right = box OR {box1, box2, ...} + -- The following `disconnected_*` boxes are the opposites of the + -- `connect_*` ones above, i.e. when a node has no suitable neighbour + -- on the respective side, the corresponding disconnected box is drawn. + disconnected_top = box OR {box1, box2, ...} + disconnected_bottom = box OR {box1, box2, ...} + disconnected_front = box OR {box1, box2, ...} + disconnected_left = box OR {box1, box2, ...} + disconnected_back = box OR {box1, box2, ...} + disconnected_right = box OR {box1, box2, ...} + disconnected = box OR {box1, box2, ...} -- when there is *no* neighbour + disconnected_sides = box OR {box1, box2, ...} -- when there are *no* + -- neighbours to the sides + } + +A `box` is defined as: + + {x1, y1, z1, x2, y2, z2} + +A box of a regular node would look like: + + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + +To avoid collision issues, keep each value within the range of +/- 1.45. +This also applies to leveled nodeboxes, where the final height shall not +exceed this soft limit. + + + +Map terminology and coordinates +=============================== + +Nodes, mapblocks, mapchunks +--------------------------- + +A 'node' is the fundamental cubic unit of a world and appears to a player as +roughly 1x1x1 meters in size. + +A 'mapblock' (often abbreviated to 'block') is 16x16x16 nodes and is the +fundamental region of a world that is stored in the world database, sent to +clients and handled by many parts of the engine. +'mapblock' is preferred terminology to 'block' to help avoid confusion with +'node', however 'block' often appears in the API. + +A 'mapchunk' (sometimes abbreviated to 'chunk') is usually 5x5x5 mapblocks +(80x80x80 nodes) and is the volume of world generated in one operation by +the map generator. +The size in mapblocks has been chosen to optimise map generation. + +Coordinates +----------- + +### Orientation of axes + +For node and mapblock coordinates, +X is East, +Y is up, +Z is North. + +### Node coordinates + +Almost all positions used in the API use node coordinates. + +### Mapblock coordinates + +Occasionally the API uses 'blockpos' which refers to mapblock coordinates that +specify a particular mapblock. +For example blockpos (0,0,0) specifies the mapblock that extends from +node position (0,0,0) to node position (15,15,15). + +#### Converting node position to the containing blockpos + +To calculate the blockpos of the mapblock that contains the node at 'nodepos', +for each axis: + +* blockpos = math.floor(nodepos / 16) + +#### Converting blockpos to min/max node positions + +To calculate the min/max node positions contained in the mapblock at 'blockpos', +for each axis: + +* Minimum: + nodepos = blockpos * 16 +* Maximum: + nodepos = blockpos * 16 + 15 + + + + +HUD +=== + +HUD element types +----------------- + +The position field is used for all element types. +To account for differing resolutions, the position coordinates are the +percentage of the screen, ranging in value from `0` to `1`. + +The `name` field is not yet used, but should contain a description of what the +HUD element represents. + +The `direction` field is the direction in which something is drawn. +`0` draws from left to right, `1` draws from right to left, `2` draws from +top to bottom, and `3` draws from bottom to top. + +The `alignment` field specifies how the item will be aligned. It is a table +where `x` and `y` range from `-1` to `1`, with `0` being central. `-1` is +moved to the left/up, and `1` is to the right/down. Fractional values can be +used. + +The `offset` field specifies a pixel offset from the position. Contrary to +position, the offset is not scaled to screen size. This allows for some +precisely positioned items in the HUD. + +**Note**: `offset` _will_ adapt to screen DPI as well as user defined scaling +factor! + +The `z_index` field specifies the order of HUD elements from back to front. +Lower z-index elements are displayed behind higher z-index elements. Elements +with same z-index are displayed in an arbitrary order. Default 0. +Supports negative values. By convention, the following values are recommended: + +* -400: Graphical effects, such as vignette +* -300: Name tags, waypoints +* -200: Wieldhand +* -100: Things that block the player's view, e.g. masks +* 0: Default. For standard in-game HUD elements like crosshair, hotbar, + minimap, builtin statbars, etc. +* 100: Temporary text messages or notification icons +* 1000: Full-screen effects such as full-black screen or credits. + This includes effects that cover the entire screen + +If your HUD element doesn't fit into any category, pick a number +between the suggested values + +Below are the specific uses for fields in each type; fields not listed for that +type are ignored. + +### `image` + +Displays an image on the HUD. + +* `scale`: The scale of the image, with 1 being the original texture size. + Only the X coordinate scale is used (positive values). + Negative values represent that percentage of the screen it + should take; e.g. `x=-100` means 100% (width). +* `text`: The name of the texture that is displayed. +* `alignment`: The alignment of the image. +* `offset`: offset in pixels from position. + +### `text` + +Displays text on the HUD. + +* `scale`: Defines the bounding rectangle of the text. + A value such as `{x=100, y=100}` should work. +* `text`: The text to be displayed in the HUD element. +* `number`: An integer containing the RGB value of the color used to draw the + text. Specify `0xFFFFFF` for white text, `0xFF0000` for red, and so on. +* `alignment`: The alignment of the text. +* `offset`: offset in pixels from position. +* `size`: size of the text. + The player-set font size is multiplied by size.x (y value isn't used). +* `style`: determines font style + Bitfield with 1 = bold, 2 = italic, 4 = monospace + +### `statbar` + +Displays a horizontal bar made up of half-images with an optional background. + +* `text`: The name of the texture to use. +* `text2`: Optional texture name to enable a background / "off state" + texture (useful to visualize the maximal value). Both textures + must have the same size. +* `number`: The number of half-textures that are displayed. + If odd, will end with a vertically center-split texture. +* `item`: Same as `number` but for the "off state" texture +* `direction`: To which direction the images will extend to +* `offset`: offset in pixels from position. +* `size`: If used, will force full-image size to this value (override texture + pack image size) + +### `inventory` + +* `text`: The name of the inventory list to be displayed. +* `number`: Number of items in the inventory to be displayed. +* `item`: Position of item that is selected. +* `direction`: Direction the list will be displayed in +* `offset`: offset in pixels from position. + +### `waypoint` + +Displays distance to selected world position. + +* `name`: The name of the waypoint. +* `text`: Distance suffix. Can be blank. +* `precision`: Waypoint precision, integer >= 0. Defaults to 10. + If set to 0, distance is not shown. Shown value is `floor(distance*precision)/precision`. + When the precision is an integer multiple of 10, there will be `log_10(precision)` digits after the decimal point. + `precision = 1000`, for example, will show 3 decimal places (eg: `0.999`). + `precision = 2` will show multiples of `0.5`; precision = 5 will show multiples of `0.2` and so on: + `precision = n` will show multiples of `1/n` +* `number:` An integer containing the RGB value of the color used to draw the + text. +* `world_pos`: World position of the waypoint. +* `offset`: offset in pixels from position. +* `alignment`: The alignment of the waypoint. + +### `image_waypoint` + +Same as `image`, but does not accept a `position`; the position is instead determined by `world_pos`, the world position of the waypoint. + +* `scale`: The scale of the image, with 1 being the original texture size. + Only the X coordinate scale is used (positive values). + Negative values represent that percentage of the screen it + should take; e.g. `x=-100` means 100% (width). +* `text`: The name of the texture that is displayed. +* `alignment`: The alignment of the image. +* `world_pos`: World position of the waypoint. +* `offset`: offset in pixels from position. + +### `compass` + +Displays an image oriented or translated according to current heading direction. + +* `size`: The size of this element. Negative values represent percentage + of the screen; e.g. `x=-100` means 100% (width). +* `scale`: Scale of the translated image (used only for dir = 2 or dir = 3). +* `text`: The name of the texture to use. +* `alignment`: The alignment of the image. +* `offset`: Offset in pixels from position. +* `direction`: How the image is rotated/translated: + * 0 - Rotate as heading direction + * 1 - Rotate in reverse direction + * 2 - Translate as landscape direction + * 3 - Translate in reverse direction + +If translation is chosen, texture is repeated horizontally to fill the whole element. + +### `minimap` + +Displays a minimap on the HUD. + +* `size`: Size of the minimap to display. Minimap should be a square to avoid + distortion. +* `alignment`: The alignment of the minimap. +* `offset`: offset in pixels from position. + +Representations of simple things +================================ + +Vector (ie. a position) +----------------------- + + vector.new(x, y, z) + +See [Spatial Vectors] for details. + +`pointed_thing` +--------------- + +* `{type="nothing"}` +* `{type="node", under=pos, above=pos}` + * Indicates a pointed node selection box. + * `under` refers to the node position behind the pointed face. + * `above` refers to the node position in front of the pointed face. +* `{type="object", ref=ObjectRef}` + +Exact pointing location (currently only `Raycast` supports these fields): + +* `pointed_thing.intersection_point`: The absolute world coordinates of the + point on the selection box which is pointed at. May be in the selection box + if the pointer is in the box too. +* `pointed_thing.box_id`: The ID of the pointed selection box (counting starts + from 1). +* `pointed_thing.intersection_normal`: Unit vector, points outwards of the + selected selection box. This specifies which face is pointed at. + Is a null vector `vector.zero()` when the pointer is inside the selection box. + + + + +Flag Specifier Format +===================== + +Flags using the standardized flag specifier format can be specified in either +of two ways, by string or table. + +The string format is a comma-delimited set of flag names; whitespace and +unrecognized flag fields are ignored. Specifying a flag in the string sets the +flag, and specifying a flag prefixed by the string `"no"` explicitly +clears the flag from whatever the default may be. + +In addition to the standard string flag format, the schematic flags field can +also be a table of flag names to boolean values representing whether or not the +flag is set. Additionally, if a field with the flag name prefixed with `"no"` +is present, mapped to a boolean of any value, the specified flag is unset. + +E.g. A flag field of value + + {place_center_x = true, place_center_y=false, place_center_z=true} + +is equivalent to + + {place_center_x = true, noplace_center_y=true, place_center_z=true} + +which is equivalent to + + "place_center_x, noplace_center_y, place_center_z" + +or even + + "place_center_x, place_center_z" + +since, by default, no schematic attributes are set. + + + + +Items +===== + +Items are things that can be held by players, dropped in the map and +stored in inventories. +Items come in the form of item stacks, which are collections of equal +items that occupy a single inventory slot. + +Item types +---------- + +There are three kinds of items: nodes, tools and craftitems. + +* Node: Placeable item form of a node in the world's voxel grid +* Tool: Has a changable wear property but cannot be stacked +* Craftitem: Has no special properties + +Every registered node (the voxel in the world) has a corresponding +item form (the thing in your inventory) that comes along with it. +This item form can be placed which will create a node in the +world (by default). +Both the 'actual' node and its item form share the same identifier. +For all practical purposes, you can treat the node and its item form +interchangeably. We usually just say 'node' to the item form of +the node as well. + +Note the definition of tools is purely technical. The only really +unique thing about tools is their wear, and that's basically it. +Beyond that, you can't make any gameplay-relevant assumptions +about tools or non-tools. It is perfectly valid to register something +that acts as tool in a gameplay sense as a craftitem, and vice-versa. + +Craftitems can be used for items that neither need to be a node +nor a tool. + +Amount and wear +--------------- + +All item stacks have an amount between 0 and 65535. It is 1 by +default. Tool item stacks can not have an amount greater than 1. + +Tools use a wear (damage) value ranging from 0 to 65535. The +value 0 is the default and is used for unworn tools. The values +1 to 65535 are used for worn tools, where a higher value stands for +a higher wear. Non-tools technically also have a wear property, +but it is always 0. There is also a special 'toolrepair' crafting +recipe that is only available to tools. + +Item formats +------------ + +Items and item stacks can exist in three formats: Serializes, table format +and `ItemStack`. + +When an item must be passed to a function, it can usually be in any of +these formats. + +### Serialized + +This is called "stackstring" or "itemstring". It is a simple string with +1-4 components: + +1. Full item identifier ("item name") +2. Optional amount +3. Optional wear value +4. Optional item metadata + +Syntax: + + <identifier> [<amount>[ <wear>[ <metadata>]]] + +Examples: + +* `"default:apple"`: 1 apple +* `"default:dirt 5"`: 5 dirt +* `"default:pick_stone"`: a new stone pickaxe +* `"default:pick_wood 1 21323"`: a wooden pickaxe, ca. 1/3 worn out +* `[[default:pick_wood 1 21323 "\u0001description\u0002My worn out pick\u0003"]]`: + * a wooden pickaxe from the `default` mod, + * amount must be 1 (pickaxe is a tool), ca. 1/3 worn out (it's a tool), + * with the `description` field set to `"My worn out pick"` in its metadata +* `[[default:dirt 5 0 "\u0001description\u0002Special dirt\u0003"]]`: + * analogeous to the above example + * note how the wear is set to `0` as dirt is not a tool + +You should ideally use the `ItemStack` format to build complex item strings +(especially if they use item metadata) +without relying on the serialization format. Example: + + local stack = ItemStack("default:pick_wood") + stack:set_wear(21323) + stack:get_meta():set_string("description", "My worn out pick") + local itemstring = stack:to_string() + +Additionally the methods `minetest.itemstring_with_palette(item, palette_index)` +and `minetest.itemstring_with_color(item, colorstring)` may be used to create +item strings encoding color information in their metadata. + +### Table format + +Examples: + +5 dirt nodes: + + {name="default:dirt", count=5, wear=0, metadata=""} + +A wooden pick about 1/3 worn out: + + {name="default:pick_wood", count=1, wear=21323, metadata=""} + +An apple: + + {name="default:apple", count=1, wear=0, metadata=""} + +### `ItemStack` + +A native C++ format with many helper methods. Useful for converting +between formats. See the [Class reference] section for details. + + + + +Groups +====== + +In a number of places, there is a group table. Groups define the +properties of a thing (item, node, armor of entity, tool capabilities) +in such a way that the engine and other mods can can interact with +the thing without actually knowing what the thing is. + +Usage +----- + +Groups are stored in a table, having the group names with keys and the +group ratings as values. Group ratings are integer values within the +range [-32767, 32767]. For example: + + -- Default dirt + groups = {crumbly=3, soil=1} + + -- A more special dirt-kind of thing + groups = {crumbly=2, soil=1, level=2, outerspace=1} + +Groups always have a rating associated with them. If there is no +useful meaning for a rating for an enabled group, it shall be `1`. + +When not defined, the rating of a group defaults to `0`. Thus when you +read groups, you must interpret `nil` and `0` as the same value, `0`. + +You can read the rating of a group for an item or a node by using + + minetest.get_item_group(itemname, groupname) + +Groups of items +--------------- + +Groups of items can define what kind of an item it is (e.g. wool). + +Groups of nodes +--------------- + +In addition to the general item things, groups are used to define whether +a node is destroyable and how long it takes to destroy by a tool. + +Groups of entities +------------------ + +For entities, groups are, as of now, used only for calculating damage. +The rating is the percentage of damage caused by items with this damage group. +See [Entity damage mechanism]. + + object.get_armor_groups() --> a group-rating table (e.g. {fleshy=100}) + object.set_armor_groups({fleshy=30, cracky=80}) + +Groups of tool capabilities +--------------------------- + +Groups in tool capabilities define which groups of nodes and entities they +are effective towards. + +Groups in crafting recipes +-------------------------- + +An example: Make meat soup from any meat, any water and any bowl: + + { + output = "food:meat_soup_raw", + recipe = { + {"group:meat"}, + {"group:water"}, + {"group:bowl"}, + }, + } + +Another example: Make red wool from white wool and red dye: + + { + type = "shapeless", + output = "wool:red", + recipe = {"wool:white", "group:dye,basecolor_red"}, + } + +Special groups +-------------- + +The asterisk `(*)` after a group name describes that there is no engine +functionality bound to it, and implementation is left up as a suggestion +to games. + +### Node and item groups + +* `not_in_creative_inventory`: (*) Special group for inventory mods to indicate + that the item should be hidden in item lists. + + +### Node-only groups + +* `attached_node`: if the node under it is not a walkable block the node will be + dropped as an item. If the node is wallmounted the wallmounted direction is + checked. +* `bouncy`: value is bounce speed in percent +* `connect_to_raillike`: makes nodes of raillike drawtype with same group value + connect to each other +* `dig_immediate`: Player can always pick up node without reducing tool wear + * `2`: the node always gets the digging time 0.5 seconds (rail, sign) + * `3`: the node always gets the digging time 0 seconds (torch) +* `disable_jump`: Player (and possibly other things) cannot jump from node + or if their feet are in the node. Note: not supported for `new_move = false` +* `fall_damage_add_percent`: modifies the fall damage suffered when hitting + the top of this node. There's also an armor group with the same name. + The final player damage is determined by the following formula: + damage = + collision speed + * ((node_fall_damage_add_percent + 100) / 100) -- node group + * ((player_fall_damage_add_percent + 100) / 100) -- player armor group + - (14) -- constant tolerance + Negative damage values are discarded as no damage. +* `falling_node`: if there is no walkable block under the node it will fall +* `float`: the node will not fall through liquids (`liquidtype ~= "none"`) +* `level`: Can be used to give an additional sense of progression in the game. + * A larger level will cause e.g. a weapon of a lower level make much less + damage, and get worn out much faster, or not be able to get drops + from destroyed nodes. + * `0` is something that is directly accessible at the start of gameplay + * There is no upper limit + * See also: `leveldiff` in [Tool Capabilities] +* `slippery`: Players and items will slide on the node. + Slipperiness rises steadily with `slippery` value, starting at 1. + + +### Tool-only groups + +* `disable_repair`: If set to 1 for a tool, it cannot be repaired using the + `"toolrepair"` crafting recipe + + +### `ObjectRef` armor groups + +* `immortal`: Skips all damage and breath handling for an object. This group + will also hide the integrated HUD status bars for players. It is + automatically set to all players when damage is disabled on the server and + cannot be reset (subject to change). +* `fall_damage_add_percent`: Modifies the fall damage suffered by players + when they hit the ground. It is analog to the node group with the same + name. See the node group above for the exact calculation. +* `punch_operable`: For entities; disables the regular damage mechanism for + players punching it by hand or a non-tool item, so that it can do something + else than take damage. + + + +Known damage and digging time defining groups +--------------------------------------------- + +* `crumbly`: dirt, sand +* `cracky`: tough but crackable stuff like stone. +* `snappy`: something that can be cut using things like scissors, shears, + bolt cutters and the like, e.g. leaves, small plants, wire, sheets of metal +* `choppy`: something that can be cut using force; e.g. trees, wooden planks +* `fleshy`: Living things like animals and the player. This could imply + some blood effects when hitting. +* `explody`: Especially prone to explosions +* `oddly_breakable_by_hand`: + Can be added to nodes that shouldn't logically be breakable by the + hand but are. Somewhat similar to `dig_immediate`, but times are more + like `{[1]=3.50,[2]=2.00,[3]=0.70}` and this does not override the + digging speed of an item if it can dig at a faster speed than this + suggests for the hand. + +Examples of custom groups +------------------------- + +Item groups are often used for defining, well, _groups of items_. + +* `meat`: any meat-kind of a thing (rating might define the size or healing + ability or be irrelevant -- it is not defined as of yet) +* `eatable`: anything that can be eaten. Rating might define HP gain in half + hearts. +* `flammable`: can be set on fire. Rating might define the intensity of the + fire, affecting e.g. the speed of the spreading of an open fire. +* `wool`: any wool (any origin, any color) +* `metal`: any metal +* `weapon`: any weapon +* `heavy`: anything considerably heavy + +Digging time calculation specifics +---------------------------------- + +Groups such as `crumbly`, `cracky` and `snappy` are used for this +purpose. Rating is `1`, `2` or `3`. A higher rating for such a group implies +faster digging time. + +The `level` group is used to limit the toughness of nodes an item capable +of digging can dig and to scale the digging times / damage to a greater extent. + +**Please do understand this**, otherwise you cannot use the system to it's +full potential. + +Items define their properties by a list of parameters for groups. They +cannot dig other groups; thus it is important to use a standard bunch of +groups to enable interaction with items. + + + + +Tool Capabilities +================= + +'Tool capabilities' is a property of items that defines two things: + +1) Which nodes it can dig and how fast +2) Which objects it can hurt by punching and by how much + +Tool capabilities are available for all items, not just tools. +But only tools can receive wear from digging and punching. + +Missing or incomplete tool capabilities will default to the +player's hand. + +Tool capabilities definition +---------------------------- + +Tool capabilities define: + +* Full punch interval +* Maximum drop level +* For an arbitrary list of node groups: + * Uses (until the tool breaks) + * Maximum level (usually `0`, `1`, `2` or `3`) + * Digging times +* Damage groups +* Punch attack uses (until the tool breaks) + +### Full punch interval `full_punch_interval` + +When used as a weapon, the item will do full damage if this time is spent +between punches. If e.g. half the time is spent, the item will do half +damage. + +### Maximum drop level `max_drop_level` + +Suggests the maximum level of node, when dug with the item, that will drop +its useful item. (e.g. iron ore to drop a lump of iron). + +This value is not used in the engine; it is the responsibility of the game/mod +code to implement this. + +### Uses `uses` (tools only) + +Determines how many uses the tool has when it is used for digging a node, +of this group, of the maximum level. The maximum supported number of +uses is 65535. The special number 0 is used for infinite uses. +For lower leveled nodes, the use count is multiplied by `3^leveldiff`. +`leveldiff` is the difference of the tool's `maxlevel` `groupcaps` and the +node's `level` group. The node cannot be dug if `leveldiff` is less than zero. + +* `uses=10, leveldiff=0`: actual uses: 10 +* `uses=10, leveldiff=1`: actual uses: 30 +* `uses=10, leveldiff=2`: actual uses: 90 + +For non-tools, this has no effect. + +### Maximum level `maxlevel` + +Tells what is the maximum level of a node of this group that the item will +be able to dig. + +### Digging times `times` + +List of digging times for different ratings of the group, for nodes of the +maximum level. + +For example, as a Lua table, `times={[2]=2.00, [3]=0.70}`. This would +result in the item to be able to dig nodes that have a rating of `2` or `3` +for this group, and unable to dig the rating `1`, which is the toughest. +Unless there is a matching group that enables digging otherwise. + +If the result digging time is 0, a delay of 0.15 seconds is added between +digging nodes; If the player releases LMB after digging, this delay is set to 0, +i.e. players can more quickly click the nodes away instead of holding LMB. + +### Damage groups + +List of damage for groups of entities. See [Entity damage mechanism]. + +### Punch attack uses (tools only) + +Determines how many uses (before breaking) the tool has when dealing damage +to an object, when the full punch interval (see above) was always +waited out fully. + +Wear received by the tool is proportional to the time spent, scaled by +the full punch interval. + +For non-tools, this has no effect. + +Example definition of the capabilities of an item +------------------------------------------------- + + tool_capabilities = { + groupcaps={ + crumbly={maxlevel=2, uses=20, times={[1]=1.60, [2]=1.20, [3]=0.80}} + }, + } + +This makes the item capable of digging nodes that fulfil both of these: + +* Have the `crumbly` group +* Have a `level` group less or equal to `2` + +Table of resulting digging times: + + crumbly 0 1 2 3 4 <- level + -> 0 - - - - - + 1 0.80 1.60 1.60 - - + 2 0.60 1.20 1.20 - - + 3 0.40 0.80 0.80 - - + + level diff: 2 1 0 -1 -2 + +Table of resulting tool uses: + + -> 0 - - - - - + 1 180 60 20 - - + 2 180 60 20 - - + 3 180 60 20 - - + +**Notes**: + +* At `crumbly==0`, the node is not diggable. +* At `crumbly==3`, the level difference digging time divider kicks in and makes + easy nodes to be quickly breakable. +* At `level > 2`, the node is not diggable, because it's `level > maxlevel` + + + + +Entity damage mechanism +======================= + +Damage calculation: + + damage = 0 + foreach group in cap.damage_groups: + damage += cap.damage_groups[group] + * limit(actual_interval / cap.full_punch_interval, 0.0, 1.0) + * (object.armor_groups[group] / 100.0) + -- Where object.armor_groups[group] is 0 for inexistent values + return damage + +Client predicts damage based on damage groups. Because of this, it is able to +give an immediate response when an entity is damaged or dies; the response is +pre-defined somehow (e.g. by defining a sprite animation) (not implemented; +TODO). +Currently a smoke puff will appear when an entity dies. + +The group `immortal` completely disables normal damage. + +Entities can define a special armor group, which is `punch_operable`. This +group disables the regular damage mechanism for players punching it by hand or +a non-tool item, so that it can do something else than take damage. + +On the Lua side, every punch calls: + + entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction, + damage) + +This should never be called directly, because damage is usually not handled by +the entity itself. + +* `puncher` is the object performing the punch. Can be `nil`. Should never be + accessed unless absolutely required, to encourage interoperability. +* `time_from_last_punch` is time from last punch (by `puncher`) or `nil`. +* `tool_capabilities` can be `nil`. +* `direction` is a unit vector, pointing from the source of the punch to + the punched object. +* `damage` damage that will be done to entity +Return value of this function will determine if damage is done by this function +(retval true) or shall be done by engine (retval false) + +To punch an entity/object in Lua, call: + + object:punch(puncher, time_from_last_punch, tool_capabilities, direction) + +* Return value is tool wear. +* Parameters are equal to the above callback. +* If `direction` equals `nil` and `puncher` does not equal `nil`, `direction` + will be automatically filled in based on the location of `puncher`. + + + + +Metadata +======== + +Node Metadata +------------- + +The instance of a node in the world normally only contains the three values +mentioned in [Nodes]. However, it is possible to insert extra data into a node. +It is called "node metadata"; See `NodeMetaRef`. + +Node metadata contains two things: + +* A key-value store +* An inventory + +Some of the values in the key-value store are handled specially: + +* `formspec`: Defines an inventory menu that is opened with the + 'place/use' key. Only works if no `on_rightclick` was + defined for the node. See also [Formspec]. +* `infotext`: Text shown on the screen when the node is pointed at. + Line-breaks will be applied automatically. + If the infotext is very long, it will be truncated. + +Example: + + local meta = minetest.get_meta(pos) + meta:set_string("formspec", + "size[8,9]".. + "list[context;main;0,0;8,4;]".. + "list[current_player;main;0,5;8,4;]") + meta:set_string("infotext", "Chest"); + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + print(dump(meta:to_table())) + meta:from_table({ + inventory = { + main = {[1] = "default:dirt", [2] = "", [3] = "", [4] = "", + [5] = "", [6] = "", [7] = "", [8] = "", [9] = "", + [10] = "", [11] = "", [12] = "", [13] = "", + [14] = "default:cobble", [15] = "", [16] = "", [17] = "", + [18] = "", [19] = "", [20] = "default:cobble", [21] = "", + [22] = "", [23] = "", [24] = "", [25] = "", [26] = "", + [27] = "", [28] = "", [29] = "", [30] = "", [31] = "", + [32] = ""} + }, + fields = { + formspec = "size[8,9]list[context;main;0,0;8,4;]list[current_player;main;0,5;8,4;]", + infotext = "Chest" + } + }) + +Item Metadata +------------- + +Item stacks can store metadata too. See [`ItemStackMetaRef`]. + +Item metadata only contains a key-value store. + +Some of the values in the key-value store are handled specially: + +* `description`: Set the item stack's description. + See also: `get_description` in [`ItemStack`] +* `short_description`: Set the item stack's short description. + See also: `get_short_description` in [`ItemStack`] +* `color`: A `ColorString`, which sets the stack's color. +* `palette_index`: If the item has a palette, this is used to get the + current color from the palette. +* `count_meta`: Replace the displayed count with any string. +* `count_alignment`: Set the alignment of the displayed count value. This is an + int value. The lowest 2 bits specify the alignment in x-direction, the 3rd and + 4th bit specify the alignment in y-direction: + 0 = default, 1 = left / up, 2 = middle, 3 = right / down + The default currently is the same as right/down. + Example: 6 = 2 + 1*4 = middle,up + +Example: + + local meta = stack:get_meta() + meta:set_string("key", "value") + print(dump(meta:to_table())) + +Example manipulations of "description" and expected output behaviors: + + print(ItemStack("default:pick_steel"):get_description()) --> Steel Pickaxe + print(ItemStack("foobar"):get_description()) --> Unknown Item + + local stack = ItemStack("default:stone") + stack:get_meta():set_string("description", "Custom description\nAnother line") + print(stack:get_description()) --> Custom description\nAnother line + print(stack:get_short_description()) --> Custom description + + stack:get_meta():set_string("short_description", "Short") + print(stack:get_description()) --> Custom description\nAnother line + print(stack:get_short_description()) --> Short + + print(ItemStack("mod:item_with_no_desc"):get_description()) --> mod:item_with_no_desc + + + +Formspec +======== + +Formspec defines a menu. This supports inventories and some of the +typical widgets like buttons, checkboxes, text input fields, etc. +It is a string, with a somewhat strange format. + +A formspec is made out of formspec elements, which includes widgets +like buttons but also can be used to set stuff like background color. + +Many formspec elements have a `name`, which is a unique identifier which +is used when the server receives user input. You must not use the name +"quit" for formspec elements. + +Spaces and newlines can be inserted between the blocks, as is used in the +examples. + +Position and size units are inventory slots unless the new coordinate system +is enabled. `X` and `Y` position the formspec element relative to the top left +of the menu or container. `W` and `H` are its width and height values. + +If the new system is enabled, all elements have unified coordinates for all +elements with no padding or spacing in between. This is highly recommended +for new forms. See `real_coordinates[<bool>]` and `Migrating to Real +Coordinates`. + +Inventories with a `player:<name>` inventory location are only sent to the +player named `<name>`. + +When displaying text which can contain formspec code, e.g. text set by a player, +use `minetest.formspec_escape`. +For colored text you can use `minetest.colorize`. + +Since formspec version 3, elements drawn in the order they are defined. All +background elements are drawn before all other elements. + +**WARNING**: do _not_ use a element name starting with `key_`; those names are +reserved to pass key press events to formspec! + +**WARNING**: Minetest allows you to add elements to every single formspec instance +using `player:set_formspec_prepend()`, which may be the reason backgrounds are +appearing when you don't expect them to, or why things are styled differently +to normal. See [`no_prepend[]`] and [Styling Formspecs]. + +Examples +-------- + +### Chest + + size[8,9] + list[context;main;0,0;8,4;] + list[current_player;main;0,5;8,4;] + +### Furnace + + size[8,9] + list[context;fuel;2,3;1,1;] + list[context;src;2,1;1,1;] + list[context;dst;5,1;2,2;] + list[current_player;main;0,5;8,4;] + +### Minecraft-like player inventory + + size[8,7.5] + image[1,0.6;1,2;player.png] + list[current_player;main;0,3.5;8,4;] + list[current_player;craft;3,0;3,3;] + list[current_player;craftpreview;7,1;1,1;] + +Version History +--------------- + +* Formspec version 1 (pre-5.1.0): + * (too much) +* Formspec version 2 (5.1.0): + * Forced real coordinates + * background9[]: 9-slice scaling parameters +* Formspec version 3 (5.2.0): + * Formspec elements are drawn in the order of definition + * bgcolor[]: use 3 parameters (bgcolor, formspec (now an enum), fbgcolor) + * box[] and image[] elements enable clipping by default + * new element: scroll_container[] +* Formspec version 4 (5.4.0): + * Allow dropdown indexing events +* Formspec version 5 (5.5.0): + * Added padding[] element +* Formspec version 6 (5.6.0): + * Add nine-slice images, animated_image, and fgimg_middle + +Elements +-------- + +### `formspec_version[<version>]` + +* Set the formspec version to a certain number. If not specified, + version 1 is assumed. +* Must be specified before `size` element. +* Clients older than this version can neither show newer elements nor display + elements with new arguments correctly. +* Available since feature `formspec_version_element`. +* See also: [Version History] + +### `size[<W>,<H>,<fixed_size>]` + +* Define the size of the menu in inventory slots +* `fixed_size`: `true`/`false` (optional) +* deprecated: `invsize[<W>,<H>;]` + +### `position[<X>,<Y>]` + +* Must be used after `size` element. +* Defines the position on the game window of the formspec's `anchor` point. +* For X and Y, 0.0 and 1.0 represent opposite edges of the game window, + for example: + * [0.0, 0.0] sets the position to the top left corner of the game window. + * [1.0, 1.0] sets the position to the bottom right of the game window. +* Defaults to the center of the game window [0.5, 0.5]. + +### `anchor[<X>,<Y>]` + +* Must be used after both `size` and `position` (if present) elements. +* Defines the location of the anchor point within the formspec. +* For X and Y, 0.0 and 1.0 represent opposite edges of the formspec, + for example: + * [0.0, 1.0] sets the anchor to the bottom left corner of the formspec. + * [1.0, 0.0] sets the anchor to the top right of the formspec. +* Defaults to the center of the formspec [0.5, 0.5]. + +* `position` and `anchor` elements need suitable values to avoid a formspec + extending off the game window due to particular game window sizes. + +### `padding[<X>,<Y>]` + +* Must be used after the `size`, `position`, and `anchor` elements (if present). +* Defines how much space is padded around the formspec if the formspec tries to + increase past the size of the screen and coordinates have to be shrunk. +* For X and Y, 0.0 represents no padding (the formspec can touch the edge of the + screen), and 0.5 represents half the screen (which forces the coordinate size + to 0). If negative, the formspec can extend off the edge of the screen. +* Defaults to [0.05, 0.05]. + +### `no_prepend[]` + +* Must be used after the `size`, `position`, `anchor`, and `padding` elements + (if present). +* Disables player:set_formspec_prepend() from applying to this formspec. + +### `real_coordinates[<bool>]` + +* INFORMATION: Enable it automatically using `formspec_version` version 2 or newer. +* When set to true, all following formspec elements will use the new coordinate system. +* If used immediately after `size`, `position`, `anchor`, and `no_prepend` elements + (if present), the form size will use the new coordinate system. +* **Note**: Formspec prepends are not affected by the coordinates in the main form. + They must enable it explicitly. +* For information on converting forms to the new coordinate system, see `Migrating + to Real Coordinates`. + +### `container[<X>,<Y>]` + +* Start of a container block, moves all physical elements in the container by + (X, Y). +* Must have matching `container_end` +* Containers can be nested, in which case the offsets are added + (child containers are relative to parent containers) + +### `container_end[]` + +* End of a container, following elements are no longer relative to this + container. + +### `scroll_container[<X>,<Y>;<W>,<H>;<scrollbar name>;<orientation>;<scroll factor>]` + +* Start of a scroll_container block. All contained elements will ... + * take the scroll_container coordinate as position origin, + * be additionally moved by the current value of the scrollbar with the name + `scrollbar name` times `scroll factor` along the orientation `orientation` and + * be clipped to the rectangle defined by `X`, `Y`, `W` and `H`. +* `orientation`: possible values are `vertical` and `horizontal`. +* `scroll factor`: optional, defaults to `0.1`. +* Nesting is possible. +* Some elements might work a little different if they are in a scroll_container. +* Note: If you want the scroll_container to actually work, you also need to add a + scrollbar element with the specified name. Furthermore, it is highly recommended + to use a scrollbaroptions element on this scrollbar. + +### `scroll_container_end[]` + +* End of a scroll_container, following elements are no longer bound to this + container. + +### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]` + +* Show an inventory list if it has been sent to the client. +* If the inventory list changes (eg. it didn't exist before, it's resized, or its items + are moved) while the formspec is open, the formspec element may (but is not guaranteed + to) adapt to the new inventory list. +* Item slots are drawn in a grid from left to right, then up to down, ordered + according to the slot index. +* `W` and `H` are in inventory slots, not in coordinates. +* `starting item index` (Optional): The index of the first (upper-left) item to draw. + Indices start at `0`. Default is `0`. +* The number of shown slots is the minimum of `W*H` and the inventory list's size minus + `starting item index`. +* **Note**: With the new coordinate system, the spacing between inventory + slots is one-fourth the size of an inventory slot by default. Also see + [Styling Formspecs] for changing the size of slots and spacing. + +### `listring[<inventory location>;<list name>]` + +* Appends to an internal ring of inventory lists. +* Shift-clicking on items in one element of the ring + will send them to the next inventory list inside the ring +* The first occurrence of an element inside the ring will + determine the inventory where items will be sent to + +### `listring[]` + +* Shorthand for doing `listring[<inventory location>;<list name>]` + for the last two inventory lists added by list[...] + +### `listcolors[<slot_bg_normal>;<slot_bg_hover>]` + +* Sets background color of slots as `ColorString` +* Sets background color of slots on mouse hovering + +### `listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>]` + +* Sets background color of slots as `ColorString` +* Sets background color of slots on mouse hovering +* Sets color of slots border + +### `listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>;<tooltip_bgcolor>;<tooltip_fontcolor>]` + +* Sets background color of slots as `ColorString` +* Sets background color of slots on mouse hovering +* Sets color of slots border +* Sets default background color of tooltips +* Sets default font color of tooltips + +### `tooltip[<gui_element_name>;<tooltip_text>;<bgcolor>;<fontcolor>]` + +* Adds tooltip for an element +* `bgcolor` tooltip background color as `ColorString` (optional) +* `fontcolor` tooltip font color as `ColorString` (optional) + +### `tooltip[<X>,<Y>;<W>,<H>;<tooltip_text>;<bgcolor>;<fontcolor>]` + +* Adds tooltip for an area. Other tooltips will take priority when present. +* `bgcolor` tooltip background color as `ColorString` (optional) +* `fontcolor` tooltip font color as `ColorString` (optional) + +### `image[<X>,<Y>;<W>,<H>;<texture name>;<middle>]` + +* Show an image. +* `middle` (optional): Makes the image render in 9-sliced mode and defines the middle rect. + * Requires formspec version >= 6. + * See `background9[]` documentation for more information. + +### `animated_image[<X>,<Y>;<W>,<H>;<name>;<texture name>;<frame count>;<frame duration>;<frame start>;<middle>]` + +* Show an animated image. The image is drawn like a "vertical_frames" tile + animation (See [Tile animation definition]), but uses a frame count/duration for simplicity +* `name`: Element name to send when an event occurs. The event value is the index of the current frame. +* `texture name`: The image to use. +* `frame count`: The number of frames animating the image. +* `frame duration`: Milliseconds between each frame. `0` means the frames don't advance. +* `frame start` (optional): The index of the frame to start on. Default `1`. +* `middle` (optional): Makes the image render in 9-sliced mode and defines the middle rect. + * Requires formspec version >= 6. + * See `background9[]` documentation for more information. + +### `model[<X>,<Y>;<W>,<H>;<name>;<mesh>;<textures>;<rotation X,Y>;<continuous>;<mouse control>;<frame loop range>;<animation speed>]` + +* Show a mesh model. +* `name`: Element name that can be used for styling +* `mesh`: The mesh model to use. +* `textures`: The mesh textures to use according to the mesh materials. + Texture names must be separated by commas. +* `rotation {X,Y}` (Optional): Initial rotation of the camera. + The axes are euler angles in degrees. +* `continuous` (Optional): Whether the rotation is continuous. Default `false`. +* `mouse control` (Optional): Whether the model can be controlled with the mouse. Default `true`. +* `frame loop range` (Optional): Range of the animation frames. + * Defaults to the full range of all available frames. + * Syntax: `<begin>,<end>` +* `animation speed` (Optional): Sets the animation speed. Default 0 FPS. + +### `item_image[<X>,<Y>;<W>,<H>;<item name>]` + +* Show an inventory image of registered item/node + +### `bgcolor[<bgcolor>;<fullscreen>;<fbgcolor>]` + +* Sets background color of formspec. +* `bgcolor` and `fbgcolor` (optional) are `ColorString`s, they define the color + of the non-fullscreen and the fullscreen background. +* `fullscreen` (optional) can be one of the following: + * `false`: Only the non-fullscreen background color is drawn. (default) + * `true`: Only the fullscreen background color is drawn. + * `both`: The non-fullscreen and the fullscreen background color are drawn. + * `neither`: No background color is drawn. +* Note: Leave a parameter empty to not modify the value. +* Note: `fbgcolor`, leaving parameters empty and values for `fullscreen` that + are not bools are only available since formspec version 3. + +### `background[<X>,<Y>;<W>,<H>;<texture name>]` + +* Example for formspec 8x4 in 16x resolution: image shall be sized + 8 times 16px times 4 times 16px. + +### `background[<X>,<Y>;<W>,<H>;<texture name>;<auto_clip>]` + +* Example for formspec 8x4 in 16x resolution: + image shall be sized 8 times 16px times 4 times 16px +* If `auto_clip` is `true`, the background is clipped to the formspec size + (`x` and `y` are used as offset values, `w` and `h` are ignored) + +### `background9[<X>,<Y>;<W>,<H>;<texture name>;<auto_clip>;<middle>]` + +* 9-sliced background. See https://en.wikipedia.org/wiki/9-slice_scaling +* Middle is a rect which defines the middle of the 9-slice. + * `x` - The middle will be x pixels from all sides. + * `x,y` - The middle will be x pixels from the horizontal and y from the vertical. + * `x,y,x2,y2` - The middle will start at x,y, and end at x2, y2. Negative x2 and y2 values + will be added to the width and height of the texture, allowing it to be used as the + distance from the far end. + * All numbers in middle are integers. +* If `auto_clip` is `true`, the background is clipped to the formspec size + (`x` and `y` are used as offset values, `w` and `h` are ignored) +* Available since formspec version 2 + +### `pwdfield[<X>,<Y>;<W>,<H>;<name>;<label>]` + +* Textual password style field; will be sent to server when a button is clicked +* When enter is pressed in field, fields.key_enter_field will be sent with the + name of this field. +* With the old coordinate system, fields are a set height, but will be vertically + centred on `H`. With the new coordinate system, `H` will modify the height. +* `name` is the name of the field as returned in fields to `on_receive_fields` +* `label`, if not blank, will be text printed on the top left above the field +* See `field_close_on_enter` to stop enter closing the formspec + +### `field[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]` + +* Textual field; will be sent to server when a button is clicked +* When enter is pressed in field, `fields.key_enter_field` will be sent with + the name of this field. +* With the old coordinate system, fields are a set height, but will be vertically + centred on `H`. With the new coordinate system, `H` will modify the height. +* `name` is the name of the field as returned in fields to `on_receive_fields` +* `label`, if not blank, will be text printed on the top left above the field +* `default` is the default value of the field + * `default` may contain variable references such as `${text}` which + will fill the value from the metadata value `text` + * **Note**: no extra text or more than a single variable is supported ATM. +* See `field_close_on_enter` to stop enter closing the formspec + +### `field[<name>;<label>;<default>]` + +* As above, but without position/size units +* When enter is pressed in field, `fields.key_enter_field` will be sent with + the name of this field. +* Special field for creating simple forms, such as sign text input +* Must be used without a `size[]` element +* A "Proceed" button will be added automatically +* See `field_close_on_enter` to stop enter closing the formspec + +### `field_close_on_enter[<name>;<close_on_enter>]` + +* <name> is the name of the field +* if <close_on_enter> is false, pressing enter in the field will submit the + form but not close it. +* defaults to true when not specified (ie: no tag for a field) + +### `textarea[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]` + +* Same as fields above, but with multi-line input +* If the text overflows, a vertical scrollbar is added. +* If the name is empty, the textarea is read-only and + the background is not shown, which corresponds to a multi-line label. + +### `label[<X>,<Y>;<label>]` + +* The label formspec element displays the text set in `label` + at the specified position. +* **Note**: If the new coordinate system is enabled, labels are + positioned from the center of the text, not the top. +* The text is displayed directly without automatic line breaking, + so label should not be used for big text chunks. Newlines can be + used to make labels multiline. +* **Note**: With the new coordinate system, newlines are spaced with + half a coordinate. With the old system, newlines are spaced 2/5 of + an inventory slot. + +### `hypertext[<X>,<Y>;<W>,<H>;<name>;<text>]` +* Displays a static formatted text with hyperlinks. +* **Note**: This element is currently unstable and subject to change. +* `x`, `y`, `w` and `h` work as per field +* `name` is the name of the field as returned in fields to `on_receive_fields` in case of action in text. +* `text` is the formatted text using `Markup Language` described below. + +### `vertlabel[<X>,<Y>;<label>]` +* Textual label drawn vertically +* `label` is the text on the label +* **Note**: If the new coordinate system is enabled, vertlabels are + positioned from the center of the text, not the left. + +### `button[<X>,<Y>;<W>,<H>;<name>;<label>]` + +* Clickable button. When clicked, fields will be sent. +* With the old coordinate system, buttons are a set height, but will be vertically + centred on `H`. With the new coordinate system, `H` will modify the height. +* `label` is the text on the button + +### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]` + +* `texture name` is the filename of an image +* **Note**: Height is supported on both the old and new coordinate systems + for image_buttons. + +### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>;<noclip>;<drawborder>;<pressed texture name>]` + +* `texture name` is the filename of an image +* `noclip=true` means the image button doesn't need to be within specified + formsize. +* `drawborder`: draw button border or not +* `pressed texture name` is the filename of an image on pressed state + +### `item_image_button[<X>,<Y>;<W>,<H>;<item name>;<name>;<label>]` + +* `item name` is the registered name of an item/node +* The item description will be used as the tooltip. This can be overridden with + a tooltip element. + +### `button_exit[<X>,<Y>;<W>,<H>;<name>;<label>]` + +* When clicked, fields will be sent and the form will quit. +* Same as `button` in all other respects. + +### `image_button_exit[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]` + +* When clicked, fields will be sent and the form will quit. +* Same as `image_button` in all other respects. + +### `textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>]` + +* Scrollable item list showing arbitrary text elements +* `name` fieldname sent to server on doubleclick value is current selected + element. +* `listelements` can be prepended by #color in hexadecimal format RRGGBB + (only). + * if you want a listelement to start with "#" write "##". + +### `textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>;<selected idx>;<transparent>]` + +* Scrollable itemlist showing arbitrary text elements +* `name` fieldname sent to server on doubleclick value is current selected + element. +* `listelements` can be prepended by #RRGGBB (only) in hexadecimal format + * if you want a listelement to start with "#" write "##" +* Index to be selected within textlist +* `true`/`false`: draw transparent background +* See also `minetest.explode_textlist_event` + (main menu: `core.explode_textlist_event`). + +### `tabheader[<X>,<Y>;<name>;<caption 1>,<caption 2>,...,<caption n>;<current_tab>;<transparent>;<draw_border>]` + +* Show a tab**header** at specific position (ignores formsize) +* `X` and `Y`: position of the tabheader +* *Note*: Width and height are automatically chosen with this syntax +* `name` fieldname data is transferred to Lua +* `caption 1`...: name shown on top of tab +* `current_tab`: index of selected tab 1... +* `transparent` (optional): if true, tabs are semi-transparent +* `draw_border` (optional): if true, draw a thin line at tab base + +### `tabheader[<X>,<Y>;<H>;<name>;<caption 1>,<caption 2>,...,<caption n>;<current_tab>;<transparent>;<draw_border>]` + +* Show a tab**header** at specific position (ignores formsize) +* **Important note**: This syntax for tabheaders can only be used with the + new coordinate system. +* `X` and `Y`: position of the tabheader +* `H`: height of the tabheader. Width is automatically determined with this syntax. +* `name` fieldname data is transferred to Lua +* `caption 1`...: name shown on top of tab +* `current_tab`: index of selected tab 1... +* `transparent` (optional): show transparent +* `draw_border` (optional): draw border + +### `tabheader[<X>,<Y>;<W>,<H>;<name>;<caption 1>,<caption 2>,...,<caption n>;<current_tab>;<transparent>;<draw_border>]` + +* Show a tab**header** at specific position (ignores formsize) +* **Important note**: This syntax for tabheaders can only be used with the + new coordinate system. +* `X` and `Y`: position of the tabheader +* `W` and `H`: width and height of the tabheader +* `name` fieldname data is transferred to Lua +* `caption 1`...: name shown on top of tab +* `current_tab`: index of selected tab 1... +* `transparent` (optional): show transparent +* `draw_border` (optional): draw border + +### `box[<X>,<Y>;<W>,<H>;<color>]` + +* Simple colored box +* `color` is color specified as a `ColorString`. + If the alpha component is left blank, the box will be semitransparent. + If the color is not specified, the box will use the options specified by + its style. If the color is specified, all styling options will be ignored. + +### `dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>;<index event>]` + +* Show a dropdown field +* **Important note**: There are two different operation modes: + 1. handle directly on change (only changed dropdown is submitted) + 2. read the value on pressing a button (all dropdown values are available) +* `X` and `Y`: position of the dropdown +* `W`: width of the dropdown. Height is automatically chosen with this syntax. +* Fieldname data is transferred to Lua +* Items to be shown in dropdown +* Index of currently selected dropdown item +* `index event` (optional, allowed parameter since formspec version 4): Specifies the + event field value for selected items. + * `true`: Selected item index + * `false` (default): Selected item value + +### `dropdown[<X>,<Y>;<W>,<H>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>;<index event>]` + +* Show a dropdown field +* **Important note**: This syntax for dropdowns can only be used with the + new coordinate system. +* **Important note**: There are two different operation modes: + 1. handle directly on change (only changed dropdown is submitted) + 2. read the value on pressing a button (all dropdown values are available) +* `X` and `Y`: position of the dropdown +* `W` and `H`: width and height of the dropdown +* Fieldname data is transferred to Lua +* Items to be shown in dropdown +* Index of currently selected dropdown item +* `index event` (optional, allowed parameter since formspec version 4): Specifies the + event field value for selected items. + * `true`: Selected item index + * `false` (default): Selected item value + +### `checkbox[<X>,<Y>;<name>;<label>;<selected>]` + +* Show a checkbox +* `name` fieldname data is transferred to Lua +* `label` to be shown left of checkbox +* `selected` (optional): `true`/`false` +* **Note**: If the new coordinate system is enabled, checkboxes are + positioned from the center of the checkbox, not the top. + +### `scrollbar[<X>,<Y>;<W>,<H>;<orientation>;<name>;<value>]` + +* Show a scrollbar using options defined by the previous `scrollbaroptions[]` +* There are two ways to use it: + 1. handle the changed event (only changed scrollbar is available) + 2. read the value on pressing a button (all scrollbars are available) +* `orientation`: `vertical`/`horizontal`. Default horizontal. +* Fieldname data is transferred to Lua +* Value of this trackbar is set to (`0`-`1000`) by default +* See also `minetest.explode_scrollbar_event` + (main menu: `core.explode_scrollbar_event`). + +### `scrollbaroptions[opt1;opt2;...]` +* Sets options for all following `scrollbar[]` elements +* `min=<int>` + * Sets scrollbar minimum value, defaults to `0`. +* `max=<int>` + * Sets scrollbar maximum value, defaults to `1000`. + If the max is equal to the min, the scrollbar will be disabled. +* `smallstep=<int>` + * Sets scrollbar step value when the arrows are clicked or the mouse wheel is + scrolled. + * If this is set to a negative number, the value will be reset to `10`. +* `largestep=<int>` + * Sets scrollbar step value used by page up and page down. + * If this is set to a negative number, the value will be reset to `100`. +* `thumbsize=<int>` + * Sets size of the thumb on the scrollbar. Size is calculated in the number of + units the thumb spans out of the range of the scrollbar values. + * Example: If a scrollbar has a `min` of 1 and a `max` of 100, a thumbsize of 10 + would span a tenth of the scrollbar space. + * If this is set to zero or less, the value will be reset to `1`. +* `arrows=<show/hide/default>` + * Whether to show the arrow buttons on the scrollbar. `default` hides the arrows + when the scrollbar gets too small, but shows them otherwise. + +### `table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]` + +* Show scrollable table using options defined by the previous `tableoptions[]` +* Displays cells as defined by the previous `tablecolumns[]` +* `name`: fieldname sent to server on row select or doubleclick +* `cell 1`...`cell n`: cell contents given in row-major order +* `selected idx`: index of row to be selected within table (first row = `1`) +* See also `minetest.explode_table_event` + (main menu: `core.explode_table_event`). + +### `tableoptions[<opt 1>;<opt 2>;...]` + +* Sets options for `table[]` +* `color=#RRGGBB` + * default text color (`ColorString`), defaults to `#FFFFFF` +* `background=#RRGGBB` + * table background color (`ColorString`), defaults to `#000000` +* `border=<true/false>` + * should the table be drawn with a border? (default: `true`) +* `highlight=#RRGGBB` + * highlight background color (`ColorString`), defaults to `#466432` +* `highlight_text=#RRGGBB` + * highlight text color (`ColorString`), defaults to `#FFFFFF` +* `opendepth=<value>` + * all subtrees up to `depth < value` are open (default value = `0`) + * only useful when there is a column of type "tree" + +### `tablecolumns[<type 1>,<opt 1a>,<opt 1b>,...;<type 2>,<opt 2a>,<opt 2b>;...]` + +* Sets columns for `table[]` +* Types: `text`, `image`, `color`, `indent`, `tree` + * `text`: show cell contents as text + * `image`: cell contents are an image index, use column options to define + images. + * `color`: cell contents are a ColorString and define color of following + cell. + * `indent`: cell contents are a number and define indentation of following + cell. + * `tree`: same as indent, but user can open and close subtrees + (treeview-like). +* Column options: + * `align=<value>` + * for `text` and `image`: content alignment within cells. + Available values: `left` (default), `center`, `right`, `inline` + * `width=<value>` + * for `text` and `image`: minimum width in em (default: `0`) + * for `indent` and `tree`: indent width in em (default: `1.5`) + * `padding=<value>`: padding left of the column, in em (default `0.5`). + Exception: defaults to 0 for indent columns + * `tooltip=<value>`: tooltip text (default: empty) + * `image` column options: + * `0=<value>` sets image for image index 0 + * `1=<value>` sets image for image index 1 + * `2=<value>` sets image for image index 2 + * and so on; defined indices need not be contiguous empty or + non-numeric cells are treated as `0`. + * `color` column options: + * `span=<value>`: number of following columns to affect + (default: infinite). + +### `style[<selector 1>,<selector 2>,...;<prop1>;<prop2>;...]` + +* Set the style for the element(s) matching `selector` by name. +* `selector` can be one of: + * `<name>` - An element name. Includes `*`, which represents every element. + * `<name>:<state>` - An element name, a colon, and one or more states. +* `state` is a list of states separated by the `+` character. + * If a state is provided, the style will only take effect when the element is in that state. + * All provided states must be active for the style to apply. +* Note: this **must** be before the element is defined. +* See [Styling Formspecs]. + + +### `style_type[<selector 1>,<selector 2>,...;<prop1>;<prop2>;...]` + +* Set the style for the element(s) matching `selector` by type. +* `selector` can be one of: + * `<type>` - An element type. Includes `*`, which represents every element. + * `<type>:<state>` - An element type, a colon, and one or more states. +* `state` is a list of states separated by the `+` character. + * If a state is provided, the style will only take effect when the element is in that state. + * All provided states must be active for the style to apply. +* See [Styling Formspecs]. + +### `set_focus[<name>;<force>]` + +* Sets the focus to the element with the same `name` parameter. +* **Note**: This element must be placed before the element it focuses. +* `force` (optional, default `false`): By default, focus is not applied for + re-sent formspecs with the same name so that player-set focus is kept. + `true` sets the focus to the specified element for every sent formspec. +* The following elements have the ability to be focused: + * checkbox + * button + * button_exit + * image_button + * image_button_exit + * item_image_button + * table + * textlist + * dropdown + * field + * pwdfield + * textarea + * scrollbar + +Migrating to Real Coordinates +----------------------------- + +In the old system, positions included padding and spacing. Padding is a gap between +the formspec window edges and content, and spacing is the gaps between items. For +example, two `1x1` elements at `0,0` and `1,1` would have a spacing of `5/4` between them, +and a padding of `3/8` from the formspec edge. It may be easiest to recreate old layouts +in the new coordinate system from scratch. + +To recreate an old layout with padding, you'll need to pass the positions and sizes +through the following formula to re-introduce padding: + +``` +pos = (oldpos + 1)*spacing + padding +where + padding = 3/8 + spacing = 5/4 +``` + +You'll need to change the `size[]` tag like this: + +``` +size = (oldsize-1)*spacing + padding*2 + 1 +``` + +A few elements had random offsets in the old system. Here is a table which shows these +offsets when migrating: + +| Element | Position | Size | Notes +|---------|------------|---------|------- +| box | +0.3, +0.1 | 0, -0.4 | +| button | | | Buttons now support height, so set h = 2 * 15/13 * 0.35, and reposition if h ~= 15/13 * 0.35 before +| list | | | Spacing is now 0.25 for both directions, meaning lists will be taller in height +| label | 0, +0.3 | | The first line of text is now positioned centered exactly at the position specified + +Styling Formspecs +----------------- + +Formspec elements can be themed using the style elements: + + style[<name 1>,<name 2>,...;<prop1>;<prop2>;...] + style[<name 1>:<state>,<name 2>:<state>,...;<prop1>;<prop2>;...] + style_type[<type 1>,<type 2>,...;<prop1>;<prop2>;...] + style_type[<type 1>:<state>,<type 2>:<state>,...;<prop1>;<prop2>;...] + +Where a prop is: + + property_name=property_value + +For example: + + style_type[button;bgcolor=#006699] + style[world_delete;bgcolor=red;textcolor=yellow] + button[4,3.95;2.6,1;world_delete;Delete] + +A name/type can optionally be a comma separated list of names/types, like so: + + world_delete,world_create,world_configure + button,image_button + +A `*` type can be used to select every element in the formspec. + +Any name/type in the list can also be accompanied by a `+`-separated list of states, like so: + + world_delete:hovered+pressed + button:pressed + +States allow you to apply styles in response to changes in the element, instead of applying at all times. + +Setting a property to nothing will reset it to the default value. For example: + + style_type[button;bgimg=button.png;bgimg_pressed=button_pressed.png;border=false] + style[btn_exit;bgimg=;bgimg_pressed=;border=;bgcolor=red] + + +### Supported Element Types + +Some types may inherit styles from parent types. + +* animated_image, inherits from image +* box +* button +* button_exit, inherits from button +* checkbox +* dropdown +* field +* image +* image_button +* item_image_button +* label +* list +* model +* pwdfield, inherits from field +* scrollbar +* tabheader +* table +* textarea +* textlist +* vertlabel, inherits from label + + +### Valid Properties + +* animated_image + * noclip - boolean, set to true to allow the element to exceed formspec bounds. +* box + * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * Defaults to false in formspec_version version 3 or higher + * **Note**: `colors`, `bordercolors`, and `borderwidths` accept multiple input types: + * Single value (e.g. `#FF0`): All corners/borders. + * Two values (e.g. `red,#FFAAFF`): top-left and bottom-right,top-right and bottom-left/ + top and bottom,left and right. + * Four values (e.g. `blue,#A0F,green,#FFFA`): top-left/top and rotates clockwise. + * These work similarly to CSS borders. + * colors - `ColorString`. Sets the color(s) of the box corners. Default `black`. + * bordercolors - `ColorString`. Sets the color(s) of the borders. Default `black`. + * borderwidths - Integer. Sets the width(s) of the borders in pixels. If the width is + negative, the border will extend inside the box, whereas positive extends outside + the box. A width of zero results in no border; this is default. +* button, button_exit, image_button, item_image_button + * alpha - boolean, whether to draw alpha in bgimg. Default true. + * bgcolor - color, sets button tint. + * bgcolor_hovered - color when hovered. Defaults to a lighter bgcolor when not provided. + * This is deprecated, use states instead. + * bgcolor_pressed - color when pressed. Defaults to a darker bgcolor when not provided. + * This is deprecated, use states instead. + * bgimg - standard background image. Defaults to none. + * bgimg_hovered - background image when hovered. Defaults to bgimg when not provided. + * This is deprecated, use states instead. + * bgimg_middle - Makes the bgimg textures render in 9-sliced mode and defines the middle rect. + See background9[] documentation for more details. This property also pads the + button's content when set. + * bgimg_pressed - background image when pressed. Defaults to bgimg when not provided. + * This is deprecated, use states instead. + * font - Sets font type. This is a comma separated list of options. Valid options: + * Main font type options. These cannot be combined with each other: + * `normal`: Default font + * `mono`: Monospaced font + * Font modification options. If used without a main font type, `normal` is used: + * `bold`: Makes font bold. + * `italic`: Makes font italic. + Default `normal`. + * font_size - Sets font size. Default is user-set. Can have multiple values: + * `<number>`: Sets absolute font size to `number`. + * `+<number>`/`-<number>`: Offsets default font size by `number` points. + * `*<number>`: Multiplies default font size by `number`, similar to CSS `em`. + * border - boolean, draw border. Set to false to hide the bevelled button pane. Default true. + * content_offset - 2d vector, shifts the position of the button's content without resizing it. + * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * padding - rect, adds space between the edges of the button and the content. This value is + relative to bgimg_middle. + * sound - a sound to be played when triggered. + * textcolor - color, default white. +* checkbox + * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * sound - a sound to be played when triggered. +* dropdown + * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * sound - a sound to be played when the entry is changed. +* field, pwdfield, textarea + * border - set to false to hide the textbox background and border. Default true. + * font - Sets font type. See button `font` property for more information. + * font_size - Sets font size. See button `font_size` property for more information. + * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * textcolor - color. Default white. +* model + * bgcolor - color, sets background color. + * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * Default to false in formspec_version version 3 or higher +* image + * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * Default to false in formspec_version version 3 or higher +* item_image + * noclip - boolean, set to true to allow the element to exceed formspec bounds. Default to false. +* label, vertlabel + * font - Sets font type. See button `font` property for more information. + * font_size - Sets font size. See button `font_size` property for more information. + * noclip - boolean, set to true to allow the element to exceed formspec bounds. +* list + * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * size - 2d vector, sets the size of inventory slots in coordinates. + * spacing - 2d vector, sets the space between inventory slots in coordinates. +* image_button (additional properties) + * fgimg - standard image. Defaults to none. + * fgimg_hovered - image when hovered. Defaults to fgimg when not provided. + * This is deprecated, use states instead. + * fgimg_pressed - image when pressed. Defaults to fgimg when not provided. + * This is deprecated, use states instead. + * fgimg_middle - Makes the fgimg textures render in 9-sliced mode and defines the middle rect. + See background9[] documentation for more details. + * NOTE: The parameters of any given image_button will take precedence over fgimg/fgimg_pressed + * sound - a sound to be played when triggered. +* scrollbar + * noclip - boolean, set to true to allow the element to exceed formspec bounds. +* tabheader + * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * sound - a sound to be played when a different tab is selected. + * textcolor - color. Default white. +* table, textlist + * font - Sets font type. See button `font` property for more information. + * font_size - Sets font size. See button `font_size` property for more information. + * noclip - boolean, set to true to allow the element to exceed formspec bounds. + +### Valid States + +* *all elements* + * default - Equivalent to providing no states +* button, button_exit, image_button, item_image_button + * hovered - Active when the mouse is hovering over the element + * pressed - Active when the button is pressed + +Markup Language +--------------- + +Markup language used in `hypertext[]` elements uses tags that look like HTML tags. +The markup language is currently unstable and subject to change. Use with caution. +Some tags can enclose text, they open with `<tagname>` and close with `</tagname>`. +Tags can have attributes, in that case, attributes are in the opening tag in +form of a key/value separated with equal signs. Attribute values should not be quoted. + +If you want to insert a literal greater-than sign or a backslash into the text, +you must escape it by preceding it with a backslash. + +These are the technically basic tags but see below for usual tags. Base tags are: + +`<style color=... font=... size=...>...</style>` + +Changes the style of the text. + +* `color`: Text color. Given color is a `colorspec`. +* `size`: Text size. +* `font`: Text font (`mono` or `normal`). + +`<global background=... margin=... valign=... color=... hovercolor=... size=... font=... halign=... >` + +Sets global style. + +Global only styles: +* `background`: Text background, a `colorspec` or `none`. +* `margin`: Page margins in pixel. +* `valign`: Text vertical alignment (`top`, `middle`, `bottom`). + +Inheriting styles (affects child elements): +* `color`: Default text color. Given color is a `colorspec`. +* `hovercolor`: Color of <action> tags when mouse is over. +* `size`: Default text size. +* `font`: Default text font (`mono` or `normal`). +* `halign`: Default text horizontal alignment (`left`, `right`, `center`, `justify`). + +This tag needs to be placed only once as it changes the global settings of the +text. Anyway, if several tags are placed, each changed will be made in the order +tags appear. + +`<tag name=... color=... hovercolor=... font=... size=...>` + +Defines or redefines tag style. This can be used to define new tags. +* `name`: Name of the tag to define or change. +* `color`: Text color. Given color is a `colorspec`. +* `hovercolor`: Text color when element hovered (only for `action` tags). Given color is a `colorspec`. +* `size`: Text size. +* `font`: Text font (`mono` or `normal`). + +Following tags are the usual tags for text layout. They are defined by default. +Other tags can be added using `<tag ...>` tag. + +`<normal>...</normal>`: Normal size text + +`<big>...</big>`: Big text + +`<bigger>...</bigger>`: Bigger text + +`<center>...</center>`: Centered text + +`<left>...</left>`: Left-aligned text + +`<right>...</right>`: Right-aligned text + +`<justify>...</justify>`: Justified text + +`<mono>...</mono>`: Monospaced font + +`<b>...</b>`, `<i>...</i>`, `<u>...</u>`: Bold, italic, underline styles. + +`<action name=...>...</action>` + +Make that text a clickable text triggering an action. + +* `name`: Name of the action (mandatory). + +When clicked, the formspec is send to the server. The value of the text field +sent to `on_player_receive_fields` will be "action:" concatenated to the action +name. + +`<img name=... float=... width=... height=...>` + +Draws an image which is present in the client media cache. + +* `name`: Name of the texture (mandatory). +* `float`: If present, makes the image floating (`left` or `right`). +* `width`: Force image width instead of taking texture width. +* `height`: Force image height instead of taking texture height. + +If only width or height given, texture aspect is kept. + +`<item name=... float=... width=... height=... rotate=...>` + +Draws an item image. + +* `name`: Item string of the item to draw (mandatory). +* `float`: If present, makes the image floating (`left` or `right`). +* `width`: Item image width. +* `height`: Item image height. +* `rotate`: Rotate item image if set to `yes` or `X,Y,Z`. X, Y and Z being +rotation speeds in percent of standard speed (-1000 to 1000). Works only if +`inventory_items_animations` is set to true. +* `angle`: Angle in which the item image is shown. Value has `X,Y,Z` form. +X, Y and Z being angles around each three axes. Works only if +`inventory_items_animations` is set to true. + +Inventory +========= + +Inventory locations +------------------- + +* `"context"`: Selected node metadata (deprecated: `"current_name"`) +* `"current_player"`: Player to whom the menu is shown +* `"player:<name>"`: Any player +* `"nodemeta:<X>,<Y>,<Z>"`: Any node metadata +* `"detached:<name>"`: A detached inventory + +Player Inventory lists +---------------------- + +* `main`: list containing the default inventory +* `craft`: list containing the craft input +* `craftpreview`: list containing the craft prediction +* `craftresult`: list containing the crafted output +* `hand`: list containing an override for the empty hand + * Is not created automatically, use `InvRef:set_size` + * Is only used to enhance the empty hand's tool capabilities + +Colors +====== + +`ColorString` +------------- + +`#RGB` defines a color in hexadecimal format. + +`#RGBA` defines a color in hexadecimal format and alpha channel. + +`#RRGGBB` defines a color in hexadecimal format. + +`#RRGGBBAA` defines a color in hexadecimal format and alpha channel. + +Named colors are also supported and are equivalent to +[CSS Color Module Level 4](https://www.w3.org/TR/css-color-4/#named-color). +To specify the value of the alpha channel, append `#A` or `#AA` to the end of +the color name (e.g. `colorname#08`). + +`ColorSpec` +----------- + +A ColorSpec specifies a 32-bit color. It can be written in any of the following +forms: + +* table form: Each element ranging from 0..255 (a, if absent, defaults to 255): + * `colorspec = {a=255, r=0, g=255, b=0}` +* numerical form: The raw integer value of an ARGB8 quad: + * `colorspec = 0xFF00FF00` +* string form: A ColorString (defined above): + * `colorspec = "green"` + + + + +Escape sequences +================ + +Most text can contain escape sequences, that can for example color the text. +There are a few exceptions: tab headers, dropdowns and vertical labels can't. +The following functions provide escape sequences: + +* `minetest.get_color_escape_sequence(color)`: + * `color` is a ColorString + * The escape sequence sets the text color to `color` +* `minetest.colorize(color, message)`: + * Equivalent to: + `minetest.get_color_escape_sequence(color) .. + message .. + minetest.get_color_escape_sequence("#ffffff")` +* `minetest.get_background_escape_sequence(color)` + * `color` is a ColorString + * The escape sequence sets the background of the whole text element to + `color`. Only defined for item descriptions and tooltips. +* `minetest.strip_foreground_colors(str)` + * Removes foreground colors added by `get_color_escape_sequence`. +* `minetest.strip_background_colors(str)` + * Removes background colors added by `get_background_escape_sequence`. +* `minetest.strip_colors(str)` + * Removes all color escape sequences. + + + + +Spatial Vectors +=============== + +Minetest stores 3-dimensional spatial vectors in Lua as tables of 3 coordinates, +and has a class to represent them (`vector.*`), which this chapter is about. +For details on what a spatial vectors is, please refer to Wikipedia: +https://en.wikipedia.org/wiki/Euclidean_vector. + +Spatial vectors are used for various things, including, but not limited to: + +* any 3D spatial vector (x/y/z-directions) +* Euler angles (pitch/yaw/roll in radians) (Spatial vectors have no real semantic + meaning here. Therefore, most vector operations make no sense in this use case.) + +Note that they are *not* used for: + +* n-dimensional vectors where n is not 3 (ie. n=2) +* arrays of the form `{num, num, num}` + +The API documentation may refer to spatial vectors, as produced by `vector.new`, +by any of the following notations: + +* `(x, y, z)` (Used rarely, and only if it's clear that it's a vector.) +* `vector.new(x, y, z)` +* `{x=num, y=num, z=num}` (Even here you are still supposed to use `vector.new`.) + +Compatibility notes +------------------- + +Vectors used to be defined as tables of the form `{x = num, y = num, z = num}`. +Since Minetest 5.5.0, vectors additionally have a metatable to enable easier use. +Note: Those old-style vectors can still be found in old mod code. Hence, mod and +engine APIs still need to be able to cope with them in many places. + +Manually constructed tables are deprecated and highly discouraged. This interface +should be used to ensure seamless compatibility between mods and the Minetest API. +This is especially important to callback function parameters and functions overwritten +by mods. +Also, though not likely, the internal implementation of a vector might change in +the future. +In your own code, or if you define your own API, you can, of course, still use +other representations of vectors. + +Vectors provided by API functions will provide an instance of this class if not +stated otherwise. Mods should adapt this for convenience reasons. + +Special properties of the class +------------------------------- + +Vectors can be indexed with numbers and allow method and operator syntax. + +All these forms of addressing a vector `v` are valid: +`v[1]`, `v[3]`, `v.x`, `v[1] = 42`, `v.y = 13` +Note: Prefer letter over number indexing for performance and compatibility reasons. + +Where `v` is a vector and `foo` stands for any function name, `v:foo(...)` does +the same as `vector.foo(v, ...)`, apart from deprecated functionality. + +`tostring` is defined for vectors, see `vector.to_string`. + +The metatable that is used for vectors can be accessed via `vector.metatable`. +Do not modify it! + +All `vector.*` functions allow vectors `{x = X, y = Y, z = Z}` without metatables. +Returned vectors always have a metatable set. + +Common functions and methods +---------------------------- + +For the following functions (and subchapters), +`v`, `v1`, `v2` are vectors, +`p1`, `p2` are position vectors, +`s` is a scalar (a number), +vectors are written like this: `(x, y, z)`: + +* `vector.new([a[, b, c]])`: + * Returns a new vector `(a, b, c)`. + * Deprecated: `vector.new()` does the same as `vector.zero()` and + `vector.new(v)` does the same as `vector.copy(v)` +* `vector.zero()`: + * Returns a new vector `(0, 0, 0)`. +* `vector.copy(v)`: + * Returns a copy of the vector `v`. +* `vector.from_string(s[, init])`: + * Returns `v, np`, where `v` is a vector read from the given string `s` and + `np` is the next position in the string after the vector. + * Returns `nil` on failure. + * `s`: Has to begin with a substring of the form `"(x, y, z)"`. Additional + spaces, leaving away commas and adding an additional comma to the end + is allowed. + * `init`: If given starts looking for the vector at this string index. +* `vector.to_string(v)`: + * Returns a string of the form `"(x, y, z)"`. + * `tostring(v)` does the same. +* `vector.direction(p1, p2)`: + * Returns a vector of length 1 with direction `p1` to `p2`. + * If `p1` and `p2` are identical, returns `(0, 0, 0)`. +* `vector.distance(p1, p2)`: + * Returns zero or a positive number, the distance between `p1` and `p2`. +* `vector.length(v)`: + * Returns zero or a positive number, the length of vector `v`. +* `vector.normalize(v)`: + * Returns a vector of length 1 with direction of vector `v`. + * If `v` has zero length, returns `(0, 0, 0)`. +* `vector.floor(v)`: + * Returns a vector, each dimension rounded down. +* `vector.round(v)`: + * Returns a vector, each dimension rounded to nearest integer. + * At a multiple of 0.5, rounds away from zero. +* `vector.apply(v, func)`: + * Returns a vector where the function `func` has been applied to each + component. +* `vector.combine(v, w, func)`: + * Returns a vector where the function `func` has combined both components of `v` and `w` + for each component +* `vector.equals(v1, v2)`: + * Returns a boolean, `true` if the vectors are identical. +* `vector.sort(v1, v2)`: + * Returns in order minp, maxp vectors of the cuboid defined by `v1`, `v2`. +* `vector.angle(v1, v2)`: + * Returns the angle between `v1` and `v2` in radians. +* `vector.dot(v1, v2)`: + * Returns the dot product of `v1` and `v2`. +* `vector.cross(v1, v2)`: + * Returns the cross product of `v1` and `v2`. +* `vector.offset(v, x, y, z)`: + * Returns the sum of the vectors `v` and `(x, y, z)`. +* `vector.check(v)`: + * Returns a boolean value indicating whether `v` is a real vector, eg. created + by a `vector.*` function. + * Returns `false` for anything else, including tables like `{x=3,y=1,z=4}`. + +For the following functions `x` can be either a vector or a number: + +* `vector.add(v, x)`: + * Returns a vector. + * If `x` is a vector: Returns the sum of `v` and `x`. + * If `x` is a number: Adds `x` to each component of `v`. +* `vector.subtract(v, x)`: + * Returns a vector. + * If `x` is a vector: Returns the difference of `v` subtracted by `x`. + * If `x` is a number: Subtracts `x` from each component of `v`. +* `vector.multiply(v, s)`: + * Returns a scaled vector. + * Deprecated: If `s` is a vector: Returns the Schur product. +* `vector.divide(v, s)`: + * Returns a scaled vector. + * Deprecated: If `s` is a vector: Returns the Schur quotient. + +Operators +--------- + +Operators can be used if all of the involved vectors have metatables: +* `v1 == v2`: + * Returns whether `v1` and `v2` are identical. +* `-v`: + * Returns the additive inverse of v. +* `v1 + v2`: + * Returns the sum of both vectors. + * Note: `+` can not be used together with scalars. +* `v1 - v2`: + * Returns the difference of `v1` subtracted by `v2`. + * Note: `-` can not be used together with scalars. +* `v * s` or `s * v`: + * Returns `v` scaled by `s`. +* `v / s`: + * Returns `v` scaled by `1 / s`. + +Rotation-related functions +-------------------------- + +For the following functions `a` is an angle in radians and `r` is a rotation +vector (`{x = <pitch>, y = <yaw>, z = <roll>}`) where pitch, yaw and roll are +angles in radians. + +* `vector.rotate(v, r)`: + * Applies the rotation `r` to `v` and returns the result. + * `vector.rotate(vector.new(0, 0, 1), r)` and + `vector.rotate(vector.new(0, 1, 0), r)` return vectors pointing + forward and up relative to an entity's rotation `r`. +* `vector.rotate_around_axis(v1, v2, a)`: + * Returns `v1` rotated around axis `v2` by `a` radians according to + the right hand rule. +* `vector.dir_to_rotation(direction[, up])`: + * Returns a rotation vector for `direction` pointing forward using `up` + as the up vector. + * If `up` is omitted, the roll of the returned vector defaults to zero. + * Otherwise `direction` and `up` need to be vectors in a 90 degree angle to each other. + +Further helpers +--------------- + +There are more helper functions involving vectors, but they are listed elsewhere +because they only work on specific sorts of vectors or involve things that are not +vectors. + +For example: + +* `minetest.hash_node_position` (Only works on node positions.) +* `minetest.dir_to_wallmounted` (Involves wallmounted param2 values.) + + + + +Helper functions +================ + +* `dump2(obj, name, dumped)`: returns a string which makes `obj` + human-readable, handles reference loops. + * `obj`: arbitrary variable + * `name`: string, default: `"_"` + * `dumped`: table, default: `{}` +* `dump(obj, dumped)`: returns a string which makes `obj` human-readable + * `obj`: arbitrary variable + * `dumped`: table, default: `{}` +* `math.hypot(x, y)` + * Get the hypotenuse of a triangle with legs x and y. + Useful for distance calculation. +* `math.sign(x, tolerance)`: returns `-1`, `0` or `1` + * Get the sign of a number. + * tolerance: number, default: `0.0` + * If the absolute value of `x` is within the `tolerance` or `x` is NaN, + `0` is returned. +* `math.factorial(x)`: returns the factorial of `x` +* `math.round(x)`: Returns `x` rounded to the nearest integer. + * At a multiple of 0.5, rounds away from zero. +* `string.split(str, separator, include_empty, max_splits, sep_is_pattern)` + * `separator`: string, default: `","` + * `include_empty`: boolean, default: `false` + * `max_splits`: number, if it's negative, splits aren't limited, + default: `-1` + * `sep_is_pattern`: boolean, it specifies whether separator is a plain + string or a pattern (regex), default: `false` + * e.g. `"a,b":split","` returns `{"a","b"}` +* `string:trim()`: returns the string without whitespace pre- and suffixes + * e.g. `"\n \t\tfoo bar\t ":trim()` returns `"foo bar"` +* `minetest.wrap_text(str, limit, as_table)`: returns a string or table + * Adds newlines to the string to keep it within the specified character + limit + * Note that the returned lines may be longer than the limit since it only + splits at word borders. + * `limit`: number, maximal amount of characters in one line + * `as_table`: boolean, if set to true, a table of lines instead of a string + is returned, default: `false` +* `minetest.pos_to_string(pos, decimal_places)`: returns string `"(X,Y,Z)"` + * `pos`: table {x=X, y=Y, z=Z} + * Converts the position `pos` to a human-readable, printable string + * `decimal_places`: number, if specified, the x, y and z values of + the position are rounded to the given decimal place. +* `minetest.string_to_pos(string)`: returns a position or `nil` + * Same but in reverse. + * If the string can't be parsed to a position, nothing is returned. +* `minetest.string_to_area("(X1, Y1, Z1) (X2, Y2, Z2)", relative_to)`: + * returns two positions + * Converts a string representing an area box into two positions + * X1, Y1, ... Z2 are coordinates + * `relative_to`: Optional. If set to a position, each coordinate + can use the tilde notation for relative positions + * Tilde notation: "~": Relative coordinate + "~<number>": Relative coordinate plus <number> + * Example: `minetest.string_to_area("(1,2,3) (~5,~-5,~)", {x=10,y=10,z=10})` + returns `{x=1,y=2,z=3}, {x=15,y=5,z=10}` +* `minetest.formspec_escape(string)`: returns a string + * escapes the characters "[", "]", "\", "," and ";", which can not be used + in formspecs. +* `minetest.is_yes(arg)` + * returns true if passed 'y', 'yes', 'true' or a number that isn't zero. +* `minetest.is_nan(arg)` + * returns true when the passed number represents NaN. +* `minetest.get_us_time()` + * returns time with microsecond precision. May not return wall time. +* `table.copy(table)`: returns a table + * returns a deep copy of `table` +* `table.indexof(list, val)`: returns the smallest numerical index containing + the value `val` in the table `list`. Non-numerical indices are ignored. + If `val` could not be found, `-1` is returned. `list` must not have + negative indices. +* `table.insert_all(table, other_table)`: + * Appends all values in `other_table` to `table` - uses `#table + 1` to + find new indices. +* `table.key_value_swap(t)`: returns a table with keys and values swapped + * If multiple keys in `t` map to the same value, it is unspecified which + value maps to that key. +* `table.shuffle(table, [from], [to], [random_func])`: + * Shuffles elements `from` to `to` in `table` in place + * `from` defaults to `1` + * `to` defaults to `#table` + * `random_func` defaults to `math.random`. This function receives two + integers as arguments and should return a random integer inclusively + between them. +* `minetest.pointed_thing_to_face_pos(placer, pointed_thing)`: returns a + position. + * returns the exact position on the surface of a pointed node +* `minetest.get_tool_wear_after_use(uses [, initial_wear])` + * Simulates a tool being used once and returns the added wear, + such that, if only this function is used to calculate wear, + the tool will break exactly after `uses` times of uses + * `uses`: Number of times the tool can be used + * `initial_wear`: The initial wear the tool starts with (default: 0) +* `minetest.get_dig_params(groups, tool_capabilities [, wear])`: + Simulates an item that digs a node. + Returns a table with the following fields: + * `diggable`: `true` if node can be dug, `false` otherwise. + * `time`: Time it would take to dig the node. + * `wear`: How much wear would be added to the tool (ignored for non-tools). + `time` and `wear` are meaningless if node's not diggable + Parameters: + * `groups`: Table of the node groups of the node that would be dug + * `tool_capabilities`: Tool capabilities table of the item + * `wear`: Amount of wear the tool starts with (default: 0) +* `minetest.get_hit_params(groups, tool_capabilities [, time_from_last_punch [, wear]])`: + Simulates an item that punches an object. + Returns a table with the following fields: + * `hp`: How much damage the punch would cause (between -65535 and 65535). + * `wear`: How much wear would be added to the tool (ignored for non-tools). + Parameters: + * `groups`: Damage groups of the object + * `tool_capabilities`: Tool capabilities table of the item + * `time_from_last_punch`: time in seconds since last punch action + * `wear`: Amount of wear the item starts with (default: 0) + + + + +Translations +============ + +Texts can be translated client-side with the help of `minetest.translate` and +translation files. + +Consider using the tool [update_translations](https://github.com/minetest-tools/update_translations) +to generate and update translation files automatically from the Lua source. + +Translating a string +-------------------- + +Two functions are provided to translate strings: `minetest.translate` and +`minetest.get_translator`. + +* `minetest.get_translator(textdomain)` is a simple wrapper around + `minetest.translate`, and `minetest.get_translator(textdomain)(str, ...)` is + equivalent to `minetest.translate(textdomain, str, ...)`. + It is intended to be used in the following way, so that it avoids verbose + repetitions of `minetest.translate`: + + local S = minetest.get_translator(textdomain) + S(str, ...) + + As an extra commodity, if `textdomain` is nil, it is assumed to be "" instead. + +* `minetest.translate(textdomain, str, ...)` translates the string `str` with + the given `textdomain` for disambiguation. The textdomain must match the + textdomain specified in the translation file in order to get the string + translated. This can be used so that a string is translated differently in + different contexts. + It is advised to use the name of the mod as textdomain whenever possible, to + avoid clashes with other mods. + This function must be given a number of arguments equal to the number of + arguments the translated string expects. + Arguments are literal strings -- they will not be translated, so if you want + them to be, they need to come as outputs of `minetest.translate` as well. + + For instance, suppose we want to translate "@1 Wool" with "@1" being replaced + by the translation of "Red". We can do the following: + + local S = minetest.get_translator() + S("@1 Wool", S("Red")) + + This will be displayed as "Red Wool" on old clients and on clients that do + not have localization enabled. However, if we have for instance a translation + file named `wool.fr.tr` containing the following: + + @1 Wool=Laine @1 + Red=Rouge + + this will be displayed as "Laine Rouge" on clients with a French locale. + +Operations on translated strings +-------------------------------- + +The output of `minetest.translate` is a string, with escape sequences adding +additional information to that string so that it can be translated on the +different clients. In particular, you can't expect operations like string.length +to work on them like you would expect them to, or string.gsub to work in the +expected manner. However, string concatenation will still work as expected +(note that you should only use this for things like formspecs; do not translate +sentences by breaking them into parts; arguments should be used instead), and +operations such as `minetest.colorize` which are also concatenation. + +Translation file format +----------------------- + +A translation file has the suffix `.[lang].tr`, where `[lang]` is the language +it corresponds to. It must be put into the `locale` subdirectory of the mod. +The file should be a text file, with the following format: + +* Lines beginning with `# textdomain:` (the space is significant) can be used + to specify the text domain of all following translations in the file. +* All other empty lines or lines beginning with `#` are ignored. +* Other lines should be in the format `original=translated`. Both `original` + and `translated` can contain escape sequences beginning with `@` to insert + arguments, literal `@`, `=` or newline (See [Escapes] below). + There must be no extraneous whitespace around the `=` or at the beginning or + the end of the line. + +Escapes +------- + +Strings that need to be translated can contain several escapes, preceded by `@`. + +* `@@` acts as a literal `@`. +* `@n`, where `n` is a digit between 1 and 9, is an argument for the translated + string that will be inlined when translated. Due to how translations are + implemented, the original translation string **must** have its arguments in + increasing order, without gaps or repetitions, starting from 1. +* `@=` acts as a literal `=`. It is not required in strings given to + `minetest.translate`, but is in translation files to avoid being confused + with the `=` separating the original from the translation. +* `@\n` (where the `\n` is a literal newline) acts as a literal newline. + As with `@=`, this escape is not required in strings given to + `minetest.translate`, but is in translation files. +* `@n` acts as a literal newline as well. + +Server side translations +------------------------ + +On some specific cases, server translation could be useful. For example, filter +a list on labels and send results to client. A method is supplied to achieve +that: + +`minetest.get_translated_string(lang_code, string)`: Translates `string` using +translations for `lang_code` language. It gives the same result as if the string +was translated by the client. + +The `lang_code` to use for a given player can be retrieved from +the table returned by `minetest.get_player_information(name)`. + +IMPORTANT: This functionality should only be used for sorting, filtering or similar purposes. +You do not need to use this to get translated strings to show up on the client. + +Perlin noise +============ + +Perlin noise creates a continuously-varying value depending on the input values. +Usually in Minetest the input values are either 2D or 3D co-ordinates in nodes. +The result is used during map generation to create the terrain shape, vary heat +and humidity to distribute biomes, vary the density of decorations or vary the +structure of ores. + +Structure of perlin noise +------------------------- + +An 'octave' is a simple noise generator that outputs a value between -1 and 1. +The smooth wavy noise it generates has a single characteristic scale, almost +like a 'wavelength', so on its own does not create fine detail. +Due to this perlin noise combines several octaves to create variation on +multiple scales. Each additional octave has a smaller 'wavelength' than the +previous. + +This combination results in noise varying very roughly between -2.0 and 2.0 and +with an average value of 0.0, so `scale` and `offset` are then used to multiply +and offset the noise variation. + +The final perlin noise variation is created as follows: + +noise = offset + scale * (octave1 + + octave2 * persistence + + octave3 * persistence ^ 2 + + octave4 * persistence ^ 3 + + ...) + +Noise Parameters +---------------- + +Noise Parameters are commonly called `NoiseParams`. + +### `offset` + +After the multiplication by `scale` this is added to the result and is the final +step in creating the noise value. +Can be positive or negative. + +### `scale` + +Once all octaves have been combined, the result is multiplied by this. +Can be positive or negative. + +### `spread` + +For octave1, this is roughly the change of input value needed for a very large +variation in the noise value generated by octave1. It is almost like a +'wavelength' for the wavy noise variation. +Each additional octave has a 'wavelength' that is smaller than the previous +octave, to create finer detail. `spread` will therefore roughly be the typical +size of the largest structures in the final noise variation. + +`spread` is a vector with values for x, y, z to allow the noise variation to be +stretched or compressed in the desired axes. +Values are positive numbers. + +### `seed` + +This is a whole number that determines the entire pattern of the noise +variation. Altering it enables different noise patterns to be created. +With other parameters equal, different seeds produce different noise patterns +and identical seeds produce identical noise patterns. + +For this parameter you can randomly choose any whole number. Usually it is +preferable for this to be different from other seeds, but sometimes it is useful +to be able to create identical noise patterns. + +In some noise APIs the world seed is added to the seed specified in noise +parameters. This is done to make the resulting noise pattern vary in different +worlds, and be 'world-specific'. + +### `octaves` + +The number of simple noise generators that are combined. +A whole number, 1 or more. +Each additional octave adds finer detail to the noise but also increases the +noise calculation load. +3 is a typical minimum for a high quality, complex and natural-looking noise +variation. 1 octave has a slight 'gridlike' appearance. + +Choose the number of octaves according to the `spread` and `lacunarity`, and the +size of the finest detail you require. For example: +if `spread` is 512 nodes, `lacunarity` is 2.0 and finest detail required is 16 +nodes, octaves will be 6 because the 'wavelengths' of the octaves will be +512, 256, 128, 64, 32, 16 nodes. +Warning: If the 'wavelength' of any octave falls below 1 an error will occur. + +### `persistence` + +Each additional octave has an amplitude that is the amplitude of the previous +octave multiplied by `persistence`, to reduce the amplitude of finer details, +as is often helpful and natural to do so. +Since this controls the balance of fine detail to large-scale detail +`persistence` can be thought of as the 'roughness' of the noise. + +A positive or negative non-zero number, often between 0.3 and 1.0. +A common medium value is 0.5, such that each octave has half the amplitude of +the previous octave. +This may need to be tuned when altering `lacunarity`; when doing so consider +that a common medium value is 1 / lacunarity. + +### `lacunarity` + +Each additional octave has a 'wavelength' that is the 'wavelength' of the +previous octave multiplied by 1 / lacunarity, to create finer detail. +'lacunarity' is often 2.0 so 'wavelength' often halves per octave. + +A positive number no smaller than 1.0. +Values below 2.0 create higher quality noise at the expense of requiring more +octaves to cover a paticular range of 'wavelengths'. + +### `flags` + +Leave this field unset for no special handling. +Currently supported are `defaults`, `eased` and `absvalue`: + +#### `defaults` + +Specify this if you would like to keep auto-selection of eased/not-eased while +specifying some other flags. + +#### `eased` + +Maps noise gradient values onto a quintic S-curve before performing +interpolation. This results in smooth, rolling noise. +Disable this (`noeased`) for sharp-looking noise with a slightly gridded +appearence. +If no flags are specified (or defaults is), 2D noise is eased and 3D noise is +not eased. +Easing a 3D noise significantly increases the noise calculation load, so use +with restraint. + +#### `absvalue` + +The absolute value of each octave's noise variation is used when combining the +octaves. The final perlin noise variation is created as follows: + +noise = offset + scale * (abs(octave1) + + abs(octave2) * persistence + + abs(octave3) * persistence ^ 2 + + abs(octave4) * persistence ^ 3 + + ...) + +### Format example + +For 2D or 3D perlin noise or perlin noise maps: + + np_terrain = { + offset = 0, + scale = 1, + spread = {x = 500, y = 500, z = 500}, + seed = 571347, + octaves = 5, + persistence = 0.63, + lacunarity = 2.0, + flags = "defaults, absvalue", + } + +For 2D noise the Z component of `spread` is still defined but is ignored. +A single noise parameter table can be used for 2D or 3D noise. + + + + +Ores +==== + +Ore types +--------- + +These tell in what manner the ore is generated. + +All default ores are of the uniformly-distributed scatter type. + +### `scatter` + +Randomly chooses a location and generates a cluster of ore. + +If `noise_params` is specified, the ore will be placed if the 3D perlin noise +at that point is greater than the `noise_threshold`, giving the ability to +create a non-equal distribution of ore. + +### `sheet` + +Creates a sheet of ore in a blob shape according to the 2D perlin noise +described by `noise_params` and `noise_threshold`. This is essentially an +improved version of the so-called "stratus" ore seen in some unofficial mods. + +This sheet consists of vertical columns of uniform randomly distributed height, +varying between the inclusive range `column_height_min` and `column_height_max`. +If `column_height_min` is not specified, this parameter defaults to 1. +If `column_height_max` is not specified, this parameter defaults to `clust_size` +for reverse compatibility. New code should prefer `column_height_max`. + +The `column_midpoint_factor` parameter controls the position of the column at +which ore emanates from. +If 1, columns grow upward. If 0, columns grow downward. If 0.5, columns grow +equally starting from each direction. +`column_midpoint_factor` is a decimal number ranging in value from 0 to 1. If +this parameter is not specified, the default is 0.5. + +The ore parameters `clust_scarcity` and `clust_num_ores` are ignored for this +ore type. + +### `puff` + +Creates a sheet of ore in a cloud-like puff shape. + +As with the `sheet` ore type, the size and shape of puffs are described by +`noise_params` and `noise_threshold` and are placed at random vertical +positions within the currently generated chunk. + +The vertical top and bottom displacement of each puff are determined by the +noise parameters `np_puff_top` and `np_puff_bottom`, respectively. + +### `blob` + +Creates a deformed sphere of ore according to 3d perlin noise described by +`noise_params`. The maximum size of the blob is `clust_size`, and +`clust_scarcity` has the same meaning as with the `scatter` type. + +### `vein` + +Creates veins of ore varying in density by according to the intersection of two +instances of 3d perlin noise with different seeds, both described by +`noise_params`. + +`random_factor` varies the influence random chance has on placement of an ore +inside the vein, which is `1` by default. Note that modifying this parameter +may require adjusting `noise_threshold`. + +The parameters `clust_scarcity`, `clust_num_ores`, and `clust_size` are ignored +by this ore type. + +This ore type is difficult to control since it is sensitive to small changes. +The following is a decent set of parameters to work from: + + noise_params = { + offset = 0, + scale = 3, + spread = {x=200, y=200, z=200}, + seed = 5390, + octaves = 4, + persistence = 0.5, + lacunarity = 2.0, + flags = "eased", + }, + noise_threshold = 1.6 + +**WARNING**: Use this ore type *very* sparingly since it is ~200x more +computationally expensive than any other ore. + +### `stratum` + +Creates a single undulating ore stratum that is continuous across mapchunk +borders and horizontally spans the world. + +The 2D perlin noise described by `noise_params` defines the Y co-ordinate of +the stratum midpoint. The 2D perlin noise described by `np_stratum_thickness` +defines the stratum's vertical thickness (in units of nodes). Due to being +continuous across mapchunk borders the stratum's vertical thickness is +unlimited. + +If the noise parameter `noise_params` is omitted the ore will occur from y_min +to y_max in a simple horizontal stratum. + +A parameter `stratum_thickness` can be provided instead of the noise parameter +`np_stratum_thickness`, to create a constant thickness. + +Leaving out one or both noise parameters makes the ore generation less +intensive, useful when adding multiple strata. + +`y_min` and `y_max` define the limits of the ore generation and for performance +reasons should be set as close together as possible but without clipping the +stratum's Y variation. + +Each node in the stratum has a 1-in-`clust_scarcity` chance of being ore, so a +solid-ore stratum would require a `clust_scarcity` of 1. + +The parameters `clust_num_ores`, `clust_size`, `noise_threshold` and +`random_factor` are ignored by this ore type. + +Ore attributes +-------------- + +See section [Flag Specifier Format]. + +Currently supported flags: +`puff_cliffs`, `puff_additive_composition`. + +### `puff_cliffs` + +If set, puff ore generation will not taper down large differences in +displacement when approaching the edge of a puff. This flag has no effect for +ore types other than `puff`. + +### `puff_additive_composition` + +By default, when noise described by `np_puff_top` or `np_puff_bottom` results +in a negative displacement, the sub-column at that point is not generated. With +this attribute set, puff ore generation will instead generate the absolute +difference in noise displacement values. This flag has no effect for ore types +other than `puff`. + + + + +Decoration types +================ + +The varying types of decorations that can be placed. + +`simple` +-------- + +Creates a 1 times `H` times 1 column of a specified node (or a random node from +a list, if a decoration list is specified). Can specify a certain node it must +spawn next to, such as water or lava, for example. Can also generate a +decoration of random height between a specified lower and upper bound. +This type of decoration is intended for placement of grass, flowers, cacti, +papyri, waterlilies and so on. + +`schematic` +----------- + +Copies a box of `MapNodes` from a specified schematic file (or raw description). +Can specify a probability of a node randomly appearing when placed. +This decoration type is intended to be used for multi-node sized discrete +structures, such as trees, cave spikes, rocks, and so on. + + + + +Schematics +========== + +Schematic specifier +-------------------- + +A schematic specifier identifies a schematic by either a filename to a +Minetest Schematic file (`.mts`) or through raw data supplied through Lua, +in the form of a table. This table specifies the following fields: + +* The `size` field is a 3D vector containing the dimensions of the provided + schematic. (required field) +* The `yslice_prob` field is a table of {ypos, prob} slice tables. A slice table + sets the probability of a particular horizontal slice of the schematic being + placed. (optional field) + `ypos` = 0 for the lowest horizontal slice of a schematic. + The default of `prob` is 255. +* The `data` field is a flat table of MapNode tables making up the schematic, + in the order of `[z [y [x]]]`. (required field) + Each MapNode table contains: + * `name`: the name of the map node to place (required) + * `prob` (alias `param1`): the probability of this node being placed + (default: 255) + * `param2`: the raw param2 value of the node being placed onto the map + (default: 0) + * `force_place`: boolean representing if the node should forcibly overwrite + any previous contents (default: false) + +About probability values: + +* A probability value of `0` or `1` means that node will never appear + (0% chance). +* A probability value of `254` or `255` means the node will always appear + (100% chance). +* If the probability value `p` is greater than `1`, then there is a + `(p / 256 * 100)` percent chance that node will appear when the schematic is + placed on the map. + +Schematic attributes +-------------------- + +See section [Flag Specifier Format]. + +Currently supported flags: `place_center_x`, `place_center_y`, `place_center_z`, + `force_placement`. + +* `place_center_x`: Placement of this decoration is centered along the X axis. +* `place_center_y`: Placement of this decoration is centered along the Y axis. +* `place_center_z`: Placement of this decoration is centered along the Z axis. +* `force_placement`: Schematic nodes other than "ignore" will replace existing + nodes. + + + + +Lua Voxel Manipulator +===================== + +About VoxelManip +---------------- + +VoxelManip is a scripting interface to the internal 'Map Voxel Manipulator' +facility. The purpose of this object is for fast, low-level, bulk access to +reading and writing Map content. As such, setting map nodes through VoxelManip +will lack many of the higher level features and concepts you may be used to +with other methods of setting nodes. For example, nodes will not have their +construction and destruction callbacks run, and no rollback information is +logged. + +It is important to note that VoxelManip is designed for speed, and *not* ease +of use or flexibility. If your mod requires a map manipulation facility that +will handle 100% of all edge cases, or the use of high level node placement +features, perhaps `minetest.set_node()` is better suited for the job. + +In addition, VoxelManip might not be faster, or could even be slower, for your +specific use case. VoxelManip is most effective when setting large areas of map +at once - for example, if only setting a 3x3x3 node area, a +`minetest.set_node()` loop may be more optimal. Always profile code using both +methods of map manipulation to determine which is most appropriate for your +usage. + +A recent simple test of setting cubic areas showed that `minetest.set_node()` +is faster than a VoxelManip for a 3x3x3 node cube or smaller. + +Using VoxelManip +---------------- + +A VoxelManip object can be created any time using either: +`VoxelManip([p1, p2])`, or `minetest.get_voxel_manip([p1, p2])`. + +If the optional position parameters are present for either of these routines, +the specified region will be pre-loaded into the VoxelManip object on creation. +Otherwise, the area of map you wish to manipulate must first be loaded into the +VoxelManip object using `VoxelManip:read_from_map()`. + +Note that `VoxelManip:read_from_map()` returns two position vectors. The region +formed by these positions indicate the minimum and maximum (respectively) +positions of the area actually loaded in the VoxelManip, which may be larger +than the area requested. For convenience, the loaded area coordinates can also +be queried any time after loading map data with `VoxelManip:get_emerged_area()`. + +Now that the VoxelManip object is populated with map data, your mod can fetch a +copy of this data using either of two methods. `VoxelManip:get_node_at()`, +which retrieves an individual node in a MapNode formatted table at the position +requested is the simplest method to use, but also the slowest. + +Nodes in a VoxelManip object may also be read in bulk to a flat array table +using: + +* `VoxelManip:get_data()` for node content (in Content ID form, see section + [Content IDs]), +* `VoxelManip:get_light_data()` for node light levels, and +* `VoxelManip:get_param2_data()` for the node type-dependent "param2" values. + +See section [Flat array format] for more details. + +It is very important to understand that the tables returned by any of the above +three functions represent a snapshot of the VoxelManip's internal state at the +time of the call. This copy of the data will not magically update itself if +another function modifies the internal VoxelManip state. +Any functions that modify a VoxelManip's contents work on the VoxelManip's +internal state unless otherwise explicitly stated. + +Once the bulk data has been edited to your liking, the internal VoxelManip +state can be set using: + +* `VoxelManip:set_data()` for node content (in Content ID form, see section + [Content IDs]), +* `VoxelManip:set_light_data()` for node light levels, and +* `VoxelManip:set_param2_data()` for the node type-dependent `param2` values. + +The parameter to each of the above three functions can use any table at all in +the same flat array format as produced by `get_data()` etc. and is not required +to be a table retrieved from `get_data()`. + +Once the internal VoxelManip state has been modified to your liking, the +changes can be committed back to the map by calling `VoxelManip:write_to_map()` + +### Flat array format + +Let + `Nx = p2.X - p1.X + 1`, + `Ny = p2.Y - p1.Y + 1`, and + `Nz = p2.Z - p1.Z + 1`. + +Then, for a loaded region of p1..p2, this array ranges from `1` up to and +including the value of the expression `Nx * Ny * Nz`. + +Positions offset from p1 are present in the array with the format of: + + [ + (0, 0, 0), (1, 0, 0), (2, 0, 0), ... (Nx, 0, 0), + (0, 1, 0), (1, 1, 0), (2, 1, 0), ... (Nx, 1, 0), + ... + (0, Ny, 0), (1, Ny, 0), (2, Ny, 0), ... (Nx, Ny, 0), + (0, 0, 1), (1, 0, 1), (2, 0, 1), ... (Nx, 0, 1), + ... + (0, Ny, 2), (1, Ny, 2), (2, Ny, 2), ... (Nx, Ny, 2), + ... + (0, Ny, Nz), (1, Ny, Nz), (2, Ny, Nz), ... (Nx, Ny, Nz) + ] + +and the array index for a position p contained completely in p1..p2 is: + +`(p.Z - p1.Z) * Ny * Nx + (p.Y - p1.Y) * Nx + (p.X - p1.X) + 1` + +Note that this is the same "flat 3D array" format as +`PerlinNoiseMap:get3dMap_flat()`. +VoxelArea objects (see section [`VoxelArea`]) can be used to simplify calculation +of the index for a single point in a flat VoxelManip array. + +### Content IDs + +A Content ID is a unique integer identifier for a specific node type. +These IDs are used by VoxelManip in place of the node name string for +`VoxelManip:get_data()` and `VoxelManip:set_data()`. You can use +`minetest.get_content_id()` to look up the Content ID for the specified node +name, and `minetest.get_name_from_content_id()` to look up the node name string +for a given Content ID. +After registration of a node, its Content ID will remain the same throughout +execution of the mod. +Note that the node being queried needs to have already been been registered. + +The following builtin node types have their Content IDs defined as constants: + +* `minetest.CONTENT_UNKNOWN`: ID for "unknown" nodes +* `minetest.CONTENT_AIR`: ID for "air" nodes +* `minetest.CONTENT_IGNORE`: ID for "ignore" nodes + +### Mapgen VoxelManip objects + +Inside of `on_generated()` callbacks, it is possible to retrieve the same +VoxelManip object used by the core's Map Generator (commonly abbreviated +Mapgen). Most of the rules previously described still apply but with a few +differences: + +* The Mapgen VoxelManip object is retrieved using: + `minetest.get_mapgen_object("voxelmanip")` +* This VoxelManip object already has the region of map just generated loaded + into it; it's not necessary to call `VoxelManip:read_from_map()`. + Note that the region of map it has loaded is NOT THE SAME as the `minp`, `maxp` + parameters of `on_generated()`. Refer to `minetest.get_mapgen_object` docs. +* The `on_generated()` callbacks of some mods may place individual nodes in the + generated area using non-VoxelManip map modification methods. Because the + same Mapgen VoxelManip object is passed through each `on_generated()` + callback, it becomes necessary for the Mapgen VoxelManip object to maintain + consistency with the current map state. For this reason, calling any of + `minetest.add_node()`, `minetest.set_node()` or `minetest.swap_node()` + will also update the Mapgen VoxelManip object's internal state active on the + current thread. +* After modifying the Mapgen VoxelManip object's internal buffer, it may be + necessary to update lighting information using either: + `VoxelManip:calc_lighting()` or `VoxelManip:set_lighting()`. + +### Other API functions operating on a VoxelManip + +If any VoxelManip contents were set to a liquid node (`liquidtype ~= "none"`), +`VoxelManip:update_liquids()` must be called for these liquid nodes to begin +flowing. It is recommended to call this function only after having written all +buffered data back to the VoxelManip object, save for special situations where +the modder desires to only have certain liquid nodes begin flowing. + +The functions `minetest.generate_ores()` and `minetest.generate_decorations()` +will generate all registered decorations and ores throughout the full area +inside of the specified VoxelManip object. + +`minetest.place_schematic_on_vmanip()` is otherwise identical to +`minetest.place_schematic()`, except instead of placing the specified schematic +directly on the map at the specified position, it will place the schematic +inside the VoxelManip. + +### Notes + +* Attempting to read data from a VoxelManip object before map is read will + result in a zero-length array table for `VoxelManip:get_data()`, and an + "ignore" node at any position for `VoxelManip:get_node_at()`. +* If either a region of map has not yet been generated or is out-of-bounds of + the map, that region is filled with "ignore" nodes. +* Other mods, or the core itself, could possibly modify the area of map + currently loaded into a VoxelManip object. With the exception of Mapgen + VoxelManips (see above section), the internal buffers are not updated. For + this reason, it is strongly encouraged to complete the usage of a particular + VoxelManip object in the same callback it had been created. +* If a VoxelManip object will be used often, such as in an `on_generated()` + callback, consider passing a file-scoped table as the optional parameter to + `VoxelManip:get_data()`, which serves as a static buffer the function can use + to write map data to instead of returning a new table each call. This greatly + enhances performance by avoiding unnecessary memory allocations. + +Methods +------- + +* `read_from_map(p1, p2)`: Loads a chunk of map into the VoxelManip object + containing the region formed by `p1` and `p2`. + * returns actual emerged `pmin`, actual emerged `pmax` +* `write_to_map([light])`: Writes the data loaded from the `VoxelManip` back to + the map. + * **important**: data must be set using `VoxelManip:set_data()` before + calling this. + * if `light` is true, then lighting is automatically recalculated. + The default value is true. + If `light` is false, no light calculations happen, and you should correct + all modified blocks with `minetest.fix_light()` as soon as possible. + Keep in mind that modifying the map where light is incorrect can cause + more lighting bugs. +* `get_node_at(pos)`: Returns a `MapNode` table of the node currently loaded in + the `VoxelManip` at that position +* `set_node_at(pos, node)`: Sets a specific `MapNode` in the `VoxelManip` at + that position. +* `get_data([buffer])`: Retrieves the node content data loaded into the + `VoxelManip` object. + * returns raw node data in the form of an array of node content IDs + * if the param `buffer` is present, this table will be used to store the + result instead. +* `set_data(data)`: Sets the data contents of the `VoxelManip` object +* `update_map()`: Does nothing, kept for compatibility. +* `set_lighting(light, [p1, p2])`: Set the lighting within the `VoxelManip` to + a uniform value. + * `light` is a table, `{day=<0...15>, night=<0...15>}` + * To be used only by a `VoxelManip` object from + `minetest.get_mapgen_object`. + * (`p1`, `p2`) is the area in which lighting is set, defaults to the whole + area if left out. +* `get_light_data()`: Gets the light data read into the `VoxelManip` object + * Returns an array (indices 1 to volume) of integers ranging from `0` to + `255`. + * Each value is the bitwise combination of day and night light values + (`0` to `15` each). + * `light = day + (night * 16)` +* `set_light_data(light_data)`: Sets the `param1` (light) contents of each node + in the `VoxelManip`. + * expects lighting data in the same format that `get_light_data()` returns +* `get_param2_data([buffer])`: Gets the raw `param2` data read into the + `VoxelManip` object. + * Returns an array (indices 1 to volume) of integers ranging from `0` to + `255`. + * If the param `buffer` is present, this table will be used to store the + result instead. +* `set_param2_data(param2_data)`: Sets the `param2` contents of each node in + the `VoxelManip`. +* `calc_lighting([p1, p2], [propagate_shadow])`: Calculate lighting within the + `VoxelManip`. + * To be used only by a `VoxelManip` object from + `minetest.get_mapgen_object`. + * (`p1`, `p2`) is the area in which lighting is set, defaults to the whole + area if left out or nil. For almost all uses these should be left out + or nil to use the default. + * `propagate_shadow` is an optional boolean deciding whether shadows in a + generated mapchunk above are propagated down into the mapchunk, defaults + to `true` if left out. +* `update_liquids()`: Update liquid flow +* `was_modified()`: Returns `true` or `false` if the data in the voxel + manipulator had been modified since the last read from map, due to a call to + `minetest.set_data()` on the loaded area elsewhere. +* `get_emerged_area()`: Returns actual emerged minimum and maximum positions. + +`VoxelArea` +----------- + +A helper class for voxel areas. +It can be created via `VoxelArea:new({MinEdge = pmin, MaxEdge = pmax})`. +The coordinates are *inclusive*, like most other things in Minetest. + +### Methods + +* `getExtent()`: returns a 3D vector containing the size of the area formed by + `MinEdge` and `MaxEdge`. +* `getVolume()`: returns the volume of the area formed by `MinEdge` and + `MaxEdge`. +* `index(x, y, z)`: returns the index of an absolute position in a flat array + starting at `1`. + * `x`, `y` and `z` must be integers to avoid an incorrect index result. + * The position (x, y, z) is not checked for being inside the area volume, + being outside can cause an incorrect index result. + * Useful for things like `VoxelManip`, raw Schematic specifiers, + `PerlinNoiseMap:get2d`/`3dMap`, and so on. +* `indexp(p)`: same functionality as `index(x, y, z)` but takes a vector. + * As with `index(x, y, z)`, the components of `p` must be integers, and `p` + is not checked for being inside the area volume. +* `position(i)`: returns the absolute position vector corresponding to index + `i`. +* `contains(x, y, z)`: check if (`x`,`y`,`z`) is inside area formed by + `MinEdge` and `MaxEdge`. +* `containsp(p)`: same as above, except takes a vector +* `containsi(i)`: same as above, except takes an index `i` +* `iter(minx, miny, minz, maxx, maxy, maxz)`: returns an iterator that returns + indices. + * from (`minx`,`miny`,`minz`) to (`maxx`,`maxy`,`maxz`) in the order of + `[z [y [x]]]`. +* `iterp(minp, maxp)`: same as above, except takes a vector + +### Y stride and z stride of a flat array + +For a particular position in a voxel area, whose flat array index is known, +it is often useful to know the index of a neighboring or nearby position. +The table below shows the changes of index required for 1 node movements along +the axes in a voxel area: + + Movement Change of index + +x +1 + -x -1 + +y +ystride + -y -ystride + +z +zstride + -z -zstride + +If, for example: + + local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) + +The values of `ystride` and `zstride` can be obtained using `area.ystride` and +`area.zstride`. + + + + +Mapgen objects +============== + +A mapgen object is a construct used in map generation. Mapgen objects can be +used by an `on_generate` callback to speed up operations by avoiding +unnecessary recalculations, these can be retrieved using the +`minetest.get_mapgen_object()` function. If the requested Mapgen object is +unavailable, or `get_mapgen_object()` was called outside of an `on_generate()` +callback, `nil` is returned. + +The following Mapgen objects are currently available: + +### `voxelmanip` + +This returns three values; the `VoxelManip` object to be used, minimum and +maximum emerged position, in that order. All mapgens support this object. + +### `heightmap` + +Returns an array containing the y coordinates of the ground levels of nodes in +the most recently generated chunk by the current mapgen. + +### `biomemap` + +Returns an array containing the biome IDs of nodes in the most recently +generated chunk by the current mapgen. + +### `heatmap` + +Returns an array containing the temperature values of nodes in the most +recently generated chunk by the current mapgen. + +### `humiditymap` + +Returns an array containing the humidity values of nodes in the most recently +generated chunk by the current mapgen. + +### `gennotify` + +Returns a table mapping requested generation notification types to arrays of +positions at which the corresponding generated structures are located within +the current chunk. To enable the capture of positions of interest to be recorded +call `minetest.set_gen_notify()` first. + +Possible fields of the returned table are: + +* `dungeon`: bottom center position of dungeon rooms +* `temple`: as above but for desert temples (mgv6 only) +* `cave_begin` +* `cave_end` +* `large_cave_begin` +* `large_cave_end` +* `decoration#id` (see below) + +Decorations have a key in the format of `"decoration#id"`, where `id` is the +numeric unique decoration ID as returned by `minetest.get_decoration_id()`. +For example, `decoration#123`. + +The returned positions are the ground surface 'place_on' nodes, +not the decorations themselves. A 'simple' type decoration is often 1 +node above the returned position and possibly displaced by 'place_offset_y'. + + +Registered entities +=================== + +Functions receive a "luaentity" table as `self`: + +* It has the member `name`, which is the registered name `("mod:thing")` +* It has the member `object`, which is an `ObjectRef` pointing to the object +* The original prototype is visible directly via a metatable + +Callbacks: + +* `on_activate(self, staticdata, dtime_s)` + * Called when the object is instantiated. + * `dtime_s` is the time passed since the object was unloaded, which can be + used for updating the entity state. +* `on_deactivate(self, removal)` + * Called when the object is about to get removed or unloaded. + * `removal`: boolean indicating whether the object is about to get removed. + Calling `object:remove()` on an active object will call this with `removal=true`. + The mapblock the entity resides in being unloaded will call this with `removal=false`. + * Note that this won't be called if the object hasn't been activated in the first place. + In particular, `minetest.clear_objects({mode = "full"})` won't call this, + whereas `minetest.clear_objects({mode = "quick"})` might call this. +* `on_step(self, dtime, moveresult)` + * Called on every server tick, after movement and collision processing. + * `dtime`: elapsed time since last call + * `moveresult`: table with collision info (only available if physical=true) +* `on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)` + * Called when somebody punches the object. + * Note that you probably want to handle most punches using the automatic + armor group system. + * `puncher`: an `ObjectRef` (can be `nil`) + * `time_from_last_punch`: Meant for disallowing spamming of clicks + (can be `nil`). + * `tool_capabilities`: capability table of used item (can be `nil`) + * `dir`: unit vector of direction of punch. Always defined. Points from the + puncher to the punched. + * `damage`: damage that will be done to entity. + * Can return `true` to prevent the default damage mechanism. +* `on_death(self, killer)` + * Called when the object dies. + * `killer`: an `ObjectRef` (can be `nil`) +* `on_rightclick(self, clicker)` + * Called when `clicker` pressed the 'place/use' key while pointing + to the object (not neccessarily an actual rightclick) + * `clicker`: an `ObjectRef` (may or may not be a player) +* `on_attach_child(self, child)` + * `child`: an `ObjectRef` of the child that attaches +* `on_detach_child(self, child)` + * `child`: an `ObjectRef` of the child that detaches +* `on_detach(self, parent)` + * `parent`: an `ObjectRef` (can be `nil`) from where it got detached + * This happens before the parent object is removed from the world +* `get_staticdata(self)` + * Should return a string that will be passed to `on_activate` when the + object is instantiated the next time. + +Collision info passed to `on_step` (`moveresult` argument): + + { + touching_ground = boolean, + -- Note that touching_ground is only true if the entity was moving and + -- collided with ground. + + collides = boolean, + standing_on_object = boolean, + + collisions = { + { + type = string, -- "node" or "object", + axis = string, -- "x", "y" or "z" + node_pos = vector, -- if type is "node" + object = ObjectRef, -- if type is "object" + old_velocity = vector, + new_velocity = vector, + }, + ... + } + -- `collisions` does not contain data of unloaded mapblock collisions + -- or when the velocity changes are negligibly small + } + + + +L-system trees +============== + +Tree definition +--------------- + + treedef={ + axiom, --string initial tree axiom + rules_a, --string rules set A + rules_b, --string rules set B + rules_c, --string rules set C + rules_d, --string rules set D + trunk, --string trunk node name + leaves, --string leaves node name + leaves2, --string secondary leaves node name + leaves2_chance,--num chance (0-100) to replace leaves with leaves2 + angle, --num angle in deg + iterations, --num max # of iterations, usually 2 -5 + random_level, --num factor to lower nr of iterations, usually 0 - 3 + trunk_type, --string single/double/crossed) type of trunk: 1 node, + -- 2x2 nodes or 3x3 in cross shape + thin_branches, --boolean true -> use thin (1 node) branches + fruit, --string fruit node name + fruit_chance, --num chance (0-100) to replace leaves with fruit node + seed, --num random seed, if no seed is provided, the engine + will create one. + } + +Key for special L-System symbols used in axioms +----------------------------------------------- + +* `G`: move forward one unit with the pen up +* `F`: move forward one unit with the pen down drawing trunks and branches +* `f`: move forward one unit with the pen down drawing leaves (100% chance) +* `T`: move forward one unit with the pen down drawing trunks only +* `R`: move forward one unit with the pen down placing fruit +* `A`: replace with rules set A +* `B`: replace with rules set B +* `C`: replace with rules set C +* `D`: replace with rules set D +* `a`: replace with rules set A, chance 90% +* `b`: replace with rules set B, chance 80% +* `c`: replace with rules set C, chance 70% +* `d`: replace with rules set D, chance 60% +* `+`: yaw the turtle right by `angle` parameter +* `-`: yaw the turtle left by `angle` parameter +* `&`: pitch the turtle down by `angle` parameter +* `^`: pitch the turtle up by `angle` parameter +* `/`: roll the turtle to the right by `angle` parameter +* `*`: roll the turtle to the left by `angle` parameter +* `[`: save in stack current state info +* `]`: recover from stack state info + +Example +------- + +Spawn a small apple tree: + + pos = {x=230,y=20,z=4} + apple_tree={ + axiom="FFFFFAFFBF", + rules_a="[&&&FFFFF&&FFFF][&&&++++FFFFF&&FFFF][&&&----FFFFF&&FFFF]", + rules_b="[&&&++FFFFF&&FFFF][&&&--FFFFF&&FFFF][&&&------FFFFF&&FFFF]", + trunk="default:tree", + leaves="default:leaves", + angle=30, + iterations=2, + random_level=0, + trunk_type="single", + thin_branches=true, + fruit_chance=10, + fruit="default:apple" + } + minetest.spawn_tree(pos,apple_tree) + + +Privileges +========== + +Privileges provide a means for server administrators to give certain players +access to special abilities in the engine, games or mods. +For example, game moderators may need to travel instantly to any place in the world, +this ability is implemented in `/teleport` command which requires `teleport` privilege. + +Registering privileges +---------------------- + +A mod can register a custom privilege using `minetest.register_privilege` function +to give server administrators fine-grained access control over mod functionality. + +For consistency and practical reasons, privileges should strictly increase the abilities of the user. +Do not register custom privileges that e.g. restrict the player from certain in-game actions. + +Checking privileges +------------------- + +A mod can call `minetest.check_player_privs` to test whether a player has privileges +to perform an operation. +Also, when registering a chat command with `minetest.register_chatcommand` a mod can +declare privileges that the command requires using the `privs` field of the command +definition. + +Managing player privileges +-------------------------- + +A mod can update player privileges using `minetest.set_player_privs` function. +Players holding the `privs` privilege can see and manage privileges for all +players on the server. + +A mod can subscribe to changes in player privileges using `minetest.register_on_priv_grant` +and `minetest.register_on_priv_revoke` functions. + +Built-in privileges +------------------- + +Minetest includes a set of built-in privileges that control capabilities +provided by the Minetest engine and can be used by mods: + + * Basic privileges are normally granted to all players: + * `shout`: can communicate using the in-game chat. + * `interact`: can modify the world by digging, building and interacting + with the nodes, entities and other players. Players without the `interact` + privilege can only travel and observe the world. + + * Advanced privileges allow bypassing certain aspects of the gameplay: + * `fast`: can use "fast mode" to move with maximum speed. + * `fly`: can use "fly mode" to move freely above the ground without falling. + * `noclip`: can use "noclip mode" to fly through solid nodes (e.g. walls). + * `teleport`: can use `/teleport` command to move to any point in the world. + * `creative`: can access creative inventory. + * `bring`: can teleport other players to oneself. + * `give`: can use `/give` and `/giveme` commands to give any item + in the game to oneself or others. + * `settime`: can use `/time` command to change current in-game time. + * `debug`: can enable wireframe rendering mode. + + * Security-related privileges: + * `privs`: can modify privileges of the players using `/grant[me]` and + `/revoke[me]` commands. + * `basic_privs`: can grant and revoke basic privileges as defined by + the `basic_privs` setting. + * `kick`: can kick other players from the server using `/kick` command. + * `ban`: can ban other players using `/ban` command. + * `password`: can use `/setpassword` and `/clearpassword` commands + to manage players' passwords. + * `protection_bypass`: can bypass node protection. Note that the engine does not act upon this privilege, + it is only an implementation suggestion for games. + + * Administrative privileges: + * `server`: can use `/fixlight`, `/deleteblocks` and `/deleteobjects` + commands. Can clear inventory of other players using `/clearinv` command. + * `rollback`: can use `/rollback_check` and `/rollback` commands. + +Related settings +---------------- + +Minetest includes the following settings to control behavior of privileges: + + * `default_privs`: defines privileges granted to new players. + * `basic_privs`: defines privileges that can be granted/revoked by players having + the `basic_privs` privilege. This can be used, for example, to give + limited moderation powers to selected users. + +'minetest' namespace reference +============================== + +Utilities +--------- + +* `minetest.get_current_modname()`: returns the currently loading mod's name, + when loading a mod. +* `minetest.get_modpath(modname)`: returns the directory path for a mod, + e.g. `"/home/user/.minetest/usermods/modname"`. + * Returns nil if the mod is not enabled or does not exist (not installed). + * Works regardless of whether the mod has been loaded yet. + * Useful for loading additional `.lua` modules or static data from a mod, + or checking if a mod is enabled. +* `minetest.get_modnames()`: returns a list of enabled mods, sorted alphabetically. + * Does not include disabled mods, even if they are installed. +* `minetest.get_worldpath()`: returns e.g. `"/home/user/.minetest/world"` + * Useful for storing custom data +* `minetest.is_singleplayer()` +* `minetest.features`: Table containing API feature flags + + { + glasslike_framed = true, -- 0.4.7 + nodebox_as_selectionbox = true, -- 0.4.7 + get_all_craft_recipes_works = true, -- 0.4.7 + -- The transparency channel of textures can optionally be used on + -- nodes (0.4.7) + use_texture_alpha = true, + -- Tree and grass ABMs are no longer done from C++ (0.4.8) + no_legacy_abms = true, + -- Texture grouping is possible using parentheses (0.4.11) + texture_names_parens = true, + -- Unique Area ID for AreaStore:insert_area (0.4.14) + area_store_custom_ids = true, + -- add_entity supports passing initial staticdata to on_activate + -- (0.4.16) + add_entity_with_staticdata = true, + -- Chat messages are no longer predicted (0.4.16) + no_chat_message_prediction = true, + -- The transparency channel of textures can optionally be used on + -- objects (ie: players and lua entities) (5.0.0) + object_use_texture_alpha = true, + -- Object selectionbox is settable independently from collisionbox + -- (5.0.0) + object_independent_selectionbox = true, + -- Specifies whether binary data can be uploaded or downloaded using + -- the HTTP API (5.1.0) + httpfetch_binary_data = true, + -- Whether formspec_version[<version>] may be used (5.1.0) + formspec_version_element = true, + -- Whether AreaStore's IDs are kept on save/load (5.1.0) + area_store_persistent_ids = true, + -- Whether minetest.find_path is functional (5.2.0) + pathfinder_works = true, + -- Whether Collision info is available to an objects' on_step (5.3.0) + object_step_has_moveresult = true, + -- Whether get_velocity() and add_velocity() can be used on players (5.4.0) + direct_velocity_on_players = true, + -- nodedef's use_texture_alpha accepts new string modes (5.4.0) + use_texture_alpha_string_modes = true, + -- degrotate param2 rotates in units of 1.5° instead of 2° + -- thus changing the range of values from 0-179 to 0-240 (5.5.0) + degrotate_240_steps = true, + -- ABM supports min_y and max_y fields in definition (5.5.0) + abm_min_max_y = true, + -- dynamic_add_media supports passing a table with options (5.5.0) + dynamic_add_media_table = true, + -- particlespawners support texpools and animation of properties, + -- particle textures support smooth fade and scale animations, and + -- sprite-sheet particle animations can by synced to the lifetime + -- of individual particles (5.6.0) + particlespawner_tweenable = true, + -- allows get_sky to return a table instead of separate values (5.6.0) + get_sky_as_table = true, + } + +* `minetest.has_feature(arg)`: returns `boolean, missing_features` + * `arg`: string or table in format `{foo=true, bar=true}` + * `missing_features`: `{foo=true, bar=true}` +* `minetest.get_player_information(player_name)`: Table containing information + about a player. Example return value: + + { + address = "127.0.0.1", -- IP address of client + ip_version = 4, -- IPv4 / IPv6 + connection_uptime = 200, -- seconds since client connected + protocol_version = 32, -- protocol version used by client + formspec_version = 2, -- supported formspec version + lang_code = "fr" -- Language code used for translation + -- the following keys can be missing if no stats have been collected yet + min_rtt = 0.01, -- minimum round trip time + max_rtt = 0.2, -- maximum round trip time + avg_rtt = 0.02, -- average round trip time + min_jitter = 0.01, -- minimum packet time jitter + max_jitter = 0.5, -- maximum packet time jitter + avg_jitter = 0.03, -- average packet time jitter + -- the following information is available in a debug build only!!! + -- DO NOT USE IN MODS + --ser_vers = 26, -- serialization version used by client + --major = 0, -- major version number + --minor = 4, -- minor version number + --patch = 10, -- patch version number + --vers_string = "0.4.9-git", -- full version string + --state = "Active" -- current client state + } + +* `minetest.mkdir(path)`: returns success. + * Creates a directory specified by `path`, creating parent directories + if they don't exist. +* `minetest.rmdir(path, recursive)`: returns success. + * Removes a directory specified by `path`. + * If `recursive` is set to `true`, the directory is recursively removed. + Otherwise, the directory will only be removed if it is empty. + * Returns true on success, false on failure. +* `minetest.cpdir(source, destination)`: returns success. + * Copies a directory specified by `path` to `destination` + * Any files in `destination` will be overwritten if they already exist. + * Returns true on success, false on failure. +* `minetest.mvdir(source, destination)`: returns success. + * Moves a directory specified by `path` to `destination`. + * If the `destination` is a non-empty directory, then the move will fail. + * Returns true on success, false on failure. +* `minetest.get_dir_list(path, [is_dir])`: returns list of entry names + * is_dir is one of: + * nil: return all entries, + * true: return only subdirectory names, or + * false: return only file names. +* `minetest.safe_file_write(path, content)`: returns boolean indicating success + * Replaces contents of file at path with new contents in a safe (atomic) + way. Use this instead of below code when writing e.g. database files: + `local f = io.open(path, "wb"); f:write(content); f:close()` +* `minetest.get_version()`: returns a table containing components of the + engine version. Components: + * `project`: Name of the project, eg, "Minetest" + * `string`: Simple version, eg, "1.2.3-dev" + * `hash`: Full git version (only set if available), + eg, "1.2.3-dev-01234567-dirty". + * `is_dev`: Boolean value indicating whether it's a development build + Use this for informational purposes only. The information in the returned + table does not represent the capabilities of the engine, nor is it + reliable or verifiable. Compatible forks will have a different name and + version entirely. To check for the presence of engine features, test + whether the functions exported by the wanted features exist. For example: + `if minetest.check_for_falling then ... end`. +* `minetest.sha1(data, [raw])`: returns the sha1 hash of data + * `data`: string of data to hash + * `raw`: return raw bytes instead of hex digits, default: false +* `minetest.colorspec_to_colorstring(colorspec)`: Converts a ColorSpec to a + ColorString. If the ColorSpec is invalid, returns `nil`. + * `colorspec`: The ColorSpec to convert +* `minetest.colorspec_to_bytes(colorspec)`: Converts a ColorSpec to a raw + string of four bytes in an RGBA layout, returned as a string. + * `colorspec`: The ColorSpec to convert +* `minetest.encode_png(width, height, data, [compression])`: Encode a PNG + image and return it in string form. + * `width`: Width of the image + * `height`: Height of the image + * `data`: Image data, one of: + * array table of ColorSpec, length must be width*height + * string with raw RGBA pixels, length must be width*height*4 + * `compression`: Optional zlib compression level, number in range 0 to 9. + The data is one-dimensional, starting in the upper left corner of the image + and laid out in scanlines going from left to right, then top to bottom. + Please note that it's not safe to use string.char to generate raw data, + use `colorspec_to_bytes` to generate raw RGBA values in a predictable way. + The resulting PNG image is always 32-bit. Palettes are not supported at the moment. + You may use this to procedurally generate textures during server init. + +Logging +------- + +* `minetest.debug(...)` + * Equivalent to `minetest.log(table.concat({...}, "\t"))` +* `minetest.log([level,] text)` + * `level` is one of `"none"`, `"error"`, `"warning"`, `"action"`, + `"info"`, or `"verbose"`. Default is `"none"`. + +Registration functions +---------------------- + +Call these functions only at load time! + +### Environment + +* `minetest.register_node(name, node definition)` +* `minetest.register_craftitem(name, item definition)` +* `minetest.register_tool(name, item definition)` +* `minetest.override_item(name, redefinition)` + * Overrides fields of an item registered with register_node/tool/craftitem. + * Note: Item must already be defined, (opt)depend on the mod defining it. + * Example: `minetest.override_item("default:mese", + {light_source=minetest.LIGHT_MAX})` +* `minetest.unregister_item(name)` + * Unregisters the item from the engine, and deletes the entry with key + `name` from `minetest.registered_items` and from the associated item table + according to its nature: `minetest.registered_nodes`, etc. +* `minetest.register_entity(name, entity definition)` +* `minetest.register_abm(abm definition)` +* `minetest.register_lbm(lbm definition)` +* `minetest.register_alias(alias, original_name)` + * Also use this to set the 'mapgen aliases' needed in a game for the core + mapgens. See [Mapgen aliases] section above. +* `minetest.register_alias_force(alias, original_name)` +* `minetest.register_ore(ore definition)` + * Returns an integer object handle uniquely identifying the registered + ore on success. + * The order of ore registrations determines the order of ore generation. +* `minetest.register_biome(biome definition)` + * Returns an integer object handle uniquely identifying the registered + biome on success. To get the biome ID, use `minetest.get_biome_id`. +* `minetest.unregister_biome(name)` + * Unregisters the biome from the engine, and deletes the entry with key + `name` from `minetest.registered_biomes`. + * Warning: This alters the biome to biome ID correspondences, so any + decorations or ores using the 'biomes' field must afterwards be cleared + and re-registered. +* `minetest.register_decoration(decoration definition)` + * Returns an integer object handle uniquely identifying the registered + decoration on success. To get the decoration ID, use + `minetest.get_decoration_id`. + * The order of decoration registrations determines the order of decoration + generation. +* `minetest.register_schematic(schematic definition)` + * Returns an integer object handle uniquely identifying the registered + schematic on success. + * If the schematic is loaded from a file, the `name` field is set to the + filename. + * If the function is called when loading the mod, and `name` is a relative + path, then the current mod path will be prepended to the schematic + filename. +* `minetest.clear_registered_biomes()` + * Clears all biomes currently registered. + * Warning: Clearing and re-registering biomes alters the biome to biome ID + correspondences, so any decorations or ores using the 'biomes' field must + afterwards be cleared and re-registered. +* `minetest.clear_registered_decorations()` + * Clears all decorations currently registered. +* `minetest.clear_registered_ores()` + * Clears all ores currently registered. +* `minetest.clear_registered_schematics()` + * Clears all schematics currently registered. + +### Gameplay + +* `minetest.register_craft(recipe)` + * Check recipe table syntax for different types below. +* `minetest.clear_craft(recipe)` + * Will erase existing craft based either on output item or on input recipe. + * Specify either output or input only. If you specify both, input will be + ignored. For input use the same recipe table syntax as for + `minetest.register_craft(recipe)`. For output specify only the item, + without a quantity. + * Returns false if no erase candidate could be found, otherwise returns true. + * **Warning**! The type field ("shaped", "cooking" or any other) will be + ignored if the recipe contains output. Erasing is then done independently + from the crafting method. +* `minetest.register_chatcommand(cmd, chatcommand definition)` +* `minetest.override_chatcommand(name, redefinition)` + * Overrides fields of a chatcommand registered with `register_chatcommand`. +* `minetest.unregister_chatcommand(name)` + * Unregisters a chatcommands registered with `register_chatcommand`. +* `minetest.register_privilege(name, definition)` + * `definition` can be a description or a definition table (see [Privilege + definition]). + * If it is a description, the priv will be granted to singleplayer and admin + by default. + * To allow players with `basic_privs` to grant, see the `basic_privs` + minetest.conf setting. +* `minetest.register_authentication_handler(authentication handler definition)` + * Registers an auth handler that overrides the builtin one. + * This function can be called by a single mod once only. + +Global callback registration functions +-------------------------------------- + +Call these functions only at load time! + +* `minetest.register_globalstep(function(dtime))` + * Called every server step, usually interval of 0.1s +* `minetest.register_on_mods_loaded(function())` + * Called after mods have finished loading and before the media is cached or the + aliases handled. +* `minetest.register_on_shutdown(function())` + * Called before server shutdown + * **Warning**: If the server terminates abnormally (i.e. crashes), the + registered callbacks **will likely not be run**. Data should be saved at + semi-frequent intervals as well as on server shutdown. +* `minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing))` + * Called when a node has been placed + * If return `true` no item is taken from `itemstack` + * `placer` may be any valid ObjectRef or nil. + * **Not recommended**; use `on_construct` or `after_place_node` in node + definition whenever possible. +* `minetest.register_on_dignode(function(pos, oldnode, digger))` + * Called when a node has been dug. + * **Not recommended**; Use `on_destruct` or `after_dig_node` in node + definition whenever possible. +* `minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing))` + * Called when a node is punched +* `minetest.register_on_generated(function(minp, maxp, blockseed))` + * Called after generating a piece of world. Modifying nodes inside the area + is a bit faster than usual. +* `minetest.register_on_newplayer(function(ObjectRef))` + * Called when a new player enters the world for the first time +* `minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage))` + * Called when a player is punched + * Note: This callback is invoked even if the punched player is dead. + * `player`: ObjectRef - Player that was punched + * `hitter`: ObjectRef - Player that hit + * `time_from_last_punch`: Meant for disallowing spamming of clicks + (can be nil). + * `tool_capabilities`: Capability table of used item (can be nil) + * `dir`: Unit vector of direction of punch. Always defined. Points from + the puncher to the punched. + * `damage`: Number that represents the damage calculated by the engine + * should return `true` to prevent the default damage mechanism +* `minetest.register_on_rightclickplayer(function(player, clicker))` + * Called when the 'place/use' key was used while pointing a player + (not neccessarily an actual rightclick) + * `player`: ObjectRef - Player that is acted upon + * `clicker`: ObjectRef - Object that acted upon `player`, may or may not be a player +* `minetest.register_on_player_hpchange(function(player, hp_change, reason), modifier)` + * Called when the player gets damaged or healed + * `player`: ObjectRef of the player + * `hp_change`: the amount of change. Negative when it is damage. + * `reason`: a PlayerHPChangeReason table. + * The `type` field will have one of the following values: + * `set_hp`: A mod or the engine called `set_hp` without + giving a type - use this for custom damage types. + * `punch`: Was punched. `reason.object` will hold the puncher, or nil if none. + * `fall` + * `node_damage`: `damage_per_second` from a neighbouring node. + `reason.node` will hold the node name or nil. + * `drown` + * `respawn` + * Any of the above types may have additional fields from mods. + * `reason.from` will be `mod` or `engine`. + * `modifier`: when true, the function should return the actual `hp_change`. + Note: modifiers only get a temporary `hp_change` that can be modified by later modifiers. + Modifiers can return true as a second argument to stop the execution of further functions. + Non-modifiers receive the final HP change calculated by the modifiers. +* `minetest.register_on_dieplayer(function(ObjectRef, reason))` + * Called when a player dies + * `reason`: a PlayerHPChangeReason table, see register_on_player_hpchange +* `minetest.register_on_respawnplayer(function(ObjectRef))` + * Called when player is to be respawned + * Called _before_ repositioning of player occurs + * return true in func to disable regular player placement +* `minetest.register_on_prejoinplayer(function(name, ip))` + * Called when a client connects to the server, prior to authentication + * If it returns a string, the client is disconnected with that string as + reason. +* `minetest.register_on_joinplayer(function(ObjectRef, last_login))` + * Called when a player joins the game + * `last_login`: The timestamp of the previous login, or nil if player is new +* `minetest.register_on_leaveplayer(function(ObjectRef, timed_out))` + * Called when a player leaves the game + * `timed_out`: True for timeout, false for other reasons. +* `minetest.register_on_authplayer(function(name, ip, is_success))` + * Called when a client attempts to log into an account. + * `name`: The name of the account being authenticated. + * `ip`: The IP address of the client + * `is_success`: Whether the client was successfully authenticated + * For newly registered accounts, `is_success` will always be true +* `minetest.register_on_auth_fail(function(name, ip))` + * Deprecated: use `minetest.register_on_authplayer(name, ip, is_success)` instead. +* `minetest.register_on_cheat(function(ObjectRef, cheat))` + * Called when a player cheats + * `cheat`: `{type=<cheat_type>}`, where `<cheat_type>` is one of: + * `moved_too_fast` + * `interacted_too_far` + * `interacted_with_self` + * `interacted_while_dead` + * `finished_unknown_dig` + * `dug_unbreakable` + * `dug_too_fast` +* `minetest.register_on_chat_message(function(name, message))` + * Called always when a player says something + * Return `true` to mark the message as handled, which means that it will + not be sent to other players. +* `minetest.register_on_chatcommand(function(name, command, params))` + * Called always when a chatcommand is triggered, before `minetest.registered_chatcommands` + is checked to see if the command exists, but after the input is parsed. + * Return `true` to mark the command as handled, which means that the default + handlers will be prevented. +* `minetest.register_on_player_receive_fields(function(player, formname, fields))` + * Called when the server received input from `player` in a formspec with + the given `formname`. Specifically, this is called on any of the + following events: + * a button was pressed, + * Enter was pressed while the focus was on a text field + * a checkbox was toggled, + * something was selected in a dropdown list, + * a different tab was selected, + * selection was changed in a textlist or table, + * an entry was double-clicked in a textlist or table, + * a scrollbar was moved, or + * the form was actively closed by the player. + * Fields are sent for formspec elements which define a field. `fields` + is a table containing each formspecs element value (as string), with + the `name` parameter as index for each. The value depends on the + formspec element type: + * `animated_image`: Returns the index of the current frame. + * `button` and variants: If pressed, contains the user-facing button + text as value. If not pressed, is `nil` + * `field`, `textarea` and variants: Text in the field + * `dropdown`: Either the index or value, depending on the `index event` + dropdown argument. + * `tabheader`: Tab index, starting with `"1"` (only if tab changed) + * `checkbox`: `"true"` if checked, `"false"` if unchecked + * `textlist`: See `minetest.explode_textlist_event` + * `table`: See `minetest.explode_table_event` + * `scrollbar`: See `minetest.explode_scrollbar_event` + * Special case: `["quit"]="true"` is sent when the user actively + closed the form by mouse click, keypress or through a button_exit[] + element. + * Special case: `["key_enter"]="true"` is sent when the user pressed + the Enter key and the focus was either nowhere (causing the formspec + to be closed) or on a button. If the focus was on a text field, + additionally, the index `key_enter_field` contains the name of the + text field. See also: `field_close_on_enter`. + * Newest functions are called first + * If function returns `true`, remaining functions are not called +* `minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv))` + * Called when `player` crafts something + * `itemstack` is the output + * `old_craft_grid` contains the recipe (Note: the one in the inventory is + cleared). + * `craft_inv` is the inventory with the crafting grid + * Return either an `ItemStack`, to replace the output, or `nil`, to not + modify it. +* `minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv))` + * The same as before, except that it is called before the player crafts, to + make craft prediction, and it should not change anything. +* `minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info))` + * Determines how much of a stack may be taken, put or moved to a + player inventory. + * `player` (type `ObjectRef`) is the player who modified the inventory + `inventory` (type `InvRef`). + * List of possible `action` (string) values and their + `inventory_info` (table) contents: + * `move`: `{from_list=string, to_list=string, from_index=number, to_index=number, count=number}` + * `put`: `{listname=string, index=number, stack=ItemStack}` + * `take`: Same as `put` + * Return a numeric value to limit the amount of items to be taken, put or + moved. A value of `-1` for `take` will make the source stack infinite. +* `minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info))` + * Called after a take, put or move event from/to/in a player inventory + * Function arguments: see `minetest.register_allow_player_inventory_action` + * Does not accept or handle any return value. +* `minetest.register_on_protection_violation(function(pos, name))` + * Called by `builtin` and mods when a player violates protection at a + position (eg, digs a node or punches a protected entity). + * The registered functions can be called using + `minetest.record_protection_violation`. + * The provided function should check that the position is protected by the + mod calling this function before it prints a message, if it does, to + allow for multiple protection mods. +* `minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, user, pointed_thing))` + * Called when an item is eaten, by `minetest.item_eat` + * Return `itemstack` to cancel the default item eat response (i.e.: hp increase). +* `minetest.register_on_priv_grant(function(name, granter, priv))` + * Called when `granter` grants the priv `priv` to `name`. + * Note that the callback will be called twice if it's done by a player, + once with granter being the player name, and again with granter being nil. +* `minetest.register_on_priv_revoke(function(name, revoker, priv))` + * Called when `revoker` revokes the priv `priv` from `name`. + * Note that the callback will be called twice if it's done by a player, + once with revoker being the player name, and again with revoker being nil. +* `minetest.register_can_bypass_userlimit(function(name, ip))` + * Called when `name` user connects with `ip`. + * Return `true` to by pass the player limit +* `minetest.register_on_modchannel_message(function(channel_name, sender, message))` + * Called when an incoming mod channel message is received + * You should have joined some channels to receive events. + * If message comes from a server mod, `sender` field is an empty string. +* `minetest.register_on_liquid_transformed(function(pos_list, node_list))` + * Called after liquid nodes (`liquidtype ~= "none"`) are modified by the + engine's liquid transformation process. + * `pos_list` is an array of all modified positions. + * `node_list` is an array of the old node that was previously at the position + with the corresponding index in pos_list. + +Setting-related +--------------- + +* `minetest.settings`: Settings object containing all of the settings from the + main config file (`minetest.conf`). +* `minetest.setting_get_pos(name)`: Loads a setting from the main settings and + parses it as a position (in the format `(1,2,3)`). Returns a position or nil. + +Authentication +-------------- + +* `minetest.string_to_privs(str[, delim])`: + * Converts string representation of privs into table form + * `delim`: String separating the privs. Defaults to `","`. + * Returns `{ priv1 = true, ... }` +* `minetest.privs_to_string(privs[, delim])`: + * Returns the string representation of `privs` + * `delim`: String to delimit privs. Defaults to `","`. +* `minetest.get_player_privs(name) -> {priv1=true,...}` +* `minetest.check_player_privs(player_or_name, ...)`: + returns `bool, missing_privs` + * A quickhand for checking privileges. + * `player_or_name`: Either a Player object or the name of a player. + * `...` is either a list of strings, e.g. `"priva", "privb"` or + a table, e.g. `{ priva = true, privb = true }`. + +* `minetest.check_password_entry(name, entry, password)` + * Returns true if the "password entry" for a player with name matches given + password, false otherwise. + * The "password entry" is the password representation generated by the + engine as returned as part of a `get_auth()` call on the auth handler. + * Only use this function for making it possible to log in via password from + external protocols such as IRC, other uses are frowned upon. +* `minetest.get_password_hash(name, raw_password)` + * Convert a name-password pair to a password hash that Minetest can use. + * The returned value alone is not a good basis for password checks based + on comparing the password hash in the database with the password hash + from the function, with an externally provided password, as the hash + in the db might use the new SRP verifier format. + * For this purpose, use `minetest.check_password_entry` instead. +* `minetest.get_player_ip(name)`: returns an IP address string for the player + `name`. + * The player needs to be online for this to be successful. + +* `minetest.get_auth_handler()`: Return the currently active auth handler + * See the [Authentication handler definition] + * Use this to e.g. get the authentication data for a player: + `local auth_data = minetest.get_auth_handler().get_auth(playername)` +* `minetest.notify_authentication_modified(name)` + * Must be called by the authentication handler for privilege changes. + * `name`: string; if omitted, all auth data should be considered modified +* `minetest.set_player_password(name, password_hash)`: Set password hash of + player `name`. +* `minetest.set_player_privs(name, {priv1=true,...})`: Set privileges of player + `name`. +* `minetest.auth_reload()` + * See `reload()` in authentication handler definition + +`minetest.set_player_password`, `minetest.set_player_privs`, +`minetest.get_player_privs` and `minetest.auth_reload` call the authentication +handler. + +Chat +---- + +* `minetest.chat_send_all(text)` +* `minetest.chat_send_player(name, text)` +* `minetest.format_chat_message(name, message)` + * Used by the server to format a chat message, based on the setting `chat_message_format`. + Refer to the documentation of the setting for a list of valid placeholders. + * Takes player name and message, and returns the formatted string to be sent to players. + * Can be redefined by mods if required, for things like colored names or messages. + * **Only** the first occurrence of each placeholder will be replaced. + +Environment access +------------------ + +* `minetest.set_node(pos, node)` +* `minetest.add_node(pos, node)`: alias to `minetest.set_node` + * Set node at position `pos` + * `node`: table `{name=string, param1=number, param2=number}` + * If param1 or param2 is omitted, it's set to `0`. + * e.g. `minetest.set_node({x=0, y=10, z=0}, {name="default:wood"})` +* `minetest.bulk_set_node({pos1, pos2, pos3, ...}, node)` + * Set node on all positions set in the first argument. + * e.g. `minetest.bulk_set_node({{x=0, y=1, z=1}, {x=1, y=2, z=2}}, {name="default:stone"})` + * For node specification or position syntax see `minetest.set_node` call + * Faster than set_node due to single call, but still considerably slower + than Lua Voxel Manipulators (LVM) for large numbers of nodes. + Unlike LVMs, this will call node callbacks. It also allows setting nodes + in spread out positions which would cause LVMs to waste memory. + For setting a cube, this is 1.3x faster than set_node whereas LVM is 20 + times faster. +* `minetest.swap_node(pos, node)` + * Set node at position, but don't remove metadata +* `minetest.remove_node(pos)` + * By default it does the same as `minetest.set_node(pos, {name="air"})` +* `minetest.get_node(pos)` + * Returns the node at the given position as table in the format + `{name="node_name", param1=0, param2=0}`, + returns `{name="ignore", param1=0, param2=0}` for unloaded areas. +* `minetest.get_node_or_nil(pos)` + * Same as `get_node` but returns `nil` for unloaded areas. +* `minetest.get_node_light(pos, timeofday)` + * Gets the light value at the given position. Note that the light value + "inside" the node at the given position is returned, so you usually want + to get the light value of a neighbor. + * `pos`: The position where to measure the light. + * `timeofday`: `nil` for current time, `0` for night, `0.5` for day + * Returns a number between `0` and `15` or `nil` + * `nil` is returned e.g. when the map isn't loaded at `pos` +* `minetest.get_natural_light(pos[, timeofday])` + * Figures out the sunlight (or moonlight) value at pos at the given time of + day. + * `pos`: The position of the node + * `timeofday`: `nil` for current time, `0` for night, `0.5` for day + * Returns a number between `0` and `15` or `nil` + * This function tests 203 nodes in the worst case, which happens very + unlikely +* `minetest.get_artificial_light(param1)` + * Calculates the artificial light (light from e.g. torches) value from the + `param1` value. + * `param1`: The param1 value of a `paramtype = "light"` node. + * Returns a number between `0` and `15` + * Currently it's the same as `math.floor(param1 / 16)`, except that it + ensures compatibility. +* `minetest.place_node(pos, node)` + * Place node with the same effects that a player would cause +* `minetest.dig_node(pos)` + * Dig node with the same effects that a player would cause + * Returns `true` if successful, `false` on failure (e.g. protected location) +* `minetest.punch_node(pos)` + * Punch node with the same effects that a player would cause +* `minetest.spawn_falling_node(pos)` + * Change node into falling node + * Returns `true` and the ObjectRef of the spawned entity if successful, `false` on failure + +* `minetest.find_nodes_with_meta(pos1, pos2)` + * Get a table of positions of nodes that have metadata within a region + {pos1, pos2}. +* `minetest.get_meta(pos)` + * Get a `NodeMetaRef` at that position +* `minetest.get_node_timer(pos)` + * Get `NodeTimerRef` + +* `minetest.add_entity(pos, name, [staticdata])`: Spawn Lua-defined entity at + position. + * Returns `ObjectRef`, or `nil` if failed +* `minetest.add_item(pos, item)`: Spawn item + * Returns `ObjectRef`, or `nil` if failed +* `minetest.get_player_by_name(name)`: Get an `ObjectRef` to a player +* `minetest.get_objects_inside_radius(pos, radius)`: returns a list of + ObjectRefs. + * `radius`: using an euclidean metric +* `minetest.get_objects_in_area(pos1, pos2)`: returns a list of + ObjectRefs. + * `pos1` and `pos2` are the min and max positions of the area to search. +* `minetest.set_timeofday(val)` + * `val` is between `0` and `1`; `0` for midnight, `0.5` for midday +* `minetest.get_timeofday()` +* `minetest.get_gametime()`: returns the time, in seconds, since the world was + created. +* `minetest.get_day_count()`: returns number days elapsed since world was + created. + * accounts for time changes. +* `minetest.find_node_near(pos, radius, nodenames, [search_center])`: returns + pos or `nil`. + * `radius`: using a maximum metric + * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` + * `search_center` is an optional boolean (default: `false`) + If true `pos` is also checked for the nodes +* `minetest.find_nodes_in_area(pos1, pos2, nodenames, [grouped])` + * `pos1` and `pos2` are the min and max positions of the area to search. + * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` + * If `grouped` is true the return value is a table indexed by node name + which contains lists of positions. + * If `grouped` is false or absent the return values are as follows: + first value: Table with all node positions + second value: Table with the count of each node with the node name + as index + * Area volume is limited to 4,096,000 nodes +* `minetest.find_nodes_in_area_under_air(pos1, pos2, nodenames)`: returns a + list of positions. + * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` + * Return value: Table with all node positions with a node air above + * Area volume is limited to 4,096,000 nodes +* `minetest.get_perlin(noiseparams)` + * Return world-specific perlin noise. + * The actual seed used is the noiseparams seed plus the world seed. +* `minetest.get_perlin(seeddiff, octaves, persistence, spread)` + * Deprecated: use `minetest.get_perlin(noiseparams)` instead. + * Return world-specific perlin noise. +* `minetest.get_voxel_manip([pos1, pos2])` + * Return voxel manipulator object. + * Loads the manipulator from the map if positions are passed. +* `minetest.set_gen_notify(flags, {deco_ids})` + * Set the types of on-generate notifications that should be collected. + * `flags` is a flag field with the available flags: + * dungeon + * temple + * cave_begin + * cave_end + * large_cave_begin + * large_cave_end + * decoration + * The second parameter is a list of IDs of decorations which notification + is requested for. +* `minetest.get_gen_notify()` + * Returns a flagstring and a table with the `deco_id`s. +* `minetest.get_decoration_id(decoration_name)` + * Returns the decoration ID number for the provided decoration name string, + or `nil` on failure. +* `minetest.get_mapgen_object(objectname)` + * Return requested mapgen object if available (see [Mapgen objects]) +* `minetest.get_heat(pos)` + * Returns the heat at the position, or `nil` on failure. +* `minetest.get_humidity(pos)` + * Returns the humidity at the position, or `nil` on failure. +* `minetest.get_biome_data(pos)` + * Returns a table containing: + * `biome` the biome id of the biome at that position + * `heat` the heat at the position + * `humidity` the humidity at the position + * Or returns `nil` on failure. +* `minetest.get_biome_id(biome_name)` + * Returns the biome id, as used in the biomemap Mapgen object and returned + by `minetest.get_biome_data(pos)`, for a given biome_name string. +* `minetest.get_biome_name(biome_id)` + * Returns the biome name string for the provided biome id, or `nil` on + failure. + * If no biomes have been registered, such as in mgv6, returns `default`. +* `minetest.get_mapgen_params()` + * Deprecated: use `minetest.get_mapgen_setting(name)` instead. + * Returns a table containing: + * `mgname` + * `seed` + * `chunksize` + * `water_level` + * `flags` +* `minetest.set_mapgen_params(MapgenParams)` + * Deprecated: use `minetest.set_mapgen_setting(name, value, override)` + instead. + * Set map generation parameters. + * Function cannot be called after the registration period. + * Takes a table as an argument with the fields: + * `mgname` + * `seed` + * `chunksize` + * `water_level` + * `flags` + * Leave field unset to leave that parameter unchanged. + * `flags` contains a comma-delimited string of flags to set, or if the + prefix `"no"` is attached, clears instead. + * `flags` is in the same format and has the same options as `mg_flags` in + `minetest.conf`. +* `minetest.get_mapgen_setting(name)` + * Gets the *active* mapgen setting (or nil if none exists) in string + format with the following order of precedence: + 1) Settings loaded from map_meta.txt or overrides set during mod + execution. + 2) Settings set by mods without a metafile override + 3) Settings explicitly set in the user config file, minetest.conf + 4) Settings set as the user config default +* `minetest.get_mapgen_setting_noiseparams(name)` + * Same as above, but returns the value as a NoiseParams table if the + setting `name` exists and is a valid NoiseParams. +* `minetest.set_mapgen_setting(name, value, [override_meta])` + * Sets a mapgen param to `value`, and will take effect if the corresponding + mapgen setting is not already present in map_meta.txt. + * `override_meta` is an optional boolean (default: `false`). If this is set + to true, the setting will become the active setting regardless of the map + metafile contents. + * Note: to set the seed, use `"seed"`, not `"fixed_map_seed"`. +* `minetest.set_mapgen_setting_noiseparams(name, value, [override_meta])` + * Same as above, except value is a NoiseParams table. +* `minetest.set_noiseparams(name, noiseparams, set_default)` + * Sets the noiseparams setting of `name` to the noiseparams table specified + in `noiseparams`. + * `set_default` is an optional boolean (default: `true`) that specifies + whether the setting should be applied to the default config or current + active config. +* `minetest.get_noiseparams(name)` + * Returns a table of the noiseparams for name. +* `minetest.generate_ores(vm, pos1, pos2)` + * Generate all registered ores within the VoxelManip `vm` and in the area + from `pos1` to `pos2`. + * `pos1` and `pos2` are optional and default to mapchunk minp and maxp. +* `minetest.generate_decorations(vm, pos1, pos2)` + * Generate all registered decorations within the VoxelManip `vm` and in the + area from `pos1` to `pos2`. + * `pos1` and `pos2` are optional and default to mapchunk minp and maxp. +* `minetest.clear_objects([options])` + * Clear all objects in the environment + * Takes an optional table as an argument with the field `mode`. + * mode = `"full"` : Load and go through every mapblock, clearing + objects (default). + * mode = `"quick"`: Clear objects immediately in loaded mapblocks, + clear objects in unloaded mapblocks only when the + mapblocks are next activated. +* `minetest.load_area(pos1[, pos2])` + * Load the mapblocks containing the area from `pos1` to `pos2`. + `pos2` defaults to `pos1` if not specified. + * This function does not trigger map generation. +* `minetest.emerge_area(pos1, pos2, [callback], [param])` + * Queue all blocks in the area from `pos1` to `pos2`, inclusive, to be + asynchronously fetched from memory, loaded from disk, or if inexistent, + generates them. + * If `callback` is a valid Lua function, this will be called for each block + emerged. + * The function signature of callback is: + `function EmergeAreaCallback(blockpos, action, calls_remaining, param)` + * `blockpos` is the *block* coordinates of the block that had been + emerged. + * `action` could be one of the following constant values: + * `minetest.EMERGE_CANCELLED` + * `minetest.EMERGE_ERRORED` + * `minetest.EMERGE_FROM_MEMORY` + * `minetest.EMERGE_FROM_DISK` + * `minetest.EMERGE_GENERATED` + * `calls_remaining` is the number of callbacks to be expected after + this one. + * `param` is the user-defined parameter passed to emerge_area (or + nil if the parameter was absent). +* `minetest.delete_area(pos1, pos2)` + * delete all mapblocks in the area from pos1 to pos2, inclusive +* `minetest.line_of_sight(pos1, pos2)`: returns `boolean, pos` + * Checks if there is anything other than air between pos1 and pos2. + * Returns false if something is blocking the sight. + * Returns the position of the blocking node when `false` + * `pos1`: First position + * `pos2`: Second position +* `minetest.raycast(pos1, pos2, objects, liquids)`: returns `Raycast` + * Creates a `Raycast` object. + * `pos1`: start of the ray + * `pos2`: end of the ray + * `objects`: if false, only nodes will be returned. Default is `true`. + * `liquids`: if false, liquid nodes (`liquidtype ~= "none"`) won't be + returned. Default is `false`. +* `minetest.find_path(pos1,pos2,searchdistance,max_jump,max_drop,algorithm)` + * returns table containing path that can be walked on + * returns a table of 3D points representing a path from `pos1` to `pos2` or + `nil` on failure. + * Reasons for failure: + * No path exists at all + * No path exists within `searchdistance` (see below) + * Start or end pos is buried in land + * `pos1`: start position + * `pos2`: end position + * `searchdistance`: maximum distance from the search positions to search in. + In detail: Path must be completely inside a cuboid. The minimum + `searchdistance` of 1 will confine search between `pos1` and `pos2`. + Larger values will increase the size of this cuboid in all directions + * `max_jump`: maximum height difference to consider walkable + * `max_drop`: maximum height difference to consider droppable + * `algorithm`: One of `"A*_noprefetch"` (default), `"A*"`, `"Dijkstra"`. + Difference between `"A*"` and `"A*_noprefetch"` is that + `"A*"` will pre-calculate the cost-data, the other will calculate it + on-the-fly +* `minetest.spawn_tree (pos, {treedef})` + * spawns L-system tree at given `pos` with definition in `treedef` table +* `minetest.transforming_liquid_add(pos)` + * add node to liquid flow update queue +* `minetest.get_node_max_level(pos)` + * get max available level for leveled node +* `minetest.get_node_level(pos)` + * get level of leveled node (water, snow) +* `minetest.set_node_level(pos, level)` + * set level of leveled node, default `level` equals `1` + * if `totallevel > maxlevel`, returns rest (`total-max`). +* `minetest.add_node_level(pos, level)` + * increase level of leveled node by level, default `level` equals `1` + * if `totallevel > maxlevel`, returns rest (`total-max`) + * `level` must be between -127 and 127 +* `minetest.fix_light(pos1, pos2)`: returns `true`/`false` + * resets the light in a cuboid-shaped part of + the map and removes lighting bugs. + * Loads the area if it is not loaded. + * `pos1` is the corner of the cuboid with the least coordinates + (in node coordinates), inclusive. + * `pos2` is the opposite corner of the cuboid, inclusive. + * The actual updated cuboid might be larger than the specified one, + because only whole map blocks can be updated. + The actual updated area consists of those map blocks that intersect + with the given cuboid. + * However, the neighborhood of the updated area might change + as well, as light can spread out of the cuboid, also light + might be removed. + * returns `false` if the area is not fully generated, + `true` otherwise +* `minetest.check_single_for_falling(pos)` + * causes an unsupported `group:falling_node` node to fall and causes an + unattached `group:attached_node` node to fall. + * does not spread these updates to neighbours. +* `minetest.check_for_falling(pos)` + * causes an unsupported `group:falling_node` node to fall and causes an + unattached `group:attached_node` node to fall. + * spread these updates to neighbours and can cause a cascade + of nodes to fall. +* `minetest.get_spawn_level(x, z)` + * Returns a player spawn y co-ordinate for the provided (x, z) + co-ordinates, or `nil` for an unsuitable spawn point. + * For most mapgens a 'suitable spawn point' is one with y between + `water_level` and `water_level + 16`, and in mgv7 well away from rivers, + so `nil` will be returned for many (x, z) co-ordinates. + * The spawn level returned is for a player spawn in unmodified terrain. + * The spawn level is intentionally above terrain level to cope with + full-node biome 'dust' nodes. + +Mod channels +------------ + +You can find mod channels communication scheme in `doc/mod_channels.png`. + +* `minetest.mod_channel_join(channel_name)` + * Server joins channel `channel_name`, and creates it if necessary. You + should listen for incoming messages with + `minetest.register_on_modchannel_message` + +Inventory +--------- + +`minetest.get_inventory(location)`: returns an `InvRef` + +* `location` = e.g. + * `{type="player", name="celeron55"}` + * `{type="node", pos={x=, y=, z=}}` + * `{type="detached", name="creative"}` +* `minetest.create_detached_inventory(name, callbacks, [player_name])`: returns + an `InvRef`. + * `callbacks`: See [Detached inventory callbacks] + * `player_name`: Make detached inventory available to one player + exclusively, by default they will be sent to every player (even if not + used). + Note that this parameter is mostly just a workaround and will be removed + in future releases. + * Creates a detached inventory. If it already exists, it is cleared. +* `minetest.remove_detached_inventory(name)` + * Returns a `boolean` indicating whether the removal succeeded. +* `minetest.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)`: + returns leftover ItemStack or nil to indicate no inventory change + * See `minetest.item_eat` and `minetest.register_on_item_eat` + +Formspec +-------- + +* `minetest.show_formspec(playername, formname, formspec)` + * `playername`: name of player to show formspec + * `formname`: name passed to `on_player_receive_fields` callbacks. + It should follow the `"modname:<whatever>"` naming convention + * `formspec`: formspec to display +* `minetest.close_formspec(playername, formname)` + * `playername`: name of player to close formspec + * `formname`: has to exactly match the one given in `show_formspec`, or the + formspec will not close. + * calling `show_formspec(playername, formname, "")` is equal to this + expression. + * to close a formspec regardless of the formname, call + `minetest.close_formspec(playername, "")`. + **USE THIS ONLY WHEN ABSOLUTELY NECESSARY!** +* `minetest.formspec_escape(string)`: returns a string + * escapes the characters "[", "]", "\", "," and ";", which can not be used + in formspecs. +* `minetest.explode_table_event(string)`: returns a table + * returns e.g. `{type="CHG", row=1, column=2}` + * `type` is one of: + * `"INV"`: no row selected + * `"CHG"`: selected + * `"DCL"`: double-click +* `minetest.explode_textlist_event(string)`: returns a table + * returns e.g. `{type="CHG", index=1}` + * `type` is one of: + * `"INV"`: no row selected + * `"CHG"`: selected + * `"DCL"`: double-click +* `minetest.explode_scrollbar_event(string)`: returns a table + * returns e.g. `{type="CHG", value=500}` + * `type` is one of: + * `"INV"`: something failed + * `"CHG"`: has been changed + * `"VAL"`: not changed + +Item handling +------------- + +* `minetest.inventorycube(img1, img2, img3)` + * Returns a string for making an image of a cube (useful as an item image) +* `minetest.get_pointed_thing_position(pointed_thing, above)` + * Returns the position of a `pointed_thing` or `nil` if the `pointed_thing` + does not refer to a node or entity. + * If the optional `above` parameter is true and the `pointed_thing` refers + to a node, then it will return the `above` position of the `pointed_thing`. +* `minetest.dir_to_facedir(dir, is6d)` + * Convert a vector to a facedir value, used in `param2` for + `paramtype2="facedir"`. + * passing something non-`nil`/`false` for the optional second parameter + causes it to take the y component into account. +* `minetest.facedir_to_dir(facedir)` + * Convert a facedir back into a vector aimed directly out the "back" of a + node. +* `minetest.dir_to_wallmounted(dir)` + * Convert a vector to a wallmounted value, used for + `paramtype2="wallmounted"`. +* `minetest.wallmounted_to_dir(wallmounted)` + * Convert a wallmounted value back into a vector aimed directly out the + "back" of a node. +* `minetest.dir_to_yaw(dir)` + * Convert a vector into a yaw (angle) +* `minetest.yaw_to_dir(yaw)` + * Convert yaw (angle) to a vector +* `minetest.is_colored_paramtype(ptype)` + * Returns a boolean. Returns `true` if the given `paramtype2` contains + color information (`color`, `colorwallmounted` or `colorfacedir`). +* `minetest.strip_param2_color(param2, paramtype2)` + * Removes everything but the color information from the + given `param2` value. + * Returns `nil` if the given `paramtype2` does not contain color + information. +* `minetest.get_node_drops(node, toolname)` + * Returns list of itemstrings that are dropped by `node` when dug + with the item `toolname` (not limited to tools). + * `node`: node as table or node name + * `toolname`: name of the item used to dig (can be `nil`) +* `minetest.get_craft_result(input)`: returns `output, decremented_input` + * `input.method` = `"normal"` or `"cooking"` or `"fuel"` + * `input.width` = for example `3` + * `input.items` = for example + `{stack1, stack2, stack3, stack4, stack 5, stack 6, stack 7, stack 8, stack 9}` + * `output.item` = `ItemStack`, if unsuccessful: empty `ItemStack` + * `output.time` = a number, if unsuccessful: `0` + * `output.replacements` = List of replacement `ItemStack`s that couldn't be + placed in `decremented_input.items`. Replacements can be placed in + `decremented_input` if the stack of the replaced item has a count of 1. + * `decremented_input` = like `input` +* `minetest.get_craft_recipe(output)`: returns input + * returns last registered recipe for output item (node) + * `output` is a node or item type such as `"default:torch"` + * `input.method` = `"normal"` or `"cooking"` or `"fuel"` + * `input.width` = for example `3` + * `input.items` = for example + `{stack1, stack2, stack3, stack4, stack 5, stack 6, stack 7, stack 8, stack 9}` + * `input.items` = `nil` if no recipe found +* `minetest.get_all_craft_recipes(query item)`: returns a table or `nil` + * returns indexed table with all registered recipes for query item (node) + or `nil` if no recipe was found. + * recipe entry table: + * `method`: 'normal' or 'cooking' or 'fuel' + * `width`: 0-3, 0 means shapeless recipe + * `items`: indexed [1-9] table with recipe items + * `output`: string with item name and quantity + * Example result for `"default:gold_ingot"` with two recipes: + + { + { + method = "cooking", width = 3, + output = "default:gold_ingot", items = {"default:gold_lump"} + }, + { + method = "normal", width = 1, + output = "default:gold_ingot 9", items = {"default:goldblock"} + } + } + +* `minetest.handle_node_drops(pos, drops, digger)` + * `drops`: list of itemstrings + * Handles drops from nodes after digging: Default action is to put them + into digger's inventory. + * Can be overridden to get different functionality (e.g. dropping items on + ground) +* `minetest.itemstring_with_palette(item, palette_index)`: returns an item + string. + * Creates an item string which contains palette index information + for hardware colorization. You can use the returned string + as an output in a craft recipe. + * `item`: the item stack which becomes colored. Can be in string, + table and native form. + * `palette_index`: this index is added to the item stack +* `minetest.itemstring_with_color(item, colorstring)`: returns an item string + * Creates an item string which contains static color information + for hardware colorization. Use this method if you wish to colorize + an item that does not own a palette. You can use the returned string + as an output in a craft recipe. + * `item`: the item stack which becomes colored. Can be in string, + table and native form. + * `colorstring`: the new color of the item stack + +Rollback +-------- + +* `minetest.rollback_get_node_actions(pos, range, seconds, limit)`: + returns `{{actor, pos, time, oldnode, newnode}, ...}` + * Find who has done something to a node, or near a node + * `actor`: `"player:<name>"`, also `"liquid"`. +* `minetest.rollback_revert_actions_by(actor, seconds)`: returns + `boolean, log_messages`. + * Revert latest actions of someone + * `actor`: `"player:<name>"`, also `"liquid"`. + +Defaults for the `on_place` and `on_drop` item definition functions +------------------------------------------------------------------- + +* `minetest.item_place_node(itemstack, placer, pointed_thing[, param2, prevent_after_place])` + * Place item as a node + * `param2` overrides `facedir` and wallmounted `param2` + * `prevent_after_place`: if set to `true`, `after_place_node` is not called + for the newly placed node to prevent a callback and placement loop + * returns `itemstack, position` + * `position`: the location the node was placed to. `nil` if nothing was placed. +* `minetest.item_place_object(itemstack, placer, pointed_thing)` + * Place item as-is + * returns the leftover itemstack + * **Note**: This function is deprecated and will never be called. +* `minetest.item_place(itemstack, placer, pointed_thing[, param2])` + * Wrapper that calls `minetest.item_place_node` if appropriate + * Calls `on_rightclick` of `pointed_thing.under` if defined instead + * **Note**: is not called when wielded item overrides `on_place` + * `param2` overrides facedir and wallmounted `param2` + * returns `itemstack, position` + * `position`: the location the node was placed to. `nil` if nothing was placed. +* `minetest.item_drop(itemstack, dropper, pos)` + * Drop the item + * returns the leftover itemstack +* `minetest.item_eat(hp_change[, replace_with_item])` + * Returns `function(itemstack, user, pointed_thing)` as a + function wrapper for `minetest.do_item_eat`. + * `replace_with_item` is the itemstring which is added to the inventory. + If the player is eating a stack, then replace_with_item goes to a + different spot. + +Defaults for the `on_punch` and `on_dig` node definition callbacks +------------------------------------------------------------------ + +* `minetest.node_punch(pos, node, puncher, pointed_thing)` + * Calls functions registered by `minetest.register_on_punchnode()` +* `minetest.node_dig(pos, node, digger)` + * Checks if node can be dug, puts item into inventory, removes node + * Calls functions registered by `minetest.registered_on_dignodes()` + +Sounds +------ + +* `minetest.sound_play(spec, parameters, [ephemeral])`: returns a handle + * `spec` is a `SimpleSoundSpec` + * `parameters` is a sound parameter table + * `ephemeral` is a boolean (default: false) + Ephemeral sounds will not return a handle and can't be stopped or faded. + It is recommend to use this for short sounds that happen in response to + player actions (e.g. door closing). +* `minetest.sound_stop(handle)` + * `handle` is a handle returned by `minetest.sound_play` +* `minetest.sound_fade(handle, step, gain)` + * `handle` is a handle returned by `minetest.sound_play` + * `step` determines how fast a sound will fade. + The gain will change by this much per second, + until it reaches the target gain. + Note: Older versions used a signed step. This is deprecated, but old + code will still work. (the client uses abs(step) to correct it) + * `gain` the target gain for the fade. + Fading to zero will delete the sound. + +Timing +------ + +* `minetest.after(time, func, ...)` : returns job table to use as below. + * Call the function `func` after `time` seconds, may be fractional + * Optional: Variable number of arguments that are passed to `func` + +* `job:cancel()` + * Cancels the job function from being called + +Async environment +----------------- + +The engine allows you to submit jobs to be ran in an isolated environment +concurrently with normal server operation. +A job consists of a function to be ran in the async environment, any amount of +arguments (will be serialized) and a callback that will be called with the return +value of the job function once it is finished. + +The async environment does *not* have access to the map, entities, players or any +globals defined in the 'usual' environment. Consequently, functions like +`minetest.get_node()` or `minetest.get_player_by_name()` simply do not exist in it. + +Arguments and return values passed through this can contain certain userdata +objects that will be seamlessly copied (not shared) to the async environment. +This allows you easy interoperability for delegating work to jobs. + +* `minetest.handle_async(func, callback, ...)`: + * Queue the function `func` to be ran in an async environment. + Note that there are multiple persistent workers and any of them may + end up running a given job. The engine will scale the amount of + worker threads automatically. + * When `func` returns the callback is called (in the normal environment) + with all of the return values as arguments. + * Optional: Variable number of arguments that are passed to `func` +* `minetest.register_async_dofile(path)`: + * Register a path to a Lua file to be imported when an async environment + is initialized. You can use this to preload code which you can then call + later using `minetest.handle_async()`. + +### List of APIs available in an async environment + +Classes: +* `ItemStack` +* `PerlinNoise` +* `PerlinNoiseMap` +* `PseudoRandom` +* `PcgRandom` +* `SecureRandom` +* `VoxelArea` +* `VoxelManip` + * only if transferred into environment; can't read/write to map +* `Settings` + +Class instances that can be transferred between environments: +* `ItemStack` +* `PerlinNoise` +* `PerlinNoiseMap` +* `VoxelManip` + +Functions: +* Standalone helpers such as logging, filesystem, encoding, + hashing or compression APIs +* `minetest.request_insecure_environment` (same restrictions apply) + +Variables: +* `minetest.settings` +* `minetest.registered_items`, `registered_nodes`, `registered_tools`, + `registered_craftitems` and `registered_aliases` + * with all functions and userdata values replaced by `true`, calling any + callbacks here is obviously not possible + +Server +------ + +* `minetest.request_shutdown([message],[reconnect],[delay])`: request for + server shutdown. Will display `message` to clients. + * `reconnect` == true displays a reconnect button + * `delay` adds an optional delay (in seconds) before shutdown. + Negative delay cancels the current active shutdown. + Zero delay triggers an immediate shutdown. +* `minetest.cancel_shutdown_requests()`: cancel current delayed shutdown +* `minetest.get_server_status(name, joined)` + * Returns the server status string when a player joins or when the command + `/status` is called. Returns `nil` or an empty string when the message is + disabled. + * `joined`: Boolean value, indicates whether the function was called when + a player joined. + * This function may be overwritten by mods to customize the status message. +* `minetest.get_server_uptime()`: returns the server uptime in seconds +* `minetest.get_server_max_lag()`: returns the current maximum lag + of the server in seconds or nil if server is not fully loaded yet +* `minetest.remove_player(name)`: remove player from database (if they are not + connected). + * As auth data is not removed, minetest.player_exists will continue to + return true. Call the below method as well if you want to remove auth + data too. + * Returns a code (0: successful, 1: no such player, 2: player is connected) +* `minetest.remove_player_auth(name)`: remove player authentication data + * Returns boolean indicating success (false if player nonexistant) +* `minetest.dynamic_add_media(options, callback)` + * `options`: table containing the following parameters + * `filepath`: path to a media file on the filesystem + * `to_player`: name of the player the media should be sent to instead of + all players (optional) + * `ephemeral`: boolean that marks the media as ephemeral, + it will not be cached on the client (optional, default false) + * `callback`: function with arguments `name`, which is a player name + * Pushes the specified media file to client(s). (details below) + The file must be a supported image, sound or model format. + Dynamically added media is not persisted between server restarts. + * Returns false on error, true if the request was accepted + * The given callback will be called for every player as soon as the + media is available on the client. + * Details/Notes: + * If `ephemeral`=false and `to_player` is unset the file is added to the media + sent to clients on startup, this means the media will appear even on + old clients if they rejoin the server. + * If `ephemeral`=false the file must not be modified, deleted, moved or + renamed after calling this function. + * Regardless of any use of `ephemeral`, adding media files with the same + name twice is not possible/guaranteed to work. An exception to this is the + use of `to_player` to send the same, already existent file to multiple + chosen players. + * Clients will attempt to fetch files added this way via remote media, + this can make transfer of bigger files painless (if set up). Nevertheless + it is advised not to use dynamic media for big media files. + +Bans +---- + +* `minetest.get_ban_list()`: returns a list of all bans formatted as string +* `minetest.get_ban_description(ip_or_name)`: returns list of bans matching + IP address or name formatted as string +* `minetest.ban_player(name)`: ban the IP of a currently connected player + * Returns boolean indicating success +* `minetest.unban_player_or_ip(ip_or_name)`: remove ban record matching + IP address or name +* `minetest.kick_player(name, [reason])`: disconnect a player with an optional + reason. + * Returns boolean indicating success (false if player nonexistant) +* `minetest.disconnect_player(name, [reason])`: disconnect a player with an + optional reason, this will not prefix with 'Kicked: ' like kick_player. + If no reason is given, it will default to 'Disconnected.' + * Returns boolean indicating success (false if player nonexistant) + +Particles +--------- + +* `minetest.add_particle(particle definition)` + * Deprecated: `minetest.add_particle(pos, velocity, acceleration, + expirationtime, size, collisiondetection, texture, playername)` + +* `minetest.add_particlespawner(particlespawner definition)` + * Add a `ParticleSpawner`, an object that spawns an amount of particles + over `time` seconds. + * Returns an `id`, and -1 if adding didn't succeed + * Deprecated: `minetest.add_particlespawner(amount, time, + minpos, maxpos, + minvel, maxvel, + minacc, maxacc, + minexptime, maxexptime, + minsize, maxsize, + collisiondetection, texture, playername)` + +* `minetest.delete_particlespawner(id, player)` + * Delete `ParticleSpawner` with `id` (return value from + `minetest.add_particlespawner`). + * If playername is specified, only deletes on the player's client, + otherwise on all clients. + +Schematics +---------- + +* `minetest.create_schematic(p1, p2, probability_list, filename, slice_prob_list)` + * Create a schematic from the volume of map specified by the box formed by + p1 and p2. + * Apply the specified probability and per-node force-place to the specified + nodes according to the `probability_list`. + * `probability_list` is an array of tables containing two fields, `pos` + and `prob`. + * `pos` is the 3D vector specifying the absolute coordinates of the + node being modified, + * `prob` is an integer value from `0` to `255` that encodes + probability and per-node force-place. Probability has levels + 0-127, then 128 may be added to encode per-node force-place. + For probability stated as 0-255, divide by 2 and round down to + get values 0-127, then add 128 to apply per-node force-place. + * If there are two or more entries with the same pos value, the + last entry is used. + * If `pos` is not inside the box formed by `p1` and `p2`, it is + ignored. + * If `probability_list` equals `nil`, no probabilities are applied. + * Apply the specified probability to the specified horizontal slices + according to the `slice_prob_list`. + * `slice_prob_list` is an array of tables containing two fields, `ypos` + and `prob`. + * `ypos` indicates the y position of the slice with a probability + applied, the lowest slice being `ypos = 0`. + * If slice probability list equals `nil`, no slice probabilities + are applied. + * Saves schematic in the Minetest Schematic format to filename. + +* `minetest.place_schematic(pos, schematic, rotation, replacements, force_placement, flags)` + * Place the schematic specified by schematic (see [Schematic specifier]) at + `pos`. + * `rotation` can equal `"0"`, `"90"`, `"180"`, `"270"`, or `"random"`. + * If the `rotation` parameter is omitted, the schematic is not rotated. + * `replacements` = `{["old_name"] = "convert_to", ...}` + * `force_placement` is a boolean indicating whether nodes other than `air` + and `ignore` are replaced by the schematic. + * Returns nil if the schematic could not be loaded. + * **Warning**: Once you have loaded a schematic from a file, it will be + cached. Future calls will always use the cached version and the + replacement list defined for it, regardless of whether the file or the + replacement list parameter have changed. The only way to load the file + anew is to restart the server. + * `flags` is a flag field with the available flags: + * place_center_x + * place_center_y + * place_center_z + +* `minetest.place_schematic_on_vmanip(vmanip, pos, schematic, rotation, replacement, force_placement, flags)`: + * This function is analogous to minetest.place_schematic, but places a + schematic onto the specified VoxelManip object `vmanip` instead of the + map. + * Returns false if any part of the schematic was cut-off due to the + VoxelManip not containing the full area required, and true if the whole + schematic was able to fit. + * Returns nil if the schematic could not be loaded. + * After execution, any external copies of the VoxelManip contents are + invalidated. + * `flags` is a flag field with the available flags: + * place_center_x + * place_center_y + * place_center_z + +* `minetest.serialize_schematic(schematic, format, options)` + * Return the serialized schematic specified by schematic + (see [Schematic specifier]) + * in the `format` of either "mts" or "lua". + * "mts" - a string containing the binary MTS data used in the MTS file + format. + * "lua" - a string containing Lua code representing the schematic in table + format. + * `options` is a table containing the following optional parameters: + * If `lua_use_comments` is true and `format` is "lua", the Lua code + generated will have (X, Z) position comments for every X row + generated in the schematic data for easier reading. + * If `lua_num_indent_spaces` is a nonzero number and `format` is "lua", + the Lua code generated will use that number of spaces as indentation + instead of a tab character. + +* `minetest.read_schematic(schematic, options)` + * Returns a Lua table representing the schematic (see: [Schematic specifier]) + * `schematic` is the schematic to read (see: [Schematic specifier]) + * `options` is a table containing the following optional parameters: + * `write_yslice_prob`: string value: + * `none`: no `write_yslice_prob` table is inserted, + * `low`: only probabilities that are not 254 or 255 are written in + the `write_ylisce_prob` table, + * `all`: write all probabilities to the `write_yslice_prob` table. + * The default for this option is `all`. + * Any invalid value will be interpreted as `all`. + +HTTP Requests +------------- + +* `minetest.request_http_api()`: + * returns `HTTPApiTable` containing http functions if the calling mod has + been granted access by being listed in the `secure.http_mods` or + `secure.trusted_mods` setting, otherwise returns `nil`. + * The returned table contains the functions `fetch`, `fetch_async` and + `fetch_async_get` described below. + * Only works at init time and must be called from the mod's main scope + (not from a function). + * Function only exists if minetest server was built with cURL support. + * **DO NOT ALLOW ANY OTHER MODS TO ACCESS THE RETURNED TABLE, STORE IT IN + A LOCAL VARIABLE!** +* `HTTPApiTable.fetch(HTTPRequest req, callback)` + * Performs given request asynchronously and calls callback upon completion + * callback: `function(HTTPRequestResult res)` + * Use this HTTP function if you are unsure, the others are for advanced use +* `HTTPApiTable.fetch_async(HTTPRequest req)`: returns handle + * Performs given request asynchronously and returns handle for + `HTTPApiTable.fetch_async_get` +* `HTTPApiTable.fetch_async_get(handle)`: returns HTTPRequestResult + * Return response data for given asynchronous HTTP request + +Storage API +----------- + +* `minetest.get_mod_storage()`: + * returns reference to mod private `StorageRef` + * must be called during mod load time + +Misc. +----- + +* `minetest.get_connected_players()`: returns list of `ObjectRefs` +* `minetest.is_player(obj)`: boolean, whether `obj` is a player +* `minetest.player_exists(name)`: boolean, whether player exists + (regardless of online status) +* `minetest.hud_replace_builtin(name, hud_definition)` + * Replaces definition of a builtin hud element + * `name`: `"breath"` or `"health"` + * `hud_definition`: definition to replace builtin definition +* `minetest.send_join_message(player_name)` + * This function can be overridden by mods to change the join message. +* `minetest.send_leave_message(player_name, timed_out)` + * This function can be overridden by mods to change the leave message. +* `minetest.hash_node_position(pos)`: returns an 48-bit integer + * `pos`: table {x=number, y=number, z=number}, + * Gives a unique hash number for a node position (16+16+16=48bit) +* `minetest.get_position_from_hash(hash)`: returns a position + * Inverse transform of `minetest.hash_node_position` +* `minetest.get_item_group(name, group)`: returns a rating + * Get rating of a group of an item. (`0` means: not in group) +* `minetest.get_node_group(name, group)`: returns a rating + * Deprecated: An alias for the former. +* `minetest.raillike_group(name)`: returns a rating + * Returns rating of the connect_to_raillike group corresponding to name + * If name is not yet the name of a connect_to_raillike group, a new group + id is created, with that name. +* `minetest.get_content_id(name)`: returns an integer + * Gets the internal content ID of `name` +* `minetest.get_name_from_content_id(content_id)`: returns a string + * Gets the name of the content with that content ID +* `minetest.parse_json(string[, nullvalue])`: returns something + * Convert a string containing JSON data into the Lua equivalent + * `nullvalue`: returned in place of the JSON null; defaults to `nil` + * On success returns a table, a string, a number, a boolean or `nullvalue` + * On failure outputs an error message and returns `nil` + * Example: `parse_json("[10, {\"a\":false}]")`, returns `{10, {a = false}}` +* `minetest.write_json(data[, styled])`: returns a string or `nil` and an error + message. + * Convert a Lua table into a JSON string + * styled: Outputs in a human-readable format if this is set, defaults to + false. + * Unserializable things like functions and userdata will cause an error. + * **Warning**: JSON is more strict than the Lua table format. + 1. You can only use strings and positive integers of at least one as + keys. + 2. You can not mix string and integer keys. + This is due to the fact that JSON has two distinct array and object + values. + * Example: `write_json({10, {a = false}})`, + returns `'[10, {"a": false}]'` +* `minetest.serialize(table)`: returns a string + * Convert a table containing tables, strings, numbers, booleans and `nil`s + into string form readable by `minetest.deserialize` + * Example: `serialize({foo="bar"})`, returns `'return { ["foo"] = "bar" }'` +* `minetest.deserialize(string[, safe])`: returns a table + * Convert a string returned by `minetest.serialize` into a table + * `string` is loaded in an empty sandbox environment. + * Will load functions if safe is false or omitted. Although these functions + cannot directly access the global environment, they could bypass this + restriction with maliciously crafted Lua bytecode if mod security is + disabled. + * This function should not be used on untrusted data, regardless of the + value of `safe`. It is fine to serialize then deserialize user-provided + data, but directly providing user input to deserialize is always unsafe. + * Example: `deserialize('return { ["foo"] = "bar" }')`, + returns `{foo="bar"}` + * Example: `deserialize('print("foo")')`, returns `nil` + (function call fails), returns + `error:[string "print("foo")"]:1: attempt to call global 'print' (a nil value)` +* `minetest.compress(data, method, ...)`: returns `compressed_data` + * Compress a string of data. + * `method` is a string identifying the compression method to be used. + * Supported compression methods: + * Deflate (zlib): `"deflate"` + * `...` indicates method-specific arguments. Currently defined arguments + are: + * Deflate: `level` - Compression level, `0`-`9` or `nil`. +* `minetest.decompress(compressed_data, method, ...)`: returns data + * Decompress a string of data (using ZLib). + * See documentation on `minetest.compress()` for supported compression + methods. + * `...` indicates method-specific arguments. Currently, no methods use this +* `minetest.rgba(red, green, blue[, alpha])`: returns a string + * Each argument is a 8 Bit unsigned integer + * Returns the ColorString from rgb or rgba values + * Example: `minetest.rgba(10, 20, 30, 40)`, returns `"#0A141E28"` +* `minetest.encode_base64(string)`: returns string encoded in base64 + * Encodes a string in base64. +* `minetest.decode_base64(string)`: returns string or nil on failure + * Padding characters are only supported starting at version 5.4.0, where + 5.5.0 and newer perform proper checks. + * Decodes a string encoded in base64. +* `minetest.is_protected(pos, name)`: returns boolean + * Returning `true` restricts the player `name` from modifying (i.e. digging, + placing) the node at position `pos`. + * `name` will be `""` for non-players or unknown players. + * This function should be overridden by protection mods. It is highly + recommended to grant access to players with the `protection_bypass` privilege. + * Cache and call the old version of this function if the position is + not protected by the mod. This will allow using multiple protection mods. + * Example: + + local old_is_protected = minetest.is_protected + function minetest.is_protected(pos, name) + if mymod:position_protected_from(pos, name) then + return true + end + return old_is_protected(pos, name) + end +* `minetest.record_protection_violation(pos, name)` + * This function calls functions registered with + `minetest.register_on_protection_violation`. +* `minetest.is_creative_enabled(name)`: returns boolean + * Returning `true` means that Creative Mode is enabled for player `name`. + * `name` will be `""` for non-players or if the player is unknown. + * This function should be overridden by Creative Mode-related mods to + implement a per-player Creative Mode. + * By default, this function returns `true` if the setting + `creative_mode` is `true` and `false` otherwise. +* `minetest.is_area_protected(pos1, pos2, player_name, interval)` + * Returns the position of the first node that `player_name` may not modify + in the specified cuboid between `pos1` and `pos2`. + * Returns `false` if no protections were found. + * Applies `is_protected()` to a 3D lattice of points in the defined volume. + The points are spaced evenly throughout the volume and have a spacing + similar to, but no larger than, `interval`. + * All corners and edges of the defined volume are checked. + * `interval` defaults to 4. + * `interval` should be carefully chosen and maximised to avoid an excessive + number of points being checked. + * Like `minetest.is_protected`, this function may be extended or + overwritten by mods to provide a faster implementation to check the + cuboid for intersections. +* `minetest.rotate_and_place(itemstack, placer, pointed_thing[, infinitestacks, + orient_flags, prevent_after_place])` + * Attempt to predict the desired orientation of the facedir-capable node + defined by `itemstack`, and place it accordingly (on-wall, on the floor, + or hanging from the ceiling). + * `infinitestacks`: if `true`, the itemstack is not changed. Otherwise the + stacks are handled normally. + * `orient_flags`: Optional table containing extra tweaks to the placement code: + * `invert_wall`: if `true`, place wall-orientation on the ground and + ground-orientation on the wall. + * `force_wall` : if `true`, always place the node in wall orientation. + * `force_ceiling`: if `true`, always place on the ceiling. + * `force_floor`: if `true`, always place the node on the floor. + * `force_facedir`: if `true`, forcefully reset the facedir to north + when placing on the floor or ceiling. + * The first four options are mutually-exclusive; the last in the list + takes precedence over the first. + * `prevent_after_place` is directly passed to `minetest.item_place_node` + * Returns the new itemstack after placement +* `minetest.rotate_node(itemstack, placer, pointed_thing)` + * calls `rotate_and_place()` with `infinitestacks` set according to the state + of the creative mode setting, checks for "sneak" to set the `invert_wall` + parameter and `prevent_after_place` set to `true`. + +* `minetest.calculate_knockback(player, hitter, time_from_last_punch, + tool_capabilities, dir, distance, damage)` + * Returns the amount of knockback applied on the punched player. + * Arguments are equivalent to `register_on_punchplayer`, except the following: + * `distance`: distance between puncher and punched player + * This function can be overriden by mods that wish to modify this behaviour. + * You may want to cache and call the old function to allow multiple mods to + change knockback behaviour. + +* `minetest.forceload_block(pos[, transient])` + * forceloads the position `pos`. + * returns `true` if area could be forceloaded + * If `transient` is `false` or absent, the forceload will be persistent + (saved between server runs). If `true`, the forceload will be transient + (not saved between server runs). + +* `minetest.forceload_free_block(pos[, transient])` + * stops forceloading the position `pos` + * If `transient` is `false` or absent, frees a persistent forceload. + If `true`, frees a transient forceload. + +* `minetest.compare_block_status(pos, condition)` + * Checks whether the mapblock at positition `pos` is in the wanted condition. + * `condition` may be one of the following values: + * `"unknown"`: not in memory + * `"emerging"`: in the queue for loading from disk or generating + * `"loaded"`: in memory but inactive (no ABMs are executed) + * `"active"`: in memory and active + * Other values are reserved for future functionality extensions + * Return value, the comparison status: + * `false`: Mapblock does not fulfil the wanted condition + * `true`: Mapblock meets the requirement + * `nil`: Unsupported `condition` value + +* `minetest.request_insecure_environment()`: returns an environment containing + insecure functions if the calling mod has been listed as trusted in the + `secure.trusted_mods` setting or security is disabled, otherwise returns + `nil`. + * Only works at init time and must be called from the mod's main scope + (ie: the init.lua of the mod, not from another Lua file or within a function). + * **DO NOT ALLOW ANY OTHER MODS TO ACCESS THE RETURNED ENVIRONMENT, STORE + IT IN A LOCAL VARIABLE!** + +* `minetest.global_exists(name)` + * Checks if a global variable has been set, without triggering a warning. + +Global objects +-------------- + +* `minetest.env`: `EnvRef` of the server environment and world. + * Any function in the minetest namespace can be called using the syntax + `minetest.env:somefunction(somearguments)` + instead of `minetest.somefunction(somearguments)` + * Deprecated, but support is not to be dropped soon + +Global tables +------------- + +### Registered definition tables + +* `minetest.registered_items` + * Map of registered items, indexed by name +* `minetest.registered_nodes` + * Map of registered node definitions, indexed by name +* `minetest.registered_craftitems` + * Map of registered craft item definitions, indexed by name +* `minetest.registered_tools` + * Map of registered tool definitions, indexed by name +* `minetest.registered_entities` + * Map of registered entity prototypes, indexed by name + * Values in this table may be modified directly. + Note: changes to initial properties will only affect entities spawned afterwards, + as they are only read when spawning. +* `minetest.object_refs` + * Map of object references, indexed by active object id +* `minetest.luaentities` + * Map of Lua entities, indexed by active object id +* `minetest.registered_abms` + * List of ABM definitions +* `minetest.registered_lbms` + * List of LBM definitions +* `minetest.registered_aliases` + * Map of registered aliases, indexed by name +* `minetest.registered_ores` + * Map of registered ore definitions, indexed by the `name` field. + * If `name` is nil, the key is the object handle returned by + `minetest.register_ore`. +* `minetest.registered_biomes` + * Map of registered biome definitions, indexed by the `name` field. + * If `name` is nil, the key is the object handle returned by + `minetest.register_biome`. +* `minetest.registered_decorations` + * Map of registered decoration definitions, indexed by the `name` field. + * If `name` is nil, the key is the object handle returned by + `minetest.register_decoration`. +* `minetest.registered_schematics` + * Map of registered schematic definitions, indexed by the `name` field. + * If `name` is nil, the key is the object handle returned by + `minetest.register_schematic`. +* `minetest.registered_chatcommands` + * Map of registered chat command definitions, indexed by name +* `minetest.registered_privileges` + * Map of registered privilege definitions, indexed by name + * Registered privileges can be modified directly in this table. + +### Registered callback tables + +All callbacks registered with [Global callback registration functions] are added +to corresponding `minetest.registered_*` tables. + + + + +Class reference +=============== + +Sorted alphabetically. + +`AreaStore` +----------- + +AreaStore is a data structure to calculate intersections of 3D cuboid volumes +and points. The `data` field (string) may be used to store and retrieve any +mod-relevant information to the specified area. + +Despite its name, mods must take care of persisting AreaStore data. They may +use the provided load and write functions for this. + + +### Methods + +* `AreaStore(type_name)` + * Returns a new AreaStore instance + * `type_name`: optional, forces the internally used API. + * Possible values: `"LibSpatial"` (default). + * When other values are specified, or SpatialIndex is not available, + the custom Minetest functions are used. +* `get_area(id, include_corners, include_data)` + * Returns the area information about the specified ID. + * Returned values are either of these: + + nil -- Area not found + true -- Without `include_corners` and `include_data` + { + min = pos, max = pos -- `include_corners == true` + data = string -- `include_data == true` + } + +* `get_areas_for_pos(pos, include_corners, include_data)` + * Returns all areas as table, indexed by the area ID. + * Table values: see `get_area`. +* `get_areas_in_area(corner1, corner2, accept_overlap, include_corners, include_data)` + * Returns all areas that contain all nodes inside the area specified by` + `corner1 and `corner2` (inclusive). + * `accept_overlap`: if `true`, areas are returned that have nodes in + common (intersect) with the specified area. + * Returns the same values as `get_areas_for_pos`. +* `insert_area(corner1, corner2, data, [id])`: inserts an area into the store. + * Returns the new area's ID, or nil if the insertion failed. + * The (inclusive) positions `corner1` and `corner2` describe the area. + * `data` is a string stored with the area. + * `id` (optional): will be used as the internal area ID if it is an unique + number between 0 and 2^32-2. +* `reserve(count)` + * Requires SpatialIndex, no-op function otherwise. + * Reserves resources for `count` many contained areas to improve + efficiency when working with many area entries. Additional areas can still + be inserted afterwards at the usual complexity. +* `remove_area(id)`: removes the area with the given id from the store, returns + success. +* `set_cache_params(params)`: sets params for the included prefiltering cache. + Calling invalidates the cache, so that its elements have to be newly + generated. + * `params` is a table with the following fields: + + enabled = boolean, -- Whether to enable, default true + block_radius = int, -- The radius (in nodes) of the areas the cache + -- generates prefiltered lists for, minimum 16, + -- default 64 + limit = int, -- The cache size, minimum 20, default 1000 +* `to_string()`: Experimental. Returns area store serialized as a (binary) + string. +* `to_file(filename)`: Experimental. Like `to_string()`, but writes the data to + a file. +* `from_string(str)`: Experimental. Deserializes string and loads it into the + AreaStore. + Returns success and, optionally, an error message. +* `from_file(filename)`: Experimental. Like `from_string()`, but reads the data + from a file. + +`InvRef` +-------- + +An `InvRef` is a reference to an inventory. + +### Methods + +* `is_empty(listname)`: return `true` if list is empty +* `get_size(listname)`: get size of a list +* `set_size(listname, size)`: set size of a list + * returns `false` on error (e.g. invalid `listname` or `size`) +* `get_width(listname)`: get width of a list +* `set_width(listname, width)`: set width of list; currently used for crafting +* `get_stack(listname, i)`: get a copy of stack index `i` in list +* `set_stack(listname, i, stack)`: copy `stack` to index `i` in list +* `get_list(listname)`: return full list (list of `ItemStack`s) +* `set_list(listname, list)`: set full list (size will not change) +* `get_lists()`: returns table that maps listnames to inventory lists +* `set_lists(lists)`: sets inventory lists (size will not change) +* `add_item(listname, stack)`: add item somewhere in list, returns leftover + `ItemStack`. +* `room_for_item(listname, stack):` returns `true` if the stack of items + can be fully added to the list +* `contains_item(listname, stack, [match_meta])`: returns `true` if + the stack of items can be fully taken from the list. + If `match_meta` is false, only the items' names are compared + (default: `false`). +* `remove_item(listname, stack)`: take as many items as specified from the + list, returns the items that were actually removed (as an `ItemStack`) + -- note that any item metadata is ignored, so attempting to remove a specific + unique item this way will likely remove the wrong one -- to do that use + `set_stack` with an empty `ItemStack`. +* `get_location()`: returns a location compatible to + `minetest.get_inventory(location)`. + * returns `{type="undefined"}` in case location is not known + +### Callbacks + +Detached & nodemeta inventories provide the following callbacks for move actions: + +#### Before + +The `allow_*` callbacks return how many items can be moved. + +* `allow_move`/`allow_metadata_inventory_move`: Moving items in the inventory +* `allow_take`/`allow_metadata_inventory_take`: Taking items from the inventory +* `allow_put`/`allow_metadata_inventory_put`: Putting items to the inventory + +#### After + +The `on_*` callbacks are called after the items have been placed in the inventories. + +* `on_move`/`on_metadata_inventory_move`: Moving items in the inventory +* `on_take`/`on_metadata_inventory_take`: Taking items from the inventory +* `on_put`/`on_metadata_inventory_put`: Putting items to the inventory + +#### Swapping + +When a player tries to put an item to a place where another item is, the items are *swapped*. +This means that all callbacks will be called twice (once for each action). + +`ItemStack` +----------- + +An `ItemStack` is a stack of items. + +It can be created via `ItemStack(x)`, where x is an `ItemStack`, +an itemstring, a table or `nil`. + +### Methods + +* `is_empty()`: returns `true` if stack is empty. +* `get_name()`: returns item name (e.g. `"default:stone"`). +* `set_name(item_name)`: returns a boolean indicating whether the item was + cleared. +* `get_count()`: Returns number of items on the stack. +* `set_count(count)`: returns a boolean indicating whether the item was cleared + * `count`: number, unsigned 16 bit integer +* `get_wear()`: returns tool wear (`0`-`65535`), `0` for non-tools. +* `set_wear(wear)`: returns boolean indicating whether item was cleared + * `wear`: number, unsigned 16 bit integer +* `get_meta()`: returns ItemStackMetaRef. See section for more details +* `get_metadata()`: (DEPRECATED) Returns metadata (a string attached to an item + stack). +* `set_metadata(metadata)`: (DEPRECATED) Returns true. +* `get_description()`: returns the description shown in inventory list tooltips. + * The engine uses this when showing item descriptions in tooltips. + * Fields for finding the description, in order: + * `description` in item metadata (See [Item Metadata].) + * `description` in item definition + * item name +* `get_short_description()`: returns the short description or nil. + * Unlike the description, this does not include new lines. + * Fields for finding the short description, in order: + * `short_description` in item metadata (See [Item Metadata].) + * `short_description` in item definition + * first line of the description (From item meta or def, see `get_description()`.) + * Returns nil if none of the above are set +* `clear()`: removes all items from the stack, making it empty. +* `replace(item)`: replace the contents of this stack. + * `item` can also be an itemstring or table. +* `to_string()`: returns the stack in itemstring form. +* `to_table()`: returns the stack in Lua table form. +* `get_stack_max()`: returns the maximum size of the stack (depends on the + item). +* `get_free_space()`: returns `get_stack_max() - get_count()`. +* `is_known()`: returns `true` if the item name refers to a defined item type. +* `get_definition()`: returns the item definition table. +* `get_tool_capabilities()`: returns the digging properties of the item, + or those of the hand if none are defined for this item type +* `add_wear(amount)` + * Increases wear by `amount` if the item is a tool, otherwise does nothing + * Valid `amount` range is [0,65536] + * `amount`: number, integer +* `add_wear_by_uses(max_uses)` + * Increases wear in such a way that, if only this function is called, + the item breaks after `max_uses` times + * Valid `max_uses` range is [0,65536] + * Does nothing if item is not a tool or if `max_uses` is 0 +* `add_item(item)`: returns leftover `ItemStack` + * Put some item or stack onto this stack +* `item_fits(item)`: returns `true` if item or stack can be fully added to + this one. +* `take_item(n)`: returns taken `ItemStack` + * Take (and remove) up to `n` items from this stack + * `n`: number, default: `1` +* `peek_item(n)`: returns taken `ItemStack` + * Copy (don't remove) up to `n` items from this stack + * `n`: number, default: `1` + +`ItemStackMetaRef` +------------------ + +ItemStack metadata: reference extra data and functionality stored in a stack. +Can be obtained via `item:get_meta()`. + +### Methods + +* All methods in MetaDataRef +* `set_tool_capabilities([tool_capabilities])` + * Overrides the item's tool capabilities + * A nil value will clear the override data and restore the original + behavior. + +`MetaDataRef` +------------- + +Base class used by [`StorageRef`], [`NodeMetaRef`], [`ItemStackMetaRef`], +and [`PlayerMetaRef`]. + +### Methods + +* `contains(key)`: Returns true if key present, otherwise false. + * Returns `nil` when the MetaData is inexistent. +* `get(key)`: Returns `nil` if key not present, else the stored string. +* `set_string(key, value)`: Value of `""` will delete the key. +* `get_string(key)`: Returns `""` if key not present. +* `set_int(key, value)` +* `get_int(key)`: Returns `0` if key not present. +* `set_float(key, value)` +* `get_float(key)`: Returns `0` if key not present. +* `to_table()`: returns `nil` or a table with keys: + * `fields`: key-value storage + * `inventory`: `{list1 = {}, ...}}` (NodeMetaRef only) +* `from_table(nil or {})` + * Any non-table value will clear the metadata + * See [Node Metadata] for an example + * returns `true` on success +* `equals(other)` + * returns `true` if this metadata has the same key-value pairs as `other` + +`ModChannel` +------------ + +An interface to use mod channels on client and server + +### Methods + +* `leave()`: leave the mod channel. + * Server leaves channel `channel_name`. + * No more incoming or outgoing messages can be sent to this channel from + server mods. + * This invalidate all future object usage. + * Ensure you set mod_channel to nil after that to free Lua resources. +* `is_writeable()`: returns true if channel is writeable and mod can send over + it. +* `send_all(message)`: Send `message` though the mod channel. + * If mod channel is not writeable or invalid, message will be dropped. + * Message size is limited to 65535 characters by protocol. + +`NodeMetaRef` +------------- + +Node metadata: reference extra data and functionality stored in a node. +Can be obtained via `minetest.get_meta(pos)`. + +### Methods + +* All methods in MetaDataRef +* `get_inventory()`: returns `InvRef` +* `mark_as_private(name or {name1, name2, ...})`: Mark specific vars as private + This will prevent them from being sent to the client. Note that the "private" + status will only be remembered if an associated key-value pair exists, + meaning it's best to call this when initializing all other meta (e.g. + `on_construct`). + +`NodeTimerRef` +-------------- + +Node Timers: a high resolution persistent per-node timer. +Can be gotten via `minetest.get_node_timer(pos)`. + +### Methods + +* `set(timeout,elapsed)` + * set a timer's state + * `timeout` is in seconds, and supports fractional values (0.1 etc) + * `elapsed` is in seconds, and supports fractional values (0.1 etc) + * will trigger the node's `on_timer` function after `(timeout - elapsed)` + seconds. +* `start(timeout)` + * start a timer + * equivalent to `set(timeout,0)` +* `stop()` + * stops the timer +* `get_timeout()`: returns current timeout in seconds + * if `timeout` equals `0`, timer is inactive +* `get_elapsed()`: returns current elapsed time in seconds + * the node's `on_timer` function will be called after `(timeout - elapsed)` + seconds. +* `is_started()`: returns boolean state of timer + * returns `true` if timer is started, otherwise `false` + +`ObjectRef` +----------- + +Moving things in the game are generally these. +This is basically a reference to a C++ `ServerActiveObject`. + +### Advice on handling `ObjectRefs` + +When you receive an `ObjectRef` as a callback argument or from another API +function, it is possible to store the reference somewhere and keep it around. +It will keep functioning until the object is unloaded or removed. + +However, doing this is **NOT** recommended as there is (intentionally) no method +to test if a previously acquired `ObjectRef` is still valid. +Instead, `ObjectRefs` should be "let go" of as soon as control is returned from +Lua back to the engine. +Doing so is much less error-prone and you will never need to wonder if the +object you are working with still exists. + +### Attachments + +It is possible to attach objects to other objects (`set_attach` method). + +When an object is attached, it is positioned relative to the parent's position +and rotation. `get_pos` and `get_rotation` will always return the parent's +values and changes via their setter counterparts are ignored. + +To change position or rotation call `set_attach` again with the new values. + +**Note**: Just like model dimensions, the relative position in `set_attach` +must be multiplied by 10 compared to world positions. + +It is also possible to attach to a bone of the parent object. In that case the +child will follow movement and rotation of that bone. + +### Methods + +* `get_pos()`: returns `{x=num, y=num, z=num}` +* `set_pos(pos)`: `pos`=`{x=num, y=num, z=num}` +* `get_velocity()`: returns the velocity, a vector. +* `add_velocity(vel)` + * `vel` is a vector, e.g. `{x=0.0, y=2.3, z=1.0}` + * In comparison to using get_velocity, adding the velocity and then using + set_velocity, add_velocity is supposed to avoid synchronization problems. + Additionally, players also do not support set_velocity. + * If a player: + * Does not apply during free_move. + * Note that since the player speed is normalized at each move step, + increasing e.g. Y velocity beyond what would usually be achieved + (see: physics overrides) will cause existing X/Z velocity to be reduced. + * Example: `add_velocity({x=0, y=6.5, z=0})` is equivalent to + pressing the jump key (assuming default settings) +* `move_to(pos, continuous=false)` + * Does an interpolated move for Lua entities for visually smooth transitions. + * If `continuous` is true, the Lua entity will not be moved to the current + position before starting the interpolated move. + * For players this does the same as `set_pos`,`continuous` is ignored. +* `punch(puncher, time_from_last_punch, tool_capabilities, direction)` + * `puncher` = another `ObjectRef`, + * `time_from_last_punch` = time since last punch action of the puncher + * `direction`: can be `nil` +* `right_click(clicker)`; `clicker` is another `ObjectRef` +* `get_hp()`: returns number of health points +* `set_hp(hp, reason)`: set number of health points + * See reason in register_on_player_hpchange + * Is limited to the range of 0 ... 65535 (2^16 - 1) + * For players: HP are also limited by `hp_max` specified in object properties +* `get_inventory()`: returns an `InvRef` for players, otherwise returns `nil` +* `get_wield_list()`: returns the name of the inventory list the wielded item + is in. +* `get_wield_index()`: returns the index of the wielded item +* `get_wielded_item()`: returns an `ItemStack` +* `set_wielded_item(item)`: replaces the wielded item, returns `true` if + successful. +* `set_armor_groups({group1=rating, group2=rating, ...})` +* `get_armor_groups()`: returns a table with the armor group ratings +* `set_animation(frame_range, frame_speed, frame_blend, frame_loop)` + * `frame_range`: table {x=num, y=num}, default: `{x=1, y=1}` + * `frame_speed`: number, default: `15.0` + * `frame_blend`: number, default: `0.0` + * `frame_loop`: boolean, default: `true` +* `get_animation()`: returns `range`, `frame_speed`, `frame_blend` and + `frame_loop`. +* `set_animation_frame_speed(frame_speed)` + * `frame_speed`: number, default: `15.0` +* `set_attach(parent[, bone, position, rotation, forced_visible])` + * `parent`: `ObjectRef` to attach to + * `bone`: default `""` (the root bone) + * `position`: relative position, default `{x=0, y=0, z=0}` + * `rotation`: relative rotation in degrees, default `{x=0, y=0, z=0}` + * `forced_visible`: Boolean to control whether the attached entity + should appear in first person, default `false`. + * Please also read the [Attachments] section above. + * This command may fail silently (do nothing) when it would result + in circular attachments. +* `get_attach()`: returns parent, bone, position, rotation, forced_visible, + or nil if it isn't attached. +* `get_children()`: returns a list of ObjectRefs that are attached to the + object. +* `set_detach()` +* `set_bone_position([bone, position, rotation])` + * `bone`: string. Default is `""`, the root bone + * `position`: `{x=num, y=num, z=num}`, relative, `default {x=0, y=0, z=0}` + * `rotation`: `{x=num, y=num, z=num}`, default `{x=0, y=0, z=0}` +* `get_bone_position(bone)`: returns position and rotation of the bone +* `set_properties(object property table)` +* `get_properties()`: returns object property table +* `is_player()`: returns true for players, false otherwise +* `get_nametag_attributes()` + * returns a table with the attributes of the nametag of an object + * { + text = "", + color = {a=0..255, r=0..255, g=0..255, b=0..255}, + bgcolor = {a=0..255, r=0..255, g=0..255, b=0..255}, + } +* `set_nametag_attributes(attributes)` + * sets the attributes of the nametag of an object + * `attributes`: + { + text = "My Nametag", + color = ColorSpec, + -- ^ Text color + bgcolor = ColorSpec or false, + -- ^ Sets background color of nametag + -- `false` will cause the background to be set automatically based on user settings + -- Default: false + } + +#### Lua entity only (no-op for other objects) + +* `remove()`: remove object + * The object is removed after returning from Lua. However the `ObjectRef` + itself instantly becomes unusable with all further method calls having + no effect and returning `nil`. +* `set_velocity(vel)` + * `vel` is a vector, e.g. `{x=0.0, y=2.3, z=1.0}` +* `set_acceleration(acc)` + * `acc` is a vector +* `get_acceleration()`: returns the acceleration, a vector +* `set_rotation(rot)` + * `rot` is a vector (radians). X is pitch (elevation), Y is yaw (heading) + and Z is roll (bank). +* `get_rotation()`: returns the rotation, a vector (radians) +* `set_yaw(yaw)`: sets the yaw in radians (heading). +* `get_yaw()`: returns number in radians +* `set_texture_mod(mod)` + * Set a texture modifier to the base texture, for sprites and meshes. + * When calling `set_texture_mod` again, the previous one is discarded. + * `mod` the texture modifier. See [Texture modifiers]. +* `get_texture_mod()` returns current texture modifier +* `set_sprite(start_frame, num_frames, framelength, select_x_by_camera)` + * Specifies and starts a sprite animation + * Animations iterate along the frame `y` position. + * `start_frame`: {x=column number, y=row number}, the coordinate of the + first frame, default: `{x=0, y=0}` + * `num_frames`: Total frames in the texture, default: `1` + * `framelength`: Time per animated frame in seconds, default: `0.2` + * `select_x_by_camera`: Only for visual = `sprite`. Changes the frame `x` + position according to the view direction. default: `false`. + * First column: subject facing the camera + * Second column: subject looking to the left + * Third column: subject backing the camera + * Fourth column: subject looking to the right + * Fifth column: subject viewed from above + * Sixth column: subject viewed from below +* `get_entity_name()` (**Deprecated**: Will be removed in a future version, use the field `self.name` instead) +* `get_luaentity()` + +#### Player only (no-op for other objects) + +* `get_player_name()`: returns `""` if is not a player +* `get_player_velocity()`: **DEPRECATED**, use get_velocity() instead. + table {x, y, z} representing the player's instantaneous velocity in nodes/s +* `add_player_velocity(vel)`: **DEPRECATED**, use add_velocity(vel) instead. +* `get_look_dir()`: get camera direction as a unit vector +* `get_look_vertical()`: pitch in radians + * Angle ranges between -pi/2 and pi/2, which are straight up and down + respectively. +* `get_look_horizontal()`: yaw in radians + * Angle is counter-clockwise from the +z direction. +* `set_look_vertical(radians)`: sets look pitch + * radians: Angle from looking forward, where positive is downwards. +* `set_look_horizontal(radians)`: sets look yaw + * radians: Angle from the +z direction, where positive is counter-clockwise. +* `get_look_pitch()`: pitch in radians - Deprecated as broken. Use + `get_look_vertical`. + * Angle ranges between -pi/2 and pi/2, which are straight down and up + respectively. +* `get_look_yaw()`: yaw in radians - Deprecated as broken. Use + `get_look_horizontal`. + * Angle is counter-clockwise from the +x direction. +* `set_look_pitch(radians)`: sets look pitch - Deprecated. Use + `set_look_vertical`. +* `set_look_yaw(radians)`: sets look yaw - Deprecated. Use + `set_look_horizontal`. +* `get_breath()`: returns player's breath +* `set_breath(value)`: sets player's breath + * values: + * `0`: player is drowning + * max: bubbles bar is not shown + * See [Object properties] for more information + * Is limited to range 0 ... 65535 (2^16 - 1) +* `set_fov(fov, is_multiplier, transition_time)`: Sets player's FOV + * `fov`: FOV value. + * `is_multiplier`: Set to `true` if the FOV value is a multiplier. + Defaults to `false`. + * `transition_time`: If defined, enables smooth FOV transition. + Interpreted as the time (in seconds) to reach target FOV. + If set to 0, FOV change is instantaneous. Defaults to 0. + * Set `fov` to 0 to clear FOV override. +* `get_fov()`: Returns the following: + * Server-sent FOV value. Returns 0 if an FOV override doesn't exist. + * Boolean indicating whether the FOV value is a multiplier. + * Time (in seconds) taken for the FOV transition. Set by `set_fov`. +* `set_attribute(attribute, value)`: DEPRECATED, use get_meta() instead + * Sets an extra attribute with value on player. + * `value` must be a string, or a number which will be converted to a + string. + * If `value` is `nil`, remove attribute from player. +* `get_attribute(attribute)`: DEPRECATED, use get_meta() instead + * Returns value (a string) for extra attribute. + * Returns `nil` if no attribute found. +* `get_meta()`: Returns a PlayerMetaRef. +* `set_inventory_formspec(formspec)` + * Redefine player's inventory form + * Should usually be called in `on_joinplayer` + * If `formspec` is `""`, the player's inventory is disabled. +* `get_inventory_formspec()`: returns a formspec string +* `set_formspec_prepend(formspec)`: + * the formspec string will be added to every formspec shown to the user, + except for those with a no_prepend[] tag. + * This should be used to set style elements such as background[] and + bgcolor[], any non-style elements (eg: label) may result in weird behaviour. + * Only affects formspecs shown after this is called. +* `get_formspec_prepend(formspec)`: returns a formspec string. +* `get_player_control()`: returns table with player pressed keys + * The table consists of fields with the following boolean values + representing the pressed keys: `up`, `down`, `left`, `right`, `jump`, + `aux1`, `sneak`, `dig`, `place`, `LMB`, `RMB`, and `zoom`. + * The fields `LMB` and `RMB` are equal to `dig` and `place` respectively, + and exist only to preserve backwards compatibility. + * Returns an empty table `{}` if the object is not a player. +* `get_player_control_bits()`: returns integer with bit packed player pressed + keys. + * Bits: + * 0 - up + * 1 - down + * 2 - left + * 3 - right + * 4 - jump + * 5 - aux1 + * 6 - sneak + * 7 - dig + * 8 - place + * 9 - zoom + * Returns `0` (no bits set) if the object is not a player. +* `set_physics_override(override_table)` + * `override_table` is a table with the following fields: + * `speed`: multiplier to default walking speed value (default: `1`) + * `jump`: multiplier to default jump value (default: `1`) + * `gravity`: multiplier to default gravity value (default: `1`) + * `sneak`: whether player can sneak (default: `true`) + * `sneak_glitch`: whether player can use the new move code replications + of the old sneak side-effects: sneak ladders and 2 node sneak jump + (default: `false`) + * `new_move`: use new move/sneak code. When `false` the exact old code + is used for the specific old sneak behaviour (default: `true`) +* `get_physics_override()`: returns the table given to `set_physics_override` +* `hud_add(hud definition)`: add a HUD element described by HUD def, returns ID + number on success +* `hud_remove(id)`: remove the HUD element of the specified id +* `hud_change(id, stat, value)`: change a value of a previously added HUD + element. + * `stat` supports the same keys as in the hud definition table except for + `"hud_elem_type"`. +* `hud_get(id)`: gets the HUD element definition structure of the specified ID +* `hud_set_flags(flags)`: sets specified HUD flags of player. + * `flags`: A table with the following fields set to boolean values + * `hotbar` + * `healthbar` + * `crosshair` + * `wielditem` + * `breathbar` + * `minimap`: Modifies the client's permission to view the minimap. + The client may locally elect to not view the minimap. + * `minimap_radar`: is only usable when `minimap` is true + * `basic_debug`: Allow showing basic debug info that might give a gameplay advantage. + This includes map seed, player position, look direction, the pointed node and block bounds. + Does not affect players with the `debug` privilege. + * If a flag equals `nil`, the flag is not modified +* `hud_get_flags()`: returns a table of player HUD flags with boolean values. + * See `hud_set_flags` for a list of flags that can be toggled. +* `hud_set_hotbar_itemcount(count)`: sets number of items in builtin hotbar + * `count`: number of items, must be between `1` and `32` +* `hud_get_hotbar_itemcount`: returns number of visible items +* `hud_set_hotbar_image(texturename)` + * sets background image for hotbar +* `hud_get_hotbar_image`: returns texturename +* `hud_set_hotbar_selected_image(texturename)` + * sets image for selected item of hotbar +* `hud_get_hotbar_selected_image`: returns texturename +* `set_minimap_modes({mode, mode, ...}, selected_mode)` + * Overrides the available minimap modes (and toggle order), and changes the + selected mode. + * `mode` is a table consisting of up to four fields: + * `type`: Available type: + * `off`: Minimap off + * `surface`: Minimap in surface mode + * `radar`: Minimap in radar mode + * `texture`: Texture to be displayed instead of terrain map + (texture is centered around 0,0 and can be scaled). + Texture size is limited to 512 x 512 pixel. + * `label`: Optional label to display on minimap mode toggle + The translation must be handled within the mod. + * `size`: Sidelength or diameter, in number of nodes, of the terrain + displayed in minimap + * `texture`: Only for texture type, name of the texture to display + * `scale`: Only for texture type, scale of the texture map in nodes per + pixel (for example a `scale` of 2 means each pixel represents a 2x2 + nodes square) + * `selected_mode` is the mode index to be selected after modes have been changed + (0 is the first mode). +* `set_sky(sky_parameters)` + * The presence of the function `set_sun`, `set_moon` or `set_stars` indicates + whether `set_sky` accepts this format. Check the legacy format otherwise. + * Passing no arguments resets the sky to its default values. + * `sky_parameters` is a table with the following optional fields: + * `base_color`: ColorSpec, changes fog in "skybox" and "plain". + (default: `#ffffff`) + * `type`: Available types: + * `"regular"`: Uses 0 textures, `base_color` ignored + * `"skybox"`: Uses 6 textures, `base_color` used as fog. + * `"plain"`: Uses 0 textures, `base_color` used as both fog and sky. + (default: `"regular"`) + * `textures`: A table containing up to six textures in the following + order: Y+ (top), Y- (bottom), X- (west), X+ (east), Z+ (north), Z- (south). + * `clouds`: Boolean for whether clouds appear. (default: `true`) + * `sky_color`: A table used in `"regular"` type only, containing the + following values (alpha is ignored): + * `day_sky`: ColorSpec, for the top half of the sky during the day. + (default: `#61b5f5`) + * `day_horizon`: ColorSpec, for the bottom half of the sky during the day. + (default: `#90d3f6`) + * `dawn_sky`: ColorSpec, for the top half of the sky during dawn/sunset. + (default: `#b4bafa`) + The resulting sky color will be a darkened version of the ColorSpec. + Warning: The darkening of the ColorSpec is subject to change. + * `dawn_horizon`: ColorSpec, for the bottom half of the sky during dawn/sunset. + (default: `#bac1f0`) + The resulting sky color will be a darkened version of the ColorSpec. + Warning: The darkening of the ColorSpec is subject to change. + * `night_sky`: ColorSpec, for the top half of the sky during the night. + (default: `#006bff`) + The resulting sky color will be a dark version of the ColorSpec. + Warning: The darkening of the ColorSpec is subject to change. + * `night_horizon`: ColorSpec, for the bottom half of the sky during the night. + (default: `#4090ff`) + The resulting sky color will be a dark version of the ColorSpec. + Warning: The darkening of the ColorSpec is subject to change. + * `indoors`: ColorSpec, for when you're either indoors or underground. + (default: `#646464`) + * `fog_sun_tint`: ColorSpec, changes the fog tinting for the sun + at sunrise and sunset. (default: `#f47d1d`) + * `fog_moon_tint`: ColorSpec, changes the fog tinting for the moon + at sunrise and sunset. (default: `#7f99cc`) + * `fog_tint_type`: string, changes which mode the directional fog + abides by, `"custom"` uses `sun_tint` and `moon_tint`, while + `"default"` uses the classic Minetest sun and moon tinting. + Will use tonemaps, if set to `"default"`. (default: `"default"`) +* `set_sky(base_color, type, {texture names}, clouds)` + * Deprecated. Use `set_sky(sky_parameters)` + * `base_color`: ColorSpec, defaults to white + * `type`: Available types: + * `"regular"`: Uses 0 textures, `bgcolor` ignored + * `"skybox"`: Uses 6 textures, `bgcolor` used + * `"plain"`: Uses 0 textures, `bgcolor` used + * `clouds`: Boolean for whether clouds appear in front of `"skybox"` or + `"plain"` custom skyboxes (default: `true`) +* `get_sky(as_table)`: + * `as_table`: boolean that determines whether the deprecated version of this + function is being used. + * `true` returns a table containing sky parameters as defined in `set_sky(sky_parameters)`. + * Deprecated: `false` or `nil` returns base_color, type, table of textures, + clouds. +* `get_sky_color()`: + * Deprecated: Use `get_sky(as_table)` instead. + * returns a table with the `sky_color` parameters as in `set_sky`. +* `set_sun(sun_parameters)`: + * Passing no arguments resets the sun to its default values. + * `sun_parameters` is a table with the following optional fields: + * `visible`: Boolean for whether the sun is visible. + (default: `true`) + * `texture`: A regular texture for the sun. Setting to `""` + will re-enable the mesh sun. (default: "sun.png", if it exists) + * `tonemap`: A 512x1 texture containing the tonemap for the sun + (default: `"sun_tonemap.png"`) + * `sunrise`: A regular texture for the sunrise texture. + (default: `"sunrisebg.png"`) + * `sunrise_visible`: Boolean for whether the sunrise texture is visible. + (default: `true`) + * `scale`: Float controlling the overall size of the sun. (default: `1`) +* `get_sun()`: returns a table with the current sun parameters as in + `set_sun`. +* `set_moon(moon_parameters)`: + * Passing no arguments resets the moon to its default values. + * `moon_parameters` is a table with the following optional fields: + * `visible`: Boolean for whether the moon is visible. + (default: `true`) + * `texture`: A regular texture for the moon. Setting to `""` + will re-enable the mesh moon. (default: `"moon.png"`, if it exists) + Note: Relative to the sun, the moon texture is rotated by 180°. + You can use the `^[transformR180` texture modifier to achieve the same orientation. + * `tonemap`: A 512x1 texture containing the tonemap for the moon + (default: `"moon_tonemap.png"`) + * `scale`: Float controlling the overall size of the moon (default: `1`) +* `get_moon()`: returns a table with the current moon parameters as in + `set_moon`. +* `set_stars(star_parameters)`: + * Passing no arguments resets stars to their default values. + * `star_parameters` is a table with the following optional fields: + * `visible`: Boolean for whether the stars are visible. + (default: `true`) + * `day_opacity`: Float for maximum opacity of stars at day. + No effect if `visible` is false. + (default: 0.0; maximum: 1.0; minimum: 0.0) + * `count`: Integer number to set the number of stars in + the skybox. Only applies to `"skybox"` and `"regular"` sky types. + (default: `1000`) + * `star_color`: ColorSpec, sets the colors of the stars, + alpha channel is used to set overall star brightness. + (default: `#ebebff69`) + * `scale`: Float controlling the overall size of the stars (default: `1`) +* `get_stars()`: returns a table with the current stars parameters as in + `set_stars`. +* `set_clouds(cloud_parameters)`: set cloud parameters + * Passing no arguments resets clouds to their default values. + * `cloud_parameters` is a table with the following optional fields: + * `density`: from `0` (no clouds) to `1` (full clouds) (default `0.4`) + * `color`: basic cloud color with alpha channel, ColorSpec + (default `#fff0f0e5`). + * `ambient`: cloud color lower bound, use for a "glow at night" effect. + ColorSpec (alpha ignored, default `#000000`) + * `height`: cloud height, i.e. y of cloud base (default per conf, + usually `120`) + * `thickness`: cloud thickness in nodes (default `16`) + * `speed`: 2D cloud speed + direction in nodes per second + (default `{x=0, z=-2}`). +* `get_clouds()`: returns a table with the current cloud parameters as in + `set_clouds`. +* `override_day_night_ratio(ratio or nil)` + * `0`...`1`: Overrides day-night ratio, controlling sunlight to a specific + amount. + * `nil`: Disables override, defaulting to sunlight based on day-night cycle +* `get_day_night_ratio()`: returns the ratio or nil if it isn't overridden +* `set_local_animation(idle, walk, dig, walk_while_dig, frame_speed)`: + set animation for player model in third person view. + * Every animation equals to a `{x=starting frame, y=ending frame}` table. + * `frame_speed` sets the animations frame speed. Default is 30. +* `get_local_animation()`: returns idle, walk, dig, walk_while_dig tables and + `frame_speed`. +* `set_eye_offset([firstperson, thirdperson])`: defines offset vectors for + camera per player. An argument defaults to `{x=0, y=0, z=0}` if unspecified. + * in first person view + * in third person view (max. values `{x=-10/10,y=-10,15,z=-5/5}`) +* `get_eye_offset()`: returns first and third person offsets. +* `send_mapblock(blockpos)`: + * Sends an already loaded mapblock to the player. + * Returns `false` if nothing was sent (note that this can also mean that + the client already has the block) + * Resource intensive - use sparsely +* `set_lighting(light_definition)`: sets lighting for the player + * `light_definition` is a table with the following optional fields: + * `shadows` is a table that controls ambient shadows + * `intensity` sets the intensity of the shadows from 0 (no shadows, default) to 1 (blackness) +* `get_lighting()`: returns the current state of lighting for the player. + * Result is a table with the same fields as `light_definition` in `set_lighting`. +* `respawn()`: Respawns the player using the same mechanism as the death screen, + including calling on_respawnplayer callbacks. + +`PcgRandom` +----------- + +A 32-bit pseudorandom number generator. +Uses PCG32, an algorithm of the permuted congruential generator family, +offering very strong randomness. + +It can be created via `PcgRandom(seed)` or `PcgRandom(seed, sequence)`. + +### Methods + +* `next()`: return next integer random number [`-2147483648`...`2147483647`] +* `next(min, max)`: return next integer random number [`min`...`max`] +* `rand_normal_dist(min, max, num_trials=6)`: return normally distributed + random number [`min`...`max`]. + * This is only a rough approximation of a normal distribution with: + * `mean = (max - min) / 2`, and + * `variance = (((max - min + 1) ^ 2) - 1) / (12 * num_trials)` + * Increasing `num_trials` improves accuracy of the approximation + +`PerlinNoise` +------------- + +A perlin noise generator. +It can be created via `PerlinNoise()` or `minetest.get_perlin()`. +For `minetest.get_perlin()`, the actual seed used is the noiseparams seed +plus the world seed, to create world-specific noise. + +`PerlinNoise(noiseparams)` +`PerlinNoise(seed, octaves, persistence, spread)` (Deprecated). + +`minetest.get_perlin(noiseparams)` +`minetest.get_perlin(seeddiff, octaves, persistence, spread)` (Deprecated). + +### Methods + +* `get_2d(pos)`: returns 2D noise value at `pos={x=,y=}` +* `get_3d(pos)`: returns 3D noise value at `pos={x=,y=,z=}` + +`PerlinNoiseMap` +---------------- + +A fast, bulk perlin noise generator. + +It can be created via `PerlinNoiseMap(noiseparams, size)` or +`minetest.get_perlin_map(noiseparams, size)`. +For `minetest.get_perlin_map()`, the actual seed used is the noiseparams seed +plus the world seed, to create world-specific noise. + +Format of `size` is `{x=dimx, y=dimy, z=dimz}`. The `z` component is omitted +for 2D noise, and it must be must be larger than 1 for 3D noise (otherwise +`nil` is returned). + +For each of the functions with an optional `buffer` parameter: If `buffer` is +not nil, this table will be used to store the result instead of creating a new +table. + +### Methods + +* `get_2d_map(pos)`: returns a `<size.x>` times `<size.y>` 2D array of 2D noise + with values starting at `pos={x=,y=}` +* `get_3d_map(pos)`: returns a `<size.x>` times `<size.y>` times `<size.z>` + 3D array of 3D noise with values starting at `pos={x=,y=,z=}`. +* `get_2d_map_flat(pos, buffer)`: returns a flat `<size.x * size.y>` element + array of 2D noise with values starting at `pos={x=,y=}` +* `get_3d_map_flat(pos, buffer)`: Same as `get2dMap_flat`, but 3D noise +* `calc_2d_map(pos)`: Calculates the 2d noise map starting at `pos`. The result + is stored internally. +* `calc_3d_map(pos)`: Calculates the 3d noise map starting at `pos`. The result + is stored internally. +* `get_map_slice(slice_offset, slice_size, buffer)`: In the form of an array, + returns a slice of the most recently computed noise results. The result slice + begins at coordinates `slice_offset` and takes a chunk of `slice_size`. + E.g. to grab a 2-slice high horizontal 2d plane of noise starting at buffer + offset y = 20: + `noisevals = noise:get_map_slice({y=20}, {y=2})` + It is important to note that `slice_offset` offset coordinates begin at 1, + and are relative to the starting position of the most recently calculated + noise. + To grab a single vertical column of noise starting at map coordinates + x = 1023, y=1000, z = 1000: + `noise:calc_3d_map({x=1000, y=1000, z=1000})` + `noisevals = noise:get_map_slice({x=24, z=1}, {x=1, z=1})` + +`PlayerMetaRef` +--------------- + +Player metadata. +Uses the same method of storage as the deprecated player attribute API, so +data there will also be in player meta. +Can be obtained using `player:get_meta()`. + +### Methods + +* All methods in MetaDataRef + +`PseudoRandom` +-------------- + +A 16-bit pseudorandom number generator. +Uses a well-known LCG algorithm introduced by K&R. + +It can be created via `PseudoRandom(seed)`. + +### Methods + +* `next()`: return next integer random number [`0`...`32767`] +* `next(min, max)`: return next integer random number [`min`...`max`] + * `((max - min) == 32767) or ((max-min) <= 6553))` must be true + due to the simple implementation making bad distribution otherwise. + +`Raycast` +--------- + +A raycast on the map. It works with selection boxes. +Can be used as an iterator in a for loop as: + + local ray = Raycast(...) + for pointed_thing in ray do + ... + end + +The map is loaded as the ray advances. If the map is modified after the +`Raycast` is created, the changes may or may not have an effect on the object. + +It can be created via `Raycast(pos1, pos2, objects, liquids)` or +`minetest.raycast(pos1, pos2, objects, liquids)` where: + +* `pos1`: start of the ray +* `pos2`: end of the ray +* `objects`: if false, only nodes will be returned. Default is true. +* `liquids`: if false, liquid nodes (`liquidtype ~= "none"`) won't be + returned. Default is false. + +### Methods + +* `next()`: returns a `pointed_thing` with exact pointing location + * Returns the next thing pointed by the ray or nil. + +`SecureRandom` +-------------- + +Interface for the operating system's crypto-secure PRNG. + +It can be created via `SecureRandom()`. The constructor returns nil if a +secure random device cannot be found on the system. + +### Methods + +* `next_bytes([count])`: return next `count` (default 1, capped at 2048) many + random bytes, as a string. + +`Settings` +---------- + +An interface to read config files in the format of `minetest.conf`. + +It can be created via `Settings(filename)`. + +### Methods + +* `get(key)`: returns a value +* `get_bool(key, [default])`: returns a boolean + * `default` is the value returned if `key` is not found. + * Returns `nil` if `key` is not found and `default` not specified. +* `get_np_group(key)`: returns a NoiseParams table +* `get_flags(key)`: + * Returns `{flag = true/false, ...}` according to the set flags. + * Is currently limited to mapgen flags `mg_flags` and mapgen-specific + flags like `mgv5_spflags`. +* `set(key, value)` + * Setting names can't contain whitespace or any of `="{}#`. + * Setting values can't contain the sequence `\n"""`. + * Setting names starting with "secure." can't be set on the main settings + object (`minetest.settings`). +* `set_bool(key, value)` + * See documentation for set() above. +* `set_np_group(key, value)` + * `value` is a NoiseParams table. + * Also, see documentation for set() above. +* `remove(key)`: returns a boolean (`true` for success) +* `get_names()`: returns `{key1,...}` +* `write()`: returns a boolean (`true` for success) + * Writes changes to file. +* `to_table()`: returns `{[key1]=value1,...}` + +### Format + +The settings have the format `key = value`. Example: + + foo = example text + bar = """ + Multiline + value + """ + + +`StorageRef` +------------ + +Mod metadata: per mod metadata, saved automatically. +Can be obtained via `minetest.get_mod_storage()` during load time. + +WARNING: This storage backend is incapable of saving raw binary data due +to restrictions of JSON. + +### Methods + +* All methods in MetaDataRef + + + + +Definition tables +================= + +Object properties +----------------- + +Used by `ObjectRef` methods. Part of an Entity definition. +These properties are not persistent, but are applied automatically to the +corresponding Lua entity using the given registration fields. +Player properties need to be saved manually. + + { + hp_max = 10, + -- Defines the maximum and default HP of the entity + -- For Lua entities the maximum is not enforced. + -- For players this defaults to `minetest.PLAYER_MAX_HP_DEFAULT`. + + breath_max = 0, + -- For players only. Defaults to `minetest.PLAYER_MAX_BREATH_DEFAULT`. + + zoom_fov = 0.0, + -- For players only. Zoom FOV in degrees. + -- Note that zoom loads and/or generates world beyond the server's + -- maximum send and generate distances, so acts like a telescope. + -- Smaller zoom_fov values increase the distance loaded/generated. + -- Defaults to 15 in creative mode, 0 in survival mode. + -- zoom_fov = 0 disables zooming for the player. + + eye_height = 1.625, + -- For players only. Camera height above feet position in nodes. + + physical = false, + -- Collide with `walkable` nodes. + + collide_with_objects = true, + -- Collide with other objects if physical = true + + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + -- Selection box uses collision box dimensions when not set. + -- For both boxes: {xmin, ymin, zmin, xmax, ymax, zmax} in nodes from + -- object position. + + pointable = true, + -- Whether the object can be pointed at + + visual = "cube" / "sprite" / "upright_sprite" / "mesh" / "wielditem" / "item", + -- "cube" is a node-sized cube. + -- "sprite" is a flat texture always facing the player. + -- "upright_sprite" is a vertical flat texture. + -- "mesh" uses the defined mesh model. + -- "wielditem" is used for dropped items. + -- (see builtin/game/item_entity.lua). + -- For this use 'wield_item = itemname' (Deprecated: 'textures = {itemname}'). + -- If the item has a 'wield_image' the object will be an extrusion of + -- that, otherwise: + -- If 'itemname' is a cubic node or nodebox the object will appear + -- identical to 'itemname'. + -- If 'itemname' is a plantlike node the object will be an extrusion + -- of its texture. + -- Otherwise for non-node items, the object will be an extrusion of + -- 'inventory_image'. + -- If 'itemname' contains a ColorString or palette index (e.g. from + -- `minetest.itemstring_with_palette()`), the entity will inherit the color. + -- "item" is similar to "wielditem" but ignores the 'wield_image' parameter. + + visual_size = {x = 1, y = 1, z = 1}, + -- Multipliers for the visual size. If `z` is not specified, `x` will be used + -- to scale the entity along both horizontal axes. + + mesh = "model.obj", + -- File name of mesh when using "mesh" visual + + textures = {}, + -- Number of required textures depends on visual. + -- "cube" uses 6 textures just like a node, but all 6 must be defined. + -- "sprite" uses 1 texture. + -- "upright_sprite" uses 2 textures: {front, back}. + -- "wielditem" expects 'textures = {itemname}' (see 'visual' above). + -- "mesh" requires one texture for each mesh buffer/material (in order) + + colors = {}, + -- Number of required colors depends on visual + + use_texture_alpha = false, + -- Use texture's alpha channel. + -- Excludes "upright_sprite" and "wielditem". + -- Note: currently causes visual issues when viewed through other + -- semi-transparent materials such as water. + + spritediv = {x = 1, y = 1}, + -- Used with spritesheet textures for animation and/or frame selection + -- according to position relative to player. + -- Defines the number of columns and rows in the spritesheet: + -- {columns, rows}. + + initial_sprite_basepos = {x = 0, y = 0}, + -- Used with spritesheet textures. + -- Defines the {column, row} position of the initially used frame in the + -- spritesheet. + + is_visible = true, + -- If false, object is invisible and can't be pointed. + + makes_footstep_sound = false, + -- If true, is able to make footstep sounds of nodes + -- (see node sound definition for details). + + automatic_rotate = 0, + -- Set constant rotation in radians per second, positive or negative. + -- Object rotates along the local Y-axis, and works with set_rotation. + -- Set to 0 to disable constant rotation. + + stepheight = 0, + -- If positive number, object will climb upwards when it moves + -- horizontally against a `walkable` node, if the height difference + -- is within `stepheight`. + + automatic_face_movement_dir = 0.0, + -- Automatically set yaw to movement direction, offset in degrees. + -- 'false' to disable. + + automatic_face_movement_max_rotation_per_sec = -1, + -- Limit automatic rotation to this value in degrees per second. + -- No limit if value <= 0. + + backface_culling = true, + -- Set to false to disable backface_culling for model + + glow = 0, + -- Add this much extra lighting when calculating texture color. + -- Value < 0 disables light's effect on texture color. + -- For faking self-lighting, UI style entities, or programmatic coloring + -- in mods. + + nametag = "", + -- The name to display on the head of the object. By default empty. + -- If the object is a player, a nil or empty nametag is replaced by the player's name. + -- For all other objects, a nil or empty string removes the nametag. + -- To hide a nametag, set its color alpha to zero. That will disable it entirely. + + nametag_color = <ColorSpec>, + -- Sets text color of nametag + + nametag_bgcolor = <ColorSpec>, + -- Sets background color of nametag + -- `false` will cause the background to be set automatically based on user settings. + -- Default: false + + infotext = "", + -- Same as infotext for nodes. Empty by default + + static_save = true, + -- If false, never save this object statically. It will simply be + -- deleted when the block gets unloaded. + -- The get_staticdata() callback is never called then. + -- Defaults to 'true'. + + damage_texture_modifier = "^[brighten", + -- Texture modifier to be applied for a short duration when object is hit + + shaded = true, + -- Setting this to 'false' disables diffuse lighting of entity + + show_on_minimap = false, + -- Defaults to true for players, false for other entities. + -- If set to true the entity will show as a marker on the minimap. + } + +Entity definition +----------------- + +Used by `minetest.register_entity`. + + { + initial_properties = { + visual = "mesh", + mesh = "boats_boat.obj", + ..., + }, + -- A table of object properties, see the `Object properties` section. + -- The properties in this table are applied to the object + -- once when it is spawned. + + -- Refer to the "Registered entities" section for explanations + on_activate = function(self, staticdata, dtime_s), + on_deactivate = function(self, removal), + on_step = function(self, dtime, moveresult), + on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage), + on_death = function(self, killer), + on_rightclick = function(self, clicker), + on_attach_child = function(self, child), + on_detach_child = function(self, child), + on_detach = function(self, parent), + get_staticdata = function(self), + + _custom_field = whatever, + -- You can define arbitrary member variables here (see Item definition + -- for more info) by using a '_' prefix + } + + +ABM (ActiveBlockModifier) definition +------------------------------------ + +Used by `minetest.register_abm`. + + { + label = "Lava cooling", + -- Descriptive label for profiling purposes (optional). + -- Definitions with identical labels will be listed as one. + + nodenames = {"default:lava_source"}, + -- Apply `action` function to these nodes. + -- `group:groupname` can also be used here. + + neighbors = {"default:water_source", "default:water_flowing"}, + -- Only apply `action` to nodes that have one of, or any + -- combination of, these neighbors. + -- If left out or empty, any neighbor will do. + -- `group:groupname` can also be used here. + + interval = 1.0, + -- Operation interval in seconds + + chance = 1, + -- Chance of triggering `action` per-node per-interval is 1.0 / this + -- value + + min_y = -32768, + max_y = 32767, + -- min and max height levels where ABM will be processed (inclusive) + -- can be used to reduce CPU usage + + catch_up = true, + -- If true, catch-up behaviour is enabled: The `chance` value is + -- temporarily reduced when returning to an area to simulate time lost + -- by the area being unattended. Note that the `chance` value can often + -- be reduced to 1. + + action = function(pos, node, active_object_count, active_object_count_wider), + -- Function triggered for each qualifying node. + -- `active_object_count` is number of active objects in the node's + -- mapblock. + -- `active_object_count_wider` is number of active objects in the node's + -- mapblock plus all 26 neighboring mapblocks. If any neighboring + -- mapblocks are unloaded an estmate is calculated for them based on + -- loaded mapblocks. + } + +LBM (LoadingBlockModifier) definition +------------------------------------- + +Used by `minetest.register_lbm`. + +A loading block modifier (LBM) is used to define a function that is called for +specific nodes (defined by `nodenames`) when a mapblock which contains such nodes +gets activated (not loaded!) + + { + label = "Upgrade legacy doors", + -- Descriptive label for profiling purposes (optional). + -- Definitions with identical labels will be listed as one. + + name = "modname:replace_legacy_door", + -- Identifier of the LBM, should follow the modname:<whatever> convention + + nodenames = {"default:lava_source"}, + -- List of node names to trigger the LBM on. + -- Names of non-registered nodes and groups (as group:groupname) + -- will work as well. + + run_at_every_load = false, + -- Whether to run the LBM's action every time a block gets activated, + -- and not only the first time the block gets activated after the LBM + -- was introduced. + + action = function(pos, node), + -- Function triggered for each qualifying node. + } + +Tile definition +--------------- + +* `"image.png"` +* `{name="image.png", animation={Tile Animation definition}}` +* `{name="image.png", backface_culling=bool, align_style="node"/"world"/"user", scale=int}` + * backface culling enabled by default for most nodes + * align style determines whether the texture will be rotated with the node + or kept aligned with its surroundings. "user" means that client + setting will be used, similar to `glasslike_framed_optional`. + Note: supported by solid nodes and nodeboxes only. + * scale is used to make texture span several (exactly `scale`) nodes, + instead of just one, in each direction. Works for world-aligned + textures only. + Note that as the effect is applied on per-mapblock basis, `16` should + be equally divisible by `scale` or you may get wrong results. +* `{name="image.png", color=ColorSpec}` + * the texture's color will be multiplied with this color. + * the tile's color overrides the owning node's color in all cases. +* deprecated, yet still supported field names: + * `image` (name) + +Tile animation definition +------------------------- + + { + type = "vertical_frames", + + aspect_w = 16, + -- Width of a frame in pixels + + aspect_h = 16, + -- Height of a frame in pixels + + length = 3.0, + -- Full loop length + } + + { + type = "sheet_2d", + + frames_w = 5, + -- Width in number of frames + + frames_h = 3, + -- Height in number of frames + + frame_length = 0.5, + -- Length of a single frame + } + +Item definition +--------------- + +Used by `minetest.register_node`, `minetest.register_craftitem`, and +`minetest.register_tool`. + + { + description = "", + -- Can contain new lines. "\n" has to be used as new line character. + -- See also: `get_description` in [`ItemStack`] + + short_description = "", + -- Must not contain new lines. + -- Defaults to nil. + -- Use an [`ItemStack`] to get the short description, e.g.: + -- ItemStack(itemname):get_short_description() + + groups = {}, + -- key = name, value = rating; rating = <number>. + -- If rating not applicable, use 1. + -- e.g. {wool = 1, fluffy = 3} + -- {soil = 2, outerspace = 1, crumbly = 1} + -- {bendy = 2, snappy = 1}, + -- {hard = 1, metal = 1, spikes = 1} + + inventory_image = "", + -- Texture shown in the inventory GUI + -- Defaults to a 3D rendering of the node if left empty. + + inventory_overlay = "", + -- An overlay texture which is not affected by colorization + + wield_image = "", + -- Texture shown when item is held in hand + -- Defaults to a 3D rendering of the node if left empty. + + wield_overlay = "", + -- Like inventory_overlay but only used in the same situation as wield_image + + wield_scale = {x = 1, y = 1, z = 1}, + -- Scale for the item when held in hand + + palette = "", + -- An image file containing the palette of a node. + -- You can set the currently used color as the "palette_index" field of + -- the item stack metadata. + -- The palette is always stretched to fit indices between 0 and 255, to + -- ensure compatibility with "colorfacedir" and "colorwallmounted" nodes. + + color = "#ffffffff", + -- Color the item is colorized with. The palette overrides this. + + stack_max = 99, + -- Maximum amount of items that can be in a single stack. + -- The default can be changed by the setting `default_stack_max` + + range = 4.0, + -- Range of node and object pointing that is possible with this item held + + liquids_pointable = false, + -- If true, item can point to all liquid nodes (`liquidtype ~= "none"`), + -- even those for which `pointable = false` + + light_source = 0, + -- When used for nodes: Defines amount of light emitted by node. + -- Otherwise: Defines texture glow when viewed as a dropped item + -- To set the maximum (14), use the value 'minetest.LIGHT_MAX'. + -- A value outside the range 0 to minetest.LIGHT_MAX causes undefined + -- behavior. + + -- See "Tool Capabilities" section for an example including explanation + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level = 0, + groupcaps = { + -- For example: + choppy = {times = {2.50, 1.40, 1.00}, uses = 20, maxlevel = 2}, + }, + damage_groups = {groupname = damage}, + -- Damage values must be between -32768 and 32767 (2^15) + + punch_attack_uses = nil, + -- Amount of uses this tool has for attacking players and entities + -- by punching them (0 = infinite uses). + -- For compatibility, this is automatically set from the first + -- suitable groupcap using the forumla "uses * 3^(maxlevel - 1)". + -- It is recommend to set this explicitly instead of relying on the + -- fallback behavior. + }, + + node_placement_prediction = nil, + -- If nil and item is node, prediction is made automatically. + -- If nil and item is not a node, no prediction is made. + -- If "" and item is anything, no prediction is made. + -- Otherwise should be name of node which the client immediately places + -- on ground when the player places the item. Server will always update + -- with actual result shortly. + + node_dig_prediction = "air", + -- if "", no prediction is made. + -- if "air", node is removed. + -- Otherwise should be name of node which the client immediately places + -- upon digging. Server will always update with actual result shortly. + + sound = { + -- Definition of item sounds to be played at various events. + -- All fields in this table are optional. + + breaks = <SimpleSoundSpec>, + -- When tool breaks due to wear. Ignored for non-tools + + eat = <SimpleSoundSpec>, + -- When item is eaten with `minetest.do_item_eat` + }, + + on_place = function(itemstack, placer, pointed_thing), + -- When the 'place' key was pressed with the item in hand + -- and a node was pointed at. + -- Shall place item and return the leftover itemstack + -- or nil to not modify the inventory. + -- The placer may be any ObjectRef or nil. + -- default: minetest.item_place + + on_secondary_use = function(itemstack, user, pointed_thing), + -- Same as on_place but called when not pointing at a node. + -- Function must return either nil if inventory shall not be modified, + -- or an itemstack to replace the original itemstack. + -- The user may be any ObjectRef or nil. + -- default: nil + + on_drop = function(itemstack, dropper, pos), + -- Shall drop item and return the leftover itemstack. + -- The dropper may be any ObjectRef or nil. + -- default: minetest.item_drop + + on_use = function(itemstack, user, pointed_thing), + -- default: nil + -- When user pressed the 'punch/mine' key with the item in hand. + -- Function must return either nil if inventory shall not be modified, + -- or an itemstack to replace the original itemstack. + -- e.g. itemstack:take_item(); return itemstack + -- Otherwise, the function is free to do what it wants. + -- The user may be any ObjectRef or nil. + -- The default functions handle regular use cases. + + after_use = function(itemstack, user, node, digparams), + -- default: nil + -- If defined, should return an itemstack and will be called instead of + -- wearing out the item (if tool). If returns nil, does nothing. + -- If after_use doesn't exist, it is the same as: + -- function(itemstack, user, node, digparams) + -- itemstack:add_wear(digparams.wear) + -- return itemstack + -- end + -- The user may be any ObjectRef or nil. + + _custom_field = whatever, + -- Add your own custom fields. By convention, all custom field names + -- should start with `_` to avoid naming collisions with future engine + -- usage. + } + +Node definition +--------------- + +Used by `minetest.register_node`. + + { + -- <all fields allowed in item definitions> + + drawtype = "normal", -- See "Node drawtypes" + + visual_scale = 1.0, + -- Supported for drawtypes "plantlike", "signlike", "torchlike", + -- "firelike", "mesh", "nodebox", "allfaces". + -- For plantlike and firelike, the image will start at the bottom of the + -- node. For torchlike, the image will start at the surface to which the + -- node "attaches". For the other drawtypes the image will be centered + -- on the node. + + tiles = {tile definition 1, def2, def3, def4, def5, def6}, + -- Textures of node; +Y, -Y, +X, -X, +Z, -Z + -- List can be shortened to needed length. + + overlay_tiles = {tile definition 1, def2, def3, def4, def5, def6}, + -- Same as `tiles`, but these textures are drawn on top of the base + -- tiles. You can use this to colorize only specific parts of your + -- texture. If the texture name is an empty string, that overlay is not + -- drawn. Since such tiles are drawn twice, it is not recommended to use + -- overlays on very common nodes. + + special_tiles = {tile definition 1, Tile definition 2}, + -- Special textures of node; used rarely. + -- List can be shortened to needed length. + + color = ColorSpec, + -- The node's original color will be multiplied with this color. + -- If the node has a palette, then this setting only has an effect in + -- the inventory and on the wield item. + + use_texture_alpha = ..., + -- Specifies how the texture's alpha channel will be used for rendering. + -- possible values: + -- * "opaque": Node is rendered opaque regardless of alpha channel + -- * "clip": A given pixel is either fully see-through or opaque + -- depending on the alpha channel being below/above 50% in value + -- * "blend": The alpha channel specifies how transparent a given pixel + -- of the rendered node is + -- The default is "opaque" for drawtypes normal, liquid and flowingliquid; + -- "clip" otherwise. + -- If set to a boolean value (deprecated): true either sets it to blend + -- or clip, false sets it to clip or opaque mode depending on the drawtype. + + palette = "", + -- The node's `param2` is used to select a pixel from the image. + -- Pixels are arranged from left to right and from top to bottom. + -- The node's color will be multiplied with the selected pixel's color. + -- Tiles can override this behavior. + -- Only when `paramtype2` supports palettes. + + post_effect_color = "#00000000", + -- Screen tint if player is inside node, see "ColorSpec" + + paramtype = "none", -- See "Nodes" + + paramtype2 = "none", -- See "Nodes" + + place_param2 = 0, + -- Value for param2 that is set when player places node + + is_ground_content = true, + -- If false, the cave generator and dungeon generator will not carve + -- through this node. + -- Specifically, this stops mod-added nodes being removed by caves and + -- dungeons when those generate in a neighbor mapchunk and extend out + -- beyond the edge of that mapchunk. + + sunlight_propagates = false, + -- If true, sunlight will go infinitely through this node + + walkable = true, -- If true, objects collide with node + + pointable = true, -- If true, can be pointed at + + diggable = true, -- If false, can never be dug + + climbable = false, -- If true, can be climbed on like a ladder + + move_resistance = 0, + -- Slows down movement of players through this node (max. 7). + -- If this is nil, it will be equal to liquid_viscosity. + -- Note: If liquid movement physics apply to the node + -- (see `liquid_move_physics`), the movement speed will also be + -- affected by the `movement_liquid_*` settings. + + buildable_to = false, -- If true, placed nodes can replace this node + + floodable = false, + -- If true, liquids flow into and replace this node. + -- Warning: making a liquid node 'floodable' will cause problems. + + liquidtype = "none", -- specifies liquid flowing physics + -- * "none": no liquid flowing physics + -- * "source": spawns flowing liquid nodes at all 4 sides and below; + -- recommended drawtype: "liquid". + -- * "flowing": spawned from source, spawns more flowing liquid nodes + -- around it until `liquid_range` is reached; + -- will drain out without a source; + -- recommended drawtype: "flowingliquid". + -- If it's "source" or "flowing" and `liquid_range > 0`, then + -- both `liquid_alternative_*` fields must be specified + + liquid_alternative_flowing = "", + -- Node that represents the flowing version of the liquid + + liquid_alternative_source = "", + -- Node that represents the source version of the liquid + + liquid_viscosity = 0, + -- Controls speed at which the liquid spreads/flows (max. 7). + -- 0 is fastest, 7 is slowest. + -- By default, this also slows down movement of players inside the node + -- (can be overridden using `move_resistance`) + + liquid_renewable = true, + -- If true, a new liquid source can be created by placing two or more + -- sources nearby + + liquid_move_physics = nil, -- specifies movement physics if inside node + -- * false: No liquid movement physics apply. + -- * true: Enables liquid movement physics. Enables things like + -- ability to "swim" up/down, sinking slowly if not moving, + -- smoother speed change when falling into, etc. The `movement_liquid_*` + -- settings apply. + -- * nil: Will be treated as true if `liquidype ~= "none"` + -- and as false otherwise. + + leveled = 0, + -- Only valid for "nodebox" drawtype with 'type = "leveled"'. + -- Allows defining the nodebox height without using param2. + -- The nodebox height is 'leveled' / 64 nodes. + -- The maximum value of 'leveled' is `leveled_max`. + + leveled_max = 127, + -- Maximum value for `leveled` (0-127), enforced in + -- `minetest.set_node_level` and `minetest.add_node_level`. + -- Values above 124 might causes collision detection issues. + + liquid_range = 8, + -- Maximum distance that flowing liquid nodes can spread around + -- source on flat land; + -- maximum = 8; set to 0 to disable liquid flow + + drowning = 0, + -- Player will take this amount of damage if no bubbles are left + + damage_per_second = 0, + -- If player is inside node, this damage is caused + + node_box = {type = "regular"}, -- See "Node boxes" + + connects_to = {}, + -- Used for nodebox nodes with the type == "connected". + -- Specifies to what neighboring nodes connections will be drawn. + -- e.g. `{"group:fence", "default:wood"}` or `"default:stone"` + + connect_sides = {}, + -- Tells connected nodebox nodes to connect only to these sides of this + -- node. possible: "top", "bottom", "front", "left", "back", "right" + + mesh = "", + -- File name of mesh when using "mesh" drawtype + + selection_box = { + -- see [Node boxes] for possibilities + }, + -- Custom selection box definition. Multiple boxes can be defined. + -- If "nodebox" drawtype is used and selection_box is nil, then node_box + -- definition is used for the selection box. + + collision_box = { + -- see [Node boxes] for possibilities + }, + -- Custom collision box definition. Multiple boxes can be defined. + -- If "nodebox" drawtype is used and collision_box is nil, then node_box + -- definition is used for the collision box. + + -- Support maps made in and before January 2012 + legacy_facedir_simple = false, + legacy_wallmounted = false, + + waving = 0, + -- Valid for drawtypes: + -- mesh, nodebox, plantlike, allfaces_optional, liquid, flowingliquid. + -- 1 - wave node like plants (node top moves side-to-side, bottom is fixed) + -- 2 - wave node like leaves (whole node moves side-to-side) + -- 3 - wave node like liquids (whole node moves up and down) + -- Not all models will properly wave. + -- plantlike drawtype can only wave like plants. + -- allfaces_optional drawtype can only wave like leaves. + -- liquid, flowingliquid drawtypes can only wave like liquids. + + sounds = { + -- Definition of node sounds to be played at various events. + -- All fields in this table are optional. + + footstep = <SimpleSoundSpec>, + -- If walkable, played when object walks on it. If node is + -- climbable or a liquid, played when object moves through it + + dig = <SimpleSoundSpec> or "__group", + -- While digging node. + -- If `"__group"`, then the sound will be + -- `default_dig_<groupname>`, where `<groupname>` is the + -- name of the item's digging group with the fastest digging time. + -- In case of a tie, one of the sounds will be played (but we + -- cannot predict which one) + -- Default value: `"__group"` + + dug = <SimpleSoundSpec>, + -- Node was dug + + place = <SimpleSoundSpec>, + -- Node was placed. Also played after falling + + place_failed = <SimpleSoundSpec>, + -- When node placement failed. + -- Note: This happens if the _built-in_ node placement failed. + -- This sound will still be played if the node is placed in the + -- `on_place` callback manually. + + fall = <SimpleSoundSpec>, + -- When node starts to fall or is detached + }, + + drop = "", + -- Name of dropped item when dug. + -- Default dropped item is the node itself. + + -- Using a table allows multiple items, drop chances and item filtering: + drop = { + max_items = 1, + -- Maximum number of item lists to drop. + -- The entries in 'items' are processed in order. For each: + -- Item filtering is applied, chance of drop is applied, if both are + -- successful the entire item list is dropped. + -- Entry processing continues until the number of dropped item lists + -- equals 'max_items'. + -- Therefore, entries should progress from low to high drop chance. + items = { + -- Examples: + { + -- 1 in 1000 chance of dropping a diamond. + -- Default rarity is '1'. + rarity = 1000, + items = {"default:diamond"}, + }, + { + -- Only drop if using an item whose name is identical to one + -- of these. + tools = {"default:shovel_mese", "default:shovel_diamond"}, + rarity = 5, + items = {"default:dirt"}, + -- Whether all items in the dropped item list inherit the + -- hardware coloring palette color from the dug node. + -- Default is 'false'. + inherit_color = true, + }, + { + -- Only drop if using an item whose name contains + -- "default:shovel_" (this item filtering by string matching + -- is deprecated, use tool_groups instead). + tools = {"~default:shovel_"}, + rarity = 2, + -- The item list dropped. + items = {"default:sand", "default:desert_sand"}, + }, + { + -- Only drop if using an item in the "magicwand" group, or + -- an item that is in both the "pickaxe" and the "lucky" + -- groups. + tool_groups = { + "magicwand", + {"pickaxe", "lucky"} + }, + items = {"default:coal_lump"}, + }, + }, + }, + + on_construct = function(pos), + -- Node constructor; called after adding node. + -- Can set up metadata and stuff like that. + -- Not called for bulk node placement (i.e. schematics and VoxelManip). + -- default: nil + + on_destruct = function(pos), + -- Node destructor; called before removing node. + -- Not called for bulk node placement. + -- default: nil + + after_destruct = function(pos, oldnode), + -- Node destructor; called after removing node. + -- Not called for bulk node placement. + -- default: nil + + on_flood = function(pos, oldnode, newnode), + -- Called when a liquid (newnode) is about to flood oldnode, if it has + -- `floodable = true` in the nodedef. Not called for bulk node placement + -- (i.e. schematics and VoxelManip) or air nodes. If return true the + -- node is not flooded, but on_flood callback will most likely be called + -- over and over again every liquid update interval. + -- Default: nil + -- Warning: making a liquid node 'floodable' will cause problems. + + preserve_metadata = function(pos, oldnode, oldmeta, drops), + -- Called when oldnode is about be converted to an item, but before the + -- node is deleted from the world or the drops are added. This is + -- generally the result of either the node being dug or an attached node + -- becoming detached. + -- oldmeta are the metadata fields (table) of the node before deletion. + -- drops is a table of ItemStacks, so any metadata to be preserved can + -- be added directly to one or more of the dropped items. See + -- "ItemStackMetaRef". + -- default: nil + + after_place_node = function(pos, placer, itemstack, pointed_thing), + -- Called after constructing node when node was placed using + -- minetest.item_place_node / minetest.place_node. + -- If return true no item is taken from itemstack. + -- `placer` may be any valid ObjectRef or nil. + -- default: nil + + after_dig_node = function(pos, oldnode, oldmetadata, digger), + -- oldmetadata is in table format. + -- Called after destructing node when node was dug using + -- minetest.node_dig / minetest.dig_node. + -- default: nil + + can_dig = function(pos, [player]), + -- Returns true if node can be dug, or false if not. + -- default: nil + + on_punch = function(pos, node, puncher, pointed_thing), + -- default: minetest.node_punch + -- Called when puncher (an ObjectRef) punches the node at pos. + -- By default calls minetest.register_on_punchnode callbacks. + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing), + -- default: nil + -- Called when clicker (an ObjectRef) used the 'place/build' key + -- (not neccessarily an actual rightclick) + -- while pointing at the node at pos with 'node' being the node table. + -- itemstack will hold clicker's wielded item. + -- Shall return the leftover itemstack. + -- Note: pointed_thing can be nil, if a mod calls this function. + -- This function does not get triggered by clients <=0.4.16 if the + -- "formspec" node metadata field is set. + + on_dig = function(pos, node, digger), + -- default: minetest.node_dig + -- By default checks privileges, wears out item (if tool) and removes node. + -- return true if the node was dug successfully, false otherwise. + -- Deprecated: returning nil is the same as returning true. + + on_timer = function(pos, elapsed), + -- default: nil + -- called by NodeTimers, see minetest.get_node_timer and NodeTimerRef. + -- elapsed is the total time passed since the timer was started. + -- return true to run the timer for another cycle with the same timeout + -- value. + + on_receive_fields = function(pos, formname, fields, sender), + -- fields = {name1 = value1, name2 = value2, ...} + -- Called when an UI form (e.g. sign text input) returns data. + -- See minetest.register_on_player_receive_fields for more info. + -- default: nil + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player), + -- Called when a player wants to move items inside the inventory. + -- Return value: number of items allowed to move. + + allow_metadata_inventory_put = function(pos, listname, index, stack, player), + -- Called when a player wants to put something into the inventory. + -- Return value: number of items allowed to put. + -- Return value -1: Allow and don't modify item count in inventory. + + allow_metadata_inventory_take = function(pos, listname, index, stack, player), + -- Called when a player wants to take something out of the inventory. + -- Return value: number of items allowed to take. + -- Return value -1: Allow and don't modify item count in inventory. + + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player), + on_metadata_inventory_put = function(pos, listname, index, stack, player), + on_metadata_inventory_take = function(pos, listname, index, stack, player), + -- Called after the actual action has happened, according to what was + -- allowed. + -- No return value. + + on_blast = function(pos, intensity), + -- intensity: 1.0 = mid range of regular TNT. + -- If defined, called when an explosion touches the node, instead of + -- removing the node. + + mod_origin = "modname", + -- stores which mod actually registered a node + -- If the source could not be determined it contains "??" + -- Useful for getting which mod truly registered something + -- example: if a node is registered as ":othermodname:nodename", + -- nodename will show "othermodname", but mod_orgin will say "modname" + } + +Crafting recipes +---------------- + +Used by `minetest.register_craft`. + +### Shaped + + { + output = "default:pick_stone", + recipe = { + {"default:cobble", "default:cobble", "default:cobble"}, + {"", "default:stick", ""}, + {"", "default:stick", ""}, -- Also groups; e.g. "group:crumbly" + }, + replacements = <list of item pairs>, + -- replacements: replace one input item with another item on crafting + -- (optional). + } + +### Shapeless + + { + type = "shapeless", + output = "mushrooms:mushroom_stew", + recipe = { + "mushrooms:bowl", + "mushrooms:mushroom_brown", + "mushrooms:mushroom_red", + }, + replacements = <list of item pairs>, + } + +### Tool repair + + { + type = "toolrepair", + additional_wear = -0.02, -- multiplier of 65536 + } + +Adds a shapeless recipe for *every* tool that doesn't have the `disable_repair=1` +group. Player can put 2 equal tools in the craft grid to get one "repaired" tool +back. +The wear of the output is determined by the wear of both tools, plus a +'repair bonus' given by `additional_wear`. To reduce the wear (i.e. 'repair'), +you want `additional_wear` to be negative. + +The formula used to calculate the resulting wear is: + + 65536 * (1 - ( (1 - tool_1_wear) + (1 - tool_2_wear) + additional_wear )) + +The result is rounded and can't be lower than 0. If the result is 65536 or higher, +no crafting is possible. + +### Cooking + + { + type = "cooking", + output = "default:glass", + recipe = "default:sand", + cooktime = 3, + } + +### Furnace fuel + + { + type = "fuel", + recipe = "bucket:bucket_lava", + burntime = 60, + replacements = {{"bucket:bucket_lava", "bucket:bucket_empty"}}, + } + +The engine does not implement anything specific to cooking or fuels, but the +recpies can be retrieved later using `minetest.get_craft_result` to have a +consistent interface across different games/mods. + +Ore definition +-------------- + +Used by `minetest.register_ore`. + +See [Ores] section above for essential information. + + { + ore_type = "", + -- Supported: "scatter", "sheet", "puff", "blob", "vein", "stratum" + + ore = "", + -- Ore node to place + + ore_param2 = 0, + -- Param2 to set for ore (e.g. facedir rotation) + + wherein = "", + -- Node to place ore in. Multiple are possible by passing a list. + + clust_scarcity = 8 * 8 * 8, + -- Ore has a 1 out of clust_scarcity chance of spawning in a node. + -- If the desired average distance between ores is 'd', set this to + -- d * d * d. + + clust_num_ores = 8, + -- Number of ores in a cluster + + clust_size = 3, + -- Size of the bounding box of the cluster. + -- In this example, there is a 3 * 3 * 3 cluster where 8 out of the 27 + -- nodes are coal ore. + + y_min = -31000, + y_max = 31000, + -- Lower and upper limits for ore (inclusive) + + flags = "", + -- Attributes for the ore generation, see 'Ore attributes' section above + + noise_threshold = 0, + -- If noise is above this threshold, ore is placed. Not needed for a + -- uniform distribution. + + noise_params = { + offset = 0, + scale = 1, + spread = {x = 100, y = 100, z = 100}, + seed = 23, + octaves = 3, + persistence = 0.7 + }, + -- NoiseParams structure describing one of the perlin noises used for + -- ore distribution. + -- Needed by "sheet", "puff", "blob" and "vein" ores. + -- Omit from "scatter" ore for a uniform ore distribution. + -- Omit from "stratum" ore for a simple horizontal strata from y_min to + -- y_max. + + biomes = {"desert", "rainforest"}, + -- List of biomes in which this ore occurs. + -- Occurs in all biomes if this is omitted, and ignored if the Mapgen + -- being used does not support biomes. + -- Can be a list of (or a single) biome names, IDs, or definitions. + + -- Type-specific parameters + + -- "sheet" + column_height_min = 1, + column_height_max = 16, + column_midpoint_factor = 0.5, + + -- "puff" + np_puff_top = { + offset = 4, + scale = 2, + spread = {x = 100, y = 100, z = 100}, + seed = 47, + octaves = 3, + persistence = 0.7 + }, + np_puff_bottom = { + offset = 4, + scale = 2, + spread = {x = 100, y = 100, z = 100}, + seed = 11, + octaves = 3, + persistence = 0.7 + }, + + -- "vein" + random_factor = 1.0, + + -- "stratum" + np_stratum_thickness = { + offset = 8, + scale = 4, + spread = {x = 100, y = 100, z = 100}, + seed = 17, + octaves = 3, + persistence = 0.7 + }, + stratum_thickness = 8, -- only used if no noise defined + } + +Biome definition +---------------- + +Used by `minetest.register_biome`. + +The maximum number of biomes that can be used is 65535. However, using an +excessive number of biomes will slow down map generation. Depending on desired +performance and computing power the practical limit is much lower. + + { + name = "tundra", + + node_dust = "default:snow", + -- Node dropped onto upper surface after all else is generated + + node_top = "default:dirt_with_snow", + depth_top = 1, + -- Node forming surface layer of biome and thickness of this layer + + node_filler = "default:permafrost", + depth_filler = 3, + -- Node forming lower layer of biome and thickness of this layer + + node_stone = "default:bluestone", + -- Node that replaces all stone nodes between roughly y_min and y_max. + + node_water_top = "default:ice", + depth_water_top = 10, + -- Node forming a surface layer in seawater with the defined thickness + + node_water = "", + -- Node that replaces all seawater nodes not in the surface layer + + node_river_water = "default:ice", + -- Node that replaces river water in mapgens that use + -- default:river_water + + node_riverbed = "default:gravel", + depth_riverbed = 2, + -- Node placed under river water and thickness of this layer + + node_cave_liquid = "default:lava_source", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + -- Nodes placed inside 50% of the medium size caves. + -- Multiple nodes can be specified, each cave will use a randomly + -- chosen node from the list. + -- If this field is left out or 'nil', cave liquids fall back to + -- classic behaviour of lava and water distributed using 3D noise. + -- For no cave liquid, specify "air". + + node_dungeon = "default:cobble", + -- Node used for primary dungeon structure. + -- If absent, dungeon nodes fall back to the 'mapgen_cobble' mapgen + -- alias, if that is also absent, dungeon nodes fall back to the biome + -- 'node_stone'. + -- If present, the following two nodes are also used. + + node_dungeon_alt = "default:mossycobble", + -- Node used for randomly-distributed alternative structure nodes. + -- If alternative structure nodes are not wanted leave this absent. + + node_dungeon_stair = "stairs:stair_cobble", + -- Node used for dungeon stairs. + -- If absent, stairs fall back to 'node_dungeon'. + + y_max = 31000, + y_min = 1, + -- Upper and lower limits for biome. + -- Alternatively you can use xyz limits as shown below. + + max_pos = {x = 31000, y = 128, z = 31000}, + min_pos = {x = -31000, y = 9, z = -31000}, + -- xyz limits for biome, an alternative to using 'y_min' and 'y_max'. + -- Biome is limited to a cuboid defined by these positions. + -- Any x, y or z field left undefined defaults to -31000 in 'min_pos' or + -- 31000 in 'max_pos'. + + vertical_blend = 8, + -- Vertical distance in nodes above 'y_max' over which the biome will + -- blend with the biome above. + -- Set to 0 for no vertical blend. Defaults to 0. + + heat_point = 0, + humidity_point = 50, + -- Characteristic temperature and humidity for the biome. + -- These values create 'biome points' on a voronoi diagram with heat and + -- humidity as axes. The resulting voronoi cells determine the + -- distribution of the biomes. + -- Heat and humidity have average values of 50, vary mostly between + -- 0 and 100 but can exceed these values. + } + +Decoration definition +--------------------- + +See [Decoration types]. Used by `minetest.register_decoration`. + + { + deco_type = "simple", + -- Type. "simple" or "schematic" supported + + place_on = "default:dirt_with_grass", + -- Node (or list of nodes) that the decoration can be placed on + + sidelen = 8, + -- Size of the square (X / Z) divisions of the mapchunk being generated. + -- Determines the resolution of noise variation if used. + -- If the chunk size is not evenly divisible by sidelen, sidelen is made + -- equal to the chunk size. + + fill_ratio = 0.02, + -- The value determines 'decorations per surface node'. + -- Used only if noise_params is not specified. + -- If >= 10.0 complete coverage is enabled and decoration placement uses + -- a different and much faster method. + + noise_params = { + offset = 0, + scale = 0.45, + spread = {x = 100, y = 100, z = 100}, + seed = 354, + octaves = 3, + persistence = 0.7, + lacunarity = 2.0, + flags = "absvalue" + }, + -- NoiseParams structure describing the perlin noise used for decoration + -- distribution. + -- A noise value is calculated for each square division and determines + -- 'decorations per surface node' within each division. + -- If the noise value >= 10.0 complete coverage is enabled and + -- decoration placement uses a different and much faster method. + + biomes = {"Oceanside", "Hills", "Plains"}, + -- List of biomes in which this decoration occurs. Occurs in all biomes + -- if this is omitted, and ignored if the Mapgen being used does not + -- support biomes. + -- Can be a list of (or a single) biome names, IDs, or definitions. + + y_min = -31000, + y_max = 31000, + -- Lower and upper limits for decoration (inclusive). + -- These parameters refer to the Y co-ordinate of the 'place_on' node. + + spawn_by = "default:water", + -- Node (or list of nodes) that the decoration only spawns next to. + -- Checks the 8 neighbouring nodes on the same Y, and also the ones + -- at Y+1, excluding both center nodes. + + num_spawn_by = 1, + -- Number of spawn_by nodes that must be surrounding the decoration + -- position to occur. + -- If absent or -1, decorations occur next to any nodes. + + flags = "liquid_surface, force_placement, all_floors, all_ceilings", + -- Flags for all decoration types. + -- "liquid_surface": Instead of placement on the highest solid surface + -- in a mapchunk column, placement is on the highest liquid surface. + -- Placement is disabled if solid nodes are found above the liquid + -- surface. + -- "force_placement": Nodes other than "air" and "ignore" are replaced + -- by the decoration. + -- "all_floors", "all_ceilings": Instead of placement on the highest + -- surface in a mapchunk the decoration is placed on all floor and/or + -- ceiling surfaces, for example in caves and dungeons. + -- Ceiling decorations act as an inversion of floor decorations so the + -- effect of 'place_offset_y' is inverted. + -- Y-slice probabilities do not function correctly for ceiling + -- schematic decorations as the behaviour is unchanged. + -- If a single decoration registration has both flags the floor and + -- ceiling decorations will be aligned vertically. + + ----- Simple-type parameters + + decoration = "default:grass", + -- The node name used as the decoration. + -- If instead a list of strings, a randomly selected node from the list + -- is placed as the decoration. + + height = 1, + -- Decoration height in nodes. + -- If height_max is not 0, this is the lower limit of a randomly + -- selected height. + + height_max = 0, + -- Upper limit of the randomly selected height. + -- If absent, the parameter 'height' is used as a constant. + + param2 = 0, + -- Param2 value of decoration nodes. + -- If param2_max is not 0, this is the lower limit of a randomly + -- selected param2. + + param2_max = 0, + -- Upper limit of the randomly selected param2. + -- If absent, the parameter 'param2' is used as a constant. + + place_offset_y = 0, + -- Y offset of the decoration base node relative to the standard base + -- node position. + -- Can be positive or negative. Default is 0. + -- Effect is inverted for "all_ceilings" decorations. + -- Ignored by 'y_min', 'y_max' and 'spawn_by' checks, which always refer + -- to the 'place_on' node. + + ----- Schematic-type parameters + + schematic = "foobar.mts", + -- If schematic is a string, it is the filepath relative to the current + -- working directory of the specified Minetest schematic file. + -- Could also be the ID of a previously registered schematic. + + schematic = { + size = {x = 4, y = 6, z = 4}, + data = { + {name = "default:cobble", param1 = 255, param2 = 0}, + {name = "default:dirt_with_grass", param1 = 255, param2 = 0}, + {name = "air", param1 = 255, param2 = 0}, + ... + }, + yslice_prob = { + {ypos = 2, prob = 128}, + {ypos = 5, prob = 64}, + ... + }, + }, + -- Alternative schematic specification by supplying a table. The fields + -- size and data are mandatory whereas yslice_prob is optional. + -- See 'Schematic specifier' for details. + + replacements = {["oldname"] = "convert_to", ...}, + -- Map of node names to replace in the schematic after reading it. + + flags = "place_center_x, place_center_y, place_center_z", + -- Flags for schematic decorations. See 'Schematic attributes'. + + rotation = "90", + -- Rotation can be "0", "90", "180", "270", or "random" + + place_offset_y = 0, + -- If the flag 'place_center_y' is set this parameter is ignored. + -- Y offset of the schematic base node layer relative to the 'place_on' + -- node. + -- Can be positive or negative. Default is 0. + -- Effect is inverted for "all_ceilings" decorations. + -- Ignored by 'y_min', 'y_max' and 'spawn_by' checks, which always refer + -- to the 'place_on' node. + } + +Chat command definition +----------------------- + +Used by `minetest.register_chatcommand`. + + { + params = "<name> <privilege>", -- Short parameter description + + description = "Remove privilege from player", -- Full description + + privs = {privs=true}, -- Require the "privs" privilege to run + + func = function(name, param), + -- Called when command is run. Returns boolean success and text output. + -- Special case: The help message is shown to the player if `func` + -- returns false without a text output. + } + +Note that in params, use of symbols is as follows: + +* `<>` signifies a placeholder to be replaced when the command is used. For + example, when a player name is needed: `<name>` +* `[]` signifies param is optional and not required when the command is used. + For example, if you require param1 but param2 is optional: + `<param1> [<param2>]` +* `|` signifies exclusive or. The command requires one param from the options + provided. For example: `<param1> | <param2>` +* `()` signifies grouping. For example, when param1 and param2 are both + required, or only param3 is required: `(<param1> <param2>) | <param3>` + +Privilege definition +-------------------- + +Used by `minetest.register_privilege`. + + { + description = "", + -- Privilege description + + give_to_singleplayer = true, + -- Whether to grant the privilege to singleplayer. + + give_to_admin = true, + -- Whether to grant the privilege to the server admin. + -- Uses value of 'give_to_singleplayer' by default. + + on_grant = function(name, granter_name), + -- Called when given to player 'name' by 'granter_name'. + -- 'granter_name' will be nil if the priv was granted by a mod. + + on_revoke = function(name, revoker_name), + -- Called when taken from player 'name' by 'revoker_name'. + -- 'revoker_name' will be nil if the priv was revoked by a mod. + + -- Note that the above two callbacks will be called twice if a player is + -- responsible, once with the player name, and then with a nil player + -- name. + -- Return true in the above callbacks to stop register_on_priv_grant or + -- revoke being called. + } + +Detached inventory callbacks +---------------------------- + +Used by `minetest.create_detached_inventory`. + + { + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player), + -- Called when a player wants to move items inside the inventory. + -- Return value: number of items allowed to move. + + allow_put = function(inv, listname, index, stack, player), + -- Called when a player wants to put something into the inventory. + -- Return value: number of items allowed to put. + -- Return value -1: Allow and don't modify item count in inventory. + + allow_take = function(inv, listname, index, stack, player), + -- Called when a player wants to take something out of the inventory. + -- Return value: number of items allowed to take. + -- Return value -1: Allow and don't modify item count in inventory. + + on_move = function(inv, from_list, from_index, to_list, to_index, count, player), + on_put = function(inv, listname, index, stack, player), + on_take = function(inv, listname, index, stack, player), + -- Called after the actual action has happened, according to what was + -- allowed. + -- No return value. + } + +HUD Definition +-------------- + +Since most values have multiple different functions, please see the +documentation in [HUD] section. + +Used by `ObjectRef:hud_add`. Returned by `ObjectRef:hud_get`. + + { + hud_elem_type = "image", + -- Type of element, can be "image", "text", "statbar", "inventory", + -- "waypoint", "image_waypoint", "compass" or "minimap" + + position = {x=0.5, y=0.5}, + -- Top left corner position of element + + name = "<name>", + + scale = {x = 1, y = 1}, + + text = "<text>", + + text2 = "<text>", + + number = 0, + + item = 0, + + direction = 0, + -- Direction: 0: left-right, 1: right-left, 2: top-bottom, 3: bottom-top + + alignment = {x=0, y=0}, + + offset = {x=0, y=0}, + + world_pos = {x=0, y=0, z=0}, + + size = {x=0, y=0}, + + z_index = 0, + -- Z index: lower z-index HUDs are displayed behind higher z-index HUDs + + style = 0, + } + +Particle definition +------------------- + +Used by `minetest.add_particle`. + + { + pos = {x=0, y=0, z=0}, + velocity = {x=0, y=0, z=0}, + acceleration = {x=0, y=0, z=0}, + -- Spawn particle at pos with velocity and acceleration + + expirationtime = 1, + -- Disappears after expirationtime seconds + + size = 1, + -- Scales the visual size of the particle texture. + -- If `node` is set, size can be set to 0 to spawn a randomly-sized + -- particle (just like actual node dig particles). + + collisiondetection = false, + -- If true collides with `walkable` nodes and, depending on the + -- `object_collision` field, objects too. + + collision_removal = false, + -- If true particle is removed when it collides. + -- Requires collisiondetection = true to have any effect. + + object_collision = false, + -- If true particle collides with objects that are defined as + -- `physical = true,` and `collide_with_objects = true,`. + -- Requires collisiondetection = true to have any effect. + + vertical = false, + -- If true faces player using y axis only + + texture = "image.png", + -- The texture of the particle + -- v5.6.0 and later: also supports the table format described in the + -- following section + + playername = "singleplayer", + -- Optional, if specified spawns particle only on the player's client + + animation = {Tile Animation definition}, + -- Optional, specifies how to animate the particle texture + + glow = 0 + -- Optional, specify particle self-luminescence in darkness. + -- Values 0-14. + + node = {name = "ignore", param2 = 0}, + -- Optional, if specified the particle will have the same appearance as + -- node dig particles for the given node. + -- `texture` and `animation` will be ignored if this is set. + + node_tile = 0, + -- Optional, only valid in combination with `node` + -- If set to a valid number 1-6, specifies the tile from which the + -- particle texture is picked. + -- Otherwise, the default behavior is used. (currently: any random tile) + + drag = {x=0, y=0, z=0}, + -- v5.6.0 and later: Optional drag value, consult the following section + + bounce = {min = ..., max = ..., bias = 0}, + -- v5.6.0 and later: Optional bounce range, consult the following section + } + + +`ParticleSpawner` definition +---------------------------- + +Used by `minetest.add_particlespawner`. + +Before v5.6.0, particlespawners used a different syntax and had a more limited set +of features. Definition fields that are the same in both legacy and modern versions +are shown in the next listing, and the fields that are used by legacy versions are +shown separated by a comment; the modern fields are too complex to compactly +describe in this manner and are documented after the listing. + +The older syntax can be used in combination with the newer syntax (e.g. having +`minpos`, `maxpos`, and `pos` all set) to support older servers. On newer servers, +the new syntax will override the older syntax; on older servers, the newer syntax +will be ignored. + + { + -- Common fields (same name and meaning in both new and legacy syntax) + + amount = 1, + -- Number of particles spawned over the time period `time`. + + time = 1, + -- Lifespan of spawner in seconds. + -- If time is 0 spawner has infinite lifespan and spawns the `amount` on + -- a per-second basis. + + collisiondetection = false, + -- If true collide with `walkable` nodes and, depending on the + -- `object_collision` field, objects too. + + collision_removal = false, + -- If true particles are removed when they collide. + -- Requires collisiondetection = true to have any effect. + + object_collision = false, + -- If true particles collide with objects that are defined as + -- `physical = true,` and `collide_with_objects = true,`. + -- Requires collisiondetection = true to have any effect. + + attached = ObjectRef, + -- If defined, particle positions, velocities and accelerations are + -- relative to this object's position and yaw + + vertical = false, + -- If true face player using y axis only + + texture = "image.png", + -- The texture of the particle + + playername = "singleplayer", + -- Optional, if specified spawns particles only on the player's client + + animation = {Tile Animation definition}, + -- Optional, specifies how to animate the particles' texture + -- v5.6.0 and later: set length to -1 to sychronize the length + -- of the animation with the expiration time of individual particles. + -- (-2 causes the animation to be played twice, and so on) + + glow = 0, + -- Optional, specify particle self-luminescence in darkness. + -- Values 0-14. + + node = {name = "ignore", param2 = 0}, + -- Optional, if specified the particles will have the same appearance as + -- node dig particles for the given node. + -- `texture` and `animation` will be ignored if this is set. + + node_tile = 0, + -- Optional, only valid in combination with `node` + -- If set to a valid number 1-6, specifies the tile from which the + -- particle texture is picked. + -- Otherwise, the default behavior is used. (currently: any random tile) + + -- Legacy definition fields + + minpos = {x=0, y=0, z=0}, + maxpos = {x=0, y=0, z=0}, + minvel = {x=0, y=0, z=0}, + maxvel = {x=0, y=0, z=0}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 1, + maxexptime = 1, + minsize = 1, + maxsize = 1, + -- The particles' properties are random values between the min and max + -- values. + -- applies to: pos, velocity, acceleration, expirationtime, size + -- If `node` is set, min and maxsize can be set to 0 to spawn + -- randomly-sized particles (just like actual node dig particles). + } + +### Modern definition fields + +After v5.6.0, spawner properties can be defined in several different ways depending +on the level of control you need. `pos` for instance can be set as a single vector, +in which case all particles will appear at that exact point throughout the lifetime +of the spawner. Alternately, it can be specified as a min-max pair, specifying a +cubic range the particles can appear randomly within. Finally, some properties can +be animated by suffixing their key with `_tween` (e.g. `pos_tween`) and supplying +a tween table. + +The following definitions are all equivalent, listed in order of precedence from +lowest (the legacy syntax) to highest (tween tables). If multiple forms of a +property definition are present, the highest-precidence form will be selected +and all lower-precedence fields will be ignored, allowing for graceful +degradation in older clients). + + { + -- old syntax + maxpos = {x = 0, y = 0, z = 0}, + minpos = {x = 0, y = 0, z = 0}, + + -- absolute value + pos = 0, + -- all components of every particle's position vector will be set to this + -- value + + -- vec3 + pos = vector.new(0,0,0), + -- all particles will appear at this exact position throughout the lifetime + -- of the particlespawner + + -- vec3 range + pos = { + -- the particle will appear at a position that is picked at random from + -- within a cubic range + + min = vector.new(0,0,0), + -- `min` is the minimum value this property will be set to in particles + -- spawned by the generator + + max = vector.new(0,0,0), + -- `max` is the minimum value this property will be set to in particles + -- spawned by the generator + + bias = 0, + -- when `bias` is 0, all random values are exactly as likely as any + -- other. when it is positive, the higher it is, the more likely values + -- will appear towards the minimum end of the allowed spectrum. when + -- it is negative, the lower it is, the more likely values will appear + -- towards the maximum end of the allowed spectrum. the curve is + -- exponential and there is no particular maximum or minimum value + }, + + -- tween table + pos_tween = {...}, + -- a tween table should consist of a list of frames in the same form as the + -- untweened pos property above, which the engine will interpolate between, + -- and optionally a number of properties that control how the interpolation + -- takes place. currently **only two frames**, the first and the last, are + -- used, but extra frames are accepted for the sake of forward compatibility. + -- any of the above definition styles can be used here as well in any combination + -- supported by the property type + + pos_tween = { + style = "fwd", + -- linear animation from first to last frame (default) + style = "rev", + -- linear animation from last to first frame + style = "pulse", + -- linear animation from first to last then back to first again + style = "flicker", + -- like "pulse", but slightly randomized to add a bit of stutter + + reps = 1, + -- number of times the animation is played over the particle's lifespan + + start = 0.0, + -- point in the spawner's lifespan at which the animation begins. 0 is + -- the very beginning, 1 is the very end + + -- frames can be defined in a number of different ways, depending on the + -- underlying type of the property. for now, all but the first and last + -- frame are ignored + + -- frames + + -- floats + 0, 0, + + -- vec3s + vector.new(0,0,0), + vector.new(0,0,0), + + -- vec3 ranges + { min = vector.new(0,0,0), max = vector.new(0,0,0), bias = 0 }, + { min = vector.new(0,0,0), max = vector.new(0,0,0), bias = 0 }, + + -- mixed + 0, { min = vector.new(0,0,0), max = vector.new(0,0,0), bias = 0 }, + }, + } + +All of the properties that can be defined in this way are listed in the next +section, along with the datatypes they accept. + +#### List of particlespawner properties +All of the properties in this list can be animated with `*_tween` tables +unless otherwise specified. For example, `jitter` can be tweened by setting +a `jitter_tween` table instead of (or in addition to) a `jitter` table/value. +Types used are defined in the previous section. + +* vec3 range `pos`: the position at which particles can appear +* vec3 range `vel`: the initial velocity of the particle +* vec3 range `acc`: the direction and speed with which the particle + accelerates +* vec3 range `jitter`: offsets the velocity of each particle by a random + amount within the specified range each frame. used to create Brownian motion. +* vec3 range `drag`: the amount by which absolute particle velocity along + each axis is decreased per second. a value of 1.0 means that the particle + will be slowed to a stop over the space of a second; a value of -1.0 means + that the particle speed will be doubled every second. to avoid interfering + with gravity provided by `acc`, a drag vector like `vector.new(1,0,1)` can + be used instead of a uniform value. +* float range `bounce`: how bouncy the particles are when `collisiondetection` + is turned on. values less than or equal to `0` turn off particle bounce; + `1` makes the particles bounce without losing any velocity, and `2` makes + them double their velocity with every bounce. `bounce` is not bounded but + values much larger than `1.0` probably aren't very useful. +* float range `exptime`: the number of seconds after which the particle + disappears. +* table `attract`: sets the birth orientation of particles relative to various + shapes defined in world coordinate space. this is an alternative means of + setting the velocity which allows particles to emerge from or enter into + some entity or node on the map, rather than simply being assigned random + velocity values within a range. the velocity calculated by this method will + be **added** to that specified by `vel` if `vel` is also set, so in most + cases **`vel` should be set to 0**. `attract` has the fields: + * string `kind`: selects the kind of shape towards which the particles will + be oriented. it must have one of the following values: + * `"none"`: no attractor is set and the `attractor` table is ignored + * `"point"`: the particles are attracted to a specific point in space. + use this also if you want a sphere-like effect, in combination with + the `radius` property. + * `"line"`: the particles are attracted to an (infinite) line passing + through the points `origin` and `angle`. use this for e.g. beacon + effects, energy beam effects, etc. + * `"plane"`: the particles are attracted to an (infinite) plane on whose + surface `origin` designates a point in world coordinate space. use this + for e.g. particles entering or emerging from a portal. + * float range `strength`: the speed with which particles will move towards + `attractor`. If negative, the particles will instead move away from that + point. + * vec3 `origin`: the origin point of the shape towards which particles will + initially be oriented. functions as an offset if `origin_attached` is also + set. + * vec3 `direction`: sets the direction in which the attractor shape faces. for + lines, this sets the angle of the line; e.g. a vector of (0,1,0) will + create a vertical line that passes through `origin`. for planes, `direction` + is the surface normal of an infinite plane on whose surface `origin` is + a point. functions as an offset if `direction_attached` is also set. + * entity `origin_attached`: allows the origin to be specified as an offset + from the position of an entity rather than a coordinate in world space. + * entity `direction_attached`: allows the direction to be specified as an offset + from the position of an entity rather than a coordinate in world space. + * bool `die_on_contact`: if true, the particles' lifetimes are adjusted so + that they will die as they cross the attractor threshold. this behavior + is the default but is undesirable for some kinds of animations; set it to + false to allow particles to live out their natural lives. +* vec3 range `radius`: if set, particles will be arranged in a sphere around + `pos`. A constant can be used to create a spherical shell of particles, a + vector to create an ovoid shell, and a range to create a volume; e.g. + `{min = 0.5, max = 1, bias = 1}` will allow particles to appear between 0.5 + and 1 nodes away from `pos` but will cluster them towards the center of the + sphere. Usually if `radius` is used, `pos` should be a single point, but it + can still be a range if you really know what you're doing (e.g. to create a + "roundcube" emitter volume). + +### Textures + +In versions before v5.6.0, particlespawner textures could only be specified as a single +texture string. After v5.6.0, textures can now be specified as a table as well. This +table contains options that allow simple animations to be applied to the texture. + + texture = { + name = "mymod_particle_texture.png", + -- the texture specification string + + alpha = 1.0, + -- controls how visible the particle is; at 1.0 the particle is fully + -- visible, at 0, it is completely invisible. + + alpha_tween = {1, 0}, + -- can be used instead of `alpha` to animate the alpha value over the + -- particle's lifetime. these tween tables work identically to the tween + -- tables used in particlespawner properties, except that time references + -- are understood with respect to the particle's lifetime, not the + -- spawner's. {1,0} fades the particle out over its lifetime. + + scale = 1, + scale = {x = 1, y = 1}, + -- scales the texture onscreen + + scale_tween = { + {x = 1, y = 1}, + {x = 0, y = 1}, + }, + -- animates the scale over the particle's lifetime. works like the + -- alpha_tween table, but can accept two-dimensional vectors as well as + -- integer values. the example value would cause the particle to shrink + -- in one dimension over the course of its life until it disappears + + blend = "alpha", + -- (default) blends transparent pixels with those they are drawn atop + -- according to the alpha channel of the source texture. useful for + -- e.g. material objects like rocks, dirt, smoke, or node chunks + blend = "add", + -- adds the value of pixels to those underneath them, modulo the sources + -- alpha channel. useful for e.g. bright light effects like sparks or fire + blend = "screen", + -- like "add" but less bright. useful for subtler light effecs. note that + -- this is NOT formally equivalent to the "screen" effect used in image + -- editors and compositors, as it does not respect the alpha channel of + -- of the image being blended + blend = "sub", + -- the inverse of "add"; the value of the source pixel is subtracted from + -- the pixel underneath it. a white pixel will turn whatever is underneath + -- it black; a black pixel will be "transparent". useful for creating + -- darkening effects + + animation = {Tile Animation definition}, + -- overrides the particlespawner's global animation property for a single + -- specific texture + } + +Instead of setting a single texture definition, it is also possible to set a +`texpool` property. A `texpool` consists of a list of possible particle textures. +Every time a particle is spawned, the engine will pick a texture at random from +the `texpool` and assign it as that particle's texture. You can also specify a +`texture` in addition to a `texpool`; the `texture` value will be ignored on newer +clients but will be sent to older (pre-v5.6.0) clients that do not implement +texpools. + + texpool = { + "mymod_particle_texture.png"; + { name = "mymod_spark.png", fade = "out" }, + { + name = "mymod_dust.png", + alpha = 0.3, + scale = 1.5, + animation = { + type = "vertical_frames", + aspect_w = 16, aspect_h = 16, + + length = 3, + -- the animation lasts for 3s and then repeats + length = -3, + -- repeat the animation three times over the particle's lifetime + -- (post-v5.6.0 clients only) + }, + }, + } + +#### List of animatable texture properties + +While animated particlespawner values vary over the course of the particlespawner's +lifetime, animated texture properties vary over the lifespans of the individual +particles spawned with that texture. So a particle with the texture property + + alpha_tween = { + 0.0, 1.0, + style = "pulse", + reps = 4, + } + +would be invisible at its spawning, pulse visible four times throughout its +lifespan, and then vanish again before expiring. + +* float `alpha` (0.0 - 1.0): controls the visibility of the texture +* vec2 `scale`: controls the size of the displayed billboard onscreen. Its units + are multiples of the parent particle's assigned size (see the `size` property above) + +`HTTPRequest` definition +------------------------ + +Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`. + + { + url = "http://example.org", + + timeout = 10, + -- Timeout for request to be completed in seconds. Default depends on engine settings. + + method = "GET", "POST", "PUT" or "DELETE" + -- The http method to use. Defaults to "GET". + + data = "Raw request data string" OR {field1 = "data1", field2 = "data2"}, + -- Data for the POST, PUT or DELETE request. + -- Accepts both a string and a table. If a table is specified, encodes + -- table as x-www-form-urlencoded key-value pairs. + + user_agent = "ExampleUserAgent", + -- Optional, if specified replaces the default minetest user agent with + -- given string + + extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" }, + -- Optional, if specified adds additional headers to the HTTP request. + -- You must make sure that the header strings follow HTTP specification + -- ("Key: Value"). + + multipart = boolean + -- Optional, if true performs a multipart HTTP request. + -- Default is false. + -- Post only, data must be array + + post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"}, + -- Deprecated, use `data` instead. Forces `method = "POST"`. + } + +`HTTPRequestResult` definition +------------------------------ + +Passed to `HTTPApiTable.fetch` callback. Returned by +`HTTPApiTable.fetch_async_get`. + + { + completed = true, + -- If true, the request has finished (either succeeded, failed or timed + -- out) + + succeeded = true, + -- If true, the request was successful + + timeout = false, + -- If true, the request timed out + + code = 200, + -- HTTP status code + + data = "response" + } + +Authentication handler definition +--------------------------------- + +Used by `minetest.register_authentication_handler`. + + { + get_auth = function(name), + -- Get authentication data for existing player `name` (`nil` if player + -- doesn't exist). + -- Returns following structure: + -- `{password=<string>, privileges=<table>, last_login=<number or nil>}` + + create_auth = function(name, password), + -- Create new auth data for player `name`. + -- Note that `password` is not plain-text but an arbitrary + -- representation decided by the engine. + + delete_auth = function(name), + -- Delete auth data of player `name`. + -- Returns boolean indicating success (false if player is nonexistent). + + set_password = function(name, password), + -- Set password of player `name` to `password`. + -- Auth data should be created if not present. + + set_privileges = function(name, privileges), + -- Set privileges of player `name`. + -- `privileges` is in table form, auth data should be created if not + -- present. + + reload = function(), + -- Reload authentication data from the storage location. + -- Returns boolean indicating success. + + record_login = function(name), + -- Called when player joins, used for keeping track of last_login + + iterate = function(), + -- Returns an iterator (use with `for` loops) for all player names + -- currently in the auth database + } + +Bit Library +----------- + +Functions: bit.tobit, bit.tohex, bit.bnot, bit.band, bit.bor, bit.bxor, bit.lshift, bit.rshift, bit.arshift, bit.rol, bit.ror, bit.bswap + +See http://bitop.luajit.org/ for advanced information. diff --git a/doc/main_page.dox b/doc/main_page.dox new file mode 100644 index 0000000..8211d9c --- /dev/null +++ b/doc/main_page.dox @@ -0,0 +1,8 @@ +/** @mainpage The Minetest engine internal documentation + +Welcome to the Minetest engine Doxygen documentation site!\n +This page documents the internal structure of the Minetest engine's C++ code.\n +Use the tree view at the left to navigate. + +*/ + diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt new file mode 100644 index 0000000..4d495f2 --- /dev/null +++ b/doc/menu_lua_api.txt @@ -0,0 +1,382 @@ +Minetest Lua Mainmenu API Reference 5.6.0 +========================================= + +Introduction +------------- + +The main menu is defined as a formspec by Lua in builtin/mainmenu/ +Description of formspec language to show your menu is in lua_api.txt + + +Callbacks +--------- + +core.button_handler(fields): called when a button is pressed. +^ fields = {name1 = value1, name2 = value2, ...} +core.event_handler(event) +^ event: "MenuQuit", "KeyEnter", "ExitButton" or "EditBoxEnter" + + +Gamedata +-------- + +The "gamedata" table is read when calling core.start(). It should contain: +{ + playername = <name>, + password = <password>, + address = <IP/adress>, + port = <port>, + selected_world = <index>, -- 0 for client mode + singleplayer = <true/false>, +} + + +Functions +--------- + +core.start() +core.close() +core.get_min_supp_proto() +^ returns the minimum supported network protocol version +core.get_max_supp_proto() +^ returns the maximum supported network protocol version +core.open_url(url) +^ opens the URL in a web browser, returns false on failure. +^ Must begin with http:// or https:// +core.open_dir(path) +^ opens the path in the system file browser/explorer, returns false on failure. +^ Must be an existing directory. +core.share_file(path) +^ Android only. Shares file using the share popup +core.get_version() (possible in async calls) +^ returns current core version + + + +Filesystem +---------- + +core.get_builtin_path() +^ returns path to builtin root +core.create_dir(absolute_path) (possible in async calls) +^ absolute_path to directory to create (needs to be absolute) +^ returns true/false +core.delete_dir(absolute_path) (possible in async calls) +^ absolute_path to directory to delete (needs to be absolute) +^ returns true/false +core.copy_dir(source,destination,keep_soure) (possible in async calls) +^ source folder +^ destination folder +^ keep_source DEFAULT true --> if set to false source is deleted after copying +^ returns true/false +core.is_dir(path) (possible in async calls) +^ returns true if path is a valid dir +core.extract_zip(zipfile,destination) [unzip within path required] +^ zipfile to extract +^ destination folder to extract to +^ returns true/false +core.sound_play(spec, looped) -> handle +^ spec = SimpleSoundSpec (see lua-api.txt) +^ looped = bool +core.sound_stop(handle) +core.get_video_drivers() +^ get list of video drivers supported by engine (not all modes are guaranteed to work) +^ returns list of available video drivers' settings name and 'friendly' display name +^ e.g. { {name="opengl", friendly_name="OpenGL"}, {name="software", friendly_name="Software Renderer"} } +^ first element of returned list is guaranteed to be the NULL driver +core.get_mapgen_names([include_hidden=false]) -> table of map generator algorithms + registered in the core (possible in async calls) +core.get_cache_path() -> path of cache +core.get_temp_path([param]) (possible in async calls) +^ param=true: returns path to a temporary file +^ otherwise: returns path to the temporary folder + + +HTTP Requests +------------- + +* core.download_file(url, target) (possible in async calls) + * url to download, and target to store to + * returns true/false +* `minetest.get_http_api()` (possible in async calls) + * returns `HTTPApiTable` containing http functions. + * The returned table contains the functions `fetch_sync`, `fetch_async` and + `fetch_async_get` described below. + * Function only exists if minetest server was built with cURL support. +* `HTTPApiTable.fetch_sync(HTTPRequest req)`: returns HTTPRequestResult + * Performs given request synchronously +* `HTTPApiTable.fetch_async(HTTPRequest req)`: returns handle + * Performs given request asynchronously and returns handle for + `HTTPApiTable.fetch_async_get` +* `HTTPApiTable.fetch_async_get(handle)`: returns HTTPRequestResult + * Return response data for given asynchronous HTTP request + +### `HTTPRequest` definition + +Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`. + + { + url = "http://example.org", + + timeout = 10, + -- Timeout for connection in seconds. Default is 3 seconds. + + post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"}, + -- Optional, if specified a POST request with post_data is performed. + -- Accepts both a string and a table. If a table is specified, encodes + -- table as x-www-form-urlencoded key-value pairs. + -- If post_data is not specified, a GET request is performed instead. + + user_agent = "ExampleUserAgent", + -- Optional, if specified replaces the default minetest user agent with + -- given string + + extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" }, + -- Optional, if specified adds additional headers to the HTTP request. + -- You must make sure that the header strings follow HTTP specification + -- ("Key: Value"). + + multipart = boolean + -- Optional, if true performs a multipart HTTP request. + -- Default is false. + } + +### `HTTPRequestResult` definition + +Passed to `HTTPApiTable.fetch` callback. Returned by +`HTTPApiTable.fetch_async_get`. + + { + completed = true, + -- If true, the request has finished (either succeeded, failed or timed + -- out) + + succeeded = true, + -- If true, the request was successful + + timeout = false, + -- If true, the request timed out + + code = 200, + -- HTTP status code + + data = "response" + } + + +Formspec +-------- + +core.update_formspec(formspec) +core.get_table_index(tablename) -> index +^ can also handle textlists +core.formspec_escape(string) -> string +^ escapes characters [ ] \ , ; that can not be used in formspecs +core.explode_table_event(string) -> table +^ returns e.g. {type="CHG", row=1, column=2} +^ type: "INV" (no row selected), "CHG" (selected) or "DCL" (double-click) +core.explode_textlist_event(string) -> table +^ returns e.g. {type="CHG", index=1} +^ type: "INV" (no row selected), "CHG" (selected) or "DCL" (double-click) +core.set_formspec_prepend(formspec) +^ string to be added to every mainmenu formspec, to be used for theming. + + +GUI +--- + +core.set_background(type, texturepath,[tile],[minsize]) +^ type: "background", "overlay", "header" or "footer" +^ tile: tile the image instead of scaling (background only) +^ minsize: minimum tile size, images are scaled to at least this size prior +^ doing tiling (background only) +core.set_clouds(<true/false>) +core.set_topleft_text(text) +core.show_keys_menu() +core.show_path_select_dialog(formname, caption, is_file_select) +^ shows a path select dialog +^ formname is base name of dialog response returned in fields +^ -if dialog was accepted "_accepted" +^ will be added to fieldname containing the path +^ -if dialog was canceled "_cancelled" +^ will be added to fieldname value is set to formname itself +^ if `is_file_select` is `true`, a file and not a folder will be selected +^ returns nil or selected file/folder +core.get_screen_info() +^ returns { + density = <screen density 0.75,1.0,2.0,3.0 ... (dpi)>, + display_width = <width of display>, + display_height = <height of display>, + window_width = <current window width>, + window_height = <current window height>, + render_info = <active render information> + } + + +Content and Packages +-------------------- + +Content - an installed mod, modpack, game, or texture pack (txt) +Package - content which is downloadable from the content db, may or may not be installed. + +* core.get_user_path() (possible in async calls) + * returns path to global user data, + the directory that contains user-provided mods, worlds, games, and texture packs. +* core.get_modpath() (possible in async calls) + * returns path to global modpath in the user path, where mods can be installed +* core.get_modpaths() (possible in async calls) + * returns table of virtual path to global modpaths, where mods have been installed + The difference with "core.get_modpath" is that no mods should be installed in these + directories by Minetest -- they might be read-only. + + Ex: + + ``` + { + mods = "/home/user/.minetest/mods", + share = "/usr/share/minetest/mods", + + -- Custom dirs can be specified by the MINETEST_MOD_DIR env variable + ["/path/to/custom/dir"] = "/path/to/custom/dir", + } + ``` + +* core.get_clientmodpath() (possible in async calls) + * returns path to global client-side modpath +* core.get_gamepath() (possible in async calls) + * returns path to global gamepath +* core.get_texturepath() (possible in async calls) + * returns path to default textures +* core.get_game(index) + * `name` in return value is deprecated, use `title` instead. + * returns: + + { + id = <id>, + path = <full path to game>, + gamemods_path = <path>, + title = <title of game>, + menuicon_path = <full path to menuicon>, + author = "author", + DEPRECATED: + addon_mods_paths = {[1] = <path>,}, + } + +* core.get_games() -> table of all games in upper format (possible in async calls) +* core.get_content_info(path) + * returns + + { + name = "technical_id", + type = "mod" or "modpack" or "game" or "txp", + title = "Human readable title", + description = "description", + author = "author", + path = "path/to/content", + depends = {"mod", "names"}, -- mods only + optional_depends = {"mod", "names"}, -- mods only + } +* core.check_mod_configuration(world_path, mod_paths) + * Checks whether configuration is valid. + * `world_path`: path to the world + * `mod_paths`: list of enabled mod paths + * returns: + + { + is_consistent = true, -- true is consistent, false otherwise + unsatisfied_mods = {}, -- list of mod specs + satisfied_mods = {}, -- list of mod specs + error_message = "", -- message or nil + } + +Logging +------- + +core.debug(line) (possible in async calls) +^ Always printed to stderr and logfile (print() is redirected here) +core.log(line) (possible in async calls) +core.log(loglevel, line) (possible in async calls) +^ loglevel one of "error", "action", "info", "verbose" + + +Settings +-------- + +core.settings:set(name, value) +core.settings:get(name) -> string or nil (possible in async calls) +core.settings:set_bool(name, value) +core.settings:get_bool(name) -> bool or nil (possible in async calls) +core.settings:save() -> nil, save all settings to config file + +For a complete list of methods of the Settings object see +[lua_api.txt](https://github.com/minetest/minetest/blob/master/doc/lua_api.txt) + + +Worlds +------ + +core.get_worlds() -> list of worlds (possible in async calls) +^ returns { + [1] = { + path = <full path to world>, + name = <name of world>, + gameid = <gameid of world>, + }, +} +core.create_world(worldname, gameid) +core.delete_world(index) + + +Helpers +------- + +core.get_us_time() +^ returns time with microsecond precision +core.gettext(string) -> string +^ look up the translation of a string in the gettext message catalog +fgettext_ne(string, ...) +^ call core.gettext(string), replace "$1"..."$9" with the given +^ extra arguments and return the result +fgettext(string, ...) -> string +^ same as fgettext_ne(), but calls core.formspec_escape before returning result +core.parse_json(string[, nullvalue]) -> something (possible in async calls) +^ see core.parse_json (lua_api.txt) +dump(obj, dumped={}) +^ Return object serialized as a string +string:split(separator) +^ eg. string:split("a,b", ",") == {"a","b"} +string:trim() +^ eg. string.trim("\n \t\tfoo bar\t ") == "foo bar" +core.is_yes(arg) (possible in async calls) +^ returns whether arg can be interpreted as yes +minetest.encode_base64(string) (possible in async calls) +^ Encodes a string in base64. +minetest.decode_base64(string) (possible in async calls) +^ Decodes a string encoded in base64. + + +Async +----- + +core.handle_async(async_job,parameters,finished) +^ execute a function asynchronously +^ async_job is a function receiving one parameter and returning one parameter +^ parameters parameter table passed to async_job +^ finished function to be called once async_job has finished +^ the result of async_job is passed to this function + +Limitations of Async operations + -No access to global lua variables, don't even try + -Limited set of available functions + e.g. No access to functions modifying menu like core.start,core.close, + core.show_path_select_dialog + + +Background music +---------------- + +The main menu supports background music. +It looks for a `main_menu` sound in `$USER_PATH/sounds`. The same naming +conventions as for normal sounds apply. +This means the player can add a custom sound. +It will be played in the main menu (gain = 1.0), looped. diff --git a/doc/minetest.6 b/doc/minetest.6 new file mode 100644 index 0000000..27a3d00 --- /dev/null +++ b/doc/minetest.6 @@ -0,0 +1,139 @@ +.TH minetest 6 "2 February 2019" "" "" + +.SH NAME +minetest, minetestserver \- Multiplayer infinite-world block sandbox + +.SH SYNOPSIS +.B minetest +[\fB--server SERVER OPTIONS\fR | \fBCLIENT OPTIONS\fR] +[\fBCOMMON OPTIONS\fR] +[\fBWORLD PATH\fR] + +.B minetestserver +[\fBSERVER OPTIONS\fR] +[\fBCOMMON OPTIONS\fR] +[\fBWORLD PATH\fR] + +.SH DESCRIPTION +.B Minetest is one of the first InfiniMiner/Minecraft(/whatever) inspired games +(started October 2010), with a goal of taking the survival multiplayer gameplay +in a slightly different direction. +.PP +The main design philosophy is to keep it technically simple, stable and +portable. It will be kept lightweight enough to run on fairly old hardware. + +.SH COMMON OPTIONS +.TP +.B \-\-help +Print allowed options and exit +.TP +.B \-\-version +Print version information and exit +.TP +.B \-\-config <value> +Load configuration from specified file +.TP +.B \-\-logfile <value> +Set logfile path ('' for no logging) +.TP +.B \-\-info +Print more information to console +.TP +.B \-\-verbose +Print even more information to console +.TP +.B \-\-trace +Print enormous amounts of information to console +.TP +.B \-\-quiet +Print only errors to console +.TP +.B \-\-color <value> +Colorize the logs ('always', 'never' or 'auto'), defaults to 'auto' +.TP +.B \-\-gameid <value> | list +Set gameid or list available ones +.TP +.B \-\-worldname <value> +Set world path by name +.TP +.B \-\-world <value> +Set world path +.TP +.B \-\-worldlist path | name | both +Get list of worlds ('path' lists paths, 'name' lists names, 'both' lists both) +.TP +.B \-\-map\-dir <value> +Same as \-\-world (deprecated) +.TP +.B \-\-port <value> +Set network port (UDP) to use +.TP +.B \-\-run\-unittests +Run unit tests and exit + +.SH CLIENT OPTIONS +.TP +.B \-\-address <value> +Address to connect to +.TP +.B \-\-go +Disable main menu +.TP +.B \-\-name <value> +Set player name +.TP +.B \-\-password <value> +Set password +.TP +.B \-\-password\-file <value> +Set password from contents of file +.TP +.B \-\-random\-input +Enable random user input, for testing (client only) +.TP +.TP +.B \-\-speedtests +Run speed tests + +.SH SERVER OPTIONS +.TP +.B \-\-migrate <value> +Migrate from current map backend to another. Possible values are sqlite3, +leveldb, redis, postgresql, and dummy. +.TP +.B \-\-migrate-auth <value> +Migrate from current auth backend to another. Possible values are sqlite3, +leveldb, and files. +.TP +.B \-\-migrate-players <value> +Migrate from current players backend to another. Possible values are sqlite3, +leveldb, postgresql, dummy, and files. +.TP +.B \-\-migrate-mod-storage <value> +Migrate from current mod storage backend to another. Possible values are +sqlite3, dummy, and files. +.TP +.B \-\-terminal +Display an interactive terminal over ncurses during execution. + +.SH ENVIRONMENT +.TP +.B MINETEST_SUBGAME_PATH +Colon delimited list of directories to search for games. +.TP +.B MINETEST_MOD_PATH +Colon delimited list of directories to search for mods. + +.SH BUGS +Please report all bugs at https://github.com/minetest/minetest/issues. + +.SH AUTHOR +.PP +Perttu Ahola <celeron55@gmail.com> and contributors. +.PP +This man page was originally written by +Juhani Numminen <juhaninumminen0@gmail.com>. + +.SH WWW +http://www.minetest.net/ diff --git a/doc/minetestserver.6 b/doc/minetestserver.6 new file mode 100644 index 0000000..db5330d --- /dev/null +++ b/doc/minetestserver.6 @@ -0,0 +1,2 @@ +.so man6/minetest.6 + diff --git a/doc/mkdocs/build.sh b/doc/mkdocs/build.sh new file mode 100644 index 0000000..f4d9468 --- /dev/null +++ b/doc/mkdocs/build.sh @@ -0,0 +1,41 @@ +#!/bin/sh -e + +# Patch Python-Markdown +MARKDOWN_FILE=$(pip show markdown | awk '/Location/ { print $2 }')/markdown/extensions/codehilite.py +patch -N -r - $MARKDOWN_FILE lua_highlight.patch || true + +# Split lua_api.txt on top level headings +cat ../lua_api.txt | csplit -sz -f docs/section - '/^=/-1' '{*}' + +cat > mkdocs.yml << EOF +site_name: Minetest API Documentation +theme: + name: readthedocs + highlightjs: False +extra_css: + - css/code_styles.css + - css/extra.css +markdown_extensions: + - toc: + permalink: True + - codehilite +plugins: + - search: + separator: '[\s\-\.\(]+' +nav: +- "Home": index.md +EOF + +mv docs/section00 docs/index.md + +for f in docs/section* +do + title=$(head -1 $f) + fname=$(echo $title | tr '[:upper:]' '[:lower:]') + fname=$(echo $fname | sed 's/ /-/g') + fname=$(echo $fname | sed "s/'//g").md + mv $f docs/$fname + echo "- \"$title\": $fname" >> mkdocs.yml +done + +mkdocs build --site-dir ../../public diff --git a/doc/mkdocs/docs/css/code_styles.css b/doc/mkdocs/docs/css/code_styles.css new file mode 100644 index 0000000..c135acd --- /dev/null +++ b/doc/mkdocs/docs/css/code_styles.css @@ -0,0 +1,68 @@ +.codehilite .hll { background-color: #ffffcc } +.codehilite .c { color: #408080; font-style: italic } /* Comment */ +/* .codehilite .err { border: 1px solid #FF0000 } /* Error */ +.codehilite .k { color: #008000; font-weight: bold } /* Keyword */ +.codehilite .o { color: #666666 } /* Operator */ +.codehilite .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ +.codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.codehilite .cp { color: #BC7A00 } /* Comment.Preproc */ +.codehilite .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ +.codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */ +.codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */ +.codehilite .gd { color: #A00000 } /* Generic.Deleted */ +.codehilite .ge { font-style: italic } /* Generic.Emph */ +.codehilite .gr { color: #FF0000 } /* Generic.Error */ +.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.codehilite .gi { color: #00A000 } /* Generic.Inserted */ +.codehilite .go { color: #888888 } /* Generic.Output */ +.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.codehilite .gs { font-weight: bold } /* Generic.Strong */ +.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.codehilite .gt { color: #0044DD } /* Generic.Traceback */ +.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.codehilite .kp { color: #008000 } /* Keyword.Pseudo */ +.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.codehilite .kt { color: #B00040 } /* Keyword.Type */ +.codehilite .m { color: #666666 } /* Literal.Number */ +.codehilite .s { color: #BA2121 } /* Literal.String */ +.codehilite .na { color: #7D9029 } /* Name.Attribute */ +.codehilite .nb { color: #008000 } /* Name.Builtin */ +.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.codehilite .no { color: #880000 } /* Name.Constant */ +.codehilite .nd { color: #AA22FF } /* Name.Decorator */ +.codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.codehilite .nf { color: #0000FF } /* Name.Function */ +.codehilite .nl { color: #A0A000 } /* Name.Label */ +.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.codehilite .nv { color: #19177C } /* Name.Variable */ +.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.codehilite .w { color: #bbbbbb } /* Text.Whitespace */ +.codehilite .mb { color: #666666 } /* Literal.Number.Bin */ +.codehilite .mf { color: #666666 } /* Literal.Number.Float */ +.codehilite .mh { color: #666666 } /* Literal.Number.Hex */ +.codehilite .mi { color: #666666 } /* Literal.Number.Integer */ +.codehilite .mo { color: #666666 } /* Literal.Number.Oct */ +.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */ +.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */ +.codehilite .sc { color: #BA2121 } /* Literal.String.Char */ +.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */ +.codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.codehilite .sx { color: #008000 } /* Literal.String.Other */ +.codehilite .sr { color: #BB6688 } /* Literal.String.Regex */ +.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */ +.codehilite .ss { color: #19177C } /* Literal.String.Symbol */ +.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.codehilite .fm { color: #0000FF } /* Name.Function.Magic */ +.codehilite .vc { color: #19177C } /* Name.Variable.Class */ +.codehilite .vg { color: #19177C } /* Name.Variable.Global */ +.codehilite .vi { color: #19177C } /* Name.Variable.Instance */ +.codehilite .vm { color: #19177C } /* Name.Variable.Magic */ +.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/doc/mkdocs/docs/css/extra.css b/doc/mkdocs/docs/css/extra.css new file mode 100644 index 0000000..8fde9f8 --- /dev/null +++ b/doc/mkdocs/docs/css/extra.css @@ -0,0 +1,15 @@ +/* Fix partly obscured last TOC element */ +.wy-menu { + padding-bottom: 20px; +} + +/* Use Minetest green instead of blue */ +.wy-nav-content a { + color: hsl(100, 40%, 40%); +} +.wy-nav-content a:hover { + color: hsl(100, 30%, 30%); +} +.wy-side-nav-search, .wy-nav-top, .wy-menu-vertical a:active { + background: hsl(100, 40%, 40%); +} diff --git a/doc/mkdocs/docs/img/favicon.ico b/doc/mkdocs/docs/img/favicon.ico new file mode 100644 index 0000000..cac34a3 --- /dev/null +++ b/doc/mkdocs/docs/img/favicon.ico @@ -0,0 +1 @@ +../../../../misc/minetest-icon.ico \ No newline at end of file diff --git a/doc/mkdocs/lua_highlight.patch b/doc/mkdocs/lua_highlight.patch new file mode 100644 index 0000000..e231081 --- /dev/null +++ b/doc/mkdocs/lua_highlight.patch @@ -0,0 +1,9 @@ +@@ -75,7 +75,7 @@ + css_class="codehilite", lang=None, style='default', + noclasses=False, tab_length=4, hl_lines=None, use_pygments=True): + self.src = src +- self.lang = lang ++ self.lang = "lua" + self.linenums = linenums + self.guess_lang = guess_lang + self.css_class = css_class diff --git a/doc/mod_channels.png b/doc/mod_channels.png new file mode 100644 index 0000000..08fdfca Binary files /dev/null and b/doc/mod_channels.png differ diff --git a/doc/protocol.txt b/doc/protocol.txt new file mode 100644 index 0000000..4c8ddd5 --- /dev/null +++ b/doc/protocol.txt @@ -0,0 +1,110 @@ +Minetest protocol (incomplete, early draft): +Updated 2011-06-18 + +A custom protocol over UDP. +Integers are big endian. +Refer to connection.{h,cpp} for further reference. + +Initialization: +- A dummy reliable packet with peer_id=PEER_ID_INEXISTENT=0 is sent to the server: + - Actually this can be sent without the reliable packet header, too, i guess, + but the sequence number in the header allows the sender to re-send the + packet without accidentally getting a double initialization. + - Packet content: + # Basic header + u32 protocol_id = PROTOCOL_ID = 0x4f457403 + u16 sender_peer_id = PEER_ID_INEXISTENT = 0 + u8 channel = 0 + # Reliable packet header + u8 type = TYPE_RELIABLE = 3 + u16 seqnum = SEQNUM_INITIAL = 65500 + # Original packet header + u8 type = TYPE_ORIGINAL = 1 + # And no actual payload. +- Server responds with something like this: + - Packet content: + # Basic header + u32 protocol_id = PROTOCOL_ID = 0x4f457403 + u16 sender_peer_id = PEER_ID_INEXISTENT = 0 + u8 channel = 0 + # Reliable packet header + u8 type = TYPE_RELIABLE = 3 + u16 seqnum = SEQNUM_INITIAL = 65500 + # Control packet header + u8 type = TYPE_CONTROL = 0 + u8 controltype = CONTROLTYPE_SET_PEER_ID = 1 + u16 peer_id_new = assigned peer id to client (other than 0 or 1) +- Then the connection can be disconnected by sending: + - Packet content: + # Basic header + u32 protocol_id = PROTOCOL_ID = 0x4f457403 + u16 sender_peer_id = whatever was gotten in CONTROLTYPE_SET_PEER_ID + u8 channel = 0 + # Control packet header + u8 type = TYPE_CONTROL = 0 + u8 controltype = CONTROLTYPE_DISCO = 3 + +- Here's a quick untested connect-disconnect done in PHP: +# host: ip of server (use gethostbyname(hostname) to get from a dns name) +# port: port of server +function check_if_minetestserver_up($host, $port) +{ + $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); + $timeout = array("sec" => 1, "usec" => 0); + socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $timeout); + $buf = "\x4f\x45\x74\x03\x00\x00\x00\x03\xff\xdc\x01"; + socket_sendto($socket, $buf, strlen($buf), 0, $host, $port); + $buf = socket_read($socket, 1000); + if($buf != "") + { + # We got a reply! read the peer id from it. + $peer_id = substr($buf, 9, 2); + + # Disconnect + $buf = "\x4f\x45\x74\x03".$peer_id."\x00\x00\x03"; + socket_sendto($socket, $buf, strlen($buf), 0, $host, $port); + socket_close($socket); + + return true; + } + return false; +} + +- Here's a Python script for checking if a minetest server is up, confirmed working + +#!/usr/bin/env python3 +import sys, time, socket + +address = "" +port = 30000 +if len(sys.argv) <= 1: + print("Usage: %s <address>" % sys.argv[0]) + exit() +if ":" in sys.argv[1]: + address = sys.argv[1].split(":")[0] + try: + port = int(sys.argv[1].split(":")[1]) + except ValueError: + print("Please specify a valid port") + exit() +else: + address = sys.argv[1] + +try: + start = time.time() + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.settimeout(2.0) + buf = b"\x4f\x45\x74\x03\x00\x00\x00\x01" + sock.sendto(buf, (address, port)) + data, addr = sock.recvfrom(1000) + if data: + peer_id = data[12:14] + buf = b"\x4f\x45\x74\x03" + peer_id + b"\x00\x00\x03" + sock.sendto(buf, (address, port)) + sock.close() + end = time.time() + print("%s is up (%0.5fms)" % (sys.argv[1], end - start)) + else: + print("%s seems to be down " % sys.argv[1]) +except Exception as err: + print("%s seems to be down (%s) " % (sys.argv[1], str(err))) diff --git a/doc/texture_packs.txt b/doc/texture_packs.txt new file mode 100644 index 0000000..f738032 --- /dev/null +++ b/doc/texture_packs.txt @@ -0,0 +1,260 @@ +Minetest Texture Pack Reference +=============================== + +Texture packs allow you to replace textures provided by a mod with your own +textures. + +Texture pack directory structure +-------------------------------- + + textures + |-- Texture Pack + | |-- texture_pack.conf + | |-- screenshot.png + | |-- description.txt + | |-- override.txt + | |-- your_texture_1.png + | |-- your_texture_2.png + `-- Another Texture Pack + +### Texture Pack +This is a directory containing the entire contents of a single texture pack. +It can be chosen more or less freely and will also become the name of the +texture pack. The name must not be “base”. + +### `texture_pack.conf` +A key-value config file with the following keys: + +* `title` - human readable title +* `description` - short description, shown in the content tab + +### `description.txt` +**Deprecated**, you should use texture_pack.conf instead. + +A file containing a short description of the texture pack to be shown in the +content tab. + +### `screenshot.png` +A preview image showing an in-game screenshot of this texture pack; it will be +shown in the texture packs tab. It should have an aspect ratio of 3:2 and a +minimum size of 300×200 pixels. + +### `your_texture_1.png`, `your_texture_2.png`, etc. +Any other PNG files will be interpreted as textures. They must have the same +names as the textures they are supposed to override. For example, to override +the apple texture of Minetest Game, add a PNG file named `default_apple.png`. + +The custom textures do not necceessarily require the same size as their +originals, but this might be required for a few particular textures. When +unsure, just test your texture pack in-game. + +Texture modifiers +----------------- + +See lua_api.txt for texture modifiers + +Special textures +---------------- + +These texture names are hardcoded into the engine but can also be overwritten +by texture packs. All existing fallback textures can be found in the directory +`textures/base/pack`. + +### Gameplay textures + +* `bubble.png`: the bubble texture when the player is drowning + (default size: 12×12) +* `bubble_gone.png`: like `bubble.png`, but denotes lack of breath + (transparent by default, same size as bubble.png) + +* `crack_anylength.png`: node overlay texture when digging + +* `crosshair.png` + * the crosshair texture in the center of the screen. The settings + `crosshair_color` and `crosshair_alpha` are used to create a cross + when no texture is found. + +* `object_crosshair.png` + * the crosshair seen when pointing at an object. The settings + `crosshair_color` and `crosshair_alpha` are used to create a cross + when no texture is found. + +* `halo.png`: used for the node highlighting mesh + +* `heart.png`: used to display the health points of the player + (default size: 12×12) +* `heart_gone.png`: like `heart.png`, but denotes lack of health points + (transparent by default, same size as heart.png) + +* `minimap_mask_round.png`: round minimap mask, white gets replaced by the map +* `minimap_mask_square.png`: mask used for the square minimap +* `minimap_overlay_round.png`: overlay texture for the round minimap +* `minimap_overlay_square.png`: overlay texture for the square minimap +* `object_marker_red.png`: texture for players on the minimap +* `player_marker.png`: texture for the own player on the square minimap +* `no_texture_airlike.png`: fallback inventory image for airlike nodes +* `no_texture.png`: fallback image for unspecified textures + +* `player.png`: front texture of the 2D upright sprite player +* `player_back.png`: back texture of the 2D upright sprite player + +* `progress_bar.png`: foreground texture of the loading screen's progress bar +* `progress_bar_bg.png`: background texture of the loading screen's progress bar + +* `moon.png`: texture of the moon. Default texture is generated by Minetest +* `moon_tonemap.png`: tonemap to be used when `moon.png` was found +* `sun.png`: texture of the sun. Default texture is generated by Minetest +* `sun_tonemap.png`: tonemap to be used when `sun.png` was found +* `sunrisebg.png`: shown sky texture when the sun rises + +* `smoke_puff.png`: texture used when an object died by punching + +* `unknown_item.png`: shown texture when an item definition was not found +* `unknown_node.png`: shown texture when a node definition was not found +* `unknown_object.png`: shown texture when an entity definition was not found + +* `wieldhand.png`: texture of the wieldhand + +Note: The default textures of `player.png`, `player_back.png` and `wieldhand.png` +are placeholders intended to be overwritten by the game. + +### Mainmenu textures + +* `menu_bg.png`: used as mainmenu background when the clouds are disabled +* `menu_header.png`: header texture when no texture pack is selected + +* `no_screenshot.png` + * texture when no screenshot was found for a texture pack or mod + +* `server_flags_creative.png`: icon for creative servers +* `server_flags_damage.png`: icon for enabled damage on servers +* `server_flags_favorite.png`: icon for your favorite servers +* `server_flags_pvp.png`: icon for enabled PvP on servers + +### Android textures + +* `down_arrow.png` +* `left_arrow.png` +* `right_arrow.png` +* `up_arrow.png` + +* `drop_btn.png` +* `fast_btn.png` +* `fly_btn.png` +* `jump_btn.png` +* `noclip_btn.png` + +* `camera_btn.png` +* `chat_btn.png` +* `inventory_btn.png` +* `rangeview_btn.png` + +* `debug_btn.png` +* `gear_icon.png` +* `rare_controls.png` + +Texture Overrides +----------------- + +You can override the textures of nodes and items from a +texture pack using texture overrides. To do this, create one or +more files in a texture pack called override.txt + +Each line in an override.txt file is a rule. It consists of + + itemname target texture + +For example, + + default:dirt_with_grass sides default_stone.png + +or + + default:sword_steel inventory my_steel_sword.png + +You can list multiple targets on one line as a comma-separated list: + + default:tree top,bottom my_special_tree.png + +You can use texture modifiers, as usual: + + default:dirt_with_grass sides default_stone.png^[brighten + +Finally, if a line is empty or starts with '#' it will be considered +a comment and not read as a rule. You can use this to better organize +your override.txt files. + +Here are targets you can choose from: + +| target | behavior | +|---------------|---------------------------------------------------| +| left | x- face | +| right | x+ face | +| front | z- face | +| back | z+ face | +| top | y+ face | +| bottom | y- face | +| sides | x-, x+, z-, z+ faces | +| all | All faces. You can also use '*' instead of 'all'. | +| special1 | The first entry in the special_tiles list | +| special2 | The second entry in the special_tiles list | +| special3 | The third entry in the special_tiles list | +| special4 | The fourth entry in the special_tiles list | +| special5 | The fifth entry in the special_tiles list | +| special6 | The sixth entry in the special_tiles list | +| inventory | The inventory texture | +| wield | The texture used when held by the player | + +Nodes support all targets, but other items only support 'inventory' +and 'wield'. + +### Using the special targets + +The special* targets only apply to specific drawtypes: + +* `flowingliquid`: special1 sets the top texture, special2 sets the side texture +* `allfaces_optional`: special1 is used by simple mode, see below +* `glasslike_framed`: When containing a liquid, special1 sets the liquid texture +* `glasslike_framed_optional`: Same as `glasslike_framed` +* `plantlike_rooted`: special1 sets the plant's texture + +Designing leaves textures for the leaves rendering options +---------------------------------------------------------- + +Minetest has three modes for rendering leaves nodes if the node has the +`allfaces_optional` drawtype. + +### Fancy + +Uses the texture specified in the `tiles` nodedef field. +The texture should have some transparent pixels and be in the RGBA format so +that the transparent pixels can have color information. +Faces of every leaves node are rendered even if they are inside a solid volume +of leaves; this gives a dense appearance. + +### Opaque + +Uses the texture specified in `tiles` but makes it opaque by converting each +transparent pixel into an opaque pixel that uses the color information of that +transparent pixel. +Due to this the `tiles` texture format must be RGBA not 'indexed alpha' to allow +each transparent pixel to have color information. + +The colors of the transparent pixels should be set for a good appearance in +`opaque` mode. This can be done by painting the pixels the desired colors then +erasing them. Then when saving the texture, use the 'save color information from +transparent pixels' option (or equivalent). + +### Simple + +Uses the texture specified in the `special_tiles` nodedef field if it exists, if +not, the `tiles` texture. +The `special_tiles` texture should have fewer transparent pixels than the +`tiles` texture and be in the 'indexed alpha' format. + +This mode is between the other two in terms of appearance and rendering load. +The nodes are rendered using the `glasslike` drawtype, only showing the surface +faces for any solid volume of leaves, not the internal faces. +Due to this the `tiles` texture might appear lacking in density, so optionally a +`special_tiles` texture can be used to provide a texture with fewer transparent +pixels for a denser appearance. diff --git a/doc/world_format.txt b/doc/world_format.txt new file mode 100644 index 0000000..17923df --- /dev/null +++ b/doc/world_format.txt @@ -0,0 +1,596 @@ +============================= +Minetest World Format 22...29 +============================= + +This applies to a world format carrying the block serialization version +22...27, used at least in +- 0.4.dev-20120322 ... 0.4.dev-20120606 (22...23) +- 0.4.0 (23) +- 24 was never released as stable and existed for ~2 days +- 27 was added in 0.4.15-dev +- 29 was added in 5.5.0-dev + +The block serialization version does not fully specify every aspect of this +format; if compliance with this format is to be checked, it needs to be +done by detecting if the files and data indeed follows it. + +Files +====== +Everything is contained in a directory, the name of which is freeform, but +often serves as the name of the world. + +Currently the authentication and ban data is stored on a per-world basis. +It can be copied over from an old world to a newly created world. + +World +|-- auth.txt ----- Authentication data +|-- auth.sqlite -- Authentication data (SQLite alternative) +|-- env_meta.txt - Environment metadata +|-- ipban.txt ---- Banned ips/users +|-- map_meta.txt - Map metadata +|-- map.sqlite --- Map data +|-- players ------ Player directory +| |-- player1 -- Player file +| '-- Foo ------ Player file +`-- world.mt ----- World metadata + +auth.txt +--------- +Contains authentication data, player per line. + <name>:<password hash>:<privilege1,...> + +Legacy format (until 0.4.12) of password hash is <name><password> SHA1'd, +in the base64 encoding. + +Format (since 0.4.13) of password hash is #1#<salt>#<verifier>, with the +parts inside <> encoded in the base64 encoding. +<verifier> is an RFC 2945 compatible SRP verifier, +of the given salt, password, and the player's name lowercased, +using the 2048-bit group specified in RFC 5054 and the SHA-256 hash function. + +Example lines: +- Player "celeron55", no password, privileges "interact" and "shout": + celeron55::interact,shout +- Player "Foo", password "bar", privilege "shout", with a legacy password hash: + foo:iEPX+SQWIR3p67lj/0zigSWTKHg:shout +- Player "Foo", password "bar", privilege "shout", with a 0.4.13 pw hash: + foo:#1#hPpy4O3IAn1hsNK00A6wNw#Kpu6rj7McsrPCt4euTb5RA5ltF7wdcWGoYMcRngwDi11cZhPuuR9i5Bo7o6A877TgcEwoc//HNrj9EjR/CGjdyTFmNhiermZOADvd8eu32FYK1kf7RMC0rXWxCenYuOQCG4WF9mMGiyTPxC63VAjAMuc1nCZzmy6D9zt0SIKxOmteI75pAEAIee2hx4OkSXRIiU4Zrxo1Xf7QFxkMY4x77vgaPcvfmuzom0y/fU1EdSnZeopGPvzMpFx80ODFx1P34R52nmVl0W8h4GNo0k8ZiWtRCdrJxs8xIg7z5P1h3Th/BJ0lwexpdK8sQZWng8xaO5ElthNuhO8UQx1l6FgEA:shout +- Player "bar", no password, no privileges: + bar:: + +auth.sqlite +------------ +Contains authentification data as an SQLite database. This replaces auth.txt +above when auth_backend is set to "sqlite3" in world.mt . + +This database contains two tables "auth" and "user_privileges": + +CREATE TABLE `auth` ( + `id` INTEGER PRIMARY KEY AUTOINCREMENT, + `name` VARCHAR(32) UNIQUE, + `password` VARCHAR(512), + `last_login` INTEGER +); +CREATE TABLE `user_privileges` ( + `id` INTEGER, + `privilege` VARCHAR(32), + PRIMARY KEY (id, privilege) + CONSTRAINT fk_id FOREIGN KEY (id) REFERENCES auth (id) ON DELETE CASCADE +); + +The "name" and "password" fields of the auth table are the same as the auth.txt +fields (with modern password hash). The "last_login" field is the last login +time as a unix time stamp. + +The "user_privileges" table contains one entry per privilege and player. +A player with "interact" and "shout" privileges will have two entries, one +with privilege="interact" and the second with privilege="shout". + +env_meta.txt +------------- +Simple global environment variables. +Example content (added indentation): + game_time = 73471 + time_of_day = 19118 + EnvArgsEnd + +ipban.txt +---------- +Banned IP addresses and usernames. +Example content (added indentation): + 123.456.78.9|foo + 123.456.78.10|bar + +map_meta.txt +------------- +Simple global map variables. +Example content (added indentation): + seed = 7980462765762429666 + [end_of_params] + +map.sqlite +----------- +Map data. +See Map File Format below. + +player1, Foo +------------- +Player data. +Filename can be anything. +See Player File Format below. + +world.mt +--------- +World metadata. +Example content (added indentation and - explanations): + gameid = mesetint - name of the game + enable_damage = true - whether damage is enabled or not + creative_mode = false - whether creative mode is enabled or not + backend = sqlite3 - which DB backend to use for blocks (sqlite3, dummy, leveldb, redis, postgresql) + player_backend = sqlite3 - which DB backend to use for player data + readonly_backend = sqlite3 - optionally readonly seed DB (DB file _must_ be located in "readonly" subfolder) + auth_backend = files - which DB backend to use for authentication data + server_announce = false - whether the server is publicly announced or not + load_mod_<mod> = false - whether <mod> is to be loaded in this world + +For load_mod_<mod>, the possible values are: + +* `false` - Do not load the mod. +* `true` - Load the mod from wherever it is found (may cause conflicts if the same mod appears also in some other place). +* `mods/modpack/moddir` - Relative path to the mod + * Must be one of the following: + * `mods/`: mods in the user path's mods folder (ex `/home/user/.minetest/mods`) + * `share/`: mods in the share's mods folder (ex: `/usr/share/minetest/mods`) + * `/path/to/env`: you can use absolute paths to mods inside folders specified with the `MINETEST_MOD_PATH` env variable. + * Other locations and absolute paths are not supported + * Note that `moddir` is the directory name, not the mod name specified in mod.conf. + +PostgreSQL backend specific settings: + pgsql_connection = host=127.0.0.1 port=5432 user=mt_user password=mt_password dbname=minetest + pgsql_player_connection = (same parameters as above) + pgsql_readonly_connection = (same parameters as above) + pgsql_auth_connection = (same parameters as above) + +Redis backend specific settings: + redis_address = 127.0.0.1 - Redis server address + redis_hash = foo - Database hash + redis_port = 6379 - (optional) connection port + redis_password = hunter2 - (optional) server password + + +Player File Format +=================== + +- Should be pretty self-explanatory. +- Note: position is in nodes * 10 + +Example content (added indentation): + hp = 11 + name = celeron55 + pitch = 39.77 + position = (-5231.97,15,1961.41) + version = 1 + yaw = 101.37 + PlayerArgsEnd + List main 32 + Item default:torch 13 + Item default:pick_steel 1 50112 + Item experimental:tnt + Item default:cobble 99 + Item default:pick_stone 1 13104 + Item default:shovel_steel 1 51838 + Item default:dirt 61 + Item default:rail 78 + Item default:coal_lump 3 + Item default:cobble 99 + Item default:leaves 22 + Item default:gravel 52 + Item default:axe_steel 1 2045 + Item default:cobble 98 + Item default:sand 61 + Item default:water_source 94 + Item default:glass 2 + Item default:mossycobble + Item default:pick_steel 1 64428 + Item animalmaterials:bone + Item default:sword_steel + Item default:sapling + Item default:sword_stone 1 10647 + Item default:dirt 99 + Empty + Empty + Empty + Empty + Empty + Empty + Empty + Empty + EndInventoryList + List craft 9 + Empty + Empty + Empty + Empty + Empty + Empty + Empty + Empty + Empty + EndInventoryList + List craftpreview 1 + Empty + EndInventoryList + List craftresult 1 + Empty + EndInventoryList + EndInventory + +Map File Format +================ + +Minetest maps consist of MapBlocks, chunks of 16x16x16 nodes. + +In addition to the bulk node data, MapBlocks stored on disk also contain +other things. + +History +-------- +We need a bit of history in here. Initially Minetest stored maps in a +format called the "sectors" format. It was a directory/file structure like +this: + sectors2/XXX/ZZZ/YYYY +For example, the MapBlock at (0,1,-2) was this file: + sectors2/000/ffd/0001 + +Eventually Minetest outgrow this directory structure, as filesystems were +struggling under the amount of files and directories. + +Large servers seriously needed a new format, and thus the base of the +current format was invented, suggested by celeron55 and implemented by +JacobF. + +SQLite3 was slammed in, and blocks files were directly inserted as blobs +in a single table, indexed by integer primary keys, oddly mangled from +coordinates. + +Today we know that SQLite3 allows multiple primary keys (which would allow +storing coordinates separately), but the format has been kept unchanged for +that part. So, this is where it has come. +</history> + +So here goes +------------- +map.sqlite is an sqlite3 database, containing a single table, called +"blocks". It looks like this: + + CREATE TABLE `blocks` (`pos` INT NOT NULL PRIMARY KEY,`data` BLOB); + +The key +-------- +"pos" is created from the three coordinates of a MapBlock using this +algorithm, defined here in Python: + + def getBlockAsInteger(p): + return int64(p[2]*16777216 + p[1]*4096 + p[0]) + + def int64(u): + while u >= 2**63: + u -= 2**64 + while u <= -2**63: + u += 2**64 + return u + +It can be converted the other way by using this code: + + def getIntegerAsBlock(i): + x = unsignedToSigned(i % 4096, 2048) + i = int((i - x) / 4096) + y = unsignedToSigned(i % 4096, 2048) + i = int((i - y) / 4096) + z = unsignedToSigned(i % 4096, 2048) + return x,y,z + + def unsignedToSigned(i, max_positive): + if i < max_positive: + return i + else: + return i - 2*max_positive + +The blob +--------- +The blob is the data that would have otherwise gone into the file. + +See below for description. + +MapBlock serialization format +============================== +NOTE: Byte order is MSB first (big-endian). +NOTE: Zlib data is in such a format that Python's zlib at least can + directly decompress. +NOTE: Since version 29 zstd is used instead of zlib. In addition the entire + block is first serialized and then compressed (except the version byte). + +u8 version +- map format version number, see serialisation.h for the latest number + +u8 flags +- Flag bitmasks: + - 0x01: is_underground: Should be set to 0 if there will be no light + obstructions above the block. If/when sunlight of a block is updated + and there is no block above it, this value is checked for determining + whether sunlight comes from the top. + - 0x02: day_night_differs: Whether the lighting of the block is different + on day and night. Only blocks that have this bit set are updated when + day transforms to night. + - 0x04: lighting_expired: Not used in version 27 and above. If true, + lighting is invalid and should be updated. If you can't calculate + lighting in your generator properly, you could try setting this 1 to + everything and setting the uppermost block in every sector as + is_underground=0. I am quite sure it doesn't work properly, though. + - 0x08: generated: True if the block has been generated. If false, block + is mostly filled with CONTENT_IGNORE and is likely to contain eg. parts + of trees of neighboring blocks. + +u16 lighting_complete +- Added in version 27. +- This contains 12 flags, each of them corresponds to a direction. +- Indicates if the light is correct at the sides of a map block. + Lighting may not be correct if the light changed, but a neighbor + block was not loaded at that time. + If these flags are false, Minetest will automatically recompute light + when both this block and its required neighbor are loaded. +- The bit order is: + nothing, nothing, nothing, nothing, + night X-, night Y-, night Z-, night Z+, night Y+, night X+, + day X-, day Y-, day Z-, day Z+, day Y+, day X+. + Where 'day' is for the day light bank, 'night' is for the night + light bank. + The 'nothing' bits should be always set, as they will be used + to indicate if direct sunlight spreading is finished. +- Example: if the block at (0, 0, 0) has + lighting_complete = 0b1111111111111110, + then Minetest will correct lighting in the day light bank when + the block at (1, 0, 0) is also loaded. + +if map format version >= 29: + u32 timestamp + - Timestamp when last saved, as seconds from starting the game. + - 0xffffffff = invalid/unknown timestamp, nothing should be done with the time + difference when loaded + + u8 name_id_mapping_version + - Should be zero for map format version 29. + + u16 num_name_id_mappings + foreach num_name_id_mappings + u16 id + u16 name_len + u8[name_len] name +if map format version < 29: + -- Nothing right here, timpstamp and node id mappings are serialized later + +u8 content_width +- Number of bytes in the content (param0) fields of nodes +if map format version <= 23: + - Always 1 +if map format version >= 24: + - Always 2 + +u8 params_width +- Number of bytes used for parameters per node +- Always 2 + +node data (zlib-compressed if version < 29): +if content_width == 1: + - content: + u8[4096]: param0 fields + u8[4096]: param1 fields + u8[4096]: param2 fields +if content_width == 2: + - content: + u16[4096]: param0 fields + u8[4096]: param1 fields + u8[4096]: param2 fields +- The location of a node in each of those arrays is (z*16*16 + y*16 + x). + +node metadata list (zlib-compressed if version < 29): +- content: + if map format version <= 22: + u16 version (=1) + u16 count of metadata + foreach count: + u16 position (p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X) + u16 type_id + u16 content_size + u8[content_size] content of metadata. Format depends on type_id, see below. + if map format version >= 23: + u8 version -- Note: type was u16 for map format version <= 22 + -- = 1 for map format version < 28 + -- = 2 since map format version 28 + u16 count of metadata + foreach count: + u16 position (p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X) + u32 num_vars + foreach num_vars: + u16 key_len + u8[key_len] key + u32 val_len + u8[val_len] value + u8 is_private -- only for version >= 2. 0 = not private, 1 = private + serialized inventory + +- Node timers +if map format version == 23: + u8 unused version (always 0) +if map format version == 24: (NOTE: Not released as stable) + u8 nodetimer_version + if nodetimer_version == 0: + (nothing else) + if nodetimer_version == 1: + u16 num_of_timers + foreach num_of_timers: + u16 timer position (z*16*16 + y*16 + x) + s32 timeout*1000 + s32 elapsed*1000 +if map format version >= 25: + -- Nothing right here, node timers are serialized later + +u8 static object version: +- Always 0 + +u16 static_object_count + +foreach static_object_count: + u8 type (object type-id) + s32 pos_x_nodes * 10000 + s32 pos_y_nodes * 10000 + s32 pos_z_nodes * 10000 + u16 data_size + u8[data_size] data + +if map format version < 29: + u32 timestamp + - Same meaning as the timestamp further up + + u8 name-id-mapping version + - Always 0 + + u16 num_name_id_mappings + foreach num_name_id_mappings + u16 id + u16 name_len + u8[name_len] name + +- Node timers +if map format version >= 25: + u8 length of the data of a single timer (always 2+4+4=10) + u16 num_of_timers + foreach num_of_timers: + u16 timer position (z*16*16 + y*16 + x) + s32 timeout*1000 + s32 elapsed*1000 + +EOF. + +Format of nodes +---------------- +A node is composed of the u8 fields param0, param1 and param2. + +if map format version <= 23: + The content id of a node is determined as so: + - If param0 < 0x80, + content_id = param0 + - Otherwise + content_id = (param0<<4) + (param2>>4) +if map format version >= 24: + The content id of a node is param0. + +The purpose of param1 and param2 depend on the definition of the node. + +The name-id-mapping +-------------------- +The mapping maps node content ids to node names. + +Node metadata format for map format versions <= 22 +--------------------------------------------------- +The node metadata are serialized depending on the type_id field. + +1: Generic metadata + serialized inventory + u32 len + u8[len] text + u16 len + u8[len] owner + u16 len + u8[len] infotext + u16 len + u8[len] inventory drawspec + u8 allow_text_input (bool) + u8 removal_disabled (bool) + u8 enforce_owner (bool) + u32 num_vars + foreach num_vars + u16 len + u8[len] name + u32 len + u8[len] value + +14: Sign metadata + u16 text_len + u8[text_len] text + +15: Chest metadata + serialized inventory + +16: Furnace metadata + TBD + +17: Locked Chest metadata + u16 len + u8[len] owner + serialized inventory + +Static objects +--------------- +Static objects are persistent freely moving objects in the world. + +Object types: +1: Test object +7: LuaEntity + +7: LuaEntity: + u8 compatibility_byte (always 1) + u16 len + u8[len] entity name + u32 len + u8[len] static data + s16 hp + s32 velocity.x * 10000 + s32 velocity.y * 10000 + s32 velocity.z * 10000 + s32 yaw * 1000 + if PROTOCOL_VERSION >= 37: + u8 version2 (=1) + s32 pitch * 1000 + s32 roll * 1000 + +Itemstring format +------------------ +eg. 'default:dirt 5' +eg. 'default:pick_wood 21323' +eg. '"default:apple" 2' +eg. 'default:apple' +- The wear value in tools is 0...65535 +- There are also a number of older formats that you might stumble upon: +eg. 'node "default:dirt" 5' +eg. 'NodeItem default:dirt 5' +eg. 'ToolItem WPick 21323' + +Inventory serialization format +------------------------------- +- The inventory serialization format is line-based +- The newline character used is "\n" +- The end condition of a serialized inventory is always "EndInventory\n" +- All the slots in a list must always be serialized. + +Example (format does not include "---"): +--- +List foo 4 +Item default:sapling +Item default:sword_stone 1 10647 +Item default:dirt 99 +Empty +EndInventoryList +List bar 9 +Empty +Empty +Empty +Empty +Empty +Empty +Empty +Empty +Empty +EndInventoryList +EndInventory +--- diff --git a/fonts/Arimo-Bold.ttf b/fonts/Arimo-Bold.ttf new file mode 100644 index 0000000..0b05b44 Binary files /dev/null and b/fonts/Arimo-Bold.ttf differ diff --git a/fonts/Arimo-BoldItalic.ttf b/fonts/Arimo-BoldItalic.ttf new file mode 100644 index 0000000..3ca5311 Binary files /dev/null and b/fonts/Arimo-BoldItalic.ttf differ diff --git a/fonts/Arimo-Italic.ttf b/fonts/Arimo-Italic.ttf new file mode 100644 index 0000000..fe31082 Binary files /dev/null and b/fonts/Arimo-Italic.ttf differ diff --git a/fonts/Arimo-LICENSE.txt b/fonts/Arimo-LICENSE.txt new file mode 100644 index 0000000..d68578f --- /dev/null +++ b/fonts/Arimo-LICENSE.txt @@ -0,0 +1,2 @@ +Arimo - Apache License, version 2.0 +Arimo-Regular.ttf: Digitized data copyright (c) 2010-2012 Google Corporation. diff --git a/fonts/Arimo-Regular.ttf b/fonts/Arimo-Regular.ttf new file mode 100644 index 0000000..9be443c Binary files /dev/null and b/fonts/Arimo-Regular.ttf differ diff --git a/fonts/Cousine-Bold.ttf b/fonts/Cousine-Bold.ttf new file mode 100644 index 0000000..997817a Binary files /dev/null and b/fonts/Cousine-Bold.ttf differ diff --git a/fonts/Cousine-BoldItalic.ttf b/fonts/Cousine-BoldItalic.ttf new file mode 100644 index 0000000..3d91878 Binary files /dev/null and b/fonts/Cousine-BoldItalic.ttf differ diff --git a/fonts/Cousine-Italic.ttf b/fonts/Cousine-Italic.ttf new file mode 100644 index 0000000..2ec2c34 Binary files /dev/null and b/fonts/Cousine-Italic.ttf differ diff --git a/fonts/Cousine-LICENSE.txt b/fonts/Cousine-LICENSE.txt new file mode 100644 index 0000000..c84465f --- /dev/null +++ b/fonts/Cousine-LICENSE.txt @@ -0,0 +1,2 @@ +Cousine - Apache License, version 2.0 +Cousine-Regular.ttf: Digitized data copyright (c) 2010-2012 Google Corporation. diff --git a/fonts/Cousine-Regular.ttf b/fonts/Cousine-Regular.ttf new file mode 100644 index 0000000..4d6990a Binary files /dev/null and b/fonts/Cousine-Regular.ttf differ diff --git a/fonts/DroidSansFallbackFull-LICENSE.txt b/fonts/DroidSansFallbackFull-LICENSE.txt new file mode 100644 index 0000000..a7bf409 --- /dev/null +++ b/fonts/DroidSansFallbackFull-LICENSE.txt @@ -0,0 +1,13 @@ +Copyright (C) 2012 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. +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/fonts/DroidSansFallbackFull.ttf b/fonts/DroidSansFallbackFull.ttf new file mode 100644 index 0000000..0cacabe Binary files /dev/null and b/fonts/DroidSansFallbackFull.ttf differ diff --git a/games/devtest/.luacheckrc b/games/devtest/.luacheckrc new file mode 100644 index 0000000..1c7d399 --- /dev/null +++ b/games/devtest/.luacheckrc @@ -0,0 +1,43 @@ +unused_args = false +allow_defined_top = true +max_string_line_length = false +max_line_length = false + +ignore = { + "131", -- Unused global variable + "211", -- Unused local variable + "231", -- Local variable never accessed + "311", -- Value assigned to a local variable is unused + "412", -- Redefining an argument + "421", -- Shadowing a local variable + "431", -- Shadowing an upvalue + "432", -- Shadowing an upvalue argument + "611", -- Line contains only whitespace +} + +read_globals = { + "ItemStack", + "INIT", + "DIR_DELIM", + "dump", "dump2", + "fgettext", "fgettext_ne", + "vector", + "VoxelArea", + "profiler", + "Settings", + "check", + "PseudoRandom", + + string = {fields = {"split", "trim"}}, + table = {fields = {"copy", "getn", "indexof", "insert_all"}}, + math = {fields = {"hypot", "round"}}, +} + +globals = { + "aborted", + "minetest", + "core", + os = { fields = { "tempfolder" } }, + "_", +} + diff --git a/games/devtest/LICENSE.txt b/games/devtest/LICENSE.txt new file mode 100644 index 0000000..71bd0e5 --- /dev/null +++ b/games/devtest/LICENSE.txt @@ -0,0 +1,4 @@ +License information for Development Test +---------------------------------------- + +The same license as for Minetest applies. diff --git a/games/devtest/README.md b/games/devtest/README.md new file mode 100644 index 0000000..77e722a --- /dev/null +++ b/games/devtest/README.md @@ -0,0 +1,51 @@ +# Development Test (devtest) + +This is a basic testing environment that contains a bunch of things to test the engine, but it could also be used as a minimal testbed for testing out mods. + +## Features + +* Basic nodes for mapgen +* Basic, minimal map generator +* Lots of example nodes for testing drawtypes, param2, light level, and many other node properties +* Example entities +* Other example items +* Formspec test (via `/test_formspec` command) +* Automated unit tests (disabled by default) +* Tools for manipulating nodes and entities, like the "Param2 Tool" + +## Getting started + +Basically, just create a world and start. A few important things to note: + +* Items are gotten from the “Chest of Everything” (`chest_of_everything:chest`) +* When you lost your initial items, type in `/stuff` command to get them back +* By default, Creative Mode activates infinite node placement. This behavior can be changed with the `devtest_infplace` setting +* Use the `/infplace` command to toggle infinite node placement in-game +* Use the Param2 Tool to change the param2 of nodes; it's useful to experiment with the various drawtype test nodes +* Check out the game settings and server commands for additional tests and features + +Confused by a certain node or item? Check out for inline code comments. The usages of most tools are explained in their tooltips. + +### Example tests + +* You can use this to test what happens if a player is simultaneously in 2 nodes with `damage_per_second` but with a different value. +* Or use the Falling Node Tool on various test nodes to see how they behave when falling. +* You could also use this as a testbed for dependency-free mods, e.g. to test out how your formspecs behave without theming. + +## Random notes + +* Experimental/strange/unstructured tests can be found in the `experimental` mod +* Textures of drawtype test nodes have a red dot at the top left corner. This is to see whether the textures are oriented properly + +## Design philosophy + +This should loosely follow the following principles: + +* Engine testing: The main focus of this is to aid testing of *engine* features, such as mapgen or node drawtypes +* Mod testing: The secondary focus is to help modders as well, either as a minimal testbed for mods or even as a code example +* Minimal interference: Under default settings, it shall not interfere with APIs except on explicit user wish. Non-trivial tests and features need to be enabled by a setting first +* Convenience: Have various tools to make usage easier and more convenient +* Reproducing engine bugs: When an engine bug was found, consider creating a test case +* Clarity: Textures and names need to be designed to keep different things clearly visually apart at a glance +* Low loading time: It must load blazing-fast so stuff can be tested quickly + diff --git a/games/devtest/game.conf b/games/devtest/game.conf new file mode 100644 index 0000000..0f5656c --- /dev/null +++ b/games/devtest/game.conf @@ -0,0 +1,2 @@ +title = Development Test +description = Testing environment to help with testing the engine features of Minetest. It can also be helpful in mod development. diff --git a/games/devtest/menu/background.png b/games/devtest/menu/background.png new file mode 100644 index 0000000..89c45fc Binary files /dev/null and b/games/devtest/menu/background.png differ diff --git a/games/devtest/menu/header.png b/games/devtest/menu/header.png new file mode 100644 index 0000000..c80ed71 Binary files /dev/null and b/games/devtest/menu/header.png differ diff --git a/games/devtest/menu/icon.png b/games/devtest/menu/icon.png new file mode 100644 index 0000000..f854b9c Binary files /dev/null and b/games/devtest/menu/icon.png differ diff --git a/games/devtest/mods/basenodes/init.lua b/games/devtest/mods/basenodes/init.lua new file mode 100644 index 0000000..2c808c3 --- /dev/null +++ b/games/devtest/mods/basenodes/init.lua @@ -0,0 +1,351 @@ +local WATER_ALPHA = "^[opacity:" .. 160 +local WATER_VISC = 1 +local LAVA_VISC = 7 + +-- +-- Node definitions +-- + +-- Register nodes + +minetest.register_node("basenodes:stone", { + description = "Stone", + tiles = {"default_stone.png"}, + groups = {cracky=3}, +}) + +minetest.register_node("basenodes:desert_stone", { + description = "Desert Stone", + tiles = {"default_desert_stone.png"}, + groups = {cracky=3}, +}) + +minetest.register_node("basenodes:dirt_with_grass", { + description = "Dirt with Grass", + tiles ={"default_grass.png", + -- a little dot on the bottom to distinguish it from dirt + "default_dirt.png^basenodes_dirt_with_grass_bottom.png", + {name = "default_dirt.png^default_grass_side.png", + tileable_vertical = false}}, + groups = {crumbly=3, soil=1}, +}) + +minetest.register_node("basenodes:dirt_with_snow", { + description = "Dirt with Snow", + tiles ={"basenodes_dirt_with_snow.png", + -- a little dot on the bottom to distinguish it from dirt + "default_dirt.png^basenodes_dirt_with_snow_bottom.png", + {name = "default_dirt.png^default_snow_side.png", + tileable_vertical = false}}, + groups = {crumbly=3, soil=1}, +}) + +minetest.register_node("basenodes:dirt", { + description = "Dirt", + tiles ={"default_dirt.png"}, + groups = {crumbly=3, soil=1}, +}) + +minetest.register_node("basenodes:sand", { + description = "Sand", + tiles ={"default_sand.png"}, + groups = {crumbly=3}, +}) + +minetest.register_node("basenodes:desert_sand", { + description = "Desert Sand", + tiles ={"default_desert_sand.png"}, + groups = {crumbly=3}, +}) + +minetest.register_node("basenodes:gravel", { + description = "Gravel", + tiles ={"default_gravel.png"}, + groups = {crumbly=2}, +}) + +minetest.register_node("basenodes:junglegrass", { + description = "Jungle Grass", + drawtype = "plantlike", + tiles ={"default_junglegrass.png"}, + inventory_image = "default_junglegrass.png", + wield_image = "default_junglegrass.png", + paramtype = "light", + walkable = false, + groups = {snappy=3}, +}) + +minetest.register_node("basenodes:tree", { + description = "Normal Tree Trunk", + tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"}, + is_ground_content = false, + groups = {choppy=2,oddly_breakable_by_hand=1}, +}) + +minetest.register_node("basenodes:leaves", { + description = "Normal Leaves", + drawtype = "allfaces_optional", + tiles = {"default_leaves.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3}, +}) + +minetest.register_node("basenodes:jungletree", { + description = "Jungle Tree Trunk", + tiles = {"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"}, + is_ground_content = false, + groups = {choppy=2,oddly_breakable_by_hand=1}, +}) + +minetest.register_node("basenodes:jungleleaves", { + description = "Jungle Leaves", + drawtype = "allfaces_optional", + tiles = {"default_jungleleaves.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3}, +}) + +minetest.register_node("basenodes:pine_tree", { + description = "Pine Tree Trunk", + tiles = {"default_pine_tree_top.png", "default_pine_tree_top.png", "default_pine_tree.png"}, + is_ground_content = false, + groups = {choppy=2,oddly_breakable_by_hand=1}, +}) + +minetest.register_node("basenodes:pine_needles", { + description = "Pine Needles", + drawtype = "allfaces_optional", + tiles = {"default_pine_needles.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3}, +}) + +minetest.register_node("basenodes:water_source", { + description = "Water Source".."\n".. + "Drowning damage: 1", + drawtype = "liquid", + waving = 3, + tiles = {"default_water.png"..WATER_ALPHA}, + special_tiles = { + {name = "default_water.png"..WATER_ALPHA, backface_culling = false}, + {name = "default_water.png"..WATER_ALPHA, backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "basenodes:water_flowing", + liquid_alternative_source = "basenodes:water_source", + liquid_viscosity = WATER_VISC, + post_effect_color = {a = 64, r = 100, g = 100, b = 200}, + groups = {water = 3, liquid = 3}, +}) + +minetest.register_node("basenodes:water_flowing", { + description = "Flowing Water".."\n".. + "Drowning damage: 1", + drawtype = "flowingliquid", + waving = 3, + tiles = {"default_water_flowing.png"}, + special_tiles = { + {name = "default_water_flowing.png"..WATER_ALPHA, + backface_culling = false}, + {name = "default_water_flowing.png"..WATER_ALPHA, + backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "basenodes:water_flowing", + liquid_alternative_source = "basenodes:water_source", + liquid_viscosity = WATER_VISC, + post_effect_color = {a = 64, r = 100, g = 100, b = 200}, + groups = {water = 3, liquid = 3}, +}) + +minetest.register_node("basenodes:river_water_source", { + description = "River Water Source".."\n".. + "Drowning damage: 1", + drawtype = "liquid", + waving = 3, + tiles = { "default_river_water.png"..WATER_ALPHA }, + special_tiles = { + {name = "default_river_water.png"..WATER_ALPHA, backface_culling = false}, + {name = "default_river_water.png"..WATER_ALPHA, backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "basenodes:river_water_flowing", + liquid_alternative_source = "basenodes:river_water_source", + liquid_viscosity = 1, + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a = 103, r = 30, g = 76, b = 90}, + groups = {water = 3, liquid = 3, }, +}) + +minetest.register_node("basenodes:river_water_flowing", { + description = "Flowing River Water".."\n".. + "Drowning damage: 1", + drawtype = "flowingliquid", + waving = 3, + tiles = {"default_river_water_flowing.png"..WATER_ALPHA}, + special_tiles = { + {name = "default_river_water_flowing.png"..WATER_ALPHA, + backface_culling = false}, + {name = "default_river_water_flowing.png"..WATER_ALPHA, + backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "basenodes:river_water_flowing", + liquid_alternative_source = "basenodes:river_water_source", + liquid_viscosity = 1, + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a = 103, r = 30, g = 76, b = 90}, + groups = {water = 3, liquid = 3, }, +}) + +minetest.register_node("basenodes:lava_flowing", { + description = "Flowing Lava".."\n".. + "4 damage per second".."\n".. + "Drowning damage: 1", + drawtype = "flowingliquid", + tiles = {"default_lava_flowing.png"}, + special_tiles = { + {name="default_lava_flowing.png", backface_culling = false}, + {name="default_lava_flowing.png", backface_culling = false}, + }, + paramtype = "light", + light_source = minetest.LIGHT_MAX, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + damage_per_second = 4, + liquidtype = "flowing", + liquid_alternative_flowing = "basenodes:lava_flowing", + liquid_alternative_source = "basenodes:lava_source", + liquid_viscosity = LAVA_VISC, + post_effect_color = {a=192, r=255, g=64, b=0}, + groups = {lava=3, liquid=1}, +}) + +minetest.register_node("basenodes:lava_source", { + description = "Lava Source".."\n".. + "4 damage per second".."\n".. + "Drowning damage: 1", + drawtype = "liquid", + tiles = { "default_lava.png" }, + special_tiles = { + {name = "default_lava.png", backface_culling = false}, + {name = "default_lava.png", backface_culling = true}, + }, + paramtype = "light", + light_source = minetest.LIGHT_MAX, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + damage_per_second = 4, + liquidtype = "source", + liquid_alternative_flowing = "basenodes:lava_flowing", + liquid_alternative_source = "basenodes:lava_source", + liquid_viscosity = LAVA_VISC, + post_effect_color = {a=192, r=255, g=64, b=0}, + groups = {lava=3, liquid=1}, +}) + +minetest.register_node("basenodes:cobble", { + description = "Cobblestone", + tiles ={"default_cobble.png"}, + is_ground_content = false, + groups = {cracky=3}, +}) + +minetest.register_node("basenodes:mossycobble", { + description = "Mossy Cobblestone", + tiles ={"default_mossycobble.png"}, + is_ground_content = false, + groups = {cracky=3}, +}) + +minetest.register_node("basenodes:apple", { + description = "Apple".."\n".. + "Food (+2)", + drawtype = "plantlike", + tiles ={"default_apple.png"}, + inventory_image = "default_apple.png", + paramtype = "light", + is_ground_content = false, + sunlight_propagates = true, + walkable = false, + groups = {dig_immediate=3}, + + -- Make eatable because why not? + on_use = minetest.item_eat(2), +}) + +minetest.register_node("basenodes:ice", { + description = "Ice", + tiles ={"default_ice.png"}, + groups = {cracky=3}, +}) + +-- The snow nodes intentionally have different tints to make them more +-- distinguishable +minetest.register_node("basenodes:snow", { + description = "Snow Sheet", + tiles = {"basenodes_snow_sheet.png"}, + groups = {crumbly=3}, + walkable = false, + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + }, +}) + +minetest.register_node("basenodes:snowblock", { + description = "Snow Block", + tiles ={"default_snow.png"}, + groups = {crumbly=3}, +}) + + diff --git a/games/devtest/mods/basenodes/mod.conf b/games/devtest/mods/basenodes/mod.conf new file mode 100644 index 0000000..25024dc --- /dev/null +++ b/games/devtest/mods/basenodes/mod.conf @@ -0,0 +1,2 @@ +name = basenodes +description = Contains basic nodes for mapgen diff --git a/games/devtest/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.png b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.png new file mode 100644 index 0000000..5e8fc41 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.png differ diff --git a/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow.png b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow.png new file mode 100644 index 0000000..7ea2d8d Binary files /dev/null and b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow.png differ diff --git a/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.png b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.png new file mode 100644 index 0000000..447c94e Binary files /dev/null and b/games/devtest/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.png differ diff --git a/games/devtest/mods/basenodes/textures/basenodes_snow_sheet.png b/games/devtest/mods/basenodes/textures/basenodes_snow_sheet.png new file mode 100644 index 0000000..4553320 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/basenodes_snow_sheet.png differ diff --git a/games/devtest/mods/basenodes/textures/default_apple.png b/games/devtest/mods/basenodes/textures/default_apple.png new file mode 100644 index 0000000..9c115da Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_apple.png differ diff --git a/games/devtest/mods/basenodes/textures/default_cobble.png b/games/devtest/mods/basenodes/textures/default_cobble.png new file mode 100644 index 0000000..5b859e9 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_cobble.png differ diff --git a/games/devtest/mods/basenodes/textures/default_desert_sand.png b/games/devtest/mods/basenodes/textures/default_desert_sand.png new file mode 100644 index 0000000..19ec87d Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_desert_sand.png differ diff --git a/games/devtest/mods/basenodes/textures/default_desert_stone.png b/games/devtest/mods/basenodes/textures/default_desert_stone.png new file mode 100644 index 0000000..5126fb6 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_desert_stone.png differ diff --git a/games/devtest/mods/basenodes/textures/default_dirt.png b/games/devtest/mods/basenodes/textures/default_dirt.png new file mode 100644 index 0000000..aa75bff Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_dirt.png differ diff --git a/games/devtest/mods/basenodes/textures/default_grass.png b/games/devtest/mods/basenodes/textures/default_grass.png new file mode 100644 index 0000000..3d63971 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_grass.png differ diff --git a/games/devtest/mods/basenodes/textures/default_gravel.png b/games/devtest/mods/basenodes/textures/default_gravel.png new file mode 100644 index 0000000..7e5ff61 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_gravel.png differ diff --git a/games/devtest/mods/basenodes/textures/default_ice.png b/games/devtest/mods/basenodes/textures/default_ice.png new file mode 100644 index 0000000..c4bddd2 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_ice.png differ diff --git a/games/devtest/mods/basenodes/textures/default_junglegrass.png b/games/devtest/mods/basenodes/textures/default_junglegrass.png new file mode 100644 index 0000000..d64e33a Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_junglegrass.png differ diff --git a/games/devtest/mods/basenodes/textures/default_jungleleaves.png b/games/devtest/mods/basenodes/textures/default_jungleleaves.png new file mode 100644 index 0000000..1fa67e8 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_jungleleaves.png differ diff --git a/games/devtest/mods/basenodes/textures/default_jungletree.png b/games/devtest/mods/basenodes/textures/default_jungletree.png new file mode 100644 index 0000000..053850f Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_jungletree.png differ diff --git a/games/devtest/mods/basenodes/textures/default_jungletree_top.png b/games/devtest/mods/basenodes/textures/default_jungletree_top.png new file mode 100644 index 0000000..e80de8a Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_jungletree_top.png differ diff --git a/games/devtest/mods/basenodes/textures/default_lava.png b/games/devtest/mods/basenodes/textures/default_lava.png new file mode 100644 index 0000000..a4cf649 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_lava.png differ diff --git a/games/devtest/mods/basenodes/textures/default_lava_flowing.png b/games/devtest/mods/basenodes/textures/default_lava_flowing.png new file mode 100644 index 0000000..07066a6 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_lava_flowing.png differ diff --git a/games/devtest/mods/basenodes/textures/default_leaves.png b/games/devtest/mods/basenodes/textures/default_leaves.png new file mode 100644 index 0000000..c0475d4 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_leaves.png differ diff --git a/games/devtest/mods/basenodes/textures/default_mossycobble.png b/games/devtest/mods/basenodes/textures/default_mossycobble.png new file mode 100644 index 0000000..69585e3 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_mossycobble.png differ diff --git a/games/devtest/mods/basenodes/textures/default_pine_needles.png b/games/devtest/mods/basenodes/textures/default_pine_needles.png new file mode 100644 index 0000000..137caa2 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_pine_needles.png differ diff --git a/games/devtest/mods/basenodes/textures/default_pine_tree.png b/games/devtest/mods/basenodes/textures/default_pine_tree.png new file mode 100644 index 0000000..5743183 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_pine_tree.png differ diff --git a/games/devtest/mods/basenodes/textures/default_pine_tree_top.png b/games/devtest/mods/basenodes/textures/default_pine_tree_top.png new file mode 100644 index 0000000..cc18f34 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_pine_tree_top.png differ diff --git a/games/devtest/mods/basenodes/textures/default_river_water.png b/games/devtest/mods/basenodes/textures/default_river_water.png new file mode 100644 index 0000000..e1074d2 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_river_water.png differ diff --git a/games/devtest/mods/basenodes/textures/default_river_water_flowing.png b/games/devtest/mods/basenodes/textures/default_river_water_flowing.png new file mode 100644 index 0000000..4a756b2 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_river_water_flowing.png differ diff --git a/games/devtest/mods/basenodes/textures/default_sand.png b/games/devtest/mods/basenodes/textures/default_sand.png new file mode 100644 index 0000000..0ed0e4c Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_sand.png differ diff --git a/games/devtest/mods/basenodes/textures/default_snow.png b/games/devtest/mods/basenodes/textures/default_snow.png new file mode 100644 index 0000000..c42e0ee Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_snow.png differ diff --git a/games/devtest/mods/basenodes/textures/default_snow_side.png b/games/devtest/mods/basenodes/textures/default_snow_side.png new file mode 100644 index 0000000..f34d109 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_snow_side.png differ diff --git a/games/devtest/mods/basenodes/textures/default_stone.png b/games/devtest/mods/basenodes/textures/default_stone.png new file mode 100644 index 0000000..763b439 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_stone.png differ diff --git a/games/devtest/mods/basenodes/textures/default_tree.png b/games/devtest/mods/basenodes/textures/default_tree.png new file mode 100644 index 0000000..189ec15 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_tree.png differ diff --git a/games/devtest/mods/basenodes/textures/default_tree_top.png b/games/devtest/mods/basenodes/textures/default_tree_top.png new file mode 100644 index 0000000..d1a4fa7 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_tree_top.png differ diff --git a/games/devtest/mods/basenodes/textures/default_water.png b/games/devtest/mods/basenodes/textures/default_water.png new file mode 100644 index 0000000..3e385ae Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_water.png differ diff --git a/games/devtest/mods/basenodes/textures/default_water_flowing.png b/games/devtest/mods/basenodes/textures/default_water_flowing.png new file mode 100644 index 0000000..7cdafd5 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/default_water_flowing.png differ diff --git a/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass.png b/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass.png new file mode 100644 index 0000000..29fde6b Binary files /dev/null and b/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass.png differ diff --git a/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass_side.png b/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass_side.png new file mode 100644 index 0000000..04770b6 Binary files /dev/null and b/games/devtest/mods/basenodes/textures/dirt_with_grass/default_grass_side.png differ diff --git a/games/devtest/mods/basenodes/textures/info.txt b/games/devtest/mods/basenodes/textures/info.txt new file mode 100644 index 0000000..2d4ef7e --- /dev/null +++ b/games/devtest/mods/basenodes/textures/info.txt @@ -0,0 +1,7 @@ + +The dirt_with_grass folder is for testing loading textures from subfolders. +If it works correctly, the default_grass_side.png file in the folder is used but +default_grass.png is not overwritten by the file in the folder. + +default_dirt.png should be overwritten by the default_dirt.png in the unittests +mod which depends on basenodes. diff --git a/games/devtest/mods/basetools/init.lua b/games/devtest/mods/basetools/init.lua new file mode 100644 index 0000000..3ec69d3 --- /dev/null +++ b/games/devtest/mods/basetools/init.lua @@ -0,0 +1,449 @@ +-- +-- Tool definitions +-- + +--[[ TOOLS SUMMARY: + +Tool types: + +* Hand: basic tool/weapon (special capabilities in creative mode) +* Pickaxe: dig cracky +* Axe: dig choppy +* Shovel: dig crumbly +* Shears: dig snappy +* Sword: deal damage +* Dagger: deal damage, but faster + +Tool materials: + +* Wood: dig nodes of rating 3 +* Stone: dig nodes of rating 3 or 2 +* Steel: dig nodes of rating 3, 2 or 1 +* Mese: dig "everything" instantly +* n-Uses: can be used n times before breaking +]] + +-- The hand +if minetest.settings:get_bool("creative_mode") then + local digtime = 42 + local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 256} + + minetest.register_item(":", { + type = "none", + wield_image = "wieldhand.png", + wield_scale = {x = 1, y = 1, z = 2.5}, + range = 10, + tool_capabilities = { + full_punch_interval = 0.5, + max_drop_level = 3, + groupcaps = { + crumbly = caps, + cracky = caps, + snappy = caps, + choppy = caps, + oddly_breakable_by_hand = caps, + -- dig_immediate group doesn't use value 1. Value 3 is instant dig + dig_immediate = + {times = {[2] = digtime, [3] = 0}, uses = 0, maxlevel = 256}, + }, + damage_groups = {fleshy = 10}, + } + }) +else + minetest.register_item(":", { + type = "none", + wield_image = "wieldhand.png", + wield_scale = {x = 1, y = 1, z = 2.5}, + tool_capabilities = { + full_punch_interval = 0.9, + max_drop_level = 0, + groupcaps = { + crumbly = {times = {[2] = 3.00, [3] = 0.70}, uses = 0, maxlevel = 1}, + snappy = {times = {[3] = 0.40}, uses = 0, maxlevel = 1}, + oddly_breakable_by_hand = + {times = {[1] = 3.50, [2] = 2.00, [3] = 0.70}, uses = 0} + }, + damage_groups = {fleshy = 1}, + } + }) +end + +-- Mese Pickaxe: special tool that digs "everything" instantly +minetest.register_tool("basetools:pick_mese", { + description = "Mese Pickaxe".."\n".. + "Digs diggable nodes instantly", + inventory_image = "basetools_mesepick.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=3, + groupcaps={ + cracky={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255}, + crumbly={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255}, + snappy={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255}, + choppy={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255}, + dig_immediate={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255}, + }, + damage_groups = {fleshy=100}, + }, +}) + + +-- +-- Pickaxes: Dig cracky +-- + +minetest.register_tool("basetools:pick_wood", { + description = "Wooden Pickaxe".."\n".. + "Digs cracky=3", + inventory_image = "basetools_woodpick.png", + tool_capabilities = { + max_drop_level=0, + groupcaps={ + cracky={times={[3]=2.00}, uses=30, maxlevel=0} + }, + }, +}) +minetest.register_tool("basetools:pick_stone", { + description = "Stone Pickaxe".."\n".. + "Digs cracky=2..3", + inventory_image = "basetools_stonepick.png", + tool_capabilities = { + max_drop_level=0, + groupcaps={ + cracky={times={[2]=1.20, [3]=0.80}, uses=60, maxlevel=0} + }, + }, +}) +minetest.register_tool("basetools:pick_steel", { + description = "Steel Pickaxe".."\n".. + "Digs cracky=1..3", + inventory_image = "basetools_steelpick.png", + tool_capabilities = { + max_drop_level=1, + groupcaps={ + cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=0} + }, + }, +}) +minetest.register_tool("basetools:pick_steel_l1", { + description = "Steel Pickaxe Level 1".."\n".. + "Digs cracky=1..3".."\n".. + "maxlevel=1", + inventory_image = "basetools_steelpick_l1.png", + tool_capabilities = { + max_drop_level=1, + groupcaps={ + cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=1} + }, + }, +}) +minetest.register_tool("basetools:pick_steel_l2", { + description = "Steel Pickaxe Level 2".."\n".. + "Digs cracky=1..3".."\n".. + "maxlevel=2", + inventory_image = "basetools_steelpick_l2.png", + tool_capabilities = { + max_drop_level=1, + groupcaps={ + cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=2} + }, + }, +}) + +-- +-- Shovels (dig crumbly) +-- + +minetest.register_tool("basetools:shovel_wood", { + description = "Wooden Shovel".."\n".. + "Digs crumbly=3", + inventory_image = "basetools_woodshovel.png", + tool_capabilities = { + max_drop_level=0, + groupcaps={ + crumbly={times={[3]=0.50}, uses=30, maxlevel=0} + }, + }, +}) +minetest.register_tool("basetools:shovel_stone", { + description = "Stone Shovel".."\n".. + "Digs crumbly=2..3", + inventory_image = "basetools_stoneshovel.png", + tool_capabilities = { + max_drop_level=0, + groupcaps={ + crumbly={times={[2]=0.50, [3]=0.30}, uses=60, maxlevel=0} + }, + }, +}) +minetest.register_tool("basetools:shovel_steel", { + description = "Steel Shovel".."\n".. + "Digs crumbly=1..3", + inventory_image = "basetools_steelshovel.png", + tool_capabilities = { + max_drop_level=1, + groupcaps={ + crumbly={times={[1]=1.00, [2]=0.70, [3]=0.60}, uses=90, maxlevel=0} + }, + }, +}) + +-- +-- Axes (dig choppy) +-- + +minetest.register_tool("basetools:axe_wood", { + description = "Wooden Axe".."\n".. + "Digs choppy=3", + inventory_image = "basetools_woodaxe.png", + tool_capabilities = { + max_drop_level=0, + groupcaps={ + choppy={times={[3]=0.80}, uses=30, maxlevel=0}, + }, + }, +}) +minetest.register_tool("basetools:axe_stone", { + description = "Stone Axe".."\n".. + "Digs choppy=2..3", + inventory_image = "basetools_stoneaxe.png", + tool_capabilities = { + max_drop_level=0, + groupcaps={ + choppy={times={[2]=1.00, [3]=0.60}, uses=60, maxlevel=0}, + }, + }, +}) +minetest.register_tool("basetools:axe_steel", { + description = "Steel Axe".."\n".. + "Digs choppy=1..3", + inventory_image = "basetools_steelaxe.png", + tool_capabilities = { + max_drop_level=1, + groupcaps={ + choppy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=90, maxlevel=0}, + }, + }, +}) + +-- +-- Shears (dig snappy) +-- + +minetest.register_tool("basetools:shears_wood", { + description = "Wooden Shears".."\n".. + "Digs snappy=3", + inventory_image = "basetools_woodshears.png", + tool_capabilities = { + max_drop_level=0, + groupcaps={ + snappy={times={[3]=1.00}, uses=30, maxlevel=0}, + }, + }, +}) +minetest.register_tool("basetools:shears_stone", { + description = "Stone Shears".."\n".. + "Digs snappy=2..3", + inventory_image = "basetools_stoneshears.png", + tool_capabilities = { + max_drop_level=0, + groupcaps={ + snappy={times={[2]=1.00, [3]=0.50}, uses=60, maxlevel=0}, + }, + }, +}) +minetest.register_tool("basetools:shears_steel", { + description = "Steel Shears".."\n".. + "Digs snappy=1..3", + inventory_image = "basetools_steelshears.png", + tool_capabilities = { + max_drop_level=1, + groupcaps={ + snappy={times={[1]=1.00, [2]=0.50, [3]=0.25}, uses=90, maxlevel=0}, + }, + }, +}) + +-- +-- Swords (deal damage) +-- + +minetest.register_tool("basetools:sword_wood", { + description = "Wooden Sword".."\n".. + "Damage: fleshy=2", + inventory_image = "basetools_woodsword.png", + tool_capabilities = { + full_punch_interval = 1.0, + damage_groups = {fleshy=2}, + } +}) +minetest.register_tool("basetools:sword_stone", { + description = "Stone Sword".."\n".. + "Damage: fleshy=5", + inventory_image = "basetools_stonesword.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=0, + damage_groups = {fleshy=5}, + } +}) +minetest.register_tool("basetools:sword_steel", { + description = "Steel Sword".."\n".. + "Damage: fleshy=10", + inventory_image = "basetools_steelsword.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + damage_groups = {fleshy=10}, + } +}) +minetest.register_tool("basetools:sword_titanium", { + description = "Titanium Sword".."\n".. + "Damage: fleshy=100", + inventory_image = "basetools_titaniumsword.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + damage_groups = {fleshy=100}, + } +}) +minetest.register_tool("basetools:sword_blood", { + description = "Blood Sword".."\n".. + "Damage: fleshy=1000", + inventory_image = "basetools_bloodsword.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + damage_groups = {fleshy=1000}, + } +}) + +-- Max. damage sword +minetest.register_tool("basetools:sword_mese", { + description = "Mese Sword".."\n".. + "Damage: fleshy=32767, fiery=32767, icy=32767".."\n".. + "Full Punch Interval: 0.0s", + inventory_image = "basetools_mesesword.png", + tool_capabilities = { + full_punch_interval = 0.0, + max_drop_level=1, + damage_groups = {fleshy=32767, fiery=32767, icy=32767}, + } +}) + +-- Fire/Ice sword: Deal damage to non-fleshy damage groups +minetest.register_tool("basetools:sword_fire", { + description = "Fire Sword".."\n".. + "Damage: icy=10", + inventory_image = "basetools_firesword.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=0, + damage_groups = {icy=10}, + } +}) +minetest.register_tool("basetools:sword_ice", { + description = "Ice Sword".."\n".. + "Damage: fiery=10", + inventory_image = "basetools_icesword.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=0, + damage_groups = {fiery=10}, + } +}) +minetest.register_tool("basetools:sword_elemental", { + description = "Elemental Sword".."\n".. + "Damage: fiery=10, icy=10", + inventory_image = "basetools_elementalsword.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=0, + damage_groups = {fiery=10, icy=10}, + } +}) + +-- Healing weapons: heal HP +minetest.register_tool("basetools:dagger_heal", { + description = "Healing Dagger".."\n".. + "Heal: fleshy=1".."\n".. + "Full Punch Interval: 0.5s", + inventory_image = "basetools_healdagger.png", + tool_capabilities = { + full_punch_interval = 0.5, + damage_groups = {fleshy=-1}, + } +}) +minetest.register_tool("basetools:sword_heal", { + description = "Healing Sword".."\n".. + "Heal: fleshy=10", + inventory_image = "basetools_healsword.png", + tool_capabilities = { + full_punch_interval = 1.0, + damage_groups = {fleshy=-10}, + } +}) +minetest.register_tool("basetools:sword_heal_super", { + description = "Super Healing Sword".."\n".. + "Heal: fleshy=32768, fiery=32768, icy=32768", + inventory_image = "basetools_superhealsword.png", + tool_capabilities = { + full_punch_interval = 1.0, + damage_groups = {fleshy=-32768, fiery=-32768, icy=-32768}, + } +}) + + +-- +-- Dagger: Low damage, fast punch interval +-- +minetest.register_tool("basetools:dagger_wood", { + description = "Wooden Dagger".."\n".. + "Damage: fleshy=1".."\n".. + "Full Punch Interval: 0.5s", + inventory_image = "basetools_wooddagger.png", + tool_capabilities = { + full_punch_interval = 0.5, + max_drop_level=0, + damage_groups = {fleshy=1}, + } +}) +minetest.register_tool("basetools:dagger_steel", { + description = "Steel Dagger".."\n".. + "Damage: fleshy=2".."\n".. + "Full Punch Interval: 0.5s", + inventory_image = "basetools_steeldagger.png", + tool_capabilities = { + full_punch_interval = 0.5, + max_drop_level=0, + damage_groups = {fleshy=2}, + } +}) + +-- Test tool uses and punch_attack_uses +local uses = { 1, 2, 3, 5, 10, 50, 100, 1000, 10000, 65535 } +for i=1, #uses do + local u = uses[i] + local color = string.format("#FF00%02X", math.floor(((i-1)/#uses) * 255)) + minetest.register_tool("basetools:pick_uses_"..string.format("%05d", u), { + description = u.."-Uses Pickaxe".."\n".. + "Digs cracky=3", + inventory_image = "basetools_usespick.png^[colorize:"..color..":127", + tool_capabilities = { + max_drop_level=0, + groupcaps={ + cracky={times={[3]=0.1, [2]=0.2, [1]=0.3}, uses=u, maxlevel=0} + }, + }, + }) + + minetest.register_tool("basetools:sword_uses_"..string.format("%05d", u), { + description = u.."-Uses Sword".."\n".. + "Damage: fleshy=1", + inventory_image = "basetools_usessword.png^[colorize:"..color..":127", + tool_capabilities = { + damage_groups = {fleshy=1}, + punch_attack_uses = u, + }, + }) +end diff --git a/games/devtest/mods/basetools/mod.conf b/games/devtest/mods/basetools/mod.conf new file mode 100644 index 0000000..f0d9f65 --- /dev/null +++ b/games/devtest/mods/basetools/mod.conf @@ -0,0 +1,2 @@ +name = basetools +description = Contains basic digging tools diff --git a/games/devtest/mods/basetools/textures/basetools_bloodsword.png b/games/devtest/mods/basetools/textures/basetools_bloodsword.png new file mode 100644 index 0000000..a521ba4 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_bloodsword.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_elementalsword.png b/games/devtest/mods/basetools/textures/basetools_elementalsword.png new file mode 100644 index 0000000..d007217 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_elementalsword.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_firesword.png b/games/devtest/mods/basetools/textures/basetools_firesword.png new file mode 100644 index 0000000..eca999b Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_firesword.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_healdagger.png b/games/devtest/mods/basetools/textures/basetools_healdagger.png new file mode 100644 index 0000000..3e6eb9c Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_healdagger.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_healsword.png b/games/devtest/mods/basetools/textures/basetools_healsword.png new file mode 100644 index 0000000..f93fddf Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_healsword.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_icesword.png b/games/devtest/mods/basetools/textures/basetools_icesword.png new file mode 100644 index 0000000..55a8d60 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_icesword.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_mesepick.png b/games/devtest/mods/basetools/textures/basetools_mesepick.png new file mode 100644 index 0000000..2993b47 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_mesepick.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_mesesword.png b/games/devtest/mods/basetools/textures/basetools_mesesword.png new file mode 100644 index 0000000..bc82769 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_mesesword.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_steelaxe.png b/games/devtest/mods/basetools/textures/basetools_steelaxe.png new file mode 100644 index 0000000..aac594d Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_steelaxe.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_steeldagger.png b/games/devtest/mods/basetools/textures/basetools_steeldagger.png new file mode 100644 index 0000000..4c91730 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_steeldagger.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_steelpick.png b/games/devtest/mods/basetools/textures/basetools_steelpick.png new file mode 100644 index 0000000..bc02aac Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_steelpick.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_steelpick_l1.png b/games/devtest/mods/basetools/textures/basetools_steelpick_l1.png new file mode 100644 index 0000000..dc03f3f Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_steelpick_l1.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_steelpick_l2.png b/games/devtest/mods/basetools/textures/basetools_steelpick_l2.png new file mode 100644 index 0000000..011df45 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_steelpick_l2.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_steelshears.png b/games/devtest/mods/basetools/textures/basetools_steelshears.png new file mode 100644 index 0000000..04c86c3 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_steelshears.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_steelshovel.png b/games/devtest/mods/basetools/textures/basetools_steelshovel.png new file mode 100644 index 0000000..8cab607 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_steelshovel.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_steelsword.png b/games/devtest/mods/basetools/textures/basetools_steelsword.png new file mode 100644 index 0000000..9909365 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_steelsword.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_stoneaxe.png b/games/devtest/mods/basetools/textures/basetools_stoneaxe.png new file mode 100644 index 0000000..a374c54 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_stoneaxe.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_stonepick.png b/games/devtest/mods/basetools/textures/basetools_stonepick.png new file mode 100644 index 0000000..d9156ee Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_stonepick.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_stoneshears.png b/games/devtest/mods/basetools/textures/basetools_stoneshears.png new file mode 100644 index 0000000..0b4bd3b Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_stoneshears.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_stoneshovel.png b/games/devtest/mods/basetools/textures/basetools_stoneshovel.png new file mode 100644 index 0000000..3c1bb48 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_stoneshovel.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_stonesword.png b/games/devtest/mods/basetools/textures/basetools_stonesword.png new file mode 100644 index 0000000..6f3e94c Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_stonesword.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_superhealsword.png b/games/devtest/mods/basetools/textures/basetools_superhealsword.png new file mode 100644 index 0000000..4175a09 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_superhealsword.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_titaniumsword.png b/games/devtest/mods/basetools/textures/basetools_titaniumsword.png new file mode 100644 index 0000000..55e22c7 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_titaniumsword.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_usespick.png b/games/devtest/mods/basetools/textures/basetools_usespick.png new file mode 100644 index 0000000..27850f9 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_usespick.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_usessword.png b/games/devtest/mods/basetools/textures/basetools_usessword.png new file mode 100644 index 0000000..0eaf4cf Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_usessword.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_woodaxe.png b/games/devtest/mods/basetools/textures/basetools_woodaxe.png new file mode 100644 index 0000000..4015e91 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_woodaxe.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_wooddagger.png b/games/devtest/mods/basetools/textures/basetools_wooddagger.png new file mode 100644 index 0000000..6e5ab0f Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_wooddagger.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_woodpick.png b/games/devtest/mods/basetools/textures/basetools_woodpick.png new file mode 100644 index 0000000..15c61f4 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_woodpick.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_woodshears.png b/games/devtest/mods/basetools/textures/basetools_woodshears.png new file mode 100644 index 0000000..4ff92fd Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_woodshears.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_woodshovel.png b/games/devtest/mods/basetools/textures/basetools_woodshovel.png new file mode 100644 index 0000000..6cc52f8 Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_woodshovel.png differ diff --git a/games/devtest/mods/basetools/textures/basetools_woodsword.png b/games/devtest/mods/basetools/textures/basetools_woodsword.png new file mode 100644 index 0000000..364016e Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_woodsword.png differ diff --git a/games/devtest/mods/broken/init.lua b/games/devtest/mods/broken/init.lua new file mode 100644 index 0000000..04993ca --- /dev/null +++ b/games/devtest/mods/broken/init.lua @@ -0,0 +1,11 @@ +-- Register stuff with empty definitions to test if Minetest fallback options +-- for these things work properly. + +-- The itemstrings are deliberately kept descriptive to keep them easy to +-- recognize. + +minetest.register_node("broken:node_with_empty_definition", {}) +minetest.register_tool("broken:tool_with_empty_definition", {}) +minetest.register_craftitem("broken:craftitem_with_empty_definition", {}) + +minetest.register_entity("broken:entity_with_empty_definition", {}) diff --git a/games/devtest/mods/broken/mod.conf b/games/devtest/mods/broken/mod.conf new file mode 100644 index 0000000..a24378a --- /dev/null +++ b/games/devtest/mods/broken/mod.conf @@ -0,0 +1,2 @@ +name = broken +description = Register items and an entity with empty definitions to test fallback diff --git a/games/devtest/mods/bucket/init.lua b/games/devtest/mods/bucket/init.lua new file mode 100644 index 0000000..ff58b06 --- /dev/null +++ b/games/devtest/mods/bucket/init.lua @@ -0,0 +1,27 @@ +-- Bucket: Punch liquid source or flowing liquid to collect it + +minetest.register_tool("bucket:bucket", { + description = "Bucket".."\n".. + "Picks up liquid nodes", + inventory_image = "bucket.png", + stack_max = 1, + liquids_pointable = true, + groups = { disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + -- Must be pointing to node + if pointed_thing.type ~= "node" then + return + end + -- Check if pointing to a liquid + local n = minetest.get_node(pointed_thing.under) + local def = minetest.registered_nodes[n.name] + if def ~= nil and (def.liquidtype == "source" or def.liquidtype == "flowing") then + minetest.add_node(pointed_thing.under, {name="air"}) + local inv = user:get_inventory() + if inv then + inv:add_item("main", ItemStack(n.name)) + end + end + end, +}) + diff --git a/games/devtest/mods/bucket/mod.conf b/games/devtest/mods/bucket/mod.conf new file mode 100644 index 0000000..d14deb4 --- /dev/null +++ b/games/devtest/mods/bucket/mod.conf @@ -0,0 +1,2 @@ +name = bucket +description = Minimal bucket to pick up liquids diff --git a/games/devtest/mods/bucket/textures/bucket.png b/games/devtest/mods/bucket/textures/bucket.png new file mode 100644 index 0000000..6779528 Binary files /dev/null and b/games/devtest/mods/bucket/textures/bucket.png differ diff --git a/games/devtest/mods/bucket/textures/bucket_lava.png b/games/devtest/mods/bucket/textures/bucket_lava.png new file mode 100644 index 0000000..dfcae65 Binary files /dev/null and b/games/devtest/mods/bucket/textures/bucket_lava.png differ diff --git a/games/devtest/mods/bucket/textures/bucket_water.png b/games/devtest/mods/bucket/textures/bucket_water.png new file mode 100644 index 0000000..e164b0a Binary files /dev/null and b/games/devtest/mods/bucket/textures/bucket_water.png differ diff --git a/games/devtest/mods/chest/init.lua b/games/devtest/mods/chest/init.lua new file mode 100644 index 0000000..5798c13 --- /dev/null +++ b/games/devtest/mods/chest/init.lua @@ -0,0 +1,40 @@ +minetest.register_node("chest:chest", { + description = "Chest" .. "\n" .. + "32 inventory slots", + tiles ={"chest_chest.png^[sheet:2x2:0,0", "chest_chest.png^[sheet:2x2:0,0", + "chest_chest.png^[sheet:2x2:1,0", "chest_chest.png^[sheet:2x2:1,0", + "chest_chest.png^[sheet:2x2:1,0", "chest_chest.png^[sheet:2x2:0,1"}, + paramtype2 = "facedir", + groups = {dig_immediate=2,choppy=3}, + is_ground_content = false, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", + "size[8,9]".. + "list[current_name;main;0,0;8,4;]".. + "list[current_player;main;0,5;8,4;]" .. + "listring[]") + meta:set_string("infotext", "Chest") + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("main") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.chat_send_player(player:get_player_name(), "Allow put: " .. stack:to_string()) + return stack:get_count() + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.chat_send_player(player:get_player_name(), "Allow take: " .. stack:to_string()) + return stack:get_count() + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.chat_send_player(player:get_player_name(), "On put: " .. stack:to_string()) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.chat_send_player(player:get_player_name(), "On take: " .. stack:to_string()) + end, +}) diff --git a/games/devtest/mods/chest/mod.conf b/games/devtest/mods/chest/mod.conf new file mode 100644 index 0000000..0d75001 --- /dev/null +++ b/games/devtest/mods/chest/mod.conf @@ -0,0 +1,2 @@ +name = chest +description = A simple chest to store items diff --git a/games/devtest/mods/chest/textures/chest_chest.png b/games/devtest/mods/chest/textures/chest_chest.png new file mode 100644 index 0000000..824b4d5 Binary files /dev/null and b/games/devtest/mods/chest/textures/chest_chest.png differ diff --git a/games/devtest/mods/chest_of_everything/init.lua b/games/devtest/mods/chest_of_everything/init.lua new file mode 100644 index 0000000..3e9d267 --- /dev/null +++ b/games/devtest/mods/chest_of_everything/init.lua @@ -0,0 +1,136 @@ +local F = minetest.formspec_escape + +-- Create a detached inventory +local inv_everything = minetest.create_detached_inventory("everything", { + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + allow_put = function(inv, listname, index, stack, player) + return 0 + end, + allow_take = function(inv, listname, index, stack, player) + return -1 + end, +}) +local inv_trash = minetest.create_detached_inventory("trash", { + allow_take = function(inv, listname, index, stack, player) + return 0 + end, + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + on_put = function(inv, listname, index, stack, player) + inv:set_list("main", {}) + end, +}) +inv_trash:set_size("main", 1) + +local max_page = 1 + +local function get_chest_formspec(page) + local start = 0 + (page-1)*32 + return "size[8,9]".. + "list[detached:everything;main;0,0;8,4;"..start.."]".. + "list[current_player;main;0,5;8,4;]" .. + "label[6,4;Trash:]" .. + "list[detached:trash;main;7,4;1,1]" .. + "button[0,4;1,1;chest_of_everything_prev;"..F("<").."]".. + "button[1,4;1,1;chest_of_everything_next;"..F(">").."]".. + "label[2,4;"..F("Page: "..page).."]".. + "listring[detached:everything;main]".. + "listring[current_player;main]".. + "listring[detached:trash;main]" +end + +minetest.register_node("chest_of_everything:chest", { + description = "Chest of Everything" .. "\n" .. + "Grants access to all items", + tiles ={"chest_of_everything_chest.png^[sheet:2x2:0,0", "chest_of_everything_chest.png^[sheet:2x2:0,0", + "chest_of_everything_chest.png^[sheet:2x2:1,0", "chest_of_everything_chest.png^[sheet:2x2:1,0", + "chest_of_everything_chest.png^[sheet:2x2:1,0", "chest_of_everything_chest.png^[sheet:2x2:0,1"}, + paramtype2 = "facedir", + groups = {dig_immediate=2,choppy=3}, + is_ground_content = false, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Chest of Everything") + meta:set_int("page", 1) + meta:set_string("formspec", get_chest_formspec(1)) + end, + on_receive_fields = function(pos, formname, fields, sender) + if formname == "" then + local meta = minetest.get_meta(pos) + local page = meta:get_int("page") + if fields.chest_of_everything_prev then + page = page - 1 + elseif fields.chest_of_everything_next then + page = page + 1 + end + if page < 1 then + page = 1 + end + if page > max_page then + page = max_page + end + meta:set_int("page", page) + meta:set_string("formspec", get_chest_formspec(page)) + end + end, +}) + +minetest.register_on_mods_loaded(function() + local items = {} + for itemstring,_ in pairs(minetest.registered_items) do + if itemstring ~= "" and itemstring ~= "unknown" and itemstring ~= "ignore" then + table.insert(items, itemstring) + end + end + --[[ Sort items in this order: + * Chest of Everything + * Test tools + * Other tools + * Craftitems + * Other items + * Dummy items ]] + local function compare(item1, item2) + local def1 = minetest.registered_items[item1] + local def2 = minetest.registered_items[item2] + local tool1 = def1.type == "tool" + local tool2 = def2.type == "tool" + local testtool1 = minetest.get_item_group(item1, "testtool") == 1 + local testtool2 = minetest.get_item_group(item2, "testtool") == 1 + local dummy1 = minetest.get_item_group(item1, "dummy") == 1 + local dummy2 = minetest.get_item_group(item2, "dummy") == 1 + local craftitem1 = def1.type == "craft" + local craftitem2 = def2.type == "craft" + if item1 == "chest_of_everything:chest" then + return true + elseif item2 == "chest_of_everything:chest" then + return false + elseif dummy1 and not dummy2 then + return false + elseif not dummy1 and dummy2 then + return true + elseif testtool1 and not testtool2 then + return true + elseif not testtool1 and testtool2 then + return false + elseif tool1 and not tool2 then + return true + elseif not tool1 and tool2 then + return false + elseif craftitem1 and not craftitem2 then + return true + elseif not craftitem1 and craftitem2 then + return false + else + return item1 < item2 + end + end + table.sort(items, compare) + inv_everything:set_size("main", #items) + max_page = math.ceil(#items / 32) + for i=1, #items do + inv_everything:add_item("main", items[i]) + end +end) diff --git a/games/devtest/mods/chest_of_everything/mod.conf b/games/devtest/mods/chest_of_everything/mod.conf new file mode 100644 index 0000000..4a4425e --- /dev/null +++ b/games/devtest/mods/chest_of_everything/mod.conf @@ -0,0 +1,2 @@ +name = chest_of_everything +description = Adds the chest of everything from which you can take all items diff --git a/games/devtest/mods/chest_of_everything/textures/chest_of_everything_chest.png b/games/devtest/mods/chest_of_everything/textures/chest_of_everything_chest.png new file mode 100644 index 0000000..6b2fd58 Binary files /dev/null and b/games/devtest/mods/chest_of_everything/textures/chest_of_everything_chest.png differ diff --git a/games/devtest/mods/dignodes/init.lua b/games/devtest/mods/dignodes/init.lua new file mode 100644 index 0000000..8331508 --- /dev/null +++ b/games/devtest/mods/dignodes/init.lua @@ -0,0 +1,37 @@ +local groups = { + "cracky", "dig_immediate" +} + +-- Register dig nodes with 1 digging group, a rating between 1-3 and a level between 0-2 +for g=1, #groups do + local gr = groups[g] + for r=1, 3 do + for l=0, 2 do + if not (gr=="dig_immediate" and (l>0 or r==1)) then + local d + if l > 0 then + d = string.format("Dig Test Node: %s=%d, level=%d", gr, r, l) + else + d = string.format("Dig Test Node: %s=%d", gr, r) + end + local tile = "dignodes_"..gr..".png^dignodes_rating"..r..".png" + if l==1 then + tile = tile .. "^[colorize:#FFFF00:127" + elseif l==2 then + tile = tile .. "^[colorize:#FF0000:127" + end + minetest.register_node("dignodes:"..gr.."_"..r.."_"..l, { + description = d, + tiles = { tile }, + groups = { [gr] = r, level = l }, + }) + end + end + end +end + +-- Node without any digging groups +minetest.register_node("dignodes:none", { + description = "Dig Test Node: groupless", + tiles = {"dignodes_none.png"}, +}) diff --git a/games/devtest/mods/dignodes/mod.conf b/games/devtest/mods/dignodes/mod.conf new file mode 100644 index 0000000..52a80d6 --- /dev/null +++ b/games/devtest/mods/dignodes/mod.conf @@ -0,0 +1,2 @@ +name = dignodes +description = Nodes with different digging groups diff --git a/games/devtest/mods/dignodes/textures/dignodes_choppy.png b/games/devtest/mods/dignodes/textures/dignodes_choppy.png new file mode 100644 index 0000000..a73fc24 Binary files /dev/null and b/games/devtest/mods/dignodes/textures/dignodes_choppy.png differ diff --git a/games/devtest/mods/dignodes/textures/dignodes_cracky.png b/games/devtest/mods/dignodes/textures/dignodes_cracky.png new file mode 100644 index 0000000..eb84e30 Binary files /dev/null and b/games/devtest/mods/dignodes/textures/dignodes_cracky.png differ diff --git a/games/devtest/mods/dignodes/textures/dignodes_crumbly.png b/games/devtest/mods/dignodes/textures/dignodes_crumbly.png new file mode 100644 index 0000000..23f2f7c Binary files /dev/null and b/games/devtest/mods/dignodes/textures/dignodes_crumbly.png differ diff --git a/games/devtest/mods/dignodes/textures/dignodes_dig_immediate.png b/games/devtest/mods/dignodes/textures/dignodes_dig_immediate.png new file mode 100644 index 0000000..a532ad9 Binary files /dev/null and b/games/devtest/mods/dignodes/textures/dignodes_dig_immediate.png differ diff --git a/games/devtest/mods/dignodes/textures/dignodes_none.png b/games/devtest/mods/dignodes/textures/dignodes_none.png new file mode 100644 index 0000000..60f1365 Binary files /dev/null and b/games/devtest/mods/dignodes/textures/dignodes_none.png differ diff --git a/games/devtest/mods/dignodes/textures/dignodes_rating1.png b/games/devtest/mods/dignodes/textures/dignodes_rating1.png new file mode 100644 index 0000000..d2fee3a Binary files /dev/null and b/games/devtest/mods/dignodes/textures/dignodes_rating1.png differ diff --git a/games/devtest/mods/dignodes/textures/dignodes_rating2.png b/games/devtest/mods/dignodes/textures/dignodes_rating2.png new file mode 100644 index 0000000..15329b9 Binary files /dev/null and b/games/devtest/mods/dignodes/textures/dignodes_rating2.png differ diff --git a/games/devtest/mods/dignodes/textures/dignodes_rating3.png b/games/devtest/mods/dignodes/textures/dignodes_rating3.png new file mode 100644 index 0000000..37216bf Binary files /dev/null and b/games/devtest/mods/dignodes/textures/dignodes_rating3.png differ diff --git a/games/devtest/mods/experimental/commands.lua b/games/devtest/mods/experimental/commands.lua new file mode 100644 index 0000000..e42ae95 --- /dev/null +++ b/games/devtest/mods/experimental/commands.lua @@ -0,0 +1,221 @@ +minetest.register_chatcommand("test_inv", { + params = "", + description = "Test: Modify player's inventory formspec", + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "No player." + end + player:set_inventory_formspec( + "size[13,7.5]".. + "image[6,0.6;1,2;player.png]".. + "list[current_player;main;5,3.5;8,4;]".. + "list[current_player;craft;8,0;3,3;]".. + "list[current_player;craftpreview;12,1;1,1;]".. + "list[detached:test_inventory;main;0,0;4,6;0]".. + "button[0.5,7;2,1;button1;Button 1]".. + "button_exit[2.5,7;2,1;button2;Exit Button]") + return true, "Done." + end, +}) + +minetest.register_chatcommand("test_bulk_set_node", { + params = "", + description = "Test: Bulk-set 9×9×9 stone nodes", + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "No player." + end + local pos_list = {} + local ppos = player:get_pos() + local i = 1 + for x=2,10 do + for y=2,10 do + for z=2,10 do + pos_list[i] = {x=ppos.x + x,y = ppos.y + y,z = ppos.z + z} + i = i + 1 + end + end + end + minetest.bulk_set_node(pos_list, {name = "mapgen_stone"}) + return true, "Done." + end, +}) + +minetest.register_chatcommand("bench_bulk_set_node", { + params = "", + description = "Benchmark: Bulk-set 99×99×99 stone nodes", + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "No player." + end + local pos_list = {} + local ppos = player:get_pos() + local i = 1 + for x=2,100 do + for y=2,100 do + for z=2,100 do + pos_list[i] = {x=ppos.x + x,y = ppos.y + y,z = ppos.z + z} + i = i + 1 + end + end + end + + minetest.chat_send_player(name, "Benchmarking minetest.bulk_set_node. Warming up ..."); + + -- warm up with stone to prevent having different callbacks + -- due to different node topology + minetest.bulk_set_node(pos_list, {name = "mapgen_stone"}) + + minetest.chat_send_player(name, "Warming up finished, now benchmarking ..."); + + local start_time = minetest.get_us_time() + for i=1,#pos_list do + minetest.set_node(pos_list[i], {name = "mapgen_stone"}) + end + local middle_time = minetest.get_us_time() + minetest.bulk_set_node(pos_list, {name = "mapgen_stone"}) + local end_time = minetest.get_us_time() + local msg = string.format("Benchmark results: minetest.set_node loop: %.2f ms; minetest.bulk_set_node: %.2f ms", + ((middle_time - start_time)) / 1000, + ((end_time - middle_time)) / 1000 + ) + return true, msg + end, +}) + +local function advance_pos(pos, start_pos, advance_z) + if advance_z then + pos.z = pos.z + 2 + pos.x = start_pos.x + else + pos.x = pos.x + 2 + end + if pos.x > 30900 or pos.x - start_pos.x > 46 then + pos.x = start_pos.x + pos.z = pos.z + 2 + end + if pos.z > 30900 then + -- We ran out of space! Aborting + aborted = true + return false + end + return pos +end + +local function place_nodes(param) + local nodes = param.nodes + local name = param.name + local pos = param.pos + local start_pos = param.start_pos + table.sort(nodes) + minetest.chat_send_player(name, "Placing nodes …") + local nodes_placed = 0 + local aborted = false + for n=1, #nodes do + local itemstring = nodes[n] + local def = minetest.registered_nodes[itemstring] + local p2_max = 0 + if param.param ~= "no_param2" then + -- Also test the param2 values of the nodes + -- ... but we only use permissible param2 values + if def.paramtype2 == "wallmounted" then + p2_max = 5 + elseif def.paramtype2 == "facedir" then + p2_max = 23 + elseif def.paramtype2 == "glasslikeliquidlevel" then + p2_max = 63 + elseif def.paramtype2 == "meshoptions" and def.drawtype == "plantlike" then + p2_max = 63 + elseif def.paramtype2 == "leveled" then + p2_max = 127 + elseif def.paramtype2 == "degrotate" and (def.drawtype == "plantlike" or def.drawtype == "mesh") then + p2_max = 239 + elseif def.paramtype2 == "colorfacedir" or + def.paramtype2 == "colorwallmounted" or + def.paramtype2 == "colordegrotate" or + def.paramtype2 == "color" then + p2_max = 255 + end + end + for p2 = 0, p2_max do + -- Skip undefined param2 values + if not ((def.paramtype2 == "meshoptions" and p2 % 8 > 4) or + (def.paramtype2 == "colorwallmounted" and p2 % 8 > 5) or + ((def.paramtype2 == "colorfacedir" or def.paramtype2 == "colordegrotate") + and p2 % 32 > 23)) then + + minetest.set_node(pos, { name = itemstring, param2 = p2 }) + nodes_placed = nodes_placed + 1 + pos = advance_pos(pos, start_pos) + if not pos then + aborted = true + break + end + end + end + if aborted then + break + end + end + if aborted then + minetest.chat_send_player(name, "Not all nodes could be placed, please move further away from the world boundary. Nodes placed: "..nodes_placed) + end + minetest.chat_send_player(name, "Nodes placed: "..nodes_placed..".") +end + +local function after_emerge(blockpos, action, calls_remaining, param) + if calls_remaining == 0 then + place_nodes(param) + end +end + +minetest.register_chatcommand("test_place_nodes", { + params = "[ no_param2 ]", + description = "Test: Place all non-experimental nodes and optionally their permissible param2 variants", + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "No player." + end + local pos = vector.floor(player:get_pos()) + pos.x = math.ceil(pos.x + 3) + pos.z = math.ceil(pos.z + 3) + pos.y = math.ceil(pos.y + 1) + local start_pos = table.copy(pos) + if pos.x > 30800 then + return false, "Too close to world boundary (+X). Please move to X < 30800." + end + if pos.z > 30800 then + return false, "Too close to world boundary (+Z). Please move to Z < 30800." + end + + local aborted = false + local nodes = {} + local emerge_estimate = 0 + for itemstring, def in pairs(minetest.registered_nodes) do + if itemstring ~= "ignore" and string.sub(itemstring, 1, 13) ~= "experimental:" then + table.insert(nodes, itemstring) + if def.paramtype2 == 0 then + emerge_estimate = emerge_estimate + 1 + else + emerge_estimate = emerge_estimate + 255 + end + end + end + -- Emerge area to make sure that all nodes are being placed. + -- Note we will emerge much more than we need to (overestimation), + -- the estimation code could be improved performance-wise … + local length = 16 + math.ceil(emerge_estimate / 24) * 2 + minetest.emerge_area(start_pos, + { x = start_pos.x + 46, y = start_pos.y, z = start_pos.z + length }, + after_emerge, { nodes = nodes, name = name, pos = pos, start_pos = start_pos, param = param }) + return true, "Emerging area …" + end, +}) + +core.register_on_chatcommand(function(name, command, params) + minetest.log("action", "caught command '"..command.."', issued by '"..name.."'. Parameters: '"..params.."'") +end) diff --git a/games/devtest/mods/experimental/detached.lua b/games/devtest/mods/experimental/detached.lua new file mode 100644 index 0000000..673adfd --- /dev/null +++ b/games/devtest/mods/experimental/detached.lua @@ -0,0 +1,29 @@ +-- Create a detached inventory +local inv = minetest.create_detached_inventory("test_inventory", { + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + experimental.print_to_everything("allow move asked") + return count -- Allow all + end, + allow_put = function(inv, listname, index, stack, player) + experimental.print_to_everything("allow put asked") + return 1 -- Allow only 1 + end, + allow_take = function(inv, listname, index, stack, player) + experimental.print_to_everything("allow take asked") + return 4 -- Allow 4 at max + end, + on_move = function(inv, from_list, from_index, to_list, to_index, count, player) + experimental.print_to_everything(player:get_player_name().." moved items") + end, + on_put = function(inv, listname, index, stack, player) + experimental.print_to_everything(player:get_player_name().." put items") + end, + on_take = function(inv, listname, index, stack, player) + experimental.print_to_everything(player:get_player_name().." took items") + end, +}) +inv:set_size("main", 4*6) +inv:add_item("main", "experimental:callback_node") +inv:add_item("main", "experimental:particle_spawner") + + diff --git a/games/devtest/mods/experimental/init.lua b/games/devtest/mods/experimental/init.lua new file mode 100644 index 0000000..b292f79 --- /dev/null +++ b/games/devtest/mods/experimental/init.lua @@ -0,0 +1,23 @@ +-- +-- Experimental things +-- + +experimental = {} + +dofile(minetest.get_modpath("experimental").."/detached.lua") +dofile(minetest.get_modpath("experimental").."/items.lua") +dofile(minetest.get_modpath("experimental").."/commands.lua") + +function experimental.print_to_everything(msg) + minetest.log("action", msg) + minetest.chat_send_all(msg) +end + +minetest.log("info", "[experimental] modname="..dump(minetest.get_current_modname())) +minetest.log("info", "[experimental] modpath="..dump(minetest.get_modpath("experimental"))) +minetest.log("info", "[experimental] worldpath="..dump(minetest.get_worldpath())) + + +minetest.register_on_mods_loaded(function() + minetest.log("action", "[experimental] on_mods_loaded()") +end) diff --git a/games/devtest/mods/experimental/items.lua b/games/devtest/mods/experimental/items.lua new file mode 100644 index 0000000..94be71c --- /dev/null +++ b/games/devtest/mods/experimental/items.lua @@ -0,0 +1,105 @@ +minetest.register_node("experimental:callback_node", { + description = "Callback Test Node (construct/destruct/timer)", + tiles = {"experimental_callback_node.png"}, + groups = {dig_immediate=3}, + -- This was known to cause a bug in minetest.item_place_node() when used + -- via minetest.place_node(), causing a placer with no position + paramtype2 = "facedir", + drop = "", + + on_construct = function(pos) + experimental.print_to_everything("experimental:callback_node:on_construct("..minetest.pos_to_string(pos)..")") + local meta = minetest.get_meta(pos) + meta:set_string("mine", "test") + local timer = minetest.get_node_timer(pos) + timer:start(4, 3) + end, + + after_place_node = function(pos, placer) + experimental.print_to_everything("experimental:callback_node:after_place_node("..minetest.pos_to_string(pos)..")") + local meta = minetest.get_meta(pos) + if meta:get_string("mine") == "test" then + experimental.print_to_everything("correct metadata found") + else + experimental.print_to_everything("incorrect metadata found") + end + end, + + on_destruct = function(pos) + experimental.print_to_everything("experimental:callback_node:on_destruct("..minetest.pos_to_string(pos)..")") + end, + + after_destruct = function(pos) + experimental.print_to_everything("experimental:callback_node:after_destruct("..minetest.pos_to_string(pos)..")") + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + experimental.print_to_everything("experimental:callback_node:after_dig_node("..minetest.pos_to_string(pos)..")") + end, + + on_timer = function(pos, elapsed) + experimental.print_to_everything("on_timer(): elapsed="..dump(elapsed)) + return true + end, +}) + +minetest.register_tool("experimental:privatizer", { + description = "Node Meta Privatizer".."\n".. + "Punch: Marks 'infotext' and 'formspec' meta fields of chest as private", + inventory_image = "experimental_tester_tool_1.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type == "node" then + local node = minetest.get_node(pointed_thing.under) + if node.name == "chest:chest" then + local p = pointed_thing.under + minetest.log("action", "Privatizer used at "..minetest.pos_to_string(p)) + minetest.get_meta(p):mark_as_private({"infotext", "formspec"}) + if user and user:is_player() then + minetest.chat_send_player(user:get_player_name(), "Chest metadata (infotext, formspec) set private!") + end + return + end + end + if user and user:is_player() then + minetest.chat_send_player(user:get_player_name(), "Privatizer can only be used on chest!") + end + end, +}) + +minetest.register_tool("experimental:particle_spawner", { + description = "Particle Spawner".."\n".. + "Punch: Spawn random test particle", + inventory_image = "experimental_tester_tool_1.png^[invert:g", + groups = { testtool = 1, disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + local pos = minetest.get_pointed_thing_position(pointed_thing, true) + if pos == nil then + if user then + pos = user:get_pos() + end + end + pos = vector.add(pos, {x=0, y=0.5, z=0}) + local tex, anim + if math.random(0, 1) == 0 then + tex = "experimental_particle_sheet.png" + anim = {type="sheet_2d", frames_w=3, frames_h=2, frame_length=0.5} + else + tex = "experimental_particle_vertical.png" + anim = {type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3} + end + + minetest.add_particle({ + pos = pos, + velocity = {x=0, y=0, z=0}, + acceleration = {x=0, y=0.04, z=0}, + expirationtime = 6, + collisiondetection = true, + texture = tex, + animation = anim, + size = 4, + glow = math.random(0, 5), + }) + end, +}) + diff --git a/games/devtest/mods/experimental/mod.conf b/games/devtest/mods/experimental/mod.conf new file mode 100644 index 0000000..cf0f9cb --- /dev/null +++ b/games/devtest/mods/experimental/mod.conf @@ -0,0 +1,2 @@ +name = experimental +description = Chaotic mod containing unstructured tests for testing out engine features. The features in this mod should be moved to other mods. diff --git a/games/devtest/mods/experimental/textures/experimental_callback_node.png b/games/devtest/mods/experimental/textures/experimental_callback_node.png new file mode 100644 index 0000000..e9d8743 Binary files /dev/null and b/games/devtest/mods/experimental/textures/experimental_callback_node.png differ diff --git a/games/devtest/mods/experimental/textures/experimental_particle_sheet.png b/games/devtest/mods/experimental/textures/experimental_particle_sheet.png new file mode 100644 index 0000000..6d70394 Binary files /dev/null and b/games/devtest/mods/experimental/textures/experimental_particle_sheet.png differ diff --git a/games/devtest/mods/experimental/textures/experimental_particle_vertical.png b/games/devtest/mods/experimental/textures/experimental_particle_vertical.png new file mode 100644 index 0000000..0320b75 Binary files /dev/null and b/games/devtest/mods/experimental/textures/experimental_particle_vertical.png differ diff --git a/games/devtest/mods/experimental/textures/experimental_tester_tool_1.png b/games/devtest/mods/experimental/textures/experimental_tester_tool_1.png new file mode 100644 index 0000000..5df416a Binary files /dev/null and b/games/devtest/mods/experimental/textures/experimental_tester_tool_1.png differ diff --git a/games/devtest/mods/give_initial_stuff/init.lua b/games/devtest/mods/give_initial_stuff/init.lua new file mode 100644 index 0000000..491a531 --- /dev/null +++ b/games/devtest/mods/give_initial_stuff/init.lua @@ -0,0 +1,37 @@ +local give_if_not_gotten_already = function(inv, list, item) + if not inv:contains_item(list, item) then + inv:add_item(list, item) + end +end + +local give_initial_stuff = function(player) + local inv = player:get_inventory() + give_if_not_gotten_already(inv, "main", "basetools:pick_mese") + give_if_not_gotten_already(inv, "main", "basetools:axe_steel") + give_if_not_gotten_already(inv, "main", "basetools:shovel_steel") + give_if_not_gotten_already(inv, "main", "bucket:bucket") + give_if_not_gotten_already(inv, "main", "testnodes:light14") + give_if_not_gotten_already(inv, "main", "chest_of_everything:chest") + minetest.log("action", "[give_initial_stuff] Giving initial stuff to "..player:get_player_name()) +end + +minetest.register_on_newplayer(function(player) + if minetest.settings:get_bool("give_initial_stuff", true) then + give_initial_stuff(player) + end +end) + +minetest.register_chatcommand("stuff", { + params = "", + privs = { give = true }, + description = "Give yourself initial items", + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player or not player:is_player() then + return false, "No player." + end + give_initial_stuff(player) + return true + end, +}) + diff --git a/games/devtest/mods/give_initial_stuff/mod.conf b/games/devtest/mods/give_initial_stuff/mod.conf new file mode 100644 index 0000000..1ba49f5 --- /dev/null +++ b/games/devtest/mods/give_initial_stuff/mod.conf @@ -0,0 +1,3 @@ +name = give_initial_stuff +description = Gives items to players on join +depends = basetools, bucket, chest_of_everything, testnodes diff --git a/games/devtest/mods/initial_message/init.lua b/games/devtest/mods/initial_message/init.lua new file mode 100644 index 0000000..59e9f5f --- /dev/null +++ b/games/devtest/mods/initial_message/init.lua @@ -0,0 +1,9 @@ +minetest.register_on_joinplayer(function(player) + local cb = function(player) + if not player or not player:is_player() then + return + end + minetest.chat_send_player(player:get_player_name(), "This is the \"Development Test\" [devtest], meant only for testing and development. Use Minetest Game for the real thing.") + end + minetest.after(2.0, cb, player) +end) diff --git a/games/devtest/mods/initial_message/mod.conf b/games/devtest/mods/initial_message/mod.conf new file mode 100644 index 0000000..32aa2ac --- /dev/null +++ b/games/devtest/mods/initial_message/mod.conf @@ -0,0 +1,2 @@ +name = initial_message +description = Show message to joining players explaining what this testing game is about diff --git a/games/devtest/mods/mapgen/init.lua b/games/devtest/mods/mapgen/init.lua new file mode 100644 index 0000000..a5f9128 --- /dev/null +++ b/games/devtest/mods/mapgen/init.lua @@ -0,0 +1,104 @@ +-- +-- Aliases for map generator outputs +-- + +-- ESSENTIAL node aliases +-- Basic nodes +minetest.register_alias("mapgen_stone", "basenodes:stone") +minetest.register_alias("mapgen_water_source", "basenodes:water_source") +minetest.register_alias("mapgen_river_water_source", "basenodes:river_water_source") + +-- Additional essential aliases for v6 +minetest.register_alias("mapgen_lava_source", "basenodes:lava_source") +minetest.register_alias("mapgen_dirt", "basenodes:dirt") +minetest.register_alias("mapgen_dirt_with_grass", "basenodes:dirt_with_grass") +minetest.register_alias("mapgen_sand", "basenodes:sand") +minetest.register_alias("mapgen_tree", "basenodes:tree") +minetest.register_alias("mapgen_leaves", "basenodes:leaves") +minetest.register_alias("mapgen_apple", "basenodes:apple") + +-- Essential alias for dungeons +minetest.register_alias("mapgen_cobble", "basenodes:cobble") + +-- Optional aliases for v6 (they all have fallback values in the engine) +if minetest.settings:get_bool("devtest_v6_mapgen_aliases", false) then + minetest.register_alias("mapgen_gravel", "basenodes:gravel") + minetest.register_alias("mapgen_desert_stone", "basenodes:desert_stone") + minetest.register_alias("mapgen_desert_sand", "basenodes:desert_sand") + minetest.register_alias("mapgen_dirt_with_snow", "basenodes:dirt_with_snow") + minetest.register_alias("mapgen_snowblock", "basenodes:snowblock") + minetest.register_alias("mapgen_snow", "basenodes:snow") + minetest.register_alias("mapgen_ice", "basenodes:ice") + minetest.register_alias("mapgen_junglegrass", "basenodes:junglegrass") + minetest.register_alias("mapgen_jungletree", "basenodes:jungletree") + minetest.register_alias("mapgen_jungleleaves", "basenodes:jungleleaves") + minetest.register_alias("mapgen_pine_tree", "basenodes:pine_tree") + minetest.register_alias("mapgen_pine_needles", "basenodes:pine_needles") +end +-- Optional alias for mossycobble (should fall back to cobble) +if minetest.settings:get_bool("devtest_dungeon_mossycobble", false) then + minetest.register_alias("mapgen_mossycobble", "basenodes:mossycobble") +end +-- Optional aliases for dungeon stairs (should fall back to full nodes) +if minetest.settings:get_bool("devtest_dungeon_stairs", false) then + minetest.register_alias("mapgen_stair_cobble", "stairs:stair_cobble") + if minetest.settings:get_bool("devtest_v6_mapgen_aliases", false) then + minetest.register_alias("mapgen_stair_desert_stone", "stairs:stair_desert_stone") + end +end + +-- +-- Register biomes for biome API +-- + +minetest.clear_registered_biomes() +minetest.clear_registered_decorations() + +if minetest.settings:get_bool("devtest_register_biomes", true) then + minetest.register_biome({ + name = "mapgen:grassland", + node_top = "basenodes:dirt_with_grass", + depth_top = 1, + node_filler = "basenodes:dirt", + depth_filler = 1, + node_riverbed = "basenodes:sand", + depth_riverbed = 2, + node_dungeon = "basenodes:cobble", + node_dungeon_alt = "basenodes:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 4, + heat_point = 50, + humidity_point = 50, + }) + + minetest.register_biome({ + name = "mapgen:grassland_ocean", + node_top = "basenodes:sand", + depth_top = 1, + node_filler = "basenodes:sand", + depth_filler = 3, + node_riverbed = "basenodes:sand", + depth_riverbed = 2, + node_cave_liquid = "basenodes:water_source", + node_dungeon = "basenodes:cobble", + node_dungeon_alt = "basenodes:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 3, + y_min = -255, + heat_point = 50, + humidity_point = 50, + }) + + minetest.register_biome({ + name = "mapgen:grassland_under", + node_cave_liquid = {"basenodes:water_source", "basenodes:lava_source"}, + node_dungeon = "basenodes:cobble", + node_dungeon_alt = "basenodes:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 50, + humidity_point = 50, + }) +end diff --git a/games/devtest/mods/mapgen/mod.conf b/games/devtest/mods/mapgen/mod.conf new file mode 100644 index 0000000..15750cc --- /dev/null +++ b/games/devtest/mods/mapgen/mod.conf @@ -0,0 +1,3 @@ +name = mapgen +description = Minimal map generator +depends = basenodes diff --git a/games/devtest/mods/modchannels/init.lua b/games/devtest/mods/modchannels/init.lua new file mode 100644 index 0000000..ee925f0 --- /dev/null +++ b/games/devtest/mods/modchannels/init.lua @@ -0,0 +1,14 @@ +-- +-- Mod channels experimental handlers +-- +local mod_channel = minetest.mod_channel_join("experimental_preview") + +minetest.register_on_modchannel_message(function(channel, sender, message) + minetest.log("action", "[modchannels] Server received message `" .. message + .. "` on channel `" .. channel .. "` from sender `" .. sender .. "`") + + if mod_channel:is_writeable() then + mod_channel:send_all("experimental answers to preview") + mod_channel:leave() + end +end) diff --git a/games/devtest/mods/modchannels/mod.conf b/games/devtest/mods/modchannels/mod.conf new file mode 100644 index 0000000..7c13aad --- /dev/null +++ b/games/devtest/mods/modchannels/mod.conf @@ -0,0 +1,2 @@ +name = modchannels +description = Add experimental mod channel handlers diff --git a/games/devtest/mods/soundstuff/init.lua b/games/devtest/mods/soundstuff/init.lua new file mode 100644 index 0000000..b263a3f --- /dev/null +++ b/games/devtest/mods/soundstuff/init.lua @@ -0,0 +1,174 @@ +local simple_nodes = { + footstep = { "Footstep Sound Node", "soundstuff_node_footstep.png" }, + dig = { "Dig Sound Node", "soundstuff_node_dig.png" }, + dug = { "Dug Sound Node", "soundstuff_node_dug.png" }, + place = { "Place Sound Node", "soundstuff_node_place.png" }, + place_failed = { "Place Failed Sound Node", "soundstuff_node_place_failed.png" }, +} + +for k,v in pairs(simple_nodes) do + minetest.register_node("soundstuff:"..k, { + description = v[1], + tiles = {"soundstuff_node_sound.png","soundstuff_node_sound.png",v[2]}, + groups = {dig_immediate=2}, + sounds = { + [k] = { name = "soundstuff_mono", gain = 1.0 }, + } + }) +end + +minetest.register_node("soundstuff:place_failed_attached", { + description = "Attached Place Failed Sound Node", + tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_place_failed.png"}, + groups = {dig_immediate=2, attached_node=1}, + drawtype = "nodebox", + paramtype = "light", + node_box = { type = "fixed", fixed = { + { -7/16, -7/16, -7/16, 7/16, 7/16, 7/16 }, + { -0.5, -0.5, -0.5, 0.5, -7/16, 0.5 }, + }}, + sounds = { + place_failed = { name = "soundstuff_mono", gain = 1.0 }, + }, +}) + +minetest.register_node("soundstuff:fall", { + description = "Fall Sound Node", + tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_fall.png"}, + groups = {dig_immediate=2, falling_node=1}, + sounds = { + fall = { name = "soundstuff_mono", gain = 1.0 }, + } +}) + +minetest.register_node("soundstuff:fall_attached", { + description = "Attached Fall Sound Node", + tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_fall.png"}, + groups = {dig_immediate=2, attached_node=1}, + drawtype = "nodebox", + paramtype = "light", + node_box = { type = "fixed", fixed = { + { -7/16, -7/16, -7/16, 7/16, 7/16, 7/16 }, + { -0.5, -0.5, -0.5, 0.5, -7/16, 0.5 }, + }}, + sounds = { + fall = { name = "soundstuff_mono", gain = 1.0 }, + } +}) + +minetest.register_node("soundstuff:footstep_liquid", { + description = "Liquid Footstep Sound Node", + drawtype = "liquid", + tiles = { + "soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190", + }, + special_tiles = { + {name = "soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190", + backface_culling = false}, + {name = "soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190", + backface_culling = true}, + }, + liquids_pointable = true, + liquidtype = "source", + liquid_alternative_flowing = "soundstuff:footstep_liquid", + liquid_alternative_source = "soundstuff:footstep_liquid", + liquid_renewable = false, + liquid_range = 0, + liquid_viscosity = 0, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + post_effect_color = {a = 64, r = 0, g = 0, b = 200}, + sounds = { + footstep = { name = "soundstuff_mono", gain = 1.0 }, + } +}) + +minetest.register_node("soundstuff:footstep_climbable", { + description = "Climbable Footstep Sound Node", + drawtype = "allfaces", + tiles = { + "soundstuff_node_climbable.png", + }, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + climbable = true, + is_ground_content = false, + groups = { dig_immediate = 2 }, + sounds = { + footstep = { name = "soundstuff_mono", gain = 1.0 }, + } +}) + + + +minetest.register_craftitem("soundstuff:eat", { + description = "Eat Sound Item".."\n".. + "Makes a sound when 'eaten' (with punch key)", + inventory_image = "soundstuff_eat.png", + on_use = minetest.item_eat(0), + sound = { + eat = { name = "soundstuff_mono", gain = 1.0 }, + } +}) + +minetest.register_tool("soundstuff:breaks", { + description = "Break Sound Tool".."\n".. + "Digs cracky=3 and more".."\n".. + "Makes a sound when it breaks", + inventory_image = "soundstuff_node_dug.png", + sound = { + breaks = { name = "soundstuff_mono", gain = 1.0 }, + }, + tool_capabilities = { + max_drop_level=0, + groupcaps={ + cracky={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0}, + choppy={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0}, + snappy={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0}, + crumbly={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0}, + }, + }, +}) + +-- Plays sound repeatedly +minetest.register_node("soundstuff:positional", { + description = "Positional Sound Node", + on_construct = function(pos) + local timer = minetest.get_node_timer(pos) + timer:start(0) + end, + on_timer = function(pos, elapsed) + local node = minetest.get_node(pos) + local dist = node.param2 + if dist == 0 then + dist = nil + end + minetest.sound_play("soundstuff_mono", { pos = pos, max_hear_distance = dist }) + local timer = minetest.get_node_timer(pos) + timer:start(0.7) + end, + on_rightclick = function(pos, node, clicker) + node.param2 = (node.param2 + 1) % 64 + minetest.set_node(pos, node) + if clicker and clicker:is_player() then + local dist = node.param2 + local diststr + if dist == 0 then + diststr = "<default>" + else + diststr = tostring(dist) + end + minetest.chat_send_player(clicker:get_player_name(), "max_hear_distance = " .. diststr) + end + end, + + groups = { dig_immediate = 2 }, + tiles = { "soundstuff_node_sound.png" }, +}) + diff --git a/games/devtest/mods/soundstuff/mod.conf b/games/devtest/mods/soundstuff/mod.conf new file mode 100644 index 0000000..2c631e2 --- /dev/null +++ b/games/devtest/mods/soundstuff/mod.conf @@ -0,0 +1,2 @@ +name = soundstuff +description = Example items and nodes for testing sound effects diff --git a/games/devtest/mods/soundstuff/sounds/soundstuff_mono.ogg b/games/devtest/mods/soundstuff/sounds/soundstuff_mono.ogg new file mode 100644 index 0000000..43428d5 Binary files /dev/null and b/games/devtest/mods/soundstuff/sounds/soundstuff_mono.ogg differ diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_eat.png b/games/devtest/mods/soundstuff/textures/soundstuff_eat.png new file mode 100644 index 0000000..aed2054 Binary files /dev/null and b/games/devtest/mods/soundstuff/textures/soundstuff_eat.png differ diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_blank.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_blank.png new file mode 100644 index 0000000..4dffacc Binary files /dev/null and b/games/devtest/mods/soundstuff/textures/soundstuff_node_blank.png differ diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_climbable.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_climbable.png new file mode 100644 index 0000000..3888f79 Binary files /dev/null and b/games/devtest/mods/soundstuff/textures/soundstuff_node_climbable.png differ diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_dig.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_dig.png new file mode 100644 index 0000000..67ba111 Binary files /dev/null and b/games/devtest/mods/soundstuff/textures/soundstuff_node_dig.png differ diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_dug.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_dug.png new file mode 100644 index 0000000..bab5fbe Binary files /dev/null and b/games/devtest/mods/soundstuff/textures/soundstuff_node_dug.png differ diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_fall.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_fall.png new file mode 100644 index 0000000..17b14f1 Binary files /dev/null and b/games/devtest/mods/soundstuff/textures/soundstuff_node_fall.png differ diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_footstep.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_footstep.png new file mode 100644 index 0000000..6367ae9 Binary files /dev/null and b/games/devtest/mods/soundstuff/textures/soundstuff_node_footstep.png differ diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_place.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_place.png new file mode 100644 index 0000000..d159ad5 Binary files /dev/null and b/games/devtest/mods/soundstuff/textures/soundstuff_node_place.png differ diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_place_failed.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_place_failed.png new file mode 100644 index 0000000..780ba94 Binary files /dev/null and b/games/devtest/mods/soundstuff/textures/soundstuff_node_place_failed.png differ diff --git a/games/devtest/mods/soundstuff/textures/soundstuff_node_sound.png b/games/devtest/mods/soundstuff/textures/soundstuff_node_sound.png new file mode 100644 index 0000000..0592a02 Binary files /dev/null and b/games/devtest/mods/soundstuff/textures/soundstuff_node_sound.png differ diff --git a/games/devtest/mods/stairs/init.lua b/games/devtest/mods/stairs/init.lua new file mode 100644 index 0000000..2701cab --- /dev/null +++ b/games/devtest/mods/stairs/init.lua @@ -0,0 +1,65 @@ +stairs = {} + +-- Node will be called stairs:stair_<subname> +function stairs.register_stair(subname, recipeitem, groups, images, description) + minetest.register_node(":stairs:stair_" .. subname, { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = true, + groups = groups, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + }) +end + +-- Node will be called stairs:slab_<subname> +function stairs.register_slab(subname, recipeitem, groups, images, description) + minetest.register_node(":stairs:slab_" .. subname, { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + is_ground_content = true, + groups = groups, + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + }) +end + +-- Nodes will be called stairs:{stair,slab}_<subname> +function stairs.register_stair_and_slab(subname, recipeitem, groups, images, desc_stair, desc_slab) + stairs.register_stair(subname, recipeitem, groups, images, desc_stair) + stairs.register_slab(subname, recipeitem, groups, images, desc_slab) +end + +stairs.register_stair_and_slab("stone", "basenodes:stone", + {cracky=3}, + {"default_stone.png"}, + "Stone Stair", + "Stone Slab") + +stairs.register_stair_and_slab("desert_stone", "basenodes:desert_stone", + {cracky=3}, + {"default_desert_stone.png"}, + "Desert Stone Stair", + "Desert Stone Slab") + +stairs.register_stair_and_slab("cobble", "basenodes:cobble", + {cracky=3}, + {"default_cobble.png"}, + "Cobblestone Stair", + "Cobblestone Slab") diff --git a/games/devtest/mods/stairs/mod.conf b/games/devtest/mods/stairs/mod.conf new file mode 100644 index 0000000..724bff8 --- /dev/null +++ b/games/devtest/mods/stairs/mod.conf @@ -0,0 +1,3 @@ +name = stairs +description = Adds stairs and slabs +depends = basenodes diff --git a/games/devtest/mods/testentities/armor.lua b/games/devtest/mods/testentities/armor.lua new file mode 100644 index 0000000..415e5bd --- /dev/null +++ b/games/devtest/mods/testentities/armor.lua @@ -0,0 +1,61 @@ +-- Armorball: Test entity for testing armor groups +-- Rightclick to change armor group + +local phasearmor = { + [0]={icy=100}, + [1]={fiery=100}, + [2]={icy=100, fiery=100}, + [3]={fleshy=-100}, + [4]={fleshy=1}, + [5]={fleshy=10}, + [6]={fleshy=50}, + [7]={fleshy=100}, + [8]={fleshy=200}, + [9]={fleshy=1000}, + [10]={fleshy=32767}, + [11]={immortal=1}, + [12]={punch_operable=1}, +} +local max_phase = 12 + +minetest.register_entity("testentities:armorball", { + initial_properties = { + hp_max = 20, + physical = false, + collisionbox = {-0.4,-0.4,-0.4, 0.4,0.4,0.4}, + visual = "sprite", + visual_size = {x=1, y=1}, + textures = {"testentities_armorball.png"}, + spritediv = {x=1, y=max_phase+1}, + initial_sprite_basepos = {x=0, y=0}, + }, + + _phase = 7, + + on_activate = function(self, staticdata) + minetest.log("action", "[testentities] armorball.on_activate") + self.object:set_armor_groups(phasearmor[self._phase]) + self.object:set_sprite({x=0, y=self._phase}) + end, + + on_rightclick = function(self, clicker) + -- Change armor group and sprite + self._phase = self._phase + 1 + if self._phase >= max_phase + 1 then + self._phase = 0 + end + self.object:set_sprite({x=0, y=self._phase}) + self.object:set_armor_groups(phasearmor[self._phase]) + end, + + on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) + if not puncher then + return + end + local name = puncher:get_player_name() + if not name then + return + end + minetest.chat_send_player(name, "time_from_last_punch="..string.format("%.3f", time_from_last_punch).."; damage="..tostring(damage)) + end, +}) diff --git a/games/devtest/mods/testentities/callbacks.lua b/games/devtest/mods/testentities/callbacks.lua new file mode 100644 index 0000000..a212fbf --- /dev/null +++ b/games/devtest/mods/testentities/callbacks.lua @@ -0,0 +1,78 @@ +-- Entities that test their callbacks + +local message = function(msg) + minetest.log("action", msg) + minetest.chat_send_all(msg) +end + +local get_object_name = function(obj) + local name = "<nil>" + if obj then + if obj:is_player() then + name = obj:get_player_name() + else + name = "<entity>" + end + end + return name +end + +local spos = function(self) + return minetest.pos_to_string(vector.round(self.object:get_pos())) +end + +-- Callback test entity (all callbacks except on_step) +minetest.register_entity("testentities:callback", { + initial_properties = { + visual = "upright_sprite", + textures = { "testentities_callback.png" }, + }, + + on_activate = function(self, staticdata, dtime_s) + message("Callback entity: on_activate! pos="..spos(self).."; dtime_s="..dtime_s) + end, + on_deactivate = function(self, removal) + message("Callback entity: on_deactivate! pos="..spos(self) .. "; removal=" .. tostring(removal)) + end, + on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) + local name = get_object_name(puncher) + message( + "Callback entity: on_punch! ".. + "pos="..spos(self).."; puncher="..name.."; ".. + "time_from_last_punch="..time_from_last_punch.."; ".. + "tool_capabilities="..tostring(dump(tool_capabilities)).."; ".. + "dir="..tostring(dump(dir)).."; damage="..damage) + end, + on_rightclick = function(self, clicker) + local name = get_object_name(clicker) + message("Callback entity: on_rightclick! pos="..spos(self).."; clicker="..name) + end, + on_death = function(self, killer) + local name = get_object_name(killer) + message("Callback entity: on_death! pos="..spos(self).."; killer="..name) + end, + on_attach_child = function(self, child) + local name = get_object_name(child) + message("Callback entity: on_attach_child! pos="..spos(self).."; child="..name) + end, + on_detach_child = function(self, child) + local name = get_object_name(child) + message("Callback entity: on_detach_child! pos="..spos(self).."; child="..name) + end, + on_detach = function(self, parent) + local name = get_object_name(parent) + message("Callback entity: on_detach! pos="..spos(self).."; parent="..name) + end, + get_staticdata = function(self) + message("Callback entity: get_staticdata! pos="..spos(self)) + end, +}) + +-- Only test on_step callback +minetest.register_entity("testentities:callback_step", { + visual = "upright_sprite", + textures = { "testentities_callback_step.png" }, + on_step = function(self, dtime) + message("on_step callback entity: on_step! pos="..spos(self).."; dtime="..dtime) + end, +}) diff --git a/games/devtest/mods/testentities/init.lua b/games/devtest/mods/testentities/init.lua new file mode 100644 index 0000000..df8c72e --- /dev/null +++ b/games/devtest/mods/testentities/init.lua @@ -0,0 +1,3 @@ +dofile(minetest.get_modpath("testentities").."/visuals.lua") +dofile(minetest.get_modpath("testentities").."/armor.lua") +dofile(minetest.get_modpath("testentities").."/callbacks.lua") diff --git a/games/devtest/mods/testentities/mod.conf b/games/devtest/mods/testentities/mod.conf new file mode 100644 index 0000000..7a8cb5a --- /dev/null +++ b/games/devtest/mods/testentities/mod.conf @@ -0,0 +1,2 @@ +name = testentities +description = Example entities for testing diff --git a/games/devtest/mods/testentities/textures/testentities_armorball.png b/games/devtest/mods/testentities/textures/testentities_armorball.png new file mode 100644 index 0000000..708c7b3 Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_armorball.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_callback.png b/games/devtest/mods/testentities/textures/testentities_callback.png new file mode 100644 index 0000000..c4c9066 Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_callback.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_callback_step.png b/games/devtest/mods/testentities/textures/testentities_callback_step.png new file mode 100644 index 0000000..b67506a Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_callback_step.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_cube1.png b/games/devtest/mods/testentities/textures/testentities_cube1.png new file mode 100644 index 0000000..c667e42 Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_cube1.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_cube2.png b/games/devtest/mods/testentities/textures/testentities_cube2.png new file mode 100644 index 0000000..4818234 Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_cube2.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_cube3.png b/games/devtest/mods/testentities/textures/testentities_cube3.png new file mode 100644 index 0000000..03b5daa Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_cube3.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_cube4.png b/games/devtest/mods/testentities/textures/testentities_cube4.png new file mode 100644 index 0000000..6392048 Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_cube4.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_cube5.png b/games/devtest/mods/testentities/textures/testentities_cube5.png new file mode 100644 index 0000000..d8acdf0 Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_cube5.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_cube6.png b/games/devtest/mods/testentities/textures/testentities_cube6.png new file mode 100644 index 0000000..5f81a64 Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_cube6.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_dungeon_master.png b/games/devtest/mods/testentities/textures/testentities_dungeon_master.png new file mode 100644 index 0000000..1e31077 Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_dungeon_master.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_sprite.png b/games/devtest/mods/testentities/textures/testentities_sprite.png new file mode 100644 index 0000000..a4b0196 Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_sprite.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_upright_sprite1.png b/games/devtest/mods/testentities/textures/testentities_upright_sprite1.png new file mode 100644 index 0000000..6242511 Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_upright_sprite1.png differ diff --git a/games/devtest/mods/testentities/textures/testentities_upright_sprite2.png b/games/devtest/mods/testentities/textures/testentities_upright_sprite2.png new file mode 100644 index 0000000..a79a760 Binary files /dev/null and b/games/devtest/mods/testentities/textures/testentities_upright_sprite2.png differ diff --git a/games/devtest/mods/testentities/visuals.lua b/games/devtest/mods/testentities/visuals.lua new file mode 100644 index 0000000..e382ec4 --- /dev/null +++ b/games/devtest/mods/testentities/visuals.lua @@ -0,0 +1,137 @@ +-- Minimal test entities to test visuals + +minetest.register_entity("testentities:sprite", { + initial_properties = { + visual = "sprite", + textures = { "testentities_sprite.png" }, + }, +}) + +minetest.register_entity("testentities:upright_sprite", { + initial_properties = { + visual = "upright_sprite", + textures = { + "testentities_upright_sprite1.png", + "testentities_upright_sprite2.png", + }, + }, +}) + +minetest.register_entity("testentities:cube", { + initial_properties = { + visual = "cube", + textures = { + "testentities_cube1.png", + "testentities_cube2.png", + "testentities_cube3.png", + "testentities_cube4.png", + "testentities_cube5.png", + "testentities_cube6.png", + }, + }, +}) + +minetest.register_entity("testentities:item", { + initial_properties = { + visual = "item", + wield_item = "testnodes:normal", + }, +}) + +minetest.register_entity("testentities:wielditem", { + initial_properties = { + visual = "wielditem", + wield_item = "testnodes:normal", + }, +}) + +minetest.register_entity("testentities:mesh", { + initial_properties = { + visual = "mesh", + mesh = "testnodes_pyramid.obj", + textures = { + "testnodes_mesh_stripes2.png" + }, + }, +}) + +minetest.register_entity("testentities:mesh_unshaded", { + initial_properties = { + visual = "mesh", + mesh = "testnodes_pyramid.obj", + textures = { + "testnodes_mesh_stripes2.png" + }, + shaded = false, + }, +}) + +-- Advanced visual tests + +-- An entity for testing animated and yaw-modulated sprites +minetest.register_entity("testentities:yawsprite", { + initial_properties = { + selectionbox = {-0.3, -0.5, -0.3, 0.3, 0.3, 0.3}, + visual = "sprite", + visual_size = {x=0.6666, y=1}, + textures = {"testentities_dungeon_master.png^[makealpha:128,0,0^[makealpha:128,128,0"}, + spritediv = {x=6, y=5}, + initial_sprite_basepos = {x=0, y=0}, + }, + on_activate = function(self, staticdata) + self.object:set_sprite({x=0, y=0}, 3, 0.5, true) + end, +}) + +-- An entity for testing animated upright sprites +minetest.register_entity("testentities:upright_animated", { + initial_properties = { + visual = "upright_sprite", + textures = {"testnodes_anim.png"}, + spritediv = {x = 1, y = 4}, + }, + on_activate = function(self) + self.object:set_sprite({x=0, y=0}, 4, 1.0, false) + end, +}) + +minetest.register_entity("testentities:nametag", { + initial_properties = { + visual = "sprite", + textures = { "testentities_sprite.png" }, + }, + + on_activate = function(self, staticdata) + if staticdata ~= "" then + local data = minetest.deserialize(staticdata) + self.color = data.color + self.bgcolor = data.bgcolor + else + self.color = { + r = math.random(0, 255), + g = math.random(0, 255), + b = math.random(0, 255), + } + + if math.random(0, 10) > 5 then + self.bgcolor = { + r = math.random(0, 255), + g = math.random(0, 255), + b = math.random(0, 255), + a = math.random(0, 255), + } + end + end + + assert(self.color) + self.object:set_properties({ + nametag = tostring(math.random(1000, 10000)), + nametag_color = self.color, + nametag_bgcolor = self.bgcolor, + }) + end, + + get_staticdata = function(self) + return minetest.serialize({ color = self.color, bgcolor = self.bgcolor }) + end, +}) diff --git a/games/devtest/mods/testfood/init.lua b/games/devtest/mods/testfood/init.lua new file mode 100644 index 0000000..39b1213 --- /dev/null +++ b/games/devtest/mods/testfood/init.lua @@ -0,0 +1,31 @@ +local S = minetest.get_translator("testfood") + +minetest.register_craftitem("testfood:good1", { + description = S("Good Food (+1)"), + inventory_image = "testfood_good.png", + on_use = minetest.item_eat(1), +}) +minetest.register_craftitem("testfood:good5", { + description = S("Good Food (+5)"), + inventory_image = "testfood_good2.png", + on_use = minetest.item_eat(5), +}) + +minetest.register_craftitem("testfood:bad1", { + description = S("Bad Food (-1)"), + inventory_image = "testfood_bad.png", + on_use = minetest.item_eat(-1), +}) +minetest.register_craftitem("testfood:bad5", { + description = S("Bad Food (-5)"), + inventory_image = "testfood_bad2.png", + on_use = minetest.item_eat(-5), +}) + +minetest.register_craftitem("testfood:replace1", { + description = S("Replacing Food (+1)").."\n".. + S("Replaced with 'Good Food (+1)' when eaten"), + inventory_image = "testfood_replace.png", + on_use = minetest.item_eat(1, "testfood:good1"), +}) + diff --git a/games/devtest/mods/testfood/mod.conf b/games/devtest/mods/testfood/mod.conf new file mode 100644 index 0000000..7bff21b --- /dev/null +++ b/games/devtest/mods/testfood/mod.conf @@ -0,0 +1,2 @@ +name = testfood +description = For testing food items diff --git a/games/devtest/mods/testfood/textures/testfood_bad.png b/games/devtest/mods/testfood/textures/testfood_bad.png new file mode 100644 index 0000000..6e92514 Binary files /dev/null and b/games/devtest/mods/testfood/textures/testfood_bad.png differ diff --git a/games/devtest/mods/testfood/textures/testfood_bad2.png b/games/devtest/mods/testfood/textures/testfood_bad2.png new file mode 100644 index 0000000..22b5678 Binary files /dev/null and b/games/devtest/mods/testfood/textures/testfood_bad2.png differ diff --git a/games/devtest/mods/testfood/textures/testfood_good.png b/games/devtest/mods/testfood/textures/testfood_good.png new file mode 100644 index 0000000..31df7f5 Binary files /dev/null and b/games/devtest/mods/testfood/textures/testfood_good.png differ diff --git a/games/devtest/mods/testfood/textures/testfood_good2.png b/games/devtest/mods/testfood/textures/testfood_good2.png new file mode 100644 index 0000000..e43dda2 Binary files /dev/null and b/games/devtest/mods/testfood/textures/testfood_good2.png differ diff --git a/games/devtest/mods/testfood/textures/testfood_replace.png b/games/devtest/mods/testfood/textures/testfood_replace.png new file mode 100644 index 0000000..1ef6876 Binary files /dev/null and b/games/devtest/mods/testfood/textures/testfood_replace.png differ diff --git a/games/devtest/mods/testformspec/LICENSE.txt b/games/devtest/mods/testformspec/LICENSE.txt new file mode 100644 index 0000000..07696cc --- /dev/null +++ b/games/devtest/mods/testformspec/LICENSE.txt @@ -0,0 +1,14 @@ +License of media files +---------------------- +Content imported from minetest_game. + + +BlockMen (CC BY-SA 3.0) + default_chest_front.png + default_chest_lock.png + default_chest_side.png + default_chest_top.png + +stujones11 (CC BY-SA 3.0) +An0n3m0us (CC BY-SA 3.0) + testformspec_character.b3d diff --git a/games/devtest/mods/testformspec/callbacks.lua b/games/devtest/mods/testformspec/callbacks.lua new file mode 100644 index 0000000..5593805 --- /dev/null +++ b/games/devtest/mods/testformspec/callbacks.lua @@ -0,0 +1,51 @@ +local callback_test = 0 + +local out = function(player, formname, fields, number) + local snum = "" + if number then + snum = " "..number + end + local msg = "Formspec callback"..snum..": player="..player:get_player_name()..", formname=\""..tostring(formname).."\", fields="..dump(fields) + minetest.chat_send_player(player:get_player_name(), msg) + minetest.log("action", msg) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if callback_test == 1 then + out(player, formname, fields) + elseif callback_test == 2 then + out(player, formname, fields, 1) + end +end) +minetest.register_on_player_receive_fields(function(player, formname, fields) + if callback_test == 2 then + out(player, formname, fields, 2) + return true -- Disable the first callback + end +end) +minetest.register_on_player_receive_fields(function(player, formname, fields) + if callback_test == 2 then + out(player, formname, fields, 3) + end +end) + +minetest.register_chatcommand("test_formspec_callbacks", { + params = "[ 0 | 1 | 2 ]", + description = "Test: Change formspec callbacks testing mode", + func = function(name, param) + local mode = tonumber(param) + if not mode then + callback_test = (callback_test + 1 % 3) + else + callback_test = mode + end + if callback_test == 1 then + minetest.chat_send_player(name, "Formspec callback test mode 1 enabled: Logging only") + elseif callback_test == 2 then + minetest.chat_send_player(name, "Formspec callback test mode 2 enabled: Three callbacks, disable pre-registered callbacks") + else + callback_test = 0 + minetest.chat_send_player(name, "Formspec callback test disabled!") + end + end +}) diff --git a/games/devtest/mods/testformspec/dummy_items.lua b/games/devtest/mods/testformspec/dummy_items.lua new file mode 100644 index 0000000..2037ae9 --- /dev/null +++ b/games/devtest/mods/testformspec/dummy_items.lua @@ -0,0 +1,14 @@ +-- This code adds dummy items that are supposed to be used in formspecs +-- for testing item_image formspec elements. + +minetest.register_node("testformspec:node", { + description = "Formspec Test Node", + tiles = { "testformspec_node.png" }, + groups = { dig_immediate = 3, dummy = 1 }, +}) + +minetest.register_craftitem("testformspec:item", { + description = "Formspec Test Item", + inventory_image = "testformspec_item.png", + groups = { dummy = 1 }, +}) diff --git a/games/devtest/mods/testformspec/formspec.lua b/games/devtest/mods/testformspec/formspec.lua new file mode 100644 index 0000000..5f1f897 --- /dev/null +++ b/games/devtest/mods/testformspec/formspec.lua @@ -0,0 +1,536 @@ +local color = minetest.colorize + +local clip_fs = [[ + style_type[label,button,image_button,item_image_button, + tabheader,scrollbar,table,animated_image + ,field,textarea,checkbox,dropdown;noclip=%c] + + label[0,0;A clipping test] + button[0,1;3,0.8;clip_button;A clipping test] + image_button[0,2;3,0.8;testformspec_button_image.png;clip_image_button;A clipping test] + item_image_button[0,3;3,0.8;testformspec:item;clip_item_image_button;A clipping test] + tabheader[0,4.7;3,0.63;clip_tabheader;Clip,Test,Text,Tabs;1;false;false] + field[0,5;3,0.8;clip_field;Title;] + textarea[0,6;3,1;clip_textarea;Title;] + checkbox[0,7.5;clip_checkbox;This is a test;true] + dropdown[0,8;3,0.8;clip_dropdown;Select An Item,One,Two,Three,Four,Five;1] + scrollbar[0,9;3,0.8;horizontal;clip_scrollbar;3] + tablecolumns[text;text] + table[0,10;3,1;clip_table;one,two,three,four;1] + animated_image[-0.5,11;4.5,1;clip_animated_image;testformspec_animation.png;4;100] +]] + +local tabheaders_fs = [[ + tabheader[0,0;10,0.63;tabs_opaque;Opaque,Without,Border;1;false;false] + tabheader[0,1;10,0.63;tabs_opaque_border;Opaque,With,Border;1;false;true] + tabheader[0,2;10,0.63;tabs_transparent;Transparent,Without,Border;1;true;false] + tabheader[0,3;10,0.63;tabs_transparent_border;Transparent,With,Border;1;true;true] + tabheader[0,4;tabs_default;Default,Tabs;1] + tabheader[0,6;10,0.5;tabs_size1;Height=0.5;1;false;false] + tabheader[2,6;10,0.75;tabs_size1;Height=0.75;1;false;false] + tabheader[4,6;10,1;tabs_size2;Height=1;1;false;false] + tabheader[6,6;10,1.25;tabs_size2;Height=1.25;1;false;false] + tabheader[8,6;10,1.5;tabs_size2;Height=1.5;1;false;false] +]] + +local inv_style_fs = [[ + style_type[list;noclip=true] + list[current_player;main;-0.75,0.75;2,2] + + real_coordinates[false] + list[current_player;main;1.5,0;3,2] + real_coordinates[true] + + real_coordinates[false] + style_type[list;size=1.1;spacing=0.1] + list[current_player;main;5,0;3,2] + real_coordinates[true] + + style_type[list;size=.001;spacing=0] + list[current_player;main;7,3.5;8,4] + + box[3,3.5;1,1;#000000] + box[5,3.5;1,1;#000000] + box[4,4.5;1,1;#000000] + box[3,5.5;1,1;#000000] + box[5,5.5;1,1;#000000] + style_type[list;spacing=.25,.125;size=.75,.875] + list[current_player;main;3,3.5;3,3] + + style_type[list;spacing=0;size=1.1] + list[current_player;main;.5,7;8,4] +]] + +local hypertext_basic = [[ +<bigger>Normal test</bigger> +This is a normal text. + +<bigger><mono>style</mono> test</bigger> +<style color=#FFFF00>Yellow text.</style> <style color=#FF0000>Red text.</style> +<style size=24>Size 24.</style> <style size=16>Size 16</style>. <style size=12>Size 12.</style> +<style font=normal>Normal font.</style> <style font=mono>Mono font.</style> + +<bigger>Tag test</bigger> +<normal>normal</normal> +<mono>mono</mono> +<b>bold</b> +<i>italic</i> +<u>underlined</u> +<big>big</big> +<bigger>bigger</bigger> +<left>left</left> +<center>center</center> +<right>right</right> +<justify>justify. Here comes a blind text: Lorem testum dolor sit amet consecutor celeron fiftifahivus e shadoninia e smalus jokus anrus relsocutoti rubenwardus. Erasputinus hara holisti dominus wusi. Grumarinsti erltusmuate ol fortitusti fla flo, blani burki e sfani fahif. Ultae ratii, e megus gigae don anonimus. Grinus dimondus krockus e nore. Endus finalus nowus comus endus o blindus tekstus.</justify> + +<bigger>Custom tag test</bigger> +<tag name=t_green color=green> +<tag name=t_hover hovercolor=yellow> +<tag name=t_size size=24> +<tag name=t_mono font=mono> +<tag name=t_multi color=green font=mono size=24> +<t_green>color=green</t_green> +Action: <action name=color><t_green>color=green</t_green></action> +Action: <action name=hovercolor><t_hover>hovercolor=yellow</t_hover></action> +<t_size>size=24</t_size> +<t_mono>font=mono</t_mono> +<t_multi>color=green font=mono size=24</t_multi> + +<bigger><mono>action</mono> test</bigger> +<action name=action_test>action</action> + +<bigger><mono>img</mono> test</bigger> +Normal: +<img name=testformspec_item.png> +<mono>width=48 height=48</mono>: +<img name=testformspec_item.png width=48 height=48> +<mono>float=left</mono>: +<img name=testformspec_item.png float=left> +<mono>float=right</mono>: +<img name=testformspec_item.png float=right> + +<bigger><mono>item</mono> test</bigger> +Normal: +<item name=testformspec:node> +<mono>width=48 height=48</mono> +<item name=testformspec:node width=48 height=48> +<mono>angle=30,0,0</mono>: +<item name=testformspec:node angle=30,0,0> +<mono>angle=0,30,0</mono>: +<item name=testformspec:node angle=0,30,0> +<mono>angle=0,0,30</mono>: +<item name=testformspec:node angle=0,0,30> +<mono>rotate=yes</mono>: +<item name=testformspec:node rotate=yes> +<mono>rotate=100,0,0</mono>: +<item name=testformspec:node rotate=100,0,0> +<mono>rotate=0,100,0</mono>: +<item name=testformspec:node rotate=0,100,0> +<mono>rotate=0,0,100</mono>: +<item name=testformspec:node rotate=0,0,100> +<mono>rotate=50,75,100</mono>: +<item name=testformspec:node rotate=50,75,100> +<mono>angle=-30,-45,90 rotate=100,150,-50</mono>: +<item name=testformspec:node angle=-30,-45,90 rotate=100,150,-50>]] + +local hypertext_global = [[ +<global background=gray margin=20 valign=bottom halign=right color=pink hovercolor=purple size=12 font=mono> +This is a test of the global tag. The parameters are: +background=gray margin=20 valign=bottom halign=right color=pink hovercolor=purple size=12 font=mono +<action name=global>action</action>]] + +local hypertext_fs = "hypertext[0,0;11,9;hypertext;"..minetest.formspec_escape(hypertext_basic).."]".. + "hypertext[0,9.5;11,2.5;hypertext;"..minetest.formspec_escape(hypertext_global).."]" + +local style_fs = [[ + style[one_btn1;bgcolor=red;textcolor=yellow;bgcolor_hovered=orange; + bgcolor_pressed=purple] + button[0,0;2.5,0.8;one_btn1;Button] + + style[one_btn2;border=false;textcolor=cyan] ]].. + "button[0,1.05;2.5,0.8;one_btn2;Text " .. color("#FF0", "Yellow") .. [[] + + style[one_btn3;bgimg=testformspec_button_image.png;bgimg_hovered=testformspec_hovered.png; + bgimg_pressed=testformspec_pressed.png] + button[0,2.1;1,1;one_btn3;Border] + + style[one_btn4;bgimg=testformspec_button_image.png;bgimg_hovered=testformspec_hovered.png; + bgimg_pressed=testformspec_pressed.png;border=false] + button[1.25,2.1;1,1;one_btn4;NoBor] + + style[one_btn5;bgimg=testformspec_button_image.png;bgimg_hovered=testformspec_hovered.png; + bgimg_pressed=testformspec_pressed.png;border=false;alpha=false] + button[0,3.35;1,1;one_btn5;Alph] + + style[one_btn6;border=true] + image_button[0,4.6;1,1;testformspec_button_image.png;one_btn6;Border] + + style[one_btn7;border=false] + image_button[1.25,4.6;1,1;testformspec_button_image.png;one_btn7;NoBor] + + style[one_btn8;border=false] + image_button[0,5.85;1,1;testformspec_button_image.png;one_btn8;Border;false;true;testformspec_pressed.png] + + style[one_btn9;border=true] + image_button[1.25,5.85;1,1;testformspec_button_image.png;one_btn9;NoBor;false;false;testformspec_pressed.png] + + style[one_btn10;alpha=false] + image_button[0,7.1;1,1;testformspec_button_image.png;one_btn10;NoAlpha] + + style[one_btn11;alpha=true] + image_button[1.25,7.1;1,1;testformspec_button_image.png;one_btn11;Alpha] + + style[one_btn12;border=true] + item_image_button[0,8.35;1,1;testformspec:item;one_btn12;Border] + + style[one_btn13;border=false] + item_image_button[1.25,8.35;1,1;testformspec:item;one_btn13;NoBor] + + style[one_btn14;border=false;bgimg=testformspec_bg.png;fgimg=testformspec_button_image.png] + style[one_btn14:hovered;bgimg=testformspec_bg_hovered.png;fgimg=testformspec_hovered.png;textcolor=yellow] + style[one_btn14:pressed;bgimg=testformspec_bg_pressed.png;fgimg=testformspec_pressed.png;textcolor=blue] + style[one_btn14:hovered+pressed;textcolor=purple] + image_button[0,9.6;1,1;testformspec_button_image.png;one_btn14;Bg] + + style[one_btn15;border=false;bgcolor=#1cc;bgimg=testformspec_bg.png;bgimg_hovered=testformspec_bg_hovered.png;bgimg_pressed=testformspec_bg_pressed.png] + item_image_button[1.25,9.6;1,1;testformspec:item;one_btn15;Bg] + + style[one_btn16;border=false;bgimg=testformspec_bg_9slice.png;bgimg_middle=4,6;padding=5,7;fgimg=testformspec_bg.png;fgimg_middle=1] + style[one_btn16:hovered;bgimg=testformspec_bg_9slice_hovered.png;fgimg=testformspec_bg_hovered.png] + style[one_btn16:pressed;bgimg=testformspec_bg_9slice_pressed.png;fgimg=testformspec_bg_pressed.png] + image_button[2.5,9.6;2,1;;one_btn16;9-Slice Bg] + + + + container[2.75,0] + + style[one_tb1;textcolor=Yellow] + tabheader[0,3;2.5,0.63;one_tb1;Yellow,Text,Tabs;1;false;false] + + style[one_f1;textcolor=yellow] + field[0,4.25;2.5,0.8;one_f1;Field One;Yellow Text] + + style[one_f2;border=false;textcolor=cyan] + field[0,5.75;2.5,0.8;one_f2;Field Two;Borderless Cyan Text] + + style[one_f3;textcolor=yellow] + textarea[0,7.025;2.5,0.8;one_f3;Label;]] .. + minetest.formspec_escape("Yellow Text\nLine two") .. [[ ] + + style[one_f4;border=false;textcolor=cyan] + textarea[0,8.324999999999999;2.5,0.8;one_f4;Label;]] .. + minetest.formspec_escape("Borderless Cyan Text\nLine two") .. [[ ] + + container_end[] +]] + +local scroll_fs = + "button[8.5,1;4,1;outside;Outside of container]".. + "box[1,1;8,6;#00aa]".. + "scroll_container[1,1;8,6;scrbar;vertical]".. + "button[0,1;1,1;lorem;Lorem]".. + "animated_image[0,1;4.5,1;clip_animated_image;testformspec_animation.png;4;100]" .. + "button[0,10;1,1;ipsum;Ipsum]".. + "pwdfield[2,2;1,1;lorem2;Lorem]".. + "list[current_player;main;4,4;1,5;]".. + "box[2,5;3,2;#ffff00]".. + "image[1,10;3,2;testformspec_item.png]".. + "image[3,1;testformspec_item.png]".. + "item_image[2,6;3,2;testformspec:node]".. + "label[2,15;bla Bli\nfoo bar]".. + "item_image_button[2,3;1,1;testformspec:node;itemimagebutton;ItemImageButton]".. + "tooltip[0,11;3,2;Buz;#f00;#000]".. + "box[0,11;3,2;#00ff00]".. + "hypertext[3,13;3,3;;" .. hypertext_basic .. "]" .. + "hypertext[3,17;3,3;;Hypertext with no scrollbar\\; the scroll container should scroll.]" .. + "textarea[3,21;3,1;textarea;;More scroll within scroll]" .. + "container[0,18]".. + "box[1,2;3,2;#0a0a]".. + "scroll_container[1,2;3,2;scrbar2;horizontal;0.06]".. + "button[0,0;6,1;butnest;Nest]".. + "label[10,0.5;nest]".. + "scroll_container_end[]".. + "scrollbar[1,0;3.5,0.3;horizontal;scrbar2;0]".. + "container_end[]".. + "dropdown[0,6;2;hmdrpdwn;apple,bulb;1]".. + "image_button[0,4;2,2;testformspec_button_image.png;imagebutton;bbbbtt;false;true;testformspec_pressed.png]".. + "box[1,22.5;4,1;#a00a]".. + "scroll_container_end[]".. + "scrollbaroptions[max=170]".. -- lowest seen pos is: 0.1*170+6=23 (factor*max+height) + "scrollbar[7.5,0;0.3,4;vertical;scrbar;0]".. + "scrollbar[8,0;0.3,4;vertical;scrbarhmmm;0]".. + "dropdown[0,6;2;hmdrpdwnnn;Outside,of,container;1]" + +--style_type[label;textcolor=green] +--label[0,0;Green] +--style_type[label;textcolor=blue] +--label[0,1;Blue] +--style_type[label;textcolor=;border=true] +--label[1.2,0;Border] +--style_type[label;border=true;bgcolor=red] +--label[1.2,1;Background] +--style_type[label;border=;bgcolor=] +--label[0.75,2;Reset] + +local window = { + sizex = 12, + sizey = 13, + positionx = 0.5, + positiony = 0.5, + anchorx = 0.5, + anchory = 0.5, + paddingx = 0.05, + paddingy = 0.05 +} + +local pages = { + -- Real Coordinates + [[ + formspec_version[3] + size[12,13] + image_button[0,0;1,1;logo.png;rc_image_button_1x1;1x1] + image_button[1,0;2,2;logo.png;rc_image_button_2x2;2x2] + button[0,2;1,1;rc_button_1x1;1x1] + button[1,2;2,2;rc_button_2x2;2x2] + item_image[0,4;1,1;air] + item_image[1,4;2,2;air] + item_image_button[0,6;1,1;testformspec:node;rc_item_image_button_1x1;1x1] + item_image_button[1,6;2,2;testformspec:node;rc_item_image_button_2x2;2x2] + field[3,.5;3,.5;rc_field;Field;text] + pwdfield[6,.5;3,1;rc_pwdfield;Password Field] + field[3,1;3,1;;Read-Only Field;text] + textarea[3,2;3,.5;rc_textarea_small;Textarea;text] + textarea[6,2;3,2;rc_textarea_big;Textarea;text\nmore text] + textarea[3,3;3,1;;Read-Only Textarea;text\nmore text] + textlist[3,4;3,2;rc_textlist;Textlist,Perfect Coordinates;1;false] + tableoptions[highlight=#ABCDEF75;background=#00000055;border=false] + table[6,4;3,2;rc_table;Table,Cool Stuff,Foo,Bar;2] + dropdown[3,6;3,1;rc_dropdown_small;This,is,a,dropdown;1] + dropdown[6,6;3,2;rc_dropdown_big;I,am,a,bigger,dropdown;5] + image[0,8;3,2;ignore.png] + box[3,7;3,1;#00A3FF] + checkbox[3,8;rc_checkbox_1;Check me!;false] + checkbox[3,9;rc_checkbox_2;Uncheck me now!;true] + scrollbar[0,11.5;11.5,.5;horizontal;rc_scrollbar_horizontal;500] + scrollbar[11.5,0;.5,11.5;vertical;rc_scrollbar_vertical;0] + list[current_player;main;6,8;3,2;1] + button[9,0;2.5,1;rc_empty_button_1;] + button[9,1;2.5,1;rc_empty_button_2;] + button[9,2;2.5,1;rc_empty_button_3;] ]].. + "label[9,0.5;This is a label.\nLine\nLine\nLine\nEnd]".. + [[button[9,3;1,1;rc_empty_button_4;] + vertlabel[9,4;VERT] + label[10,3;HORIZ] + tabheader[8,0;6,0.65;rc_tabheader;Tab 1,Tab 2,Tab 3,Secrets;1;false;false] + ]], + -- Style + + "formspec_version[3]size[12,13]" .. + ("label[0.375,0.375;Styled - %s %s]"):format( + color("#F00", "red text"), + color("#77FF00CC", "green text")) .. + "label[6.375,0.375;Unstyled]" .. + "box[0,0.75;12,0.1;#999]" .. + "box[6,0.85;0.1,11.15;#999]" .. + "container[0.375,1.225]" .. + style_fs .. + "container_end[]container[6.375,1.225]" .. + style_fs:gsub("one_", "two_"):gsub("style%[[^%]]+%]", ""):gsub("style_type%[[^%]]+%]", "") .. + "container_end[]", + + -- Noclip + "formspec_version[3]size[12,13]" .. + "label[0.1,0.5;Clip]" .. + "container[-2.5,1]" .. clip_fs:gsub("%%c", "false") .. "container_end[]" .. + "label[11,0.5;Noclip]" .. + "container[11.5,1]" .. clip_fs:gsub("%%c", "true") .. "container_end[]", + + -- Hypertext + "size[12,13]real_coordinates[true]" .. + "container[0.5,0.5]" .. hypertext_fs .. "container_end[]", + + -- Tabheaders + "size[12,13]real_coordinates[true]" .. + "container[0.5,1.5]" .. tabheaders_fs .. "container_end[]", + + -- Inv + "size[12,13]real_coordinates[true]" .. inv_style_fs, + + -- Window + function() + return "formspec_version[3]" .. + string.format("size[%s,%s]position[%s,%s]anchor[%s,%s]padding[%s,%s]", + window.sizex, window.sizey, window.positionx, window.positiony, + window.anchorx, window.anchory, window.paddingx, window.paddingy) .. + string.format("field[0.5,0.5;2.5,0.5;sizex;X Size;%s]field[3.5,0.5;2.5,0.5;sizey;Y Size;%s]" .. + "field[0.5,1.5;2.5,0.5;positionx;X Position;%s]field[3.5,1.5;2.5,0.5;positiony;Y Position;%s]" .. + "field[0.5,2.5;2.5,0.5;anchorx;X Anchor;%s]field[3.5,2.5;2.5,0.5;anchory;Y Anchor;%s]" .. + "field[0.5,3.5;2.5,0.5;paddingx;X Padding;%s]field[3.5,3.5;2.5,0.5;paddingy;Y Padding;%s]" .. + "button[2,4.5;2.5,0.5;submit_window;Submit]", + window.sizex, window.sizey, window.positionx, window.positiony, + window.anchorx, window.anchory, window.paddingx, window.paddingy) .. + "field_close_on_enter[sizex;false]field_close_on_enter[sizey;false]" .. + "field_close_on_enter[positionx;false]field_close_on_enter[positiony;false]" .. + "field_close_on_enter[anchorx;false]field_close_on_enter[anchory;false]" .. + "field_close_on_enter[paddingx;false]field_close_on_enter[paddingy;false]" + end, + + -- Animation + [[ + formspec_version[6] + size[12,13] + animated_image[0.5,0.5;1,1;;testformspec_animation.png;4;100] + animated_image[0.5,1.75;1,1;;testformspec_animation.jpg;4;100] + animated_image[1.75,0.5;1,1;;testformspec_animation.png;100;100] + animated_image[3,0.5;1,1;ani_img_1;testformspec_animation.png;4;1000] + image[0.5,3;1,1;testformspec_bg.png;1] + animated_image[0.5,4.25;1,1;;[combine:16x48:0,0=testformspec_bg.png:0,16=testformspec_bg_hovered.png:0,32=testformspec_bg_pressed.png;3;250;1;1] + image[0.5,5.5;2,1;testformspec_9slice.png;16,0,-16,-16] + animated_image[2.75,5.5;1.5,0.5;;[combine:300x140:0,0=testformspec_9slice.png:0,70=(testformspec_9slice.png^[transformFX);2;500;1;16,0,-16,-16] + button[4.25,0.5;1,1;ani_btn_1;Current +Number] + animated_image[3,1.75;1,1;ani_img_2;testformspec_animation.png;4;1000;2] + button[4.25,1.75;1,1;ani_btn_2;Current +Number] + animated_image[3,3;1,1;;testformspec_animation.png;4;0] + animated_image[3,4.25;1,1;;testformspec_animation.png;4;0;3] + animated_image[5.5,0.5;5,2;;testformspec_animation.png;4;100] + animated_image[5.5,2.75;5,2;;testformspec_animation.jpg;4;100] + + ]], + + -- Model + [[ + formspec_version[3] + size[12,13] + style[m1;bgcolor=black] + style[m2;bgcolor=black] + label[5,1;all defaults] + label[5,5.1;angle = 0, 180 +continuous = false +mouse control = false +frame loop range = 0,30] + label[5,9.2;continuous = true +mouse control = true] + model[0.5,0.1;4,4;m1;testformspec_character.b3d;testformspec_character.png] + model[0.5,4.2;4,4;m2;testformspec_character.b3d;testformspec_character.png;0,180;false;false;0,30] + model[0.5,8.3;4,4;m3;testformspec_chest.obj;default_chest_top.png,default_chest_top.png,default_chest_side.png,default_chest_side.png,default_chest_front.png,default_chest_inside.png;30,1;true;true] + ]], + + -- Scroll containers + "formspec_version[3]size[12,13]" .. + scroll_fs, + + -- Sound + [[ + formspec_version[3] + size[12,13] + style[snd_btn;sound=soundstuff_mono] + style[snd_ibtn;sound=soundstuff_mono] + style[snd_drp;sound=soundstuff_mono] + style[snd_chk;sound=soundstuff_mono] + style[snd_tab;sound=soundstuff_mono] + button[0.5,0.5;2,1;snd_btn;Sound] + image_button[0.5,2;2,1;testformspec_item.png;snd_ibtn;Sound] + dropdown[0.5,4;4;snd_drp;Sound,Two,Three;] + checkbox[0.5,5.5.5;snd_chk;Sound;] + tabheader[0.5,7;8,0.65;snd_tab;Soundtab1,Soundtab2,Soundtab3;1;false;false] + ]], + + -- Background + [[ + formspec_version[3] + size[12,13] + box[0,0;12,13;#f0f1] + background[0,0;0,0;testformspec_bg.png;true] + box[3.9,2.9;6.2,4.2;#d00f] + scroll_container[4,3;6,4;scrbar;vertical] + background9[1,0.5;0,0;testformspec_bg_9slice.png;true;4,6] + label[0,0.2;Backgrounds are not be applied to scroll containers,] + label[0,0.5;but to the whole form.] + scroll_container_end[] + scrollbar[3.5,3;0.3,4;vertical;scrbar;0] + container[2,11] + box[-0.1,0.5;3.2,1;#fff5] + background[0,0;2,3;testformspec_bg.png;false] + background9[1,0;2,3;testformspec_bg_9slice.png;false;4,6] + container_end[] + ]], + + -- Unsized + [[ + formspec_version[3] + background9[0,0;0,0;testformspec_bg_9slice.png;true;4,6] + background[1,1;0,0;testformspec_bg.png;true] + ]], +} + +local page_id = 2 +local function show_test_formspec(pname) + local page = pages[page_id] + if type(page) == "function" then + page = page() + end + + local fs = page .. "tabheader[0,0;11,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Window,Anim,Model,ScrollC,Sound,Background,Unsized;" .. page_id .. ";false;false]" + + minetest.show_formspec(pname, "testformspec:formspec", fs) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "testformspec:formspec" then + return false + end + + if fields.maintabs then + page_id = tonumber(fields.maintabs) + show_test_formspec(player:get_player_name()) + return true + end + + if fields.ani_img_1 and fields.ani_btn_1 then + minetest.chat_send_player(player:get_player_name(), "ani_img_1 = " .. tostring(fields.ani_img_1)) + return true + elseif fields.ani_img_2 and fields.ani_btn_2 then + minetest.chat_send_player(player:get_player_name(), "ani_img_2 = " .. tostring(fields.ani_img_2)) + return true + end + + if fields.hypertext then + minetest.chat_send_player(player:get_player_name(), "Hypertext action received: " .. tostring(fields.hypertext)) + return true + end + + for name, value in pairs(fields) do + if window[name] then + print(name, window[name]) + local num_val = tonumber(value) or 0 + + if name == "sizex" and num_val < 4 then + num_val = 6.5 + elseif name == "sizey" and num_val < 5 then + num_val = 5.5 + end + + window[name] = num_val + print(name, window[name]) + end + end + + if fields.submit_window then + show_test_formspec(player:get_player_name()) + end +end) + +minetest.register_chatcommand("test_formspec", { + params = "", + description = "Open the test formspec", + func = function(name) + if not minetest.get_player_by_name(name) then + return false, "You need to be online!" + end + + show_test_formspec(name) + return true + end, +}) diff --git a/games/devtest/mods/testformspec/init.lua b/games/devtest/mods/testformspec/init.lua new file mode 100644 index 0000000..23b565f --- /dev/null +++ b/games/devtest/mods/testformspec/init.lua @@ -0,0 +1,3 @@ +dofile(minetest.get_modpath("testformspec").."/dummy_items.lua") +dofile(minetest.get_modpath("testformspec").."/formspec.lua") +dofile(minetest.get_modpath("testformspec").."/callbacks.lua") diff --git a/games/devtest/mods/testformspec/mod.conf b/games/devtest/mods/testformspec/mod.conf new file mode 100644 index 0000000..00eac30 --- /dev/null +++ b/games/devtest/mods/testformspec/mod.conf @@ -0,0 +1,2 @@ +name = testformspec +description = Contains an example formspec to test all the features of formspecs diff --git a/games/devtest/mods/testformspec/models/testformspec_character.b3d b/games/devtest/mods/testformspec/models/testformspec_character.b3d new file mode 100644 index 0000000..8edbaf6 Binary files /dev/null and b/games/devtest/mods/testformspec/models/testformspec_character.b3d differ diff --git a/games/devtest/mods/testformspec/models/testformspec_chest.obj b/games/devtest/mods/testformspec/models/testformspec_chest.obj new file mode 100644 index 0000000..72ba175 --- /dev/null +++ b/games/devtest/mods/testformspec/models/testformspec_chest.obj @@ -0,0 +1,79 @@ +# Blender v2.78 (sub 0) OBJ File: 'chest-open.blend' +# www.blender.org +o Top_Cube.002_None_Top_Cube.002_None_bottom +v -0.500000 0.408471 0.720970 +v -0.500000 1.115578 0.013863 +v -0.500000 0.894607 -0.207108 +v -0.500000 0.187501 0.499999 +v 0.500000 1.115578 0.013863 +v 0.500000 0.408471 0.720970 +v 0.500000 0.187501 0.499999 +v 0.500000 0.894607 -0.207108 +v -0.500000 0.187500 -0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 0.187500 -0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +vt 0.0000 1.0000 +vt 0.0000 0.0000 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.0000 +vt 0.0000 1.0000 +vt 1.0000 1.0000 +vt 1.0000 0.6875 +vt 0.0000 0.6875 +vt 1.0000 1.0000 +vt 0.0000 0.6875 +vt 1.0000 0.6875 +vt 1.0000 0.6875 +vt 1.0000 0.0000 +vt 0.0000 0.0000 +vt 1.0000 0.6875 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt 1.0000 0.6875 +vt 1.0000 0.0000 +vt 0.0000 1.0000 +vt 0.0000 0.6875 +vt 0.0000 0.6875 +vt 0.0000 0.0000 +vt 1.0000 0.5000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.5000 +vt 0.0000 0.0000 +vt 1.0000 0.0000 +vn 0.0000 0.7071 0.7071 +vn -0.0000 -1.0000 -0.0000 +vn -1.0000 0.0000 0.0000 +vn 1.0000 0.0000 -0.0000 +vn 0.0000 -0.7071 0.7071 +vn 0.0000 0.0000 1.0000 +vn -0.0000 0.7071 -0.7071 +vn -0.0000 0.0000 -1.0000 +vn -0.0000 -0.7071 -0.7071 +vn -0.0000 1.0000 -0.0000 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Top +s off +f 6/1/1 5/2/1 2/3/1 1/4/1 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Bottom +f 11/5/2 10/6/2 14/7/2 13/8/2 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Right-Left +f 1/9/3 2/10/3 3/11/3 4/12/3 +f 5/13/4 6/1/4 7/14/4 8/15/4 +f 4/12/3 9/16/3 10/17/3 11/18/3 +f 12/19/4 7/14/4 13/8/4 14/20/4 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Back +f 6/21/5 1/9/5 4/12/5 7/22/5 +f 7/22/6 4/12/6 11/18/6 13/23/6 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Front +f 2/10/7 5/24/7 8/25/7 3/11/7 +f 9/16/8 12/26/8 14/27/8 10/17/8 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Inside +f 4/28/9 3/29/9 8/30/9 7/31/9 +f 7/31/10 12/32/10 9/33/10 4/28/10 diff --git a/games/devtest/mods/testformspec/textures/default_chest_front.png b/games/devtest/mods/testformspec/textures/default_chest_front.png new file mode 100644 index 0000000..85227d8 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/default_chest_front.png differ diff --git a/games/devtest/mods/testformspec/textures/default_chest_inside.png b/games/devtest/mods/testformspec/textures/default_chest_inside.png new file mode 100644 index 0000000..5f7b6b1 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/default_chest_inside.png differ diff --git a/games/devtest/mods/testformspec/textures/default_chest_side.png b/games/devtest/mods/testformspec/textures/default_chest_side.png new file mode 100644 index 0000000..44a65a4 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/default_chest_side.png differ diff --git a/games/devtest/mods/testformspec/textures/default_chest_top.png b/games/devtest/mods/testformspec/textures/default_chest_top.png new file mode 100644 index 0000000..f4a92ee Binary files /dev/null and b/games/devtest/mods/testformspec/textures/default_chest_top.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_9slice.png b/games/devtest/mods/testformspec/textures/testformspec_9slice.png new file mode 100644 index 0000000..70b6412 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_9slice.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_animation.jpg b/games/devtest/mods/testformspec/textures/testformspec_animation.jpg new file mode 100644 index 0000000..b98ca26 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_animation.jpg differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_animation.png b/games/devtest/mods/testformspec/textures/testformspec_animation.png new file mode 100644 index 0000000..b972e5d Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_animation.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg.png b/games/devtest/mods/testformspec/textures/testformspec_bg.png new file mode 100644 index 0000000..cd1e509 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_bg.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg_9slice.png b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice.png new file mode 100644 index 0000000..34433ac Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_hovered.png b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_hovered.png new file mode 100644 index 0000000..01c2dc7 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_hovered.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_pressed.png b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_pressed.png new file mode 100644 index 0000000..0cbac75 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_bg_9slice_pressed.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg_hovered.png b/games/devtest/mods/testformspec/textures/testformspec_bg_hovered.png new file mode 100644 index 0000000..3ebbb98 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_bg_hovered.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_bg_pressed.png b/games/devtest/mods/testformspec/textures/testformspec_bg_pressed.png new file mode 100644 index 0000000..2fb5fc2 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_bg_pressed.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_button_image.png b/games/devtest/mods/testformspec/textures/testformspec_button_image.png new file mode 100644 index 0000000..75c438a Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_button_image.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_character.png b/games/devtest/mods/testformspec/textures/testformspec_character.png new file mode 100644 index 0000000..0502178 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_character.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_hovered.png b/games/devtest/mods/testformspec/textures/testformspec_hovered.png new file mode 100644 index 0000000..3ccad30 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_hovered.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_item.png b/games/devtest/mods/testformspec/textures/testformspec_item.png new file mode 100644 index 0000000..4fd823b Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_item.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_node.png b/games/devtest/mods/testformspec/textures/testformspec_node.png new file mode 100644 index 0000000..c107f28 Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_node.png differ diff --git a/games/devtest/mods/testformspec/textures/testformspec_pressed.png b/games/devtest/mods/testformspec/textures/testformspec_pressed.png new file mode 100644 index 0000000..45c504f Binary files /dev/null and b/games/devtest/mods/testformspec/textures/testformspec_pressed.png differ diff --git a/games/devtest/mods/testhud/init.lua b/games/devtest/mods/testhud/init.lua new file mode 100644 index 0000000..2fa12fd --- /dev/null +++ b/games/devtest/mods/testhud/init.lua @@ -0,0 +1,81 @@ +local player_huds = {} + +local states = { + {0, "Normal font"}, + {1, "Bold font"}, + {2, "Italic font"}, + {3, "Bold and italic font"}, + {4, "Monospace font"}, + {5, "Bold and monospace font"}, + {7, "ZOMG all the font styles"}, +} + + +local default_def = { + hud_elem_type = "text", + position = {x = 0.5, y = 0.5}, + scale = {x = 2, y = 2}, + alignment = { x = 0, y = 0 }, +} + +local function add_hud(player, state) + local def = table.copy(default_def) + local statetbl = states[state] + def.offset = {x = 0, y = 32 * state} + def.style = statetbl[1] + def.text = statetbl[2] + return player:hud_add(def) +end + +minetest.register_on_leaveplayer(function(player) + player_huds[player:get_player_name()] = nil +end) + +local etime = 0 +local state = 0 + +minetest.register_globalstep(function(dtime) + etime = etime + dtime + if etime < 1 then + return + end + etime = 0 + for _, player in ipairs(minetest.get_connected_players()) do + local huds = player_huds[player:get_player_name()] + if huds then + for i, hud_id in ipairs(huds) do + local statetbl = states[(state + i) % #states + 1] + player:hud_change(hud_id, "style", statetbl[1]) + player:hud_change(hud_id, "text", statetbl[2]) + end + end + end + state = state + 1 +end) + +minetest.register_chatcommand("hudfonts", { + params = "", + description = "Show/Hide some text on the HUD with various font options", + func = function(name, param) + local player = minetest.get_player_by_name(name) + local param = tonumber(param) or 0 + param = math.min(math.max(param, 1), #states) + if player_huds[name] == nil then + player_huds[name] = {} + for i = 1, param do + table.insert(player_huds[name], add_hud(player, i)) + end + minetest.chat_send_player(name, ("%d HUD element(s) added."):format(param)) + else + local huds = player_huds[name] + if huds then + for _, hud_id in ipairs(huds) do + player:hud_remove(hud_id) + end + minetest.chat_send_player(name, "All HUD elements removed.") + end + player_huds[name] = nil + end + return true + end, +}) diff --git a/games/devtest/mods/testhud/mod.conf b/games/devtest/mods/testhud/mod.conf new file mode 100644 index 0000000..ed9f65c --- /dev/null +++ b/games/devtest/mods/testhud/mod.conf @@ -0,0 +1,2 @@ +name = testhud +description = For testing HUD functionality diff --git a/games/devtest/mods/testitems/init.lua b/games/devtest/mods/testitems/init.lua new file mode 100644 index 0000000..33ebf50 --- /dev/null +++ b/games/devtest/mods/testitems/init.lua @@ -0,0 +1,55 @@ +local S = minetest.get_translator("testitems") + +-- +-- Texture overlays for items +-- + +-- For the global overlay color test +local GLOBAL_COLOR_ARG = "orange" + +-- Punch handler to set random color with "color" argument in item metadata +local overlay_on_use = function(itemstack, user, pointed_thing) + local meta = itemstack:get_meta() + local color = math.random(0x0, 0xFFFFFF) + local colorstr = string.format("#%06x", color) + meta:set_string("color", colorstr) + minetest.log("action", "[testitems] Color of "..itemstack:get_name().." changed to "..colorstr) + return itemstack +end +-- Place handler to clear item metadata color +local overlay_on_place = function(itemstack, user, pointed_thing) + local meta = itemstack:get_meta() + meta:set_string("color", "") + return itemstack +end + +minetest.register_craftitem("testitems:overlay_meta", { + description = S("Texture Overlay Test Item, Meta Color") .. "\n" .. + S("Image must be a square with rainbow cross (inventory and wield)") .. "\n" .. + S("Item meta color must only change square color") .. "\n" .. + S("Punch: Set random color") .. "\n" .. + S("Place: Clear color"), + -- Base texture: A grayscale square (can be colorized) + inventory_image = "testitems_overlay_base.png", + wield_image = "testitems_overlay_base.png", + -- Overlay: A rainbow cross (NOT to be colorized!) + inventory_overlay = "testitems_overlay_overlay.png", + wield_overlay = "testitems_overlay_overlay.png", + + on_use = overlay_on_use, + on_place = overlay_on_place, + on_secondary_use = overlay_on_place, +}) +minetest.register_craftitem("testitems:overlay_global", { + description = S("Texture Overlay Test Item, Global Color") .. "\n" .. + S("Image must be an orange square with rainbow cross (inventory and wield)"), + -- Base texture: A grayscale square (to be colorized) + inventory_image = "testitems_overlay_base.png", + wield_image = "testitems_overlay_base.png", + -- Overlay: A rainbow cross (NOT to be colorized!) + inventory_overlay = "testitems_overlay_overlay.png", + wield_overlay = "testitems_overlay_overlay.png", + color = GLOBAL_COLOR_ARG, +}) + + diff --git a/games/devtest/mods/testitems/mod.conf b/games/devtest/mods/testitems/mod.conf new file mode 100644 index 0000000..f91febe --- /dev/null +++ b/games/devtest/mods/testitems/mod.conf @@ -0,0 +1,2 @@ +name = testitems +description = Test mod to test misc. items that are neither tools nor nodes diff --git a/games/devtest/mods/testitems/textures/testitems_overlay_base.png b/games/devtest/mods/testitems/textures/testitems_overlay_base.png new file mode 100644 index 0000000..f473623 Binary files /dev/null and b/games/devtest/mods/testitems/textures/testitems_overlay_base.png differ diff --git a/games/devtest/mods/testitems/textures/testitems_overlay_overlay.png b/games/devtest/mods/testitems/textures/testitems_overlay_overlay.png new file mode 100644 index 0000000..75a7d9f Binary files /dev/null and b/games/devtest/mods/testitems/textures/testitems_overlay_overlay.png differ diff --git a/games/devtest/mods/testnodes/README.md b/games/devtest/mods/testnodes/README.md new file mode 100644 index 0000000..13ed972 --- /dev/null +++ b/games/devtest/mods/testnodes/README.md @@ -0,0 +1,11 @@ +# Test Nodes + +This mod contains a bunch of basic nodes to test development stuff. +Most nodes are kept as minimal as possible in order to show off one particular feature of the engine, to make testing stuff easier. + +This mod includes tests for: + +* drawtypes +* paramtype2's +* node properties such as damage, drowning, falling, etc. +* other random stuff diff --git a/games/devtest/mods/testnodes/drawtypes.lua b/games/devtest/mods/testnodes/drawtypes.lua new file mode 100644 index 0000000..208774f --- /dev/null +++ b/games/devtest/mods/testnodes/drawtypes.lua @@ -0,0 +1,629 @@ +--[[ Drawtype Test: This file tests out and provides examples for +all drawtypes in Minetest. It is attempted to keep the node +definitions as simple and minimal as possible to keep +side-effects to a minimum. + +How to read the node definitions: +There are two parts which are separated by 2 newlines: +The first part contains the things that are more or less essential +for defining the drawtype (except description, which is +at the top for readability). +The second part (after the 2 newlines) contains stuff that are +unrelated to the drawtype, stuff that is mostly there to make +testing this node easier and more convenient. +]] + +local S = minetest.get_translator("testnodes") + +-- A regular cube +minetest.register_node("testnodes:normal", { + description = S("Normal Drawtype Test Node"), + drawtype = "normal", + tiles = { "testnodes_normal.png" }, + + groups = { dig_immediate = 3 }, +}) + +-- Standard glasslike node +minetest.register_node("testnodes:glasslike", { + description = S("Glasslike Drawtype Test Node"), + drawtype = "glasslike", + paramtype = "light", + tiles = { "testnodes_glasslike.png" }, + + groups = { dig_immediate = 3 }, +}) + +-- Glasslike framed with the two textures (normal and "detail") +minetest.register_node("testnodes:glasslike_framed", { + description = S("Glasslike Framed Drawtype Test Node"), + drawtype = "glasslike_framed", + paramtype = "light", + tiles = { + "testnodes_glasslike_framed.png", + "testnodes_glasslike_detail.png", + }, + + + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +-- Like the one above, but without the "detail" texture (texture 2). +-- This node was added to see how the engine behaves when the "detail" texture +-- is missing. +minetest.register_node("testnodes:glasslike_framed_no_detail", { + description = S("Glasslike Framed without Detail Drawtype Test Node"), + drawtype = "glasslike_framed", + paramtype = "light", + tiles = { "testnodes_glasslike_framed2.png" }, + + + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + + +minetest.register_node("testnodes:glasslike_framed_optional", { + description = S("Glasslike Framed Optional Drawtype Test Node"), + drawtype = "glasslike_framed_optional", + paramtype = "light", + tiles = { + "testnodes_glasslike_framed_optional.png", + "testnodes_glasslike_detail.png", + }, + + + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + + + +minetest.register_node("testnodes:allfaces", { + description = S("Allfaces Drawtype Test Node"), + drawtype = "allfaces", + paramtype = "light", + tiles = { "testnodes_allfaces.png" }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:allfaces_optional", { + description = S("Allfaces Optional Drawtype Test Node"), + drawtype = "allfaces_optional", + paramtype = "light", + tiles = { "testnodes_allfaces_optional.png" }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:allfaces_optional_waving", { + description = S("Waving Allfaces Optional Drawtype Test Node"), + drawtype = "allfaces_optional", + paramtype = "light", + tiles = { "testnodes_allfaces_optional.png^[brighten" }, + waving = 2, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:firelike", { + description = S("Firelike Drawtype Test Node"), + drawtype = "firelike", + paramtype = "light", + tiles = { "testnodes_firelike.png" }, + + + walkable = false, + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:fencelike", { + description = S("Fencelike Drawtype Test Node"), + drawtype = "fencelike", + paramtype = "light", + tiles = { "testnodes_fencelike.png" }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:torchlike", { + description = S("Floor Torchlike Drawtype Test Node"), + drawtype = "torchlike", + paramtype = "light", + tiles = { "testnodes_torchlike_floor.png^[colorize:#FF0000:64" }, + + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:torchlike_wallmounted", { + description = S("Wallmounted Torchlike Drawtype Test Node"), + drawtype = "torchlike", + paramtype = "light", + paramtype2 = "wallmounted", + tiles = { + "testnodes_torchlike_floor.png", + "testnodes_torchlike_ceiling.png", + "testnodes_torchlike_wall.png", + }, + + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:signlike", { + description = S("Floor Signlike Drawtype Test Node"), + drawtype = "signlike", + paramtype = "light", + tiles = { "testnodes_signlike.png^[colorize:#FF0000:64" }, + + + walkable = false, + groups = { dig_immediate = 3 }, + sunlight_propagates = true, +}) + + +minetest.register_node("testnodes:signlike_wallmounted", { + description = S("Wallmounted Signlike Drawtype Test Node"), + drawtype = "signlike", + paramtype = "light", + paramtype2 = "wallmounted", + tiles = { "testnodes_signlike.png" }, + + + walkable = false, + groups = { dig_immediate = 3 }, + sunlight_propagates = true, +}) + +minetest.register_node("testnodes:plantlike", { + description = S("Plantlike Drawtype Test Node"), + drawtype = "plantlike", + paramtype = "light", + tiles = { "testnodes_plantlike.png" }, + + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:plantlike_waving", { + description = S("Waving Plantlike Drawtype Test Node"), + drawtype = "plantlike", + paramtype = "light", + tiles = { "testnodes_plantlike_waving.png" }, + waving = 1, + + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:plantlike_wallmounted", { + description = S("Wallmounted Plantlike Drawtype Test Node"), + drawtype = "plantlike", + paramtype = "light", + paramtype2 = "wallmounted", + tiles = { "testnodes_plantlike_wallmounted.png" }, + leveled = 1, + + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + + +-- param2 will rotate +local function rotate_on_rightclick(pos, node, clicker) + local def = minetest.registered_nodes[node.name] + local aux1 = clicker:get_player_control().aux1 + + local deg, deg_max + local color, color_mult = 0, 0 + if def.paramtype2 == "degrotate" then + deg = node.param2 + deg_max = 240 + elseif def.paramtype2 == "colordegrotate" then + -- MSB [3x color, 5x rotation] LSB + deg = node.param2 % 2^5 + deg_max = 24 + color_mult = 2^5 + color = math.floor(node.param2 / color_mult) + end + + deg = (deg + (aux1 and 10 or 1)) % deg_max + node.param2 = color * color_mult + deg + minetest.swap_node(pos, node) + minetest.chat_send_player(clicker:get_player_name(), + "Rotation is now " .. deg .. " / " .. deg_max) +end + +minetest.register_node("testnodes:plantlike_degrotate", { + description = S("Degrotate Plantlike Drawtype Test Node"), + drawtype = "plantlike", + paramtype = "light", + paramtype2 = "degrotate", + tiles = { "testnodes_plantlike_degrotate.png" }, + + on_rightclick = rotate_on_rightclick, + place_param2 = 7, + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:mesh_degrotate", { + description = S("Degrotate Mesh Drawtype Test Node"), + drawtype = "mesh", + paramtype = "light", + paramtype2 = "degrotate", + mesh = "testnodes_ocorner.obj", + tiles = { "testnodes_mesh_stripes2.png" }, + + on_rightclick = rotate_on_rightclick, + place_param2 = 10, -- 15° + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:mesh_colordegrotate", { + description = S("Color Degrotate Mesh Drawtype Test Node"), + drawtype = "mesh", + paramtype = "light", + paramtype2 = "colordegrotate", + palette = "testnodes_palette_facedir.png", + mesh = "testnodes_ocorner.obj", + tiles = { "testnodes_mesh_stripes3.png" }, + + on_rightclick = rotate_on_rightclick, + -- color index 1, 1 step (=15°) rotated + place_param2 = 1 * 2^5 + 1, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +-- param2 will change height +minetest.register_node("testnodes:plantlike_leveled", { + description = S("Leveled Plantlike Drawtype Test Node"), + drawtype = "plantlike", + paramtype = "light", + paramtype2 = "leveled", + tiles = { + { name = "testnodes_plantlike_leveled.png", tileable_vertical = true }, + }, + + + -- We set a default param2 here only for convenience, to make the "plant" visible after placement + place_param2 = 8, + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +-- param2 changes shape +minetest.register_node("testnodes:plantlike_meshoptions", { + description = S("Meshoptions Plantlike Drawtype Test Node"), + drawtype = "plantlike", + paramtype = "light", + paramtype2 = "meshoptions", + tiles = { "testnodes_plantlike_meshoptions.png" }, + + + walkable = false, + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:plantlike_rooted", { + description = S("Rooted Plantlike Drawtype Test Node"), + drawtype = "plantlike_rooted", + paramtype = "light", + tiles = { "testnodes_plantlike_rooted_base.png" }, + special_tiles = { "testnodes_plantlike_rooted.png" }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:plantlike_rooted_wallmounted", { + description = S("Wallmounted Rooted Plantlike Drawtype Test Node"), + drawtype = "plantlike_rooted", + paramtype = "light", + paramtype2 = "wallmounted", + tiles = { + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base_side_wallmounted.png" }, + special_tiles = { "testnodes_plantlike_rooted_wallmounted.png" }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:plantlike_rooted_waving", { + description = S("Waving Rooted Plantlike Drawtype Test Node"), + drawtype = "plantlike_rooted", + paramtype = "light", + tiles = { + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base_side_waving.png", + }, + special_tiles = { "testnodes_plantlike_rooted_waving.png" }, + waving = 1, + + groups = { dig_immediate = 3 }, +}) + +-- param2 changes height +minetest.register_node("testnodes:plantlike_rooted_leveled", { + description = S("Leveled Rooted Plantlike Drawtype Test Node"), + drawtype = "plantlike_rooted", + paramtype = "light", + paramtype2 = "leveled", + tiles = { + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base_side_leveled.png", + }, + special_tiles = { + { name = "testnodes_plantlike_rooted_leveled.png", tileable_vertical = true }, + }, + + + -- We set a default param2 here only for convenience, to make the "plant" visible after placement + place_param2 = 8, + groups = { dig_immediate = 3 }, +}) + +-- param2 changes shape +minetest.register_node("testnodes:plantlike_rooted_meshoptions", { + description = S("Meshoptions Rooted Plantlike Drawtype Test Node"), + drawtype = "plantlike_rooted", + paramtype = "light", + paramtype2 = "meshoptions", + tiles = { + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base_side_meshoptions.png", + }, + special_tiles = { + "testnodes_plantlike_rooted_meshoptions.png", + }, + + groups = { dig_immediate = 3 }, +}) + +-- param2 changes rotation +minetest.register_node("testnodes:plantlike_rooted_degrotate", { + description = S("Degrotate Rooted Plantlike Drawtype Test Node"), + drawtype = "plantlike_rooted", + paramtype = "light", + paramtype2 = "degrotate", + tiles = { + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base_side_degrotate.png", + }, + special_tiles = { + "testnodes_plantlike_rooted_degrotate.png", + }, + + groups = { dig_immediate = 3 }, +}) + +-- Demonstrative liquid nodes, source and flowing form. +-- DRAWTYPE ONLY, NO LIQUID PHYSICS! +-- Liquid ranges 0 to 8 +for r = 0, 8 do + minetest.register_node("testnodes:liquid_"..r, { + description = S("Source Liquid Drawtype Test Node, Range @1", r), + drawtype = "liquid", + paramtype = "light", + tiles = { + "testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100", + }, + special_tiles = { + {name="testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false}, + {name="testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=true}, + }, + use_texture_alpha = "blend", + + + walkable = false, + liquid_range = r, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquid_flowing_"..r, + liquid_alternative_source = "testnodes:liquid_"..r, + groups = { dig_immediate = 3 }, + }) + minetest.register_node("testnodes:liquid_flowing_"..r, { + description = S("Flowing Liquid Drawtype Test Node, Range @1", r), + drawtype = "flowingliquid", + paramtype = "light", + paramtype2 = "flowingliquid", + tiles = { + "testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100", + }, + special_tiles = { + {name="testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false}, + {name="testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false}, + }, + use_texture_alpha = "blend", + + + walkable = false, + liquid_range = r, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquid_flowing_"..r, + liquid_alternative_source = "testnodes:liquid_"..r, + groups = { dig_immediate = 3 }, + }) + +end + +-- Waving liquid test (drawtype only) +minetest.register_node("testnodes:liquid_waving", { + description = S("Waving Source Liquid Drawtype Test Node"), + drawtype = "liquid", + paramtype = "light", + tiles = { + "testnodes_liquidsource.png^[colorize:#0000FF:127", + }, + special_tiles = { + {name="testnodes_liquidsource.png^[colorize:#0000FF:127", backface_culling=false}, + {name="testnodes_liquidsource.png^[colorize:#0000FF:127", backface_culling=true}, + }, + use_texture_alpha = "blend", + waving = 3, + + + walkable = false, + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquid_flowing_waving", + liquid_alternative_source = "testnodes:liquid_waving", + groups = { dig_immediate = 3 }, +}) +minetest.register_node("testnodes:liquid_flowing_waving", { + description = S("Waving Flowing Liquid Drawtype Test Node"), + drawtype = "flowingliquid", + paramtype = "light", + paramtype2 = "flowingliquid", + tiles = { + "testnodes_liquidflowing.png^[colorize:#0000FF:127", + }, + special_tiles = { + {name="testnodes_liquidflowing.png^[colorize:#0000FF:127", backface_culling=false}, + {name="testnodes_liquidflowing.png^[colorize:#0000FF:127", backface_culling=false}, + }, + use_texture_alpha = "blend", + waving = 3, + + + walkable = false, + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquid_flowing_waving", + liquid_alternative_source = "testnodes:liquid_waving", + groups = { dig_immediate = 3 }, +}) + +-- Invisible node +minetest.register_node("testnodes:airlike", { + description = S("Airlike Drawtype Test Node"), + drawtype = "airlike", + paramtype = "light", + + + walkable = false, + groups = { dig_immediate = 3 }, + sunlight_propagates = true, +}) + +-- param2 changes liquid height +minetest.register_node("testnodes:glassliquid", { + description = S("Glasslike Liquid Level Drawtype Test Node"), + drawtype = "glasslike_framed", + paramtype = "light", + paramtype2 = "glasslikeliquidlevel", + tiles = { + "testnodes_glasslikeliquid.png", + }, + special_tiles = { + "testnodes_liquid.png", + }, + + groups = { dig_immediate = 3 }, +}) + +-- Adding many raillike examples, primarily to demonstrate the behavior of +-- "raillike groups". Nodes of the same type (rail, groupless, line, street) +-- should connect to nodes of the same "rail type" (=same shape, different +-- color) only. +local rails = { + { "rail", {"testnodes_rail_straight.png", "testnodes_rail_curved.png", "testnodes_rail_t_junction.png", "testnodes_rail_crossing.png"} }, + { "line", {"testnodes_line_straight.png", "testnodes_line_curved.png", "testnodes_line_t_junction.png", "testnodes_line_crossing.png"}, }, + { "street", {"testnodes_street_straight.png", "testnodes_street_curved.png", "testnodes_street_t_junction.png", "testnodes_street_crossing.png"}, }, + -- the "groupless" nodes are nodes in which the "connect_to_raillike" group is not set + { "groupless", {"testnodes_rail2_straight.png", "testnodes_rail2_curved.png", "testnodes_rail2_t_junction.png", "testnodes_rail2_crossing.png"} }, +} +local colors = { "", "cyan", "red" } + +for r=1, #rails do + local id = rails[r][1] + local tiles = rails[r][2] + local raillike_group + if id ~= "groupless" then + raillike_group = minetest.raillike_group(id) + end + for c=1, #colors do + local color + if colors[c] ~= "" then + color = colors[c] + end + minetest.register_node("testnodes:raillike_"..id..c, { + description = S("Raillike Drawtype Test Node: @1 @2", id, c), + drawtype = "raillike", + paramtype = "light", + tiles = tiles, + groups = { connect_to_raillike = raillike_group, dig_immediate = 3 }, + + + color = color, + selection_box = { + type = "fixed", + fixed = {{-0.5, -0.5, -0.5, 0.5, -0.4, 0.5}}, + }, + sunlight_propagates = true, + walkable = false, + }) + end +end + + + +-- Add visual_scale variants of previous nodes for half and double size +local scale = function(subname, desc_double, desc_half) + local original = "testnodes:"..subname + local def = table.copy(minetest.registered_items[original]) + def.visual_scale = 2.0 + def.description = desc_double + minetest.register_node("testnodes:"..subname.."_double", def) + def = table.copy(minetest.registered_items[original]) + def.visual_scale = 0.5 + def.description = desc_half + minetest.register_node("testnodes:"..subname.."_half", def) +end + +scale("allfaces", + S("Double-sized Allfaces Drawtype Test Node"), + S("Half-sized Allfaces Drawtype Test Node")) +scale("allfaces_optional", + S("Double-sized Allfaces Optional Drawtype Test Node"), + S("Half-sized Allfaces Optional Drawtype Test Node")) +scale("allfaces_optional_waving", + S("Double-sized Waving Allfaces Optional Drawtype Test Node"), + S("Half-sized Waving Allfaces Optional Drawtype Test Node")) +scale("plantlike", + S("Double-sized Plantlike Drawtype Test Node"), + S("Half-sized Plantlike Drawtype Test Node")) +scale("plantlike_wallmounted", + S("Double-sized Wallmounted Plantlike Drawtype Test Node"), + S("Half-sized Wallmounted Plantlike Drawtype Test Node")) +scale("torchlike_wallmounted", + S("Double-sized Wallmounted Torchlike Drawtype Test Node"), + S("Half-sized Wallmounted Torchlike Drawtype Test Node")) +scale("signlike_wallmounted", + S("Double-sized Wallmounted Signlike Drawtype Test Node"), + S("Half-sized Wallmounted Signlike Drawtype Test Node")) +scale("firelike", + S("Double-sized Firelike Drawtype Test Node"), + S("Half-sized Firelike Drawtype Test Node")) diff --git a/games/devtest/mods/testnodes/init.lua b/games/devtest/mods/testnodes/init.lua new file mode 100644 index 0000000..d355c42 --- /dev/null +++ b/games/devtest/mods/testnodes/init.lua @@ -0,0 +1,11 @@ +local path = minetest.get_modpath(minetest.get_current_modname()) + +dofile(path.."/drawtypes.lua") +dofile(path.."/meshes.lua") +dofile(path.."/nodeboxes.lua") +dofile(path.."/param2.lua") +dofile(path.."/properties.lua") +dofile(path.."/liquids.lua") +dofile(path.."/light.lua") +dofile(path.."/textures.lua") +dofile(path.."/overlays.lua") diff --git a/games/devtest/mods/testnodes/light.lua b/games/devtest/mods/testnodes/light.lua new file mode 100644 index 0000000..8ab4416 --- /dev/null +++ b/games/devtest/mods/testnodes/light.lua @@ -0,0 +1,50 @@ +-- Test Nodes: Light test + +local S = minetest.get_translator("testnodes") + +-- All possible light levels +for i=1, minetest.LIGHT_MAX do + minetest.register_node("testnodes:light"..i, { + description = S("Light Source (@1)", i), + paramtype = "light", + light_source = i, + + + tiles ={"testnodes_light_"..i..".png"}, + drawtype = "glasslike", + walkable = false, + sunlight_propagates = true, + is_ground_content = false, + groups = {dig_immediate=3}, + }) +end + +-- Lets light through, but not sunlight, leading to a +-- reduction in light level when light passes through +minetest.register_node("testnodes:sunlight_filter", { + description = S("Sunlight Filter") .."\n".. + S("Lets light through, but weakens sunlight"), + paramtype = "light", + + + drawtype = "glasslike", + tiles = { + "testnodes_sunlight_filter.png", + }, + groups = { dig_immediate = 3 }, +}) + +-- Lets light and sunlight through without obstruction +minetest.register_node("testnodes:sunlight_propagator", { + description = S("Sunlight Propagator") .."\n".. + S("Lets all light through"), + paramtype = "light", + sunlight_propagates = true, + + + drawtype = "glasslike", + tiles = { + "testnodes_sunlight_filter.png^[brighten", + }, + groups = { dig_immediate = 3 }, +}) diff --git a/games/devtest/mods/testnodes/liquids.lua b/games/devtest/mods/testnodes/liquids.lua new file mode 100644 index 0000000..be33814 --- /dev/null +++ b/games/devtest/mods/testnodes/liquids.lua @@ -0,0 +1,134 @@ +-- Add liquids for ranges and viscosity levels 0-8 + +for d=0, 8 do + minetest.register_node("testnodes:rliquid_"..d, { + description = "Test Liquid Source, Range "..d, + drawtype = "liquid", + tiles = {"testnodes_liquidsource_r"..d..".png"}, + special_tiles = { + {name = "testnodes_liquidsource_r"..d..".png", backface_culling = false}, + {name = "testnodes_liquidsource_r"..d..".png", backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "source", + liquid_alternative_flowing = "testnodes:rliquid_flowing_"..d, + liquid_alternative_source = "testnodes:rliquid_"..d, + liquid_range = d, + }) + + minetest.register_node("testnodes:rliquid_flowing_"..d, { + description = "Flowing Test Liquid, Range "..d, + drawtype = "flowingliquid", + tiles = {"testnodes_liquidflowing_r"..d..".png"}, + special_tiles = { + {name = "testnodes_liquidflowing_r"..d..".png", backface_culling = false}, + {name = "testnodes_liquidflowing_r"..d..".png", backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "flowing", + liquid_alternative_flowing = "testnodes:rliquid_flowing_"..d, + liquid_alternative_source = "testnodes:rliquid_"..d, + liquid_range = d, + }) + + if d <= 7 then + + local mod = "^[colorize:#000000:127" + minetest.register_node("testnodes:vliquid_"..d, { + description = "Test Liquid Source, Viscosity/Resistance "..d, + drawtype = "liquid", + tiles = {"testnodes_liquidsource_r"..d..".png"..mod}, + special_tiles = { + {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = false}, + {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "source", + liquid_alternative_flowing = "testnodes:vliquid_flowing_"..d, + liquid_alternative_source = "testnodes:vliquid_"..d, + liquid_viscosity = d, + }) + + minetest.register_node("testnodes:vliquid_flowing_"..d, { + description = "Flowing Test Liquid, Viscosity/Resistance "..d, + drawtype = "flowingliquid", + tiles = {"testnodes_liquidflowing_r"..d..".png"..mod}, + special_tiles = { + {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false}, + {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "flowing", + liquid_alternative_flowing = "testnodes:vliquid_flowing_"..d, + liquid_alternative_source = "testnodes:vliquid_"..d, + liquid_viscosity = d, + }) + + mod = "^[colorize:#000000:192" + local v = 4 + minetest.register_node("testnodes:vrliquid_"..d, { + description = "Test Liquid Source, Viscosity "..v..", Resistance "..d, + drawtype = "liquid", + tiles = {"testnodes_liquidsource_r"..d..".png"..mod}, + special_tiles = { + {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = false}, + {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "source", + liquid_alternative_flowing = "testnodes:vrliquid_flowing_"..d, + liquid_alternative_source = "testnodes:vrliquid_"..d, + liquid_viscosity = v, + move_resistance = d, + }) + + minetest.register_node("testnodes:vrliquid_flowing_"..d, { + description = "Flowing Test Liquid, Viscosity "..v..", Resistance "..d, + drawtype = "flowingliquid", + tiles = {"testnodes_liquidflowing_r"..d..".png"..mod}, + special_tiles = { + {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false}, + {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "flowing", + liquid_alternative_flowing = "testnodes:vrliquid_flowing_"..d, + liquid_alternative_source = "testnodes:vrliquid_"..d, + liquid_viscosity = v, + move_resistance = d, + }) + + end + +end diff --git a/games/devtest/mods/testnodes/meshes.lua b/games/devtest/mods/testnodes/meshes.lua new file mode 100644 index 0000000..900abc1 --- /dev/null +++ b/games/devtest/mods/testnodes/meshes.lua @@ -0,0 +1,145 @@ +-- Meshes + +local S = minetest.get_translator("testnodes") + +local ocorner_cbox = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + {-0.5, -0.25, -0.25, 0.25, 0, 0.5}, + {-0.5, 0, 0, 0, 0.25, 0.5}, + {-0.5, 0.25, 0.25, -0.25, 0.5, 0.5} + } +} + +local tall_pyr_cbox = { + type = "fixed", + fixed = { + { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 }, + { -0.375, -0.25, -0.375, 0.375, 0, 0.375}, + { -0.25, 0, -0.25, 0.25, 0.25, 0.25}, + { -0.125, 0.25, -0.125, 0.125, 0.5, 0.125} + } +} + +-- Normal mesh +minetest.register_node("testnodes:mesh", { + description = S("Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes2.png"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + + groups = {dig_immediate=3}, +}) + +-- Facedir mesh: outer corner slope +minetest.register_node("testnodes:mesh_facedir", { + description = S("Facedir Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_ocorner.obj", + tiles = {"testnodes_mesh_stripes.png"}, + paramtype = "light", + paramtype2 = "facedir", + collision_box = ocorner_cbox, + + groups = {dig_immediate=3}, +}) + +minetest.register_node("testnodes:mesh_colorfacedir", { + description = S("Color Facedir Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_ocorner.obj", + tiles = {"testnodes_mesh_stripes3.png"}, + paramtype = "light", + paramtype2 = "colorfacedir", + palette = "testnodes_palette_facedir.png", + collision_box = ocorner_cbox, + + groups = {dig_immediate=3}, +}) + +-- Wallmounted mesh: pyramid +minetest.register_node("testnodes:mesh_wallmounted", { + description = S("Wallmounted Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes2.png"}, + paramtype = "light", + paramtype2 = "wallmounted", + collision_box = tall_pyr_cbox, + + groups = {dig_immediate=3}, +}) + +minetest.register_node("testnodes:mesh_colorwallmounted", { + description = S("Color Wallmounted Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes3.png"}, + paramtype = "light", + paramtype2 = "colorwallmounted", + palette = "testnodes_palette_wallmounted.png", + collision_box = tall_pyr_cbox, + + groups = {dig_immediate=3}, +}) + + +minetest.register_node("testnodes:mesh_double", { + description = S("Double-sized Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes2.png"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + visual_scale = 2, + + groups = {dig_immediate=3}, +}) +minetest.register_node("testnodes:mesh_half", { + description = S("Half-sized Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes2.png"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + visual_scale = 0.5, + + groups = {dig_immediate=3}, +}) + +minetest.register_node("testnodes:mesh_waving1", { + description = S("Plantlike-waving Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes4.png^[multiply:#B0FFB0"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + waving = 1, + + groups = {dig_immediate=3}, +}) +minetest.register_node("testnodes:mesh_waving2", { + description = S("Leaflike-waving Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes4.png^[multiply:#FFFFB0"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + waving = 2, + + groups = {dig_immediate=3}, +}) +minetest.register_node("testnodes:mesh_waving3", { + description = S("Liquidlike-waving Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes4.png^[multiply:#B0B0FF"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + waving = 3, + + groups = {dig_immediate=3}, +}) diff --git a/games/devtest/mods/testnodes/mod.conf b/games/devtest/mods/testnodes/mod.conf new file mode 100644 index 0000000..d894c34 --- /dev/null +++ b/games/devtest/mods/testnodes/mod.conf @@ -0,0 +1,3 @@ +name = testnodes +description = Contains a bunch of basic example nodes for demonstrative purposes, development and testing +depends = stairs diff --git a/games/devtest/mods/testnodes/models/testnodes_ocorner.obj b/games/devtest/mods/testnodes/models/testnodes_ocorner.obj new file mode 100644 index 0000000..231d705 --- /dev/null +++ b/games/devtest/mods/testnodes/models/testnodes_ocorner.obj @@ -0,0 +1,23 @@ +# Blender v2.73 (sub 0) OBJ File: 'slope_test_ocorner_onetexture.blend' +# www.blender.org +o Cube_Cube.002 +v 0.500000 0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -0.000000 1.000000 +vn -0.707100 0.707100 0.000000 +vn 0.000000 0.707100 -0.707100 +s off +f 3/1/1 2/2/1 4/3/1 5/4/1 +f 1/2/2 3/3/2 5/4/2 +f 1/1/3 2/3/3 3/4/3 +f 1/1/4 4/3/4 2/4/4 +f 1/2/5 5/3/5 4/4/5 diff --git a/games/devtest/mods/testnodes/models/testnodes_pyramid.obj b/games/devtest/mods/testnodes/models/testnodes_pyramid.obj new file mode 100644 index 0000000..b305af2 --- /dev/null +++ b/games/devtest/mods/testnodes/models/testnodes_pyramid.obj @@ -0,0 +1,24 @@ +# Blender v2.73 (sub 0) OBJ File: 'slope_test_pyramid_onetexture.blend' +# www.blender.org +o Cube +v 0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.000000 0.500000 -0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.894400 0.447200 -0.000000 +vn 0.000000 0.447200 -0.894400 +vn 0.894400 0.447200 0.000000 +vn -0.000000 0.447200 0.894400 +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 3/4/2 5/5/2 4/3/2 +f 5/5/3 1/3/3 4/4/3 +f 1/4/4 5/5/4 2/3/4 +f 2/4/5 5/5/5 3/3/5 diff --git a/games/devtest/mods/testnodes/nodeboxes.lua b/games/devtest/mods/testnodes/nodeboxes.lua new file mode 100644 index 0000000..7e966fd --- /dev/null +++ b/games/devtest/mods/testnodes/nodeboxes.lua @@ -0,0 +1,81 @@ +local S = minetest.get_translator("testnodes") + +-- Nodebox examples and tests. + +-- An simple example nodebox with one centered box +minetest.register_node("testnodes:nodebox_fixed", { + description = S("Fixed Nodebox Test Node"), + tiles = {"testnodes_nodebox.png"}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}, + }, + + groups = {dig_immediate=3}, +}) + +-- 50% higher than a regular node +minetest.register_node("testnodes:nodebox_overhigh", { + description = S("+50% high Nodebox Test Node"), + tiles = {"testnodes_nodebox.png"}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 1, 0.5}, + }, + + groups = {dig_immediate=3}, +}) + +-- 95% higher than a regular node +minetest.register_node("testnodes:nodebox_overhigh2", { + description = S("+95% high Nodebox Test Node"), + tiles = {"testnodes_nodebox.png"}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + -- Y max: more is possible, but glitchy + fixed = {-0.5, -0.5, -0.5, 0.5, 1.45, 0.5}, + }, + + groups = {dig_immediate=3}, +}) + +-- Height of nodebox changes with its param2 value +minetest.register_node("testnodes:nodebox_leveled", { + description = S("Leveled Nodebox Test Node"), + tiles = {"testnodes_nodebox.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "leveled", + node_box = { + type = "leveled", + fixed = {-0.5, 0.0, -0.5, 0.5, -0.499, 0.5}, + }, + + groups = {dig_immediate=3}, +}) + +-- Wall-like nodebox that connects to neighbors +minetest.register_node("testnodes:nodebox_connected", { + description = S("Connected Nodebox Test Node"), + tiles = {"testnodes_nodebox.png"}, + groups = {connected_nodebox=1, dig_immediate=3}, + drawtype = "nodebox", + paramtype = "light", + connects_to = {"group:connected_nodebox"}, + connect_sides = {"front", "back", "left", "right"}, + node_box = { + type = "connected", + fixed = {-0.125, -0.500, -0.125, 0.125, 0.500, 0.125}, + connect_front = {-0.125, -0.500, -0.500, 0.125, 0.400, -0.125}, + connect_back = {-0.125, -0.500, 0.125, 0.125, 0.400, 0.500}, + connect_left = {-0.500, -0.500, -0.125, -0.125, 0.400, 0.125}, + connect_right = {0.125, -0.500, -0.125, 0.500, 0.400, 0.125}, + }, +}) + diff --git a/games/devtest/mods/testnodes/overlays.lua b/games/devtest/mods/testnodes/overlays.lua new file mode 100644 index 0000000..294e06a --- /dev/null +++ b/games/devtest/mods/testnodes/overlays.lua @@ -0,0 +1,93 @@ +local S = minetest.get_translator("testnodes") + +minetest.register_node("testnodes:overlay", { + description = S("Texture Overlay Test Node") .. "\n" .. + S("Uncolorized"), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + groups = { dig_immediate = 2 }, +}) +minetest.register_node("testnodes:overlay_color_all", { + description = S("Texture Overlay Test Node, Colorized") .. "\n" .. + S("param2 changes color"), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) +minetest.register_node("testnodes:overlay_color_overlay", { + description = S("Texture Overlay Test Node, Colorized Overlay") .. "\n" .. + S("param2 changes color of overlay"), + tiles = {{name = "testnodes_overlayable.png", color="white"}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) +minetest.register_node("testnodes:overlay_color_overlayed", { + description = S("Texture Overlay Test Node, Colorized Base") .. "\n" .. + S("param2 changes color of base texture"), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png", color="white"}}, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) + +local global_overlay_color = "#FF2000" +minetest.register_node("testnodes:overlay_global", { + description = S("Texture Overlay Test Node, Global Color") .. "\n" .. + S("Global color = @1", global_overlay_color), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + color = global_overlay_color, + + + groups = { dig_immediate = 2 }, +}) +minetest.register_node("testnodes:overlay_global_color_all", { + description = S("Texture Overlay Test Node, Global Color + Colorized") .. "\n" .. + S("Global color = @1", global_overlay_color) .. "\n" .. + S("param2 changes color"), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + color = global_overlay_color, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) +minetest.register_node("testnodes:overlay_global_color_overlay", { + description = S("Texture Overlay Test Node, Global Color + Colorized Overlay") .. "\n" .. + S("Global color = @1", global_overlay_color) .. "\n" .. + S("param2 changes color of overlay"), + tiles = {{name = "testnodes_overlayable.png", color=global_overlay_color}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + color = global_overlay_color, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) +minetest.register_node("testnodes:overlay_global_color_overlayed", { + description = S("Texture Overlay Test Node, Global Color + Colorized Base") .. "\n" .. + S("Global color = @1", global_overlay_color) .. "\n" .. + S("param2 changes color of base texture"), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png", color=global_overlay_color}}, + color = global_overlay_color, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) diff --git a/games/devtest/mods/testnodes/param2.lua b/games/devtest/mods/testnodes/param2.lua new file mode 100644 index 0000000..5d64376 --- /dev/null +++ b/games/devtest/mods/testnodes/param2.lua @@ -0,0 +1,168 @@ +-- This file is for misc. param2 tests that aren't covered in drawtypes.lua already. + +local S = minetest.get_translator("testnodes") + +minetest.register_node("testnodes:facedir", { + description = S("Facedir Test Node"), + paramtype2 = "facedir", + tiles = { + "testnodes_1.png", + "testnodes_2.png", + "testnodes_3.png", + "testnodes_4.png", + "testnodes_5.png", + "testnodes_6.png", + }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:facedir_nodebox", { + description = S("Facedir Nodebox Test Node"), + tiles = { + "testnodes_1.png", + "testnodes_2.png", + "testnodes_3.png", + "testnodes_4.png", + "testnodes_5.png", + "testnodes_6.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.2, 0.2, 0.2}, + }, + + groups = {dig_immediate=3}, +}) + +minetest.register_node("testnodes:wallmounted", { + description = S("Wallmounted Test Node"), + paramtype2 = "wallmounted", + tiles = { + "testnodes_1w.png", + "testnodes_2w.png", + "testnodes_3w.png", + "testnodes_4w.png", + "testnodes_5w.png", + "testnodes_6w.png", + }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:wallmounted_nodebox", { + description = S("Wallmounted Nodebox Test Node"), + paramtype2 = "wallmounted", + paramtype = "light", + tiles = { + "testnodes_1w.png", + "testnodes_2w.png", + "testnodes_3w.png", + "testnodes_4w.png", + "testnodes_5w.png", + "testnodes_6w.png", + }, + drawtype = "nodebox", + node_box = { + type = "wallmounted", + wall_top = { -0.5, 0, -0.5, 0.5, 0.5, 0.5 }, + wall_bottom = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 }, + wall_side = { -0.5, -0.5, -0.5, 0, 0.5, 0.5 }, + }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:color", { + description = S("Color Test Node"), + paramtype2 = "color", + palette = "testnodes_palette_full.png", + tiles = { + "testnodes_node.png", + }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:colorfacedir", { + description = S("Color Facedir Test Node"), + paramtype2 = "colorfacedir", + palette = "testnodes_palette_facedir.png", + tiles = { + "testnodes_1g.png", + "testnodes_2g.png", + "testnodes_3g.png", + "testnodes_4g.png", + "testnodes_5g.png", + "testnodes_6g.png", + }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:colorfacedir_nodebox", { + description = S("Color Facedir Nodebox Test Node"), + tiles = { + "testnodes_1g.png", + "testnodes_2g.png", + "testnodes_3g.png", + "testnodes_4g.png", + "testnodes_5g.png", + "testnodes_6g.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "colorfacedir", + palette = "testnodes_palette_facedir.png", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.2, 0.2, 0.2}, + }, + + groups = {dig_immediate=3}, +}) + +minetest.register_node("testnodes:colorwallmounted", { + description = S("Color Wallmounted Test Node"), + paramtype2 = "colorwallmounted", + paramtype = "light", + palette = "testnodes_palette_wallmounted.png", + tiles = { + "testnodes_1wg.png", + "testnodes_2wg.png", + "testnodes_3wg.png", + "testnodes_4wg.png", + "testnodes_5wg.png", + "testnodes_6wg.png", + }, + + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:colorwallmounted_nodebox", { + description = S("Color Wallmounted Nodebox Test Node"), + paramtype2 = "colorwallmounted", + paramtype = "light", + palette = "testnodes_palette_wallmounted.png", + tiles = { + "testnodes_1wg.png", + "testnodes_2wg.png", + "testnodes_3wg.png", + "testnodes_4wg.png", + "testnodes_5wg.png", + "testnodes_6wg.png", + }, + drawtype = "nodebox", + node_box = { + type = "wallmounted", + wall_top = { -0.5, 0, -0.5, 0.5, 0.5, 0.5 }, + wall_bottom = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 }, + wall_side = { -0.5, -0.5, -0.5, 0, 0.5, 0.5 }, + }, + + groups = { dig_immediate = 3 }, +}) + diff --git a/games/devtest/mods/testnodes/properties.lua b/games/devtest/mods/testnodes/properties.lua new file mode 100644 index 0000000..bacd555 --- /dev/null +++ b/games/devtest/mods/testnodes/properties.lua @@ -0,0 +1,397 @@ +-- Test Nodes: Node property tests + +local S = minetest.get_translator("testnodes") + +-- Is supposed to fall when it doesn't rest on solid ground +minetest.register_node("testnodes:falling", { + description = S("Falling Node"), + tiles = { + "testnodes_node.png", + "testnodes_node.png", + "testnodes_node_falling.png", + }, + groups = { falling_node = 1, dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:falling_facedir", { + description = S("Falling Facedir Node"), + tiles = { + "testnodes_1.png", + "testnodes_2.png", + "testnodes_3.png", + "testnodes_4.png", + "testnodes_5.png", + "testnodes_6.png", + }, + paramtype2 = "facedir", + groups = { falling_node = 1, dig_immediate = 3 }, +}) + +-- Same as falling node, but will stop falling on top of liquids +minetest.register_node("testnodes:falling_float", { + description = S("Falling+Floating Node"), + groups = { falling_node = 1, float = 1, dig_immediate = 3 }, + + + tiles = { + "testnodes_node.png", + "testnodes_node.png", + "testnodes_node_falling.png", + }, + color = "cyan", +}) + +-- This node attaches to the floor and drops as item +-- when the floor is gone. +minetest.register_node("testnodes:attached", { + description = S("Floor-Attached Node"), + tiles = { + "testnodes_attached_top.png", + "testnodes_attached_bottom.png", + "testnodes_attached_side.png", + }, + groups = { attached_node = 1, dig_immediate = 3 }, +}) + +-- This node attaches to the side of a node and drops as item +-- when the node it attaches to is gone. +minetest.register_node("testnodes:attached_wallmounted", { + description = S("Wallmounted Attached Node"), + paramtype2 = "wallmounted", + tiles = { + "testnodes_attachedw_top.png", + "testnodes_attachedw_bottom.png", + "testnodes_attachedw_side.png", + }, + groups = { attached_node = 1, dig_immediate = 3 }, +}) + +-- Jump disabled +minetest.register_node("testnodes:nojump", { + description = S("Non-jumping Node"), + groups = {disable_jump=1, dig_immediate=3}, + tiles = {"testnodes_nojump_top.png", "testnodes_nojump_side.png"}, +}) + +-- Jump disabled plant +minetest.register_node("testnodes:nojump_walkable", { + description = S("Non-jumping Plant Node"), + drawtype = "plantlike", + groups = {disable_jump=1, dig_immediate=3}, + walkable = false, + tiles = {"testnodes_nojump_top.png"}, +}) + +-- Climbable up and down with jump and sneak keys +minetest.register_node("testnodes:climbable", { + description = S("Climbable Node"), + climbable = true, + walkable = false, + + + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + tiles ={"testnodes_climbable_side.png"}, + drawtype = "glasslike", + groups = {dig_immediate=3}, +}) + +-- Climbable only downwards with sneak key +minetest.register_node("testnodes:climbable_nojump", { + description = S("Downwards-climbable Node"), + climbable = true, + walkable = false, + + groups = {disable_jump=1, dig_immediate=3}, + drawtype = "glasslike", + tiles ={"testnodes_climbable_nojump_side.png"}, + paramtype = "light", + sunlight_propagates = true, +}) + +-- A liquid in which you can't rise +minetest.register_node("testnodes:liquid_nojump", { + description = S("Non-jumping Liquid Source Node"), + liquidtype = "source", + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquidflowing_nojump", + liquid_alternative_source = "testnodes:liquid_nojump", + liquid_renewable = false, + groups = {disable_jump=1, dig_immediate=3}, + walkable = false, + + drawtype = "liquid", + tiles = {"testnodes_liquidsource.png^[colorize:#FF0000:127"}, + special_tiles = { + {name = "testnodes_liquidsource.png^[colorize:#FF0000:127", backface_culling = false}, + {name = "testnodes_liquidsource.png^[colorize:#FF0000:127", backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + pointable = false, + liquids_pointable = true, + buildable_to = true, + is_ground_content = false, + post_effect_color = {a = 70, r = 255, g = 0, b = 200}, +}) + +-- A liquid in which you can't rise (flowing variant) +minetest.register_node("testnodes:liquidflowing_nojump", { + description = S("Non-jumping Flowing Liquid Node"), + liquidtype = "flowing", + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquidflowing_nojump", + liquid_alternative_source = "testnodes:liquid_nojump", + liquid_renewable = false, + groups = {disable_jump=1, dig_immediate=3}, + walkable = false, + + + drawtype = "flowingliquid", + tiles = {"testnodes_liquidflowing.png^[colorize:#FF0000:127"}, + special_tiles = { + {name = "testnodes_liquidflowing.png^[colorize:#FF0000:127", backface_culling = false}, + {name = "testnodes_liquidflowing.png^[colorize:#FF0000:127", backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + pointable = false, + liquids_pointable = true, + buildable_to = true, + is_ground_content = false, + post_effect_color = {a = 70, r = 255, g = 0, b = 200}, +}) + +-- A liquid which doesn't have liquid movement physics (source variant) +minetest.register_node("testnodes:liquid_noswim", { + description = S("No-swim Liquid Source Node"), + liquidtype = "source", + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquidflowing_noswim", + liquid_alternative_source = "testnodes:liquid_noswim", + liquid_renewable = false, + liquid_move_physics = false, + groups = {dig_immediate=3}, + walkable = false, + + drawtype = "liquid", + tiles = {"testnodes_liquidsource.png^[colorize:#FF00FF:127"}, + special_tiles = { + {name = "testnodes_liquidsource.png^[colorize:#FF00FF:127", backface_culling = false}, + {name = "testnodes_liquidsource.png^[colorize:#FF00FF:127", backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + pointable = false, + liquids_pointable = true, + buildable_to = true, + is_ground_content = false, + post_effect_color = {a = 70, r = 255, g = 200, b = 200}, +}) + +-- A liquid which doen't have liquid movement physics (flowing variant) +minetest.register_node("testnodes:liquidflowing_noswim", { + description = S("No-swim Flowing Liquid Node"), + liquidtype = "flowing", + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquidflowing_noswim", + liquid_alternative_source = "testnodes:liquid_noswim", + liquid_renewable = false, + liquid_move_physics = false, + groups = {dig_immediate=3}, + walkable = false, + + + drawtype = "flowingliquid", + tiles = {"testnodes_liquidflowing.png^[colorize:#FF00FF:127"}, + special_tiles = { + {name = "testnodes_liquidflowing.png^[colorize:#FF00FF:127", backface_culling = false}, + {name = "testnodes_liquidflowing.png^[colorize:#FF00FF:127", backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + pointable = false, + liquids_pointable = true, + buildable_to = true, + is_ground_content = false, + post_effect_color = {a = 70, r = 255, g = 200, b = 200}, +}) + + + +-- Nodes that modify fall damage (various damage modifiers) +for i=-100, 100, 25 do + if i ~= 0 then + local subname, descnum + if i < 0 then + subname = "m"..math.abs(i) + descnum = tostring(i) + else + subname = tostring(i) + descnum = S("+@1", i) + end + local tex, color, desc + if i > 0 then + local val = math.floor((i/100)*255) + tex = "testnodes_fall_damage_plus.png" + color = { b=0, g=255-val, r=255, a=255 } + desc = S("Fall Damage Node (+@1%)", i) + else + tex = "testnodes_fall_damage_minus.png" + if i == -100 then + color = { r=0, b=0, g=255, a=255 } + else + local val = math.floor((math.abs(i)/100)*255) + color = { r=0, b=255, g=255-val, a=255 } + end + desc = S("Fall Damage Node (-@1%)", math.abs(i)) + end + minetest.register_node("testnodes:damage"..subname, { + description = desc, + groups = {fall_damage_add_percent=i, dig_immediate=3}, + + + tiles = { tex }, + is_ground_content = false, + color = color, + }) + end +end + +-- Bouncy nodes (various bounce levels) +for i=-140, 180, 20 do + local val = math.floor(((i-20)/200)*255) + minetest.register_node(("testnodes:bouncy"..i):gsub("-","NEG"), { + description = S("Bouncy Node (@1%)", i), + groups = {bouncy=i, dig_immediate=3}, + + + tiles ={"testnodes_bouncy.png"}, + is_ground_content = false, + color = { r=255, g=255-val, b=val, a=255 }, + }) +end + +-- Slippery nodes (various slippery levels) +for i=1, 5 do + minetest.register_node("testnodes:slippery"..i, { + description = S("Slippery Node (@1)", i), + tiles ={"testnodes_slippery.png"}, + is_ground_content = false, + groups = {slippery=i, dig_immediate=3}, + color = { r=0, g=255, b=math.floor((i/5)*255), a=255 }, + }) +end + +-- Move resistance nodes (various resistance levels) +for r=0, 7 do + if r > 0 then + minetest.register_node("testnodes:move_resistance"..r, { + description = S("Move-resistant Node (@1)", r), + walkable = false, + move_resistance = r, + + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_move_resistance.png" }, + is_ground_content = false, + groups = { dig_immediate = 3 }, + color = { b = 0, g = 255, r = math.floor((r/7)*255), a = 255 }, + }) + end + + minetest.register_node("testnodes:move_resistance_liquidlike"..r, { + description = S("Move-resistant Node, liquidlike (@1)", r), + walkable = false, + move_resistance = r, + liquid_move_physics = true, + + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_move_resistance.png" }, + is_ground_content = false, + groups = { dig_immediate = 3 }, + color = { b = 255, g = 0, r = math.floor((r/7)*255), a = 255 }, + }) +end + +minetest.register_node("testnodes:climbable_move_resistance_4", { + description = S("Climbable Move-resistant Node (4)"), + walkable = false, + climbable = true, + move_resistance = 4, + + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = {"testnodes_climbable_resistance_side.png"}, + is_ground_content = false, + groups = { dig_immediate = 3 }, +}) + +-- By placing something on the node, the node itself will be replaced +minetest.register_node("testnodes:buildable_to", { + description = S("Replacable Node"), + buildable_to = true, + tiles = {"testnodes_buildable_to.png"}, + is_ground_content = false, + groups = {dig_immediate=3}, +}) + +-- Nodes that deal damage to players that are inside them. +-- Negative damage nodes should heal. +for d=-3,3 do + if d ~= 0 then + local sub, tile + if d > 0 then + sub = tostring(d) + tile = "testnodes_damage.png" + else + sub = "m" .. tostring(math.abs(d)) + tile = "testnodes_damage_neg.png" + end + if math.abs(d) == 2 then + tile = tile .. "^[colorize:#000000:70" + elseif math.abs(d) == 3 then + tile = tile .. "^[colorize:#000000:140" + end + minetest.register_node("testnodes:damage_"..sub, { + description = S("Damage Node (@1 damage per second)", d), + damage_per_second = d, + + + walkable = false, + is_ground_content = false, + drawtype = "allfaces", + paramtype = "light", + sunlight_propagates = true, + tiles = { tile }, + groups = {dig_immediate=3}, + }) + end +end + +-- Causes drowning damage +minetest.register_node("testnodes:drowning_1", { + description = S("Drowning Node (@1 damage)", 1), + drowning = 1, + + + walkable = false, + is_ground_content = false, + drawtype = "allfaces", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_drowning.png" }, + groups = {dig_immediate=3}, +}) + diff --git a/games/devtest/mods/testnodes/textures.lua b/games/devtest/mods/testnodes/textures.lua new file mode 100644 index 0000000..2faacdd --- /dev/null +++ b/games/devtest/mods/testnodes/textures.lua @@ -0,0 +1,290 @@ +-- Node texture tests + +local S = minetest.get_translator("testnodes") + +minetest.register_node("testnodes:6sides", { + description = S("Six Textures Test Node"), + tiles = { + "testnodes_normal1.png", + "testnodes_normal2.png", + "testnodes_normal3.png", + "testnodes_normal4.png", + "testnodes_normal5.png", + "testnodes_normal6.png", + }, + + groups = { dig_immediate = 2 }, +}) + +minetest.register_node("testnodes:anim", { + description = S("Animated Test Node"), + tiles = { + { name = "testnodes_anim.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 4.0, + }, }, + }, + + groups = { dig_immediate = 2 }, +}) + +-- Node texture transparency test + +local alphas = { 64, 128, 191 } + +for a=1,#alphas do + local alpha = alphas[a] + + -- Transparency taken from texture + minetest.register_node("testnodes:alpha_texture_"..alpha, { + description = S("Texture Alpha Test Node (@1)", alpha), + drawtype = "glasslike", + paramtype = "light", + tiles = { + "testnodes_alpha"..alpha..".png", + }, + use_texture_alpha = "blend", + + groups = { dig_immediate = 3 }, + }) + + -- Transparency set via texture modifier + minetest.register_node("testnodes:alpha_"..alpha, { + description = S("Alpha Test Node (@1)", alpha), + drawtype = "glasslike", + paramtype = "light", + tiles = { + "testnodes_alpha.png^[opacity:" .. alpha, + }, + use_texture_alpha = "blend", + + groups = { dig_immediate = 3 }, + }) +end + +-- Generate PNG textures + +local function mandelbrot(w, h, iterations) + local r = {} + for y=0, h-1 do + for x=0, w-1 do + local re = (x - w/2) * 4/w + local im = (y - h/2) * 4/h + -- zoom in on a nice view + re = re / 128 - 0.23 + im = im / 128 - 0.82 + + local px, py = 0, 0 + local i = 0 + while px*px + py*py <= 4 and i < iterations do + px, py = px*px - py*py + re, 2 * px * py + im + i = i + 1 + end + r[w*y+x+1] = i / iterations + end + end + return r +end + +local function gen_checkers(w, h, tile) + local r = {} + for y=0, h-1 do + for x=0, w-1 do + local hori = math.floor(x / tile) % 2 == 0 + local vert = math.floor(y / tile) % 2 == 0 + r[w*y+x+1] = hori ~= vert and 1 or 0 + end + end + return r +end + +local fractal = mandelbrot(512, 512, 128) +local frac_emb = mandelbrot(64, 64, 64) +local checker = gen_checkers(512, 512, 32) + +local floor = math.floor +local abs = math.abs +local data_emb = {} +local data_mb = {} +local data_ck = {} +for i=1, #frac_emb do + data_emb[i] = { + r = floor(abs(frac_emb[i] * 2 - 1) * 255), + g = floor(abs(1 - frac_emb[i]) * 255), + b = floor(frac_emb[i] * 255), + a = frac_emb[i] < 0.95 and 255 or 0, + } +end +for i=1, #fractal do + data_mb[i] = { + r = floor(fractal[i] * 255), + g = floor(abs(fractal[i] * 2 - 1) * 255), + b = floor(abs(1 - fractal[i]) * 255), + a = 255, + } + data_ck[i] = checker[i] > 0 and "#F80" or "#000" +end + +local textures_path = minetest.get_modpath( minetest.get_current_modname() ) .. "/textures/" +minetest.safe_file_write( + textures_path .. "testnodes_generated_mb.png", + minetest.encode_png(512,512,data_mb) +) +minetest.safe_file_write( + textures_path .. "testnodes_generated_ck.png", + minetest.encode_png(512,512,data_ck) +) + +minetest.register_node("testnodes:generated_png_mb", { + description = S("Generated Mandelbrot PNG Test Node"), + tiles = { "testnodes_generated_mb.png" }, + + groups = { dig_immediate = 2 }, +}) +minetest.register_node("testnodes:generated_png_ck", { + description = S("Generated Checker PNG Test Node"), + tiles = { "testnodes_generated_ck.png" }, + + groups = { dig_immediate = 2 }, +}) + +local png_emb = "[png:" .. minetest.encode_base64(minetest.encode_png(64,64,data_emb)) + +minetest.register_node("testnodes:generated_png_emb", { + description = S("Generated In-Band Mandelbrot PNG Test Node"), + tiles = { png_emb }, + + groups = { dig_immediate = 2 }, +}) +minetest.register_node("testnodes:generated_png_src_emb", { + description = S("Generated In-Band Source Blit Mandelbrot PNG Test Node"), + tiles = { png_emb .. "^testnodes_damage_neg.png" }, + + groups = { dig_immediate = 2 }, +}) +minetest.register_node("testnodes:generated_png_dst_emb", { + description = S("Generated In-Band Dest Blit Mandelbrot PNG Test Node"), + tiles = { "testnodes_generated_ck.png^" .. png_emb }, + + groups = { dig_immediate = 2 }, +}) + +--[[ + +The following nodes can be used to demonstrate the TGA format support. + +Minetest supports TGA types 1, 2, 3 & 10. While adding the support for +TGA type 9 (RLE-compressed, color-mapped) is easy, it is not advisable +to do so, as it is not backwards compatible with any Minetest pre-5.5; +content creators should therefore either use TGA type 1 or 10, or PNG. + +TODO: Types 1, 2 & 10 should have two test nodes each (i.e. bottom-top +and top-bottom) for 16bpp (A1R5G5B5), 24bpp (B8G8R8), 32bpp (B8G8R8A8) +colors. + +Note: Minetest requires the optional TGA footer for a texture to load. +If a TGA image does not load in Minetest, append eight (8) null bytes, +then the string “TRUEVISION-XFILE.”, then another null byte. + +]]-- + +minetest.register_node("testnodes:tga_type1_24bpp_bt", { + description = S("TGA Type 1 (color-mapped RGB) 24bpp bottom-top Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type1_24bpp_bt.tga" }, + groups = { dig_immediate = 2 }, +}) + +minetest.register_node("testnodes:tga_type1_24bpp_tb", { + description = S("TGA Type 1 (color-mapped RGB) 24bpp top-bottom Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type1_24bpp_tb.tga" }, + groups = { dig_immediate = 2 }, +}) + +minetest.register_node("testnodes:tga_type2_16bpp_bt", { + description = S("TGA Type 2 (uncompressed RGB) 16bpp bottom-top Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type2_16bpp_bt.tga" }, + use_texture_alpha = "clip", + groups = { dig_immediate = 2 }, +}) + +minetest.register_node("testnodes:tga_type2_16bpp_tb", { + description = S("TGA Type 2 (uncompressed RGB) 16bpp top-bottom Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type2_16bpp_tb.tga" }, + use_texture_alpha = "clip", + groups = { dig_immediate = 2 }, +}) + +minetest.register_node("testnodes:tga_type2_32bpp_bt", { + description = S("TGA Type 2 (uncompressed RGB) 32bpp bottom-top Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type2_32bpp_bt.tga" }, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) + +minetest.register_node("testnodes:tga_type2_32bpp_tb", { + description = S("TGA Type 2 (uncompressed RGB) 32bpp top-bottom Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type2_32bpp_tb.tga" }, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) + +minetest.register_node("testnodes:tga_type3_16bpp_bt", { + description = S("TGA Type 3 (uncompressed grayscale) 16bpp bottom-top Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type3_16bpp_bt.tga" }, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) + +minetest.register_node("testnodes:tga_type3_16bpp_tb", { + description = S("TGA Type 3 (uncompressed grayscale) 16bpp top-bottom Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type3_16bpp_tb.tga" }, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) + +minetest.register_node("testnodes:tga_type10_32bpp_bt", { + description = S("TGA Type 10 (RLE-compressed RGB) 32bpp bottom-top Test Node"), + tiles = { "testnodes_tga_type10_32bpp_bt.tga" }, + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) + +minetest.register_node("testnodes:tga_type10_32bpp_tb", { + description = S("TGA Type 10 (RLE-compressed RGB) 32bpp top-bottom Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type10_32bpp_tb.tga" }, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) diff --git a/games/devtest/mods/testnodes/textures/testnodes_1.png b/games/devtest/mods/testnodes/textures/testnodes_1.png new file mode 100644 index 0000000..6730997 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_1.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_1g.png b/games/devtest/mods/testnodes/textures/testnodes_1g.png new file mode 100644 index 0000000..529298e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_1g.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_1w.png b/games/devtest/mods/testnodes/textures/testnodes_1w.png new file mode 100644 index 0000000..d24e571 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_1w.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_1wg.png b/games/devtest/mods/testnodes/textures/testnodes_1wg.png new file mode 100644 index 0000000..b2eba0e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_1wg.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_2.png b/games/devtest/mods/testnodes/textures/testnodes_2.png new file mode 100644 index 0000000..6c87c86 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_2.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_2g.png b/games/devtest/mods/testnodes/textures/testnodes_2g.png new file mode 100644 index 0000000..cb9060f Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_2g.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_2w.png b/games/devtest/mods/testnodes/textures/testnodes_2w.png new file mode 100644 index 0000000..b56874e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_2w.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_2wg.png b/games/devtest/mods/testnodes/textures/testnodes_2wg.png new file mode 100644 index 0000000..108dc87 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_2wg.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_3.png b/games/devtest/mods/testnodes/textures/testnodes_3.png new file mode 100644 index 0000000..05b4562 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_3.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_3g.png b/games/devtest/mods/testnodes/textures/testnodes_3g.png new file mode 100644 index 0000000..5c84f58 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_3g.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_3w.png b/games/devtest/mods/testnodes/textures/testnodes_3w.png new file mode 100644 index 0000000..8b435cf Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_3w.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_3wg.png b/games/devtest/mods/testnodes/textures/testnodes_3wg.png new file mode 100644 index 0000000..9ee9006 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_3wg.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_4.png b/games/devtest/mods/testnodes/textures/testnodes_4.png new file mode 100644 index 0000000..15e6ffe Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_4.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_4g.png b/games/devtest/mods/testnodes/textures/testnodes_4g.png new file mode 100644 index 0000000..8f144fa Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_4g.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_4w.png b/games/devtest/mods/testnodes/textures/testnodes_4w.png new file mode 100644 index 0000000..214e0df Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_4w.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_4wg.png b/games/devtest/mods/testnodes/textures/testnodes_4wg.png new file mode 100644 index 0000000..888b3d4 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_4wg.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_5.png b/games/devtest/mods/testnodes/textures/testnodes_5.png new file mode 100644 index 0000000..1ef1c72 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_5.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_5g.png b/games/devtest/mods/testnodes/textures/testnodes_5g.png new file mode 100644 index 0000000..30da479 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_5g.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_5w.png b/games/devtest/mods/testnodes/textures/testnodes_5w.png new file mode 100644 index 0000000..b4cb424 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_5w.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_5wg.png b/games/devtest/mods/testnodes/textures/testnodes_5wg.png new file mode 100644 index 0000000..fac9db2 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_5wg.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_6.png b/games/devtest/mods/testnodes/textures/testnodes_6.png new file mode 100644 index 0000000..805813e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_6.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_6g.png b/games/devtest/mods/testnodes/textures/testnodes_6g.png new file mode 100644 index 0000000..a88f4c9 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_6g.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_6w.png b/games/devtest/mods/testnodes/textures/testnodes_6w.png new file mode 100644 index 0000000..e6bbf97 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_6w.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_6wg.png b/games/devtest/mods/testnodes/textures/testnodes_6wg.png new file mode 100644 index 0000000..29ca933 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_6wg.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_airlike.png b/games/devtest/mods/testnodes/textures/testnodes_airlike.png new file mode 100644 index 0000000..5a5664a Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_airlike.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_allfaces.png b/games/devtest/mods/testnodes/textures/testnodes_allfaces.png new file mode 100644 index 0000000..c0a7dc5 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_allfaces.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_allfaces_optional.png b/games/devtest/mods/testnodes/textures/testnodes_allfaces_optional.png new file mode 100644 index 0000000..1f6a173 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_allfaces_optional.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_alpha.png b/games/devtest/mods/testnodes/textures/testnodes_alpha.png new file mode 100644 index 0000000..157fa73 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_alpha.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_alpha128.png b/games/devtest/mods/testnodes/textures/testnodes_alpha128.png new file mode 100644 index 0000000..16babf6 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_alpha128.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_alpha191.png b/games/devtest/mods/testnodes/textures/testnodes_alpha191.png new file mode 100644 index 0000000..f165d28 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_alpha191.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_alpha64.png b/games/devtest/mods/testnodes/textures/testnodes_alpha64.png new file mode 100644 index 0000000..c343c32 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_alpha64.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_anim.png b/games/devtest/mods/testnodes/textures/testnodes_anim.png new file mode 100644 index 0000000..d321fe8 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_anim.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_attached_bottom.png b/games/devtest/mods/testnodes/textures/testnodes_attached_bottom.png new file mode 100644 index 0000000..e01ae57 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_attached_bottom.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_attached_side.png b/games/devtest/mods/testnodes/textures/testnodes_attached_side.png new file mode 100644 index 0000000..9459cbb Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_attached_side.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_attached_top.png b/games/devtest/mods/testnodes/textures/testnodes_attached_top.png new file mode 100644 index 0000000..0148b41 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_attached_top.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_attachedw_bottom.png b/games/devtest/mods/testnodes/textures/testnodes_attachedw_bottom.png new file mode 100644 index 0000000..488ad23 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_attachedw_bottom.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_attachedw_side.png b/games/devtest/mods/testnodes/textures/testnodes_attachedw_side.png new file mode 100644 index 0000000..a02facb Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_attachedw_side.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_attachedw_top.png b/games/devtest/mods/testnodes/textures/testnodes_attachedw_top.png new file mode 100644 index 0000000..1f4fc7b Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_attachedw_top.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_bouncy.png b/games/devtest/mods/testnodes/textures/testnodes_bouncy.png new file mode 100644 index 0000000..eabbbdf Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_bouncy.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_buildable_to.png b/games/devtest/mods/testnodes/textures/testnodes_buildable_to.png new file mode 100644 index 0000000..23b5e54 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_buildable_to.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_climbable_nojump_side.png b/games/devtest/mods/testnodes/textures/testnodes_climbable_nojump_side.png new file mode 100644 index 0000000..d5ca130 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_climbable_nojump_side.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_climbable_resistance_side.png b/games/devtest/mods/testnodes/textures/testnodes_climbable_resistance_side.png new file mode 100644 index 0000000..be01583 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_climbable_resistance_side.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_climbable_side.png b/games/devtest/mods/testnodes/textures/testnodes_climbable_side.png new file mode 100644 index 0000000..c56ea90 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_climbable_side.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_damage.png b/games/devtest/mods/testnodes/textures/testnodes_damage.png new file mode 100644 index 0000000..9de2ab5 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_damage.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_damage_neg.png b/games/devtest/mods/testnodes/textures/testnodes_damage_neg.png new file mode 100644 index 0000000..85811bc Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_damage_neg.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_drowning.png b/games/devtest/mods/testnodes/textures/testnodes_drowning.png new file mode 100644 index 0000000..57ffc8f Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_drowning.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_fall_damage_minus.png b/games/devtest/mods/testnodes/textures/testnodes_fall_damage_minus.png new file mode 100644 index 0000000..88d3bdf Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_fall_damage_minus.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_fall_damage_plus.png b/games/devtest/mods/testnodes/textures/testnodes_fall_damage_plus.png new file mode 100644 index 0000000..61fdec2 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_fall_damage_plus.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_fencelike.png b/games/devtest/mods/testnodes/textures/testnodes_fencelike.png new file mode 100644 index 0000000..84dea1b Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_fencelike.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_firelike.png b/games/devtest/mods/testnodes/textures/testnodes_firelike.png new file mode 100644 index 0000000..ee59b0d Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_firelike.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslike.png b/games/devtest/mods/testnodes/textures/testnodes_glasslike.png new file mode 100644 index 0000000..cf3e354 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_glasslike.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslike_detail.png b/games/devtest/mods/testnodes/textures/testnodes_glasslike_detail.png new file mode 100644 index 0000000..30c9586 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_glasslike_detail.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed.png b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed.png new file mode 100644 index 0000000..8a513f2 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed2.png b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed2.png new file mode 100644 index 0000000..4ea839c Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed2.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed_optional.png b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed_optional.png new file mode 100644 index 0000000..37de77d Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_glasslike_framed_optional.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_glasslikeliquid.png b/games/devtest/mods/testnodes/textures/testnodes_glasslikeliquid.png new file mode 100644 index 0000000..e1e96ff Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_glasslikeliquid.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light.png b/games/devtest/mods/testnodes/textures/testnodes_light.png new file mode 100644 index 0000000..4ba0081 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_1.png b/games/devtest/mods/testnodes/textures/testnodes_light_1.png new file mode 100644 index 0000000..57adf5a Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_1.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_10.png b/games/devtest/mods/testnodes/textures/testnodes_light_10.png new file mode 100644 index 0000000..4838347 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_10.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_11.png b/games/devtest/mods/testnodes/textures/testnodes_light_11.png new file mode 100644 index 0000000..4c423d9 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_11.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_12.png b/games/devtest/mods/testnodes/textures/testnodes_light_12.png new file mode 100644 index 0000000..bc7946d Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_12.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_13.png b/games/devtest/mods/testnodes/textures/testnodes_light_13.png new file mode 100644 index 0000000..0b63c84 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_13.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_14.png b/games/devtest/mods/testnodes/textures/testnodes_light_14.png new file mode 100644 index 0000000..a817bd3 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_14.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_2.png b/games/devtest/mods/testnodes/textures/testnodes_light_2.png new file mode 100644 index 0000000..852eaef Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_2.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_3.png b/games/devtest/mods/testnodes/textures/testnodes_light_3.png new file mode 100644 index 0000000..79fc834 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_3.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_4.png b/games/devtest/mods/testnodes/textures/testnodes_light_4.png new file mode 100644 index 0000000..75f8c61 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_4.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_5.png b/games/devtest/mods/testnodes/textures/testnodes_light_5.png new file mode 100644 index 0000000..b6eede0 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_5.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_6.png b/games/devtest/mods/testnodes/textures/testnodes_light_6.png new file mode 100644 index 0000000..ef54add Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_6.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_7.png b/games/devtest/mods/testnodes/textures/testnodes_light_7.png new file mode 100644 index 0000000..4a885b0 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_7.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_8.png b/games/devtest/mods/testnodes/textures/testnodes_light_8.png new file mode 100644 index 0000000..b283301 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_8.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_light_9.png b/games/devtest/mods/testnodes/textures/testnodes_light_9.png new file mode 100644 index 0000000..2aa9023 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_light_9.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_line_crossing.png b/games/devtest/mods/testnodes/textures/testnodes_line_crossing.png new file mode 100644 index 0000000..e566f27 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_line_crossing.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_line_curved.png b/games/devtest/mods/testnodes/textures/testnodes_line_curved.png new file mode 100644 index 0000000..ab9f8e7 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_line_curved.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_line_straight.png b/games/devtest/mods/testnodes/textures/testnodes_line_straight.png new file mode 100644 index 0000000..4f33d9c Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_line_straight.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_line_t_junction.png b/games/devtest/mods/testnodes/textures/testnodes_line_t_junction.png new file mode 100644 index 0000000..5668f6e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_line_t_junction.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquid.png b/games/devtest/mods/testnodes/textures/testnodes_liquid.png new file mode 100644 index 0000000..98ab270 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquid.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing.png new file mode 100644 index 0000000..1736b89 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r0.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r0.png new file mode 100644 index 0000000..e8a6103 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r0.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r1.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r1.png new file mode 100644 index 0000000..b4e45b4 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r1.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r2.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r2.png new file mode 100644 index 0000000..e064b8f Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r2.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r3.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r3.png new file mode 100644 index 0000000..bef7739 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r3.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r4.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r4.png new file mode 100644 index 0000000..de1001b Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r4.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r5.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r5.png new file mode 100644 index 0000000..97b422e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r5.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r6.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r6.png new file mode 100644 index 0000000..4cd8e4e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r6.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r7.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r7.png new file mode 100644 index 0000000..711dd96 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r7.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r8.png b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r8.png new file mode 100644 index 0000000..9cf22b8 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidflowing_r8.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource.png new file mode 100644 index 0000000..b3f29b7 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidsource.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r0.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r0.png new file mode 100644 index 0000000..da0a996 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r0.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r1.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r1.png new file mode 100644 index 0000000..66bf2be Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r1.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r2.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r2.png new file mode 100644 index 0000000..fc5f65c Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r2.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r3.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r3.png new file mode 100644 index 0000000..0f46e29 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r3.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r4.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r4.png new file mode 100644 index 0000000..0693a04 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r4.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r5.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r5.png new file mode 100644 index 0000000..cc9d039 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r5.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r6.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r6.png new file mode 100644 index 0000000..e276a07 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r6.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r7.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r7.png new file mode 100644 index 0000000..3534a4b Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r7.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r8.png b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r8.png new file mode 100644 index 0000000..ee1a8b1 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_liquidsource_r8.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes.png b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes.png new file mode 100644 index 0000000..51b8e00 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes2.png b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes2.png new file mode 100644 index 0000000..9ea65c1 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes2.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes3.png b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes3.png new file mode 100644 index 0000000..96bc55a Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes3.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes4.png b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes4.png new file mode 100644 index 0000000..fca3372 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_mesh_stripes4.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_move_resistance.png b/games/devtest/mods/testnodes/textures/testnodes_move_resistance.png new file mode 100644 index 0000000..cac3944 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_move_resistance.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_node.png b/games/devtest/mods/testnodes/textures/testnodes_node.png new file mode 100644 index 0000000..145099b Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_node.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_node_falling.png b/games/devtest/mods/testnodes/textures/testnodes_node_falling.png new file mode 100644 index 0000000..4415318 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_node_falling.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_nodebox.png b/games/devtest/mods/testnodes/textures/testnodes_nodebox.png new file mode 100644 index 0000000..66e8dd6 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_nodebox.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_nojump_side.png b/games/devtest/mods/testnodes/textures/testnodes_nojump_side.png new file mode 100644 index 0000000..6a64cff Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_nojump_side.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_nojump_top.png b/games/devtest/mods/testnodes/textures/testnodes_nojump_top.png new file mode 100644 index 0000000..fe77083 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_nojump_top.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal.png b/games/devtest/mods/testnodes/textures/testnodes_normal.png new file mode 100644 index 0000000..a1acfd9 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_normal.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal1.png b/games/devtest/mods/testnodes/textures/testnodes_normal1.png new file mode 100644 index 0000000..edaba77 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_normal1.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal2.png b/games/devtest/mods/testnodes/textures/testnodes_normal2.png new file mode 100644 index 0000000..0080a9e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_normal2.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal3.png b/games/devtest/mods/testnodes/textures/testnodes_normal3.png new file mode 100644 index 0000000..0426ab2 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_normal3.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal4.png b/games/devtest/mods/testnodes/textures/testnodes_normal4.png new file mode 100644 index 0000000..0d1922e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_normal4.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal5.png b/games/devtest/mods/testnodes/textures/testnodes_normal5.png new file mode 100644 index 0000000..0b7dcd2 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_normal5.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_normal6.png b/games/devtest/mods/testnodes/textures/testnodes_normal6.png new file mode 100644 index 0000000..f34a67d Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_normal6.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_overlay.png b/games/devtest/mods/testnodes/textures/testnodes_overlay.png new file mode 100644 index 0000000..1c69b5e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_overlay.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_overlayable.png b/games/devtest/mods/testnodes/textures/testnodes_overlayable.png new file mode 100644 index 0000000..431bc94 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_overlayable.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_palette_facedir.png b/games/devtest/mods/testnodes/textures/testnodes_palette_facedir.png new file mode 100644 index 0000000..8cf47bb Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_palette_facedir.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_palette_full.png b/games/devtest/mods/testnodes/textures/testnodes_palette_full.png new file mode 100644 index 0000000..e0a5f8b Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_palette_full.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_palette_wallmounted.png b/games/devtest/mods/testnodes/textures/testnodes_palette_wallmounted.png new file mode 100644 index 0000000..682f3ac Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_palette_wallmounted.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike.png new file mode 100644 index 0000000..cc46444 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_degrotate.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_degrotate.png new file mode 100644 index 0000000..01c81da Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_degrotate.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_leveled.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_leveled.png new file mode 100644 index 0000000..53504db Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_leveled.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_meshoptions.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_meshoptions.png new file mode 100644 index 0000000..d504d45 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_meshoptions.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted.png new file mode 100644 index 0000000..79cf212 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base.png new file mode 100644 index 0000000..b9ee9e5 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_degrotate.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_degrotate.png new file mode 100644 index 0000000..85311cb Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_degrotate.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_leveled.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_leveled.png new file mode 100644 index 0000000..bc602ba Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_leveled.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_meshoptions.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_meshoptions.png new file mode 100644 index 0000000..d100023 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_meshoptions.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_wallmounted.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_wallmounted.png new file mode 100644 index 0000000..b0be8d0 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_wallmounted.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_waving.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_waving.png new file mode 100644 index 0000000..527817b Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_waving.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_degrotate.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_degrotate.png new file mode 100644 index 0000000..45e75bd Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_degrotate.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_leveled.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_leveled.png new file mode 100644 index 0000000..8954b2c Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_leveled.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_meshoptions.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_meshoptions.png new file mode 100644 index 0000000..a782d48 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_meshoptions.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_wallmounted.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_wallmounted.png new file mode 100644 index 0000000..4214664 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_wallmounted.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_waving.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_waving.png new file mode 100644 index 0000000..112a054 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_rooted_waving.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_wallmounted.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_wallmounted.png new file mode 100644 index 0000000..c89b29e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_wallmounted.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_plantlike_waving.png b/games/devtest/mods/testnodes/textures/testnodes_plantlike_waving.png new file mode 100644 index 0000000..b584a8d Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_plantlike_waving.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail2_crossing.png b/games/devtest/mods/testnodes/textures/testnodes_rail2_crossing.png new file mode 100644 index 0000000..530bbba Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_rail2_crossing.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail2_curved.png b/games/devtest/mods/testnodes/textures/testnodes_rail2_curved.png new file mode 100644 index 0000000..4ed1ca0 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_rail2_curved.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail2_straight.png b/games/devtest/mods/testnodes/textures/testnodes_rail2_straight.png new file mode 100644 index 0000000..8749330 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_rail2_straight.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail2_t_junction.png b/games/devtest/mods/testnodes/textures/testnodes_rail2_t_junction.png new file mode 100644 index 0000000..0517f65 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_rail2_t_junction.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail_crossing.png b/games/devtest/mods/testnodes/textures/testnodes_rail_crossing.png new file mode 100644 index 0000000..3916ce1 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_rail_crossing.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail_curved.png b/games/devtest/mods/testnodes/textures/testnodes_rail_curved.png new file mode 100644 index 0000000..e444198 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_rail_curved.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail_straight.png b/games/devtest/mods/testnodes/textures/testnodes_rail_straight.png new file mode 100644 index 0000000..872d04f Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_rail_straight.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_rail_t_junction.png b/games/devtest/mods/testnodes/textures/testnodes_rail_t_junction.png new file mode 100644 index 0000000..7e4af51 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_rail_t_junction.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_signlike.png b/games/devtest/mods/testnodes/textures/testnodes_signlike.png new file mode 100644 index 0000000..33ffcba Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_signlike.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_slippery.png b/games/devtest/mods/testnodes/textures/testnodes_slippery.png new file mode 100644 index 0000000..b990468 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_slippery.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_street_crossing.png b/games/devtest/mods/testnodes/textures/testnodes_street_crossing.png new file mode 100644 index 0000000..d6e35ad Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_street_crossing.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_street_curved.png b/games/devtest/mods/testnodes/textures/testnodes_street_curved.png new file mode 100644 index 0000000..251b7fb Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_street_curved.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_street_straight.png b/games/devtest/mods/testnodes/textures/testnodes_street_straight.png new file mode 100644 index 0000000..639e24b Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_street_straight.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_street_t_junction.png b/games/devtest/mods/testnodes/textures/testnodes_street_t_junction.png new file mode 100644 index 0000000..713621e Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_street_t_junction.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_sunlight_filter.png b/games/devtest/mods/testnodes/textures/testnodes_sunlight_filter.png new file mode 100644 index 0000000..b38ea40 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_sunlight_filter.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga new file mode 100644 index 0000000..2dc587b Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga new file mode 100644 index 0000000..b44a81c Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tga new file mode 100644 index 0000000..d2c2ca6 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tga differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tga new file mode 100644 index 0000000..dfcb988 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tga differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga new file mode 100644 index 0000000..0206216 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tga new file mode 100644 index 0000000..2563f08 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tga differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tga new file mode 100644 index 0000000..3350500 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tga differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga new file mode 100644 index 0000000..216de06 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tga new file mode 100644 index 0000000..695bb4b Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tga differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tga new file mode 100644 index 0000000..c08a093 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tga differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_torchlike_ceiling.png b/games/devtest/mods/testnodes/textures/testnodes_torchlike_ceiling.png new file mode 100644 index 0000000..5d9862c Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_torchlike_ceiling.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_torchlike_floor.png b/games/devtest/mods/testnodes/textures/testnodes_torchlike_floor.png new file mode 100644 index 0000000..adf1e00 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_torchlike_floor.png differ diff --git a/games/devtest/mods/testnodes/textures/testnodes_torchlike_wall.png b/games/devtest/mods/testnodes/textures/testnodes_torchlike_wall.png new file mode 100644 index 0000000..cb442b2 Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_torchlike_wall.png differ diff --git a/games/devtest/mods/testpathfinder/README.md b/games/devtest/mods/testpathfinder/README.md new file mode 100644 index 0000000..2b9d46e --- /dev/null +++ b/games/devtest/mods/testpathfinder/README.md @@ -0,0 +1,15 @@ +# Pathfinder Tester + +Usage: + +Use the Pathfinder Tester tool (`testpathfinder:testpathfinder`). +Here's how it works: + +* Place on node: Set destination position +* Punch: Find path +* Sneak+punch: Select pathfinding algorithm + +Information will be shown in chat. If a path was found, all waypoints +will be shown for a few seconds. + +See `init.lua` for config variables. diff --git a/games/devtest/mods/testpathfinder/init.lua b/games/devtest/mods/testpathfinder/init.lua new file mode 100644 index 0000000..67748af --- /dev/null +++ b/games/devtest/mods/testpathfinder/init.lua @@ -0,0 +1,136 @@ +local S = minetest.get_translator("testpathfinder") + +-- Config parameters + +-- Maximum direct distance between start and end +local MAX_DIRECT_DISTANCE = 64 +-- Maximum search distance +local MAX_SEARCH_DISTANCE = 32 +-- Maximum permitted jump height +local MAX_JUMP = 1 +-- Maximum permitted drop height +local MAX_DROP = 5 +-- If true, mod won't refuse to run pathfinder even at long distances +local IGNORE_MAX_DISTANCE_SAFEGUARD = false + +-- End of config parameters + +local timer = 0 +local algorithms = { + "A*_noprefetch", + "A*", + "Dijkstra", +} + +local function find_path_for_player(player, itemstack) + local meta = itemstack:get_meta() + if not meta then + return + end + local x = meta:get_int("pos_x") + local y = meta:get_int("pos_y") + local z = meta:get_int("pos_z") + local algo = meta:get_int("algorithm") + if x and y and z then + local pos2 = {x=x, y=y, z=z} + algo = algorithms[algo+1] + local pos1 = vector.round(player:get_pos()) + -- Don't bother calling pathfinder for high distance to avoid freezing + if (not IGNORE_MAX_DISTANCE_SAFEGUARD) and (vector.distance(pos1, pos2) > MAX_DIRECT_DISTANCE) then + minetest.chat_send_player(player:get_player_name(), S("Destination too far away! Set a destination (via placing) within a distance of @1 and try again!", MAX_DIRECT_DISTANCE)) + return + end + local str = S("Path from @1 to @2:", + minetest.pos_to_string(pos1), + minetest.pos_to_string(pos2)) + + minetest.chat_send_player(player:get_player_name(), str) + local time_start = minetest.get_us_time() + local path = minetest.find_path(pos1, pos2, MAX_SEARCH_DISTANCE, MAX_JUMP, MAX_DROP, algo) + local time_end = minetest.get_us_time() + local time_diff = time_end - time_start + str = "" + if not path then + minetest.chat_send_player(player:get_player_name(), S("No path!")) + minetest.chat_send_player(player:get_player_name(), S("Time: @1 ms", time_diff/1000)) + return + end + for s=1, #path do + str = str .. minetest.pos_to_string(path[s]) .. "\n" + local t + if s == #path then + t = "testpathfinder_waypoint_end.png" + elseif s == 1 then + t = "testpathfinder_waypoint_start.png" + else + local c = math.floor(((#path-s)/#path)*255) + t = string.format("testpathfinder_waypoint.png^[multiply:#%02x%02x00", 0xFF-c, c) + end + minetest.add_particle({ + pos = path[s], + expirationtime = 5 + 0.2 * s, + playername = player:get_player_name(), + glow = minetest.LIGHT_MAX, + texture = t, + size = 3, + }) + end + minetest.chat_send_player(player:get_player_name(), str) + minetest.chat_send_player(player:get_player_name(), S("Path length: @1", #path)) + minetest.chat_send_player(player:get_player_name(), S("Time: @1 ms", time_diff/1000)) + end +end + +local function set_destination(itemstack, user, pointed_thing) + if not (user and user:is_player()) then + return + end + local name = user:get_player_name() + local obj + local meta = itemstack:get_meta() + if pointed_thing.type == "node" then + local pos = pointed_thing.above + meta:set_int("pos_x", pos.x) + meta:set_int("pos_y", pos.y) + meta:set_int("pos_z", pos.z) + minetest.chat_send_player(user:get_player_name(), S("Destination set to @1", minetest.pos_to_string(pos))) + return itemstack + end +end + +local function find_path_or_set_algorithm(itemstack, user, pointed_thing) + if not (user and user:is_player()) then + return + end + local ctrl = user:get_player_control() + -- No sneak: Find path + if not ctrl.sneak then + find_path_for_player(user, itemstack) + else + -- Sneak: Set algorithm + local meta = itemstack:get_meta() + local algo = meta:get_int("algorithm") + algo = (algo + 1) % #algorithms + meta:set_int("algorithm", algo) + minetest.chat_send_player(user:get_player_name(), S("Algorithm: @1", algorithms[algo+1])) + return itemstack + end +end + +-- Punch: Find path +-- Sneak+punch: Select pathfinding algorithm +-- Place: Select destination node +minetest.register_tool("testpathfinder:testpathfinder", { + description = S("Pathfinder Tester") .."\n".. + S("Finds path between 2 points") .."\n".. + S("Place on node: Select destination") .."\n".. + S("Punch: Find path from here") .."\n".. + S("Sneak+Punch: Change algorithm"), + inventory_image = "testpathfinder_testpathfinder.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = find_path_or_set_algorithm, + on_secondary_use = set_destination, + on_place = set_destination, +}) + + diff --git a/games/devtest/mods/testpathfinder/mod.conf b/games/devtest/mods/testpathfinder/mod.conf new file mode 100644 index 0000000..e6034ae --- /dev/null +++ b/games/devtest/mods/testpathfinder/mod.conf @@ -0,0 +1,2 @@ +name = testpathfinder +description = Tool to test Minetest's pathfinder function diff --git a/games/devtest/mods/testpathfinder/textures/testpathfinder_testpathfinder.png b/games/devtest/mods/testpathfinder/textures/testpathfinder_testpathfinder.png new file mode 100644 index 0000000..37eef05 Binary files /dev/null and b/games/devtest/mods/testpathfinder/textures/testpathfinder_testpathfinder.png differ diff --git a/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint.png b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint.png new file mode 100644 index 0000000..661dcf9 Binary files /dev/null and b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint.png differ diff --git a/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_end.png b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_end.png new file mode 100644 index 0000000..41a1cc5 Binary files /dev/null and b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_end.png differ diff --git a/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_start.png b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_start.png new file mode 100644 index 0000000..a22e31c Binary files /dev/null and b/games/devtest/mods/testpathfinder/textures/testpathfinder_waypoint_start.png differ diff --git a/games/devtest/mods/testtools/README.md b/games/devtest/mods/testtools/README.md new file mode 100644 index 0000000..72f0a2d --- /dev/null +++ b/games/devtest/mods/testtools/README.md @@ -0,0 +1,128 @@ +# Test Tools readme + +Test Tools is a mod for developers that adds a bunch of tools to directly manipulate nodes and entities. This is great for quickly testing out stuff. + +Here's the list of tools: + +## Remover +Removes nodes and non-player entities that you punch. + +## Node Setter +Replace a node with another one. + +First, punch a node you want to remember. +Then rightclick any other node to replace it with the node you remembered. + +If you rightclick while pointing nothing, you can manually enter the node and param2. + +## Param2 Tool +Change the value param2 of nodes. + +* Punch: Add 1 to param2 +* Sneak+Punch: Add 8 to param2 +* Place: Subtract 1 from param2 +* Sneak+Place: Subtract 8 from param2 + +Note: Use the debug screen (F5) to see the param2 of the pointed node. + +## Falling Node Tool +Turns nodes into falling nodes. + +Usage: + +* Punch node: Make it fall +* Place: Try to teleport up to 2 units upwards, then make it fall + +## Node Meta Editor +Edit and view metadata of nodes. + +Usage: + +* Punch: Open node metadata editor + +## Item Meta Editor +Edit and view metadata of items. + +Usage: + +* Place/Punch: Opens item metadata editor of the item in the next + inventory slot from the wielded item + +## Entity Rotator +Changes the entity rotation (with `set_rotation`). + +Usage: + +* Punch entity: Rotate yaw +* Punch entity while holding down “Sneak” key: Rotate pitch +* Punch entity while holding down “Special” key (aka “Aux”): Rotate roll + +Each usage rotates the entity by 22.5°. + +## Entity Spawner +Spawns entities. + +Usage: + +* Punch to select entity or spawn one directly +* Place to place selected entity + +## Object Property Editor +Edits properties of objects. + +Usage: + +* Punch object to open a formspec that allows you to view and edit properties +* Punch air to edit properties of your own player object + +To edit a property, select it in the list, enter a new value (in Lua syntax) +and hit “Submit”. + +## Object Attacher +Allows you to attach an object to another one. + +Basic usage: +* First select the parent object, then the child object that should be attached +* Selecting an object is done by punching it +* Sneak+punch to detach selected object +* If you punch air, you select yourself + +Configuration: +* Place: Increase attachment Y position +* Sneak+place: decrease attachment Y position +* Aux+place: Increase attachment X rotation +* Aux+Sneak+Rightclick: Decrease attachment X rotation + +Hint: To detach all objects nearby you (including on yourself), use the +`/detach` server command. + +## Object Mover +Move an object by a given distance. + +Usage: +* Punch object into the direction you want to move it +* Sneak+punch: Move object towards you +* Place: Increase move distance +* Sneak+place: Decrease move distance + +## Children Getter +Shows list of objects that are attached to an object (aka "children") in chat. + +Usage: +* Punch object: Show children of punched object +* Punch air: Show your own children + +## Entity Visual Scaler +Change visual size of entities + +Usage: + +* Punch entity to increase visual size +* Sneak+punch entity to decrease visual size + +## Light Tool +Show light level of node. + +Usage: +* Punch: Show light info of node in front of the punched node's side +* Place: Show light info of the node that you touched diff --git a/games/devtest/mods/testtools/init.lua b/games/devtest/mods/testtools/init.lua new file mode 100644 index 0000000..abc1ed7 --- /dev/null +++ b/games/devtest/mods/testtools/init.lua @@ -0,0 +1,951 @@ +local S = minetest.get_translator("testtools") +local F = minetest.formspec_escape + +dofile(minetest.get_modpath("testtools") .. "/light.lua") + +minetest.register_tool("testtools:param2tool", { + description = S("Param2 Tool") .."\n".. + S("Modify param2 value of nodes") .."\n".. + S("Punch: +1") .."\n".. + S("Sneak+Punch: +8") .."\n".. + S("Place: -1") .."\n".. + S("Sneak+Place: -8"), + inventory_image = "testtools_param2tool.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + local pos = minetest.get_pointed_thing_position(pointed_thing) + if pointed_thing.type ~= "node" or (not pos) then + return + end + local add = 1 + if user then + local ctrl = user:get_player_control() + if ctrl.sneak then + add = 8 + end + end + local node = minetest.get_node(pos) + node.param2 = node.param2 + add + minetest.swap_node(pos, node) + end, + on_place = function(itemstack, user, pointed_thing) + local pos = minetest.get_pointed_thing_position(pointed_thing) + if pointed_thing.type ~= "node" or (not pos) then + return + end + local add = -1 + if user then + local ctrl = user:get_player_control() + if ctrl.sneak then + add = -8 + end + end + local node = minetest.get_node(pos) + node.param2 = node.param2 + add + minetest.swap_node(pos, node) + end, +}) + +minetest.register_tool("testtools:node_setter", { + description = S("Node Setter") .."\n".. + S("Replace pointed node with something else") .."\n".. + S("Punch: Select pointed node") .."\n".. + S("Place on node: Replace node with selected node") .."\n".. + S("Place in air: Manually select a node"), + inventory_image = "testtools_node_setter.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + local pos = minetest.get_pointed_thing_position(pointed_thing) + if pointed_thing.type == "nothing" then + local meta = itemstack:get_meta() + meta:set_string("node", "air") + meta:set_int("node_param2", 0) + if user and user:is_player() then + minetest.chat_send_player(user:get_player_name(), S("Now placing: @1 (param2=@2)", "air", 0)) + end + return itemstack + elseif pointed_thing.type ~= "node" or (not pos) then + return + end + local node = minetest.get_node(pos) + local meta = itemstack:get_meta() + meta:set_string("node", node.name) + meta:set_int("node_param2", node.param2) + if user and user:is_player() then + minetest.chat_send_player(user:get_player_name(), S("Now placing: @1 (param2=@2)", node.name, node.param2)) + end + return itemstack + end, + on_secondary_use = function(itemstack, user, pointed_thing) + local meta = itemstack:get_meta() + local nodename = meta:get_string("node") or "" + local param2 = meta:get_int("node_param2") or 0 + + minetest.show_formspec(user:get_player_name(), "testtools:node_setter", + "size[4,4]".. + "field[0.5,1;3,1;nodename;"..F(S("Node name (itemstring):"))..";"..F(nodename).."]".. + "field[0.5,2;3,1;param2;"..F(S("param2:"))..";"..F(tostring(param2)).."]".. + "button_exit[0.5,3;3,1;submit;"..F(S("Submit")).."]" + ) + end, + on_place = function(itemstack, user, pointed_thing) + local pos = minetest.get_pointed_thing_position(pointed_thing) + local meta = itemstack:get_meta() + local nodename = meta:get_string("node") + if nodename == "" and user and user:is_player() then + minetest.chat_send_player(user:get_player_name(), S("Punch a node first!")) + return + end + local param2 = meta:get_int("node_param2") + if not param2 then + param2 = 0 + end + local node = { name = nodename, param2 = param2 } + if not minetest.registered_nodes[nodename] then + minetest.chat_send_player(user:get_player_name(), S("Cannot set unknown node: @1", nodename)) + return + end + minetest.set_node(pos, node) + end, +}) + +minetest.register_tool("testtools:remover", { + description = S("Remover") .."\n".. + S("Punch: Remove pointed node or object"), + inventory_image = "testtools_remover.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + local pos = minetest.get_pointed_thing_position(pointed_thing) + if pointed_thing.type == "node" and pos ~= nil then + minetest.remove_node(pos) + elseif pointed_thing.type == "object" then + local obj = pointed_thing.ref + if not obj:is_player() then + obj:remove() + else + minetest.chat_send_player(user:get_player_name(), S("Can't remove players!")) + end + end + end, +}) + +minetest.register_tool("testtools:falling_node_tool", { + description = S("Falling Node Tool") .."\n".. + S("Punch: Make pointed node fall") .."\n".. + S("Place: Move pointed node 2 units upwards, then make it fall"), + inventory_image = "testtools_falling_node_tool.png", + groups = { testtool = 1, disable_repair = 1 }, + on_place = function(itemstack, user, pointed_thing) + -- Teleport node 1-2 units upwards (if possible) and make it fall + local pos = minetest.get_pointed_thing_position(pointed_thing) + if pointed_thing.type ~= "node" or (not pos) then + return + end + local ok = false + local highest + for i=1,2 do + local above = {x=pos.x,y=pos.y+i,z=pos.z} + local n2 = minetest.get_node(above) + local def2 = minetest.registered_nodes[n2.name] + if def2 and (not def2.walkable) then + highest = above + else + break + end + end + if highest then + local node = minetest.get_node(pos) + local metatable = minetest.get_meta(pos):to_table() + minetest.remove_node(pos) + minetest.set_node(highest, node) + local meta_highest = minetest.get_meta(highest) + meta_highest:from_table(metatable) + ok = minetest.spawn_falling_node(highest) + else + ok = minetest.spawn_falling_node(pos) + end + if not ok and user and user:is_player() then + minetest.chat_send_player(user:get_player_name(), S("Falling node could not be spawned!")) + end + end, + on_use = function(itemstack, user, pointed_thing) + local pos = minetest.get_pointed_thing_position(pointed_thing) + if pointed_thing.type ~= "node" or (not pos) then + return + end + local ok = minetest.spawn_falling_node(pos) + if not ok and user and user:is_player() then + minetest.chat_send_player(user:get_player_name(), S("Falling node could not be spawned!")) + end + end, +}) + +minetest.register_tool("testtools:rotator", { + description = S("Entity Rotator") .. "\n" .. + S("Rotate pointed entity") .."\n".. + S("Punch: Yaw") .."\n".. + S("Sneak+Punch: Pitch") .."\n".. + S("Aux1+Punch: Roll"), + inventory_image = "testtools_entity_rotator.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= "object" then + return + end + local obj = pointed_thing.ref + if obj:is_player() then + -- No player rotation + return + else + local axis = "y" + if user and user:is_player() then + local ctrl = user:get_player_control() + if ctrl.sneak then + axis = "x" + elseif ctrl.aux1 then + axis = "z" + end + end + local rot = obj:get_rotation() + rot[axis] = rot[axis] + math.pi/8 + if rot[axis] > math.pi*2 then + rot[axis] = rot[axis] - math.pi*2 + end + obj:set_rotation(rot) + end + end, +}) + +local mover_config = function(itemstack, user, pointed_thing) + if not (user and user:is_player()) then + return + end + local name = user:get_player_name() + local ctrl = user:get_player_control() + local meta = itemstack:get_meta() + local dist = 1.0 + if meta:contains("distance") then + dist = meta:get_int("distance") + end + if ctrl.sneak then + dist = dist - 1 + else + dist = dist + 1 + end + meta:set_int("distance", dist) + minetest.chat_send_player(user:get_player_name(), S("distance=@1/10", dist*2)) + return itemstack +end + +minetest.register_tool("testtools:object_mover", { + description = S("Object Mover") .."\n".. + S("Move pointed object towards or away from you") .."\n".. + S("Punch: Move by distance").."\n".. + S("Sneak+Punch: Move by negative distance").."\n".. + S("Place: Increase distance").."\n".. + S("Sneak+Place: Decrease distance"), + inventory_image = "testtools_object_mover.png", + groups = { testtool = 1, disable_repair = 1 }, + on_place = mover_config, + on_secondary_use = mover_config, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= "object" then + return + end + local obj = pointed_thing.ref + if not (user and user:is_player()) then + return + end + local yaw = user:get_look_horizontal() + local dir = minetest.yaw_to_dir(yaw) + local pos = obj:get_pos() + local pitch = user:get_look_vertical() + if pitch > 0.25 * math.pi then + dir.y = -1 + dir.x = 0 + dir.z = 0 + elseif pitch < -0.25 * math.pi then + dir.y = 1 + dir.x = 0 + dir.z = 0 + end + local ctrl = user:get_player_control() + if ctrl.sneak then + dir = vector.multiply(dir, -1) + end + local meta = itemstack:get_meta() + if meta:contains("distance") then + local dist = meta:get_int("distance") + dir = vector.multiply(dir, dist*0.2) + end + pos = vector.add(pos, dir) + obj:set_pos(pos) + end, +}) + + + +minetest.register_tool("testtools:entity_scaler", { + description = S("Entity Visual Scaler") .."\n".. + S("Scale visual size of entities") .."\n".. + S("Punch: Increase size") .."\n".. + S("Sneak+Punch: Decrease scale"), + inventory_image = "testtools_entity_scaler.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= "object" then + return + end + local obj = pointed_thing.ref + if obj:is_player() then + -- No player scaling + return + else + local diff = 0.1 + if user and user:is_player() then + local ctrl = user:get_player_control() + if ctrl.sneak then + diff = -0.1 + end + end + local prop = obj:get_properties() + if not prop.visual_size then + prop.visual_size = { x=1, y=1, z=1 } + else + prop.visual_size = { x=prop.visual_size.x+diff, y=prop.visual_size.y+diff, z=prop.visual_size.z+diff } + if prop.visual_size.x <= 0.1 then + prop.visual_size.x = 0.1 + end + if prop.visual_size.y <= 0.1 then + prop.visual_size.y = 0.1 + end + if prop.visual_size.z <= 0.1 then + prop.visual_size.z = 0.1 + end + end + obj:set_properties(prop) + end + end, +}) + +local selections = {} +local entity_list +local function get_entity_list() + if entity_list then + return entity_list + end + local ents = minetest.registered_entities + local list = {} + for k,_ in pairs(ents) do + table.insert(list, k) + end + table.sort(list) + entity_list = list + return entity_list +end +minetest.register_tool("testtools:entity_spawner", { + description = S("Entity Spawner") .."\n".. + S("Spawns entities") .."\n".. + S("Punch: Select entity to spawn") .."\n".. + S("Place: Spawn selected entity"), + inventory_image = "testtools_entity_spawner.png", + groups = { testtool = 1, disable_repair = 1 }, + on_place = function(itemstack, user, pointed_thing) + local name = user:get_player_name() + if pointed_thing.type == "node" then + if selections[name] then + local pos = pointed_thing.above + minetest.add_entity(pos, get_entity_list()[selections[name]]) + else + minetest.chat_send_player(name, S("Select an entity first (with punch key)!")) + end + end + end, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type == "object" then + return + end + if user and user:is_player() then + local list = table.concat(get_entity_list(), ",") + local name = user:get_player_name() + local sel = selections[name] or "" + minetest.show_formspec(name, "testtools:entity_list", + "size[9,9]".. + "textlist[0,0;9,8;entity_list;"..list..";"..sel..";false]".. + "button[0,8;4,1;spawn;Spawn entity]" + ) + end + end, +}) + +local function prop_to_string(property) + if type(property) == "string" then + return "\"" .. property .. "\"" + elseif type(property) == "table" then + return tostring(dump(property)):gsub("\n", "") + else + return tostring(property) + end +end + +local property_formspec_data = {} +local property_formspec_index = {} +local selected_objects = {} +local function get_object_properties_form(obj, playername) + if not playername then return "" end + local props = obj:get_properties() + local str = "" + property_formspec_data[playername] = {} + local proplist = {} + for k,_ in pairs(props) do + table.insert(proplist, k) + end + table.sort(proplist) + for p=1, #proplist do + local k = proplist[p] + local v = props[k] + local newline = "" + newline = k .. " = " + newline = newline .. prop_to_string(v) + str = str .. F(newline) + if p < #proplist then + str = str .. "," + end + table.insert(property_formspec_data[playername], k) + end + return str +end + +local editor_formspec_selindex = {} + +local editor_formspec = function(playername, obj, value, sel) + if not value then + value = "" + end + if not sel then + sel = "" + end + local list = get_object_properties_form(obj, playername) + local title + if obj:is_player() then + title = S("Object properties of player “@1”", obj:get_player_name()) + else + local ent = obj:get_luaentity() + title = S("Object properties of @1", ent.name) + end + minetest.show_formspec(playername, "testtools:object_editor", + "size[9,9]".. + "label[0,0;"..F(title).."]".. + "textlist[0,0.5;9,7.5;object_props;"..list..";"..sel..";false]".. + "field[0.2,8.75;8,1;value;"..F(S("Value"))..";"..F(value).."]".. + "field_close_on_enter[value;false]".. + "button[8,8.5;1,1;submit;"..F(S("Submit")).."]" + ) +end + +minetest.register_tool("testtools:object_editor", { + description = S("Object Property Editor") .."\n".. + S("Edit properties of objects") .."\n".. + S("Punch object: Edit object") .."\n".. + S("Punch air: Edit yourself"), + inventory_image = "testtools_object_editor.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + if user and user:is_player() then + local name = user:get_player_name() + + if pointed_thing.type == "object" then + selected_objects[name] = pointed_thing.ref + elseif pointed_thing.type == "nothing" then + -- Use on yourself if pointing nothing + selected_objects[name] = user + else + -- Unsupported pointed thing + return + end + + local sel = editor_formspec_selindex[name] + local val + if selected_objects[name] and selected_objects[name]:get_properties() then + local props = selected_objects[name]:get_properties() + local keys = property_formspec_data[name] + if property_formspec_index[name] and props then + local key = keys[property_formspec_index[name]] + val = prop_to_string(props[key]) + end + end + + editor_formspec(name, selected_objects[name], val, sel) + end + end, +}) + +local ent_parent = {} +local ent_child = {} +local DEFAULT_ATTACH_OFFSET_Y = 11 + +local attacher_config = function(itemstack, user, pointed_thing) + if not (user and user:is_player()) then + return + end + if pointed_thing.type == "object" then + return + end + local name = user:get_player_name() + local ctrl = user:get_player_control() + local meta = itemstack:get_meta() + if ctrl.aux1 then + local rot_x = meta:get_float("rot_x") + if ctrl.sneak then + rot_x = rot_x - math.pi/8 + else + rot_x = rot_x + math.pi/8 + end + if rot_x > 6.2 then + rot_x = 0 + elseif rot_x < 0 then + rot_x = math.pi * (15/8) + end + minetest.chat_send_player(name, S("rotation=@1", minetest.pos_to_string({x=rot_x,y=0,z=0}))) + meta:set_float("rot_x", rot_x) + else + local pos_y + if meta:contains("pos_y") then + pos_y = meta:get_int("pos_y") + else + pos_y = DEFAULT_ATTACH_OFFSET_Y + end + if ctrl.sneak then + pos_y = pos_y - 1 + else + pos_y = pos_y + 1 + end + minetest.chat_send_player(name, S("position=@1", minetest.pos_to_string({x=0,y=pos_y,z=0}))) + meta:set_int("pos_y", pos_y) + end + return itemstack +end + +minetest.register_tool("testtools:object_attacher", { + description = S("Object Attacher") .."\n".. + S("Attach object to another") .."\n".. + S("Punch objects to first select parent object, then the child object to attach") .."\n".. + S("Punch air to select yourself") .."\n".. + S("Place: Incease attachment Y offset") .."\n".. + S("Sneak+Place: Decease attachment Y offset") .."\n".. + S("Aux1+Place: Incease attachment rotation") .."\n".. + S("Aux1+Sneak+Place: Decrease attachment rotation"), + inventory_image = "testtools_object_attacher.png", + groups = { testtool = 1, disable_repair = 1 }, + on_place = attacher_config, + on_secondary_use = attacher_config, + on_use = function(itemstack, user, pointed_thing) + if user and user:is_player() then + local name = user:get_player_name() + local selected_object + if pointed_thing.type == "object" then + selected_object = pointed_thing.ref + elseif pointed_thing.type == "nothing" then + selected_object = user + else + return + end + local ctrl = user:get_player_control() + if ctrl.sneak then + if selected_object:get_attach() then + selected_object:set_detach() + minetest.chat_send_player(name, S("Object detached!")) + else + minetest.chat_send_player(name, S("Object is not attached!")) + end + return + end + local parent = ent_parent[name] + local child = ent_child[name] + local ename = S("<unknown>") + if not parent then + parent = selected_object + ent_parent[name] = parent + elseif not child then + child = selected_object + ent_child[name] = child + end + local entity = selected_object:get_luaentity() + if entity then + ename = entity.name + elseif selected_object:is_player() then + ename = selected_object:get_player_name() + end + if selected_object == parent then + minetest.chat_send_player(name, S("Parent object selected: @1", ename)) + elseif selected_object == child then + minetest.chat_send_player(name, S("Child object selected: @1", ename)) + end + if parent and child then + if parent == child then + minetest.chat_send_player(name, S("Can't attach an object to itself!")) + ent_parent[name] = nil + ent_child[name] = nil + return + end + local meta = itemstack:get_meta() + local y + if meta:contains("pos_y") then + y = meta:get_int("pos_y") + else + y = DEFAULT_ATTACH_OFFSET_Y + end + local rx = meta:get_float("rot_x") or 0 + local offset = {x=0,y=y,z=0} + local angle = {x=rx,y=0,z=0} + child:set_attach(parent, "", offset, angle) + local check_parent = child:get_attach() + if check_parent then + minetest.chat_send_player(name, S("Object attached! position=@1, rotation=@2", + minetest.pos_to_string(offset), minetest.pos_to_string(angle))) + else + minetest.chat_send_player(name, S("Attachment failed!")) + end + ent_parent[name] = nil + ent_child[name] = nil + end + end + end, +}) + +local function print_object(obj) + if obj:is_player() then + return "player '"..obj:get_player_name().."'" + elseif obj:get_luaentity() then + return "LuaEntity '"..obj:get_luaentity().name.."'" + else + return "object" + end +end + +minetest.register_tool("testtools:children_getter", { + description = S("Children Getter") .."\n".. + S("Shows list of objects attached to object") .."\n".. + S("Punch object to show its 'children'") .."\n".. + S("Punch air to show your own 'children'"), + inventory_image = "testtools_children_getter.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + if user and user:is_player() then + local name = user:get_player_name() + local selected_object + local self_name + if pointed_thing.type == "object" then + selected_object = pointed_thing.ref + elseif pointed_thing.type == "nothing" then + selected_object = user + else + return + end + self_name = print_object(selected_object) + local children = selected_object:get_children() + local ret = "" + for c=1, #children do + ret = ret .. "* " .. print_object(children[c]) + if c < #children then + ret = ret .. "\n" + end + end + if ret == "" then + ret = S("No children attached to @1.", self_name) + else + ret = S("Children of @1:", self_name) .. "\n" .. ret + end + minetest.chat_send_player(user:get_player_name(), ret) + end + end, +}) + +-- Use loadstring to parse param as a Lua value +local function use_loadstring(param, player) + -- For security reasons, require 'server' priv, just in case + -- someone is actually crazy enough to run this on a public server. + local privs = minetest.get_player_privs(player:get_player_name()) + if not privs.server then + return false, "You need 'server' privilege to change object properties!" + end + if not param then + return false, "Failed: parameter is nil" + end + --[[ DANGER ZONE ]] + -- Interpret string as Lua value + local func, errormsg = loadstring("return (" .. param .. ")") + if not func then + return false, "Failed: " .. errormsg + end + + -- Apply sandbox here using setfenv + setfenv(func, {}) + + -- Run it + local good, errOrResult = pcall(func) + if not good then + -- A Lua error was thrown + return false, "Failed: " .. errOrResult + end + + -- errOrResult will be the value + return true, errOrResult +end + +-- Item Meta Editor + Node Meta Editor +local node_meta_posses = {} +local meta_latest_keylist = {} + +local function show_meta_formspec(user, metatype, pos_or_item, key, value, keylist) + local textlist + if keylist then + textlist = "textlist[0,0.5;2.5,6.5;keylist;"..keylist.."]" + else + textlist = "" + end + + local form = "size[15,9]".. + "label[0,0;"..F(S("Current keys:")).."]".. + textlist.. + "field[3,0.5;12,1;key;"..F(S("Key"))..";"..F(key).."]".. + "textarea[3,1.5;12,6;value;"..F(S("Value (use empty value to delete key)"))..";"..F(value).."]".. + "button[4,8;3,1;set;"..F(S("Set value")).."]" + + local extra_label + local formname + if metatype == "node" then + formname = "testtools:node_meta_editor" + extra_label = S("pos = @1", minetest.pos_to_string(pos_or_item)) + else + formname = "testtools:item_meta_editor" + extra_label = S("item = @1", pos_or_item:get_name()) + end + form = form .. "label[0,7.2;"..F(extra_label).."]" + + minetest.show_formspec(user:get_player_name(), formname, form) +end + +local function get_meta_keylist(meta, playername, escaped) + local keys = {} + local ekeys = {} + local mtable = meta:to_table() + for k,_ in pairs(mtable.fields) do + table.insert(keys, k) + if escaped then + table.insert(ekeys, F(k)) + else + table.insert(ekeys, k) + end + end + if playername then + meta_latest_keylist[playername] = keys + end + return table.concat(ekeys, ",") +end + +minetest.register_tool("testtools:node_meta_editor", { + description = S("Node Meta Editor") .. "\n" .. + S("Place: Edit node metadata"), + inventory_image = "testtools_node_meta_editor.png", + groups = { testtool = 1, disable_repair = 1 }, + on_place = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + if not user:is_player() then + return itemstack + end + local pos = pointed_thing.under + node_meta_posses[user:get_player_name()] = pos + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + show_meta_formspec(user, "node", pos, "", "", get_meta_keylist(meta, user:get_player_name(), true)) + return itemstack + end, +}) + +local function get_item_next_to_wielded_item(player) + local inv = player:get_inventory() + local wield = player:get_wield_index() + local itemstack = inv:get_stack("main", wield+1) + return itemstack +end +local function set_item_next_to_wielded_item(player, itemstack) + local inv = player:get_inventory() + local wield = player:get_wield_index() + inv:set_stack("main", wield+1, itemstack) +end + +local function use_item_meta_editor(itemstack, user, pointed_thing) + if not user:is_player() then + return itemstack + end + local item_to_edit = get_item_next_to_wielded_item(user) + if item_to_edit:is_empty() then + minetest.chat_send_player(user:get_player_name(), S("Place an item next to the Item Meta Editor in your inventory first!")) + return itemstack + end + local meta = item_to_edit:get_meta() + show_meta_formspec(user, "item", item_to_edit, "", "", get_meta_keylist(meta, user:get_player_name(), true)) + return itemstack +end + +minetest.register_tool("testtools:item_meta_editor", { + description = S("Item Meta Editor") .. "\n" .. + S("Punch/Place: Edit item metadata of item in the next inventory slot"), + inventory_image = "testtools_item_meta_editor.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = use_item_meta_editor, + on_secondary_use = use_item_meta_editor, + on_place = use_item_meta_editor, +}) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if not (player and player:is_player()) then + return + end + if formname == "testtools:entity_list" then + local name = player:get_player_name() + if fields.entity_list then + local expl = minetest.explode_textlist_event(fields.entity_list) + if expl.type == "DCL" then + local pos = vector.add(player:get_pos(), {x=0,y=1,z=0}) + selections[name] = expl.index + minetest.add_entity(pos, get_entity_list()[expl.index]) + return + elseif expl.type == "CHG" then + selections[name] = expl.index + return + end + elseif fields.spawn and selections[name] then + local pos = vector.add(player:get_pos(), {x=0,y=1,z=0}) + minetest.add_entity(pos, get_entity_list()[selections[name]]) + return + end + elseif formname == "testtools:object_editor" then + local name = player:get_player_name() + if fields.object_props then + local expl = minetest.explode_textlist_event(fields.object_props) + if expl.type == "DCL" or expl.type == "CHG" then + property_formspec_index[name] = expl.index + + local props = selected_objects[name]:get_properties() + local keys = property_formspec_data[name] + if (not property_formspec_index[name]) or (not props) then + return + end + local key = keys[property_formspec_index[name]] + editor_formspec_selindex[name] = expl.index + editor_formspec(name, selected_objects[name], prop_to_string(props[key]), expl.index) + return + end + end + if fields.key_enter_field == "value" or fields.submit then + local props = selected_objects[name]:get_properties() + local keys = property_formspec_data[name] + if (not property_formspec_index[name]) or (not props) then + return + end + local key = keys[property_formspec_index[name]] + if not key then + return + end + local success, str = use_loadstring(fields.value, player) + if success then + props[key] = str + else + minetest.chat_send_player(name, str) + return + end + selected_objects[name]:set_properties(props) + local sel = editor_formspec_selindex[name] + editor_formspec(name, selected_objects[name], prop_to_string(props[key]), sel) + return + end + elseif formname == "testtools:node_setter" then + local playername = player:get_player_name() + local witem = player:get_wielded_item() + if witem:get_name() == "testtools:node_setter" then + if fields.nodename and fields.param2 then + local param2 = tonumber(fields.param2) + if not param2 then + return + end + local meta = witem:get_meta() + meta:set_string("node", fields.nodename) + meta:set_int("node_param2", param2) + player:set_wielded_item(witem) + end + end + elseif formname == "testtools:node_meta_editor" or formname == "testtools:item_meta_editor" then + local name = player:get_player_name() + local metatype + local pos_or_item + if formname == "testtools:node_meta_editor" then + metatype = "node" + pos_or_item = node_meta_posses[name] + else + metatype = "item" + pos_or_item = get_item_next_to_wielded_item(player) + end + if fields.keylist then + local evnt = minetest.explode_textlist_event(fields.keylist) + if evnt.type == "DCL" or evnt.type == "CHG" then + local keylist_table = meta_latest_keylist[name] + if metatype == "node" and not pos_or_item then + return + end + local meta + if metatype == "node" then + meta = minetest.get_meta(pos_or_item) + else + meta = pos_or_item:get_meta() + end + if not keylist_table then + return + end + if #keylist_table == 0 then + return + end + local key = keylist_table[evnt.index] + local value = meta:get_string(key) + local keylist_escaped = {} + for k,v in pairs(keylist_table) do + keylist_escaped[k] = F(v) + end + local keylist = table.concat(keylist_escaped, ",") + show_meta_formspec(player, metatype, pos_or_item, key, value, keylist) + return + end + elseif fields.key and fields.key ~= "" and fields.value then + if metatype == "node" and not pos_or_item then + return + end + local meta + if metatype == "node" then + meta = minetest.get_meta(pos_or_item) + elseif metatype == "item" then + if pos_or_item:is_empty() then + return + end + meta = pos_or_item:get_meta() + end + if fields.set then + meta:set_string(fields.key, fields.value) + if metatype == "item" then + set_item_next_to_wielded_item(player, pos_or_item) + end + show_meta_formspec(player, metatype, pos_or_item, fields.key, fields.value, + get_meta_keylist(meta, name, true)) + end + return + end + end +end) + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + meta_latest_keylist[name] = nil + node_meta_posses[name] = nil +end) diff --git a/games/devtest/mods/testtools/light.lua b/games/devtest/mods/testtools/light.lua new file mode 100644 index 0000000..afca9a4 --- /dev/null +++ b/games/devtest/mods/testtools/light.lua @@ -0,0 +1,37 @@ + +local S = minetest.get_translator("testtools") + +local function get_func(is_place) + return function(itemstack, user, pointed_thing) + local pos + if is_place then + pos = pointed_thing.under + else + pos = pointed_thing.above + end + if pointed_thing.type ~= "node" or not pos then + return + end + + local node = minetest.get_node(pos) + local pstr = minetest.pos_to_string(pos) + local time = minetest.get_timeofday() + local sunlight = minetest.get_natural_light(pos) + local artificial = minetest.get_artificial_light(node.param1) + local message = ("pos=%s | param1=0x%02x | " .. + "sunlight=%d | artificial=%d | timeofday=%.5f" ) + :format(pstr, node.param1, sunlight, artificial, time) + minetest.chat_send_player(user:get_player_name(), message) + end +end + +minetest.register_tool("testtools:lighttool", { + description = S("Light Tool") .. "\n" .. + S("Show light values of node") .. "\n" .. + S("Punch: Light of node above touched node") .. "\n" .. + S("Place: Light of touched node itself"), + inventory_image = "testtools_lighttool.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = get_func(false), + on_place = get_func(true), +}) diff --git a/games/devtest/mods/testtools/mod.conf b/games/devtest/mods/testtools/mod.conf new file mode 100644 index 0000000..cde1b26 --- /dev/null +++ b/games/devtest/mods/testtools/mod.conf @@ -0,0 +1,2 @@ +name = testtools +description = Some tools to directly manipulate nodes and entities. Great for development and testing diff --git a/games/devtest/mods/testtools/textures/testtools_children_getter.png b/games/devtest/mods/testtools/textures/testtools_children_getter.png new file mode 100644 index 0000000..b7fa340 Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_children_getter.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_entity_rotator.png b/games/devtest/mods/testtools/textures/testtools_entity_rotator.png new file mode 100644 index 0000000..17ebb2d Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_entity_rotator.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_entity_scaler.png b/games/devtest/mods/testtools/textures/testtools_entity_scaler.png new file mode 100644 index 0000000..4909c25 Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_entity_scaler.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_entity_spawner.png b/games/devtest/mods/testtools/textures/testtools_entity_spawner.png new file mode 100644 index 0000000..6199e01 Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_entity_spawner.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_falling_node_tool.png b/games/devtest/mods/testtools/textures/testtools_falling_node_tool.png new file mode 100644 index 0000000..30099a7 Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_falling_node_tool.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_item_meta_editor.png b/games/devtest/mods/testtools/textures/testtools_item_meta_editor.png new file mode 100644 index 0000000..5cebb0a Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_item_meta_editor.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_lighttool.png b/games/devtest/mods/testtools/textures/testtools_lighttool.png new file mode 100644 index 0000000..6f744b7 Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_lighttool.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_node_meta_editor.png b/games/devtest/mods/testtools/textures/testtools_node_meta_editor.png new file mode 100644 index 0000000..89eafd6 Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_node_meta_editor.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_node_setter.png b/games/devtest/mods/testtools/textures/testtools_node_setter.png new file mode 100644 index 0000000..8599438 Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_node_setter.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_object_attacher.png b/games/devtest/mods/testtools/textures/testtools_object_attacher.png new file mode 100644 index 0000000..4d9bf6f Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_object_attacher.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_object_editor.png b/games/devtest/mods/testtools/textures/testtools_object_editor.png new file mode 100644 index 0000000..d1ce9ce Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_object_editor.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_object_mover.png b/games/devtest/mods/testtools/textures/testtools_object_mover.png new file mode 100644 index 0000000..8b14e9f Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_object_mover.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_param2tool.png b/games/devtest/mods/testtools/textures/testtools_param2tool.png new file mode 100644 index 0000000..dbc6635 Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_param2tool.png differ diff --git a/games/devtest/mods/testtools/textures/testtools_remover.png b/games/devtest/mods/testtools/textures/testtools_remover.png new file mode 100644 index 0000000..73f14cd Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_remover.png differ diff --git a/games/devtest/mods/tiled/init.lua b/games/devtest/mods/tiled/init.lua new file mode 100644 index 0000000..68ead8e --- /dev/null +++ b/games/devtest/mods/tiled/init.lua @@ -0,0 +1,33 @@ +minetest.register_node("tiled:tiled", { + description = "Tiled Node (world-aligned)", + tiles = {{ + name = "tiled_tiled.png", + align_style = "world", + scale = 8, + }}, + groups = {cracky=3}, +}) + +minetest.register_node("tiled:tiled_n", { + description = "Tiled Node (node-aligned)", + tiles = {{ + name = "tiled_tiled.png", + align_style = "node", + scale = 8, + }}, + groups = {cracky=3}, +}) + +stairs.register_stair_and_slab("tiled_n", "tiled:tiled", + {cracky=3}, + {{name="tiled_tiled.png", align_style="node", scale=8}}, + "Tiled Stair (node-aligned)", + "Tiled Slab (node-aligned)") + +stairs.register_stair_and_slab("tiled", "tiled:tiled", + {cracky=3}, + {{name="tiled_tiled.png", align_style="world", scale=8}}, + "Tiled Stair (world-aligned)", + "Tiled Slab (world-aligned)") + + diff --git a/games/devtest/mods/tiled/mod.conf b/games/devtest/mods/tiled/mod.conf new file mode 100644 index 0000000..78b19f9 --- /dev/null +++ b/games/devtest/mods/tiled/mod.conf @@ -0,0 +1,3 @@ +name = tiled +description = Add nodes with a special texture that spans multiple nodes (aka "world-aligned") +depends = stairs diff --git a/games/devtest/mods/tiled/textures/tiled_tiled.png b/games/devtest/mods/tiled/textures/tiled_tiled.png new file mode 100644 index 0000000..363a264 Binary files /dev/null and b/games/devtest/mods/tiled/textures/tiled_tiled.png differ diff --git a/games/devtest/mods/unittests/async_env.lua b/games/devtest/mods/unittests/async_env.lua new file mode 100644 index 0000000..b7edf94 --- /dev/null +++ b/games/devtest/mods/unittests/async_env.lua @@ -0,0 +1,168 @@ +-- helper + +core.register_async_dofile(core.get_modpath(core.get_current_modname()) .. + DIR_DELIM .. "inside_async_env.lua") + +local function deepequal(a, b) + if type(a) == "function" then + return type(b) == "function" + elseif type(a) ~= "table" then + return a == b + elseif type(b) ~= "table" then + return false + end + for k, v in pairs(a) do + if not deepequal(v, b[k]) then + return false + end + end + for k, v in pairs(b) do + if not deepequal(a[k], v) then + return false + end + end + return true +end + +-- Object Passing / Serialization + +local test_object = { + name = "stairs:stair_glass", + type = "node", + groups = {oddly_breakable_by_hand = 3, cracky = 3, stair = 1}, + description = "Glass Stair", + sounds = { + dig = {name = "default_glass_footstep", gain = 0.5}, + footstep = {name = "default_glass_footstep", gain = 0.3}, + dug = {name = "default_break_glass", gain = 1} + }, + node_box = { + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.5, 0.5} + }, + type = "fixed" + }, + tiles = { + {name = "stairs_glass_split.png", backface_culling = true}, + {name = "default_glass.png", backface_culling = true}, + {name = "stairs_glass_stairside.png^[transformFX", backface_culling = true} + }, + on_place = function(itemstack, placer) + return core.is_player(placer) + end, + sunlight_propagates = true, + is_ground_content = false, + light_source = 0, +} + +local function test_object_passing() + local tmp = core.serialize_roundtrip(test_object) + assert(deepequal(test_object, tmp)) + + local circular_key = {"foo", "bar"} + circular_key[circular_key] = true + tmp = core.serialize_roundtrip(circular_key) + assert(tmp[1] == "foo") + assert(tmp[2] == "bar") + assert(tmp[tmp] == true) + + local circular_value = {"foo"} + circular_value[2] = circular_value + tmp = core.serialize_roundtrip(circular_value) + assert(tmp[1] == "foo") + assert(tmp[2] == tmp) + + -- Two-segment cycle + local cycle_seg_1, cycle_seg_2 = {}, {} + cycle_seg_1[1] = cycle_seg_2 + cycle_seg_2[1] = cycle_seg_1 + tmp = core.serialize_roundtrip(cycle_seg_1) + assert(tmp[1][1] == tmp) + + -- Duplicated value without a cycle + local acyclic_dup_holder = {} + tmp = ItemStack("") + acyclic_dup_holder[tmp] = tmp + tmp = core.serialize_roundtrip(acyclic_dup_holder) + for k, v in pairs(tmp) do + assert(rawequal(k, v)) + end +end +unittests.register("test_object_passing", test_object_passing) + +local function test_userdata_passing(_, pos) + -- basic userdata passing + local obj = table.copy(test_object.tiles[1]) + obj.test = ItemStack("default:cobble 99") + local tmp = core.serialize_roundtrip(obj) + assert(type(tmp.test) == "userdata") + assert(obj.test:to_string() == tmp.test:to_string()) + + -- object can't be passed, should error + obj = core.raycast(pos, pos) + assert(not pcall(core.serialize_roundtrip, obj)) + + -- VManip + local vm = core.get_voxel_manip(pos, pos) + local expect = vm:get_node_at(pos) + local vm2 = core.serialize_roundtrip(vm) + assert(deepequal(vm2:get_node_at(pos), expect)) +end +unittests.register("test_userdata_passing", test_userdata_passing, {map=true}) + +-- Asynchronous jobs + +local function test_handle_async(cb) + -- Basic test including mod name tracking and unittests.async_test() + -- which is defined inside_async_env.lua + local func = function(x) + return core.get_last_run_mod(), _VERSION, unittests[x]() + end + local expect = {core.get_last_run_mod(), _VERSION, true} + + core.handle_async(func, function(...) + if not deepequal(expect, {...}) then + return cb("Values did not equal") + end + if core.get_last_run_mod() ~= expect[1] then + return cb("Mod name not tracked correctly") + end + + -- Test passing of nil arguments and return values + core.handle_async(function(a, b) + return a, b + end, function(a, b) + if b ~= 123 then + return cb("Argument went missing") + end + cb() + end, nil, 123) + end, "async_test") +end +unittests.register("test_handle_async", test_handle_async, {async=true}) + +local function test_userdata_passing2(cb, _, pos) + -- VManip: check transfer into other env + local vm = core.get_voxel_manip(pos, pos) + local expect = vm:get_node_at(pos) + + core.handle_async(function(vm_, pos_) + return vm_:get_node_at(pos_) + end, function(ret) + if not deepequal(expect, ret) then + return cb("Node data mismatch (one-way)") + end + + -- VManip: test a roundtrip + core.handle_async(function(vm_) + return vm_ + end, function(vm2) + if not deepequal(expect, vm2:get_node_at(pos)) then + return cb("Node data mismatch (roundtrip)") + end + cb() + end, vm) + end, vm, pos) +end +unittests.register("test_userdata_passing2", test_userdata_passing2, {map=true, async=true}) diff --git a/games/devtest/mods/unittests/crafting.lua b/games/devtest/mods/unittests/crafting.lua new file mode 100644 index 0000000..8c16d3e --- /dev/null +++ b/games/devtest/mods/unittests/crafting.lua @@ -0,0 +1,112 @@ +dofile(core.get_modpath(core.get_current_modname()) .. "/crafting_prepare.lua") + +-- Test minetest.clear_craft function +local function test_clear_craft() + -- Clearing by output + minetest.register_craft({ + output = "foo", + recipe = {{"bar"}} + }) + minetest.register_craft({ + output = "foo 4", + recipe = {{"foo", "bar"}} + }) + assert(#minetest.get_all_craft_recipes("foo") == 2) + minetest.clear_craft({output="foo"}) + assert(minetest.get_all_craft_recipes("foo") == nil) + -- Clearing by input + minetest.register_craft({ + output = "foo 4", + recipe = {{"foo", "bar"}} + }) + assert(#minetest.get_all_craft_recipes("foo") == 1) + minetest.clear_craft({recipe={{"foo", "bar"}}}) + assert(minetest.get_all_craft_recipes("foo") == nil) +end +unittests.register("test_clear_craft", test_clear_craft) + +-- Test minetest.get_craft_result function +local function test_get_craft_result() + -- normal + local input = { + method = "normal", + width = 2, + items = {"", "unittests:coal_lump", "", "unittests:stick"} + } + minetest.log("info", "[unittests] torch crafting input: "..dump(input)) + local output, decremented_input = minetest.get_craft_result(input) + minetest.log("info", "[unittests] torch crafting output: "..dump(output)) + minetest.log("info", "[unittests] torch crafting decremented input: "..dump(decremented_input)) + assert(output.item) + minetest.log("info", "[unittests] torch crafting output.item:to_table(): "..dump(output.item:to_table())) + assert(output.item:get_name() == "unittests:torch") + assert(output.item:get_count() == 4) + + -- fuel + input = { + method = "fuel", + width = 1, + items = {"unittests:coal_lump"} + } + minetest.log("info", "[unittests] coal fuel input: "..dump(input)) + output, decremented_input = minetest.get_craft_result(input) + minetest.log("info", "[unittests] coal fuel output: "..dump(output)) + minetest.log("info", "[unittests] coal fuel decremented input: "..dump(decremented_input)) + assert(output.time) + assert(output.time > 0) + + -- cooking + input = { + method = "cooking", + width = 1, + items = {"unittests:iron_lump"} + } + minetest.log("info", "[unittests] iron lump cooking input: "..dump(output)) + output, decremented_input = minetest.get_craft_result(input) + minetest.log("info", "[unittests] iron lump cooking output: "..dump(output)) + minetest.log("info", "[unittests] iron lump cooking decremented input: "..dump(decremented_input)) + assert(output.time) + assert(output.time > 0) + assert(output.item) + minetest.log("info", "[unittests] iron lump cooking output.item:to_table(): "..dump(output.item:to_table())) + assert(output.item:get_name() == "unittests:steel_ingot") + assert(output.item:get_count() == 1) + + -- tool repair (repairable) + input = { + method = "normal", + width = 2, + -- Using a wear of 60000 + items = {"unittests:repairable_tool 1 60000", "unittests:repairable_tool 1 60000"} + } + minetest.log("info", "[unittests] repairable tool crafting input: "..dump(input)) + output, decremented_input = minetest.get_craft_result(input) + minetest.log("info", "[unittests] repairable tool crafting output: "..dump(output)) + minetest.log("info", "[unittests] repairable tool crafting decremented input: "..dump(decremented_input)) + assert(output.item) + minetest.log("info", "[unittests] repairable tool crafting output.item:to_table(): "..dump(output.item:to_table())) + assert(output.item:get_name() == "unittests:repairable_tool") + -- Test the wear value. + -- See src/craftdef.cpp in Minetest source code for the formula. The formula to calculate + -- the value 51187 is: + -- 65536 - ((65536-60000)+(65536-60000)) + floor(additonal_wear * 65536 + 0.5) = 51187 + -- where additional_wear = 0.05 + assert(output.item:get_wear() == 51187) + assert(output.item:get_count() == 1) + + -- failing tool repair (unrepairable) + input = { + method = "normal", + width = 2, + items = {"unittests:unrepairable_tool 1 60000", "unittests:unrepairable_tool 1 60000"} + } + minetest.log("info", "[unittests] unrepairable tool crafting input: "..dump(input)) + output, decremented_input = minetest.get_craft_result(input) + minetest.log("info", "[unittests] unrepairable tool crafting output: "..dump(output)) + minetest.log("info", "[unittests] unrepairable tool crafting decremented input: "..dump(decremented_input)) + assert(output.item) + minetest.log("info", "[unittests] unrepairable tool crafting output.item:to_table(): "..dump(output.item:to_table())) + -- unrepairable tool must not yield any output + assert(output.item:is_empty()) +end +unittests.register("test_get_craft_result", test_get_craft_result) diff --git a/games/devtest/mods/unittests/crafting_prepare.lua b/games/devtest/mods/unittests/crafting_prepare.lua new file mode 100644 index 0000000..5cf5775 --- /dev/null +++ b/games/devtest/mods/unittests/crafting_prepare.lua @@ -0,0 +1,94 @@ +-- Registering some dummy items and recipes for the crafting tests + +minetest.register_craftitem("unittests:torch", { + description = "Crafting Test Item: Torch", + inventory_image = "unittests_torch.png", + + groups = { dummy = 1 }, +}) +minetest.register_craftitem("unittests:coal_lump", { + description = "Crafting Test Item: Coal Lump", + inventory_image = "unittests_coal_lump.png", + + groups = { dummy = 1 }, +}) +minetest.register_craftitem("unittests:stick", { + description = "Crafting Test Item: Stick", + inventory_image = "unittests_stick.png", + + groups = { dummy = 1 }, +}) +minetest.register_craftitem("unittests:iron_lump", { + description = "Crafting Test Item: Iron Lump", + inventory_image = "unittests_iron_lump.png", + + groups = { dummy = 1 }, +}) +minetest.register_craftitem("unittests:steel_ingot", { + description = "Crafting Test Item: Steel Ingot", + inventory_image = "unittests_steel_ingot.png", + + groups = { dummy = 1 }, +}) + +-- Use aliases in recipes for more complete testing + +minetest.register_alias("unittests:steel_ingot_alias", "unittests:steel_ingot") +minetest.register_alias("unittests:coal_lump_alias", "unittests:coal_lump") +minetest.register_alias("unittests:iron_lump_alias", "unittests:iron_lump") + +-- Recipes for tests: Normal crafting, cooking and fuel + +minetest.register_craft({ + output = 'unittests:torch 4', + recipe = { + {'unittests:coal_lump_alias'}, + {'unittests:stick'}, + } +}) + +minetest.register_craft({ + type = "cooking", + output = "unittests:steel_ingot_alias", + recipe = "unittests:iron_lump_alias", +}) + +minetest.register_craft({ + type = "fuel", + recipe = "unittests:coal_lump_alias", + burntime = 40, +}) + +-- Test tool repair +minetest.register_craft({ + type = "toolrepair", + additional_wear = -0.05, +}) + +-- Test the disable_repair=1 group +minetest.register_tool("unittests:unrepairable_tool", { + description = "Crafting Test Item: Unrepairable Tool", + inventory_image = "unittests_unrepairable_tool.png", + tool_capabilities = { + groupcaps = { + cracky = { + times = {3, 2, 1}, + } + } + }, + groups = { disable_repair = 1, dummy = 1 } +}) + +minetest.register_tool("unittests:repairable_tool", { + description = "Crafting Test Item: Repairable Tool", + inventory_image = "unittests_repairable_tool.png", + tool_capabilities = { + groupcaps = { + cracky = { + times = {3, 2, 1}, + } + } + }, + + groups = { dummy = 1 }, +}) diff --git a/games/devtest/mods/unittests/entity.lua b/games/devtest/mods/unittests/entity.lua new file mode 100644 index 0000000..68635ca --- /dev/null +++ b/games/devtest/mods/unittests/entity.lua @@ -0,0 +1,132 @@ +local log = {} + +local function insert_log(...) + log[#log+1] = string.format(...) +end + +local function objref_str(self, ref) + if ref and ref:is_player() then + return "player" + end + return self.object == ref and "self" or tostring(ref) +end + +core.register_entity("unittests:callbacks", { + initial_properties = { + hp_max = 5, + visual = "upright_sprite", + textures = { "unittests_stick.png" }, + static_save = false, + }, + + on_activate = function(self, staticdata, dtime_s) + self.object:set_armor_groups({test = 100}) + assert(self.object:get_hp() == self.initial_properties.hp_max) + insert_log("on_activate(%d)", #staticdata) + end, + on_deactivate = function(self, removal) + insert_log("on_deactivate(%s)", tostring(removal)) + end, + on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) + insert_log("on_punch(%s, %.1f, %d)", objref_str(self, puncher), + time_from_last_punch, damage) + end, + on_death = function(self, killer) + assert(self.object:get_hp() == 0) + insert_log("on_death(%s)", objref_str(self, killer)) + end, + on_rightclick = function(self, clicker) + insert_log("on_rightclick(%s)", objref_str(self, clicker)) + end, + on_attach_child = function(self, child) + insert_log("on_attach_child(%s)", objref_str(self, child)) + end, + on_detach_child = function(self, child) + insert_log("on_detach_child(%s)", objref_str(self, child)) + end, + on_detach = function(self, parent) + insert_log("on_detach(%s)", objref_str(self, parent)) + end, + get_staticdata = function(self) + assert(false) + end, +}) + +-- + +local function check_log(expect) + if #expect ~= #log then + error("Log mismatch: " .. core.write_json(log)) + end + for i, s in ipairs(expect) do + if log[i] ~= s then + error("Log mismatch at " .. i .. ": " .. core.write_json(log)) + end + end + log = {} -- clear it for next time +end + +local function test_entity_lifecycle(_, pos) + log = {} + + -- with binary in staticdata + local obj = core.add_entity(pos, "unittests:callbacks", "abc\000def") + check_log({"on_activate(7)"}) + + obj:set_hp(0) + check_log({"on_death(nil)", "on_deactivate(true)"}) + + -- objectref must be invalid now + assert(obj:get_velocity() == nil) +end +unittests.register("test_entity_lifecycle", test_entity_lifecycle, {map=true}) + +local function test_entity_interact(_, pos) + log = {} + + local obj = core.add_entity(pos, "unittests:callbacks") + check_log({"on_activate(0)"}) + + -- rightclick + obj:right_click(obj) + check_log({"on_rightclick(self)"}) + + -- useless punch + obj:punch(obj, 0.5, {}) + check_log({"on_punch(self, 0.5, 0)"}) + + -- fatal punch + obj:punch(obj, 1.9, { + full_punch_interval = 1.0, + damage_groups = { test = 10 }, + }) + check_log({ + -- does 10 damage even though we only have 5 hp + "on_punch(self, 1.9, 10)", + "on_death(self)", + "on_deactivate(true)" + }) +end +unittests.register("test_entity_interact", test_entity_interact, {map=true}) + +local function test_entity_attach(player, pos) + log = {} + + local obj = core.add_entity(pos, "unittests:callbacks") + check_log({"on_activate(0)"}) + + -- attach player to entity + player:set_attach(obj) + check_log({"on_attach_child(player)"}) + player:set_detach() + check_log({"on_detach_child(player)"}) + + -- attach entity to player + obj:set_attach(player) + check_log({}) + obj:set_detach() + check_log({"on_detach(player)"}) + + obj:remove() +end +unittests.register("test_entity_attach", test_entity_attach, {player=true, map=true}) diff --git a/games/devtest/mods/unittests/init.lua b/games/devtest/mods/unittests/init.lua new file mode 100644 index 0000000..0e041be --- /dev/null +++ b/games/devtest/mods/unittests/init.lua @@ -0,0 +1,202 @@ +unittests = {} + +unittests.list = {} + +-- name: Name of the test +-- func: +-- for sync: function(player, pos), should error on failure +-- for async: function(callback, player, pos) +-- MUST call callback() or callback("error msg") in case of error once test is finished +-- this means you cannot use assert() in the test implementation +-- opts: { +-- player = false, -- Does test require a player? +-- map = false, -- Does test require map access? +-- async = false, -- Does the test run asynchronously? (read notes above!) +-- } +function unittests.register(name, func, opts) + local def = table.copy(opts or {}) + def.name = name + def.func = func + table.insert(unittests.list, def) +end + +function unittests.on_finished(all_passed) + -- free to override +end + +-- Calls invoke with a callback as argument +-- Suspends coroutine until that callback is called +-- Return values are passed through +local function await(invoke) + local co = coroutine.running() + assert(co) + local called_early = true + invoke(function(...) + if called_early == true then + called_early = {...} + else + coroutine.resume(co, ...) + co = nil + end + end) + if called_early ~= true then + -- callback was already called before yielding + return unpack(called_early) + end + called_early = nil + return coroutine.yield() +end + +function unittests.run_one(idx, counters, out_callback, player, pos) + local def = unittests.list[idx] + if not def.player then + player = nil + elseif player == nil then + out_callback(false) + return false + end + if not def.map then + pos = nil + elseif pos == nil then + out_callback(false) + return false + end + + local tbegin = core.get_us_time() + local function done(status, err) + local tend = core.get_us_time() + local ms_taken = (tend - tbegin) / 1000 + + if not status then + core.log("error", err) + end + print(string.format("[%s] %s - %dms", + status and "PASS" or "FAIL", def.name, ms_taken)) + counters.time = counters.time + ms_taken + counters.total = counters.total + 1 + if status then + counters.passed = counters.passed + 1 + end + end + + if def.async then + core.log("info", "[unittest] running " .. def.name .. " (async)") + def.func(function(err) + done(err == nil, err) + out_callback(true) + end, player, pos) + else + core.log("info", "[unittest] running " .. def.name) + local status, err = pcall(def.func, player, pos) + done(status, err) + out_callback(true) + end + + return true +end + +local function wait_for_player(callback) + if #core.get_connected_players() > 0 then + return callback(core.get_connected_players()[1]) + end + local first = true + core.register_on_joinplayer(function(player) + if first then + callback(player) + first = false + end + end) +end + +local function wait_for_map(player, callback) + local check = function() + if core.get_node_or_nil(player:get_pos()) ~= nil then + callback() + else + core.after(0, check) + end + end + check() +end + +function unittests.run_all() + -- This runs in a coroutine so it uses await(). + local counters = { time = 0, total = 0, passed = 0 } + + -- Run standalone tests first + for idx = 1, #unittests.list do + local def = unittests.list[idx] + def.done = await(function(cb) + unittests.run_one(idx, counters, cb, nil, nil) + end) + end + + -- Wait for a player to join, run tests that require a player + local player = await(wait_for_player) + for idx = 1, #unittests.list do + local def = unittests.list[idx] + if not def.done then + def.done = await(function(cb) + unittests.run_one(idx, counters, cb, player, nil) + end) + end + end + + -- Wait for the world to generate/load, run tests that require map access + await(function(cb) + wait_for_map(player, cb) + end) + local pos = vector.round(player:get_pos()) + for idx = 1, #unittests.list do + local def = unittests.list[idx] + if not def.done then + def.done = await(function(cb) + unittests.run_one(idx, counters, cb, player, pos) + end) + end + end + + -- Print stats + assert(#unittests.list == counters.total) + print(string.rep("+", 80)) + print(string.format("Unit Test Results: %s", + counters.total == counters.passed and "PASSED" or "FAILED")) + print(string.format(" %d / %d failed tests.", + counters.total - counters.passed, counters.total)) + print(string.format(" Testing took %dms total.", counters.time)) + print(string.rep("+", 80)) + unittests.on_finished(counters.total == counters.passed) + return counters.total == counters.passed +end + +-------------- + +local modpath = core.get_modpath("unittests") +dofile(modpath .. "/misc.lua") +dofile(modpath .. "/player.lua") +dofile(modpath .. "/crafting.lua") +dofile(modpath .. "/itemdescription.lua") +dofile(modpath .. "/async_env.lua") +dofile(modpath .. "/entity.lua") + +-------------- + +if core.settings:get_bool("devtest_unittests_autostart", false) then + core.after(0, function() + coroutine.wrap(unittests.run_all)() + end) +else + core.register_chatcommand("unittests", { + privs = {basic_privs=true}, + description = "Runs devtest unittests (may modify player or map state)", + func = function(name, param) + unittests.on_finished = function(ok) + core.chat_send_player(name, + (ok and "All tests passed." or "There were test failures.") .. + " Check the console for detailed output.") + end + coroutine.wrap(unittests.run_all)() + return true, "" + end, + }) +end diff --git a/games/devtest/mods/unittests/inside_async_env.lua b/games/devtest/mods/unittests/inside_async_env.lua new file mode 100644 index 0000000..4ed0fcc --- /dev/null +++ b/games/devtest/mods/unittests/inside_async_env.lua @@ -0,0 +1,25 @@ +unittests = {} + +core.log("info", "Hello World") + +local function do_tests() + assert(core == minetest) + -- stuff that should not be here + assert(not core.get_player_by_name) + assert(not core.set_node) + assert(not core.object_refs) + -- stuff that should be here + assert(ItemStack) + assert(core.registered_items[""]) + -- alias handling + assert(core.registered_items["unittests:steel_ingot_alias"].name == + "unittests:steel_ingot") +end + +function unittests.async_test() + local ok, err = pcall(do_tests) + if not ok then + core.log("error", err) + end + return ok +end diff --git a/games/devtest/mods/unittests/itemdescription.lua b/games/devtest/mods/unittests/itemdescription.lua new file mode 100644 index 0000000..b4c218c --- /dev/null +++ b/games/devtest/mods/unittests/itemdescription.lua @@ -0,0 +1,42 @@ +local full_description = "Description Test Item\nFor testing item decription" +minetest.register_tool("unittests:description_test", { + description = full_description, + inventory_image = "unittests_description_test.png", +}) + +minetest.register_chatcommand("item_description", { + param = "", + description = "Show the short and full description of the wielded item.", + func = function(name) + local player = minetest.get_player_by_name(name) + local item = player:get_wielded_item() + return true, string.format("short_description: %s\ndescription: %s", + item:get_short_description(), item:get_description()) + end +}) + +local function test_short_desc() + local function get_short_description(item) + return ItemStack(item):get_short_description() + end + + local stack = ItemStack("unittests:description_test") + assert(stack:get_short_description() == "Description Test Item") + assert(get_short_description("unittests:description_test") == "Description Test Item") + assert(minetest.registered_items["unittests:description_test"].short_description == nil) + assert(stack:get_description() == full_description) + assert(stack:get_description() == minetest.registered_items["unittests:description_test"].description) + + stack:get_meta():set_string("description", "Hello World") + assert(stack:get_short_description() == "Hello World") + assert(stack:get_description() == "Hello World") + assert(get_short_description(stack) == "Hello World") + assert(get_short_description("unittests:description_test") == "Description Test Item") + + stack:get_meta():set_string("short_description", "Foo Bar") + assert(stack:get_short_description() == "Foo Bar") + assert(stack:get_description() == "Hello World") + + return true +end +unittests.register("test_short_desc", test_short_desc) diff --git a/games/devtest/mods/unittests/misc.lua b/games/devtest/mods/unittests/misc.lua new file mode 100644 index 0000000..4811c80 --- /dev/null +++ b/games/devtest/mods/unittests/misc.lua @@ -0,0 +1,82 @@ +local function test_random() + -- Try out PseudoRandom + local pseudo = PseudoRandom(13) + assert(pseudo:next() == 22290) + assert(pseudo:next() == 13854) +end +unittests.register("test_random", test_random) + +local function test_dynamic_media(cb, player) + if core.get_player_information(player:get_player_name()).protocol_version < 40 then + core.log("warning", "test_dynamic_media: Client too old, skipping test.") + return cb() + end + + -- Check that the client acknowledges media transfers + local path = core.get_worldpath() .. "/test_media.obj" + local f = io.open(path, "w") + f:write("# contents don't matter\n") + f:close() + + local call_ok = false + local ok = core.dynamic_add_media({ + filepath = path, + to_player = player:get_player_name(), + }, function(name) + if not call_ok then + return cb("impossible condition") + end + cb() + end) + if not ok then + return cb("dynamic_add_media() returned error") + end + call_ok = true + + -- if the callback isn't called this test will just hang :shrug: +end +unittests.register("test_dynamic_media", test_dynamic_media, {async=true, player=true}) + +local function test_v3f_metatable(player) + assert(vector.check(player:get_pos())) +end +unittests.register("test_v3f_metatable", test_v3f_metatable, {player=true}) + +local function test_v3s16_metatable(player, pos) + local node = minetest.get_node(pos) + local found_pos = minetest.find_node_near(pos, 0, node.name, true) + assert(vector.check(found_pos)) +end +unittests.register("test_v3s16_metatable", test_v3s16_metatable, {map=true}) + +local function test_clear_meta(_, pos) + local ref = core.get_meta(pos) + + for way = 1, 3 do + ref:set_string("foo", "bar") + assert(ref:contains("foo")) + + if way == 1 then + ref:from_table({}) + elseif way == 2 then + ref:from_table(nil) + else + ref:set_string("foo", "") + end + + assert(#core.find_nodes_with_meta(pos, pos) == 0, "clearing failed " .. way) + end +end +unittests.register("test_clear_meta", test_clear_meta, {map=true}) + +local on_punch_called +minetest.register_on_punchnode(function() + on_punch_called = true +end) +unittests.register("test_punch_node", function(_, pos) + minetest.place_node(pos, {name="basenodes:dirt"}) + on_punch_called = false + minetest.punch_node(pos) + minetest.remove_node(pos) + -- currently failing: assert(on_punch_called) +end, {map=true}) diff --git a/games/devtest/mods/unittests/mod.conf b/games/devtest/mods/unittests/mod.conf new file mode 100644 index 0000000..fa94e01 --- /dev/null +++ b/games/devtest/mods/unittests/mod.conf @@ -0,0 +1,3 @@ +name = unittests +description = Adds automated unit tests for the engine +depends = basenodes diff --git a/games/devtest/mods/unittests/player.lua b/games/devtest/mods/unittests/player.lua new file mode 100644 index 0000000..fa05579 --- /dev/null +++ b/games/devtest/mods/unittests/player.lua @@ -0,0 +1,70 @@ +-- +-- HP Change Reasons +-- +local expect = nil +minetest.register_on_player_hpchange(function(player, hp, reason) + if expect == nil then + return + end + + for key, value in pairs(reason) do + assert(expect[key] == value) + end + for key, value in pairs(expect) do + assert(reason[key] == value) + end + + expect = nil +end) + +local function run_hpchangereason_tests(player) + local old_hp = player:get_hp() + + player:set_hp(20) + expect = { type = "set_hp", from = "mod" } + player:set_hp(3) + assert(expect == nil) + + expect = { a = 234, type = "set_hp", from = "mod" } + player:set_hp(7, { a= 234 }) + assert(expect == nil) + + expect = { df = 3458973454, type = "fall", from = "mod" } + player:set_hp(10, { type = "fall", df = 3458973454 }) + assert(expect == nil) + + player:set_hp(old_hp) +end +unittests.register("test_hpchangereason", run_hpchangereason_tests, {player=true}) + +-- +-- Player meta +-- +local function run_player_meta_tests(player) + local meta = player:get_meta() + meta:set_string("foo", "bar") + assert(meta:contains("foo")) + assert(meta:get_string("foo") == "bar") + assert(meta:get("foo") == "bar") + + local meta2 = player:get_meta() + assert(meta2:get_string("foo") == "bar") + assert(meta2:get("foo") == "bar") + assert(meta:equals(meta2)) + + meta:set_string("bob", "dillan") + assert(meta:get_string("foo") == "bar") + assert(meta:get_string("bob") == "dillan") + assert(meta:get("bob") == "dillan") + assert(meta2:get_string("foo") == "bar") + assert(meta2:get_string("bob") == "dillan") + assert(meta2:get("bob") == "dillan") + assert(meta:equals(meta2)) + + meta:set_string("foo", "") + assert(not meta:contains("foo")) + assert(meta:get("foo") == nil) + assert(meta:get_string("foo") == "") + assert(meta:equals(meta2)) +end +unittests.register("test_player_meta", run_player_meta_tests, {player=true}) diff --git a/games/devtest/mods/unittests/textures/default_dirt.png b/games/devtest/mods/unittests/textures/default_dirt.png new file mode 100644 index 0000000..5867030 Binary files /dev/null and b/games/devtest/mods/unittests/textures/default_dirt.png differ diff --git a/games/devtest/mods/unittests/textures/unittests_coal_lump.png b/games/devtest/mods/unittests/textures/unittests_coal_lump.png new file mode 100644 index 0000000..f460d90 Binary files /dev/null and b/games/devtest/mods/unittests/textures/unittests_coal_lump.png differ diff --git a/games/devtest/mods/unittests/textures/unittests_description_test.png b/games/devtest/mods/unittests/textures/unittests_description_test.png new file mode 100644 index 0000000..a6be433 Binary files /dev/null and b/games/devtest/mods/unittests/textures/unittests_description_test.png differ diff --git a/games/devtest/mods/unittests/textures/unittests_iron_lump.png b/games/devtest/mods/unittests/textures/unittests_iron_lump.png new file mode 100644 index 0000000..22f43e9 Binary files /dev/null and b/games/devtest/mods/unittests/textures/unittests_iron_lump.png differ diff --git a/games/devtest/mods/unittests/textures/unittests_repairable_tool.png b/games/devtest/mods/unittests/textures/unittests_repairable_tool.png new file mode 100644 index 0000000..46fbbaa Binary files /dev/null and b/games/devtest/mods/unittests/textures/unittests_repairable_tool.png differ diff --git a/games/devtest/mods/unittests/textures/unittests_steel_ingot.png b/games/devtest/mods/unittests/textures/unittests_steel_ingot.png new file mode 100644 index 0000000..6977696 Binary files /dev/null and b/games/devtest/mods/unittests/textures/unittests_steel_ingot.png differ diff --git a/games/devtest/mods/unittests/textures/unittests_stick.png b/games/devtest/mods/unittests/textures/unittests_stick.png new file mode 100644 index 0000000..ffdce70 Binary files /dev/null and b/games/devtest/mods/unittests/textures/unittests_stick.png differ diff --git a/games/devtest/mods/unittests/textures/unittests_torch.png b/games/devtest/mods/unittests/textures/unittests_torch.png new file mode 100644 index 0000000..ba5eebe Binary files /dev/null and b/games/devtest/mods/unittests/textures/unittests_torch.png differ diff --git a/games/devtest/mods/unittests/textures/unittests_unrepairable_tool.png b/games/devtest/mods/unittests/textures/unittests_unrepairable_tool.png new file mode 100644 index 0000000..c676213 Binary files /dev/null and b/games/devtest/mods/unittests/textures/unittests_unrepairable_tool.png differ diff --git a/games/devtest/mods/util_commands/init.lua b/games/devtest/mods/util_commands/init.lua new file mode 100644 index 0000000..c373640 --- /dev/null +++ b/games/devtest/mods/util_commands/init.lua @@ -0,0 +1,309 @@ +minetest.register_chatcommand("hotbar", { + params = "<size>", + description = "Set hotbar size", + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "No player." + end + local size = tonumber(param) + if not size then + return false, "Missing or incorrect size parameter!" + end + local ok = player:hud_set_hotbar_itemcount(size) + if ok then + return true + else + return false, "Invalid item count!" + end + end, +}) + +minetest.register_chatcommand("hp", { + params = "<hp>", + description = "Set your health", + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "No player." + end + local hp = tonumber(param) + if not hp then + return false, "Missing or incorrect hp parameter!" + end + player:set_hp(hp) + return true + end, +}) + +minetest.register_on_joinplayer(function(player) + player:set_properties({zoom_fov = 15}) +end) + +minetest.register_chatcommand("zoomfov", { + params = "[<FOV>]", + description = "Set or display your zoom_fov", + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "No player." + end + if param == "" then + local fov = player:get_properties().zoom_fov + return true, "zoom_fov = "..tostring(fov) + end + local fov = tonumber(param) + if not fov then + return false, "Missing or incorrect zoom_fov parameter!" + end + player:set_properties({zoom_fov = fov}) + fov = player:get_properties().zoom_fov + return true, "zoom_fov = "..tostring(fov) + end, +}) + +local s_infplace = minetest.settings:get("devtest_infplace") +if s_infplace == "true" then + infplace = true +elseif s_infplace == "false" then + infplace = false +else + infplace = minetest.is_creative_enabled("") +end + +minetest.register_chatcommand("infplace", { + params = "", + description = "Toggle infinite node placement", + func = function(name, param) + infplace = not infplace + if infplace then + minetest.chat_send_all("Infinite node placement enabled!") + minetest.log("action", "Infinite node placement enabled") + else + minetest.chat_send_all("Infinite node placement disabled!") + minetest.log("action", "Infinite node placement disabled") + end + return true + end, +}) + +minetest.register_chatcommand("detach", { + params = "[<radius>]", + description = "Detach all objects nearby", + func = function(name, param) + local radius = tonumber(param) + if type(radius) ~= "number" then + radius = 8 + end + if radius < 1 then + radius = 1 + end + local player = minetest.get_player_by_name(name) + if not player then + return false, "No player." + end + local objs = minetest.get_objects_inside_radius(player:get_pos(), radius) + local num = 0 + for o=1, #objs do + if objs[o]:get_attach() then + objs[o]:set_detach() + num = num + 1 + end + end + return true, string.format("%d object(s) detached.", num) + end, +}) + +minetest.register_chatcommand("use_tool", { + params = "(dig <group> <leveldiff>) | (hit <damage_group> <time_from_last_punch>) [<uses>]", + description = "Apply tool wear a number of times, as if it were used for digging", + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "No player." + end + local mode, group, level, uses = string.match(param, "([a-z]+) ([a-z0-9]+) (-?%d+) (%d+)") + if not mode then + mode, group, level = string.match(param, "([a-z]+) ([a-z0-9]+) (-?%d+)") + uses = 1 + end + if not mode or not group or not level then + return false + end + if mode ~= "dig" and mode ~= "hit" then + return false + end + local tool = player:get_wielded_item() + local caps = tool:get_tool_capabilities() + if not caps or tool:get_count() == 0 then + return false, "No tool in hand." + end + local actual_uses = 0 + for u=1, uses do + local wear = tool:get_wear() + local dp + if mode == "dig" then + dp = minetest.get_dig_params({[group]=3, level=level}, caps, wear) + else + dp = minetest.get_hit_params({[group]=100}, caps, level, wear) + end + tool:add_wear(dp.wear) + actual_uses = actual_uses + 1 + if tool:get_count() == 0 then + break + end + end + player:set_wielded_item(tool) + if tool:get_count() == 0 then + return true, string.format("Tool used %d time(s). ".. + "The tool broke after %d use(s).", uses, actual_uses) + else + local wear = tool:get_wear() + return true, string.format("Tool used %d time(s). ".. + "Final wear=%d", uses, wear) + end + end, +}) + + + +-- Use this to test waypoint capabilities +minetest.register_chatcommand("test_waypoints", { + params = "[change_immediate]", + description = "tests waypoint capabilities", + func = function(name, params) + local player = minetest.get_player_by_name(name) + local regular = player:hud_add { + hud_elem_type = "waypoint", + name = "regular waypoint", + text = "m", + number = 0xFF0000, + world_pos = vector.add(player:get_pos(), {x = 0, y = 1.5, z = 0}) + } + local reduced_precision = player:hud_add { + hud_elem_type = "waypoint", + name = "better waypoint", + text = "m (0.5 steps, precision = 2)", + precision = 10, + number = 0xFFFF00, + world_pos = vector.add(player:get_pos(), {x = 0, y = 1, z = 0}) + } + local function change() + if regular then + player:hud_change(regular, "world_pos", vector.add(player:get_pos(), {x = 0, y = 3, z = 0})) + end + if reduced_precision then + player:hud_change(reduced_precision, "precision", 2) + end + end + if params ~= "" then + -- change immediate + change() + else + minetest.after(0.5, change) + end + regular = regular or "error" + reduced_precision = reduced_precision or "error" + local hidden_distance = player:hud_add { + hud_elem_type = "waypoint", + name = "waypoint with hidden distance", + text = "this text is hidden as well (precision = 0)", + precision = 0, + number = 0x0000FF, + world_pos = vector.add(player:get_pos(), {x = 0, y = 0.5, z = 0}) + } or "error" + local image_waypoint = player:hud_add { + hud_elem_type = "image_waypoint", + text = "wieldhand.png", + world_pos = player:get_pos(), + scale = {x = 10, y = 10}, + offset = {x = 0, y = -32} + } or "error" + minetest.chat_send_player(name, "Waypoint IDs: regular: " .. regular .. ", reduced precision: " .. reduced_precision .. + ", hidden distance: " .. hidden_distance .. ", image waypoint: " .. image_waypoint) + end +}) + +-- Unlimited node placement +minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) + if placer and placer:is_player() then + return infplace + end +end) + +-- Don't pick up if the item is already in the inventory +local old_handle_node_drops = minetest.handle_node_drops +function minetest.handle_node_drops(pos, drops, digger) + if not digger or not digger:is_player() or not infplace then + return old_handle_node_drops(pos, drops, digger) + end + local inv = digger:get_inventory() + if inv then + for _, item in ipairs(drops) do + if not inv:contains_item("main", item, true) then + inv:add_item("main", item) + end + end + end +end + +minetest.register_chatcommand("set_displayed_itemcount", { + params = "(-s \"<string>\" [-c <color>]) | -a <alignment_num>", + description = "Set the displayed itemcount of the wielded item", + func = function(name, param) + local player = minetest.get_player_by_name(name) + local item = player:get_wielded_item() + local meta = item:get_meta() + local flag1 = param:sub(1, 2) + if flag1 == "-s" then + if param:sub(3, 4) ~= " \"" then + return false, "Error: Space and string with \"s expected after -s." + end + local se = param:find("\"", 5, true) + if not se then + return false, "Error: String with two \"s expected after -s." + end + local s = param:sub(5, se - 1) + if param:sub(se + 1, se + 4) == " -c " then + s = minetest.colorize(param:sub(se + 5), s) + end + meta:set_string("count_meta", s) + elseif flag1 == "-a" then + local num = tonumber(param:sub(4)) + if not num then + return false, "Error: Invalid number: "..param:sub(4) + end + meta:set_int("count_alignment", num) + else + return false + end + player:set_wielded_item(item) + return true, "Displayed itemcount set." + end, +}) + +minetest.register_chatcommand("dump_item", { + params = "", + description = "Prints a dump of the wielded item in table form", + func = function(name, param) + local player = minetest.get_player_by_name(name) + local item = player:get_wielded_item() + local str = dump(item:to_table()) + print(str) + return true, str + end, +}) + +-- shadow control +minetest.register_on_joinplayer(function (player) + player:set_lighting({shadows={intensity = 0.33}}) +end) + +core.register_chatcommand("set_shadow", { + params = "<shadow_intensity>", + description = "Set shadow parameters of current player.", + func = function(player_name, param) + local shadow_intensity = tonumber(param) + minetest.get_player_by_name(player_name):set_lighting({shadows = { intensity = shadow_intensity} }) + end +}) diff --git a/games/devtest/mods/util_commands/mod.conf b/games/devtest/mods/util_commands/mod.conf new file mode 100644 index 0000000..fea6dd3 --- /dev/null +++ b/games/devtest/mods/util_commands/mod.conf @@ -0,0 +1,2 @@ +name = util_commands +description = Random server commands to make testing easier and more convenient diff --git a/games/devtest/screenshot.png b/games/devtest/screenshot.png new file mode 100644 index 0000000..7324883 Binary files /dev/null and b/games/devtest/screenshot.png differ diff --git a/games/devtest/settingtypes.txt b/games/devtest/settingtypes.txt new file mode 100644 index 0000000..c436564 --- /dev/null +++ b/games/devtest/settingtypes.txt @@ -0,0 +1,32 @@ +# If enabled, nodes won't be used up when placed. +# Note: This behavior can also be toggled in-game with the /infplace command. +# +# - true: enabled +# - false: disabled +# - auto: only enabled when Creative Mode is enabled (default) +devtest_infplace (Infinite node placement) enum auto true,false,auto + +# If enabled, new players receive some initial items when joining for the first time. +give_initial_stuff (Give initial stuff) bool true + +# If enabled, automated tests of the Lua API such as player health, crafting and PseudoRandom will be performed on startup. +devtest_unittests_autostart (Perform unit tests) bool false + +# If enabled, the game will use all mapgen aliases for the v6 mapgen. +# If disabled, it will only use a minimal set of mapgen aliases. +# If enabled, there should be biome-specific tree, leaves and ground nodes. If disabled, stuff should use fallback nodes (like stone instead of desert stone). +# +# Many mapgen aliases have fallback values when no value is provided. Having this setting disabled can be useful to test whether those fallback values are functional. +devtest_v6_mapgen_aliases (Use all v6 mapgen aliases) bool false + +# If enabled, the game will use dungeon stairs by enabling the corresponding mapgen aliases. +# +# Disabling this setting can be useful to test whether dungeons still work when stairs are not defined. +devtest_dungeon_stairs (Generate dungeon stairs) bool false + +# If enabled, the mapgen alias 'mapgen_mossycobble' will be used. This should enable random mossy cobblestone in dungeons. +# If disabled, it won't be used. The engine should fall back to cobble instead. +devtest_dungeon_mossycobble (Generate mossy cobblestone) bool false + +# If enabled, some very basic biomes will be registered. +devtest_register_biomes (Register biomes) bool true diff --git a/lib/bitop/CMakeLists.txt b/lib/bitop/CMakeLists.txt new file mode 100644 index 0000000..02e8a42 --- /dev/null +++ b/lib/bitop/CMakeLists.txt @@ -0,0 +1,4 @@ +add_library(bitop STATIC bit.c) +target_link_libraries(bitop) + +include_directories(${LUA_INCLUDE_DIR}) diff --git a/lib/bitop/bit.c b/lib/bitop/bit.c new file mode 100644 index 0000000..f23c31a --- /dev/null +++ b/lib/bitop/bit.c @@ -0,0 +1,189 @@ +/* +** Lua BitOp -- a bit operations library for Lua 5.1/5.2. +** http://bitop.luajit.org/ +** +** Copyright (C) 2008-2012 Mike Pall. 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. +** +** [ MIT license: http://www.opensource.org/licenses/mit-license.php ] +*/ + +#include "bit.h" + +#define LUA_BITOP_VERSION "1.0.2" + +#define LUA_LIB +#include "lauxlib.h" + +#ifdef _MSC_VER +/* MSVC is stuck in the last century and doesn't have C99's stdint.h. */ +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +#else +#include <stdint.h> +#endif + +typedef int32_t SBits; +typedef uint32_t UBits; + +typedef union { + lua_Number n; +#ifdef LUA_NUMBER_DOUBLE + uint64_t b; +#else + UBits b; +#endif +} BitNum; + +/* Convert argument to bit type. */ +static UBits barg(lua_State *L, int idx) +{ + BitNum bn; + UBits b; +#if LUA_VERSION_NUM < 502 + bn.n = lua_tonumber(L, idx); +#else + bn.n = luaL_checknumber(L, idx); +#endif +#if defined(LUA_NUMBER_DOUBLE) + bn.n += 6755399441055744.0; /* 2^52+2^51 */ +#ifdef SWAPPED_DOUBLE + b = (UBits)(bn.b >> 32); +#else + b = (UBits)bn.b; +#endif +#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \ + defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \ + defined(LUA_NUMBER_LLONG) + if (sizeof(UBits) == sizeof(lua_Number)) + b = bn.b; + else + b = (UBits)(SBits)bn.n; +#elif defined(LUA_NUMBER_FLOAT) +#error "A 'float' lua_Number type is incompatible with this library" +#else +#error "Unknown number type, check LUA_NUMBER_* in luaconf.h" +#endif +#if LUA_VERSION_NUM < 502 + if (b == 0 && !lua_isnumber(L, idx)) { + luaL_typerror(L, idx, "number"); + } +#endif + return b; +} + +/* Return bit type. */ +#define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1; + +static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) } +static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) } + +#define BIT_OP(func, opr) \ + static int func(lua_State *L) { int i; UBits b = barg(L, 1); \ + for (i = lua_gettop(L); i > 1; i--) b opr barg(L, i); BRET(b) } +BIT_OP(bit_band, &=) +BIT_OP(bit_bor, |=) +BIT_OP(bit_bxor, ^=) + +#define bshl(b, n) (b << n) +#define bshr(b, n) (b >> n) +#define bsar(b, n) ((SBits)b >> n) +#define brol(b, n) ((b << n) | (b >> (32-n))) +#define bror(b, n) ((b << (32-n)) | (b >> n)) +#define BIT_SH(func, fn) \ + static int func(lua_State *L) { \ + UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) } +BIT_SH(bit_lshift, bshl) +BIT_SH(bit_rshift, bshr) +BIT_SH(bit_arshift, bsar) +BIT_SH(bit_rol, brol) +BIT_SH(bit_ror, bror) + +static int bit_bswap(lua_State *L) +{ + UBits b = barg(L, 1); + b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24); + BRET(b) +} + +static int bit_tohex(lua_State *L) +{ + UBits b = barg(L, 1); + SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2); + const char *hexdigits = "0123456789abcdef"; + char buf[8]; + int i; + if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } + if (n > 8) n = 8; + for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; } + lua_pushlstring(L, buf, (size_t)n); + return 1; +} + +static const struct luaL_Reg bit_funcs[] = { + { "tobit", bit_tobit }, + { "bnot", bit_bnot }, + { "band", bit_band }, + { "bor", bit_bor }, + { "bxor", bit_bxor }, + { "lshift", bit_lshift }, + { "rshift", bit_rshift }, + { "arshift", bit_arshift }, + { "rol", bit_rol }, + { "ror", bit_ror }, + { "bswap", bit_bswap }, + { "tohex", bit_tohex }, + { NULL, NULL } +}; + +/* Signed right-shifts are implementation-defined per C89/C99. +** But the de facto standard are arithmetic right-shifts on two's +** complement CPUs. This behaviour is required here, so test for it. +*/ +#define BAD_SAR (bsar(-8, 2) != (SBits)-2) + +LUALIB_API int luaopen_bit(lua_State *L) +{ + UBits b; + lua_pushnumber(L, (lua_Number)1437217655L); + b = barg(L, -1); + if (b != (UBits)1437217655L || BAD_SAR) { /* Perform a simple self-test. */ + const char *msg = "compiled with incompatible luaconf.h"; +#ifdef LUA_NUMBER_DOUBLE +#ifdef _WIN32 + if (b == (UBits)1610612736L) + msg = "use D3DCREATE_FPU_PRESERVE with DirectX"; +#endif + if (b == (UBits)1127743488L) + msg = "not compiled with SWAPPED_DOUBLE"; +#endif + if (BAD_SAR) + msg = "arithmetic right-shift broken"; + luaL_error(L, "bit library self-test failed (%s)", msg); + } +#if LUA_VERSION_NUM < 502 + luaL_register(L, "bit", bit_funcs); +#else + luaL_newlib(L, bit_funcs); +#endif + return 1; +} diff --git a/lib/bitop/bit.h b/lib/bitop/bit.h new file mode 100644 index 0000000..3e5845e --- /dev/null +++ b/lib/bitop/bit.h @@ -0,0 +1,34 @@ +/* +** Lua BitOp -- a bit operations library for Lua 5.1/5.2. +** http://bitop.luajit.org/ +** +** Copyright (C) 2008-2012 Mike Pall. 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. +** +** [ MIT license: http://www.opensource.org/licenses/mit-license.php ] +*/ + +#pragma once + +#include "lua.h" + +#define LUA_BITLIBNAME "bit" +LUALIB_API int luaopen_bit(lua_State *L); diff --git a/lib/catch2/CMakeLists.txt b/lib/catch2/CMakeLists.txt new file mode 100644 index 0000000..3c471d4 --- /dev/null +++ b/lib/catch2/CMakeLists.txt @@ -0,0 +1,16 @@ +# catch2 is distributed as a standalone header. +# +# Downloaded from: +# +# https://github.com/catchorg/Catch2/releases/download/v2.13.9/catch.hpp +# +# The following changes were made to always print in microseconds, fixed format: +# +# - explicit Duration(double inNanoseconds, Unit units = Unit::Auto) +# + explicit Duration(double inNanoseconds, Unit units = Unit::Microseconds) +# +# - return os << duration.value() << ' ' << duration.unitsAsString(); +# + return os << std::fixed << duration.value() << ' ' << duration.unitsAsString(); + +add_library(catch2 INTERFACE) +target_include_directories(catch2 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/lib/catch2/catch.hpp b/lib/catch2/catch.hpp new file mode 100644 index 0000000..88f1106 --- /dev/null +++ b/lib/catch2/catch.hpp @@ -0,0 +1,17970 @@ +/* + * Catch v2.13.9 + * Generated: 2022-04-12 22:37:23.260201 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +// start catch.hpp + + +#define CATCH_VERSION_MAJOR 2 +#define CATCH_VERSION_MINOR 13 +#define CATCH_VERSION_PATCH 9 + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// start catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ + // Because REQUIREs trigger GCC's -Wparentheses, and because still + // supported version of g++ have only buggy support for _Pragmas, + // Wparentheses have to be suppressed globally. +# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details + +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wpadded" +#endif +// end catch_suppress_warnings.h +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +# define CATCH_CONFIG_ALL_PARTS +#endif + +// In the impl file, we want to have access to all parts of the headers +// Can also be used to sanely support PCHs +#if defined(CATCH_CONFIG_ALL_PARTS) +# define CATCH_CONFIG_EXTERNAL_INTERFACES +# if defined(CATCH_CONFIG_DISABLE_MATCHERS) +# undef CATCH_CONFIG_DISABLE_MATCHERS +# endif +# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +# endif +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) +// start catch_platform.h + +// See e.g.: +// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html +#ifdef __APPLE__ +# include <TargetConditionals.h> +# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ + (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) +# define CATCH_PLATFORM_MAC +# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) +# define CATCH_PLATFORM_IPHONE +# endif + +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX + +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) +# define CATCH_PLATFORM_WINDOWS +#endif + +// end catch_platform.h + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// start catch_user_interfaces.h + +namespace Catch { + unsigned int rngSeed(); +} + +// end catch_user_interfaces.h +// start catch_tag_alias_autoregistrar.h + +// start catch_common.h + +// start catch_compiler_capabilities.h + +// Detect a number of compiler features - by compiler +// The following features are defined: +// +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_<feature name> form +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +#ifdef __cplusplus + +# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +# define CATCH_CPP14_OR_GREATER +# endif + +# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# define CATCH_CPP17_OR_GREATER +# endif + +#endif + +// Only GCC compiler should be used in this block, so other compilers trying to +// mask themselves as GCC should be ignored. +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) + +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) + +#endif + +#if defined(__clang__) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) + +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +# if !defined(__ibmxl__) && !defined(__CUDACC__) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ +# endif + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) + +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Assume that non-Windows platforms support posix signals by default +#if !defined(CATCH_PLATFORM_WINDOWS) + #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#endif + +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#endif + +#ifdef __OS400__ +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# define CATCH_CONFIG_COLOUR_NONE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif + +//////////////////////////////////////////////////////////////////////////////// +// PS4 +#if defined(__ORBIS__) +# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE +// some versions of cygwin (most) do not support std::to_string. Use the libstd check. +// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 +# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ + && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) + +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING + +# endif +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#if defined(_MSC_VER) + +// Universal Windows platform does not support SEH +// Or console colours (or console at all...) +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define CATCH_CONFIG_COLOUR_NONE +# else +# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +# endif + +# if !defined(__clang__) // Handle Clang masquerading for msvc + +// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ +// _MSVC_TRADITIONAL == 0 means new conformant preprocessor +// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif // MSVC_TRADITIONAL + +// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) +# endif // __clang__ + +#endif // _MSC_VER + +#if defined(_REENTRANT) || defined(_MSC_VER) +// Enable async processing, as -pthread is specified or no additional linking is required +# define CATCH_INTERNAL_CONFIG_USE_ASYNC +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// +// Check if we are compiled with -fno-exceptions or equivalent +#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) +# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED +#endif + +//////////////////////////////////////////////////////////////////////////////// +// DJGPP +#ifdef __DJGPP__ +# define CATCH_INTERNAL_CONFIG_NO_WCHAR +#endif // __DJGPP__ + +//////////////////////////////////////////////////////////////////////////////// +// Embarcadero C++Build +#if defined(__BORLANDC__) + #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// Use of __COUNTER__ is suppressed during code analysis in +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly +// handled by it. +// Otherwise all supported compilers support COUNTER macro, +// but user still might want to turn it off +#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) + #define CATCH_INTERNAL_CONFIG_COUNTER +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// RTX is a special version of Windows that is real time. +// This means that it is detected as Windows, but does not provide +// the same set of capabilities as real Windows does. +#if defined(UNDER_RTSS) || defined(RTX64_BUILD) + #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH + #define CATCH_INTERNAL_CONFIG_NO_ASYNC + #define CATCH_CONFIG_COLOUR_NONE +#endif + +#if !defined(_GLIBCXX_USE_C99_MATH_TR1) +#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Various stdlib support checks that require __has_include +#if defined(__has_include) + // Check if string_view is available and usable + #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW + #endif + + // Check if optional is available and usable + # if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL + # endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER) + + // Check if byte is available and usable + # if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER) + # include <cstddef> + # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) + # define CATCH_INTERNAL_CONFIG_CPP17_BYTE + # endif + # endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER) + + // Check if variant is available and usable + # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER) + # if defined(__clang__) && (__clang_major__ < 8) + // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 + // fix should be in clang 8, workaround in libstdc++ 8.2 + # include <ciso646> + # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # define CATCH_CONFIG_NO_CPP17_VARIANT + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__clang__) && (__clang_major__ < 8) + # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER) +#endif // defined(__has_include) + +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +# define CATCH_CONFIG_WCHAR +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) +# define CATCH_CONFIG_CPP17_OPTIONAL +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) +# define CATCH_CONFIG_CPP17_STRING_VIEW +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) +# define CATCH_CONFIG_CPP17_VARIANT +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) +# define CATCH_CONFIG_CPP17_BYTE +#endif + +#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) +# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) +# define CATCH_CONFIG_NEW_CAPTURE +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +# define CATCH_CONFIG_DISABLE_EXCEPTIONS +#endif + +#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) +# define CATCH_CONFIG_POLYFILL_ISNAN +#endif + +#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) +# define CATCH_CONFIG_USE_ASYNC +#endif + +#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +# define CATCH_CONFIG_ANDROID_LOGWRITE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +# define CATCH_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Even if we do not think the compiler has that warning, we still have +// to provide a macro that can be used by the code. +#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS +#endif + +// The goal of this macro is to avoid evaluation of the arguments, but +// still have the compiler warn on problems inside... +#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) +#endif + +#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#elif defined(__clang__) && (__clang_major__ < 5) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +#define CATCH_TRY if ((true)) +#define CATCH_CATCH_ALL if ((false)) +#define CATCH_CATCH_ANON(type) if ((false)) +#else +#define CATCH_TRY try +#define CATCH_CATCH_ALL catch (...) +#define CATCH_CATCH_ANON(type) catch (type) +#endif + +#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) +#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#endif + +// end catch_compiler_capabilities.h +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#include <iosfwd> +#include <string> +#include <cstdint> + +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); + +namespace Catch { + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; + + protected: + NonCopyable(); + virtual ~NonCopyable(); + }; + + struct SourceLineInfo { + + SourceLineInfo() = delete; + SourceLineInfo( char const* _file, std::size_t _line ) noexcept + : file( _file ), + line( _line ) + {} + + SourceLineInfo( SourceLineInfo const& other ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo( SourceLineInfo&& ) noexcept = default; + SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; + + bool empty() const noexcept { return file[0] == '\0'; } + bool operator == ( SourceLineInfo const& other ) const noexcept; + bool operator < ( SourceLineInfo const& other ) const noexcept; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // Bring in operator<< from global namespace into Catch namespace + // This is necessary because the overload of operator<< above makes + // lookup stop at namespace Catch + using ::operator<<; + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() const; + }; + template<typename T> + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO \ + ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) ) + +// end catch_common.h +namespace Catch { + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + +// end catch_tag_alias_autoregistrar.h +// start catch_test_registry.h + +// start catch_interfaces_testcase.h + +#include <vector> + +namespace Catch { + + class TestSpec; + + struct ITestInvoker { + virtual void invoke () const = 0; + virtual ~ITestInvoker(); + }; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector<TestCase> const& getAllTests() const = 0; + virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool isThrowSafe( TestCase const& testCase, IConfig const& config ); + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ); + +} + +// end catch_interfaces_testcase.h +// start catch_stringref.h + +#include <cstddef> +#include <string> +#include <iosfwd> +#include <cassert> + +namespace Catch { + + /// A non-owning string class (similar to the forthcoming std::string_view) + /// Note that, because a StringRef may be a substring of another string, + /// it may not be null terminated. + class StringRef { + public: + using size_type = std::size_t; + using const_iterator = const char*; + + private: + static constexpr char const* const s_empty = ""; + + char const* m_start = s_empty; + size_type m_size = 0; + + public: // construction + constexpr StringRef() noexcept = default; + + StringRef( char const* rawChars ) noexcept; + + constexpr StringRef( char const* rawChars, size_type size ) noexcept + : m_start( rawChars ), + m_size( size ) + {} + + StringRef( std::string const& stdString ) noexcept + : m_start( stdString.c_str() ), + m_size( stdString.size() ) + {} + + explicit operator std::string() const { + return std::string(m_start, m_size); + } + + public: // operators + auto operator == ( StringRef const& other ) const noexcept -> bool; + auto operator != (StringRef const& other) const noexcept -> bool { + return !(*this == other); + } + + auto operator[] ( size_type index ) const noexcept -> char { + assert(index < m_size); + return m_start[index]; + } + + public: // named queries + constexpr auto empty() const noexcept -> bool { + return m_size == 0; + } + constexpr auto size() const noexcept -> size_type { + return m_size; + } + + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception + auto c_str() const -> char const*; + + public: // substrings and searches + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr( size_type start, size_type length ) const noexcept -> StringRef; + + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const*; + + constexpr auto isNullTerminated() const noexcept -> bool { + return m_start[m_size] == '\0'; + } + + public: // iterators + constexpr const_iterator begin() const { return m_start; } + constexpr const_iterator end() const { return m_start + m_size; } + }; + + auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; + auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; + + constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + return StringRef( rawChars, size ); + } +} // namespace Catch + +constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { + return Catch::StringRef( rawChars, size ); +} + +// end catch_stringref.h +// start catch_preprocessor.hpp + + +#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ +#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) + +#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ +// MSVC needs more evaluations +#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) +#else +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) +#endif + +#define CATCH_REC_END(...) +#define CATCH_REC_OUT + +#define CATCH_EMPTY() +#define CATCH_DEFER(id) id CATCH_EMPTY() + +#define CATCH_REC_GET_END2() 0, CATCH_REC_END +#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 +#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 +#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT +#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) +#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) + +#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) + +#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) + +// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, +// and passes userdata as the first parameter to each invocation, +// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) +#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) +#else +// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) +#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) +#endif + +#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ +#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) + +#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) +#else +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) +#endif + +#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ + CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) + +#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) +#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) +#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) +#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) +#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) +#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) +#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) +#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) +#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) + +#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N + +#define INTERNAL_CATCH_TYPE_GEN\ + template<typename...> struct TypeList {};\ + template<typename...Ts>\ + constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\ + template<template<typename...> class...> struct TemplateTypeList{};\ + template<template<typename...> class...Cs>\ + constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\ + template<typename...>\ + struct append;\ + template<typename...>\ + struct rewrap;\ + template<template<typename...> class, typename...>\ + struct create;\ + template<template<typename...> class, typename>\ + struct convert;\ + \ + template<typename T> \ + struct append<T> { using type = T; };\ + template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\ + struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\ + template< template<typename...> class L1, typename...E1, typename...Rest>\ + struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\ + \ + template< template<typename...> class Container, template<typename...> class List, typename...elems>\ + struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\ + template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\ + struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\ + \ + template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\ + struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\ + template<template <typename...> class Final, template <typename...> class List, typename...Ts>\ + struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; }; + +#define INTERNAL_CATCH_NTTP_1(signature, ...)\ + template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\ + template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\ + constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \ + template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\ + template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\ + constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \ + \ + template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\ + struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\ + template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\ + struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\ + template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\ + struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; }; + +#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName) +#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\ + template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\ + static void TestName() +#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\ + template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\ + static void TestName() + +#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName) +#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\ + template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\ + static void TestName() +#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\ + template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\ + static void TestName() + +#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\ + template<typename Type>\ + void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\ + {\ + Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\ + } + +#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\ + template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\ + void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\ + {\ + Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\ + } + +#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\ + template<typename Type>\ + void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\ + {\ + Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\ + } + +#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\ + template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\ + void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\ + {\ + Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\ + } + +#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName) +#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\ + template<typename TestType> \ + struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \ + void test();\ + } + +#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\ + template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \ + struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \ + void test();\ + } + +#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName) +#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\ + template<typename TestType> \ + void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test() +#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\ + template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \ + void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test() + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_NTTP_0 +#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0) +#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__) +#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__) +#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__) +#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__) +#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__) +#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__) +#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__) +#else +#define INTERNAL_CATCH_NTTP_0(signature) +#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__)) +#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)) +#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)) +#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)) +#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)) +#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)) +#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)) +#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)) +#endif + +// end catch_preprocessor.hpp +// start catch_meta.hpp + + +#include <type_traits> + +namespace Catch { + template<typename T> + struct always_false : std::false_type {}; + + template <typename> struct true_given : std::true_type {}; + struct is_callable_tester { + template <typename Fun, typename... Args> + true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int); + template <typename...> + std::false_type static test(...); + }; + + template <typename T> + struct is_callable; + + template <typename Fun, typename... Args> + struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {}; + +#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703 + // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is + // replaced with std::invoke_result here. + template <typename Func, typename... U> + using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>; +#else + // Keep ::type here because we still support C++11 + template <typename Func, typename... U> + using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type; +#endif + +} // namespace Catch + +namespace mpl_{ + struct na; +} + +// end catch_meta.hpp +namespace Catch { + +template<typename C> +class TestInvokerAsMethod : public ITestInvoker { + void (C::*m_testAsMethod)(); +public: + TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {} + + void invoke() const override { + C obj; + (obj.*m_testAsMethod)(); + } +}; + +auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*; + +template<typename C> +auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* { + return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod ); +} + +struct NameAndTags { + NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept; + StringRef name; + StringRef tags; +}; + +struct AutoReg : NonCopyable { + AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept; + ~AutoReg(); +}; + +} // end namespace Catch + +#if defined(CATCH_CONFIG_DISABLE) + #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \ + static void TestName() + #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \ + namespace{ \ + struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \ + void test(); \ + }; \ + } \ + void TestName::test() + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... ) \ + INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature)) + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \ + namespace{ \ + namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \ + INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\ + } \ + } \ + INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature)) + + #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ + INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) + #else + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) + #endif + + #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ + INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) + #else + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) + #endif + + #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) + #else + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) + #endif + + #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) + #else + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) + #endif +#endif + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ + static void TestName(); \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ + static void TestName() + #define INTERNAL_CATCH_TESTCASE( ... ) \ + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ \ + struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ + } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ + void TestName::test() + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\ + namespace {\ + namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\ + INTERNAL_CATCH_TYPE_GEN\ + INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\ + INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\ + template<typename...Types> \ + struct TestName{\ + TestName(){\ + int index = 0; \ + constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\ + using expander = int[];\ + (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \ + }\ + };\ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ + TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\ + return 0;\ + }();\ + }\ + }\ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ + INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature)) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ + INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) +#else + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) +#endif + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ + INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) +#else + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) +#endif + + #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + template<typename TestType> static void TestFuncName(); \ + namespace {\ + namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \ + INTERNAL_CATCH_TYPE_GEN \ + INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \ + template<typename... Types> \ + struct TestName { \ + void reg_tests() { \ + int index = 0; \ + using expander = int[]; \ + constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\ + constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\ + constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\ + (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */\ + } \ + }; \ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ + using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \ + TestInit t; \ + t.reg_tests(); \ + return 0; \ + }(); \ + } \ + } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ + template<typename TestType> \ + static void TestFuncName() + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__) +#else + #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) ) +#endif + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__) +#else + #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) +#endif + + #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + template<typename TestType> static void TestFunc(); \ + namespace {\ + namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\ + INTERNAL_CATCH_TYPE_GEN\ + template<typename... Types> \ + struct TestName { \ + void reg_tests() { \ + int index = 0; \ + using expander = int[]; \ + (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\ + } \ + };\ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ + using TestInit = typename convert<TestName, TmplList>::type; \ + TestInit t; \ + t.reg_tests(); \ + return 0; \ + }(); \ + }}\ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ + template<typename TestType> \ + static void TestFunc() + + #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \ + INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList ) + + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + namespace {\ + namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \ + INTERNAL_CATCH_TYPE_GEN\ + INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\ + INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\ + INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\ + template<typename...Types> \ + struct TestNameClass{\ + TestNameClass(){\ + int index = 0; \ + constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\ + using expander = int[];\ + (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \ + }\ + };\ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ + TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\ + return 0;\ + }();\ + }\ + }\ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ + INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature)) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) +#else + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) +#endif + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) +#else + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) +#endif + + #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + template<typename TestType> \ + struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \ + void test();\ + };\ + namespace {\ + namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\ + INTERNAL_CATCH_TYPE_GEN \ + INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\ + template<typename...Types>\ + struct TestNameClass{\ + void reg_tests(){\ + int index = 0;\ + using expander = int[];\ + constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\ + constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\ + constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\ + (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */ \ + }\ + };\ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ + using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\ + TestInit t;\ + t.reg_tests();\ + return 0;\ + }(); \ + }\ + }\ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ + template<typename TestType> \ + void TestName<TestType>::test() + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ ) +#else + #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) ) +#endif + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ ) +#else + #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) ) +#endif + + #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + template<typename TestType> \ + struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \ + void test();\ + };\ + namespace {\ + namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \ + INTERNAL_CATCH_TYPE_GEN\ + template<typename...Types>\ + struct TestNameClass{\ + void reg_tests(){\ + int index = 0;\ + using expander = int[];\ + (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \ + }\ + };\ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ + using TestInit = typename convert<TestNameClass, TmplList>::type;\ + TestInit t;\ + t.reg_tests();\ + return 0;\ + }(); \ + }}\ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ + template<typename TestType> \ + void TestName<TestType>::test() + +#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \ + INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList ) + +// end catch_test_registry.h +// start catch_capture.hpp + +// start catch_assertionhandler.h + +// start catch_assertioninfo.h + +// start catch_result_type.h + +namespace Catch { + + // ResultWas::OfType enum + struct ResultWas { enum OfType { + Unknown = -1, + Ok = 0, + Info = 1, + Warning = 2, + + FailureBit = 0x10, + + ExpressionFailed = FailureBit | 1, + ExplicitFailure = FailureBit | 2, + + Exception = 0x100 | FailureBit, + + ThrewException = Exception | 1, + DidntThrowException = Exception | 2, + + FatalErrorCondition = 0x200 | FailureBit + + }; }; + + bool isOk( ResultWas::OfType resultType ); + bool isJustInfo( int flags ); + + // ResultDisposition::Flags enum + struct ResultDisposition { enum Flags { + Normal = 0x01, + + ContinueOnFailure = 0x02, // Failures fail test, but execution continues + FalseTest = 0x04, // Prefix expression with ! + SuppressFail = 0x08 // Failures are reported but do not fail the test + }; }; + + ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ); + + bool shouldContinueOnFailure( int flags ); + inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } + bool shouldSuppressFailure( int flags ); + +} // end namespace Catch + +// end catch_result_type.h +namespace Catch { + + struct AssertionInfo + { + StringRef macroName; + SourceLineInfo lineInfo; + StringRef capturedExpression; + ResultDisposition::Flags resultDisposition; + + // We want to delete this constructor but a compiler bug in 4.8 means + // the struct is then treated as non-aggregate + //AssertionInfo() = delete; + }; + +} // end namespace Catch + +// end catch_assertioninfo.h +// start catch_decomposer.h + +// start catch_tostring.h + +#include <vector> +#include <cstddef> +#include <type_traits> +#include <string> +// start catch_stream.h + +#include <iosfwd> +#include <cstddef> +#include <ostream> + +namespace Catch { + + std::ostream& cout(); + std::ostream& cerr(); + std::ostream& clog(); + + class StringRef; + + struct IStream { + virtual ~IStream(); + virtual std::ostream& stream() const = 0; + }; + + auto makeStream( StringRef const &filename ) -> IStream const*; + + class ReusableStringStream : NonCopyable { + std::size_t m_index; + std::ostream* m_oss; + public: + ReusableStringStream(); + ~ReusableStringStream(); + + auto str() const -> std::string; + + template<typename T> + auto operator << ( T const& value ) -> ReusableStringStream& { + *m_oss << value; + return *this; + } + auto get() -> std::ostream& { return *m_oss; } + }; +} + +// end catch_stream.h +// start catch_interfaces_enum_values_registry.h + +#include <vector> + +namespace Catch { + + namespace Detail { + struct EnumInfo { + StringRef m_name; + std::vector<std::pair<int, StringRef>> m_values; + + ~EnumInfo(); + + StringRef lookup( int value ) const; + }; + } // namespace Detail + + struct IMutableEnumValuesRegistry { + virtual ~IMutableEnumValuesRegistry(); + + virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0; + + template<typename E> + Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) { + static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int"); + std::vector<int> intValues; + intValues.reserve( values.size() ); + for( auto enumValue : values ) + intValues.push_back( static_cast<int>( enumValue ) ); + return registerEnum( enumName, allEnums, intValues ); + } + }; + +} // Catch + +// end catch_interfaces_enum_values_registry.h + +#ifdef CATCH_CONFIG_CPP17_STRING_VIEW +#include <string_view> +#endif + +#ifdef __OBJC__ +// start catch_objc_arc.hpp + +#import <Foundation/Foundation.h> + +#ifdef __has_feature +#define CATCH_ARC_ENABLED __has_feature(objc_arc) +#else +#define CATCH_ARC_ENABLED 0 +#endif + +void arcSafeRelease( NSObject* obj ); +id performOptionalSelector( id obj, SEL sel ); + +#if !CATCH_ARC_ENABLED +inline void arcSafeRelease( NSObject* obj ) { + [obj release]; +} +inline id performOptionalSelector( id obj, SEL sel ) { + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; + return nil; +} +#define CATCH_UNSAFE_UNRETAINED +#define CATCH_ARC_STRONG +#else +inline void arcSafeRelease( NSObject* ){} +inline id performOptionalSelector( id obj, SEL sel ) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +#endif + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + return nil; +} +#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained +#define CATCH_ARC_STRONG __strong +#endif + +// end catch_objc_arc.hpp +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless +#endif + +namespace Catch { + namespace Detail { + + extern const std::string unprintableString; + + std::string rawMemoryToString( const void *object, std::size_t size ); + + template<typename T> + std::string rawMemoryToString( const T& object ) { + return rawMemoryToString( &object, sizeof(object) ); + } + + template<typename T> + class IsStreamInsertable { + template<typename Stream, typename U> + static auto test(int) + -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type()); + + template<typename, typename> + static auto test(...)->std::false_type; + + public: + static const bool value = decltype(test<std::ostream, const T&>(0))::value; + }; + + template<typename E> + std::string convertUnknownEnumToString( E e ); + + template<typename T> + typename std::enable_if< + !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value, + std::string>::type convertUnstreamable( T const& ) { + return Detail::unprintableString; + } + template<typename T> + typename std::enable_if< + !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value, + std::string>::type convertUnstreamable(T const& ex) { + return ex.what(); + } + + template<typename T> + typename std::enable_if< + std::is_enum<T>::value + , std::string>::type convertUnstreamable( T const& value ) { + return convertUnknownEnumToString( value ); + } + +#if defined(_MANAGED) + //! Convert a CLR string to a utf8 std::string + template<typename T> + std::string clrReferenceToString( T^ ref ) { + if (ref == nullptr) + return std::string("null"); + auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString()); + cli::pin_ptr<System::Byte> p = &bytes[0]; + return std::string(reinterpret_cast<char const *>(p), bytes->Length); + } +#endif + + } // namespace Detail + + // If we decide for C++14, change these to enable_if_ts + template <typename T, typename = void> + struct StringMaker { + template <typename Fake = T> + static + typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type + convert(const Fake& value) { + ReusableStringStream rss; + // NB: call using the function-like syntax to avoid ambiguity with + // user-defined templated operator<< under clang. + rss.operator<<(value); + return rss.str(); + } + + template <typename Fake = T> + static + typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type + convert( const Fake& value ) { +#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER) + return Detail::convertUnstreamable(value); +#else + return CATCH_CONFIG_FALLBACK_STRINGIFIER(value); +#endif + } + }; + + namespace Detail { + + // This function dispatches all stringification requests inside of Catch. + // Should be preferably called fully qualified, like ::Catch::Detail::stringify + template <typename T> + std::string stringify(const T& e) { + return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e); + } + + template<typename E> + std::string convertUnknownEnumToString( E e ) { + return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e)); + } + +#if defined(_MANAGED) + template <typename T> + std::string stringify( T^ e ) { + return ::Catch::StringMaker<T^>::convert(e); + } +#endif + + } // namespace Detail + + // Some predefined specializations + + template<> + struct StringMaker<std::string> { + static std::string convert(const std::string& str); + }; + +#ifdef CATCH_CONFIG_CPP17_STRING_VIEW + template<> + struct StringMaker<std::string_view> { + static std::string convert(std::string_view str); + }; +#endif + + template<> + struct StringMaker<char const *> { + static std::string convert(char const * str); + }; + template<> + struct StringMaker<char *> { + static std::string convert(char * str); + }; + +#ifdef CATCH_CONFIG_WCHAR + template<> + struct StringMaker<std::wstring> { + static std::string convert(const std::wstring& wstr); + }; + +# ifdef CATCH_CONFIG_CPP17_STRING_VIEW + template<> + struct StringMaker<std::wstring_view> { + static std::string convert(std::wstring_view str); + }; +# endif + + template<> + struct StringMaker<wchar_t const *> { + static std::string convert(wchar_t const * str); + }; + template<> + struct StringMaker<wchar_t *> { + static std::string convert(wchar_t * str); + }; +#endif + + // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer, + // while keeping string semantics? + template<int SZ> + struct StringMaker<char[SZ]> { + static std::string convert(char const* str) { + return ::Catch::Detail::stringify(std::string{ str }); + } + }; + template<int SZ> + struct StringMaker<signed char[SZ]> { + static std::string convert(signed char const* str) { + return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) }); + } + }; + template<int SZ> + struct StringMaker<unsigned char[SZ]> { + static std::string convert(unsigned char const* str) { + return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) }); + } + }; + +#if defined(CATCH_CONFIG_CPP17_BYTE) + template<> + struct StringMaker<std::byte> { + static std::string convert(std::byte value); + }; +#endif // defined(CATCH_CONFIG_CPP17_BYTE) + template<> + struct StringMaker<int> { + static std::string convert(int value); + }; + template<> + struct StringMaker<long> { + static std::string convert(long value); + }; + template<> + struct StringMaker<long long> { + static std::string convert(long long value); + }; + template<> + struct StringMaker<unsigned int> { + static std::string convert(unsigned int value); + }; + template<> + struct StringMaker<unsigned long> { + static std::string convert(unsigned long value); + }; + template<> + struct StringMaker<unsigned long long> { + static std::string convert(unsigned long long value); + }; + + template<> + struct StringMaker<bool> { + static std::string convert(bool b); + }; + + template<> + struct StringMaker<char> { + static std::string convert(char c); + }; + template<> + struct StringMaker<signed char> { + static std::string convert(signed char c); + }; + template<> + struct StringMaker<unsigned char> { + static std::string convert(unsigned char c); + }; + + template<> + struct StringMaker<std::nullptr_t> { + static std::string convert(std::nullptr_t); + }; + + template<> + struct StringMaker<float> { + static std::string convert(float value); + static int precision; + }; + + template<> + struct StringMaker<double> { + static std::string convert(double value); + static int precision; + }; + + template <typename T> + struct StringMaker<T*> { + template <typename U> + static std::string convert(U* p) { + if (p) { + return ::Catch::Detail::rawMemoryToString(p); + } else { + return "nullptr"; + } + } + }; + + template <typename R, typename C> + struct StringMaker<R C::*> { + static std::string convert(R C::* p) { + if (p) { + return ::Catch::Detail::rawMemoryToString(p); + } else { + return "nullptr"; + } + } + }; + +#if defined(_MANAGED) + template <typename T> + struct StringMaker<T^> { + static std::string convert( T^ ref ) { + return ::Catch::Detail::clrReferenceToString(ref); + } + }; +#endif + + namespace Detail { + template<typename InputIterator, typename Sentinel = InputIterator> + std::string rangeToString(InputIterator first, Sentinel last) { + ReusableStringStream rss; + rss << "{ "; + if (first != last) { + rss << ::Catch::Detail::stringify(*first); + for (++first; first != last; ++first) + rss << ", " << ::Catch::Detail::stringify(*first); + } + rss << " }"; + return rss.str(); + } + } + +#ifdef __OBJC__ + template<> + struct StringMaker<NSString*> { + static std::string convert(NSString * nsstring) { + if (!nsstring) + return "nil"; + return std::string("@") + [nsstring UTF8String]; + } + }; + template<> + struct StringMaker<NSObject*> { + static std::string convert(NSObject* nsObject) { + return ::Catch::Detail::stringify([nsObject description]); + } + + }; + namespace Detail { + inline std::string stringify( NSString* nsstring ) { + return StringMaker<NSString*>::convert( nsstring ); + } + + } // namespace Detail +#endif // __OBJC__ + +} // namespace Catch + +////////////////////////////////////////////////////// +// Separate std-lib types stringification, so it can be selectively enabled +// This means that we do not bring in + +#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS) +# define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER +# define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER +# define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +# define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER +#endif + +// Separate std::pair specialization +#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER) +#include <utility> +namespace Catch { + template<typename T1, typename T2> + struct StringMaker<std::pair<T1, T2> > { + static std::string convert(const std::pair<T1, T2>& pair) { + ReusableStringStream rss; + rss << "{ " + << ::Catch::Detail::stringify(pair.first) + << ", " + << ::Catch::Detail::stringify(pair.second) + << " }"; + return rss.str(); + } + }; +} +#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER + +#if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL) +#include <optional> +namespace Catch { + template<typename T> + struct StringMaker<std::optional<T> > { + static std::string convert(const std::optional<T>& optional) { + ReusableStringStream rss; + if (optional.has_value()) { + rss << ::Catch::Detail::stringify(*optional); + } else { + rss << "{ }"; + } + return rss.str(); + } + }; +} +#endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER + +// Separate std::tuple specialization +#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER) +#include <tuple> +namespace Catch { + namespace Detail { + template< + typename Tuple, + std::size_t N = 0, + bool = (N < std::tuple_size<Tuple>::value) + > + struct TupleElementPrinter { + static void print(const Tuple& tuple, std::ostream& os) { + os << (N ? ", " : " ") + << ::Catch::Detail::stringify(std::get<N>(tuple)); + TupleElementPrinter<Tuple, N + 1>::print(tuple, os); + } + }; + + template< + typename Tuple, + std::size_t N + > + struct TupleElementPrinter<Tuple, N, false> { + static void print(const Tuple&, std::ostream&) {} + }; + + } + + template<typename ...Types> + struct StringMaker<std::tuple<Types...>> { + static std::string convert(const std::tuple<Types...>& tuple) { + ReusableStringStream rss; + rss << '{'; + Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get()); + rss << " }"; + return rss.str(); + } + }; +} +#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER + +#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT) +#include <variant> +namespace Catch { + template<> + struct StringMaker<std::monostate> { + static std::string convert(const std::monostate&) { + return "{ }"; + } + }; + + template<typename... Elements> + struct StringMaker<std::variant<Elements...>> { + static std::string convert(const std::variant<Elements...>& variant) { + if (variant.valueless_by_exception()) { + return "{valueless variant}"; + } else { + return std::visit( + [](const auto& value) { + return ::Catch::Detail::stringify(value); + }, + variant + ); + } + } + }; +} +#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER + +namespace Catch { + // Import begin/ end from std here + using std::begin; + using std::end; + + namespace detail { + template <typename...> + struct void_type { + using type = void; + }; + + template <typename T, typename = void> + struct is_range_impl : std::false_type { + }; + + template <typename T> + struct is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type> : std::true_type { + }; + } // namespace detail + + template <typename T> + struct is_range : detail::is_range_impl<T> { + }; + +#if defined(_MANAGED) // Managed types are never ranges + template <typename T> + struct is_range<T^> { + static const bool value = false; + }; +#endif + + template<typename Range> + std::string rangeToString( Range const& range ) { + return ::Catch::Detail::rangeToString( begin( range ), end( range ) ); + } + + // Handle vector<bool> specially + template<typename Allocator> + std::string rangeToString( std::vector<bool, Allocator> const& v ) { + ReusableStringStream rss; + rss << "{ "; + bool first = true; + for( bool b : v ) { + if( first ) + first = false; + else + rss << ", "; + rss << ::Catch::Detail::stringify( b ); + } + rss << " }"; + return rss.str(); + } + + template<typename R> + struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> { + static std::string convert( R const& range ) { + return rangeToString( range ); + } + }; + + template <typename T, int SZ> + struct StringMaker<T[SZ]> { + static std::string convert(T const(&arr)[SZ]) { + return rangeToString(arr); + } + }; + +} // namespace Catch + +// Separate std::chrono::duration specialization +#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +#include <ctime> +#include <ratio> +#include <chrono> + +namespace Catch { + +template <class Ratio> +struct ratio_string { + static std::string symbol(); +}; + +template <class Ratio> +std::string ratio_string<Ratio>::symbol() { + Catch::ReusableStringStream rss; + rss << '[' << Ratio::num << '/' + << Ratio::den << ']'; + return rss.str(); +} +template <> +struct ratio_string<std::atto> { + static std::string symbol(); +}; +template <> +struct ratio_string<std::femto> { + static std::string symbol(); +}; +template <> +struct ratio_string<std::pico> { + static std::string symbol(); +}; +template <> +struct ratio_string<std::nano> { + static std::string symbol(); +}; +template <> +struct ratio_string<std::micro> { + static std::string symbol(); +}; +template <> +struct ratio_string<std::milli> { + static std::string symbol(); +}; + + //////////// + // std::chrono::duration specializations + template<typename Value, typename Ratio> + struct StringMaker<std::chrono::duration<Value, Ratio>> { + static std::string convert(std::chrono::duration<Value, Ratio> const& duration) { + ReusableStringStream rss; + rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's'; + return rss.str(); + } + }; + template<typename Value> + struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> { + static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) { + ReusableStringStream rss; + rss << duration.count() << " s"; + return rss.str(); + } + }; + template<typename Value> + struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> { + static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) { + ReusableStringStream rss; + rss << duration.count() << " m"; + return rss.str(); + } + }; + template<typename Value> + struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> { + static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) { + ReusableStringStream rss; + rss << duration.count() << " h"; + return rss.str(); + } + }; + + //////////// + // std::chrono::time_point specialization + // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock> + template<typename Clock, typename Duration> + struct StringMaker<std::chrono::time_point<Clock, Duration>> { + static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) { + return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch"; + } + }; + // std::chrono::time_point<system_clock> specialization + template<typename Duration> + struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> { + static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) { + auto converted = std::chrono::system_clock::to_time_t(time_point); + +#ifdef _MSC_VER + std::tm timeInfo = {}; + gmtime_s(&timeInfo, &converted); +#else + std::tm* timeInfo = std::gmtime(&converted); +#endif + + auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); + char timeStamp[timeStampSize]; + const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; + +#ifdef _MSC_VER + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); +#else + std::strftime(timeStamp, timeStampSize, fmt, timeInfo); +#endif + return std::string(timeStamp); + } + }; +} +#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER + +#define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \ +namespace Catch { \ + template<> struct StringMaker<enumName> { \ + static std::string convert( enumName value ) { \ + static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \ + return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \ + } \ + }; \ +} + +#define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ ) + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// end catch_tostring.h +#include <iosfwd> + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4389) // '==' : signed/unsigned mismatch +#pragma warning(disable:4018) // more "signed/unsigned mismatch" +#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) +#pragma warning(disable:4180) // qualifier applied to function type has no meaning +#pragma warning(disable:4800) // Forcing result to true or false +#endif + +namespace Catch { + + struct ITransientExpression { + auto isBinaryExpression() const -> bool { return m_isBinaryExpression; } + auto getResult() const -> bool { return m_result; } + virtual void streamReconstructedExpression( std::ostream &os ) const = 0; + + ITransientExpression( bool isBinaryExpression, bool result ) + : m_isBinaryExpression( isBinaryExpression ), + m_result( result ) + {} + + // We don't actually need a virtual destructor, but many static analysers + // complain if it's not here :-( + virtual ~ITransientExpression(); + + bool m_isBinaryExpression; + bool m_result; + + }; + + void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ); + + template<typename LhsT, typename RhsT> + class BinaryExpr : public ITransientExpression { + LhsT m_lhs; + StringRef m_op; + RhsT m_rhs; + + void streamReconstructedExpression( std::ostream &os ) const override { + formatReconstructedExpression + ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) ); + } + + public: + BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs ) + : ITransientExpression{ true, comparisonResult }, + m_lhs( lhs ), + m_op( op ), + m_rhs( rhs ) + {} + + template<typename T> + auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const { + static_assert(always_false<T>::value, + "chained comparisons are not supported inside assertions, " + "wrap the expression inside parentheses, or decompose it"); + } + + template<typename T> + auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const { + static_assert(always_false<T>::value, + "chained comparisons are not supported inside assertions, " + "wrap the expression inside parentheses, or decompose it"); + } + + template<typename T> + auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const { + static_assert(always_false<T>::value, + "chained comparisons are not supported inside assertions, " + "wrap the expression inside parentheses, or decompose it"); + } + + template<typename T> + auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const { + static_assert(always_false<T>::value, + "chained comparisons are not supported inside assertions, " + "wrap the expression inside parentheses, or decompose it"); + } + + template<typename T> + auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const { + static_assert(always_false<T>::value, + "chained comparisons are not supported inside assertions, " + "wrap the expression inside parentheses, or decompose it"); + } + + template<typename T> + auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const { + static_assert(always_false<T>::value, + "chained comparisons are not supported inside assertions, " + "wrap the expression inside parentheses, or decompose it"); + } + + template<typename T> + auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const { + static_assert(always_false<T>::value, + "chained comparisons are not supported inside assertions, " + "wrap the expression inside parentheses, or decompose it"); + } + + template<typename T> + auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const { + static_assert(always_false<T>::value, + "chained comparisons are not supported inside assertions, " + "wrap the expression inside parentheses, or decompose it"); + } + }; + + template<typename LhsT> + class UnaryExpr : public ITransientExpression { + LhsT m_lhs; + + void streamReconstructedExpression( std::ostream &os ) const override { + os << Catch::Detail::stringify( m_lhs ); + } + + public: + explicit UnaryExpr( LhsT lhs ) + : ITransientExpression{ false, static_cast<bool>(lhs) }, + m_lhs( lhs ) + {} + }; + + // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int) + template<typename LhsT, typename RhsT> + auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); } + template<typename T> + auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); } + template<typename T> + auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); } + template<typename T> + auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; } + template<typename T> + auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; } + + template<typename LhsT, typename RhsT> + auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); } + template<typename T> + auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); } + template<typename T> + auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); } + template<typename T> + auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; } + template<typename T> + auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; } + + template<typename LhsT> + class ExprLhs { + LhsT m_lhs; + public: + explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {} + + template<typename RhsT> + auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs }; + } + auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const { + return { m_lhs == rhs, m_lhs, "==", rhs }; + } + + template<typename RhsT> + auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs }; + } + auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const { + return { m_lhs != rhs, m_lhs, "!=", rhs }; + } + + template<typename RhsT> + auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs }; + } + template<typename RhsT> + auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs }; + } + template<typename RhsT> + auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs }; + } + template<typename RhsT> + auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs }; + } + template <typename RhsT> + auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs | rhs), m_lhs, "|", rhs }; + } + template <typename RhsT> + auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs & rhs), m_lhs, "&", rhs }; + } + template <typename RhsT> + auto operator ^ (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const { + return { static_cast<bool>(m_lhs ^ rhs), m_lhs, "^", rhs }; + } + + template<typename RhsT> + auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const { + static_assert(always_false<RhsT>::value, + "operator&& is not supported inside assertions, " + "wrap the expression inside parentheses, or decompose it"); + } + + template<typename RhsT> + auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const { + static_assert(always_false<RhsT>::value, + "operator|| is not supported inside assertions, " + "wrap the expression inside parentheses, or decompose it"); + } + + auto makeUnaryExpr() const -> UnaryExpr<LhsT> { + return UnaryExpr<LhsT>{ m_lhs }; + } + }; + + void handleExpression( ITransientExpression const& expr ); + + template<typename T> + void handleExpression( ExprLhs<T> const& expr ) { + handleExpression( expr.makeUnaryExpr() ); + } + + struct Decomposer { + template<typename T> + auto operator <= ( T const& lhs ) -> ExprLhs<T const&> { + return ExprLhs<T const&>{ lhs }; + } + + auto operator <=( bool value ) -> ExprLhs<bool> { + return ExprLhs<bool>{ value }; + } + }; + +} // end namespace Catch + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// end catch_decomposer.h +// start catch_interfaces_capture.h + +#include <string> +#include <chrono> + +namespace Catch { + + class AssertionResult; + struct AssertionInfo; + struct SectionInfo; + struct SectionEndInfo; + struct MessageInfo; + struct MessageBuilder; + struct Counts; + struct AssertionReaction; + struct SourceLineInfo; + + struct ITransientExpression; + struct IGeneratorTracker; + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + struct BenchmarkInfo; + template <typename Duration = std::chrono::duration<double, std::nano>> + struct BenchmarkStats; +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + + struct IResultCapture { + + virtual ~IResultCapture(); + + virtual bool sectionStarted( SectionInfo const& sectionInfo, + Counts& assertions ) = 0; + virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; + + virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0; + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + virtual void benchmarkPreparing( std::string const& name ) = 0; + virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0; + virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0; + virtual void benchmarkFailed( std::string const& error ) = 0; +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + + virtual void pushScopedMessage( MessageInfo const& message ) = 0; + virtual void popScopedMessage( MessageInfo const& message ) = 0; + + virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0; + + virtual void handleFatalErrorCondition( StringRef message ) = 0; + + virtual void handleExpr + ( AssertionInfo const& info, + ITransientExpression const& expr, + AssertionReaction& reaction ) = 0; + virtual void handleMessage + ( AssertionInfo const& info, + ResultWas::OfType resultType, + StringRef const& message, + AssertionReaction& reaction ) = 0; + virtual void handleUnexpectedExceptionNotThrown + ( AssertionInfo const& info, + AssertionReaction& reaction ) = 0; + virtual void handleUnexpectedInflightException + ( AssertionInfo const& info, + std::string const& message, + AssertionReaction& reaction ) = 0; + virtual void handleIncomplete + ( AssertionInfo const& info ) = 0; + virtual void handleNonExpr + ( AssertionInfo const &info, + ResultWas::OfType resultType, + AssertionReaction &reaction ) = 0; + + virtual bool lastAssertionPassed() = 0; + virtual void assertionPassed() = 0; + + // Deprecated, do not use: + virtual std::string getCurrentTestName() const = 0; + virtual const AssertionResult* getLastResult() const = 0; + virtual void exceptionEarlyReported() = 0; + }; + + IResultCapture& getResultCapture(); +} + +// end catch_interfaces_capture.h +namespace Catch { + + struct TestFailureException{}; + struct AssertionResultData; + struct IResultCapture; + class RunContext; + + class LazyExpression { + friend class AssertionHandler; + friend struct AssertionStats; + friend class RunContext; + + ITransientExpression const* m_transientExpression = nullptr; + bool m_isNegated; + public: + LazyExpression( bool isNegated ); + LazyExpression( LazyExpression const& other ); + LazyExpression& operator = ( LazyExpression const& ) = delete; + + explicit operator bool() const; + + friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&; + }; + + struct AssertionReaction { + bool shouldDebugBreak = false; + bool shouldThrow = false; + }; + + class AssertionHandler { + AssertionInfo m_assertionInfo; + AssertionReaction m_reaction; + bool m_completed = false; + IResultCapture& m_resultCapture; + + public: + AssertionHandler + ( StringRef const& macroName, + SourceLineInfo const& lineInfo, + StringRef capturedExpression, + ResultDisposition::Flags resultDisposition ); + ~AssertionHandler() { + if ( !m_completed ) { + m_resultCapture.handleIncomplete( m_assertionInfo ); + } + } + + template<typename T> + void handleExpr( ExprLhs<T> const& expr ) { + handleExpr( expr.makeUnaryExpr() ); + } + void handleExpr( ITransientExpression const& expr ); + + void handleMessage(ResultWas::OfType resultType, StringRef const& message); + + void handleExceptionThrownAsExpected(); + void handleUnexpectedExceptionNotThrown(); + void handleExceptionNotThrownAsExpected(); + void handleThrowingCallSkipped(); + void handleUnexpectedInflightException(); + + void complete(); + void setCompleted(); + + // query + auto allowThrows() const -> bool; + }; + + void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ); + +} // namespace Catch + +// end catch_assertionhandler.h +// start catch_message.h + +#include <string> +#include <vector> + +namespace Catch { + + struct MessageInfo { + MessageInfo( StringRef const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + + StringRef macroName; + std::string message; + SourceLineInfo lineInfo; + ResultWas::OfType type; + unsigned int sequence; + + bool operator == ( MessageInfo const& other ) const; + bool operator < ( MessageInfo const& other ) const; + private: + static unsigned int globalCount; + }; + + struct MessageStream { + + template<typename T> + MessageStream& operator << ( T const& value ) { + m_stream << value; + return *this; + } + + ReusableStringStream m_stream; + }; + + struct MessageBuilder : MessageStream { + MessageBuilder( StringRef const& macroName, + SourceLineInfo const& lineInfo, + ResultWas::OfType type ); + + template<typename T> + MessageBuilder& operator << ( T const& value ) { + m_stream << value; + return *this; + } + + MessageInfo m_info; + }; + + class ScopedMessage { + public: + explicit ScopedMessage( MessageBuilder const& builder ); + ScopedMessage( ScopedMessage& duplicate ) = delete; + ScopedMessage( ScopedMessage&& old ); + ~ScopedMessage(); + + MessageInfo m_info; + bool m_moved; + }; + + class Capturer { + std::vector<MessageInfo> m_messages; + IResultCapture& m_resultCapture = getResultCapture(); + size_t m_captured = 0; + public: + Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ); + ~Capturer(); + + void captureValue( size_t index, std::string const& value ); + + template<typename T> + void captureValues( size_t index, T const& value ) { + captureValue( index, Catch::Detail::stringify( value ) ); + } + + template<typename T, typename... Ts> + void captureValues( size_t index, T const& value, Ts const&... values ) { + captureValue( index, Catch::Detail::stringify(value) ); + captureValues( index+1, values... ); + } + }; + +} // end namespace Catch + +// end catch_message.h +#if !defined(CATCH_CONFIG_DISABLE) + +#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) + #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__ +#else + #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" +#endif + +#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + +/////////////////////////////////////////////////////////////////////////////// +// Another way to speed-up compilation is to omit local try-catch for REQUIRE* +// macros. +#define INTERNAL_CATCH_TRY +#define INTERNAL_CATCH_CATCH( capturer ) + +#else // CATCH_CONFIG_FAST_COMPILE + +#define INTERNAL_CATCH_TRY try +#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); } + +#endif + +#define INTERNAL_CATCH_REACT( handler ) handler.complete(); + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ + do { \ + CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \ + Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ + INTERNAL_CATCH_TRY { \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ + } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \ + INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ + if( Catch::getResultCapture().lastAssertionPassed() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \ + INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ + if( !Catch::getResultCapture().lastAssertionPassed() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ + try { \ + static_cast<void>(__VA_ARGS__); \ + catchAssertionHandler.handleExceptionNotThrownAsExpected(); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast<void>(__VA_ARGS__); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleExceptionThrownAsExpected(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast<void>(expr); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( exceptionType const& ) { \ + catchAssertionHandler.handleExceptionThrownAsExpected(); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \ + catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \ + auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \ + varName.captureValues( 0, __VA_ARGS__ ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_INFO( macroName, log ) \ + Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ); + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \ + Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ) + +/////////////////////////////////////////////////////////////////////////////// +// Although this is matcher-based, it can be used with just a string +#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast<void>(__VA_ARGS__); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( ... ) { \ + Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +#endif // CATCH_CONFIG_DISABLE + +// end catch_capture.hpp +// start catch_section.h + +// start catch_section_info.h + +// start catch_totals.h + +#include <cstddef> + +namespace Catch { + + struct Counts { + Counts operator - ( Counts const& other ) const; + Counts& operator += ( Counts const& other ); + + std::size_t total() const; + bool allPassed() const; + bool allOk() const; + + std::size_t passed = 0; + std::size_t failed = 0; + std::size_t failedButOk = 0; + }; + + struct Totals { + + Totals operator - ( Totals const& other ) const; + Totals& operator += ( Totals const& other ); + + Totals delta( Totals const& prevTotals ) const; + + int error = 0; + Counts assertions; + Counts testCases; + }; +} + +// end catch_totals.h +#include <string> + +namespace Catch { + + struct SectionInfo { + SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name ); + + // Deprecated + SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& ) : SectionInfo( _lineInfo, _name ) {} + + std::string name; + std::string description; // !Deprecated: this will always be empty + SourceLineInfo lineInfo; + }; + + struct SectionEndInfo { + SectionInfo sectionInfo; + Counts prevAssertions; + double durationInSeconds; + }; + +} // end namespace Catch + +// end catch_section_info.h +// start catch_timer.h + +#include <cstdint> + +namespace Catch { + + auto getCurrentNanosecondsSinceEpoch() -> uint64_t; + auto getEstimatedClockResolution() -> uint64_t; + + class Timer { + uint64_t m_nanoseconds = 0; + public: + void start(); + auto getElapsedNanoseconds() const -> uint64_t; + auto getElapsedMicroseconds() const -> uint64_t; + auto getElapsedMilliseconds() const -> unsigned int; + auto getElapsedSeconds() const -> double; + }; + +} // namespace Catch + +// end catch_timer.h +#include <string> + +namespace Catch { + + class Section : NonCopyable { + public: + Section( SectionInfo const& info ); + ~Section(); + + // This indicates whether the section should be executed or not + explicit operator bool() const; + + private: + SectionInfo m_info; + + std::string m_name; + Counts m_assertions; + bool m_sectionIncluded; + Timer m_timer; + }; + +} // end namespace Catch + +#define INTERNAL_CATCH_SECTION( ... ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + +#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + +// end catch_section.h +// start catch_interfaces_exception.h + +// start catch_interfaces_registry_hub.h + +#include <string> +#include <memory> + +namespace Catch { + + class TestCase; + struct ITestCaseRegistry; + struct IExceptionTranslatorRegistry; + struct IExceptionTranslator; + struct IReporterRegistry; + struct IReporterFactory; + struct ITagAliasRegistry; + struct IMutableEnumValuesRegistry; + + class StartupExceptionRegistry; + + using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>; + + struct IRegistryHub { + virtual ~IRegistryHub(); + + virtual IReporterRegistry const& getReporterRegistry() const = 0; + virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; + virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; + virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0; + + virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0; + }; + + struct IMutableRegistryHub { + virtual ~IMutableRegistryHub(); + virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0; + virtual void registerListener( IReporterFactoryPtr const& factory ) = 0; + virtual void registerTest( TestCase const& testInfo ) = 0; + virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; + virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; + virtual void registerStartupException() noexcept = 0; + virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0; + }; + + IRegistryHub const& getRegistryHub(); + IMutableRegistryHub& getMutableRegistryHub(); + void cleanUp(); + std::string translateActiveException(); + +} + +// end catch_interfaces_registry_hub.h +#if defined(CATCH_CONFIG_DISABLE) + #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \ + static std::string translatorName( signature ) +#endif + +#include <exception> +#include <string> +#include <vector> + +namespace Catch { + using exceptionTranslateFunction = std::string(*)(); + + struct IExceptionTranslator; + using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>; + + struct IExceptionTranslator { + virtual ~IExceptionTranslator(); + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; + }; + + struct IExceptionTranslatorRegistry { + virtual ~IExceptionTranslatorRegistry(); + + virtual std::string translateActiveException() const = 0; + }; + + class ExceptionTranslatorRegistrar { + template<typename T> + class ExceptionTranslator : public IExceptionTranslator { + public: + + ExceptionTranslator( std::string(*translateFunction)( T& ) ) + : m_translateFunction( translateFunction ) + {} + + std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override { +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + return ""; +#else + try { + if( it == itEnd ) + std::rethrow_exception(std::current_exception()); + else + return (*it)->translate( it+1, itEnd ); + } + catch( T& ex ) { + return m_translateFunction( ex ); + } +#endif + } + + protected: + std::string(*m_translateFunction)( T& ); + }; + + public: + template<typename T> + ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { + getMutableRegistryHub().registerTranslator + ( new ExceptionTranslator<T>( translateFunction ) ); + } + }; +} + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ + static std::string translatorName( signature ); \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ + static std::string translatorName( signature ) + +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) + +// end catch_interfaces_exception.h +// start catch_approx.h + +#include <type_traits> + +namespace Catch { +namespace Detail { + + class Approx { + private: + bool equalityComparisonImpl(double other) const; + // Validates the new margin (margin >= 0) + // out-of-line to avoid including stdexcept in the header + void setMargin(double margin); + // Validates the new epsilon (0 < epsilon < 1) + // out-of-line to avoid including stdexcept in the header + void setEpsilon(double epsilon); + + public: + explicit Approx ( double value ); + + static Approx custom(); + + Approx operator-() const; + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + Approx operator()( T const& value ) const { + Approx approx( static_cast<double>(value) ); + approx.m_epsilon = m_epsilon; + approx.m_margin = m_margin; + approx.m_scale = m_scale; + return approx; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + explicit Approx( T const& value ): Approx(static_cast<double>(value)) + {} + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator == ( const T& lhs, Approx const& rhs ) { + auto lhs_v = static_cast<double>(lhs); + return rhs.equalityComparisonImpl(lhs_v); + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator == ( Approx const& lhs, const T& rhs ) { + return operator==( rhs, lhs ); + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator != ( T const& lhs, Approx const& rhs ) { + return !operator==( lhs, rhs ); + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator != ( Approx const& lhs, T const& rhs ) { + return !operator==( rhs, lhs ); + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator <= ( T const& lhs, Approx const& rhs ) { + return static_cast<double>(lhs) < rhs.m_value || lhs == rhs; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator <= ( Approx const& lhs, T const& rhs ) { + return lhs.m_value < static_cast<double>(rhs) || lhs == rhs; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator >= ( T const& lhs, Approx const& rhs ) { + return static_cast<double>(lhs) > rhs.m_value || lhs == rhs; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + friend bool operator >= ( Approx const& lhs, T const& rhs ) { + return lhs.m_value > static_cast<double>(rhs) || lhs == rhs; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + Approx& epsilon( T const& newEpsilon ) { + double epsilonAsDouble = static_cast<double>(newEpsilon); + setEpsilon(epsilonAsDouble); + return *this; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + Approx& margin( T const& newMargin ) { + double marginAsDouble = static_cast<double>(newMargin); + setMargin(marginAsDouble); + return *this; + } + + template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + Approx& scale( T const& newScale ) { + m_scale = static_cast<double>(newScale); + return *this; + } + + std::string toString() const; + + private: + double m_epsilon; + double m_margin; + double m_scale; + double m_value; + }; +} // end namespace Detail + +namespace literals { + Detail::Approx operator "" _a(long double val); + Detail::Approx operator "" _a(unsigned long long val); +} // end namespace literals + +template<> +struct StringMaker<Catch::Detail::Approx> { + static std::string convert(Catch::Detail::Approx const& value); +}; + +} // end namespace Catch + +// end catch_approx.h +// start catch_string_manip.h + +#include <string> +#include <iosfwd> +#include <vector> + +namespace Catch { + + bool startsWith( std::string const& s, std::string const& prefix ); + bool startsWith( std::string const& s, char prefix ); + bool endsWith( std::string const& s, std::string const& suffix ); + bool endsWith( std::string const& s, char suffix ); + bool contains( std::string const& s, std::string const& infix ); + void toLowerInPlace( std::string& s ); + std::string toLower( std::string const& s ); + //! Returns a new string without whitespace at the start/end + std::string trim( std::string const& str ); + //! Returns a substring of the original ref without whitespace. Beware lifetimes! + StringRef trim(StringRef ref); + + // !!! Be aware, returns refs into original string - make sure original string outlives them + std::vector<StringRef> splitStringRef( StringRef str, char delimiter ); + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); + + struct pluralise { + pluralise( std::size_t count, std::string const& label ); + + friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); + + std::size_t m_count; + std::string m_label; + }; +} + +// end catch_string_manip.h +#ifndef CATCH_CONFIG_DISABLE_MATCHERS +// start catch_capture_matchers.h + +// start catch_matchers.h + +#include <string> +#include <vector> + +namespace Catch { +namespace Matchers { + namespace Impl { + + template<typename ArgT> struct MatchAllOf; + template<typename ArgT> struct MatchAnyOf; + template<typename ArgT> struct MatchNotOf; + + class MatcherUntypedBase { + public: + MatcherUntypedBase() = default; + MatcherUntypedBase ( MatcherUntypedBase const& ) = default; + MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete; + std::string toString() const; + + protected: + virtual ~MatcherUntypedBase(); + virtual std::string describe() const = 0; + mutable std::string m_cachedToString; + }; + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif + + template<typename ObjectT> + struct MatcherMethod { + virtual bool match( ObjectT const& arg ) const = 0; + }; + +#if defined(__OBJC__) + // Hack to fix Catch GH issue #1661. Could use id for generic Object support. + // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation + template<> + struct MatcherMethod<NSString*> { + virtual bool match( NSString* arg ) const = 0; + }; +#endif + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + + template<typename T> + struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> { + + MatchAllOf<T> operator && ( MatcherBase const& other ) const; + MatchAnyOf<T> operator || ( MatcherBase const& other ) const; + MatchNotOf<T> operator ! () const; + }; + + template<typename ArgT> + struct MatchAllOf : MatcherBase<ArgT> { + bool match( ArgT const& arg ) const override { + for( auto matcher : m_matchers ) { + if (!matcher->match(arg)) + return false; + } + return true; + } + std::string describe() const override { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + bool first = true; + for( auto matcher : m_matchers ) { + if( first ) + first = false; + else + description += " and "; + description += matcher->toString(); + } + description += " )"; + return description; + } + + MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) { + auto copy(*this); + copy.m_matchers.push_back( &other ); + return copy; + } + + std::vector<MatcherBase<ArgT> const*> m_matchers; + }; + template<typename ArgT> + struct MatchAnyOf : MatcherBase<ArgT> { + + bool match( ArgT const& arg ) const override { + for( auto matcher : m_matchers ) { + if (matcher->match(arg)) + return true; + } + return false; + } + std::string describe() const override { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + bool first = true; + for( auto matcher : m_matchers ) { + if( first ) + first = false; + else + description += " or "; + description += matcher->toString(); + } + description += " )"; + return description; + } + + MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) { + auto copy(*this); + copy.m_matchers.push_back( &other ); + return copy; + } + + std::vector<MatcherBase<ArgT> const*> m_matchers; + }; + + template<typename ArgT> + struct MatchNotOf : MatcherBase<ArgT> { + + MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {} + + bool match( ArgT const& arg ) const override { + return !m_underlyingMatcher.match( arg ); + } + + std::string describe() const override { + return "not " + m_underlyingMatcher.toString(); + } + MatcherBase<ArgT> const& m_underlyingMatcher; + }; + + template<typename T> + MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const { + return MatchAllOf<T>() && *this && other; + } + template<typename T> + MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const { + return MatchAnyOf<T>() || *this || other; + } + template<typename T> + MatchNotOf<T> MatcherBase<T>::operator ! () const { + return MatchNotOf<T>( *this ); + } + + } // namespace Impl + +} // namespace Matchers + +using namespace Matchers; +using Matchers::Impl::MatcherBase; + +} // namespace Catch + +// end catch_matchers.h +// start catch_matchers_exception.hpp + +namespace Catch { +namespace Matchers { +namespace Exception { + +class ExceptionMessageMatcher : public MatcherBase<std::exception> { + std::string m_message; +public: + + ExceptionMessageMatcher(std::string const& message): + m_message(message) + {} + + bool match(std::exception const& ex) const override; + + std::string describe() const override; +}; + +} // namespace Exception + +Exception::ExceptionMessageMatcher Message(std::string const& message); + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_exception.hpp +// start catch_matchers_floating.h + +namespace Catch { +namespace Matchers { + + namespace Floating { + + enum class FloatingPointKind : uint8_t; + + struct WithinAbsMatcher : MatcherBase<double> { + WithinAbsMatcher(double target, double margin); + bool match(double const& matchee) const override; + std::string describe() const override; + private: + double m_target; + double m_margin; + }; + + struct WithinUlpsMatcher : MatcherBase<double> { + WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType); + bool match(double const& matchee) const override; + std::string describe() const override; + private: + double m_target; + uint64_t m_ulps; + FloatingPointKind m_type; + }; + + // Given IEEE-754 format for floats and doubles, we can assume + // that float -> double promotion is lossless. Given this, we can + // assume that if we do the standard relative comparison of + // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get + // the same result if we do this for floats, as if we do this for + // doubles that were promoted from floats. + struct WithinRelMatcher : MatcherBase<double> { + WithinRelMatcher(double target, double epsilon); + bool match(double const& matchee) const override; + std::string describe() const override; + private: + double m_target; + double m_epsilon; + }; + + } // namespace Floating + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff); + Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff); + Floating::WithinAbsMatcher WithinAbs(double target, double margin); + Floating::WithinRelMatcher WithinRel(double target, double eps); + // defaults epsilon to 100*numeric_limits<double>::epsilon() + Floating::WithinRelMatcher WithinRel(double target); + Floating::WithinRelMatcher WithinRel(float target, float eps); + // defaults epsilon to 100*numeric_limits<float>::epsilon() + Floating::WithinRelMatcher WithinRel(float target); + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_floating.h +// start catch_matchers_generic.hpp + +#include <functional> +#include <string> + +namespace Catch { +namespace Matchers { +namespace Generic { + +namespace Detail { + std::string finalizeDescription(const std::string& desc); +} + +template <typename T> +class PredicateMatcher : public MatcherBase<T> { + std::function<bool(T const&)> m_predicate; + std::string m_description; +public: + + PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr) + :m_predicate(std::move(elem)), + m_description(Detail::finalizeDescription(descr)) + {} + + bool match( T const& item ) const override { + return m_predicate(item); + } + + std::string describe() const override { + return m_description; + } +}; + +} // namespace Generic + + // The following functions create the actual matcher objects. + // The user has to explicitly specify type to the function, because + // inferring std::function<bool(T const&)> is hard (but possible) and + // requires a lot of TMP. + template<typename T> + Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") { + return Generic::PredicateMatcher<T>(predicate, description); + } + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_generic.hpp +// start catch_matchers_string.h + +#include <string> + +namespace Catch { +namespace Matchers { + + namespace StdString { + + struct CasedString + { + CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ); + std::string adjustString( std::string const& str ) const; + std::string caseSensitivitySuffix() const; + + CaseSensitive::Choice m_caseSensitivity; + std::string m_str; + }; + + struct StringMatcherBase : MatcherBase<std::string> { + StringMatcherBase( std::string const& operation, CasedString const& comparator ); + std::string describe() const override; + + CasedString m_comparator; + std::string m_operation; + }; + + struct EqualsMatcher : StringMatcherBase { + EqualsMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + struct ContainsMatcher : StringMatcherBase { + ContainsMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + struct StartsWithMatcher : StringMatcherBase { + StartsWithMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + struct EndsWithMatcher : StringMatcherBase { + EndsWithMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + + struct RegexMatcher : MatcherBase<std::string> { + RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity ); + bool match( std::string const& matchee ) const override; + std::string describe() const override; + + private: + std::string m_regex; + CaseSensitive::Choice m_caseSensitivity; + }; + + } // namespace StdString + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_string.h +// start catch_matchers_vector.h + +#include <algorithm> + +namespace Catch { +namespace Matchers { + + namespace Vector { + template<typename T, typename Alloc> + struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> { + + ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} + + bool match(std::vector<T, Alloc> const &v) const override { + for (auto const& el : v) { + if (el == m_comparator) { + return true; + } + } + return false; + } + + std::string describe() const override { + return "Contains: " + ::Catch::Detail::stringify( m_comparator ); + } + + T const& m_comparator; + }; + + template<typename T, typename AllocComp, typename AllocMatch> + struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> { + + ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector<T, AllocMatch> const &v) const override { + // !TBD: see note in EqualsMatcher + if (m_comparator.size() > v.size()) + return false; + for (auto const& comparator : m_comparator) { + auto present = false; + for (const auto& el : v) { + if (el == comparator) { + present = true; + break; + } + } + if (!present) { + return false; + } + } + return true; + } + std::string describe() const override { + return "Contains: " + ::Catch::Detail::stringify( m_comparator ); + } + + std::vector<T, AllocComp> const& m_comparator; + }; + + template<typename T, typename AllocComp, typename AllocMatch> + struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> { + + EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector<T, AllocMatch> const &v) const override { + // !TBD: This currently works if all elements can be compared using != + // - a more general approach would be via a compare template that defaults + // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc + // - then just call that directly + if (m_comparator.size() != v.size()) + return false; + for (std::size_t i = 0; i < v.size(); ++i) + if (m_comparator[i] != v[i]) + return false; + return true; + } + std::string describe() const override { + return "Equals: " + ::Catch::Detail::stringify( m_comparator ); + } + std::vector<T, AllocComp> const& m_comparator; + }; + + template<typename T, typename AllocComp, typename AllocMatch> + struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> { + + ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {} + + bool match(std::vector<T, AllocMatch> const &v) const override { + if (m_comparator.size() != v.size()) + return false; + for (std::size_t i = 0; i < v.size(); ++i) + if (m_comparator[i] != approx(v[i])) + return false; + return true; + } + std::string describe() const override { + return "is approx: " + ::Catch::Detail::stringify( m_comparator ); + } + template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + ApproxMatcher& epsilon( T const& newEpsilon ) { + approx.epsilon(newEpsilon); + return *this; + } + template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + ApproxMatcher& margin( T const& newMargin ) { + approx.margin(newMargin); + return *this; + } + template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> + ApproxMatcher& scale( T const& newScale ) { + approx.scale(newScale); + return *this; + } + + std::vector<T, AllocComp> const& m_comparator; + mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom(); + }; + + template<typename T, typename AllocComp, typename AllocMatch> + struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> { + UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {} + bool match(std::vector<T, AllocMatch> const& vec) const override { + if (m_target.size() != vec.size()) { + return false; + } + return std::is_permutation(m_target.begin(), m_target.end(), vec.begin()); + } + + std::string describe() const override { + return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target); + } + private: + std::vector<T, AllocComp> const& m_target; + }; + + } // namespace Vector + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp> + Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) { + return Vector::ContainsMatcher<T, AllocComp, AllocMatch>( comparator ); + } + + template<typename T, typename Alloc = std::allocator<T>> + Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) { + return Vector::ContainsElementMatcher<T, Alloc>( comparator ); + } + + template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp> + Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) { + return Vector::EqualsMatcher<T, AllocComp, AllocMatch>( comparator ); + } + + template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp> + Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) { + return Vector::ApproxMatcher<T, AllocComp, AllocMatch>( comparator ); + } + + template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp> + Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) { + return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>( target ); + } + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_vector.h +namespace Catch { + + template<typename ArgT, typename MatcherT> + class MatchExpr : public ITransientExpression { + ArgT const& m_arg; + MatcherT m_matcher; + StringRef m_matcherString; + public: + MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) + : ITransientExpression{ true, matcher.match( arg ) }, + m_arg( arg ), + m_matcher( matcher ), + m_matcherString( matcherString ) + {} + + void streamReconstructedExpression( std::ostream &os ) const override { + auto matcherAsString = m_matcher.toString(); + os << Catch::Detail::stringify( m_arg ) << ' '; + if( matcherAsString == Detail::unprintableString ) + os << m_matcherString; + else + os << matcherAsString; + } + }; + + using StringMatcher = Matchers::Impl::MatcherBase<std::string>; + + void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ); + + template<typename ArgT, typename MatcherT> + auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> { + return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString ); + } + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ + INTERNAL_CATCH_TRY { \ + catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \ + } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast<void>(__VA_ARGS__ ); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( exceptionType const& ex ) { \ + catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +// end catch_capture_matchers.h +#endif +// start catch_generators.hpp + +// start catch_interfaces_generatortracker.h + + +#include <memory> + +namespace Catch { + + namespace Generators { + class GeneratorUntypedBase { + public: + GeneratorUntypedBase() = default; + virtual ~GeneratorUntypedBase(); + // Attempts to move the generator to the next element + // + // Returns true iff the move succeeded (and a valid element + // can be retrieved). + virtual bool next() = 0; + }; + using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>; + + } // namespace Generators + + struct IGeneratorTracker { + virtual ~IGeneratorTracker(); + virtual auto hasGenerator() const -> bool = 0; + virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0; + virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0; + }; + +} // namespace Catch + +// end catch_interfaces_generatortracker.h +// start catch_enforce.h + +#include <exception> + +namespace Catch { +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + template <typename Ex> + [[noreturn]] + void throw_exception(Ex const& e) { + throw e; + } +#else // ^^ Exceptions are enabled // Exceptions are disabled vv + [[noreturn]] + void throw_exception(std::exception const& e); +#endif + + [[noreturn]] + void throw_logic_error(std::string const& msg); + [[noreturn]] + void throw_domain_error(std::string const& msg); + [[noreturn]] + void throw_runtime_error(std::string const& msg); + +} // namespace Catch; + +#define CATCH_MAKE_MSG(...) \ + (Catch::ReusableStringStream() << __VA_ARGS__).str() + +#define CATCH_INTERNAL_ERROR(...) \ + Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__)) + +#define CATCH_ERROR(...) \ + Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ )) + +#define CATCH_RUNTIME_ERROR(...) \ + Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ )) + +#define CATCH_ENFORCE( condition, ... ) \ + do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false) + +// end catch_enforce.h +#include <memory> +#include <vector> +#include <cassert> + +#include <utility> +#include <exception> + +namespace Catch { + +class GeneratorException : public std::exception { + const char* const m_msg = ""; + +public: + GeneratorException(const char* msg): + m_msg(msg) + {} + + const char* what() const noexcept override final; +}; + +namespace Generators { + + // !TBD move this into its own location? + namespace pf{ + template<typename T, typename... Args> + std::unique_ptr<T> make_unique( Args&&... args ) { + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); + } + } + + template<typename T> + struct IGenerator : GeneratorUntypedBase { + virtual ~IGenerator() = default; + + // Returns the current element of the generator + // + // \Precondition The generator is either freshly constructed, + // or the last call to `next()` returned true + virtual T const& get() const = 0; + using type = T; + }; + + template<typename T> + class SingleValueGenerator final : public IGenerator<T> { + T m_value; + public: + SingleValueGenerator(T&& value) : m_value(std::move(value)) {} + + T const& get() const override { + return m_value; + } + bool next() override { + return false; + } + }; + + template<typename T> + class FixedValuesGenerator final : public IGenerator<T> { + static_assert(!std::is_same<T, bool>::value, + "FixedValuesGenerator does not support bools because of std::vector<bool>" + "specialization, use SingleValue Generator instead."); + std::vector<T> m_values; + size_t m_idx = 0; + public: + FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {} + + T const& get() const override { + return m_values[m_idx]; + } + bool next() override { + ++m_idx; + return m_idx < m_values.size(); + } + }; + + template <typename T> + class GeneratorWrapper final { + std::unique_ptr<IGenerator<T>> m_generator; + public: + GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator): + m_generator(std::move(generator)) + {} + T const& get() const { + return m_generator->get(); + } + bool next() { + return m_generator->next(); + } + }; + + template <typename T> + GeneratorWrapper<T> value(T&& value) { + return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value))); + } + template <typename T> + GeneratorWrapper<T> values(std::initializer_list<T> values) { + return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values)); + } + + template<typename T> + class Generators : public IGenerator<T> { + std::vector<GeneratorWrapper<T>> m_generators; + size_t m_current = 0; + + void populate(GeneratorWrapper<T>&& generator) { + m_generators.emplace_back(std::move(generator)); + } + void populate(T&& val) { + m_generators.emplace_back(value(std::forward<T>(val))); + } + template<typename U> + void populate(U&& val) { + populate(T(std::forward<U>(val))); + } + template<typename U, typename... Gs> + void populate(U&& valueOrGenerator, Gs &&... moreGenerators) { + populate(std::forward<U>(valueOrGenerator)); + populate(std::forward<Gs>(moreGenerators)...); + } + + public: + template <typename... Gs> + Generators(Gs &&... moreGenerators) { + m_generators.reserve(sizeof...(Gs)); + populate(std::forward<Gs>(moreGenerators)...); + } + + T const& get() const override { + return m_generators[m_current].get(); + } + + bool next() override { + if (m_current >= m_generators.size()) { + return false; + } + const bool current_status = m_generators[m_current].next(); + if (!current_status) { + ++m_current; + } + return m_current < m_generators.size(); + } + }; + + template<typename... Ts> + GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) { + return values<std::tuple<Ts...>>( tuples ); + } + + // Tag type to signal that a generator sequence should convert arguments to a specific type + template <typename T> + struct as {}; + + template<typename T, typename... Gs> + auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> { + return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...); + } + template<typename T> + auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> { + return Generators<T>(std::move(generator)); + } + template<typename T, typename... Gs> + auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> { + return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... ); + } + template<typename T, typename U, typename... Gs> + auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> { + return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... ); + } + + auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; + + template<typename L> + // Note: The type after -> is weird, because VS2015 cannot parse + // the expression used in the typedef inside, when it is in + // return type. Yeah. + auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) { + using UnderlyingType = typename decltype(generatorExpression())::type; + + IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo ); + if (!tracker.hasGenerator()) { + tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression())); + } + + auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() ); + return generator.get(); + } + +} // namespace Generators +} // namespace Catch + +#define GENERATE( ... ) \ + Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ + CATCH_INTERNAL_LINEINFO, \ + [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) +#define GENERATE_COPY( ... ) \ + Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ + CATCH_INTERNAL_LINEINFO, \ + [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) +#define GENERATE_REF( ... ) \ + Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ + CATCH_INTERNAL_LINEINFO, \ + [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) + +// end catch_generators.hpp +// start catch_generators_generic.hpp + +namespace Catch { +namespace Generators { + + template <typename T> + class TakeGenerator : public IGenerator<T> { + GeneratorWrapper<T> m_generator; + size_t m_returned = 0; + size_t m_target; + public: + TakeGenerator(size_t target, GeneratorWrapper<T>&& generator): + m_generator(std::move(generator)), + m_target(target) + { + assert(target != 0 && "Empty generators are not allowed"); + } + T const& get() const override { + return m_generator.get(); + } + bool next() override { + ++m_returned; + if (m_returned >= m_target) { + return false; + } + + const auto success = m_generator.next(); + // If the underlying generator does not contain enough values + // then we cut short as well + if (!success) { + m_returned = m_target; + } + return success; + } + }; + + template <typename T> + GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) { + return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator))); + } + + template <typename T, typename Predicate> + class FilterGenerator : public IGenerator<T> { + GeneratorWrapper<T> m_generator; + Predicate m_predicate; + public: + template <typename P = Predicate> + FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator): + m_generator(std::move(generator)), + m_predicate(std::forward<P>(pred)) + { + if (!m_predicate(m_generator.get())) { + // It might happen that there are no values that pass the + // filter. In that case we throw an exception. + auto has_initial_value = nextImpl(); + if (!has_initial_value) { + Catch::throw_exception(GeneratorException("No valid value found in filtered generator")); + } + } + } + + T const& get() const override { + return m_generator.get(); + } + + bool next() override { + return nextImpl(); + } + + private: + bool nextImpl() { + bool success = m_generator.next(); + if (!success) { + return false; + } + while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true); + return success; + } + }; + + template <typename T, typename Predicate> + GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) { + return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator)))); + } + + template <typename T> + class RepeatGenerator : public IGenerator<T> { + static_assert(!std::is_same<T, bool>::value, + "RepeatGenerator currently does not support bools" + "because of std::vector<bool> specialization"); + GeneratorWrapper<T> m_generator; + mutable std::vector<T> m_returned; + size_t m_target_repeats; + size_t m_current_repeat = 0; + size_t m_repeat_index = 0; + public: + RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator): + m_generator(std::move(generator)), + m_target_repeats(repeats) + { + assert(m_target_repeats > 0 && "Repeat generator must repeat at least once"); + } + + T const& get() const override { + if (m_current_repeat == 0) { + m_returned.push_back(m_generator.get()); + return m_returned.back(); + } + return m_returned[m_repeat_index]; + } + + bool next() override { + // There are 2 basic cases: + // 1) We are still reading the generator + // 2) We are reading our own cache + + // In the first case, we need to poke the underlying generator. + // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache + if (m_current_repeat == 0) { + const auto success = m_generator.next(); + if (!success) { + ++m_current_repeat; + } + return m_current_repeat < m_target_repeats; + } + + // In the second case, we need to move indices forward and check that we haven't run up against the end + ++m_repeat_index; + if (m_repeat_index == m_returned.size()) { + m_repeat_index = 0; + ++m_current_repeat; + } + return m_current_repeat < m_target_repeats; + } + }; + + template <typename T> + GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) { + return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator))); + } + + template <typename T, typename U, typename Func> + class MapGenerator : public IGenerator<T> { + // TBD: provide static assert for mapping function, for friendly error message + GeneratorWrapper<U> m_generator; + Func m_function; + // To avoid returning dangling reference, we have to save the values + T m_cache; + public: + template <typename F2 = Func> + MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) : + m_generator(std::move(generator)), + m_function(std::forward<F2>(function)), + m_cache(m_function(m_generator.get())) + {} + + T const& get() const override { + return m_cache; + } + bool next() override { + const auto success = m_generator.next(); + if (success) { + m_cache = m_function(m_generator.get()); + } + return success; + } + }; + + template <typename Func, typename U, typename T = FunctionReturnType<Func, U>> + GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) { + return GeneratorWrapper<T>( + pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator)) + ); + } + + template <typename T, typename U, typename Func> + GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) { + return GeneratorWrapper<T>( + pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator)) + ); + } + + template <typename T> + class ChunkGenerator final : public IGenerator<std::vector<T>> { + std::vector<T> m_chunk; + size_t m_chunk_size; + GeneratorWrapper<T> m_generator; + bool m_used_up = false; + public: + ChunkGenerator(size_t size, GeneratorWrapper<T> generator) : + m_chunk_size(size), m_generator(std::move(generator)) + { + m_chunk.reserve(m_chunk_size); + if (m_chunk_size != 0) { + m_chunk.push_back(m_generator.get()); + for (size_t i = 1; i < m_chunk_size; ++i) { + if (!m_generator.next()) { + Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk")); + } + m_chunk.push_back(m_generator.get()); + } + } + } + std::vector<T> const& get() const override { + return m_chunk; + } + bool next() override { + m_chunk.clear(); + for (size_t idx = 0; idx < m_chunk_size; ++idx) { + if (!m_generator.next()) { + return false; + } + m_chunk.push_back(m_generator.get()); + } + return true; + } + }; + + template <typename T> + GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) { + return GeneratorWrapper<std::vector<T>>( + pf::make_unique<ChunkGenerator<T>>(size, std::move(generator)) + ); + } + +} // namespace Generators +} // namespace Catch + +// end catch_generators_generic.hpp +// start catch_generators_specific.hpp + +// start catch_context.h + +#include <memory> + +namespace Catch { + + struct IResultCapture; + struct IRunner; + struct IConfig; + struct IMutableContext; + + using IConfigPtr = std::shared_ptr<IConfig const>; + + struct IContext + { + virtual ~IContext(); + + virtual IResultCapture* getResultCapture() = 0; + virtual IRunner* getRunner() = 0; + virtual IConfigPtr const& getConfig() const = 0; + }; + + struct IMutableContext : IContext + { + virtual ~IMutableContext(); + virtual void setResultCapture( IResultCapture* resultCapture ) = 0; + virtual void setRunner( IRunner* runner ) = 0; + virtual void setConfig( IConfigPtr const& config ) = 0; + + private: + static IMutableContext *currentContext; + friend IMutableContext& getCurrentMutableContext(); + friend void cleanUpContext(); + static void createContext(); + }; + + inline IMutableContext& getCurrentMutableContext() + { + if( !IMutableContext::currentContext ) + IMutableContext::createContext(); + // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn) + return *IMutableContext::currentContext; + } + + inline IContext& getCurrentContext() + { + return getCurrentMutableContext(); + } + + void cleanUpContext(); + + class SimplePcg32; + SimplePcg32& rng(); +} + +// end catch_context.h +// start catch_interfaces_config.h + +// start catch_option.hpp + +namespace Catch { + + // An optional type + template<typename T> + class Option { + public: + Option() : nullableValue( nullptr ) {} + Option( T const& _value ) + : nullableValue( new( storage ) T( _value ) ) + {} + Option( Option const& _other ) + : nullableValue( _other ? new( storage ) T( *_other ) : nullptr ) + {} + + ~Option() { + reset(); + } + + Option& operator= ( Option const& _other ) { + if( &_other != this ) { + reset(); + if( _other ) + nullableValue = new( storage ) T( *_other ); + } + return *this; + } + Option& operator = ( T const& _value ) { + reset(); + nullableValue = new( storage ) T( _value ); + return *this; + } + + void reset() { + if( nullableValue ) + nullableValue->~T(); + nullableValue = nullptr; + } + + T& operator*() { return *nullableValue; } + T const& operator*() const { return *nullableValue; } + T* operator->() { return nullableValue; } + const T* operator->() const { return nullableValue; } + + T valueOr( T const& defaultValue ) const { + return nullableValue ? *nullableValue : defaultValue; + } + + bool some() const { return nullableValue != nullptr; } + bool none() const { return nullableValue == nullptr; } + + bool operator !() const { return nullableValue == nullptr; } + explicit operator bool() const { + return some(); + } + + private: + T *nullableValue; + alignas(alignof(T)) char storage[sizeof(T)]; + }; + +} // end namespace Catch + +// end catch_option.hpp +#include <chrono> +#include <iosfwd> +#include <string> +#include <vector> +#include <memory> + +namespace Catch { + + enum class Verbosity { + Quiet = 0, + Normal, + High + }; + + struct WarnAbout { enum What { + Nothing = 0x00, + NoAssertions = 0x01, + NoTests = 0x02 + }; }; + + struct ShowDurations { enum OrNot { + DefaultForReporter, + Always, + Never + }; }; + struct RunTests { enum InWhatOrder { + InDeclarationOrder, + InLexicographicalOrder, + InRandomOrder + }; }; + struct UseColour { enum YesOrNo { + Auto, + Yes, + No + }; }; + struct WaitForKeypress { enum When { + Never, + BeforeStart = 1, + BeforeExit = 2, + BeforeStartAndExit = BeforeStart | BeforeExit + }; }; + + class TestSpec; + + struct IConfig : NonCopyable { + + virtual ~IConfig(); + + virtual bool allowThrows() const = 0; + virtual std::ostream& stream() const = 0; + virtual std::string name() const = 0; + virtual bool includeSuccessfulResults() const = 0; + virtual bool shouldDebugBreak() const = 0; + virtual bool warnAboutMissingAssertions() const = 0; + virtual bool warnAboutNoTests() const = 0; + virtual int abortAfter() const = 0; + virtual bool showInvisibles() const = 0; + virtual ShowDurations::OrNot showDurations() const = 0; + virtual double minDuration() const = 0; + virtual TestSpec const& testSpec() const = 0; + virtual bool hasTestFilters() const = 0; + virtual std::vector<std::string> const& getTestsOrTags() const = 0; + virtual RunTests::InWhatOrder runOrder() const = 0; + virtual unsigned int rngSeed() const = 0; + virtual UseColour::YesOrNo useColour() const = 0; + virtual std::vector<std::string> const& getSectionsToRun() const = 0; + virtual Verbosity verbosity() const = 0; + + virtual bool benchmarkNoAnalysis() const = 0; + virtual int benchmarkSamples() const = 0; + virtual double benchmarkConfidenceInterval() const = 0; + virtual unsigned int benchmarkResamples() const = 0; + virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0; + }; + + using IConfigPtr = std::shared_ptr<IConfig const>; +} + +// end catch_interfaces_config.h +// start catch_random_number_generator.h + +#include <cstdint> + +namespace Catch { + + // This is a simple implementation of C++11 Uniform Random Number + // Generator. It does not provide all operators, because Catch2 + // does not use it, but it should behave as expected inside stdlib's + // distributions. + // The implementation is based on the PCG family (http://pcg-random.org) + class SimplePcg32 { + using state_type = std::uint64_t; + public: + using result_type = std::uint32_t; + static constexpr result_type (min)() { + return 0; + } + static constexpr result_type (max)() { + return static_cast<result_type>(-1); + } + + // Provide some default initial state for the default constructor + SimplePcg32():SimplePcg32(0xed743cc4U) {} + + explicit SimplePcg32(result_type seed_); + + void seed(result_type seed_); + void discard(uint64_t skip); + + result_type operator()(); + + private: + friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs); + friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs); + + // In theory we also need operator<< and operator>> + // In practice we do not use them, so we will skip them for now + + std::uint64_t m_state; + // This part of the state determines which "stream" of the numbers + // is chosen -- we take it as a constant for Catch2, so we only + // need to deal with seeding the main state. + // Picked by reading 8 bytes from `/dev/random` :-) + static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL; + }; + +} // end namespace Catch + +// end catch_random_number_generator.h +#include <random> + +namespace Catch { +namespace Generators { + +template <typename Float> +class RandomFloatingGenerator final : public IGenerator<Float> { + Catch::SimplePcg32& m_rng; + std::uniform_real_distribution<Float> m_dist; + Float m_current_number; +public: + + RandomFloatingGenerator(Float a, Float b): + m_rng(rng()), + m_dist(a, b) { + static_cast<void>(next()); + } + + Float const& get() const override { + return m_current_number; + } + bool next() override { + m_current_number = m_dist(m_rng); + return true; + } +}; + +template <typename Integer> +class RandomIntegerGenerator final : public IGenerator<Integer> { + Catch::SimplePcg32& m_rng; + std::uniform_int_distribution<Integer> m_dist; + Integer m_current_number; +public: + + RandomIntegerGenerator(Integer a, Integer b): + m_rng(rng()), + m_dist(a, b) { + static_cast<void>(next()); + } + + Integer const& get() const override { + return m_current_number; + } + bool next() override { + m_current_number = m_dist(m_rng); + return true; + } +}; + +// TODO: Ideally this would be also constrained against the various char types, +// but I don't expect users to run into that in practice. +template <typename T> +typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value, +GeneratorWrapper<T>>::type +random(T a, T b) { + return GeneratorWrapper<T>( + pf::make_unique<RandomIntegerGenerator<T>>(a, b) + ); +} + +template <typename T> +typename std::enable_if<std::is_floating_point<T>::value, +GeneratorWrapper<T>>::type +random(T a, T b) { + return GeneratorWrapper<T>( + pf::make_unique<RandomFloatingGenerator<T>>(a, b) + ); +} + +template <typename T> +class RangeGenerator final : public IGenerator<T> { + T m_current; + T m_end; + T m_step; + bool m_positive; + +public: + RangeGenerator(T const& start, T const& end, T const& step): + m_current(start), + m_end(end), + m_step(step), + m_positive(m_step > T(0)) + { + assert(m_current != m_end && "Range start and end cannot be equal"); + assert(m_step != T(0) && "Step size cannot be zero"); + assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end"); + } + + RangeGenerator(T const& start, T const& end): + RangeGenerator(start, end, (start < end) ? T(1) : T(-1)) + {} + + T const& get() const override { + return m_current; + } + + bool next() override { + m_current += m_step; + return (m_positive) ? (m_current < m_end) : (m_current > m_end); + } +}; + +template <typename T> +GeneratorWrapper<T> range(T const& start, T const& end, T const& step) { + static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric"); + return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step)); +} + +template <typename T> +GeneratorWrapper<T> range(T const& start, T const& end) { + static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer"); + return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end)); +} + +template <typename T> +class IteratorGenerator final : public IGenerator<T> { + static_assert(!std::is_same<T, bool>::value, + "IteratorGenerator currently does not support bools" + "because of std::vector<bool> specialization"); + + std::vector<T> m_elems; + size_t m_current = 0; +public: + template <typename InputIterator, typename InputSentinel> + IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) { + if (m_elems.empty()) { + Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values")); + } + } + + T const& get() const override { + return m_elems[m_current]; + } + + bool next() override { + ++m_current; + return m_current != m_elems.size(); + } +}; + +template <typename InputIterator, + typename InputSentinel, + typename ResultType = typename std::iterator_traits<InputIterator>::value_type> +GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) { + return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to)); +} + +template <typename Container, + typename ResultType = typename Container::value_type> +GeneratorWrapper<ResultType> from_range(Container const& cnt) { + return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end())); +} + +} // namespace Generators +} // namespace Catch + +// end catch_generators_specific.hpp + +// These files are included here so the single_include script doesn't put them +// in the conditionally compiled sections +// start catch_test_case_info.h + +#include <string> +#include <vector> +#include <memory> + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + + struct ITestInvoker; + + struct TestCaseInfo { + enum SpecialProperties{ + None = 0, + IsHidden = 1 << 1, + ShouldFail = 1 << 2, + MayFail = 1 << 3, + Throws = 1 << 4, + NonPortable = 1 << 5, + Benchmark = 1 << 6 + }; + + TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::vector<std::string> const& _tags, + SourceLineInfo const& _lineInfo ); + + friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ); + + bool isHidden() const; + bool throws() const; + bool okToFail() const; + bool expectedToFail() const; + + std::string tagsAsString() const; + + std::string name; + std::string className; + std::string description; + std::vector<std::string> tags; + std::vector<std::string> lcaseTags; + SourceLineInfo lineInfo; + SpecialProperties properties; + }; + + class TestCase : public TestCaseInfo { + public: + + TestCase( ITestInvoker* testCase, TestCaseInfo&& info ); + + TestCase withName( std::string const& _newName ) const; + + void invoke() const; + + TestCaseInfo const& getTestCaseInfo() const; + + bool operator == ( TestCase const& other ) const; + bool operator < ( TestCase const& other ) const; + + private: + std::shared_ptr<ITestInvoker> test; + }; + + TestCase makeTestCase( ITestInvoker* testCase, + std::string const& className, + NameAndTags const& nameAndTags, + SourceLineInfo const& lineInfo ); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_case_info.h +// start catch_interfaces_runner.h + +namespace Catch { + + struct IRunner { + virtual ~IRunner(); + virtual bool aborting() const = 0; + }; +} + +// end catch_interfaces_runner.h + +#ifdef __OBJC__ +// start catch_objc.hpp + +#import <objc/runtime.h> + +#include <string> + +// NB. Any general catch headers included here must be included +// in catch.hpp first to make sure they are included by the single +// header for non obj-usage + +/////////////////////////////////////////////////////////////////////////////// +// This protocol is really only here for (self) documenting purposes, since +// all its methods are optional. +@protocol OcFixture + +@optional + +-(void) setUp; +-(void) tearDown; + +@end + +namespace Catch { + + class OcMethod : public ITestInvoker { + + public: + OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} + + virtual void invoke() const { + id obj = [[m_cls alloc] init]; + + performOptionalSelector( obj, @selector(setUp) ); + performOptionalSelector( obj, m_sel ); + performOptionalSelector( obj, @selector(tearDown) ); + + arcSafeRelease( obj ); + } + private: + virtual ~OcMethod() {} + + Class m_cls; + SEL m_sel; + }; + + namespace Detail{ + + inline std::string getAnnotation( Class cls, + std::string const& annotationName, + std::string const& testCaseName ) { + NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; + SEL sel = NSSelectorFromString( selStr ); + arcSafeRelease( selStr ); + id value = performOptionalSelector( cls, sel ); + if( value ) + return [(NSString*)value UTF8String]; + return ""; + } + } + + inline std::size_t registerTestMethods() { + std::size_t noTestMethods = 0; + int noClasses = objc_getClassList( nullptr, 0 ); + + Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); + objc_getClassList( classes, noClasses ); + + for( int c = 0; c < noClasses; c++ ) { + Class cls = classes[c]; + { + u_int count; + Method* methods = class_copyMethodList( cls, &count ); + for( u_int m = 0; m < count ; m++ ) { + SEL selector = method_getName(methods[m]); + std::string methodName = sel_getName(selector); + if( startsWith( methodName, "Catch_TestCase_" ) ) { + std::string testCaseName = methodName.substr( 15 ); + std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); + std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); + const char* className = class_getName( cls ); + + getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) ); + noTestMethods++; + } + } + free(methods); + } + } + return noTestMethods; + } + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) + + namespace Matchers { + namespace Impl { + namespace NSStringMatchers { + + struct StringHolder : MatcherBase<NSString*>{ + StringHolder( NSString* substr ) : m_substr( [substr copy] ){} + StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} + StringHolder() { + arcSafeRelease( m_substr ); + } + + bool match( NSString* str ) const override { + return false; + } + + NSString* CATCH_ARC_STRONG m_substr; + }; + + struct Equals : StringHolder { + Equals( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const override { + return (str != nil || m_substr == nil ) && + [str isEqualToString:m_substr]; + } + + std::string describe() const override { + return "equals string: " + Catch::Detail::stringify( m_substr ); + } + }; + + struct Contains : StringHolder { + Contains( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const override { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location != NSNotFound; + } + + std::string describe() const override { + return "contains string: " + Catch::Detail::stringify( m_substr ); + } + }; + + struct StartsWith : StringHolder { + StartsWith( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const override { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == 0; + } + + std::string describe() const override { + return "starts with: " + Catch::Detail::stringify( m_substr ); + } + }; + struct EndsWith : StringHolder { + EndsWith( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const override { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == [str length] - [m_substr length]; + } + + std::string describe() const override { + return "ends with: " + Catch::Detail::stringify( m_substr ); + } + }; + + } // namespace NSStringMatchers + } // namespace Impl + + inline Impl::NSStringMatchers::Equals + Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } + + inline Impl::NSStringMatchers::Contains + Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } + + inline Impl::NSStringMatchers::StartsWith + StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } + + inline Impl::NSStringMatchers::EndsWith + EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } + + } // namespace Matchers + + using namespace Matchers; + +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix +#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \ ++(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \ +{ \ +return @ name; \ +} \ ++(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \ +{ \ +return @ desc; \ +} \ +-(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix ) + +#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ ) + +// end catch_objc.hpp +#endif + +// Benchmarking needs the externally-facing parts of reporters to work +#if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING) +// start catch_external_interfaces.h + +// start catch_reporter_bases.hpp + +// start catch_interfaces_reporter.h + +// start catch_config.hpp + +// start catch_test_spec_parser.h + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// start catch_test_spec.h + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// start catch_wildcard_pattern.h + +namespace Catch +{ + class WildcardPattern { + enum WildcardPosition { + NoWildcard = 0, + WildcardAtStart = 1, + WildcardAtEnd = 2, + WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd + }; + + public: + + WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ); + virtual ~WildcardPattern() = default; + virtual bool matches( std::string const& str ) const; + + private: + std::string normaliseString( std::string const& str ) const; + CaseSensitive::Choice m_caseSensitivity; + WildcardPosition m_wildcard = NoWildcard; + std::string m_pattern; + }; +} + +// end catch_wildcard_pattern.h +#include <string> +#include <vector> +#include <memory> + +namespace Catch { + + struct IConfig; + + class TestSpec { + class Pattern { + public: + explicit Pattern( std::string const& name ); + virtual ~Pattern(); + virtual bool matches( TestCaseInfo const& testCase ) const = 0; + std::string const& name() const; + private: + std::string const m_name; + }; + using PatternPtr = std::shared_ptr<Pattern>; + + class NamePattern : public Pattern { + public: + explicit NamePattern( std::string const& name, std::string const& filterString ); + bool matches( TestCaseInfo const& testCase ) const override; + private: + WildcardPattern m_wildcardPattern; + }; + + class TagPattern : public Pattern { + public: + explicit TagPattern( std::string const& tag, std::string const& filterString ); + bool matches( TestCaseInfo const& testCase ) const override; + private: + std::string m_tag; + }; + + class ExcludedPattern : public Pattern { + public: + explicit ExcludedPattern( PatternPtr const& underlyingPattern ); + bool matches( TestCaseInfo const& testCase ) const override; + private: + PatternPtr m_underlyingPattern; + }; + + struct Filter { + std::vector<PatternPtr> m_patterns; + + bool matches( TestCaseInfo const& testCase ) const; + std::string name() const; + }; + + public: + struct FilterMatch { + std::string name; + std::vector<TestCase const*> tests; + }; + using Matches = std::vector<FilterMatch>; + using vectorStrings = std::vector<std::string>; + + bool hasFilters() const; + bool matches( TestCaseInfo const& testCase ) const; + Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const; + const vectorStrings & getInvalidArgs() const; + + private: + std::vector<Filter> m_filters; + std::vector<std::string> m_invalidArgs; + friend class TestSpecParser; + }; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_spec.h +// start catch_interfaces_tag_alias_registry.h + +#include <string> + +namespace Catch { + + struct TagAlias; + + struct ITagAliasRegistry { + virtual ~ITagAliasRegistry(); + // Nullptr if not present + virtual TagAlias const* find( std::string const& alias ) const = 0; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; + + static ITagAliasRegistry const& get(); + }; + +} // end namespace Catch + +// end catch_interfaces_tag_alias_registry.h +namespace Catch { + + class TestSpecParser { + enum Mode{ None, Name, QuotedName, Tag, EscapedName }; + Mode m_mode = None; + Mode lastMode = None; + bool m_exclusion = false; + std::size_t m_pos = 0; + std::size_t m_realPatternPos = 0; + std::string m_arg; + std::string m_substring; + std::string m_patternName; + std::vector<std::size_t> m_escapeChars; + TestSpec::Filter m_currentFilter; + TestSpec m_testSpec; + ITagAliasRegistry const* m_tagAliases = nullptr; + + public: + TestSpecParser( ITagAliasRegistry const& tagAliases ); + + TestSpecParser& parse( std::string const& arg ); + TestSpec testSpec(); + + private: + bool visitChar( char c ); + void startNewMode( Mode mode ); + bool processNoneChar( char c ); + void processNameChar( char c ); + bool processOtherChar( char c ); + void endMode(); + void escape(); + bool isControlChar( char c ) const; + void saveLastMode(); + void revertBackToLastMode(); + void addFilter(); + bool separate(); + + // Handles common preprocessing of the pattern for name/tag patterns + std::string preprocessPattern(); + // Adds the current pattern as a test name + void addNamePattern(); + // Adds the current pattern as a tag + void addTagPattern(); + + inline void addCharToPattern(char c) { + m_substring += c; + m_patternName += c; + m_realPatternPos++; + } + + }; + TestSpec parseTestSpec( std::string const& arg ); + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_spec_parser.h +// Libstdc++ doesn't like incomplete classes for unique_ptr + +#include <memory> +#include <vector> +#include <string> + +#ifndef CATCH_CONFIG_CONSOLE_WIDTH +#define CATCH_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { + + struct IStream; + + struct ConfigData { + bool listTests = false; + bool listTags = false; + bool listReporters = false; + bool listTestNamesOnly = false; + + bool showSuccessfulTests = false; + bool shouldDebugBreak = false; + bool noThrow = false; + bool showHelp = false; + bool showInvisibles = false; + bool filenamesAsTags = false; + bool libIdentify = false; + + int abortAfter = -1; + unsigned int rngSeed = 0; + + bool benchmarkNoAnalysis = false; + unsigned int benchmarkSamples = 100; + double benchmarkConfidenceInterval = 0.95; + unsigned int benchmarkResamples = 100000; + std::chrono::milliseconds::rep benchmarkWarmupTime = 100; + + Verbosity verbosity = Verbosity::Normal; + WarnAbout::What warnings = WarnAbout::Nothing; + ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter; + double minDuration = -1; + RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder; + UseColour::YesOrNo useColour = UseColour::Auto; + WaitForKeypress::When waitForKeypress = WaitForKeypress::Never; + + std::string outputFilename; + std::string name; + std::string processName; +#ifndef CATCH_CONFIG_DEFAULT_REPORTER +#define CATCH_CONFIG_DEFAULT_REPORTER "console" +#endif + std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER; +#undef CATCH_CONFIG_DEFAULT_REPORTER + + std::vector<std::string> testsOrTags; + std::vector<std::string> sectionsToRun; + }; + + class Config : public IConfig { + public: + + Config() = default; + Config( ConfigData const& data ); + virtual ~Config() = default; + + std::string const& getFilename() const; + + bool listTests() const; + bool listTestNamesOnly() const; + bool listTags() const; + bool listReporters() const; + + std::string getProcessName() const; + std::string const& getReporterName() const; + + std::vector<std::string> const& getTestsOrTags() const override; + std::vector<std::string> const& getSectionsToRun() const override; + + TestSpec const& testSpec() const override; + bool hasTestFilters() const override; + + bool showHelp() const; + + // IConfig interface + bool allowThrows() const override; + std::ostream& stream() const override; + std::string name() const override; + bool includeSuccessfulResults() const override; + bool warnAboutMissingAssertions() const override; + bool warnAboutNoTests() const override; + ShowDurations::OrNot showDurations() const override; + double minDuration() const override; + RunTests::InWhatOrder runOrder() const override; + unsigned int rngSeed() const override; + UseColour::YesOrNo useColour() const override; + bool shouldDebugBreak() const override; + int abortAfter() const override; + bool showInvisibles() const override; + Verbosity verbosity() const override; + bool benchmarkNoAnalysis() const override; + int benchmarkSamples() const override; + double benchmarkConfidenceInterval() const override; + unsigned int benchmarkResamples() const override; + std::chrono::milliseconds benchmarkWarmupTime() const override; + + private: + + IStream const* openStream(); + ConfigData m_data; + + std::unique_ptr<IStream const> m_stream; + TestSpec m_testSpec; + bool m_hasTestFilters = false; + }; + +} // end namespace Catch + +// end catch_config.hpp +// start catch_assertionresult.h + +#include <string> + +namespace Catch { + + struct AssertionResultData + { + AssertionResultData() = delete; + + AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression ); + + std::string message; + mutable std::string reconstructedExpression; + LazyExpression lazyExpression; + ResultWas::OfType resultType; + + std::string reconstructExpression() const; + }; + + class AssertionResult { + public: + AssertionResult() = delete; + AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); + + bool isOk() const; + bool succeeded() const; + ResultWas::OfType getResultType() const; + bool hasExpression() const; + bool hasMessage() const; + std::string getExpression() const; + std::string getExpressionInMacro() const; + bool hasExpandedExpression() const; + std::string getExpandedExpression() const; + std::string getMessage() const; + SourceLineInfo getSourceInfo() const; + StringRef getTestMacroName() const; + + //protected: + AssertionInfo m_info; + AssertionResultData m_resultData; + }; + +} // end namespace Catch + +// end catch_assertionresult.h +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) +// start catch_estimate.hpp + + // Statistics estimates + + +namespace Catch { + namespace Benchmark { + template <typename Duration> + struct Estimate { + Duration point; + Duration lower_bound; + Duration upper_bound; + double confidence_interval; + + template <typename Duration2> + operator Estimate<Duration2>() const { + return { point, lower_bound, upper_bound, confidence_interval }; + } + }; + } // namespace Benchmark +} // namespace Catch + +// end catch_estimate.hpp +// start catch_outlier_classification.hpp + +// Outlier information + +namespace Catch { + namespace Benchmark { + struct OutlierClassification { + int samples_seen = 0; + int low_severe = 0; // more than 3 times IQR below Q1 + int low_mild = 0; // 1.5 to 3 times IQR below Q1 + int high_mild = 0; // 1.5 to 3 times IQR above Q3 + int high_severe = 0; // more than 3 times IQR above Q3 + + int total() const { + return low_severe + low_mild + high_mild + high_severe; + } + }; + } // namespace Benchmark +} // namespace Catch + +// end catch_outlier_classification.hpp + +#include <iterator> +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + +#include <string> +#include <iosfwd> +#include <map> +#include <set> +#include <memory> +#include <algorithm> + +namespace Catch { + + struct ReporterConfig { + explicit ReporterConfig( IConfigPtr const& _fullConfig ); + + ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream ); + + std::ostream& stream() const; + IConfigPtr fullConfig() const; + + private: + std::ostream* m_stream; + IConfigPtr m_fullConfig; + }; + + struct ReporterPreferences { + bool shouldRedirectStdOut = false; + bool shouldReportAllAssertions = false; + }; + + template<typename T> + struct LazyStat : Option<T> { + LazyStat& operator=( T const& _value ) { + Option<T>::operator=( _value ); + used = false; + return *this; + } + void reset() { + Option<T>::reset(); + used = false; + } + bool used = false; + }; + + struct TestRunInfo { + TestRunInfo( std::string const& _name ); + std::string name; + }; + struct GroupInfo { + GroupInfo( std::string const& _name, + std::size_t _groupIndex, + std::size_t _groupsCount ); + + std::string name; + std::size_t groupIndex; + std::size_t groupsCounts; + }; + + struct AssertionStats { + AssertionStats( AssertionResult const& _assertionResult, + std::vector<MessageInfo> const& _infoMessages, + Totals const& _totals ); + + AssertionStats( AssertionStats const& ) = default; + AssertionStats( AssertionStats && ) = default; + AssertionStats& operator = ( AssertionStats const& ) = delete; + AssertionStats& operator = ( AssertionStats && ) = delete; + virtual ~AssertionStats(); + + AssertionResult assertionResult; + std::vector<MessageInfo> infoMessages; + Totals totals; + }; + + struct SectionStats { + SectionStats( SectionInfo const& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ); + SectionStats( SectionStats const& ) = default; + SectionStats( SectionStats && ) = default; + SectionStats& operator = ( SectionStats const& ) = default; + SectionStats& operator = ( SectionStats && ) = default; + virtual ~SectionStats(); + + SectionInfo sectionInfo; + Counts assertions; + double durationInSeconds; + bool missingAssertions; + }; + + struct TestCaseStats { + TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string const& _stdOut, + std::string const& _stdErr, + bool _aborting ); + + TestCaseStats( TestCaseStats const& ) = default; + TestCaseStats( TestCaseStats && ) = default; + TestCaseStats& operator = ( TestCaseStats const& ) = default; + TestCaseStats& operator = ( TestCaseStats && ) = default; + virtual ~TestCaseStats(); + + TestCaseInfo testInfo; + Totals totals; + std::string stdOut; + std::string stdErr; + bool aborting; + }; + + struct TestGroupStats { + TestGroupStats( GroupInfo const& _groupInfo, + Totals const& _totals, + bool _aborting ); + TestGroupStats( GroupInfo const& _groupInfo ); + + TestGroupStats( TestGroupStats const& ) = default; + TestGroupStats( TestGroupStats && ) = default; + TestGroupStats& operator = ( TestGroupStats const& ) = default; + TestGroupStats& operator = ( TestGroupStats && ) = default; + virtual ~TestGroupStats(); + + GroupInfo groupInfo; + Totals totals; + bool aborting; + }; + + struct TestRunStats { + TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ); + + TestRunStats( TestRunStats const& ) = default; + TestRunStats( TestRunStats && ) = default; + TestRunStats& operator = ( TestRunStats const& ) = default; + TestRunStats& operator = ( TestRunStats && ) = default; + virtual ~TestRunStats(); + + TestRunInfo runInfo; + Totals totals; + bool aborting; + }; + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + struct BenchmarkInfo { + std::string name; + double estimatedDuration; + int iterations; + int samples; + unsigned int resamples; + double clockResolution; + double clockCost; + }; + + template <class Duration> + struct BenchmarkStats { + BenchmarkInfo info; + + std::vector<Duration> samples; + Benchmark::Estimate<Duration> mean; + Benchmark::Estimate<Duration> standardDeviation; + Benchmark::OutlierClassification outliers; + double outlierVariance; + + template <typename Duration2> + operator BenchmarkStats<Duration2>() const { + std::vector<Duration2> samples2; + samples2.reserve(samples.size()); + std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); }); + return { + info, + std::move(samples2), + mean, + standardDeviation, + outliers, + outlierVariance, + }; + } + }; +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + + struct IStreamingReporter { + virtual ~IStreamingReporter() = default; + + // Implementing class must also provide the following static methods: + // static std::string getDescription(); + // static std::set<Verbosity> getSupportedVerbosities() + + virtual ReporterPreferences getPreferences() const = 0; + + virtual void noMatchingTestCases( std::string const& spec ) = 0; + + virtual void reportInvalidArguments(std::string const&) {} + + virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; + virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; + virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + virtual void benchmarkPreparing( std::string const& ) {} + virtual void benchmarkStarting( BenchmarkInfo const& ) {} + virtual void benchmarkEnded( BenchmarkStats<> const& ) {} + virtual void benchmarkFailed( std::string const& ) {} +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + + virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; + + virtual void sectionEnded( SectionStats const& sectionStats ) = 0; + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; + virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; + + virtual void skipTest( TestCaseInfo const& testInfo ) = 0; + + // Default empty implementation provided + virtual void fatalErrorEncountered( StringRef name ); + + virtual bool isMulti() const; + }; + using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>; + + struct IReporterFactory { + virtual ~IReporterFactory(); + virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0; + virtual std::string getDescription() const = 0; + }; + using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>; + + struct IReporterRegistry { + using FactoryMap = std::map<std::string, IReporterFactoryPtr>; + using Listeners = std::vector<IReporterFactoryPtr>; + + virtual ~IReporterRegistry(); + virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0; + virtual FactoryMap const& getFactories() const = 0; + virtual Listeners const& getListeners() const = 0; + }; + +} // end namespace Catch + +// end catch_interfaces_reporter.h +#include <algorithm> +#include <cstring> +#include <cfloat> +#include <cstdio> +#include <cassert> +#include <memory> +#include <ostream> + +namespace Catch { + void prepareExpandedExpression(AssertionResult& result); + + // Returns double formatted as %.3f (format expected on output) + std::string getFormattedDuration( double duration ); + + //! Should the reporter show + bool shouldShowDuration( IConfig const& config, double duration ); + + std::string serializeFilters( std::vector<std::string> const& container ); + + template<typename DerivedT> + struct StreamingReporterBase : IStreamingReporter { + + StreamingReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) ) + CATCH_ERROR( "Verbosity level not supported by this reporter" ); + } + + ReporterPreferences getPreferences() const override { + return m_reporterPrefs; + } + + static std::set<Verbosity> getSupportedVerbosities() { + return { Verbosity::Normal }; + } + + ~StreamingReporterBase() override = default; + + void noMatchingTestCases(std::string const&) override {} + + void reportInvalidArguments(std::string const&) override {} + + void testRunStarting(TestRunInfo const& _testRunInfo) override { + currentTestRunInfo = _testRunInfo; + } + + void testGroupStarting(GroupInfo const& _groupInfo) override { + currentGroupInfo = _groupInfo; + } + + void testCaseStarting(TestCaseInfo const& _testInfo) override { + currentTestCaseInfo = _testInfo; + } + void sectionStarting(SectionInfo const& _sectionInfo) override { + m_sectionStack.push_back(_sectionInfo); + } + + void sectionEnded(SectionStats const& /* _sectionStats */) override { + m_sectionStack.pop_back(); + } + void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override { + currentTestCaseInfo.reset(); + } + void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override { + currentGroupInfo.reset(); + } + void testRunEnded(TestRunStats const& /* _testRunStats */) override { + currentTestCaseInfo.reset(); + currentGroupInfo.reset(); + currentTestRunInfo.reset(); + } + + void skipTest(TestCaseInfo const&) override { + // Don't do anything with this by default. + // It can optionally be overridden in the derived class. + } + + IConfigPtr m_config; + std::ostream& stream; + + LazyStat<TestRunInfo> currentTestRunInfo; + LazyStat<GroupInfo> currentGroupInfo; + LazyStat<TestCaseInfo> currentTestCaseInfo; + + std::vector<SectionInfo> m_sectionStack; + ReporterPreferences m_reporterPrefs; + }; + + template<typename DerivedT> + struct CumulativeReporterBase : IStreamingReporter { + template<typename T, typename ChildNodeT> + struct Node { + explicit Node( T const& _value ) : value( _value ) {} + virtual ~Node() {} + + using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>; + T value; + ChildNodes children; + }; + struct SectionNode { + explicit SectionNode(SectionStats const& _stats) : stats(_stats) {} + virtual ~SectionNode() = default; + + bool operator == (SectionNode const& other) const { + return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; + } + bool operator == (std::shared_ptr<SectionNode> const& other) const { + return operator==(*other); + } + + SectionStats stats; + using ChildSections = std::vector<std::shared_ptr<SectionNode>>; + using Assertions = std::vector<AssertionStats>; + ChildSections childSections; + Assertions assertions; + std::string stdOut; + std::string stdErr; + }; + + struct BySectionInfo { + BySectionInfo( SectionInfo const& other ) : m_other( other ) {} + BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} + bool operator() (std::shared_ptr<SectionNode> const& node) const { + return ((node->stats.sectionInfo.name == m_other.name) && + (node->stats.sectionInfo.lineInfo == m_other.lineInfo)); + } + void operator=(BySectionInfo const&) = delete; + + private: + SectionInfo const& m_other; + }; + + using TestCaseNode = Node<TestCaseStats, SectionNode>; + using TestGroupNode = Node<TestGroupStats, TestCaseNode>; + using TestRunNode = Node<TestRunStats, TestGroupNode>; + + CumulativeReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) ) + CATCH_ERROR( "Verbosity level not supported by this reporter" ); + } + ~CumulativeReporterBase() override = default; + + ReporterPreferences getPreferences() const override { + return m_reporterPrefs; + } + + static std::set<Verbosity> getSupportedVerbosities() { + return { Verbosity::Normal }; + } + + void testRunStarting( TestRunInfo const& ) override {} + void testGroupStarting( GroupInfo const& ) override {} + + void testCaseStarting( TestCaseInfo const& ) override {} + + void sectionStarting( SectionInfo const& sectionInfo ) override { + SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); + std::shared_ptr<SectionNode> node; + if( m_sectionStack.empty() ) { + if( !m_rootSection ) + m_rootSection = std::make_shared<SectionNode>( incompleteStats ); + node = m_rootSection; + } + else { + SectionNode& parentNode = *m_sectionStack.back(); + auto it = + std::find_if( parentNode.childSections.begin(), + parentNode.childSections.end(), + BySectionInfo( sectionInfo ) ); + if( it == parentNode.childSections.end() ) { + node = std::make_shared<SectionNode>( incompleteStats ); + parentNode.childSections.push_back( node ); + } + else + node = *it; + } + m_sectionStack.push_back( node ); + m_deepestSection = std::move(node); + } + + void assertionStarting(AssertionInfo const&) override {} + + bool assertionEnded(AssertionStats const& assertionStats) override { + assert(!m_sectionStack.empty()); + // AssertionResult holds a pointer to a temporary DecomposedExpression, + // which getExpandedExpression() calls to build the expression string. + // Our section stack copy of the assertionResult will likely outlive the + // temporary, so it must be expanded or discarded now to avoid calling + // a destroyed object later. + prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) ); + SectionNode& sectionNode = *m_sectionStack.back(); + sectionNode.assertions.push_back(assertionStats); + return true; + } + void sectionEnded(SectionStats const& sectionStats) override { + assert(!m_sectionStack.empty()); + SectionNode& node = *m_sectionStack.back(); + node.stats = sectionStats; + m_sectionStack.pop_back(); + } + void testCaseEnded(TestCaseStats const& testCaseStats) override { + auto node = std::make_shared<TestCaseNode>(testCaseStats); + assert(m_sectionStack.size() == 0); + node->children.push_back(m_rootSection); + m_testCases.push_back(node); + m_rootSection.reset(); + + assert(m_deepestSection); + m_deepestSection->stdOut = testCaseStats.stdOut; + m_deepestSection->stdErr = testCaseStats.stdErr; + } + void testGroupEnded(TestGroupStats const& testGroupStats) override { + auto node = std::make_shared<TestGroupNode>(testGroupStats); + node->children.swap(m_testCases); + m_testGroups.push_back(node); + } + void testRunEnded(TestRunStats const& testRunStats) override { + auto node = std::make_shared<TestRunNode>(testRunStats); + node->children.swap(m_testGroups); + m_testRuns.push_back(node); + testRunEndedCumulative(); + } + virtual void testRunEndedCumulative() = 0; + + void skipTest(TestCaseInfo const&) override {} + + IConfigPtr m_config; + std::ostream& stream; + std::vector<AssertionStats> m_assertions; + std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections; + std::vector<std::shared_ptr<TestCaseNode>> m_testCases; + std::vector<std::shared_ptr<TestGroupNode>> m_testGroups; + + std::vector<std::shared_ptr<TestRunNode>> m_testRuns; + + std::shared_ptr<SectionNode> m_rootSection; + std::shared_ptr<SectionNode> m_deepestSection; + std::vector<std::shared_ptr<SectionNode>> m_sectionStack; + ReporterPreferences m_reporterPrefs; + }; + + template<char C> + char const* getLineOfChars() { + static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; + if( !*line ) { + std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); + line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; + } + return line; + } + + struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> { + TestEventListenerBase( ReporterConfig const& _config ); + + static std::set<Verbosity> getSupportedVerbosities(); + + void assertionStarting(AssertionInfo const&) override; + bool assertionEnded(AssertionStats const&) override; + }; + +} // end namespace Catch + +// end catch_reporter_bases.hpp +// start catch_console_colour.h + +namespace Catch { + + struct Colour { + enum Code { + None = 0, + + White, + Red, + Green, + Blue, + Cyan, + Yellow, + Grey, + + Bright = 0x10, + + BrightRed = Bright | Red, + BrightGreen = Bright | Green, + LightGrey = Bright | Grey, + BrightWhite = Bright | White, + BrightYellow = Bright | Yellow, + + // By intention + FileName = LightGrey, + Warning = BrightYellow, + ResultError = BrightRed, + ResultSuccess = BrightGreen, + ResultExpectedFailure = Warning, + + Error = BrightRed, + Success = Green, + + OriginalExpression = Cyan, + ReconstructedExpression = BrightYellow, + + SecondaryText = LightGrey, + Headers = White + }; + + // Use constructed object for RAII guard + Colour( Code _colourCode ); + Colour( Colour&& other ) noexcept; + Colour& operator=( Colour&& other ) noexcept; + ~Colour(); + + // Use static method for one-shot changes + static void use( Code _colourCode ); + + private: + bool m_moved = false; + }; + + std::ostream& operator << ( std::ostream& os, Colour const& ); + +} // end namespace Catch + +// end catch_console_colour.h +// start catch_reporter_registrars.hpp + + +namespace Catch { + + template<typename T> + class ReporterRegistrar { + + class ReporterFactory : public IReporterFactory { + + IStreamingReporterPtr create( ReporterConfig const& config ) const override { + return std::unique_ptr<T>( new T( config ) ); + } + + std::string getDescription() const override { + return T::getDescription(); + } + }; + + public: + + explicit ReporterRegistrar( std::string const& name ) { + getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() ); + } + }; + + template<typename T> + class ListenerRegistrar { + + class ListenerFactory : public IReporterFactory { + + IStreamingReporterPtr create( ReporterConfig const& config ) const override { + return std::unique_ptr<T>( new T( config ) ); + } + std::string getDescription() const override { + return std::string(); + } + }; + + public: + + ListenerRegistrar() { + getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() ); + } + }; +} + +#if !defined(CATCH_CONFIG_DISABLE) + +#define CATCH_REGISTER_REPORTER( name, reporterType ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + +#define CATCH_REGISTER_LISTENER( listenerType ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#else // CATCH_CONFIG_DISABLE + +#define CATCH_REGISTER_REPORTER(name, reporterType) +#define CATCH_REGISTER_LISTENER(listenerType) + +#endif // CATCH_CONFIG_DISABLE + +// end catch_reporter_registrars.hpp +// Allow users to base their work off existing reporters +// start catch_reporter_compact.h + +namespace Catch { + + struct CompactReporter : StreamingReporterBase<CompactReporter> { + + using StreamingReporterBase::StreamingReporterBase; + + ~CompactReporter() override; + + static std::string getDescription(); + + void noMatchingTestCases(std::string const& spec) override; + + void assertionStarting(AssertionInfo const&) override; + + bool assertionEnded(AssertionStats const& _assertionStats) override; + + void sectionEnded(SectionStats const& _sectionStats) override; + + void testRunEnded(TestRunStats const& _testRunStats) override; + + }; + +} // end namespace Catch + +// end catch_reporter_compact.h +// start catch_reporter_console.h + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch + // Note that 4062 (not all labels are handled + // and default is missing) is enabled +#endif + +namespace Catch { + // Fwd decls + struct SummaryColumn; + class TablePrinter; + + struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> { + std::unique_ptr<TablePrinter> m_tablePrinter; + + ConsoleReporter(ReporterConfig const& config); + ~ConsoleReporter() override; + static std::string getDescription(); + + void noMatchingTestCases(std::string const& spec) override; + + void reportInvalidArguments(std::string const&arg) override; + + void assertionStarting(AssertionInfo const&) override; + + bool assertionEnded(AssertionStats const& _assertionStats) override; + + void sectionStarting(SectionInfo const& _sectionInfo) override; + void sectionEnded(SectionStats const& _sectionStats) override; + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + void benchmarkPreparing(std::string const& name) override; + void benchmarkStarting(BenchmarkInfo const& info) override; + void benchmarkEnded(BenchmarkStats<> const& stats) override; + void benchmarkFailed(std::string const& error) override; +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + + void testCaseEnded(TestCaseStats const& _testCaseStats) override; + void testGroupEnded(TestGroupStats const& _testGroupStats) override; + void testRunEnded(TestRunStats const& _testRunStats) override; + void testRunStarting(TestRunInfo const& _testRunInfo) override; + private: + + void lazyPrint(); + + void lazyPrintWithoutClosingBenchmarkTable(); + void lazyPrintRunInfo(); + void lazyPrintGroupInfo(); + void printTestCaseAndSectionHeader(); + + void printClosedHeader(std::string const& _name); + void printOpenHeader(std::string const& _name); + + // if string has a : in first line will set indent to follow it on + // subsequent lines + void printHeaderString(std::string const& _string, std::size_t indent = 0); + + void printTotals(Totals const& totals); + void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row); + + void printTotalsDivider(Totals const& totals); + void printSummaryDivider(); + void printTestFilters(); + + private: + bool m_headerPrinted = false; + }; + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +// end catch_reporter_console.h +// start catch_reporter_junit.h + +// start catch_xmlwriter.h + +#include <vector> + +namespace Catch { + enum class XmlFormatting { + None = 0x00, + Indent = 0x01, + Newline = 0x02, + }; + + XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs); + XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs); + + class XmlEncode { + public: + enum ForWhat { ForTextNodes, ForAttributes }; + + XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ); + + void encodeTo( std::ostream& os ) const; + + friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ); + + private: + std::string m_str; + ForWhat m_forWhat; + }; + + class XmlWriter { + public: + + class ScopedElement { + public: + ScopedElement( XmlWriter* writer, XmlFormatting fmt ); + + ScopedElement( ScopedElement&& other ) noexcept; + ScopedElement& operator=( ScopedElement&& other ) noexcept; + + ~ScopedElement(); + + ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent ); + + template<typename T> + ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { + m_writer->writeAttribute( name, attribute ); + return *this; + } + + private: + mutable XmlWriter* m_writer = nullptr; + XmlFormatting m_fmt; + }; + + XmlWriter( std::ostream& os = Catch::cout() ); + ~XmlWriter(); + + XmlWriter( XmlWriter const& ) = delete; + XmlWriter& operator=( XmlWriter const& ) = delete; + + XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent); + + ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent); + + XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent); + + XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ); + + XmlWriter& writeAttribute( std::string const& name, bool attribute ); + + template<typename T> + XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { + ReusableStringStream rss; + rss << attribute; + return writeAttribute( name, rss.str() ); + } + + XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent); + + XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent); + + void writeStylesheetRef( std::string const& url ); + + XmlWriter& writeBlankLine(); + + void ensureTagClosed(); + + private: + + void applyFormatting(XmlFormatting fmt); + + void writeDeclaration(); + + void newlineIfNecessary(); + + bool m_tagIsOpen = false; + bool m_needsNewline = false; + std::vector<std::string> m_tags; + std::string m_indent; + std::ostream& m_os; + }; + +} + +// end catch_xmlwriter.h +namespace Catch { + + class JunitReporter : public CumulativeReporterBase<JunitReporter> { + public: + JunitReporter(ReporterConfig const& _config); + + ~JunitReporter() override; + + static std::string getDescription(); + + void noMatchingTestCases(std::string const& /*spec*/) override; + + void testRunStarting(TestRunInfo const& runInfo) override; + + void testGroupStarting(GroupInfo const& groupInfo) override; + + void testCaseStarting(TestCaseInfo const& testCaseInfo) override; + bool assertionEnded(AssertionStats const& assertionStats) override; + + void testCaseEnded(TestCaseStats const& testCaseStats) override; + + void testGroupEnded(TestGroupStats const& testGroupStats) override; + + void testRunEndedCumulative() override; + + void writeGroup(TestGroupNode const& groupNode, double suiteTime); + + void writeTestCase(TestCaseNode const& testCaseNode); + + void writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode, + bool testOkToFail ); + + void writeAssertions(SectionNode const& sectionNode); + void writeAssertion(AssertionStats const& stats); + + XmlWriter xml; + Timer suiteTimer; + std::string stdOutForSuite; + std::string stdErrForSuite; + unsigned int unexpectedExceptions = 0; + bool m_okToFail = false; + }; + +} // end namespace Catch + +// end catch_reporter_junit.h +// start catch_reporter_xml.h + +namespace Catch { + class XmlReporter : public StreamingReporterBase<XmlReporter> { + public: + XmlReporter(ReporterConfig const& _config); + + ~XmlReporter() override; + + static std::string getDescription(); + + virtual std::string getStylesheetRef() const; + + void writeSourceInfo(SourceLineInfo const& sourceInfo); + + public: // StreamingReporterBase + + void noMatchingTestCases(std::string const& s) override; + + void testRunStarting(TestRunInfo const& testInfo) override; + + void testGroupStarting(GroupInfo const& groupInfo) override; + + void testCaseStarting(TestCaseInfo const& testInfo) override; + + void sectionStarting(SectionInfo const& sectionInfo) override; + + void assertionStarting(AssertionInfo const&) override; + + bool assertionEnded(AssertionStats const& assertionStats) override; + + void sectionEnded(SectionStats const& sectionStats) override; + + void testCaseEnded(TestCaseStats const& testCaseStats) override; + + void testGroupEnded(TestGroupStats const& testGroupStats) override; + + void testRunEnded(TestRunStats const& testRunStats) override; + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + void benchmarkPreparing(std::string const& name) override; + void benchmarkStarting(BenchmarkInfo const&) override; + void benchmarkEnded(BenchmarkStats<> const&) override; + void benchmarkFailed(std::string const&) override; +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + + private: + Timer m_testCaseTimer; + XmlWriter m_xml; + int m_sectionDepth = 0; + }; + +} // end namespace Catch + +// end catch_reporter_xml.h + +// end catch_external_interfaces.h +#endif + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) +// start catch_benchmarking_all.hpp + +// A proxy header that includes all of the benchmarking headers to allow +// concise include of the benchmarking features. You should prefer the +// individual includes in standard use. + +// start catch_benchmark.hpp + + // Benchmark + +// start catch_chronometer.hpp + +// User-facing chronometer + + +// start catch_clock.hpp + +// Clocks + + +#include <chrono> +#include <ratio> + +namespace Catch { + namespace Benchmark { + template <typename Clock> + using ClockDuration = typename Clock::duration; + template <typename Clock> + using FloatDuration = std::chrono::duration<double, typename Clock::period>; + + template <typename Clock> + using TimePoint = typename Clock::time_point; + + using default_clock = std::chrono::steady_clock; + + template <typename Clock> + struct now { + TimePoint<Clock> operator()() const { + return Clock::now(); + } + }; + + using fp_seconds = std::chrono::duration<double, std::ratio<1>>; + } // namespace Benchmark +} // namespace Catch + +// end catch_clock.hpp +// start catch_optimizer.hpp + + // Hinting the optimizer + + +#if defined(_MSC_VER) +# include <atomic> // atomic_thread_fence +#endif + +namespace Catch { + namespace Benchmark { +#if defined(__GNUC__) || defined(__clang__) + template <typename T> + inline void keep_memory(T* p) { + asm volatile("" : : "g"(p) : "memory"); + } + inline void keep_memory() { + asm volatile("" : : : "memory"); + } + + namespace Detail { + inline void optimizer_barrier() { keep_memory(); } + } // namespace Detail +#elif defined(_MSC_VER) + +#pragma optimize("", off) + template <typename T> + inline void keep_memory(T* p) { + // thanks @milleniumbug + *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p); + } + // TODO equivalent keep_memory() +#pragma optimize("", on) + + namespace Detail { + inline void optimizer_barrier() { + std::atomic_thread_fence(std::memory_order_seq_cst); + } + } // namespace Detail + +#endif + + template <typename T> + inline void deoptimize_value(T&& x) { + keep_memory(&x); + } + + template <typename Fn, typename... Args> + inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type { + deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...))); + } + + template <typename Fn, typename... Args> + inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type { + std::forward<Fn>(fn) (std::forward<Args...>(args...)); + } + } // namespace Benchmark +} // namespace Catch + +// end catch_optimizer.hpp +// start catch_complete_invoke.hpp + +// Invoke with a special case for void + + +#include <type_traits> +#include <utility> + +namespace Catch { + namespace Benchmark { + namespace Detail { + template <typename T> + struct CompleteType { using type = T; }; + template <> + struct CompleteType<void> { struct type {}; }; + + template <typename T> + using CompleteType_t = typename CompleteType<T>::type; + + template <typename Result> + struct CompleteInvoker { + template <typename Fun, typename... Args> + static Result invoke(Fun&& fun, Args&&... args) { + return std::forward<Fun>(fun)(std::forward<Args>(args)...); + } + }; + template <> + struct CompleteInvoker<void> { + template <typename Fun, typename... Args> + static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) { + std::forward<Fun>(fun)(std::forward<Args>(args)...); + return {}; + } + }; + + // invoke and not return void :( + template <typename Fun, typename... Args> + CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) { + return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...); + } + + const std::string benchmarkErrorMsg = "a benchmark failed to run successfully"; + } // namespace Detail + + template <typename Fun> + Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) { + CATCH_TRY{ + return Detail::complete_invoke(std::forward<Fun>(fun)); + } CATCH_CATCH_ALL{ + getResultCapture().benchmarkFailed(translateActiveException()); + CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg); + } + } + } // namespace Benchmark +} // namespace Catch + +// end catch_complete_invoke.hpp +namespace Catch { + namespace Benchmark { + namespace Detail { + struct ChronometerConcept { + virtual void start() = 0; + virtual void finish() = 0; + virtual ~ChronometerConcept() = default; + }; + template <typename Clock> + struct ChronometerModel final : public ChronometerConcept { + void start() override { started = Clock::now(); } + void finish() override { finished = Clock::now(); } + + ClockDuration<Clock> elapsed() const { return finished - started; } + + TimePoint<Clock> started; + TimePoint<Clock> finished; + }; + } // namespace Detail + + struct Chronometer { + public: + template <typename Fun> + void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); } + + int runs() const { return k; } + + Chronometer(Detail::ChronometerConcept& meter, int k) + : impl(&meter) + , k(k) {} + + private: + template <typename Fun> + void measure(Fun&& fun, std::false_type) { + measure([&fun](int) { return fun(); }, std::true_type()); + } + + template <typename Fun> + void measure(Fun&& fun, std::true_type) { + Detail::optimizer_barrier(); + impl->start(); + for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i); + impl->finish(); + Detail::optimizer_barrier(); + } + + Detail::ChronometerConcept* impl; + int k; + }; + } // namespace Benchmark +} // namespace Catch + +// end catch_chronometer.hpp +// start catch_environment.hpp + +// Environment information + + +namespace Catch { + namespace Benchmark { + template <typename Duration> + struct EnvironmentEstimate { + Duration mean; + OutlierClassification outliers; + + template <typename Duration2> + operator EnvironmentEstimate<Duration2>() const { + return { mean, outliers }; + } + }; + template <typename Clock> + struct Environment { + using clock_type = Clock; + EnvironmentEstimate<FloatDuration<Clock>> clock_resolution; + EnvironmentEstimate<FloatDuration<Clock>> clock_cost; + }; + } // namespace Benchmark +} // namespace Catch + +// end catch_environment.hpp +// start catch_execution_plan.hpp + + // Execution plan + + +// start catch_benchmark_function.hpp + + // Dumb std::function implementation for consistent call overhead + + +#include <cassert> +#include <type_traits> +#include <utility> +#include <memory> + +namespace Catch { + namespace Benchmark { + namespace Detail { + template <typename T> + using Decay = typename std::decay<T>::type; + template <typename T, typename U> + struct is_related + : std::is_same<Decay<T>, Decay<U>> {}; + + /// We need to reinvent std::function because every piece of code that might add overhead + /// in a measurement context needs to have consistent performance characteristics so that we + /// can account for it in the measurement. + /// Implementations of std::function with optimizations that aren't always applicable, like + /// small buffer optimizations, are not uncommon. + /// This is effectively an implementation of std::function without any such optimizations; + /// it may be slow, but it is consistently slow. + struct BenchmarkFunction { + private: + struct callable { + virtual void call(Chronometer meter) const = 0; + virtual callable* clone() const = 0; + virtual ~callable() = default; + }; + template <typename Fun> + struct model : public callable { + model(Fun&& fun) : fun(std::move(fun)) {} + model(Fun const& fun) : fun(fun) {} + + model<Fun>* clone() const override { return new model<Fun>(*this); } + + void call(Chronometer meter) const override { + call(meter, is_callable<Fun(Chronometer)>()); + } + void call(Chronometer meter, std::true_type) const { + fun(meter); + } + void call(Chronometer meter, std::false_type) const { + meter.measure(fun); + } + + Fun fun; + }; + + struct do_nothing { void operator()() const {} }; + + template <typename T> + BenchmarkFunction(model<T>* c) : f(c) {} + + public: + BenchmarkFunction() + : f(new model<do_nothing>{ {} }) {} + + template <typename Fun, + typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0> + BenchmarkFunction(Fun&& fun) + : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {} + + BenchmarkFunction(BenchmarkFunction&& that) + : f(std::move(that.f)) {} + + BenchmarkFunction(BenchmarkFunction const& that) + : f(that.f->clone()) {} + + BenchmarkFunction& operator=(BenchmarkFunction&& that) { + f = std::move(that.f); + return *this; + } + + BenchmarkFunction& operator=(BenchmarkFunction const& that) { + f.reset(that.f->clone()); + return *this; + } + + void operator()(Chronometer meter) const { f->call(meter); } + + private: + std::unique_ptr<callable> f; + }; + } // namespace Detail + } // namespace Benchmark +} // namespace Catch + +// end catch_benchmark_function.hpp +// start catch_repeat.hpp + +// repeat algorithm + + +#include <type_traits> +#include <utility> + +namespace Catch { + namespace Benchmark { + namespace Detail { + template <typename Fun> + struct repeater { + void operator()(int k) const { + for (int i = 0; i < k; ++i) { + fun(); + } + } + Fun fun; + }; + template <typename Fun> + repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) { + return { std::forward<Fun>(fun) }; + } + } // namespace Detail + } // namespace Benchmark +} // namespace Catch + +// end catch_repeat.hpp +// start catch_run_for_at_least.hpp + +// Run a function for a minimum amount of time + + +// start catch_measure.hpp + +// Measure + + +// start catch_timing.hpp + +// Timing + + +#include <tuple> +#include <type_traits> + +namespace Catch { + namespace Benchmark { + template <typename Duration, typename Result> + struct Timing { + Duration elapsed; + Result result; + int iterations; + }; + template <typename Clock, typename Func, typename... Args> + using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>; + } // namespace Benchmark +} // namespace Catch + +// end catch_timing.hpp +#include <utility> + +namespace Catch { + namespace Benchmark { + namespace Detail { + template <typename Clock, typename Fun, typename... Args> + TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) { + auto start = Clock::now(); + auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...); + auto end = Clock::now(); + auto delta = end - start; + return { delta, std::forward<decltype(r)>(r), 1 }; + } + } // namespace Detail + } // namespace Benchmark +} // namespace Catch + +// end catch_measure.hpp +#include <utility> +#include <type_traits> + +namespace Catch { + namespace Benchmark { + namespace Detail { + template <typename Clock, typename Fun> + TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) { + return Detail::measure<Clock>(fun, iters); + } + template <typename Clock, typename Fun> + TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) { + Detail::ChronometerModel<Clock> meter; + auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters)); + + return { meter.elapsed(), std::move(result), iters }; + } + + template <typename Clock, typename Fun> + using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type; + + struct optimized_away_error : std::exception { + const char* what() const noexcept override { + return "could not measure benchmark, maybe it was optimized away"; + } + }; + + template <typename Clock, typename Fun> + TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) { + auto iters = seed; + while (iters < (1 << 30)) { + auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>()); + + if (Timing.elapsed >= how_long) { + return { Timing.elapsed, std::move(Timing.result), iters }; + } + iters *= 2; + } + Catch::throw_exception(optimized_away_error{}); + } + } // namespace Detail + } // namespace Benchmark +} // namespace Catch + +// end catch_run_for_at_least.hpp +#include <algorithm> +#include <iterator> + +namespace Catch { + namespace Benchmark { + template <typename Duration> + struct ExecutionPlan { + int iterations_per_sample; + Duration estimated_duration; + Detail::BenchmarkFunction benchmark; + Duration warmup_time; + int warmup_iterations; + + template <typename Duration2> + operator ExecutionPlan<Duration2>() const { + return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations }; + } + + template <typename Clock> + std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const { + // warmup a bit + Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{})); + + std::vector<FloatDuration<Clock>> times; + times.reserve(cfg.benchmarkSamples()); + std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] { + Detail::ChronometerModel<Clock> model; + this->benchmark(Chronometer(model, iterations_per_sample)); + auto sample_time = model.elapsed() - env.clock_cost.mean; + if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero(); + return sample_time / iterations_per_sample; + }); + return times; + } + }; + } // namespace Benchmark +} // namespace Catch + +// end catch_execution_plan.hpp +// start catch_estimate_clock.hpp + + // Environment measurement + + +// start catch_stats.hpp + +// Statistical analysis tools + + +#include <algorithm> +#include <functional> +#include <vector> +#include <iterator> +#include <numeric> +#include <tuple> +#include <cmath> +#include <utility> +#include <cstddef> +#include <random> + +namespace Catch { + namespace Benchmark { + namespace Detail { + using sample = std::vector<double>; + + double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last); + + template <typename Iterator> + OutlierClassification classify_outliers(Iterator first, Iterator last) { + std::vector<double> copy(first, last); + + auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end()); + auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end()); + auto iqr = q3 - q1; + auto los = q1 - (iqr * 3.); + auto lom = q1 - (iqr * 1.5); + auto him = q3 + (iqr * 1.5); + auto his = q3 + (iqr * 3.); + + OutlierClassification o; + for (; first != last; ++first) { + auto&& t = *first; + if (t < los) ++o.low_severe; + else if (t < lom) ++o.low_mild; + else if (t > his) ++o.high_severe; + else if (t > him) ++o.high_mild; + ++o.samples_seen; + } + return o; + } + + template <typename Iterator> + double mean(Iterator first, Iterator last) { + auto count = last - first; + double sum = std::accumulate(first, last, 0.); + return sum / count; + } + + template <typename URng, typename Iterator, typename Estimator> + sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) { + auto n = last - first; + std::uniform_int_distribution<decltype(n)> dist(0, n - 1); + + sample out; + out.reserve(resamples); + std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] { + std::vector<double> resampled; + resampled.reserve(n); + std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; }); + return estimator(resampled.begin(), resampled.end()); + }); + std::sort(out.begin(), out.end()); + return out; + } + + template <typename Estimator, typename Iterator> + sample jackknife(Estimator&& estimator, Iterator first, Iterator last) { + auto n = last - first; + auto second = std::next(first); + sample results; + results.reserve(n); + + for (auto it = first; it != last; ++it) { + std::iter_swap(it, first); + results.push_back(estimator(second, last)); + } + + return results; + } + + inline double normal_cdf(double x) { + return std::erfc(-x / std::sqrt(2.0)) / 2.0; + } + + double erfc_inv(double x); + + double normal_quantile(double p); + + template <typename Iterator, typename Estimator> + Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) { + auto n_samples = last - first; + + double point = estimator(first, last); + // Degenerate case with a single sample + if (n_samples == 1) return { point, point, point, confidence_level }; + + sample jack = jackknife(estimator, first, last); + double jack_mean = mean(jack.begin(), jack.end()); + double sum_squares, sum_cubes; + std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> { + auto d = jack_mean - x; + auto d2 = d * d; + auto d3 = d2 * d; + return { sqcb.first + d2, sqcb.second + d3 }; + }); + + double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5)); + int n = static_cast<int>(resample.size()); + double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n; + // degenerate case with uniform samples + if (prob_n == 0) return { point, point, point, confidence_level }; + + double bias = normal_quantile(prob_n); + double z1 = normal_quantile((1. - confidence_level) / 2.); + + auto cumn = [n](double x) -> int { + return std::lround(normal_cdf(x) * n); }; + auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); }; + double b1 = bias + z1; + double b2 = bias - z1; + double a1 = a(b1); + double a2 = a(b2); + auto lo = (std::max)(cumn(a1), 0); + auto hi = (std::min)(cumn(a2), n - 1); + + return { point, resample[lo], resample[hi], confidence_level }; + } + + double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n); + + struct bootstrap_analysis { + Estimate<double> mean; + Estimate<double> standard_deviation; + double outlier_variance; + }; + + bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last); + } // namespace Detail + } // namespace Benchmark +} // namespace Catch + +// end catch_stats.hpp +#include <algorithm> +#include <iterator> +#include <tuple> +#include <vector> +#include <cmath> + +namespace Catch { + namespace Benchmark { + namespace Detail { + template <typename Clock> + std::vector<double> resolution(int k) { + std::vector<TimePoint<Clock>> times; + times.reserve(k + 1); + std::generate_n(std::back_inserter(times), k + 1, now<Clock>{}); + + std::vector<double> deltas; + deltas.reserve(k); + std::transform(std::next(times.begin()), times.end(), times.begin(), + std::back_inserter(deltas), + [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); }); + + return deltas; + } + + const auto warmup_iterations = 10000; + const auto warmup_time = std::chrono::milliseconds(100); + const auto minimum_ticks = 1000; + const auto warmup_seed = 10000; + const auto clock_resolution_estimation_time = std::chrono::milliseconds(500); + const auto clock_cost_estimation_time_limit = std::chrono::seconds(1); + const auto clock_cost_estimation_tick_limit = 100000; + const auto clock_cost_estimation_time = std::chrono::milliseconds(10); + const auto clock_cost_estimation_iterations = 10000; + + template <typename Clock> + int warmup() { + return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>) + .iterations; + } + template <typename Clock> + EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) { + auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>) + .result; + return { + FloatDuration<Clock>(mean(r.begin(), r.end())), + classify_outliers(r.begin(), r.end()), + }; + } + template <typename Clock> + EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) { + auto time_limit = (std::min)( + resolution * clock_cost_estimation_tick_limit, + FloatDuration<Clock>(clock_cost_estimation_time_limit)); + auto time_clock = [](int k) { + return Detail::measure<Clock>([k] { + for (int i = 0; i < k; ++i) { + volatile auto ignored = Clock::now(); + (void)ignored; + } + }).elapsed; + }; + time_clock(1); + int iters = clock_cost_estimation_iterations; + auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock); + std::vector<double> times; + int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed)); + times.reserve(nsamples); + std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] { + return static_cast<double>((time_clock(r.iterations) / r.iterations).count()); + }); + return { + FloatDuration<Clock>(mean(times.begin(), times.end())), + classify_outliers(times.begin(), times.end()), + }; + } + + template <typename Clock> + Environment<FloatDuration<Clock>> measure_environment() { + static Environment<FloatDuration<Clock>>* env = nullptr; + if (env) { + return *env; + } + + auto iters = Detail::warmup<Clock>(); + auto resolution = Detail::estimate_clock_resolution<Clock>(iters); + auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean); + + env = new Environment<FloatDuration<Clock>>{ resolution, cost }; + return *env; + } + } // namespace Detail + } // namespace Benchmark +} // namespace Catch + +// end catch_estimate_clock.hpp +// start catch_analyse.hpp + + // Run and analyse one benchmark + + +// start catch_sample_analysis.hpp + +// Benchmark results + + +#include <algorithm> +#include <vector> +#include <string> +#include <iterator> + +namespace Catch { + namespace Benchmark { + template <typename Duration> + struct SampleAnalysis { + std::vector<Duration> samples; + Estimate<Duration> mean; + Estimate<Duration> standard_deviation; + OutlierClassification outliers; + double outlier_variance; + + template <typename Duration2> + operator SampleAnalysis<Duration2>() const { + std::vector<Duration2> samples2; + samples2.reserve(samples.size()); + std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); }); + return { + std::move(samples2), + mean, + standard_deviation, + outliers, + outlier_variance, + }; + } + }; + } // namespace Benchmark +} // namespace Catch + +// end catch_sample_analysis.hpp +#include <algorithm> +#include <iterator> +#include <vector> + +namespace Catch { + namespace Benchmark { + namespace Detail { + template <typename Duration, typename Iterator> + SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) { + if (!cfg.benchmarkNoAnalysis()) { + std::vector<double> samples; + samples.reserve(last - first); + std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); }); + + auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end()); + auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end()); + + auto wrap_estimate = [](Estimate<double> e) { + return Estimate<Duration> { + Duration(e.point), + Duration(e.lower_bound), + Duration(e.upper_bound), + e.confidence_interval, + }; + }; + std::vector<Duration> samples2; + samples2.reserve(samples.size()); + std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); }); + return { + std::move(samples2), + wrap_estimate(analysis.mean), + wrap_estimate(analysis.standard_deviation), + outliers, + analysis.outlier_variance, + }; + } else { + std::vector<Duration> samples; + samples.reserve(last - first); + + Duration mean = Duration(0); + int i = 0; + for (auto it = first; it < last; ++it, ++i) { + samples.push_back(Duration(*it)); + mean += Duration(*it); + } + mean /= i; + + return { + std::move(samples), + Estimate<Duration>{mean, mean, mean, 0.0}, + Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0}, + OutlierClassification{}, + 0.0 + }; + } + } + } // namespace Detail + } // namespace Benchmark +} // namespace Catch + +// end catch_analyse.hpp +#include <algorithm> +#include <functional> +#include <string> +#include <vector> +#include <cmath> + +namespace Catch { + namespace Benchmark { + struct Benchmark { + Benchmark(std::string &&name) + : name(std::move(name)) {} + + template <class FUN> + Benchmark(std::string &&name, FUN &&func) + : fun(std::move(func)), name(std::move(name)) {} + + template <typename Clock> + ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const { + auto min_time = env.clock_resolution.mean * Detail::minimum_ticks; + auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime())); + auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun); + int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed)); + return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations }; + } + + template <typename Clock = default_clock> + void run() { + IConfigPtr cfg = getCurrentContext().getConfig(); + + auto env = Detail::measure_environment<Clock>(); + + getResultCapture().benchmarkPreparing(name); + CATCH_TRY{ + auto plan = user_code([&] { + return prepare<Clock>(*cfg, env); + }); + + BenchmarkInfo info { + name, + plan.estimated_duration.count(), + plan.iterations_per_sample, + cfg->benchmarkSamples(), + cfg->benchmarkResamples(), + env.clock_resolution.mean.count(), + env.clock_cost.mean.count() + }; + + getResultCapture().benchmarkStarting(info); + + auto samples = user_code([&] { + return plan.template run<Clock>(*cfg, env); + }); + + auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end()); + BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance }; + getResultCapture().benchmarkEnded(stats); + + } CATCH_CATCH_ALL{ + if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow. + std::rethrow_exception(std::current_exception()); + } + } + + // sets lambda to be used in fun *and* executes benchmark! + template <typename Fun, + typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0> + Benchmark & operator=(Fun func) { + fun = Detail::BenchmarkFunction(func); + run(); + return *this; + } + + explicit operator bool() { + return true; + } + + private: + Detail::BenchmarkFunction fun; + std::string name; + }; + } +} // namespace Catch + +#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1 +#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2 + +#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\ + if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \ + BenchmarkName = [&](int benchmarkIndex) + +#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\ + if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \ + BenchmarkName = [&] + +// end catch_benchmark.hpp +// start catch_constructor.hpp + +// Constructor and destructor helpers + + +#include <type_traits> + +namespace Catch { + namespace Benchmark { + namespace Detail { + template <typename T, bool Destruct> + struct ObjectStorage + { + using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type; + + ObjectStorage() : data() {} + + ObjectStorage(const ObjectStorage& other) + { + new(&data) T(other.stored_object()); + } + + ObjectStorage(ObjectStorage&& other) + { + new(&data) T(std::move(other.stored_object())); + } + + ~ObjectStorage() { destruct_on_exit<T>(); } + + template <typename... Args> + void construct(Args&&... args) + { + new (&data) T(std::forward<Args>(args)...); + } + + template <bool AllowManualDestruction = !Destruct> + typename std::enable_if<AllowManualDestruction>::type destruct() + { + stored_object().~T(); + } + + private: + // If this is a constructor benchmark, destruct the underlying object + template <typename U> + void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); } + // Otherwise, don't + template <typename U> + void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { } + + T& stored_object() { + return *static_cast<T*>(static_cast<void*>(&data)); + } + + T const& stored_object() const { + return *static_cast<T*>(static_cast<void*>(&data)); + } + + TStorage data; + }; + } + + template <typename T> + using storage_for = Detail::ObjectStorage<T, true>; + + template <typename T> + using destructable_object = Detail::ObjectStorage<T, false>; + } +} + +// end catch_constructor.hpp +// end catch_benchmarking_all.hpp +#endif + +#endif // ! CATCH_CONFIG_IMPL_ONLY + +#ifdef CATCH_IMPL +// start catch_impl.hpp + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#endif + +// Keep these here for external reporters +// start catch_test_case_tracker.h + +#include <string> +#include <vector> +#include <memory> + +namespace Catch { +namespace TestCaseTracking { + + struct NameAndLocation { + std::string name; + SourceLineInfo location; + + NameAndLocation( std::string const& _name, SourceLineInfo const& _location ); + friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) { + return lhs.name == rhs.name + && lhs.location == rhs.location; + } + }; + + class ITracker; + + using ITrackerPtr = std::shared_ptr<ITracker>; + + class ITracker { + NameAndLocation m_nameAndLocation; + + public: + ITracker(NameAndLocation const& nameAndLoc) : + m_nameAndLocation(nameAndLoc) + {} + + // static queries + NameAndLocation const& nameAndLocation() const { + return m_nameAndLocation; + } + + virtual ~ITracker(); + + // dynamic queries + virtual bool isComplete() const = 0; // Successfully completed or failed + virtual bool isSuccessfullyCompleted() const = 0; + virtual bool isOpen() const = 0; // Started but not complete + virtual bool hasChildren() const = 0; + virtual bool hasStarted() const = 0; + + virtual ITracker& parent() = 0; + + // actions + virtual void close() = 0; // Successfully complete + virtual void fail() = 0; + virtual void markAsNeedingAnotherRun() = 0; + + virtual void addChild( ITrackerPtr const& child ) = 0; + virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0; + virtual void openChild() = 0; + + // Debug/ checking + virtual bool isSectionTracker() const = 0; + virtual bool isGeneratorTracker() const = 0; + }; + + class TrackerContext { + + enum RunState { + NotStarted, + Executing, + CompletedCycle + }; + + ITrackerPtr m_rootTracker; + ITracker* m_currentTracker = nullptr; + RunState m_runState = NotStarted; + + public: + + ITracker& startRun(); + void endRun(); + + void startCycle(); + void completeCycle(); + + bool completedCycle() const; + ITracker& currentTracker(); + void setCurrentTracker( ITracker* tracker ); + }; + + class TrackerBase : public ITracker { + protected: + enum CycleState { + NotStarted, + Executing, + ExecutingChildren, + NeedsAnotherRun, + CompletedSuccessfully, + Failed + }; + + using Children = std::vector<ITrackerPtr>; + TrackerContext& m_ctx; + ITracker* m_parent; + Children m_children; + CycleState m_runState = NotStarted; + + public: + TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); + + bool isComplete() const override; + bool isSuccessfullyCompleted() const override; + bool isOpen() const override; + bool hasChildren() const override; + bool hasStarted() const override { + return m_runState != NotStarted; + } + + void addChild( ITrackerPtr const& child ) override; + + ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override; + ITracker& parent() override; + + void openChild() override; + + bool isSectionTracker() const override; + bool isGeneratorTracker() const override; + + void open(); + + void close() override; + void fail() override; + void markAsNeedingAnotherRun() override; + + private: + void moveToParent(); + void moveToThis(); + }; + + class SectionTracker : public TrackerBase { + std::vector<std::string> m_filters; + std::string m_trimmed_name; + public: + SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); + + bool isSectionTracker() const override; + + bool isComplete() const override; + + static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ); + + void tryOpen(); + + void addInitialFilters( std::vector<std::string> const& filters ); + void addNextFilters( std::vector<std::string> const& filters ); + //! Returns filters active in this tracker + std::vector<std::string> const& getFilters() const; + //! Returns whitespace-trimmed name of the tracked section + std::string const& trimmedName() const; + }; + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; + +} // namespace Catch + +// end catch_test_case_tracker.h + +// start catch_leak_detector.h + +namespace Catch { + + struct LeakDetector { + LeakDetector(); + ~LeakDetector(); + }; + +} +// end catch_leak_detector.h +// Cpp files will be included in the single-header file here +// start catch_stats.cpp + +// Statistical analysis tools + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + +#include <cassert> +#include <random> + +#if defined(CATCH_CONFIG_USE_ASYNC) +#include <future> +#endif + +namespace { + double erf_inv(double x) { + // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2 + double w, p; + + w = -log((1.0 - x) * (1.0 + x)); + + if (w < 6.250000) { + w = w - 3.125000; + p = -3.6444120640178196996e-21; + p = -1.685059138182016589e-19 + p * w; + p = 1.2858480715256400167e-18 + p * w; + p = 1.115787767802518096e-17 + p * w; + p = -1.333171662854620906e-16 + p * w; + p = 2.0972767875968561637e-17 + p * w; + p = 6.6376381343583238325e-15 + p * w; + p = -4.0545662729752068639e-14 + p * w; + p = -8.1519341976054721522e-14 + p * w; + p = 2.6335093153082322977e-12 + p * w; + p = -1.2975133253453532498e-11 + p * w; + p = -5.4154120542946279317e-11 + p * w; + p = 1.051212273321532285e-09 + p * w; + p = -4.1126339803469836976e-09 + p * w; + p = -2.9070369957882005086e-08 + p * w; + p = 4.2347877827932403518e-07 + p * w; + p = -1.3654692000834678645e-06 + p * w; + p = -1.3882523362786468719e-05 + p * w; + p = 0.0001867342080340571352 + p * w; + p = -0.00074070253416626697512 + p * w; + p = -0.0060336708714301490533 + p * w; + p = 0.24015818242558961693 + p * w; + p = 1.6536545626831027356 + p * w; + } else if (w < 16.000000) { + w = sqrt(w) - 3.250000; + p = 2.2137376921775787049e-09; + p = 9.0756561938885390979e-08 + p * w; + p = -2.7517406297064545428e-07 + p * w; + p = 1.8239629214389227755e-08 + p * w; + p = 1.5027403968909827627e-06 + p * w; + p = -4.013867526981545969e-06 + p * w; + p = 2.9234449089955446044e-06 + p * w; + p = 1.2475304481671778723e-05 + p * w; + p = -4.7318229009055733981e-05 + p * w; + p = 6.8284851459573175448e-05 + p * w; + p = 2.4031110387097893999e-05 + p * w; + p = -0.0003550375203628474796 + p * w; + p = 0.00095328937973738049703 + p * w; + p = -0.0016882755560235047313 + p * w; + p = 0.0024914420961078508066 + p * w; + p = -0.0037512085075692412107 + p * w; + p = 0.005370914553590063617 + p * w; + p = 1.0052589676941592334 + p * w; + p = 3.0838856104922207635 + p * w; + } else { + w = sqrt(w) - 5.000000; + p = -2.7109920616438573243e-11; + p = -2.5556418169965252055e-10 + p * w; + p = 1.5076572693500548083e-09 + p * w; + p = -3.7894654401267369937e-09 + p * w; + p = 7.6157012080783393804e-09 + p * w; + p = -1.4960026627149240478e-08 + p * w; + p = 2.9147953450901080826e-08 + p * w; + p = -6.7711997758452339498e-08 + p * w; + p = 2.2900482228026654717e-07 + p * w; + p = -9.9298272942317002539e-07 + p * w; + p = 4.5260625972231537039e-06 + p * w; + p = -1.9681778105531670567e-05 + p * w; + p = 7.5995277030017761139e-05 + p * w; + p = -0.00021503011930044477347 + p * w; + p = -0.00013871931833623122026 + p * w; + p = 1.0103004648645343977 + p * w; + p = 4.8499064014085844221 + p * w; + } + return p * x; + } + + double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) { + auto m = Catch::Benchmark::Detail::mean(first, last); + double variance = std::accumulate(first, last, 0., [m](double a, double b) { + double diff = b - m; + return a + diff * diff; + }) / (last - first); + return std::sqrt(variance); + } + +} + +namespace Catch { + namespace Benchmark { + namespace Detail { + + double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) { + auto count = last - first; + double idx = (count - 1) * k / static_cast<double>(q); + int j = static_cast<int>(idx); + double g = idx - j; + std::nth_element(first, first + j, last); + auto xj = first[j]; + if (g == 0) return xj; + + auto xj1 = *std::min_element(first + (j + 1), last); + return xj + g * (xj1 - xj); + } + + double erfc_inv(double x) { + return erf_inv(1.0 - x); + } + + double normal_quantile(double p) { + static const double ROOT_TWO = std::sqrt(2.0); + + double result = 0.0; + assert(p >= 0 && p <= 1); + if (p < 0 || p > 1) { + return result; + } + + result = -erfc_inv(2.0 * p); + // result *= normal distribution standard deviation (1.0) * sqrt(2) + result *= /*sd * */ ROOT_TWO; + // result += normal disttribution mean (0) + return result; + } + + double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) { + double sb = stddev.point; + double mn = mean.point / n; + double mg_min = mn / 2.; + double sg = (std::min)(mg_min / 4., sb / std::sqrt(n)); + double sg2 = sg * sg; + double sb2 = sb * sb; + + auto c_max = [n, mn, sb2, sg2](double x) -> double { + double k = mn - x; + double d = k * k; + double nd = n * d; + double k0 = -n * nd; + double k1 = sb2 - n * sg2 + nd; + double det = k1 * k1 - 4 * sg2 * k0; + return (int)(-2. * k0 / (k1 + std::sqrt(det))); + }; + + auto var_out = [n, sb2, sg2](double c) { + double nc = n - c; + return (nc / n) * (sb2 - nc * sg2); + }; + + return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2; + } + + bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) { + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS + static std::random_device entropy; + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + + auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++ + + auto mean = &Detail::mean<std::vector<double>::iterator>; + auto stddev = &standard_deviation; + +#if defined(CATCH_CONFIG_USE_ASYNC) + auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) { + auto seed = entropy(); + return std::async(std::launch::async, [=] { + std::mt19937 rng(seed); + auto resampled = resample(rng, n_resamples, first, last, f); + return bootstrap(confidence_level, first, last, resampled, f); + }); + }; + + auto mean_future = Estimate(mean); + auto stddev_future = Estimate(stddev); + + auto mean_estimate = mean_future.get(); + auto stddev_estimate = stddev_future.get(); +#else + auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) { + auto seed = entropy(); + std::mt19937 rng(seed); + auto resampled = resample(rng, n_resamples, first, last, f); + return bootstrap(confidence_level, first, last, resampled, f); + }; + + auto mean_estimate = Estimate(mean); + auto stddev_estimate = Estimate(stddev); +#endif // CATCH_USE_ASYNC + + double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n); + + return { mean_estimate, stddev_estimate, outlier_variance }; + } + } // namespace Detail + } // namespace Benchmark +} // namespace Catch + +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING +// end catch_stats.cpp +// start catch_approx.cpp + +#include <cmath> +#include <limits> + +namespace { + +// Performs equivalent check of std::fabs(lhs - rhs) <= margin +// But without the subtraction to allow for INFINITY in comparison +bool marginComparison(double lhs, double rhs, double margin) { + return (lhs + margin >= rhs) && (rhs + margin >= lhs); +} + +} + +namespace Catch { +namespace Detail { + + Approx::Approx ( double value ) + : m_epsilon( std::numeric_limits<float>::epsilon()*100 ), + m_margin( 0.0 ), + m_scale( 0.0 ), + m_value( value ) + {} + + Approx Approx::custom() { + return Approx( 0 ); + } + + Approx Approx::operator-() const { + auto temp(*this); + temp.m_value = -temp.m_value; + return temp; + } + + std::string Approx::toString() const { + ReusableStringStream rss; + rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )"; + return rss.str(); + } + + bool Approx::equalityComparisonImpl(const double other) const { + // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value + // Thanks to Richard Harris for his help refining the scaled margin value + return marginComparison(m_value, other, m_margin) + || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value))); + } + + void Approx::setMargin(double newMargin) { + CATCH_ENFORCE(newMargin >= 0, + "Invalid Approx::margin: " << newMargin << '.' + << " Approx::Margin has to be non-negative."); + m_margin = newMargin; + } + + void Approx::setEpsilon(double newEpsilon) { + CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0, + "Invalid Approx::epsilon: " << newEpsilon << '.' + << " Approx::epsilon has to be in [0, 1]"); + m_epsilon = newEpsilon; + } + +} // end namespace Detail + +namespace literals { + Detail::Approx operator "" _a(long double val) { + return Detail::Approx(val); + } + Detail::Approx operator "" _a(unsigned long long val) { + return Detail::Approx(val); + } +} // end namespace literals + +std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) { + return value.toString(); +} + +} // end namespace Catch +// end catch_approx.cpp +// start catch_assertionhandler.cpp + +// start catch_debugger.h + +namespace Catch { + bool isDebuggerActive(); +} + +#ifdef CATCH_PLATFORM_MAC + + #if defined(__i386__) || defined(__x86_64__) + #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ + #elif defined(__aarch64__) + #define CATCH_TRAP() __asm__(".inst 0xd4200000") + #endif + +#elif defined(CATCH_PLATFORM_IPHONE) + + // use inline assembler + #if defined(__i386__) || defined(__x86_64__) + #define CATCH_TRAP() __asm__("int $3") + #elif defined(__aarch64__) + #define CATCH_TRAP() __asm__(".inst 0xd4200000") + #elif defined(__arm__) && !defined(__thumb__) + #define CATCH_TRAP() __asm__(".inst 0xe7f001f0") + #elif defined(__arm__) && defined(__thumb__) + #define CATCH_TRAP() __asm__(".inst 0xde01") + #endif + +#elif defined(CATCH_PLATFORM_LINUX) + // If we can use inline assembler, do it because this allows us to break + // directly at the location of the failing check instead of breaking inside + // raise() called from it, i.e. one stack frame below. + #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) + #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ + #else // Fall back to the generic way. + #include <signal.h> + + #define CATCH_TRAP() raise(SIGTRAP) + #endif +#elif defined(_MSC_VER) + #define CATCH_TRAP() __debugbreak() +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) void __stdcall DebugBreak(); + #define CATCH_TRAP() DebugBreak() +#endif + +#ifndef CATCH_BREAK_INTO_DEBUGGER + #ifdef CATCH_TRAP + #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }() + #else + #define CATCH_BREAK_INTO_DEBUGGER() []{}() + #endif +#endif + +// end catch_debugger.h +// start catch_run_context.h + +// start catch_fatal_condition.h + +#include <cassert> + +namespace Catch { + + // Wrapper for platform-specific fatal error (signals/SEH) handlers + // + // Tries to be cooperative with other handlers, and not step over + // other handlers. This means that unknown structured exceptions + // are passed on, previous signal handlers are called, and so on. + // + // Can only be instantiated once, and assumes that once a signal + // is caught, the binary will end up terminating. Thus, there + class FatalConditionHandler { + bool m_started = false; + + // Install/disengage implementation for specific platform. + // Should be if-defed to work on current platform, can assume + // engage-disengage 1:1 pairing. + void engage_platform(); + void disengage_platform(); + public: + // Should also have platform-specific implementations as needed + FatalConditionHandler(); + ~FatalConditionHandler(); + + void engage() { + assert(!m_started && "Handler cannot be installed twice."); + m_started = true; + engage_platform(); + } + + void disengage() { + assert(m_started && "Handler cannot be uninstalled without being installed first"); + m_started = false; + disengage_platform(); + } + }; + + //! Simple RAII guard for (dis)engaging the FatalConditionHandler + class FatalConditionHandlerGuard { + FatalConditionHandler* m_handler; + public: + FatalConditionHandlerGuard(FatalConditionHandler* handler): + m_handler(handler) { + m_handler->engage(); + } + ~FatalConditionHandlerGuard() { + m_handler->disengage(); + } + }; + +} // end namespace Catch + +// end catch_fatal_condition.h +#include <string> + +namespace Catch { + + struct IMutableContext; + + /////////////////////////////////////////////////////////////////////////// + + class RunContext : public IResultCapture, public IRunner { + + public: + RunContext( RunContext const& ) = delete; + RunContext& operator =( RunContext const& ) = delete; + + explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter ); + + ~RunContext() override; + + void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ); + void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ); + + Totals runTest(TestCase const& testCase); + + IConfigPtr config() const; + IStreamingReporter& reporter() const; + + public: // IResultCapture + + // Assertion handlers + void handleExpr + ( AssertionInfo const& info, + ITransientExpression const& expr, + AssertionReaction& reaction ) override; + void handleMessage + ( AssertionInfo const& info, + ResultWas::OfType resultType, + StringRef const& message, + AssertionReaction& reaction ) override; + void handleUnexpectedExceptionNotThrown + ( AssertionInfo const& info, + AssertionReaction& reaction ) override; + void handleUnexpectedInflightException + ( AssertionInfo const& info, + std::string const& message, + AssertionReaction& reaction ) override; + void handleIncomplete + ( AssertionInfo const& info ) override; + void handleNonExpr + ( AssertionInfo const &info, + ResultWas::OfType resultType, + AssertionReaction &reaction ) override; + + bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override; + + void sectionEnded( SectionEndInfo const& endInfo ) override; + void sectionEndedEarly( SectionEndInfo const& endInfo ) override; + + auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override; + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + void benchmarkPreparing( std::string const& name ) override; + void benchmarkStarting( BenchmarkInfo const& info ) override; + void benchmarkEnded( BenchmarkStats<> const& stats ) override; + void benchmarkFailed( std::string const& error ) override; +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + + void pushScopedMessage( MessageInfo const& message ) override; + void popScopedMessage( MessageInfo const& message ) override; + + void emplaceUnscopedMessage( MessageBuilder const& builder ) override; + + std::string getCurrentTestName() const override; + + const AssertionResult* getLastResult() const override; + + void exceptionEarlyReported() override; + + void handleFatalErrorCondition( StringRef message ) override; + + bool lastAssertionPassed() override; + + void assertionPassed() override; + + public: + // !TBD We need to do this another way! + bool aborting() const final; + + private: + + void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ); + void invokeActiveTestCase(); + + void resetAssertionInfo(); + bool testForMissingAssertions( Counts& assertions ); + + void assertionEnded( AssertionResult const& result ); + void reportExpr + ( AssertionInfo const &info, + ResultWas::OfType resultType, + ITransientExpression const *expr, + bool negated ); + + void populateReaction( AssertionReaction& reaction ); + + private: + + void handleUnfinishedSections(); + + TestRunInfo m_runInfo; + IMutableContext& m_context; + TestCase const* m_activeTestCase = nullptr; + ITracker* m_testCaseTracker = nullptr; + Option<AssertionResult> m_lastResult; + + IConfigPtr m_config; + Totals m_totals; + IStreamingReporterPtr m_reporter; + std::vector<MessageInfo> m_messages; + std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */ + AssertionInfo m_lastAssertionInfo; + std::vector<SectionEndInfo> m_unfinishedSections; + std::vector<ITracker*> m_activeSections; + TrackerContext m_trackerContext; + FatalConditionHandler m_fatalConditionhandler; + bool m_lastAssertionPassed = false; + bool m_shouldReportUnexpected = true; + bool m_includeSuccessfulResults; + }; + + void seedRng(IConfig const& config); + unsigned int rngSeed(); +} // end namespace Catch + +// end catch_run_context.h +namespace Catch { + + namespace { + auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& { + expr.streamReconstructedExpression( os ); + return os; + } + } + + LazyExpression::LazyExpression( bool isNegated ) + : m_isNegated( isNegated ) + {} + + LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {} + + LazyExpression::operator bool() const { + return m_transientExpression != nullptr; + } + + auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& { + if( lazyExpr.m_isNegated ) + os << "!"; + + if( lazyExpr ) { + if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() ) + os << "(" << *lazyExpr.m_transientExpression << ")"; + else + os << *lazyExpr.m_transientExpression; + } + else { + os << "{** error - unchecked empty expression requested **}"; + } + return os; + } + + AssertionHandler::AssertionHandler + ( StringRef const& macroName, + SourceLineInfo const& lineInfo, + StringRef capturedExpression, + ResultDisposition::Flags resultDisposition ) + : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition }, + m_resultCapture( getResultCapture() ) + {} + + void AssertionHandler::handleExpr( ITransientExpression const& expr ) { + m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction ); + } + void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) { + m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction ); + } + + auto AssertionHandler::allowThrows() const -> bool { + return getCurrentContext().getConfig()->allowThrows(); + } + + void AssertionHandler::complete() { + setCompleted(); + if( m_reaction.shouldDebugBreak ) { + + // If you find your debugger stopping you here then go one level up on the + // call-stack for the code that caused it (typically a failed assertion) + + // (To go back to the test and change execution, jump over the throw, next) + CATCH_BREAK_INTO_DEBUGGER(); + } + if (m_reaction.shouldThrow) { +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + throw Catch::TestFailureException(); +#else + CATCH_ERROR( "Test failure requires aborting test!" ); +#endif + } + } + void AssertionHandler::setCompleted() { + m_completed = true; + } + + void AssertionHandler::handleUnexpectedInflightException() { + m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction ); + } + + void AssertionHandler::handleExceptionThrownAsExpected() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); + } + void AssertionHandler::handleExceptionNotThrownAsExpected() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); + } + + void AssertionHandler::handleUnexpectedExceptionNotThrown() { + m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction ); + } + + void AssertionHandler::handleThrowingCallSkipped() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); + } + + // This is the overload that takes a string and infers the Equals matcher from it + // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp + void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) { + handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString ); + } + +} // namespace Catch +// end catch_assertionhandler.cpp +// start catch_assertionresult.cpp + +namespace Catch { + AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression): + lazyExpression(_lazyExpression), + resultType(_resultType) {} + + std::string AssertionResultData::reconstructExpression() const { + + if( reconstructedExpression.empty() ) { + if( lazyExpression ) { + ReusableStringStream rss; + rss << lazyExpression; + reconstructedExpression = rss.str(); + } + } + return reconstructedExpression; + } + + AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) + : m_info( info ), + m_resultData( data ) + {} + + // Result was a success + bool AssertionResult::succeeded() const { + return Catch::isOk( m_resultData.resultType ); + } + + // Result was a success, or failure is suppressed + bool AssertionResult::isOk() const { + return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); + } + + ResultWas::OfType AssertionResult::getResultType() const { + return m_resultData.resultType; + } + + bool AssertionResult::hasExpression() const { + return !m_info.capturedExpression.empty(); + } + + bool AssertionResult::hasMessage() const { + return !m_resultData.message.empty(); + } + + std::string AssertionResult::getExpression() const { + // Possibly overallocating by 3 characters should be basically free + std::string expr; expr.reserve(m_info.capturedExpression.size() + 3); + if (isFalseTest(m_info.resultDisposition)) { + expr += "!("; + } + expr += m_info.capturedExpression; + if (isFalseTest(m_info.resultDisposition)) { + expr += ')'; + } + return expr; + } + + std::string AssertionResult::getExpressionInMacro() const { + std::string expr; + if( m_info.macroName.empty() ) + expr = static_cast<std::string>(m_info.capturedExpression); + else { + expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 ); + expr += m_info.macroName; + expr += "( "; + expr += m_info.capturedExpression; + expr += " )"; + } + return expr; + } + + bool AssertionResult::hasExpandedExpression() const { + return hasExpression() && getExpandedExpression() != getExpression(); + } + + std::string AssertionResult::getExpandedExpression() const { + std::string expr = m_resultData.reconstructExpression(); + return expr.empty() + ? getExpression() + : expr; + } + + std::string AssertionResult::getMessage() const { + return m_resultData.message; + } + SourceLineInfo AssertionResult::getSourceInfo() const { + return m_info.lineInfo; + } + + StringRef AssertionResult::getTestMacroName() const { + return m_info.macroName; + } + +} // end namespace Catch +// end catch_assertionresult.cpp +// start catch_capture_matchers.cpp + +namespace Catch { + + using StringMatcher = Matchers::Impl::MatcherBase<std::string>; + + // This is the general overload that takes a any string matcher + // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers + // the Equals matcher (so the header does not mention matchers) + void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) { + std::string exceptionMessage = Catch::translateActiveException(); + MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString ); + handler.handleExpr( expr ); + } + +} // namespace Catch +// end catch_capture_matchers.cpp +// start catch_commandline.cpp + +// start catch_commandline.h + +// start catch_clara.h + +// Use Catch's value for console width (store Clara's off to the side, if present) +#ifdef CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#endif +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1 + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#pragma clang diagnostic ignored "-Wshadow" +#endif + +// start clara.hpp +// Copyright 2017 Two Blue Cubes Ltd. All rights reserved. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See https://github.com/philsquared/Clara for more details + +// Clara v1.1.5 + + +#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80 +#endif + +#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +#ifndef CLARA_CONFIG_OPTIONAL_TYPE +#ifdef __has_include +#if __has_include(<optional>) && __cplusplus >= 201703L +#include <optional> +#define CLARA_CONFIG_OPTIONAL_TYPE std::optional +#endif +#endif +#endif + +// ----------- #included from clara_textflow.hpp ----------- + +// TextFlowCpp +// +// A single-header library for wrapping and laying out basic text, by Phil Nash +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// This project is hosted at https://github.com/philsquared/textflowcpp + + +#include <cassert> +#include <ostream> +#include <sstream> +#include <vector> + +#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { +namespace clara { +namespace TextFlow { + +inline auto isWhitespace(char c) -> bool { + static std::string chars = " \t\n\r"; + return chars.find(c) != std::string::npos; +} +inline auto isBreakableBefore(char c) -> bool { + static std::string chars = "[({<|"; + return chars.find(c) != std::string::npos; +} +inline auto isBreakableAfter(char c) -> bool { + static std::string chars = "])}>.,:;*+-=&/\\"; + return chars.find(c) != std::string::npos; +} + +class Columns; + +class Column { + std::vector<std::string> m_strings; + size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH; + size_t m_indent = 0; + size_t m_initialIndent = std::string::npos; + +public: + class iterator { + friend Column; + + Column const& m_column; + size_t m_stringIndex = 0; + size_t m_pos = 0; + + size_t m_len = 0; + size_t m_end = 0; + bool m_suffix = false; + + iterator(Column const& column, size_t stringIndex) + : m_column(column), + m_stringIndex(stringIndex) {} + + auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; } + + auto isBoundary(size_t at) const -> bool { + assert(at > 0); + assert(at <= line().size()); + + return at == line().size() || + (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) || + isBreakableBefore(line()[at]) || + isBreakableAfter(line()[at - 1]); + } + + void calcLength() { + assert(m_stringIndex < m_column.m_strings.size()); + + m_suffix = false; + auto width = m_column.m_width - indent(); + m_end = m_pos; + if (line()[m_pos] == '\n') { + ++m_end; + } + while (m_end < line().size() && line()[m_end] != '\n') + ++m_end; + + if (m_end < m_pos + width) { + m_len = m_end - m_pos; + } else { + size_t len = width; + while (len > 0 && !isBoundary(m_pos + len)) + --len; + while (len > 0 && isWhitespace(line()[m_pos + len - 1])) + --len; + + if (len > 0) { + m_len = len; + } else { + m_suffix = true; + m_len = width - 1; + } + } + } + + auto indent() const -> size_t { + auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos; + return initial == std::string::npos ? m_column.m_indent : initial; + } + + auto addIndentAndSuffix(std::string const &plain) const -> std::string { + return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain); + } + + public: + using difference_type = std::ptrdiff_t; + using value_type = std::string; + using pointer = value_type * ; + using reference = value_type & ; + using iterator_category = std::forward_iterator_tag; + + explicit iterator(Column const& column) : m_column(column) { + assert(m_column.m_width > m_column.m_indent); + assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent); + calcLength(); + if (m_len == 0) + m_stringIndex++; // Empty string + } + + auto operator *() const -> std::string { + assert(m_stringIndex < m_column.m_strings.size()); + assert(m_pos <= m_end); + return addIndentAndSuffix(line().substr(m_pos, m_len)); + } + + auto operator ++() -> iterator& { + m_pos += m_len; + if (m_pos < line().size() && line()[m_pos] == '\n') + m_pos += 1; + else + while (m_pos < line().size() && isWhitespace(line()[m_pos])) + ++m_pos; + + if (m_pos == line().size()) { + m_pos = 0; + ++m_stringIndex; + } + if (m_stringIndex < m_column.m_strings.size()) + calcLength(); + return *this; + } + auto operator ++(int) -> iterator { + iterator prev(*this); + operator++(); + return prev; + } + + auto operator ==(iterator const& other) const -> bool { + return + m_pos == other.m_pos && + m_stringIndex == other.m_stringIndex && + &m_column == &other.m_column; + } + auto operator !=(iterator const& other) const -> bool { + return !operator==(other); + } + }; + using const_iterator = iterator; + + explicit Column(std::string const& text) { m_strings.push_back(text); } + + auto width(size_t newWidth) -> Column& { + assert(newWidth > 0); + m_width = newWidth; + return *this; + } + auto indent(size_t newIndent) -> Column& { + m_indent = newIndent; + return *this; + } + auto initialIndent(size_t newIndent) -> Column& { + m_initialIndent = newIndent; + return *this; + } + + auto width() const -> size_t { return m_width; } + auto begin() const -> iterator { return iterator(*this); } + auto end() const -> iterator { return { *this, m_strings.size() }; } + + inline friend std::ostream& operator << (std::ostream& os, Column const& col) { + bool first = true; + for (auto line : col) { + if (first) + first = false; + else + os << "\n"; + os << line; + } + return os; + } + + auto operator + (Column const& other)->Columns; + + auto toString() const -> std::string { + std::ostringstream oss; + oss << *this; + return oss.str(); + } +}; + +class Spacer : public Column { + +public: + explicit Spacer(size_t spaceWidth) : Column("") { + width(spaceWidth); + } +}; + +class Columns { + std::vector<Column> m_columns; + +public: + + class iterator { + friend Columns; + struct EndTag {}; + + std::vector<Column> const& m_columns; + std::vector<Column::iterator> m_iterators; + size_t m_activeIterators; + + iterator(Columns const& columns, EndTag) + : m_columns(columns.m_columns), + m_activeIterators(0) { + m_iterators.reserve(m_columns.size()); + + for (auto const& col : m_columns) + m_iterators.push_back(col.end()); + } + + public: + using difference_type = std::ptrdiff_t; + using value_type = std::string; + using pointer = value_type * ; + using reference = value_type & ; + using iterator_category = std::forward_iterator_tag; + + explicit iterator(Columns const& columns) + : m_columns(columns.m_columns), + m_activeIterators(m_columns.size()) { + m_iterators.reserve(m_columns.size()); + + for (auto const& col : m_columns) + m_iterators.push_back(col.begin()); + } + + auto operator ==(iterator const& other) const -> bool { + return m_iterators == other.m_iterators; + } + auto operator !=(iterator const& other) const -> bool { + return m_iterators != other.m_iterators; + } + auto operator *() const -> std::string { + std::string row, padding; + + for (size_t i = 0; i < m_columns.size(); ++i) { + auto width = m_columns[i].width(); + if (m_iterators[i] != m_columns[i].end()) { + std::string col = *m_iterators[i]; + row += padding + col; + if (col.size() < width) + padding = std::string(width - col.size(), ' '); + else + padding = ""; + } else { + padding += std::string(width, ' '); + } + } + return row; + } + auto operator ++() -> iterator& { + for (size_t i = 0; i < m_columns.size(); ++i) { + if (m_iterators[i] != m_columns[i].end()) + ++m_iterators[i]; + } + return *this; + } + auto operator ++(int) -> iterator { + iterator prev(*this); + operator++(); + return prev; + } + }; + using const_iterator = iterator; + + auto begin() const -> iterator { return iterator(*this); } + auto end() const -> iterator { return { *this, iterator::EndTag() }; } + + auto operator += (Column const& col) -> Columns& { + m_columns.push_back(col); + return *this; + } + auto operator + (Column const& col) -> Columns { + Columns combined = *this; + combined += col; + return combined; + } + + inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) { + + bool first = true; + for (auto line : cols) { + if (first) + first = false; + else + os << "\n"; + os << line; + } + return os; + } + + auto toString() const -> std::string { + std::ostringstream oss; + oss << *this; + return oss.str(); + } +}; + +inline auto Column::operator + (Column const& other) -> Columns { + Columns cols; + cols += *this; + cols += other; + return cols; +} +} + +} +} + +// ----------- end of #include from clara_textflow.hpp ----------- +// ........... back in clara.hpp + +#include <cctype> +#include <string> +#include <memory> +#include <set> +#include <algorithm> + +#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) ) +#define CATCH_PLATFORM_WINDOWS +#endif + +namespace Catch { namespace clara { +namespace detail { + + // Traits for extracting arg and return type of lambdas (for single argument lambdas) + template<typename L> + struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {}; + + template<typename ClassT, typename ReturnT, typename... Args> + struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> { + static const bool isValid = false; + }; + + template<typename ClassT, typename ReturnT, typename ArgT> + struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> { + static const bool isValid = true; + using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type; + using ReturnType = ReturnT; + }; + + class TokenStream; + + // Transport for raw args (copied from main args, or supplied via init list for testing) + class Args { + friend TokenStream; + std::string m_exeName; + std::vector<std::string> m_args; + + public: + Args( int argc, char const* const* argv ) + : m_exeName(argv[0]), + m_args(argv + 1, argv + argc) {} + + Args( std::initializer_list<std::string> args ) + : m_exeName( *args.begin() ), + m_args( args.begin()+1, args.end() ) + {} + + auto exeName() const -> std::string { + return m_exeName; + } + }; + + // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string + // may encode an option + its argument if the : or = form is used + enum class TokenType { + Option, Argument + }; + struct Token { + TokenType type; + std::string token; + }; + + inline auto isOptPrefix( char c ) -> bool { + return c == '-' +#ifdef CATCH_PLATFORM_WINDOWS + || c == '/' +#endif + ; + } + + // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled + class TokenStream { + using Iterator = std::vector<std::string>::const_iterator; + Iterator it; + Iterator itEnd; + std::vector<Token> m_tokenBuffer; + + void loadBuffer() { + m_tokenBuffer.resize( 0 ); + + // Skip any empty strings + while( it != itEnd && it->empty() ) + ++it; + + if( it != itEnd ) { + auto const &next = *it; + if( isOptPrefix( next[0] ) ) { + auto delimiterPos = next.find_first_of( " :=" ); + if( delimiterPos != std::string::npos ) { + m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } ); + m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } ); + } else { + if( next[1] != '-' && next.size() > 2 ) { + std::string opt = "- "; + for( size_t i = 1; i < next.size(); ++i ) { + opt[1] = next[i]; + m_tokenBuffer.push_back( { TokenType::Option, opt } ); + } + } else { + m_tokenBuffer.push_back( { TokenType::Option, next } ); + } + } + } else { + m_tokenBuffer.push_back( { TokenType::Argument, next } ); + } + } + } + + public: + explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {} + + TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) { + loadBuffer(); + } + + explicit operator bool() const { + return !m_tokenBuffer.empty() || it != itEnd; + } + + auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); } + + auto operator*() const -> Token { + assert( !m_tokenBuffer.empty() ); + return m_tokenBuffer.front(); + } + + auto operator->() const -> Token const * { + assert( !m_tokenBuffer.empty() ); + return &m_tokenBuffer.front(); + } + + auto operator++() -> TokenStream & { + if( m_tokenBuffer.size() >= 2 ) { + m_tokenBuffer.erase( m_tokenBuffer.begin() ); + } else { + if( it != itEnd ) + ++it; + loadBuffer(); + } + return *this; + } + }; + + class ResultBase { + public: + enum Type { + Ok, LogicError, RuntimeError + }; + + protected: + ResultBase( Type type ) : m_type( type ) {} + virtual ~ResultBase() = default; + + virtual void enforceOk() const = 0; + + Type m_type; + }; + + template<typename T> + class ResultValueBase : public ResultBase { + public: + auto value() const -> T const & { + enforceOk(); + return m_value; + } + + protected: + ResultValueBase( Type type ) : ResultBase( type ) {} + + ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) { + if( m_type == ResultBase::Ok ) + new( &m_value ) T( other.m_value ); + } + + ResultValueBase( Type, T const &value ) : ResultBase( Ok ) { + new( &m_value ) T( value ); + } + + auto operator=( ResultValueBase const &other ) -> ResultValueBase & { + if( m_type == ResultBase::Ok ) + m_value.~T(); + ResultBase::operator=(other); + if( m_type == ResultBase::Ok ) + new( &m_value ) T( other.m_value ); + return *this; + } + + ~ResultValueBase() override { + if( m_type == Ok ) + m_value.~T(); + } + + union { + T m_value; + }; + }; + + template<> + class ResultValueBase<void> : public ResultBase { + protected: + using ResultBase::ResultBase; + }; + + template<typename T = void> + class BasicResult : public ResultValueBase<T> { + public: + template<typename U> + explicit BasicResult( BasicResult<U> const &other ) + : ResultValueBase<T>( other.type() ), + m_errorMessage( other.errorMessage() ) + { + assert( type() != ResultBase::Ok ); + } + + template<typename U> + static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; } + static auto ok() -> BasicResult { return { ResultBase::Ok }; } + static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; } + static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; } + + explicit operator bool() const { return m_type == ResultBase::Ok; } + auto type() const -> ResultBase::Type { return m_type; } + auto errorMessage() const -> std::string { return m_errorMessage; } + + protected: + void enforceOk() const override { + + // Errors shouldn't reach this point, but if they do + // the actual error message will be in m_errorMessage + assert( m_type != ResultBase::LogicError ); + assert( m_type != ResultBase::RuntimeError ); + if( m_type != ResultBase::Ok ) + std::abort(); + } + + std::string m_errorMessage; // Only populated if resultType is an error + + BasicResult( ResultBase::Type type, std::string const &message ) + : ResultValueBase<T>(type), + m_errorMessage(message) + { + assert( m_type != ResultBase::Ok ); + } + + using ResultValueBase<T>::ResultValueBase; + using ResultBase::m_type; + }; + + enum class ParseResultType { + Matched, NoMatch, ShortCircuitAll, ShortCircuitSame + }; + + class ParseState { + public: + + ParseState( ParseResultType type, TokenStream const &remainingTokens ) + : m_type(type), + m_remainingTokens( remainingTokens ) + {} + + auto type() const -> ParseResultType { return m_type; } + auto remainingTokens() const -> TokenStream { return m_remainingTokens; } + + private: + ParseResultType m_type; + TokenStream m_remainingTokens; + }; + + using Result = BasicResult<void>; + using ParserResult = BasicResult<ParseResultType>; + using InternalParseResult = BasicResult<ParseState>; + + struct HelpColumns { + std::string left; + std::string right; + }; + + template<typename T> + inline auto convertInto( std::string const &source, T& target ) -> ParserResult { + std::stringstream ss; + ss << source; + ss >> target; + if( ss.fail() ) + return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" ); + else + return ParserResult::ok( ParseResultType::Matched ); + } + inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult { + target = source; + return ParserResult::ok( ParseResultType::Matched ); + } + inline auto convertInto( std::string const &source, bool &target ) -> ParserResult { + std::string srcLC = source; + std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } ); + if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") + target = true; + else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off") + target = false; + else + return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" ); + return ParserResult::ok( ParseResultType::Matched ); + } +#ifdef CLARA_CONFIG_OPTIONAL_TYPE + template<typename T> + inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult { + T temp; + auto result = convertInto( source, temp ); + if( result ) + target = std::move(temp); + return result; + } +#endif // CLARA_CONFIG_OPTIONAL_TYPE + + struct NonCopyable { + NonCopyable() = default; + NonCopyable( NonCopyable const & ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable &operator=( NonCopyable const & ) = delete; + NonCopyable &operator=( NonCopyable && ) = delete; + }; + + struct BoundRef : NonCopyable { + virtual ~BoundRef() = default; + virtual auto isContainer() const -> bool { return false; } + virtual auto isFlag() const -> bool { return false; } + }; + struct BoundValueRefBase : BoundRef { + virtual auto setValue( std::string const &arg ) -> ParserResult = 0; + }; + struct BoundFlagRefBase : BoundRef { + virtual auto setFlag( bool flag ) -> ParserResult = 0; + virtual auto isFlag() const -> bool { return true; } + }; + + template<typename T> + struct BoundValueRef : BoundValueRefBase { + T &m_ref; + + explicit BoundValueRef( T &ref ) : m_ref( ref ) {} + + auto setValue( std::string const &arg ) -> ParserResult override { + return convertInto( arg, m_ref ); + } + }; + + template<typename T> + struct BoundValueRef<std::vector<T>> : BoundValueRefBase { + std::vector<T> &m_ref; + + explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {} + + auto isContainer() const -> bool override { return true; } + + auto setValue( std::string const &arg ) -> ParserResult override { + T temp; + auto result = convertInto( arg, temp ); + if( result ) + m_ref.push_back( temp ); + return result; + } + }; + + struct BoundFlagRef : BoundFlagRefBase { + bool &m_ref; + + explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {} + + auto setFlag( bool flag ) -> ParserResult override { + m_ref = flag; + return ParserResult::ok( ParseResultType::Matched ); + } + }; + + template<typename ReturnType> + struct LambdaInvoker { + static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" ); + + template<typename L, typename ArgType> + static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult { + return lambda( arg ); + } + }; + + template<> + struct LambdaInvoker<void> { + template<typename L, typename ArgType> + static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult { + lambda( arg ); + return ParserResult::ok( ParseResultType::Matched ); + } + }; + + template<typename ArgType, typename L> + inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult { + ArgType temp{}; + auto result = convertInto( arg, temp ); + return !result + ? result + : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp ); + } + + template<typename L> + struct BoundLambda : BoundValueRefBase { + L m_lambda; + + static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" ); + explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {} + + auto setValue( std::string const &arg ) -> ParserResult override { + return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg ); + } + }; + + template<typename L> + struct BoundFlagLambda : BoundFlagRefBase { + L m_lambda; + + static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" ); + static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" ); + + explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {} + + auto setFlag( bool flag ) -> ParserResult override { + return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag ); + } + }; + + enum class Optionality { Optional, Required }; + + struct Parser; + + class ParserBase { + public: + virtual ~ParserBase() = default; + virtual auto validate() const -> Result { return Result::ok(); } + virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0; + virtual auto cardinality() const -> size_t { return 1; } + + auto parse( Args const &args ) const -> InternalParseResult { + return parse( args.exeName(), TokenStream( args ) ); + } + }; + + template<typename DerivedT> + class ComposableParserImpl : public ParserBase { + public: + template<typename T> + auto operator|( T const &other ) const -> Parser; + + template<typename T> + auto operator+( T const &other ) const -> Parser; + }; + + // Common code and state for Args and Opts + template<typename DerivedT> + class ParserRefImpl : public ComposableParserImpl<DerivedT> { + protected: + Optionality m_optionality = Optionality::Optional; + std::shared_ptr<BoundRef> m_ref; + std::string m_hint; + std::string m_description; + + explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {} + + public: + template<typename T> + ParserRefImpl( T &ref, std::string const &hint ) + : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ), + m_hint( hint ) + {} + + template<typename LambdaT> + ParserRefImpl( LambdaT const &ref, std::string const &hint ) + : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ), + m_hint(hint) + {} + + auto operator()( std::string const &description ) -> DerivedT & { + m_description = description; + return static_cast<DerivedT &>( *this ); + } + + auto optional() -> DerivedT & { + m_optionality = Optionality::Optional; + return static_cast<DerivedT &>( *this ); + }; + + auto required() -> DerivedT & { + m_optionality = Optionality::Required; + return static_cast<DerivedT &>( *this ); + }; + + auto isOptional() const -> bool { + return m_optionality == Optionality::Optional; + } + + auto cardinality() const -> size_t override { + if( m_ref->isContainer() ) + return 0; + else + return 1; + } + + auto hint() const -> std::string { return m_hint; } + }; + + class ExeName : public ComposableParserImpl<ExeName> { + std::shared_ptr<std::string> m_name; + std::shared_ptr<BoundValueRefBase> m_ref; + + template<typename LambdaT> + static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> { + return std::make_shared<BoundLambda<LambdaT>>( lambda) ; + } + + public: + ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {} + + explicit ExeName( std::string &ref ) : ExeName() { + m_ref = std::make_shared<BoundValueRef<std::string>>( ref ); + } + + template<typename LambdaT> + explicit ExeName( LambdaT const& lambda ) : ExeName() { + m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda ); + } + + // The exe name is not parsed out of the normal tokens, but is handled specially + auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override { + return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) ); + } + + auto name() const -> std::string { return *m_name; } + auto set( std::string const& newName ) -> ParserResult { + + auto lastSlash = newName.find_last_of( "\\/" ); + auto filename = ( lastSlash == std::string::npos ) + ? newName + : newName.substr( lastSlash+1 ); + + *m_name = filename; + if( m_ref ) + return m_ref->setValue( filename ); + else + return ParserResult::ok( ParseResultType::Matched ); + } + }; + + class Arg : public ParserRefImpl<Arg> { + public: + using ParserRefImpl::ParserRefImpl; + + auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override { + auto validationResult = validate(); + if( !validationResult ) + return InternalParseResult( validationResult ); + + auto remainingTokens = tokens; + auto const &token = *remainingTokens; + if( token.type != TokenType::Argument ) + return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) ); + + assert( !m_ref->isFlag() ); + auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() ); + + auto result = valueRef->setValue( remainingTokens->token ); + if( !result ) + return InternalParseResult( result ); + else + return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) ); + } + }; + + inline auto normaliseOpt( std::string const &optName ) -> std::string { +#ifdef CATCH_PLATFORM_WINDOWS + if( optName[0] == '/' ) + return "-" + optName.substr( 1 ); + else +#endif + return optName; + } + + class Opt : public ParserRefImpl<Opt> { + protected: + std::vector<std::string> m_optNames; + + public: + template<typename LambdaT> + explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {} + + explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {} + + template<typename LambdaT> + Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {} + + template<typename T> + Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {} + + auto operator[]( std::string const &optName ) -> Opt & { + m_optNames.push_back( optName ); + return *this; + } + + auto getHelpColumns() const -> std::vector<HelpColumns> { + std::ostringstream oss; + bool first = true; + for( auto const &opt : m_optNames ) { + if (first) + first = false; + else + oss << ", "; + oss << opt; + } + if( !m_hint.empty() ) + oss << " <" << m_hint << ">"; + return { { oss.str(), m_description } }; + } + + auto isMatch( std::string const &optToken ) const -> bool { + auto normalisedToken = normaliseOpt( optToken ); + for( auto const &name : m_optNames ) { + if( normaliseOpt( name ) == normalisedToken ) + return true; + } + return false; + } + + using ParserBase::parse; + + auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override { + auto validationResult = validate(); + if( !validationResult ) + return InternalParseResult( validationResult ); + + auto remainingTokens = tokens; + if( remainingTokens && remainingTokens->type == TokenType::Option ) { + auto const &token = *remainingTokens; + if( isMatch(token.token ) ) { + if( m_ref->isFlag() ) { + auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() ); + auto result = flagRef->setFlag( true ); + if( !result ) + return InternalParseResult( result ); + if( result.value() == ParseResultType::ShortCircuitAll ) + return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) ); + } else { + auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() ); + ++remainingTokens; + if( !remainingTokens ) + return InternalParseResult::runtimeError( "Expected argument following " + token.token ); + auto const &argToken = *remainingTokens; + if( argToken.type != TokenType::Argument ) + return InternalParseResult::runtimeError( "Expected argument following " + token.token ); + auto result = valueRef->setValue( argToken.token ); + if( !result ) + return InternalParseResult( result ); + if( result.value() == ParseResultType::ShortCircuitAll ) + return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) ); + } + return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) ); + } + } + return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) ); + } + + auto validate() const -> Result override { + if( m_optNames.empty() ) + return Result::logicError( "No options supplied to Opt" ); + for( auto const &name : m_optNames ) { + if( name.empty() ) + return Result::logicError( "Option name cannot be empty" ); +#ifdef CATCH_PLATFORM_WINDOWS + if( name[0] != '-' && name[0] != '/' ) + return Result::logicError( "Option name must begin with '-' or '/'" ); +#else + if( name[0] != '-' ) + return Result::logicError( "Option name must begin with '-'" ); +#endif + } + return ParserRefImpl::validate(); + } + }; + + struct Help : Opt { + Help( bool &showHelpFlag ) + : Opt([&]( bool flag ) { + showHelpFlag = flag; + return ParserResult::ok( ParseResultType::ShortCircuitAll ); + }) + { + static_cast<Opt &>( *this ) + ("display usage information") + ["-?"]["-h"]["--help"] + .optional(); + } + }; + + struct Parser : ParserBase { + + mutable ExeName m_exeName; + std::vector<Opt> m_options; + std::vector<Arg> m_args; + + auto operator|=( ExeName const &exeName ) -> Parser & { + m_exeName = exeName; + return *this; + } + + auto operator|=( Arg const &arg ) -> Parser & { + m_args.push_back(arg); + return *this; + } + + auto operator|=( Opt const &opt ) -> Parser & { + m_options.push_back(opt); + return *this; + } + + auto operator|=( Parser const &other ) -> Parser & { + m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end()); + m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end()); + return *this; + } + + template<typename T> + auto operator|( T const &other ) const -> Parser { + return Parser( *this ) |= other; + } + + // Forward deprecated interface with '+' instead of '|' + template<typename T> + auto operator+=( T const &other ) -> Parser & { return operator|=( other ); } + template<typename T> + auto operator+( T const &other ) const -> Parser { return operator|( other ); } + + auto getHelpColumns() const -> std::vector<HelpColumns> { + std::vector<HelpColumns> cols; + for (auto const &o : m_options) { + auto childCols = o.getHelpColumns(); + cols.insert( cols.end(), childCols.begin(), childCols.end() ); + } + return cols; + } + + void writeToStream( std::ostream &os ) const { + if (!m_exeName.name().empty()) { + os << "usage:\n" << " " << m_exeName.name() << " "; + bool required = true, first = true; + for( auto const &arg : m_args ) { + if (first) + first = false; + else + os << " "; + if( arg.isOptional() && required ) { + os << "["; + required = false; + } + os << "<" << arg.hint() << ">"; + if( arg.cardinality() == 0 ) + os << " ... "; + } + if( !required ) + os << "]"; + if( !m_options.empty() ) + os << " options"; + os << "\n\nwhere options are:" << std::endl; + } + + auto rows = getHelpColumns(); + size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH; + size_t optWidth = 0; + for( auto const &cols : rows ) + optWidth = (std::max)(optWidth, cols.left.size() + 2); + + optWidth = (std::min)(optWidth, consoleWidth/2); + + for( auto const &cols : rows ) { + auto row = + TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) + + TextFlow::Spacer(4) + + TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth ); + os << row << std::endl; + } + } + + friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& { + parser.writeToStream( os ); + return os; + } + + auto validate() const -> Result override { + for( auto const &opt : m_options ) { + auto result = opt.validate(); + if( !result ) + return result; + } + for( auto const &arg : m_args ) { + auto result = arg.validate(); + if( !result ) + return result; + } + return Result::ok(); + } + + using ParserBase::parse; + + auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override { + + struct ParserInfo { + ParserBase const* parser = nullptr; + size_t count = 0; + }; + const size_t totalParsers = m_options.size() + m_args.size(); + assert( totalParsers < 512 ); + // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do + ParserInfo parseInfos[512]; + + { + size_t i = 0; + for (auto const &opt : m_options) parseInfos[i++].parser = &opt; + for (auto const &arg : m_args) parseInfos[i++].parser = &arg; + } + + m_exeName.set( exeName ); + + auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) ); + while( result.value().remainingTokens() ) { + bool tokenParsed = false; + + for( size_t i = 0; i < totalParsers; ++i ) { + auto& parseInfo = parseInfos[i]; + if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) { + result = parseInfo.parser->parse(exeName, result.value().remainingTokens()); + if (!result) + return result; + if (result.value().type() != ParseResultType::NoMatch) { + tokenParsed = true; + ++parseInfo.count; + break; + } + } + } + + if( result.value().type() == ParseResultType::ShortCircuitAll ) + return result; + if( !tokenParsed ) + return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token ); + } + // !TBD Check missing required options + return result; + } + }; + + template<typename DerivedT> + template<typename T> + auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser { + return Parser() | static_cast<DerivedT const &>( *this ) | other; + } +} // namespace detail + +// A Combined parser +using detail::Parser; + +// A parser for options +using detail::Opt; + +// A parser for arguments +using detail::Arg; + +// Wrapper for argc, argv from main() +using detail::Args; + +// Specifies the name of the executable +using detail::ExeName; + +// Convenience wrapper for option parser that specifies the help option +using detail::Help; + +// enum of result types from a parse +using detail::ParseResultType; + +// Result type for parser operation +using detail::ParserResult; + +}} // namespace Catch::clara + +// end clara.hpp +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// Restore Clara's value for console width, if present +#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +// end catch_clara.h +namespace Catch { + + clara::Parser makeCommandLineParser( ConfigData& config ); + +} // end namespace Catch + +// end catch_commandline.h +#include <fstream> +#include <ctime> + +namespace Catch { + + clara::Parser makeCommandLineParser( ConfigData& config ) { + + using namespace clara; + + auto const setWarning = [&]( std::string const& warning ) { + auto warningSet = [&]() { + if( warning == "NoAssertions" ) + return WarnAbout::NoAssertions; + + if ( warning == "NoTests" ) + return WarnAbout::NoTests; + + return WarnAbout::Nothing; + }(); + + if (warningSet == WarnAbout::Nothing) + return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" ); + config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const loadTestNamesFromFile = [&]( std::string const& filename ) { + std::ifstream f( filename.c_str() ); + if( !f.is_open() ) + return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" ); + + std::string line; + while( std::getline( f, line ) ) { + line = trim(line); + if( !line.empty() && !startsWith( line, '#' ) ) { + if( !startsWith( line, '"' ) ) + line = '"' + line + '"'; + config.testsOrTags.push_back( line ); + config.testsOrTags.emplace_back( "," ); + } + } + //Remove comma in the end + if(!config.testsOrTags.empty()) + config.testsOrTags.erase( config.testsOrTags.end()-1 ); + + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setTestOrder = [&]( std::string const& order ) { + if( startsWith( "declared", order ) ) + config.runOrder = RunTests::InDeclarationOrder; + else if( startsWith( "lexical", order ) ) + config.runOrder = RunTests::InLexicographicalOrder; + else if( startsWith( "random", order ) ) + config.runOrder = RunTests::InRandomOrder; + else + return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setRngSeed = [&]( std::string const& seed ) { + if( seed != "time" ) + return clara::detail::convertInto( seed, config.rngSeed ); + config.rngSeed = static_cast<unsigned int>( std::time(nullptr) ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setColourUsage = [&]( std::string const& useColour ) { + auto mode = toLower( useColour ); + + if( mode == "yes" ) + config.useColour = UseColour::Yes; + else if( mode == "no" ) + config.useColour = UseColour::No; + else if( mode == "auto" ) + config.useColour = UseColour::Auto; + else + return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setWaitForKeypress = [&]( std::string const& keypress ) { + auto keypressLc = toLower( keypress ); + if (keypressLc == "never") + config.waitForKeypress = WaitForKeypress::Never; + else if( keypressLc == "start" ) + config.waitForKeypress = WaitForKeypress::BeforeStart; + else if( keypressLc == "exit" ) + config.waitForKeypress = WaitForKeypress::BeforeExit; + else if( keypressLc == "both" ) + config.waitForKeypress = WaitForKeypress::BeforeStartAndExit; + else + return ParserResult::runtimeError( "keypress argument must be one of: never, start, exit or both. '" + keypress + "' not recognised" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setVerbosity = [&]( std::string const& verbosity ) { + auto lcVerbosity = toLower( verbosity ); + if( lcVerbosity == "quiet" ) + config.verbosity = Verbosity::Quiet; + else if( lcVerbosity == "normal" ) + config.verbosity = Verbosity::Normal; + else if( lcVerbosity == "high" ) + config.verbosity = Verbosity::High; + else + return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setReporter = [&]( std::string const& reporter ) { + IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); + + auto lcReporter = toLower( reporter ); + auto result = factories.find( lcReporter ); + + if( factories.end() != result ) + config.reporterName = lcReporter; + else + return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + + auto cli + = ExeName( config.processName ) + | Help( config.showHelp ) + | Opt( config.listTests ) + ["-l"]["--list-tests"] + ( "list all/matching test cases" ) + | Opt( config.listTags ) + ["-t"]["--list-tags"] + ( "list all/matching tags" ) + | Opt( config.showSuccessfulTests ) + ["-s"]["--success"] + ( "include successful tests in output" ) + | Opt( config.shouldDebugBreak ) + ["-b"]["--break"] + ( "break into debugger on failure" ) + | Opt( config.noThrow ) + ["-e"]["--nothrow"] + ( "skip exception tests" ) + | Opt( config.showInvisibles ) + ["-i"]["--invisibles"] + ( "show invisibles (tabs, newlines)" ) + | Opt( config.outputFilename, "filename" ) + ["-o"]["--out"] + ( "output filename" ) + | Opt( setReporter, "name" ) + ["-r"]["--reporter"] + ( "reporter to use (defaults to console)" ) + | Opt( config.name, "name" ) + ["-n"]["--name"] + ( "suite name" ) + | Opt( [&]( bool ){ config.abortAfter = 1; } ) + ["-a"]["--abort"] + ( "abort at first failure" ) + | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" ) + ["-x"]["--abortx"] + ( "abort after x failures" ) + | Opt( setWarning, "warning name" ) + ["-w"]["--warn"] + ( "enable warnings" ) + | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" ) + ["-d"]["--durations"] + ( "show test durations" ) + | Opt( config.minDuration, "seconds" ) + ["-D"]["--min-duration"] + ( "show test durations for tests taking at least the given number of seconds" ) + | Opt( loadTestNamesFromFile, "filename" ) + ["-f"]["--input-file"] + ( "load test names to run from a file" ) + | Opt( config.filenamesAsTags ) + ["-#"]["--filenames-as-tags"] + ( "adds a tag for the filename" ) + | Opt( config.sectionsToRun, "section name" ) + ["-c"]["--section"] + ( "specify section to run" ) + | Opt( setVerbosity, "quiet|normal|high" ) + ["-v"]["--verbosity"] + ( "set output verbosity" ) + | Opt( config.listTestNamesOnly ) + ["--list-test-names-only"] + ( "list all/matching test cases names only" ) + | Opt( config.listReporters ) + ["--list-reporters"] + ( "list all reporters" ) + | Opt( setTestOrder, "decl|lex|rand" ) + ["--order"] + ( "test case order (defaults to decl)" ) + | Opt( setRngSeed, "'time'|number" ) + ["--rng-seed"] + ( "set a specific seed for random numbers" ) + | Opt( setColourUsage, "yes|no" ) + ["--use-colour"] + ( "should output be colourised" ) + | Opt( config.libIdentify ) + ["--libidentify"] + ( "report name and version according to libidentify standard" ) + | Opt( setWaitForKeypress, "never|start|exit|both" ) + ["--wait-for-keypress"] + ( "waits for a keypress before exiting" ) + | Opt( config.benchmarkSamples, "samples" ) + ["--benchmark-samples"] + ( "number of samples to collect (default: 100)" ) + | Opt( config.benchmarkResamples, "resamples" ) + ["--benchmark-resamples"] + ( "number of resamples for the bootstrap (default: 100000)" ) + | Opt( config.benchmarkConfidenceInterval, "confidence interval" ) + ["--benchmark-confidence-interval"] + ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" ) + | Opt( config.benchmarkNoAnalysis ) + ["--benchmark-no-analysis"] + ( "perform only measurements; do not perform any analysis" ) + | Opt( config.benchmarkWarmupTime, "benchmarkWarmupTime" ) + ["--benchmark-warmup-time"] + ( "amount of time in milliseconds spent on warming up each test (default: 100)" ) + | Arg( config.testsOrTags, "test name|pattern|tags" ) + ( "which test or tests to use" ); + + return cli; + } + +} // end namespace Catch +// end catch_commandline.cpp +// start catch_common.cpp + +#include <cstring> +#include <ostream> + +namespace Catch { + + bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept { + return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); + } + bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept { + // We can assume that the same file will usually have the same pointer. + // Thus, if the pointers are the same, there is no point in calling the strcmp + return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0)); + } + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { +#ifndef __GNUG__ + os << info.file << '(' << info.line << ')'; +#else + os << info.file << ':' << info.line; +#endif + return os; + } + + std::string StreamEndStop::operator+() const { + return std::string(); + } + + NonCopyable::NonCopyable() = default; + NonCopyable::~NonCopyable() = default; + +} +// end catch_common.cpp +// start catch_config.cpp + +namespace Catch { + + Config::Config( ConfigData const& data ) + : m_data( data ), + m_stream( openStream() ) + { + // We need to trim filter specs to avoid trouble with superfluous + // whitespace (esp. important for bdd macros, as those are manually + // aligned with whitespace). + + for (auto& elem : m_data.testsOrTags) { + elem = trim(elem); + } + for (auto& elem : m_data.sectionsToRun) { + elem = trim(elem); + } + + TestSpecParser parser(ITagAliasRegistry::get()); + if (!m_data.testsOrTags.empty()) { + m_hasTestFilters = true; + for (auto const& testOrTags : m_data.testsOrTags) { + parser.parse(testOrTags); + } + } + m_testSpec = parser.testSpec(); + } + + std::string const& Config::getFilename() const { + return m_data.outputFilename ; + } + + bool Config::listTests() const { return m_data.listTests; } + bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; } + bool Config::listTags() const { return m_data.listTags; } + bool Config::listReporters() const { return m_data.listReporters; } + + std::string Config::getProcessName() const { return m_data.processName; } + std::string const& Config::getReporterName() const { return m_data.reporterName; } + + std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; } + std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; } + + TestSpec const& Config::testSpec() const { return m_testSpec; } + bool Config::hasTestFilters() const { return m_hasTestFilters; } + + bool Config::showHelp() const { return m_data.showHelp; } + + // IConfig interface + bool Config::allowThrows() const { return !m_data.noThrow; } + std::ostream& Config::stream() const { return m_stream->stream(); } + std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; } + bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; } + bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); } + bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); } + ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; } + double Config::minDuration() const { return m_data.minDuration; } + RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; } + unsigned int Config::rngSeed() const { return m_data.rngSeed; } + UseColour::YesOrNo Config::useColour() const { return m_data.useColour; } + bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; } + int Config::abortAfter() const { return m_data.abortAfter; } + bool Config::showInvisibles() const { return m_data.showInvisibles; } + Verbosity Config::verbosity() const { return m_data.verbosity; } + + bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; } + int Config::benchmarkSamples() const { return m_data.benchmarkSamples; } + double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; } + unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; } + std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); } + + IStream const* Config::openStream() { + return Catch::makeStream(m_data.outputFilename); + } + +} // end namespace Catch +// end catch_config.cpp +// start catch_console_colour.cpp + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +// start catch_errno_guard.h + +namespace Catch { + + class ErrnoGuard { + public: + ErrnoGuard(); + ~ErrnoGuard(); + private: + int m_oldErrno; + }; + +} + +// end catch_errno_guard.h +// start catch_windows_h_proxy.h + + +#if defined(CATCH_PLATFORM_WINDOWS) + +#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) +# define CATCH_DEFINED_NOMINMAX +# define NOMINMAX +#endif +#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) +# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#ifdef __AFXDLL +#include <AfxWin.h> +#else +#include <windows.h> +#endif + +#ifdef CATCH_DEFINED_NOMINMAX +# undef NOMINMAX +#endif +#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN +# undef WIN32_LEAN_AND_MEAN +#endif + +#endif // defined(CATCH_PLATFORM_WINDOWS) + +// end catch_windows_h_proxy.h +#include <sstream> + +namespace Catch { + namespace { + + struct IColourImpl { + virtual ~IColourImpl() = default; + virtual void use( Colour::Code _colourCode ) = 0; + }; + + struct NoColourImpl : IColourImpl { + void use( Colour::Code ) override {} + + static IColourImpl* instance() { + static NoColourImpl s_instance; + return &s_instance; + } + }; + + } // anon namespace +} // namespace Catch + +#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) +# ifdef CATCH_PLATFORM_WINDOWS +# define CATCH_CONFIG_COLOUR_WINDOWS +# else +# define CATCH_CONFIG_COLOUR_ANSI +# endif +#endif + +#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// + +namespace Catch { +namespace { + + class Win32ColourImpl : public IColourImpl { + public: + Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) + { + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); + originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); + originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); + } + + void use( Colour::Code _colourCode ) override { + switch( _colourCode ) { + case Colour::None: return setTextAttribute( originalForegroundAttributes ); + case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + case Colour::Red: return setTextAttribute( FOREGROUND_RED ); + case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); + case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); + case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); + case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); + case Colour::Grey: return setTextAttribute( 0 ); + + case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); + case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); + case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); + case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN ); + + case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" ); + + default: + CATCH_ERROR( "Unknown colour requested" ); + } + } + + private: + void setTextAttribute( WORD _textAttribute ) { + SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); + } + HANDLE stdoutHandle; + WORD originalForegroundAttributes; + WORD originalBackgroundAttributes; + }; + + IColourImpl* platformColourInstance() { + static Win32ColourImpl s_instance; + + IConfigPtr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = UseColour::Yes; + return colourMode == UseColour::Yes + ? &s_instance + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// + +#include <unistd.h> + +namespace Catch { +namespace { + + // use POSIX/ ANSI console terminal codes + // Thanks to Adam Strzelecki for original contribution + // (http://github.com/nanoant) + // https://github.com/philsquared/Catch/pull/131 + class PosixColourImpl : public IColourImpl { + public: + void use( Colour::Code _colourCode ) override { + switch( _colourCode ) { + case Colour::None: + case Colour::White: return setColour( "[0m" ); + case Colour::Red: return setColour( "[0;31m" ); + case Colour::Green: return setColour( "[0;32m" ); + case Colour::Blue: return setColour( "[0;34m" ); + case Colour::Cyan: return setColour( "[0;36m" ); + case Colour::Yellow: return setColour( "[0;33m" ); + case Colour::Grey: return setColour( "[1;30m" ); + + case Colour::LightGrey: return setColour( "[0;37m" ); + case Colour::BrightRed: return setColour( "[1;31m" ); + case Colour::BrightGreen: return setColour( "[1;32m" ); + case Colour::BrightWhite: return setColour( "[1;37m" ); + case Colour::BrightYellow: return setColour( "[1;33m" ); + + case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" ); + default: CATCH_INTERNAL_ERROR( "Unknown colour requested" ); + } + } + static IColourImpl* instance() { + static PosixColourImpl s_instance; + return &s_instance; + } + + private: + void setColour( const char* _escapeCode ) { + getCurrentContext().getConfig()->stream() + << '\033' << _escapeCode; + } + }; + + bool useColourOnPlatform() { + return +#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE) + !isDebuggerActive() && +#endif +#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__)) + isatty(STDOUT_FILENO) +#else + false +#endif + ; + } + IColourImpl* platformColourInstance() { + ErrnoGuard guard; + IConfigPtr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = useColourOnPlatform() + ? UseColour::Yes + : UseColour::No; + return colourMode == UseColour::Yes + ? PosixColourImpl::instance() + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#else // not Windows or ANSI /////////////////////////////////////////////// + +namespace Catch { + + static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } + +} // end namespace Catch + +#endif // Windows/ ANSI/ None + +namespace Catch { + + Colour::Colour( Code _colourCode ) { use( _colourCode ); } + Colour::Colour( Colour&& other ) noexcept { + m_moved = other.m_moved; + other.m_moved = true; + } + Colour& Colour::operator=( Colour&& other ) noexcept { + m_moved = other.m_moved; + other.m_moved = true; + return *this; + } + + Colour::~Colour(){ if( !m_moved ) use( None ); } + + void Colour::use( Code _colourCode ) { + static IColourImpl* impl = platformColourInstance(); + // Strictly speaking, this cannot possibly happen. + // However, under some conditions it does happen (see #1626), + // and this change is small enough that we can let practicality + // triumph over purity in this case. + if (impl != nullptr) { + impl->use( _colourCode ); + } + } + + std::ostream& operator << ( std::ostream& os, Colour const& ) { + return os; + } + +} // end namespace Catch + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +// end catch_console_colour.cpp +// start catch_context.cpp + +namespace Catch { + + class Context : public IMutableContext, NonCopyable { + + public: // IContext + IResultCapture* getResultCapture() override { + return m_resultCapture; + } + IRunner* getRunner() override { + return m_runner; + } + + IConfigPtr const& getConfig() const override { + return m_config; + } + + ~Context() override; + + public: // IMutableContext + void setResultCapture( IResultCapture* resultCapture ) override { + m_resultCapture = resultCapture; + } + void setRunner( IRunner* runner ) override { + m_runner = runner; + } + void setConfig( IConfigPtr const& config ) override { + m_config = config; + } + + friend IMutableContext& getCurrentMutableContext(); + + private: + IConfigPtr m_config; + IRunner* m_runner = nullptr; + IResultCapture* m_resultCapture = nullptr; + }; + + IMutableContext *IMutableContext::currentContext = nullptr; + + void IMutableContext::createContext() + { + currentContext = new Context(); + } + + void cleanUpContext() { + delete IMutableContext::currentContext; + IMutableContext::currentContext = nullptr; + } + IContext::~IContext() = default; + IMutableContext::~IMutableContext() = default; + Context::~Context() = default; + + SimplePcg32& rng() { + static SimplePcg32 s_rng; + return s_rng; + } + +} +// end catch_context.cpp +// start catch_debug_console.cpp + +// start catch_debug_console.h + +#include <string> + +namespace Catch { + void writeToDebugConsole( std::string const& text ); +} + +// end catch_debug_console.h +#if defined(CATCH_CONFIG_ANDROID_LOGWRITE) +#include <android/log.h> + + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() ); + } + } + +#elif defined(CATCH_PLATFORM_WINDOWS) + + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + ::OutputDebugStringA( text.c_str() ); + } + } + +#else + + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + // !TBD: Need a version for Mac/ XCode and other IDEs + Catch::cout() << text; + } + } + +#endif // Platform +// end catch_debug_console.cpp +// start catch_debugger.cpp + +#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE) + +# include <cassert> +# include <sys/types.h> +# include <unistd.h> +# include <cstddef> +# include <ostream> + +#ifdef __apple_build_version__ + // These headers will only compile with AppleClang (XCode) + // For other compilers (Clang, GCC, ... ) we need to exclude them +# include <sys/sysctl.h> +#endif + + namespace Catch { + #ifdef __apple_build_version__ + // The following function is taken directly from the following technical note: + // https://developer.apple.com/library/archive/qa/qa1361/_index.html + + // Returns true if the current process is being debugged (either + // running under the debugger or has a debugger attached post facto). + bool isDebuggerActive(){ + int mib[4]; + struct kinfo_proc info; + std::size_t size; + + // Initialize the flags so that, if sysctl fails for some bizarre + // reason, we get a predictable result. + + info.kp_proc.p_flag = 0; + + // Initialize mib, which tells sysctl the info we want, in this case + // we're looking for information about a specific process ID. + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + // Call sysctl. + + size = sizeof(info); + if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) { + Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; + return false; + } + + // We're being debugged if the P_TRACED flag is set. + + return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); + } + #else + bool isDebuggerActive() { + // We need to find another way to determine this for non-appleclang compilers on macOS + return false; + } + #endif + } // namespace Catch + +#elif defined(CATCH_PLATFORM_LINUX) + #include <fstream> + #include <string> + + namespace Catch{ + // The standard POSIX way of detecting a debugger is to attempt to + // ptrace() the process, but this needs to be done from a child and not + // this process itself to still allow attaching to this process later + // if wanted, so is rather heavy. Under Linux we have the PID of the + // "debugger" (which doesn't need to be gdb, of course, it could also + // be strace, for example) in /proc/$PID/status, so just get it from + // there instead. + bool isDebuggerActive(){ + // Libstdc++ has a bug, where std::ifstream sets errno to 0 + // This way our users can properly assert over errno values + ErrnoGuard guard; + std::ifstream in("/proc/self/status"); + for( std::string line; std::getline(in, line); ) { + static const int PREFIX_LEN = 11; + if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) { + // We're traced if the PID is not 0 and no other PID starts + // with 0 digit, so it's enough to check for just a single + // character. + return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; + } + } + + return false; + } + } // namespace Catch +#elif defined(_MSC_VER) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#else + namespace Catch { + bool isDebuggerActive() { return false; } + } +#endif // Platform +// end catch_debugger.cpp +// start catch_decomposer.cpp + +namespace Catch { + + ITransientExpression::~ITransientExpression() = default; + + void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) { + if( lhs.size() + rhs.size() < 40 && + lhs.find('\n') == std::string::npos && + rhs.find('\n') == std::string::npos ) + os << lhs << " " << op << " " << rhs; + else + os << lhs << "\n" << op << "\n" << rhs; + } +} +// end catch_decomposer.cpp +// start catch_enforce.cpp + +#include <stdexcept> + +namespace Catch { +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER) + [[noreturn]] + void throw_exception(std::exception const& e) { + Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n" + << "The message was: " << e.what() << '\n'; + std::terminate(); + } +#endif + + [[noreturn]] + void throw_logic_error(std::string const& msg) { + throw_exception(std::logic_error(msg)); + } + + [[noreturn]] + void throw_domain_error(std::string const& msg) { + throw_exception(std::domain_error(msg)); + } + + [[noreturn]] + void throw_runtime_error(std::string const& msg) { + throw_exception(std::runtime_error(msg)); + } + +} // namespace Catch; +// end catch_enforce.cpp +// start catch_enum_values_registry.cpp +// start catch_enum_values_registry.h + +#include <vector> +#include <memory> + +namespace Catch { + + namespace Detail { + + std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ); + + class EnumValuesRegistry : public IMutableEnumValuesRegistry { + + std::vector<std::unique_ptr<EnumInfo>> m_enumInfos; + + EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override; + }; + + std::vector<StringRef> parseEnums( StringRef enums ); + + } // Detail + +} // Catch + +// end catch_enum_values_registry.h + +#include <map> +#include <cassert> + +namespace Catch { + + IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {} + + namespace Detail { + + namespace { + // Extracts the actual name part of an enum instance + // In other words, it returns the Blue part of Bikeshed::Colour::Blue + StringRef extractInstanceName(StringRef enumInstance) { + // Find last occurrence of ":" + size_t name_start = enumInstance.size(); + while (name_start > 0 && enumInstance[name_start - 1] != ':') { + --name_start; + } + return enumInstance.substr(name_start, enumInstance.size() - name_start); + } + } + + std::vector<StringRef> parseEnums( StringRef enums ) { + auto enumValues = splitStringRef( enums, ',' ); + std::vector<StringRef> parsed; + parsed.reserve( enumValues.size() ); + for( auto const& enumValue : enumValues ) { + parsed.push_back(trim(extractInstanceName(enumValue))); + } + return parsed; + } + + EnumInfo::~EnumInfo() {} + + StringRef EnumInfo::lookup( int value ) const { + for( auto const& valueToName : m_values ) { + if( valueToName.first == value ) + return valueToName.second; + } + return "{** unexpected enum value **}"_sr; + } + + std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) { + std::unique_ptr<EnumInfo> enumInfo( new EnumInfo ); + enumInfo->m_name = enumName; + enumInfo->m_values.reserve( values.size() ); + + const auto valueNames = Catch::Detail::parseEnums( allValueNames ); + assert( valueNames.size() == values.size() ); + std::size_t i = 0; + for( auto value : values ) + enumInfo->m_values.emplace_back(value, valueNames[i++]); + + return enumInfo; + } + + EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) { + m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values)); + return *m_enumInfos.back(); + } + + } // Detail +} // Catch + +// end catch_enum_values_registry.cpp +// start catch_errno_guard.cpp + +#include <cerrno> + +namespace Catch { + ErrnoGuard::ErrnoGuard():m_oldErrno(errno){} + ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; } +} +// end catch_errno_guard.cpp +// start catch_exception_translator_registry.cpp + +// start catch_exception_translator_registry.h + +#include <vector> +#include <string> +#include <memory> + +namespace Catch { + + class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { + public: + ~ExceptionTranslatorRegistry(); + virtual void registerTranslator( const IExceptionTranslator* translator ); + std::string translateActiveException() const override; + std::string tryTranslators() const; + + private: + std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators; + }; +} + +// end catch_exception_translator_registry.h +#ifdef __OBJC__ +#import "Foundation/Foundation.h" +#endif + +namespace Catch { + + ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() { + } + + void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) { + m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) ); + } + +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + std::string ExceptionTranslatorRegistry::translateActiveException() const { + try { +#ifdef __OBJC__ + // In Objective-C try objective-c exceptions first + @try { + return tryTranslators(); + } + @catch (NSException *exception) { + return Catch::Detail::stringify( [exception description] ); + } +#else + // Compiling a mixed mode project with MSVC means that CLR + // exceptions will be caught in (...) as well. However, these + // do not fill-in std::current_exception and thus lead to crash + // when attempting rethrow. + // /EHa switch also causes structured exceptions to be caught + // here, but they fill-in current_exception properly, so + // at worst the output should be a little weird, instead of + // causing a crash. + if (std::current_exception() == nullptr) { + return "Non C++ exception. Possibly a CLR exception."; + } + return tryTranslators(); +#endif + } + catch( TestFailureException& ) { + std::rethrow_exception(std::current_exception()); + } + catch( std::exception& ex ) { + return ex.what(); + } + catch( std::string& msg ) { + return msg; + } + catch( const char* msg ) { + return msg; + } + catch(...) { + return "Unknown exception"; + } + } + + std::string ExceptionTranslatorRegistry::tryTranslators() const { + if (m_translators.empty()) { + std::rethrow_exception(std::current_exception()); + } else { + return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end()); + } + } + +#else // ^^ Exceptions are enabled // Exceptions are disabled vv + std::string ExceptionTranslatorRegistry::translateActiveException() const { + CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!"); + } + + std::string ExceptionTranslatorRegistry::tryTranslators() const { + CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!"); + } +#endif + +} +// end catch_exception_translator_registry.cpp +// start catch_fatal_condition.cpp + +#include <algorithm> + +#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS ) + +namespace Catch { + + // If neither SEH nor signal handling is required, the handler impls + // do not have to do anything, and can be empty. + void FatalConditionHandler::engage_platform() {} + void FatalConditionHandler::disengage_platform() {} + FatalConditionHandler::FatalConditionHandler() = default; + FatalConditionHandler::~FatalConditionHandler() = default; + +} // end namespace Catch + +#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS + +#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS ) +#error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time" +#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS + +#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS ) + +namespace { + //! Signals fatal error message to the run context + void reportFatal( char const * const message ) { + Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message ); + } + + //! Minimal size Catch2 needs for its own fatal error handling. + //! Picked anecdotally, so it might not be sufficient on all + //! platforms, and for all configurations. + constexpr std::size_t minStackSizeForErrors = 32 * 1024; +} // end unnamed namespace + +#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS + +#if defined( CATCH_CONFIG_WINDOWS_SEH ) + +namespace Catch { + + struct SignalDefs { DWORD id; const char* name; }; + + // There is no 1-1 mapping between signals and windows exceptions. + // Windows can easily distinguish between SO and SigSegV, + // but SigInt, SigTerm, etc are handled differently. + static SignalDefs signalDefs[] = { + { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal" }, + { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" }, + { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" }, + { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" }, + }; + + static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { + for (auto const& def : signalDefs) { + if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) { + reportFatal(def.name); + } + } + // If its not an exception we care about, pass it along. + // This stops us from eating debugger breaks etc. + return EXCEPTION_CONTINUE_SEARCH; + } + + // Since we do not support multiple instantiations, we put these + // into global variables and rely on cleaning them up in outlined + // constructors/destructors + static PVOID exceptionHandlerHandle = nullptr; + + // For MSVC, we reserve part of the stack memory for handling + // memory overflow structured exception. + FatalConditionHandler::FatalConditionHandler() { + ULONG guaranteeSize = static_cast<ULONG>(minStackSizeForErrors); + if (!SetThreadStackGuarantee(&guaranteeSize)) { + // We do not want to fully error out, because needing + // the stack reserve should be rare enough anyway. + Catch::cerr() + << "Failed to reserve piece of stack." + << " Stack overflows will not be reported successfully."; + } + } + + // We do not attempt to unset the stack guarantee, because + // Windows does not support lowering the stack size guarantee. + FatalConditionHandler::~FatalConditionHandler() = default; + + void FatalConditionHandler::engage_platform() { + // Register as first handler in current chain + exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); + if (!exceptionHandlerHandle) { + CATCH_RUNTIME_ERROR("Could not register vectored exception handler"); + } + } + + void FatalConditionHandler::disengage_platform() { + if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) { + CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler"); + } + exceptionHandlerHandle = nullptr; + } + +} // end namespace Catch + +#endif // CATCH_CONFIG_WINDOWS_SEH + +#if defined( CATCH_CONFIG_POSIX_SIGNALS ) + +#include <signal.h> + +namespace Catch { + + struct SignalDefs { + int id; + const char* name; + }; + + static SignalDefs signalDefs[] = { + { SIGINT, "SIGINT - Terminal interrupt signal" }, + { SIGILL, "SIGILL - Illegal instruction signal" }, + { SIGFPE, "SIGFPE - Floating point error signal" }, + { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, + { SIGTERM, "SIGTERM - Termination request signal" }, + { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } + }; + +// Older GCCs trigger -Wmissing-field-initializers for T foo = {} +// which is zero initialization, but not explicit. We want to avoid +// that. +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + + static char* altStackMem = nullptr; + static std::size_t altStackSize = 0; + static stack_t oldSigStack{}; + static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{}; + + static void restorePreviousSignalHandlers() { + // We set signal handlers back to the previous ones. Hopefully + // nobody overwrote them in the meantime, and doesn't expect + // their signal handlers to live past ours given that they + // installed them after ours.. + for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { + sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); + } + // Return the old stack + sigaltstack(&oldSigStack, nullptr); + } + + static void handleSignal( int sig ) { + char const * name = "<unknown signal>"; + for (auto const& def : signalDefs) { + if (sig == def.id) { + name = def.name; + break; + } + } + // We need to restore previous signal handlers and let them do + // their thing, so that the users can have the debugger break + // when a signal is raised, and so on. + restorePreviousSignalHandlers(); + reportFatal( name ); + raise( sig ); + } + + FatalConditionHandler::FatalConditionHandler() { + assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists"); + if (altStackSize == 0) { + altStackSize = std::max(static_cast<size_t>(SIGSTKSZ), minStackSizeForErrors); + } + altStackMem = new char[altStackSize](); + } + + FatalConditionHandler::~FatalConditionHandler() { + delete[] altStackMem; + // We signal that another instance can be constructed by zeroing + // out the pointer. + altStackMem = nullptr; + } + + void FatalConditionHandler::engage_platform() { + stack_t sigStack; + sigStack.ss_sp = altStackMem; + sigStack.ss_size = altStackSize; + sigStack.ss_flags = 0; + sigaltstack(&sigStack, &oldSigStack); + struct sigaction sa = { }; + + sa.sa_handler = handleSignal; + sa.sa_flags = SA_ONSTACK; + for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { + sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); + } + } + +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif + + void FatalConditionHandler::disengage_platform() { + restorePreviousSignalHandlers(); + } + +} // end namespace Catch + +#endif // CATCH_CONFIG_POSIX_SIGNALS +// end catch_fatal_condition.cpp +// start catch_generators.cpp + +#include <limits> +#include <set> + +namespace Catch { + +IGeneratorTracker::~IGeneratorTracker() {} + +const char* GeneratorException::what() const noexcept { + return m_msg; +} + +namespace Generators { + + GeneratorUntypedBase::~GeneratorUntypedBase() {} + + auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { + return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo ); + } + +} // namespace Generators +} // namespace Catch +// end catch_generators.cpp +// start catch_interfaces_capture.cpp + +namespace Catch { + IResultCapture::~IResultCapture() = default; +} +// end catch_interfaces_capture.cpp +// start catch_interfaces_config.cpp + +namespace Catch { + IConfig::~IConfig() = default; +} +// end catch_interfaces_config.cpp +// start catch_interfaces_exception.cpp + +namespace Catch { + IExceptionTranslator::~IExceptionTranslator() = default; + IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default; +} +// end catch_interfaces_exception.cpp +// start catch_interfaces_registry_hub.cpp + +namespace Catch { + IRegistryHub::~IRegistryHub() = default; + IMutableRegistryHub::~IMutableRegistryHub() = default; +} +// end catch_interfaces_registry_hub.cpp +// start catch_interfaces_reporter.cpp + +// start catch_reporter_listening.h + +namespace Catch { + + class ListeningReporter : public IStreamingReporter { + using Reporters = std::vector<IStreamingReporterPtr>; + Reporters m_listeners; + IStreamingReporterPtr m_reporter = nullptr; + ReporterPreferences m_preferences; + + public: + ListeningReporter(); + + void addListener( IStreamingReporterPtr&& listener ); + void addReporter( IStreamingReporterPtr&& reporter ); + + public: // IStreamingReporter + + ReporterPreferences getPreferences() const override; + + void noMatchingTestCases( std::string const& spec ) override; + + void reportInvalidArguments(std::string const&arg) override; + + static std::set<Verbosity> getSupportedVerbosities(); + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + void benchmarkPreparing(std::string const& name) override; + void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override; + void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override; + void benchmarkFailed(std::string const&) override; +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + + void testRunStarting( TestRunInfo const& testRunInfo ) override; + void testGroupStarting( GroupInfo const& groupInfo ) override; + void testCaseStarting( TestCaseInfo const& testInfo ) override; + void sectionStarting( SectionInfo const& sectionInfo ) override; + void assertionStarting( AssertionInfo const& assertionInfo ) override; + + // The return value indicates if the messages buffer should be cleared: + bool assertionEnded( AssertionStats const& assertionStats ) override; + void sectionEnded( SectionStats const& sectionStats ) override; + void testCaseEnded( TestCaseStats const& testCaseStats ) override; + void testGroupEnded( TestGroupStats const& testGroupStats ) override; + void testRunEnded( TestRunStats const& testRunStats ) override; + + void skipTest( TestCaseInfo const& testInfo ) override; + bool isMulti() const override; + + }; + +} // end namespace Catch + +// end catch_reporter_listening.h +namespace Catch { + + ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig ) + : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} + + ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream ) + : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} + + std::ostream& ReporterConfig::stream() const { return *m_stream; } + IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; } + + TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {} + + GroupInfo::GroupInfo( std::string const& _name, + std::size_t _groupIndex, + std::size_t _groupsCount ) + : name( _name ), + groupIndex( _groupIndex ), + groupsCounts( _groupsCount ) + {} + + AssertionStats::AssertionStats( AssertionResult const& _assertionResult, + std::vector<MessageInfo> const& _infoMessages, + Totals const& _totals ) + : assertionResult( _assertionResult ), + infoMessages( _infoMessages ), + totals( _totals ) + { + assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression; + + if( assertionResult.hasMessage() ) { + // Copy message into messages list. + // !TBD This should have been done earlier, somewhere + MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); + builder << assertionResult.getMessage(); + builder.m_info.message = builder.m_stream.str(); + + infoMessages.push_back( builder.m_info ); + } + } + + AssertionStats::~AssertionStats() = default; + + SectionStats::SectionStats( SectionInfo const& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ) + : sectionInfo( _sectionInfo ), + assertions( _assertions ), + durationInSeconds( _durationInSeconds ), + missingAssertions( _missingAssertions ) + {} + + SectionStats::~SectionStats() = default; + + TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string const& _stdOut, + std::string const& _stdErr, + bool _aborting ) + : testInfo( _testInfo ), + totals( _totals ), + stdOut( _stdOut ), + stdErr( _stdErr ), + aborting( _aborting ) + {} + + TestCaseStats::~TestCaseStats() = default; + + TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo, + Totals const& _totals, + bool _aborting ) + : groupInfo( _groupInfo ), + totals( _totals ), + aborting( _aborting ) + {} + + TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo ) + : groupInfo( _groupInfo ), + aborting( false ) + {} + + TestGroupStats::~TestGroupStats() = default; + + TestRunStats::TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ) + : runInfo( _runInfo ), + totals( _totals ), + aborting( _aborting ) + {} + + TestRunStats::~TestRunStats() = default; + + void IStreamingReporter::fatalErrorEncountered( StringRef ) {} + bool IStreamingReporter::isMulti() const { return false; } + + IReporterFactory::~IReporterFactory() = default; + IReporterRegistry::~IReporterRegistry() = default; + +} // end namespace Catch +// end catch_interfaces_reporter.cpp +// start catch_interfaces_runner.cpp + +namespace Catch { + IRunner::~IRunner() = default; +} +// end catch_interfaces_runner.cpp +// start catch_interfaces_testcase.cpp + +namespace Catch { + ITestInvoker::~ITestInvoker() = default; + ITestCaseRegistry::~ITestCaseRegistry() = default; +} +// end catch_interfaces_testcase.cpp +// start catch_leak_detector.cpp + +#ifdef CATCH_CONFIG_WINDOWS_CRTDBG +#include <crtdbg.h> + +namespace Catch { + + LeakDetector::LeakDetector() { + int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + flag |= _CRTDBG_LEAK_CHECK_DF; + flag |= _CRTDBG_ALLOC_MEM_DF; + _CrtSetDbgFlag(flag); + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + // Change this to leaking allocation's number to break there + _CrtSetBreakAlloc(-1); + } +} + +#else + + Catch::LeakDetector::LeakDetector() {} + +#endif + +Catch::LeakDetector::~LeakDetector() { + Catch::cleanUp(); +} +// end catch_leak_detector.cpp +// start catch_list.cpp + +// start catch_list.h + +#include <set> + +namespace Catch { + + std::size_t listTests( Config const& config ); + + std::size_t listTestsNamesOnly( Config const& config ); + + struct TagInfo { + void add( std::string const& spelling ); + std::string all() const; + + std::set<std::string> spellings; + std::size_t count = 0; + }; + + std::size_t listTags( Config const& config ); + + std::size_t listReporters(); + + Option<std::size_t> list( std::shared_ptr<Config> const& config ); + +} // end namespace Catch + +// end catch_list.h +// start catch_text.h + +namespace Catch { + using namespace clara::TextFlow; +} + +// end catch_text.h +#include <limits> +#include <algorithm> +#include <iomanip> + +namespace Catch { + + std::size_t listTests( Config const& config ) { + TestSpec const& testSpec = config.testSpec(); + if( config.hasTestFilters() ) + Catch::cout() << "Matching test cases:\n"; + else { + Catch::cout() << "All available test cases:\n"; + } + + auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( auto const& testCaseInfo : matchedTestCases ) { + Colour::Code colour = testCaseInfo.isHidden() + ? Colour::SecondaryText + : Colour::None; + Colour colourGuard( colour ); + + Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n"; + if( config.verbosity() >= Verbosity::High ) { + Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl; + std::string description = testCaseInfo.description; + if( description.empty() ) + description = "(NO DESCRIPTION)"; + Catch::cout() << Column( description ).indent(4) << std::endl; + } + if( !testCaseInfo.tags.empty() ) + Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n"; + } + + if( !config.hasTestFilters() ) + Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl; + else + Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl; + return matchedTestCases.size(); + } + + std::size_t listTestsNamesOnly( Config const& config ) { + TestSpec const& testSpec = config.testSpec(); + std::size_t matchedTests = 0; + std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( auto const& testCaseInfo : matchedTestCases ) { + matchedTests++; + if( startsWith( testCaseInfo.name, '#' ) ) + Catch::cout() << '"' << testCaseInfo.name << '"'; + else + Catch::cout() << testCaseInfo.name; + if ( config.verbosity() >= Verbosity::High ) + Catch::cout() << "\t@" << testCaseInfo.lineInfo; + Catch::cout() << std::endl; + } + return matchedTests; + } + + void TagInfo::add( std::string const& spelling ) { + ++count; + spellings.insert( spelling ); + } + + std::string TagInfo::all() const { + size_t size = 0; + for (auto const& spelling : spellings) { + // Add 2 for the brackes + size += spelling.size() + 2; + } + + std::string out; out.reserve(size); + for (auto const& spelling : spellings) { + out += '['; + out += spelling; + out += ']'; + } + return out; + } + + std::size_t listTags( Config const& config ) { + TestSpec const& testSpec = config.testSpec(); + if( config.hasTestFilters() ) + Catch::cout() << "Tags for matching test cases:\n"; + else { + Catch::cout() << "All available tags:\n"; + } + + std::map<std::string, TagInfo> tagCounts; + + std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( auto const& testCase : matchedTestCases ) { + for( auto const& tagName : testCase.getTestCaseInfo().tags ) { + std::string lcaseTagName = toLower( tagName ); + auto countIt = tagCounts.find( lcaseTagName ); + if( countIt == tagCounts.end() ) + countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; + countIt->second.add( tagName ); + } + } + + for( auto const& tagCount : tagCounts ) { + ReusableStringStream rss; + rss << " " << std::setw(2) << tagCount.second.count << " "; + auto str = rss.str(); + auto wrapper = Column( tagCount.second.all() ) + .initialIndent( 0 ) + .indent( str.size() ) + .width( CATCH_CONFIG_CONSOLE_WIDTH-10 ); + Catch::cout() << str << wrapper << '\n'; + } + Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; + return tagCounts.size(); + } + + std::size_t listReporters() { + Catch::cout() << "Available reporters:\n"; + IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); + std::size_t maxNameLen = 0; + for( auto const& factoryKvp : factories ) + maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() ); + + for( auto const& factoryKvp : factories ) { + Catch::cout() + << Column( factoryKvp.first + ":" ) + .indent(2) + .width( 5+maxNameLen ) + + Column( factoryKvp.second->getDescription() ) + .initialIndent(0) + .indent(2) + .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) + << "\n"; + } + Catch::cout() << std::endl; + return factories.size(); + } + + Option<std::size_t> list( std::shared_ptr<Config> const& config ) { + Option<std::size_t> listedCount; + getCurrentMutableContext().setConfig( config ); + if( config->listTests() ) + listedCount = listedCount.valueOr(0) + listTests( *config ); + if( config->listTestNamesOnly() ) + listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config ); + if( config->listTags() ) + listedCount = listedCount.valueOr(0) + listTags( *config ); + if( config->listReporters() ) + listedCount = listedCount.valueOr(0) + listReporters(); + return listedCount; + } + +} // end namespace Catch +// end catch_list.cpp +// start catch_matchers.cpp + +namespace Catch { +namespace Matchers { + namespace Impl { + + std::string MatcherUntypedBase::toString() const { + if( m_cachedToString.empty() ) + m_cachedToString = describe(); + return m_cachedToString; + } + + MatcherUntypedBase::~MatcherUntypedBase() = default; + + } // namespace Impl +} // namespace Matchers + +using namespace Matchers; +using Matchers::Impl::MatcherBase; + +} // namespace Catch +// end catch_matchers.cpp +// start catch_matchers_exception.cpp + +namespace Catch { +namespace Matchers { +namespace Exception { + +bool ExceptionMessageMatcher::match(std::exception const& ex) const { + return ex.what() == m_message; +} + +std::string ExceptionMessageMatcher::describe() const { + return "exception message matches \"" + m_message + "\""; +} + +} +Exception::ExceptionMessageMatcher Message(std::string const& message) { + return Exception::ExceptionMessageMatcher(message); +} + +// namespace Exception +} // namespace Matchers +} // namespace Catch +// end catch_matchers_exception.cpp +// start catch_matchers_floating.cpp + +// start catch_polyfills.hpp + +namespace Catch { + bool isnan(float f); + bool isnan(double d); +} + +// end catch_polyfills.hpp +// start catch_to_string.hpp + +#include <string> + +namespace Catch { + template <typename T> + std::string to_string(T const& t) { +#if defined(CATCH_CONFIG_CPP11_TO_STRING) + return std::to_string(t); +#else + ReusableStringStream rss; + rss << t; + return rss.str(); +#endif + } +} // end namespace Catch + +// end catch_to_string.hpp +#include <algorithm> +#include <cmath> +#include <cstdlib> +#include <cstdint> +#include <cstring> +#include <sstream> +#include <type_traits> +#include <iomanip> +#include <limits> + +namespace Catch { +namespace { + + int32_t convert(float f) { + static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated"); + int32_t i; + std::memcpy(&i, &f, sizeof(f)); + return i; + } + + int64_t convert(double d) { + static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated"); + int64_t i; + std::memcpy(&i, &d, sizeof(d)); + return i; + } + + template <typename FP> + bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) { + // Comparison with NaN should always be false. + // This way we can rule it out before getting into the ugly details + if (Catch::isnan(lhs) || Catch::isnan(rhs)) { + return false; + } + + auto lc = convert(lhs); + auto rc = convert(rhs); + + if ((lc < 0) != (rc < 0)) { + // Potentially we can have +0 and -0 + return lhs == rhs; + } + + // static cast as a workaround for IBM XLC + auto ulpDiff = std::abs(static_cast<FP>(lc - rc)); + return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff; + } + +#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) + + float nextafter(float x, float y) { + return ::nextafterf(x, y); + } + + double nextafter(double x, double y) { + return ::nextafter(x, y); + } + +#endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^ + +template <typename FP> +FP step(FP start, FP direction, uint64_t steps) { + for (uint64_t i = 0; i < steps; ++i) { +#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) + start = Catch::nextafter(start, direction); +#else + start = std::nextafter(start, direction); +#endif + } + return start; +} + +// Performs equivalent check of std::fabs(lhs - rhs) <= margin +// But without the subtraction to allow for INFINITY in comparison +bool marginComparison(double lhs, double rhs, double margin) { + return (lhs + margin >= rhs) && (rhs + margin >= lhs); +} + +template <typename FloatingPoint> +void write(std::ostream& out, FloatingPoint num) { + out << std::scientific + << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1) + << num; +} + +} // end anonymous namespace + +namespace Matchers { +namespace Floating { + + enum class FloatingPointKind : uint8_t { + Float, + Double + }; + + WithinAbsMatcher::WithinAbsMatcher(double target, double margin) + :m_target{ target }, m_margin{ margin } { + CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.' + << " Margin has to be non-negative."); + } + + // Performs equivalent check of std::fabs(lhs - rhs) <= margin + // But without the subtraction to allow for INFINITY in comparison + bool WithinAbsMatcher::match(double const& matchee) const { + return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee); + } + + std::string WithinAbsMatcher::describe() const { + return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target); + } + + WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType) + :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } { + CATCH_ENFORCE(m_type == FloatingPointKind::Double + || m_ulps < (std::numeric_limits<uint32_t>::max)(), + "Provided ULP is impossibly large for a float comparison."); + } + +#if defined(__clang__) +#pragma clang diagnostic push +// Clang <3.5 reports on the default branch in the switch below +#pragma clang diagnostic ignored "-Wunreachable-code" +#endif + + bool WithinUlpsMatcher::match(double const& matchee) const { + switch (m_type) { + case FloatingPointKind::Float: + return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps); + case FloatingPointKind::Double: + return almostEqualUlps<double>(matchee, m_target, m_ulps); + default: + CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" ); + } + } + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + + std::string WithinUlpsMatcher::describe() const { + std::stringstream ret; + + ret << "is within " << m_ulps << " ULPs of "; + + if (m_type == FloatingPointKind::Float) { + write(ret, static_cast<float>(m_target)); + ret << 'f'; + } else { + write(ret, m_target); + } + + ret << " (["; + if (m_type == FloatingPointKind::Double) { + write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps)); + ret << ", "; + write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps)); + } else { + // We have to cast INFINITY to float because of MinGW, see #1782 + write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps)); + ret << ", "; + write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps)); + } + ret << "])"; + + return ret.str(); + } + + WithinRelMatcher::WithinRelMatcher(double target, double epsilon): + m_target(target), + m_epsilon(epsilon){ + CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon < 0 does not make sense."); + CATCH_ENFORCE(m_epsilon < 1., "Relative comparison with epsilon >= 1 does not make sense."); + } + + bool WithinRelMatcher::match(double const& matchee) const { + const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target)); + return marginComparison(matchee, m_target, + std::isinf(relMargin)? 0 : relMargin); + } + + std::string WithinRelMatcher::describe() const { + Catch::ReusableStringStream sstr; + sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other"; + return sstr.str(); + } + +}// namespace Floating + +Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) { + return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double); +} + +Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) { + return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float); +} + +Floating::WithinAbsMatcher WithinAbs(double target, double margin) { + return Floating::WithinAbsMatcher(target, margin); +} + +Floating::WithinRelMatcher WithinRel(double target, double eps) { + return Floating::WithinRelMatcher(target, eps); +} + +Floating::WithinRelMatcher WithinRel(double target) { + return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100); +} + +Floating::WithinRelMatcher WithinRel(float target, float eps) { + return Floating::WithinRelMatcher(target, eps); +} + +Floating::WithinRelMatcher WithinRel(float target) { + return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100); +} + +} // namespace Matchers +} // namespace Catch +// end catch_matchers_floating.cpp +// start catch_matchers_generic.cpp + +std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) { + if (desc.empty()) { + return "matches undescribed predicate"; + } else { + return "matches predicate: \"" + desc + '"'; + } +} +// end catch_matchers_generic.cpp +// start catch_matchers_string.cpp + +#include <regex> + +namespace Catch { +namespace Matchers { + + namespace StdString { + + CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_str( adjustString( str ) ) + {} + std::string CasedString::adjustString( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No + ? toLower( str ) + : str; + } + std::string CasedString::caseSensitivitySuffix() const { + return m_caseSensitivity == CaseSensitive::No + ? " (case insensitive)" + : std::string(); + } + + StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator ) + : m_comparator( comparator ), + m_operation( operation ) { + } + + std::string StringMatcherBase::describe() const { + std::string description; + description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + + m_comparator.caseSensitivitySuffix().size()); + description += m_operation; + description += ": \""; + description += m_comparator.m_str; + description += "\""; + description += m_comparator.caseSensitivitySuffix(); + return description; + } + + EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {} + + bool EqualsMatcher::match( std::string const& source ) const { + return m_comparator.adjustString( source ) == m_comparator.m_str; + } + + ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {} + + bool ContainsMatcher::match( std::string const& source ) const { + return contains( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {} + + bool StartsWithMatcher::match( std::string const& source ) const { + return startsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {} + + bool EndsWithMatcher::match( std::string const& source ) const { + return endsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {} + + bool RegexMatcher::match(std::string const& matchee) const { + auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway + if (m_caseSensitivity == CaseSensitive::Choice::No) { + flags |= std::regex::icase; + } + auto reg = std::regex(m_regex, flags); + return std::regex_match(matchee, reg); + } + + std::string RegexMatcher::describe() const { + return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively"); + } + + } // namespace StdString + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + + StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) { + return StdString::RegexMatcher(regex, caseSensitivity); + } + +} // namespace Matchers +} // namespace Catch +// end catch_matchers_string.cpp +// start catch_message.cpp + +// start catch_uncaught_exceptions.h + +namespace Catch { + bool uncaught_exceptions(); +} // end namespace Catch + +// end catch_uncaught_exceptions.h +#include <cassert> +#include <stack> + +namespace Catch { + + MessageInfo::MessageInfo( StringRef const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + type( _type ), + sequence( ++globalCount ) + {} + + bool MessageInfo::operator==( MessageInfo const& other ) const { + return sequence == other.sequence; + } + + bool MessageInfo::operator<( MessageInfo const& other ) const { + return sequence < other.sequence; + } + + // This may need protecting if threading support is added + unsigned int MessageInfo::globalCount = 0; + + //////////////////////////////////////////////////////////////////////////// + + Catch::MessageBuilder::MessageBuilder( StringRef const& macroName, + SourceLineInfo const& lineInfo, + ResultWas::OfType type ) + :m_info(macroName, lineInfo, type) {} + + //////////////////////////////////////////////////////////////////////////// + + ScopedMessage::ScopedMessage( MessageBuilder const& builder ) + : m_info( builder.m_info ), m_moved() + { + m_info.message = builder.m_stream.str(); + getResultCapture().pushScopedMessage( m_info ); + } + + ScopedMessage::ScopedMessage( ScopedMessage&& old ) + : m_info( old.m_info ), m_moved() + { + old.m_moved = true; + } + + ScopedMessage::~ScopedMessage() { + if ( !uncaught_exceptions() && !m_moved ){ + getResultCapture().popScopedMessage(m_info); + } + } + + Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) { + auto trimmed = [&] (size_t start, size_t end) { + while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) { + ++start; + } + while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) { + --end; + } + return names.substr(start, end - start + 1); + }; + auto skipq = [&] (size_t start, char quote) { + for (auto i = start + 1; i < names.size() ; ++i) { + if (names[i] == quote) + return i; + if (names[i] == '\\') + ++i; + } + CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote"); + }; + + size_t start = 0; + std::stack<char> openings; + for (size_t pos = 0; pos < names.size(); ++pos) { + char c = names[pos]; + switch (c) { + case '[': + case '{': + case '(': + // It is basically impossible to disambiguate between + // comparison and start of template args in this context +// case '<': + openings.push(c); + break; + case ']': + case '}': + case ')': +// case '>': + openings.pop(); + break; + case '"': + case '\'': + pos = skipq(pos, c); + break; + case ',': + if (start != pos && openings.empty()) { + m_messages.emplace_back(macroName, lineInfo, resultType); + m_messages.back().message = static_cast<std::string>(trimmed(start, pos)); + m_messages.back().message += " := "; + start = pos; + } + } + } + assert(openings.empty() && "Mismatched openings"); + m_messages.emplace_back(macroName, lineInfo, resultType); + m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1)); + m_messages.back().message += " := "; + } + Capturer::~Capturer() { + if ( !uncaught_exceptions() ){ + assert( m_captured == m_messages.size() ); + for( size_t i = 0; i < m_captured; ++i ) + m_resultCapture.popScopedMessage( m_messages[i] ); + } + } + + void Capturer::captureValue( size_t index, std::string const& value ) { + assert( index < m_messages.size() ); + m_messages[index].message += value; + m_resultCapture.pushScopedMessage( m_messages[index] ); + m_captured++; + } + +} // end namespace Catch +// end catch_message.cpp +// start catch_output_redirect.cpp + +// start catch_output_redirect.h +#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H +#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H + +#include <cstdio> +#include <iosfwd> +#include <string> + +namespace Catch { + + class RedirectedStream { + std::ostream& m_originalStream; + std::ostream& m_redirectionStream; + std::streambuf* m_prevBuf; + + public: + RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ); + ~RedirectedStream(); + }; + + class RedirectedStdOut { + ReusableStringStream m_rss; + RedirectedStream m_cout; + public: + RedirectedStdOut(); + auto str() const -> std::string; + }; + + // StdErr has two constituent streams in C++, std::cerr and std::clog + // This means that we need to redirect 2 streams into 1 to keep proper + // order of writes + class RedirectedStdErr { + ReusableStringStream m_rss; + RedirectedStream m_cerr; + RedirectedStream m_clog; + public: + RedirectedStdErr(); + auto str() const -> std::string; + }; + + class RedirectedStreams { + public: + RedirectedStreams(RedirectedStreams const&) = delete; + RedirectedStreams& operator=(RedirectedStreams const&) = delete; + RedirectedStreams(RedirectedStreams&&) = delete; + RedirectedStreams& operator=(RedirectedStreams&&) = delete; + + RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr); + ~RedirectedStreams(); + private: + std::string& m_redirectedCout; + std::string& m_redirectedCerr; + RedirectedStdOut m_redirectedStdOut; + RedirectedStdErr m_redirectedStdErr; + }; + +#if defined(CATCH_CONFIG_NEW_CAPTURE) + + // Windows's implementation of std::tmpfile is terrible (it tries + // to create a file inside system folder, thus requiring elevated + // privileges for the binary), so we have to use tmpnam(_s) and + // create the file ourselves there. + class TempFile { + public: + TempFile(TempFile const&) = delete; + TempFile& operator=(TempFile const&) = delete; + TempFile(TempFile&&) = delete; + TempFile& operator=(TempFile&&) = delete; + + TempFile(); + ~TempFile(); + + std::FILE* getFile(); + std::string getContents(); + + private: + std::FILE* m_file = nullptr; + #if defined(_MSC_VER) + char m_buffer[L_tmpnam] = { 0 }; + #endif + }; + + class OutputRedirect { + public: + OutputRedirect(OutputRedirect const&) = delete; + OutputRedirect& operator=(OutputRedirect const&) = delete; + OutputRedirect(OutputRedirect&&) = delete; + OutputRedirect& operator=(OutputRedirect&&) = delete; + + OutputRedirect(std::string& stdout_dest, std::string& stderr_dest); + ~OutputRedirect(); + + private: + int m_originalStdout = -1; + int m_originalStderr = -1; + TempFile m_stdoutFile; + TempFile m_stderrFile; + std::string& m_stdoutDest; + std::string& m_stderrDest; + }; + +#endif + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H +// end catch_output_redirect.h +#include <cstdio> +#include <cstring> +#include <fstream> +#include <sstream> +#include <stdexcept> + +#if defined(CATCH_CONFIG_NEW_CAPTURE) + #if defined(_MSC_VER) + #include <io.h> //_dup and _dup2 + #define dup _dup + #define dup2 _dup2 + #define fileno _fileno + #else + #include <unistd.h> // dup and dup2 + #endif +#endif + +namespace Catch { + + RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ) + : m_originalStream( originalStream ), + m_redirectionStream( redirectionStream ), + m_prevBuf( m_originalStream.rdbuf() ) + { + m_originalStream.rdbuf( m_redirectionStream.rdbuf() ); + } + + RedirectedStream::~RedirectedStream() { + m_originalStream.rdbuf( m_prevBuf ); + } + + RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {} + auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); } + + RedirectedStdErr::RedirectedStdErr() + : m_cerr( Catch::cerr(), m_rss.get() ), + m_clog( Catch::clog(), m_rss.get() ) + {} + auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); } + + RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr) + : m_redirectedCout(redirectedCout), + m_redirectedCerr(redirectedCerr) + {} + + RedirectedStreams::~RedirectedStreams() { + m_redirectedCout += m_redirectedStdOut.str(); + m_redirectedCerr += m_redirectedStdErr.str(); + } + +#if defined(CATCH_CONFIG_NEW_CAPTURE) + +#if defined(_MSC_VER) + TempFile::TempFile() { + if (tmpnam_s(m_buffer)) { + CATCH_RUNTIME_ERROR("Could not get a temp filename"); + } + if (fopen_s(&m_file, m_buffer, "w+")) { + char buffer[100]; + if (strerror_s(buffer, errno)) { + CATCH_RUNTIME_ERROR("Could not translate errno to a string"); + } + CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer); + } + } +#else + TempFile::TempFile() { + m_file = std::tmpfile(); + if (!m_file) { + CATCH_RUNTIME_ERROR("Could not create a temp file."); + } + } + +#endif + + TempFile::~TempFile() { + // TBD: What to do about errors here? + std::fclose(m_file); + // We manually create the file on Windows only, on Linux + // it will be autodeleted +#if defined(_MSC_VER) + std::remove(m_buffer); +#endif + } + + FILE* TempFile::getFile() { + return m_file; + } + + std::string TempFile::getContents() { + std::stringstream sstr; + char buffer[100] = {}; + std::rewind(m_file); + while (std::fgets(buffer, sizeof(buffer), m_file)) { + sstr << buffer; + } + return sstr.str(); + } + + OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) : + m_originalStdout(dup(1)), + m_originalStderr(dup(2)), + m_stdoutDest(stdout_dest), + m_stderrDest(stderr_dest) { + dup2(fileno(m_stdoutFile.getFile()), 1); + dup2(fileno(m_stderrFile.getFile()), 2); + } + + OutputRedirect::~OutputRedirect() { + Catch::cout() << std::flush; + fflush(stdout); + // Since we support overriding these streams, we flush cerr + // even though std::cerr is unbuffered + Catch::cerr() << std::flush; + Catch::clog() << std::flush; + fflush(stderr); + + dup2(m_originalStdout, 1); + dup2(m_originalStderr, 2); + + m_stdoutDest += m_stdoutFile.getContents(); + m_stderrDest += m_stderrFile.getContents(); + } + +#endif // CATCH_CONFIG_NEW_CAPTURE + +} // namespace Catch + +#if defined(CATCH_CONFIG_NEW_CAPTURE) + #if defined(_MSC_VER) + #undef dup + #undef dup2 + #undef fileno + #endif +#endif +// end catch_output_redirect.cpp +// start catch_polyfills.cpp + +#include <cmath> + +namespace Catch { + +#if !defined(CATCH_CONFIG_POLYFILL_ISNAN) + bool isnan(float f) { + return std::isnan(f); + } + bool isnan(double d) { + return std::isnan(d); + } +#else + // For now we only use this for embarcadero + bool isnan(float f) { + return std::_isnan(f); + } + bool isnan(double d) { + return std::_isnan(d); + } +#endif + +} // end namespace Catch +// end catch_polyfills.cpp +// start catch_random_number_generator.cpp + +namespace Catch { + +namespace { + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4146) // we negate uint32 during the rotate +#endif + // Safe rotr implementation thanks to John Regehr + uint32_t rotate_right(uint32_t val, uint32_t count) { + const uint32_t mask = 31; + count &= mask; + return (val >> count) | (val << (-count & mask)); + } + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +} + + SimplePcg32::SimplePcg32(result_type seed_) { + seed(seed_); + } + + void SimplePcg32::seed(result_type seed_) { + m_state = 0; + (*this)(); + m_state += seed_; + (*this)(); + } + + void SimplePcg32::discard(uint64_t skip) { + // We could implement this to run in O(log n) steps, but this + // should suffice for our use case. + for (uint64_t s = 0; s < skip; ++s) { + static_cast<void>((*this)()); + } + } + + SimplePcg32::result_type SimplePcg32::operator()() { + // prepare the output value + const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u); + const auto output = rotate_right(xorshifted, m_state >> 59u); + + // advance state + m_state = m_state * 6364136223846793005ULL + s_inc; + + return output; + } + + bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) { + return lhs.m_state == rhs.m_state; + } + + bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) { + return lhs.m_state != rhs.m_state; + } +} +// end catch_random_number_generator.cpp +// start catch_registry_hub.cpp + +// start catch_test_case_registry_impl.h + +#include <vector> +#include <set> +#include <algorithm> +#include <ios> + +namespace Catch { + + class TestCase; + struct IConfig; + + std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ); + + bool isThrowSafe( TestCase const& testCase, IConfig const& config ); + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + + void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ); + + std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ); + + class TestRegistry : public ITestCaseRegistry { + public: + virtual ~TestRegistry() = default; + + virtual void registerTest( TestCase const& testCase ); + + std::vector<TestCase> const& getAllTests() const override; + std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override; + + private: + std::vector<TestCase> m_functions; + mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder; + mutable std::vector<TestCase> m_sortedFunctions; + std::size_t m_unnamedCount = 0; + std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised + }; + + /////////////////////////////////////////////////////////////////////////// + + class TestInvokerAsFunction : public ITestInvoker { + void(*m_testAsFunction)(); + public: + TestInvokerAsFunction( void(*testAsFunction)() ) noexcept; + + void invoke() const override; + }; + + std::string extractClassName( StringRef const& classOrQualifiedMethodName ); + + /////////////////////////////////////////////////////////////////////////// + +} // end namespace Catch + +// end catch_test_case_registry_impl.h +// start catch_reporter_registry.h + +#include <map> + +namespace Catch { + + class ReporterRegistry : public IReporterRegistry { + + public: + + ~ReporterRegistry() override; + + IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override; + + void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ); + void registerListener( IReporterFactoryPtr const& factory ); + + FactoryMap const& getFactories() const override; + Listeners const& getListeners() const override; + + private: + FactoryMap m_factories; + Listeners m_listeners; + }; +} + +// end catch_reporter_registry.h +// start catch_tag_alias_registry.h + +// start catch_tag_alias.h + +#include <string> + +namespace Catch { + + struct TagAlias { + TagAlias(std::string const& _tag, SourceLineInfo _lineInfo); + + std::string tag; + SourceLineInfo lineInfo; + }; + +} // end namespace Catch + +// end catch_tag_alias.h +#include <map> + +namespace Catch { + + class TagAliasRegistry : public ITagAliasRegistry { + public: + ~TagAliasRegistry() override; + TagAlias const* find( std::string const& alias ) const override; + std::string expandAliases( std::string const& unexpandedTestSpec ) const override; + void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ); + + private: + std::map<std::string, TagAlias> m_registry; + }; + +} // end namespace Catch + +// end catch_tag_alias_registry.h +// start catch_startup_exception_registry.h + +#include <vector> +#include <exception> + +namespace Catch { + + class StartupExceptionRegistry { +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + public: + void add(std::exception_ptr const& exception) noexcept; + std::vector<std::exception_ptr> const& getExceptions() const noexcept; + private: + std::vector<std::exception_ptr> m_exceptions; +#endif + }; + +} // end namespace Catch + +// end catch_startup_exception_registry.h +// start catch_singletons.hpp + +namespace Catch { + + struct ISingleton { + virtual ~ISingleton(); + }; + + void addSingleton( ISingleton* singleton ); + void cleanupSingletons(); + + template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT> + class Singleton : SingletonImplT, public ISingleton { + + static auto getInternal() -> Singleton* { + static Singleton* s_instance = nullptr; + if( !s_instance ) { + s_instance = new Singleton; + addSingleton( s_instance ); + } + return s_instance; + } + + public: + static auto get() -> InterfaceT const& { + return *getInternal(); + } + static auto getMutable() -> MutableInterfaceT& { + return *getInternal(); + } + }; + +} // namespace Catch + +// end catch_singletons.hpp +namespace Catch { + + namespace { + + class RegistryHub : public IRegistryHub, public IMutableRegistryHub, + private NonCopyable { + + public: // IRegistryHub + RegistryHub() = default; + IReporterRegistry const& getReporterRegistry() const override { + return m_reporterRegistry; + } + ITestCaseRegistry const& getTestCaseRegistry() const override { + return m_testCaseRegistry; + } + IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override { + return m_exceptionTranslatorRegistry; + } + ITagAliasRegistry const& getTagAliasRegistry() const override { + return m_tagAliasRegistry; + } + StartupExceptionRegistry const& getStartupExceptionRegistry() const override { + return m_exceptionRegistry; + } + + public: // IMutableRegistryHub + void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override { + m_reporterRegistry.registerReporter( name, factory ); + } + void registerListener( IReporterFactoryPtr const& factory ) override { + m_reporterRegistry.registerListener( factory ); + } + void registerTest( TestCase const& testInfo ) override { + m_testCaseRegistry.registerTest( testInfo ); + } + void registerTranslator( const IExceptionTranslator* translator ) override { + m_exceptionTranslatorRegistry.registerTranslator( translator ); + } + void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override { + m_tagAliasRegistry.add( alias, tag, lineInfo ); + } + void registerStartupException() noexcept override { +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + m_exceptionRegistry.add(std::current_exception()); +#else + CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!"); +#endif + } + IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override { + return m_enumValuesRegistry; + } + + private: + TestRegistry m_testCaseRegistry; + ReporterRegistry m_reporterRegistry; + ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; + TagAliasRegistry m_tagAliasRegistry; + StartupExceptionRegistry m_exceptionRegistry; + Detail::EnumValuesRegistry m_enumValuesRegistry; + }; + } + + using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>; + + IRegistryHub const& getRegistryHub() { + return RegistryHubSingleton::get(); + } + IMutableRegistryHub& getMutableRegistryHub() { + return RegistryHubSingleton::getMutable(); + } + void cleanUp() { + cleanupSingletons(); + cleanUpContext(); + } + std::string translateActiveException() { + return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); + } + +} // end namespace Catch +// end catch_registry_hub.cpp +// start catch_reporter_registry.cpp + +namespace Catch { + + ReporterRegistry::~ReporterRegistry() = default; + + IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const { + auto it = m_factories.find( name ); + if( it == m_factories.end() ) + return nullptr; + return it->second->create( ReporterConfig( config ) ); + } + + void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) { + m_factories.emplace(name, factory); + } + void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) { + m_listeners.push_back( factory ); + } + + IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const { + return m_factories; + } + IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const { + return m_listeners; + } + +} +// end catch_reporter_registry.cpp +// start catch_result_type.cpp + +namespace Catch { + + bool isOk( ResultWas::OfType resultType ) { + return ( resultType & ResultWas::FailureBit ) == 0; + } + bool isJustInfo( int flags ) { + return flags == ResultWas::Info; + } + + ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { + return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) ); + } + + bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } + bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } + +} // end namespace Catch +// end catch_result_type.cpp +// start catch_run_context.cpp + +#include <cassert> +#include <algorithm> +#include <sstream> + +namespace Catch { + + namespace Generators { + struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker { + GeneratorBasePtr m_generator; + + GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( nameAndLocation, ctx, parent ) + {} + ~GeneratorTracker(); + + static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) { + std::shared_ptr<GeneratorTracker> tracker; + + ITracker& currentTracker = ctx.currentTracker(); + // Under specific circumstances, the generator we want + // to acquire is also the current tracker. If this is + // the case, we have to avoid looking through current + // tracker's children, and instead return the current + // tracker. + // A case where this check is important is e.g. + // for (int i = 0; i < 5; ++i) { + // int n = GENERATE(1, 2); + // } + // + // without it, the code above creates 5 nested generators. + if (currentTracker.nameAndLocation() == nameAndLocation) { + auto thisTracker = currentTracker.parent().findChild(nameAndLocation); + assert(thisTracker); + assert(thisTracker->isGeneratorTracker()); + tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker); + } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isGeneratorTracker() ); + tracker = std::static_pointer_cast<GeneratorTracker>( childTracker ); + } else { + tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, ¤tTracker ); + currentTracker.addChild( tracker ); + } + + if( !tracker->isComplete() ) { + tracker->open(); + } + + return *tracker; + } + + // TrackerBase interface + bool isGeneratorTracker() const override { return true; } + auto hasGenerator() const -> bool override { + return !!m_generator; + } + void close() override { + TrackerBase::close(); + // If a generator has a child (it is followed by a section) + // and none of its children have started, then we must wait + // until later to start consuming its values. + // This catches cases where `GENERATE` is placed between two + // `SECTION`s. + // **The check for m_children.empty cannot be removed**. + // doing so would break `GENERATE` _not_ followed by `SECTION`s. + const bool should_wait_for_child = [&]() { + // No children -> nobody to wait for + if ( m_children.empty() ) { + return false; + } + // If at least one child started executing, don't wait + if ( std::find_if( + m_children.begin(), + m_children.end(), + []( TestCaseTracking::ITrackerPtr tracker ) { + return tracker->hasStarted(); + } ) != m_children.end() ) { + return false; + } + + // No children have started. We need to check if they _can_ + // start, and thus we should wait for them, or they cannot + // start (due to filters), and we shouldn't wait for them + auto* parent = m_parent; + // This is safe: there is always at least one section + // tracker in a test case tracking tree + while ( !parent->isSectionTracker() ) { + parent = &( parent->parent() ); + } + assert( parent && + "Missing root (test case) level section" ); + + auto const& parentSection = + static_cast<SectionTracker&>( *parent ); + auto const& filters = parentSection.getFilters(); + // No filters -> no restrictions on running sections + if ( filters.empty() ) { + return true; + } + + for ( auto const& child : m_children ) { + if ( child->isSectionTracker() && + std::find( filters.begin(), + filters.end(), + static_cast<SectionTracker&>( *child ) + .trimmedName() ) != + filters.end() ) { + return true; + } + } + return false; + }(); + + // This check is a bit tricky, because m_generator->next() + // has a side-effect, where it consumes generator's current + // value, but we do not want to invoke the side-effect if + // this generator is still waiting for any child to start. + if ( should_wait_for_child || + ( m_runState == CompletedSuccessfully && + m_generator->next() ) ) { + m_children.clear(); + m_runState = Executing; + } + } + + // IGeneratorTracker interface + auto getGenerator() const -> GeneratorBasePtr const& override { + return m_generator; + } + void setGenerator( GeneratorBasePtr&& generator ) override { + m_generator = std::move( generator ); + } + }; + GeneratorTracker::~GeneratorTracker() {} + } + + RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter) + : m_runInfo(_config->name()), + m_context(getCurrentMutableContext()), + m_config(_config), + m_reporter(std::move(reporter)), + m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal }, + m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions ) + { + m_context.setRunner(this); + m_context.setConfig(m_config); + m_context.setResultCapture(this); + m_reporter->testRunStarting(m_runInfo); + } + + RunContext::~RunContext() { + m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting())); + } + + void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) { + m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount)); + } + + void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) { + m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting())); + } + + Totals RunContext::runTest(TestCase const& testCase) { + Totals prevTotals = m_totals; + + std::string redirectedCout; + std::string redirectedCerr; + + auto const& testInfo = testCase.getTestCaseInfo(); + + m_reporter->testCaseStarting(testInfo); + + m_activeTestCase = &testCase; + + ITracker& rootTracker = m_trackerContext.startRun(); + assert(rootTracker.isSectionTracker()); + static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun()); + do { + m_trackerContext.startCycle(); + m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo)); + runCurrentTest(redirectedCout, redirectedCerr); + } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting()); + + Totals deltaTotals = m_totals.delta(prevTotals); + if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) { + deltaTotals.assertions.failed++; + deltaTotals.testCases.passed--; + deltaTotals.testCases.failed++; + } + m_totals.testCases += deltaTotals.testCases; + m_reporter->testCaseEnded(TestCaseStats(testInfo, + deltaTotals, + redirectedCout, + redirectedCerr, + aborting())); + + m_activeTestCase = nullptr; + m_testCaseTracker = nullptr; + + return deltaTotals; + } + + IConfigPtr RunContext::config() const { + return m_config; + } + + IStreamingReporter& RunContext::reporter() const { + return *m_reporter; + } + + void RunContext::assertionEnded(AssertionResult const & result) { + if (result.getResultType() == ResultWas::Ok) { + m_totals.assertions.passed++; + m_lastAssertionPassed = true; + } else if (!result.isOk()) { + m_lastAssertionPassed = false; + if( m_activeTestCase->getTestCaseInfo().okToFail() ) + m_totals.assertions.failedButOk++; + else + m_totals.assertions.failed++; + } + else { + m_lastAssertionPassed = true; + } + + // We have no use for the return value (whether messages should be cleared), because messages were made scoped + // and should be let to clear themselves out. + static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); + + if (result.getResultType() != ResultWas::Warning) + m_messageScopes.clear(); + + // Reset working state + resetAssertionInfo(); + m_lastResult = result; + } + void RunContext::resetAssertionInfo() { + m_lastAssertionInfo.macroName = StringRef(); + m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr; + } + + bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) { + ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo)); + if (!sectionTracker.isOpen()) + return false; + m_activeSections.push_back(§ionTracker); + + m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; + + m_reporter->sectionStarting(sectionInfo); + + assertions = m_totals.assertions; + + return true; + } + auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { + using namespace Generators; + GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext, + TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) ); + m_lastAssertionInfo.lineInfo = lineInfo; + return tracker; + } + + bool RunContext::testForMissingAssertions(Counts& assertions) { + if (assertions.total() != 0) + return false; + if (!m_config->warnAboutMissingAssertions()) + return false; + if (m_trackerContext.currentTracker().hasChildren()) + return false; + m_totals.assertions.failed++; + assertions.failed++; + return true; + } + + void RunContext::sectionEnded(SectionEndInfo const & endInfo) { + Counts assertions = m_totals.assertions - endInfo.prevAssertions; + bool missingAssertions = testForMissingAssertions(assertions); + + if (!m_activeSections.empty()) { + m_activeSections.back()->close(); + m_activeSections.pop_back(); + } + + m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions)); + m_messages.clear(); + m_messageScopes.clear(); + } + + void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) { + if (m_unfinishedSections.empty()) + m_activeSections.back()->fail(); + else + m_activeSections.back()->close(); + m_activeSections.pop_back(); + + m_unfinishedSections.push_back(endInfo); + } + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + void RunContext::benchmarkPreparing(std::string const& name) { + m_reporter->benchmarkPreparing(name); + } + void RunContext::benchmarkStarting( BenchmarkInfo const& info ) { + m_reporter->benchmarkStarting( info ); + } + void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) { + m_reporter->benchmarkEnded( stats ); + } + void RunContext::benchmarkFailed(std::string const & error) { + m_reporter->benchmarkFailed(error); + } +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + + void RunContext::pushScopedMessage(MessageInfo const & message) { + m_messages.push_back(message); + } + + void RunContext::popScopedMessage(MessageInfo const & message) { + m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end()); + } + + void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) { + m_messageScopes.emplace_back( builder ); + } + + std::string RunContext::getCurrentTestName() const { + return m_activeTestCase + ? m_activeTestCase->getTestCaseInfo().name + : std::string(); + } + + const AssertionResult * RunContext::getLastResult() const { + return &(*m_lastResult); + } + + void RunContext::exceptionEarlyReported() { + m_shouldReportUnexpected = false; + } + + void RunContext::handleFatalErrorCondition( StringRef message ) { + // First notify reporter that bad things happened + m_reporter->fatalErrorEncountered(message); + + // Don't rebuild the result -- the stringification itself can cause more fatal errors + // Instead, fake a result data. + AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } ); + tempResult.message = static_cast<std::string>(message); + AssertionResult result(m_lastAssertionInfo, tempResult); + + assertionEnded(result); + + handleUnfinishedSections(); + + // Recreate section for test case (as we will lose the one that was in scope) + auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name); + + Counts assertions; + assertions.failed = 1; + SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false); + m_reporter->sectionEnded(testCaseSectionStats); + + auto const& testInfo = m_activeTestCase->getTestCaseInfo(); + + Totals deltaTotals; + deltaTotals.testCases.failed = 1; + deltaTotals.assertions.failed = 1; + m_reporter->testCaseEnded(TestCaseStats(testInfo, + deltaTotals, + std::string(), + std::string(), + false)); + m_totals.testCases.failed++; + testGroupEnded(std::string(), m_totals, 1, 1); + m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false)); + } + + bool RunContext::lastAssertionPassed() { + return m_lastAssertionPassed; + } + + void RunContext::assertionPassed() { + m_lastAssertionPassed = true; + ++m_totals.assertions.passed; + resetAssertionInfo(); + m_messageScopes.clear(); + } + + bool RunContext::aborting() const { + return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter()); + } + + void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) { + auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name); + m_reporter->sectionStarting(testCaseSection); + Counts prevAssertions = m_totals.assertions; + double duration = 0; + m_shouldReportUnexpected = true; + m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal }; + + seedRng(*m_config); + + Timer timer; + CATCH_TRY { + if (m_reporter->getPreferences().shouldRedirectStdOut) { +#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) + RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr); + + timer.start(); + invokeActiveTestCase(); +#else + OutputRedirect r(redirectedCout, redirectedCerr); + timer.start(); + invokeActiveTestCase(); +#endif + } else { + timer.start(); + invokeActiveTestCase(); + } + duration = timer.getElapsedSeconds(); + } CATCH_CATCH_ANON (TestFailureException&) { + // This just means the test was aborted due to failure + } CATCH_CATCH_ALL { + // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions + // are reported without translation at the point of origin. + if( m_shouldReportUnexpected ) { + AssertionReaction dummyReaction; + handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction ); + } + } + Counts assertions = m_totals.assertions - prevAssertions; + bool missingAssertions = testForMissingAssertions(assertions); + + m_testCaseTracker->close(); + handleUnfinishedSections(); + m_messages.clear(); + m_messageScopes.clear(); + + SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); + m_reporter->sectionEnded(testCaseSectionStats); + } + + void RunContext::invokeActiveTestCase() { + FatalConditionHandlerGuard _(&m_fatalConditionhandler); + m_activeTestCase->invoke(); + } + + void RunContext::handleUnfinishedSections() { + // If sections ended prematurely due to an exception we stored their + // infos here so we can tear them down outside the unwind process. + for (auto it = m_unfinishedSections.rbegin(), + itEnd = m_unfinishedSections.rend(); + it != itEnd; + ++it) + sectionEnded(*it); + m_unfinishedSections.clear(); + } + + void RunContext::handleExpr( + AssertionInfo const& info, + ITransientExpression const& expr, + AssertionReaction& reaction + ) { + m_reporter->assertionStarting( info ); + + bool negated = isFalseTest( info.resultDisposition ); + bool result = expr.getResult() != negated; + + if( result ) { + if (!m_includeSuccessfulResults) { + assertionPassed(); + } + else { + reportExpr(info, ResultWas::Ok, &expr, negated); + } + } + else { + reportExpr(info, ResultWas::ExpressionFailed, &expr, negated ); + populateReaction( reaction ); + } + } + void RunContext::reportExpr( + AssertionInfo const &info, + ResultWas::OfType resultType, + ITransientExpression const *expr, + bool negated ) { + + m_lastAssertionInfo = info; + AssertionResultData data( resultType, LazyExpression( negated ) ); + + AssertionResult assertionResult{ info, data }; + assertionResult.m_resultData.lazyExpression.m_transientExpression = expr; + + assertionEnded( assertionResult ); + } + + void RunContext::handleMessage( + AssertionInfo const& info, + ResultWas::OfType resultType, + StringRef const& message, + AssertionReaction& reaction + ) { + m_reporter->assertionStarting( info ); + + m_lastAssertionInfo = info; + + AssertionResultData data( resultType, LazyExpression( false ) ); + data.message = static_cast<std::string>(message); + AssertionResult assertionResult{ m_lastAssertionInfo, data }; + assertionEnded( assertionResult ); + if( !assertionResult.isOk() ) + populateReaction( reaction ); + } + void RunContext::handleUnexpectedExceptionNotThrown( + AssertionInfo const& info, + AssertionReaction& reaction + ) { + handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction); + } + + void RunContext::handleUnexpectedInflightException( + AssertionInfo const& info, + std::string const& message, + AssertionReaction& reaction + ) { + m_lastAssertionInfo = info; + + AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); + data.message = message; + AssertionResult assertionResult{ info, data }; + assertionEnded( assertionResult ); + populateReaction( reaction ); + } + + void RunContext::populateReaction( AssertionReaction& reaction ) { + reaction.shouldDebugBreak = m_config->shouldDebugBreak(); + reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal); + } + + void RunContext::handleIncomplete( + AssertionInfo const& info + ) { + m_lastAssertionInfo = info; + + AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); + data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; + AssertionResult assertionResult{ info, data }; + assertionEnded( assertionResult ); + } + void RunContext::handleNonExpr( + AssertionInfo const &info, + ResultWas::OfType resultType, + AssertionReaction &reaction + ) { + m_lastAssertionInfo = info; + + AssertionResultData data( resultType, LazyExpression( false ) ); + AssertionResult assertionResult{ info, data }; + assertionEnded( assertionResult ); + + if( !assertionResult.isOk() ) + populateReaction( reaction ); + } + + IResultCapture& getResultCapture() { + if (auto* capture = getCurrentContext().getResultCapture()) + return *capture; + else + CATCH_INTERNAL_ERROR("No result capture instance"); + } + + void seedRng(IConfig const& config) { + if (config.rngSeed() != 0) { + std::srand(config.rngSeed()); + rng().seed(config.rngSeed()); + } + } + + unsigned int rngSeed() { + return getCurrentContext().getConfig()->rngSeed(); + } + +} +// end catch_run_context.cpp +// start catch_section.cpp + +namespace Catch { + + Section::Section( SectionInfo const& info ) + : m_info( info ), + m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) + { + m_timer.start(); + } + + Section::~Section() { + if( m_sectionIncluded ) { + SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() }; + if( uncaught_exceptions() ) + getResultCapture().sectionEndedEarly( endInfo ); + else + getResultCapture().sectionEnded( endInfo ); + } + } + + // This indicates whether the section should be executed or not + Section::operator bool() const { + return m_sectionIncluded; + } + +} // end namespace Catch +// end catch_section.cpp +// start catch_section_info.cpp + +namespace Catch { + + SectionInfo::SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name ) + : name( _name ), + lineInfo( _lineInfo ) + {} + +} // end namespace Catch +// end catch_section_info.cpp +// start catch_session.cpp + +// start catch_session.h + +#include <memory> + +namespace Catch { + + class Session : NonCopyable { + public: + + Session(); + ~Session() override; + + void showHelp() const; + void libIdentify(); + + int applyCommandLine( int argc, char const * const * argv ); + #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE) + int applyCommandLine( int argc, wchar_t const * const * argv ); + #endif + + void useConfigData( ConfigData const& configData ); + + template<typename CharT> + int run(int argc, CharT const * const argv[]) { + if (m_startupExceptions) + return 1; + int returnCode = applyCommandLine(argc, argv); + if (returnCode == 0) + returnCode = run(); + return returnCode; + } + + int run(); + + clara::Parser const& cli() const; + void cli( clara::Parser const& newParser ); + ConfigData& configData(); + Config& config(); + private: + int runInternal(); + + clara::Parser m_cli; + ConfigData m_configData; + std::shared_ptr<Config> m_config; + bool m_startupExceptions = false; + }; + +} // end namespace Catch + +// end catch_session.h +// start catch_version.h + +#include <iosfwd> + +namespace Catch { + + // Versioning information + struct Version { + Version( Version const& ) = delete; + Version& operator=( Version const& ) = delete; + Version( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + char const * const _branchName, + unsigned int _buildNumber ); + + unsigned int const majorVersion; + unsigned int const minorVersion; + unsigned int const patchNumber; + + // buildNumber is only used if branchName is not null + char const * const branchName; + unsigned int const buildNumber; + + friend std::ostream& operator << ( std::ostream& os, Version const& version ); + }; + + Version const& libraryVersion(); +} + +// end catch_version.h +#include <cstdlib> +#include <iomanip> +#include <set> +#include <iterator> + +namespace Catch { + + namespace { + const int MaxExitCode = 255; + + IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) { + auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config); + CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'"); + + return reporter; + } + + IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) { + if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) { + return createReporter(config->getReporterName(), config); + } + + // On older platforms, returning std::unique_ptr<ListeningReporter> + // when the return type is std::unique_ptr<IStreamingReporter> + // doesn't compile without a std::move call. However, this causes + // a warning on newer platforms. Thus, we have to work around + // it a bit and downcast the pointer manually. + auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter); + auto& multi = static_cast<ListeningReporter&>(*ret); + auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners(); + for (auto const& listener : listeners) { + multi.addListener(listener->create(Catch::ReporterConfig(config))); + } + multi.addReporter(createReporter(config->getReporterName(), config)); + return ret; + } + + class TestGroup { + public: + explicit TestGroup(std::shared_ptr<Config> const& config) + : m_config{config} + , m_context{config, makeReporter(config)} + { + auto const& allTestCases = getAllTestCasesSorted(*m_config); + m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config); + auto const& invalidArgs = m_config->testSpec().getInvalidArgs(); + + if (m_matches.empty() && invalidArgs.empty()) { + for (auto const& test : allTestCases) + if (!test.isHidden()) + m_tests.emplace(&test); + } else { + for (auto const& match : m_matches) + m_tests.insert(match.tests.begin(), match.tests.end()); + } + } + + Totals execute() { + auto const& invalidArgs = m_config->testSpec().getInvalidArgs(); + Totals totals; + m_context.testGroupStarting(m_config->name(), 1, 1); + for (auto const& testCase : m_tests) { + if (!m_context.aborting()) + totals += m_context.runTest(*testCase); + else + m_context.reporter().skipTest(*testCase); + } + + for (auto const& match : m_matches) { + if (match.tests.empty()) { + m_context.reporter().noMatchingTestCases(match.name); + totals.error = -1; + } + } + + if (!invalidArgs.empty()) { + for (auto const& invalidArg: invalidArgs) + m_context.reporter().reportInvalidArguments(invalidArg); + } + + m_context.testGroupEnded(m_config->name(), totals, 1, 1); + return totals; + } + + private: + using Tests = std::set<TestCase const*>; + + std::shared_ptr<Config> m_config; + RunContext m_context; + Tests m_tests; + TestSpec::Matches m_matches; + }; + + void applyFilenamesAsTags(Catch::IConfig const& config) { + auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config)); + for (auto& testCase : tests) { + auto tags = testCase.tags; + + std::string filename = testCase.lineInfo.file; + auto lastSlash = filename.find_last_of("\\/"); + if (lastSlash != std::string::npos) { + filename.erase(0, lastSlash); + filename[0] = '#'; + } + else + { + filename.insert(0, "#"); + } + + auto lastDot = filename.find_last_of('.'); + if (lastDot != std::string::npos) { + filename.erase(lastDot); + } + + tags.push_back(std::move(filename)); + setTags(testCase, tags); + } + } + + } // anon namespace + + Session::Session() { + static bool alreadyInstantiated = false; + if( alreadyInstantiated ) { + CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); } + CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); } + } + + // There cannot be exceptions at startup in no-exception mode. +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions(); + if ( !exceptions.empty() ) { + config(); + getCurrentMutableContext().setConfig(m_config); + + m_startupExceptions = true; + Colour colourGuard( Colour::Red ); + Catch::cerr() << "Errors occurred during startup!" << '\n'; + // iterate over all exceptions and notify user + for ( const auto& ex_ptr : exceptions ) { + try { + std::rethrow_exception(ex_ptr); + } catch ( std::exception const& ex ) { + Catch::cerr() << Column( ex.what() ).indent(2) << '\n'; + } + } + } +#endif + + alreadyInstantiated = true; + m_cli = makeCommandLineParser( m_configData ); + } + Session::~Session() { + Catch::cleanUp(); + } + + void Session::showHelp() const { + Catch::cout() + << "\nCatch v" << libraryVersion() << "\n" + << m_cli << std::endl + << "For more detailed usage please see the project docs\n" << std::endl; + } + void Session::libIdentify() { + Catch::cout() + << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n" + << std::left << std::setw(16) << "category: " << "testframework\n" + << std::left << std::setw(16) << "framework: " << "Catch Test\n" + << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl; + } + + int Session::applyCommandLine( int argc, char const * const * argv ) { + if( m_startupExceptions ) + return 1; + + auto result = m_cli.parse( clara::Args( argc, argv ) ); + if( !result ) { + config(); + getCurrentMutableContext().setConfig(m_config); + Catch::cerr() + << Colour( Colour::Red ) + << "\nError(s) in input:\n" + << Column( result.errorMessage() ).indent( 2 ) + << "\n\n"; + Catch::cerr() << "Run with -? for usage\n" << std::endl; + return MaxExitCode; + } + + if( m_configData.showHelp ) + showHelp(); + if( m_configData.libIdentify ) + libIdentify(); + m_config.reset(); + return 0; + } + +#if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE) + int Session::applyCommandLine( int argc, wchar_t const * const * argv ) { + + char **utf8Argv = new char *[ argc ]; + + for ( int i = 0; i < argc; ++i ) { + int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr ); + + utf8Argv[ i ] = new char[ bufSize ]; + + WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr ); + } + + int returnCode = applyCommandLine( argc, utf8Argv ); + + for ( int i = 0; i < argc; ++i ) + delete [] utf8Argv[ i ]; + + delete [] utf8Argv; + + return returnCode; + } +#endif + + void Session::useConfigData( ConfigData const& configData ) { + m_configData = configData; + m_config.reset(); + } + + int Session::run() { + if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) { + Catch::cout() << "...waiting for enter/ return before starting" << std::endl; + static_cast<void>(std::getchar()); + } + int exitCode = runInternal(); + if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) { + Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl; + static_cast<void>(std::getchar()); + } + return exitCode; + } + + clara::Parser const& Session::cli() const { + return m_cli; + } + void Session::cli( clara::Parser const& newParser ) { + m_cli = newParser; + } + ConfigData& Session::configData() { + return m_configData; + } + Config& Session::config() { + if( !m_config ) + m_config = std::make_shared<Config>( m_configData ); + return *m_config; + } + + int Session::runInternal() { + if( m_startupExceptions ) + return 1; + + if (m_configData.showHelp || m_configData.libIdentify) { + return 0; + } + + CATCH_TRY { + config(); // Force config to be constructed + + seedRng( *m_config ); + + if( m_configData.filenamesAsTags ) + applyFilenamesAsTags( *m_config ); + + // Handle list request + if( Option<std::size_t> listed = list( m_config ) ) + return static_cast<int>( *listed ); + + TestGroup tests { m_config }; + auto const totals = tests.execute(); + + if( m_config->warnAboutNoTests() && totals.error == -1 ) + return 2; + + // Note that on unices only the lower 8 bits are usually used, clamping + // the return value to 255 prevents false negative when some multiple + // of 256 tests has failed + return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed))); + } +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + catch( std::exception& ex ) { + Catch::cerr() << ex.what() << std::endl; + return MaxExitCode; + } +#endif + } + +} // end namespace Catch +// end catch_session.cpp +// start catch_singletons.cpp + +#include <vector> + +namespace Catch { + + namespace { + static auto getSingletons() -> std::vector<ISingleton*>*& { + static std::vector<ISingleton*>* g_singletons = nullptr; + if( !g_singletons ) + g_singletons = new std::vector<ISingleton*>(); + return g_singletons; + } + } + + ISingleton::~ISingleton() {} + + void addSingleton(ISingleton* singleton ) { + getSingletons()->push_back( singleton ); + } + void cleanupSingletons() { + auto& singletons = getSingletons(); + for( auto singleton : *singletons ) + delete singleton; + delete singletons; + singletons = nullptr; + } + +} // namespace Catch +// end catch_singletons.cpp +// start catch_startup_exception_registry.cpp + +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +namespace Catch { +void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept { + CATCH_TRY { + m_exceptions.push_back(exception); + } CATCH_CATCH_ALL { + // If we run out of memory during start-up there's really not a lot more we can do about it + std::terminate(); + } + } + + std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept { + return m_exceptions; + } + +} // end namespace Catch +#endif +// end catch_startup_exception_registry.cpp +// start catch_stream.cpp + +#include <cstdio> +#include <iostream> +#include <fstream> +#include <sstream> +#include <vector> +#include <memory> + +namespace Catch { + + Catch::IStream::~IStream() = default; + + namespace Detail { namespace { + template<typename WriterF, std::size_t bufferSize=256> + class StreamBufImpl : public std::streambuf { + char data[bufferSize]; + WriterF m_writer; + + public: + StreamBufImpl() { + setp( data, data + sizeof(data) ); + } + + ~StreamBufImpl() noexcept { + StreamBufImpl::sync(); + } + + private: + int overflow( int c ) override { + sync(); + + if( c != EOF ) { + if( pbase() == epptr() ) + m_writer( std::string( 1, static_cast<char>( c ) ) ); + else + sputc( static_cast<char>( c ) ); + } + return 0; + } + + int sync() override { + if( pbase() != pptr() ) { + m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) ); + setp( pbase(), epptr() ); + } + return 0; + } + }; + + /////////////////////////////////////////////////////////////////////////// + + struct OutputDebugWriter { + + void operator()( std::string const&str ) { + writeToDebugConsole( str ); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + class FileStream : public IStream { + mutable std::ofstream m_ofs; + public: + FileStream( StringRef filename ) { + m_ofs.open( filename.c_str() ); + CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" ); + } + ~FileStream() override = default; + public: // IStream + std::ostream& stream() const override { + return m_ofs; + } + }; + + /////////////////////////////////////////////////////////////////////////// + + class CoutStream : public IStream { + mutable std::ostream m_os; + public: + // Store the streambuf from cout up-front because + // cout may get redirected when running tests + CoutStream() : m_os( Catch::cout().rdbuf() ) {} + ~CoutStream() override = default; + + public: // IStream + std::ostream& stream() const override { return m_os; } + }; + + /////////////////////////////////////////////////////////////////////////// + + class DebugOutStream : public IStream { + std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf; + mutable std::ostream m_os; + public: + DebugOutStream() + : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ), + m_os( m_streamBuf.get() ) + {} + + ~DebugOutStream() override = default; + + public: // IStream + std::ostream& stream() const override { return m_os; } + }; + + }} // namespace anon::detail + + /////////////////////////////////////////////////////////////////////////// + + auto makeStream( StringRef const &filename ) -> IStream const* { + if( filename.empty() ) + return new Detail::CoutStream(); + else if( filename[0] == '%' ) { + if( filename == "%debug" ) + return new Detail::DebugOutStream(); + else + CATCH_ERROR( "Unrecognised stream: '" << filename << "'" ); + } + else + return new Detail::FileStream( filename ); + } + + // This class encapsulates the idea of a pool of ostringstreams that can be reused. + struct StringStreams { + std::vector<std::unique_ptr<std::ostringstream>> m_streams; + std::vector<std::size_t> m_unused; + std::ostringstream m_referenceStream; // Used for copy state/ flags from + + auto add() -> std::size_t { + if( m_unused.empty() ) { + m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) ); + return m_streams.size()-1; + } + else { + auto index = m_unused.back(); + m_unused.pop_back(); + return index; + } + } + + void release( std::size_t index ) { + m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state + m_unused.push_back(index); + } + }; + + ReusableStringStream::ReusableStringStream() + : m_index( Singleton<StringStreams>::getMutable().add() ), + m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() ) + {} + + ReusableStringStream::~ReusableStringStream() { + static_cast<std::ostringstream*>( m_oss )->str(""); + m_oss->clear(); + Singleton<StringStreams>::getMutable().release( m_index ); + } + + auto ReusableStringStream::str() const -> std::string { + return static_cast<std::ostringstream*>( m_oss )->str(); + } + + /////////////////////////////////////////////////////////////////////////// + +#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions + std::ostream& cout() { return std::cout; } + std::ostream& cerr() { return std::cerr; } + std::ostream& clog() { return std::clog; } +#endif +} +// end catch_stream.cpp +// start catch_string_manip.cpp + +#include <algorithm> +#include <ostream> +#include <cstring> +#include <cctype> +#include <vector> + +namespace Catch { + + namespace { + char toLowerCh(char c) { + return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) ); + } + } + + bool startsWith( std::string const& s, std::string const& prefix ) { + return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); + } + bool startsWith( std::string const& s, char prefix ) { + return !s.empty() && s[0] == prefix; + } + bool endsWith( std::string const& s, std::string const& suffix ) { + return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); + } + bool endsWith( std::string const& s, char suffix ) { + return !s.empty() && s[s.size()-1] == suffix; + } + bool contains( std::string const& s, std::string const& infix ) { + return s.find( infix ) != std::string::npos; + } + void toLowerInPlace( std::string& s ) { + std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); + } + std::string toLower( std::string const& s ) { + std::string lc = s; + toLowerInPlace( lc ); + return lc; + } + std::string trim( std::string const& str ) { + static char const* whitespaceChars = "\n\r\t "; + std::string::size_type start = str.find_first_not_of( whitespaceChars ); + std::string::size_type end = str.find_last_not_of( whitespaceChars ); + + return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); + } + + StringRef trim(StringRef ref) { + const auto is_ws = [](char c) { + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; + }; + size_t real_begin = 0; + while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; } + size_t real_end = ref.size(); + while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; } + + return ref.substr(real_begin, real_end - real_begin); + } + + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { + bool replaced = false; + std::size_t i = str.find( replaceThis ); + while( i != std::string::npos ) { + replaced = true; + str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); + if( i < str.size()-withThis.size() ) + i = str.find( replaceThis, i+withThis.size() ); + else + i = std::string::npos; + } + return replaced; + } + + std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) { + std::vector<StringRef> subStrings; + std::size_t start = 0; + for(std::size_t pos = 0; pos < str.size(); ++pos ) { + if( str[pos] == delimiter ) { + if( pos - start > 1 ) + subStrings.push_back( str.substr( start, pos-start ) ); + start = pos+1; + } + } + if( start < str.size() ) + subStrings.push_back( str.substr( start, str.size()-start ) ); + return subStrings; + } + + pluralise::pluralise( std::size_t count, std::string const& label ) + : m_count( count ), + m_label( label ) + {} + + std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { + os << pluraliser.m_count << ' ' << pluraliser.m_label; + if( pluraliser.m_count != 1 ) + os << 's'; + return os; + } + +} +// end catch_string_manip.cpp +// start catch_stringref.cpp + +#include <algorithm> +#include <ostream> +#include <cstring> +#include <cstdint> + +namespace Catch { + StringRef::StringRef( char const* rawChars ) noexcept + : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) ) + {} + + auto StringRef::c_str() const -> char const* { + CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance"); + return m_start; + } + auto StringRef::data() const noexcept -> char const* { + return m_start; + } + + auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef { + if (start < m_size) { + return StringRef(m_start + start, (std::min)(m_size - start, size)); + } else { + return StringRef(); + } + } + auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool { + return m_size == other.m_size + && (std::memcmp( m_start, other.m_start, m_size ) == 0); + } + + auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& { + return os.write(str.data(), str.size()); + } + + auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& { + lhs.append(rhs.data(), rhs.size()); + return lhs; + } + +} // namespace Catch +// end catch_stringref.cpp +// start catch_tag_alias.cpp + +namespace Catch { + TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {} +} +// end catch_tag_alias.cpp +// start catch_tag_alias_autoregistrar.cpp + +namespace Catch { + + RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) { + CATCH_TRY { + getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo); + } CATCH_CATCH_ALL { + // Do not throw when constructing global objects, instead register the exception to be processed later + getMutableRegistryHub().registerStartupException(); + } + } + +} +// end catch_tag_alias_autoregistrar.cpp +// start catch_tag_alias_registry.cpp + +#include <sstream> + +namespace Catch { + + TagAliasRegistry::~TagAliasRegistry() {} + + TagAlias const* TagAliasRegistry::find( std::string const& alias ) const { + auto it = m_registry.find( alias ); + if( it != m_registry.end() ) + return &(it->second); + else + return nullptr; + } + + std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { + std::string expandedTestSpec = unexpandedTestSpec; + for( auto const& registryKvp : m_registry ) { + std::size_t pos = expandedTestSpec.find( registryKvp.first ); + if( pos != std::string::npos ) { + expandedTestSpec = expandedTestSpec.substr( 0, pos ) + + registryKvp.second.tag + + expandedTestSpec.substr( pos + registryKvp.first.size() ); + } + } + return expandedTestSpec; + } + + void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) { + CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'), + "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo ); + + CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second, + "error: tag alias, '" << alias << "' already registered.\n" + << "\tFirst seen at: " << find(alias)->lineInfo << "\n" + << "\tRedefined at: " << lineInfo ); + } + + ITagAliasRegistry::~ITagAliasRegistry() {} + + ITagAliasRegistry const& ITagAliasRegistry::get() { + return getRegistryHub().getTagAliasRegistry(); + } + +} // end namespace Catch +// end catch_tag_alias_registry.cpp +// start catch_test_case_info.cpp + +#include <cctype> +#include <exception> +#include <algorithm> +#include <sstream> + +namespace Catch { + + namespace { + TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { + if( startsWith( tag, '.' ) || + tag == "!hide" ) + return TestCaseInfo::IsHidden; + else if( tag == "!throws" ) + return TestCaseInfo::Throws; + else if( tag == "!shouldfail" ) + return TestCaseInfo::ShouldFail; + else if( tag == "!mayfail" ) + return TestCaseInfo::MayFail; + else if( tag == "!nonportable" ) + return TestCaseInfo::NonPortable; + else if( tag == "!benchmark" ) + return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden ); + else + return TestCaseInfo::None; + } + bool isReservedTag( std::string const& tag ) { + return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) ); + } + void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { + CATCH_ENFORCE( !isReservedTag(tag), + "Tag name: [" << tag << "] is not allowed.\n" + << "Tag names starting with non alphanumeric characters are reserved\n" + << _lineInfo ); + } + } + + TestCase makeTestCase( ITestInvoker* _testCase, + std::string const& _className, + NameAndTags const& nameAndTags, + SourceLineInfo const& _lineInfo ) + { + bool isHidden = false; + + // Parse out tags + std::vector<std::string> tags; + std::string desc, tag; + bool inTag = false; + for (char c : nameAndTags.tags) { + if( !inTag ) { + if( c == '[' ) + inTag = true; + else + desc += c; + } + else { + if( c == ']' ) { + TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); + if( ( prop & TestCaseInfo::IsHidden ) != 0 ) + isHidden = true; + else if( prop == TestCaseInfo::None ) + enforceNotReservedTag( tag, _lineInfo ); + + // Merged hide tags like `[.approvals]` should be added as + // `[.][approvals]`. The `[.]` is added at later point, so + // we only strip the prefix + if (startsWith(tag, '.') && tag.size() > 1) { + tag.erase(0, 1); + } + tags.push_back( tag ); + tag.clear(); + inTag = false; + } + else + tag += c; + } + } + if( isHidden ) { + // Add all "hidden" tags to make them behave identically + tags.insert( tags.end(), { ".", "!hide" } ); + } + + TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo ); + return TestCase( _testCase, std::move(info) ); + } + + void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) { + std::sort(begin(tags), end(tags)); + tags.erase(std::unique(begin(tags), end(tags)), end(tags)); + testCaseInfo.lcaseTags.clear(); + + for( auto const& tag : tags ) { + std::string lcaseTag = toLower( tag ); + testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); + testCaseInfo.lcaseTags.push_back( lcaseTag ); + } + testCaseInfo.tags = std::move(tags); + } + + TestCaseInfo::TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::vector<std::string> const& _tags, + SourceLineInfo const& _lineInfo ) + : name( _name ), + className( _className ), + description( _description ), + lineInfo( _lineInfo ), + properties( None ) + { + setTags( *this, _tags ); + } + + bool TestCaseInfo::isHidden() const { + return ( properties & IsHidden ) != 0; + } + bool TestCaseInfo::throws() const { + return ( properties & Throws ) != 0; + } + bool TestCaseInfo::okToFail() const { + return ( properties & (ShouldFail | MayFail ) ) != 0; + } + bool TestCaseInfo::expectedToFail() const { + return ( properties & (ShouldFail ) ) != 0; + } + + std::string TestCaseInfo::tagsAsString() const { + std::string ret; + // '[' and ']' per tag + std::size_t full_size = 2 * tags.size(); + for (const auto& tag : tags) { + full_size += tag.size(); + } + ret.reserve(full_size); + for (const auto& tag : tags) { + ret.push_back('['); + ret.append(tag); + ret.push_back(']'); + } + + return ret; + } + + TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {} + + TestCase TestCase::withName( std::string const& _newName ) const { + TestCase other( *this ); + other.name = _newName; + return other; + } + + void TestCase::invoke() const { + test->invoke(); + } + + bool TestCase::operator == ( TestCase const& other ) const { + return test.get() == other.test.get() && + name == other.name && + className == other.className; + } + + bool TestCase::operator < ( TestCase const& other ) const { + return name < other.name; + } + + TestCaseInfo const& TestCase::getTestCaseInfo() const + { + return *this; + } + +} // end namespace Catch +// end catch_test_case_info.cpp +// start catch_test_case_registry_impl.cpp + +#include <algorithm> +#include <sstream> + +namespace Catch { + + namespace { + struct TestHasher { + using hash_t = uint64_t; + + explicit TestHasher( hash_t hashSuffix ): + m_hashSuffix{ hashSuffix } {} + + uint32_t operator()( TestCase const& t ) const { + // FNV-1a hash with multiplication fold. + const hash_t prime = 1099511628211u; + hash_t hash = 14695981039346656037u; + for ( const char c : t.name ) { + hash ^= c; + hash *= prime; + } + hash ^= m_hashSuffix; + hash *= prime; + const uint32_t low{ static_cast<uint32_t>( hash ) }; + const uint32_t high{ static_cast<uint32_t>( hash >> 32 ) }; + return low * high; + } + + private: + hash_t m_hashSuffix; + }; + } // end unnamed namespace + + std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) { + switch( config.runOrder() ) { + case RunTests::InDeclarationOrder: + // already in declaration order + break; + + case RunTests::InLexicographicalOrder: { + std::vector<TestCase> sorted = unsortedTestCases; + std::sort( sorted.begin(), sorted.end() ); + return sorted; + } + + case RunTests::InRandomOrder: { + seedRng( config ); + TestHasher h{ config.rngSeed() }; + + using hashedTest = std::pair<TestHasher::hash_t, TestCase const*>; + std::vector<hashedTest> indexed_tests; + indexed_tests.reserve( unsortedTestCases.size() ); + + for (auto const& testCase : unsortedTestCases) { + indexed_tests.emplace_back(h(testCase), &testCase); + } + + std::sort(indexed_tests.begin(), indexed_tests.end(), + [](hashedTest const& lhs, hashedTest const& rhs) { + if (lhs.first == rhs.first) { + return lhs.second->name < rhs.second->name; + } + return lhs.first < rhs.first; + }); + + std::vector<TestCase> sorted; + sorted.reserve( indexed_tests.size() ); + + for (auto const& hashed : indexed_tests) { + sorted.emplace_back(*hashed.second); + } + + return sorted; + } + } + return unsortedTestCases; + } + + bool isThrowSafe( TestCase const& testCase, IConfig const& config ) { + return !testCase.throws() || config.allowThrows(); + } + + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { + return testSpec.matches( testCase ) && isThrowSafe( testCase, config ); + } + + void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) { + std::set<TestCase> seenFunctions; + for( auto const& function : functions ) { + auto prev = seenFunctions.insert( function ); + CATCH_ENFORCE( prev.second, + "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n" + << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n" + << "\tRedefined at " << function.getTestCaseInfo().lineInfo ); + } + } + + std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) { + std::vector<TestCase> filtered; + filtered.reserve( testCases.size() ); + for (auto const& testCase : testCases) { + if ((!testSpec.hasFilters() && !testCase.isHidden()) || + (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) { + filtered.push_back(testCase); + } + } + return filtered; + } + std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) { + return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); + } + + void TestRegistry::registerTest( TestCase const& testCase ) { + std::string name = testCase.getTestCaseInfo().name; + if( name.empty() ) { + ReusableStringStream rss; + rss << "Anonymous test case " << ++m_unnamedCount; + return registerTest( testCase.withName( rss.str() ) ); + } + m_functions.push_back( testCase ); + } + + std::vector<TestCase> const& TestRegistry::getAllTests() const { + return m_functions; + } + std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const { + if( m_sortedFunctions.empty() ) + enforceNoDuplicateTestCases( m_functions ); + + if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { + m_sortedFunctions = sortTests( config, m_functions ); + m_currentSortOrder = config.runOrder(); + } + return m_sortedFunctions; + } + + /////////////////////////////////////////////////////////////////////////// + TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {} + + void TestInvokerAsFunction::invoke() const { + m_testAsFunction(); + } + + std::string extractClassName( StringRef const& classOrQualifiedMethodName ) { + std::string className(classOrQualifiedMethodName); + if( startsWith( className, '&' ) ) + { + std::size_t lastColons = className.rfind( "::" ); + std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); + if( penultimateColons == std::string::npos ) + penultimateColons = 1; + className = className.substr( penultimateColons, lastColons-penultimateColons ); + } + return className; + } + +} // end namespace Catch +// end catch_test_case_registry_impl.cpp +// start catch_test_case_tracker.cpp + +#include <algorithm> +#include <cassert> +#include <stdexcept> +#include <memory> +#include <sstream> + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +namespace Catch { +namespace TestCaseTracking { + + NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) + : name( _name ), + location( _location ) + {} + + ITracker::~ITracker() = default; + + ITracker& TrackerContext::startRun() { + m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr ); + m_currentTracker = nullptr; + m_runState = Executing; + return *m_rootTracker; + } + + void TrackerContext::endRun() { + m_rootTracker.reset(); + m_currentTracker = nullptr; + m_runState = NotStarted; + } + + void TrackerContext::startCycle() { + m_currentTracker = m_rootTracker.get(); + m_runState = Executing; + } + void TrackerContext::completeCycle() { + m_runState = CompletedCycle; + } + + bool TrackerContext::completedCycle() const { + return m_runState == CompletedCycle; + } + ITracker& TrackerContext::currentTracker() { + return *m_currentTracker; + } + void TrackerContext::setCurrentTracker( ITracker* tracker ) { + m_currentTracker = tracker; + } + + TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ): + ITracker(nameAndLocation), + m_ctx( ctx ), + m_parent( parent ) + {} + + bool TrackerBase::isComplete() const { + return m_runState == CompletedSuccessfully || m_runState == Failed; + } + bool TrackerBase::isSuccessfullyCompleted() const { + return m_runState == CompletedSuccessfully; + } + bool TrackerBase::isOpen() const { + return m_runState != NotStarted && !isComplete(); + } + bool TrackerBase::hasChildren() const { + return !m_children.empty(); + } + + void TrackerBase::addChild( ITrackerPtr const& child ) { + m_children.push_back( child ); + } + + ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) { + auto it = std::find_if( m_children.begin(), m_children.end(), + [&nameAndLocation]( ITrackerPtr const& tracker ){ + return + tracker->nameAndLocation().location == nameAndLocation.location && + tracker->nameAndLocation().name == nameAndLocation.name; + } ); + return( it != m_children.end() ) + ? *it + : nullptr; + } + ITracker& TrackerBase::parent() { + assert( m_parent ); // Should always be non-null except for root + return *m_parent; + } + + void TrackerBase::openChild() { + if( m_runState != ExecutingChildren ) { + m_runState = ExecutingChildren; + if( m_parent ) + m_parent->openChild(); + } + } + + bool TrackerBase::isSectionTracker() const { return false; } + bool TrackerBase::isGeneratorTracker() const { return false; } + + void TrackerBase::open() { + m_runState = Executing; + moveToThis(); + if( m_parent ) + m_parent->openChild(); + } + + void TrackerBase::close() { + + // Close any still open children (e.g. generators) + while( &m_ctx.currentTracker() != this ) + m_ctx.currentTracker().close(); + + switch( m_runState ) { + case NeedsAnotherRun: + break; + + case Executing: + m_runState = CompletedSuccessfully; + break; + case ExecutingChildren: + if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) ) + m_runState = CompletedSuccessfully; + break; + + case NotStarted: + case CompletedSuccessfully: + case Failed: + CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState ); + + default: + CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState ); + } + moveToParent(); + m_ctx.completeCycle(); + } + void TrackerBase::fail() { + m_runState = Failed; + if( m_parent ) + m_parent->markAsNeedingAnotherRun(); + moveToParent(); + m_ctx.completeCycle(); + } + void TrackerBase::markAsNeedingAnotherRun() { + m_runState = NeedsAnotherRun; + } + + void TrackerBase::moveToParent() { + assert( m_parent ); + m_ctx.setCurrentTracker( m_parent ); + } + void TrackerBase::moveToThis() { + m_ctx.setCurrentTracker( this ); + } + + SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( nameAndLocation, ctx, parent ), + m_trimmed_name(trim(nameAndLocation.name)) + { + if( parent ) { + while( !parent->isSectionTracker() ) + parent = &parent->parent(); + + SectionTracker& parentSection = static_cast<SectionTracker&>( *parent ); + addNextFilters( parentSection.m_filters ); + } + } + + bool SectionTracker::isComplete() const { + bool complete = true; + + if (m_filters.empty() + || m_filters[0] == "" + || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) { + complete = TrackerBase::isComplete(); + } + return complete; + } + + bool SectionTracker::isSectionTracker() const { return true; } + + SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { + std::shared_ptr<SectionTracker> section; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isSectionTracker() ); + section = std::static_pointer_cast<SectionTracker>( childTracker ); + } + else { + section = std::make_shared<SectionTracker>( nameAndLocation, ctx, ¤tTracker ); + currentTracker.addChild( section ); + } + if( !ctx.completedCycle() ) + section->tryOpen(); + return *section; + } + + void SectionTracker::tryOpen() { + if( !isComplete() ) + open(); + } + + void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) { + if( !filters.empty() ) { + m_filters.reserve( m_filters.size() + filters.size() + 2 ); + m_filters.emplace_back(""); // Root - should never be consulted + m_filters.emplace_back(""); // Test Case - not a section filter + m_filters.insert( m_filters.end(), filters.begin(), filters.end() ); + } + } + void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) { + if( filters.size() > 1 ) + m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() ); + } + + std::vector<std::string> const& SectionTracker::getFilters() const { + return m_filters; + } + + std::string const& SectionTracker::trimmedName() const { + return m_trimmed_name; + } + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; + +} // namespace Catch + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +// end catch_test_case_tracker.cpp +// start catch_test_registry.cpp + +namespace Catch { + + auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* { + return new(std::nothrow) TestInvokerAsFunction( testAsFunction ); + } + + NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {} + + AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept { + CATCH_TRY { + getMutableRegistryHub() + .registerTest( + makeTestCase( + invoker, + extractClassName( classOrMethod ), + nameAndTags, + lineInfo)); + } CATCH_CATCH_ALL { + // Do not throw when constructing global objects, instead register the exception to be processed later + getMutableRegistryHub().registerStartupException(); + } + } + + AutoReg::~AutoReg() = default; +} +// end catch_test_registry.cpp +// start catch_test_spec.cpp + +#include <algorithm> +#include <string> +#include <vector> +#include <memory> + +namespace Catch { + + TestSpec::Pattern::Pattern( std::string const& name ) + : m_name( name ) + {} + + TestSpec::Pattern::~Pattern() = default; + + std::string const& TestSpec::Pattern::name() const { + return m_name; + } + + TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString ) + : Pattern( filterString ) + , m_wildcardPattern( toLower( name ), CaseSensitive::No ) + {} + + bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const { + return m_wildcardPattern.matches( testCase.name ); + } + + TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString ) + : Pattern( filterString ) + , m_tag( toLower( tag ) ) + {} + + bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const { + return std::find(begin(testCase.lcaseTags), + end(testCase.lcaseTags), + m_tag) != end(testCase.lcaseTags); + } + + TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) + : Pattern( underlyingPattern->name() ) + , m_underlyingPattern( underlyingPattern ) + {} + + bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { + return !m_underlyingPattern->matches( testCase ); + } + + bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const { + return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } ); + } + + std::string TestSpec::Filter::name() const { + std::string name; + for( auto const& p : m_patterns ) + name += p->name(); + return name; + } + + bool TestSpec::hasFilters() const { + return !m_filters.empty(); + } + + bool TestSpec::matches( TestCaseInfo const& testCase ) const { + return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } ); + } + + TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const + { + Matches matches( m_filters.size() ); + std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){ + std::vector<TestCase const*> currentMatches; + for( auto const& test : testCases ) + if( isThrowSafe( test, config ) && filter.matches( test ) ) + currentMatches.emplace_back( &test ); + return FilterMatch{ filter.name(), currentMatches }; + } ); + return matches; + } + + const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{ + return (m_invalidArgs); + } + +} +// end catch_test_spec.cpp +// start catch_test_spec_parser.cpp + +namespace Catch { + + TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} + + TestSpecParser& TestSpecParser::parse( std::string const& arg ) { + m_mode = None; + m_exclusion = false; + m_arg = m_tagAliases->expandAliases( arg ); + m_escapeChars.clear(); + m_substring.reserve(m_arg.size()); + m_patternName.reserve(m_arg.size()); + m_realPatternPos = 0; + + for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) + //if visitChar fails + if( !visitChar( m_arg[m_pos] ) ){ + m_testSpec.m_invalidArgs.push_back(arg); + break; + } + endMode(); + return *this; + } + TestSpec TestSpecParser::testSpec() { + addFilter(); + return m_testSpec; + } + bool TestSpecParser::visitChar( char c ) { + if( (m_mode != EscapedName) && (c == '\\') ) { + escape(); + addCharToPattern(c); + return true; + }else if((m_mode != EscapedName) && (c == ',') ) { + return separate(); + } + + switch( m_mode ) { + case None: + if( processNoneChar( c ) ) + return true; + break; + case Name: + processNameChar( c ); + break; + case EscapedName: + endMode(); + addCharToPattern(c); + return true; + default: + case Tag: + case QuotedName: + if( processOtherChar( c ) ) + return true; + break; + } + + m_substring += c; + if( !isControlChar( c ) ) { + m_patternName += c; + m_realPatternPos++; + } + return true; + } + // Two of the processing methods return true to signal the caller to return + // without adding the given character to the current pattern strings + bool TestSpecParser::processNoneChar( char c ) { + switch( c ) { + case ' ': + return true; + case '~': + m_exclusion = true; + return false; + case '[': + startNewMode( Tag ); + return false; + case '"': + startNewMode( QuotedName ); + return false; + default: + startNewMode( Name ); + return false; + } + } + void TestSpecParser::processNameChar( char c ) { + if( c == '[' ) { + if( m_substring == "exclude:" ) + m_exclusion = true; + else + endMode(); + startNewMode( Tag ); + } + } + bool TestSpecParser::processOtherChar( char c ) { + if( !isControlChar( c ) ) + return false; + m_substring += c; + endMode(); + return true; + } + void TestSpecParser::startNewMode( Mode mode ) { + m_mode = mode; + } + void TestSpecParser::endMode() { + switch( m_mode ) { + case Name: + case QuotedName: + return addNamePattern(); + case Tag: + return addTagPattern(); + case EscapedName: + revertBackToLastMode(); + return; + case None: + default: + return startNewMode( None ); + } + } + void TestSpecParser::escape() { + saveLastMode(); + m_mode = EscapedName; + m_escapeChars.push_back(m_realPatternPos); + } + bool TestSpecParser::isControlChar( char c ) const { + switch( m_mode ) { + default: + return false; + case None: + return c == '~'; + case Name: + return c == '['; + case EscapedName: + return true; + case QuotedName: + return c == '"'; + case Tag: + return c == '[' || c == ']'; + } + } + + void TestSpecParser::addFilter() { + if( !m_currentFilter.m_patterns.empty() ) { + m_testSpec.m_filters.push_back( m_currentFilter ); + m_currentFilter = TestSpec::Filter(); + } + } + + void TestSpecParser::saveLastMode() { + lastMode = m_mode; + } + + void TestSpecParser::revertBackToLastMode() { + m_mode = lastMode; + } + + bool TestSpecParser::separate() { + if( (m_mode==QuotedName) || (m_mode==Tag) ){ + //invalid argument, signal failure to previous scope. + m_mode = None; + m_pos = m_arg.size(); + m_substring.clear(); + m_patternName.clear(); + m_realPatternPos = 0; + return false; + } + endMode(); + addFilter(); + return true; //success + } + + std::string TestSpecParser::preprocessPattern() { + std::string token = m_patternName; + for (std::size_t i = 0; i < m_escapeChars.size(); ++i) + token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1); + m_escapeChars.clear(); + if (startsWith(token, "exclude:")) { + m_exclusion = true; + token = token.substr(8); + } + + m_patternName.clear(); + m_realPatternPos = 0; + + return token; + } + + void TestSpecParser::addNamePattern() { + auto token = preprocessPattern(); + + if (!token.empty()) { + TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring); + if (m_exclusion) + pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern); + m_currentFilter.m_patterns.push_back(pattern); + } + m_substring.clear(); + m_exclusion = false; + m_mode = None; + } + + void TestSpecParser::addTagPattern() { + auto token = preprocessPattern(); + + if (!token.empty()) { + // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo]) + // we have to create a separate hide tag and shorten the real one + if (token.size() > 1 && token[0] == '.') { + token.erase(token.begin()); + TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring); + if (m_exclusion) { + pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern); + } + m_currentFilter.m_patterns.push_back(pattern); + } + + TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring); + + if (m_exclusion) { + pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern); + } + m_currentFilter.m_patterns.push_back(pattern); + } + m_substring.clear(); + m_exclusion = false; + m_mode = None; + } + + TestSpec parseTestSpec( std::string const& arg ) { + return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); + } + +} // namespace Catch +// end catch_test_spec_parser.cpp +// start catch_timer.cpp + +#include <chrono> + +static const uint64_t nanosecondsInSecond = 1000000000; + +namespace Catch { + + auto getCurrentNanosecondsSinceEpoch() -> uint64_t { + return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count(); + } + + namespace { + auto estimateClockResolution() -> uint64_t { + uint64_t sum = 0; + static const uint64_t iterations = 1000000; + + auto startTime = getCurrentNanosecondsSinceEpoch(); + + for( std::size_t i = 0; i < iterations; ++i ) { + + uint64_t ticks; + uint64_t baseTicks = getCurrentNanosecondsSinceEpoch(); + do { + ticks = getCurrentNanosecondsSinceEpoch(); + } while( ticks == baseTicks ); + + auto delta = ticks - baseTicks; + sum += delta; + + // If we have been calibrating for over 3 seconds -- the clock + // is terrible and we should move on. + // TBD: How to signal that the measured resolution is probably wrong? + if (ticks > startTime + 3 * nanosecondsInSecond) { + return sum / ( i + 1u ); + } + } + + // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers + // - and potentially do more iterations if there's a high variance. + return sum/iterations; + } + } + auto getEstimatedClockResolution() -> uint64_t { + static auto s_resolution = estimateClockResolution(); + return s_resolution; + } + + void Timer::start() { + m_nanoseconds = getCurrentNanosecondsSinceEpoch(); + } + auto Timer::getElapsedNanoseconds() const -> uint64_t { + return getCurrentNanosecondsSinceEpoch() - m_nanoseconds; + } + auto Timer::getElapsedMicroseconds() const -> uint64_t { + return getElapsedNanoseconds()/1000; + } + auto Timer::getElapsedMilliseconds() const -> unsigned int { + return static_cast<unsigned int>(getElapsedMicroseconds()/1000); + } + auto Timer::getElapsedSeconds() const -> double { + return getElapsedMicroseconds()/1000000.0; + } + +} // namespace Catch +// end catch_timer.cpp +// start catch_tostring.cpp + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +# pragma clang diagnostic ignored "-Wglobal-constructors" +#endif + +// Enable specific decls locally +#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +#endif + +#include <cmath> +#include <iomanip> + +namespace Catch { + +namespace Detail { + + const std::string unprintableString = "{?}"; + + namespace { + const int hexThreshold = 255; + + struct Endianness { + enum Arch { Big, Little }; + + static Arch which() { + int one = 1; + // If the lowest byte we read is non-zero, we can assume + // that little endian format is used. + auto value = *reinterpret_cast<char*>(&one); + return value ? Little : Big; + } + }; + } + + std::string rawMemoryToString( const void *object, std::size_t size ) { + // Reverse order for little endian architectures + int i = 0, end = static_cast<int>( size ), inc = 1; + if( Endianness::which() == Endianness::Little ) { + i = end-1; + end = inc = -1; + } + + unsigned char const *bytes = static_cast<unsigned char const *>(object); + ReusableStringStream rss; + rss << "0x" << std::setfill('0') << std::hex; + for( ; i != end; i += inc ) + rss << std::setw(2) << static_cast<unsigned>(bytes[i]); + return rss.str(); + } +} + +template<typename T> +std::string fpToString( T value, int precision ) { + if (Catch::isnan(value)) { + return "nan"; + } + + ReusableStringStream rss; + rss << std::setprecision( precision ) + << std::fixed + << value; + std::string d = rss.str(); + std::size_t i = d.find_last_not_of( '0' ); + if( i != std::string::npos && i != d.size()-1 ) { + if( d[i] == '.' ) + i++; + d = d.substr( 0, i+1 ); + } + return d; +} + +//// ======================================================= //// +// +// Out-of-line defs for full specialization of StringMaker +// +//// ======================================================= //// + +std::string StringMaker<std::string>::convert(const std::string& str) { + if (!getCurrentContext().getConfig()->showInvisibles()) { + return '"' + str + '"'; + } + + std::string s("\""); + for (char c : str) { + switch (c) { + case '\n': + s.append("\\n"); + break; + case '\t': + s.append("\\t"); + break; + default: + s.push_back(c); + break; + } + } + s.append("\""); + return s; +} + +#ifdef CATCH_CONFIG_CPP17_STRING_VIEW +std::string StringMaker<std::string_view>::convert(std::string_view str) { + return ::Catch::Detail::stringify(std::string{ str }); +} +#endif + +std::string StringMaker<char const*>::convert(char const* str) { + if (str) { + return ::Catch::Detail::stringify(std::string{ str }); + } else { + return{ "{null string}" }; + } +} +std::string StringMaker<char*>::convert(char* str) { + if (str) { + return ::Catch::Detail::stringify(std::string{ str }); + } else { + return{ "{null string}" }; + } +} + +#ifdef CATCH_CONFIG_WCHAR +std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) { + std::string s; + s.reserve(wstr.size()); + for (auto c : wstr) { + s += (c <= 0xff) ? static_cast<char>(c) : '?'; + } + return ::Catch::Detail::stringify(s); +} + +# ifdef CATCH_CONFIG_CPP17_STRING_VIEW +std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) { + return StringMaker<std::wstring>::convert(std::wstring(str)); +} +# endif + +std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) { + if (str) { + return ::Catch::Detail::stringify(std::wstring{ str }); + } else { + return{ "{null string}" }; + } +} +std::string StringMaker<wchar_t *>::convert(wchar_t * str) { + if (str) { + return ::Catch::Detail::stringify(std::wstring{ str }); + } else { + return{ "{null string}" }; + } +} +#endif + +#if defined(CATCH_CONFIG_CPP17_BYTE) +#include <cstddef> +std::string StringMaker<std::byte>::convert(std::byte value) { + return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value)); +} +#endif // defined(CATCH_CONFIG_CPP17_BYTE) + +std::string StringMaker<int>::convert(int value) { + return ::Catch::Detail::stringify(static_cast<long long>(value)); +} +std::string StringMaker<long>::convert(long value) { + return ::Catch::Detail::stringify(static_cast<long long>(value)); +} +std::string StringMaker<long long>::convert(long long value) { + ReusableStringStream rss; + rss << value; + if (value > Detail::hexThreshold) { + rss << " (0x" << std::hex << value << ')'; + } + return rss.str(); +} + +std::string StringMaker<unsigned int>::convert(unsigned int value) { + return ::Catch::Detail::stringify(static_cast<unsigned long long>(value)); +} +std::string StringMaker<unsigned long>::convert(unsigned long value) { + return ::Catch::Detail::stringify(static_cast<unsigned long long>(value)); +} +std::string StringMaker<unsigned long long>::convert(unsigned long long value) { + ReusableStringStream rss; + rss << value; + if (value > Detail::hexThreshold) { + rss << " (0x" << std::hex << value << ')'; + } + return rss.str(); +} + +std::string StringMaker<bool>::convert(bool b) { + return b ? "true" : "false"; +} + +std::string StringMaker<signed char>::convert(signed char value) { + if (value == '\r') { + return "'\\r'"; + } else if (value == '\f') { + return "'\\f'"; + } else if (value == '\n') { + return "'\\n'"; + } else if (value == '\t') { + return "'\\t'"; + } else if ('\0' <= value && value < ' ') { + return ::Catch::Detail::stringify(static_cast<unsigned int>(value)); + } else { + char chstr[] = "' '"; + chstr[1] = value; + return chstr; + } +} +std::string StringMaker<char>::convert(char c) { + return ::Catch::Detail::stringify(static_cast<signed char>(c)); +} +std::string StringMaker<unsigned char>::convert(unsigned char c) { + return ::Catch::Detail::stringify(static_cast<char>(c)); +} + +std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) { + return "nullptr"; +} + +int StringMaker<float>::precision = 5; + +std::string StringMaker<float>::convert(float value) { + return fpToString(value, precision) + 'f'; +} + +int StringMaker<double>::precision = 10; + +std::string StringMaker<double>::convert(double value) { + return fpToString(value, precision); +} + +std::string ratio_string<std::atto>::symbol() { return "a"; } +std::string ratio_string<std::femto>::symbol() { return "f"; } +std::string ratio_string<std::pico>::symbol() { return "p"; } +std::string ratio_string<std::nano>::symbol() { return "n"; } +std::string ratio_string<std::micro>::symbol() { return "u"; } +std::string ratio_string<std::milli>::symbol() { return "m"; } + +} // end namespace Catch + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +// end catch_tostring.cpp +// start catch_totals.cpp + +namespace Catch { + + Counts Counts::operator - ( Counts const& other ) const { + Counts diff; + diff.passed = passed - other.passed; + diff.failed = failed - other.failed; + diff.failedButOk = failedButOk - other.failedButOk; + return diff; + } + + Counts& Counts::operator += ( Counts const& other ) { + passed += other.passed; + failed += other.failed; + failedButOk += other.failedButOk; + return *this; + } + + std::size_t Counts::total() const { + return passed + failed + failedButOk; + } + bool Counts::allPassed() const { + return failed == 0 && failedButOk == 0; + } + bool Counts::allOk() const { + return failed == 0; + } + + Totals Totals::operator - ( Totals const& other ) const { + Totals diff; + diff.assertions = assertions - other.assertions; + diff.testCases = testCases - other.testCases; + return diff; + } + + Totals& Totals::operator += ( Totals const& other ) { + assertions += other.assertions; + testCases += other.testCases; + return *this; + } + + Totals Totals::delta( Totals const& prevTotals ) const { + Totals diff = *this - prevTotals; + if( diff.assertions.failed > 0 ) + ++diff.testCases.failed; + else if( diff.assertions.failedButOk > 0 ) + ++diff.testCases.failedButOk; + else + ++diff.testCases.passed; + return diff; + } + +} +// end catch_totals.cpp +// start catch_uncaught_exceptions.cpp + +// start catch_config_uncaught_exceptions.hpp + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP +#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP + +#if defined(_MSC_VER) +# if _MSC_VER >= 1900 // Visual Studio 2015 or newer +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +# endif +#endif + +#include <exception> + +#if defined(__cpp_lib_uncaught_exceptions) \ + && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) + +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif // __cpp_lib_uncaught_exceptions + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \ + && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \ + && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) + +# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP +// end catch_config_uncaught_exceptions.hpp +#include <exception> + +namespace Catch { + bool uncaught_exceptions() { +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + return false; +#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) + return std::uncaught_exceptions() > 0; +#else + return std::uncaught_exception(); +#endif + } +} // end namespace Catch +// end catch_uncaught_exceptions.cpp +// start catch_version.cpp + +#include <ostream> + +namespace Catch { + + Version::Version + ( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + char const * const _branchName, + unsigned int _buildNumber ) + : majorVersion( _majorVersion ), + minorVersion( _minorVersion ), + patchNumber( _patchNumber ), + branchName( _branchName ), + buildNumber( _buildNumber ) + {} + + std::ostream& operator << ( std::ostream& os, Version const& version ) { + os << version.majorVersion << '.' + << version.minorVersion << '.' + << version.patchNumber; + // branchName is never null -> 0th char is \0 if it is empty + if (version.branchName[0]) { + os << '-' << version.branchName + << '.' << version.buildNumber; + } + return os; + } + + Version const& libraryVersion() { + static Version version( 2, 13, 9, "", 0 ); + return version; + } + +} +// end catch_version.cpp +// start catch_wildcard_pattern.cpp + +namespace Catch { + + WildcardPattern::WildcardPattern( std::string const& pattern, + CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_pattern( normaliseString( pattern ) ) + { + if( startsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 1 ); + m_wildcard = WildcardAtStart; + } + if( endsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); + m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd ); + } + } + + bool WildcardPattern::matches( std::string const& str ) const { + switch( m_wildcard ) { + case NoWildcard: + return m_pattern == normaliseString( str ); + case WildcardAtStart: + return endsWith( normaliseString( str ), m_pattern ); + case WildcardAtEnd: + return startsWith( normaliseString( str ), m_pattern ); + case WildcardAtBothEnds: + return contains( normaliseString( str ), m_pattern ); + default: + CATCH_INTERNAL_ERROR( "Unknown enum" ); + } + } + + std::string WildcardPattern::normaliseString( std::string const& str ) const { + return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str ); + } +} +// end catch_wildcard_pattern.cpp +// start catch_xmlwriter.cpp + +#include <iomanip> +#include <type_traits> + +namespace Catch { + +namespace { + + size_t trailingBytes(unsigned char c) { + if ((c & 0xE0) == 0xC0) { + return 2; + } + if ((c & 0xF0) == 0xE0) { + return 3; + } + if ((c & 0xF8) == 0xF0) { + return 4; + } + CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); + } + + uint32_t headerValue(unsigned char c) { + if ((c & 0xE0) == 0xC0) { + return c & 0x1F; + } + if ((c & 0xF0) == 0xE0) { + return c & 0x0F; + } + if ((c & 0xF8) == 0xF0) { + return c & 0x07; + } + CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); + } + + void hexEscapeChar(std::ostream& os, unsigned char c) { + std::ios_base::fmtflags f(os.flags()); + os << "\\x" + << std::uppercase << std::hex << std::setfill('0') << std::setw(2) + << static_cast<int>(c); + os.flags(f); + } + + bool shouldNewline(XmlFormatting fmt) { + return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline)); + } + + bool shouldIndent(XmlFormatting fmt) { + return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent)); + } + +} // anonymous namespace + + XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) { + return static_cast<XmlFormatting>( + static_cast<std::underlying_type<XmlFormatting>::type>(lhs) | + static_cast<std::underlying_type<XmlFormatting>::type>(rhs) + ); + } + + XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) { + return static_cast<XmlFormatting>( + static_cast<std::underlying_type<XmlFormatting>::type>(lhs) & + static_cast<std::underlying_type<XmlFormatting>::type>(rhs) + ); + } + + XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat ) + : m_str( str ), + m_forWhat( forWhat ) + {} + + void XmlEncode::encodeTo( std::ostream& os ) const { + // Apostrophe escaping not necessary if we always use " to write attributes + // (see: http://www.w3.org/TR/xml/#syntax) + + for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) { + unsigned char c = m_str[idx]; + switch (c) { + case '<': os << "<"; break; + case '&': os << "&"; break; + + case '>': + // See: http://www.w3.org/TR/xml/#syntax + if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') + os << ">"; + else + os << c; + break; + + case '\"': + if (m_forWhat == ForAttributes) + os << """; + else + os << c; + break; + + default: + // Check for control characters and invalid utf-8 + + // Escape control characters in standard ascii + // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { + hexEscapeChar(os, c); + break; + } + + // Plain ASCII: Write it to stream + if (c < 0x7F) { + os << c; + break; + } + + // UTF-8 territory + // Check if the encoding is valid and if it is not, hex escape bytes. + // Important: We do not check the exact decoded values for validity, only the encoding format + // First check that this bytes is a valid lead byte: + // This means that it is not encoded as 1111 1XXX + // Or as 10XX XXXX + if (c < 0xC0 || + c >= 0xF8) { + hexEscapeChar(os, c); + break; + } + + auto encBytes = trailingBytes(c); + // Are there enough bytes left to avoid accessing out-of-bounds memory? + if (idx + encBytes - 1 >= m_str.size()) { + hexEscapeChar(os, c); + break; + } + // The header is valid, check data + // The next encBytes bytes must together be a valid utf-8 + // This means: bitpattern 10XX XXXX and the extracted value is sane (ish) + bool valid = true; + uint32_t value = headerValue(c); + for (std::size_t n = 1; n < encBytes; ++n) { + unsigned char nc = m_str[idx + n]; + valid &= ((nc & 0xC0) == 0x80); + value = (value << 6) | (nc & 0x3F); + } + + if ( + // Wrong bit pattern of following bytes + (!valid) || + // Overlong encodings + (value < 0x80) || + (0x80 <= value && value < 0x800 && encBytes > 2) || + (0x800 < value && value < 0x10000 && encBytes > 3) || + // Encoded value out of range + (value >= 0x110000) + ) { + hexEscapeChar(os, c); + break; + } + + // If we got here, this is in fact a valid(ish) utf-8 sequence + for (std::size_t n = 0; n < encBytes; ++n) { + os << m_str[idx + n]; + } + idx += encBytes - 1; + break; + } + } + } + + std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { + xmlEncode.encodeTo( os ); + return os; + } + + XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt ) + : m_writer( writer ), + m_fmt(fmt) + {} + + XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept + : m_writer( other.m_writer ), + m_fmt(other.m_fmt) + { + other.m_writer = nullptr; + other.m_fmt = XmlFormatting::None; + } + XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept { + if ( m_writer ) { + m_writer->endElement(); + } + m_writer = other.m_writer; + other.m_writer = nullptr; + m_fmt = other.m_fmt; + other.m_fmt = XmlFormatting::None; + return *this; + } + + XmlWriter::ScopedElement::~ScopedElement() { + if (m_writer) { + m_writer->endElement(m_fmt); + } + } + + XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) { + m_writer->writeText( text, fmt ); + return *this; + } + + XmlWriter::XmlWriter( std::ostream& os ) : m_os( os ) + { + writeDeclaration(); + } + + XmlWriter::~XmlWriter() { + while (!m_tags.empty()) { + endElement(); + } + newlineIfNecessary(); + } + + XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) { + ensureTagClosed(); + newlineIfNecessary(); + if (shouldIndent(fmt)) { + m_os << m_indent; + m_indent += " "; + } + m_os << '<' << name; + m_tags.push_back( name ); + m_tagIsOpen = true; + applyFormatting(fmt); + return *this; + } + + XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) { + ScopedElement scoped( this, fmt ); + startElement( name, fmt ); + return scoped; + } + + XmlWriter& XmlWriter::endElement(XmlFormatting fmt) { + m_indent = m_indent.substr(0, m_indent.size() - 2); + + if( m_tagIsOpen ) { + m_os << "/>"; + m_tagIsOpen = false; + } else { + newlineIfNecessary(); + if (shouldIndent(fmt)) { + m_os << m_indent; + } + m_os << "</" << m_tags.back() << ">"; + } + m_os << std::flush; + applyFormatting(fmt); + m_tags.pop_back(); + return *this; + } + + XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) { + if( !name.empty() && !attribute.empty() ) + m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; + return *this; + } + + XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) { + m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; + return *this; + } + + XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) { + if( !text.empty() ){ + bool tagWasOpen = m_tagIsOpen; + ensureTagClosed(); + if (tagWasOpen && shouldIndent(fmt)) { + m_os << m_indent; + } + m_os << XmlEncode( text ); + applyFormatting(fmt); + } + return *this; + } + + XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) { + ensureTagClosed(); + if (shouldIndent(fmt)) { + m_os << m_indent; + } + m_os << "<!--" << text << "-->"; + applyFormatting(fmt); + return *this; + } + + void XmlWriter::writeStylesheetRef( std::string const& url ) { + m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n"; + } + + XmlWriter& XmlWriter::writeBlankLine() { + ensureTagClosed(); + m_os << '\n'; + return *this; + } + + void XmlWriter::ensureTagClosed() { + if( m_tagIsOpen ) { + m_os << '>' << std::flush; + newlineIfNecessary(); + m_tagIsOpen = false; + } + } + + void XmlWriter::applyFormatting(XmlFormatting fmt) { + m_needsNewline = shouldNewline(fmt); + } + + void XmlWriter::writeDeclaration() { + m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; + } + + void XmlWriter::newlineIfNecessary() { + if( m_needsNewline ) { + m_os << std::endl; + m_needsNewline = false; + } + } +} +// end catch_xmlwriter.cpp +// start catch_reporter_bases.cpp + +#include <cstring> +#include <cfloat> +#include <cstdio> +#include <cassert> +#include <memory> + +namespace Catch { + void prepareExpandedExpression(AssertionResult& result) { + result.getExpandedExpression(); + } + + // Because formatting using c++ streams is stateful, drop down to C is required + // Alternatively we could use stringstream, but its performance is... not good. + std::string getFormattedDuration( double duration ) { + // Max exponent + 1 is required to represent the whole part + // + 1 for decimal point + // + 3 for the 3 decimal places + // + 1 for null terminator + const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; + char buffer[maxDoubleSize]; + + // Save previous errno, to prevent sprintf from overwriting it + ErrnoGuard guard; +#ifdef _MSC_VER + sprintf_s(buffer, "%.3f", duration); +#else + std::sprintf(buffer, "%.3f", duration); +#endif + return std::string(buffer); + } + + bool shouldShowDuration( IConfig const& config, double duration ) { + if ( config.showDurations() == ShowDurations::Always ) { + return true; + } + if ( config.showDurations() == ShowDurations::Never ) { + return false; + } + const double min = config.minDuration(); + return min >= 0 && duration >= min; + } + + std::string serializeFilters( std::vector<std::string> const& container ) { + ReusableStringStream oss; + bool first = true; + for (auto&& filter : container) + { + if (!first) + oss << ' '; + else + first = false; + + oss << filter; + } + return oss.str(); + } + + TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config) + :StreamingReporterBase(_config) {} + + std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() { + return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High }; + } + + void TestEventListenerBase::assertionStarting(AssertionInfo const &) {} + + bool TestEventListenerBase::assertionEnded(AssertionStats const &) { + return false; + } + +} // end namespace Catch +// end catch_reporter_bases.cpp +// start catch_reporter_compact.cpp + +namespace { + +#ifdef CATCH_PLATFORM_MAC + const char* failedString() { return "FAILED"; } + const char* passedString() { return "PASSED"; } +#else + const char* failedString() { return "failed"; } + const char* passedString() { return "passed"; } +#endif + + // Colour::LightGrey + Catch::Colour::Code dimColour() { return Catch::Colour::FileName; } + + std::string bothOrAll( std::size_t count ) { + return count == 1 ? std::string() : + count == 2 ? "both " : "all " ; + } + +} // anon namespace + +namespace Catch { +namespace { +// Colour, message variants: +// - white: No tests ran. +// - red: Failed [both/all] N test cases, failed [both/all] M assertions. +// - white: Passed [both/all] N test cases (no assertions). +// - red: Failed N tests cases, failed M assertions. +// - green: Passed [both/all] N tests cases with M assertions. +void printTotals(std::ostream& out, const Totals& totals) { + if (totals.testCases.total() == 0) { + out << "No tests ran."; + } else if (totals.testCases.failed == totals.testCases.total()) { + Colour colour(Colour::ResultError); + const std::string qualify_assertions_failed = + totals.assertions.failed == totals.assertions.total() ? + bothOrAll(totals.assertions.failed) : std::string(); + out << + "Failed " << bothOrAll(totals.testCases.failed) + << pluralise(totals.testCases.failed, "test case") << ", " + "failed " << qualify_assertions_failed << + pluralise(totals.assertions.failed, "assertion") << '.'; + } else if (totals.assertions.total() == 0) { + out << + "Passed " << bothOrAll(totals.testCases.total()) + << pluralise(totals.testCases.total(), "test case") + << " (no assertions)."; + } else if (totals.assertions.failed) { + Colour colour(Colour::ResultError); + out << + "Failed " << pluralise(totals.testCases.failed, "test case") << ", " + "failed " << pluralise(totals.assertions.failed, "assertion") << '.'; + } else { + Colour colour(Colour::ResultSuccess); + out << + "Passed " << bothOrAll(totals.testCases.passed) + << pluralise(totals.testCases.passed, "test case") << + " with " << pluralise(totals.assertions.passed, "assertion") << '.'; + } +} + +// Implementation of CompactReporter formatting +class AssertionPrinter { +public: + AssertionPrinter& operator= (AssertionPrinter const&) = delete; + AssertionPrinter(AssertionPrinter const&) = delete; + AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages) + : stream(_stream) + , result(_stats.assertionResult) + , messages(_stats.infoMessages) + , itMessage(_stats.infoMessages.begin()) + , printInfoMessages(_printInfoMessages) {} + + void print() { + printSourceInfo(); + + itMessage = messages.begin(); + + switch (result.getResultType()) { + case ResultWas::Ok: + printResultType(Colour::ResultSuccess, passedString()); + printOriginalExpression(); + printReconstructedExpression(); + if (!result.hasExpression()) + printRemainingMessages(Colour::None); + else + printRemainingMessages(); + break; + case ResultWas::ExpressionFailed: + if (result.isOk()) + printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok")); + else + printResultType(Colour::Error, failedString()); + printOriginalExpression(); + printReconstructedExpression(); + printRemainingMessages(); + break; + case ResultWas::ThrewException: + printResultType(Colour::Error, failedString()); + printIssue("unexpected exception with message:"); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::FatalErrorCondition: + printResultType(Colour::Error, failedString()); + printIssue("fatal error condition with message:"); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::DidntThrowException: + printResultType(Colour::Error, failedString()); + printIssue("expected exception, got none"); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::Info: + printResultType(Colour::None, "info"); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::Warning: + printResultType(Colour::None, "warning"); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::ExplicitFailure: + printResultType(Colour::Error, failedString()); + printIssue("explicitly"); + printRemainingMessages(Colour::None); + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + printResultType(Colour::Error, "** internal error **"); + break; + } + } + +private: + void printSourceInfo() const { + Colour colourGuard(Colour::FileName); + stream << result.getSourceInfo() << ':'; + } + + void printResultType(Colour::Code colour, std::string const& passOrFail) const { + if (!passOrFail.empty()) { + { + Colour colourGuard(colour); + stream << ' ' << passOrFail; + } + stream << ':'; + } + } + + void printIssue(std::string const& issue) const { + stream << ' ' << issue; + } + + void printExpressionWas() { + if (result.hasExpression()) { + stream << ';'; + { + Colour colour(dimColour()); + stream << " expression was:"; + } + printOriginalExpression(); + } + } + + void printOriginalExpression() const { + if (result.hasExpression()) { + stream << ' ' << result.getExpression(); + } + } + + void printReconstructedExpression() const { + if (result.hasExpandedExpression()) { + { + Colour colour(dimColour()); + stream << " for: "; + } + stream << result.getExpandedExpression(); + } + } + + void printMessage() { + if (itMessage != messages.end()) { + stream << " '" << itMessage->message << '\''; + ++itMessage; + } + } + + void printRemainingMessages(Colour::Code colour = dimColour()) { + if (itMessage == messages.end()) + return; + + const auto itEnd = messages.cend(); + const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd)); + + { + Colour colourGuard(colour); + stream << " with " << pluralise(N, "message") << ':'; + } + + while (itMessage != itEnd) { + // If this assertion is a warning ignore any INFO messages + if (printInfoMessages || itMessage->type != ResultWas::Info) { + printMessage(); + if (itMessage != itEnd) { + Colour colourGuard(dimColour()); + stream << " and"; + } + continue; + } + ++itMessage; + } + } + +private: + std::ostream& stream; + AssertionResult const& result; + std::vector<MessageInfo> messages; + std::vector<MessageInfo>::const_iterator itMessage; + bool printInfoMessages; +}; + +} // anon namespace + + std::string CompactReporter::getDescription() { + return "Reports test results on a single line, suitable for IDEs"; + } + + void CompactReporter::noMatchingTestCases( std::string const& spec ) { + stream << "No test cases matched '" << spec << '\'' << std::endl; + } + + void CompactReporter::assertionStarting( AssertionInfo const& ) {} + + bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) { + AssertionResult const& result = _assertionStats.assertionResult; + + bool printInfoMessages = true; + + // Drop out if result was successful and we're not printing those + if( !m_config->includeSuccessfulResults() && result.isOk() ) { + if( result.getResultType() != ResultWas::Warning ) + return false; + printInfoMessages = false; + } + + AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); + printer.print(); + + stream << std::endl; + return true; + } + + void CompactReporter::sectionEnded(SectionStats const& _sectionStats) { + double dur = _sectionStats.durationInSeconds; + if ( shouldShowDuration( *m_config, dur ) ) { + stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << std::endl; + } + } + + void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) { + printTotals( stream, _testRunStats.totals ); + stream << '\n' << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + CompactReporter::~CompactReporter() {} + + CATCH_REGISTER_REPORTER( "compact", CompactReporter ) + +} // end namespace Catch +// end catch_reporter_compact.cpp +// start catch_reporter_console.cpp + +#include <cfloat> +#include <cstdio> + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch + // Note that 4062 (not all labels are handled and default is missing) is enabled +#endif + +#if defined(__clang__) +# pragma clang diagnostic push +// For simplicity, benchmarking-only helpers are always enabled +# pragma clang diagnostic ignored "-Wunused-function" +#endif + +namespace Catch { + +namespace { + +// Formatter impl for ConsoleReporter +class ConsoleAssertionPrinter { +public: + ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete; + ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete; + ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages) + : stream(_stream), + stats(_stats), + result(_stats.assertionResult), + colour(Colour::None), + message(result.getMessage()), + messages(_stats.infoMessages), + printInfoMessages(_printInfoMessages) { + switch (result.getResultType()) { + case ResultWas::Ok: + colour = Colour::Success; + passOrFail = "PASSED"; + //if( result.hasMessage() ) + if (_stats.infoMessages.size() == 1) + messageLabel = "with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "with messages"; + break; + case ResultWas::ExpressionFailed: + if (result.isOk()) { + colour = Colour::Success; + passOrFail = "FAILED - but was ok"; + } else { + colour = Colour::Error; + passOrFail = "FAILED"; + } + if (_stats.infoMessages.size() == 1) + messageLabel = "with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "with messages"; + break; + case ResultWas::ThrewException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to unexpected exception with "; + if (_stats.infoMessages.size() == 1) + messageLabel += "message"; + if (_stats.infoMessages.size() > 1) + messageLabel += "messages"; + break; + case ResultWas::FatalErrorCondition: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to a fatal error condition"; + break; + case ResultWas::DidntThrowException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "because no exception was thrown where one was expected"; + break; + case ResultWas::Info: + messageLabel = "info"; + break; + case ResultWas::Warning: + messageLabel = "warning"; + break; + case ResultWas::ExplicitFailure: + passOrFail = "FAILED"; + colour = Colour::Error; + if (_stats.infoMessages.size() == 1) + messageLabel = "explicitly with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "explicitly with messages"; + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + passOrFail = "** internal error **"; + colour = Colour::Error; + break; + } + } + + void print() const { + printSourceInfo(); + if (stats.totals.assertions.total() > 0) { + printResultType(); + printOriginalExpression(); + printReconstructedExpression(); + } else { + stream << '\n'; + } + printMessage(); + } + +private: + void printResultType() const { + if (!passOrFail.empty()) { + Colour colourGuard(colour); + stream << passOrFail << ":\n"; + } + } + void printOriginalExpression() const { + if (result.hasExpression()) { + Colour colourGuard(Colour::OriginalExpression); + stream << " "; + stream << result.getExpressionInMacro(); + stream << '\n'; + } + } + void printReconstructedExpression() const { + if (result.hasExpandedExpression()) { + stream << "with expansion:\n"; + Colour colourGuard(Colour::ReconstructedExpression); + stream << Column(result.getExpandedExpression()).indent(2) << '\n'; + } + } + void printMessage() const { + if (!messageLabel.empty()) + stream << messageLabel << ':' << '\n'; + for (auto const& msg : messages) { + // If this assertion is a warning ignore any INFO messages + if (printInfoMessages || msg.type != ResultWas::Info) + stream << Column(msg.message).indent(2) << '\n'; + } + } + void printSourceInfo() const { + Colour colourGuard(Colour::FileName); + stream << result.getSourceInfo() << ": "; + } + + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + Colour::Code colour; + std::string passOrFail; + std::string messageLabel; + std::string message; + std::vector<MessageInfo> messages; + bool printInfoMessages; +}; + +std::size_t makeRatio(std::size_t number, std::size_t total) { + std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0; + return (ratio == 0 && number > 0) ? 1 : ratio; +} + +std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) { + if (i > j && i > k) + return i; + else if (j > k) + return j; + else + return k; +} + +struct ColumnInfo { + enum Justification { Left, Right }; + std::string name; + int width; + Justification justification; +}; +struct ColumnBreak {}; +struct RowBreak {}; + +class Duration { + enum class Unit { + Auto, + Nanoseconds, + Microseconds, + Milliseconds, + Seconds, + Minutes + }; + static const uint64_t s_nanosecondsInAMicrosecond = 1000; + static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond; + static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond; + static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond; + + double m_inNanoseconds; + Unit m_units; + +public: + explicit Duration(double inNanoseconds, Unit units = Unit::Microseconds) + : m_inNanoseconds(inNanoseconds), + m_units(units) { + if (m_units == Unit::Auto) { + if (m_inNanoseconds < s_nanosecondsInAMicrosecond) + m_units = Unit::Nanoseconds; + else if (m_inNanoseconds < s_nanosecondsInAMillisecond) + m_units = Unit::Microseconds; + else if (m_inNanoseconds < s_nanosecondsInASecond) + m_units = Unit::Milliseconds; + else if (m_inNanoseconds < s_nanosecondsInAMinute) + m_units = Unit::Seconds; + else + m_units = Unit::Minutes; + } + + } + + auto value() const -> double { + switch (m_units) { + case Unit::Microseconds: + return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond); + case Unit::Milliseconds: + return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond); + case Unit::Seconds: + return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond); + case Unit::Minutes: + return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute); + default: + return m_inNanoseconds; + } + } + auto unitsAsString() const -> std::string { + switch (m_units) { + case Unit::Nanoseconds: + return "ns"; + case Unit::Microseconds: + return "us"; + case Unit::Milliseconds: + return "ms"; + case Unit::Seconds: + return "s"; + case Unit::Minutes: + return "m"; + default: + return "** internal error **"; + } + + } + friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& { + return os << std::fixed << duration.value() << ' ' << duration.unitsAsString(); + } +}; +} // end anon namespace + +class TablePrinter { + std::ostream& m_os; + std::vector<ColumnInfo> m_columnInfos; + std::ostringstream m_oss; + int m_currentColumn = -1; + bool m_isOpen = false; + +public: + TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos ) + : m_os( os ), + m_columnInfos( std::move( columnInfos ) ) {} + + auto columnInfos() const -> std::vector<ColumnInfo> const& { + return m_columnInfos; + } + + void open() { + if (!m_isOpen) { + m_isOpen = true; + *this << RowBreak(); + + Columns headerCols; + Spacer spacer(2); + for (auto const& info : m_columnInfos) { + headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2)); + headerCols += spacer; + } + m_os << headerCols << '\n'; + + m_os << Catch::getLineOfChars<'-'>() << '\n'; + } + } + void close() { + if (m_isOpen) { + *this << RowBreak(); + m_os << std::endl; + m_isOpen = false; + } + } + + template<typename T> + friend TablePrinter& operator << (TablePrinter& tp, T const& value) { + tp.m_oss << value; + return tp; + } + + friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) { + auto colStr = tp.m_oss.str(); + const auto strSize = colStr.size(); + tp.m_oss.str(""); + tp.open(); + if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) { + tp.m_currentColumn = -1; + tp.m_os << '\n'; + } + tp.m_currentColumn++; + + auto colInfo = tp.m_columnInfos[tp.m_currentColumn]; + auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width)) + ? std::string(colInfo.width - (strSize + 1), ' ') + : std::string(); + if (colInfo.justification == ColumnInfo::Left) + tp.m_os << colStr << padding << ' '; + else + tp.m_os << padding << colStr << ' '; + return tp; + } + + friend TablePrinter& operator << (TablePrinter& tp, RowBreak) { + if (tp.m_currentColumn > 0) { + tp.m_os << '\n'; + tp.m_currentColumn = -1; + } + return tp; + } +}; + +ConsoleReporter::ConsoleReporter(ReporterConfig const& config) + : StreamingReporterBase(config), + m_tablePrinter(new TablePrinter(config.stream(), + [&config]() -> std::vector<ColumnInfo> { + if (config.fullConfig()->benchmarkNoAnalysis()) + { + return{ + { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left }, + { " samples", 14, ColumnInfo::Right }, + { " iterations", 14, ColumnInfo::Right }, + { " mean", 14, ColumnInfo::Right } + }; + } + else + { + return{ + { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left }, + { "samples mean std dev", 14, ColumnInfo::Right }, + { "iterations low mean low std dev", 14, ColumnInfo::Right }, + { "estimated high mean high std dev", 14, ColumnInfo::Right } + }; + } + }())) {} +ConsoleReporter::~ConsoleReporter() = default; + +std::string ConsoleReporter::getDescription() { + return "Reports test results as plain lines of text"; +} + +void ConsoleReporter::noMatchingTestCases(std::string const& spec) { + stream << "No test cases matched '" << spec << '\'' << std::endl; +} + +void ConsoleReporter::reportInvalidArguments(std::string const&arg){ + stream << "Invalid Filter: " << arg << std::endl; +} + +void ConsoleReporter::assertionStarting(AssertionInfo const&) {} + +bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) { + AssertionResult const& result = _assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + // Drop out if result was successful but we're not printing them. + if (!includeResults && result.getResultType() != ResultWas::Warning) + return false; + + lazyPrint(); + + ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults); + printer.print(); + stream << std::endl; + return true; +} + +void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) { + m_tablePrinter->close(); + m_headerPrinted = false; + StreamingReporterBase::sectionStarting(_sectionInfo); +} +void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) { + m_tablePrinter->close(); + if (_sectionStats.missingAssertions) { + lazyPrint(); + Colour colour(Colour::ResultError); + if (m_sectionStack.size() > 1) + stream << "\nNo assertions in section"; + else + stream << "\nNo assertions in test case"; + stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; + } + double dur = _sectionStats.durationInSeconds; + if (shouldShowDuration(*m_config, dur)) { + stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl; + } + if (m_headerPrinted) { + m_headerPrinted = false; + } + StreamingReporterBase::sectionEnded(_sectionStats); +} + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) +void ConsoleReporter::benchmarkPreparing(std::string const& name) { + lazyPrintWithoutClosingBenchmarkTable(); + + auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2)); + + bool firstLine = true; + for (auto line : nameCol) { + if (!firstLine) + (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak(); + else + firstLine = false; + + (*m_tablePrinter) << line << ColumnBreak(); + } +} + +void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) { + (*m_tablePrinter) << info.samples << ColumnBreak() + << info.iterations << ColumnBreak(); + if (!m_config->benchmarkNoAnalysis()) + (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak(); +} +void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) { + if (m_config->benchmarkNoAnalysis()) + { + (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak(); + } + else + { + (*m_tablePrinter) << ColumnBreak() + << Duration(stats.mean.point.count()) << ColumnBreak() + << Duration(stats.mean.lower_bound.count()) << ColumnBreak() + << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak() + << Duration(stats.standardDeviation.point.count()) << ColumnBreak() + << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak() + << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak(); + } +} + +void ConsoleReporter::benchmarkFailed(std::string const& error) { + Colour colour(Colour::Red); + (*m_tablePrinter) + << "Benchmark failed (" << error << ')' + << ColumnBreak() << RowBreak(); +} +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + +void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) { + m_tablePrinter->close(); + StreamingReporterBase::testCaseEnded(_testCaseStats); + m_headerPrinted = false; +} +void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) { + if (currentGroupInfo.used) { + printSummaryDivider(); + stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; + printTotals(_testGroupStats.totals); + stream << '\n' << std::endl; + } + StreamingReporterBase::testGroupEnded(_testGroupStats); +} +void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) { + printTotalsDivider(_testRunStats.totals); + printTotals(_testRunStats.totals); + stream << std::endl; + StreamingReporterBase::testRunEnded(_testRunStats); +} +void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) { + StreamingReporterBase::testRunStarting(_testInfo); + printTestFilters(); +} + +void ConsoleReporter::lazyPrint() { + + m_tablePrinter->close(); + lazyPrintWithoutClosingBenchmarkTable(); +} + +void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() { + + if (!currentTestRunInfo.used) + lazyPrintRunInfo(); + if (!currentGroupInfo.used) + lazyPrintGroupInfo(); + + if (!m_headerPrinted) { + printTestCaseAndSectionHeader(); + m_headerPrinted = true; + } +} +void ConsoleReporter::lazyPrintRunInfo() { + stream << '\n' << getLineOfChars<'~'>() << '\n'; + Colour colour(Colour::SecondaryText); + stream << currentTestRunInfo->name + << " is a Catch v" << libraryVersion() << " host application.\n" + << "Run with -? for options\n\n"; + + if (m_config->rngSeed() != 0) + stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; + + currentTestRunInfo.used = true; +} +void ConsoleReporter::lazyPrintGroupInfo() { + if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) { + printClosedHeader("Group: " + currentGroupInfo->name); + currentGroupInfo.used = true; + } +} +void ConsoleReporter::printTestCaseAndSectionHeader() { + assert(!m_sectionStack.empty()); + printOpenHeader(currentTestCaseInfo->name); + + if (m_sectionStack.size() > 1) { + Colour colourGuard(Colour::Headers); + + auto + it = m_sectionStack.begin() + 1, // Skip first section (test case) + itEnd = m_sectionStack.end(); + for (; it != itEnd; ++it) + printHeaderString(it->name, 2); + } + + SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; + + stream << getLineOfChars<'-'>() << '\n'; + Colour colourGuard(Colour::FileName); + stream << lineInfo << '\n'; + stream << getLineOfChars<'.'>() << '\n' << std::endl; +} + +void ConsoleReporter::printClosedHeader(std::string const& _name) { + printOpenHeader(_name); + stream << getLineOfChars<'.'>() << '\n'; +} +void ConsoleReporter::printOpenHeader(std::string const& _name) { + stream << getLineOfChars<'-'>() << '\n'; + { + Colour colourGuard(Colour::Headers); + printHeaderString(_name); + } +} + +// if string has a : in first line will set indent to follow it on +// subsequent lines +void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) { + std::size_t i = _string.find(": "); + if (i != std::string::npos) + i += 2; + else + i = 0; + stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n'; +} + +struct SummaryColumn { + + SummaryColumn( std::string _label, Colour::Code _colour ) + : label( std::move( _label ) ), + colour( _colour ) {} + SummaryColumn addRow( std::size_t count ) { + ReusableStringStream rss; + rss << count; + std::string row = rss.str(); + for (auto& oldRow : rows) { + while (oldRow.size() < row.size()) + oldRow = ' ' + oldRow; + while (oldRow.size() > row.size()) + row = ' ' + row; + } + rows.push_back(row); + return *this; + } + + std::string label; + Colour::Code colour; + std::vector<std::string> rows; + +}; + +void ConsoleReporter::printTotals( Totals const& totals ) { + if (totals.testCases.total() == 0) { + stream << Colour(Colour::Warning) << "No tests ran\n"; + } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) { + stream << Colour(Colour::ResultSuccess) << "All tests passed"; + stream << " (" + << pluralise(totals.assertions.passed, "assertion") << " in " + << pluralise(totals.testCases.passed, "test case") << ')' + << '\n'; + } else { + + std::vector<SummaryColumn> columns; + columns.push_back(SummaryColumn("", Colour::None) + .addRow(totals.testCases.total()) + .addRow(totals.assertions.total())); + columns.push_back(SummaryColumn("passed", Colour::Success) + .addRow(totals.testCases.passed) + .addRow(totals.assertions.passed)); + columns.push_back(SummaryColumn("failed", Colour::ResultError) + .addRow(totals.testCases.failed) + .addRow(totals.assertions.failed)); + columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure) + .addRow(totals.testCases.failedButOk) + .addRow(totals.assertions.failedButOk)); + + printSummaryRow("test cases", columns, 0); + printSummaryRow("assertions", columns, 1); + } +} +void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) { + for (auto col : cols) { + std::string value = col.rows[row]; + if (col.label.empty()) { + stream << label << ": "; + if (value != "0") + stream << value; + else + stream << Colour(Colour::Warning) << "- none -"; + } else if (value != "0") { + stream << Colour(Colour::LightGrey) << " | "; + stream << Colour(col.colour) + << value << ' ' << col.label; + } + } + stream << '\n'; +} + +void ConsoleReporter::printTotalsDivider(Totals const& totals) { + if (totals.testCases.total() > 0) { + std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total()); + std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total()); + std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total()); + while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1) + findMax(failedRatio, failedButOkRatio, passedRatio)++; + while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1) + findMax(failedRatio, failedButOkRatio, passedRatio)--; + + stream << Colour(Colour::Error) << std::string(failedRatio, '='); + stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '='); + if (totals.testCases.allPassed()) + stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '='); + else + stream << Colour(Colour::Success) << std::string(passedRatio, '='); + } else { + stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '='); + } + stream << '\n'; +} +void ConsoleReporter::printSummaryDivider() { + stream << getLineOfChars<'-'>() << '\n'; +} + +void ConsoleReporter::printTestFilters() { + if (m_config->testSpec().hasFilters()) { + Colour guard(Colour::BrightYellow); + stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n'; + } +} + +CATCH_REGISTER_REPORTER("console", ConsoleReporter) + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +// end catch_reporter_console.cpp +// start catch_reporter_junit.cpp + +#include <cassert> +#include <sstream> +#include <ctime> +#include <algorithm> +#include <iomanip> + +namespace Catch { + + namespace { + std::string getCurrentTimestamp() { + // Beware, this is not reentrant because of backward compatibility issues + // Also, UTC only, again because of backward compatibility (%z is C++11) + time_t rawtime; + std::time(&rawtime); + auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); + +#ifdef _MSC_VER + std::tm timeInfo = {}; + gmtime_s(&timeInfo, &rawtime); +#else + std::tm* timeInfo; + timeInfo = std::gmtime(&rawtime); +#endif + + char timeStamp[timeStampSize]; + const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; + +#ifdef _MSC_VER + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); +#else + std::strftime(timeStamp, timeStampSize, fmt, timeInfo); +#endif + return std::string(timeStamp, timeStampSize-1); + } + + std::string fileNameTag(const std::vector<std::string> &tags) { + auto it = std::find_if(begin(tags), + end(tags), + [] (std::string const& tag) {return tag.front() == '#'; }); + if (it != tags.end()) + return it->substr(1); + return std::string(); + } + + // Formats the duration in seconds to 3 decimal places. + // This is done because some genius defined Maven Surefire schema + // in a way that only accepts 3 decimal places, and tools like + // Jenkins use that schema for validation JUnit reporter output. + std::string formatDuration( double seconds ) { + ReusableStringStream rss; + rss << std::fixed << std::setprecision( 3 ) << seconds; + return rss.str(); + } + + } // anonymous namespace + + JunitReporter::JunitReporter( ReporterConfig const& _config ) + : CumulativeReporterBase( _config ), + xml( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + m_reporterPrefs.shouldReportAllAssertions = true; + } + + JunitReporter::~JunitReporter() {} + + std::string JunitReporter::getDescription() { + return "Reports test results in an XML format that looks like Ant's junitreport target"; + } + + void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {} + + void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) { + CumulativeReporterBase::testRunStarting( runInfo ); + xml.startElement( "testsuites" ); + } + + void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) { + suiteTimer.start(); + stdOutForSuite.clear(); + stdErrForSuite.clear(); + unexpectedExceptions = 0; + CumulativeReporterBase::testGroupStarting( groupInfo ); + } + + void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) { + m_okToFail = testCaseInfo.okToFail(); + } + + bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) { + if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail ) + unexpectedExceptions++; + return CumulativeReporterBase::assertionEnded( assertionStats ); + } + + void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { + stdOutForSuite += testCaseStats.stdOut; + stdErrForSuite += testCaseStats.stdErr; + CumulativeReporterBase::testCaseEnded( testCaseStats ); + } + + void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { + double suiteTime = suiteTimer.getElapsedSeconds(); + CumulativeReporterBase::testGroupEnded( testGroupStats ); + writeGroup( *m_testGroups.back(), suiteTime ); + } + + void JunitReporter::testRunEndedCumulative() { + xml.endElement(); + } + + void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); + + TestGroupStats const& stats = groupNode.value; + xml.writeAttribute( "name", stats.groupInfo.name ); + xml.writeAttribute( "errors", unexpectedExceptions ); + xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); + xml.writeAttribute( "tests", stats.totals.assertions.total() ); + xml.writeAttribute( "hostname", "tbd" ); // !TBD + if( m_config->showDurations() == ShowDurations::Never ) + xml.writeAttribute( "time", "" ); + else + xml.writeAttribute( "time", formatDuration( suiteTime ) ); + xml.writeAttribute( "timestamp", getCurrentTimestamp() ); + + // Write properties if there are any + if (m_config->hasTestFilters() || m_config->rngSeed() != 0) { + auto properties = xml.scopedElement("properties"); + if (m_config->hasTestFilters()) { + xml.scopedElement("property") + .writeAttribute("name", "filters") + .writeAttribute("value", serializeFilters(m_config->getTestsOrTags())); + } + if (m_config->rngSeed() != 0) { + xml.scopedElement("property") + .writeAttribute("name", "random-seed") + .writeAttribute("value", m_config->rngSeed()); + } + } + + // Write test cases + for( auto const& child : groupNode.children ) + writeTestCase( *child ); + + xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline ); + xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline ); + } + + void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) { + TestCaseStats const& stats = testCaseNode.value; + + // All test cases have exactly one section - which represents the + // test case itself. That section may have 0-n nested sections + assert( testCaseNode.children.size() == 1 ); + SectionNode const& rootSection = *testCaseNode.children.front(); + + std::string className = stats.testInfo.className; + + if( className.empty() ) { + className = fileNameTag(stats.testInfo.tags); + if ( className.empty() ) + className = "global"; + } + + if ( !m_config->name().empty() ) + className = m_config->name() + "." + className; + + writeSection( className, "", rootSection, stats.testInfo.okToFail() ); + } + + void JunitReporter::writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode, + bool testOkToFail) { + std::string name = trim( sectionNode.stats.sectionInfo.name ); + if( !rootName.empty() ) + name = rootName + '/' + name; + + if( !sectionNode.assertions.empty() || + !sectionNode.stdOut.empty() || + !sectionNode.stdErr.empty() ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); + if( className.empty() ) { + xml.writeAttribute( "classname", name ); + xml.writeAttribute( "name", "root" ); + } + else { + xml.writeAttribute( "classname", className ); + xml.writeAttribute( "name", name ); + } + xml.writeAttribute( "time", formatDuration( sectionNode.stats.durationInSeconds ) ); + // This is not ideal, but it should be enough to mimic gtest's + // junit output. + // Ideally the JUnit reporter would also handle `skipTest` + // events and write those out appropriately. + xml.writeAttribute( "status", "run" ); + + if (sectionNode.stats.assertions.failedButOk) { + xml.scopedElement("skipped") + .writeAttribute("message", "TEST_CASE tagged with !mayfail"); + } + + writeAssertions( sectionNode ); + + if( !sectionNode.stdOut.empty() ) + xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline ); + if( !sectionNode.stdErr.empty() ) + xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline ); + } + for( auto const& childNode : sectionNode.childSections ) + if( className.empty() ) + writeSection( name, "", *childNode, testOkToFail ); + else + writeSection( className, name, *childNode, testOkToFail ); + } + + void JunitReporter::writeAssertions( SectionNode const& sectionNode ) { + for( auto const& assertion : sectionNode.assertions ) + writeAssertion( assertion ); + } + + void JunitReporter::writeAssertion( AssertionStats const& stats ) { + AssertionResult const& result = stats.assertionResult; + if( !result.isOk() ) { + std::string elementName; + switch( result.getResultType() ) { + case ResultWas::ThrewException: + case ResultWas::FatalErrorCondition: + elementName = "error"; + break; + case ResultWas::ExplicitFailure: + case ResultWas::ExpressionFailed: + case ResultWas::DidntThrowException: + elementName = "failure"; + break; + + // We should never see these here: + case ResultWas::Info: + case ResultWas::Warning: + case ResultWas::Ok: + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + elementName = "internalError"; + break; + } + + XmlWriter::ScopedElement e = xml.scopedElement( elementName ); + + xml.writeAttribute( "message", result.getExpression() ); + xml.writeAttribute( "type", result.getTestMacroName() ); + + ReusableStringStream rss; + if (stats.totals.assertions.total() > 0) { + rss << "FAILED" << ":\n"; + if (result.hasExpression()) { + rss << " "; + rss << result.getExpressionInMacro(); + rss << '\n'; + } + if (result.hasExpandedExpression()) { + rss << "with expansion:\n"; + rss << Column(result.getExpandedExpression()).indent(2) << '\n'; + } + } else { + rss << '\n'; + } + + if( !result.getMessage().empty() ) + rss << result.getMessage() << '\n'; + for( auto const& msg : stats.infoMessages ) + if( msg.type == ResultWas::Info ) + rss << msg.message << '\n'; + + rss << "at " << result.getSourceInfo(); + xml.writeText( rss.str(), XmlFormatting::Newline ); + } + } + + CATCH_REGISTER_REPORTER( "junit", JunitReporter ) + +} // end namespace Catch +// end catch_reporter_junit.cpp +// start catch_reporter_listening.cpp + +#include <cassert> + +namespace Catch { + + ListeningReporter::ListeningReporter() { + // We will assume that listeners will always want all assertions + m_preferences.shouldReportAllAssertions = true; + } + + void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) { + m_listeners.push_back( std::move( listener ) ); + } + + void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) { + assert(!m_reporter && "Listening reporter can wrap only 1 real reporter"); + m_reporter = std::move( reporter ); + m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut; + } + + ReporterPreferences ListeningReporter::getPreferences() const { + return m_preferences; + } + + std::set<Verbosity> ListeningReporter::getSupportedVerbosities() { + return std::set<Verbosity>{ }; + } + + void ListeningReporter::noMatchingTestCases( std::string const& spec ) { + for ( auto const& listener : m_listeners ) { + listener->noMatchingTestCases( spec ); + } + m_reporter->noMatchingTestCases( spec ); + } + + void ListeningReporter::reportInvalidArguments(std::string const&arg){ + for ( auto const& listener : m_listeners ) { + listener->reportInvalidArguments( arg ); + } + m_reporter->reportInvalidArguments( arg ); + } + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + void ListeningReporter::benchmarkPreparing( std::string const& name ) { + for (auto const& listener : m_listeners) { + listener->benchmarkPreparing(name); + } + m_reporter->benchmarkPreparing(name); + } + void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) { + for ( auto const& listener : m_listeners ) { + listener->benchmarkStarting( benchmarkInfo ); + } + m_reporter->benchmarkStarting( benchmarkInfo ); + } + void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) { + for ( auto const& listener : m_listeners ) { + listener->benchmarkEnded( benchmarkStats ); + } + m_reporter->benchmarkEnded( benchmarkStats ); + } + + void ListeningReporter::benchmarkFailed( std::string const& error ) { + for (auto const& listener : m_listeners) { + listener->benchmarkFailed(error); + } + m_reporter->benchmarkFailed(error); + } +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + + void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) { + for ( auto const& listener : m_listeners ) { + listener->testRunStarting( testRunInfo ); + } + m_reporter->testRunStarting( testRunInfo ); + } + + void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) { + for ( auto const& listener : m_listeners ) { + listener->testGroupStarting( groupInfo ); + } + m_reporter->testGroupStarting( groupInfo ); + } + + void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) { + for ( auto const& listener : m_listeners ) { + listener->testCaseStarting( testInfo ); + } + m_reporter->testCaseStarting( testInfo ); + } + + void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) { + for ( auto const& listener : m_listeners ) { + listener->sectionStarting( sectionInfo ); + } + m_reporter->sectionStarting( sectionInfo ); + } + + void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) { + for ( auto const& listener : m_listeners ) { + listener->assertionStarting( assertionInfo ); + } + m_reporter->assertionStarting( assertionInfo ); + } + + // The return value indicates if the messages buffer should be cleared: + bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) { + for( auto const& listener : m_listeners ) { + static_cast<void>( listener->assertionEnded( assertionStats ) ); + } + return m_reporter->assertionEnded( assertionStats ); + } + + void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) { + for ( auto const& listener : m_listeners ) { + listener->sectionEnded( sectionStats ); + } + m_reporter->sectionEnded( sectionStats ); + } + + void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { + for ( auto const& listener : m_listeners ) { + listener->testCaseEnded( testCaseStats ); + } + m_reporter->testCaseEnded( testCaseStats ); + } + + void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { + for ( auto const& listener : m_listeners ) { + listener->testGroupEnded( testGroupStats ); + } + m_reporter->testGroupEnded( testGroupStats ); + } + + void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) { + for ( auto const& listener : m_listeners ) { + listener->testRunEnded( testRunStats ); + } + m_reporter->testRunEnded( testRunStats ); + } + + void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) { + for ( auto const& listener : m_listeners ) { + listener->skipTest( testInfo ); + } + m_reporter->skipTest( testInfo ); + } + + bool ListeningReporter::isMulti() const { + return true; + } + +} // end namespace Catch +// end catch_reporter_listening.cpp +// start catch_reporter_xml.cpp + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch + // Note that 4062 (not all labels are handled + // and default is missing) is enabled +#endif + +namespace Catch { + XmlReporter::XmlReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_xml(_config.stream()) + { + m_reporterPrefs.shouldRedirectStdOut = true; + m_reporterPrefs.shouldReportAllAssertions = true; + } + + XmlReporter::~XmlReporter() = default; + + std::string XmlReporter::getDescription() { + return "Reports test results as an XML document"; + } + + std::string XmlReporter::getStylesheetRef() const { + return std::string(); + } + + void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) { + m_xml + .writeAttribute( "filename", sourceInfo.file ) + .writeAttribute( "line", sourceInfo.line ); + } + + void XmlReporter::noMatchingTestCases( std::string const& s ) { + StreamingReporterBase::noMatchingTestCases( s ); + } + + void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) { + StreamingReporterBase::testRunStarting( testInfo ); + std::string stylesheetRef = getStylesheetRef(); + if( !stylesheetRef.empty() ) + m_xml.writeStylesheetRef( stylesheetRef ); + m_xml.startElement( "Catch" ); + if( !m_config->name().empty() ) + m_xml.writeAttribute( "name", m_config->name() ); + if (m_config->testSpec().hasFilters()) + m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) ); + if( m_config->rngSeed() != 0 ) + m_xml.scopedElement( "Randomness" ) + .writeAttribute( "seed", m_config->rngSeed() ); + } + + void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) { + StreamingReporterBase::testGroupStarting( groupInfo ); + m_xml.startElement( "Group" ) + .writeAttribute( "name", groupInfo.name ); + } + + void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) { + StreamingReporterBase::testCaseStarting(testInfo); + m_xml.startElement( "TestCase" ) + .writeAttribute( "name", trim( testInfo.name ) ) + .writeAttribute( "description", testInfo.description ) + .writeAttribute( "tags", testInfo.tagsAsString() ); + + writeSourceInfo( testInfo.lineInfo ); + + if ( m_config->showDurations() == ShowDurations::Always ) + m_testCaseTimer.start(); + m_xml.ensureTagClosed(); + } + + void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) { + StreamingReporterBase::sectionStarting( sectionInfo ); + if( m_sectionDepth++ > 0 ) { + m_xml.startElement( "Section" ) + .writeAttribute( "name", trim( sectionInfo.name ) ); + writeSourceInfo( sectionInfo.lineInfo ); + m_xml.ensureTagClosed(); + } + } + + void XmlReporter::assertionStarting( AssertionInfo const& ) { } + + bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) { + + AssertionResult const& result = assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + if( includeResults || result.getResultType() == ResultWas::Warning ) { + // Print any info messages in <Info> tags. + for( auto const& msg : assertionStats.infoMessages ) { + if( msg.type == ResultWas::Info && includeResults ) { + m_xml.scopedElement( "Info" ) + .writeText( msg.message ); + } else if ( msg.type == ResultWas::Warning ) { + m_xml.scopedElement( "Warning" ) + .writeText( msg.message ); + } + } + } + + // Drop out if result was successful but we're not printing them. + if( !includeResults && result.getResultType() != ResultWas::Warning ) + return true; + + // Print the expression if there is one. + if( result.hasExpression() ) { + m_xml.startElement( "Expression" ) + .writeAttribute( "success", result.succeeded() ) + .writeAttribute( "type", result.getTestMacroName() ); + + writeSourceInfo( result.getSourceInfo() ); + + m_xml.scopedElement( "Original" ) + .writeText( result.getExpression() ); + m_xml.scopedElement( "Expanded" ) + .writeText( result.getExpandedExpression() ); + } + + // And... Print a result applicable to each result type. + switch( result.getResultType() ) { + case ResultWas::ThrewException: + m_xml.startElement( "Exception" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::FatalErrorCondition: + m_xml.startElement( "FatalErrorCondition" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::Info: + m_xml.scopedElement( "Info" ) + .writeText( result.getMessage() ); + break; + case ResultWas::Warning: + // Warning will already have been written + break; + case ResultWas::ExplicitFailure: + m_xml.startElement( "Failure" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + default: + break; + } + + if( result.hasExpression() ) + m_xml.endElement(); + + return true; + } + + void XmlReporter::sectionEnded( SectionStats const& sectionStats ) { + StreamingReporterBase::sectionEnded( sectionStats ); + if( --m_sectionDepth > 0 ) { + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); + e.writeAttribute( "successes", sectionStats.assertions.passed ); + e.writeAttribute( "failures", sectionStats.assertions.failed ); + e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); + + m_xml.endElement(); + } + } + + void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { + StreamingReporterBase::testCaseEnded( testCaseStats ); + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); + e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); + + if( !testCaseStats.stdOut.empty() ) + m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline ); + if( !testCaseStats.stdErr.empty() ) + m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline ); + + m_xml.endElement(); + } + + void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { + StreamingReporterBase::testGroupEnded( testGroupStats ); + // TODO: Check testGroupStats.aborting and act accordingly. + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) + .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); + m_xml.scopedElement( "OverallResultsCases") + .writeAttribute( "successes", testGroupStats.totals.testCases.passed ) + .writeAttribute( "failures", testGroupStats.totals.testCases.failed ) + .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk ); + m_xml.endElement(); + } + + void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) { + StreamingReporterBase::testRunEnded( testRunStats ); + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testRunStats.totals.assertions.passed ) + .writeAttribute( "failures", testRunStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); + m_xml.scopedElement( "OverallResultsCases") + .writeAttribute( "successes", testRunStats.totals.testCases.passed ) + .writeAttribute( "failures", testRunStats.totals.testCases.failed ) + .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk ); + m_xml.endElement(); + } + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) + void XmlReporter::benchmarkPreparing(std::string const& name) { + m_xml.startElement("BenchmarkResults") + .writeAttribute("name", name); + } + + void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) { + m_xml.writeAttribute("samples", info.samples) + .writeAttribute("resamples", info.resamples) + .writeAttribute("iterations", info.iterations) + .writeAttribute("clockResolution", info.clockResolution) + .writeAttribute("estimatedDuration", info.estimatedDuration) + .writeComment("All values in nano seconds"); + } + + void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) { + m_xml.startElement("mean") + .writeAttribute("value", benchmarkStats.mean.point.count()) + .writeAttribute("lowerBound", benchmarkStats.mean.lower_bound.count()) + .writeAttribute("upperBound", benchmarkStats.mean.upper_bound.count()) + .writeAttribute("ci", benchmarkStats.mean.confidence_interval); + m_xml.endElement(); + m_xml.startElement("standardDeviation") + .writeAttribute("value", benchmarkStats.standardDeviation.point.count()) + .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count()) + .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count()) + .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval); + m_xml.endElement(); + m_xml.startElement("outliers") + .writeAttribute("variance", benchmarkStats.outlierVariance) + .writeAttribute("lowMild", benchmarkStats.outliers.low_mild) + .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe) + .writeAttribute("highMild", benchmarkStats.outliers.high_mild) + .writeAttribute("highSevere", benchmarkStats.outliers.high_severe); + m_xml.endElement(); + m_xml.endElement(); + } + + void XmlReporter::benchmarkFailed(std::string const &error) { + m_xml.scopedElement("failed"). + writeAttribute("message", error); + m_xml.endElement(); + } +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + + CATCH_REGISTER_REPORTER( "xml", XmlReporter ) + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +// end catch_reporter_xml.cpp + +namespace Catch { + LeakDetector leakDetector; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_impl.hpp +#endif + +#ifdef CATCH_CONFIG_MAIN +// start catch_default_main.hpp + +#ifndef __OBJC__ + +#if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) +// Standard C/C++ Win32 Unicode wmain entry point +extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { +#else +// Standard C/C++ main entry point +int main (int argc, char * argv[]) { +#endif + + return Catch::Session().run( argc, argv ); +} + +#else // __OBJC__ + +// Objective-C entry point +int main (int argc, char * const argv[]) { +#if !CATCH_ARC_ENABLED + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; +#endif + + Catch::registerTestMethods(); + int result = Catch::Session().run( argc, (char**)argv ); + +#if !CATCH_ARC_ENABLED + [pool drain]; +#endif + + return result; +} + +#endif // __OBJC__ + +// end catch_default_main.hpp +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) + +#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED +# undef CLARA_CONFIG_MAIN +#endif + +#if !defined(CATCH_CONFIG_DISABLE) +////// +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) + +#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) +#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) +#endif// CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) + +#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) +#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) + +#define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) + +#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) +#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg ) +#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) +#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ ) + +#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) +#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) +#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) +#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) +#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ ) +#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) + +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) +#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) +#else +#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) ) +#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) ) +#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) +#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) +#endif + +#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) +#define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ ) +#define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ ) +#else +#define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ ) +#define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ ) +#endif + +// "BDD-style" convenience wrappers +#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) +#define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc ) +#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc ) +#define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc ) +#define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc ) +#define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc ) +#define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc ) + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) +#define CATCH_BENCHMARK(...) \ + INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) +#define CATCH_BENCHMARK_ADVANCED(name) \ + INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name) +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) + +#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) +#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) + +#define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) +#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) + +#define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) + +#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) +#define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg ) +#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) +#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ ) + +#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) +#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) +#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) +#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) +#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ ) +#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) +#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) +#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) +#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) +#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) +#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__) +#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#else +#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) ) +#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) ) +#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) +#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) +#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) ) +#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) ) +#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) +#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) +#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) ) +#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) +#endif + +#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) +#define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ ) +#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" ) +#else +#define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ ) +#define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ ) +#endif + +#endif + +#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) + +// "BDD-style" convenience wrappers +#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) + +#define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc ) +#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc ) +#define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc ) +#define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc ) +#define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc ) +#define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc ) + +#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) +#define BENCHMARK(...) \ + INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) +#define BENCHMARK_ADVANCED(name) \ + INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name) +#endif // CATCH_CONFIG_ENABLE_BENCHMARKING + +using Catch::Detail::Approx; + +#else // CATCH_CONFIG_DISABLE + +////// +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#define CATCH_REQUIRE( ... ) (void)(0) +#define CATCH_REQUIRE_FALSE( ... ) (void)(0) + +#define CATCH_REQUIRE_THROWS( ... ) (void)(0) +#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) +#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif// CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0) + +#define CATCH_CHECK( ... ) (void)(0) +#define CATCH_CHECK_FALSE( ... ) (void)(0) +#define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__) +#define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__)) +#define CATCH_CHECK_NOFAIL( ... ) (void)(0) + +#define CATCH_CHECK_THROWS( ... ) (void)(0) +#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0) +#define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_CHECK_NOTHROW( ... ) (void)(0) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THAT( arg, matcher ) (void)(0) + +#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define CATCH_INFO( msg ) (void)(0) +#define CATCH_UNSCOPED_INFO( msg ) (void)(0) +#define CATCH_WARN( msg ) (void)(0) +#define CATCH_CAPTURE( msg ) (void)(0) + +#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define CATCH_METHOD_AS_TEST_CASE( method, ... ) +#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) +#define CATCH_SECTION( ... ) +#define CATCH_DYNAMIC_SECTION( ... ) +#define CATCH_FAIL( ... ) (void)(0) +#define CATCH_FAIL_CHECK( ... ) (void)(0) +#define CATCH_SUCCEED( ... ) (void)(0) + +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) +#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) +#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__) +#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#else +#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) ) +#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) ) +#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) ) +#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#endif + +// "BDD-style" convenience wrappers +#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className ) +#define CATCH_GIVEN( desc ) +#define CATCH_AND_GIVEN( desc ) +#define CATCH_WHEN( desc ) +#define CATCH_AND_WHEN( desc ) +#define CATCH_THEN( desc ) +#define CATCH_AND_THEN( desc ) + +#define CATCH_STATIC_REQUIRE( ... ) (void)(0) +#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0) + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#define REQUIRE( ... ) (void)(0) +#define REQUIRE_FALSE( ... ) (void)(0) + +#define REQUIRE_THROWS( ... ) (void)(0) +#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) +#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define REQUIRE_NOTHROW( ... ) (void)(0) + +#define CHECK( ... ) (void)(0) +#define CHECK_FALSE( ... ) (void)(0) +#define CHECKED_IF( ... ) if (__VA_ARGS__) +#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__)) +#define CHECK_NOFAIL( ... ) (void)(0) + +#define CHECK_THROWS( ... ) (void)(0) +#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0) +#define CHECK_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CHECK_NOTHROW( ... ) (void)(0) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THAT( arg, matcher ) (void)(0) + +#define REQUIRE_THAT( arg, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define INFO( msg ) (void)(0) +#define UNSCOPED_INFO( msg ) (void)(0) +#define WARN( msg ) (void)(0) +#define CAPTURE( ... ) (void)(0) + +#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define METHOD_AS_TEST_CASE( method, ... ) +#define REGISTER_TEST_CASE( Function, ... ) (void)(0) +#define SECTION( ... ) +#define DYNAMIC_SECTION( ... ) +#define FAIL( ... ) (void)(0) +#define FAIL_CHECK( ... ) (void)(0) +#define SUCCEED( ... ) (void)(0) +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) +#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) +#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__) +#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) +#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#else +#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) ) +#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) ) +#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) ) +#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) ) +#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#endif + +#define STATIC_REQUIRE( ... ) (void)(0) +#define STATIC_REQUIRE_FALSE( ... ) (void)(0) + +#endif + +#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) + +// "BDD-style" convenience wrappers +#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className ) + +#define GIVEN( desc ) +#define AND_GIVEN( desc ) +#define WHEN( desc ) +#define AND_WHEN( desc ) +#define THEN( desc ) +#define AND_THEN( desc ) + +using Catch::Detail::Approx; + +#endif + +#endif // ! CATCH_CONFIG_IMPL_ONLY + +// start catch_reenable_warnings.h + + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(pop) +# else +# pragma clang diagnostic pop +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic pop +#endif + +// end catch_reenable_warnings.h +// end catch.hpp +#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED + diff --git a/lib/gmp/CMakeLists.txt b/lib/gmp/CMakeLists.txt new file mode 100644 index 0000000..f0604a4 --- /dev/null +++ b/lib/gmp/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(gmp STATIC mini-gmp.c) +target_link_libraries(gmp) + diff --git a/lib/gmp/mini-gmp.c b/lib/gmp/mini-gmp.c new file mode 100644 index 0000000..e2e6861 --- /dev/null +++ b/lib/gmp/mini-gmp.c @@ -0,0 +1,4560 @@ +/* mini-gmp, a minimalistic implementation of a GNU GMP subset. + + Contributed to the GNU project by Niels Möller + +Copyright 1991-1997, 1999-2019 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library 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 3 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that 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 the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ + +/* NOTE: All functions in this file which are not declared in + mini-gmp.h are internal, and are not intended to be compatible + neither with GMP nor with future versions of mini-gmp. */ + +/* Much of the material copied from GMP files, including: gmp-impl.h, + longlong.h, mpn/generic/add_n.c, mpn/generic/addmul_1.c, + mpn/generic/lshift.c, mpn/generic/mul_1.c, + mpn/generic/mul_basecase.c, mpn/generic/rshift.c, + mpn/generic/sbpi1_div_qr.c, mpn/generic/sub_n.c, + mpn/generic/submul_1.c. */ + +#include <assert.h> +#include <ctype.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mini-gmp.h" + +#if !defined(MINI_GMP_DONT_USE_FLOAT_H) +#include <float.h> +#endif + + +/* Macros */ +#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT) + +#define GMP_LIMB_MAX ((mp_limb_t) ~ (mp_limb_t) 0) +#define GMP_LIMB_HIGHBIT ((mp_limb_t) 1 << (GMP_LIMB_BITS - 1)) + +#define GMP_HLIMB_BIT ((mp_limb_t) 1 << (GMP_LIMB_BITS / 2)) +#define GMP_LLIMB_MASK (GMP_HLIMB_BIT - 1) + +#define GMP_ULONG_BITS (sizeof(unsigned long) * CHAR_BIT) +#define GMP_ULONG_HIGHBIT ((unsigned long) 1 << (GMP_ULONG_BITS - 1)) + +#define GMP_ABS(x) ((x) >= 0 ? (x) : -(x)) +#define GMP_NEG_CAST(T,x) (-((T)((x) + 1) - 1)) + +#define GMP_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define GMP_MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define GMP_CMP(a,b) (((a) > (b)) - ((a) < (b))) + +#if defined(DBL_MANT_DIG) && FLT_RADIX == 2 +#define GMP_DBL_MANT_BITS DBL_MANT_DIG +#else +#define GMP_DBL_MANT_BITS (53) +#endif + +/* Return non-zero if xp,xsize and yp,ysize overlap. + If xp+xsize<=yp there's no overlap, or if yp+ysize<=xp there's no + overlap. If both these are false, there's an overlap. */ +#define GMP_MPN_OVERLAP_P(xp, xsize, yp, ysize) \ + ((xp) + (xsize) > (yp) && (yp) + (ysize) > (xp)) + +#define gmp_assert_nocarry(x) do { \ + mp_limb_t __cy = (x); \ + assert (__cy == 0); \ + } while (0) + +#define gmp_clz(count, x) do { \ + mp_limb_t __clz_x = (x); \ + unsigned __clz_c = 0; \ + int LOCAL_SHIFT_BITS = 8; \ + if (GMP_LIMB_BITS > LOCAL_SHIFT_BITS) \ + for (; \ + (__clz_x & ((mp_limb_t) 0xff << (GMP_LIMB_BITS - 8))) == 0; \ + __clz_c += 8) \ + { __clz_x <<= LOCAL_SHIFT_BITS; } \ + for (; (__clz_x & GMP_LIMB_HIGHBIT) == 0; __clz_c++) \ + __clz_x <<= 1; \ + (count) = __clz_c; \ + } while (0) + +#define gmp_ctz(count, x) do { \ + mp_limb_t __ctz_x = (x); \ + unsigned __ctz_c = 0; \ + gmp_clz (__ctz_c, __ctz_x & - __ctz_x); \ + (count) = GMP_LIMB_BITS - 1 - __ctz_c; \ + } while (0) + +#define gmp_add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + mp_limb_t __x; \ + __x = (al) + (bl); \ + (sh) = (ah) + (bh) + (__x < (al)); \ + (sl) = __x; \ + } while (0) + +#define gmp_sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + mp_limb_t __x; \ + __x = (al) - (bl); \ + (sh) = (ah) - (bh) - ((al) < (bl)); \ + (sl) = __x; \ + } while (0) + +#define gmp_umul_ppmm(w1, w0, u, v) \ + do { \ + int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS; \ + if (sizeof(unsigned int) * CHAR_BIT >= 2 * GMP_LIMB_BITS) \ + { \ + unsigned int __ww = (unsigned int) (u) * (v); \ + w0 = (mp_limb_t) __ww; \ + w1 = (mp_limb_t) (__ww >> LOCAL_GMP_LIMB_BITS); \ + } \ + else if (GMP_ULONG_BITS >= 2 * GMP_LIMB_BITS) \ + { \ + unsigned long int __ww = (unsigned long int) (u) * (v); \ + w0 = (mp_limb_t) __ww; \ + w1 = (mp_limb_t) (__ww >> LOCAL_GMP_LIMB_BITS); \ + } \ + else { \ + mp_limb_t __x0, __x1, __x2, __x3; \ + unsigned __ul, __vl, __uh, __vh; \ + mp_limb_t __u = (u), __v = (v); \ + \ + __ul = __u & GMP_LLIMB_MASK; \ + __uh = __u >> (GMP_LIMB_BITS / 2); \ + __vl = __v & GMP_LLIMB_MASK; \ + __vh = __v >> (GMP_LIMB_BITS / 2); \ + \ + __x0 = (mp_limb_t) __ul * __vl; \ + __x1 = (mp_limb_t) __ul * __vh; \ + __x2 = (mp_limb_t) __uh * __vl; \ + __x3 = (mp_limb_t) __uh * __vh; \ + \ + __x1 += __x0 >> (GMP_LIMB_BITS / 2);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += GMP_HLIMB_BIT; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + (__x1 >> (GMP_LIMB_BITS / 2)); \ + (w0) = (__x1 << (GMP_LIMB_BITS / 2)) + (__x0 & GMP_LLIMB_MASK); \ + } \ + } while (0) + +#define gmp_udiv_qrnnd_preinv(q, r, nh, nl, d, di) \ + do { \ + mp_limb_t _qh, _ql, _r, _mask; \ + gmp_umul_ppmm (_qh, _ql, (nh), (di)); \ + gmp_add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \ + _r = (nl) - _qh * (d); \ + _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \ + _qh += _mask; \ + _r += _mask & (d); \ + if (_r >= (d)) \ + { \ + _r -= (d); \ + _qh++; \ + } \ + \ + (r) = _r; \ + (q) = _qh; \ + } while (0) + +#define gmp_udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv) \ + do { \ + mp_limb_t _q0, _t1, _t0, _mask; \ + gmp_umul_ppmm ((q), _q0, (n2), (dinv)); \ + gmp_add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1)); \ + \ + /* Compute the two most significant limbs of n - q'd */ \ + (r1) = (n1) - (d1) * (q); \ + gmp_sub_ddmmss ((r1), (r0), (r1), (n0), (d1), (d0)); \ + gmp_umul_ppmm (_t1, _t0, (d0), (q)); \ + gmp_sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0); \ + (q)++; \ + \ + /* Conditionally adjust q and the remainders */ \ + _mask = - (mp_limb_t) ((r1) >= _q0); \ + (q) += _mask; \ + gmp_add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0)); \ + if ((r1) >= (d1)) \ + { \ + if ((r1) > (d1) || (r0) >= (d0)) \ + { \ + (q)++; \ + gmp_sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0)); \ + } \ + } \ + } while (0) + +/* Swap macros. */ +#define MP_LIMB_T_SWAP(x, y) \ + do { \ + mp_limb_t __mp_limb_t_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mp_limb_t_swap__tmp; \ + } while (0) +#define MP_SIZE_T_SWAP(x, y) \ + do { \ + mp_size_t __mp_size_t_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mp_size_t_swap__tmp; \ + } while (0) +#define MP_BITCNT_T_SWAP(x,y) \ + do { \ + mp_bitcnt_t __mp_bitcnt_t_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mp_bitcnt_t_swap__tmp; \ + } while (0) +#define MP_PTR_SWAP(x, y) \ + do { \ + mp_ptr __mp_ptr_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mp_ptr_swap__tmp; \ + } while (0) +#define MP_SRCPTR_SWAP(x, y) \ + do { \ + mp_srcptr __mp_srcptr_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mp_srcptr_swap__tmp; \ + } while (0) + +#define MPN_PTR_SWAP(xp,xs, yp,ys) \ + do { \ + MP_PTR_SWAP (xp, yp); \ + MP_SIZE_T_SWAP (xs, ys); \ + } while(0) +#define MPN_SRCPTR_SWAP(xp,xs, yp,ys) \ + do { \ + MP_SRCPTR_SWAP (xp, yp); \ + MP_SIZE_T_SWAP (xs, ys); \ + } while(0) + +#define MPZ_PTR_SWAP(x, y) \ + do { \ + mpz_ptr __mpz_ptr_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mpz_ptr_swap__tmp; \ + } while (0) +#define MPZ_SRCPTR_SWAP(x, y) \ + do { \ + mpz_srcptr __mpz_srcptr_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mpz_srcptr_swap__tmp; \ + } while (0) + +const int mp_bits_per_limb = GMP_LIMB_BITS; + + +/* Memory allocation and other helper functions. */ +static void +gmp_die (const char *msg) +{ + fprintf (stderr, "%s\n", msg); + abort(); +} + +static void * +gmp_default_alloc (size_t size) +{ + void *p; + + assert (size > 0); + + p = malloc (size); + if (!p) + gmp_die("gmp_default_alloc: Virtual memory exhausted."); + + return p; +} + +static void * +gmp_default_realloc (void *old, size_t unused_old_size, size_t new_size) +{ + void * p; + + p = realloc (old, new_size); + + if (!p) + gmp_die("gmp_default_realloc: Virtual memory exhausted."); + + return p; +} + +static void +gmp_default_free (void *p, size_t unused_size) +{ + free (p); +} + +static void * (*gmp_allocate_func) (size_t) = gmp_default_alloc; +static void * (*gmp_reallocate_func) (void *, size_t, size_t) = gmp_default_realloc; +static void (*gmp_free_func) (void *, size_t) = gmp_default_free; + +void +mp_get_memory_functions (void *(**alloc_func) (size_t), + void *(**realloc_func) (void *, size_t, size_t), + void (**free_func) (void *, size_t)) +{ + if (alloc_func) + *alloc_func = gmp_allocate_func; + + if (realloc_func) + *realloc_func = gmp_reallocate_func; + + if (free_func) + *free_func = gmp_free_func; +} + +void +mp_set_memory_functions (void *(*alloc_func) (size_t), + void *(*realloc_func) (void *, size_t, size_t), + void (*free_func) (void *, size_t)) +{ + if (!alloc_func) + alloc_func = gmp_default_alloc; + if (!realloc_func) + realloc_func = gmp_default_realloc; + if (!free_func) + free_func = gmp_default_free; + + gmp_allocate_func = alloc_func; + gmp_reallocate_func = realloc_func; + gmp_free_func = free_func; +} + +#define gmp_xalloc(size) ((*gmp_allocate_func)((size))) +#define gmp_free(p) ((*gmp_free_func) ((p), 0)) + +static mp_ptr +gmp_xalloc_limbs (mp_size_t size) +{ + return (mp_ptr) gmp_xalloc (size * sizeof (mp_limb_t)); +} + +static mp_ptr +gmp_xrealloc_limbs (mp_ptr old, mp_size_t size) +{ + assert (size > 0); + return (mp_ptr) (*gmp_reallocate_func) (old, 0, size * sizeof (mp_limb_t)); +} + + +/* MPN interface */ + +void +mpn_copyi (mp_ptr d, mp_srcptr s, mp_size_t n) +{ + mp_size_t i; + for (i = 0; i < n; i++) + d[i] = s[i]; +} + +void +mpn_copyd (mp_ptr d, mp_srcptr s, mp_size_t n) +{ + while (--n >= 0) + d[n] = s[n]; +} + +int +mpn_cmp (mp_srcptr ap, mp_srcptr bp, mp_size_t n) +{ + while (--n >= 0) + { + if (ap[n] != bp[n]) + return ap[n] > bp[n] ? 1 : -1; + } + return 0; +} + +static int +mpn_cmp4 (mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn) +{ + if (an != bn) + return an < bn ? -1 : 1; + else + return mpn_cmp (ap, bp, an); +} + +static mp_size_t +mpn_normalized_size (mp_srcptr xp, mp_size_t n) +{ + while (n > 0 && xp[n-1] == 0) + --n; + return n; +} + +int +mpn_zero_p(mp_srcptr rp, mp_size_t n) +{ + return mpn_normalized_size (rp, n) == 0; +} + +void +mpn_zero (mp_ptr rp, mp_size_t n) +{ + while (--n >= 0) + rp[n] = 0; +} + +mp_limb_t +mpn_add_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b) +{ + mp_size_t i; + + assert (n > 0); + i = 0; + do + { + mp_limb_t r = ap[i] + b; + /* Carry out */ + b = (r < b); + rp[i] = r; + } + while (++i < n); + + return b; +} + +mp_limb_t +mpn_add_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n) +{ + mp_size_t i; + mp_limb_t cy; + + for (i = 0, cy = 0; i < n; i++) + { + mp_limb_t a, b, r; + a = ap[i]; b = bp[i]; + r = a + cy; + cy = (r < cy); + r += b; + cy += (r < b); + rp[i] = r; + } + return cy; +} + +mp_limb_t +mpn_add (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn) +{ + mp_limb_t cy; + + assert (an >= bn); + + cy = mpn_add_n (rp, ap, bp, bn); + if (an > bn) + cy = mpn_add_1 (rp + bn, ap + bn, an - bn, cy); + return cy; +} + +mp_limb_t +mpn_sub_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b) +{ + mp_size_t i; + + assert (n > 0); + + i = 0; + do + { + mp_limb_t a = ap[i]; + /* Carry out */ + mp_limb_t cy = a < b; + rp[i] = a - b; + b = cy; + } + while (++i < n); + + return b; +} + +mp_limb_t +mpn_sub_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n) +{ + mp_size_t i; + mp_limb_t cy; + + for (i = 0, cy = 0; i < n; i++) + { + mp_limb_t a, b; + a = ap[i]; b = bp[i]; + b += cy; + cy = (b < cy); + cy += (a < b); + rp[i] = a - b; + } + return cy; +} + +mp_limb_t +mpn_sub (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn) +{ + mp_limb_t cy; + + assert (an >= bn); + + cy = mpn_sub_n (rp, ap, bp, bn); + if (an > bn) + cy = mpn_sub_1 (rp + bn, ap + bn, an - bn, cy); + return cy; +} + +mp_limb_t +mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl) +{ + mp_limb_t ul, cl, hpl, lpl; + + assert (n >= 1); + + cl = 0; + do + { + ul = *up++; + gmp_umul_ppmm (hpl, lpl, ul, vl); + + lpl += cl; + cl = (lpl < cl) + hpl; + + *rp++ = lpl; + } + while (--n != 0); + + return cl; +} + +mp_limb_t +mpn_addmul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl) +{ + mp_limb_t ul, cl, hpl, lpl, rl; + + assert (n >= 1); + + cl = 0; + do + { + ul = *up++; + gmp_umul_ppmm (hpl, lpl, ul, vl); + + lpl += cl; + cl = (lpl < cl) + hpl; + + rl = *rp; + lpl = rl + lpl; + cl += lpl < rl; + *rp++ = lpl; + } + while (--n != 0); + + return cl; +} + +mp_limb_t +mpn_submul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl) +{ + mp_limb_t ul, cl, hpl, lpl, rl; + + assert (n >= 1); + + cl = 0; + do + { + ul = *up++; + gmp_umul_ppmm (hpl, lpl, ul, vl); + + lpl += cl; + cl = (lpl < cl) + hpl; + + rl = *rp; + lpl = rl - lpl; + cl += lpl > rl; + *rp++ = lpl; + } + while (--n != 0); + + return cl; +} + +mp_limb_t +mpn_mul (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn) +{ + assert (un >= vn); + assert (vn >= 1); + assert (!GMP_MPN_OVERLAP_P(rp, un + vn, up, un)); + assert (!GMP_MPN_OVERLAP_P(rp, un + vn, vp, vn)); + + /* We first multiply by the low order limb. This result can be + stored, not added, to rp. We also avoid a loop for zeroing this + way. */ + + rp[un] = mpn_mul_1 (rp, up, un, vp[0]); + + /* Now accumulate the product of up[] and the next higher limb from + vp[]. */ + + while (--vn >= 1) + { + rp += 1, vp += 1; + rp[un] = mpn_addmul_1 (rp, up, un, vp[0]); + } + return rp[un]; +} + +void +mpn_mul_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n) +{ + mpn_mul (rp, ap, n, bp, n); +} + +void +mpn_sqr (mp_ptr rp, mp_srcptr ap, mp_size_t n) +{ + mpn_mul (rp, ap, n, ap, n); +} + +mp_limb_t +mpn_lshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt) +{ + mp_limb_t high_limb, low_limb; + unsigned int tnc; + mp_limb_t retval; + + assert (n >= 1); + assert (cnt >= 1); + assert (cnt < GMP_LIMB_BITS); + + up += n; + rp += n; + + tnc = GMP_LIMB_BITS - cnt; + low_limb = *--up; + retval = low_limb >> tnc; + high_limb = (low_limb << cnt); + + while (--n != 0) + { + low_limb = *--up; + *--rp = high_limb | (low_limb >> tnc); + high_limb = (low_limb << cnt); + } + *--rp = high_limb; + + return retval; +} + +mp_limb_t +mpn_rshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt) +{ + mp_limb_t high_limb, low_limb; + unsigned int tnc; + mp_limb_t retval; + + assert (n >= 1); + assert (cnt >= 1); + assert (cnt < GMP_LIMB_BITS); + + tnc = GMP_LIMB_BITS - cnt; + high_limb = *up++; + retval = (high_limb << tnc); + low_limb = high_limb >> cnt; + + while (--n != 0) + { + high_limb = *up++; + *rp++ = low_limb | (high_limb << tnc); + low_limb = high_limb >> cnt; + } + *rp = low_limb; + + return retval; +} + +static mp_bitcnt_t +mpn_common_scan (mp_limb_t limb, mp_size_t i, mp_srcptr up, mp_size_t un, + mp_limb_t ux) +{ + unsigned cnt; + + assert (ux == 0 || ux == GMP_LIMB_MAX); + assert (0 <= i && i <= un ); + + while (limb == 0) + { + i++; + if (i == un) + return (ux == 0 ? ~(mp_bitcnt_t) 0 : un * GMP_LIMB_BITS); + limb = ux ^ up[i]; + } + gmp_ctz (cnt, limb); + return (mp_bitcnt_t) i * GMP_LIMB_BITS + cnt; +} + +mp_bitcnt_t +mpn_scan1 (mp_srcptr ptr, mp_bitcnt_t bit) +{ + mp_size_t i; + i = bit / GMP_LIMB_BITS; + + return mpn_common_scan ( ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)), + i, ptr, i, 0); +} + +mp_bitcnt_t +mpn_scan0 (mp_srcptr ptr, mp_bitcnt_t bit) +{ + mp_size_t i; + i = bit / GMP_LIMB_BITS; + + return mpn_common_scan (~ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)), + i, ptr, i, GMP_LIMB_MAX); +} + +void +mpn_com (mp_ptr rp, mp_srcptr up, mp_size_t n) +{ + while (--n >= 0) + *rp++ = ~ *up++; +} + +mp_limb_t +mpn_neg (mp_ptr rp, mp_srcptr up, mp_size_t n) +{ + while (*up == 0) + { + *rp = 0; + if (!--n) + return 0; + ++up; ++rp; + } + *rp = - *up; + mpn_com (++rp, ++up, --n); + return 1; +} + + +/* MPN division interface. */ + +/* The 3/2 inverse is defined as + + m = floor( (B^3-1) / (B u1 + u0)) - B +*/ +mp_limb_t +mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) +{ + mp_limb_t r, m; + + { + mp_limb_t p, ql; + unsigned ul, uh, qh; + + /* For notation, let b denote the half-limb base, so that B = b^2. + Split u1 = b uh + ul. */ + ul = u1 & GMP_LLIMB_MASK; + uh = u1 >> (GMP_LIMB_BITS / 2); + + /* Approximation of the high half of quotient. Differs from the 2/1 + inverse of the half limb uh, since we have already subtracted + u0. */ + qh = (u1 ^ GMP_LIMB_MAX) / uh; + + /* Adjust to get a half-limb 3/2 inverse, i.e., we want + + qh' = floor( (b^3 - 1) / u) - b = floor ((b^3 - b u - 1) / u + = floor( (b (~u) + b-1) / u), + + and the remainder + + r = b (~u) + b-1 - qh (b uh + ul) + = b (~u - qh uh) + b-1 - qh ul + + Subtraction of qh ul may underflow, which implies adjustments. + But by normalization, 2 u >= B > qh ul, so we need to adjust by + at most 2. + */ + + r = ((~u1 - (mp_limb_t) qh * uh) << (GMP_LIMB_BITS / 2)) | GMP_LLIMB_MASK; + + p = (mp_limb_t) qh * ul; + /* Adjustment steps taken from udiv_qrnnd_c */ + if (r < p) + { + qh--; + r += u1; + if (r >= u1) /* i.e. we didn't get carry when adding to r */ + if (r < p) + { + qh--; + r += u1; + } + } + r -= p; + + /* Low half of the quotient is + + ql = floor ( (b r + b-1) / u1). + + This is a 3/2 division (on half-limbs), for which qh is a + suitable inverse. */ + + p = (r >> (GMP_LIMB_BITS / 2)) * qh + r; + /* Unlike full-limb 3/2, we can add 1 without overflow. For this to + work, it is essential that ql is a full mp_limb_t. */ + ql = (p >> (GMP_LIMB_BITS / 2)) + 1; + + /* By the 3/2 trick, we don't need the high half limb. */ + r = (r << (GMP_LIMB_BITS / 2)) + GMP_LLIMB_MASK - ql * u1; + + if (r >= (GMP_LIMB_MAX & (p << (GMP_LIMB_BITS / 2)))) + { + ql--; + r += u1; + } + m = ((mp_limb_t) qh << (GMP_LIMB_BITS / 2)) + ql; + if (r >= u1) + { + m++; + r -= u1; + } + } + + /* Now m is the 2/1 inverse of u1. If u0 > 0, adjust it to become a + 3/2 inverse. */ + if (u0 > 0) + { + mp_limb_t th, tl; + r = ~r; + r += u0; + if (r < u0) + { + m--; + if (r >= u1) + { + m--; + r -= u1; + } + r -= u1; + } + gmp_umul_ppmm (th, tl, u0, m); + r += th; + if (r < th) + { + m--; + m -= ((r > u1) | ((r == u1) & (tl > u0))); + } + } + + return m; +} + +struct gmp_div_inverse +{ + /* Normalization shift count. */ + unsigned shift; + /* Normalized divisor (d0 unused for mpn_div_qr_1) */ + mp_limb_t d1, d0; + /* Inverse, for 2/1 or 3/2. */ + mp_limb_t di; +}; + +static void +mpn_div_qr_1_invert (struct gmp_div_inverse *inv, mp_limb_t d) +{ + unsigned shift; + + assert (d > 0); + gmp_clz (shift, d); + inv->shift = shift; + inv->d1 = d << shift; + inv->di = mpn_invert_limb (inv->d1); +} + +static void +mpn_div_qr_2_invert (struct gmp_div_inverse *inv, + mp_limb_t d1, mp_limb_t d0) +{ + unsigned shift; + + assert (d1 > 0); + gmp_clz (shift, d1); + inv->shift = shift; + if (shift > 0) + { + d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift)); + d0 <<= shift; + } + inv->d1 = d1; + inv->d0 = d0; + inv->di = mpn_invert_3by2 (d1, d0); +} + +static void +mpn_div_qr_invert (struct gmp_div_inverse *inv, + mp_srcptr dp, mp_size_t dn) +{ + assert (dn > 0); + + if (dn == 1) + mpn_div_qr_1_invert (inv, dp[0]); + else if (dn == 2) + mpn_div_qr_2_invert (inv, dp[1], dp[0]); + else + { + unsigned shift; + mp_limb_t d1, d0; + + d1 = dp[dn-1]; + d0 = dp[dn-2]; + assert (d1 > 0); + gmp_clz (shift, d1); + inv->shift = shift; + if (shift > 0) + { + d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift)); + d0 = (d0 << shift) | (dp[dn-3] >> (GMP_LIMB_BITS - shift)); + } + inv->d1 = d1; + inv->d0 = d0; + inv->di = mpn_invert_3by2 (d1, d0); + } +} + +/* Not matching current public gmp interface, rather corresponding to + the sbpi1_div_* functions. */ +static mp_limb_t +mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn, + const struct gmp_div_inverse *inv) +{ + mp_limb_t d, di; + mp_limb_t r; + mp_ptr tp = NULL; + + if (inv->shift > 0) + { + /* Shift, reusing qp area if possible. In-place shift if qp == np. */ + tp = qp ? qp : gmp_xalloc_limbs (nn); + r = mpn_lshift (tp, np, nn, inv->shift); + np = tp; + } + else + r = 0; + + d = inv->d1; + di = inv->di; + while (--nn >= 0) + { + mp_limb_t q; + + gmp_udiv_qrnnd_preinv (q, r, r, np[nn], d, di); + if (qp) + qp[nn] = q; + } + if ((inv->shift > 0) && (tp != qp)) + gmp_free (tp); + + return r >> inv->shift; +} + +static void +mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn, + const struct gmp_div_inverse *inv) +{ + unsigned shift; + mp_size_t i; + mp_limb_t d1, d0, di, r1, r0; + + assert (nn >= 2); + shift = inv->shift; + d1 = inv->d1; + d0 = inv->d0; + di = inv->di; + + if (shift > 0) + r1 = mpn_lshift (np, np, nn, shift); + else + r1 = 0; + + r0 = np[nn - 1]; + + i = nn - 2; + do + { + mp_limb_t n0, q; + n0 = np[i]; + gmp_udiv_qr_3by2 (q, r1, r0, r1, r0, n0, d1, d0, di); + + if (qp) + qp[i] = q; + } + while (--i >= 0); + + if (shift > 0) + { + assert ((r0 & (GMP_LIMB_MAX >> (GMP_LIMB_BITS - shift))) == 0); + r0 = (r0 >> shift) | (r1 << (GMP_LIMB_BITS - shift)); + r1 >>= shift; + } + + np[1] = r1; + np[0] = r0; +} + +static void +mpn_div_qr_pi1 (mp_ptr qp, + mp_ptr np, mp_size_t nn, mp_limb_t n1, + mp_srcptr dp, mp_size_t dn, + mp_limb_t dinv) +{ + mp_size_t i; + + mp_limb_t d1, d0; + mp_limb_t cy, cy1; + mp_limb_t q; + + assert (dn > 2); + assert (nn >= dn); + + d1 = dp[dn - 1]; + d0 = dp[dn - 2]; + + assert ((d1 & GMP_LIMB_HIGHBIT) != 0); + /* Iteration variable is the index of the q limb. + * + * We divide <n1, np[dn-1+i], np[dn-2+i], np[dn-3+i],..., np[i]> + * by <d1, d0, dp[dn-3], ..., dp[0] > + */ + + i = nn - dn; + do + { + mp_limb_t n0 = np[dn-1+i]; + + if (n1 == d1 && n0 == d0) + { + q = GMP_LIMB_MAX; + mpn_submul_1 (np+i, dp, dn, q); + n1 = np[dn-1+i]; /* update n1, last loop's value will now be invalid */ + } + else + { + gmp_udiv_qr_3by2 (q, n1, n0, n1, n0, np[dn-2+i], d1, d0, dinv); + + cy = mpn_submul_1 (np + i, dp, dn-2, q); + + cy1 = n0 < cy; + n0 = n0 - cy; + cy = n1 < cy1; + n1 = n1 - cy1; + np[dn-2+i] = n0; + + if (cy != 0) + { + n1 += d1 + mpn_add_n (np + i, np + i, dp, dn - 1); + q--; + } + } + + if (qp) + qp[i] = q; + } + while (--i >= 0); + + np[dn - 1] = n1; +} + +static void +mpn_div_qr_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn, + mp_srcptr dp, mp_size_t dn, + const struct gmp_div_inverse *inv) +{ + assert (dn > 0); + assert (nn >= dn); + + if (dn == 1) + np[0] = mpn_div_qr_1_preinv (qp, np, nn, inv); + else if (dn == 2) + mpn_div_qr_2_preinv (qp, np, nn, inv); + else + { + mp_limb_t nh; + unsigned shift; + + assert (inv->d1 == dp[dn-1]); + assert (inv->d0 == dp[dn-2]); + assert ((inv->d1 & GMP_LIMB_HIGHBIT) != 0); + + shift = inv->shift; + if (shift > 0) + nh = mpn_lshift (np, np, nn, shift); + else + nh = 0; + + mpn_div_qr_pi1 (qp, np, nn, nh, dp, dn, inv->di); + + if (shift > 0) + gmp_assert_nocarry (mpn_rshift (np, np, dn, shift)); + } +} + +static void +mpn_div_qr (mp_ptr qp, mp_ptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn) +{ + struct gmp_div_inverse inv; + mp_ptr tp = NULL; + + assert (dn > 0); + assert (nn >= dn); + + mpn_div_qr_invert (&inv, dp, dn); + if (dn > 2 && inv.shift > 0) + { + tp = gmp_xalloc_limbs (dn); + gmp_assert_nocarry (mpn_lshift (tp, dp, dn, inv.shift)); + dp = tp; + } + mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv); + if (tp) + gmp_free (tp); +} + + +/* MPN base conversion. */ +static unsigned +mpn_base_power_of_two_p (unsigned b) +{ + switch (b) + { + case 2: return 1; + case 4: return 2; + case 8: return 3; + case 16: return 4; + case 32: return 5; + case 64: return 6; + case 128: return 7; + case 256: return 8; + default: return 0; + } +} + +struct mpn_base_info +{ + /* bb is the largest power of the base which fits in one limb, and + exp is the corresponding exponent. */ + unsigned exp; + mp_limb_t bb; +}; + +static void +mpn_get_base_info (struct mpn_base_info *info, mp_limb_t b) +{ + mp_limb_t m; + mp_limb_t p; + unsigned exp; + + m = GMP_LIMB_MAX / b; + for (exp = 1, p = b; p <= m; exp++) + p *= b; + + info->exp = exp; + info->bb = p; +} + +static mp_bitcnt_t +mpn_limb_size_in_base_2 (mp_limb_t u) +{ + unsigned shift; + + assert (u > 0); + gmp_clz (shift, u); + return GMP_LIMB_BITS - shift; +} + +static size_t +mpn_get_str_bits (unsigned char *sp, unsigned bits, mp_srcptr up, mp_size_t un) +{ + unsigned char mask; + size_t sn, j; + mp_size_t i; + unsigned shift; + + sn = ((un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1]) + + bits - 1) / bits; + + mask = (1U << bits) - 1; + + for (i = 0, j = sn, shift = 0; j-- > 0;) + { + unsigned char digit = up[i] >> shift; + + shift += bits; + + if (shift >= GMP_LIMB_BITS && ++i < un) + { + shift -= GMP_LIMB_BITS; + digit |= up[i] << (bits - shift); + } + sp[j] = digit & mask; + } + return sn; +} + +/* We generate digits from the least significant end, and reverse at + the end. */ +static size_t +mpn_limb_get_str (unsigned char *sp, mp_limb_t w, + const struct gmp_div_inverse *binv) +{ + mp_size_t i; + for (i = 0; w > 0; i++) + { + mp_limb_t h, l, r; + + h = w >> (GMP_LIMB_BITS - binv->shift); + l = w << binv->shift; + + gmp_udiv_qrnnd_preinv (w, r, h, l, binv->d1, binv->di); + assert ((r & (GMP_LIMB_MAX >> (GMP_LIMB_BITS - binv->shift))) == 0); + r >>= binv->shift; + + sp[i] = r; + } + return i; +} + +static size_t +mpn_get_str_other (unsigned char *sp, + int base, const struct mpn_base_info *info, + mp_ptr up, mp_size_t un) +{ + struct gmp_div_inverse binv; + size_t sn; + size_t i; + + mpn_div_qr_1_invert (&binv, base); + + sn = 0; + + if (un > 1) + { + struct gmp_div_inverse bbinv; + mpn_div_qr_1_invert (&bbinv, info->bb); + + do + { + mp_limb_t w; + size_t done; + w = mpn_div_qr_1_preinv (up, up, un, &bbinv); + un -= (up[un-1] == 0); + done = mpn_limb_get_str (sp + sn, w, &binv); + + for (sn += done; done < info->exp; done++) + sp[sn++] = 0; + } + while (un > 1); + } + sn += mpn_limb_get_str (sp + sn, up[0], &binv); + + /* Reverse order */ + for (i = 0; 2*i + 1 < sn; i++) + { + unsigned char t = sp[i]; + sp[i] = sp[sn - i - 1]; + sp[sn - i - 1] = t; + } + + return sn; +} + +size_t +mpn_get_str (unsigned char *sp, int base, mp_ptr up, mp_size_t un) +{ + unsigned bits; + + assert (un > 0); + assert (up[un-1] > 0); + + bits = mpn_base_power_of_two_p (base); + if (bits) + return mpn_get_str_bits (sp, bits, up, un); + else + { + struct mpn_base_info info; + + mpn_get_base_info (&info, base); + return mpn_get_str_other (sp, base, &info, up, un); + } +} + +static mp_size_t +mpn_set_str_bits (mp_ptr rp, const unsigned char *sp, size_t sn, + unsigned bits) +{ + mp_size_t rn; + size_t j; + unsigned shift; + + for (j = sn, rn = 0, shift = 0; j-- > 0; ) + { + if (shift == 0) + { + rp[rn++] = sp[j]; + shift += bits; + } + else + { + rp[rn-1] |= (mp_limb_t) sp[j] << shift; + shift += bits; + if (shift >= GMP_LIMB_BITS) + { + shift -= GMP_LIMB_BITS; + if (shift > 0) + rp[rn++] = (mp_limb_t) sp[j] >> (bits - shift); + } + } + } + rn = mpn_normalized_size (rp, rn); + return rn; +} + +/* Result is usually normalized, except for all-zero input, in which + case a single zero limb is written at *RP, and 1 is returned. */ +static mp_size_t +mpn_set_str_other (mp_ptr rp, const unsigned char *sp, size_t sn, + mp_limb_t b, const struct mpn_base_info *info) +{ + mp_size_t rn; + mp_limb_t w; + unsigned k; + size_t j; + + assert (sn > 0); + + k = 1 + (sn - 1) % info->exp; + + j = 0; + w = sp[j++]; + while (--k != 0) + w = w * b + sp[j++]; + + rp[0] = w; + + for (rn = 1; j < sn;) + { + mp_limb_t cy; + + w = sp[j++]; + for (k = 1; k < info->exp; k++) + w = w * b + sp[j++]; + + cy = mpn_mul_1 (rp, rp, rn, info->bb); + cy += mpn_add_1 (rp, rp, rn, w); + if (cy > 0) + rp[rn++] = cy; + } + assert (j == sn); + + return rn; +} + +mp_size_t +mpn_set_str (mp_ptr rp, const unsigned char *sp, size_t sn, int base) +{ + unsigned bits; + + if (sn == 0) + return 0; + + bits = mpn_base_power_of_two_p (base); + if (bits) + return mpn_set_str_bits (rp, sp, sn, bits); + else + { + struct mpn_base_info info; + + mpn_get_base_info (&info, base); + return mpn_set_str_other (rp, sp, sn, base, &info); + } +} + + +/* MPZ interface */ +void +mpz_init (mpz_t r) +{ + static const mp_limb_t dummy_limb = GMP_LIMB_MAX & 0xc1a0; + + r->_mp_alloc = 0; + r->_mp_size = 0; + r->_mp_d = (mp_ptr) &dummy_limb; +} + +/* The utility of this function is a bit limited, since many functions + assigns the result variable using mpz_swap. */ +void +mpz_init2 (mpz_t r, mp_bitcnt_t bits) +{ + mp_size_t rn; + + bits -= (bits != 0); /* Round down, except if 0 */ + rn = 1 + bits / GMP_LIMB_BITS; + + r->_mp_alloc = rn; + r->_mp_size = 0; + r->_mp_d = gmp_xalloc_limbs (rn); +} + +void +mpz_clear (mpz_t r) +{ + if (r->_mp_alloc) + gmp_free (r->_mp_d); +} + +static mp_ptr +mpz_realloc (mpz_t r, mp_size_t size) +{ + size = GMP_MAX (size, 1); + + if (r->_mp_alloc) + r->_mp_d = gmp_xrealloc_limbs (r->_mp_d, size); + else + r->_mp_d = gmp_xalloc_limbs (size); + r->_mp_alloc = size; + + if (GMP_ABS (r->_mp_size) > size) + r->_mp_size = 0; + + return r->_mp_d; +} + +/* Realloc for an mpz_t WHAT if it has less than NEEDED limbs. */ +#define MPZ_REALLOC(z,n) ((n) > (z)->_mp_alloc \ + ? mpz_realloc(z,n) \ + : (z)->_mp_d) + +/* MPZ assignment and basic conversions. */ +void +mpz_set_si (mpz_t r, signed long int x) +{ + if (x >= 0) + mpz_set_ui (r, x); + else /* (x < 0) */ + if (GMP_LIMB_BITS < GMP_ULONG_BITS) + { + mpz_set_ui (r, GMP_NEG_CAST (unsigned long int, x)); + mpz_neg (r, r); + } + else + { + r->_mp_size = -1; + MPZ_REALLOC (r, 1)[0] = GMP_NEG_CAST (unsigned long int, x); + } +} + +void +mpz_set_ui (mpz_t r, unsigned long int x) +{ + if (x > 0) + { + r->_mp_size = 1; + MPZ_REALLOC (r, 1)[0] = x; + if (GMP_LIMB_BITS < GMP_ULONG_BITS) + { + int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS; + while (x >>= LOCAL_GMP_LIMB_BITS) + { + ++ r->_mp_size; + MPZ_REALLOC (r, r->_mp_size)[r->_mp_size - 1] = x; + } + } + } + else + r->_mp_size = 0; +} + +void +mpz_set (mpz_t r, const mpz_t x) +{ + /* Allow the NOP r == x */ + if (r != x) + { + mp_size_t n; + mp_ptr rp; + + n = GMP_ABS (x->_mp_size); + rp = MPZ_REALLOC (r, n); + + mpn_copyi (rp, x->_mp_d, n); + r->_mp_size = x->_mp_size; + } +} + +void +mpz_init_set_si (mpz_t r, signed long int x) +{ + mpz_init (r); + mpz_set_si (r, x); +} + +void +mpz_init_set_ui (mpz_t r, unsigned long int x) +{ + mpz_init (r); + mpz_set_ui (r, x); +} + +void +mpz_init_set (mpz_t r, const mpz_t x) +{ + mpz_init (r); + mpz_set (r, x); +} + +int +mpz_fits_slong_p (const mpz_t u) +{ + return (LONG_MAX + LONG_MIN == 0 || mpz_cmp_ui (u, LONG_MAX) <= 0) && + mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, LONG_MIN)) <= 0; +} + +static int +mpn_absfits_ulong_p (mp_srcptr up, mp_size_t un) +{ + int ulongsize = GMP_ULONG_BITS / GMP_LIMB_BITS; + mp_limb_t ulongrem = 0; + + if (GMP_ULONG_BITS % GMP_LIMB_BITS != 0) + ulongrem = (mp_limb_t) (ULONG_MAX >> GMP_LIMB_BITS * ulongsize) + 1; + + return un <= ulongsize || (up[ulongsize] < ulongrem && un == ulongsize + 1); +} + +int +mpz_fits_ulong_p (const mpz_t u) +{ + mp_size_t us = u->_mp_size; + + return us >= 0 && mpn_absfits_ulong_p (u->_mp_d, us); +} + +long int +mpz_get_si (const mpz_t u) +{ + unsigned long r = mpz_get_ui (u); + unsigned long c = -LONG_MAX - LONG_MIN; + + if (u->_mp_size < 0) + /* This expression is necessary to properly handle -LONG_MIN */ + return -(long) c - (long) ((r - c) & LONG_MAX); + else + return (long) (r & LONG_MAX); +} + +unsigned long int +mpz_get_ui (const mpz_t u) +{ + if (GMP_LIMB_BITS < GMP_ULONG_BITS) + { + int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS; + unsigned long r = 0; + mp_size_t n = GMP_ABS (u->_mp_size); + n = GMP_MIN (n, 1 + (mp_size_t) (GMP_ULONG_BITS - 1) / GMP_LIMB_BITS); + while (--n >= 0) + r = (r << LOCAL_GMP_LIMB_BITS) + u->_mp_d[n]; + return r; + } + + return u->_mp_size == 0 ? 0 : u->_mp_d[0]; +} + +size_t +mpz_size (const mpz_t u) +{ + return GMP_ABS (u->_mp_size); +} + +mp_limb_t +mpz_getlimbn (const mpz_t u, mp_size_t n) +{ + if (n >= 0 && n < GMP_ABS (u->_mp_size)) + return u->_mp_d[n]; + else + return 0; +} + +void +mpz_realloc2 (mpz_t x, mp_bitcnt_t n) +{ + mpz_realloc (x, 1 + (n - (n != 0)) / GMP_LIMB_BITS); +} + +mp_srcptr +mpz_limbs_read (mpz_srcptr x) +{ + return x->_mp_d; +} + +mp_ptr +mpz_limbs_modify (mpz_t x, mp_size_t n) +{ + assert (n > 0); + return MPZ_REALLOC (x, n); +} + +mp_ptr +mpz_limbs_write (mpz_t x, mp_size_t n) +{ + return mpz_limbs_modify (x, n); +} + +void +mpz_limbs_finish (mpz_t x, mp_size_t xs) +{ + mp_size_t xn; + xn = mpn_normalized_size (x->_mp_d, GMP_ABS (xs)); + x->_mp_size = xs < 0 ? -xn : xn; +} + +static mpz_srcptr +mpz_roinit_normal_n (mpz_t x, mp_srcptr xp, mp_size_t xs) +{ + x->_mp_alloc = 0; + x->_mp_d = (mp_ptr) xp; + x->_mp_size = xs; + return x; +} + +mpz_srcptr +mpz_roinit_n (mpz_t x, mp_srcptr xp, mp_size_t xs) +{ + mpz_roinit_normal_n (x, xp, xs); + mpz_limbs_finish (x, xs); + return x; +} + + +/* Conversions and comparison to double. */ +void +mpz_set_d (mpz_t r, double x) +{ + int sign; + mp_ptr rp; + mp_size_t rn, i; + double B; + double Bi; + mp_limb_t f; + + /* x != x is true when x is a NaN, and x == x * 0.5 is true when x is + zero or infinity. */ + if (x != x || x == x * 0.5) + { + r->_mp_size = 0; + return; + } + + sign = x < 0.0 ; + if (sign) + x = - x; + + if (x < 1.0) + { + r->_mp_size = 0; + return; + } + B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1); + Bi = 1.0 / B; + for (rn = 1; x >= B; rn++) + x *= Bi; + + rp = MPZ_REALLOC (r, rn); + + f = (mp_limb_t) x; + x -= f; + assert (x < 1.0); + i = rn-1; + rp[i] = f; + while (--i >= 0) + { + x = B * x; + f = (mp_limb_t) x; + x -= f; + assert (x < 1.0); + rp[i] = f; + } + + r->_mp_size = sign ? - rn : rn; +} + +void +mpz_init_set_d (mpz_t r, double x) +{ + mpz_init (r); + mpz_set_d (r, x); +} + +double +mpz_get_d (const mpz_t u) +{ + int m; + mp_limb_t l; + mp_size_t un; + double x; + double B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1); + + un = GMP_ABS (u->_mp_size); + + if (un == 0) + return 0.0; + + l = u->_mp_d[--un]; + gmp_clz (m, l); + m = m + GMP_DBL_MANT_BITS - GMP_LIMB_BITS; + if (m < 0) + l &= GMP_LIMB_MAX << -m; + + for (x = l; --un >= 0;) + { + x = B*x; + if (m > 0) { + l = u->_mp_d[un]; + m -= GMP_LIMB_BITS; + if (m < 0) + l &= GMP_LIMB_MAX << -m; + x += l; + } + } + + if (u->_mp_size < 0) + x = -x; + + return x; +} + +int +mpz_cmpabs_d (const mpz_t x, double d) +{ + mp_size_t xn; + double B, Bi; + mp_size_t i; + + xn = x->_mp_size; + d = GMP_ABS (d); + + if (xn != 0) + { + xn = GMP_ABS (xn); + + B = 4.0 * (double) (GMP_LIMB_HIGHBIT >> 1); + Bi = 1.0 / B; + + /* Scale d so it can be compared with the top limb. */ + for (i = 1; i < xn; i++) + d *= Bi; + + if (d >= B) + return -1; + + /* Compare floor(d) to top limb, subtract and cancel when equal. */ + for (i = xn; i-- > 0;) + { + mp_limb_t f, xl; + + f = (mp_limb_t) d; + xl = x->_mp_d[i]; + if (xl > f) + return 1; + else if (xl < f) + return -1; + d = B * (d - f); + } + } + return - (d > 0.0); +} + +int +mpz_cmp_d (const mpz_t x, double d) +{ + if (x->_mp_size < 0) + { + if (d >= 0.0) + return -1; + else + return -mpz_cmpabs_d (x, d); + } + else + { + if (d < 0.0) + return 1; + else + return mpz_cmpabs_d (x, d); + } +} + + +/* MPZ comparisons and the like. */ +int +mpz_sgn (const mpz_t u) +{ + return GMP_CMP (u->_mp_size, 0); +} + +int +mpz_cmp_si (const mpz_t u, long v) +{ + mp_size_t usize = u->_mp_size; + + if (v >= 0) + return mpz_cmp_ui (u, v); + else if (usize >= 0) + return 1; + else + return - mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, v)); +} + +int +mpz_cmp_ui (const mpz_t u, unsigned long v) +{ + mp_size_t usize = u->_mp_size; + + if (usize < 0) + return -1; + else + return mpz_cmpabs_ui (u, v); +} + +int +mpz_cmp (const mpz_t a, const mpz_t b) +{ + mp_size_t asize = a->_mp_size; + mp_size_t bsize = b->_mp_size; + + if (asize != bsize) + return (asize < bsize) ? -1 : 1; + else if (asize >= 0) + return mpn_cmp (a->_mp_d, b->_mp_d, asize); + else + return mpn_cmp (b->_mp_d, a->_mp_d, -asize); +} + +int +mpz_cmpabs_ui (const mpz_t u, unsigned long v) +{ + mp_size_t un = GMP_ABS (u->_mp_size); + + if (! mpn_absfits_ulong_p (u->_mp_d, un)) + return 1; + else + { + unsigned long uu = mpz_get_ui (u); + return GMP_CMP(uu, v); + } +} + +int +mpz_cmpabs (const mpz_t u, const mpz_t v) +{ + return mpn_cmp4 (u->_mp_d, GMP_ABS (u->_mp_size), + v->_mp_d, GMP_ABS (v->_mp_size)); +} + +void +mpz_abs (mpz_t r, const mpz_t u) +{ + mpz_set (r, u); + r->_mp_size = GMP_ABS (r->_mp_size); +} + +void +mpz_neg (mpz_t r, const mpz_t u) +{ + mpz_set (r, u); + r->_mp_size = -r->_mp_size; +} + +void +mpz_swap (mpz_t u, mpz_t v) +{ + MP_SIZE_T_SWAP (u->_mp_size, v->_mp_size); + MP_SIZE_T_SWAP (u->_mp_alloc, v->_mp_alloc); + MP_PTR_SWAP (u->_mp_d, v->_mp_d); +} + + +/* MPZ addition and subtraction */ + + +void +mpz_add_ui (mpz_t r, const mpz_t a, unsigned long b) +{ + mpz_t bb; + mpz_init_set_ui (bb, b); + mpz_add (r, a, bb); + mpz_clear (bb); +} + +void +mpz_sub_ui (mpz_t r, const mpz_t a, unsigned long b) +{ + mpz_ui_sub (r, b, a); + mpz_neg (r, r); +} + +void +mpz_ui_sub (mpz_t r, unsigned long a, const mpz_t b) +{ + mpz_neg (r, b); + mpz_add_ui (r, r, a); +} + +static mp_size_t +mpz_abs_add (mpz_t r, const mpz_t a, const mpz_t b) +{ + mp_size_t an = GMP_ABS (a->_mp_size); + mp_size_t bn = GMP_ABS (b->_mp_size); + mp_ptr rp; + mp_limb_t cy; + + if (an < bn) + { + MPZ_SRCPTR_SWAP (a, b); + MP_SIZE_T_SWAP (an, bn); + } + + rp = MPZ_REALLOC (r, an + 1); + cy = mpn_add (rp, a->_mp_d, an, b->_mp_d, bn); + + rp[an] = cy; + + return an + cy; +} + +static mp_size_t +mpz_abs_sub (mpz_t r, const mpz_t a, const mpz_t b) +{ + mp_size_t an = GMP_ABS (a->_mp_size); + mp_size_t bn = GMP_ABS (b->_mp_size); + int cmp; + mp_ptr rp; + + cmp = mpn_cmp4 (a->_mp_d, an, b->_mp_d, bn); + if (cmp > 0) + { + rp = MPZ_REALLOC (r, an); + gmp_assert_nocarry (mpn_sub (rp, a->_mp_d, an, b->_mp_d, bn)); + return mpn_normalized_size (rp, an); + } + else if (cmp < 0) + { + rp = MPZ_REALLOC (r, bn); + gmp_assert_nocarry (mpn_sub (rp, b->_mp_d, bn, a->_mp_d, an)); + return -mpn_normalized_size (rp, bn); + } + else + return 0; +} + +void +mpz_add (mpz_t r, const mpz_t a, const mpz_t b) +{ + mp_size_t rn; + + if ( (a->_mp_size ^ b->_mp_size) >= 0) + rn = mpz_abs_add (r, a, b); + else + rn = mpz_abs_sub (r, a, b); + + r->_mp_size = a->_mp_size >= 0 ? rn : - rn; +} + +void +mpz_sub (mpz_t r, const mpz_t a, const mpz_t b) +{ + mp_size_t rn; + + if ( (a->_mp_size ^ b->_mp_size) >= 0) + rn = mpz_abs_sub (r, a, b); + else + rn = mpz_abs_add (r, a, b); + + r->_mp_size = a->_mp_size >= 0 ? rn : - rn; +} + + +/* MPZ multiplication */ +void +mpz_mul_si (mpz_t r, const mpz_t u, long int v) +{ + if (v < 0) + { + mpz_mul_ui (r, u, GMP_NEG_CAST (unsigned long int, v)); + mpz_neg (r, r); + } + else + mpz_mul_ui (r, u, v); +} + +void +mpz_mul_ui (mpz_t r, const mpz_t u, unsigned long int v) +{ + mpz_t vv; + mpz_init_set_ui (vv, v); + mpz_mul (r, u, vv); + mpz_clear (vv); + return; +} + +void +mpz_mul (mpz_t r, const mpz_t u, const mpz_t v) +{ + int sign; + mp_size_t un, vn, rn; + mpz_t t; + mp_ptr tp; + + un = u->_mp_size; + vn = v->_mp_size; + + if (un == 0 || vn == 0) + { + r->_mp_size = 0; + return; + } + + sign = (un ^ vn) < 0; + + un = GMP_ABS (un); + vn = GMP_ABS (vn); + + mpz_init2 (t, (un + vn) * GMP_LIMB_BITS); + + tp = t->_mp_d; + if (un >= vn) + mpn_mul (tp, u->_mp_d, un, v->_mp_d, vn); + else + mpn_mul (tp, v->_mp_d, vn, u->_mp_d, un); + + rn = un + vn; + rn -= tp[rn-1] == 0; + + t->_mp_size = sign ? - rn : rn; + mpz_swap (r, t); + mpz_clear (t); +} + +void +mpz_mul_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bits) +{ + mp_size_t un, rn; + mp_size_t limbs; + unsigned shift; + mp_ptr rp; + + un = GMP_ABS (u->_mp_size); + if (un == 0) + { + r->_mp_size = 0; + return; + } + + limbs = bits / GMP_LIMB_BITS; + shift = bits % GMP_LIMB_BITS; + + rn = un + limbs + (shift > 0); + rp = MPZ_REALLOC (r, rn); + if (shift > 0) + { + mp_limb_t cy = mpn_lshift (rp + limbs, u->_mp_d, un, shift); + rp[rn-1] = cy; + rn -= (cy == 0); + } + else + mpn_copyd (rp + limbs, u->_mp_d, un); + + mpn_zero (rp, limbs); + + r->_mp_size = (u->_mp_size < 0) ? - rn : rn; +} + +void +mpz_addmul_ui (mpz_t r, const mpz_t u, unsigned long int v) +{ + mpz_t t; + mpz_init_set_ui (t, v); + mpz_mul (t, u, t); + mpz_add (r, r, t); + mpz_clear (t); +} + +void +mpz_submul_ui (mpz_t r, const mpz_t u, unsigned long int v) +{ + mpz_t t; + mpz_init_set_ui (t, v); + mpz_mul (t, u, t); + mpz_sub (r, r, t); + mpz_clear (t); +} + +void +mpz_addmul (mpz_t r, const mpz_t u, const mpz_t v) +{ + mpz_t t; + mpz_init (t); + mpz_mul (t, u, v); + mpz_add (r, r, t); + mpz_clear (t); +} + +void +mpz_submul (mpz_t r, const mpz_t u, const mpz_t v) +{ + mpz_t t; + mpz_init (t); + mpz_mul (t, u, v); + mpz_sub (r, r, t); + mpz_clear (t); +} + + +/* MPZ division */ +enum mpz_div_round_mode { GMP_DIV_FLOOR, GMP_DIV_CEIL, GMP_DIV_TRUNC }; + +/* Allows q or r to be zero. Returns 1 iff remainder is non-zero. */ +static int +mpz_div_qr (mpz_t q, mpz_t r, + const mpz_t n, const mpz_t d, enum mpz_div_round_mode mode) +{ + mp_size_t ns, ds, nn, dn, qs; + ns = n->_mp_size; + ds = d->_mp_size; + + if (ds == 0) + gmp_die("mpz_div_qr: Divide by zero."); + + if (ns == 0) + { + if (q) + q->_mp_size = 0; + if (r) + r->_mp_size = 0; + return 0; + } + + nn = GMP_ABS (ns); + dn = GMP_ABS (ds); + + qs = ds ^ ns; + + if (nn < dn) + { + if (mode == GMP_DIV_CEIL && qs >= 0) + { + /* q = 1, r = n - d */ + if (r) + mpz_sub (r, n, d); + if (q) + mpz_set_ui (q, 1); + } + else if (mode == GMP_DIV_FLOOR && qs < 0) + { + /* q = -1, r = n + d */ + if (r) + mpz_add (r, n, d); + if (q) + mpz_set_si (q, -1); + } + else + { + /* q = 0, r = d */ + if (r) + mpz_set (r, n); + if (q) + q->_mp_size = 0; + } + return 1; + } + else + { + mp_ptr np, qp; + mp_size_t qn, rn; + mpz_t tq, tr; + + mpz_init_set (tr, n); + np = tr->_mp_d; + + qn = nn - dn + 1; + + if (q) + { + mpz_init2 (tq, qn * GMP_LIMB_BITS); + qp = tq->_mp_d; + } + else + qp = NULL; + + mpn_div_qr (qp, np, nn, d->_mp_d, dn); + + if (qp) + { + qn -= (qp[qn-1] == 0); + + tq->_mp_size = qs < 0 ? -qn : qn; + } + rn = mpn_normalized_size (np, dn); + tr->_mp_size = ns < 0 ? - rn : rn; + + if (mode == GMP_DIV_FLOOR && qs < 0 && rn != 0) + { + if (q) + mpz_sub_ui (tq, tq, 1); + if (r) + mpz_add (tr, tr, d); + } + else if (mode == GMP_DIV_CEIL && qs >= 0 && rn != 0) + { + if (q) + mpz_add_ui (tq, tq, 1); + if (r) + mpz_sub (tr, tr, d); + } + + if (q) + { + mpz_swap (tq, q); + mpz_clear (tq); + } + if (r) + mpz_swap (tr, r); + + mpz_clear (tr); + + return rn != 0; + } +} + +void +mpz_cdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, r, n, d, GMP_DIV_CEIL); +} + +void +mpz_fdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, r, n, d, GMP_DIV_FLOOR); +} + +void +mpz_tdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, r, n, d, GMP_DIV_TRUNC); +} + +void +mpz_cdiv_q (mpz_t q, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, NULL, n, d, GMP_DIV_CEIL); +} + +void +mpz_fdiv_q (mpz_t q, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, NULL, n, d, GMP_DIV_FLOOR); +} + +void +mpz_tdiv_q (mpz_t q, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC); +} + +void +mpz_cdiv_r (mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (NULL, r, n, d, GMP_DIV_CEIL); +} + +void +mpz_fdiv_r (mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (NULL, r, n, d, GMP_DIV_FLOOR); +} + +void +mpz_tdiv_r (mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (NULL, r, n, d, GMP_DIV_TRUNC); +} + +void +mpz_mod (mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (NULL, r, n, d, d->_mp_size >= 0 ? GMP_DIV_FLOOR : GMP_DIV_CEIL); +} + +static void +mpz_div_q_2exp (mpz_t q, const mpz_t u, mp_bitcnt_t bit_index, + enum mpz_div_round_mode mode) +{ + mp_size_t un, qn; + mp_size_t limb_cnt; + mp_ptr qp; + int adjust; + + un = u->_mp_size; + if (un == 0) + { + q->_mp_size = 0; + return; + } + limb_cnt = bit_index / GMP_LIMB_BITS; + qn = GMP_ABS (un) - limb_cnt; + bit_index %= GMP_LIMB_BITS; + + if (mode == ((un > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* un != 0 here. */ + /* Note: Below, the final indexing at limb_cnt is valid because at + that point we have qn > 0. */ + adjust = (qn <= 0 + || !mpn_zero_p (u->_mp_d, limb_cnt) + || (u->_mp_d[limb_cnt] + & (((mp_limb_t) 1 << bit_index) - 1))); + else + adjust = 0; + + if (qn <= 0) + qn = 0; + else + { + qp = MPZ_REALLOC (q, qn); + + if (bit_index != 0) + { + mpn_rshift (qp, u->_mp_d + limb_cnt, qn, bit_index); + qn -= qp[qn - 1] == 0; + } + else + { + mpn_copyi (qp, u->_mp_d + limb_cnt, qn); + } + } + + q->_mp_size = qn; + + if (adjust) + mpz_add_ui (q, q, 1); + if (un < 0) + mpz_neg (q, q); +} + +static void +mpz_div_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bit_index, + enum mpz_div_round_mode mode) +{ + mp_size_t us, un, rn; + mp_ptr rp; + mp_limb_t mask; + + us = u->_mp_size; + if (us == 0 || bit_index == 0) + { + r->_mp_size = 0; + return; + } + rn = (bit_index + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; + assert (rn > 0); + + rp = MPZ_REALLOC (r, rn); + un = GMP_ABS (us); + + mask = GMP_LIMB_MAX >> (rn * GMP_LIMB_BITS - bit_index); + + if (rn > un) + { + /* Quotient (with truncation) is zero, and remainder is + non-zero */ + if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */ + { + /* Have to negate and sign extend. */ + mp_size_t i; + + gmp_assert_nocarry (! mpn_neg (rp, u->_mp_d, un)); + for (i = un; i < rn - 1; i++) + rp[i] = GMP_LIMB_MAX; + + rp[rn-1] = mask; + us = -us; + } + else + { + /* Just copy */ + if (r != u) + mpn_copyi (rp, u->_mp_d, un); + + rn = un; + } + } + else + { + if (r != u) + mpn_copyi (rp, u->_mp_d, rn - 1); + + rp[rn-1] = u->_mp_d[rn-1] & mask; + + if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */ + { + /* If r != 0, compute 2^{bit_count} - r. */ + mpn_neg (rp, rp, rn); + + rp[rn-1] &= mask; + + /* us is not used for anything else, so we can modify it + here to indicate flipped sign. */ + us = -us; + } + } + rn = mpn_normalized_size (rp, rn); + r->_mp_size = us < 0 ? -rn : rn; +} + +void +mpz_cdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_q_2exp (r, u, cnt, GMP_DIV_CEIL); +} + +void +mpz_fdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_q_2exp (r, u, cnt, GMP_DIV_FLOOR); +} + +void +mpz_tdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_q_2exp (r, u, cnt, GMP_DIV_TRUNC); +} + +void +mpz_cdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_r_2exp (r, u, cnt, GMP_DIV_CEIL); +} + +void +mpz_fdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_r_2exp (r, u, cnt, GMP_DIV_FLOOR); +} + +void +mpz_tdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_r_2exp (r, u, cnt, GMP_DIV_TRUNC); +} + +void +mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d) +{ + gmp_assert_nocarry (mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC)); +} + +int +mpz_divisible_p (const mpz_t n, const mpz_t d) +{ + return mpz_div_qr (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0; +} + +int +mpz_congruent_p (const mpz_t a, const mpz_t b, const mpz_t m) +{ + mpz_t t; + int res; + + /* a == b (mod 0) iff a == b */ + if (mpz_sgn (m) == 0) + return (mpz_cmp (a, b) == 0); + + mpz_init (t); + mpz_sub (t, a, b); + res = mpz_divisible_p (t, m); + mpz_clear (t); + + return res; +} + +static unsigned long +mpz_div_qr_ui (mpz_t q, mpz_t r, + const mpz_t n, unsigned long d, enum mpz_div_round_mode mode) +{ + unsigned long ret; + mpz_t rr, dd; + + mpz_init (rr); + mpz_init_set_ui (dd, d); + mpz_div_qr (q, rr, n, dd, mode); + mpz_clear (dd); + ret = mpz_get_ui (rr); + + if (r) + mpz_swap (r, rr); + mpz_clear (rr); + + return ret; +} + +unsigned long +mpz_cdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, r, n, d, GMP_DIV_CEIL); +} + +unsigned long +mpz_fdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, r, n, d, GMP_DIV_FLOOR); +} + +unsigned long +mpz_tdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, r, n, d, GMP_DIV_TRUNC); +} + +unsigned long +mpz_cdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_CEIL); +} + +unsigned long +mpz_fdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_FLOOR); +} + +unsigned long +mpz_tdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC); +} + +unsigned long +mpz_cdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_CEIL); +} +unsigned long +mpz_fdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR); +} +unsigned long +mpz_tdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_TRUNC); +} + +unsigned long +mpz_cdiv_ui (const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_CEIL); +} + +unsigned long +mpz_fdiv_ui (const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_FLOOR); +} + +unsigned long +mpz_tdiv_ui (const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC); +} + +unsigned long +mpz_mod_ui (mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR); +} + +void +mpz_divexact_ui (mpz_t q, const mpz_t n, unsigned long d) +{ + gmp_assert_nocarry (mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC)); +} + +int +mpz_divisible_ui_p (const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0; +} + + +/* GCD */ +static mp_limb_t +mpn_gcd_11 (mp_limb_t u, mp_limb_t v) +{ + unsigned shift; + + assert ( (u | v) > 0); + + if (u == 0) + return v; + else if (v == 0) + return u; + + gmp_ctz (shift, u | v); + + u >>= shift; + v >>= shift; + + if ( (u & 1) == 0) + MP_LIMB_T_SWAP (u, v); + + while ( (v & 1) == 0) + v >>= 1; + + while (u != v) + { + if (u > v) + { + u -= v; + do + u >>= 1; + while ( (u & 1) == 0); + } + else + { + v -= u; + do + v >>= 1; + while ( (v & 1) == 0); + } + } + return u << shift; +} + +unsigned long +mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v) +{ + mpz_t t; + mpz_init_set_ui(t, v); + mpz_gcd (t, u, t); + if (v > 0) + v = mpz_get_ui (t); + + if (g) + mpz_swap (t, g); + + mpz_clear (t); + + return v; +} + +static mp_bitcnt_t +mpz_make_odd (mpz_t r) +{ + mp_bitcnt_t shift; + + assert (r->_mp_size > 0); + /* Count trailing zeros, equivalent to mpn_scan1, because we know that there is a 1 */ + shift = mpn_common_scan (r->_mp_d[0], 0, r->_mp_d, 0, 0); + mpz_tdiv_q_2exp (r, r, shift); + + return shift; +} + +void +mpz_gcd (mpz_t g, const mpz_t u, const mpz_t v) +{ + mpz_t tu, tv; + mp_bitcnt_t uz, vz, gz; + + if (u->_mp_size == 0) + { + mpz_abs (g, v); + return; + } + if (v->_mp_size == 0) + { + mpz_abs (g, u); + return; + } + + mpz_init (tu); + mpz_init (tv); + + mpz_abs (tu, u); + uz = mpz_make_odd (tu); + mpz_abs (tv, v); + vz = mpz_make_odd (tv); + gz = GMP_MIN (uz, vz); + + if (tu->_mp_size < tv->_mp_size) + mpz_swap (tu, tv); + + mpz_tdiv_r (tu, tu, tv); + if (tu->_mp_size == 0) + { + mpz_swap (g, tv); + } + else + for (;;) + { + int c; + + mpz_make_odd (tu); + c = mpz_cmp (tu, tv); + if (c == 0) + { + mpz_swap (g, tu); + break; + } + if (c < 0) + mpz_swap (tu, tv); + + if (tv->_mp_size == 1) + { + mp_limb_t vl = tv->_mp_d[0]; + mp_limb_t ul = mpz_tdiv_ui (tu, vl); + mpz_set_ui (g, mpn_gcd_11 (ul, vl)); + break; + } + mpz_sub (tu, tu, tv); + } + mpz_clear (tu); + mpz_clear (tv); + mpz_mul_2exp (g, g, gz); +} + +void +mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) +{ + mpz_t tu, tv, s0, s1, t0, t1; + mp_bitcnt_t uz, vz, gz; + mp_bitcnt_t power; + + if (u->_mp_size == 0) + { + /* g = 0 u + sgn(v) v */ + signed long sign = mpz_sgn (v); + mpz_abs (g, v); + if (s) + s->_mp_size = 0; + if (t) + mpz_set_si (t, sign); + return; + } + + if (v->_mp_size == 0) + { + /* g = sgn(u) u + 0 v */ + signed long sign = mpz_sgn (u); + mpz_abs (g, u); + if (s) + mpz_set_si (s, sign); + if (t) + t->_mp_size = 0; + return; + } + + mpz_init (tu); + mpz_init (tv); + mpz_init (s0); + mpz_init (s1); + mpz_init (t0); + mpz_init (t1); + + mpz_abs (tu, u); + uz = mpz_make_odd (tu); + mpz_abs (tv, v); + vz = mpz_make_odd (tv); + gz = GMP_MIN (uz, vz); + + uz -= gz; + vz -= gz; + + /* Cofactors corresponding to odd gcd. gz handled later. */ + if (tu->_mp_size < tv->_mp_size) + { + mpz_swap (tu, tv); + MPZ_SRCPTR_SWAP (u, v); + MPZ_PTR_SWAP (s, t); + MP_BITCNT_T_SWAP (uz, vz); + } + + /* Maintain + * + * u = t0 tu + t1 tv + * v = s0 tu + s1 tv + * + * where u and v denote the inputs with common factors of two + * eliminated, and det (s0, t0; s1, t1) = 2^p. Then + * + * 2^p tu = s1 u - t1 v + * 2^p tv = -s0 u + t0 v + */ + + /* After initial division, tu = q tv + tu', we have + * + * u = 2^uz (tu' + q tv) + * v = 2^vz tv + * + * or + * + * t0 = 2^uz, t1 = 2^uz q + * s0 = 0, s1 = 2^vz + */ + + mpz_setbit (t0, uz); + mpz_tdiv_qr (t1, tu, tu, tv); + mpz_mul_2exp (t1, t1, uz); + + mpz_setbit (s1, vz); + power = uz + vz; + + if (tu->_mp_size > 0) + { + mp_bitcnt_t shift; + shift = mpz_make_odd (tu); + mpz_mul_2exp (t0, t0, shift); + mpz_mul_2exp (s0, s0, shift); + power += shift; + + for (;;) + { + int c; + c = mpz_cmp (tu, tv); + if (c == 0) + break; + + if (c < 0) + { + /* tv = tv' + tu + * + * u = t0 tu + t1 (tv' + tu) = (t0 + t1) tu + t1 tv' + * v = s0 tu + s1 (tv' + tu) = (s0 + s1) tu + s1 tv' */ + + mpz_sub (tv, tv, tu); + mpz_add (t0, t0, t1); + mpz_add (s0, s0, s1); + + shift = mpz_make_odd (tv); + mpz_mul_2exp (t1, t1, shift); + mpz_mul_2exp (s1, s1, shift); + } + else + { + mpz_sub (tu, tu, tv); + mpz_add (t1, t0, t1); + mpz_add (s1, s0, s1); + + shift = mpz_make_odd (tu); + mpz_mul_2exp (t0, t0, shift); + mpz_mul_2exp (s0, s0, shift); + } + power += shift; + } + } + + /* Now tv = odd part of gcd, and -s0 and t0 are corresponding + cofactors. */ + + mpz_mul_2exp (tv, tv, gz); + mpz_neg (s0, s0); + + /* 2^p g = s0 u + t0 v. Eliminate one factor of two at a time. To + adjust cofactors, we need u / g and v / g */ + + mpz_divexact (s1, v, tv); + mpz_abs (s1, s1); + mpz_divexact (t1, u, tv); + mpz_abs (t1, t1); + + while (power-- > 0) + { + /* s0 u + t0 v = (s0 - v/g) u - (t0 + u/g) v */ + if (mpz_odd_p (s0) || mpz_odd_p (t0)) + { + mpz_sub (s0, s0, s1); + mpz_add (t0, t0, t1); + } + assert (mpz_even_p (t0) && mpz_even_p (s0)); + mpz_tdiv_q_2exp (s0, s0, 1); + mpz_tdiv_q_2exp (t0, t0, 1); + } + + /* Arrange so that |s| < |u| / 2g */ + mpz_add (s1, s0, s1); + if (mpz_cmpabs (s0, s1) > 0) + { + mpz_swap (s0, s1); + mpz_sub (t0, t0, t1); + } + if (u->_mp_size < 0) + mpz_neg (s0, s0); + if (v->_mp_size < 0) + mpz_neg (t0, t0); + + mpz_swap (g, tv); + if (s) + mpz_swap (s, s0); + if (t) + mpz_swap (t, t0); + + mpz_clear (tu); + mpz_clear (tv); + mpz_clear (s0); + mpz_clear (s1); + mpz_clear (t0); + mpz_clear (t1); +} + +void +mpz_lcm (mpz_t r, const mpz_t u, const mpz_t v) +{ + mpz_t g; + + if (u->_mp_size == 0 || v->_mp_size == 0) + { + r->_mp_size = 0; + return; + } + + mpz_init (g); + + mpz_gcd (g, u, v); + mpz_divexact (g, u, g); + mpz_mul (r, g, v); + + mpz_clear (g); + mpz_abs (r, r); +} + +void +mpz_lcm_ui (mpz_t r, const mpz_t u, unsigned long v) +{ + if (v == 0 || u->_mp_size == 0) + { + r->_mp_size = 0; + return; + } + + v /= mpz_gcd_ui (NULL, u, v); + mpz_mul_ui (r, u, v); + + mpz_abs (r, r); +} + +int +mpz_invert (mpz_t r, const mpz_t u, const mpz_t m) +{ + mpz_t g, tr; + int invertible; + + if (u->_mp_size == 0 || mpz_cmpabs_ui (m, 1) <= 0) + return 0; + + mpz_init (g); + mpz_init (tr); + + mpz_gcdext (g, tr, NULL, u, m); + invertible = (mpz_cmp_ui (g, 1) == 0); + + if (invertible) + { + if (tr->_mp_size < 0) + { + if (m->_mp_size >= 0) + mpz_add (tr, tr, m); + else + mpz_sub (tr, tr, m); + } + mpz_swap (r, tr); + } + + mpz_clear (g); + mpz_clear (tr); + return invertible; +} + + +/* Higher level operations (sqrt, pow and root) */ + +void +mpz_pow_ui (mpz_t r, const mpz_t b, unsigned long e) +{ + unsigned long bit; + mpz_t tr; + mpz_init_set_ui (tr, 1); + + bit = GMP_ULONG_HIGHBIT; + do + { + mpz_mul (tr, tr, tr); + if (e & bit) + mpz_mul (tr, tr, b); + bit >>= 1; + } + while (bit > 0); + + mpz_swap (r, tr); + mpz_clear (tr); +} + +void +mpz_ui_pow_ui (mpz_t r, unsigned long blimb, unsigned long e) +{ + mpz_t b; + + mpz_init_set_ui (b, blimb); + mpz_pow_ui (r, b, e); + mpz_clear (b); +} + +void +mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m) +{ + mpz_t tr; + mpz_t base; + mp_size_t en, mn; + mp_srcptr mp; + struct gmp_div_inverse minv; + unsigned shift; + mp_ptr tp = NULL; + + en = GMP_ABS (e->_mp_size); + mn = GMP_ABS (m->_mp_size); + if (mn == 0) + gmp_die ("mpz_powm: Zero modulo."); + + if (en == 0) + { + mpz_set_ui (r, 1); + return; + } + + mp = m->_mp_d; + mpn_div_qr_invert (&minv, mp, mn); + shift = minv.shift; + + if (shift > 0) + { + /* To avoid shifts, we do all our reductions, except the final + one, using a *normalized* m. */ + minv.shift = 0; + + tp = gmp_xalloc_limbs (mn); + gmp_assert_nocarry (mpn_lshift (tp, mp, mn, shift)); + mp = tp; + } + + mpz_init (base); + + if (e->_mp_size < 0) + { + if (!mpz_invert (base, b, m)) + gmp_die ("mpz_powm: Negative exponent and non-invertible base."); + } + else + { + mp_size_t bn; + mpz_abs (base, b); + + bn = base->_mp_size; + if (bn >= mn) + { + mpn_div_qr_preinv (NULL, base->_mp_d, base->_mp_size, mp, mn, &minv); + bn = mn; + } + + /* We have reduced the absolute value. Now take care of the + sign. Note that we get zero represented non-canonically as + m. */ + if (b->_mp_size < 0) + { + mp_ptr bp = MPZ_REALLOC (base, mn); + gmp_assert_nocarry (mpn_sub (bp, mp, mn, bp, bn)); + bn = mn; + } + base->_mp_size = mpn_normalized_size (base->_mp_d, bn); + } + mpz_init_set_ui (tr, 1); + + while (--en >= 0) + { + mp_limb_t w = e->_mp_d[en]; + mp_limb_t bit; + + bit = GMP_LIMB_HIGHBIT; + do + { + mpz_mul (tr, tr, tr); + if (w & bit) + mpz_mul (tr, tr, base); + if (tr->_mp_size > mn) + { + mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv); + tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn); + } + bit >>= 1; + } + while (bit > 0); + } + + /* Final reduction */ + if (tr->_mp_size >= mn) + { + minv.shift = shift; + mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv); + tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn); + } + if (tp) + gmp_free (tp); + + mpz_swap (r, tr); + mpz_clear (tr); + mpz_clear (base); +} + +void +mpz_powm_ui (mpz_t r, const mpz_t b, unsigned long elimb, const mpz_t m) +{ + mpz_t e; + + mpz_init_set_ui (e, elimb); + mpz_powm (r, b, e, m); + mpz_clear (e); +} + +/* x=trunc(y^(1/z)), r=y-x^z */ +void +mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z) +{ + int sgn; + mpz_t t, u; + + sgn = y->_mp_size < 0; + if ((~z & sgn) != 0) + gmp_die ("mpz_rootrem: Negative argument, with even root."); + if (z == 0) + gmp_die ("mpz_rootrem: Zeroth root."); + + if (mpz_cmpabs_ui (y, 1) <= 0) { + if (x) + mpz_set (x, y); + if (r) + r->_mp_size = 0; + return; + } + + mpz_init (u); + mpz_init (t); + mpz_setbit (t, mpz_sizeinbase (y, 2) / z + 1); + + if (z == 2) /* simplify sqrt loop: z-1 == 1 */ + do { + mpz_swap (u, t); /* u = x */ + mpz_tdiv_q (t, y, u); /* t = y/x */ + mpz_add (t, t, u); /* t = y/x + x */ + mpz_tdiv_q_2exp (t, t, 1); /* x'= (y/x + x)/2 */ + } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */ + else /* z != 2 */ { + mpz_t v; + + mpz_init (v); + if (sgn) + mpz_neg (t, t); + + do { + mpz_swap (u, t); /* u = x */ + mpz_pow_ui (t, u, z - 1); /* t = x^(z-1) */ + mpz_tdiv_q (t, y, t); /* t = y/x^(z-1) */ + mpz_mul_ui (v, u, z - 1); /* v = x*(z-1) */ + mpz_add (t, t, v); /* t = y/x^(z-1) + x*(z-1) */ + mpz_tdiv_q_ui (t, t, z); /* x'=(y/x^(z-1) + x*(z-1))/z */ + } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */ + + mpz_clear (v); + } + + if (r) { + mpz_pow_ui (t, u, z); + mpz_sub (r, y, t); + } + if (x) + mpz_swap (x, u); + mpz_clear (u); + mpz_clear (t); +} + +int +mpz_root (mpz_t x, const mpz_t y, unsigned long z) +{ + int res; + mpz_t r; + + mpz_init (r); + mpz_rootrem (x, r, y, z); + res = r->_mp_size == 0; + mpz_clear (r); + + return res; +} + +/* Compute s = floor(sqrt(u)) and r = u - s^2. Allows r == NULL */ +void +mpz_sqrtrem (mpz_t s, mpz_t r, const mpz_t u) +{ + mpz_rootrem (s, r, u, 2); +} + +void +mpz_sqrt (mpz_t s, const mpz_t u) +{ + mpz_rootrem (s, NULL, u, 2); +} + +int +mpz_perfect_square_p (const mpz_t u) +{ + if (u->_mp_size <= 0) + return (u->_mp_size == 0); + else + return mpz_root (NULL, u, 2); +} + +int +mpn_perfect_square_p (mp_srcptr p, mp_size_t n) +{ + mpz_t t; + + assert (n > 0); + assert (p [n-1] != 0); + return mpz_root (NULL, mpz_roinit_normal_n (t, p, n), 2); +} + +mp_size_t +mpn_sqrtrem (mp_ptr sp, mp_ptr rp, mp_srcptr p, mp_size_t n) +{ + mpz_t s, r, u; + mp_size_t res; + + assert (n > 0); + assert (p [n-1] != 0); + + mpz_init (r); + mpz_init (s); + mpz_rootrem (s, r, mpz_roinit_normal_n (u, p, n), 2); + + assert (s->_mp_size == (n+1)/2); + mpn_copyd (sp, s->_mp_d, s->_mp_size); + mpz_clear (s); + res = r->_mp_size; + if (rp) + mpn_copyd (rp, r->_mp_d, res); + mpz_clear (r); + return res; +} + +/* Combinatorics */ + +void +mpz_mfac_uiui (mpz_t x, unsigned long n, unsigned long m) +{ + mpz_set_ui (x, n + (n == 0)); + if (m + 1 < 2) return; + while (n > m + 1) + mpz_mul_ui (x, x, n -= m); +} + +void +mpz_2fac_ui (mpz_t x, unsigned long n) +{ + mpz_mfac_uiui (x, n, 2); +} + +void +mpz_fac_ui (mpz_t x, unsigned long n) +{ + mpz_mfac_uiui (x, n, 1); +} + +void +mpz_bin_uiui (mpz_t r, unsigned long n, unsigned long k) +{ + mpz_t t; + + mpz_set_ui (r, k <= n); + + if (k > (n >> 1)) + k = (k <= n) ? n - k : 0; + + mpz_init (t); + mpz_fac_ui (t, k); + + for (; k > 0; --k) + mpz_mul_ui (r, r, n--); + + mpz_divexact (r, r, t); + mpz_clear (t); +} + + +/* Primality testing */ + +/* Computes Kronecker (a/b) with odd b, a!=0 and GCD(a,b) = 1 */ +/* Adapted from JACOBI_BASE_METHOD==4 in mpn/generic/jacbase.c */ +static int +gmp_jacobi_coprime (mp_limb_t a, mp_limb_t b) +{ + int c, bit = 0; + + assert (b & 1); + assert (a != 0); + /* assert (mpn_gcd_11 (a, b) == 1); */ + + /* Below, we represent a and b shifted right so that the least + significant one bit is implicit. */ + b >>= 1; + + gmp_ctz(c, a); + a >>= 1; + + do + { + a >>= c; + /* (2/b) = -1 if b = 3 or 5 mod 8 */ + bit ^= c & (b ^ (b >> 1)); + if (a < b) + { + bit ^= a & b; + a = b - a; + b -= a; + } + else + { + a -= b; + assert (a != 0); + } + + gmp_ctz(c, a); + ++c; + } + while (b > 0); + + return bit & 1 ? -1 : 1; +} + +static void +gmp_lucas_step_k_2k (mpz_t V, mpz_t Qk, const mpz_t n) +{ + mpz_mod (Qk, Qk, n); + /* V_{2k} <- V_k ^ 2 - 2Q^k */ + mpz_mul (V, V, V); + mpz_submul_ui (V, Qk, 2); + mpz_tdiv_r (V, V, n); + /* Q^{2k} = (Q^k)^2 */ + mpz_mul (Qk, Qk, Qk); +} + +/* Computes V_k, Q^k (mod n) for the Lucas' sequence */ +/* with P=1, Q=Q; k = (n>>b0)|1. */ +/* Requires an odd n > 4; b0 > 0; -2*Q must not overflow a long */ +/* Returns (U_k == 0) and sets V=V_k and Qk=Q^k. */ +static int +gmp_lucas_mod (mpz_t V, mpz_t Qk, long Q, + mp_bitcnt_t b0, const mpz_t n) +{ + mp_bitcnt_t bs; + mpz_t U; + int res; + + assert (b0 > 0); + assert (Q <= - (LONG_MIN / 2)); + assert (Q >= - (LONG_MAX / 2)); + assert (mpz_cmp_ui (n, 4) > 0); + assert (mpz_odd_p (n)); + + mpz_init_set_ui (U, 1); /* U1 = 1 */ + mpz_set_ui (V, 1); /* V1 = 1 */ + mpz_set_si (Qk, Q); + + for (bs = mpz_sizeinbase (n, 2) - 1; --bs >= b0;) + { + /* U_{2k} <- U_k * V_k */ + mpz_mul (U, U, V); + /* V_{2k} <- V_k ^ 2 - 2Q^k */ + /* Q^{2k} = (Q^k)^2 */ + gmp_lucas_step_k_2k (V, Qk, n); + + /* A step k->k+1 is performed if the bit in $n$ is 1 */ + /* mpz_tstbit(n,bs) or the the bit is 0 in $n$ but */ + /* should be 1 in $n+1$ (bs == b0) */ + if (b0 == bs || mpz_tstbit (n, bs)) + { + /* Q^{k+1} <- Q^k * Q */ + mpz_mul_si (Qk, Qk, Q); + /* U_{k+1} <- (U_k + V_k) / 2 */ + mpz_swap (U, V); /* Keep in V the old value of U_k */ + mpz_add (U, U, V); + /* We have to compute U/2, so we need an even value, */ + /* equivalent (mod n) */ + if (mpz_odd_p (U)) + mpz_add (U, U, n); + mpz_tdiv_q_2exp (U, U, 1); + /* V_{k+1} <-(D*U_k + V_k) / 2 = + U_{k+1} + (D-1)/2*U_k = U_{k+1} - 2Q*U_k */ + mpz_mul_si (V, V, -2*Q); + mpz_add (V, U, V); + mpz_tdiv_r (V, V, n); + } + mpz_tdiv_r (U, U, n); + } + + res = U->_mp_size == 0; + mpz_clear (U); + return res; +} + +/* Performs strong Lucas' test on x, with parameters suggested */ +/* for the BPSW test. Qk is only passed to recycle a variable. */ +/* Requires GCD (x,6) = 1.*/ +static int +gmp_stronglucas (const mpz_t x, mpz_t Qk) +{ + mp_bitcnt_t b0; + mpz_t V, n; + mp_limb_t maxD, D; /* The absolute value is stored. */ + long Q; + mp_limb_t tl; + + /* Test on the absolute value. */ + mpz_roinit_normal_n (n, x->_mp_d, GMP_ABS (x->_mp_size)); + + assert (mpz_odd_p (n)); + /* assert (mpz_gcd_ui (NULL, n, 6) == 1); */ + if (mpz_root (Qk, n, 2)) + return 0; /* A square is composite. */ + + /* Check Ds up to square root (in case, n is prime) + or avoid overflows */ + maxD = (Qk->_mp_size == 1) ? Qk->_mp_d [0] - 1 : GMP_LIMB_MAX; + + D = 3; + /* Search a D such that (D/n) = -1 in the sequence 5,-7,9,-11,.. */ + /* For those Ds we have (D/n) = (n/|D|) */ + do + { + if (D >= maxD) + return 1 + (D != GMP_LIMB_MAX); /* (1 + ! ~ D) */ + D += 2; + tl = mpz_tdiv_ui (n, D); + if (tl == 0) + return 0; + } + while (gmp_jacobi_coprime (tl, D) == 1); + + mpz_init (V); + + /* n-(D/n) = n+1 = d*2^{b0}, with d = (n>>b0) | 1 */ + b0 = mpz_scan0 (n, 0); + + /* D= P^2 - 4Q; P = 1; Q = (1-D)/4 */ + Q = (D & 2) ? (long) (D >> 2) + 1 : -(long) (D >> 2); + + if (! gmp_lucas_mod (V, Qk, Q, b0, n)) /* If Ud != 0 */ + while (V->_mp_size != 0 && --b0 != 0) /* while Vk != 0 */ + /* V <- V ^ 2 - 2Q^k */ + /* Q^{2k} = (Q^k)^2 */ + gmp_lucas_step_k_2k (V, Qk, n); + + mpz_clear (V); + return (b0 != 0); +} + +static int +gmp_millerrabin (const mpz_t n, const mpz_t nm1, mpz_t y, + const mpz_t q, mp_bitcnt_t k) +{ + assert (k > 0); + + /* Caller must initialize y to the base. */ + mpz_powm (y, y, q, n); + + if (mpz_cmp_ui (y, 1) == 0 || mpz_cmp (y, nm1) == 0) + return 1; + + while (--k > 0) + { + mpz_powm_ui (y, y, 2, n); + if (mpz_cmp (y, nm1) == 0) + return 1; + /* y == 1 means that the previous y was a non-trivial square root + of 1 (mod n). y == 0 means that n is a power of the base. + In either case, n is not prime. */ + if (mpz_cmp_ui (y, 1) <= 0) + return 0; + } + return 0; +} + +/* This product is 0xc0cfd797, and fits in 32 bits. */ +#define GMP_PRIME_PRODUCT \ + (3UL*5UL*7UL*11UL*13UL*17UL*19UL*23UL*29UL) + +/* Bit (p+1)/2 is set, for each odd prime <= 61 */ +#define GMP_PRIME_MASK 0xc96996dcUL + +int +mpz_probab_prime_p (const mpz_t n, int reps) +{ + mpz_t nm1; + mpz_t q; + mpz_t y; + mp_bitcnt_t k; + int is_prime; + int j; + + /* Note that we use the absolute value of n only, for compatibility + with the real GMP. */ + if (mpz_even_p (n)) + return (mpz_cmpabs_ui (n, 2) == 0) ? 2 : 0; + + /* Above test excludes n == 0 */ + assert (n->_mp_size != 0); + + if (mpz_cmpabs_ui (n, 64) < 0) + return (GMP_PRIME_MASK >> (n->_mp_d[0] >> 1)) & 2; + + if (mpz_gcd_ui (NULL, n, GMP_PRIME_PRODUCT) != 1) + return 0; + + /* All prime factors are >= 31. */ + if (mpz_cmpabs_ui (n, 31*31) < 0) + return 2; + + mpz_init (nm1); + mpz_init (q); + + /* Find q and k, where q is odd and n = 1 + 2**k * q. */ + mpz_abs (nm1, n); + nm1->_mp_d[0] -= 1; + k = mpz_scan1 (nm1, 0); + mpz_tdiv_q_2exp (q, nm1, k); + + /* BPSW test */ + mpz_init_set_ui (y, 2); + is_prime = gmp_millerrabin (n, nm1, y, q, k) && gmp_stronglucas (n, y); + reps -= 24; /* skip the first 24 repetitions */ + + /* Use Miller-Rabin, with a deterministic sequence of bases, a[j] = + j^2 + j + 41 using Euler's polynomial. We potentially stop early, + if a[j] >= n - 1. Since n >= 31*31, this can happen only if reps > + 30 (a[30] == 971 > 31*31 == 961). */ + + for (j = 0; is_prime & (j < reps); j++) + { + mpz_set_ui (y, (unsigned long) j*j+j+41); + if (mpz_cmp (y, nm1) >= 0) + { + /* Don't try any further bases. This "early" break does not affect + the result for any reasonable reps value (<=5000 was tested) */ + assert (j >= 30); + break; + } + is_prime = gmp_millerrabin (n, nm1, y, q, k); + } + mpz_clear (nm1); + mpz_clear (q); + mpz_clear (y); + + return is_prime; +} + + +/* Logical operations and bit manipulation. */ + +/* Numbers are treated as if represented in two's complement (and + infinitely sign extended). For a negative values we get the two's + complement from -x = ~x + 1, where ~ is bitwise complement. + Negation transforms + + xxxx10...0 + + into + + yyyy10...0 + + where yyyy is the bitwise complement of xxxx. So least significant + bits, up to and including the first one bit, are unchanged, and + the more significant bits are all complemented. + + To change a bit from zero to one in a negative number, subtract the + corresponding power of two from the absolute value. This can never + underflow. To change a bit from one to zero, add the corresponding + power of two, and this might overflow. E.g., if x = -001111, the + two's complement is 110001. Clearing the least significant bit, we + get two's complement 110000, and -010000. */ + +int +mpz_tstbit (const mpz_t d, mp_bitcnt_t bit_index) +{ + mp_size_t limb_index; + unsigned shift; + mp_size_t ds; + mp_size_t dn; + mp_limb_t w; + int bit; + + ds = d->_mp_size; + dn = GMP_ABS (ds); + limb_index = bit_index / GMP_LIMB_BITS; + if (limb_index >= dn) + return ds < 0; + + shift = bit_index % GMP_LIMB_BITS; + w = d->_mp_d[limb_index]; + bit = (w >> shift) & 1; + + if (ds < 0) + { + /* d < 0. Check if any of the bits below is set: If so, our bit + must be complemented. */ + if (shift > 0 && (mp_limb_t) (w << (GMP_LIMB_BITS - shift)) > 0) + return bit ^ 1; + while (--limb_index >= 0) + if (d->_mp_d[limb_index] > 0) + return bit ^ 1; + } + return bit; +} + +static void +mpz_abs_add_bit (mpz_t d, mp_bitcnt_t bit_index) +{ + mp_size_t dn, limb_index; + mp_limb_t bit; + mp_ptr dp; + + dn = GMP_ABS (d->_mp_size); + + limb_index = bit_index / GMP_LIMB_BITS; + bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS); + + if (limb_index >= dn) + { + mp_size_t i; + /* The bit should be set outside of the end of the number. + We have to increase the size of the number. */ + dp = MPZ_REALLOC (d, limb_index + 1); + + dp[limb_index] = bit; + for (i = dn; i < limb_index; i++) + dp[i] = 0; + dn = limb_index + 1; + } + else + { + mp_limb_t cy; + + dp = d->_mp_d; + + cy = mpn_add_1 (dp + limb_index, dp + limb_index, dn - limb_index, bit); + if (cy > 0) + { + dp = MPZ_REALLOC (d, dn + 1); + dp[dn++] = cy; + } + } + + d->_mp_size = (d->_mp_size < 0) ? - dn : dn; +} + +static void +mpz_abs_sub_bit (mpz_t d, mp_bitcnt_t bit_index) +{ + mp_size_t dn, limb_index; + mp_ptr dp; + mp_limb_t bit; + + dn = GMP_ABS (d->_mp_size); + dp = d->_mp_d; + + limb_index = bit_index / GMP_LIMB_BITS; + bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS); + + assert (limb_index < dn); + + gmp_assert_nocarry (mpn_sub_1 (dp + limb_index, dp + limb_index, + dn - limb_index, bit)); + dn = mpn_normalized_size (dp, dn); + d->_mp_size = (d->_mp_size < 0) ? - dn : dn; +} + +void +mpz_setbit (mpz_t d, mp_bitcnt_t bit_index) +{ + if (!mpz_tstbit (d, bit_index)) + { + if (d->_mp_size >= 0) + mpz_abs_add_bit (d, bit_index); + else + mpz_abs_sub_bit (d, bit_index); + } +} + +void +mpz_clrbit (mpz_t d, mp_bitcnt_t bit_index) +{ + if (mpz_tstbit (d, bit_index)) + { + if (d->_mp_size >= 0) + mpz_abs_sub_bit (d, bit_index); + else + mpz_abs_add_bit (d, bit_index); + } +} + +void +mpz_combit (mpz_t d, mp_bitcnt_t bit_index) +{ + if (mpz_tstbit (d, bit_index) ^ (d->_mp_size < 0)) + mpz_abs_sub_bit (d, bit_index); + else + mpz_abs_add_bit (d, bit_index); +} + +void +mpz_com (mpz_t r, const mpz_t u) +{ + mpz_add_ui (r, u, 1); + mpz_neg (r, r); +} + +void +mpz_and (mpz_t r, const mpz_t u, const mpz_t v) +{ + mp_size_t un, vn, rn, i; + mp_ptr up, vp, rp; + + mp_limb_t ux, vx, rx; + mp_limb_t uc, vc, rc; + mp_limb_t ul, vl, rl; + + un = GMP_ABS (u->_mp_size); + vn = GMP_ABS (v->_mp_size); + if (un < vn) + { + MPZ_SRCPTR_SWAP (u, v); + MP_SIZE_T_SWAP (un, vn); + } + if (vn == 0) + { + r->_mp_size = 0; + return; + } + + uc = u->_mp_size < 0; + vc = v->_mp_size < 0; + rc = uc & vc; + + ux = -uc; + vx = -vc; + rx = -rc; + + /* If the smaller input is positive, higher limbs don't matter. */ + rn = vx ? un : vn; + + rp = MPZ_REALLOC (r, rn + (mp_size_t) rc); + + up = u->_mp_d; + vp = v->_mp_d; + + i = 0; + do + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + vl = (vp[i] ^ vx) + vc; + vc = vl < vc; + + rl = ( (ul & vl) ^ rx) + rc; + rc = rl < rc; + rp[i] = rl; + } + while (++i < vn); + assert (vc == 0); + + for (; i < rn; i++) + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + rl = ( (ul & vx) ^ rx) + rc; + rc = rl < rc; + rp[i] = rl; + } + if (rc) + rp[rn++] = rc; + else + rn = mpn_normalized_size (rp, rn); + + r->_mp_size = rx ? -rn : rn; +} + +void +mpz_ior (mpz_t r, const mpz_t u, const mpz_t v) +{ + mp_size_t un, vn, rn, i; + mp_ptr up, vp, rp; + + mp_limb_t ux, vx, rx; + mp_limb_t uc, vc, rc; + mp_limb_t ul, vl, rl; + + un = GMP_ABS (u->_mp_size); + vn = GMP_ABS (v->_mp_size); + if (un < vn) + { + MPZ_SRCPTR_SWAP (u, v); + MP_SIZE_T_SWAP (un, vn); + } + if (vn == 0) + { + mpz_set (r, u); + return; + } + + uc = u->_mp_size < 0; + vc = v->_mp_size < 0; + rc = uc | vc; + + ux = -uc; + vx = -vc; + rx = -rc; + + /* If the smaller input is negative, by sign extension higher limbs + don't matter. */ + rn = vx ? vn : un; + + rp = MPZ_REALLOC (r, rn + (mp_size_t) rc); + + up = u->_mp_d; + vp = v->_mp_d; + + i = 0; + do + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + vl = (vp[i] ^ vx) + vc; + vc = vl < vc; + + rl = ( (ul | vl) ^ rx) + rc; + rc = rl < rc; + rp[i] = rl; + } + while (++i < vn); + assert (vc == 0); + + for (; i < rn; i++) + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + rl = ( (ul | vx) ^ rx) + rc; + rc = rl < rc; + rp[i] = rl; + } + if (rc) + rp[rn++] = rc; + else + rn = mpn_normalized_size (rp, rn); + + r->_mp_size = rx ? -rn : rn; +} + +void +mpz_xor (mpz_t r, const mpz_t u, const mpz_t v) +{ + mp_size_t un, vn, i; + mp_ptr up, vp, rp; + + mp_limb_t ux, vx, rx; + mp_limb_t uc, vc, rc; + mp_limb_t ul, vl, rl; + + un = GMP_ABS (u->_mp_size); + vn = GMP_ABS (v->_mp_size); + if (un < vn) + { + MPZ_SRCPTR_SWAP (u, v); + MP_SIZE_T_SWAP (un, vn); + } + if (vn == 0) + { + mpz_set (r, u); + return; + } + + uc = u->_mp_size < 0; + vc = v->_mp_size < 0; + rc = uc ^ vc; + + ux = -uc; + vx = -vc; + rx = -rc; + + rp = MPZ_REALLOC (r, un + (mp_size_t) rc); + + up = u->_mp_d; + vp = v->_mp_d; + + i = 0; + do + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + vl = (vp[i] ^ vx) + vc; + vc = vl < vc; + + rl = (ul ^ vl ^ rx) + rc; + rc = rl < rc; + rp[i] = rl; + } + while (++i < vn); + assert (vc == 0); + + for (; i < un; i++) + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + rl = (ul ^ ux) + rc; + rc = rl < rc; + rp[i] = rl; + } + if (rc) + rp[un++] = rc; + else + un = mpn_normalized_size (rp, un); + + r->_mp_size = rx ? -un : un; +} + +static unsigned +gmp_popcount_limb (mp_limb_t x) +{ + unsigned c; + + /* Do 16 bits at a time, to avoid limb-sized constants. */ + int LOCAL_SHIFT_BITS = 16; + for (c = 0; x > 0;) + { + unsigned w = x - ((x >> 1) & 0x5555); + w = ((w >> 2) & 0x3333) + (w & 0x3333); + w = (w >> 4) + w; + w = ((w >> 8) & 0x000f) + (w & 0x000f); + c += w; + if (GMP_LIMB_BITS > LOCAL_SHIFT_BITS) + x >>= LOCAL_SHIFT_BITS; + else + x = 0; + } + return c; +} + +mp_bitcnt_t +mpn_popcount (mp_srcptr p, mp_size_t n) +{ + mp_size_t i; + mp_bitcnt_t c; + + for (c = 0, i = 0; i < n; i++) + c += gmp_popcount_limb (p[i]); + + return c; +} + +mp_bitcnt_t +mpz_popcount (const mpz_t u) +{ + mp_size_t un; + + un = u->_mp_size; + + if (un < 0) + return ~(mp_bitcnt_t) 0; + + return mpn_popcount (u->_mp_d, un); +} + +mp_bitcnt_t +mpz_hamdist (const mpz_t u, const mpz_t v) +{ + mp_size_t un, vn, i; + mp_limb_t uc, vc, ul, vl, comp; + mp_srcptr up, vp; + mp_bitcnt_t c; + + un = u->_mp_size; + vn = v->_mp_size; + + if ( (un ^ vn) < 0) + return ~(mp_bitcnt_t) 0; + + comp = - (uc = vc = (un < 0)); + if (uc) + { + assert (vn < 0); + un = -un; + vn = -vn; + } + + up = u->_mp_d; + vp = v->_mp_d; + + if (un < vn) + MPN_SRCPTR_SWAP (up, un, vp, vn); + + for (i = 0, c = 0; i < vn; i++) + { + ul = (up[i] ^ comp) + uc; + uc = ul < uc; + + vl = (vp[i] ^ comp) + vc; + vc = vl < vc; + + c += gmp_popcount_limb (ul ^ vl); + } + assert (vc == 0); + + for (; i < un; i++) + { + ul = (up[i] ^ comp) + uc; + uc = ul < uc; + + c += gmp_popcount_limb (ul ^ comp); + } + + return c; +} + +mp_bitcnt_t +mpz_scan1 (const mpz_t u, mp_bitcnt_t starting_bit) +{ + mp_ptr up; + mp_size_t us, un, i; + mp_limb_t limb, ux; + + us = u->_mp_size; + un = GMP_ABS (us); + i = starting_bit / GMP_LIMB_BITS; + + /* Past the end there's no 1 bits for u>=0, or an immediate 1 bit + for u<0. Notice this test picks up any u==0 too. */ + if (i >= un) + return (us >= 0 ? ~(mp_bitcnt_t) 0 : starting_bit); + + up = u->_mp_d; + ux = 0; + limb = up[i]; + + if (starting_bit != 0) + { + if (us < 0) + { + ux = mpn_zero_p (up, i); + limb = ~ limb + ux; + ux = - (mp_limb_t) (limb >= ux); + } + + /* Mask to 0 all bits before starting_bit, thus ignoring them. */ + limb &= GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS); + } + + return mpn_common_scan (limb, i, up, un, ux); +} + +mp_bitcnt_t +mpz_scan0 (const mpz_t u, mp_bitcnt_t starting_bit) +{ + mp_ptr up; + mp_size_t us, un, i; + mp_limb_t limb, ux; + + us = u->_mp_size; + ux = - (mp_limb_t) (us >= 0); + un = GMP_ABS (us); + i = starting_bit / GMP_LIMB_BITS; + + /* When past end, there's an immediate 0 bit for u>=0, or no 0 bits for + u<0. Notice this test picks up all cases of u==0 too. */ + if (i >= un) + return (ux ? starting_bit : ~(mp_bitcnt_t) 0); + + up = u->_mp_d; + limb = up[i] ^ ux; + + if (ux == 0) + limb -= mpn_zero_p (up, i); /* limb = ~(~limb + zero_p) */ + + /* Mask all bits before starting_bit, thus ignoring them. */ + limb &= GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS); + + return mpn_common_scan (limb, i, up, un, ux); +} + + +/* MPZ base conversion. */ + +size_t +mpz_sizeinbase (const mpz_t u, int base) +{ + mp_size_t un; + mp_srcptr up; + mp_ptr tp; + mp_bitcnt_t bits; + struct gmp_div_inverse bi; + size_t ndigits; + + assert (base >= 2); + assert (base <= 62); + + un = GMP_ABS (u->_mp_size); + if (un == 0) + return 1; + + up = u->_mp_d; + + bits = (un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1]); + switch (base) + { + case 2: + return bits; + case 4: + return (bits + 1) / 2; + case 8: + return (bits + 2) / 3; + case 16: + return (bits + 3) / 4; + case 32: + return (bits + 4) / 5; + /* FIXME: Do something more clever for the common case of base + 10. */ + } + + tp = gmp_xalloc_limbs (un); + mpn_copyi (tp, up, un); + mpn_div_qr_1_invert (&bi, base); + + ndigits = 0; + do + { + ndigits++; + mpn_div_qr_1_preinv (tp, tp, un, &bi); + un -= (tp[un-1] == 0); + } + while (un > 0); + + gmp_free (tp); + return ndigits; +} + +char * +mpz_get_str (char *sp, int base, const mpz_t u) +{ + unsigned bits; + const char *digits; + mp_size_t un; + size_t i, sn; + + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + if (base > 1) + { + if (base <= 36) + digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + else if (base > 62) + return NULL; + } + else if (base >= -1) + base = 10; + else + { + base = -base; + if (base > 36) + return NULL; + } + + sn = 1 + mpz_sizeinbase (u, base); + if (!sp) + sp = (char *) gmp_xalloc (1 + sn); + + un = GMP_ABS (u->_mp_size); + + if (un == 0) + { + sp[0] = '0'; + sp[1] = '\0'; + return sp; + } + + i = 0; + + if (u->_mp_size < 0) + sp[i++] = '-'; + + bits = mpn_base_power_of_two_p (base); + + if (bits) + /* Not modified in this case. */ + sn = i + mpn_get_str_bits ((unsigned char *) sp + i, bits, u->_mp_d, un); + else + { + struct mpn_base_info info; + mp_ptr tp; + + mpn_get_base_info (&info, base); + tp = gmp_xalloc_limbs (un); + mpn_copyi (tp, u->_mp_d, un); + + sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un); + gmp_free (tp); + } + + for (; i < sn; i++) + sp[i] = digits[(unsigned char) sp[i]]; + + sp[sn] = '\0'; + return sp; +} + +int +mpz_set_str (mpz_t r, const char *sp, int base) +{ + unsigned bits, value_of_a; + mp_size_t rn, alloc; + mp_ptr rp; + size_t dn; + int sign; + unsigned char *dp; + + assert (base == 0 || (base >= 2 && base <= 62)); + + while (isspace( (unsigned char) *sp)) + sp++; + + sign = (*sp == '-'); + sp += sign; + + if (base == 0) + { + if (sp[0] == '0') + { + if (sp[1] == 'x' || sp[1] == 'X') + { + base = 16; + sp += 2; + } + else if (sp[1] == 'b' || sp[1] == 'B') + { + base = 2; + sp += 2; + } + else + base = 8; + } + else + base = 10; + } + + if (!*sp) + { + r->_mp_size = 0; + return -1; + } + dp = (unsigned char *) gmp_xalloc (strlen (sp)); + + value_of_a = (base > 36) ? 36 : 10; + for (dn = 0; *sp; sp++) + { + unsigned digit; + + if (isspace ((unsigned char) *sp)) + continue; + else if (*sp >= '0' && *sp <= '9') + digit = *sp - '0'; + else if (*sp >= 'a' && *sp <= 'z') + digit = *sp - 'a' + value_of_a; + else if (*sp >= 'A' && *sp <= 'Z') + digit = *sp - 'A' + 10; + else + digit = base; /* fail */ + + if (digit >= (unsigned) base) + { + gmp_free (dp); + r->_mp_size = 0; + return -1; + } + + dp[dn++] = digit; + } + + if (!dn) + { + gmp_free (dp); + r->_mp_size = 0; + return -1; + } + bits = mpn_base_power_of_two_p (base); + + if (bits > 0) + { + alloc = (dn * bits + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; + rp = MPZ_REALLOC (r, alloc); + rn = mpn_set_str_bits (rp, dp, dn, bits); + } + else + { + struct mpn_base_info info; + mpn_get_base_info (&info, base); + alloc = (dn + info.exp - 1) / info.exp; + rp = MPZ_REALLOC (r, alloc); + rn = mpn_set_str_other (rp, dp, dn, base, &info); + /* Normalization, needed for all-zero input. */ + assert (rn > 0); + rn -= rp[rn-1] == 0; + } + assert (rn <= alloc); + gmp_free (dp); + + r->_mp_size = sign ? - rn : rn; + + return 0; +} + +int +mpz_init_set_str (mpz_t r, const char *sp, int base) +{ + mpz_init (r); + return mpz_set_str (r, sp, base); +} + +size_t +mpz_out_str (FILE *stream, int base, const mpz_t x) +{ + char *str; + size_t len; + + str = mpz_get_str (NULL, base, x); + len = strlen (str); + len = fwrite (str, 1, len, stream); + gmp_free (str); + return len; +} + + +static int +gmp_detect_endian (void) +{ + static const int i = 2; + const unsigned char *p = (const unsigned char *) &i; + return 1 - *p; +} + +/* Import and export. Does not support nails. */ +void +mpz_import (mpz_t r, size_t count, int order, size_t size, int endian, + size_t nails, const void *src) +{ + const unsigned char *p; + ptrdiff_t word_step; + mp_ptr rp; + mp_size_t rn; + + /* The current (partial) limb. */ + mp_limb_t limb; + /* The number of bytes already copied to this limb (starting from + the low end). */ + size_t bytes; + /* The index where the limb should be stored, when completed. */ + mp_size_t i; + + if (nails != 0) + gmp_die ("mpz_import: Nails not supported."); + + assert (order == 1 || order == -1); + assert (endian >= -1 && endian <= 1); + + if (endian == 0) + endian = gmp_detect_endian (); + + p = (unsigned char *) src; + + word_step = (order != endian) ? 2 * size : 0; + + /* Process bytes from the least significant end, so point p at the + least significant word. */ + if (order == 1) + { + p += size * (count - 1); + word_step = - word_step; + } + + /* And at least significant byte of that word. */ + if (endian == 1) + p += (size - 1); + + rn = (size * count + sizeof(mp_limb_t) - 1) / sizeof(mp_limb_t); + rp = MPZ_REALLOC (r, rn); + + for (limb = 0, bytes = 0, i = 0; count > 0; count--, p += word_step) + { + size_t j; + for (j = 0; j < size; j++, p -= (ptrdiff_t) endian) + { + limb |= (mp_limb_t) *p << (bytes++ * CHAR_BIT); + if (bytes == sizeof(mp_limb_t)) + { + rp[i++] = limb; + bytes = 0; + limb = 0; + } + } + } + assert (i + (bytes > 0) == rn); + if (limb != 0) + rp[i++] = limb; + else + i = mpn_normalized_size (rp, i); + + r->_mp_size = i; +} + +void * +mpz_export (void *r, size_t *countp, int order, size_t size, int endian, + size_t nails, const mpz_t u) +{ + size_t count; + mp_size_t un; + + if (nails != 0) + gmp_die ("mpz_import: Nails not supported."); + + assert (order == 1 || order == -1); + assert (endian >= -1 && endian <= 1); + assert (size > 0 || u->_mp_size == 0); + + un = u->_mp_size; + count = 0; + if (un != 0) + { + size_t k; + unsigned char *p; + ptrdiff_t word_step; + /* The current (partial) limb. */ + mp_limb_t limb; + /* The number of bytes left to to in this limb. */ + size_t bytes; + /* The index where the limb was read. */ + mp_size_t i; + + un = GMP_ABS (un); + + /* Count bytes in top limb. */ + limb = u->_mp_d[un-1]; + assert (limb != 0); + + k = (GMP_LIMB_BITS <= CHAR_BIT); + if (!k) + { + do { + int LOCAL_CHAR_BIT = CHAR_BIT; + k++; limb >>= LOCAL_CHAR_BIT; + } while (limb != 0); + } + /* else limb = 0; */ + + count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size; + + if (!r) + r = gmp_xalloc (count * size); + + if (endian == 0) + endian = gmp_detect_endian (); + + p = (unsigned char *) r; + + word_step = (order != endian) ? 2 * size : 0; + + /* Process bytes from the least significant end, so point p at the + least significant word. */ + if (order == 1) + { + p += size * (count - 1); + word_step = - word_step; + } + + /* And at least significant byte of that word. */ + if (endian == 1) + p += (size - 1); + + for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step) + { + size_t j; + for (j = 0; j < size; ++j, p -= (ptrdiff_t) endian) + { + if (sizeof (mp_limb_t) == 1) + { + if (i < un) + *p = u->_mp_d[i++]; + else + *p = 0; + } + else + { + int LOCAL_CHAR_BIT = CHAR_BIT; + if (bytes == 0) + { + if (i < un) + limb = u->_mp_d[i++]; + bytes = sizeof (mp_limb_t); + } + *p = limb; + limb >>= LOCAL_CHAR_BIT; + bytes--; + } + } + } + assert (i == un); + assert (k == count); + } + + if (countp) + *countp = count; + + return r; +} diff --git a/lib/gmp/mini-gmp.h b/lib/gmp/mini-gmp.h new file mode 100644 index 0000000..45ec808 --- /dev/null +++ b/lib/gmp/mini-gmp.h @@ -0,0 +1,293 @@ +/* mini-gmp, a minimalistic implementation of a GNU GMP subset. + +Copyright 2011-2015, 2017, 2019 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library 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 3 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that 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 the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ + +/* About mini-gmp: This is a minimal implementation of a subset of the + GMP interface. It is intended for inclusion into applications which + have modest bignums needs, as a fallback when the real GMP library + is not installed. + + This file defines the public interface. */ + +#ifndef __MINI_GMP_H__ +#define __MINI_GMP_H__ + +/* For size_t */ +#include <stddef.h> + +#if defined (__cplusplus) +extern "C" { +#endif + +void mp_set_memory_functions (void *(*) (size_t), + void *(*) (void *, size_t, size_t), + void (*) (void *, size_t)); + +void mp_get_memory_functions (void *(**) (size_t), + void *(**) (void *, size_t, size_t), + void (**) (void *, size_t)); + +#ifndef MINI_GMP_LIMB_TYPE +#define MINI_GMP_LIMB_TYPE long +#endif + +typedef unsigned MINI_GMP_LIMB_TYPE mp_limb_t; +typedef long mp_size_t; +typedef unsigned long mp_bitcnt_t; + +typedef mp_limb_t *mp_ptr; +typedef const mp_limb_t *mp_srcptr; + +typedef struct +{ + int _mp_alloc; /* Number of *limbs* allocated and pointed + to by the _mp_d field. */ + int _mp_size; /* abs(_mp_size) is the number of limbs the + last field points to. If _mp_size is + negative this is a negative number. */ + mp_limb_t *_mp_d; /* Pointer to the limbs. */ +} __mpz_struct; + +typedef __mpz_struct mpz_t[1]; + +typedef __mpz_struct *mpz_ptr; +typedef const __mpz_struct *mpz_srcptr; + +extern const int mp_bits_per_limb; + +void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t); +void mpn_copyd (mp_ptr, mp_srcptr, mp_size_t); +void mpn_zero (mp_ptr, mp_size_t); + +int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t); +int mpn_zero_p (mp_srcptr, mp_size_t); + +mp_limb_t mpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); +mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); +mp_limb_t mpn_add (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); + +mp_limb_t mpn_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); +mp_limb_t mpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); +mp_limb_t mpn_sub (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); + +mp_limb_t mpn_mul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); +mp_limb_t mpn_addmul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); +mp_limb_t mpn_submul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); + +mp_limb_t mpn_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); +void mpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); +void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t); +int mpn_perfect_square_p (mp_srcptr, mp_size_t); +mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t); + +mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); +mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); + +mp_bitcnt_t mpn_scan0 (mp_srcptr, mp_bitcnt_t); +mp_bitcnt_t mpn_scan1 (mp_srcptr, mp_bitcnt_t); + +void mpn_com (mp_ptr, mp_srcptr, mp_size_t); +mp_limb_t mpn_neg (mp_ptr, mp_srcptr, mp_size_t); + +mp_bitcnt_t mpn_popcount (mp_srcptr, mp_size_t); + +mp_limb_t mpn_invert_3by2 (mp_limb_t, mp_limb_t); +#define mpn_invert_limb(x) mpn_invert_3by2 ((x), 0) + +size_t mpn_get_str (unsigned char *, int, mp_ptr, mp_size_t); +mp_size_t mpn_set_str (mp_ptr, const unsigned char *, size_t, int); + +void mpz_init (mpz_t); +void mpz_init2 (mpz_t, mp_bitcnt_t); +void mpz_clear (mpz_t); + +#define mpz_odd_p(z) (((z)->_mp_size != 0) & (int) (z)->_mp_d[0]) +#define mpz_even_p(z) (! mpz_odd_p (z)) + +int mpz_sgn (const mpz_t); +int mpz_cmp_si (const mpz_t, long); +int mpz_cmp_ui (const mpz_t, unsigned long); +int mpz_cmp (const mpz_t, const mpz_t); +int mpz_cmpabs_ui (const mpz_t, unsigned long); +int mpz_cmpabs (const mpz_t, const mpz_t); +int mpz_cmp_d (const mpz_t, double); +int mpz_cmpabs_d (const mpz_t, double); + +void mpz_abs (mpz_t, const mpz_t); +void mpz_neg (mpz_t, const mpz_t); +void mpz_swap (mpz_t, mpz_t); + +void mpz_add_ui (mpz_t, const mpz_t, unsigned long); +void mpz_add (mpz_t, const mpz_t, const mpz_t); +void mpz_sub_ui (mpz_t, const mpz_t, unsigned long); +void mpz_ui_sub (mpz_t, unsigned long, const mpz_t); +void mpz_sub (mpz_t, const mpz_t, const mpz_t); + +void mpz_mul_si (mpz_t, const mpz_t, long int); +void mpz_mul_ui (mpz_t, const mpz_t, unsigned long int); +void mpz_mul (mpz_t, const mpz_t, const mpz_t); +void mpz_mul_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_addmul_ui (mpz_t, const mpz_t, unsigned long int); +void mpz_addmul (mpz_t, const mpz_t, const mpz_t); +void mpz_submul_ui (mpz_t, const mpz_t, unsigned long int); +void mpz_submul (mpz_t, const mpz_t, const mpz_t); + +void mpz_cdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t); +void mpz_fdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t); +void mpz_tdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t); +void mpz_cdiv_q (mpz_t, const mpz_t, const mpz_t); +void mpz_fdiv_q (mpz_t, const mpz_t, const mpz_t); +void mpz_tdiv_q (mpz_t, const mpz_t, const mpz_t); +void mpz_cdiv_r (mpz_t, const mpz_t, const mpz_t); +void mpz_fdiv_r (mpz_t, const mpz_t, const mpz_t); +void mpz_tdiv_r (mpz_t, const mpz_t, const mpz_t); + +void mpz_cdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_fdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_tdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_cdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_fdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_tdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t); + +void mpz_mod (mpz_t, const mpz_t, const mpz_t); + +void mpz_divexact (mpz_t, const mpz_t, const mpz_t); + +int mpz_divisible_p (const mpz_t, const mpz_t); +int mpz_congruent_p (const mpz_t, const mpz_t, const mpz_t); + +unsigned long mpz_cdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); +unsigned long mpz_fdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); +unsigned long mpz_tdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); +unsigned long mpz_cdiv_q_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_fdiv_q_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_tdiv_q_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_cdiv_r_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_fdiv_r_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_tdiv_r_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_cdiv_ui (const mpz_t, unsigned long); +unsigned long mpz_fdiv_ui (const mpz_t, unsigned long); +unsigned long mpz_tdiv_ui (const mpz_t, unsigned long); + +unsigned long mpz_mod_ui (mpz_t, const mpz_t, unsigned long); + +void mpz_divexact_ui (mpz_t, const mpz_t, unsigned long); + +int mpz_divisible_ui_p (const mpz_t, unsigned long); + +unsigned long mpz_gcd_ui (mpz_t, const mpz_t, unsigned long); +void mpz_gcd (mpz_t, const mpz_t, const mpz_t); +void mpz_gcdext (mpz_t, mpz_t, mpz_t, const mpz_t, const mpz_t); +void mpz_lcm_ui (mpz_t, const mpz_t, unsigned long); +void mpz_lcm (mpz_t, const mpz_t, const mpz_t); +int mpz_invert (mpz_t, const mpz_t, const mpz_t); + +void mpz_sqrtrem (mpz_t, mpz_t, const mpz_t); +void mpz_sqrt (mpz_t, const mpz_t); +int mpz_perfect_square_p (const mpz_t); + +void mpz_pow_ui (mpz_t, const mpz_t, unsigned long); +void mpz_ui_pow_ui (mpz_t, unsigned long, unsigned long); +void mpz_powm (mpz_t, const mpz_t, const mpz_t, const mpz_t); +void mpz_powm_ui (mpz_t, const mpz_t, unsigned long, const mpz_t); + +void mpz_rootrem (mpz_t, mpz_t, const mpz_t, unsigned long); +int mpz_root (mpz_t, const mpz_t, unsigned long); + +void mpz_fac_ui (mpz_t, unsigned long); +void mpz_2fac_ui (mpz_t, unsigned long); +void mpz_mfac_uiui (mpz_t, unsigned long, unsigned long); +void mpz_bin_uiui (mpz_t, unsigned long, unsigned long); + +int mpz_probab_prime_p (const mpz_t, int); + +int mpz_tstbit (const mpz_t, mp_bitcnt_t); +void mpz_setbit (mpz_t, mp_bitcnt_t); +void mpz_clrbit (mpz_t, mp_bitcnt_t); +void mpz_combit (mpz_t, mp_bitcnt_t); + +void mpz_com (mpz_t, const mpz_t); +void mpz_and (mpz_t, const mpz_t, const mpz_t); +void mpz_ior (mpz_t, const mpz_t, const mpz_t); +void mpz_xor (mpz_t, const mpz_t, const mpz_t); + +mp_bitcnt_t mpz_popcount (const mpz_t); +mp_bitcnt_t mpz_hamdist (const mpz_t, const mpz_t); +mp_bitcnt_t mpz_scan0 (const mpz_t, mp_bitcnt_t); +mp_bitcnt_t mpz_scan1 (const mpz_t, mp_bitcnt_t); + +int mpz_fits_slong_p (const mpz_t); +int mpz_fits_ulong_p (const mpz_t); +long int mpz_get_si (const mpz_t); +unsigned long int mpz_get_ui (const mpz_t); +double mpz_get_d (const mpz_t); +size_t mpz_size (const mpz_t); +mp_limb_t mpz_getlimbn (const mpz_t, mp_size_t); + +void mpz_realloc2 (mpz_t, mp_bitcnt_t); +mp_srcptr mpz_limbs_read (mpz_srcptr); +mp_ptr mpz_limbs_modify (mpz_t, mp_size_t); +mp_ptr mpz_limbs_write (mpz_t, mp_size_t); +void mpz_limbs_finish (mpz_t, mp_size_t); +mpz_srcptr mpz_roinit_n (mpz_t, mp_srcptr, mp_size_t); + +#define MPZ_ROINIT_N(xp, xs) {{0, (xs),(xp) }} + +void mpz_set_si (mpz_t, signed long int); +void mpz_set_ui (mpz_t, unsigned long int); +void mpz_set (mpz_t, const mpz_t); +void mpz_set_d (mpz_t, double); + +void mpz_init_set_si (mpz_t, signed long int); +void mpz_init_set_ui (mpz_t, unsigned long int); +void mpz_init_set (mpz_t, const mpz_t); +void mpz_init_set_d (mpz_t, double); + +size_t mpz_sizeinbase (const mpz_t, int); +char *mpz_get_str (char *, int, const mpz_t); +int mpz_set_str (mpz_t, const char *, int); +int mpz_init_set_str (mpz_t, const char *, int); + +/* This long list taken from gmp.h. */ +/* For reference, "defined(EOF)" cannot be used here. In g++ 2.95.4, + <iostream> defines EOF but not FILE. */ +#if defined (FILE) \ + || defined (H_STDIO) \ + || defined (_H_STDIO) /* AIX */ \ + || defined (_STDIO_H) /* glibc, Sun, SCO */ \ + || defined (_STDIO_H_) /* BSD, OSF */ \ + || defined (__STDIO_H) /* Borland */ \ + || defined (__STDIO_H__) /* IRIX */ \ + || defined (_STDIO_INCLUDED) /* HPUX */ \ + || defined (__dj_include_stdio_h_) /* DJGPP */ \ + || defined (_FILE_DEFINED) /* Microsoft */ \ + || defined (__STDIO__) /* Apple MPW MrC */ \ + || defined (_MSL_STDIO_H) /* Metrowerks */ \ + || defined (_STDIO_H_INCLUDED) /* QNX4 */ \ + || defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \ + || defined (__STDIO_LOADED) /* VMS */ +size_t mpz_out_str (FILE *, int, const mpz_t); +#endif + +void mpz_import (mpz_t, size_t, int, size_t, int, size_t, const void *); +void *mpz_export (void *, size_t *, int, size_t, int, size_t, const mpz_t); + +#if defined (__cplusplus) +} +#endif +#endif /* __MINI_GMP_H__ */ diff --git a/lib/jsoncpp/CMakeLists.txt b/lib/jsoncpp/CMakeLists.txt new file mode 100644 index 0000000..cdd1a7e --- /dev/null +++ b/lib/jsoncpp/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(jsoncpp STATIC jsoncpp.cpp) +target_link_libraries(jsoncpp) + diff --git a/lib/jsoncpp/json/UPDATING b/lib/jsoncpp/json/UPDATING new file mode 100644 index 0000000..0893244 --- /dev/null +++ b/lib/jsoncpp/json/UPDATING @@ -0,0 +1,7 @@ +#!/bin/sh +cd .. +git clone https://github.com/open-source-parsers/jsoncpp -b 1.9.4 --depth 1 +cd jsoncpp +python amalgamate.py +cp -R dist/json ../json +cp dist/jsoncpp.cpp .. diff --git a/lib/jsoncpp/json/json-forwards.h b/lib/jsoncpp/json/json-forwards.h new file mode 100644 index 0000000..d3260c5 --- /dev/null +++ b/lib/jsoncpp/json/json-forwards.h @@ -0,0 +1,447 @@ +/// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/). +/// It is intended to be used with #include "json/json-forwards.h" +/// This header provides forward declaration for all JsonCpp types. + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + +/* +The JsonCpp library's source code, including accompanying documentation, +tests and demonstration applications, are licensed under the following +conditions... + +Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, +this software is released into the Public Domain. + +In jurisdictions which do not recognize Public Domain property (e.g. Germany as of +2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and +The JsonCpp Authors, and is released under the terms of the MIT License (see below). + +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual +Public Domain/MIT License conditions described here, as they choose. + +The MIT License is about as close to Public Domain as a license can get, and is +described in clear, concise terms at: + + http://en.wikipedia.org/wiki/MIT_License + +The full text of the MIT License follows: + +======================================================================== +Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors + +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. +======================================================================== +(END LICENSE TEXT) + +The MIT license is compatible with both the GPL and commercial +software, affording one all of the rights of Public Domain with the +minor nuisance of being required to keep the above copyright notice +and license text in the source code. Note also that by accepting the +Public Domain "license" you can re-license your copy using whatever +license you like. + +*/ + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + + + + + +#ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED +# define JSON_FORWARD_AMALGAMATED_H_INCLUDED +/// If defined, indicates that the source file is amalgamated +/// to prevent private header inclusion. +#define JSON_IS_AMALGAMATION + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/version.h +// ////////////////////////////////////////////////////////////////////// + +#ifndef JSON_VERSION_H_INCLUDED +#define JSON_VERSION_H_INCLUDED + +// Note: version must be updated in three places when doing a release. This +// annoying process ensures that amalgamate, CMake, and meson all report the +// correct version. +// 1. /meson.build +// 2. /include/json/version.h +// 3. /CMakeLists.txt +// IMPORTANT: also update the SOVERSION!! + +#define JSONCPP_VERSION_STRING "1.9.4" +#define JSONCPP_VERSION_MAJOR 1 +#define JSONCPP_VERSION_MINOR 9 +#define JSONCPP_VERSION_PATCH 3 +#define JSONCPP_VERSION_QUALIFIER +#define JSONCPP_VERSION_HEXA \ + ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ + (JSONCPP_VERSION_PATCH << 8)) + +#ifdef JSONCPP_USING_SECURE_MEMORY +#undef JSONCPP_USING_SECURE_MEMORY +#endif +#define JSONCPP_USING_SECURE_MEMORY 0 +// If non-zero, the library zeroes any memory that it has allocated before +// it frees its memory. + +#endif // JSON_VERSION_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/version.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/allocator.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_ALLOCATOR_H_INCLUDED +#define JSON_ALLOCATOR_H_INCLUDED + +#include <cstring> +#include <memory> + +#pragma pack(push, 8) + +namespace Json { +template <typename T> class SecureAllocator { +public: + // Type definitions + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + /** + * Allocate memory for N items using the standard allocator. + */ + pointer allocate(size_type n) { + // allocate using "global operator new" + return static_cast<pointer>(::operator new(n * sizeof(T))); + } + + /** + * Release memory which was allocated for N items at pointer P. + * + * The memory block is filled with zeroes before being released. + * The pointer argument is tagged as "volatile" to prevent the + * compiler optimizing out this critical step. + */ + void deallocate(volatile pointer p, size_type n) { + std::memset(p, 0, n * sizeof(T)); + // free using "global operator delete" + ::operator delete(p); + } + + /** + * Construct an item in-place at pointer P. + */ + template <typename... Args> void construct(pointer p, Args&&... args) { + // construct using "placement new" and "perfect forwarding" + ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...); + } + + size_type max_size() const { return size_t(-1) / sizeof(T); } + + pointer address(reference x) const { return std::addressof(x); } + + const_pointer address(const_reference x) const { return std::addressof(x); } + + /** + * Destroy an item in-place at pointer P. + */ + void destroy(pointer p) { + // destroy using "explicit destructor" + p->~T(); + } + + // Boilerplate + SecureAllocator() {} + template <typename U> SecureAllocator(const SecureAllocator<U>&) {} + template <typename U> struct rebind { using other = SecureAllocator<U>; }; +}; + +template <typename T, typename U> +bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) { + return true; +} + +template <typename T, typename U> +bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) { + return false; +} + +} // namespace Json + +#pragma pack(pop) + +#endif // JSON_ALLOCATOR_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/allocator.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_CONFIG_H_INCLUDED +#define JSON_CONFIG_H_INCLUDED +#include <cstddef> +#include <cstdint> +#include <istream> +#include <memory> +#include <ostream> +#include <sstream> +#include <string> +#include <type_traits> + +// If non-zero, the library uses exceptions to report bad input instead of C +// assertion macros. The default is to use exceptions. +#ifndef JSON_USE_EXCEPTION +#define JSON_USE_EXCEPTION 1 +#endif + +// Temporary, tracked for removal with issue #982. +#ifndef JSON_USE_NULLREF +#define JSON_USE_NULLREF 1 +#endif + +/// If defined, indicates that the source file is amalgamated +/// to prevent private header inclusion. +/// Remarks: it is automatically defined in the generated amalgamated header. +// #define JSON_IS_AMALGAMATION + +// Export macros for DLL visibility +#if defined(JSON_DLL_BUILD) +#if defined(_MSC_VER) || defined(__MINGW32__) +#define JSON_API __declspec(dllexport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#elif defined(__GNUC__) || defined(__clang__) +#define JSON_API __attribute__((visibility("default"))) +#endif // if defined(_MSC_VER) + +#elif defined(JSON_DLL) +#if defined(_MSC_VER) || defined(__MINGW32__) +#define JSON_API __declspec(dllimport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#endif // if defined(_MSC_VER) +#endif // ifdef JSON_DLL_BUILD + +#if !defined(JSON_API) +#define JSON_API +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1800 +#error \ + "ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities" +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +// As recommended at +// https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 +extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size, + const char* format, ...); +#define jsoncpp_snprintf msvc_pre1900_c99_snprintf +#else +#define jsoncpp_snprintf std::snprintf +#endif + +// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for +// integer +// Storages, and 64 bits integer support is disabled. +// #define JSON_NO_INT64 1 + +// JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools. +// C++11 should be used directly in JSONCPP. +#define JSONCPP_OVERRIDE override + +#ifdef __clang__ +#if __has_extension(attribute_deprecated_with_message) +#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) +#endif +#elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc) +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) +#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) +#endif // GNUC version +#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates + // MSVC) +#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) +#endif // __clang__ || __GNUC__ || _MSC_VER + +#if !defined(JSONCPP_DEPRECATED) +#define JSONCPP_DEPRECATED(message) +#endif // if !defined(JSONCPP_DEPRECATED) + +#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6)) +#define JSON_USE_INT64_DOUBLE_CONVERSION 1 +#endif + +#if !defined(JSON_IS_AMALGAMATION) + +#include "allocator.h" +#include "version.h" + +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { +using Int = int; +using UInt = unsigned int; +#if defined(JSON_NO_INT64) +using LargestInt = int; +using LargestUInt = unsigned int; +#undef JSON_HAS_INT64 +#else // if defined(JSON_NO_INT64) +// For Microsoft Visual use specific types as long long is not supported +#if defined(_MSC_VER) // Microsoft Visual Studio +using Int64 = __int64; +using UInt64 = unsigned __int64; +#else // if defined(_MSC_VER) // Other platforms, use long long +using Int64 = int64_t; +using UInt64 = uint64_t; +#endif // if defined(_MSC_VER) +using LargestInt = Int64; +using LargestUInt = UInt64; +#define JSON_HAS_INT64 +#endif // if defined(JSON_NO_INT64) + +template <typename T> +using Allocator = + typename std::conditional<JSONCPP_USING_SECURE_MEMORY, SecureAllocator<T>, + std::allocator<T>>::type; +using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>; +using IStringStream = + std::basic_istringstream<String::value_type, String::traits_type, + String::allocator_type>; +using OStringStream = + std::basic_ostringstream<String::value_type, String::traits_type, + String::allocator_type>; +using IStream = std::istream; +using OStream = std::ostream; +} // namespace Json + +// Legacy names (formerly macros). +using JSONCPP_STRING = Json::String; +using JSONCPP_ISTRINGSTREAM = Json::IStringStream; +using JSONCPP_OSTRINGSTREAM = Json::OStringStream; +using JSONCPP_ISTREAM = Json::IStream; +using JSONCPP_OSTREAM = Json::OStream; + +#endif // JSON_CONFIG_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_FORWARDS_H_INCLUDED +#define JSON_FORWARDS_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "config.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +// writer.h +class StreamWriter; +class StreamWriterBuilder; +class Writer; +class FastWriter; +class StyledWriter; +class StyledStreamWriter; + +// reader.h +class Reader; +class CharReader; +class CharReaderBuilder; + +// json_features.h +class Features; + +// value.h +using ArrayIndex = unsigned int; +class StaticString; +class Path; +class PathArgument; +class Value; +class ValueIteratorBase; +class ValueIterator; +class ValueConstIterator; + +} // namespace Json + +#endif // JSON_FORWARDS_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + + + + + +#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED diff --git a/lib/jsoncpp/json/json.h b/lib/jsoncpp/json/json.h new file mode 100644 index 0000000..3f4813a --- /dev/null +++ b/lib/jsoncpp/json/json.h @@ -0,0 +1,2343 @@ +/// Json-cpp amalgamated header (http://jsoncpp.sourceforge.net/). +/// It is intended to be used with #include "json/json.h" + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + +/* +The JsonCpp library's source code, including accompanying documentation, +tests and demonstration applications, are licensed under the following +conditions... + +Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, +this software is released into the Public Domain. + +In jurisdictions which do not recognize Public Domain property (e.g. Germany as of +2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and +The JsonCpp Authors, and is released under the terms of the MIT License (see below). + +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual +Public Domain/MIT License conditions described here, as they choose. + +The MIT License is about as close to Public Domain as a license can get, and is +described in clear, concise terms at: + + http://en.wikipedia.org/wiki/MIT_License + +The full text of the MIT License follows: + +======================================================================== +Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors + +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. +======================================================================== +(END LICENSE TEXT) + +The MIT license is compatible with both the GPL and commercial +software, affording one all of the rights of Public Domain with the +minor nuisance of being required to keep the above copyright notice +and license text in the source code. Note also that by accepting the +Public Domain "license" you can re-license your copy using whatever +license you like. + +*/ + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + + + + + +#ifndef JSON_AMALGAMATED_H_INCLUDED +# define JSON_AMALGAMATED_H_INCLUDED +/// If defined, indicates that the source file is amalgamated +/// to prevent private header inclusion. +#define JSON_IS_AMALGAMATION + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/version.h +// ////////////////////////////////////////////////////////////////////// + +#ifndef JSON_VERSION_H_INCLUDED +#define JSON_VERSION_H_INCLUDED + +// Note: version must be updated in three places when doing a release. This +// annoying process ensures that amalgamate, CMake, and meson all report the +// correct version. +// 1. /meson.build +// 2. /include/json/version.h +// 3. /CMakeLists.txt +// IMPORTANT: also update the SOVERSION!! + +#define JSONCPP_VERSION_STRING "1.9.4" +#define JSONCPP_VERSION_MAJOR 1 +#define JSONCPP_VERSION_MINOR 9 +#define JSONCPP_VERSION_PATCH 3 +#define JSONCPP_VERSION_QUALIFIER +#define JSONCPP_VERSION_HEXA \ + ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ + (JSONCPP_VERSION_PATCH << 8)) + +#ifdef JSONCPP_USING_SECURE_MEMORY +#undef JSONCPP_USING_SECURE_MEMORY +#endif +#define JSONCPP_USING_SECURE_MEMORY 0 +// If non-zero, the library zeroes any memory that it has allocated before +// it frees its memory. + +#endif // JSON_VERSION_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/version.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/allocator.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_ALLOCATOR_H_INCLUDED +#define JSON_ALLOCATOR_H_INCLUDED + +#include <cstring> +#include <memory> + +#pragma pack(push, 8) + +namespace Json { +template <typename T> class SecureAllocator { +public: + // Type definitions + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + /** + * Allocate memory for N items using the standard allocator. + */ + pointer allocate(size_type n) { + // allocate using "global operator new" + return static_cast<pointer>(::operator new(n * sizeof(T))); + } + + /** + * Release memory which was allocated for N items at pointer P. + * + * The memory block is filled with zeroes before being released. + * The pointer argument is tagged as "volatile" to prevent the + * compiler optimizing out this critical step. + */ + void deallocate(volatile pointer p, size_type n) { + std::memset(p, 0, n * sizeof(T)); + // free using "global operator delete" + ::operator delete(p); + } + + /** + * Construct an item in-place at pointer P. + */ + template <typename... Args> void construct(pointer p, Args&&... args) { + // construct using "placement new" and "perfect forwarding" + ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...); + } + + size_type max_size() const { return size_t(-1) / sizeof(T); } + + pointer address(reference x) const { return std::addressof(x); } + + const_pointer address(const_reference x) const { return std::addressof(x); } + + /** + * Destroy an item in-place at pointer P. + */ + void destroy(pointer p) { + // destroy using "explicit destructor" + p->~T(); + } + + // Boilerplate + SecureAllocator() {} + template <typename U> SecureAllocator(const SecureAllocator<U>&) {} + template <typename U> struct rebind { using other = SecureAllocator<U>; }; +}; + +template <typename T, typename U> +bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) { + return true; +} + +template <typename T, typename U> +bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) { + return false; +} + +} // namespace Json + +#pragma pack(pop) + +#endif // JSON_ALLOCATOR_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/allocator.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_CONFIG_H_INCLUDED +#define JSON_CONFIG_H_INCLUDED +#include <cstddef> +#include <cstdint> +#include <istream> +#include <memory> +#include <ostream> +#include <sstream> +#include <string> +#include <type_traits> + +// If non-zero, the library uses exceptions to report bad input instead of C +// assertion macros. The default is to use exceptions. +#ifndef JSON_USE_EXCEPTION +#define JSON_USE_EXCEPTION 1 +#endif + +// Temporary, tracked for removal with issue #982. +#ifndef JSON_USE_NULLREF +#define JSON_USE_NULLREF 1 +#endif + +/// If defined, indicates that the source file is amalgamated +/// to prevent private header inclusion. +/// Remarks: it is automatically defined in the generated amalgamated header. +// #define JSON_IS_AMALGAMATION + +// Export macros for DLL visibility +#if defined(JSON_DLL_BUILD) +#if defined(_MSC_VER) || defined(__MINGW32__) +#define JSON_API __declspec(dllexport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#elif defined(__GNUC__) || defined(__clang__) +#define JSON_API __attribute__((visibility("default"))) +#endif // if defined(_MSC_VER) + +#elif defined(JSON_DLL) +#if defined(_MSC_VER) || defined(__MINGW32__) +#define JSON_API __declspec(dllimport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#endif // if defined(_MSC_VER) +#endif // ifdef JSON_DLL_BUILD + +#if !defined(JSON_API) +#define JSON_API +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1800 +#error \ + "ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities" +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +// As recommended at +// https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 +extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size, + const char* format, ...); +#define jsoncpp_snprintf msvc_pre1900_c99_snprintf +#else +#define jsoncpp_snprintf std::snprintf +#endif + +// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for +// integer +// Storages, and 64 bits integer support is disabled. +// #define JSON_NO_INT64 1 + +// JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools. +// C++11 should be used directly in JSONCPP. +#define JSONCPP_OVERRIDE override + +#ifdef __clang__ +#if __has_extension(attribute_deprecated_with_message) +#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) +#endif +#elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc) +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) +#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) +#endif // GNUC version +#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates + // MSVC) +#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) +#endif // __clang__ || __GNUC__ || _MSC_VER + +#if !defined(JSONCPP_DEPRECATED) +#define JSONCPP_DEPRECATED(message) +#endif // if !defined(JSONCPP_DEPRECATED) + +#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6)) +#define JSON_USE_INT64_DOUBLE_CONVERSION 1 +#endif + +#if !defined(JSON_IS_AMALGAMATION) + +#include "allocator.h" +#include "version.h" + +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { +using Int = int; +using UInt = unsigned int; +#if defined(JSON_NO_INT64) +using LargestInt = int; +using LargestUInt = unsigned int; +#undef JSON_HAS_INT64 +#else // if defined(JSON_NO_INT64) +// For Microsoft Visual use specific types as long long is not supported +#if defined(_MSC_VER) // Microsoft Visual Studio +using Int64 = __int64; +using UInt64 = unsigned __int64; +#else // if defined(_MSC_VER) // Other platforms, use long long +using Int64 = int64_t; +using UInt64 = uint64_t; +#endif // if defined(_MSC_VER) +using LargestInt = Int64; +using LargestUInt = UInt64; +#define JSON_HAS_INT64 +#endif // if defined(JSON_NO_INT64) + +template <typename T> +using Allocator = + typename std::conditional<JSONCPP_USING_SECURE_MEMORY, SecureAllocator<T>, + std::allocator<T>>::type; +using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>; +using IStringStream = + std::basic_istringstream<String::value_type, String::traits_type, + String::allocator_type>; +using OStringStream = + std::basic_ostringstream<String::value_type, String::traits_type, + String::allocator_type>; +using IStream = std::istream; +using OStream = std::ostream; +} // namespace Json + +// Legacy names (formerly macros). +using JSONCPP_STRING = Json::String; +using JSONCPP_ISTRINGSTREAM = Json::IStringStream; +using JSONCPP_OSTRINGSTREAM = Json::OStringStream; +using JSONCPP_ISTREAM = Json::IStream; +using JSONCPP_OSTREAM = Json::OStream; + +#endif // JSON_CONFIG_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_FORWARDS_H_INCLUDED +#define JSON_FORWARDS_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "config.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +// writer.h +class StreamWriter; +class StreamWriterBuilder; +class Writer; +class FastWriter; +class StyledWriter; +class StyledStreamWriter; + +// reader.h +class Reader; +class CharReader; +class CharReaderBuilder; + +// json_features.h +class Features; + +// value.h +using ArrayIndex = unsigned int; +class StaticString; +class Path; +class PathArgument; +class Value; +class ValueIteratorBase; +class ValueIterator; +class ValueConstIterator; + +} // namespace Json + +#endif // JSON_FORWARDS_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/json_features.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_FEATURES_H_INCLUDED +#define JSON_FEATURES_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "forwards.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +#pragma pack(push, 8) + +namespace Json { + +/** \brief Configuration passed to reader and writer. + * This configuration object can be used to force the Reader or Writer + * to behave in a standard conforming way. + */ +class JSON_API Features { +public: + /** \brief A configuration that allows all features and assumes all strings + * are UTF-8. + * - C & C++ comments are allowed + * - Root object can be any JSON value + * - Assumes Value strings are encoded in UTF-8 + */ + static Features all(); + + /** \brief A configuration that is strictly compatible with the JSON + * specification. + * - Comments are forbidden. + * - Root object must be either an array or an object value. + * - Assumes Value strings are encoded in UTF-8 + */ + static Features strictMode(); + + /** \brief Initialize the configuration like JsonConfig::allFeatures; + */ + Features(); + + /// \c true if comments are allowed. Default: \c true. + bool allowComments_{true}; + + /// \c true if root must be either an array or an object value. Default: \c + /// false. + bool strictRoot_{false}; + + /// \c true if dropped null placeholders are allowed. Default: \c false. + bool allowDroppedNullPlaceholders_{false}; + + /// \c true if numeric object key are allowed. Default: \c false. + bool allowNumericKeys_{false}; +}; + +} // namespace Json + +#pragma pack(pop) + +#endif // JSON_FEATURES_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/json_features.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/value.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_H_INCLUDED +#define JSON_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "forwards.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +// Conditional NORETURN attribute on the throw functions would: +// a) suppress false positives from static code analysis +// b) possibly improve optimization opportunities. +#if !defined(JSONCPP_NORETURN) +#if defined(_MSC_VER) && _MSC_VER == 1800 +#define JSONCPP_NORETURN __declspec(noreturn) +#else +#define JSONCPP_NORETURN [[noreturn]] +#endif +#endif + +// Support for '= delete' with template declarations was a late addition +// to the c++11 standard and is rejected by clang 3.8 and Apple clang 8.2 +// even though these declare themselves to be c++11 compilers. +#if !defined(JSONCPP_TEMPLATE_DELETE) +#if defined(__clang__) && defined(__apple_build_version__) +#if __apple_build_version__ <= 8000042 +#define JSONCPP_TEMPLATE_DELETE +#endif +#elif defined(__clang__) +#if __clang_major__ == 3 && __clang_minor__ <= 8 +#define JSONCPP_TEMPLATE_DELETE +#endif +#endif +#if !defined(JSONCPP_TEMPLATE_DELETE) +#define JSONCPP_TEMPLATE_DELETE = delete +#endif +#endif + +#include <array> +#include <exception> +#include <map> +#include <memory> +#include <string> +#include <vector> + +// Disable warning C4251: <data member>: <type> needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#pragma pack(push, 8) + +/** \brief JSON (JavaScript Object Notation). + */ +namespace Json { + +#if JSON_USE_EXCEPTION +/** Base class for all exceptions we throw. + * + * We use nothing but these internally. Of course, STL can throw others. + */ +class JSON_API Exception : public std::exception { +public: + Exception(String msg); + ~Exception() noexcept override; + char const* what() const noexcept override; + +protected: + String msg_; +}; + +/** Exceptions which the user cannot easily avoid. + * + * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input + * + * \remark derived from Json::Exception + */ +class JSON_API RuntimeError : public Exception { +public: + RuntimeError(String const& msg); +}; + +/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros. + * + * These are precondition-violations (user bugs) and internal errors (our bugs). + * + * \remark derived from Json::Exception + */ +class JSON_API LogicError : public Exception { +public: + LogicError(String const& msg); +}; +#endif + +/// used internally +JSONCPP_NORETURN void throwRuntimeError(String const& msg); +/// used internally +JSONCPP_NORETURN void throwLogicError(String const& msg); + +/** \brief Type of the value held by a Value object. + */ +enum ValueType { + nullValue = 0, ///< 'null' value + intValue, ///< signed integer value + uintValue, ///< unsigned integer value + realValue, ///< double value + stringValue, ///< UTF-8 string value + booleanValue, ///< bool value + arrayValue, ///< array value (ordered list) + objectValue ///< object value (collection of name/value pairs). +}; + +enum CommentPlacement { + commentBefore = 0, ///< a comment placed on the line before a value + commentAfterOnSameLine, ///< a comment just after a value on the same line + commentAfter, ///< a comment on the line after a value (only make sense for + /// root value) + numberOfCommentPlacement +}; + +/** \brief Type of precision for formatting of real values. + */ +enum PrecisionType { + significantDigits = 0, ///< we set max number of significant digits in string + decimalPlaces ///< we set max number of digits after "." in string +}; + +/** \brief Lightweight wrapper to tag static string. + * + * Value constructor and objectValue member assignment takes advantage of the + * StaticString and avoid the cost of string duplication when storing the + * string or the member name. + * + * Example of usage: + * \code + * Json::Value aValue( StaticString("some text") ); + * Json::Value object; + * static const StaticString code("code"); + * object[code] = 1234; + * \endcode + */ +class JSON_API StaticString { +public: + explicit StaticString(const char* czstring) : c_str_(czstring) {} + + operator const char*() const { return c_str_; } + + const char* c_str() const { return c_str_; } + +private: + const char* c_str_; +}; + +/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value. + * + * This class is a discriminated union wrapper that can represents a: + * - signed integer [range: Value::minInt - Value::maxInt] + * - unsigned integer (range: 0 - Value::maxUInt) + * - double + * - UTF-8 string + * - boolean + * - 'null' + * - an ordered list of Value + * - collection of name/value pairs (javascript object) + * + * The type of the held value is represented by a #ValueType and + * can be obtained using type(). + * + * Values of an #objectValue or #arrayValue can be accessed using operator[]() + * methods. + * Non-const methods will automatically create the a #nullValue element + * if it does not exist. + * The sequence of an #arrayValue will be automatically resized and initialized + * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. + * + * The get() methods can be used to obtain default value in the case the + * required element does not exist. + * + * It is possible to iterate over the list of member keys of an object using + * the getMemberNames() method. + * + * \note #Value string-length fit in size_t, but keys must be < 2^30. + * (The reason is an implementation detail.) A #CharReader will raise an + * exception if a bound is exceeded to avoid security holes in your app, + * but the Value API does *not* check bounds. That is the responsibility + * of the caller. + */ +class JSON_API Value { + friend class ValueIteratorBase; + +public: + using Members = std::vector<String>; + using iterator = ValueIterator; + using const_iterator = ValueConstIterator; + using UInt = Json::UInt; + using Int = Json::Int; +#if defined(JSON_HAS_INT64) + using UInt64 = Json::UInt64; + using Int64 = Json::Int64; +#endif // defined(JSON_HAS_INT64) + using LargestInt = Json::LargestInt; + using LargestUInt = Json::LargestUInt; + using ArrayIndex = Json::ArrayIndex; + + // Required for boost integration, e. g. BOOST_TEST + using value_type = std::string; + +#if JSON_USE_NULLREF + // Binary compatibility kludges, do not use. + static const Value& null; + static const Value& nullRef; +#endif + + // null and nullRef are deprecated, use this instead. + static Value const& nullSingleton(); + + /// Minimum signed integer value that can be stored in a Json::Value. + static constexpr LargestInt minLargestInt = + LargestInt(~(LargestUInt(-1) / 2)); + /// Maximum signed integer value that can be stored in a Json::Value. + static constexpr LargestInt maxLargestInt = LargestInt(LargestUInt(-1) / 2); + /// Maximum unsigned integer value that can be stored in a Json::Value. + static constexpr LargestUInt maxLargestUInt = LargestUInt(-1); + + /// Minimum signed int value that can be stored in a Json::Value. + static constexpr Int minInt = Int(~(UInt(-1) / 2)); + /// Maximum signed int value that can be stored in a Json::Value. + static constexpr Int maxInt = Int(UInt(-1) / 2); + /// Maximum unsigned int value that can be stored in a Json::Value. + static constexpr UInt maxUInt = UInt(-1); + +#if defined(JSON_HAS_INT64) + /// Minimum signed 64 bits int value that can be stored in a Json::Value. + static constexpr Int64 minInt64 = Int64(~(UInt64(-1) / 2)); + /// Maximum signed 64 bits int value that can be stored in a Json::Value. + static constexpr Int64 maxInt64 = Int64(UInt64(-1) / 2); + /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. + static constexpr UInt64 maxUInt64 = UInt64(-1); +#endif // defined(JSON_HAS_INT64) + /// Default precision for real value for string representation. + static constexpr UInt defaultRealPrecision = 17; + // The constant is hard-coded because some compiler have trouble + // converting Value::maxUInt64 to a double correctly (AIX/xlC). + // Assumes that UInt64 is a 64 bits integer. + static constexpr double maxUInt64AsDouble = 18446744073709551615.0; +// Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler +// when using gcc and clang backend compilers. CZString +// cannot be defined as private. See issue #486 +#ifdef __NVCC__ +public: +#else +private: +#endif +#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + class CZString { + public: + enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy }; + CZString(ArrayIndex index); + CZString(char const* str, unsigned length, DuplicationPolicy allocate); + CZString(CZString const& other); + CZString(CZString&& other); + ~CZString(); + CZString& operator=(const CZString& other); + CZString& operator=(CZString&& other); + + bool operator<(CZString const& other) const; + bool operator==(CZString const& other) const; + ArrayIndex index() const; + // const char* c_str() const; ///< \deprecated + char const* data() const; + unsigned length() const; + bool isStaticString() const; + + private: + void swap(CZString& other); + + struct StringStorage { + unsigned policy_ : 2; + unsigned length_ : 30; // 1GB max + }; + + char const* cstr_; // actually, a prefixed string, unless policy is noDup + union { + ArrayIndex index_; + StringStorage storage_; + }; + }; + +public: + typedef std::map<CZString, Value> ObjectValues; +#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + +public: + /** + * \brief Create a default Value of the given type. + * + * This is a very useful constructor. + * To create an empty array, pass arrayValue. + * To create an empty object, pass objectValue. + * Another Value can then be set to this one by assignment. + * This is useful since clear() and resize() will not alter types. + * + * Examples: + * \code + * Json::Value null_value; // null + * Json::Value arr_value(Json::arrayValue); // [] + * Json::Value obj_value(Json::objectValue); // {} + * \endcode + */ + Value(ValueType type = nullValue); + Value(Int value); + Value(UInt value); +#if defined(JSON_HAS_INT64) + Value(Int64 value); + Value(UInt64 value); +#endif // if defined(JSON_HAS_INT64) + Value(double value); + Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.) + Value(const char* begin, const char* end); ///< Copy all, incl zeroes. + /** + * \brief Constructs a value from a static string. + * + * Like other value string constructor but do not duplicate the string for + * internal storage. The given string must remain alive after the call to + * this constructor. + * + * \note This works only for null-terminated strings. (We cannot change the + * size of this class, so we have nowhere to store the length, which might be + * computed later for various operations.) + * + * Example of usage: + * \code + * static StaticString foo("some text"); + * Json::Value aValue(foo); + * \endcode + */ + Value(const StaticString& value); + Value(const String& value); + Value(bool value); + Value(std::nullptr_t ptr) = delete; + Value(const Value& other); + Value(Value&& other); + ~Value(); + + /// \note Overwrite existing comments. To preserve comments, use + /// #swapPayload(). + Value& operator=(const Value& other); + Value& operator=(Value&& other); + + /// Swap everything. + void swap(Value& other); + /// Swap values but leave comments and source offsets in place. + void swapPayload(Value& other); + + /// copy everything. + void copy(const Value& other); + /// copy values but leave comments and source offsets in place. + void copyPayload(const Value& other); + + ValueType type() const; + + /// Compare payload only, not comments etc. + bool operator<(const Value& other) const; + bool operator<=(const Value& other) const; + bool operator>=(const Value& other) const; + bool operator>(const Value& other) const; + bool operator==(const Value& other) const; + bool operator!=(const Value& other) const; + int compare(const Value& other) const; + + const char* asCString() const; ///< Embedded zeroes could cause you trouble! +#if JSONCPP_USING_SECURE_MEMORY + unsigned getCStringLength() const; // Allows you to understand the length of + // the CString +#endif + String asString() const; ///< Embedded zeroes are possible. + /** Get raw char* of string-value. + * \return false if !string. (Seg-fault if str or end are NULL.) + */ + bool getString(char const** begin, char const** end) const; + Int asInt() const; + UInt asUInt() const; +#if defined(JSON_HAS_INT64) + Int64 asInt64() const; + UInt64 asUInt64() const; +#endif // if defined(JSON_HAS_INT64) + LargestInt asLargestInt() const; + LargestUInt asLargestUInt() const; + float asFloat() const; + double asDouble() const; + bool asBool() const; + + bool isNull() const; + bool isBool() const; + bool isInt() const; + bool isInt64() const; + bool isUInt() const; + bool isUInt64() const; + bool isIntegral() const; + bool isDouble() const; + bool isNumeric() const; + bool isString() const; + bool isArray() const; + bool isObject() const; + + /// The `as<T>` and `is<T>` member function templates and specializations. + template <typename T> T as() const JSONCPP_TEMPLATE_DELETE; + template <typename T> bool is() const JSONCPP_TEMPLATE_DELETE; + + bool isConvertibleTo(ValueType other) const; + + /// Number of values in array or object + ArrayIndex size() const; + + /// \brief Return true if empty array, empty object, or null; + /// otherwise, false. + bool empty() const; + + /// Return !isNull() + explicit operator bool() const; + + /// Remove all object members and array elements. + /// \pre type() is arrayValue, objectValue, or nullValue + /// \post type() is unchanged + void clear(); + + /// Resize the array to newSize elements. + /// New elements are initialized to null. + /// May only be called on nullValue or arrayValue. + /// \pre type() is arrayValue or nullValue + /// \post type() is arrayValue + void resize(ArrayIndex newSize); + + //@{ + /// Access an array element (zero based index). If the array contains less + /// than index element, then null value are inserted in the array so that + /// its size is index+1. + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + Value& operator[](ArrayIndex index); + Value& operator[](int index); + //@} + + //@{ + /// Access an array element (zero based index). + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + const Value& operator[](ArrayIndex index) const; + const Value& operator[](int index) const; + //@} + + /// If the array contains at least index+1 elements, returns the element + /// value, otherwise returns defaultValue. + Value get(ArrayIndex index, const Value& defaultValue) const; + /// Return true if index < size(). + bool isValidIndex(ArrayIndex index) const; + /// \brief Append value to array at the end. + /// + /// Equivalent to jsonvalue[jsonvalue.size()] = value; + Value& append(const Value& value); + Value& append(Value&& value); + + /// \brief Insert value in array at specific index + bool insert(ArrayIndex index, const Value& newValue); + bool insert(ArrayIndex index, Value&& newValue); + + /// Access an object value by name, create a null member if it does not exist. + /// \note Because of our implementation, keys are limited to 2^30 -1 chars. + /// Exceeding that will cause an exception. + Value& operator[](const char* key); + /// Access an object value by name, returns null if there is no member with + /// that name. + const Value& operator[](const char* key) const; + /// Access an object value by name, create a null member if it does not exist. + /// \param key may contain embedded nulls. + Value& operator[](const String& key); + /// Access an object value by name, returns null if there is no member with + /// that name. + /// \param key may contain embedded nulls. + const Value& operator[](const String& key) const; + /** \brief Access an object value by name, create a null member if it does not + * exist. + * + * If the object has no entry for that name, then the member name used to + * store the new entry is not duplicated. + * Example of use: + * \code + * Json::Value object; + * static const StaticString code("code"); + * object[code] = 1234; + * \endcode + */ + Value& operator[](const StaticString& key); + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + Value get(const char* key, const Value& defaultValue) const; + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + /// \note key may contain embedded nulls. + Value get(const char* begin, const char* end, + const Value& defaultValue) const; + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + /// \param key may contain embedded nulls. + Value get(const String& key, const Value& defaultValue) const; + /// Most general and efficient version of isMember()const, get()const, + /// and operator[]const + /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 + Value const* find(char const* begin, char const* end) const; + /// Most general and efficient version of object-mutators. + /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 + /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. + Value* demand(char const* begin, char const* end); + /// \brief Remove and return the named member. + /// + /// Do nothing if it did not exist. + /// \pre type() is objectValue or nullValue + /// \post type() is unchanged + void removeMember(const char* key); + /// Same as removeMember(const char*) + /// \param key may contain embedded nulls. + void removeMember(const String& key); + /// Same as removeMember(const char* begin, const char* end, Value* removed), + /// but 'key' is null-terminated. + bool removeMember(const char* key, Value* removed); + /** \brief Remove the named map member. + * + * Update 'removed' iff removed. + * \param key may contain embedded nulls. + * \return true iff removed (no exceptions) + */ + bool removeMember(String const& key, Value* removed); + /// Same as removeMember(String const& key, Value* removed) + bool removeMember(const char* begin, const char* end, Value* removed); + /** \brief Remove the indexed array element. + * + * O(n) expensive operations. + * Update 'removed' iff removed. + * \return true if removed (no exceptions) + */ + bool removeIndex(ArrayIndex index, Value* removed); + + /// Return true if the object has a member named key. + /// \note 'key' must be null-terminated. + bool isMember(const char* key) const; + /// Return true if the object has a member named key. + /// \param key may contain embedded nulls. + bool isMember(const String& key) const; + /// Same as isMember(String const& key)const + bool isMember(const char* begin, const char* end) const; + + /// \brief Return a list of the member names. + /// + /// If null, return an empty list. + /// \pre type() is objectValue or nullValue + /// \post if type() was nullValue, it remains nullValue + Members getMemberNames() const; + + /// \deprecated Always pass len. + JSONCPP_DEPRECATED("Use setComment(String const&) instead.") + void setComment(const char* comment, CommentPlacement placement) { + setComment(String(comment, strlen(comment)), placement); + } + /// Comments must be //... or /* ... */ + void setComment(const char* comment, size_t len, CommentPlacement placement) { + setComment(String(comment, len), placement); + } + /// Comments must be //... or /* ... */ + void setComment(String comment, CommentPlacement placement); + bool hasComment(CommentPlacement placement) const; + /// Include delimiters and embedded newlines. + String getComment(CommentPlacement placement) const; + + String toStyledString() const; + + const_iterator begin() const; + const_iterator end() const; + + iterator begin(); + iterator end(); + + // Accessors for the [start, limit) range of bytes within the JSON text from + // which this value was parsed, if any. + void setOffsetStart(ptrdiff_t start); + void setOffsetLimit(ptrdiff_t limit); + ptrdiff_t getOffsetStart() const; + ptrdiff_t getOffsetLimit() const; + +private: + void setType(ValueType v) { + bits_.value_type_ = static_cast<unsigned char>(v); + } + bool isAllocated() const { return bits_.allocated_; } + void setIsAllocated(bool v) { bits_.allocated_ = v; } + + void initBasic(ValueType type, bool allocated = false); + void dupPayload(const Value& other); + void releasePayload(); + void dupMeta(const Value& other); + + Value& resolveReference(const char* key); + Value& resolveReference(const char* key, const char* end); + + // struct MemberNamesTransform + //{ + // typedef const char *result_type; + // const char *operator()( const CZString &name ) const + // { + // return name.c_str(); + // } + //}; + + union ValueHolder { + LargestInt int_; + LargestUInt uint_; + double real_; + bool bool_; + char* string_; // if allocated_, ptr to { unsigned, char[] }. + ObjectValues* map_; + } value_; + + struct { + // Really a ValueType, but types should agree for bitfield packing. + unsigned int value_type_ : 8; + // Unless allocated_, string_ must be null-terminated. + unsigned int allocated_ : 1; + } bits_; + + class Comments { + public: + Comments() = default; + Comments(const Comments& that); + Comments(Comments&& that); + Comments& operator=(const Comments& that); + Comments& operator=(Comments&& that); + bool has(CommentPlacement slot) const; + String get(CommentPlacement slot) const; + void set(CommentPlacement slot, String comment); + + private: + using Array = std::array<String, numberOfCommentPlacement>; + std::unique_ptr<Array> ptr_; + }; + Comments comments_; + + // [start, limit) byte offsets in the source JSON text from which this Value + // was extracted. + ptrdiff_t start_; + ptrdiff_t limit_; +}; + +template <> inline bool Value::as<bool>() const { return asBool(); } +template <> inline bool Value::is<bool>() const { return isBool(); } + +template <> inline Int Value::as<Int>() const { return asInt(); } +template <> inline bool Value::is<Int>() const { return isInt(); } + +template <> inline UInt Value::as<UInt>() const { return asUInt(); } +template <> inline bool Value::is<UInt>() const { return isUInt(); } + +#if defined(JSON_HAS_INT64) +template <> inline Int64 Value::as<Int64>() const { return asInt64(); } +template <> inline bool Value::is<Int64>() const { return isInt64(); } + +template <> inline UInt64 Value::as<UInt64>() const { return asUInt64(); } +template <> inline bool Value::is<UInt64>() const { return isUInt64(); } +#endif + +template <> inline double Value::as<double>() const { return asDouble(); } +template <> inline bool Value::is<double>() const { return isDouble(); } + +template <> inline String Value::as<String>() const { return asString(); } +template <> inline bool Value::is<String>() const { return isString(); } + +/// These `as` specializations are type conversions, and do not have a +/// corresponding `is`. +template <> inline float Value::as<float>() const { return asFloat(); } +template <> inline const char* Value::as<const char*>() const { + return asCString(); +} + +/** \brief Experimental and untested: represents an element of the "path" to + * access a node. + */ +class JSON_API PathArgument { +public: + friend class Path; + + PathArgument(); + PathArgument(ArrayIndex index); + PathArgument(const char* key); + PathArgument(String key); + +private: + enum Kind { kindNone = 0, kindIndex, kindKey }; + String key_; + ArrayIndex index_{}; + Kind kind_{kindNone}; +}; + +/** \brief Experimental and untested: represents a "path" to access a node. + * + * Syntax: + * - "." => root node + * - ".[n]" => elements at index 'n' of root node (an array value) + * - ".name" => member named 'name' of root node (an object value) + * - ".name1.name2.name3" + * - ".[0][1][2].name1[3]" + * - ".%" => member name is provided as parameter + * - ".[%]" => index is provided as parameter + */ +class JSON_API Path { +public: + Path(const String& path, const PathArgument& a1 = PathArgument(), + const PathArgument& a2 = PathArgument(), + const PathArgument& a3 = PathArgument(), + const PathArgument& a4 = PathArgument(), + const PathArgument& a5 = PathArgument()); + + const Value& resolve(const Value& root) const; + Value resolve(const Value& root, const Value& defaultValue) const; + /// Creates the "path" to access the specified node and returns a reference on + /// the node. + Value& make(Value& root) const; + +private: + using InArgs = std::vector<const PathArgument*>; + using Args = std::vector<PathArgument>; + + void makePath(const String& path, const InArgs& in); + void addPathInArg(const String& path, const InArgs& in, + InArgs::const_iterator& itInArg, PathArgument::Kind kind); + static void invalidPath(const String& path, int location); + + Args args_; +}; + +/** \brief base class for Value iterators. + * + */ +class JSON_API ValueIteratorBase { +public: + using iterator_category = std::bidirectional_iterator_tag; + using size_t = unsigned int; + using difference_type = int; + using SelfType = ValueIteratorBase; + + bool operator==(const SelfType& other) const { return isEqual(other); } + + bool operator!=(const SelfType& other) const { return !isEqual(other); } + + difference_type operator-(const SelfType& other) const { + return other.computeDistance(*this); + } + + /// Return either the index or the member name of the referenced value as a + /// Value. + Value key() const; + + /// Return the index of the referenced Value, or -1 if it is not an + /// arrayValue. + UInt index() const; + + /// Return the member name of the referenced Value, or "" if it is not an + /// objectValue. + /// \note Avoid `c_str()` on result, as embedded zeroes are possible. + String name() const; + + /// Return the member name of the referenced Value. "" if it is not an + /// objectValue. + /// \deprecated This cannot be used for UTF-8 strings, since there can be + /// embedded nulls. + JSONCPP_DEPRECATED("Use `key = name();` instead.") + char const* memberName() const; + /// Return the member name of the referenced Value, or NULL if it is not an + /// objectValue. + /// \note Better version than memberName(). Allows embedded nulls. + char const* memberName(char const** end) const; + +protected: + /*! Internal utility functions to assist with implementing + * other iterator functions. The const and non-const versions + * of the "deref" protected methods expose the protected + * current_ member variable in a way that can often be + * optimized away by the compiler. + */ + const Value& deref() const; + Value& deref(); + + void increment(); + + void decrement(); + + difference_type computeDistance(const SelfType& other) const; + + bool isEqual(const SelfType& other) const; + + void copy(const SelfType& other); + +private: + Value::ObjectValues::iterator current_; + // Indicates that iterator is for a null value. + bool isNull_{true}; + +public: + // For some reason, BORLAND needs these at the end, rather + // than earlier. No idea why. + ValueIteratorBase(); + explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); +}; + +/** \brief const iterator for object and array value. + * + */ +class JSON_API ValueConstIterator : public ValueIteratorBase { + friend class Value; + +public: + using value_type = const Value; + // typedef unsigned int size_t; + // typedef int difference_type; + using reference = const Value&; + using pointer = const Value*; + using SelfType = ValueConstIterator; + + ValueConstIterator(); + ValueConstIterator(ValueIterator const& other); + +private: + /*! \internal Use by Value to create an iterator. + */ + explicit ValueConstIterator(const Value::ObjectValues::iterator& current); + +public: + SelfType& operator=(const ValueIteratorBase& other); + + SelfType operator++(int) { + SelfType temp(*this); + ++*this; + return temp; + } + + SelfType operator--(int) { + SelfType temp(*this); + --*this; + return temp; + } + + SelfType& operator--() { + decrement(); + return *this; + } + + SelfType& operator++() { + increment(); + return *this; + } + + reference operator*() const { return deref(); } + + pointer operator->() const { return &deref(); } +}; + +/** \brief Iterator for object and array value. + */ +class JSON_API ValueIterator : public ValueIteratorBase { + friend class Value; + +public: + using value_type = Value; + using size_t = unsigned int; + using difference_type = int; + using reference = Value&; + using pointer = Value*; + using SelfType = ValueIterator; + + ValueIterator(); + explicit ValueIterator(const ValueConstIterator& other); + ValueIterator(const ValueIterator& other); + +private: + /*! \internal Use by Value to create an iterator. + */ + explicit ValueIterator(const Value::ObjectValues::iterator& current); + +public: + SelfType& operator=(const SelfType& other); + + SelfType operator++(int) { + SelfType temp(*this); + ++*this; + return temp; + } + + SelfType operator--(int) { + SelfType temp(*this); + --*this; + return temp; + } + + SelfType& operator--() { + decrement(); + return *this; + } + + SelfType& operator++() { + increment(); + return *this; + } + + /*! The return value of non-const iterators can be + * changed, so the these functions are not const + * because the returned references/pointers can be used + * to change state of the base class. + */ + reference operator*() { return deref(); } + pointer operator->() { return &deref(); } +}; + +inline void swap(Value& a, Value& b) { a.swap(b); } + +} // namespace Json + +#pragma pack(pop) + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // JSON_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/value.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/reader.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_READER_H_INCLUDED +#define JSON_READER_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "json_features.h" +#include "value.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include <deque> +#include <iosfwd> +#include <istream> +#include <stack> +#include <string> + +// Disable warning C4251: <data member>: <type> needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#pragma pack(push, 8) + +namespace Json { + +/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a + * Value. + * + * \deprecated Use CharReader and CharReaderBuilder. + */ + +class JSONCPP_DEPRECATED( + "Use CharReader and CharReaderBuilder instead.") JSON_API Reader { +public: + using Char = char; + using Location = const Char*; + + /** \brief An error tagged with where in the JSON text it was encountered. + * + * The offsets give the [start, limit) range of bytes within the text. Note + * that this is bytes, not codepoints. + */ + struct StructuredError { + ptrdiff_t offset_start; + ptrdiff_t offset_limit; + String message; + }; + + /** \brief Constructs a Reader allowing all features for parsing. + */ + JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") + Reader(); + + /** \brief Constructs a Reader allowing the specified feature set for parsing. + */ + JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") + Reader(const Features& features); + + /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> + * document. + * + * \param document UTF-8 encoded string containing the document + * to read. + * \param[out] root Contains the root value of the document if it + * was successfully parsed. + * \param collectComments \c true to collect comment and allow writing + * them back during serialization, \c false to + * discard comments. This parameter is ignored + * if Features::allowComments_ is \c false. + * \return \c true if the document was successfully parsed, \c false if an + * error occurred. + */ + bool parse(const std::string& document, Value& root, + bool collectComments = true); + + /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> + * document. + * + * \param beginDoc Pointer on the beginning of the UTF-8 encoded + * string of the document to read. + * \param endDoc Pointer on the end of the UTF-8 encoded string + * of the document to read. Must be >= beginDoc. + * \param[out] root Contains the root value of the document if it + * was successfully parsed. + * \param collectComments \c true to collect comment and allow writing + * them back during serialization, \c false to + * discard comments. This parameter is ignored + * if Features::allowComments_ is \c false. + * \return \c true if the document was successfully parsed, \c false if an + * error occurred. + */ + bool parse(const char* beginDoc, const char* endDoc, Value& root, + bool collectComments = true); + + /// \brief Parse from input stream. + /// \see Json::operator>>(std::istream&, Json::Value&). + bool parse(IStream& is, Value& root, bool collectComments = true); + + /** \brief Returns a user friendly string that list errors in the parsed + * document. + * + * \return Formatted error message with the list of errors with their + * location in the parsed document. An empty string is returned if no error + * occurred during parsing. + * \deprecated Use getFormattedErrorMessages() instead (typo fix). + */ + JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") + String getFormatedErrorMessages() const; + + /** \brief Returns a user friendly string that list errors in the parsed + * document. + * + * \return Formatted error message with the list of errors with their + * location in the parsed document. An empty string is returned if no error + * occurred during parsing. + */ + String getFormattedErrorMessages() const; + + /** \brief Returns a vector of structured errors encountered while parsing. + * + * \return A (possibly empty) vector of StructuredError objects. Currently + * only one error can be returned, but the caller should tolerate multiple + * errors. This can occur if the parser recovers from a non-fatal parse + * error and then encounters additional errors. + */ + std::vector<StructuredError> getStructuredErrors() const; + + /** \brief Add a semantic error message. + * + * \param value JSON Value location associated with the error + * \param message The error message. + * \return \c true if the error was successfully added, \c false if the Value + * offset exceeds the document size. + */ + bool pushError(const Value& value, const String& message); + + /** \brief Add a semantic error message with extra context. + * + * \param value JSON Value location associated with the error + * \param message The error message. + * \param extra Additional JSON Value location to contextualize the error + * \return \c true if the error was successfully added, \c false if either + * Value offset exceeds the document size. + */ + bool pushError(const Value& value, const String& message, const Value& extra); + + /** \brief Return whether there are any errors. + * + * \return \c true if there are no errors to report \c false if errors have + * occurred. + */ + bool good() const; + +private: + enum TokenType { + tokenEndOfStream = 0, + tokenObjectBegin, + tokenObjectEnd, + tokenArrayBegin, + tokenArrayEnd, + tokenString, + tokenNumber, + tokenTrue, + tokenFalse, + tokenNull, + tokenArraySeparator, + tokenMemberSeparator, + tokenComment, + tokenError + }; + + class Token { + public: + TokenType type_; + Location start_; + Location end_; + }; + + class ErrorInfo { + public: + Token token_; + String message_; + Location extra_; + }; + + using Errors = std::deque<ErrorInfo>; + + bool readToken(Token& token); + void skipSpaces(); + bool match(const Char* pattern, int patternLength); + bool readComment(); + bool readCStyleComment(); + bool readCppStyleComment(); + bool readString(); + void readNumber(); + bool readValue(); + bool readObject(Token& token); + bool readArray(Token& token); + bool decodeNumber(Token& token); + bool decodeNumber(Token& token, Value& decoded); + bool decodeString(Token& token); + bool decodeString(Token& token, String& decoded); + bool decodeDouble(Token& token); + bool decodeDouble(Token& token, Value& decoded); + bool decodeUnicodeCodePoint(Token& token, Location& current, Location end, + unsigned int& unicode); + bool decodeUnicodeEscapeSequence(Token& token, Location& current, + Location end, unsigned int& unicode); + bool addError(const String& message, Token& token, Location extra = nullptr); + bool recoverFromError(TokenType skipUntilToken); + bool addErrorAndRecover(const String& message, Token& token, + TokenType skipUntilToken); + void skipUntilSpace(); + Value& currentValue(); + Char getNextChar(); + void getLocationLineAndColumn(Location location, int& line, + int& column) const; + String getLocationLineAndColumn(Location location) const; + void addComment(Location begin, Location end, CommentPlacement placement); + void skipCommentTokens(Token& token); + + static bool containsNewLine(Location begin, Location end); + static String normalizeEOL(Location begin, Location end); + + using Nodes = std::stack<Value*>; + Nodes nodes_; + Errors errors_; + String document_; + Location begin_{}; + Location end_{}; + Location current_{}; + Location lastValueEnd_{}; + Value* lastValue_{}; + String commentsBefore_; + Features features_; + bool collectComments_{}; +}; // Reader + +/** Interface for reading JSON from a char array. + */ +class JSON_API CharReader { +public: + virtual ~CharReader() = default; + /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> + * document. The document must be a UTF-8 encoded string containing the + * document to read. + * + * \param beginDoc Pointer on the beginning of the UTF-8 encoded string + * of the document to read. + * \param endDoc Pointer on the end of the UTF-8 encoded string of the + * document to read. Must be >= beginDoc. + * \param[out] root Contains the root value of the document if it was + * successfully parsed. + * \param[out] errs Formatted error messages (if not NULL) a user + * friendly string that lists errors in the parsed + * document. + * \return \c true if the document was successfully parsed, \c false if an + * error occurred. + */ + virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, + String* errs) = 0; + + class JSON_API Factory { + public: + virtual ~Factory() = default; + /** \brief Allocate a CharReader via operator new(). + * \throw std::exception if something goes wrong (e.g. invalid settings) + */ + virtual CharReader* newCharReader() const = 0; + }; // Factory +}; // CharReader + +/** \brief Build a CharReader implementation. + * + * Usage: + * \code + * using namespace Json; + * CharReaderBuilder builder; + * builder["collectComments"] = false; + * Value value; + * String errs; + * bool ok = parseFromStream(builder, std::cin, &value, &errs); + * \endcode + */ +class JSON_API CharReaderBuilder : public CharReader::Factory { +public: + // Note: We use a Json::Value so that we can add data-members to this class + // without a major version bump. + /** Configuration of this builder. + * These are case-sensitive. + * Available settings (case-sensitive): + * - `"collectComments": false or true` + * - true to collect comment and allow writing them back during + * serialization, false to discard comments. This parameter is ignored + * if allowComments is false. + * - `"allowComments": false or true` + * - true if comments are allowed. + * - `"allowTrailingCommas": false or true` + * - true if trailing commas in objects and arrays are allowed. + * - `"strictRoot": false or true` + * - true if root must be either an array or an object value + * - `"allowDroppedNullPlaceholders": false or true` + * - true if dropped null placeholders are allowed. (See + * StreamWriterBuilder.) + * - `"allowNumericKeys": false or true` + * - true if numeric object keys are allowed. + * - `"allowSingleQuotes": false or true` + * - true if '' are allowed for strings (both keys and values) + * - `"stackLimit": integer` + * - Exceeding stackLimit (recursive depth of `readValue()`) will cause an + * exception. + * - This is a security issue (seg-faults caused by deeply nested JSON), so + * the default is low. + * - `"failIfExtra": false or true` + * - If true, `parse()` returns false when extra non-whitespace trails the + * JSON value in the input string. + * - `"rejectDupKeys": false or true` + * - If true, `parse()` returns false when a key is duplicated within an + * object. + * - `"allowSpecialFloats": false or true` + * - If true, special float values (NaNs and infinities) are allowed and + * their values are lossfree restorable. + * + * You can examine 'settings_` yourself to see the defaults. You can also + * write and read them just like any JSON Value. + * \sa setDefaults() + */ + Json::Value settings_; + + CharReaderBuilder(); + ~CharReaderBuilder() override; + + CharReader* newCharReader() const override; + + /** \return true if 'settings' are legal and consistent; + * otherwise, indicate bad settings via 'invalid'. + */ + bool validate(Json::Value* invalid) const; + + /** A simple way to update a specific setting. + */ + Value& operator[](const String& key); + + /** Called by ctor, but you can use this to reset settings_. + * \pre 'settings' != NULL (but Json::null is fine) + * \remark Defaults: + * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults + */ + static void setDefaults(Json::Value* settings); + /** Same as old Features::strictMode(). + * \pre 'settings' != NULL (but Json::null is fine) + * \remark Defaults: + * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode + */ + static void strictMode(Json::Value* settings); +}; + +/** Consume entire stream and use its begin/end. + * Someday we might have a real StreamReader, but for now this + * is convenient. + */ +bool JSON_API parseFromStream(CharReader::Factory const&, IStream&, Value* root, + String* errs); + +/** \brief Read from 'sin' into 'root'. + * + * Always keep comments from the input JSON. + * + * This can be used to read a file into a particular sub-object. + * For example: + * \code + * Json::Value root; + * cin >> root["dir"]["file"]; + * cout << root; + * \endcode + * Result: + * \verbatim + * { + * "dir": { + * "file": { + * // The input stream JSON would be nested here. + * } + * } + * } + * \endverbatim + * \throw std::exception on parse error. + * \see Json::operator<<() + */ +JSON_API IStream& operator>>(IStream&, Value&); + +} // namespace Json + +#pragma pack(pop) + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // JSON_READER_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/reader.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/writer.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_WRITER_H_INCLUDED +#define JSON_WRITER_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "value.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include <ostream> +#include <string> +#include <vector> + +// Disable warning C4251: <data member>: <type> needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) && defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#pragma pack(push, 8) + +namespace Json { + +class Value; + +/** + * + * Usage: + * \code + * using namespace Json; + * void writeToStdout(StreamWriter::Factory const& factory, Value const& value) + * { std::unique_ptr<StreamWriter> const writer( factory.newStreamWriter()); + * writer->write(value, &std::cout); + * std::cout << std::endl; // add lf and flush + * } + * \endcode + */ +class JSON_API StreamWriter { +protected: + OStream* sout_; // not owned; will not delete +public: + StreamWriter(); + virtual ~StreamWriter(); + /** Write Value into document as configured in sub-class. + * Do not take ownership of sout, but maintain a reference during function. + * \pre sout != NULL + * \return zero on success (For now, we always return zero, so check the + * stream instead.) \throw std::exception possibly, depending on + * configuration + */ + virtual int write(Value const& root, OStream* sout) = 0; + + /** \brief A simple abstract factory. + */ + class JSON_API Factory { + public: + virtual ~Factory(); + /** \brief Allocate a CharReader via operator new(). + * \throw std::exception if something goes wrong (e.g. invalid settings) + */ + virtual StreamWriter* newStreamWriter() const = 0; + }; // Factory +}; // StreamWriter + +/** \brief Write into stringstream, then return string, for convenience. + * A StreamWriter will be created from the factory, used, and then deleted. + */ +String JSON_API writeString(StreamWriter::Factory const& factory, + Value const& root); + +/** \brief Build a StreamWriter implementation. + +* Usage: +* \code +* using namespace Json; +* Value value = ...; +* StreamWriterBuilder builder; +* builder["commentStyle"] = "None"; +* builder["indentation"] = " "; // or whatever you like +* std::unique_ptr<Json::StreamWriter> writer( +* builder.newStreamWriter()); +* writer->write(value, &std::cout); +* std::cout << std::endl; // add lf and flush +* \endcode +*/ +class JSON_API StreamWriterBuilder : public StreamWriter::Factory { +public: + // Note: We use a Json::Value so that we can add data-members to this class + // without a major version bump. + /** Configuration of this builder. + * Available settings (case-sensitive): + * - "commentStyle": "None" or "All" + * - "indentation": "<anything>". + * - Setting this to an empty string also omits newline characters. + * - "enableYAMLCompatibility": false or true + * - slightly change the whitespace around colons + * - "dropNullPlaceholders": false or true + * - Drop the "null" string from the writer's output for nullValues. + * Strictly speaking, this is not valid JSON. But when the output is being + * fed to a browser's JavaScript, it makes for smaller output and the + * browser can handle the output just fine. + * - "useSpecialFloats": false or true + * - If true, outputs non-finite floating point values in the following way: + * NaN values as "NaN", positive infinity as "Infinity", and negative + * infinity as "-Infinity". + * - "precision": int + * - Number of precision digits for formatting of real values. + * - "precisionType": "significant"(default) or "decimal" + * - Type of precision for formatting of real values. + + * You can examine 'settings_` yourself + * to see the defaults. You can also write and read them just like any + * JSON Value. + * \sa setDefaults() + */ + Json::Value settings_; + + StreamWriterBuilder(); + ~StreamWriterBuilder() override; + + /** + * \throw std::exception if something goes wrong (e.g. invalid settings) + */ + StreamWriter* newStreamWriter() const override; + + /** \return true if 'settings' are legal and consistent; + * otherwise, indicate bad settings via 'invalid'. + */ + bool validate(Json::Value* invalid) const; + /** A simple way to update a specific setting. + */ + Value& operator[](const String& key); + + /** Called by ctor, but you can use this to reset settings_. + * \pre 'settings' != NULL (but Json::null is fine) + * \remark Defaults: + * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults + */ + static void setDefaults(Json::Value* settings); +}; + +/** \brief Abstract class for writers. + * \deprecated Use StreamWriter. (And really, this is an implementation detail.) + */ +class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { +public: + virtual ~Writer(); + + virtual String write(const Value& root) = 0; +}; + +/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format + *without formatting (not human friendly). + * + * The JSON document is written in a single line. It is not intended for 'human' + *consumption, + * but may be useful to support feature such as RPC where bandwidth is limited. + * \sa Reader, Value + * \deprecated Use StreamWriterBuilder. + */ +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable : 4996) // Deriving from deprecated class +#endif +class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter + : public Writer { +public: + FastWriter(); + ~FastWriter() override = default; + + void enableYAMLCompatibility(); + + /** \brief Drop the "null" string from the writer's output for nullValues. + * Strictly speaking, this is not valid JSON. But when the output is being + * fed to a browser's JavaScript, it makes for smaller output and the + * browser can handle the output just fine. + */ + void dropNullPlaceholders(); + + void omitEndingLineFeed(); + +public: // overridden from Writer + String write(const Value& root) override; + +private: + void writeValue(const Value& value); + + String document_; + bool yamlCompatibilityEnabled_{false}; + bool dropNullPlaceholders_{false}; + bool omitEndingLineFeed_{false}; +}; +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a + *human friendly way. + * + * The rules for line break and indent are as follow: + * - Object value: + * - if empty then print {} without indent and line break + * - if not empty the print '{', line break & indent, print one value per + *line + * and then unindent and line break and print '}'. + * - Array value: + * - if empty then print [] without indent and line break + * - if the array contains no object value, empty array or some other value + *types, + * and all the values fit on one lines, then print the array on a single + *line. + * - otherwise, it the values do not fit on one line, or the array contains + * object or non empty array, then print one value per line. + * + * If the Value have comments then they are outputed according to their + *#CommentPlacement. + * + * \sa Reader, Value, Value::setComment() + * \deprecated Use StreamWriterBuilder. + */ +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable : 4996) // Deriving from deprecated class +#endif +class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API + StyledWriter : public Writer { +public: + StyledWriter(); + ~StyledWriter() override = default; + +public: // overridden from Writer + /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format. + * \param root Value to serialize. + * \return String containing the JSON document that represents the root value. + */ + String write(const Value& root) override; + +private: + void writeValue(const Value& value); + void writeArrayValue(const Value& value); + bool isMultilineArray(const Value& value); + void pushValue(const String& value); + void writeIndent(); + void writeWithIndent(const String& value); + void indent(); + void unindent(); + void writeCommentBeforeValue(const Value& root); + void writeCommentAfterValueOnSameLine(const Value& root); + static bool hasCommentForValue(const Value& value); + static String normalizeEOL(const String& text); + + using ChildValues = std::vector<String>; + + ChildValues childValues_; + String document_; + String indentString_; + unsigned int rightMargin_{74}; + unsigned int indentSize_{3}; + bool addChildValues_{false}; +}; +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a + human friendly way, + to a stream rather than to a string. + * + * The rules for line break and indent are as follow: + * - Object value: + * - if empty then print {} without indent and line break + * - if not empty the print '{', line break & indent, print one value per + line + * and then unindent and line break and print '}'. + * - Array value: + * - if empty then print [] without indent and line break + * - if the array contains no object value, empty array or some other value + types, + * and all the values fit on one lines, then print the array on a single + line. + * - otherwise, it the values do not fit on one line, or the array contains + * object or non empty array, then print one value per line. + * + * If the Value have comments then they are outputed according to their + #CommentPlacement. + * + * \sa Reader, Value, Value::setComment() + * \deprecated Use StreamWriterBuilder. + */ +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable : 4996) // Deriving from deprecated class +#endif +class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API + StyledStreamWriter { +public: + /** + * \param indentation Each level will be indented by this amount extra. + */ + StyledStreamWriter(String indentation = "\t"); + ~StyledStreamWriter() = default; + +public: + /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format. + * \param out Stream to write to. (Can be ostringstream, e.g.) + * \param root Value to serialize. + * \note There is no point in deriving from Writer, since write() should not + * return a value. + */ + void write(OStream& out, const Value& root); + +private: + void writeValue(const Value& value); + void writeArrayValue(const Value& value); + bool isMultilineArray(const Value& value); + void pushValue(const String& value); + void writeIndent(); + void writeWithIndent(const String& value); + void indent(); + void unindent(); + void writeCommentBeforeValue(const Value& root); + void writeCommentAfterValueOnSameLine(const Value& root); + static bool hasCommentForValue(const Value& value); + static String normalizeEOL(const String& text); + + using ChildValues = std::vector<String>; + + ChildValues childValues_; + OStream* document_; + String indentString_; + unsigned int rightMargin_{74}; + String indentation_; + bool addChildValues_ : 1; + bool indented_ : 1; +}; +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#if defined(JSON_HAS_INT64) +String JSON_API valueToString(Int value); +String JSON_API valueToString(UInt value); +#endif // if defined(JSON_HAS_INT64) +String JSON_API valueToString(LargestInt value); +String JSON_API valueToString(LargestUInt value); +String JSON_API valueToString( + double value, unsigned int precision = Value::defaultRealPrecision, + PrecisionType precisionType = PrecisionType::significantDigits); +String JSON_API valueToString(bool value); +String JSON_API valueToQuotedString(const char* value); + +/// \brief Output using the StyledStreamWriter. +/// \see Json::operator>>() +JSON_API OStream& operator<<(OStream&, const Value& root); + +} // namespace Json + +#pragma pack(pop) + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // JSON_WRITER_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/writer.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/assertions.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_ASSERTIONS_H_INCLUDED +#define JSON_ASSERTIONS_H_INCLUDED + +#include <cstdlib> +#include <sstream> + +#if !defined(JSON_IS_AMALGAMATION) +#include "config.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +/** It should not be possible for a maliciously designed file to + * cause an abort() or seg-fault, so these macros are used only + * for pre-condition violations and internal logic errors. + */ +#if JSON_USE_EXCEPTION + +// @todo <= add detail about condition in exception +#define JSON_ASSERT(condition) \ + do { \ + if (!(condition)) { \ + Json::throwLogicError("assert json failed"); \ + } \ + } while (0) + +#define JSON_FAIL_MESSAGE(message) \ + do { \ + OStringStream oss; \ + oss << message; \ + Json::throwLogicError(oss.str()); \ + abort(); \ + } while (0) + +#else // JSON_USE_EXCEPTION + +#define JSON_ASSERT(condition) assert(condition) + +// The call to assert() will show the failure message in debug builds. In +// release builds we abort, for a core-dump or debugger. +#define JSON_FAIL_MESSAGE(message) \ + { \ + OStringStream oss; \ + oss << message; \ + assert(false && oss.str().c_str()); \ + abort(); \ + } + +#endif + +#define JSON_ASSERT_MESSAGE(condition, message) \ + do { \ + if (!(condition)) { \ + JSON_FAIL_MESSAGE(message); \ + } \ + } while (0) + +#endif // JSON_ASSERTIONS_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/assertions.h +// ////////////////////////////////////////////////////////////////////// + + + + + +#endif //ifndef JSON_AMALGAMATED_H_INCLUDED diff --git a/lib/jsoncpp/jsoncpp.cpp b/lib/jsoncpp/jsoncpp.cpp new file mode 100644 index 0000000..30e0a69 --- /dev/null +++ b/lib/jsoncpp/jsoncpp.cpp @@ -0,0 +1,5326 @@ +/// Json-cpp amalgamated source (http://jsoncpp.sourceforge.net/). +/// It is intended to be used with #include "json/json.h" + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + +/* +The JsonCpp library's source code, including accompanying documentation, +tests and demonstration applications, are licensed under the following +conditions... + +Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, +this software is released into the Public Domain. + +In jurisdictions which do not recognize Public Domain property (e.g. Germany as of +2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and +The JsonCpp Authors, and is released under the terms of the MIT License (see below). + +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual +Public Domain/MIT License conditions described here, as they choose. + +The MIT License is about as close to Public Domain as a license can get, and is +described in clear, concise terms at: + + http://en.wikipedia.org/wiki/MIT_License + +The full text of the MIT License follows: + +======================================================================== +Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors + +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. +======================================================================== +(END LICENSE TEXT) + +The MIT license is compatible with both the GPL and commercial +software, affording one all of the rights of Public Domain with the +minor nuisance of being required to keep the above copyright notice +and license text in the source code. Note also that by accepting the +Public Domain "license" you can re-license your copy using whatever +license you like. + +*/ + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + + + + + + +#include "json/json.h" + +#ifndef JSON_IS_AMALGAMATION +#error "Compile with -I PATH_TO_JSON_DIRECTORY" +#endif + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: src/lib_json/json_tool.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED +#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include <json/config.h> +#endif + +// Also support old flag NO_LOCALE_SUPPORT +#ifdef NO_LOCALE_SUPPORT +#define JSONCPP_NO_LOCALE_SUPPORT +#endif + +#ifndef JSONCPP_NO_LOCALE_SUPPORT +#include <clocale> +#endif + +/* This header provides common string manipulation support, such as UTF-8, + * portable conversion from/to string... + * + * It is an internal header that must not be exposed. + */ + +namespace Json { +static inline char getDecimalPoint() { +#ifdef JSONCPP_NO_LOCALE_SUPPORT + return '\0'; +#else + struct lconv* lc = localeconv(); + return lc ? *(lc->decimal_point) : '\0'; +#endif +} + +/// Converts a unicode code-point to UTF-8. +static inline String codePointToUTF8(unsigned int cp) { + String result; + + // based on description from http://en.wikipedia.org/wiki/UTF-8 + + if (cp <= 0x7f) { + result.resize(1); + result[0] = static_cast<char>(cp); + } else if (cp <= 0x7FF) { + result.resize(2); + result[1] = static_cast<char>(0x80 | (0x3f & cp)); + result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6))); + } else if (cp <= 0xFFFF) { + result.resize(3); + result[2] = static_cast<char>(0x80 | (0x3f & cp)); + result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 6))); + result[0] = static_cast<char>(0xE0 | (0xf & (cp >> 12))); + } else if (cp <= 0x10FFFF) { + result.resize(4); + result[3] = static_cast<char>(0x80 | (0x3f & cp)); + result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6))); + result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12))); + result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18))); + } + + return result; +} + +enum { + /// Constant that specify the size of the buffer that must be passed to + /// uintToString. + uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1 +}; + +// Defines a char buffer for use with uintToString(). +using UIntToStringBuffer = char[uintToStringBufferSize]; + +/** Converts an unsigned integer to string. + * @param value Unsigned integer to convert to string + * @param current Input/Output string buffer. + * Must have at least uintToStringBufferSize chars free. + */ +static inline void uintToString(LargestUInt value, char*& current) { + *--current = 0; + do { + *--current = static_cast<char>(value % 10U + static_cast<unsigned>('0')); + value /= 10; + } while (value != 0); +} + +/** Change ',' to '.' everywhere in buffer. + * + * We had a sophisticated way, but it did not work in WinCE. + * @see https://github.com/open-source-parsers/jsoncpp/pull/9 + */ +template <typename Iter> Iter fixNumericLocale(Iter begin, Iter end) { + for (; begin != end; ++begin) { + if (*begin == ',') { + *begin = '.'; + } + } + return begin; +} + +template <typename Iter> void fixNumericLocaleInput(Iter begin, Iter end) { + char decimalPoint = getDecimalPoint(); + if (decimalPoint == '\0' || decimalPoint == '.') { + return; + } + for (; begin != end; ++begin) { + if (*begin == '.') { + *begin = decimalPoint; + } + } +} + +/** + * Return iterator that would be the new end of the range [begin,end), if we + * were to delete zeros in the end of string, but not the last zero before '.'. + */ +template <typename Iter> Iter fixZerosInTheEnd(Iter begin, Iter end) { + for (; begin != end; --end) { + if (*(end - 1) != '0') { + return end; + } + // Don't delete the last zero before the decimal point. + if (begin != (end - 1) && *(end - 2) == '.') { + return end; + } + } + return end; +} + +} // namespace Json + +#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: src/lib_json/json_tool.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: src/lib_json/json_reader.cpp +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2011 Baptiste Lepilleur and The JsonCpp Authors +// Copyright (C) 2016 InfoTeCS JSC. All rights reserved. +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#if !defined(JSON_IS_AMALGAMATION) +#include "json_tool.h" +#include <json/assertions.h> +#include <json/reader.h> +#include <json/value.h> +#endif // if !defined(JSON_IS_AMALGAMATION) +#include <algorithm> +#include <cassert> +#include <cstring> +#include <iostream> +#include <istream> +#include <limits> +#include <memory> +#include <set> +#include <sstream> +#include <utility> + +#include <cstdio> +#if __cplusplus >= 201103L + +#if !defined(sscanf) +#define sscanf std::sscanf +#endif + +#endif //__cplusplus + +#if defined(_MSC_VER) +#if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) +#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 +#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES +#endif //_MSC_VER + +#if defined(_MSC_VER) +// Disable warning about strdup being deprecated. +#pragma warning(disable : 4996) +#endif + +// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile +// time to change the stack limit +#if !defined(JSONCPP_DEPRECATED_STACK_LIMIT) +#define JSONCPP_DEPRECATED_STACK_LIMIT 1000 +#endif + +static size_t const stackLimit_g = + JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue() + +namespace Json { + +#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) +using CharReaderPtr = std::unique_ptr<CharReader>; +#else +using CharReaderPtr = std::auto_ptr<CharReader>; +#endif + +// Implementation of class Features +// //////////////////////////////// + +Features::Features() = default; + +Features Features::all() { return {}; } + +Features Features::strictMode() { + Features features; + features.allowComments_ = false; + features.strictRoot_ = true; + features.allowDroppedNullPlaceholders_ = false; + features.allowNumericKeys_ = false; + return features; +} + +// Implementation of class Reader +// //////////////////////////////// + +bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) { + return std::any_of(begin, end, [](char b) { return b == '\n' || b == '\r'; }); +} + +// Class Reader +// ////////////////////////////////////////////////////////////////// + +Reader::Reader() : features_(Features::all()) {} + +Reader::Reader(const Features& features) : features_(features) {} + +bool Reader::parse(const std::string& document, Value& root, + bool collectComments) { + document_.assign(document.begin(), document.end()); + const char* begin = document_.c_str(); + const char* end = begin + document_.length(); + return parse(begin, end, root, collectComments); +} + +bool Reader::parse(std::istream& is, Value& root, bool collectComments) { + // std::istream_iterator<char> begin(is); + // std::istream_iterator<char> end; + // Those would allow streamed input from a file, if parse() were a + // template function. + + // Since String is reference-counted, this at least does not + // create an extra copy. + String doc; + std::getline(is, doc, static_cast<char> EOF); + return parse(doc.data(), doc.data() + doc.size(), root, collectComments); +} + +bool Reader::parse(const char* beginDoc, const char* endDoc, Value& root, + bool collectComments) { + if (!features_.allowComments_) { + collectComments = false; + } + + begin_ = beginDoc; + end_ = endDoc; + collectComments_ = collectComments; + current_ = begin_; + lastValueEnd_ = nullptr; + lastValue_ = nullptr; + commentsBefore_.clear(); + errors_.clear(); + while (!nodes_.empty()) + nodes_.pop(); + nodes_.push(&root); + + bool successful = readValue(); + Token token; + skipCommentTokens(token); + if (collectComments_ && !commentsBefore_.empty()) + root.setComment(commentsBefore_, commentAfter); + if (features_.strictRoot_) { + if (!root.isArray() && !root.isObject()) { + // Set error location to start of doc, ideally should be first token found + // in doc + token.type_ = tokenError; + token.start_ = beginDoc; + token.end_ = endDoc; + addError( + "A valid JSON document must be either an array or an object value.", + token); + return false; + } + } + return successful; +} + +bool Reader::readValue() { + // readValue() may call itself only if it calls readObject() or ReadArray(). + // These methods execute nodes_.push() just before and nodes_.pop)() just + // after calling readValue(). parse() executes one nodes_.push(), so > instead + // of >=. + if (nodes_.size() > stackLimit_g) + throwRuntimeError("Exceeded stackLimit in readValue()."); + + Token token; + skipCommentTokens(token); + bool successful = true; + + if (collectComments_ && !commentsBefore_.empty()) { + currentValue().setComment(commentsBefore_, commentBefore); + commentsBefore_.clear(); + } + + switch (token.type_) { + case tokenObjectBegin: + successful = readObject(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenArrayBegin: + successful = readArray(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenNumber: + successful = decodeNumber(token); + break; + case tokenString: + successful = decodeString(token); + break; + case tokenTrue: { + Value v(true); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } break; + case tokenFalse: { + Value v(false); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } break; + case tokenNull: { + Value v; + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } break; + case tokenArraySeparator: + case tokenObjectEnd: + case tokenArrayEnd: + if (features_.allowDroppedNullPlaceholders_) { + // "Un-read" the current token and mark the current value as a null + // token. + current_--; + Value v; + currentValue().swapPayload(v); + currentValue().setOffsetStart(current_ - begin_ - 1); + currentValue().setOffsetLimit(current_ - begin_); + break; + } // Else, fall through... + default: + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return addError("Syntax error: value, object or array expected.", token); + } + + if (collectComments_) { + lastValueEnd_ = current_; + lastValue_ = ¤tValue(); + } + + return successful; +} + +void Reader::skipCommentTokens(Token& token) { + if (features_.allowComments_) { + do { + readToken(token); + } while (token.type_ == tokenComment); + } else { + readToken(token); + } +} + +bool Reader::readToken(Token& token) { + skipSpaces(); + token.start_ = current_; + Char c = getNextChar(); + bool ok = true; + switch (c) { + case '{': + token.type_ = tokenObjectBegin; + break; + case '}': + token.type_ = tokenObjectEnd; + break; + case '[': + token.type_ = tokenArrayBegin; + break; + case ']': + token.type_ = tokenArrayEnd; + break; + case '"': + token.type_ = tokenString; + ok = readString(); + break; + case '/': + token.type_ = tokenComment; + ok = readComment(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + token.type_ = tokenNumber; + readNumber(); + break; + case 't': + token.type_ = tokenTrue; + ok = match("rue", 3); + break; + case 'f': + token.type_ = tokenFalse; + ok = match("alse", 4); + break; + case 'n': + token.type_ = tokenNull; + ok = match("ull", 3); + break; + case ',': + token.type_ = tokenArraySeparator; + break; + case ':': + token.type_ = tokenMemberSeparator; + break; + case 0: + token.type_ = tokenEndOfStream; + break; + default: + ok = false; + break; + } + if (!ok) + token.type_ = tokenError; + token.end_ = current_; + return ok; +} + +void Reader::skipSpaces() { + while (current_ != end_) { + Char c = *current_; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n') + ++current_; + else + break; + } +} + +bool Reader::match(const Char* pattern, int patternLength) { + if (end_ - current_ < patternLength) + return false; + int index = patternLength; + while (index--) + if (current_[index] != pattern[index]) + return false; + current_ += patternLength; + return true; +} + +bool Reader::readComment() { + Location commentBegin = current_ - 1; + Char c = getNextChar(); + bool successful = false; + if (c == '*') + successful = readCStyleComment(); + else if (c == '/') + successful = readCppStyleComment(); + if (!successful) + return false; + + if (collectComments_) { + CommentPlacement placement = commentBefore; + if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { + if (c != '*' || !containsNewLine(commentBegin, current_)) + placement = commentAfterOnSameLine; + } + + addComment(commentBegin, current_, placement); + } + return true; +} + +String Reader::normalizeEOL(Reader::Location begin, Reader::Location end) { + String normalized; + normalized.reserve(static_cast<size_t>(end - begin)); + Reader::Location current = begin; + while (current != end) { + char c = *current++; + if (c == '\r') { + if (current != end && *current == '\n') + // convert dos EOL + ++current; + // convert Mac EOL + normalized += '\n'; + } else { + normalized += c; + } + } + return normalized; +} + +void Reader::addComment(Location begin, Location end, + CommentPlacement placement) { + assert(collectComments_); + const String& normalized = normalizeEOL(begin, end); + if (placement == commentAfterOnSameLine) { + assert(lastValue_ != nullptr); + lastValue_->setComment(normalized, placement); + } else { + commentsBefore_ += normalized; + } +} + +bool Reader::readCStyleComment() { + while ((current_ + 1) < end_) { + Char c = getNextChar(); + if (c == '*' && *current_ == '/') + break; + } + return getNextChar() == '/'; +} + +bool Reader::readCppStyleComment() { + while (current_ != end_) { + Char c = getNextChar(); + if (c == '\n') + break; + if (c == '\r') { + // Consume DOS EOL. It will be normalized in addComment. + if (current_ != end_ && *current_ == '\n') + getNextChar(); + // Break on Moc OS 9 EOL. + break; + } + } + return true; +} + +void Reader::readNumber() { + Location p = current_; + char c = '0'; // stopgap for already consumed character + // integral part + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : '\0'; + // fractional part + if (c == '.') { + c = (current_ = p) < end_ ? *p++ : '\0'; + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : '\0'; + } + // exponential part + if (c == 'e' || c == 'E') { + c = (current_ = p) < end_ ? *p++ : '\0'; + if (c == '+' || c == '-') + c = (current_ = p) < end_ ? *p++ : '\0'; + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : '\0'; + } +} + +bool Reader::readString() { + Char c = '\0'; + while (current_ != end_) { + c = getNextChar(); + if (c == '\\') + getNextChar(); + else if (c == '"') + break; + } + return c == '"'; +} + +bool Reader::readObject(Token& token) { + Token tokenName; + String name; + Value init(objectValue); + currentValue().swapPayload(init); + currentValue().setOffsetStart(token.start_ - begin_); + while (readToken(tokenName)) { + bool initialTokenOk = true; + while (tokenName.type_ == tokenComment && initialTokenOk) + initialTokenOk = readToken(tokenName); + if (!initialTokenOk) + break; + if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object + return true; + name.clear(); + if (tokenName.type_ == tokenString) { + if (!decodeString(tokenName, name)) + return recoverFromError(tokenObjectEnd); + } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { + Value numberName; + if (!decodeNumber(tokenName, numberName)) + return recoverFromError(tokenObjectEnd); + name = numberName.asString(); + } else { + break; + } + + Token colon; + if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { + return addErrorAndRecover("Missing ':' after object member name", colon, + tokenObjectEnd); + } + Value& value = currentValue()[name]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); + if (!ok) // error already set + return recoverFromError(tokenObjectEnd); + + Token comma; + if (!readToken(comma) || + (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && + comma.type_ != tokenComment)) { + return addErrorAndRecover("Missing ',' or '}' in object declaration", + comma, tokenObjectEnd); + } + bool finalizeTokenOk = true; + while (comma.type_ == tokenComment && finalizeTokenOk) + finalizeTokenOk = readToken(comma); + if (comma.type_ == tokenObjectEnd) + return true; + } + return addErrorAndRecover("Missing '}' or object member name", tokenName, + tokenObjectEnd); +} + +bool Reader::readArray(Token& token) { + Value init(arrayValue); + currentValue().swapPayload(init); + currentValue().setOffsetStart(token.start_ - begin_); + skipSpaces(); + if (current_ != end_ && *current_ == ']') // empty array + { + Token endArray; + readToken(endArray); + return true; + } + int index = 0; + for (;;) { + Value& value = currentValue()[index++]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); + if (!ok) // error already set + return recoverFromError(tokenArrayEnd); + + Token currentToken; + // Accept Comment after last item in the array. + ok = readToken(currentToken); + while (currentToken.type_ == tokenComment && ok) { + ok = readToken(currentToken); + } + bool badTokenType = (currentToken.type_ != tokenArraySeparator && + currentToken.type_ != tokenArrayEnd); + if (!ok || badTokenType) { + return addErrorAndRecover("Missing ',' or ']' in array declaration", + currentToken, tokenArrayEnd); + } + if (currentToken.type_ == tokenArrayEnd) + break; + } + return true; +} + +bool Reader::decodeNumber(Token& token) { + Value decoded; + if (!decodeNumber(token, decoded)) + return false; + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool Reader::decodeNumber(Token& token, Value& decoded) { + // Attempts to parse the number as an integer. If the number is + // larger than the maximum supported value of an integer then + // we decode the number as a double. + Location current = token.start_; + bool isNegative = *current == '-'; + if (isNegative) + ++current; + // TODO: Help the compiler do the div and mod at compile time or get rid of + // them. + Value::LargestUInt maxIntegerValue = + isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1 + : Value::maxLargestUInt; + Value::LargestUInt threshold = maxIntegerValue / 10; + Value::LargestUInt value = 0; + while (current < token.end_) { + Char c = *current++; + if (c < '0' || c > '9') + return decodeDouble(token, decoded); + auto digit(static_cast<Value::UInt>(c - '0')); + if (value >= threshold) { + // We've hit or exceeded the max value divided by 10 (rounded down). If + // a) we've only just touched the limit, b) this is the last digit, and + // c) it's small enough to fit in that rounding delta, we're okay. + // Otherwise treat this number as a double to avoid overflow. + if (value > threshold || current != token.end_ || + digit > maxIntegerValue % 10) { + return decodeDouble(token, decoded); + } + } + value = value * 10 + digit; + } + if (isNegative && value == maxIntegerValue) + decoded = Value::minLargestInt; + else if (isNegative) + decoded = -Value::LargestInt(value); + else if (value <= Value::LargestUInt(Value::maxInt)) + decoded = Value::LargestInt(value); + else + decoded = value; + return true; +} + +bool Reader::decodeDouble(Token& token) { + Value decoded; + if (!decodeDouble(token, decoded)) + return false; + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool Reader::decodeDouble(Token& token, Value& decoded) { + double value = 0; + String buffer(token.start_, token.end_); + IStringStream is(buffer); + if (!(is >> value)) + return addError( + "'" + String(token.start_, token.end_) + "' is not a number.", token); + decoded = value; + return true; +} + +bool Reader::decodeString(Token& token) { + String decoded_string; + if (!decodeString(token, decoded_string)) + return false; + Value decoded(decoded_string); + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool Reader::decodeString(Token& token, String& decoded) { + decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2)); + Location current = token.start_ + 1; // skip '"' + Location end = token.end_ - 1; // do not include '"' + while (current != end) { + Char c = *current++; + if (c == '"') + break; + if (c == '\\') { + if (current == end) + return addError("Empty escape sequence in string", token, current); + Char escape = *current++; + switch (escape) { + case '"': + decoded += '"'; + break; + case '/': + decoded += '/'; + break; + case '\\': + decoded += '\\'; + break; + case 'b': + decoded += '\b'; + break; + case 'f': + decoded += '\f'; + break; + case 'n': + decoded += '\n'; + break; + case 'r': + decoded += '\r'; + break; + case 't': + decoded += '\t'; + break; + case 'u': { + unsigned int unicode; + if (!decodeUnicodeCodePoint(token, current, end, unicode)) + return false; + decoded += codePointToUTF8(unicode); + } break; + default: + return addError("Bad escape sequence in string", token, current); + } + } else { + decoded += c; + } + } + return true; +} + +bool Reader::decodeUnicodeCodePoint(Token& token, Location& current, + Location end, unsigned int& unicode) { + + if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) + return false; + if (unicode >= 0xD800 && unicode <= 0xDBFF) { + // surrogate pairs + if (end - current < 6) + return addError( + "additional six characters expected to parse unicode surrogate pair.", + token, current); + if (*(current++) == '\\' && *(current++) == 'u') { + unsigned int surrogatePair; + if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { + unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); + } else + return false; + } else + return addError("expecting another \\u token to begin the second half of " + "a unicode surrogate pair", + token, current); + } + return true; +} + +bool Reader::decodeUnicodeEscapeSequence(Token& token, Location& current, + Location end, + unsigned int& ret_unicode) { + if (end - current < 4) + return addError( + "Bad unicode escape sequence in string: four digits expected.", token, + current); + int unicode = 0; + for (int index = 0; index < 4; ++index) { + Char c = *current++; + unicode *= 16; + if (c >= '0' && c <= '9') + unicode += c - '0'; + else if (c >= 'a' && c <= 'f') + unicode += c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + unicode += c - 'A' + 10; + else + return addError( + "Bad unicode escape sequence in string: hexadecimal digit expected.", + token, current); + } + ret_unicode = static_cast<unsigned int>(unicode); + return true; +} + +bool Reader::addError(const String& message, Token& token, Location extra) { + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = extra; + errors_.push_back(info); + return false; +} + +bool Reader::recoverFromError(TokenType skipUntilToken) { + size_t const errorCount = errors_.size(); + Token skip; + for (;;) { + if (!readToken(skip)) + errors_.resize(errorCount); // discard errors caused by recovery + if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) + break; + } + errors_.resize(errorCount); + return false; +} + +bool Reader::addErrorAndRecover(const String& message, Token& token, + TokenType skipUntilToken) { + addError(message, token); + return recoverFromError(skipUntilToken); +} + +Value& Reader::currentValue() { return *(nodes_.top()); } + +Reader::Char Reader::getNextChar() { + if (current_ == end_) + return 0; + return *current_++; +} + +void Reader::getLocationLineAndColumn(Location location, int& line, + int& column) const { + Location current = begin_; + Location lastLineStart = current; + line = 0; + while (current < location && current != end_) { + Char c = *current++; + if (c == '\r') { + if (*current == '\n') + ++current; + lastLineStart = current; + ++line; + } else if (c == '\n') { + lastLineStart = current; + ++line; + } + } + // column & line start at 1 + column = int(location - lastLineStart) + 1; + ++line; +} + +String Reader::getLocationLineAndColumn(Location location) const { + int line, column; + getLocationLineAndColumn(location, line, column); + char buffer[18 + 16 + 16 + 1]; + jsoncpp_snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); + return buffer; +} + +// Deprecated. Preserved for backward compatibility +String Reader::getFormatedErrorMessages() const { + return getFormattedErrorMessages(); +} + +String Reader::getFormattedErrorMessages() const { + String formattedMessage; + for (const auto& error : errors_) { + formattedMessage += + "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; + formattedMessage += " " + error.message_ + "\n"; + if (error.extra_) + formattedMessage += + "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; + } + return formattedMessage; +} + +std::vector<Reader::StructuredError> Reader::getStructuredErrors() const { + std::vector<Reader::StructuredError> allErrors; + for (const auto& error : errors_) { + Reader::StructuredError structured; + structured.offset_start = error.token_.start_ - begin_; + structured.offset_limit = error.token_.end_ - begin_; + structured.message = error.message_; + allErrors.push_back(structured); + } + return allErrors; +} + +bool Reader::pushError(const Value& value, const String& message) { + ptrdiff_t const length = end_ - begin_; + if (value.getOffsetStart() > length || value.getOffsetLimit() > length) + return false; + Token token; + token.type_ = tokenError; + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = begin_ + value.getOffsetLimit(); + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = nullptr; + errors_.push_back(info); + return true; +} + +bool Reader::pushError(const Value& value, const String& message, + const Value& extra) { + ptrdiff_t const length = end_ - begin_; + if (value.getOffsetStart() > length || value.getOffsetLimit() > length || + extra.getOffsetLimit() > length) + return false; + Token token; + token.type_ = tokenError; + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = begin_ + value.getOffsetLimit(); + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = begin_ + extra.getOffsetStart(); + errors_.push_back(info); + return true; +} + +bool Reader::good() const { return errors_.empty(); } + +// Originally copied from the Features class (now deprecated), used internally +// for features implementation. +class OurFeatures { +public: + static OurFeatures all(); + bool allowComments_; + bool allowTrailingCommas_; + bool strictRoot_; + bool allowDroppedNullPlaceholders_; + bool allowNumericKeys_; + bool allowSingleQuotes_; + bool failIfExtra_; + bool rejectDupKeys_; + bool allowSpecialFloats_; + bool skipBom_; + size_t stackLimit_; +}; // OurFeatures + +OurFeatures OurFeatures::all() { return {}; } + +// Implementation of class Reader +// //////////////////////////////// + +// Originally copied from the Reader class (now deprecated), used internally +// for implementing JSON reading. +class OurReader { +public: + using Char = char; + using Location = const Char*; + struct StructuredError { + ptrdiff_t offset_start; + ptrdiff_t offset_limit; + String message; + }; + + explicit OurReader(OurFeatures const& features); + bool parse(const char* beginDoc, const char* endDoc, Value& root, + bool collectComments = true); + String getFormattedErrorMessages() const; + std::vector<StructuredError> getStructuredErrors() const; + +private: + OurReader(OurReader const&); // no impl + void operator=(OurReader const&); // no impl + + enum TokenType { + tokenEndOfStream = 0, + tokenObjectBegin, + tokenObjectEnd, + tokenArrayBegin, + tokenArrayEnd, + tokenString, + tokenNumber, + tokenTrue, + tokenFalse, + tokenNull, + tokenNaN, + tokenPosInf, + tokenNegInf, + tokenArraySeparator, + tokenMemberSeparator, + tokenComment, + tokenError + }; + + class Token { + public: + TokenType type_; + Location start_; + Location end_; + }; + + class ErrorInfo { + public: + Token token_; + String message_; + Location extra_; + }; + + using Errors = std::deque<ErrorInfo>; + + bool readToken(Token& token); + void skipSpaces(); + void skipBom(bool skipBom); + bool match(const Char* pattern, int patternLength); + bool readComment(); + bool readCStyleComment(bool* containsNewLineResult); + bool readCppStyleComment(); + bool readString(); + bool readStringSingleQuote(); + bool readNumber(bool checkInf); + bool readValue(); + bool readObject(Token& token); + bool readArray(Token& token); + bool decodeNumber(Token& token); + bool decodeNumber(Token& token, Value& decoded); + bool decodeString(Token& token); + bool decodeString(Token& token, String& decoded); + bool decodeDouble(Token& token); + bool decodeDouble(Token& token, Value& decoded); + bool decodeUnicodeCodePoint(Token& token, Location& current, Location end, + unsigned int& unicode); + bool decodeUnicodeEscapeSequence(Token& token, Location& current, + Location end, unsigned int& unicode); + bool addError(const String& message, Token& token, Location extra = nullptr); + bool recoverFromError(TokenType skipUntilToken); + bool addErrorAndRecover(const String& message, Token& token, + TokenType skipUntilToken); + void skipUntilSpace(); + Value& currentValue(); + Char getNextChar(); + void getLocationLineAndColumn(Location location, int& line, + int& column) const; + String getLocationLineAndColumn(Location location) const; + void addComment(Location begin, Location end, CommentPlacement placement); + void skipCommentTokens(Token& token); + + static String normalizeEOL(Location begin, Location end); + static bool containsNewLine(Location begin, Location end); + + using Nodes = std::stack<Value*>; + + Nodes nodes_{}; + Errors errors_{}; + String document_{}; + Location begin_ = nullptr; + Location end_ = nullptr; + Location current_ = nullptr; + Location lastValueEnd_ = nullptr; + Value* lastValue_ = nullptr; + bool lastValueHasAComment_ = false; + String commentsBefore_{}; + + OurFeatures const features_; + bool collectComments_ = false; +}; // OurReader + +// complete copy of Read impl, for OurReader + +bool OurReader::containsNewLine(OurReader::Location begin, + OurReader::Location end) { + return std::any_of(begin, end, [](char b) { return b == '\n' || b == '\r'; }); +} + +OurReader::OurReader(OurFeatures const& features) : features_(features) {} + +bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, + bool collectComments) { + if (!features_.allowComments_) { + collectComments = false; + } + + begin_ = beginDoc; + end_ = endDoc; + collectComments_ = collectComments; + current_ = begin_; + lastValueEnd_ = nullptr; + lastValue_ = nullptr; + commentsBefore_.clear(); + errors_.clear(); + while (!nodes_.empty()) + nodes_.pop(); + nodes_.push(&root); + + // skip byte order mark if it exists at the beginning of the UTF-8 text. + skipBom(features_.skipBom_); + bool successful = readValue(); + nodes_.pop(); + Token token; + skipCommentTokens(token); + if (features_.failIfExtra_ && (token.type_ != tokenEndOfStream)) { + addError("Extra non-whitespace after JSON value.", token); + return false; + } + if (collectComments_ && !commentsBefore_.empty()) + root.setComment(commentsBefore_, commentAfter); + if (features_.strictRoot_) { + if (!root.isArray() && !root.isObject()) { + // Set error location to start of doc, ideally should be first token found + // in doc + token.type_ = tokenError; + token.start_ = beginDoc; + token.end_ = endDoc; + addError( + "A valid JSON document must be either an array or an object value.", + token); + return false; + } + } + return successful; +} + +bool OurReader::readValue() { + // To preserve the old behaviour we cast size_t to int. + if (nodes_.size() > features_.stackLimit_) + throwRuntimeError("Exceeded stackLimit in readValue()."); + Token token; + skipCommentTokens(token); + bool successful = true; + + if (collectComments_ && !commentsBefore_.empty()) { + currentValue().setComment(commentsBefore_, commentBefore); + commentsBefore_.clear(); + } + + switch (token.type_) { + case tokenObjectBegin: + successful = readObject(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenArrayBegin: + successful = readArray(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenNumber: + successful = decodeNumber(token); + break; + case tokenString: + successful = decodeString(token); + break; + case tokenTrue: { + Value v(true); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } break; + case tokenFalse: { + Value v(false); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } break; + case tokenNull: { + Value v; + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } break; + case tokenNaN: { + Value v(std::numeric_limits<double>::quiet_NaN()); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } break; + case tokenPosInf: { + Value v(std::numeric_limits<double>::infinity()); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } break; + case tokenNegInf: { + Value v(-std::numeric_limits<double>::infinity()); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } break; + case tokenArraySeparator: + case tokenObjectEnd: + case tokenArrayEnd: + if (features_.allowDroppedNullPlaceholders_) { + // "Un-read" the current token and mark the current value as a null + // token. + current_--; + Value v; + currentValue().swapPayload(v); + currentValue().setOffsetStart(current_ - begin_ - 1); + currentValue().setOffsetLimit(current_ - begin_); + break; + } // else, fall through ... + default: + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return addError("Syntax error: value, object or array expected.", token); + } + + if (collectComments_) { + lastValueEnd_ = current_; + lastValueHasAComment_ = false; + lastValue_ = ¤tValue(); + } + + return successful; +} + +void OurReader::skipCommentTokens(Token& token) { + if (features_.allowComments_) { + do { + readToken(token); + } while (token.type_ == tokenComment); + } else { + readToken(token); + } +} + +bool OurReader::readToken(Token& token) { + skipSpaces(); + token.start_ = current_; + Char c = getNextChar(); + bool ok = true; + switch (c) { + case '{': + token.type_ = tokenObjectBegin; + break; + case '}': + token.type_ = tokenObjectEnd; + break; + case '[': + token.type_ = tokenArrayBegin; + break; + case ']': + token.type_ = tokenArrayEnd; + break; + case '"': + token.type_ = tokenString; + ok = readString(); + break; + case '\'': + if (features_.allowSingleQuotes_) { + token.type_ = tokenString; + ok = readStringSingleQuote(); + } else { + // If we don't allow single quotes, this is a failure case. + ok = false; + } + break; + case '/': + token.type_ = tokenComment; + ok = readComment(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + token.type_ = tokenNumber; + readNumber(false); + break; + case '-': + if (readNumber(true)) { + token.type_ = tokenNumber; + } else { + token.type_ = tokenNegInf; + ok = features_.allowSpecialFloats_ && match("nfinity", 7); + } + break; + case '+': + if (readNumber(true)) { + token.type_ = tokenNumber; + } else { + token.type_ = tokenPosInf; + ok = features_.allowSpecialFloats_ && match("nfinity", 7); + } + break; + case 't': + token.type_ = tokenTrue; + ok = match("rue", 3); + break; + case 'f': + token.type_ = tokenFalse; + ok = match("alse", 4); + break; + case 'n': + token.type_ = tokenNull; + ok = match("ull", 3); + break; + case 'N': + if (features_.allowSpecialFloats_) { + token.type_ = tokenNaN; + ok = match("aN", 2); + } else { + ok = false; + } + break; + case 'I': + if (features_.allowSpecialFloats_) { + token.type_ = tokenPosInf; + ok = match("nfinity", 7); + } else { + ok = false; + } + break; + case ',': + token.type_ = tokenArraySeparator; + break; + case ':': + token.type_ = tokenMemberSeparator; + break; + case 0: + token.type_ = tokenEndOfStream; + break; + default: + ok = false; + break; + } + if (!ok) + token.type_ = tokenError; + token.end_ = current_; + return ok; +} + +void OurReader::skipSpaces() { + while (current_ != end_) { + Char c = *current_; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n') + ++current_; + else + break; + } +} + +void OurReader::skipBom(bool skipBom) { + // The default behavior is to skip BOM. + if (skipBom) { + if ((end_ - begin_) >= 3 && strncmp(begin_, "\xEF\xBB\xBF", 3) == 0) { + begin_ += 3; + current_ = begin_; + } + } +} + +bool OurReader::match(const Char* pattern, int patternLength) { + if (end_ - current_ < patternLength) + return false; + int index = patternLength; + while (index--) + if (current_[index] != pattern[index]) + return false; + current_ += patternLength; + return true; +} + +bool OurReader::readComment() { + const Location commentBegin = current_ - 1; + const Char c = getNextChar(); + bool successful = false; + bool cStyleWithEmbeddedNewline = false; + + const bool isCStyleComment = (c == '*'); + const bool isCppStyleComment = (c == '/'); + if (isCStyleComment) { + successful = readCStyleComment(&cStyleWithEmbeddedNewline); + } else if (isCppStyleComment) { + successful = readCppStyleComment(); + } + + if (!successful) + return false; + + if (collectComments_) { + CommentPlacement placement = commentBefore; + + if (!lastValueHasAComment_) { + if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { + if (isCppStyleComment || !cStyleWithEmbeddedNewline) { + placement = commentAfterOnSameLine; + lastValueHasAComment_ = true; + } + } + } + + addComment(commentBegin, current_, placement); + } + return true; +} + +String OurReader::normalizeEOL(OurReader::Location begin, + OurReader::Location end) { + String normalized; + normalized.reserve(static_cast<size_t>(end - begin)); + OurReader::Location current = begin; + while (current != end) { + char c = *current++; + if (c == '\r') { + if (current != end && *current == '\n') + // convert dos EOL + ++current; + // convert Mac EOL + normalized += '\n'; + } else { + normalized += c; + } + } + return normalized; +} + +void OurReader::addComment(Location begin, Location end, + CommentPlacement placement) { + assert(collectComments_); + const String& normalized = normalizeEOL(begin, end); + if (placement == commentAfterOnSameLine) { + assert(lastValue_ != nullptr); + lastValue_->setComment(normalized, placement); + } else { + commentsBefore_ += normalized; + } +} + +bool OurReader::readCStyleComment(bool* containsNewLineResult) { + *containsNewLineResult = false; + + while ((current_ + 1) < end_) { + Char c = getNextChar(); + if (c == '*' && *current_ == '/') + break; + if (c == '\n') + *containsNewLineResult = true; + } + + return getNextChar() == '/'; +} + +bool OurReader::readCppStyleComment() { + while (current_ != end_) { + Char c = getNextChar(); + if (c == '\n') + break; + if (c == '\r') { + // Consume DOS EOL. It will be normalized in addComment. + if (current_ != end_ && *current_ == '\n') + getNextChar(); + // Break on Moc OS 9 EOL. + break; + } + } + return true; +} + +bool OurReader::readNumber(bool checkInf) { + Location p = current_; + if (checkInf && p != end_ && *p == 'I') { + current_ = ++p; + return false; + } + char c = '0'; // stopgap for already consumed character + // integral part + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : '\0'; + // fractional part + if (c == '.') { + c = (current_ = p) < end_ ? *p++ : '\0'; + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : '\0'; + } + // exponential part + if (c == 'e' || c == 'E') { + c = (current_ = p) < end_ ? *p++ : '\0'; + if (c == '+' || c == '-') + c = (current_ = p) < end_ ? *p++ : '\0'; + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : '\0'; + } + return true; +} +bool OurReader::readString() { + Char c = 0; + while (current_ != end_) { + c = getNextChar(); + if (c == '\\') + getNextChar(); + else if (c == '"') + break; + } + return c == '"'; +} + +bool OurReader::readStringSingleQuote() { + Char c = 0; + while (current_ != end_) { + c = getNextChar(); + if (c == '\\') + getNextChar(); + else if (c == '\'') + break; + } + return c == '\''; +} + +bool OurReader::readObject(Token& token) { + Token tokenName; + String name; + Value init(objectValue); + currentValue().swapPayload(init); + currentValue().setOffsetStart(token.start_ - begin_); + while (readToken(tokenName)) { + bool initialTokenOk = true; + while (tokenName.type_ == tokenComment && initialTokenOk) + initialTokenOk = readToken(tokenName); + if (!initialTokenOk) + break; + if (tokenName.type_ == tokenObjectEnd && + (name.empty() || + features_.allowTrailingCommas_)) // empty object or trailing comma + return true; + name.clear(); + if (tokenName.type_ == tokenString) { + if (!decodeString(tokenName, name)) + return recoverFromError(tokenObjectEnd); + } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { + Value numberName; + if (!decodeNumber(tokenName, numberName)) + return recoverFromError(tokenObjectEnd); + name = numberName.asString(); + } else { + break; + } + if (name.length() >= (1U << 30)) + throwRuntimeError("keylength >= 2^30"); + if (features_.rejectDupKeys_ && currentValue().isMember(name)) { + String msg = "Duplicate key: '" + name + "'"; + return addErrorAndRecover(msg, tokenName, tokenObjectEnd); + } + + Token colon; + if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { + return addErrorAndRecover("Missing ':' after object member name", colon, + tokenObjectEnd); + } + Value& value = currentValue()[name]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); + if (!ok) // error already set + return recoverFromError(tokenObjectEnd); + + Token comma; + if (!readToken(comma) || + (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && + comma.type_ != tokenComment)) { + return addErrorAndRecover("Missing ',' or '}' in object declaration", + comma, tokenObjectEnd); + } + bool finalizeTokenOk = true; + while (comma.type_ == tokenComment && finalizeTokenOk) + finalizeTokenOk = readToken(comma); + if (comma.type_ == tokenObjectEnd) + return true; + } + return addErrorAndRecover("Missing '}' or object member name", tokenName, + tokenObjectEnd); +} + +bool OurReader::readArray(Token& token) { + Value init(arrayValue); + currentValue().swapPayload(init); + currentValue().setOffsetStart(token.start_ - begin_); + int index = 0; + for (;;) { + skipSpaces(); + if (current_ != end_ && *current_ == ']' && + (index == 0 || + (features_.allowTrailingCommas_ && + !features_.allowDroppedNullPlaceholders_))) // empty array or trailing + // comma + { + Token endArray; + readToken(endArray); + return true; + } + Value& value = currentValue()[index++]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); + if (!ok) // error already set + return recoverFromError(tokenArrayEnd); + + Token currentToken; + // Accept Comment after last item in the array. + ok = readToken(currentToken); + while (currentToken.type_ == tokenComment && ok) { + ok = readToken(currentToken); + } + bool badTokenType = (currentToken.type_ != tokenArraySeparator && + currentToken.type_ != tokenArrayEnd); + if (!ok || badTokenType) { + return addErrorAndRecover("Missing ',' or ']' in array declaration", + currentToken, tokenArrayEnd); + } + if (currentToken.type_ == tokenArrayEnd) + break; + } + return true; +} + +bool OurReader::decodeNumber(Token& token) { + Value decoded; + if (!decodeNumber(token, decoded)) + return false; + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool OurReader::decodeNumber(Token& token, Value& decoded) { + // Attempts to parse the number as an integer. If the number is + // larger than the maximum supported value of an integer then + // we decode the number as a double. + Location current = token.start_; + const bool isNegative = *current == '-'; + if (isNegative) { + ++current; + } + + // We assume we can represent the largest and smallest integer types as + // unsigned integers with separate sign. This is only true if they can fit + // into an unsigned integer. + static_assert(Value::maxLargestInt <= Value::maxLargestUInt, + "Int must be smaller than UInt"); + + // We need to convert minLargestInt into a positive number. The easiest way + // to do this conversion is to assume our "threshold" value of minLargestInt + // divided by 10 can fit in maxLargestInt when absolute valued. This should + // be a safe assumption. + static_assert(Value::minLargestInt <= -Value::maxLargestInt, + "The absolute value of minLargestInt must be greater than or " + "equal to maxLargestInt"); + static_assert(Value::minLargestInt / 10 >= -Value::maxLargestInt, + "The absolute value of minLargestInt must be only 1 magnitude " + "larger than maxLargest Int"); + + static constexpr Value::LargestUInt positive_threshold = + Value::maxLargestUInt / 10; + static constexpr Value::UInt positive_last_digit = Value::maxLargestUInt % 10; + + // For the negative values, we have to be more careful. Since typically + // -Value::minLargestInt will cause an overflow, we first divide by 10 and + // then take the inverse. This assumes that minLargestInt is only a single + // power of 10 different in magnitude, which we check above. For the last + // digit, we take the modulus before negating for the same reason. + static constexpr auto negative_threshold = + Value::LargestUInt(-(Value::minLargestInt / 10)); + static constexpr auto negative_last_digit = + Value::UInt(-(Value::minLargestInt % 10)); + + const Value::LargestUInt threshold = + isNegative ? negative_threshold : positive_threshold; + const Value::UInt max_last_digit = + isNegative ? negative_last_digit : positive_last_digit; + + Value::LargestUInt value = 0; + while (current < token.end_) { + Char c = *current++; + if (c < '0' || c > '9') + return decodeDouble(token, decoded); + + const auto digit(static_cast<Value::UInt>(c - '0')); + if (value >= threshold) { + // We've hit or exceeded the max value divided by 10 (rounded down). If + // a) we've only just touched the limit, meaing value == threshold, + // b) this is the last digit, or + // c) it's small enough to fit in that rounding delta, we're okay. + // Otherwise treat this number as a double to avoid overflow. + if (value > threshold || current != token.end_ || + digit > max_last_digit) { + return decodeDouble(token, decoded); + } + } + value = value * 10 + digit; + } + + if (isNegative) { + // We use the same magnitude assumption here, just in case. + const auto last_digit = static_cast<Value::UInt>(value % 10); + decoded = -Value::LargestInt(value / 10) * 10 - last_digit; + } else if (value <= Value::LargestUInt(Value::maxLargestInt)) { + decoded = Value::LargestInt(value); + } else { + decoded = value; + } + + return true; +} + +bool OurReader::decodeDouble(Token& token) { + Value decoded; + if (!decodeDouble(token, decoded)) + return false; + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool OurReader::decodeDouble(Token& token, Value& decoded) { + double value = 0; + const String buffer(token.start_, token.end_); + IStringStream is(buffer); + if (!(is >> value)) { + return addError( + "'" + String(token.start_, token.end_) + "' is not a number.", token); + } + decoded = value; + return true; +} + +bool OurReader::decodeString(Token& token) { + String decoded_string; + if (!decodeString(token, decoded_string)) + return false; + Value decoded(decoded_string); + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool OurReader::decodeString(Token& token, String& decoded) { + decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2)); + Location current = token.start_ + 1; // skip '"' + Location end = token.end_ - 1; // do not include '"' + while (current != end) { + Char c = *current++; + if (c == '"') + break; + if (c == '\\') { + if (current == end) + return addError("Empty escape sequence in string", token, current); + Char escape = *current++; + switch (escape) { + case '"': + decoded += '"'; + break; + case '/': + decoded += '/'; + break; + case '\\': + decoded += '\\'; + break; + case 'b': + decoded += '\b'; + break; + case 'f': + decoded += '\f'; + break; + case 'n': + decoded += '\n'; + break; + case 'r': + decoded += '\r'; + break; + case 't': + decoded += '\t'; + break; + case 'u': { + unsigned int unicode; + if (!decodeUnicodeCodePoint(token, current, end, unicode)) + return false; + decoded += codePointToUTF8(unicode); + } break; + default: + return addError("Bad escape sequence in string", token, current); + } + } else { + decoded += c; + } + } + return true; +} + +bool OurReader::decodeUnicodeCodePoint(Token& token, Location& current, + Location end, unsigned int& unicode) { + + if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) + return false; + if (unicode >= 0xD800 && unicode <= 0xDBFF) { + // surrogate pairs + if (end - current < 6) + return addError( + "additional six characters expected to parse unicode surrogate pair.", + token, current); + if (*(current++) == '\\' && *(current++) == 'u') { + unsigned int surrogatePair; + if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { + unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); + } else + return false; + } else + return addError("expecting another \\u token to begin the second half of " + "a unicode surrogate pair", + token, current); + } + return true; +} + +bool OurReader::decodeUnicodeEscapeSequence(Token& token, Location& current, + Location end, + unsigned int& ret_unicode) { + if (end - current < 4) + return addError( + "Bad unicode escape sequence in string: four digits expected.", token, + current); + int unicode = 0; + for (int index = 0; index < 4; ++index) { + Char c = *current++; + unicode *= 16; + if (c >= '0' && c <= '9') + unicode += c - '0'; + else if (c >= 'a' && c <= 'f') + unicode += c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + unicode += c - 'A' + 10; + else + return addError( + "Bad unicode escape sequence in string: hexadecimal digit expected.", + token, current); + } + ret_unicode = static_cast<unsigned int>(unicode); + return true; +} + +bool OurReader::addError(const String& message, Token& token, Location extra) { + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = extra; + errors_.push_back(info); + return false; +} + +bool OurReader::recoverFromError(TokenType skipUntilToken) { + size_t errorCount = errors_.size(); + Token skip; + for (;;) { + if (!readToken(skip)) + errors_.resize(errorCount); // discard errors caused by recovery + if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) + break; + } + errors_.resize(errorCount); + return false; +} + +bool OurReader::addErrorAndRecover(const String& message, Token& token, + TokenType skipUntilToken) { + addError(message, token); + return recoverFromError(skipUntilToken); +} + +Value& OurReader::currentValue() { return *(nodes_.top()); } + +OurReader::Char OurReader::getNextChar() { + if (current_ == end_) + return 0; + return *current_++; +} + +void OurReader::getLocationLineAndColumn(Location location, int& line, + int& column) const { + Location current = begin_; + Location lastLineStart = current; + line = 0; + while (current < location && current != end_) { + Char c = *current++; + if (c == '\r') { + if (*current == '\n') + ++current; + lastLineStart = current; + ++line; + } else if (c == '\n') { + lastLineStart = current; + ++line; + } + } + // column & line start at 1 + column = int(location - lastLineStart) + 1; + ++line; +} + +String OurReader::getLocationLineAndColumn(Location location) const { + int line, column; + getLocationLineAndColumn(location, line, column); + char buffer[18 + 16 + 16 + 1]; + jsoncpp_snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); + return buffer; +} + +String OurReader::getFormattedErrorMessages() const { + String formattedMessage; + for (const auto& error : errors_) { + formattedMessage += + "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; + formattedMessage += " " + error.message_ + "\n"; + if (error.extra_) + formattedMessage += + "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; + } + return formattedMessage; +} + +std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const { + std::vector<OurReader::StructuredError> allErrors; + for (const auto& error : errors_) { + OurReader::StructuredError structured; + structured.offset_start = error.token_.start_ - begin_; + structured.offset_limit = error.token_.end_ - begin_; + structured.message = error.message_; + allErrors.push_back(structured); + } + return allErrors; +} + +class OurCharReader : public CharReader { + bool const collectComments_; + OurReader reader_; + +public: + OurCharReader(bool collectComments, OurFeatures const& features) + : collectComments_(collectComments), reader_(features) {} + bool parse(char const* beginDoc, char const* endDoc, Value* root, + String* errs) override { + bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); + if (errs) { + *errs = reader_.getFormattedErrorMessages(); + } + return ok; + } +}; + +CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); } +CharReaderBuilder::~CharReaderBuilder() = default; +CharReader* CharReaderBuilder::newCharReader() const { + bool collectComments = settings_["collectComments"].asBool(); + OurFeatures features = OurFeatures::all(); + features.allowComments_ = settings_["allowComments"].asBool(); + features.allowTrailingCommas_ = settings_["allowTrailingCommas"].asBool(); + features.strictRoot_ = settings_["strictRoot"].asBool(); + features.allowDroppedNullPlaceholders_ = + settings_["allowDroppedNullPlaceholders"].asBool(); + features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool(); + features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool(); + + // Stack limit is always a size_t, so we get this as an unsigned int + // regardless of it we have 64-bit integer support enabled. + features.stackLimit_ = static_cast<size_t>(settings_["stackLimit"].asUInt()); + features.failIfExtra_ = settings_["failIfExtra"].asBool(); + features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool(); + features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool(); + features.skipBom_ = settings_["skipBom"].asBool(); + return new OurCharReader(collectComments, features); +} + +bool CharReaderBuilder::validate(Json::Value* invalid) const { + static const auto& valid_keys = *new std::set<String>{ + "collectComments", + "allowComments", + "allowTrailingCommas", + "strictRoot", + "allowDroppedNullPlaceholders", + "allowNumericKeys", + "allowSingleQuotes", + "stackLimit", + "failIfExtra", + "rejectDupKeys", + "allowSpecialFloats", + "skipBom", + }; + for (auto si = settings_.begin(); si != settings_.end(); ++si) { + auto key = si.name(); + if (valid_keys.count(key)) + continue; + if (invalid) + (*invalid)[std::move(key)] = *si; + else + return false; + } + return invalid ? invalid->empty() : true; +} + +Value& CharReaderBuilder::operator[](const String& key) { + return settings_[key]; +} +// static +void CharReaderBuilder::strictMode(Json::Value* settings) { + //! [CharReaderBuilderStrictMode] + (*settings)["allowComments"] = false; + (*settings)["allowTrailingCommas"] = false; + (*settings)["strictRoot"] = true; + (*settings)["allowDroppedNullPlaceholders"] = false; + (*settings)["allowNumericKeys"] = false; + (*settings)["allowSingleQuotes"] = false; + (*settings)["stackLimit"] = 1000; + (*settings)["failIfExtra"] = true; + (*settings)["rejectDupKeys"] = true; + (*settings)["allowSpecialFloats"] = false; + (*settings)["skipBom"] = true; + //! [CharReaderBuilderStrictMode] +} +// static +void CharReaderBuilder::setDefaults(Json::Value* settings) { + //! [CharReaderBuilderDefaults] + (*settings)["collectComments"] = true; + (*settings)["allowComments"] = true; + (*settings)["allowTrailingCommas"] = true; + (*settings)["strictRoot"] = false; + (*settings)["allowDroppedNullPlaceholders"] = false; + (*settings)["allowNumericKeys"] = false; + (*settings)["allowSingleQuotes"] = false; + (*settings)["stackLimit"] = 1000; + (*settings)["failIfExtra"] = false; + (*settings)["rejectDupKeys"] = false; + (*settings)["allowSpecialFloats"] = false; + (*settings)["skipBom"] = true; + //! [CharReaderBuilderDefaults] +} + +////////////////////////////////// +// global functions + +bool parseFromStream(CharReader::Factory const& fact, IStream& sin, Value* root, + String* errs) { + OStringStream ssin; + ssin << sin.rdbuf(); + String doc = ssin.str(); + char const* begin = doc.data(); + char const* end = begin + doc.size(); + // Note that we do not actually need a null-terminator. + CharReaderPtr const reader(fact.newCharReader()); + return reader->parse(begin, end, root, errs); +} + +IStream& operator>>(IStream& sin, Value& root) { + CharReaderBuilder b; + String errs; + bool ok = parseFromStream(b, sin, &root, &errs); + if (!ok) { + throwRuntimeError(errs); + } + return sin; +} + +} // namespace Json + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: src/lib_json/json_reader.cpp +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: src/lib_json/json_valueiterator.inl +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +// included by json_value.cpp + +namespace Json { + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueIteratorBase +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueIteratorBase::ValueIteratorBase() : current_() {} + +ValueIteratorBase::ValueIteratorBase( + const Value::ObjectValues::iterator& current) + : current_(current), isNull_(false) {} + +Value& ValueIteratorBase::deref() { return current_->second; } +const Value& ValueIteratorBase::deref() const { return current_->second; } + +void ValueIteratorBase::increment() { ++current_; } + +void ValueIteratorBase::decrement() { --current_; } + +ValueIteratorBase::difference_type +ValueIteratorBase::computeDistance(const SelfType& other) const { + // Iterator for null value are initialized using the default + // constructor, which initialize current_ to the default + // std::map::iterator. As begin() and end() are two instance + // of the default std::map::iterator, they can not be compared. + // To allow this, we handle this comparison specifically. + if (isNull_ && other.isNull_) { + return 0; + } + + // Usage of std::distance is not portable (does not compile with Sun Studio 12 + // RogueWave STL, + // which is the one used by default). + // Using a portable hand-made version for non random iterator instead: + // return difference_type( std::distance( current_, other.current_ ) ); + difference_type myDistance = 0; + for (Value::ObjectValues::iterator it = current_; it != other.current_; + ++it) { + ++myDistance; + } + return myDistance; +} + +bool ValueIteratorBase::isEqual(const SelfType& other) const { + if (isNull_) { + return other.isNull_; + } + return current_ == other.current_; +} + +void ValueIteratorBase::copy(const SelfType& other) { + current_ = other.current_; + isNull_ = other.isNull_; +} + +Value ValueIteratorBase::key() const { + const Value::CZString czstring = (*current_).first; + if (czstring.data()) { + if (czstring.isStaticString()) + return Value(StaticString(czstring.data())); + return Value(czstring.data(), czstring.data() + czstring.length()); + } + return Value(czstring.index()); +} + +UInt ValueIteratorBase::index() const { + const Value::CZString czstring = (*current_).first; + if (!czstring.data()) + return czstring.index(); + return Value::UInt(-1); +} + +String ValueIteratorBase::name() const { + char const* keey; + char const* end; + keey = memberName(&end); + if (!keey) + return String(); + return String(keey, end); +} + +char const* ValueIteratorBase::memberName() const { + const char* cname = (*current_).first.data(); + return cname ? cname : ""; +} + +char const* ValueIteratorBase::memberName(char const** end) const { + const char* cname = (*current_).first.data(); + if (!cname) { + *end = nullptr; + return nullptr; + } + *end = cname + (*current_).first.length(); + return cname; +} + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueConstIterator +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueConstIterator::ValueConstIterator() = default; + +ValueConstIterator::ValueConstIterator( + const Value::ObjectValues::iterator& current) + : ValueIteratorBase(current) {} + +ValueConstIterator::ValueConstIterator(ValueIterator const& other) + : ValueIteratorBase(other) {} + +ValueConstIterator& ValueConstIterator:: +operator=(const ValueIteratorBase& other) { + copy(other); + return *this; +} + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueIterator +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueIterator::ValueIterator() = default; + +ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current) + : ValueIteratorBase(current) {} + +ValueIterator::ValueIterator(const ValueConstIterator& other) + : ValueIteratorBase(other) { + throwRuntimeError("ConstIterator to Iterator should never be allowed."); +} + +ValueIterator::ValueIterator(const ValueIterator& other) = default; + +ValueIterator& ValueIterator::operator=(const SelfType& other) { + copy(other); + return *this; +} + +} // namespace Json + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: src/lib_json/json_valueiterator.inl +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: src/lib_json/json_value.cpp +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#if !defined(JSON_IS_AMALGAMATION) +#include <json/assertions.h> +#include <json/value.h> +#include <json/writer.h> +#endif // if !defined(JSON_IS_AMALGAMATION) +#include <algorithm> +#include <cassert> +#include <cmath> +#include <cstddef> +#include <cstring> +#include <iostream> +#include <sstream> +#include <utility> + +// Provide implementation equivalent of std::snprintf for older _MSC compilers +#if defined(_MSC_VER) && _MSC_VER < 1900 +#include <stdarg.h> +static int msvc_pre1900_c99_vsnprintf(char* outBuf, size_t size, + const char* format, va_list ap) { + int count = -1; + if (size != 0) + count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + return count; +} + +int JSON_API msvc_pre1900_c99_snprintf(char* outBuf, size_t size, + const char* format, ...) { + va_list ap; + va_start(ap, format); + const int count = msvc_pre1900_c99_vsnprintf(outBuf, size, format, ap); + va_end(ap); + return count; +} +#endif + +// Disable warning C4702 : unreachable code +#if defined(_MSC_VER) +#pragma warning(disable : 4702) +#endif + +#define JSON_ASSERT_UNREACHABLE assert(false) + +namespace Json { +template <typename T> +static std::unique_ptr<T> cloneUnique(const std::unique_ptr<T>& p) { + std::unique_ptr<T> r; + if (p) { + r = std::unique_ptr<T>(new T(*p)); + } + return r; +} + +// This is a walkaround to avoid the static initialization of Value::null. +// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of +// 8 (instead of 4) as a bit of future-proofing. +#if defined(__ARMEL__) +#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) +#else +#define ALIGNAS(byte_alignment) +#endif + +// static +Value const& Value::nullSingleton() { + static Value const nullStatic; + return nullStatic; +} + +#if JSON_USE_NULLREF +// for backwards compatibility, we'll leave these global references around, but +// DO NOT use them in JSONCPP library code any more! +// static +Value const& Value::null = Value::nullSingleton(); + +// static +Value const& Value::nullRef = Value::nullSingleton(); +#endif + +#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) +template <typename T, typename U> +static inline bool InRange(double d, T min, U max) { + // The casts can lose precision, but we are looking only for + // an approximate range. Might fail on edge cases though. ~cdunn + return d >= static_cast<double>(min) && d <= static_cast<double>(max); +} +#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) +static inline double integerToDouble(Json::UInt64 value) { + return static_cast<double>(Int64(value / 2)) * 2.0 + + static_cast<double>(Int64(value & 1)); +} + +template <typename T> static inline double integerToDouble(T value) { + return static_cast<double>(value); +} + +template <typename T, typename U> +static inline bool InRange(double d, T min, U max) { + return d >= integerToDouble(min) && d <= integerToDouble(max); +} +#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + +/** Duplicates the specified string value. + * @param value Pointer to the string to duplicate. Must be zero-terminated if + * length is "unknown". + * @param length Length of the value. if equals to unknown, then it will be + * computed using strlen(value). + * @return Pointer on the duplicate instance of string. + */ +static inline char* duplicateStringValue(const char* value, size_t length) { + // Avoid an integer overflow in the call to malloc below by limiting length + // to a sane value. + if (length >= static_cast<size_t>(Value::maxInt)) + length = Value::maxInt - 1; + + auto newString = static_cast<char*>(malloc(length + 1)); + if (newString == nullptr) { + throwRuntimeError("in Json::Value::duplicateStringValue(): " + "Failed to allocate string value buffer"); + } + memcpy(newString, value, length); + newString[length] = 0; + return newString; +} + +/* Record the length as a prefix. + */ +static inline char* duplicateAndPrefixStringValue(const char* value, + unsigned int length) { + // Avoid an integer overflow in the call to malloc below by limiting length + // to a sane value. + JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) - + sizeof(unsigned) - 1U, + "in Json::Value::duplicateAndPrefixStringValue(): " + "length too big for prefixing"); + size_t actualLength = sizeof(length) + length + 1; + auto newString = static_cast<char*>(malloc(actualLength)); + if (newString == nullptr) { + throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): " + "Failed to allocate string value buffer"); + } + *reinterpret_cast<unsigned*>(newString) = length; + memcpy(newString + sizeof(unsigned), value, length); + newString[actualLength - 1U] = + 0; // to avoid buffer over-run accidents by users later + return newString; +} +inline static void decodePrefixedString(bool isPrefixed, char const* prefixed, + unsigned* length, char const** value) { + if (!isPrefixed) { + *length = static_cast<unsigned>(strlen(prefixed)); + *value = prefixed; + } else { + *length = *reinterpret_cast<unsigned const*>(prefixed); + *value = prefixed + sizeof(unsigned); + } +} +/** Free the string duplicated by + * duplicateStringValue()/duplicateAndPrefixStringValue(). + */ +#if JSONCPP_USING_SECURE_MEMORY +static inline void releasePrefixedStringValue(char* value) { + unsigned length = 0; + char const* valueDecoded; + decodePrefixedString(true, value, &length, &valueDecoded); + size_t const size = sizeof(unsigned) + length + 1U; + memset(value, 0, size); + free(value); +} +static inline void releaseStringValue(char* value, unsigned length) { + // length==0 => we allocated the strings memory + size_t size = (length == 0) ? strlen(value) : length; + memset(value, 0, size); + free(value); +} +#else // !JSONCPP_USING_SECURE_MEMORY +static inline void releasePrefixedStringValue(char* value) { free(value); } +static inline void releaseStringValue(char* value, unsigned) { free(value); } +#endif // JSONCPP_USING_SECURE_MEMORY + +} // namespace Json + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ValueInternals... +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +#if !defined(JSON_IS_AMALGAMATION) + +#include "json_valueiterator.inl" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +#if JSON_USE_EXCEPTION +Exception::Exception(String msg) : msg_(std::move(msg)) {} +Exception::~Exception() noexcept = default; +char const* Exception::what() const noexcept { return msg_.c_str(); } +RuntimeError::RuntimeError(String const& msg) : Exception(msg) {} +LogicError::LogicError(String const& msg) : Exception(msg) {} +JSONCPP_NORETURN void throwRuntimeError(String const& msg) { + throw RuntimeError(msg); +} +JSONCPP_NORETURN void throwLogicError(String const& msg) { + throw LogicError(msg); +} +#else // !JSON_USE_EXCEPTION +JSONCPP_NORETURN void throwRuntimeError(String const& msg) { + std::cerr << msg << std::endl; + abort(); +} +JSONCPP_NORETURN void throwLogicError(String const& msg) { + std::cerr << msg << std::endl; + abort(); +} +#endif + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class Value::CZString +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +// Notes: policy_ indicates if the string was allocated when +// a string is stored. + +Value::CZString::CZString(ArrayIndex index) : cstr_(nullptr), index_(index) {} + +Value::CZString::CZString(char const* str, unsigned length, + DuplicationPolicy allocate) + : cstr_(str) { + // allocate != duplicate + storage_.policy_ = allocate & 0x3; + storage_.length_ = length & 0x3FFFFFFF; +} + +Value::CZString::CZString(const CZString& other) { + cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != nullptr + ? duplicateStringValue(other.cstr_, other.storage_.length_) + : other.cstr_); + storage_.policy_ = + static_cast<unsigned>( + other.cstr_ + ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == + noDuplication + ? noDuplication + : duplicate) + : static_cast<DuplicationPolicy>(other.storage_.policy_)) & + 3U; + storage_.length_ = other.storage_.length_; +} + +Value::CZString::CZString(CZString&& other) + : cstr_(other.cstr_), index_(other.index_) { + other.cstr_ = nullptr; +} + +Value::CZString::~CZString() { + if (cstr_ && storage_.policy_ == duplicate) { + releaseStringValue(const_cast<char*>(cstr_), + storage_.length_ + 1U); // +1 for null terminating + // character for sake of + // completeness but not actually + // necessary + } +} + +void Value::CZString::swap(CZString& other) { + std::swap(cstr_, other.cstr_); + std::swap(index_, other.index_); +} + +Value::CZString& Value::CZString::operator=(const CZString& other) { + cstr_ = other.cstr_; + index_ = other.index_; + return *this; +} + +Value::CZString& Value::CZString::operator=(CZString&& other) { + cstr_ = other.cstr_; + index_ = other.index_; + other.cstr_ = nullptr; + return *this; +} + +bool Value::CZString::operator<(const CZString& other) const { + if (!cstr_) + return index_ < other.index_; + // return strcmp(cstr_, other.cstr_) < 0; + // Assume both are strings. + unsigned this_len = this->storage_.length_; + unsigned other_len = other.storage_.length_; + unsigned min_len = std::min<unsigned>(this_len, other_len); + JSON_ASSERT(this->cstr_ && other.cstr_); + int comp = memcmp(this->cstr_, other.cstr_, min_len); + if (comp < 0) + return true; + if (comp > 0) + return false; + return (this_len < other_len); +} + +bool Value::CZString::operator==(const CZString& other) const { + if (!cstr_) + return index_ == other.index_; + // return strcmp(cstr_, other.cstr_) == 0; + // Assume both are strings. + unsigned this_len = this->storage_.length_; + unsigned other_len = other.storage_.length_; + if (this_len != other_len) + return false; + JSON_ASSERT(this->cstr_ && other.cstr_); + int comp = memcmp(this->cstr_, other.cstr_, this_len); + return comp == 0; +} + +ArrayIndex Value::CZString::index() const { return index_; } + +// const char* Value::CZString::c_str() const { return cstr_; } +const char* Value::CZString::data() const { return cstr_; } +unsigned Value::CZString::length() const { return storage_.length_; } +bool Value::CZString::isStaticString() const { + return storage_.policy_ == noDuplication; +} + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class Value::Value +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +/*! \internal Default constructor initialization must be equivalent to: + * memset( this, 0, sizeof(Value) ) + * This optimization is used in ValueInternalMap fast allocator. + */ +Value::Value(ValueType type) { + static char const emptyString[] = ""; + initBasic(type); + switch (type) { + case nullValue: + break; + case intValue: + case uintValue: + value_.int_ = 0; + break; + case realValue: + value_.real_ = 0.0; + break; + case stringValue: + // allocated_ == false, so this is safe. + value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString)); + break; + case arrayValue: + case objectValue: + value_.map_ = new ObjectValues(); + break; + case booleanValue: + value_.bool_ = false; + break; + default: + JSON_ASSERT_UNREACHABLE; + } +} + +Value::Value(Int value) { + initBasic(intValue); + value_.int_ = value; +} + +Value::Value(UInt value) { + initBasic(uintValue); + value_.uint_ = value; +} +#if defined(JSON_HAS_INT64) +Value::Value(Int64 value) { + initBasic(intValue); + value_.int_ = value; +} +Value::Value(UInt64 value) { + initBasic(uintValue); + value_.uint_ = value; +} +#endif // defined(JSON_HAS_INT64) + +Value::Value(double value) { + initBasic(realValue); + value_.real_ = value; +} + +Value::Value(const char* value) { + initBasic(stringValue, true); + JSON_ASSERT_MESSAGE(value != nullptr, + "Null Value Passed to Value Constructor"); + value_.string_ = duplicateAndPrefixStringValue( + value, static_cast<unsigned>(strlen(value))); +} + +Value::Value(const char* begin, const char* end) { + initBasic(stringValue, true); + value_.string_ = + duplicateAndPrefixStringValue(begin, static_cast<unsigned>(end - begin)); +} + +Value::Value(const String& value) { + initBasic(stringValue, true); + value_.string_ = duplicateAndPrefixStringValue( + value.data(), static_cast<unsigned>(value.length())); +} + +Value::Value(const StaticString& value) { + initBasic(stringValue); + value_.string_ = const_cast<char*>(value.c_str()); +} + +Value::Value(bool value) { + initBasic(booleanValue); + value_.bool_ = value; +} + +Value::Value(const Value& other) { + dupPayload(other); + dupMeta(other); +} + +Value::Value(Value&& other) { + initBasic(nullValue); + swap(other); +} + +Value::~Value() { + releasePayload(); + value_.uint_ = 0; +} + +Value& Value::operator=(const Value& other) { + Value(other).swap(*this); + return *this; +} + +Value& Value::operator=(Value&& other) { + other.swap(*this); + return *this; +} + +void Value::swapPayload(Value& other) { + std::swap(bits_, other.bits_); + std::swap(value_, other.value_); +} + +void Value::copyPayload(const Value& other) { + releasePayload(); + dupPayload(other); +} + +void Value::swap(Value& other) { + swapPayload(other); + std::swap(comments_, other.comments_); + std::swap(start_, other.start_); + std::swap(limit_, other.limit_); +} + +void Value::copy(const Value& other) { + copyPayload(other); + dupMeta(other); +} + +ValueType Value::type() const { + return static_cast<ValueType>(bits_.value_type_); +} + +int Value::compare(const Value& other) const { + if (*this < other) + return -1; + if (*this > other) + return 1; + return 0; +} + +bool Value::operator<(const Value& other) const { + int typeDelta = type() - other.type(); + if (typeDelta) + return typeDelta < 0; + switch (type()) { + case nullValue: + return false; + case intValue: + return value_.int_ < other.value_.int_; + case uintValue: + return value_.uint_ < other.value_.uint_; + case realValue: + return value_.real_ < other.value_.real_; + case booleanValue: + return value_.bool_ < other.value_.bool_; + case stringValue: { + if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) { + return other.value_.string_ != nullptr; + } + unsigned this_len; + unsigned other_len; + char const* this_str; + char const* other_str; + decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len, + &this_str); + decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len, + &other_str); + unsigned min_len = std::min<unsigned>(this_len, other_len); + JSON_ASSERT(this_str && other_str); + int comp = memcmp(this_str, other_str, min_len); + if (comp < 0) + return true; + if (comp > 0) + return false; + return (this_len < other_len); + } + case arrayValue: + case objectValue: { + auto thisSize = value_.map_->size(); + auto otherSize = other.value_.map_->size(); + if (thisSize != otherSize) + return thisSize < otherSize; + return (*value_.map_) < (*other.value_.map_); + } + default: + JSON_ASSERT_UNREACHABLE; + } + return false; // unreachable +} + +bool Value::operator<=(const Value& other) const { return !(other < *this); } + +bool Value::operator>=(const Value& other) const { return !(*this < other); } + +bool Value::operator>(const Value& other) const { return other < *this; } + +bool Value::operator==(const Value& other) const { + if (type() != other.type()) + return false; + switch (type()) { + case nullValue: + return true; + case intValue: + return value_.int_ == other.value_.int_; + case uintValue: + return value_.uint_ == other.value_.uint_; + case realValue: + return value_.real_ == other.value_.real_; + case booleanValue: + return value_.bool_ == other.value_.bool_; + case stringValue: { + if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) { + return (value_.string_ == other.value_.string_); + } + unsigned this_len; + unsigned other_len; + char const* this_str; + char const* other_str; + decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len, + &this_str); + decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len, + &other_str); + if (this_len != other_len) + return false; + JSON_ASSERT(this_str && other_str); + int comp = memcmp(this_str, other_str, this_len); + return comp == 0; + } + case arrayValue: + case objectValue: + return value_.map_->size() == other.value_.map_->size() && + (*value_.map_) == (*other.value_.map_); + default: + JSON_ASSERT_UNREACHABLE; + } + return false; // unreachable +} + +bool Value::operator!=(const Value& other) const { return !(*this == other); } + +const char* Value::asCString() const { + JSON_ASSERT_MESSAGE(type() == stringValue, + "in Json::Value::asCString(): requires stringValue"); + if (value_.string_ == nullptr) + return nullptr; + unsigned this_len; + char const* this_str; + decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len, + &this_str); + return this_str; +} + +#if JSONCPP_USING_SECURE_MEMORY +unsigned Value::getCStringLength() const { + JSON_ASSERT_MESSAGE(type() == stringValue, + "in Json::Value::asCString(): requires stringValue"); + if (value_.string_ == 0) + return 0; + unsigned this_len; + char const* this_str; + decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len, + &this_str); + return this_len; +} +#endif + +bool Value::getString(char const** begin, char const** end) const { + if (type() != stringValue) + return false; + if (value_.string_ == nullptr) + return false; + unsigned length; + decodePrefixedString(this->isAllocated(), this->value_.string_, &length, + begin); + *end = *begin + length; + return true; +} + +String Value::asString() const { + switch (type()) { + case nullValue: + return ""; + case stringValue: { + if (value_.string_ == nullptr) + return ""; + unsigned this_len; + char const* this_str; + decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len, + &this_str); + return String(this_str, this_len); + } + case booleanValue: + return value_.bool_ ? "true" : "false"; + case intValue: + return valueToString(value_.int_); + case uintValue: + return valueToString(value_.uint_); + case realValue: + return valueToString(value_.real_); + default: + JSON_FAIL_MESSAGE("Type is not convertible to string"); + } +} + +Value::Int Value::asInt() const { + switch (type()) { + case intValue: + JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range"); + return Int(value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range"); + return Int(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt), + "double out of Int range"); + return Int(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to Int."); +} + +Value::UInt Value::asUInt() const { + switch (type()) { + case intValue: + JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range"); + return UInt(value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range"); + return UInt(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt), + "double out of UInt range"); + return UInt(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to UInt."); +} + +#if defined(JSON_HAS_INT64) + +Value::Int64 Value::asInt64() const { + switch (type()) { + case intValue: + return Int64(value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range"); + return Int64(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), + "double out of Int64 range"); + return Int64(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to Int64."); +} + +Value::UInt64 Value::asUInt64() const { + switch (type()) { + case intValue: + JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range"); + return UInt64(value_.int_); + case uintValue: + return UInt64(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64), + "double out of UInt64 range"); + return UInt64(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to UInt64."); +} +#endif // if defined(JSON_HAS_INT64) + +LargestInt Value::asLargestInt() const { +#if defined(JSON_NO_INT64) + return asInt(); +#else + return asInt64(); +#endif +} + +LargestUInt Value::asLargestUInt() const { +#if defined(JSON_NO_INT64) + return asUInt(); +#else + return asUInt64(); +#endif +} + +double Value::asDouble() const { + switch (type()) { + case intValue: + return static_cast<double>(value_.int_); + case uintValue: +#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return static_cast<double>(value_.uint_); +#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return integerToDouble(value_.uint_); +#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + case realValue: + return value_.real_; + case nullValue: + return 0.0; + case booleanValue: + return value_.bool_ ? 1.0 : 0.0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to double."); +} + +float Value::asFloat() const { + switch (type()) { + case intValue: + return static_cast<float>(value_.int_); + case uintValue: +#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return static_cast<float>(value_.uint_); +#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + // This can fail (silently?) if the value is bigger than MAX_FLOAT. + return static_cast<float>(integerToDouble(value_.uint_)); +#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + case realValue: + return static_cast<float>(value_.real_); + case nullValue: + return 0.0; + case booleanValue: + return value_.bool_ ? 1.0F : 0.0F; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to float."); +} + +bool Value::asBool() const { + switch (type()) { + case booleanValue: + return value_.bool_; + case nullValue: + return false; + case intValue: + return value_.int_ != 0; + case uintValue: + return value_.uint_ != 0; + case realValue: { + // According to JavaScript language zero or NaN is regarded as false + const auto value_classification = std::fpclassify(value_.real_); + return value_classification != FP_ZERO && value_classification != FP_NAN; + } + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to bool."); +} + +bool Value::isConvertibleTo(ValueType other) const { + switch (other) { + case nullValue: + return (isNumeric() && asDouble() == 0.0) || + (type() == booleanValue && !value_.bool_) || + (type() == stringValue && asString().empty()) || + (type() == arrayValue && value_.map_->empty()) || + (type() == objectValue && value_.map_->empty()) || + type() == nullValue; + case intValue: + return isInt() || + (type() == realValue && InRange(value_.real_, minInt, maxInt)) || + type() == booleanValue || type() == nullValue; + case uintValue: + return isUInt() || + (type() == realValue && InRange(value_.real_, 0, maxUInt)) || + type() == booleanValue || type() == nullValue; + case realValue: + return isNumeric() || type() == booleanValue || type() == nullValue; + case booleanValue: + return isNumeric() || type() == booleanValue || type() == nullValue; + case stringValue: + return isNumeric() || type() == booleanValue || type() == stringValue || + type() == nullValue; + case arrayValue: + return type() == arrayValue || type() == nullValue; + case objectValue: + return type() == objectValue || type() == nullValue; + } + JSON_ASSERT_UNREACHABLE; + return false; +} + +/// Number of values in array or object +ArrayIndex Value::size() const { + switch (type()) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + case stringValue: + return 0; + case arrayValue: // size of the array is highest index + 1 + if (!value_.map_->empty()) { + ObjectValues::const_iterator itLast = value_.map_->end(); + --itLast; + return (*itLast).first.index() + 1; + } + return 0; + case objectValue: + return ArrayIndex(value_.map_->size()); + } + JSON_ASSERT_UNREACHABLE; + return 0; // unreachable; +} + +bool Value::empty() const { + if (isNull() || isArray() || isObject()) + return size() == 0U; + return false; +} + +Value::operator bool() const { return !isNull(); } + +void Value::clear() { + JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue || + type() == objectValue, + "in Json::Value::clear(): requires complex value"); + start_ = 0; + limit_ = 0; + switch (type()) { + case arrayValue: + case objectValue: + value_.map_->clear(); + break; + default: + break; + } +} + +void Value::resize(ArrayIndex newSize) { + JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue, + "in Json::Value::resize(): requires arrayValue"); + if (type() == nullValue) + *this = Value(arrayValue); + ArrayIndex oldSize = size(); + if (newSize == 0) + clear(); + else if (newSize > oldSize) + this->operator[](newSize - 1); + else { + for (ArrayIndex index = newSize; index < oldSize; ++index) { + value_.map_->erase(index); + } + JSON_ASSERT(size() == newSize); + } +} + +Value& Value::operator[](ArrayIndex index) { + JSON_ASSERT_MESSAGE( + type() == nullValue || type() == arrayValue, + "in Json::Value::operator[](ArrayIndex): requires arrayValue"); + if (type() == nullValue) + *this = Value(arrayValue); + CZString key(index); + auto it = value_.map_->lower_bound(key); + if (it != value_.map_->end() && (*it).first == key) + return (*it).second; + + ObjectValues::value_type defaultValue(key, nullSingleton()); + it = value_.map_->insert(it, defaultValue); + return (*it).second; +} + +Value& Value::operator[](int index) { + JSON_ASSERT_MESSAGE( + index >= 0, + "in Json::Value::operator[](int index): index cannot be negative"); + return (*this)[ArrayIndex(index)]; +} + +const Value& Value::operator[](ArrayIndex index) const { + JSON_ASSERT_MESSAGE( + type() == nullValue || type() == arrayValue, + "in Json::Value::operator[](ArrayIndex)const: requires arrayValue"); + if (type() == nullValue) + return nullSingleton(); + CZString key(index); + ObjectValues::const_iterator it = value_.map_->find(key); + if (it == value_.map_->end()) + return nullSingleton(); + return (*it).second; +} + +const Value& Value::operator[](int index) const { + JSON_ASSERT_MESSAGE( + index >= 0, + "in Json::Value::operator[](int index) const: index cannot be negative"); + return (*this)[ArrayIndex(index)]; +} + +void Value::initBasic(ValueType type, bool allocated) { + setType(type); + setIsAllocated(allocated); + comments_ = Comments{}; + start_ = 0; + limit_ = 0; +} + +void Value::dupPayload(const Value& other) { + setType(other.type()); + setIsAllocated(false); + switch (type()) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + value_ = other.value_; + break; + case stringValue: + if (other.value_.string_ && other.isAllocated()) { + unsigned len; + char const* str; + decodePrefixedString(other.isAllocated(), other.value_.string_, &len, + &str); + value_.string_ = duplicateAndPrefixStringValue(str, len); + setIsAllocated(true); + } else { + value_.string_ = other.value_.string_; + } + break; + case arrayValue: + case objectValue: + value_.map_ = new ObjectValues(*other.value_.map_); + break; + default: + JSON_ASSERT_UNREACHABLE; + } +} + +void Value::releasePayload() { + switch (type()) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + break; + case stringValue: + if (isAllocated()) + releasePrefixedStringValue(value_.string_); + break; + case arrayValue: + case objectValue: + delete value_.map_; + break; + default: + JSON_ASSERT_UNREACHABLE; + } +} + +void Value::dupMeta(const Value& other) { + comments_ = other.comments_; + start_ = other.start_; + limit_ = other.limit_; +} + +// Access an object value by name, create a null member if it does not exist. +// @pre Type of '*this' is object or null. +// @param key is null-terminated. +Value& Value::resolveReference(const char* key) { + JSON_ASSERT_MESSAGE( + type() == nullValue || type() == objectValue, + "in Json::Value::resolveReference(): requires objectValue"); + if (type() == nullValue) + *this = Value(objectValue); + CZString actualKey(key, static_cast<unsigned>(strlen(key)), + CZString::noDuplication); // NOTE! + auto it = value_.map_->lower_bound(actualKey); + if (it != value_.map_->end() && (*it).first == actualKey) + return (*it).second; + + ObjectValues::value_type defaultValue(actualKey, nullSingleton()); + it = value_.map_->insert(it, defaultValue); + Value& value = (*it).second; + return value; +} + +// @param key is not null-terminated. +Value& Value::resolveReference(char const* key, char const* end) { + JSON_ASSERT_MESSAGE( + type() == nullValue || type() == objectValue, + "in Json::Value::resolveReference(key, end): requires objectValue"); + if (type() == nullValue) + *this = Value(objectValue); + CZString actualKey(key, static_cast<unsigned>(end - key), + CZString::duplicateOnCopy); + auto it = value_.map_->lower_bound(actualKey); + if (it != value_.map_->end() && (*it).first == actualKey) + return (*it).second; + + ObjectValues::value_type defaultValue(actualKey, nullSingleton()); + it = value_.map_->insert(it, defaultValue); + Value& value = (*it).second; + return value; +} + +Value Value::get(ArrayIndex index, const Value& defaultValue) const { + const Value* value = &((*this)[index]); + return value == &nullSingleton() ? defaultValue : *value; +} + +bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } + +Value const* Value::find(char const* begin, char const* end) const { + JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, + "in Json::Value::find(begin, end): requires " + "objectValue or nullValue"); + if (type() == nullValue) + return nullptr; + CZString actualKey(begin, static_cast<unsigned>(end - begin), + CZString::noDuplication); + ObjectValues::const_iterator it = value_.map_->find(actualKey); + if (it == value_.map_->end()) + return nullptr; + return &(*it).second; +} +Value* Value::demand(char const* begin, char const* end) { + JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, + "in Json::Value::demand(begin, end): requires " + "objectValue or nullValue"); + return &resolveReference(begin, end); +} +const Value& Value::operator[](const char* key) const { + Value const* found = find(key, key + strlen(key)); + if (!found) + return nullSingleton(); + return *found; +} +Value const& Value::operator[](const String& key) const { + Value const* found = find(key.data(), key.data() + key.length()); + if (!found) + return nullSingleton(); + return *found; +} + +Value& Value::operator[](const char* key) { + return resolveReference(key, key + strlen(key)); +} + +Value& Value::operator[](const String& key) { + return resolveReference(key.data(), key.data() + key.length()); +} + +Value& Value::operator[](const StaticString& key) { + return resolveReference(key.c_str()); +} + +Value& Value::append(const Value& value) { return append(Value(value)); } + +Value& Value::append(Value&& value) { + JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue, + "in Json::Value::append: requires arrayValue"); + if (type() == nullValue) { + *this = Value(arrayValue); + } + return this->value_.map_->emplace(size(), std::move(value)).first->second; +} + +bool Value::insert(ArrayIndex index, const Value& newValue) { + return insert(index, Value(newValue)); +} + +bool Value::insert(ArrayIndex index, Value&& newValue) { + JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue, + "in Json::Value::insert: requires arrayValue"); + ArrayIndex length = size(); + if (index > length) { + return false; + } + for (ArrayIndex i = length; i > index; i--) { + (*this)[i] = std::move((*this)[i - 1]); + } + (*this)[index] = std::move(newValue); + return true; +} + +Value Value::get(char const* begin, char const* end, + Value const& defaultValue) const { + Value const* found = find(begin, end); + return !found ? defaultValue : *found; +} +Value Value::get(char const* key, Value const& defaultValue) const { + return get(key, key + strlen(key), defaultValue); +} +Value Value::get(String const& key, Value const& defaultValue) const { + return get(key.data(), key.data() + key.length(), defaultValue); +} + +bool Value::removeMember(const char* begin, const char* end, Value* removed) { + if (type() != objectValue) { + return false; + } + CZString actualKey(begin, static_cast<unsigned>(end - begin), + CZString::noDuplication); + auto it = value_.map_->find(actualKey); + if (it == value_.map_->end()) + return false; + if (removed) + *removed = std::move(it->second); + value_.map_->erase(it); + return true; +} +bool Value::removeMember(const char* key, Value* removed) { + return removeMember(key, key + strlen(key), removed); +} +bool Value::removeMember(String const& key, Value* removed) { + return removeMember(key.data(), key.data() + key.length(), removed); +} +void Value::removeMember(const char* key) { + JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, + "in Json::Value::removeMember(): requires objectValue"); + if (type() == nullValue) + return; + + CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication); + value_.map_->erase(actualKey); +} +void Value::removeMember(const String& key) { removeMember(key.c_str()); } + +bool Value::removeIndex(ArrayIndex index, Value* removed) { + if (type() != arrayValue) { + return false; + } + CZString key(index); + auto it = value_.map_->find(key); + if (it == value_.map_->end()) { + return false; + } + if (removed) + *removed = it->second; + ArrayIndex oldSize = size(); + // shift left all items left, into the place of the "removed" + for (ArrayIndex i = index; i < (oldSize - 1); ++i) { + CZString keey(i); + (*value_.map_)[keey] = (*this)[i + 1]; + } + // erase the last one ("leftover") + CZString keyLast(oldSize - 1); + auto itLast = value_.map_->find(keyLast); + value_.map_->erase(itLast); + return true; +} + +bool Value::isMember(char const* begin, char const* end) const { + Value const* value = find(begin, end); + return nullptr != value; +} +bool Value::isMember(char const* key) const { + return isMember(key, key + strlen(key)); +} +bool Value::isMember(String const& key) const { + return isMember(key.data(), key.data() + key.length()); +} + +Value::Members Value::getMemberNames() const { + JSON_ASSERT_MESSAGE( + type() == nullValue || type() == objectValue, + "in Json::Value::getMemberNames(), value must be objectValue"); + if (type() == nullValue) + return Value::Members(); + Members members; + members.reserve(value_.map_->size()); + ObjectValues::const_iterator it = value_.map_->begin(); + ObjectValues::const_iterator itEnd = value_.map_->end(); + for (; it != itEnd; ++it) { + members.push_back(String((*it).first.data(), (*it).first.length())); + } + return members; +} + +static bool IsIntegral(double d) { + double integral_part; + return modf(d, &integral_part) == 0.0; +} + +bool Value::isNull() const { return type() == nullValue; } + +bool Value::isBool() const { return type() == booleanValue; } + +bool Value::isInt() const { + switch (type()) { + case intValue: +#if defined(JSON_HAS_INT64) + return value_.int_ >= minInt && value_.int_ <= maxInt; +#else + return true; +#endif + case uintValue: + return value_.uint_ <= UInt(maxInt); + case realValue: + return value_.real_ >= minInt && value_.real_ <= maxInt && + IsIntegral(value_.real_); + default: + break; + } + return false; +} + +bool Value::isUInt() const { + switch (type()) { + case intValue: +#if defined(JSON_HAS_INT64) + return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt); +#else + return value_.int_ >= 0; +#endif + case uintValue: +#if defined(JSON_HAS_INT64) + return value_.uint_ <= maxUInt; +#else + return true; +#endif + case realValue: + return value_.real_ >= 0 && value_.real_ <= maxUInt && + IsIntegral(value_.real_); + default: + break; + } + return false; +} + +bool Value::isInt64() const { +#if defined(JSON_HAS_INT64) + switch (type()) { + case intValue: + return true; + case uintValue: + return value_.uint_ <= UInt64(maxInt64); + case realValue: + // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a + // double, so double(maxInt64) will be rounded up to 2^63. Therefore we + // require the value to be strictly less than the limit. + return value_.real_ >= double(minInt64) && + value_.real_ < double(maxInt64) && IsIntegral(value_.real_); + default: + break; + } +#endif // JSON_HAS_INT64 + return false; +} + +bool Value::isUInt64() const { +#if defined(JSON_HAS_INT64) + switch (type()) { + case intValue: + return value_.int_ >= 0; + case uintValue: + return true; + case realValue: + // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a + // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we + // require the value to be strictly less than the limit. + return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble && + IsIntegral(value_.real_); + default: + break; + } +#endif // JSON_HAS_INT64 + return false; +} + +bool Value::isIntegral() const { + switch (type()) { + case intValue: + case uintValue: + return true; + case realValue: +#if defined(JSON_HAS_INT64) + // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a + // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we + // require the value to be strictly less than the limit. + return value_.real_ >= double(minInt64) && + value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_); +#else + return value_.real_ >= minInt && value_.real_ <= maxUInt && + IsIntegral(value_.real_); +#endif // JSON_HAS_INT64 + default: + break; + } + return false; +} + +bool Value::isDouble() const { + return type() == intValue || type() == uintValue || type() == realValue; +} + +bool Value::isNumeric() const { return isDouble(); } + +bool Value::isString() const { return type() == stringValue; } + +bool Value::isArray() const { return type() == arrayValue; } + +bool Value::isObject() const { return type() == objectValue; } + +Value::Comments::Comments(const Comments& that) + : ptr_{cloneUnique(that.ptr_)} {} + +Value::Comments::Comments(Comments&& that) : ptr_{std::move(that.ptr_)} {} + +Value::Comments& Value::Comments::operator=(const Comments& that) { + ptr_ = cloneUnique(that.ptr_); + return *this; +} + +Value::Comments& Value::Comments::operator=(Comments&& that) { + ptr_ = std::move(that.ptr_); + return *this; +} + +bool Value::Comments::has(CommentPlacement slot) const { + return ptr_ && !(*ptr_)[slot].empty(); +} + +String Value::Comments::get(CommentPlacement slot) const { + if (!ptr_) + return {}; + return (*ptr_)[slot]; +} + +void Value::Comments::set(CommentPlacement slot, String comment) { + if (!ptr_) { + ptr_ = std::unique_ptr<Array>(new Array()); + } + // check comments array boundry. + if (slot < CommentPlacement::numberOfCommentPlacement) { + (*ptr_)[slot] = std::move(comment); + } +} + +void Value::setComment(String comment, CommentPlacement placement) { + if (!comment.empty() && (comment.back() == '\n')) { + // Always discard trailing newline, to aid indentation. + comment.pop_back(); + } + JSON_ASSERT(!comment.empty()); + JSON_ASSERT_MESSAGE( + comment[0] == '\0' || comment[0] == '/', + "in Json::Value::setComment(): Comments must start with /"); + comments_.set(placement, std::move(comment)); +} + +bool Value::hasComment(CommentPlacement placement) const { + return comments_.has(placement); +} + +String Value::getComment(CommentPlacement placement) const { + return comments_.get(placement); +} + +void Value::setOffsetStart(ptrdiff_t start) { start_ = start; } + +void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; } + +ptrdiff_t Value::getOffsetStart() const { return start_; } + +ptrdiff_t Value::getOffsetLimit() const { return limit_; } + +String Value::toStyledString() const { + StreamWriterBuilder builder; + + String out = this->hasComment(commentBefore) ? "\n" : ""; + out += Json::writeString(builder, *this); + out += '\n'; + + return out; +} + +Value::const_iterator Value::begin() const { + switch (type()) { + case arrayValue: + case objectValue: + if (value_.map_) + return const_iterator(value_.map_->begin()); + break; + default: + break; + } + return {}; +} + +Value::const_iterator Value::end() const { + switch (type()) { + case arrayValue: + case objectValue: + if (value_.map_) + return const_iterator(value_.map_->end()); + break; + default: + break; + } + return {}; +} + +Value::iterator Value::begin() { + switch (type()) { + case arrayValue: + case objectValue: + if (value_.map_) + return iterator(value_.map_->begin()); + break; + default: + break; + } + return iterator(); +} + +Value::iterator Value::end() { + switch (type()) { + case arrayValue: + case objectValue: + if (value_.map_) + return iterator(value_.map_->end()); + break; + default: + break; + } + return iterator(); +} + +// class PathArgument +// ////////////////////////////////////////////////////////////////// + +PathArgument::PathArgument() = default; + +PathArgument::PathArgument(ArrayIndex index) + : index_(index), kind_(kindIndex) {} + +PathArgument::PathArgument(const char* key) : key_(key), kind_(kindKey) {} + +PathArgument::PathArgument(String key) : key_(std::move(key)), kind_(kindKey) {} + +// class Path +// ////////////////////////////////////////////////////////////////// + +Path::Path(const String& path, const PathArgument& a1, const PathArgument& a2, + const PathArgument& a3, const PathArgument& a4, + const PathArgument& a5) { + InArgs in; + in.reserve(5); + in.push_back(&a1); + in.push_back(&a2); + in.push_back(&a3); + in.push_back(&a4); + in.push_back(&a5); + makePath(path, in); +} + +void Path::makePath(const String& path, const InArgs& in) { + const char* current = path.c_str(); + const char* end = current + path.length(); + auto itInArg = in.begin(); + while (current != end) { + if (*current == '[') { + ++current; + if (*current == '%') + addPathInArg(path, in, itInArg, PathArgument::kindIndex); + else { + ArrayIndex index = 0; + for (; current != end && *current >= '0' && *current <= '9'; ++current) + index = index * 10 + ArrayIndex(*current - '0'); + args_.push_back(index); + } + if (current == end || *++current != ']') + invalidPath(path, int(current - path.c_str())); + } else if (*current == '%') { + addPathInArg(path, in, itInArg, PathArgument::kindKey); + ++current; + } else if (*current == '.' || *current == ']') { + ++current; + } else { + const char* beginName = current; + while (current != end && !strchr("[.", *current)) + ++current; + args_.push_back(String(beginName, current)); + } + } +} + +void Path::addPathInArg(const String& /*path*/, const InArgs& in, + InArgs::const_iterator& itInArg, + PathArgument::Kind kind) { + if (itInArg == in.end()) { + // Error: missing argument %d + } else if ((*itInArg)->kind_ != kind) { + // Error: bad argument type + } else { + args_.push_back(**itInArg++); + } +} + +void Path::invalidPath(const String& /*path*/, int /*location*/) { + // Error: invalid path. +} + +const Value& Path::resolve(const Value& root) const { + const Value* node = &root; + for (const auto& arg : args_) { + if (arg.kind_ == PathArgument::kindIndex) { + if (!node->isArray() || !node->isValidIndex(arg.index_)) { + // Error: unable to resolve path (array value expected at position... ) + return Value::nullSingleton(); + } + node = &((*node)[arg.index_]); + } else if (arg.kind_ == PathArgument::kindKey) { + if (!node->isObject()) { + // Error: unable to resolve path (object value expected at position...) + return Value::nullSingleton(); + } + node = &((*node)[arg.key_]); + if (node == &Value::nullSingleton()) { + // Error: unable to resolve path (object has no member named '' at + // position...) + return Value::nullSingleton(); + } + } + } + return *node; +} + +Value Path::resolve(const Value& root, const Value& defaultValue) const { + const Value* node = &root; + for (const auto& arg : args_) { + if (arg.kind_ == PathArgument::kindIndex) { + if (!node->isArray() || !node->isValidIndex(arg.index_)) + return defaultValue; + node = &((*node)[arg.index_]); + } else if (arg.kind_ == PathArgument::kindKey) { + if (!node->isObject()) + return defaultValue; + node = &((*node)[arg.key_]); + if (node == &Value::nullSingleton()) + return defaultValue; + } + } + return *node; +} + +Value& Path::make(Value& root) const { + Value* node = &root; + for (const auto& arg : args_) { + if (arg.kind_ == PathArgument::kindIndex) { + if (!node->isArray()) { + // Error: node is not an array at position ... + } + node = &((*node)[arg.index_]); + } else if (arg.kind_ == PathArgument::kindKey) { + if (!node->isObject()) { + // Error: node is not an object at position... + } + node = &((*node)[arg.key_]); + } + } + return *node; +} + +} // namespace Json + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: src/lib_json/json_value.cpp +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: src/lib_json/json_writer.cpp +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#if !defined(JSON_IS_AMALGAMATION) +#include "json_tool.h" +#include <json/writer.h> +#endif // if !defined(JSON_IS_AMALGAMATION) +#include <algorithm> +#include <cassert> +#include <cctype> +#include <cstring> +#include <iomanip> +#include <memory> +#include <set> +#include <sstream> +#include <utility> + +#if __cplusplus >= 201103L +#include <cmath> +#include <cstdio> + +#if !defined(isnan) +#define isnan std::isnan +#endif + +#if !defined(isfinite) +#define isfinite std::isfinite +#endif + +#else +#include <cmath> +#include <cstdio> + +#if defined(_MSC_VER) +#if !defined(isnan) +#include <float.h> +#define isnan _isnan +#endif + +#if !defined(isfinite) +#include <float.h> +#define isfinite _finite +#endif + +#if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) +#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 +#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES + +#endif //_MSC_VER + +#if defined(__sun) && defined(__SVR4) // Solaris +#if !defined(isfinite) +#include <ieeefp.h> +#define isfinite finite +#endif +#endif + +#if defined(__hpux) +#if !defined(isfinite) +#if defined(__ia64) && !defined(finite) +#define isfinite(x) \ + ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x))) +#endif +#endif +#endif + +#if !defined(isnan) +// IEEE standard states that NaN values will not compare to themselves +#define isnan(x) (x != x) +#endif + +#if !defined(__APPLE__) +#if !defined(isfinite) +#define isfinite finite +#endif +#endif +#endif + +#if defined(_MSC_VER) +// Disable warning about strdup being deprecated. +#pragma warning(disable : 4996) +#endif + +namespace Json { + +#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) +using StreamWriterPtr = std::unique_ptr<StreamWriter>; +#else +using StreamWriterPtr = std::auto_ptr<StreamWriter>; +#endif + +String valueToString(LargestInt value) { + UIntToStringBuffer buffer; + char* current = buffer + sizeof(buffer); + if (value == Value::minLargestInt) { + uintToString(LargestUInt(Value::maxLargestInt) + 1, current); + *--current = '-'; + } else if (value < 0) { + uintToString(LargestUInt(-value), current); + *--current = '-'; + } else { + uintToString(LargestUInt(value), current); + } + assert(current >= buffer); + return current; +} + +String valueToString(LargestUInt value) { + UIntToStringBuffer buffer; + char* current = buffer + sizeof(buffer); + uintToString(value, current); + assert(current >= buffer); + return current; +} + +#if defined(JSON_HAS_INT64) + +String valueToString(Int value) { return valueToString(LargestInt(value)); } + +String valueToString(UInt value) { return valueToString(LargestUInt(value)); } + +#endif // # if defined(JSON_HAS_INT64) + +namespace { +String valueToString(double value, bool useSpecialFloats, + unsigned int precision, PrecisionType precisionType) { + // Print into the buffer. We need not request the alternative representation + // that always has a decimal point because JSON doesn't distinguish the + // concepts of reals and integers. + if (!isfinite(value)) { + static const char* const reps[2][3] = {{"NaN", "-Infinity", "Infinity"}, + {"null", "-1e+9999", "1e+9999"}}; + return reps[useSpecialFloats ? 0 : 1] + [isnan(value) ? 0 : (value < 0) ? 1 : 2]; + } + + String buffer(size_t(36), '\0'); + while (true) { + int len = jsoncpp_snprintf( + &*buffer.begin(), buffer.size(), + (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f", + precision, value); + assert(len >= 0); + auto wouldPrint = static_cast<size_t>(len); + if (wouldPrint >= buffer.size()) { + buffer.resize(wouldPrint + 1); + continue; + } + buffer.resize(wouldPrint); + break; + } + + buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end()); + + // strip the zero padding from the right + if (precisionType == PrecisionType::decimalPlaces) { + buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end()); + } + + // try to ensure we preserve the fact that this was given to us as a double on + // input + if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) { + buffer += ".0"; + } + return buffer; +} +} // namespace + +String valueToString(double value, unsigned int precision, + PrecisionType precisionType) { + return valueToString(value, false, precision, precisionType); +} + +String valueToString(bool value) { return value ? "true" : "false"; } + +static bool doesAnyCharRequireEscaping(char const* s, size_t n) { + assert(s || !n); + + return std::any_of(s, s + n, [](unsigned char c) { + return c == '\\' || c == '"' || c < 0x20 || c > 0x7F; + }); +} + +static unsigned int utf8ToCodepoint(const char*& s, const char* e) { + const unsigned int REPLACEMENT_CHARACTER = 0xFFFD; + + unsigned int firstByte = static_cast<unsigned char>(*s); + + if (firstByte < 0x80) + return firstByte; + + if (firstByte < 0xE0) { + if (e - s < 2) + return REPLACEMENT_CHARACTER; + + unsigned int calculated = + ((firstByte & 0x1F) << 6) | (static_cast<unsigned int>(s[1]) & 0x3F); + s += 1; + // oversized encoded characters are invalid + return calculated < 0x80 ? REPLACEMENT_CHARACTER : calculated; + } + + if (firstByte < 0xF0) { + if (e - s < 3) + return REPLACEMENT_CHARACTER; + + unsigned int calculated = ((firstByte & 0x0F) << 12) | + ((static_cast<unsigned int>(s[1]) & 0x3F) << 6) | + (static_cast<unsigned int>(s[2]) & 0x3F); + s += 2; + // surrogates aren't valid codepoints itself + // shouldn't be UTF-8 encoded + if (calculated >= 0xD800 && calculated <= 0xDFFF) + return REPLACEMENT_CHARACTER; + // oversized encoded characters are invalid + return calculated < 0x800 ? REPLACEMENT_CHARACTER : calculated; + } + + if (firstByte < 0xF8) { + if (e - s < 4) + return REPLACEMENT_CHARACTER; + + unsigned int calculated = ((firstByte & 0x07) << 18) | + ((static_cast<unsigned int>(s[1]) & 0x3F) << 12) | + ((static_cast<unsigned int>(s[2]) & 0x3F) << 6) | + (static_cast<unsigned int>(s[3]) & 0x3F); + s += 3; + // oversized encoded characters are invalid + return calculated < 0x10000 ? REPLACEMENT_CHARACTER : calculated; + } + + return REPLACEMENT_CHARACTER; +} + +static const char hex2[] = "000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f" + "505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f" + "707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f" + "909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; + +static String toHex16Bit(unsigned int x) { + const unsigned int hi = (x >> 8) & 0xff; + const unsigned int lo = x & 0xff; + String result(4, ' '); + result[0] = hex2[2 * hi]; + result[1] = hex2[2 * hi + 1]; + result[2] = hex2[2 * lo]; + result[3] = hex2[2 * lo + 1]; + return result; +} + +static void appendRaw(String& result, unsigned ch) { + result += static_cast<char>(ch); +} + +static void appendHex(String& result, unsigned ch) { + result.append("\\u").append(toHex16Bit(ch)); +} + +static String valueToQuotedStringN(const char* value, unsigned length, + bool emitUTF8 = false) { + if (value == nullptr) + return ""; + + if (!doesAnyCharRequireEscaping(value, length)) + return String("\"") + value + "\""; + // We have to walk value and escape any special characters. + // Appending to String is not efficient, but this should be rare. + // (Note: forward slashes are *not* rare, but I am not escaping them.) + String::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL + String result; + result.reserve(maxsize); // to avoid lots of mallocs + result += "\""; + char const* end = value + length; + for (const char* c = value; c != end; ++c) { + switch (*c) { + case '\"': + result += "\\\""; + break; + case '\\': + result += "\\\\"; + break; + case '\b': + result += "\\b"; + break; + case '\f': + result += "\\f"; + break; + case '\n': + result += "\\n"; + break; + case '\r': + result += "\\r"; + break; + case '\t': + result += "\\t"; + break; + // case '/': + // Even though \/ is considered a legal escape in JSON, a bare + // slash is also legal, so I see no reason to escape it. + // (I hope I am not misunderstanding something.) + // blep notes: actually escaping \/ may be useful in javascript to avoid </ + // sequence. + // Should add a flag to allow this compatibility mode and prevent this + // sequence from occurring. + default: { + if (emitUTF8) { + unsigned codepoint = static_cast<unsigned char>(*c); + if (codepoint < 0x20) { + appendHex(result, codepoint); + } else { + appendRaw(result, codepoint); + } + } else { + unsigned codepoint = utf8ToCodepoint(c, end); // modifies `c` + if (codepoint < 0x20) { + appendHex(result, codepoint); + } else if (codepoint < 0x80) { + appendRaw(result, codepoint); + } else if (codepoint < 0x10000) { + // Basic Multilingual Plane + appendHex(result, codepoint); + } else { + // Extended Unicode. Encode 20 bits as a surrogate pair. + codepoint -= 0x10000; + appendHex(result, 0xd800 + ((codepoint >> 10) & 0x3ff)); + appendHex(result, 0xdc00 + (codepoint & 0x3ff)); + } + } + } break; + } + } + result += "\""; + return result; +} + +String valueToQuotedString(const char* value) { + return valueToQuotedStringN(value, static_cast<unsigned int>(strlen(value))); +} + +// Class Writer +// ////////////////////////////////////////////////////////////////// +Writer::~Writer() = default; + +// Class FastWriter +// ////////////////////////////////////////////////////////////////// + +FastWriter::FastWriter() + + = default; + +void FastWriter::enableYAMLCompatibility() { yamlCompatibilityEnabled_ = true; } + +void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; } + +void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; } + +String FastWriter::write(const Value& root) { + document_.clear(); + writeValue(root); + if (!omitEndingLineFeed_) + document_ += '\n'; + return document_; +} + +void FastWriter::writeValue(const Value& value) { + switch (value.type()) { + case nullValue: + if (!dropNullPlaceholders_) + document_ += "null"; + break; + case intValue: + document_ += valueToString(value.asLargestInt()); + break; + case uintValue: + document_ += valueToString(value.asLargestUInt()); + break; + case realValue: + document_ += valueToString(value.asDouble()); + break; + case stringValue: { + // Is NULL possible for value.string_? No. + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) + document_ += valueToQuotedStringN(str, static_cast<unsigned>(end - str)); + break; + } + case booleanValue: + document_ += valueToString(value.asBool()); + break; + case arrayValue: { + document_ += '['; + ArrayIndex size = value.size(); + for (ArrayIndex index = 0; index < size; ++index) { + if (index > 0) + document_ += ','; + writeValue(value[index]); + } + document_ += ']'; + } break; + case objectValue: { + Value::Members members(value.getMemberNames()); + document_ += '{'; + for (auto it = members.begin(); it != members.end(); ++it) { + const String& name = *it; + if (it != members.begin()) + document_ += ','; + document_ += valueToQuotedStringN(name.data(), + static_cast<unsigned>(name.length())); + document_ += yamlCompatibilityEnabled_ ? ": " : ":"; + writeValue(value[name]); + } + document_ += '}'; + } break; + } +} + +// Class StyledWriter +// ////////////////////////////////////////////////////////////////// + +StyledWriter::StyledWriter() = default; + +String StyledWriter::write(const Value& root) { + document_.clear(); + addChildValues_ = false; + indentString_.clear(); + writeCommentBeforeValue(root); + writeValue(root); + writeCommentAfterValueOnSameLine(root); + document_ += '\n'; + return document_; +} + +void StyledWriter::writeValue(const Value& value) { + switch (value.type()) { + case nullValue: + pushValue("null"); + break; + case intValue: + pushValue(valueToString(value.asLargestInt())); + break; + case uintValue: + pushValue(valueToString(value.asLargestUInt())); + break; + case realValue: + pushValue(valueToString(value.asDouble())); + break; + case stringValue: { + // Is NULL possible for value.string_? No. + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) + pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str))); + else + pushValue(""); + break; + } + case booleanValue: + pushValue(valueToString(value.asBool())); + break; + case arrayValue: + writeArrayValue(value); + break; + case objectValue: { + Value::Members members(value.getMemberNames()); + if (members.empty()) + pushValue("{}"); + else { + writeWithIndent("{"); + indent(); + auto it = members.begin(); + for (;;) { + const String& name = *it; + const Value& childValue = value[name]; + writeCommentBeforeValue(childValue); + writeWithIndent(valueToQuotedString(name.c_str())); + document_ += " : "; + writeValue(childValue); + if (++it == members.end()) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + document_ += ','; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("}"); + } + } break; + } +} + +void StyledWriter::writeArrayValue(const Value& value) { + unsigned size = value.size(); + if (size == 0) + pushValue("[]"); + else { + bool isArrayMultiLine = isMultilineArray(value); + if (isArrayMultiLine) { + writeWithIndent("["); + indent(); + bool hasChildValue = !childValues_.empty(); + unsigned index = 0; + for (;;) { + const Value& childValue = value[index]; + writeCommentBeforeValue(childValue); + if (hasChildValue) + writeWithIndent(childValues_[index]); + else { + writeIndent(); + writeValue(childValue); + } + if (++index == size) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + document_ += ','; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("]"); + } else // output on a single line + { + assert(childValues_.size() == size); + document_ += "[ "; + for (unsigned index = 0; index < size; ++index) { + if (index > 0) + document_ += ", "; + document_ += childValues_[index]; + } + document_ += " ]"; + } + } +} + +bool StyledWriter::isMultilineArray(const Value& value) { + ArrayIndex const size = value.size(); + bool isMultiLine = size * 3 >= rightMargin_; + childValues_.clear(); + for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { + const Value& childValue = value[index]; + isMultiLine = ((childValue.isArray() || childValue.isObject()) && + !childValue.empty()); + } + if (!isMultiLine) // check if line length > max line length + { + childValues_.reserve(size); + addChildValues_ = true; + ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + for (ArrayIndex index = 0; index < size; ++index) { + if (hasCommentForValue(value[index])) { + isMultiLine = true; + } + writeValue(value[index]); + lineLength += static_cast<ArrayIndex>(childValues_[index].length()); + } + addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= rightMargin_; + } + return isMultiLine; +} + +void StyledWriter::pushValue(const String& value) { + if (addChildValues_) + childValues_.push_back(value); + else + document_ += value; +} + +void StyledWriter::writeIndent() { + if (!document_.empty()) { + char last = document_[document_.length() - 1]; + if (last == ' ') // already indented + return; + if (last != '\n') // Comments may add new-line + document_ += '\n'; + } + document_ += indentString_; +} + +void StyledWriter::writeWithIndent(const String& value) { + writeIndent(); + document_ += value; +} + +void StyledWriter::indent() { indentString_ += String(indentSize_, ' '); } + +void StyledWriter::unindent() { + assert(indentString_.size() >= indentSize_); + indentString_.resize(indentString_.size() - indentSize_); +} + +void StyledWriter::writeCommentBeforeValue(const Value& root) { + if (!root.hasComment(commentBefore)) + return; + + document_ += '\n'; + writeIndent(); + const String& comment = root.getComment(commentBefore); + String::const_iterator iter = comment.begin(); + while (iter != comment.end()) { + document_ += *iter; + if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/')) + writeIndent(); + ++iter; + } + + // Comments are stripped of trailing newlines, so add one here + document_ += '\n'; +} + +void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) { + if (root.hasComment(commentAfterOnSameLine)) + document_ += " " + root.getComment(commentAfterOnSameLine); + + if (root.hasComment(commentAfter)) { + document_ += '\n'; + document_ += root.getComment(commentAfter); + document_ += '\n'; + } +} + +bool StyledWriter::hasCommentForValue(const Value& value) { + return value.hasComment(commentBefore) || + value.hasComment(commentAfterOnSameLine) || + value.hasComment(commentAfter); +} + +// Class StyledStreamWriter +// ////////////////////////////////////////////////////////////////// + +StyledStreamWriter::StyledStreamWriter(String indentation) + : document_(nullptr), indentation_(std::move(indentation)), + addChildValues_(), indented_(false) {} + +void StyledStreamWriter::write(OStream& out, const Value& root) { + document_ = &out; + addChildValues_ = false; + indentString_.clear(); + indented_ = true; + writeCommentBeforeValue(root); + if (!indented_) + writeIndent(); + indented_ = true; + writeValue(root); + writeCommentAfterValueOnSameLine(root); + *document_ << "\n"; + document_ = nullptr; // Forget the stream, for safety. +} + +void StyledStreamWriter::writeValue(const Value& value) { + switch (value.type()) { + case nullValue: + pushValue("null"); + break; + case intValue: + pushValue(valueToString(value.asLargestInt())); + break; + case uintValue: + pushValue(valueToString(value.asLargestUInt())); + break; + case realValue: + pushValue(valueToString(value.asDouble())); + break; + case stringValue: { + // Is NULL possible for value.string_? No. + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) + pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str))); + else + pushValue(""); + break; + } + case booleanValue: + pushValue(valueToString(value.asBool())); + break; + case arrayValue: + writeArrayValue(value); + break; + case objectValue: { + Value::Members members(value.getMemberNames()); + if (members.empty()) + pushValue("{}"); + else { + writeWithIndent("{"); + indent(); + auto it = members.begin(); + for (;;) { + const String& name = *it; + const Value& childValue = value[name]; + writeCommentBeforeValue(childValue); + writeWithIndent(valueToQuotedString(name.c_str())); + *document_ << " : "; + writeValue(childValue); + if (++it == members.end()) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + *document_ << ","; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("}"); + } + } break; + } +} + +void StyledStreamWriter::writeArrayValue(const Value& value) { + unsigned size = value.size(); + if (size == 0) + pushValue("[]"); + else { + bool isArrayMultiLine = isMultilineArray(value); + if (isArrayMultiLine) { + writeWithIndent("["); + indent(); + bool hasChildValue = !childValues_.empty(); + unsigned index = 0; + for (;;) { + const Value& childValue = value[index]; + writeCommentBeforeValue(childValue); + if (hasChildValue) + writeWithIndent(childValues_[index]); + else { + if (!indented_) + writeIndent(); + indented_ = true; + writeValue(childValue); + indented_ = false; + } + if (++index == size) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + *document_ << ","; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("]"); + } else // output on a single line + { + assert(childValues_.size() == size); + *document_ << "[ "; + for (unsigned index = 0; index < size; ++index) { + if (index > 0) + *document_ << ", "; + *document_ << childValues_[index]; + } + *document_ << " ]"; + } + } +} + +bool StyledStreamWriter::isMultilineArray(const Value& value) { + ArrayIndex const size = value.size(); + bool isMultiLine = size * 3 >= rightMargin_; + childValues_.clear(); + for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { + const Value& childValue = value[index]; + isMultiLine = ((childValue.isArray() || childValue.isObject()) && + !childValue.empty()); + } + if (!isMultiLine) // check if line length > max line length + { + childValues_.reserve(size); + addChildValues_ = true; + ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + for (ArrayIndex index = 0; index < size; ++index) { + if (hasCommentForValue(value[index])) { + isMultiLine = true; + } + writeValue(value[index]); + lineLength += static_cast<ArrayIndex>(childValues_[index].length()); + } + addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= rightMargin_; + } + return isMultiLine; +} + +void StyledStreamWriter::pushValue(const String& value) { + if (addChildValues_) + childValues_.push_back(value); + else + *document_ << value; +} + +void StyledStreamWriter::writeIndent() { + // blep intended this to look at the so-far-written string + // to determine whether we are already indented, but + // with a stream we cannot do that. So we rely on some saved state. + // The caller checks indented_. + *document_ << '\n' << indentString_; +} + +void StyledStreamWriter::writeWithIndent(const String& value) { + if (!indented_) + writeIndent(); + *document_ << value; + indented_ = false; +} + +void StyledStreamWriter::indent() { indentString_ += indentation_; } + +void StyledStreamWriter::unindent() { + assert(indentString_.size() >= indentation_.size()); + indentString_.resize(indentString_.size() - indentation_.size()); +} + +void StyledStreamWriter::writeCommentBeforeValue(const Value& root) { + if (!root.hasComment(commentBefore)) + return; + + if (!indented_) + writeIndent(); + const String& comment = root.getComment(commentBefore); + String::const_iterator iter = comment.begin(); + while (iter != comment.end()) { + *document_ << *iter; + if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/')) + // writeIndent(); // would include newline + *document_ << indentString_; + ++iter; + } + indented_ = false; +} + +void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) { + if (root.hasComment(commentAfterOnSameLine)) + *document_ << ' ' << root.getComment(commentAfterOnSameLine); + + if (root.hasComment(commentAfter)) { + writeIndent(); + *document_ << root.getComment(commentAfter); + } + indented_ = false; +} + +bool StyledStreamWriter::hasCommentForValue(const Value& value) { + return value.hasComment(commentBefore) || + value.hasComment(commentAfterOnSameLine) || + value.hasComment(commentAfter); +} + +////////////////////////// +// BuiltStyledStreamWriter + +/// Scoped enums are not available until C++11. +struct CommentStyle { + /// Decide whether to write comments. + enum Enum { + None, ///< Drop all comments. + Most, ///< Recover odd behavior of previous versions (not implemented yet). + All ///< Keep all comments. + }; +}; + +struct BuiltStyledStreamWriter : public StreamWriter { + BuiltStyledStreamWriter(String indentation, CommentStyle::Enum cs, + String colonSymbol, String nullSymbol, + String endingLineFeedSymbol, bool useSpecialFloats, + bool emitUTF8, unsigned int precision, + PrecisionType precisionType); + int write(Value const& root, OStream* sout) override; + +private: + void writeValue(Value const& value); + void writeArrayValue(Value const& value); + bool isMultilineArray(Value const& value); + void pushValue(String const& value); + void writeIndent(); + void writeWithIndent(String const& value); + void indent(); + void unindent(); + void writeCommentBeforeValue(Value const& root); + void writeCommentAfterValueOnSameLine(Value const& root); + static bool hasCommentForValue(const Value& value); + + using ChildValues = std::vector<String>; + + ChildValues childValues_; + String indentString_; + unsigned int rightMargin_; + String indentation_; + CommentStyle::Enum cs_; + String colonSymbol_; + String nullSymbol_; + String endingLineFeedSymbol_; + bool addChildValues_ : 1; + bool indented_ : 1; + bool useSpecialFloats_ : 1; + bool emitUTF8_ : 1; + unsigned int precision_; + PrecisionType precisionType_; +}; +BuiltStyledStreamWriter::BuiltStyledStreamWriter( + String indentation, CommentStyle::Enum cs, String colonSymbol, + String nullSymbol, String endingLineFeedSymbol, bool useSpecialFloats, + bool emitUTF8, unsigned int precision, PrecisionType precisionType) + : rightMargin_(74), indentation_(std::move(indentation)), cs_(cs), + colonSymbol_(std::move(colonSymbol)), nullSymbol_(std::move(nullSymbol)), + endingLineFeedSymbol_(std::move(endingLineFeedSymbol)), + addChildValues_(false), indented_(false), + useSpecialFloats_(useSpecialFloats), emitUTF8_(emitUTF8), + precision_(precision), precisionType_(precisionType) {} +int BuiltStyledStreamWriter::write(Value const& root, OStream* sout) { + sout_ = sout; + addChildValues_ = false; + indented_ = true; + indentString_.clear(); + writeCommentBeforeValue(root); + if (!indented_) + writeIndent(); + indented_ = true; + writeValue(root); + writeCommentAfterValueOnSameLine(root); + *sout_ << endingLineFeedSymbol_; + sout_ = nullptr; + return 0; +} +void BuiltStyledStreamWriter::writeValue(Value const& value) { + switch (value.type()) { + case nullValue: + pushValue(nullSymbol_); + break; + case intValue: + pushValue(valueToString(value.asLargestInt())); + break; + case uintValue: + pushValue(valueToString(value.asLargestUInt())); + break; + case realValue: + pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_, + precisionType_)); + break; + case stringValue: { + // Is NULL is possible for value.string_? No. + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) + pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str), + emitUTF8_)); + else + pushValue(""); + break; + } + case booleanValue: + pushValue(valueToString(value.asBool())); + break; + case arrayValue: + writeArrayValue(value); + break; + case objectValue: { + Value::Members members(value.getMemberNames()); + if (members.empty()) + pushValue("{}"); + else { + writeWithIndent("{"); + indent(); + auto it = members.begin(); + for (;;) { + String const& name = *it; + Value const& childValue = value[name]; + writeCommentBeforeValue(childValue); + writeWithIndent(valueToQuotedStringN( + name.data(), static_cast<unsigned>(name.length()), emitUTF8_)); + *sout_ << colonSymbol_; + writeValue(childValue); + if (++it == members.end()) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + *sout_ << ","; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("}"); + } + } break; + } +} + +void BuiltStyledStreamWriter::writeArrayValue(Value const& value) { + unsigned size = value.size(); + if (size == 0) + pushValue("[]"); + else { + bool isMultiLine = (cs_ == CommentStyle::All) || isMultilineArray(value); + if (isMultiLine) { + writeWithIndent("["); + indent(); + bool hasChildValue = !childValues_.empty(); + unsigned index = 0; + for (;;) { + Value const& childValue = value[index]; + writeCommentBeforeValue(childValue); + if (hasChildValue) + writeWithIndent(childValues_[index]); + else { + if (!indented_) + writeIndent(); + indented_ = true; + writeValue(childValue); + indented_ = false; + } + if (++index == size) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + *sout_ << ","; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("]"); + } else // output on a single line + { + assert(childValues_.size() == size); + *sout_ << "["; + if (!indentation_.empty()) + *sout_ << " "; + for (unsigned index = 0; index < size; ++index) { + if (index > 0) + *sout_ << ((!indentation_.empty()) ? ", " : ","); + *sout_ << childValues_[index]; + } + if (!indentation_.empty()) + *sout_ << " "; + *sout_ << "]"; + } + } +} + +bool BuiltStyledStreamWriter::isMultilineArray(Value const& value) { + ArrayIndex const size = value.size(); + bool isMultiLine = size * 3 >= rightMargin_; + childValues_.clear(); + for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { + Value const& childValue = value[index]; + isMultiLine = ((childValue.isArray() || childValue.isObject()) && + !childValue.empty()); + } + if (!isMultiLine) // check if line length > max line length + { + childValues_.reserve(size); + addChildValues_ = true; + ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + for (ArrayIndex index = 0; index < size; ++index) { + if (hasCommentForValue(value[index])) { + isMultiLine = true; + } + writeValue(value[index]); + lineLength += static_cast<ArrayIndex>(childValues_[index].length()); + } + addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= rightMargin_; + } + return isMultiLine; +} + +void BuiltStyledStreamWriter::pushValue(String const& value) { + if (addChildValues_) + childValues_.push_back(value); + else + *sout_ << value; +} + +void BuiltStyledStreamWriter::writeIndent() { + // blep intended this to look at the so-far-written string + // to determine whether we are already indented, but + // with a stream we cannot do that. So we rely on some saved state. + // The caller checks indented_. + + if (!indentation_.empty()) { + // In this case, drop newlines too. + *sout_ << '\n' << indentString_; + } +} + +void BuiltStyledStreamWriter::writeWithIndent(String const& value) { + if (!indented_) + writeIndent(); + *sout_ << value; + indented_ = false; +} + +void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; } + +void BuiltStyledStreamWriter::unindent() { + assert(indentString_.size() >= indentation_.size()); + indentString_.resize(indentString_.size() - indentation_.size()); +} + +void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) { + if (cs_ == CommentStyle::None) + return; + if (!root.hasComment(commentBefore)) + return; + + if (!indented_) + writeIndent(); + const String& comment = root.getComment(commentBefore); + String::const_iterator iter = comment.begin(); + while (iter != comment.end()) { + *sout_ << *iter; + if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/')) + // writeIndent(); // would write extra newline + *sout_ << indentString_; + ++iter; + } + indented_ = false; +} + +void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine( + Value const& root) { + if (cs_ == CommentStyle::None) + return; + if (root.hasComment(commentAfterOnSameLine)) + *sout_ << " " + root.getComment(commentAfterOnSameLine); + + if (root.hasComment(commentAfter)) { + writeIndent(); + *sout_ << root.getComment(commentAfter); + } +} + +// static +bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) { + return value.hasComment(commentBefore) || + value.hasComment(commentAfterOnSameLine) || + value.hasComment(commentAfter); +} + +/////////////// +// StreamWriter + +StreamWriter::StreamWriter() : sout_(nullptr) {} +StreamWriter::~StreamWriter() = default; +StreamWriter::Factory::~Factory() = default; +StreamWriterBuilder::StreamWriterBuilder() { setDefaults(&settings_); } +StreamWriterBuilder::~StreamWriterBuilder() = default; +StreamWriter* StreamWriterBuilder::newStreamWriter() const { + const String indentation = settings_["indentation"].asString(); + const String cs_str = settings_["commentStyle"].asString(); + const String pt_str = settings_["precisionType"].asString(); + const bool eyc = settings_["enableYAMLCompatibility"].asBool(); + const bool dnp = settings_["dropNullPlaceholders"].asBool(); + const bool usf = settings_["useSpecialFloats"].asBool(); + const bool emitUTF8 = settings_["emitUTF8"].asBool(); + unsigned int pre = settings_["precision"].asUInt(); + CommentStyle::Enum cs = CommentStyle::All; + if (cs_str == "All") { + cs = CommentStyle::All; + } else if (cs_str == "None") { + cs = CommentStyle::None; + } else { + throwRuntimeError("commentStyle must be 'All' or 'None'"); + } + PrecisionType precisionType(significantDigits); + if (pt_str == "significant") { + precisionType = PrecisionType::significantDigits; + } else if (pt_str == "decimal") { + precisionType = PrecisionType::decimalPlaces; + } else { + throwRuntimeError("precisionType must be 'significant' or 'decimal'"); + } + String colonSymbol = " : "; + if (eyc) { + colonSymbol = ": "; + } else if (indentation.empty()) { + colonSymbol = ":"; + } + String nullSymbol = "null"; + if (dnp) { + nullSymbol.clear(); + } + if (pre > 17) + pre = 17; + String endingLineFeedSymbol; + return new BuiltStyledStreamWriter(indentation, cs, colonSymbol, nullSymbol, + endingLineFeedSymbol, usf, emitUTF8, pre, + precisionType); +} + +bool StreamWriterBuilder::validate(Json::Value* invalid) const { + static const auto& valid_keys = *new std::set<String>{ + "indentation", + "commentStyle", + "enableYAMLCompatibility", + "dropNullPlaceholders", + "useSpecialFloats", + "emitUTF8", + "precision", + "precisionType", + }; + for (auto si = settings_.begin(); si != settings_.end(); ++si) { + auto key = si.name(); + if (valid_keys.count(key)) + continue; + if (invalid) + (*invalid)[std::move(key)] = *si; + else + return false; + } + return invalid ? invalid->empty() : true; +} + +Value& StreamWriterBuilder::operator[](const String& key) { + return settings_[key]; +} +// static +void StreamWriterBuilder::setDefaults(Json::Value* settings) { + //! [StreamWriterBuilderDefaults] + (*settings)["commentStyle"] = "All"; + (*settings)["indentation"] = "\t"; + (*settings)["enableYAMLCompatibility"] = false; + (*settings)["dropNullPlaceholders"] = false; + (*settings)["useSpecialFloats"] = false; + (*settings)["emitUTF8"] = false; + (*settings)["precision"] = 17; + (*settings)["precisionType"] = "significant"; + //! [StreamWriterBuilderDefaults] +} + +String writeString(StreamWriter::Factory const& factory, Value const& root) { + OStringStream sout; + StreamWriterPtr const writer(factory.newStreamWriter()); + writer->write(root, &sout); + return sout.str(); +} + +OStream& operator<<(OStream& sout, Value const& root) { + StreamWriterBuilder builder; + StreamWriterPtr const writer(builder.newStreamWriter()); + writer->write(root, &sout); + return sout; +} + +} // namespace Json + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: src/lib_json/json_writer.cpp +// ////////////////////////////////////////////////////////////////////// + + + + + diff --git a/lib/lua/CMakeLists.txt b/lib/lua/CMakeLists.txt new file mode 100644 index 0000000..2de4840 --- /dev/null +++ b/lib/lua/CMakeLists.txt @@ -0,0 +1,59 @@ +project(lua CXX) + +set(LUA_VERSION_MAJOR 5) +set(LUA_VERSION_MINOR 1) +set(LUA_VERSION_PATCH 4) +set(LUA_VERSION "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}") + +set(COMMON_CFLAGS) +set(COMMON_LDFLAGS) +set(LIBS) + +if(APPLE) + set(DEFAULT_POSIX TRUE) + set(DEFAULT_DLOPEN OFF) + set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_USE_MACOSX") +elseif(UNIX OR CYGWIN) + set(DEFAULT_POSIX TRUE) +elseif(WIN32) + set(LUA_WIN TRUE) + set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_BUILD_AS_DLL") +else() + set(DEFAULT_ANSI TRUE) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(COMMON_LDFLAGS "${COMMON_LDFLAGS} -Wl,-E -lm") + set(DEFAULT_DLOPEN ON) +endif() + +option(LUA_USE_DLOPEN "Enable dlopen support." ${DEFAULT_DLOPEN}) +mark_as_advanced(LUA_USE_DLOPEN) + +option(LUA_ANSI "Disable non-ANSI features." ${DEFAULT_ANSI}) +mark_as_advanced(LUA_ANSI) + +if(LUA_USE_DLOPEN) + set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_USE_DLOPEN") + if(NOT APPLE) + set(COMMON_LDFLAGS "${COMMON_LDFLAGS} -ldl ") + endif(NOT APPLE) +endif(LUA_USE_DLOPEN) + +if(DEFAULT_POSIX) + set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_USE_POSIX") +endif(DEFAULT_POSIX) + +if(LUA_ANSI) + set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_ANSI") +endif(LUA_ANSI) + +# Standard flags to use +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|(Apple)?Clang") + set(COMMON_CFLAGS "${COMMON_CFLAGS} -pipe -Wall -Wextra -Wshadow -W -pedantic") +endif() + +# COMMON_CFLAGS has no effect without this line +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_CFLAGS}") + +add_subdirectory(src) diff --git a/lib/lua/COPYRIGHT b/lib/lua/COPYRIGHT new file mode 100644 index 0000000..a860268 --- /dev/null +++ b/lib/lua/COPYRIGHT @@ -0,0 +1,34 @@ +Lua License +----------- + +Lua is licensed under the terms of the MIT license reproduced below. +This means that Lua is free software and can be used for both academic +and commercial purposes at absolutely no cost. + +For details and rationale, see http://www.lua.org/license.html . + +=============================================================================== + +Copyright (C) 1994-2012 Lua.org, PUC-Rio. + +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. + +=============================================================================== + +(end of COPYRIGHT) diff --git a/lib/lua/src/CMakeLists.txt b/lib/lua/src/CMakeLists.txt new file mode 100644 index 0000000..2ca4f41 --- /dev/null +++ b/lib/lua/src/CMakeLists.txt @@ -0,0 +1,44 @@ + +# Lua core source files. +set(LUA_CORE_SRC + 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 +) + +# Lua library +add_library(lua STATIC ${LUA_CORE_SRC}) +target_link_libraries(lua ${LIBS}) +set_target_properties(lua PROPERTIES + VERSION ${LUA_VERSION} + CLEAN_DIRECT_OUTPUT 1 +) + +# Compile code as C++ +set_source_files_properties(${LUA_CORE_SRC} PROPERTIES LANGUAGE CXX) diff --git a/lib/lua/src/lapi.c b/lib/lua/src/lapi.c new file mode 100644 index 0000000..5d5145d --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lapi.h b/lib/lua/src/lapi.h new file mode 100644 index 0000000..2c3fab2 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lauxlib.c b/lib/lua/src/lauxlib.c new file mode 100644 index 0000000..10f14e2 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lauxlib.h b/lib/lua/src/lauxlib.h new file mode 100644 index 0000000..3425823 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lbaselib.c b/lib/lua/src/lbaselib.c new file mode 100644 index 0000000..2ab550b --- /dev/null +++ b/lib/lua/src/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 auxiliary 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/lib/lua/src/lcode.c b/lib/lua/src/lcode.c new file mode 100644 index 0000000..679cb9c --- /dev/null +++ b/lib/lua/src/lcode.c @@ -0,0 +1,831 @@ +/* +** $Id: lcode.c,v 2.25.1.5 2011/01/31 14:53:16 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 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 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/lib/lua/src/lcode.h b/lib/lua/src/lcode.h new file mode 100644 index 0000000..b941c60 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/ldblib.c b/lib/lua/src/ldblib.c new file mode 100644 index 0000000..2027eda --- /dev/null +++ b/lib/lua/src/ldblib.c @@ -0,0 +1,398 @@ +/* +** $Id: ldblib.c,v 1.104.1.4 2009/08/04 18:50:18 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) { + luaL_checkany(L, 1); + 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/lib/lua/src/ldebug.c b/lib/lua/src/ldebug.c new file mode 100644 index 0000000..50ad3d3 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/ldebug.h b/lib/lua/src/ldebug.h new file mode 100644 index 0000000..ba28a97 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/ldo.c b/lib/lua/src/ldo.c new file mode 100644 index 0000000..d1bf786 --- /dev/null +++ b/lib/lua/src/ldo.c @@ -0,0 +1,519 @@ +/* +** $Id: ldo.c,v 2.38.1.4 2012/01/18 02:27:10 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); + luaD_checkstack(L, p->maxstacksize); + 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/lib/lua/src/ldo.h b/lib/lua/src/ldo.h new file mode 100644 index 0000000..98fddac --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/ldump.c b/lib/lua/src/ldump.c new file mode 100644 index 0000000..c9d3d48 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lfunc.c b/lib/lua/src/lfunc.c new file mode 100644 index 0000000..813e88f --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lfunc.h b/lib/lua/src/lfunc.h new file mode 100644 index 0000000..a68cf51 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lgc.c b/lib/lua/src/lgc.c new file mode 100644 index 0000000..9141a1c --- /dev/null +++ b/lib/lua/src/lgc.c @@ -0,0 +1,715 @@ +/* +** $Id: lgc.c,v 2.38.1.2 2011/03/18 18:05:38 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? */ + // Android's 'FORTIFY libc' calls __builtin_object_size on the argument of strchr. + // This produces an incorrect size for the expression `svalue(mode)`, causing + // an assertion. By placing it in a temporary, __builtin_object_size returns + // -1 (for unknown size) which functions correctly. + const char *tmp = svalue(mode); + weakkey = (strchr(tmp, 'k') != NULL); + weakvalue = (strchr(tmp, '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 { + 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/lib/lua/src/lgc.h b/lib/lua/src/lgc.h new file mode 100644 index 0000000..5a8dc60 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/linit.c b/lib/lua/src/linit.c new file mode 100644 index 0000000..c1f90df --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/liolib.c b/lib/lua/src/liolib.c new file mode 100644 index 0000000..649f9a5 --- /dev/null +++ b/lib/lua/src/liolib.c @@ -0,0 +1,556 @@ +/* +** $Id: liolib.c,v 2.73.1.4 2010/05/14 15:33:51 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 { + lua_pushnil(L); /* "result" to be removed */ + 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/lib/lua/src/llex.c b/lib/lua/src/llex.c new file mode 100644 index 0000000..d1b1796 --- /dev/null +++ b/lib/lua/src/llex.c @@ -0,0 +1,469 @@ +/* +** $Id: llex.c,v 2.20.1.2 2009/11/23 14:58:22 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 */ + luaC_checkGC(L); + } + 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; +#ifndef __ANDROID__ + ls->decpoint = (cv ? cv->decimal_point[0] : '.'); +#else + ls->decpoint = '.'; +#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/lib/lua/src/llex.h b/lib/lua/src/llex.h new file mode 100644 index 0000000..a9201ce --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/llimits.h b/lib/lua/src/llimits.h new file mode 100644 index 0000000..ca8dcb7 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lmathlib.c b/lib/lua/src/lmathlib.c new file mode 100644 index 0000000..441fbf7 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lmem.c b/lib/lua/src/lmem.c new file mode 100644 index 0000000..ae7d8c9 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lmem.h b/lib/lua/src/lmem.h new file mode 100644 index 0000000..7c2dcb3 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/loadlib.c b/lib/lua/src/loadlib.c new file mode 100644 index 0000000..6158c53 --- /dev/null +++ b/lib/lua/src/loadlib.c @@ -0,0 +1,666 @@ +/* +** $Id: loadlib.c,v 1.52.1.4 2009/09/09 13:17:16 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, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); + /* 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/lib/lua/src/lobject.c b/lib/lua/src/lobject.c new file mode 100644 index 0000000..4ff5073 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lobject.h b/lib/lua/src/lobject.h new file mode 100644 index 0000000..f1e447e --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lopcodes.c b/lib/lua/src/lopcodes.c new file mode 100644 index 0000000..4cc7452 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lopcodes.h b/lib/lua/src/lopcodes.h new file mode 100644 index 0000000..41224d6 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/loslib.c b/lib/lua/src/loslib.c new file mode 100644 index 0000000..da06a57 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lparser.c b/lib/lua/src/lparser.c new file mode 100644 index 0000000..dda7488 --- /dev/null +++ b/lib/lua/src/lparser.c @@ -0,0 +1,1339 @@ +/* +** $Id: lparser.c,v 2.42.1.4 2011/10/21 19:31:42 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; + /* last token read was anchored in defunct function; must reanchor it */ + if (fs) anchor_token(ls); + L->top -= 2; /* remove table and prototype from the stack */ +} + + +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/lib/lua/src/lparser.h b/lib/lua/src/lparser.h new file mode 100644 index 0000000..18836af --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lstate.c b/lib/lua/src/lstate.c new file mode 100644 index 0000000..4313b83 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lstate.h b/lib/lua/src/lstate.h new file mode 100644 index 0000000..3bc575b --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lstring.c b/lib/lua/src/lstring.c new file mode 100644 index 0000000..4911315 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lstring.h b/lib/lua/src/lstring.h new file mode 100644 index 0000000..73a2ff8 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lstrlib.c b/lib/lua/src/lstrlib.c new file mode 100644 index 0000000..7a03489 --- /dev/null +++ b/lib/lua/src/lstrlib.c @@ -0,0 +1,871 @@ +/* +** $Id: lstrlib.c,v 1.132.1.5 2010/05/14 15:34:19 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 top = lua_gettop(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 */ + if (++arg > top) + luaL_argerror(L, arg, "no value"); + 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/lib/lua/src/ltable.c b/lib/lua/src/ltable.c new file mode 100644 index 0000000..ec84f4f --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/ltable.h b/lib/lua/src/ltable.h new file mode 100644 index 0000000..f5b9d5e --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/ltablib.c b/lib/lua/src/ltablib.c new file mode 100644 index 0000000..b6d9cb4 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/ltm.c b/lib/lua/src/ltm.c new file mode 100644 index 0000000..c27f0f6 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/ltm.h b/lib/lua/src/ltm.h new file mode 100644 index 0000000..64343b7 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lua.c b/lib/lua/src/lua.c new file mode 100644 index 0000000..3a46609 --- /dev/null +++ b/lib/lua/src/lua.c @@ -0,0 +1,392 @@ +/* +** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $ +** Lua stand-alone interpreter +** See Copyright Notice in lua.h +*/ + + +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define lua_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static lua_State *globalL = NULL; + +static const char *progname = LUA_PROGNAME; + + + +static void lstop (lua_State *L, lua_Debug *ar) { + (void)ar; /* unused arg. */ + lua_sethook(L, NULL, 0, 0); + luaL_error(L, "interrupted!"); +} + + +static void laction (int i) { + signal(i, SIG_DFL); /* if another SIGINT happens before lstop, + terminate process (default action) */ + lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); +} + + +static void print_usage (void) { + fprintf(stderr, + "usage: %s [options] [script [args]].\n" + "Available options are:\n" + " -e stat execute string " LUA_QL("stat") "\n" + " -l name require library " LUA_QL("name") "\n" + " -i enter interactive mode after executing " LUA_QL("script") "\n" + " -v show version information\n" + " -- stop handling options\n" + " - execute stdin and stop handling options\n" + , + progname); + fflush(stderr); +} + + +static void l_message (const char *pname, const char *msg) { + if (pname) fprintf(stderr, "%s: ", pname); + fprintf(stderr, "%s\n", msg); + fflush(stderr); +} + + +static int report (lua_State *L, int status) { + if (status && !lua_isnil(L, -1)) { + const char *msg = lua_tostring(L, -1); + if (msg == NULL) msg = "(error object is not a string)"; + l_message(progname, msg); + lua_pop(L, 1); + } + return status; +} + + +static int traceback (lua_State *L) { + if (!lua_isstring(L, 1)) /* 'message' not a string? */ + return 1; /* keep it intact */ + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call debug.traceback */ + return 1; +} + + +static int docall (lua_State *L, int narg, int clear) { + int status; + int base = lua_gettop(L) - narg; /* function index */ + lua_pushcfunction(L, traceback); /* push traceback function */ + lua_insert(L, base); /* put it under chunk and args */ + signal(SIGINT, laction); + status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); + signal(SIGINT, SIG_DFL); + lua_remove(L, base); /* remove traceback function */ + /* force a complete garbage collection in case of errors */ + if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); + return status; +} + + +static void print_version (void) { + l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT); +} + + +static int getargs (lua_State *L, char **argv, int n) { + int narg; + int i; + int argc = 0; + while (argv[argc]) argc++; /* count total number of arguments */ + narg = argc - (n + 1); /* number of arguments to the script */ + luaL_checkstack(L, narg + 3, "too many arguments to script"); + for (i=n+1; i < argc; i++) + lua_pushstring(L, argv[i]); + lua_createtable(L, narg, n + 1); + for (i=0; i < argc; i++) { + lua_pushstring(L, argv[i]); + lua_rawseti(L, -2, i - n); + } + return narg; +} + + +static int dofile (lua_State *L, const char *name) { + int status = luaL_loadfile(L, name) || docall(L, 0, 1); + return report(L, status); +} + + +static int dostring (lua_State *L, const char *s, const char *name) { + int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); + return report(L, status); +} + + +static int dolibrary (lua_State *L, const char *name) { + lua_getglobal(L, "require"); + lua_pushstring(L, name); + return report(L, docall(L, 1, 1)); +} + + +static const char *get_prompt (lua_State *L, int firstline) { + const char *p; + lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2"); + p = lua_tostring(L, -1); + if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); + lua_pop(L, 1); /* remove global */ + return p; +} + + +static int incomplete (lua_State *L, int status) { + if (status == LUA_ERRSYNTAX) { + size_t lmsg; + const char *msg = lua_tolstring(L, -1, &lmsg); + const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1); + if (strstr(msg, LUA_QL("<eof>")) == tp) { + lua_pop(L, 1); + return 1; + } + } + return 0; /* else... */ +} + + +static int pushline (lua_State *L, int firstline) { + char buffer[LUA_MAXINPUT]; + char *b = buffer; + size_t l; + const char *prmt = get_prompt(L, firstline); + if (lua_readline(L, b, prmt) == 0) + return 0; /* no input */ + l = strlen(b); + if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ + b[l-1] = '\0'; /* remove it */ + if (firstline && b[0] == '=') /* first line starts with `=' ? */ + lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ + else + lua_pushstring(L, b); + lua_freeline(L, b); + return 1; +} + + +static int loadline (lua_State *L) { + int status; + lua_settop(L, 0); + if (!pushline(L, 1)) + return -1; /* no input */ + for (;;) { /* repeat until gets a complete line */ + status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); + if (!incomplete(L, status)) break; /* cannot try to add lines? */ + if (!pushline(L, 0)) /* no more input? */ + return -1; + lua_pushliteral(L, "\n"); /* add a new line... */ + lua_insert(L, -2); /* ...between the two lines */ + lua_concat(L, 3); /* join them */ + } + lua_saveline(L, 1); + lua_remove(L, 1); /* remove line */ + return status; +} + + +static void dotty (lua_State *L) { + int status; + const char *oldprogname = progname; + progname = NULL; + while ((status = loadline(L)) != -1) { + if (status == 0) status = docall(L, 0, 0); + report(L, status); + if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ + lua_getglobal(L, "print"); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) + l_message(progname, lua_pushfstring(L, + "error calling " LUA_QL("print") " (%s)", + lua_tostring(L, -1))); + } + } + lua_settop(L, 0); /* clear stack */ + fputs("\n", stdout); + fflush(stdout); + progname = oldprogname; +} + + +static int handle_script (lua_State *L, char **argv, int n) { + int status; + const char *fname; + int narg = getargs(L, argv, n); /* collect arguments */ + lua_setglobal(L, "arg"); + fname = argv[n]; + if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) + fname = NULL; /* stdin */ + status = luaL_loadfile(L, fname); + lua_insert(L, -(narg+1)); + if (status == 0) + status = docall(L, narg, 0); + else + lua_pop(L, narg); + return report(L, status); +} + + +/* check that argument has no extra characters at the end */ +#define notail(x) {if ((x)[2] != '\0') return -1;} + + +static int collectargs (char **argv, int *pi, int *pv, int *pe) { + int i; + for (i = 1; argv[i] != NULL; i++) { + if (argv[i][0] != '-') /* not an option? */ + return i; + switch (argv[i][1]) { /* option */ + case '-': + notail(argv[i]); + return (argv[i+1] != NULL ? i+1 : 0); + case '\0': + return i; + case 'i': + notail(argv[i]); + *pi = 1; /* go through */ + case 'v': + notail(argv[i]); + *pv = 1; + break; + case 'e': + *pe = 1; /* go through */ + case 'l': + if (argv[i][2] == '\0') { + i++; + if (argv[i] == NULL) return -1; + } + break; + default: return -1; /* invalid option */ + } + } + return 0; +} + + +static int runargs (lua_State *L, char **argv, int n) { + int i; + for (i = 1; i < n; i++) { + if (argv[i] == NULL) continue; + lua_assert(argv[i][0] == '-'); + switch (argv[i][1]) { /* option */ + case 'e': { + const char *chunk = argv[i] + 2; + if (*chunk == '\0') chunk = argv[++i]; + lua_assert(chunk != NULL); + if (dostring(L, chunk, "=(command line)") != 0) + return 1; + break; + } + case 'l': { + const char *filename = argv[i] + 2; + if (*filename == '\0') filename = argv[++i]; + lua_assert(filename != NULL); + if (dolibrary(L, filename)) + return 1; /* stop if file fails */ + break; + } + default: break; + } + } + return 0; +} + + +static int handle_luainit (lua_State *L) { + const char *init = getenv(LUA_INIT); + if (init == NULL) return 0; /* status OK */ + else if (init[0] == '@') + return dofile(L, init+1); + else + return dostring(L, init, "=" LUA_INIT); +} + + +struct Smain { + int argc; + char **argv; + int status; +}; + + +static int pmain (lua_State *L) { + struct Smain *s = (struct Smain *)lua_touserdata(L, 1); + char **argv = s->argv; + int script; + int has_i = 0, has_v = 0, has_e = 0; + globalL = L; + if (argv[0] && argv[0][0]) progname = argv[0]; + lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ + luaL_openlibs(L); /* open libraries */ + lua_gc(L, LUA_GCRESTART, 0); + s->status = handle_luainit(L); + if (s->status != 0) return 0; + script = collectargs(argv, &has_i, &has_v, &has_e); + if (script < 0) { /* invalid args? */ + print_usage(); + s->status = 1; + return 0; + } + if (has_v) print_version(); + s->status = runargs(L, argv, (script > 0) ? script : s->argc); + if (s->status != 0) return 0; + if (script) + s->status = handle_script(L, argv, script); + if (s->status != 0) return 0; + if (has_i) + dotty(L); + else if (script == 0 && !has_e && !has_v) { + if (lua_stdin_is_tty()) { + print_version(); + dotty(L); + } + else dofile(L, NULL); /* executes stdin as a file */ + } + return 0; +} + + +int main (int argc, char **argv) { + int status; + struct Smain s; + lua_State *L = lua_open(); /* create state */ + if (L == NULL) { + l_message(argv[0], "cannot create state: not enough memory"); + return EXIT_FAILURE; + } + s.argc = argc; + s.argv = argv; + status = lua_cpcall(L, &pmain, &s); + report(L, status); + lua_close(L); + return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; +} + diff --git a/lib/lua/src/lua.h b/lib/lua/src/lua.h new file mode 100644 index 0000000..a4b73e7 --- /dev/null +++ b/lib/lua/src/lua.h @@ -0,0 +1,388 @@ +/* +** $Id: lua.h,v 1.218.1.7 2012/01/13 20:36:20 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.5" +#define LUA_VERSION_NUM 501 +#define LUA_COPYRIGHT "Copyright (C) 1994-2012 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-2012 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/lib/lua/src/luac.c b/lib/lua/src/luac.c new file mode 100644 index 0000000..d070173 --- /dev/null +++ b/lib/lua/src/luac.c @@ -0,0 +1,200 @@ +/* +** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $ +** Lua compiler (saves bytecodes to files; also list bytecodes) +** See Copyright Notice in lua.h +*/ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define luac_c +#define LUA_CORE + +#include "lua.h" +#include "lauxlib.h" + +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstring.h" +#include "lundump.h" + +#define PROGNAME "luac" /* default program name */ +#define OUTPUT PROGNAME ".out" /* default output file */ + +static int listing=0; /* list bytecodes? */ +static int dumping=1; /* dump bytecodes? */ +static int stripping=0; /* strip debug information? */ +static char Output[]={ OUTPUT }; /* default output file name */ +static const char* output=Output; /* actual output file name */ +static const char* progname=PROGNAME; /* actual program name */ + +static void fatal(const char* message) +{ + fprintf(stderr,"%s: %s\n",progname,message); + exit(EXIT_FAILURE); +} + +static void cannot(const char* what) +{ + fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); + exit(EXIT_FAILURE); +} + +static void usage(const char* message) +{ + if (*message=='-') + fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); + else + fprintf(stderr,"%s: %s\n",progname,message); + fprintf(stderr, + "usage: %s [options] [filenames].\n" + "Available options are:\n" + " - process stdin\n" + " -l list\n" + " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n", + progname,Output); + exit(EXIT_FAILURE); +} + +#define IS(s) (strcmp(argv[i],s)==0) + +static int doargs(int argc, char* argv[]) +{ + int i; + int version=0; + if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; + for (i=1; i<argc; i++) + { + if (*argv[i]!='-') /* end of options; keep it */ + break; + else if (IS("--")) /* end of options; skip it */ + { + ++i; + if (version) ++version; + break; + } + else if (IS("-")) /* end of options; use stdin */ + break; + else if (IS("-l")) /* list */ + ++listing; + else if (IS("-o")) /* output file */ + { + output=argv[++i]; + if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument"); + if (IS("-")) output=NULL; + } + else if (IS("-p")) /* parse only */ + dumping=0; + else if (IS("-s")) /* strip debug information */ + stripping=1; + else if (IS("-v")) /* show version */ + ++version; + else /* unknown option */ + usage(argv[i]); + } + if (i==argc && (listing || !dumping)) + { + dumping=0; + argv[--i]=Output; + } + if (version) + { + printf("%s %s\n",LUA_RELEASE,LUA_COPYRIGHT); + if (version==argc-1) exit(EXIT_SUCCESS); + } + return i; +} + +#define toproto(L,i) (clvalue(L->top+(i))->l.p) + +static const Proto* combine(lua_State* L, int n) +{ + if (n==1) + return toproto(L,-1); + else + { + int i,pc; + Proto* f=luaF_newproto(L); + setptvalue2s(L,L->top,f); incr_top(L); + f->source=luaS_newliteral(L,"=(" PROGNAME ")"); + f->maxstacksize=1; + pc=2*n+1; + f->code=luaM_newvector(L,pc,Instruction); + f->sizecode=pc; + f->p=luaM_newvector(L,n,Proto*); + f->sizep=n; + pc=0; + for (i=0; i<n; i++) + { + f->p[i]=toproto(L,i-n-1); + f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); + f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); + } + f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); + return f; + } +} + +static int writer(lua_State* L, const void* p, size_t size, void* u) +{ + UNUSED(L); + return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); +} + +struct Smain { + int argc; + char** argv; +}; + +static int pmain(lua_State* L) +{ + struct Smain* s = (struct Smain*)lua_touserdata(L, 1); + int argc=s->argc; + char** argv=s->argv; + const Proto* f; + int i; + if (!lua_checkstack(L,argc)) fatal("too many input files"); + for (i=0; i<argc; i++) + { + const char* filename=IS("-") ? NULL : argv[i]; + if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1)); + } + f=combine(L,argc); + if (listing) luaU_print(f,listing>1); + if (dumping) + { + FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); + if (D==NULL) cannot("open"); + lua_lock(L); + luaU_dump(L,f,writer,D,stripping); + lua_unlock(L); + if (ferror(D)) cannot("write"); + if (fclose(D)) cannot("close"); + } + return 0; +} + +int main(int argc, char* argv[]) +{ + lua_State* L; + struct Smain s; + int i=doargs(argc,argv); + argc-=i; argv+=i; + if (argc<=0) usage("no input files given"); + L=lua_open(); + if (L==NULL) fatal("not enough memory for state"); + s.argc=argc; + s.argv=argv; + if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1)); + lua_close(L); + return EXIT_SUCCESS; +} diff --git a/lib/lua/src/luaconf.h b/lib/lua/src/luaconf.h new file mode 100644 index 0000000..1521f0c --- /dev/null +++ b/lib/lua/src/luaconf.h @@ -0,0 +1,771 @@ +/* +** $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 + + +/* MINETEST-SPECIFIC CHANGE: make sure API functions conform to the C ABI. */ +#if defined(__cplusplus) +#define LUAI_API_EXTERN extern "C" +#else +#define LUAI_API_EXTERN extern +#endif + + +/* +@@ 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 LUAI_API_EXTERN __declspec(dllexport) +#else +#define LUA_API LUAI_API_EXTERN __declspec(dllimport) +#endif + +#else + +#define LUA_API LUAI_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/lib/lua/src/lualib.h b/lib/lua/src/lualib.h new file mode 100644 index 0000000..469417f --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lundump.c b/lib/lua/src/lundump.c new file mode 100644 index 0000000..8010a45 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lundump.h b/lib/lua/src/lundump.h new file mode 100644 index 0000000..c80189d --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lvm.c b/lib/lua/src/lvm.c new file mode 100644 index 0000000..e0a0cd8 --- /dev/null +++ b/lib/lua/src/lvm.c @@ -0,0 +1,767 @@ +/* +** $Id: lvm.c,v 2.63.1.5 2011/08/17 20:43:11 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; + TValue temp; + 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); + h->flags = 0; + 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; + } + /* else repeat with `tm' */ + setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ + t = &temp; + } + 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/lib/lua/src/lvm.h b/lib/lua/src/lvm.h new file mode 100644 index 0000000..bfe4f56 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lzio.c b/lib/lua/src/lzio.c new file mode 100644 index 0000000..293edd5 --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/lzio.h b/lib/lua/src/lzio.h new file mode 100644 index 0000000..51d695d --- /dev/null +++ b/lib/lua/src/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/lib/lua/src/print.c b/lib/lua/src/print.c new file mode 100644 index 0000000..e240cfc --- /dev/null +++ b/lib/lua/src/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/minetest.conf.example b/minetest.conf.example new file mode 100644 index 0000000..2f15341 --- /dev/null +++ b/minetest.conf.example @@ -0,0 +1,3524 @@ +# This file contains a list of all available settings and their default value for minetest.conf + +# By default, all the settings are commented and not functional. +# Uncomment settings by removing the preceding #. + +# minetest.conf is read by default from: +# ../minetest.conf +# ../../minetest.conf +# Any other path can be chosen by passing the path as a parameter +# to the program, eg. "minetest.exe --config ../minetest.conf.example". + +# Further documentation: +# http://wiki.minetest.net/ + +# +# Controls +# + +## General + +# If enabled, you can place blocks at the position (feet + eye level) where you stand. +# This is helpful when working with nodeboxes in small areas. +# type: bool +# enable_build_where_you_stand = false + +# Smooths camera when looking around. Also called look or mouse smoothing. +# Useful for recording videos. +# type: bool +# cinematic = false + +# Smooths rotation of camera. 0 to disable. +# type: float min: 0 max: 0.99 +# camera_smoothing = 0.0 + +# Smooths rotation of camera in cinematic mode. 0 to disable. +# type: float min: 0 max: 0.99 +# cinematic_camera_smoothing = 0.7 + +# If enabled, "Aux1" key instead of "Sneak" key is used for climbing down and +# descending. +# type: bool +# aux1_descends = false + +# Double-tapping the jump key toggles fly mode. +# type: bool +# doubletap_jump = false + +# If disabled, "Aux1" key is used to fly fast if both fly and fast mode are +# enabled. +# type: bool +# always_fly_fast = true + +# The time in seconds it takes between repeated node placements when holding +# the place button. +# type: float min: 0.25 max: 2 +# repeat_place_time = 0.25 + +# Automatically jump up single-node obstacles. +# type: bool +# autojump = false + +# Prevent digging and placing from repeating when holding the mouse buttons. +# Enable this when you dig or place too often by accident. +# type: bool +# safe_dig_and_place = false + +## Keyboard and Mouse + +# Invert vertical mouse movement. +# type: bool +# invert_mouse = false + +# Mouse sensitivity multiplier. +# type: float min: 0.001 max: 10 +# mouse_sensitivity = 0.2 + +## Touchscreen + +# The length in pixels it takes for touch screen interaction to start. +# type: int min: 0 max: 100 +# touchscreen_threshold = 20 + +# (Android) Fixes the position of virtual joystick. +# If disabled, virtual joystick will center to first-touch's position. +# type: bool +# fixed_virtual_joystick = false + +# (Android) Use virtual joystick to trigger "Aux1" button. +# If enabled, virtual joystick will also tap "Aux1" button when out of main circle. +# type: bool +# virtual_joystick_triggers_aux1 = false + +# +# Graphics and Audio +# + +## Graphics + +### Screen + +# Width component of the initial window size. Ignored in fullscreen mode. +# type: int min: 1 max: 65535 +# screen_w = 1024 + +# Height component of the initial window size. Ignored in fullscreen mode. +# type: int min: 1 max: 65535 +# screen_h = 600 + +# Save window size automatically when modified. +# type: bool +# autosave_screensize = true + +# Fullscreen mode. +# type: bool +# fullscreen = false + +# Open the pause menu when the window's focus is lost. Does not pause if a formspec is +# open. +# type: bool +# pause_on_lost_focus = false + +### FPS + +# If FPS would go higher than this, limit it by sleeping +# to not waste CPU power for no benefit. +# type: int min: 1 max: 4294967295 +# fps_max = 60 + +# Vertical screen synchronization. +# type: bool +# vsync = false + +# Maximum FPS when the window is not focused, or when the game is paused. +# type: int min: 1 max: 4294967295 +# fps_max_unfocused = 20 + +# View distance in nodes. +# type: int min: 20 max: 4000 +# viewing_range = 190 + +# Undersampling is similar to using a lower screen resolution, but it applies +# to the game world only, keeping the GUI intact. +# It should give a significant performance boost at the cost of less detailed image. +# Higher values result in a less detailed image. +# type: int min: 1 max: 8 +# undersampling = 1 + +### Graphics Effects + +# Makes all liquids opaque +# type: bool +# opaque_water = false + +# Leaves style: +# - Fancy: all faces visible +# - Simple: only outer faces, if defined special_tiles are used +# - Opaque: disable transparency +# type: enum values: fancy, simple, opaque +# leaves_style = fancy + +# Connects glass if supported by node. +# type: bool +# connected_glass = false + +# Enable smooth lighting with simple ambient occlusion. +# Disable for speed or for different looks. +# type: bool +# smooth_lighting = true + +# Enables tradeoffs that reduce CPU load or increase rendering performance +# at the expense of minor visual glitches that do not impact game playability. +# type: bool +# performance_tradeoffs = false + +# Adds particles when digging a node. +# type: bool +# enable_particles = true + +### 3d + +# 3D support. +# Currently supported: +# - none: no 3d output. +# - anaglyph: cyan/magenta color 3d. +# - interlaced: odd/even line based polarisation screen support. +# - topbottom: split screen top/bottom. +# - sidebyside: split screen side by side. +# - crossview: Cross-eyed 3d +# - pageflip: quadbuffer based 3d. +# Note that the interlaced mode requires shaders to be enabled. +# type: enum values: none, anaglyph, interlaced, topbottom, sidebyside, crossview, pageflip +# 3d_mode = none + +# Strength of 3D mode parallax. +# type: float min: -0.087 max: 0.087 +# 3d_paralax_strength = 0.025 + +### Bobbing + +# Arm inertia, gives a more realistic movement of +# the arm when the camera moves. +# type: bool +# arm_inertia = true + +# Enable view bobbing and amount of view bobbing. +# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double. +# type: float min: 0 max: 7.9 +# view_bobbing_amount = 1.0 + +# Multiplier for fall bobbing. +# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double. +# type: float min: 0 max: 100 +# fall_bobbing_amount = 0.03 + +### Camera + +# Camera 'near clipping plane' distance in nodes, between 0 and 0.25 +# Only works on GLES platforms. Most users will not need to change this. +# Increasing can reduce artifacting on weaker GPUs. +# 0.1 = Default, 0.25 = Good value for weaker tablets. +# type: float min: 0 max: 0.25 +# near_plane = 0.1 + +# Field of view in degrees. +# type: int min: 45 max: 160 +# fov = 72 + +# Alters the light curve by applying 'gamma correction' to it. +# Higher values make middle and lower light levels brighter. +# Value '1.0' leaves the light curve unaltered. +# This only has significant effect on daylight and artificial +# light, it has very little effect on natural night light. +# type: float min: 0.33 max: 3 +# display_gamma = 1.0 + +# The strength (darkness) of node ambient-occlusion shading. +# Lower is darker, Higher is lighter. The valid range of values for this +# setting is 0.25 to 4.0 inclusive. If the value is out of range it will be +# set to the nearest valid value. +# type: float min: 0.25 max: 4 +# ambient_occlusion_gamma = 2.2 + +### Screenshots + +# Path to save screenshots at. Can be an absolute or relative path. +# The folder will be created if it doesn't already exist. +# type: path +# screenshot_path = screenshots + +# Format of screenshots. +# type: enum values: png, jpg +# screenshot_format = png + +# Screenshot quality. Only used for JPEG format. +# 1 means worst quality; 100 means best quality. +# Use 0 for default quality. +# type: int min: 0 max: 100 +# screenshot_quality = 0 + +### Node and Entity Highlighting + +# Method used to highlight selected object. +# type: enum values: box, halo, none +# node_highlighting = box + +# Show entity selection boxes +# A restart is required after changing this. +# type: bool +# show_entity_selectionbox = false + +# Selection box border color (R,G,B). +# type: string +# selectionbox_color = (0,0,0) + +# Width of the selection box lines around nodes. +# type: int min: 1 max: 5 +# selectionbox_width = 2 + +# Crosshair color (R,G,B). +# Also controls the object crosshair color +# type: string +# crosshair_color = (255,255,255) + +# Crosshair alpha (opaqueness, between 0 and 255). +# This also applies to the object crosshair. +# type: int min: 0 max: 255 +# crosshair_alpha = 255 + +### Fog + +# Whether to fog out the end of the visible area. +# type: bool +# enable_fog = true + +# Make fog and sky colors depend on daytime (dawn/sunset) and view direction. +# type: bool +# directional_colored_fog = true + +# Fraction of the visible distance at which fog starts to be rendered +# type: float min: 0 max: 0.99 +# fog_start = 0.4 + +### Clouds + +# Clouds are a client side effect. +# type: bool +# enable_clouds = true + +# Use 3D cloud look instead of flat. +# type: bool +# enable_3d_clouds = true + +### Filtering and Antialiasing + +# Use mipmapping to scale textures. May slightly increase performance, +# especially when using a high resolution texture pack. +# Gamma correct downscaling is not supported. +# type: bool +# mip_map = false + +# Use anisotropic filtering when viewing at textures from an angle. +# type: bool +# anisotropic_filter = false + +# Use bilinear filtering when scaling textures. +# type: bool +# bilinear_filter = false + +# Use trilinear filtering when scaling textures. +# type: bool +# trilinear_filter = false + +# Filtered textures can blend RGB values with fully-transparent neighbors, +# which PNG optimizers usually discard, often resulting in dark or +# light edges to transparent textures. Apply a filter to clean that up +# at texture load time. This is automatically enabled if mipmapping is enabled. +# type: bool +# texture_clean_transparent = false + +# When using bilinear/trilinear/anisotropic filters, low-resolution textures +# can be blurred, so automatically upscale them with nearest-neighbor +# interpolation to preserve crisp pixels. This sets the minimum texture size +# for the upscaled textures; higher values look sharper, but require more +# memory. Powers of 2 are recommended. This setting is ONLY applied if +# bilinear/trilinear/anisotropic filtering is enabled. +# This is also used as the base node texture size for world-aligned +# texture autoscaling. +# type: int min: 1 max: 32768 +# texture_min_size = 64 + +# Use multi-sample antialiasing (MSAA) to smooth out block edges. +# This algorithm smooths out the 3D viewport while keeping the image sharp, +# but it doesn't affect the insides of textures +# (which is especially noticeable with transparent textures). +# Visible spaces appear between nodes when shaders are disabled. +# If set to 0, MSAA is disabled. +# A restart is required after changing this option. +# type: enum values: 0, 1, 2, 4, 8, 16 +# fsaa = 0 + +## Shaders + +# Shaders allow advanced visual effects and may increase performance on some video +# cards. +# This only works with the OpenGL video backend. +# type: bool +# enable_shaders = true + +### Tone Mapping + +# Enables Hable's 'Uncharted 2' filmic tone mapping. +# Simulates the tone curve of photographic film and how this approximates the +# appearance of high dynamic range images. Mid-range contrast is slightly +# enhanced, highlights and shadows are gradually compressed. +# type: bool +# tone_mapping = false + +### Waving Nodes + +# Set to true to enable waving leaves. +# Requires shaders to be enabled. +# type: bool +# enable_waving_leaves = false + +# Set to true to enable waving plants. +# Requires shaders to be enabled. +# type: bool +# enable_waving_plants = false + +# Set to true to enable waving liquids (like water). +# Requires shaders to be enabled. +# type: bool +# enable_waving_water = false + +# The maximum height of the surface of waving liquids. +# 4.0 = Wave height is two nodes. +# 0.0 = Wave doesn't move at all. +# Default is 1.0 (1/2 node). +# Requires waving liquids to be enabled. +# type: float min: 0 max: 4 +# water_wave_height = 1.0 + +# Length of liquid waves. +# Requires waving liquids to be enabled. +# type: float min: 0.1 +# water_wave_length = 20.0 + +# How fast liquid waves will move. Higher = faster. +# If negative, liquid waves will move backwards. +# Requires waving liquids to be enabled. +# type: float +# water_wave_speed = 5.0 + +### Dynamic shadows + +# Set to true to enable Shadow Mapping. +# Requires shaders to be enabled. +# type: bool +# enable_dynamic_shadows = false + +# Set the shadow strength gamma. +# Adjusts the intensity of in-game dynamic shadows. +# Lower value means lighter shadows, higher value means darker shadows. +# type: float min: 0.1 max: 10 +# shadow_strength_gamma = 1.0 + +# Maximum distance to render shadows. +# type: float min: 10 max: 1000 +# shadow_map_max_distance = 120.0 + +# Texture size to render the shadow map on. +# This must be a power of two. +# Bigger numbers create better shadows but it is also more expensive. +# type: int min: 128 max: 8192 +# shadow_map_texture_size = 1024 + +# Sets shadow texture quality to 32 bits. +# On false, 16 bits texture will be used. +# This can cause much more artifacts in the shadow. +# type: bool +# shadow_map_texture_32bit = true + +# Enable Poisson disk filtering. +# On true uses Poisson disk to make "soft shadows". Otherwise uses PCF filtering. +# type: bool +# shadow_poisson_filter = true + +# Define shadow filtering quality. +# This simulates the soft shadows effect by applying a PCF or Poisson disk +# but also uses more resources. +# type: enum values: 0, 1, 2 +# shadow_filters = 1 + +# Enable colored shadows. +# On true translucent nodes cast colored shadows. This is expensive. +# type: bool +# shadow_map_color = false + +# Spread a complete update of shadow map over given amount of frames. +# Higher values might make shadows laggy, lower values +# will consume more resources. +# Minimum value: 1; maximum value: 16 +# type: int min: 1 max: 16 +# shadow_update_frames = 8 + +# Set the soft shadow radius size. +# Lower values mean sharper shadows, bigger values mean softer shadows. +# Minimum value: 1.0; maximum value: 15.0 +# type: float min: 1 max: 15 +# shadow_soft_radius = 5.0 + +# Set the tilt of Sun/Moon orbit in degrees. +# Value of 0 means no tilt / vertical orbit. +# Minimum value: 0.0; maximum value: 60.0 +# type: float min: 0 max: 60 +# shadow_sky_body_orbit_tilt = 0.0 + +## Audio + +# Volume of all sounds. +# Requires the sound system to be enabled. +# type: float min: 0 max: 1 +# sound_volume = 0.7 + +# Whether to mute sounds. You can unmute sounds at any time, unless the +# sound system is disabled (enable_sound=false). +# In-game, you can toggle the mute state with the mute key or by using the +# pause menu. +# type: bool +# mute_sound = false + +## User Interfaces + +# Set the language. Leave empty to use the system language. +# A restart is required after changing this. +# type: enum values: , be, bg, ca, cs, da, de, el, en, eo, es, et, eu, fi, fr, gd, gl, hu, id, it, ja, jbo, kk, ko, lt, lv, ms, nb, nl, nn, pl, pt, pt_BR, ro, ru, sk, sl, sr_Cyrl, sr_Latn, sv, sw, tr, uk, vi, zh_CN, zh_TW +# language = + +### GUIs + +# Scale GUI by a user specified value. +# Use a nearest-neighbor-anti-alias filter to scale the GUI. +# This will smooth over some of the rough edges, and blend +# pixels when scaling down, at the cost of blurring some +# edge pixels when images are scaled by non-integer sizes. +# type: float min: 0.5 max: 20 +# gui_scaling = 1.0 + +# Enables animation of inventory items. +# type: bool +# inventory_items_animations = false + +# Formspec full-screen background opacity (between 0 and 255). +# type: int min: 0 max: 255 +# formspec_fullscreen_bg_opacity = 140 + +# Formspec full-screen background color (R,G,B). +# type: string +# formspec_fullscreen_bg_color = (0,0,0) + +# When gui_scaling_filter is true, all GUI images need to be +# filtered in software, but some images are generated directly +# to hardware (e.g. render-to-texture for nodes in inventory). +# type: bool +# gui_scaling_filter = false + +# When gui_scaling_filter_txr2img is true, copy those images +# from hardware to software for scaling. When false, fall back +# to the old scaling method, for video drivers that don't +# properly support downloading textures back from hardware. +# type: bool +# gui_scaling_filter_txr2img = true + +# Delay showing tooltips, stated in milliseconds. +# type: int min: 0 max: 1.844674407371e+19 +# tooltip_show_delay = 400 + +# Append item name to tooltip. +# type: bool +# tooltip_append_itemname = false + +# Use a cloud animation for the main menu background. +# type: bool +# menu_clouds = true + +### HUD + +# Modifies the size of the HUD elements. +# type: float min: 0.5 max: 20 +# hud_scaling = 1.0 + +# Whether name tag backgrounds should be shown by default. +# Mods may still set a background. +# type: bool +# show_nametag_backgrounds = true + +### Chat + +# Maximum number of recent chat messages to show +# type: int min: 2 max: 20 +# recent_chat_messages = 6 + +# In-game chat console height, between 0.1 (10%) and 1.0 (100%). +# type: float min: 0.1 max: 1 +# console_height = 0.6 + +# In-game chat console background color (R,G,B). +# type: string +# console_color = (0,0,0) + +# In-game chat console background alpha (opaqueness, between 0 and 255). +# type: int min: 0 max: 255 +# console_alpha = 200 + +# Maximum proportion of current window to be used for hotbar. +# Useful if there's something to be displayed right or left of hotbar. +# type: float min: 0.001 max: 1 +# hud_hotbar_max_width = 1.0 + +# Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output. +# type: bool +# clickable_chat_weblinks = true + +# Optional override for chat weblink color. +# type: string +# chat_weblink_color = + +# Font size of the recent chat text and chat prompt in point (pt). +# Value 0 will use the default font size. +# type: int min: 0 max: 72 +# chat_font_size = 0 + +### Content Repository + +# The URL for the content repository +# type: string +# contentdb_url = https://content.minetest.net + +# Comma-separated list of flags to hide in the content repository. +# "nonfree" can be used to hide packages which do not qualify as 'free software', +# as defined by the Free Software Foundation. +# You can also specify content ratings. +# These flags are independent from Minetest versions, +# so see a full list at https://content.minetest.net/help/content_flags/ +# type: string +# contentdb_flag_blacklist = nonfree, desktop_default + +# Maximum number of concurrent downloads. Downloads exceeding this limit will be queued. +# This should be lower than curl_parallel_limit. +# type: int min: 1 +# contentdb_max_concurrent_downloads = 3 + +# +# Client and Server +# + +## Client + +# Save the map received by the client on disk. +# type: bool +# enable_local_map_saving = false + +# URL to the server list displayed in the Multiplayer Tab. +# type: string +# serverlist_url = servers.minetest.net + +# If enabled, account registration is separate from login in the UI. +# If disabled, new accounts will be registered automatically when logging in. +# type: bool +# enable_split_login_register = true + +## Server + +# Name of the player. +# When running a server, clients connecting with this name are admins. +# When starting from the main menu, this is overridden. +# type: string +# name = + +### Serverlist and MOTD + +# Name of the server, to be displayed when players join and in the serverlist. +# type: string +# server_name = Minetest server + +# Description of server, to be displayed when players join and in the serverlist. +# type: string +# server_description = mine here + +# Domain name of server, to be displayed in the serverlist. +# type: string +# server_address = game.minetest.net + +# Homepage of server, to be displayed in the serverlist. +# type: string +# server_url = https://minetest.net + +# Automatically report to the serverlist. +# type: bool +# server_announce = false + +# Announce to this serverlist. +# type: string +# serverlist_url = servers.minetest.net + +# Message of the day displayed to players connecting. +# type: string +# motd = + +# Maximum number of players that can be connected simultaneously. +# type: int min: 0 max: 65535 +# max_users = 15 + +# If this is set, players will always (re)spawn at the given position. +# type: string +# static_spawnpoint = + +### Networking + +# Network port to listen (UDP). +# This value will be overridden when starting from the main menu. +# type: int min: 1 max: 65535 +# port = 30000 + +# The network interface that the server listens on. +# type: string +# bind_address = + +# Enable to disallow old clients from connecting. +# Older clients are compatible in the sense that they will not crash when connecting +# to new servers, but they may not support all new features that you are expecting. +# type: bool +# strict_protocol_version_checking = false + +# Specifies URL from which client fetches media instead of using UDP. +# $filename should be accessible from $remote_media$filename via cURL +# (obviously, remote_media should end with a slash). +# Files that are not present will be fetched the usual way. +# type: string +# remote_media = + +# Enable/disable running an IPv6 server. +# Ignored if bind_address is set. +# Needs enable_ipv6 to be enabled. +# type: bool +# ipv6_server = false + +## Server Security + +# New users need to input this password. +# type: string +# default_password = + +# If enabled, players cannot join without a password or change theirs to an empty password. +# type: bool +# disallow_empty_password = false + +# The privileges that new users automatically get. +# See /privs in game for a full list on your server and mod configuration. +# type: string +# default_privs = interact, shout + +# Privileges that players with basic_privs can grant +# type: string +# basic_privs = interact, shout + +# If enabled, disable cheat prevention in multiplayer. +# type: bool +# disable_anticheat = false + +# If enabled, actions are recorded for rollback. +# This option is only read when server starts. +# type: bool +# enable_rollback_recording = false + +### Client-side Modding + +# Restricts the access of certain client-side functions on servers. +# Combine the byteflags below to restrict client-side features, or set to 0 +# for no restrictions: +# LOAD_CLIENT_MODS: 1 (disable loading client-provided mods) +# CHAT_MESSAGES: 2 (disable send_chat_message call client-side) +# READ_ITEMDEFS: 4 (disable get_item_def call client-side) +# READ_NODEDEFS: 8 (disable get_node_def call client-side) +# LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to +# csm_restriction_noderange) +# READ_PLAYERINFO: 32 (disable get_player_names call client-side) +# type: int min: 0 max: 63 +# csm_restriction_flags = 62 + +# If the CSM restriction for node range is enabled, get_node calls are limited +# to this distance from the player to the node. +# type: int min: 0 max: 4294967295 +# csm_restriction_noderange = 0 + +### Chat + +# Remove color codes from incoming chat messages +# Use this to stop players from being able to use color in their messages +# type: bool +# strip_color_codes = false + +# Set the maximum length of a chat message (in characters) sent by clients. +# type: int min: 10 max: 65535 +# chat_message_max_size = 500 + +# Amount of messages a player may send per 10 seconds. +# type: float min: 1 +# chat_message_limit_per_10sec = 10.0 + +# Kick players who sent more than X messages per 10 seconds. +# type: int min: 1 max: 65535 +# chat_message_limit_trigger_kick = 50 + +## Server Gameplay + +# Controls length of day/night cycle. +# Examples: +# 72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged. +# type: int min: 0 +# time_speed = 72 + +# Time of day when a new world is started, in millihours (0-23999). +# type: int min: 0 max: 23999 +# world_start_time = 6125 + +# Time in seconds for item entity (dropped items) to live. +# Setting it to -1 disables the feature. +# type: int min: -1 +# item_entity_ttl = 900 + +# Specifies the default stack size of nodes, items and tools. +# Note that mods or games may explicitly set a stack for certain (or all) items. +# type: int min: 1 max: 65535 +# default_stack_max = 99 + +### Physics + +# Horizontal and vertical acceleration on ground or when climbing, +# in nodes per second per second. +# type: float min: 0 +# movement_acceleration_default = 3.0 + +# Horizontal acceleration in air when jumping or falling, +# in nodes per second per second. +# type: float min: 0 +# movement_acceleration_air = 2.0 + +# Horizontal and vertical acceleration in fast mode, +# in nodes per second per second. +# type: float min: 0 +# movement_acceleration_fast = 10.0 + +# Walking and flying speed, in nodes per second. +# type: float min: 0 +# movement_speed_walk = 4.0 + +# Sneaking speed, in nodes per second. +# type: float min: 0 +# movement_speed_crouch = 1.35 + +# Walking, flying and climbing speed in fast mode, in nodes per second. +# type: float min: 0 +# movement_speed_fast = 20.0 + +# Vertical climbing speed, in nodes per second. +# type: float min: 0 +# movement_speed_climb = 3.0 + +# Initial vertical speed when jumping, in nodes per second. +# type: float min: 0 +# movement_speed_jump = 6.5 + +# How much you are slowed down when moving inside a liquid. +# Decrease this to increase liquid resistance to movement. +# type: float min: 0.001 +# movement_liquid_fluidity = 1.0 + +# Maximum liquid resistance. Controls deceleration when entering liquid at +# high speed. +# type: float +# movement_liquid_fluidity_smooth = 0.5 + +# Controls sinking speed in liquid when idling. Negative values will cause +# you to rise instead. +# type: float +# movement_liquid_sink = 10.0 + +# Acceleration of gravity, in nodes per second per second. +# type: float +# movement_gravity = 9.81 + +# +# Mapgen +# + +# A chosen map seed for a new map, leave empty for random. +# Will be overridden when creating a new world in the main menu. +# type: string +# fixed_map_seed = + +# Name of map generator to be used when creating a new world. +# Creating a world in the main menu will override this. +# Current mapgens in a highly unstable state: +# - The optional floatlands of v7 (disabled by default). +# type: enum values: v7, valleys, carpathian, v5, flat, fractal, singlenode, v6 +# mg_name = v7 + +# Water surface level of the world. +# type: int min: -31000 max: 31000 +# water_level = 1 + +# From how far blocks are generated for clients, stated in mapblocks (16 nodes). +# type: int min: 1 max: 32767 +# max_block_generate_distance = 10 + +# Limit of map generation, in nodes, in all 6 directions from (0, 0, 0). +# Only mapchunks completely within the mapgen limit are generated. +# Value is stored per-world. +# type: int min: 0 max: 31007 +# mapgen_limit = 31007 + +# Global map generation attributes. +# In Mapgen v6 the 'decorations' flag controls all decorations except trees +# and jungle grass, in all other mapgens this flag controls all decorations. +# type: flags possible values: caves, dungeons, light, decorations, biomes, ores, nocaves, nodungeons, nolight, nodecorations, nobiomes, noores +# mg_flags = caves,dungeons,light,decorations,biomes,ores + +## Biome API noise parameters + +# Temperature variation for biomes. +# type: noise_params_2d +# mg_biome_np_heat = { +# offset = 50, +# scale = 50, +# spread = (1000, 1000, 1000), +# seed = 5349, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# Small-scale temperature variation for blending biomes on borders. +# type: noise_params_2d +# mg_biome_np_heat_blend = { +# offset = 0, +# scale = 1.5, +# spread = (8, 8, 8), +# seed = 13, +# octaves = 2, +# persistence = 1.0, +# lacunarity = 2.0, +# flags = eased +# } + +# Humidity variation for biomes. +# type: noise_params_2d +# mg_biome_np_humidity = { +# offset = 50, +# scale = 50, +# spread = (1000, 1000, 1000), +# seed = 842, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# Small-scale humidity variation for blending biomes on borders. +# type: noise_params_2d +# mg_biome_np_humidity_blend = { +# offset = 0, +# scale = 1.5, +# spread = (8, 8, 8), +# seed = 90003, +# octaves = 2, +# persistence = 1.0, +# lacunarity = 2.0, +# flags = eased +# } + +## Mapgen V5 + +# Map generation attributes specific to Mapgen v5. +# type: flags possible values: caverns, nocaverns +# mgv5_spflags = caverns + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgv5_cave_width = 0.09 + +# Y of upper limit of large caves. +# type: int min: -31000 max: 31000 +# mgv5_large_cave_depth = -256 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgv5_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgv5_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgv5_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgv5_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgv5_large_cave_flooded = 0.5 + +# Y-level of cavern upper limit. +# type: int min: -31000 max: 31000 +# mgv5_cavern_limit = -256 + +# Y-distance over which caverns expand to full size. +# type: int min: 0 max: 32767 +# mgv5_cavern_taper = 256 + +# Defines full size of caverns, smaller values create larger caverns. +# type: float +# mgv5_cavern_threshold = 0.7 + +# Lower Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgv5_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgv5_dungeon_ymax = 31000 + +### Noises + +# Variation of biome filler depth. +# type: noise_params_2d +# mgv5_np_filler_depth = { +# offset = 0, +# scale = 1, +# spread = (150, 150, 150), +# seed = 261, +# octaves = 4, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of terrain vertical scale. +# When noise is < -0.55 terrain is near-flat. +# type: noise_params_2d +# mgv5_np_factor = { +# offset = 0, +# scale = 1, +# spread = (250, 250, 250), +# seed = 920381, +# octaves = 3, +# persistence = 0.45, +# lacunarity = 2.0, +# flags = eased +# } + +# Y-level of average terrain surface. +# type: noise_params_2d +# mgv5_np_height = { +# offset = 0, +# scale = 10, +# spread = (250, 250, 250), +# seed = 84174, +# octaves = 4, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgv5_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgv5_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining giant caverns. +# type: noise_params_3d +# mgv5_np_cavern = { +# offset = 0, +# scale = 1, +# spread = (384, 128, 384), +# seed = 723, +# octaves = 5, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining terrain. +# type: noise_params_3d +# mgv5_np_ground = { +# offset = 0, +# scale = 40, +# spread = (80, 80, 80), +# seed = 983240, +# octaves = 4, +# persistence = 0.55, +# lacunarity = 2.0, +# flags = eased +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgv5_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +## Mapgen V6 + +# Map generation attributes specific to Mapgen v6. +# The 'snowbiomes' flag enables the new 5 biome system. +# When the 'snowbiomes' flag is enabled jungles are automatically enabled and +# the 'jungles' flag is ignored. +# type: flags possible values: jungles, biomeblend, mudflow, snowbiomes, flat, trees, nojungles, nobiomeblend, nomudflow, nosnowbiomes, noflat, notrees +# mgv6_spflags = jungles,biomeblend,mudflow,snowbiomes,noflat,trees + +# Deserts occur when np_biome exceeds this value. +# When the 'snowbiomes' flag is enabled, this is ignored. +# type: float +# mgv6_freq_desert = 0.45 + +# Sandy beaches occur when np_beach exceeds this value. +# type: float +# mgv6_freq_beach = 0.15 + +# Lower Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgv6_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgv6_dungeon_ymax = 31000 + +### Noises + +# Y-level of lower terrain and seabed. +# type: noise_params_2d +# mgv6_np_terrain_base = { +# offset = -4, +# scale = 20, +# spread = (250, 250, 250), +# seed = 82341, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Y-level of higher terrain that creates cliffs. +# type: noise_params_2d +# mgv6_np_terrain_higher = { +# offset = 20, +# scale = 16, +# spread = (500, 500, 500), +# seed = 85039, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Varies steepness of cliffs. +# type: noise_params_2d +# mgv6_np_steepness = { +# offset = 0.85, +# scale = 0.5, +# spread = (125, 125, 125), +# seed = -932, +# octaves = 5, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines distribution of higher terrain. +# type: noise_params_2d +# mgv6_np_height_select = { +# offset = 0.5, +# scale = 1, +# spread = (250, 250, 250), +# seed = 4213, +# octaves = 5, +# persistence = 0.69, +# lacunarity = 2.0, +# flags = eased +# } + +# Varies depth of biome surface nodes. +# type: noise_params_2d +# mgv6_np_mud = { +# offset = 4, +# scale = 2, +# spread = (200, 200, 200), +# seed = 91013, +# octaves = 3, +# persistence = 0.55, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines areas with sandy beaches. +# type: noise_params_2d +# mgv6_np_beach = { +# offset = 0, +# scale = 1, +# spread = (250, 250, 250), +# seed = 59420, +# octaves = 3, +# persistence = 0.50, +# lacunarity = 2.0, +# flags = eased +# } + +# Temperature variation for biomes. +# type: noise_params_2d +# mgv6_np_biome = { +# offset = 0, +# scale = 1, +# spread = (500, 500, 500), +# seed = 9130, +# octaves = 3, +# persistence = 0.50, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of number of caves. +# type: noise_params_2d +# mgv6_np_cave = { +# offset = 6, +# scale = 6, +# spread = (250, 250, 250), +# seed = 34329, +# octaves = 3, +# persistence = 0.50, +# lacunarity = 2.0, +# flags = eased +# } + +# Humidity variation for biomes. +# type: noise_params_2d +# mgv6_np_humidity = { +# offset = 0.5, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 72384, +# octaves = 3, +# persistence = 0.50, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines tree areas and tree density. +# type: noise_params_2d +# mgv6_np_trees = { +# offset = 0, +# scale = 1, +# spread = (125, 125, 125), +# seed = 2, +# octaves = 4, +# persistence = 0.66, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines areas where trees have apples. +# type: noise_params_2d +# mgv6_np_apple_trees = { +# offset = 0, +# scale = 1, +# spread = (100, 100, 100), +# seed = 342902, +# octaves = 3, +# persistence = 0.45, +# lacunarity = 2.0, +# flags = eased +# } + +## Mapgen V7 + +# Map generation attributes specific to Mapgen v7. +# 'ridges': Rivers. +# 'floatlands': Floating land masses in the atmosphere. +# 'caverns': Giant caves deep underground. +# type: flags possible values: mountains, ridges, floatlands, caverns, nomountains, noridges, nofloatlands, nocaverns +# mgv7_spflags = mountains,ridges,nofloatlands,caverns + +# Y of mountain density gradient zero level. Used to shift mountains vertically. +# type: int min: -31000 max: 31000 +# mgv7_mount_zero_level = 0 + +# Lower Y limit of floatlands. +# type: int min: -31000 max: 31000 +# mgv7_floatland_ymin = 1024 + +# Upper Y limit of floatlands. +# type: int min: -31000 max: 31000 +# mgv7_floatland_ymax = 4096 + +# Y-distance over which floatlands taper from full density to nothing. +# Tapering starts at this distance from the Y limit. +# For a solid floatland layer, this controls the height of hills/mountains. +# Must be less than or equal to half the distance between the Y limits. +# type: int min: 0 max: 32767 +# mgv7_floatland_taper = 256 + +# Exponent of the floatland tapering. Alters the tapering behaviour. +# Value = 1.0 creates a uniform, linear tapering. +# Values > 1.0 create a smooth tapering suitable for the default separated +# floatlands. +# Values < 1.0 (for example 0.25) create a more defined surface level with +# flatter lowlands, suitable for a solid floatland layer. +# type: float +# mgv7_float_taper_exp = 2.0 + +# Adjusts the density of the floatland layer. +# Increase value to increase density. Can be positive or negative. +# Value = 0.0: 50% of volume is floatland. +# Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test +# to be sure) creates a solid floatland layer. +# type: float +# mgv7_floatland_density = -0.6 + +# Surface level of optional water placed on a solid floatland layer. +# Water is disabled by default and will only be placed if this value is set +# to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the +# upper tapering). +# ***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***: +# When enabling water placement the floatlands must be configured and tested +# to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other +# required value depending on 'mgv7_np_floatland'), to avoid +# server-intensive extreme water flow and to avoid vast flooding of the +# world surface below. +# type: int min: -31000 max: 31000 +# mgv7_floatland_ywater = -31000 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgv7_cave_width = 0.09 + +# Y of upper limit of large caves. +# type: int min: -31000 max: 31000 +# mgv7_large_cave_depth = -33 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgv7_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgv7_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgv7_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgv7_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgv7_large_cave_flooded = 0.5 + +# Y-level of cavern upper limit. +# type: int min: -31000 max: 31000 +# mgv7_cavern_limit = -256 + +# Y-distance over which caverns expand to full size. +# type: int min: 0 max: 32767 +# mgv7_cavern_taper = 256 + +# Defines full size of caverns, smaller values create larger caverns. +# type: float +# mgv7_cavern_threshold = 0.7 + +# Lower Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgv7_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgv7_dungeon_ymax = 31000 + +### Noises + +# Y-level of higher terrain that creates cliffs. +# type: noise_params_2d +# mgv7_np_terrain_base = { +# offset = 4, +# scale = 70, +# spread = (600, 600, 600), +# seed = 82341, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Y-level of lower terrain and seabed. +# type: noise_params_2d +# mgv7_np_terrain_alt = { +# offset = 4, +# scale = 25, +# spread = (600, 600, 600), +# seed = 5934, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Varies roughness of terrain. +# Defines the 'persistence' value for terrain_base and terrain_alt noises. +# type: noise_params_2d +# mgv7_np_terrain_persist = { +# offset = 0.6, +# scale = 0.1, +# spread = (2000, 2000, 2000), +# seed = 539, +# octaves = 3, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines distribution of higher terrain and steepness of cliffs. +# type: noise_params_2d +# mgv7_np_height_select = { +# offset = -8, +# scale = 16, +# spread = (500, 500, 500), +# seed = 4213, +# octaves = 6, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of biome filler depth. +# type: noise_params_2d +# mgv7_np_filler_depth = { +# offset = 0, +# scale = 1.2, +# spread = (150, 150, 150), +# seed = 261, +# octaves = 3, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of maximum mountain height (in nodes). +# type: noise_params_2d +# mgv7_np_mount_height = { +# offset = 256, +# scale = 112, +# spread = (1000, 1000, 1000), +# seed = 72449, +# octaves = 3, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines large-scale river channel structure. +# type: noise_params_2d +# mgv7_np_ridge_uwater = { +# offset = 0, +# scale = 1, +# spread = (1000, 1000, 1000), +# seed = 85039, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# 3D noise defining mountain structure and height. +# Also defines structure of floatland mountain terrain. +# type: noise_params_3d +# mgv7_np_mountain = { +# offset = -0.6, +# scale = 1, +# spread = (250, 350, 250), +# seed = 5333, +# octaves = 5, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining structure of river canyon walls. +# type: noise_params_3d +# mgv7_np_ridge = { +# offset = 0, +# scale = 1, +# spread = (100, 100, 100), +# seed = 6467, +# octaves = 4, +# persistence = 0.75, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining structure of floatlands. +# If altered from the default, the noise 'scale' (0.7 by default) may need +# to be adjusted, as floatland tapering functions best when this noise has +# a value range of approximately -2.0 to 2.0. +# type: noise_params_3d +# mgv7_np_floatland = { +# offset = 0, +# scale = 0.7, +# spread = (384, 96, 384), +# seed = 1009, +# octaves = 4, +# persistence = 0.75, +# lacunarity = 1.618, +# flags = +# } + +# 3D noise defining giant caverns. +# type: noise_params_3d +# mgv7_np_cavern = { +# offset = 0, +# scale = 1, +# spread = (384, 128, 384), +# seed = 723, +# octaves = 5, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgv7_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgv7_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgv7_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +## Mapgen Carpathian + +# Map generation attributes specific to Mapgen Carpathian. +# type: flags possible values: caverns, rivers, nocaverns, norivers +# mgcarpathian_spflags = caverns,norivers + +# Defines the base ground level. +# type: float +# mgcarpathian_base_level = 12.0 + +# Defines the width of the river channel. +# type: float +# mgcarpathian_river_width = 0.05 + +# Defines the depth of the river channel. +# type: float +# mgcarpathian_river_depth = 24.0 + +# Defines the width of the river valley. +# type: float +# mgcarpathian_valley_width = 0.25 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgcarpathian_cave_width = 0.09 + +# Y of upper limit of large caves. +# type: int min: -31000 max: 31000 +# mgcarpathian_large_cave_depth = -33 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgcarpathian_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgcarpathian_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgcarpathian_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgcarpathian_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgcarpathian_large_cave_flooded = 0.5 + +# Y-level of cavern upper limit. +# type: int min: -31000 max: 31000 +# mgcarpathian_cavern_limit = -256 + +# Y-distance over which caverns expand to full size. +# type: int min: 0 max: 32767 +# mgcarpathian_cavern_taper = 256 + +# Defines full size of caverns, smaller values create larger caverns. +# type: float +# mgcarpathian_cavern_threshold = 0.7 + +# Lower Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgcarpathian_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgcarpathian_dungeon_ymax = 31000 + +### Noises + +# Variation of biome filler depth. +# type: noise_params_2d +# mgcarpathian_np_filler_depth = { +# offset = 0, +# scale = 1, +# spread = (128, 128, 128), +# seed = 261, +# octaves = 3, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# First of 4 2D noises that together define hill/mountain range height. +# type: noise_params_2d +# mgcarpathian_np_height1 = { +# offset = 0, +# scale = 5, +# spread = (251, 251, 251), +# seed = 9613, +# octaves = 5, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# Second of 4 2D noises that together define hill/mountain range height. +# type: noise_params_2d +# mgcarpathian_np_height2 = { +# offset = 0, +# scale = 5, +# spread = (383, 383, 383), +# seed = 1949, +# octaves = 5, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# Third of 4 2D noises that together define hill/mountain range height. +# type: noise_params_2d +# mgcarpathian_np_height3 = { +# offset = 0, +# scale = 5, +# spread = (509, 509, 509), +# seed = 3211, +# octaves = 5, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# Fourth of 4 2D noises that together define hill/mountain range height. +# type: noise_params_2d +# mgcarpathian_np_height4 = { +# offset = 0, +# scale = 5, +# spread = (631, 631, 631), +# seed = 1583, +# octaves = 5, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the size/occurrence of rolling hills. +# type: noise_params_2d +# mgcarpathian_np_hills_terrain = { +# offset = 1, +# scale = 1, +# spread = (1301, 1301, 1301), +# seed = 1692, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the size/occurrence of ridged mountain ranges. +# type: noise_params_2d +# mgcarpathian_np_ridge_terrain = { +# offset = 1, +# scale = 1, +# spread = (1889, 1889, 1889), +# seed = 3568, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the size/occurrence of step mountain ranges. +# type: noise_params_2d +# mgcarpathian_np_step_terrain = { +# offset = 1, +# scale = 1, +# spread = (1889, 1889, 1889), +# seed = 4157, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the shape/size of rolling hills. +# type: noise_params_2d +# mgcarpathian_np_hills = { +# offset = 0, +# scale = 3, +# spread = (257, 257, 257), +# seed = 6604, +# octaves = 6, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the shape/size of ridged mountains. +# type: noise_params_2d +# mgcarpathian_np_ridge_mnt = { +# offset = 0, +# scale = 12, +# spread = (743, 743, 743), +# seed = 5520, +# octaves = 6, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the shape/size of step mountains. +# type: noise_params_2d +# mgcarpathian_np_step_mnt = { +# offset = 0, +# scale = 8, +# spread = (509, 509, 509), +# seed = 2590, +# octaves = 6, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that locates the river valleys and channels. +# type: noise_params_2d +# mgcarpathian_np_rivers = { +# offset = 0, +# scale = 1, +# spread = (1000, 1000, 1000), +# seed = 85039, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# 3D noise for mountain overhangs, cliffs, etc. Usually small variations. +# type: noise_params_3d +# mgcarpathian_np_mnt_var = { +# offset = 0, +# scale = 1, +# spread = (499, 499, 499), +# seed = 2490, +# octaves = 5, +# persistence = 0.55, +# lacunarity = 2.0, +# flags = +# } + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgcarpathian_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgcarpathian_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining giant caverns. +# type: noise_params_3d +# mgcarpathian_np_cavern = { +# offset = 0, +# scale = 1, +# spread = (384, 128, 384), +# seed = 723, +# octaves = 5, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgcarpathian_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +## Mapgen Flat + +# Map generation attributes specific to Mapgen Flat. +# Occasional lakes and hills can be added to the flat world. +# type: flags possible values: lakes, hills, caverns, nolakes, nohills, nocaverns +# mgflat_spflags = nolakes,nohills,nocaverns + +# Y of flat ground. +# type: int min: -31000 max: 31000 +# mgflat_ground_level = 8 + +# Y of upper limit of large caves. +# type: int min: -31000 max: 31000 +# mgflat_large_cave_depth = -33 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgflat_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgflat_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgflat_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgflat_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgflat_large_cave_flooded = 0.5 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgflat_cave_width = 0.09 + +# Terrain noise threshold for lakes. +# Controls proportion of world area covered by lakes. +# Adjust towards 0.0 for a larger proportion. +# type: float +# mgflat_lake_threshold = -0.45 + +# Controls steepness/depth of lake depressions. +# type: float +# mgflat_lake_steepness = 48.0 + +# Terrain noise threshold for hills. +# Controls proportion of world area covered by hills. +# Adjust towards 0.0 for a larger proportion. +# type: float +# mgflat_hill_threshold = 0.45 + +# Controls steepness/height of hills. +# type: float +# mgflat_hill_steepness = 64.0 + +# Y-level of cavern upper limit. +# type: int min: -31000 max: 31000 +# mgflat_cavern_limit = -256 + +# Y-distance over which caverns expand to full size. +# type: int min: 0 max: 32767 +# mgflat_cavern_taper = 256 + +# Defines full size of caverns, smaller values create larger caverns. +# type: float +# mgflat_cavern_threshold = 0.7 + +# Lower Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgflat_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgflat_dungeon_ymax = 31000 + +### Noises + +# Defines location and terrain of optional hills and lakes. +# type: noise_params_2d +# mgflat_np_terrain = { +# offset = 0, +# scale = 1, +# spread = (600, 600, 600), +# seed = 7244, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of biome filler depth. +# type: noise_params_2d +# mgflat_np_filler_depth = { +# offset = 0, +# scale = 1.2, +# spread = (150, 150, 150), +# seed = 261, +# octaves = 3, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgflat_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgflat_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining giant caverns. +# type: noise_params_3d +# mgflat_np_cavern = { +# offset = 0, +# scale = 1, +# spread = (384, 128, 384), +# seed = 723, +# octaves = 5, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgflat_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +## Mapgen Fractal + +# Map generation attributes specific to Mapgen Fractal. +# 'terrain' enables the generation of non-fractal terrain: +# ocean, islands and underground. +# type: flags possible values: terrain, noterrain +# mgfractal_spflags = terrain + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgfractal_cave_width = 0.09 + +# Y of upper limit of large caves. +# type: int min: -31000 max: 31000 +# mgfractal_large_cave_depth = -33 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgfractal_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgfractal_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgfractal_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgfractal_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgfractal_large_cave_flooded = 0.5 + +# Lower Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgfractal_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgfractal_dungeon_ymax = 31000 + +# Selects one of 18 fractal types. +# 1 = 4D "Roundy" Mandelbrot set. +# 2 = 4D "Roundy" Julia set. +# 3 = 4D "Squarry" Mandelbrot set. +# 4 = 4D "Squarry" Julia set. +# 5 = 4D "Mandy Cousin" Mandelbrot set. +# 6 = 4D "Mandy Cousin" Julia set. +# 7 = 4D "Variation" Mandelbrot set. +# 8 = 4D "Variation" Julia set. +# 9 = 3D "Mandelbrot/Mandelbar" Mandelbrot set. +# 10 = 3D "Mandelbrot/Mandelbar" Julia set. +# 11 = 3D "Christmas Tree" Mandelbrot set. +# 12 = 3D "Christmas Tree" Julia set. +# 13 = 3D "Mandelbulb" Mandelbrot set. +# 14 = 3D "Mandelbulb" Julia set. +# 15 = 3D "Cosine Mandelbulb" Mandelbrot set. +# 16 = 3D "Cosine Mandelbulb" Julia set. +# 17 = 4D "Mandelbulb" Mandelbrot set. +# 18 = 4D "Mandelbulb" Julia set. +# type: int min: 1 max: 18 +# mgfractal_fractal = 1 + +# Iterations of the recursive function. +# Increasing this increases the amount of fine detail, but also +# increases processing load. +# At iterations = 20 this mapgen has a similar load to mapgen V7. +# type: int min: 1 max: 65535 +# mgfractal_iterations = 11 + +# (X,Y,Z) scale of fractal in nodes. +# Actual fractal size will be 2 to 3 times larger. +# These numbers can be made very large, the fractal does +# not have to fit inside the world. +# Increase these to 'zoom' into the detail of the fractal. +# Default is for a vertically-squashed shape suitable for +# an island, set all 3 numbers equal for the raw shape. +# type: v3f +# mgfractal_scale = (4096.0, 1024.0, 4096.0) + +# (X,Y,Z) offset of fractal from world center in units of 'scale'. +# Can be used to move a desired point to (0, 0) to create a +# suitable spawn point, or to allow 'zooming in' on a desired +# point by increasing 'scale'. +# The default is tuned for a suitable spawn point for Mandelbrot +# sets with default parameters, it may need altering in other +# situations. +# Range roughly -2 to 2. Multiply by 'scale' for offset in nodes. +# type: v3f +# mgfractal_offset = (1.79, 0.0, 0.0) + +# W coordinate of the generated 3D slice of a 4D fractal. +# Determines which 3D slice of the 4D shape is generated. +# Alters the shape of the fractal. +# Has no effect on 3D fractals. +# Range roughly -2 to 2. +# type: float +# mgfractal_slice_w = 0.0 + +# Julia set only. +# X component of hypercomplex constant. +# Alters the shape of the fractal. +# Range roughly -2 to 2. +# type: float +# mgfractal_julia_x = 0.33 + +# Julia set only. +# Y component of hypercomplex constant. +# Alters the shape of the fractal. +# Range roughly -2 to 2. +# type: float +# mgfractal_julia_y = 0.33 + +# Julia set only. +# Z component of hypercomplex constant. +# Alters the shape of the fractal. +# Range roughly -2 to 2. +# type: float +# mgfractal_julia_z = 0.33 + +# Julia set only. +# W component of hypercomplex constant. +# Alters the shape of the fractal. +# Has no effect on 3D fractals. +# Range roughly -2 to 2. +# type: float +# mgfractal_julia_w = 0.33 + +### Noises + +# Y-level of seabed. +# type: noise_params_2d +# mgfractal_np_seabed = { +# offset = -14, +# scale = 9, +# spread = (600, 600, 600), +# seed = 41900, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of biome filler depth. +# type: noise_params_2d +# mgfractal_np_filler_depth = { +# offset = 0, +# scale = 1.2, +# spread = (150, 150, 150), +# seed = 261, +# octaves = 3, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgfractal_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgfractal_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgfractal_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +## Mapgen Valleys + +# Map generation attributes specific to Mapgen Valleys. +# 'altitude_chill': Reduces heat with altitude. +# 'humid_rivers': Increases humidity around rivers. +# 'vary_river_depth': If enabled, low humidity and high heat causes rivers +# to become shallower and occasionally dry. +# 'altitude_dry': Reduces humidity with altitude. +# type: flags possible values: altitude_chill, humid_rivers, vary_river_depth, altitude_dry, noaltitude_chill, nohumid_rivers, novary_river_depth, noaltitude_dry +# mgvalleys_spflags = altitude_chill,humid_rivers,vary_river_depth,altitude_dry + +# The vertical distance over which heat drops by 20 if 'altitude_chill' is +# enabled. Also the vertical distance over which humidity drops by 10 if +# 'altitude_dry' is enabled. +# type: int min: 0 max: 65535 +# mgvalleys_altitude_chill = 90 + +# Depth below which you'll find large caves. +# type: int min: -31000 max: 31000 +# mgvalleys_large_cave_depth = -33 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgvalleys_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgvalleys_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgvalleys_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgvalleys_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgvalleys_large_cave_flooded = 0.5 + +# Depth below which you'll find giant caverns. +# type: int min: -31000 max: 31000 +# mgvalleys_cavern_limit = -256 + +# Y-distance over which caverns expand to full size. +# type: int min: 0 max: 32767 +# mgvalleys_cavern_taper = 192 + +# Defines full size of caverns, smaller values create larger caverns. +# type: float +# mgvalleys_cavern_threshold = 0.6 + +# How deep to make rivers. +# type: int min: 0 max: 65535 +# mgvalleys_river_depth = 4 + +# How wide to make rivers. +# type: int min: 0 max: 65535 +# mgvalleys_river_size = 5 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgvalleys_cave_width = 0.09 + +# Lower Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgvalleys_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int min: -31000 max: 31000 +# mgvalleys_dungeon_ymax = 63 + +### Noises + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgvalleys_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgvalleys_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# The depth of dirt or other biome filler node. +# type: noise_params_2d +# mgvalleys_np_filler_depth = { +# offset = 0, +# scale = 1.2, +# spread = (256, 256, 256), +# seed = 1605, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 3D noise defining giant caverns. +# type: noise_params_3d +# mgvalleys_np_cavern = { +# offset = 0, +# scale = 1, +# spread = (768, 256, 768), +# seed = 59033, +# octaves = 6, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# Defines large-scale river channel structure. +# type: noise_params_2d +# mgvalleys_np_rivers = { +# offset = 0, +# scale = 1, +# spread = (256, 256, 256), +# seed = -6050, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Base terrain height. +# type: noise_params_2d +# mgvalleys_np_terrain_height = { +# offset = -10, +# scale = 50, +# spread = (1024, 1024, 1024), +# seed = 5202, +# octaves = 6, +# persistence = 0.4, +# lacunarity = 2.0, +# flags = eased +# } + +# Raises terrain to make valleys around the rivers. +# type: noise_params_2d +# mgvalleys_np_valley_depth = { +# offset = 5, +# scale = 4, +# spread = (512, 512, 512), +# seed = -1914, +# octaves = 1, +# persistence = 1.0, +# lacunarity = 2.0, +# flags = eased +# } + +# Slope and fill work together to modify the heights. +# type: noise_params_3d +# mgvalleys_np_inter_valley_fill = { +# offset = 0, +# scale = 1, +# spread = (256, 512, 256), +# seed = 1993, +# octaves = 6, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +# Amplifies the valleys. +# type: noise_params_2d +# mgvalleys_np_valley_profile = { +# offset = 0.6, +# scale = 0.5, +# spread = (512, 512, 512), +# seed = 777, +# octaves = 1, +# persistence = 1.0, +# lacunarity = 2.0, +# flags = eased +# } + +# Slope and fill work together to modify the heights. +# type: noise_params_2d +# mgvalleys_np_inter_valley_slope = { +# offset = 0.5, +# scale = 0.5, +# spread = (128, 128, 128), +# seed = 746, +# octaves = 1, +# persistence = 1.0, +# lacunarity = 2.0, +# flags = eased +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgvalleys_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +# +# Advanced +# + +## Developer Options + +# Enable Lua modding support on client. +# This support is experimental and API can change. +# type: bool +# enable_client_modding = false + +# Replaces the default main menu with a custom one. +# type: string +# main_menu_script = + +### Mod Security + +# Prevent mods from doing insecure things like running shell commands. +# type: bool +# secure.enable_security = true + +# Comma-separated list of trusted mods that are allowed to access insecure +# functions even when mod security is on (via request_insecure_environment()). +# type: string +# secure.trusted_mods = + +# Comma-separated list of mods that are allowed to access HTTP APIs, which +# allow them to upload and download data to/from the internet. +# type: string +# secure.http_mods = + +### Debugging + +# Level of logging to be written to debug.txt: +# - <nothing> (no logging) +# - none (messages with no level) +# - error +# - warning +# - action +# - info +# - verbose +# - trace +# type: enum values: , none, error, warning, action, info, verbose, trace +# debug_log_level = action + +# If the file size of debug.txt exceeds the number of megabytes specified in +# this setting when it is opened, the file is moved to debug.txt.1, +# deleting an older debug.txt.1 if it exists. +# debug.txt is only moved if this setting is positive. +# type: int min: 1 +# debug_log_size_max = 50 + +# Minimal level of logging to be written to chat. +# type: enum values: , none, error, warning, action, info, verbose, trace +# chat_log_level = error + +# Handling for deprecated Lua API calls: +# - none: Do not log deprecated calls +# - log: mimic and log backtrace of deprecated call (default). +# - error: abort on usage of deprecated call (suggested for mod developers). +# type: enum values: none, log, error +# deprecated_lua_api_handling = log + +# Enable random user input (only used for testing). +# type: bool +# random_input = false + +# Enable mod channels support. +# type: bool +# enable_mod_channels = false + +### Mod Profiler + +# Load the game profiler to collect game profiling data. +# Provides a /profiler command to access the compiled profile. +# Useful for mod developers and server operators. +# type: bool +# profiler.load = false + +# The default format in which profiles are being saved, +# when calling `/profiler save [format]` without format. +# type: enum values: txt, csv, lua, json, json_pretty +# profiler.default_report_format = txt + +# The file path relative to your worldpath in which profiles will be saved to. +# type: string +# profiler.report_path = "" + +# Instrument the methods of entities on registration. +# type: bool +# instrument.entity = true + +# Instrument the action function of Active Block Modifiers on registration. +# type: bool +# instrument.abm = true + +# Instrument the action function of Loading Block Modifiers on registration. +# type: bool +# instrument.lbm = true + +# Instrument chat commands on registration. +# type: bool +# instrument.chatcommand = true + +# Instrument global callback functions on registration. +# (anything you pass to a minetest.register_*() function) +# type: bool +# instrument.global_callback = true + +# Instrument builtin. +# This is usually only needed by core/builtin contributors +# type: bool +# instrument.builtin = false + +# Have the profiler instrument itself: +# * Instrument an empty function. +# This estimates the overhead, that instrumentation is adding (+1 function call). +# * Instrument the sampler being used to update the statistics. +# type: bool +# instrument.profiler = false + +### Engine profiler + +# Print the engine's profiling data in regular intervals (in seconds). +# 0 = disable. Useful for developers. +# type: int min: 0 +# profiler_print_interval = 0 + +## Advanced + +# Enable IPv6 support (for both client and server). +# Required for IPv6 connections to work at all. +# type: bool +# enable_ipv6 = true + +# If enabled, invalid world data won't cause the server to shut down. +# Only enable this if you know what you are doing. +# type: bool +# ignore_world_load_errors = false + +### Graphics + +# Path to shader directory. If no path is defined, default location will be used. +# type: path +# shader_path = + +# The rendering back-end. +# A restart is required after changing this. +# Note: On Android, stick with OGLES1 if unsure! App may fail to start otherwise. +# On other platforms, OpenGL is recommended. +# Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental) +# type: enum values: opengl, ogles1, ogles2 +# video_driver = opengl + +# Distance in nodes at which transparency depth sorting is enabled +# Use this to limit the performance impact of transparency depth sorting +# type: int min: 0 max: 128 +# transparency_sorting_distance = 16 + +# Enable vertex buffer objects. +# This should greatly improve graphics performance. +# type: bool +# enable_vbo = true + +# Radius of cloud area stated in number of 64 node cloud squares. +# Values larger than 26 will start to produce sharp cutoffs at cloud area corners. +# type: int min: 1 max: 62 +# cloud_radius = 12 + +# Whether node texture animations should be desynchronized per mapblock. +# type: bool +# desynchronize_mapblock_texture_animation = true + +# Enables caching of facedir rotated meshes. +# type: bool +# enable_mesh_cache = false + +# Delay between mesh updates on the client in ms. Increasing this will slow +# down the rate of mesh updates, thus reducing jitter on slower clients. +# type: int min: 0 max: 50 +# mesh_generation_interval = 0 + +# Size of the MapBlock cache of the mesh generator. Increasing this will +# increase the cache hit %, reducing the data being copied from the main +# thread, thus reducing jitter. +# type: int min: 0 max: 1000 +# meshgen_block_cache_size = 20 + +# True = 256 +# False = 128 +# Usable to make minimap smoother on slower machines. +# type: bool +# minimap_double_scan_height = true + +# Textures on a node may be aligned either to the node or to the world. +# The former mode suits better things like machines, furniture, etc., while +# the latter makes stairs and microblocks fit surroundings better. +# However, as this possibility is new, thus may not be used by older servers, +# this option allows enforcing it for certain node types. Note though that +# that is considered EXPERIMENTAL and may not work properly. +# type: enum values: disable, enable, force_solid, force_nodebox +# world_aligned_mode = enable + +# World-aligned textures may be scaled to span several nodes. However, +# the server may not send the scale you want, especially if you use +# a specially-designed texture pack; with this option, the client tries +# to determine the scale automatically basing on the texture size. +# See also texture_min_size. +# Warning: This option is EXPERIMENTAL! +# type: enum values: disable, enable, force +# autoscale_mode = disable + +### Font + +# type: bool +# font_bold = false + +# type: bool +# font_italic = false + +# Shadow offset (in pixels) of the default font. If 0, then shadow will not be drawn. +# type: int min: 0 max: 65535 +# font_shadow = 1 + +# Opaqueness (alpha) of the shadow behind the default font, between 0 and 255. +# type: int min: 0 max: 255 +# font_shadow_alpha = 127 + +# Font size of the default font where 1 unit = 1 pixel at 96 DPI +# type: int min: 5 max: 72 +# font_size = 16 + +# For pixel-style fonts that do not scale well, this ensures that font sizes used +# with this font will always be divisible by this value, in pixels. For instance, +# a pixel font 16 pixels tall should have this set to 16, so it will only ever be +# sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32. +# type: int min: 1 +# font_size_divisible_by = 1 + +# Path to the default font. Must be a TrueType font. +# The fallback font will be used if the font cannot be loaded. +# type: filepath +# font_path = fonts/Arimo-Regular.ttf + +# type: filepath +# font_path_bold = fonts/Arimo-Bold.ttf + +# type: filepath +# font_path_italic = fonts/Arimo-Italic.ttf + +# type: filepath +# font_path_bold_italic = fonts/Arimo-BoldItalic.ttf + +# Font size of the monospace font where 1 unit = 1 pixel at 96 DPI +# type: int min: 5 max: 72 +# mono_font_size = 16 + +# For pixel-style fonts that do not scale well, this ensures that font sizes used +# with this font will always be divisible by this value, in pixels. For instance, +# a pixel font 16 pixels tall should have this set to 16, so it will only ever be +# sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32. +# type: int min: 1 +# mono_font_size_divisible_by = 1 + +# Path to the monospace font. Must be a TrueType font. +# This font is used for e.g. the console and profiler screen. +# type: filepath +# mono_font_path = fonts/Cousine-Regular.ttf + +# type: filepath +# mono_font_path_bold = fonts/Cousine-Bold.ttf + +# type: filepath +# mono_font_path_italic = fonts/Cousine-Italic.ttf + +# type: filepath +# mono_font_path_bold_italic = fonts/Cousine-BoldItalic.ttf + +# Path of the fallback font. Must be a TrueType font. +# This font will be used for certain languages or if the default font is unavailable. +# type: filepath +# fallback_font_path = fonts/DroidSansFallbackFull.ttf + +### Lighting + +# Gradient of light curve at minimum light level. +# Controls the contrast of the lowest light levels. +# type: float min: 0 max: 3 +# lighting_alpha = 0.0 + +# Gradient of light curve at maximum light level. +# Controls the contrast of the highest light levels. +# type: float min: 0 max: 3 +# lighting_beta = 1.5 + +# Strength of light curve boost. +# The 3 'boost' parameters define a range of the light +# curve that is boosted in brightness. +# type: float min: 0 max: 0.4 +# lighting_boost = 0.2 + +# Center of light curve boost range. +# Where 0.0 is minimum light level, 1.0 is maximum light level. +# type: float min: 0 max: 1 +# lighting_boost_center = 0.5 + +# Spread of light curve boost range. +# Controls the width of the range to be boosted. +# Standard deviation of the light curve boost Gaussian. +# type: float min: 0 max: 0.4 +# lighting_boost_spread = 0.2 + +### Networking + +# Prometheus listener address. +# If Minetest is compiled with ENABLE_PROMETHEUS option enabled, +# enable metrics listener for Prometheus on that address. +# Metrics can be fetched on http://127.0.0.1:30000/metrics +# type: string +# prometheus_listener_address = 127.0.0.1:30000 + +# Maximum size of the out chat queue. +# 0 to disable queueing and -1 to make the queue size unlimited. +# type: int min: -1 max: 32767 +# max_out_chat_queue_size = 20 + +# Timeout for client to remove unused map data from memory, in seconds. +# type: float min: 0 +# client_unload_unused_data_timeout = 600.0 + +# Maximum number of mapblocks for client to be kept in memory. +# Set to -1 for unlimited amount. +# type: int min: -1 max: 2147483647 +# client_mapblock_limit = 7500 + +# Whether to show the client debug info (has the same effect as hitting F5). +# type: bool +# show_debug = false + +# Maximum number of blocks that are simultaneously sent per client. +# The maximum total count is calculated dynamically: +# max_total = ceil((#clients + max_users) * per_client / 4) +# type: int min: 1 max: 4294967295 +# max_simultaneous_block_sends_per_client = 40 + +# To reduce lag, block transfers are slowed down when a player is building something. +# This determines how long they are slowed down after placing or removing a node. +# type: float min: 0 +# full_block_send_enable_min_time_from_building = 2.0 + +# Maximum number of packets sent per send step, if you have a slow connection +# try reducing it, but don't reduce it to a number below double of targeted +# client number. +# type: int min: 1 max: 65535 +# max_packets_per_iteration = 1024 + +# Compression level to use when sending mapblocks to the client. +# -1 - use default compression level +# 0 - least compression, fastest +# 9 - best compression, slowest +# type: int min: -1 max: 9 +# map_compression_level_net = -1 + +### Server + +# Format of player chat messages. The following strings are valid placeholders: +# @name, @message, @timestamp (optional) +# type: string +# chat_message_format = <@name> @message + +# If the execution of a chat command takes longer than this specified time in +# seconds, add the time information to the chat command message +# type: float min: 0 +# chatcommand_msg_time_threshold = 0.1 + +# A message to be displayed to all clients when the server shuts down. +# type: string +# kick_msg_shutdown = Server shutting down. + +# A message to be displayed to all clients when the server crashes. +# type: string +# kick_msg_crash = This server has experienced an internal error. You will now be disconnected. + +# Whether to ask clients to reconnect after a (Lua) crash. +# Set this to true if your server is set up to restart automatically. +# type: bool +# ask_reconnect_on_crash = false + +### Server/Env Performance + +# Length of a server tick and the interval at which objects are generally updated over +# network, stated in seconds. +# type: float min: 0 +# dedicated_server_step = 0.09 + +# Whether players are shown to clients without any range limit. +# Deprecated, use the setting player_transfer_distance instead. +# type: bool +# unlimited_player_transfer_distance = true + +# Defines the maximal player transfer distance in blocks (0 = unlimited). +# type: int min: 0 max: 65535 +# player_transfer_distance = 0 + +# From how far clients know about objects, stated in mapblocks (16 nodes). +# +# Setting this larger than active_block_range will also cause the server +# to maintain active objects up to this distance in the direction the +# player is looking. (This can avoid mobs suddenly disappearing from view) +# type: int min: 1 max: 65535 +# active_object_send_range_blocks = 8 + +# The radius of the volume of blocks around every player that is subject to the +# active block stuff, stated in mapblocks (16 nodes). +# In active blocks objects are loaded and ABMs run. +# This is also the minimum range in which active objects (mobs) are maintained. +# This should be configured together with active_object_send_range_blocks. +# type: int min: 1 max: 65535 +# active_block_range = 4 + +# From how far blocks are sent to clients, stated in mapblocks (16 nodes). +# type: int min: 1 max: 65535 +# max_block_send_distance = 12 + +# Maximum number of forceloaded mapblocks. +# type: int min: 0 +# max_forceloaded_blocks = 16 + +# Interval of sending time of day to clients, stated in seconds. +# type: float min: 0.001 +# time_send_interval = 5.0 + +# Interval of saving important changes in the world, stated in seconds. +# type: float min: 0.001 +# server_map_save_interval = 5.3 + +# How long the server will wait before unloading unused mapblocks, stated in seconds. +# Higher value is smoother, but will use more RAM. +# type: int min: 0 max: 4294967295 +# server_unload_unused_data_timeout = 29 + +# Maximum number of statically stored objects in a block. +# type: int min: 1 max: 65535 +# max_objects_per_block = 256 + +# Length of time between active block management cycles, stated in seconds. +# type: float min: 0 +# active_block_mgmt_interval = 2.0 + +# Length of time between Active Block Modifier (ABM) execution cycles, stated in seconds. +# type: float min: 0 +# abm_interval = 1.0 + +# The time budget allowed for ABMs to execute on each step +# (as a fraction of the ABM Interval) +# type: float min: 0.1 max: 0.9 +# abm_time_budget = 0.2 + +# Length of time between NodeTimer execution cycles, stated in seconds. +# type: float min: 0 +# nodetimer_interval = 0.2 + +# Max liquids processed per step. +# type: int min: 1 max: 4294967295 +# liquid_loop_max = 100000 + +# The time (in seconds) that the liquids queue may grow beyond processing +# capacity until an attempt is made to decrease its size by dumping old queue +# items. A value of 0 disables the functionality. +# type: int min: 0 max: 65535 +# liquid_queue_purge_time = 0 + +# Liquid update interval in seconds. +# type: float min: 0.001 +# liquid_update = 1.0 + +# At this distance the server will aggressively optimize which blocks are sent to +# clients. +# Small values potentially improve performance a lot, at the expense of visible +# rendering glitches (some blocks will not be rendered under water and in caves, +# as well as sometimes on land). +# Setting this to a value greater than max_block_send_distance disables this +# optimization. +# Stated in mapblocks (16 nodes). +# type: int min: 2 max: 32767 +# block_send_optimize_distance = 4 + +# If enabled the server will perform map block occlusion culling based on +# on the eye position of the player. This can reduce the number of blocks +# sent to the client 50-80%. The client will not longer receive most invisible +# so that the utility of noclip mode is reduced. +# type: bool +# server_side_occlusion_culling = true + +### Mapgen + +# Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes). +# WARNING!: There is no benefit, and there are several dangers, in +# increasing this value above 5. +# Reducing this value increases cave and dungeon density. +# Altering this value is for special usage, leaving it unchanged is +# recommended. +# type: int min: 1 max: 10 +# chunksize = 5 + +# Dump the mapgen debug information. +# type: bool +# enable_mapgen_debug_info = false + +# Maximum number of blocks that can be queued for loading. +# type: int min: 1 max: 1000000 +# emergequeue_limit_total = 1024 + +# Maximum number of blocks to be queued that are to be loaded from file. +# This limit is enforced per player. +# type: int min: 1 max: 1000000 +# emergequeue_limit_diskonly = 128 + +# Maximum number of blocks to be queued that are to be generated. +# This limit is enforced per player. +# type: int min: 1 max: 1000000 +# emergequeue_limit_generate = 128 + +# Number of emerge threads to use. +# Value 0: +# - Automatic selection. The number of emerge threads will be +# - 'number of processors - 2', with a lower limit of 1. +# Any other value: +# - Specifies the number of emerge threads, with a lower limit of 1. +# WARNING: Increasing the number of emerge threads increases engine mapgen +# speed, but this may harm game performance by interfering with other +# processes, especially in singleplayer and/or when running Lua code in +# 'on_generated'. For many users the optimum setting may be '1'. +# type: int min: 0 max: 32767 +# num_emerge_threads = 1 + +### cURL + +# Maximum time an interactive request (e.g. server list fetch) may take, stated in milliseconds. +# type: int min: 100 max: 2147483647 +# curl_timeout = 20000 + +# Limits number of parallel HTTP requests. Affects: +# - Media fetch if server uses remote_media setting. +# - Serverlist download and server announcement. +# - Downloads performed by main menu (e.g. mod manager). +# Only has an effect if compiled with cURL. +# type: int min: 1 max: 2147483647 +# curl_parallel_limit = 8 + +# Maximum time a file download (e.g. a mod download) may take, stated in milliseconds. +# type: int min: 100 max: 2147483647 +# curl_file_download_timeout = 300000 + +### Misc + +# Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens. +# type: int min: 1 +# screen_dpi = 72 + +# Adjust the detected display density, used for scaling UI elements. +# type: float min: 0.5 max: 5 +# display_density_factor = 1 + +# Windows systems only: Start Minetest with the command line window in the background. +# Contains the same information as the file debug.txt (default name). +# type: bool +# enable_console = false + +# Number of extra blocks that can be loaded by /clearobjects at once. +# This is a trade-off between SQLite transaction overhead and +# memory consumption (4096=100MB, as a rule of thumb). +# type: int min: 0 max: 4294967295 +# max_clearobjects_extra_loaded_blocks = 4096 + +# World directory (everything in the world is stored here). +# Not needed if starting from the main menu. +# type: path +# map-dir = + +# See https://www.sqlite.org/pragma.html#pragma_synchronous +# type: enum values: 0, 1, 2 +# sqlite_synchronous = 2 + +# Compression level to use when saving mapblocks to disk. +# -1 - use default compression level +# 0 - least compression, fastest +# 9 - best compression, slowest +# type: int min: -1 max: 9 +# map_compression_level_disk = -1 + +# Enable usage of remote media server (if provided by server). +# Remote servers offer a significantly faster way to download media (e.g. textures) +# when connecting to the server. +# type: bool +# enable_remote_media_server = true + +# File in client/serverlist/ that contains your favorite servers displayed in the +# Multiplayer Tab. +# type: string +# serverlist_file = favoriteservers.json + +## Gamepads + +# Enable joysticks. Requires a restart to take effect +# type: bool +# enable_joysticks = false + +# The identifier of the joystick to use +# type: int min: 0 max: 255 +# joystick_id = 0 + +# The type of joystick +# type: enum values: auto, generic, xbox, dragonrise_gamecube +# joystick_type = auto + +# The time in seconds it takes between repeated events +# when holding down a joystick button combination. +# type: float min: 0.001 +# repeat_joystick_button_time = 0.17 + +# The dead zone of the joystick +# type: int min: 0 max: 65535 +# joystick_deadzone = 2048 + +# The sensitivity of the joystick axes for moving the +# in-game view frustum around. +# type: float min: 0.001 +# joystick_frustum_sensitivity = 170.0 + +## Temporary Settings + +# Path to texture directory. All textures are first searched from here. +# type: path +# texture_path = + +# Enables minimap. +# type: bool +# enable_minimap = true + +# Shape of the minimap. Enabled = round, disabled = square. +# type: bool +# minimap_shape_round = true + +# Address to connect to. +# Leave this blank to start a local server. +# Note that the address field in the main menu overrides this setting. +# type: string +# address = + +# Port to connect to (UDP). +# Note that the port field in the main menu overrides this setting. +# type: int min: 1 max: 65535 +# remote_port = 30000 + +# Default game when creating a new world. +# This will be overridden when creating a world from the main menu. +# type: string +# default_game = minetest + +# Enable players getting damage and dying. +# type: bool +# enable_damage = false + +# Enable creative mode for all players +# type: bool +# creative_mode = false + +# Whether to allow players to damage and kill each other. +# type: bool +# enable_pvp = true + +# Player is able to fly without being affected by gravity. +# This requires the "fly" privilege on the server. +# type: bool +# free_move = false + +# If enabled, makes move directions relative to the player's pitch when flying or swimming. +# type: bool +# pitch_move = false + +# Fast movement (via the "Aux1" key). +# This requires the "fast" privilege on the server. +# type: bool +# fast_move = false + +# If enabled together with fly mode, player is able to fly through solid nodes. +# This requires the "noclip" privilege on the server. +# type: bool +# noclip = false + +# Continuous forward movement, toggled by autoforward key. +# Press the autoforward key again or the backwards movement to disable. +# type: bool +# continuous_forward = false + +# Formspec default background opacity (between 0 and 255). +# type: int min: 0 max: 255 +# formspec_default_bg_opacity = 140 + +# Formspec default background color (R,G,B). +# type: string +# formspec_default_bg_color = (0,0,0) + +# Whether to show technical names. +# Affects mods and texture packs in the Content and Select Mods menus, as well as +# setting names in All Settings. +# Controlled by the checkbox in the "All settings" menu. +# type: bool +# show_technical_names = false + +# Enables the sound system. +# If disabled, this completely disables all sounds everywhere and the in-game +# sound controls will be non-functional. +# Changing this setting requires a restart. +# type: bool +# enable_sound = true + +# Key for moving the player forward. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_forward = KEY_KEY_W + +# Key for moving the player backward. +# Will also disable autoforward, when active. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_backward = KEY_KEY_S + +# Key for moving the player left. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_left = KEY_KEY_A + +# Key for moving the player right. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_right = KEY_KEY_D + +# Key for jumping. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_jump = KEY_SPACE + +# Key for sneaking. +# Also used for climbing down and descending in water if aux1_descends is disabled. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_sneak = KEY_LSHIFT + +# Key for digging. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_dig = KEY_LBUTTON + +# Key for placing. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_place = KEY_RBUTTON + +# Key for opening the inventory. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_inventory = KEY_KEY_I + +# Key for moving fast in fast mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_aux1 = KEY_KEY_E + +# Key for opening the chat window. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_chat = KEY_KEY_T + +# Key for opening the chat window to type commands. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_cmd = / + +# Key for opening the chat window to type local commands. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_cmd_local = . + +# Key for toggling unlimited view range. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_rangeselect = KEY_KEY_R + +# Key for toggling flying. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_freemove = KEY_KEY_K + +# Key for toggling pitch move mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_pitchmove = KEY_KEY_P + +# Key for toggling fast mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_fastmove = KEY_KEY_J + +# Key for toggling noclip mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_noclip = KEY_KEY_H + +# Key for selecting the next item in the hotbar. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_hotbar_next = KEY_KEY_N + +# Key for selecting the previous item in the hotbar. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_hotbar_previous = KEY_KEY_B + +# Key for muting the game. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_mute = KEY_KEY_M + +# Key for increasing the volume. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_increase_volume = + +# Key for decreasing the volume. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_decrease_volume = + +# Key for toggling autoforward. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_autoforward = + +# Key for toggling cinematic mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_cinematic = + +# Key for toggling display of minimap. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_minimap = KEY_KEY_V + +# Key for taking screenshots. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_screenshot = KEY_F12 + +# Key for dropping the currently selected item. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_drop = KEY_KEY_Q + +# Key to use view zoom when possible. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_zoom = KEY_KEY_Z + +# Key for selecting the first hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot1 = KEY_KEY_1 + +# Key for selecting the second hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot2 = KEY_KEY_2 + +# Key for selecting the third hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot3 = KEY_KEY_3 + +# Key for selecting the fourth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot4 = KEY_KEY_4 + +# Key for selecting the fifth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot5 = KEY_KEY_5 + +# Key for selecting the sixth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot6 = KEY_KEY_6 + +# Key for selecting the seventh hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot7 = KEY_KEY_7 + +# Key for selecting the eighth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot8 = KEY_KEY_8 + +# Key for selecting the ninth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot9 = KEY_KEY_9 + +# Key for selecting the tenth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot10 = KEY_KEY_0 + +# Key for selecting the 11th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot11 = + +# Key for selecting the 12th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot12 = + +# Key for selecting the 13th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot13 = + +# Key for selecting the 14th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot14 = + +# Key for selecting the 15th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot15 = + +# Key for selecting the 16th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot16 = + +# Key for selecting the 17th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot17 = + +# Key for selecting the 18th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot18 = + +# Key for selecting the 19th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot19 = + +# Key for selecting the 20th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot20 = + +# Key for selecting the 21st hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot21 = + +# Key for selecting the 22nd hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot22 = + +# Key for selecting the 23rd hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot23 = + +# Key for selecting the 24th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot24 = + +# Key for selecting the 25th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot25 = + +# Key for selecting the 26th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot26 = + +# Key for selecting the 27th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot27 = + +# Key for selecting the 28th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot28 = + +# Key for selecting the 29th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot29 = + +# Key for selecting the 30th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot30 = + +# Key for selecting the 31st hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot31 = + +# Key for selecting the 32nd hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot32 = + +# Key for toggling the display of the HUD. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_hud = KEY_F1 + +# Key for toggling the display of chat. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_chat = KEY_F2 + +# Key for toggling the display of the large chat console. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_console = KEY_F10 + +# Key for toggling the display of fog. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_force_fog_off = KEY_F3 + +# Key for toggling the camera update. Only used for development +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_update_camera = + +# Key for toggling the display of debug info. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_debug = KEY_F5 + +# Key for toggling the display of the profiler. Used for development. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_profiler = KEY_F6 + +# Key for switching between first- and third-person camera. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_camera_mode = KEY_KEY_C + +# Key for increasing the viewing range. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_increase_viewing_range_min = + + +# Key for decreasing the viewing range. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_decrease_viewing_range_min = - + diff --git a/misc/CPACK_WIX_UI_BANNER.BMP b/misc/CPACK_WIX_UI_BANNER.BMP new file mode 100644 index 0000000..612d537 Binary files /dev/null and b/misc/CPACK_WIX_UI_BANNER.BMP differ diff --git a/misc/CPACK_WIX_UI_DIALOG.BMP b/misc/CPACK_WIX_UI_DIALOG.BMP new file mode 100644 index 0000000..c6750e7 Binary files /dev/null and b/misc/CPACK_WIX_UI_DIALOG.BMP differ diff --git a/misc/Info.plist b/misc/Info.plist new file mode 100644 index 0000000..0491d2f --- /dev/null +++ b/misc/Info.plist @@ -0,0 +1,20 @@ +<?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>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>minetest</string> + <key>CFBundleIconFile</key> + <string>minetest-icon.icns</string> + <key>CFBundleName</key> + <string>Minetest</string> + <key>CFBundleDisplayName</key> + <string>Minetest</string> + <key>CFBundleIdentifier</key> + <string>net.minetest.minetest</string> + <key>NSHighResolutionCapable</key> + <false/> +</dict> +</plist> diff --git a/misc/debpkg-control b/misc/debpkg-control new file mode 100644 index 0000000..e867f3e --- /dev/null +++ b/misc/debpkg-control @@ -0,0 +1,33 @@ +Section: games +Priority: extra +Standards-Version: 3.6.2 +Package: minetest-staging +Version: 5.4.0-DATEPLACEHOLDER +Depends: libc6, libcurl3-gnutls, libfreetype6, libgl1, JPEG_PLACEHOLDER, JSONCPP_PLACEHOLDER, LEVELDB_PLACEHOLDER, libopenal1, libpng16-16, libsqlite3-0, libstdc++6, libvorbisfile3, libx11-6, libxxf86vm1, libzstd1, zlib1g +Maintainer: Loic Blot <loic.blot@unix-experience.fr> +Homepage: https://www.minetest.net/ +Vcs-Git: https://github.com/minetest/minetest.git +Vcs-Browser: https://github.com/minetest/minetest.git +Architecture: amd64 +Build-Depends: + cmake, + gettext, + libcurl4-gnutls-dev, + libfreetype6-dev, + libgl1-mesa-dev, + libjpeg-dev, + libjsoncpp-dev, + libleveldb-dev, + libogg-dev, + libopenal-dev, + libpng-dev, + libsqlite3-dev, + libvorbis-dev, + libx11-dev, + zlib1g-dev +Description: Multiplayer infinite-world block sandbox game + Minetest is a minecraft-inspired game written from scratch and licensed + under the LGPL (version 2.1 or later). It supports both survival and creative + modes along with multiplayer support, dynamic lighting, and an "infinite" map + generator. +Conflicts: minetestc55, minetest, minetest-server, minetest-data diff --git a/misc/irrlichtmt_tag.txt b/misc/irrlichtmt_tag.txt new file mode 100644 index 0000000..be66833 --- /dev/null +++ b/misc/irrlichtmt_tag.txt @@ -0,0 +1 @@ +1.9.0mt8 diff --git a/misc/kubernetes.yml b/misc/kubernetes.yml new file mode 100644 index 0000000..1a956ab --- /dev/null +++ b/misc/kubernetes.yml @@ -0,0 +1,53 @@ +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: minetest + name: minetest + namespace: default +spec: + selector: + matchLabels: + app: minetest + template: + metadata: + labels: + app: minetest + spec: + containers: + - image: registry.gitlab.com/minetest/minetest/server:master + name: minetest + ports: + - containerPort: 30000 + protocol: UDP + volumeMounts: + - mountPath: /var/lib/minetest + name: minetest-data + - mountPath: /etc/minetest + name: config + restartPolicy: Always + volumes: + - name: minetest-data + persistentVolumeClaim: + claimName: minetest-data + - configMap: + defaultMode: 420 + name: minetest + name: config +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: minetest + name: minetest + namespace: default +spec: + ports: + - name: minetest + port: 30000 + protocol: UDP + selector: + app: minetest + type: NodePort diff --git a/misc/minetest-icon-24x24.png b/misc/minetest-icon-24x24.png new file mode 100644 index 0000000..334e2f6 Binary files /dev/null and b/misc/minetest-icon-24x24.png differ diff --git a/misc/minetest-icon.icns b/misc/minetest-icon.icns new file mode 100644 index 0000000..14731c2 Binary files /dev/null and b/misc/minetest-icon.icns differ diff --git a/misc/minetest-icon.ico b/misc/minetest-icon.ico new file mode 100644 index 0000000..82af67b Binary files /dev/null and b/misc/minetest-icon.ico differ diff --git a/misc/minetest-xorg-icon-128.png b/misc/minetest-xorg-icon-128.png new file mode 100644 index 0000000..0241a91 Binary files /dev/null and b/misc/minetest-xorg-icon-128.png differ diff --git a/misc/minetest.exe.manifest b/misc/minetest.exe.manifest new file mode 100644 index 0000000..dcad3fc --- /dev/null +++ b/misc/minetest.exe.manifest @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity type="win32" name="minetest" version="0.0.0.0" /> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel> + </requestedPrivileges> + </security> + </trustInfo> + <application xmlns="urn:schemas-microsoft-com:asm.v3"> + <windowsSettings> + <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware> + <activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage> + </windowsSettings> + </application> +</assembly> diff --git a/misc/minetest.svg b/misc/minetest.svg new file mode 100644 index 0000000..fe036c3 --- /dev/null +++ b/misc/minetest.svg @@ -0,0 +1,183 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="48px" + height="48px" + id="svg2856" + version="1.1" + inkscape:version="0.47 r22583" + sodipodi:docname="minetest.svg" + inkscape:export-filename="/home/erlehmann/pics/icons/minetest/minetest-icon-24x24.png" + inkscape:export-xdpi="45" + inkscape:export-ydpi="45"> + <defs + id="defs2858"> + <filter + inkscape:collect="always" + id="filter3864"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.20490381" + id="feGaussianBlur3866" /> + </filter> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="12.083333" + inkscape:cx="24" + inkscape:cy="24" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:window-width="1233" + inkscape:window-height="755" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1"> + <inkscape:grid + type="xygrid" + id="grid2866" + empspacing="2" + visible="true" + enabled="true" + snapvisiblegridlinesonly="true" + spacingx="0.5px" + spacingy="10px" + color="#ff0000" + opacity="0.1254902" + empcolor="#ff0000" + empopacity="0.25098039" + dotted="false" /> + <inkscape:grid + type="axonomgrid" + id="grid2870" + units="px" + empspacing="1" + visible="true" + enabled="true" + snapvisiblegridlinesonly="true" + spacingy="1px" + originx="0px" /> + </sodipodi:namedview> + <metadata + id="metadata2861"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="layer1" + inkscape:label="Layer 1" + inkscape:groupmode="layer"> + <path + style="fill:#e9b96e;fill-opacity:1;stroke:#573a0d;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="M 6.1513775e-7,16 3.2110204e-7,28 21.035899,40.145082 l 21,-12.414519 0,-11.461126 L 20.78461,4 6.1513775e-7,16 z" + id="path3047" + transform="translate(3.4641013,6)" + sodipodi:nodetypes="ccccccc" /> + <path + style="fill:#2e3436;fill-opacity:1;stroke:#2e3436;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="m 8.5,30.907477 -2,-1.1547 0,6 L 17.320508,42 l 0,-2 -1.732051,-1 0,-2 L 13.5,35.794229 l 0,-4 -5,-2.886752 0,2 z" + id="path3831" + sodipodi:nodetypes="ccccccccccc" /> + <path + style="opacity:1;fill:#555753;fill-opacity:1;stroke:#2e3436;stroke-linejoin:miter" + d="m 6.9282032,36 3.4641018,-2 3.464101,2 1.643594,0.948929 0,2 2,1.154701 0,2 L 6.9282032,36 z" + id="path3870" + sodipodi:nodetypes="cccccccc" /> + <path + style="fill:#fce94f;fill-opacity:1;stroke:#625802;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="M 25.980762,19 31.5,22.186533 l 0,2 L 38.09375,28 41.5625,26 45.5,23.730563 l 0,2.538874 0,-4 L 32.908965,15 25.980762,19 z" + id="path3851" + sodipodi:nodetypes="cccccccccc" /> + <path + style="fill:#e9b96e;fill-opacity:1;stroke:#573a0d;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.50000000000000000" + d="m 24.839746,18.341234 8.660254,-5 0,2 -8.660254,5 0,-2 z" + id="path5684" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:#73d216;fill-opacity:1;stroke:#325b09;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="M 25.980762,5 3.4641016,18 17.5,26.10363 31.5,18.186533 24.839746,14.341234 33.5,9.341234 25.980762,5 z" + id="path3821" + sodipodi:nodetypes="ccccccc" + transform="translate(0,4)" /> + <path + style="fill:#729fcf;fill-opacity:1;stroke:#19314b;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="m 17.5,28.10363 0,2 1.552559,0.89637 0,2 5.447441,3.145082 12,-7.071797 0,-2.14657 2,-1.1547 0,-1.54403 -7,-4.041452 -14,7.917097 z" + id="path3825" + sodipodi:nodetypes="ccccccccccc" + transform="translate(0,4)" /> + <g + id="g5691" + style="stroke-linejoin:miter"> + <path + sodipodi:nodetypes="ccccc" + id="path3862" + d="m 13.856406,20 6.928204,4 -6.928204,4 -6.9282028,-4 6.9282028,-4 z" + style="fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter3864);opacity:0.25000000000000000" /> + <g + id="g3858" + style="stroke-linejoin:miter"> + <path + style="fill:#c17d11;fill-opacity:1;stroke:#8f5902;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="m 15.588457,21 1.732051,1 1.732051,-1 0,-6 -1.732051,-1 -1.732051,1 0,6 z" + id="path3833" + sodipodi:nodetypes="ccccccc" + transform="translate(-3.4641015,2)" /> + <path + style="fill:#4e9a06;fill-opacity:1;stroke:#316004;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="M 9.9641015,13.752777 17.320508,18 l 6.643593,-3.835681 0,-8.3286385 L 17.320508,2 9.9641015,6.2472233 l 0,7.5055537 z" + id="path3837" + transform="translate(-3.4641015,2)" + sodipodi:nodetypes="ccccccc" /> + </g> + </g> + <g + id="g5686" + transform="translate(-4.2591582e-7,2)" + style="stroke-linejoin:miter"> + <path + transform="translate(24.248712,-2)" + style="opacity:0.25000000000000000;fill:#2e3436;fill-opacity:1;stroke:none;filter:url(#filter3864);stroke-linejoin:miter" + d="m 13.856406,20 5.196153,3 -5.196153,3 -5.196152,-3 5.196152,-3 z" + id="path3868" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:#4e9a06;fill-opacity:1;stroke:#316004;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="M 15.71539,21.073285 17.320508,22 l 1.394882,-0.805336 0,-8.389328 L 17.320508,12 l -1.605118,1.073285 0,8 z" + id="path3853" + sodipodi:nodetypes="ccccccc" + transform="translate(20.78461,0)" /> + </g> + <path + style="fill:none;fill-opacity:1;stroke:#ef2929;stroke-width:0.50000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.50000000000000000, 0.50000000000000000;stroke-dashoffset:0.25000000000000000" + d="M 12.124356,33 11.25833,32.5" + id="path3872" + sodipodi:nodetypes="cc" /> + <path + style="fill:#888a85;stroke:#2e3436;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.50000000000000000" + d="m 45.5,26.730563 -4,2.309401 0,1 -2,1.1547 0,2 -2,1.154701 0,4 8,-4.618802 0,-7 z" + id="path3874" + sodipodi:nodetypes="ccccccccc" /> + </g> +</svg> diff --git a/misc/net.minetest.minetest.appdata.xml b/misc/net.minetest.minetest.appdata.xml new file mode 100644 index 0000000..357aa82 --- /dev/null +++ b/misc/net.minetest.minetest.appdata.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="UTF-8"?> +<component type="desktop-application"> + <id>net.minetest.minetest.desktop</id> + <metadata_license>CC0-1.0</metadata_license> + <project_license>LGPL-2.1+ and CC-BY-SA-3.0 and MIT and Apache-2.0</project_license> + <content_rating type="oars-1.0"> + <content_attribute id="violence-cartoon">mild</content_attribute> + <content_attribute id="violence-fantasy">mild</content_attribute> + <content_attribute id="social-chat">intense</content_attribute> + <content_attribute id="social-info">mild</content_attribute> + </content_rating> + <name>Minetest</name> + <summary>Multiplayer infinite-world block sandbox game</summary> + <summary xml:lang="de">Mehrspieler-Sandkastenspiel mit unendlichen Blockwelten</summary> + <description> + <p> + Minetest is an infinite-world block sandbox game and game engine. + </p><p xml:lang="de"> + Minetest ist ein Sandkastenspiel und eine Spielengine mit unendlichen Welten. + </p><p> + Players can create and destroy various types of blocks in a + three-dimensional open world. This allows forming structures in + every possible creation, on multiplayer servers or in singleplayer. + </p><p xml:lang="de"> + Spieler können in einer offenen 3D-Welt viele verschiedene Arten von + Blöcken platzieren und abbauen. Dies erlaubt das Bauen von vielfältigen + Strukturen im Einzelspieler oder auf Mehrspielerservern. + </p><p> + Minetest is designed to be simple, stable, and portable. + It is lightweight enough to run on fairly old hardware. + </p><p xml:lang="de"> + Minetest wurde entworfen, um einfach, stabil und portabel zu sein. + Es ist leichtgewichtig genug, um auf relativ alter Hardware zu laufen. + </p><p> + Minetest has many features, including: + </p><p xml:lang="de"> + Minetest besitzt viele Features, unter anderem: + </p> + <ul> + <li>Ability to walk around, dig, and build in a near-infinite voxel world</li> + <li xml:lang="de">Die Möglichkeit, in einer nahezu unendlichen Voxel-Welt herumzulaufen, zu graben und zu bauen</li> + <li>Crafting of items from raw materials</li> + <li xml:lang="de">Fertigen von Items aus Rohmaterialien</li> + <li>Fast and able to run on old and slow hardware</li> + <li xml:lang="de">Gute Performance selbst auf älterer und langsamer Hardware</li> + <li>A simple modding API that supports many additions and modifications to the game</li> + <li xml:lang="de">Eine einfache Modding-API, die viele Ergänzungen und Änderungen am Spiel unterstützt</li> + <li>Multiplayer support via servers hosted by users</li> + <li xml:lang="de">Mehrspieler auf selber gehosteten Servern</li> + <li>Beautiful lightning-fast map generator</li> + <li xml:lang="de">Wunderschöner, blitzschneller Kartengenerator</li> + </ul> + </description> + <screenshots> + <screenshot type="default"> + <image>http://www.minetest.net/media/gallery/1.jpg</image> + </screenshot> + <screenshot> + <image>http://www.minetest.net/media/gallery/3.jpg</image> + </screenshot> + <screenshot> + <image>http://www.minetest.net/media/gallery/5.jpg</image> + </screenshot> + </screenshots> + <keywords> + <keyword>sandbox</keyword> + <keyword>world</keyword> + <keyword>mining</keyword> + <keyword>multiplayer</keyword> + </keywords> + <url type="homepage">https://www.minetest.net</url> + <url type="bugtracker">https://www.minetest.net/development/#reporting-issues</url> + <url type="translate">https://dev.minetest.net/Translation</url> + <url type="donation">https://www.minetest.net/development/#donate</url> + <url type="faq">https://wiki.minetest.net/FAQ</url> + <url type="help">https://wiki.minetest.net</url> + <url type="vcs-browser">https://github.com/minetest/minetest</url> + <url type="contribute">https://www.minetest.net/get-involved/</url> + <provides> + <binary>minetest</binary> + </provides> + <translation type="gettext">minetest</translation> + <update_contact>sfan5@live.de</update_contact> + <releases> + <release date="2022-09-19" version="5.6.1"/> + </releases> +</component> diff --git a/misc/net.minetest.minetest.desktop b/misc/net.minetest.minetest.desktop new file mode 100644 index 0000000..a94dbab --- /dev/null +++ b/misc/net.minetest.minetest.desktop @@ -0,0 +1,18 @@ +[Desktop Entry] +Name=Minetest +GenericName=Minetest +Comment=Multiplayer infinite-world block sandbox +Comment[de]=Mehrspieler-Sandkastenspiel mit unendlichen Blockwelten +Comment[es]=Juego sandbox multijugador con mundos infinitos +Comment[fr]=Jeu multijoueurs de type bac à sable avec des mondes infinis +Comment[ja]=マルチプレイに対応した、無限の世界のブロック型サンドボックスゲームです +Comment[ru]=Игра-песочница с безграничным миром, состоящим из блоков +Comment[tr]=Tek-Çok oyuncuyla küplerden sonsuz dünyalar inşa et +Exec=minetest +Icon=minetest +Terminal=false +PrefersNonDefaultGPU=true +Type=Application +Categories=Game;Simulation; +StartupNotify=false +Keywords=sandbox;world;mining;crafting;blocks;nodes;multiplayer;roleplaying; diff --git a/misc/winresource.rc b/misc/winresource.rc new file mode 100644 index 0000000..d5a7179 --- /dev/null +++ b/misc/winresource.rc @@ -0,0 +1,66 @@ +#include <windows.h> +#include <winuser.h> +#include <commctrl.h> +#include <richedit.h> + +#ifndef USE_CMAKE_CONFIG_H +#define USE_CMAKE_CONFIG_H +#endif +#include "config.h" +#undef USE_CMAKE_CONFIG_H + +#if RUN_IN_PLACE + #define BUILDMODE "RUN_IN_PLACE=1" +#else + #define BUILDMODE "RUN_IN_PLACE=0" +#endif + +#ifdef __MINGW32__ +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "minetest.exe.manifest" +#endif + +LANGUAGE 0, SUBLANG_NEUTRAL +130 ICON "minetest-icon.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +1 VERSIONINFO + FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0 + PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0 + FILEFLAGSMASK 0x3fL +#ifndef NDEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "" + VALUE "CompanyName", PROJECT_NAME_C " community" + VALUE "FileDescription", PROJECT_NAME_C " engine" + VALUE "FileVersion", VERSION_STRING + VALUE "InternalName", PROJECT_NAME + VALUE "LegalCopyright", "(c) 2011-2015 celeron55" + VALUE "LegalTrademarks", """Minetest"" is the property of the Minetest community, don't use it without permission!" + VALUE "OriginalFilename", "minetest.exe" + VALUE "PrivateBuild", VERSION_EXTRA + VALUE "ProductName", PROJECT_NAME_C + VALUE "ProductVersion", PRODUCT_VERSION_STRING + VALUE "SpecialBuild", BUILDMODE + END +END +BLOCK "VarFileInfo" +BEGIN + VALUE "Translation", 0x409, 1200 +END +END + diff --git a/po/ar/minetest.po b/po/ar/minetest.po new file mode 100644 index 0000000..55ba0af --- /dev/null +++ b/po/ar/minetest.po @@ -0,0 +1,7139 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-03-18 02:57+0000\n" +"Last-Translator: abidin toumi <abidin24@disroot.org>\n" +"Language-Team: Arabic <https://hosted.weblate.org/projects/minetest/minetest/" +"ar/>\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" +"X-Generator: Weblate 4.12-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "امسح طابور الرسائل الصادرة" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "أمر فارغ." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "اخرج للقائمة الرئيسة" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "أمر غير صالح: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "قائمة اللاعبين المتصلين" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "اللاعبون المتصلون: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "طابور الرسائل الصادرة فارغ." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "هذا الأمر معطل من الخادم." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "أعِد الإحياء" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "مِت" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "الأوامر المتوفرة:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "الأوامر المتاحة: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "الأوامر غير المتاحة: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "احصل على تعليمات الأوامر" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"استخدم '.help <cmd>' للحصول على مزيد من المعلومات أو '.help all' لعرض كل شيء." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "موافق" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<ليس متاحًا>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "حدث خطأ في برنامج Lua النصي:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "حدث خطأ:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "القائمة الرئيسية" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "أعد الإتصال" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "يطلب الخادم إعادة الإتصال:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "اختر التعديلات" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "لا تتطابق نسخ الميفاق. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "يفرظ الخادم إ ستخدام الميفاق $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "الخادم يدعم نسخ الميفاق ما بين $1 و $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "نحن ندعم نسخة الميفاق $1فقط." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "نحن ندعم نسخ الميفاق ما بين $1 و $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "ألغِ" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "الإعتماديات:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "عطِل الكل" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "عطل حزمة التعديلات" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "فعِل الكل" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "مكن حزمة التعديلات" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"فشل تمكين التعديل \"$1\" لإحتوائه على محارف غير مسموحة. المحارف المسموحة هي " +"[a-z0-9_] فقط." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "جد المزيد من التعديلات" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "التعديل:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "بدون إعتماديات إختيارية" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "لا يتوفر وصف للعبة." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "بدون إعتماديات لازمة" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "وصف حزمة التعديلات غير متوفر." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "بدون إعتماديات إختيارية" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "الإعتماديات الإختيارية:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "إحفظ" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "العالم:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "مُفعل" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" موجود مسبقًا. هل تريد الكتابة عليه؟" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "الاعتماديتان \"$1\" و $2 ستثبتان." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 بواسطة $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"يُنزل $1،\n" +"$2 في الطابور" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "ينزل $1..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "يحتاج $1 لكن لم يُعثر عليها." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 سيُثبت، واعتماديات $1 ستُتجاهل." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "كل الحزم" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "مثبت مسبقا" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "عُد للقائمة الرئيسة" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "اللعبة القاعدية :" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "لا يمكن استخدام ContentDB عند بناء Minetest بدون cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "يحمل..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "فشل تحميل $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "الألعاب" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "ثبت" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "ثبت $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "ثبت الإعتماديات المفقودة" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "التثبيت: نوع الملف غير مدعوم أو هو أرشيف تالف" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "التعديلات" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "تعذر استيراد الحزم" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "بدون نتائج" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "لا توجد تحديثات" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "لم يُعثر عليه" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "اكتب عليه" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "تحقق من صحة اللعبة القاعدية." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "في الطابور" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "حِزم الإكساء" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "أزل" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "حدِث" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "حدِّث الكل [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "اعرض مزيدًا من المعلومات عبر المتصفح" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "إسم العالم \"$1\" موجود مسبقاً" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "تضاريس إضافية" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "تبريد مع زيادة الارتفاع" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "نقص الرطوبة مع الارتفاع" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "دمج المواطن البيئية" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "مواطن بيئية" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "كهوف" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "مغارات" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "أنشئ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "تحذير: إختبار التطور موجه للمطورين." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "الزنزانات" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "أرض مسطحة" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "أرض عائمة في السماء" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "أراضيٌ عائمة (تجريبية)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "ولد تضاريس غير كسورية: محيطات وباطن الأرض" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "التلال" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "أنهار رطبة" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "زِد الرطوبة قرب الأنهار" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "ثبت $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "بحيرات" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "قلة الرطوبة وارتفاعه الحرارة تسبب جفاف او ضحالة الانهار" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "مولِد الخريطة" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "جبال" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "تدفق الطين" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "شبكة أنفاق ومغارات" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "لم تحدد لعبة" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "يخفض الحرارة مع ازدياد الإرتفاع" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "يخفض الرطوبة مع ازدياد الإرتفاع" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "أنهار" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "أنهار بمستوى البحر" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "البذرة" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "تغيير سلس للمناطق البيئية" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "المنشآت السطحية (لا تأثر على الأشجار والأعشاب المنشأة ب v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "الهياكل التي تظهر على التضاريس ، عادة الأشجار والنباتات" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "معتدل، صحراء" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "معتدل، صحراء، غابة" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "المعتدلة, الصحراء, الغابة, التندرا, التايغا" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "تآكل التربة" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "أعشاب الغابة والشجر" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "تمايز عمق النهر" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "كهوف كبيرة في أعماق الأرض" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "إسم العالم" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "ليس لديك لعبة مثبتت." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "هل تريد حذف \"$1\" ؟" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "إحذف" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "مدير الحزم: فشل حذف \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "مدير الحزم: المسار \"$1\" غير صالح" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "حذف العالم \"$1\"؟" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "أكد كلمة المرور" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "الاسم" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "كلمة المرور" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "كلمتا المرور غير متطابقتين!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "سجل وادخل" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "أقبل" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "أعد تسمية حزمة التعديلات:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"اسم حزمة التعديلات هذه مصرح في modpack.conf لذا أي تسمية سيتم استبدالها." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(الإعداد بدون وصف)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "ضوضاء 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< عد لصفحة الإعدادات" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "استعرض" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "المحتوى" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "المحتوى" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "عطِّل" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "حرر" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "مُفعل" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "المُعادل" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "استمرار" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "يرجى إدخال رقم صحيح صالح." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "يرجى إدخال رقم صالح." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "إستعِد الإفتراضي" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "تكبير/تصغير" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "إبحث" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "إختر الدليل" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "إختر ملف" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "إعرض الأسماء التقنية" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "يحب أن لا تقل القيمة عن $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "يحب أن لا تزيد القيمة عن $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "التوزع على محور X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Y spread" +msgstr "التوزع على محور Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "التوزع على محور Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "القيمة المطلقة" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "إفتراضي" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "مخفف" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (مفعل)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 تعديلات" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "فشل تثبيت $1 في $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "تثبيت تعديل: لا يمكن ايجاد الاسم الحقيقي التعديل$1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "تثبيت تعديل: لا يمكن العصور على اسم مجلد مناسب لحزمة التعديلات $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "فشل إيجاد تعديل أو حزمة تعديلات صالحة" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "فشل تثبيت $1 كحزمة إكساء" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "فشل تثبيت اللعبة ك $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "فشل تثبيت التعديل كـ $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "تعذر تثبيت حزمة التعديلات مثل $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "يحمل..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "قائمة الخوادم العمومية معطلة" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "جرب إعادة تمكين قائمة الحوادم العامة وتحقق من إتصالك بالانترنت." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "حول" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "المساهمون النشطون" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "محرك التصيير النشط:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "المطورون الرئيسيون" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "افتح دليل بيانات المستخدم" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"يفتح الدليل الذي يحوي العوالم والألعاب والتعديلات \n" +"وحزم الإكساء في مدير الملفات." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "المساهمون السابقون" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "المطورون الرئيسيون السابقون" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "تصفح المحتوى عبر الانترنت" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "المحتوى" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "عطل حزمة الإكساء" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "معلومات:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "الحومة المثبتت:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "بدون اعتماديات." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "لايتوفر وصف للحزمة" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "أعد التسمية" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "أزل الحزمة" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "إستعمال حزمة الإكساء" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "أعلن عن الخادوم" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Bind Address" +msgstr "العنوان المطلوب" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "النمط الإبداعي" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "مكن الضرر" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "استضف لعبة" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "استضف خدوم" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "ثبت العابا من ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "جديد" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "لم تنشئ او تحدد عالما!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "إلعب" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "المنفذ" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "اختر التعديلات" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "حدد العالم:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "منفذ الخدوم" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "ابدأ اللعبة" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "عنوان" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "امسح" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "النمط الإبداعي" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "الضرر / قتال اللاعبين" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "المفضلة" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "خوادم غير متوافقة" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "انضم للعبة" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "خوادم عمومية" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "حدِّث" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "حذف المفضلة" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "وصف الخادم" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "سحب 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "كل الإعدادات" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "التنعييم:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "حفظ حجم الشاشة تلقائيا" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "مرشح خطي ثنائي" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "غيِر المفاتيح" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "زجاج متصل" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "ظلال ديناميكية" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "ظلال ديناميكية: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "اوراق بتفاصيل واضحة" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "عالي" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "متوسط" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "بدون مرشح" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "إبراز العقد" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "اقتضاب العقد" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "بدون" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "اوراق معتِمة" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "مياه معتمة" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "جسيمات" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "الشاشة:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "إعدادات" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "مُظللات" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "المظللات (تجريبية)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "مظللات (غير متوفر)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "أوراق بسيطة" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "إضاءة سلسة" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "الإكساء:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "حساسية اللمس: (بكسل)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "مرشح خطي ثلاثي" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "عالية جدا" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "منخفضة جدًا" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "اوراق متموجة" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "سوائل متموجة" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "نباتات متموجة" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "خطأ في الاتصال (انتهاء المهلة؟)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "انتهت مهلة الاتصال." + +#: src/client/client.cpp +msgid "Done!" +msgstr "تم!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "تحضير العقد" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "تحضير العقد..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "يحمل الإكساء..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "يعيد بناء المظلِلات..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "خطأ في الاتصال (انتهاء المهلة؟)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "تعذر العثور على اللعبة أو تحميلها " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "مواصفات اللعبة غير صالحة." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "القائمة الرئيسية" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "بدون عالم محدد وعنوان معطى. لاشيء لفعله." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "إسم اللاعب طويل." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "يرجى اختيار اسم!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "فشل فتح ملف كلمة المرور المدخل: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "مسار العالم المدخل غير موجود: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"راجع debug.txt لمزيد من التفاصيل." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- العنوان: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- النمط: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- المنفذ: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- عام: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- قتال اللاعبين: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- اسم الخادم: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "حدث خطأ في التسلسل:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "رُفض النفاذ. السبب: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "المشي التلقائي معطل" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "المشي التلقائي ممكن" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "حدود الكتل مخفية" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "حدود كل الكتل ظاهرة" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "حدود الكتلة الحالية ظاهرة" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "حدود الكتل القريبة ظاهرة" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "تحديث الكاميرا معطل" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "تحديث الكاميرا مفعل" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "تعذر إظهار حدود الكتل ( تحتاج امتياز 'basic_debug')" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "غير كلمة المرور" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "الوضع السينمائي معطل" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "الوضع السينمائي مفعل" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "فُصل الاتصال عن العميل" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "البرمجة النصية معطلة من جانب العميل" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "يتصل بالخادوم…" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "فشل الاتصال لسبب مجهول" + +#: src/client/game.cpp +msgid "Continue" +msgstr "تابع" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"أزرار التحكم:\n" +"- %s: سر للأمام\n" +"- %s: سر للخلف\n" +"- %s: سر يسارا\n" +"- %s: سر يمينا\n" +"- %s: اقفز/تسلق\n" +"- %s: احفر/الكم\n" +"- %s: ضع/استخدم\n" +"- %s: ازحف/انزل\n" +"- %s: ارمي عنصر\n" +"- %s: افتح المخزن\n" +"- تحريك الفأرة: دوران\n" +"- عجلة الفأرة: غيير العنصر\n" +"- -%s: دردشة\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "تعذر تحليل العنوان:%s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "ينشىء عميلا…" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "ينشىء خادوما…" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "معلومات التنقيح ومنحنى محلل البيانات مخفيان" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "معلومات التنقيح مرئية" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"اعدادات التحكم الافتراضية: \n" +"بدون قائمة مرئية: \n" +"- لمسة واحدة: زر تفعيل\n" +"- لمسة مزدوجة: ضع/استخدم\n" +"- تحريك إصبع: دوران\n" +"المخزن أو قائمة مرئية: \n" +"- لمسة مزدوجة (خارج القائمة): \n" +" --> اغلق القائمة\n" +"- لمس خانة أو تكديس: \n" +" --> حرك التكديس\n" +"- لمس وسحب, ولمس باصبع ثان: \n" +" --> وضع عنصر واحد في خانة\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "مدى الرؤية غير المحدود معطل" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "مدى الرؤية غير المحدود مفعل" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "ينشىء عميلا…" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "اخرج للقائمة" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "اخرج لنظام التشغيل" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "نمط السرعة معطل" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "نمط السرعة مفعل" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "نمط السرعة مفعل (ملاحظة: لا تمتلك امتياز 'السرعة')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "نمط الطيران معطل" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "نمط الطيران مفعل" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "نمط الطيران مفعل (ملاحظة: لا تمتلك امتياز 'الطيران')" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "الضباب معطل" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "الضباب مفعل" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "معلومات اللعبة:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "اللعبة موقفة مؤقتا" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "استضافة خادوم" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "تعريف العنصر…" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "كب\\ثا" + +#: src/client/game.cpp +msgid "Media..." +msgstr "وسائط…" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "مب\\ثا" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "الخريطة المصغرة معطلة من قبل لعبة أو تعديل" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "متعدد اللاعبين" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "وضع العقبات مفعل" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "وضع القبات معطل" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "تعريفات العقدة..." + +#: src/client/game.cpp +msgid "Off" +msgstr "معطّل" + +#: src/client/game.cpp +msgid "On" +msgstr "مفعل" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "منحنى محلل البيانات ظاهر" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "خادوم بعيد" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "يستورد العناوين…" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "يغلق…" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "لاعب منفرد" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "حجم الصوت" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "الصوت مكتوم" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "نظام الصوت معطل" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "نظام الصوت غير مدمج أثناء البناء" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "الصوت غير مكتوم" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "يُحتمل أن نسخة الخادم مختلفة عن %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "تعذر الاتصال بـ %s لأن IPv6 معطلة" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "غُيرَ مدى الرؤية الى %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "مدى الرؤية في أقصى حد: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "مدى الرؤية في أدنى حد: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "غُير الحجم الى %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "التكبير معطل من قبل لعبة أو تعديل" + +#: src/client/game.cpp +msgid "ok" +msgstr "موافق" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "الدردشة مخفية" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "الدردشة ظاهرة" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "الواجهة مخفية" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "الواجهة ظاهرة" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "محلل البيانات مخفي" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "محلل البيانات ظاهر ( صفحة %d من %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "تطبيقات" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "التحكم" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "أسفل" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "شغّل" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "مساعدة" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "الرئيسية" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Accept" +msgstr "IME Accept" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Convert" +msgstr "IME Convert" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Escape" +msgstr "IME Escape" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Mode Change" +msgstr "IME Mode Change" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Nonconvert" +msgstr "IME Nonconvert" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "يسار" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "الزر الأيسر" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Left Control" +msgstr "Left Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "القائمة اليسرى" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Left Shift" +msgstr "Left Shift" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Left Windows" +msgstr "Left Windows" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +#, fuzzy +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Middle Button" +msgstr "Middle Button" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad *" +msgstr "Numpad *" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad +" +msgstr "Numpad +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad ." +msgstr "Numpad ." + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad /" +msgstr "Numpad /" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad 0" +msgstr "Numpad 0" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad 1" +msgstr "Numpad 1" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad 2" +msgstr "Numpad 2" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad 3" +msgstr "Numpad 3" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad 4" +msgstr "Numpad 4" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad 5" +msgstr "Numpad 5" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad 6" +msgstr "Numpad 6" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad 7" +msgstr "Numpad 7" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad 8" +msgstr "Numpad 8" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad 9" +msgstr "Numpad 9" + +#: src/client/keycode.cpp +#, fuzzy +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Play" +msgstr "Play" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +#, fuzzy +msgid "Print" +msgstr "Print" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Return" +msgstr "Return" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Right" +msgstr "Right" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Right Control" +msgstr "Right Control" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Right Menu" +msgstr "Right Menu" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Right Shift" +msgstr "Right Shift" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Right Windows" +msgstr "Right Windows" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +#, fuzzy +msgid "Select" +msgstr "Select" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Sleep" +msgstr "Sleep" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Snapshot" +msgstr "Snapshot" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Up" +msgstr "Up" + +#: src/client/keycode.cpp +#, fuzzy +msgid "X Button 1" +msgstr "X Button 1" + +#: src/client/keycode.cpp +#, fuzzy +msgid "X Button 2" +msgstr "X Button 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "كبِر" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "الخريطة المصغرة مخفية" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "الخريطة المصغرة في وضع الرادار، تكبير x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "الخريطة المصغرة في وضع الأسطح، تكبير x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "الخريطة المصغرة في وضع الاكساء" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "فشل فتح صفحة الويب" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "يفتح صفحة الويب" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "تابع" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = التسلق نزولا" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "المشي التلقائي" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "القفز التلقائي" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "للخلف" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "حدود الكتلة" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "غير الكاميرا" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "دردشة" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "الأوامر" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "قلل المدى" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "قلل الحجم" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "اضغط مرتين على \"اقفز\" لتفعيل الطيران" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "اسقاط" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "للأمام" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "زد المدى" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "زد الحجم" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "المخزن" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "اقفز" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "المفتاح مستخدم مسبقا" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "اكتم" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "العنصر التالي" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "العنصر السابق" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "حدد المدى" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "صوّر الشاشة" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "تسلل" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "بدّل عرض الواجهة" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "بدّل عرض سجل المحادثة" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "بدّل وضع السرعة" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "بدّل حالة الطيران" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "بدّل ظهور الضباب" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "بدّل ظهور الخريطة المصغرة" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "اضغط على زر" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "غيِّر" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "كلمة مرور جديدة" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "كلمة المرور القديمة" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "كلمتا المرور غير متطابقتين!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "أخرج" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "مكتوم" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "حجم الصوت: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "ar" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "يرجى اختيار اسم!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(أندرويد) ثبت موقع عصى التحكم.\n" +"اذا عُطل ستنتقل عصى التحكم لموقع اللمسة الأولى." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "سحب ثلاثية الأبعاد" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "وضع الشاشة ثلاثية الأبعاد" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "رسالة ستعرض عند انهيار الخادم." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "رسالة تعرض لكل العملاء عند اغلاق الخادم." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "تسارع الطيران" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "تسارع الجاذبية، عقدة/ثانية²." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "معدِلات الكتل النشطة" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "مهلة إدارة الكتل النشطة" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "مدى الكتل النشطة" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"عنوان الخادم\n" +"اتركه فارغًا لاستضافة لعبة محلية.\n" +"أدرك أن هذه القيمة ستُتجاوز إذا كان حقل العنوان في القائمة الرئيسية يحوي " +"عنوانًا." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "ضمّن اسم العنصر" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "متقدم" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"يعدل منحنى الضوء عن طريق تطبيق \"تصحيح جاما\" عليه.\n" +"القيم الأعلى تجعل مستويات الإضاءة المتوسطة والدنيا أكثر بريقًا.\n" +"تترك القيمة \"1.0\" منحنى الضوء على حاله.\n" +"لها تأثير كبير فقط على ضوء النهار والضوء الصناعي ، ولها تأثير ضئيل للغاية " +"على ضوء الليل الطبيعي." + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "عدد اارسائل المسموح بها لكل 10 ثوان." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "تضخيم الوديان." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "أعلن عن الخادم" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "أدرجه في هذه القائمة." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "ضمّن اسم العنصر" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "اطلب إعادة الاتصال بعد انقطاعه" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "زر المشي التلقائي" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "قفز تلقائي فوق العوائق التي ارتفاعها كتلة واحدة." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "حفظ حجم الشاشة تلقائيًا" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "مفتاح Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "مفتاح Aux1 للتسلق / للنزول" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "مستوى الأرض الأساسي" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "إرتفاع التضاريس الأساسي." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "الإمتيازات الأساسية" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "ترشيح خطي ثنائي" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "مسار الخطين العريض والمائل" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "مسار خطي monospace العريض والمائل" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "مسار الخط العريض" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "مسار خط monospace العريض" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "ضع الكتلة في موقع اللاعب" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "مدمج" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "غير الكاميرا" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "انسيابية حركة الكامير" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "انسيابية حركة الكامير في الوضع السنيمائي" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "عُرض المغارة" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "الأوامر" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "حجم خط المحادثة" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "مفتاح المحادثة" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "حدُّ رسائل المحادثة" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "نسقُ رسائل المحادثة" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "الطول الأقصى لرسائل المحادثة" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "روابط المحادثة" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "الوضع السنيمائي" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "مفتاح الوضع السنيمائي" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"روابط ويب قابلة للنقر (زر الفأرة الأوسط أو زر الفأرة الأيسر+Ctrl) مفعلة في " +"المحادثة." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "عميل" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "عميل وخادم" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "سرعة التسلق" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "تفاصيل السحاب" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "سحاب" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "سحب في القائمة" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "ضباب ملون" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "ظلال ملونة" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"مستوى ضغط لحفظ الملف mapblocks في القرص.\n" +"-1 - المستوى الافتراضي\n" +"0 - ضغط ضعيف، سريع\n" +"9 - ضغط قوي، بطيء" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"مستوى ضغط لإرسال ملف mapblocks للعميل.\n" +"-1 - المستوى الافتراضي\n" +"0 - ضغط ضعيف، سريع\n" +"9 - ضغط قوي، بطيء" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "زجاج متصل" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "اتصل بخادم وسائط خارجي" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "زجاج متصل اذا كانت العقدة تدعمه." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "التحكم" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"يتحكم في طول دورة النهار والليل.\n" +"أمثلة:\n" +"72 = 20 دقيقة ، 360 = 4 دقائق ، 1 = 24 ساعة ، 0 = نهار / ليل أبدي." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "رسالة الانهيار" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "إبداعي" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "ضرر" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "مفتاح تقليل الحجم" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "التسارع الافتراضي" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "اللعبة الافتراضية" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"اللعبة الافتراضية عند إنشاء عالم جديد.\n" +"سيُتجاوز هذا الخيار عند إنشاء عالم جديد من القائمة." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "كلمة المرور الافتراضية" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "الامتيازات الافتراضية" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "نسقُ التقارير الافتراضي" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "حجم المكدس الافتراضي" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "يحدد المناطق التي تتواجد بها أشجار التفاح." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "يحدد المناطق التي توجد بها شواطئ رملية." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "يحدد توزع التضاريس العالية والمنحدرات." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "يحدد توزع التضاريس العالية." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "يضبط حجم الكهوف ، كلما قلت القيمة زاد حجم الكهوف." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "يحدد تضاريس التلال والبحيرات الاختيارية وموقعها." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "يحدد مستوى الأرض الأساسي." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "يحدد عمق الأنهار." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "يحدد مواقع الأشجار وكثافتها." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "تأخير إرسال الكتل بعد البناء" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Deprecated Lua API handling" +msgstr "معالجة API Lua القديمة" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "بُعد الكهوف الكبيرة عن السطح." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "المطورون الرئيسيون" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "حقل الرؤية" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "حقل الرؤية بالدرجات." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "التنعييم:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "عصا التحكم الافتراضية ثابتة" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "كثافة الأرض الطافية" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "زر الطيران" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "الضباب" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "بداية الضباب" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "مفتاح تبديل ظهور الضباب" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "حجم الخط" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "الخط عريض افتراضيًا" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "الخط مائل افتراضيًا" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "ظل الخط" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "حجم الخط" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "الألعاب" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "الواجهة ظاهرة" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"التسارع الأفقي عند الصقوط والقفز،\n" +"وحدتها عقدة/ثانية²." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"التسارع الأفقي والعمودي في نمط السرعة،\n" +"وحدتها عقدة/ثانية²." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"التسارع الأفقي والعمودي أثناء التسلق،\n" +"وحدتها عقدة/ثانية²." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "مفتاح العنصر التالي في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "مفتاح العنصر السابق في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "مفتاح الخانة 1 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "مفتاح الخانة 10 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "مفتاح الخانة 11 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "مفتاح الخانة 21 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "مفتاح الخانة 13 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "مفتاح الخانة 14 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "مفتاح الخانة 15 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "مفتاح الخانة 16 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "مفتاح الخانة 17 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "مفتاح الخانة 18 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "مفتاح الخانة 19 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "مفتاح الخانة 2 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "مفتاح الخانة 20 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "مفتاح الخانة 21 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "مفتاح الخانة 22 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "مفتاح الخانة 23 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "مفتاح الخانة 24 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "مفتاح الخانة 25 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "مفتاح الخانة 26 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "مفتاح الخانة 27 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "مفتاح الخانة 28 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "مفتاح الخانة 29 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "مفتاح الخانة 3 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "مفتاح الخانة 30 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "مفتاح الخانة 31 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "مفتاح الخانة 32 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "مفتاح الخانة 4 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "مفتاح الخانة 5 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "مفتاح الخانة 6 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "مفتاح الخانة 7 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "مفتاح الخانة 8 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "مفتاح الخانة 9 في شريط الإجراءات" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"سرعة موجات السوائل.كلما زادت القيمة زادت سرعتها.\n" +"إذا كانت سالبة ، فإن حركة الموجات ستكون لجهة المعاكسة .\n" +"لاستخدامها فعّل سوائل متموجة." + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "قلل منه لزيادة مقاومة الحركة في السوائل." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "اختلاف الرطوبة في الحيوم." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "خادم IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"إذا كان عدد الإطارات في الثانية (FPS) يتجاوز هذه القيمة\n" +"حدّه حتى لا تستهلك سرعة المعالج هباءً." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"إذا تم تعطيله ، فسيتم استخدام مفتاح \"Aux1\" للطيران بسرعة إذا كانت أوضاع " +"الطيران والسرعة \n" +"مفعلة." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"إذا فُعّل ، سيستخدم مفتاح \"Aux1\" بدلاً من مفتاح \"التسلل\" للتحرك للتسلق " +"والنزول." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "إذا فُعّل، سيعطل مكافحة الغش في وضع تعدد اللاعبين." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "اطرد اللاعبين الذين أرسلوا أكثر من X رسالة في 10 ثوانٍ." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "اللغة" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "عمق المغارات الكبيرة" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "أقصى عدد للمغارات الكبيرة" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "أقل عدد للمغارات الكبيرة" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "مظهر الأوراق" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"مظهر أوراق الشجر:\n" +"- مفصل: كل الوجوه مرئية\n" +"- بسيط: الوجوه الخارجية فقط ، إذا تم تحديد \"special_tiles\"\n" +"- معتم: يعطل الشفافية" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "إضاءة سلسة" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "حمّل محلل بيانات اللعبة" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "إبراز العقد" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "الشاشة:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "صوّر الشاشة" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "استضف خدوم" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "- اسم الخادم: " + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "وصف الخادم" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "منفذ الخدوم" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Show name tag backgrounds by default" +msgstr "الخط عريض افتراضيًا" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "إعدادات" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- النمط الإبداعي: " + +#~ msgid "- Damage: " +#~ msgstr "- التضرر: " + +#~ msgid "Address / Port" +#~ msgstr "العنوان \\ المنفذ" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "هل أنت متأكد من إعادة تعيين عالم اللاعب الوحيد؟" + +#~ msgid "Back" +#~ msgstr "عُد" + +#~ msgid "Basic" +#~ msgstr "أساسي" + +#~ msgid "Bump Mapping" +#~ msgstr "خريطة النتوءات" + +#~ msgid "Config mods" +#~ msgstr "اضبط التعديلات" + +#~ msgid "Configure" +#~ msgstr "اضبط" + +#~ msgid "Connect" +#~ msgstr "اتصل" + +#~ msgid "Credits" +#~ msgstr "إشادات" + +#~ msgid "Damage enabled" +#~ msgstr "الضرر ممكن" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "نزِّل لعبة,مثل لعبة Minetest, من minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "نزِّل لعبة من minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "تنزيل وتثبيت $1, يرجى الإنتظار..." + +#~ msgid "Enter " +#~ msgstr "أدخل " + +#~ msgid "Filtering" +#~ msgstr "الترشيح" + +#~ msgid "Game" +#~ msgstr "اللعبة" + +#~ msgid "Generate Normal Maps" +#~ msgstr "ولِد خرائط عادية" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "ثبت: الملف: \"$1\"" + +#~ msgid "Main" +#~ msgstr "الرئيسية" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "الخريطة المصغرة في وضع الرادار، تكبير x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "الخريطة المصغرة في وضع الرادار، تكبير x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "الخريطة المصغرة في وضع الأسطح، تكبير x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "الخريطة المصغرة في وضع الأسطح، تكبير x4" + +#~ msgid "Name / Password" +#~ msgstr "الاسم \\ كلمة المرور" + +#~ msgid "Name/Password" +#~ msgstr "الاسم\\كلمة المرور" + +#~ msgid "No" +#~ msgstr "لا" + +#~ msgid "Ok" +#~ msgstr "موافق" + +#~ msgid "PvP enabled" +#~ msgstr "قتال اللاعبين ممكن" + +#~ msgid "Reset singleplayer world" +#~ msgstr "أعد تعيين عالم اللاعب المنفرد" + +#~ msgid "Special" +#~ msgstr "خاص" + +#~ msgid "Start Singleplayer" +#~ msgstr "إلعب فرديا" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "لاستخدام المظللات يجب استخدام تعريف OpenGL." + +#~ msgid "View" +#~ msgstr "إعرض" + +#~ msgid "Yes" +#~ msgstr "نعم" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "أنت على وشك دخول هذا الخادوم للمرة الأولى باسم \"%s\".\n" +#~ "اذا رغبت بالاستمرار سيتم إنشاء حساب جديد باستخدام بياناتك الاعتمادية.\n" +#~ "لتأكيد التسجيل ادخل كلمة مرورك وانقر 'سجل وادخل'، أو 'ألغ' للإلغاء." + +#~ msgid "You died." +#~ msgstr "مِت" + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/be/minetest.po b/po/be/minetest.po new file mode 100644 index 0000000..8fa81a0 --- /dev/null +++ b/po/be/minetest.po @@ -0,0 +1,8320 @@ +msgid "" +msgstr "" +"Project-Id-Version: Belarusian (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2019-11-19 23:04+0000\n" +"Last-Translator: Viktar Vauchkevich <victorenator@gmail.com>\n" +"Language-Team: Belarusian <https://hosted.weblate.org/projects/minetest/" +"minetest/be/>\n" +"Language: be\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 3.10-dev\n" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Clear the out chat queue" +msgstr "Максімальны памер чаргі размовы" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Empty command." +msgstr "Загады размовы" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Выхад у меню" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Invalid command: " +msgstr "Лакальная каманда" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "Адзіночная гульня" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "Адзіночная гульня" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Адрадзіцца" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Вы загінулі" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "Лакальная каманда" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "Лакальная каманда" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Адбылася памылка ў Lua-скрыпце:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Адбылася памылка:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Галоўнае меню" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Перазлучыцца" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Сервер патрабуе перазлучыцца:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Абраць свет:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Версіі пратакола адрозніваюцца. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Сервер патрабуе версію пратакола $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Сервер падтрымлівае версіі пратакола паміж $1 і $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Мы падтрымліваем толькі $1 версію пратакола." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Мы падтрымліваем версіі пратакола паміж $1 і $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Скасаваць" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Залежнасці:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Адключыць усё" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Адключыць пакунак" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Уключыць усё" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Уключыць пакунак" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Не атрымалася ўключыць мадыфікацыю \"$1\" бо яна ўтрымлівае недапушчальныя " +"сімвалы. Дапускаюцца толькі [a-z0-9_]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Мадыфікацыя:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Няма (неабясковыя) залежнасцей" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Апісанне гульні адсутнічае." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Няма жорсткіх залежнасцяў" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Апісанне мадыфікацыі адсутнічае." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Няма неабавязковых залежнасцей" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Неабавязковыя залежнасці:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Захаваць" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Свет:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "уключаны" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "Загрузка…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Усе пакункі" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Already installed" +msgstr "Клавіша ўжо выкарыстоўваецца" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Вярнуцца ў галоўнае меню" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "Гуляць (сервер)" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Downloading..." +msgstr "Загрузка…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Не атрымалася спампаваць $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Гульні" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Усталяваць" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "Усталяваць" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "Неабавязковыя залежнасці:" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "Усталёўка: непадтрымліваемы файл тыпу \"$1\" або сапсаваны архіў" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Мадыфікацыі" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Немагчыма атрымаць пакункі" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Вынікі адсутнічаюць" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "No updates" +msgstr "Абнавіць" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Not found" +msgstr "Выключыць гук" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Пакункі тэкстур" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Выдаліць" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Абнавіць" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Свет з назвай \"$1\" ужо існуе" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Вышыня нівальнага поясу" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Altitude dry" +msgstr "Вышыня нівальнага поясу" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biome blending" +msgstr "Шум біёму" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biomes" +msgstr "Шум біёму" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caverns" +msgstr "Шум пячор" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caves" +msgstr "Актавы" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Стварыць" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Decorations" +msgstr "Ітэрацыі" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "" +"Увага: \"The minimal development test\" прызначаны толькі распрацоўшчыкам." + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Dungeons" +msgstr "Шум падзямелля" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Floating landmasses in the sky" +msgstr "Шчыльнасць гор лятучых астравоў" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Floatlands (experimental)" +msgstr "Узровень лятучых астравоў" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Humid rivers" +msgstr "Відэадрайвер" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Усталяваць" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Генератар мапы" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Генератар мапы: параметры" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mapgen-specific flags" +msgstr "Адмысловыя параметры генератара мапы 5" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mountains" +msgstr "Шум гор" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Гульня не абраная" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Rivers" +msgstr "Памер рэк" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Зерне" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Terrain surface erosion" +msgstr "Базавы шум рэльефу" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Vary river depth" +msgstr "Глыбіня рэк" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Назва свету" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "У вас няма ўсталяваных гульняў." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Вы ўпэўненыя, што хочаце выдаліць «$1»?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Выдаліць" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: не атрымалася выдаліць \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: хібны шлях да \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Выдаліць свет \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Пацвердзіць пароль" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Назва генератара мапы" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "Новы пароль" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Паролі не супадаюць!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Зарэгістравацца і далучыцца" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Ухваліць" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Змяніць назву пакунка мадыфікацый:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Гэты пакунак мадыфікацый мае назву ў modpack.conf, якая не зменіцца, калі яе " +"змяніць тут." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Няма апісання)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D-шум" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Назад на старонку налад" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Праглядзець" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Змесціва" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Змесціва" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Адключаны" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Рэдагаваць" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Уключаны" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Лакунарнасць" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Актавы" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Зрух" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Сталасць" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Калі ласка, увядзіце цэлы лік." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Калі ласка, увядзіце нумар." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Аднавіць прадвызначанае" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Маштаб" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Пошук" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Абраць каталог" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Абраць файл" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Паказваць тэхнічныя назвы" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Значэнне мусіць быць не менш за $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Значэнне мусіць быць не больш за $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X распаўсюджвання" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y распаўсюджвання" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z распаўсюджвання" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "абсалютная велічыня" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "прадвызначаны" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "паслаблены" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (уключана)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 мадыфікацый" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Не атрымалася ўсталяваць $1 у $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" +"Усталёўка мадыфікацыі: не атрымалася знайсці сапраўдную назву для \"$1\"" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Усталёўка мадыфікацыі: не атрымалася знайсці прыдатны каталог для пакунка " +"мадыфікацый \"$1\"" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Не атрымалася знайсці прыдатную мадыфікацыю альбо пакунак мадыфікацый" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Не атрымалася ўсталяваць $1 як пакунак тэкстур" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Не атрымалася ўсталяваць як $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Не атрымалася ўсталяваць мадыфікацыю як $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Не атрымалася ўсталяваць пакунак мадыфікацый як $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Загрузка…" + +#: builtin/mainmenu/serverlistmgr.lua +#, fuzzy +msgid "Public server list is disabled" +msgstr "Кліентскія мадыфікацыі выключаныя" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Паспрабуйце паўторна ўключыць спіс публічных сервераў і праверце злучэнне з " +"сецівам." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Актыўныя ўдзельнікі" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Active renderer:" +msgstr "Адлегласць адпраўлення актыўнага аб'екта" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Асноўныя распрацоўшчыкі" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Абраць каталог" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Былыя ўдзельнікі" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Былыя асноўныя распрацоўшчыкі" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Паказваць адладачную інфармацыю" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Пошук у сеціве" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Змесціва" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Адключыць пакунак тэкстур" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Інфармацыя:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Усталяваныя пакункі:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Залежнасці адсутнічаюць." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Апісанне пакунка адсутнічае" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Змяніць назву" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Выдаліць пакунак" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Выкарыстоўваць пакунак тэкстур" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Анансаваць сервер" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Адрас прывязкі" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Творчы рэжым" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Уключыць пашкоджанні" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Гуляць (сервер)" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Сервер" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Новы" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Няма створанага альбо абранага свету!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Гуляць" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Порт" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "Абраць свет:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Абраць свет:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Порт сервера" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Пачаць гульню" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "- Адрас: " + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Ачысціць" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Творчы рэжым" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "Пашкоджанні" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "Упадабанае" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Далучыцца да гульні" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Пінг" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "Анансаваць сервер" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Адлеглы порт" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "Апісанне сервера" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D-аблокі" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Усе налады" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Згладжванне:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Запамінаць памеры экрана" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Білінейны фільтр" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Змяніць клавішы" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Суцэльнае шкло" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Dynamic shadows" +msgstr "Цень шрыфту" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Цень шрыфту" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Аздобленае лісце" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "MIP-тэкстураванне" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "MIP-тэкстураванне + анізатропны фільтр" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Без фільтра" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Без MIP-тэкстуравання" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Падсвятленне вузла" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Абрыс вузла" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Няма" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Непразрыстае лісце" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Непразрыстая вада" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Часціцы" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Экран:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Налады" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Шэйдэры" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "Узровень лятучых астравоў" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Шэйдэры (недаступна)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Простае лісце" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Мяккае асвятленне" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Тэкстураванне:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Танальнае адлюстраванне" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Сэнсарны парог: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Трылінейны фільтр" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Дрыготкае лісце" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Калыханне вадкасцяў" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Дрыготкія расліны" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Памылка злучэння (таймаут?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Таймаут злучэння." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Завершана!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Ініцыялізацыя вузлоў" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Ініцыялізацыя вузлоў…" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Загрузка тэкстур…" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Перабудова шэйдэраў…" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Памылка злучэння (таймаут?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "Немагчыма знайсці ці загрузіць гульню \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Хібная спецыфікацыя гульні." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Галоўнае меню" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Няма абранага свету альбо адрасу. Немагчыма працягнуць." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Імя гульца задоўгае." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Калі ласка, абярыце імя!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Не атрымалася адкрыць пададзены файл пароля: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Пададзены шлях не існуе: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Падрабязней у файле debug.txt." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Адрас: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Рэжым: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Порт: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Публічны: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Назва сервера: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Адбылася памылка:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Аўтаматычны рух наперад адключаны" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Аўтаматычны рух наперад уключаны" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Абнаўленне камеры адключана" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Абнаўленне камеры ўключана" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Змяніць пароль" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Кінематаграфічны рэжым адключаны" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Кінематаграфічны рэжым уключаны" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "Модынг кліента" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Кліентскія мадыфікацыі выключаныя" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Злучэнне з серверам…" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Працягнуць" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Кіраванне:\n" +"- %s: ісці ўперад\n" +"- %s: ісці назад\n" +"- %s: ісці ўлева\n" +"- %s: ісці ўправа\n" +"- %s: скакаць/караскацца\n" +"- %s: красціся/спускацца\n" +"- %s: выкінуць прадмет\n" +"- %s: інвентар\n" +"- Mouse: круціцца/глядзець\n" +"- Mouse left: капаць/прабіваць\n" +"- Mouse right: змясціць/ужыць\n" +"- Mouse wheel: абраць прадмет\n" +"- %s: размова\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Стварэнне кліента…" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Стварэнне сервера…" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Адладачная інфармацыя і графік прафіліроўшчыка схаваныя" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Адладачная інфармацыя паказваецца" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Адладачная інфармацыя, графік прафіліроўшчыка і каркас схаваныя" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Прадвызначанае кіраванне:\n" +"Не ў меню:\n" +"- адзін націск: кнопка актывізацыі\n" +"- падвойны націск: пакласці/выкарыстаць\n" +"- слізганне пальцам: аглядзецца\n" +"У меню/інвентары:\n" +"- падвойны націск па-за меню:\n" +" --> закрыць\n" +"- крануць стос, крануць слот:\n" +" --> рухаць стос\n" +"- крануць і валачы, націснуць другім пальцам:\n" +" --> пакласці адзін прадмет у слот\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Абмежаванне бачнасці адключана" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Абмежаванне бачнасці ўключана" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Стварэнне кліента…" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Выхад у меню" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Выхад у сістэму" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Шпаркі рэжым адключаны" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Шпаркі рэжым уключаны" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Шпаркі рэжым уключаны (прывілей \"fast\" адсутнічае)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Рэжым палёту адключаны" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Рэжым палёту ўключаны" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Рэжым палёту ўключаны (прывілей \"fly\" адсутнічае)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Туман адключаны" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Туман уключаны" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Інфармацыя пра гульню:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Гульня прыпыненая" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Сервер (хост)" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Апісанне прадметаў…" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "КіБ/сек" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Медыя…" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "МіБ/сек" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Мінімапа на дадзены момант адключаная гульнёй альбо мадыфікацыяй" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "Адзіночная гульня" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Рэжым руху скрозь сцены адключаны" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Рэжым руху скрозь сцены ўключаны" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Рэжым руху скрозь сцены ўключаны (прывілей \"noclip\" адсутнічае)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Апісанне вузлоў…" + +#: src/client/game.cpp +msgid "Off" +msgstr "Адключана" + +#: src/client/game.cpp +msgid "On" +msgstr "Уключана" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Рэжым нахілення руху выключаны" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Рэжым нахілення руху ўключаны" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Графік прафіліроўшчыка паказваецца" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Адлеглы сервер" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Распазнаванне адраса…" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Выключэнне…" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Адзіночная гульня" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Гучнасць" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Гук адключаны" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Гук уключаны" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Бачнасць змененая на %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Бачнасць прызначаная на максімум: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Бачнасць прызначаная на мінімум: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Гучнасць змененая на %d %%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Каркас паказваецца" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Павелічэнне зараз выключана гульнёй альбо мадыфікацыяй" + +#: src/client/game.cpp +msgid "ok" +msgstr "добра" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Размова схаваная" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Размова паказваецца" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD схаваны" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD паказваецца" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Прафіліроўшчык схаваны" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Прафіліроўшчык паказваецца (старонка %d з %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Праграмы" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Ctrl" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Уніз" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Ачысціць EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Выканаць" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Даведка" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME Accept" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Пераўтварыць IME" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME Escape" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Змяніць рэжым IME" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME без пераўтварэння" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Уставіць" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Улева" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Левая кнопка" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Левы Ctrl" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Левае меню" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Левы Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Левы Super" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Меню" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Сярэдняя кнопка" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Дадат. *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Дадат. +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Дадат. -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Дадат. ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Дадат. /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Дадат. 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Дадат. 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Дадат. 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Дадат. 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Дадат. 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Дадат. 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Дадат. 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Дадат. 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Дадат. 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Дадат. 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Ачысціць OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Паўза" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Гуляць" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Друкаваць" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Вярнуцца" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Управа" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Правая кнопка" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Правы Ctrl" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Правае меню" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Правы Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Правы Super" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Абраць" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Сон" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Здымак" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Прагал" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Табуляцыя" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Уверх" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Дадат. кнопка 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Дадат. кнопка 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Павялічыць" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Мінімапа схаваная" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Мінімапа ў рэжыме радару, павелічэнне х1" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Мінімапа ў рэжыме паверхні, павелічэнне х1" + +#: src/client/minimap.cpp +#, fuzzy +msgid "Minimap in texture mode" +msgstr "Мінімальны памер тэкстуры" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Не атрымалася спампаваць $1" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Працягнуць" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "«Адмысловая» = злазіць" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Аўтабег" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Аўтаскок" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Назад" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Змяніць камеру" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Размова" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Загад" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Кансоль" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Паменшыць бачнасць" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Паменшыць гучнасць" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Падвойны \"скок\" = палёт" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Выкінуць" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Уперад" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Павялічыць бачнасць" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Павялічыць гучнасць" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Інвентар" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Скакаць" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Клавіша ўжо выкарыстоўваецца" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Лакальная каманда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Прыглушыць" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Наступны прадмет" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Папярэдні прадмет" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Адлегласць бачнасці" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Здымак экрана" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Красціся" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Размова" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Шпаркасць" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Палёт" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Туман" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Мінімапа" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Рух скрозь сцены" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Нахіленне руху" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "націсніце кнопку" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Змяніць" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Новы пароль" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Стары пароль" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Паролі не супадаюць!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Выхад" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Сцішаны" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Гучнасць: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "be" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Калі ласка, абярыце імя!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Фіксуе пазіцыю віртуальнага джойсціка.\n" +"Калі выключана, віртуальны джойсцік будзе з’яўляцца на пазіцыі першага " +"дотыку." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Выкарыстоўваць віртуальны джойсцік для актывацыі кнопкі \"aux\".\n" +"Калі ўключана, віртуальны джойсцік таксама будзе націскаць кнопку \"aux\" " +"калі будзе знаходзіцца па-за межамі асноўнага кола." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X, Y, Z) зрух фрактала ад цэнтру свету ў адзінках шкалы маштабу.\n" +"Выкарыстоўваецца для перамяшчэння вобласці адраджэння бліжэй да зямлі (0, " +"0).\n" +"Прадвызначанае значэнне падыходзіць для мностваў Мандэльброта, але для " +"мностваў Жулія яго неабходна падладзіць.\n" +"Дыяпазон прыкладна ад −2 да 2. Памножце на адзінку шкалы маштабу, каб " +"атрымаць зрух ў блоках." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(Х,Y,Z) шкала фрактала ў блоках.\n" +"Фактычны фрактальны памер будзе ў 2-3 разы больш.\n" +"Гэтыя ліку могуць быць вельмі вялікімі, фракталу няма патрэбы запаўняць " +"свет.\n" +"Павялічце іх, каб павялічыць маштаб дэталі фрактала.\n" +"Для вертыкальна сціснутай фігуры, што падыходзіць\n" +"востраву, зрабіце ўсе 3 лікі роўнымі для неапрацаванай формы." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2D-шум, што кіруе формай/памерам горных хрыбтоў." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2D-шум, што кіруе формай/памерам пагоркаў." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2D-шум, што кіруе формай/памерам сталовых гор." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "2D-шум, што кіруе памерам/распаўсюдам складчатых горных ланцугоў." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D-шум, што кіруе памерам/распаўсюдам пагоркаў." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "2D-шум, што кіруе памерам/распаўсюдам ступенявых горных ланцугоў." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2D-шум, што размяшчае поймы рэк і рэчышчы." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D-аблокі" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D-рэжым" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "3D mode parallax strength" +msgstr "Моц мапы нармаляў" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D-шум, што вызначае гіганцкія гроты." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D-шум, што вызначае структуру і вышыню гор.\n" +"Таксама вызначае структуру горнага рэльефу лятучых астравоў." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "3D-шум, што вызначае структуру схілаў рачных каньёнаў." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3D-шум, што вызначае гіганцкія гроты." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"3D-шум, што вызначае горныя выступы, скалы і т. п. Звычайна няшмат варыяцый." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D-шум, што вызначае колькасць падзямелляў на кавалку мапы." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3D-падтрымка.\n" +"Зараз падтрымліваюцца:\n" +"- none: без 3D-вываду.\n" +"- anaglyph: блакітны/пурпурны колеры ў 3D.\n" +"- interlaced: цотныя і няцотныя лініі адлюстроўваюць два розных кадра для " +"экранаў з падтрымкай палярызацыі.\n" +"- topbottom: падзел экрана верх/ніз.\n" +"- sidebyside: падзел экрана права/лева.\n" +"- pageflip: чатырохразовая буферызацыя (квадра-буфер)." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Абранае зерне для новай мапы, пакінце пустым для выпадковага.\n" +"Можна будзе змяніць пры стварэнні новага свету ў галоўным меню." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Паведамленне, якое будзе паказана ўсім кліентам пры крушэнні сервера." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Паведамленне, якое будзе паказана ўсім кліентам пры выключэнні сервера." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Інтэрвал захавання мапы" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Absolute limit of queued blocks to emerge" +msgstr "Абсалютны ліміт чаргі запытаў" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Паскарэнне ў паветры" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Паскарэнне свабоднага падзення ў вузлах за секунду за секунду." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Мадыфікатары актыўных блокаў" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Інтэрвал кіравання актыўнымі блокамі" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Адлегласць узаемадзеяння з блокамі" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Адлегласць адпраўлення актыўнага аб'екта" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Адрас для злучэння.\n" +"Пакінце пустым для запуску лакальнага сервера.\n" +"Майце на ўвазе, што поле адраса ў галоўным меню перавызначае гэты параметр." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Дадае часціцы пры капанні блока." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Наладка DPI (кропак на цалю) на экране\n" +"(не толькі X11/Android), напрыклад, для 4k-экранаў." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Дадаваць назвы прадметаў" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Пашыраныя" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Заўсёды ў палёце і шпарка" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Гама навакольнай аклюзіі" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" +"Колькасць паведамленняў, што гулец можа адправіць у размову цягам 10 секунд." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Узмацненне далін." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Анізатропная фільтрацыя" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Аб серверы" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Аб гэтым серверы." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Дадаваць назвы прадметаў" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Дадаваць назвы прадметаў у выплыўных падказках." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Шум яблынь" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Інэрцыя рукі" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Робіць больш рэалістычным рух рукі\n" +"падчас перамяшчэння камеры." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Прапанаваць перазлучыцца пасля крушэння" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"На гэтай дыстанцыі сервер будзе агрэсіўна аптымізаваць блокі, якія будзе " +"адпраўляць кліентам.\n" +"Малыя значэнні патэнцыйна палепшаць працаздольнасць за кошт бачных глюкаў " +"візуалізацыі.\n" +"(некаторыя блокі не будуць адлюстроўвацца пад вадой і ў пячорах, а таксама " +"часам на сушы)\n" +"Прызначэнне гэтага значэння на больш чым max_block_send_distance адключыць " +"аптымізацыю.\n" +"Прызначаецца ў блоках мапы (16 вузлоў)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Клавіша аўта-ўперад" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Аўтаматычна заскокваць на аднаблокавыя перашкоды." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Аўтаматычна дадаваць у спіс сервераў." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Аўтаматычна захоўваць памеры экрана" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Рэжым аўтамаштабавання" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "Клавіша скока" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key for climbing/descending" +msgstr "Адмысловая клавіша для караскання/спускання" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Клавіша назад" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Узровень зямлі" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Вышыня асноўнай мясцовасці." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Базавыя прывілеі" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Шум пляжаў" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Парог шуму пляжаў" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Білінейная фільтрацыя" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Адрас прывязкі" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Параметры шуму тэмпературы і вільготнасці для API-біёму" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Шум біёму" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Аптымізаваная адлегласць адпраўлення блокаў" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bold and italic font path" +msgstr "Шлях да монашырыннага шрыфту" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bold and italic monospace font path" +msgstr "Шлях да монашырыннага шрыфту" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bold font path" +msgstr "Шлях да шрыфту" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bold monospace font path" +msgstr "Шлях да монашырыннага шрыфту" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Будаваць на месцы гульца" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Убудаваны" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Змяніць камеру" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Блізкая плоскаць адсячэння камеры ў вузлах ад 0 да 0.5.\n" +"Большасці карыстальнікаў няма патрэбы змяняць гэты параметр.\n" +"Павелічэнне можа паменшыць колькасць артэфактаў на слабых графічных " +"працэсарах.\n" +"Тыповае — 0.1, а 0.25 будзе добра для слабых планшэтаў." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Згладжванне камеры" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Згладжванне камеры ў кінематаграфічным рэжыме" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Клавіша пераключэння абнаўлення камеры" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Шум пячор" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Шум пячоры № 1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Шум пячоры № 2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Шырыня пячор" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Шум пячоры 1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Шум пячоры 2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Абмежаванне пячор" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Шум пячор" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Конуснасць пячор" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Парог пячор" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Абмежаванне пячор" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "Максімальная колькасць паведамленняў у размове для выключэння" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Загады размовы" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat font size" +msgstr "Памер шрыфту" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Клавіша размовы" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat log level" +msgstr "Узровень журнала адладкі" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Максімальная колькасць паведамленняў у размове" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Фармат чат-паведамленняў" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Максімальная колькасць паведамленняў у размове для выключэння" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Максімальная працягласць паведамлення ў размове" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Клавіша пераключэння размовы" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Размова паказваецца" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Памер кавалка" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Кінематаграфічны рэжым" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Клавіша кінематаграфічнага рэжыму" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Чыстыя празрыстыя тэкстуры" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Кліент" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Кліент і сервер" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Модынг кліента" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Модынг кліента" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Абмежаванне дыяпазону пошуку ад кліента" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Модынг кліента" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Хуткасць караскання" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Радыус аблокаў" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Аблокі" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Аблокі — эфект на баку кліента." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Аблокі ў меню" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Каляровы туман" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Colored shadows" +msgstr "Каляровы туман" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Падзелены коскамі спіс пазнак, якія можна хаваць у рэпазіторыі.\n" +"\"nonfree\" можна выкарыстоўвацца, каб схаваць пакункі, якія з’яўляюцца " +"свабодным праграмным забеспячэннем паводле Free Software Foundation.\n" +"Таксама вы можаце прызначыць рэйтынг.\n" +"Пазнакі не залежаць ад версіі Minetest,\n" +"таму ўбачыць поўны спіс можна на https://content.minetest.net/help/" +"content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Спіс модаў, падзеленых коскамі, якім дазволены доступ да HTTP API, які\n" +"дазваляе ім адпраўляць і атрымліваць даныя праз Інтэрнэт." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Спіс давераных модаў, падзеленых коскамі, якім дазволены доступ да\n" +"небяспечных функцый, нават калі мод бяспекі ўключаны\n" +"(праз request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Клавіша загаду" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Суцэльнае шкло" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Злучэнне з вонкавым медыясерверам" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Злучае шкло, калі падтрымліваецца блокам." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Празрыстасць кансолі" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Колер кансолі" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Вышыня кансолі" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Сеціўны рэпазіторый" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Чорны спіс сцяжкоў ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "URL ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Бесперапынная хада" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Бесперапынны рух уперад, што пераключаецца клавішай \"аўтаматычны бег\".\n" +"Націсніце аўтаматычны бег яшчэ раз альбо рух назад, каб выключыць." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Кіраванне" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Кіруе працягласцю цыкла дня/ночы.\n" +"Прыклады: 72 = 20 мін, 360 = 4 мін, 1 = 24 г, 0 — дзень і ноч не змяняюцца." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Кіруе крутасцю/глыбінёй азёр." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Кіруе крутасцю/вышынёй пагоркаў." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Паведамленне пры крушэнні" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Творчасць" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Празрыстасць перакрыжавання" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "Празрыстасць перакрыжавання (паміж 0 і 255)." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Колер перакрыжавання" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI (кропак на цалю)" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Пашкоджанні" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Клавіша пераключэння адладачных даных" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Парог памеру файла журнала адладкі" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Узровень журнала адладкі" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Кнопка памяншэння гучнасці" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Крок адведзенага сервера" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Прадвызначанае паскарэнне" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Прадвызначаная гульня" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Прадвызначаная гульня пры стварэнні новага свету.\n" +"Гэта можна змяніць пры стварэнні свету ў галоўным меню." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Прадвызначаны пароль" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Прадвызначаныя прывілеі" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Прадвызначаны фармат справаздачы" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default stack size" +msgstr "Прадвызначаная гульня" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Вызначае вобласці, дзе на дрэвах ёсць яблыкі." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Вызначае вобласці з пяшчанымі пляжамі." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Вызначае вобласці ўзвышэнняў паверхні і ўплывае на крутасць скал." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Вызначае размеркаванне паверхні на ўзвышшах." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Вызначае поўны памер пячор. Пры малых значэннях ствараюцца вялікія пячоры." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Вызначае буйнамаштабную структуру рэчышч." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Вызначае размяшчэнне і рэльеф дадатковых пагоркаў і азёр." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Вызначае базавы ўзровень зямлі." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Вызначае глыбіню рэчышча." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Вызначае максімальную адлегласць перадачы даных гульца ў блоках\n" +"(0 — неабмежаваная)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Вызначае шырыню рэчышча." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Вызначае шырыню поймы ракі." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Вызначае вобласці і шчыльнасць дрэў." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Затрымка паміж абнаўленнямі сетак на кліенце ў мілісекундах. Павелічэнне " +"гэтага значэння\n" +"запаволіць тэмп абнаўлення сетак, і такім чынам паменшыць дрыжанне на " +"павольных кліентах." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Затрымка ў адпраўленні блокаў пасля будаўніцтва" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Затрымка паказу падказак, зададзеная ў мілісекундах." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Апрацоўка састарэлых выклікаў Lua API" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Глыбіня, ніжэй якой трапляюцца вялікія пячоры." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Глыбіня, ніжэй якой трапляюцца вялікія пячоры." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Апісанне сервера, якое паказваецца пры далучэнні гульцоў і ў спісе сервераў." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Парог шуму пустынь" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Пустыні з'яўляюцца, калі np_biome перавысіць гэтае значэнне.\n" +"Ігнаруецца, калі ўключаны сцяжок snowbiomes." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Дэсінхранізаваць анімацыю блока" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Ітэрацыі" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "Клавіша ўправа" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Часціцы пры капанні" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Выключыць антычыт" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Забараніць пустыя паролі" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Даменная назва сервера, што будзе паказвацца ў спісе сервераў." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Падвойны націск \"скока\" пераключае рэжым палёту" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Палвойны націск клавішы скока пераключае рэжым палёту." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Клавіша выкідання прадмета" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Зводка адладачных даных генератара мапы." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Максімальная Y падзямелля" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Мінімальная Y падзямелля" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Шум падзямелля" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Уключыць падтрымку Lua-модынгу на кліенце.\n" +"Гэта падтрымка эксперыментальная і API можа змяніцца." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Уключаць акно кансолі" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable creative mode for all players" +msgstr "Уключыць творчы рэжым для новых мап." + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Уключыць джойсцікі" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Уключыць абарону мадыфікацый." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Уключыць абарону мадыфікацый" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Дазволіць гульцам атрымоўваць пашкоджанні і паміраць." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Уключыць выпадковы карыстальніцкі ўвод (толькі для тэставання)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Уключыць мяккае асвятленне з простай навакольнай аклюзіяй.\n" +"Адключыць для хуткасці ці другога выгляду." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Забараніць падлучэнне старых кліентаў.\n" +"Старыя кліенты — тыя, што не крушацца пры злучэнні\n" +"з новымі серверамі, але яны могуць не падтрымліваць усе новыя функцыі, што " +"чакаюцца." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Уключыць выкарыстанне адлеглага медыясервера (калі забяспечана серверам).\n" +"Адлеглыя серверы даюць магчымасць хутчэй спампоўваць медыяфайлы (напрыклад " +"тэкстуры) пры злучэнні з серверам." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Уключыць калыханне камеры і вызначыць яго значэнне.\n" +"Напрыклад: 0 — няма, 1.0 — звычайнае, 2.0 — падвойнае." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Уключыць/выключыць падтрымку IPv6. Сервер IPv6 можа быць абмежаваны IPv6-" +"кліентамі ў залежнасці ад сістэмнай канфігурацыі.\n" +"Ігнаруецца, калі зададзены «bind_address»." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Уключае анімацыю прадметаў інвентару." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Уключае кэшаванне павернутых вонкі сетак." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Уключае мінімапу." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Профіль даліны" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Інтэрвал друкавання даных прафілявання рухавіка" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Метады сутнасці" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "FPS when unfocused or paused" +msgstr "Максімальны FPS, калі гульня прыпыненая." + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Каэфіцыентны шум" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Каэфіцыент калыхання пры падзенні" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Fallback font path" +msgstr "Рэзервовы шрыфт" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Клавіша шпаркасці" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Паскарэнне шпаркага рэжыму" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Хуткасць шпаркага рэжыму" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Шпаркае перамяшчэнне" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Шпаркае перамяшчэнне (з дапамогай клавішы выкарыстання).\n" +"Патрабуецца прывілей \"fast\" на серверы." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Поле зроку" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Поле зроку ў градусах." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Файл у каталозе client/serverlist/, які змяшчае вашыя ўлюбёныя серверы, якія " +"паказваюцца\n" +"ва ўкладцы сумеснай гульні." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Глыбіня запаўняльніка" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Шум глыбіні запаўняльніка" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Кінематаграфічнае танальнае адлюстраванне" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Адфільтраваныя тэкстуры могуць змешваць значэнні RGB з цалкам празрыстымі " +"суседнімі, якія PNG-аптымізатары звычайна адкідваюць, што часам прыводзіць " +"да з’яўлення цёмнага ці светлага краёў празрыстых тэкстур.\n" +"Выкарыстайце гэты фільтр, каб выправіць тэкстуры падчас загрузкі." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Згладжванне:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Першы з чатырох 3D-шумоў, якія разам вызначаюць дыяпазон вышыні пагоркаў/гор." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Першы з двух 3D-шумоў, якія разам вызначаюць тунэлі." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Фіксацыя зерня мапы" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Фіксацыя віртуальнага джойсціка" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland density" +msgstr "Шчыльнасць гор лятучых астравоў" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland maximum Y" +msgstr "Максімальная Y падзямелля" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland minimum Y" +msgstr "Мінімальная Y падзямелля" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland noise" +msgstr "Базавы шум лятучых астравоў" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland taper exponent" +msgstr "Шчыльнасць гор лятучых астравоў" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland tapering distance" +msgstr "Базавы шум лятучых астравоў" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland water level" +msgstr "Узровень лятучых астравоў" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Клавіша палёту" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Палёт" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Туман" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Пачатак туману" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Клавіша пераключэння туману" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Памер шрыфту" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Цень шрыфту" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Празрыстасць цені шрыфту" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Памер шрыфту" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Фармат чат-паведамленняў гульца. Наступныя радкі з'яўляюцца " +"запаўняльнікамі:\n" +"@name, @message і @timestamp (неабавязкова)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Фармат здымкаў экрана." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Прадвызначаны колер фону гульнявой кансолі" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Прадвызначаная непразрыстасць фону гульнявой кансолі" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Колер фону гульнявой кансолі ў поўнаэкранным рэжыме" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Непразрыстасць фону гульнявой кансолі ў поўнаэкранным рэжыме" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Колер фону гульнявой кансолі (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Непразрыстасць фону гульнявой кансолі (паміж 0 і 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Колер фону гульнявой кансолі (R,G,B) у поўнаэкранным рэжыме." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" +"Непразрыстасць фону гульнявой кансолі ў поўнаэкранным рэжыме (паміж 0 і 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Клавіша ўперад" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Першы з чатырох 2D-шумоў, якія разам вызначаюць дыяпазон вышыні пагоркаў/гор." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Тып фрактала" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Частка бачнай адлегласці, на якой пачынае з'яўляцца туман" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Як далёка ад кліентаў ствараюцца блокі. Вызначаецца ў блоках мапы (16 " +"блокаў)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Як далёка блокі адпраўляюцца кліенту. Вызначаецца ў блоках мапы (16 блокаў)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Адлегласць у блоках, на якой кліенты распазнаюць аб'екты (16 блокаў).\n" +"\n" +"Калі прызначыць значэнне больш за active_block_range, то сервер будзе " +"запамінаць рухаючыяся аб’екты на гэтай адлегласці ў накірунку погляду " +"гульца. (Гэта дапаможа пазбегнуць раптоўнага знікнення жывых істот)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "На ўвесь экран" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Поўнаэкранны рэжым." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Маштабаванне графічнага інтэрфейсу" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Фільтр маштабавання графічнага інтэрфейсу" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "txr2img-фільтр маштабавання графічнага інтэрфейсу" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Гульні" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Глабальныя зваротныя выклікі" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Глабальныя параметры генерацыі мапы.\n" +"У генератары мапы 6 параметр «decorations» кіруе ўсімі дэкарацыямі,\n" +"апроч дрэў і травы джунгляў, а ў астатніх генератарах гэты параметр\n" +"кіруе ўсімі дэкарацыямі." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "Градыент крывой святла на максімальным узроўні святла." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "Градыент крывой святла на мінімальным узроўні святла." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Графіка" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Графіка" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Графіка" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Гравітацыя" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Узровень зямлі" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Шум бруду" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP-мадыфікацыі" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Маштабаванне графічнага інтэрфейсу" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Клавіша пераключэння HUD" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Апрацоўка састарэлых выклікаў Lua API:\n" +"- legacy: (паспрабаваць) імітаваць старыя паводзіны (прадвызначана для " +"рэлізу).\n" +"- log: імітаваць і запісваць састарэлыя выклікі (прадвызначана для " +"адладкі).\n" +"- error: прыпыніць пры састарэлым выкліку (пажадана для распрацоўшчыкаў " +"модаў)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Прафіляваць самаго прафіліроўшчыка:\n" +"* Вымяраць пустую функцыю.\n" +"Вызначыць дадатковыя выдаткі ад вымярэнняў (+1 выклік функцыі).\n" +"* Вымяраць сэмплера, што выкарыстоўваецца для абнаўлення статыстыкі." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Шум цеплавога змешвання" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Цеплавы шум" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "Вышыня акна падчас запуску." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Шум вышыні" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Шум выбару вышыні" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Крутасць пагоркаў" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Парог пагоркаў" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Шум крутасці" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Шум крутасці 2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Шум крутасці 3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Шум крутасці 4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Хатняя старонка сервера, якая будзе паказвацца ў спісе сервераў." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Гарызантальнае паскарэнне ў паветры пры скачках ці падзенні\n" +"ў вузлах за секунду за секунду." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Гарызантальнае паскарэнне ў хуткі рэжыме\n" +"ў вузлах за секунду за секунду." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Гарызантальнае і вертыкальнае паскарэнне на зямлі ці пры карасканні\n" +"ў вузлах за секунду за секунду." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Наступны прадмет на панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Папярэдні прадмет на панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Прадмет 1 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Прадмет 10 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Прадмет 11 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Прадмет 12 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Прадмет 13 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Прадмет 14 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Прадмет 15 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Прадмет 16 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Прадмет 17 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Прадмет 18 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Прадмет 19 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Прадмет 2 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Прадмет 20 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Прадмет 21 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Прадмет 22 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Прадмет 23 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Прадмет 24 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Прадмет 25 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Прадмет 26 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Прадмет 27 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Прадмет 28 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Прадмет 29 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Прадмет 3 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Прадмет 30 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Прадмет 31 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Прадмет 32 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Прадмет 4 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Прадмет 5 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Прадмет 6 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Прадмет 7 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Прадмет 8 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Прадмет 9 панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Наколькі глыбокімі рабіць рэкі." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Як доўга сервер будзе чакаць перад выгрузкай блокаў мапы,\n" +"якія не выкарыстоўваюцца.\n" +"На больш высокіх значэннях адбываецца плаўней, але патрабуецца больш памяці." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Паменшыце гэта, каб павялічыць інерцыю вадкасці." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Наколькі шырокімі рабіць рэкі." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Шум змешвання вільготнасці" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Шум вільготнасці" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Варыяцыя вільготнасці для біёмаў." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "Сервер IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Калі FPS перасягне гэтае значэнне, абмежаваць прастоем,\n" +"каб не марнаваць дарма магутнасць працэсара." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Калі выключана, то клавіша \"special\" выкарыстоўваецца для хуткага палёту, " +"калі палёт і шпаркі рэжым уключаныя." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Калі ўключаны, то сервер будзе выконваць адсяканне блокаў кіруючыся пазіцыяй " +"вачэй гульца. Гэта можа паменшыць колькасць адпраўляемых\n" +"блокаў на 50–60 %. Кліент не будзе атрымоўваць большую частку нябачных\n" +"блокаў, таму рэжым руху скрозь сцены стане менш карысным." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Калі ўключана адначасова з рэжымам палёту, то гулец будзе мець магчымасць " +"лятаць скрозь цвёрдыя блокі.\n" +"На серверы патрабуецца прывілей \"noclip\"." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Калі ўключана, то для спускання і апускання будзе выкарыстоўвацца клавіша " +"\"special\" замест \"sneak\"." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Уключае пацвярджэнне рэгістрацыі пры злучэнні з серверам.\n" +"Калі выключана, новы акаўнт будзе рэгістравацца аўтаматычна." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Калі ўключана, то дзеянні запісваюцца для адраблення.\n" +"Гэты параметр чытаецца толькі падчас запуску сервера." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Калі ўключана, то выключае абарону ад падману ў сумеснай гульні." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Калі ўключаны, то з’яўленне хібных даных у свеце не прывядзе да выключэння " +"сервера.\n" +"Уключайце гэта толькі, калі ведаеце, што робіце." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Калі ўключана, вызначае накірункі руху адносна нахілу гульца падчас палёту " +"або плавання." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "Калі ўключана, то гульцы не змогуць далучыцца з пустым паролем." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Калі ўключана, то вы зможаце паставіць блокі на месцы гульца (ногі + " +"узровень вачэй).\n" +"Гэта спрашчае працу з блокамі ў вузкіх месцах." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Калі абмежаванне CSM для дыяпазону блокаў уключана, выклікі get_node " +"абмяжоўваюцца на гэтую адлегласць ад гульца да блока." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Калі памер файла debug.txt пры адкрыцці перавысіць колькасць мегабайтаў,\n" +"пазначаных гэтай наладай, файл будзе перамешчаны ў debug.txt.1,\n" +"а стары debug.txt.1 будзе выдалены.\n" +"debug.txt перамяшчаецца, калі гэтая значэнне станоўчае." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "Калі вызначана, гульцы заўсёды адраджаюцца ў абраным месцы." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Не зважаць на памылкі свету" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "Празрыстасць фону гульнявой кансолі (непразрыстасць, паміж 0 і 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Колер фону гульнявой кансолі (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "Вышыня гульнявой кансолі, паміж 0,1 (10 %) і 1,0 (100 %)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Клавіша павелічэння гучнасці" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Пачатковая вертыкальная хуткасць пры скоках у вызлах за секунду." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Убудаваныя інструменты.\n" +"Звычайна патрабуюцца толькі распрацоўшчыкам ядра" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Instrument chat commands on registration." +msgstr "Выконваць загады ў размове пры рэгістрацыі." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Інструмент функцый глабальных зваротных выклікаў пры рэгістрацыі.\n" +"(усё, што перадаецца ў функцыю minetest.register_*())" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Інструмент функцыі дзеяння мадыфікатараў актыўных блокаў пры рэгістрацыі." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Інструмент функцыі дзеяння мадыфікатараў загружаемых блокаў пры рэгістрацыі." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Інструмент метадаў сутнасці пры рэгістрацыі." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "Інтэрвал захавання важных змен свету, вызначаны ў секундах." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Інтэрвал адпраўлення кліентам часу." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Анімацыя прадметаў інвентару" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Клавіша інвентару" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Адвярнуць мыш" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Змяняе вертыкальны рух мышы на адваротны." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Italic font path" +msgstr "Шлях да монашырыннага шрыфту" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Italic monospace font path" +msgstr "Шлях да монашырыннага шрыфту" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Час існавання выкінутай рэчы" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Ітэрацыі" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Інтэрацыі рэкурсіўнай функцыі.\n" +"Пры павелічэнні павялічваецца колькасць дэталяў, але павялічваецца час " +"апрацоўкі.\n" +"Пры інтэрацыях 20 гэты генератар мапы будзе падобны да mapgen V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID джойсціка" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Інтэрвал паўтору кнопкі джойсціка" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick dead zone" +msgstr "Тып джойсціка" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Адчувальнасць джойсціка" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Тып джойсціка" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Толькі для мноства Жулія: кампанент W гіперкомплекснай канстанты,\n" +"што вызначае форму фрактала Жулія.\n" +"Не ўплывае на 3D-фракталы.\n" +"Дыяпазон прыкладна ад −2 да 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Толькі для мноства Жулія: кампанент X гіперкомплекснай канстанты,\n" +"што вызначае форму фрактала Жулія.\n" +"Дыяпазон прыкладна ад −2 да 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Толькі для мноства Жулія: кампанент Y гіперкомплекснай канстанты,\n" +"што вызначае форму фрактала Жулія.\n" +"Не ўплывае на 3D-фракталы.\n" +"Дыяпазон прыкладна ад −2 да 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Толькі для мноства Жулія: кампанент Z гіперкомплекснай канстанты, што " +"вызначае форму фрактала Жулія.\n" +"Не ўплывае на 3D-фракталы.\n" +"Дыяпазон прыкладна ад −2 да 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Жулія W" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Жулія X" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Жулія у" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Жулія z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Клавіша скока" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Хуткасць скокаў" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша памяншэння дыяпазону бачнасці.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша памяншэння гучнасці.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша скока.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выкідання абранага прадмета.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша павелічэння дыяпазону бачнасці.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Кнопка павелічэння гучнасці.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша скока.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша паскарэння руху ў шпаркім рэжыме.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для руху назад.\n" +"Таксама выключае аўтабег, калі той актыўны.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша руху ўперад.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша руху ўлева.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша руху ўправа.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выключэння гуку.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша адкрыцця акна размовы для ўводу загадаў.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Кнопка адкрыцця акна размовы для ўводу лакальных загадаў.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша адкрыцця акна размовы.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша адкрыцця інвентару.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша скока.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 11 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 12 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 13 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 14 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 15 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 16 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 17 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 18 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 19 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 20 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 21 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 22 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 23 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 24 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 25 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 26 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 27 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 28 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 29 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 30 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 31 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 32 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 8 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 5 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 1 прадмета панэлі хуткага доступу..\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 4 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару наступнага прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 9 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару папярэдняга прадмета панэлі хуткага доступу..\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 2 прадмета панэлі хуткага доступу..\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 7 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 6 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 10 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выбару 3 прадмета панэлі хуткага доступу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша \"красціся\".\n" +"Таксама выкарыстоўваецца для спускання і апускання ў ваду, калі " +"aux1_descends выключана.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння паміж камерамі ад першай асобы і ад трэцяй асобы.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша стварэння здымкаў экрана.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння аўтабегу.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння кінематаграфічнага рэжыму.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння адлюстравання мінімапы.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння шпаркага рэжыму.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння рэжыму палёту.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння рэжыму руху скрозь сцены.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для пераключэння рэжыму нахілення руху.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння абнаўлення камеры. Выкарыстоўваецца толькі для " +"распрацоўкі.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння адлюстравання размовы.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння адлюстравання адладачных даных.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння адлюстравання туману.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння адлюстравання HUD.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння адлюстравання буйной размовы.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння адлюстравання прафіліроўшчыка. Выкарыстоўваецца для " +"распрацоўкі.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша пераключэння абмежавання дыяпазону бачнасці.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша выкарыстання набліжэння калі гэта магчыма.\n" +"Глядзіце http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" +"Адлучаць гульцоў, што ўвялі гэтую колькасць паведамленняў цягам 10 секунд." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Крутасць азёр" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Парог азёр" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Мова" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Глыбіня вялікіх пячор" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Клавіша буйной кансолі" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Стыль лісця" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Стыль лісця:\n" +"- Fancy: бачныя ўсе бакі\n" +"- Simple: бачныя вонкавыя бакі, калі выкарыстоўваюцца адмысловыя " +"special_tiles\n" +"- Opaque: вылючыць празрыстасць" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Клавіша ўлева" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Працягласць цыкла сервера і інтэрвал, па якім аб'екты, як правіла, " +"абнаўляюцца па сетцы." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Значэнне \"true\" уключае калыханне лісця.\n" +"Патрабуюцца ўключаныя шэйдэры." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Інтэрвал часу паміж цыкламі выканання мадыфікатараў актыўных блокаў" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Інтэрвал часу паміж цыкламі выканання таймераў блокаў" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Інтэрвал часу паміж цыкламі кіравання актыўнымі блокамі (ABM)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Узровень дэталізацыі журнала debug.txt:\n" +"- <nothing> (не вядзецца)\n" +"- none (паведамленні без ўзроўня)\n" +"- error (памылкі)\n" +"- warning (папярэджанні)\n" +"- action (дзеянні)\n" +"- info (інфармацыя)\n" +"- verbose (падрабязнасці)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Light curve boost" +msgstr "Сярэдні ўздым крывой святла" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Light curve boost center" +msgstr "Цэнтр сярэдняга ўздыму крывой святла" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Light curve boost spread" +msgstr "Распаўсюджванне сярэдняга ўздыму крывой святла" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Light curve gamma" +msgstr "Сярэдні ўздым крывой святла" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Light curve high gradient" +msgstr "Сярэдні ўздым крывой святла" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Light curve low gradient" +msgstr "Цэнтр сярэдняга ўздыму крывой святла" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Мяккае асвятленне" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Ліміт генерацыі мапы ў блоках ва ўсіх 6 напрамках ад (0, 0, 0).\n" +"Генеруюцца толькі блокі, якія цалкам заходзяцца ў дадзеных межах.\n" +"Значэнне захоўваецца для кожнага свету." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Абмяжоўвае колькасць паралельных HTTP-запытаў. Уплывае на:\n" +"- Спампоўванне медыяданых калі сервер выкарыстоўвае параметр " +"remote_media.\n" +"- Спампоўванне спіса сервераў і аб'яў сервера.\n" +"- Спампоўванні праз галоўнае меню (напрыклад кіраўнік мадыфікацый).\n" +"Дзейнічае толькі пры кампіляцыі з cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Цякучасць вадкасці" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Згладжванне цякучасці вадкасці" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Максімум цыклічных вадкасцяў" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Час ачышчэння чаргі вадкасцяў" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Сцяканне вадкасці" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Інтэрвал абнаўлення вадкасці ў секундах." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Інтэрвал абнаўлення вадкасці" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Загружаць прафіліроўшчык гульні" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Загружаць прафіліроўшчык гульні для збору даных.\n" +"Падае загад /profiler для доступу да скампіляванага профілю.\n" +"Карысна для распрацоўшчыкаў мадыфікацый і аператараў сервераў." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Загрузка мадыфікатараў блокаў" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Ніжні ліміт Y для падзямелляў." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lower Y limit of floatlands." +msgstr "Ніжні ліміт Y для падзямелляў." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Скрыпт галоўнага меню" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Зрабіць колер туману і неба залежным ад часу сутак (світанак, захад) і " +"напрамку погляду." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Робіць усе вадкасці непразрыстымі" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Каталог мапаў" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Атрыбуты генерацыі для генератара Карпат." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Атрыбуты генерацыі мапы для генератара плоскасці.\n" +"Часам азёры і пагоркі могуць дадавацца ў плоскі свет." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Атрыбуты генерацыі для плоскага генератара.\n" +"«terrain» уключае генерацыю не-фрактальнага рельефу:\n" +"акіяны, выспы і падзямеллі." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Атрыбуты генерацыі мапы для генератара далін.\n" +"«altitude_chill»: памяншае цеплыню з ростам вышыні.\n" +"«humid_rivers»: павялічвае вільготнасць абапал рэк.\n" +"«vary_river_depth»: калі ўключана, то нізкая вільготнасць і высокая " +"тэмпература ўплываюць на ўзровень вады ў рэках.\n" +"«altitude_dry»: памяншае вільготнасць з ростам вышыні." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Атрыбуты генерацыі для генератара 5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Атрыбуты генерацыі мапы для генератара мапы 6.\n" +"Параметр «snowbiomes» (снежныя біёмы) ўключае новую сістэму з 5 біёмамі.\n" +"Калі «snowbiomes» ўключаны, то аўтаматычна ўключаюцца «джунглі»,\n" +"а параметр «jungles» ігнаруецца." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Атрыбуты генерацыі для генератара 7.\n" +"«ridges» уключае рэкі." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Ліміт генерацыі мапы" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Інтэрвал захавання мапы" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map shadows update frames" +msgstr "Інтэрвал абнаўлення вадкасці" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Ліміт блокаў мапы" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Затрымка генерацыі сеткі блокаў мапы" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Памер кэшу блокаў у генератары сетак у МБ" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Таймаут выгрузкі блокаў мапы" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Генератар мапы: Карпаты" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Адмысловыя параметры генератара \"Карпаты\"" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Генератар мапы: плоскасць" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Адмысловыя параметры генератара плоскасці мапы" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Генератар мапы: фракталы" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Адмысловыя параметры фрактальнага генератара мапы" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Генератар мапы 5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Адмысловыя параметры генератара мапы 5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Генератар мапы 6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Адмысловыя параметры генератара мапы 6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Генератар мапы 7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Адмысловыя параметры генератара мапы 7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Генератар мапы: даліны" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Адмысловыя параметры генератара далін" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Генератар мапы: адладка" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Назва генератара мапы" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Максімальная адлегласць генерацыі блокаў" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Максімальная адлегласць адпраўлення блокаў" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Максімальная колькасць вадкасці, якая апрацоўваецца за крок." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Максімальная колькасць дадатковых блокаў clearobjects" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Максімальная колькасць пакункаў за ітэрацыю" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Максімальны FPS (кадраў за секунду)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "Максімальны FPS, калі гульня прыпыненая." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Максімальная колькасць прымусова загружаемых блокаў" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Максімальная шырыня панэлі хуткага доступу" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Максімальная ўстойлівасць вадкасці. Кантралюе запавольванне\n" +"пры паступленні вадкасці з высокай хуткасцю." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Максімальная колькасць блокаў, што адначасова адпраўляюцца аднаму кліенту.\n" +"Агульная максімальная колькасць падлічваецца дынамічна:\n" +"max_total = ceil ((# кліентаў + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "Максімальная колькасць блокаў, што можна дадаць у чаргу загрузкі." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Максімальная колькасць блокаў, што можна дадаць у чаргу генерацыі.\n" +"Пакінце пустым для аўтаматычнага выбару неабходнага значэння." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Максімальная колькасць блокаў у чарзе на загрузку з файла.\n" +"Пакінце пустым для аўтаматычнага выбару неабходнага значэння." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Максімальная колькасць прымусова загружаемых блокаў мапы." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Максімальная колькасць блокаў мапы для кліента, якія застануцца ў памяці.\n" +"Значэнне -1 для неабмежаванай колькасці." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Максімальная колькасць пакункаў, што адпраўляюцца за крок адпраўлення.\n" +"Калі ў вас маруднае злучэнне, паспрабуйце паменшыць, але не памяншайце\n" +"ніжэй за колькасць кліентаў памножаную на 2." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Максімальная колькасць адначасова падлучаных гульцоў." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Максімальная колькасць адлюстроўваемых у размове паведамленняў" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Максімальная колькасць статычна захаваных аб'ектаў у блоку." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Максімальная колькасць аб'ектаў у блоку" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Максімальная частка бягучага акна, што будзе выкарыстоўвацца для панэлі " +"хуткага доступу.\n" +"Карысна, калі ёсць што-небудзь, што будзе паказвацца справа ці злева ад " +"панэлі." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Максімальная колькасць адначасова адпраўляемых блокаў на кліента" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Максімальны памер чаргі размовы" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Максімальны памер чаргі размовы.\n" +"0 - выключыць чаргу, -1 - зрабіць неабмежаванай." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Максімальны час у мілісекундах, які можа заняць спампоўванне файла\n" +"(напрыклад спампоўванне мадыфікацыі)." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Максімальная колькасць карыстальнікаў" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Кэш сетак" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Паведамленне дня" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Паведамленне, якое паказваецца для гульцоў, што падлучаюцца." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Метад падсвятлення абранага аб'екта." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Мінімапа" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Клавіша мінімапы" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Вышыня сканавання мінімапы" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "3D-шум, што вызначае колькасць падзямелляў на кавалку мапы." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Мінімальны памер тэкстуры" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "MIP-тэкстураванне" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Прафіліроўшчык" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Бяспека" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Каналы мадыфікацый" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Modifies the size of the HUD elements." +msgstr "Змяняе памер элеметаў панэлі HUD." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Шлях да монашырыннага шрыфту" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Памер монашырыннага шрыфту" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "Памер монашырыннага шрыфту" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Шум вышыні гор" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Шум гор" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Шум вышыні гор" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Нулявы ўзровень гары" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Адчувальнасць мышы" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Множнік адчувальнасці мышы." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Шум бруду" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Множнік калыхання пры падзенні.\n" +"Напрыклад: 0 — няма, 1.0 — звычайнае, 2.0 — падвойнае." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Клавіша выключэння гуку" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Выключыць гук" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Назва генератара мапы, што будзе выкарыстоўвацца для стварэння новага " +"свету.\n" +"Гэта можна змяніць пры стварэнні свету ў галоўным меню.\n" +"Цяперашнія вельмі нестабільныя генератары:\n" +"- Неабавясковыя плаваючыя выспы 7 (звычайна адключаны)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Імя гульца.\n" +"Падча запуску сервера, кліенты, што падлучаюцца з гэтым імем будуць " +"адміністратарамі.\n" +"Гэта можна перавызначыць у галоўным меню перад запускам." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "Назва сервера, што будзе паказвацца пры падлучэнні і ў спісе сервераў." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Near plane" +msgstr "Блізкая плоскасць адсячэння" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Сеткавы порт для праслухоўвання (UDP).\n" +"Гэтае значэнне можна перавызначыць у галоўным меню падчас запуску." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Сетка" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Новыя карыстальнікі мусяц ўвесці гэты пароль." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Рух скрозь сцены" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Клавіша руху скрозь сцены" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Падсвятленне вузла" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Падсвятленне блокаў" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Інтэрвал абнаўлення блокаў" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Шумы" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Колькасць узнікаючых патокаў" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Колькасць узнікаючых патокаў.\n" +"УВАГА: Цяпер можа ўзнікаць мноства хібаў, калі «num_emerge_threads» больш за " +"1.\n" +"Строга рэкамендуецца ўстанавіць гэтае значэнне ў 1, пакуль гэта папярэджанне " +"не знікне.\n" +"Значэнне 0:\n" +"- аўтаматычны выбар. Колькасць узнікаючых патокаў будзе вызначацца\n" +"як «колькасць працэсараў - 2» з ніжняй мяжой у 1.\n" +"Любое іншае значэнне:\n" +"- вызначае колькасць узнікаючых патокаў з ніжняй мяжой у 1.\n" +"УВАГА: Майце на ўвазе, што павелічэнне колькасці патокаў павялічвае\n" +"хуткасць рухавіка генератара мапы, але можа ўплываць на прадукцыйнасць " +"гульні,\n" +"замінаючы іншым працэсам, асабліва адзіночнай гульні і (альбо) запуску коду " +"Lua у\n" +"'On_generated. Для большасці карыстальнікаў найлепшым значэннем можа быць 1." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Колькасць дадатковых блокаў, што могуць адначасова загружацца загадам /" +"clearobjects.\n" +"Гэта кампраміс паміж дадатковымі выдаткамі на транзакцыю sqlite\n" +"і спажываннем памяці (4096 = 100 МБ, як правіла)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Непразрыстыя вадкасці" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Адкрыць меню паўзы калі акно страціла фокус. Не будзе працаваць калі якое-" +"небудзь меню ўжо адкрыта." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Шлях да каталога з шэйдэрамі. Калі не зададзены, то будзе выкарыстоўвацца " +"прадвызначаны шлях." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "Шлях да каталога тэкстур. Усе тэкстуры ў першую чаргу шукаюцца тут." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Паўза пры страце фокусу" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Per-player limit of queued blocks to generate" +msgstr "Абмежаванне чэргаў на генерацыю" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Фізіка" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Клавіша нахілення руху" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Рэжым нахілення руху" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Клавіша палёту" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place repetition interval" +msgstr "Інтэрвал паўторнай пстрычкі правай кнопкі мышы" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Гулец можа лётаць без ўплыву дзеяння сілы цяжару.\n" +"Неабходны прывілей «noclip» на серверы." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Дыстанцыя перадачы даных гульца" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Гулец супраць гульца" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Білінейная фільтрацыя" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Порт для злучэння (UDP).\n" +"Майце на ўвазе, што поле порта ў галоўным меню пераазначае гэтую наладу." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Прадухіляе паўтарэнне капання і размяшчэння блокаў пры ўтрыманні кнопкі " +"мышы.\n" +"Уключыце гэты параметр, калі занадта часта выпадкова капаеце або будуеце." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Забараняць мадыфікацыям выконваць небяспечныя дзеянні кшталту запуску " +"кансольных загадаў." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Друкаваць даныя прафілявання рухавіка праз вызначаныя інтэрвалы часу (у " +"секундах).\n" +"0 для адключэння. Карысна для распрацоўшчыкаў." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Прывілеі, якія маюць гульцы з basic_privs" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Прафіліроўшчык" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Клавіша пераключэння прафіліроўшчыка" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Радыус зоны аблокаў складаецца з 64 квадратаў з блокаў.\n" +"Значэнне вышэй 26 прывядзе да рэзкіх зрэзаў вуглоў вобласці аблокаў." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Падымае мясцовасць, каб зрабіць поймы ўздоўж рэк." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Выпадковы ўвод" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Клавіша выбару дыяпазону бачнасці" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Надаўнія паведамленні размовы" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Regular font path" +msgstr "Шлях да справаздач" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Адлеглы медыясервер" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Адлеглы порт" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Выдаляе коды колераў з уваходных паведамленняў размовы\n" +"Выкарыстоўвайце, каб забараніць гульцам ужываць колеры ў сваіх паведамленнях" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Замяняе прадвызначанае галоўнае меню на карыстальніцкае." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Шлях да справаздач" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Абмяжоўвае доступ да пэўных функцый з боку кліента на серверах.\n" +"Спалучыце адзнакі байтаў ніжэй, каб абмежаваць функцыі, альбо ўвядзіце 0, " +"каб нічога не абмяжоўваць:\n" +"LOAD_CLIENT_MODS: 1 (выключыць загрузку карыстальніцкіх мадыфікацый)\n" +"CHAT_MESSAGES: 2 (выключыць выклік send_chat_message з боку кліента)\n" +"READ_ITEMDEFS: 4 (выключыць выклік get_item_def з боку кліента)\n" +"READ_NODEDEFS: 8 (выключыць выклік get_node_def з боку кліента)\n" +"LOOKUP_NODES_LIMIT: 16 (абмяжоўвае выклік get_node з боку кліента\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (выключыць выклік get_player_names з боку кліента)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Шум распаўсюджвання горных хрыбтоў" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Шум хрыбтоў" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Шум падводных хрыбтоў" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Памер шуму падводных хрыбтоў" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Клавіша ўправа" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Глыбіня рэчышча" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Шырыня рэчышча" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Глыбіня рэк" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Шум рэк" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Памер рэк" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Шырыня поймы ракі" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Запіс аднаўлення" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Памер шуму пагоркаў" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Шум распаўсюджвання пагоркаў" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Круглая мінімапа" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Бяспечнае капанне і размяшчэнне блокаў" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Пясчаныя пляжы з'яўляюцца, калі np_beach перавышае гэта значэнне." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Захоўваць мапу, атрыманую ад кліента, на дыск." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Аўтаматычна захоўваць памер акна пры змене." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Захаванне мапы, атрыманай з сервера" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Маштабаваць графічны інтэрфейс да вызначанага значэння.\n" +"Выкарыстоўваецца фільтр бліжэйшых суседзяў са згладжваннем.\n" +"Гэта згладзіць некаторыя вострыя вуглы і змяшае пікселі\n" +"пры маштабаванні ўніз за кошт размыцця некаторых крайніх пікселяў,\n" +"калі выява маштабуецца не да цэлых памераў." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Экран:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Вышыня экрана" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Шырыня экрана" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Каталог здымкаў экрана" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Фармат здымкаў экрана" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Якасць здымкаў экрана" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Якасць здымкаў экрана. Выкарыстоўваецца толькі для фармату JPEG.\n" +"1 азначае найгоршую якасць, а 100 — найлепшую. 0 - прадвызначаная якасць." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Здымак экрана" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Шум марскога дна" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Другі з чатырох 2D-шумоў, што разам вызначаюць межы вышыні пагоркаў/гор." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Другі з двух 3D-шумоў, што разам вызначаюць тунэлі." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Глядзіце https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Колер рамкі вобласці вылучэння (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Колер вобласці вылучэння" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Шырыня вобласці вылучэння" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Выбірае адзін з 18 тыпаў фракталаў.\n" +"1 = 4D-«круглае» мноства Мандэльброта.\n" +"2 = 4D-«круглае» мноства Жулія.\n" +"3 = 4D-«квадратнае» мноства Мандэльброта.\n" +"4 = 4D-«квадратнае» мноства Жулія.\n" +"5 = 4D-мноства Мандэльброта «Кузэна Мэндзі».\n" +"6 = 4D-мноства Жулія «Кузэна Мэндзі».\n" +"7 = 4D-мноства Мандэльброта «Варыяцыя».\n" +"8 = 4D-мноства Жулія «Варыяцыя».\n" +"9 = 3D-мноства Мандэльброта «Мандэльброт/Мандэльбар».\n" +"10 = 3D-мноства Жулія «Мандэльброт/Мандэльбар».\n" +"11 = 3D-мноства Мандэльброта «Калядная яліна».\n" +"12 = 3D-мноства Жулія «Калядная яліна».\n" +"13 = 3D-мноства Мандэльброта «Мандэльбульб».\n" +"14 = 3D-мноства Жулія «Мандэльбульб».\n" +"15 = 3D-мноства Мандэльброта «Кузэн Мандэльбульб».\n" +"16 = 3D-мноства Жулія «Кузэн Мандэльбульб».\n" +"17 = 4D-мноства Мандэльброта «Мандэльбульб».\n" +"18 = 4D-мноства Жулія «Мандэльбульб»." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL сервера" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Назва сервера" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Апісанне сервера" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL сервера" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Адрас сервера" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Апісанне сервера" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Назва сервера" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Порт сервера" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Адсячэнне аклюзіі на баку сервера" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Порт сервера" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL спіса сервераў" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "URL спіса сервераў" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Файл спіса сервераў" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Прызначыць мову. Пакіньце пустым, каб выкарыстаць мову сістэмы.\n" +"Пасля змены мовы патрэбна перазапусціць гульню." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Вызначае максімальную колькасць сімвалаў у паведамленнях, што адпраўляюцца " +"кліентамі ў размову." + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Значэнне \"true\" уключае калыханне лісця.\n" +"Патрабуюцца ўключаныя шэйдэры." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Значэнне \"true\" уключае калыханне лісця.\n" +"Патрабуюцца ўключаныя шэйдэры." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Значэнне \"true\" уключае хваляванне вады.\n" +"Патрабуюцца ўключаныя шэйдэры." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Значэнне \"true\" уключае калыханне раслін.\n" +"Патрабуюцца ўключаныя шэйдэры." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Шлях да шэйдэраў" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Шэйдэры дазваляюць выкарыстоўваць дадатковыя візуальныя эфекты і могуць " +"павялічыць\n" +"прадукцыйнасць на некаторых відэакартах.\n" +"Працуюць толькі з OpenGL." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "Якасць здымкаў экрана" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map texture size" +msgstr "Мінімальны памер тэкстуры" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "Зрух цені шрыфту. Калі 0, то цень не будзе паказвацца." + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Форма мінімапы. Уключана — круг, выключана — квадрат." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Паказваць адладачную інфармацыю" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Паказваць вобласць вылучэння" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Прызначыць мову. Пакіньце пустым, каб выкарыстаць мову сістэмы.\n" +"Пасля змены мовы патрэбна перазапусціць гульню." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Паведамленне аб выключэнні" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Памер кавалкаў мапы, ствараемых генератарам мапы, падаецца ў блоках мапы (16 " +"блокаў).\n" +"УВАГА!: Ад змены гэтага значэння няма амаль ніякай карысці, а прызначэнне\n" +"яму больш 5 можа выклікаць шкоду.\n" +"З павелічэннем гэтага значэння павялічыцца шчыльнасць размяшчэння пячор і " +"падзямелляў.\n" +"Змяняць гэтае значэнне патрэбна толькі ў асаблівых сітуацыях, а ў звычайных " +"рэкамендуецца пакінуць як ёсць." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Памер кэшу блокаў у генератары сетак. Павелічэнне гэтага значэння\n" +"павялічыць адсотак пераносу ў кэш, прадухіляючы капіяванне даных\n" +"з галоўнага патоку гульні, тым самым памяншаючы дрыжанне." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Частка W" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Нахіл і запаўненне выкарыстоўваюцца разам для змены вышыні." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "Невялікія варыацыі вільготнасці для змешвання біёмаў на межах." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "Невялікія варыацыі тэмпературы для змешвання біёмаў на межах." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Мяккае асвятленне" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Згладжваць камеру пры яе панарамным руху. Таксама завецца як згладжванне " +"выгляду або мышы.\n" +"Карысна для запісу відэа." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"Плаўнае паварочванне камеры ў кінематаграфічным рэжыме. 0 для выключэння." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Плаўнае паварочванне камеры. 0 для выключэння." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Клавіша \"красціся\"" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Хуткасць хады ўпотай" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Хуткасць крадкоў у вузлах за секунду." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Празрыстасць цені шрыфту" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Гук" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Вызначае URL, з якога кліент будзе спампоўваць медыяфайлы замест " +"выкарыстання UDP.\n" +"$filename мусіць быць даступным па адрасе з $remote_media$filename праз " +"cURL\n" +"(відавочна, што remote_media мусіць заканчвацца скосам).\n" +"Недасяжныя файлы будуць спампоўвацца звычайным чынам." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Распаўсюджванне сярэдняга ўздыму крывой святла.\n" +"Стандартнае адхіленне сярэдняга ўздыму па Гаўсу." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Статычная кропка адраджэння" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Шум крутасці" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Крок шуму памеру гары" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Крок шуму распаўсюджвання гор" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Strength of 3D mode parallax." +msgstr "Моц паралакса." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Строгая праверка пратакола" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Прыбіраць коды колераў" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "Сінхронны SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Варыяцыя тэмпературы ў біёмах." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Налады" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Альтэрнатыўны шум рэльефу" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Базавы шум рэльефу" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Вышыня рэльефу" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Шум высокага рэльефу" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Шум рэльефу" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Парог шуму рэльефу пагоркаў.\n" +"Рэгулюе прапорцыю плошчы свету, запоўненую пагоркамі.\n" +"Наладжвайце ў бок 0.0 для павелічэння прапорцыю." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Парог шуму рэльефу азёр.\n" +"Рэгулюе прапорцыю плошчы свету, запоўненую азёрамі.\n" +"Наладжвайце ў бок 0.0 для павелічэння прапорцыю." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Сталы шум рэльефу" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Шлях да тэкстур" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Тэкстуры блока можна выраўняць альбо адносна блока, альбо свету.\n" +"Першы рэжым лепш падыходзіць да такіх рэчаў, як машыны, мэбля і г.д., а ў " +"другім лесвіцы і мікраблокі робяцца больш адпаведнымі\n" +"асяроддзю. Аднак, гэтая магчымасць з'яўляецца новай, і не можа " +"выкарыстоўвацца на старых серверах, гэты параметр дае магчымасць ужываць яго " +"да пэўных тыпаў блокаў. Майце на ўвазе, што гэты\n" +"рэжым лічыцца эксперыментальным і можа працаваць неналежным чынам." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "URL рэпазіторыя" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The dead zone of the joystick" +msgstr "Ідэнтыфікатар джойсціка для выкарыстання" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Прадвызначаны фармат захавання профіляў,\n" +"пры запуску `/profiler save [format]` без вызначэння фармату." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "Глыбіня глебы альбо іншага запаўняльніка." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"Шлях да файла адносна каталога свету, у якім будуць захоўвацца профілі." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "Ідэнтыфікатар джойсціка для выкарыстання" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"Адлегласць у пікселях, з якой пачынаецца ўзаемадзеянне з сэнсарных экранам." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "Сеткавы інтэрфейс, які праслухоўвае сервер." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Прывілеі, якія аўтаматычна атрымліваюць новыя карыстальнікі.\n" +"Глядзіце поўны спіс прывілеяў у /privs." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"Радыус аб'ёму блокаў вакол кожнага гульца, у якім дзейнічаюць\n" +"актыўныя блокі, вызначаны ў блоках мапы (16 блокаў).\n" +"У актыўных блоках загружаюцца аб'екты і працуе ABM.\n" +"Таксама гэта мінімальны дыяпазон, у якім апрацоўваюцца актыўныя аб'екты " +"(жывыя істоты).\n" +"Неабходна наладжваць разам з active_object_range." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"Рухавік адмалёўкі для Irrlicht.\n" +"Пасля змены гэтага параметра спатрэбіцца перазупуск.\n" +"Заўвага: на Андроідзе, калі не ведаеце што выбраць, ужывайце OGLES1, інакш " +"дадатак можа не запусціцца.\n" +"На іншых платформах рэкамендуецца OpenGL, бо цяпер гэта адзіны драйвер\n" +"з падтрымкай шэйдэраў." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "Адчувальнасць восяў джойсціка пры азіранні." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"Інтэнсіўнасць навакольнага аклюзіўнага зацямнення блока.\n" +"Чым меншае значэнне, тым цямней, чым большае, тым святлей.\n" +"Дыяпазон карэктных значэнняў ад 0,25 да 4,0 уключна.\n" +"Калі значэнне будзе па-за дыяпазонам, то будзе брацца бліжэйшае прыдатнае " +"значэнне." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Час (у секундах), на які чарга вадкасці можа перавысіць апрацоўку,\n" +"пакуль не адбудзецца спроба паменшыць памер чаргі, прыбраўшы з яе старыя " +"элементы.\n" +"Значэнне 0 выключае гэтую функцыю." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Час у секундах паміж паўторамі падзей пры ўтрыманні камбінацыі кнопак " +"джойсціка." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Час у секундах паміж паўторамі падзей пры ўтрыманні правай кнопкі мышы." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Тып джойсціка" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"Вертыкальная адлегласць, на якой тэмпература падае на 20, калі\n" +"«altitude_chill» уключаны. Таксама вертыкальная адлегласць,\n" +"на якой вільготнасць падае на 10, калі «altitude_dry» уключаны." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Трэці з чатырох 2D-шумоў, якія разам вызначаюць межы вышыні пагоркаў/гор." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Час існавання выкінутай рэчы ў секундах.\n" +"Прызначце −1 для выключэння гэтай асаблівасці." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "Час дня пры запуску новага свету ў мілігадзінах (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Інтэрвал адпраўлення часу" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Хуткасць часу" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "Таймаут выдалення невыкарыстоўваемых даных з памяці кліента." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Для памяншэння лагаў, перадача блокаў запавольваецца калі гулец штосьці " +"будуе.\n" +"Гэты параметр вызначае, наколькі перадача будзе запавольвацца пасля " +"размяшчэння альбо выдалення блока." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Клавіша пераключэння рэжыму камеры" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Затрымка падказкі" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Парог сэнсарнага экрана" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Парог сэнсарнага экрана" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Шум дрэў" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Трылінейная фільтрацыя" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"Карысна для згладжвання мінімапы на павольных машынах." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Давераныя мадыфікацыі" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL спіса сервераў, які паказваецца ва ўкладцы сумеснай гульні." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Субдыскрэтызацыя" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Субдыскрэтызацыя падобная на выкарыстанне нізкай раздзяляльнай здольнасці " +"экрана,\n" +"але ўжываецца толькі да гульнявога свету, не кранаючы інтэрфейс.\n" +"Гэта значна павялічвае працаздольнасць за кошт вываду менш падрабязнай " +"выявы.\n" +"Высокія значэнні прыводзяць да менш дэталізаванай выявы." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Неабмежаваная дыстанцыя перадачы даных гульца" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Выгрузіць невыкарыстоўваемыя даныя сервера" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Верхні ліміт Y для падзямелляў." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Upper Y limit of floatlands." +msgstr "Верхні ліміт Y для падзямелляў." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Аб'ёмныя аблокі замест плоскіх." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Выкарыстоўваць анімацыю аблокаў для фона галоўнага меню." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" +"Выкарыстоўваць анізатропную фільтрацыю пры праглядзе тэкстуры пад вуглом." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Выкарыстоўваць білінейную фільтрацыю пры маштабаванні тэкстур." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Выкарыстоўвайць MIP-тэкстураванне для маштабавання тэкстур.\n" +"Можа трохі павялічыць прадукцыйнасць, асабліва пры выкарыстанні\n" +"пакета тэкстур з высокай раздзяляльнай здольнасцю.\n" +"Гама-карэкцыя пры памяншэнні маштабу не падтрымліваецца." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Выкарыстоўваць трылінейную фільтрацыю пры маштабаванні тэкстур." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Вертыкальная сінхранізацыя" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Глыбіня далін" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Запаўненне далін" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Профіль даліны" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Схіл далін" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Варыяцыя глыбіні запаўняльніка біёму." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Варыяцыя максімальнай вышыні гор (у блоках)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Варыяцыя колькасці пячор." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Варыяцыя вертыкальнага маштабавання рэльефу.\n" +"Рэльеф становіцца амаль плоскім, калі шум менш -0.55." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Змяняе глыбіню паверхневых блокаў біёму." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Змяняе няроўнасць рэльефу.\n" +"Вызначае значэнне «persistence» для шумоў terrain_base і terrain_alt." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Кіруе крутасцю гор." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Хуткасць вертыкальнага караскання ў вузлах за секунду." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Вертыкальная сінхранізацыя." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Відэадрайвер" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Каэфіцыент калыхання прагляду" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Дыстанцыя бачнасці ў блоках." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Клавіша памяншэння дыяпазону бачнасці" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Клавіша павелічэння дыяпазону бачнасці" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Клавіша прыбліжэння" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Дыяпазон бачнасці" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Virtual joystick triggers Aux1 button" +msgstr "Дадатковая кнопка трыгераў віртуальнага джойсціка" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Гучнасць" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Уключае паралакснае аклюзіўнае тэкстураванне.\n" +"Патрабуюцца ўключаныя шэйдэры." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Каардыната W згенераванай 3D-часткі 4D-фрактала.\n" +"Вызначае, якая 3D-частка 4D-формы згенеруецца.\n" +"Змяняе форму фрактала.\n" +"Не ўплывае на 3D-фракталы.\n" +"Дыяпазон прыкладна ад −2 да 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Хуткасць хады і палёту ў вузлах за секунду." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Хуткасць хады" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "Хуткасць хады, палёту і караскання ў хуткі рэжыме ў вузлах за секунду." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Узровень вады" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Узровень воднай паверхні свету." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Калыханне блокаў" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Калыханне лісця" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Калыханне вадкасцяў" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Вышыня водных хваляў" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Хуткасць водных хваляў" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Даўжыня водных хваляў" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Калыханне раслін" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "Колер вобласці вылучэння" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Пры ўключэнні gui_scaling_filter усе выявы графічнага інтэрфейсу павінны " +"быць адфільтраваныя праграмна, але некаторыя выявы генеруюцца апаратна " +"(напрыклад, рэндэрынг у тэкстуру для элементаў інвентару)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Калі gui_scaling_filter_txr2img уключаны, выявы капіююцца\n" +"з апаратуры ў праграмнае асяроддзе для маштабавання.\n" +"Калі не, то вярнуцца да старога метаду маштабавання для відэадрайвераў,\n" +"якія не падтрымліваюць перадачу тэкстур з апаратуры назад." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Пры выкарыстанні білінейнага, трылінейнага або анізатропнага фільтра,\n" +"тэкстуры малога памеру могуць быць расплывістыя, таму адбываецца\n" +"аўтаматычнае маштабаванне іх з інтэрпаляцыяй па бліжэйшым суседзям,\n" +"каб захаваць выразныя пікселі.\n" +"Гэты параметр вызначае мінімальны памер для павялічаных тэкстур.\n" +"Пры высокіх значэннях выглядае больш выразна, але патрабуе больш памяці.\n" +"Рэкамендаванае значэнне - 2.\n" +"Значэнне гэтага параметру вышэй за 1 можа не мець бачнага эфекту,\n" +"калі не ўключаныя білінейная, трылінейная або анізатропная фільтрацыя.\n" +"Таксама выкарыстоўваецца як памер тэкстуры базавага блока для\n" +"сусветнага аўтамасштабавання тэкстур." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"Ці павінна быць паміж блокамі мапы дэсінхранізацыя анімацыі тэкстур блокаў." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Ці паказваюцца гульцы кліентам без абмежавання дыстанцыі бачнасці.\n" +"Састарэла, выкарыстоўвайце параметр «player_transfer_distance»." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Ці дазваляць гульцам прычыняць шкоду і забіваць іншых." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Ці пытацца кліентаў аб перазлучэнні пасля крушэння (Lua).\n" +"Вызначце, калі ваш сервер наладжаны на аўтаматычны перазапуск." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Ці размяшчаць туманы па-за зонай бачнасці." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "Паказваць адладачную інфармацыю (тое ж, што і F5)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "Шырыня кампанента пачатковага памеру акна." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Шырыня межаў вылучэння блокаў." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Толькі для Windows-сістэм: запускае Minetest з акном загаднага радка ў " +"фоне.\n" +"Змяшчае тую ж інфармацыю, што і файл debug.txt (прадвызначаная назва)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Каталог свету (усё ў свеце захоўваецца тут).\n" +"Не патрабуецца, калі запускаецца з галоўнага меню." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Пачатковы час свету" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Выраўнаваныя па свеце тэкстуры можна маштабаваць так, каб яны ахоплівалі " +"некалькі блокаў. Але сервер можа не адправіць патрэбны\n" +"маштаб, асабліва калі вы выкарыстоўваеце адмыслова\n" +"распрацаваны пакунак тэкстур; з гэтым параметрам кліент спрабуе\n" +"вызначыць маштаб аўтаматычна на падставе памеру тэкстуры.\n" +"Глядзіце таксама texture_min_size.\n" +"Увага: Гэты параметр ЭКСПЕРЫМЕНТАЛЬНЫ!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Рэжым выроўнівання тэкстур па свеце" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Каардыната Y плоскай паверхні." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y нулявога ўзроўня градыента шчыльнасці гор. Выкарыстоўваецца для " +"вертыкальнага зруху гор." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Y верхняга ліміту шырокіх пячор." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Y-адлегласць, на якой пячора пашырыцца да поўнага памеру." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Y-узровень сярэдняй паверхні рэльефу." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Y-узровень верхняга ліміту пячоры." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Y-узровень высокага рэльефу, што стварае горы." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Y-узровень нізкага рэльефу і марскога дна." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Y-узровень марскога дна." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Таймаўт спампоўвання файла па cURL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "Таймаўт cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Ліміт адначасовых злучэнняў cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Творчы рэжым: " + +#~ msgid "- Damage: " +#~ msgstr "- Пашкоджанні: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = паралаксная аклюзія са звесткамі аб нахіле (хутка).\n" +#~ "1 = рэльефнае тэкстураванне (павольней, але якасней)." + +#~ msgid "Address / Port" +#~ msgstr "Адрас / Порт" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Наладка гама-кадавання для светлавых табліц. Высокія значэнні — больш " +#~ "ярчэйшыя.\n" +#~ "Гэты параметр прызначаны толькі для кліента і ігнаруецца серверам." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "Кіруе звужэннем астравоў горнага тыпу ніжэй сярэдняй кропкі." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Вы ўпэўненыя, што хочаце скінуць свет адзіночнай гульні?" + +#~ msgid "Back" +#~ msgstr "Назад" + +#~ msgid "Basic" +#~ msgstr "Базавыя" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Біты на піксель (глыбіня колеру) у поўнаэкранным рэжыме." + +#~ msgid "Bump Mapping" +#~ msgstr "Тэкстураванне маскамі" + +#~ msgid "Bumpmapping" +#~ msgstr "Рэльефнае тэкстураванне" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "Цэнтр сярэдняга ўздыму крывой святла." + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Змена інтэрфейсу галоўнага меню:\n" +#~ "- full: выбар свету для адзіночнай альбо сеткавай гульні, асобны спіс " +#~ "чужых сервераў.\n" +#~ "- simple: адзін свет для адзіночнай гульні ў меню, дзе спіс чужых " +#~ "сервераў; можа быць карысна для невелічкіх экранаў.\n" +#~ "Прадвызначана: simple для Android, full для ўсіх астатніх." + +#~ msgid "Config mods" +#~ msgstr "Налады мадыфікацый" + +#~ msgid "Configure" +#~ msgstr "Наладзіць" + +#~ msgid "Connect" +#~ msgstr "Злучыцца" + +#~ msgid "Content Store" +#~ msgstr "Крама дадаткаў" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Кантралюе хуткасць сцякання вадкасці." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Кіруе шчыльнасцю горнага рэльефу лятучых астравоў.\n" +#~ "Гэты зрух дадаецца да значэння 'np_mountain'." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Кіруе шырынёй тунэляў. Меншае значэнне стварае больш шырокія тунэлі." + +#~ msgid "Credits" +#~ msgstr "Падзякі" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Колер перакрыжавання (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Пашкоджанні ўключаныя" + +#~ msgid "Darkness sharpness" +#~ msgstr "Рэзкасць цемры" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Прадвызначаны таймаўт для cURL, зададзены ў мілісекундах.\n" +#~ "Уплывае толькі пры кампіляцыі з cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Вызначае вобласці гладкага рэльефу лятучых астравоў.\n" +#~ "Гладкая паверхня з'яўляецца, калі шум больш нуля." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Вызначае крок дыскрэтызацыі тэкстуры.\n" +#~ "Больш высокае значэнне прыводзіць да больш гладкіх мапаў нармаляў." + +#~ msgid "Del. Favorite" +#~ msgstr "Прыбраць з упадабанага" + +#~ msgid "" +#~ "Deprecated, define and locate cave liquids using biome definitions " +#~ "instead.\n" +#~ "Y of upper limit of lava in large caves." +#~ msgstr "" +#~ "Састарэлы. Вызначае і размяшчае пячорныя вадкасці з выкарыстаннем " +#~ "азначэнняў біёму.\n" +#~ "Y верхняй мяжы лавы ў вялікіх пячорах." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Спампоўвайце гульні кшталту «Minetest Game», з minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Спампаваць з minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Спампоўванне і ўсталёўка $1. Калі ласка, пачакайце…" + +#~ msgid "Enable VBO" +#~ msgstr "Уключыць VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "Уключыць пацвярджэнне рэгістрацыі" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Уключае рэльефнае тэкстураванне. Мапы нармаляў мусяць быць пакункам " +#~ "тэкстур ці створанымі аўтаматычна.\n" +#~ "Патрабуюцца ўключаныя шэйдэры." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Уключае кінематаграфічнае танальнае адлюстраванне" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Уключае генерацыю мапаў нармаляў лётма (эфект Emboss).\n" +#~ "Патрабуецца рэльефнае тэкстураванне." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Уключае паралакснае аклюзіўнае тэкстураванне.\n" +#~ "Патрабуюцца ўключаныя шэйдэры." + +#~ msgid "Enter " +#~ msgstr "Увод " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Эксперыментальны параметр, які можа прывесці да візуальных прагалаў\n" +#~ "паміж блокамі пры значэнні большым за 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS у меню паўзы" + +#~ msgid "Fallback font shadow" +#~ msgstr "Цень рэзервовага шрыфту" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Празрыстасць цені рэзервовага шрыфту" + +#~ msgid "Fallback font size" +#~ msgstr "Памер рэзервовага шрыфту" + +#~ msgid "Filtering" +#~ msgstr "Фільтрацыя" + +#~ msgid "Floatland base height noise" +#~ msgstr "Шум базавай вышыні лятучых астравоў" + +#~ msgid "Floatland mountain height" +#~ msgstr "Вышыня гор на лятучых астравоў" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Празрыстасць цені шрыфту (ад 0 да 255)." + +#~ msgid "FreeType fonts" +#~ msgstr "Шрыфты FreeType" + +#~ msgid "Full screen BPP" +#~ msgstr "Глыбіня колеру ў поўнаэкранным рэжыме (бітаў на піксель)" + +#~ msgid "Game" +#~ msgstr "Гульня" + +#~ msgid "Gamma" +#~ msgstr "Гама" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Генерацыя мапы нармаляў" + +#~ msgid "Generate normalmaps" +#~ msgstr "Генерацыя мапы нармаляў" + +#~ msgid "HUD scale factor" +#~ msgstr "Каэфіцыент маштабавання HUD" + +#~ msgid "High-precision FPU" +#~ msgstr "Высокадакладны FPU" + +#~ msgid "IPv6 support." +#~ msgstr "Падтрымка IPv6." + +#~ msgid "" +#~ "If enabled together with fly mode, makes move directions relative to the " +#~ "player's pitch." +#~ msgstr "" +#~ "Калі ўключана адначасова з рэжымам палёту, то вызначае напрамак руху " +#~ "адносна кроку гульца." + +#~ msgid "In-Game" +#~ msgstr "У гульні" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Усталёўка: файл: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Інструменты" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Прывязкі клавіш. (Калі меню сапсавана, выдаліце налады з minetest.conf)" + +#~ msgid "Lava depth" +#~ msgstr "Глыбіня лавы" + +#~ msgid "Lightness sharpness" +#~ msgstr "Рэзкасць паваротлівасці" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Абмежаванне чэргаў на дыску" + +#~ msgid "Main" +#~ msgstr "Галоўнае меню" + +#~ msgid "Main menu style" +#~ msgstr "Стыль галоўнага меню" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "Прымушае DirectX працаваць з LuaJIT. Выключыце, калі гэта выклікае " +#~ "праблемы." + +#~ msgid "" +#~ "Map generation attributes specific to Mapgen Carpathian.\n" +#~ "Flags that are not enabled are not modified from the default.\n" +#~ "Flags starting with 'no' are used to explicitly disable them." +#~ msgstr "" +#~ "Атрыбуты генерацыі мапы для генератара мапы \"Карпаты\".\n" +#~ "Нявызначаныя атрыбуты прадвызначана не змяняюцца.\n" +#~ "Атрыбуты, што пачынаюцца з \"no\", выкарыстоўваюцца для іх выключэння." + +#~ msgid "" +#~ "Map generation attributes specific to Mapgen v5.\n" +#~ "Flags that are not enabled are not modified from the default.\n" +#~ "Flags starting with 'no' are used to explicitly disable them." +#~ msgstr "" +#~ "Атрыбуты генерацыі мапы для генератара мапы 5.\n" +#~ "Нявызначаныя атрыбуты прадвызначана не змяняюцца.\n" +#~ "Атрыбуты, што пачынаюцца з 'no' выкарыстоўваюцца для іх выключэння." + +#~ msgid "" +#~ "Map generation attributes specific to Mapgen v7.\n" +#~ "'ridges' enables the rivers.\n" +#~ "Flags that are not enabled are not modified from the default.\n" +#~ "Flags starting with 'no' are used to explicitly disable them." +#~ msgstr "" +#~ "Атрыбуты генерацыі мапы для генератара мапы 7.\n" +#~ "Параметр \"ridges\" (хрыбты) ўключае рэкі.\n" +#~ "Нявызначаныя параметры прадвызначана не змяняюцца.\n" +#~ "Параметры, што пачынаюцца з \"no\", выкарыстоўваюцца для выключэння." + +#~ msgid "Menus" +#~ msgstr "Меню" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Мінімапа ў рэжыме радару, павелічэнне х2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Мінімапа ў рэжыме радару, павелічэнне х4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Мінімапа ў рэжыме паверхні, павелічэнне х2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Мінімапа ў рэжыме паверхні, павелічэнне х4" + +#~ msgid "Name / Password" +#~ msgstr "Імя / Пароль" + +#~ msgid "Name/Password" +#~ msgstr "Імя/Пароль" + +#~ msgid "No" +#~ msgstr "Не" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Дыскрэтызацыя мапы нармаляў" + +#~ msgid "Normalmaps strength" +#~ msgstr "Моц мапы нармаляў" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Колькасць ітэрацый паралакснай аклюзіі." + +#~ msgid "Ok" +#~ msgstr "Добра" + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "Агульны зрух эфекту паралакснай аклюзіі. Звычайна маштаб/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Агульны маштаб эфекту паралакснай аклюзіі." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Паралаксная аклюзія" + +#~ msgid "Parallax occlusion" +#~ msgstr "Паралаксная аклюзія" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Зрух паралакснай аклюзіі" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Ітэрацыі паралакснай аклюзіі" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Рэжым паралакснай аклюзіі" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Маштаб паралакснай аклюзіі" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Інтэнсіўнасць паралакснай аклюзіі" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Шлях да TrueTypeFont ці растравага шрыфту." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Каталог для захоўвання здымкаў экрана." + +#~ msgid "Player name" +#~ msgstr "Імя гульца" + +#~ msgid "Profiling" +#~ msgstr "Прафіляванне" + +#~ msgid "Projecting dungeons" +#~ msgstr "Праектаванне падзямелляў" + +#~ msgid "PvP enabled" +#~ msgstr "PvP уключаны" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Скінуць свет адзіночнай гульні" + +#~ msgid "Select Package File:" +#~ msgstr "Абраць файл пакунка:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Сервер / Адзіночная гульня" + +#~ msgid "Shadow limit" +#~ msgstr "Ліміт ценяў" + +#, fuzzy +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "Зрух цені шрыфту. Калі 0, то цень не будзе паказвацца." + +#~ msgid "Special" +#~ msgstr "Адмысловая" + +#~ msgid "Special key" +#~ msgstr "Адмысловая клавіша" + +#~ msgid "Start Singleplayer" +#~ msgstr "Пачаць адзіночную гульню" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Моц згенераваных мапаў нармаляў." + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "Моц сярэдняга ўздыму крывой святла." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Гэты шрыфт будзе выкарыстоўваецца для некаторых моў." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Для ўключэння шэйдэраў неабходна выкарыстоўваць OpenGL." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Кінематаграфічнасць" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Тыповая максімальная вышыня, вышэй і ніжэй сярэдняй кропкі гор лятучых " +#~ "астравоў." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Варыяцыя вышыні пагоркаў і глыбінь азёр на гладкай мясцовасці лятучых " +#~ "астравоў." + +#~ msgid "Waving Water" +#~ msgstr "Хваляванне вады" + +#~ msgid "Waving water" +#~ msgstr "Хваляванне вады" + +#, fuzzy +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Выкарыстанне шрыфтоў FreeType. Падтрымка FreeType мусіць быць уключаная " +#~ "падчас кампіляцыі." + +#~ msgid "Whether dungeons occasionally project from the terrain." +#~ msgstr "Выступ падзямелляў па-над рэльефам." + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Y верхняга ліміту лавы ў шырокіх пячорах." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "Y-узровень сярэдняй кропкі і паверхні азёр лятучых астравоў." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Y-узровень, да якога распаўсюджваюцца цені лятучых астравоў." + +#~ msgid "Yes" +#~ msgstr "Так" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Вы хочаце першы раз увайсці на сервер з назвай «%s».\n" +#~ "Калі вы працягнеце, то на серверы будзе створаны новы конт з вашамі " +#~ "данымі.\n" +#~ "Калі ласка, ўвядзіце пароль яшчэ раз і націсніце «Зарэгістравацца і " +#~ "далучыцца», каб пацвердзіць стварэнне конта альбо \"Скасаваць\", каб " +#~ "адмовіцца." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Вы загінулі" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/bg/minetest.po b/po/bg/minetest.po new file mode 100644 index 0000000..ce95a88 --- /dev/null +++ b/po/bg/minetest.po @@ -0,0 +1,6986 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-04-11 15:08+0000\n" +"Last-Translator: 109247019824 <stoyan@gmx.com>\n" +"Language-Team: Bulgarian <https://hosted.weblate.org/projects/minetest/" +"minetest/bg/>\n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.12-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Изчистване на изходящата опашка на разговорите" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Празна команда." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Главно меню" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Недействителна команда: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Подадена команда: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Играчи на линия" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Играчи на линия: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Изходящата опашка на разговори е изпразнена." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Командата е забранена от сървъра." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Прераждане" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Умряхте" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Достъпни команди:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Достъпни команди: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Недостъпни команди: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Помощ за командите" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Въведете „.help <cmd>“ за повече информация или „.help all“ за списък с " +"всички команди." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <команда>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Добре" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<няма достъпни>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Грешка в скрипт на Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Възникна грешка:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Главно меню" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Повторно свързване" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Сървърът поиска повторно свързване:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Модификации" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Изданието на протокола не съвпада. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Сървърът налага издание $1 на протокола. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Сървърът поддържа изданията на протокола между $1 и $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Поддържаме само издание $1 на протокола." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Поддържаме само изданията на протокола между $1 и $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Отказ" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Зависимости:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Изключване всички" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Изкл. на пакета" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Включване всички" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Вкл. на пакета" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Включването на модификацията „$1“ не е успешно, защото съдържа забранени " +"символи. Разрешени са само символите [a-z0-9_]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Още модификации" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Модификация:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Няма (незадължителни) зависимости" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Играта няма описание." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Няма задължителни зависимости" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Пакетът с модификации няма описание." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Няма незадължителни зависимости" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Незадължителни зависимости:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Запазване" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Свят:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "включен" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "„$1“ вече съществува. Да бъде ли презаписан?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$1 и $2 зависимости ще бъдат инсталирани." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 от $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 се изтеглят,\n" +"$2 изчакват" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 се изтеглят…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 задължителни зависимости не могат да бъдат намерени." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 ще бъдат инсталирани, а $2 зависимости ще бъдат пропуснати." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Всички пакети" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Вече инсталирано" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Главно меню" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Основна игра:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" +"Съдържанието от ContentDB не е налично, когато Minetest е компилиран без cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Изтегляне…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Грешка при изтеглянето на $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Игри" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Инсталиране" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Инсталиране $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Инсталиране на липсващи зависимости" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Инсталиране: Неподдържан вид на файл или повреден архив" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Модификации" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Пакетите не могат да бъдат получени" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Няма резултати" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Няма обновяване" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Не е намерено" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Презаписване" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Уверете се, че основната игра е правилна." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Изчакващи" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Пакети с текстури" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Премахване" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Обновяване" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Обновяване всички [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Вижте повече в браузъра" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Свят с името „$1“ вече съществува" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Допълнителен терен" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Застудяване във височина" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Засушаване във височина" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Смесване на биоми" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Биоми" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Големи пещери" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Пещери" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Създаване" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Декорации" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Внимание: Тестът за разработка е предназначен за разработчици." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Тъмници" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Равен терен" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Плаващи земни маси в небето" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Небесни острови (експериментално)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Създаване на нефрактален терен: Морета и подземен свят" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Хълмове" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Влажни реки" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Увеличава влажността около реките" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Инсталиране $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Езера" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Ниската влажност и горещините причиняват плитки или пресъхнали реки" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Генератор на карти" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Настройки на генератора" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Специфични за генератора настройки" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Планини" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Кален поток" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Мрежа от тунели и пещери" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Няма избрана игра" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Намалява топлината във височина" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Намалява влажността във височина" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Реки" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Реки на морското ниво" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Семе" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Плавен преход между биомите" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Структури, появяващи се върху терена (няма ефект върху дърветата и тревата в " +"джунглата, създадени от v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Структури, появяващи се върху терена, обикновено дървета и растения" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Умерен климат, пустиня" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Умерен климат, пустиня, джунгла" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Умерен климат, пустиня, джунгла, тундра, тайга" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Ерозия на земната повърхност" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Трева в джунглата и дървета" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Промяна в дълбочината на реките" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Много големи пещери дълбоко под земята" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Име на света" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Няма инсталирани игри." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Сигурни ли сте, че искате да премахнете „$1“?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Премахване" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: грешка при премахване на „$1“" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: недействителен път „$1“" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Премахване на света „$1“?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Потвърж. на парола" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Име" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Парола" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Паролите не съвпадат!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Регистриране и вход" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Приемане" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Преименуване на пакет модификации:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Този пакет с модификации има изрично зададено име в modpack.conf, което ще " +"отмени всяко преименуване." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Настройката няма описание)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Двуизмерен шум" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "Главно меню" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Разглеждане" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Съдържание" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Съдържание" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Изключено" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Редактиране" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Включено" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Лакунарност" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Октави" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Отместване" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Устойчивост" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Въведете цяло число." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Въведете число." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "По подразбиране" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Мащаб" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Търсене" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Избор на папка" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Избор на файл" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Технически наименования" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Стойността трябва да е най-малко $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Стойността трябва да е най-много $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Разпределение по X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Разпределение по Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Разпределение по Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "абсолютна стойност" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "подразбирани" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (включено)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 модификации" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Грешка при инсталиране на $1 в $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Зареждане…" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Списъкът с обществени сървъри е изключен" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Включете списъка на обществени сървъри и проверете връзката с интернет." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Относно" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Активни сътрудници" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Активен визуализатор:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Основни разработчици" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Папка с данни" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Отваря папката, съдържаща предоставените от потребителя\n" +"светове, игри, модификации и текстури." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Предишни сътрудници" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Предишни основни разработчици" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Преглед на съдържание онлайн" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Съдържание" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Изкл. на пакет с текстури" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Описание:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Инсталирани пакети:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Няма зависимости." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Пакетът е без описание" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Преименуване" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Премахване на пакет" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Вкл. на пакет с текстури" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Обявяване на сървъра" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Адрес за свързване" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Творчески режим" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Получаване на щети" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Създаване на игра" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Създаване на сървър" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Инсталиране на игри от ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Създаване" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Не е създаден или избран свят!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Започване на игра" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Порт" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Модификации" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Избор на свят:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Порт на сървъра" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Създаване на игра" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Адрес" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Изчистване" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Творчески режим" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Щети / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Любими" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Несъвместими сървъри" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Включване към игра" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Обществени сървъри" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Презареждане" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Отдалечен порт" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Описание на сървър" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Тримерни облаци" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Всички настройки" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Сгласяне:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Авт. запазване на размера" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Промяна на клавиши" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Свързано стъкло" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Динамични сенки" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Динамични сенки: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Луксозни листа" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Силни" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Слаби" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Нормални" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Mipmap" +msgstr "Миникарта" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Mipmap + Aniso. Filter" +msgstr "Миникарта + анизо. филтър" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Без филтър" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "No Mipmap" +msgstr "Без миникарта" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Осветяване на възел" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Ограждане на възел" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Без" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Непрозрачни листа" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Непрозрачна вода" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Отломки" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Екран:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Настройки" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "Земни маси в небето (експериментално)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Обикновени листа" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Гладко осветление" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Текстуриране:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Праг на докосване: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Много силни" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Много слаби" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Поклащащи се листа" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Поклащащи се течности" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Поклащащи се растения" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Грешка при свързване (изтекло време?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Времето за свързване изтече." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Готово!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Иницииране на възли" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Иницииране на възли…" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Зареждане на текстури…" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Грешка при свързване (изтекло време?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Играта не може да бъде намерена или заредена: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Главно меню" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Няма избран свят, нито зададен адрес. Няма какво да бъде направено." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Името на играча е твърде дълго." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Изберете име!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Файлът с пароли не се отваря: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Зададеният път към света не съществува: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Прегледайте debug.txt за повече информация." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Адрес: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Режим: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Порт: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Обществен: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Име на сървър: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Възникна грешка:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Достъпът е отказан. Причина: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Автоматичното движение напред е изключено" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Автоматичното движение напред е включено" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Контурите на блоковете са скрити" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Контурите на всички блокове са видими" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Контурите на текущия блок са видими" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Контурите на близките блокове са видими" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Опресняването на екрана при движение е изключено" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Опресняването на екрана при движение е включено" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" +"Контурите на блоковете не могат да бъдат показани (заб.: липсва правото " +"„basic_debug“)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Промяна на парола" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Кинематографичният режим е изключен" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Кинематографичният режим е включен" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Клиентът е изключен" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Изпълняване на скриптове от страната на клиента е изключено" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Свързване със сървър…" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Грешка във връзката поради неизвестна причина" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Продължаване" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Управление:\n" +"- %s: движение напред\n" +"- %s: движение назад\n" +"- %s: движение наляво\n" +"- %s: движение надясно\n" +"- %s: скачане/катерене\n" +"- %s: копаене/удар\n" +"- %s: поставяне/използване\n" +"- %s: промъкване/слизане\n" +"- %s: пускане на предмет\n" +"- %s: инвентар\n" +"- мишка: завъртане/разглеждане\n" +"- колелце на мишка: избор на предмет\n" +"- %s: разговор\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Създаване на клиент…" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Създаване на сървър…" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Неограниченият обхват на видимост е изключен" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Неограниченият обхват на видимост е включен" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Създаване на клиент…" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Изход към менюто" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Изход към ОС" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Режимът на бързо движение е изключен" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Режимът на бързо движение е включен" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Режимът на бързо движение е включен (заб.: липсва правото „fast“)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Режимът на летене е изключен" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Режимът на летене е включен" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Режимът на летене е включен (заб.: липсва правото „fly“)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Мъглата е изключена" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Мъглата е включена" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Информация за играта:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Играта е на пауза" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Домакин на играта" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Дефиниции на предмети…" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Медия…" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Картата е спряна или от играта, или от модификация" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Множество играчи" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Режимът „без изрязване“ е изключен" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Режимът „без изрязване“ е включен" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Режимът „без изрязване“ е включен (заб.: липсва правото „noclip“)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Дефиниции на възли…" + +#: src/client/game.cpp +msgid "Off" +msgstr "Изключено" + +#: src/client/game.cpp +msgid "On" +msgstr "Включено" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Режимът „промяна на височината“ е изключен" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Режимът „промяна на височината“ е включен" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Графиката на профилатора е показана" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Отдалечен сървър" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Намиране на адрес…" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Изключване…" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Един играч" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Сила на звука" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Звукът е заглушен" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Системата за звук е изключена" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "В това издание не се поддържа звукова система" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Звукът е пуснат" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Сървърът вероятно използва друго издание на %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Обхватът на видимостта е променен на %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Обхватът на видимостта е на своя максимум: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Обхватът на видимостта е на своя минимум: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Силата на звука е променена на %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Показани са телените рамки" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Мащабирането е спряно или от играта, или от модификация" + +#: src/client/game.cpp +msgid "ok" +msgstr "добре" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Разговорите са скрити" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Разговорите са видими" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD скрит" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD видим" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Профилаторът е скрит" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Профилаторът е видим (страница %d от %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Приложения" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Надолу" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Наляво" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Ляв бутон" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Ляв Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Ляв Menu" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Ляв Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Ляв Windows" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Среден бутон" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Дясно" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Десен бутон" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Десен Control" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Десен Menu" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Десен Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Десен Windows" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Sleep" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Снимка на екрана" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Интервал" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Табулатор" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Нагоре" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Мащабиране" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Картата е скрита" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Картата е в режим на радар, мащаб x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Картата е в режим на повърхност, мащаб x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Картата е в режим на текстура" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Грешка при отваряне на страница" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Отваряне на страница" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Напред" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "„Aux1“ = слизане" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Автоматично напред" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Автоматично скачане" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Назад" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Граници на блокове" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Промяна на камера" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Разговори" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Команда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Конзола" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Намал. на обхвата" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Намал. на звука" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Двоен „скок“ превключва летене" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Пускане предмет" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Напред" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Увелич. на обхвата" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Увелич. на звука" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Инвентар" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Скок" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Клавишът вече се ползва" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Местна команда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Заглушаване" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "След. предмет" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Пред. предмет" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Обхват видимост" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Снимка на екрана" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Промъкване" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Превкл. HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Превкл. разговори" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Превкл. бързина" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Превкл. полет" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Превкл. мъгла" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Превкл. карта" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Превкл. изрязване" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Превкл. „pitchmove“" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "избор бутон" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Променяне" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Нова парола" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Стара парола" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Паролите не съвпадат!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Изход" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Без звук" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Сила на звука: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "bg" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Изберете име!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Добавят се отломки при копане на възел." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Име на света" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Автоматично прескача препятствия от единични възли." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Автоматично докладване в списъка на сървърите." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Автоматично запазване на размера на екрана" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Основни права" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Адрес за свързване" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Промяна на камера" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Команда" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Разговорите са видими" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Свързва стъкло, ако се поддържа от възела." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Прозрачност на конзолата" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Цвят на конзолата" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Височина на конзолата" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Управлява дължината на цикъла ден/нощ.\n" +"Пример:\n" +"72 = 20 мин, 360 = 4 мин, 1 = 24 часа, 0 = ден/нощ/каквото е остава без " +"промяна." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Творчески" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Подразбирани права" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Формат на отчета по подразбиране" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Декорации" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Отломки при копане" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Задаване на творчески режим на всички играчи" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Бърздо движение чрез клавиш „Aux1“.\n" +"Изисква правото „fast“ от сървъра." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Сгласяне:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Игри" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "HUD видим" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Ако е включено заедно с режима на летене, играчът може да лети през плътни " +"възли.\n" +"Изисква правото „noclip“ от сървъра." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Голяма част от пещерите са наводнени" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Гладко осветление" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Осветяване на възел" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Играчът може да лети без да се влияе от гравитацията.\n" +"Изисква правото „fly“ от сървъра." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Правата, които играчите с „basic_privs“ могат да получат" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Съотношението на големи пещери, съдържащи течности." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Отдалечен порт" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Екран:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Снимка на екрана" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Създаване на сървър" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "- Име на сървър: " + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Описание на сървър" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Адрес на сървър" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Порт на сървъра" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Порт на сървъра" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Настройки" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Правата, които получават новите играчи.\n" +"В играта вижте „/privs“ за пълен списък от права за сървъра и модификациите." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Творчески режим: " + +#~ msgid "- Damage: " +#~ msgstr "- Щети: " + +#~ msgid "Connect" +#~ msgstr "Свързване" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Управлява скоростта на потъване в течности." + +#~ msgid "Del. Favorite" +#~ msgstr "Премах. любим" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Изтегляне на игра, например Minetest Game, от minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Изтеглете от minetest.net" + +#~ msgid "Enter " +#~ msgstr "Въведете " + +#~ msgid "Game" +#~ msgstr "Игра" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Инсталиране: файл: „$1“" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Клавишни комбинации (Ако екранът изглежда счупен махнете нещата от " +#~ "minetest.conf)" + +#~ msgid "Player name" +#~ msgstr "Име на играча" + +#~ msgid "View" +#~ msgstr "Гледане" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "На път сте да влезете в сървъра с име „%s“ за първи път.\n" +#~ "Ако продължите нова сметка с тези данни ще бъде създадена на сървъра.\n" +#~ "Въведете паролата отново и натиснете „Регистриране и вход“, за да " +#~ "потвърдите или „Отказ“ за връщане обратно." + +#~ msgid "You died." +#~ msgstr "Умряхте." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/ca/minetest.po b/po/ca/minetest.po new file mode 100644 index 0000000..e58bc7f --- /dev/null +++ b/po/ca/minetest.po @@ -0,0 +1,7564 @@ +msgid "" +msgstr "" +"Project-Id-Version: Catalan (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: Catalan <https://hosted.weblate.org/projects/minetest/" +"minetest/ca/>\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.9-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Empty command." +msgstr "Comands de xat" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Eixir al menú" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Invalid command: " +msgstr "Comands de xat" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "Un jugador" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "Un jugador" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Reaparèixer" + +#: builtin/client/death_formspec.lua src/client/game.cpp +#, fuzzy +msgid "You died" +msgstr "Has mort." + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "Comands de xat" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "Comands de xat" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "An error occurred in a Lua script:" +msgstr "S'ha produït un error en un script Lua, com per exemple un mod." + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "An error occurred:" +msgstr "Ha ocorregut un error:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menú principal" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Torneu a connectar" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "El servidor ha sol·licitat una reconnexió:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Seleccionar un món:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Desajust de la versió del protocol. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "El servidor fa complir la versió $1 del protocol. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "" +"El servidor es compatible amb les versions de protocol entre $ 1 i $ 2 . " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Nosaltres sols suportem la versió $1 del protocol." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Nosaltres suportem versions del protocol entre la versió $1 i la $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Cancel·lar" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Dependències:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Desactivar tot" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "Disable modpack" +msgstr "Desactivat" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Activar tot" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "Enable modpack" +msgstr "Reanomenar el paquet de mods:" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Error al habilitar el mod \"$1\" perquè conté caràcters no permesos. Només " +"estan permesos els caràcters [a-z0-9_]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No (optional) dependencies" +msgstr "Dependències opcionals:" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No game description provided." +msgstr "Cap descripció del mod disponible" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No hard dependencies" +msgstr "Sense dependències." + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No modpack description provided." +msgstr "Cap descripció del mod disponible" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No optional dependencies" +msgstr "Dependències opcionals:" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Dependències opcionals:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Guardar" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Món:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "Activat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "Carregant ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Already installed" +msgstr "La tecla s'està utilitzant" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Back to Main Menu" +msgstr "Menú principal" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "Ocultar Joc" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Downloading..." +msgstr "Carregant ..." + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Failed to download $1" +msgstr "Error al instal·lar $1 en $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Jocs" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instal·lar" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "Instal·lar" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "Dependències opcionals:" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "" +"\n" +"Instal·lar mod: Format de arxiu \"$1\" no suportat o arxiu corrupte" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mods" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Texture packs" +msgstr "Textures" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Uninstall" +msgstr "Instal·lar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Ja existeix un món anomenat \"$1\"" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Altitude chill" +msgstr "Fred d'altitud" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Altitude dry" +msgstr "Fred d'altitud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caverns" +msgstr "Soroll de cova #1" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caves" +msgstr "Soroll de cova #1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Crear" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Decorations" +msgstr "Informació del mod:" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "" +"Advertència: El joc \"Minimal development test\" esta dissenyat per a " +"desenvolupadors." + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Dungeons" +msgstr "Soroll de cova #1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Instal·lar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Generador de mapes" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mapgen-specific flags" +msgstr "Generador de mapes" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "No game selected" +msgstr "Seleccionar distancia" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Rivers" +msgstr "Soroll de cova #1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Llavor" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nom del món" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "You have no games installed." +msgstr "No tens subjocs instal·lats." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Realment desitja esborrar \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Esborrar" + +#: builtin/mainmenu/dlg_delete_content.lua +#, fuzzy +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "Modmgr: Error al esborrar \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +#, fuzzy +msgid "pkgmgr: invalid path \"$1\"" +msgstr "Modmgr: Ruta del mod \"$1\" invàlida" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Eliminar el món \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Confirma contrasenya" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "Nova contrasenya" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Les contrasenyes no coincideixen!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Acceptar" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Reanomenar el paquet de mods:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Cap descripció d'ajustament donada)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "2D Noise" +msgstr "Soroll de cova #1" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Torna a la pàgina de configuració" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Navegar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Continuar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Continuar" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Desactivat" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Editar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Activat" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Si us plau, introduïu un enter vàlid." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Si us plau, introduïu un nombre vàlid." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Restablir per defecte" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Buscar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Select directory" +msgstr "Selecciona el fitxer del mod:" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Select file" +msgstr "Selecciona el fitxer del mod:" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Mostrar els noms tècnics" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "El valor ha de ser major que $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "El valor ha de ser menor que $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "defaults" +msgstr "Joc per defecte" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "$1 (Enabled)" +msgstr "Activat" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "$1 mods" +msgstr "Mode 3D" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Error al instal·lar $1 en $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Instal·lar mod: Impossible trobar el nom real del mod per a: $1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Instal·lar mod: Impossible de trobar el nom de la carpeta adequat per al " +"paquet de mods $1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to find a valid mod or modpack" +msgstr "" +"Instal·lar mod: Impossible de trobar el nom de la carpeta adequat per al " +"paquet de mods $1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a $1 as a texture pack" +msgstr "Error al instal·lar $1 en $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a game as a $1" +msgstr "Error al instal·lar $1 en $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a mod as a $1" +msgstr "Error al instal·lar $1 en $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a modpack as a $1" +msgstr "Error al instal·lar $1 en $2" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Carregant ..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Intenta tornar a habilitar la llista de servidors públics i comprovi la seva " +"connexió a Internet ." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Col·laboradors Actius" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Active renderer:" +msgstr "Rang d'enviament de l'objecte actiu" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Desenvolupadors del nucli" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Selecciona el fitxer del mod:" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Antics Col·laboradors" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Antics Desenvolupadors del nucli" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Content" +msgstr "Continuar" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Disable Texture Pack" +msgstr "Selecciona un paquet de textures:" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Information:" +msgstr "Informació del mod:" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Installed Packages:" +msgstr "Mods Instal·lats:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Sense dependències." + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "No package description available" +msgstr "Cap descripció del mod disponible" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Reanomenar" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Uninstall Package" +msgstr "Desinstal·lar el mod seleccionat" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Use Texture Pack" +msgstr "Textures" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Anunciar servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Adreça BIND" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Mode Creatiu" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Permetre Danys" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Host Game" +msgstr "Ocultar Joc" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Host Server" +msgstr "Servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Nou" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "No s'ha creat ningun món o no s'ha seleccionat!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Jugar Joc" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "Seleccionar un món:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Seleccionar un món:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Port del Servidor" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Start Game" +msgstr "Ocultar Joc" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "Adreça BIND" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Netejar" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Mode creatiu" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "Dany" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "Preferit" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Join Game" +msgstr "Ocultar Joc" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "Anunciar servidor" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Esborra preferit" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "Port del Servidor" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Núvols 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "All Settings" +msgstr "Configuració" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Suavitzat (Antialiasing):" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Autosave Screen Size" +msgstr "Desar automàticament mesures de la pantalla" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Filtre Bilineal" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Configurar Controls" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Vidres connectats" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Fulles Boniques" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Aniso. Filtre" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Sense Filtre" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Sense MipMap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Node ressaltat" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Nodes ressaltats" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Ningun" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Fulles opaques" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Aigua opaca" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partícules" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Pantalla:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Configuració" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Ombres" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Fulles senzilles" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Il·luminació suau" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Texturització:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Llindar tàctil (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Filtratge Trilineal" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Moviment de les Fulles" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Liquids" +msgstr "Moviment de les Fulles" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Moviment de Plantes" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Error de connexió (¿temps esgotat?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Temps d'espera de la connexió esgotat." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Completat!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inicialitzant nodes" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Inicialitzant nodes ..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Carregant textures ..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Reconstruint ombreig ..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Error de connexió (¿temps esgotat?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "No es pot trobar o carregar el joc \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "El Joc especificat no és vàlid." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menú principal" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Cap món seleccionat i cap adreça facilitada. Res a fer." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Nom del jugador massa llarg." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "La ruta del món especificat no existeix: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Comprovi debug.txt per a detalls." + +#: src/client/game.cpp +#, fuzzy +msgid "- Address: " +msgstr "Adreça BIND" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "- Port: " +msgstr "Port" + +#: src/client/game.cpp +#, fuzzy +msgid "- Public: " +msgstr "Públic" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Ha ocorregut un error:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward disabled" +msgstr "Tecla Avançar" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward enabled" +msgstr "Tecla Avançar" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Camera update disabled" +msgstr "Tecla alternativa per a l'actualització de la càmera" + +#: src/client/game.cpp +#, fuzzy +msgid "Camera update enabled" +msgstr "Tecla alternativa per a l'actualització de la càmera" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Canviar contrasenya" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode disabled" +msgstr "Tecla mode cinematogràfic" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode enabled" +msgstr "Tecla mode cinematogràfic" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "Client" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Connectant al servidor ..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Continuar" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Controls predeterminats:\n" +"- WASD: moure\n" +"- Espai: botar / pujar\n" +"- Maj .: puntetes / baixar\n" +"- Q: deixar anar objecte\n" +"- I: inventari\n" +"- Ratolí: girar / mirar\n" +"- Ratolí esq .: excavar / colpejar\n" +"- Ratolí dre .: col·locar / utilitzar\n" +"- Roda ratolí: triar objecte\n" +"- T: xat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Creant client ..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Creant servidor ..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Debug info shown" +msgstr "Tecla alternativa per a la informació de la depuració" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Controls predeterminats:\n" +"Amb el menú ocult:\n" +"- Toc simple: botó activar\n" +"- Toc doble: posar / utilitzar\n" +"- Lliscar dit: mirar al voltant\n" +"Amb el menú / inventari visible:\n" +"- Toc doble (fora):\n" +" -> tancar\n" +"- Toc a la pila d'objectes:\n" +" -> moure la pila\n" +"- Toc i arrossegar, toc amb 2 dits:\n" +" -> col·locar només un objecte\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Creant client ..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Eixir al menú" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Eixir al S.O" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fast mode enabled" +msgstr "Dany activat" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode enabled" +msgstr "Dany activat" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog disabled" +msgstr "Desactivat" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog enabled" +msgstr "Activat" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Game paused" +msgstr "Jocs" + +#: src/client/game.cpp +#, fuzzy +msgid "Hosting server" +msgstr "Creant servidor ..." + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Definicions d'objectes ..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Media ..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "Un jugador" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Noclip mode enabled" +msgstr "Dany activat" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Definicions dels nodes ..." + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Remote server" +msgstr "Anunciar servidor" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Resolent adreça ..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Tancant ..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Un jugador" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Volum del so" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound muted" +msgstr "Volum del so" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound unmuted" +msgstr "Volum del so" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "Acceptar" + +#: src/client/gameui.cpp +#, fuzzy +msgid "Chat hidden" +msgstr "Tecla del xat" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplicacions" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Backspace" +msgstr "Enrere" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Avall" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Fi" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Erase EOF" +msgstr "Esborrar OEF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Executar" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Ajuda" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Inici" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Accept" +msgstr "Acceptar" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Convert" +msgstr "Convertir" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Escape" +msgstr "Esc" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Mode Change" +msgstr "Canvi de mode" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Nonconvert" +msgstr "No convertir" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Introduir" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Esquerra" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Botó esquerre" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Control esq" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menú esq" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Shift esq" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Windows esquerre" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menú" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Botó del mig" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Bloq Num" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Teclat Num. *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Teclat Num. +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Teclat Num. -" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad ." +msgstr "Teclat Num. *" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Teclat Num. /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Teclat Num. 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Teclat Num. 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Teclat Num. 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Teclat Num. 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Teclat Num. 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Teclat Num. 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Teclat Num. 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Teclat Num. 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Teclat Num. 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Teclat Num. 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Netejar OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pausa" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Jugar" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Imprimir" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Tornar" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Dreta" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Botó dret" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Control dta" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menú dta" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Shift Dta" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Windows dret" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Bloq Despl" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Seleccionar" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Dormir" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Captura de pantalla" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Espai" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabulador" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Amunt" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Botó 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Botó 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Error al instal·lar $1 en $2" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Continuar" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "\"Utilitzar\" = Descendir" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Autoforward" +msgstr "Avant" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Arrere" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Change camera" +msgstr "Configurar controls" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Xat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Comandament" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Consola" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Dos tocs \"botar\" per volar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Amollar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Avant" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Inc. volume" +msgstr "Volum del so" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventari" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Botar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "La tecla s'està utilitzant" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Local command" +msgstr "Comands de xat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Next item" +msgstr "Següent" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Seleccionar distancia" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Discreció" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle HUD" +msgstr "Activar volar" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle chat log" +msgstr "Activar ràpid" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Activar ràpid" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Activar volar" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle fog" +msgstr "Activar volar" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle minimap" +msgstr "Activar noclip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Activar noclip" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle pitchmove" +msgstr "Activar ràpid" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "Premsa una tecla" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Canviar" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nova contrasenya" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Contrasenya vella" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Les contrasenyes no coincideixen!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Tancar" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy +msgid "Muted" +msgstr "Utilitza la tecla" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Volum de so: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "ca" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X, Y, Z) compensar de fractal del món centre en unitats d \"escala\".\n" +"Solia passar un adequat respawn de terra baixa a prop de (0, 0).\n" +"L'omissió és adequat per als conjunts de mandelbrot, que necessita ser " +"editats per julia estableix.\n" +"Gamma aproximadament -2 a 2. Multiplicar per el \"escala\" per a òfset de " +"nodes." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Núvols 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Mode 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Suport 3D.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- pageflip: quadbuffer based 3d." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Elegeix una llavor per al nou mapa, deixa buit per a una llavor a l'atzar.\n" +"Serà anul·lat si es crea un nou món al menú principal." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" +"Un missatge que es mostrarà a tots els clients quan el servidor s'estavella." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Un missatge que es mostrarà a tots els clients quan el servidor s'apaga." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Absolute limit of queued blocks to emerge" +msgstr "Límit absolut de cues emergents" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Acceleració en l'aire" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Active Block Modifiers" +msgstr "Rang del bloc actiu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Active block management interval" +msgstr "Rang del bloc actiu" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Rang del bloc actiu" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Rang d'enviament de l'objecte actiu" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Adreça a connectar-se.\n" +"Deixar aquest espai en buit per començar un servidor local.\n" +"Tingueu en compte que el camp d'adreça en el menú principal invalida aquest " +"paràmetre." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Ajustar la configuració de punts per polsada (dpi) a la teva pantalla (no " +"X11/Sols Android) Ex. per a pantalles amb 4K." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Nom del món" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avançat" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Sempre volar y ràpid" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Gamma d'oclusió d'ambient" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Amplifies the valleys." +msgstr "Amplifica les valls" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Filtrat anisotròpic" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Anunciar servidor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Announce to this serverlist." +msgstr "Anunciar servidor" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Preguntar per tornar a connectar després d'una caiguda" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatic forward key" +msgstr "Tecla Avançar" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatically report to the serverlist." +msgstr "Automàticament informar a la llista del servidor." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Desar automàticament mesures de la pantalla" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "Tecla botar" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key for climbing/descending" +msgstr "Utilitzar la tecla \"utilitzar\" per escalar/descendir" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tecla de retrocés" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Base terrain height." +msgstr "Alçada del terreny base" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Basic privileges" +msgstr "Privilegis per defecte" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Filtre bilineal" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Adreça BIND" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Construir dins el jugador" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Configurar controls" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Suavitzat de la càmera" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Suavitzat de la càmera en mode cinematogràfic" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Tecla alternativa per a l'actualització de la càmera" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Soroll de cova #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Amplada de les coves" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave1 noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave2 noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern limit" +msgstr "Amplada de les coves" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern upper limit" +msgstr "Amplada de les coves" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Comands de xat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat font size" +msgstr "Mida del chunk" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Tecla del xat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat log level" +msgstr "Nivell de registre de depuració" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat message format" +msgstr "Missatge d'error" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Tecla alternativa per al xat" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Mida del chunk" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Mode cinematogràfic" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tecla mode cinematogràfic" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Netejar textures transparents" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Client" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Client i Servidor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client modding" +msgstr "Client" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client side modding restrictions" +msgstr "Client" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Client" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Velocitat d'escalada" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Radi del núvol" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Núvols" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Els núvols són un efecte de costat del client." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Núvols en el menú" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Boira de color" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Colored shadows" +msgstr "Boira de color" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Llista de mods separada per comes que tenen permís per accedir a les APIs " +"HTTP,\n" +"les quals els permeten pujar/descarregar informació de/cap a internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Llista de mods de fiar separada per comes que tenen permís per accedir a " +"funcions\n" +"insegures fins i tot quan \"mod security\" està activat (via " +"request_insecure_environment ())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Tecla comandament" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Connectar vidre" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Connectar a servidor de mitjans externs" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Connecta vidre si el node ho admet." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Console alpha" +msgstr "Consola Alpha" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Color de la consola" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Console height" +msgstr "Tecla de la consola" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ContentDB URL" +msgstr "Continuar" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Avanç continu" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Controls" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Controla la duració del cicle dia/nit.\n" +"Exemples: 72 = 20min, 360 = 4min, 1 = 24hora, 0 = dia/nit/el que sigui es " +"queda inalterat." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Controla el pendent o la profunditat de les depressions de llac." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Controla la pendent i alçada dels turons." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Missatge d'error" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Creative" +msgstr "Crear" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Punt de mira Alpha" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Color del punt de mira" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI (punts per polsada)" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Dany" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Tecla alternativa per a la informació de la depuració" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Debug log file size threshold" +msgstr "Nivell de registre de depuració" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Nivell de registre de depuració" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Pas de servidor dedicat" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Acceleració per defecte" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Joc per defecte" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Joc per defecte en crear un nou món.\n" +"Aço será invalid quan es cree un món des del menú principal." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Contrasenya per defecte" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Privilegis per defecte" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default stack size" +msgstr "Joc per defecte" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Retràs per enviar blocs després de col•locarlos" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Depth below which you'll find giant caverns." +msgstr "Profunditat davall la qual trobaràs grans coves." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Profunditat davall la qual trobaràs grans coves." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Informació del mod:" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "Tecla dreta" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Digging particles" +msgstr "Partícules" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Polsar dues vegades \"botar\" per volar" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Polsar dues vegades \"botar\" per alternar el mode de vol." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dungeon noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Habilitar l'entrada aleatòria d'usuari (només utilitzat per testing)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Moviment ràpid" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Moviment ràpid (via utilitzar clau).\n" +"Això requereix el \"privilegi\" ràpid en el servidor." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Suavitzat (Antialiasing):" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Tecla Avançar" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Jocs" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ground noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HTTP mods" +msgstr "Mods HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Heat noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Height noise" +msgstr "Windows dret" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness1 noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness2 noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness3 noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness4 noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Inc. volume key" +msgstr "Tecla de la consola" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Tecla Inventari" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Invertir ratolí" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Invertir moviment vertical del ratolí." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick button repetition interval" +msgstr "Interval de repetició del click dret" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick frustum sensitivity" +msgstr "Sensibilitat del ratolí" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Tecla botar" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per disminuir el rang de visió.\n" +"Mira\n" +"http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per disminuir el rang de visió.\n" +"Mira\n" +"http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per botar.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per incrementar el rang de visió.\n" +"Mira\n" +"http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per incrementar el rang de visió.\n" +"Mira\n" +"http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per botar.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per moure el jugador cap arrere.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per moure avant al jugador.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per moure el jugador cap a l'esquerra.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per moure el jugador cap a la dreta.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per botar.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per botar.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per obrir el inventari.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per botar.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per botar.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per moure el jugador cap a l'esquerra.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per moure el jugador cap a la dreta.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per moure el jugador cap a l'esquerra.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per moure el jugador cap a la dreta.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla per botar.\n" +"Veure http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Large chat console key" +msgstr "Tecla de la consola" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Tecla esquerra" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Il·luminació suau" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Loading Block Modifiers" +msgstr "Rang del bloc actiu" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lower Y limit of floatlands." +msgstr "Límit absolut de cues emergents" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian" +msgstr "Generador de mapes plans" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat" +msgstr "Generador de mapes plans" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal" +msgstr "Generador de mapes plans" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "Generador de mapes" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5" +msgstr "Generador de mapes" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6" +msgstr "Generador de mapes" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7" +msgstr "Generador de mapes" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Valleys" +msgstr "Generador de mapes" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Valleys specific flags" +msgstr "Generador de mapes" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Sensibilitat del ratolí" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Multiplicador de sensibilitat del ratolí." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mute key" +msgstr "Utilitza la tecla" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Node ressaltat" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move key" +msgstr "Tecla mode cinematogràfic" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Tecla mode cinematogràfic" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place repetition interval" +msgstr "Interval de repetició del click dret" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Filtre bilineal" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Entrada aleatòria" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Regular font path" +msgstr "Seleccioneu la ruta" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Report path" +msgstr "Seleccioneu la ruta" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Tecla dreta" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Pantalla:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Pantalla:" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Seabed noise" +msgstr "Soroll de cova #1" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Selecció de 18 fractals de 9 fórmules.\n" +"1 = 4D \"Roundy\" mandelbrot set.\n" +"2 = 4D \"Roundy\" julia set.\n" +"3 = 4D \"Squarry\" mandelbrot set.\n" +"4 = 4D \"Squarry\" julia set.\n" +"5 = 4D \"Mandy Cousin\" mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" julia set.\n" +"7 = 4D \"Variation\" mandelbrot set.\n" +"8 = 4D \"Variation\" julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" julia set.\n" +"11 = 3D \"Christmas Tree\" mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" julia set.\n" +"13 = 3D \"Mandelbulb\" mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" julia set.\n" +"17 = 4D \"Mandelbulb\" mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" julia set." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Servidor" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Port del Servidor" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Port del Servidor" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shader path" +msgstr "Ombres" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Suavitzat de càmara durant el seu moviment.\n" +"Útil per a la gravació de vídeos." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"Suavitza la rotació de la càmera en mode cinematogràfic. 0 per deshabilitar." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Suavitza la rotació de la càmera. 0 per deshabilitar." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Tecla sigil" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed" +msgstr "Velocitat d'escalada" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Radi del núvol" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Configuració" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain height" +msgstr "Alçada del terreny base" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"El temps en segons que es pren entre la repetició de clicks drets quan " +"s'està mantenint el botó dret del ratolí." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"El temps en segons que es pren entre la repetició de clicks drets quan " +"s'està mantenint el botó dret del ratolí." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touch screen threshold" +msgstr "Llindar tàctil (px)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Llindar tàctil (px)" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Upper Y limit of floatlands." +msgstr "Límit absolut de cues emergents" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Varies steepness of cliffs." +msgstr "Controla la pendent i alçada dels turons." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Moviment de les Fulles" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Onatge" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Moviment de les Fulles" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Onatge" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Directori del món (totes les seves dades es guarden aquí).\n" +"No necessari si s'inicia des de el menú principal." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "World start time" +msgstr "Nom del món" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Y of upper limit of large caves." +msgstr "Límit absolut de cues emergents" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#, fuzzy +#~ msgid "- Creative Mode: " +#~ msgstr "Mode Creatiu" + +#, fuzzy +#~ msgid "- Damage: " +#~ msgstr "Dany" + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = oclusió de la paral.laxi amb informació d'inclinació (més ràpid).\n" +#~ "1 = mapa de relleu (més lent, més precís)." + +#~ msgid "Address / Port" +#~ msgstr "Adreça / Port" + +#, fuzzy +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Ajusta la codificació gamma per les taules de llum. Els nombrés nés " +#~ "petits n'augmentaràn la brillantor.\n" +#~ "Aquesta configuració només afecta al client, el servidor l'ignora." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Esteu segur que voleu reiniciar el seu món d'un sol jugador?" + +#~ msgid "Back" +#~ msgstr "Enrere" + +#~ msgid "Basic" +#~ msgstr "Bàsic" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "" +#~ "Bits per píxel (profunditat de color) en el mode de pantalla completa." + +#~ msgid "Bump Mapping" +#~ msgstr "Mapat de relleu" + +#~ msgid "Bumpmapping" +#~ msgstr "Mapat de relleu" + +#~ msgid "Config mods" +#~ msgstr "Configurar mods" + +#~ msgid "Configure" +#~ msgstr "Configurar" + +#~ msgid "Connect" +#~ msgstr "Connectar" + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Controla l'amplada dels túnels, un valor més petit crea túnels més amples." + +#~ msgid "Credits" +#~ msgstr "Crèdits" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Color del punt de mira (R, G, B)." + +#~ msgid "Damage enabled" +#~ msgstr "Dany activat" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Temporització per defecte per a cURL, manifestat en mil·lisegons.\n" +#~ "Només té un efecte si és compilat amb cURL." + +#, fuzzy +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "" +#~ "Descarrega un subjoc, com per exemple minetest_game, des de minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Descarrega'n alguns des de minetest.net" + +#, fuzzy +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Descarregant $1, si us plau esperi ..." + +#~ msgid "Enable VBO" +#~ msgstr "Activar VBO" + +#~ msgid "Enter " +#~ msgstr "Introdueix " + +#~ msgid "Game" +#~ msgstr "Joc" + +#, fuzzy +#~ msgid "Generate Normal Maps" +#~ msgstr "Generar Mapes Normals" + +#, fuzzy +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Instal·lar mod: Arxiu: \"$1\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Combinacions de tecles. (Si aquest menú espatlla, esborrar coses de " +#~ "minetest.conf)" + +#~ msgid "Main" +#~ msgstr "Principal" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "Menú principal" + +#~ msgid "Name / Password" +#~ msgstr "Nom / Contrasenya" + +#~ msgid "Name/Password" +#~ msgstr "Nom/Contrasenya" + +#~ msgid "No" +#~ msgstr "No" + +#~ msgid "Ok" +#~ msgstr "D'acord" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Oclusió de paral·laxi" + +#, fuzzy +#~ msgid "Parallax occlusion scale" +#~ msgstr "Oclusió de paral·laxi" + +#~ msgid "PvP enabled" +#~ msgstr "PvP activat" + +#, fuzzy +#~ msgid "Reset singleplayer world" +#~ msgstr "Reiniciar el mon individual" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "Selecciona el fitxer del mod:" + +#, fuzzy +#~ msgid "Special key" +#~ msgstr "Tecla sigil" + +#~ msgid "Start Singleplayer" +#~ msgstr "Començar Un Jugador" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Per habilitar les ombres el controlador OpenGL ha ser utilitzat." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Activar Cinematogràfic" + +#~ msgid "Yes" +#~ msgstr "Sí" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Has mort." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/cs/minetest.po b/po/cs/minetest.po new file mode 100644 index 0000000..714fe75 --- /dev/null +++ b/po/cs/minetest.po @@ -0,0 +1,7879 @@ +msgid "" +msgstr "" +"Project-Id-Version: Czech (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-31 17:28+0000\n" +"Last-Translator: Fjuro <fjuro@seznam.cz>\n" +"Language-Team: Czech <https://hosted.weblate.org/projects/minetest/minetest/" +"cs/>\n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Vyprázdnit frontu odchozího chatu" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Prázdný příkaz." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Odejít do hlavní nabídky" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Neplatný příkaz: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Zadaný příkaz: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Vypsat připojené hráče" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Připojení hráči: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Fronta odchozího chatu je nyní prázdná." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Server zakázal tento příkaz." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Oživit" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Zemřel jsi" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Příkazy k dispozici:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Příkazy k dispozici: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Příkaz není k dispozici: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Získat nápovědu pro příkazy" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Použij \".help <příkaz>\" pro obdržení více informací, nebo \".help all\" " +"pro celý výpis." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <příkaz>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Dobře" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "<none available>" +msgstr "Příkaz není k dispozici: " + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Nastala chyba v Lua skriptu:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Nastala chyba:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Hlavní nabídka" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Znovu se připojit" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Server vyžaduje opětovné připojení:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Vybrat mody" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Neshoda verze protokolu. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Server vyžaduje protokol verze $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Server podporuje verze protokolů mezi $1 a $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Podporujeme pouze protokol verze $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Podporujeme verze protokolů mezi $1 a $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Zrušit" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Závislosti:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Vypnout vše" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Zakázat balíček modifikací" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Zapnout vše" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Povolit balíček modifikací" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Nepodařilo se povolit mod \"$1\" protože obsahuje nepovolené znaky. Povoleny " +"jsou pouze znaky [a-z0-9_]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Najít více modů" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Žádné (volitelné) závislosti" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Není k dispozici žádný popis hry." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Žádné pevné závislosti" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Není k dispozici žádný popis balíčku modifikací." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Žádné volitelné závislosti" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Volitelné závislosti:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Uložit" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Svět:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "zapnuto" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" již existuje. Chcete jej přepsat?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Budou nainstalovány závislosti $1 a $2." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 od $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 se stahuje,\n" +"$2 čeká ve frontě" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 se stahuje..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 požadovaných závislostí nebylo nalezeno." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 závislostí bude nainstalováno a $2 bude vynecháno." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Všechny balíčky" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Již nainstalováno" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Zpět do hlavní nabídky" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Základní hra:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" +"ContentDB není přístupná pokud byl Minetest kompilován bez použití cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Stahuji..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Selhalo stažení $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Hry" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instalovat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Instalovat $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Instalovat chybějící závislosti" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "" +"Instalace rozšíření: poškozený archiv nebo nepodporovaný typ souboru \"$1\"" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mody" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Nelze načíst žádný balíček" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Žádné výsledky" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Žádné aktualizace" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Nenalezeno" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Přepsat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Ověř prosím, zda je základní hra v pořádku." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Ve frontě" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Balíčky textur" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Odinstalovat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Aktualizovat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Aktualizovat vše [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Zobrazit více informací v prohlížeči" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Svět s názvem \"$1\" již existuje" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Další terén" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Teplota (výšková)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Vlhkost (výšková)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Prolínání biomů" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomy" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Jeskyně (velké)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Jeskyně (malé)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Vytvořit" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekorace" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Varování: Development Test je určen pro vývojáře." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Žaláře" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Plochý terén" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Krajina vznášející se na nebi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Létající ostrovy (experimentální)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Generovat terén bez použití fraktálů: Oceány a podzemí" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Kopce" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Vodnost řek" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Zvyšuje vlhkost v okolí řek" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Instalovat $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Jezera" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Nízká vlhkost a vysoké teploty mají za následek mělké či vyschlé řeky" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Generátor mapy" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Nastavení pro Generátor mapy" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Nastavení pro Generátor mapy" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Hory" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Eroze" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Jeskynní systém" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Není vybrána žádná hra" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Snižuje teplotu a nadmořskou výšku" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Snižuje vlhkost s rostoucí nadmořskou výškou" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Řeky" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Řeky v úrovni mořské hladiny" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Seedové číslo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Pozvolný přechod mezi biomy" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Povrchové struktury (nemá vliv na stromy a tropickou trávu vytvořené ve v6 a " +"později)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Povrchové struktury, především stromy a rostliny" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Mírné, Poušť" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Mírné, Poušť, Džungle" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Mírné, Poušť, Džungle, Tundra, Tajga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Povrchová eroze" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Stromy a tropická tráva" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Proměnná hloubka řek" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Veliké jeskyně hluboko pod zemí" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Název světa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Nemáte nainstalované žádné hry." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Skutečně chcete odstranit \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Smazat" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: nepodařilo se odstranit \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: neplatná cesta \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Doopravdy chcete smazat svět \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Potvrdit heslo" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Jméno Generátoru mapy" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Jméno" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Heslo" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Hesla se neshodují!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Registrovat a Připojit se" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Přijmout" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Přejmenovat balíček modů:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Tento balíček modů má uvedené jméno ve svém modpack.conf, které přepíše " +"jakékoliv přejmenování zde." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(bez popisu)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D šum" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Zpět do Nastavení" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Procházet" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Obsah" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Obsah" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Vypnuto" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Upravit" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Zapnuto" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lakunarita" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktávy" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Odstup" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Urputnost" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Prosím zadejte platné celé číslo." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Zadejte prosím platné číslo." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Obnovit výchozí" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Přiblížení" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Hledat" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Vyberte adresář" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Vybrat soubor" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Zobrazit technické názvy" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Hodnota musí být alespoň $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Hodnota nesmí být větší než $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Rozptyl X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Rozptyl Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Rozptyl Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "absolutnihodnota" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "Výchozí hodnoty" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "vyhlazení" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Povoleno)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 rozšíření" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Selhala instalace $1 do $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Instalace rozšíření: nenašel jsem skutečné jméno modu: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Instalace rozšíření: nenalezen vhodný adresář s příslušným názvem pro " +"balíček $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Platné rozšíření nebylo nalezeno" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Selhala instalace $1 jako rozšíření textur" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Selhala instalace hru jako $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Selhala instalace rozšíření $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Selhala instalace rozšíření $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Nahrávám..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Seznam veřejných serverů je vypnut" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Zkuste znovu povolit seznam veřejných serverů a zkontrolujte své internetové " +"připojení." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "O nás" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktivní přispěvatelé" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Aktivní renderer:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Hlavní vývojáři" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Otevřít uživatelský adresář" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Ve správci souborů otevře adresář obsahující uživatelské světy, hry,\n" +"mody a balíčky textur." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Bývalí přispěvatelé" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Bývalí klíčoví vývojáři" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Zobrazit ladící informace" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Procházet online obsah" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Obsah" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Zakázat Rozšíření Textur" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informace:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Instalované balíčky:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Žádné závislosti." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Balíček nemá žádný popis" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Přejmenovat" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Odinstalovat balíček" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Použít Rozšíření Textur" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Uveřejnit server" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Poslouchat na Adrese" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Kreativní mód" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Povolit zranění" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Založit hru" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Založit server" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Instalovat hry z ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Nový" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Žádný svět nebyl vytvořen ani vybrán!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Spustit hru" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Vybrat mody" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Vyberte svět:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Port serveru" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Spustit hru" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adresa" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Vyčistit" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Kreativní mód" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Zranění / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Oblíbené" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Nekompatibilní server" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Připojit se ke hře" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Veřejné servery" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Obnovit" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Vzdálený port" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Popis serveru" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D mraky" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Všechna Nastavení" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Antialiasing:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Pamatovat si velikost obrazovky" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilineární filtr" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Změnit klávesy" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Propojené sklo" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dynamické stíny" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Dynamické stíny: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Vícevrstevné listí" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Vysoké" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Nízké" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Střední" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmapy" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmapy + anizotropní filtr" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Filtrování vypnuto" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Mipmapy vypnuté" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Osvícení bloku" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Obrys bloku" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Žádný" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Neprůhledné listí" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Neprůhledná voda" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Částice" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Obrazovka:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Nastavení" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shadery" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shader (experimentální)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Shadery (není dostupné)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Jednoduché listí" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Plynulé osvětlení" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Texturování:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Tone mapping" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Dosah dotyku: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Trilineární filtr" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Velmi vysoké" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Vylmi nízké" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Vlnění listů" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Vlnění Kapalin" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Vlnění rostlin" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Chyba spojení (vypršel čas?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Vypršel časový limit připojení." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Hotovo!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inicializuji bloky" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Vytvářím bloky..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Načítám textury..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Sestavuji shadery..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Chyba spojení (vypršel čas?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "Hru nebylo možné nahrát nebo najít \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Neplatná specifikace hry." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Hlavní nabídka" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" +"Nebyl vybrán žádný svět a nebyla poskytnuta žádná adresa. Nemám co dělat." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Jméno hráče je příliš dlouhé." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Zvolte prosím název!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Soubor s heslem nebylo možné otevřít: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Uvedená cesta ke světu neexistuje: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Detaily naleznete v souboru debug.txt." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Adresa: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Mód: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Veřejný: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Název serveru: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Nastala chyba:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Automatický posun vpřed zakázán" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Automatický posun vpřed povolen" + +#: src/client/game.cpp +#, fuzzy +msgid "Block bounds hidden" +msgstr "Ohraničení bloku" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Aktualizace kamery (pohledu) zakázána" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Aktualizace kamery (pohledu) povolena" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Změnit heslo" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Filmový režim zakázán" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Filmový režim povolen" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "Lokální mody" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Uživatelské skripty nejsou povoleny" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Připojuji se k serveru..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Pokračovat" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Ovládání:\n" +"- %s: pohyb dopředu\n" +"- %s: pohyb dozadu\n" +"- %s: pohyb doleva\n" +"- %s: pohyb doprava\n" +"- %s: skok/výstup\n" +"- %s: těžit/uhodit\n" +"- %s: umístit/použít\n" +"- %s: plížení/sestup\n" +"- %s: zahození předmětu\n" +"- %s: inventář\n" +"- Myš: otáčení/rozhlížení\n" +"- Kolečko myši: výběr předmětu\n" +"- %s: chat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Vytvářím klienta..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Spouštím server…" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Ladící informace a profilovací graf skryty" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Ladící informace zobrazeny" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Ladící informace, profilovací graf a obrysy skryty" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Výchozí ovládání:\n" +"Bez menu:\n" +"- klik: aktivace tlačítka\n" +"- dvojklik: položit/použít\n" +"- pohyb prstem: rozhlížení\n" +"Menu/Inventář zobrazen:\n" +"- dvojklik (mimo):\n" +" -->zavřít\n" +"- stisk hromádky, přihrádky :\n" +" --> přesunutí hromádky\n" +"- stisk a přesun, klik druhým prstem\n" +" --> umístit samostatnou věc do přihrádky\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Neomezený pohled zakázán" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Neomezený pohled povolen" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Vytvářím klienta..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Odejít do nabídky" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Ukončit hru" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Rychlý režim zakázán" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Rychlý režim povolen" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Rychlý režim povolen (pozn.: nemáte oprávnění 'fast')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Režim létání zakázán" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Režim létání povolen" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Režim létání povolen (pozn.: nemáte oprávnění 'fly')" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Mlha je zakázána" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Mlha je povolena" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Informace o hře:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Hra pozastavena" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Běží server" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Definice věcí..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Média..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Minimapa je aktuálně zakázána" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Multiplayer" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Režim bez ořezu zakázán" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Režim bez ořezu povolen" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Režim bez ořezu povolen (pozn.: nemáte oprávnění 'noclip')" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Definice bloků..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Vypnuto" + +#: src/client/game.cpp +msgid "On" +msgstr "Zapnuto" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Posun v režimu Pitch zakázán" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Posun v režimu Pitch povolen" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profilovací graf zobrazen" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Vzdálený server" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Překládám adresu..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Vypínání..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Singleplayer" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Hlasitost" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Zvuk vypnut" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Zvukový systém je vypnutý" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Zvukový systém není v této verzi podporovaný" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Zvuk zapnut" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Omezení dohlédnutí upraveno na %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Omezení dohlédnutí na maximu: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Omezení dohlédnutí na minimu: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Hlasitost nastavena na %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Obrysy zobrazeny" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Přiblížení je aktuálně zakázáno" + +#: src/client/game.cpp +msgid "ok" +msgstr "OK" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Chat skryt" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Chat zobrazen" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "Ovládací prvky skryty" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "Ovládací prvky zobrazeny" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profilování skryto" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profilování zobrazeno (strana %d z %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplikace" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Dolů" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Erase EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Spustit" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Pomoc" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Povolené IME" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME Convert" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME Escape" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME Mode Change" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME Nonconvert" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Doleva" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Levé tlačítko myši" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Levý Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Levá klávesa Menu" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Levý Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Levá klávesa Windows" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Nabídka" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Prostřední tlačítko myši" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numerická klávesnice: *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numerická klávesnice: +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numerická klávesnice: -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numerická klávesnice: ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numerická klávesnice: /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numerická klávesnice: 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numerická klávesnice: 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numerická klávesnice: 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numerická klávesnice: 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numerická klávesnice: 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numerická klávesnice: 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numerická klávesnice: 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numerická klávesnice: 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numerická klávesnice: 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numerická klávesnice: 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Klávesa Page Down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Klávesa Page Up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pauza" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Hrát" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Print Screen" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Vrátit" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Doprava" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Pravé tlačítko myši" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Pravý Control" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Pravá klávesa Menu" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Pravý Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Pravá klávesa Windows" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Vybrat" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Spánek" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Snapshot" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Mezerník" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabulátor" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Nahoru" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Tlačítko 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Tlačítko 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Přiblížení" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Minimapa je skryta" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimapa v režimu Radar, Přiblížení x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimapa v režimu Povrch, Přiblížení x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimapa v režimu Textura" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Selhalo stažení $1" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Pokračovat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = sestoupit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Automaticky vpřed" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Automaticky skákat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Vzad" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Ohraničení bloku" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Změnit nastavení kamery" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Příkaz" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konzole" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Snížit rozsah" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Snížit hlasitost" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "2× skok přepne létání" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Zahodit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Vpřed" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Zvýšit rozsah" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Zvýšit hlasitost" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventář" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Skok" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Klávesa je již používána" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Místní příkaz" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Ztlumit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Další věc" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Předchozí věc" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Změna dohledu" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Snímek obrazovky" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Plížit se" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Zapnout/Vypnout ovládací prvky" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Zapnout/Vypnout záznam chatu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Zapnout/Vypnout rychlost" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Zapnout/Vypnout létání" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Zapnout/Vypnout mlhu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Zapnout/Vypnout minimapu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Zapnout/Vypnout režim ořezu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Zapnout/Vypnout režim posunu Pitch" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "stiskni klávesu" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Změnit" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nové heslo" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Staré heslo" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Hesla se neshodují!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Odejít" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Ztlumeno" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Hlasitost: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "cs" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Zvolte prosím název!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Opravena pozice virtuálního joysticku.\n" +"Pokud je zakázán, virtuální joystick se upraví podle umístění prvního dotyku." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Použít virtuální joystick pro stisk tlačítka \"Aux1\".\n" +"Pokud je povoleno, virtuální joystick automaticky stiskne tlačítko \"Aux1\" " +"pokud je mimo hlavní kruh." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) rozestup fraktálu od středu světa v jednotkách 'scale'.\n" +"Může být použito k posunutí spawnu ze souřadnic (0,0),\n" +"nebo k umožnění přiblížení 'zoom in' na konkrétní bod,\n" +"zvýšením hodnoty 'scale'.\n" +"Výchozí nastavení je vhodné pro Mandelbrotovu množinu,\n" +"pro Juliovu a další množiny, může být potřeba speciálního\n" +"nastavení.\n" +"Rozsah je přibližně od -2 do 2. Násobte 'scale' pro posun v blocích." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X, Y, Z) měřítko fraktálu v uzlech.\n" +"Skutečná fraktální velikost bude 2 až 3krát větší.\n" +"Tato čísla mohou být velmi velká, fraktál se nemusí\n" +"vejít do světa.\n" +"Zvětšete tyto, abyste „přiblížili“ detail fraktálu.\n" +"Výchozí je pro svisle stlačený tvar, vhodný například\n" +"pro ostrov, nastavte všechna 3 čísla stejně pro ryzí tvar." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2D šum, který definuje tvar/velikost horských útvarů." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2D šum, který definuje tvar/velikost postupných hor." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2D šum, který definuje tvar/velikost schodišťových hor." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "2D šum, který definuje velikost/četnost horských masivů." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D šum, který definuje velikost/četnost postupných hor." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "2D šum, který definuje velikost/četnost schodišťových horských útvarů." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2D šum, který umisťuje říční koryta a kanály." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D mraky" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Režim 3D zobrazení" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Intezita Parallax ve 3D modu" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D šum určující obří jeskynní dutiny." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D šum určující strukturu a výšku hor.\n" +"Určuje také strukturu horského terénu na létajících ostrovech." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"3D šum definující strukturu létajících ostrovů.\n" +"Pokud je odlišný od výchozího, může být nutné upravit\n" +"\"měřítko\" šumu (výchozí 0.7), jelikož zužování (obrácené hory)\n" +"létajících ostrovů funguje nejlépe pokud je šum v rozmezí přibližně -2.0 až " +"2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "3D šum určující strukturu stěn kaňonů řek." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3D šum určující terén." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "3D šum definující horské převisy, atp. Typicky malé odchylky." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D šum definující počet žalářů na kusu mapy." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Podpora 3D zobrazení.\n" +"V současné době podporovány:\n" +"- none: žádný 3D výstup.\n" +"- anaglyph: azurové/purpurové barevné 3D.\n" +"- interlaced: pro polarizaci lichý/sudý řádek.\n" +"- topbottom: rozdělení obrazovky na horní a dolní část.\n" +"- sidebyside: rozdělení obrazovky na levou a pravou část.\n" +"- crossview: Zkřížení očí 3d\n" +"- pageflip: 3d se 4-násobným bufferem.\n" +"Pozn.: Režim 'interlaced' vyžaduje podporu 'shaderů'." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Zvolený seed pro novou mapu, nechte prázdné pro vygenerování náhodného " +"seedu.\n" +"Toto bude přepsáno při vytváření nové mapy přes hlavní menu." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Zpráva, která se zobrazí všem klientům, když server havaruje." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Zpráva, která se zobrazí všem klientům, když se server vypne." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Interval Aktivní Blokové Modifikace (ABM)" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "ABM použitelný čas" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Maximální počet připravených bloků ve frontě" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Zrychlení ve vzduchu" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Gravitační zrychlení, v blocích za vteřinu za vteřinu." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Active Block Modifiery" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Interval pro Active Block Management" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Rozsah aktivních bloků" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Odesílací rozsah aktivních bloků" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Adresa, kam se připojit.\n" +"Nechte prázdné, pokud chcete spustit místní server.\n" +"Poznámka: pole adresy v hlavním menu přepisuje toto nastavení." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Aktivuje částicové efekty při těžení bloku." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Upraví nastavení DPI pro vaši obrazovku (není pro X11/Android). Pro použití " +"například s 4k obrazovkami." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Upravit hustotu roviny létajících ostrovů.\n" +"Zvýšením hodnoty se zvýší hustota. Hodnota může být kladná i záporná.\n" +"Hodnota = 0.0: 50% světa tvoří létajících ostrovy.\n" +"Hodnota = 2.0 (může být i vyšší v závislosti na “mgv7_np_floatland“,\n" +"nutno vždy otestovat) vytvoří souvislou vrstvu létajících ostrovů." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Dodatkový název položky" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Pokročilé" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Změní křivku světla použitím \"gamma korekce\".\n" +"Vysoké hodnoty zesvětlí málo a středně osvětlené prostory.\n" +"Hodnota \"1.0\" nastaví výchozí křivku.\n" +"Tato úprava slouží především pro úpravu denního\n" +"a umělého osvětlení a má pouze malý dopad na noční osvětlení." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Vždy mít zapnuté létání a turbo" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Gamma ambientní okluze" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Množství zpráv, které může hráč odeslat za 10 vteřin." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Zvýrazní údolí." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Anizotropní filtrování" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Zveřejnit server" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Oznámit tomuto seznamu serverů." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Dodatkový název položky" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Dodatkový název položky v popisku." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Použít stromový šum" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Setrvačnost ruky" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Setrvačnost ruky, vytváří větší dojem opravdového pohybu\n" +"ruky, výkyvem/pohybem kamery." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Zeptat se na znovupřipojení po havárii" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"V této vzdálenosti bude server razantně optimalizovat výběr bloků,\n" +"které pošle klientům.\n" +"Malé hodnoty mohou zlepšit výkon, však mohou také způsobit chyby\n" +"ve vykreslování (některé bloky, zvláště pod vodou, v jeskyních\n" +"a někdy i na zemi, nebudou vykresleny).\n" +"Nastavení této hodnoty vyšší než max_block_send_distance zakáže vypne\n" +"tuto optimalizaci.\n" +"Jednotkou je mapblok (16 bloků)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Automaticky vpřed klávesa" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Automaticky vyskočit na překážky vysoké 1 blok." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Automaticky nahlásit do seznamu serverů." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Ukládat velikost obr." + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Režim automatického přiblížení" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Aux1 klávesa" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Aux1 klávesa pro výstup/sestup" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Vzad" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Základní úroveň povrchu" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Základní výška terénu." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Základní práva" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Šum pláže" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Práh šumu pláže" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilineární filtrování" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Svázat adresu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Parametry tepelného a vlhkostního šumu pro Biome API" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Šum biomů" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Optimalizace vzdálenosti vysílání bloku" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Cesta k tučnému písmu s kurzívou" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Cesta k tučnému proporcionálnímu písmu s kurzívou" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Cesta k tučnému písmu" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Cesta k proporcionálnímu písmu" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Stavění uvnitř hráče" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Zabudované" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Změnit nastavení kamery" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Plynulost pohybu kamery" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Plynulost pohybu kamery ve filmovém režimu" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Klávesa pro přepínání aktualizace pohledu" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Šum v jeskynních" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Šum v jeskynních 1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Šum v jeskynních 2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Šířka jeskyní" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Šum jeskyní 1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Šum jeskyní 2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Limit jeskynních dutin" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Šum jeskynních dutin" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Zúžení jeskynních dutin" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Práh jeskynních dutin" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Horní hranice jeskynních dutin" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Střed posílené křivky světla.\n" +"0.0 odpovídá nejnižší úrovni, 1.0 odpovídá nejvyšší úrovni světla." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Doba do zobrazení času pro příkaz v chatu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Příkazy" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Velikost písma v chatu" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Klávesa chatu" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Úroveň důležitosti ladících informací" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Omezení počtu zpráv v Chatu" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Formát zpráv v chatu" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Doba do vyhození zprávy z chatu" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Omezení velikosti jedné zprávy v Chatu" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Klávesa zobrazení chatu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Chat zobrazen" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Velikost chunku" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Plynulá kamera" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Klávesa plynulého pohybu kamery" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Vynulovat průhledné textury" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Klient" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Klient a Server" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Lokální mody" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Omezení modování na straně klienta" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Omezení vyhledávání bloků z klientské aplikace" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Lokální mody" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Rychlost šplhání" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Poloměr mraků" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Mraky" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Mraky jsou pouze lokální efekt." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Mraky v menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Barevná mlha" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Zbarvené stíny" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Seznam nastavení ve formátu CSV sloužící k filtrování obsahu repozitáře.\n" +"\"nesvobodné\" slouží pro skrytí balíčků, které se podle definice Free " +"Software Foundation\n" +"neřadí do \"svobodného softwaru\".\n" +"Můžete také zadat hodnocení obsahu.\n" +"Tato nastavení jsou nezávislá na versi Minetestu,\n" +"kompletní seznam na: https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Seznam modů, oddělených čárkami, které mohou přistupovat k HTTP API,\n" +"které jim dovoluje nahrávat a stahovat data na/z internetu." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Seznam důvěryhodných modů, oddělených čárkami, které mohou používat\n" +"nebezpečné funkce i když je zapnuto zabezpečení modů (pomocí " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "CMD ⌘" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Propojené sklo" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Připojit se k externímu serveru" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Spojí bloky skla, pokud je to jimi podporováno." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Konzole" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Barva konzole" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Šírka konzole" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "ContentDB: Černá listina" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "ContentDB Max. souběžných stahování" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "ContentDB-URL" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Neustálý pohyb vpřed" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Nepřetržitý pohyb vpřed zapnutý klávesou Automaticky vpřed.\n" +"Stisk klávesy Automaticky vpřed nebo Dozadu, pohyb zruší." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Ovládání" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Ovládání délky denního cyklu.\n" +"Příklad:\n" +"72 = 20 minut, 360 = 4 minuty, 1 = 24 hodin, 0 = zůstává pouze noc nebo den." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Stanovuje strmost/hloubku jezerních prohlubní." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Stanovuje strmost/výšku hor." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Stanovuje šířku tunelů. Nižší hodnota vytváří širší tunely.\n" +"Hodnota >= 10.0 úplně vypne generování tunelů, čímž se zruší\n" +"náročné výpočty šumu." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Zpráva o havárii" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Kreativní" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Průhlednost zaměřovače" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Průhlednost zaměřovače (0 až 255).\n" +"Také určuje barvu zaměřovače" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Barva zaměřovače" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Barva zaměřovače (R,G,B).\n" +"Také určuje barvu zaměřovače" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Zranění" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Klávesa pro zobrazení ladících informací" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Práh velikosti souboru s ladícími informacemi" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Úroveň minimální důležitosti ladících informací" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Klávesa snížení hlasitosti" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Délka serverového kroku" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Výchozí zrychlení" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Výchozí hra" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Výchozí hra pro nové světy.\n" +"Při vytváření nového světa přes hlavní menu bude toto nastavení přepsáno." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Výchozí heslo" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Výchozí práva" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Výchozí formát reportů" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Výchozí velikost hromádky" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Určit kvalitu filtrování stínů\n" +"Simuluje efekt měkkých stínů použitím PCF nebo Poissonova disku,\n" +"za využívá většího výkonu." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Určuje oblasti, kde stromy nesou plody." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Určuje oblasti s písčitými plážemi." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Určuje rozmístění vyššího terénu a strmých útesů." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Určuje rozmístění vyššího terénu." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Určuje celkovou velikost jeskynních dutin, menší hodnoty vytváří větší " +"dutiny." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Určuje makroskopickou strukturu koryta řeky." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Určuje pozici a terén možných hor a jezer." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Určuje základní úroveň povrchu." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Určuje hloubku říčního koryta." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "Určuje maximální posun hráče v blocích (0 = neomezený)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Určuje šířku říčního koryta." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Určuje šířku údolí řeky." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Určuje lesní oblasti a hustotu stromového porostu." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Interval mezi aktualizacemi geom. sítí na klientovi (v milisekundách).\n" +"Zvýšení této hodnoty sníží rychlost změn, tudíž omezí sekání u pomalejších " +"klientů." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Zpoždění odeslání bloků po položení" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Prodleva před zobrazením bublinové nápovědy, uvádějte v milisekundách." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Zacházení se zastaralým Lua API" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Hloubka, pod kterou se nachází velké jeskynní dutiny." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Hloubka, pod kterou se nachází velké jeskyně." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Popis serveru, který bude zobrazen nově připojeným hráčům a který bude " +"uveden v seznamu serverů." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Práh pouštního šumu" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Pouště se objeví v místech, kde 'np_biome' přesahuje tuto hodnotu.\n" +"Ignorováno, pokud je zapnuté nastavení \"snowbiomes\"." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Nesynchronizovat animace bloků" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Dekorace" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Klávesa těžení" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Částicové efekty při těžení" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Vypnout anticheat" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Zakázat prázdná hesla" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Doménové jméno serveru zobrazované na seznamu serverů." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Dvojstisk skoku zapne létání" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Dvojstisk klávesy skoku zapne létání." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Klávesa vyhození předmětu" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Vypsat ladící informace z Generátoru mapy." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Horní hranice Y pro žaláře" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Dolní hranice Y pro žaláře" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Šum žalářů" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Zapnout podporu IPv6 (pro klienta i server).\n" +"Požadováno pro IPv6 připojení." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Zapnout podporu Lua modů na straně klienta.\n" +"Tato funkce je experimentální a její API se může změnit." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Zapnout filtrování Poissoným diskem.\n" +"Pokud je zapnuto, využívá Poissonův disk pro generování \"měkkých stínů\". V " +"opačném případě je využito filtrování PCF." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Zanout zbarvené stíny.\n" +"Po zapnutí vrhají průhledné předměty zbarvené stíny. Toto má velký vliv na " +"výkon." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Povolit konzolové okno" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Zapnout kreativní mód pro všechny hráče" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Zapnout joysticky" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Zapnout zabezpečení módů" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Povolit zraňování a umírání hráčů." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Povolit náhodný uživatelský vstup (pouze pro testování)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Zapne plynulé osvětlení s jednoduchou ambientní okluzí.\n" +"Vypněte pro zrychlení či jiný vzhled." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Zapněte pro zakázání připojení starých klientů.\n" +"Starší klienti jsou kompatibilní v takovém smyslu, že při připojení k novým " +"serverům\n" +"nehavarují, ale nemusí podporovat všechny vlastnosti, které byste očekával/a." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Umožnit použití vzdáleného media serveru (je-li poskytnut serverem).\n" +"Vzdálené servery nabízejí výrazně rychlejší způsob, jak stáhnout\n" +"média (např. textury) při připojování k serveru." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Zapnout objekty vyrovnávací paměti vertexů.\n" +"Toto by mělo výrazně zlepšit grafický výkon." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Nastavit pohupování pohledu a jeho výraznost.\n" +"Např.: 0 pro žádné, 1.0 pro normální a 2.0 pro dvojité klepání." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Povolit/zakázat spuštění IPv6 serveru.\n" +"Ignorováno, pokud je 'bind_address' nastaveno.\n" +"Je třeba mít povoleno enable_ipv6." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Zapíná Hableho \"Uncharted 2\" filmové mapování odstínů.\n" +"Simuluje křivku odstínu fotografického filmu a tím přibližný vzhled\n" +"obrázků s vysokým dynamickým rozsahem (HDR). Kontrast středních\n" +"hodnot je lehce zvýšený, vysoké a nízké hodnoty jsou postupně komprimovány." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Povolí animaci věcí v inventáři." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Zapnout cachování geom. sítí otočených pomocí facedir." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Zapne minimapu." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Zapíná zvukový systém.\n" +"Vypnutí má za náledek úplné ztlumení všech zvuků\n" +"a zvukového ovládání ve hře.\n" +"Změna tohoto nastavení vyžaduje restart." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Interval vypisování profilovacích dat enginu" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Metody entit" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Exponent pro zužování létajících ostrovů. Mění míru zúžení.\n" +"Hodnota = 1.0 vytvoří rovnoměrné přímé zúžení.\n" +"Hodnoty > 1.0 vytvoří hladké zúžení vhodné pro výchozí oddělené\n" +"létající ostrovy.\n" +"Hodnoty < 1.0 (např. 0.25) vytvoří výraznější úroveň povrchu\n" +"s rovinatějšími nížinami, vhodné pro souvislou vrstvu létajících ostrovů." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "Snímky za sekundu (FPS) při pauze či hře běžící na pozadí" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Součinový šum" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Součinitel houpání pohledu při pádu" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Cesta k záložnímu písmu" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Klávesa pro přepnutí turbo režimu" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Zrychlení v turbo režimu" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Rychlost v turbo režimu" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Turbo režim pohybu" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Turbo režim pohybu (pomocí klávesy \"Aux1\").\n" +"Vyžaduje na serveru přidělené právo \"fast\"." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Úhel pohledu" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Úhel pohledu ve stupních." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Soubor v client/serverlist/, který obsahuje oblíbené servery zobrazené na " +"záložce 'Multiplayer'." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Hloubka výplně" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Šum hloubky výplně" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Filmový tone mapping" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Okraje filtrovaných textur se mohou mísit s průhlednými sousedními pixely,\n" +"které PNG optimizery obvykle zahazují. To může vyústit v tmavé nebo světlé\n" +"okraje hran. Zapnutí tohoto filtru problém řeší při načítání textur.\n" +"Toto nastavení je automaticky zapnuto, pokud je povoleno Mip-Mapování." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Antialiasing:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "První ze 4 2D šumů, které dohromady definují rozsah výšek kopců/hor." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "První ze dvou 3D šumů, které dohromady definují tunely." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Fixované seedové čislo" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Nepohyblivý virtuální joystick" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Hustota létajících ostrovů" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Létajících ostrovy: Max. Y" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Létajících ostrovy: Min. Y" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Šum létajících ostrovů" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Exponent zúžení létajících ostrovů" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Vzdálenost zužování létajících ostrovů" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Hladina vody na létajících ostrovech" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Klávesa létání" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Létání" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Mlha" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Začátek mlhy" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Klávesa pro přepnutí mlhy" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Velikost písma" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Tučné písmo jako výchozí" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Kurzíva jako výchozí" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Stín písma" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Průhlednost stínu písma" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Velikost písma" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Velikost výchozího písma v bodech (pt)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Velikost proporcionálního písma v bodech (pt)." + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Velikost písma posledního textu a výzvy v chatu v bodech (pt).\n" +"Výchozí velikost písma se nastaví hodnotou 0." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Formát hráčovy zprávy v chatu. Řetězec níže obsahuje platné zástupce:\n" +"@name, @message, @timestamp (optional)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Formát snímků obrazovky." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Konzole Výchozí barva pozadí" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Konzole Výchozí průhlednost pozadí" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Konzole Barva pozadí při zobrazení na celé obrazovce" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Konzole Průhlednost pozadí při zobrazení na celé obrazovce" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Konzole Výchozí barva pozadí (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Konzole Výchozí průhlednost pozadí (0 až 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Konzole Barva pozadí při zobrazení na celou obrazovku (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" +"Konzole Průhlednost pozadí při zobrazení na celou obrazovku (0 až 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Vpřed" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Čtvrtý ze čtyř 2D šumů, které dohromady definují rozsah výšek kopců/hor." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Typ fraktálu" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Podíl viditelné vzdálenosti, na kterém začne být mlha vykreslována" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Vzdálenost, ve které jsou klientům generovány bloky, určená v mapblocích (16 " +"bloků)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Vzdálenost, ze které jsou klientům odesílány bloky, určená v mapblocích (16 " +"bloků)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Vzdálenost, na kterou má klient inforamace o objektech,\n" +"určená v mapblocích (16 bloků).\n" +"Nastavení této hodnoty výše než active_block_range umožní serveru\n" +"udržet v paměti aktivní objekty až do této vzdálenosti ve směru hráčova\n" +"pohledu. (Toto může předejít náhlému mizení postav)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Celá obrazovka" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Celoobrazovkový režim." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Měřítko GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Filtrovat při škálování GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Filtrovat při škálování GUI (txr2img)" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Hry" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Globální callback funkce" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Globální parametry generování mapy.\n" +"V Generátoru mapy v6 ovládá nastavení \"decorations\" všechny dekorace\n" +"kromě stromů a tropické trávy, ve všech ostatních verzích Generátoru mapy\n" +"ovládá toto nastavení všechny dekorace." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Gradient křivky světla na nejvyšší úrovni světla.\n" +"Určuje kontrast nejvyšších světelných hodnot." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Gradient křivky světla na nejnižší úrovni světla.\n" +"Určuje kontrast nejnižších světelných hodnot." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravitace" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Výška povrchu země" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Šum povrchu" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP režimy" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Měřítko GUI" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Klávesa pro přepnutí HUD (Head-Up Display)" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Zacházení s voláními zastaralého Lua API:\n" +"- none: Nezaznamenávat zastaralá volání\n" +"- log: pokusí se napodobit staré chování a zaznamená backtrace volání\n" +" (výchozí pro debug).\n" +"- error: při volání zastaralé funkce skončit (doporučeno vývojářům modů)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Nechat profiler instrumentovat sám sebe:\n" +"* Instrumentovat prázdnou funkci.\n" +"Tak se dá odhadnout zpomalení způsobené instrumentací (+1 volání funkce).\n" +"* Instrumentovat vzorkovací funkci, která se používá k aktualizaci statistik." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Šum tepelných přechodů" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Tepelný šum" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Výškový parametr počáteční velikosti okna. Ignorováno v režimu na celé " +"obrazovce." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Výškový šum" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Šum vybírání výšky" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Strmost kopců" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Práh kopců" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Šum kopcovitosti1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Šum kopcovitosti2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Šum kopcovitosti3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Šum kopcovitosti4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Domácí stránka serveru. Bude zobrazena v seznamu serverů." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Horizontální zrychlení ve vzduchu při skoku nebo pádu,\n" +"určeno v blocích za sekundu za sekundu." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Horizontální a vertikální zrychlení v rychlém režimu,\n" +"určeno v blocích za sekundu za sekundu." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Horizontální a vertikální zrychlení na zemi nebo při lezení,\n" +"určeno v blocích za sekundu za sekundu." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Klávesa pro následující věc v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Klávesa pro předchozí věc v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Klávesa pro přihrádku 1 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Klávesa pro přihrádku 10 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Klávesa pro přihrádku 11 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Klávesa pro přihrádku 12 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Klávesa pro přihrádku 13 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Klávesa pro přihrádku 14 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Klávesa pro přihrádku 15 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Klávesa pro přihrádku 16 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Klávesa pro přihrádku 17 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Klávesa pro přihrádku 18 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Klávesa pro přihrádku 19 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Klávesa pro přihrádku 2 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Klávesa pro přihrádku 20 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Klávesa pro přihrádku 21 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Klávesa pro přihrádku 22 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Klávesa pro přihrádku 23 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Klávesa pro přihrádku 24 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Klávesa pro přihrádku 25 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Klávesa pro přihrádku 26 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Klávesa pro přihrádku 27 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Klávesa pro přihrádku 28 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Klávesa pro přihrádku 29 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Klávesa pro přihrádku 3 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Klávesa pro přihrádku 30 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Klávesa pro přihrádku 31 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Klávesa pro přihrádku 32 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Klávesa pro přihrádku 4 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Klávesa pro přihrádku 5 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Klávesa pro přihrádku 6 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Klávesa pro přihrádku 7 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Klávesa pro přihrádku 8 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Klávesa pro přihrádku 9 v liště předmětů" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Jak hluboké dělat řeky." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Rychlost pohybu vln v kapalinách. Vyšší = rychlejší.\n" +"Záporné hodnoty vytvoří vlny jdoucí pozpátku.\n" +"Vyžaduje zapnuté vlnění kapalin." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Jak dlouho bude server čekat před uvolněním nepotřebných mapbloků.\n" +"Vyšší hodnota zlepší rychlost programu, ale také způsobí větší spotřebu RAM." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Snižte toto pro zvýšení odporu kapalin vůči pohybu." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Jak široké dělat řeky." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Šum přechodu vlhkosti" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Šum vlhkosti" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Rozdílnost vlhkosti pro biomy." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6 server" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Pokud by snímková frekvence překročila tuto hodnotu,\n" +"omezit ji vyčkáváním, aby se zbytečně neplýtvalo výkonem CPU." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Pokud je vypnuto, klávesa \"Aux1\" je , při zapnutém létání\n" +"a rychlém režimu, použita k rychlému létání." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Když zapnuto, server bude provádět detekci zacloněných bloků na základě\n" +"pozice očí hráče. Tím lze snížit počet klientům odesílaných bloků o 50-80 " +"%.\n" +"Klienti už nebudou dostávat většinu neviditelných bloků, tím pádem ale\n" +"užitečnost režimu ducha bude omezená." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Když zapnuto, můžou se hráči v režimu létání pohybovat skrz pevné bloky.\n" +"K tomu je potřeba mít na serveru oprávnění \"noclip\"." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Pokud je zapnuto, je klávesa \"Aux1\" využita pro sestup\n" +"namísto klávesy \"Plížení\"." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Zapnout potvrzení registrace pro připojení na server.\n" +"Pokud je toto vypnuto, je nový účet registrován automaticky." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Když zapnuto, akce hráčů se zaznamenávají pro funkci vracení změn.\n" +"Toto nastavení je čteno pouze při startu serveru." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Když zapnuto, vypne opatření proti podvádění." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Když zapnuto, nezpůsobí neplatná data světa vypnutí serveru.\n" +"Zapínejte pouze pokud víte, co děláte." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Pokud je zapnuto, je směr pohybu, při létání nebo plavání, závislý na úhlu " +"hráčova pohledu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "Když zapnuto, noví hráči se nemohou připojit s prázdným heslem." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Pokud zapnuto, můžete stavět bloky na pozicích (nohy + výška očí), kde " +"stojíte.\n" +"Užitečné, pokud pracujete s \"nodeboxy\" ve stísněných prostorech." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Pokud je omezení CSM pro vzdálenost bloků povoleno, jsou volání get_node\n" +"omezena na tuto vzdálenost hráče od bloku." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Pokud je doba výkonu příkazu z chatu delší než zadaný čas v sekundách,\n" +"přidej informaci o čase do příkazu v chatu" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Pokud velikost souboru debug.txt po otevření přesáhne počet megabytů určený\n" +"tímto nastavením, bude soubor přesunut do debug.txt.1 (toto vymaže původní " +"debug.txt.1,\n" +"pokud existuje).\n" +"debug.txt je přesunut pouze pokud je toto nastavení platné." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "Jestliže je toto nastaveno, hráči se budou oživovat na uvedeném místě." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ignorovat chyby světa" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "Průhlednost pozadí herní chatovací konzole (neprůhlednost, 0 až 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Barva (R,G,B) pozadí herní chatovací konzole." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"Výška herní chatovací konzole, mezi 0.1 (10 %) a 1.0 (100 %).\n" +"(Pozor, použijte anglickou desetinnou tečku, nikoliv čárku.)" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Klávesa zvýšení hlasitosti" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Počáteční vertikální rychlost skoku v blocích za sekundu." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Instrumentovat \"builtin\".\n" +"Obvykle využíváno jen vývojáři jádra/builtin" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Instrument chat commands on registration." +msgstr "Instrumentovat chatovací přikazy při registraci." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Instrumentovat globální callback funkce při registraci.\n" +"(jakákoliv, kterou můžete předat do funkcí minetest.register_*())" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "Instrumentovat funkci action u Active Block Modifierů při registraci." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "Instrumentovat funkci action u Loading Block Modifierů při registraci." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Instrumentovat metody entit při registraci." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "Časový interval ukládání důležitých změn ve světě, udaný v sekundách." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Časový interval, ve kterém se klientům posílá herní čas." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animace předmětů v inventáři" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Klávesa inventáře" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Invertovat myš" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Obrátit svislý pohyb myši." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Cesta k písmu s kurzívou" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Cesta k proporcionálnímu písmu s kurzívou" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Maximální stáří vyhozeného předmětu" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Iterace" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Opakování rekurzivní funkce.\n" +"Zvýšení hodnoty vede ke zlepšení detailů, ale také zvyšuje nároky na výkon.\n" +"Při opakování = 20 má tento Generátor mapy podobné nároky jako\n" +"Generátor mapy v7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID joysticku" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Interval opakování tlačítek joysticku" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick dead zone" +msgstr "Mrtvá zóna joysticku" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Citlivost otáčení pohledu joystickem" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Typ joysticku" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Pouze pro set Julia.\n" +"Komponenta W hyperkomplexní konstanty.\n" +"Mění tvar fraktálu.\n" +"Nemá žádný vliv na 3D fraktály.\n" +"Rozmezí přibližně -2 až 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Pouze pro set Julia.\n" +"Komponenta X hyperkomplexní konstanty.\n" +"Mění tvar fraktálu.\n" +"Rozmezí přibližně -2 až 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Pouze pro set Julia.\n" +"Komponenta Y hyperkomplexní konstanty.\n" +"Mění tvar fraktálu.\n" +"Rozmezí přibližně -2 až 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Pouze pro set Julia.\n" +"Komponenta Z hyperkomplexní konstanty.\n" +"Mění tvar fraktálu.\n" +"Rozmezí přibližně -2 až 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Klávesa skoku" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Rychlost skákání" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro snížení dohledu.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro těžení\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro odhození právě drženého předmětu.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro zvýšení dohledu.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro zvýšení hlasitosti\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro skok.\n" +"viz. See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro rychlý pohyb v rychlém režimu.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro pohyb hráče zpět.\n" +"Také vypne automatický pohyb vpřed, pokud je zapnutý.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro pohyb hráče vpřed.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro pohyb hráče doleva.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro pohyb hráče doprava.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro ztlumení hry.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klávesa pro otevření okna chatu za účelem zadání příkazů.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"klávesy pro snížení hlasitosti.\n" +"viz. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "Vyhodit hráče, který poslal více jak X zpráv během 10 sekund." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Strmost jezer" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Strmost jezer" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Jazyk" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Hloubka velkých jeskyní" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Horní hranice velkých jeskyní" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Spodní hranice velkých jeskyní" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Poměr zatopení velkých jeskyní" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Klávesa velkého chatu" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Styl listí" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Styl listí:\n" +"- Vícevrstevné: všechny plochy jsou viditelné\n" +"- Jednoduché: pouze vnější plochy, pokud je definováno special_tiles, jsou " +"použity\n" +"- Neprůhledné: vypne průhlednost" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Doleva" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Frekvence aktualizece objektů na serveru.\n" +"Určeno v délce jedné periody." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Délka vln v kapalinách.\n" +"Vyžaduje zapnuté vlnění kapalin." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Frekvence vykonání cyklů Active Block Modifieru (ABM)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Frekvence vykonání cyklů ČasovačeBloku" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Frekvence vykonání cyklů aktivní správy bloků" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Úroveň ladících informací zapsaných do debug.txt:\n" +"- <nothing> (žádné ladící informace)\n" +"- none (zprávy budou vypsány bez patřičné úrovně)\n" +"- error (chyba)\n" +"- warning (varování)\n" +"- action (akce)\n" +"- info (informace)\n" +"- verbose (slovně)" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Posílení křivky světla" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Posílení křivky světla Středy" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Posílení křivky světla Šíření" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Křivka světla Gamma" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Křivka světla Vysoký gradient" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Křivka světla Nízký gradient" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Plynulé osvětlení" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Limit generování mapy v blocích, ve všech 6 směrech od (0,0,0).\n" +"Generují se pouze kusy nacházející se kompletně v zadaném limitu.\n" +"Tato hodnota je unikátní pro každý svět." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Omezuje počet paralelních HTTP požadavků. Má vliv na:\n" +"- Načítání multimédií, pokud server používá nastavení remote_media.\n" +"- Stahování seznamu serverů a oznámení na serveru.\n" +"- Stahování prováděná přes hlavní nabídku (např. Správce modů).\n" +"Má vliv pouze v případě kompilace přes cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Tekutost kapalin" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Vyhlazení tekutosti kapalin" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Horní hranice kapalinového cyklu" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Doba vymazání fronty kapalin" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Rychlost stékání kapalin" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Frekvence aktualizace kapalin v sekundách." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Jeden cyklus aktualizace kapalin" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Načíst profilování hry" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Načíst profilování hry pro sběr profilovacích dat.\n" +"Umožňuje použít příkaz /profiler pro přístup ke zkopilovanému profilu.\n" +"Užitečné pro vývojáře modů a provozovatele serverů." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Loading Block Modifiery" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Spodní hranice Y pro žaláře." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Spodní hranice Y pro létající ostrovy." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Skript hlavní nabídky" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Barva mlhy a oblohy záleží na denní době (svítání/soumrak) a na směru " +"pohledu." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Udělá všechny kapaliny neprůhledné" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Úroveň komprese mapy pro pevné úložiště" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Úroveň komprese mapy pro přenost internetem" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Směr mapy" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Parametry generování mapy pro Generátor mapy - Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Parametry generování mapy pro Generátor mapy - Plocha.\n" +"Do plochého světa je možné přidat občasná jezera a kopce." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Parametry generování mapy pro Generátor mapy - Fraktál.\n" +"\"terén\" umožňuje generování \"nefraktálového\" terénu:\n" +"oceány, ostrovy a podzemí." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Parametry generování mapy pro Generátor mapy - Údolí.\n" +"„altitude_chill“: Snižuje teplotu s nadmořskou výškou.\n" +"„humid_rivers“: Zvyšuje vlhkost podél řek.\n" +"„vary_river_depth“: Pokud zapnuto, nízká vlhkost a vysoká teplota\n" +"budou mít za následek mělčí nebo místy úplně vyschlé řeky.\n" +"„altitude_dry“: Snižuje vlhkost s nadmořskou výškou." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Parametry generování mapy pro Generátor mapy v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Parametry generování mapy pro Generátor mapy v6.\n" +"Nastavení \"snowbiomes\" umožňuje systém 5 biomů.\n" +"Pokud je nastavení \"snowbiomes\" zapnuto, džungle jsou automaticky\n" +"zapnuty a nastavení \"jungles\" je ignorováno." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Parametry generování mapy v Generátoru mapy v7.\n" +"'hřebeny': Rivers.\n" +"'létající ostrovy': Ostrovy vznášející se v prostoru.\n" +"'jeskynní dutiny': Obrovské jeskyně hluboko v podzemí." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Limit generování mapy" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Interval ukládání mapy" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map shadows update frames" +msgstr "Doba aktualizace mapy" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Limit mapbloků" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Prodleva generování sítě mapbloků" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Velikost cache paměti v MB Generátoru mapy pro Mapbloky" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Časový limit pro vymazání Mapbloku z paměti" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Generátor mapy - Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Nastavení pro Generátor mapy - Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Generátor mapy - Plocha" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Nastavení Generátory mapy - Plocha" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Generátor mapy - Fraktál" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Nastavení pro Generátor mapy - Fraktál" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Generátor mapy V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Nastavení pro Generátor mapy v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Generátor mapy v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Nastavení pro Generátor mapy v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Generátor mapy v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Nastavení pro Generátor mapy v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Mapgen údolí" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Nastavení pro Generátor mapy - Údolí" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Ladění Generátoru mapy" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Jméno Generátoru mapy" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Horní hranice vzdálenosti pro generování bloků" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Horní hranice vzdálenosti pro posílání bloků" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Horní hranice počtu kapalin zpracovaných za jeden krok." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Maximální FPS" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "Horní hranice pro náhodný počet velkých jeskyní na kus mapy." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "Horní hranice pro náhodný počet malých jeskyní na kus mapy." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Zpráva dne" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Spodní hranice pro náhodný počet velkých jeskyní na kus mapy." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Spodní hranice pro náhodný počet malých jeskyní na kus mapy." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimum texture size" +msgstr "Minimální velikost textury k filtrování" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mip-mapování" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Zabezpečení" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Cesta k neproporcionálnímu písmu" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Velikost neproporcionálního písma" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "Velikost neproporcionálního písma" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mountain zero level" +msgstr "Hladina vody" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Citlivost myši" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Klávesa ztlumit" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Síť" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Osvícení bloku" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Dekorace označených bloků" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fyzika" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "létání" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Klávesa létání" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place repetition interval" +msgstr "Interval opakování pravého kliknutí" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Player versus player" +msgstr "Hráč proti hráči (PvP)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Bilineární filtrování" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Poměr velkých jeskyní s kapalinami." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Náhodný vstup" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Klávesa pro označení většího počtu věcí" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Regular font path" +msgstr "Cesta pro reporty" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Vzdálená média" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Vzdálený port" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Cesta pro reporty" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Šum hřbetů" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Klávesa doprava" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River channel depth" +msgstr "Hloubka řeky" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River channel width" +msgstr "Hloubka řeky" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River depth" +msgstr "Hloubka řeky" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River noise" +msgstr "Hlučnost řeky" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River size" +msgstr "Velikost řeky" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River valley width" +msgstr "Hloubka řeky" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Kulatá minimapa" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Obrazovka:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Výška obrazovky" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Šířka obrazovky" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Složka se snímky obrazovky" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Formát snímků obrazovky" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Kvalita snímků obrazovky" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Kvalita snímků obrazovky. Použito jen na formát JPEG.\n" +"1 znamená nejhorší kvalita; 100 znamená nejlepší kvalita.\n" +"Použijte 0 pro výchozí kvalitu." + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "Obrázky" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "První ze dvou 3D šumů, které dohromady definují tunely." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Second of two 3D noises that together define tunnels." +msgstr "První ze dvou 3D šumů, které dohromady definují tunely." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Barva obrysu bloku" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Šířka obrysu bloku" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Výběr z 18 fraktálů z 9 rovnic.\n" +"1 = 4D \"Roundy\" – Mandelbrotova množina.\n" +"2 = 4D \"Roundy\" – Juliova množina.\n" +"3 = 4D \"Squarry\" – Mandelbrotova množina.\n" +"4 = 4D \"Squarry\" – Juliova množina.\n" +"5 = 4D \"Mandy Cousin\" – Mandelbrotova množina.\n" +"6 = 4D \"Mandy Cousin\" – Juliova množina.\n" +"7 = 4D \"Variation\" – Mandelbrotova množina.\n" +"8 = 4D \"Variation\" – Juliova množina.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" – Mandelbrotova množina.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" – Juliova množina.\n" +"11 = 3D \"Christmas Tree\" – Mandelbrotova množina.\n" +"12 = 3D \"Christmas Tree\" – Juliova množina.\n" +"13 = 3D \"Mandelbulb\" – Mandelbrotova množina.\n" +"14 = 3D \"Mandelbulb\" – Juliova množina.\n" +"15 = 3D \"Cosine Mandelbulb\" – Mandelbrotova množina.\n" +"16 = 3D \"Cosine Mandelbulb\" – Juliova množina.\n" +"17 = 4D \"Mandelbulb\" – Mandelbrotova množina.\n" +"18 = 4D \"Mandelbulb\" – Juliova množina." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL serveru" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Jméno serveru" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Popis serveru" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL serveru" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Adresa serveru" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Popis serveru" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Jméno serveru" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Port serveru" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Port serveru" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "Adresa seznamu veřejných serverů" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "Adresa seznamu veřejných serverů" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Soubor se seznamem veřejných serverů" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Zapne parallax occlusion mapping.\n" +"Nastavení vyžaduje zapnuté shadery." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Zapne parallax occlusion mapping.\n" +"Nastavení vyžaduje zapnuté shadery." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Zapne parallax occlusion mapping.\n" +"Nastavení vyžaduje zapnuté shadery." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Zapne parallax occlusion mapping.\n" +"Nastavení vyžaduje zapnuté shadery." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Cesta k shaderům" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "Kvalita snímků obrazovky" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map texture size" +msgstr "Minimální velikost textury k filtrování" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "Odsazení stínu písma, pokud je nastaveno na 0, stín nebude vykreslen." + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Zobrazit ladící informace" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Show name tag backgrounds by default" +msgstr "Tučné písmo jako výchozí" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Zpráva o vypnutí" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Velikost kusů mapy vytovřených Generátorem mapy v mapblocích (16 bloků).\n" +"VAROVÁNÍ!: Hodnota vyšší než 5 nepřináší žádné zlepšení\n" +"a zvyšuje riziko problémů.\n" +"Snížení hodnoty zvýší husotou jeskyní a žalářů.\n" +"Změna hodnoty je pro zvláštní případy, jinak je doporučeno\n" +"nechat ji na výchozí hodnotě." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Horní hranice počtu malých jeskyní" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Spodní hranice počtu malých jeskyní" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Plynulé osvětlení" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Klávesa plížení" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed" +msgstr "Rychlost chůze" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Průhlednost stínu písma" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Zvuk" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Stálé místo oživení" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Strength of 3D mode parallax." +msgstr "Síla vygenerovaných normálových map." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Nastavení" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain height" +msgstr "Základní výška terénu" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Cesta k texturám" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "První ze dvou 3D šumů, které dohromady definují tunely." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Rychlost času" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Zpoždění nápovědy" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touch screen threshold" +msgstr "Práh šumu pláže" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Práh šumu pláže" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Trilineární filtrování" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Důvěryhodné mody" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Podvzorkování" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Upper Y limit of floatlands." +msgstr "Maximální počet emerge front" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "VSync" +msgstr "Vertikální synchronizace" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Valley depth" +msgstr "Hloubka výplně" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Variace počtu jeskyní." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Ovladač grafiky" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Vzdálenost dohledu" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Hlasitost" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Zapne parallax occlusion mapping.\n" +"Nastavení vyžaduje zapnuté shadery." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Rychlost chůze" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Hladina vody" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Vlnění bloků" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Vlnění listů" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Vlnění bloků" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Výška vodních vln" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Rychlost vodních vln" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Délka vodních vln" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Vlnění rostlin" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "Barva obrysu bloku" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Zda-li povolit hráčům vzájemně se napadat a zabíjet." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "Výšková část počáteční velikosti okna." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "World start time" +msgstr "Název světa" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Hodnota Y pro horní hranici velkých jeskyní." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" +"Vzdálenost Y, přes kterou se jeskynní dutiny rozšíří do plné velikosti." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Úroveň Y horní hranice jeskynních dutin." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "cURL timeout" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "cURL limit paralelních stahování" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Kreativní mód: " + +#~ msgid "- Damage: " +#~ msgstr "- Zranění: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = parallax occlusion s informacemi o sklonu (rychlejší).\n" +#~ "1 = mapování reliéfu (pomalejší, ale přesnější)." + +#~ msgid "Address / Port" +#~ msgstr "Adresa / Port" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Upraví gamma kódování světelných tabulek. Vyšší čísla znamenají světlejší " +#~ "hodnoty.\n" +#~ "Toto nastavení ovlivňuje pouze klienta a serverem není použito." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Jste si jisti, že chcete resetovat místní svět?" + +#~ msgid "Back" +#~ msgstr "Zpět" + +#~ msgid "Basic" +#~ msgstr "Základní" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bitová hloubka (bity na pixel) v celoobrazovkovém režimu." + +#~ msgid "Bump Mapping" +#~ msgstr "Bump mapping" + +#~ msgid "Bumpmapping" +#~ msgstr "Bump mapování" + +#~ msgid "Config mods" +#~ msgstr "Nastavení modů" + +#~ msgid "Configure" +#~ msgstr "Nastavit" + +#~ msgid "Connect" +#~ msgstr "Připojit" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Stanovuje rychlost potápění v kapalinách." + +#, fuzzy +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Stanovuje hustotu horského terénu na létajících ostrovech.\n" +#~ "Jedná se o posun přidaný k hodnotě šumu 'np_mountain'." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "Ovládá šířku tunelů, menší hodnota vytváří širší tunely." + +#~ msgid "Credits" +#~ msgstr "Autoři" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Barva zaměřovače (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Zranění povoleno" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Výchozí časový limit požadavku pro cURL, v milisekundách.\n" +#~ "Má vliv, pouze pokud byl program sestaven s cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Určuje oblasti létajících ostrovů s rovinný terénem.\n" +#~ "Terén bude rovný v místech, kde hodnota šumu bude větší než 0." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Určuje vyhlazovací krok textur.\n" +#~ "Vyšší hodnota znamená vyhlazenější normálové mapy." + +#~ msgid "Del. Favorite" +#~ msgstr "Smazat oblíbené" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Stáhněte si z minetest.net hru, například Minetest Game" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Stáhněte si jednu z minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Stahuji a instaluji $1, prosím čekejte..." + +#~ msgid "Enable VBO" +#~ msgstr "Zapnout VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "Zapnout potvrzení registrace" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Povolí bump mapping textur. Balík textur buď poskytne normálové mapy,\n" +#~ "nebo musí být automaticky vytvořeny.\n" +#~ "Nastavení vyžaduje zapnuté shadery." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Zapne filmový tone mapping" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Zapne generování normálových map za běhu (efekt protlačení).\n" +#~ "Nastavení vyžaduje zapnutý bump mapping." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Zapne parallax occlusion mapping.\n" +#~ "Nastavení vyžaduje zapnuté shadery." + +#~ msgid "Enter " +#~ msgstr "Zadejte " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Experimentální nastavení, může zapříčinit viditelné mezery mezi bloky,\n" +#~ "je-li nastaveno na vyšší číslo než 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS v menu pauzy" + +#~ msgid "Fallback font shadow" +#~ msgstr "Stín záložního písma" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Průhlednost stínu záložního písma" + +#~ msgid "Fallback font size" +#~ msgstr "Velikost záložního písma" + +#~ msgid "Filtering" +#~ msgstr "Filtrování" + +#~ msgid "Floatland base height noise" +#~ msgstr "Šum základní výšky létajících ostrovů" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Neprůhlednost stínu písma (od 0 do 255)." + +#~ msgid "FreeType fonts" +#~ msgstr "Písma Freetype" + +#~ msgid "Full screen BPP" +#~ msgstr "Bitová hloubka v celoobrazovkovém režimu" + +#~ msgid "Game" +#~ msgstr "Hra" + +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Generovat Normální Mapy" + +#~ msgid "Generate normalmaps" +#~ msgstr "Generovat normálové mapy" + +#~ msgid "HUD scale factor" +#~ msgstr "Součinitel škálování HUD" + +#~ msgid "High-precision FPU" +#~ msgstr "Výpočty ve FPU s vysokou přesností" + +#~ msgid "IPv6 support." +#~ msgstr "" +#~ "Nastavuje reálnou délku dne.\n" +#~ "Např.: 72 = 20 minut, 360 = 4 minuty, 1 = 24 hodin, 0 = čas zůstává stále " +#~ "stejný." + +#~ msgid "In-Game" +#~ msgstr "Ve hře" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Instalace: soubor: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Instrumentace" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Nastavení kláves (pokud toto menu je špatně naformátované, upravte " +#~ "nastavení v minetest.conf)" + +#, fuzzy +#~ msgid "Lava depth" +#~ msgstr "Hloubka velké jeskyně" + +#~ msgid "Main" +#~ msgstr "Hlavní nabídka" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "Skript hlavní nabídky" + +#~ msgid "Menus" +#~ msgstr "Nabídky" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Minimapa v režimu radar, Přiblížení x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Minimapa v režimu radar, Přiblížení x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Minimapa v režimu povrch, Přiblížení x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Minimapa v režimu povrch, Přiblížení x4" + +#~ msgid "Name / Password" +#~ msgstr "Jméno / Heslo" + +#~ msgid "Name/Password" +#~ msgstr "Jméno/Heslo" + +#~ msgid "No" +#~ msgstr "Ne" + +#~ msgid "Ok" +#~ msgstr "OK" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallax occlusion" + +#~ msgid "Parallax occlusion" +#~ msgstr "Parallax occlusion" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Náklon parallax occlusion" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Počet iterací parallax occlusion" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Režim parallax occlusion" + +#, fuzzy +#~ msgid "Parallax occlusion scale" +#~ msgstr "Škála parallax occlusion" + +#~ msgid "Player name" +#~ msgstr "Jméno hráče" + +#~ msgid "PvP enabled" +#~ msgstr "PvP (hráč proti hráči) povoleno" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Reset místního světa" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "Vybrat soubor s modem:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Server / Místní hra" + +#, fuzzy +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Odsazení stínu písma, pokud je nastaveno na 0, stín nebude vykreslen." + +#~ msgid "Special" +#~ msgstr "Speciální" + +#, fuzzy +#~ msgid "Special key" +#~ msgstr "Klávesa plížení" + +#~ msgid "Start Singleplayer" +#~ msgstr "Start místní hry" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Síla vygenerovaných normálových map." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Pro zapnutí shaderů musíte používat OpenGL ovladač." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Plynulá kamera" + +#~ msgid "Waving Water" +#~ msgstr "Vlnění vody" + +#~ msgid "Waving water" +#~ msgstr "Vlnění vody" + +#~ msgid "Yes" +#~ msgstr "Ano" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Budete poprvé připojeni k serveru \"%s\".\n" +#~ "Pokud budete pokračovat, nový uživatelský účet s vašimi údaji bude " +#~ "vytvořen na tomto serveru.\n" +#~ "Prosím znovu napište svoje aktuální heslo a klikněte na 'Registrovat a " +#~ "Připojit se' pro potvrzení souhlasu, nebo vyberte 'Zrušit' pro návrat." + +#~ msgid "You died." +#~ msgstr "Zemřel jsi." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/da/minetest.po b/po/da/minetest.po new file mode 100644 index 0000000..645c052 --- /dev/null +++ b/po/da/minetest.po @@ -0,0 +1,7933 @@ +msgid "" +msgstr "" +"Project-Id-Version: Danish (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-01-26 12:17+0000\n" +"Last-Translator: Thomas Wagner Nielsen <thomas@viawords.com>\n" +"Language-Team: Danish <https://hosted.weblate.org/projects/minetest/minetest/" +"da/>\n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.11-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Empty command." +msgstr "Snakkekommandoer" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Afslut til menu" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Ugyldig kommando: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "Enlig spiller" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Online-spillere: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Genopstå" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Du døde" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Tilgængelige kommandoer:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Tilgængelige kommandoer: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "An error occurred in a Lua script:" +msgstr "Der skete en fejl i Lua scriptet, muligvis af et mod:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Der skete en fejl:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Hovedmenu" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Forbind igen" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Serveren har anmodet om at forbinde igen:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Vælg verden:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protokol versionerne matchede ikke. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Serveren kræver protokol version $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Serveren understøtter protokol versioner mellem $1 og $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Vi understøtter kun protokol version $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Vi understøtter protokol versioner mellem $1 og $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Anuller" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Afhængigheder:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Deaktivér alle" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Deaktiver samlingen af mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Aktivér alle" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Aktiver samlingen af mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Kunne ikke slå mod \"$1\" til, da den indeholder ugyldige tegn. Kun tegnene " +"[a-z0-9_] er tilladte." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Ingen (valgfrie) afhængigheder" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Der er ikke nogen beskrivelse af tilgængelig af det valgte spil." + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No hard dependencies" +msgstr "Ingen afhængigheder." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "" +"Der er ikke nogen beskrivelse af tilgængelig af den valgte samling af mods." + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No optional dependencies" +msgstr "Valgfrie afhængigheder:" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Valgfrie afhængigheder:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Gem" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Verden:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "aktiveret" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "Indlæser..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Alle pakker" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Already installed" +msgstr "Tast allerede i brug" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Tilbage til hovedmenuen" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "Vær vært for spil" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Downloading..." +msgstr "Indlæser..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Kunne ikke hente $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Spil" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Installer" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "Installer" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "Valgfrie afhængigheder:" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "" +"Installer mod: Filtypen \"$1\" er enten ikke understøttet, ellers er arkivet " +"korrupt" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mods" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Der var ingen pakker at hente" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Der er ingen resultater at vise" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "No updates" +msgstr "Opdater" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Teksturpakker" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Afinstaller" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Opdater" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "En verden med navnet »$1« findes allerede" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Altitude chill" +msgstr "Højdekulde" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Altitude dry" +msgstr "Højdekulde" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biome blending" +msgstr "Biom støj" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biomes" +msgstr "Biom støj" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caverns" +msgstr "Hule støj" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caves" +msgstr "Oktaver" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Skab" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Decorations" +msgstr "Gentagelser" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Advarsel: Den minimale udvikings test er kun lavet for udviklerne." + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Dungeons" +msgstr "Ridge støj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Floatlands (experimental)" +msgstr "Svævelandsniveau" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Humid rivers" +msgstr "Luftfugtighedsstøj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Installer" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Mapgen" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Flag for Mapgen" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mapgen-specific flags" +msgstr "Mapgen v5 særlige flag" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Intet spil valgt" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Rivers" +msgstr "Flodstørrelse" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Seed" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Terrain surface erosion" +msgstr "Terræn base støj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Vary river depth" +msgstr "Floddybde" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Verdens navn" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Du har ikke installeret nogle spil." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Er du sikker på, at du vil slette »$1«?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Slet" + +#: builtin/mainmenu/dlg_delete_content.lua +#, fuzzy +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "Modmgr: Kunne ikke slette \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +#, fuzzy +msgid "pkgmgr: invalid path \"$1\"" +msgstr "Modmgr: ugyldig mod-sti \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Slet verden \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Bekræft kodeord" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Mapgen-navn" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "Nyt kodeord" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Kodeordene er ikke ens!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Accepter" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Omdøb Modpack:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Denne samling af mods har et specifik navn defineret i sit modpack.conf " +"hvilket vil overskrive enhver omdøbning her." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Der er ikke nogen beskrivelse af denne indstilling)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Todimensionelle lyde" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Tilbage til siden Indstillinger" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Gennemse" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Indhold" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Indhold" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Deaktiveret" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Rediger" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "aktiveret" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Lacunarity" +msgstr "Sikkerhed" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktaver" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Persistens" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Indtast venligst et gyldigt heltal." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Indtast venligt et gyldigt nummer." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Gendan standard" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Skala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Søg" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Vælg mappe" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Vælg fil" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Vis tekniske navne" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Værdien skal være mindst $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Værdien må ikke være større end $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X spredning" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y spredning" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z spredning" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Absolut værdi" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "Standard" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (aktiveret)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mods" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Kunne ikke installere $1 til $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Installer mod: Kunne ikke finde det rigtige mod-navn for: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Installer mod: Kunne ikke finde passende mappe navn for samling af mods $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Kan ikke finde en korrekt mod eller samling af mods" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Kan ikke installere $1 som en teksturpakke" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Kan ikke installere $1 som et spil" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Kan ikke installere $1 som et mod" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Kan ikke installere $1 som en samling af mods" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Indlæser..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Prøv at slå den offentlige serverliste fra og til, og tjek din internet " +"forbindelse." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktive bidragere" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Active renderer:" +msgstr "Aktivt objektafsendelsesinterval" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Primære udviklere" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Vælg mappe" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Tidligere bidragere" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Tidligere primære udviklere" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Gennemse online indhold" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Indhold" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Deaktiver teksturpakke" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Information:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Installerede pakker:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Ingen afhængigheder." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Der er ikke nogen beskrivelse af tilgængelig af den valgte pakke" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Omdøb" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Afinstaller den valgte pakke" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Anvend teksturpakker" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Meddelelsesserver" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Bind adresse" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Kreativ tilstand" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Aktivér skade" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Vær vært for spil" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Host Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Ny" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Ingen verden oprettet eller valgt!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Start spil" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "Vælg verden:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Vælg verden:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Server port" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Start Game" +msgstr "Vær vært for spil" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "Adresse" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Ryd" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Kreativ tilstand" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "Skade" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "Favorit" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Join Game" +msgstr "Vær vært for spil" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "Meddelelsesserver" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Fjernport" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "Serverbeskrivelse" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D-skyer" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "All Settings" +msgstr "Indstillinger" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Udjævning:" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Autosave Screen Size" +msgstr "Autogem skærmstørrelse" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bi-lineær filtréring" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Skift tastatur-bindinger" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Forbundet glas" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Dynamic shadows" +msgstr "Fontskygge" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Fontskygge" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Smukke blade" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Aniso-filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Intet filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Ingen Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Knudepunktsfremhævelse" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Knudepunktsomrids" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Ingen" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Uuigennemsigtige blade" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Uigennemsigtigt vand" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partikler" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Skærm:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Indstillinger" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Dybdeskabere" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "Svævelandsniveau" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Enkle blade" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Glat belysning" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Teksturering:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Toneoversættelse" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Føletærskel (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Tri-lineær filtréring" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Bølgende blade" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Liquids" +msgstr "Bølgende blade" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Bølgende planter" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Forbindelses fejl (udløbelse af tidsfrist?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Forbindelses fejl (tidsfristen udløb)." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Færdig!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Initialiserer noder" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Initialiserer noder..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Indlæser teksturer..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Genbygger dybdeskabere ..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Forbindelses fejl (udløbelse af tidsfrist?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Kunne ikke finde eller indlæse spillet: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Ugyldig spilspecifikationer." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Hovedmenu" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" +"Ingen verden valgt og ingen adresse angivet. Der er ikke noget at gøre." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Spillerens navn er for langt." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Vælg venligst et navn!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Angivne sti til verdenen findes ikke: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Tjek debug.txt for detaljer." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Adresse: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Tilstand: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Offentlig: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- Spiller mod spiller (PvP): " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Servernavn: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Der skete en fejl:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward disabled" +msgstr "Fremadtast" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward enabled" +msgstr "Fremadtast" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Camera update disabled" +msgstr "Tast til ændring af kameraopdatering" + +#: src/client/game.cpp +#, fuzzy +msgid "Camera update enabled" +msgstr "Tast til ændring af kameraopdatering" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Skift kodeord" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode disabled" +msgstr "Tast for filmisk tilstand" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode enabled" +msgstr "Tast for filmisk tilstand" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "Klient modding" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Forbinder til server..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Fortsæt" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Styring:\n" +"- %s: bevæg dig fremad\n" +"- %s: bevæg dig baglæns\n" +"- %s: bevæg dig til venstre\n" +"- %s: bevæg dig til højre\n" +"- %s: hoppe/klatre\n" +"- %s: snige/gå nedad\n" +"- %s: smid genstand\n" +"- %s: medbragt/lager\n" +"- Mus: vende rundt/kigge\n" +"- Mus venstre: grave/slå\n" +"- Mus højre: placere/bruge\n" +"- Musehjul: vælge genstand\n" +"- %s: snakke (chat)\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Opretter klient ..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Opretter server ..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Debug info shown" +msgstr "Tast til aktivering af fejlsøgningsinfo" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Standardstyring:\n" +"Ingen menu synlig:\n" +"- Enkelt tryk: Aktivér knap\n" +"- Dobbelt tryk: Placér/brug\n" +"- Stryg finger: Kig rundt\n" +"Menu/Medbragt synlig:\n" +"- Dobbelt tryk (uden for):\n" +" --> Luk\n" +"- Rør ved stakken, rør ved felt:\n" +" --> Flyt stakken\n" +"- Rør ved og træk, tryk med 2. finger\n" +" --> Placér enkelt genstand på feltet\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Opretter klient ..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Afslut til menu" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Afslut til operativsystemet" + +#: src/client/game.cpp +#, fuzzy +msgid "Fast mode disabled" +msgstr "Hurtig tilstandshastighed" + +#: src/client/game.cpp +#, fuzzy +msgid "Fast mode enabled" +msgstr "Hurtig tilstandshastighed" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode disabled" +msgstr "Hurtig tilstandshastighed" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode enabled" +msgstr "Skade aktiveret" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog disabled" +msgstr "Deaktivér alle" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog enabled" +msgstr "aktiveret" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Spilinfo:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Spil på pause" + +#: src/client/game.cpp +#, fuzzy +msgid "Hosting server" +msgstr "Hosting server" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Elementdefinitioner ..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Medier..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "Enlig spiller" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Noclip mode enabled" +msgstr "Skade aktiveret" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Knudepunktsdefinitioner ..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Fra" + +#: src/client/game.cpp +msgid "On" +msgstr "Til" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Fjernserver" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Slår adresse op ..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Lukker ned..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Enlig spiller" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Lydniveau" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound muted" +msgstr "Lydniveau" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound unmuted" +msgstr "Lydniveau" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Viewing range changed to %d" +msgstr "Lydstyrke ændret til %d%%" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Lydstyrke ændret til %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +#, fuzzy +msgid "Chat hidden" +msgstr "Snakketast" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Prg." + +#: src/client/keycode.cpp +#, fuzzy +msgid "Backspace" +msgstr "Tilbage" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Ned" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Slet slut-på-fil (EOF)" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Eksekvér" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Hjælp" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME-accept" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME-konvertér" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME Escape" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME-tilstandsskift" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME-ikke-konvertér" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Venstre" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Venstre knap" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Venstre Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Venstre Menu" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Venstre Skift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Venstre meta" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Midterste knap" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numpad *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numpad +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numpad -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Num. tast. ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numpad /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numpad 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numpad 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numpad 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numpad 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numpad 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numpad 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numpad 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numpad 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numpad 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numpad 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Ryd" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Spil" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Udskriv" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Højre" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Højre knap" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Højre Control" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Højre Menu" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Højre Skift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Højre meta" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Vælg" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Sov" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Øjebliksbillede" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Mellemrum" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabulator" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Op" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X knap 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X knap 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +#, fuzzy +msgid "Minimap hidden" +msgstr "Minikorttast" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Kunne ikke hente $1" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Fortsæt" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "\"Brug\" = klatre ned" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Autoforward" +msgstr "Fremad" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Baglæns" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Change camera" +msgstr "Skift bindinger" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Snak" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Kommando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsol" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Sænk lydstyrken" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" +"Tryk på \"hop\" hurtigt to gange for at skifte frem og tilbage mellem flyve-" +"tilstand" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Slip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Fremad" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Øg lydstyrken" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Beholdning" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Hop" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Tast allerede i brug" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Lokal kommando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Lydløs" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Næste genst." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Forr. genstand" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Afstands vælg" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Skærmbillede" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Snige" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle HUD" +msgstr "Omstil flyvning" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle chat log" +msgstr "Omstil hurtig" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Omstil hurtig" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Omstil flyvning" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle fog" +msgstr "Omstil flyvning" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle minimap" +msgstr "Omstil fylde" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Omstil fylde" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle pitchmove" +msgstr "Omstil hurtig" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "Tryk på en tast" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Skift" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nyt kodeord" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Gammelt kodeord" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Kodeordene er ikke ens!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Afslut" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy +msgid "Muted" +msgstr "Lydløs" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Lydstyrke: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "da" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Vælg venligst et navn!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z)-forskydning for fraktal fra verdencentrum i enheder af »skala«.\n" +"Brugt til at flytte en egnet udlægning af lavt land tæt på (0, 0).\n" +"Standarden er egnet til mandelbrot-sæt, skal redigeres for julia-sæt.\n" +"Interval cirka -2 til 2. Gang med »skala« i knudepunkter." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D-skyer" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D-tilstand" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D-støj, der definerer kæmpe grotter." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D-støj, der definerer bjergstruktur og -højde.\n" +"Definerer også svævelandsbjergterrænstrukturen." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "3D-støj, der definerer flodkløftvægstrukturen." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "3D noise defining terrain." +msgstr "3D-støj, der definerer kæmpe grotter." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Understøttelse af 3D.\n" +"Understøttet på nuværende tidspunkt:\n" +"- none: ingen 3d-udgang.\n" +"- anaglyph: cyan/magenta farve 3d.\n" +"- interlaced: ulige/lige linjebaseret polarisering for " +"skærmunderstøttelsen\n" +"- topbottom: opdel skærm top/bund.\n" +"- sidebyside: opdel skærm side om side.\n" +"- pageflip: quadbuffer baseret 3d." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"En valgt kortfødning for et nyt kort, efterlad tom for vilkårlig.\n" +"Vil blive overskrevet når en ny verden oprettes i hovedmenuen." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Besked, som skal vises til alle klienter, når serveren går ned." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Besked, som skal vises til alle klienter, når serveren lukker ned." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ABM interval" +msgstr "Interval for kortlagring" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Absolute limit of queued blocks to emerge" +msgstr "Absolut begrænsning af fremkomstkøer" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Acceleration i luft" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Aktive blokændringer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Active block management interval" +msgstr "Aktiv blokhåndteringsinterval" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Aktiv blokinterval" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Aktivt objektafsendelsesinterval" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Adressen, der skal forbindes til.\n" +"Lad dette være tomt for at starte en lokal server.\n" +"Bemærk, at adressefeltet i hovedmenuen tilsidesætter denne indstilling." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Tilføjer partikler, når man graver en blok." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Justér DPI-konfigurationen til din skærm (ikke-X11 / kun Android) f.eks. til " +"4k-skærme." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Verdens navn" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avanceret" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Flyv altid og hurtigt" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Ambient okklusiongamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Amplifies the valleys." +msgstr "Forstærker dalene" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Anisotropisk filtrering" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Meddelelsesserver" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Announce to this serverlist." +msgstr "Meddelelsesserver" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Æbletræsstøj" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Spørg om at forbinde igen efter nedbrud" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatic forward key" +msgstr "Fremadtast" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatically report to the serverlist." +msgstr "Rapporter automatisk til serverlisten." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Autogem skærmstørrelse" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "Hop-tast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key for climbing/descending" +msgstr "Tast brugt til at klatre op/ned" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tilbage-tast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Base ground level" +msgstr "Jordoverfladen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Base terrain height." +msgstr "Baseterrænhøjde" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Basic privileges" +msgstr "Grundlæggende privilegier" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Strandstøj" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Strandstøjtærskel" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilineær filtrering" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Bind adresse" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Biom API temperatur og luftfugtighed støj parametre" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome noise" +msgstr "Biom støj" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bold font path" +msgstr "Sti til font" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Byg intern spiller" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Indbygget" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Skift bindinger" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Kameraudjævning" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Kameraudjævning i biograftilstand" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Tast til ændring af kameraopdatering" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave noise" +msgstr "Hulestøj" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Hulestøj #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Hulestøj #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Grottebredde" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave1 noise" +msgstr "Cave1 støj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave2 noise" +msgstr "Cave2 støj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern limit" +msgstr "Hule grænse" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern noise" +msgstr "Hule støj" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern threshold" +msgstr "Hule tærskel" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern upper limit" +msgstr "Hule grænse" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "Ørkenstøjtærskel" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Snakkekommandoer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat font size" +msgstr "Skriftstørrelse" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Snakketast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat log level" +msgstr "Logniveau for fejlsøgning" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat message format" +msgstr "Nedbrudsbesked" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat message kick threshold" +msgstr "Ørkenstøjtærskel" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Tast for snak (chat)" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Klumpstørrelse" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Filmisk tilstand" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tast for filmisk tilstand" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Rene gennemsigtige teksturer" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Klient" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Klient og server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client modding" +msgstr "Klient modding" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client side modding restrictions" +msgstr "Klient modding" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Klient modding" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Klatringshastighed" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Skyradius" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Skyer" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Skyer er en klientsideeffekt." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Skyer i menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Farvet tåge" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Colored shadows" +msgstr "Farvet tåge" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Kommaadskilt liste af mod'er som har tilladelse til at tilgå HTTP API'er, " +"som\n" +"tillader dem at hente og overføre data fra internettet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Kommaadskil liste over troværdige mod'er som har tilladelse til at tilgå " +"usikre\n" +"funktioner selv når mod-sikkerhed er aktiveret (via " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Kommandotast" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Forbind glas" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Opret forbindelse til ekstern medieserver" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Forbinder glass hvis understøttet af knudepunkt." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Konsolalfa" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Konsolfarve" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Konsolhøjde" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ContentDB URL" +msgstr "Fortsæt" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Kontinuerlig fremad" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Styring" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Styrer længden af dag-/natcyklussen.\n" +"Eksempler: 72 = 20 min, 360 = 4 min, 1 = 24 timer, 0 = dag/nat/hvad som " +"helst forbliver uændret." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Kontrollerer hældning/dybe for sødybder." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Styrer stejlheden/højden af bakkerne." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Nedbrudsbesked" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Kreativ" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Crosshair alpha" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "Crosshair alpha (uigennemsigtighed, mellem 0 og 255)." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Crosshair-farve" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Skade" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Tast til aktivering af fejlsøgningsinfo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Debug log file size threshold" +msgstr "Ørkenstøjtærskel" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Logniveau for fejlsøgning" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dec. volume key" +msgstr "Dec. lydstyrketasten" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Dedikeret server-trin" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Standardacceleration" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Standard spil" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "Standard spil, når du skaber en ny verden." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Standardadgangskode" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Standardprivilegier" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Standardformat for rapport" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default stack size" +msgstr "Standard spil" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Definerer områder, hvor træerne har æbler." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Definerer områder med sandstrande." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Definerer fuld størrelse af grotter - mindre værdier genererer større " +"grotter." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines the base ground level." +msgstr "Definerer træområder og trætæthed." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines the depth of the river channel." +msgstr "Definerer træområder og trætæthed." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Definerer den maksimale spillerflytningsafstand i blokke (0 = ubegrænset)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines the width of the river valley." +msgstr "Definerer områder, hvor træerne har æbler." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Definerer træområder og trætæthed." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Forsinkelse i afsendelse af blokke efter bygning" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Forsinkelse ved visning af værktøjsfif, angivet i millisekunder." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Forældet Lua API-håndtering" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Depth below which you'll find giant caverns." +msgstr "Dybde hvorunder du kan finde store huler." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Dybde hvorunder du kan finde store huler." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Beskrivelse af server, som vises når spillere tilslutter sig og i " +"serverlisten." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Ørkenstøjtærskel" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Afsynkroniser blokanimation" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Gentagelser" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "Højretast" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Gravepartikler" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Deaktiver antisnyd" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Tillad ikke tomme adgangskoder" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Domænenavn for server, til visning i serverlisten." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Tryk to gange på »hop« for at flyve" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" +"Tryk på »hop« to gange for at skifte frem og tilbage fra flyvetilstand." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Drop element-tast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dump the mapgen debug information." +msgstr "Dump mapgen-fejlsøgningsinfo." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dungeon noise" +msgstr "Ridge støj" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Aktivér konsolvindue" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable creative mode for all players" +msgstr "Aktivér kreativ tilstand for nyoprettede kort." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable joysticks" +msgstr "Aktivér joysticks" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable mod channels support." +msgstr "Aktiver mod-sikkerhed" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Aktiver mod-sikkerhed" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Aktiver at spillere kan skades og dø." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Aktiver vilkårlig brugerinddata (kun til test)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Aktiver blød lyssætning med simpel ambient okklusion.\n" +"Deaktiver for hastighed eller for anderledes udseender." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Aktiver for at nægte gamle klienter i at forbinde.\n" +"Ældre klienter er kompatible på den måde, at de ikke vil stoppe ved " +"tilkobling\n" +"til nye servere, men de understøtter ikke alle nye funktioner." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Aktiver brug af ekstern medieserver (hvis tilbudt af server).\n" +"Eksterne servere tilbyder en signifikant hurtigere måde at hente medier (f." +"eks. teksturer\n" +"ved forbindelse til serveren." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Aktivere/deaktivere afvikling af en IPv6-server. En IPv6-server kan være " +"begrænset\n" +"til IPv6-klienter, afhængig af systemkonfiguration.\n" +"Ignoreret hvis bind_address er angivet." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Aktiverer animation af lagerelementer." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Aktiverer mellemlagring af facedir-roterede mesher." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Aktiverer minikort." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Udskrivningsinterval for motorprofileringsdata" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Entitetmetoder" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Faktorstøj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Fall bobbing factor" +msgstr "Fall bobbing faktor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Fallback font path" +msgstr "Reserveskrifttype" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Hurtigtast" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Hurtig tilstandsacceleration" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Hurtig tilstandshastighed" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Hurtig bevægelse" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Hurtig bevægelse (via tast).\n" +"Dette kræver privilegiet »fast« på serveren." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Visningsområde" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Visningsområde i grader." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Fil i client/serverlist/ som indeholder dine favoritservere vist i " +"fanebladet for flere spillere." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filler depth" +msgstr "Fyldstofdybde" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filler depth noise" +msgstr "Fyldningsdybde støj" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Filmisk toneoversættelse" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Filtrerede teksturer kan blande RGB-værdier med fuldt gennemsigtige naboer,\n" +"som PNG-optimeringsprogrammer normalt fjerner, undertiden resulterende i " +"en \n" +"mørk eller lys kant for gennemsigtige teksturer. Anvend dette filter for at " +"rydde\n" +"op i dette på indlæsningstidspunktet for tekstur." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Udjævning:" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "Første af 2 3D-støj, der sammen definerer tunneler." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "First of two 3D noises that together define tunnels." +msgstr "Første af 2 3D-støj, der sammen definerer tunneler." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Fast kortfødning" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland density" +msgstr "Svævelandsniveau" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland noise" +msgstr "Svævelandsniveau" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland taper exponent" +msgstr "Svævelandsgrundhøjdestøj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland tapering distance" +msgstr "Svævelandsgrundhøjdestøj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland water level" +msgstr "Svævelandsniveau" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Flyvetast" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Flyver" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Tåge" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Fog start" +msgstr "Tågebegyndelse" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Tast for tåge" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Skriftstørrelse" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Fontskygge" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Alfa for skrifttypeskygge" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Skriftstørrelse" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Format for skærmbilleder." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec default background color (R,G,B)." +msgstr "Baggrundsfarve for snakkekonsollen i spillet (R,G,B)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" +"Baggrundsalfa for snakkekonsollen i spillet (uigennemsigtighed, mellem 0 og " +"255)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Baggrundsfarve for snakkekonsollen i spillet (R,G,B)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" +"Baggrundsalfa for snakkekonsollen i spillet (uigennemsigtighed, mellem 0 og " +"255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Fremadtast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "Første af 2 3D-støj, der sammen definerer tunneler." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Fraktaltype" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Fra hvor langt væk blokke oprettes for klienten, angivet i kortblokke (16 " +"knudepunkter)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Fra hvor langt væk blokke sendes til klienter, angivet i kortblokke (16 " +"knudepunker)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Fuld skærm" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Fuldskærmstilstand." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Skalering af grafisk brugerflade" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "GUI-skaleringsfilter" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "GUI-skaleringsfilter txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Spil" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Globale tilbagekald" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Globale kortoprettelsesattributter.\n" +"I Mapgen v6 kontrollerer flaget »decorations« alle dekorationer undtagen " +"træer\n" +"og junglegræs, i alle andre mapgen'er kontrollerer dette flag alle " +"dekorationer.\n" +"Flag som ikke er angivet i flagstrengen ændres ikke fra standarden.\n" +"Flag startende med »no« (nej) bruges til eksplicit at deaktivere dem." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafik" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafik" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafik" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Tyngdekraft" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ground level" +msgstr "Jordoverfladen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ground noise" +msgstr "Jordoverfladen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HTTP mods" +msgstr "HTTP-Mod'er" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Skalering af grafisk brugerflade" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Tast for HUD" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Håndtering for forældede lua api-kald:\n" +"- legacy: (prøv at) efterligne gammel opførsel (standard for udgivelse).\n" +"- log: efterlign og log tilbagesporing for forældede kald (standard for " +"fejlsøgning).\n" +"- error: afbryd ved brug af forældede kald (foreslået af mod-udviklere)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Få profilprogrammet til at instruere sig selv:\n" +"* Instruer en tom funktion.\n" +"Dette estimerer belastningen, som instrumenteringen tilføjer (+1 " +"funktionkald).\n" +"* Instruer sampleren i brug til at opdatere statistikken." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Heat blend noise" +msgstr "Varme blanding støj" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Varmestøj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "Højdekomponent for den oprindelige vinduestørrelse." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Højdestøj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Height select noise" +msgstr "Højde Vælg støj" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Bakkestejlhed" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Bakketærskel" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness1 noise" +msgstr "Varmestøj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness2 noise" +msgstr "Varmestøj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness3 noise" +msgstr "Varmestøj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness4 noise" +msgstr "Varmestøj" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Hjemmeside for serveren, som vist i serverlisten." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "How deep to make rivers." +msgstr "Dybde for floder" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Hvor lang tid serveren vil vente før ubrugt kortblokke fjernes.\n" +"Højere værdier er længere tid, men vil bruge mere RAM." + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "How wide to make rivers." +msgstr "Hvor brede floder skal være" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Luftfugtighedsstøj" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6-server" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Hvis FPS skal være højere end dette, så begræns ved at sove\n" +"for ikke at spilde CPU-kraft uden nogen fordel." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Hvis deaktiveret bruges »brug«-tasten til at flyve hurtig hvis både flyvning " +"og hurtig tilstand er aktiveret." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Hvis aktiveret sammen med fly-tilstand, kan spilleren flyve igennem faste " +"knudepunkter.\n" +"Dette kræver privilegiet »noclip« på serveren." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Hvis aktiveret bruges »brug«-tasten i stedet for »snig«-tasten til at klatre " +"ned og aftagende." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Hvis aktiveret, optages handlinger for tilbagerulning.\n" +"Dette tilvalg læses kun når serveren starter." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" +"Hvis aktiveret så deaktiver forhindring af snyd i spil med flere deltagere." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Hvis aktiveret, så vil ugyldige data ikke medføre at serveren lukke ned.\n" +"Aktiver kun hvis du ved hvad du gør." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Hvis aktiveret kan nye spillere ikke slutte sig til uden en tom adgangskode." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Hvis aktiveret så kan du placere blokke ved positionen (fod + øje niveau) " +"hvor du står.\n" +"Dette er nyttigt under arbejde med knudepunktbokse i små områder." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" +"Hvis aktiveret, så vil spillere altid (gen)starte ved den angivne position." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ignorer verdensfejl" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Baggrundsalfa for snakkekonsollen i spillet (uigennemsigtighed, mellem 0 og " +"255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Baggrundsfarve for snakkekonsollen i spillet (R,G,B)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "Spillechat konsol højde, mellem 0,1 (10%) og 1,0 (100%)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Inc. volume key" +msgstr "Øg lydstyrketasten" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Instrumenteringsindbygning.\n" +"Er normalt kun krævet af kerne/indbygningsbidragydere" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Instrument chat commands on registration." +msgstr "Udstyr chatkommandoer ved registrering." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Udstyr globale tilbagekaldsfunktioner ved registrering.\n" +"(alt du sender til en minetest.register_*()-funktion)" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "Udstyr handlingsfunktionen for Aktiv blokændringer ved registrering." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Udstyr handlingsfunktionen for Indlæsning af blokændringer ved registrering." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Udstyr metoderne for enheder ved registrering." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Interval for lagring af vigtige ændringer i verden, angivet i sekunder." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Interval for afsendelse af tidspunkt på dagen til klienter." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animationer for lagerelementer" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Lagertast" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Invertér mus" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Vend lodret musebevægelse om." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Italic font path" +msgstr "Sti til font" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Elemententitet TTL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Iterations" +msgstr "Gentagelser" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Joystick-knaps gentagelsesinterval" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Joystick frustum-sensitivitet" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Kun Juliasæt: W-komponent for hyperkompleks konstant der bestemmer " +"Juliaform.\n" +"Har ingen effekt på 3D-fraktaler.\n" +"Interval cirka -2 til 2." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Kun Juliasæt: X-komponent for hyperkompleks konstant der bestemmer " +"Juliaform.\n" +"Interval cirka -2 til 2." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Kun Juliasæt: Y-komponent for hyperkompleks konstant der bestemmer " +"Juliaform.\n" +"Interval cirka -2 til 2." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Kun Juliasæt: Z-komponent for hyperkompleks konstant der bestemmer " +"Juliaform.\n" +"Interval cirka -2 til 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Hop-tast" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Hoppehastighed" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for mindskning af den sete afstand.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for sænkning af lydstyrken.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hop.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast som smider det nuværende valgte element.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for øgning af den sete afstand.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for øgning af lydstyrken.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hop.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at bevæge sig hurtigt i tilstanden hurtig.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at bevæge spilleren baglæns.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at bevæge spilleren fremad.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at bevæge spilleren mod venstre.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at bevæge spilleren mod højre.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for stum.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne snakkevinduet for at indtaste kommandoer.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne snakkevinduet for at indtaste kommandoer.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne snakkevinduet (chat).\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hop.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at åbne lageret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til snigning.\n" +"Bruges også til at klatre ned og synke ned i vand hvis aux1_descends er " +"deaktiveret.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte mellem første- og tredjepersons kamera.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at lave skærmbilleder.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte til automatisk løb.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte til biograftilstand.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte til visning af minikort.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte til hurtig tilstand.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte til flyvning.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte til noclip-tilstand.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte til noclip-tilstand.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for at skifte kameraopdateringen. Bruges kun til udvikling\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte visningen af snakken (chat).\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte til visning af fejlsøgningsinformation.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte visningen af tåge.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til skift af visningen for HUD'en.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte visningen af snakken (chat).\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte visningen af profileringsprogrammet. Brugt til " +"udvikling.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast til at skifte til ubegrænset se-afstand.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hop.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Søstejlhed" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Søtærskel" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Sprog" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Dybde for stor hule" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Large chat console key" +msgstr "Store chat konsol tast" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Bladstil" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Bladstil:\n" +"- Fancy: alle sider synlige\n" +"- Simple: kun ydre sider, hvis defineret special_tiles anvendes\n" +"- Opaque: deaktiver gennemsigtighed" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Venstretast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Længde på serveraktivering og intervallet som objekter opdateres efter over " +"netværket." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Sat til true (sand) aktiverer bølgende blade.\n" +"Kræver at dybdeskabere er aktiveret." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Tidslængde mellem ABM-kørselscyklusser" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Tidslængde mellem NodeTimer-kørselscyklusser" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Tidslængde mellem ABM-kørselscyklusser" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Niveau for logning der skrives til debug.txt:\n" +"- <nothing> (ingen logning)\n" +"- none (beskeder uden niveau)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Glat belysning" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Begrænser antallet af parallelle HTTP-forespørgsler. Påvirker:\n" +"- Medioverførsel hvis serveren bruger indstillingen remote_media.\n" +"- Serverlist-overførsel og serverbesked.\n" +"- Overførsler udført af hovedmenuen (f.eks. mod-håndtering).\n" +"Har kun en effekt hvis kompileret med cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Væskes evne til at flyde" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Blødgøring af væskes evne til at flyde" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Væskesløjfe maks." + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Køfjernelsestid for væske" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Liquid sinking" +msgstr "Synkehastighed for væske" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Væskeopdateringsinterval i sekunder." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Væskeopdateringsudløsning" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Indlæs spilprofileringsprogrammet" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Indlæs spilprofileringsprogrammet for at indsamle profileringsdata.\n" +"Tilbyder en kommando /profiler til at tilgå den indsamlede profil.\n" +"Nyttig for mod-udviklere og serveroperatører." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Indlæser blokændringer" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lower Y limit of floatlands." +msgstr "Absolut begrænsning af fremkomstkøer" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Hovedmenuskript" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Tåge- og himmelfarver afhænger af tid på dagen (solopgang/solnedgang) og den " +"sete retning." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Kortmappe" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Kortoprettelsesattributter specifikke for Mapgen flat.\n" +"Undtagelsesvis kan søer og bakker tilføjes til den flade verden.\n" +"Flag som ikke er specificeret i flag-strengen ændres ikke fra standarden.\n" +"Flag der starter med »no« bruges til eksplicit at deaktivere dem." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Kortoprettelsesattributter specifikke for Mapgen flat.\n" +"Undtagelsesvis kan søer og bakker tilføjes til den flade verden.\n" +"Flag som ikke er specificeret i flag-strengen ændres ikke fra standarden.\n" +"Flag der starter med »no« bruges til eksplicit at deaktivere dem." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Tilknyttes Mapgen v6 generation attributter specifikke.\n" +"'Snowbiomes' flag gør det muligt for det nye 5 biom system.\n" +"Når den nye biom system aktiveres jungler er automatisk aktiveret og flaget " +"'junglen' er ignoreret.\n" +"Flag, der ikke er angivet i strengen flag er ikke ændret fra standarden.\n" +"Flag starter med \"nej\" er brugt udtrykkeligt deaktivere dem." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Kortoprettelsesattributter specifikke for Mapgen flat.\n" +"Undtagelsesvis kan søer og bakker tilføjes til den flade verden.\n" +"Flag som ikke er specificeret i flag-strengen ændres ikke fra standarden.\n" +"Flag der starter med »no« bruges til eksplicit at deaktivere dem." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Kortoprettelsesbegrænsning" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Interval for kortlagring" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map shadows update frames" +msgstr "Væskeopdateringsudløsning" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Kortblokbegrænsning" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapblock mesh generation delay" +msgstr "Mapblock mesh generation forsinkelse" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Mapblock mesh generation forsinkelse" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Tidsudløb for kortblokfjernelse" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian" +msgstr "Fraktral for Mapgen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian specific flags" +msgstr "Flade flag for Mapgen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat" +msgstr "Mapgen-flad" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat specific flags" +msgstr "Flade flag for Mapgen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal" +msgstr "Fraktral for Mapgen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "Flade flag for Mapgen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5" +msgstr "Mapgen v5" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5 specific flags" +msgstr "Mapgen v5 særlige flag" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6" +msgstr "Mapgen v6" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6 specific flags" +msgstr "Mapgen v6 særlige flag" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7" +msgstr "Mapgen v7" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7 specific flags" +msgstr "Mapgen v7 særlige flag" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Mapgen-daler" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Valleys specific flags" +msgstr "Flade flag for Mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Fejlsøgning for Mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Mapgen-navn" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Maksimal FPS" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Maksimum antal brugere" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Dagens besked" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Message of the day displayed to players connecting." +msgstr "Besked i dag vist til spillere, der forbinder." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Minikort" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Minikorttast" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mipmapping" +msgstr "Mipmapping" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Sikkerhed" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mountain zero level" +msgstr "Vandstand" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mute key" +msgstr "MUTE-tasten" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Netværk" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Knudepunktsfremhævelse" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Lyde" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Per-player limit of queued blocks to generate" +msgstr "Begrænsning af fremkomsten af køer at oprette" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fysik" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move key" +msgstr "Flyvetast" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Flyvetast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place repetition interval" +msgstr "Joystick-knaps gentagelsesinterval" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Bilineær filtrering" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Range select key" +msgstr "Range select tasten" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Regular font path" +msgstr "Rapportsti" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Fjernport" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Rapportsti" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ridge noise" +msgstr "Ridge støj" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Højretast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River channel depth" +msgstr "Floddybde" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River channel width" +msgstr "Floddybde" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River depth" +msgstr "Floddybde" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River noise" +msgstr "Flodstøj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River size" +msgstr "Flodstørrelse" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River valley width" +msgstr "Floddybde" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Rundt minikort" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Skærm:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Skærmhøjde" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Skærmbredde" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Skærmbilledformat" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Skærmbilledkvalitet" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Skærmbillede" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Seabed noise" +msgstr "Havbunden støj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "Første af 2 3D-støj, der sammen definerer tunneler." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Second of two 3D noises that together define tunnels." +msgstr "Første af 2 3D-støj, der sammen definerer tunneler." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Valg af 18 fraktaler fra 9 formler.\n" +"1 = 4D »Roundy« mandelbrot-sæt.\n" +"2 = 4D »Roundy« julia-sæt.\n" +"3 = 4D »Squarry« mandelbrot-sæt.\n" +"4 = 4D »Squarry\" julia-sæt.\n" +"5 = 4D »Mandy Cousin« mandelbrot-sæt.\n" +"6 = 4D »Mandy Cousin« julia-sæt.\n" +"7 = 4D »Variation« mandelbrot-sæt.\n" +"8 = 4D »Variation« julia-sæt.\n" +"9 = 3D »Mandelbrot/Mandelbar« mandelbrot-sæt.\n" +"10 = 3D »Mandelbrot/Mandelbar« julia-sæt.\n" +"11 = 3D »Christmas Tree« mandelbrot-sæt.\n" +"12 = 3D »Christmas Tree« julia-sæt.\n" +"13 = 3D »Mandelbulb« mandelbrot-sæt.\n" +"14 = 3D »Mandelbulb« julia-sæt.\n" +"15 = 3D »Cosine Mandelbulb« mandelbrot-sæt.\n" +"16 = 3D »Cosine Mandelbulb« julia-sæt.\n" +"17 = 4D »Mandelbulb« mandelbrot-sæt.\n" +"18 = 4D »Mandelbulb« julia-sæt." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Server-URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Servernavn" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Serverbeskrivelse" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "Server-URL" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Serveradresse" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Serverbeskrivelse" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Servernavn" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Serverport" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Server port" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Sat til true (sand) aktiverer bølgende blade.\n" +"Kræver at dybdeskabere er aktiveret." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Sat til true (sand) aktiverer bølgende blade.\n" +"Kræver at dybdeskabere er aktiveret." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Angivet til true (sand) aktiverer bølgende vand.\n" +"Kræver at dybdeskabere er aktiveret." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Angivet til true (sand) aktiverer bølgende planter.\n" +"Kræver at dybdeskabere er aktiveret." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shader path" +msgstr "Shader sti" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Dybdeskabere tillader avancerede visuelle effekter og kan forøge ydelsen på " +"nogle videokort.\n" +"De fungerer kun med OpenGL-videomotoren." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "Skærmbilledkvalitet" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Forskydning for skrifttypeskygge, hvis 0 så vil skygge ikke blive tegnet." + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Nedlukningsbesked" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Blød belysning" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Snigetast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed" +msgstr "Ganghastighed" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Alfa for skrifttypeskygge" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Lyd" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Step mountain size noise" +msgstr "Terræn base støj" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Indstillinger" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain alternative noise" +msgstr "Terræn base støj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain base noise" +msgstr "Terræn base støj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain height" +msgstr "Terrænhøjde" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain higher noise" +msgstr "Terræn højere støj" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Terrænstøj" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The depth of dirt or other biome filler node." +msgstr "Dybde for smuds eller andet fyldstof" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "Første af 2 3D-støj, der sammen definerer tunneler." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Tidshastighed" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touch screen threshold" +msgstr "Strandstøjtærskel" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Strandstøjtærskel" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Trilineær filtrering" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Upper Y limit of floatlands." +msgstr "Absolut begrænsning af fremkomstkøer" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "VSync" +msgstr "V-Sync" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Valley depth" +msgstr "Fyldstofdybde" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Varies steepness of cliffs." +msgstr "Varierer stejlhed af klipper." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Lydstyrke" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Aktiverer parallax-okklusionoversættelse.\n" +"Kræver at dybdeskabere er aktiveret." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Ganghastighed" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Vandstand" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Bølgende blade" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Bølgende blade" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Bølgende vand" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Bølgende blade" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Bølgende vand" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "Højdekomponent for den oprindelige vinduestørrelse." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "World start time" +msgstr "Verdens navn" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Y of upper limit of large caves." +msgstr "Absolut begrænsning af fremkomstkøer" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "cURL-tidsudløb" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Kreativ tilstand: " + +#~ msgid "- Damage: " +#~ msgstr "- Skade: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = parallax-okklusion med kurveinformation (hurtigere).\n" +#~ "1 = relief-oversættelse (langsommere, mere præcis)." + +#~ msgid "Address / Port" +#~ msgstr "Adresse/port" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Justér gammakodningen for lystabellerne. Et større tal betyder lysere.\n" +#~ "Denne indstilling gælder kun for klienten og ignoreres af serveren." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Er du sikker på, at du vil nulstille din enkelt spiller-verden?" + +#~ msgid "Back" +#~ msgstr "Tilbage" + +#~ msgid "Basic" +#~ msgstr "Grundlæggende" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bit per billedpunkt (a.k.a. farvedybde) i fuldskærmtilstand." + +#, fuzzy +#~ msgid "Bump Mapping" +#~ msgstr "Bump Mapping" + +#, fuzzy +#~ msgid "Bumpmapping" +#~ msgstr "Bumpmapping" + +#~ msgid "Config mods" +#~ msgstr "Konfigurér mods" + +#~ msgid "Configure" +#~ msgstr "Konfigurér" + +#~ msgid "Connect" +#~ msgstr "Forbind" + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Styrer bredden af tunneller. En lavere værdi giver bredere tunneller." + +#~ msgid "Credits" +#~ msgstr "Skabt af" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Crosshair-farve (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Skade aktiveret" + +#, fuzzy +#~ msgid "Darkness sharpness" +#~ msgstr "Søstejlhed" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Standardtidsudløb for cURL, angivet i millisekunder.\n" +#~ "Har kun effekt hvis kompileret med cURL." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Definerer sampling-trin for tekstur.\n" +#~ "En højere værdi resulterer i en mere rullende normale kort." + +#~ msgid "Del. Favorite" +#~ msgstr "Slet favorit" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Hent et spil, såsom Minetest Game fra minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Hent en fra minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Henter og installerer $1, vent venligst..." + +#~ msgid "Enable VBO" +#~ msgstr "Aktiver VBO" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Aktiverer bumpmapping for teksturer. Normalmaps skal være angivet af " +#~ "teksturpakken\n" +#~ "eller skal være automatisk oprettet.\n" +#~ "Kræver at dybdeskabere er aktiveret." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Aktiverer filmisk toneoversættelse" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Aktiverer løbende normalmap-oprettelse (Emboss-effekt).\n" +#~ "Kræver bumpmapping for at være aktiveret." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Aktiverer parallax-okklusionoversættelse.\n" +#~ "Kræver at dybdeskabere er aktiveret." + +#~ msgid "Enter " +#~ msgstr " " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Eksperimentelt tilvalg, kan medføre synlige mellemrum mellem blokke\n" +#~ "når angivet til et højere nummer end 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS i pausemenu" + +#~ msgid "Fallback font shadow" +#~ msgstr "Skygge for reserveskrifttypen" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Skyggealfa for reserveskrifttypen" + +#~ msgid "Fallback font size" +#~ msgstr "Størrelse for reserveskrifttypen" + +#~ msgid "Filtering" +#~ msgstr "Filtrering" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Alfa for skrifttypeskygge (uigennemsigtighed, mellem 0 og 255)." + +#, fuzzy +#~ msgid "FreeType fonts" +#~ msgstr "Freetype-skrifttyper" + +#~ msgid "Full screen BPP" +#~ msgstr "Fuldskærm BPP" + +#~ msgid "Game" +#~ msgstr "Spil" + +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#, fuzzy +#~ msgid "Generate Normal Maps" +#~ msgstr "Opret normalkort" + +#~ msgid "Generate normalmaps" +#~ msgstr "Opret normalkort" + +#~ msgid "HUD scale factor" +#~ msgstr "HUD-skaleringsfaktor" + +#~ msgid "High-precision FPU" +#~ msgstr "Højpræcisions FPU" + +#~ msgid "IPv6 support." +#~ msgstr "Understøttelse af IPv6." + +#~ msgid "In-Game" +#~ msgstr "I-spil" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Installer mod: Fil: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Instrumentering" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Tastebindinger. (Hvis denne menu fucker op, fjern elementer fra minetest." +#~ "conf)" + +#, fuzzy +#~ msgid "Lava depth" +#~ msgstr "Dybde for stor hule" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Begrænsning af fremkomsten af forespørgsler på disk" + +#~ msgid "Main" +#~ msgstr "Hovedmenu" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "Hovedmenuskript" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "Får DirectX til at fungere med LuaJIT. Deaktiver hvis det giver problemer." + +#~ msgid "Menus" +#~ msgstr "Menuer" + +#~ msgid "Name / Password" +#~ msgstr "Navn/adgangskode" + +#~ msgid "Name/Password" +#~ msgstr "Navn/kodeord" + +#~ msgid "No" +#~ msgstr "Nej" + +#~ msgid "Ok" +#~ msgstr "Ok" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallax-okklusion" + +#, fuzzy +#~ msgid "Parallax occlusion scale" +#~ msgstr "Parallax-okklusion" + +#~ msgid "Player name" +#~ msgstr "Spillerens navn" + +#~ msgid "PvP enabled" +#~ msgstr "Spiller mod spiller aktiveret" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Nulstil spillerverden" + +#~ msgid "Select Package File:" +#~ msgstr "Vælg pakke fil:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Server/alene" + +#, fuzzy +#~ msgid "Shadow limit" +#~ msgstr "Skygge grænse" + +#, fuzzy +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Forskydning for skrifttypeskygge, hvis 0 så vil skygge ikke blive tegnet." + +#, fuzzy +#~ msgid "Special key" +#~ msgstr "Snigetast" + +#~ msgid "Start Singleplayer" +#~ msgstr "Enlig spiller" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "For at aktivere dybdeskabere skal OpenGL-driveren bruges." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Aktiver filmisk" + +#~ msgid "Yes" +#~ msgstr "Ja" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Du døde" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/de/minetest.po b/po/de/minetest.po new file mode 100644 index 0000000..36d47a7 --- /dev/null +++ b/po/de/minetest.po @@ -0,0 +1,8473 @@ +msgid "" +msgstr "" +"Project-Id-Version: German (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-24 09:24+0000\n" +"Last-Translator: Wuzzy <Wuzzy@disroot.org>\n" +"Language-Team: German <https://hosted.weblate.org/projects/minetest/minetest/" +"de/>\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Die ausgehende Chatwarteschlange leeren" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Leerer Befehl." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Zum Hauptmenü verlassen" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Ungültiger Befehl: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Befehl erteilt: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Online spielende Spieler auflisten" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Online-Spieler: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Die ausgehende Chatwarteschlange ist nun leer." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Dieser Befehl ist vom Server deaktiviert." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Wiederbeleben" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Sie sind gestorben" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Verfügbare Befehle:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Verfügbare Befehle: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Befehl nicht verfügbar: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Hilfe für Befehle erhalten" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"„.help <Befehl>“ benutzen, um mehr Informationen zu erhalten, oder „.help " +"all“ benutzen, um alles aufzulisten." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <Befehl>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<keine verfügbar>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "In einem Lua-Skript ist ein Fehler aufgetreten:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Ein Fehler ist aufgetreten:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Hauptmenü" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Erneut verbinden" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Der Server hat um eine Wiederverbindung gebeten:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "Eine neue $1-Version ist verfügbar" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "Client-Mods" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" +"Installierte Version: $1\n" +"Neue Version: $2\n" +"Besuchen Sie $3, um herauszufinden, wie man die neueste Version erhält und auf " +"dem neuesten Stand mit Features und Fehlerbehebungen bleibt." + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "Später" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "Niemals" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protokollversion stimmt nicht überein. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Der Server erfordert Protokollversion $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Der Server unterstützt die Protokollversionen von $1 bis $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "Webseite besuchen" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Wir unterstützen nur Protokollversion $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Wir unterstützen Protokollversionen zwischen $1 und $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "(Aktiviert, hat Fehler)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "(Nicht erfüllt)" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Abbrechen" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Abhängigkeiten:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Alle deaktivieren" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Modpack deaktivieren" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Alle aktivieren" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Modpack aktivieren" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Die Mod „$1“ konnte nicht aktiviert werden, da sie unzulässige Zeichen " +"enthält. Nur die folgenden Zeichen sind erlaubt: [a-z0-9_]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Mehr Mods finden" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Keine (optionalen) Abhängigkeiten" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Keine Spielbeschreibung verfügbar." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Keine notwendigen Abhängigkeiten" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Keine Beschreibung für das Modpack verfügbar." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Keine optionalen Abhängigkeiten" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Optionale Abhängigkeiten:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Speichern" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Weltname:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "Aktiviert" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "„$1“ existiert bereits. Wollen Sie es überschreiben?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$1 und $2 Abhängigkeiten werden installiert." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 von $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 laden herunter,\n" +"$2 warten" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 laden herunter…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 benötigte Abhängigkeiten konnten nicht gefunden werden." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 wird installiert und $2 Abhängigkeiten werden übersprungen." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Alle Pakete" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Bereits installiert" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Zurück zum Hauptmenü" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Basis-Spiel:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" +"ContentDB ist nicht verfügbar, wenn Minetest ohne cURL kompiliert wurde" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Herunterladen …" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Fehler beim Download von $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Spiele" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Installieren" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "$1 installieren" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Fehlende Abhängigkeiten installieren" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Installation: Nicht unterstützter Dateityp oder kaputtes Archiv" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mods" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Es konnten keine Pakete abgerufen werden" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Keine Treffer" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Keine Updates" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Nicht gefunden" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Überschreiben" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Bitte prüfen Sie, ob das Basis-Spiel korrekt ist." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Eingereiht" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Texturenpakete" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Deinstallieren" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Update" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Alle aktualisieren [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Mehr Informationen im Webbrowser anschauen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Eine Welt namens „$1“ existiert bereits" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Zusätzliches Gelände" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Höhenabkühlung" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Höhenabtrocknung" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Biomübergänge" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biome" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Hohlräume" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Höhlen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Erstellen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekorationen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "Development Test ist für Entwickler gedacht." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Verliese" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Flaches Gelände" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Schwebende Landmassen im Himmel" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Schwebeländer (experimentell)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Nicht-fraktales Gelände erzeugen: Ozeane und Untergrund" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Hügel" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Feuchte Flüsse" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Erhöht die Luftfeuchte um Flüsse" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "Ein Spiel installieren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "Ein anderes Spiel installieren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Seen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Niedrige Luftfeuchtigkeit und große Wärme erzeugen seichte oder " +"ausgetrocknete Flüsse" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Kartengenerator" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Kartengenerator-Flags" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Kartengeneratorspezifische Flags" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Berge" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Erosion" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Netzwerk aus Tunneln und Höhlen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Kein Spiel ausgewählt" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Reduziert die Wärme mit der Höhe" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Reduziert Luftfeuchtigkeit mit der Höhe" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Flüsse" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Flüsse auf Meeresspiegelhöhe" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Startwert (Seed)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Weicher Übergang zwischen Biomen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Strukturen, die auf dem Gelände auftauchen (keine Wirkung auf von v6 " +"erzeugte Bäume u. Dschungelgras)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" +"Strukturen, die auf dem Gelände auftauchen, üblicherweise Bäume und Pflanzen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Gemäßigt, Wüste" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Gemäßigt, Wüste, Dschungel" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Gemäßigt, Wüste, Dschungel, Tundra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Geländeoberflächenerosion" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Bäume und Dschungelgras" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Flusstiefe variieren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Sehr große Hohlräume tief im Untergrund" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Weltname" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Es sind keine Spiele installiert." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Sind Sie sicher, dass „$1“ gelöscht werden soll?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Löschen" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: Fehler beim Entfernen von „$1“" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: Ungültiger Pfad „$1“" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Die Welt „$1“ löschen?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Passw. bestätigen" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "$1 beitreten" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "Fehlender Name" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Name" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Passwort" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "Passwörter stimmen nicht überein" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "Registrieren" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Annehmen" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Modpack umbenennen:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Diesem Modpaket wurde in seiner modpack.conf ein expliziter Name vergeben, " +"der jede Umbennenung hier überschreiben wird." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Keine Beschreibung vorhanden)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2-D-Rauschen" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Einstellungsseite" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Durchsuchen" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "Inhalt: Spiele" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "Inhalt: Mods" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Deaktiviert" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Bearbeiten" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Aktiviert" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lückenhaftigkeit" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktaven" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Versatz" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Persistenz" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Bitte geben Sie eine gültige ganze Zahl ein." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Bitte geben Sie eine gültige Zahl ein." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Zurücksetzen" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Skalierung" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Suchen" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Verzeichnis auswählen" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Datei auswählen" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Techn. Bezeichnung zeigen" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Der Wert muss mindestens $1 sein." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Der Wert darf nicht größer als $1 sein." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X-Ausbreitung" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y-Ausbreitung" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z-Ausbreitung" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Absolutwert" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "Standardwerte" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "weich (eased)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Aktiviert)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "Mods von $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Fehler bei der Installation von $1 nach $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Modinstallation: Richtiger Modname für $1 konnte nicht gefunden werden" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Modinstallation: Geeigneter Verzeichnisname für Modpack $1 konnte nicht " +"gefunden werden" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Keine gültige Mod oder Modpack gefunden" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Fehler bei der Texturenpaket-Installation von $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Fehler bei der Spiel-Installation von $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Fehler bei der Mod-Installation von $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Fehler bei der Modpack-Installation von $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Lädt …" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Öffentliche Serverliste ist deaktiviert" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Versuchen Sie die öffentliche Serverliste neu zu laden und prüfen Sie Ihre " +"Internetverbindung." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Über" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktive Mitwirkende" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Aktiver Renderer:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Hauptentwickler" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Benutzerdatenverzeichnis öffnen" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Öffnet das Verzeichnis, welches die Welten, Spiele, Mods und\n" +"Texturenpakete des Benutzers enthält, im Datei-Manager." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Frühere Mitwirkende" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Ehemalige Hauptentwickler" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "Debug-Log teilen" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Onlineinhalte durchsuchen" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Inhalt" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Texturenpaket deaktivieren" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Information:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Installierte Pakete:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Keine Abhängigkeiten." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Keine Paketbeschreibung verfügbar" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Umbenennen" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Paket deinstallieren" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Texturenpaket benutzen" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Server veröffentlichen" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Bind-Adresse" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Kreativmodus" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Schaden einschalten" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Spiel hosten" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Server hosten" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Spiele aus ContentDB installieren" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Neu" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Keine Welt angegeben oder ausgewählt!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Spiel starten" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Mods auswählen" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Welt wählen:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Serverport" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Spiel starten" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adresse" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Clear" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Kreativmodus" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Schaden / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favoriten" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Inkompatible Server" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Spiel beitreten" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "Login" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Latenz" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Öffentliche Server" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Neu laden" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "Favorit entfernen" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Serverbeschreibung" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "(Spielunterstützung benötigt)" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3-D-Wolken" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Alle Einstellungen" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Kantenglättung:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Fenstergröße merken" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilinearer Filter" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Tastenbelegung" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Verbundenes Glas" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dynamische Schatten" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "Dynamische Schatten:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Schöne Blätter" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Hoch" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Niedrig" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Mittel" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap u. Aniso. Filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Kein Filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Kein Mipmapping" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Blöcke aufhellen" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Blöcke umranden" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Keine" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Undurchs. Blätter" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Undurchs. Wasser" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partikel" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Monitor:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Einstellungen" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shader" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shader (experimentell)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Shader (nicht verfügbar)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Einfache Blätter" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Weiches Licht" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Texturierung:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Dynamikkompression" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "Berührungsempfindlichkeit (px):" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Trilinearer Filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "Sehr hoch" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Sehr niedrig" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Wehende Blätter" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Flüssigkeitswellen" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Wehende Pflanzen" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "Verbindung abgebrochen (Protokollfehler?)." + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Zeitüberschreitung." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Fertig!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Blöcke initialisieren" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Initialisiere Blöcke …" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Lade Texturen …" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Shader erneuern …" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Verbindungsfehler (Zeitüberschreitung?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Spiel konnte nicht gefunden oder geladen werden: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Ungültige Spielspezifikationen" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Hauptmenü" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Keine Welt ausgewählt und keine Adresse angegeben. Nichts zu tun." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Der Spielername ist zu lang." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Bitte wählen Sie einen Namen!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Fehler beim Öffnen der angegebenen Passwortdatei: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Angegebener Weltpfad existiert nicht: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Für mehr Details siehe debug.txt." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Adresse: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Modus: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Öffentlich: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- Spielerkampf: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Servername: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Ein Serialisierungsfehler ist aufgetreten:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Zugriff verweigert. Grund: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Vorwärtsautomatik deaktiviert" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Vorwärtsautomatik aktiviert" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Blockgrenzen verborgen" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Blockgrenzen für alle Blöcke angezeigt" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Blockgrenzen für aktuellen Block angezeigt" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Blockgrenzen für Blöcke in Nähe angezeigt" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Kameraaktualisierung deaktiviert" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Kameraaktualisierung aktiviert" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" +"Blockgrenzen können nicht gezeigt werden (von Mod oder Spiel deaktiviert)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Passwort ändern" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Filmmodus deaktiviert" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Filmmodus aktiviert" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Client getrennt" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Clientseitige Skripte sind deaktiviert" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Mit Server verbinden …" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Verbindung aus unbekanntem Grund fehlgeschlagen" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Weiter" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Steuerung:\n" +"- %s: Vorwärts\n" +"- %s: Rückwärts\n" +"- %s: Nach links\n" +"- %s: Nach rechts\n" +"- %s: Springen/klettern\n" +"- %s: Graben/Schlagen\n" +"- %s: Bauen/Benutzen\n" +"- %s: Kriechen/runter\n" +"- %s: Gegenstand wegwerfen\n" +"- %s: Inventar\n" +"- Maus: Drehen/Umschauen\n" +"- Mausrad: Gegenstand wählen\n" +"- %s: Chat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Adresse konnte nicht aufgelöst werden: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Client erstellen …" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Erstelle Server …" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Debug-Infos und Profiler-Graph verborgen" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Debug-Infos angezeigt" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Debug-Infos, Profiler und Drahtgitter deaktiviert" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Standardsteuerung:\n" +"Kein Menü sichtbar:\n" +"- einmal antippen: Knopf betätigen\n" +"- doppelt antippen: bauen/benutzen\n" +"- Finger wischen: umsehen\n" +"Menü/Inventar sichtbar:\n" +"- doppelt antippen (außen):\n" +" -->schließen\n" +"- Stapel berühren, Feld berühren:\n" +" --> Stapel verschieben\n" +"- berühren u. ziehen, mit 2. Finger antippen\n" +" --> 1 Gegenstand ins Feld platzieren\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Unbegrenzte Sichtweite deaktiviert" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Unbegrenzte Sichtweite aktiviert" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "Fehler bei Erstellung des Clients: %s" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Hauptmenü" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Programm beenden" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Schnellmodus deaktiviert" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Schnellmodus aktiviert" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Schnellmodus aktiviert (Hinweis: Kein „fast“-Privileg)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Flugmodus deaktiviert" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Flugmodus aktiviert" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Flugmodus aktiviert (Hinweis: Kein „fly“-Privileg)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Nebel deaktiviert" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Nebel aktiviert" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Spielinfo:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Spiel pausiert" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Gehosteter Server" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Gegenstandsdefinitionen …" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Medien …" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Übersichtskarte momentan von Spiel oder Mod deaktiviert" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Mehrspieler" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Geistmodus deaktiviert" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Geistmodus aktiviert" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Geistmodus aktiviert (Hinweis: Kein „noclip“-Privileg)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Blockdefinitionen …" + +#: src/client/game.cpp +msgid "Off" +msgstr "Aus" + +#: src/client/game.cpp +msgid "On" +msgstr "Ein" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Nick-Bewegungsmodus deaktiviert" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Nick-Bewegungsmodus aktiviert" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profiler-Graph angezeigt" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Entfernter Server" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Adressauflösung …" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Herunterfahren …" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Einzelspieler" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Tonlautstärke" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Ton stummgeschaltet" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Tonsystem ist deaktiviert" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Tonsystem ist in diesem Build nicht unterstützt" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Ton nicht mehr stumm" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Auf dem Server läuft möglicherweise eine andere Version von %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" +"Verbindung konnte nicht zu %s aufgebaut werden, weil IPv6 deaktiviert ist" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Konnte nicht auf %s lauschen, weil IPv6 deaktiviert ist" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Sichtweite geändert auf %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Maximale Sichtweite erreicht: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Minimale Sichtweite erreicht: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Lautstärke auf %d%% gesetzt" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Drahtmodell aktiv" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zoom ist momentan von Spiel oder Mod deaktiviert" + +#: src/client/game.cpp +msgid "ok" +msgstr "OK" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Chat verborgen" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Chat angezeigt" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD verborgen" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD angezeigt" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profiler verborgen" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profiler angezeigt (Seite %d von %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Anwendungen" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Rücktaste" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Feststellt." + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Strg" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Runter" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Ende" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Erase OEF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Ausführen" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Hilfe" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Pos1" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME: Akzept." + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME: Konvert." + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME: Escape" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME: Moduswechsel" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME: Nonconvert" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Einfg" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Links" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Linke Taste" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Strg links" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menü links" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Umsch. links" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Win. links" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menü" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Mittlere Taste" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Ziffernblock *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Ziffernblock +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Ziffernblock -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Ziffernblock ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Ziffernblock /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Ziffernblock 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Ziffernblock 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Ziffernblock 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Ziffernblock 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Ziffernblock 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Ziffernblock 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Ziffernblock 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Ziffernblock 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Ziffernblock 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Ziffernblock 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Bild ab" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Bild auf" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Spielen" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Druck" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Eingabe" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Rechts" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Rechte Taste" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Strg rechts" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menü rechts" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Umsch. rechts" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Win. rechts" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Rollen" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Auswählen" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Umsch." + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Schlaf" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Druck" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Leertaste" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Hoch" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X-Knopf 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X-Knopf 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Übersichtskarte verborgen" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Übersichtskarte im Radarmodus, Zoom ×%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Übersichtskarte im Bodenmodus, Zoom ×%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Übersichtskarte im Texturmodus" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Fehler beim Öffnen der Webseite" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Öffne Webseite" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Fortsetzen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "„Aux1“ = runter" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Autovorwärts" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Auto-Springen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Rückwärts" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Blockgrenzen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Kamerawechsel" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Befehl" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsole" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Sicht verringern" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Leiser" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "2×Sprungtaste zum Fliegen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Wegwerfen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Vorwärts" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Sicht erhöhen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Lauter" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Springen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Taste bereits in Benutzung" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "Tastenbelegung." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Lokaler Befehl" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Stumm" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Nächst. Ggnstd." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Vorh. Ggnstd." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Weite Sicht" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Bildschirmfoto" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Schleichen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "HUD an/aus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Chat an/aus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Schnellmodus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Flugmodus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Nebel an/aus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Karte an/aus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Geistmodus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Nickbewegung" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "Taste drücken" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Ändern" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Neues Passwort" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Altes Passwort" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Passwörter stimmen nicht überein!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Zurück" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Stumm" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Tonlautstärke: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "de" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" +"Name ist nicht registriert. Um ein Konto auf diesem Server zu erstellen, " +"klicken Sie auf „Registrieren“" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "Name ist belegt. Bitte einen anderen Namen wählen" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Fixiert die Position des virtuellen Joysticks.\n" +"Falls deaktiviert, wird der virtuelle Joystick zur ersten berührten Position " +"zentriert." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Den virtuellen Joystick benutzen, um die „Aux1“-Taste zu " +"betätigen.\n" +"Falls aktiviert, wird der virtuelle Joystick außerdem die „Aux1“-Taste " +"drücken, wenn er sich außerhalb des Hauptkreises befindet." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z)-Versatz des Fraktals vom Weltmittelpunkt in Einheiten von „scale“.\n" +"Kann benutzt werden, um einen gewünschten Punkt nach (0, 0) zu\n" +"verschieben, um einen geeigneten Einstiegspunkt zu erstellen, oder,\n" +"um es zu ermöglichen, in einen gewünschten Punkt „hereinzuoomen“,\n" +"indem man „scale“ erhöht.\n" +"Die Standardeinstellung ist brauchbar für Mandelbrotmengen mit\n" +"Standardparametern, sie könnte jedoch Anpassungen für andere\n" +"Situationen benötigen.\n" +"Die Reichweite liegt grob zwischen -2 und 2. Mit „scale“ multiplizieren,\n" +"um einen Versatz in Blöcken zu erhalten." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z)-Skalierung des Fraktals in Blöcken.\n" +"Die tatsächliche Fraktalgröße wird 2 bis 3 mal größer sein.\n" +"Es können sehr große Zahlen gewählt werden, das\n" +"Fraktal muss nicht in die ganze Welt passen.\n" +"Erhöhen Sie diese Zahlen, um in die Details des Fraktals\n" +"„hereinzuzoomen“.\n" +"Der Standardwert ist eine vertikal zusammengestauchte Form,\n" +"welche geeignet für eine Insel ist; setzen Sie alle 3 Zahlen\n" +"gleich für die Reinform." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2-D-Rauschen, welches die Form/Größe von gezahnten Bergen steuert." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2-D-Rauschen, welches die Form/Größe von sanften Hügeln steuert." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2-D-Rauschen, welches die Form/Größe von Stufenbergen steuert." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" +"2-D-Rauschen, welches die Größe/Vorkommen von gezahnten Bergketten steuert." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2-D-Rauschen, welches die Größe/Vorkommen von sanften Hügeln steuert." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" +"2-D-Rauschen, welches die Größe/Vorkommen von Stufenbergketten steuert." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2-D-Rauschen, welches den Ort der Flusstäler und -kanäle regelt." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3-D-Wolken" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3-Dimensionaler-Modus" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "3-D-Modus-Parallaxstärke" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3-D-Rauschen, welches riesige Hohlräume definiert." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3-D-Rauschen, welches Bergformationen- und Höhe\n" +"definiert. Außerdem definiert dies die Formationen\n" +"der Berge in den Schwebeländern." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"3-D-Rauschen, das die Form von Schwebeländern definiert.\n" +"Falls vom Standardwert verschieden, müsste der Rauschwert „Skalierung“\n" +"(standardmäßig 0.7) evtl. angepasst werden, da die Schwebeland-\n" +"zuspitzung am Besten funktioniert, wenn dieses Rauschen\n" +"einen Wert zwischen etwa -2.0 bis 2.0 hat." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" +"3-D-Rauschen, welches die Form von Erdwällen von Flusscanyons definiert." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3-D-Rauschen, welches das Terrain definiert." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"3-D-Rauschen für Bergüberhänge, Klippen, usw. Üblicherweise kleine " +"Variationen." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3-D-Rauschen, welches die Anzahl der Verliese je Mapchunk festlegt." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3-D-Unterstützung.\n" +"Aktuell verfügbar:\n" +"- none: Keine 3-D-Ausgabe.\n" +"- anaglyph: Türkises / magenta 3-D.\n" +"- interlaced: Bildschirmunterstützung für gerade / ungerade " +"zeilenbasierte Polarisation.\n" +"- topbottom: Bildschirm horizontal teilen.\n" +"- sidebyside: Bildschirm vertikal teilen.\n" +"- crossview: Schieläugiges 3-D\n" +"- pageflip: Quadbuffer-basiertes 3-D.\n" +"Beachten Sie, dass der „interlaced“-Modus erfordert, dass Shader aktiviert " +"sind." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "3-D" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Ein festgelegter Kartengenerator-Seed für neue Welten. Leer lassen für " +"zufällige Erzeugung.\n" +"Wird überschrieben, wenn die Welt im Menü erstellt wird." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" +"Eine Nachricht, die an alle verbundenen Clients versendet wird, wenn der " +"Server abstürzt." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Eine Nachricht, die an alle verbundene Clients gesendet wird, wenn der " +"Server\n" +"herunterfährt." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "ABM-Intervall" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "ABM-Zeitbudget" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Absolute Grenze der zu erzeugenden Kartenblöcke in Warteschlange" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Beschleunigung in der Luft" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Beschleunigung der Schwerkraft, in Blöcken pro Sekunde pro Sekunde." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Active Block Modifiers" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Active-Block-Management-Intervall" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Reichweite aktiver Kartenblöcke" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Reichweite aktiver Objekte" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Adresse, mit der verbunden werden soll.\n" +"Leer lassen, um einen lokalen Server zu starten.\n" +"Die Adresse im Hauptmenü überschreibt diese Einstellung." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Zeigt Partikel, wenn man einen Block ausgräbt." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "DPI des Bildschirms (nicht für X11/Android) z.B. für 4K-Bildschirme." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Die erfasste Anzeigendichte anpassen, benutzt für die Skalierung von UI-" +"Elementen." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Passt die Dichte der Schwebelandebene an.\n" +"Wert erhöhen, um die Dichte zu erhöhen. Kann positiv oder negativ sein.\n" +"Wert = 0.0: 50% des Volumens sind Schwebeländer.\n" +"Wert = 2.0 (kann abhängig von „mgv7_np_floatland“ höher sein, solle man\n" +"immer testen, um sicher zu sein) erzeugt eine durchgehende\n" +"Schwebelandebene." + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "Admin-Name" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Erweitert" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Passt die Lichtkurve an, indem eine sog. Gammakorrektur\n" +"an ihr vorgenommen wird. Höhere Werte können mittlere\n" +"und niedrigere Lichtstufen heller machen. Der Wert „1.0“\n" +"lässt die Lichtkurve unverändert.\n" +"Das hat nur einen merkliche Wirkung auf das Tageslicht und\n" +"dem künstlichem Licht, es hat sehr geringe Auswirkungen\n" +"auf natürliches Licht bei Nacht." + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "Immer schnell fliegen" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Umgebungsverdeckungs-Gamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" +"Anzahl der Nachrichten, die ein Spieler innerhalb 10 Sekunden senden darf." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Verstärkt die Täler." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Anisotroper Filter" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Server ankündigen" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Zu dieser Serverliste ankündigen." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Gegenstandsnamen anhängen" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Gegenstandsnamen an Tooltip anhängen." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Apfelbaumrauschen" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Armträgheit" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Armträgheit, ergibt eine realistischere Bewegung\n" +"des Arms, wenn sich die Kamera bewegt." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Abfrage zum Neuverbinden nach Absturz" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"In dieser Distanz wird der Server die zu den Clients gesendeten Blöcke " +"aggressiv\n" +"optimieren.\n" +"Kleine Werte werden die Performanz möglicherweise stark erhöhen, auf\n" +"Kosten von sichtbaren Renderfehlern (einige Blöcke werden nicht unter dem " +"Wasser\n" +"und in Höhlen gerendert, sowie manchmal auf dem Land).\n" +"Wird dieser Wert auf eine Zahl größer als max_block_send_distance gesetzt,\n" +"wird diese Optimierung deaktiviert.\n" +"In Kartenblöcken (16 Blöcke) angegeben." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "Ton" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Vorwärtsautomatiktaste" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Automatisch bei 1 Block hohen Hindernissen springen." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Automatisch bei der Serverliste melden." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Monitorgröße merken" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Autoskalierungsmodus" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Aux1-Taste" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Aux1-Taste zum Klettern/Sinken" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Rückwärtstaste" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Basisbodenhöhe" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Basisgeländehöhe." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Grundprivilegien" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Strandrauschen" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Strandrauschschwellwert" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilinearer Filter" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Bind-Adresse" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "Biom-API-Rauschparameter" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Biomrauschen" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Distanz für Sendeoptimierungen von Kartenblöcken" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "Wackeln" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Pfad der Fett- und Kursivschrift" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Pfad der fetten und kursiven Festbreitenschrift" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Pfad der Fettschrift" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Pfad der fetten Festbreitenschrift" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Innerhalb des Spielers bauen" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Builtin" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "Kamera" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Distanz von der Kamera zur vorderen Clippingebene in Blöcken, zwischen 0 und " +"0.25.\n" +"Funktioniert nur auf GLES-Plattformen. Die meisten Benutzer müssen dies " +"nicht ändern.\n" +"Eine Erhöhung dieses Wertes kann Artefakte auf schwächeren GPUs reduzieren.\n" +"0.1 = Standard, 0.25 = Guter Wert für schwächere Tablets." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Kameraglättung" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Kameraglättung im Filmmodus" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Taste zum Umschalten der Kameraaktualisierung" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Höhlenrauschen" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Höhlenrauschen Nr. 1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Höhlenrauschen Nr. 2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Höhlenbreite" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Höhlenrauschen Nr. 1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Höhlenrauschen Nr. 2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Hohlraumgrenze" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Hohlraumrauschen" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Hohlraumzuspitzung" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Hohlraumschwellwert" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Hohlraumobergrenze" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Mittelpunkt des Lichtkurvenverstärkungsintervalls.\n" +"Wobei 0.0 die minimale Lichtstufe und 1.0 die höchste Lichtstufe ist." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Chatbefehlzeitnachrichtenschwellwert" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Chatbefehle" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Chat-Schriftgröße" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Chattaste" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Chatprotokollausgabelevel" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Max. Anzahl Chatnachrichten" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Chatnachrichtenformat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Chatnachrichten-Kick-Schwellwert" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Max. Chatnachrichtenlänge" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Taste zum Umschalten des Chatprotokolls" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Chatweblinks" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Chunk-Größe" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Filmmodus" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Filmmodustaste" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Transparente Texturen säubern" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Anklickbare Weblinks (Mittelklick oder Strg+Linksklick) werden in der " +"Chatkonsolenausgabe aktiviert." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Client" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Client und Server" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Client-Modding" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Client-Modding-Einschränkungen" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Distanzlimit für clientseitige Block-Definitionsabfrage" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "Clientseitiges Modding" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Klettergeschwindigkeit" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Wolkenradius" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Wolken" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Wolken sind ein clientseitiger Effekt." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Wolken im Menü" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Gefärbter Nebel" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Gefärbte Schatten" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Kommagetrennte Liste von Flags für Dinge, die im Inhaltespeicher verborgen " +"werden sollten.\n" +"„nonfree“ kann benutzt werden, um Pakete, die nicht als „freie Software“ " +"nach\n" +"der Definition der Free Software Foundation gelten, zu verbergen.\n" +"Sie können auch Inhaltseinstufungen festlegen.\n" +"Diese Flags sind von Minetestversionen unabhängig,\n" +"für eine vollständige Liste gehen Sie auf:\n" +"https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Kommagetrennte Liste von Mods, welche auf HTTP-APIs zugreifen dürfen, was\n" +"es ihnen erlaubt, Daten aus und Daten zum Internet herunter- und hochzuladen." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Kommagetrennte Liste der Mods, denen Sie vertrauen. Vertrauten Mods ist es " +"erlaubt,\n" +"unsichere Funktionen zu verwenden, sogar dann, wenn Modsicherheit " +"eingeschaltet ist\n" +"(mit request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Befehlstaste" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Zu verwendendes Kompressionsniveau, wenn Kartenblöcke auf den Datenträger " +"gespeichert werden.\n" +"-1 - Standard-Kompressionsniveau benutzen\n" +"0 - geringste Kompression, am schnellsten\n" +"9 - beste Kompression, am langsamsten" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Kompressionsniveau für Kartenblöcke, die zu Clients gesendet werden.\n" +"-1 - Standard-Kompressionsniveau benutzen\n" +"0 - keine Kompression, am schnellsten\n" +"9 - beste Kompression, am langsamsten" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Verbundenes Glas" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Zu externen Medienserver verbinden" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Verbindet Glas, wenn der Block dies unterstützt." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Konsolenundurchsichtigkeit" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Konsolenfarbe" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Konsolenhöhe" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "Inhaltespeicher" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "ContentDB: Schwarze Liste" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "ContentDB Max. gleichzeitige Downloads" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "ContentDB-URL" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Kontinuierliche Vorwärtsbewegung" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Beständige Vorwärtsbewegung, umgeschaltet von der Vorwärtsautomatiktaste.\n" +"Drücken Sie die Vorwärtsautomatiktaste erneut, oder die Rückwärtstaste zum " +"Deaktivieren." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Steuerung" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Verändert die Länge des Tag-Nacht-Zyklus.\n" +"Beispiele:\n" +"72 = 20min, 360 = 4min, 1 = 24h, 0 = Tag/Nacht/was auch immer bleibt " +"unverändert." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" +"Beeinflusst die Sinkgeschwindigkeit in der Flüssigkeit, wenn man sich nicht " +"bewegt.\n" +"Negative Werte werden Sie stattdessen aufsteigen lassen." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Steuert die Steilheit/Tiefe von Seesenken." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Steuert die Steilheit/Höhe von Hügeln." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Passt die Breite von Tunneln an. Ein kleinerer Wert erzeugt breitere\n" +"Tunnel. Ein Wert >= 10.0 deaktiviert die Erzeugung von Tunneln vollständig\n" +"und verhindert rechenintensive Rauschberechnungen." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Absturzmeldung" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Kreativ" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Fadenkreuzundurchsichtigkeit" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Fadenkreuz-Alpha (Undurchsichtigkeit, zwischen 0 und 255).\n" +"Gilt auch für das Objektfadenkreuz." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Fadenkreuzfarbe" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Fadenkreuzfarbe (R,G,B).\n" +"Gilt auch für das Objektfadenkreuz" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Schaden" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Taste zum Umschalten der Debug-Info" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Debugprotokolldateigrößengrenze" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Debugausgabelevel" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "Debugging" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Leiser-Taste" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Taktung dedizierter Server" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Standardbeschleunigung" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Standardspiel" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Standardspiel beim Erstellen einer neuen Welt.\n" +"Diese Einstellung wird nicht genutzt, wenn die Welt im Hauptmenü erstellt " +"wird." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Standardpasswort" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Standardprivilegien" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Standard-Berichtsformat" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Standardstapelgröße" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Definiert die Schattenfilterqualität.\n" +"Dies simuliert den weichen Schatteneffekt, indem eine PCF- oder Poisson-" +"Scheibe angewendet wird,\n" +"aber dies verbraucht auch mehr Ressourcen." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Definiert Gebiete, in denen Bäume Äpfel tragen." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Definiert Gebiete mit Sandstränden." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" +"Definiert die Verteilung von erhöhtem Gelände und die Steilheit von Klippen." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Definiert die Verteilung von erhöhtem Gelände." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Definiert die volle Größe von Hohlräumen, kleinere Werte erzeugen\n" +"größere Hohlräume." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Definiert große Flusskanalformationen." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Definiert Ort und Gelände der optionalen Hügel und Seen." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Definiert die Basisgeländehöhe." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Definiert die Tiefe des Flusskanals." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Setzt die maximale Distanz, in der die Spieler übertragen werden,\n" +"in Kartenblöcken (0 = unbegrenzt)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Definiert die Breite des Flusskanals." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Definiert die Breite des Flusstals." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Definiert Baumgebiete und Baumdichte." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Zeitabstand zwischen Mesh-Updates auf dem Client in ms. Wenn dieser Wert\n" +"erhöht wird, wird die Rate der Mesh-Updates verringert, was das Stottern " +"auf\n" +"langsameren Clients reduziert." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Verzögerung beim Senden von Blöcken nach dem Bauen" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Verzögerung beim Zeigen von Tooltipps, in Millisekunden." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Veraltete Lua-API-Handhabung" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Tiefe, unter der man große Höhlen finden wird." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Tiefe, unter der man große Höhlen finden wird." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Die Beschreibung des Servers. Wird neuen Clients und in der Serverliste " +"angezeigt." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Wüstenrauschschwellwert" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Wüsten treten auf, wenn np_biome diesen Wert überschreitet.\n" +"Falls das „snowbiomes“-Flag aktiviert ist, wird dies ignoriert." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Blockanimationen desynchronisieren" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "Entwickleroptionen" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Grabetaste" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Grabepartikel" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Anti-Cheat deaktivieren" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Leere Passwörter verbieten" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Anzeigendichtenskalierungsfaktor" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" +"Entfernung in Nodes, bei welcher die Transparenztiefensortierung aktiviert " +"ist.\n" +"Dies benutzen, um die Performanzeinbußen der Transparenztiefensortierung zu " +"begrenzen" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Domainname des Servers. Wird in der Serverliste angezeigt." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "2×Sprungtaste zum Fliegen" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Doppelttippen der Sprungtaste schaltet Flugmodus um." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Wegwerfen-Taste" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Die Kartengenerator-Debuginformationen auf Konsole ausgeben." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Verlies: Max. Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Verlies: Min. Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Verliesrauschen" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"IPv6-Unterstützung aktivieren (sowohl für Client als auch Server).\n" +"Benötigt, damit IPv6-Verbindungen funktionieren." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Lua-Modding-Unterstützung auf dem Client aktivieren.\n" +"Diese Unterstützung ist experimentell und die API kann sich ändern." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Aktiviert eine Poisson-Scheibenfilterung.\n" +"Falls aktiv, werden Poisson-Scheiben verwendet, um „weiche Schatten“ zu " +"erzeugen. Ansonsten wird die PCF-Filterung benutzt." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Aktiviert gefärbte Schatten. \n" +"Falls aktiv, werden transluzente Blöcke gefärbte Schatten werfen. Dies ist " +"rechenintensiv." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Konsolenfenster aktivieren" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Kreativmodus für alle Spieler aktivieren" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Joysticks aktivieren" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "Aktiviert Joysticks. Benötigt einen Neustart, um wirksam zu werden" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Modkanäle-Unterstützung aktivieren." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Modsicherheit aktivieren" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Spielerschaden und -tod aktivieren." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Schaltet zufällige Steuerung ein (nur zum Testen verwendet)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Weiches Licht mit einfacher Ambient-Occlusion aktivieren.\n" +"Für bessere Performanz oder anderes Aussehen deaktivieren." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "Login und Registrierung trennen" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Aktivieren, um alten Clients die Verbindung zu verwehren.\n" +"Ältere Clients sind kompatibel in der Hinsicht, dass sie beim Verbinden zu " +"neuen\n" +"Servern nicht abstürzen, aber sie könnten nicht alle neuen Funktionen, die " +"Sie\n" +"erwarten, unterstützen." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Aktiviert die Benutzung eines entfernen Medienservers (falls vom Server " +"angeboten).\n" +"Entfernte Server bieten eine deutlich schnellere Methode, um Medien (z.B. " +"Texturen)\n" +"während des Verbindungsaufbaus zum Server herunterzuladen." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Aktiviert Vertex Buffer Objects.\n" +"Dies sollte die Grafikperformanz beträchtlich verbessern." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Hiermit aktiviert man die Auf- und Abbewegung\n" +"der Ansicht und legt außerdem die Stärke des Effekts fest.\n" +"Zum Beispiel: 0 für keine Auf- und Abbewegung,\n" +"1.0 für den Standardwert, 2.0 für doppelte Geschwindigkeit." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Server als IPv6 laufen lassen (oder nicht).\n" +"Wird ignoriert, falls bind_address gesetzt ist.\n" +"Dafür muss außerdem enable_ipv6 aktiviert sein." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Aktiviert filmische Dynamikkompression wie in Hables „Uncharted 2“.\n" +"Simuliert die Tonkurve von fotografischem Film und wie dies das Aussehen\n" +"von „High Dynamic Range“-Bildern annähert. Mittlerer Kontrast wird leicht\n" +"verstärkt, aufleuchtende Bereiche und Schatten werden graduell komprimiert." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Aktiviert die Animation von Inventargegenständen." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" +"Aktiviert das Zwischenspeichern von 3-D-Modellen, die mittels facedir " +"rotiert werden." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Aktiviert die Übersichtskarte." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Aktiviert das Tonsystem.\n" +"Falls deaktiviert, wird es alle Geräusche überall abschalten und\n" +"die Tonsteuerung im Spiel wird funktionslos sein.\n" +"Die Änderung dieser Einstellung benötigt einen Neustart." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Aktiviert Kompromisse, die die CPU-Last verringern oder die Rendering-" +"Leistung erhöhen\n" +"auf Kosten kleinerer visueller Fehler, die die Spielbarkeit nicht " +"beeinträchtigen." + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "Engine-Profiler" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Engine-Profiling-Datenausgabeintervall" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Entity-Methoden" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Exponent der Schwebelandzuspitzung. Passt das Zuspitzungverhalten an.\n" +"Wert = 1.0 erzeugt eine einheitliche lineare Zuspitzung.\n" +"Werte > 1.0 erzeugen eine weiche Zuspitzung, die für die standardmäßig\n" +"getrennten Schwebeländer geeignet sind.\n" +"Werte < 1.0 (z.B. 0.25) erzeugen eine bestimmtere Oberflächenhöhe mit\n" +"flacheren Tiefländern; dies ist für eine durchgehende Schwebelandebene\n" +"geeignet." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "Bildwiederholrate" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" +"Maximale Bildwiederholrate, während das Spiel pausiert oder nicht fokussiert " +"ist" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Faktorrauschen" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Kamerawackeln beim Sturz" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Ersatzschriftpfad" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Schnelltaste" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Schnellmodusbeschleunigung" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Schnellmodusgeschwindigkeit" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Schnell bewegen" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Schnelle Bewegung (mit der „Aux1“-Taste).\n" +"Dazu wird das „fast“-Privileg auf dem Server benötigt." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Sichtfeld" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Sichtfeld in Grad." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Datei in client/serverlist/, die Ihre Serverfavoriten enthält, die im\n" +"Registerkartenreiter „Mehrspieler“ angezeigt werden." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Fülltiefe" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Fülltiefenrauschen" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Filmische Dynamikkompression" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Gefilterte Texturen können RGB-Werte mit voll transparenten Nachbarn,\n" +"die PNG-Optimierer üblicherweise verwerfen, mischen. Manchmal\n" +"resultiert dies in einer dunklen oder hellen Kante bei transparenten\n" +"Texturen. Aktivieren Sie einen Filter, um dies beim Laden der\n" +"Texturen aufzuräumen. Dies wird automatisch aktiviert, falls Mipmapping " +"aktiviert ist." + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "Filter und Antialiasing" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Das erste von vier 2-D-Rauschen, welche gemeinsam Hügel-/Bergkettenhöhe " +"definieren." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Das erste von zwei 3-D-Rauschen, welche gemeinsam Tunnel definieren." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Fester Karten-Seed" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Fester virtueller Joystick" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Schwebelanddichte" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Schwebeland: Max. Y" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Schwebeland: Min. Y" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Schwebelandrauschen" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Schwebelandzuspitzexponent" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Schwebelandzuspitzdistanz" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Schwebelandwasserhöhe" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Flugtaste" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Fliegen" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Nebel" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Nebelbeginn" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Taste für Nebel umschalten" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "Schrift" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Schrift standardmäßig fett" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Schrift standardmäßig kursiv" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Schriftschatten" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Schriftschatten-Undurchsichtigkeit" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Schriftgröße" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Schriftgröße teilbar durch" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Schriftgröße der Standardschrift, wobei 1 Einheit = 1 Pixel bei 96 DPI" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" +"Schriftgröße der Festbreitenschrift, wobei 1 Einheit = 1 Pixel bei 96 DPI" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Schriftgröße für den Chattext (für neue Chatnachrichten) und\n" +"der Chateingabe in Punkt (pt).\n" +"Der Wert 0 wird die Standardschriftgröße benutzen." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"Bei Schriften im Pixelstil, die sich nicht gut skalieren lassen, stellt dies " +"sicher,\n" +"dass die mit dieser Schrift verwendeten Schriftgrößen immer durch diesen " +"Wert\n" +"in Pixeln teilbar ist. Zum Beispiel: Eine Pixelschrift mit einer Höhe von 16 " +"Pixeln\n" +"sollte auf 16 gesetzt werden, so dass sie immer nur die Größe 16, 32, 48 " +"usw. hat,\n" +"damit eine Mod, die eine Größe von 25 anfordert, 32 erhält." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Format der Spielerchatnachrichten. Die folgenden Zeichenketten sind gültige " +"Platzhalter:\n" +"@name, @message, @timestamp (optional)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Dateiformat von Bildschirmfotos." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Formspec-Standardhintergrundfarbe" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Formspec-Standardhintergrundundurchsichtigkeit" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Formspec-Vollbildhintergrundfarbe" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Formspec-Vollbildhintergrundundurchsichtigkeit" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Standardhintergrundfarbe (R,G,B) von Formspecs." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" +"Standard-Undurchsichtigkeit des Hintergrundes von Formspecs (zwischen 0 und " +"255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Hintergrundfarbe von Vollbild-Formspecs (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" +"Undurchsichtigkeit des Hintergrundes von Vollbild-Formspecs (zwischen 0 und " +"255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Vorwärtstaste" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Das vierte von vier 2-D-Rauschen, welche gemeinsam Hügel-/Bergkettenhöhe " +"definieren." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Fraktaltyp" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" +"Anteil der sichtbaren Entfernung, in welcher begonnen wird, den Nebel zu " +"rendern" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Maximale Entfernung, in der Kartenblöcke für Clients erzeugt werden, in\n" +"Kartenblöcken (16 Blöcke) angegeben." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Maximale Entfernung, in der Kartenblöcke zu Clients gesendet werden, in\n" +"Kartenblöcken (16 Blöcke) angegeben." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Von wie weit her Clients über Objekte wissen, in Kartenblöcken (16 Blöcke)\n" +"angegeben.\n" +"\n" +"Wird dieser Wert größer als active_block_range angegeben, wird dies außer-\n" +"dem den Server dazu veranlassen, aktive Objekte bis zu dieser Distanz in " +"der\n" +"Richtung, in die der Spieler blickt, zu verwalten. (Dies kann verhindern, " +"dass\n" +"Mobs plötzlich aus der Sicht verschwinden.)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Vollbild" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Vollbildmodus." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "GUI-Skalierung" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "GUI-Skalierfilter" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "GUI-Skalierungsfilter txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "GUIs" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "Gamepads" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "Allgemein" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Globale Rückruffunktionen" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Globale Kartengenerierungsattribute.\n" +"Im Kartengenerator v6 wird das „decorations“-Flag alle Dekorationen außer\n" +"Bäume und Dschungelgras beinflussen, in allen anderen Kartengeneratoren\n" +"wird es alle Dekorationen beinflussen." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Steigung der Lichtkurve an der maximalen Lichtstufe.\n" +"Regelt den Kontrast der höchsten Lichtstufen." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Steigung der Lichtkurve an der minimalen Lichtstufe.\n" +"Regelt den Kontrast der niedrigsten Lichtstufen." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafik" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "Grafikeffekte" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "Grafik und Ton" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravitation" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Bodenhöhe" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Bodenrauschen" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP-Mods" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "HUD" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "HUD-Skalierung" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Taste zum Umschalten des HUD" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Handhabung für veraltete Lua-API-Aufrufe:\n" +"- none: Veraltete Aufrufe nicht protokollieren.\n" +"- log: Imitieren und den Backtrace des veralteten Funktionsaufrufs " +"protokollieren\n" +" (Standard).\n" +"- error: Bei Verwendung eines veralteten Funktionsaufrufs abbrechen\n" +" (empfohlen für Mod-Entwickler)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Den Profiler sich selbst instrumentieren lassen:\n" +"* Instrumentiert eine leere Funktion.\n" +"Dies schätzt den Overhead, der von der Instrumentierung\n" +"hinzugefügt wird, ab (+1 Funktionsaufruf).\n" +"* Instrumentiert die Abtastfunktion, die zur Aktualisierung der Statistiken " +"benutzt wird." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Hitzenübergangsrauschen" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Hitzenrauschen" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Höhenkomponente der anfänglichen Fenstergröße. Im Vollbildmodus ignoriert." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Höhenrauschen" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Höhenauswahlrauschen" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Hügelsteilheilt" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Hügelschwellwert" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Steilheitsrauschen 1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Steilheitsrauschen 2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Steilheitsrauschen 3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Steilheitsrauschen 4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Homepage des Servers. Wird in der Serverliste angezeigt." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Horizontale Beschleunigung in der Luft beim Springen oder Fallen,\n" +"in Blöcken pro Sekunde pro Sekunde." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Horizontale und vertikale Beschleunigung im Schnellmodus,\n" +"in Blöcken pro Sekunde pro Sekunde." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Horizontale und vertikale Beschleunigung auf dem Boden oder beim Klettern,\n" +"in Blöcken pro Sekunde pro Sekunde." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Taste für nächsten Ggnstd. in Schnellleiste" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Taste für vorherigen Ggnstd. in Schnellleiste" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Schnellleistentaste 1" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Schnellleistentaste 10" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Schnellleistentaste 11" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Schnellleistentaste 12" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Schnellleistentaste 13" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Schnellleistentaste 14" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Schnellleistentaste 15" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Schnellleistentaste 16" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Schnellleistentaste 17" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Schnellleistentaste 18" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Schnellleistentaste 18" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Schnellleistentaste 2" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Schnellleistentaste 20" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Schnellleistentaste 21" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Schnellleistentaste 22" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Schnellleistentaste 23" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Schnellleistentaste 24" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Schnellleistentaste 25" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Schnellleistentaste 26" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Schnellleistentaste 27" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Schnellleistentaste 28" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Schnellleistentaste 29" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Schnellleistentaste 3" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Schnellleistentaste 30" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Schnellleistentaste 31" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Schnellleistentaste 32" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Schnellleistentaste 4" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Schnellleistentaste 5" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Schnellleistentaste 6" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Schnellleistentaste 7" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Schnellleistentaste 8" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Schnellleistentaste 9" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Wie tief Flüsse gemacht werden sollen." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Wie schnell sich Flüssigkeitswellen bewegen werden. Höher = schneller.\n" +"Falls negativ, werden sich die Wellen rückwärts bewegen.\n" +"Hierfür müssen Flüssigkeitswellen aktiviert sein." + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Wie lange der Server warten wird, bevor nicht mehr verwendete Kartenblöcke " +"entladen werden, in Sekunden.\n" +"Ein höher Wert wird das Programm flüssiger laufen lassen, aber auch mehr " +"Arbeitsspeicher benutzen." + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" +"Wie stark man bei der Bewegung in einer Flüssigkeit verlangsamt wird.\n" +"Dies verringern, um den Bewegungswiderstand in Flüssigkeiten zu erhöhen." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Wie breit Flüsse gemacht werden sollen." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Luftfeuchtigkeitsübergangsrauschen" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Luftfeuchtigkeitsrauschen" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Luftfeuchtigkeitsvariierung für Biome." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6-Server" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Falls die Bildwiederholrate diesen Wert überschreitet,\n" +"wird sie durch Nichtstun begrenzt, um die CPU nicht\n" +"unnötig zu belasten." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Falls deaktiviert, wird die „Aux1“-Taste benutzt, um schnell zu fliegen,\n" +"wenn sowohl Flug- als auch Schnellmodus aktiviert sind." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Falls aktiviert, wird der Server Occlusion Culling für Kartenblöcke " +"basierend\n" +"auf der Augenposition des Spielers anwenden. Dadurch kann die Anzahl\n" +"der Kartenblöcke, die zum Client gesendet werden, um 50-80% reduziert\n" +"werden. Der Client wird nicht mehr die meisten unsichtbaren Kartenblöcke\n" +"empfangen, was den Nutzen vom Geistmodus reduziert." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Falls es aktiviert ist, kann der Spieler im Flugmodus durch feste Blöcke " +"fliegen.\n" +"Dafür wird das „noclip“-Privileg auf dem Server benötigt." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Falls aktiviert, wird die „Aux1“-Taste statt der „Schleichen“-Taste zum\n" +"Herunterklettern und Sinken benutzt." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Falls aktiviert, wird die Kontoregistrierung vom Einloggen in der " +"Benutzeroberfläche getrennt behandelt.\n" +"Falls deaktiviert, werden neue Konten beim Einloggen automatisch registriert." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Falls aktiviert, werden Aktionen für die Rollback-Funktion aufgezeichnet.\n" +"Diese Einstellung wird nur beim Starten des Servers gelesen." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" +"Wenn diese Einstellung aktiviert ist, werden die Anti-Cheat-Maßnahmen " +"deaktiviert." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Falls aktiviert, werden ungültige Weltdaten den Server nicht dazu\n" +"veranlassen, sich zu beenden.\n" +"Aktivieren Sie dies nur, wenn Sie wissen, was sie tun." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Falls aktiviert, werden Bewegungsrichtungen relativ zum Nick des Spielers " +"beim Fliegen oder Schwimmen sein." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Falls aktiviert, können neue Spieler nicht ohne ein Passwort beitreten oder " +"ihr Passwort zu ein leeres Passwort ändern." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Falls aktiviert, können Sie Blöcke an der Position (Füße u. Augenhöhe), auf " +"der Sie\n" +"stehen, platzieren. Dies ist hilfreich, wenn mit „Nodeboxen“ auf engen Raum\n" +"gearbeitet wird." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Falls die CSM-Einschränkung für Blockreichweite aktiviert ist, werden\n" +"get_node-Aufrufe auf diese Distanz vom Spieler zum Block begrenzt sein." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Falls die Ausführung eines Chatbefehls länger als diese angegebene Zeit in\n" +"Sekunden braucht, wird die Zeitinformation an die Chatbefehlsnachricht " +"angehängt" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Falls die Dateigröße von debug.txt die Anzahl an in dieser Einstellung " +"festgelegten Megabytes überschreitet, wenn die Datei geöffnet wird, wird sie " +"nach debug.txt.1 verschoben, wobei eine ältere debug.txt.1 gelöscht wird, " +"falls sie existiert.\n" +"debug.txt wird nur verschoben, falls diese Einstellung positiv ist." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" +"Falls dies gesetzt ist, werden Spieler immer an der gegebenen\n" +"Position im Spiel einsteigen bzw. nach dem Tod wieder einsteigen." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Weltfehler ignorieren" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Undurchsichtigkeit des Hintergrundes der Chat-Konsole im Spiel (Wert " +"zwischen 0 und 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Hintergrundfarbe (R,G,B) der Chat-Konsole im Spiel." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"Chatkonsolenhöhe im Spiel, zwischen 0.1 (10%) und 1.0 (100%).\n" +"(Beachten Sie die englische Notation mit Punkt als Dezimaltrennzeichen.)" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Lauter-Taste" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" +"Anfängliche vertikale Geschwindigkeit beim Springen, in Blöcken pro Sekunde." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"„builtin“ instrumentieren.\n" +"Dies wird normalerweise nur von Haupt-/builtin-Entwicklern benötigt" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "Chatbefehle bei ihrer Registrierung instrumentieren." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Globale Rückruffunktionen bei ihrer Registrierung instrumentieren\n" +"(alles, was man einer Funktion wie minetest.register_*() übergibt)." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Die action-Funktion von Active-Block-Modifiers bei ihrer Registrierung " +"instrumentieren." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Die action-Funktion von Loading-Block-Modifiers bei ihrer Registrierung " +"instrumentieren." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Die Methoden von Entitys bei ihrer Registrierung instrumentieren." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Zeitintervall des Abspeicherns wichtiger Änderungen in der Welt, in Sekunden." + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" +"Zeitintervall, in dem die Tageszeit an Clients gesendet wird, in Sekunden " +"angegeben." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animierte Inventargegenstände" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Inventartaste" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Maus umkehren" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Kehrt die vertikale Mausbewegung um." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Pfad der Kursivschrift" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Pfad der kursiven Festbreitenschrift" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Item-Entity-TTL" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Iterationen" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Iterationen der rekursiven Funktion.\n" +"Eine Erhöhung des Wertes wird die Menge an Details erhöhen,\n" +"aber auch die Rechenlast erhöhen.\n" +"Mit 20 Iterationen hat dieser Kartengenerator eine ähnliche\n" +"Rechenlast wie der Kartengenerator V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "Joystick-ID" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Joystick-Button-Wiederholungsrate" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "Joystick-Totbereich" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Joystick-Pyramidenstumpf-Empfindlichkeit" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Joystick-Typ" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Nur für Juliamenge.\n" +"W-Komponente der hyperkomplexen Konstante.\n" +"Beeinflusst die Form des Fraktals.\n" +"Hat keine Wirkung auf 3-D-Fraktale.\n" +"Reichweite liegt grob zwischen -2 und 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Nur für Juliamenge.\n" +"X-Komponente der hyperkomplexen Konstante.\n" +"Ändert die Form des Fraktals.\n" +"Weite liegt grob zwischen -2 und 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Nur für Juliamenge.\n" +"Y-Komponente der hyperkomplexen Konstante.\n" +"Ändert die Form des Fraktals.\n" +"Weite liegt grob zwischen -2 und 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Nur für Juliamenge.\n" +"Z-Komponente der hyperkomplexen Konstante.\n" +"Ändert die Form des Fraktals.\n" +"Weite liegt grob zwischen -2 und 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia-w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia-x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia-y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia-z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Sprungtaste" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Sprunggeschwindigkeit" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um die Sichtweite zu reduzieren.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zur Reduzierung der Lautstärke.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Graben.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Fallenlassen des ausgewählten Gegenstandes.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um die Sichtweite zu erhöhen.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zur Erhöhung der Lautstärke.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Springen.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um sich schnell im Schnellmodus zu bewegen.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um den Spieler rückwärts zu bewegen.\n" +"Wird, wenn aktiviert, auch die Vorwärtsautomatik deaktivieren.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um den Spieler vorwärts zu bewegen.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um den Spieler nach links zu bewegen.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um den Spieler nach rechts zu bewegen.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um das Spiel stumm zu schalten.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um das Chat-Fenster zu öffnen, um Kommandos einzugeben.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um das Chat-Fenster zu öffnen, um lokale Befehle einzugeben.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Öffnen des Chat-Fensters.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Öffnen des Inventars.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Bauen.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 11. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 12. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 13. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 14. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 15. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 16. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 16. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 18. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 19. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 20. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 21. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 22. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 23. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 24. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 25. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 26. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 27. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 28. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 29. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 30. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 31. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des 32. Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des achten Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des fünften Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des ersten Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des vierten Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des nächsten Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des neunten Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des vorherigen Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des zweiten Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des siebten Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des sechsten Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des zehnten Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Auswählen des dritten Gegenstands in der Schnellleiste.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Schleichen.\n" +"Wird auch zum Runterklettern und das Sinken im Wasser verwendet, falls " +"aux1_descends deaktiviert ist.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Wechseln der Kamera (Ego- oder Dritte-Person-Perspektive).\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zur Erzeugung von Bildschirmfotos.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Umschalten der automatischen Vorwärtsbewegung.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Umschalten des Filmmodus.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Wechseln der Anzeige der Übersichtskarte.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Umschalten des Schnellmodus.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Umschalten des Flugmodus.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Umschalten des Geistmodus.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Umschalten des Nick-Bewegungsmodus.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Umschalten der Kameraaktualisierung. Nur für die Entwicklung " +"benutzt.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um die Anzeige des Chats umzuschalten.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Umschalten der Anzeige der Debug-Informationen.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Umschalten der Anzeige des Nebels.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um das HUD zu verbergen oder wieder anzuzeigen.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um die Anzeige der großen Chatkonsole umzuschalten.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste zum Umschalten der Profiler-Anzeige. Für die Entwicklung benutzt.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um die unbegrenzte Sichtweite ein- oder auszuschalten.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Taste, um die Zoom-Ansicht zu verwenden, falls möglich.\n" +"Siehe http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "Tastatur und Maus" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" +"Spieler, die mehr als X Nachrichten innerhalb von 10 Sekunden sendeten, " +"hinauswerfen." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "See-Steilheit" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "See-Schwellwert" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Sprache" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Tiefe für große Höhlen" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Max. Anzahl großer Höhlen" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Min. Anzahl großer Höhlen" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Anteil gefluteter großer Höhlen" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Taste für große Chatkonsole" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Blätterstil" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Blätterstil:\n" +"- Fancy: Alle Seiten sind sichtbar\n" +"- Simple: Nur äußere Seiten, falls definierte special_tiles benutzt " +"werden\n" +"- Opaque: Transparenz deaktivieren" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Linkstaste" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Länge eines Servertakts und dem Zeitintervall, in dem Objekte über das " +"Netzwerk\n" +"üblicherweise aktualisiert werden; in Sekunden angegeben." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Länge von Flüssigkeitswellen.\n" +"Dafür müssen Flüssigkeitswellen aktiviert sein." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" +"Dauer zwischen Active-Block-Modifier-(ABM)-Ausführungszyklen, in Sekunden." + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Dauer der Zeit zwischen NodeTimer-Ausführungszyklen, in Sekunden." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Zeit zwischen Active-Block-Management-Zyklen, in Sekunden." + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Bis zu welcher Stufe Protokollmeldungen in debug.txt geschrieben werden " +"sollen:\n" +"- <nichts> (keine Protokollierung)\n" +"- none (Meldungen ohne Einstufung)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Lichtkurvenverstärkung" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Lichtkurvenverstärkung: Mitte" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Lichtkurvenverstärkung: Ausbreitung" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Lichtkurven-Gammawert" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Lichtkurve: Hoher Gradient" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Lichtkurve: Niedriger Gradient" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "Licht" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Grenze der Kartengenerierung, in Blöcken, in alle 6 Richtungen von\n" +"(0, 0, 0). Nur Mapchunks, die sich vollständig in der Kartengenerator-\n" +"grenze befinden, werden generiert. Der Wert wird für jede Welt\n" +"getrennt abgespeichert." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Begrenzt die Anzahl der parallelen HTTP-Anfragen. Betrifft:\n" +"- Medienabholung, falls der Server die remote_media-Einstellung " +"verwendet.\n" +"- Herunterladen der Serverliste und Server-Ankündigungsdaten.\n" +"- Downloads, die vom Hauptmenü aus getätigt werden (z.B. Mod-Manager).\n" +"Hat nur eine Wirkung, wenn mit cURL-Unterstützung kompiliert wurde." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Flüssigkeitswiderstand" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Flüssigkeitswiderstandsglättung" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Max. Flüssigkeitsiterationen" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Aufräumzeit für Flüssigkeitswarteschlange" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Flüssigkeitsabsinken" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Flüssigkeitsaktualisierungsintervall in Sekunden." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Flüssigkeitsaktualisierungstakt" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Spielprofiler laden" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Den Spielprofiler laden, um Profilingdaten für das Spiel zu sammeln.\n" +"Aktiviert den „/profiler“-Befehl, um auf das erzeugte Profil zuzugreifen.\n" +"Nützlich für Modentwickler und Serverbetreiber." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Loading Block Modifiers" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Y-Untergrenze von Verliesen." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Y-Untergrenze von Schwebeländern." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Hauptmenü-Skript" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Nebel- und Himmelsfarben von der Tageszeit (Sonnenaufgang/Sonnenuntergang) " +"und Blickrichtung abhängig machen." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Macht alle Flüssigkeiten undurchsichtig" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Kartenkompressionsstufe für Festspeicher" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Kartenkompressionsstufe für Netzwerkverkehr" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Kartenverzeichnis" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" +"Kartengenerierungsattribute speziell für den Carpathian-Kartengenerator." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Kartengenerierungsattribute speziell für den flachen Kartengenerator.\n" +"Zu einer flachen Welt können gelegentliche Seen und Hügel hinzugefügt werden." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Kartengenerierungsattribute speziell für den Fraktale-Kartengenerator.\n" +"„terrain“ aktiviert die Erzeugung von nicht-fraktalem Gelände:\n" +"Ozean, Inseln und der Untergrund." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Kartengenerierungsattribute speziell für den Täler-Kartengenerator.\n" +"„altitude_chill“: Reduziert Hitze mit der Höhe.\n" +"„humid_rivers“: Erhöht Luftfeuchte um Flüsse und Wasserbecken.\n" +"„vary_river_depth“: Falls aktiviert, werden eine niedrige Luftfeuchte und\n" +"hohe Hitze dafür sorgen, dass Flüsse seichter und gelegentlich trocken\n" +"werden.\n" +"„altitude_dry“: Reduziert Luftfeuchte mit der Höhe." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Kartengenerierungsattribute speziell für den Kartengenerator v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Kartengenerierungsattribute speziell für den Kartengenerator v6.\n" +"Das Flag „snowbiomes“ aktiviert das neue 5-Biom-System.\n" +"Falls das „snowbiomes“-Flag aktiviert ist, werden Dschungel automatisch " +"aktiviert und das „jungles“-Flag wird ignoriert." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Kartengenerierungsattribute speziell für den Kartengenerator v7.\n" +"„ridges”: Flüsse.\n" +"„floatlands“: Schwebende Landmassen in der Atmosphäre.\n" +"„caverns“: Gigantische Höhlen tief im Untergrund." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Kartenerzeugungsgrenze" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Speicherintervall der Karte" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "Kartenschatten-Aktualisierungsframes" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Kartenblock-Grenze" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Kartenblockmesh-Generierungsverzögerung" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Cachegröße des Kartenblock-Meshgenerators in MB" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Timeout zum Entladen von Kartenblöcken" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Carpathian-Kartengenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Flags spezifisch für Carpathian-Kartengenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Flacher Kartengenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Flags spezifisch für flachen Kartengenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Fraktale-Kartengenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Flags spezifisch für Fraktale-Kartengenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "V5-Kartengenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Flags spezifisch für Kartengenerator V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "V6-Kartengenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Flags spezifisch für Kartengenerator V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "V7-Kartengenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Flags spezifisch für Kartengenerator V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Täler-Kartengenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Flags spezifisch für Täler-Kartengenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Kartengenerator-Debugging" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Kartengeneratorname" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Max. Distanz für Kartenblockerzeugung" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Max. Distanz für Kartenblockübertragung" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Max. Flüssigkeitsblöcke, die pro Schritt verarbeitet werden." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Max. clearobjects-Zusatz-Kartenblöcke" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Max. Pakete pro Iteration" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Maximale Bildwiederholrate" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"Maximale Bildwiederholrate, während das Fenster nicht fokussiert oder das " +"Spiel pausiert ist." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Maximale Distanz zum Rendern von Schatten." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Maximal zwangsgeladene Kartenblöcke" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Maximale Breite der Schnellleiste" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "Obergrenze der zufälligen Anzahl großer Höhlen je Mapchunk." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "Obergrenze Anzahl der zufälligen Anzahl kleiner Höhlen je Mapchunk." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Maximaler Flüssigkeitswiderstand. Regelt die Abbremsung beim\n" +"Eintauchen in eine Flüssigkeit bei hoher Geschwindigkeit." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Maximale Anzahl an Kartenblöcke, die simultan pro Client gesendet werden.\n" +"Die maximale Gesamtanzahl wird dynamisch berechnet:\n" +"max_Gesamt = aufrunden((#Clients + max_Benutzer) * je_Client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "Maximale Anzahl der Kartenblöcke in der Ladewarteschlange." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Maximale Anzahl der Kartenblöcke, die in die Warteschlange für\n" +"die Erzeugung eingereiht werden sollen.\n" +"Diese Grenze wird für jeden Spieler einzeln erzwungen." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Maximale Anzahl der Kartenblöcke, die in die Warteschlange zum Laden aus " +"einer Datei eingereiht werden.\n" +"Diese Grenze wird für jeden Spieler einzeln erzwungen." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Maximale Anzahl an gleichzeitigen Downloads. Weitere werden in einer " +"Warteschlange eingereiht.\n" +"Dies sollte niedriger als das curl_parallel_limit sein." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Maximale Anzahl der zwangsgeladenen Kartenblöcke." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Maximale Anzahl der Kartenblöcke, die der Client im Speicher vorhalten " +"soll.\n" +"Auf -1 setzen, um keine Obergrenze zu verwenden." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Maximale Anzahl der Pakete, die pro Sendeschritt gesendet werden. Falls Sie " +"eine\n" +"langsame Verbindung haben, probieren Sie, diesen Wert zu reduzieren,\n" +"aber reduzieren Sie ihn nicht unter der doppelten Anzahl der Clients, die " +"Sie\n" +"anstreben." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Maximale Anzahl der Spieler, die sich simultan verbinden können." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Maximale Anzahl der anzuzeigenden neuen Chatnachrichten" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" +"Maximale Anzahl der statisch gespeicherten Objekte in einem Kartenblock." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Maximale Objekte pro Block" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Maximales Verhältnis zum aktuellen Fenster, das für die\n" +"Schnellleiste verwendet werden soll. Nützlich, wenn es\n" +"etwas gibt, was links oder rechts von ihr angezeigt werden soll." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Max. gleichzeitig versendete Blöcke pro Client" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Maximale Größe der ausgehenden Chatwarteschlange" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Maximale Größe der ausgehenden Chatwarteschlange.\n" +"0, um Warteschlange zu deaktivieren, -1, um die Wartenschlangengröße nicht " +"zu begrenzen." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Maximale Zeit in Millisekunden, die das Herunterladen einer Datei (z.B. " +"einer Mod) dauern darf." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Maximale Zeit in Millisekunden, die eine interaktive Anfrage (z.B. " +"Serverlistenanfrage) brauchen darf." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Maximale Benutzerzahl" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "3-D-Modell-Zwischenspeicher" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Meldung des Tages (message of the day)" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" +"Die Meldung des Tages, die frisch verbundenen Spielern angezeigt werden " +"soll.\n" +"Auf Englisch bekannt als „message of the day“ oder „MOTD“." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Verwendete Methode, um ein ausgewähltes Objekt hervorzuheben." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Minimaler Level des Prokolls, die in den Chat geschrieben werden soll." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Übersichtskarte" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Übersichtskartentaste" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Abtasthöhe der Übersichtskarte" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Untergrenze der zufälligen Anzahl großer Höhlen je Mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Untergrenze der zufälligen Anzahl kleiner Höhlen je Mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Minimale Texturengröße" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mip-Mapping" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "Sonstiges" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "Mod-Profiler" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "Mod-Sicherheit" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Mod-Kanäle" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Modifiziert die Größe der HUD-Elemente." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Pfad der Festbreitenschrift" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Größe der Festbreitenschrift" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "Festbreitenschriftgröße teilbar durch" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Berghöhenrauschen" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Bergrauschen" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Bergvariationsrauschen" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Bergnullhöhe" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Mausempfindlichkeit" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Faktor für die Mausempfindlichkeit." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Schlammrauschen" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Faktor für Kamerawackeln beim Sturz.\n" +"Zum Beispiel: 0 für kein Wackeln, 1.0 für den Standardwert, 2.0 für doppelte " +"Geschwindigkeit." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Stummtaste" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Ton verstummen" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Name des Kartengenerators, der für neue Welten benutzt werden soll.\n" +"Wird eine Welt im Hauptmenü erstellt, wird diese Einstellung überschrieben.\n" +"Aktuelle Kartengeneratoren in einem sehr instabilem Zustand:\n" +"- Die optionalen Schwebeländer von v7 (standardmäßig deaktiviert)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Name des Spielers.\n" +"Wenn ein Server gestartet wird, werden Clients mit diesem Namen zu " +"Administratoren.\n" +"Wird vom Hauptmenü aus gestartet, wird diese Einstellung überschrieben." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Name des Servers. Er wird in der Serverliste angezeigt und für frisch " +"verbundene Spieler angezeigt." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Vordere Ebene" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Netzwerkport (UDP), auf dem gelauscht werden soll.\n" +"Dieser Wert wird überschrieben, wenn vom Hauptmenü aus gestartet wird." + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "Netzwerk" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Neue Benutzer müssen dieses Passwort eingeben." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Geistmodus" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Geistmodustaste" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "Block- und Entityhervorhebung" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Blockhervorhebung" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "NodeTimer-Intervall" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Rauschen" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Anzahl der Erzeugerthreads" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Anzahl der zu verwendeten Erzeugerthreads.\n" +"Wert 0:\n" +"- Automatische Wahl. Die Anzahl der Erzeugerthreads wird\n" +"- „Anzahl der Prozessoren - 2“ sein, mit einer Untergrenze von 1.\n" +"Jeder andere Wert:\n" +"- Legt die Anzahl der Erzeugerthreads fest, mit einer Untergrenze von 1.\n" +"ACHTUNG: Das Erhöhen der Anzahl der Erzeugerthreads erhöht die\n" +"Geschwindigkeit des Engine-Kartengenerators, aber dies könnte die Spiel-\n" +"performanz beeinträchtigen, da mit anderen Prozessen konkurriert wird;\n" +"das ist besonders im Einzelspielermodus der Fall und/oder, wenn Lua-Code\n" +"in „on_generated“ ausgeführt wird.\n" +"Für viele Benutzer wird die optimale Einstellung wohl die „1“ sein." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Anzahl der zusätzlichen Kartenblöcke, welche mit /clearobjects gleichzeitig\n" +"geladen werden können. Dies ist ein Kompromiss zwischen SQLite-\n" +"Transaktions-Overhead und Speicherverbrauch (Faustregel: 4096=100MB)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Undurchsichtige Flüssigkeiten" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" +"Undurchsichtigkeit (Alpha) des Schattens hinter der Standardschrift, " +"zwischen 0 und 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Das Pausemenü öffnen, wenn der Fokus des Fensters verloren geht.\n" +"Wird nicht pausieren, wenn ein Formspec geöffnet ist." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Optionaler manueller Wert für die Farbe von Chat-Weblinks." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Pfad der Ersatzschrift. Muss eine TrueType-Schrift sein.\n" +"Diese Schrift wird für bestimmte Sprachen benutzt, oder, wenn die " +"Standardschrift nicht verfügbar ist." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Pfad, in dem Bildschirmfotos gespeichert werden sollen. Kann ein absoluter " +"oder relativer Pfad sein.\n" +"Dieses Verzeichnis wird erstellt, wenn es nicht bereits existiert." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Pfad zum Shader-Verzeichnis. Falls kein Pfad definiert ist, wird der " +"Standardpfad benutzt." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" +"Pfad der Texturenverzeichnisse. Alle Texturen werden von dort zuerst gesucht." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Pfad der Standardschrift. Muss eine TrueType-Schrift sein.\n" +"Die Ersatzschrift wird benutzt, falls diese Schrift nicht geladen werden " +"kann." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Pfad der Festbreitenschrift. Muss eine TrueType-Schrift sein.\n" +"Diese Schrift wird z.B. für die Konsole und die Profiler-Anzeige benutzt." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Pausieren bei Fensterfokusverlust" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "Je-Spieler-Grenze der Ladewarteschlange für Kartenblöcke" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Je-Spieler-Grenze der Kartenblöcke in Erzeugungswarteschlange" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Physik" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Nick-Bewegungstaste" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Nick-Bewegungsmodus" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Bautaste" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Bauen-Wiederholungsrate" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Der Spieler kann unabhängig von der Schwerkraft fliegen.\n" +"Dafür wird das „fly“-Privileg auf dem Server benötigt." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Spieler-Übertragungsdistanz" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Spielerkampf" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Poissonfilter" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"UDP-Port, zu dem sich verbunden werden soll.\n" +"Beachten Sie, dass das Port-Feld im Hauptmenü diese Einstellung überschreibt." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Verhindert wiederholtes Graben und Bauen, wenn man die Maustasten gedrückt " +"hält.\n" +"Aktivieren Sie dies, wenn sie zu oft aus Versehen graben oder bauen." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Verhindert, dass Mods unsichere Funktionen, wie das Ausführen von Shell-" +"Kommandos, benutzen können." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Gibt die Profiling-Daten der Engine in regelmäßigen Abständen aus (in " +"Sekunden).\n" +"„0“ deaktiviert das Profiling. Nützlich für Entwickler." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Privilegien, die Spieler mit basic_privs gewähren können" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Profiler" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Profiler-Umschalten-Taste" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Prometheus-Lauschadresse" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Prometheus-Lauschadresse.\n" +"Falls Minetest mit der ENABLE_PROMETEUS-Option kompiliert wurde,\n" +"wird dies den Metriklauscher für Prometheus auf dieser Adresse aktivieren.\n" +"Metriken können von http://127.0.0.1:30000/metrics abgegriffen werden." + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Anteil der großen Höhlen, die eine Flüssigkeit enthalten." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Radius des Wolkenbereichs; In Einheiten von 64 Wolkenquadraten.\n" +"Werte größer als 26 werden scharfe Schnittkanten an den Ecken des " +"Wolkenbereichs erzeugen." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Erhöht das Gelände, um Täler um den Flüssen zu erzeugen." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Zufällige Steuerung" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Sichtweitentaste" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Letzte Chatnachrichten" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Normalschriftpfad" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Externer Medienserver" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Serverport" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Farbcodes aus eingehenden Chatnachrichten entfernen.\n" +"Benutzen Sie dies, um Spieler daran zu hindern, Farbe in ihren Nachrichten " +"zu verwenden" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Ersetzt das Standardhauptmenü mit einem benutzerdefinierten Hauptmenü." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Berichtspfad" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Schränkt den Zugriff auf bestimmte clientseitige Funktionen auf\n" +"Servern ein. Kombinieren Sie diese Byteflags unten, um client-\n" +"seitige Funktionen einzuschränken:\n" +"LOAD_CLIENT_MODS: 1 (deaktiviert das Laden von Clientmods)\n" +"CHAT_MESSAGES: 2 (deaktiviert clientseitigen Aufruf von send_chat_message)\n" +"READ_ITEMDEFS: 4 (deaktiviert clientseitigen Aufruf von get_item_def)\n" +"READ_NODEDEFS: 8 (deaktiviert clientseitigen Aufruf von get_node_def)\n" +"LOOKUP_NODES_LIMIT: 16 (begrenzt clientseitigen Aufruf von\n" +"get_node auf csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (deaktiviert clientseitigen Aufruf von get_player_names)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Flusskanalbergausbreitungsrauschen" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Flusskanalrauschen" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Flusskanal-Unterwasserrauschen" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Rauschen für Größe gezahnter Berge" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Rechtstaste" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Flusskanaltiefe" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Flusskanalbreite" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Flusstiefe" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Flussrauschen" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Flussgröße" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Flusstalbreite" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Rollback-Aufzeichnung" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Rauschen für Größe sanfter Hügel" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Rauschen für Ausbreitung sanfter Hügel" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Runde Übersichtskarte" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Sicheres Graben und Bauen" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Sandstrände treten auf, wenn np_beach diesen Wert überschreitet." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Speichert die vom Client empfangene Karte auf dem Datenträger." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Fenstergröße automatisch speichern, wenn sie geändert wird." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Karte vom Server speichern" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"GUI mit einem benutzerdefinierten Wert skalieren.\n" +"Benutzt einen Pixelwiederholungs-Anti-Aliasing-Filter, um\n" +"die GUI zu skalieren. Dies wird einige der harten Kanten\n" +"abglätten und Pixel beim Verkleinern mischen, wobei einige\n" +"Kantenpixel verschwommen werden, wenn sie mit nicht-\n" +"ganzzahligen Größen skaliert werden." + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "Monitor" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Bildschirmhöhe" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Bildschirmbreite" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Bildschirmfotoverzeichnis" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Bildschirmfotoformat" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Bildschirmfotoqualität" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Bildschirmfotoqualität. Wird nur für das JPEG-Format benutzt.\n" +"1 steht für die schlechteste Qualität, 100 für die beste Qualität.\n" +"Benutzen Sie 0 für die Standardqualität." + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "Bildschirmfotos" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Meeresgrundrauschen" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Das zweite von vier 2-D-Rauschen, welche gemeinsam Hügel-/Bergkettenhöhe " +"definieren." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Das zweite von zwei 3-D-Rauschen, welche gemeinsam Tunnel definieren." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Siehe https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Farbe der Auswahlbox (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Auswahlboxfarbe" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Auswahlboxbreite" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Wählt einen von 18 Fraktaltypen aus.\n" +"1 = 4-D-Mandelbrotmenge, Typ „rund“.\n" +"2 = 4-D-Juliamenge, Typ „rund“.\n" +"3 = 4-D-Mandelbrotmenge, Typ „eckig“.\n" +"4 = 4-D-Juliamenge, Typ „eckig“.\n" +"5 = 4-D-Mandelbrotmenge, Typ „Mandel-Cousin“.\n" +"6 = 4-D-Juliamenge, Typ „Mandel-Cousin“.\n" +"7 = 4-D-Mandelbrotmenge, Typ „Variante“.\n" +"8 = 4-D-Juliamenge, Typ „Variante“.\n" +"9 = 3-D-Mandelbrotmenge, Typ „Madelbrot/Mandelbar“.\n" +"10 = 3-D-Juliamenge, Typ „Madelbrot/Mandelbar“.\n" +"11 = 3-D-Mandelbrotmenge, Typ „Weihnachtsbaum“.\n" +"12 = 3-D-Juliamenge, Typ „Weihnachtsbaum“.\n" +"13 = 3-D-Mandelbrotmenge, Typ „Mandelbulb“.\n" +"14 = 3-D-Juliamenge, Typ „Mandelbulb“.\n" +"15 = 3-D-Mandelbrotmenge, Typ „Kosinus-Mandelbulb“.\n" +"16 = 3-D-Juliamenge, Typ „Kosinus-Mandelbulb“.\n" +"17 = 4-D-Mandelbrotmenge, Typ „Mandelbulb“.\n" +"18 = 4-D-Juliamenge, Typ „Mandelbulb“." + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "Server" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "Server-Gameplay" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "Serversicherheit" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "Server-URL" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Serveradresse" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Serverbeschreibung" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Servername" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Serverport" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Serverseitiges Occlusion Culling" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "Server-/Umgebungsperformanz" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "Serverlisten-URL" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "Serverliste und MOTD" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Serverlistendatei" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Setzt die Sprache. Leer lassen, um Systemsprache zu verwenden.\n" +"Nach Änderung ist ein Neustart erforderlich." + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Setzt die maximale Zeichenlänge einer Chatnachricht (in Zeichen), die von " +"Clients gesendet wird." + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Setzt den Schattenstärkegammawert.\n" +"Passt die Intensität der dynamischen Schatten im Spiel an.\n" +"Ein niedrigerer Wert führt zu schwächeren Schatten, ein höherer Wert führt " +"zu dunkleren Schatten." + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Setzt den Radius von weichen Schatten.\n" +"Niedrigere Werte führen zu schärferen Schatten, größere Werte führen zu " +"weicheren Schatten.\n" +"Minimalwert: 1.0; Maximalwert: 15.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Setzt die Neigung vom Sonnen-/Mondorbit in Grad.\n" +"0 = keine Neigung / vertikaler Orbit.\n" +"Minimalwert: 0.0; Maximalwert: 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Auf „wahr“ setzen, um Shadow-Mapping zu aktivieren.\n" +"Dafür müssen Shader aktiviert sein." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Auf „wahr“ setzen, um wehende Blätter zu aktivieren.\n" +"Dafür müssen Shader aktiviert sein." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Auf „wahr“ setzen, um Flüssigkeitswellen (wie bei Wasser) zu aktivieren.\n" +"Dafür müssen Shader aktiviert sein." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Auf „wahr“ setzen, um wehende Pflanzen zu aktivieren.\n" +"Dafür müssen Shader aktiviert sein." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Setzt die Schattentexturqualität auf 32 Bits.\n" +"Falls aktiviert, werden 16-Bit-Texturen benutzt.\n" +"Dies kann zu viel mehr Artefakten im Schatten führen." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Shader-Pfad" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Shader ermöglichen fortgeschrittene visuelle Effekte und können die " +"Performanz auf\n" +"einigen Grafikkarten erhöhen.\n" +"Das funktioniert nur mit dem OpenGL-Grafik-Backend." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Schattenfilterqualität" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "Maximale Schattenrenderdistanz von Schattenkarten in Blöcken" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "Schattenkartentextur in 32 Bits" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Schattenkartentexturengröße" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Versatz des Schattens hinter der Standardschrift (in Pixeln). Falls 0, wird " +"der Schatten nicht gezeichnet." + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "Schattenstärkengammawert" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Form der Übersichtskarte. Aktiviert = rund, Deaktiviert = rechteckig." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Debug-Info zeigen" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Entity-Auswahlboxen zeigen" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Entityauswahlboxen zeigen\n" +"Nach Änderung ist ein Neustart erforderlich." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Standardmäßig Hintergründe für Namensschilder anzeigen" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Herunterfahrnachricht" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Größe der Mapchunks, die vom Kartengenerator generiert werden, in Karten-\n" +"blöcken (16 Blöcke) angegeben.\n" +"ACHTUNG! Es bringt nichts und es birgt viele Gefahren, diesen Wert über\n" +"5 zu erhöhen.\n" +"Die Höhlen- und Verliesdichte wird erhöht, wenn dieser Wert verringert " +"wird.\n" +"Die Änderung dieses Wertes ist für besondere Verwendungszwecke, es\n" +"wird empfohlen, ihn unverändert zu lassen." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Größe vom Kartenblock-Cache des Meshgenerators. Wird sie\n" +"erhöht, wird die Cache-Trefferrate erhöht, was die Anzahl der Daten,\n" +"die vom Hauptthread kopiert werden, reduziert und somit das Stottern " +"reduziert." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Himmelskörperorbitneigung" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "w-Ausschnitt" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Hänge und Füllungen arbeiten zusammen, um die Höhen zu verändern." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Max. Anzahl kleiner Höhlen" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Min. Anzahl kleiner Höhlen" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" +"Kleinräumige Luftfeuchtigkeitsvarriierung für Biomübergänge an Grenzen." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "Kleinräumige Temperaturvariierung für Biomübergänge an Grenzen." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Weiches Licht" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Glättet Kamerabewegungen bei der Fortbewegung und beim Umsehen. Auch bekannt " +"als „Look Smoothing“ oder „Mouse Smoothing“.\n" +"Nützlich zum Aufnehmen von Videos." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "Glättet die Rotation der Kamera im Filmmodus. 0 zum Ausschalten." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Glättet die Rotation der Kamera. 0 zum Ausschalten." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Schleichtaste" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Schleichgeschwindigkeit" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Schleichgeschwindigkeit, in Blöcken pro Sekunde." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Weicher-Schatten-Radius" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Ton" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Spezifiziert die URL, von der die Clients die Medien (Texturen, Töne, …) " +"herunterladen.\n" +"$Dateiname sollte von $remote_media$Dateiname mittels cURL erreichbar sein\n" +"(diese Einstellung sollte also mit einem Schrägstrich enden).\n" +"Dateien, die nicht über diesen Server erreichbar sind, werden auf dem " +"üblichen Weg heruntergeladen (UDP)." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Legt die Standardstapelgröße von Blöcken, Gegenständen und Werkzeugen fest.\n" +"Beachten Sie, dass Mods oder Spiele eine explizite Stapelgröße für " +"bestimmte\n" +"(oder alle) Gegenstände setzen kann." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Eine vollständige Aktualisierung der Schattenkarte über der angegebenen\n" +"Anzahl Frames ausbreiten. Höhere Werte können dazu führen, dass\n" +"Schatten langsamer reagieren,\n" +"niedrigere Werte sind rechenintensiver.\n" +"Minimalwert: 1; Maximalwert: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Ausbreitung des Lichtkurvenverstärkungsintervalls.\n" +"Regelt die Breite des Intervalls, das verstärkt werden soll.\n" +"Standardabweichung der Lichtkurvenverstärkungs-Gaußfunktion." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Statische Einstiegsposition" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Steilheitsrauschen" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Stufenberggrößenrauschen" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Stufenbergsausbreitungsrauschen" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Stärke von 3-D-Modus-Parallax." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Stärke der Lichtkurvenverstärkung.\n" +"Die 3 Verstärkungsparameter („boost“) definieren ein Intervall der\n" +"Lichtkurve, die in ihrer Helligkeit verstärkt wird." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Strikte Protokollversionsprüfung" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Farbcodes entfernen" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Oberfläche mit optionalem Wasser, das auf einer durchgehenden\n" +"Schwebelandebene platziert wird. Wasser ist standardmäßig deaktiviert\n" +"und wird nur platziert, wenn dieser Wert auf einem Wert größer als\n" +"„mgv7_floatland_ymax” minus „mgv7_floatland_taper” (dem Start\n" +"der oberen Zuspitzung) gesetzt wurde.\n" +"***ACHTUNG, MÖGLICHE GEFAHR FÜR WELTEN UND SERVERPERFORMANZ***:\n" +"Wenn die Wasserplatzierung aktiviert wird, müssen die Schwebeländer\n" +"konfiguriert und darauf abgeklopft werden, dass sie eine durchgehende\n" +"Ebene sind, indem „mgv7_floatland_density“ auf 2.0 (oder einem anderen\n" +"erforderlichen Wert, abhängig von „mgv7_np_floatland“) gesetzt wird,\n" +"um ein serverbelastendes extremes Wasserfließen und einer gewaltigen\n" +"Überflutung der Weltoberfläche unten zu vermeiden." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "Synchrones SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Temperaturvariierung für Biome." + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "Temporäre Einstellungen" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Geländealternativrauschen" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Geländebasisrauschen" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Geländehöhe" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Höheres-Gelände-Rauschen" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Geländerauschen" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Schwellwert für Geländerauschen der Hügel.\n" +"Steuert das Verhältnis des Weltgebiets, das von Hügeln bedeckt ist.\n" +"Passen Sie diesen Wert in Richtung 0.0 für ein größeres Verhältnis an." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Schwellwert für Geländerauschen der Seen.\n" +"Steuert das Verhältnis des Weltgebiets, das von Seen bedeckt ist.\n" +"Passen Sie diesen Wert in Richtung 0.0 für ein größeres Verhältnis an." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Geländepersistenzrauschen" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Texturenpfad" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Texturengröße zum Rendern der Schattenkarte.\n" +"Dies muss eine Zweierpotenz sein.\n" +"Größere Werte erzeugen bessere Schatten, aber dies ist auch rechenintensiver." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Texturen auf einem Block können entweder auf dem Block oder zur Welt\n" +"ausgerichtet sein. Der erste Modus eignet sich besser für Dinge wie\n" +"Maschinen, Möbel, usw., während der zweite Modus besser zu Treppen\n" +"und Mikroblöcken passt.\n" +"Allerdings, da diese Möglichkeit neu ist, könnte sie von älteren Servern\n" +"nicht unterstützt werden. Diese Einstellung ermöglicht es, dies für " +"bestimmte\n" +"Blocktypen zu erzwingen. Bitte beachten Sie, dass diese Option als\n" +"EXPERIMENTELL eingestuft wird und nicht richtig funktionieren könnte." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "Die URL für den Inhaltespeicher" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "Der Totbereich des Joysticks" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Das Standardformat, in dem Profile gespeichert werden,\n" +"wenn „/profiler save [Format]“ ohne Format aufgerufen wird." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "Die Tiefe der Erde oder eines anderen Biomfüllerblocks." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"Der Dateipfad relativ zu Ihrem Weltpfad, in dem Profile abgespeichert werden." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "Die Kennung des zu verwendeten Joysticks" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"Die Länge in Pixeln, die benötigt wird, damit die Touchscreen-Interaktion " +"beginnt." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"Die maximale Höhe der Oberfläche von Flüssigkeitswellen.\n" +"4.0 = Wellenhöhe ist zwei Blöcke.\n" +"0.0 = Wellen bewegen sich gar nicht.\n" +"Standard ist 1.0 (1/2 Block).\n" +"Dafür müssen Flüssigkeitswellen aktiviert sein." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "Die Netzwerkschnittstelle, auf die der Server lauscht." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Die Privilegien, die neue Benutzer automatisch erhalten.\n" +"Siehe /privs im Spiel für eine vollständige Liste aller möglichen " +"Privilegien auf Ihrem Server und die Modkonfiguration." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"Der Radius des Volumens von Blöcken um jeden Spieler, der dem\n" +"Active-Block-Zeugs unterliegt, in Kartenblöcken angegeben (16 Blöcke).\n" +"In aktiven Kartenblöcken werden Objekte geladen und ABMs ausgeführt.\n" +"Dies ist außerdem die minimale Reichweite, in der aktive Objekte (Mobs) " +"verwaltet\n" +"werden. Dies sollte zusammen mit active_object_send_range_blocks\n" +"konfiguriert werden." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"Das Renderer-Backend.\n" +"Ein Neustart ist erforderlich, wenn dies geändert wird.\n" +"Anmerkung: Auf Android belassen Sie dies bei OGLES1, wenn Sie sich unsicher " +"sind.\n" +"Die App könnte sonst nicht mehr starten.\n" +"Auf anderen Plattformen wird OpenGL empfohlen.\n" +"Shader werden unter OpenGL (nur Desktop) und OGLES2 (experimentell) " +"unterstützt." + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"Die Empfindlichkeit der Joystick-Achsen, um den\n" +"Pyramidenstumpf der Spielansicht herumzubewegen." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"Die Stärke (Dunkelheit) der blockweisen Ambient-Occlusion-Schattierung.\n" +"Niedriger bedeutet dunkler, höher bedeutet heller. Gültige Werte liegen\n" +"zwischen 0.25 und 4.0 inklusive. (Achtung: Punkt als Dezimaltrennzeichen\n" +"verwenden!) Falls der Wert außerhalb liegt, wird er zum nächsten gültigen\n" +"Wert gesetzt." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Die Zeit (in Sekunden), die die Flüssigkeitswarteschlange über die " +"Verarbeitungs-\n" +"kapazität hinauswachsen darf, bevor versucht wird, ihre Größe durch das\n" +"Verwerfen alter Warteschlangeneinträge zu reduzieren. Der Wert 0 deaktiviert " +"diese Funktion." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"Das erlaubte Zeitbudget für ABM-Ausführung jeden Schritt\n" +"(als Bruchteil des ABM-Intervalls)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Das Intervall in Sekunden, in dem Ereignisse wiederholt werden,\n" +"wenn eine Joystick-Tastenkombination gedrückt gehalten wird." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Die Zeit in Sekunden, in dem die Blockplatzierung wiederholt wird, wenn\n" +"die Bautaste gedrückt gehalten wird." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Der Typ des Joysticks" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"Die vertikale Distanz, über die die Hitze um 20 abfällt, falls " +"„altitude_chill“\n" +"aktiviert ist. Außerdem ist dies die vertikale Distanz, über die die " +"Luftfeuchte\n" +"um 10 abfällt, wenn „altitude_dry“ aktiviert ist." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Das dritte von vier 2-D-Rauschen, welche gemeinsam Hügel-/Bergkettenhöhe " +"definieren." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Zeit in Sekunden, die Item-Entitys (fallengelassene Gegenstände)\n" +"existieren dürfen. Der Wert -1 deaktiviert diese Funktion." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" +"Tageszeit, wenn eine neue Welt gestartet wird, in Millistunden (0-23999) " +"angegeben." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Zeit-Sendeintervall" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Zeitgeschwindigkeit" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Zeit, nach dem Clients nicht benutzte Kartendaten aus dem Speicher löschen, " +"in Sekunden." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Um Verzögerungen zu reduzieren, werden Kartenblockübertragungen " +"verlangsamt,\n" +"wenn ein Spieler etwas baut. Diese Einstellung bestimmt, wie lange sie\n" +"verlangsamt werden, nachdem ein Block platziert oder entfernt wurde." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Kameraauswahltaste" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Tooltip-Verzögerung" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Touchscreenschwellwert" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "Touchscreen" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "Kompromisse für Performanz" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "Transparenzsortierungsdistanz" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Bäumerauschen" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Trilinearer Filter" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"Wahr = 256\n" +"Falsch = 128\n" +"Nützlich, um die Übersichtskarte ruckelfrei auf langsamen Maschinen zu " +"machen." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Vertrauenswürdige Mods" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" +"URL der Serverliste, die in der Mehrspieler-Registerkarte angezeigt wird." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Unterabtastung" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Unterabtastung ist ähnlich der Verwendung einer niedrigeren " +"Bildschirmauflösung, aber sie wird nur auf die Spielwelt angewandt, während " +"die GUI intakt bleibt.\n" +"Dies sollte einen beträchtlichen Performanzschub auf Kosten einer weniger " +"detaillierten Grafik geben.\n" +"Hohe Werte führen zu einer weniger detaillierten Grafik." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Unbegrenzte Spielerübertragungsdistanz" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Nicht benutzte Serverdaten entladen" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Y-Obergrenze von Verliesen." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Y-Obergrenze von Schwebeländern." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Wolken blockförmig statt flach aussehen lassen." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Eine Wolkenanimation für den Hintergrund im Hauptmenü benutzen." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" +"Anisotrope Filterung verwenden, wenn auf Texturen aus einem gewissen " +"Blickwinkel heraus geschaut wird." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Bilineare Filterung bei der Skalierung von Texturen benutzen." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Mip-Mapping benutzen, um Texturen zu skalieren. Könnte die Performanz\n" +"leicht erhöhen, besonders, wenn ein hochauflösendes Texturenpaket benutzt " +"wird.\n" +"Eine gammakorrigierte Herunterskalierung wird nicht unterstützt." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Multi-Sample-Antialiasing (MSAA) benutzen, um Blockecken zu glätten.\n" +"Dieser Algorithmus glättet das 3-D-Sichtfeld während das Bild scharf " +"bleibt,\n" +"beeinträchtigt jedoch nicht die Textureninnenflächen\n" +"(was sich insbesondere bei transparenten Texturen bemerkbar macht).\n" +"Sichtbare Lücken erscheinen zwischen Blöcken, wenn Shader ausgeschaltet " +"sind.\n" +"Wenn der Wert auf 0 steht, ist MSAA deaktiviert.\n" +"Ein Neustart ist erforderlich, nachdem diese Option geändert worden ist." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Trilineare Filterung bei der Skalierung von Texturen benutzen." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "Benutzeroberflächen" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "VSync" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Taltiefe" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Talfüllung" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Talprofil" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Talhang" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Variierung der Biomfülltiefe." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Varriierung der maximalen Berghöhe (in Blöcken)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Variierung der Anzahl von Höhlen." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Variierung der vertikalen Skalierung des Geländes.\n" +"Falls das Rauschen < -0.55 ist, ist das Gelände nahezu flach.\n" +"(Beachten Sie die englische Notation mit Punkt als Dezimaltrennzeichen.)" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Variiert die Tiefe der Blöcke an der Oberfläche von Biomen." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Variiert die Rauheit des Geländes.\n" +"Definiert den „persistence“-Wert für „terrain_base“- und „terrain_alt“-" +"Rauschen." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Varriiert die Steilheit von Klippen." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Vertikale Klettergeschwindigkeit, in Blöcken pro Sekunde." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Vertikale Bildschirmsynchronisation." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Grafiktreiber" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Faktor für Wackeln der Ansicht" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Sichtweite in Blöcken." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Taste „Sichtweite reduzieren“" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Taste „Sichtweite erhöhen“" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Zoomansichtstaste" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Sichtweite" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "Virtueller Joystick löst Aux1-Taste aus" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Tonlautstärke" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Lautstärke aller Töne.\n" +"Dafür muss das Tonsystem aktiviert sein." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"W-Koordinate des generierten 3-D-Ausschnitts eines 4-D-Fraktals.\n" +"Bestimmt, welcher 3-D-Ausschnitt der 4-D-Form generiert wird.\n" +"Beeinflusst die Form des Fraktals.\n" +"Hat keine Auswirkung auf 3-D-Fraktale.\n" +"Die Weite liegt grob zwischen -2 und 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Geh- und Fluggeschwindigkeit, in Blöcken pro Sekunde." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Gehgeschwindigkeit" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Geh-, Flug- und Klettergeschwindigkeit im Schnellmodus, in Blöcken pro " +"Sekunde." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Meeresspiegel" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Die Höhe des (Meer-)Wassers in der Welt." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Wehende Blöcke" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Wehende Blätter" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Flüssigkeitswellen" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Flüssigkeitswellen: Wellenhöhe" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Flüssigkeitswellen: Wellengeschwindigkeit" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Flüssigkeitswellen: Wellenlänge" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Wehende Pflanzen" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "Weblinkfarbe" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Falls gui_scaling_filter wahr ist, dann müssen alle GUI-Bilder\n" +"von der Software gefiltert werden, aber einige Bilder werden\n" +"direkt zur Hardware erzeugt (z.B. Rendern in die Textur für\n" +"die Inventarbilder von Blöcken)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Falls gui_scaling_filter_txr2img auf „wahr“ gesetzt ist, werden\n" +"diese Bilder von der Hardware zur Software für die Skalierung\n" +"kopiert. Falls es auf „falsch“ gesetzt ist, wird die alte Skalierungs-\n" +"methode angewandt, für Grafiktreiber, welche das\n" +"Herunterladen von Texturen zurück von der Hardware nicht\n" +"korrekt unterstützen." + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Wenn bilineare, trilineare oder anisotrope Filter benutzt werden, können\n" +"niedrigauflösende Texturen verschwommen sein, also werden sie automatisch\n" +"mit Pixelwiederholung vergrößert, um scharfe Pixel zu behalten. Dies setzt " +"die\n" +"minimale Texturengröße für die vergrößerten Texturen; höhere Werte führen\n" +"zu einem schärferen Aussehen, aber erfordern mehr Speicher. Zweierpotenzen\n" +"werden empfohlen. Diese Einstellung trifft NUR dann in Kraft, falls\n" +"der bilineare/trilineare/anisotrope Filter aktiviert ist.\n" +"Dies wird außerdem verwendet als die Basisblocktexturengröße für\n" +"welt-ausgerichtete automatische Texturenskalierung." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Ob Namensschildhintergründe standardmäßig angezeigt werden sollen.\n" +"Mods können immer noch einen Hintergrund setzen." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"Ob Blocktexturanimationen pro Kartenblock desynchronisiert sein sollten." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Ob Spieler an Clients ohne Distanzbegrenzung angezeigt werden.\n" +"Veraltet, benutzen Sie stattdessen die Einstellung " +"„player_transfer_distance“." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Ob sich Spieler gegenseitig Schaden zufügen und töten können." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Ob Clients gefragt werden sollen, sich nach einem (Lua-)Absturz neu zu " +"verbinden.\n" +"Auf „wahr“ setzen, falls Ihr Server für automatische Neustarts eingerichtet " +"ist." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Ob das Ende des sichtbaren Gebietes im Nebel verschwinden soll." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Ob die Töne stummgeschaltet werden. Man kann die Töne jederzeit " +"stummschalten,\n" +"außer, wenn das Tonsystem ausgeschaltet wurde (enable_sound=false).\n" +"Im Spiel können die Töne mit der Stummtaste oder mit Hilfe des\n" +"Pausemenüs stummgeschaltet werden." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" +"Ob technische Namen angezeigt werden sollen.\n" +"Betrifft Mods und Texturenpakete in den Inhalte- und Modauswahlmenüs,\n" +"als auch die Einstellungsnamen in Alle Einstellungen.\n" +"Wird vom Kontrollkästchen im „Alle Einstellungen“-Menü beeinflusst." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"Ob der Client Debug-Informationen zeigen soll (hat die selbe Wirkung wie das " +"Drücken von F5)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Breiten-Komponente der anfänglichen Fenstergröße. Im Vollbildmodus ignoriert." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Breite der Auswahlboxlinien um Blöcke." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Nur für Windows-Systeme: Startet Minetest mit dem Kommandozeilenfenster im\n" +"Hintergrund. Enthält die selbe Information wie die Datei debug.txt " +"(Standardname)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Weltverzeichnis (alles in der Welt wird hier gespeichert).\n" +"Nicht benötigt, wenn vom Hauptmenü aus gestartet wird." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Weltstartzeit" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Welt-ausgerichtete Texturen können skaliert werden, um über mehrere\n" +"Blöcke zu reichen. Allerdings könnte der Server nicht die Skalierung\n" +"senden, die Sie gerne hätten, besonders dann, wenn Sie ein besonders\n" +"gestaltetes Texturenparket benutzen; mit dieser Einstellung versucht\n" +"der Client, die Skalierung automatisch basierend auf der Texturengröße\n" +"zu ermitteln.\n" +"Sie auch: texture_min_size.\n" +"Achtung: Diese Einstellung ist EXPERIMENTELL!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Welt-ausgerichtete-Texturen-Modus" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y-Höhe des flachen Bodens." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y der Bergdichtenverlaufsnullhöhe. Benutzt, um Berge vertikal zu verschieben." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Y-Wert der Obergrenze von großen Höhlen." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Y-Entfernung, über welche Hohlräume zu voller Größe expandieren." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Y-Distanz, über welche die Schwebeländer sich von voller Dichte\n" +"zu nichts zuspitzen. Die Zuspitzung beginnt an dieser Distanz vom\n" +"Y-Limit.\n" +"Für eine durchgehende Schwebelandebene regelt dies die Höhe von\n" +"Hügeln/Bergen.\n" +"Muss kleiner als oder gleich der Hälfte der Distanz zwischen den\n" +"Y-Limits sein." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Y-Höhe der durchschnittlichen Geländeoberfläche." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Y-Höhe der Obergrenze von Hohlräumen." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Y-Höhe von erhöhtem Gelände, welches Klippen erzeugt." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Y-Höhe von niedrigerem Gelände und dem Meeresgrund." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Y-Höhe vom Meeresgrund." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "cURL" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "cURL-Dateidownload-Zeitüberschreitung" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "cURL-Interaktiv-Zeitüberschreitung" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "cURL-Parallel-Begrenzung" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Kreativmodus: " + +#~ msgid "- Damage: " +#~ msgstr "- Schaden: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = Parallax-Mapping mit Stufeninformation (schneller).\n" +#~ "1 = Relief-Mapping (langsamer, genauer)." + +#~ msgid "Address / Port" +#~ msgstr "Adresse / Port" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Ändert die Gammakodierung der Lichttabellen. Kleinere Werte sind heller.\n" +#~ "Diese Einstellung ist rein clientseitig und wird vom Server ignoriert." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "" +#~ "Verändert, wie Schwebeländer des Bergtyps sich über und unter dem " +#~ "Mittelpunkt zuspitzen." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Sind Sie sicher, dass Sie die Einzelspielerwelt löschen wollen?" + +#~ msgid "Back" +#~ msgstr "Rücktaste" + +#~ msgid "Basic" +#~ msgstr "Grundlegend" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bits pro Pixel (Farbtiefe) im Vollbildmodus." + +#~ msgid "Bump Mapping" +#~ msgstr "Bumpmapping" + +#~ msgid "Bumpmapping" +#~ msgstr "Bumpmapping" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "Mitte der Lichtkurven-Mittenverstärkung." + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Ändert die Hauptmenü-UI:\n" +#~ "- Full: Mehrere Einzelspielerwelten, Spiel- und Texturenpaketauswahl, " +#~ "usw.\n" +#~ "- Simple: Eine Einzelspielerwelt, keine Spiel- oder " +#~ "Texturenpaketauswahl. Könnte\n" +#~ "für kleinere Bildschirme nötig sein." + +#~ msgid "Config mods" +#~ msgstr "Mods konfigurieren" + +#~ msgid "Configure" +#~ msgstr "Konfigurieren" + +#~ msgid "Connect" +#~ msgstr "Verbinden" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Regelt die Sinkgeschwindigkeit in Flüssigkeiten." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Legt die Dichte von Gebirgen in den Schwebeländern fest.\n" +#~ "Dies ist ein Versatz, der zum Rauschwert „mgv7_np_mountain“ addiert wird." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Legt die Breite von Tunneln fest; ein kleinerer Wert erzeugt breitere " +#~ "Tunnel." + +#~ msgid "Credits" +#~ msgstr "Mitwirkende" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Fadenkreuzfarbe (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Schaden aktiviert" + +#~ msgid "Darkness sharpness" +#~ msgstr "Dunkelheits-Steilheit" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Standardzeitlimit für cURL, in Millisekunden.\n" +#~ "Hat nur eine Wirkung, wenn mit cURL kompiliert wurde." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Definiert Gebiete von ruhig verlaufendem\n" +#~ "Gelände in den Schwebeländern. Weiche\n" +#~ "Schwebeländer treten auf, wenn der\n" +#~ "Rauschwert > 0 ist." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Definiert die Sampling-Schrittgröße der Textur.\n" +#~ "Ein höherer Wert resultiert in weichere Normal-Maps." + +#~ msgid "Del. Favorite" +#~ msgstr "Favorit löschen" + +#~ msgid "" +#~ "Deprecated, define and locate cave liquids using biome definitions " +#~ "instead.\n" +#~ "Y of upper limit of lava in large caves." +#~ msgstr "" +#~ "Misbilligte Einstellung. Definieren/Finden Sie statdessen " +#~ "Höhlenflüssigkeiten in Biomdefinitionen.\n" +#~ "Y der Obergrenze von Lava in großen Höhlen." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "" +#~ "Laden Sie sich ein Spiel (wie Minetest Game) von minetest.net herunter" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Spiele können von minetest.net heruntergeladen werden" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "$1 wird heruntergeladen und installiert, bitte warten …" + +#~ msgid "Enable VBO" +#~ msgstr "VBO aktivieren" + +#~ msgid "Enable register confirmation" +#~ msgstr "Registrierungsbestätigung aktivieren" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Aktiviert das Bump-Mapping für Texturen. Normal-Maps müssen im " +#~ "Texturenpaket\n" +#~ "vorhanden sein oder müssen automatisch erzeugt werden.\n" +#~ "Shader müssen aktiviert werden, bevor diese Einstellung aktiviert werden " +#~ "kann." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Aktiviert filmisches Tone-Mapping" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Aktiviert die spontane Normalmap-Erzeugung (Prägungseffekt).\n" +#~ "Für diese Einstellung muss außerdem Bump-Mapping aktiviert sein." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Aktiviert Parralax-Occlusion-Mapping.\n" +#~ "Hierfür müssen Shader aktiviert sein." + +#~ msgid "Enter " +#~ msgstr "Eingabe " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Experimentelle Einstellung, könnte sichtbare Leerräume zwischen\n" +#~ "Blöcken verursachen, wenn auf einen Wert größer 0 gesetzt." + +#~ msgid "FPS in pause menu" +#~ msgstr "Bildwiederholrate im Pausenmenü" + +#~ msgid "Fallback font shadow" +#~ msgstr "Ersatzschriftschatten" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Undurchsichtigkeit des Ersatzschriftschattens" + +#~ msgid "Fallback font size" +#~ msgstr "Ersatzschriftgröße" + +#~ msgid "Filtering" +#~ msgstr "Filter" + +#~ msgid "Floatland base height noise" +#~ msgstr "Schwebeland-Basishöhenrauschen" + +#~ msgid "Floatland mountain height" +#~ msgstr "Schwebelandberghöhe" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "" +#~ "Undurchsichtigkeit des Schattens der Schrift (Wert zwischen 0 und 255)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Schriftgröße der Ersatzschrift in Punkt (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "FreeType-Schriften" + +#~ msgid "Full screen BPP" +#~ msgstr "Vollbildfarbtiefe" + +#~ msgid "Game" +#~ msgstr "Spiel" + +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Normalmaps generieren" + +#~ msgid "Generate normalmaps" +#~ msgstr "Normalmaps generieren" + +#~ msgid "HUD scale factor" +#~ msgstr "HUD-Skalierungsfaktor" + +#~ msgid "High-precision FPU" +#~ msgstr "Hochpräzisions-FPU" + +#~ msgid "IPv6 support." +#~ msgstr "IPv6-Unterstützung." + +#~ msgid "In-Game" +#~ msgstr "Spiel" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Installation: Datei: „$1“" + +#~ msgid "Instrumentation" +#~ msgstr "Instrumentierung" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Steuerung (Falls dieses Menü defekt ist, entfernen Sie Zeugs aus minetest." +#~ "conf)" + +#~ msgid "Lava depth" +#~ msgstr "Lavatiefe" + +#~ msgid "Lightness sharpness" +#~ msgstr "Helligkeitsschärfe" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Erzeugungswarteschlangengrenze auf Festspeicher" + +#~ msgid "Main" +#~ msgstr "Hauptmenü" + +#~ msgid "Main menu style" +#~ msgstr "Hauptmenü-Stil" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "DirectX mit LuaJIT zusammenarbeiten lassen. Deaktivieren Sie dies, falls " +#~ "es Probleme verursacht." + +#~ msgid "Menus" +#~ msgstr "Menüs" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Übersichtskarte im Radarmodus, Zoom ×2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Übersichtskarte im Radarmodus, Zoom ×4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Übersichtskarte im Bodenmodus, Zoom ×2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Übersichtskarte im Bodenmodus, Zoom ×4" + +#~ msgid "Name / Password" +#~ msgstr "Name / Passwort" + +#~ msgid "Name/Password" +#~ msgstr "Name/Passwort" + +#~ msgid "No" +#~ msgstr "Nein" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Normalmaps-Sampling" + +#~ msgid "Normalmaps strength" +#~ msgstr "Normalmap-Stärke" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Anzahl der Parallax-Occlusion-Iterationen." + +#~ msgid "Ok" +#~ msgstr "OK" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "" +#~ "Undurchsichtigkeit (Alpha) des Schattens hinter der Ersatzschrift, " +#~ "zwischen 0 und 255." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "" +#~ "Startwert des Parallax-Occlusion-Effektes, üblicherweise Skalierung " +#~ "geteilt durch 2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Gesamtskalierung des Parallax-Occlusion-Effektes." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallax-Occlusion" + +#~ msgid "Parallax occlusion" +#~ msgstr "Parallax-Occlusion" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Parallax-Occlusion-Startwert" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Parallax-Occlusion-Iterationen" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Parallax-Occlusion-Modus" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Parallax-Occlusion-Skalierung" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Parallax-Occlusion-Stärke" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Pfad zu einer TrueType- oder Bitmap-Schrift." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Pfad, in dem Bildschirmfotos abgespeichert werden." + +#~ msgid "Player name" +#~ msgstr "Spielername" + +#~ msgid "Profiling" +#~ msgstr "Profiling" + +#~ msgid "Projecting dungeons" +#~ msgstr "Herausragende Verliese" + +#~ msgid "PvP enabled" +#~ msgstr "Spielerkampf aktiviert" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Einzelspielerwelt zurücksetzen" + +#~ msgid "Select Package File:" +#~ msgstr "Paket-Datei auswählen:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Server / Einzelspieler" + +#~ msgid "" +#~ "Set the shadow update time.\n" +#~ "Lower value means shadows and map updates faster, but it consume more " +#~ "resources.\n" +#~ "Minimun value 0.001 seconds max value 0.2 seconds" +#~ msgstr "" +#~ "Setzt die Schattenupdatezeit.\n" +#~ "Ein niedrigerer Wert bedeutet, dass Schatten und die Karte schneller " +#~ "aktualisiert werden, aber dies verbraucht mehr Ressourcen.\n" +#~ "Minimalwert: 0.001 Sekunden. Maximalwert: 0.2 Sekunden.\n" +#~ "(Beachten Sie die englische Notation mit Punkt als Dezimaltrennzeichen.)" + +#~ msgid "Shadow limit" +#~ msgstr "Schattenbegrenzung" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Versatz des Schattens hinter der Ersatzschrift (in Pixeln). Falls 0, wird " +#~ "der Schatten nicht gezeichnet." + +#~ msgid "Special" +#~ msgstr "Spezial" + +#~ msgid "Special key" +#~ msgstr "Spezialtaste" + +#~ msgid "Start Singleplayer" +#~ msgstr "Einzelspieler starten" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Stärke der generierten Normalmaps." + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "Stärke der Lichtkurven-Mittenverstärkung." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Diese Schrift wird von bestimmten Sprachen benutzt." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Um Shader zu aktivieren, muss der OpenGL-Treiber genutzt werden." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Filmmodus umschalten" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Typische Maximalhöhe, über und unter dem Mittelpunkt von Gebirgen in den\n" +#~ "Schwebeländern." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Variierung der Hügelhöhe und Seetiefe in den ruhig verlaufenden\n" +#~ "Regionen der Schwebeländer." + +#~ msgid "View" +#~ msgstr "Ansehen" + +#~ msgid "Waving Water" +#~ msgstr "Wasserwellen" + +#~ msgid "Waving water" +#~ msgstr "Wasserwellen" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Ob FreeType-Schriften benutzt werden. Dafür muss FreeType-Unterstüzung " +#~ "einkompiliert worden sein.\n" +#~ "Falls deaktiviert, werden stattdessen Bitmap- und XML-Vektor-Schriften " +#~ "benutzt." + +#~ msgid "Whether dungeons occasionally project from the terrain." +#~ msgstr "Ob Verliese manchmal aus dem Gelände herausragen." + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Y-Wert der Obergrenze von Lava in großen Höhlen." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "" +#~ "Y-Höhe vom Mittelpunkt der Schwebeländer sowie\n" +#~ "des Wasserspiegels von Seen." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Y-Höhe, bis zu der sich die Schatten der Schwebeländer ausbreiten." + +#~ msgid "Yes" +#~ msgstr "Ja" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Sie sind im Begriff, dem Server mit dem Namen „%s“ für das erste Mal " +#~ "beizutreten.\n" +#~ "Falls Sie fortfahren, wird ein neues Benutzerkonto mit Ihren Anmeldedaten " +#~ "auf diesem Server erstellt.\n" +#~ "Bitte geben Sie Ihr Passwort erneut ein und klicken Sie auf „Registrieren " +#~ "und beitreten“, um die Erstellung des Benutzerkontos zu bestätigen oder " +#~ "klicken Sie auf „Abbrechen“ zum Abbrechen." + +#~ msgid "You died." +#~ msgstr "Sie sind gestorben." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/dv/minetest.po b/po/dv/minetest.po new file mode 100644 index 0000000..6626fd9 --- /dev/null +++ b/po/dv/minetest.po @@ -0,0 +1,6986 @@ +msgid "" +msgstr "" +"Project-Id-Version: Dhivehi (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2019-11-10 15:04+0000\n" +"Last-Translator: Krock <mk939@ymail.com>\n" +"Language-Team: Dhivehi <https://hosted.weblate.org/projects/minetest/" +"minetest/dv/>\n" +"Language: dv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.10-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "މެއިން މެނޫ" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "އަލުން ސްޕައުންވޭ" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "މަރުވީ" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "An error occurred in a Lua script:" +msgstr "މޮޑެއްފަދަ ލުއޭ ސްކްރިޕްޓެއްގައި މައްސަލައެއް ޖެހިއްޖެ:" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "An error occurred:" +msgstr "މޮޑެއްފަދަ ލުއޭ ސްކްރިޕްޓެއްގައި މައްސަލައެއް ދިމާވެއްޖެ:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "maigandu menu" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "aa gulhumeh" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "ސަާވަރ އިން ރިކަނެކްޓަކަށް އެދެފި:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "ދުނިޔެ އިހްތިޔާރު ކުރޭ:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "ޕްރޮޓޮކޯލް ވާޝަން ފުށުއެރުމެއް. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "ސާވަރ އިން ޕްރޮޓޮކޯލް ވާޝަން 1$ ތަންފީޒުކުރޭ. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "$1 އާއި 2$ ދެމެދުގެ ޕްރޮޓޮކޯލް ވާޝަންތައް ސާވަރ ސަިޕޯޓް ކުރޭ. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "އަޅުގަނޑުމެން ހަމައެކަނި ސަޕޯޓްކުރަނީ ޕްރޮޓޮކޯލް ވާޝަން 1$." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "އަޅުގަނޑުމެން 1$ އާއި 2$ އާއި ދެމެދުގެ ޕޮރޮޓޮކޯލް ވާޝަންތައް ސަޕޯޓް ކުރަން." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "ކެންސަލް" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "ބަރޯސާވާ(ޑިޕެންޑެންސީޒް):" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "ހުރިހާ އެއްޗެއް އޮފްކޮށްލާ" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "މޮޑްޕެކް އޮފްކުރޭ" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "ހުރިހާއެއްޗެއް ޖައްސާ" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "މޮޑްޕެކްގެ އޮންކުރޭ:" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "މަނާ އަކުރުތަށް ހިމެނޭތީ މޮޑް '1$' ނުޖެއްސުނު. ހަމައެކަނި ހުއްދައީ [Z-A0-9] މި އަކުރުތައް." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "މޮޑް:" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No (optional) dependencies" +msgstr "ލާޒިމުނޫން ޑިޕެންޑެންސީތައް:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No hard dependencies" +msgstr "އެއްވެސް ޑިޕެންޑެންސީއެއް ނެތް." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No optional dependencies" +msgstr "ލާޒިމުނޫން ޑިޕެންޑެންސީތައް:" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "ލާޒިމުނޫން ޑިޕެންޑެންސީތައް:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "ސޭވްކުރޭ" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "ދުނިޔެ:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "ޖައްސާފަ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "ލޯޑްވަނީ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "އެނބުރި މެއިން މެނޫއަށް" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "ގޭމް ހޮސްޓްކުރޭ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Downloading..." +msgstr "ލޯޑްވަނީ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "$1 ނޭޅުނު" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "ގޭމްތައް" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "އަޅާ" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "އަޅާ" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "ލާޒިމުނޫން ޑިޕެންޑެންސީތައް:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "މޮޑްތައް" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "ފުހެލާ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "\"$1\" ކޔާ ދިުނިޔެއެއް އެބައިން" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "ހަދާ" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Decorations" +msgstr "މޮޑްގެ މައުލޫލާތު:" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "އިންޒާރު: މިނިމަލް ޑިވެލޮޕްމަންޓް ހާއްސަކުރެވިފައިވަނީ ޑިވެލޮޕަރުންނަށް." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "އަޅާ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "މެޕްޖެން" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mapgen-specific flags" +msgstr "މެޕްޖެން" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "އެއްވެސް ގޭމެއް އިހްތިޔާރުވެފައެއް ނެޠް" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "ސީޑް" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "ދުނިޔޭގެ ނަން" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "އެއްވެސް ސަބްގޭމެއް އެޅިފައެއް ނެތް." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "\"$1\" ޑިލީޓްކުރައްވަން ބޭނުންފުޅުކަން ޔަގީންތޯ؟" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "ޑިލީޓްކުރޭ" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "މޮޑްއެމް.ޖީ.އާރް: \"1$\" ޑިލީޓެއް ނުކުރެވުނު" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "މޮޑްއެމް.ޖީ.އާރް: ޕާތު \"1$\" ބާތިލް" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "ދުނިޔެ \"1$\" ޑިލީޓްކުރަންވީތޯ؟" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "ޕާސްވޯޑް / ނަން" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "ގަބޫލުކުރޭ" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "މޮޑްޕެކްގެ ނަން ބަދަލުކުރޭ:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(ސެޓިންގްގެ ތައާރަފެއް ދީފައެއް ނެތް)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "އަނބުރާ ސެޓިންގްސް ސަފުހާއަށް>" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "ފުންކޮށް ހޯދާ" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "ގޭމް ހޮސްޓްކުރޭ" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "ސޮޓޯރ ކުލޯޒްކޮށްލާ" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "އޮފްކޮށްފަ" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "ބަދަލުކުރޭ" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "ޖައްސާފަ" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "ސައްހަ އިންޓީޖަރއެއް ލިޔުއްވާ." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "ސައްހަ އަދަދެއް ލިޔުއްވާ." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "ޑިފޯލްޓައަށް ރައްދުކުރޭ" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "ހޯދާ" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Select directory" +msgstr "މޮޑްގެ ފައިލް އިހްތިޔާރުކުރޭ:" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Select file" +msgstr "މޮޑްގެ ފައިލް އިހްތިޔާރުކުރޭ:" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "ޓެކްނިކަލް ނަންތައް ދައްކާ" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "އަދަދު އެންމެ ކުޑަވެގެން 1$އަށް ވާން ޖެހޭ." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "އަދަދު 1$އަށްވުރެއް ބޮޑުވާންޖެހޭ." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "$1 (Enabled)" +msgstr "ޖައްސާފަ" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "$1 $2އަށް ނޭޅުނު" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a $1 as a texture pack" +msgstr "$1 $2އަށް ނޭޅުނު" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a game as a $1" +msgstr "$1 $2އަށް ނޭޅުނު" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a mod as a $1" +msgstr "$1 $2އަށް ނޭޅުނު" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a modpack as a $1" +msgstr "$1 $2އަށް ނޭޅުނު" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "ލޯޑްވަނީ..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "ޕަބްލިކް ސާވަރ ލިސްޓު އަލުން ޖައްސަވާ.އަދި އިންޓަނެޓް ކަނެކްޝަން ޗެކްކުރައްވާ." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "މޮޑްގެ ފައިލް އިހްތިޔާރުކުރޭ:" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Disable Texture Pack" +msgstr "އެމް.ޕީ އޮފްކޮށްލާ" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Information:" +msgstr "މޮޑްގެ މައުލޫލާތު:" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Installed Packages:" +msgstr "އެޅިފައިވާ މޮޑްތައް:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "އެއްވެސް ޑިޕެންޑެންސީއެއް ނެތް." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "ނަންބަދަލުކުރޭ" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Uninstall Package" +msgstr "އިހްތިޔާރުކުރެވިފައިވާ މޮޑް ޑިލީޓްކުރޭ" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "ސާވަރ އިއުލާންކުރޭ" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "ކްރިއޭޓިވް މޯޑް" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "ގެއްލުން ޖައްސާ" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "ގޭމް ހޮސްޓްކުރޭ" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "ސާވަރއެއް ހޮސްޓްކުރޭ" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "އައު" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "އެއްވެސް ދުނިޔެއެއް އުފެދިފައެއް ނުވަތަ އިހްތިޔާރުވެފައެއް ނެޠް!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "ގޭމް ކުޅޭ" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "ޕޯޓް" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "ދުނިޔެ އިހްތިޔާރު ކުރޭ:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "ދުނިޔެ އިހްތިޔާރު ކުރޭ:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "ސާވަރ ޕޯޓް" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Start Game" +msgstr "ގޭމް ހޮސްޓްކުރޭ" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "އެޑްރެސް / ޕޯޓް" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "ކްރިއޭޓިވް މޯޑް" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "އެންމެ ގަޔާވޭ" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Join Game" +msgstr "ގޭމް ހޮސްޓްކުރޭ" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "ސާވަރ އިއުލާންކުރޭ" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "އެންމެ ގަޔާނުވޭ" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "ސާވަރ ޕޯޓް" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "ނެތް" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "ސްކްރީން:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "މެއިން މެނޫ" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "" + +#: src/client/game.cpp +msgid "- Public: " +msgstr "" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "މޮޑެއްފަދަ ލުއޭ ސްކްރިޕްޓެއްގައި މައްސަލައެއް ދިމާވެއްޖެ:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward enabled" +msgstr "އަނިޔާވުން ޖައްސާފައި" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Camera update enabled" +msgstr "އަނިޔާވުން ޖައްސާފައި" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode enabled" +msgstr "އަނިޔާވުން ޖައްސާފައި" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"ޑިފޯލްޓް ކޮންޓްޜޯލްތައް:\n" +"މެނޫ ނުފެންނައިރު:\n" +"-އެއްފަހަރު ފިއްތުން: ފިތް އޮންކުރުން\n" +"-ދެފަހަރު ފިއްތުން: ބޭންދުން/ބޭނުންކުރުން\n" +"-އިނގިލި ކާތާލުން: ފަރާތްފަޜާތަށް ބެލުން\n" +"މެނޫ/އިންވެންޓަރީ ފެންނައިރު:\n" +"-ދެ ފަހަރު ފިއްތުން(ބޭރުގަ)\n" +"-->ކްލޯޒްކުރޭ\n" +"-ބަރީގައި އަތްލާފައި ޖާގައިގައި އަތްލުން:\n" +"-->ބަރީގެ ތަން ބަދަލުކުރޭ\n" +"-އަތްލާފައި ދަމާ، ދެވަނަ އިނގިލިން ފިއްތާ:\n" +"-->ޖާގައިގައި އެކަތި ބައިންދާ\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "މެއިން މެނޫ" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fast mode enabled" +msgstr "އަނިޔާވުން ޖައްސާފައި" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode enabled" +msgstr "އަނިޔާވުން ޖައްސާފައި" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog disabled" +msgstr "އޮފްކޮށްފަ" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog enabled" +msgstr "ޖައްސާފަ" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Noclip mode enabled" +msgstr "އަނިޔާވުން ޖައްސާފައި" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "ވާތު މެނޫ" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "މެނޫ" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "ކަނާތު މެނޫ" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "އިހްތިޔާރުކުރޭ" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "$1 ނޭޅުނު" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Change camera" +msgstr "ފިތްތައް ބަދަލުކުރޭ" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "dv" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"ކަނެކްޓްވާންވީ އެޑްރެސް.\n" +"ލޯކަލް ސާވަރ އެއް ފެއްޓެވުމަށް މި ހުސްކޮށް ދޫކޮށްލައްވާ.\n" +"މެއިން މެނޫގެ އެޑްރެސް ގޮޅި މި ސެޓިންގްއަށްވުރެ ނުފޫޒު ގަދަެވާނެކަމަށް ދަންނަވަން." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "ދުނިޔޭގެ ނަން" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Announce to this serverlist." +msgstr "ސާވަރ އިއުލާންކުރޭ" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "ފިތްތައް ބަދަލުކުރޭ" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "މެނޫގައި ވިލާތައް" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ContentDB URL" +msgstr "ސޮޓޯރ ކުލޯޒްކޮށްލާ" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "ކްރިއޭޓިވް" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"އާ ދުނިޔެއެއް އުފައްދާއިރު ޑިފޯލްޓްކޮށް ބޭނުންކުރާ ގޭމް.\n" +"މެއިން މެނޫއިން ދުނިޔެއެއް ހަދާއިރު މީގެ މައްޗަށް ބާރު ހިނގާނެ." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "މޮޑްގެ މައުލޫލާތު:" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "ގޭމްތައް" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "މެއިން މެނޫ ސްކްރިޕްޓް" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat" +msgstr "މެޕްޖެން" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal" +msgstr "މެޕްޖެން" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "މެޕްޖެން" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5" +msgstr "މެޕްޖެން" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6" +msgstr "މެޕްޖެން" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7" +msgstr "މެޕްޖެން" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"ކުޅުންތެރިޔާގެ ނަން.\n" +"ސާވަރއެއް ހިންގަވާއރު މިނަމުގައި ކަނެކްޓްވާ ކްލައެންޓުންނަކީ އެޑްމިނުން.\n" +"މެއިން މެނޫއިން ފައްޓަވާއިރު މީގެ މައްޗަށް ބާރު ހިނގާނެ ވާހަކަ ދަންނަވަން." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "ސްކްރީން:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "ސްކްރީން:" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "ސާވަރއެއް ހޮސްޓްކުރޭ" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "ސާވަރ ޕޯޓް" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "ސާވަރ ޕޯޓް" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "World start time" +msgstr "ދުނިޔޭގެ ނަން" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "Configure" +#~ msgstr "ބަދަލުގެނޭ" + +#~ msgid "Connect" +#~ msgstr "ކަނެކްޓްކުރޭ" + +#~ msgid "Damage enabled" +#~ msgstr "އަނިޔާވުން ޖައްސާފައި" + +#, fuzzy +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "މައިންޓެސްޓް_ގޭމް ފަދަ ސަބްގޭމެއް މައިންޓެސްޓް.ނެޓް އިން ޑައުންލޯޑްކުރައްވާ" + +#~ msgid "Download one from minetest.net" +#~ msgstr "މައިންޓެސްޓް.ނެޓް އިން އެކަތި ޑައުންލޯޑްކުރައްވާ" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "$1 ޑައުންލޯޑޮކޮށް އިންސްޓޯލްކުރަނީ، މަޑުކުރައްވާ..." + +#~ msgid "FPS in pause menu" +#~ msgstr "ޕޯސް މެނޫގައި އެފް.ޕީ.އެސް" + +#~ msgid "Game" +#~ msgstr "ގޭމް" + +#, fuzzy +#~ msgid "Install: file: \"$1\"" +#~ msgstr "މޮޑް އަޚާ: ފައިލް:\"1$\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "ފިތްތައް. (މި މެނޫ މައްސަލަ ޖެހިއްޖެނަމަ minetest.confއިން ތަކެތި ފުހެލައްވާ)" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "މެއިން މެނޫ ސްކްރިޕްޓް" + +#~ msgid "Name / Password" +#~ msgstr "ޕާސްވޯޑް / ނަން" + +#~ msgid "No" +#~ msgstr "ނޫން" + +#~ msgid "Ok" +#~ msgstr "emme rangalhu" + +#~ msgid "PvP enabled" +#~ msgstr "ޕީ.ވީ.ޕީ ޖައްސާ" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "މޮޑްގެ ފައިލް އިހްތިޔާރުކުރޭ:" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "މަރުވީ" + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/el/minetest.po b/po/el/minetest.po new file mode 100644 index 0000000..154b81e --- /dev/null +++ b/po/el/minetest.po @@ -0,0 +1,6965 @@ +msgid "" +msgstr "" +"Project-Id-Version: Greek (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-03-24 18:55+0000\n" +"Last-Translator: Elnaz javadi <elnazjavadii1369@gmail.com>\n" +"Language-Team: Greek <https://hosted.weblate.org/projects/minetest/minetest/" +"el/>\n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.12-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Διαγραφή της ουράς συνομιλίας" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Κενή εντολή." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Έξοδος στο κεντρικό μενού" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Άκυρη εντολή: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Λίστα συνδεδεμένων παικτών" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Συνδεδεμένοι παίκτες: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Η ουρά συνομιλίας είναι τώρα κενή." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Αυτή η εντολή είναι απενεργοποιημένη από τον διακομιστή." + +#: builtin/client/death_formspec.lua src/client/game.cpp +#, fuzzy +msgid "Respawn" +msgstr "Επανεμφάνηση" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Πέθανες" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Διαθέσιμες εντολές:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Διαθέσιμες εντολές: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Η εντολή δεν είναι διαθέσιμη: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Βοήθεια για τις εντολές" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Χρησιμοποιήστε το '.help <cmd>' για να λάβετε περισσότερες πληροφορίες ή το " +"'.help all' για την λίστα των εντολών." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <εντολή>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Εντάξει" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<κανένα διαθέσιμο>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Ένα σφάλμα προέκυψε σε ένα σενάριο Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Παρουσιάστηκε σφάλμα:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Κύριο μενού" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Επανασύνδεση" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Ο διακομιστής ζήτησε επανασύνδεση:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Επιλογή Τροποποιήσεων" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Ασυμφωνία έκδοσης πρωτοκόλλου. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Ο διακομιστής επιβάλλει το πρωτόκολλο έκδοσης $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Ο διακομιστής υποστηρίζει εκδόσεις πρωτοκόλλων μεταξύ $1 και $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Υποστηρίζουμε μόνο το πρωτόκολλο έκδοσης $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Υποστηρίζουμε τις εκδόσεις πρωτοκόλλων μεταξύ της έκδοσης $1 και $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Άκυρο" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Εξαρτήσεις:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Απενεργοποίηση όλων" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Απενεργοποίηση πακέτου τροποποιήσεων" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Ενεργοποίηση όλων" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Ενεργοποίηση πακέτου τροποποιήσεων" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Η ενεργοποίηση του mod \"$1\" απέτυχε καθώς περιέχει μη επιτρεπόμενους " +"χαρακτήρες. Επιτρέπονται μόνο χαρακτήρες [a-z0-9_]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Εύρεση Περισσότερων Τροποποιήσεων" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Τροποποίηση:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Δεν υπάρχουν (προαιρετικές) εξαρτήσεις" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Δεν παρέχεται περιγραφή παιχνιδιού." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Δεν υπάρχουν απαραίτητες εξαρτήσεις" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Δεν παρέχεται περιγραφή για το πακέτο τροποποιήσεων." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Δεν υπάρχουν προαιρετικές εξαρτήσεις" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Προαιρετικές εξαρτήσεις:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Αποθήκευση" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Κόσμος:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "ενεργοποιήθηκε" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "Το \"$1\" ήδη υπάρχει. Θέλετε να το αντικαταστήσετε;" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Οι εξαρτήσεις $1 και $2 θα εγκατασταθούν." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 με $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 σε λήψη,\n" +"$2 σε αναμονή" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "Λήψη ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "Δεν ήταν δυνατή η εύρεση των απαιτούμενων εξαρτήσεων $1." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "Θα εγκατασταθεί το $1 και οι εξαρτήσεις $2 θα παραβλεφθούν." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Όλα τα Πακέτα" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Ήδη εγκαταστημένο" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Πίσω στο Κύριο Μενού" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Βασικό παιχνίδι:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" +"Το ContentDB δεν είναι διαθέσιμο όταν το Minetest μεταγλωττίστηκε χωρίς cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Λήψη ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Η λήψη του $1 απέτυχε" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Παιχνίδια" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Εγκατάσταση" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Εγκατάσταση $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Εγκατάσταση των εξαρτήσεων που λείπουν" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Εγκατάσταση: Μη υποστηριζόμενος τύπος αρχείου ή κατεστραμμένο αρχείο" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Τροποποιήσεις" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Δεν ήταν δυνατή η ανάκτηση πακέτων" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Χωρίς αποτελέσματα" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Δεν υπάρχουν ενημερώσεις" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Δε βρέθηκε" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Αντικατάσταση" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Ελέγξτε ότι το βασικό παιχνίδι είναι σωστό." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Σε αναμονή" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Πακέτα υφής" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Απεγκατάσταση" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Αναβάθμιση" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Ενημέρωση Όλων [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Δείτε περισσότερες πληροφορίες σε ένα πρόγραμμα περιήγησης ιστού" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Υπάρχει ήδη ένας κόσμος με το όνομα \"$1\"" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Πρόσθετο έδαφος" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Κρύο υψομέτρου" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Ξηρασία υψομέτρου" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Σπήλαια" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Σπηλιές" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Δημιουργία" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Διακοσμήσεις" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Προειδοποίηση: Τα Development Test προορίζονται για προγραμματιστές." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Μπουντρούμια" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Επίπεδο έδαφος" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Αιωρούμενες μάζες γης στον ουρανό" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Αιωρούμενες μάζες γης (πειραματικό)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Δημιουργία non-fractal εδάφους: ωκεανοί και υπόγεια" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Λόφοι" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Υγρά ποτάμια" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Αύξηση της υγρασίας γύρω από τα ποτάμια" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Εγκατάσταση $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Λίμνες" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Η χαμηλή υγρασία και η υψηλή ζέστη προκαλούν ρηχά ή ξηρά ποτάμια" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Δημιουργία χάρτη" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Ρυθμίσεις δημιουργίας χάρτη" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Ειδικές ρυθμίσεις δημιουργίας χάρτη" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Βουνά" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Ροή λάσπης" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Δίκτυο σηράγγων και σπηλαίων" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Κανένα παιχνίδι επιλεγμένο" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Μείωση της θερμότητας με το υψόμετρο" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Μείωση της υγρασίας με το υψόμετρο" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Ποτάμια" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Ποτάμια στο επίπεδο της θάλασσας" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Σπόρος" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Κατασκευές που εμφανίζονται στο έδαφος (καμία επίδραση στα δέντρα και το " +"γρασίδι της ζούγκλας που δημιουργήθηκε από v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Δομές που εμφανίζονται στο έδαφος, συνήθως δέντρα και φυτά" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Εύκρατο, Έρημος" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Εύκρατο, Έρημος, Ζούγκλα" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Εύκρατο, Έρημος, Ζούγκλα, Τούντρα, Τάιγκα" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Διάβρωση επιφάνειας εδάφους" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Δέντρα και γρασίδι ζούγκλας" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Μεταβολή βάθους ποταμού" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Πολύ μεγάλα σπήλαια βαθιά στο υπέδαφος" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Όνομα κόσμου" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Δεν έχετε εγκαταστήσει παιχνίδια." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Είστε βέβαιοι ότι θέλετε να διαγράψετε το \\\"$1\\\";" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Διαγραφή" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: απέτυχε η διαγραφή του \\\"$1\\\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: μη έγκυρη διαδρομή \\\"$1\\\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Διαγραφή Κόσμου \\\"$1\\\";" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Επιβεβαίωση Κωδικού" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Όνομα" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Κωδικός" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Αποδοχή" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Μετονομασία Modpack:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Αυτό το modpack έχει ένα ρητό όνομα που δίνεται στο modpack.conf το οποίο θα " +"παρακάμψει οποιαδήποτε μετονομασία εδώ." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Δεν δόθηκε περιγραφή της ρύθμισης)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D θόρυβος" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Επιστροφή στη σελίδα Ρυθμίσεις" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Περιήγηση" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Περιεχόμενο" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Περιεχόμενο" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Απενεργοποιημένο" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Επεξεργασία" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Ενεργοποιημένο" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Οκτάβες" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Αντιστάθμιση" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Εισαγάγετε έναν έγκυρο ακέραιο αριθμό." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Εισαγάγετε έναν έγκυρο αριθμό." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Επαναφορά προεπιλογής" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Κλίμακα" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Αναζήτηση" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Επιλογή φακέλου" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Επιλογή αρχείου" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Εμφάνιση τεχνικών ονομάτων" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Η τιμή πρέπει να είναι τουλάχιστον $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Η τιμή δεν πρέπει να είναι μεγαλύτερη από $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Χ εξάπλωση" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Υ εξάπλωση" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Ζ εξάπλωση" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "απόλυτη τιμή" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "προεπιλογή" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "Ομαλός Χάρτης" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Ενεργοποιημένο)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 Τροποποιήσεις" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Αποτυχία εγκατάστασης $1 έως $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" +"Εγκατάσταση Τροποποίησης: Δεν είναι δυνατή η εύρεση του πραγματικού ονόματος " +"τροποποίησης για: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Εγκατάσταση Τροποποίησης: Δεν είναι δυνατή η εύρεση του κατάλληλου ονόματος " +"φακέλου για την τροποποίηση $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Δεν είναι δυνατή η εύρεση έγκυρης τροποποίησης ή πακέτου τροποποίησης" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Δεν είναι δυνατή η εγκατάσταση $1 ως πακέτου υφής" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Δεν είναι δυνατή η εγκατάσταση ενός παιχνιδιού ως $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Δεν είναι δυνατή η εγκατάσταση τροποποίησης ως $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Δεν είναι δυνατή η εγκατάσταση πακέτου τροποποίησης ως $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Φόρτωση..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Η λίστα δημόσιων διακομιστών είναι απενεργοποιημένη" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Δοκιμάστε να ενεργοποιήσετε ξανά τη δημόσια λίστα διακομιστών και ελέγξτε τη " +"σύνδεσή σας στο διαδίκτυο." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Σχετικά" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Ενεργοί Συντελεστές" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Βασικοί Προγραμματιστές" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Άνοιγμα Καταλόγου Δεδομένων Χρήστη" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Ανοίγει τον κατάλογο που περιέχει κόσμους, παιχνίδια, τροποποιήσεις που " +"παρέχονται από τον χρήστη,\n" +"και πακέτα υφής σε έναν διαχειριστή αρχείων / εξερευνητή." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Προηγούμενοι Συντελεστές" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Προηγούμενοι Βασικοί Προγραμματιστές" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Περιήγηση διαδικτυακού περιεχομένου" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Περιεχόμενο" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Απενεργοποίηση πακέτου υφής" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Πληροφορίες:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Εγκαταστημένα Πακέτα:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Χωρίς εξαρτήσεις." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Δεν υπάρχει διαθέσιμη περιγραφή πακέτου" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Μετονομασία" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Απεγκατάσταση πακέτου" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Χρήση Πακέτου Υφής" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Ανακοίνωση Διακομιστή" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Δεσμευμένη διεύθυνση" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Λειτουργία Δημιουργίας" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Ενεργοποίηση Ζημίας" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Φιλοξενία Παιχνιδιού" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Διακομιστής Φιλοξενίας" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Εγκατάσταση παιχνιδιών από το ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Νέο" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Κανένας κόσμος δεν δημιουργήθηκε ούτε επιλέχθηκε!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Εκκίνηση Παιχνιδιού" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Θήρα" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Επιλογή Τροποποιήσεων" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Επιλογή Κόσμου:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Θήρα Διακομιστή" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Εκκίνηση Παιχνιδιού" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Διεύθυνση" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Εκκαθάριση" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Λειτουργία Δημιουργίας" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Μάχες μεταξύ παιχτών" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Αγαπημένα" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Μη συμβατοί διακομιστές" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Συμμετοχή στο Παιχνίδι" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Δημόσιοι Διακομιστές" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Ανανέωση" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Περιγραφή Διακομιστή" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D Σύννεφα" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Όλες οι ρυθμίσεις" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Αυτόματη αποθήκευση Μεγέθους Οθόνης" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Διγραμμικό Φίλτρο" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Αλλαγή πλήκτρων" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Δυναμικές σκιές" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Δυναμικές σκιές: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Φανταχτερά Φύλλα" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Υψηλό" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Χαμηλό" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Μεσαίο" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Χωρίς Φίλτρο" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Επισήμανση Στοιχείων" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Περίγραμμα Στοιχείων" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Κανένα" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Αδιαφανή Φύλλα" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Αδιαφανές Νερό" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Σωματίδια" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Οθόνη:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Ρυθμίσεις" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Απλά Φύλλα" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Απαλός Φωτισμός" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Υφή:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Χαρτογράφηση Τόνου" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Όριο αφής: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Τριγραμμικό Φίλτρο" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Εξαιρετικά Υψηλό" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Πολύ Χαμηλό" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Κινούμενα Φύλλα" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Κυματιζόμενα Υγρά" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Κυματιζόμενα Φυτά" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Σφάλμα σύνδεσης (λήξη χρόνου;)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Λήξη χρονικού ορίου σύνδεσης." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Έτοιμο!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Εκκίνηση στοιχείων" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Εκκίνηση στοιχείων..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Φόρτωση υφών..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Ανακατασκευή σκίαστρων..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Σφάλμα σύνδεσης (λήξη χρόνου;)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Δεν ήταν δυνατή η εύρεση ή η φόρτωση του παιχνιδιού: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Μη έγκυρη προδιαγραφή παιχνιδιού." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Κύριο μενού" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Δεν έχει επιλεγεί κόσμος και δεν παρέχεται διεύθυνση." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Το όνομα παίκτη είναι πολύ μεγάλο." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Παρακαλώ επιλέξτε ένα όνομα!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Απέτυχε το άνοιγμα του παρεχόμενου αρχείου κωδικού πρόσβασης: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Το αρχείο του Κόσμου δεν υπάρχει: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Ελέγξτε το debug.txt για λεπτομέρειες." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Διεύθυνση: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Λειτουργία: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Θήρα: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Δημόσιο: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Όνομα Διακομιστή: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Παρουσιάστηκε σφάλμα:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Δεν επιτρέπεται η πρόσβαση. Αιτία: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Η αυτόματη προώθηση είναι απενεργοποιημένη" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Η αυτόματη προώθηση είναι ενεργοποιημένη" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Αποκλεισμός ορίων κρυφά" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Τα όρια μπλοκ εμφανίζονται για όλα τα μπλοκ" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Εμφανίζονται όρια αποκλεισμού για το τρέχον μπλοκ" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Εμφανίζονται όρια αποκλεισμού για κοντινά μπλοκ" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Η ενημέρωση κάμερας απενεργοποιήθηκε" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Η ενημέρωση κάμερας ενεργοποιήθηκε" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" +"Δεν είναι δυνατή η εμφάνιση ορίων μπλοκ (χρειάζεται το δικαίωμα " +"\"basic_debug\")" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Αλλαγή Κωδικού" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Η κινηματογραφική λειτουργία απενεργοποιήθηκε" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Η κινηματογραφική λειτουργία ενεργοποιήθηκε" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Ο πελάτης αποσυνδέθηκε" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Η δέσμη ενεργειών από την πλευρά του πελάτη είναι απενεργοποιημένη" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Σύνδεση με διακομιστή..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Η σύνδεση απέτυχε για άγνωστο λόγο" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Συνέχεια" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Στοιχεία ελέγχου:\n" +"- %s: κίνηση προς τα εμπρός\n" +"- %s: κίνηση προς τα πίσω\n" +"- %s: κίνηση αριστερά\n" +"- %s: κίνηση δεξιά\n" +"- %s: άλμα/σκαρφάλωμα\n" +"- %s: σκάψιμο/διάτρηση\n" +"- %s: τοποθέτηση/χρήση\n" +"- %s: ολίσθηση/κατέβασμα\n" +"- %s: απόθεση αντικειμένου\n" +"- %s: αποθέματα\n" +"- Ποντίκι: στροφή/παρακολούθηση\n" +"- Τροχός ποντικιού: επιλογή στοιχείου\n" +"- %s: συνομιλία\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Δεν ήταν δυνατή η επίλυση της διεύθυνσης: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Δημιουργία πελάτη..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Δημιουργία διακομιστή..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Κρυφές πληροφορίες εντοπισμού σφαλμάτων και γράφημα προφίλ" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Εμφάνιση πληροφοριών εντοπισμού σφαλμάτων" + +#: src/client/game.cpp +#, fuzzy +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" +"Απόκρυψη πληροφοριών εντοπισμού σφαλμάτων, γραφήματος προφίλ και wireframe" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Προεπιλεγμένα στοιχεία ελέγχου:\n" +"Δεν εμφανίζεται μενού:\n" +"- ένα πάτημα: κουμπί ενεργοποίησης\n" +"- διπλό πάτημα: θέση/χρήση\n" +"- σύρσιμο δαχτύλου: παρακολούθηση γύρω\n" +"Ορατό μενού/απόθεμα:\n" +"- διπλό πάτημα (εξωτερικό):\n" +" -->κλείσιμο\n" +"- στοίβα αφής, υποδοχή αφής:\n" +" --> μετακίνηση στοίβας\n" +"- άγγιγμα & σύρσιμο, πάτημα του 2ου δαχτύλου\n" +" --> τοποθέτηση μεμονωμένου αντικειμένου στην υποδοχή\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Απενεργοποιημένο το απεριόριστο εύρος προβολής" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Ενεργοποιημένο το απεριόριστο εύρος προβολής" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Δημιουργία πελάτη..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Έξοδος στο Μενού" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Έξοδος στο ΛΣ" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Γρήγορη λειτουργία απενεργοποιημένη" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Γρήγορη λειτουργία ενεργοποιημένη" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" +"Γρήγορη λειτουργία ενεργοποιημένη (σημείωση: δεν υπάρχει προνόμιο \"fast\")" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Λειτουργία πτήσης απενεργοποιημένη" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Λειτουργία πτήσης ενεργοποιημένη" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" +"Λειτουργία πτήσης ενεργοποιημένη (σημείωση: δεν υπάρχει προνόμιο \"fly\")" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Η ομίχλη απενεργοποιήθηκε" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Η ομίχλη ενεργοποιήθηκε" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Πληροφορίες Παιχνιδιού:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Το παιχνίδι διακόπηκε" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Διακομιστής Φιλοξενίας" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Ορισμοί στοιχείων..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Πολλοί παίκτες" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Απομακρυσμένος διακομιστής" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Επίλυση διεύθυνσης..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Τερματισμός Λειτουργίας..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Ένταση Ήχου" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Σίγαση Ήχου" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Το Σύστημα Ήχου είναι απενεργοποιημένο" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Το Σύστημα Ήχου δεν υποστηρίζεται σε αυτή την έκδοση" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Ο διακομιστής πιθανότατα εκτελεί διαφορετική έκδοση του %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" +"Δεν είναι δυνατή η σύνδεση στο %s επειδή το IPv6 είναι απενεργοποιημένο" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" +"Δεν είναι δυνατή η ακρόαση στο %s επειδή το IPv6 είναι απενεργοποιημένο" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Το εύρος προβολής άλλαξε σε %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Το εύρος προβολής πρέπει να είναι έως: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Το εύρος προβολής πρέπει να είναι τουλάχιστον: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Η ένταση άλλαξε σε %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Το ζουμ είναι απενεργοποιημένο από το παιχνίδι ή την τροποποίηση" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Συνομιλία κρυφή" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Συνομιλία εμφανής" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Εφαρμογές" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Κάτω" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Τέλος" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Βοήθεια" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Σπίτι" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Εισαγωγή" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Αριστερά" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Μενού" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Αριθμητικό Πληκτρολόγιο *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Αριθμητικό Πληκτρολόγιο +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Αριθμητικό Πληκτρολόγιο -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Αριθμητικό Πληκτρολόγιο ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Αριθμητικό Πληκτρολόγιο /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Αριθμητικό Πληκτρολόγιο 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Αριθμητικό Πληκτρολόγιο 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Αριθμητικό Πληκτρολόγιο 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Αριθμητικό Πληκτρολόγιο 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Αριθμητικό Πληκτρολόγιο 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Αριθμητικό Πληκτρολόγιο 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Αριθμητικό Πληκτρολόγιο 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Αριθμητικό Πληκτρολόγιο 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Αριθμητικό Πληκτρολόγιο 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Αριθμητικό Πληκτρολόγιο 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Παύση" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Αναπαραγωγή" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Εκτύπωση" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Επιστροφή" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Δεξιά" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Επιλογή" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Ύπνος" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Πάνω" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Μεγέθυνση" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Εντολή" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Το πλήκτρο ήδη χρησιμοποιείται" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Σίγαση" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Επόμενο αντικείμενο" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Στιγμιότυπο οθόνης" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Αλλαγή" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Νέος Κωδικός" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Παλιός Κωδικός" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Έξοδος" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Σε σίγαση" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Sound Volume: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "el" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Παρακαλώ επιλέξτε ένα όνομα!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D σύννεφα" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Όνομα κόσμου" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Για προχωρημένους" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Εντολές Συνομιλίας" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Σύννεφα" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Διακοσμήσεις" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Ομίχλη" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Μέγεθος γραμματοσειράς" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Μέγεθος γραμματοσειράς" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Πλήρης οθόνη" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Παιχνίδια" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Βαρύτητα" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Γλώσσα" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Απαλός Φωτισμός" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Ασφάλεια" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Σίγαση ήχου" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Δίκτυο" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Επισήμανση Στοιχείων" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Οθόνη:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Στιγμιότυπο οθόνης" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL διακομιστή" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Όνομα διακομιστή" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Περιγραφή Διακομιστή" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL διακομιστή" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Διεύθυνση διακομιστή" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Περιγραφή διακομιστή" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Όνομα διακομιστή" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Θύρα διακομιστή" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Θήρα Διακομιστή" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Ήχος" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Ρυθμίσεις" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Πλήρης οθόνη" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Ένταση" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Παράλληλο όριο cURL" + +#~ msgid "Address / Port" +#~ msgstr "Διεύθυνση / Θήρα" + +#~ msgid "Basic" +#~ msgstr "Βασικό" + +#~ msgid "Connect" +#~ msgstr "Σύνδεση" + +#~ msgid "Credits" +#~ msgstr "Μνείες" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Κατέβασε ένα παιχνίδι, όπως το Minetest Game, από το minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Κατέβασε ένα από το minetest.net" + +#~ msgid "Game" +#~ msgstr "Παιχνίδι" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Εγκατάσταση: αρχείο: \"$1\"" + +#~ msgid "Name / Password" +#~ msgstr "Όνομα / Κωδικός" + +#~ msgid "Ok" +#~ msgstr "Οκ" + +#~ msgid "Player name" +#~ msgstr "Όνομα παίκτη" + +#~ msgid "Special key" +#~ msgstr "Ειδικό πλήκτρο" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Πέθανες" + +#~ msgid "needs_fallback_font" +#~ msgstr "needs_fallback_font" diff --git a/po/eo/minetest.po b/po/eo/minetest.po new file mode 100644 index 0000000..73de3a5 --- /dev/null +++ b/po/eo/minetest.po @@ -0,0 +1,8297 @@ +msgid "" +msgstr "" +"Project-Id-Version: Esperanto (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2021-10-05 08:09+0000\n" +"Last-Translator: phlostically <phlostically@mailinator.com>\n" +"Language-Team: Esperanto <https://hosted.weblate.org/projects/minetest/" +"minetest/eo/>\n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.9-dev\n" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Clear the out chat queue" +msgstr "Maksimumo da atendantaj elaj mesaĝoj" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Malplena komando." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Eliri al ĉefmenuo" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Nevalida komando: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Donita komando: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Listigi enretajn ludantojn" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Enretaj ludantoj: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Ĉi tiun komandon malŝaltis servilo." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Renaskiĝi" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Vi mortis" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Uzeblaj komandoj:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Uzeblaj komandoj: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Komando ne uzeblas: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Trovu helpon pri komandoj" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <komando>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Bone" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "<none available>" +msgstr "Komando ne uzeblas: " + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Eraris Lua-skripto:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Eraro okazis:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Ĉefmenuo" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Rekonekti" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "La servilo petis rekonekton:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Elektu Modifaĵojn" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protokola versia miskongruo. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "La servilo postulas protokolan version $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "La servilo subtenas protokolajn versiojn inter $1 kaj $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Ni nur subtenas protokolan version $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Ni subtenas protokolajn versiojn inter versioj $1 kaj $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Nuligi" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Dependas de:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Malŝalti ĉiujn" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Malŝalti modifaĵaron" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Ŝalti ĉiujn" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Ŝalti modifaĵaron" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Malsukcesis ŝalti modifaĵon «$1», ĉar ĝi enhavas malpermesatajn signojn. Nur " +"signoj a–z kaj 0–9 estas permesataj." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Trovu pliajn modifaĵojn" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Modifaĵo:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Neniuj (malnepraj) dependaĵoj" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Neniu priskribo de ludo estas donita." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Sen dependaĵoj" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Neniu priskribo de modifaĵaro estas donita." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Neniuj malnepraj dependaĵoj" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Malnepraj dependaĵoj:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Konservi" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Mondo:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "ŝaltita" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "«$ 1» jam ekzistas. Ĉu superskribi ĝin?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Dependaĵoj $1 kaj $2 estos instalitaj." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 de $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"elŝutante $1,\n" +"atendante $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "Elŝutante $1…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 nepraj dependaĵoj ne estis troveblaj." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$ 1 estos instalita, ignorante $2 dependaĵojn." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Ĉiuj pakaĵoj" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Jam instalita" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Reen al ĉefmenuo" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Baza Ludo:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB ne estas disponebla per Minetest kodotradukita sen cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Elŝutante…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Malsukcesis elŝuti $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Ludoj" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instali" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Instali $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Instali mankantajn dependaĵojn" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "Instalo: Nesubtenata dosierspeco «$1» aŭ rompita arĥivo" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Modifaĵoj" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Neniujn pakaĵojn eblis ricevi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Neniuj rezultoj" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Neniuj ĝisdatigoj" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Ne trovita" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Superskribi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Bonvolu kontroli, ke la baza ludo estas ĝusta." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Atendata" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Teksturaroj" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Malinstali" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Ĝisdatigi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Ĝisdatigi Ĉiujn [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Vidi pli da informoj per TTT-legilo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Mondo kun nomo «$1» jam ekzistas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Aldona tereno" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Alteca malvarmiĝo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Alteca sekeco" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Klimata miksado" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Klimatoj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Kavernegoj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Kavernoj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Krei" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Ornamoj" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Averto: La programista testo estas intencita por programistoj." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Forgeskeloj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Plata tereno" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Flugantaj teramasoj en la ĉielo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Fluginsuloj (eksperimentaj)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Estigi nefraktalan terenon: oceano kaj subtero" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Montetoj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Malsekaj riveroj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Plialtigas malsekecon ĉirkaŭ riveroj" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Instali $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Lagoj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Malalta malsekeco kaj alta varmeco kaŭzas malprofundajn aŭ sekajn riverojn" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Mondestigilo" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Parametroj de mondestigilo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Parametroj specialaj por Mondestigilo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Montoj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Fluo de koto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Reto de tuneloj kaj kavernoj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Neniu ludo estas elektita" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Malpliigas varmecon kun alteco" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Malpliigas malsekecon kun alteco" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Riveroj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Marnivelaj riveroj" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Fontnombro" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Glatigi transiron inter klimatoj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Konstruaĵoj aperantaj sur la tereno (neniu efiko sur arboj kaj ĝangala herbo " +"kreitaj de v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Konstruaĵoj aperantaj sur la tereno, ofte arboj kaj kreskaĵoj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Milda, Dezerto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Milda, Dezerto, Ĝangalo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Milda, Dezerto, Ĝangalo, Tundro, Tajgo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Terensurfaca forfrotiĝo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Arboj kaj ĝangala herbo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Variigi profundecon de riveroj" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Tre grandaj kavernoj profunde subtere" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nomo de mondo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Vi havas neniujn instalitajn ludojn." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Ĉu vi certe volas forigi «$1»?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Forigi" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: malskucesis forigi «$1»" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: malvalida dosiervojo «$1»" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Ĉu forigi mondon «$1»?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Konfirmi pasvorton" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Nomo de mondestigilo" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nomo" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Pasvorto" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Pasvortoj ne kongruas!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Registriĝi kaj aliĝi" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Akcepti" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Alinomi modifaĵaron:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Ĉi tiu modifaĵaro havas malimplican nomon en sia dosiero modpack.conf, kiu " +"transpasos ĉiun alinomon ĉi tiean." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Neniu priskribo de agordo estas donita)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2d-a bruo" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Reiri al agorda paĝo" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Foliumi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Enhavo" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Enhavo" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Malŝaltita" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Redakti" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Ŝaltita" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Interspacoj" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktavoj" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Deŝovo" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Persisteco" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Bonvolu enigi validan entjeron." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Bonvolu enigi validan nombron." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Restarigi pravaloron" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Skalo" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Serĉi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Elekti dosierujon" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Elekti dosieron" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Montri teĥnikajn nomojn" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "La valoro devas esti almenaŭ $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "La valoro devas esti pli ol $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X-disiĝo" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y-disiĝo" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z-disiĝo" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "absoluta valoro" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "normoj" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "faciligita" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Ŝaltita)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 modifaĵoj" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Malsukcesis instali $1 al $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Instali modifaĵon: Ne povas trovi veran nomon de modifaĵo por: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Instali modifaĵon: Ne povas trovi ĝustan dosierujan nomon por modifaĵaro $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Ne povas trovi validan modifaĵon aŭ modifaĵaron" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Malsukcesis instali $1 kiel teksturaron" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Malsukcesis instali ludon kiel $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Malsukcesis instali modifaĵon kiel $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Malsukcesis instali modifaĵaron kiel $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Enlegante…" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Listo de publikaj serviloj estas malŝaltita" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Provu reŝalti la publikan liston de serviloj kaj kontroli vian retkonekton." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Pri" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktivaj kontribuantoj" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Aktiva bildigilo:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Kernprogramistoj" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Malfermi dosierujon de datenoj de uzanto" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Malfermi per dosieradministrilo la dosierujon, kiu enhavas la mondojn,\n" +"ludojn, modifaĵojn, kaj teksturojn provizitajn de la uzanto." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Eksaj kontribuistoj" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Eksaj kernprogramistoj" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Montri erarserĉajn informojn" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Foliumi enretan enhavon" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Enhavo" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Malŝalti teksturaron" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informoj:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Instalantaj pakaĵoj:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Sen dependaĵoj." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Neniu priskribo de pakaĵo disponeblas" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Alinomi" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Malinstali pakaĵon" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Uzi teksturaron" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Enlistigi servilon" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Asocii adreso" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Krea reĝimo" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Ŝalti difektadon" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Gastigi ludon" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Gastigi servilon" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Instali ludojn de ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Nova" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Neniu mondo estas kreita aŭ elektita!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Ludi" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Pordo" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Elektu Modifaĵojn" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Elektu mondon:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Servila pordo" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Ekigi ludon" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adreso" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Vakigo" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Krea reĝimo" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "Difekto" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "Ŝati" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Neakordaj serviloj" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Aliĝi al ludo" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Retprokrasto" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Publikaj serviloj" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Reŝargi" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Fora pordo" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Priskribo pri servilo" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2×" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D nuboj" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4×" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8×" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Ĉiuj agordoj" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Glatigo:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Memori grandecon de ekrano" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Dulineara filtrilo" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Ŝanĝi klavojn" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Ligata vitro" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dinamikaj ombroj" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Dinamikaj ombroj: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Ŝikaj folioj" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Alta" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Malalta" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Mezalta" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Etmapo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Etmapo + Neizotropa filtrilo" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Neniu filtrilo" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Neniu Etmapo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Emfazado de monderoj" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Kadrado de monderoj" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Neniu" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Netravideblaj folioj" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Netravidebla akvo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partikloj" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Ekrano:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Agordoj" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Ombrigiloj" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Ombrigiloj (eksperimentaj)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Ombrigiloj (nehaveblaj)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Simplaj folioj" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Glata lumado" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Teksturado:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Nuanca mapado" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Tuŝa sojlo: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Trilineara filtrilo" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Altega" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Malaltega" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Ondantaj foliaĵoj" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Ondantaj fluaĵoj" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Ondantaj plantoj" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Konekta eraro (ĉu eltempiĝo?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Konekto eltempiĝis." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Finite!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Pravalorigante monderojn" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Pravalorigante monderojn…" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Enlegante teksturojn…" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Refarante ombrigilojn…" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Konekta eraro (ĉu eltempiĝo?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "Ne povis trovi aŭ enlegi ludon \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Nevalida ludspecifo." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Ĉefmenuo" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Neniu mondo estas elektita kaj neniu adreso donita. Nenio fareblas." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Nomo de ludanto estas tro longa." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Bonvolu elekti nomon!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Malsukcesis malfermi donitan pasvortan dosieron: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Donita monda dosierindiko ne ekzistas: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Rigardu dosieron debug.txt por detaloj." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "– Adreso: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "– Reĝimo: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "– Pordo: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "– Publika: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "– LkL: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "– Nomo de servilo: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Eraro okazis:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Memaga pluigo malŝaltita" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Memaga pluigo ŝaltita" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Ĝisdatigo de vidpunkto malŝaltita" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Ĝisdatigo de vidpunkto ŝaltita" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Ŝanĝi pasvorton" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Glita vidpunkto malŝaltita" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Glita vidpunkto ŝaltita" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "Klienta modifado" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Klient-flanka skriptado malŝaltita" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Konektante al servilo…" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Daŭrigi" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Stirado:\n" +"– %s: moviĝi antaŭen\n" +"– %s: moviĝi posten\n" +"– %s: moviĝi maldekstren\n" +"– %s: moviĝi dekstren\n" +"– %s: salti/supreniri\n" +"- %s: fosi/bati\n" +"- %s: meti/uzi\n" +"– %s: kaŝiri/malsupreniri\n" +"– %s: demeti portaĵojn\n" +"– %s: portaĵujo\n" +"– Muso: turniĝi/rigardi\n" +"– Musrado: elekti portaĵon\n" +"– %s: babili\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Kreante klienton…" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Kreante servilon…" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Erarserĉaj informoj kaj profilila grafikaĵo kaŝitaj" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Erarserĉaj informoj montritaj" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Erarserĉaj informoj, profilila grafikaĵo, kaj dratostaro kaŝitaj" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Implicita stirado:\n" +"Senmenue:\n" +"- unuobla tuŝeto: aktivigi butonon\n" +"- duobla tuŝeto: meti/uzi\n" +"- ŝova fingro: rigardi\n" +"Videbla menuo/portaĵujo:\n" +"- duobla tuŝeto (ekstere):\n" +" -->fermi\n" +"- tuŝi portaĵaron, tuŝi portaĵingon:\n" +" --> movi portaĵaron\n" +"- tuŝi kaj tiri, tuŝeti per dua fingro\n" +" --> meti unu portaĵon en portaĵingon\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Malŝaltis senliman vidodistancon" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Ŝaltis senliman vidodistancon" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Kreante klienton…" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Eliri al menuo" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Eliri al operaciumo" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Rapidega reĝimo malŝaltita" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Rapidega reĝimo ŝaltita" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Rapidega reĝimo ŝaltita (mankas rajto «rapidegi»)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Fluga reĝimo malŝaltita" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Fluga reĝimo ŝaltita" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Fluga reĝimo ŝaltita (mankas rajto «flugi»)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Nebulo malŝaltita" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Nebulo ŝaltita" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Ludaj informoj:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Ludo paŭzigita" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Gastiganta servile" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Objektaj difinoj…" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Vidaŭdaĵoj…" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Mapeto nuntempe malŝaltita de ludo aŭ modifaĵo" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Ludo por pluraj ludantoj" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Trapasa reĝimo malŝaltita" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Trapasa reĝimo ŝaltita" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Trapasa reĝimo ŝaltita (mankas rajto «trapasi»)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Monderaj difinoj…" + +#: src/client/game.cpp +msgid "Off" +msgstr "For" + +#: src/client/game.cpp +msgid "On" +msgstr "Ek" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Celilsekva reĝimo malŝaltita" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Celilsekva reĝimo ŝaltita" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profilila grafikaĵo montrita" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Fora servilo" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Serĉante adreson…" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Malŝaltiĝante…" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Ludo por unu" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Laŭteco" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Silentigite" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Sonsistemo estas malŝaltita" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Sonsistemo ne estas subtenata de ĉi tiu muntaĵo" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Malsilentigite" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Vidodistanco agordita al %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Vidodistanco maksimumas: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Vidodistanco je la minimumo: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Laŭteco agordita al %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Dratostaro montrita" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zomado nuntempe malŝaltita de ludo aŭ modifaĵo" + +#: src/client/game.cpp +msgid "ok" +msgstr "bone" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Babilo kaŝita" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Babilo montrita" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "Travida fasado kaŝita" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "Travida fasado montrita" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profililo kaŝita" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profililo montrita (paĝo %d el %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplikaĵoj" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Reenklavo" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Majuskla baskulo" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Stiro" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Malsupren" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Fino" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Viŝi dosierfinon" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Ruli" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Helpo" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Hejmen" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME-akcepto" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME-konverto" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME-eskapo" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME-reĝimŝanĝo" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME-nekonverto" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Enmeti" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Maldekstren" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Maldekstra butono" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Maldekstra Stiro" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Maldekstra Menuo" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Maldekstra Majuskligo" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Maldekstra Vindozo" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menuo" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Meza butono" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Nombra Baskulo" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Klavareta *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Klavareta +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Klavareta -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Klavareta ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Klavareta /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Klavareta 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Klavareta 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Klavareta 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Klavareta 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Klavareta 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Klavareta 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Klavareta 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Klavareta 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Klavareta 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Klavareta 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Vakigi" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Paĝon malsupren" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Paĝon supren" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Haltigo" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Ludi" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Presi" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enen" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Dekstren" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Dekstra butono" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Dekstra Stiro" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Dekstra Menuo" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Dekstra Majuskligo" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Dekstra Vindozo" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Ruluma Baskulo" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Elekti" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Majuskligo" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Dormo" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Ekrankopio" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Spacetklavo" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabo" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Supren" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X-Butono 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X-Butono 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zomo" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Mapeto kaŝita" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Mapeto en radara reĝimo, zomo ×%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Mapeto en supraĵa reĝimo, zomo ×%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Mapeto en tekstura reĝimo" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Malsukcesis elŝuti $1" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Daŭrigi" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "«Speciala» = malsupreniri" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Memirado" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Memaga saltado" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Malantaŭen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Ŝanĝi vidpunkton" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Babilo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Komando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konzolo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Malgrandigi vidodistancon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Mallaŭtigi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Dufoje tuŝetu salton por baskuligi flugan reĝimon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Lasi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Antaŭen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Pligrandigi vidodistancon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Plilaŭtigi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Portaĵujo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Salti" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Klavo jam estas uzata" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Loka komando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Silentigi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Sekva portaĵo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Antaŭa portaĵo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Ŝanĝi vidodistancon" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Ekrankopio" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Kaŝiri" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Baskuligi travidan fasadon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Baskuligi babilan protokolon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Baskuligi rapidegan reĝimon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Baskuligi flugan reĝimon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Baskuligi nebulon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Baskuligi mapeton" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Baskuligi trapasan reĝimon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Baskuligi celilsekvadon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "premi klavon" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Ŝanĝi" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nova pasvorto" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Malnova pasvorto" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Pasvortoj ne kongruas!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Foriri" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Silentigita" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Laŭteco: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "eo" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Bonvolu elekti nomon!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Korektas pozicion de virtuala stirstango.\n" +"Se malŝaltita, virtuala stirstango centriĝos je la unua tuŝo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Uzi virtualan stirstangon por agigi la butonon «aux».\n" +"Se ŝaltita, virtuala stirstango tuŝetos la butonon «aux» ankaŭ ekster la " +"ĉefa ringo." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) deŝovo de fraktalo for de la centro de la mondo en unuoj\n" +"de «scale».\n" +"Utilas por movo de volata punkto proksimen al (0, 0) por krei taŭgan\n" +"naskiĝejon, aŭ por permeso «zomi» al volata punkto per pligrandigo\n" +"de la skalo.\n" +"La normo estas agordita al taŭga naskiĝejo por aroj de Mandelbrot\n" +"kun la normaj parametroj; ĝi eble bezonos alĝustigon por aliaj situacioj.\n" +"Amplekso proksimume inter -2 kaj 2. Obligu per skalo por deŝovo\n" +"en monderoj." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z) skalo de fraktalo en monderoj.\n" +"La vera grando de la fraktalo estos du aŭ trioble pli granda.\n" +"Ĉi tiuj nombroj povas esti tre grandaj; la fraktalo ne devas\n" +"nepre engrandi la mondon.\n" +"Pligrandigu ĉi tiujn por «zomi» al la detaloj de la fraktalo.\n" +"La normo estas vertikale ŝrumpita formo taŭga por insulo;\n" +"egaligu ĉiujn tri nombrojn por akiri la krudan formon." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2d-a bruo, kiu regas la formon/grandon de krestaj montoj." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2d-a bruo, kiu regas la formon/grandecon de mildaj montetoj." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2d-a bruo, kiu regas la formon/grandon de terasaj montoj." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "2d-a bruo, kiu regas la grandon/ofton de krestaj montaroj." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2d-a bruo, kiu regas la grandecon/oftecon de mildaj montetoj." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "2d-a bruo, kiu regas la grandon/ofton de terasaj montaroj." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2d-a bruo, kiu lokas la riverajn valojn kaj kanalojn." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D nuboj" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3d-a reĝimo" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Forteco de 3D-reĝima paralakso" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3d-a bruo difinanta grandegajn kavernojn." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3d-a bruo difinanta montan strukturon kaj altecon.\n" +"Ankaŭ difinas strukturon de montoj sur fluginsuloj." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"3d-bruo difinanta la strukturon de fluginsuloj.\n" +"Ŝanĝite de la implicita valoro, la bruo «scale» (implicite 0.7) eble\n" +"bezonos alĝustigon, ĉar maldikigaj funkcioj de fluginsuloj funkcias\n" +"plej bone kiam la bruo havas valoron inter -2.0 kaj 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "3d-a bruo difinanta strukturon de riveraj kanjonaj muroj." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3d-a bruo difinanta terenon." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"3d-a bruo por montaj superelstaraĵoj, rokmuroj, ktp. Plej ofte la etaj " +"variaĵoj." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D-bruo, kiu determinas la nombron de forgeskeloj en mondoparto." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Subteno de 3d-a vido.\n" +"Nun subtenataj:\n" +"– none: nenia 3d-a eligo.\n" +"– anaglyph: bluverde/pulpure kolora 3d-o.\n" +"– interlaced: polarigo de paraj/neparaj linioj.\n" +"– topbottom: dividi ekranon horizontale.\n" +"– sidebyside: dividi ekranon vertikale.\n" +"– crossview: krucokula 3d-o.\n" +"– pageflip: kvarbufra 3d-o.\n" +"Rimarku, ke la reĝimo «interlaced» postulas ŝaltitajn ombrigilojn." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Elektita mapfonto por nova mapo; lasu malplena por hazarda mapfonto.\n" +"Kreante novan mondon per ĉefmenuo oni transpasos ĉi tion." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Mesaĝo montrota al ĉiuj klientoj post servila fiasko." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Mesaĝo montrota al ĉiuj klientoj post servila malŝaltiĝo." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Intertempo de ABM (aktiva modifilo de monderoj)" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Tempobuĝeto de ABM (aktiva modifilo de monderoj)" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Absoluta maksimumo de atendantaj estigotaj monderoj" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Akcelo en aero" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Akcelo de pezforto, en monderoj sekunde sekunde." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Aktivaj modifiloj de monderoj (ABM)" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Intertempo de aktiva mastrumilo de monderoj" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Aktiva amplekso de monderoj" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Aktiva senda amplekso de objektoj" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Adreso alkonektota.\n" +"Lasu ĝin malplena por komenci lokan servilon.\n" +"La adresa kampo en la ĉefmenuo transpasas ĉi tiun agordon." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Aldonas partiklojn ĉe fosado de mondero." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Ĝustigi punktojn cole al via ekrano (ekster X11/Android), ekzemple por " +"kvarmilaj ekranoj." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Alĝustigas densecon de la fluginsula tavolo.\n" +"Plialtigu la valoron por pliigi densecon. Eblas plusa aŭ minusa.\n" +"Valoro = 0.0: 50% de volumeno estas fluginsuloj.\n" +"Valoro = 2.0 (povas esti pli alta, depende de «mgv7_np_floatland»; ĉiam\n" +"kontrolu certige) kreas solidan tavolon de fluginsulaĵo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Almeti nomon de portaĵo" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Specialaj" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Modifas la luman kurbon per apliko de «gamaa korekto» al ĝi.\n" +"Pli altaj valoroj heligas mezajn kaj malaltajn lumnivelojn.\n" +"Valoro «1.0» lasas la luman kurbon neŝanĝita.\n" +"Ĉi tio nur grave efikas sur taglumo kaj artlumo; ĝi nur\n" +"tre malmulte efikas sur natura noktlumo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Ĉiam en fluga kaj rapida reĝimoj" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Gamao de media ombrigo" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Kiom da mesaĝoj ludanto rajtas sendi en dek sekundoj." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Plifortigas la valojn." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Neizotropa filtrado" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Enlistigi servilon" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Anonci al ĉi tiu servillisto." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Almeti nomon de portaĵo" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Almeti nomon de portaĵo al ŝpruchelplio." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Bruo de pomujoj" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Braka movofirmo" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Braka movofirmo donas pli verecan movadon\n" +"de la brako dum movo de la vidpunkto." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Demandi pri rekonekto fiaskinte" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"Je ĉi tiu distanco, la servilo fervore alĝustigos la nombron de monderoj\n" +"sendataj al klientoj.\n" +"Malgrandaj valoroj povas multe plibonigi efikecon, je la kosto de videblaj\n" +"bildigaj eraroj (iuj monderoj ne bildiĝos sub akvo kaj en kavernoj, kaj iam\n" +"eĉ ne surtere).\n" +"Valoro pli granda ol tiu de «max_block_send_distance» malŝaltas ĉi tiun\n" +"plibonigon.\n" +"Donita en mondopecoj (16 monderoj)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Memage antaŭen" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Memage salti unumonderajn barojn." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Memage raporti al la listo de serviloj." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Memori grandecon de ekrano" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Reĝimo de memaga skalado" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "Salta klavo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key for climbing/descending" +msgstr "Speciala klavo por supreniri/malsupreniri" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Malantaŭen" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Baza ternivelo" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Baza alteco de tereno." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Bazaj rajtoj" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Borda bruo" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Sojlo de borda bruo" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Dulineara filtrado" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Bindi adreson" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Parametroj de varmeco kaj sekeco por Klimata API" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Klimata bruo" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Optimuma distanco de monder-sendado" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Dosierindiko al egrasa kaj kursiva tiparo" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Dosierindiko al grasa kaj kursiva egallarĝa tiparo" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Dosierindiko al grasa tiparo" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Dosierindiko al grasa egallarĝa tiparo" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Konstruado en ludanto" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Primitivaĵo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Ŝanĝi vidpunkton" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Distanco de vidpunkto «proksime tonda ebeno» en monderoj, inter 0 kaj 0.25.\n" +"Funkcias nur sur GLES-platformoj. Plejparto de uzantoj ne bezonos ĉi tion " +"ŝanĝi.\n" +"Plialtigo povas malpliigi misbildojn por malfortaj grafiktraktiloj.\n" +"0.1 = Norma, 0.25 = Bona valoro por malfortaj tabulkomputiloj." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Glatigo de vidpunkto" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Glatigo de vidpunkto por glita vidpunkto" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Baskula klavo de ĝisdatigo de vidpunkto" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Kaverna bruo" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Kaverna bruo #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Kaverna bruo #1" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Kaverna larĝo" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Kaverna bruo 1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Kaverna bruo 2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Kaverna limo" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Bruo de kavernoj" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Maldikiĝo de kavernoj" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Sojlo de kavernoj" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Supra limo de kavernoj" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Centro de amplekso de pliigo de la luma kurbo.\n" +"Kie 0.0 estas minimuma lumnivelo, 1.0 estas maksimuma numnivelo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "Sojlo de babilaj mesaĝoj antaŭ forpelo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Babilaj komandoj" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Grandeco de babiluja tiparo" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Babila klavo" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Babileja protokola nivelo" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Supra limo de babilaj mesaĝoj" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Formato de babilaj mesaĝoj" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Sojlo de babilaj mesaĝoj antaŭ forpelo" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Plejlongo de babilaj mesaĝoj" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Babila baskula klavo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Babilo montrita" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Grando de peco" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Glita vidpunkto" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Klavo de glita vidpunkto" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Puraj travideblaj teksturoj" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Kliento" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Kliento kaj servilo" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Klienta modifado" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Limigoj de klient-flanka modifado" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Limigoj de amplekso por klientflanka serĉado de monderoj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Klienta modifado" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Suprenira rapido" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Nuba duondiametro" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Nuboj" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Nuboj kreiĝas klient-flanke." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Nuboj en ĉefmenuo" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Kolora nebulo" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Koloraj ombroj" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Diskomita listo de etikedoj, kies havantojn kaŝi en la datena deponejo.\n" +"«nonfree» povas identigi kaj kaŝi pakaĵojn, kiuj ne estas liberaj laŭ la " +"difino\n" +"de «Free Software Foundation» (Fondaĵo por libera programaro).\n" +"Vi ankaŭ povas specifi aĝtaksojn de l’ enhavo.\n" +"Ĉi tiuj etikedoj ne dependas de versioj de Minetest, do vi ĉiam povas " +"rigardi\n" +"la plenan liston je https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Diskomita listo de modifaĵoj, kiuj rajtas aliri la API-on de HTTP, kiu\n" +"ebligas alŝutadon kaj elŝutadon de datenoj al/el la interreto." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Diskomita listo de fidataj modifaĵoj, kiuj rajtas aliri nesekurajn " +"funkciojn\n" +"eĉ kiam modifaĵa sekureco estas ŝaltita (per " +"«request_insecure_environment()»)." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Komanda klavo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Nivelo de desigo per ZLib uzota por densigi mondopecojn dum konservado sur " +"disko.\n" +"-1 - la implicita nivelo de densigo per Zlib\n" +"0 - neniu densigo, plej rapida\n" +"9 - plej bona densigo, plej malrapida\n" +"(niveloj 1-3 uzas la \"rapidan\" metodon de Zlib; 4-9 uzas la ordinaran " +"metodon)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Nivelo de desigo per ZLib uzota por densigi mondopecojn dum sendado al " +"kliento.\n" +"-1 - la implicita nivelo de densigo per Zlib\n" +"0 - neniu densigo, plej rapida\n" +"9 - plej bona densigo, plej malrapida\n" +"(niveloj 1-3 uzas la \"rapidan\" metodon de Zlib; 4-9 uzas la ordinaran " +"metodon)" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Kunfandi vitron" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Konekti al fora vidaŭdaĵa servilo" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Kunfandas vitron, se la monderoj tion subtenas." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Travidebleco de konzolo" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Koloro de konzolo" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Alteco de konzolo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Enreta deponejo de enhavo" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Malpermesitaj flagoj de ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Maksimuma nombro de samtempaj elŝutoj de ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "URL de la datena deponejo" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Senĉese antaŭen" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Senĉesa antaŭena movado, baskuligata de la memirada klavo.\n" +"Premu la memiran klavon ree, aŭ reeniru por ĝin malŝalti." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Stirado" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Regas daŭron de tagnokta periodo.\n" +"Ekzemploj:\n" +"72 = 20 minutoj, 360 = 4 minutoj, 1 = 24 horoj, 0 = restadas senŝanĝe." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Regas krutecon/profundecon de lagaj profundaĵoj." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Regas krutecon/altecon de montetoj." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Regas larĝon de tuneloj, pli malalta valoro kreas pli larĝajn tunelojn.\n" +"Valoro ≥ 10.0 tute malŝaltas estigon de tuneloj kaj evitas la intensan\n" +"kalkulojn de bruo." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Fiaska mesaĝo" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Krea" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Travidebleco de celilo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Travidebleco de celilo (maltravidebleco, inter 0 kaj 255).\n" +"Ankaŭ determinas la koloron de la celilo de objekto" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Koloro de celilo" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Koloro de celilo (Ruĝo, Verdo, Bluo).\n" +"Ankaŭ determinas la koloron de la celilo de objekto" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "Punktoj cole" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Difekto" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Baskula klavo de erarserĉaj informoj" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Sojlo de grandeco de protokola dosiero" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Erarserĉa protokola nivelo" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Mallaŭtiga klavo" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Dediĉita servila paŝo" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Implicita akcelo" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Norma ludo" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Implicita ludo kreante novajn mondojn.\n" +"Ĝi estos transpasita kreante mondon de la ĉefmenuo." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Implicita pasvorto" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Implicitaj rajtoj" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Implicita raporta formo" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Implicita grandeco de la kolumno" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Difinas zonojn kie arboj donas pomojn." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Difinas zonojn kun sablaj bordoj." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Difinas distribuon de pli alta tereno kaj krutecon de rokmuroj." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Difinas distribuon de alta tereno." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Difinas tutan grandecon de kavernoj; pli malgrandaj valoroj kreas pli " +"grandajn kavernojn." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Difinas vastan sturkturon de akvovojo." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Difinas lokon kaj terenon de malnepraj montetoj kaj lagoj." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Difinas la bazan ternivelon." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Difinas la profundecon de la rivera akvovojo." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Difinas maksimuman distancon por transsendo de ludantoj, en monderoj (0 = " +"senlima)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Difinas larĝecon de la rivera akvovojo." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Difinas larĝecon de la rivera valo." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Difinas arbajn zonojn kaj densecon." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Prokrasto antaŭ ĝisdatigo de maŝoj kliente (en milisekundoj).\n" +"Pli grandaj valoroj malrapidigas oftecon de ŝanĝoj, malhelpante postreston\n" +"je malrapidaj klientoj." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Prokrasti sendon de metitaj monderoj" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Prokrasto antaŭ montro de ŝpruchelpiloj, sekunde." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Traktado de evitinda Lua API" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Profundo sub kiu troveblos grandegaj kavernoj." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Profundo sub kiu troveblos grandaj kavernoj." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Priskribo de servilo, montrota al ludantoj aliĝintaj kaj en la listo de " +"serviloj." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Sojlo de dezerta bruo" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Dezertoj estiĝas kiam «np_biome» superas ĉi tiun valoron.\n" +"Kiam la nova klimata sistemo aktivas, ĉi tio estas malatentata." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Malsamtempigi bildmovon de monderoj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Ornamoj" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Klavo por fosi" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Fosaj partikloj" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Malŝalti senartifikigon" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Malpermesi malplenajn pasvortojn" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Domajna nomo de servilo montrota en la listo de serviloj." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Duoble premu salto-klavon por flugi" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Duobla premo de salto-klavo baskulas flugan reĝimon." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Demeta klavo" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Ŝuti la erarserĉajn informojn de «mapgen»." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Maksimuma Y de forgeskelo" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Minimuma Y de forgeskeloj" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Bruo de forgeskeloj" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Ŝalti subtenon de IPv6 (por kaj kliento kaj servilo).\n" +"Bezonata por ia funkciado de IPv6-konektoj." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Ŝalti klient-flankajn Lua-modifojn.\n" +"Tiu ĉi funkcio estas prova kaj la API eble ŝanĝontas." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Ŝalti konzolan fenestron" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Ŝalti krean reĝimon por ĉiuj ludantoj" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Ŝalti stirstangojn" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Ŝalti subtenon de modifaĵaj kanaloj." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Ŝalti modifaĵan sekurecon" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Ŝalti difektadon kaj mortadon de ludantoj." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Ŝalti hazardan uzulan enigon (nur por testado)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Ŝalti glatan lumadon kun simpla media ombrado.\n" +"Malŝaltu por rapido aŭ alia aspekto." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Ŝalti por malpermesi konekton de malnovaj klientoj.\n" +"Malnovaj klientoj estas akordaj tiel, ke ili ne fiaskas konektante al novaj " +"serviloj,\n" +"sed eble ili ne subtenos ĉiujn atendatajn funkciojn." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Ŝalti uzon de fora vidaŭdaĵa servilo (se ĝi donitas de la servilo).\n" +"Foraj serviloj prezentas ege pli rapidon manieron elŝuti vidaŭdaĵojn\n" +"(ekzemple teksturojn) konektante al la servilo." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Ŝalti verticajn bufrajn objektojn.\n" +"Ĉi tio devus multe plibonigi efikecon de grafiko." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Ŝalti balanciĝon kaj ĝian fortecon.\n" +"Ekzemple: 0 por nenioma balanciĝo, 1.0 por normala, 2.0 por duobla." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Ŝalti/malŝalti ruladon de IPv6-a servilo.\n" +"Ignorita, se «bind_address» estas agordita.\n" +"Bezonas «enable_ipv6» ŝaltitan." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Ŝaltas filmecan mapadon de tono «Uncharted 2», fare de Hable.\n" +"Simulas la tonan kurbon de fotofilmo, kaj ĝian proksimigon al aspekto\n" +"de bildoj kun alta dinamika amplekso. Mezampleksa kontrasto estas\n" +"iomete alĝustigita, ombroj kaj malombroj estas glate densigitaj." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Ŝaltas movbildojn en portaĵujo." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Ŝaltas kaŝmemoradon de maŝoj turnitaj per «facedir»." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Ŝaltas mapeton." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Ŝaltas la sonsistemon.\n" +"Malŝaltite, ĉi tio tute malŝaltas ĉiujn sonojn kaj la enludoj sonregiloj\n" +"ne funkcios.\n" +"Ŝanĝo de ĉi tiu agordo postulos restartigon." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Profilo de valoj" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Intervalo inter presoj de profilaj datenoj de la motoro" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Metodoj de estoj" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Eksponento de maldikigo de fluginsuloj. Ŝanĝas la konduton\n" +"de maldikigo.\n" +"Valoro = 1.0 kreas unuforman, linearan maldikigon.\n" +"Valoroj > 1.0 kreas glatan maldikigon taŭgan por la implicitaj apartaj\n" +"fluginsuloj.\n" +"Valoroj < 1.0 (ekzemple 0.25) kreas pli difinitan ternivelon kun\n" +"pli plataj malaltejoj, taŭgaj por solida tavolo de fluginsulaĵo." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "Maksimuma nombro de kadroj en sekundo dum paŭzo aŭ sen fokuso" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA(glatigo/anti-aliasing)" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Koeficienta bruo" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Koeficiento de balancado dum falo" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Dosierindiko al reenpaŝa tiparo" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Rapida klavo" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Akcelo en rapida reĝimo" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Rapido en rapida reĝimo" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Rapida moviĝo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Rapida moviĝo (per la klavo «speciala»).\n" +"Ĉi tio postulas la rajton «rapidegi» en la servilo." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Vidamplekso" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Vidokampo grade." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Dosiero en client/serverlist/ kiu enhavas viajn ŝatatajn servilojn " +"montritajn en la\n" +"langeto «Ludo por pluraj»." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Profundeco de plenigaĵo" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Bruo de profundeco de plenigaĵo" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Filmeca mapado de tono" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Filtritaj teksturoj povas intermiksi RVB valorojn kun plene travideblaj\n" +"apud-bilderoj, kiujn PNG bonigiloj kutime forigas, farante helan aŭ\n" +"malhelan limon al la travideblaj teksturoj. Ŝaltu ĉi tiun filtrilon por " +"ĝustigi\n" +"tion dum legado de teksturoj." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Glatigo:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Unua el la 4 2d-aj bruoj, kiuj kune difinas la alton de mont(et)aj krestoj." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Unua el la du 3d-aj bruoj, kiuj kune difinas tunelojn." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Fiksa mapa greno" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Fiksita virtuala stirstango" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Denseco de fluginsuloj" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Maksimuma Y de fluginsuloj" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Minimuma Y de fluginsuloj" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Bruo de fluginsuloj" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Eksponento de maldikigo de fluginsuloj" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Distanco de maldikigo de fluginsuloj" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Akvonivelo de fluginsuloj" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Fluga klavo" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Flugado" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Nebulo" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Komenco de nebulo" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Nebula baskula klavo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Tipara grandeco" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Implice grasa tiparo" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Implice kursiva tiparo" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Tipara ombro" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Travidebleco de tipara ombro" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Tipara grandeco" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Grando de la implicita tiparo, punkte (pt)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Grandeco de la egallarĝa tiparo, punkte (pt)." + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Grandeco de tiparo de freŝa babila teksto kaj babilujo en punktoj (pt).\n" +"Valoro 0 uzos la implicitan grandecon de tiparo." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Formato de babilaj mesaĝoj de ludantoj. La jenaj tekstĉenoj estas validaj\n" +"lokokupiloj: @name, @message, @timestamp (malnepra)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Dosierformo de ekrankopioj." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Implicata fonkoloro de fenestroj" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Implicata fona netravidebleco de fenestroj" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Fonkoloro de tutekranaj fenestroj" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Fona netravidebleco de tutekrana fenestro" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Implicata fonkoloro de fenestroj (R,V,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Implicata netravidebleco de fenestroj (inter 0 kaj 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Fonkoloro de tutekranaj fenestroj (R,V,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "Fona netravidebleco de tutekranaj fenestroj (inter 0 kaj 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Antaŭen" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Kvara el la 4 2d-aj bruoj, kiuj kune difinas altecon de mont(et)aj krestoj." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Speco de fraktalo" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Ono de la videbla distanco, ekde kiu nebulo bildiĝas" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"De kia distanco monderoj aperas por klientoj, mondopece (po 16 monderoj)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"De kia distanco monderoj sendiĝas al klinentoj, mondopece (po 16 monderoj)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"De kia distanco klientoj ekkonas objektojn, en mondopecoj (16 monderoj).\n" +"\n" +"Agordo pli alta ol « active_block_range » ankaŭ kaŭzos, ke la servilo tenos\n" +"aktivajn objektojn ĝis ĉi tiu distanco, en la direkto, kien la ludulo " +"rigardas.\n" +"(Tio malhelpas subitan malaperon de estuloj el la vido.)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Tutekrane" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Tutekrana reĝimo." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Skalo de grafika fasado" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Skala filtrilo de grafika interfaco" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Skala filtrilo de grafika interfaco txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Ludoj" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Mallokaj revokoj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Ĉieaj atributoj de mondestigo.\n" +"En mondestigo v6, la parametro «decorations» regas ĉiujn ornamojn\n" +"krom arboj kaj ĝangala herbo; en ĉiuj ailaj mondestigiloj, ĉi tiu parametro\n" +"regas ĉiujn ornamojn." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Transiro de luma kurbo je plejalta lumnivelo.\n" +"Regas la kontraston de la plej altaj lumniveloj." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Transiro de luma kurbo je minimuma lumnivelo.\n" +"Regas kontraston je la malplej altaj lumniveloj." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafiko" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafiko" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafiko" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Pezforto" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Ternivelo" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Tera bruo" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP-modifaĵoj" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Skalo de grafika fasado" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Baskula klavo por travida fasado" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Traktado de evitindaj Lua-API-vokoj:\n" +"- none: ne prokoli evitindajn vokojn\n" +"- log: imiti kaj protokoli respuron de evitindaj vokoj (implicita).\n" +"- error: ĉesigi je evitinda voko (proponata al evoluigistoj de modifaĵoj)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Ekzamenigi la profililon per ĝi mem:\n" +"* Ekzameni malplenan funkcion.\n" +"Tio prikalkulos la ekstron aldonatan de ekzamenado (+1 voko de funkcio).\n" +"* Ekzameni la specimenilon uzatan por ĝisdatigo de la statistiko." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Bruo de kunfando de varmeco" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Varmeca bruo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "Alteco de la fenestro je ĝia komenca grando." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Alteca bruo" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Bruo de elekto de alto" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Kruteco de montetoj" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Sojlo de montetoj" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Bruo de monteteco 1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Bruo de monteteco 2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Bruo de monteteco 3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Bruo de monteteco 4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Hejmpaĝo de la servilo, montrota en la listo de serviloj." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Horizontala akcelo en aero dum saltado aŭ falado, \n" +"en monderoj sekunde sekunde." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Horizontala kaj vertikala akcelo en rapida reĝimo,\n" +"en monderoj sekunde sekunde." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Horizontala kaj vertikala akcelo sur tero aŭ dum grimpado,\n" +"en monderoj sekunde sekunde." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Sekva portaĵo en fulmobreto" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Antaŭa portaĵo en fulmobreto" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Klavo de fulmobreta portaĵingo 1" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Klavo de fulmobreta portaĵingo 10" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Klavo de fulmobreta portaĵingo 11" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Klavo de fulmobreta portaĵingo 12" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Klavo de fulmobreta portaĵingo 13" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Klavo de fulmobreta portaĵingo 14" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Klavo de fulmobreta portaĵingo 15" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Klavo de fulmobreta portaĵingo 16" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Klavo de fulmobreta portaĵingo 17" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Klavo de fulmobreta portaĵingo 18" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Klavo de fulmobreta portaĵingo 19" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Klavo de fulmobreta portaĵingo 2" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Klavo de fulmobreta portaĵingo 20" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Klavo de fulmobreta portaĵingo 21" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Klavo de fulmobreta portaĵingo 22" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Klavo de fulmobreta portaĵingo 23" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Klavo de fulmobreta portaĵingo 24" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Klavo de fulmobreta portaĵingo 25" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Klavo de fulmobreta portaĵingo 26" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Klavo de fulmobreta portaĵingo 27" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Klavo de fulmobreta portaĵingo 28" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Klavo de fulmobreta portaĵingo 29" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Klavo de fulmobreta portaĵingo 3" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Klavo de fulmobreta portaĵingo 30" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Klavo de fulmobreta portaĵingo 31" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Klavo de fulmobreta portaĵingo 32" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Klavo de fulmobreta portaĵingo 4" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Klavo de fulmobreta portaĵingo 5" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Klavo de fulmobreta portaĵingo 6" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Klavo de fulmobreta portaĵingo 7" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Klavo de fulmobreta portaĵingo 8" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Klavo de fulmobreta portaĵingo 9" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Kiel profundaj fari riverojn." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Kiel rapide ondoj de fluaĵoj moviĝos. Pli alta = pli rapide.\n" +"Je minusa valoro, ondoj de fluaĵoj moviĝos reen.\n" +"Bezonas ŝaltitajn ondantajn fluaĵojn." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Kioman tempon la servilo atendos antaŭ delasi neuzatajn mondopecojn.\n" +"Pli alta valoro estas pli glata, sed uzos pli da tujmemoro." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Malpliigu ĉi tion por pliigi reziston de fluaĵoj al movo." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Kiel larĝajn fari riverojn." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Bruo de intermiksado de malsekeco" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Bruo de malsekeco" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Variado de malsekeco por klimatoj." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "Servilo kun IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Se la nombro de kadroj superas ĉi tion, limigu ilin per dormo,\n" +"por ne malŝpari vane potencon de procesoro." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Malŝaltite, postulas uzon de la «speciala» klavo se ambaŭ la fluga kaj\n" +"la rapida reĝimoj estas ŝaltitaj." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Je ŝalto, servilo elektos postkaŝitajn mondopecojn laŭ loko de okuloj\n" +"de la ludanto. Tio povas malpliigi la nombron de mondopecoj sendotaj\n" +"al la kliento je 50–80%. La kliento ne plu ricevos nevideblajn, tiel ke la\n" +"utileco de trapasa reĝimo malpliiĝos." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Kune kun la fluga reĝimo, ebligas trapasadon de firmaĵo.\n" +"Por tio necesas la rajto «noclip» servile." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Ŝaltite, klavo «uzi» estas uzata anstataŭ klavo «kaŝiri» por malsupreniro." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Ŝalti konfirmon de registriĝo dum konekto al servilo.\n" +"Se ĝi estas malŝaltita, nova konto registriĝos memage." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Registras agojn por eblaj malfaroj.\n" +"Ĉi tiu agordo nur legatas je la komenco de la servilo." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Ŝaltite malŝaltas sentrompigon en ludo por pluraj." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Protektas la servilon kontraŭ nevalidaj datenoj.\n" +"Ŝaltu nur se vi bone scias, kion vi faras." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Ŝaltite akordigas direkton de movoj de la ludanto al la direkto de ĝia " +"rigardo dum flugado aŭ naĝado." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "Malebligas konekton kun malplena pasvorto." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Ebligas metadon de monderoj en lokojn (kruroj + supraĵo), kie vi staras.\n" +"Tio utilas, se vi prilaboras monderojn kun malmulte da spaco." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Se la limigo de klient-flankaj modifaĵoj por mondera distanco ŝaltiĝas, " +"vokoj\n" +"al get_node limiĝas al ĉi tiu distanco inter la ludanto kaj la mondero." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Se la dosiergrando de «debug.txt» superas la nombron de milionbitokoj\n" +"agorditan ĉi tie, kiam ĝi malfermiĝas, la dosiero moviĝas al «debug.txt.1»,\n" +"kaj pli malnova «debug.txt.1» foriĝas, se ĝi ekzistas.\n" +"«debug.txt» moviĝas nur se ĉi tiu agordo estas ŝaltita." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "Ŝaltite, ludantoj ĉiam renaskiĝos je la donita loko." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Malatenti mondajn erarojn" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Travidebleco de enluda babila konzolo (maltravidebleco, inter 0 kaj 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Fonkoloro de la enluda babila konzolo (R,V,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "(Alteco de la enluda babila konzolo, inter 0.1 (10%) kaj 1.0 (100%)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Plilaŭtiga klavo" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Unuaeca vertikala rapido dum salto, en monderoj sekunde." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Ekzameni primitivojn.\n" +"Ĉi tion normale bezonas nur evoluigistoj de kerno/primitivoj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Instrument chat commands on registration." +msgstr "Ekzameni babilajn komandojn je registriĝo." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Ekzameni mallokajn revokajn funkciojn je registriĝo.\n" +"(ĉio, kion vi donas al la funkcio minetest.register_*())" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Ekzameni la agan funkcion de Aktivaj Modifiloj de Monderoj je registriĝo." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Ekzameni la agan funkcion de Ŝargaj Modifiloj de Monderoj je registriĝo." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Ekzameni la metodojn de estoj je registriĝo." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "Periodo inter konservo de gravaj ŝanĝoj en la mondo, sekunde." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Periodo inter sendoj de tagtempo al klientoj." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Bildmovado de portaĵoj en portaĵujo" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Klavo de portaĵujo" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Renversi muson" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Renversi vertikalan movon de muso." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Dosierindiko al kursiva tiparo" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Dosierindiko al kursiva egallarĝa tiparo" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Daŭro de lasita portaĵo" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Ripetoj" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Ripetoj de la sinvoka funkcio.\n" +"Ĉi tio pliiĝinte pliigas etajn detalojn, sed ankaŭ pliigas\n" +"la ŝarĝon al la datentraktilo.\n" +"Je 20 ripetoj, ĉi tiu mondestigilo havas ŝarĝon similan al\n" +"la mondestigilo V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "Identigilo de stirstango" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Ripeta periodo de stirstangaj klavoj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick dead zone" +msgstr "Nerespondema zono de stirstango" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Sentemo de stirstanga vidamplekso" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Speco de stirstango" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Nur por aro de Julia.\n" +"W-ero de supermalsimpla konstanto.\n" +"Ŝanĝas la formon de la fraktalo.\n" +"Neniel efikas sur 3D-fraktaloj.\n" +"Amplekso proksimume de -2 ĝis 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Nur por aro de Julia.\n" +"X-ero de supermalsimpla konstanto.\n" +"Ŝanĝas la formon de la fraktalo.\n" +"Amplekso proksimume de -2 ĝis 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Nur por aro de Julia.\n" +"Y-ero de supermalsimpla konstanto.\n" +"Ŝanĝas la formon de la fraktalo.\n" +"Amplekso proksimume de -2 ĝis 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Nur aro de Julia.\n" +"Z-a ero de supermalsimpla konstanto.\n" +"Ŝanĝas la formon de la fraktalo.\n" +"Amplekso proksimume de -2 ĝis 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Salta klavo" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Salta rapido" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por malkreskigi la vidan distancon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por malkreskigi la laŭtecon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por fosi.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por demeti la elektitan portaĵon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por kreskigi la vidan distancon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por kreskigi la laŭtecon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por salti.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por moviĝi rapide en rapida reĝimo.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por movi la ludanton reen.\n" +"Aktivigo ankaŭ malŝaltos memiradon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por movi la ludanton pluen.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por movi la ludanton maldekstren.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por movi la ludantan dekstren.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por silentigi la ludon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por malfermi la babilan fenestron por entajpi komandojn.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por malfermi la babilan fenestron por entajpi lokajn komandojn.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por malfermi la babilan fenestron.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por malfermi la portaĵujon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por meti.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 11-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 12-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 13-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 14-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 15-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 16-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 17-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 18-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 19-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 20-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 21-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 22-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 23-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 24-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 25-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 26-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 27-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 28-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 29-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 30-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 31-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti 32-an portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti okan portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti kvinan portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti unuan portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti kvaran portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti sekvan portaĵon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti naŭan portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti antaŭan portaĵon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti duan portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti sepan portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti sesan portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti dekan portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por elekti trian portaĵingon en la fulmobreto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por kaŝirado.\n" +"Ankaŭ uzata por malsupreniro kaj malsuprennaĝo se ‹aux1_descends› estas " +"malŝaltita.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por unua kaj tria vidpunktoj.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por ekrankopiado.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por memirado.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por glita vidpunkto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por mapeto.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por rapida reĝimo.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por flugado.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por trapasa reĝimo.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por celilsekva reĝimo.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por vidpunkta ĝisdatigo. Nur uzata por evoluigado.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por montri babilon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por montri erarserĉajn informojn.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por montri nebulon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por montri la travidan fasadon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por montri grandan babilan konzolon.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por montri la profililon. Uzu programante.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Baskula klavo por senlima vido.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klavo por zomi vidon kiam tio eblas.\n" +"Vidu http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "Forpeli ludantojn, kiuj sendis pli ol X mesaĝojn en 10 sekundoj." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Laga kruteco" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Laga sojlo" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Lingvo" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Profundeco de granda kaverno" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Maksimuma nombro de grandaj kavernoj" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Minimuma nombro de grandaj kavernoj" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Subakva parto de granda kaverno" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Klavo de granda konzolo" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Stilo de folioj" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Stiloj de folioj:\n" +"– Fajna: Ĉiuj facoj videblas\n" +"– Simpla: nur eksteraj facoj, se difinitaj special_tiles uzatas\n" +"– Maltravidebla: malŝalti travideblecon" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Maldekstra klavo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Longeco de servila agociklo, kaj la intervalo dum kiu objektoj ĝenerale " +"ĝisdatiĝas\n" +"trans la reto." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Longo de fluaĵaj ondoj.\n" +"Bezonas ondantajn fluaĵojn." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Tempodaŭro inter rulaj cikloj de Aktiva Modifilo de Monderoj (AMM)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Tempodaŭro inter rulaj cikloj de NodeTimer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Daŭro inter cikloj de aktiva administrado de monderoj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Nivelo de protokolado skribota al debug.txt:\n" +"- <nenio> (nenio protokoliĝas)\n" +"- none (neniu – mesaĝoj sen nivelo)\n" +"- error (eraro)\n" +"- warning (averto)\n" +"- action (ago)\n" +"- info (informo)\n" +"- verbose (babilema)" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Pliigo de luma kurbo" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Centro de pliigo de luma kurbo" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Disvastiĝo de pliigo de luma kurbo" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Gamao de luma kurbo" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Alta transiro de luma kurbo" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Malalta transiro de luma kurbo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Glata lumado" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Limo de mapa estigo, mondere, en ĉiuj ses direktoj de (0, 0, 0).\n" +"Nur mondopartoj plene en la mondestigila limo estiĝos.\n" +"Valoro konserviĝas aparte por ĉiu mondo." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Limigas nombron da samtempaj HTTP-petoj. Afliktas:\n" +"– Elŝuton de vidaŭdaĵoj, se la servilo uzas la agordon «remote_media».\n" +"– Elŝuton de listo de serviloj, kaj servila anonco.\n" +"– Elŝutojn fare de la ĉefmenuo (ekz. modifaĵa administrilo).\n" +"Efektivas nur se la ludo tradukiĝis kun cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Flueco de fluaĵoj" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Glatigo de fluida flueco" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Maksimumo de fluaĵa ciklo" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Tempo antaŭ vakigo de fluaĵa atendovico" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Profundiĝo en fluaĵoj" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Intervalo inter ĝisdatigoj de fluaĵoj (en sekundoj)." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Longeco de fluaĵa agociklo" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Enlegi la ludan profililon" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Enlegas la ludan profililon por kolekti datenojn de luda profilado.\n" +"Disponigas la komandon «/profiler» por atingi la kodotradukitan profilon.\n" +"Utila por evoluigistoj de modifaĵoj kaj administrantoj de serviloj." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Ŝargaj Modifiloj de Monderoj" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Suba Y-limo de forgeskeloj." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Suba Y-limo de fluginsuloj." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Ĉefmenua skripto" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Dependigi kolorojn de nebulo kaj ĉielo de tagtempo (sunleviĝo/sunsubiro)\n" +"kaj direkto de rigardo." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Igas fluaĵojn netravideblaj" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Nivelo de densigo de mondopecoj por konservado sur disko" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Nivelo de densigo de mondopecoj por sendado tra reto" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Dosierujo kun mapoj" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Mondestigaj ecoj speciale por la Karpata Mondestigilo." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Mondestigaj ecoj speciale por la Plata Mondestigilo.\n" +"Kelklokaj lagoj kaj montetoj povas aldoniĝi al la plata mondo." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Mondestigaj ecoj speciale por la Plata Mondestigilo.\n" +"«terrain» ŝaltas estigon de nefraktala tereno:\n" +"oceano, insuloj, kaj subtero." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Apartaj mapestigaj ecoj de la mapestigilo «Valleys».\n" +"«altitude_chill»: Malpliigas varmon laŭ alto.\n" +"«humid_rivers»: Pliigas malsekecon ĉirkaŭ riveroj.\n" +"«vary_river_depth»: Ŝaltite foje sekigas riverojn pro malalta malsekeco\n" +"kaj alta varmo.\n" +"«altitude_dry»: Malpliigas malsekecon laŭ alto." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Mapestigaj ecoj speciale por Mapestigilo v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Mondestigaj ecoj apartaj al Mondestigilo v6.\n" +"La flago «snowbiomes» ŝaltas la novan 5-klimatan sistemon.\n" +"Kiam la flago «snowbiomes» estas ŝaltita, ĝangaloj estas memage ŝaltitaj\n" +"kaj la flago «jungles» estas malatentata." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Mapestigaj ecoj speciale por Mapestigilo v7.\n" +"«ridges»: Riveroj.\n" +"«floatlands»: Flugantaj teramasoj en la atmosfero.\n" +"«caverns»: Grandaj kavernegoj profunde sub tero." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Limo de mondestigo" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Intervaloj inter konservoj de mondo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map shadows update frames" +msgstr "Longeco de fluaĵa agociklo" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Mondopeca limo" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Prokrasto de estigo de maŝoj de mondopecoj" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Grando (en megabitokoj) de la kaŝmemoro de la estiganto de mondopecoj" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Tempolimo de mallego de mondopecoj" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Mondestigilo karpata" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Parametroj specialaj por Karpata Mondestigilo" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Mondestigilo plata" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Parametroj specialaj por Plata Mondestigilo" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Mondestigilo fraktala" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Parametroj speciale por Fraktala Mondestigilo" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Mondestigilo v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Parametroj specialaj por Mondestigilo v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Mondestigilo v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Parametroj specialaj por Mondestigilo v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Mondestigilo v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Parametroj specialaj por Mondestigilo v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Mondestigilo vala" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Parametroj specialaj por Vala Mondestigilo" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Mapestigila erarserĉilo" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Nomo de mondestigilo" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Estiga distanco de mondopecoj" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Senda distanco de mondopecoj" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Plejmulto da fluaĵoj traktataj en unu paŝo." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Maksimumo da ekstraj mondopecoj por «clearobjects»" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Maksimumaj paketoj iteracie" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Maksimuma nombro de kadroj en sekundo" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"Maksimuma nombro de kadroj en sekundo, kiam la fokuso mankas al la fenestro, " +"aŭ dum paŭzo de la ludo." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Maksimumo de perforte enlegitaj mondopecoj" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Maksimuma larĝo de la fulmobreto" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" +"Maksimuma limo de hazarda nombro de grandaj kavernoj en unu mondoparto." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" +"Maksimuma limo de hazarda nombro de malgrandaj kavernoj en unu mondoparto." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Maksimuma rezisto de fluaĵoj. Regas malakcelon dum eniĝo en fluaĵon\n" +"je granda rapido." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Maksimuma nombro de mondopecoj samtempe sendataj al unu kliento.\n" +"La maksimuma sumo estas kalkulata flue:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "Maksimuma nombro da mondopecoj atendantaj legon." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Maksimumo nombro de mondopecoj atendantaj estigon.\n" +"Ĉi tiu limo estas devigata al ĉiu ludanto aparte." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Maksimuma nombro de atendantaj mondopecoj legotaj de loka dosiero.\n" +"Ĉi tiu limo estas devigata al ĉiu ludanto aparte." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Maksimuma nombro de samtempaj elŝutoj. Elŝutoj superantaj ĉi tiun limon " +"estos atendataj.\n" +"Tiu nombro devas esti malpli granda ol curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Maksimuma nombro de perforte enlegitaj mondopecoj." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Maksimuma nombro da mondopecoj por la kliento en memoro.\n" +"Agordu -1 por senlima kvanto." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Maksimuma nombro da paketoj sendotaj per sendopaŝo. Se via ret-konekto\n" +"malrapidas, provu ĝin malkreskigi, sed neniam malpli ol duoblo de la " +"versio,\n" +"kiun havas la celata kliento." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Maksimuma nombro de ludantoj, kiuj povas konektiĝi samtempe." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Maksimuma nombro da freŝaj babilaj mesaĝoj montrotaj" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Maksimuma nombro de statike memorataj objektoj en mondopeco." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Maksimuma nombro de objektoj en mondopeco" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Maksimuma parto de la nuna fenestro uzota por la fulmobreto.\n" +"Utilas se io montrotas dekstre aŭ maldekstre de la fulmobreto." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Maksimumaj samtempaj sendoj de mondopecoj po kliento" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Maksimumo da atendantaj elaj mesaĝoj" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Maksimuma grando de la elira babila atendovico.\n" +"0 malŝaltas envicigon, kaj -1 senlimigas ĝin." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Maksimuma tempo (en milisekundoj) por elŝuto de dosiero (ekz. modifaĵo)." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Maksimuma nombro da uzantoj" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Maŝa kaŝmemoro" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Tagmesaĝo" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Tagmesaĝo montrota al konektantaj ludantoj." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Metodo emfazi elektitan objekton." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Minimuma nivelo de protokolado skribota al la babilujo." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Mapeto" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Mapeta klavo" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Alteco de mapeta skanado" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Minimuma limo de hazarda nombro de grandaj kavernoj en mondoparto." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Minimuma limo de hazarda nombro de malgrandaj kavernoj unu mondoparto." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Minimuma grandeco de teksturoj" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Etmapigo" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Profililo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Sekureco" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Kanaloj por modifaĵoj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Modifies the size of the HUD elements." +msgstr "Ŝanĝas la grandecon de eroj de la travida fasado." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Dosierindiko al egallarĝa tiparo" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Grandeco de egalspaca tiparo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "Grandeco de egalspaca tiparo" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Bruo de monta alteco" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Bruo de montoj" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Bruo de monta variigo" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Nulnivelo de montoj" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Respondemo de muso" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Obligilo por respondeco de muso." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Bruo de koto" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Obligilo por fala balancado.\n" +"Ekzemple: 0 por neniu balancado; 1.0 por normala; 2.0 por duobla." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Silentiga klavo" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Silentigi sonon" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Nomo de mapestigilo uzota por krei novan mondon.\n" +"Kreo de nova mondo en la ĉefmenuo transpasos ĉi tiun agordon.\n" +"Nunaj tre malstabilaj mapestigiloj estas:\n" +"- La malnepraj fluginsuloj de v7 (implicite malŝaltitaj)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Nomo de la ludanto.\n" +"Gastigante per servilo, klientoj konektantaj kun ĉi tiu nomo estas " +"administrantoj.\n" +"Komencante de la ĉefmenuo, oni tranpasas ĉi tion." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "Nomo de la servilo, montrota al ludantoj kaj en la listo de serviloj." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Proksima ebeno" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Ricevigota pordo (UDP).\n" +"Komencante de la ĉefmenuo, ĉi tio estos transpasita." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Reto" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Novaj uzantoj devas enigi ĉi tiun pasvorton." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Trapasado" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Trapasa klavo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Emfazado de monderoj" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Emfazado de monderoj" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Intervalo de NodeTimer" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Bruoj" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Nombro da mondestigaj fadenoj" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Nombro de uzotaj fadenoj enlegontaj.\n" +"Valoro 0:\n" +"- Memaga elekto. La nombro de fadenoj enlegontaj estos\n" +"- 'nombro de datentraktiloj - 2', kun suba limo de 1.\n" +"Ĉiu alia valoro:\n" +"- Precizigas la nombron de fadenoj enlegontaj, kun suba limo de 1.\n" +"AVERTO: Pligrandigo de la nombro de fadenoj enlegontaj plirapidigas " +"mondestigon,\n" +"sed povas malrapidigi la ludon per ĝenado de aliaj programoj, precipe en " +"reĝimo\n" +"por unu ludanto, kaj/aŭ dum rulado de Lua-kodo en «on_generated». Por " +"multaj\n" +"uzantoj, la optimuma agordo eble estos «1»." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Nombro da aldonaj mondopecoj legontaj de «/clearobjects» je unu fojo.\n" +"Ĉi tio decidas preferon inter superŝarĝaj negocoj de «sqlite»\n" +"kaj uzon de memoro (4096=100MB, proksimume)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Netralumeblaj fluidoj" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" +"Netravidebleco (alfa) de la ombro post la implicita tiparo, inter 0 kaj 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Malfermas haltan menuon kiam fokuso je la fenestro perdiĝas. Ne haltigas se " +"enluda\n" +"fenestro estas malfermita." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Dosierindiko de la reenpaŝa tiparo.\n" +"Se la agordo «freetype» estas ŝaltita: devas esti tiparspeco «TrueType».\n" +"Se la agordo «freetype» estas malŝaltita: devas esti bitbilda aŭ XML-vektora " +"tiparo.\n" +"Ĉi tiu tiparo uziĝos por kelkaj lingvoj, aŭ se la norma tiparo ne " +"disponeblas." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Dosierindiko por konservotaj ekrankopioj. Povas esti absoluta\n" +"aŭ relativa. La dosierujo estos kreita, se ĝi ne jam ekzistas." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Dosierindiko al ombrigiloj. Se neniu estas difinita, la implicita estos " +"uzata." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "Dosierindiko al teksturoj. Ĉiuj teksturoj estas unue serĉataj tie." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Dosierindiko al la implicita tiparo.\n" +"Se la agordo «freetype» estas ŝaltita: devas esti tiparspeco «TrueType».\n" +"Se la agordo «freetype» estas malŝaltita: devas esti bitbilda aŭ XML-vektora " +"tiparo.\n" +"La reenpaŝa tiparo uziĝos se la tiparo ne povas enlegiĝi." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Dosierindiko al la egallarĝa tiparo.\n" +"Se la agordo «freetype» estas ŝaltita: devas esti tiparspeco «TrueType».\n" +"Se la agordo «freetype» estas malŝaltita: devas esti bitbilda aŭ XML-vektora " +"tiparo.\n" +"Ĉi tiu tiparo estas uzata por ekz. la ekranoj de konzolo kaj profililo." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Paŭzigi je perdita fokuso de la fenestro" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "Limo de atendataj monderoj ŝargotaj el disko por unu ludanto" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Limo de viceroj estigotaj por unu ludanto" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fiziko" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Celilsekva klavo" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Celilsekva reĝimo" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Klavo por meti" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Intertempo inter ripetaj metoj" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Ludanto povas flugi sed efiko de pezforto.\n" +"Bezonas la rajton «flugi» je la servilo." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Distanco por transsendo de ludantoj" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Ludanto kontraŭ ludanto" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Poisson-filtrado" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Konektota pordo (UDP).\n" +"Rimarku, ke la porda kampo en la ĉefmenuo transpasas ĉi tiun agordon." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Malhelpu ripetadon de fosado kaj metado dum premo de la musklavoj.\n" +"Ŝaltu ĉi tion, se vi tro ofte nevole fosas aŭ metas monderojn." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Malhelpi al reguligistoj agi nesekure (ekzemple ruli ŝelajn komandojn)." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Presi la profilajn datenojn de la motoro laŭ regulaj intervaloj (en " +"sekundoj).\n" +"0 = malŝalti. Utila por evoluigistoj." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Rajtoj, kiujn ludantoj kun «basic_privs» povas doni" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Profililo" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Profilila baskula klavo" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Aŭskulta adreso de Prometheus" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Aŭskulta adreso de Prometheus.\n" +"Se Minetest estas tradukita kun la elekteblo ENABLE_PROMETHEUS ŝaltita,\n" +"ŝaltiĝos aŭskultado de mezuriloj por Prometheus ĉe tiu adreso.\n" +"Mezuriloj disponeblos ĉe http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Proporcio de grandaj kavernoj, kiu enhavas fluaĵon." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Duondiametro de nuba areo donita en nombro da 64-monderaj nubaj ortanguloj.\n" +"Valoroj super 26 estigos akrajn randojn je anguloj de la areo." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Levas terenon por krei valojn ĉirkaŭ la riveroj." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Hazarda enigo" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Klavo por ŝanĝi vidodistancon" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Freŝaj mesaĝoj de babilo" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Dosierindiko al normala tiparo" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Foraj vidaŭdaĵoj" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Fora pordo" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Forigi kolorkodojn de envenaj babilaj mesaĝoj\n" +"Uzu tion por ĉesigi uzon de koloroj en mesaĝoj de ludantoj" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Anstataŭigas la implicitan ĉefmenuon per propra." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Raporta indiko" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Limigas atingon de kelkaj klient-flankaj funkcioj sur serviloj.\n" +"Kombinu la ĉi-subajn bitindikilojn por limigi klient-flakajn funkciojn,\n" +"aŭ agordu al 0 por nenion limigi:\n" +"LOAD_CLIENT_MODS: 1 (malŝaltas enlegadon de klient-flankaj modifaĵoj)\n" +"CHAT_MESSAGES: 2 (malŝaltas klient-flankan vokadon de «send_chat_message»)\n" +"READ_ITEMDEFS: 4 (malŝaltas klient-flankan vokadon de «get_item_def»)\n" +"READ_NODEDEFS: 8 (malŝaltas klient-flankan vokadon de «get_node_def»)\n" +"LOOKUP_NODES_LIMIT: 16 (limigas klient-flankan vokadon de «get_node_call»\n" +"al «csm_restriction_noderange»)\n" +"READ_PLAYERINFO: 32 (malŝaltas klient-flankan vokadon de «get_player_names»)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Bruo de disvastiĝo de krestaj montoj" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Bruo de krestoj" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Subakva bruo de krestoj" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Bruo de grandeco de krestaj montoj" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Dekstren-klavo" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Profundeco de rivera akvovojo" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Larĝeco de riveraj akvovojoj" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Rivera profundo" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Rivera bruo" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Grandeco de riveroj" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Profundeco de riveraj valoj" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Malfarebligo" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Bruo de grandeco de mildaj montetoj" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Bruo de disvastiĝo de mildaj montetoj" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Ronda mapeto" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Sekuraj fosado kaj metado" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Sablaj bordoj okazas kiam «np_beach» superas ĉi tiun valoron." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Konservi mapon ricevitan fare de la kliento al la disko." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Memori fenestran grandon post ties ŝanĝo." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Konservanta mapon ricevitan de la servilo" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Skali la fasadon per valoro difinita de la uzanto.\n" +"Uzi glatigan filtrilon per la plej proksimaj bilderoj por skali la fasadon.\n" +"Ĉi tio glatigos iom da malglataj limoj, kaj miksos bilderojn\n" +"malskalante, kontraŭ malklarigo de kelkaj limaj bilderoj, malskalante\n" +"per neentejraj kvantoj." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Ekrano:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Alteco de ekrano" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Larĝeco de ekrano" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Ekrankopia dosierujo" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Ekrankopia dosierformo" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Ekrankopia kvalito" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Ekrankopia kvalito. Nur uzata por la dosierformo « JPEG ».\n" +"1 estas plej malaltkvalita; 100 estas plej altkvalita.\n" +"Uzu 0 por implicita kvalito." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Ekrankopio" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Bruo de marfundo" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Dua el la kvar 2d-aj bruoj, kiuj kune difinas altecon de mont(et)aj krestoj." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Dua el la du 3d-aj bruoj, kiuj kune difinas tunelojn." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Vidu https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Limkoloro de elektujo (R,V,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Koloro de elektujo" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Larĝo de elektujo" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Elektas unu de 18 tipoj de fraktaloj.\n" +"1 = 4D «Rondeca» aro de Mandelbrot.\n" +"2 = 4D «Rondeca» aro de Julia.\n" +"3 = 4D «Ortanguleca» aro de Mandelbrot.\n" +"4 = 4D «Ortanguleca» aro de Julia.\n" +"5 = 4D «Mandy Cousin» aro de Mandelbrot.\n" +"6 = 4D «Mandy Cousin» aro de Julia.\n" +"7 = 4D «Variaĵa» aro de Mandelbrot.\n" +"8 = 4D «Variaĵa» aro de Julia.\n" +"9 = 3D «Mandelbrot/Mandelbar» aro de Mandelbrot.\n" +"10 = 3D «Mandelbrot/Mandelbar» aro de Julia.\n" +"11 = 3D «Kristnaskarba» aro de Mandelbrot.\n" +"12 = 3D «Kristnaskarba» aro de Julia.\n" +"13 = 3D «Mandelbulb» aro de Mandelbrot.\n" +"14 = 3D «Mandelbulb» aro de Julia.\n" +"15 = 3D «Kosinuse Mandelbulb» aro de Mandelbrot.\n" +"16 = 3D «Kosinuse Mandelbulb» aro de Julia.\n" +"17 = 4D «Mandelbulb» aro de Mandelbrot.\n" +"18 = 4D «Mandelbulb» aro de Julia." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL de servilo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Nomo de servilo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Priskribo pri servilo" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL de servilo" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Adreso de servilo" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Priskribo pri servilo" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Nomo de servilo" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Pordo de servilo" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Servilflanka elektado de postkaŝitoj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Servila pordo" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL de listo de publikaj serviloj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "URL de listo de publikaj serviloj" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Dosiero kun listo de serviloj" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Agordi la lingvon. Lasu malplena por uzi la sisteman.\n" +"Rerulo necesas post la ŝanĝo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Agordi maksimuman longon de babilaj mesaĝoj (en signoj) sendotaj de klientoj." + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Ŝaltu por ebligi ondantajn foliojn.\n" +"Bezonas ombrigilojn." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Ŝaltu por ebligi ondantajn foliojn.\n" +"Bezonas ombrigilojn." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Ŝaltu por ebligi ondantajn fluaĵojn (kiel akvon).\n" +"Bezonas ombrigilojn." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Verigo ŝaltas ondantajn kreskaĵojn.\n" +"Bezonas ŝalton de ombrigiloj." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Indiko al ombrigiloj" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Ombrigiloj ebligas specialaj vidajn efektojn kaj povas plibonigi efikecon je " +"kelkaj vidkartoj.\n" +"Ĉi tio funkcias nur kun la bildiga internaĵo de «OpenGL»." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "Ekrankopia kvalito" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map texture size" +msgstr "Minimuma grandeco de teksturoj" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Deŝovo de ombro de la norma tiparo. Se ĝi estas 0, la ombro ne desegniĝos." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "Forto de ombro" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Formo de la mapeto. Ŝaltita = ronda, malŝaltita = orta." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Montri erarserĉajn informojn" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Montri elektujojn de estoj" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Montri elektujojn de estoj\n" +"Rerulo necesas post la ŝanĝo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Show name tag backgrounds by default" +msgstr "Implicite montri fonojn de nometikedoj" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Ferma mesaĝo" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Grandeco de mondopartoj estigitaj de mondestigilo, esprimita en mondopecoj\n" +"(16 monderoj).\n" +"AVERTO: Estas neniu avantaĝo, nur kelkaj danĝeroj, en pliigo de la valoro " +"super 5.\n" +"Malpliigo de la valoro plialtigas densecon de kavernoj kaj forgeskeloj.\n" +"Ŝanĝeblo de la valoro celas specialajn uzojn; senŝanĝo estas rekomendata." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Grandeco de la mondopeca kaŝmemoro de la meŝestigilo. Plialtigo ankaŭ\n" +"plialtigos la elcenton de kaŝmemoraj trafoj, kaj malpliigos la datenojn\n" +"kopiatajn de la ĉefa fadeno, malhelpante skuadon." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Tranĉo w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Deklivo kaj plenigo kunlaboras por ŝanĝi la altecojn." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Maksimuma nombro de malgrandaj kavernoj" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Minimuma nombro de etaj kavernoj" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "Malgranda variado de malsekeco por kontinuigi klimatojn ĉe limoj." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "Etarea variigo de varmeco por intermiksado de klimatoj je limoj." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Glata lumado" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Glitigas movojn de la vidpunkto dum ĉirkaŭrigardado.\n" +"Utila por registrado de filmoj." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "Glatigas la turnadon de vidpunkto en glita reĝimo. 0 por malŝalti." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Glitigas turnadon de la vidpunkto. 0 por malŝalti." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Kaŝira klavo" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Rapido de kaŝiro" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Rapido de kaŝirado, en monderoj sekunde." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Radiuso de mola ombro" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Sono" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Specifas URL de kiu la kliento elŝutos vidaŭdaĵojn, anstataŭ uzi UDP.\n" +"$filename atingeblu de $remote_media$filename per cURL\n" +"(kompreneble, «remote_media» finiĝu per dekliva streko).\n" +"Dosieroj mankantaj elŝutiĝos per la kutima maniero." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Specifas la implicitajn kolumnograndojn de monderoj, portaĵoj kaj iloj.\n" +"Notu, ke modifaĵoj aŭ ludoj povas eksplicite agordi kolumnograndojn por iuj " +"(aŭ ĉiuj) portaĵoj." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Disvastiĝo de pliiga amplekso de luma kurbo.\n" +"Regas la larĝecon de la pliigota amplekso.\n" +"Norma deflankiĝo de pliigo de la luma kurbo Gaŭsa." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Statika naskiĝejo" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Bruo de kruteco" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Bruo de grandeco de terasaj montoj" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Bruo de disvastiĝo de terasaj montoj" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Potenco de paralakso en tridimensia reĝimo." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Forteco de pliigo de la luma kurbo.\n" +"La 3 parametroj de «boost» definas amplekson\n" +"de la luma kurbo, kies heleco estas pliigita." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Severa kontrolo de protokoloj" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Forpreni kolorkodojn" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Surfaca nivelo de ebla akvo sur solida fluginsula tavolo.\n" +"Tia akvo estas malŝaltita implicite kaj ĉeestos nur se ĉi tiu valoro estas\n" +"pli granda ol 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (la komenco de " +"la\n" +"supra maldikiĝo).\n" +"***AVERTO, EBLA DANĜERO AL MONDOJ KAJ SERVILA RENDIMENTO***:\n" +"Se vi ebligas akvon sur fluginsuloj, la fluginsuloj devas esti solidaj " +"tavoloj.\n" +"Por tio, la agordo 'mgv7_floatland_density' devas esti '2.0' (aŭ alia\n" +"postulata valoro depende de 'mgv7_np_floatland'). Tio evitos\n" +"servil-intensan ekstreman akvofluon kaj vastan inundadon de la\n" +"suba mondsurfaco." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "Akorda SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Varmeca diverseco por klimatoj." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Agordoj" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Alternativa bruo de tereno" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Bruo de terena bazo" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Alteco de tereno" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Pli alta bruo de tereno" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Bruo de tereno" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Sojlo de terena bruo por montetoj.\n" +"Regas parton de la mondon kovratan per montetoj.\n" +"Proksimigu al 0.0 por pligrandigi la parton." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Sojlo de terena bruo por lagoj.\n" +"Regas la parton de mondo kovritan per lagoj.\n" +"Proksimigu al 0.0 por pli granda parto." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Bruo de persisteco de tereno" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Indiko al teksturoj" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Teksturoj sur mondero povas laŭi aŭ la monderon aŭ la mondon.\n" +"La unua reĝimo pli taŭgas por maŝinoj, mebloj, ktp., kaj la dua donas\n" +"pli bonan similecon kun ĉirkaŭo al ŝtupoj kaj etblokoj.\n" +"Sed ĉar tiu ĉi eblo estas nova, kaj malnovaj serviloj ne povas ĝin uzi,\n" +"ĉi tiu elekteblo bezonigas ĝin por kelkaj specoj de monderoj. Tio ĉi tamen\n" +"estas EKSPERIMENTA, kaj eble ne funkcios bone." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "URL al la deponejo de enhavo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The dead zone of the joystick" +msgstr "La nerespondema zono de la stirstango" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"La norma formo, en kiu konserviĝas profiloj, kiam\n" +"vokiĝas «/profiler save [formo]» sen formo." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "La profundeco de tero aŭ alia surfaca klimata plenigilo." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"La dosierindiko relativa al via mondoindiko, kien konserviĝos profiloj." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "Identigilo de la uzota stirstango" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "Longeco (en bilderoj) necesa por komenco de interago kun tuŝekrano." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"Maksimuma alteco de la nivelo de ondantaj fluaĵoj.\n" +"4.0 = Alteco de ondo estas du monderoj.\n" +"0.0 = Ondo tute ne moviĝas.\n" +"La antaŭagordo estas 1.0 (duono de mondero).\n" +"Bezonas ŝaltitajn ondantajn fluaĵojn." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "La reta interfaco kie la servilo aŭskultas." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"La rajtoj, kiuj novaj uzantoj memage akiras.\n" +"Vidu «/privs» en la ludo por plena listo de via servilo kaj modifaĵa " +"agordaro." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"La volumena radiuso, mezurita en mondopecoj (16 monderoj),\n" +"de monderoj ĉirkaŭ ĉiu ludanto submetataj al la trajtoj de aktivaj " +"monderoj. \n" +"En aktivaj monderoj, objektoj enlegiĝas kaj aktivaj modifiloj de monderoj " +"(ABM) ruliĝas.\n" +"Ĉi tio ankaŭ estas la minimuma vidodistanco, en kiu teniĝas aktivaj objektoj " +"(estuloj).\n" +"Ĉi tio devas esti agordita kune kun active_object_send_range_blocks." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"La bildiga internaĵo.\n" +"Relanĉo necesas post ĉi tiu ŝanĝo.\n" +"Rimarko: Sur Androido, restu ĉe OGLES1, se vi ne certas! Aplikaĵo alie " +"povus\n" +"malsukcesi ruliĝon. Sur aliaj sistemoj, OpenGL estas rekomendata.\n" +"Ombrigiloj estas subtenataj de OpenGL (nur sur tablaj komputiloj) kaj OGLES2 " +"(eksperimente)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"Sentemo de la stirstangaj aksoj por movadi la\n" +"enludan vidamplekson." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"La potenco (mallumeco) de ĉirkaŭaĵa ombrigo de monderoj.\n" +"Malpli estas mallume, pli estas lume. La valida amplekso de valoroj\n" +"estas inter 0.25 kaj 4.0, inkluzive. Se la valoro estas ekster la amplekso,\n" +"ĝi prezentos la plej proksiman valoron validan." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Tempo (en sekundoj) dum kiu atendovico de fluaĵoj povas superkreski\n" +"la datentraktan kapablon, ĝis oni provos ĝin malgrandigi per forĵeto de\n" +"malnovaj viceroj. Nula valoro malŝaltas la funkcion." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"Tempobuĝeto por rulado de ABM (aktiva modifilo de monderoj) dum ĉiu paŝo\n" +"(kiel frakcio de la intertempo de ABM)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Tempo (en sekundoj) inter ripetataj okazoj dum premo\n" +"de stirstangaj klavoj." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Tempo (en sekundoj) inter ripetaj metoj de monderoj dum premado de\n" +"la butono por meti." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "La speco de stirstango" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"Vertikala distanco post kiu varmeco malpliiĝas je 20, se «altitude_chill»\n" +"estas ŝaltita. Ankaŭ la vertikala distanco post kiu malsekeco malpliiĝas\n" +"je 10 se «altitude_dry» estas ŝaltita." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "Tria el la 4 3d-aj bruoj, kiuj kune difinas altecon de mont(et)aroj." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Vivodaŭro de metitaj portaĵoj en sekundoj.\n" +"Agordo al -1 malŝaltas la funkcion." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "Tagtempo kiam nova mondo ekas, en hormilonoj (0–23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Intervalo de sendado de tempaj informoj" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Rapido de tempo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "Tempolimo por forigi neuzatajn mapajn datenojn de klienta memoro." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Por malpliigi retprokraston, transsendoj de menderoj malrapidiĝas kiam " +"ludanto ion\n" +"konstruas. Ĉi tio decidas, kiom longe ili malrapidos post meto aŭ forigo de " +"mondero." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Baskula klavo de vidpunkta reĝimo" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Prokrasto de ŝpruchelpilo" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Sojlo de tuŝekrano" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Sojlo de tuŝekrano" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Bruo de arboj" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Triineara filtrado" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"Vera = 256\n" +"Falsa = 128\n" +"Povas faciligi mapeton por malrapidaj komputiloj." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Fidataj modifaĵoj" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL al la listo de serviloj, montrota en la langeto «Ludo por pluraj»." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Subspecimenado" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Subspecimenado similas uzon de malgranda ekrana distingumo, sed ĝi nur\n" +"efektivas en la ludo, lasante la fasadon senŝanĝa.\n" +"Ĝi grave helpu la efikecon kontraŭ malpli detala filmo." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Senlima distanco por transsendo de ludantoj" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Mallegi neuzatajn servilajn datenojn" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Supra Y-limo de forgeskeloj." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Supra Y-limo de fluginsuloj." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Uzi 3d-ajn nubojn anstataŭ ebenajn." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Uzi moviĝantajn nubojn por la fono de la ĉefmenuo." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "Uzi neizotropan filtradon vidante teksturojn deflanke." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Uzi dulinearan filtradon skalante teksturojn." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Uzi etmapigon por skali teksturojn. Povas iomete plibonigi efikecon,\n" +"precipe dum uzo de teksturaro je alta distingumo.\n" +"Gamae ĝusta malgrandigado ne estas subtenata." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Uzi multspecimenan glatigon (MSAA) por glatigi randojn de monderoj.\n" +"Tiu algoritmo glatigas la tridimensian vidon, ne malklarigante la bildon.\n" +"Tamen, ĝi ne ŝanĝas la internon de teksturoj\n" +"(kio estas speciale rimarkebla pri travideblaj teksturoj).\n" +"Videblaj spacoj aperas inter monderoj, se ombrigiloj estas malŝaltitaj.\n" +"Se la valoro de ĉi tiu elekteblo estas 0, multspecimena glatigo estas " +"malŝaltita.\n" +"Vi devas relanĉi post ŝanĝo de ĉi tiu elekteblo." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Uzi trilinearan filtradon skalante teksturojn." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "Vertica bufrobjekto" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Vertikala akordigo" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Profundeco de valoj" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Plenigo de valoj" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Profilo de valoj" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Deklivo de valoj" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Vario de profundoj de surfacoj de klimato." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Variaĵo de maksimuma alteco de montoj (en monderoj)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Variado de nombro de kavernoj." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Variado de vertikala skalo de tereno.\n" +"Kiam brua subas -0.55, tereno estas preskaŭ plata." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Variigas profundecon de surfacaj monderoj de klimato." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Variigas krudecon de tereno.\n" +"Difinas la valoron de «persistence» (persisto) por la bruoj «terrain_base»\n" +"kaj «terrain_alt»." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Variigas la krutecon de krutaĵoj." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Vertikala rapido de grimpado, en monderoj sekunde." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Vertikala samtempigo de ekrano." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Videa pelilo" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Koeficiento de balancado de vido" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Vidodistanco mondere." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Klavo por malgrandigi vidodistancon" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Klavo por pligrandigi vidodistancon" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Vidpunkta zoma klavo" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Vidodistanco" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Virtual joystick triggers Aux1 button" +msgstr "Virtuala stirstango premas specialan klavon" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Laŭteco" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Laŭteco de ĉiuj sonoj\n" +"Bezonas ŝaltitan sonsistemon." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"W-koordinato de la estigita 3D-tranĉo de la 4D-fraktalo.\n" +"Determinas kiu 3D-tranĉo de la 4D-formo estiĝas.\n" +"ŝanĝas la formon de la fraktalo.\n" +"Neniel efikas sur 3D-fraktaloj.\n" +"Ampleksa proksimume de -2 ĝis 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Rapido de irado kaj flugado, en monderoj sekunde." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Rapido de irado" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Rapido de irado, flugado kaj grimpado en rapida reĝimo, en monderoj sekunde." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Akvonivelo" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Nivelo de la akvonivelo tra la mondo." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Ondantaj monderoj" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Ondantaj foliaĵoj" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Ondantaj fluaĵoj" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Alteco de ondoj de ondantaj fluaĵoj" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Rapido de ondoj sur ondanta akvo" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Longo de ondoj de ondantaj fluaĵoj" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Ondantaj plantoj" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "Koloro de elektujo" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Kiam veras «gui_scaling_filter», ĉiuj bildoj de la grafika fasado\n" +"devas filtriĝi en la programaro, sed iuj bildoj estiĝas rekte en la\n" +"programaro (ekz. «render-to-texture» por monderoj en portaĵujo)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Kiam veras «gui_scaling_filter_txr2img», kopii la bildojn\n" +"de aparataro al programaro por skalado. Kiam malveras, repaŝu\n" +"al la malnova metodo de skalado, por vid-peliloj, kiuj ne subtenas\n" +"bone elŝutadon de teksturoj de la aparataro." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Dum uzo de duliniaj/triliniaj/neizotropaj filtriloj, tekstruoj je malaltaj\n" +"distingumoj povas malklariĝi; tial memage grandigu ĝin per interpolado\n" +"laŭ plej proksimaj bilderoj por teni klarajn bilderojn. Ĉi tio agordas la\n" +"malplejaltan grandecon de teksturo por la grandigitaj teksturoj; pli altaj\n" +"valoroj aspektas pli klare, sed bezonas pli da memoro. Potencoj de duo\n" +"estas rekomendataj. Valoroj pli grandaj ol 1 eble ne estos videblaj, se ne\n" +"estas ŝaltita dulinia, trilinia, aŭ neizotropa filtrado.\n" +"Ĉi tio ankaŭ uziĝas kiel la baza grando de monderaj teksturoj por memaga\n" +"grandigado de monde laŭigitaj teksturoj." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Ĉu implicite montri fonojn de nometikedoj.\n" +"Modifaĵoj malgraŭ tio povas agordi fonojn." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "Ĉu teksturaj movbildoj de monderoj malsamtempiĝu en ĉiu mondopeco." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Ĉu ludantoj montriĝas al klientoj sen limo de vidodistanco.\n" +"Evitinda; uzu anstataŭe la agordon «player_transfer_distance»." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Ĉu permesi al ludantoj vundi kaj mortigi unu la alian." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Ĉu peti rekonekton de klientoj post kolapso (de Lua).\n" +"Ĉi tion agordu al vero se via servilo rekomencos memage." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Ĉu nebuli finon de la videbla areo." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Ĉu silentigi sonojn. Vi povas malsilentigi ilin kiam ajn, malse\n" +"la sonsistemo estas malŝaltita (enable_sound=false).\n" +"Enlude, vi povas ŝalti la staton de silentigo per la silentiga klavo,\n" +"aŭ per la paŭza menuo." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"Ĉu montri erarserĉajn informojn de la kliento (efikas samkiel premo de F5)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Larĝo de la fenestro je ĝia komenca grando. Ignorata en plenekrana reĝimo." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Larĝo de linioj de la elektujo ĉirkaŭ monderoj." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Nur por Vindozo: Rulu Mineteston fone per la komanduja fenestro.\n" +"Ĝi enhavos la samajn informojn kiel la dosiero (norme nomita) debug.txt." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Monda dosierujo (ĉio en la mondo konserviĝos ĉi tie).\n" +"Ne necesas dum komenco el la ĉefmenuo." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Tempo je komenco de mondo" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Monde laŭigitaj teksturoj povas skaliĝi trans kelkaj monderoj. Tamen,\n" +"la servilo eble ne sendos la volatan skalon, precipe se vi uzas speciale\n" +"fasonitan teksturaron; per ĉi tiu elekteblo, la kliento provas determini\n" +"la skalon memage, surbaze de la grandeco de la teksturo.\n" +"Vidu ankaŭ «texture_min_size».\n" +"Averto: Ĉi tiu elekteblo estas EKSPERIMENTA!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Reĝimo de monde laŭigitaj teksturoj" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y de plata tero." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y de nula nivelo de la transiro de monta denseco. Uzata por movi montojn " +"vertikale." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Y de supera limo de grandaj kavernoj." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Y-distanco trans kiu kavernoj etendiĝas al plena grandeco." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Y-distanco, ekde kiu fluginsuloj maldikiĝas de plena denso al nenio.\n" +"Maldikiĝo komenciĝas ĉe ĉi tiu distanco de la Y-limo.\n" +"Sur solida fluginsula tavolo, tio regas la altojn de montetoj/montoj.\n" +"Devas esti ne pli ol duono de la distanco inter la Y-limoj." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Y-nivelo de mezuma terena surfaco." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Y-nivelo de kaverna supra limo." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Y-nivelo de pli alta tereno, kiu estigas krutaĵojn." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Y-nivelo de malsupra tereno kaj marfundo." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Y-nivelo de marplanko." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Tempolimo de dosiere elŝuto de cURL" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "Interaga tempolimo de cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Samtempa limo de cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "– Krea reĝimo: " + +#~ msgid "- Damage: " +#~ msgstr "– Difekto: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = paralaksa ombrigo kun klinaj informoj (pli rapida).\n" +#~ "1 = reliefa mapado (pli preciza)." + +#~ msgid "Address / Port" +#~ msgstr "Adreso / Pordo" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Alĝustigi la gamaan kodadon al la lumtabeloj. Pli altaj nombroj estas pli " +#~ "helaj.\n" +#~ "Ĉi tiu agordo estas klientflanka, kaj serviloj ĝin malatentos." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "" +#~ "Ŝanĝas kiel montecaj fluginsuloj maldikiĝas super kaj sub la mezpunkto." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Ĉu vi certas, ke vi volas rekomenci vian mondon por unu ludanto?" + +#~ msgid "Back" +#~ msgstr "Reeniri" + +#~ msgid "Basic" +#~ msgstr "Baza" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bitoj bildere (aŭ kolornombro) en tutekrana reĝimo." + +#~ msgid "Bump Mapping" +#~ msgstr "Tubera mapado" + +#~ msgid "Bumpmapping" +#~ msgstr "Mapado de elstaraĵoj" + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Ŝanĝoj al fasado de la ĉefmenuo:\n" +#~ "- full (plena): Pluraj mondoj por unu ludanto, elektilo de ludo, " +#~ "teksturaro, ktp.\n" +#~ "- simple (simpla): Unu mondo por unu ludanto, neniuj elektiloj de ludo " +#~ "aŭ teksturaro.\n" +#~ "Povus esti bezona por malgrandaj ekranoj." + +#~ msgid "Config mods" +#~ msgstr "Agordi modifaĵojn" + +#~ msgid "Configure" +#~ msgstr "Agordi" + +#~ msgid "Connect" +#~ msgstr "Konekti" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Regas rapidon de profundiĝo en fluaĵoj." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Regas densecon de montecaj fluginsuloj.\n" +#~ "Temas pri deŝovo de la brua valoro «np_mountain»." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Regas larĝecon de tuneloj; pli malgranda valoro kreas pri larĝajn " +#~ "tunelojn." + +#~ msgid "Credits" +#~ msgstr "Kontribuantaro" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Koloro de celilo (R,V,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Difektado estas ŝaltita" + +#~ msgid "Darkness sharpness" +#~ msgstr "Akreco de mallumo" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Implicita tempolimo por cURL, milisekunde.\n" +#~ "Nur efektiviĝas programtradukite kun cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Difinas zonojn de glata tereno sur fluginsuloj.\n" +#~ "Glataj fluginsuloj okazas kiam bruo superas nulon." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Difinas glatigan paŝon de teksturoj.\n" +#~ "Pli alta valoro signifas pli glatajn normalmapojn." + +#~ msgid "Del. Favorite" +#~ msgstr "Forigi ŝataton" + +#~ msgid "" +#~ "Deprecated, define and locate cave liquids using biome definitions " +#~ "instead.\n" +#~ "Y of upper limit of lava in large caves." +#~ msgstr "" +#~ "Evitinda, difini kaj trovi kavernajn fluaĵojn anstataŭe per klimataj " +#~ "difinoj\n" +#~ "Y de supra limo de lafo en grandaj kavernoj." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Elŝuti ludon, ekzemple minetest_game, el minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Elŝutu ludon el minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Elŝutante kaj instalante $1, bonvolu atendi…" + +#~ msgid "Enable VBO" +#~ msgstr "Ŝalti VBO(Vertex Buffer Object)" + +#~ msgid "Enable register confirmation" +#~ msgstr "Ŝalti konfirmon de registriĝo" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Ŝaltas mapadon de elstaraĵoj por teksturoj. Normalmapoj devas veni kun la " +#~ "teksturaro,\n" +#~ "aŭ estiĝi memage.\n" +#~ "Bezonas ŝaltitajn ombrigilojn." + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Ŝaltas dumludan estigadon de normalmapoj (Reliefiga efekto).\n" +#~ "Bezonas ŝaltitan mapadon de elstaraĵoj." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Ŝaltas mapadon de paralaksa ombrigo.\n" +#~ "Bezonas ŝaltitajn ombrigilojn." + +#~ msgid "Enter " +#~ msgstr "Enigi " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Prova elekteblo; povas estigi videblajn spacojn inter monderoj\n" +#~ "je nombro super 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "Kadroj sekunde en paŭza menuo" + +#~ msgid "Fallback font shadow" +#~ msgstr "Ombro de reenpaŝa tiparo" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Travidebleco de ombro de la reenpaŝa tiparo" + +#~ msgid "Fallback font size" +#~ msgstr "Grando de reenpaŝa tiparo" + +#~ msgid "Filtering" +#~ msgstr "Filtrado" + +#~ msgid "Floatland base height noise" +#~ msgstr "Bruo de baza alteco de fluginsuloj" + +#~ msgid "Floatland mountain height" +#~ msgstr "Alteco de fluginsulaj montoj" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Maltravidebleco de tipara ombro (inter 0 kaj 255)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Grandeco de la reenpaŝa tiparo, punkte (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "Tiparoj «FreeType»" + +#~ msgid "Full screen BPP" +#~ msgstr "Kolornombro tutekrane" + +#~ msgid "Game" +#~ msgstr "Ludo" + +#~ msgid "Gamma" +#~ msgstr "Helĝustigo" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Estigi Normalmapojn" + +#~ msgid "Generate normalmaps" +#~ msgstr "Estigi normalmapojn" + +#~ msgid "HUD scale factor" +#~ msgstr "Skala koeficiento por travida fasado" + +#~ msgid "High-precision FPU" +#~ msgstr "Preciza glitkoma datentraktilo (FPU)" + +#~ msgid "IPv6 support." +#~ msgstr "Subteno de IPv6." + +#~ msgid "In-Game" +#~ msgstr "Lude" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Instali: dosiero: «$1»" + +#~ msgid "Instrumentation" +#~ msgstr "Ekzamenado" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Klavagordoj. (Se tiu menuo misfunkcias, forigu agordojn el minetest.conf)" + +#~ msgid "Lava depth" +#~ msgstr "Lafo-profundeco" + +#~ msgid "Lightness sharpness" +#~ msgstr "Akreco de heleco" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Limo de viceroj enlegotaj de disko" + +#~ msgid "Main" +#~ msgstr "Ĉefmenuo" + +#~ msgid "Main menu style" +#~ msgstr "Stilo de ĉefmenuo" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "Funkciigas programaron «DirectX» kun «LuaJIT». Malŝaltu okaze de " +#~ "problemoj." + +#~ msgid "Menus" +#~ msgstr "Menuoj" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Mapeto en radara reĝimo, zomo ×2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Mapeto en radara reĝimo, zomo ×4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Mapeto en supraĵa reĝimo, zomo ×2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Mapeto en supraĵa reĝimo, zomo ×4" + +#~ msgid "Name / Password" +#~ msgstr "Nomo / Pasvorto" + +#~ msgid "Name/Password" +#~ msgstr "Nomo/Pasvorto" + +#~ msgid "No" +#~ msgstr "Ne" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Normalmapa specimenado" + +#~ msgid "Normalmaps strength" +#~ msgstr "Normalmapa potenco" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Nombro da iteracioj de paralaksa ombrigo." + +#~ msgid "Ok" +#~ msgstr "Bone" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "" +#~ "Netravidebleco (alfa) de la ombro post la reenpaŝa tiparo, inter 0 kaj " +#~ "255." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "Entuta ekarto de la efiko de paralaksa ombrigo, kutime skalo/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Entuta vasteco de paralaksa ombrigo." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Paralaksa ombrigo" + +#~ msgid "Parallax occlusion" +#~ msgstr "Paralaksa ombrigo" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Ekarto de paralaksa okludo" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Iteracioj de paralaksa ombrigo" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Reĝimo de paralaksa ombrigo" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Skalo de paralaksa ombrigo" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Potenco de paralaksa ombrigo" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Dosierindiko al tiparo «TrueType» aŭ bitbildo." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Dosierindiko por konservi ekrankopiojn." + +#~ msgid "Player name" +#~ msgstr "Nomo de ludanto" + +#~ msgid "Profiling" +#~ msgstr "Profilado" + +#~ msgid "Projecting dungeons" +#~ msgstr "Planante forgeskelojn" + +#~ msgid "PvP enabled" +#~ msgstr "Dueloj ŝaltitas" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Rekomenci mondon por unu ludanto" + +#~ msgid "Select Package File:" +#~ msgstr "Elekti pakaĵan dosieron:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Servilo / Ludo por unu" + +#~ msgid "Shadow limit" +#~ msgstr "Limo por ombroj" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Deŝovo de tipara ombro (en bilderoj); se ĝi estas 0, la ombro ne " +#~ "desegniĝos." + +#~ msgid "Special" +#~ msgstr "Speciala" + +#~ msgid "Special key" +#~ msgstr "Speciala klavo" + +#~ msgid "Start Singleplayer" +#~ msgstr "Komenci ludon por unu" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Forteco de estigitaj normalmapoj." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Tiu ĉi tiparo uziĝos por iuj lingvoj." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Por uzi ombrigilojn, OpenGL-pelilo estas necesa." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Baskuligi glitan vidpunkton" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Ordinara plejalto, super kaj sub la mezpunkto, de fluginsulaj montoj." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Variaĵo de alteco de montetoj kaj profundeco de lagoj sur glata tereno de " +#~ "fluginsuloj." + +#~ msgid "View" +#~ msgstr "Vido" + +#~ msgid "Waving Water" +#~ msgstr "Ondanta akvo" + +#~ msgid "Waving water" +#~ msgstr "Ondanta akvo" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Ĉu tiparoj de FreeType uziĝas; postulas entradukitan subtenon de " +#~ "FreeType.\n" +#~ "Malŝaltite, ĉi tio anstataŭe uzigas tiparojn bitbildajn kaj XML-vektorajn." + +#, fuzzy +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Y de supera limo de grandaj kvazaŭ-hazardaj kavernoj." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Y-nivelo kien etendiĝas ombroj de fluginsuloj." + +#~ msgid "Yes" +#~ msgstr "Jes" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Vi estas aliĝonta al ĉi tiu servilo kun la nomo «%s» unuafoje.\n" +#~ "Se vi pluigos, nova konto kun viaj salutiloj registriĝos ĉe la servilo.\n" +#~ "Bonvolu retajpi vian pasvorton kaj klaki al «Registriĝi kaj aliĝi» por " +#~ "konfirmi kreon de konto, aŭ al «Nuligi» por ĉesigi." + +#~ msgid "You died." +#~ msgstr "Vi mortis." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/es/minetest.po b/po/es/minetest.po new file mode 100644 index 0000000..812e594 --- /dev/null +++ b/po/es/minetest.po @@ -0,0 +1,8194 @@ +msgid "" +msgstr "" +"Project-Id-Version: Spanish (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-24 09:24+0000\n" +"Last-Translator: Valentino <phamtomwhite@protonmail.com>\n" +"Language-Team: Spanish <https://hosted.weblate.org/projects/minetest/" +"minetest/es/>\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Vaciar la cola de chat de salida" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Comando vacío." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Salir al menú principal" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Comando inválido: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Comando emitido: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Listar jugadores conectados" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Jugadores conectados: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "La cola de salida del chat está ahora vacía." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Este comando está deshabilitado por el servidor." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Reaparecer" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Has muerto" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Comandos disponibles:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Comandos disponibles: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Comando no disponible: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Obtener ayuda para los comandos" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Usa '.help <cmd>' para obtener más información, o '.help all' para mostrar " +"todo." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Aceptar" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "<none available>" +msgstr "Comando no disponible: " + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Ha ocurrido un error en un script de Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Ha ocurrido un error:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menú principal" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Reconectar" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "El servidor ha solicitado una reconexión:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Selecciona Mods" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "Más tarde" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "Nunca" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "La versión del protocolo no coincide. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "El servidor utiliza el protocolo versión $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "El servidor soporta versiones del protocolo entre $1 y $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "Visitar el sitio web" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Solo se soporta la versión de protocolo $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Nosotros soportamos versiones de protocolo entre la versión $1 y $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "(Unsatisfied)" +msgstr "(Insatisfecho)" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Cancelar" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Dependencias:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Desactivar todo" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Desactivar pack de mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Activar todos" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Activar pack de mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Error al activar el mod \"$1\" por contener caracteres no permitidos. Solo " +"los caracteres [a-z0-9_] están permitidos." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Encontrar más mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Sin dependencias opcionales" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "La descripción del juego no está disponible." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Sin dependencias importantes" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "La descripción del mod no está disponible." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Sin dependencias opcionales" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Dependencias opcionales:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Guardar" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Mundo:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "activado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" ya existe. Quieres remplazarlo?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Las dependencias $1 y $2 serán instaladas." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 por $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 descargando,\n" +"$2 en espera" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 descargando..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 dependencias requeridas no se encuentren." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 serán instalados, y $2 dependencias serán ignoradas." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Todos los paquetes" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Ya está instalado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Volver al menú principal" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Juego Base:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" +"ContentDB no se encuentra disponible cuando Minetest se compiló sin cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Descargando..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Fallo al descargar $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Juegos" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instalar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Instalar $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Instalar dependencias faltantes" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Instalar: Formato de archivo no soportado o archivo corrupto" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mods" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "No se ha podido obtener ningún paquete" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Sin resultados" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "No hay actualizaciones" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "No encontrado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Sobreescribir" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Por favor verifica que el juego base está bien." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "En cola" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Paq. de texturas" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Desinstalar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Actualizar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Actualizar Todo [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Ver más información en un navegador web" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Ya existe un mundo llamado \"$1\"" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Terreno adicional" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Frío de altitud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Sequedad de altitud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Mezclado de biomas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Cavernas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Cavernas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Crear" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Decoraciones" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "" +"Advertencia: La prueba de desarrollo está destinada a los desarrolladores." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Mazmorras" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Terreno plano" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Tierras flotantes en el cielo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Tierras flotantes (experimental)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Generar terreno no fractal: Oceanos y subterráneos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Colinas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Ríos húmedos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Incrementa humedad alrededor de los ríos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "Instalar un juego" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Lagos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"La baja humedad y el alto calor causan que los ríos sean poco profundos o " +"secos" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Generador de mapas" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Banderas de Mapgen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Banderas específicas de Mapgen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Montañas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Flujo de lodo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Red de túneles y cuevas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Ningún juego seleccionado" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Reduce el calor con la altitud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Reduce la humedad con la altitud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Ríos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Ríos a nivel de mar" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Semilla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Transición suave entre biomas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Estructuras generadas en el terreno (sin efecto en arboles y césped de " +"jungla creado por v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Estructuras que aparecen en el terreno, típicamente árboles y plantas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Templado, Desierto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Templado, Desierto, Jungla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Templado, Desierto, Jungla, Tundra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erosión de la superficie del terreno" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Árboles y hierba de la selva" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Variar la profundidad del río" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Cavernas muy grandes en lo profundo del subsuelo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nombre del mundo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "No tienes juegos instalados." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "¿Realmente desea borrar \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Borrar" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: Error al borrar \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: Ruta \"$1\" inválida" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "¿Eliminar el mundo \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Confirmar contraseña" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Generador de mapas" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nombre" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Contraseña" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "Las contraseñas no coinciden" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Registrarse y unirse" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Aceptar" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Renombrar paquete de mod:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Éste paquete de mods tiene un nombre explícito dado en su modpack.conf el " +"cual sobreescribirá cualquier renombrado desde aquí." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Ninguna descripción de ajuste dada)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Ruido 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Volver a la página de configuración" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Explorar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "Contenido: Juegos" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "Contenido: Mods" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Desactivado" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Editar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Activado" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lagunaridad" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Octavas" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Compensado" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Persistencia" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Por favor, introduce un entero válido." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Por favor, introduzca un número válido." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Restablecer por defecto" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Escala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Buscar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Seleccionar carpeta" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Seleccionar archivo" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Mostrar los nombres técnicos" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "El valor debe ser mayor o igual que $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "El valor debe ser menor o igual que $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Propagación X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Propagación Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Propagación Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Valor absoluto" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "Predeterminados" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "Suavizado" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Activado)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mods" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Fallo al instalar $1 en $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Instalar mod: Imposible encontrar el nombre real del mod para: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Instalar mod: Imposible encontrar un nombre de carpeta adecuado para el " +"paquete de mod $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Imposible encontrar un mod o paquete de mod" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Fallo al instalar $1 como paquete de texturas" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Fallo al instalar un juego como $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Fallo al instalar un mod como $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Fallo al instalar un paquete de mod como $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Cargando..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "La lista de servidores públicos está desactivada" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Intente rehabilitar la lista de servidores públicos y verifique su conexión " +"a Internet." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Acerca de" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Colaboradores activos" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Renderizador activo:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Desarrolladores principales" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Abrir Directorio de Datos de Usuario" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Abre el directorio que contiene los mundos, juegos, mods, y paquetes de\n" +"textura, del usuario, en un gestor / explorador de archivos." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Antiguos colaboradores" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Antiguos desarrolladores principales" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Mostrar la informacion de la depuración" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Explorar contenido en línea" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Contenido" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Desactivar el paquete de texturas" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Información:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Paquetes instalados:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Sin dependencias." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "La descripción del paquete no está disponible" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Renombrar" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Desinstalar el paquete" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Usar el paqu. de texturas" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Anunciar servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Asociar dirección" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Modo creativo" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Permitir daños" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Hospedar juego" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Hospedar servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Instalar juegos desde ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Nuevo" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "¡No se ha dado un nombre al mundo o no se ha seleccionado uno!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Jugar juego" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Puerto" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Selecciona Mods" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Selecciona un mundo:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Puerto del servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Empezar juego" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Dirección" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Limpiar" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Modo creativo" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Daño / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favoritos" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Servidores Incompatibles" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Unirse al juego" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Servidores Públicos" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Actualizar" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Puerto remoto" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Descripción del servidor" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Nubes 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Todos los ajustes" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Suavizado:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Auto-guardar tamaño de pantalla" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Filtrado bilineal" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Configurar teclas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Vidrio conectado" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Sombras dinámicas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "Sombras dinámicas:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Hojas elegantes" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Alto" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Bajo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Medio" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Filtro aniso." + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Sin filtrado" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Sin Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Resaltar nodos" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Marcar nodos" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Nada" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Hojas opacas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Agua opaca" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partículas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Pantalla:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Ajustes" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Sombreadores" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Sombreadores (experimental)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Sombreadores (no disponible)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Hojas simples" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Iluminación suave" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Texturizado:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Mapeado de tonos" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "Umbral táctil (px):" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Filtrado trilineal" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Ultra Alto" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Muy bajo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Movimiento de hojas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Movimiento de líquidos" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Movimiento de plantas" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Error de conexión (¿tiempo agotado?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Tiempo de espera de la conexión agotado." + +#: src/client/client.cpp +msgid "Done!" +msgstr "¡Completado!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inicializando nodos" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Inicializando nodos..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Cargando texturas..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Reconstruyendo sombreadores..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Error de conexión (¿tiempo agotado?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "No se puede encontrar o cargar el juego: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Juego especificado no válido." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menú principal" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" +"No se seleccionó el mundo y no se ha especificado una dirección. Nada que " +"hacer." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Nombre de jugador demasiado largo." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "¡Por favor, elige un nombre!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Fallo para abrir el archivo con la contraseña proveída: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "La ruta del mundo especificada no existe: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Revisa debug.txt para más detalles." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Dirección: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Modo: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Puerto: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Público: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Nombre del servidor: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Ha ocurrido un error:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Acceso denegado. Razón: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Avance automático desactivado" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Avance automático activado" + +#: src/client/game.cpp +#, fuzzy +msgid "Block bounds hidden" +msgstr "Límites de bloque" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Límites de bloque mostrados para todos los bloques" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Actualización de la cámara desactivada" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Actualización de la cámara activada" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Cambiar Contraseña" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Modo cinematográfico desactivado" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Modo cinematográfico activado" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "El cliente se desconectó" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "El Scripting en el lado del cliente está desactivado" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Conectando al servidor..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "La conexión falló por razones desconocidas" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Continuar" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Controles:\n" +"- %s: moverse adelante\n" +"- %s: moverse atras\n" +"- %s: moverse a la izquierda\n" +"- %s: moverse a la derecha\n" +"- %s: saltar/escalar\n" +"- %s: excavar/golpear\n" +"- %s: colocar/usar\n" +"- %s: a hurtadillas/bajar\n" +"- %s: soltar objeto\n" +"- %s: inventario\n" +"- Ratón: girar/mirar\n" +"- Rueda del ratón: elegir objeto\n" +"- %s: chat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "No se pudo resolver la dirección : %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Creando cliente..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Creando servidor..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Info de depuración y gráfico de perfil ocultos" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Info de depuración mostrada" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Info de depuración, gráfico de perfil, y 'wireframe' ocultos" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Controles predeterminados:\n" +"Con el menú oculto:\n" +"- toque simple: botón activar\n" +"- toque doble: colocar/usar\n" +"- deslizar dedo: mirar alrededor\n" +"Con el menú/inventario visible:\n" +"- toque doble (fuera):\n" +" -->cerrar\n" +"- toque en la pila de objetos:\n" +" -->mover la pila\n" +"- toque y arrastrar, toque con 2 dedos:\n" +" -->colocar solamente un objeto\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Rango de visión ilimitada desactivado" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Rango de visión ilimitada activado" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Creando cliente..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Salir al menú" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Salir al S.O." + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Modo rápido desactivado" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Modo rápido activado" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Modo rápido activado (nota: sin privilegio 'rápido')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Modo de vuelo desactivado" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Modo de vuelo activado" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Modo de vuelo activado (nota: sin privilegio de vuelo)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Niebla desactivada" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Niebla activada" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Información del juego:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Juego pausado" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Servidor anfitrión" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Definiciones de objetos..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Multimedia..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "El minimapa se encuentra actualmente desactivado por el juego o un mod" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Multijugador" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Modo 'Noclip' desactivado" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Modo 'Noclip' activado" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Modo 'Noclip' activado (nota: sin privilegio 'noclip')" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Definiciones de nodos..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Deshabilitado" + +#: src/client/game.cpp +msgid "On" +msgstr "Habilitado" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Modo de movimiento de inclinación desactivado" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Modo de movimiento de inclinación activado" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Gráfico de monitorización visible" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Servidor remoto" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Resolviendo dirección..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Cerrando..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Un jugador" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Volumen del sonido" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Sonido silenciado" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "El sistema de sonido está desactivado" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "El sistema de sonido no está soportado en esta \"build\"" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Sonido no silenciado" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Este servidor probablemente use una versión diferente de %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "No se puede conectar a %s porque IPv6 esta" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Rango de visión cambiado a %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "El rango de visión está al máximo: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Rango de visión está al mínimo: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Volumen cambiado a %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Lineas 3D mostradas" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "El zoom está actualmente desactivado por el juego o un mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "Aceptar" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Chat oculto" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Chat visible" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD oculto" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD mostrado" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Monitorización oculta" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Monitorización visible (página %d de %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplicaciones" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Tecla de borrado" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Bloq. Mayús" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Abajo" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Fin" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Borrar EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Ejecutar" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Ayuda" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Inicio" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Aceptar IME" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Convertir IME" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "Escape IME" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Cambiar Modo IME" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "No convertir IME" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insertar" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Izquierda" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Botón izquierdo" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Control izq." + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menú izq." + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Shift izq." + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Win izq." + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menú" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Botón central" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Bloq Núm" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Teclado Numérico *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Teclado Numérico +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Teclado Numérico -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Teclado Numérico ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Teclado Numérico /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Teclado Numérico 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Teclado Numérico 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Teclado Numérico 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Teclado Numérico 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Teclado Numérico 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Teclado Numérico 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Teclado Numérico 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Teclado Numérico 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Teclado Numérico 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Teclado Numérico 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Limpiar OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Re. pág" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Av. pág" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pausa" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Jugar" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Captura" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Retorno" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Derecha" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Botón derecho" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Control der." + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menú der." + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Shift der." + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Win der." + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Bloq Despl" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Seleccionar" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Suspender" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Captura de pantalla" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Espacio" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabulador" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Arriba" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Botón 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Botón 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Minimapa oculto" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimapa en modo radar, Zoom x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimapa en modo superficie, Zoom x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimapa en modo textura" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Fallo al abrir la página web" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Abriendo página web" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Continuar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = bajar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Auto-avance" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Salto automático" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Atrás" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Límites de bloque" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Cambiar cámara" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Comando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Consola" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Dec. rango" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Bajar volumen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Pulsar dos veces \"saltar\" para volar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Tirar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Adelante" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Inc. rango" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Subir volumen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventario" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Saltar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "La tecla ya se está utilizando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Comando local" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Silenciar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Siguiente" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Anterior" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Seleccionar distancia" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Captura de pantalla" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Caminar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Alternar el HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Alternar el registro del chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Activar rápido" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Activar volar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Alternar la niebla" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Alternar el minimapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Activar noclip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Alternar inclinación" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "pulsa una tecla" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Cambiar" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Contraseña nueva" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Contraseña anterior" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "¡Las contraseñas no coinciden!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Cerrar" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Silenciado" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Volumen del sonido: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "es" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "¡Por favor, elige un nombre!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Fija la posición de la palanca virtual.\n" +"Si está desactivado, la palanca virtual se centrará en la primera posición " +"al tocar." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Usar palanca virtual para activar el botón \"aux\".\n" +"Si está activado, la palanca virtual también activará el botón \"aux\" fuera " +"del círculo principal." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"Desvío (X,Y,Z) del fractal desde el centro del mundo en unidades de " +"'escala'.\n" +"Puede ser utilizado para mover el punto deseado al inicio de coordenadas (0, " +"0) para crear un\n" +"punto de aparición mejor, o permitir 'ampliar' en un punto deseado si\n" +"se incrementa la 'escala'.\n" +"El valor por defecto está ajustado para un punto de aparición adecuado " +"para \n" +"los conjuntos Madelbrot\n" +"Con parámetros por defecto, podría ser necesariomodificarlo para otras \n" +"situaciones.\n" +"El rango de está comprendido entre -2 y 2. Multiplicar por la 'escala' para " +"el desvío en nodos." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"Escala (X,Y,Z) del fractal en nodos.\n" +"El tamañó actual de fractal será de 2 a 3 veces mayor.\n" +"Estos números puede ser muy grandes, el fractal no está\n" +"limitado en tamaño por el mundo.\n" +"Incrementa estos valores para 'ampliar' el detalle del fractal.\n" +"El valor por defecto es para ajustar verticalmente la forma para\n" +"una isla, establece los 3 números iguales para la forma inicial." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Ruido 2D para controlar la forma/tamaño de las montañas escarpadas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Ruido 2D para controlar la forma/tamaño de las colinas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Ruido 2D para controlar la forma/tamaño de las montañas inclinadas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "Ruido 2D que controla el tamaño/aparición de cordilleras montañosas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "Ruido 2D que controla el tamaño/aparición de las colinas ondulantes." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" +"Ruido 2D que controla el tamaño/aparición de los intervalos de montañas " +"inclinadas." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Ruido 2D para ubicar los ríos, valles y canales." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Nubes 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Modo 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Fuerza de paralaje en modo 3D" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Ruido 3D definiendo cavernas gigantes." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Ruido 3D definiendo estructuras montañosas y altura.\n" +"También define la estructura de las islas flotantes montañosas." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Ruido 3D que define las estructuras flotantes.\n" +"Si se altera la escala de ruido por defecto (0,7), puede ser necesario " +"ajustarla, \n" +"los valores de ruido que definen la estrechez de islas flotantes funcionan " +"mejor \n" +"cuando están en un rango de aproximadamente -2.0 a 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Ruido 3D definiendo la estructura de las paredes de ríos de cañón." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Ruido 3D definiendo el terreno." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"Ruido 3D para los salientes de montañas, precipicios, etc. Pequeñas " +"variaciones, normalmente." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "Ruido 3D que determina la cantidad de mazmorras por chunk." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Soporte 3D.\n" +"Soportado actualmente:\n" +"- Ninguno (none): sin salida 3D.\n" +"- Anaglifo (anaglyph): 3D en colores cian y magenta.\n" +"- Entrelazado (interlaced): soporte para pantallas con polarización " +"basada en filas impar/par.\n" +"- Arriba-abajo (topbottom): dividir pantalla arriba y abajo.\n" +"- Lado a lado (sidebyside): dividir pantalla lado a lado.\n" +"- Vista cruzada (crossview): visión 3D cruzada.\n" +"- Rotación de página (pageflip): 3D basado en buffer cuádruple.\n" +"Nota: el modo entrelazado requiere que los shaders estén activados." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Semilla de mapa para un nuevo mapa, dejar vacío para una semilla aleatoria.\n" +"Será ignorado si se crea un nuevo mundo desde el menú principal." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" +"Un mensaje para ser mostrado a todos los clientes cuando el servidor cae." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Un mensaje para ser mostrado a todos los clientes cuando el servidor se " +"apaga." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Intervalo ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Límite de tiempo para MBA" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Límite absoluto de bloques en proceso" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Aceleración en el aire" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Aceleración de gravedad, en nodos por segundo." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Modificadores de bloques activos" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Intervalo de administración de bloques activos" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Rango de bloque activo" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Rango de envío en objetos activos" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Dirección para conectarse.\n" +"Dejar esto vacío para iniciar un servidor local.\n" +"Nótese que el campo de dirección del menú principal anula este ajuste." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Añade partículas al excavar un nodo." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Ajustar la configuración de puntos por pulgada a tu pantalla (no X11/Android " +"sólo), por ejemplo para pantallas 4K." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Adjuste la densidad de visualización detectada, usada para escalar elementos " +"de la interfaz." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Ajusta la densidad de la isla flotante.\n" +"Incrementar el valor para incrementar la densidad. Este puede ser negativo o " +"positivo\n" +"Valor = 0.0: 50% del volumen está flotando \n" +"Valor = 2.0 (puede ser mayor dependiendo de 'mgv7_np_floatland',\n" +"siempre pruébelo para asegurarse) crea una isla flotante compacta." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Añadir nombre de objeto" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avanzado" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Altera la curva de luz aplicándole una \"corrección gamma\".\n" +"Los valores más altos hacen que los niveles de luz medios y bajos sean más " +"brillantes.\n" +"El valor \"1.0\" deja la curva de luz inalterada.\n" +"Esto sólo tiene un efecto significativo en la luz del día y en la luz " +"artificial, \n" +"tiene muy poco efecto en la luz natural nocturna." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Siempre volando y rápido" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Gamma de oclusión ambiental" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Cantidad de mensajes que un jugador puede enviar en 10 segundos." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Ampliar los valles." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Filtrado anisotrópico" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Anunciar servidor" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Anunciar en esta lista de servidores." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Añadir nombre de objeto" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Añadir nombre de objeto a la burbuja informativa." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Ruido de manzanos" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Inercia de brazo" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Inercia de brazo, proporciona un movimiento más realista\n" +"del brazo cuando la cámara se mueve." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Preguntar para reconectar tras una caída" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"A esta distancia el servidor optimizará agresivamente qué bloques son " +"enviados a\n" +"los clientes.\n" +"Los valores bajos mejorarán mucho el rendimiento, a costa de \n" +"errores gráficos visibles (algunos bloques no serán renderizados bajo el " +"agua y en cuevas,\n" +"así como ocasionalmente en tierra).\n" +"Definir esto a un valor mayor que max_block_send_distance deshabilita esta\n" +"optimización.\n" +"Fijado en bloques de mapa (16 nodos)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Tecla de avance automático" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Saltar obstáculos de un nodo automáticamente." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Informar automáticamente a la lista del servidor." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Autoguardar el tamaño de la pantalla" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Modo de autoescalado" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Tecla Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Tecla Aux1 para subir/bajar" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tecla retroceso" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Nivel del suelo" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Altura base del terreno." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Privilegios básicos" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Sonido de playa" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Límite de ruido de playa" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Filtrado bilineal" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Dirección BIND" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Parámetros de ruido y humedad en la API de temperatura de biomas" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Ruido de bioma" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Optimizar la distancia del envío de bloques" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Ruta de la fuente en negrita y cursiva" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Ruta de la fuente monoespacio en negrita y cursiva" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Ruta de la fuente en negrita" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Ruta de la fuente monoespacio en negrita" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Construir dentro del jugador" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Incorporado" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Cambiar cámara" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Distancia de la cámara 'cerca del plano delimitador' en nodos, entre 0 y " +"0,25.\n" +"Solo funciona en plataformas GLES. La mayoría de los usuarios no necesitarán " +"cambiar esto.\n" +"Aumentarlo puede reducir el artifacting en GPU más débiles.\n" +"0.1 = Predeterminado, 0,25 = Buen valor para comprimidos más débiles." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Suavizado de cámara" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Suavizado de cámara en modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Tecla alternativa para la actualización de la cámara" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Ruido de cueva" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Ruido de cueva Nº1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Ruido de cueva Nº2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Ancho de cueva" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Ruido de cueva1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Ruido de cueva2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Límite de caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Ruido de caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Contención de la cueva" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Límite de caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Límite superior de caverna" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Centro de rango de impulso de la curva de luz.\n" +"Cuando 0.0 es el nivel mínimo de luz, 1.0 es el nivel de luz máximo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "Umbral de expulsión por mensajes" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Comandos de Chat" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Tamaño de la fuente del chat" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Tecla del Chat" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Nivel de registro del chat" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Límite de mensajes de chat" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Formato del mensaje del chat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Umbral de expulsión por mensajes" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Longitud máx. de mensaje de chat" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Tecla alternativa para el chat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Chat visible" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Tamaño del chunk" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tecla modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Limpiar texturas transparentes" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Cliente" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Cliente y servidor" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Customización del cliente" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Restricciones para modear del lado del cliente" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Restricción del rango de búsqueda del nodo del lado cliente" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Customización del cliente" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Velocidad de escalada" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Radio de nube" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Nubes" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Las nubes son un efecto del lado del cliente." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Nubes en el menú" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Niebla colorida" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Sombras coloridas" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Lista de 'marcas' a ocultar en el repositorio de contenido. La lista usa la " +"coma como separador.\n" +"Se puede usar la etiqueta \"nonfree\" para ocultar paquetes que no tienen " +"licencia libre (tal como define la Fundación de software libre (FSF)).\n" +"También puedes especificar clasificaciones de contenido.\n" +"Estas 'marcas' son independientes de la versión de Minetest.\n" +"Si quieres ver una lista completa visita https://content.minetest.net/help/" +"content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Lista (separada por comas) de mods a los que se les permite acceder a APIs " +"de HTTP, las cuales \n" +"les permiten subir y descargar archivos al/desde internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Lista de mods de fiar separada por coma que se permiten acceder a funciones\n" +"inseguras incluso quando securidad de mods está puesto (vía " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Tecla comando" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Nivel de compresión a usar para guardar bloques del mapa al disco.\n" +"-1 - usar compresión por defecto\n" +"0 - menor compresión, más rápido\n" +"9 - mejor compresión, más lento" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Nivel de compresión a usar cuando se envían bloques del mapa al cliente.\n" +"-1 - usar nivel de compresión por defecto\n" +"0 - menor compresión, más rápido\n" +"9 - mejor compresión, más lento" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Conectar vidrio" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Conectar a un servidor media externo" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Conectar gafas si el nodo lo permite." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Alfa de consola" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Color de la consola" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Altura de consola" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Contenido del repositorio en linea" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Lista negra de Contenido de la Base de Datos" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Descargas máximas simultáneas para ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "Dirección URL de ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Avance continuo" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Movimiento continuo hacia adelante. Activado por la tecla de auto-avance.\n" +"Presiona la tecla de auto-avance otra vez o retrocede para desactivar." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Controles" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Controla la duración del ciclo día/noche.\n" +"Ejemplos: \n" +"72 = 20min, 360 = 4min, 1 = 24hs, 0 = día/noche/lo que sea se queda " +"inalterado." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Controla la pendiente/profundidad de las depresiones del lago." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Controla la pendiente/altura de las colinas." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Controla la anchura de los túneles, un valor más pequeño crea túneles más " +"anchos.\n" +"El valor >- 10.0 desactiva completamente la generación de túneles y evita " +"la\n" +"cálculos intensivos de ruido." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Mensaje de error" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Creativo" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Opacidad del punto de mira" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Alfa del punto de mira (opacidad, entre 0 y 255).\n" +"También controla el color del objeto punto de mira" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Color de la cruz" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Color del punto de mira (R,G,B).\n" +"También controla el color del objeto punto de mira" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Daño" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Tecla alternativa para la información de la depuración" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Umbral del tamaño del archivo de registro de depuración" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Nivel de registro de depuración" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Dec. tecla de volumen" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Intervalo de servidor dedicado" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Aceleración por defecto" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Juego por defecto" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Juego predeterminado al crear un nuevo mundo.\n" +"Será sobreescrito al crear un mundo desde el menú principal." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Contraseña por defecto" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Privilegios por defecto" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Formato de Reporte por defecto" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Tamaño por defecto del stack (Montón)" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Define la calidad del filtro de sombras.\n" +"Esto simula el efecto de sombras suaves aplicando un PCF o Poisson disk\n" +"pero tambien utiliza más recursos." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Define las áreas donde los árboles tienen manzanas." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Define areas con playas arenosas." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" +"Define áreas de terreno más alto (acantilado) y afecta la inclinación de los " +"acantilados." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Define la distribución del terreno alto." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "Define el tamaño de las cuevas, valones bajos crean cuervas mayores." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Define la estructura del canal fluvial a gran escala." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Define la localización y terreno de colinas y lagos opcionales." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Define el nivel base del terreno." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Define la profundidad del canal del río." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Define la distancia máxima de envío de jugadores, en bloques (0 = sin " +"límite)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Define el ancho del canal del río." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Define el ancho del valle del río." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Define las áreas de árboles y densidad de árboles." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Retardo entre las actualizaciones de mallas en el cliente, en ms. " +"Incrementar esto\n" +"reducirá la cantidad de actualizaciones de mallas, lo que reducirá también " +"la inestabilidad en equipos antiguos." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Retraso en enviar bloques después de construir" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Demora para mostrar información sobre herramientas, en milisegundos." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Manejo de funciones de Lua obsoletas" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Profundidad en la cual comienzan las grandes cuevas." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Profundidad en la cual comienzan las grandes cuevas." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Descripción del servidor, que se muestra en la lista de servidores y cuando " +"los jugadores se unen." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Umbral de ruido del desierto" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Los desiertos se producen cuando np_biome supera este valor.\n" +"Cuando se activa la bandera de \"snowbiomes\", esto se ignora." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Desincronizar la animación de los bloques" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Decoraciones" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Tecla Excavar" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Partículas de excavación" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Desactivar Anticheat" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "No permitir contraseñas vacías" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Factor del Escalado de la Densidad de Visualización" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" +"Nombre de dominio del servidor, será mostrado en la lista de servidores." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Pulsar dos veces \"saltar\" para volar" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Pulsar dos veces \"saltar\" alterna el modo vuelo." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Tecla de \"Soltar objeto\"" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Imprimir información de depuración del generador de mapas." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Mazmorras, máx. Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Mazmorras, mín. Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Ruido de mazmorra" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Habilitar el soporte de IPv6 (tanto para el cliente como para el servidor).\n" +"Requerido para que las conexiones IPv6 funcionen." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Habilitar el soporte de mods de Lua en el cliente.\n" +"El soporte es experimental y la API puede cambiar." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Habilitar filtrado \"poisson disk\".\n" +"Si el valor es verdadero, utiliza \"poisson disk\" para proyectar sombras " +"suaves. De otro modo utiliza filtrado PCF." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Habilitar las sombras a color.\n" +"Si el valor es verdadero los nodos traslúcidos proyectarán sombras a color. " +"Esta opción usa muchos recursos." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Habilitar la ventana de la consola" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Activar el modo creativo para todos los jugadores" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Activar joysticks" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Activar soporte para los canales de mods." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Activar seguridad de mods" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Habilitar daños y muerte de jugadores." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Habilitar entrada aleatoria (solo usar para pruebas)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Habilita iluminación suave con oclusión ambiental simple.\n" +"Deshabilítalo para mayor velocidad o una vista diferente." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Habilitar para no permitir que clientes antíguos se conecten.\n" +"Los clientes antíguos son compatibles al punto de conectarse a nueos " +"servidores,\n" +"pero pueden no soportar nuevas características." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Habilita el uso de un servidor remoto de medios (si lo provee el servidor).\n" +"Servidores remotos ofrecen una manera significativamente más rápida de\n" +"descargar medios (por ej. texturas) cuando se conecta a un servidor." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Habilitar los objetos vértices del buffer.\n" +"Esto debería mejorar enormemente el rendimiento de los gráficos." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Habilita el balanceo de la vista y la cantidad de balanceo de la vista.\n" +"Por ejemplo: 0 para balanceo sin vista; 1.0 para normal; 2.0 para doble." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Habilita/deshabilita la ejecución de un servidor IPv6.\n" +"Ignorado si se establece bind_address.\n" +"Necesita habilitar enable_ipv6 para ser activado." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Permite el mapeo de tonos fílmicos de Hable \"Uncharted 2\".\n" +"Simula la curva de tono de la película fotográfica y cómo ésta se aproxima a " +"la\n" +"aparición de imágenes de alto rango dinámico. El contraste de gama media es " +"ligeramente\n" +"mejorado, los reflejos y las sombras se comprimen gradualmente." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Habilita la animación de objetos en el inventario." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Habilitar cacheado de mallas giradas." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Activar mini-mapa." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Habilita el sistema de sonido.\n" +"Si está desactivado, esto desactiva completamente todos los sonidos y\n" +"los controles de sonido el juego no serán funcionales.\n" +"Cambiar esta configuración requiere un reinicio." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Habilita compensaciones que reducen la carga del procesador o aumentan el " +"rendimiento de la renderizacion\n" +"a cambio de pequeños errores visuales que no impactan a la jugabilidad del " +"juego." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Perfilador" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Intervalo de impresión de datos del perfil del motor" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Métodos de entidad" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Exponente de la estrechez de tierra flotante. Altera el comportamiento de la " +"estrechez.\n" +"Valor = 1.0 crea una estrechez uniforme y lineal.\n" +"Valores > 1.0 crea una estrechez suave apropiada para las tierras flotantes " +"separadas\n" +"por defecto.\n" +"Valores < 1.0 (0.25, por ejemplo) crea un nivel de superficie más definida " +"con \n" +"tierras bajas más planas, apropiada para una capa de tierra flotante sólida." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS cuando está en segundo plano o pausado" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Factor de ruido" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Factor de balanceo en caída" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Ruta de la fuente alternativa" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Tecla rápida" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Aceleración del modo rápido" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Velocidad del modo rápido" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Movimiento rápido" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Movimiento rápido (por medio de tecla de \"Aux1\").\n" +"Requiere privilegio \"fast\" (rápido) en el servidor." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Campo visual" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Campo visual en grados." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Archivo en client/serverlist/ que contiene sus servidores favoritos " +"mostrados en la \n" +"página de Multijugador." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Profundidad del relleno" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Nivel lleno de ruido" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Mapa de tonos fílmico" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Las texturas filtradas pueden mezclar valores RGB con sus nodos adyacentes " +"que sean completamente transparentes,\n" +"los cuales los optimizadores de PNG usualmente descartan, lo que a veces " +"resulta en un borde claro u\n" +"oscuro en las texturas transparentes. Aplica éste filtro para limpiar esto\n" +"al cargar las texturas. Esto se habilita automaticamente si el mapeado MIP " +"tambien lo está." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Suavizado:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "Primero de 2 ruidos 3D que juntos definen la altura de la montañas." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Primero de 2 ruidos 3D que juntos definen túneles." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Semilla de mapa fija" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Joystick virtual fijo" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Densidad de las tierras flotantes" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Máximo valor de Y de las tierras flotantes" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Mínimo valor de Y de las tierras flotantes" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Ruido de la tierra flotante" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Exponente de la cónica de las tierras flotantes" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Distancia de cónico de la tierra flotante" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Nivel de agua de la tierra flotante" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Tecla vuelo" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Volar" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Niebla" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Inicio de Niebla" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Tecla para alternar niebla" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Tamaño de la fuente" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Fuente en negrita por defecto" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Letra cursiva por defecto" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Sombra de la fuente" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Alfa de sombra de la fuente" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Tamaño de la fuente" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Tamaño de fuente divisible por" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Tamaño de la fuente por defecto donde 1 unidad = 1 pixel a 96 DPI" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Tamaño de la fuente monoespaciada donde 1 unidad = 1 pixel a 96 DPI" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"El tamaño de la fuente del texto del chat reciente y el indicador del chat " +"en punto (pt).\n" +"El valor 0 utilizará el tamaño de fuente predeterminado." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"Para fuentes pixeladas que no escalan bien, esto asegura que los tamaños de " +"fuente utilizados\n" +"con esta fuente siempre seran divisibles por este valor, en píxeles. Por " +"ejemplo,\n" +"una fuente pixelada de 16 píxeles de alto debería tener un valor de 16, " +"entonces solo tendrá\n" +"un tamaño de 16,32,48,etc., por lo que un mod pidiendo un tamaño de 25 " +"recibira uno de 32." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Formato en los mensajes del chat del jugador. Los siguientes strings son " +"válidos:\n" +"@name, @message, @timestamp (opcional)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Formato de las capturas de pantalla." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Color de fondo predeterminado para los formularios" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Opacidad de fondo Predeterminada para formularios" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Color de fondo para formularios en pantalla completa" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Opacidad de los formularios en pantalla completa" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Color de fondo predeterminado para los formularios (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Opacidad predeterminada del fondo de los formularios (entre 0 y 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Color de fondo de los formularios en pantalla completa (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" +"Opacidad de fondo de los formularios en pantalla completa (entre 0 y 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Tecla Avanzar" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "Cuarto de 4 ruidos 2D que juntos definen la altura de las montañas." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Tipo de fractal" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" +"Fracción de la distancia visible en la que la niebla se empieza a renderizar" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Desde cuán lejos se generan los bloques para los clientes, especificado en " +"bloques de mapa (mapblocks, 16 nodos)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Desde cuán lejos se envían bloques a los clientes, especificado en bloques " +"de mapa (mapblocks, 16 nodos)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Desde cuan lejano los clientes saben de los objetos, en bloques (16 nodos).\n" +"\n" +"Establecer esto a más de 'active_block_range' tambien causará que\n" +"el servidor mantenga objetos activos hasta ésta distancia en la dirección\n" +"que el jugador está mirando. (Ésto puede evitar que los enemigos " +"desaparezcan)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Pantalla completa" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Modo de pantalla completa." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Escala de IGU" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Filtro de escala de IGU" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Filtro de escala de IGU \"txr2img\"" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Juegos" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Llamadas globales" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Atributos globales del generador de mapas.\n" +"En el generador de mapas V6 la opción (o marcador) \"decorations\" controla " +"todos los elementos decorativos excepto los árboles\n" +"y la hierba de la jungla, en todos los otros generadores de mapas esta " +"opción controla todas las decoraciones." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Gradiente de la curva de luz en el nivel máximo de luz.\n" +"Controla el contraste de los niveles de luz más altos." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Gradiente de la curva de luz en el nivel mínimo de luz.\n" +"Controla el contraste de los niveles de luz más bajos." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Gráficos" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Gráficos" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Gráficos" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravedad" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Nivel del suelo" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Ruido del suelo" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "Mods HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Escala de IGU" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Tecla de cambio del HUD" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Manejo de llamadas a la API de Lua en desuso:\n" +"- none: no registrar llamadas en desuso.\n" +"- log: imitar y registrar la pista de seguimiento de la llamada en desuso " +"(predeterminado para la depuración).\n" +"- error: abortar el uso de la llamada en desuso (sugerido para " +"desarrolladores de mods)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Tener el propio instrumento del generador de perfiles:\n" +"* Instrumente una función vacía.\n" +"Esto estima la sobrecarga, que la instrumentación está agregando (+1 llamada " +"de función).\n" +"* Instrumente el sampler que se utiliza para actualizar las estadísticas." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Mezcla de calor del ruido" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Calor del ruido" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Componente de altura del tamaño inicial de la ventana. Ignorado en el modo " +"de pantalla completa." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Altura del ruido" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Altura del ruido seleccionado" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Pendiente de la colina" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Umbral de la colina" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Ruido de las colinas 1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Ruido de las colinas 2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Ruido de las colinas 3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Ruido de las colinas 4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" +"Página de inicio del servidor, que se mostrará en la lista de servidores." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Aceleración horizontal en el aire al saltar o caer,\n" +"en nodos por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Aceleración horizontal y vertical en modo rápido,\n" +"en nodos por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Aceleración horizontal y vertical en el suelo o al subir,\n" +"en nodos por segundo." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Tecla de siguiente de la barra rápida" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Tecla de anterior de la barra rápida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Tecla de barra rápida ranura 1" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Tecla de barra rápida ranura 10" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Tecla de barra rápida ranura 11" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Tecla de barra rápida ranura 12" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Tecla de barra rápida ranura 13" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Tecla de barra rápida ranura 14" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Tecla de barra rápida ranura 15" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Tecla de barra rápida ranura 16" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Tecla de barra rápida ranura 17" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Tecla de barra rápida ranura 18" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Tecla de barra rápida ranura 19" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Tecla de barra rápida ranura 2" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Tecla de barra rápida ranura 20" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Tecla de barra rápida ranura 21" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Tecla de barra rápida ranura 22" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Tecla de barra rápida ranura 23" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Tecla de barra rápida ranura 24" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Tecla de barra rápida ranura 25" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Tecla de barra rápida ranura 26" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Tecla de barra rápida ranura 27" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Tecla de barra rápida ranura 28" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Tecla de barra rápida ranura 29" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Tecla de barra rápida ranura 3" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Tecla de barra rápida ranura 30" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Tecla de barra rápida ranura 31" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Tecla de barra rápida ranura 32" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Tecla de barra rápida ranura 4" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Tecla de barra rápida ranura 5" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Tecla de barra rápida ranura 6" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Tecla de barra rápida ranura 7" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Tecla de barra rápida ranura 8" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Tecla de barra rápida ranura 9" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Profundidad para los ríos." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Como de rápido se moverán las ondas de líquido. Más alto = más rápido.\n" +"Si es negativo, las ondas de líquido se moverán hacia atrás.\n" +"Requiere que se habiliten los líquidos de agitación." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Cuanto espera el servidor antes de descargar los bloques de mapa no " +"utilizados.\n" +"Con valores mayores es mas fluido, pero se utiliza mas RAM." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Disminuya esto para aumentar la resistencia del líquido al movimiento." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Ancho de los ríos." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Ruido de la mezcla de humedad" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Ruido para la humedad" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Variación de humedad para los biomas." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "servidor IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Si los FPS subieran a más de esto, limítelos durmiendo\n" +"a fin de no malgastar potencia de CPU sin beneficio." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Si está desactivado, la tecla \"Aux1\" se utiliza para volar rápido si el " +"modo\n" +"de vuelo y el modo rápido están habilitados." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Si está habilitado, el servidor realizará la selección de la oclusión del " +"bloque del mapa basado\n" +"en la posición del ojo del jugador. Esto puede reducir el número de bloques\n" +"enviados al cliente en un 50-80%. El cliente ya no recibirá lo mas " +"invisible\n" +"por lo que la utilidad del modo \"NoClip\" se reduce." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Si se activa junto con el modo vuelo, el jugador puede volar a través de " +"nodos sólidos.\n" +"Requiere del privilegio \"noclip\" en el servidor." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Si está activada, la tecla \"Aux1\" en lugar de la tecla \"Sneak\" se " +"utilizará para bajar y\n" +"descender." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Habilitar confirmación de registro al conectar al servidor\n" +"Si esta deshabilitado, se registrará una nueva cuenta automáticamente." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Si se activa, las acciones se graban para poder deshacerse.\n" +"Esta opción sólo se lee al arrancar el servidor." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" +"Si se habilita, deshabilita la prevención de trampas en modo multijugador." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Si se habilita, los datos del mundo inválidos no causarán que el servidor se " +"apague.\n" +"Actívelo solo si sabe lo que hace." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Si está activada, hace que las direcciones de movimiento sean relativas al " +"lanzamiento del jugador cuando vuela o nada." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Si esta activado, los nuevos jugadores no pueden unirse con contraseñas " +"vacías." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Si está habilitado, puede colocar bloques en la posición (pies + nivel de " +"los ojos) donde se encuentra.\n" +"Esto es útil cuando se trabaja con nódulos en áreas pequeñas." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Si la restricción CSM para el rango de nodos está activada, las llamadas a " +"get_node están limitadas\n" +"a esta distancia del jugador al nodo." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Si la ejecución de un comando toma más tiempo del especificado en\n" +"segundos, agrega la información del tiempo al mensaje del comando" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Si el tamaño del archivo debug.txt excede el número de megabytes " +"especificado en\n" +"esta configuración cuando se abre, el archivo se mueve a debug.txt.1,\n" +"borrando un antiguo debug.txt.1 si existe.\n" +"debug.txt sólo se mueve si esta configuración es positiva." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "Si se activa, los jugadores siempre reaparecerán en la posición dada." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ignora los errores del mundo" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Valor alfa del fondo de la consola de chat durante el juego (opacidad, entre " +"0 y 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Color del fondo de la consola de chat durante el juego (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"Altura de la consola de chat en el juego, entre 0.1 (10%) y 1.0 (100%)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Tecla para subir volumen" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Velocidad vertical inicial al saltar, en nodos por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Instrumento incorporado.\n" +"Esto solo suele ser necesario para los colaboradores principales o integrados" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Instrument chat commands on registration." +msgstr "Instrumento de comandos del chat en el registro." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Funciones de devolución de llamada global del instrumento en el registro.\n" +"(Cualquier cosa que pase a una función minetest.register _ * ())" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Instrumenta la función de acción de los Modificadores de Bloque Activos en " +"el registro." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Instrumenta la función de acción de Carga de Modificadores de Bloque en el " +"registro." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Instrumenta los métodos de las entidades en el registro." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Intervalo de guardar cambios importantes en el mundo, expresado en segundos." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Intervalo de envío de la hora del día a los clientes." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animaciones de elementos del inventario" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Tecla Inventario" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Invertir el ratón" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Invertir movimiento vertical del ratón." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Ruta de fuente cursiva" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Ruta de la fuente monoespacial cursiva" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Ítem entidad TTL" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Iteraciones" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Iteraciones de la función recursiva.\n" +"Aumentar esto aumenta la cantidad de detalles finos, pero también\n" +"aumenta la carga de procesamiento.\n" +"En las iteraciones = 20 este mapgen tiene una carga similar al mapgen V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID de Joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Intervalo de repetición del botón del Joystick" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick dead zone" +msgstr "Zona muerta del joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Sensibilidad del Joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Tipo de Joystick" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Sólo conjuntos de Julia.\n" +"El componente W de la constante hipercompleja.\n" +"Altera la forma del fractal.\n" +"No tiene efecto en los fractales 3D.\n" +"Rango aproximadamente entre -2 y 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Sólo conjuntos de Julia: \n" +"El componente X de la constante hipercompleja.\n" +"Altera la forma del fractal.\n" +"Rango aproximadamente de -2 a 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Sólo conjunto de Julia: \n" +"El componente Y de la constante hipercompleja.\n" +"Altera la forma del fractal.\n" +"Rango aproximadamente de -2 a 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Sólo conjunto de Julia:\n" +"Componente Z de la constante hipercompleja.\n" +"Altera la forma del fractal.\n" +"Rango aproximadamente entre -2 y 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Tecla Saltar" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Velocidad de salto" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para disminuir la distancia de visión.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para disminuir el volumen.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para cavar.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para eliminar el elemento seleccionado actualmente.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para aumentar la distancia de visión.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para incrementar el volumen.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para saltar.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para moverse rápido en modo rápido.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para desplazar el jugador hacia atrás.\n" +"Cuando esté activa, También desactivará el desplazamiento automático hacia " +"adelante.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover el jugador hacia delante.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para desplazar el jugador hacia la izquierda.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para desplazar el jugador hacia la derecha.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para silenciar el juego.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir la ventana de chat y escribir comandos.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir la ventana de chat y escribir comandos.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir la ventana de chat.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir la ventana de chat.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para colocar.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 11 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 12 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 13 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el decimocuarto elemento en la barra de acceso " +"directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el decimoquinto elemento en la barra de acceso " +"directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 16 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 17 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 18 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 19 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 20 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 21 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 22 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 23 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 24 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 25 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 26 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 27 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 28 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 29 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 30 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 31 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el elemento 32 en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el octavo elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el quinto elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el primer elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el cuarto elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el siguiente elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el noveno elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el siguiente elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el segundo elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el septimo elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el sexto elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el decimo elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar el tercer elemento en la barra de acceso directo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para agacharse.\n" +"También utilizada para escalar hacia abajo y hundirse en agua si " +"aux1_descends está deshabilitado.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar entre cámar en primera y tercera persona.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para tomar capturas de pantalla.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla activar/desactivar el avance automatico.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar el modo cinemático.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar la vista del minimapa.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar el modo veloz.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar el vuelo.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar el modo noclip.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla activar/desactivar el modo de inclinacion.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar la actualización de la cámara. Solo usada para " +"desarrollo\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar el chat.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar la visualización de información de " +"depuración.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar visualización de niebla.\n" +"Véase http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar la visualización del HUD.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar la consola de chat larga.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar el perfilador. Usado para desarrollo.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para activar/desactivar rango de vista ilimitado.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para hacer zoom cuando sea posible.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" +"Expulsa a los jugadores que enviaron más de X mensajes cada 10 segundos." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Pendiente del lago" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Umbral del lago" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Idioma" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Profundidad de la cueva grande" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Numero máximo de cuevas grandes" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Numero mínimo de cuevas grandes" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Proporción de cuevas grandes inundadas" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Tecla de la consola del chat grande" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Estilo de las hojas" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Estilo de hojas:\n" +"- Fabuloso: Todas las caras son visibles\n" +"- Simple: Solo caras externas, si se utilizan special_tiles definidos\n" +"- Opaco: Transparencia desactivada" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Tecla izquierda" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Duración de un tick del servidor y el intervalo en el que los objetos se " +"actualizan generalmente sobre la\n" +"red." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Longitud de las ondas líquidas.\n" +"Requiere que se habiliten los líquidos ondulados." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" +"Período de tiempo entre ciclos de ejecución de Active Block Modifier (ABM)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Cantidad de tiempo entre ciclos de ejecución de NodeTimer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Periodo de tiempo entre ciclos de gestión de bloques activos" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Nivel de registro que se escribirá en debug.txt:\n" +"- <nada> (sin registro)\n" +"- ninguno (mensajes sin nivel)\n" +"- error\n" +"- advertencia\n" +"- acción\n" +"- información\n" +"- detallado" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Aumento medio del centro de la curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Centro de impulso de curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Dispersión de impulso de curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Gamma de la curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Curva de luz de alto gradiente" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Curva de luz de bajo gradiente" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Iluminación suave" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Límite de la generación de mapa, en nodos, en todas las 6 direcciones desde " +"(0, 0, 0).\n" +"Solo se generan fragmentos de mapa completamente dentro del límite de " +"generación de mapas.\n" +"Los valores se guardan por mundo." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Limita el número de solicitudes HTTP paralelas. Afecta:\n" +"- Recuperación de medios si el servidor utiliza remote_media setting.\n" +"- Descarga de la lista de servidores y anuncio del servidor.\n" +"- Descargas realizadas por el menú principal (por ejemplo, gestor de mods).\n" +"Sólo tiene un efecto si se compila con cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Fluidez líquida" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Suavizado de la fluidez líquida" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Bucle de máximo líquido" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Tiempo de purga de colas de líquidos" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Hundimiento del líquido" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Intervalo de actualización del líquido en segundos." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Tick de actualización de los líquidos" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Cargar el generador de perfiles del juego" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Cargue el generador de perfiles de juego para recopilar datos de generación " +"de perfiles de juegos.\n" +"Proporciona un comando /profiler para tener acceso al perfil compilado.\n" +"Útil para desarrolladores de mods y operadores de servidores." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Carga de modificadores de bloque" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Límite inferior en Y de mazmorras." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Límite inferior Y de las tierras flotantes." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Script del menú principal" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Hace que la niebla y los colores del cielo dependan de la hora del día " +"(amanecer / atardecer) y la dirección de vista." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Vuelve opacos a todos los líquidos" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Nivel de comprensión del mapa para almacenamiento de disco" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Nivel de comprensión del mapa para transferencias por la red" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Directorio de mapas" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Atributos de generación de mapas específicos de Mapgen Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Atributos de generación de mapa específicos para generador de mapas planos.\n" +"Ocasionalmente pueden agregarse lagos y colinas al mundo plano." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Atributos de generación de mapas específicos de Mapgen Fractal.\n" +"'terreno' permite la generación de terrenos no fractales:\n" +"océanos, islas y subterráneo." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Atributos de generación de mapas específicos del generador de mapas " +"Valleys.\n" +"'altitude_chill': Reduce el calor con la altitud.\n" +"'humid_rivers': Aumenta la humedad alrededor de ríos.\n" +"'vary_river_depth': Si está activo, la baja humedad y alto calor causan que\n" +"los ríos sean poco profundos y ocasionalmente secos.\n" +"'altitude_dry': Reduce la humedad con la altitud." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Atributos de generación de mapas específicos al generador de mapas v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Atributos específicos para la generación de Mapgen v6.\n" +"La opción 'snowbiomes' activa el nuevo sistema de generación de 5 biomas.\n" +"Cuando la opción 'snowbiomes' está activada, las junglas se activan " +"automáticamente y\n" +"la opción 'jungles' es ignorada." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Atributos específicos para la generación de Mapgen v7.\n" +"'ridges': Rios.\n" +"'floatlands': Masas de tierra flotantes en la atmósfera.\n" +"'caverns': Cavernas gigantes subterráneo profundo." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Límite de generación de mapa" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Intervalo de guardado de mapa" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map shadows update frames" +msgstr "Tiempo de actualización de mapa" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Limite del Mapblock" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Retraso de generación de la malla del Mapblock" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" +"Tamaño de cache en MB del Mapblock del generador de la malla del Mapblock" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Expirado de descarga de Mapblock" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Generador de mapas carpatiano" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian specific flags" +msgstr "Banderas planas de Mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Generador de mapas plano" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Banderas de generador de mapas plano" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Generador de mapas fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Banderas de generador de mapas fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Generador de mapas V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Banderas de generador de mapas V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Generador de mapas V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Banderas de generador de mapas V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Generador de mapas v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Banderas de generador de mapas V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Generador de mapas Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Banderas de generador de mapas Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Depuración del generador de mapas" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Generador de mapas" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Distancia máxima de generación de bloques" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Distancia máxima de envío de bloques" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Máxima cantidad de líquidos procesada por paso." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Bloques extra máximos de clearobjects" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Máximos paquetes por iteración" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "FPS máximo" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "FPS máximo cuando el juego está pausado." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Distancia máxima para renderizar las sombras." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Máximos bloques cargados a la fuerza" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Anchura máxima de la barra de acceso rápido" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "Límite máximo de grandes cuevas aleatorias por chunk." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" +"Límite máximo de número aleatorio de cavernas pequeñas por pedazo de mapa." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Resistencia de líquidos máxima. Controla la deceleración al entrar en un " +"líquido a:\n" +"alta velocidad." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Número máximo de bloques que se envían simultáneamente por cliente.\n" +"El recuento total máximo se calcula dinámicamente:\n" +"max_total = ceil ((# clients + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" +"Número máximo de bloques que pueden ser añadidos a la cola para cargarse." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Número máximo de bloques para ser añadidos a la cola para ser generados.\n" +"Este límite se cumple por jugador." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Número máximo de bloques para ser añadidos a a cola para cargarse desde un " +"archivo.\n" +"Este límite se cumple por jugador." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Número máximo de descargas simultáneas. Las descargas que sobrepasen este " +"límite se añadirán a la cola.\n" +"Esto debería ser menor que curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Número máximo de bloques de mapa cargados forzosamente." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Número máximo de bloques de mapa para el cliente para ser mantenidos en la " +"memoria.\n" +"Establecer a -1 para cantidad ilimitada." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Número máximo de paquetes enviados por paso de envío. Si tiene una conexión\n" +"lenta, intente reducirlo, pero no lo reduzca a un número menor al doble del\n" +"número de cliente objetivo." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Número máximo de jugadores que se pueden conectar simultáneamente." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Número máximo de mensajes del chat recientes a mostrar" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Número máximo de objetos almacenados estáticamente en un bloque." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Objetos máximos por bloque" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Proporción máxima de la ventana actual a ser usada para la barra de acceso " +"rápido.\n" +"Útil si hay algo para ser mostrado a la derecha o a la izquierda de la barra " +"de acceso rápido." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Envíos de bloque simultáneos máximos por cliente" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Tamaño máximo de la cola de salida del chat" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Tamaño máximo de la cola del chat externo.\n" +"0 para desactivar el añadido a la cola y -1 para hacer el tamaño de la cola " +"ilimitado." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Tiempo máximo que puede tardar la descarga de archivo (p.ej. una descarga de " +"mod) en milisegundos." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Tiempo máximo que puede tardar la solicitud interactiva (p.ej. una búsqueda " +"de lista de servidores) en milisegundos." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Usuarios máximos" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Caché de mallas poligonales" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Mensaje del día" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Mensaje del día mostrado a los jugadores que se conectan." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Método utilizado para resaltar el objeto seleccionado." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Nivel mínimo de logging a ser escrito al chat." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Clave del minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Altura de escaneo del minimapa" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Límite mínimo del número aleatorio de cuevas grandes por mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Límite mínimo del número aleatorio de cavernas pequeñas por mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Tamaño mínimo de textura" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mipmapping" +msgstr "Mapeado de relieve" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Perfilador" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Seguridad" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Modifica el tamaño de los elementos del HUD." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Ruta de fuente monoespaciada" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Tamaño de fuente monoespaciada" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "Tamaño de fuente monoespaciada divisible por" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Ruido de altura de montañas" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Variación del ruido de montaña" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Nivel cero de montañas" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Sensibilidad del ratón" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Multiplicador de sensiblidad del ratón." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Ruido del barro" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Multiplicador del balanceo de caída.\n" +"Por ejemplo: 0 para no ver balanceo; 1.0 para normal; 2.0 para doble." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Tecla de silencio" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Silenciar sonido" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Nombre del generador de mapas que se utilizará al crear un nuevo mundo.\n" +"Crear un mundo en el menú principal anulará esto.\n" +"Los generadores de mapas actuales estan en un estado altamente inestable:\n" +"- …Las floatlands opcionales de la v7 (desactivado por defecto)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Nombre del jugador.\n" +"Cuando se ejecuta un servidor, los clientes que se conecten con este nombre " +"son administradores.\n" +"Al comenzar desde el menú principal, esto se anula." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Nombre del servior, será mostrado cuando los jugadores se unan y en la lista " +"de servidores." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Plano cercano" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Puerto de red a escuchar (UDP).\n" +"Este valor será anulado al iniciar desde el menú principal." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Red" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Los usuarios nuevos deben ingresar esta contraseña." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Resaltar nodos" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Resaltado de los nodos" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Intervalo de cronometro de nodo" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Ruidos" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Número de bloques extra que pueden ser cargados por /clearobjects a la vez.\n" +"Esto es un intercambio entre una sobrecarga de transacciones SQLite y\n" +"consumo de memoria (4096=100MB, como regla general)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Líquidos opacos" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" +"Opacidad (alfa) de la sombra detrás de la fuente predeterminada, entre 0 y " +"255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Abrir el menú de pausa al perder el foco de la ventana. No se pausa si hay " +"un formulario\n" +"abierto." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Anulación opcional del color de un enlace web en el chat." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Ruta de la fuente de respaldo. Debe ser una fuente TrueType.\n" +"Esta fuente será utilizada para ciertos idiomas o si la fuente por defecto " +"no está disponible." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Ruta en la que guardar capturas de pantalla. Puede ser una ruta absoluta o " +"relativa.\n" +"La carpeta será creada si no existe." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Ruta al directorio de los shaders. Si no es especificada, se usará la " +"ubicación por defecto." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" +"Ruta al directorio de texturas. Todas las texturas se buscaran primero desde " +"aquí." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Ruta a la fuente por defecto. Debe ser una fuente TrueType.\n" +"La fuente de respaldo se utilizará si la fuente no se puede cargar." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Ruta a la fuente monoespaciada. Debe ser una fuente TrueType.\n" +"Este fuente es usada, por ejemplo, para la consola y la pantalla del " +"perfilador." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Pausar cuando se pierda el foco de la ventana" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "Límite por jugador de bloques en cola que se cargan desde el disco" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Límite por jugador de bloques en espera para generar" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Físicas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move key" +msgstr "Tecla vuelo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move mode" +msgstr "Modo de movimiento de inclinación activado" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Tecla Colocar" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Intervalo de repetición para colocar" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"El jugador es capaz de volar sin ser afectado por la gravedad.\n" +"Esto requiere el privilegio \"fly\" en el servidor." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Distancia de transferencia del jugador" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Jugador contra jugador" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Filtrado bilineal" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Puerto de conectarse (UDP).\n" +"Nota que el campo de puerto en el menú principal anula esta configuración." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Evite que cavar y colocar se repita cuando mantenga presionados los botones " +"del ratón.\n" +"Habilite esto cuando excave o coloque con demasiada frecuencia por accidente." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "Evitar que mods hagan cosas inseguras como ejecutar comandos de shell." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Imprima los datos de perfilado del motor en intervalos regulares (en " +"segundos).\n" +"0 = desactivar. Útil para desarrolladores." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Privilegios que los jugadores con privilegios basicos pueden otorgar" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Perfilador" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Tecla para alternar perfiles" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Proporción de cuevas grandes que contienen líquido." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Radio del área de nube indicado en número de 64 nodos cuadrados de nube.\n" +"Los valores mayores de 26 comenzarán a producir cortes agudos en las " +"esquinas del área de nubes." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Levanta terreno para hacer valles alrededor de los ríos." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Entrada aleatoria" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Tecla seleccionar rango de visión" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Mensajes Recientes del Chat" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Ruta de fuente regular" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Medios remotos" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Puerto remoto" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Eliminar códigos de color de los mensajes de chat entrantes\n" +"Use esto para evitar que los jugadores puedan usar color en sus mensajes" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Sustituye el menú principal por defecto con uno personalizado." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Report path" +msgstr "Ruta de fuentes" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Restringe el acceso de ciertas funciones del lado del cliente en los " +"servidores.\n" +"Combine los byteflags a continuación para restringir las características del " +"lado del cliente, o establezca en 0\n" +"para no tener restricciones:\n" +"LOAD_CLIENT_MODS: 1 (desactivar la carga de mods proporcionados por el " +"cliente)\n" +"CHAT_MESSAGES: 2 (desactivar la llamada send_chat_message del lado del " +"cliente)\n" +"READ_ITEMDEFS: 4 (deshabilitar la llamada get_item_def del lado del " +"cliente)\n" +"READ_NODEDEFS: 8 (deshabilitar la llamada get_node_def del lado del " +"cliente)\n" +"LOOKUP_NODES_LIMIT: 16 (limita la llamada get_node del lado del cliente a\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (desactivar la llamada get_player_names del lado del " +"cliente)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Ruido de las crestas marinas" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Tecla derecha" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River channel depth" +msgstr "Profundidad del relleno" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Ancho de canal de río" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Profundidad de río" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Ruido de río" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Tamaño del río" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Anchura de los valles con ríos" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Minimapa redondo" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Las playas de arena se producen cuando np_beach supera este valor." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Guardar el mapa recibido por el cliente en el disco." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Guardar el tamaño de la ventana automáticamente cuando se modifique." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Guardando el mapa recibido del servidor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Escala la interfaz por un valor epecificado por el usuario.\n" +"Utilice el filtro anti-alias mas cercano para escalar la interfaz.\n" +"Esto suavizará algunos de los bordes ásperos y mezclará\n" +"píxeles al reducir el tamaño, a costa de difuminar algunos\n" +"píxeles en los bordes cuando las imágenes son escaladas por tamaños que no " +"sean números enteros" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Pantalla:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Altura de la pantalla" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Ancho de la pantalla" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Carpeta de captura de pantalla" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Formato de captura de pantalla" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Calidad de captura de pantalla" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Calidad de captura de pantalla. Solo se utiliza para el formato JPEG.\n" +"1 significa la peor calidad; 100 significa la mejor calidad.\n" +"Utilice 0 para la calidad predeterminada." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Captura de pantalla" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Ruido del lecho marino" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Segundo de 4 ruidos 2D que juntos definen la altura de la colina/cordillera." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Segundo de 2 ruidos 3D que juntos definen túneles." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Ver https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Color del borde del cuadro de selección (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Color del cuadro de selección" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Ancho de la caja de selección" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Elección de 18 fractales desde 9 fórmulas.\n" +"1 = Conjunto de Mandelbrot 4D \"Redondo\".\n" +"2 = Conjunto de Julia 4D \"Redondo\".\n" +"3 = Conjunto de Mandelbrot 4D \"Cuadrado\".\n" +"4 = Conjunto de Julia 4D \"Cuadrado\".\n" +"5 = Conjunto de Mandelbrot 4D \"Mandy Cousin\".\n" +"6 = Conjunto de Julia 4D \"Mandy Cousin\".\n" +"7 = Conjunto de Mandelbrot 4D \"Variado\".\n" +"8 = Conjunto de Julia 4D \"Variado\".\n" +"9 = Conjunto de Mandelbrot 3D \"Mandelbrot/Mandelbar\".\n" +"10 = Conjunto de Julia 3D \"Mandelbrot/Mandelbar\".\n" +"11 = Conjunto de Mandelbrot 3D \"Árbol de Navidad\".\n" +"12 = Conjunto de Julia 3D \"Árbol de Navidad\".\n" +"13 = Conjunto de Mandelbrot 3D \"Mandelbulb\".\n" +"14 = Conjunto de Julia 3D \"Mandelbulb\".\n" +"15 = Conjunto de Mandelbrot 3D \"Mandelbulb Coseno\".\n" +"16 = Conjunto de Julia 3D \"Mandelbulb Coseno\".\n" +"17 = Conjunto de Mandelbrot 4D \"Mandelbulb\".\n" +"18 = Conjunto de Julia 4D \"Mandelbulb\"." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL del servidor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Nombre del servidor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Descripción del servidor" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL del servidor" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Dirección del servidor" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Descripción del servidor" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Nombre del servidor" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Puerto del servidor" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Puerto del servidor" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "Lista de las URLs de servidores" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "Lista de las URLs de servidores" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Archivo de la lista de servidores" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Seleccionar el idioma. Dejar vacío para usar el idioma del sistema.\n" +"Se requiere reiniciar para cambiar esto." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Establecer la longitud máxima de caracteres de un mensaje de chat enviado " +"por los clientes." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Establecer la fuerza de la sombra.\n" +"Un valor menor significa sombras más claras, un valor mayor valor significa " +"sombras más oscuras." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Establecer el tamaño del radio de las sombras suaves.\n" +"Los valores más bajos significan sombras más nítidas, los valores más altos " +"significan sombras más suaves.\n" +"Valor mínimo: 1.0; valor máximo: 10.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Establecer la inclinación de la órbita del Sol/Luna en grados.\n" +"El valor 0 significa que no hay inclinación / órbita vertical.\n" +"Valor mínimo: 0.0; valor máximo: 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Establecer en verdero para habilitar el mapeo de sombras.\n" +"Requiere que los sombreadores estén habilitados." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Habilita mapeado de oclusión de paralaje.\n" +"Requiere habilitar sombreadores." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Habilita mapeado de oclusión de paralaje.\n" +"Requiere habilitar sombreadores." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Habilita mapeado de oclusión de paralaje.\n" +"Requiere habilitar sombreadores." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Ruta de sombreador" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Los sombreadores permiten efectos visuales avanzados y pueden aumentar el " +"rendimiento en algunas tarjetas de\n" +"vídeo.\n" +"Esto solo funciona con el motor de vídeo OpenGL." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "Calidad de captura de pantalla" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "Compensado de sombra de fuente, si es 0 no se dibujará la sombra." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "Intensidad de sombra" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Forma del minimapa. Habilitado = redodondo, deshabilitado = cuadrado." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Mostrar la informacion de la depuración" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Show name tag backgrounds by default" +msgstr "Fuente en negrita por defecto" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Iluminación suave" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Suaviza la cámara al mirar alrededor. También se llama suavizado de mirada o " +"ratón.\n" +"Útil para grabar vídeos." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"Suaviza la rotación de la cámara en modo cinematográfico. 0 para desactivar." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Suaviza la rotación de la cámara. 0 para desactivar." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Tecla sigilo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed" +msgstr "Velocidad del caminar" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Velocidad agachado, en nodos por segundo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Alfa de sombra de la fuente" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Sonido" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Especifica el tamaño por defecto de los stacks (Montónes) de nodos, items y " +"bloques.\n" +"Cabe aclarar que los mods o juegos pueden establecer un stack para algunos " +"items (o todos)." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Punto de aparición estático" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "La fuerza del paralaje del modo 3D." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Variación de temperatura de los biomas." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Ajustes" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Ruido alternativo de terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Ruido base del terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Altura del terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Ruido del terreno" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Umbral de ruido del terreno para las colinas.\n" +"Controla la proporción del mundo cubierta por colinas.\n" +"Ajústalo hacia 0.0 para una mayor proporción." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Umbral de ruido del terreno para los lagos.\n" +"Controla la proporción del mundo cubierta por lagos.\n" +"Ajústalo hacia 0.0 para una mayor proporción." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Ruta de la textura" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "La URL para el repositorio de contenido" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "La zona muerta del joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "La profundidad de la tierra u otros nodos de relleno de biomas." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"El tiempo en segundos entre la colocación de cada nodo mientras\n" +"se mantiene pulsado el botón para colocar." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "El tipo de joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "Primero de 2 ruidos 3D que juntos definen túneles." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Velocidad del tiempo" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Tecla para cambiar el modo de cámara" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touch screen threshold" +msgstr "Límite de ruido de playa" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Límite de ruido de playa" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Ruido de árboles" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Filtrado trilineal" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"Habilitado = 256\n" +"Deshabilitado= 128\n" +"Sirve para suavizar el minimapa en dispositivos mas lentos." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL a la lista de servidores mostrada en la pestaña de Multijugador." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Renderizado" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Límite superior Y de las tierras flotantes." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Usar nubes 3D en lugar de planas." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Usar nubes con animaciones para el fondo del menú principal." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Usar filtrado bilinear al escalar texturas." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Usa el antialiasing multimuestra (MSAA) para suavizar los bordes de los " +"bloques.\n" +"Este algoritmo suaviza la vizualización 3D mientras que la imagen sigue " +"nítida,\n" +"pero esto no afecta el interior de las texturas\n" +"(lo que es especialmente visible con texturas transparentes).\n" +"Aparecen espacios visibles cuando los sombreadores estan deshabilitados.\n" +"Si se establece en 0, se desactiva MSAA.\n" +"Se requiere un reinicio después de cambiar esta opción." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Usar filtrado trilinear al escalar texturas." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "VSync" +msgstr "VSync (Sincronización vertical)" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Profundidad del valle" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Variación de la altura maxima de las montañas (En nodos)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Varies steepness of cliffs." +msgstr "Controla lo escarpado/alto de las colinas." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Velocidad de escalado vertical, en nodos por segundo." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Sincronización vertical de la pantalla." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Distancia de visión en nodos." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Tecla para disminuir el rango de visión" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Tecla para aumentar el rango de visión" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Volumen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Habilita mapeado de oclusión de paralaje.\n" +"Requiere habilitar sombreadores." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Velocidad al caminar y volar, en nodos por segundo." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Velocidad del caminar" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Nivel del agua" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Movimiento de nodos" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Movimiento de hojas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Movimiento de Líquidos" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Altura de las ondulaciones del agua" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Velocidad del oleaje en el agua" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Oleaje en el agua" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Movimiento de plantas" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "Componente de altura del tamaño inicial de la ventana." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Solo para sistemas Windows: Iniciar Minetest con la ventana de la linea de " +"comandos en el fondo.\n" +"Contiene la misma información que el archivo debug.txt (Nombre por defecto)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Tiempo comienzo mundo" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y de suelo plano." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "\"Y\" del límite superior de las grandes cuevas." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Nivel Y del límite superior de las cavernas." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Nivel Y del terreno bajo y el fondo marino." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Nivel Y del fondo marino." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "cURL" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Tiempo de espera de descarga por cURL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "Tiempo de espera de cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Límite de cURL en paralelo" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Modo creativo: " + +#~ msgid "- Damage: " +#~ msgstr "- Daño: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = oclusión de paralaje con información de inclinación (más rápido).\n" +#~ "1 = mapa de relieve (más lento, más preciso)." + +#~ msgid "Address / Port" +#~ msgstr "Dirección / puerto" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Ajustar la codificación gamma para las tablas de iluminación. Números " +#~ "mayores son mas brillantes.\n" +#~ "Este ajuste es solo para cliente y es ignorado por el servidor." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "" +#~ "Modifica cómo las tierras flotantes del tipo montaña aparecen arriba y " +#~ "abajo del punto medio." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "¿Estás seguro de querer reiniciar el mundo de un jugador?" + +#~ msgid "Back" +#~ msgstr "Atrás" + +#~ msgid "Basic" +#~ msgstr "Básico" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "" +#~ "Bits por píxel (también conocido como profundidad de color) en modo de " +#~ "pantalla completa." + +#~ msgid "Bump Mapping" +#~ msgstr "Mapeado de relieve" + +#~ msgid "Bumpmapping" +#~ msgstr "Mapeado de relieve" + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Cambia la UI del menú principal:\n" +#~ "- Completo: Múltiples mundos, elección de juegos y texturas, etc.\n" +#~ "- Simple: Un solo mundo, sin elección de juegos o texturas.\n" +#~ "Puede ser necesario en pantallas pequeñas." + +#~ msgid "Config mods" +#~ msgstr "Configurar mods" + +#~ msgid "Configure" +#~ msgstr "Configurar" + +#~ msgid "Connect" +#~ msgstr "Conectar" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Controla la velocidad de hundimiento en líquidos." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Controla la densidad del terreno montañoso flotante.\n" +#~ "Se agrega un desplazamiento al valor de ruido 'mgv7_np_mountain'." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Controla el ancho de los túneles, un valor menor crea túneles más anchos." + +#~ msgid "Credits" +#~ msgstr "Créditos" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Color de la cruz (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Daño activado" + +#, fuzzy +#~ msgid "Darkness sharpness" +#~ msgstr "Agudeza de la obscuridad" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Tiempo de espera predeterminado para cURL, en milisegundos.\n" +#~ "Sólo tiene efecto si está compilado con cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Define áreas de terreno liso flotante.\n" +#~ "Las zonas flotantes lisas se producen cuando el ruido > 0." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Define el intervalo de muestreo de las texturas.\n" +#~ "Un valor más alto causa mapas de relieve más suaves." + +#~ msgid "Del. Favorite" +#~ msgstr "Borrar Fav." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Descarga un subjuego, como minetest_game, desde minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Descarga uno desde minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Descargando e instalando $1, por favor espere..." + +#~ msgid "Enable VBO" +#~ msgstr "Activar VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "Habilitar confirmación de registro" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Habilita mapeado de relieves para las texturas. El mapeado de normales " +#~ "necesita ser\n" +#~ "suministrados por el paquete de texturas, o será generado " +#~ "automaticamente.\n" +#~ "Requiere habilitar sombreadores." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Habilita el mapeado de tonos fílmico" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Habilita la generación de mapas de normales (efecto realzado) en el " +#~ "momento.\n" +#~ "Requiere habilitar mapeado de relieve." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Habilita mapeado de oclusión de paralaje.\n" +#~ "Requiere habilitar sombreadores." + +#~ msgid "Enter " +#~ msgstr "Ingresar " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Opción experimental, puede causar espacios visibles entre los\n" +#~ "bloques si se le da un valor mayor a 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS (cuadros/s) en el menú de pausa" + +#~ msgid "Fallback font shadow" +#~ msgstr "Sombra de la fuente de reserva" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Alfa de la sombra de la fuente de reserva" + +#~ msgid "Fallback font size" +#~ msgstr "Tamaño de la fuente de reserva" + +#~ msgid "Filtering" +#~ msgstr "Filtrado" + +#~ msgid "Floatland base height noise" +#~ msgstr "Ruido de altura base para tierra flotante" + +#~ msgid "Floatland mountain height" +#~ msgstr "Altura de las montañas en tierras flotantes" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Alfa de sombra de fuentes (opacidad, entre 0 y 255)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Tamaño de la fuente de reserva en punto (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "Fuentes FreeType" + +#~ msgid "Full screen BPP" +#~ msgstr "Profundidad de color en pantalla completa" + +#~ msgid "Game" +#~ msgstr "Juego" + +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Generar mapas normales" + +#~ msgid "Generate normalmaps" +#~ msgstr "Generar mapas normales" + +#~ msgid "HUD scale factor" +#~ msgstr "Factor de escala HUD" + +#~ msgid "High-precision FPU" +#~ msgstr "Alta-precisión FPU" + +#~ msgid "IPv6 support." +#~ msgstr "soporte IPv6." + +#~ msgid "In-Game" +#~ msgstr "Dentro del juego" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Instalar: Archivo: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Instrumentación" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Combinaciones de teclas. (Si este menú da error, elimina líneas en " +#~ "minetest.conf)" + +#, fuzzy +#~ msgid "Lava depth" +#~ msgstr "Características de la Lava" + +#~ msgid "Main" +#~ msgstr "Principal" + +#~ msgid "Main menu style" +#~ msgstr "Estilo del menú principal" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "Hace que DirectX funcione con LuaJIT. Desactivar si ocasiona problemas." + +#~ msgid "Menus" +#~ msgstr "Menús" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Minimapa en modo radar, Zoom x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Minimapa en modo radar, Zoom x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Minimapa en modo superficie, Zoom x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Minimapa en modo superficie, Zoom x4" + +#~ msgid "Name / Password" +#~ msgstr "Nombre / contraseña" + +#~ msgid "Name/Password" +#~ msgstr "Nombre / contraseña" + +#~ msgid "No" +#~ msgstr "No" + +#~ msgid "Ok" +#~ msgstr "Aceptar" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Oclusión de paralaje" + +#, fuzzy +#~ msgid "Parallax occlusion" +#~ msgstr "Oclusión de paralaje" + +#, fuzzy +#~ msgid "Parallax occlusion bias" +#~ msgstr "Oclusión de paralaje" + +#, fuzzy +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Oclusión de paralaje" + +#, fuzzy +#~ msgid "Parallax occlusion mode" +#~ msgstr "Oclusión de paralaje" + +#, fuzzy +#~ msgid "Parallax occlusion scale" +#~ msgstr "Oclusión de paralaje" + +#~ msgid "Path to save screenshots at." +#~ msgstr "Ruta para guardar las capturas de pantalla." + +#~ msgid "Player name" +#~ msgstr "Nombre del jugador" + +#~ msgid "Profiling" +#~ msgstr "Perfilando" + +#~ msgid "PvP enabled" +#~ msgstr "PvP activado" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Reiniciar mundo de un jugador" + +#~ msgid "Select Package File:" +#~ msgstr "Seleccionar el archivo del paquete:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Servidor / Un jugador" + +#, fuzzy +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "Compensado de sombra de fuente, si es 0 no se dibujará la sombra." + +#~ msgid "Special" +#~ msgstr "Especial" + +#~ msgid "Special key" +#~ msgstr "Tecla especial" + +#~ msgid "Start Singleplayer" +#~ msgstr "Comenzar un jugador" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Fuerza de los mapas normales generados." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "" +#~ "Para habilitar los sombreadores debe utilizar el controlador OpenGL." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Activar cinemático" + +#~ msgid "View" +#~ msgstr "Ver" + +#~ msgid "Waving Water" +#~ msgstr "Oleaje" + +#~ msgid "Waving water" +#~ msgstr "Oleaje en el agua" + +#~ msgid "Yes" +#~ msgstr "Sí" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Te vas unir al servidor con el nombre \"%s\" por primera vez.\n" +#~ "Cuando procedas, se creará una nueva cuenta en este servidor usando tus " +#~ "credenciales.\n" +#~ "Por favor, reescribe tu contraseña y haz clic en 'Registrarse y unirse' " +#~ "para confirmar la creación de la cuenta, o haz clic en 'Cancelar' para " +#~ "abortar." + +#~ msgid "You died." +#~ msgstr "Has muerto." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/et/minetest.po b/po/et/minetest.po new file mode 100644 index 0000000..150005f --- /dev/null +++ b/po/et/minetest.po @@ -0,0 +1,7096 @@ +msgid "" +msgstr "" +"Project-Id-Version: Estonian (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2021-06-29 10:33+0000\n" +"Last-Translator: Janar Leas <janarleas+ubuntuone@googlemail.com>\n" +"Language-Team: Estonian <https://hosted.weblate.org/projects/minetest/" +"minetest/et/>\n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.7.1-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Tühi käsk." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Välju menüüsse" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Väär käsk: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Anti käsklus: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Võrgus mängijate loend" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Mängijaid võrgus: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Võõrustaja piiras selle käsu kasutuse." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Ärka ellu" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Said surma" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Võimalikud käsud:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Võimalikud käsud: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Käsk pole saadaval: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Leia abi käskude kohta" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "'.help <käsk>' jagab rohkem teadmisi, ning '.help all' loetleb kõik." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <käsk>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Valmis" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "<none available>" +msgstr "Käsk pole saadaval: " + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Lua skriptis ilmnes viga:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Ilmnes viga:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Peamenüü" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Taasühenda" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Server taotles taasühendumist:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Vali mod" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protokolli versioon ei sobi. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Server jõustab protokolli versiooni $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Server toetab protokolli versioone $1 kuni $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Meie toetame ainult protokolli versiooni $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Meie toetame protokolli versioone $1 kuni $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Tühista" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Sõltuvused:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Keela kõik" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Keela MOD-i pakk" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Luba kõik" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Luba MOD-i pakk" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"MOD-i \"$1\" kasutamine nurjus, kuna sisaldab keelatud sümboleid. Lubatud on " +"ainult [a-z0-9_] märgid." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Leia rohkem MODe" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "(Valikulised) sõltuvused puuduvad" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Mängule pole kirjeldust saadaval." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Vajalikud sõltuvused puuduvad" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "MOD-i pakile pole kirjeldust saadaval." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Valikulised sõltuvused puuduvad" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Valikulised sõltuvused:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Salvesta" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Maailm:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "Sisse lülitatud" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" on juba olemas. Kas sa tahad seda üle kirjutada?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Paigaldatakse sõltuvused $1 ja $2." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 $2 poolt" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 allalaadimisel,\n" +"$2 ootel" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 allalaadimine..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 vajaliku sõltuvust polnud leida." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "Installitakse $1 ja $2 sõltuvus jäetakse vahele." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Kõik pakid" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Juba installeeritud" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Tagasi peamenüüsse" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Põhi Mäng:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB ei ole olemas kui Minetest on kompileeritud ilma cURL'ita" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Allalaadimine..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "$1 allalaadimine nurjus" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Mängud" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Paigalda" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Paigalda $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Paigalda puuduvad sõltuvused" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "Paigaldus: Toetamata failitüüp \"$1\" või katkine arhiiv" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "MOD-id" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Ei õnnestunud ühtki pakki vastu võtta" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Tulemused puuduvad" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Värskendusi pole" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Ei leitud" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Ümber kirjuta" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Palun tee kindlaks et põhi mäng on õige." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Ootel" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Tekstuuri pakid" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Eemalda" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Uuenda" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Uuenda kõiki [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Vaata rohkem infot veebibrauseris" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Maailm nimega \"$1\" on juba olemas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Täiendav maastik" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Külmetus kõrgus" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Põua kõrgus" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Loodusvööndi hajumine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Loodusvööndid" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Koopasaalid" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Koopad" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Loo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Ilmestused" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Hoiatus: \"Arendustest\" on mõeldud arendajatele." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Keldrid" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Lame maastik" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Taevas hõljuvad saared" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Lendsaared (katseline)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Mitte-fraktaalse maastiku tekitamine: mered ja süvapinnas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Künkad" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Rõsked jõed" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Suurendab niiskust jõe lähistel" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Paigalda $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Järved" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Madal niiskus ja suur kuum põhjustavad madala või kuiva jõesängi" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Kaardi generaator" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Kaartiloome lipud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Kaartiloome-põhised lipud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Mäed" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Muda voog" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Käikude ja koobaste võrgustik" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Mäng valimata" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Ilma jahenemine kõrgemal" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Ilma kuivenemine kõrgemal" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Jõed" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Jõed merekõrgusel" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Külv" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Sujuv loodusvööndi vaheldumine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Rajatised ilmuvad maastikul (v6 tekitatud puudele ja tihniku rohule mõju ei " +"avaldu)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Struktuurid ilmuvad maastikul, enamasti puud ja teised taimed" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Rohtla, Lagendik" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Rohtla, Lagendik, Tihnik" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Rohtla, Lagendik, Tihnik, Tundra, Laas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Maapinna kulumine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Puud ja tihniku rohi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Muutlik jõe sügavus" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Väga suured koopasaalid maapõue sügavuses" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Maailma nimi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Sul pole ühtki mängu paigaldatud." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Kindlasti kustutad „$1“?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Kustuta" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "PakiHaldur: Nurjus „$1“ kustutamine" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "PakiHaldur: väär asukoht „$1“" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Kustutad maailma \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Kinnita parooli" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Maailma tekitus-valemi nimi" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nimi" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Salasõna" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Paroolid ei ole samad!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Registreeru ja liitu" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Nõustu" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Taasnimeta MOD-i pakk:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Selle MOD-i pakk nimi on määratud oma „modpack.conf“ failid, mis asendab " +"siinse ümber nimetamise." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Kirjeldus seadistusele puudub)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "kahemõõtmeline müra" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Tagasi lehele „Seaded“" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Sirvi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Sisu" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Sisu" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Keelatud" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Muuda" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Lubatud" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Pinna auklikus" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktavid" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Nihe" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Püsivus" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Palun sisesta korrektne täisarv." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Palun sisesta korrektne arv." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Taasta vaikeväärtus" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Ulatus" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Otsi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Vali kataloog" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Vali fail" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Kuva tehnilised nimetused" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Väärtus peab olema vähemalt $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Väärtus ei tohi olla suurem kui $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X levi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y levi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z levi" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "täisväärtus" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "algne" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "pehmendatud" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Lubatud)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mod-i" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "$1 paigaldamine $2 nurjus" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Paigalda mod: Tegeliku nime leidmine ebaõnnestus mod-ile: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Paigalda mod: Sobiva katalooginime leidmine ebaõnnestus mod-komplektile $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Ei leitud sobivat mod-i ega mod-komplekti" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "$1 paigaldamine tekstuurikomplektiks nurjus" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Mängu nimega $1 paigaldamine nurjus" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Mod nimega $1 paigaldamine nurjus" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Mod-komplekt nimega $1 paigaldamine nurjus" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Laadimine..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Avalike serverite loend on keelatud" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Proovi lubada uuesti avalike serverite loend ja kontrolli oma Interneti " +"ühendust." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Teavet" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Tegevad panustajad" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Põhi arendajad" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Avalik Kasutaja Andmete Kaust" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Kasutaja poolsete maailmate, mängude, mod-de ning tekstuuri pakide\n" +"kausta avamine faili-halduris." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Eelnevad panustajad" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Eelnevad põhi-arendajad" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Sirvi veebist sisu" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Sisu" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Keela tekstuurikomplekt" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Teave:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Paigaldatud paketid:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Sõltuvused puuduvad." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Paketil puudub kirjeldus" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Nimeta ümber" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Eemalda pakett" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Vali tekstuurikomplekt" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Võõrustamise kuulutamine" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Seo aadress" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Looja" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Ellujääja" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Võõrusta" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Majuta külastajatele" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Lisa mänge sisuvaramust" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Uus" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Pole valitud ega loodud ühtegi maailma!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Mängi" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Vali mod" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Vali maailm:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Võõrustaja kanal" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Alusta mängu" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Aadress" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Tühjenda" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Looja" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Vigastused mängijatelt" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Lemmikud" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Ühildumatud Võõrustajad" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Ühine" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Viivitus" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Avalikud võõrustajad" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Värskenda" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Pole lemmik" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Võõrustaja kirjeldus" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Ruumilised pilved" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Kõik sätted" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Silu servad:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Mäleta ekraani suurust" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bi-lineaarne filtreerimine" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Vaheta klahve" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Ühendatud klaas" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Elavad varjud" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Elavad varjud: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Uhked lehed" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Kõrge" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Madal" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Keskmine" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "KaugVaatEsemeKaart" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Filtrita" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Mipmapita" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Valitud klotsi ilme" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Klotsi servad" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Puudub" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Läbipaistmatud lehed" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Läbipaistmatu vesi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Osakesed" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Ekraan:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Sätted" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Varjutajad" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shaderid (katselised)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Varjutajad (pole saadaval)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Lihtsad lehed" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Sujuv valgustus" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Tekstureerimine:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Tooni kaardistamine" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Puutelävi: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Tri-lineaar filtreerimine" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Ülikõrge" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Vägamadal" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Lehvivad lehed" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Lainetavad vedelikud" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Lehvivad taimed" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Ühenduse viga (Aeg otsas?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Ühendus aegus." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Valmis!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Klotsidega täitmine" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Klotsidega täitmine..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Tekstuuride laadimine ..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Varjutajate taasloomine..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Ühenduse viga (Aeg otsas?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "Ei leia ega suuda jätkata mängu \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Vale mängu ID." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menüü" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Pole valitud ei maailma ega IP aadressi. Pole midagi teha." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Mängija nimi on liiga pikk." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Palun vali nimi!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Salasõnafaili avamine ebaõnnestus: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Maailma failiteed pole olemas: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Vaata debug.txt info jaoks." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Aadress: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Režiim: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Avalik: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- Üksteise vastu: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Serveri nimi: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Ilmnes viga:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Automaatne edastus keelatud" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Automaatne edastus lubatud" + +#: src/client/game.cpp +#, fuzzy +msgid "Block bounds hidden" +msgstr "Klotsi piirid" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Kaamera värskendamine on keelatud" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Kaamera värskendamine on lubatud" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Vaheta parooli" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Filmirežiim on keelatud" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Filmirežiim on lubatud" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Kliendipoolne skriptimine on keelatud" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Serveriga ühenduse loomine..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Jätka" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Klahvid:\n" +"- %s: liigu edasi\n" +"- %s: liigu tagasi\n" +"- %s: liigu vasakule\n" +"- %s: liigu paremale\n" +"- %s: hüppa/roni\n" +"- %s: kaeva/viruta\n" +"- %s: paigalda/kasuta\n" +"- %s: hiili/mine alla\n" +"- %s: viska ese\n" +"- %s: seljakott\n" +"- Hiir: keera/vaata\n" +"- Hiireratas: vali ese\n" +"- %s: vestlus\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Kliendi loomine..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Serveri loomine..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Siluri info ja profiileri graafik peidetud" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Silumisteave kuvatud" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Siluri info, profiileri graafik ja sõrestik peidetud" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Vaikimisi juhtimine:\n" +"Menüü pole nähtav:\n" +"- toksa: nupu käitamine\n" +"- kaksiktoksa: aseta/kasuta\n" +"- libista näpuga: vaata ringi\n" +"Menüü/varamu nähtav:\n" +"- kaksiktoksa (välja):\n" +" -->sulgeb\n" +"- puutu vihku, puutu pesa:\n" +" --> teisaldab vihu\n" +"- puutu&lohista, toksa 2-se näpuga\n" +" --> asetab ühe eseme pessa\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Piiramatu vaatamisulatus keelatud" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Piiramatu vaatamisulatus lubatud" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Kliendi loomine..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Välju menüüsse" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Välju mängust" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Kiirrežiim on keelatud" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Kiirrežiim on lubatud" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Kiirrežiim on lubatud (hoiatus: 'fast' privileeg puudub)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Lennurežiim on keelatud" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Lennurežiim lubatud" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Lennurežiim lubatud (hoiatus: 'fly' privileeg puudub)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Udu keelatud" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Udu lubatud" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Mängu teave:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Mäng pausil" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Majutan serverit" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Esemete määratlused..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Meedia..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Pisikaardi keelab hetkel mäng või MOD" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Hulgimängija" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Haakumatus keelatud" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Nakkumatus lubatud" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Haakumatus lubatud (pole 'haakumatus' volitust)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Klotsi määratlused..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Väljas" + +#: src/client/game.cpp +msgid "On" +msgstr "Sees" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Koormushinnangu kuvamine" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Kaug võõrustaja" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Aadressi lahendamine..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Sulgemine..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Üksikmäng" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Hääle volüüm" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Heli vaigistatud" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Heli süsteem on keelatud" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "See kooste ei toeta heli süsteemi" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Heli taastatud" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Vaate kaugus on nüüd: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Vaate kaugus on suurim võimalik: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Vaate kaugus on vähim võimalik: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Helitugevus muutus %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Raamvõrgustiku paljastus" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Suumimine on praegu mängu või modi tõttu keelatud" + +#: src/client/game.cpp +msgid "ok" +msgstr "sobib" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Vestlus peidetud" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Vestluse näitamine" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "Liidese peitmine" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "Liidese näitamine" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Koormushindaja peitmine" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Koormushinnang (%d leht %d-st)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplikatsioonid" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Tagasinihe" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Suurtähelukk" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "CTRL" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Alla" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Lõpeta" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Kustuta EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Soorita" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Abi" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Kodu" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Sisendviisiga nõustumine" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Sisendviisi teisendamine" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "Sisendviisi paoklahv" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Sisendviisi laadi vahetus" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "Sisendviisi mitte-teisendada" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Sisesta" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Vasakule" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Vasak nupp" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Vasak CTRL" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Vasak Menüü" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Vasak Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Vasak Windowsi nupp" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menüü" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Keskmine nupp" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Numbrilaual Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numbrilaual *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numbrilaual +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numbrilaual -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numbrilaual ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numbrilaual /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numbrilaual 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numbrilaual 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numbrilaual 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numbrilaual 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numbrilaual 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numbrilaual 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numbrilaual 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numbrilaual 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numbrilaual 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numbrilaual 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Tühi" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Lehekülg alla" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Lehekülg üles" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Paus" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Mängi" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Prindi" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Paremale" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Parem nupp" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Parem CTRL" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Parem Menüü" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Parem Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Parem Windowsi nupp" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll lukk" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Vali" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift," + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Maga" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Mängupilt" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Tühik" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Reavahetus" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Üles" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Nuppp 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Nupp 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Suumi" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Pisikaart peidetud" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Radarkaart, Suurendus ×%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Pinnakaart, Suurendus ×%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Pisikaart tekstuur-laadis" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "$1 allalaadimine nurjus" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Jätka" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = roni alla" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Iseastuja" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Automaatne hüppamine" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Tagasi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Klotsi piirid" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Muuda kaamerat" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Jututuba" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Käsklus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsool" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Vähenda ulatust" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Vähenda valjust" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Topeltklõpsa \"Hüppamist\" et sisse lülitada lendamine" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Viska maha" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Edasi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Suurenda ulatust" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Helitugevus üles" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Seljakott" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Hüppamine" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Nupp juba kasutuses" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Kohalik käsk" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Vaigista" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Järgmine üksus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Eelmine asi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Kauguse valik" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Kuvatõmmis" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Hiilimine" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Lülita HUD sisse/välja" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Lülita vestluslogi sisse/välja" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Lülita kiirus sisse" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Lülita lendamine sisse" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Lülita udu sisse/välja" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Lülita minikaart sisse/välja" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Lülita läbi seinte minek sisse" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Lülita pitchmove sisse/välja" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "Vajuta nuppu" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Muuda" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Uus parool" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Vana parool" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Paroolid ei ole samad!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Välju" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Vaigistatud" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Hääle Volüüm: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "et" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Palun vali nimi!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Parendab virtuaalse juhtkangi asukohta.\n" +"Kui keelatud, siis juhtkangi kese asub esmapuute kohal." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Virtuaal-juhtkangi kasutamine \"Aux1\" nupu päästmiseks.\n" +"Kui lubatud, juhtkang päästab ka \"Aux1\" nupu kui läheb väljapoole pearingi." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Kahemõõtmeline müra mis määrab seljandike kuju/suuruse." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Kahemõõtmeline müra mis määrab vooremaa kuju/suuruse." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Kahemõõtmeline müra mis määrab astmikkõrgustike kuju/suuruse." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "Kahemõõtmeline müra mis määrab seljandike ala suuruse/ilmingu." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "Kahemõõtmeline müra mis määrab vooremaa ala suuruse/ilmingu." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "Kahemõõtmeline müra mis määrab astmikkõrgendike ala suuruse/ilmingu." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Kahemõõtmeline müra mis paigutab jõeorud ja kanalid." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D pilved" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D-režiim" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Üüratuid koopasaale määratlev kolmemõõtmeline müra." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Kanjonjõe järsakkaldaid määratlev kolmemõõtmeline müra." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Maastiku määratlev kolmemõõtmeline müra." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"Kolmemõõtmeline müra kaljudele, eenditele, jms. Tavaliselt väikesed erisused." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "Kolmemõõtmeline müra, mis määratleb kambristike sageduse kaardijaos." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Teade kõigile külalistele, kui võõrustaja kooleb." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Teade kõigile külalistele, kui server kinni läheb." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "ABM sagedus" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "ABM-i ajakava" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Kõrgeim piirang ilmumist ootavatele klotsiedele" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Kiirendus õhus" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Raskuskiirendus, (klotsi sekundis) sekundi kohta." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Lendlevad osakesed klotsi kaevandamisel." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Maailma nimi" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Arenenud sätted" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Anisotroopne filtreerimine" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Automaatse edasiliikumise klahv" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Iseseisvalt hüppab üle ühe klotsi kordse tõkke." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Aux1 võti" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tagasi liikumise klahv" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Baas maapinna tase" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilineaarne filtreerimine" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Ehitamine mängija sisse" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Muuda kaamerat" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Koobaste läve" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Vestluskäskluse ajalise sõnumi lävi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Käsklused" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Vestlusklahv" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Vestlus päeviku täpsus" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Vestluse sõnumi formaat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Vestlus sõnumi väljaviskamis lävi" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Vestluse lülitusklahv" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Vestluse näitamine" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Filmirežiim" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Filmirežiimi klahv" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Pilved" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Pilved menüüs" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Käsuklahv" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Ühenda klaasi" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Ühendab klaasi, kui klots võimaldab." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Konsooli läbipaistvus" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Konsooli värv" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Konsooli kõrgus" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "ContentDB aadress" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Juhtklahvid" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Loominguline" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Vigastused" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Vaikemäng" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Vaikimisi salasõna" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Vaike lasu hulk" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Müra künnis lagendikule" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Lagendikud ilmuvad kui np_biome ületab selle väärtuse.\n" +"Seda eiratakse, kui lipp 'lumistud' on lubatud." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Ilmestused" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Kaevuri klahv" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Kaevamisel tekkivad osakesed" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Lülita sohituvastus välja" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Topeltklõpsa \"hüppamist\" lendamiseks" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Topeltklõpsates \"hüppamist\" lülitatakse lennurežiim sisse/välja." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Müra keldritele" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Lubab minikaarti." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Silu servad:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Müra lendsaartele" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Edasi klahv" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Mängud" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Üldised maailma loome omadused.\n" +"Maailma loome v6 puhul lipp 'ilmestused' ei avalda mõju puudele ja \n" +"tihniku rohule, kõigi teistega mõjutab see lipp kõiki ilmestusi." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Pinna tase" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Müra pinnasele" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Liidese näitamine" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Müra kõrgusele" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Küngaste järskus" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Küngaste lävi" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Heli valjemaks" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Varustuse klahv" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Hüppa" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Sügavus järvedele" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Järvede lävi" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Suure vestlus-viiba klahv" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Vasak klahv" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Sujuv valgustus" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Peamenüü skript" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Maailma-loome v6 spetsiifilised omadused. \n" +"Lipp 'lumistud' võimaldab uudse 5-e loodusvööndi süsteemi.\n" +"Kui lipp 'lumistud' on lubatud, siis võimaldatakse ka tihnikud ning " +"eiratakse \n" +"lippu 'tihnikud'." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Maailmaloome: Mäestik" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Mäestiku spetsiifilised omadused" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Maailmaloome: Lamemaa" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Lamemaa spetsiifilised omadused" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Maailmaloome: Fraktaalne" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Fraktaalse maailma spetsiifilised lipud" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Maailmaloome: V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "V5 spetsiifilised lipud" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Maailmaloome: V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "V6 spetsiifilised lipud" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Maailmaloome: V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "V7 spetsiifilised lipud" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Maailmaloome: Vooremaa" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Vooremaa spetsiifilised lipud" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Maailmaloome: veaproov" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Maailma tekitus-valemi nimi" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Astmik-tapeetimine" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Vaigista" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Valitud klotsi ilme" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Kõrvale astumise klahv" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Asetamis klahv" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Poissoni filtreerimine" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Valiku ulatuse klahv" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Tavafondi asukoht" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Aruande asukoht" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Parem klahv" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Jõe müra" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Ekraan:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Kuvapildi vorming" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Kuvapildi tase" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Kuvatõmmis" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Majuta külastajatele" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Võõrusta / Üksi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Võõrustaja kirjeldus" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Võõrustaja kanal" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "Võõrustaja-loendi aadress" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "Võõrustaja-loendi aadress" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Võõrustaja-loendi fail" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Varjutaja asukoht" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Varju filtreerimis aste" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Hajus valgus" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Hiilimis klahv" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Hiilimis kiirus" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Sätted" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Tapeedi kaust" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Puuteekraani lävi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Puuteekraani lävi" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "kolmik-lineaar filtreerimine" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Vaate kaugus klotsides." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Valjus" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Merepinna kõrgus maailmas." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Lainetavad klotsid" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Lehvivad lehed" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Lainetavad vedelikud" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Vedeliku laine kõrgus" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Vedeliku laine kiirus" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Vedeliku laine pikkus" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Õõtsuvad taimed" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Kas mängjail on võimalus teineteist tappa." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Kas nähtava ala lõpp udutada." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Aeg alustatavas maailmas" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "cURL faili allalaadimine aegus" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "cURL-i interaktiivne aegumine" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Kujunduslik mängumood: " + +#~ msgid "- Damage: " +#~ msgstr "- Valu: " + +#~ msgid "Address / Port" +#~ msgstr "Aadress / kanal" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Kindlasti lähtestad oma üksikmängija maailma algseks?" + +#~ msgid "Back" +#~ msgstr "Tagasi" + +#~ msgid "Bump Mapping" +#~ msgstr "Konarlik tapeet" + +#~ msgid "Bumpmapping" +#~ msgstr "Muhkkaardistamine" + +#~ msgid "Config mods" +#~ msgstr "Seadista mod-e" + +#~ msgid "Configure" +#~ msgstr "Kohanda" + +#~ msgid "Connect" +#~ msgstr "Ühine" + +#~ msgid "Credits" +#~ msgstr "Tegijad" + +#~ msgid "Damage enabled" +#~ msgstr "Ellujääja" + +#~ msgid "Darkness sharpness" +#~ msgstr "Pimeduse teravus" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Lae alla mäng: näiteks „Minetest Game“, aadressilt: minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Laadi minetest.net-st üks mäng alla" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Palun oota $1 allalaadimist ja paigaldamist…" + +#~ msgid "Enable VBO" +#~ msgstr "Luba VBO" + +#, fuzzy +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Lubab filmic tone mapping" + +#~ msgid "Enter " +#~ msgstr "Sisesta " + +#~ msgid "Filtering" +#~ msgstr "Filtreerimine" + +#~ msgid "Game" +#~ msgstr "Mäng" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Loo normaalkaardistusi" + +#~ msgid "In-Game" +#~ msgstr "Mängu-sisene" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Paigaldus: fail: \"$1\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Nupusätted. (Kui see menüü sassi läheb, siis kustuta asju failist " +#~ "minetest.conf)" + +#~ msgid "Main" +#~ msgstr "Peamine" + +#~ msgid "Main menu style" +#~ msgstr "Peamenüü ilme" + +#~ msgid "Menus" +#~ msgstr "Menüüd" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Radarkaart, Suurendus ×2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Radarkaart, Suurendus ×4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Pinnakaart, Suurendus ×2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Pinnakaart, Suurendus ×4" + +#~ msgid "Name / Password" +#~ msgstr "Nimi / salasõna" + +#~ msgid "Name/Password" +#~ msgstr "Nimi/Salasõna" + +#~ msgid "No" +#~ msgstr "Ei" + +#~ msgid "Ok" +#~ msgstr "Olgu." + +#~ msgid "PvP enabled" +#~ msgstr "Vaenulikus lubatud" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Lähtesta üksikmängija maailm" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "Vali modifikatsiooni fail:" + +#~ msgid "Special key" +#~ msgstr "Eri klahv" + +#~ msgid "Start Singleplayer" +#~ msgstr "Alusta üksikmängu" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Aktiveerimiseks varjud, nad vajavad OpenGL draiver." + +#, fuzzy +#~ msgid "Toggle Cinematic" +#~ msgstr "Lülita kiirus sisse" + +#~ msgid "View" +#~ msgstr "Vaade" + +#~ msgid "Yes" +#~ msgstr "Jah" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Oled esmakordselt liitumas selle võõrustajaga, kandes nime \"%s\".\n" +#~ "Kui jätkad, siis luuakse sellele võõrustajale uus konto sinu volitus " +#~ "andmetega.\n" +#~ "Trüki salasõna uuesti ning klõpsa 'Registreeru ja ühine' konto loomisega " +#~ "nõustumiseks, või 'Loobu' keeldumiseks." + +#~ msgid "You died." +#~ msgstr "Said otsa." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/eu/minetest.po b/po/eu/minetest.po new file mode 100644 index 0000000..dc360ef --- /dev/null +++ b/po/eu/minetest.po @@ -0,0 +1,7008 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-04-29 20:12+0000\n" +"Last-Translator: JonAnder Oier <jonanderetaoier@gmail.com>\n" +"Language-Team: Basque <https://hosted.weblate.org/projects/minetest/minetest/" +"eu/>\n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.12.1\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Garbitu txat-ilara" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Agindu hutsa." + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Itzuli menu nagusira" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Komando baliogabea: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Igorritako komandoa: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Online jokalariak zerrendatu" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Online jokalariak: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Irteerako txat-ilara hutsik dago orain." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Komando hau serbitzariaren bidez desgaituta dago." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Birsortu" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Hil zara" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Komando erabilgarriak:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Komando erabilgarriak: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Komandoa ez dago eskuragarri: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Eskuratu laguntza komandoetarako" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Erabili '.help <cmd>' informazio gehiago eskuratzeko, edo '.help all' guztia " +"zerrendatzeko." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[guztia | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Ados" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<bat ere ez dago eskuragarri>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Errore bat gertatu da Lua script batean:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Errore bat gertatu da:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menu nagusia" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Birkonektatu" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Zerbitzariak birkonexioa eskatu du:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Hautatu Modak" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protokoloaren bertsioen desadostasuna. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Zerbitzariak $1 protokolo bertsioa darabil. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Zerbitzariak $1 eta $2 arteko protokolo bertsioak onartzen ditu. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "$1 bertsioa soilik onartzen dugu." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "$1 eta $2 arteko protokolo bertsioak onartzen ditugu." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Utzi" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Mendekotasunak:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Desgaitu denak" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Mod paketea desgaitu" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Gaitu denak" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Mod paketea gaitu" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Akatsa \"$1\" mod-a gaitzerakoan baimendu gabeko karaktereak dituelako. [a-" +"z0-9_] karaktereak erabil daitezke soilik." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Mod gehiago aurkitu" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "(Aukerako) mendekotasunik ez" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Ez da jolasaren deskripziorik eman." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Mendekotasun zorrotzik ez" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Mod-aren deskribapena ez dago eskuragarri." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Aukerako mendekotasunik ez" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Aukerako mendekotasunak:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Gorde" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Mundua:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "gaituta" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" existitzen da. Gainidatzi egin nahi al duzu?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$1 et $2 mendekotasunak instalatuko dira." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 bider $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 deskargatzen,\n" +"$2 ilaran" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 deskargatzen..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1-ek behar dituen mendekotasunak ezin dira aurkitu." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" +"$1 instalatua izango da, eta $2-ren mendekotasunak baztertu egingo dira." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Pakete guztiak" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Instalaturik jada" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Itzuli menu nagusira" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Oinarri jokoa:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB ez dago erabilgarri Minetest cURL gabe konpilatzean" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Deskargatzen..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Huts egin du $1 deskargatzean" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Jolasak" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instalatu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "$1 Instalatu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Falta diren mendekotasunak instalatu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Instalazioa: Fitxategi ez bateragarria edo fitxategi hautsia" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mod-ak" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Ezin izan da paketerik eskuratu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Emaitzarik ez" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Eguneraketarik ez" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Ez da aurkitu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Gainidatzi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Mesedez, egiaztatu oinarri jokoa zuzena dela." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Ilaran" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "testura paketeak" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Desinstalatu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Eguneratu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Guztia eguneratu [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Ikusi informazio gehiago web nabigatzailean" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Badago \"$1\" izeneko mundu bat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Lurrazal gehigarria" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Garaierako hotza" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Garaierako lehortasuna" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Bioma nahasketa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Leizeak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Leizeak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Sortu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Apaingarriak" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Abisua: Garapen Testa garatzaileentzat da." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Leotzak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Lurrazal laua" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Zeruan flotatzen duten lur-masak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Lur flotagarriak (esperimentala)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Lurrazal ez fraktalak sortu: Ozeanoak eta lurpekoak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Mendiak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Erreka hezeak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Hezetasuna areagotu erreka inguruetan" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "$1 Instalatu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Lakuak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Hezetasun baxuak eta bero handiak sakonera gutxikoak edo lehorrak diren " +"ibaiak sortzen dituzte" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Mapa sortzailea" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Mapgen banderatxoak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Mapgen berariazko banderak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Mendiak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Lokatz-jarioa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Tunel eta kobazuloen sarea" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Ez da jolasik aukeratu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Beroa murrizten du altuerarekin" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Hezetasuna murrizten du altuerarekin" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Ibaiak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Itsas mailako ibaiak" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Hazia" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Biomen arteko trantsizio leuna" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Lurrean agertzen diren egiturak (v6-z sortutako ohianeko zuhaitzetan eta " +"belarretan eraginik gabe)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Lurrean agertzen diren egiturak, normalean zuhaitzak eta landareak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Epela, Basamortua" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Epela, Basamortua, Ohiana" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Epela, Basamortua, Ohiana, Tundra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Lurraren gainazaleko higidura" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Zuhaitzak eta ohianeko belarra" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Ibaiaren sakonera aldatu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Kobazulo oso handiak lurpean sakon" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Munduaren izena" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Ez duzu jolasik instalatuta." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Ziur \"$1\" ezabatu nahi duzula?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Ezabatu" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: Akatsa \"$1\" ezabatzean" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: \"$1\" bide baliogabea" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Ezabatu \"$1\" mundua?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Berretsi pasahitza" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Izena" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Pasahitza" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Pasahitzak ez datoz bat!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Eman izena eta hasi saioa" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Onartu" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Mod paketea berrizendatu:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Mod pakete honek berezko izen zehatza du emanda bere modpack.conf-ean eta " +"berrizendatutako edozein gainidatziko du hemen." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Ez da ezarpenaren deskripziorik eman)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D Zarata" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Itzuli ezarpenen orrira" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Arakatu" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Edukia" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Edukia" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Desgaituta" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Editatu" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Gaituta" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Hutsunetasuna" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Zortzigarrenak" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Desplazamendua" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Iraunkortasuna" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Sartu baliozko zenbaki oso bat." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Sartu baliozko zenbaki bat." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Berrezarri lehenespena" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Eskala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Bilatu" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Hautatu direktorioa" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Hautatu fitxategia" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Erakutsi izen teknikoak" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Balioa gutxienez $1 izan behar da." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Balioa ezin da $1 baino handiagoa izan." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X hedapena" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y hedapena" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z hedapena" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Balio absolutua" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "lehenespenak" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "Arindua" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Gaituta)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mod" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Huts egin du $1 %2-n instalatzean" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Mod instalakuntza: Ezinezkoa S1 mod-en berezko izena aurkitzea" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Mod instalakuntza: ezinezkoa $1 mod-entzako karpeta izen egokia aurkitzea" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Ezinezkoa baliozko mod edo mod pakete bat aurkitzea" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Akatsa $1 testura pakete moduan instalatzea" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Ezinezkoa joko bat $1 moduan instalatzea" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Ezinezkoa mod bat $1 moduan instalatzea" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Ezinezkoa mod pakete bat $1 moduan instalatzea" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Kargatzen..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Zerbitzari publikoen zerrenda desgaituta dago" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Saia zaitez zerbitzari publikoen zerrenda birgaitzen eta egiazta ezazu zure " +"internet konexioa." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Buruz" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Laguntzaile aktiboak" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Renderizatzaile aktiboa:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Garatzaile nagusiak" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Ireki Erabiltzaile Datuen Direktorioa" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Erabiltzaileak emandako munduak, jokoak, modak\n" +"eta testura paketeak fitxategi kudeatzaile / esploratzaile batean." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Lehenagoko laguntzaileak" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Lehenagoko garatzaile nagusiak" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Lineako edukiak esploratu" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Edukia" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Desgaitu testura paketea" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informazioa:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Instalaturiko paketeak:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Mendekotasunik gabe." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Paketearen deskribapena ez dago erabilgarri" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Berrizendatu" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Paketea desinstalatu" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Testura paketea erabili" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Zerbitzaria iragarri" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Helbidea lotu" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Sormen modua" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Kalteak baimendu" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Joko ostalaria" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Zerbitzari ostalaria" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Instalatu ContentDB-ko jolasak" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Berria" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Ez da mundurik sortu edo hautatu!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Jolastu Jokoa" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Portua" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Hautatu Modak" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Munduko selekzioa:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Zerbitzariaren portua" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Hasi partida" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Helbidea" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Garbi" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Sormen modua" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Mina / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Gogokoak" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Zerbitzari bateraezinak" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Elkartu partidara" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "Zerbitzaria iragarri" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Freskatu" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Ez. gogokoena" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Zerbitzariaren deskribapena" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D Hodeiak" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Ezarpen guztiak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Antialiasinga:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Gorde automatikoki Pantailaren Tamaina" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Iragazki bilineala" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Aldatu teklak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Konektatutako beira" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Itzal dinamikoak" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Itzal dinamikoak: " + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Fancy Leaves" +msgstr "Luxuzko hostoak" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Altua" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Baxua" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Erdi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Iragazki Aniso." + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Iragazkirik gabe" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "No Mipmap" +msgstr "Mipmap gabe" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Nabarmendu nodoak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Nodoen ingerada" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Hosto opakoak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Ur opakoa" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partikulak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Pantaila:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Ezarpenak" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Itzalgailuak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Itzalgailuak (esperimentala)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Itzalgailuak (ez dago eskuragarri)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Orri sinpleak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Argiztapen leuna" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Testurizazioa:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Iragazki hirulineala" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Ultra Altua" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Oso Baxua" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Hosto Uhinduak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Likido Uhinduak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Landare Uhinduak" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Konexio-errorea (denbora agortua?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Konexioaren itxaronaldia agortu egin da." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Egina!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Nodoak hasieratzen" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Nodoak hasieratzen..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Testurak kargatzen..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Itzalgailuak berreraikitzen..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Konexio-errorea (denbora agortua?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Ezin izan da jokoa aurkitu edo kargatu: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Jokoaren espezifikazioa ez da baliozkoa." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menu nagusia" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Ez da mundurik hautatu eta ez da helbiderik eman. Ez dago zer eginik." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Jokalariaren izena luzeegia da." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Mesedez, aukeratu izen bat!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Ezin izan da ireki emandako pasahitzaren fitxategia: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Zehaztutako munduaren ibilbidea ez da existitzen: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Helbidea: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Modua: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Ataka: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Publikoa: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- Jokalaria Jokalariaren aurka (PvP): " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Zerbitzariaren izena: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Errore bat gertatu da:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Sarbidea ukatuta. Arrazoia: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Kameraren eguneraketa desaktibatuta dago" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Kameraren eguneraketa gaituta dago" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Pasahitza aldatu" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Modu zinematografiko desaktibatuta" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Modu zinematografiko gaituta" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Bezero deskonektatua" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Zerbitzarira konektatzen..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Konexioak huts egin du arrazoi ezezagun batengatik" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Jarraitu" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Ezin izan da helbidea ebatzi: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Bezeroa sortzen..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Zerbitzaria sortzen..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Arazte informazioa eta profilariaren grafikoa ezkutatuta" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Arazketari buruzko informazioa erakusten da" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Arazte informazioa, profilariaren grafikoa, eta hari-sareta ezkutatuta" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Desgaitu mugagabeko ikusmen barrutia" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Gaitu mugagabeko ikusmen barrutia" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Bezeroa sortzen..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Irten menura" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Irten sistema eragilera" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Modu azkarra desaktibatuta" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Modu azkarra gaituta" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Lainoa desaktibatuta" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Lainoa gaituta" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Jokoari buruzko informazioa:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Itemen definizioak..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Multimedia..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Nodoen definizioak..." + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profilariaren grafikoa ikusigai" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Urruneko zerbitzaria" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Itzaltzen..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Jokalari bakarra" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Soinuaren bolumena" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Zerbitzaria ziurrenik %s bertsio desberdin bat exekutatzen ari da." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Ezin da %s-ra konektatu IPv6 desaktibatuta dagoelako" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Ezin da %s-n entzun IPv6 desaktibatuta dagoelako" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Ikusmen barrutia aldatu da: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Ikusmen barrutia maximoan dago: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Ikusmen barrutia minimoan dago: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Bolumena %d%%ra aldatu da" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "Ados" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Txat ezkutua" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profilaria ezkutatuta" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profilaria ikusgai (%d/%d orria)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplikazioak" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Ctrl" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Behera" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Amaiera" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Exekutatu" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Laguntza" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Hasiera" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Txertatu" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Ezkerra" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Ezkerreko botoia" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Ezkerreko ctrl" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Ezkerreko menua" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Ezkerreko maius." + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Ezkerreko leihoa" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Erdiko botoia" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Orrialdea behera" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Orrialdea gora" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Jolastu" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Inprimatu" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Itzuli" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Eskuina" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Eskuineko botoia" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Eskuineko ctrl" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Eskuineko menua" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Eskuineko maius." + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Eskuineko leihoa" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Hautatu" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Maius." + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Lokartu" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Pantaila-argazkia" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Espazioa" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabuladorea" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Gora" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "1. X botoia" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "2. X botoia" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Huts egin du $1 deskargatzean" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Web orria irekitzen" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Jarraitu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Aurrera automatikoki" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Jauzi automatikoa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Atzera" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Aldatu kamera" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Txata" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Agindua" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Kontsola" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Txikitu barrutia" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Jaitsi bolumena" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Laga" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Aurrera" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Handitu barrutia" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Igo bolumena" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inbentarioa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Jauzi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Dagoeneko erabiltzen ari den tekla" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Agindu lokala" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Isilarazi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Hurrengoa elementua" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Aurreko elementua" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Barruti hautaketa" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Pantaila-argazkia" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "isilean mugitu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Txandakatu azkar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Txandakatu hegaz egitea" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Txandakatu minimapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "sakatu tekla" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Aldatu" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Pasahitzak ez datoz bat!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "eu" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Mesedez, aukeratu izen bat!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Bloke aktiboaren barrutia" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Objektu aktiboak bidaltzeko barrutia" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Munduaren izena" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "Jauzi tekla" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Atzera tekla" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Aldatu kamera" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Kameraren eguneraketa txandakatzeko tekla" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Agindua" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Txat tekla" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Agindua tekla" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Konektatu kanpo multimedia zerbitzari batera" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Sareko eduki biltegia" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Sormena" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Kaltea" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Arazte informazioa txandakatzeko tekla" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Jokalari transferentziaren distantzia maximoa blokeetan definitzen du (0 = " +"mugagabea)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Apaingarriak" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "Eskuinera tekla" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable creative mode for all players" +msgstr "Gaitu sormen modua mapa sortu berrietan." + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Ahalbidetu jokalariek kaltea jasotzea eta hiltzea." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Gaitu urruneko multimedia zerbitzariaren erabilera (zerbitzariak ematen " +"badu),\n" +"Urruneko zerbitzariek deskarga azkarragoa eskaini dezakete multimedia " +"deskargatzeko (adib. testurak)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Profilaria" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Azkar tekla" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Antialiasinga:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland tapering distance" +msgstr "Jokalariaren transferentzia distantzia" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Hegaz egin tekla" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Aurrera tekla" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Zein distantziatik dakite bezeroek objektuei buruz, mapa blokeetan (16 nodo) " +"adierazita.\n" +"\n" +"Hau active_block_range baino handiagoa ezarriz gero zerbitzariak jokalariak\n" +"begiratzen duen norabidean objektu aktiboak distantzia honetara arte\n" +"mantentzea eragingo du. (Honek gauzak bat batean desagertzea saihestu dezake)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Jolasak" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Inbentarioa tekla" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick dead zone" +msgstr "Joystick mota" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Joystick mota" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Jauzi tekla" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Ikusmen barrutia txikitzeko tekla.\n" +"Ikusi http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Ikusmen barrutia txikitzeko tekla.\n" +"Ikusi http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Ikusmen barrutia handitzeko tekla.\n" +"Ikusi http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Komando lokalak idazteko txat leihoa irekitzeko tekla.\n" +"Ikusi http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Ikusmen barrutia txikitzeko tekla.\n" +"Ikusi http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kameraren eguneraketa txandakatzeko tekla. Garapenerako soilik erabilia\n" +"Ikusi http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Arazte informazioa txandakatzeko tekla\n" +"Ikusi http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Profilaria txandakatzeko tekla. Garapenerako soilik erabilia.\n" +"Ikusi http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Ikusmen barruti mugagabea txandakatzeko tekla.\n" +"Ikusi http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Ezkerrera tekla" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Argiztapen leuna" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Kargatu jolasaren profilaria" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Kargatu jolasaren profilaria jolasaren profil datuak jasotzeko.\n" +"/profiler komandoa eskaintzen du jasotako profila atzitzeko.\n" +"Mod garatzaileentzat eta zerbitzari jabeentzat erabilgarria." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Profilaria" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Nabarmendu nodoak" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Hegaz egin tekla" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Jokalariaren transferentzia distantzia" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Profilaria" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Profilaria txandakatzeko tekla" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Ikusmen barrutia hautatzeko tekla" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Urruneko multimedia" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Eskuinera tekla" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Pantaila:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Pantaila-argazkia" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Zerbitzari ostalaria" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "- Zerbitzariaren izena: " + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Zerbitzariaren deskribapena" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Zerbitzariaren portua" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Isilean mugitu tekla" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Ezarpenak" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "Eduki biltegiaren URL helbidea" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The dead zone of the joystick" +msgstr "Joystick mota" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Profilak gordetzeko lehenetsitako formatua,\n" +"`/profiler save [format]` formaturik gabe deitzean erabilia." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Joystick mota" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Atzerapena murrizteko, blokeen transferentziak moteldu egiten dira jokalari " +"bat zerbait eraikitzen ari denean.\n" +"Honek nodo bat jarri edo kendu ondoren zenbat motelduko diren zehazten du." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Jokalari transferentzia distantzia mugagabea" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Ikusmen barrutia txikitzeko tekla" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Ikusmen barrutia handitzeko tekla" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Ikusmen barrutia" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Jokalariak bezeroei barruti mugarik gabe erakutsiko al zaizkien.\n" +"Zaharkitua, erabili player_transfer_distance ezarpena honen ordez." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Jokalariak elkarren artean hil daitezkeen ala ez." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "cURL-en denbora muga" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Sormen modua: " + +#~ msgid "- Damage: " +#~ msgstr "- Kaltea: " + +#~ msgid "Back" +#~ msgstr "Atzera" + +#~ msgid "Configure" +#~ msgstr "Konfiguratu" + +#~ msgid "Connect" +#~ msgstr "Konektatu" + +#~ msgid "Credits" +#~ msgstr "Kredituak" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "" +#~ "Deskargatu jolasen bat, esaterako Minetest Game, minetest.net " +#~ "zerbitzaritik" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Deskargatu minetest.net zerbitzaritik" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "$1 deskargatu eta instalatzen, itxaron mesedez..." + +#~ msgid "Game" +#~ msgstr "Jolasa" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Instalakuntza: fitxategia: \"$1\"" + +#~ msgid "Ok" +#~ msgstr "Ados" + +#~ msgid "Special" +#~ msgstr "Berezia" + +#~ msgid "Special key" +#~ msgstr "Berezia tekla" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Hil zara" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/fi/minetest.po b/po/fi/minetest.po new file mode 100644 index 0000000..489b66b --- /dev/null +++ b/po/fi/minetest.po @@ -0,0 +1,6950 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-07 17:16+0000\n" +"Last-Translator: Oftox <oftox@protonmail.com>\n" +"Language-Team: Finnish <https://hosted.weblate.org/projects/minetest/" +"minetest/fi/>\n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.13.1-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Tyhjennä keskustelujono" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Tyhjä komento." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Poistu päävalikkoon" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Virheellinen komento: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Annettu komento: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Listaa verkkopelaajat" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Verkkopelaajat: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Keskustelujono on nyt tyhjä." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Palvelin on poistanut komennon käytöstä." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Synny uudelleen" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Kuolit" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Käytettävissä olevat komennot:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Käytettävissä olevat komennot: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Komento ei ole käytettävissä: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Ohjeita komentojen käyttöön" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Käytä '.help <cmd>' saadaksesi lisätietoja komennosta, tai '.help all' " +"listataksesi kaiken." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[kaikki | <komento>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<ei saatavilla>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Lua-skriptissä tapahtui virhe:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Tapahtui virhe:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Päävalikko" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Yhdistä uudelleen" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Palvelin pyysi yhteyden muodostamista uudelleen:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Valitse modit" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protokollaversiot epäyhteensopivat. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Palvelin vaatii protokollaversion $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Palvelin tukee protokollia versioiden $1 ja $2 välillä. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Tuemme vain protokollaversiota $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Tuemme protokollaversioita välillä $1 ja $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Peruuta" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Riippuvuudet:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Poista kaikki käytöstä" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Poista modipaketti käytöstä" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Ota kaikki käyttöön" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Ota modipaketti käyttöön" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Modin \"$1\" käyttöönotto epäonnistui, koska se sisälsi sallimattomia " +"merkkejä. Vain merkit [a-z0-9_] ovat sallittuja." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Löydä lisää modeja" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Modi:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Ei (valinnaisia) riippuvuuksia" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Pelin kuvausta ei ole annettu." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Ei kovia riippuvuuksia" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Modipaketin kuvausta ei annettu." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Ei valinnaisia riippuvuuksia" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Valinnaiset riippuvuudet:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Tallenna" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Maailma:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "käytössä" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" on jo olemassa. Haluatko korvata sen?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Riippuvuudet $1 ja $2 asennetaan." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 lataa,\n" +"$2 jonossa" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 latautuu..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 tarvittavaa riippuvuutta ei löytynyt." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 asennetaan, ja $2 riippuvuutta sivuutetaan." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Kaikki paketit" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Asennettu jo" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Palaa päävalikkoon" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Peruspeli:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB ei ole saatavilla, jos Minetest on koottu ilman cURLia" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Ladataan..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Epäonnistui ladata $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Pelit" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Asentaa" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Asenna $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Asenna puuttuvat riippuvuudet" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Lataus: Tukematon tiedostotyyppi tai rikkinäinen arkisto" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Modit" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Paketteja ei löydetty" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Ei tuloksia" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Ei päivityksiä" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Ei löytynyt" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Ylikirjoita" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Jonotettu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Tekstuuripaketit" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Poista" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Päivitä" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Päivitä kaikki [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Katso lisätietoja verkkoselaimessa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Maailma nimellä \"$1\" on jo olemassa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomit" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Luolat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Luolat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Luo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Koristeet" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Varoitus: Development Test on tarkoitettu kehittäjille." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Tasainen maasto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Taivaalla leijuvat maamassat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Mäet" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Kosteat joet" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Asenna $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Järvet" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Mapgen-valitsimet" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Mapgen-spesifit valitsimet" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Vuoret" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Ei peliä valittu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Joet" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Siemen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Maailman nimi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Sinulla ei ole pelejä asennettuna." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Oletko varma että haluat poistaa \"$1\":n?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Poista" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: kohteen \"$1\" poistaminen epäonnistui" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: virheellinen polku \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Poista maailma \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Vahvista salasana" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nimi" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Salasana" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Salasanat eivät täsmää!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Rekisteröidy ja liity" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Hyväksy" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Nimeä modipaketti uudelleen:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Palaa asetussivulle" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Selaa" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Sisältö" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Sisältö" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Poistettu käytöstä" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Muokkaa" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Otettu käyttöön" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Anna kelvollinen kokonaisuluku." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Anna kelvollinen numero." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Palauta oletus" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Etsi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Valitse hakemisto" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Valitse tiedosto" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Näytä tekniset nimet" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Arvon tulee olla vähintään $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Arvo ei saa olla suurempi kuin $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Käytössä)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 modia" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Ladataan..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Julkinen palvelinlista on pois käytöstä" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Kokeile ottaa julkinen palvelinlista uudelleen käyttöön ja tarkista " +"internetyhteytesi." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Tietoja" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Avaa käyttäjätietohakemisto" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Selaa sisältöä verkossa" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Sisältö" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Poista tekstuuripaketti käytöstä" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Tietoja:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Asennetut paketit:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Ei riippuvuuksia." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Ei paketin kuvausta saatavilla" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Nimeä uudelleen" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Poista paketti" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Käytä tekstuuripakettia" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Ilmoita palvelin" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Sido osoite" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Luova tila" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Ota vahinko käyttöön" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Isännöi peli" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Isännöi palvelin" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Asenna pelejä ContentDB:stä" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Uusi" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Maailmaa ei ole luotu tai valittu!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Pelaa peliä" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Portti" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Valitse modit" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Valitse maailma:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Palvelimen portti" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Aloita peli" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Osoite" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Tyhjennä" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Luova tila" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Vahinko / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Suosikit" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Palvelimet eivät ole yhteensopivat" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Liity peliin" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Viive" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Julkiset palvelimet" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Päivitä" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Palvelimen kuvaus" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D-pilvet" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Kaikki asetukset" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Reunanpehmennys:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Tallenna näytön koko automaattisesti" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilineaarinen suodatus" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Näppäinasetukset" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dynaamiset varjot" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Dynaamiset varjot: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Hienot lehdet" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Ei suodatinta" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Läpinäkymätön vesi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partikkelit" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Näyttö:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Asetukset" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Varjostimet" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Varjostimet (kokeellinen)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Varjostimet (ei käytettävissä)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Tasainen valaistus" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Teksturointi:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Yhteys aikakatkaistiin." + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Yhteys aikakatkaistiin." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Valmis!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Ladataan tekstuureja..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Rakennetaan uudelleen varjostimia..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Päävalikko" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Pelaajan nimi on liian pitkä." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Valitse nimi!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Osoite: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Tila: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Portti: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Julkinen: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Palvelimen nimi: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Tapahtui virhe:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Vaihda salasana" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Yhdistetään palvelimeen..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Jatka" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Luodaan asiakasta..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Luodaan palvelinta..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Luodaan asiakasta..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Poistu valikkoon" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Poistu käyttöjärjestelmään" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Lentotila pois käytöstä" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Lentotila käytössä" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Sumu pois käytöstä" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Sumu käytössä" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Pelin tiedot:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Peli keskeytetty" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "Pois" + +#: src/client/game.cpp +msgid "On" +msgstr "Päällä" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Etäpalvelin" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Selvitetään osoitetta..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Sammutetaan..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Yksinpeli" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Äänenvoimakkuus" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Ääni mykistetty" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Ääni palautettu" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Keskustelu piilotettu" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Verkkosivun avaaminen epäonnistui" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Hypi automaattisesti" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Taakse" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Vaihda kameraa" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Keskustelu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Komento" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsoli" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Eteen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventaario" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Hyppää" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Paikallinen komento" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Kuvakaappaus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Hiivi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Uusi salasana" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Vanha salasana" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Salasanat eivät täsmää!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Poistu" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Mykistetty" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Äänenvoimakkuus: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "fi" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Valitse nimi!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D-pilvet" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D-tila" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Maailman nimi" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Lisäasetukset" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Tallenna näytön koko automaattisesti" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Vaihda kameraa" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Chat-komennnot" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Asiakas" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Asiakas ja palvelin" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Pilvet" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Koristeet" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Käytä konsoli-ikkunaa" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Reunanpehmennys:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Koko näyttö" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Koko näytön tila." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Pelit" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafiikka" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafiikka" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafiikka" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP-modit" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Palvelimen sivusto, näytetään palvelinlistauksessa." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6-palvelin" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Kieli" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Tasainen valaistus" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "FPS enintään" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Käyttäjiä enintään" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Turvallisuus" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Hiiren herkkyys" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Mykistä ääni" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Verkko" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Uusien käyttäjien tulee syöttää tämä salasana." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fysiikka" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Pelaaja vastaan pelaaja" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Näyttö:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Näytön korkeus" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Näytön leveys" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Kuvakaappausten kansio" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Kuvakaappausten muoto" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Kuvakaappausten laatu" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Kuvakaappaus" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Lue https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Palvelimen URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Palvelimen nimi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Palvelimen kuvaus" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "Palvelimen URL" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Palvelimen osoite" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Palvelimen kuvaus" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Palvelimen nimi" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Palvelimen portti" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Palvelimen portti" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Hiiviskelyn nopeus" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Ääni" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "Synkroninen SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Asetukset" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Koko näyttö" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Luotetut modit" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Videoajuri" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Kävelyn nopeus" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Luova tila: " + +#~ msgid "- Damage: " +#~ msgstr "- Vahinko: " + +#~ msgid "Connect" +#~ msgstr "Yhdistä" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Lataa peli, kuten Minetest Game, minetest.netistä" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Lataa yksi minetest.netistä" + +#~ msgid "FreeType fonts" +#~ msgstr "FreeType-fontit" + +#~ msgid "Game" +#~ msgstr "Peli" + +#~ msgid "In-Game" +#~ msgstr "Pelinsisäinen" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Asenna: tiedosto: \"$1\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Näppäimistöasetukset. (Jos tämä valikko rikkoutuu, poista asioita " +#~ "minetest.conf-tiedostosta)" + +#~ msgid "Menus" +#~ msgstr "Valikot" + +#~ msgid "Name / Password" +#~ msgstr "Nimi / Salasana" + +#~ msgid "Player name" +#~ msgstr "Pelaajan nimi" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Palvelin / yksinpeli" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Varjostimien käyttäminen vaatii, että käytössä on OpenGL-ajuri." + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Olet aikeissa liittyä tälle palvelimelle nimellä \"%s\" ensimmäistä " +#~ "kertaa.\n" +#~ "Jos jatkat, uusi tili kirjautumistietojen kera luodaan tälle " +#~ "palvelimelle.\n" +#~ "Kirjoita salasana ja napsauta \"Rekisteröidy ja liity\" vahvistaaksesi " +#~ "tilin luomisen, tai napsauta \"Peruuta\" lopettaaksesi." + +#~ msgid "You died." +#~ msgstr "Kuolit." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/fil/minetest.po b/po/fil/minetest.po new file mode 100644 index 0000000..85444da --- /dev/null +++ b/po/fil/minetest.po @@ -0,0 +1,7064 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-06-27 03:16+0000\n" +"Last-Translator: Marco Santos <enum.scima@gmail.com>\n" +"Language-Team: Filipino <https://hosted.weblate.org/projects/minetest/" +"minetest/fil/>\n" +"Language: fil\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1 && n != 2 && n != 3 && (n % 10 == 4 " +"|| n % 10 == 6 || n % 10 == 9);\n" +"X-Generator: Weblate 4.13.1-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Linisin ang pila ng out chat" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Bakanteng utos." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Umalis sa main menu" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Invalid na utos: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Inisyu na utos: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Ilista ang mga naka-online na player" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Mga naka-online na player: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Bakante na ang pila ng out chat." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Sinara ng server ang utos na ito." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Mag-respawn" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Namatay ka" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Mga magagamit na utos:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Mga magagamit na utos: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Di magagamit ang utos: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Humingi ng tulong para sa mga utos" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Gamitin ang '.help <utos>' para makakuha ka pa ng mas maraming impormasyon, " +"o '.help all' para ilista lahat." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <utos>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Sige" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<wala>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "May error sa Lua script:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "May error:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Main menu" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Kumonekta uli" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Humiling ang server ng pagkonekta muli:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Pumili ng mga Mod" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Di tumugmang bersyon ng protocol. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Pinapatupad ng server ang bersyon ng protocol na $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "" +"Sinusuportahan ng server ang mga bersyon ng protocol sa pagitan $1 at $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Suportado lang po namin ang bersyon ng protocol na $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "" +"Suportado lang po namin ang mga bersyon ng protocol sa pagitan ng $1 at $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Ikansela" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Mga kailangan:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Isara lahat" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Isara ang modpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Buksan lahat" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Buksan ang modpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Bigong mabuksan ang mod na \"$1\" dahil naglalaman ito ng mga bawal na " +"karakter. Tanging mga karakter na [a-z0-9_] lang ang pwede." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Maghanap pa ng mga Mod" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Walang (optional na) kailangan" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Walang binigay na paglalarawan sa laro." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Walang kailangang kailangan" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Walang binigay na paglalarawan sa modpack." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Walang mga optional na kailangan" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Mga optional na kailangan:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "I-save" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Mundo:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "bukas" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "Meron na'ng \"$1\". Gusto mo bang i-overwrite ito?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Ii-install ang mga kailangan na $1 at $2." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 ni $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 dina-download,\n" +"$2 nakapila" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 dina-download..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "Di makita ang $1 (na) kailangan." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "Ii-install ang $1, at lalaktawan ang %2." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Lahat ng package" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Naka-install na" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Balik sa Main Menu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Basehang Laro:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" +"Di magagamit ang ContentDB kapag na-compile ang Minetest nang walang cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Dina-download..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Bigong ma-download ang $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Mga Laro" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "I-install" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "I-install ang $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "I-install ang mga nawawalang kailangan" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "I-install: Di-suportadong file type o sirang archive" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mga Mod" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Walang makuhang mga package" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Walang mga resulta" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Walang mga update" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Di nakita" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "I-overwrite" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Siguraduhing tama ang basehang laro." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Nakapila" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Mga Texture Pack" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Burahin" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "I-update" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "I-update Lahat [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Tumingin pa ng mas maraming impormasyon sa web browser" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Meron na'ng mundong may pangalang \"$1\"" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Karagdagang terrain" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Lamig ng altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Tuyo ng altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Paghahalo ng biome" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Mga biome" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Mga kweba" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Mga kweba" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Gumawa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Mga dekorasyon" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Babala: Para sa mga developer ang Development Test." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Mga dungeon" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Patag na terrain" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Mga lumulutang na kalupaan sa langit" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Lumulutang na Lupa (eksperimento)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Gumawa ng di fractal na terrain: Mga karagatan at ilalim ng lupa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Mga burol" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Mga mahalumigmig na ilog" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Pinapataas ang halumigmig sa mga ilog" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "I-install ang $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Mga lawa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Bumababa o natutuyo ang mga ilog kapag mababa ang halumigmig at mataas ang " +"init" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Mapgen" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Mga flag ng mapgen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Mga flag na specific sa mapgen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Mga bundok" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Agos ng putik" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Network ng mga tunnel at kweba" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Walang larong napili" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Binabawasan ang init ng altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Binabawasan ang halumigmig ng altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Mga ilog" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Lebel ng dagat sa mga ilog" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Seed" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Malinis na transition sa pagitan ng mga biome" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Mga istrakturang magpapakita sa terrain (walang epekto sa mga puno at damo " +"sa gubat na nagawa ng v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" +"Mga istrakturang magpapakita sa terrain, tipikal na mga puno at halaman" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Temperate, Disyerto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Temperate, Disyerto, Kagubatan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Temperate, Disyerto, Kagubatan, Tundra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erosyon sa lupa ng terrain" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Mga puno at damo sa gubat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Nagbabagong lalim ng ilog" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Mga napakalaking malalalim na kweba" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Pangalan ng mundo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Wala kang na-install na mga laro." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Sigurado ka bang buburahin mo ang \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Burahin" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: bigong mabura ang \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: invalid na path na \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Burahin ang Mundong \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Kumpirmahin ang Password" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Pangalan" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Password" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Di tugma ang mga password!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Magparehistro at Sumali" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Tanggapin" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "I-rename ang Modpack:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"May explicit na pangalan ang modpack na ito na nakalagay sa modpack.conf " +"nito na mag-o-override sa kahit anong pag-rename dito." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Walang binigay na paglalarawan)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D Noise" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Balik sa Pagsasaayos" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Mag-browse" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Content" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Content" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Nakasara" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Baguhin" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Nakabukas" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lacunarity" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Mga octave" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Offset" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Persistence" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Mangyaring maglagay ng valid na integer." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Mangyaring maglagay ng valid na bilang." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "I-restore ang Default" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Scale" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Maghanap" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Pumili ng directory" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Pumili ng file" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Ipakita ang mga teknikal na pangalan" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Dapat di bababa sa $1 ang value." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Dapat di lalaki sa $1 ang value." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Pagkalat ng X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Pagkalat ng Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Pagkalat ng Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "absvalue" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "defaults" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "eased" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Nakabukas)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 (na) mod" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Bigong ma-install ang $1 sa $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "I-install ang Mod: Bigong mahanap ang tunay na pangalan ng mod ng: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"I-install ang Mod: Bigong mahanap ang akmang pangalan ng folder para sa " +"modpack na $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Bigong makahanap ng valid na mod o modpack" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Bigong ma-install ang $1 bilang texture pack" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Bigong ma-install ang laro bilang $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Bigong ma-install ang mod bilang $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Bigong ma-install ang modpack bilang $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Nilo-load..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Nakasara ang listahan ng mga pampublikong server" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Subukang buksan muli ang listahan ng pampublikong server at tingnan ang " +"koneksyon mo sa internet." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Patungkol" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Mga Aktibong Nag-aambag" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Aktibong renderer:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Mga Core Developer" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Buksan ang User Data Directory" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Bubuksan ang directory na naglalaman ng mga user-provided na mundo,\n" +"laro, mod, at texture pack sa isang file manager/explorer." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Mga Nakaraang Nag-ambag" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Mga Nakaraang Core Developer" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Mag-browse ng online content" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Content" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Isara ang Texture Pack" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Impormasyon:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Mga Naka-install na Package:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Walang mga kailangan." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Walang paglalarawan sa package" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "I-rename" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Burahin ang Package" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Gumamit ng Texture Pack" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Ianunsyo ang Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "I-bind ang Address" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Creative Mode" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Buksan ang Pinsala" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Mag-host ng Laro" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Mag-host ng Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Mag-install ng mga laro mula sa ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Bago" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Walang nagawa o napiling mundo!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Maglaro" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Pumili ng mga Mod" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Pumili ng Mundo:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Port ng Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Magsimula" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Address" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Linisin" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Creative mode" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Pinsala/PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Mga Paborito" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Di compatible na mga Server" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Sumali sa Laro" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Mga Pampublikong Server" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "I-refresh" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Burahin Paborito" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Paglalarawan sa Server" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D na Ulap" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Lahat ng Pagsasaayos" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Antialiasing:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Kusang I-save ang Laki ng Screen" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilinear Filter" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Baguhin ang mga Key" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Konektadong Salamin" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dynamic na mga anino" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Dynamic na mga anino: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Magagarang Dahon" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Mataas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Mababa" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Katamtaman" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Aniso. Filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Walang Filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Walang Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Pag-highlight sa Node" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Pag-outline sa Node" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Wala" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Opaque na Dahon" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Opaque na Tubig" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Mga Particle" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Screen:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Pagsasaayos" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Mga Shader" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Mga Shader (eksperimento)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Mga Shader (di available)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Simpleng Dahon" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Malinis na Liwanag" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Pagte-texture:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Tone Mapping" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Touchthreshold: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Trilinear Filter" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Napakataas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Napakababa" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Nahahanginang Dahon" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Umaalong Tubig" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Nahahanginang Halaman" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Error sa koneksyon (nag-timeout?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Nag-timeout ang koneksyon." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Tapos na!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Ini-initialize ang mga node" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Ini-initialize ang mga node..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Nilo-load ang mga texture..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Rine-rebuild ang mga shader..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Error sa koneksyon (nag-timeout?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Di mahanap o ma-load ang laro: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Invalid na gamespec." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Main Menu" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Walang napiling mundo at walang binigay na address. Walang gagawin." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Masyadong mahaba ang pangalan ng player." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Mangyaring pumili po ng pangalan!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Bigong mabuksan ang binigay na password file: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Walang path sa mundo na tumugma sa binigay: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Tingnan ang debug.txt para sa mga detalye." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Address: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Mode: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Pampubliko: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Pangalan ng Server: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "May naganap na serialization error:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Tinanggihan ang access: Dahilan: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Nakasara ang kusang pag-abante" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Nakabukas ang kusang pag-abante" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Nakatago ang mga block bound" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Ipinapakita ang mga block bound para sa lahat ng mga block" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Ipinapakita ang block bound para sa kasalukuyang block" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Ipinapakita ang mga block bound para sa mga malalapit na block" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Nakasara ang pag-update sa kamera" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Nakabukas ang pag-update sa kamera" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" +"Bawal maipakita ang mga block bound (kailangan ng pribilehiyong " +"'basic_debug')" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Baguhin ang Password" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Nakasara ang cinematic mode" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Nakabukas ang cinematic mode" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Nadiskonekta ang client" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Nakasara ang scripting sa client side" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Kumokonekta sa server..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Bigong makakonekta dahil sa di matukoy na dahilan" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Magpatuloy" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Mga kontrol:\n" +"- %s: abante paharap\n" +"- %s: abante patalikod\n" +"- %s: kumaliwa\n" +"- %s: kumanan\n" +"- %s: tumalon/umakyat\n" +"- %s: maghukay/sumuntok\n" +"- %s: maglagay/gumamit\n" +"- %s: dahan-dahan/bumaba\n" +"- %s: ihulog ang item\n" +"- %s: inventory\n" +"- Mouse: umikot/tumingin\n" +"- Mouse wheel: pumili ng item\n" +"- %s: chat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Di maresolba ang address: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Ginagawa ang client..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Ginagawa ang server..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Nakatago ang debug info at profiler graph" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Ipinapakita ang debug info" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Nakatago ang debug info, profiler graph, at wireframe" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Mga Default na Kontrol:\n" +"Kapag walang makikitang Menu:\n" +"- isang pindot: i-activate ang button\n" +"- dobleng pindot: ilagay/gamitin\n" +"- padulasin ang daliri: tumingin-tingin sa paligid\n" +"Kapag makikita ang Menu/Inventory:\n" +"- dobleng pindot (sa labas):\n" +" -->isara\n" +"- pindutin ang stack, pindutin ang slot:\n" +" --> ilipat ang stack\n" +"- pindutin at i-drag, pindutin pangalawang daliri\n" +" --> ilagay ang isang item sa slot\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Nakasara ang unlimited na viewing range" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Nakabukas ang unlimited na viewing range" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Ginagawa ang client..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Umalis sa Menu" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Umalis sa OS" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Nakasara ang fast mode" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Nakabukas ang fast mode" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Nakabukas ang fast mode (paalala: walang pribilehiyong 'fast')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Nakasara ang fly mode" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Nakabukas ang fly mode" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Nakabukas ang fly mode (paalala: walang pribilehiyong 'fly')" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Nakasara ang hamog" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Nakabukas ang hamog" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Info ng laro:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Nakahinto ang laro" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Nagho-host na server" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Mga definition ng item..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Media..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Kasalukuyang sinara ng laro o mod ang minimap" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Multiplayer" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Nakasara ang noclip mode" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Nakabukas ang noclip mode" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Nakabukas ang noclip mode (paalala: walang pribilehiyong 'noclip')" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Mga definition ng node..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Sarado" + +#: src/client/game.cpp +msgid "On" +msgstr "Bukas" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Nakasara ang pitch move mode" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Nakabukas ang pitch move mode" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Ipinapakita ang profiler graph" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Remote na server" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Rineresolba ang address..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Sina-shutdown..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Singleplayer" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Volume ng Tunog" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Naka-mute ang tunog" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Nakasara ang system ng tunog" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Di suportado ang system ng tunog sa build na ito" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Di na naka-mute ang tunog" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Baka ibang bersyon ng %s ang pinapatakbo ng server." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Bigong makakonekta sa %s dahil nakasara ang IPv6" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Bigong makakinig sa %s dahil nakasara ang IPv6" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Binago ang viewing range papuntang %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Nasa maximum na ang viewing range: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Nasa minimum na ang viewing range: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Binago ang volume papuntang %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Ipinapakita ang wireframe" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Kasalukuyang sinara ng laro o mod ang pag-zoom" + +#: src/client/game.cpp +msgid "ok" +msgstr "sige" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Nakatago ang chat" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Ipinapakita ang chat" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "Nakatago ang HUD" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "Ipinapakita ang HUD" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Nakatago ang profiler" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Ipinapakita ang profiler (pahina %d ng %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Mga App" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Down" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Erase EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Execute" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Help" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME Accept" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME Convert" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME Escape" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME Mode Change" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME Nonconvert" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Left" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Left Button" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Left Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Left Menu" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Left Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Left Windows" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Middle Button" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numpad *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numpad +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numpad -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numpad ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numpad /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numpad 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numpad 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numpad 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numpad 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numpad 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numpad 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numpad 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numpad 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numpad 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numpad 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Play" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Print" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Return" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Right" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Right Button" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Right Control" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Right Menu" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Right Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Right Windows" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Select" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Sleep" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Snapshot" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Space" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Up" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Button 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Button 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Nakatago ang minimap" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimap sa radar mode, Zoom x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimap sa surface mode, Zoom x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimap sa texture mode" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Bigong mabuksan ang webpage" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Binubuksan ang webpage" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Tumuloy" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = bumaba" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Kusang abante" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Kusang talon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Pabalik" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Mga block bound" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Palitan ang kamera" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Utos" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Console" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Dec. range" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Dec. volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Dobleng pindutin ang \"tumalon\" para makalipad" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Ihulog" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Abante" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Inc. range" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Inc. volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventory" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Tumalon" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "May gamit na ang key" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Lokal na utos" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "I-mute" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Susunod na item" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Nakaraang item" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Pagpili sa saklaw" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Mag-screenshot" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Magdahan-dahan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "I-toggle ang HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "I-toggle ang chat log" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "I-toggle ang fast" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "I-toggle ang fly" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "I-toggle ang hamog" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "I-toggle ang minimap" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "I-toggle ang noclip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "I-toggle ang pitchmove" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "pumindot ng key" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Baguhin" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Bagong Password" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Lumang Password" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Di tugma ang mga password!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Umalis" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Naka-mute" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Volume ng Tunog: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "fil" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Mangyaring pumili po ng pangalan!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Inaayos ang posisyon ng virtual joystick.\n" +"Kung nakasara, isesentro ang virtual joystick sa posisyon na unang pinindot." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Gamitin ang virtual joystick para i-trigger ang button na " +"\"Aux1\".\n" +"Kung nakabukas, pipindutin din ng virtual joystick ang button na \"Aux1\" " +"kapag nasa labas ng pinakabilog." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) offset ng fractal mula sa sentro ng mundo sa mga unit ng 'scale'.\n" +"Pwedeng magamit para ilipat ang isang partikular na punto papunta sa (0,0) " +"para\n" +"makagawa ng isang maayos na spawn point, o para payagan ang\n" +"pag-zoom papalapit sa naturang punto sa pamamagitan ng pagtaas sa 'scale'.\n" +"Ginawa ang default para sa maayos na spawn point para sa\n" +"mga Mandelbrot set na may mga default na parametro,\n" +"posibleng kailangang baguhin ito sa ilang mga sitwasyon.\n" +"Mula -2 hanggang 2 ang tipikal na saklaw. I-multiply sa 'scale' para sa " +"offset sa mga node." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z) scale ng fractal sa mga node.\n" +"2 hanggang 3 beses na mas malaki ang aktwal na laki ng fractal.\n" +"Pwede sobrang laki ang mga bilang nito, hindi naman dapat\n" +"sinlaki ng mundo ang fractal.\n" +"Palakihin ito para mag-zoom sa mga detalye ng fractal.\n" +"Para sa isang hugis na inipit taas-baba ang default,\n" +"na bagay para sa mga isla, itakda ang lahat ng 3 bilang nang magkakapareho " +"para sa raw na hugis." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" +"2D noise na kumokonttol sa hugis/laki ng mga mala-gulugod na kabundukan." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2D noise na kumokontrol sa hugis/laki ng mga malalambot na burol." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2D noise na kumokontrol sa hugis/laki ng mga mala-hagdang kabundukan." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" +"2D noise na kumokontrol sa laki/paglitaw ng mga mala-gulugod na kabundukan." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D noise na kumokontrol sa laki/paglitaw ng mga malalambot na burol." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" +"2D noise na kumokontrol sa laki/paglitaw ng mga mala-hagdang kabundukan." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2D noise na nagpapakita sa mga lambak-ilog at daluyan." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Mga 3D na ulap" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D mode" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Tindi ng parallax ng 3D mode" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D noise na gumagawa sa mga malalaking kweba." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D noise na gumagawa sa istraktura at taas ng bundok.\n" +"Ito rij ang gumagawa sa istraktura ng terrain ng bundok sa mga lumulutang na " +"lupa." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"3D noise na gumagawa sa istraktura ng mga lumulutang na lupa.\n" +"Kung binago sa default, posibleng kailangang baguhin ang noise 'scale' (0.7 " +"sa default),\n" +"dahil mas maganda na kalalabasan nito kung ang noise ay may value\n" +"na nasa pagitan ng -2.0 at 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" +"3D noise na gumagawa sa istraktura ng mga dingding ng bangin sa mga ilog." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3D noise na gumagawa sa terrain." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"3D noise para sa mga overhang ng bundok, dalisdis, atbp. Madalas na maliit " +"ang mga pagbabago." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D noise na nagdedetermina sa bilang ng mga dungeon kada mapchunk." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Suporta sa 3D.\n" +"Kasalukuyang suportado:\n" +"- wala: walang 3d output.\n" +"- anaglyph: kulay cyan/magenta color na 3d.\n" +"- interlaced: linyang odd/even na nakabase sa suporta sa polarisation " +"screen.\n" +"- topbottom: hatiin ang screen taas-baba.\n" +"- sidebyside: hatiin ang screen gilid sa gilid.\n" +"- crossview: naka-cross eye na 3d\n" +"- pageflip: nakabase sa quadbuffer na 3d.\n" +"Tandaan na dapat nakabukas ang mga shader para gumana ang interlaced mode." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Piniling seed ng mapa para sa bagong mapa, ibakante para kahit ano.\n" +"Io-override kapag gumagawa ng bagong mundo sa main menu." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" +"Ipapakitang mensahe sa lahat ng mga client sakaling mag-crash ang server." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Mensaheng ipapakita sa lahat ng mga client kapag nag-shutdown ang server." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Pagitan ng ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Budget sa oras ng ABM" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Pinakalimit ng nakapilang block na lalabas" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Acceleration sa ere" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Acceleration ng gravity, sa node kada segundo kada segundo." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Mga Modifier sa Aktibong Block" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Pagitan sa management sa aktibong block" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Saklaw na aktibong block" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Saklaw na mapapadala sa aktibong bagay" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Address na kokonektahan.\n" +"Ibakante para magsimula ng lokal na server.\n" +"Tandaan na ang ino-override ng pagsasaayos na ito ang address field sa main " +"menu." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Nagdadagdag ng mga particle habang naghuhukay ng node." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Ayusin ang dpi configuration ayon sa screen mo (non X11/Android lang) hal. " +"para sa mga 4k screen." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Ayusin ang na-detect na display density, ginagamit para sa pag-scale sa mga " +"UI element." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Ayusin ang density ng layer ng lumulutang na lupa.\n" +"Pataasin ang value para pataasin ang density.\n" +"Pwedeng maging postibo o negatibo.\n" +"Value = 0.0: 50% ng volume ay lumulutang na lupa.\n" +"Value = 2.0 (o mas mataas, depende sa 'mgv7_np_floatland', palaging subukan " +"para makasiguro)\n" +"gumagawa ng solidong layer ng lumulutang na lupa." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Idagdag ang pangalan ng item" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Karagdagan" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Binabago ang kurba ng liwanag sa pamamagitan ng paglapat ng 'pagtama sa " +"gamma' dito.\n" +"Mas mataas ang value, mas maliwanag ang mga katamtaman at mabababang lebel " +"ng liwanag.\n" +"Kapag 1.0 ang value, walang mababago sa kurba ng liwanag.\n" +"Malaki ang epekto nito sa liwanag ng araw at artipisyal,\n" +"at maliit lang ang epekto nito sa natural na liwanag sa gabi." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Palaging lumipad at mabilis" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Ambient occlusion gamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Dami ng mga mensaheng pwede maipadala ng isang player kada 10 segundo." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Ina-amplify ang mga lambak." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Anisotropic filtering" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Ianunsyo ang server" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Ianunsyo sa serverlist na ito." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Idagdag ang pangalan ng item" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Idagdag ang pangalan ng item sa tooltip." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Noise ng mga puno ng mansanas" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Inertia ng braso" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Inertia ng braso, nagbibigay ng mas makatotohanang paggalaw sa\n" +"braso kapag gumagalaw ang kamera." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Tanunging kung kokonekta uli matapos mag-crash" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"Sa layong ito, agresibong iooptimisa ng server ang mga\n" +"block na ipapadala sa client.\n" +"Posibleng humusay ang performance kapag mababa ang value, pero may mga " +"makikita lang\n" +"mga glitch sa pag-render (may mga block na hindi mare-render sa\n" +"ilalim ng tubig at kweba, paminsan-minsan sa lupa rin).\n" +"Kung lagpas ang value sa max_block_send_distance,\n" +"isasara ang pag-ooptimisa.\n" +"Tinukoy sa mga mapblock (16 na node)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Key sa kusang pag-abante" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Kusang tumalon sa mga harang na isang node." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Kusang mag-ulat sa serverlist." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Kusang i-save ang laki ng screen" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Kusang mag-scale" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Aux1 key" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Aux1 key para sa pag-akyat/pagbaba" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Key sa pag-atras" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Basehang lebel ng lupa" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Basehang taas ng terrain." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Mga pribilehiyong basic" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Noise ng dalampasigan" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Threshold ng noise ng dalampasigan" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilinear filtering" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Bind address" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Mga parametro sa noise ng temperatura at halumigmig sa Biome API" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Noise ng biome" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Layo ng pag-optimisa sa pagpadala ng block" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Path ng font na bold at italic" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Path ng monospace font na bold at italic" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Path ng font na bold" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Path ng monospace font na bold" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Build sa player" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Builtin" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Palitan ang kamera" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Layo sa node ng 'near clipping plane' ng kamera, mula 0 hanggang 0.25\n" +"Gagana lang sa mga GLES platform. Hindi kailangang baguhin ito ng karamihan " +"sa mga user.\n" +"Posibleng mabawasan ang pag-artifact sa mga mahihinang GPU kapag tinaasan " +"ito.\n" +"0.1 = Default, 0.25 = Magandang value para sa mga mahihinang tablet." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Pag-smooth sa kamera" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Pag-smooth sa kamera sa cinematic mode" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Toggle key sa pag-update sa kamera" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Noise ng kweba" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Noise ng kweba #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Noise ng kweba #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Lapad ng kweba" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Cave1 noise" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Cave2 noise" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Limit ng kweba" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Noise ng kweba" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Taper ng kweba" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Threshold ng kweba" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Mataas na limit ng kweba" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Gitna ng saklaw ng boost sa kurba ng liwanag.\n" +"Kung saan 0.0 ang pinakamababang lebel ng liwanag, 1.0 naman ang " +"pinakamataas." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Threshold sa mensahe sa oras ng utos sa chat" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Mga utos sa chat" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Laki ng font ng chat" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Key ng chat" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Lebel ng pag-log sa chat" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Limit sa bilang ng mga mensahe sa chat" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Format ng mensahe sa chat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Threshold sa pagsipa sa mensahe sa chat" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Max na haba ng mensahe sa chat" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Toggle key sa chat" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Mga weblink sa chat" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Laki ng chunk" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Cinematic mode" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Key sa cinematic mode" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Malilinis na transparent na texture" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Nakabukas ang napipindot na mga weblink (gitnang pindot o Ctrl+kaliwang " +"pindot) sa chat console output." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Client" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Client at Server" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Pag-mod ng client" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Mga restriksyon sa pag-mod ng client side" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Restriksyon sa saklaw ng pagtingin sa node ng client side" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Pag-mod ng client" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Bilis ng pag-akyat" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Radius ng ulap" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Mga ulap" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Epekto sa client side ang mga ulap." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Mga ulap sa menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "May kulay na hamog" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Makukulay na anino" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Mga dekorasyon" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Antialiasing:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Mga Laro" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Ipinapakita ang HUD" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Malinis na Liwanag" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Pag-highlight sa Node" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Screen:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Mag-screenshot" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Mag-host ng Server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "- Pangalan ng Server: " + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Paglalarawan sa Server" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Port ng Server" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Pagsasaayos" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "Basic" +#~ msgstr "Basic" + +#~ msgid "Connect" +#~ msgstr "Kumonekta" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Mag-download ng laro, tulad ng Minetest Game, mula sa minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Mag-download ng isa mula sa minetest.net" + +#~ msgid "Enter " +#~ msgstr "Ipasok " + +#~ msgid "Game" +#~ msgstr "Laro" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Mga keybinding. (Kung pumalpak ang menu na ito, tanggalin ang laman ng " +#~ "minetest.conf)" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Sasali ka sa server na ito na may pangalang \"%s\" sa unang pagkakataon.\n" +#~ "Kung tutuloy ka, may magagawang bagong account sa server na ito gamit ang " +#~ "iyong mga credential.\n" +#~ "Mangyaring i-type muli ang password mo at pindutin ang 'Magparehistro at " +#~ "Sumali' para kumpirmahin ang paggawa sa account, o pindutin ang " +#~ "'Ikansela' para pigilan ito." diff --git a/po/fr/minetest.po b/po/fr/minetest.po new file mode 100644 index 0000000..815a0a4 --- /dev/null +++ b/po/fr/minetest.po @@ -0,0 +1,8412 @@ +msgid "" +msgstr "" +"Project-Id-Version: French (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-24 18:04+0000\n" +"Last-Translator: waxtatect <piero@live.ie>\n" +"Language-Team: French <https://hosted.weblate.org/projects/minetest/minetest/" +"fr/>\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Effacer la file de sortie de message du tchat" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Commande vide." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Quitter vers le menu principal" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Commande invalide : " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Commande émise : " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Liste des joueurs en ligne" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Joueurs en ligne : " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "La file de sortie de message du tchat est maintenant vide." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Cette commande est désactivée par le serveur." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Réapparaître" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Vous êtes mort" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Commandes disponibles :" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Commandes disponibles : " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Commande non disponible : " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Obtenir de l'aide pour les commandes" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Utiliser « .help <cmd> » pour obtenir plus d'informations, ou « .help all » " +"pour tout lister." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "< aucun disponible >" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Une erreur est survenue dans un script Lua :" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Une erreur est survenue :" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menu principal" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Se reconnecter" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Le serveur souhaite rétablir une connexion :" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "Une nouvelle $1 version est disponible" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "Mods client" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" +"Version installée : $1\n" +"Nouvelle version : $2\n" +"Visiter $3 pour savoir comment obtenir la nouvelle version et rester à jour " +"des fonctionnalités et des corrections de bogues." + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "Plus tard" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "Jamais" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "La version du protocole ne correspond pas. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Le serveur impose la version $1 du protocole. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Le serveur supporte les versions de protocole entre $1 et $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "Visiter le site web" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Nous supportons seulement la version du protocole $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Nous supportons seulement les versions du protocole entre $1 et $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "(Activé, a une erreur)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "(Insatisfait)" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Annuler" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Dépend de :" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Tout désactiver" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Désactiver le pack de mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Tout activer" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Activer le pack de mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Échec du chargement du mod « $1 » car il contient des caractères non " +"autorisés.\n" +"Seuls les caractères alphanumériques [a–z0–9_] sont autorisés." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Rechercher des mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod :" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Pas de dépendances (optionnelles)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Pas de description du jeu fournie." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Pas de dépendances" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Aucune description fournie pour le pack de mods." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Pas de dépendances optionnelles" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Dépendances optionnelles :" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Sauvegarder" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Monde :" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "activé" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "« $1 » existe déjà. Voulez-vous l'écraser ?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Les dépendances $1 et $2 vont être installées." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 par $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 en téléchargement,\n" +"$2 mis en attente" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "Téléchargement de $1…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "Les dépendances nécessaires à $1 n'ont pas pu être trouvées." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 sera installé, et les dépendances de $2 seront ignorées." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Tous les paquets" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Déjà installé" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Retour au menu principal" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Jeu de base :" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB n'est pas disponible quand Minetest est compilé sans cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Téléchargement…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Échec du téléchargement de $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Jeux" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Installer" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Installer $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Installer les dépendances manquantes" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Installation : type de fichier non supporté ou archive endommagée" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mods" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Aucun paquet n'a pu être récupéré" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Aucun résultat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Aucune mise à jour" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Non trouvé" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Écraser" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Veuillez vérifier que le jeu de base est correct." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "En file d'attente" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Packs de textures" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Désinstaller" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Mettre à jour" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Tout mettre à jour [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Voir plus d'informations dans un navigateur web" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Le monde « $1 » existe déjà" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Terrain supplémentaire" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Refroidissement en altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Faible humidité en altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Mélange de biomes" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomes" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Cavernes" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Grottes" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Créer" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Décorations" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "« Development Test » est destiné aux développeurs." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Donjons" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Terrain plat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Masses de terrains flottants dans le ciel" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Terrains flottants (expérimental)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Générer un terrain non fractal : océans et souterrains" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Collines" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Rivières irrigantes" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Augmente l'humidité autour des rivières" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "Installer un jeu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "Installer un autre jeu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Lacs" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Humidité basse et chaleur élevée rendent les rivières peu profondes ou sèches" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Générateur de terrain" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Drapeaux de génération de terrain" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Drapeaux spécifiques au générateur de terrain" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Montagnes" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Coulée de boue" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Réseau de tunnels et de grottes" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Aucun jeu sélectionné" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Réduit la chaleur avec l'altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Réduit l'humidité avec l'altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Rivières" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Rivières au niveau de la mer" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Graine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Transition progressive entre les biomes" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Structures apparaissant sur le sol (sans effet sur la création d'arbres et " +"d'herbes de la jungle par v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" +"Structures apparaissant sur le terrain, généralement des arbres et des " +"plantes" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Tempéré, désertique" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Tempéré, désertique, jungle" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Tempéré, désertique, jungle, toundra, taïga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Érosion du sol" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Arbres et herbes de la jungle" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Varier la profondeur fluviale" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Très grandes cavernes profondes souterraines" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nom du monde" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Vous n'avez pas de jeu installé." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Êtes-vous sûr de vouloir supprimer « $1 » ?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Supprimer" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "Gestionnaire de mods : échec de la suppression de « $1 »" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "Gestionnaire de mods : chemin invalide de « $1 »" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Supprimer le monde « $1 » ?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Confirmer le mot de passe" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "Rejoindre $1" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "Nom manquant" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nom" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Mot de passe" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "Les mots de passe ne correspondent pas" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "S'inscrire" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Accepter" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Renommer le pack de mods :" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Ce pack de mods a un nom explicitement donné dans son fichier modpack.conf " +"qui remplacera tout renommage effectué ici." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Aucune description du paramètre donnée)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Bruit 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Revenir aux paramètres" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Parcourir" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "Contenu : Jeux" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "Contenu : Mods" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Désactivé" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Modifier" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Activé" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lacunarité" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Octaves" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Décalage" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Persistance" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Veuillez entrer un nombre entier valide." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Veuillez entrer un nombre valide." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Réinitialiser" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Échelle" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Rechercher" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Choisir un répertoire" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Choisir un fichier" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Montrer les noms techniques" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "La valeur doit être au moins $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "La valeur ne doit pas être supérieure à $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Écart X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Écart Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Écart Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Valeur absolue" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "Paramètres par défaut" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "Lissé" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Activé)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mods" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Échec de l'installation de $1 vers $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Installer mod : impossible de trouver le nom réel du mod pour : $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Installer mod : impossible de trouver un nom de dossier valide pour le pack " +"de mods $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Impossible de trouver un mod ou un pack de mods valide" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Impossible d'installer un $1 comme un pack de textures" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Impossible d'installer un jeu comme un $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Impossible d'installer un mod comme un $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Impossible d'installer un pack de mods comme un $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Chargement…" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "La liste des serveurs publics est désactivée" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Essayer de réactiver la liste des serveurs et vérifier votre connexion " +"Internet." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "À propos" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Contributeurs actifs" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Moteur de rendu actif :" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Développeurs principaux" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Répertoire de données utilisateur" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Ouvre le répertoire qui contient les mondes, les jeux, les mods et les packs " +"de textures\n" +"fournis par l'utilisateur dans un gestionnaire de fichiers/explorateur." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Anciens contributeurs" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Anciens développeurs principaux" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "Partager le journal de débogage" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Parcourir le contenu en ligne" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Contenu" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Désactiver le pack de textures" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informations :" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Paquets installés :" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Pas de dépendances." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Pas de description du paquet disponible" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Renommer" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Désinstaller le paquet" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Utiliser un pack de texture" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Annoncer le serveur" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Adresse à assigner" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Mode créatif" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Activer les dégâts" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Héberger une partie" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Héberger le serveur" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Installer à partir de ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Nouveau" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Aucun monde créé ou sélectionné !" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Jouer" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Sélectionner les mods" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Sélectionner un monde :" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Port du serveur" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Démarrer" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adresse" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Effacer" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Mode créatif" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Dégâts / JcJ" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favoris" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Serveurs incompatibles" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Rejoindre une partie" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "Connexion" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Serveurs publics" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Actualiser" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "Supprimer le favori" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Description du serveur" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "(support du jeu requis)" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2×" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Nuages en 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4×" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8×" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Tous les paramètres" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Anticrénelage :" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Sauv. autom. de la taille d'écran" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Filtrage bilinéaire" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Changer les touches" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Verre unifié" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Ombres dynamiques" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "Ombres dynamiques :" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Feuilles détaillées" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Élevées" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Basses" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Moyennes" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "MIP map" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "MIP map + anisotropie" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Aucun filtre" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Sans MIP map" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Surbrillance des blocs" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Non-surbrillance des blocs" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Aucun" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Feuilles opaques" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Eau opaque" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Activer les particules" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Écran :" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Paramètres" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shaders" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shaders (expérimental)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Shaders (indisponible)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Feuilles simples" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Lumière douce" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Texturisation :" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Mappage tonal" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "Sensibilité tactile (px) :" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Filtrage trilinéaire" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "Très élevées" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Très basses" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Feuilles ondulantes" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Liquides ondulants" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Plantes ondulantes" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "Connexion interrompue (erreur de protocole ?)." + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Connexion perdue." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Terminé !" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Initialisation des blocs" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Initialisation des blocs…" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Chargement des textures…" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Reconstruction des shaders…" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Erreur de connexion (perte de connexion ?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Impossible de trouver ou charger le jeu : " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Jeu spécifié invalide." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menu principal" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Pas de monde sélectionné et pas d'adresse fournie. Rien à faire." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Nom du joueur trop long." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Veuillez choisir un nom !" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Le fichier de mot de passe fourni n'a pas pu être ouvert : " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Le chemin du monde spécifié n'existe pas : " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Voir « debug.txt » pour plus d'informations." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "– Adresse : " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "– Mode : " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "– Port : " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "– Public : " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "– JcJ : " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "– Nom du serveur : " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Une erreur de sérialisation est survenue :" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Accès refusé. Raison : %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Marche automatique désactivée" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Marche automatique activée" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Limites des blocs cachées" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Limites des blocs affichées pour tous les blocs" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Limites des blocs affichées pour le bloc actuel" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Limites des blocs affichées pour les blocs voisins" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Mise à jour de la caméra désactivée" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Mise à jour de la caméra activée" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" +"Impossible d'afficher les limites des blocs (désactivé par un jeu ou un mod)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Changer le mot de passe" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Mode cinématique désactivé" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Mode cinématique activé" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Client déconnecté" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Les scripts côté client sont désactivés" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Connexion au serveur…" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "La connexion a échoué pour une raison inconnue" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Continuer" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Contrôles :\n" +"– %s : avancer\n" +"– %s : reculer\n" +"– %s : à gauche\n" +"– %s : à droite\n" +"– %s : sauter/grimper\n" +"– %s : creuser/actionner\n" +"– %s : placer/utiliser\n" +"– %s : marcher lentement/descendre\n" +"– %s : lâcher un objet\n" +"– %s : inventaire\n" +"– Souris : tourner/regarder\n" +"– Molette souris : sélectionner un objet\n" +"– %s : tchat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Impossible de résoudre l'adresse : %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Création du client…" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Création du serveur…" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Informations de débogage et graphique du profileur cachés" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Informations de débogage affichées" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Informations de débogage, graphique du profileur et fils de fer cachés" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Touches par défaut :\n" +"Sans menu visible :\n" +"– un seul appui : touche d'activation\n" +"– double-appui : placement / utilisation\n" +"– Glissement du doigt : regarder autour\n" +"Menu / Inventaire visible :\n" +"– double-appui (en dehors) : fermeture\n" +"– objets dans l'inventaire : déplacement\n" +"– appui, glissement et appui : pose d'un seul objet par emplacement\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "La limite de vue a été activée" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "La limite de vue a été désactivée" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "Erreur de création du client : %s" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Menu principal" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Quitter le jeu" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Mode rapide désactivé" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Mode rapide activé" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Mode rapide activé (note : pas de privilège « fast »)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Mode vol désactivé" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Mode vol activé" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Mode vol activé (note : pas de privilège « fly »)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Brouillard désactivé" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Brouillard activé" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Infos de jeu :" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Jeu en pause" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Serveur hôte" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Définitions des objets…" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "Kio/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Média…" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "Mio/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Mini-carte actuellement désactivée par un jeu ou un mod" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Multijoueur" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Collisions activées" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Collisions désactivées" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Collisions activées (note : pas de privilège « noclip »)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Définitions des blocs…" + +#: src/client/game.cpp +msgid "Off" +msgstr "Désactivé" + +#: src/client/game.cpp +msgid "On" +msgstr "Activé" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Mode mouvement de tangage désactivé" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Mode mouvement de tangage activé" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Graphique du profileur affiché" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Serveur distant" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Résolution de l'adresse…" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Fermeture du jeu…" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Solo" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Volume du son" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Son coupé" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Le système audio est désactivé" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Cette compilation ne gère pas l'audio du système" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Son rétabli" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Le serveur utilise probablement une version différente de %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Impossible de se connecter à %s car IPv6 est désactivé" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Impossible d’écouter sur %s car IPv6 est désactivé" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Distance de vue réglée sur %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Distance de vue maximale : %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Distance de vue minimale : %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Volume réglé sur %d %%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Fils de fer affichés" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zoom actuellement désactivé par un jeu ou un mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Tchat caché" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Tchat affiché" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "Interface cachée" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "Interface affichée" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profileur caché" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profileur affiché (page %d1 sur %d2)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Applications" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Retour" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Verr. Maj" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Contrôle" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Bas" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Fin" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Écraser l'EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Exécuter" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Aide" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Origine" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Accepter IME" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Convertir IME" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "Échap. IME" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Changer de mode IME" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "Non converti IME" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insérer" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Gauche" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Clic gauche" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Contrôle gauche" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menu Gauche" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Maj. gauche" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Windows gauche" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Clic central" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Verr Num" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Pavé num. *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Pavé num. +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Pavé num. -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Pavé num. ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Pavé num. /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Pavé num. 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Pavé num. 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Pavé num. 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Pavé num. 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Pavé num. 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Pavé num. 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Pavé num. 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Pavé num. 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Pavé num. 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Pavé num. 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Bas de page" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Haut de page" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Jouer" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Capture d'écran" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Retour" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Droite" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Clic droit" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Contrôle droite" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menu droite" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Majuscule droit" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Windows droite" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Verr. défilement" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Sélectionner" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Maj." + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Mise en veille" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Capture d'écran" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Espace" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabulation" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Haut" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Bouton X 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Bouton X 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Mini-carte cachée" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Mini-carte en mode radar, zoom ×%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Mini-carte en mode surface, zoom ×%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Mini-carte en mode texture" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Échec de l'ouverture de la page Web" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Ouverture de la page web" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Procéder" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "« Aux1 » = descendre" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Avancer autom." + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Sauts automatiques" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Reculer" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Limites des blocs" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Changer la caméra" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Tchat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Commande" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Console" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Réd. la distance" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Réd. le volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Double-appui sur « saut » pour voler" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Lâcher" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Avancer" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Augm. la distance" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Augm. le volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventaire" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Sauter" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Touche déjà utilisée" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "Raccourcis clavier" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Commande locale" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Muet" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Objet suivant" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Objet précédent" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Distance de vue" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Capture d'écran" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Marcher lentement" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Interface" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Afficher le tchat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Mode rapide" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Voler" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Brouillard" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Mini-carte" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Mode sans collision" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Mouvement de tang." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "Appuyer sur une touche" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Changer" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nouveau mot de passe" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Ancien mot de passe" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Les mots de passe ne correspondent pas !" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Quitter" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Muet" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Volume du son : %d %%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "fr" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" +"Le nom n'est pas enregistré. Pour créer un compte sur ce serveur, cliquer " +"sur « S'inscrire »." + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "Le nom est pris. Veuillez choisir un autre nom." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Fixe la position de la manette virtuel.\n" +"Si désactivé, la manette virtuelle sera centrée sur la position du doigt " +"principal." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Utiliser la manette virtuelle pour déclencher le bouton « Aux1 ».\n" +"Si activé, la manette virtuelle va également appuyer sur le bouton « Aux1 » " +"lorsqu'en dehors du cercle principal." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) de décalage du fractal à partir du centre du monde en unités " +"« échelle ».\n" +"Peut être utilisé pour déplacer un point désiré à (0, 0) pour créer une zone " +"d'apparition convenable, ou pour autoriser à « zoomer » sur un point désiré " +"en augmentant l'« échelle ».\n" +"La valeur par défaut est adaptée pour créer une zone d'apparition convenable " +"pour les ensembles de Mandelbrot crées avec des paramètres par défaut. Elle " +"peut nécessiter une modification dans d'autres situations.\n" +"La gamme est d'environ -2 à 2. Multiplier par « échelle » pour le décalage " +"en nœuds." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"Échelle (X,Y,Z) de la fractale en nœuds.\n" +"La taille réelle de la fractale sera 2 à 3 fois plus grande.\n" +"Ces nombres peuvent être très grands, la fractale n'a pas à être contenue " +"dans le monde. Les augmenter pour « zoomer » dans les détails de la " +"fractale.\n" +"Le valeur par défaut est pour une forme verticalement écrasée convenant pour " +"une île, définir les 3 nombres égaux pour la forme brute." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Bruit 2D contrôlant la forme et taille des montagnes crantées." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Bruit 2D contrôlant la forme et la taille des collines arrondies." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Bruit 2D contrôlant la forme et taille du pas des montagnes." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "Bruit 2D contrôlant la taille/fréquence des chaînes de montagnes." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "Bruit 2D contrôlant la taille et la fréquence des collines arrondies." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "Bruit 2D contrôlant la taille et la fréquence des plateaux montagneux." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Bruit 2D qui localise les vallées et les chenaux des rivières." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Nuages 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Mode écran 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Intensité parallaxe en mode 3D" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Bruit 3D définissant les cavernes géantes." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Bruit 3D définissant la structure et la hauteur des montagnes.\n" +"Définit également la structure de terrain flottant type montagne." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Bruit 3D pour la structures des terrains flottants.\n" +"Si la valeur par défaut est changée, le bruit « d'échelle » (0,7 par défaut) " +"peut demander à être ajustée, comme l'effilage des terrains flottants " +"fonctionne mieux quand le bruit à une valeur approximativement comprise " +"entre -2,0 et 2,0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Bruit 3D définissant la structure des gorges." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Bruit 3D définissant le terrain." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"Bruit 3D pour les surplombs, falaises, etc. Généralement peu de variations." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "Bruit 3D qui détermine le nombre de donjons par tranche de carte." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Support 3D.\n" +"Actuellement supporté :\n" +"– aucun : pas de sortie 3D.\n" +"– anaglyphe : couleur 3D bleu turquoise/violet.\n" +"– entrelacé : polarisation basée sur des lignes avec support de l'écran.\n" +"– horizontal : partage haut/bas de l'écran.\n" +"– vertical : séparation côte à côte de l'écran.\n" +"– vue mixte : 3D binoculaire.\n" +"– « pageflip » : 3D basé sur « quadbuffer ».\n" +"Noter que le mode entrelacé nécessite que les shaders soient activés." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "3D" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Une graine de génération de terrain pour un nouveau monde, laisser vide pour " +"une graine aléatoire.\n" +"Sera annulé lors de la création d'un nouveau monde dans le menu." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Un message envoyé à tous les joueurs lorsque le serveur plante." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Un message envoyé à tous les joueurs lorsque le serveur s’arrête." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Intervalle « ABM »" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Budget de temps « ABM »" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Limite stricte de la file de blocs émergents" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Accélération en l'air" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Accélération de la gravité, en nœuds par seconde par seconde." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Modificateurs de bloc actif" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "intervalle de gestion des blocs actifs" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Portée des blocs actifs" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Portée des objets actifs envoyés" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Adresse où se connecter.\n" +"Laisser vide pour démarrer un serveur local.\n" +"Noter que le champ de l'adresse dans le menu principal passe outre ce " +"paramètre." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Ajoute des particules lorsqu'un bloc est creusé." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Ajuste la configuration des PPP à votre écran (non X11 / Android seulement), " +"par exemple pour les écrans 4k." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Ajuste la densité d'affichage détectée, utilisée pour la mise à l'échelle " +"des éléments de l'interface utilisateur." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Règle la densité de la couche de terrain flottant.\n" +"Augmenter la valeur pour augmenter la densité. Peut être positive ou " +"négative.\n" +"Valeur = 0,0 : 50 % du volume est terrain flottant.\n" +"Valeur = 2,0 (peut être plus élevée selon « mgv7_np_floatland », toujours " +"vérifier pour être sûr) créée une couche de terrain flottant solide." + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "Nom de l’administrateur" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avancé" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Il modifie la courbe de lumière en lui appliquant une « correction gamma ».\n" +"Des valeurs plus élevées rendent les niveaux de lumière moyens et inférieurs " +"plus lumineux.\n" +"La valeur « 1,0 » laisse la courbe de lumière intacte.\n" +"Cela n'a un effet significatif que sur la lumière du jour et la lumière " +"artificielle, elle a très peu d'effet sur la lumière naturelle nocturne." + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "Toujours voler vite" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Occlusion gamma ambiante" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Nombre de messages qu'un joueur peut envoyer en 10 secondes." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Amplifier les vallées." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Filtrage anisotrope" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Annoncer le serveur" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Annoncer à cette liste de serveurs." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Ajouter un nom d'objet" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Ajouter un nom d'objet à l'infobulle." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Bruit appliqué aux pommiers" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Inertie du bras" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Inertie du bras, donne un mouvement plus réaliste du bras lors des " +"mouvements de caméra." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Demander de se reconnecter après une coupure de connexion" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"À cette distance, le serveur va agressivement optimiser quels blocs seront " +"envoyés aux clients.\n" +"Des valeurs faibles peuvent augmenter fortement la performance du serveur, " +"mais peut provoquer l'apparition de problèmes de rendu visibles (certains " +"blocs ne seront pas affichés sous l'eau ou dans les cavernes, ou parfois sur " +"terre).\n" +"Une valeur supérieure à « max_block_send_distance » désactive cette " +"optimisation.\n" +"Établie en blocs de carte (16 nœuds)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "Audio" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Touche marche automatique" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Saute automatiquement sur les obstacles d'un bloc de haut." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Déclarer automatiquement le serveur à la liste des serveurs." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Sauvegarde automatique de la taille d'écran" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Mode d'agrandissement automatique" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Touche Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Touche Aux1 pour monter/descendre" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Touche reculer" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Niveau du sol de base" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Hauteur du terrain de base." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Privilèges de base" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Bruit des plages" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Seuil de bruit des plages" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Filtrage bilinéaire" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Adresse à assigner" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "Paramètres de bruit de l'API des biomes" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Bruit des biomes" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Distance d'optimisation d'envoi des blocs" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "Balancement" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Chemin de la police en gras et en italique" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Chemin de la police monospace en gras et en italique" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Chemin de la police en gras" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Chemin de la police monospace en gras" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Placement de bloc à la position du joueur" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Intégré" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "Caméra" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Distance de la caméra « près du plan de coupure » dans les nœuds, entre 0 et " +"0,25\n" +"Ne fonctionne que sur les plateformes GLES. La plupart des utilisateurs " +"n’auront pas besoin de changer cela.\n" +"L’augmentation peut réduire les artefacts sur des GPUs plus faibles.\n" +"0,1 = Défaut, 0,25 = Bonne valeur pour les tablettes plus faibles." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Lissage du mouvement de la caméra" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Lissage du mouvement de la caméra en mode cinématique" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Touche mise à jour de la caméra" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Bruit de grottes" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Bruit de grottes nº 1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Bruit de grottes nº 2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Largeur des grottes" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Bruit de grottes nº 1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Bruit de grottes nº 2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Limite des cavernes" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Bruit de cavernes" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Conicité des cavernes" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Seuil des cavernes" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Limite haute des cavernes" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Centre de la plage d'amplification de la courbe de lumière.\n" +"Où 0,0 est le niveau de lumière minimale, et 1,0 est le niveau de lumière " +"maximale." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Seuil de message du temps de commande du tchat" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Commandes de tchat" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Taille de la police du tchat" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Touche tchat" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Niveau du journal du tchat" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Limite du nombre de messages de tchat" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Format de message du tchat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Seuil de messages de discussion avant déconnexion forcée" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Longueur maximale d'un message de tchat" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Touche afficher le tchat" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Liens web de tchat" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Taille des tranches" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Mode cinématique" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Touche mode cinématique" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Textures transparentes filtrées" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Liens web cliquables (molette de la souris ou ctrl+clic gauche) activés dans " +"la sortie de la console de tchat." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Client" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Client et serveur" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Personnalisation client" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Restrictions du modding côté client" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Restriction de distance de recherche des noeuds côté client" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "Modding côté client" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Vitesse d'escalade du joueur" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Niveau de détails des nuages" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Nuages" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Les nuages ont un effet sur le client exclusivement." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Nuages dans le menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Brouillard coloré" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Ombres colorées" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Liste des drapeaux à cacher du dépôt des contenus.\n" +"« nonfree » peut être utilisé pour cacher les paquets non libres, comme " +"défini par la Free Software Foundation.\n" +"Vous pouvez aussi spécifier des classifications de contenu.\n" +"Ces drapeaux sont indépendants des versions de Minetest, consulter la liste " +"complète à l'adresse https://content.minetest.net/help/content_flags/." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Liste des mods de confiance séparés par des virgules qui sont autorisés à " +"accéder\n" +"aux API HTTP, leur permettant d'envoyer et de télécharger des données vers/" +"depuis Internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Liste séparée par des virgules des mods de confiance qui sont autorisés à " +"accéder aux fonctions non sécurisées même lorsque l'option de sécurisation " +"des mods est activée (via « request_insecure_environment() »)." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Touche commande" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Niveau de compression à utiliser lors de la sauvegarde des blocs de carte " +"sur le disque.\n" +"-1 - utilise le niveau de compression par défaut\n" +"0 - compression minimale, le plus rapide\n" +"9 - meilleure compression, le plus lent" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Niveau de compression à utiliser lors de l'envoi des blocs de carte au " +"client.\n" +"-1 - utilise le niveau de compression par défaut\n" +"0 - compression minimale, le plus rapide\n" +"9 - meilleure compression, le plus lent" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Verre unifié" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Se connecter à un serveur de média externe" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Unifier le verre si le bloc le permet." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Opacité de la console" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Couleur de la console" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Hauteur de la console" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "Dépôt de contenu" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Drapeaux ContentDB en liste noire" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Maximum de téléchargement en parallèle pour ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "Adresse de la ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Avancer en continu" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Mouvement continu en avant, activé par la touche d'avance automatique.\n" +"Appuyer à nouveau sur la touche d'avance automatique ou de recul pour le " +"désactiver." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Contrôles" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Contrôle la durée complet du cycle jour/nuit.\n" +"Exemples :\n" +"72 = 20 minutes, 360 = 4 minutes, 1 = 24 heures, 0 = jour/nuit/n'importe " +"quoi éternellement." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" +"Contrôle la vitesse d'immersion dans un liquide lorsque inactif. Des valeurs " +"négatives feront remonter." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Contrôle l'élévation/profondeur des dépressions lacustres." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Contrôle l'élévation/hauteur des collines." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Contrôle la largeur des tunnels, une valeur plus faible crée des tunnels " +"plus larges.\n" +"Valeur >= 10,0 désactive complètement la génération de tunnels et évite le " +"calcul intensif de bruit." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Message de plantage" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Créatif" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Opacité du réticule" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Opacité du réticule (entre 0 et 255).\n" +"Ceci s'applique également au réticule de l'objet." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Couleur du réticule" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Couleur du réticule (R,V,B).\n" +"Contrôle également la couleur du réticule de l'objet." + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "PPP" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Dégâts" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Touche infos de débogage" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Seuil de la taille du fichier journal de débogage" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Niveau du journal de débogage" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "Débogage" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Touche réduire le volume" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Intervalle de mise à jour des objets sur le serveur" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Vitesse d’accélération par défaut" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Jeu par défaut" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Jeu par défaut lors de la création d'un nouveau monde.\n" +"Sera annulé lors de la création d'un nouveau monde dans le menu." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Mot de passe par défaut" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Privilèges par défaut" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Format de rapport par défaut" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Taille d’empilement par défaut" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Définit la qualité du filtrage des ombres. Cela simule l'effet d'ombres " +"douces en appliquant un disque PCF ou Poisson mais utilise également plus de " +"ressources." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Définit des zones où les arbres ont des pommes." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Définit des zones où on trouve des plages de sable." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Définit la répartition des hauts reliefs et la pente des falaises." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Définit la répartition des zones de hauts reliefs." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Définit la taille totale des cavernes, une valeur plus petite crée des " +"cavernes plus larges." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Définit la structure des canaux fluviaux à grande échelle." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" +"Définit l'emplacement et le terrain des collines et des lacs optionnels." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Définit le niveau du sol de base." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Définit la profondeur du court de la rivière." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Détermine la distance maximale de transfert du joueur en blocs (0 = " +"illimité)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Définit la largeur des canaux fluviaux." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Définit la largeur de la vallée de la rivière." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Définit des zones avec arbres et leur densité." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Délai entre les mises à jour du maillage sur le client en ms. Augmenter ceci " +"ralentit le taux de mise à jour et réduit donc les tremblements sur les " +"client lents." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Retard dans les blocs envoyés après la construction" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Délai d'apparition des infobulles, établi en millisecondes." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Traitement d'API Lua obsolète(s)" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Profondeur en-dessous de laquelle se trouvent les grandes cavernes." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Profondeur en-dessous duquel se trouvent de grandes grottes." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Description du serveur affichée lorsque les joueurs se connectent et sur la " +"liste des serveurs." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Seuil de bruit des déserts" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Des déserts apparaissent lorsque « np_biome » dépasse cette valeur.\n" +"Quand le drapeau « snowbiomes » est activé (avec le nouveau système de " +"biomes), ce paramètre est ignoré." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Désynchroniser les animations de blocs" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "Options de développeur" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Touche creuser" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Particules au minage" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Désactiver l'anti-triche" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Refuser les mots de passe vides" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Facteur d'échelle de la densité d'affichage" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" +"Distance en nœuds à laquelle le tri de profondeur de la transparence est " +"activé.\n" +"Utiliser cette option pour limiter l'impact sur les performances du tri de " +"profondeur de la transparence." + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Nom de domaine du serveur affichée sur la liste des serveurs." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Double-appui sur « saut » pour voler" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Double-appui sur la touche « saut » pour voler." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Touche lâcher un objet" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Afficher les informations de débogage de la génération de terrain." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Maximum Y des donjons" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Minimum Y des donjons" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Bruit de donjons" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Activer la prise en charge IPv6 (pour le client et le serveur).\n" +"Requis pour que les connexions IPv6 fonctionnent." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Active le support des mods Lua sur le client.\n" +"Ce support est expérimental et l'API peut changer." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Active le filtrage par disque de Poisson.\n" +"Si activé, utilise le disque de Poisson pour créer des « ombres douces ». " +"Sinon, utilise le filtrage PCF." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Active les ombres colorées.\n" +"Sur les nœuds vraiment transparents, projette des ombres colorées. Ceci est " +"coûteux." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Activer la console" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Activer le mode créatif pour tous les joueurs." + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Activer les manettes" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "Activer les manettes. Nécessite un redémarrage pour prendre effet." + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Activer le support des canaux de mods." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Activer la sécurisation des mods" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Active les dégâts et la mort des joueurs." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" +"Active l'entrée aléatoire du joueur (seulement utilisé pour des tests)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Active l'éclairage doux avec une occlusion ambiante simple.\n" +"Désactiver pour davantage de performances ou pour un visuel différent." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "Active la séparation de connexion / s'inscrire" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Activer pour empêcher les anciens clients de se connecter.\n" +"Les anciens clients sont compatibles dans le sens où ils ne s'interrompent " +"pas lors de la connexion aux serveurs récents, mais ils peuvent ne pas " +"supporter certaines fonctionnalités." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Activer l'usage d'un serveur de média distant (si pourvu par le serveur).\n" +"Les serveurs de média distants offrent un moyen significativement plus " +"rapide de télécharger des données média (ex. : textures) lors de la " +"connexion au serveur." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Active les « vertex buffer objects ».\n" +"Cela devrait grandement augmenter les performances graphiques." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Active le balancement de la vue et la quantité de balancement de la vue.\n" +"Par exemple : 0 pour aucun balancement de la vue, 1 pour normal, 2 pour " +"double." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Active/désactive l'usage d'un serveur IPv6.\n" +"Ignoré si « bind_address » est activé.\n" +"A besoin de « enable_ipv6 » pour être activé." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Active le mappage de tons filmique « Uncharted 2 » de Hable.\n" +"Simule la courbe des tons du film photographique, ce qui se rapproche de la " +"l'apparition d'images à plage dynamique élevée. Le contraste de milieu de " +"gamme est légèrement améliorées, les reflets et les ombres sont " +"progressivement compressés." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Active la rotation des items d'inventaire." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Active la mise en cache des maillages orientés." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Active la mini-carte." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Active le système audio.\n" +"Si désactivé, cela désactive complètement tous les sons partout et les " +"commandes audio dans le jeu ne fonctionneront pas.\n" +"La modification de ce paramètre nécessite un redémarrage." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Active les compromis qui réduisent la charge du CPU ou augmentent les " +"performances de rendu au détriment de problèmes visuels mineurs qui n'ont " +"pas d'impact sur la jouabilité du jeu." + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "Profileur de moteur" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Intervalle d'impression des données du moteur de profilage" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Systèmes d'entité" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Exposant de l'effilement des terrains flottants. Modifie le comportement de " +"l'effilement.\n" +"Une valeur égale à 1 créée un effilement uniforme et linéaire.\n" +"Une valeur supérieure à 1 créée un effilement lisse adaptée pour les " +"terrains flottants séparés par défaut.\n" +"Une valeur inférieure à 1 (par exemple 0,25) créée une surface plus définie " +"avec des terrains bas plus plats, adaptée pour une couche solide de terrain " +"flottant." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "FPS" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS lorsqu’il n’est pas sélectionné ou mis en pause" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Facteur de bruit" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Facteur de balancement de chute" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Chemin de la police alternative" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Touche mode rapide" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Accélération en mode rapide" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Vitesse en mode rapide" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Mouvement rapide" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Mouvement rapide (via la touche « Aux1 »).\n" +"Nécessite le privilège « fast » sur le serveur." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Champ de vision" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Champ de vision en degrés." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Fichier dans « client/serverlist/ » contenant vos serveurs favoris affichés " +"dans l'onglet « Rejoindre une partie »." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Profondeur du remplissage" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Bruit de profondeur de remplissage" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Mappage de tons filmique" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Les textures filtrées peuvent mélanger des valeurs RVB avec des zones " +"complètement transparentes, que les optimiseurs PNG ignorent généralement, " +"aboutissant souvent à des bords foncés ou clairs sur les textures " +"transparentes.\n" +"Appliquer ce filtre pour nettoyer cela au chargement de la texture. Ceci est " +"automatiquement activé si le mip-mapping est activé." + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "Filtrage et anticrénelage" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Le premier des 4 bruits 2D qui définissent ensemble la hauteur des collines " +"et des montagnes." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Le premier des deux bruits 3D qui définissent ensemble les tunnels." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Graine de génération de terrain déterminée" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Fixer la manette virtuelle" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Densité des terrains flottants" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Maximum Y des terrains flottants" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Minimum Y des terrains flottants" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Bruit des terrains flottants" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Exposant de l'effilement des terrains flottants" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Hauteur de la base des terrains flottants" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Niveau d'eau des terrains flottants" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Touche voler" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Voler" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Brouillard" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Début du brouillard" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Touche brouillard" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "Police" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Police en gras par défaut" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Police en italique par défaut" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Ombre de la police" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Opacité de l'ombre de la police" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Taille de la police" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Taille de la police divisible par" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Taille de la police par défaut où 1 unité = 1 pixel à 96 PPP" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Taille de la police monospace où 1 unité = 1 pixel à 96 PPP" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Taille de la police des messages récents de tchat et de l'invité de tchat en " +"point (pt).\n" +"La valeur 0 utilise la taille de police par défaut." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"Pour les polices de style pixel qui ne s'adaptent pas bien, cela garantit " +"que les tailles de police utilisées avec cette police seront toujours " +"divisibles par cette valeur, en pixels. Par exemple une police de style " +"pixel de 16 pixels de haut doit avoir cette valeur définie sur 16, alors " +"elle ne sera jamais que de taille 16, 32, 48, etc., donc un mod demandant " +"une taille de 25 obtiendra 32." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Format des messages de tchat des joueurs. Substituts valides :\n" +"@name, @message, @timestamp (optionnel)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Format de captures d'écran." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Couleur de l'arrière-plan par défaut des formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Opacité de l'arrière-plan par défaut des formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Couleur de l'arrière-plan en plein écran des formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Opacité de l'arrière-plan en plein écran des formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Couleur de l'arrière-plan par défaut des formspec (R,V,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Opacité de l'arrière-plan par défaut des formspec (entre 0 et 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Couleur de l'arrière-plan en plein écran des formspec (R,V,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" +"Opacité de l'arrière-plan en plein écran des formspec (entre 0 et 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Touche avancer" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Le quatrième des 4 bruits 2D qui définissent ensemble la hauteur des " +"collines et des montagnes." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Type fractal" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" +"Fraction de la distance de vue à partir de laquelle le brouillard commence à " +"être rendu." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Distance maximale de génération des blocs depuis la position du client, " +"établie en blocs de carte (16^3 blocs)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Distance maximale d'envoi des blocs aux clients, établie en blocs de carte " +"(16^3 blocs)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Distance maximale à laquelle les clients ont connaissance des objets, " +"établie en blocs de carte (16 nœuds).\n" +"\n" +"Définir cela plus grand que « active_block_range », ainsi le serveur va " +"maintenir les objets actifs jusqu’à cette distance dans la direction où un " +"joueur regarde (cela peut éviter que des mobs disparaissent soudainement de " +"la vue)." + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Plein écran" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" +"Mode plein écran.\n" +"Un redémarrage est nécessaire après la modification de cette option." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Taille du GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Filtrage des images du GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Filtrage de mise à l'échelle txr2img du GUI" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "GUIs" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "Manettes de jeu" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "Général" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Rappels globaux" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Attributs de génération de terrain globaux.\n" +"Dans le générateur de terrain v6, le drapeau « décorations » contrôle toutes " +"les décorations sauf les arbres et les herbes de la jungle, dans tous les " +"autres générateurs de terrain, ce drapeau contrôle toutes les décorations." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Gradient de la courbe de lumière au niveau de lumière maximale.\n" +"Contrôle le contraste aux niveaux d'éclairage les plus élevés." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Gradient de la courbe de lumière au niveau de lumière minimale.\n" +"Contrôle le contraste aux niveaux d'éclairage les plus bas." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Graphiques" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "Effets graphiques" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "Graphiques et audio" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravité" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Niveau du sol" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Bruit au sol" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "Mods HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "HUD" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "Taille du HUD" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Touche HUD" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Traitement des appels d'API Lua obsolètes :\n" +"– aucun : n'enregistre pas les appels obsolètes.\n" +"– journal : imite et enregistre la trace des appels obsolètes (par défaut).\n" +"– erreur : s'interrompt lors d'un appel obsolète (recommandé pour les " +"développeurs de mods)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Auto-instrumentaliser le profileur :\n" +"* Instrumentalise une fonction vide.\n" +"La surcharge est évaluée (l'auto-instrumentalisation ajoute 1 appel de " +"fonction à chaque fois).\n" +"* Instrumentalise l’échantillonneur utilisé pour mettre à jour les " +"statistiques." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Bruit de mélange de chaleur" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Bruit de chaleur" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Composant de hauteur de la taille initiale de la fenêtre. Ignoré en mode " +"plein écran." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Bruit de hauteur" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Bruit de sélection de hauteur" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Pente des collines" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Seuil des collines" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Bruit de collines nº 1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Bruit de collines nº 2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Bruit de collines nº 3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Bruit de collines nº 4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Adresse web du serveur affichée sur la liste des serveurs." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Accélération horizontale dans l'air en sautant ou en tombant, en nœuds par " +"seconde par seconde." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Accélération horizontale et verticale en mode rapide, en nœuds par seconde " +"par seconde." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Accélération horizontale et verticale au sol ou en montée, en nœuds par " +"seconde." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Touche suivant sur la barre d'actions" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Touche précédent sur la barre d'actions" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Touche emplacement 1 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Touche emplacement 10 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Touche emplacement 11 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Touche emplacement 12 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Touche emplacement 13 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Touche emplacement 14 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Touche emplacement 15 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Touche emplacement 16 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Touche emplacement 17 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Touche emplacement 18 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Touche emplacement 19 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Touche emplacement 2 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Touche emplacement 20 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Touche emplacement 21 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Touche emplacement 22 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Touche emplacement 23 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Touche emplacement 24 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Touche emplacement 25 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Touche emplacement 26 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Touche emplacement 27 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Touche emplacement 28 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Touche emplacement 29 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Touche emplacement 3 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Touche emplacement 30 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Touche emplacement 31 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Touche emplacement 32 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Touche emplacement 4 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Touche emplacement 5 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Touche emplacement 6 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Touche emplacement 7 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Touche emplacement 8 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Touche emplacement 9 de la barre d'action" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Quelle profondeur pour faire des rivières." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Vitesse à laquelle les ondes de liquides se déplacent. Plus élevé = plus " +"rapide.\n" +"Si elle est négative, les ondes de liquides se déplaceront en arrière.\n" +"Nécessite les liquides ondulants pour être activé." + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Combien de temps le serveur attendra avant de décharger les blocs de carte " +"inutilisés, établi en secondes.\n" +"Une valeur plus élevée est plus fluide, mais utilise plus de RAM." + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" +"Ralentissement lors du déplacement dans un liquide.\n" +"Réduire ceci pour augmenter la résistance liquide au mouvement." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Quelle largeur doivent avoir les rivières." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Bruit de mélange de l'humidité" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Bruit de l'humidité" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Variation de l'humidité pour les biomes." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "Serveur IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Si les FPS (nombre d'images par seconde) sont supérieurs à cette valeur, " +"limitez-les en les mettant en sommeil pour ne pas gaspiller la puissance du " +"CPU sans aucun bénéfice." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Si désactivé, la touche « Aux1 » est utilisée pour voler vite si les modes " +"vol et rapide sont activés." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Si activé, le serveur effectuera la détermination des blocs de carte " +"invisibles selon la position des yeux du joueur.\n" +"Cela peut réduire le nombre de blocs envoyés au client de 50 à 80 %.\n" +"Le client ne recevra plus la plupart des blocs invisibles, de sorte que " +"l'utilité du mode sans collision est réduite." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Si activé avec le mode vol, le joueur sera capable de traverser les blocs " +"solides en volant.\n" +"Nécessite le privilège « noclip » sur le serveur." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Si activé, la touche « Aux1 » est utilisée à la place de la touche « Marcher " +"lentement » pour monter ou descendre." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Si activé, l'enregistrement du compte est séparé de la connexion dans " +"l'interface utilisateur.\n" +"Si désactivé, les nouveaux comptes seront enregistrés automatiquement lors " +"de la connexion." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Si activé, les actions sont enregistrés pour une restauration éventuelle.\n" +"Cette option est seulement activé quand le serveur démarre." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Si activé, cela désactive la détection anti-triche en multijoueur." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Si activé, les données invalides du monde ne causeront pas l'interruption du " +"serveur.\n" +"Activer cette option seulement si vous savez ce que vous faites." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Si activé, rend les directions de déplacement relatives à l'assiette du " +"joueur lorsqu'il vole ou nage." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Si activé, les joueurs ne peuvent pas se connecter sans un mot de passe ou " +"de le remplacer par un mot de passe vide." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Si activé, vous pourrez placer des blocs à la position où vous êtes.\n" +"C'est utile pour travailler avec des modèles « nodebox » dans des zones " +"exiguës." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Si la restriction « CSM » pour la distance des blocs est activée, les appels " +"« get_node » sont limités à la distance entre le joueur et le bloc." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Si l'exécution d'une commande de tchat prend plus de temps que cette durée " +"spécifiée en secondes, ajoute les informations de temps au message de la " +"commande de tchat." + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Si la taille du fichier « debug.txt » dépasse le nombre de mégaoctets " +"spécifié par ce paramètre ; une fois ouvert, le fichier est déplacé vers " +"« debug.txt.1 » et supprime l'ancien « debug.txt.1 » s'il existe.\n" +"« debug.txt » est déplacé seulement si ce paramètre est activé." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "Détermine les coordonnées où les joueurs vont toujours réapparaître." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ignorer les erreurs du monde" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Opacité de l'arrière-plan de la console de tchat dans le jeu (entre 0 et " +"255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Couleur de l'arrière-plan de la console de tchat dans le jeu (R,V,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"Hauteur de la console de tchat dans le jeu, entre 0,1 (10 %) et 1,0 (100 %)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Touche augmenter le volume" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Vitesse verticale initiale lors du saut, en nœuds par seconde." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Instrument d'intégration.\n" +"Ceci est habituellement nécessaire pour les contributeurs d'intégration au " +"noyau." + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "Instrument d'enregistrement des commandes de tchat." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Instrument des fonctions de rappel global enregistrées.\n" +"(tout ce que vous passez dans une fonction minetest.register_*())" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Instrumentalise la fonction d'action des modificateurs de bloc actif lors de " +"l'enregistrement." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Instrumentalise la fonction d'action des modificateurs de blocs de " +"chargement à l'enregistrement." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Instrumentalise les systèmes d'entités lors de l'enregistrement." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Intervalle de sauvegarde des changements importants dans le monde, établi en " +"secondes." + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Intervalle d'envoi de l'heure aux clients, établi en secondes." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animation des items d'inventaire" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Touche inventaire" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Inverser la souris" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Inverser les mouvements verticaux de la souris." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Chemin de la police italique" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Chemin de la police monospace en italique" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Temps de vie des entités objets" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Itérations" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Itérations de la fonction récursive.\n" +"L'augmenter, augmente la quantité de détails, mais également la charge du " +"processeur.\n" +"Quand itérations = 20 cette méthode de génération est aussi gourmande en " +"ressources que la méthode v7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID de manette" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Intervalle de répétition des boutons de la manette" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "Zone morte de la manette." + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Sensibilité tronconique de la manette" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Type de manette." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Réglage Julia uniquement.\n" +"La composante W de la constante hypercomplexe.\n" +"Modifie la forme de la fractale.\n" +"N'a aucun effet sur les fractales 3D.\n" +"Gamme d'environ -2 à 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Série Julia uniquement.\n" +"La composante X de la constante hypercomplexe.\n" +"Transforme la forme de la fractale.\n" +"Portée environ -2 à 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Série Julia uniquement.\n" +"La composante Y de la constante hypercomplexe.\n" +"Transforme la forme de la fractale.\n" +"Portée environ -2 à 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Série Julia uniquement.\n" +"La composante Z de la constante hypercomplexe.\n" +"Transforme la forme de la fractale.\n" +"Portée environ -2 à 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Touche sauter" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Vitesse de saut du joueur" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour réduire la distance d'affichage.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour réduire le volume.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour creuser.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour lâcher l'objet sélectionné.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour augmenter la distance d'affichage.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour augmenter le volume.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sauter.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour se déplacer rapidement en mode rapide.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour déplacer le joueur en arrière.\n" +"Désactive également l’avance automatique, lorsqu’elle est active.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour déplacer le joueur en avant.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour déplacer le joueur à gauche.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour déplacer le joueur à droite.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour rendre le jeu muet.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour ouvrir la fenêtre de tchat pour entrer des commandes.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour ouvrir la fenêtre de tchat pour entrer des commandes locales.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour ouvrir la fenêtre de tchat.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour ouvrir l'inventaire.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour placer.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 11ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 12ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 13ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 14ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 15ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 16ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 17ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 18ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 19ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 20ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 21ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 22ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 23ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 24ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 25ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 26ᵉ case des la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 27ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 28ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 29ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 30ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 31ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la 32ᵉ case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la huitième case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la cinquième case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la première case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la quatrième case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner l'objet suivant dans la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la neuvième case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner l'objet précédent dans la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la deuxième case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la septième case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la sixième case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la dixième case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour sélectionner la troisième case de la barre d'action.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour se déplacer lentement.\n" +"Également utilisée pour descendre et plonger dans l'eau si « aux1_descends » " +"est désactivé.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour changer de vue entre la première et troisième personne.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour prendre des captures d'écran.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche d'avance automatique.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour passer en mode cinématique.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour afficher/cacher la mini-carte.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour passer en mode rapide.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour voler.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour passer en mode sans collision.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour passer en mode mouvement de tangage.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche de mise à jour de la caméra. Seulement utilisé pour le " +"développement.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour afficher/cacher la zone de tchat.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour afficher/cacher les infos de débogage.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour afficher/cacher le brouillard.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour afficher/masquer le HUD (affichage tête haute).\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour afficher/cacher la grande console de tchat.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour afficher/cacher le profileur. Utilisé pour le développement.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour activer/désactiver la distance de vue illimitée.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Touche pour zoomer si possible.\n" +"Voir http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "Clavier et souris" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" +"Expulser les joueurs qui ont envoyé plus de X messages sur 10 secondes." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Pic du lac" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Seuil de lacs" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Langue" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Profondeur de grandes grottes" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Nombre maximal de grandes grottes" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Nombre minimal de grandes grottes" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Proportion de grandes grottes inondées" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Touche grande console de tchat" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Apparence des feuilles" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Apparence des feuilles d’arbres :\n" +"– Détaillée : toutes les faces sont visibles\n" +"– Simple : seulement les faces externes, si des « special_tiles » sont " +"définies\n" +"– Opaque : désactive la transparence" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Touche gauche" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Durée d'intervalle serveur et intervalle auquel les objets sont généralement " +"mis à jour sur le réseau, établie en secondes." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Longueur des ondes de liquides.\n" +"Nécessite les liquides ondulants pour être activé." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" +"Durée entre les cycles d’exécution du Modificateur de Bloc Actif (« ABM »), " +"établie en secondes." + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Durée entre les cycles d’exécution « NodeTimer », établie en secondes." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" +"Durée entre les cycles de gestion des blocs actifs, établie en secondes." + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Niveau de journalisation à écrire dans « debug.txt » :\n" +"– < rien > (pas de journalisation)\n" +"– aucun (messages sans niveau)\n" +"– erreur\n" +"– avertissement\n" +"– action\n" +"– info\n" +"– prolixe\n" +"– traçage" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Amplification de la courbe de lumière" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Centre d'amplification de la courbe de lumière" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Étalement de l'amplification de la courbe de lumière" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Gamma de la courbe de lumière" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Fort gradient de la courbe de lumière" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Faible gradient de la courbe de lumière" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "Lumière" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Limite du générateur de terrain, en nœuds, dans les 6 directions à partir de " +"(0,0,0).\n" +"Seules les tranches de la carte totalement comprises dans cette limite sont " +"générées.\n" +"Valeur différente pour chaque monde." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Nombre limite de requête HTTP en parallèle. Affecte :\n" +"– L'obtention de média si le serveur utilise le paramètre « remote_media ».\n" +"– Le téléchargement de la liste des serveurs et l'annonce du serveur.\n" +"– Les téléchargements effectués par le menu (ex. : gestionnaire de mods).\n" +"Prend seulement effet si Minetest est compilé avec cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Fluidité des liquides" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Régularité de la fluidité des liquides" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Itérations maximales pendant la transformation des liquides" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Délais de nettoyage d'une file de liquide" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Écoulement du liquide" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Intervalle de mise à jour des liquides en secondes." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Intervalle de mise à jour des liquides" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Charger le profileur du jeu" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Charge le profileur du jeu pour collecter des données de profilage du jeu.\n" +"Fournit une commande « /profiler » pour accéder au profil compilé.\n" +"Utile pour les développeurs de mod et les opérateurs de serveurs." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Chargement des modificateurs de blocs" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Limite basse Y des donjons." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Limite basse Y des terrains flottants." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Script du menu principal" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Rendre la couleur du brouillard et du ciel différents selon l'heure du jour " +"(aube/crépuscule) et la direction du regard." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Rend toutes les liquides opaques." + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Niveau de compression des cartes pour le stockage sur disque" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Niveau de compression de la carte pour le transfert réseau" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Répertoire de la carte du monde" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Attributs spécifiques au générateur de terrain carpatien." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Attributs spécifiques au générateur de terrain plat.\n" +"Des lacs et des collines peuvent être occasionnellement ajoutés au monde " +"plat." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Attributs spécifiques au générateur de terrain fractal.\n" +"« terrain » active la création de terrains non fractals : océans, îles et " +"souterrains." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Attributs spécifiques au générateur de terrain vallées.\n" +"« altitude_chill » : réduit la chaleur avec l’altitude.\n" +"« humid_rivers » : augmente l’humidité autour des rivières.\n" +"« vary_river_dept » : si activé, une humidité basse et une chaleur élevée " +"rendent les rivières moins profondes et parfois sèches.\n" +"« altitude_dry » : réduit l’humidité avec l’altitude." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Attributs spécifiques au générateur de terrain v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Attributs spécifiques au générateur de terrain v6.\n" +"Le drapeau « snowbiomes » active le nouveau système à 5 biomes.\n" +"Lorsque le drapeau « snowbiomes » est activé, les jungles sont " +"automatiquement activées et le drapeau « jungles » est ignoré." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Attributs spécifiques au générateur de terrain v7.\n" +"« montagnes » : montagnes.\n" +"« crêtes » : rivières.\n" +"« terrains flottants » : vaste terrain flottant dans l'atmosphère.\n" +"« cavernes » : cavernes immenses souterraines profondes." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Limite de génération du terrain" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Intervalle de sauvegarde de la carte" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "Images de mise à jour des ombres de la carte" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Limite des blocs de carte" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Délai de génération des maillages de blocs de carte" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Taille du cache de blocs de carte en Mo du générateur de maillage" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Délai d'interruption du déchargement de blocs de carte" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Générateur de terrain carpatien" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Drapeaux spécifiques au générateur de terrain carpatien" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Générateur de terrain plat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Drapeaux spécifiques au générateur de terrain plat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Générateur de terrain fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Drapeaux spécifiques au générateur de terrain fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Générateur de terrain v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Drapeaux spécifiques au générateur de terrain v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Générateur de terrain v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Drapeaux spécifiques au générateur de terrain v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Générateur de terrain v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Drapeaux spécifiques au générateur de terrain v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Générateur de terrain vallées" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Drapeaux spécifiques au générateur de terrain vallées" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Débogage de la génération de terrain" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Nom du générateur de terrain" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Distance maximale de génération de blocs" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Distance maximale d'envoi de blocs" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Maximum de liquides traités par étape de serveur." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Blocs supplémentaires maximum de « clearobjects »" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Paquets maximaux par itération" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "FPS maximum" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"FPS maximum lorsque la fenêtre n'est pas sélectionnée, ou lorsque le jeu est " +"en pause." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Distance maximale pour le rendu des ombres." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Blocs maximum chargés de force" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Largeur maximale de la barre d'inventaire" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" +"Limite maximale du nombre aléatoire de grandes grottes par tranche de carte." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" +"Limite maximale du nombre aléatoire de petites grottes par tranche de carte." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Résistance maximale aux liquides. Contrôle la décélération lorsqu'un joueur " +"entre dans un liquide à haute vitesse." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Le nombre maximal de blocs envoyés simultanément par client.\n" +"Le compte total maximal est calculé dynamiquement :\n" +"max_total = ceil((nombre clients + max_users) × per_client ÷ 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" +"Nombre maximal de blocs qui peuvent être mis en file d'attente pour " +"chargement." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Nombre maximal de blocs à mettre en file d'attente qui doivent être " +"générés.\n" +"Cette limite est appliquée par joueur." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Nombre maximal de blocs à mettre en file d'attente qui doivent être chargés " +"depuis un fichier.\n" +"Cette limite est appliquée par joueur." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Nombre maximal de téléchargements simultanés. Les téléchargements dépassant " +"cette limite seront mis en file d'attente.\n" +"Ce nombre doit être inférieur à la limite de « curl_parallel_limit »." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Nombre maximal de blocs de carte chargés de force." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Nombre maximal de blocs de carte pour le client à garder en mémoire.\n" +"Définir à -1 pour un montant illimité." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Nombre maximal de paquets envoyés par étape d'envoi. Si vous avez une " +"connexion lente, essayer de réduire cette valeur, mais ne pas réduire cette " +"valeur en-dessous du double du nombre de clients maximum sur le serveur." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Nombre maximal de joueurs qui peuvent être connectés en même temps." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Nombre maximal de message récent à afficher." + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" +"Nombre maximal d'objets sauvegardés dans un bloc de carte (16^3 blocs)." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Nombre maximal d'objets par bloc" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Proportion maximale de la fenêtre à utiliser pour la barre d'inventaire.\n" +"Utile quand il y a quelque chose à afficher à gauche ou à droite de la barre." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Nombre maximal de blocs simultanés envoyés par client" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Taille maximale de la file de sortie de message du tchat" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Taille maximale de la file de sortie de message du tchat.\n" +"0 pour désactiver la file de sortie et -1 pour rendre la taille de la file " +"de sortie illimitée." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Durée maximale qu'un téléchargement de fichier (ex. : un téléchargement de " +"mod) peut prendre, établie en millisecondes." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Durée maximale qu'une requête interactive (ex. : récupération de la liste de " +"serveurs) peut prendre, établie en millisecondes." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Joueurs maximums" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Mise en cache des maillages" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Message du jour" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Message du jour affiché aux joueurs lors de la connexion." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Méthodes utilisées pour l'éclairage des objets." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Niveau minimal de journalisation à écrire dans le tchat." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Mini-carte" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Touche mini-carte" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Hauteur de balayage de la mini-carte" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" +"Limite minimale du nombre aléatoire de grandes grottes par tranche de carte." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" +"Limite minimale du nombre aléatoire de petites grottes par tranche de carte." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Taille minimale des textures" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mip-mapping" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "Divers" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "Profileur des mods" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "Sécurité des mods" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Canaux de mods" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Modifie la taille des éléments de l'interface." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Chemin de la police monospace" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Taille de la police monospace" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "Taille de la police monospace divisible par" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Bruit de hauteur des montagnes" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Bruit des montagnes" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Bruit de variation des montagnes" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Niveau de base des montagnes" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Sensibilité de la souris" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Facteur de sensibilité de la souris." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Bruit de boue" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Facteur de balancement de chute.\n" +"Par exemple : 0 pour aucun balancement de la vue, 1 pour normal, 2 pour " +"double." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Touche muet" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Couper le son" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Nom du générateur de terrain qui sera utilisé à la création d’un nouveau " +"monde.\n" +"La création d'un monde depuis le menu principal le remplacera.\n" +"Les générateurs de terrain actuellement très instables sont :\n" +"– Les terrains flottants optionnels du générateur v7 (désactivé par défaut)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Nom du joueur.\n" +"Lorsqu'un serveur est lancé, les clients se connectant avec ce nom sont " +"administrateurs.\n" +"Lors du démarrage à partir du menu principal, celui-ci est remplacé." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Nom du serveur affiché lorsque les joueurs se connectent et sur la liste des " +"serveurs." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Plan à proximité" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Port du réseau à écouter (UDP).\n" +"Cette valeur est annulée en commençant depuis le menu." + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "Réseau" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Les nouveaux joueurs ont besoin d'entrer ce mot de passe." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Sans collision" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Touche mode sans collision" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "Surbrillance des blocs et des entités" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Surbrillance des blocs" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Intervalle « NodeTimer »" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Bruits" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Nombre de tâches en cours" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Nombre de processus « emerge » à utiliser.\n" +"Valeur 0 :\n" +"– Sélection automatique. Le nombre de processus sera le\n" +"– « nombre de processeurs - 2 », avec un minimum de 1.\n" +"Toute autre valeur :\n" +"– Spécifie le nombre de processus, avec un minimum de 1.\n" +"ATTENTION : augmenter le nombre de processus « emerge » accélère bien la\n" +"création de terrain, mais cela peut nuire à la performance du jeu en " +"interférant\n" +"avec d’autres processus, en particulier en mode solo et/ou lors de " +"l’exécution de\n" +"code Lua en mode « on_generated ». Pour beaucoup, le réglage optimal peut " +"être « 1 »." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Nombre de blocs supplémentaires qui peuvent être chargés par « /" +"clearobjects » à la fois.\n" +"C'est un compromis entre la surcharge de transaction SQLite et la " +"consommation mémoire\n" +"(4096 = 100 Mo, comme règle générale)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Liquides opaques" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" +"Opacité (alpha) de l'ombre derrière la police par défaut, entre 0 et 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Ouvre le menu pause lorsque la sélection de la fenêtre est perdue. Ne met " +"pas en pause si un formspec est ouvert." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Remplacement optionnel pour la couleur du lien web du tchat." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Chemin de la police alternative. Doit être une police TrueType.\n" +"Cette police sera utilisée pour certaines langues ou si la police par défaut " +"est indisponible." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Chemin pour enregistrer les captures d'écran (absolu ou relatif).\n" +"La création du dossier sera faite si besoin." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Répertoire des shaders. Si le chemin n'est pas défini, le chemin par défaut " +"est utilisé." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" +"Chemin vers le dossier des textures. Toutes les textures sont d'abord " +"cherchées dans ce dossier." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Chemin de la police par défaut. Doit être une police TrueType.\n" +"La police alternative sera utilisée si la police ne peut pas être chargée." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Chemin de la police monospace. Doit être une police TrueType.\n" +"Cette police est utilisée par exemple pour la console et l’écran du " +"profileur." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Mettre en pause sur perte de sélection de la fenêtre" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "Limite par joueur de blocs en attente à charger depuis le disque" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Limite par joueur de la file de blocs à générer" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Physique" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Touche mouvement de tangage" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Mode mouvement de tangage" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Touche placer" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Intervalle de répétition du placement" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Le joueur est capable de voler sans être affecté par la gravité.\n" +"Nécessite le privilège « fly » sur le serveur." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Distance de transfert du joueur" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Joueur contre joueur" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Filtrage de Poisson" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Port où se connecter (UDP).\n" +"Noter que le champ de port dans le menu principal passe outre ce paramètre." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Empêche le minage et le placement de se répéter lors du maintien des boutons " +"de la souris.\n" +"Activer cette option lorsque vous creusez ou placez trop souvent par " +"accident." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Empêcher les mods d'exécuter des fonctions insécurisées (comme des commandes " +"système)." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Affiche les données de profilage du moteur à intervalles réguliers (en " +"secondes).\n" +"0 = désactivé. Utile pour les développeurs." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" +"Les privilèges que les joueurs avec le privilège « basic_privs » peuvent " +"accorder." + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Profileur" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Touche profilage" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Adresse d'écoute pour Prometheus" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Adresse d'écoute pour Prometheus.\n" +"Lorsque Minetest est compilé avec l'option « ENABLE_PROMETHEUS », cette " +"adresse est utilisée pour l'écoute de données pour Prometheus.\n" +"Les métriques peuvent être récupérées sur http://127.0.0.1:30000/metrics." + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Proportion de grandes grottes qui contiennent du liquide." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Rayon de la zone de nuages établi en nombre de 64 blocs de nuages carrés.\n" +"Les valeurs plus grandes que 26 entraînent une coupure nette des nuages aux " +"coins des zones de nuages." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Élève le terrain pour former des vallées autour des rivières." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Entrée aléatoire" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Touche distance d'affichage illimitée" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Messages de discussion récents" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Chemin de la police par défaut" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Média distant" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Port distant" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Supprime les codes couleurs venant des messages du tchat.\n" +"Utiliser cette option pour empêcher les joueurs d’utiliser la couleur dans " +"leurs messages." + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Remplace le menu par défaut par un menu personnalisé." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Chemin du rapport" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Limite l'accès de certaines fonctions côté client sur les serveurs.\n" +"Combiner les « byteflags » ci dessous pour restreindre les fonctionnalités " +"client, ou mettre 0 pour laisser sans restriction :\n" +"LOAD_CLIENT_MODS : 1 (désactive le chargement des mods client)\n" +"CHAT_MESSAGES : 2 (désactive l'appel « send_chat_message côté » client)\n" +"READ_ITEMDEFS : 4 (désactive l'appel « get_item_def côté » client)\n" +"READ_NODEDEFS : 8 (désactive l'appel « get_node_def » côté client)\n" +"LOOKUP_NODES_LIMIT : 16 (limite l'appel « get_node » côté client à « " +"csm_restriction_noderange »)\n" +"READ_PLAYERINFO : 32 (désactive l'appel « get_player_names » côté client)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Bruit pour l'espacement des crêtes de montagnes" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Bruit des crêtes" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Bruit des crêtes sous l'eau" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Bruit de la taille des crêtes de montagnes" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Touche droite" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Profondeur des rivières" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Largeur des rivières" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Profondeur des rivières" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Bruit des rivières" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Taille des rivières" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Largeur des vallées fluviales" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Enregistrement des actions" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Taille du bruit des collines arrondies" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Étalement du bruit de collines arrondies" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Mini-carte circulaire" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Minage et placement sécurisés" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" +"Des plages de sables apparaissent lorsque « np_beach » dépasse cette valeur." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Sauvegarde le monde du serveur sur le disque dur du client." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" +"Sauvegarde automatiquement la taille de la fenêtre quand elle est modifiée." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Sauvegarde de la carte reçue du serveur" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Met à l'échelle l'interface par une valeur spécifiée par l'utilisateur, à " +"l'aide d'un filtre au plus proche voisin avec anticrénelage.\n" +"Cela va lisser certains bords grossiers, et mélanger les pixels en réduisant " +"l'échelle au détriment d'un effet de flou sur des pixels en bordure quand " +"les images sont mises à l'échelle par des valeurs fractionnelles." + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "Écran" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Hauteur de la fenêtre" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Largeur de la fenêtre" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Dossier des captures d'écran" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Format des captures d'écran" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Qualité des captures d'écran" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Qualité de capture d'écran. Utilisé uniquement pour le format JPEG.\n" +"1 signifie mauvaise qualité ; 100 signifie la meilleure qualité.\n" +"Utiliser 0 pour la qualité par défaut." + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "Captures d'écran" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Bruit des fonds marins" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Deuxième des 4 bruits 2D qui définissent ensemble la hauteur des collines et " +"des montagnes." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Deuxième des deux bruits 3D qui définissent ensemble les tunnels." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Voir http://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Couleur des bords de sélection (R,V,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Couleur des bords de sélection" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Epaisseur des bords de sélection" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Choisit parmi 18 types de fractales.\n" +"1 = réglage Mandelbrot « Roundy » 4D.\n" +"2 = réglage Julia « Roundy » 4D.\n" +"3 = réglage Mandelbrot « Squarry » 4D.\n" +"4 = réglage Julia « Squarry » 4D.\n" +"5 = réglage Mandelbrot « Cousin Mandy » 4D.\n" +"6 = réglage Julia « Cousin Mandy » 4D.\n" +"7 = réglage Mandelbrot « Variation » 4D.\n" +"8 = réglage Julia « Variation » 4D.\n" +"9 = réglage Mandelbrot « Mandelbrot/Mandelbar » 3D.\n" +"10 = réglage Julia « Mandelbrot/Mandelbar » 3D.\n" +"11 = réglage Mandelbrot « Christmas Tree » 3D.\n" +"12 = réglage Julia « Christmas Tree » 3D.\n" +"13 = réglage Mandelbrot « Mandelbulb » 3D.\n" +"14 = réglage Julia « Mandelbulb » 3D.\n" +"15 = réglage Mandelbrot « Cosine Mandelbulb » 3D.\n" +"16 = réglage Julia « Cosine Mandelbulb » 3D.\n" +"17 = réglage Mandelbrot « Mandelbulb » 4D.\n" +"18 = réglage Julia « Mandelbulb » 4D." + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "Serveur" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "Jeu du serveur" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "Sécurité du serveur" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL du serveur" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Adresse du serveur" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Description du serveur" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Nom du serveur" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Port du serveur" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Détermination des blocs invisibles côté serveur" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "Performance du serveur" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL de la liste des serveurs" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "Liste des serveurs et message du jour" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Fichier de la liste des serveurs" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Définit la langue. Laisser vide pour utiliser la langue du système.\n" +"Un redémarrage est nécessaire après cette modification." + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Définit la longueur maximale d'un message de tchat (en caractères) envoyé " +"par les clients." + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Définit l'intensité gamma de l'ombre.\n" +"Ajuste l’intensité des ombres dynamiques dans le jeu.\n" +"Une valeur plus faible signifie des ombres plus claires, une valeur plus " +"élevée signifie des ombres plus sombres." + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Définit la taille du rayon de l'ombre douce.\n" +"Les valeurs les plus faibles signifient des ombres plus nettes, les valeurs " +"les plus élevées des ombres plus douces.\n" +"Valeur minimale : 1,0 ; valeur maximale : 15,0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Définit l'inclinaison de l'orbite du soleil / lune en degrés.\n" +"La valeur de 0 signifie aucune inclinaison / orbite verticale.\n" +"Valeur minimale : 0,0 ; valeur maximale : 60,0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Mettre sur « Activé » active le « Shadow Mapping ».\n" +"Nécessite les shaders pour être activé." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Mettre sur « Activé » active les feuilles ondulantes.\n" +"Nécessite les shaders pour être activé." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Mettre sur « Activé » active les liquides ondulants (comme l'eau).\n" +"Nécessite les shaders pour être activé." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Mettre sur « Activé » active le mouvement des végétaux.\n" +"Nécessite les shaders pour être activé." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Définit la qualité de la texture de l'ombre sur 32 bits.\n" +"Si désactivé, une texture de 16 bits sera utilisée.\n" +"Cela peut causer beaucoup plus d'artefacts sur l'ombre." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Chemin des shaders" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Les shaders permettent des effets visuels avancés et peuvent améliorer les " +"performances sur certaines cartes graphiques.\n" +"Fonctionne seulement avec OpenGL." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Qualité du filtre d’ombre" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" +"Distance maximale de la carte des ombres en nœuds pour le rendu des ombres" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "Texture de la carte des ombres en 32 bits" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Taille de la texture de la carte des ombres" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Décalage de l'ombre de la police par défaut (en pixel). Aucune ombre si la " +"valeur est 0." + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "Intensité gamma de l'ombre" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Forme de la mini-carte. Activé = ronde, désactivé = carrée." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Afficher les infos de débogage" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Afficher les boîtes de sélection de l'entité" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Afficher les boîtes de sélection de l'entité\n" +"Un redémarrage est nécessaire après cette modification." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Afficher l'arrière-plan des badges par défaut" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Message d'arrêt" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Taille des tranches de carte générés à la création de terrain, établie en " +"blocs de carte (16 nœuds).\n" +"ATTENTION ! : Il n’y a aucun avantage, et plusieurs dangers, à augmenter " +"cette valeur au-dessus de 5.\n" +"Réduire cette valeur augmente la densité de cavernes et de donjons.\n" +"La modification de cette valeur est réservée à un usage spécial. Il est " +"conseillé de la laisser inchangée." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Taille du cache de blocs de carte du générateur de maillage. Augmenter ceci " +"augmente le % d'interception du cache et réduit la copie de données dans le " +"fil principal, réduisant les tremblements." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Inclinaison de l'orbite du corps du ciel" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Largeur de part" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" +"La pente et le remplissage fonctionnent ensemble pour modifier les hauteurs." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Nombre maximal de petites grottes" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Nombre minimal de petites grottes" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" +"Variation de l'humidité de petite échelle pour la transition entre les " +"biomes." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" +"Variation de température de petite échelle pour la transition entre les " +"biomes." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Lumière douce" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Lisse les mouvements de la caméra en se déplaçant et en regardant autour. " +"Également appelé « look smoothing » ou « mouse smoothing ».\n" +"Utile pour enregistrer des vidéos." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "Lisse la rotation de la caméra en mode cinématique. 0 pour désactiver." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Lisse la rotation de la caméra. 0 pour désactiver." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Touche déplacement lent" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Vitesse de déplacement lent" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Vitesse de déplacement lent, en nœuds par seconde." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Rayon de l'ombre douce" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Audio" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Spécifie l'URL à laquelle les clients obtiennent les fichiers média au lieu " +"d'utiliser le port UDP.\n" +"$filename doit être accessible depuis $remote_media$filename via cURL " +"(évidemment, remote_media devrait se terminer avec un slash).\n" +"Les fichiers qui ne sont pas présents seront récupérés de la manière " +"habituelle." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Donne les valeurs par défaut de la taille des piles de nœuds, d'items et " +"d'outils.\n" +"Les mods ou les parties peuvent fixer explicitement une pile pour certains " +"items." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Répartit une mise à jour complète de la carte des ombres sur un nombre donné " +"d'images.\n" +"Des valeurs plus élevées peuvent rendre les ombres plus lentes, des valeurs " +"plus faibles consommeront plus de ressources.\n" +"Valeur minimale : 1 ; valeur maximale : 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Longueur d'intervalle de l'amplification de la courbe de lumière.\n" +"Contrôle la largeur de l'intervalle d'amplification.\n" +"Écart type de la gaussienne d'amplification de courbe de lumière." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Point d'apparition statique" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Bruit des pentes" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Bruit de la taille des montagnes en escalier" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Bruit d'étalement des montagnes en escalier" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Intensité de parallaxe en mode 3D." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Niveau d'amplification de la courbure de la lumière.\n" +"Les trois paramètres « d'amplification » définissent un intervalle de la " +"courbe de lumière pour lequel la luminosité est amplifiée." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Vérification stricte du protocole" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Supprimer les codes couleurs" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Niveau de la surface de l'eau (optionnel) placée sur une couche solide de " +"terrain flottant.\n" +"L'eau est désactivée par défaut et ne sera placée que si cette valeur est " +"définie à plus de « mgv7_floatland_ymax » - « mgv7_floatland_taper » (début " +"de l’effilage du haut).\n" +"***ATTENTION, DANGER POTENTIEL AU MONDES ET AUX PERFORMANCES DES " +"SERVEURS*** :\n" +"Lorsque le placement de l'eau est activé, les terrains flottants doivent " +"être configurés et vérifiés pour être une couche solide en mettant " +"« mgv7_floatland_density » à 2,0 (ou autre valeur dépendante de " +"« mgv7_np_floatland »), pour éviter les chutes d'eaux énormes qui " +"surchargent les serveurs et pourraient inonder les terres en dessous." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "SQLite synchronisé" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Variation de température pour les biomes." + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "Paramètres temporaires" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Bruit alternatif de terrain" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Bruit de terrain de base" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Hauteur du terrain" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Bruit de hauteur du terrain" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Bruit de terrain" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Seuil du bruit de relief pour les collines.\n" +"Contrôle la proportion sur la zone d'un monde recouvert de collines.\n" +"Ajuster vers 0,0 pour une plus grande proportion." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Seuil du bruit de relief pour les lacs.\n" +"Contrôle la proportion sur la zone d'un monde recouvert de lacs.\n" +"Ajuster vers 0,0 pour une plus grande proportion." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Bruit de persistance du terrain" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Chemin des textures" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Taille de la texture pour le rendu de la carte des ombres.\n" +"Il doit s'agir d'une puissance de deux.\n" +"Les nombres plus grands créent de meilleures ombres, mais ils sont aussi " +"plus coûteux." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Les textures sur un nœud peuvent être alignées soit sur le nœud, soit sur le " +"monde. Le premier mode convient mieux aux choses comme des machines, des " +"meubles, etc., tandis que le second rend les escaliers et les microblocs " +"mieux adaptés à l'environnement. Cependant, comme cette possibilité est " +"nouvelle, elle ne peut donc pas être utilisée par les anciens serveurs, " +"cette option permet de l'appliquer pour certains types de nœuds. Noter " +"cependant que c'est considéré comme EXPÉRIMENTAL et peut ne pas fonctionner " +"correctement." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "L'URL du dépôt de contenu." + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "La zone morte de la manette" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Le format par défaut dans lequel les profils sont enregistrés, lors de " +"l'appel de « /profiler save [format] » sans format." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" +"La profondeur de la terre ou autre matériau de remplissage dépendant du " +"biome." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"Le chemin d'accès au fichier relatif au monde dans lequel les profils seront " +"sauvegardés." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "L'identifiant de la manette à utiliser." + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"La longueur en pixels qu'il faut pour que l'interaction avec l'écran tactile " +"commence." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"La hauteur maximale de la surface des liquides ondulants.\n" +"4,0 - La hauteur des vagues est de deux blocs.\n" +"0,0 - La vague ne bouge pas du tout.\n" +"Par défaut est de 1,0 (1/2 bloc).\n" +"Nécessite les liquides ondulants pour être activé." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "L'interface réseau que le serveur écoute." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Les privilèges que les nouveaux joueurs obtiennent automatiquement.\n" +"Entrer « /privs » dans le jeu pour voir une liste complète des privilèges." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"Le rayon du volume de blocs autour de chaque joueur soumis au bloc actif, " +"établi en blocs de carte (16 nœuds).\n" +"Dans les blocs actifs, les objets sont chargés et les « ABMs » sont " +"exécutés.\n" +"C'est également la distance minimale dans laquelle les objets actifs (mobs) " +"sont conservés.\n" +"Ceci devrait être configuré avec « active_object_send_range_blocks »." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"Le moteur de rendu.\n" +"Un redémarrage est nécessaire après cette modification.\n" +"Remarque : Sur Android, rester avec OGLES1 en cas de doute ! Autrement, " +"l'application peut ne pas démarrer.\n" +"Sur les autres plateformes, OpenGL est recommandé.\n" +"Les shaders sont pris en charge par OpenGL (ordinateur de bureau uniquement) " +"et OGLES2 (expérimental)." + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"Sensibilité des axes de la manette pour déplacer la vue en jeu autour du " +"tronc." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"Intensité (obscurité) de l'ombrage des blocs avec l'occlusion ambiante.\n" +"Les valeurs plus basses sont plus sombres, les valeurs plus hautes sont plus " +"claires.\n" +"Une gamme valide de valeurs pour ceci se situe entre 0,25 et 4,0. Si la " +"valeur est en dehors de cette gamme alors elle sera définie à la plus proche " +"des valeurs valides." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Le temps (en secondes) où la file des liquides peut s'agrandir au-delà de sa " +"capacité de traitement jusqu'à ce qu'une tentative soit faite pour réduire " +"sa taille en vidant l'ancienne file d'articles.\n" +"Une valeur de 0 désactive cette fonctionnalité." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"Budget de temps alloué aux « ABMs » pour s'exécuter à chaque étape (en " +"fraction de l'intervalle « ABM »)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Le temps en secondes qu'il faut entre des événements répétés lors de l'appui " +"d'une combinaison de boutons de la manette." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Le temps en secondes qu'il faut entre des placements de blocs répétés lors " +"de l'appui sur le bouton de placement." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Le type de manette" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"La distance verticale sur laquelle la chaleur diminue de 20 si " +"« altitude_chill » est activé. Également la distance verticale sur laquelle " +"l’humidité diminue de 10 si « altitude_dry » est activé." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Le troisième des 4 bruits 2D qui définissent ensemble la hauteur des " +"collines et des montagnes." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Temps en secondes pour les entités objets (objets lâchés) à exister.\n" +"Définir à -1 pour désactiver cette fonctionnalité." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" +"Heure de la journée lorsqu'un nouveau monde est créé, en milliheures (0–" +"23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Intervalle d'envoi du temps" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Vitesse du temps" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Délai d'interruption pour le client pour supprimer les données de carte " +"inutilisées de la mémoire, établi en secondes." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Pour réduire le décalage, le transfert des blocs est ralenti quand un joueur " +"construit quelque chose.\n" +"Cela détermine la durée du ralentissement après placement ou destruction " +"d'un nœud." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Touche basculer en mode caméra" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Délai d'apparition des infobulles" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Sensibilité de l'écran tactile" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "Écran tactile" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "Compromis pour la performance" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "Distance de tri de la transparence" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Bruit des arbres" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Filtrage trilinéaire" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"Activé = 256\n" +"Désactive = 128\n" +"Utile pour rendre la mini-carte plus fluide sur des ordinateurs peu " +"performants." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Mods de confiance" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" +"URL de la liste des serveurs affichée dans l'onglet « Rejoindre une partie »." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Sous-échantillonnage" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Le sous-échantillonnage ressemble à l'utilisation d'une résolution d'écran " +"inférieure, mais il ne s'applique qu'au rendu 3D, gardant l'interface " +"intacte.\n" +"Cela doit donner un bonus de performance conséquent, au détriment de la " +"qualité d'image.\n" +"Les valeurs plus élevées réduisent la qualité du détail des images." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Distance de transfert du joueur illimitée" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Décharger les données de serveur inutilisées" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Limite haute Y des donjons." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Limite haute Y des terrains flottants." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Activer les nuages 3D au lieu des nuages 2D (plats)." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" +"Utiliser une animation de nuages pour l'arrière-plan du menu principal." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" +"Utilisation du filtrage anisotrope lors de la visualisation des textures de " +"biais." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Utilisation du filtrage bilinéaire." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Utilise le mip-mapping pour mettre à l'échelle les textures.\n" +"Peut augmenter légèrement les performances, surtout lors de l'utilisation " +"d'un pack de textures haute résolution.\n" +"La réduction d'échelle gamma correcte n'est pas prise en charge." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Utilise l'anticrénelage multi-échantillons (MSAA) pour lisser les bords des " +"blocs.\n" +"Cet algorithme lisse la vue 3D tout en conservant l'image nette, mais cela " +"ne concerne pas la partie interne des textures (ce qui est particulièrement " +"visible avec des textures transparentes).\n" +"Des espaces visibles apparaissent entre les blocs lorsque les shaders sont " +"désactivés.\n" +"Si définie à 0, MSAA est désactivé.\n" +"Un redémarrage est nécessaire après la modification de cette option." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Utilisation du filtrage trilinéaire." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "Interfaces utilisateur" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Synchronisation verticale" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Profondeur des vallées" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Comblement des vallées" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Profil des vallées" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Inclinaison des vallées" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Variation de la profondeur du remplisseur de biome." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Variation de la hauteur maximale des montagnes (en blocs)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Variation du nombre de grottes." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Variation du terrain en hauteur.\n" +"Quand le bruit est inférieur à -0,55, le terrain est presque plat." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Variation de la profondeur des blocs en surface pour les biomes." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Variation de la rugosité du terrain.\n" +"Définit la valeur de « persistance » pour les bruits terrain_base et " +"terrain_alt." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Contrôle l'élévation/hauteur des falaises." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Vitesse d’escalade verticale, en nœuds par seconde." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Synchronisation verticale de la fenêtre de jeu." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Pilote vidéo" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Facteur de balancement de la vue" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Distance d'affichage en blocs." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Touche réduire la distance d'affichage" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Touche augmenter la distance d'affichage" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Touche zoomer" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Plage de visualisation" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "Manette virtuelle déclenche le bouton Aux1" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Volume du son" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Volume de tous les sons.\n" +"Exige que le son du système soit activé." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Coordonnée W de la couche 3D de la forme 4D.\n" +"Détermine la tranche 3D de la forme 4D qui est générée.\n" +"Transforme la forme de la fractale.\n" +"N'a aucun effet sur les fractales 3D.\n" +"La portée est d'environ -2 à 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Vitesse de marche et de vol, en nœuds par seconde." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Vitesse de marche" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Vitesse de marche, de vol et de montée en mode rapide, en nœuds par seconde." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Niveau de l'eau" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Niveau de la surface de l'eau du monde." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Environnement mouvant" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Feuilles ondulantes" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Liquides ondulants" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Hauteur des vagues des liquides ondulants" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Vitesse de mouvement des liquides ondulants" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Longueur d'onde des liquides ondulants" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Plantes ondulantes" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "Couleur du lien web" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Quand « gui_scaling_filter » est activé, tous les images du GUI sont " +"filtrées par le logiciel, mais certaines sont générées directement par le " +"matériel (ex. : textures des blocs dans l'inventaire)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Quand « gui_scaling_filter_txr2img » est activé, copier les images du " +"matériel au logiciel pour mise à l'échelle.\n" +"Si désactivé, l'ancienne méthode de mise à l'échelle est utilisée, pour les " +"pilotes vidéos qui ne supportent pas le chargement des textures depuis le " +"matériel." + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"En utilisant le filtrage bilinéaire/trilinéaire/anisotrope, les textures de " +"basse résolution peuvent être brouillées. Elles seront donc automatiquement " +"agrandies avec l'interpolation du plus proche voisin pour garder des pixels " +"moins floues. Ceci détermine la taille de la texture minimale pour les " +"textures agrandies ; les valeurs plus hautes rendent plus détaillées, mais " +"nécessitent plus de mémoire. Les puissances de 2 sont recommandées. Ce " +"paramètre est appliqué uniquement si le filtrage bilinéaire/trilinéaire/" +"anisotrope est activé.\n" +"Ceci est également utilisée comme taille de texture de nœud de base pour " +"l'agrandissement automatique des textures alignées sur le monde." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Si l'arrière-plan des badges doit être affiché par défaut.\n" +"Les mods peuvent toujours définir un arrière-plan." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"Détermine la désynchronisation des animations de texture de nœud par bloc de " +"carte." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Détermine l'exposition illimitée des noms de joueurs aux autres clients.\n" +"Obsolète : utiliser le paramètre « player_transfer_distance » à la place." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Détermine la possibilité des joueurs de tuer d'autres joueurs." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"S’il faut demander aux clients de se reconnecter après un crash (Lua).\n" +"Définir sur « Activé » si le serveur est paramétré pour redémarrer " +"automatiquement." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Détermine la visibilité du brouillard au bout de l'aire visible." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"S'il faut couper le son. Vous pouvez réactiver le son à tout moment, sauf si " +"le système audio est désactivé (« enable_sound=false »).\n" +"Dans le jeu, vous pouvez basculer l'état du son avec la touche « Muet » ou " +"en utilisant le menu pause." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" +"Détermine si les noms techniques doivent être affichés.\n" +"Affecte les mods et les packs de textures dans les menus « Contenu » et « " +"Sélectionner les mods », ainsi que les noms de paramètres dans « Tous les " +"paramètres ».\n" +"Contrôlé par la case à cocher dans le menu « Tous les paramètres »." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"Détermine la visibilité des informations de débogage du client (même effet " +"que taper F5)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Composant de largeur de la taille initiale de la fenêtre. Ignoré en mode " +"plein écran." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Épaisseur des bordures de sélection autour des blocs." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Systèmes Windows seulement : démarrer Minetest avec la fenêtre de ligne de " +"commande en arrière-plan. Contient les mêmes informations que le fichier " +"« debug.txt » (nom par défaut)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Chemin du monde (tout ce qui relatif au monde est enregistré ici).\n" +"Inutile si démarré depuis le menu." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Heure de début du monde" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Les textures alignées sur le monde peuvent être mises à l'échelle pour " +"couvrir plusieurs nœuds. Cependant, le serveur peut ne pas envoyer l'échelle " +"que vous voulez, surtout si vous utilisez un pack de textures spécialement " +"conçu ; avec cette option, le client essaie de déterminer l'échelle " +"automatiquement en fonction de la taille de la texture.\n" +"Voir aussi « texture_min_size ».\n" +"Avertissement : cette option est EXPÉRIMENTALE !" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Mode d’alignement des textures sur le monde" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Coordonnée Y des terrains plats." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y du niveau zéro du gradient de densité de la montagne. Utilisé pour " +"déplacer les montagnes verticalement." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Limite haute Y des grandes grottes." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" +"La distance Y jusqu'à laquelle les cavernes s'étendent à leur taille " +"maximale." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Hauteur-Y à laquelle les terrains flottants commencent à rétrécir.\n" +"L'effilage comment à cette distance de la limite en Y.\n" +"Pour une couche solide de terrain flottant, ceci contrôle la hauteur des " +"montagnes.\n" +"Doit être égale ou moindre à la moitié de la distance entre les limites Y." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Limite moyenne Y de la surface du terrain." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Limite haute Y de génération des cavernes." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Limite Y du plus haut terrain qui crée des falaises." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Limite Y du plus bas terrain et des fonds marins." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Limite Y du fond marin." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "cURL" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Délai d'interruption de cURL lors d'un téléchargement de fichier" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "Délai d'interruption interactive de cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Limite parallèle de cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "– Mode créatif : " + +#~ msgid "- Damage: " +#~ msgstr "– Dégâts : " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = occlusion parallaxe avec des informations de pente (plus rapide).\n" +#~ "1 = cartographie en relief (plus lent, plus précis)." + +#~ msgid "Address / Port" +#~ msgstr "Adresse / Port" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Ajuster la correction gamma. Les valeurs plus basses sont plus claires.\n" +#~ "Ce paramètre s'applique au client seulement et est ignoré par le serveur." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "" +#~ "Modifie la façon dont les terres flottantes montagneuses s’effilent au-" +#~ "dessus et au-dessous du point médian." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Êtes-vous sûr de vouloir réinitialiser votre monde ?" + +#~ msgid "Back" +#~ msgstr "Retour" + +#~ msgid "Basic" +#~ msgstr "Principal" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bits par pixel (profondeur de couleur) en mode plein-écran." + +#~ msgid "Bump Mapping" +#~ msgstr "Placage de relief" + +#~ msgid "Bumpmapping" +#~ msgstr "Bump mapping" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "Milieu de la courbe de lumière mi-boost." + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Change l’interface du menu principal :\n" +#~ "- Complet : Mondes solo, choix du jeu, sélecteur du pack de textures, " +#~ "etc.\n" +#~ "- Simple : un monde solo, pas de sélecteurs de jeu ou de pack de " +#~ "textures. Peut être\n" +#~ "nécessaire pour les plus petits écrans." + +#~ msgid "Config mods" +#~ msgstr "Configurer les mods" + +#~ msgid "Configure" +#~ msgstr "Configurer" + +#~ msgid "Connect" +#~ msgstr "Rejoindre" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Contrôle la vitesse de descente dans un liquide." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Contrôle la densité des terrains montagneux sur les terres flottantes.\n" +#~ "C'est un décalage ajouté à la valeur du bruit 'mgv7_np_mountain'." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Contrôle la largeur des tunnels, une valeur plus petite crée des tunnels " +#~ "plus larges." + +#~ msgid "Credits" +#~ msgstr "Crédits" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Couleur du réticule (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Dégâts activés" + +#~ msgid "Darkness sharpness" +#~ msgstr "Démarcation de l'obscurité" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Délais d'interruption de cURL par défaut, établi en millisecondes.\n" +#~ "Seulement appliqué si Minetest est compilé avec cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Défini les zones de terrain plat flottant.\n" +#~ "Des terrains plats flottants apparaissent lorsque le bruit > 0." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Niveau de lissage des normal maps.\n" +#~ "Une valeur plus grande lisse davantage les normal maps." + +#~ msgid "Del. Favorite" +#~ msgstr "Supprimer favori" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Télécharger un jeu comme Minetest Game depuis minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Télécharger en un depuis minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Téléchargement et installation de $1, veuillez patienter..." + +#~ msgid "Enable VBO" +#~ msgstr "Activer Vertex Buffer Object: objet tampon de vertex" + +#~ msgid "Enable register confirmation" +#~ msgstr "Activer la confirmation d'enregistrement" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Active le bumpmapping pour les textures.\n" +#~ "Les normalmaps peuvent être fournies par un pack de textures pour un " +#~ "meilleur effet de relief,\n" +#~ "ou bien celui-ci est auto-généré.\n" +#~ "Nécessite les shaders pour être activé." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Autorise le mappage tonal cinématographique" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Active la génération à la volée des normalmaps.\n" +#~ "Nécessite le bumpmapping pour être activé." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Active l'occlusion parallaxe.\n" +#~ "Nécessite les shaders pour être activé." + +#~ msgid "Enter " +#~ msgstr "Entrer " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Option expérimentale, peut causer un espace vide visible entre les blocs\n" +#~ "quand paramétré avec un nombre supérieur à 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS maximum sur le menu pause" + +#~ msgid "Fallback font shadow" +#~ msgstr "Ombre de la police alternative" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Opacité de l'ombre de la police alternative" + +#~ msgid "Fallback font size" +#~ msgstr "Taille de la police alternative" + +#~ msgid "Filtering" +#~ msgstr "Filtrage" + +#~ msgid "Floatland base height noise" +#~ msgstr "Le bruit de hauteur de base des terres flottantes" + +#~ msgid "Floatland mountain height" +#~ msgstr "Hauteur des montagnes flottantes" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Niveau d'opacité de l'ombre de la police (entre 0 et 255)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Taille de police secondaire au point (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "Polices Freetype" + +#~ msgid "Full screen BPP" +#~ msgstr "Bits par pixel en mode plein écran" + +#~ msgid "Game" +#~ msgstr "Jeu" + +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Génération de Normal Maps" + +#~ msgid "Generate normalmaps" +#~ msgstr "Normal mapping" + +#~ msgid "HUD scale factor" +#~ msgstr "Facteur de mise à l'échelle de l'interface" + +#~ msgid "High-precision FPU" +#~ msgstr "FPU de haute précision" + +#~ msgid "IPv6 support." +#~ msgstr "Support IPv6." + +#~ msgid "In-Game" +#~ msgstr "Dans le jeu" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Installation : fichier : « $1 »" + +#~ msgid "Instrumentation" +#~ msgstr "Instrumentalisation" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "Raccourcis clavier" + +#~ msgid "Lava depth" +#~ msgstr "Profondeur de lave" + +#~ msgid "Lightness sharpness" +#~ msgstr "Démarcation de la luminosité" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Limite des files émergentes sur le disque" + +#~ msgid "Main" +#~ msgstr "Principal" + +#~ msgid "Main menu style" +#~ msgstr "Style du menu principal" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "Rendre DirectX compatible avec LuaJIT. Désactiver si cela cause des " +#~ "problèmes." + +#~ msgid "Menus" +#~ msgstr "Menus" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Mini-carte en mode radar, zoom x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Mini-carte en mode radar, zoom x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Mini-carte en mode surface, zoom x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Mini-carte en mode surface, zoom x4" + +#~ msgid "Name / Password" +#~ msgstr "Nom / Mot de passe" + +#~ msgid "Name/Password" +#~ msgstr "Nom / Mot de passe" + +#~ msgid "No" +#~ msgstr "Non" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Échantillonnage de normalmaps" + +#~ msgid "Normalmaps strength" +#~ msgstr "Force des normalmaps" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Nombre d'itérations sur l'occlusion parallaxe." + +#~ msgid "Ok" +#~ msgstr "Ok" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "" +#~ "Opacité (alpha) de l'ombre derrière la police secondaire, entre 0 et 255." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "Bias général de l'occlusion parallaxe, habituellement échelle/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Echelle générale de l'effet de l'occlusion parallaxe." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Occlusion parallaxe" + +#~ msgid "Parallax occlusion" +#~ msgstr "Occlusion parallaxe" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Bias de l'occlusion parallaxe" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Nombre d'itérations sur l'occlusion parallaxe" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Mode occlusion parallaxe" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Echelle de l'occlusion parallaxe" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Force de l'occlusion parallaxe" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Chemin vers police TrueType ou Bitmap." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Chemin où les captures d'écran sont sauvegardées." + +#~ msgid "Player name" +#~ msgstr "Nom du joueur" + +#~ msgid "Profiling" +#~ msgstr "Profilage" + +#~ msgid "Projecting dungeons" +#~ msgstr "Projection des donjons" + +#~ msgid "PvP enabled" +#~ msgstr "JcJ activé" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Réinitialiser le monde" + +#~ msgid "Select Package File:" +#~ msgstr "Sélectionner le fichier du mod :" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Serveur / Partie solo" + +#~ msgid "" +#~ "Set the shadow update time.\n" +#~ "Lower value means shadows and map updates faster, but it consume more " +#~ "resources.\n" +#~ "Minimun value 0.001 seconds max value 0.2 seconds" +#~ msgstr "" +#~ "Définit le temps de mise à jour des ombres.\n" +#~ "Une valeur plus faible signifie que les ombres et les mises à jour de la " +#~ "carte sont plus rapides, mais cela consomme plus de ressources.\n" +#~ "Valeur minimale 0,001 seconde et maximale 0,2 seconde." + +#~ msgid "Shadow limit" +#~ msgstr "Limite des ombres" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Décalage de l'ombre de la police de secours (en pixel). Aucune ombre si " +#~ "la valeur est 0." + +#~ msgid "Special" +#~ msgstr "Spécial" + +#~ msgid "Special key" +#~ msgstr "Touche spéciale" + +#~ msgid "Start Singleplayer" +#~ msgstr "Démarrer une partie solo" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Force des normalmaps autogénérés." + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "Force de la courbe de lumière mi-boost." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Cette police sera utilisée pour certaines langues." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Pour activer les shaders, le pilote OpenGL doit être utilisé." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Mode cinématique" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Hauteur maximum typique, au-dessus et au-dessous du point médian, du " +#~ "terrain de montagne flottantes." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Variation de la hauteur des collines et de la profondeur des lacs sur les " +#~ "terrains plats flottants." + +#~ msgid "View" +#~ msgstr "Voir" + +#~ msgid "Waving Water" +#~ msgstr "Eau ondulante" + +#~ msgid "Waving water" +#~ msgstr "Vagues" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Détermine l'utilisation des polices Freetype. Nécessite une compilation " +#~ "avec le support Freetype.\n" +#~ "Si désactivée, des polices bitmap et en vecteurs XML seront utilisé en " +#~ "remplacement." + +#~ msgid "Whether dungeons occasionally project from the terrain." +#~ msgstr "Si les donjons font parfois saillie du terrain." + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "" +#~ "Coordonnée Y de la limite supérieure des grandes grottes pseudo-" +#~ "aléatoires." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "Hauteur (Y) du point de flottaison et de la surface des lacs." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Hauteur (Y) auquel les ombres portées s’étendent." + +#~ msgid "Yes" +#~ msgstr "Oui" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Vous êtes sur le point de rejoindre ce serveur avec le nom « %s » pour la " +#~ "première fois.\n" +#~ "Si vous continuez, un nouveau compte utilisant vos identifiants sera créé " +#~ "sur ce serveur.\n" +#~ "Veuillez retaper votre mot de passe et cliquer sur « S'enregistrer et " +#~ "rejoindre » pour confirmer la création de votre compte, ou cliquer sur " +#~ "« Annuler »." + +#~ msgid "You died." +#~ msgstr "Vous êtes mort." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/gd/minetest.po b/po/gd/minetest.po new file mode 100644 index 0000000..5c46bfe --- /dev/null +++ b/po/gd/minetest.po @@ -0,0 +1,7199 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2021-08-19 06:36+0000\n" +"Last-Translator: GunChleoc <fios@foramnagaidhlig.net>\n" +"Language-Team: Gaelic <https://hosted.weblate.org/projects/minetest/minetest/" +"gd/>\n" +"Language: gd\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : " +"(n > 2 && n < 20) ? 2 : 3;\n" +"X-Generator: Weblate 4.8-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Prìomh chlàr-taice" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Prìomh chlàr-taice" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Protocol version mismatch. " +msgstr " " + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Server enforces protocol version $1. " +msgstr " " + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Server supports protocol versions between $1 and $2. " +msgstr " " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Gun eisimeileachd chruaidh" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "" +"Stàladh: Faidhle dhen t-seòrsa “$1” ris nach eil taic no tasglann bhriste" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Tìr air fhleòd san speur" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Aibhnean boga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Nì seo an tìr nas buige faisg air aibhnean" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Pacaidean air an stàladh:" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Adhbharaichidh saoghal tioram is teth aibhnean tana no tioram" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Gineadair nam mapa" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Brataich gineadair nam mapa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Brataich shònraichte do ghineadair nam mapa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Aibhnean" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Aibhnean air àirde na mara" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Caochail doimhne nan aibhnean" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Ainm gineadair nam mapa" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Pacaidean air an stàladh:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Stàlaich geamannan o ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr " " + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "– Dochann: " + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "Aibhnean boga" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Sgrìn:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Provided password file failed to open: " +msgstr " " + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Provided world path doesn't exist: " +msgstr " " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "- Address: " +msgstr " " + +#: src/client/game.cpp +#, fuzzy +msgid "- Mode: " +msgstr " " + +#: src/client/game.cpp +#, fuzzy +msgid "- Port: " +msgstr " " + +#: src/client/game.cpp +#, fuzzy +msgid "- Public: " +msgstr " " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +#, fuzzy +msgid "- PvP: " +msgstr " " + +#: src/client/game.cpp +#, fuzzy +msgid "- Server Name: " +msgstr " " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Tha am modh film an comas" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Stiùireadh:\n" +"- %s: gluais an comhair a’ bheòil\n" +"- %s: gluais an comhair a’ chùil\n" +"- %s: gluais dhan taobh clì\n" +"- %s: gluais dhan taobh deas\n" +"- %s: leum/sreap\n" +"- %s: tàislich/dìrich\n" +"- %s: leig às nì\n" +"- %s: an tasgadh\n" +"- Luchag: tionndaidh/coimhead\n" +"- Putan clì na luchaige: geàrr/buail\n" +"- Putan deas na luchaige: cuir ann/cleachd\n" +"- Cuibhle na luchaige: tagh nì\n" +"- %s: cabadaich\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Tha am modh luath an comas (an aire: gun sochair “fast”)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Tha am modh sgiathaidh à comas" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Tha am modh sgiathaidh an comas" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Tha am modh sgiathaidh an comas (an aire: gun sochair “fly”)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Fiosrachadh mun gheama:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Tha am modh gun bhearradh à comas" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Tha am modh gun bhearradh an comas" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Tha am modh gun bhearradh an comas (an aire: gun sochair “noclip”)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Tha astar na faicsinn cho mòr sa ghabhas: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Tha a’ chabadaich ’ga shealltainn" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Control clì" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "4 air pada nan àireamhan" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "8 air pada nan àireamhan" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Thoir gnogag dhùbailte air “leum” airson sgiathadh a thoglachadh" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Meudaich an t-astar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Tàislich" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Toglaich sgiathadh" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Toglaich am modh gun bhearradh" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "brùth air iuchair" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr " " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "gd" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Riasladh 2D a stiùiricheas cruth/meud nan cnoc." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Riasladh 2D a shuidhicheas glinn is sruthan nan aibhnean." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Riasladh 3D a mhìnicheas structar is àirde nam beanntan.\n" +"Mìnichidh e cruth-tìre nam beanntan air tìr air fhleòd cuideachd." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Riasladh 3D a mhìnicheas structar na tìre air fhleòd.\n" +"Mura cleachd thu an luach bunaiteach, dh’fhaoidte gum b’ fheàirrde thu\n" +"gleus a chur air “scale” an riaslaidh (0.7 a ghnàth) on a dh’obraicheas " +"foincseanan\n" +"cinn-chaoil as fheàrr nuair a bhios an riasladh seo eadar mu -2.0 agus 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Riasladh 3D a mhìnicheas structar ballachan sgoltaidhean-aibhne." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" +"Riasladh 3D a mhìnicheas an àireamh dhe thuill-dhubha anns gach cnap mapa." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Atharraichidh seo lùb an t-solais a’ cur “gamma correction” air.\n" +"Nì luachan nas àirde an solas meadhanach no fann nas soilleire.\n" +"Fàgaidh luach “1.0” lùb an t-solais mar a tha i.\n" +"Chan eil buaidh mhòr aige ach air solas an latha is na h-oidhche fuadaine,\n" +"agus cha mhòr nach bi buaidh air solas oidhche nàdarra idir." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Sgiathaich an-còmhnaidh ’s gu luath" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Meudaichidh seo na glinn." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Ainmich am frithealaiche" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Àirde bhunasach a’ ghrunnda" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Sochairean bunasach" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Meadhan rainse meudachadh lùb an t-solais.\n" +"Is 0.0 an ìre as fhainne agus 1.0 an ìre as soilleire air an solas." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Tha a’ chabadaich ’ga shealltainn" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Ìre loga na cabadaich" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Tha a’ chabadaich ’ga shealltainn" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Meud nan cnapan" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Cuingeachadh tuilleadain air a’ chliant" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Cuingeachadh tuilleadain air a’ chliant" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Ionad-tasgaidh susbaint air loidhne" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Iuchair toglachadh an fhiosrachaidh dì-bhugachaidh" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Ìre an loga dì-bhugachaidh" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Sochairean bunaiteach" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Mìnichidh seo structar sruth nan aibhnean mòra." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Mìnichidh seo àirde bhunasach a’ ghrunnda." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Mìnichidh seo doimhne sruth nan aibhnean." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Mìnichidh seo an t-astar as motha airson tar-chur chluicheadairean ann am " +"bloca (0 = gun chuingeachadh)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Mìnichidh seo leud sruth nan aibhnean." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Mìnichidh seo leud gleanntan nan aibhnean." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Thoir gnogag dhùbailte airson leum no sgiathadh" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Toglaichidh gnogag dhùbailte air iuchair an leuma am modh sgiathaidh." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Dumpaich fiosrachadh dì-bhugachaidh aig gineadair nam mapa." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"An t-easponant aig cinn-chaoil na tìre air fhleòd. Atharraichidh seo giùlnan " +"nan ceann-caol.\n" +"Cruthaichidh luach = 1.0 cinn-chaoil aon-fhillte loidhneach.\n" +"Cruthaichidh luachan > 1.0 cinn-chaoil rèidhe\n" +"a bhios freagarrach dha na cinn-chaoill sgaraichte thùsail.\n" +"Cruthaichidh luachan < 1.0 (can 0.25) uachdar nas mionaidiche le tìr-ìosal " +"nas rèidhe a bhios freagarrach\n" +"do bhreath tìre air fhleòd sholadach." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Factar bogadaich an tuiteim" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Gluasad luath (leis an iuchair “shònraichte”).\n" +"Bidh feum air sochair “fast” air an fhrithealaiche." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Mapadh tòna film" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Dùmhlachd na tìre air fhleòd" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Riasladh na tìre air fhleòd" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Easponant cinn-chaoil air tìr air fhleòd" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Astar cinn-chaoil air tìr air fhleòd" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Àirde an uisge air tìr air fhleòd" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Iuchair an sgiathaidh" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Sgiathadh" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"An t-astar on a thèid blocaichean a ghintinn dha na cliantan, ann am bloca " +"mapa (16 nòdan)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Buadhan gintinn mapa uile-choitcheann.\n" +"Ann an gineadair nam mapa v6, stiùirichidh bratach “decorations” sgeadachadh " +"seach craobhan is feur dlùth-choille\n" +"agus ann an gineadairean nam mapa eile, stiùirichidh a’ bhratach seo a h-" +"uile sgeadachadh." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Caisead lùb an t-solais aig an ìre as soilleire.\n" +"Stiùirichidh seo iomsgaradh an t-solais shoilleir." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Caisead lùb an t-solais aig an ìre as fainne.\n" +"Stiùirichidh seo iomsgaradh an t-solais fhainn." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Àirde a’ ghrunnda" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Iuchair air adhart a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Iuchair air ais a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Iuchair air slot 1 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Iuchair air slot 10 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Iuchair air slot 11 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Iuchair air slot 12 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Iuchair air slot 13 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Iuchair air slot 14 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Iuchair air slot 15 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Iuchair air slot 16 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Iuchair air slot 17 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Iuchair air slot 18 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Iuchair air slot 19 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Iuchair air slot 2 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Iuchair air slot 20 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Iuchair air slot 21 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Iuchair air slot 22 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Iuchair air slot 23 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Iuchair air slot 24 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Iuchair air slot 25 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Iuchair air slot 26 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Iuchair air slot 27 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Iuchair air slot 28 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Iuchair air slot 29 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Iuchair air slot 3 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Iuchair air slot 30 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Iuchair air slot 31 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Iuchair air slot 32 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Iuchair air slot 4 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Iuchair air slot 5 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Iuchair air slot 6 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Iuchair air slot 7 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Iuchair air slot 8 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Iuchair air slot 9 a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Dè cho domhainn ’s a bhios aibhnean." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Dè cho leathann ’s a bhios aibhnean." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Ma tha seo à comas, thèid iuchair “shònraichte” a chleachdadh airson " +"sgiathadh\n" +"ma tha an dà chuid am modh sgiathaidh ’s am modh luadh an comas." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Ma tha seo an comas còmhla ris a’ mhodh sgiathaidh, ’s urrainn dhan " +"chluicheadair sgiathadh tro nòdan soladach.\n" +"Bidh feum air sochair “noclip” on fhrithealaiche." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Ma tha seo an comas, thèid iuchair “shònraichte” seach “tàisleachaidh” a " +"chleachdadh\n" +"airson dìreadh." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Ma tha seo an comas, bidh an gluasad a-rèir pids a’ chluicheadair rè " +"sgiathaidh no snàimh." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Ma tha seo an comas, ’s urrainn dhut blocaichean a chur ann far a bheil thu " +"’nad sheasamh (co chois + àirde do shùil).\n" +"Bidh seo feumail nuair a bhios tu ag obair le bogsaichean nòd ann an " +"raointean beaga." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Leig seachad mearachdan an t-saoghail" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Ath-thriall an fhoincsein ath-chùrsaiche.\n" +"Ma mheudaicheas tu seo, bidh barrachd mion-chruthan air\n" +"ach bi barrachd eallaich air a’ phròiseasadh cuideachd.\n" +"Ma tha ath-thriall = 20, bidh an t-eallach aig gineadair nam mapa seo " +"coltach ri eallach gineadair nam mapa V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thoglaicheas an sgiathadh.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a ghluaiseas gu luath sa mhodh luath.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a ghluaiseas an cluicheadair dhan taobh chlì.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a ghluaiseas an cluicheadair dhan taobh deas.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thoglaicheas an sgiathadh.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an 11mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an 12mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an 13mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an 14mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an 15mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an 16mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an 17mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an 18mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an 19mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 20mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 21mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 22mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 23mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 24mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 25mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 26mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 27mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 28mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 29mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 30mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 31mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas am 32mh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an t-ochdamh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an còigeamh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas a’ chiad slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an ceathramh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an ath-nì air a’ ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an naoidheamh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an nì roimhe air a’ ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an dàrna slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an seachdamh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an siathamh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an deicheamh slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thaghas an treas slot dhen ghrad-bhàr.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair airson tàisleachadh.\n" +"Tha i ‘ga cleachdadh airson dìreadh agus dìreadh san uisge ma bhios " +"aux1_descends à comas.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thoglaicheas an sgiathadh.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"An iuchair a thoglaicheas am modh gun bhearradh.\n" +"Faic http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Ìre an loga a thèid a sgrìobhadh gu debug.txt:\n" +"- <bàn> (gun logadh)\n" +"- none (teachdaireachdan gun ìre)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Cuingeachadh gintinn mapa, ann an nòd, sa h-uile 6 comhair o (0, 0, 0).\n" +"Cha dèid ach cnapan mapa a tha am broinn cuingeachadh gineadair nam mapa a " +"ghintinn.\n" +"Thèid luach fa leth a stòradh air gach saoghal." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Eadaramh nan ùrachaidhean air an lionn ann an diog." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Dèan gach lionn trìd-dhoilleir" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" +"Buadhan gintinn mapa a tha sònraichte do ghineadair nam mapa Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Buadhan gintinn mapa a tha sònraichte do ghineadair nam mapa Flat.\n" +"’S urrainn dhut lochan is cnuic ghanna a chur ris an t-saoghal rèidh." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Buadhan gintinn mapa a tha sònraichte do ghineadair nam mapa Fractal.\n" +"Cuiridh “terrain” gintinn crutha-tìre nach eil fractalach an comas:\n" +"cuan, eileanan is fon talamh." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Buadhan gintinn mapa a tha sònraichte do ghineadair nam mapa Valleys.\n" +"“altitude_chill”: Bidh tìr àrd nas fhuaire.\n" +"“humid_rivers”: Bidh an tìr nas buige faisg air aibhnean.\n" +"“vary_river_depth”: Ma tha seo an comas, bidh aibhnean nas tana agus tioram " +"aig amannan ma tha an saoghal tioram no teth.\n" +"’“altitude_dry”: Bidh tìr àrd nas tiorma." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Buadhan gintinn mapa a tha sònraichte do ghineadair nam mapa v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Buadhan gintinn mapa a tha sònraichte do ghineadair nam mapa v6.\n" +"Cuiridh a’ bhratach “snowbiomes” siostam 5 ùr nam bitheom an comas.\n" +"Nuair a bhios a’ bhratach “snowbiomes” an comas, thèid dlùth-choilltean a " +"chur an comas gu fèin-obrachail \n" +"agus a’ bhratach “jungles” a leigeil seachad." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Buadhan gintinn mapa a tha sònraichte do ghineadair nam mapa v7.\n" +"“ridges”: Aibhnean.\n" +"“floatlands”: Tìr air fhleòd san àile.\n" +"“caverns”: Uamhan mòra domhainn fon talamh." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Cuingeachadh gintinn mapa" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Gineadair nam mapa Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Brataich shònraichte do ghineadair nam mapa Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Gineadair nam mapa Flat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Brataich shònraichte do ghineadair nam mapa Flat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Gineadair nam mapa Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Brataich shònraichte do ghineadair nam mapa Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Gineadair nam mapa V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Brataich shònraichte do ghineadair nam mapa V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Gineadair nam mapa V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Brataich shònraichte do ghineadair nam mapa V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Gineadair nam mapa V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Brataich shònraichte do ghineadair nam mapa V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Gineadair nam mapa Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Brataich shònraichte do ghineadair nam mapa Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Dì-bhugachadh gineadair nam mapa" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Ainm gineadair nam mapa" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Leud as motha a’ ghrad-bhàr" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" +"An àireamh as motha de dh’uamhan mòra air thuaiream anns gach cnap mapa." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" +"An àireamh as motha de dh’uamhan beaga air thuaiream anns gach cnap mapa." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"A’ chuid as motha dhen uinneag làithreach a thèid a chleachdadh airson a’ " +"ghrad-bhàr.\n" +"Tha seo feumail ma dh’fheumas tu rudeigin a shealltainn taobh deas no clì " +"air a’ ghrad-bhàr." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "An ìre as lugha dhen loga a thèid a sgrìobhadh dhan chabadaich." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" +"An àireamh as lugha de dh’uamhan mòra air thuaiream anns gach cnap mapa." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" +"An àireamh as lugha de dh’uamhan beaga air thuaiream anns gach cnap mapa." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Slighe dhan chlò aon-leud" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Àirde neoini nam beanntan" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Ainm air gineadair nam mapa a thèid a chleachdadh airson saoghal ùr a " +"chruthachadh.\n" +"Tar-aithnidh cruthachadh saoghail ùir sa phrìomh chlàr-taice seo.\n" +"Seo gineadairean nam mapa a tha glè neo-sheasmhach aig an àm seo:\n" +"- floatlands roghainneil aig v7 (à comas o thùs)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Gun bhearradh" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Iuchair modha gun bhearradh" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Fosgail clàr-taice a’ chuir ’na stad nuair a chailleas an uinneag am fòcas.\n" +"Cha dèid a chur ’na stad nuair a bhios formspec fosgailte." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Iuchair an sgiathaidh" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"’S urrainn dhan chluicheadair sgiathadh gun bhuaidh na iom-tharraing air.\n" +"Bidh feum air sochair “fly” air an fhrithealaiche." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Sochairean as urrainn do chluicheadairean le basic_privs a cheadachadh" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" +"Àrdaichidh seo an cruth-tìre airson glinn a chruthachadh timcheall air na h-" +"aibhnean." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Doimhne sruth nan aibhnean" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Leud sruth nan aibhnean" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Doimhne nan aibhnean" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Riasladh aibhnean" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Meud nan aibhnean" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Leud gleanntan aibhne" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Sgrìn:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Sgrìn:" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Aibhnean boga" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr " " + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Meud nan cnapan mapa a thèid a ghintinn le gineadair nam mapa, ann am bloca " +"mapa (16 nòd).\n" +"RABHADH: Chan fhaigh thu buannachd ach cunnartan à luach nas àirde na 5.\n" +"Le luach nas lugha, gheibh thu barrachd uamhan is thuill-dubha.\n" +"Chan fhiach atharrachadh an luach seo ach air adhbhar sònraichte ’s " +"mholamaid\n" +"nach atharraich thu e." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Iuchair an tàisleachaidh" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Luaths an tàisleachaidh" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Luaths an tàisleachaidh ann an nòd gach diog." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Àirde uachdar an uisge roghainneil a thèid a chur air breath tìre air fhleòd " +"soladaiche.\n" +"Tha uisge à comas o thùs agus cha dèid gin a chur ach\n" +"ma tha an luach seo nas àirde na “mgv7_floatland_ymax” − " +"“mgv7_floatland_taper”\n" +"(seo toiseach a’ chinn-chaoil).\n" +"***RABHADH, CUNNART AIR SAOGHLAN IS DÈANADAS AN FHRITHEALAICHE***:\n" +"Ma chuireas tu cur ann uisge an comas, feumaidh tu an tìr air fhleòd a " +"rèiteachadh ’s a chur fo dheuchainn a dhèanamh cinnteach gu bheil e ’na " +"breath sholadach\n" +"’s tu a’ cur 2.0 air “mgv7_floatland_density”\n" +"(no luach riatanach eile a-rèir “mgv7_np_floatland”)\n" +"ach an seachnaich thu sruthadh uisge anabarrach a chuireas ealach air an " +"fhrithealaiche ’s ach an seachnaich thu tuil mhòr air uachdar na tìre " +"foidhpe." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Na sochairean a gheibh cleachdaichean ùra gu fèin-obrachail.\n" +"Faic /privs sa gheama airson liosta slàn air rèiteachadh an fhrithealaiche " +"’s nan tuilleadan agad." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"Gabhaidh a chleachdadh airson am meanbh-mhapa a dhèanamh nas rèidhe air " +"uidheaman slaodach." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Astar tar-chur nan cluicheadairean gun chuingeachadh" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Dràibhear video" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Luaths na coiseachd is sgiathaidh, ann an nòd gach diog." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Luaths na coiseachd, sgiathaidh is sreap sa mhodh luath, ann an nòd gach " +"diog." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Àirde an uisge" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Àirde uachdar an uisge air an t-saoghal." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Crathadh duillich" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" +"Co-dhiù am faod cluicheadairean càch a chèile a leòn ’s a mharbhadh gus nach " +"fhaod." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y air àirde neoini air caisead dùmhlachd nam beanntan. Thèid seo a " +"chleachdadh airson beanntan a thogail gu h-inghearach." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Seo an t-astar-Y eadar an dùbhlachd làn ’s an òir air cinn-chaoil na tìre " +"air fhleòd.\n" +"Tòsichidh na cinn-chaoil aig an astar seo on chrìoch Y.\n" +"Airson breath tìre air fhleòd sholadach, stiùirichidh seo àirde nan cnoc/nam " +"beanntan.\n" +"Feumaidh e a bhith nas lugha na no co-ionnann ris an dàrna leth dhen astar " +"eadar na crìochan Y." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Àirde-Y aig uachdar cuibheasach a’ chrutha-thìre." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Àirde-Y aig crìoch àrd nan uamhan." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Àirde-Y a’ chrutha-thìre nas àirde a chruthaicheas creagan." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Àirde-Y a’ chrutha-thìre ìosal agus grunnd na mara." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Àirde-Y aig grunnd na mara." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#, fuzzy +#~ msgid "- Creative Mode: " +#~ msgstr " " + +#~ msgid "- Damage: " +#~ msgstr "– Dochann: " + +#~ msgid "Address / Port" +#~ msgstr "Seòladh / Port" + +#~ msgid "Enter " +#~ msgstr "Cuir a-steach " + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "" +#~ "Claonadh na h-èifeachd occlusion na paraileig air fheadh, seo sgèile/2 " +#~ "mar as àbhaist." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "" +#~ "Airson sgàileadairean a chur an comas, feumaidh tu draibhear OpenGL a " +#~ "chleachdadh." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/gl/minetest.po b/po/gl/minetest.po new file mode 100644 index 0000000..064f740 --- /dev/null +++ b/po/gl/minetest.po @@ -0,0 +1,8021 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-06-27 03:16+0000\n" +"Last-Translator: Raquel Fariña Agra <raquelagra1@gmail.com>\n" +"Language-Team: Galician <https://hosted.weblate.org/projects/minetest/" +"minetest/gl/>\n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.13.1-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Limpar a fila de espera do chat" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Comando baleiro." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Sair ao menú principal" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Comando non válido: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Comando emitido: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Lista de xogadores en liña" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Xogadores en liña: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "A fila de espera do chat agora está baleira." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Este comando está desactivado polo servidor." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Reaparecer" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Morreches" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Comandos dispoñibeis:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Comandos dispoñibeis: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Comando non dispoñible: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Obter axuda para os comandos" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Usa '.help <cmd>' para conseguir máis información ou '.help all' para ver a " +"lista completa." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Aceptar" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<Comando non dispoñible>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Produciuse un erro nun script Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Produciuse un erro:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menú principal" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Volver conectar" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "O servidor solicitou volver conectar:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Seleccionar mods" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "A versión do protocolo non coincide " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "O servidor impor a versión do protocolo $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "O servidor admite as versións de protocolo entre $1 e $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Só admítese a versión de protocolo $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Só admítense as versións de protocolo entre $1 e $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Cancelar" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Dependencias:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Desactivar todo" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Desactivar paq. de mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Activar todo" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Activar paq. de mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Erro ao activar o mod \"$1\" porque conteñe caracteres non autorizados. Só " +"permítense os caracteres [a-z e 0-9]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Buscar máis mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Sen dependencias (opcionais)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Non se forneceu a descripción do xogo." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Sen dependencias importantes" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Non se forneceu a descripción do paquete de mods." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Sen dependencias opcionais" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Dependencias opcionais:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Gardar" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Mundo:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "activado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" xa existe. Desexa substituílo?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Instalaranse as dependencias $1 e $2." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 por $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 descargando,\n" +"$2 en cola" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "Descargando $1..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "Non se puido atopar as dependencias requeridas para $1 ." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "Instalarase $1 e omitiranse as dependencias de $2." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Todos os paq." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Xa está instalado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Volver ao menú principal" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Xogo base:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB non está dispoñible cando Minetest compilouse sen cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Descargando..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Erro ao descargar $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Xogos" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instalar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Instalar $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Instalar dependencias faltantes" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" +"Instalación: Formato de ficheiro \"$1\" non compatible ou ficheiro corrupto" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mods" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Non se puido recuperar ningún paquete" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Non hai resultados" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Sen actualizacións" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Non atopado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Sobrescribir" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Verifica que o xogo base esté correcto." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "En cola" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Paq. de text." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Desinstalar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Actualizar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Actualizar Todo [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Ver máis información nun navegador web" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Xa existe un mundo chamado \"$1\"" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Terreo adicional" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Frío de altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Sequedade en altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Mestura de biomas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Cavernas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Covas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Crear" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Decoracións" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Aviso: O Test de Desenvolvemento está destinado aos desenvolvedores." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Calabozos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Terreo chan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Terreos flotantes no ceo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Terreos flotantes (experimental)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Xerar terreo non fractal: Océanos e subsolo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Outeiros" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Ríos húmidos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Incrementa a humidade arredor dos ríos" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Instalar $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Lagos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"A baixa humidade e a calor elevada provocan ríos pouco profundos ou secos" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Xerador de mundos" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Parámetros do xerador de mundos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Parámetros específicos do xerador de mundos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Montañas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Fluxo de lodo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Rede de túneis e covas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Ningunha partida seleccionada" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Reduce a calor coa altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Reduce a humidade coa altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Ríos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Ríos ao nivel do mar" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Semente" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Transición suave entre biomas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Estruturas que aparecen no terreo (sen efecto nas árbores e no céspede da " +"xungla que creou a v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Estruturas que aparecen no terreo, xeralmente árbores e plantas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Temperado, Deserto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Temperado, Deserto, Xungla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Temperado, Deserto, Xungla, Tundra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erosión superficial do terreo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Árbores e céspede da xungla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Variar a profundidade do río" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Cavernas moi grandes nas profundidades do subsolo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nome do mundo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Non tes xogos instalados." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Desexa eliminar \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Eliminar" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: erro ao eliminar \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: ruta \"$1\" non válida" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Eliminar o mundo \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Confirmar contrasinal" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Nome do xerador de mundos" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nome" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Contrasinal" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Os contrasinais non coinciden!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Rexistrarse e unirse" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Aceptar" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Renomear paquete de mods:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Este paquete de mods ten un nome explícito no seu modpack.conf que non " +"permitirá cambios de nome aquí." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Ningunha descripción da configuración dada)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Ruído 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "<Volver á configuración" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Explorar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Contido" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Contido" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Desactivado" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Editar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Activado" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lacunaridade" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oitavas" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Desprazamento" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Persistencia" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Introduce un número enteiro válido." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Introduce un número válido." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Restaurar" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Escala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Procurar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Seleccionar directorio" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Seleccionar ficheiro" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Mostrar nomes técnicos" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "O valor debe ser polo menos $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "O valor non debe ser máis grande que $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Amplitude X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Amplitude Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Amplitude Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Valor absoluto" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "Predefinido" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "Suavizado" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Activado)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mods" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Error ao instalar $1 en $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Instalación do mod: Non se puido atopar o nome real do mod para: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Instalación do mod: Non se puido atopar un nome de cartafol adecuado para o " +"paquete de mods $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Non se puido atopar un mod ou paquete de mods válido" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Non se puido instalar $1 como paquete de texturas" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Non se puido instalar un xogo como $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Non se puido instalar un mod como $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Non se puido instalar un paquete de mods como $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Cargando..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "A lista de servidores públicos está desactivada" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Tente volver activar a lista de servidores públicos e verifique a súa " +"conexión a Internet." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Acerca de" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Colaboradores activos" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Renderizador activo:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Desenvolvedores principais" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Abrir dir. datos de usuario" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Abre o directorio que contén mundos, xogos, mods fornecidos polo usuario\n" +"e paquetes de textura nun xestor de ficheiros ou explorador." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Colaboradores anteriores" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Desenvolvedores principais anteriores" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Mostrar información de depuración" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Explorar contido en liña" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Contido" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Desactivar paq. de texturas" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Información:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Paquetes instalados:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Sen dependencias." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "A descripción do paquete non está dispoñible" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Renomear" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Desinstalar paquete" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Usar paquete de texturas" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Anunciar servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Ligazón de enderezo" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Modo creativo" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Activar danos" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Hospedar xogo" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Hospedar servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Instalar xogos do ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Novo" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Ningún mundo creado ou seleccionado!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Xogar" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Porto" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Seleccionar mods" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Seleccionar mundo:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Porto do servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Xogar só" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Enderezo" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Limpar" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Modo creativo" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Dano / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favoritos" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Servidores incompatibles" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Xogar en liña" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Servidores públicos" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Actualizar" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Porto remoto" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Descripción do servidor" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Nubes 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Toda a configuración" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Suavizado:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Autogardar tam. pantalla" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Filtrado bilineal" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Configurar teclas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Vidro unificado" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Sombras dinámicas" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Sombras dinámicas: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Follas detalladas" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Alto" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Baixo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Medio" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Filtro aniso." + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Sen filtros" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Sen Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Resaltar nodos" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Marcar nodos" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Ningún" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Follas opacas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Auga opaca" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partículas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Pantalla:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Configuración" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Sombreadores" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Sombreadores (experimental)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Sombreadores (non dispoñible)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Follas simples" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Iluminación suave" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Texturización:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Mapeado de tons" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Nivel de sensibilidade ao toque (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Filtro trilineal" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Moi alto" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Moi baixo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Movemento das follas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Movemento dos líquidos" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Movemento das plantas" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Erro de conexión (tempo esgotado?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Esgotouse o tempo de conexión." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Feito!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Iniciando nodos" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Iniciando nodos..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Cargando texturas..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Reconstruíndo sombreadores..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Erro de conexión (tempo esgotado?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Non se puido atopar ou cargar o xogo: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Especificación do xogo non válida." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menú principal" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Ningún mundo seleccionado e ningún enderezo fornecido. Nada que facer." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Nome do xogador demasiado longo." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Escolle un nome!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "O ficheiro do contrasinal fornecido non se puido abrir: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "O camiño do mundo fornecido non existe: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Verifique debug.txt para obter detalles." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Enderezo: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Modo: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Porto: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Público: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Nome do servidor: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Ocurreu un erro:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Acceso negado. Motivo: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Avance automático desactivado" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Avance automático activado" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Lím. bloques ocultos" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Límites de bloque mostrados para todos os bloques" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Límites de bloques mostrados para o bloque actual" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Límites de bloques mostrados para bloques pretos" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Actualización da cámara desactivada" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Actualización da cámara activada" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" +"Non se puido mostrar os límites de bloco (é preciso o permiso 'basic_debug')" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Cambiar contrasinal" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Modo cinematográfico desactivado" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Modo cinematográfico activado" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Cliente desconectado" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "O scripting de cliente está desactivado" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Conectando ao servidor..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Erro na conexión por un motivo descoñecido" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Continuar" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Controis:\n" +"- %s: ir cara adiante\n" +"- %s: ir cara atrás\n" +"- %s: ir cara esquerda\n" +"- %s: ir cara dereita\n" +"- %s: saltar/escalar\n" +"- %s: romper bloque/golpear\n" +"- %s: colocar/usar\n" +"- %s: agacharse/abaxaise\n" +"- %s: soltar obxecto\n" +"- %s: inventario\n" +"- Rato: virarse/ver\n" +"- Roda do rato: seleccionar obxecto\n" +"- %s: chat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Non se puido resolver o enderezo: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Creando cliente..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Creando servidor..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Información de depuración e gráfico de análise do mundo ocultos" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Info de depuración mostrada" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" +"Info de depuración, gráfico de análise do mundo e estrutura de arames ocultos" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Controis por defecto:\n" +"Menú oculto:\n" +"- Un clic: activa botón\n" +"- Dobre clic: colocar/usar\n" +"- Deslizar dedo: mirar arredor\n" +"Menú/inventario visible:\n" +"- Dobre clic: (fóra do menú/inventario):\n" +" -->pechar\n" +"- Clic no obxecto e logo clic nun compartimento:\n" +" --> mover obxecto\n" +"- Clic e arrastar, e logo clic con os dous dedos\n" +" --> colocar un só obxecto\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Campo de visión ilimitada desactivado" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Campo de visión ilimitada activado" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Creando cliente..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Saír ao menú" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Saír do xogo" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Modo rápido desactivado" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Modo rápido activado" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Modo rápido activado (nota: sen permiso 'rápido')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Modo voo desactivado" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Modo voo activado" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Modo voo activado (nota: sen permiso de 'voo')" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Néboa desactivada" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Néboa activada" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Información do xogo:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Xogo pausado" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Servidor anfitrión" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Definicións dos obxectos..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Multimedia..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "O minimapa está actualmente desactivado polo xogo ou mod" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Xogar en liña" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Modo espectador desactivado" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Modo espectador activado" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Modo espectador activado (nota: sen permiso 'noclip')" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Definicións de nodos..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Desactivado" + +#: src/client/game.cpp +msgid "On" +msgstr "Activado" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Modo de movemiento rotación vertical desactivado" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Modo de movemiento de rotación vertical activado" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Gráfico de análise do mundo mostrado" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Servidor remoto" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Resolvendo enderezo..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Cerrando..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Un xogador" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Volume do son" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Sonido silenciado" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "O sistema de son está desactivado" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "O sistema de son non é compatible con esta versión" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Son reactivado" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "É posible que o servidor esté executando unha versión diferente de %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Non se puido conectar a %s porque o IPv6 está desactivado" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Non se puido escoitar %s porque o IPv6 está desactivado" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Campo de visión cambiada a %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "O campo de visión está ao máximo: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "O campo de visión está ao mínimo: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Volume cambiado a %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Estrutura de arames mostrada" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "O zoom está actualmente desactivado polo xogo ou mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Chat oculto" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Chat visible" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD oculto" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD visible" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Análise do mundo oculta" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Análise do mundo visible (páx. %d de %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplicaciones" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Retroceso" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Bloq Maiús" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Abaixo" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Fin" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Borrar EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Executar" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Axuda" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Inicio" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Aceptar IME" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Converter IME" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "Saír do IME" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Cambiar modo do IME" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "Non converter IME" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Inserir" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Esquerda" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Botón esquerdo" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Ctrl esq." + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menú esquerdo" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Shift esq." + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Win. esq." + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menú" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Botón central" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Bloq. núm." + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Teclado numérico *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Teclado numérico +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Teclado numérico -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Teclado numérico ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Teclado numérico /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Teclado numérico 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Teclado numérico 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Teclado numérico 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Teclado numérico 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Teclado numérico 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Teclado numérico 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Teclado numérico 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Teclado numérico 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Teclado numérico 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Teclado numérico 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Limpar OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Avance páx." + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Retroceso pax." + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pausa" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Xogar" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Impr. pant." + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Dereita" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Botón dereito" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Ctrl der." + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menú dereito" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Shift der." + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Win. der." + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Bloq. Despr." + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Seleccionar" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Suspender" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Instantánea" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Espazo" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabulador" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Arriba" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Botón 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Botón 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Minimapa oculto" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimapa en modo radar, Zoom x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimapa en modo superficie, Zoom x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimapa en modo textura" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Erro ao abrir páxina web" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Abrindo páxina web" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Continuar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = baixar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Avance automático" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Salto automático" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Atrás" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Lím. bloques" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Cambiar cámara" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Comando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Consola" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Dism. alcance" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Baixar volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Con 2 veces \"saltar\" voas" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Soltar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Adiante" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Aum. alcance" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Subir volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventario" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Saltar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "A tecla xa está en uso" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Comando local" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Silenciar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Seg. obxecto" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Obxecto ant." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Sel. alcance" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Captura" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Ir agachado" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Alt. HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Alt. rexistro chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Alt. correr" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Alt. voo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Alt. néboa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Alt. minimapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Modo espectar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Alt. rot. vertical" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "Unha tecla" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Cambiar" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Novo" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Anterior contrasinal" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Os contrasinais non coinciden!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Pechar" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Silenciado" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Son: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "gl" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Escolle un nome!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Corrixe a posición do joystick virtual.\n" +"Se está desactivado, o joystick virtual centrarase na posición do primeiro " +"toque." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Use o joystick virtual para activar o botón \"Aux1\".\n" +"Se está activado, o joystick virtual tamén tocará o botón \"Aux1\" cando " +"estea fóra do círculo principal." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) compensación do fractal do centro do mundo en unidades de 'escala'.\n" +"Pódese usar para mover un punto desexado a (0, 0) e para crear un\n" +"punto de reaparición adecuado, ou para permitir \"aproximarse\" a un\n" +"punto desexado aumentando a \"escala\".\n" +"O valor predeterminado está axustado para un punto de aparición adecuado " +"para Mandelbrot\n" +"conxuntos con parámetros predeterminados, pode ser necesario modificar " +"noutras\n" +"situacións.\n" +"Intervalo aproximadamente entre -2 e 2. Multiplique por \"escala\" para a " +"compensación nos nós." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z) Escala fractal en nós\n" +"O tamaño real do fractal será de 2 a 3 veces maior.\n" +"Estes números poden ser moi grandes, pero o fractal\n" +"non ten que caber no mundo.\n" +"Aumenta estes valores para indagar nos detalles do fractal.\n" +"O valor por defecto é para axustar verticalmente a forma e que sexa " +"adecuada\n" +"para unha illa, establece os 3 números iguais para a forma inicial." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Ruído 2D que controla a forma/tamaño das montañas escarpadas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Ruído 2D que controla a forma/tamaño dos outeiros." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Ruído 2D que controla a forma/tamaño das montañas inclinadas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "Ruído 2D que controla o tamaño/frecuencia das cordilleiras montañosas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "Ruído 2D que controla o tamaño/frecuencia dos outeiros." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "Ruído 2D que controla o tamaño/frecuencia das cordilleiras de paso." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Ruído 2D que localiza os vales fluviais e canles dos ríos." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Nubes 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Modo 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Forza de paralaxe en modo 3D" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Ruído 3D que define cavernas xigantes." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Ruído 3D que define a estrutura e a altura da montaña.\n" +"Tamén define a estrutura do terreo montañoso flotante." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Ruído 3D que define a estrutura dos terreos flotantes.\n" +"Se se modifica a partir do valor por defecto, é posible que necesite a " +"\"escala\" de ruído (0,7 por defecto).\n" +"para ser axustado, xa que o tapering flotante funciona mellor cando este " +"ruído ten\n" +"un intervalo de valores de aproximadamente -2,0 a 2,0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Ruído 3D que define a estrutura das paredes do canón do río." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Ruído 3D que define o terreo." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"Ruído 3D que define saíntes de montañas, acantilados, etc. Normalmente " +"pequenas variacións." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "Ruído 3D que determina a cantidade de calabozos por chunk." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Soporte 3D.\n" +"Modos admitidos actualmente:\n" +"- none: ningún efecto 3D.\n" +"- anaglyph: sistema de cor Ciano/Magenta (lentes 3D azul e vermelho).\n" +"- interlaced: sistema interlazado (lentes polarizadas).\n" +"- topbottom: divide a pantalla en dous: unha encima e a outra debaixo.\n" +"- sidebyside: divide a pantalla en dous: lado a lado.\n" +" - crossview: 3D de ollos cruzados.\n" +" - pageflip: quadbuffer basado en 3D.\n" +"Ten en conta que o modo interlazado precisa que os sombreadores estean " +"activados." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Semente aleatoria para un novo mundo (deixar en branco para que sexa " +"aleatoria).\n" +"Será sustituída ao crearse un novo mundo no menú principal." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Mostrarase unha mensaxe a todos os clientes cando o servidor falle." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Mostrarase unha mensaxe a todos os clientes cando o servidor peche." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Intervalo ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Límite de tempo para MBA" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Límite absoluto de bloques en proceso de emerxer" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Aceleración no aire" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Aceleración da gravidade, en nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Modificadores de bloques activos" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Intervalo de administración de bloques activos" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Rango de bloque activo" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Rango de envío en obxetos activos" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Enderezo ao que se conectar.\n" +"Deixa isto en branco para iniciar un servidor local.\n" +"Teña en conta que o campo de enderezo do menú principal anula esta " +"configuración." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Añade partículas ao excavar un nó." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Axusta a configuración de ppp á túa pantalla (no X11/Android non) p. ex. " +"para pantallas 4K." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Axusta a densidade de visualización detectada, usada para escalar os " +"elementos da IU." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Axusta a densidade da capa flotante.\n" +"Aumentar o valor para aumentar a densidade. Pode ser positivo ou negativo.\n" +"Valor = 0,0: o 50 % do volume é terreo flotante.\n" +"Valor = 2.0 (pode ser maior dependendo de 'mgv7_np_floatland', probar\n" +"para estar seguro) crea una capa sólida de terreo flotante." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Añadir nome de obxeto" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avanzado" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Altera a curva de luz aplicándolle \"corrección gamma\".\n" +"Os valores máis altos fan que os niveis de luz medio e inferior sexan máis " +"brillantes.\n" +"O valor \"1,0\" deixa a curva de luz inalterada.\n" +"Isto só ten máis efecto na luz do día e na artificia,\n" +"ten moi pouco efecto sobre a luz nocturna natural." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Sempre voar e correr" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Oclusión ambiental gamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Cantidade de mensaxes que un xogador pode enviar en 10 segundos." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Amplifica os vales." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Filtrado anisotrópico" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Anunciar o servidor" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Anuncar en esta lista de servidores." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Añadir nome de obxeto" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Añadir nome do obxecto á descripción." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Ruído das maceiras" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Inercia do brazo" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Inercia do brazo proporciona un movementomáis realista\n" +"do brazo cando a cámara se move." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Preguntar para reconectar logo dunha caída de conexión" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"A esta distancia, o servidor optimizará de forma agresiva a que bloques se " +"envían\n" +"clientes.\n" +"Os valores pequenos poden mellorar moito o rendemento, a costa de\n" +"fallos visibles de renderizado (algúns bloques non se mostrarán baixo a auga " +"nin nas covas,\n" +"así como ás veces en chán).\n" +"Establecer isto nun valor maior que \"max_block_send_distance\" desactiva " +"isto\n" +"optimización.\n" +"Indicado en bloques de mapas (16 nós)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Tecla de avance automático" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Saltar obstáculos de un só no automáticamente." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Informar automáticamente á lista do servidor." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Autogardar o tamaño da pantalla" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Modo de autoescalado" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Tecla Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Tecla Aux1 para escalar/descender" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tecla retroceso" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Nivel do chán base" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Altura base do terreo." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Permisos básicos" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Ruído da praia" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Límite de ruído de praia" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Filtrado bilineal" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Vincular enderezo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Parámetros de ruído de humidade e temperatura da API de bioma" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Ruído de bioma" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Distancia de optimización do envío de bloques" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Camiño das fontes negras e cursivas" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Camiño das fontes negras e cursivas monoespaciadas" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Camiño das fontes negras" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Camiño das fontes negras monoespaciadas" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Colocar bloque na posición do xogador" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Integrado" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Cambiar cámara" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Distancia do plano próximo á cámara en nós, entre 0 e 0,25\n" +"Só funciona en plataformas GLES. A maioría dos usuarios non terán que " +"cambiar isto.\n" +"Aumentalo pode reducir a aparición de artefactos en GPU máis débiles.\n" +"0,1 = Por defecto, 0,25 = Bo valor para tabletas débiles." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Suavizado de cámara" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Suavizado de cámara en modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Alt. actualización de cámara" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Ruído de covas" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Ruído de covas #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Sonido de covas #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Ancho da cova" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Sonido de cova1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Sonido de cova2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Limite da cova" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Ruído da cova" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Conicidade da cova" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Límite da cova" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Límite superior da cova" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Rango de aumento do centro da curva de luz.\n" +"0,0 é o nível mínimo de luz, 1,0 é o nível máximo." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Límite de tempo de mensaxe de comando de chat" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Comandos do chat" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Tamaño da fonte do chat" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Tecla do chat" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Nivel de rexistro do chat" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Límite de mensaxes do chat" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Formato da mensaxe do chat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Límite da mensaxe de expulsión" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Lonxitude máxima da mensaxe do chat" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Alt. chat" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Ligazóns web do chat" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Tamaño do chunk" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tecla para modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Limpar texturas transparentes" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Ligazóns da web que se poden clicar (clic do medio ou Ctrl + botón " +"esquerdo). Actívanse na saída da consola do chat." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Cliente" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Cliente e servidor" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Personalización do cliente" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Restricións para modear no lado do cliente" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Restrición do rango de busca do nodo do lado do cliente" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Personalización do cliente" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Velocidade de escalada" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Radio de nubes" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Nubes" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "As nubes son un efecto do lado do cliente." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Nubes no menú" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Néboa colorida" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Sombras coloridas" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Lista de marcas separadas por comas para ocultar no repositorio de contido.\n" +"\"Non libre\" pódese usar para ocultar paquetes que non sexan \"software " +"libre\",\n" +"segundo a definición da Free Software Foundation.\n" +"Tamén podes especificar clasificacións de contido.\n" +"Estas marcas son independentes das versións de Minetest,\n" +"así que consulta unha lista completa en https://content.minetest.net/help/" +"content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Lista separada por comas de mods que poden acceder ás API de HTTP, que\n" +"permiten cargar e descargar datos a/desde Internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Lista separada por comas de mods de confianza que poden acceder funcións " +"inseguras\n" +"incluso cando a seguridade mod está activada (cía " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Tecla comando" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Nivel de compresión para usar ao gardar mundos no disco.\n" +"-1 - usa o nivel de compresión por defecto\n" +"0 - menor compresión, máis rápido\n" +"9 - mellor compresión, máis lenta" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Nivel de compresión para usar ao mandar mundos ao cliente:\n" +"-1 - usa o nivel de compresión por defecto\n" +"0 - menor compresión, máis rápido\n" +"9 - mellor compresión, máis lenta" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Unificar vidro" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Conectar a un servidor multimedia externo" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Unifica o vidro se o bloque é compatible." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Opacidade da consola" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Cor da consola" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Altura da consola" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Contido do repositorio en liña" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Lista negra de marcas de ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Descargas máximas simultáneas para ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "Ligazón URL de ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Avance contínuo" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Movemento contínuo cara diante. Actívase coa tecla de autoavance.\n" +"Preme a tecla de autoavance outra vez ou retrocede para desactivar." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Controis" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Controla a duración do ciclo de día/noite.\n" +"Exemplos:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = Día/noite permanece inalterado." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Controla a inclinación/profundidade dos lagos." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Controla a inclinación/altura dos outeiros." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Controla o ancho dos túneis. Un valor menor crea túneis máis anchos.\n" +"Valor >= 10.0 desactiva completamente a xeración de túneis e evita\n" +"cálculos intensivos de ruído." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Mensaxe de erro" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Creativo" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Opacidade do cursor" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Opacidade do cursor (entre 0 e 255).\n" +"Tamén pasa o menos con a cruz do obxecto." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Cor da cruz" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Cor da cruz (R, G, B)\n" +"Tamén pasa o mesmo coa cruz do obxecto" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Dano" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Alt. inf. para depuración" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Límite do tamaño do ficheiro de información de depuración" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Nivel de rexistro de depuración" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Tecla baixar volume" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Intervalo de servidor dedicado" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Aceleración por defecto" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Xogo por defecto" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Xogo por defecto ao crear un novo mundo.\n" +"Sobreescribirase ao crear un mundo desde o menú principal." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Contrasinal por defecto" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Permisos por defecto" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Formato de reporte por defecto" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Tamaño do agrupamento de obxectos por defecto" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Define a calidade do filtrado de sombras.\n" +"Isto simula un efecto de sombras suaves aplicando un PCF ou Poisson disk\n" +"pero tamén consume máis recursos." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Define as áreas onde as árbores teñen mazás." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Define áreas con praias areosas." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" +"Define a distribución de terreos más elevados e a inclinación de acantilados." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Define a distribución de terreos elevados." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Define o tamaño de covas. Valores máis baixos crean covas máis grandes." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Define estruturas de canles fluviais a gran escala." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Define a localización e terreo de outeiros e lagos opcionais." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Define o nivel base do terreo." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Define a profundidade da canle do río." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Define a distancia máxima de transferencia de xogadores en bloques (0 = " +"ilimitado)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Define a largura da canle do río." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Define a largura do val do río." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Define as áreas arbóreas e a densidade das árbores." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Atraso entre as actualizacións de mallas do cliente en ms. Incrementar isto " +"consegue\n" +"reducir a cantidade de actualizacións de mallas, reducindo así a " +"inestabilidade nos clientes máis lentos." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Atraso no envío de bloques logo de construír" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Atraso para mostrar información de herramientas, en milisegundos." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Manexo de funcións de API Lua obsoletas" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Profundidade na que atoparás cavernas xigantes." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Profundidade na que atoparás covas grandes." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Descripción do servidor. Móstrase na lista de servidores e cando os " +"xogadores únense." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Límite do ruído do deserto" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Os desertos aparecen cando np_biome supera este valor.\n" +"Cando a marca 'snowbiomes' actívase, isto é ignorado." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Desincronizar a animación dos bloques" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Decoracións" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Tecla romper bloque" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Partículas ao excavar" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Desactivar anticheat" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Non permitir contrasinais baleiros" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Factor de escala de densidade de exposición" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Nome do servidor. Mostrarase na lista de servidores." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Pulsar dúas veces \"salto\" para voar" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Pulsar dúas veces \"salto\" serve para activar e desactivar o voo." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Tecla para soltar obxecto" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Mostrar información de depuración do xerador de terreos." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Nº máx. de calabozos Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Nº mín. de calabozos Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Sonido de calabozos" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Activar axuda IPv6 (para o cliente e o servidor).\n" +"É preciso para que as conexións IPv6 funcionen." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Activar a axuda de mods de Lua no cliente.\n" +"Isto é experimental e a API pode cambiar." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Activar filtrado \"poisson disk\".\n" +"Utiliza o \"poisson disk\" para proxectar sombras suaves cando o valor sexa " +"verdadero. Senón, utiliza o filtrado PCF." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Activar sombras coloridas.\n" +"Se o valor é verdadeiro, os bloques traslúcidos proxectarán sombras " +"coloridas. Esta opción precisa de moitos recursos." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Activar a xanela da consola" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Activar o modo creativo para todos os xogadores" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Activar joysticks" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Activar axuda para as canles de mods." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Activar seguridade dos mods" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Activar dano e morte dos xogadores." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Activar a entrada de comandos aleatoria (só para tests)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Activar a iluminación suave con oclusión de ambiente simple.\n" +"Desactivar para velocidade ou vistas diferentes." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Activar para impedir a conexión de clientes antigos.\n" +"Os clientes máis antigos son compatibles porque non fallarán ao conectarse\n" +"a novos servidores, pero é posible que non sexan compatibles todas as " +"funcións novas que esperan." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Activa o uso do servidor multimedia remoto (se o proporciona o servidor).\n" +"Os servidores remotos ofrecen unha forma máis rápida de descargar datos (por " +"exemplo, texturas)\n" +"ao conectarse ao servidor." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Activar os objectos buffer de vértice.\n" +"Isto debería mellorar muito o rendimento gráfico." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Activa o balanceo de vista e canto o fai.\n" +"Por exemplo: 0 para nada de balanceo; 1.0 para o normal; 2.0 para o dobre." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Activa/desactiva a execución dun servidor IPv6.\n" +"Ignorado se establécese bind_address.\n" +"É preciso enable_ipv6 para activalo." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Activa o mapeo de tons fílmicos 'Uncharted 2' de Hable.\n" +"Simula a curva de ton da película fotográfica e como esta se aproxima á\n" +"aparición de imaxes de alto rango dinámico. O contraste de gama media é\n" +"un poulllo mellor, pois as luces e as sombras comprímense gradualmente." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Activa a animación de obxetos no inventario." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Activa o rexistro de mallas xiradas." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Activa o minimapa." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Activa o son.\n" +"Se está desactivado, deixarán de escoitarse todos os sons e os sons do xogo\n" +"xa non funcionarán.\n" +"Para cambiar esta configuración, é necesario reiniciar." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Permite compensar para reducir a carga da CPU ou aumenta o desempeño de " +"renderización\n" +"a costa de pequenos falllos visuais que non afectan á hora de xogar." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Perfil dos vales" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Intervalo de exposición dos datos da perfilaxe do motor" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Métodos de entidade" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Expoñente do estreitamento da terreo flotante. Altera este comportamento.\n" +"O valor = 1,0 crea un estrechamento uniforme e lineal.\n" +"Os valores > 1.0 crean un afilamento suave adecuado para a separación " +"predeterminada\n" +"cháns flotantes.\n" +"Os valores < 1,0 (por exemplo 0,25) crean un nivel de superficie máis " +"definido con\n" +"cháns baixas máis planas, adecuadas para unha capa sólida de terreo flotante." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS cando está en segundo plano ou pausado" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Factor de ruído" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Factor de balanceo en caída" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Camiño da fonte alternativa" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Tecla de correr" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Aceleración no modo rápido" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Velocidade do modo rápido" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Movemento rápido" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Movemento rápido (vía tecla \"Aux1\").\n" +"É preciso o permiso \"fast\" no servidor." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Campo de visión" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Campo de visión en grados." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Ficheiro no cartafol client/serverlist/ que contén os seus servidores " +"favoritos.\n" +"Móstranse na xanela de Xogar en liña." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Profundidade de recheo" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Ruído da profundidade de recheo" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Mapa de tons fílmico" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"As texturas filtradas poden combinar valores RGB con áreas totalmente " +"transparentes.\n" +"que os optimizadores PNG adoitan descartar, a miúdo resultando en\n" +"bordos claros ou escuros en texturas transparentes. Aplique un filtro para " +"limpalo\n" +"no tempo de carga da textura. Isto habilitarase automaticamente se o " +"\"mipmapping \"está activado." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Suavizado:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Primeiro de 4 ruídos 2D que xuntos definen a altura de outeiros/montañas." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Primeiro de 2 ruídos 3D que xuntos definen túneis." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Semente de mapa fixa" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Joystick virtual fixo" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Densidade dos terreos flotantes" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Valor máximo de Y dos terreos flotantes" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Valor mínimo de Y dos terreos flotantes" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Ruído de terreos flotantes" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Expoñente de conicidade de terreos flotantes" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Distancia cónica de terreos flotantes" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Nivel da auga de terreos flotantes" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Tecla de voo" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Voar" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Néboa" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Inicio de néboa" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Alt. néboa" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Tamaño da fonte" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Fonte en negra por defecto" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Fonte en cursiva por defecto" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Sombra da fonte" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Opacidade da sombra da fonte" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Tamaño da fonte" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Tamaño da fonte divisible por" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Tamaño da fonte por defecto. 1 unidade = 1 píxel en 96 DPI" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Tamaño da fonte monoespacial. 1 unidade = 1 píxel en 96 DPI" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Tamaño da fonte do texto do chat reciente e do indicador do chat en puntos " +"(pt).\n" +"O valor 0 utilizará o tamaño de fonte por defecto." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"Para fontes de estilo píxel que non se escalan ben, isto garante que se " +"utilicen os tamaños de letra\n" +"con este tipo de letra sempre serán divisible por este valor, en píxeles. " +"Por exemplo,\n" +"un tipo de letra de 16 píxeles de alto debería ter este valor establecido en " +"16, polo que só o será\n" +"tamaño 16, 32, 48, etc., polo que un mod que solicite un tamaño de 25 obterá " +"32." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Formato dos mensajes do chat do xogador. As seguintes cadeas son válidas:\n" +"@name, @message, @timestamp (opcional)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Formato das capturas de pantalla." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Cor de fondo por defecto para formularios" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Opacidade de fondo por defecto para formularios" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Cor de fondo para formularios en pantalla completa" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Opacidade dos formularios en pantalla completa" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Cor de fondo por defecto para os formularios (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Opacidade por defecto do fondo dos formularios (entre 0 e 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Cor de fondo para os formularios en pantalla completa(R, G, B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "Opacidade de fondo por defecto para os formularios (entre 0 e 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Tecla avance" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "Cuarto de 4 ruídos 2D que xuntos definen a altura das montañas." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Tipo de fractal" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Fracción de distancia visible na que a néboa comeza a aparecer" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Distancia máxima de xeración de bloques para clientes, en mapblocks (16x3 " +"bloques)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Distancia máxima de envío de bloques para clientes, en mapblocks (16 nós)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Onde ata os clientes receben información dos obxectos, indicado en bloques " +"(16 nós).\n" +"\n" +"Establecer isto máis grande que active_block_range tamén fará que o " +"servidor\n" +"manteña os obxectos activos ata esta distancia na dirección que o\n" +"xogador está mirando. (Isto pode evitar que os enemigos desaparezan " +"repentinamente)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Pantalla completa" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Modo de pantalla completa." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Escala de IGU" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Filtro de escala de IGU" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Filtro de escala de IGU \"txr2img\"" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Xogos" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Chamadas de retorno globais" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Atributos globais do xerador de mundos.\n" +"En Mapgen v6 o marcador \"decoracións\" controla todas as decoracións " +"excepto as árbores\n" +"e herba da selva, en todos os demais xeradores de mundos este marcador " +"controla todas as decoracións." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Gradiente da curva de luz no nivel máximo de luz.\n" +"Controla o contraste dos niveis de luz máis altos." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Gradiente da curva de luz no nivel mímino de luz.\n" +"Controla o contraste dos niveis de luz máis baixos." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Gráficos" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Gráficos" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Gráficos" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravidade" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Nivel do chán" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Ruído do chán" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "Mods HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Escala de IGU" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Alt. HUD" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Manexo de chamadas obsoletas da API de Lua:\n" +"- none: non rexistrar chamadas obsoletas\n" +"- log: imitar e rexistrar o rexistro de chamadas obsoletas (por defecto).\n" +"- error: abortar ao usar a chamada obsoleta (suxerido para desenvolvedores " +"do mod)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Ter o propio instrumento de análise do mundor:\n" +"* Instrumentar unha función baleira.\n" +"Isto estima a sobrecarga que a instrumentación está engadindo (chamada de " +"función +1).\n" +"* Instrumentar a mostraxe que se utiliza para actualizar as estatísticas." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Ruído de mestura de calor" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Ruído da calor" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Componente de altura do tamaño inicial xanela inicial. Ignórase en pantalla " +"completa." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Altura do ruído" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Altura do ruído seleccionado" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Desnivel do outeiro" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Límites do outeiro" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Sonido de outeiros 1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Sonido de outeiros 2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Sonido de outeiros 3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Sonido de outeiros 4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Páxina web do servidor. Mostrarase na lista de servidores." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Aceleración horizontal no aire ao saltar ou caer,\n" +"en nodos por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Aceleración horizontal e vertical en modo rápido,\n" +"en nodos por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Aceleración horizontal e vertical no chán ou ao escalar,\n" +"en nodos por segundo." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Tecla de próximo obxecto na barra principal" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Tecla de obxecto anterior na barra principal" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Tecla de rañura 1" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Tecla de rañura 10" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Tecla de rañura 11" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Tecla de rañura 12" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Tecla de rañura 13" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Tecla de rañura 14" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Tecla de rañura 15" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Tecla de rañura 16" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Tecla de rañura 17" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Tecla de rañura 18" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Tecla de rañura 19" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Tecla de rañura 2" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Tecla de rañura 20" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Tecla de rañura 21" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Tecla de rañura 22" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Tecla de rañura 23" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Tecla de rañura 24" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Tecla de rañura 25" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Tecla de rañura 26" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Tecla de rañura 27" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Tecla de rañura 28" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Tecla de rañura 29" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Tecla de rañura 3" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Tecla de rañura 30" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Tecla de rañura 31" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Tecla de rañura 32" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Tecla de rañura 4" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Tecla de rañura 5" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Tecla de rañura 6" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Tecla de rañura 7" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Tecla de rañura 8" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Tecla de rañura 9" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Profundidade dos ríos." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Velocidade das ondas dos líquidos. Máis alto = máis rápido.\n" +"Se o valor é negativo, as ondas moveranse cara atrás.\n" +"É necesario activar a ondulación dos líquidos." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Tempo de espera do servidor en eliminar bloques non utilizados.\n" +"Canta maior resolución maior fluidez, aínda que consume máis memoria RAM." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Diminúe isto para aumentar a resistencia do líquido ao movemento." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Largura dos ríos." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Ruído de mestura da humidade" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Ruído da humidade" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Variación da humidade dos biomas." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "Servidor IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Se os FPS fosen máis altos que isto, limítaos suspendendo o programa\n" +"para non gastar a potencia da CPU innecesariamente." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Se está desactivado, a tecla \"Aux1\" usarase para voar rápido se o modo voo " +"e rápido están\n" +"ativados." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Se está activado, o servidor realizará a eliminación de oclusión de bloques " +"de mapa baseándose\n" +"na posición dos ollos do xogador. Isto pode reducir o número de bloques\n" +"enviado ao cliente entre un 50 % e un 80 %. O cliente xa non recibirá o máis " +"invisible,\n" +"de xeito que se reduce a utilidade do modo espectador." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Se se activa xunto co modo voar, o xogador poderá voar a través de nós " +"sólidos.\n" +"Isto require o permiso \"noclip\" no servidor." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Se está activada, a tecla \"Aux1\" utilízase en lugar da tecla \"Agacharse\" " +"para baixar e\n" +"descender." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Activar confirmación de rexistro ao se conectar ao servidor\n" +"Se está desactivado, rexistrarase unha nova conta automáticamente." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Se está activado, as accións rexístranse para logo podelas desfacer.\n" +"Esta opción só funciona cando se inicia o servidor." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" +"Se está activado, o sistema de prevención de trampas no modo de xogo en liña " +"desactivarase." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Se está activado, os datos non válidos do mundo non farán que o servidor " +"peche.\n" +"Actívao só se sabes o que fas." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Se está activado, fai direccións de movemento relativas á rotación vertical " +"do xogador cando voa ou nada." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Se está activado, os novos xogadores non poderán unirse con contrasinais " +"baleiros." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Se está activado, pode colocar bloques na posición (pés + nivel dos ollos) " +"onde está.\n" +"Isto é útil cando se traballa con caixas de nós en áreas pequenas." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Se a restrición CSM para o intervalo de nodos está activada, as chamadas " +"get_node están limitadas\n" +"a esta distancia do xogador ao nó." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Se a execución dun comando de chat leva máis tempo do que o especificado en\n" +"segundos, engade a información da hora á mensaxe de comando de chat" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Se o tamaño do ficheiro de debug.txt supera o número de megabytes " +"especificado en\n" +"esta configuración cando se abre, o ficheiro móvese a debug.txt.1,\n" +"eliminando un debug.txt.1 máis antigo se existe.\n" +"debug.txt só se move se esta configuración ten un valor positivo." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" +"Se isto se establece, os xogadores sempre (re) aparecerán na posición " +"indicada." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ignorar erros do mundo" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "Opacidade do fondo da consola do chat no xogo (entre 0 e 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Cor do fondo da consola do chat no xogo (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "Altura da consola do chat no xogo, entre 0,1 (10 %) e 1,0 (100 %)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Tecla para aumentar o volume" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Velocidade vertical ao saltar, en nodos por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Instrumento aplicado.\n" +"Isto case sempre só o necesitan os contribuidores principais" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "Instrumento de comandos do chat no rexistro." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Instrumentación das funcións de chamadas de retorno globais no rexistro.\n" +"(todo o que pasee a unha función minetest.register_*())" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Instrumenta a función de acción dos modificadores de bloque activos no " +"rexistro." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Instrumenta e función de acción de carga de modificadores de bloque no " +"rexistro." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Instrumenta os métodos das entidades durante o rexistro." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Intervalo para gardado de cambios importantes no mundo, indicado en segundos." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Intervalo de envío da hora do dia aos clientes." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animacións dos obxectos do inventario" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Tecla de inventario" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Inverter rato" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Inverter o movemento vertical do rato." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Ruta da fonte cursiva" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Ruta da fonte monoespaciada en cursiva" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "TTL da entidade obxecto" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Iteracións" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Iteracións da función recursiva.\n" +"Aumentar isto aumenta a cantidade de pequenos detalles, pero tamén\n" +"aumenta a carga de procesamento.\n" +"En iteracións = 20 este xerador de mundos ten unha carga similar ao da V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID do joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Intervalo de repetición do botón do joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "Zona morta do joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Sensibilidade do gatillo do joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Tipo de joystick" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Só conxunto de Julia.\n" +"Compoñente W da constante hipercomplexa.\n" +"Altera a forma do fractal.\n" +"Non ten efecto nos fractais 3D.\n" +"Rango de aproximadamente -2 a 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Só conxunto de Julia.\n" +"Compoñente X da constante hipercomplexa.\n" +"Altera a forma do fractal.\n" +"Rango de aproximadamente -2 a 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Só conxunto de Julia.\n" +"Compoñente Y da constante hipercomplexa.\n" +"Altera a forma do fractal.\n" +"Rango de aproximadamente -2 a 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Só conxunto de Julia.\n" +"Compoñente Z da constante hipercomplexa.\n" +"Altera a forma do fractal.\n" +"Rango de aproximadamente -2 a 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Tecla de salto" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Velocidade de salto" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para disminuir o campo de visión.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para disminuir o volume.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para romper bloques.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para soltar o obxecto seleccionado.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para aumentar o campo de visión.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para aumentar o volume.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para saltar.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para moverse máis axilmente en modo rápido.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o xogador cara atrás.\n" +"Tamén desactivará o desprazamento automático cando estea activo.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para moverse cara adiante.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para moverse cara esquerda.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para moverse cara dereita.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para silenciar o xogo.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir a xanela do chat e escribir comandos.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir a xanela do chat e escribir comandos locales.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir a xanela do chat.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir o inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para colocar un obxecto.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 11 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 12 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 13 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 14 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 15 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 16 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 17 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 18 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 19 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 20 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 21 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 22 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 23 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 24 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 25 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 26 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 27 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 28 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 29 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 30 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 31 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 32 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 8 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 5 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 1 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 4 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar o seguinte obxecto na barra de acceso directo do " +"inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 9 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar o obxecto anterior na barra de acceso directo do " +"inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 2 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 7 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 6 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 10 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para seleccionar a rañura 3 do inventario.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para agacharse.\n" +"Tamén serve para descender dentro da auga se aux1_descends está " +"desactivado.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para cambiar entre a cámara en primeira e terceira persoa.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para facer capturas.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar avance automático.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar modo cinemático.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar visualización do minimapa.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar modo rápido.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar voo.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar modo espectador.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar modo de rotación horizontal.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar actualización da cámara. Usado só para o " +"desenvolvemento.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar chat.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar visualización de información de depuración.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar a visualización da néboa.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar visualización do HUD.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar visualización do chat de consola largo.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar a análise do mundo. Emprégase para o desenvolvemento.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar campo de visión ilimitado.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para facer zoom cando sexa posible.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "Expulsar xogadores que enviaron máis de X mensaxes cada 10 segundos." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Inclinación dos lagos" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Límite de lagos no mapa" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Idiomas" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Profundidade das covas grandes" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Número máximo de covas grandes" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Número mínimo de covas grandes" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Proporción de covas grandes inundadas" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Tecla da consola do chat grande" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Apariencia das follas" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Apariencia das follas:\n" +"- Detalladas: todas as caras son visibles\n" +"- Simples: só vense as caras externas, se se utilizan special_tiles " +"definidos\n" +"- Opacas: desactiva a transparencia" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Tecla esquerda" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Duración do tick do servidor e o intervalo no que os obxetos actualízanse " +"polo xeral\n" +"na rede." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Lonxitude das ondas de líquidos.\n" +"É necesario que a ondulación dos líquidos estea activa." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Periodo de tempo entre os ciclos de execución dos ABM" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Periodo de tempo entre os ciclos de execución de NodeTimer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Periodo de tempo entre os ciclos de xestión de bloques activos" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Nivel de rexistro que se gardará en debug.txt:\n" +"- <nothing> (sen rexistro)\n" +"- none (mensaxes sen nivel)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Impulso da curva da luz" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Centro de impulso da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Dispersión de impulso de curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Gamma da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Gradiente alto da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Gradiente baixo da curva de luz" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Iluminación suave" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Límite de xeración de mundos, en nós, nas 6 direccións desde (0, 0, 0).\n" +"Só se xeran fragmentos do mundo dentro do límite.\n" +"O valor almacénase por mundo." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Limita o número de solicitudes paralelas HTTP. Afecta:\n" +"- Recuperación de medios se o servidor usa a configuración " +"\"remote_media\".\n" +"- Descarga da lista de servidores e anuncio do servidor.\n" +"- Descargas realizadas polo menú principal (por exemplo, xestor de mods).\n" +"Só ten efecto se se compila con cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Fluidez dos líquidos" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Suavizado da fluidez dos líquidos" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Límite de procesamento de líquidos" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Tempo para eliminar filas de líquidos" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Afundimento en líquidos" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Intervalo de actualización de líquidos en segundos." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Periodo de actualización dos líquidos" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Cargar a análise do mundo" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Carga a análise do mundo para recoller datos.\n" +"Ofrece un comando /profiler para acceder ao perfil compilado.\n" +"É útil para desenvolvedores de mods e operadores de servidores." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Carga de modiificadores de bloques" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Límite inferior Y de calabozos." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Límite inferior Y de terreos flotantes." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Script do menú principal" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Facer que as cores da néboa e do ceo dependan do día (amencer/posta de sol) " +"e da dirección da vista." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Fai que todos os líquidos sexan opacos" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Nivel de compresión do mapa para almacenamiento de disco" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Nivel de compresión do mapa para tranferencias pola rede" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Directorio de mapas" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" +"Atributos de xeración de mundos específicos do xerador de mundos carpatianos." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Atributos de xeración de mapas específicos de mundos planos.\n" +"Os lagos e outeiros pódense engadir ao mundo plano ás veces." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Atributos de xeración de mundos específicos de mundos planos.\n" +"'terreo' permite a xeración de terreos non fractales:\n" +"océanos, illas e subterráneos." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Atributos de xeración de mapas específicos de xerador de mundos con vales.\n" +"'altitude_chill': reduce a calor coa altitude.\n" +"'humid_rivers': aumenta a humidade arredor dos ríos.\n" +"'vary_river_depth': se está activado, a baixa humidade e a alta calor fan os " +"ríos\n" +"máis profundos e ocasionalmente secos.\n" +"'altitude_dry': reduce a humidade coa altitude." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Atributos de xeración de mundos específicos do xerador de mundos v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Atributos de xeración de mundos específicos do xerador de mundos v6.\n" +"O marcador \"snowbiomes\" activa o novo sistema de 5 biomas.\n" +"Cando o marcador \"snowbiomes\" está activado, as selvas están habilitadas " +"automaticamente e\n" +"o marcador \"selvas\" é ignorado." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Atributos de xeración de mapas específicos do xerador de mundos v7.\n" +"'cristas': ríos.\n" +"'floatlands': masas terrestres flotantes na atmosfera.\n" +"'cavernas': covas xigantes no subsolo." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Límite de xeración de mapas" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Intervalo de gardado de mapa" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "Tempo de actualización das sombras do mapa" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Límite do mapa de bloques" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Retraso da xeración da malla do mapa de bloques" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" +"Tamaño da caché do mapa de bloques do xerador da malla do mapa de bloques en " +"MB" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Tempo límite de eliminación do mapa de bloques" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Xerador de mundos carpatianos" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Parámetros específicos de mundos carpatianos" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Xerador de mundos planos" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Parámetros específicos de mundos planos" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Xerador de mundos fractais" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Parámetros específicos de mundos fractais" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Xerador de mundos v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Parámetros específicos do xerador de mundos v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Xerador de mundos v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Parámetros específicos do xerador de mundos v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Xerador de mundos v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Parámetros específicos do xerador de mundos v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Xerador de mundos con vales" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Parámetros espcíficos o xerador de mundos con vales" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Depuración do xerador de mundos" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Nome do xerador de mundos" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Distancia máxima de xeración de bloques" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Distancia máxima de envío de bloques" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Máximo de líquidos procesados por paso." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Max. clearobjects bloques extra" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Máx. paquetes por iteración" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "FPS máximos" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"FPS máximos cando a xanela non está enfocada ou cando o xogo está en pausa." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Distancia máxima para renderizar as sombras." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Máximo de bloques cargados de maneira forzada" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Largura máxima da barra do inventario" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "Límite máximo de covas grandes aleatorias por chunk." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "Límite máximo de covas pequenas aleatorias por chunk." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Resistencia máxma a líquidos. Controla a desaceleración ao entrar en " +"líquidos a\n" +"alta velocidade." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Número máximo de bloques que se envían simultaneamente por cliente.\n" +"O reconto total máximo calcúlase de forma dinámica:\n" +"max_total = ceil((#clientes + max_users) * por_cliente / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "Número máximo de bloques que se poden poñer en cola para a súa carga." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Número máximo de bloques a poñer en cola que se van xerar.\n" +"Este límite aplícase por xogador." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Número máximo de bloques que se deben poñer en cola que se van cargar desde " +"o ficheiro.\n" +"Este límite aplícase por xogador." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Número máximo de descargas simultáneas. As descargas que superen este límite " +"poñeranse en cola.\n" +"Debería ser inferior a curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Número máximo de bloques de mapa cargados de maneira forzada." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Número máximo de bloques de mapas para que o cliente os manteña na memoria.\n" +"Establecese en -1 para cantidade ilimitada." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Número máximo de paquetes enviados por etapa de envío. Se tes unha conexión " +"lenta\n" +"intenta reducilo, pero non ata un número inferior ao dobre do que ten por " +"obxectivo o cliente." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Número máximo de xogadores que se poden conectar simultaneamente." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Número máximo de mensaxes de chat recientes para mostrar" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Número máximo de obxectos almacenados estáticamente nun bloque." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Obxectos máximos por bloque" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Proporción máxima da xanela actual que se utilizará para a barra do " +"inventario.\n" +"Útil se hai algo para mostrar á dereita ou á esquerda da barra." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Número máximo de envíos de bloques simultáneos por cliente" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Tamaño máximo da cola de saída do chat" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Tamaño máximo da fila de chat de saída.\n" +"0 para desactivar a cola e -1 para que o tamaño da cola sexa ilimitado." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Tempo máximo que pode tardar unha descarga dun ficheiro (por exemplo, un " +"mod), expresado en milisegundos." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Tempo máximo que pode tardar unha solicitude interactiva (por exemplo, a " +"recuperación da lista de servidores), expresado en milisegundos." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Usuarios máximos" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Caché de malla" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Mensaxe do día" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Mensaxe do día mostrada aos xogadores que se conectan." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Método usado para resaltar o obxecto seleccionado." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Nivel mínimo de rexistro para escribir no chat." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Tecla do minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Altura de escaneo do minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Ruído 3D que determina a cantidade de calabozos por chunk." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Límite mínimo do número aleatorio de covas pequenas por chunk." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Tamaño mínimo de textura" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mapeado do relieve" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Análise do mundo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Seguridade" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Canais de mod" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Modifica o tamaño dos elementos do HUD." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Ruta da fonte monoespaciada" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Tamaño da fonte monoespaciada" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "Tamaño da fonte monoespaciada divisible por" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Ruído da altura das montañas" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Ruído das montañas" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Variación do ruído das montañas" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Nivel cero das montañas" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Sensibilidade do rato" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Multiplicador da sensibilidade do rato." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Ruído do lodo" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Multiplicador para balanceo dos brazos en caída.\n" +"Por exemplo: 0 para velos estáticos; 1.0 para normal; 2.0 para o dobre." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Tecla para silenciar" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Silenciar son" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Nome do xerador de mundos que se utilizará ao crear un mundo novo.\n" +"Crear un mundo no menú principal substituirá isto.\n" +"Xeradores de mundos actuais nun estado moi inestable:\n" +"- Os terreos flotantes opcionais de v7 (desactivados por defecto)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Nome do xogador.\n" +"Cando se executa un servidor, os clientes que se conectan con este nome son " +"administradores.\n" +"Ao comezar desde o menú principal, isto substitúese." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Nome do servidor, que se mostrará na lista de servidores e cando os " +"xogadores se unan." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Plano cercano" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Porto de rede para recibir ratos (UDP).\n" +"Este valor substituirase ao comezar desde o menú principal." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Rede" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Os novos usuarios deben introducir este contrasinal." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Modo espectador" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Tecla para modo espectador" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Resaltar nodos" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Resaltado dos nós" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Intervalo NodeTimer" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Ruídos" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Número de fíos emerxentes" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Número de fíos emerxentes a usar.\n" +"Valor 0:\n" +"- Selección automática. O número de fíos emerxentes será\n" +"- \"número de procesadores - 2\", cun límite inferior de 1.\n" +"Calquera outro valor:\n" +"- Especifica o número de fíos emerxentes, cun límite inferior de 1.\n" +"AVISO: aumentar o número de fíos emerxentes aumenta o mundo do motor\n" +"velocidade, pero isto pode prexudicar o rendemento do xogo ao interferir con " +"outros\n" +"procesos, especialmente en modo único e/ou cando se executa código Lua\n" +"'on_xerado'. Para moitos usuarios, a configuración óptima pode ser \"1\"." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Número de bloques adicionais que se poden cargar con /clearobjects á vez.\n" +"Esta é unha compensación entre a sobrecarga de transaccións de SQLite e\n" +"consumo de memoria (4096=100MB, como regra xeral)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Líquidos opacos" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" +"Opacidade (alfa) da sombra detrás do tipo de letra por defecto, entre 0 e " +"255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Abre o menú de pausa cando se perda o foco da xanela. Non se detén se hai " +"unha especificación de formulario\n" +"aberto." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Substitución opcional da cor da ligazón web do chat." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Camiño da fonte alternativa. Debe ser un tipo de letra TrueType.\n" +"Emprégarase para certos idiomas ou se o tipo de letra por defecto non está " +"dispoñible." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Camiño onde gardar capturas de pantalla. Pode ser un camiño absoluto ou " +"relativo.\n" +"O cartafol crearase se aínda non existe." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Camiño ao directorio dos sombreadores. Se non se define ningún, utilizarase " +"a localización por defecto." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "Camiño ao directorio de texturas. Primeiro búscanse alí." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Camiño ao tipo de letra por defecto. Debe ser un tipo de letra TrueType.\n" +"Usarase o tipo de letra alternativo se non se pode cargar." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Camiño ao tipo de letra monoespacial. Debe ser un tipo de letra TrueType.\n" +"Este tipo de letra úsase para, por exemplo, a consola e a pantalla da " +"análise do mundo." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Pausa cando se perfe o foco da pantalla" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "Límite por xogador de carga de bloques en cola desde o disco" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Límite por xogador de bloques en cola que xerar" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Físicas" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Tecla de voo libre" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Modo de rotación vertical" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Tecla para colocar obxectos" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Intervalo de repetición da acción \"colocar\"" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"O xogador é capaz de voar sen ser afectado pola gravidade.\n" +"Isto require o permiso \"fly\" no servidor." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Distancia de transferencia do xogador" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Xogador contra xogador" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Filtrado de Poisson" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Porto para conectarse á (UDP).\n" +"Ten en conta que o campo do porto do menú principal substitúe esta " +"configuración." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Evita que a acción de romper e colocar bloques se repitan cando se manteñen " +"os botóns do rato.\n" +"Activa isto se rompes ou colocas bloques por accidente moitas veces." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Evita que os mods fagan cousas perigosas como executar comandos de shell." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Expor os datos da perfilaxe en intervalos regulares (en segundos).\n" +"0 = desactivar. Útil para desenvolvedores." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Permisos que poden conceder os xogadores con basic_privs" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Análise do mundo" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Alt. análise do mundo" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Enderezo do Prometheus" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Enderezo do Prometheus.\n" +"Se Minetest se compila coa opción ENABLE_PROMETHEUS activada,\n" +"habilita a obteción de métricas para Prometheus nese enderezo.\n" +"As métricas pódense obter en http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Proporción de covas grandes que conteñen líquido." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Rango da área de nubes indicado nun número de 64 cadrados de nubes de nós.\n" +"Os valores superiores a 26 comezarán a producir cortes nítidos nas esquinas " +"da área de nubes." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Eleva o terreo para facer vales arredor dos ríos." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Entrada aleatoria" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Tecla de campo de visión" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Mensaxes do chat recientes" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Camiño da fonte regular" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Medios remotos" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Porto remoto" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Elimina os códigos de cores das mensaxes de chat entrantes\n" +"Usa isto para evitar que os xogadores poidan usar cor nas súas mensaxes" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Substitúe o menú principal por defecto por un personalizado." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Directorio para logs" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Restrinxe o acceso de algunhas funcións do cliente en servidores.\n" +"Combine isto de abaixo para restrinxir recursos aos clientes ou coloque 0 " +"para que non haxa restriccións:\n" +"LOAD_CLIENT_MODS: 1 (desactiva a carga de mods no cliente)\n" +"CHAT_MESSAGES: 2 (desactiva a chamada \"send_chat_message\" no cliente)\n" +"READ_ITEMDEFS: 4 (desactiva a chamada \"get_item_def\" no cliente)\n" +"READ_NODEDEFS: 8 (desactiva a chamada \"get_node_def\" no cliente)\n" +"LOOKUP_NODES_LIMIT: 16 (desactiva a chamada \"get_node\" no cliente para " +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (desactiva a chamada \"get_player_names\" no cliente)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Ruído de extensión do cume de montañas" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Ruído da cresta da montaña" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Ruído das cristas debaixo da auga" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Ruído do tamaño das dorsais das montañas" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Tecla dereita" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Profundidade da canle do río" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Largura da canle do río" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Profundidade do río" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Ruído do río" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Tamaño do río" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Largura do val do río" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Rexistro das accións" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Tamaño do ruído de outeiros redondeados" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Ruído espallado de outeiros redondeados" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Minimapa circular" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Remover e colocar obxectos de maneira segura" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Aparecen praias areosas cando \"np_beach\" supera este valor." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Gardar o mapa recibido polo cliente no disco." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Gardar automaticamente o tamaño da xanela cando é modificado." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Gardar mapa recibido do servidor" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Escala a GUI por un valor especificado polo usuario.\n" +"Use o filtro antialias de veciño máis próximo para escalar a GUI.\n" +"Isto suavizará algúns dos bordos ásperos e mestura\n" +"píxeles ao reducir a escala, a costa de difuminar algúns\n" +"píxeles de bordo cando as imaxes son escaladas por tamaños non enteiros." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Pantalla:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Altura da xanela" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Largura da xanela" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Cartafol das capturas" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Formato de captura de pantalla" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Calidade de captura de pantalla" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Calidade da captura de pantalla. Só se usa para formato JPEG.\n" +"1 é a peor calidade; 100 é a mellor calidade.\n" +"Usa 0 para a calidade por defecto." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Captura" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Sonido do fondo marino" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Segundo de 4 ruídos 2D que xuntos definen a altura de outeiros/montañas." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Segundo de 2 ruídos 3D que xuntos definen túneis." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Ver https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Cor dos bordes da caixa de selección (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Cor da caixa de selección" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Largura da caixa de selección" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Escolle un dos 18 tipos de fractais:\n" +"1 = Conxunto 4D de Mandelbrot \"Roundy\".\n" +"2 = Conxunto 4D de Julia \"Roundy\".\n" +"3 = Conxunto 4D de Mandelbrot \"Squarry”.\n" +"4 = Conxunto 4D de Julia \"Squarry”.\n" +"5 = Conxunto 4D de Mandelbrot \"Mandy Cousin\".\n" +"6 = Conxunto 4D de Julia \"Mandy Cousin\".\n" +"7 = Conxunto 4D de Mandelbrot \"Variation\".\n" +"8 = Conxunto 4D de Julia \"Variation\".\n" +"9 = Conxunto 4D de Mandelbrot \"Mandelbrot/Mandelbar\".\n" +"10 = Conxunto 3D de Julia \"Mandelbrot/Mandelbar”.\n" +"11 = Conxunto 3D de Mandelbrot \"Christmas Tree\".\n" +"12 = Conxunto 3D de Julia \"Christmas Tree\".\n" +"13 = Conxunto 3D de Mandelbrot \"Mandelbulb\".\n" +"14 = Conxunto 3D de Julia \"Mandelbulb\".\n" +"15 = Conxunto 3D de Mandelbrot \"Cosine Mandelbulb\".\n" +"16 = Conxunto 3D de Julia \"Cosine Mandelbulb\".\n" +"17 = Conxunto 3D de Mandelbrot \"Mandelbulb\".\n" +"18 = Conxunto 3D de Julia \"Mandelbulb\"." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL do servidor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Nome do servidor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Descripción do servidor" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL do servidor" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Enderezo do servidor" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Descripción do servidor" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Nome do servidor" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Porto do servidor" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Determinar bloques invisibles do lado do servidor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Porto do servidor" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL da lista de servidores" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "URL da lista de servidores" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Ficheiro da lista de servidores" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Establece o idioma. Deixa o campo baleiro para usar o idioma do sistema.\n" +"É necesario reiniciar despois de cambiar isto." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Establece a lonxitude máxima de caracteres dunha mensaxe de chat enviada " +"polos clientes." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Establece a forza da sombra.\n" +"Un valor máis baixo son sombras máis claras, un valor máis alto son sombras " +"máis escuras." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Establece o tamaño do raio de sombras suaves.\n" +"Os valores máis baixos son sombras máis nítidas, os valores maiores " +"significan son máis suaves.\n" +"Valor mínimo: 1,0; valor máximo: 10,0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Establece a inclinación da órbita Sol/Lúa en graos.\n" +"O valor de 0 é sen inclinación/órbita vertical.\n" +"Valor mínimo: 0,0; valor máximo: 60,0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Establece o valor verdadeiro para activar o mapeado de sombras.\n" +"É necesario que os sombreadores estean activados." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Establece o valor verdadeiro para activar o movemento das follas.\n" +"É necesario que os sombreadores estean activados." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Establece o valor verdadeiro para activar o movemento dos líquidos (auga, " +"por exemplo).\n" +"É necesario que os sombreadores estean activados." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Establece o valor verdadeiro para activar o movemento das plantas.\n" +"É necesario que os sombreadores estean activados." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Establece a calidade da textura da sombra en 32 bits.\n" +"En valor falso, utilizarase textura de 16 bits.\n" +"Isto pode causar moitos máis detalles na sombra." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Camiño dos sombreadores" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Os sombreadores permiten efectos visuais avanzados e poden aumentar o " +"rendemento nalgunhas\n" +"tarxetas de vídeo.\n" +"Isto só funciona con o modo de vídeo OpenGL." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Calidade do filtro de sombras" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "Distancia do mapa de sombras en nós para renderizar sombras" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "Textura do mapa de sombras en 32 bits" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Tamaño da textura do mapa de sombras" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Desfase de sombra (en píxeles) da fonte por defecto. Se é 0, non se fará a " +"sombra." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "Intensidade da sombra" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Forma do minimapa. Activado = redondo, desactivado = cadrado." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Mostrar información de depuración" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Mostrar as caixas de selección de entidades" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Mostrar as caixas de selección de entidades\n" +"É necesario reiniciar despois de cambiar isto." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Mostra os fondos das etiquetas de nome por defecto" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Mensaxe de desconexión" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Tamaño dos chunks que creou o xerador de terreos, indicado en bloques (16 " +"nós).\n" +"AVISO!: Non hai ningún beneficio, e hai varios perigos, ao\n" +"aumentar este valor por riba de 5.\n" +"Reducir este valor aumenta a densidade de covas e calabozos.\n" +"Modificar este valor é para uso especial. Recoméndase non modificalo." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Tamaño da caché do xerador de terreos do xerador de malla. Isto fai que\n" +"aumentae o % de acertos da caché, reducindo os datos que se copian do fío\n" +"principal, reducindo así a fluctuación." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Inclinación da órbita do ceo" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Porción w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Pendente e recheo traballan xuntos para modificar as alturas." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Cantidade máxima de covas pequenas" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Cantidade mínima de covas pequenas" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" +"Variación de humidade a pequena escala para mesturar biomas nos bordes." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" +"Variación de temperatura a pequena escala para mesturar biomas nos bordes." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Iluminación suave" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Suaviza a cámara ao mirar arredor. Tamén se chama suavización do rato.\n" +"Útil para gravar vídeos." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "Suaviza a rotación da cámara en modo cinemático. 0 para desactivar." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Suaviza a rotación da cámara. 0 para desactivar." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Tecla para agacharse" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Velocidade ao estar agachado" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Velocidade ao se agachar, en nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Radio das sombras suaves" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Son" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Especifica o URL do que o cliente obtén os medios en lugar de usar UDP.\n" +"$filename debe ser accesible desde $remote_media$filename a través de cURL\n" +"(obviamente, remote_media debería rematar cunha barra).\n" +"Os ficheiros que non están presentes buscaranse do xeito habitual." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Especifica a cantidade por defecto na que se agrupan os nós, obxectos e " +"ferramentas.\n" +"Ten en conta que algúns xogos ou mods poden especificar unha cantidade na " +"que agrupar algúns (ou todos) os obxectos." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Distribuír unha actualización completa do mapa de sombras sobre unha " +"determinada cantidade de fotogramas.\n" +"Os valores máis altos poden facer que as sombras sexan latentes e os valores " +"máis baixos\n" +"consumirán máis recursos.\n" +"Valor mínimo: 1; Valor máximo 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Difusión do intervalo de aumento da curva de luz.\n" +"Controla a largura do intervalo que se quere aumentar.\n" +"A desviación estándar da curva de luz gaussiana aumenta." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Punto de aparición estático" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Ruído das pendentes" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Ruído do tamaño das montañas de paso" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Ruído doespallamento das montañas de paso" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Intensidade do modo de paralaxe 3D." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Ampliación da curva de luz.\n" +"Os 3 parámetros de \"impulso\" definen un rango da curva\n" +"de luz que aumenta o brillo." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Verificación estricta do protocolo" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Eliminar códigos de cores" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Nivel superficial de auga opcional colocado sobre unha capa sólida de terreo " +"flotante.\n" +"A auga está desactivada por defecto e só se colocará se se establece este " +"valor\n" +"arriba 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (o inicio do\n" +"afilamento superior).\n" +"***ADVERTENCIA, PERIGO POTENCIAL PARA OS MUNDOS E O RENDEMENTO DO " +"SERVIDOR***:\n" +"Ao activar a colocación de auga débense configurar e probar os terreos " +"flotantes\n" +"para ser unha capa sólida configurando 'mgv7_floatland_density' en 2.0 (ou " +"outro\n" +"valor necesario en función de 'mgv7_np_floatland'), para evitar\n" +"fluxo de auga extremo intensivo en servidores e evitar grandes inundacións " +"do\n" +"superficie do mundo abaixo." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "SQLite sincrónico" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Variación de temperatura para biomas." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Configuración" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Ruído alternativo do terreo" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Ruído base do terreo" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Altura do terreo" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Maior ruído do terreo" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Ruído do terreo" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Limiar de ruído do terreo para outeiros.\n" +"Controla a proporción da superficie do mundo cuberta por outeiros.\n" +"Axusta cara a 0,0 para unha proporción maior." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Limiar de ruído do terreo para lagos.\n" +"Controla a proporción da superficie do mundo cuberta por lagos.\n" +"Axusta cara a 0,0 para unha proporción maior." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Ruído de persistencia do terreo" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Camiño dos packs de textura" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Tamaño da textura para renderizar o mapa de sombras.\n" +"Este debe ser un poder de dous.\n" +"Os números máis grandes crean mellores sombras pero tamén consume máis." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"As texturas dun nodo poden estar aliñadas co nó ou co mundo.\n" +"O primeiro modo se adapta mellor a cousas como máquinas, mobles, etc., " +"mentres\n" +"este último fai que as escaleiras e os microbloques se adapten mellor ao " +"contorno.\n" +"Non obstante, como esta posibilidade é nova, non pode ser utilizada por " +"servidores máis antigos,\n" +"esta opción permite aplicala para certos tipos de nodos. Ten en conta que\n" +"que se considera EXPERIMENTAL e pode non funcionar correctamente." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "O URL do repositorio de contido" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "A zona morta do joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"O formato por defecto no que se gardan as análises do mundo,\n" +"ao chamar a `/profiler save [format]` sen formato." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "A profundidade da chán ou outro nó de recheo do bioma." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"O camiño do ficheiro relativa ao camiño do mundo no que se gardarán os " +"perfís." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "O identificador do joystick que se vai utilizar" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"A lonxitude en píxeles que tarda en iniciar a interacción da pantalla táctil." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"Altura máxima da superficie de líquidos con ondas.\n" +"4.0 = Altura da onda é dous nós.\n" +"0.0 = A onda non se move.\n" +"Por defecto é 1.0 (medio nó).\n" +"É necesario activar os líquidos con ondas." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "A interface de rede na que o servidor agarda a conexión." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Os permisos que obteñen automaticamente os novos usuarios.\n" +"Consulta /privs no xogo para ver unha lista completa do teu servidor e da " +"configuración do mod." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"O radio do volume de bloques ao redor de cada xogador que está suxeito ao\n" +"material de bloque activo, indicado en bloques de mapas (16 nós).\n" +"Nos bloques activos cárganse obxectos e execútanse os ABM.\n" +"Este é tamén o intervalo mínimo no que se manteñen os obxectos activos " +"(mobs).\n" +"Isto debería configurarse xunto con active_object_send_range_blocks." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"O motor de renderizado.\n" +"É necesario un reinicio logo de cambiar isto.\n" +"Nota: en Android, segue con OGLES1 se non está seguro. A aplicación pode non " +"iniciarse doutro xeito.\n" +"Noutras plataformas recoméndase OpenGL.\n" +"Os sombreadores son compatibles con OpenGL (só para escritorio) e OGLES2 " +"(experimental)" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"A sensibilidade dos eixes do joystick para mover o\n" +"vista no xogo frustum ao redor." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"A intensidade (escuridade) do sombreado de oclusión ambiental do nó\n" +"Abaixo é máis escuro, máis alto é máis claro. O intervalo de valores válido " +"para isto\n" +"a configuración é de 0,25 a 4,0 inclusive. Se o valor está fóra do intervalo " +"será\n" +"establecer o valor válido máis próximo." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"O tempo (en segundos) que a cola de líquidos pode crecer máis alá da " +"capacidade\n" +"de procesamento ata que se intente diminuír o seu tamaño eliminando a cola " +"antiga de\n" +"elementos. Un valor de 0 desactiva isto." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"O tempo permitido aos ABM para executarse en cada paso\n" +"(como unha fracción do intervalo ABM)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"O tempo en segundos que tarda entre eventos repetidos\n" +"ao manter premida unha combinación de botóns do joystick." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"O tempo en segundos que tarda entre colocacións repetidas de nodos cando se " +"mantén presionado\n" +"o botón de colocar obxectos." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "O tipo de joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"A distancia vertical sobre a que a calor cae 20 se é 'altitude_chill'\n" +"activado. Tamén a distancia vertical na que a humidade cae 10 se\n" +"'altitude_dry' está activado." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Terceiro de 4 ruídos 2D que xuntos definen a altura de outeiros/montañas." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Tempo en segundos para que a entidade de obxecto (obxectos tirados) viva.\n" +"Axustándoo a -1 desactiva a función." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "Hora do día en que se inicia un novo mundo, en milihoras (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Intervalo de envío de tempo" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Velocidade do tempo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Tempo de espera para que o cliente elimine os datos do mapa non utilizados " +"da memoria." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Para reducir a latencia, as transferencias en bloque son máis lentas cando " +"un xogador está a construír algo.\n" +"Isto determina canto tempo se ralentizan despois de colocar ou eliminar un " +"nó." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Tecla para alternar o modo cámara" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Atraso da información sobre ferramentas" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Límite da pantalla táctil" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Límite da pantalla táctil" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "Compensacións para o rendemento" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Ruído das árbores" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Filtrado trilineal" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"Verdadeiro = 256\n" +"Falso = 128\n" +"Pódese usar para facer o minimapa máis suave en ordenadores máis lentos." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Mods seguros" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL á lista de servidores que aparece na xanela Xogo en liña." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Submostraxe" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"A submostraxe é semellante ao uso dunha resolución de pantalla inferior, " +"pero aplícase\n" +"só para o mundo, mantendo a GUI intacta.\n" +"Debería dar un aumento máis significativo do rendemento a costa dunha imaxe " +"menos detallada.\n" +"Os valores máis altos dan como resultado unha imaxe menos detallada." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Distancia de transferencia de xogador ilimitada" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Eliminar datos do servidor non utilizados" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Límite Y superior dos calabozos." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Límite Y superior dos terreos flotantes." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Activa as nubes 3D en lugar de nubes 2D (planas)." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Usa unha animación de nube para o fondo do menú principal." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "Usa o filtro anisótropo ao ver texturas desde un ángulo." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Usa o filtro bilineal ao escalar texturas." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Usa o mipmapping para escalar texturas. Pode aumentar lixeiramente o " +"rendemento,\n" +"sobre todo cando se usa un paquete de texturas de alta resolución.\n" +"Non se admite a redución de escala correcta gamma." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Use o suavizado de varias mostras (MSAA) para suavizar os bordos do bloque.\n" +"Este algoritmo suaviza a ventana 3D mentres mantén a imaxe nítida,\n" +"pero non afecta o interior das texturas\n" +"(nótase especialmente con texturas transparentes).\n" +"Aparecen espazos visibles entre os nós cando os sombreadores están " +"desactivados.\n" +"Se se establece en 0, MSAA está desactivado.\n" +"É necesario reiniciar logo de cambiar esta opción." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Usa o filtro trilineal ao escalar texturas." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Sincronizaión vertical" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Profundade dos vales" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Recheo dos vales" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Perfil dos vales" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Inclinación dos vales" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Variación da profundidade do recheo do bioma." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Variación da altura máxima da montaña (en nós)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Variación do número de covas." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Variación da escala vertical do terreo.\n" +"Cando o ruído é < -0,55 o terreo é case plano." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Variación da profundidade dos nós da superficie do bioma." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Varía a rugosidade do terreo.\n" +"Define o valor de \"persistencia\" para os ruídos \"chánin_base\" e " +"\"chánin_alt\"." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Varía a pendiente dos acantilados." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Velocidade de escalada vertical, en nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Sincronización de pantalla vertical." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Controlador de vídeo" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Ver o factor de balance" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Distancia de visión en nós." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Ver a tecla de diminución do intervalo" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Ver a tecla de aumento do intervalo" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Ver tecla de zoom" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Campo de visión" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "O joystick virtual activa o botón Aux1" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Volume" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Todos os sons.\n" +"É necesario que o son do sistema estea activado." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Coordenada W da porción 3D xerada dun fractal 4D.\n" +"Determina que parte 3D da forma 4D se xera.\n" +"Altera a forma do fractal.\n" +"Non ten efecto sobre os fractais 3D.\n" +"Rango de aproximadamente -2 a 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Velocidade ao camiñar e voar, en nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Velocidade ao camiñar" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Velocidade ao camiñar, voar e escalar no modo rápido, en nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Nivel da auga" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Nivel da superficie da auga no mundo." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Bloques ondulantes" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Movemento das follas" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Ondas dos líquidos" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Altura das ondas dos líquidos" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Velocidade de movemento das ondas dos líquidos" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Movemento das ondas dos líquidos" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Movemento das plantas" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "Cor de ligazóns web" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Cando gui_scaling_filter ten valor verdadeiro, todas as imaxes da GUI deben " +"ser\n" +"filtradas no software, pero algunhas imaxes xéranse directamente\n" +"ao hardware (por exemplo, renderizado en textura para nós do inventario)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Cando gui_scaling_filter_txr2img teña un valor verdadeiro, copia esas " +"imaxes\n" +"do hardware ao software para escalar. Cando sexa falso, retrocede\n" +"ao método de escala antigo para controladores de vídeo que non o fan\n" +"admite correctamente a descarga de texturas desde o hardware." + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Cando se usan filtros bilineais/trilineais/anisótropos, texturas de baixa " +"resolución\n" +"poden ser borrosas, polo que amplíaos automaticamente co veciño máis " +"próximo\n" +"interpolación para preservar píxeles nítidos. Isto establece o tamaño mínimo " +"de textura\n" +"para as texturas mejoradas; valores máis altos parecen máis nítidos, pero " +"requiren máis\n" +"memoria. Recoméndase potencias de 2. Esta configuración só se aplica se\n" +"O filtrado bilineal/trilineal/anisótropo está activado.\n" +"Tamén se usa como tamaño de textura do nodo base para aliñados ao mundo\n" +"autoescalado de texturas." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Indica se os fondos das etiquetas de nome deberían mostrarse por defecto.\n" +"Os mods aínda poden establecer un fondo." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"Indica se as animacións de textura de nós deben desincronizarse por bloque " +"de mapas." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Indica se os xogadores son mostrados aos clientes sen límites.\n" +"Se non, utiliza a configuración player_transfer_distance no seu lugar." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Se permitir que os xogadores se danen e se maten entre si." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Indica se pedir aos clientes volverse conectar logo dun fallo (Lua).\n" +"Establece isto como verdadeiro se o teu servidor está configurado para " +"reiniciarse automaticamente." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Indica se hai que poñar néboa ao final da zona visible." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Indica se hai que silenciar os sons. Podes activar o son en calquera " +"momento, a non ser que\n" +"esté desactivado (enable_sound=false).\n" +"No xogo podes cambiar o estado de silencio coa tecla de silencio ou no\n" +"menú de pausa." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"Debe mostrarse a información de depuración do cliente (premer F5 fai o " +"mesmo)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Componente de largura do tamaño inicial da xanela. Ignórase en pantalla " +"completa." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Largura das liñas do bloque de selección arredor dos nós." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Só sistemas Windows: Inicia Minetest coa xanela da liña de comandos en " +"segundo plano.\n" +"Contén a mesma información que o ficheiro debug.txt (nome por defecto)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Directorio do mundo (todo almacénase aquí).\n" +"Non é necesario se comeza desde o menú." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Horario de inicio do mundo" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"As texturas aliñadas ao mundo pódense escalar para abarcar varios nós. Non " +"obstante,\n" +"é posible que o servidor non envíe a escala que desexa, especialmente se " +"usa\n" +"un paquete de texturas especialmente deseñado; con esta opción, o cliente " +"tenta\n" +"determinar a escala automaticamente baseándose no tamaño da textura.\n" +"Consulte tamén texture_min_size.\n" +"Aviso: esta opción é EXPERIMENTAL!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Modo de texturas aliñadas ao mundo" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y de terreo chán." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y da densidade do gradiente nivel cero das montañas. Úsase para mover " +"montañas verticalmente." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Límite Y máximo das covas grandes." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Distancia Y sobre a cal as cavernas expándense até o seu tamaño total." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Distancia Y sobre a cal os terreos flotantes estrechanse desde a densidade " +"total ata nada.\n" +"A diminución comeza a esta distancia do límite Y.\n" +"Para unha capa sólida de terreo flotante, isto controla a altura dos " +"outeiros/montañas.\n" +"Debe ser menor ou igual á metade da distancia entre os límites Y." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Nivel Y da superficie media do terreo." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Nivel Y do límite superior da caverna." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Nivel Y de terreo que crea acantilados." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Nivel Y do terreo inferior e do solo oceánico." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Nivel Y do fondo do mar." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Tempo límite de descarga do ficheiro por cURL" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "Tempo limite de cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Límite paralelo de cURL" + +#~ msgid "Basic" +#~ msgstr "Básico" + +#~ msgid "Connect" +#~ msgstr "Conectar" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Controla a velocidade de afundimento en líquidos." + +#~ msgid "Del. Favorite" +#~ msgstr "Eliminar fav." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Descarga un xogo como Minetest Game en minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Descarga un en minetest.net" + +#~ msgid "Enable register confirmation" +#~ msgstr "Activar confirmación de rexistro" + +#~ msgid "Enter " +#~ msgstr "Introducir: " + +#~ msgid "Filtering" +#~ msgstr "Filtrado" + +#~ msgid "Game" +#~ msgstr "Xogo" + +#~ msgid "HUD scale factor" +#~ msgstr "Factor de escala HUD" + +#~ msgid "In-Game" +#~ msgstr "No xogo" + +#~ msgid "Instrumentation" +#~ msgstr "Instrumentación" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "Combinacións de teclas" + +#~ msgid "Menus" +#~ msgstr "Menús" + +#~ msgid "Player name" +#~ msgstr "Nome do xogador" + +#~ msgid "Profiling" +#~ msgstr "Perfilaxe" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Servidor / Un xogador" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Estás a piques de unirte ao servidor \"%s\" por primeira vez.\n" +#~ "Se continúas, crearase unha nova conta neste servidor usando as túas " +#~ "credenciais.\n" +#~ "Reescribe o teu contrasinal e fai clic en \"Rexistrarse e unirse\" para " +#~ "confirmar a creación da conta ou fai clic en \"Cancelar\" para deter o " +#~ "proceso." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Morreches" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/he/minetest.po b/po/he/minetest.po new file mode 100644 index 0000000..f396cc0 --- /dev/null +++ b/po/he/minetest.po @@ -0,0 +1,7122 @@ +msgid "" +msgstr "" +"Project-Id-Version: Hebrew (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2021-04-17 07:27+0000\n" +"Last-Translator: Omer I.S. <omeritzicschwartz@gmail.com>\n" +"Language-Team: Hebrew <https://hosted.weblate.org/projects/minetest/minetest/" +"he/>\n" +"Language: he\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " +"n % 10 == 0) ? 2 : 3));\n" +"X-Generator: Weblate 4.6-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Empty command." +msgstr "פקודות צ'אט" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "יציאה לתפריט" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Invalid command: " +msgstr "פקודה מקומית" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "שחקן יחיד" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "שחקן יחיד" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "הזדמן" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "מתת" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "פקודה מקומית" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "פקודה מקומית" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "אישור" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "אירעה שגיאה בתסריט Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "אירעה שגיאה:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "תפריט ראשי" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "התחברות מחדש" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "השרת מבקש התחברות מחדש:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "בחירת שיפורים" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "שגיאה בגרסאות הפרוטוקול. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "השרת מחייב שימוש בגרסת פרוטוקול $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "השרת תומך בפרוטוקולים בין גרסה $1 וגרסה $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "אנו תומכים רק בגירסה 1$ של הפרוטוקול." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "אנו תומכים בגרסאות בין 1$ ל-2$ של הפרוטוקול." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "ביטול" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "תלויות:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "להשבית הכול" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "השבתת ערכת השיפורים" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "להפעיל הכול" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "הפעלת ערכת השיפורים" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"הפעלת השיפור \"1$\" נכשלה מכיוון שהוא מכיל תווים לא חוקיים. רק התווים [a-" +"z0-9_] מותרים." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "חיפוש שיפורים נוספים" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "שיפור:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "אין תלויות (רשות)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "לא סופק תיאור משחק." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "ללא תלויות קשות" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "לא סופק תיאור לערכת השיפורים." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "אין תלויות רשות" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "תלויות אופציונאליות:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "שמירה" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "עולם:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "מופעל" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" כבר קיים. האם תרצה להחליף אותו?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "התלויות $1 ו $2 יותקנו." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 ליד $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 מוריד,\n" +"$2 ממתין" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 כעת בהורדה..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "לא ניתן למצוא תלות חובה של $1." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 יותקן ו $2 תלויות שידולגו." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "כל החבילות" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "כבר מותקן" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "חזרה לתפריט הראשי" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "משחק בסיסי:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "בסיס נתוני התוכן לא זמין כאשר מיינטסט מקומפל בלי cUrl" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "כעת בהורדה..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "הורדת $1 נכשלה" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "משחקים" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "התקנה" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "התקנת $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "מתקין תלויות חסרות" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "התקנה: סוג קובץ לא נתמך \"$1\" או שהארכיב פגום" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "שיפורים" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "לא ניתן להביא את החבילות" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "אין תוצאות" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "אין עדכונים" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "לא נמצא" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "דרוס" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "אנא בדוק שמשחק הבסיס תקין." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "נכנס לתור" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "חבילות טקסטורה (מרקם)" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "הסרה" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "עדכון" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "עדכן הכל [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "צפה במידע נוסף בדפדפן האינטרנט" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "כבר קיים עולם בשם \"$1\"" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "שטח נוסף" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "קור בגבהים" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "יובש בגבהים" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "מיזוג ביומים (אקולוגי)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "ביומים (צמחיה אקולוגית)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "מערות (טבעיות בחלקן מוארות)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "מערות (ללא אור שמש)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "יצירה" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "קישוטים" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "אזהרה: מצב בדיקת הפיתוח נועד למפתחים." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "מבוכים" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "עולם שטוח" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "גושי אדמה צפים בשמים" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "אדמה צפה (נסיוני)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "צור שטח לא פרקטלי: אוקיינוסים ותת קרקעי" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "גבעות" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "נהרות לחים" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "הגברת הלחות בסביבת נהרות" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "התקנת $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "אגמים" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "לחות נמוכה וחום גבוה גורמים לנהרות רדודים או יבשים" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "מנוע (מחולל) מפות" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "אפשרויות מנוע מפות" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "אפשרויות ספציפיות למנוע מפות" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "הרים" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "זרימת בוץ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "רשת מערות ומחילות" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "לא נבחר משחק" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "הפחתה בחום בגובה רב" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "הפחתת הלחות בגובה רב" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "נהרות" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "נהרות בגובה פני הים" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "זרע" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "מעבר חלק בין אזורי אקלים שונים" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "מבנים המופיעים בשטח (אין השפעה על עצים ועשבי ג'ונגל שנוצרו על ידי v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "מבנים המופיעים בשטח, בדרך כלל עצים וצמחים" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "ממוזג, מדברי" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "ממוזג, מדברי, ג'ונגל" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "ממוזג, מדברי, ג'ונגל, טונדרה, טייגה" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "סחף פני השטח" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "עצים ודשא של ג׳ונגל" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "עומק נהרות משתנה" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "מערות גדולות מאוד עמוק מתחת לאדמה" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "שם העולם" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "אין לך משחקים מותקנים." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "האם אכן ברצונך למחוק את \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "מחיקה" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: מחיקת \"$1\" נכשלה" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: נתיב לא חוקי \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "למחוק את העולם \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "אשר סיסמה" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "שם" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "סיסמה" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "סיסמאות לא תואמות!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "הרשם והצטרף" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "הסכמה" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "שינוי שם ערכת השיפורים:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"לערכת שיפורים זו יש שם מפורש שניתן בקובץ modpack.conf שלה שיעקוף כל שינוי שם " +"מכאן." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(לא נוסף תיאור להגדרה)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "רעש דו-מיימדי" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "חזור לדף ההגדרות >" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "דפדף" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "תוכן" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "תוכן" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "מושבת" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "עריכה" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "מופעל" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "מרווחיות" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "אוקטבות" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "היסט" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "התמדה" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "הכנס מספר שלם חוקי." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "הכנס מספר חוקי." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "שחזור לברירת המחדל" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "קנה מידה" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "חיפוש" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "נא לבחור תיקיה" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "נא לבחור קובץ" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "הצגת שמות טכניים" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "הערך חייב להיות לפחות $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "הערך לא יכול להיות גדול מ־$1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "מרווחיות X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "מרווחיות Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "מרווחיות Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "ערך מוחלט" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "ברירת מחדל" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "החלקת ערכים" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (מופעל)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 שיפורים" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "התקנת $1 אל $2 נכשלה" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "התקנת שיפור: לא ניתן למצוא את שם השיפור האמיתי עבור: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "התקנת שיפור: לא ניתן למצוא שם תיקייה מתאים לערכת השיפורים $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "אין אפשרות למצוא שיפור או ערכת שיפורים במצב תקין" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "לא ניתן להתקין $1 כחבילת טקסטורות" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "לא ניתן להתקין משחק בתור $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "אין אפשרות להתקין שיפור בשם $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "אין אפשרות להתקין ערכת שיפורים בשם $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "כעת בטעינה..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "רשימת השרתים הציבורים מושבתת" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"נא לנסות לצאת ולהיכנס מחדש לרשימת השרתים ולבדוק את החיבור שלך לאינטרנט." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "תורמים פעילים" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Active renderer:" +msgstr "טווח שליחת אובייקט פעיל" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "מפתחים עיקריים" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "נא לבחור תיקיית משתמש" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"פותח את התיקייה שמכילה עולמות, משחקים, מודים,\n" +"וחבילות טקסטורה במנהל קבצים." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "תורמים קודמים" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "מפתחי ליבה קודמים" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "עיון בתוכן מקוון" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "תוכן" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "השבתת חבילת המרקם" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "מידע:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "חבילות מותקנות:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "אין תלויות." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "אין תיאור חבילה זמין" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "שנה שם" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "הסרת החבילה" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "שימוש בחבילת המרקם" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "הכרז על השרת" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "הצמד כתובת" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "מצב יצירתי" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "לאפשר חבלה" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "אירוח משחק" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "אכסון שרת" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "התקנת משחק מContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "חדש" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "אין עולם שנוצר או נבחר!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "להתחיל לשחק" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "פורט" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "בחירת שיפורים" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "נא לבחור עולם:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "פורט לשרת" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "התחלת המשחק" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "- כתובת: " + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "נקה" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "מצב יצירתי" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "חבלה" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "מועדף" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "הצטרפות למשחק" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "פינג" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "הכרז על השרת" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "מחק מועדף" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "פורט לשרת" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "x2" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "עננים תלת מימדיים" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "x4" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "x8" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "כל ההגדרות" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "החלקת קצוות (AA):" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "שמור אוטומטית גודל מסך" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "פילטר בילינארי" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "שנה מקשים" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "זכוכיות מחוברות" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "עלים מגניבים" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "מיפמאפ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "מיפמאפ + פילטר אניסוטרופי" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "בלי פילטר" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "בלי מיפמאפ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "הבלטת קוביות" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "הדגשת מסגרת קוביות" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "ללא" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "עלים אטומים" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "מים אטומים לאור" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "חלקיקים" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "מסך:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "הגדרות" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "שיידרים" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "שיידרים (נסיוני)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "שיידרים (לא זמינים)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "עלים פשוטים" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "החלקת תאורה" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "טקסטורות:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "מיפוי גוונים" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "סף נגיעה: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "פילטר תלת לינארי" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "עלים מתנופפים" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "נוזלים עם גלים" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "צמחים מתנוענעים" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "בעיה בחיבור (נגמר זמן ההמתנה?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "זמן המתנה לחיבור אזל." + +#: src/client/client.cpp +msgid "Done!" +msgstr "הסתיים!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "מאתחל קוביות" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "מאתחל קוביות..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "טוען טקסטורות..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "בונה מחדש שיידרים..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "בעיה בחיבור (נגמר זמן ההמתנה?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "לא מצליח למצוא או לטעון משחק \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "הגדרת משחק לא תקינה." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "תפריט ראשי" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "לא נבחר עולם ולא נתנה כתובת. לא עושה כלום." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "שם השחקן ארוך מידי." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "נא לבחור שם!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "הסיסמה שניתנה לא פתחה: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "נתיב העולם שניתן לא קיים: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"בדוק את debug.txt לפרטים נוספים." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- כתובת: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- מצב: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- פורט: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- ציבורי: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- קרב: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- שם שרת: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "אירעה שגיאה:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "התקדמות אוטומטית קדימה מבוטלת" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "תנועה קדימה אוטומטית מופעל" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "עדכון מצלמה מבוטל" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "עדכון מצלמה מופעל" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "שנה סיסמה" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "מצב קולנועי מבוטל" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "מצב קולנועי מופעל" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "קלינט" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "סקריפטים בצד לקוח מבוטלים" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "מתחבר לשרת..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "המשך" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"פקדים:\n" +"- %s: כדי לזוז קדימה\n" +"- %s: כדי לזוז אחורה\n" +"- %s: כדי לזוז שמאלה\n" +"- %s: כדי לזוז ימינה\n" +"- %s: כדי לקפוץ או לטפס למעלה\n" +"- %s: כדי לחפור או לחבוט\n" +"- %s: כדי להניח או להשתמש\n" +"- %s: כדי להתכופף או לטפס למטה\n" +"- %s: כדי לזרוק פריט\n" +"- %s: כדי לפתוח את תיק החפצים\n" +"- עכבר: כדי להסתובב או להסתכל\n" +"- גלגלת העכבר: כדי לבחור פריט\n" +"- %s: כדי לפתוח את הצ׳אט\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "יוצר לקוח..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "יוצר שרת..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "מידע דיבאג וגרף פרופיילר מוסתר" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "מידע דיבאג מוצג" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "מידע דיבאג, גרף פרופיילר, ומצב שלד מוסתר" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"פקדי ברירת מחדל:\n" +"לא נראה תפריט:\n" +"- לחיצה בודדת: הפעלת כפתור\n" +"- הקשה כפולה: מקום / שימוש\n" +"- החלק אצבע: הביט סביב\n" +"תפריט / מלאי גלוי:\n" +"- לחיצה כפולה (בחוץ):\n" +"--> סגור\n" +"- מחסנית מגע, חריץ מגע:\n" +"--> הזז מחסנית\n" +"- גע וגרור, הקש על האצבע השנייה\n" +"--> מקם פריט יחיד לחריץ\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "ביטול טווח ראיה בלתי מוגבל" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "הפעלת טווח ראיה בלתי מוגבל" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "יוצר לקוח..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "יציאה לתפריט" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "יציאה למערכת ההפעלה" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "מצב המהירות מושבת" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "מצב המהירות מופעל" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "מצב המהירות מופעל (לתשומת ליבך: אין הרשאת \"fast\")" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "מצב התעופה מושבת" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "מצב התעופה מופעל" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "מצב התעופה מופעל (לתשומת ליבך: אין הרשאת \"fly\")" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "ערפל מבוטל" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "ערפל מופעל" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "מידע על המשחק:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "המשחק הושהה" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "שרת אירוח" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "הגדרות פריט..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "‏KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "מדיה..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "מגהבייט/שניה" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "מיפמאפ כרגע מבוטל ע\"י המשחק או המוד" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "שחקן יחיד" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "מעבר דרך קירות מבוטל" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "מעבר דרך קירות מופעל" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "מעבר דרך קירות מופעל (שים לב, אין הרשאת 'noclip')" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "הגדרות קוביה..." + +#: src/client/game.cpp +msgid "Off" +msgstr "מכובה" + +#: src/client/game.cpp +msgid "On" +msgstr "דולק" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "תנועה לכיוון מבט מכובה" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "תנועה לכיוון מבט מופעל" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "גרף פרופיילר מוצג" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "שרת מרוחק" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "מפענח כתובת..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "מכבה..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "שחקן יחיד" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "ווליום שמע" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "שמע מושתק" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "מערכת שמע לא מופעלת" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "מערכת שמע לא נתמכת בבניה הנוכחית" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "מערכת שמע מופעלת" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "טווח ראיה השתנה ל %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "טווח ראיה הגיע למקסימום: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "טווח ראיה הגיע למינימום: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "עוצמת שמע שונתה ל %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "מסגרת שלדית מוצגת" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "המבט מקרוב מושבת על ידי המשחק או השיפור" + +#: src/client/game.cpp +msgid "ok" +msgstr "אוקיי" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "צ'אט מוסתר" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "צ'אט מוצג" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "מידע-על-מסך מוסתר" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "מידע-על-מסך מוצג" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "פרופיילר מוסתר" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "פרופיילר מוצג (עמוד %d מתוך %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "אפליקציות" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "קונטרול" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "למטה" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "מחק EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "בצע" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "עזרה" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "קבל IME" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "המרת IME" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "יציאת IME" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "שינוי מצב IME" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME ללא המרה" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "שמאלה" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "הלחצן השמאלי" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "מקש Control השמאלי" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "תפריט שמאלי" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "מקש Shift השמאלי" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "מקש Windows השמאלי" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "תפריט" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "כפתור אמצעי" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "נעילה נומרית" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "מקלדת נומרית *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "מקלדת נומרית +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "מקלדת נומרית -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "מקלדת נומרית ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "מקלדת נומרית /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "מקלדת נומרית 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "מקלדת נומרית 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "מקלדת נומרית 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "מקלדת נומרית 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "מקלדת נומרית 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "מקלדת נומרית 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "מקלדת נומרית 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "מקלדת נומרית 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "מקלדת נומרית 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "מקלדת נומרית 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "ניקוי OME" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "שחק" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "PrintScreen" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "ימינה" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "הלחצן הימני" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "מקש Control הימני" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "תפריט ימני" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "מקש Shift הימני" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "מקש Windows הימני" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Select" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "שינה" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "צילום רגעי" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "רווח" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "למעלה" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X כפתור 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X כפתור 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "זום" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "מפה קטנה מוסתרת" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "מפה קטנה במצב מכ״ם, יחס תצוגה x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "מפה קטנה במצב שטח, זום x %d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "מפה קטנה במצב טקסטורה" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "הורדת $1 נכשלה" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "להמשיך" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "\"מיוחד\" = טפס למטה" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "קדימה אוטומטי" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "קפיצה אוטומטית" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "אחורה" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "שנה מצלמה" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "צ'אט" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "פקודה" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "קונסולה" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "הקטן טווח" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "הנמך ווליום" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "לחיצה כפולה על \"קפיצה\" כדי לכבות או להדליק את מצב התעופה" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "הפל" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "קדימה" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "הגדל טווח" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "הגבר ווליום" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "תיק חפצים" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "קפיצה" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "מקש כבר בשימוש" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "פקודה מקומית" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "השתק" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "הפריט הבא" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "הפריט הקודם" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "בחר טווח" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "צילום מסך" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "התכופף" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "מתג מידע על מסך" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "מתג צא'ט לוג" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "מתג מצב מהיר" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "מתג תעופה" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "מתג ערפל" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "מתג מפה קטנה" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "מתג מעבר דרך קירות" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "מתג תנועה לכיוון מבט" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "לחץ מקש" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "שנה" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "סיסמה חדשה" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "סיסמה ישנה" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "סיסמאות לא תואמות!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "יציאה" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "מושתק" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "עוצמת שמע: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "he" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "נא לבחור שם!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) מתקן את המיקום של הג'ויסטיק הווירטואלי.\n" +"אם מושבת, הג'ויסטיק הווירטואלי יעמוד במיקום המגע הראשון." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) השתמש בג'ויסטיק וירטואלי כדי להפעיל את כפתור \"aux\".\n" +"אם הוא מופעל, הג'ויסטיק הווירטואלי ילחץ גם על כפתור \"aux\" כשהוא מחוץ למעגל " +"הראשי." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X, Y, Z) היסט של פרקטל ממרכז עולמי ביחידות 'סקאלה'.\n" +"ניתן להשתמש בה כדי להעביר נקודה רצויה ל (0, 0) כדי ליצור\n" +"נקודת הופעה מתאימה, או כדי לאפשר 'התקרבות' לנקודה רצויה\n" +"על ידי הגדלת 'סקאלה'.\n" +"ברירת המחדל מכוונת לנקודת הופעה מתאימה למנדלברוט\n" +"קבוצות עם פרמטרי ברירת מחדל, יתכן שיהיה צורך לשנות זאת\n" +"מצבים.\n" +"טווח בערך -2 עד 2. הכפל באמצעות 'קנה מידה' עבור קיזוז בצמתים." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X, Y, Z) סקאלה של פרקטל בצמתים.\n" +"גודל הפרקטל בפועל יהיה גדול פי 2 עד 3.\n" +"ניתן להפוך את המספרים הללו לגדולים מאוד, כך הפרקטל\n" +"לא צריך להשתלב בעולם.\n" +"הגדל את אלה ל\"התקרב \"לפרטי הפרקטל.\n" +"ברירת המחדל היא לצורה מעוכה אנכית המתאימה ל\n" +"אי, קבע את כל 3 המספרים שווים לצורה הגולמית." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "רעש דו-ממדי השולט על צורתם / גודל ההרים המחורצים." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "רעש דו-ממדי השולט על צורתם / גודל הגבעות המתונות." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "רעש דו-ממדי השולט על צורתם / גודל ההרים הנישאים." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "רעש דו-ממדי השולט על תדירות/ גודל רכסי ההרים." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "רעש דו-ממדי השולט על תדירות/גודל הגבעות המתונות." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "רעש דו-ממדי השולט על תדירות/גודל רכסי ההרים." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "רעש דו-ממדי שמאתר את עמקי הנהרות ותעלותיהם." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "עננים תלת מימדיים" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "מצב תלת־ממד" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "חוזק פרלקסה במצב תלת ממדי" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "רעשי תלת מימד המגדירים מערות ענק." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"רעש תלת ממדי המגדיר את מבנה ההרים וגובהם.\n" +"מגדיר גם מבנה שטח הרים צפים." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"רעש תלת ממדי מגדיר מבנה של שטחי צף.\n" +"אם משתנה מברירת המחדל, ייתכן ש\"סקאלת\" הרעש (0.7 כברירת מחדל) זקוקה\n" +"להיות מותאמת, מכיוון שההתפשטות של שטחי צף מתפקדת בצורה הטובה ביותר כאשר יש " +"לרעש זה\n" +"טווח ערכים של כ -2.0 עד 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "מבנה מגדיר רעש תלת ממדי של קירות קניון הנהר." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "רעש תלת ממדי המגדיר שטח." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "רעש תלת ממדי להרים תלויים, צוקים וכו'בדרך כלל וריאציות קטנות." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "רעש תלת ממדי הקובע את מספר הצינוקים בנתח מפה." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"תמיכה בתלת מימד.\n" +"נתמך כרגע:\n" +"- ללא: אין פלט תלת-ממדי.\n" +"- אנאגליף: צבע ציאן / מגנטה 3d.\n" +"- interlaced: תמיכה במסך קיטוב מבוסס מוזר / שווה\n" +"- topbottom: מסך מפוצל למעלה / למטה.\n" +"- צדדי: פיצול מסך זה לצד זה.\n" +"- תצוגת רוחב: 3D עם עיניים צולבות\n" +"- pageflip: quadbuffer מבוסס 3d.\n" +"שים לב שמצב interlaced מחייב הפעלת shaders." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"זרע מפה שנבחר עבור מפה חדשה, השאר ריק לאקראי.\n" +"יבוטל בעת יצירת עולם חדש בתפריט הראשי." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "הודעה שתוצג בפני כל הלקוחות כאשר השרת קורס." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "הודעה שתוצג בפני כל הלקוחות כאשר השרת יכבה." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "אינטרוול ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "הקצאת זמן ABM" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "מגבלה מוחלטת של בלוקים בתור שיופיעו" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "תאוצה באויר" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "האצת כוח הכבידה, בקוביות לשנייה בריבוע." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "משניי בלוק פעיל" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "אינטרוול ניהול בלוק פעיל" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "טווח בלוק פעיל" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "טווח שליחת אובייקט פעיל" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"כתובת להתחברות אליה.\n" +"השאר את זה ריק כדי להפעיל שרת מקומי.\n" +"שים לב ששדה הכתובת בתפריט הראשי עוקף הגדרה זו." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "הוסף חלקיקים כשחופרים בקוביה." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "התאם את תצורת dpi למסך שלך (לא X11 / Android בלבד) למשל. למסכי 4k." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"מכוון את הצפיפות של שכבת אדמות צותף.\n" +"הגדל את הערך כדי להגדיל את הצפיפות. יכול להיות חיובי או שלילי.\n" +"ערך = 0.0: 50% מהנפח הוא שטח צף.\n" +"ערך = 2.0 (יכול להיות גבוה יותר בהתאם ל- 'mgv7_np_floatland', בדוק תמיד\n" +"כדי להיות בטוח) יוצר שכבת צף מוצקה." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "הוסף שם פריט" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "מתקדם" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"משנה את עקומת האור על ידי החלת 'תיקון גמא' עליה.\n" +"ערכים גבוהים הופכים את רמות האור האמצעיות והתחתונות לבהירות יותר.\n" +"הערך '1.0' משאיר את עקומת האור ללא שינוי.\n" +"יש לכך השפעה משמעותית רק על אור יום ומלאכותי\n" +"זה משפיע מעט מאוד על אור הלילה הטבעי." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "תמיד לעוף ומהר" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "גמא חסימה סביבתית" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "כמות ההודעות ששחקן עשוי לשלוח לכל 10 שניות." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "מגביר את העמקים." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "פילטר אנטיסטרופי" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "הכרזת שרת" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "הכרז לרשימת השרתים." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "הוסף שם פריט" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "הוסף את שם הפריט לטיפ הכלים." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "רעש עצי תפוחים" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "אינרציה בזרוע" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"אינרציה בזרוע, נותנת תנועה מציאותית יותר של\n" +"הזרוע כשהמצלמה נעה." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "שאל האם להתחבר מחדש לאחר קריסה" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"במרחק זה השרת יעשה אופטימיזציה לאילו בלוקים נשלחים\n" +"ללקוחות.\n" +"ערכים קטנים עשויים לשפר ביצועים רבות, על חשבון גלוי\n" +"עיבוד תקלות (חלק מהבלוקים לא יועברו מתחת למים ובמערות,\n" +"כמו גם לפעמים ביבשה).\n" +"הגדרת ערך זה יותר מ- max_block_send_distance מבטלת זאת\n" +"אופטימיזציה.\n" +"מצוין במפה (16 קוביות)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "מקש התקדמות אוטומטית" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "קפיצה אוטומטית של מכשולים בקוביה יחידה." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "דווח אוטומטית לרשימת השרתים." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "שמור אוטומטית גודל מסך" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "מצב סקאלה אוטומטית (Autoscale)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "מקש הקפיצה" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "מקש התזוזה אחורה" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "מפלס בסיס האדמה" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "גובה השטח." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "הרשאות בסיסיות" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "רעש חופים" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "סף רעש חופים" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "סינון בילינארי" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "הצמד כתובת" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "פרמטרי רעש טמפרטורה ולחות של Biome API" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "רעש Biome" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "אופטימיזצית שליחת בלוק" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "נתיב גופן עבה/מוטה" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "נתיב גופן עם מרווח אחיד עבה/מוטה" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "נתיב גופן עבה" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "נתיב גופן מרווח אחיד" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "בנה בתוך שחקן" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "בילדאין" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "שנה מצלמה" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"מרחק מצלמה 'קרוב לקיר' בקוביות, בין 0 ל -0.25\n" +"עובד רק בפלטפורמות GLES. רוב המשתמשים לא יצטרכו לשנות זאת.\n" +"הגדלה יכולה להפחית חפצים על גרפי GPU חלשים יותר.\n" +"0.1 = ברירת מחדל, 0.25 = ערך טוב לטאבלטים חלשים יותר." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "החלקת מצלמה" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "החלקת מצלמה ומצב קולנועי" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "מקש החלפת עדכון המצלמה" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "רעש מערות" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "רעש מערות #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "רעש מערות #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "רוחב מערות" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "רעש מערה1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "רעש מערה2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "גבול מנהרות" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "רעש מנהרות" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "מחדד מערות" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "סף מערות" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "גבול עליון מערות" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"טווח דחיפה של מרכז עקומת אור.\n" +"כאשר 0.0 הוא רמת אור מינימלית, 1.0 הוא רמת אור מקסימלית." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "סף בעיטה להודעות צ'אט" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "פקודות צ'אט" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "גודל גופן צ'אט" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "מקש צ'אט" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "רמת לוג צ'אט" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "הגבלת מספר הודעות צ'אט" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "פורמט הודעות צ'אט" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "סף בעיטה להודעות צ'אט" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "אורך הודעת צ'אט מקסימלי" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "מתג הפעלת צ'אט" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "צ'אט מוצג" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "גודל חתיכה" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "מצב קולנועי" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "מקש מצב קולנועי" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "טקסטורות נקיות ושקופות" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "לקוח" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "שרת ולקוח" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client modding" +msgstr "קלינט" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client side modding restrictions" +msgstr "קלינט" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "קלינט" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "יצירתי" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "חבלה" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "קישוטים" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "מקש התזוזה ימינה" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Digging particles" +msgstr "חלקיקים" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "הקשה כפולה על \"קפיצה\" לתעופה" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "הפעלת המצב היצירתי עבור כל השחקנים" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "לאפשר חבלה ומוות של השחקנים." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "החלקת קצוות (AA):" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "מקש התזוזה קדימה" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "מצב מסך מלא." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "משחקים" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HTTP mods" +msgstr "מודים" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "מידע-על-מסך מוצג" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "רכיב רוחב של גודל החלון הראשוני." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "מקש הקפיצה" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "מהירות הקפיצה" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "מקש התזוזה שמאלה" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "החלקת תאורה" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat" +msgstr "מנוע מפות" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal" +msgstr "מנוע מפות" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "מנוע מפות" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5" +msgstr "מנוע מפות" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6" +msgstr "מנוע מפות" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7" +msgstr "מנוע מפות" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "מיפמאפינג" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "הבלטת קוביות" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "סינון בילינארי" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "מקש התזוזה ימינה" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "מסך:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "צילום מסך" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "אכסון שרת" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "שרת / שחקן יחיד" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "פורט לשרת" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "פורט לשרת" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"עוצמת הקול של כל הצלילים.\n" +"דורש הפעלת מערכת הקול." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "הגדרות" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "טווח ראיה בקוביות." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "מקש הקטנת טווח ראיה" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "מקש הגדלת טוחח ראיה" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "מקש זום (משקפת)" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "טווח ראיה" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Virtual joystick triggers Aux1 button" +msgstr "מקש הפעלת ג'ויסטיק וירטואלי" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "ווליום" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"עוצמת הקול של כל הצלילים.\n" +"דורש הפעלת מערכת הקול." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "מהירות הליכה" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "מהירות הליכה, טיסה וטיפוס במצב מהיר, בקוביות לשנייה." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "מפלס המים" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "מפלס פני המים בעולם." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "מהירות גל של נוזלים עם גלים" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "אורך גל של נוזלים עם גלים" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "צמחים מתנופפים" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "האם לאפשר לשחקנים להרוג אחד־את־השני." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "רכיב רוחב של גודל החלון הראשוני." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "World start time" +msgstr "שם העולם" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "מצב טקסטורות מיושרות לעולם" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y לקרקע שטוחה." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "Y של צפיפות הרים שיפוע רמת אפס. משמש להעברת הרים אנכית." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Y של הגבול העליון של מערות גדולות." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "מרחק Y שעליו מתרחבות מערות לגודל מלא." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "(cURL) זמן להורדה נגמר" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "(cURL) מגבלת זמן" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "(cURL) מגבלה לפעולות במקביל" + +#~ msgid "- Creative Mode: " +#~ msgstr "- מצב יצירתי: " + +#~ msgid "- Damage: " +#~ msgstr "- חבלה: " + +#~ msgid "Address / Port" +#~ msgstr "כתובת / פורט" + +#~ msgid "Basic" +#~ msgstr "בסיסי" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "ביטים לפיקסל (עומק צבע) במצב מסך מלא." + +#~ msgid "Configure" +#~ msgstr "קביעת תצורה" + +#~ msgid "Connect" +#~ msgstr "התחברות" + +#~ msgid "Credits" +#~ msgstr "תודות" + +#~ msgid "Damage enabled" +#~ msgstr "נזק מופעל" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "הורדת משחק, כמו משחק Minetest, מאתר minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "הורד אחד מאתר minetest.net" + +#, fuzzy +#~ msgid "Enable VBO" +#~ msgstr "אפשר בכל" + +#~ msgid "Enter " +#~ msgstr "הכנס " + +#~ msgid "Game" +#~ msgstr "משחק" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "התקנה: מקובץ: \"$1\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "קישור מקשים (אם התפריט מתקלקל, הסר דברים מminetest.conf)" + +#~ msgid "Main menu style" +#~ msgstr "סגנון התפריט הראשי" + +#~ msgid "Name / Password" +#~ msgstr "שם/סיסמה" + +#~ msgid "No" +#~ msgstr "לא" + +#~ msgid "Ok" +#~ msgstr "אישור" + +#~ msgid "PvP enabled" +#~ msgstr "לאפשר קרבות" + +#, fuzzy +#~ msgid "Reset singleplayer world" +#~ msgstr "שרת" + +#~ msgid "Special" +#~ msgstr "מיוחד" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "כדי לאפשר שיידרים יש להשתמש בדרייבר של OpenGL." + +#~ msgid "View" +#~ msgstr "תצוגה" + +#~ msgid "Yes" +#~ msgstr "כן" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "אתה עומד להצטרף לשרת זה עם השם \"%s\" בפעם הראשונה.\n" +#~ "אם תמשיך, ייווצר חשבון חדש באמצעות אישוריך בשרת זה.\n" +#~ "אנא הקלד מחדש את הסיסמה שלך ולחץ על 'הירשם והצטרף' כדי לאשר את יצירת " +#~ "החשבון, או לחץ על 'ביטול' כדי לבטל." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "מתת" + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/hi/minetest.po b/po/hi/minetest.po new file mode 100644 index 0000000..dc79d1c --- /dev/null +++ b/po/hi/minetest.po @@ -0,0 +1,7083 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2020-10-06 14:26+0000\n" +"Last-Translator: Eyekay49 <satvikpatwardhan@gmail.com>\n" +"Language-Team: Hindi <https://hosted.weblate.org/projects/minetest/minetest/" +"hi/>\n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.3-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "बंद करके मेनू पर जाएं" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Invalid command: " +msgstr "लोकल कमांड" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "एक-खिलाडी" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "एक-खिलाडी" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "वापस ज़िंदा होएं" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "आपकी मौत हो गयी" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "लोकल कमांड" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "लोकल कमांड" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "ठीक है" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Lua कोड में यह परेशानी हुई :" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "एक खराबी हो गयी :" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "मुख्य पृष्ठ" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "वापस कनेक्ट करें" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "सर्वर वापस कनेक्ट करना चाहता है :" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "दुनिया चुन्हें :" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "प्रोटोकॉल संख्या एक नहीं है। " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "सर्वर केवल प्रोटोकॉल $1 लेता है। " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "सर्वर केवल प्रोटोकॉल $1 से $2 ही लेता है। " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "हम केवल प्रोटोकॉल $1 ही लेते हैं।" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "हम प्रोटोकॉल $1 से $2 ही लेते हैं।" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "रोकें" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "निर्भरताएं :" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "प्रत्येक रोकें" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "माॅडपैक रोकें" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "प्रत्येक चालू करें" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "माॅडपैक चालू करें" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"मना किए गए वर्णों के कारण माॅड \"$1\" चालू नहीं हो सका। कृपया [a-z0-9] अंग्रेजी वर्ण का " +"ही प्रयोग करें।" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "और मोड खोजें" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "माॅड :" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "कोई (अनावश्यक) निर्भरताएं नहीं हैं" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "खेल ने अपने बारे में कुछ नहीं बताया।" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "कोई आवश्यक निर्भरताएं नहीं" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "माॅडपैक ने अपने बारे में कुछ नहीं बताया।" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "कोई अनावश्यक निर्भरताएं नहीं" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "अनावश्यक निर्भरताएं :" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "सेव करें" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "दुनिया :" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "चालू" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "लोड हो रहा है ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "सभी पैकेज" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Already installed" +msgstr "की पहले से इस्तेमाल में है" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "वापस मुख्य पृष्ठ पर जाएं" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "खेल चलाएं" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "cURL के बगैर कंपाइल होने के कारण Content DB उपलब्ध नहीं है" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "लोड हो रहा है ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "$1 का डाऊनलोड असफल हुआ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "अनेक खेल" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "इन्स्टाल करें" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "इन्स्टाल करें" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "अनावश्यक निर्भरताएं :" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "इन्स्टाल : \"$1\" का फाईल टाईप अंजान है याफिर आरकाइव खराब है" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "माॅड" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "कोई पैकेज नहीं ला पाया गया" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "कुछ नहीं मिला" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "No updates" +msgstr "नया संस्करण इन्स्टाल करें" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "कला संकुल" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "हटाऐं" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "नया संस्करण इन्स्टाल करें" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "\"$1\" नामक दुनिया पहले से ही है" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "अतिरिक्त भूमि" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "ऊंचाई की ठंडक" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "ऊंचाई का सूखापन" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "बायोम परिवर्तन नज़र न आना (Biome Blending)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "बायोम" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "गुफाएं" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "गुफाएं" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "बनाइए" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "सजावट" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "" +"चेतावनी : न्यूनतम विकास खेल (Minimal development test) खेल बनाने वालों के लिए है।" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "कालकोठरियां" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "समतल भूमि" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "आसमान में तैरते हुए भूमि-खंड" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "फ्लोटलैंड्स (आसमान में तैरते हुए भूमि-खंड) (प्रायोगिक)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Non-fractal भूमि तैयार हो : समुद्र व भूमि के नीचे" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "छोटे पहाड़" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "नम नदियाँ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "नदियों के आसपास नमी बढ़ाता है" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "इन्स्टाल करें" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "झीलें" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "कम आर्द्रता और उच्च गर्मी की वजह से नदियाँ उथली या सूखी हो जाती है" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "नक्शा स्रोत" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "पहाड़ों" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "कीचड़ का बहाव" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "सुरंगों और गुफाओं का नेटवर्क" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "कोई खेल चूना नहीं गया है" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "ऊंचाई के साथ गर्मी कम करता है" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "ऊंचाई के साथ नमी कम करता है" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "नदियाँ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "समुद्र तल की नदियाँ" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "बीज" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "बायोम के बीच में धीरे-धीरे परिवर्तन" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "भूमि पर बनावटें (v6 के पेड़ व जंगली घास पर कोई असर नहीं)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "इलाके में दिखने वाली संरचनाएं, आमतौर पर पेड़-पौधे" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "शीतोष्ण, रेगिस्तान" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "शीतोष्ण, रेगिस्तान, जंगल" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "शीतोष्ण, रेगिस्तान, जंगल, टुंड्रा, तायगा" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "इलाके की सतह का कटाव" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "पेड़ और जंगल की घास" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "नदी की गहराईयों में अंतर" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "दुनिया का नाम" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "आपने कोई खेल इन्स्टाल नहीं किया है।" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "क्या आप सचमुच \"$1\" को रद्द करना चाहते हैं?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "रद्द करें" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: \"$1\" रद्द नहीं किया जा सका" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: \"$1\" फाईल पार गलत है" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "दुनिया रद्द करें?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "पासवर्ड दोबारा लिखें" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "नया पासवर्ड" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "पासवर्ड अलग-अलग हैं!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "पंजीकरण व खेलें" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "हां" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "माॅडपैक का नाम बदलें :" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "modpack.conf फाईल में इस माॅडपैक को जो नाम दिया गया है वही माना जाएगा।" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(सेटिंग के बारे में कुछ नहीं बताया गया है)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "द्वि आयामी नॉइस" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "वापस सेटिंग पृष्ठ पर जाएं" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "ढूंढें" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "वस्तुएं" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "वस्तुएं" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "रुका हुआ" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "बदलें" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "चालू" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "लैकुनारिटी" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "सप्टक (आक्टेव)" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "आफसेट" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "हठ (पर्सिस्टेन्स)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "कृपया एक पूर्णांक (integer) भरें।" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "कृपया एक अंक भरें।" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "मूल चुनें" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "स्केल" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "ढूंढें" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "फाईल पाथ चुनें" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "फाईल चुनें" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "तकनीकी नाम देखें" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "इसका मूल्य कम-से-कम $1 होना चाहिए।" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "इसका मूल्य $1 से अधिक नहीं होना चाहिए।" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "एक्स" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X स्प्रेड" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "वाई" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y स्प्रेड" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "जेड" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z स्प्रेड" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "एब्सोल्यूट वैल्यू" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "डीफाल्ट" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "आरामदायक (ईज़्ड)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "($1) चालू" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 यह सब मॉड" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "$2 में $1 को इन्स्टाल नहीं किया जा सका" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "इन्स्टाल मॉड: $1 का असल नाम नहीं जान पाया गया" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "माॅड इन्स्टाल: माॅडपैक $1 के लिए सही फोल्डर नहीं ढूंढा जा सका" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "सही माॅड या माॅडपैक नहीं ढूंढ पाया गया" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "$1 कला संकुल के रूप में इन्स्टाल नहीं किया जा सका" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "खेल को $1 के रूप में इन्स्टाल नहीं किया जा सका" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "मॉड को $1 के रूप में इन्स्टाल नहीं किया जा सका" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "माॅडपैक को $1 के रूप में इन्स्टाल नहीं किया जा सका" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "लोड हो रहा है ..." + +#: builtin/mainmenu/serverlistmgr.lua +#, fuzzy +msgid "Public server list is disabled" +msgstr "क्लाइंट की तरफ से स्क्रिप्ट लगाना मना है" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "सार्वजनिक सर्वर शृंखला (सर्वर लिस्ट) को 'हां' करें और इंटरनेट कनेक्शन जांचें।" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "सक्रिय सहायक" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "मुख्य डेवेलपर" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "फाईल पाथ चुनें" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "पूर्व सहायक" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "पूर्व मुख्य डेवेलपर" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "नेट पर वस्तुएं ढूंढें" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "वस्तुएं" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "कला संकुल रोकें" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "जानकारी :" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "इन्स्टाल किये गये पैकेज :" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "कोई निर्भर्ताएं नहीं हैं|" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "पैकेज के बारे में कुछ नहीं बताया गया है" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "नाम बदलें" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "पैकेज हटाएं" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "कला संकुल चालू करें" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "सर्वर सार्वजनिक सर्वर सूची (server list) में दिखे" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "बाईंड एड्रेस" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "असीमित संसाधन" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "हानि व मृत्यु हो सकती है" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "खेल चलाएं" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "सर्वर चलाएं" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "नया" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "कोई दुनिया उपस्थित या चुनी गयी नहीं है !" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "खेल खेलें" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "पोर्ट" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "दुनिया चुन्हें :" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "दुनिया चुन्हें :" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "सर्वर पोर्ट" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "खेल शुरू करें" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "- एड्रेस : " + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "खाली करें" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "असीमित संसाधन" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "- हानि : " + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "पसंद" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "खेल में शामिल होएं" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "पिंग" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "सर्वर सार्वजनिक सर्वर सूची (server list) में दिखे" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "पसंद हटाएं" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "सर्वर पोर्ट" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "दुग्ना" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "त्रिविम दृश्यन बादल" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "चार गुना" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "आठ गुना" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "सभी सेटिंग देखें" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "ऐन्टी एलियासिंग :" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "स्क्रीन परिमाण स्वयं सेव हो" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "द्विरेखिय फिल्टर" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "की बदलें" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "जुडे शिशे" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "रोचक पत्ते" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "मिपमैप" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "मिपमैप व अनीसो. फिल्टर" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "कोई फिल्टर नहीं" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "मिपमैप नहीं हो" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "डिब्बें उजाले हों" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "डिब्बों की रूपरेखा" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "कुछ नहीं" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "अपारदर्शी पत्ते" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "अपारदर्शी पानी" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "कण" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "स्क्रीन :" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "सेटिंग" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "छाया बनावट" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "फ्लोटलैंड्स (आसमान में तैरते हुए भूमि-खंड) (प्रायोगिक)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "छाया बनावट (अनुपलब्ध)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "मामूली पत्ते" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "चिकना उजाला" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "कला बनावट :" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "टोन मैपिंग" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "छूने की त्रिज्या : (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "त्रिरेखीय फिल्टर" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "पत्ते लहराएं" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "पानी में लहरें बनें" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "पाैधे लहराएं" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "कनेक्शन खराबी (समय अंत?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "कनेक्शन समय अंत|" + +#: src/client/client.cpp +msgid "Done!" +msgstr "हो गया !" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "डीब्बे बन रहे हें" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "डिब्बे बन रहें हैं ..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "कला लोड हो रही है ..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "छायाएं वापस बन रहीं हैं ..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "कनेक्शन खराबी (समय अंत?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "खेल ढूंढा ना जा सका या लोड नहीं किया जा सका \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "गलत गेमस्पेक कोड।" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "मुख्य पृ़ष्ठ" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "कोई दुनिया नहीं चुनी गयी है, ना ही पता दिया गया है। कुछ नहीं करना।" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "खिलाडी का नाम अधिक लंबा है|" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "कृपया एक नाम चुनें!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "पासवर्ड फाईल नहीं खुला :- " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "दुनिया का फाईल पाथ नहीं है : " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"अधिक जानकारी के लिए debug.txt देखें।" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- एड्रेस : " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- तकनीक : " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- पोर्ट : " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- सार्वजनिक : " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- खिलाड़ियों में मारा-पीटी : " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- सर्वर का नाम : " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "एक खराबी हो गयी :" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "स्वचाल रुका हुआ" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "स्वचाल चालू" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "कैमरा रुका हुआ" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "कैमरा चालू" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "पासवर्ड बदलें" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "सिनेमा चाल रुका हुआ" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "सिनेमा चाल चालू" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "क्लाइंट की तरफ से स्क्रिप्ट लगाना मना है" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "सर्वर से कनेक्ट हुआ जा रहा है ..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "आगे बढ़ें" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"कंट्रोल्स:\n" +"- %s : आगे बढ़ने के लिए\n" +"- %s : पीछे जाने के लिए\n" +"- %s : बाय की ओर चलें\n" +"- %s : दाएं की ओर चलें\n" +"- %s : कूदे या चढ़े\n" +"- %s : उतरे / संभल के चलें\n" +"- %s : वस्तु गिराएं\n" +"- %s : वस्तु सूची खोलें\n" +"- : माउस मुड़े देखें\n" +"- : माउस बाय : खोदें / मुक्का मारें\n" +"- : माउस दाहिने : डाले / इस्तेमाल करें\n" +"- : माउस पहिया : वस्तु चुनें\n" +"- %s : बात करने के लिए\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "क्लाइंट बनाया जा रहा है ..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "सर्वर बनाया जा रहा है ..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "डीबग जानकारी व प्रोफाइल गायब" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "डीबग जानकारी दिखाई दे रही है" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "डीबग जानकारी, प्रोफाइलर व रूपरेखा गायब" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"आम कंट्रोल्स :\n" +"कोई मेनू खुला नहीं है :\n" +"-एक बार टैप : बटन दबेगा\n" +"-दो टॉप: डालना/ इस्तेमाल करना\n" +"-उंगली फिसलाना : मुड़ना\n" +"कोई मेनू या वस्तु सूची खुली है :\n" +"-बाहर दो बार टैप :\n" +"--> बंद\n" +"- ढेर छूएं, स्थान छूएं\n" +"--> ढेर का स्थान बदलने के लिए\n" +"- छुए व खींचे, दूसरी उंगली से टैप करें\n" +"--> एक वस्तु स्थान में डालें\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "दृष्टि सीमित" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "दृष्टि असीमित" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "क्लाइंट बनाया जा रहा है ..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "बंद करके मेनू पर जाएं" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "बंद करके ओ॰ एस॰ में जाएं" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "तेज चलन रुका हुआ" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "तेज जलन चालू" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "तेज चैनल चालू (सूचना: आपके पास 'तेज' विशेषाधिकार नहीं है)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "उड़ान अनुपलब्ध है" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "उड़ान उपलब्ध है" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "उड़ान उपलब्ध है (सूचना: आपके पास 'उड़ान' विशेषाधिकार नहीं है)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "कोहरा रुका हुआ" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "कोहरा चालू" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "खेल की जानकारी :" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "खेल रुका हुआ है" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "सर्वर चलन" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "वस्तुओं के अर्थ ..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "कि॰बी॰/एस॰" + +#: src/client/game.cpp +msgid "Media..." +msgstr "कला एवं आवाज़ें ..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "एम॰ आई॰ बी॰/ एस॰" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "खेल या मॉड़ के वजह से छोटा नक्शा मना है" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "एक-खिलाडी" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "तरल चाल रुका हुआ" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "तरल चाल चालू" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "तरल चाल चालू (सूचना: आपके पास तरल विशेषाधिकार नहीं है)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "डिब्बों का अर्थ ..." + +#: src/client/game.cpp +msgid "Off" +msgstr "ऑफ" + +#: src/client/game.cpp +msgid "On" +msgstr "ऑन" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "पिच चलन रुका हुआ" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "पिच चलन चालू" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "प्रोफाईलर दिखाई दे रहा है" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "बाहर का सर्वर" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "एड्रेस समझा जा रहा है ..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "शट डाउन हो रहा है ..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "एक-खिलाडी" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "आवाज़ वॉल्यूम" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "आवाज़ बंद" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "आवाज चालू" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "दृष्टि सीमा बदलकर %d है" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "दृष्टि सीमा अधिकतम : %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "दृष्टि सीमा न्यूनतम : %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "वॉल्यूम को बदलकर %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "डिब्बे रेखांकित" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "खेल या मॉड़ के वजह से इस समय ज़ूम मना है" + +#: src/client/game.cpp +msgid "ok" +msgstr "ठीक है" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "बातें दिखाई नहीं देंगी" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "बातें दिखाई देंगी" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "हे॰अ॰डि॰ दिखाई नहीं देंगी" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "हे॰अ॰डि॰ दिखाई देंगी" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "प्रोफाइलर नहीं दिखाई देगा" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "प्रोफाईलर दिखाई दे रही है (पृष्ठ %d %d पृष्ठों में से)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "एप्स" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "बैकस्पेस" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "कैप्स लाक" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "कंट्रोल" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "नीचे" + +#: src/client/keycode.cpp +msgid "End" +msgstr "एंड" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "ई.ओ.एफ खाली करें" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "एग्सीक्यूट" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "हेल्प" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "होम" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "आई एम ई एक्सेप्ट" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "आई एम ई कन्वर्ट" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "आई एम ई एस्केप" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "आई एम ई मोड चेंज" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "आई एम ई नानकन्वर्ट" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "इन्सर्ट" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "बायां" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "बायां बटन" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "बायां कंट्रोल" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "बायां मेनू" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "लेफ्ट शिफ्ट" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "लेफ्ट विंडोज" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "मेनू (कीबोर्ड)" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "बीच का बटन" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "नम लाक" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "नम्पैड *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "नम्पैड +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "नम्पैड -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "नम्पैड ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "नम्पैड /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "नम्पैड ०" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "नम्पैड १" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "नम्पैड २" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "नम्पैड ३" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "नम्पैड ४" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "नम्पैड ५" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "नम्पैड ६" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "नम्पैड ७" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "नम्पैड ८" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "नम्पैड ९" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "ओ ई एम क्लीयर" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "पेज डाऊन" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "पेज अप" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "पॉज़" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "खेलें" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "प्रिन्ट बटन" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "रिटर्न बटन" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "दाहिना" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "दाहिना बटन" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "दाहिना" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "दाहिना मेनू" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "राईट शिफ्ट" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "राईट विंडोज" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "स्क्रोल लाक" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "सिलेक्ट" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "शिफ्ट" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "स्लीप" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "स्नैपशॉट" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "स्पेसबार" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "टैब बटन" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "ऊपर" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X बटन १" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X बटन २" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "ज़ूम" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "छोटा नक्शा गायब" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "छोटा नक्शा रेडार मोड, 1 गुना ज़ूम" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "छोटा नक्शा जमीन मोड, 1 गुना ज़ूम" + +#: src/client/minimap.cpp +#, fuzzy +msgid "Minimap in texture mode" +msgstr "छोटा नक्शा जमीन मोड, 1 गुना ज़ूम" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "$1 का डाऊनलोड असफल हुआ" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "आगे बढ़े" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "\"स्पेशल\" = नीचे उतरना" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "स्वचालन" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "कूदने के लिए बटन दबाना अनावश्यक" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "पीछे जाएं" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "कैमरा बदलना" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "बातें" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "आज्ञा" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "कन्सोल" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "दृष्टि सीमा कम" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "आवाज़ कम" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "उड़ने के लिए दो बार कूदें" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "वस्तु गिराना" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "आगे जाएं" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "दृष्टि सीमा अधिक" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "आवाज अधिक" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "वस्तु सूची" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "कूदना" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "की पहले से इस्तेमाल में है" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "लोकल कमांड" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "आवाज बंद" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "अगला वस्तु" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "पिछली वस्तु" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "दृष्टि सीमा चुनना" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "स्क्रीनशॉट" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "संभल के चलना" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "हे. अ. डि" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "बातें दिखना" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "तेज चलन" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "उड़ना" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "कोहरा" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "छोटा नक्शा" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "तरल चाल" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "पिच चलन" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "की दबाएं" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "बदलें" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "नया पासवर्ड" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "पुराना पासवर्ड" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "पासवर्ड अलग-अलग हैं!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "निकास" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "चुप" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "आवाज " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "hi" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "कृपया एक नाम चुनें!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "दुनिया का नाम" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "हमेशा उड़ान और तेज" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key for climbing/descending" +msgstr "चलने उतरने के लिए स्पेशल की" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "खिलाडी पर डिब्बे डालना" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "कैमरा बदलना" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "केमरा चिकनाई" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "सिनेमा मोड में केमरा चिकनाई" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "आज्ञा" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "बातें दिखाई देंगी" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "सिनेमा मोड" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "कंट्रोल्स" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "सजावट" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "उड़ने के लिए दो बार कूदें" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "दो बार कूदने से उड़ान चलन चालू हो जाता है।" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "तेज चलन" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"स्पेशल की दबाने पर आप बहुत तॆज चलने लगेंगे |\n" +"इसके लिये \"तेज\" विषेशाधिकार आवश्यक है |" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "ऐन्टी एलियासिंग :" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "उडना" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "अनेक खेल" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "हे॰अ॰डि॰ दिखाई देंगी" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"अगर यह रुका हुआ हुआ तो तेज उड़ने के लिए\n" +"स्पेशल की दबानी पड़ेगी |" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"अगर यह उडान के साथ चालू होगा तो आप हर चीज़ के आर-पार उड पाएंगे |\n" +"इसके लिये \"तरल चाल\" विषेशाधिकार आवश्यक है |" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"अगर यहां चालू हुआ तो नीचे उतरने के लिए स्पेशल\n" +"की का इस्तेमाल होगा।" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "चालू होने पर आप जहां देखेंगे उस दिशा को सामने माना जाएगा (पिच चलन)|" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"अगर यह चालू होगा तो आप जिस स्थान मैं खडें हैं वही पर डिब्बे डाल सकेंगे |\n" +"यह छोटी जगहों में काम करते वख़्त काम आ सकता है |" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "माउस उल्टा" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "माउस ऊपर करने पर केमरा नीचे जाएगा, और नीचे करने पर ऊपर |" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "चिकना उजाला" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "माउस संवेदनशीलता" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "माउस संवेदनशीलता गुणक।" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "तरल चाल" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "डिब्बें उजाले हों" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "पिच चलन" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place repetition interval" +msgstr "राइट क्लिक के दोहराने का समय" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"खिलाडी के असर से मुक्त उड सकेगा |\n" +"इसके लिये \"उडान\" विषेशाधिकार आवश्यक है |" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "स्क्रीन :" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "स्क्रीनशॉट" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "सर्वर चलाएं" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "- सर्वर का नाम : " + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "सर्वर पोर्ट" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "सर्वर पोर्ट" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"आपका माउस चिकने तरीके से हिलेगा | इसे माउस या दृष्टि चिकनाई भी कहा जाता है |\n" +"विडियो बनाते वख़्त काम आ सकता है |" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "सिनेमा मोड में केमरा चिकने तरीके से मुडेगा | मना करने के लिये 0." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "केमरा के मुडने की चिकनाई. मना करने के लिये 0." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "सेटिंग" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- असीमित साधन " + +#~ msgid "- Damage: " +#~ msgstr "- हानि : " + +#~ msgid "Address / Port" +#~ msgstr "ऐडरेस / पोर्ट" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "क्या आप सचमुच अपने एक-खिलाडी दुनिया रद्द करना चाहते हैं?" + +#~ msgid "Back" +#~ msgstr "पीछे" + +#~ msgid "Bump Mapping" +#~ msgstr "टकराव मैपिंग" + +#~ msgid "Config mods" +#~ msgstr "मॉड कॆ सेटिंग बदलें" + +#~ msgid "Configure" +#~ msgstr "सेटिंग बदलें" + +#~ msgid "Connect" +#~ msgstr "कनेक्ट करें" + +#~ msgid "Credits" +#~ msgstr "आभार सूची" + +#~ msgid "Damage enabled" +#~ msgstr "हानि व मृत्यु हो सकती है" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "मैनटेस्ट खेल जैसे अन्य खेल minetest.net से डाऊनलोड किए जा सकते हैं" + +#~ msgid "Download one from minetest.net" +#~ msgstr "आप किसी भी खेल को minetest.net से डाऊनलोड कर सकते हैं" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "$1 का डाऊनलोड व इन्स्टाल चल रहा है, कृपया ठहरें ..." + +#~ msgid "Enter " +#~ msgstr "डालें " + +#~ msgid "Game" +#~ msgstr "खेल" + +#~ msgid "Generate Normal Maps" +#~ msgstr "मामूली नक्शे बनाएं" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "इन्स्टाल : फाईल : \"$1\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "कीबोर्ड सेटिंग (अगर यह मेनू खराब हो जाए तो minetest.conf से सब कुछ खाली कर दें)" + +#~ msgid "Main" +#~ msgstr "मुख्य" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "छोटा नक्शा रेडर मोड, दोगुना जूम" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "छोटा नक्शा रेडार मोड, 4 गुना ज़ूम" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "छोटा नक्शा जमीन मोड, दोगुना जूम" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "छोटा नक्शा जमीन मोड, 4 गुना जून" + +#~ msgid "Name / Password" +#~ msgstr "नाम/पासवर्ड" + +#~ msgid "Name/Password" +#~ msgstr "नाम/पासवर्ड" + +#~ msgid "No" +#~ msgstr "नहीं" + +#~ msgid "Ok" +#~ msgstr "ठीक है" + +#~ msgid "Parallax Occlusion" +#~ msgstr "पेरलेक्स ऑक्लूजन" + +#~ msgid "PvP enabled" +#~ msgstr "खिलाडियों में मारा-पीटी की अनुमती है" + +#~ msgid "Reset singleplayer world" +#~ msgstr "एक-खिलाडी दुनिया रीसेट करें" + +#~ msgid "Special" +#~ msgstr "स्पेशल" + +#~ msgid "Start Singleplayer" +#~ msgstr "एक-खिलाडी शुरू करें" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "छाया बनावट कॆ लिये OpenGL ड्राईवर आवश्यक हैं|" + +#~ msgid "View" +#~ msgstr "दृश्य" + +#~ msgid "Yes" +#~ msgstr "हां" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "आप \"%s\" नाम से इस सरवर में पहली बार आने वाले हैं। अगर आप आगे बढ़ते हैं तो आपके लिए " +#~ "इस सर्वर पर एक अकाउंट बनाया जाएगा।\n" +#~ "\n" +#~ "आगे बढ़ने ए लिखें कृपया अपने पासवर्ड को वापस लिखें और फिर 'पंजीकरण व खेलें' दबाएं, अथवा " +#~ "'रोकें' दबाएं।" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "आपकी मौत हो गयी" + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/hu/minetest.po b/po/hu/minetest.po new file mode 100644 index 0000000..7bc6b52 --- /dev/null +++ b/po/hu/minetest.po @@ -0,0 +1,8332 @@ +msgid "" +msgstr "" +"Project-Id-Version: Hungarian (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-06-05 13:19+0000\n" +"Last-Translator: Ács Zoltán <acszoltan111@gmail.com>\n" +"Language-Team: Hungarian <https://hosted.weblate.org/projects/minetest/" +"minetest/hu/>\n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.13-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Kimenő üzenetek sorának törlése" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Üres parancs." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Kilépés a főmenübe" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Érvénytelen parancs: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Kiadott parancs: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Online játékosok listázása" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Online játékosok: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "A kimenő üzenetek sora jelenleg üres." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Ezt a parancsot a szerver letiltotta." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Újraéledés" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Meghaltál" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Elérhető parancsok:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Elérhető parancsok: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "A parancs nem elérhető: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Segítség kérése a parancsokhoz" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"További információkhoz adja ki a '.help <cmd>' parancsot, vagy az összes " +"kilistázásához a '.help all' parancsot." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<nincs elérhető>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Hiba történt egy Lua parancsfájlban:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Hiba történt:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Főmenü" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Újrakapcsolódás" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "A szerver újrakapcsolódást kért:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Modok kiválasztása" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protokollverzió-eltérés. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "A szerver által megkövetelt protokollverzió: $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "A szerver $1 és $2 protokollverzió közötti verziókat támogat. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Csak $1 protokollverziót támogatjuk." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "$1 és $2 közötti protokollverziókat támogatjuk." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Mégse" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Függőségek:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Összes letiltása" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Modcsomag letiltása" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Összes engedélyezése" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Modcsomag engedélyezése" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"A(z) „$1” mod engedélyezése sikertelen, mert nem engedélyezett karaktereket " +"tartalmaz. Csak az [a-z0-9_] karakterek engedélyezettek." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "További modok keresése" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Nincsenek (választható) függőségek" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Nincs elérhető játékleírás." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Nincsenek kötelező függőségek" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Nincs elérhető modcsomag-leírás." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Nincsenek választható függőségek" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Választható függőségek:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Mentés" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Világ:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "engedélyezve" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" már létezik. Szeretné felülírni?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$1 és $2 függőségek telepítve lesznek." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 az $2-ből" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 letöltése,\n" +"$2 sorba állítva" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 Letöltése…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "Ehhez szükséges függőségek nem találhatók: $1." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 telepítve lesz, és $2 függőségek ki lesznek hagyva." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Minden csomag" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Már telepítve" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Vissza a főmenübe" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Alapjáték:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "A ContentDB nem elérhető, ha a Minetest cURL nélkül lett lefordítva" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Letöltés…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "$1 letöltése nem sikerült" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Játékok" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Telepítés" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "$1 telepítése" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "hiányzó függőségek telepitése" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Telepítés: nem támogatott fájltípus vagy sérült archívum" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Modok" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "A csomagok nem nyerhetők vissza" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Nincs találat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Nincsenek frissítések" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Nem található" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Felülírás" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Az alapjáték ellenörzése szükséges ." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Sorbaállítva" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Textúracsomagok" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Eltávolítás" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Frissítés" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Összes frissítése [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "További információ megtekintése böngészőben" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Már létezik egy „$1” nevű világ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "További terep" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Hőmérséklet-csökkenés a magassággal" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Páratartalomcsökkenés a magassággal" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Biom keverés" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomok" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Üregek" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Barlangok" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Létrehozás" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekorációk" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Figyelmeztetés: a Development Test fejlesztők számára készült." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Tömlöcök" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Lapos terep" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Lebegő földtömegek az égben" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Lebegő földek (kísérleti)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Nem-fraktál terep generálása: Óceánok és földalatti rész" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Dombok" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Párás folyók" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Megnöveli a páratartalmat a folyók körül" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "$1 telepítése" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Tavak" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Az alacsony páratartalom és a magas hőmérséklet sekélyesíti vagy ki is " +"száríthatja a folyókat" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Térkép generálás" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Térképgenerátor zászlók" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Térképgenerátor különleges zászlói" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Hegyek" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Iszapáramlás" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Alagutak és barlangok hálózata" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Nincs játékmód kiválasztva" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "A magassággal csökken a hőmérséklet" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "A magassággal csökken a páratartalom" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Folyók" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Tengerszinti folyók" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Kezdőérték" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Lágy átmenet a biomok között" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"A terepen megjelenő struktúrák (nincs hatása a fákra és a dzsungelfűre, " +"amelyet a v6 készített)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "A terepen megjelenő struktúrák, általában fák és növények" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Mérsékelt, Sivatag" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Mérsékelt, Sivatag, Dzsungel" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Mérsékelt, Sivatag, Dzsungel, Tundra, Tajga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Terepfelület erózió" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Fák és dzsungelfű" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Változatos folyómélység" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Nagyon nagy üregek mélyen a föld alatt" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Világ neve" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Nincsenek játékok telepítve." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Biztosan törölni szeretnéd ezt: „$1”?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Törlés" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmr: a(z) „$1” törlése sikertelen" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: érvénytelen útvonal: „$1”" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Törlöd a(z) „$1” világot?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Jelszó megerősítése" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Térképgenerátor neve" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Név" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Jelszó" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "A jelszavak nem egyeznek!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Regisztráció és belépés" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Elfogadás" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Modcsomag átnevezése:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Ennek a modcsomagnak a neve a modpack.conf fájlban meghatározott, ami " +"felülír minden itteni átnevezést." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Nincs megadva leírás a beállításhoz)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D zaj" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Vissza a Beállításokra" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Tallózás" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Tartalom" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Tartalom" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Letiltva" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Szerkesztés" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Engedélyezve" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Hézagosság" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktávok" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Eltolás" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Folytonosság" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Írj be egy érvényes egész számot." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Írj be egy érvényes számot." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Alapértelmezés visszaállítása" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Mérték" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Keresés" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Útvonal kiválasztása" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Fájl kiválasztása" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Technikai nevek megjelenítése" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Az érték nem lehet kisebb mint $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Az érték nem lehet nagyobb mint $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X kiterjedés" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y kiterjedés" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z kiterjedés" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "abszolút érték" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "alapértelmezett" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "könyített" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Engedélyezve)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 modok" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "$1 telepítése meghiúsult ide: $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Mod telepítése: nem található valódi mod név ehhez: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Mod telepítése: nem található megfelelő mappanév ehhez a modcsomaghoz: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Nem található érvényes mod vagy modcsomag" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "$1 textúracsomag telepítése meghiúsult" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "$1 aljáték telepítése meghiúsult" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "$1 mod telepítése meghiúsult" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "$1 modcsomag telepítése meghiúsult" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Betöltés…" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "A nyilvános szerverlista le van tiltva" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Próbáld újra engedélyezni a nyilvános szerverlistát, és ellenőrizd az " +"internetkapcsolatot." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Névjegy" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktív közreműködők" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Aktív renderelő:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Játékmotor-fejlesztők" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Felhasználói adatok mappája" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Megnyitja a fájlkezelőben / intézőben azt a könyvtárat, amely a felhasználó " +"világait,\n" +"játékait, modjait, és textúráit tartalmazza." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Korábbi közreműködők" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Korábbi játékmotor-fejlesztők" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Hibakereső információ megjelenítése" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Online tartalmak böngészése" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Tartalom" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Textúracsomag kikapcsolása" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Információ:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Telepített csomagok:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Nincsenek függőségek." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Nincs elérhető csomagleírás" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Átnevezés" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Csomag eltávolítása" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Textúracsomag használata" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Szerver nyilvánossá tétele" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Cím csatolása" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Kreatív mód" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Sérülés engedélyezése" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Játék megosztása" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Szerver felállítása" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Játékok telepítése ContentDB-ről" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Új" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Nincs létrehozott vagy kiválasztott világ!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Játék indítása" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Modok kiválasztása" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Világ kiválasztása:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Szerver portja" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Indítás" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Cím" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Törlés" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Kreatív mód" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Sérülés / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Kedvencek" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Nem kompatibilis szerverek" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Csatlakozás játékhoz" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Nyilvános szerverek" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Frissítés" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Távoli port" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Szerver leírása" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D felhők" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Minden beállítás" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Élsimítás:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Képernyőméret megjegyzése" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilineáris szűrés" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Gombok megváltoztatása" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Csatlakoztatott üveg" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dinamikus árnyékok" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Dinamikus árnyékok: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Szép levelek" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Magas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Alacsony" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Közepes" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + anizotróp szűrés" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Nincs szűrés" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Nincs mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Kockák kiemelése" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Kockák körvonala" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Nincs" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Átlátszatlan levelek" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Átlátszatlan víz" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Részecskék" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Képernyő:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Beállítások" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Árnyalók" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Árnyalók (kísérleti)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Árnyalók (nem elérhető)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Egyszerű levelek" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Lágy megvilágítás" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Textúrázás:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Színleképezés" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Érintésküszöb (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Trilineáris szűrés" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Nagyon magas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Nagyon alacsony" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Ringatózó lombok" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Hullámzó folyadékok" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Ringatózó növények" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Kapcsolódási hiba (időtúllépés?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Csatlakozási idő lejárt." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Kész!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Kockák előkészítése" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Kockák előkészítése…" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Textúrák betöltése…" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Árnyalók újraépítése…" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Kapcsolódási hiba (időtúllépés?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Nem található vagy nem betölthető a játék: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Érvénytelen játékmeghatározás." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Főmenü" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Nincs világ kiválasztva és nincs cím megadva. Nincs mit tenni." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "A játékosnév túl hosszú." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Válassz egy nevet!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "A megadott jelszófájlt nem sikerült megnyitni: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "A megadott útvonalon nem létezik világ: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"A részletekért tekintsd meg a debug.txt fájlt." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Cím: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Mód: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Nyilvános: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Szerver neve: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Hiba történt a sorosítás közben:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Hozzáférés megtagadva. Oka: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Önjárás letiltva" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Önjárás engedélyezve" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Blokkhatárok elrejtve" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Blokkhatárok mutatása minden blokk esetén" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Blokkhatárok mutatása az aktuális blokk esetén" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Közeli blokkok blokkhatárainak megjelenítése" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Kamera frissítés letiltva" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Kamera frissítés engedélyezve" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" +"Blokkhatárok mutatása nem lehetséges ('basic_debug' jogosultság szükséges)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Jelszó módosítása" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Operatőr mód letiltva" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Operatőr mód engedélyezve" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Kliens lecsatlakozott" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Kliens oldali szkriptek letiltva" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Kapcsolódás szerverhez..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Kapcsolat megszakadt ismeretlen okból" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Folytatás" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Irányítás:\n" +"- %s: mozgás előre\n" +"- %s: mozgás hátra\n" +"- %s: mozgás balra\n" +"- %s: mozgás jobbra\n" +"- %s: ugrás/mászás\n" +"- %s: ásás/ütés\n" +"- %s: letevés/használat\n" +"- %s: lopakodás/lefelé mászás\n" +"- %s: tárgy eldobása\n" +"- %s: felszerelés\n" +"- Egér: forgás/nézelődés\n" +"- Egérgörgő: tárgy kiválasztása\n" +"- %s: csevegés\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Cím feloldása sikertelen: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Kliens létrehozása…" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Szerver létrehozása…" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Hibakereső információ és pofiler elrejtése" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Hibakereső információ engedélyezve" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Hibakereső információk, profilgrafika, hálós rajz rejtett" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Alapértelmezett irányítás:\n" +"Ha nem látható menü:\n" +"- egy érintés: gomb aktiválás\n" +"- dupla érintés: lehelyezés/használat\n" +"- ujj csúsztatás: körbenézés\n" +"Ha a Menü/Felszerelés látható:\n" +"- dupla érintés (kívül):\n" +" -->bezárás\n" +"- köteg, vagy hely érintése:\n" +" --> köteg mozgatás\n" +"- \"érint&húz\", érintés 2. ujjal\n" +" --> letesz egyetlen tárgyat a helyre\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Korlátlan látótáv letiltása" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Korlátlan látótáv engedélyezése" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Kliens létrehozása…" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Kilépés a főmenübe" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Kilépés a játékból" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Gyors mód letiltva" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Gyors mód engedélyezve" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Gyors mód engedélyezve (de nincs jogosultságod)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Repülés letiltva" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Repülés engedélyezve" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Repülés engedélyezve (de nincs jogosultságod)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Köd letiltva" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "köd engedélyezve" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Játékinformációk:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Játék szüneteltetve" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Szerver felállítása" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Tárgyak meghatározása…" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Tartalom..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "A kistérkép letiltva (szerver, vagy mod által)" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Többjátékos" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Noclip mód letiltva" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Noclip mód engedélyezve" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Noclip mód engedélyezve (de nincs jogosultságod)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Kockák meghatározása…" + +#: src/client/game.cpp +msgid "Off" +msgstr "Ki" + +#: src/client/game.cpp +msgid "On" +msgstr "Be" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Pályamozgás mód letiltva" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Pályamozgás mód engedélyezve" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profilergrafika megjelenítése" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Távoli szerver" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Cím feloldása…" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Leállítás…" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Egyjátékos" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Hangerő" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Hang némítva" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "A hangrendszer letiltva" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "A hangrendszer nem támogatott ebben build-ben" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Hang visszahangosítva" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "A szerveren valószínűleg a %s másik verziója fut." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Nem lehet csatlakozni a %s-hoz mivel az IPv6 nincs engedélyezve" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Nem lehet figyelni a %s-t mert az IPv6 nincs engedélyezve" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "látótáv %d1" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "látótáv maximum %d1" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "látótáv minimum %d1" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Hangerő átállítva: %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Drótváz megjelenítése" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Nagyítás letiltva (szerver, vagy mod által)" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Csevegés elrejtve" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Csevegés megjelenítése" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD elrejtése" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD megjelenítése" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profiler elrejtése" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profiler megjelenítése (lap: %d1 ennyiből: %d2)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Alkalmazások" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Le" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "EOF törlése" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Végrehajtás" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Segítség" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME Elfogadás" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME átalakítás" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME Kilépés" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME módváltás" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME nem átalakított" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Beszúrás" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Balra" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Bal gomb" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Bal Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Bal menü" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Bal Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Bal Windows" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menü" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Középső gomb" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numpad *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numpad +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numpad -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numpad ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numpad /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numpad 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numpad 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numpad 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numpad 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numpad 5" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numpad 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numpad 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numpad 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numpad 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numpad 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page Down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page Up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Szünet" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Játék" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "PrintScreen" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Jobbra" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Jobb gomb" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Jobb Control" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Jobb menü" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Jobb Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Jobb Windows" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Kiválasztás" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Alvás" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Pillanatkép" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Szóköz" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabulátor" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Fel" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X gomb 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Gomb 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Nagyítás" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Kistérkép letiltva" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimap radar módban, Nagyítás x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Kistérkép terület módban x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Kistérkép textúra módban" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Weblap megnyitása nem sikerült" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Weblap megnyitása" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Folytatás" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = lemászás" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Önjárás" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Automatikus ugrás" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Hátra" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Blokkhatárok" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Nézet váltása" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Csevegés" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Parancs" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konzol" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Látótáv csökkentése" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Halkítás" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Nyomj duplán az „ugrásra” a repülés be-/kikapcsolásához" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Eldobás" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Előre" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Látótáv növelése" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Hangosítás" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Felszerelés" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Ugrás" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "A gomb már használatban van" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Helyi parancs" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Némítás" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Következő tárgy" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Előző elem" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Látótávolság választása" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Képernyőkép" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Lopakodás" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "HUD váltása" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Csevegésnapló váltása" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Gyors mód váltása" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Repülés váltása" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Köd váltása" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Kistérkép váltása" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Noclip mód váltása" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Pályamozgás mód váltása" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "Nyomj meg egy gombot" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Megváltoztatás" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Új jelszó" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Régi jelszó" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "A jelszavak nem egyeznek!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Kilépés" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Némitva" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Hangerő: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "hu" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Válassz egy nevet!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) A virtuális joystick helyének rögzítése.\n" +"Ha le van tiltva, akkor a kijelző megérintésének kezdőpozíciója lesz a " +"virtuális joystick középpontja." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Használd a virtuális joystickot az \"Aux1\" gomb működtetéséhez.\n" +"Ha ez engedélyezve van, akkor a virtuális joystick fő körén kívülre húzáskor " +"az \"Aux1\" gomb is lenyomódik." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"A fraktál (X,Y,Z) relatív pozíciója a világ közepéhez képest, egységekben " +"mérve.\n" +"Használható arra, hogy egy kívánt pontot a (0, 0)-ra tegyünk, hogy " +"megfelelő\n" +"játékoskezdőpontot készítsünk, vagy hogy \"rázoomoljunk\" egy kívánt pontra\n" +"az egység növelése által.\n" +"Az alapérték úgy lett meghatározva, hogy megfelelő játékoskezdőpontot adjon\n" +"az alapparaméterekkel generált Mandelbrot-halmazokhoz, de egyéb esetben\n" +"lehet, hogy meg kell változtatni.\n" +"Nagyjából -2 és 2 közötti értékek. Kockákban mért pozícióhoz szorzunk az " +"egységgel." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"A fraktál (X,Y,Z) méretezési faktora kockatávolságban kifejezve.\n" +"A fraktál tényleges mérete 2-3-szorosa lesz ennek.\n" +"Ezek a számok nagyon nagyok is lehetnek, a fraktálnak\n" +"nem kell elférnie a világban.\n" +"Növelje meg, hogy \"rázoomoljon\" a fraktál részleteire.\n" +"Az alapérték egy függőlegesen összenyomott alakot ad, amely\n" +"szigetekhez alkalmas. Ha a 3 szám egyenlő, a nyers alakot kapjuk." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2D zaj, amely a hegyvonulatok az alakját/méretét szabályozza." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2D zaj, amely a dombok alakját/méretét szabályozza." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2D zaj amely szabályozza a lépés hegyek formáját/méretét." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" +"2D zaj, amely szabályozza az méretét/előfordulását a sziklás hegyláncoknak." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D zaj, amely a dombok méretét/előfordulását szabályozza." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "2D zaj, amely a lépcsős hegységek méretét/előrordulását szabályozza." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" +"2D zaj, amely a folyóvölgyek és a folyómedrek elhelyezkedését szabályozza." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D felhők" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D mód" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "3D mód parallax hatásának erőssége" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Óriási üregeket meghatározó 3D zaj." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"A hegyek szerkezetét és magasságát meghatározó 3D zaj.\n" +"A lebegő földek hegyeit is meghatározza." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"A lebegő földek szerkezetét meghatározó 3D zaj.\n" +"Ha az alapértékekekt megváltoztatják, a zajszintet is át kell állítani\n" +"(0,7 alapbeállításban), mivel a lebegő földeket vékonyítása akkor a\n" +"leghatékonyabb, ha ez az érték körülbelül -2,0 és 2,0 közötti." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "A folyókanyonok falainak szerkezetét meghatározó 3D zaj." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3D zaj amely meghatározza a terepet." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"3D zaj a sziklapárkányokhoz, szirtekhez, stb. Általában kisebb változások." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D-s zaj, amely meghatározza a tömlöcök számát egy térképdarabkánként." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3D támogatás.\n" +"Jelenleg támogatott:\n" +"- none: nincs 3d kimenet.\n" +"- anaglyph: cián/magenta színű 3d.\n" +"- interlaced: páros/páratlan soralapú polarizációs képernyő támogatás.\n" +"- topbottom: osztott képernyő fent/lent.\n" +"- sidebyside: osztott képernyő kétoldalt.\n" +"- crossview: bandzsítva nézendő 3d\n" +"- pageflip: quadbuffer alapú 3d.\n" +"Ne feledje, hogy az interlaced üzemmód, igényli az árnyalók használatát." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Egy választott seed az új térképhez, a véletlenszerűhöz hagyd üresen.\n" +"Felül lesz írva új világ létrehozásánál a főmenüben." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Az összes kliensen megjelenített üzenet a szerver összeomlásakor." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Az összes kliensen megjelenített üzenet a szerver leállításakor." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "ABM intervallum" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "ABM időgazdálkodás" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "A várakozó blokkok felbukkanásának határa" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Gyorsulás levegőben" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Gravitációs gyorsulás, kocka/másodperc/másodpercben." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Aktív blokk módosítók" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Aktív blokk kezelés időköze" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Aktív blokk kiterjedési terület" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Aktív objektum küldés hatótávolsága" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Cím a csatlakozáshoz.\n" +"Hagyd üresen helyi szerver indításához.\n" +"Megjegyzés: a cím mező a főmenüben felülírja ezt a beállítást." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Részecskéket mutat a kockák ásásakor." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Dpi konfiguráció igazítása a képernyődhöz (nem X11/csak Android) pl. 4k " +"képernyőkhöz." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Az észlelt képsűrűség kiigazítása a felhasználói felület elemeinek " +"méretezéséhez." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"A lebegő föld réteg sűrűségét szabályozza.\n" +"Nagyobb sűrűséghez használjon nagyobb értéket. Lehet pozitív vagy negatív " +"is.\n" +"Érték = 0,0: a térfogat 50%-a lebegő föld.\n" +"Érték = 2,0 (magasabb is lehet az 'mgv7_np_floatland'-től függően, a " +"biztonság\n" +"kedvéért mindig próbálja ki) egybefüggő lebegő föld réteget eredményez." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Elemnév hozzáadása" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Haladó" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Módosítja a fénygörbét gamma korrekció hozzáadásával.\n" +"Magasabb értékek esetén a közepes és alacsony fényszintek világosabbak.\n" +"Az 1,0-ás érték a fénygörbét érintetlenül hagyja.\n" +"Csak a nappali és a mesterséges fényt befolyásolja jelentősen,\n" +"a természetes éjszakai fényre nagyon kis hatása van." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Állandó repülés és gyors mód" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Környezeti árnyékolás gamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Üzenetek száma / 10 s." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Erősíti a völgyeket." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Anizotróp szűrés" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Szerver hirdetése" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Szerver kihirdetése erre a szerverlistára." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Elemnév hozzáadása" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Elem nevének hozzáadása az eszköztipphez." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Almafa zaj" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Kar tehetetlenség" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"A kar tehetetlensége reálisabb mozgást biztosít\n" +"a karnak, amikor a kamera mozog." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Összeomlás után újracsatlakozás kérése" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"Ennél a távolságnál a szerver agresszívan optimalizálja, hogy melyik " +"blokkokat\n" +"küldje a klienseknek.\n" +"Kis értékek valószínűleg sokat javítanak a teljesítményen, látható " +"megjelenítési\n" +"hibák árán. (Néhány víz alatti és barlangokban lévő blokk nem jelenik meg,\n" +"néha a felszínen lévők sem.)\n" +"Ha ez az érték nagyobb, mint a \"max_block_send_distance\", akkor nincs\n" +"optimalizáció.\n" +"A távolság blokkokban értendő (16 kocka)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Önjárás gomb" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Automatikusan felugrik az egy kocka magas akadályokra." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Automatikus bejelentés a szerverlistára." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Képernyőméret megjegyzése" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Automatikus méretezés mód" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Aux1 gomb" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Aux1 gomb a mászáshoz/ereszkedéshez" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Vissza gomb" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Talajszint" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Az elsődleges terep magassága." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Alap jogosultságok" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Tengerpart zaj" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Tengerpart zaj határa" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilineáris szűrés" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Cím csatolása" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Biom API hőmérséklet- és páratartalom zaj paraméterei" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Biom zaj" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Max blokk küldési távolság" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Félkövér dőlt betűtípus útvonal" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Félkövér dőlt monospace betűtípus útvonal" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Félkövér betűtípus útvonala" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Félkövér betűtípus útvonal" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Építés játékos helyére" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Beépített" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Nézet váltása" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"A kamera \"közelségi vágósíkjának\" kockákban mért távolsága 0 és 0,25 " +"között.\n" +"Csak GLES platformon működik. A legtöbb felhasználó változatlanul " +"hagyhatja.\n" +"Növelése csökkentheti a grafikai hibákat a gyengébb GPU-kon.\n" +"0,1 = alapértelmezett, 0,25 = jóválasztás gyengébb tabletekhez." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Kamera stabilizálása" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Lágy kameramozgás operatőr módban" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Kamera frissítés váltása gomb" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Barlang zaj" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "1. Barlang zaj" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "2. Barlang zaj" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Barlang szélesség" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "1. Barlang zaj" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "2. Barlang zaj" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Üreg korlát" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Üreg zaj" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Üreg vékonyodás" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Üreg küszöb" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Üreg felső korlát" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"A fénygörbe közepének erősítési tartománya.\n" +"Ahol 0,0 a minimális fényszint, 1,0 a maximális fényszint." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Csevegésparancs üzeneteinek időkorlátja" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Parancsok" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Chat betűméret" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Csevegés gomb" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Chat napló szintje" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Csevegőüzenetek számának korlátozása" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Üzenet formátum" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Sivatag zajának küszöbe" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "CSevegésüzenet maximális hossza" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Csevegés váltása gomb" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Internetes linkek a csevegésben" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Térképdarabka (chunk) mérete" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Operatőr mód" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Operatőr mód gomb" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Tiszta átlátszó textúrák" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Kattintható internetes hivatkozások (középső egérkattintás vagy Ctrl+bal " +"klikk) engedélyezve az elküldött chatüzenetekben." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Kliens" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Kliens és szerver" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Kliens modolás" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Kliens modolási korlátozások" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "A kockakeresési távolság kliensoldali korlátozása" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Kliens modolás" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Mászás sebessége" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Felhők sugara" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Felhők" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "A felhő kliens oldali effektus." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Felhők a menüben" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Színezett köd" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Színezett árnyékok" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"A tartalomtárban elrejtendő jelölők vesszővel tagolt listája.\n" +"\"nonfree\" használatával elrejthetők azok a csomagok, amelyek nem tartoznak " +"a\n" +"\"szabad szoftverek kategóriájába a Free Software Foundation meghatározása " +"szerint.\n" +"Megadhatja továbbá a tartalom besorolásait is.\n" +"Ezek a jelölők függetlenek a Minetest verziótól, ezért nézze meg\n" +"a teljes listát itt: https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Modok vesszővel elválasztott listája, melyeknek engedélyezett HTTP API-k " +"elérése, amik\n" +"lehetővé teszik, hogy fel-letöltsenek adatokat a netről - netre." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Megbízható modok vesszővel elválasztott listája amiknek engedélyezettek nem " +"biztonságos\n" +"funkcióik még a mod biztonság bekapcsolása esetén is " +"(request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Parancs gomb" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"A tömörítés foka a térképblokkok lemezre mentéséhez.\n" +"-1 - alapértelmezett tömörítési fok\n" +"0 - legkisebb tömörítés, leggyorsabb\n" +"9 - legjobb tömörítés, leglassabb" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Tömörítés foka a térképblokkok kliensnek küldéséhez.\n" +"-1 - alapértelmezett tömörítési fok\n" +"0 - legkisebb tömörítés, leggyorsabb\n" +"9 - legjobb tömörítés, leglassabb" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Üveg összeillesztése" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Csatlakozás külső médiaszerverhez" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Üvegfelületek egybeolvasztása, ha a kocka támogatja." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Konzol alfa" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Konzol szín" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Konzol magasság" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Online tartalomtár" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "ContentDB zászló feketelista" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "ContentDB egyidejű letöltések maximális száma" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "ContentDB URL" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Önjárás" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Az \"Önjárás\" gombbal aktiválható folyamatos előre mozgás.\n" +"Nyomja meg az \"Önjárás\" vagy a hátrafelé gombot a kikapcsoláshoz." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Irányítás" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Nappal/éjjel ciklus hosszát határozza meg.\n" +"Példák:\n" +"72 = 20 perc, 360 = 4 perc, 1 = 24 óra, 0 = nappal/éjjel/bármelyik " +"változatlan marad." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "A tavak süllyedésének meredekségét/mélységét állítja." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "A dombok meredekségét/magasságát állítja." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"A csatornák szélességét irányítja, a kisebb érték szélesebb csatornát hoz " +"létre.\n" +"Érték >= 10.0 teljesen kikapcsolja a csatornák generálását és elkerüli az\n" +"intenzív zajszámítást." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Üzenet összeomláskor" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Kreatív" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Célkereszt átlátszóság" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Célkereszt átlátszóság (0 és 255 között).\n" +"Az objektum célkereszt színét is meghatározza." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Célkereszt színe" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Célkereszt szín (R,G,B).\n" +"Az objektum célkereszt színét is állítja" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Sérülés" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Hibakereső információra váltás gomb" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Hibakeresési naplófájl méretküszöbe" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Hibakereső naplózás szintje" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Hangerő csökkentés gomb" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Dedikált szerver lépés" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Alapértelmezett gyorsulás" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Alapértelmezett játék" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Alapértelmezett játék új világ létrehozásánál.\n" +"A főmenüből történő világ létrehozása ezt felülírja." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Alapértelmezett jelszó" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Alap jogosultságok" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Alapértelmezett jelentésformátum" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Alapértelmezett kötegméret" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Árnyékszűrők minőségének beállítása.\n" +"Lágy árnyék effektus szimulálása PCF vagy Poisson disk eljárással,\n" +"de egyéb erőforrásokat is használ." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Azokat a területeket adja meg, ahol a fák almát teremnek." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "A homokos tengerpartok területeit határozza meg." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "A magasabb terep eloszlását, a szirtek meredekségét szabályozza." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "A magasabb területek eloszlását határozza meg." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Az üregek teljes méretét adja meg, a kisebb értékek nagyobb üregeket " +"képeznek." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "A nagy léptékű folyómeder-struktúrát határozza meg." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Az opcionális hegyek és tavak helyzetét és terepét határozza meg." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Meghatározza az alap talajszintet." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "A folyómedrek mélységét határozza meg." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"A maximális játékos küldési távolság blokkokban megadva (0 = korlátlan)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "A folyómedrek szélességét határozza meg." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "A folyóvölgy szélességét határozza meg." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Az erdős területeket és a fák sűrűségét szabályozza." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"A világ modelljének frissítési időköze a klienseken. Ennek a megnövelése\n" +"lelassítja a frissítéseket,így csökkenti a lassú kliensek szaggatását." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Késleltetés az építés és a blokk elküldése között" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Eszköztippek megjelenítésének késleltetése, ezredmásodpercben megadva." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Elavult Lua API kezelése" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "A mélység, ami alatt óriási üregeket találsz majd." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "A mélység, ami alatt nagy barlangokat találsz majd." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"A szerver leírása, amely a szerverlistában jelenik meg és amikor a játékosok " +"csatlakoznak." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Sivatag zaj küszöbe" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Sivatag akkor keletkezik, ha az np_biome meghaladja ezt az értéket.\n" +"Ha az új biom rendszer engedélyezve van, akkor ez mellőzésre kerül." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Blokkanimáció deszinkronizálása" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Dekorációk" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Ásás gomb" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Ásási részecskék" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Csalás elleni védelem letiltása" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Üres jelszavak tiltása" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Képsűrűség méretezési faktor" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "A szerver domain neve, ami a szerverlistában megjelenik." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Az ugrás gomb dupla megnyomása a repüléshez" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Az ugrás gomb kétszeri megnyomásával lehet repülés módba váltani." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Tárgy eldobása gomb" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "A térképgenerátor hibakeresési információinak kiírása." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Tömlöc maximális Y magassága" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Tömlöc minimális Y magassága" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Tömlöc zaj" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"IPv6 támogatás engedélyezése (a kliens és a szerver számára is).\n" +"Szükséges, hogy az IPv6 kapcsolatok egyáltalán működjenek." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Lua modolás támogatás bekapcsolása a kliensen.\n" +"Ez a támogatás még kísérleti fázisban van, így az API változhat." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Poisson disk szűrés engedélyezése.\n" +"Igazra állítás esetén Poisson disk eljárással képez lágy árnyékokat. " +"Különben a PCF szűrőt használja." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Színes árnyékok engedélyezése.\n" +"Igaz érték esetén az áttettsző kockák színes árnyékot vetnek. " +"Erőforrásigényes." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Konzolablak engedélyezése" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Kreatív mód engedélyezése az összes játékos számára" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Joystick engedélyezése" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "A mod csatornák támogatásának engedélyezése." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Mod biztonság engedélyezése" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Játékosok sérülésének és halálának engedélyezése." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" +"Véletlenszerű felhasználói bemenet engedélyezése (csak teszteléshez " +"használható)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"A lágy megvilágítás engedélyezése egyszerű környezeti árnyékolással.\n" +"A sebesség érdekében vagy másféle kinézetért kikapcsolhatod." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Régi verziójú kliensek csatlakozásának tiltása.\n" +"A régi kliensek kompatibilisek olyan értelemben, hogy nem omlanak össze ha " +"egy új verziójú\n" +"szerverhez csatlakoznak, de nem biztos, hogy támogatnak minden elvárt " +"funkciót." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Távoli média szerver használatának engedélyezése (ha a szerver biztosítja).\n" +"Ezekről jelentősen gyorsabb a média letöltése (pl. textúrák)\n" +"a szerverhez történő csatlakozáskor." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Vertex buffer objektumok engedélyezése.\n" +"Ez nagyban javíthatja a grafikus teljesítményt." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Bekapcsolja a fejbillegést és beállítja a mértékét.\n" +"Pl: 0 nincs fejmozgás; 1.0 alapértelmezett fejmozgás van; 2.0 dupla " +"fejmozgás van." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"IPv6 szerver futtatásának engedélyezése/letiltása.\n" +"Nincs figyelembe véve, ha bind_address van beállítva.\n" +"Szükséges hozzá, hogy az ipv6 engedélyezve legyen." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Engedélyezi Hable 'Uncharted 2' színtónusleképezését.\n" +"A fotófilmek színgörbéjét szimulálja és utánozza a nagy dinamikatartományú\n" +"képi megjelenést. A közepző színtartomány kontrasztját kissé\n" +"erősíti, a világosabb és sötétebb részeket fokozatosan tömöríti." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Az felszerelésben lévő tárgyak animációjának engedélyezése." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Az elforgatott hálók irányának gyorsítótárazásának engedélyezése." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Engedélyezi a kistérképet." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Engedélyezi a hangrendszert.\n" +"Ha ki van kapcsolva, teljesen kikapcsol minden hangot és a játék " +"hangvezérlői\n" +"nem fognak működni.\n" +"Ennek a beállításnak a megváltoztatása a játék újraindítását igényli." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Engedélyez olyan kompromisszimus megoldásokat, amelyek csökkentik a CPU " +"terhelését vagy\n" +"növelik a renderelési teljesítményt kisebb vizuális hibák árán, amelyek nem " +"befolyásolják a játszhatóságot." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Völgyek profilja" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Játékmotor profiler adatok kiírási időköze" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Entitás metódusok" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"A lebegő földek vékonyításának kitevője. A vékonyítás módján változtat.\n" +"Érték = 1,0 egyeneletes, lineáris vékonyítás.\n" +"Értékek > 1,0 az alapértelmezett különálló lebegő földekhez illő könnyed\n" +"vékonyítás.\n" +"Értékek < 1,0 (például 0,25) határozottab felszínt képez laposabb " +"alföldekkel,\n" +"egybefüggű lebegő föld réteghez használható." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS, amikor a játék meg van állítva, vagy nincs fókuszban" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Tényezőzaj" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Leesés utáni fejrázkódási tényező" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Tartalék betűtípus útvonala" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Gyorsaság gomb" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Gyorsulás gyors módban" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Sebesség gyors módban" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Gyors mozgás" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Gyors mozgás (az \"Aux1\" gombbal).\n" +"Szükséges hozzá a gyors mód jogosultság a szerveren." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Látótávolság" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Látóterület fokokban." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"A client/serverlist/ mappában lévő fájl, ami tartalmazza a kedvenc " +"szervereidet,\n" +"amik a Többjátékos fül alatt jelennek meg." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "A kitöltőanyag mélysége" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Kitöltőanyag mélység zaj" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Filmes színhatás" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"A szűrt textúrák vegyíthetik a teljesen átlátszó szomszédokkal rendelkező " +"RGB értékeket,\n" +"amit a PNG optimalizálók általában figyelmen kívül hagynak, és ez gyakran " +"sötét vagy\n" +"világos élekhez vezet az átlátszó textúráknál. Használjon szűrőt ezeknek a " +"textúra betöltésekor\n" +"történő eltüntetésére. Ez automatikusan bekapcsol, ha a mipmapping be van " +"kapcsolva." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Élsimítás:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Az első a négy 2D zajból, amelyek együttesen meghatározzák a dombságok/" +"hegységek magasságát." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" +"Az első a két 3D zajból, amelyek együttesen meghatározzák az alagutakat." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Fix térkép seed" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Rögzített virtuális joystick" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Lebegő földek sűrűsége" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Lebegő földek maximális Y magassága" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Lebegő földek minimális Y magassága" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Lebegő földek zaja" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "A lebegő földek kúpkitevője" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "A lebegő földek kúpjainak távolsága" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Lebegő földek vízszintje" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Repülés gomb" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Repülés" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Köd" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Köd indulás" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Köd váltása gomb" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Betűtípus mérete" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Félkövér betűtípus alapértelmezetten" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Dőlt betűtípus alapértelmezetten" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Betűtípus árnyéka" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Betűtípus árnyék átlátszósága" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Betűtípus mérete" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Betűméret osztója" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" +"Az alapértelmezett betűtípus betűmérete, ahol 1 egység = 1 pixel 96 DPI " +"esetén" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" +"A monospace betűtípus betűmérete, ahol 1 egység = 1 pixel 96 DPI esetén" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"A legutóbbi csevegésszövegek és üzenetek betűmérete pontban (pt).\n" +"0 érték esetén az alapértelmezett betűméretet fogja használni." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"A pixeles stílusú betűtípusokhoz, amelyek nem méretezhetők olyan jól, ez " +"biztosítja, hogy a használt\n" +"betűméretek az ilyen betűtípus esetén mindig oszthatók legyenek ezzel az " +"értékkel, pixelben. Például\n" +"egy 16 pixel magas pixeles stílusú betűtípus esetén ezt 16-ra kell állítani, " +"ezáltal csak 16, 32, 48 stb.\n" +"lesz használható, ezért ha egy mod 25-ös méretet igényel, 32-est fog kapni." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"A játékos csevegési üzeneteinek formátuma. A következő karakterláncok " +"érvényesek:\n" +"@név, @üzenet, @időbélyeg (opcionális)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Képernyőmentések formátuma." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Formspec panelek alapértelmezett háttérszíne" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Formspec panelek hátterének alapértelmezett átlátszósága" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Teljes képernyős Formspec panelek háttérszíne" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Teljes képernyős Formspec panelek hátterének átlátszósága" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Formspec panelek alapértelmezett háttérszíne (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" +"Játékon belüli kezelőpanelek hátterének alfája (átlátszatlanság, 0 és 255 " +"között)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" +"Játékon belüli teljes képrenyős kezelőpanelek hátterének színe (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" +"Játékon belüli csevegő konzol hátterének átlátszósága (0 és 255 között)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Előre gomb" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"A negyedik a négy 2D zajból, amelyek együttesen meghatározzák a dombságok/" +"hegységek magasságát." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Fraktál típusa" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "A látótávolságnak az a része, amelynél a köd renderelése kezdődik" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Milyen távolságból generálódnak a blokkok a kliensek számára, " +"térképblokkokban megadva (16 kocka)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Milyen távolságból lesznek elküldve a blokkok a kliens számára, " +"térképblokkokban megadva (16 kocka)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Mekkora távolságból észleljék a kliensek az objektumokat, térképblokkokban " +"mérve (16 kocka).\n" +"\n" +"Ha nagyobbra van állítva, mint az active_block_range, akkor a szervert arra " +"kényszeríti, hogy\n" +"az aktív objektumokat betöltve tartsa eddig a távolságig a játékos " +"tekintetének irányában.\n" +"(Ez megakadályozza, hogy a mobok hirtelen eltűnjenek a látómezőből)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Teljes képernyő" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Teljes képernyős mód." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Felhasználói felület méretaránya" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Felhasználói felület méretarány szűrő" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Felhasználói felület méretarány szűrő txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Játékok" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Globális visszatérések" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Globális térképgenerálási jellemzők.\n" +"A Mapgen v6 térképgenerátorban a 'decorations' jelző szabályozza az összes " +"dekorációt,\n" +"kivéve a fákat és a dzsungelfüvet, a többi térképgenerátornál pedig az " +"összeset." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"A fénygörbe gradiense a legmagasabb fényszinten.\n" +"A legmagasabb fényszintek kontrasztrját szabályozza." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"A fénygörbe gradiense a legalacsonyabb fényszinten.\n" +"A legalacsonyabb fényszintek kontrasztrját szabályozza." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravitáció" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Talajszint" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Talaj zaj" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP Modok" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Felhasználói felület méretaránya" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "HUD váltás gomb" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Az elavult Lua API hívások kezelése:\n" +"-none: ne naplózza az elavult hívásokat\n" +"-log: elavult hívás utánozása és naplózása (alapértelmezett).\n" +"-error: megszakítja az elavult hívás használatát (javasolt a " +"modfejlesztőknek)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Hagyja, hogy a profiler behangolja magát:\n" +"* Üres függvény behangolása.\n" +"Ezáltal mérhető, hogy a hangolás maga mennyi időbe telik (+1 " +"függvényhívás).\n" +"* A mintavevő hangolása a mutatószámok frissítésehez." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Hőkeverési zaj" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Hőzaj" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"A kezdőablak magassága. Teljes képernyős módban nem kerül figyelmbe vételre." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Magasság zaj" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "A magasságot kiválasztó zaj" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Domb meredekség" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Domb küszöb" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "1. dombosság zaj" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "2. dombosság zaj" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "3. dombosság zaj" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "4. dombosság zaj" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "A szerver honlapja, ami a szerverlistában megjelenik." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Vízszintes gyorsulás a levegőben ugráskor vagy leeséskor,\n" +"kocka/másodperc/másodpercben." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Vízszintes és függőleges gyorsulás gyors módban,\n" +"kocka/másodperc/másodpercben." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Vízszintes és függőleges gyorsulás a földön, vagy mászáskor,\n" +"kocka/másodperc/másodpercben." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Gyorselérési sáv következő gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Gyorselérési sáv előző gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Gyorselérési sáv 1-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Gyorselérési sáv 10-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Gyorselérési sáv 11-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Gyorselérési sáv 12-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Gyorselérési sáv 13-as hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Gyorselérési sáv 14-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Gyorselérési sáv 15-ös hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Gyorselérési sáv 16-os hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Gyorselérési sáv 17-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Gyorselérési sáv 18-as hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Gyorselérési sáv 19-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Gyorselérési sáv 2-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Gyorselérési sáv 20-as hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Gyorselérési sáv 21-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Gyorselérési sáv 22-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Gyorselérési sáv 23-as hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Gyorselérési sáv 24-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Gyorselérési sáv 25-ös hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Gyorselérési sáv 26-os hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Gyorselérési sáv 27-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Gyorselérési sáv 28-as hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Gyorselérési sáv 29-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Gyorselérési sáv 3-as hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Gyorselérési sáv 30-as hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Gyorselérési sáv 31-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Gyorselérési sáv 32-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Gyorselérési sáv 4-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Gyorselérési sáv 5-ös hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Gyorselérési sáv 6-os hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Gyorselérési sáv 7-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Gyorselérési sáv 8-as hely gomb" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Gyorselérési sáv 9-es hely gomb" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "A folyók mélysége." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Milyen gyorsan mozognak a folyadékhullámok. Magasabb = gyorsabb.\n" +"Ha negatív, a folyadékhullámok hátrafelé mozognak.\n" +"Engedélyezni kell a hullámzó folyadékokat hozzá." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Mennyi ideig vár a szerver, mielőtt eltávolítja a memóriából a nem használt " +"térképblokkokat.\n" +"Magasabb érték stabilabb, de több RAM-ot használ." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Csökkentse ezt hogy megnövelje a folyadék ellenállását." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "A folyók szélessége." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Páratartalom keverés zaj" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Páratartalom zaj" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Páratartalom-változékonyság a biomokban." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6 szerver" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Ha az FPS ennél magasabbra is tudna menni, lekorlátozható, \n" +"hogy ne pazaroljon CPU erőforrást feleslegesen." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Ha le van tiltva, az \"Aux1\" gombbal lehet gyorsan repülni, ha a repülés és " +"a gyors mód is engedélyezve van." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Ha engedélyezve, a szerver kiválogatja a takarásban lévő térképblokkokat\n" +"a játékos szemszögének megfelelően. Ezáltal a kliensnek küldött blokkok\n" +"száma 50-80%-kal csökkenthető. A klines nem kapja ezentúl a legtöbb nem\n" +"látható blokkot, emiatt a noclip mód (falonátjárás) kevésbé lesz használható." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Ha a repülés móddal együtt van engedélyezve, a játékos átrepülhet szilárd\n" +"kockákon. Szükséges hozzá a noclip jogosultság a szerveren." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Ha engedélyezve van, az \"Aux1\" gombbal lehet lefelé mászni vagy " +"leereszkedni a \"Lopakodás\" gomb helyett." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Ha be van kapcsolva, a regisztráció megerősítését kéri, amikor csatlakozik " +"egy szerverhez.\n" +"Ha ki van kapcsolva, az új fiók automatikusan regisztrálásra kerül." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Ha engedélyezve van, akkor a műveletek rögzülnek a visszavonhatóság " +"érdekében.\n" +"Ez az opció csak akkor van beolvasva, amikor a szerver elindul." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" +"Ha ez engedélyezve van, kikapcsolja a csalás megelőzést többjátékos módban." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Ha engedélyezve van, érvénytelen világ adat nem okozza a szerver leállását.\n" +"Csak akkor engedélyezd, ha tudod, hogy mit csinálsz." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Ha engedélyezve van, a játékos abba az irányba megy, amerre néz, amikor " +"úszik vagy repül." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "Ha engedélyezve van, új játékosok nem csatlakozhatnak jelszó nélkül." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Ha engedélyezve van, lehelyezhetsz kockákat oda, ahol állsz (láb + " +"szemmagasság).\n" +"Ez segít, ha kis területen dolgozol." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Ha a CSM-korlátozás be van kapcsolva az aktív kockák távolságára, akkor a " +"get_node\n" +"hívások korlátozva lesznek a játékostól e távolságon belül található " +"kockákra." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Ha egy parancs végrehajtása tovább tart, mint az itt másodpercben megadott " +"idő,\n" +"az időadatok hozzá lesznek fűzve a parancs visszajelző üzenetéhez" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Ha a debug.txt fájlmérete megabájtban meghaladja megnyitáskor az itt \n" +"megadott számot, a fájl átnevezésre kerül debug.txt.1-re,\n" +"és ha létezett egy régebbi debug.txt.1, az törlésre kerül.\n" +"A debug.txt csak akkor lesz átnevezve, ha ez a beállítás engedélyzve van." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" +"Ha be van állítva, a játékosok mindig a megadott pozícióban élednek újra (és " +"jelennek meg új csatlakozáskor)." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Világhibák figyelmen kívül hagyása" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Játékon belüli csevegő konzol hátterének átlátszósága (0 és 255 között)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Játékon belüli csevegő konzol hátterének színe (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"Játékon belüli csevegéskonzol magassága 0,1 (10%) és 1,0 (100%) között." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Hangerő növelése gomb" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Kezdeti függőleges sebesség ugráskor, kocka/másodpercben." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Beépülő behangolása.\n" +"Erre általában csak a játékmotor vagy a beépülők készítésében " +"közreműködőknek van szükségük" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "Csevegésparancsok behangolása regisztrációkor." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"A globális callback függvények behangolása regisztrációkor.\n" +"(bármi, amit átadsz egy minetest.register_*() függvénynek)" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Az aktív blokk módosítók akciófüggvényének behangolása regisztrációkor." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"A betöltendő blokk módosítók akciófüggvényének behangolása regisztrációkor." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Az entitások metódusainak hangolása regisztrációkor." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Fontos változások mentésének időköze a világban, másodpercekben megadva." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "A napszak kliensnek való küldésének gyakorisága." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Felszerelésben lévő tárgyak animációi" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Felszerelés gomb" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Egér megfordítása" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Függőleges egérmozgás megfordítása." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Dőlt betűtípus útvonala" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Dőlt monospace betűtípus útvonala" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Elem entitás TTL" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Ismétlések" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"A rekurzív függvény ismétlései.\n" +"Ennek növelése növeli a finom részletek mennyiségét és\n" +"növeli a feldolgozási terhelést.\n" +" 20 ismétlésnél ez a térképgeneráló hasonló terheléssel rendelkezik, mint a " +"V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "Joystick ID" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Joystick gomb ismétlési időköze" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "Joystick holttér" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Joystick látómező-érzékenység" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Joystick típusa" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Julia-halmaz.\n" +"W komponens hiperkomplex állandó.\n" +"Megváltoztatja a fraktál alakját.\n" +"Nincs hatása a 3D Fraktálokra.\n" +"Tartomány nagyjából -2 és 2 között." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Julia-halmaz.\n" +"X komponens hiperkomplex állandó.\n" +"Megváltoztatja a fraktál alakját.\n" +"Tartomány nagyjából -2 és 2 között." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Julia-halmaz.\n" +"Y komponens hiperkomplex állandó.\n" +"Megváltoztatja a fraktál alakját.\n" +"Tartomány nagyjából -2 és 2 között." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Csak Julia-halmaz.\n" +"Hiperkomplex állandó Z összetevője.\n" +"Megváltoztatja a fraktál alakját.\n" +"Tartomány nagyjából -2 és 2 között." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia W" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Júlia X" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Júlia Y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Júlia Z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Ugrás gomb" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Ugrás sebessége" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a látóterület csökkentéséhez.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a hangerő csökkentéséhez.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb az ásáshoz.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb az éppen kijelölt tárgy eldobásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a látóterület növeléséhez.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a hangerő növeléséhez.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb az ugráshoz.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a gyors mozgáshoz gyors módban.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a játékos hátrafelé mozgásához.\n" +"Kikapcsolja az önjárást is, ha aktív.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a játékos előre mozgásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a játékos balra mozgatásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a játékos jobbra mozgatásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a játék némításához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a csevegőablak megnyitásához, parancsok beírásához.\n" +"Lásd: //irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a csevegőablak megnyitásához, helyi parancsok beírásához.\n" +"Lásd: //irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a csevegőablak megnyitásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a felszerelés megnyitásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a lehelyezéshez.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 11. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 12. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 13. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 14. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 15. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 16. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 17. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 18. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 19. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 20. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 21. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 22. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 23. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 24. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 25. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 26. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 27. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 28. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 29. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 30. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 31. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 32. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 8. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 5. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 1. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 4. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a következő elem kiválasztásához az eszköztárban.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 9. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb az előző elem kiválasztásához az eszköztárban.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 2. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 7. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 6. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 10. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a 3. eszköztárhely kiválasztásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a lopakodáshoz.\n" +"A lefelé mászáshoz és vízben történő ereszkedéshez is ezt lehet használni, " +"ha az aux1_descends le van tiltva.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a belső és külső nézetre váltáshoz.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb képernyőkép készítéshez.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb az automatikus előrehaladás bekapcsolásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb az operatőr mód kapcsolgatásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a kistérkép váltásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a gyors mód váltásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a repülés mód váltásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a noclip mód váltásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb pályamozgás mód váltásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a kamerafrissítés váltásához. Csak fejlesztők számára.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a csevegés megjelenítéséhez.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a hibakeresési információ megjelenítéséhez.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a köd váltásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a HUD váltásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a nagy csevegéskonzol megjelenítéséhez.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"A profiler kijelzőjének kapcsológombja. Fejlesztéshez használatos.\n" +"Lásd http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a végtelen látóterület váltásához.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Gomb a nagyításhoz amikor lehetséges.\n" +"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" +"Azon játékosok kirúgása, akik 10 másodpercenként több mint X üzenetet " +"küldtek." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Tó meredekség" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Tó küszöb" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Nyelv" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Nagy barlang mélység" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Nagy barlangok maximális száma" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Nagy barlangok minimális száma" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "A nagy barlangok egy része elárasztott" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Nagy csevegéskonzol gomb" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Levelek stílusa" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Levelek stílusa:\n" +"- fancy: (szép) minden oldal látható\n" +"- simple: (egyszerű) csak a külső oldalak láthatók, a special_tiles-t " +"használja, ha meg van adva\n" +"- opaque: (átlátszatlan) átlátszóság kikapcsolása" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Bal gomb" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"A szerver órajelének hossza és az az intervallum, amely alatt az " +"objektumokat általánosan\n" +"frissíti a hálózaton." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Folyadékhullámok hossza.\n" +"A hullámzó folyadékok engedélyezése szükséges hozzá." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Az Aktív Blokk módosító (ABM) végrehajtási ciklusok közötti időtartam" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Két NodeTimer végrehajtás között eltelt idő" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Két aktív blokk kezelési fázis között eltelt idő" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"A debug.txt fájlba írandó naplózási szint:\n" +"-semmi (nincs naplózás)\n" +"-minimális (szint nélküli üzenetek)\n" +"-hiba\n" +"-figyelmeztetés\n" +"-művelet\n" +"-információ\n" +"-fecsegő" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Fénygörbe kiemelés" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Fénygörbe kiemelés középpontja" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Fénygörbe kiemelés kiterjedése" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Fénygörbe kiemelés gammája" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "A fénygörbe tetejének gradiense" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "A fénygörbe aljának gradiense" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Lágy megvilágítás" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"A térképgenerálás határa, kockákban, mind a 6 irányban a (0, 0, 0) " +"pozíciótól kezdve.\n" +"Csak a teljesen a térképgenerálási határon belül lévő térképdarabkák " +"generálódnak le.\n" +"Az érték világonként külön tárolódik." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"A párhzamos HTTP-kérések számának korlátja. Hatása:\n" +"- Médialekérések, ha a szerver remote_media beállítást használ.\n" +"- Szerverlista letöltés és szerverközzététel.\n" +"- Letöltések a főmenüből (pl. mod manager).\n" +"Csak akkor van hatása, ha cURL-lel lett összeállítva." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Folyadék folyékonysága" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Folyadékok egyenletesebb folyása" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Folyadékhullámzás maximum" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Folyadék sortisztítási ideje" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Folyadék süllyedés" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "A folyadékok frissítési időköze másodpercben." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Folyadékfrissítés tick" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Játék profiler betöltése" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"A játék profiler betöltése hogy játékprofílozási adatokat gyűjtsön.\n" +"Elérhetővé teszi a /profiler parancsot, amellyel elérhetők az összeállított " +"profilok.\n" +"Hasznos lehet modfejelsztőknek és szerverüzemeltetőknek." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Betöltendő blokk módosítók" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "A tömlöcök alsó Y határa." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "A lebegő földek alsó Y határa." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Főmenü szkript" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"A köd és az ég színe függjön a napszaktól (hajnal/naplemente) és a " +"látószögtől." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Az összes folyadékot átlátszatlanná teszi" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "A térkép tömörítésének foka merevlemezen való tároláshoz" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "A térkép tömörítésének foka hálózati átvitelhez" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Térkép mappája" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "A Kárpátok térképgenerátorra vonatkozó térképgenerálási beállítások." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"A Lapos térképgenerátor sajátos tulajdonságai.\n" +"Alkalmanként tavak és dombok hozzáadódhatnak a lapos világhoz." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"A Fraktál térképgenerátor sajátos jellemzői.\n" +"A 'terrain' engedélyezi a nem-fraktál terep generálását,\n" +"mint az óceán, szigetek és a földalatti részek." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"A Völgyek térképgenerátor sajátos jellemzői.\n" +"'altitude_chill': csökkenti a hőmérsékletet a magassággal.\n" +"'humid_rivers': megnöveli a páratartalmat a folyók körül.\n" +"'vary_river_depth': ha engedélyezve van, az alacsony páratalom és a magas\n" +"hőmérséklet hatására a folyók sekélyebbé válnak, és lehet, hogy " +"kiszáradnak.\n" +"'altitude_dry': csökkenti a páratartalmat a magassággal." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "A v5 térképgenerátor sajátos tulajdonságai." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"A v6 térképgenerátor sajátos jellemzői.\n" +"A 'snowbiomes' zászló engedélyezi az új 5 biomos rendszert.\n" +"Amikor a 'snowbiomes' zászló engedélyezett a dzsungelek automatikusan " +"engedélyezve vannak\n" +"és a 'jungles' zászló figyelmen kívül van hagyva." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Térkép generálási jellemzők csak a v7 térképgenerátor esetében.\n" +"'ridges': folyók.\n" +"'floatlands': lebegő földtömegek a légkörben.\n" +"'caverns': óriási barlangok mélyen a föld alatt." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Térkép generálási korlát" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Térkép mentésének időköze" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "Árnyéktérkép frissítési idő" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Térképblokk korlát" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Térképblokk háló generálási késleltetés" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Térképblokk hálógenerátor MapBlock gyorsítótár mérete MB-ban" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Térképblokk memóriaürítésének időkorlátja" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Kárpátok térképgenerátor" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Kárpátok térképgenerátor különleges zászlói" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Lapos térképgenerátor" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Lapos térképgenerátor különleges zászlói" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Fraktál térképgenerátor" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Fraktál térképgenerátor domb meredekség" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "V5 térképgenerátor" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Lapos térképgenerátor különleges zászlók" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "V6 térképgenerátor" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "V6 térképgenerátor különleges zászlói" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "V7 térképgenerátor" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "V7 térképgenerátor különleges zászlói" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Völgyek térképgenerátor" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Völgyek térképgenerátor különleges zászlói" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Térképgenerátor hibakereső" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Térképgenerátor neve" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Max blokk generálási távolság" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Max blokk-küldési távolság" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Max folyadék feldolgozva lépésenként." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Max. objektumtakarítás az extra blokkora" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Maximum csomagok ismétlésenként" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Maximum FPS (képkocka/mp)" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "Maximum FPS, amikor a játék szüneteltetve van, vagy nincs fókuszban." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Az árnyékok renderelésének maximális távolsága." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Az erőltetett betöltésű blokkok maximuma" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Gyorselérési sáv maximális szélessége" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" +"A véletlenszerűen egy térképdarabkára jutó nagy barlangok számának maximális " +"korlátja." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" +"A véletlenszerűen egy térképdarabkára jutó kis barlangok számának maximális " +"korlátja." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Maximális közegellenállás folyadékban. A nagy sebességgel folyadékba való\n" +"belépéskor bekövetkező lassulást szabályozza." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"A szimultán küldött blokkok maximális száma kliensenként.\n" +"A maximális összértéket így számoljuk dinamikusan:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "Maximum blokkok száma, amik sorban állhatnak betöltésre." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Maximum blokkok száma, amik sorban állhatnak generálásra.\n" +"Ez a korlát játékosonként van kényszerítve." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Maximum blokkok száma, amik sorban állhatnak egy fájlból való betöltésre.\n" +"Ez a korlát játékosonként van kényszerítve." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Az egyszerre folyó letöltések maximális száma. A korláton túli letöltéseket " +"várólistára teszi.\n" +"A curl_parallel_limit-nél kisebbnek kell lennie." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Az erőltetetten betöltött térképblokkok maximális száma." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Maximum térképblokkok száma, amit a kliens memóriában tárolhat.\n" +"Állítsd -1-re végtelen mennyiségért." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"A lépésenként küldött csomagok maximális száma,\n" +"ha lassú kapcsolattal rendelkezel, próbáld csökkenteni,\n" +"de ne csökkentsd a kívánt kliensszám duplája alá." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Az egy időben csatlakozó játékosok maximális száma." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "A megjelenítendő csevegésüzenetek maximális száma" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Statikusan tárolt objektumok maximális száma egy térképblokkban." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Maximum objektumok térképblokkonként" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Az aktuális ablak maximum hányada a gyorselérési sáv számára.\n" +"Hasznos, ha valamit el kell helyezni a sáv jobb, vagy bal oldalán." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Az egyidejűleg a kliensenként küldött térképblokkok maximális száma" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Kimenő üzenetek sorának maximális mérete" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"A kimenő üzenetek sorának maximális mérete.\n" +"0 letiltja a várolistára helyezést, míg -1 korlátlanná teszi a sor méretét." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Egy fájl letöltésének maximum ideje (milliszekundumban), amíg eltarthat (pl. " +"mod letöltés)." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Az interaktív kérések (pl. szerverlista lekérése) számára rendelkezésre álló " +"maximális idő milliszekundumban." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Maximum felhasználók" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Poligonháló cashe" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Napi üzenet" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Napi üzenet a csatlakozó játékosoknak." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Kijelölt objektum kiemelésére használt módszer." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "A naplózás csevegésbe írásának minimális szintje." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Kistérkép" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Kistérkép gomb" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Kistérkép letapogatási magasság" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" +"A véletlenszerűen egy térképdarabkára jutó nagy barlangok számának minimális " +"korlátja." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" +"A véletlenszerűen egy térképdarabkára jutó kis barlangok számának minimális " +"korlátja." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Minimum textúra méret" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mipmapping" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Profiler" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Biztonság" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Mod csatornák" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "A HUD elemméretét módosítja." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Monospace betűtípus útvonal" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Monospace betűméret" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "Monospace betűméret osztója" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Hegy magasság zaj" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Hegy zaj" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Hegy változékonyság zaj" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Hegyek legkisebb szintje" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Egér érzékenysége" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Egér érzékenységi faktora." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Iszap zaj" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"A zuhanás utáni fejbillenés szorzója.\n" +"Például: 0 nincs biccentés; 1,0 normál; 2,0 dupla." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Némítás gomb" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Hang némítása" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Az új világ létrehozásakor használandó térképgenerátor neve.\n" +"Új világ főmenüben történő létrehozása felülírja ezt.\n" +"Jelenleg a következő térképgenerátorok nagyon instabilak:\n" +"- Az opcionális lebegő földek a v7-ben (alapértelmezés szerint tiltott)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"A játékos neve.\n" +"Szerver indításakor ezzel a névvel csatlakozó játékos admin jogú.\n" +"A főmenüből történő indítás ezt felülírja." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"A szerver neve, ami megjelenik a szerverlistában, és amikor a játékosok " +"csatlakoznak." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Majdnem mint a repülőgép" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Figyelt hálózati port (UDP).\n" +"Főmenüből való indításkor felülíródik ez az érték." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Hálózat" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Az új felhasználóknak ezt a jelszót kell megadniuk." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Noclip" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Noclip mód gomb" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Kockák kiemelése" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Kockák kiemelése" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "NodeTimer időköz" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Zajok" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "A térképblokk betöltő szálak száma" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"A térképblokkok betöltésére használt szálak száma.\n" +"Érték 0:\n" +"- Automatikus választás. A térképblokkok betöltését végző szálak száma\n" +"- \"processzorok száma - 2\" lesz, de legalább 1.\n" +"Bármilyen más érték:\n" +"- Meghatározza a térképblokkbetöltő szálak számát, amelynek alsó korlátja " +"1.\n" +"FIGYELEM: A térképblokkbetöltő szálak számának növelése növeli a játékmotor " +"mapgen\n" +"folyamatainak sebességét, de csökkentheti a játékteljesítményt azáltal, hogy " +"más\n" +"folyamatokat akadályoznak, különösen egyjátékos módban és/vagy Lua kódok " +"futtatásakor\n" +"az 'on_generated' eseményben. Sok játékos számára valószínűleg az 1 az " +"optimális beállítás." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"A /clearobjects parancs által egyidejűleg betölthető extra blokkok száma.\n" +"Kompromisszum az SQLite tranzakciók erőforrásigénye és a\n" +"memóriahasználat között (4096=100MB hüvelykujjszabályként)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Átlátszatlan folyadékok" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" +"Az alapértelmezett betűtípus mögötti árnyék átlátszatlansága (alfa) 0 és 255 " +"között." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Megnyitja a szünet menüt, ha az ablak kikerül a fókuszból. Nem szünetel, ha " +"nyitva van\n" +"egy formspec panel." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "A csevegésben lévő internetes linkek színének opcionális felülírása." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"A tartalék betűtípus elérési útvonala. TrueType betűtípusnak kell lenni.\n" +"Bizonyos nyelvek ezt a betűtípust használják vagy ha az alapértelmezett " +"betűtípus nem elérhető." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"A képernyőképek mentésének elérési útvonala. Lehet abszolút vagy relatív " +"elérési út.\n" +"Ha még nem létezik a mappa, létre lesz hozva." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Az árnyalókat tartalmazó mappa elérési útvonala. Ha nincs beállítva, az " +"alapértelmezett útvonalat használja." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "Textúra mappa útvonala. Először minden textúrát itt keres a játék." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Az alapértelmezett betűtípus elérési útja. TrueType betűtípusnak kell " +"lenni.\n" +"Ha nem lehet betölteni a betűtípust, a tartalék betűtípust fogja használni." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"A monospace betűtípus elérési útvonala. TrueType betűtípusnak kell lenni.\n" +"Ezt a betűtípust használja pl. a konzol és a profiler képernyő." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Szüneteltetés ha az ablak kikerül a fókuszból" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" +"A merevlemezről várólistára töltött blokkok számának korlátja játékosonként" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" +"A várólistára töltött létrehozandó blokkok számának korlátja játékosonként" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fizika" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Pályamozgás mód gomb" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Tekintet irányába mozgás" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Lehelyezés gomb" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Lehelyezés-ismétlési időköz" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"A játékos képes repülni, nem hat rá a gravitáció.\n" +"Szükséges hozzá a repülés jogosultság a szerveren." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Játékosátviteli távolság" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Játékos játékos ellen" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Poisson szűrés" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Port a csatlakozáshoz (UDP).\n" +"A főmenü port mezője ezt a beállítást felülírja." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Ásás és lehelyezés ismétlődésének megakadályozása, amikor nyomva tartod az " +"egérgombokat.\n" +"Engedélyezd, ha túl gyakran fordul elő, hogy véletlenül lehelyezel vagy " +"kiásol blokkokat." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Annak megelőzése, hogy a modok nem biztonságos dolgokat futtassanak, pl. " +"shell parancsok." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"A játékmotor profiladatainak kiírása szabályos időközökben " +"(másodpercekben).\n" +"0 a kikapcsoláshoz. Hasznos fejlesztőknek." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Jogosultságok, amiket a basic_privs adhat a játékosoknak" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Profiler" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Profiler váltó gomb" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Prometheus figyelési cím" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Prometheus figyelési cím.\n" +"Ha a Minetest-et az ENABLE_PROMETHEUS opció engedélyezésével állítták " +"össze,\n" +"elérhetővé válnak a Prometheus mérőszám figyelői ezen a címen.\n" +"A mérőszámok itt érhetők el: http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Nagy barlangok aránya amelyek folyadékot tartalmaznak." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"A felhők kiterjedése 64 kockás felhőnégyzetek számában mérve.\n" +"26-nál nagyobb értékek éles határt eredményeznek a felhők sarkainál." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Megemeli a terepet, hogy völgyek alakuljanak a folyók körül." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Véletlenszerű bemenet" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Látóterület választása gomb" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Legutóbbi csevegésüzenetek" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Betűtípus útvonala" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Távoli média" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Távoli port" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Színkódok eltávolítása a bejövő csevegésüzenetekből\n" +"Használd ezt hogy megakadályozd, hogy a játékosok színeket használjanak az " +"üzeneteikben" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Az alapértelmezett főmenüt lecseréli egy másikkal." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Napló útvonala" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Korlátozza bizonyos kliensoldali függvényekhez a hozzáférést a szerveren.\n" +"Kombináld az alábbi bájtcímkéket a kliensoldali képességek korlátozásához,\n" +"vagy állítsd 0-ra a korlátozások eltávolításához:\n" +"LOAD_CLIENT_MODS: 1 (letitlja a kliensoldali modok betöltését)\n" +"CHAT_MESSAGES: 2 (letiltja a send_chat_message hívásokat kliensoldalon)\n" +"READ_ITEMDEFS: 4 (letiltja a get_item_def hívásokat kliensoldalon)\n" +"READ_NODEDEFS: 8 (letiltja a get_node_def hívásokat kliensoldalon)\n" +"LOOKUP_NODES_LIMIT: 16 (korlátozza a get_node hívásokat kliensoldalon a\n" +"csm_restriction_noderange esetén)\n" +"READ_PLAYERINFO: 32 (letiltja a get_player_names hívásokat kliensoldalon)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "A hegyvonulatok kiterjedésének zaja" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Hegygerinc zaj" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Víz alatti hegygerinc zaj" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Hegyvonulatok méretének zaja" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Jobb gomb" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Folyómeder mélysége" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Folyómeder szélessége" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Folyó mélység" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Folyó zaj" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Folyó méret" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Folyóvölgy szélessége" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Visszavonási pontok rögzítése" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Dombok méret zaja" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Dombok kiterjedés zaja" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Kerek kistérkép" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Biztonságos ásás és lehelyezés" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Homokos partok képződnek, ha az np_beach meghaladja ezt az értéket." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "A kliens által fogadott térkép mentése lemezre." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Ablakméret automatikus mentése amikor módosítva van." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "A szerverről fogadott térkép mentése" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"A felhasználói felület méretezése egy meghatározott értékkel.\n" +"A legközelebbi-szomszéd-élsimítás szűrőt használja a GUI méretezésére.\n" +"Ez elsimít néhány durva élt, és elhajlítja a pixeleket a méret " +"csökkentésekor,\n" +"de ennek az ára, hogy elhomályosít néhány szélső pixelt, ha a képek nem\n" +"egész számok alapján vannak méretezve." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Képernyő:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Képernyő magasság" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Képernyő szélesség" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Képernyőkép mappa" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Képernyőkép formátum" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Képernyőkép minőség" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Képernyőkép minőség. Csak a JPEG formátumnál használatos.\n" +"1 jelenti a legrosszabb minőséget; 100 jelenti a legjobb minőséget.\n" +"Használd a 0-t az alapértelmezett minőséghez." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Képernyőkép" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Folyómeder zaj" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"A második a négy 2D zajból, amelyek együttesen meghatározzák a dombságok/" +"hegységek magasságát." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" +"A második a két 3D zajból, amelyek együttesen meghatározzák az alagutakat." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Lásd: http://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Kijelölő doboz keret színe (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Kijelölő doboz színe" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Kijelölő doboz szélessége" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"18 fraktál választható, 9 formulából.\n" +"1 = 4D \"Gömbölyded\" Mandelbrot-halmaz.\n" +"2 = 4D \"Gömbölyded\" Julia-halmaz.\n" +"3 = 4D \"Négyszögletes\" Mandelbrot-halmaz.\n" +"4 = 4D \"Négyszögletes\" Julia-halmaz.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot-halmaz.\n" +"6 = 4D \"Mandy Cousin\" Julia-halmaz.\n" +"7 = 4D \"Variáció\" Mandelbrot-halmaz.\n" +"8 = 4D \"Variáció\" Julia-halmaz.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot-halmaz.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia-halmaz.\n" +"11 = 3D \"Karácsonyfa\" Mandelbrot-halmaz.\n" +"12 = 3D \"Karácsonyfa\" Julia-halmaz.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot-halmaz.\n" +"14 = 3D \"Mandelbulb\" Julia-halmaz.\n" +"15 = 3D \"Koszinusz Mandelbulb\" Mandelbrot-halmaz.\n" +"16 = 3D \"Koszinusz Mandelbulb\" Julia-halmaz.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot-halmaz.\n" +"18 = 4D \"Mandelbulb\" Julia-halmaz." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Szerver URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Szerver név" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Szerver leírása" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "Szerver URL" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Szerver címe" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Szerver leírása" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Szerver név" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Szerver portja" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Takarásban lévő térképblokkok szerveroldali kiválogatása" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Szerver portja" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "Szerverlista URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "Szerverlista URL" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Szerverlista fájl" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Nyelv beállítása. Hagyd üresen a rendszer nyelvének használatához.\n" +"A változtatás után a játék újraindítása szükséges." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "A csevegés maximális szöveghossza amelyet a kliensek küldhetnek." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Az árnyékok kivehetőségét szabályozza.\n" +"Kisebb érték világosabb, magasabb érték sötétebb árnyékokat jelent." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Az árnyékok lágy szélének kiterjedését szabályozza.\n" +"Kisebb érték élesebb, nagyobb érték lágyabb árnyékokat jelent.\n" +"Minimális érték: 1,0; maximális érték: 10,0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"A Nap/Hold pályájának fokokban mért döntési szögét szabályozza.\n" +"A 0 érték azt jelenti, hogy nincs döntés / függőleges a pályájuk.\n" +"Minimális érték: 0,0; maximális érték: 60,0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Állítsa igazra az árnyéktérképezés (Shadow Mapping) engedélyezéséhez.\n" +"Az árnyalók engedélyezése szükséges hozzá." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"A \"true\" beállítás engedélyezi a levelek hullámzását.\n" +"Az árnyalók engedélyezése szükséges hozzá." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"A \"true\" beállítás engedélyezi a víz hullámzását.\n" +"Az árnyalók engedélyezése szükséges hozzá." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"A \"true\" beállítás engedélyezi a növények hullámzását.\n" +"Az árnyalók engedélyezése szükséges hozzá." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Az árnyék textúrájának minőségét 32 bitesre állítja.\n" +"Ha hamis, 16 bites textúrát fog használni.\n" +"Ez sokkal több grafikai hibát okoz az árnyékon." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Árnyaló útvonala" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Az árnyalók fejlett vizuális effekteket tesznek lehetővé és növelhetik a " +"teljesítményt\n" +"néhány videókártya esetében.\n" +"Csak OpenGL-el működnek." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Árnyék szűrő minőség" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "Az árnyéktérkép maximális renderelési távolsága kockákban" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "32 bites árnyéktérkép textúra" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Árnyéktérkép textúra méret" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "Betűtípus árnyékának eltolása. Ha 0, akkor nem lesz árnyék rajzolva." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "Árnyék kivehetősége" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" +"A kistérkép alakja. Engedélyezve (enabled) = kerek, letiltva (disabled) = " +"négyzet." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Hibakereső információ megjelenítése" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Entitások kijelölő dobozának megjelenítése" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Entitás hitboxok megjelenítése.\n" +"A változtatás után a játék újraindítása szükséges." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Névcédulák háttere alapértelmezésben látszik" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Leállítási üzenet" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"A mapgen által generált térképdarabka mérete térképblokkokban (16 kocka) " +"mérve.\n" +"FIGYELEM!: Nincs értelme és bizonyos veszélyekkel is jár ennek az értéknek\n" +"5 fölés emelése.\n" +"Ha csökkentjük ezt az értéket, gyakrabban fordulnak elő barlangok és " +"tömlöcök.\n" +"Változtasd meg, ha valami különleges okból kell, de ajánlott\n" +"változatlanul hagyni." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"A poligonhálót generáló MapBlock cache mérete. Növelése megnöveli a\n" +"cache kiszolgálási teljesítményét, ezáltal csökken a fő szálból másolt " +"adatok\n" +"mennyisége, és ezáltal csökken a szaggatás." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Égitestek pályájának döntése" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "W szelet" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "A lejtés és a kitöltés együtt módosítja a magasságot." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Kis barlangok maximális száma" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Kis barlangok minimális száma" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" +"A biomok közötti átmeneti határra vonatkozó kisléptékű páratartalom-" +"ingadozás." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" +"A biomok közötti átmeneti határra vonatkozó kisléptékű hőmérséklet-ingadozás." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Lágy megvilágítás" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Kamera mozgásának lágyítása körbenézéskor. Nézet- vagy egérstabilizálásnak " +"is hívják.\n" +"Hasznos videók felvételénél." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "A kameraforgást lágyítja operatőr módban. 0 a letiltáshoz." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Kameraforgás lágyítása. 0 = letiltás." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Lopakodás gomb" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Lopakodás sebessége" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Lopakodás sebessége kocka/másodpercben." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Lágy árnyék sugara" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Hang" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Meghatározza, mely URL-ről töltse le a kliens a médiatartalmat az UDP " +"helyett.\n" +"$filename -nek elérhetőnek kell lennie a $remote_media$filename helyről " +"cURL\n" +"használatával (nyilván, a remote_media elérési útnak perjelre kell " +"végződni).\n" +"A nem elérhető fájlokat a normál módon fogja letölteni." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"A kockák, tárgyak és eszközök alapértelmezett kötegméretét szabályozza.\n" +"Megjegyzendő, hogy a modok vagy játékok kifejezetten meghatározhatják a " +"kötegek méretét bizonyos vagy az összes tárgy esetén." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Az árnyéktérkép firssítését széthúzza a megadott számú képkockára.\n" +"Magasabb érték esetén az árnyékok késhetnek, alacsabb érékek\n" +"viszont több erőforrást igényelnek.\n" +"Minimális érték: 1; maximális érték: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"A fénygörbe kiemelésének hatósugara.\n" +"A kiemelendő tartomány szélességét szabályozza.\n" +"A fénygörbe kiemelés Gauss-görbéjének szórása." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Statikus újraéledési pont" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Meredekség zaj" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Lépcsős hegyek méretének zajossága" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Lépcsős hegy kiterjedésének zaja" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "3D mód parallax hatásának erőssége." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"A fénygörbe kiemelésének erőssége.\n" +"A 3 'boost' parameter a fénygörbe egy tartományát\n" +"határozza meg, amelyeken erősebbek a fények." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Szigorú protokollellenőrzés" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Színkódok kinyerése" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Az egybefüggő lebegő föld rétegre opcionálisan helyezhető vízfelület " +"szintje.\n" +"Alapértelmezésben a víz nem engedélyezett és csak akkor helyezi le, ha ez " +"az\n" +"érték nagyobb, mint 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (a " +"vékonyítás\n" +"felső részének kezdete).\n" +"***FIGYELEM! VESZÉLYES LEHET A VILÁGOKRA ÉS A SZERVERTELJESÍTMÉNYRE***:\n" +"Ha endgedélyezve van a vízlehelyezés, úgy kell konfigurálni a lebegő " +"földeket és\n" +"tesztelni kell, hogy valóban egybefüggő réteget alkosson, az " +"'mgv7_floatland_density'\n" +"értékének 2,0-nak (vagy az 'mgv7_np_floatland'-től függően más szükséges " +"értéknek)\n" +"kell lenni, hogy elkerülhető legyen a szervert leterhelő extrém vízfolyás és " +"az alatta lévő\n" +"földfelszín elárasztása." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "Szinkron SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Hőmérséklet-változékonyság a biomokban." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Beállítások" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Terep alternatív zaj" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Terep alapzaj" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Terep magasság" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Terep legmagasabb zaj" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Terepzaj" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"A dombok terep zajküszöbe.\n" +"A világ dombokkal fedett területének arányát szabályozza.\n" +"Állítsd 0,0-hoz közelebb, hogy az arány növekedjen." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"A tavak terep zajküszöbe.\n" +"A világ tavakkal fedett területének arányát szabályozza.\n" +"Állítsd 0,0-hoz közelebb, hogy az arány növekedjen." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Terep folytonossági zaj" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Textúrák útvonala" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Az árnyéktérkép rendereléséhez használt textúraméret.\n" +"Kettő hatványának kell lennie.\n" +"Nagyobb számok nagyobb árnyékokat hoznak létre, de ez egyben " +"erőforrásigényesebb is." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Egy kocka textúráját lehet a kockához vagy a világhoz igazítani.\n" +"Az első megoldás jobban illik olyan dolgokhoz, mint a gépek, bútorok stb.,\n" +"míg a másodikkal jobban beleillenek a környezetükbe a lépcsők és " +"mikroblokkok.\n" +"Mivel azonban ez a lehetőség még új, és így a régebbi szerverek még nem " +"használják,\n" +"ezzel az opcióval ki lehet kényszeríteni ezt bizonyos kockákra. Meg kell " +"azonban\n" +"jegyezni, hogy ez még KÍSÉRLETI fázisban van és lehet, hogy nem működik " +"helyesen." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "Az URL a tartalomtárhoz" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "A joystick holttere" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"A profilok mentéséhez használt alapértelmezett formátum, amikor\n" +"formátum nélkül kerül meghívásra a `/profiler save [format]` parancs." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "A föld vagy egyéb biomkitöltő kockaréteg mélysége." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"A profilok mentésének relatív elérési útja a világod elérési útjához képest." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "A használni kívánt joystick azonosítója" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"Az érintőképernyős interakció aktiválódásához szükséges távolság pixelekben." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"A hullámzó folyadékok felszínének maximális magassága.\n" +"4,0 = A hullámok magasága két kocka.\n" +"0,0 = A hullámok egyáltalán nem mozognak.\n" +"Az alapértelmezett érték 1,0 (1/2 kocka).\n" +"A hullámzó folyadék engedélyezése szükséges hozzá." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "A hálózati interfész, amelyen a szerver figyel." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Jogosultságok, amiket az új játékosok automatikusan megkapnak.\n" +"A játékban a /privs parancs beírásával láthatod a teljes listát a " +"szervereden." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"A játékosok körüli blokktérfogat sugara, amelyen belül érvényesülnek\n" +"az aktív blokkok dolgai. Térképblokkban (16 kocka) mérve.\n" +"Az aktív blokkokban betöltődnek az objektumok és ABM-ek futnak.\n" +"Ez egyben az a legkisebb sugár is, amelyen belül az aktív objektumokról " +"(mobok) gondoskodik a játék.\n" +"Ezt a beállítást az active_object_send_range_blocks-szal összhangban kell " +"megadni." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"A renderelő háttérprogram.\n" +"Ha ezt megváltoztatod, újraindítás szükséges.\n" +"Megjegyzés: Androidon, hagyd OGLES1-en, ha bizonytalan vagy! Lehet, hogy nem " +"indul az app különben.\n" +"Más platformokon az OpenGL az ajánlott.\n" +"Az árnyalókat az OpenGL (csak asztali rendszeren) és OGLES2 (kísérleti) " +"támogatja" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"A jostick tengelyeinek érzékenysége, amely a játékbeli látómező mozgatását " +"befolyásolja." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"A körülvett, illetve takarásban lévő kockák árnyékolásának erőssége " +"(sötétsége).\n" +"Alacsonyabb érték sötétebb, magasabb érték világosabb. E beállítás érvényes\n" +"értéktartománya 0,25-től 4,0-ig terjed. Ha a tartományon kívüli értéket " +"adunk meg,\n" +"a legközelebbi érvényes értékre lesz állítva." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"A másodpercben megadott idő, ameddig a folyadékok várólistája a számítási\n" +"teljesítmény fölé nőhet, és ezután megpróbálja csökkenteni a méretét " +"azáltal,\n" +"hogy törli a régóta sorbanálló elemeket. A 0 érték letiltja ezt a funkciót." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"Az ABM-ek rendelkezésére álló lépésenkénti végrehajtási időkeret\n" +"(az ABM intervallum törtrésze)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Ennyi másodperc szükséges az esemény megismétléséhez a joystick gombok " +"nyomva tartásakor." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Ennyi másodperc szükséges az ismételt kockalehelyezéshez a lehelyezés gomb " +"nyomva tartásakor." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "A joystick típusa" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"Az a függőleges távolság, amely során a hőmérséklet 20 fokkal csökken, ha az " +"'altitude_chill'\n" +"be van kapcsolva. Ugyanez a távolság, amely során a páratartalom esik 10 " +"egységgel, ha az\n" +"'altitude_dry' be van kapcsolva." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"A harmadik a négy 2D zajból, amelyek együttesen meghatározzák a dombságok/" +"hegységek magasságát." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Annak az ideje, hogy mennyi ideig maradnak meg az eldobott tárgyak.\n" +"-1-re állítás kikapcsolja ezt a funkciót." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "Az új világ létrehozásakor érvényes napszak milliórában (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Idő küldési gyakoriság" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Idő sebessége" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"A kliens rendelkezésére álló időkorlát, hogy eltávolítsa a használaton " +"kívüli térképadatokat a memóriából." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"A lag (késés) csökkentése érdekében a kockainformációk küldése le van " +"lassítva, ha a játékos épít valamit.\n" +"Ez azt határozza meg, hogy mennyire van lelassítva a küldés a kockák " +"lehelyezése, vagy eltávolítása után." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Kamera mód váltó gomb" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Eszköztipp késleltetés" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Érintőképernyő érzékenysége" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Érintőképernyő érzékenysége" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "Teljesítménybeli kompromisszumok" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Fa zaj" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Trilineáris szűrés" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"Arra használható, hogy egyenletesebbé tegye a minitérképet lassabb gépeken." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Megbízható modok" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "A Többjátékos fül alatt megjelenített szerverlista URL-je." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Alulmintavételezés" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Az alulmintavételezés olyan, mintha kisebb képernyőfelbontást használnál, " +"de\n" +"csak a játék világára van hatással, a GUI-t változatlanul hagyja.\n" +"Sokkal jobb teljesítmény érhető el vele annak árán, hogy a kép kevésbé\n" +"részletgazdaggá válik. Magasabb értékek kevésbé részletes képet " +"eredményeznek." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Korlátlan játékosátviteli távolság" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "A használaton kívüli szerveradatok eltávolítása a memóriából" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "A tömlöcök felső Y határa." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "A lebegő földek felső Y határa." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "3D felhők használata lapos helyett." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Felhő animáció használata a főmenü háttereként." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "Anizotróp szűrés használata, ha egy szögből nézzük a textúrákat." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Bilineáris szűrés a textúrák méretezésekor." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Mipmapping használata a textúrák méretezéséhez. Kis mértékben növelheti a\n" +"teljesítményt, különösen nagy felbontású textúracsomagok használatakor.\n" +"Gamma-megőrző zsugorítás nem támogatott." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Többmintás élsimítás (MSAA) használata a blokkélek simításához.\n" +"Ez az algoritmus kisimítja a 3D látómezőt miközben a kép éles marad,\n" +"a textúrák beljsejét azonban nem módosítja\n" +"(ami főleg az átlátszó textúráknál vehető észre).\n" +"A kockák között látható rések jelennek meg, ha az árnyalók nincsenek\n" +"engedélyezve. Ha 0-ra van állítva, az MSAA tiltva van.\n" +"E beállítás megváltoztatása után újraindítás szükséges." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Trilineáris szűrés a textúrák méretezéséhez." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Függőleges szinkron" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Völgyek mélysége" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Völgyek kitöltése" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Völgyek profilja" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Völgyek meredeksége" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "A biom töltőanyag mélységének változékonysága." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "A legnagyobb eltérés a hegyek magasságában (hány kocka)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "A barlangok számának változása." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"A terep függőleges kiterjedésének mozgástere.\n" +"Ha a zaj < -0,55, akkor a terep szinte lapos." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "A biomok felületét képező kockaréteg mélységét variálja." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"A terep töredezettségét variálja.\n" +"Meghatározza a terrain_base és terrain_alt zajok folytonosságának értékét." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "A szirtek meredekségét variálja." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Függőleges mászási sebesség kocka/másodpercben." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Függőleges képernyő szinkronizálás." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Videó driver" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Fejbillegési faktor" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Látótávolság kockában megadva." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Látóterület csökkentése gomb" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Látóterület növelése gomb" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Nagyítás gomb" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Látóterület" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "A virtuális joystick működteti az Aux1 gombot" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Hangerő" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Az összes hang hangereje.\n" +"A hangrendszer engedélyezésére van szükség hozzá." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"A 4D fraktál generált 3D szeletének W koordinátája.\n" +"Meghatározza, hogy a 4D-s alakzat mely 3D-s szeletét kell generálni.\n" +"Megváltoztatja a fraktál alakját.\n" +"Nincs hatása a 3D fraktálokra.\n" +"Nagyjából -2 és 2 közötti az értéktartománya." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Sétálás és repülés sebessége kocka/másodpercben." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Sétálás sebessége" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "Sétálás, repülés és mászás sebessége gyors módban kocka/másodpercben." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Vízszint" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "A világ vízfelszínének szintje." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Hullámzó kockák" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Ringatózó levelek" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Hullámzó folyadékok" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Hullámzó folyadékok hullámmagassága" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Hullámzó folyadékok hullámsebessége" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Hullámzó folyadékok hullámhossza" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Ringatózó növények" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "Internetes hivatkozások színe" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Ha a gui_scaling_filter értéke igaz, minden GUI képet szoftveres\n" +"szűrő fogja kezelni, de néhány kép közvetlenül a harverre\n" +"generálódik (pl. a felszerelésben lévő kockák textúrára renderelése)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Ha a gui_scaling_filter_txr2img be van kapcsolva, ezeket a képeket\n" +"a hardverről a szoftverbe másolja méretezésre. Ha ki van kapcsolva,\n" +"a régi méretezési módszert használja, azoknál a videó drivereknél,\n" +"amelyek nem megfelelően támogatják a textúra hardverről való letöltését." + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"A bilineáris/trilineáris/anizotróp szűrők használatakor, a kis felbontású " +"textúrák\n" +"homályosak lehetnek, ezért automatikusan felskálázza őket legközelebbi\n" +"szomszéd módszerrel, hogy megőrizze az éles pixeleket. Ez a beállítás " +"meghatározza\n" +"a minimális textúraméretet a felnagyított textúrákhoz; magasabb értéknél " +"élesebb,\n" +"de több memóriát igényel. 2 hatványait ajánlott használni. CSAK akkor " +"érvényes ez a\n" +"beállítás, ha a bilineáris/trilineáris/anizotróp szűrés engedélyezett.\n" +"Ez egyben azon kockák alap textúraméreteként is használatos, amelyeknél a " +"világhoz\n" +"igazítva kell méretezni a textúrát." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Látszódjon-e a névcédulák háttere alapértelmezésként.\n" +"A modok ettől még a beállíthatják a hátteret." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"Legyen-e független a kockák textúraanimációinak időzítése az egyes " +"térképblokkokban." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Lássák-e a játékosokat a kliensek mindenféle távolsági korlát nélkül.\n" +"Elavult, használd a player_transfer_distance beállítást ehelyett." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Engedélyezve van-e, hogy a játékosok sebezzék és megöljék egymást." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Kérjük-e a klienseket, hogy újracsatlakozzanak egy (Lua) összeomlás után.\n" +"Állítsd true-ra, ha a szervered automatikus újraindításra van állítva." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "A látható terület vége el legyen-e ködösítve." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Némítsuk-e le a hangokat. Bármikor visszakapcsolhatod a hangokat, kivéve,\n" +"ha a hangrendszer le van tiltva (enable_sound=false).\n" +"A játékon belül a némítás állapotát a némítás gombbal vagy a szünet\n" +"menüben tudod beállítani." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"A hibakereső információ megjelenítése (ugyanaz a hatás, ha F5-öt nyomunk)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"A kezdőablak szélessége. Teljes képernyős módban nem kerül figyelmbe vételre." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "A kijelölésdoboz vonalainak szélessége a kockák körül." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Csak Windows rendszeren: Minetest indítása parancssorral a háttérben.\n" +"Ugyanazokat az információkat tartalmazza, mint a debug.txt fájl " +"(alapértelmezett név)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Világ mappája (minden itt tárolódik ami a világban van).\n" +"Ez nem szükséges, ha a főmenüből indítják." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Világ-kezdőidő" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"A világhoz igazított textúrák több kockára is ki kiterjedhetnek. A szerver\n" +"azonban nem biztos, hogy az általad kívánt módon terjeszti ki azt, " +"különösen,\n" +"ha egyedi tervezésű textúracsomagról van szó; ezzel a beállítással a kliens\n" +"megpróbálja automatikusan meghatározni a méretezést a textúra mérete " +"alapján.\n" +"Lásd még texture_min_size.\n" +"Figyelem: Ez KÍSÉRLETI beállítás!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Világhoz igazított textúrakezelési mód" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Lapos föld Y magassága." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"A hegyek sűrűséggradiensének alapsíkjának Y koordinátája. A hegyek " +"függőleges eltolásához használatos." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Nagy barlangok felső Y határa." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Y-távolság, amelyen az üregek teljes méretre kinyúlnak." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Az az Y irányú távolság, amely során a lebegő földek a maximális sűrűségtől " +"kezdve teljesen elvékonyodnak.\n" +"A vékonyítás ennél az Y határtól való távolságnál kezdőik.\n" +"Egybefüggő lebegő föld rétegek esetén, ez a beállítás szabályozza a dombok/" +"hegyek magasságát.\n" +"Kisebbnek vagy egyenlőnek kell lennie az Y határok közötti távolság felénél." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "A terep átlagos Y szintje." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Az üregek felső Y határa." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Magas terep Y szintje amely szirteket hoz létre." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Alacsony terep és tengerfenék Y szintje." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Tengerfenék Y szintje." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "cURL fájlletöltés időkorlát" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "cURL interaktív időtúllépés" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "cURL párhuzamossági korlát" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Kreatív mód: " + +#~ msgid "- Damage: " +#~ msgstr "- Sérülés: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = parallax occlusion with slope information (gyorsabb).\n" +#~ "1 = relief mapping (lassabb, pontosabb)." + +#~ msgid "Address / Port" +#~ msgstr "Cím / Port" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Gamma kódolás beállítása a fényhez. Alacsonyabb számok - nagyobb " +#~ "fényerő.\n" +#~ "Ez a beállítás csak a kliensre érvényes, a szerver nem veszi figyelembe." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Biztosan visszaállítod az egyjátékos világod?" + +#~ msgid "Back" +#~ msgstr "Vissza" + +#~ msgid "Basic" +#~ msgstr "Alap" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bit/pixel (vagyis színmélység) teljes képernyős módban." + +#~ msgid "Bump Mapping" +#~ msgstr "Bump mapping" + +#~ msgid "Bumpmapping" +#~ msgstr "Bumpmappolás" + +#, fuzzy +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Megváltoztatja a főmenü felhasználói felületét:\n" +#~ "- Teljes: Több egyjátékos világ, játékválasztás, textúracsomag-választó " +#~ "stb.\n" +#~ "- Egyszerű: Egy egyjátékos világ, nincs játék- vagy textúracsomag-" +#~ "választó.\n" +#~ "Szükséges lehet a kisebb képernyőkhöz." + +#~ msgid "Config mods" +#~ msgstr "Modok beállítása" + +#~ msgid "Configure" +#~ msgstr "Beállítás" + +#~ msgid "Connect" +#~ msgstr "Kapcsolódás" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Folyadékban a süllyedési sebességet szabályozza." + +#, fuzzy +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "A lebegő szigetek hegységeinek sűrűségét szabályozza.\n" +#~ "Az \"np_mountain\" zaj értékéhez hozzáadott eltolás." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "A járatok szélességét határozza meg, alacsonyabb érték szélesebb " +#~ "járatokat hoz létre." + +#~ msgid "Credits" +#~ msgstr "Köszönetnyilvánítás" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Célkereszt színe (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Sérülés engedélyezve" + +#~ msgid "Darkness sharpness" +#~ msgstr "a sötétség élessége" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "A cURL alapértelmezett időkorlátja ezredmásodpercekben.\n" +#~ "Csak akkor van hatása, ha a program cURL-lel lett lefordítva." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "A lebegő szigetek sima területeit határozza meg.\n" +#~ "Lapos szigetek ott fordulnak elő, ahol a zaj értéke pozitív." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "A textúrák mintavételezési lépésközét adja meg.\n" +#~ "Nagyobb érték simább normal map-et eredményez." + +#~ msgid "Del. Favorite" +#~ msgstr "Kedvenc törlése" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Játék (mint a minetest_game) letöltése a minetest.net címről" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Letöltés a minetest.net címről" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "$1 letöltése és telepítése, kérlek várj…" + +#~ msgid "Enable VBO" +#~ msgstr "VBO engedélyez" + +#~ msgid "Enable register confirmation" +#~ msgstr "Regisztráció megerősítés engedélyezése" + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "filmes tónus effektek bekapcsolása" + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Parallax occlusion mapping bekapcsolása.\n" +#~ "A shaderek engedélyezve kell hogy legyenek." + +#~ msgid "Enter " +#~ msgstr "Belépés " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Kísérleti opció, látható rések jelenhetnek meg a blokkok között\n" +#~ "ha nagyobbra van állítva, mint 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS a szünet menüben" + +#~ msgid "Fallback font shadow" +#~ msgstr "Tartalék betűtípus árnyéka" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Tartalék betűtípus árnyék átlátszósága" + +#~ msgid "Fallback font size" +#~ msgstr "Tartalék betűtípus mérete" + +#~ msgid "Filtering" +#~ msgstr "Szűrés" + +#, fuzzy +#~ msgid "Floatland base height noise" +#~ msgstr "A lebegő hegyek alapmagassága" + +#, fuzzy +#~ msgid "Floatland mountain height" +#~ msgstr "Lebegő hegyek magassága" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Betűtípus árnyék alfa (átlátszatlanság, 0 és 255 között)." + +#~ msgid "FreeType fonts" +#~ msgstr "FreeType betűtípusok" + +#~ msgid "Full screen BPP" +#~ msgstr "Teljes képernyő BPP" + +#~ msgid "Game" +#~ msgstr "Játék" + +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Normál felületek generálása" + +#~ msgid "Generate normalmaps" +#~ msgstr "Normálfelületek generálása" + +#~ msgid "HUD scale factor" +#~ msgstr "Vezérlőelemek mérete" + +#~ msgid "High-precision FPU" +#~ msgstr "Nagy pontosságú FPU" + +#~ msgid "IPv6 support." +#~ msgstr "IPv6 támogatás." + +#~ msgid "In-Game" +#~ msgstr "Játékon belül" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Fájl telepítése: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Behangolás" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Billentyűzetkiosztás. (Ha ez a menü összeomlik, távolíts el néhány dolgot " +#~ "a minetest.conf-ból)" + +#, fuzzy +#~ msgid "Lava depth" +#~ msgstr "Nagy barlang mélység" + +#, fuzzy +#~ msgid "Lightness sharpness" +#~ msgstr "Fényélesség" + +#~ msgid "Main" +#~ msgstr "Fő" + +#~ msgid "Main menu style" +#~ msgstr "Főmenü stílusa" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "Lehetővé teszi, hogy a DirectX működjön a LuaJIT-tel. Tiltsd le, ha " +#~ "problémákat okoz." + +#~ msgid "Menus" +#~ msgstr "Menük" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Kistérkép radar módban x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Kistérkép radar módban x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Kistérkép terület módban x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Kistérkép terület módban x4" + +#~ msgid "Name / Password" +#~ msgstr "Név / Jelszó" + +#~ msgid "Name/Password" +#~ msgstr "Név/jelszó" + +#~ msgid "No" +#~ msgstr "Nem" + +#~ msgid "Ok" +#~ msgstr "Ok" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallax Occlusion ( domború textúra )" + +#~ msgid "Parallax occlusion" +#~ msgstr "Parallax Occlusion effekt" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Parallax Occlusion módja" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Parallax Occlusion mértéke" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "A TrueType betűtípus (ttf) vagy bitmap útvonala." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Képernyőmentések mappája." + +#~ msgid "Player name" +#~ msgstr "Játékos neve" + +#~ msgid "Profiling" +#~ msgstr "Pfolilozás" + +#~ msgid "PvP enabled" +#~ msgstr "PvP engedélyezve" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Egyjátékos világ visszaállítása" + +#~ msgid "Select Package File:" +#~ msgstr "csomag fájl kiválasztása:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Szerver / Egyjátékos" + +#, fuzzy +#~ msgid "Shadow limit" +#~ msgstr "Térképblokk korlát" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Tartalék betűtípus árnyékának eltolása. Ha 0, akkor nem lesz árnyék " +#~ "rajzolva." + +#~ msgid "Special" +#~ msgstr "Különleges" + +#~ msgid "Special key" +#~ msgstr "Különleges gomb" + +#~ msgid "Start Singleplayer" +#~ msgstr "Egyjátékos mód indítása" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Generált normálfelületek erőssége." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Ezt a betűtípust bizonyos nyelvek használják." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Az árnyalók engedélyezéséhez OpenGL driver használata szükséges." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Váltás „mozi” módba" + +#~ msgid "View" +#~ msgstr "Megtekintés" + +#~ msgid "Waving Water" +#~ msgstr "Hullámzó víz" + +#~ msgid "Waving water" +#~ msgstr "Hullámzó víz" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Használhatók-e FreeType betűtípusok. Szükséges a beépített FreeType " +#~ "támogatás.\n" +#~ "Ha ki van kapcsolva, bittérképes és XML vektoros betűtípusok lesznek " +#~ "használva helyette." + +#~ msgid "Yes" +#~ msgstr "Igen" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Most először csatlakozol erre a szerverre a \"%s\" névvel.\n" +#~ "Ha folytatod, akkor a hitelesítő adataiddal egy új fiók jön létre a " +#~ "szerveren.\n" +#~ "Kérlek írd be újra a jelszavad, majd kattints a \"Regisztráció és " +#~ "Bejelentkezés\"-re, hogy megerősítsd a fióklétrehozást, vagy kattints a " +#~ "\"Mégse\" gombra a megszakításhoz." + +#~ msgid "You died." +#~ msgstr "Meghaltál." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/id/minetest.po b/po/id/minetest.po new file mode 100644 index 0000000..d3a32b8 --- /dev/null +++ b/po/id/minetest.po @@ -0,0 +1,8293 @@ +msgid "" +msgstr "" +"Project-Id-Version: Indonesian (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-02-05 02:53+0000\n" +"Last-Translator: Linerly <linerly@protonmail.com>\n" +"Language-Team: Indonesian <https://hosted.weblate.org/projects/minetest/" +"minetest/id/>\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.11-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Bersihkan antrean obrolan keluar" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Perintah kosong." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Kembali ke menu utama" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Perintah tidak sah " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Perintah yang dikeluarkan: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Daftar pemain daring" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Pemain daring: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Antran obrolan keluar sudah dibersihkan." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Perintah ini dinonaktifkan oleh server." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Bangkit kembali" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Anda mati" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Perintah yang ada:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Perintah yang ada: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Perintah tidak tersedia: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Dapatkan bantuan untuk perintah-perintah" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Pakai '.help <cmd>' untuk mendapatkan informasi lanjut atau '.help all' " +"untuk menampilkan semuanya." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[semua | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Oke" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<tiada yang tersedia>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Suatu galat terjadi pada suatu skrip Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Sebuah galat terjadi:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menu utama" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Sambung ulang" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Server ini meminta untuk menyambung ulang:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Pilih Mod" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Versi protokol tidak sesuai. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Server mengharuskan protokol versi $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Server mendukung protokol antara versi $1 dan versi $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Kami hanya mendukung protokol versi $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Kami mendukung protokol antara versi $1 dan versi $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Batal" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Dependensi:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Matikan semua" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Matikan paket mod" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Nyalakan semua" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Nyalakan paket mod" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Gagal menyalakan mod \"$1\" karena terdapat karakter terlarang. Hanya " +"karakter [a-z0-9_] yang dibolehkan." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Cari Mod Lainnya" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Tiada dependensi (opsional)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Tiada keterangan permainan yang tersedia." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Tiada dependensi wajib" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Tiada keterangan paket mod yang tersedia." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Tiada dependensi opsional" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Dependensi opsional:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Simpan" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Dunia:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "dinyalakan" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" telah ada. Apakah Anda mau menimpanya?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Dependensi $1 dan $2 akan dipasang." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 oleh $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 sedang diunduh,\n" +"$2 dalam antrean" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 mengunduh..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 membutuhkan dependensi yang tidak bisa ditemukan." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 akan dipasang dan $2 dependensi akan dilewati." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Semua paket" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Telah terpasang" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Kembali ke menu utama" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Permainan Dasar:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB tidak tersedia ketika Minetest tidak dikompilasi dengan cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Mengunduh..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Gagal mengunduh $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Permainan" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Pasang" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Pasang $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Pasang dependensi yang belum ada" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Pemasangan: Tipe berkas tidak didukung atau arsip rusak" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mod" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Tiada paket yang dapat diambil" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Tiada hasil" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Tiada pembaruan" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Tidak ditemukan" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Timpa" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Harap pastikan bahwa permainan dasar telah sesuai." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Diantrekan" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Paket tekstur" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Copot" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Perbarui" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Perbarui Semua [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Lihat informasi lebih lanjut di peramban web" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Dunia yang bernama \"$1\" telah ada" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Medan tambahan" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Dingin di ketinggian" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Kering di ketinggian" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Pemaduan bioma" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Bioma" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Gua besar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Gua" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Buat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekorasi" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Peringatan: Development Test ditujukan untuk para pengembang." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Dungeon" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Medan datar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Tanah mengambang di langit" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Floatland (tahap percobaan)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Buat medan nonfraktal: Samudra dan bawah tanah" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Bukit" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Sungai lembap" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Tambah kelembapan di sekitar sungai" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Pasang $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Danau" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Kelembapan rendah dan suhu tinggi membuat sungai dangkal atau kering" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Pembuat peta" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Flag pembuat peta" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Flag khusus pembuat peta" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Pegunungan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Aliran tanah" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Jaringan terowongan dan gua" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Tiada permainan yang dipilih" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Mengurangi suhu di ketinggian" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Mengurangi kelembapan di ketinggian" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Sungai" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Sungai setinggi permukaan laut" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Seed" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Pergantian halus antarbioma" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Struktur muncul pada permukaan (tidak berdampak pada pohon dan rumput hutan " +"rimba yang dibuat oleh v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Struktur muncul pada permukaan, biasanya pohon dan tanaman" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Iklim Sedang, Gurun" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Iklim Sedang, Gurun, Hutan Rimba" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Iklim Sedang, Gurun, Hutan Rimba, Tundra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erosi permukaan medan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Pohon dan rumput hutan rimba" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Variasi kedalaman sungai" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Gua sangat besar di kedalaman bawah tanah" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nama dunia" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Anda tidak punya permainan yang terpasang." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Anda yakin ingin menghapus \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Hapus" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: gagal menghapus \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: jalur tidak sah \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Hapus dunia \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Konfirmasi kata sandi" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Nama pembuat peta" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nama" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Kata sandi" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Kata sandi tidak cocok!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Daftar dan Gabung" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Setuju" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Ganti nama paket mod:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Paket mod ini memiliki nama tersurat yang diberikan dalam modpack.conf yang " +"akan menimpa penggantian nama yang ada." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Tiada keterangan pengaturan yang diberikan)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Noise 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Halaman pengaturan" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Jelajahi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Konten" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Konten" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Dimatikan" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Sunting" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Dinyalakan" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lakuna (celah)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktaf" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Pergeseran" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Kegigihan" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Mohon masukkan sebuah bilangan bulat yang sah." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Mohon masukkan sebuah bilangan yang sah." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Atur ke bawaan" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Skala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Cari" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Pilih direktori" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Pilih berkas" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Tampilkan nama teknis" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Nilai tidak boleh lebih kecil dari $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Nilai tidak boleh lebih besar dari $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Persebaran X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Persebaran Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Persebaran Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "nilai mutlak" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "bawaan" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "kehalusan (eased)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Dinyalakan)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mod" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Gagal memasang $1 ke $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Pemasangan mod: Tidak dapat mencari nama yang sebenarnya dari: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Pemasangan mod: Tidak dapat mencari nama folder yang sesuai untuk paket mod " +"$1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Tidak dapat mencari mod atau paket mod yang sah" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Gagal memasang $1 sebagai paket tekstur" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Gagal memasang permainan sebagai $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Gagal memasang mod sebagai $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Gagal memasang paket mod sebagai $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Memuat..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Daftar server publik dimatikan" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Coba nyalakan ulang daftar server publik dan periksa sambungan internet Anda." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Tentang" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Penyumbang Aktif" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Penggambar aktif:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Pengembang Inti" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Pilih direktori" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Membuka direktori yang berisi dunia, permainan, mod, dan paket tekstur\n" +"dari pengguna dalam pengelola/penjelajah berkas." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Penyumbang Sebelumnya" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Pengembang Inti Sebelumnya" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Tampilkan info awakutu" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Jelajahi konten daring" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Konten" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Matikan paket tekstur" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informasi:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Paket yang terpasang:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Tidak bergantung pada mod lain." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Tiada keterangan paket tersedia" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Ganti nama" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Copot paket" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Gunakan paket tekstur" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Umumkan Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Alamat Sambungan" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Mode Kreatif" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Nyalakan Kerusakan" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Host Permainan" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Host Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Pasang permainan dari ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Baru" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Tiada dunia yang dibuat atau dipilih!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Mainkan Permainan" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Porta" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Pilih Mod" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Pilih Dunia:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Port Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Mulai Permainan" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Alamat" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Clear" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Mode kreatif" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Kerusakan/PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favorit" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Server Tidak Kompatibel" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Gabung Permainan" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Server Publik" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Segarkan" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Port utk Kendali Jarak Jauh" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Keterangan Server" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Awan 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Semua Pengaturan" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Antialiasing:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Simpan Ukuran Layar" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Filter Bilinear" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Ubah Tombol" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Kaca Tersambung" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Bayangan dinamis" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Bayangan dinamis: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Daun Megah" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Tinggi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Rendah" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Menengah" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Filter Aniso. + Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Tanpa Filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Tanpa Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Sorot Nodus" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Garis Bentuk Nodus" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Tidak Ada" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Daun Opak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Air Opak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partikel" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Layar:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Pengaturan" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shader" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shader (tahap percobaan)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Shader (tidak tersedia)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Daun Sederhana" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Pencahayaan Halus" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Peneksturan:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Pemetaan Nada" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Batas Sentuhan: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Filter Trilinear" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Ultratinggi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Sangat Rendah" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Daun Melambai" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Air Berombak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Tanaman Berayun" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Galat sambungan (terlalu lama?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Sambungan kehabisan waktu." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Selesai!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Menyiapkan nodus" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Menyiapkan nodus..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Memuat tekstur..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Membangun ulang shader..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Galat sambungan (terlalu lama?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Tidak dapat mencari atau memuat permainan: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Spesifikasi permainan tidak sah." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menu Utama" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Tiada dunia yang dipilih dan tiada alamat yang diberikan." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Nama pemain terlalu panjang." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Tolong pilih sebuah nama!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Berkas kata sandi yang diberikan gagal dibuka: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Jalur dunia yang diberikan tidak ada: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Periksa debug.txt untuk detail." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Alamat: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Mode: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Porta: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Publik: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Nama Server: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Sebuah galat serialisasi terjadi:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Akses ditolak. Alasan: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Maju otomatis dimatikan" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Maju otomatis dinyalakan" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Batasan blok disembunyikan" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Batasan blok ditampilkan untuk semua blok" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Batasan blok ditampilkan untuk blok saat ini" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Batasan blok ditampilkan untuk blok sekitar" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Pembaruan kamera dimatikan" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Pembaruan kamera dinyalakan" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "Tidak bisa menampilkan batasan blok (butuh hak 'basic_debug')" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Ganti Kata Sandi" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Mode sinema dimatikan" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Mode sinema dinyalakan" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Klien terputus" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Skrip sisi klien dimatikan" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Menyambung ke server..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Sambungan gagal karena sebab yang tak diketahui" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Lanjutkan" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Kontrol:\n" +"- %s: maju\n" +"- %s: mundur\n" +"- %s: geser kiri\n" +"- %s: geser kanan\n" +"- %s: lompat/panjat\n" +"- %s: gali/pukul\n" +"- %s: taruh/pakai\n" +"- %s: menyelinap/turun\n" +"- %s: jatuhkan barang\n" +"- %s: inventaris\n" +"- Tetikus: belok/lihat\n" +"- Roda tetikus: pilih barang\n" +"- %s: obrolan\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Tidak bisa menyelesaikan alamat: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Membuat klien..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Membuat server..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Info awakutu dan grafik profiler disembunyikan" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Info awakutu ditampilkan" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Info awakutu, grafik profiler, dan rangka kawat disembunyikan" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Kontrol bawaan:\n" +"Tanpa menu yang tampak:\n" +"- ketuk sekali: tekan tombol\n" +"- ketuk ganda: taruh/pakai\n" +"- geser: melihat sekitar\n" +"Menu/inventaris tampak:\n" +"- ketuk ganda (di luar):\n" +" -->tutup\n" +"- sentuh tumpukan, sentuh wadah:\n" +" --> pindah tumpukan\n" +"- sentuh & geser, ketuk jari kedua\n" +" --> taruh barang tunggal ke wadah\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Matikan jarak pandang tak terbatas" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Nyalakan jarak pandang tak terbatas" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Membuat klien..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Menu Utama" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Tutup Aplikasi" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Mode cepat dimatikan" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Mode cepat dinyalakan" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Mode cepat dinyalakan (catatan: tanpa hak \"fast\")" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Mode terbang dimatikan" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Mode terbang dinyalakan" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Mode terbang dinyalakan (catatan: tanpa hak \"fly\")" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Kabut dimatikan" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Kabut dinyalakan" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Informasi permainan:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Permainan dijeda" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Membuat server" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Definisi barang..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Media..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Peta mini sedang dilarang oleh permainan atau mod" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Multipemain" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Mode tembus blok dimatikan" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Mode tembus blok dinyalakan" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Mode tembus blok dinyalakan (catatan: tanpa hak \"noclip\")" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Definisi nodus..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Mati" + +#: src/client/game.cpp +msgid "On" +msgstr "Nyala" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Mode gerak sesuai pandang dimatikan" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Mode gerak sesuai pandang dinyalakan" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Grafik profiler ditampilkan" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Server jarak jauh" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Mencari alamat..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Mematikan..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Pemain tunggal" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Volume Suara" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Suara dibisukan" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Sistem suara dimatikan" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Sistem suara tidak didukung dalam buatan ini" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Suara dibunyikan" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Server ini mungkin menjalankan versi %s yang berbeda." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Tidak bisa menyambung ke %s karena IPv6 dimatikan" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Tidak bisa mendengarkan %s karena IPv6 dimatikan" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Jarak pandang diubah menjadi %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Jarak pandang pada titik maksimum: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Jarak pandang pada titik minimum: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Volume diubah ke %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Rangka kawat ditampilkan" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zum sedang dilarang oleh permainan atau mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "oke" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Obrolan disembunyikan" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Obrolan ditampilkan" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD disembunyikan" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD ditampilkan" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profiler disembunyikan" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profiler ditampilkan (halaman %d dari %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplikasi" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Turun" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Erase OEF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Execute" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Bantuan" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME Accept" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME Convert" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME Escape" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME Mode Change" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME Nonconvert" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Kiri" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Klik Kiri" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Ctrl Kiri" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menu Kiri" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Shift Kiri" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Windows Kiri" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Klik Tengah" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numpad *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numpad +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numpad -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numpad ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numpad /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numpad 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numpad 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numpad 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numpad 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numpad 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numpad 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numpad 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numpad 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numpad 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numpad 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Play" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Print" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Return" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Kanan" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Klik Kanan" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Ctrl Kanan" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menu Kanan" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Shift Kanan" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Windows Kanan" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Select" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Sleep" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Snapshot" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Spasi" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Atas" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Tombol X 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Tombol X 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zum" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Peta mini disembunyikan" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Peta mini mode radar, perbesaran %dx" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Peta mini mode permukaan, perbesaran %dx" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Peta mini mode tekstur" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Gagal membuka laman web" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Membuka laman web" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Lanjut" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = turun" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Maju otomatis" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Lompat otomatis" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Mundur" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Batasan blok" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Ubah kamera" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Obrolan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Perintah" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsol" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Turunkan jangkauan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Turunkan volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Tekan ganda \"lompat\" untuk terbang" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Jatuhkan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Maju" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Naikkan jangkauan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Naikkan volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventaris" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Lompat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Tombol telah terpakai" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Perintah lokal" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Bisukan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Barang selanjutnya" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Barang sebelumnya" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Jarak pandang" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Tangkapan layar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Menyelinap" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Alih HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Alih log obrolan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Gerak cepat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Terbang" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Alih kabut" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Alih peta mini" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Tembus nodus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Gerak sesuai pandang" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "tekan tombol" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Ubah" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Kata sandi baru" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Kata sandi lama" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Kata sandi tidak cocok!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Keluar" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Dibisukan" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Volume Suara: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "id" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Tolong pilih sebuah nama!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Tetapkan posisi joystick virtual.\n" +"Jika dimatikan, joystick virtual akan menengah di posisi sentuhan pertama." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Gunakan joystick virtual untuk mengetuk tombol \"Aux1\".\n" +"Jika dinyalakan, joystick virtual juga akan mengetuk tombol \"Aux1\" saat " +"berada di luar lingkaran utama." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"Pergeseran (X,Y,Z) fraktal dari tengah dunia dalam satuan \"scale\".\n" +"Dapat digunakan untuk memindahkan titik yang diinginkan ke (0, 0)\n" +"untuk membuat titik bangkit atau untuk \"zum masuk\" pada titik yang\n" +"diinginkan dengan menaikkan \"scale\".\n" +"Nilai bawaan telah diatur agar cocok untuk Mandelbrot set dengan\n" +"parameter bawaan, ini mungkin butuh diganti untuk keadaan lain.\n" +"Jangkauan sekitar -2 ke 2. Kalikan dengan \"scale\" untuk pergeseran\n" +"dalam satuan nodus." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"Skala (X,Y,Z) fraktal dalam nodus.\n" +"Ukuran fraktal sebenarnya bisa jadi 2 hingga 3 kali lebih besar.\n" +"Angka-angka ini dapat dibuat sangat besar, fraktal tidak harus\n" +"cukup di dalam dunia.\n" +"Naikkan nilai ini untuk \"zum\" ke dalam detail dari fraktal.\n" +"Nilai bawaannya untuk bentuk pipih vertikal yang cocok\n" +"untuk pulau, atur ketiga angka menjadi sama untuk bentuk mentah." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Noise 2D yang mengatur bentuk/ukuran punggung gunung." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Noise 2D yang mengatur bentuk/ukuran perbukitan." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Noise 2D yang mengatur bentuk/ukuran teras gunung." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "Noise 2D yang mengatur ukuran/kemunculan punggung pegunungan." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "Noise 2D yang mengatur ukuran/kemunculan perbukitan." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "Noise 2D yang mengatur ukuran/kemunculan teras pegunungan." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Noise 2D yang mengatur letak sungai dan kanal." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Awan 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Mode 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Kekuatan mode paralaks 3D" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Noise 3D yang mengatur gua besar." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Noise 3D yang mengatur struktur dan ketinggian gunung.\n" +"Juga mengatur struktur dari medan gunung floatland." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Noise 3D yang membentuk struktur floatland.\n" +"Jika diubah dari bawaan, skala noise (bawaannya 0.7) mungkin butuh\n" +"disesuaikan karena fungsi penirus floatland berfungsi baik ketika\n" +"noise ini bernilai antara -2.0 hingga 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Noise 3D yang mengatur struktur dari dinding ngarai sungai." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Noise 3D yang mengatur medan." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"Noise 3D untuk gunung menggantung, tebing, dll. Biasanya variasi kecil." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "Noise 3D yang mengatur jumlah dungeon per mapchunk." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Dukungan 3D.\n" +"Yang didukung saat ini:\n" +"- none: tidak ada keluaran 3d.\n" +"- anaglyph: 3d berwarna sian/magenta.\n" +"- interlaced: garis ganjil/genap berdasarkan polarisasi layar.\n" +"- topbottom: pisahkan layar atas/bawah.\n" +"- sidebyside: pisahkan layar kiri/kanan.\n" +"- crossview: 3d pandang silang\n" +"- pageflip: 3d dengan quadbuffer.\n" +"Catat bahwa mode interlaced membutuhkan penggunaan shader." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Seed peta terpilih untuk peta baru, kosongkan untuk nilai acak.\n" +"Akan diganti ketika menciptakan dunia baru lewat menu utama." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Sebuah pesan yang akan ditampilkan ke semua klien ketika server gagal." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Sebuah pesan yang akan ditampilkan ke semua klien ketika server dimatikan." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Selang waktu ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Anggaran waktu ABM" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Batas mutlak antrean kemunculan blok" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Percepatan di udara" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Percepatan gravitasi dalam nodus per detik per detik." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Pengubah Blok Aktif" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Selang waktu pengelola blok aktif" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Jangkauan blok aktif" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Batas pengiriman objek aktif" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Alamat tujuan sambungan.\n" +"Biarkan kosong untuk memulai sebuah server lokal.\n" +"Perhatikan bahwa bidang alamat dalam menu utama menimpa pengaturan ini." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Tambahkan partikel saat menggali nodus." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Atur konfigurasi dpi ke layar Anda (selain X11/Android saja) misalnya untuk " +"layar 4K." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Menyesuaikan kepadatan tampilan yang dideteksi, dipakai untuk mengatur skala " +"elemen UI." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Sesuaikan kepadatan lapisan floatland.\n" +"Tambahkan nilai untuk menambah kepadatan. Dapat positif atau negatif.\n" +"Nilai = 0.0: 50% o volume adalah floatland.\n" +"Nilai = 2.0 (dapat lebih tinggi tergantung 'mgv7_np_floatland', selalu uji\n" +"terlebih dahulu) membuat lapisan floatland padat (penuh)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Sisipkan nama barang" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Lanjutan" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Ubah kurva cahaya dengan menerapkan penyesuaian gama.\n" +"Nilai yang lebih tinggi menerangkan tingkatan cahaya rendah\n" +"dan menengah. Nilai \"1.0\" membiarkan kurva cahaya seperti\n" +"asalnya. Ini hanya berpengaruh kepada cahaya siang dan cahaya\n" +"buatan. Ini punya pengaruh kecil kepada cahaya malam alami." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Selalu terbang dan bergerak cepat" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Ambient occlusion gamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Jumlah pesan yang dapat dikirim pemain per 10 detik." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Memperbesar lembah." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Pemfilteran anisotropik" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Umumkan server" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Umumkan ke daftar server ini." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Sisipkan nama barang" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Sisipkan nama barang pada tooltip." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Noise pohon apel" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Kelembaman tangan" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Kelembaman tangan memberikan gerakan tangan\n" +"yang lebih nyata saat kamera bergerak." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Minta untuk menyambung ulang setelah crash" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"Pada jarak ini, server akan melakukan optimasi dengan agresif terhadap\n" +"blok yang dikirim kepada klien.\n" +"Nilai yang kecil dapat meningkatkan kinerja dengan glitch pada tampilan\n" +"(beberapa blok di bawah air dan dalam gua tidak akan digambar,\n" +"terkadang juga di darat).\n" +"Nilai yang lebih besar daripada max_block_send_distance mematikan\n" +"optimasi ini.\n" +"Dalam satuan blok peta (16 nodus)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Tombol maju otomatis" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Lompati otomatis halangan satu nodus." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Secara otomatis melaporkan ke daftar server ini." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Simpan ukuran layar" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Mode penyekalaan otomatis" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Tombol Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Tombol Aux1 untuk memanjat/turun" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tombol mundur" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Ketinggian dasar tanah" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Ketinggian dasar medan." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Hak-hak dasar" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Noise pantai" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Ambang batas noise pantai" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Pemfilteran bilinear" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Alamat sambungan" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Parameter noise suhu dan kelembapan Biome API" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Noise bioma" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Jarak optimasi pengiriman blok" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Jalur fon tebal dan miring" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Jalur fon monospace tebal dan miring" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Jalur fon tebal" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Jalur fon monospace tebal" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Bangun di dalam pemain" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Terpasang bawaan" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Ubah kamera" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Jarak bidang dekat kamera dalam nodus, antara 0 dan 0.5\n" +"Hanya untuk GLES. Kebanyakan pengguna tidak perlu mengganti ini.\n" +"Menaikkan nilai dapat mengurangi cacat pada GPU yang lebih lemah.\n" +"0.1 = Bawaan, 0.25 = Bagus untuk tablet yang lebih lemah." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Penghalusan kamera" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Penghalusan kamera dalam mode sinema" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Tombol beralih pembaruan kamera" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Noise gua" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Noise #1 gua" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Noise #2 gua" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Lebar gua" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Noise gua1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Noise gua2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Batas gua besar" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Noise #1 gua besar" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Kelancipan gua" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Ambang batas gua besar" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Batas atas gua besar" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Pertengahan rentang penguatan kurva cahaya.\n" +"Nilai 0.0 adalah minimum, 1.0 adalah maksimum." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Ambang batas waktu pesan perintah obrolan" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Perintah obrolan" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Ukuran fon obrolan" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Tombol obrolan" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Tingkat log obrolan" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Batas jumlah pesan obrolan" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Format pesan obrolan" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Ambang batas jumlah pesan sebelum ditendang keluar" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Panjang maksimum pesan obrolan" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Tombol beralih obrolan" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Tautan web obrolan" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Besar chunk" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Mode sinema" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tombol mode sinema" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Bersihkan tekstur transparan" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Tautan web yang bisa diklik (klik-tengah atau Ctrl+klik-kiri) dibolehkan " +"dalam konsol obrolan." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Klien" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Klien dan Server" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Mod klien" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Pembatasan mod sisi klien" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Batas jangkauan pencarian nodus sisi klien" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Mod klien" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Kelajuan memanjat" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Jari-jari awan" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Awan" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Awan adalah efek sisi klien." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Awan dalam menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Kabut berwarna" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Bayangan berwarna" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Daftar yang dipisahkan dengan koma dari flag yang akan disembunyikan dalam " +"gudang konten.\n" +"\"nonfree\" dapat digunakan untuk menyembunyikan paket yang tidak tergolong\n" +"\"perangkat lunak bebas gratis\" seperti yang ditetapkan oleh Free Software " +"Foundation.\n" +"Anda juga dapat menentukan sensor konten.\n" +"Flag-flag ini tidak bergantung pada versi Minetest,\n" +"maka lihat daftar lengkap di https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Daftar yang dipisahkan dengan koma dari mod yang dibolehkan untuk\n" +"mengakses HTTP API, membolehkan mereka untuk mengunggah dan mengunduh data " +"ke/dari internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Daftar yang dengan dipisahkan koma dari mod terpercaya yang diperbolehkan\n" +"untuk mengakses fungsi yang tidak aman bahkan ketika mod security aktif " +"(melalui request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Tombol perintah" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Tingkat kompresi saat menyimpan blok peta ke diska.\n" +"-1 - tingkat kompresi bawaan\n" +"0 - kompresi sedikit, tercepat\n" +"9 - kompresi terbaik, terlambat" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Tingkat kompresi saat mengirimkan blok peta kepada klien.\n" +"-1 - tingkat kompresi bawaan\n" +"0 - kompresi sedikit, tercepat\n" +"9 - kompresi terbaik, terlambat" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Sambungkan kaca" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Sambungkan ke server media eksternal" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Sambungkan kaca jika didukung oleh nodus." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Keburaman konsol" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Warna konsol" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Tombol konsol" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Gudang konten daring" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Daftar Hitam Flag ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Jumlah Maks Pengunduhan ContentDB Bersamaan" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "URL ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Maju terus-menerus" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Gerakan maju terus-menerus, diatur oleh tombol maju otomatis.\n" +"Tekan tombol maju otomatis lagu atau gerak mundur untuk mematikannya." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Kontrol" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Mengatur panjang siklus pagi/malam.\n" +"Contoh:\n" +"72 = 20 menit, 360 = 4 menit, 1 = 24 jam, 0 = pagi/malam/lainnya tidak " +"berubah." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Mengatur kecuraman/kedalaman lekukan danau." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Mengatur kecuraman/ketinggian bukit." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Atur lebah terowongan, nilai yang lebih kecil melebarkan terowongan.\n" +"Nilai >= 10.0 mematikan terowongan dan menghindari perhitungan\n" +"noise intensif." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Pesan crash" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Kreatif" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Keburaman crosshair" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Keburaman crosshair (keopakan, dari 0 sampai 255).\n" +"Juga mengatur warna crosshair objek." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Warna crosshair" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Warna crosshair (R,G,B),\n" +"sekaligus mengatur warna crosshair objek" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Kerusakan" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Tombol info awakutu" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Ambang batas ukuran log awakutu" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Tingkat log awakutu" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Tombol turunkan volume" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Langkah server khusus" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Percepatan bawaan" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Permainan bawaan" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Permainan bawaan saat membuat dunia baru.\n" +"Ini akan diganti saat membuat dunia lewat menu utama." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Kata sandi bawaan" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Hak-hak bawaan" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Format laporan bawaan" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Ukuran tumpukan bawaan" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Mengatur kualitas filter bayangan.\n" +"Ini menyimulasikan efek bayangan halus dengan menerapkan PCF atau\n" +"diska Poisson, tetapi menggunakan sumber daya lebih banyak." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Menetapkan daerah tempat pohon punya apel." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Menetapkan daerah dengan pantai berpasir." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Mengatur persebaran medan yang lebih tinggi dan kecuraman tebing." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Mengatur persebaran medan yang lebih tinggi." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Mengatur ukuran penuh gua besar, nilai yang lebih kecil memperbesar gua." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Menetapkan struktur kanal sungai skala besar." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Menetapkan lokasi dan medan dari danau dan bukit pilihan." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Mengatur ketinggian dasar tanah." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Mengatur kedalaman kanal sungai." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Menentukan jarak maksimal perpindahan pemain dalam blok (0 = tak terbatas)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Mengatur lebar kanal sungai." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Mengatur lebar ngarai sungai." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Menetapkan daerah pohon dan kepadatan pohon." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Jeda antarpembaruan mesh pada klien dalam milidetik. Menaikkan nilai ini " +"akan\n" +"memperlambat pembaruan mesh sehingga mengurangi jitter pada klien lambat." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Jeda dalam pengiriman blok setelah membangun" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Jeda menampilkan tooltip dalam milidetik." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Penanganan Lua API usang" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Kedalaman minimal tempat Anda akan menemukan gua raksasa." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Kedalaman minimal tempat Anda akan menemukan gua besar." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Keterangan server yang ditampilkan saat pemain bergabung dan dalam daftar " +"server." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Ambang batas noise gurun" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Gurun muncul saat np_biome melebihi nilai ini.\n" +"Ketika flag \"snowbiomes\" dinyalakan, nilai ini diabaikan." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Putuskan sinkronasi animasi blok" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Dekorasi" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Tombol gali" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Partikel menggali" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Matikan anticurang" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Larang kata sandi kosong" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Faktor Skala Kepadatan Tampilan" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Nama domain dari server yang akan ditampilkan pada daftar server." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Tekan ganda lompat untuk terbang" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Menekan ganda tombol lompat untuk beralih terbang." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Tombol menjatuhkan barang" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Keluarkan informasi awakutu pembuat peta." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Y maksimum dungeon" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Y minimum dungeon" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Noise dungeon" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Nyalakan dukungan IPv6 (untuk kllien dan server).\n" +"Membutuhkan sambungan IPv6." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Gunakan dukungan Lua modding pada klien.\n" +"Dukungan ini masih tahap percobaan dan API dapat berubah." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Menyalakan filter diska Poisson.\n" +"Nilai true berarti memakai diska Poisson untuk \"bayangan halus\". Nilai " +"lain berarti\n" +"memakai filter PCF." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Menyalakan bayangan berwarna.\n" +"Nilai true berarti nodus agak tembus pandang memiliki bayangan berwarna.\n" +"Ini sangat membutuhkan sumber daya besar." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Gunakan jendela konsol" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Nyalakan mode kreatif untuk semua pemain" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Gunakan joystick" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Nyalakan dukungan saluran mod." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Nyalakan pengamanan mod" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Membolehkan pemain terkena kerusakan dan mati." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Gunakan masukan pengguna acak (hanya digunakan untuk pengujian)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Gunakan pencahayaan halus dengan ambient occlusion sederhana.\n" +"Jangan gunakan untuk kecepatan atau untuk tampilan lain." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Nyalakan untuk melarang sambungan dari klien lawas.\n" +"Klien lawas dianggap sesuai jika mereka tidak rusak saat menyambung ke " +"server-\n" +"server baru, tetapi mungkin tidak mendukung semua fitur baru yang diharapkan." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Gunakan server media jarak jauh (jika diberikan oleh server).\n" +"Server jarak jauh menawarkan cara lebih cepat untuk mengunduh media\n" +"(misal: tekstur) saat tersambung ke server." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Nyalakan vertex buffer object.\n" +"Ini dapat meningkatkan kinerja grafika." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Gunakan view bobbing dan nilai dari view bobbing\n" +"Misalkan: 0 untuk tanpa view bobbing; 1.0 untuk normal; 2.0 untuk 2x lipat." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Nyalakan/matikan server IPv6.\n" +"Diabaikan jika bind_address telah diatur.\n" +"Membutuhkan enable_ipv6 untuk dinyalakan." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Nyalakan tone mapping \"Uncharted 2\" dari Hable.\n" +"Menyimulasikan kurva warna film foto dan memperkirakan penampilan\n" +"citra rentang dinamis tinggi (HDR). Kontras tengah sedikit dikuatkan,\n" +"sedangkan sorotan dan bayangan dilemahkan." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Jalankan animasi barang inventaris." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Gunakan tembolok untuk facedir mesh yang diputar." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Gunakan peta mini." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Nyalakan sistem suara.\n" +"Jika dimatikan, semua suara dimatikan dan pengaturan suara dalam permainan\n" +"akan tidak berfungsi.\n" +"Perubahan pengaturan ini membutuhkan mulai ulang." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Mengaktifkan pertukaran yang mengurangi beban CPU atau meningkatkan kinerja " +"rendering\n" +"atas biaya gangguan visual kecil yang tidak memengaruhi pemutaran game." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Profil lembah" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Jarak pencetakan data profiling mesin" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Metode benda (entity)" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Pangkat untuk penirusan floatland. Mengubah perilaku penirusan.\n" +"Nilai = 1.0 membuat penirusan linear seragam.\n" +"Nilai > 1.0 membuat penirusan halus yang cocok untuk pemisahan\n" +"floatland bawaan.\n" +"Nilai < 1.0 (misal 0.25) membuat tingkat permukaan dengan lembah\n" +"yang rata dan cocok untuk lapisan floatland padat (penuh)." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS (bingkai per detik) saat dijeda atau tidak difokuskan" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Noise faktor" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Faktor fall bobbing" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Jalur fon cadangan" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Tombol gerak cepat" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Percepatan mode gerak cepat" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Kelajuan mode gerak cepat" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Gerak cepat" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Gerak cepat (lewat tombol \"Aux1\").\n" +"Membutuhkan hak \"fast\" pada server." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Bidang pandang" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Bidang pandang dalam derajat." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Berkas dalam client/serverlist/ yang berisi server favorit Anda yang\n" +"ditampilkan dalam Tab Multipemain." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Kedalaman isian" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Noise kedalaman isian" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Pemetaan suasana filmis" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Tekstur yang difilter dapat memadukan nilai RGB dengan tetangganya yang\n" +"sepenuhnya transparan, yang biasanya diabaikan oleh pengoptimal PNG,\n" +"terkadang menghasilkan tepi gelap atau terang pada tekstur transparan. \n" +"Terapkan filter ini untuk membersihkannya ketika memuat tekstur. Ini " +"dinyalakan\n" +"otomatis jika mipmap dinyalakan." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Antialiasing:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "Noise 2D pertama dari empat yang mengatur ketinggian bukit/gunung." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Noise 3D pertama dari dua yang mengatur terowongan." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Seed peta tetap" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Joystick virtual tetap" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Kepadatan floatland" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Y maksimum floatland" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Y minimum floatland" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Noise floatland" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Pangkat penirusan floatland" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Jarak penirusan floatland" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Ketinggian permukaan air floatland" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Tombol terbang" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Terbang" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Kabut" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Mulai kabut" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Tombol beralih kabut" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Ukuran fon" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Fon tebal bawaan" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Fon miring bawaan" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Bayangan fon" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Keburaman bayangan fon" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Ukuran fon" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Ukuran fon dapat dibagi dengan" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Ukuran fon bawaan dalam dimana 1 unit = 1 pixel di 96 DPI" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Ukuran fon monospace bawaan dimana 1 unit = 1 pixel di 96 DPI" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Ukuran fon teks obrolan terkini dan prompt obrolan dalam poin (pt).\n" +"Nilai 0 akan memakai ukuran bawaan." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"Untuk fon bergaya pixel yang tidak dapat diskalakan dengan baik, ini " +"memastikan ukuran fon yang digunakan\n" +"dengan fon ini akan selalu dapat dibagi dengan nilai ini, dalam pixel. " +"Misalnya,\n" +"fon pixel setinggi 16 pixel harus diatur ke 16, jadi itu hanya akan " +"berukuran 16, 32, 48, dll.,\n" +"jadi sebuah mod yang meminta ukuran 25 akan mendapatkan 32." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Format pesan obrolan pemain. Berikut daftar kode yang sah:\n" +"@name, @message, @timestamp (opsional)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Format tangkapan layar." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Warna bawaan latar belakang formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Keburaman bawaan latar belakang formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Warna latar belakang layar penuh formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Keburaman latar belakang layar penuh formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Warna bawaan latar belakang formspec (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Keburaman bawaan latar belakang formspec (dari 0 sampai 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Warna latar belakang layar penuh formspec (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "Keburaman latar belakang layar penuh formspec (dari 0 sampai 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Tombol maju" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "Noise 2D keempat dari empat yang mengatur ketinggian bukit/gunung." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Jenis fraktal" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Bagian dari jarak pandang tempat kabut mulai tampak" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Dari seberapa jauh blok dibuat untuk klien, dalam satuan blok peta (16 " +"nodus)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Dari seberapa jauh blok dikirim ke klien, dalam satuan blok peta (16 nodus)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Jarak terjauh objek dapat diketahui klien, dalam blok peta (16 nodus).\n" +"\n" +"Mengatur dengan nilai yang lebih tinggi daripada active_block_range akan\n" +"menyebabkan server menjaga objek aktif hingga jarak ini pada arah pandang\n" +"pemain. (Ini dapat menghindari makhluk yang mendadak hilang dari pandangan.)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Layar penuh" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Mode layar penuh." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Skala GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Filter skala GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Filter txr2img skala GUI" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Permainan" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Callback global" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Atribut pembuatan peta global.\n" +"Dalam pembuat peta v6, flag \"decorations\" mengatur semua hiasan, kecuali\n" +"pohon dan rumput rimba. Dalam pembuat peta lain, flag ini mengatur semua " +"dekorasi." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Kemiringan kurva cahaya di titik maksimum.\n" +"Mengatur kontras tingkatan cahaya tertinggi." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Kemiringan kurva cahaya di titik minimum.\n" +"Mengatur kontras tingkatan cahaya terendah." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravitasi" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Ketinggian tanah" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Noise tanah" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "Mod HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Skala GUI" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Tombol beralih HUD" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Penanganan panggilan Lua API usang:\n" +"- none: jangan catat panggilan usang\n" +"- log: menyerupai dan mencatat asal-usul panggilan usang (bawaan untuk " +"awakutu).\n" +"- error: batalkan penggunaan panggilan usang (disarankan untuk pengembang " +"mod)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Buat profiler lengkapi dirinya sendiri dengan perkakas:\n" +"* Lengkapi fungsi kosong, dengan perkakas.\n" +"Memperkirakan ongkos, yang pelengkapan gunakan (+1 panggilan fungsi).\n" +"* Lengkapi penyampel yang dipakai untuk memperbarui statistik." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Noise paduan panas" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Noise panas" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "Tinggi ukuran jendela mula-mula. Ini diabaikan dalam mode layar penuh." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Noise ketinggian" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Noise pemilihan ketinggian" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Kecuraman bukit" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Ambang batas bukit" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Noise bukit1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Noise bukit2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Noise bukit3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Noise bukit4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Halaman awal server, ditampilkan pada daftar server." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Percepatan mendatar di udara saat lompat atau jatuh\n" +"dalam nodus per detik per detik." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Percepatan mendatar dan vertikal dalam mode gerak\n" +"cepat dalam nodus per detik per detik." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Percepatan mendatar dan vertikal di atas tanah atau saat memanjat\n" +"dalam nodus per detik per detik." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Tombol hotbar selanjutnya" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Tombol hotbar sebelumnya" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Tombol hotbar slot 1" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Tombol hotbar slot 10" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Tombol hotbar slot 11" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Tombol hotbar slot 12" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Tombol hotbar slot 13" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Tombol hotbar slot 14" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Tombol hotbar slot 15" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Tombol hotbar slot 16" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Tombol hotbar slot 17" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Tombol hotbar slot 18" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Tombol hotbar slot 19" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Tombol hotbar slot 2" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Tombol hotbar slot 20" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Tombol hotbar slot 21" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Tombol hotbar slot 22" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Tombol hotbar slot 23" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Tombol hotbar slot 24" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Tombol hotbar slot 25" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Tombol hotbar slot 26" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Tombol hotbar slot 27" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Tombol hotbar slot 28" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Tombol hotbar slot 29" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Tombol hotbar slot 3" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Tombol hotbar slot 30" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Tombol hotbar slot 31" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Tombol hotbar slot 32" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Tombol hotbar slot 4" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Tombol hotbar slot 5" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Tombol hotbar slot 6" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Tombol hotbar slot 7" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Tombol hotbar slot 8" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Tombol hotbar slot 9" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Kedalaman sungai yang dibuat." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Kelajuan gerakan ombak. Lebih tinggi = lebih cepat.\n" +"Jika negatif, ombak akan bergerak mundur.\n" +"Membutuhkan air berombak untuk dinyalakan." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Seberapa lama server akan menunggu sebelum membongkar blok peta yang tidak " +"dipakai.\n" +"Semakin tinggi semakin halus, tetapi menggunakan lebih banyak RAM." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Turunkan ini untuk menaikkan ketahanan cairan terhadap gerakan." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Lebar sungai yang dibuat." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Noise paduan kelembapan" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Noise kelembapan" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Variasi kelembapan untuk bioma." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "Server IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Jika FPS (bingkai per detik) lebih tinggi daripada ini, akan dibatasi\n" +"dengan jeda agar tidak membuang tenaga CPU dengan percuma." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Jika dimatikan, tombol \"Aux1\" digunakan untuk terbang cepat jika mode\n" +"terbang dan cepat dinyalakan." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Jika dinyalakan, server akan melakukan occlusion culling blok peta\n" +"menurut posisi mata pemain. Ini dapat mengurangi jumlah blok yang\n" +"dikirim ke klien sebesar 50-80%. Klien tidak dapat menerima yang tidak\n" +"terlihat sehingga kemampuan mode tembus blok berkurang." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Jika dinyalakan bersama mode terbang, pemain mampu terbang melalui nodus " +"padat.\n" +"Hal ini membutuhkan hak \"noclip\" pada server." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Jika dinyalakan, tombol \"Aux1\" digunakan untuk bergerak turun alih-alih\n" +"tombol \"menyelinap\"." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Gunakan konfirmasi pendaftaran saat menyambung ke server.\n" +"Jika dimatikan, akun baru akan didaftarkan otomatis." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Jika dinyalakan, perilaku akan direkam untuk cadangan.\n" +"Pilihan ini hanya dibaca saat server dimulai." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Jika dinyalakan, jangan gunakan pencegahan curang dalam multipemain." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Jika dinyalakan, data dunia yang tidak sah tidak akan menyebabkan server " +"mati.\n" +"Hanya nyalakan ini jika Anda tahu yang Anda lakukan." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Jika dinyalakan, arah gerak menyesuaikan pandangan pemain saat terbang atau " +"menyelam." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Jika dinyalakan, pemain baru tidak dapat bergabung dengan kata sandi kosong." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Jika dinyalakan, Anda dapat menaruh blok pada posisi (kaki + ketinggian " +"mata)\n" +"tempat Anda berdiri. Ini berguna saat bekerja dengan kotak nodus (nodebox) " +"dalam daerah sempit." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Jika pembatasan CSM untuk jangkauan nodus dinyalakan, panggilan\n" +"get_node dibatasi hingga sejauh ini dari pemain ke nodus." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Jika pelaksanaan perintah obrolan lebih lama daripada ini (dalam detik),\n" +"tambahkan informasi waktu ke pesan perintah obrolan" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Jika ukuran berkas debug.txt melebihi nilai yang diberikan (dalam " +"megabita),\n" +"berkas tersebut akan dipindah ke debug.txt.1 dan berkas debug.txt.1 lama\n" +"akan dihapus jika ada.\n" +"Berkas debug.txt hanya dipindah jika pengaturan ini dinyalakan." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "Jika diatur, pemain akan bangkit (ulang) pada posisi yang diberikan." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Abaikan galat pada dunia" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Keburaman konsol obrolan dalam permainan (keopakan, dari 0 sampai 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Warna latar belakang konsol obrolan dalam permainan (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"Tinggi konsol obrolan dalam permainan, dari 0.1 (10%) sampai 1.0 (100%)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Tombol konsol" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Kelajuan vertikal awal ketika lompat dalam nodus per detik." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Instrumen bawaan.\n" +"Ini biasanya hanya dibutuhkan oleh kontributor inti/bawaan" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "Perkakas perintah obrolan saat pendaftaran." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Melengkapi fungsi panggil balik (callback) global saat didaftarkan.\n" +"(semua yang dimasukkan ke fungsi minetest.register_*())" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Melengkapi fungsi aksi Pengubah Blok Aktif dengan perkakas ketika " +"didaftarkan." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Melengkapi fungsi aksi Pengubah Blok Termuat dengan perkakas ketika " +"didaftarkan." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Melengkapi metode entitas dengan perkakas ketika didaftarkan." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "Jarak waktu penyimpanan perubahan penting dari dunia dalam detik." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Jarak pengiriman waktu ke klien." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animasi barang inventaris" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Tombol inventaris" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Balik tetikus" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Balik pergerakan vertikal tetikus." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Jalur fon miring" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Jalur fon monospace miring" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Umur hidup entitas barang" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Perulangan" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Perulangan fungsi rekursif.\n" +"Menaikkan nilai ini menaikkan detail, tetapi juga menambah\n" +"beban pemrosesan.\n" +"Saat perulangan = 20, beban pembuat peta ini mirip dengan v7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID Joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Jarak penekanan tombol joystick terus-menerus" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "Zona mati joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Kepekaan ruang gerak joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Jenis joystick" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Khusus Julia set.\n" +"Komponen W dari tetapan hiperkompleks.\n" +"Mengubah bentuk fraktal.\n" +"Tidak berlaku pada fraktal 3D.\n" +"Jangkauan sekitar -2 ke 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Khusus Julia set.\n" +"Komponen X dari tetapan hiperkompleks.\n" +"Mengubah bentuk fraktal.\n" +"Jangkauan sekitar -2 ke 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Khusus Julia set.\n" +"Komponen Y dari tetapan hiperkompleks.\n" +"Mengubah bentuk fraktal.\n" +"Jangkauan sekitar -2 ke 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Khusus Julia set.\n" +"Komponen Z dari tetapan hiperkompleks.\n" +"Mengubah bentuk fraktal.\n" +"Jangkauan sekitar -2 ke 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "W Julia" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "X Julia" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Y Julia" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Z Julia" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Tombol lompat" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Kelajuan lompat" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk mengurangi jarak pandang.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk mengurangi volume.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk gali.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk menjatuhkan barang yang sedang dipilih.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk menambah jarak pandang.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk menambah volume.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk lompat.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk bergerak cepat dalam mode cepat.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk bergerak mundur.\n" +"Akan mematikan maju otomatis, saat dinyalakan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk bergerak maju.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk bergerak ke kiri.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk bergerak ke kanan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk membisukan permainan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk membuka jendela obrolan untuk mengetik perintah.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk membuka jendela obrolan untuk mengetik perintah lokal.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk membuka jendela obrolan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk membuka inventaris.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk taruh.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-11.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-12.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-13.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-14.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-15.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-16.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-17.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-18.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-19.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-20.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-21.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-22.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-23.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-24.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-25.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-26.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-27.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-28.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-29.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-30.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-31.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ke-32.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar kedelapan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar kelima.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar pertama.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar keempat.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih barang selanjutnya di hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar kesembilan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih barang sebelumnya di hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar kedua.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ketujuh.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar keenam.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar kesepuluh.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk memilih slot hotbar ketiga.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk menyelinap.\n" +"Juga digunakan untuk turun dan menyelam dalam air jika aux1_descends " +"dimatikan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk mengganti kamera antara orang pertama dan ketiga.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk mengambil tangkapan layar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih maju otomatis.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih mode sinema.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk mengganti tampilan peta mini.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih mode cepat.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih terbang.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih mode tembus nodus.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih mode gerak sesuai pandang.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih pembaruan kamera. Hanya digunakan dalam pengembangan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih tampilan obrolan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih tampilan info awakutu.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih tampilan kabut.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih tampilan HUD.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih tampilan konsol obrolan besar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk menampilkan profiler. Digunakan untuk pengembangan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk beralih menjadi jarak pandang tanpa batas.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tombol untuk zum jika bisa.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "Keluarkan pemain yang mengirim lebih dari X pesan per 10 detik." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Kecuraman danau" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Ambang batas danau" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Bahasa" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Kedalaman gua besar" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Nilai maksimum gua besar" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Nilai minimum gua besar" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Perbandingan cairan dalam gua besar" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Tombol konsol obrolan besar" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Gaya dedaunan" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Gaya daun:\n" +"- Fancy: semua sisi terlihat\n" +"- Simple: hanya sisi terluar jika special_tiles yang didefinisikan " +"digunakan\n" +"- Opaque: matikan transparansi" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Tombol kiri" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Lama detikan server dan selang waktu bagi objek secara umum untuk " +"diperbarui\n" +"ke jaringan." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Panjang ombak.\n" +"Membutuhkan air berombak untuk dinyalakan." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Jarak waktu antarsiklus pelaksanaan Pengubah Blok Aktif (ABM)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Jarak waktu antarsiklus pelaksanaan NodeTimer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Jarak waktu antarsiklus pengelola blok aktif" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Tingkatan log yang ditulis ke debug.txt:\n" +"- <kosong> (tanpa pencatatan)\n" +"- none (pesan tanpa tingkatan)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Penguatan kurva cahaya" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Titik tengah penguatan kurva cahaya" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Persebaran penguatan kurva cahaya" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Gama kurva cahaya" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Titik tinggi gradasi kurva cahaya" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Titik rendah gradasi kurva cahaya" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Pencahayaan Halus" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Batas dari pembuatan peta, dalam nodus, untuk semua 6 arah mulai dari (0, 0, " +"0).\n" +"Hanya potongan peta yang seluruhnya berada dalam batasan yang akan dibuat.\n" +"Nilai disimpan tiap dunia." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Membatasi jumlah permintaan HTTP paralel. Memengaruhi:\n" +"- Pengambilan media jika server menggunakan pengaturan remote_media.\n" +"- Unduhan daftar server dan mengumumkan server.\n" +"- Unduhan oleh menu utama (misal. pengelola mod).\n" +"Hanya berlaku jika dikompilasi dengan cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Keenceran cairan" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Penghalusan keenceran cairan" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Loop cairan paling banyak" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Waktu pembersihan antrean cairan" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Kelajuan tenggelam dalam cairan" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Jarak pembaruan cairan dalam detik." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Detikan pembaruan cairan" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Muat profiler permainan" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Muat profiler permainan untuk mengumpulkan data game profiling.\n" +"Menyediakan perintah /profiler untuk akses ke rangkuman profile.\n" +"Berguna untuk pengembang mod dan operator server." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Pengubah Blok Termuat" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Batas bawah Y dungeon." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Batas bawah Y floatland." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Skrip menu utama" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Buat warna kabut dan langit tergantung pada waktu (fajar/maghrib) dan arah " +"pandangan." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Buat semua cairan buram" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Tingkat Kompresi Peta untuk Penyimpanan Diska" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Tingkat Kompresi Peta untuk Transfer Jaringan" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Direktori peta" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Atribut pembuatan peta khusus untuk pembuat peta Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Atribut pembuatan peta khusus untuk pembuat peta Flat.\n" +"Beberapa danau dan bukit dapat ditambahkan ke dunia datar." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Atribut pembuatan peta khusus untuk pembuat peta Fractal.\n" +"\"terrain\" membolehkan pembuatan medan nonfraktal:\n" +"samudra, pulau, dan bawah tanah." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Atribut khusus pembuat peta Valleys.\n" +"\"altitude_chill\": Mengurangi suhu seiring ketinggian.\n" +"\"humid_rivers\": Meningkatkan kelembapan di sekitar sungai dan danau.\n" +"\"vary_river_depth\": Jika dinyalakan, cuaca kering dan panas menyebabkan\n" +"sungai menjadi lebih dangkal dan terkadang kering.\n" +"\"altitude_dry\": Mengurangi kelembapan seiring ketinggian." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Atribut pembuatan peta khusus untuk pembuat peta v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Atribut pembuatan peta khusus untuk pembuat peta v6.\n" +"Flag \"snowbiomes\" menyalakan sistem 5 bioma yang baru.\n" +"Saat sistem bioma baru dipakai, hutan rimba otomatis dinyalakan dan\n" +"flag \"jungle\" diabaikan." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Atribut pembuatan peta khusus untuk pembuat peta v7.\n" +"\"ridges\": Sungai.\n" +"\"floatlands\": Tanah mengambang di atmosfer.\n" +"\"caverns\": Gua raksasa di kedalaman bawah tanah." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Batas pembuatan peta" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Selang waktu menyimpan peta" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "Bingkai pembaruan peta bayangan" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Batas blok peta" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Jarak waktu pembuatan mesh blok peta" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Ukuran tembolok blok peta dari pembuat mesh blok peta dalam MB" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Batas waktu pembongkaran blok peta" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Pembuat peta Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Flag khusus pembuat peta Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Pembuat peta flat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Flag khusus pembuat peta Flat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Pembuat peta fraktal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Flag khusus pembuat peta Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Pembuat peta v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Flag khusus pembuat peta v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Pembuat peta v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Flag khusus pembuat peta v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Pembuat peta v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Flag khusus pembuat peta v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Pembuat peta Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Flag khusus pembuat peta Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Awakutu pembuat peta" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Nama pembuat peta" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Jarak terjauh pembuatan blok" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Jarak terjauh pengiriman blok" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Cairan paling banyak terproses tiap langkah." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Blok tambahan paling banyak untuk clearobject" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Paket paling banyak tiap perulangan" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "FPS (bingkai per detik) maksimum" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"FPS (bingkai per detik) maksimum saat permainan dijeda atau saat jendela " +"tidak difokuskan." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Jarak maksimum untuk menggambar bayangan." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Jumlah maksimum blok yang dipaksa muat (forceloaded)" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Lebar maksimum hotbar" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "Batas maksimal nilai acak untuk gua besar per mapchunk." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "Batas maksimal nilai acak untuk gua kecil per mapchunk." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Ketahanan cairan maksimum. Mengatur perlambatan ketika memasuki\n" +"cairan dengan kelajuan tinggi." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Jumlah maksimum blok yang dikirim serentak per klien.\n" +"Jumlah maksimum dihitung secara dinamis:\n" +"total_maks = bulat_naik((#klien + pengguna_maks) * per_klien / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "Jumlah maksimum blok yang dapat diantrekan untuk dimuat." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Jumlah maksimum blok yang akan diantrekan untuk dihasilkan.\n" +"Batasan ini diatur per pemain." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Jumlah maksimum blok yang akan diantrekan untuk dimuat dari berkas.\n" +"Batasan ini diatur per pemain." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Jumlah maksimum pengunduhan bersamaan. Pengunduhan yang melebihi batas ini " +"akan\n" +"diantrekan. Nilai ini harus lebih rendah daripada curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Jumlah maksimum blok peta yang dipaksa muat." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Jumlah maksimum blok peta yang disimpan dalam memori klien.\n" +"Atur ke -1 untuk tak terbatas." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Jumlah maksimum paket dikirim tiap langkah mengirim (send step), jika Anda\n" +"memiliki sambungan lambat, cobalah untuk menguranginya, tetapi jangan " +"mengurangi\n" +"di bawah dua kalinya jumlah klien yang ditargetkan." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Jumlah maksimum pemain yang dapat tersambung serentak." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Jumlah maksimum pesan terkini yang ditampilkan" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Jumlah maksimum objek yang disimpan secara statis dalam satu blok." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Jumlah objek maksimum tiap blok" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Proporsi maksimum jendela saat ini yang digunakan untuk hotbar.\n" +"Berguna jika ada sesuatu yang akan ditampilkan di kanan atau kiri hotbar." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Jumlah maksimum blok yang dikirim serentak ke tiap klien" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Ukuran maksimum antrean obrolan keluar" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Ukuran maksimum antrean obrolan keluar.\n" +"0 untuk mematikan pengantrean dan -1 untuk mengatur antrean tanpa batas." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Waktu maksimum saat mengunduh berkas (misal.: mengunduh mod) dalam milidetik." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Waktu maksimum permintaan interaktif (misal ambil daftar server), dalam " +"milidetik." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Jumlah pengguna maksimum" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Tembolok mesh" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Pesan hari ini" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Pesan hari ini yang ditampilkan ke pemain yang tersambung." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Metode yang digunakan untuk menyorot objek yang dipilih." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Tingkat minimal log untuk ditulis ke obrolan." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Peta mini" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Tombol peta mini" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Ketinggian pemindaian peta mini" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Batas minimal nilai acak untuk gua besar per mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Batas minimal nilai acak untuk gua kecil per mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Ukuran tekstur minimum" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mipmapping" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Profiler" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Keamanan" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Saluran mod" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Mengubah ukuran elemen HUD." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Jalur fon monospace" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Ukuran fon monospace" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "Ukuran fon monospace dapat dibagi dengan" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Noise ketinggian gunung" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Noise gunung" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Noise variasi gunung" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Titik acuan gunung" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Kepekaan tetikus" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Pengali kepekaan tetikus." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Noise lumpur" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Pengali untuk fall bobbing.\n" +"Misalkan: 0 untuk tanpa view bobbing; 1.0 untuk normal; 2.0 untuk 2x lipat." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Tombol bisu" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Bisukan suara" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Nama pembuat peta yang digunakan saat membuat dunia baru.\n" +"Pembuatan dunia lewat menu utama akan menimpa ini.\n" +"Pembuat peta yang tidak stabil saat ini:\n" +"- \"floatlands\" pada pembuat peta v7 (dimatikan secara bawaan)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Nama pemain.\n" +"Saat menjalankan server, klien yang tersambung dengan nama ini adalah " +"admin.\n" +"Saat menjalankan dari menu utama, nilai ini ditimpa." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "Nama server, ditampilkan saat pemain bergabung dan pada daftar server." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Bidang dekat" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Porta jaringan untuk didengar (UDP).\n" +"Nilai ini akan diubah saat memulai dari menu utama." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Jaringan" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Pengguna baru butuh memasukkan kata sandi." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Tembus nodus" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Tombol tembus nodus" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Sorot Nodus" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Penyorotan nodus" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Jarak NodeTimer" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Noise" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Jumlah utas kemunculan" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Jumlah utas kemunculan yang dipakai.\n" +"Nilai 0:\n" +"- Pemilihan otomatis. Utas kemunculan akan berjumlah\n" +"- 'jumlah prosesor - 2', dengan batas bawah 1.\n" +"Nilai lain:\n" +"- Menentukan jumlah utas kemunculan, dengan batas bawah 1.\n" +"PERINGATAN: Penambahan jumlah utas kemunculan mempercepat mesin pembuat\n" +"peta, tetapi dapat merusak kinerja permainan dengan mengganggu proses lain,\n" +"terutama dalam pemain tunggal dan/atau saat menjalankan kode Lua dalam\n" +"\"on_generated\". Untuk kebanyakan pengguna, pengaturan yang cocok adalah " +"\"1\"." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Jumlah dari blok tambahan yang dapat dimuat oleh /clearobjects dalam satu " +"waktu.\n" +"Ini adalah pemilihan antara transaksi SQLite dan\n" +"penggunaan memori (4096=100MB, kasarannya)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Cairan opak" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "Keburaman (alfa) bayangan di belakang fon bawaan, antara 0 dan 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Buka menu jeda saat jendela hilang fokus. Tidak menjeda jika formspec " +"sedang \n" +"dibuka." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Penimpaan opsional untuk warna tautan web pada obrolan." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Jalur ke fon cadangan. Harus sebuah font TrueType.\n" +"Fon ini akan digunakan untuk beberapa bahasa atau jika fon bawaan tidak " +"tersedia." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Jalur penyimpanan tangkapan layar. Dapat berupa jalur absolut atau relatif.\n" +"Folder akan dibuat jika belum ada." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Jalur ke direktori shader. Jika tidak diatur, lokasi bawaan akan digunakan." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "Jalur ke direktori tekstur. Semua tekstur akan dicari mulai dari sini." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Jalur ke fon bawaan. Harus sebuah fon TrueType.\n" +"Fon cadangan akan dipakai jika fon tidak dapat dimuat." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Jalur ke fon monospace. Harus sebuah fon TrueType.\n" +"Fon ini dipakai dalam layar konsol dan profiler, misalnya." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Jeda saat jendela hilang fokus" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "Batasan antrean blok yang dimuat dari diska per pemain" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Batasan antrean blok yang dibuat per pemain" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fisika" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Tombol gerak sesuai pandang" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Mode gerak sesuai pandang" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Tombol taruh" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Jeda waktu taruh berulang" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Pemain dapat terbang tanpa terpengaruh gravitasi.\n" +"Hal ini membutuhkan hak \"fly\" pada server." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Jarak pemindahan pemain" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Pemain lawan pemain" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Pemfilteran Poisson" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Porta untuk disambungkan (UDP).\n" +"Catat bahwa kolom porta pada menu utama mengubah pengaturan ini." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Cegah gali dan taruh secara berulang saat menekan tombol tetikus.\n" +"Nyalakan jika Anda merasa tidak sengaja menggali dan menaruh terlalu sering." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Mencegah mod untuk melakukan hal yang tidak aman misalnya menjalankan " +"perintah shell." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Cetak data profiling mesin dalam selang waktu tetap (dalam detik).\n" +"0 = dimatikan. Berguna untuk pengembang." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Hak yang dapat diberikan oleh pemain dengan basic_privs" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Profiler" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Tombol profiler" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Alamat pendengar Prometheus" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Alamat pendengar Prometheus.\n" +"Jika Minetest dikompilasi dengan pilihan ENABLE_PROMETHEUS dinyalakan,\n" +"ini menyalakan pendengar metrik untuk Prometheus pada alamat itu.\n" +"Metrik dapat diambil pada http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Perbandingan gua besar yang punya cairan." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Jari-jari daerah awan dalam jumlah dari 64 nodus awan kotak.\n" +"Nilai lebih dari 26 akan mulai menghasilkan tepian tajam pada sudut awan." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Menaikkan medan untuk membuat lembah di sekitar sungai." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Masukan acak" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Tombol memilih jarak pandang" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Pesan obrolan terkini" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Jalur fon biasa" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Media jarak jauh" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Port utk Kendali Jarak Jauh" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Buang kode warna dari pesan obrolan yang masuk\n" +"Gunakan ini untuk membuat para pemain tidak bisa menggunakan warna pada " +"pesan mereka" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Mengganti menu utama bawaan dengan buatan lain." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Jalur pelaporan" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Batasi akses beberapa fungsi sisi klien pada server\n" +"Gabungkan flag bita berikut untuk membatasi fitur pada sisi klien atau\n" +"atur ke 0 untuk tanpa batasan:\n" +"LOAD_CLIENT_MODS: 1 (matikan pemuatan mod klien)\n" +"CHAT_MESSAGES: 2 (cegah pemanggilan send_chat_message sisi klien)\n" +"READ_ITEMDEFS: 4 (cegah pemanggilan get_item_def sisi klien)\n" +"READ_NODEDEFS: 8 (cegah pemanggilan get_node_def sisi klien)\n" +"LOOKUP_NODES_LIMIT: 16 (batasi pemanggilan get_node\n" +"sisi klien dalam csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (cegah pemanggilan get_player_names sisi klien)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Noise persebaran punggung gunung" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Noise punggung bukit" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Noise punggung bukit bawah air" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Noise ukuran punggung gunung" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Tombol kanan" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Kedalaman kanal sungai" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Lebar kanal sungai" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Kedalaman sungai" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Noise sungai" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Ukuran sungai" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Lebar ngarai sungai" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Perekaman cadangan" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Noise ukuran perbukitan" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Noise persebaran perbukitan" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Peta mini bundar" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Penggalian dan peletakan dengan aman" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Pantai berpasir muncul saat np_beach melebihi nilai ini." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Simpan peta yang diterima klien pada diska." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Simpan otomatis ukuran jendela saat berubah." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Simpan peta yang diterima dari server" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Perbesar/perkecil GUI sesuai pengguna.\n" +"Menggunakan filter nearest-neighbor-anti-alias untuk perbesar/perkecil GUI.\n" +"Ini akan menghaluskan beberapa tepi kasar dan\n" +"mencampurkan piksel-piksel saat diperkecil dengan\n" +"mengaburkan beberapa piksel tepi saat diperkecil dengan skala bukan bilangan " +"bulat." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Layar:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Tinggi layar" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Lebar layar" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Folder tangkapan layar" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Format tangkapan layar" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Kualitas tangkapan layar" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Kualitas tangkapan layar. Hanya digunakan untuk format JPEG.\n" +"1 berarti kualitas terburuk; 100 berarti kualitas terbaik.\n" +"Gunakan 0 untuk kualitas bawaan." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Tangkapan layar" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Noise dasar laut" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "Noise 2D kedua dari empat yang mengatur ketinggian bukit/gunung." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Noise 3D kedua dari dua yang mengatur terowongan." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Lihat https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Warna pinggiran kotak pilihan (merah,hijau,biru) atau (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Warna kotak pilihan" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Lebar kotak pilihan" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Pilih satu dari 18 jenis fraktal.\n" +"1 = Mandelbrot set 4D \"Bulat\".\n" +"2 = Julia set 4D \"Bulat\".\n" +"3 = Mandelbrot set 4D \"Kotak\".\n" +"4 = Julia set 4D \"Kotak\".\n" +"5 = Mandelbrot set 4D \"Mandy Cousin\".\n" +"6 = Julia set 4D \"Mandy Cousin\".\n" +"7 = Mandelbrot set 4D \"Variasi\".\n" +"8 = Julia set 4D \"Variasi\".\n" +"9 = Mandelbrot set 3D \"Mandelbrot/Mandelbar\".\n" +"10 = Julia set 3D \"Mandelbrot/Mandelbar\".\n" +"11 = Mandelbrot set 3D \"Pohon Natal\".\n" +"12 = Julia set 3D \"Pohon Natal\".\n" +"13 = Mandelbrot set 3D \"Mandelbulb\".\n" +"14 = Julia set 3D \"Mandelbulb\".\n" +"15 = Mandelbrot set 3D \"Cosine Mandelbulb\".\n" +"16 = Julia set 3D \"Cosine Mandelbulb\".\n" +"17 = Mandelbrot set 4D \"Mandelbulb\".\n" +"18 = Julia set 4D \"Mandelbulb\"." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Nama server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Keterangan Server" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL server" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Alamat server" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Keterangan server" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Nama server" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Porta server" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Occlusion culling sisi server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Port Server" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL daftar server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "URL daftar server" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Berkas daftar server" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Atur bahasa. Biarkan kosong untuk menggunakan bahasa sistem.\n" +"Dibutuhkan mulai ulang setelah mengganti ini." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "Atur jumlah karakter maksimum per pesan obrolan yang dikirim klien." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Atur kekuatan bayangan.\n" +"Nilai rendah berarti bayangan lebih terang, nilai tinggi berarti lebih gelap." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Atur besar jari-jari bayangan halus.\n" +"Nilai rendah berarti bayangan lebih tajam, nilai tinggi berarti lebih " +"halus.\n" +"Nilai minimum: 1.0; nilai maksimum 10.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Atur kemiringan orbit Matahari/Bulan dalam derajat.\n" +"Nilai 0 berarti tidak miring/orbit tegak.\n" +"Nilai minimum: 0.0; nilai maksimum 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Atur ke true untuk menyalakan Pemetaan Bayangan.\n" +"Membutuhkan penggunaan shader." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Atur ke true untuk menyalakan daun melambai.\n" +"Membutuhkan penggunaan shader." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Atur ke true untuk menyalakan air berombak.\n" +"Membutuhkan penggunaan shader." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Atur ke true untuk menyalakan tanaman berayun.\n" +"Membutuhkan penggunaan shader." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Atur kualitas tekstur bayangan ke 32 bit.\n" +"Nilai false berarti tekstur 16 bit akan dipakai.\n" +"Ini akan menimbulkan lebih banyak artefak pada bayangan." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Jalur shader" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Shader membolehkan efek visual tingkat lanjut dan dapat meningkatkan " +"kinerja\n" +"pada beberapa kartu video.\n" +"Ini hanya bekerja dengan video OpenGL." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Kualitas filter bayangan" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "Jarak maks. peta bayangan (dalam nodus) untuk digambar" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "Tekstur peta bayangan dalam 32 bit" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Ukuran tekstur peta bayangan" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Pergeseran bayangan fon bawaan dalam piksel. Jika 0, bayangan tidak akan " +"digambar." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "Kekuatan bayangan" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Bentuk dari peta mini. Dinyalakan = bundar, dimatikan = persegi." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Tampilkan info awakutu" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Tampilkan kotak pilihan benda" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Tampilkan kotak pilihan entitas\n" +"Dibutuhkan mulai ulang setelah mengganti ini." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Tampilkan latar belakang tanda nama secara bawaan" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Pesan saat server dimatikan" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Ukuran potongan peta yang dibuat oleh pembuat peta, dalam blok peta (16 " +"nodus).\n" +"PERINGATAN! Tidak ada untungnya dan berbahaya jika menaikkan\n" +"nilai ini di atas 5.\n" +"Mengecilkan nilai ini akan meningkatkan kekerapan gua dan dungeon.\n" +"Mengubah nilai ini untuk kegunaan khusus, membiarkannya \n" +"disarankan." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Ukuran dari tembolok blok peta dari pembuat mesh. Menaikkan ini akan\n" +"menambah persentase cache hit, mengurangi data yang disalin dari\n" +"utas utama, sehingga mengurangi jitter." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Kemiringan Orbit Benda Langit" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Irisan w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Kemiringan dan isian bekerja sama mengatur ketinggian." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Nilai maksimum gua kecil" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Nilai minimum gua kecil" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "Variasi kelembapan skala kecil untuk paduan di tepi bioma." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "Variasi suhu skala kecil untuk paduan di tepi bioma." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Pencahayaan halus" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Memperhalus kamera saat melihat sekeliling. Juga disebut penghalusan " +"tetikus.\n" +"Berguna untuk perekaman video." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"Menghaluskan rotasi kamera dalam modus sinema. 0 untuk tidak menggunakannya." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Penghalusan perputaran kamera. 0 untuk tidak menggunakannya." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Tombol menyelinap" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Kelajuan menyelinap" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Kelajuan menyelinap dalam nodus per detik." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Jari-jari bayangan halus" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Suara" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Menentukan URL yang akan klien ambil medianya daripada menggunakan UDP.\n" +"$filename harus dapat diakses dari $remote_media$filename melalui cURL\n" +"(tentunya, remote_media harus diakhiri dengan sebuah garis miring).\n" +"File yang tidak ada akan diambil cara yang biasa." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Mengatur ukuran tumpukan bawaan untuk nodus, barang, dan alat.\n" +"Catat bahwa mod dan permainan dapat mengatur tumpukan untuk sebagian (atau " +"semua) barang." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Menyebarkan pembaruan peta bayangan dalam jumlah bingkai yang diberikan.\n" +"Nilai tinggi bisa membuat bayangan patah-patah, nilai rendah akan butuh\n" +"sumber daya lebih banyak.\n" +"Nilai minimum: 1; nilai maksimum: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Persebaran rentang penguatan kurva cahaya.\n" +"Mengatur lebar rentang yang dikuatkan.\n" +"Simpangan baku dari penguatan kurva cahaya Gauss." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Titk bangkit tetap" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Noise kecuraman" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Noise ukuran teras gunung" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Noise persebaran teras gunung" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Kekuatan mode paralaks 3D." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Besar penguatan kurva cahaya.\n" +"Tiga parameter \"boost\" menentukan rentang kurva\n" +"cahaya yang dikuatkan menurut kecerahannya." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Perketat pemeriksaan protokol" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Buang kode warna" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Tingkat permukaan peletakan air pada lapisan floatland padat.\n" +"Air tidak ditaruh secara bawaan dan akan ditaruh jika nilai ini diatur ke\n" +"atas 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (mulai dari\n" +"penirusan atas).\n" +"***PERINGATAN, POTENSI BAHAYA TERHADAP DUNIA DAN KINERJA SERVER***\n" +"Ketika penaruhan air dinyalakan, floatland wajib diatur dan diuji agar\n" +"berupa lapisan padat dengan mengatur 'mgv7_floatland_density' ke 2.0\n" +"(atau nilai wajib lainnya sesuai 'mgv7_np_floatland') untuk menghindari\n" +"aliran air ekstrem yang membebani server dan menghindari banjir\n" +"bandang di permukaan dunia bawah." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "SQLite sinkron" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Variasi suhu pada bioma." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Pengaturan" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Noise medan alternatif" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Noise dasar medan" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Ketinggian medan" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Noise medan (lebih tinggi)" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Noise medan" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Ambang batas noise medan untuk bukit.\n" +"Atur perbandingan dari daerah dunia yang diselimuti bukit.\n" +"Atur menuju 0.0 untuk perbandingan yang lebih besar." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Ambang batas noise medan untuk danau.\n" +"Atur perbandingan dari daerah dunia yang diselimuti danau.\n" +"Atur menuju 0.0 untuk perbandingan yang lebih besar." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Persistence noise medan" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Jalur tekstur" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Ukuran tekstur tempat peta bayangan digambar.\n" +"Ini harus bernilai perpangkatan dua.\n" +"Nilai yang besar akan menghasilkan bayangan yang bagus, tetapi lebih berat." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Tekstur pada nodus dapat disejajarkan, baik dengan nodus maupun dunia.\n" +"Mode pertama cocok untuk mesin, furnitur, dll., sedangkan mode kedua\n" +"cocok agar tangga dan mikroblok cocok dengan sekitarnya.\n" +"Namun, karena masih baru, ini tidak dipakai pada server lawas, pilihan ini\n" +"bisa memaksakan untuk jenis nodus tertentu. Catat bahwa ini masih dalam\n" +"tahap PERCOBAAN dan dapat tidak berjalan dengan semestinya." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "URL dari gudang konten" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "Zona mati joystick yang digunakan" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Format bawaan pada berkas untuk menyimpan profile,\n" +"saat memanggil `/profiler save [format]` tanpa format." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "Kedalaman tanah atau nodus pengisi bioma lainnya." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"Jalur berkas relatif terhadap jalur dunia Anda tempat profile akan disimpan " +"di dalamnya." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "Identitas dari joystick yang digunakan" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"Jarak dalam piksel yang dibutuhkan untuk memulai interaksi layar sentuh." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"Tinggi maksimum permukaan ombak.\n" +"4.0 = Tinggi ombak dua nodus.\n" +"0.0 = Ombak tidak bergerak sama sekali.\n" +"Bawaannya 1.0 (1/2 nodus).\n" +"Membutuhkan air berombak untuk dinyalakan." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "Antarmuka jaringan yang server dengarkan." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Hak yang didapatkan pengguna baru otomatis.\n" +"Lihat /privs dalam permainan untuk daftar lengkap pada konfigurasi mod dan " +"server Anda." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"Jari-jari volume blok di sekitar pemain yang menjadi blok aktif, dalam\n" +"blok peta (16 nodus).\n" +"Dalam blok aktif, objek dimuat dan ABM berjalan.\n" +"Ini juga jangkauan minimum pengelolaan objek aktif (makhluk).\n" +"Ini harus diatur bersama dengan active_object_range." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"Penggambar untuk Irrlicht.\n" +"Mulai ulang dibutuhkan setelah mengganti ini.\n" +"Catatan: Pada Android, gunakan OGLES1 jika tidak yakin! Apl mungkin gagal\n" +"berjalan untuk pilihan lainnya. Pada platform lain, OpenGL disarankan.\n" +"Shader didukung oleh OpenGL (khusus desktop) dan OGLES2 (tahap percobaan)" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"Kepekaan dari sumbu joystick untuk menggerakkan batas\n" +"tampilan dalam permainan." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"Kekuatan (kegelapan) dari shade ambient occlusion pada nodus.\n" +"Semakin kecil semakin gelap, juga sebaliknya. Jangkauan yang sah\n" +"berkisar dari 0.25 sampai 4.0 inklusif. Jika nilai di luar jangkauan,\n" +"akan diatur ke nilai yang sah terdekat." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Waktu (dalam detik) sehingga antrean cairan dapat bertambah di luar " +"kapasitas\n" +"pemrosesan sampai usaha dilakukan untuk mengurangi ukurannya dengan\n" +"membuang antrean lama. Nilai 0 mematikan fungsi ini." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"Anggaran waktu yang dibolehkan untuk ABM dalam menjalankan\n" +"tiap langkah (dalam pecahan dari jarak ABM)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Waktu dalam detik antarkejadian berulang saat\n" +"menekan terus-menerus kombinasi tombol joystick." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Jeda dalam detik antar-penaruhan berulang saat menekan \n" +"tombol taruh." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Jenis joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"Jarak vertikal bagi suhu untuk turun 20 jika \"altitude_chill\" dinyalakan.\n" +"Juga jarak vertikal bagi kelembapan untuk turun 10 jika \"altitude_dry\"\n" +"dinyalakan." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "Noise 2D ketiga dari empat yang mengatur ketinggian bukit/gunung." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Waktu dalam detik bagi benda (yang dijatuhkan) untuk hidup.\n" +"Atur ke -1 untuk mematikan fitur ini." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "Waktu saat dunia baru dimulai, dalam milijam (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Jarak pengiriman waktu" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Kelajuan waktu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Batas waktu bagi klien untuk menghapus data peta yang tidak digunakan dari " +"memori." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Untuk mengurangi lag, pengiriman blok diperlambat saat pemain sedang " +"membangun.\n" +"Ini menentukan seberapa lama mereka diperlambat setelah menaruh atau " +"mencopot nodus." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Tombol beralih mode kamera" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Jeda tooltip" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Ambang batas layar sentuh" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Ambang batas layar sentuh" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "Pertukaran untuk kinerja" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Noise pepohonan" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Pemfilteran trilinear" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"Berguna untuk membuat peta mini lebih halus pada mesin yang lambat." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Mod yang dipercaya" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL ke daftar server yang tampil pada Tab Multipemain." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Undersampling" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Undersampling seperti menggunakan resolusi layar yang lebih rendah, tetapi\n" +"hanya berlaku untuk dunia permainan saja, antarmuka grafis tetap.\n" +"Seharusnya memberikan dorongan kinerja dengan gambar yang kurang detail.\n" +"Nilai yang lebih tinggi menghasilkan gambar yang kurang detail." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Jarak pemindahan pemain tak terbatas" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Membongkar data server yang tak terpakai" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Batas atas Y dungeon." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Batas atas Y floatland." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Gunakan tampilan awan 3D daripada datar." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Gunakan animasi awan untuk latar belakang menu utama." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" +"Gunakan pemfilteran anisotropik saat melihat tekstur pada sudut tertentu." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Gunakan pemfilteran bilinear saat mengubah ukuran tekstur." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Pakai mipmap untuk penyekalaan tekstur. Bisa sedikit menaikkan\n" +"kinerja, terutama pada saat memakai paket tekstur beresolusi tinggi.\n" +"Pengecilan dengan tepat-gamma tidak didukung." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Pakai antialias multisampel (MSAA) untuk memperhalus tepian blok.\n" +"Algoritme ini memperhalus tampilan 3D sambil menjaga ketajaman gambar,\n" +"tetapi tidak memengaruhi tekstur bagian dalam (yang terlihat khususnya\n" +"dengan tekstur transparan).\n" +"Muncul spasi tampak di antara nodus ketika shader dimatikan.\n" +"Jika diatur 0, MSAA dimatikan.\n" +"Dibutuhkan mulai ulang setelah penggantian pengaturan ini." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Gunakan pemfilteran trilinear saat mengubah ukuran tekstur." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Sinkronisasi Vertikal" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Kedalaman lembah" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Isian lembah" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Profil lembah" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Kemiringan lembah" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Variasi dari kedalaman isian bioma." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Variasi dari ketinggian gunung paling tinggi (dalam nodus)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Variasi dari jumlah gua." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Variasi dari skala vertikal medan.\n" +"Saat noise < -0,55 medan mendekati datar." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Merubah kedalaman dari nodus permukaan bioma." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Merubah kekasaran dari medan.\n" +"Mengatur nilai \"persistence\" dari noise terrain_base dan terrain_alt." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Merubah kecuraman tebing." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Kelajuan vertikal memanjat dalam nodus per detik." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Sinkronisasi layar vertikal." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Pengandar video" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Faktor view bobbing" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Jarak pandang dalam nodus." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Tombol mengurangi jarak pandang" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Tombol menambah jarak pandang" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Tombol zum" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Jarak pandang" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "Joystick virtual mengetuk tombol Aux1" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Volume" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Volume semua suara.\n" +"Membutuhkan sistem suara untuk dinyalakan." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Koordinat W dari irisan 3D dari fraktal 4D.\n" +"Menentukan irisan 3D dari bangun 4D untuk dibuat.\n" +"Mengubah bentuk fraktal.\n" +"Tidak berlaku pada fraktal 3D.\n" +"Jangkauan sekitar -2 ke 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Kelajuan jalan dan terbang dalan nodus per detik." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Kelajuan jalan" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Kelajuan jalan, terbang, dan memanjat dalam mode gerak cepat dalam nodus per " +"detik." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Ketinggian air" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Ketinggian permukaan air dunia." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Nodus melambai" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Daun melambai" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Air berombak" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Ketinggian ombak air" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Kelajuan gelombang ombak" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Panjang ombak air" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Tanaman berayun" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "Warna tautan web" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Saat gui_scaling_filter diatur ke true, semua gambar GUI harus difilter\n" +"dalam perangkat lunak, tetapi beberapa gambar dibuat langsung ke\n" +"perangkat keras (misal. render ke tekstur untuk nodus dalam inventaris)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Saat gui_scaling_filter_txr2img dibolehkan, salin gambar-gambar tersebut\n" +"dari perangkat keras ke perangkat lunak untuk perbesar/perkecil. Saat tidak\n" +"dibolehkan, kembali ke cara lama, untuk pengandar video yang tidak\n" +"mendukung pengunduhan tekstur dari perangkat keras." + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Saat menggunakan filter bilinear/trilinear/anisotropik, tekstur resolusi\n" +"rendah dapat dikaburkan sehingga diperbesar otomatis dengan interpolasi\n" +"nearest-neighbor untuk menjaga ketajaman piksel. Ini mengatur ukuran\n" +"tekstur minimum untuk tekstur yang diperbesar; semakin tinggi semakin\n" +"tajam, tetapi butuh memori lebih. Perpangkatan dua disarankan. Pengaturan\n" +"ini HANYA diterapkan jika menggunakan filter bilinear/trilinear/" +"anisotropik.\n" +"Ini juga dipakai sebagai ukuran dasar tekstur nodus untuk penyekalaan\n" +"otomatis tekstur yang sejajar dengan dunia." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Apakah latar belakang tanda nama ditampilkan secara bawaan.\n" +"Mod masih bisa mengatur latar belakang." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "Apakah animasi tekstur nodus harus tidak disinkronkan tiap blok peta." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Apakah para pemain ditampilkan ke klien tanpa batas jangkauan?\n" +"Usang, gunakan pengaturan player_transfer_distance." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Apakah pemain boleh melukai dan membunuh satu sama lain." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Apakah meminta klien untuk menyambung ulang setelah kerusakan (Lua)?\n" +"Atur ke true jika server Anda diatur untuk mulai ulang otomatis." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Apakah harus memberi kabut pada akhir daerah yang terlihat." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Apakah akan membisukan suara atau tidak. Anda dapat membunyikan\n" +"suara kapan pun, kecuali sistem suara dimatikan (enable_sound = false).\n" +"Dalam permainan, Anda dapat beralih mode bisu dengan tombol bisu\n" +"atau melalui menu jeda." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "Apakah menampilkan informasi awakutu klien (sama dengan menekan F5)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "Lebar ukuran jendela mula-mula. Ini diabaikan dalam mode layar penuh." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Lebar garis kotak pilihan di sekeliling nodus." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Sistem Windows saja: Mulai Minetest dengan jendela perintah baris di latar " +"belakang.\n" +"Memiliki informasi yang sama dengan berkas debug.txt (nama bawaan)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Direktori dunia (semua yang ada di dunia disimpan di sini).\n" +"Tidak perlu jika dimulai dari menu utama." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Waktu mulai dunia" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Tekstur yang sejajar dengan dunia dapat diperbesar hingga beberapa nodus.\n" +"Namun, server mungkin tidak mengirimkan perbesaran yang Anda inginkan,\n" +"terlebih jika Anda menggunakan paket tekstur yang didesain khusus; dengan\n" +"pilihan ini, klien mencoba untuk menentukan perbesaran otomatis sesuai\n" +"ukuran tekstur. Lihat juga texture_min_size.\n" +"Peringatan: Pilihan ini dalam tahap PERCOBAAN!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Mode tekstur sejajar dengan dunia" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y dari tanah flat." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Titik acuan kemiringan kepadatan gunung pada sumbu Y. Digunakan untuk " +"menggeser gunung secara vertikal." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Batas atas Y untuk gua besar." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Jarak Y dari gua besar untuk meluas ke ukuran penuh." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Jarak Y penirusan floatland dari padat sampai kosong.\n" +"Penirusan dimulai dari jarak ini sampai batas Y.\n" +"Untuk lapisan floatland padat, nilai ini mengatur tinggi bukit/gunung.\n" +"Nilai ini harus kurang dari atau sama dengan setengah jarak antarbatas Y." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Ketinggian Y dari permukaan medan rata-rata." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Ketinggian Y dari batas atas gua." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Ketinggian Y dari medan yang lebih tinggi dan menyusun tebing." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Ketinggian Y dari medan yang lebih rendah dan dasar laut." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Ketinggian Y dari dasar laut." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Batas waktu cURL mengunduh berkas" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "Waktu habis untuk cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Batas cURL paralel" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Mode Kreatif: " + +#~ msgid "- Damage: " +#~ msgstr "- Kerusakan: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = parallax occlusion dengan informasi kemiringan (cepat).\n" +#~ "1 = relief mapping (pelan, lebih akurat)." + +#~ msgid "Address / Port" +#~ msgstr "Alamat/Porta" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Sesuaikan pengodean gamma untuk tabel cahaya.\n" +#~ "Angka yang lebih tinggi lebih terang.\n" +#~ "Pengaturan ini untuk klien saja dan diabaikan oleh peladen." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "" +#~ "Ubah cara gunung floatland meramping di atas dan di bawah titik tengah." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Apakah Anda yakin ingin mengatur ulang dunia Anda?" + +#~ msgid "Back" +#~ msgstr "Kembali" + +#~ msgid "Basic" +#~ msgstr "Dasar" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bit per piksel (alias kedalaman warna) dalam mode layar penuh." + +#~ msgid "Bump Mapping" +#~ msgstr "Bump Mapping" + +#~ msgid "Bumpmapping" +#~ msgstr "Bumpmapping" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "Titik tengah penguatan tengah kurva cahaya." + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Mengubah antarmuka menu utama:\n" +#~ "- Full: Banyak dunia pemain tunggal, pilih permainan, paket tekstur, " +#~ "dll.\n" +#~ "- Simple: Satu dunia pemain tunggal, tanpa pilihan permainan atau " +#~ "paket\n" +#~ "tekstur. Cocok untuk layar kecil." + +#~ msgid "Config mods" +#~ msgstr "Konfigurasi mod" + +#~ msgid "Configure" +#~ msgstr "Konfigurasi" + +#~ msgid "Connect" +#~ msgstr "Sambung" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Atur kelajuan tenggelam dalam cairan." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Atur kepadatan floatland berbentuk gunung.\n" +#~ "Merupakan pergeseran yang ditambahkan ke nilai noise \"mgv7_np_mountain\"." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Mengatur lebar terowongan, nilai lebih kecil terowongan semakin lebar." + +#~ msgid "Credits" +#~ msgstr "Penghargaan" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Warna crosshair: (merah,hijau,biru) atau (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Kerusakan dinyalakan" + +#~ msgid "Darkness sharpness" +#~ msgstr "Kecuraman kegelapan" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Batas waktu bawaan untuk cURL, dalam milidetik.\n" +#~ "Hanya berlaku jika dikompilasi dengan cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Mengatur daerah dari medan halus floatland.\n" +#~ "Floatland halus muncul saat noise > 0." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Menentukan langkah penyampelan tekstur.\n" +#~ "Nilai lebih tinggi menghasilkan peta lebih halus." + +#~ msgid "Del. Favorite" +#~ msgstr "Hapus favorit" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Unduh suatu permainan, misalnya Minetest Game, dari minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Unduh satu dari minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Mengunduh dan memasang $1, mohon tunggu..." + +#~ msgid "Enable VBO" +#~ msgstr "Gunakan VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "Gunakan konfirmasi pendaftaran" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Gunakan bumpmapping untuk tekstur. Normalmap harus disediakan oleh paket\n" +#~ "tekstur atau harus dihasilkan otomatis.\n" +#~ "Membutuhkan penggunaan shader." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Gunakan pemetaan suasana (tone mapping) filmis" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Buat normalmap secara langsung (efek Emboss).\n" +#~ "Membutuhkan penggunaan bumpmapping." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Gunakan pemetaan parallax occlusion.\n" +#~ "Membutuhkan penggunaan shader." + +#~ msgid "Enter " +#~ msgstr "Masuk " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Masih tahap percobaan, dapat menyebabkan terlihatnya spasi antarblok\n" +#~ "saat diatur dengan angka yang lebih besar dari 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS (bingkai per detik) pada menu jeda" + +#~ msgid "Fallback font shadow" +#~ msgstr "Bayangan fon cadangan" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Keburaman bayangan fon cadangan" + +#~ msgid "Fallback font size" +#~ msgstr "Ukuran fon cadangan" + +#~ msgid "Filtering" +#~ msgstr "Pemfilteran" + +#~ msgid "Floatland base height noise" +#~ msgstr "Noise ketinggian dasar floatland" + +#~ msgid "Floatland mountain height" +#~ msgstr "Ketinggian gunung floatland" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Keburaman bayangan fon (keopakan, dari 0 sampai 255)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Ukuran fon cadangan bawaan dalam poin (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "Fon FreeType" + +#~ msgid "Full screen BPP" +#~ msgstr "BPP layar penuh" + +#~ msgid "Game" +#~ msgstr "Permainan" + +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Buat Normal Maps" + +#~ msgid "Generate normalmaps" +#~ msgstr "Buat normalmap" + +#~ msgid "HUD scale factor" +#~ msgstr "Faktor skala HUD" + +#~ msgid "High-precision FPU" +#~ msgstr "FPU (satuan titik mengambang) berketelitian tinggi" + +#~ msgid "IPv6 support." +#~ msgstr "Dukungan IPv6." + +#~ msgid "In-Game" +#~ msgstr "Dalam permainan" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Pemasangan: berkas: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Instrumentasi" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Pengaturan tombol. (Jika menu ini kacau, hapus pengaturan kontrol dari " +#~ "minetest.conf)" + +#~ msgid "Lava depth" +#~ msgstr "Kedalaman lava" + +#~ msgid "Lightness sharpness" +#~ msgstr "Kecuraman keterangan" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Batas antrean kemunculan (emerge queue) pada diska" + +#~ msgid "Main" +#~ msgstr "Beranda" + +#~ msgid "Main menu style" +#~ msgstr "Gaya menu utama" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "Buat DirectX bekerja dengan LuaJIT. Matikan jika bermasalah." + +#~ msgid "Menus" +#~ msgstr "Menu" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Peta mini mode radar, perbesaran 2x" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Peta mini mode radar, perbesaran 4x" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Peta mini mode permukaan, perbesaran 2x" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Peta mini mode permukaan, perbesaran 4x" + +#~ msgid "Name / Password" +#~ msgstr "Nama/Kata Sandi" + +#~ msgid "Name/Password" +#~ msgstr "Nama/Kata Sandi" + +#~ msgid "No" +#~ msgstr "Tidak" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Sampling normalmap" + +#~ msgid "Normalmaps strength" +#~ msgstr "Kekuatan normalmap" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Jumlah pengulangan parallax occlusion." + +#~ msgid "Ok" +#~ msgstr "Oke" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "" +#~ "Keburaman (alfa) bayangan di belakang fon cadangan, antara 0 dan 255." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "Bias keseluruhan dari efek parallax occlusion, biasanya skala/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Skala keseluruhan dari efek parallax occlusion." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallax Occlusion" + +#~ msgid "Parallax occlusion" +#~ msgstr "Parallax occlusion" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Pergeseran parallax occlusion" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Pengulangan parallax occlusion" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Mode parallax occlusion" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Skala parallax occlusion" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Kekuatan parallax occlusion" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Jalur ke TrueTypeFont atau bitmap." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Jalur untuk menyimpan tangkapan layar." + +#~ msgid "Player name" +#~ msgstr "Nama pemain" + +#~ msgid "Profiling" +#~ msgstr "Profiling" + +#~ msgid "Projecting dungeons" +#~ msgstr "Dungeon yang menonjol" + +#~ msgid "PvP enabled" +#~ msgstr "PvP dinyalakan" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Atur ulang dunia pemain tunggal" + +#~ msgid "Select Package File:" +#~ msgstr "Pilih berkas paket:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Server/Pemain tunggal" + +#~ msgid "Shadow limit" +#~ msgstr "Batas bayangan" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Pergeseran bayangan fon cadangan dalam piksel. Jika 0, bayangan tidak " +#~ "akan digambar." + +#~ msgid "Special" +#~ msgstr "Spesial" + +#~ msgid "Special key" +#~ msgstr "Tombol spesial" + +#~ msgid "Start Singleplayer" +#~ msgstr "Mulai Pemain Tunggal" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Kekuatan normalmap yang dibuat." + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "Kekuatan penguatan tengah kurva cahaya." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Fon ini akan digunakan pada bahasa tertentu." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Untuk menggunakan shader, pengandar OpenGL harus digunakan." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Mode sinema" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Ketinggian maksimum secara umum, di atas dan di bawah titik tengah, dari " +#~ "gunung floatland." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Variasi dari ketinggian bukit dan kedalaman danau pada medan halus " +#~ "floatland." + +#~ msgid "View" +#~ msgstr "Tinjau" + +#~ msgid "Waving Water" +#~ msgstr "Air Berombak" + +#~ msgid "Waving water" +#~ msgstr "Air berombak" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Apakah fon FreeType digunakan, membutuhkan dukungan FreeType saat " +#~ "dikompilasi.\n" +#~ "Jika dimatikan, fon bitmap dan vektor XML akan dipakai." + +#~ msgid "Whether dungeons occasionally project from the terrain." +#~ msgstr "Apakah dungeon terkadang muncul dari medan." + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Batas atas Y untuk lava dalam gua besar." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "Ketinggian Y dari titik tengah floatland dan permukaan danau." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Ketinggian Y tempat bayangan floatland diperpanjang." + +#~ msgid "Yes" +#~ msgstr "Ya" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Anda akan bergabung ke server dengan nama \"%s\" untuk pertama kalinya.\n" +#~ "Jika Anda melanjutkan, akun baru yang telah Anda isikan akan dibuat pada " +#~ "server ini.\n" +#~ "Silakan ketik ulang kata sandi Anda dan klik \"Daftar dan Gabung\" untuk " +#~ "mengonfirmasi pembuatan akun atau klik Batal untuk membatalkan." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Anda mati" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/it/minetest.po b/po/it/minetest.po new file mode 100644 index 0000000..b986bfb --- /dev/null +++ b/po/it/minetest.po @@ -0,0 +1,8484 @@ +msgid "" +msgstr "" +"Project-Id-Version: Italian (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-06-20 09:52+0000\n" +"Last-Translator: Giov4 <brancacciogiovanni1@gmail.com>\n" +"Language-Team: Italian <https://hosted.weblate.org/projects/minetest/" +"minetest/it/>\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.13.1-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Pulisci la coda di uscita dei messaggi della chat" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Comando vuoto." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Ritorna al menu principale" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Comando non valido: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Comando eseguito: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Elenca i giocatori connessi" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Giocatori connessi: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "La coda di uscita dei messaggi della chat ora è vuota." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Questo comando è stato disabilitato dal server." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Rinasci" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Sei morto" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Comandi disponibili:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Comandi disponibili: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Comando non disponibile: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Ottieni aiuto per i comandi" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Digita '.help <cmd>' per ricevere ulteriori informazioni sul comando, o " +"digita '.help all' per elencare tutti i comandi." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[tutto | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Conferma" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<nessuno disponibile>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Si è verificato un errore in uno script Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Si è verificato un errore:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menu principale" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Riconnettiti" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Il server ha richiesto la riconnessione:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Seleziona i Moduli" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "La versione del protocollo non coincide. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Il server impone la versione $1 del protocollo. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Il server supporta versioni di protocollo comprese tra la $1 e la $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Supportiamo solo la versione $1 del protocollo." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Supportiamo versioni di protocollo comprese tra la $1 e la $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Annulla" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Dipendenze:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Disattiva tutto" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Disattiva la raccolta di mod" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Attiva tutto" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Attiva la raccolta di mod" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Impossibile abilitare la mod \"$1\" poiché contiene caratteri non " +"consentiti. Sono ammessi solo caratteri [a-z0-9_]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Trova Più Moduli" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Nessuna dipendenza (facoltativa)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Non è stata fornita alcuna descrizione del gioco." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Nessuna dipendenza necessaria" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Non è stata fornita alcuna descrizione per la raccolta di mod." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Nessuna dipendenza facoltativa" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Dipendenze facoltative:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Salva" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Mondo:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "abilitato" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" esiste già. Vuoi sovrascriverlo?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Le dipendenze $1 e $2 saranno installate." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 con $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"Scaricando $1,\n" +"$2 in coda" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "Scaricando $1..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 impossibile trovare le dipendeze necessarie." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 sarà installato, e $2 dipendenze verranno ignorate." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Tutti i contenuti" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Già installato" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Torna al Menu Principale" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Gioco di Base:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB non è disponibile quando Minetest viene compilato senza cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Scaricamento..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Impossibile scaricare $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Giochi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Installa" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Installa $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Installa le dipendenze mancanti" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Installazione: Tipo di file non supportato o archivio danneggiato" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Moduli" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Non è stato possibile recuperare alcun contenuto" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Nessun risultato" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Nessun aggiornamento" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Non trovato" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Sovrascrivi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Per favore, controlla che il gioco di base sia corretto." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "In coda" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Raccolte di texture" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Disinstalla" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Aggiorna" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Aggiorna Tutto [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Visualizza ulteriori informazioni in un browser Web" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Un mondo chiamato \"$1\" esiste già" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Terreno aggiuntivo" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Raffreddamento da altitudine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Siccità da altitudine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Mescolamento biomi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Caverne" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Grotte" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Crea" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Decorazioni" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Avviso: Il Development Test è inteso per gli sviluppatori." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Sotterranei" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Terreno piatto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Regioni di terreno fluttuanti nel cielo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Terre fluttuanti (sperimentale)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Generare terreno non-frattale: oceani e spazio sotterraneo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Colline" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Fiumi umidi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Aumenta l'umidità attorno ai fiumi" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Installa $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Laghi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Bassa umidità e calore elevato rendono i fiumi bassi o secchi" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "generatore della mappatura del terreno" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Valori del generatore della mappatura del terreno" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Valori specifici del generatore della mappatura del terreno" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Montagne" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Scorrimento fangoso" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Rete di gallerie e grotte" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Nessun gioco selezionato" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Diminuisce il calore con l'altitudine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Diminuisce l'umidità con l'altitudine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Fiumi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Fiumi a livello del mare" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Seme" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Transizione uniforme tra biomi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Strutture che compaiono sul terreno (nessun effetto su alberi ed erba della " +"giungla creati dal v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Strutture che compaiono sul terreno, tipicamente alberi e piante" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Temperato, Deserto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Temperato, Deserto, Giungla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Temperato, Deserto, Giungla, Tundra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erosione della superficie del terreno" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Alberi ed erba della giungla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Diversifica la profondità dei fiumi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Caverne davvero grandi in profondità sottoterra" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nome del mondo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Non hai nessun gioco installato." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Siete sicuri di volere cancellare \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Rimuovi" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: non è stato possibile eliminare \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: percorso non valido \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Eliminare il mondo \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Conferma la password" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Nome del generatore mappa" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nome" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Password" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Le password non corrispondono!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Registrati e accedi" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Conferma" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Rinomina la raccolta di mod:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Questa raccolta di mod esplicita un nome fornito in modpack.conf che " +"sovrascriverà ogni modifica del nome qui effettuata." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Nessuna descrizione fornita per l'impostazione)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Rumore 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Torna alla pagina Impostazioni" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Esplora" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Contenuto" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Contenuto" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Disabilitato" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Modifica" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Abilitato" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lacunarità" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Ottave" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Scarto" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Persistenza" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Per favore inserisci un numero intero valido." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Per favore inserisci un numero valido." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Ripristina predefinito" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Ridimensiona" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Ricerca" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Scegli l'indirizzo" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Scegli un file" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Mostra i nomi tecnici" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Il valore deve essere almeno $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Il valore non deve essere più grande di $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Propagazione X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Propagazione Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Propagazione Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "\"absvalue\"" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "\"defaults\"" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "\"eased\"" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Attivato)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 moduli" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "installazione fallita di $1 a $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Installa Modulo: Impossibile trovare il nome vero del mod per: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Installa Modulo: Impossibile trovare un nome della cartella adeguato per la " +"raccolta di mod $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Impossibile trovare un mod o una raccolta di mod validi" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Impossibile installare un $1 come una raccolta di texture" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Impossibile installare un gioco come un $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Impossibile installare un mod come un $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Impossibile installare una raccolta di mod come un $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Caricamento..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "L'elenco dei server pubblici è disabilitato" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Prova a riabilitare l'elenco dei server pubblici e controlla la tua " +"connessione Internet." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Informazioni" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Contributori Attivi" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Algoritmo di resa attivo:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Sviluppatori Principali" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Apri l'Indirizzo dei Dati Utente" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Apre l'indirizzo contenente mondi, giochi, mod e raccolte di\n" +"textures forniti dall'utente in un gestore / visualizzatore di file ." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Contributori precedenti" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Sviluppatori Principali Precedenti" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Mostra le informazioni di debug" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Esplora i contenuti online" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Contenuto" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Disattiva la Raccolta di Texture" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informazioni:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Contenuti Installati:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Nessuna dipendenza." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Nessuna descrizione disponibile per il contenuto" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Rinomina" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Disinstalla il Contenuto" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Utilizza la Raccolta di Textures" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Annunciare il Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Indirizzo Incorporato" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Modalità Creativa" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Abilita il Ferimento" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Ospita un Gioco" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Ospita un Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Installa giochi da ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Nuovo" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Nessun mondo creato o selezionato!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Avvia il gioco" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Porta" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Seleziona i Moduli" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Seleziona il Mondo:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Porta del Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Gioca" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Indirizzo" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Canc" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Modalità creativa" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Ferimento / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Preferiti" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Server Incompatibili" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Unisciti al Gioco" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Server Pubblici" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Ricarica" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Porta remota" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Descrizione del Server" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Nuvole in 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Tutte le Impostazioni" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Anti-Scalettatura:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Ricorda Dim. Finestra" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Filtro Bilineare" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Cambia i Tasti" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Vetro Contiguo" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Ombre Dinamiche" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Ombre dinamiche: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Foglie di Qualità" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Alto" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Basso" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Medio" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "MIP map" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Filtro Aniso." + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Nessun Filtro" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Nessuna Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Evidenziatura dei Nodi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Profilo dei Nodi" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Nessuno" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Foglie Opache" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Acqua Opaca" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Particelle" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Schermo:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Impostazioni" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shader" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shaders (sperimentali)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Shaders (non disponibili)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Foglie Semplici" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Illuminazione Uniforme" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Resa Immagini:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Mappatura del Tono" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Soglia del Tocco: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Filtro Trilineare" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Ultra" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Molto Basso" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Foglie Ondeggianti" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Liquidi Ondeggianti" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Piante Ondeggianti" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Errore di connessione (scaduta?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Connessione scaduta." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Fatto!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inizializzando i nodi" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Inizializzando i nodi..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Caricando le textures..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Ricostruendo le shaders..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Errore di connessione (scaduta?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Impossibile trovare o caricare il gioco: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Requisiti del gioco non validi." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menu Principale" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Nessun mondo selezionato e nessun indirizzo fornito. Nulla da fare." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Nome del giocatore troppo lungo." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Per favore scegli un nome!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Impossibile aprire il file di password fornito: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Il percorso del mondo fornito non esiste: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Controlla debug.txt per i dettagli." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Indirizzo: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Modalità: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Porta: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Pubblico: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Nome del Server: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Si è verificato un errore di serializzazione:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Accesso negato. Motivo: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Avanzamento automatico disabilitato" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Avanzamento automatico abilitato" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Limiti del blocco nascosti" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "I limiti del blocco sono mostrati per tutti i blocchi" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "I limiti del blocco sono mostrati per il blocco attuale" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "I limiti del blocco sono mostrati per i blocchi vicini" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Aggiornamento della telecamera disabilitato" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Aggiornamento telecamera abilitato" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" +"Impossibile mostrare i limiti del blocco (si ha bisogno del privilegio " +"'basic_debug')" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Cambia la Password" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Modalità cinematica disattiva" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Modalità cinematica attiva" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Client disconnesso" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Scripting su lato client disabilitato" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Connessione al server..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Connessione fallita per motivo sconosciuto" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Continua" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Controlli:\n" +"- %s: avanza\n" +"- %s: arretra\n" +"- %s: sinistra\n" +"- %s: destra\n" +"- %s: salta/scala su\n" +"- %s: scava/colpisci\n" +"- %s: piazza/utilizza\n" +"- %s: furtivo/scendi\n" +"- %s: getta via oggetto\n" +"- %s: inventario\n" +"- Mouse: girati/guarda\n" +"- Rotella mouse: scegli oggetto\n" +"- %s: chat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Impossibile risolvere l'indirizzo: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Creazione del client..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Creazione del server..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Info di debug e grafico profiler nascosti" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Info debug mostrate" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Info debug, grafico profiler e struttura a fili nascosti" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Controlli Predefiniti:\n" +"Nessun menu visibile:\n" +"- tocco singolo: attiva pulsante\n" +"- tocco doppio; piazza/utilizza\n" +"- trascina il dito: guarda attorno\n" +"Menu/Inventario visibile:\n" +"- doppio tocco (esterno):\n" +" -->chiudi\n" +"- tocco pila, tocco casella:\n" +" --> sposta pila\n" +"- tocca e trascina, tocco 2° dito\n" +" --> piazza oggetto singolo nella casella\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Raggio visivo illimitato disabilitato" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Raggio visivo illimitato abilitato" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Creazione del client..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Menu Principale" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Torna al S.O." + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Modalità rapida disabilitata" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Modalità rapida abilitata" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Modalità rapida abilitata (nota: privilegio 'fast' mancante)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Modalità volo disabilitata" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Modalità volo abilitata" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Modalità volo abilitata (nota: privilegio 'fly' mancante)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Nebbia disattivata" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Nebbia attivata" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Informazioni del gioco:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Gioco in pausa" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Server ospitante" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Definizione degli oggetti..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "File multimediali..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Minimappa attualmente disabilitata dal gioco o da un modulo" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Multigiocatore" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Modalità incorporea disabilitata" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Modalità incorporea abilitata" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Modalità incorporea abilitata (nota: privilegio 'noclip' mancante)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Definizione dei nodi..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Disattivato" + +#: src/client/game.cpp +msgid "On" +msgstr "Attivato" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Modalità inclinazione movimento disabilitata" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Modalità inclinazione movimento abilitata" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Grafico profiler visualizzato" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Server remoto" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Risoluzione dell'indirizzo..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Uscita dal gioco..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Gioco locale" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Volume del Suono" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Suono disattivato" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Il sistema audio è disabilitato" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Il sistema audio non è supportato su questa compilazione" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Suono attivato" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Il server sta probabilmente eseguendo una versione differente di %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Impossibile connettersi a %s perché IPv6 è disabilitato" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Impossibile ascoltare su %s perché IPv6 è disabilitato" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Raggio visivo cambiato a %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Il raggio visivo è al massimo: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Il raggio visivo è al minimo: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Volume cambiato a %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Struttura a fili visualizzata" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Ingrandimento attualmente disabilitato dal gioco o da un mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "va bene" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Chat nascosta" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Chat mostrata" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD nascosto" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD visibile" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profilatore nascosto" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profilatore visualizzato (pagina %d di %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Applicazioni" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Tasto di ritorno" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Blocco Maiusc." + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Giù" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Fine" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Canc. EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Eseguire" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Aiuto" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Inizio" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Accetta IME" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Converti IME" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "Ritorno da IME" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Cambia Modalità IME" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "Non Convertire IME" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Inserisci" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Sinistra" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Pulsante Sinistro" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Control Sinistro" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menu Sinistro" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Shift Sinistro" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Windows Sinistro" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Pulsante Centrale" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Bloc Num" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Tastierino *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Tastierino +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Tastierino -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Tastierino ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Tastierino /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Tastierino 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Tastierino 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Tastierino 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Tastierino 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Tastierino 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Tastierino 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Tastierino 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Tastierino 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Tastierino 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Tastierino 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Canc" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Pag. giù" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Pag. su" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pausa" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Avvia" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Stampa" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Invio" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Destra" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Pusante detro" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Ctrl destro" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menu destro" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Maiusc destro" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Windows destro" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Selezione" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Maiusc" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Sospensione" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Stampa" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Spazio" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Su" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Pulsante X 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Pulsante X 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Ingrandimento" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Minimappa nascosta" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimappa in modalità radar, ingrandimento x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimappa in modalità superficie, ingrandimento x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimappa in modalità texture" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Impossibile aprire la pagina web" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Apertura pagina web" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Prosegui" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Speciale\" = discendi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Avanzam. autom." + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Salto automatico" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Speciale" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Indietreggia" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Limiti del blocco nascosto" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Cambia vista" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Comando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Console" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Diminuisci raggio" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Diminuisci volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Doppio \"salta\" per volare" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Butta" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Avanza" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Aumenta raggio" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Aumenta volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventario" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Salta" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Tasto già usato" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Comando locale" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Muta audio" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Oggetto successivo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Oggetto precedente" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Selezione raggio" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Screenshot" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Furtivo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "HUD sì/no" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Log chat sì/no" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Corsa sì/no" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Volo sì/no" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Nebbia sì/no" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Minimappa sì/no" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Incorporeità sì/no" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Beccheggio sì/no" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "premi il tasto" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Cambia" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nuova password" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Vecchia password" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Le password non corrispondono!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Uscita" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Silenziato" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Volume suono: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "it" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Per favore scegli un nome!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Fissa la posizione del joystick virtuale.\n" +"Se disabilitato, il joystick sarà centrato alla posizione del primo tocco." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Usa il joystick virtuale per attivare il pulsante \"Speciale\".\n" +"Se abilitato, inoltre, il joystick virtuale premerà il pulsante \"Speciale\" " +"quando fuori dal cerchio principale." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"Scarto (X,Y,Z) del frattale dal centro del mondo in unità di \"scala\".\n" +"Può essere usato per spostare un punto desiderato a (0,0) per creare un\n" +"punto di comparsa adatto, o per consentire l'ingrandimento su di un punto " +"desiderato\n" +"per mezzo dell'aumento della \"scala\".\n" +"Il valore predefinito è regolato per un punto di comparsa opportuno con le " +"serie Mandelbrot\n" +"che usino i parametri predefiniti, potrebbe richiedere modifiche in altre\n" +"situazioni.\n" +"Varia grossomodo da -2 a 2. Si moltiplichi per \"scala\" per lo scarto in " +"nodi." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"Scala (X,Y,Z) del frattale in nodi.\n" +"La dimensione effettiva del frattale sarà due o tre volte più grande.\n" +"Questi numeri possono essere impostati su valori molto alti, il frattale non " +"deve\n" +"necessariamente rientrare nel mondo.\n" +"Li si aumenti per \"ingrandire\" nel dettaglio del frattale.\n" +"Il valore predefinito è per una forma schiacciata verticalmente, adatta\n" +"a un'isola, si impostino tutti e tre i numeri sullo stesso valore per la " +"forma grezza." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Rumore 2D che controlla forma/dimensione delle montagne con dirupi." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Rumore 2D che controlla forma/dimensione delle colline in serie." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Rumore 2D che controlla forma/dimensione delle montagne a terrazza." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" +"Rumore 2D che controlla forma/comparsa delle file di montagne con dirupi." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "Rumore 2D che controlla forma/comparsa delle colline in serie." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" +"Rumore 2D che controlla forma/comparsa delle file di montagne con dirupi." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Rumore 2D che posiziona fiumi e canali." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Nuvole in 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Modalità 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Intensità della modalità 3D di parallasse" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Rumore 3D che definisce le caverne giganti." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Rumore 3D che definisce struttura e altezza delle montagne.\n" +"Definisce anche la struttura del terreno montano delle terre fluttuanti." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Rumore 3D che stabilisce la struttura delle terre fluttuanti.\n" +"Se cambiata dal valore predefinito, la 'scala' di rumore (0.7 in modo " +"predefinito) potrebbe necessitare\n" +"d'essere aggiustata, dato che l'affusolamento delle terre fluttuanti " +"funziona meglio quando questo rumore\n" +"ha un intervallo di valori approssimativamente tra -2.0 e 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Rumore 3D che definisce la struttura dei muri dei canyon dei fiumi." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Rumore 3D che definisce il terreno." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"Rumore 3D per sporgenze, dirupi, ecc. delle montagne. Normalmente piccole " +"variazioni." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "Rumore 3D che stabilisce il numero di segrete per blocco di mondo." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Supporto 3D.\n" +"Attualmente supportati:\n" +"- nessuno: nessuna resa 3D.\n" +"- anaglifo: 3D a colori ciano/magenta.\n" +"- intrecciato: supporto polarizzazione schermo basato sulle linee pari/" +"dispari.\n" +"- sopra-sotto: divide lo schermo sopra-sotto.\n" +"- fianco-a-fianco: divide lo schermo fianco a fianco.\n" +"- vista incrociata: 3D a occhi incrociati.\n" +"- inversione pagina: 3D basato su quadbuffer.\n" +"Si noti che la modalità intrecciata richiede l'abilitazione degli shader." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Un seme prescelto per una nuova mappa, lascialo vuoto per uno casuale.\n" +"Sarà ignorato quando si crea un nuovo mondo nel menu principale." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" +"Un messaggio da mostrare a tutti i client quando il server va in crash." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Un messaggio da mostrare a tutti i client quando il server chiude." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Intervallo ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Budget di tempo ABM" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Limite assoluto di blocchi in coda da fare apparire" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Accelerazione in aria" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Accelerazione di gravità, in nodi per secondo al secondo." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Modificatori dei blocchi attivi" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Intervallo di gestione dei blocchi attivi" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Raggio dei blocchi attivi" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Raggio di invio degli oggetti attivi" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Indirizzo a cui connettersi.\n" +"Lascialo vuoto per avviare un server locale.\n" +"Si noti che il campo indirizzo nel menu principale sovrascrive questa " +"impostazione." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Aggiunge particelle quando scavi un nodo." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Regolate la configurazione dpi per il vostro schermo (solo non X11/Android) " +"per es. per schermi 4K." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Aggiusta la densità del display rilevato, utilizzato per scalare gli " +"elementi UI." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Calibra la densità dello strato della terra fluttuante.\n" +"Si aumenti il valore per aumentare la densità. Può essere positivo o " +"negativo.\n" +"Valore = 0.0: 50% del volume è terra fluttuante.\n" +"Value = 2.0 (può essere maggiore dipendentemente da 'mgv7_np_floatland', " +"provare sempre\n" +"per essere sicuri) crea uno strato solido di terre fluttuanti." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Posponi nome oggetto" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avanzate" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Altera la curva di luce applicandovi la 'correzione gamma'.\n" +"Valori più alti rendono più luminosi i livelli di luce medi e inferiori.\n" +"Il valore '1.0' lascia inalterata la curva di luce.\n" +"Questo ha un effetto significativo solo sulla luce diurna e sulla luce " +"artificiale,\n" +"ha pochissimo effetto sulla luce notturna naturale." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Sempre volo e veloce" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Gamma dell'occlusione ambientale" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Numero di messaggi che un giocatore può inviare ogni 10sec." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Allarga le vallate." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Filtraggio anisotropico" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Rendere noto il server" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Annuncia a questo elenco di server." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Posponi nome oggetto" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Posponi nome oggetto a suggerimenti." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Rumore dei meli" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Inerzia del braccio" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Inerzia del braccio, dà un movimento più realistico\n" +"al braccio quando si sposta la visuale." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Chiedi di riconnettersi dopo un crash" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"A questa distanza il server ottimizzerà aggressivamente quali blocchi sono\n" +"inviati ai client.\n" +"Potenzialmente valori piccoli migliorano molto le prestazioni, al costo di\n" +"difetti di disegno visibili (alcuni blocchi non saranno disegnati sott'acqua " +"e\n" +"nelle grotte, come a volte sul terreno).\n" +"Impostarla a un valore maggiore di max_block_send_distance disabilita\n" +"questa ottimizzazione.\n" +"Fissata in blocchi mappa (16 nodi)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Tasto di avanzamento automatico" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Salta automaticamente su ostacoli di un nodo singolo." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Fa rapporto automatico all'elenco dei server." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Salvare dim. finestra" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Modalità scalamento automatico" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Tasto Speciale" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Tasto Speciale per scendere/immergersi" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tasto per indietreggiare" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Livello base del terreno" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Altezza base del terreno." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Privilegi di base" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Rumore delle spiagge" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Soglia del rumore delle spiagge" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Filtraggio bilineare" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Lega indirizzo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Parametri di rumore dell'API dei biomi per temperatura e umidità" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Rumore biomi" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Distanza di ottimizzazione dell'invio dei blocchi" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Percorso dei caratteri in grassetto e corsivo" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Percorso dei font monospaziali in grassetto e corsivo" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Percorso dei caratteri in grassetto" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Percorso caratteri monospaziale in grassetto" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Costruisci dentro giocatore" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Incorporato" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Cambia vista" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Distanza dei nodi del \"piano di ritaglio vicino\" alla telecamera, tra 0 e " +"0.5.\n" +"La maggior parte degli utenti non dovrà cambiarla.\n" +"Aumentarla può ridurre l'artificialità sulle GPU più deboli.\n" +"0.1 = predefinita, 0.25 = buon valore per tablet più deboli." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Fluidità della telecamera" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Fluidità della telecamera in modalità cinematic" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Tasto di (dis)attivazione dell'aggiornamento della telecamera" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Rumore della caverna" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "1° rumore della caverna" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "2° rumore della caverna" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Larghezza della caverna" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Rumore della 1a caverna" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Rumore della 2a caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Limite della caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Rumore della caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Restringimento della caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Soglia della caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Limite superiore della caverna" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Centro della gamma di amplificazione della curva di luce.\n" +"Dove 0.0 è il livello di luce minimo, 1.0 è il livello di luce massimo." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" +"Limite di tempo per il completamento di un comando, oltre cui mostrare un " +"messaggio nella chat" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Comandi della chat" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Dimensione del carattere dell'area di messaggistica" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Tasto della chat" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Livello del registro dell'area di messaggistica" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Numero limite dei messaggi di chat" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Formato dei messaggi di chat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Limite dei messaggi di chat per l'espulsione" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Lunghezza massima dei messaggi di chat" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Tasto di (dis)attivazione della chat" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Collegamenti a siti Web nella chat" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Dimensione del pezzo" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Modalità cinematica" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tasto modalità cinematic" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Pulizia delle textures trasparenti" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Link web cliccabili (tasto-centrale o Ctrl+tasto-sinistro) abilitati nel " +"output della chat." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Client" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Client e server" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Modifica del client" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Restrizioni delle modifiche del client" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Restrizione dell'area di ricerca dei nodi su lato client" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Modifica del client" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Velocità di arrampicata" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Raggio delle nuvole" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Nuvole" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Le nuvole sono un effetto sul lato client." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Nuvole nel menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Nebbia colorata" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Ombre colorate" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Elenco di valori separato da virgole che si vuole nascondere dal deposito " +"dei contenuti.\n" +"\"nonfree\" può essere usato per nascondere pacchetti che non si " +"qualificano\n" +"come \"software libero\", così come definito dalla Free Software " +"Foundation.\n" +"Puoi anche specificare la classificazione dei contenuti.\n" +"Questi valori sono indipendenti dalle versioni Minetest,\n" +"si veda un elenco completo qui https://content.minetest.net/help/" +"content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Elenco separato da virgole di mod a cui è permesso l'accesso alle API HTTP,\n" +"che gli permettono di caricare e scaricare dati su/da internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Elenco separato da virgole dei mod fidati ai quali è permesso l'accesso a " +"funzioni non sicure\n" +"anche quando è attiva la sicurezza dei moduli (tramite " +"request_insecure_environment()." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Tasto comando" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Livello di compressione da utilizzare durante il salvataggio dei blocchi-" +"mappa su disco.\n" +"-1 - utilizza il livello di compressione predefinito\n" +"0 - compressione minima, più veloce\n" +"9 - compressione migliore, più lento" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Livello di compressione da utilizzare per l'invio dei blocchi-mappa al " +"client.\n" +"-1 - utilizza il livello di compressione predefinito\n" +"0 - compressione minima, più veloce\n" +"9 - compressione migliore, più lento" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Unire i vetri" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Connessione a un server multimediale esterno" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Unione vetri se il nodo lo supporta." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Trasparenza della console" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Colore della console" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Altezza della console" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Deposito dei contenuti in linea" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Contenuti esclusi da ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Massimi download contemporanei di ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "URL ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Avanzamento continuo" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Avanzamento continuo, attivato dal tasto avanzamento automatico.\n" +"Premi nuovamente il tasto di avanzamento automatico o il tasto di " +"arretramento per disabilitarlo." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Controlli" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Controlla la durata del ciclo giorno/notte.\n" +"Esempi:\n" +"72 = 20min, 360 = 4min, 1 = 24ore, 0 = giorno/notte/ecc. restano invariati." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Controlla la ripidità/profondità delle depressioni lacustri." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Controlla la ripidità/altezza delle colline." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Controlla la larghezza delle gallerie, un valore più piccolo crea gallerie " +"più ampie.\n" +"Il valore >= 10.0 disabilita completamente la generazione di tunnel ed evita " +"l'opzione\n" +"calcoli intensivi del rumore." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Messaggio di crash" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Creativa" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Trasparenza del mirino" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Trasparenza del mirino (opacità, tra 0 e 255).\n" +"Lo stesso si applica al mirino dell'oggetto." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Colore del mirino" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Colore del mirino (R,G,B).\n" +"Controlla anche il colore del mirino dell'oggetto" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Ferimento" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Tasto di (dis)attivazione delle informazioni di debug" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Dimensione del file di debug" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Livello del registro di debug" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Tasto dim. volume" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Passo dedicato del server" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Accelerazione predefinita" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Gioco predefinito" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Gioco predefinito alla creazione di un nuovo mondo.\n" +"Questo verrà scavalcato alla creazione di un mondo dal menu principale." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Password predefinita" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Privilegi predefiniti" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Formato di rapporto predefinito" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Dimensione predefinita della pila" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Definisci la qualità del filtraggio delle ombre.\n" +"Questo simula l'effetto delle ombre morbide applicando un PCF o Poisson " +"disk\n" +"ma utilizza più risorse." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Definisce aree in cui gli alberi hanno le mele." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Definisce aree con spiagge sabbiose." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" +"Definisce la distribuzione del terreno superiore e la ripidità dei dirupi." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Definisce la distribuzione del terreno più alto." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Definisce la dimensione completa delle caverne, valori minori creano caverne " +"più grandi." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Definisce la struttura dei canali fluviali di ampia scala." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Definisce posizione e terreno di colline e laghi facoltativi." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Definisce il livello base del terreno." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Stabilisce la profondità del letto del fiume." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Definisce la distanza massima di trasferimento del personaggio in blocchi (0 " +"= illimitata)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Stabilisce la larghezza del fiume." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Stabilisce la larghezza della valle del fiume." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Definisce aree boschive e densità degli alberi." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Ritardo in ms tra gli aggiornamenti delle mesh sul client. Aumentandolo si\n" +"ritarderà il ritmo di aggiornamento delle mesh, riducendo così lo sfarfallio " +"sui client più lenti." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Ritardo dell'invio dei blocchi dopo la costruzione" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Ritardo nella comparsa dei suggerimenti, fissato in millisecondi." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Gestione delle API Lua deprecate" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Profondità sotto cui troverete caverne enormi." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Profondità sotto cui troverete caverne grandi." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Descrizione del server, da mostrarsi all'accesso dell'utente e nell'elenco " +"dei server." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Soglia di rumore del deserto" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"I deserti si presentano quando np_biome supera questo valore.\n" +"Quando è attivo il parametro 'snowbiomes', viene ignorato." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "De-sincronizza l'animazione del blocco" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Decorazioni" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Tasto scava" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Particelle di scavo" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Disattiva anti-trucchi" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Rifiutare le password vuote" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Fattore di Scala della densità del display" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Nome di dominio del server, da mostrarsi nell'elenco dei server." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Doppio \"salta\" per volare" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" +"Premendo due volte il tasto di salto si (dis)attiva la modalità di volo." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Tasto butta oggetto" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Scarica le informazioni di debug del generatore della mappa." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Y massimo dei sotterranei" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Y minimo dei sotterranei" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Rumore per le segrete" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Abilitare il supporto IPv6 (sia per il client che per il server).\n" +"Necessario per il funzionamento delle connessioni IPv6." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Abilita il supporto per le modifiche tramite Lua sul client.\n" +"Questo supporto è sperimentale e l'API potrebbe cambiare." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Abilità il filtraggio Poisson disk\n" +"Se abilitato si hanno le \\\"ombre morbide\\\". Altrimenti utilizza il " +"filtraggio PCF." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Abilità ombre colorate.\n" +"Se abilitato nodi traslucidi producono ombre colorate. Questo è costoso." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Attivare la finestra della console" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Abilitare la modalità creativa per tutti i giocatori" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Abilitare i joystick" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Abilita il supporto canali mod." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Abilita la sicurezza moduli" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Abilita il ferimento e la morte dei giocatori." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" +"Abilita l'ingresso di dati casuali da parte dell'utente (utilizzato solo per " +"i test)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Abilita l'illuminazione armoniosa con una occlusione ambientale semplice.\n" +"Disattivarla per velocizzare o per un aspetto diverso." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Abilitare per impedire ai client obsoleti di connettersi.\n" +"I client più vecchi sono compatibili nel senso che non andranno in crash " +"alla connessione\n" +"ai nuovi server, ma potrebbero non supportare tutte le nuove caratteristiche " +"che ti aspetti." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Abilita l'utilizzo di un server multimediale remoto (se fornito dal " +"server).\n" +"I server remoti offrono un sistema significativamente più rapido per " +"scaricare\n" +"contenuti multimediali (es. textures) quando ci si connette al server." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Attivare gli oggetti tampone per i vertici.\n" +"Questo dovrebbe migliorare notevolmente le prestazioni grafiche." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Attivare l'ondeggiamento visivo e ammontare del medesimo.\n" +"Per esempio: 0 per nessun ondeggiamento, 1.0 per normale, 2.0 per doppio." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Abilita/Disabilita l'esecuzione di un server IPv6.\n" +"Ignorata se si imposta bind_address.\n" +"Necessita di enable_ipv6 per essere abilitata." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Abilita la mappatura dei toni filmici \"Uncharted 2\" di Hable.\n" +"Simula la curva di tono della pellicola fotografica e come questa approssimi " +"la\n" +"comparsa di immagini ad alta gamma dinamica. Il contrasto a medio raggio è " +"leggermente\n" +"potenziato, i punti salienti e le ombre vengono gradualmente compressi." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Attiva l'animazione degli oggetti dell'inventario." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Attiva la cache delle mesh ruotate con facedir." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Attiva la minimappa." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Abilita il sistema audio.\n" +"Se disabilitato, disabilita completamente tutti i suoni ovunque e i " +"controlli audio\n" +"nel gioco non saranno funzionanti.\n" +"Cambiare questa impostazione richiede un riavvio." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Consente compromessi che riducono il carico della CPU o aumentano le " +"prestazioni di rendering\n" +"a scapito di piccoli difetti visivi che non influiscono sulla giocabilità." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Profilo valli" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Intervallo di stampa dei dati di profilo del motore di gioco" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Sistemi di entità" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Esponente dell'affusolamento delle terre fluttuanti. Cambia il comportamento " +"di affusolamento.\n" +"Valore = 1.0 crea un affusolamento uniforme, lineare.\n" +"Valori > 1.0 creano un affusolamento uniforme adatto alle\n" +"terre fluttuanti separate predefinite.\n" +"Valori < 1.0 (per esempio 0.25) creano un livello di superficie più definito " +"con\n" +"pianure più piatte, adatti a uno strato solido di terre fluttuanti." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS quando il gioco è in pausa o in secondo piano" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Rumore di fattore" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Fattore di ondeggiamento in caduta" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Percorso del carattere di ripiego" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Tasto corsa" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Accelerazione della modalità veloce" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Velocità della modalità veloce" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Movimento rapido" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Movimento rapido (tramite il tasto \"Speciale\").\n" +"Richiede il privilegio \"fast\" sul server di gioco." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Campo visivo" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Campo visivo in gradi." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"File in client/serverlist/ contenente i vostri server preferiti mostrati " +"nella\n" +"scheda di gioco in rete." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Profondità dello riempitore" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Profondità di rumore dello riempitore" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Mappatura del tono filmica" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Le textures a cui si applicano i filtri possono amalgamare i valori RGB con " +"quelle vicine\n" +"completamente trasparenti, che normalmente vengono scartati dagli " +"ottimizzatori PNG, risultando\n" +"spesso in bordi chiari o scuri per le textures trasparenti. Applicare un " +"filtro per ripulire tutto ciò al\n" +"caricamento delle texture. Viene attivato automaticamente se si abilita il " +"mipmapping." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Anti-Scalettatura:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Primo di 4 rumori 2D che insieme definiscono l'intervallo di altezza " +"collinare/montuoso." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Primo di due rumori 3D che insieme definiscono le gallerie." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Seme fisso della mappa" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Joystick virtuale fisso" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Densità delle terre fluttuanti" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Y massimo delle terre fluttuanti" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Y minimo delle terre fluttuanti" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Rumore delle terre fluttuanti" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Esponente dell'affusolamento delle terre fluttuanti" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Distanza di affusolamento delle terre fluttuanti" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Livello dell'acqua delle terre fluttuanti" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Tasto volo" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Volo" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Nebbia" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Inizio nebbia" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Tasto (dis)attivazione nebbia" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Dimensione del carattere" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Carattere grassetto per impostazione predefinita" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Carattere corsivo per impostazione predefinita" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Ombreggiatura carattere" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Trasparenza dell'ombreggiatura del carattere" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Dimensione del carattere" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Dimensione carattere divisibile per" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" +"Dimensione carattere del carattere predefinito, dove 1 unità equivale ad 1 " +"pixel a DPI 96" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" +"Dimensione carattere del carattere a spaziatura fissa, dove 1 unità equivale " +"ad 1 pixel a DPI 96" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Dimensione carattere del testo e del prompt dell'area di messaggistica, in " +"punti (pt).\n" +"Valore 0 userà la dimensione carattere predefinita." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"Assicura che le grandezze utilizzate con questo carattere saranno sempre " +"divisibili per questo\n" +"valore, in pixel, in caso di caratteri in stile pixel che non vengono " +"ridimensionati correttamente.\n" +"Per esempio, un carattere pixelato alto 16 pixels richiederebbe che questo " +"sia 16, così sarà sempre\n" +"solo grande 16, 32, 48, etc., e una mod che richiede una grandezza di 25 " +"otterrà 32." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Formato dei messaggi del giocatore. Le stringhe seguenti sono segnaposto " +"validi:\n" +"@name, @message, @timestamp (optional)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Formato degli screenshot." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Colore di sfondo predefinito delle finestre" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Opacità di sfondo predefinita delle finestre" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Colore di sfondo delle finestre a tutto schermo" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Opacità dello sfondo delle finestre a tutto schermo" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Colore di sfondo predefinito delle finestre (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Opacità di sfondo predefinita delle finestre (tra 0 e 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Colore di sfondo delle finestre a tutto schermo (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "Opacità dello sfondo delle finestre a tutto schermo (tra 0 e 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Tasto avanti" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Quarto di 4 rumori 2D che insieme definiscono l'intervallo di altezza " +"collinare/montuoso." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Tipo di frattale" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" +"Frazione della distanza visibile oltre cui si comincia a renderizzare la " +"nebbia" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Da che distanza vengono generati i blocchi per i client, fissata in blocchi " +"mappa (16 nodi)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Da che distanza i blocchi sono inviati ai client, fissata in blocchi mappa " +"(16 nodi)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Da che distanza il client sa degli oggetti, fissata in blocchi mappa (16 " +"nodi).\n" +"\n" +"Impostarla maggiore di active_block_range provocherà il mantenimento\n" +"degli oggetti attivi, fino a questa distanza, da parte del server, nella\n" +"direzione in cui guarda il giocatore. (Ciò può evitare l'improvvisa " +"scomparsa dei mob)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Schermo intero" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Modalità a schermo intero." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Scala dell'interfaccia grafica" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Filtro di scala dell'interfaccia grafica" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Filtro di scala txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Giochi" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Callback globali" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Attributi globali di generazione della mappa.\n" +"Nel Mapgen v6 il valore 'decorations' controlla tutte le decorazioni eccetto " +"alberi\n" +"ed erba della giungla, in tutti gli altri Mapgens questa opzione controlla " +"tutte le decorazioni." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Gradiente della curva della luce al livello massimo di luce.\n" +"Controlla il contrasto dei massimi livelli di luce." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Gradiente della curva della luce al livello minimo di luce.\n" +"Controlla il contrasto dei livelli di luce più bassi." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafica" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafica" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafica" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravità" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Livello del terreno" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Rumore del terreno" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "Moduli HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Scala dell'interfaccia grafica" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Tasto di (dis)attivazione dell'HUD" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Gestione delle chiamate API Lua deprecate:\n" +"- none (nessuno): non registra le chiamate obsolete\n" +"- log (registro): imita e registra il backtrace di una chiamata obsoleta " +"(impostazione predefinita).\n" +"- error (errore): interrompe l'utilizzo della chiamata deprecata " +"(consigliata per gli sviluppatori di mod)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Fare in modo che il generatore di profili si predisponga da sé:\n" +"* Predisporre una funzione vuota.\n" +"Ciò stima il sovraccarico che la predisposizione aggiunge (+1 chiamata di " +"funzione).\n" +"* Predisporre il campionatore utilizzato per aggiornare le statistiche." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Rumore di amalgama del calore" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Rumore del calore" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Componente altezza della dimensione iniziale della finestra. Ignorata in " +"modalità a schermo intero." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Rumore dell'altezza" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Rumore di selezione dell'altezza" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Ripidità delle colline" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Soglia delle colline" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Rumore della collinarità1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Rumore della collinarità2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Rumore della collinarità3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Rumore della collinarità4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Sito del server, da mostrarsi nell'elenco dei server." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Accelerazione orizzontale in aria quando si salta o si cade,\n" +"in nodi al secondo per secondo." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Accelerazione orizzontale e verticale in modalità veloce,\n" +"in nodi al secondo per secondo." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Accelerazione orizzontale sul terreno o in scalata,\n" +"in nodi al secondo per secondo." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Tasto successivo della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Tasto precedente della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Tasto riquadro 1 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Tasto riquadro 10 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Tasto riquadro 11 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Tasto riquadro 12 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Tasto riquadro 13 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Tasto riquadro 14 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Tasto riquadro 15 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Tasto riquadro 16 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Tasto riquadro 17 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Tasto riquadro 18 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Tasto riquadro 19 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Tasto riquadro 2 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Tasto riquadro 20 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Tasto riquadro 21 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Tasto riquadro 22 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Tasto riquadro 23 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Tasto riquadro 24 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Tasto riquadro 25 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Tasto riquadro 26 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Tasto riquadro 27 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Tasto riquadro 28 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Tasto riquadro 29 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Tasto riquadro 3 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Tasto riquadro 30 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Tasto riquadro 31 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Tasto riquadro 32 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Tasto riquadro 4 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Tasto riquadro 5 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Tasto riquadro 6 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Tasto riquadro 7 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Tasto riquadro 8 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Tasto riquadro 9 della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Quanto fare profondi i fiumi." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"A quale velocità si muovono le onde dei liquidi. Maggiore = più veloce.\n" +"Se negativa, le onde dei liquidi si sposteranno all'indietro.\n" +"Richiede l'abilitazione dei liquidi ondeggianti." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Quanto aspetterà il server prima di scaricare i blocchi mappa inutilizzati.\n" +"Con un valore più alto sarà più fluido, ma userà più RAM." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Decrementalo per aumentare la resistenza al movimento nel liquido." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Quanto fare larghi i fiumi." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Rumore di amalgama dell'umidità" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Rumore dell'umidità" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Variazione di umidità per i biomi." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "Server IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Se i FPS dovessero superare questo, limitarli con la sospensione\n" +"per non sprecare la potenza della CPU senza alcun beneficio." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Se disabilitata, viene utilizzato il tasto \"Speciale\" per volare " +"velocemente\n" +"se le modalità volo e corsa sono entrambe attive." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Se abilitata il server effettuerà l'occlusion culling dei blocchi mappa " +"basandosi\n" +"sulla posizione degli occhi del giocatore. Questo può ridurre del 50-80% il " +"numero dei blocchi\n" +"inviati al client. Il client non riceverà più la maggior parte degli " +"invisibili\n" +"cosicché l'utilità della modalità incorporea è ridotta." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Se abilitata assieme al volo, il giocatore può volare attraverso i nodi " +"solidi.\n" +"Richiede il privilegio \"noclip\" sul server." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Se abilitata, viene utilizzato il tasto \"Speciale\" invece di \"Furtivo\" " +"per\n" +"scendere e immergersi." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Abilita la conferma della registrazione quando ci si connette al server.\n" +"Se disabilitata, i nuovi account saranno registrati automaticamente." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Se abilitata, le azioni sono registrate per il ripristino.\n" +"Questa opzione viene letta solo all'avvio del server." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Se abilitata, disabilita la protezione anti-trucchi nel gioco in rete." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Se abilitata, i dati non validi del mondo non provocheranno lo spegnimento " +"del server.\n" +"Attivala solo se sai cosa stai facendo." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Se abilitata, rende le direzioni di movimento relative all'inclinazione del " +"giocatore quando vola o nuota." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Se abilitata, i nuovi giocatori non possono accedere con una password vuota." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Se abilitata, puoi mettere i blocchi nel punto (piedi + livello oculare) in " +"cui sei.\n" +"Questo è utile quando si lavora con nodebox in aree piccole." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Se la restrizione CSM per il raggio dei nodi è abilitata, le chiamate " +"get_node\n" +"sono limitate a questa distanza dal giocatore al nodo." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Se l'esecuzione del comando in chat impiega più tempo di quello specificato " +"in\n" +"secondi, aggiungi l'informazione sul tempo al messaggio di comando in chat" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Se la dimensione del file debug.txt supera il numero di Mb indicati in\n" +"questa impostazione quando viene aperto, il file viene rinominato in debug." +"txt.1,\n" +"eliminando un eventuale debug.txt.1 più vecchio.\n" +"debug.txt viene rinominato solo se c'è questa impostazione." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "Se impostata, i giocatori (ri)compariranno sempre alla posizione data." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ignorare gli errori del mondo" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Trasparenza dello sfondo della console di chat nel gioco (opacità, tra 0 e " +"255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Colore dello sfondo della console di chat nel gioco (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "Altezza della console di chat nel gioco, tra 0.1 (10%) e 1.0 (100%)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Tasto aum. volume" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Velocità verticale iniziale quando si salta, in nodi al secondo." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Predisporre incorporate.\n" +"Questo normalmente serve solo ai contributori principali" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "Predisporre i comandi della chat alla registrazione." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Predisporre le funzioni globali di callback alla registrazione.\n" +"(qualsiasi cosa tu passi a una funzione minetest.register_*())" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Predisporre la funzione di azione dei modificatori dei blocchi attivi alla " +"registrazione." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Predisporre la funzione di azione dei modificatori dei blocchi in " +"caricamento alla registrazione." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Predisporre i metodi delle entità alla registrazione." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Intervallo di salvataggio dei cambiamenti importanti nel mondo, fissato in " +"secondi." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Intervallo di invio dell'ora del giorno ai client." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animazioni degli oggetti dell'inventario" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Tasto inventario" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Invertire il mouse" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Inverte il movimento verticale del mouse." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Percorso del carattere corsivo" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Percorso del carattere corsivo a spaziatura fissa" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Tempo di vita delle entità oggetto" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Iterazioni" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Iterazioni della funzione ricorsiva.\n" +"Aumentarle aumenta l'ammontare del dettaglio fine,\n" +"ma aumenta anche il carico di elaborazione.\n" +"A iterazioni = 20 questo generatore di mappe ha un carico simile al " +"generatore di mappe v7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID del joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Intervallo di ripetizione del pulsante del joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "Punto cieco joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Sensibilità del tronco del joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Tipo di joystick" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Solo serie Julia.\n" +"Componente W della costante super complessa.\n" +"Altera la forma del frattale.\n" +"Non ha effetto su frattali 3D.\n" +"Spazia grossomodo da -2 a 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Solo serie Julia.\n" +"Componente X della costante supercomplessa.\n" +"Altara la forma del frattale.\n" +"Spazia grossomodo da -2 a 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Solo serie Julia.\n" +"Componente Y della costante supercomplessa.\n" +"Altera la forma del frattale.\n" +"Spazia grossomodo da -2 a 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Solo serie Julia.\n" +"Componente Z della costante supercomplessa.\n" +"Altera la forma del frattale.\n" +"Spazia grossomodo da -2 a 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Tasto salta" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Velocità di salto" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per diminuire il raggio visivo.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per abbassare il volume.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scavare.\n" +"Vedi http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per buttare l'oggetto attualmente selezionato.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per aumentare il raggio visivo.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per alzare il volume.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per saltare.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per correre in modalità veloce.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per muovere indietro il giocatore.\n" +"Disabiliterà anche l'avanzamento automatico, quando attivo.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per muovere in avanti il giocatore.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per muovere a sinistra il giocatore.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per muovere a destra il giocatore.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per silenziare il gioco.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per aprire la finestra di chat per inserire comandi.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per aprire la finestra di chat per inserire comandi locali.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per aprire la finestra di chat.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per aprire l'inventario.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per piazzare.\n" +"Vedi http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere l'11° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 12° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 13° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 14° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 15° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 16° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 17° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 18° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 19° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 20° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 21° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 22° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 23° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 24° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 25° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 26° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 27° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 28° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 29° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 30° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 31° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il 32° riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere l'ottavo riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il quinto riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il primo riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il quarto riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere l'oggetto successivo nella barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il nono riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere l'oggetto precedente nella barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il secondo riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il settimo riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il sesto riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il decimo riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il terzo riquadro della barra di scelta rapida.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per muoversi furtivamente.\n" +"Usato anche per scendere, e per immergersi in acqua se aux1_descends è " +"disattivato.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per passare tra la telecamera in prima o terza persona.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scattare gli screenshot.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere l'avanzamento automatico.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere la modalità cinematic.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere la visualizzazione della minimappa.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere la modalità veloce.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il volo.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere la modalità incorporea.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere la modalità di inclinazione del movimento. \n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto di scelta dell'aggiornamento della telecamera. Usato solo per lo " +"sviluppo.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere la visualizzazione della chat.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere la visualizzazione delle informazioni di debug.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per attivare/disattivare la visualizzazione della nebbia.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per attivare/disattivare la visualizzazione dell'HUD.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere la visualizzazione della console grande di chat.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere la visualizzazione del generatore di profili. Usato per " +"lo sviluppo.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per scegliere il raggio visivo illimitato.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tasto per usare l'ingrandimento della visuale quando possibile.\n" +"Si veda http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" +"Allontana i giocatori che hanno inviato più di X messaggi in 10 secondi." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Ripidità dei laghi" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Soglia dei laghi" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Lingua" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Profondità delle caverne grandi" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Numero massimo di grotte di grandi dimensioni" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Numero minimo di caverne di grandi dimensioni" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Proporzione inondata della grotta grande" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Tasto console grande di chat" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Stile foglie" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Stile foglie:\n" +"- Di qualità: tutte le facce sono visibili\n" +"- Semplice: solo le facce esterne, se sono usate le special_tiles " +"definite\n" +"- Opache: disabilita la trasparenza" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Tasto sin." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Durata di uno scatto del server e intervallo con cui gli oggetti\n" +"sono aggiornati in generale sulla rete." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Lunghezza delle onde dei liquidi.\n" +"Richiede l'attivazione dei liquidi ondeggianti." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" +"Durata di tempo tra i cicli di esecuzione dei modificatori dei blocchi " +"attivi (ABM)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Intervallo di tempo tra l'esecuzione dei cicli del NodeTimer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Durata di tempo tra cicli di gestione del blocco attivo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Livello di registro da scriversi su debug.txt:\n" +"- <niente> (nessun registro)\n" +"- none (nessuno) (messaggi senza livello)\n" +"- error (errore)\n" +"- warning (avviso)\n" +"- action (azione)\n" +"- info (informazione)\n" +"- verbose (verboso)" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Aumento della curva di luce" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Centro dell'aumento della curva di luce" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Diffusione dell'aumento della curva di luce" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Gamma della curva di luce" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Gradiente alto della curva di luce" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Gradiente basso della curva di luce" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Illuminazione Uniforme" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Limite della generazione della mappa, in nodi, in tutte e sei le direzioni " +"da (0,0,0).\n" +"Sono generati solo i pezzi di mappa completamente all'interno del limite del " +"generatore di mappe.\n" +"Il valore è immagazzinato per ciascun mondo." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Limita il numero di richieste HTTP parallele. Influisce su:\n" +"- Recupero dei file multimediali se il server usa l'impostazione " +"remote_media.\n" +"- Scaricamento dell'elenco dei server e annuncio del server.\n" +"- Scaricamenti effettuati dal menu principale (per es. il gestore mod.).\n" +"Ha effetto solo se compilato con cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Fluidità del liquido" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Omogeneizzazione della fluidità del liquido" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Max ripetizioni del liquido" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Tempo di svuotamento della coda del liquido" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Velocità di affondamento nel liquido" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Intervallo in secondi di aggiornamento del liquido." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Scatto di aggiornamento del liquido" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Caricare il generatore di profili del gioco" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Caricare il generatore di profili del gioco per raccogliere dati di " +"profilo.\n" +"Fornisce un comando /profiler per accedere al profilo compilato.\n" +"Utile per sviluppatori di moduli e operatori di server." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Modificatori del blocco in caricamento" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Limite inferiore Y dei sotterranei." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Limite inferiore Y delle terre fluttuanti." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Script del menu principale" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Far sì che i colori di nebbia e cielo dipendano da ora del giorno (alba/" +"tramonto) e direzione della visuale." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Rende opachi tutti i liquidi" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Livello di compressione della mappa per l'archiviazione su disco" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Livello di compressione della mappa per il trasferimento in rete" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Indirizzo della mappa" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" +"Attributi di generazione della mappa specifici del generatore di mappe " +"Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Attributi di generazione della mappa specifici del generatore di mappe " +"Flat.\n" +"Al mondo piatto possono essere aggiunti laghi e colline occasionali." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Attributi di generazione della mappa specifici del generatore di mappe " +"frattale.\n" +"'terrain' abilita la generazione di terreno non-frattale:\n" +"oceano, isole e sottoterra." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Attributi di generazione della mappa specifici del generatore di mappe " +"Valleys.\n" +"\"altitude_chill\": riduce il calore con l'altitudine.\n" +"\"humid_rivers\": aumenta l'umidità attorno ai fiumi.\n" +"\"vary_river_depth\": se abilitato, bassa umidità e calore alto provocano\n" +"l'abbassamento del livello dei fiumi e saltuariamente le secche.\n" +"\"altitude_dry\": riduce l'umidità con l'altitudine." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" +"Attributi di generazione della mappa specifici del generatore di mappe v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Attributi di generazione della mappa specifici del generatore di mappe v6.\n" +"Il valore \"snowbiomes\" abilita il nuovo sistema di 5 biomi.\n" +"Quando è abilitato,le giungle sono abilitate automaticamente \n" +"e il valore \"jungles\" viene ignorato." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Attributi di generazione mappa specifici per il generatore di mappe v7.\n" +"'ridges': fiumi.\n" +"'floatlands': masse di terra fluttuanti nell'atmosfera.\n" +"'caverns': caverne giganti profondamente sottoterra." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Limite di generazione della mappa" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Intervallo di salvataggio della mappa" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "Frame di aggiornamento delle mappe d'ombra" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Limite dei blocchi mappa" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Ritardo di generazione della mesh del blocco mappa" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Dimensione in MB del generatore mesh del blocco mappa" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Scadenza dello scaricamento del blocco mappa" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Generatore mappe Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Valori specifici del generatore di mappe Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Generatore mappe Flat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Valori specifici del generatore di mappe Flat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Generatore di mappe Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Valori specifici del generatore di mappe frattale" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Generatore di mappe v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Valori specifici del generatore di mappe v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Generatore di mappe v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Valori specifici del generatore di mappe v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Generatore di mappe v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Valori specifici del generatore di mappe v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Generatore di mappe Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Valori specifici del generatore di mappe Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Debug del generatore mappa" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Nome del generatore mappa" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Distanza massima di generazione dei blocchi" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Distanza massima di invio dei blocchi" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Numero massimo di liquidi elaborati per passo." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Blocchi extra massimi per clearobjects" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Numero massimo di pacchetti per iterazione" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "FPS massimi" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"FPS massimi quando la finestra è in secondo piano o quando il gioco è in " +"pausa." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Distanza massima per renderizzare le ombre." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Numero massimo di blocchi caricati a forza" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Larghezza massima della barra di scelta rapida" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" +"Limite massimo di grotte casuali di grandi dimensioni per pezzo di mappa." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "Limite massimo di piccole grotte casuali per pezzo di mappa." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Resistenza massima dei liquidi. Controlla la decelerazione \n" +"quando si entra ad alta velocità in un liquido." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Numero massimo di blocchi inviati simultaneamente per client.\n" +"Il conto totale massimo è calcolato dinamicamente:\n" +"tot_max = arrotonda((N°client + max_utenti) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" +"Numero massimo di blocchi che possono essere accodati per il caricamento." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Numero massimo di blocchi da accodarsi che devono essere generati.\n" +"Questo limite viene imposto per ciascun giocatore." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Numero massimo di blocchi da accodarsi che devono essere caricati da file.\n" +"Questo limite viene imposto per ciascun giocatore." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Numero massimo di download simultanei. I download che superano questo limite " +"verranno messi in coda.\n" +"Dovrebbe essere inferiore a curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Numero massimo di blocchi mappa caricati a forza." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Numero massimo di blocchi mappa per il client da tenere in memoria.\n" +"Imposta a -1 per una quantità illimitata." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Numero massimo di pacchetti inviati per passo di invio, se hai una " +"connessione\n" +"lenta prova a ridurlo, ma non ridurlo a un numero inferiore al doppio del " +"numero\n" +"dei client interessati." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" +"Numero massimo di giocatori che possono essere connessi simultaneamente." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Numero massimo di messaggi recenti della chat da visualizzare" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Numero massimo di oggetti immagazzinati staticamente in un blocco." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Oggetti massimi per blocco" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Porzione massima della finestra attuale da usarsi per la barra di scelta " +"rapida.\n" +"Utile se c'è qualcosa da mostrare a destra o sinistra della barra." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Invii simultanei massimi di blocchi per client" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Dimensione massima della coda esterna della chat" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Dimensione massima della coda esterna della chat.\n" +"0 per disabilitare l'accodamento e -1 per rendere illimitata la dimensione " +"della coda." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Tempo massimo in millisecondi che può richiedere lo scaricamento di un file " +"(es. un mod)." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Tempo massimo che può richiedere una richiesta interattiva (es. lista presa " +"dal server), dichiarato in secondi." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Utenti massimi" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Cache mesh" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Messaggio del giorno" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Messaggio del giorno mostrato ai giocatori che si connettono." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Metodo usato per evidenziare l'oggetto scelto." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Livello di registro minimo da scriversi nell'area di messaggistica." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Minimappa" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Tasto minimappa" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Altezza di scansione della minimappa" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" +"Limite minimo di grotte casuali di grandi dimensioni per pezzo di mappa." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Limite minimo di piccole grotte casuali per pezzo di mappa." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Dimensione minima della texture" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "MIP mapping" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Generatore di profili" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Sicurezza" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Canali mod" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Modifica la dimensione degli elementi dello HUD." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Percorso del carattere a spaziatura fissa" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Dimensione del carattere a spaziatura fissa" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "Dimensione del carattere a spaziatura fissa divisibile per" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Rumore dell'altezza montana" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Rumore montano" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Rumore di variazione montano" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Livello zero montano" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Sensibilità del mouse" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Moltiplicatore della sensibilità del mouse." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Rumore del fango" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Moltiplicatore per l'ondeggiamento in caduta.\n" +"Per esempio: 0 per nessun ondeggiamento visivo, 1.0 normale, 2.0 doppio." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Tasto muta" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Silenzia audio" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Nome del generatore mappa da usare alla creazione di un nuovo mondo.\n" +"Non viene usato se si crea un mondo nel menu principale.\n" +"Generatori mappe attualmente molto instabili:\n" +"- 'floatlands' in v7 (disabilitato per impostazione predefinita)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Nome del giocatore.\n" +"Quando si esegue un server, i client che si connettono con questo nome sono " +"amministratori.\n" +"Quando si avvia dal menu principale, questo viene scavalcato." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Nome del server, da mostrare quando si connettono i giocatori e nell'elenco " +"dei server." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Piano vicino" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Porta di rete da ascoltare (UDP).\n" +"Questo valore verrà scavalcato quando si avvia dal menu principale." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Rete" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "I nuovi utenti devono immettere questa password." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Incorporeo" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Tasto incorporeo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Evidenziatura dei Nodi" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Evidenziamento nodo" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Intervallo NodeTimer" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Rumori" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Numero di thread emerge" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Numero di thread di comparsa da usare.\n" +"Valore 0:\n" +"- Selezione automatica. Il numero di thread di comparsa sarà\n" +"- 'numero di processori - 2', con un limite inferiore di 1.\n" +"Qualsiasi altro valore:\n" +"- Specifica il numero di thread di comparsa, con un limite inferiore di " +"1.\n" +"AVVISO: Aumentare il numero dei thread di comparsa aumenta la velocità del " +"motore\n" +"del generatore di mappe, ma questo potrebbe danneggiare le prestazioni del " +"gioco interferendo con\n" +"altri processi, specialmente in modalità locale e/o quando si esegue codice " +"Lua in 'on_generated'.\n" +"Per molti utenti l'impostazione ottimale può essere '1'." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Numero di blocchi extra che possono essere caricati da /clearobjects in una " +"volta.\n" +"Questo è un compromesso tra spesa di transazione sqlite e\n" +"consumo di memoria (4096 = 100MB, come regola generale)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Liquidi opachi" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" +"Opacità (alfa) dell'ombra dietro il carattere predefinito, tra 0 e 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Apre il menu di pausa quando si perde la messa a fuoco della finestra. Non\n" +"mette in pausa se è aperta una finestra di dialogo." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Sovrascrittura opzionale per i colori dei link web in chat." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Percorso del carattere di riserva. Deve essere un carattere TrueType.\n" +"Questo carattere verrà utilizzato per alcune lingue o se il carattere " +"predefinito non è disponibile." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Percorso dove salvare gli screenshot. Può essere un percorso assoluto o " +"relativo.\n" +"La cartella sarà create se non esiste già." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Percorso dell'indirizzo degli shader. Se non se ne stabilisce nessuno, verrà " +"usato quello predefinito." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" +"Percorso dell'indirizzo contenente le textures. Tutte le textures vengono " +"cercate a partire da qui." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Percorso del carattere predefinito. Deve essere un carattere TrueType.\n" +"Il carattere di riserva verrà utilizzato se il carattere non può essere " +"caricato." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Percorso del carattere a spaziatura fissa. Deve essere un carattere " +"TrueType.\n" +"Questo carattere viene utilizzato ad es. per la console e lo schermo del " +"profilatore." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Pausa alla perdita di fuoco della finestra" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "Limite per giocatore di blocchi accodati per il caricamento dal disco" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Limite per giocatore di blocchi accodati da generare" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fisica" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Modalità inclinazione movimento" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Modalità inclinazione movimento" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Tasto piazza" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Intervallo di ripetizione per il piazzamento" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Il giocatore può volare senza essere soggetto alla gravità.\n" +"Ciò richiede il privilegio \"fly\" sul server." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Distanza di trasferimento del giocatore" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Giocatore contro giocatore" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Filtraggio Poisson" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Porta a cui connettersi (UDP).\n" +"Si noti che il campo della porta nel menu principale scavalca questa " +"impostazione." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Impedisce la ripetizione di scavo e posizionamento quando si tengono premuti " +"i pulsanti del mouse.\n" +"Abilitalo quando scavi o piazzi troppo spesso per sbaglio." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Impedisce che i mod facciano cose non sicure come eseguire comandi della " +"shell." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Stampare i dati di profilo del motore di gioco a intervalli regolari (in " +"secondi).\n" +"0 = disabilita. Utile per gli sviluppatori." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Privilegi che i giocatori con basic_privs possono concedere" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Generatore di profili" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Tasto di (dis)attivazione del generatore di profili" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Indirizzo del listener Prometheus" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Indirizzo del listener Prometheus.\n" +"Se Minetest viene compilato con l'opzione ENABLE_PROMETHEUS attivata,\n" +"abilita il listener delle statistiche per Prometheus su quell'indirizzo.\n" +"Le statistiche possono essere recuperate su http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" +"Proporzione delle grotte di grandi dimensioni che contiene del liquido." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Raggio dell'area delle nuvole fissato in numero di 64 nodi quadrati nuvola.\n" +"Valori maggiori di 26 cominceranno a produrre interruzioni appuntite agli " +"angoli delle aree nuvola." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Solleva il terreno per creare vallate attorno ai fiumi." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Dati in ingresso casuali" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Tasto di scelta del raggio" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Messaggi di chat recenti" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Percorso del carattere regolare" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "File multimediali remoti" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Porta remota" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Leva i codici di colore dai messaggi di chat in arrivo\n" +"Usalo per impedire ai giocatori di usare i colori nei loro messaggi" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Sostituisce il menu principale predefinito con uno personalizzato." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Percorso di rapporto" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Restringe l'accesso di certe funzioni lato-client sui server.\n" +"Combina i valori byte sottostanti per restringere le caratteristiche\n" +"lato-client, o imposta a 0 per nessuna restrizione:\n" +"LOAD_CLIENT_MODS: 1 (disabilita il caricamento di mod forniti dal client)\n" +"CHAT_MESSAGES: 2 (disabilita la chiamata di send_chat_message su lato-" +"client)\n" +"READ_ITEMDEFS: 4 (disabilita la chiamata di get_item_def su lato-client)\n" +"READ_NODEDEFS: 8 (disabilita la chiamata di get_node_def su lato-client)\n" +"LOOKUP_NODES_LIMIT: 16 (limita la chiamata get_node su lato-client a\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disabilita la chiamata di get_player_names su lato-" +"client)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Diffusione del rumore dei crinali montani" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Rumore dei crinali" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Rumore sottomarino dei crinali" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Dimensione del rumore dei crinali montani" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Tasto des." + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Profondità dell'alveo dei fiumi" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Larghezza dell'alveo dei fiumi" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Profondità dei fiumi" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Rumore dei fiumi" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Dimensione dei fiumi" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Larghezza delle valli dei fiumi" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Registrazione di ripristino" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Rumore della dimensione delle colline in serie" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Rumore della diffusione delle colline in serie" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Minimappa rotonda" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Scavo e piazzamento sicuri" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" +"Quando np_beach eccede questo valore si verificano le spiagge sabbiose." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Salvare su disco la mappa ricevuta dal client." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" +"Salvare automaticamente la dimensione della finestra quando viene modificata." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Salvataggio della mappa ricevuta dal server" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Ridimensionare l'interfaccia secondo un valore specificato dall'utente.\n" +"Usate un filtro nearest-neighbor-anti-alias per ridimensionare " +"l'interfaccia.\n" +"Questo liscerà alcuni degli spigoli vivi, e armonizzerà i pixel al\n" +"rimpicciolimento, al costo di sfocare alcuni pixel di punta\n" +"quando le immagini sono ridimensionate per valori frazionari." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Schermo:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Altezza dello schermo" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Larghezza dello schermo" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Cartella degli screenshot" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Formato degli screenshot" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Qualità degli screenshot" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Qualità degli screenshot. Usata solo per il formato JPEG.\n" +"1 significa la qualità peggiore, 100 quella migliore.\n" +"Usa 0 per la qualità predefinita." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Screenshot" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Rumore del fondale marino" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Secondo di 4 rumori 2D che insieme definiscono l'intervallo di altezza " +"collinare/montuoso." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Secondo di due rumori 3D che assieme definiscono le gallerie." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Si veda http://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Colore del bordo del riquadro di selezione (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Colore del riquadro di selezione" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Larghezza del riquadro di selezione" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Scegli uno dei 18 tipi di frattale.\n" +"1 = 4D Serie Mandelbrot \"arrotondata\".\n" +"2 = 4D Serie Julia \"arrotondata\".\n" +"3 = 4D Serie Mandelbrot \"squadrata\".\n" +"4 = 4D Serie Julia \"squadrata\".\n" +"5 = 4D Serie Mandelbrot \"cugino Mandy\".\n" +"6 = 4D Serie Julia \"cugino Mandy\".\n" +"7 = 4D Serie Mandelbrot \"variazione\".\n" +"8 = 4D Serie Julia \"variazione\".\n" +"9 = 3D Serie Mandelbrot \"Mandelbrot/Mandelbar\".\n" +"10 = 3D Serie Julia \"Mandelbrot/Mandelbar\".\n" +"11 = 3D Serie Mandelbrot \"Albero di Natale\".\n" +"12 = 3D Serie Julia \"Albero di Natale\".\n" +"13 = 3D Serie Mandelbrot \"Mandelbulb\".\n" +"14 = 3D Serie Julia \"Mandelbulb\".\n" +"15 = 3D Serie Mandelbrot \"Coseno Mandelbulb\".\n" +"16 = 3D Serie Julia \"Coseno Mandelbulb\".\n" +"17 = 4D Serie Mandelbrot \"Mandelbulb\".\n" +"18 = 4D Serie Julia \"Mandelbulb\"." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL del server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Nome del server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Descrizione del Server" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL del server" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Indirizzo del server" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Descrizione del server" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Nome del server" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Porta del server" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Occlusion culling su lato server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Porta del Server" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL dell'elenco dei server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "URL dell'elenco dei server" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "File dell'elenco dei server" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Imposta la Lingua. Lascia vuoto per usare la Lingua di sistema.\n" +"Dopo avere modificato questa impostazione è necessario il riavvio." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Imposta la lunghezza massima di caratteri di un messaggio di chat inviato " +"dai client." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Imposta l'intensità dell'ombra.\n" +"Un valore basso significa avere ombre chiare, un valore alto significa avere " +"ombre scure." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Imposta la dimensione del raggio delle ombre morbide.\n" +"Valori bassi significano ombre nitide, valori alti significano ombre " +"morbide.\n" +"Valore minimo: 1.0; Valore massimo: 10.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Imposta l'inclinazione dell'orbita del Sole/Luna in gradi.\n" +"Il valore 0 significa nessuna inclinazione/orbita verticale.\n" +"Valore minimo: 0.0; valore massimo: 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Impostata su vero abilita la Mappatura delle ombre.\n" +"Necessita l'attivazione degli shader." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Impostata su vero abilita le foglie ondeggianti.\n" +"Necessita l'attivazione degli shader." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Impostata su vero abilita i liquidi ondeggianti (come, ad esempio, " +"l'acqua).\n" +"Necessita l'attivazione degli shader." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Impostata su vero abilita le piante ondeggianti.\n" +"Necessita l'attivazione degli shader." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Imposta la qualità della textura dell'ombra a 32 bit.\n" +"Su falso, 16 bit di texture saranno utilizzati.\n" +"Questo può causare molti più artefatti nell'ombra." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Percorso shader" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Gli shader permettono l'utilizzo di effetti visivi avanzati e potrebbero " +"aumentare\n" +"le prestazioni su alcune schede video.\n" +"Ciò funziona solo col supporto video OpenGL." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Qualità filtro ombra" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" +"Distanza massima della mappa delle ombre nei nodi per renderizzare le ombre" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "Texture della mappa delle ombre in 32 bit" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Dimensione della texture della mappa d'ombra" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Scarto (in pixel) dell'ombreggiatura del carattere predefinito. Se è 0, " +"allora l'ombra non sarà disegnata." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "Intensità dell'ombra" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Forma della minimappa. Abilitata = rotonda, disabilitata = quadrata." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Mostra le informazioni di debug" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Mostrare le aree di selezione delle entità" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Mostra la casella di selezione delle entità\n" +"È necessario riavviare dopo aver cambiato questo." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Mostra lo sfondo dell'etichetta del nome per impostazione predefinita" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Messaggio di chiusura" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Dimensione dei pezzi di mappa generati dal generatore mappe, dichiarata in " +"blocchi mappa (16 nodi).\n" +"AVVISO: non c'è nessun beneficio, e ci sono diversi pericoli,\n" +"nell'aumentare questo valore al di sopra di 5.\n" +"Ridurre questo valore aumenta la densità di grotte e sotterranei.\n" +"L'alterazione di questo valore è per uso speciale, si raccomanda di\n" +"lasciarlo invariato." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Dimensione della cache del blocco mappa del generatore della mesh.\n" +"Aumentandola si incrementerà l'impatto percentuale sulla cache, diminuendo\n" +"i dati copiati dal thread principale, riducendo così lo sfarfallio." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Inclinazione dell'orbita di un corpo celeste" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Fetta w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Pendenza e riempimento lavorano assieme per modificare le altezze." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Numero massimo di grotte piccole" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Numero minimo di grotte piccole" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" +"Variazione dell'umidità su piccola scala per l'amalgama dei biomi sui bordi." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" +"Variazione della temperatura su piccola scala per l'amalgama dei biomi sui " +"bordi." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Illuminazione uniforme" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Rende fluida la telecamera quando si guarda attorno. Chiamata anche visione\n" +"o mouse fluido. Utile per la registrazione di video." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"Rende fluida la rotazione della telecamera in modalità cinematic. 0 per " +"disattivare." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Rende fluida la rotazione della telecamera. 0 per disattivare." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Tasto furtivo" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Velocità furtiva" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Velocità furtiva, in nodi al secondo." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Raggio dell'ombra morbida" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Audio" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Specifica l'URL da cui il client recupera i file multimediali invece di " +"usare UDP.\n" +"$filename dovrebbe essere accessibile da $remote_media$filename tramite\n" +"cURL (ovviamente, remote_media dovrebbe finire con una barra).\n" +"I file che non sono presenti saranno recuperati nel solito modo." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Fissa la dimensione predefinita della pila di nodi, oggetti e strumenti.\n" +"Si noti che mod o giochi possono impostare esplicitamente una pila per " +"alcuni (o tutti) gli oggetti." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Diffondi un aggiornamento completo della mappa d'ombra su un certo numero di " +"frame.\n" +"Valori alti potrebbero rendere le ombre laggose, valori bassi\n" +"consumeranno più risorse.\n" +"Valore minimo: 1; valore massimo: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Diffusione dell'aumento mediano della curva di luce.\n" +"Controlla l'ampiezza del raggio da aumentare.\n" +"Scostamento tipo dell'aumento della curva di luce gaussiano." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Punto statico di comparsa" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Rumore della ripidità" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Rumore della dimensione del passo montano" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Rumore della diffusione del passo montano" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Intensità della parallasse della modalità 3D." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Intensità dell'incremento della curva di luce.\n" +"I 3 parametri \"incremento\" definiscono un intervallo della luce\n" +"che ne potenzia la luminosità." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Controllo severo del protocollo" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Elimina i codici di colore" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Livello di superficie dell'aqua facoltativa posizionata su uno strato solido " +"di terra fluttuante.\n" +"L'acqua è disabilitata in modo predefinito e sarà posizionata se questo " +"valore è impostato\n" +"al di sopra di 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (l'inizio " +"dell'affusolamento\n" +"superiore).\n" +"***AVVISO, PERICOLO POTENZIALE PER MONDI E PRESTAZIONI SERVER***:\n" +"Quando si abilita il posizionamento dell'acqua, le terre fluttuanti devono " +"essere configurate e verificate\n" +"per essere uno strato solido impostando 'mgv7_floatland_density' a 2.0 (o un " +"altro\n" +"valore richiesto dipendentemente da 'mgv7_np_floatland', per evitare\n" +"flussi d'acqua estremamente intensi per il server e per evitare vasti " +"allagamenti\n" +"della superficie del mondo sottostante." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "SQLite sincronizzato" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Variazione di temperatura per i biomi." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Impostazioni" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Rumore alternativo del terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Rumore di base del terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Altezza del terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Rumore superiore del terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Rumore del terreno" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Soglia di rumore del terreno per le colline.\n" +"Controlla la porzione d'area del mondo ricoperta da colline.\n" +"Aggiustare verso 0.0 per una porzione più ampia." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Soglia di rumore del terreno per i laghi.\n" +"Controlla la porzione d'area del mondo ricoperta da laghi.\n" +"Aggiustare verso 0.0 per una porzione più ampia." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Rumore di continuità del terreno" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Percorso delle texture" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Dimensione della texture su cui renderizzare la mappa d'ombra.\n" +"Questa deve essere una potenza di due.\n" +"Valori alti creano ombre migliori ma è anche molto costoso." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Le textures su un nodo possono essere allineate sia al nodo che al mondo.\n" +"Il primo modo si addice meglio a cose come macchine, arredamento, ecc.,\n" +"mentre il secondo fa sì che scale e microblocchi si adattino meglio ai " +"dintorni.\n" +"Comunque, dato che questa possibilità è nuova, automaticamente potrebbe non " +"essere usata dai server più vecchi,\n" +"questa opzione consente di imporla per alcuni tipi di nodo. Si noti però\n" +"che questa è considerata SPERIMENTALE e potrebbe non funzionare bene." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "L'URL per il deposito dei contenuti" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "Il punto cieco del joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Il formato predefinito in cui si salvano i profili,\n" +"quando si chiama \"/profiler save [format]\" senza formato." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "La profondità della terra o altri riempitori del bioma." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"Il percorso del file relativo al percorso del vostro mondo in cui saranno " +"salvati i profili." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "L'identificatore del joystick da usare" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "La distanza in pixel richiesta per avviare l'interazione touch screen." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"L'altezza massima della superficie dei liquidi ondulanti.\n" +"4.0 = L'altezza dell'onda è di due nodi.\n" +"0.0 = L'onda non si muove affatto.\n" +"Il valore predefinito è 1.0 (1/2 nodo).\n" +"Richiede l'abilitazione dei liquidi ondulanti." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "Su quale interfaccia di rete sarà in ascolto il server." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"I privilegi ricevuti automaticamente dai nuovi utenti.\n" +"Si veda /privs in gioco per un elenco completo sul vostro server e la " +"configurazione dei mod." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"Il raggio del volume di blocchi attorno ciascun giocatore che è soggetto\n" +"alle cose del blocco attivo, dichiarata in blocchi mappa (16 nodi).\n" +"Nei blocchi attivi vengono caricati gli oggetti ed eseguiti gli ABM.\n" +"Questo è anche l'intervallo minimo in cui sono mantenuti gli oggetti attivi " +"(mob).\n" +"Questo dovrebbe essere configurato assieme ad " +"active_object_send_range_blocks." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"Il rendering di back-end.\n" +"Dopo averlo cambiato è necessario un riavvio.\n" +"Nota: su Android, restare con OGLES1 se incerti! Altrimenti l'app potrebbe " +"non partire.\n" +"Su altre piattaforme, si raccomanda OpenGL\n" +"Gli shader sono supportati da OpenGL (solo su desktop) e OGLES2 " +"(sperimentale)" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"La sensibilità degli assi del joystick per spostare\n" +"il campo visivo nel gioco." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"L'intensità (oscurità) dell'ombreggiatura di occlusione ambientale dei " +"nodi.\n" +"Minore è più scura, maggiore è più chiara. L'intervallo di valori validi " +"per\n" +"questa impostazione è tra 0.25 e 4.0 inclusi. Se il valore è fuori " +"intervallo\n" +"verrà impostato sul valore valido più vicino." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Il tempo (in secondi) in cui la coda dei liquidi può crescere oltre alla " +"capacità\n" +"di elaborazione finché viene fatto un tentativo di diminuirne la dimensione\n" +"scaricando gli oggetti della vecchia coda. Un valore di 0 disabilita la " +"funzionalità." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"Il budget di tempo ha consentito agli ABM per eseguire ogni passaggio\n" +"(come frazione dell'intervallo ABM)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Il tempo in secondi richiesto tra eventi ripetuti quando\n" +"si tiene premuta una combinazione di pulsanti del joystick." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Il tempo in secondi che intercorre tra il piazzamento dei nodi quando si " +"tiene\n" +"premuto il pulsante piazza." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Il tipo di joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"La distanza verticale oltre la quale il calore diminuisce di 20 se " +"\"altitude_chill\"\n" +"è abilitata. Rappresenta anche la distanza verticale oltre cui l'umidità\n" +"diminuisce di 10 se \"altitude_dry\" è abilitata." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Terzo di 4 rumori 2D che insieme definiscono l'intervallo di altezza " +"collinare/montuoso." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Tempo di vita in secondi per le entità oggetto (oggetti buttati).\n" +"Impostandola a -1 disabilita la caratteristica." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" +"Ora del giorno in cui è avviato un nuovo mondo, in millesimi di ora " +"(0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Intervallo del tempo di invio" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Velocità del tempo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Scadenza per il client per rimuovere dalla memoria dati mappa inutilizzati." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Per ridurre il ritardo, i trasferimenti di blocchi sono rallentati quando un " +"giocatore sta costruendo qualcosa.\n" +"Ciò determina per quanto a lungo sono rallentati dopo avere posizionato o " +"rimosso un nodo." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Tasto di (dis)attivazione della modalità telecamera" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Ritardo dei suggerimenti" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Soglia del touch screen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Soglia del touch screen" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "Compromessi per migliorare le prestazioni" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Rumore degli alberi" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Filtraggio trilineare" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"Vero = 256\n" +"Falso = 128\n" +"Utilizzabile per rendere più fluida la minimappa su macchine più lente." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Moduli fidati" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL per l'elenco dei server mostrato nella scheda del gioco in rete." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Sotto-campionamento" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Il sotto-campionamento è analogo all'uso di una risoluzione schermo " +"inferiore,\n" +"ma è applicato solo al mondo di gioco, mantenendo intatta l'interfaccia " +"utente.\n" +"Dovrebbe dare un aumento di prestazioni significativo al costo di immagini " +"meno dettagliate.\n" +"Più si aumenta il valore, meno dettagliata sarà l'immagine." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Distanza di trasferimento giocatore illimitata" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Scaricare i dati server inutilizzati" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Livello Y superiore dei sotterranei." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Livello Y superiore delle terre fluttuanti." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Usare l'aspetto 3D per le nuvole invece di quello piatto." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Usare un'animazione con le nuvole per lo sfondo del menu principale." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" +"Usare il filtraggio anisotropico quando si guardano le textures da " +"un'angolazione." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Usare il filtraggio bilineare quando si ridimensionano le textures." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Usare il mipmapping per ridimensionare le textures. Potrebbe aumentare " +"leggermente le prestazioni,\n" +"specialmente quando si utilizza un pacchetto di texture ad alta " +"risoluzione.\n" +"Il ridimensionamento mediante downscaling gamma-corretto non è supportato." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Utilizzare l'antialiasing multi-campione (MSAA) per smussare i bordi del " +"blocco.\n" +"Questo algoritmo uniforma la visualizzazione 3D mantenendo l'immagine " +"nitida,\n" +"ma non influenza l'interno delle textures\n" +"(che è particolarmente evidente con trame trasparenti).\n" +"Gli spazi visibili appaiono tra i nodi quando gli shader sono disabilitati.\n" +"Se impostato a 0, MSAA è disabilitato.\n" +"È necessario riavviare dopo aver modificato questa opzione." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Usare il filtraggio trilineare quando si ridimensionano le textures." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Sincronia verticale" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Profondità valli" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Riempimento valli" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Profilo valli" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Pendenza valli" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Variazione della profondità del riempitore del bioma." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Variazione dell'altezza montana massima (in nodi)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Variazione del numero di caverne." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Variazione della scala verticale del terreno.\n" +"Il terreno è quasi piatto quando il rumore è inferiore a -0.55." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Varia la profondità dei nodi di superficie del bioma." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Varia l'asprezza del terreno.\n" +"Determina il valore 'persistence' (continuità) per i rumori di terrain_base " +"e terrain_alt." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Varia la ripidità dei dirupi." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Velocità di scalata, in nodi al secondo." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Sincronizzazione verticale dello schermo." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Driver video" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Fattore di ondeggiamento visivo" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Distanza visiva in nodi." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Tasto diminuzione raggio visivo" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Tasto aumento raggio visivo" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Tasto ingrandimento visuale" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Raggio visivo" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "Il joystick virtuale aziona il pulsante \"Speciale\"" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Volume" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Volume dei suoni.\n" +"Necessita l'attivazione dell'audio." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Coordinata W della fetta in 3D generata di un frattale in 4D.\n" +"Determina quale fetta in 3D viene generata della forma in 4D.\n" +"Altera la forma del frattale.\n" +"Non ha effetto su frattali in 3D.\n" +"Spazia grossomodo tra -2 e 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Velocità a terra o in volo, in nodi al secondo." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Velocità di cammino" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Velocità sul terreno, in volo e in scalata con modalità rapida, in nodi al " +"secondo." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Livello dell'acqua" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Livello di superficie dell'acqua del mondo." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Nodi ondeggianti" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Foglie ondeggianti" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Liquidi ondeggianti" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Altezza dell'onda dei liquidi ondeggianti" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Velocità dell'onda dei liquidi ondeggianti" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Lunghezza d'onda dei liquidi ondulanti" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Piante ondeggianti" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "Colore del link web" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Quando gui_scaling_filter è Vero, tutte le immagini dell'interfaccia\n" +"necessitano il filtraggio software, ma alcune immagini sono generate\n" +"direttamente dall'hardware (es. render-to-texture per i nodi " +"nell'inventario)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Quando gui_scaling_filter_txr2img è Vero, copia quelle immagini\n" +"dall'hardware al software per il ridimensionamento. Quando è Falso,\n" +"ripiega sul vecchio metodo di ridimensionamento, per i driver video che\n" +"non supportano correttamente lo scaricamento delle textures dall'hardware." + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Quando si usano i filtri bilineare/trilineare/anisotropico, le textures a " +"bassa risoluzione possono\n" +"essere sfocate, così viene eseguito l'ingrandimento automatico con " +"l'interpolazione\n" +"nearest-neighbor per conservare la chiarezza dei pixels. Questa opzione " +"imposta la dimensione\n" +"minima per le textures ingrandite; valori superiori permettono un aspetto " +"più nitido, ma richiedono\n" +"più memoria. Sono raccomandate le potenze di 2. Questa impostazione si " +"attiva SOLO SE il filtraggio\n" +"bilineare/trilineare/anisotropico è abilitato.\n" +"Viene anche utilizzata come dimensione di base delle texturesdei nodi per " +"l'auto-ridimensionamento\n" +"delle textures con allineamento relativo al mondo." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Se lo sfondo dell'etichetta del nome debba essere mostrato per impostazione " +"predefinita.\n" +"Le mod possono comunque impostare uno sfondo." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"Se le animazioni delle texture dei nodi dovrebbero essere asincrone per " +"blocco mappa." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Se i giocatori vengono mostrati ai client senza alcun limite di raggio.\n" +"Deprecata, usa invece l'impostazione player_transfer_distance." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Se permettere ai giocatori di ferirsi e uccidersi a vicenda." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Se chiedere ai client di riconnettersi dopo un crash (Lua).\n" +"Impostatela su Vero se il vostro server è configurato per riavviarsi " +"automaticamente." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Se annebbiare o meno la fine dell'area visibile." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Se silenziare i suoni. È possibile de-silenziare i suoni in qualsiasi " +"momento, a meno che\n" +"il sistema audio non sia disabilitato (enable_sound=false).\n" +"Nel gioco, puoi alternare lo stato silenziato col tasto muta o usando\n" +"il menu di pausa." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"Se mostrare le informazioni di debug del client (ha lo stesso effetto di " +"premere F5)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Componente larghezza della dimensione iniziale della finestra. Ignorata in " +"modalità a schermo intero." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Larghezza delle linee dei riquadri di selezione attorno ai nodi." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Solo per sistemi Windows: avviare Minetest con la finestra della riga di " +"comando sullo sfondo.\n" +"Contiene le stesse informazioni del file debug.txt (nome predefinito)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Indirizzo del mondo (ogni cosa nel mondo viene immagazzinata qui).\n" +"Non necessaria se si avvia dal menu principale." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Ora di avvio del mondo" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Le textures allineate al mondo possono essere ridimensionate per estendersi " +"su diversi nodi.\n" +"Tuttavia, il server potrebbe non inviare le dimensioni desiderate, " +"specialmente se è in uso un\n" +"pacchetto texture progettato in modo specifico; con questa opzione, il " +"client prova a stabilire\n" +"automaticamente le dimensioni basandosi sulla grandezza della texture.\n" +"Si veda anche texture_min_size.\n" +"Avviso: questa opzione è SPERIMENTALE!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Modalità delle textures allineate al mondo" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y del terreno piatto." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y del livello zero della densità del dislivello montano. Usato per spostare " +"verticalmente le montagne." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Y del limite superiore delle caverne grandi." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Distanza Y sopra cui le caverne si espandono a piena grandezza." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Distanza-Y sopra cui le terre fluttuanti si affusolano dalla piena densità a " +"niente.\n" +"L'affusolamento comincia a questa distanza dal limite Y.\n" +"Per uno strato solido di terra fluttuante, questo controlla l'altezza di " +"colline/montagne.\n" +"Dev'essere inferiore o uguale alla metà della distanza tra i limiti Y." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Livello Y della superficie media del terreno." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Livello Y del limite superiore delle caverne." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Livello Y del terreno superiore che crea dirupi." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Livello Y del terreno inferiore e del fondale marino." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Livello Y del fondale marino." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Scadenza cURL scaricamento file" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "Scadenza interattiva cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Limite parallelo cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Modalità creativa: " + +#~ msgid "- Damage: " +#~ msgstr "- Ferimento: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = occlusione di parallasse con informazione di inclinazione (più " +#~ "veloce).\n" +#~ "1 = relief mapping (più lenta, più accurata)." + +#~ msgid "Address / Port" +#~ msgstr "Indirizzo / Porta" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Regola la codifica della gamma per le tabelle della luce. Numeri maggiori " +#~ "sono più chiari.\n" +#~ "Questa impostazione è solo per il client ed è ignorata dal server." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "" +#~ "Modifica il restringimento superiore e inferiore rispetto al punto " +#~ "mediano delle terre fluttuanti di tipo montagnoso." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Sei sicuro di azzerare il tuo mondo locale?" + +#~ msgid "Back" +#~ msgstr "Indietro" + +#~ msgid "Basic" +#~ msgstr "Base" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bit per pixel (o profondità di colore) in modalità schermo intero." + +#~ msgid "Bump Mapping" +#~ msgstr "Bump Mapping" + +#~ msgid "Bumpmapping" +#~ msgstr "Bumpmapping" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "Centro dell'aumento mediano della curva della luce." + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Cambia l'UI del menu principale:\n" +#~ "- Completa: mondi locali multipli, scelta del gioco, selettore " +#~ "pacchetti texture, ecc.\n" +#~ "- Semplice: un mondo locale, nessun selettore di gioco o pacchetti " +#~ "grafici.\n" +#~ "Potrebbe servire per gli schermi più piccoli." + +#~ msgid "Config mods" +#~ msgstr "Config mod" + +#~ msgid "Configure" +#~ msgstr "Configura" + +#~ msgid "Connect" +#~ msgstr "Connettiti" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Controlla la velocità di affondamento nei liquidi." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Controlla la densità delle terre fluttuanti di tipo montuoso.\n" +#~ "È uno spostamento di rumore aggiunto al valore del rumore " +#~ "'mgv7_np_mountain'." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Controlla la larghezza delle gallerie, un valore più piccolo crea " +#~ "gallerie più larghe." + +#~ msgid "Credits" +#~ msgstr "Riconoscimenti" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Colore del mirino (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Danno fisico abilitato" + +#~ msgid "Darkness sharpness" +#~ msgstr "Nitidezza dell'oscurità" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Scadenza predefinita per cURL, fissata in millisecondi.\n" +#~ "Ha effetto solo se Minetest è stato compilato con cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Definisce aree di terreno uniforme nelle terre fluttuanti.\n" +#~ "Le terre fluttuanti uniformi avvengono quando il rumore è > 0." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Stabilisce il passo di campionamento della texture.\n" +#~ "Un valore maggiore dà normalmap più uniformi." + +#~ msgid "Del. Favorite" +#~ msgstr "Elimina il Preferito" + +#~ msgid "" +#~ "Deprecated, define and locate cave liquids using biome definitions " +#~ "instead.\n" +#~ "Y of upper limit of lava in large caves." +#~ msgstr "" +#~ "Sconsigliato, va usata la definizione del bioma per definire e " +#~ "posizionare le caverne di liquido.\n" +#~ "Limite verticale della lava nelle caverne grandi." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Scarica un gioco, come Minetest Game, da minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Scaricane uno da minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Scaricamento e installazione di $1, attendere prego..." + +#~ msgid "Enable VBO" +#~ msgstr "Abilitare i VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "Abilita conferma registrazione" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Attiva il bumpmapping per le texture. È necessario fornire le normalmap\n" +#~ "con i pacchetti texture, o devono essere generate automaticamente.\n" +#~ "Necessita l'attivazione degli shader." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Attiva il filmic tone mapping" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Attiva la generazione istantanea delle normalmap (effetto rilievo).\n" +#~ "Necessita l'attivazione del bumpmapping." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Attiva la parallax occlusion mapping.\n" +#~ "Necessita l'attivazione degli shader." + +#~ msgid "Enter " +#~ msgstr "Inserisci " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Opzione sperimentale, potrebbe causare spazi visibili tra i blocchi\n" +#~ "quando impostata su numeri maggiori di 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS nel menu di pausa" + +#~ msgid "Fallback font shadow" +#~ msgstr "Ombreggiatura del carattere di ripiego" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Trasparenza del carattere di ripiego" + +#~ msgid "Fallback font size" +#~ msgstr "Dimensione del carattere di ripiego" + +#~ msgid "Filtering" +#~ msgstr "Filtraggio" + +#~ msgid "Floatland base height noise" +#~ msgstr "Rumore base dell'altezza delle terre fluttuanti" + +#~ msgid "Floatland mountain height" +#~ msgstr "Altezza delle montagne delle terre fluttuanti" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Trasparenza ombreggiatura carattere (opacità, tra 0 e 255)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Dimensione carattere del carattere di ripiego, in punti (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "Caratteri FreeType" + +#~ msgid "Full screen BPP" +#~ msgstr "BPP dello schermo intero" + +#~ msgid "Game" +#~ msgstr "Gioco" + +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Genera Normal Map" + +#~ msgid "Generate normalmaps" +#~ msgstr "Generare le normalmap" + +#~ msgid "HUD scale factor" +#~ msgstr "Fattore di scala dell'HUD" + +#~ msgid "High-precision FPU" +#~ msgstr "FPU ad alta precisione" + +#~ msgid "IPv6 support." +#~ msgstr "Supporto IPv6." + +#~ msgid "In-Game" +#~ msgstr "Nel gioco" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Install: File: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Predisposizione" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Associamenti tasti. (Se questo menu si incasina, togli roba da minetest." +#~ "conf)" + +#~ msgid "Lava depth" +#~ msgstr "Profondità della lava" + +#~ msgid "Lightness sharpness" +#~ msgstr "Nitidezza della luminosità" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Limite di code emerge su disco" + +#~ msgid "Main" +#~ msgstr "Principale" + +#~ msgid "Main menu style" +#~ msgstr "Stile del menu principale" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "Fa lavorare DirectX con LuaJIT. Disabilitare se provoca problemi." + +#~ msgid "Menus" +#~ msgstr "Menu" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Minimappa in modalità radar, ingrandimento x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Minimappa in modalità radar, ingrandimento x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Minimappa in modalità superficie, ingrandimento x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Minimappa in modalità superficie, ingrandimento x4" + +#~ msgid "Name / Password" +#~ msgstr "Nome / Password" + +#~ msgid "Name/Password" +#~ msgstr "Nome/Password" + +#~ msgid "No" +#~ msgstr "No" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Campionamento normalmap" + +#~ msgid "Normalmaps strength" +#~ msgstr "Intensità normalmap" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Numero di iterazioni dell'occlusione di parallasse." + +#~ msgid "Ok" +#~ msgstr "OK" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "" +#~ "Opacità (alfa) dell'ombra dietro il carattere di riserva, tra 0 e 255." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "" +#~ "Deviazione complessiva dell'effetto di occlusione di parallasse, " +#~ "solitamente scala/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Scala globale dell'effetto di occlusione di parallasse." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallax Occlusion" + +#~ msgid "Parallax occlusion" +#~ msgstr "Parallax Occlusion" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Deviazione dell'occlusione di parallasse" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Iterazioni dell'occlusione di parallasse" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Modalità dell'occlusione di parallasse" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Scala dell'occlusione di parallasse" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Intensità dell'occlusione di parallasse" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Percorso del carattere TrueType o bitmap." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Percorso dove salvare le schermate." + +#~ msgid "Player name" +#~ msgstr "Nome del giocatore" + +#~ msgid "Profiling" +#~ msgstr "Generazione di profili" + +#~ msgid "Projecting dungeons" +#~ msgstr "Sotterranei protundenti" + +#~ msgid "PvP enabled" +#~ msgstr "PvP abilitato" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Azzera mondo locale" + +#~ msgid "Select Package File:" +#~ msgstr "Seleziona pacchetto file:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Server / Gioco locale" + +#~ msgid "Shadow limit" +#~ msgstr "Limite dell'ombra" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Scarto (in pixel) dell'ombreggiatura del carattere di riserva. Se è 0, " +#~ "allora l'ombra non sarà disegnata." + +#~ msgid "Special" +#~ msgstr "Speciale" + +#~ msgid "Special key" +#~ msgstr "Tasto speciale" + +#~ msgid "Start Singleplayer" +#~ msgstr "Avvia in locale" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Intensità delle normalmap generate." + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "Intensità dell'aumento mediano della curva di luce." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Questo carattere sarà usato per certe Lingue." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Per abilitare gli shader si deve usare il driver OpenGL." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Scegli cinematica" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Altezza massima tipica, sopra e sotto il punto medio, delle montagne dei " +#~ "terreni fluttuanti." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Variazione dell'altezza delle colline, e della profondità dei laghi sul\n" +#~ "terreno uniforme delle terre fluttuanti." + +#~ msgid "View" +#~ msgstr "Vedi" + +#~ msgid "Waving Water" +#~ msgstr "Acqua ondeggiante" + +#~ msgid "Waving water" +#~ msgstr "Acqua ondeggiante" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Se si usano caratteri FreeType, richiede la compilazione col supporto " +#~ "FreeType.\n" +#~ "Se disabilitati, si utilizzano invece i caratteri bitmap e XML vettoriali." + +#~ msgid "Whether dungeons occasionally project from the terrain." +#~ msgstr "Se i sotterranei saltuariamente si protendono dal terreno." + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Y del limite superiore della lava nelle caverne grandi." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "" +#~ "Livello Y del punto medio delle terre fluttuanti e della superficie dei " +#~ "laghi." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Livello Y a cui si estendono le ombre delle terre fluttuanti." + +#~ msgid "Yes" +#~ msgstr "Sì" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Stai per accedere a questo server col nome \"%s\" per la prima volta. \n" +#~ "Se prosegui, su questo server sarà creato un nuovo account usando le tue " +#~ "credenziali.\n" +#~ "Per favore reinserisci la tua password e premi Registrati e accedi per " +#~ "confermare la creazione dell'account, o premi Annulla per interrompere." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Sei morto" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/ja/minetest.po b/po/ja/minetest.po new file mode 100644 index 0000000..bb80f77 --- /dev/null +++ b/po/ja/minetest.po @@ -0,0 +1,8223 @@ +msgid "" +msgstr "" +"Project-Id-Version: Japanese (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-31 17:28+0000\n" +"Last-Translator: BreadW <toshiharu.uno@gmail.com>\n" +"Language-Team: Japanese <https://hosted.weblate.org/projects/minetest/" +"minetest/ja/>\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "アウト チャット キューをクリアする" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "空のコマンドです。" + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "メインメニューに戻る" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "無効なコマンド: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "発行されたコマンド: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "オンラインプレーヤーを一覧表示する" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "オンラインプレイヤー: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "アウトチャットキューは空になりました。" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "このコマンドはサーバによって無効にされています。" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "リスポーン" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "死んでしまった" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "使用可能なコマンド:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "使用可能なコマンド: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "コマンドは使用できません: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "コマンドのヘルプを表示する" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"'.help <cmd>' を使用して詳細情報を取得するか、または '.help all' を使用してす" +"べてを一覧表示します。" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<利用できません>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Luaスクリプトでエラーが発生しました:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "エラーが発生しました:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "メインメニュー" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "再接続" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "サーバーが再接続を要求しました:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "新しいバージョン $1 が利用可能" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "クライアントMOD" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" +"インストール済みバージョン: $1\n" +"新バージョン: $2\n" +"$3 にアクセスして、最新バージョンを入手し、機能とバグ修正を最新の状態に保つ方" +"法を確認してください。" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "あとで" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "しない" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "プロトコルのバージョンが一致していません。 " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "サーバーはバージョン$1のプロトコルを強制しています。 " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "サーバーは$1から$2までのプロトコルのバージョンをサポートしています。 " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "ウェブサイトを見る" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "プロトコルはバージョン$1のみをサポートしています。" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "バージョン$1から$2までのプロトコルをサポートしています。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "(有効、エラーあり)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "(不十分)" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "キャンセル" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "依存MOD:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "すべて無効化" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "MODパック無効化" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "すべて有効化" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "MODパック有効化" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "許可されていない文字が含まれているため、MOD \"$1\" を有効にできませんでした。" +"許可される文字は [a-z0-9_] のみです。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "他のMODを探す" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "MOD:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "(任意) 依存MODなし" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "ゲームの説明がありません。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "必須依存MODなし" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "MODパックの説明がありません。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "任意依存MODなし" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "任意依存MOD:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "保存" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "ワールド:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "有効" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "「$1」はすでに存在します。上書きしますか?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$1 と依存MOD $2 がインストールされます。" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 by $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 ダウンロード中、\n" +"$2 ダウンロード待機中" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 ダウンロード中..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 つの必要な依存MODが見つかりませんでした。" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 がインストールされ、依存MOD $2 はスキップされます。" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "すべて" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "インストール済み" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "メインメニューへ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "基盤ゲーム:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "MinetestがcURLなしでコンパイルされた場合、コンテンツDBは使用できません" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "ダウンロード中..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "$1のダウンロードに失敗" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "ゲーム" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "入手" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "$1 のインストール" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "不足依存MODインストール" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "インストール: 非対応のファイル形式か、壊れたアーカイブ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "MOD" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "パッケージを取得できませんでした" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "何も見つかりませんでした" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "更新なし" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "見つかりません" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "上書き" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "基盤となるゲームが正しいかどうか確認してください。" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "待機中" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "テクスチャパック" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "削除" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "更新" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "すべて更新 [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Webブラウザで詳細を見る" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "ワールド名「$1」はすでに存在します" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "追加の地形" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "高所で低温" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "高所で乾燥" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "バイオームの交錯" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "バイオーム" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "大きな洞窟" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "洞窟" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "作成" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "デコレーション" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "Development Testは開発者用です。" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "ダンジョン" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "平らな地形" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "空に浮かぶ大陸" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "浮遊大陸 (実験的)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "非フラクタルな地形の生成: 海と地下" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "丘" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "湿気のある川" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "川周辺の湿度を上げる" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "ゲームをインストール" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "ほかのゲームをインストール" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "湖" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "低湿度と高熱は浅いまたは乾燥した川をもたらす" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "マップジェネレータ" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "マップジェネレータフラグ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "マップジェネレータ固有のフラグ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "山" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "泥流" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "トンネルと洞窟の繋がり" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "ゲームが選択されていません" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "高度で熱を低下" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "高度で湿度を低下" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "川" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "海面の高さの川" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Seed値" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "バイオーム間の円滑な移行" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "地形上に現れる構造物 (v6によって生成された木やジャングルの草に影響なし)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "地形上に現れる構造物、通常は木や植物" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "温帯、砂漠" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "温帯、砂漠、ジャングル" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "温帯、砂漠、ジャングル、ツンドラ、タイガ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "地形表面の侵食" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "木とジャングルの草" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "川の深さを多様にする" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "地下深くにある非常に大きな洞窟" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "ワールド名" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "ゲームがインストールされていません。" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "本当に「$1」を削除してよろしいですか?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "削除" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: \"$1\"の削除に失敗しました" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: パス\"$1\"は無効" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "ワールド「$1」を削除しますか?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "パスワードの確認" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "$1 に参加する" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "名前が見つかりません" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "名前" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "パスワード" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "パスワードが一致しない" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "登録" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "決定" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "MODパック名を変更:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "このMODパックは、modpack.conf " +"に明示的な名前が付けられており、ここでの名前変更をすべて上書きします。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(設定の説明はありません)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2Dノイズ" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< 設定ページに戻る" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "参照" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "コンテンツ: ゲーム" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "コンテンツ: MOD" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "無効" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "編集" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "有効" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "空隙性" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "オクターブ" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "オフセット" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "永続性" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "有効な整数を入力してください。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "有効な数字を入力してください。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "初期設定に戻す" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "スケール" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "検索" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "ディレクトリの選択" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "ファイルの選択" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "技術名称を表示" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "値は$1より大きくなければなりません。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "値は$1より小さくなければなりません。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Xの広がり" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Yの広がり" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Zの広がり" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "絶対値" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "既定値" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "緩和する" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (有効)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 MOD" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "$2へ$1をインストールできませんでした" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "MODインストール: 実際のMOD名が見つかりません: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "MODインストール: MODパック $1 に適したフォルダ名が見つかりません" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "有効なMODまたはMODパックが見つかりません" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "$1をテクスチャパックとしてインストールすることができません" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "ゲームを$1としてインストールすることができません" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "MODを$1としてインストールすることができません" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "MODパックを$1としてインストールすることができません" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "読み込み中..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "公開サーバー一覧は無効" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "インターネット接続を確認し、公開サーバー一覧を再有効化してください。" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "情報" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "活動中の貢献者" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "アクティブなレンダラー:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "開発者" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "ディレクトリを開く" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"ファイルマネージャー/エクスプローラーで、ワールド、ゲーム、MOD、\n" +"およびテクスチャパックを含むディレクトリを開きます。" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "以前の貢献者" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "以前の開発者" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "デバッグログを共有" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "オンラインコンテンツ参照" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "コンテンツ" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "テクスチャパック無効化" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "情報:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "インストール済みのパッケージ:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "依存MODなし。" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "パッケージの説明がありません" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "名前を変更" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "パッケージを削除" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "テクスチャパック使用" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "公開サーバー" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "バインドアドレス" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "クリエイティブ" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "ダメージ有効" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "ゲームホスト" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "ホストサーバー" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "コンテンツDBからゲームをインストール" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "新規作成" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "ワールドが作成または選択されていません!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "ゲームプレイ" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "ポート" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "MODを選択" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "ワールドを選択:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "サーバーのポート" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "ゲームスタート" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "アドレス" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Clear" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "クリエイティブモード" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "ダメージ / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "お気に入り" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "互換性のないサーバ" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "ゲームに参加" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "ログイン" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "応答速度" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "公開サーバー" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "再読込" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "お気に入りを削除" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "サーバーの説明" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "(ゲームサポート必須)" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2倍" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "立体な雲" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4倍" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8倍" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "すべての設定" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "アンチエイリアス:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "大きさを自動保存" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "バイリニアフィルタ" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "キー変更" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "ガラスを繋げる" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "動的な影" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "動的な影:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "綺麗な葉" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "強め" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "弱め" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "普通" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "ミップマップ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "ミップマップと異方性フィルタ" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "フィルタ無し" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "ミップマップ無し" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "ノードを高輝度表示" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "ノードの輪郭線を描画" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "無し" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "不透明な葉" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "不透明な水" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "パーティクル" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "画面:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "設定" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "シェーダー" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "シェーダー (実験的)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "シェーダー (無効)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "シンプルな葉" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "滑らかな光" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "テクスチャリング:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "トーンマッピング" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "タッチのしきい値 (px):" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "トライリニアフィルタ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "とても強く" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "とても弱く" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "揺れる葉" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "揺れる液体" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "揺れる草花" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "接続が中断されました (プロトコル エラー?)。" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "接続がタイムアウトしました。" + +#: src/client/client.cpp +msgid "Done!" +msgstr "完了!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "ノードを初期化中" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "ノードを初期化中..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "テクスチャを読み込み中..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "シェーダーを再構築中..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "接続エラー (タイムアウト?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "ゲームが見つからないか読み込めません: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "無効なゲーム情報です。" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "メインメニュー" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "ワールドが選択されていないか存在しないアドレスです。続行できません。" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "プレイヤー名が長過ぎます。" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "名前を選択してください!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "パスワードファイルを開けませんでした: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "ワールドが存在しません: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"詳細はdebug.txtを確認してください。" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- アドレス: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- モード: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- ポート: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- 公開サーバー: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- サーバー名: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "シリアライズエラーが発生しました:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "アクセスが拒否されました。理由: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "自動前進 無効" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "自動前進 有効" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "ブロック境界線を非表示" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "すべてのブロックにブロック境界線を表示" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "現在のブロックにブロック境界を表示" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "近くのブロックにブロック境界を表示" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "カメラ更新 無効" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "カメラ更新 有効" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "ブロック境界を表示できない (MODやゲームで無効化されている)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "パスワード変更" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "映画風モード 無効" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "映画風モード 有効" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "クライアントが切断されました" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "クライアント側のスクリプトは無効" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "サーバーに接続中..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "未知の理由で接続に失敗しました" + +#: src/client/game.cpp +msgid "Continue" +msgstr "再開" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"操作方法:\n" +"- %s: 前進\n" +"- %s: 後退\n" +"- %s: 左移動\n" +"- %s: 右移動\n" +"- %s: ジャンプ/登る\n" +"- %s: 掘削/パンチ\n" +"- %s: 設置/使用\n" +"- %s: スニーク/降りる\n" +"- %s: アイテムを落とす\n" +"- %s: インベントリ\n" +"- マウス: 見回す\n" +"- マウスホイール: アイテム選択\n" +"- %s: チャット\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "アドレスを解決できませんでした: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "クライアントを作成中..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "サーバーを作成中..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "デバッグ情報、観測記録グラフ 非表示" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "デバッグ情報 表示" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "デバッグ情報、観測記録グラフ、ワイヤーフレーム 非表示" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"既定の操作:\n" +"タッチ操作:\n" +"- シングルタップ: ブロックの破壊\n" +"- ダブルタップ: 設置/使用\n" +"- スライド: 見回す\n" +"メニュー/インベントリの操作:\n" +"- メニューの外をダブルタップ:\n" +" --> 閉じる\n" +"- アイテムをタッチ:\n" +" --> アイテムの移動\n" +"- タッチしてドラッグ、二本指タップ:\n" +" --> アイテムを一つスロットに置く\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "視野無制限 無効" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "視野無制限 有効" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "クライアント作成中にエラー: %s" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "メインメニュー" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "終了" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "高速移動モード 無効" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "高速移動モード 有効" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "高速移動モード有効化 (メモ: 'fast' 特権がありません)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "飛行モード 無効" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "飛行モード 有効" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "飛行モード有効化 (メモ: 'fly' 特権がありません)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "霧 無効" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "霧 有効" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "ゲーム情報:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "ポーズメニュー" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "ホスティングサーバー" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "アイテムを定義中..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/秒" + +#: src/client/game.cpp +msgid "Media..." +msgstr "メディアを受信中..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/秒" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "ミニマップは現在ゲームまたはMODにより無効" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "マルチプレイヤー" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "すり抜けモード 無効" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "すり抜けモード 有効" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "すり抜けモード有効化 (メモ: 'noclip' 特権がありません)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "ノードを定義中..." + +#: src/client/game.cpp +msgid "Off" +msgstr "オフ" + +#: src/client/game.cpp +msgid "On" +msgstr "オン" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "ピッチ移動モード 無効" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "ピッチ移動モード 有効" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "観測記録グラフ 表示" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "リモートサーバー" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "アドレスを解決中..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "終了中..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "シングルプレイヤー" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "音量" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "消音" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "サウンドシステムは無効" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "このビルドではサウンド システムがサポートされていない" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "消音 取り消し" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "サーバーが別のバージョン %s を実行している可能性があります。" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "IPv6が無効なため、%sに接続できません" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "IPv6が無効なため、%sでリッスンできません" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "視野を %d に変更" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "視野はいま最大値: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "視野はいま最小値: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "音量を %d%% に変更" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "ワイヤーフレーム 表示" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "ズームは現在ゲームまたはMODにより無効" + +#: src/client/game.cpp +msgid "ok" +msgstr "決定" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "チャット 非表示" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "チャット 表示" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD 非表示" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD 表示" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "観測記録 非表示" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "観測記録 表示 (ページ %d / %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "アプリケーション" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Back Space" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Ctrl" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Down" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "EOFを消去する" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Execute" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "ヘルプ" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME Accept" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME変換" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "Esc" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IMEモード変更" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "無変換" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "左移動" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "左ボタン" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "左Ctrl" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "左Alt" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "左Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "左Windows" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Alt" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "中ボタン" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "NumLock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "数値キーパッド *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "数値キーパッド +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "数値キーパッド -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "数値キーパッド ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "数値キーパッド /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "数値キーパッド 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "数値キーパッド 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "数値キーパッド 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "数値キーパッド 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "数値キーパッド 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "数値キーパッド 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "数値キーパッド 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "数値キーパッド 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "数値キーパッド 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "数値キーパッド 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page Down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page Up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Play" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Print" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "右移動" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "右ボタン" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "右Ctrl" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "右メニュー" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "右Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "右Windows" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Select" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Sleep" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Snapshot" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Space" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "上" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Xボタン1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Xボタン2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "ズーム" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "ミニマップ 非表示" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "ミニマップ レーダーモード、ズーム x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "ミニマップ 表面モード、ズーム x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "ミニマップ テクスチャモード" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "ウェブページを開けませんでした" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "ウェブページを開いています" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "決定" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"スペシャル\" = 降りる" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "自動前進" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "自動ジャンプ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "後退" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "ブロック境界線表示切替" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "視点変更" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "チャット" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "コマンド" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "コンソール" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "視野を縮小" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "音量を下げる" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "\"ジャンプ\"2回で飛行モード切替" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "落とす" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "前進" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "視野を拡大" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "音量を上げる" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "インベントリ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "ジャンプ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "キーが重複しています" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "キーバインド。" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "ローカルコマンド" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "消音" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "次のアイテム" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "前のアイテム" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "視野の選択" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "スクリーンショット" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "スニーク" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "HUD表示切替" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "チャット表示切替" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "高速移動モード切替" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "飛行モード切替" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "霧表示切替" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "ミニマップ表示切替" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "すり抜けモード切替" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "ピッチ移動モード切替" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "キー入力待ち" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "変更" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "新しいパスワード" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "古いパスワード" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "パスワードが一致しません!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "閉じる" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "消音" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "音量: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "ja" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "名前が登録されていません。このサーバーにアカウントを作成するには「登録」をク" +"リック。" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "名前は使われています。他の名前に変えてください" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) バーチャルパッドの位置を修正します。\n" +"無効にした場合、最初に触れた位置がバーチャルパッドの中心になります。" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) バーチャルパッドを使用して\"Aux1\"ボタンを起動します。\n" +"有効にした場合、バーチャルパッドはメインサークルから外れたときにも\n" +"\"Aux1\"ボタンをタップします。" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) ワールドの中心からのフラクタルの「スケール」単位のオフセット。\n" +"目的のポイントを (0,0) に移動して適切なスポーンポイントを作成したり、\n" +"「スケール」を増やして目的のポイントに「ズームイン」したりするために\n" +"使用できます。\n" +"既定のパラメータを使用してマンデルブロ集合の適切なスポーンポイントに\n" +"合わせて調整されていますが、他の状況では変更が必要になる場合があります。\n" +"範囲は約-2〜2です。ノードのオフセットに「スケール」を掛けます。" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z)ノード内のフラクタルのスケール。\n" +"実際のフラクタルサイズは2〜3倍大きくなります。\n" +"これらの数字は非常に大きくすることができ、フラクタルは\n" +"ワールドの中に収まる必要はありません。\n" +"これらを増加してフラクタルの細部を'ズーム'します。\n" +"既定値は島に適した垂直方向に押しつぶされた形状のためのもので、\n" +"加工していないの形状のためには3つの数字をすべて等しく設定します。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "尾根の形状/大きさを制御する2Dノイズ。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "ゆるやかな丘の形状/大きさを制御する2Dノイズ。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "ステップマウンテンの形状/大きさを制御する2Dノイズ。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "山岳地帯の大きさ/出現を制御する2Dノイズ。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "ゆるやかな丘の大きさ/出現を制御する2Dノイズ。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "ステップマウンテン地帯の大きさ/出現を制御する2Dノイズ。" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "川の谷と水路を特定する2Dノイズ。" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "立体な雲" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3Dモード" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "3Dモード視差強度" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "巨大な洞窟を定義する3Dノイズ。" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"山の構造と高さを定義する3Dノイズ。\n" +"また、浮遊大陸の山地の構造を定義します。" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"浮遊大陸の構造を定義する3Dノイズ。\n" +"既定から変更すると、ノイズの「スケール」 (規定では 0.7) の調整が\n" +"必要になる場合があり、このノイズの値の範囲は約 -2.0 ~ 2.0 で\n" +"浮遊大陸の先細りが最も良く機能します。" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "川の峡谷の壁の構造を定義する3Dノイズ。" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3Dノイズは地形を定義しています。" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "山の張り出し、崖などの3Dノイズ。通常は小さな変化です。" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "マップチャンクごとのダンジョンの数を決定する3Dノイズ。" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3Dサポート。\n" +"現在のサポート:\n" +"- none: 3D出力を行いません。\n" +"- anaglyph: シアン/マゼンタ色による3Dです。\n" +"- interlaced: 奇数/偶数のラインをベースで偏光式スクリーンに対応。\n" +"- topbottom: 画面を上下で分割します。\n" +"- sidebyside: 画面を左右で分割します。\n" +"- crossview: 交差法による3Dです。\n" +"- pageflip: クァドバッファベースの3Dです。\n" +"interlacedはシェーダーが有効である必要があることに注意してください。" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "3D" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"新規マップを作成する際の初期シード値、空にするとランダムに設定されます。\n" +"ワールドを新規作成する際にシード値を入力すると上書きされます。" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "サーバークラッシュ時にすべてのクライアントへ表示するメッセージ。" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "サーバー終了時にすべてのクライアントへ表示するメッセージ。" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "ABMの間隔" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "ABMの時間予算" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "キューに入れられたブロックが出現する絶対制限" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "空中での加速" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "重力加速度、1秒あたりのノード数/秒です。" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "アクティブブロックモディファイヤー (ABM)" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "アクティブなブロックの管理間隔" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "アクティブなブロックの範囲" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "アクティブなオブジェクトの送信範囲" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"接続先のアドレスです。\n" +"ローカルサーバーを起動する際は空白に設定してください。\n" +"メインメニューのアドレス欄はこの設定を上書きすることに注意してください。" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "ノードを掘る際にパーティクルを追加します。" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"4kスクリーンなどのための、画面の解像度の設定です (非X11/Android環境のみ)。" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"検出されたディスプレイの密度を調整し、UI要素のスケーリングに使用します。" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"浮遊大陸層の密度を調整します。\n" +"密度を高めるために値を増やします。正または負の値を指定できます。\n" +"値 = 0.0: 50% が浮遊大陸です。\n" +"値 = 2.0 ('mgv7_np_floatland' によって高くなる場合があります、常に\n" +"念のためテスト) 浮遊大陸層を密に作成します。" + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "管理者名" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "詳細" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"「ガンマ補正」を適用して、光度曲線を変更します。\n" +"値を大きくすると、中間光と低光レベルが明るくなります。\n" +"値が「1.0」の場合、光度曲線は変更されません。\n" +"これは、日光と人工光にのみ大きな影響を与え、\n" +"自然な夜の光にはほとんど影響を与えません。" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "常に高速で飛行" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "アンビエントオクルージョンガンマ" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "プレイヤーが10秒間に送信できるメッセージの量。" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "谷を増幅します。" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "異方性フィルタリング" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "サーバーを公開" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "このサーバー一覧に告知します。" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "アイテム名を付け加える" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "ツールチップにアイテム名を付け加えます。" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "リンゴの木のノイズ" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "腕の惰性" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"腕の惰性、カメラが動いたときに\n" +"腕がより現実的な動きをします。" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "クラッシュ後に再接続を促す" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"この距離でサーバーはどのブロックをクライアントへ送信するかを積極的に\n" +"最適化します。\n" +"小さい値に設定すると、描画の視覚的な不具合を犠牲にして、\n" +"パフォーマンスが大幅に向上する可能性があります(いくつかのブロックは\n" +"水中や洞窟、時には陸の上でも描画されません)。\n" +"max_block_send_distance より大きい値に設定すると、この最適化は\n" +"無効になります。 \n" +"マップブロック(16ノード)で表記。" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "オーディオ" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "自動前進キー" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "自動的に1ノードの障害物をジャンプします。" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "サーバー一覧に自動的に報告します。" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "画面の大きさを自動保存" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "自動拡大縮小モード" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Aux1キー" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "昇降用のAux1キー" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "後退キー" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "基準地上レベル" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "基準地形の高さ。" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "基本的な特権" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "浜ノイズ" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "浜ノイズのしきい値" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "バイリニアフィルタリング" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "バインドアドレス" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "バイオームAPIのノイズパラメータ" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "バイオームノイズ" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "ブロック送信最適化距離" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "上下の揺れ" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "太字と斜体のフォントのパス" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "太字と斜体の固定幅フォントのパス" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "太字フォントのパス" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "太字の固定幅フォントのパス" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "プレイヤーの位置に設置" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "ビルトイン" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "カメラ" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"カメラと '近クリッピング面' の距離、0~0.25の間のノード数で、\n" +"GLESプラットフォームでのみ機能します。\n" +"ほとんどのユーザーはこれを変更する必要はありません。\n" +"増加すると、低性能GPUでの画像の乱れを減らすことができます。\n" +"0.1 = 既定値、0.25 = 低性能タブレットに適した値です。" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "カメラの滑らかさ" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "映画風モードでのカメラの滑らかさ" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "カメラ更新切り替えキー" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "洞窟ノイズ" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "洞窟ノイズ #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "洞窟ノイズ #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "洞窟の幅" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "洞窟1ノイズ" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "洞窟2ノイズ" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "大きな洞窟の制限" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "大きな洞窟ノイズ" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "大きな洞窟の先細り" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "大きな洞窟のしきい値" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "大きな洞窟の上限" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"光度曲線ブースト範囲の中心。\n" +"0.0は最小光レベル、1.0は最大光レベルです。" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "チャットコマンド時間切れメッセージのしきい値" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "チャットコマンド" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "チャットのフォントサイズ" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "チャットキー" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "チャットログのレベル" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "チャットメッセージ数の限度" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "チャットメッセージの形式" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "チャットメッセージキックのしきい値" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "チャットメッセージの最大長" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "チャット切替キー" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "チャットのウェブリンク" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "チャンクサイズ" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "映画風モード" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "映画風モード切り替えキー" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "テクスチャの透過を削除" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "チャットコンソールの出力で、クリック可能なウェブリンク " +"(中クリックまたはCtrl+左クリック) を有効になります。" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "クライアント" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "クライアントとサーバー" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "クライアントの改造" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "クライアント側での改造制限" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "クライアント側のノード参照範囲の制限" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "クライアント側の改造" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "上る速度" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "雲の半径" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "雲" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "雲はクライアント側で描画されます。" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "メニューに雲" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "色つきの霧" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "色つきの影" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"コンテンツリポジトリで非表示にするフラグのカンマ区切りリスト。\n" +"\"nonfree\"は、フリーソフトウェア財団によって定義されている\n" +"「フリーソフトウェア」として認定されていないパッケージを隠すために\n" +"使うことができます。\n" +"コンテンツの評価を指定することもできます。\n" +"これらのフラグはMinetestのバージョンから独立しています、\n" +"https://content.minetest.net/help/content_flags/ にある完全なリスト参照" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"HTTP APIへのアクセスが許可され、インターネットでデータをアップロード\n" +"およびダウンロードできるようにするModのコンマ区切りリスト。" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"MODのセキュリティが有効の場合でも (request_insecure_environment() \n" +"を介して) 安全でない機能へのアクセスが許可されている信頼できる\n" +"MODのコンマ区切りリスト。" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "コマンドキー" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"マップブロックをディスクに保存するときに使用する圧縮レベル。\n" +"-1 - 規定の圧縮レベルを使用\n" +"0 - 最小の圧縮、最も速い\n" +"9 - 最高の圧縮、最も遅い" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"マップブロックをクライアントに送信するときに使用する圧縮レベル。\n" +"-1 - 規定の圧縮レベルを使用\n" +"0 - 最小の圧縮、最も速い\n" +"9 - 最高の圧縮、最も遅い" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "ガラスを繋げる" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "外部メディアサーバーに接続" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "ノードでサポートされている場合はガラスを繋ぎます。" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "コンソールの透過度" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "コンソール色" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "コンソールの高さ" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "コンテンツリポジトリ" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "コンテンツDBフラグのブラックリスト" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "コンテンツDBの最大同時ダウンロード数" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "コンテンツDBのURL" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "自動前進" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"連側的な前進、自動前進キーで切り替えます。\n" +"自動前進キーをもう一度押すか、後退で停止します。" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "操作" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"昼夜サイクルの長さを制御します。\n" +"例:\n" +"72 = 20分、360 = 4分、1 = 24時間、0 = 昼/夜/変更されません。" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" +"アイドリング時の液体中沈下速度を制御します。負の値は\n" +"代わりに浮上します。" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "湖の窪みの険しさ/深さを制御します。" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "丘陵の険しさ/高さを制御します。" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"トンネルの幅を制御し、小さい値ほど広いトンネルを作成します。\n" +"値 >= 10.0 の場合、トンネルの生成が完全に無効になり、集中的な\n" +"ノイズ計算が回避されます。" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "クラッシュメッセージ" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "クリエイティブ" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "十字カーソルの透過度" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"十字カーソルの透過度 (不透明、0~255の間)。\n" +"これはオブジェクトの十字カーソルにも適用されます。" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "十字カーソルの色" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"十字カーソルの色 (R,G,B)。\n" +"オブジェクト十字カーソルの色も制御" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "ダメージ" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "デバッグ情報切り替えキー" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "デバッグログファイルのサイズのしきい値" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "デバッグログのレベル" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "デバッグ" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "音量を下げるキー" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "専用サーバーステップ" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "既定の加速度" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "標準ゲーム" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"新しいワールドを作成する際の既定のゲーム。\n" +"メインメニューからワールドを作成するときにこれは上書きされます。" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "既定のパスワード" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "既定の特権" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "既定のレポート形式" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "既定のスタック数" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"影フィルタの品質を定義します。\n" +"これは、PCFまたはポアソンディスクを適用することで、やわらない影効果をシミュ" +"レートするものです。\n" +"しかし、より多くのリソースを消費します。" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "木にリンゴがある地域を定義します。" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "砂浜の地域を定義します。" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "高い地形と崖の急勾配の分布を定義します。" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "高い地形の分布を定義します。" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "大きな洞窟の最大サイズを定義し、より小さい値はさらに大きな洞窟を作成。" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "大規模な河川構造を定義します。" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "オプションの丘と湖の場所と地形を定義します。" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "基準地上レベルを定義します。" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "河道の深さを定義します。" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "最大プレイヤー転送距離をブロック数で定義します(0 = 無制限)。" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "河道の幅を定義します。" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "川の谷の幅を定義します。" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "木の地域と木の密度を定義します。" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"クライアント上のメッシュ更新間の遅延 (ミリ秒)。これを大きくすると\n" +"メッシュの更新速度が遅くなり、低速のクライアントのジッタが減少します。" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "設置後のブロック送信遅延" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "ツールチップを表示するまでの遅延、ミリ秒で定めます。" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "非推奨の Lua API の処理" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "これ以下の深さで巨大な洞窟が見つかります。" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "これ以下の深さで大きな洞窟が見つかります。" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "サーバーの説明。プレイヤーが参加したときとサーバー一覧に表示されます。" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "砂漠ノイズのしきい値" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"砂漠は np_biome がこの値を超えたときに出現します。\n" +"'snowbiomes' フラグを有効にすると、これは無視されます。" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "ブロックのアニメーションの非同期化" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "開発者向けオプション" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "掘削キー" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "掘削時パーティクル" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "対チート機関無効化" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "空のパスワードを許可しない" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "ディスプレイ密度スケーリング係数" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" +"透明度の深さの並べ替えが有効になっているノードの距離\n" +"これを使用して、透明度の深さの並べ替えによるパフォーマンスへの影響を制限" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "サーバー一覧に表示されるサーバーのドメイン名。" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "「ジャンプ」キー二回押しで飛行モード" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "\"ジャンプ\"キー二回押しで飛行モードへ切り替えます。" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "アイテムを落とすキー" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "マップジェネレータのデバッグ情報を出力します。" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "ダンジョンの最大Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "ダンジョンの最小Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "ダンジョンノイズ" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"IPv6サポートを有効にします (クライアントとサーバーの両方に対して)。\n" +"機能するためにはIPv6接続が必要です。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"クライアントでのLua改造サポートを有効にします。\n" +"このサポートは実験的であり、APIは変わることがあります。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"ポアソンディスクによるフィルタリングを有効にします。\n" +"true の場合、ポアソンディスクを使用して「やわらない影」を作ります。それ以外の" +"場合は、PCFフィルタリングを使用します。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"色つきの影を有効にします。\n" +"真の半透明ノードでは、色つきの影を落とします。これは負荷が大きいです。" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "コンソールウィンドウを有効化" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "すべてのプレイヤーにクリエイティブモードを有効化" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "ジョイスティック作動" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "ジョイスティックを有効にします。変更には再起動が必要" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "MODチャンネルのサポートを有効にします。" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "MODのセキュリティを有効化" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "プレイヤーがダメージを受けて死亡するのを有効にします。" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "ランダムなユーザー入力を有効にします (テストにのみ使用)。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"シンプルなアンビエントオクルージョンで滑らかな照明を有効にします。\n" +"速度や異なる見た目のために無効にしてください。" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "ログインと登録を分ける" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"古いクライアントが接続できないようにします。\n" +"古いクライアントは新しいサーバーに接続してもクラッシュしないという\n" +"意味で互換性がありますが、期待しているすべての新機能をサポート\n" +"しているわけではありません。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"リモートメディアサーバーの使用を有効にします (サーバーによって提供\n" +"されている場合)。\n" +"リモートサーバはサーバーに接続するときにメディア (例えば、テクスチャ) を\n" +"ダウンロードするための非常に高速な方法を提供します。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"頂点バッファオブジェクトを有効にします。\n" +"これにより、グラフィックスのパフォーマンスが大幅に向上します。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"移動時の上下の揺れと移動時の上下の揺れの量を有効にします。\n" +"例: 0 揺れなし; 1.0 標準の揺れ; 2.0 標準の倍の揺れ。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"IPv6サーバーの実行を有効/無効にします。\n" +"bind_addressが設定されている場合は無視されます。\n" +"enable_ipv6を有効にする必要があります。" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Hableの「アンチャーテッド2」フィルムトーンマッピングを有効にします。\n" +"写真フィルムのトーンカーブと、これがハイダイナミックレンジイメージの外観に\n" +"どのように近似するかをシミュレートします。ミッドレンジのコントラストが\n" +"わずかに強化され、ハイライトとシャドウが徐々に圧縮されます。" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "インベントリのアイテムのアニメーションを有効にします。" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "facedir回転メッシュのキャッシングを有効にします。" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "ミニマップを有効にする。" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"サウンドシステムを有効にします。\n" +"無効にすると、すべてのサウンドが完全に無効になり、\n" +"ゲーム内の音の制御は機能しなくなります。\n" +"この設定を変更するには再起動が必要です。" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"ゲームのプレイアビリティに影響を与えない小さな視覚的な不具合を犠牲にして\n" +"CPU負荷を軽減するか、レンダリングパフォーマンスを向上させるトレードオフを有効" +"にします。" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "エンジンの観測記録" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "エンジンプロファイリングデータの出力間隔" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "エンティティメソッド" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"浮遊大陸の先細り指数。先細りの動作を変更します。\n" +"値 = 1.0は、均一で線形な先細りを作成します。\n" +"値 > 1.0は、規定の分離された浮遊大陸に適した滑らかな先細りを\n" +"作成します。\n" +"値 < 1.0 (例 0.25) は、より明確な表面レベルで平坦な低地を\n" +"作成し、密な浮遊大陸層に適しています。" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "FPS" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "非アクティブまたはポーズメニュー表示中のFPS" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "フルスクリーンアンチエイリアシング" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "係数ノイズ" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "落下時の上下の揺れ係数" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "フォールバックフォントのパス" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "高速移動モード切替キー" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "高速移動モードの加速度" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "高速移動モードの速度" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "高速移動モード" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"高速移動 (\"Aux1\"キーによる)。\n" +"これにはサーバー上に \"fast\" 特権が必要です。" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "視野角" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "視野角の度数。" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"client/serverlist/ フォルダ内のファイルで、ゲームに参加タブで表示されている\n" +"お気に入りのサーバーが含まれています。" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "充填深さ" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "充填深さノイズ" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "フィルム調トーンマッピング" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"フィルタ処理されたテクスチャは、RGB値を完全に透明な隣り合うものと\n" +"混ぜることができます。これはPNGオプティマイザーが通常廃棄するもので、\n" +"透過テクスチャの端が暗くなったり明るくなったりすることがよくあります。\n" +"テクスチャの読み込み時にフィルタを適用してそれをきれいにします。\n" +"これはミップマッピングが有効な場合に自動的に有効になります。" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "フィルタリングとアンチエイリアス" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "一緒に丘陵/山岳地帯の高さを定義する2Dノイズ4つのうちの1番目です。" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "トンネルを定義する2つの3Dノイズのうちの1番目。" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "固定マップシード値" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "バーチャルパッドを固定" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "浮遊大陸の密度" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "浮遊大陸の最大 Y" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "浮遊大陸の最小 Y" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "浮遊大陸ノイズ" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "浮遊大陸の先細り指数" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "浮遊大陸の先細り距離" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "浮遊大陸の水位" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "飛行キー" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "飛行モード" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "霧" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "霧の始まり" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "霧表示切り替えキー" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "フォント" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "既定で太字のフォント" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "既定で斜体のフォント" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "フォントの影" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "フォントの影の透過" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "フォントの大きさ" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "割り切れるフォントサイズ" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "96 DPIで1ユニット=1ピクセルとなる既定のフォントのフォントサイズ" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "96 DPIで1ユニット=1ピクセルとなる固定幅フォントのフォントサイズ" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"最近のチャットテキストとチャットプロンプトのフォントサイズ (pt)。\n" +"値 0 は規定のフォントサイズを使用します。" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"拡大縮小がうまくいかないピクセルスタイルのフォントの場合、このフォントで\n" +"使用されるフォントサイズは、常にこの値で割り切れます。例えば高さ16ピクセル" +"の\n" +"ピクセルフォントの場合、この値を16に設定すると、16、32、48などのサイズにし" +"か\n" +"なりませんので、25のサイズを要求したMODは32を取得します。" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"プレーヤーのチャットメッセージの形式。以下の文字列は有効なプレースホルダで" +"す。:\n" +"@name, @message, @timestamp (任意)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "スクリーンショットのファイル形式です。" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "フォームスペックの既定の背景色" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "フォームスペックの既定の背景不透明度" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "フォームスペックのフルスクリーンの背景色" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "フォームスペックのフルスクリーンの背景不透明度" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "フォームスペックの既定の背景色 (R,G,B)。" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "フォームスペックの既定の背景不透明度 (0~255の間)。" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "フォームスペックのフルスクリーンの背景色 (R,G,B)。" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "フォームスペックのフルスクリーンの背景不透明度 (0~255の間)。" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "前進キー" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "一緒に丘陵/山岳地帯の高さを定義する2Dノイズ4つのうちの4番目です。" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "フラクタルの種類" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "霧が描画され始める可視距離の割合" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"どれくらいの距離のブロックからクライアントで生成するか、\n" +"マップブロック(16ノード)で定めます。" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"どれくらいの距離のブロックからクライアントへ送信するか、\n" +"マップブロック(16ノード)で定めます。" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"クライアントがどれくらいの距離のオブジェクトを知っているか、\n" +"マップブロック (16ノード) で定めます。\n" +"\n" +"これを active_block_range よりも大きく設定すると、サーバーは\n" +"この距離までプレーヤーが見ている方向に\n" +"アクティブなオブジェクトを維持します。(これによりモブが突然\n" +"視野から消えるのを避けることができます)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "フルスクリーン表示" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "全画面表示モードです。" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "GUIの拡大縮小" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "GUI拡大縮小フィルタ" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "GUI拡大縮小フィルタ txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "GUI" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "ゲームパッド" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "一般" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "グローバルコールバック" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"全体的なマップ生成属性。\n" +"マップジェネレータv6では、'decorations' フラグで木とジャングルの草を\n" +"除くすべての装飾を制御しますが、他のすべてのマップジェネレータでは\n" +"このフラグがすべての装飾を制御します。" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"最大光レベルでの光度曲線の勾配。\n" +"最も高い光レベルのコントラストを制御します。" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"最小光レベルでの光度曲線の勾配。\n" +"最も低い光レベルのコントラストを制御します。" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "グラフィック" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "グラフィック効果" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "グラフィックとオーディオ" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "重力" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "地上レベル" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "地上ノイズ" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP MOD" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "HUD" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "HUDのサイズ" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "HUD表示切り替えキー" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"非推奨の Lua API 呼び出しの処理:\n" +"- none: 非推奨の呼び出しを記録しない\n" +"- log: 非推奨の呼び出しのバックトレースを模倣して記録します (既定値)。\n" +"- error: 非推奨の呼び出しの使用を中止します (MOD開発者に推奨)。" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"観測記録計測器自体を持ちます: \n" +"*空の関数を計測します。\n" +"これによりオーバーヘッドが見積もられ、計測器は (+1関数呼び出し) を\n" +"追加します。\n" +"*統計を更新するために使用されているサンプラを計測します。" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "温度混合ノイズ" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "熱ノイズ" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "初期ウィンドウサイズの高さ。フルスクリーンモードでは無視されます。" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "高さノイズ" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "高さ選択ノイズ" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "丘陵の険しさ" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "丘陵のしきい値" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "丘陵性1ノイズ" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "丘陵性2ノイズ" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "丘陵性3ノイズ" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "丘陵性4ノイズ" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "サーバー一覧に表示されるサーバのホームページ。" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"ジャンプや落下時の空気中の水平加速度、\n" +"1秒あたりのノード数/秒です。" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"高速移動モード中の水平および垂直加速度、\n" +"1秒あたりのノード数/秒です。" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"地面や登山時の水平および垂直加速度、\n" +"1秒あたりのノード数/秒です。" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "ホットバー次へキー" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "ホットバー前へキー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "ホットバースロット1キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "ホットバースロット10キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "ホットバースロット11キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "ホットバースロット12キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "ホットバースロット13キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "ホットバースロット14キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "ホットバースロット15キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "ホットバースロット16キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "ホットバースロット17キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "ホットバースロット18キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "ホットバースロット19キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "ホットバースロット2キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "ホットバースロット20キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "ホットバースロット21キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "ホットバースロット22キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "ホットバースロット23キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "ホットバースロット24キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "ホットバースロット25キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "ホットバースロット26キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "ホットバースロット27キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "ホットバースロット28キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "ホットバースロット29キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "ホットバースロット3キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "ホットバースロット30キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "ホットバースロット31キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "ホットバースロット32キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "ホットバースロット4キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "ホットバースロット5キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "ホットバースロット6キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "ホットバースロット7キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "ホットバースロット8キー" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "ホットバースロット9キー" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "川を作る深さ。" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"液体波の移動速度。高い値=より速い。\n" +"負の値の場合、液体波は逆方向に移動します。\n" +"揺れる液体 を有効にする必要があります。" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"未使用のマップブロックをアンロードするまでにサーバーが待機する時間を秒単位で" +"定めます。\n" +"値が大きいほど滑らかになりますが、より多くのRAMが使用されます。" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" +"液体の中を移動するときに、どれくらい速度を低下させるかです。\n" +"これを小さくすると、液体の動きに対する抵抗が大きくなります。" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "川を作る幅。" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "湿度混合ノイズ" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "湿度ノイズ" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "バイオームの湿度変動です。" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6 サーバー" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"FPSがこれより高くなる場合は、CPUの電力を無駄にしないように\n" +"スリープ状態で制限します。" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"無効になっている場合、飛行モードと高速移動モードの両方が有効になって\n" +"いると、\"Aux1\"キーを使用して高速で飛行できます。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"有効にすると、サーバーはプレーヤーの目の位置に基づいてマップブロック\n" +"オクルージョンカリングを実行します。これによりクライアントに送信される\n" +"ブロック数を50〜80%減らすことができます。すり抜けモードの有用性が\n" +"減るように、クライアントはもはや目に見えないものを受け取りません。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"飛行モードと一緒に有効にされている場合、プレイヤーは個体ノードを\n" +"すり抜けて飛ぶことができます。\n" +"これにはサーバー上に \"noclip\" 特権が必要です。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"有効にすると、降りるとき \"スニーク\" キーの代りに \n" +"\"Aux1\" キーが使用されます。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"有効にした場合、アカウント登録はログインとは別になります。\n" +"無効にした場合、新しいアカウントはログイン時に自動的に登録されます。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"有効にした場合、ロールバックのために行動が記録されます。\n" +"このオプションはサーバー起動時にのみ読み込まれます。" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "有効にすると、マルチプレイでチート防止を無効にします。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"有効にした場合、無効なワールドデータによってサーバーがシャットダウン\n" +"することはありません。\n" +"自分がしていることがわかっている場合のみこれを有効にします。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "有効にすると、飛行中または水泳中にプレーヤーのピッチ方向に移動します。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "有効にすると、プレーヤーはパスワードなしで参加したり、空のパスワードに変更す" +"ることはできません。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"有効になっている場合は、立っている位置 (足と目の高さ) にブロックを\n" +"配置できます。\n" +"狭い領域でノードボックスを操作するときに役立ちます。" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"ノード範囲のCSM制限が有効になっている場合、get_node 呼び出しは\n" +"プレーヤーからノードまでのこの距離に制限されます。" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"チャットコマンドの実行が、この指定された時間 (秒) よりも長くかかる場合は\n" +"チャットコマンドのメッセージに時間の情報を追加" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"debug.txt のファイルサイズが指定されたメガバイト数を超える場合、\n" +"ファイルは debug.txt.1 に移動されます。\n" +"古い debug.txt.1 が存在する場合は削除されます。\n" +"debug.txt は、この設定が正の場合にのみ移動されます。" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "これを設定すると、プレーヤーが常に与えられた場所に(リ)スポーンします。" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "ワールドエラーを無視" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "ゲーム内チャットコンソール背景の透過 (不透明、0~255の間)。" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "ゲーム内チャットコンソール背景の色 (R,G,B)。" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "ゲーム内チャットコンソールの高さ、0.1 (10%) ~ 1.0 (100%) の間。" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "音量を上げるキー" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "ジャンプ時の初期垂直速度、1秒あたりのノード数です。" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"計測器内蔵。\n" +"これは通常、コア/ビルトイン貢献者にのみ必要" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "チャットコマンドが登録されるとすぐに計測します。" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"グローバルコールバック関数が登録されるとすぐに計測します。\n" +"(あなたが minetest.register_*() 関数に渡すもの)" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"アクティブブロックモディファイヤー (ABM) のアクション関数が\n" +"登録されるとすぐに計測します。" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"ローディングブロックモディファイヤー (LBM) のアクション関数が\n" +"登録されるとすぐに計測します。" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "エンティティのメソッドを登録するとすぐに計測します。" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "ワールドで重要な変化を保存する間隔を秒単位で定めます。" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "クライアントに時刻を送信する間隔を秒単位で定めます。" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "インベントリのアイテムのアニメーション" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "インベントリキー" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "マウスの反転" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "マウスの上下の動きを反転させます。" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "斜体フォントのパス" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "斜体の固定幅フォントのパス" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "アイテムエンティティTTL" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "繰り返し" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"再帰関数の繰り返し。\n" +"これを大きくすると細部の量が増えますが、処理負荷も増えます。\n" +"繰り返し = 20では、このマップジェネレータはマップジェネレータ V7 と\n" +"同じように負荷をかけます。" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ジョイスティックID" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "ジョイスティックボタンの繰り返し間隔" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "ジョイスティックのデッドゾーン" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "ジョイスティック視錐台感度" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "ジョイスティックの種類" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"ジュリア集合のみ。\n" +"超複素定数のW成分。\n" +"フラクタルの形を変えます。\n" +"3Dフラクタル上の効果はありません。\n" +"おおよそ -2~2 の範囲。" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"ジュリア集合のみ。\n" +"超複素定数のX成分。\n" +"フラクタルの形を変えます。\n" +"おおよそ -2~2 の範囲。" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"ジュリア集合のみ。\n" +"超複素定数のY成分。\n" +"フラクタルの形を変えます。\n" +"おおよそ -2~2 の範囲。" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"ジュリア集合のみ。\n" +"超複素定数のZ成分。\n" +"フラクタルの形を変えます。\n" +"おおよそ -2~2 の範囲。" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "ジュリア w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "ジュリア x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "ジュリア y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "ジュリア z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "ジャンプキー" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "ジャンプ時の速度" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"視野を縮小するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"音量を下げるキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"掘削するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"現在選択されているアイテムを落とすキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"視野を拡大するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"音量を上げるキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ジャンプするキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"高速移動モード中に高速移動するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"プレイヤーを後方へ移動するキーです。\n" +"自動前進中に押すと自動前進を停止します。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"プレイヤーを前方へ移動するキーです。\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"プレイヤーを左方向へ移動させるキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"プレイヤーを右方向へ移動させるキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ゲームを消音にするキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"コマンドを入力するためのチャットウィンドウを開くキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ローカルコマンドを入力するためのチャットウィンドウを開くキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"チャットウィンドウを開くキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"インベントリを開くキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"設置するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"11番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"12番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"13番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"14番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"15番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"16番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"17番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"18番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"19番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"20番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"21番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"22番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"23番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"24番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"25番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"26番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"27番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"28番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"29番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"30番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"31番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"32番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"8番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"5番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"1番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"4番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ホットバーから次のアイテムを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"9番目のホットバースロットを選択するキーです。\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ホットバーから前のアイテムを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"2番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"7番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"6番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"10番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"3番目のホットバースロットを選択するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"スニークするキーです。\n" +"aux1_descends が無効になっている場合は、降りるときや水中を潜るためにも使用さ" +"れます。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"一人称から三人称の間でカメラを切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"スクリーンショットを撮るキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"自動前進を切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"映画風モードを切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ミニマップ表示を切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"高速移動モードを切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"飛行モードを切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"すり抜けモードを切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ピッチ移動モードを切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"カメラ更新を切り替えるキー。開発にのみ使用される\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"チャット表示を切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"デバッグ情報の表示を切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"霧の表示を切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"HUDの表示を切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"大型チャットコンソールの表示を切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"観測記録の表示を切り替えるキー。開発に使用されます。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"無制限の視野を切り替えるキー。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ズーム可能なときに使用するキーです。\n" +"参照 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "キーボードとマウス" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "10秒あたりにXメッセージ以上送信したプレイヤーをキックします。" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "湖の険しさ" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "湖のしきい値" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "言語" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "大きな洞窟の深さ" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "大きな洞窟の最大数" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "大きな洞窟の最小数" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "大きな洞窟の浸水割合" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "大型チャットコンソールキー" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "葉のスタイル" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"葉のスタイル:\n" +"- Fancy: すべての面が見える\n" +"- Simple: special_tiles が定義されている場合は外側の面のみ\n" +"- Opaque: 透明性を無効化" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "左キー" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"サーバーが時を刻む間隔とオブジェクトが通常ネットワーク上で更新される間隔を\n" +"秒単位で定めます。" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"液体波の長さ。\n" +"揺れる液体 を有効にする必要があります。" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "アクティブブロックモディファイヤー (ABM) " +"実行サイクル間の時間の長さを秒単位で定めます。" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "ノードタイマー実行サイクル間の時間の長さを秒単位で定めます。" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "アクティブなブロック管理サイクル間の時間の長さを秒単位で定めます。" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"debug.txt に書き込まれるログのレベル:\n" +"- <nothing> (ログなし)\n" +"- none (レベルがないメッセージ)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "光度曲線ブースト" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "光度曲線ブーストの中心" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "光度曲線ブーストの広がり" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "光度曲線のガンマ" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "光度曲線の高勾配" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "光度曲線の低勾配" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "光度" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"ノード内の (0, 0, 0) からの6方向すべてにおけるマップ生成の制限。\n" +"マップ生成の制限内に完全に収まるマップチャンクだけが生成されます。\n" +"値はワールドごとに保存されます。" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"並列HTTPリクエストの数を制限します。影響:\n" +"- サーバーが remote_media 設定を使用している場合はメディアの取得。\n" +"- サーバー一覧のダウンロードとサーバの公開。\n" +"- メインメニューで実行されたダウンロード (例えば、コンテンツ)。\n" +"cURLでコンパイルされた場合にのみ効果があります。" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "液体の流動性" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "液体流動の滑らかさ" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "液体ループ最大" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "液体キューのパージ時間" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "液体中の沈降" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "液体の秒単位の更新間隔。" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "液体の更新間隔" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "ゲーム観測記録の読み込み" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"ゲームの観測記録を読み込んで、ゲームの観測データを収集します。\n" +"集められた観測記録にアクセスするための /profiler コマンドを提供します。\n" +"MOD開発者やサーバーオペレーターに役立ちます。" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "ローディングブロックモディファイヤー (LBM)" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "ダンジョンのY値の下限。" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "浮遊大陸の Y の下限。" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "メインメニュースクリプト" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "霧と空の色を日中(夜明け/日没)と視線方向に依存させます。" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "すべての液体を不透明にする" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "ディスクストレージのマップ圧縮レベル" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "ネットワーク転送のためのマップ圧縮レベル" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "マップディレクトリ" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "マップジェネレータ Carpathian に固有のマップ生成属性。" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"マップジェネレータ flat に固有のマップ生成属性。\n" +"時折、湖や丘を平らなワールドに追加することができます。" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"マップジェネレータ fractal に固有のマップ生成属性。\n" +"'terrain' は非フラクタルな地形の生成を可能にします:\n" +"海、島そして地下。" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"マップジェネレータ Valleys に固有のマップ生成属性。\n" +"'altitude_chill': 高度とともに熱を減らします。\n" +"'humid_rivers': 川の周辺の湿度を上げます。\n" +"'vary_river_depth': 有効になっていると低湿度と高熱により川は浅くなり、\n" +"時には乾いてしまいます。\n" +"'altitude_dry': 高度とともに湿度を下げます。" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "マップジェネレータ v5 に固有のマップ生成属性。" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"マップジェネレータ v6 に固有のマップ生成属性。\n" +"'snowbiomes' フラグは新しい5つのバイオームシステムを有効にします。\n" +"'snowbiomes' フラグを有効にすると、ジャングルが自動的に有効になり、\n" +"'jungles' フラグは無視されます。" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"マップジェネレータ v7 に固有のマップ生成属性。\n" +"'ridges': 川。\n" +"'floatlands': 空に浮かぶ大陸。\n" +"'caverns': 地下深くの巨大な洞窟。" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "マップ生成の制限" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "マップ保存間隔" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "地図の影の更新フレーム" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "マップブロック制限" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "マップブロックのメッシュ生成遅延" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "メッシュ生成のマップブロックキャッシュサイズ(MB)" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "マップブロック破棄タイムアウト" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "マップジェネレータ Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "マップジェネレータ Carpathian 固有のフラグ" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "マップジェネレータ Flat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "マップジェネレータ Flat 固有のフラグ" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "マップジェネレータ Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "マップジェネレータ Fractal 固有のフラグ" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "マップジェネレータ V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "マップジェネレータ V5 固有のフラグ" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "マップジェネレータ V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "マップジェネレータ V6 固有のフラグ" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "マップジェネレータ V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "マップジェネレータ V7 固有のフラグ" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "マップジェネレータ Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "マップジェネレータ Valleys 固有のフラグ" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "マップジェネレータのデバッグ" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "マップジェネレータ名" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "ブロック生成最大距離" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "ブロック送信最大距離" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "ステップあたりの液体の最大処理。" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "最大 clearobjects 追加ブロック" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "繰り返しあたりの最大パケット" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "最大FPS" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"ウィンドウにフォーカスが合っていないとき、またはポーズメニュー表示中の最大" +"FPS。" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "影を描画する最大距離。" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "最大強制読み込みブロック" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "ホットバー最大幅" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "マップチャンクあたりの大きな洞窟の乱数の最大値。" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "マップチャンクあたりの小さな洞窟の乱数の最大値。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "最大の液体抵抗。高速で液体に入る際の減速を制御します。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"クライアントごとに同時に送信される最大ブロック数。\n" +"最大合計数は動的に計算されます:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "読み込みのためにキューに入れることができる最大ブロック数。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"生成されてキューに入れられる最大ブロック数。\n" +"この制限はプレイヤーごとに適用されます。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"ファイルから読み込まれてキューに入れられる最大ブロック数。\n" +"この制限はプレイヤーごとに適用されます。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"同時ダウンロードの最大数です。この制限を超えるダウンロードはキューに入れられ" +"ます。\n" +"これは curl_parallel_limit よりも低い値でなければなりません。" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "強制読み込みマップブロックの最大数。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"クライアントがメモリに保持する最大マップブロック数。\n" +"無制限の金額の場合は -1 に設定します。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"接続速度が遅い場合は、送信ステップごとに送信される最大パケット数を\n" +"減らしてみてください。ただし、対象のクライアント数の2倍未満に減らさ\n" +"ないでください。" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "同時に接続できるプレーヤーの最大数。" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "表示する最近のチャットメッセージの最大数" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "ブロック内に静的に格納されたオブジェクトの最大数。" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "ブロックあたりの最大オブジェクト" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"ホットバーに使用される現在のウィンドウの最大割合です。\n" +"ホットバーの左右に表示するものがある場合に便利です。" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "クライアントあたりの最大同時ブロック送信数" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "アウトチャットキューの最大サイズ" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"アウトチャットキューの最大サイズ。\n" +"キューを無効にするには 0、サイズを無制限にするには -1 を指定します。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "ファイルダウンロード (MODのダウンロードなど) " +"にかかる最大時間をミリ秒単位で定めます。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "インタラクティブリクエスト (サーバー一覧の取得など) " +"にかかる最大時間をミリ秒単位で定めます。" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "最大ユーザー数" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "メッシュキャッシュ" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "その日のメッセージ" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "接続中のプレイヤーに表示されるその日のメッセージ。" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "選択したオブジェクトを強調表示するために使用される方法。" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "チャットに書き込まれる最小限のログレベル。" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "ミニマップ" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "ミニマップ表示切替キー" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "ミニマップのスキャン高さ" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "マップチャンクあたりの大きな洞窟の乱数の最小値。" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "マップチャンクあたりの小さな洞窟の乱数の最小値。" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "最小テクスチャサイズ" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "ミップマッピング" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "その他" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "MODの観測記録" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "MODのセキュリティ" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "MODのチャンネル" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "HUD要素のサイズを変更します。" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "固定幅フォントのパス" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "固定幅フォントのサイズ" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "割り切れる固定幅フォントのサイズ" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "山の高さノイズ" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "山ノイズ" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "山の変動ノイズ" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "山のゼロレベル" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "マウスの感度" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "マウス感度の倍率。" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "泥ノイズ" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"落下時の上下の揺れ乗数。\n" +"例: 0 揺れなし; 1.0 標準の揺れ; 2.0 標準の倍の揺れ。" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "消音キー" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "消音" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"新しいワールドを作成するときに使用されるマップジェネレータの名前。\n" +"メインメニューでワールドを作成すると、これが上書きされます。\n" +"現在非常に不安定な状態のマップジェネレータ:\n" +"- v7の浮遊大陸 (既定では無効)。" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"プレイヤーの名前。\n" +"サーバーを実行している場合、この名前で接続しているクライアントは管理者\n" +"です。\n" +"メインメニューから起動すると、これは上書きされます。" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "プレイヤーが参加したときにサーバー一覧に表示されるサーバーの名前。" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "近くの面" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"待機するネットワークポート (UDP)。\n" +"メインメニューから起動すると、この値は上書きされます。" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "ネットワーク" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "新しいユーザーはこのパスワードを入力する必要があります。" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "すり抜けモード" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "すり抜けモード切替キー" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "ノードとエンティティのハイライト" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "ノードをハイライト" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "ノードタイマーの間隔" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "ノイズ" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "出現するスレッド数" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"使用する出現スレッド数。\n" +"値 0:\n" +"- 自動選択。 出現スレッド数は\n" +"- 'プロセッサー数 - 2'、下限は 1 です。\n" +"その他の値:\n" +"- 出現スレッド数を指定します、下限は 1 です。\n" +"警告: 出現するスレッド数を増やすとエンジンのマップ生成速度が\n" +"上がりますが、特にシングルプレイヤーや 'on_generated' で\n" +"Luaコードを実行している場合、他のプロセスと干渉してゲームの\n" +"パフォーマンスを低下させる可能性があります。\n" +"多くのユーザーにとって最適な設定は '1' です。" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"/clearobjects によって一度に読み込みできる追加ブロックの数です。\n" +"これは、SQLiteトランザクションのオーバーヘッドとメモリ消費の間の\n" +"トレードオフです (大体 4096 = 100MB)。" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "不透明な液体" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "既定のフォントの影の不透明度 (透過) は0から255の間です。" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"ウィンドウのフォーカスが失われたときにポーズメニューを開きます。\n" +"フォームスペックが開かれているときはポーズメニューを開きません。" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "チャットのウェブリンクの色を上書きするオプションです。" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"フォールバックフォントのパス。TrueType フォントでなければなりません。\n" +"このフォントは特定の言語か、規定のフォントが使用できないときに使用されます。" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"スクリーンショットを保存するパス。絶対パスまたは相対パスを指定できます。\n" +"フォルダーが存在しない場合は作成されます。" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"シェーダーディレクトリへのパス。パスが定義されていない場合は、\n" +"既定の場所が使用されます。" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" +"テクスチャディレクトリへのパス。すべてのテクスチャは最初にここから\n" +"検索されます。" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"既定のフォントのパス。TrueType フォントでなければなりません。\n" +"このフォールバックフォントはフォントが読み込めないときに使用されます。" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"固定幅フォントのパス。TrueType フォントでなければなりません。\n" +"このフォントはコンソールや観測記録画面などで使用されます。" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "ウィンドウフォーカス喪失時に一時停止" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "ファイルから読み込まれるキューブロックのプレイヤーごとの制限" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "生成されるキューブロックのプレイヤーごとの制限" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "物理" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "ピッチ移動モード切替キー" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "ピッチ移動モード" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "設置キー" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "設置の繰り返し間隔" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"プレイヤーは重力の影響を受けずに飛ぶことができます。\n" +"これにはサーバー上に \"fly\" 特権が必要です。" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "プレイヤー転送距離" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "プレイヤー対プレイヤー" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "ポアソンフィルタリング" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"(UDP) に接続するポート。\n" +"メインメニューのポート欄はこの設定を上書きすることに注意してください。" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"マウスボタンを押したままにして掘り下げたり設置したりするのを防ぎます。\n" +"思いがけずあまりにも頻繁に掘ったり置いたりするときにこれを有効にします。" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "MODがシェルコマンドを実行するような安全でないことをするのを防ぎます。" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"エンジンのプロファイリングデータを出力する定期的な間隔 (秒)。\n" +"0 = 無効。開発者にとって便利です。" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "basic_privs を持っているプレイヤーが付与できる特権" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "観測記録" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "観測記録表示切替キー" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "プロメテウスリスナーのアドレス" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"プロメテウスリスナーのアドレス。\n" +"Minetest が ENABLE_PROMETHEUS オプションを有効にしてコンパイルされている場" +"合、\n" +"そのアドレスのプロメテウスのメトリックスリスナーを有効にします。\n" +"メトリックスは http://127.0.0.1:30000/metrics で取得可能" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "大きな洞窟の液体を含む割合です。" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"雲域の半径は64ノードの雲の正方形の数で表されます。\n" +"26を超える値は、雲域の隅に急な切断を作り出します。" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "川の周りに谷を作るために地形を上げます。" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "ランダム入力" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "視野範囲変更" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "最近のチャットメッセージ" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "通常フォントのパス" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "リモートメディア" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "リモートポート" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"チャットメッセージから色コードを取り除きます\n" +"これを使用して、プレイヤーが自分のメッセージに色を使用できない\n" +"ようにします" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "既定のメインメニューをカスタム化したものに置き換えます。" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "レポートパス" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"サーバーで特定のクライアント側機能へのアクセスを制限します。\n" +"以下の byteflags を合わせてクライアント側の機能を制限するか、制限なしの\n" +"場合は 0 に設定します。\n" +"LOAD_CLIENT_MODS: 1 (クライアント提供のMODの読み込みを無効)\n" +"CHAT_MESSAGES: 2 (クライアント側での send_chat_message 呼び出しを無効)\n" +"READ_ITEMDEFS: 4 (クライアント側での get_item_def 呼び出しを無効)\n" +"READ_NODEDEFS: 8 (クライアント側での get_node_def 呼び出しを無効)\n" +"LOOKUP_NODES_LIMIT: 16 (クライアント側での get_node 呼び出しを\n" +"csm_restriction_noderange に制限)\n" +"READ_PLAYERINFO: 32 (クライアント側での get_player_names 呼び出しを無効)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "尾根の広がりノイズ" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "尾根ノイズ" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "尾根水中ノイズ" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "尾根の大きさノイズ" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "右キー" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "河道の深さ" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "河道の幅" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "川の深さ" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "川ノイズ" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "川のサイズ" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "川の谷の幅" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "ロールバックの記録" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "ゆるやかな丘の大きさノイズ" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "ゆるやかな丘の広がりノイズ" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "円形ミニマップ" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "安全な掘削と設置" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "砂浜は np_beach がこの値を超えたときに出現します。" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "クライアントが受信したマップをディスクに保存します。" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "ウィンドウサイズ変更時に自動的に保存します。" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "サーバーから受信したマップ保存" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"ユーザー指定の値でGUIを拡大縮小します。\n" +"GUIを拡大縮小するには、最近傍補間アンチエイリアスフィルタを使用します。\n" +"これは、画像が整数以外のサイズで拡大縮小されるときにいくつかの\n" +"エッジピクセルをぼかすことを犠牲にして、粗いエッジの一部を滑らかにし、\n" +"縮小するときにピクセルを混合します。" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "画面" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "画面の高さ" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "画面の幅" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "スクリーンショットのフォルダ" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "スクリーンショットのファイル形式" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "スクリーンショットの品質" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"スクリーンショットの品質です。JPEG形式にのみ使用します。\n" +"1 は最低品質; 100 は最高品質です。\n" +"既定の品質には 0 を使用します。" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "スクリーンショット" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "海底ノイズ" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "一緒に丘陵/山岳地帯の高さを定義する2Dノイズ4つのうちの2番目です。" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "トンネルを定義する2つの3Dノイズのうちの2番目。" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "参照 https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "選択ボックスの枠線の色 (R,G,B)。" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "選択ボックスの色" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "選択ボックスの幅" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"18種類のフラクタルタイプから1つを選択します。\n" +"1 = 4D \"Roundy\" マンデルブロ集合。\n" +"2 = 4D \"Roundy\" ジュリア集合。\n" +"3 = 4D \"Squarry\" マンデルブロ集合。\n" +"4 = 4D \"Squarry\" ジュリア集合。\n" +"5 = 4D \"Mandy Cousin\" マンデルブロ集合。\n" +"6 = 4D \"Mandy Cousin\" ジュリア集合。\n" +"7 = 4D \"Variation\" マンデルブロ集合。\n" +"8 = 4D \"Variation\" ジュリア集合。\n" +"9 = 3D \"Mandelbrot / Mandelbar\" マンデルブロ集合。\n" +"10 = 3D \"Mandelbrot / Mandelbar\" ジュリア集合。\n" +"11 = 3D \"Christmas Tree\" マンデルブロ集合。\n" +"12 = 3D \"Christmas Tree\" ジュリア集合。\n" +"13 = 3D \"Mandelbulb\" マンデルブロ集合。\n" +"14 = 3D \"Mandelbulb\" ジュリア集合。\n" +"15 = 3D \"Cosine Mandelbulb\" マンデルブロ集合。\n" +"16 = 3D \"Cosine Mandelbulb\" ジュリア集合。\n" +"17 = 4D \"Mandelbulb\" マンデルブロ集合。\n" +"18 = 4D \"Mandelbulb\" ジュリア集合。" + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "サーバー" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "サーバーのゲームプレイ" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "サーバーのセキュリティ" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "サーバーURL" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "サーバーアドレス" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "サーバー説明" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "サーバー名" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "サーバーポート" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "サーバー側のオクルージョンカリング" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "サーバー/環境のパフォーマンス" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "サーバー一覧URL" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "サーバー一覧とその日のメッセージ" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "サーバー一覧ファイル" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"言語を設定してください。システム言語を使用するには空のままにします。\n" +"変更後は再起動が必要です。" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "クライアントから送信されるチャットメッセージの最大長 (文字数) を設定します。" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"影の強さのガンマを設定します。\n" +"ゲーム内の動的な影の強度を調整します。\n" +"低い値は明るい影を意味し、高い値は暗い影を意味します。" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"やわらかい影の半径サイズを設定します。\n" +"値が小さいほどシャープな影、大きいほどやわらない影になります。\n" +"最小値: 1.0、最大値: 15.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"太陽/月の軌道の傾きを度数で設定します。\n" +"0 は傾きのない垂直な軌道です。\n" +"最小値: 0.0、最大値: 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"有効にすると影を映します。\n" +"シェーダーが有効である必要があります。" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"有効にすると葉が揺れます。\n" +"シェーダーが有効である必要があります。" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"有効にすると液体が揺れます (水のような)。\n" +"シェーダーが有効である必要があります。" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"有効にすると草花が揺れます。\n" +"シェーダーが有効である必要があります。" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"影のテクスチャの品質を 32 ビットに設定します。\n" +"false の場合、16ビットのテクスチャが使用されます。\n" +"これは、影がさら不自然になる可能性があります。" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "シェーダーパス" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"シェーダーは高度な視覚効果を可能にし、ビデオカードによっては\n" +"パフォーマンスが向上する可能性があります。\n" +"これはOpenGLビデオバックエンドでのみ機能します。" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "影フィルタの品質" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "影を描画するためのノードの最大距離" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "32ビットの影投影テクスチャ" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "影投影テクスチャサイズ" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "既定のフォントの影のオフセット (ピクセル単位)。 0の場合、影は描画されません。" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "影の強さのガンマ" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "ミニマップの形状。有効 = 円形、無効 = 四角形。" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "デバッグ情報を表示" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "エンティティの選択ボックス表示" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"エンティティの選択ボックスを表示\n" +"変更後は再起動が必要です。" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "ネームタグの背景を既定で表示" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "サーバー終了時のメッセージ" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"マップジェネレータによって生成されたマップチャンクのサイズで、\n" +"マップブロック (16ノード) で表されます。\n" +"警告!: この値を5より大きくすることには利点がなく、いくつかの危険が\n" +"あります。この値を減らすと洞窟とダンジョンの密度が上がります。\n" +"この値を変更するのは特別な用途のためです。変更しないでおくことを\n" +"お勧めします。" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"メッシュ生成のマップブロックキャッシュサイズ。これを大きくすると、\n" +"キャッシュヒット率が上がり、メインスレッドからコピーされるデータが\n" +"減るため、ジッタが減少します。" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "天体の軌道傾斜角" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "スライス w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "傾斜と堆積物は高さを変えるために連携します。" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "小さな洞窟の最大数" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "小さな洞窟の最小数" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "バイオームが混合している境界線上の小規模湿度の変動。" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "バイオームが混合している境界線上の小規模温度の変動。" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "滑らかな照明" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"周りを見ているときにカメラを滑らかにします。マウススムージングとも\n" +"呼ばれます。\n" +"ビデオを録画するときに便利です。" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "映画風モードでのカメラの回転を滑らかにします。無効にする場合は 0。" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "カメラの回転を滑らかにします。無効にする場合は 0。" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "スニークキー" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "スニーク時の速度" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "スニーク時の速度、1秒あたりのノード数です。" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "やわらない影半径" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "サウンド" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"クライアントがUDPを使用せずにメディアを取得するURLを指定します。\n" +"$filename はcURLを介して $remote_media$filename からアクセス可能で\n" +"あるべきです (明らかに、remote_media はスラッシュで終わるべきです)。\n" +"存在しないファイルは通常の方法で取得されます。" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"既定のノード、アイテム、ツールのスタック数を指定します。\n" +"MOD またはゲームは、特定の (またはすべての) アイテムのスタック数を\n" +"明示的に設定する場合があることに注意してください。" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"影の描画の完全な更新を指定されたフレーム数に広げます。\n" +"値を大きくすると影が遅延することがあり、値を小さくすると\n" +"より多くのリソースを消費します。\n" +"最小値: 1、最大値: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"光度曲線ブースト範囲の広がり。\n" +"ブーストする範囲の幅を制御します。\n" +"光度曲線ブーストガウス分布の標準偏差。" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "静的なスポーンポイント" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "険しさノイズ" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "ステップマウンテンの大きさノイズ" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "ステップマウンテンの広がりノイズ" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "3Dモード視差の強さです。" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"光度曲線ブーストの強度。\n" +"3つの「ブースト」パラメーターは、明るさをブーストする\n" +"光度曲線の範囲を定義します。" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "厳密なプロトコルチェック" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "色コードを取り除く" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"密な浮遊大陸層に配置されるオプションの水の表面レベル。\n" +"水は規定で無効になっており、この値が 'mgv7_floatland_ymax' - " +"'mgv7_floatland_taper'\n" +"(上部の先細り開始点)より上に設定されている場合にのみ配置されます。\n" +"***警告、サーバーのパフォーマンスへの潜在的な危険性***:\n" +"水の配置を有効にする場合、浮遊大陸を密な層にするために\n" +"'mgv7_floatland_density' を2.0 (または 'mgv7_np_floatland' " +"に応じて他の必要な値) に\n" +"設定して、サーバーに集中する極端な水の流れを避け、下の世界表面への大規模な\n" +"洪水を避けるようにテストする必要があります。" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "SQLite同期" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "バイオームの温度変動。" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "一時的な設定" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "地形別ノイズ" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "地形基準ノイズ" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "地形の高さ" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "地形高いノイズ" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "地形ノイズ" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"丘陵地形ノイズのしきい値。\n" +"丘陵で覆われた地域の割合を制御します。\n" +"より大きい割合の場合は0.0に近づけて調整します。" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"湖地形ノイズのしきい値。\n" +"湖で覆われた地域の割合を制御します。\n" +"より大きい割合の場合は0.0に近づけて調整します。" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "地形持続性ノイズ" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "テクスチャパス" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"影を描画するためのテクスチャサイズです。\n" +"これは2の累乗でなければなりません。\n" +"数字が大きいほどより良い影ができますが、負荷も高くなります。" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"ノード上のテクスチャは、ノードまたはワールドに合わせて整列させる\n" +"ことができます。\n" +"前者のモードは、機械、家具などのようなものに適していますが、\n" +"後者のモードは階段やマイクロブロックを周囲の環境に合わせやすくします。\n" +"しかし、この機能は新しく、古いサーバーでは使用できない可能性があります。\n" +"このオプションを使用すると特定のノードタイプに適用できます。ただし、\n" +"これは実験的なものであり、正しく機能しない可能性があります。" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "コンテンツリポジトリのURL" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "ジョイスティックのデッドゾーン" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"観測記録が保存されている既定のファイル形式、\n" +"`/profiler save [format]`がファイル形式なしで呼び出されたときに使われます。" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "土や他のバイオーム充填ノードの深さ。" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "観測記録が保存されるワールドパスに対する相対的なファイルパスです。" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "使用するジョイスティックの識別子" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "タッチスクリーンの操作が始まるピクセル単位の距離。" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"揺れる液体の表面の最大高さ。\n" +"4.0 =波高は2ノードです。\n" +"0.0 =波はまったく動きません。\n" +"既定は1.0 (1/2ノード) です。\n" +"揺れる液体 を有効にする必要があります。" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "サーバがー待機しているネットワークインターフェース。" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"新規ユーザーが自動的に取得する特権。\n" +"サーバーとMODの構成の完全なリストについては、ゲーム内の /privs を参照\n" +"してください。" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"アクティブブロックの対象となる各プレイヤーの周囲のブロックの量の半径、\n" +"マップブロック (16ノード) で定めます。\n" +"アクティブブロックのオブジェクトはロードされ、ABMが実行されます。\n" +"これはアクティブオブジェクト (モブ) が維持される最小範囲でもあります。\n" +"これは active_object_send_range_blocks と一緒に設定する必要があります。" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"レンダリングのバックエンドです。\n" +"変更後は再起動が必要です。\n" +"注:Androidでは、不明な場合はOGRES1を使用してください!そうしないとアプリの起" +"動に失敗することがあります。\n" +"その他のプラットフォームでは、OpenGLを推奨します。\n" +"シェーダーは、OpenGL (デスクトップのみ) とOGRES2 (実験的) " +"でサポートされています。" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "ゲーム内の視錐台を動かすためのジョイスティック軸の感度。" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"ノードのアンビエントオクルージョンシェーディングの強度 (暗さ)。\n" +"低いほど暗く、高いほど明るくなります。設定の有効範囲は 0.25~4.0 です。\n" +"値が範囲外の場合は、最も近い有効な値に設定されます。" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"古いキューアイテムを出力してサイズを減らそうとするまでに、液体キューが\n" +"処理能力を超えて拡張できる時間(秒単位)。値 0 は機能を無効にします。" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"ABM が各ステップで実行できる時間予算\n" +"(ABM間隔の一部として)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"ジョイスティックのボタンの組み合わせを押したときに\n" +"繰り返されるイベントの秒単位の間隔。" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "設置ボタンを押したままノードの設置を繰り返す秒単位の間隔。" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "ジョイスティックの種類" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"'altitude_chill' が有効な場合、温度が20低下する垂直距離。同様に\n" +"'altitude_dry' が有効な場合、湿度が20低下する垂直距離。" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "一緒に丘陵/山岳地帯の高さを定義する2Dノイズ4つのうちの3番目です。" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"アイテムエンティティ (落下したアイテム) が存在できる秒単位の時間。\n" +"-1 に設定すると、機能は無効になります。" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "新しいワールドが開始される時刻。ミリ時間単位 (0〜23999)。" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "時刻送信間隔" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "時間の速さ" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "クライアントがメモリから未使用のマップデータを削除するためのタイムアウト " +"(秒単位)。" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"ラグを減らすために、プレーヤーが何かを設置しているときブロック転送は\n" +"遅くなります。\n" +"これはノードを設置または破壊した後にどれくらい遅くなるかを決定します。" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "視点変更キー" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "ツールチップの遅延" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "タッチスクリーンのしきい値" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "タッチスクリーン" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "パフォーマンスのためのトレードオフ" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "透明度の並べ替え距離" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "木のノイズ" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "トライリニアフィルタリング" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"より遅いマシンでミニマップを滑らかにするために使用できます。" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "信頼するMOD" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "ゲームに参加タブで表示されるサーバー一覧へのURL。" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "アンダーサンプリング" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"アンダーサンプリングは低い画面解像度を使用するのと似ていますが、\n" +"GUIをそのままにしてゲームのワールドにのみ適用されます。\n" +"より詳細なイメージを犠牲にしてパフォーマンスをかなり高めるでしょう。\n" +"値を大きくすると、画像の詳細が少なくなります。" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "無制限のプレーヤー転送距離" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "未使用のサーバーデータを破棄" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "ダンジョンのY値の上限。" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "浮遊大陸の Y の上限。" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "平らではなく立体な雲を使用します。" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "メインメニューの背景には雲のアニメーションを使用します。" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "ある角度からテクスチャを見るときは異方性フィルタリングを使用します。" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "テクスチャを拡大縮小する場合はバイリニアフィルタリングを使用します。" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"ミップマッピングを使用してテクスチャを拡大縮小します。特に高解像度の\n" +"テクスチャパックを使用する場合は、パフォーマンスがわずかに向上する\n" +"可能性があります。ガンマ補正縮小はサポートされていません。" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"マルチサンプルアンチエイリアス (MSAA) " +"を使用して、ブロックエッジを滑らかにします。\n" +"このアルゴリズムは、画像を鮮明に保ちながら3Dビューポートを滑らかにします。\n" +"しかし、それはテクスチャの内部には影響しません\n" +"(これは、透明なテクスチャで特に目立ちます)。\n" +"シェーダーを無効にすると、ノード間に可視スペースが表示されます。\n" +"0 に設定すると、MSAAは無効になります。\n" +"このオプションを変更した場合、再起動が必要です。" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "テクスチャを拡大縮小する場合はトライリニアフィルタリングを使用します。" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "ユーザーインターフェース" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "VSYNC" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "谷の深さ" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "渓谷堆積物" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Valley プロファイル" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "谷の傾斜" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "バイオーム充填深さの変動。" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "最大の山の高さ変動 (ノード単位)。" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "洞窟の数の変動。" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"地形垂直スケールの変動。\n" +"ノイズが -0.55 未満の場合、地形はほぼ平坦です。" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "バイオーム表面ノードの深さを変えます。" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"地形の粗さを変えます。\n" +"terrain_base および terrain_alt ノイズの 'persistence' 値を定義します。" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "崖の険しさが異なります。" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "垂直方向の上る速度、1秒あたりのノード数です。" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "垂直スクリーン同期。" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "ビデオドライバ" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "移動時の上下の揺れ係数" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "ノードの表示距離です。" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "視野縮小キー" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "視野拡大キー" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "ズーム眺望キー" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "視野" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "バーチャルパッドで Aux1 ボタン動作" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "音量" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"すべての音の音量。\n" +"サウンド システムを有効にする必要があります。" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"4Dフラクタルの生成された3DスライスのW座標。\n" +"4Dシェイプのどの3Dスライスを生成するかを決定します。\n" +"フラクタルの形を変えます。\n" +"3Dフラクタルには何の影響もありません。\n" +"おおよそ -2~2 の範囲。" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "歩行と飛行速度、1秒あたりのノード数です。" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "歩く速度" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "高速移動モード中の歩行と飛行と上る速度、1秒あたりのノード数です。" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "水位" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "ワールドの水面の高さです。" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "揺れるノード" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "揺れる葉" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "揺れる液体" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "揺れる液体の波の高さ" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "揺れる液体の波の速度" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "揺れる液体の波長" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "揺れる草花" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "ウェブリンクの色" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"gui_scaling_filter が有効な場合、すべてのGUIイメージはソフトウェアで\n" +"フィルタ処理される必要がありますが、いくつかのイメージは直接\n" +"ハードウェアで生成されます(例えば、インベントリ内のノードのための\n" +"テクスチャへのレンダリング)。" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"gui_scaling_filter_txr2img が有効な場合、拡大縮小のためにそれらの\n" +"イメージをハードウェアからソフトウェアにコピーします。 無効な場合、\n" +"ハードウェアからのテクスチャのダウンロードを適切にサポートしていない\n" +"ビデオドライバのときは、古い拡大縮小方法に戻ります。" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"バイリニア/トライリニア/異方性フィルタを使用すると、低解像度の\n" +"テクスチャがぼやける可能性があるため、鮮明なピクセルを保持するために\n" +"最近傍補間を使用して自動的にそれらを拡大します。これは拡大されたテクスチャ" +"の\n" +"ための最小テクスチャサイズを設定します。より高い値はよりシャープに見えます" +"が、\n" +"より多くのメモリを必要とします。2の累乗が推奨されます。この設定は、\n" +"バイリニア/トライリニア/異方性フィルタリングが有効の場合にのみ適用されま" +"す。\n" +"これは整列テクスチャの自動スケーリング用の基準ノードテクスチャサイズと\n" +"しても使用されます。" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"ネームタグの背景を既定で表示するかどうかです。\n" +"MODで背景を設定することもできます。" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"ノードのテクスチャのアニメーションをマップブロックごとに非同期に\n" +"するかどうかの設定です。" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"プレイヤーが範囲制限なしでクライアントに表示されるかどうかです。\n" +"非推奨。代わりに設定 player_transfer_distance を使用してください。" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "他のプレイヤーを殺すことができるかどうかの設定です。" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"(Luaが)クラッシュした際にクライアントに再接続を要求するかどうかの\n" +"設定です。\n" +"サーバーが自動で再起動されるように設定されているならば true に設定\n" +"してください。" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "可視領域の端に霧を表示するかどうかの設定です。" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"音をミュートするかどうか。サウンドシステムが無効になっていない限り\n" +"(enable_sound = false)、いつでもミュートを解除できます。\n" +"ゲーム内ではミュートキーを使用するかポーズメニューを使用して、\n" +"ミュート状態を切り替えることができます。" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" +"技術名を表示するかどうか。\n" +"コンテンツとMOD選択メニューのMODとテクスチャパック、および\n" +"すべての設定の設定名に影響します。\n" +"「すべての設定」メニューのチェックボックスで制御されます。" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"クライアントのデバッグ情報を表示するかどうかの設定です\n" +"(F5を押すのと同じ効果)。" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "初期ウィンドウサイズの幅。フルスクリーンモードでは無視されます。" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "ノードを囲む選択ボックスの枠線の幅。" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Windowsのみ: Minetestと一緒にバックグランドでコマンドプロンプトを\n" +"起動します。\n" +"debug.txt (既定の名前) と同じ情報を含んでいます。" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"ワールドを保存するディレクトリです(全てのワールドはここに保存\n" +"されます)。\n" +"メインメニューから開始する場合必要ありません。" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "ワールド開始時刻" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"整列テクスチャは、いくつかのノードにまたがるように拡大縮小する\n" +"ことができます。ただし、特別に設計されたテクスチャパックを使用\n" +"している場合は特に、サーバーから必要なスケールが送信されない\n" +"ことがあります。\n" +"このオプションでは、クライアントはテクスチャサイズに基づいて\n" +"自動的にスケールを決定しようとします。\n" +"texture_min_size も参照してください。\n" +"警告: このオプションは実験的なものです!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "整列テクスチャモード" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "平地のY。" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "山の密度勾配ゼロのY。山を垂直方向に移動するために使用。" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "大きな洞窟のY高さ上限。" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "大きな洞窟が最大サイズに拡大するYの距離。" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"完全な密度からゼロまでの浮遊大陸先細りの Y距離。\n" +"先細りは、Y制限からこの距離で始まります。\n" +"密な浮遊大陸層の場合、これは丘/山の高さを制御します。\n" +"Y制限間の距離の半分以下でなければなりません。" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "平均地形面のYレベル。" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "大きな洞窟の上限Yレベル。" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "崖を作る高い地形のYレベル。" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "低い地形と海底のYレベル。" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "海底のYレベル。" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "cURL" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "cURLファイルダウンロードタイムアウト" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "cURL インタラクティブタイムアウト" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "cURL並行処理制限" + +#~ msgid "- Creative Mode: " +#~ msgstr "- クリエイティブモード: " + +#~ msgid "- Damage: " +#~ msgstr "- ダメージ: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = 斜面情報付きの視差遮蔽マッピング(高速)。\n" +#~ "1 = リリーフマッピング(正確だが低速)。" + +#~ msgid "Address / Port" +#~ msgstr "アドレス / ポート" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "ライトテーブルのガンマ補正を調整します。数値が大きいほど明るくなります。\n" +#~ "この設定はクライアント専用であり、サーバでは無視されます。" + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "山型浮遊大陸が中間点の上下でどのように先細くなるかを変更します。" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "シングルプレイヤーのワールドをリセットしてよろしいですか?" + +#~ msgid "Back" +#~ msgstr "戻る" + +#~ msgid "Basic" +#~ msgstr "基本" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "フルスクリーンモードでのビット数(色深度)。" + +#~ msgid "Bump Mapping" +#~ msgstr "バンプマッピング" + +#~ msgid "Bumpmapping" +#~ msgstr "バンプマッピング" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "光度曲線ミッドブーストの中心。" + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "メインメニューUIを変更:\n" +#~ "- Full: 複数のシングルプレイヤーのワールド、ゲームの選択、\n" +#~ "テクスチャパックの選択、その他。\n" +#~ "- Simple: 1つのシングルプレイヤーのワールド、ゲームや\n" +#~ "テクスチャパックの選択はありません。小さな画面で必要かもしれません。" + +#~ msgid "Config mods" +#~ msgstr "Mod設定" + +#~ msgid "Configure" +#~ msgstr "設定" + +#~ msgid "Connect" +#~ msgstr "接続" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "液体中の沈降速度を制御します。" + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "山型浮遊大陸の密度を制御します。\n" +#~ "ノイズのオフセットは、'mgv7_np_mountain' ノイズ値に追加されます。" + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "トンネルの幅を制御、小さい方の値ほど広いトンネルを生成します。" + +#~ msgid "Credits" +#~ msgstr "クレジット" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "照準線の色 (R,G,B)。" + +#~ msgid "Damage enabled" +#~ msgstr "ダメージ有効" + +#~ msgid "Darkness sharpness" +#~ msgstr "暗さの鋭さ" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "cURLの既定のタイムアウト、ミリ秒で定めます。\n" +#~ "cURLでコンパイルされた場合にのみ効果があります。" + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "浮遊大陸の滑らかな地形の地域を定義します。\n" +#~ "ノイズが 0 より大きいとき、滑らかな浮遊大陸になります。" + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "テクスチャのサンプリング手順を定義します。\n" +#~ "値が大きいほど、法線マップが滑らかになります。" + +#~ msgid "Del. Favorite" +#~ msgstr "お気に入り削除" + +#~ msgid "" +#~ "Deprecated, define and locate cave liquids using biome definitions " +#~ "instead.\n" +#~ "Y of upper limit of lava in large caves." +#~ msgstr "" +#~ "廃止予定、代わりにバイオーム定義を使用して洞窟の液体を定義および特定しま" +#~ "す。\n" +#~ "大きな洞窟内の溶岩のY高さ上限。" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "" +#~ "Minetest Game などのゲームを minetest.net からダウンロードしてください" + +#~ msgid "Download one from minetest.net" +#~ msgstr "minetest.netからダウンロードしてください" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "$1をインストールしています、お待ちください..." + +#~ msgid "Enable VBO" +#~ msgstr "VBOを有効化" + +#~ msgid "Enable register confirmation" +#~ msgstr "登録確認を有効化" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "テクスチャのバンプマッピングを有効にします。法線マップは\n" +#~ "テクスチャパックによって提供されるかまたは自動生成される必要があります。\n" +#~ "シェーダーが有効である必要があります。" + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "フィルム調トーンマッピング有効にする" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "法線マップ生成を臨機応変に有効にします(エンボス効果)。\n" +#~ "バンプマッピングが有効である必要があります。" + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "視差遮蔽マッピングを有効にします。\n" +#~ "シェーダーが有効である必要があります。" + +#~ msgid "Enter " +#~ msgstr "エンター " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "実験的なオプションで、0 より大きい数値に設定すると、ブロック間に\n" +#~ "目に見えるスペースが生じる可能性があります。" + +#~ msgid "FPS in pause menu" +#~ msgstr "ポーズメニューでのFPS" + +#~ msgid "Fallback font shadow" +#~ msgstr "フォールバックフォントの影" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "フォールバックフォントの影の透過" + +#~ msgid "Fallback font size" +#~ msgstr "フォールバックフォントの大きさ" + +#~ msgid "Filtering" +#~ msgstr "フィルタリング" + +#~ msgid "Floatland base height noise" +#~ msgstr "浮遊大陸の基準高さノイズ" + +#~ msgid "Floatland mountain height" +#~ msgstr "浮遊大陸の山の高さ" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "フォントの影の透過 (不透明、0~255の間)。" + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "フォールバックフォントのフォント サイズ (pt)。" + +#~ msgid "FreeType fonts" +#~ msgstr "フリータイプフォント" + +#~ msgid "Full screen BPP" +#~ msgstr "フルスクリーンのBPP" + +#~ msgid "Game" +#~ msgstr "ゲーム" + +#~ msgid "Gamma" +#~ msgstr "ガンマ" + +#~ msgid "Generate Normal Maps" +#~ msgstr "法線マップの生成" + +#~ msgid "Generate normalmaps" +#~ msgstr "法線マップの生成" + +#~ msgid "HUD scale factor" +#~ msgstr "HUDの倍率" + +#~ msgid "High-precision FPU" +#~ msgstr "高精度FPU" + +#~ msgid "IPv6 support." +#~ msgstr "IPv6 サポート。" + +#~ msgid "In-Game" +#~ msgstr "ゲーム" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "インストール: ファイル: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "計測器" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "キー設定です。 (このメニューで失敗する場合は minetest.conf から該当する設" +#~ "定を削除してください)" + +#~ msgid "Lava depth" +#~ msgstr "溶岩の深さ" + +#~ msgid "Lightness sharpness" +#~ msgstr "明るさの鋭さ" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "ディスク上に出現するキューの制限" + +#~ msgid "Main" +#~ msgstr "メイン" + +#~ msgid "Main menu style" +#~ msgstr "メインメニューのスタイル" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "DirectX を LuaJIT と連携させます。問題がある場合は無効にしてください。" + +#~ msgid "Menus" +#~ msgstr "メニュー" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "ミニマップ レーダーモード、ズーム x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "ミニマップ レーダーモード、ズーム x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "ミニマップ 表面モード、ズーム x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "ミニマップ 表面モード、ズーム x4" + +#~ msgid "Name / Password" +#~ msgstr "名前 / パスワード" + +#~ msgid "Name/Password" +#~ msgstr "名前 / パスワード" + +#~ msgid "No" +#~ msgstr "いいえ" + +#~ msgid "Normalmaps sampling" +#~ msgstr "法線マップのサンプリング" + +#~ msgid "Normalmaps strength" +#~ msgstr "法線マップの強さ" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "視差遮蔽反復の回数です。" + +#~ msgid "Ok" +#~ msgstr "決定" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "フォールバックフォントの影の不透明度(透過)は0から255の間です。" + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "視差遮蔽効果の全体的バイアス、通常 スケール/2 です。" + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "視差遮蔽効果の全体的なスケールです。" + +#~ msgid "Parallax Occlusion" +#~ msgstr "視差遮蔽" + +#~ msgid "Parallax occlusion" +#~ msgstr "視差遮蔽" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "視差遮蔽バイアス" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "視差遮蔽反復" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "視差遮蔽モード" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "視差遮蔽スケール" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "視差遮蔽強度" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "TrueTypeフォントまたはビットマップへのパス。" + +#~ msgid "Path to save screenshots at." +#~ msgstr "スクリーンショットを保存するパス。" + +#~ msgid "Player name" +#~ msgstr "プレイヤー名" + +#~ msgid "Profiling" +#~ msgstr "プロファイリング" + +#~ msgid "Projecting dungeons" +#~ msgstr "突出するダンジョン" + +#~ msgid "PvP enabled" +#~ msgstr "PvP有効" + +#~ msgid "Reset singleplayer world" +#~ msgstr "ワールドをリセット" + +#~ msgid "Select Package File:" +#~ msgstr "パッケージファイルを選択:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "サーバー / シングルプレイヤー" + +#~ msgid "" +#~ "Set the shadow update time.\n" +#~ "Lower value means shadows and map updates faster, but it consume more " +#~ "resources.\n" +#~ "Minimun value 0.001 seconds max value 0.2 seconds" +#~ msgstr "" +#~ "影の更新時間を設定します。\n" +#~ "値が小さいほど影やマップの更新が速くなりますが、リソースを多く消費しま" +#~ "す。\n" +#~ "最小値0.001秒、最大値0.2秒" + +#~ msgid "Shadow limit" +#~ msgstr "影の制限" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "フォールバックフォントの影のオフセット(ピクセル単位)。 \n" +#~ "0の場合、影は描画されません。" + +#~ msgid "Special" +#~ msgstr "スペシャル" + +#~ msgid "Special key" +#~ msgstr "スペシャルキー" + +#~ msgid "Start Singleplayer" +#~ msgstr "シングルプレイスタート" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "生成された法線マップの強さです。" + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "光度曲線ミッドブーストの強さ。" + +#~ msgid "This font will be used for certain languages." +#~ msgstr "このフォントは特定の言語で使用されます。" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "" +#~ "シェーダーを有効にするにはOpenGLのドライバを使用する必要があります。" + +#~ msgid "Toggle Cinematic" +#~ msgstr "映画風モード切替" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "浮遊大陸の山の中間点の上と下の典型的な最大高さ。" + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "浮遊大陸の滑らかな地形における丘の高さと湖の深さの変動。" + +#~ msgid "View" +#~ msgstr "見る" + +#~ msgid "Waving Water" +#~ msgstr "揺れる水" + +#~ msgid "Waving water" +#~ msgstr "揺れる水" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "フリータイプフォントを使用するかどうかは、フリータイプをサポートして\n" +#~ "コンパイルされている必要があります。 \n" +#~ "無効にした場合、代わりにビットマップおよび XML ベクターフォントが使用され" +#~ "ます。" + +#~ msgid "Whether dungeons occasionally project from the terrain." +#~ msgstr "ダンジョンが時折地形から突出するかどうか。" + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "大きな洞窟内の溶岩のY高さ上限。" + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "浮遊大陸の中間点と湖面のYレベル。" + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "浮遊大陸の影が広がるYレベル。" + +#~ msgid "Yes" +#~ msgstr "はい" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "あなたはこのサーバ ーに名前 \"%s\" ではじめて参加しようとしています。\n" +#~ "続行する場合、あなたの情報が新しいアカウントとしてこのサーバーに作成されま" +#~ "す。\n" +#~ "あなたのパスワードを再入力してから '参加登録' をクリックしてアカウント作成" +#~ "するか、\n" +#~ "キャンセルをクリックして中断してください。" + +#~ msgid "You died." +#~ msgstr "あなたは死にました。" + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/jbo/minetest.po b/po/jbo/minetest.po new file mode 100644 index 0000000..1f5f4e5 --- /dev/null +++ b/po/jbo/minetest.po @@ -0,0 +1,7098 @@ +msgid "" +msgstr "" +"Project-Id-Version: Lojban (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2021-02-13 08:50+0000\n" +"Last-Translator: Wuzzy <almikes@aol.com>\n" +"Language-Team: Lojban <https://hosted.weblate.org/projects/minetest/minetest/" +"jbo/>\n" +"Language: jbo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.5-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Empty command." +msgstr "minde" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "sisti tu'a le se kelci" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Invalid command: " +msgstr "minde" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "nonselkansa" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "nonselkansa" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "tolcanci" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr ".i do morsi" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "minde" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "minde" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "fitytu'i" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "An error occurred in a Lua script:" +msgstr "" +".i da poi me la .luuas. ku samtci zo'u la'e di'e nabmi fi tu'a da noi la'a " +"cu'i se samtcise'a" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr ".i da nabmi" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "ralju liste" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "za'u re'u samjo'e" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr ".i le samtcise'u cu cpedu pa nu za'u re'u co'a samjo'e" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr ".i ko cuxna fi lu'i le munje" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Protocol version mismatch. " +msgstr "le ve judrnporte favatcini na mapti " + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Server enforces protocol version $1. " +msgstr "le samci'ejudri cu jitro lo du'u ve judrnporte favytcini li $1 " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "fitytoltu'i" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "jai se nitcu" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "ro co'e cu ganda" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "le se samtcise'a bakfu cu ganda" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "ro co'e cu katci" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "le se samtcise'a bakfu cu katci" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "se samtcise'a" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No (optional) dependencies" +msgstr "na'e se nitcu" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "to'i no da ve skicu le se kelci toi" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No hard dependencies" +msgstr ".i nitcu no da" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "to'i no da ve skicu le se samtcise'a bakfu toi" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No optional dependencies" +msgstr "na'e se nitcu" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "na'e se nitcu" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "co'a vreji" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "munje" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "katci" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr ".i ca'o samymo'i" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "se cmima ro bakfu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "xruti fi tu'a le ralju liste" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "cfari fa lo nu kelci" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Downloading..." +msgstr ".i ca'o samymo'i" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr ".i da nabmi fi le nu kibycpa la'o zoi. $1 .zoi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "se kelci" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "samtcise'a" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "samtcise'a" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "na'e se nitcu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "se samtcise'a" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr ".i na kakne le ka kibycpa pa bakfu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr ".i no da ckaji lo se sisku" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Texture packs" +msgstr "jvinu bakfu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "to'e samtcise'a" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr ".i zoi zoi. $1 .zoi xa'o cmene pa munje" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "kevzda" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "cupra" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Decorations" +msgstr "datni" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr ".i la'o zoi. Minimal development test .zoi na'o selpli lo favgau .o'i" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "kevdi'u" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "lo tumla cu fulta lo tsani" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Floatlands (experimental)" +msgstr "fulta tumla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "samtcise'a" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen" +msgstr "te cupra le munje" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "cmana" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr ".i do cuxna no se kelci" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "rirxe" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "cunso namcu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "cmene le munje" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr ".i do samtcise'a no se kelci" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr ".i xu do djica le nu vimcu la'o zoi. $1 .zoi" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "vimcu" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr ".i xu do djica le nu vimcu la'o zoi. $1 .zoi noi munje" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +#, fuzzy +msgid "Confirm Password" +msgstr "le rapli lerpoijaspu" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "lo lerpoijaspu" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr ".i lu'i le re lerpoijaspu na simxu le ka mintu" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "mulno" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "basti fi lo ka cmene le se samtcise'a bakfu" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "to'i no da ve skicu le te tcimi'e toi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "kakne le ka se samtcise'a" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "kakne le ka se samtcise'a" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "ganda" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "binxo" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "katci" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr ".i ko samci'a da poi drani le ka lerpoi fi pa mulna'u" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr ".i ko samci'a da poi drani fi le ka lerpoi fi pa namcu" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "xruti fi le zmiselcu'a" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "sisku" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "cuxna fi lu'i le datnyveimei" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "cuxna fi lu'i le datnyvei" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr ".i sarcu fa le nu le namcu cu dubjavmau li $1" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr ".i sarcu fa le nu le namcu na zmadu li $1" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 to'i katci toi" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "se samtcise'a fi la'o zoi. $1 .zoi" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "" +".i da nabmi fi le nu setca la'o zoi. $1 .zoi lu'i ro se datnyveimei be la'o " +"zoi. $2 .zoi" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr ".i ca'o samymo'i" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +".i ko troci lo nu za'u re'u samymo'i lo liste be lo'i samse'u .i ko cipcta " +"lo do te samjo'e" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "liste lu'i ro ca gunka" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "cuxna fi lu'i le datnyveimei" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "liste lu'i ro pu je nai ca gunka" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Content" +msgstr "kakne le ka se samtcise'a" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Disable Texture Pack" +msgstr "le jvinu bakfu cu ganda" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "datni" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "pu mo'u se samtcise'a" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "No dependencies." +msgstr ".i nitcu no da" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "to'i no da ve skicu le bakfu toi" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "basti fi le ka cmene" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "to'e samtcise'a le bakfu" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "finti se kelci" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "pilno lo selxai" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Host Game" +msgstr "cfari fa lo nu kelci" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "co'a samtcise'u" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "cnino" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr ".i do no munje cu cupra ja cu cuxna" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "co'a kelci" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "judrnporte" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr ".i ko cuxna fi lu'i le munje" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr ".i ko cuxna fi lu'i le munje" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "judrnporte le samtcise'u" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "co'a kelci" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "- judri: " + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "finti se kelci" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "nelci se tcita" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "co'a kansa fi le ka kelci" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr ".pin. temci" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "co'u cmima lu'i ro nelci se tcita" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "ve skicu le samtcise'u" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "cibyca'u dilnu" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "se cmima ro te tcimi'e" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "puvyrelyli'iju'e" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Connected Glass" +msgstr "lo jorne blaci" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Fancy Leaves" +msgstr "lo tolkli pezli" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "lo puvrmipmepi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "lo puvrmipmepi .e lo puvytolmanfyju'e" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Node Highlighting" +msgstr "lo xutla se gusni" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Node Outlining" +msgstr "lo xutla se gusni" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Opaque Leaves" +msgstr "lo tolkli pezli" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "tolkli djacu" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "kantu" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "te tcimi'e" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "ti'orkemsamtci" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "ti'orkemsamtci to na kakne toi" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (unavailable)" +msgstr "ti'orkemsamtci to na kakne toi" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Simple Leaves" +msgstr "lo sampu pezli" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Smooth Lighting" +msgstr "lo xutla se gusni" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Tone Mapping" +msgstr "lo puvrmipmepi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "puvycibli'iju'e" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Leaves" +msgstr "lo melbi pezli" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Liquids" +msgstr ".i ca'o samymo'i lo me la'o gy.node.gy." + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Plants" +msgstr "lo melbi pezli" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "" +".i da nabmi fi le nu co'a jorne to la'a cu'i le temci cu dukse le ka clani " +"toi" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr ".i mulno" + +#: src/client/client.cpp +#, fuzzy +msgid "Initializing nodes" +msgstr ".i ca'o samymo'i lo me la'o gy.node.gy." + +#: src/client/client.cpp +#, fuzzy +msgid "Initializing nodes..." +msgstr ".i ca'o samymo'i lo me la'o gy.node.gy." + +#: src/client/client.cpp +#, fuzzy +msgid "Loading textures..." +msgstr ".i ca'o samymo'i le tengu datnyvei" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" +".i da nabmi fi le nu co'a jorne to la'a cu'i le temci cu dukse le ka clani " +"toi" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "" +".i na cumki fa le nu le se kelci cu jai se facki je cu se samymo'i .i ky. du " +"la'o zoi." + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr ".i le se kelci ve skicu vreji na drani" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "ralju liste" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr ".i do cuxna no munje .i do ciska no judri .i do zukte no da" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr ".i le plicme cu dukse le ka clani" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr ".i ko ckaji le ka da zo'u jdice le du'u da cmene" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +".i sarcu fa le nu do cipcta la'o zoi. debug.txt .zoi kei tu'a le tcila" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- judri: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- judrnporte: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- gubni: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +#, fuzzy +msgid "- PvP: " +msgstr "- kakne le ka simxu le ka xrani: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- cmene le samtcise'u: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr ".i da nabmi" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward disabled" +msgstr "za'i ca'u muvdu" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward enabled" +msgstr "za'i ca'u muvdu" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "basti fi le ka lerpoijaspu" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode disabled" +msgstr "le nu finti kelci" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode enabled" +msgstr "le nu finti kelci" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "lo samtciselse'u" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr ".i ca'o samjo'e le samse'u" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "ranji" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr ".i ca'o cupra le samtciselse'u" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr ".i ca'o cupra le samtcise'u" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr ".i ca'o cupra le samtciselse'u" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "sisti tu'a le se kelci" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "sisti tu'a le samtci" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode enabled" +msgstr "selpli" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog disabled" +msgstr "selpli" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog enabled" +msgstr "selpli" + +#: src/client/game.cpp +msgid "Game info:" +msgstr ".i datni le se kelci" + +#: src/client/game.cpp +msgid "Game paused" +msgstr ".i ca'o denpa fo le nu kelci" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr ".i le samtci pe do cu samtcise'u" + +#: src/client/game.cpp +#, fuzzy +msgid "Item definitions..." +msgstr ".i ca'o samymo'i tu'a le dacti" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "nonselkansa" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Node definitions..." +msgstr ".i ca'o samymo'i tu'a lo me la'o gy.node.gy." + +#: src/client/game.cpp +msgid "Off" +msgstr "ganda" + +#: src/client/game.cpp +msgid "On" +msgstr "katci" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr ".i da poi na du le samtci pe do cu samtcise'u" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr ".i ca'o sisku le ka se judri da kau" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr ".i ca'o sisti" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "nonselkansa" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "ni sance" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound muted" +msgstr "lo ni sance " + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound unmuted" +msgstr "lo ni sance " + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr ".i fe lo ni sance cu cenba fi li %d ce'i" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "je'e" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr ".i ca mipri le tavla .uidje" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr ".i ca viska le tavla .uidje" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr ".i ca mipri le crakemsazycimde" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr ".i ca viska le crakemsazycimde" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Erase EOF" +msgstr "la'o gy.Erase OEF.gy." + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Accept" +msgstr "fitytu'i" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Mode Change" +msgstr "la'o gy.Mode Change.gy." + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "zu'e muvdu" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "zulselpevysmacu" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "mijyselpevysmacu" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +#, fuzzy +msgid "OEM Clear" +msgstr "la'o gy.OEM Clear.gy." + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "ri'u muvdu" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "prityselpevysmacu" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +#, fuzzy +msgid "X Button 1" +msgstr "la'o gy.X Button 1.gy." + +#: src/client/keycode.cpp +#, fuzzy +msgid "X Button 2" +msgstr "la'o gy.X Button 2.gy." + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr ".i da nabmi fi le nu kibycpa la'o zoi. $1 .zoi" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Autoforward" +msgstr "za'i ca'u muvdu" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "ti'a muvdu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Change camera" +msgstr "gafygau lo lerpoijaspu" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "tavla" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "minde" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "samtrotci" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "jdikygau lo ni sance" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "falcru" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "ca'u muvdu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "zengau lo ni sance" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "sorcu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "plipe" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Local command" +msgstr "minde" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "se lamli'e fi lu'i le dacti" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "lamli'e fi lu'i le dacti" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "cuxna fi lu'i le se kuspe" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "vidnyxra" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "masno cadzu" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle HUD" +msgstr "mu'e co'a jonai mo'u vofli" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle chat log" +msgstr "mu'e co'a jonai mo'u sutra" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle fast" +msgstr "mu'e co'a jonai mo'u sutra" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle fly" +msgstr "mu'e co'a jonai mo'u vofli" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle fog" +msgstr "mu'e co'a jonai mo'u vofli" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle minimap" +msgstr "mu'e co'a jonai mo'u sutra" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle pitchmove" +msgstr "mu'e co'a jonai mo'u sutra" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "press key" +msgstr ".i ko da'ergau pa batke" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "basti" + +#: src/gui/guiPasswordChange.cpp +#, fuzzy +msgid "New Password" +msgstr "lo cnino lerpoijaspu" + +#: src/gui/guiPasswordChange.cpp +#, fuzzy +msgid "Old Password" +msgstr "lo slabu lerpoijaspu" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr ".i lu'i le re lerpoijaspu na simxu le ka mintu" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "sisti" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy +msgid "Muted" +msgstr "ko da'ergau le batke" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "lo ni sance " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "jbo" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr ".i ko ckaji le ka da zo'u jdice le du'u da cmene" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "cibyca'u dilnu" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr ".i benji le notci ro se samtcise'u ca ro nu le samtcise'u cu samfli" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +".i benji le notci ro se samtcise'u ca ro nu le samtcise'u co'u samtcise'u" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "cmene le munje" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "gubysku zo'e pe tu'a le samtcise'u" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "krefu samjo'e te preti ba ro nu samfli" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatic forward key" +msgstr "za'i ca'u muvdu" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "mu'e plipe" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Backward key" +msgstr "za'i ti'a muvdu" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "jicmu se curmi" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "puvyrelyli'iju'e" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bind address" +msgstr ".i ca'o troci lo nu facki lo samjudri" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "gafygau lo lerpoijaspu" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "minde" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat key" +msgstr "samta'a" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr ".i ca viska le tavla .uidje" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cinematic mode" +msgstr "le nu finti kelci" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cinematic mode key" +msgstr "le nu finti kelci" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "lo samtciselse'u" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client modding" +msgstr "lo samtciselse'u" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client side modding restrictions" +msgstr "lo samtciselse'u" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "lo samtciselse'u" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "dilnu" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Clouds in menu" +msgstr "lo ralju" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "le bumgapci cu skari" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Colored shadows" +msgstr "le bumgapci cu skari" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Command key" +msgstr "minde" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Connect glass" +msgstr "lo jorne blaci" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Connect to external media server" +msgstr ".i ca'o troci lo za'i samjo'e lo samse'u" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ContentDB URL" +msgstr "ranji" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "finti se kelci" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "zmiselcu'a fi lu'i ro lerpoijaspu" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "datni" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "za'i ri'u muvdu" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "kakpa kantu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Disable anticheat" +msgstr "lo kantu" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Fallback font path" +msgstr "no" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Forward key" +msgstr "za'i ca'u muvdu" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "se kelci" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr ".i ca viska le crakemsazycimde" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Inventory key" +msgstr "lo dacti uidje" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Jump key" +msgstr "mu'e plipe" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "bangu" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Left key" +msgstr "za'i zu'e muvdu" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "lo xutla se gusni" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Main menu script" +msgstr "lo ralju" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "lo puvrmipmepi" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mute key" +msgstr "ko da'ergau le batke" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "te samjo'e" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "lo xutla se gusni" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move key" +msgstr "le nu finti kelci" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "le nu finti kelci" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "puvyrelyli'iju'e" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Range select key" +msgstr "mu'e cuxna fi le'i se kuspe" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Right key" +msgstr "za'i ri'u muvdu" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "vidnyxra" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "vidnyxra" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "veirjudri le samtcise'u" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "cmene le samtcise'u" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "ve skicu le samtcise'u" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "veirjudri le samtcise'u" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "judri le samtcise'u" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "ve skicu le samtcise'u" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "cmene le samtcise'u" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "judrnporte le samtcise'u" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "judrnporte le samtcise'u" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist URL" +msgstr "lo samtcise'u" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "lo samtcise'u" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "judri le ti'orkemsamtci" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Smooth lighting" +msgstr "lo xutla se gusni" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneak key" +msgstr "za'i masno cadzu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed" +msgstr "za'i masno cadzu" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "te tcimi'e" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Trilinear filtering" +msgstr "lo puvycibli'iju'e" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "lo ni sance" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving Nodes" +msgstr ".i ca'o samymo'i lo me la'o gy.node.gy." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving leaves" +msgstr "lo melbi pezli" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr ".i ca'o samymo'i lo me la'o gy.node.gy." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "lo melbi pezli" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "lo melbi pezli" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "lo melbi pezli" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "World start time" +msgstr "munje cmene" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- finti se kelci: " + +#~ msgid "Address / Port" +#~ msgstr "lo samjudri jo'u judrnporte" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr ".i xu do djica le nu xruti le do nonselkansa munje" + +#~ msgid "Back" +#~ msgstr "xruti" + +#~ msgid "Basic" +#~ msgstr "jicmu" + +#, fuzzy +#~ msgid "Bump Mapping" +#~ msgstr "lo puvrmipmepi" + +#~ msgid "Configure" +#~ msgstr "tcimi'e" + +#~ msgid "Connect" +#~ msgstr "co'a samjo'e" + +#~ msgid "Credits" +#~ msgstr "liste lu'i ro gunka" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "" +#~ ".i ko kibycpa pa se kelci to mupli fa la .maintest. se kelci toi la'o " +#~ "zoi. minetest.net .zoi" + +#~ msgid "Download one from minetest.net" +#~ msgstr ".i ko kibycpa pa se kelci la'o zoi. minetest.net .zoi" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr ".i ca'o kibycpa la'o zoi. $1 .zoi je cu samtcise'a ri .i ko denpa" + +#, fuzzy +#~ msgid "Enable VBO" +#~ msgstr "selpli" + +#~ msgid "Game" +#~ msgstr "se kelci" + +#~ msgid "Main" +#~ msgstr "ralju" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "lo ralju" + +#~ msgid "Name / Password" +#~ msgstr "lo cmene .e lo lerpoijaspu" + +#~ msgid "Name/Password" +#~ msgstr "cmene .i lerpoijaspu" + +#~ msgid "No" +#~ msgstr "na go'i" + +#~ msgid "Ok" +#~ msgstr "je'e" + +#~ msgid "Player name" +#~ msgstr "plicme" + +#~ msgid "Reset singleplayer world" +#~ msgstr "xruti le nonselkansa munje" + +#, fuzzy +#~ msgid "Server / Singleplayer" +#~ msgstr "pa kelci" + +#, fuzzy +#~ msgid "Special key" +#~ msgstr "za'i masno cadzu" + +#~ msgid "Start Singleplayer" +#~ msgstr "co'a nonselkansa kelci" + +#~ msgid "Yes" +#~ msgstr "go'i" + +#, fuzzy +#~ msgid "You died." +#~ msgstr ".i do morsi" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/kk/minetest.po b/po/kk/minetest.po new file mode 100644 index 0000000..7e97de7 --- /dev/null +++ b/po/kk/minetest.po @@ -0,0 +1,6872 @@ +msgid "" +msgstr "" +"Project-Id-Version: Kazakh (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2020-09-09 01:23+0000\n" +"Last-Translator: Fontan 030 <pomanfedurin@gmail.com>\n" +"Language-Team: Kazakh <https://hosted.weblate.org/projects/minetest/minetest/" +"kk/>\n" +"Language: kk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Мәзірге шығу" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "Бір ойыншы" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "Бір ойыншы" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Lua скриптінде қате кездесті:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Қате кездесті:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Басты мәзір" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Болдырмау" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Мод:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Ойын сипаттамасы жоқ." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Сақтау" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "қосылған" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "Жүктелуде..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Ойындар" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "Жою" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Модтар" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "No updates" +msgstr "Жаңарту" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Жою" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Жаңарту" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Жою" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Көлдер" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Жою" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "Құпия сөзді өзгерту" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Іздеу" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Жүктелуде..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Атауын өзгерту" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Жаңа" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D бұлттар" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Бисызықты фильтрация" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Жоқ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Бөлшектер" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Баптаулар" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Текстурлеу:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Үшсызықты фильтрация" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Басты мәзір" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Ойыншының аты тым ұзын." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "" + +#: src/client/game.cpp +msgid "- Public: " +msgstr "" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Қате кездесті:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Құпия сөзді өзгерту" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Жалғастыру" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Мәзірге шығу" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Ойыннан шығу" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Тұман қосылды" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "Бір ойыншы" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Бір ойыншы" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Чат жасырылды" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Чат көрсетілді" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD жасырылды" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD көрсетілді" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Сол Win" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Ойнау" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Бос орын" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Миникарта жасырылды" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "kk" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D бұлттар" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Алма ағаштары шуы" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Қол инерциясы" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Чат көрсетілді" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Чат көрсетілді" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Тұман" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Ойындар" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Графика" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Графика" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Графика" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Гравитация" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "HUD көрсетілді" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Физика" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Баптаулар" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Видеодрайвер" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Жүру жылдамдығы" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Үлкен үңгірлердің жоғарғы шегінің Y координаты." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "FreeType fonts" +#~ msgstr "FreeType қаріптері" + +#~ msgid "Game" +#~ msgstr "Ойын" + +#~ msgid "Main" +#~ msgstr "Басты мәзір" + +#~ msgid "No" +#~ msgstr "Жоқ" + +#~ msgid "Yes" +#~ msgstr "Иә" + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/kn/minetest.po b/po/kn/minetest.po new file mode 100644 index 0000000..7d640cc --- /dev/null +++ b/po/kn/minetest.po @@ -0,0 +1,6897 @@ +msgid "" +msgstr "" +"Project-Id-Version: Kannada (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2021-01-02 07:29+0000\n" +"Last-Translator: Tejaswi Hegde <tejaswihegde1@gmail.com>\n" +"Language-Team: Kannada <https://hosted.weblate.org/projects/minetest/" +"minetest/kn/>\n" +"Language: kn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.4.1-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "ಮುಖ್ಯ ಮೆನುಗೆ ಹಿಂತಿರುಗಿ" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "ಮತ್ತೆ ಹುಟ್ಟು" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "ನೀನು ಸತ್ತುಹೋದೆ" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "ಸರಿ" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "ಒಂದು ಲುವಾ ಸ್ಕ್ರಿಪ್ಟ್ ನಲ್ಲಿ ತಪ್ಪಾಗಿದೆ:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "ದೋಷ ವೊಂದು ಸಂಭವಿಸಿದೆ:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "ಮುಖ್ಯ ಮೆನು" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "ಮರುಸಂಪರ್ಕಿಸು" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "ಸರ್ವರ್ ಮರುಸಂಪರ್ಕ ಮಾಡಲು ಕೇಳಿದೆ:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "ಪ್ರೋಟೋಕಾಲ್ ಆವೃತ್ತಿ ಹೊಂದಿಕೆಯಾಗಿಲ್ಲ. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "ಸರ್ವರ್ ಪ್ರೋಟೋಕಾಲ್ ಆವೃತ್ತಿ $1 ಅನ್ನು ಜಾರಿಗೊಳಿಸುತ್ತದೆ. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "ಸರ್ವರ್ $1 ಮತ್ತು $2 ನಡುವೆಯ ಪ್ರೋಟೋಕಾಲ್ ಅವೃತ್ತಿಗಳನ್ನು ಬೆಂಬಲಿಸುತ್ತದೆ. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "ನಾವು $ 1 ಪ್ರೋಟೋಕಾಲ್ ಆವೃತ್ತಿಯನ್ನು ಮಾತ್ರ ಬೆಂಬಲಿಸುತ್ತೇವೆ." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "ಆವೃತ್ತಿ $1 ಮತ್ತು $2 ನಡುವಿನ ಪ್ರೋಟೋಕಾಲ್ ಆವೃತ್ತಿಯನ್ನು ನಾವು ಬೆಂಬಲಿಸುತ್ತೇವೆ." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "ರದ್ದುಮಾಡಿ" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "ಅವಲಂಬನೆಗಳು:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "ಎಲ್ಲವನ್ನೂ ನಿಷ್ಕ್ರಿಯೆಗೊಳಿಸು" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "ಮಾಡ್ ಪ್ಯಾಕ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "ಎಲ್ಲವನ್ನೂ ಸಕ್ರಿಯಗೊಳಿಸಿ" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "ಮಾಡ್ ಪ್ಯಾಕ್ ಕ್ರಿಯಾತ್ಮಕಗೊಳಿಸಿ" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"ಅನುಮತಿಸದೇ ಇರುವ ಅಕ್ಷರಗಳನ್ನು ಹೊಂದಿರುವ ುದರಿಂದ mod \"$1\" ಅನ್ನು ಕ್ರಿಯಾತ್ಮಕಗೊಳಿಸಲು " +"ವಿಫಲವಾಗಿದೆ. ಕೇವಲ ಅಕ್ಷರಗಳನ್ನು [a-z0-9_] ಗೆ ಮಾತ್ರ ಅನುಮತಿಸಲಾಗುತ್ತದೆ." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "ಇನ್ನಷ್ಟು ಮಾಡ್ ಗಳನ್ನು ಹುಡುಕಿ" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "ಮಾಡ್:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "(ಐಚ್ಛಿಕ) ಅವಲಂಬನೆಗಳು ಇಲ್ಲ" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "ಯಾವುದೇ ಆಟದ ವಿವರಣೆ ಒದಗಿಸಿಲ್ಲ." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "ಯಾವುದೇ ಗಟ್ಟಿ ಅವಲಂಬನೆಗಳಿಲ್ಲ" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "ಯಾವುದೇ ಮಾಡ್ಪ್ಯಾಕ್ ವಿವರಣೆ ಕೊಟ್ಟಿಲ್ಲ." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "ಯಾವುದೇ ಐಚ್ಛಿಕ ಅವಲಂಬನೆಗಳಿಲ್ಲ" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "ಐಚ್ಛಿಕ ಅವಲಂಬನೆಗಳು:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "ಸೇವ್" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "ಪ್ರಪಂಚ:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "ಡೌನ್ ಲೋಡ್ ಆಗುತ್ತಿದೆ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "ಎಲ್ಲಾ ಪ್ಯಾಕೇಜುಗಳು" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "ಮುಖ್ಯ ಮೆನುಗೆ ಹಿಂತಿರುಗಿ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "cURL ಇಲ್ಲದೆ ಮೈನ್ ಟೆಸ್ಟ್ ಅನ್ನು ಕಂಪೈಲ್ ಮಾಡಿದಾಗ ContentDB ಲಭ್ಯವಿಲ್ಲ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "ಡೌನ್ ಲೋಡ್ ಆಗುತ್ತಿದೆ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "$1 ಡೌನ್ಲೋಡ್ ಮಾಡಲು ಆಗಿಲ್ಲ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "ಆಟಗಳು" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "ಇನ್ಸ್ಟಾಲ್" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "ಇನ್ಸ್ಟಾಲ್" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "ಐಚ್ಛಿಕ ಅವಲಂಬನೆಗಳು:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "ಮಾಡ್‍ಗಳು" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "ಯಾವುದೇ ಪ್ಯಾಕೇಜ್ ಗಳನ್ನು ಪಡೆಯಲಾಗಲಿಲ್ಲ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "ಫಲಿತಾಂಶಗಳಿಲ್ಲ" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "No updates" +msgstr "ನವೀಕರಿಸಿ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "ಟೆಕ್‍ಸ್ಚರ್ ಪ್ಯಾಕ್ಗಳು" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "ಅನ್ಇನ್ಸ್ಟಾಲ್" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "ನವೀಕರಿಸಿ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "\"$1\" ಹೆಸರಿನ ಒಂದು ಪ್ರಪಂಚವು ಈಗಾಗಲೇ ಇದೆ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "ಹೆಚ್ಚುವರಿ ಭೂಪ್ರದೇಶ" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biome blending" +msgstr "ಪ್ರದೇಶ ಮಿಶ್ರಣ" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biomes" +msgstr "ಪ್ರದೇಶಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caverns" +msgstr "ಗುಹೆಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caves" +msgstr "ಗುಹೆಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Create" +msgstr "ರಚಿಸು" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "ಅಲಂಕಾರಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Dungeons" +msgstr "ಡಂಗೆನ್ಸ್" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "ಸಮತಟ್ಟಾದ ಭೂಪ್ರದೇಶ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "ಆಕಾಶದಲ್ಲಿ ತೇಲುತ್ತಿರುವ ಭೂಭಾಗಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Floatlands (experimental)" +msgstr "ತೇಲುವ ಭೂಮಿಗಳು (ಪ್ರಾಯೋಗಿಕ)" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "ಫ್ರಾಕ್ಟಲ್ ಅಲ್ಲದ ಭೂಪ್ರದೇಶ ಸೃಷ್ಟಿಸಿ: ಸಾಗರಗಳು ಮತ್ತು ಭೂಗರ್ಭ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "ಬೆಟ್ಟಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Humid rivers" +msgstr "ಆರ್ದ್ರ ನದಿಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "ನದಿಗಳ ಸುತ್ತ ತೇವಾಂಶ ವನ್ನು ಹೆಚ್ಚಿಸುತ್ತದೆ" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "ಇನ್ಸ್ಟಾಲ್" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "ಕೆರೆ" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "ಕಡಿಮೆ ಆರ್ದ್ರತೆ ಮತ್ತು ಅಧಿಕ ಶಾಖವು ಆಳವಿಲ್ಲದ ಅಥವಾ ಶುಷ್ಕ ನದಿಗಳನ್ನು ಉಂಟುಮಾಡುತ್ತದೆ" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen" +msgstr "ಮ್ಯಾಪ್ಜೆನ್" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen flags" +msgstr "ಮ್ಯಾಪ್ಜೆನ್ ಧ್ವಜಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mapgen-specific flags" +msgstr "ಮ್ಯಾಪ್ಜೆನ್-ನಿರ್ದಿಷ್ಟ ಧ್ವಜಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "ಪರ್ವತಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mud flow" +msgstr "ಮಣ್ಣಿನ ಹರಿವು" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "ಸುರಂಗಗಳು ಮತ್ತು ಗುಹೆಗಳ ಜಾಲ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "ಯಾವುದೇ ಆಟ ಆಯ್ಕೆಯಾಗಿಲ್ಲ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "ಎತ್ತರದಲ್ಲಿ ಶಾಖವನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "ಎತ್ತರದಲ್ಲಿ ತೇವಾಂಶವನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "ನದಿಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "ಸಮುದ್ರ ಮಟ್ಟದಲ್ಲಿರುವ ನದಿಗಳು" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Seed" +msgstr "ಬೀಜ" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Smooth transition between biomes" +msgstr "ಪ್ರದೇಶಗಳ ನಡುವೆ ಸುಗಮವಾದ ಸ್ಥಿತ್ಯಂತರ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "ಹುಡುಕು" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "ಲೋಡ್ ಆಗುತ್ತಿದೆ..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "ಪಬ್ಲಿಕ್ ಸರ್ವರ್ಲಿಸ್ಟ್ಅನ್ನು ರಿಎನೆಬಲ್ ಮಾಡಿ ಮತ್ತು ಅಂತರ್ಜಾಲ ಸಂಪರ್ಕ ಪರಿಶೀಲಿಸಿ." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "ಆರ್ದ್ರ ನದಿಗಳು" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "ತೇಲುವ ಭೂಮಿಗಳು (ಪ್ರಾಯೋಗಿಕ)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "" + +#: src/client/game.cpp +msgid "- Public: " +msgstr "" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "ದೋಷ ವೊಂದು ಸಂಭವಿಸಿದೆ:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "$1 ಡೌನ್ಲೋಡ್ ಮಾಡಲು ಆಗಿಲ್ಲ" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "kn" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "ಅಲಂಕಾರಗಳು" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "ಆಟಗಳು" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "ಆರ್ದ್ರ ನದಿಗಳು" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "Back" +#~ msgstr "ಹಿಂದೆ" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "minetest.net ನಿಂದ ಮೈನ್ಟೆಸ್ಟ್ ಗೇಮ್ ನಂತಹ ಆಟವನ್ನು ಡೌನ್ ಲೋಡ್ ಮಾಡಿ" + +#~ msgid "Download one from minetest.net" +#~ msgstr "minetest.net ಇಂದ ಒಂದನ್ನು ಡೌನ್ ಲೋಡ್ ಮಾಡಿ" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "$1 ಡೌನ್ಲೋಡ್ ಮತ್ತು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗುತ್ತಿದೆ, ದಯವಿಟ್ಟು ನಿರೀಕ್ಷಿಸಿ..." + +#~ msgid "Game" +#~ msgstr "ಆಟ" + +#~ msgid "Ok" +#~ msgstr "ಸರಿ" + +#, fuzzy +#~ msgid "View" +#~ msgstr "ತೋರಿಸು" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "ನೀನು ಸತ್ತುಹೋದೆ" + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/ko/minetest.po b/po/ko/minetest.po new file mode 100644 index 0000000..f309433 --- /dev/null +++ b/po/ko/minetest.po @@ -0,0 +1,7739 @@ +msgid "" +msgstr "" +"Project-Id-Version: Korean (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-05-08 00:22+0000\n" +"Last-Translator: Han So Ri <2_0_2_0_@naver.com>\n" +"Language-Team: Korean <https://hosted.weblate.org/projects/minetest/minetest/" +"ko/>\n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.12.1\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Empty command." +msgstr "채팅 명렁어" + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "메인 메뉴로 나가기" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "유효하지 않은 명령어: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "온라인 플레이어 목록" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "온라인 플레이어: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "서버에서 사용 할 수 없는 명령어입니다." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "리스폰" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "사망했습니다" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "지역 명령어" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "지역 명령어" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "확인" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Lua 스크립트에서 오류가 발생했습니다:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "오류가 발생했습니다:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "메인 메뉴" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "재연결" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "서버에 재접속 하세요:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "월드 선택:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "프로토콜 버전이 알맞지 않습니다. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "서버는 프로토콜 버전 $1을(를) 사용합니다. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "서버가 프로토콜 버전 $1와(과) $2 두 가지를 제공합니다. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "프로토콜 버전 $1만 제공합니다." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "프로토콜 버전 $1와(과) $2 사이의 버전을 제공합니다." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "취소" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "의존:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "모두 사용안함" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "모드 팩 비활성화" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "모두 활성화" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "모드 팩 활성화" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"\"$1\"은(는) 사용할 수 없는 문자이기에 모드를 활성화하지 못했습니다. 이름에" +"는 [a-z,0-9,_]만 사용할 수 있습니다." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "더 많은 모드 찾기" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "모드:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "종속성 없음 (옵션)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "게임 설명이 제공되지 않았습니다." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "요구사항 없음" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "모드 설명이 제공되지 않았습니다." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "선택되지 않은 종속성" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "종속성 선택:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "저장" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "세계:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "활성화됨" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "다운 받는 중..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "모든 패키지" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "이미 설치됨" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "주 메뉴로 돌아가기" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "호스트 게임" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "cURL 없이 Minetest를 컴파일한 경우 ContentDB를 사용할 수 없습니다" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "다운 받는 중..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "$1을 다운로드하는 데에 실패했습니다" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "게임" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "설치" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "설치" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "종속성 선택:" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "" +"모드 설치: \"$1\"는(은) 지원 되지 않는 파일 형식 이거나 손상된 압축 파일입니" +"다" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "모드" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "검색할 수 있는 패키지가 없습니다" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "결과 없음" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "업데이트 없음" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "찾을 수 없음" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "텍스처 팩" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "제거" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "업데이트" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "\"$1\" 은(는) 이미 존재합니다" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "추가 지형" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "한랭 고도" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "건조한 고도" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "혼합 생물 군계" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "생물 군계" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "석회동굴" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "동굴" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "만들기" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "장식" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "경고: Development Test는 개발자를 위한 모드입니다." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "던전" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "평평한 지형" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "하늘에 떠있는 광대한 대지" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "평평한 땅 (실험용)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "추상적이지 않은 지형 생성: 바다와 지하" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "언덕" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "습한 강" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "강 주변의 습도 증가" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "설치" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "호수" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "낮은 습도와 높은 열로 인해 얕거나 건조한 강이 발생함" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "세계 생성기" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "세계 생성기 신호" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "세계 생성기-특정 신호" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "산" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "진흙 흐름" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "터널과 동굴의 네트워크" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "선택된 게임이 없습니다" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "고도에 따른 열 감소" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "고도에 따른 습도 감소" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "강" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "해수면 강" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "시드" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "생물 군계 간 부드러운 전환" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"지형에 나타나는 구조물 (v6에서 만든 나무와 정글 및 풀에는 영향을 주지 않음)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "지형에 나타나는 구조물(일반적으로 나무와 식물)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "온대, 사막" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "온대, 사막, 정글" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "온대, 사막, 정글, 툰드라(한대), 침엽수 삼림 지대" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "침식된 지형" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "나무와 정글 , 풀" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "강 깊이 변화" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "지하의 큰 동굴의 깊이 변화" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "세계 이름" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "게임이 설치되어 있지 않습니다." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "$1을(를) 삭제하시겠습니까?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "삭제" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: \"$1\"을(를) 삭제하지 못했습니다" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: 잘못된 경로\"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "\"$1\"을(를) 삭제하시겠습니까?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "비밀번호 확인" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Mapgen 이름" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "새로운 비밀번호" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "비밀번호가 맞지 않습니다!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "등록하고 참여" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "수락" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "모드 팩 이름 바꾸기:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"이 모드팩에는 modpack.conf에 명시적인 이름이 부여되어 있으며, 이는 여기서 이" +"름을 바꾸는 것을 적용하지 않습니다." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(설정에 대한 설명이 없습니다)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2차원 소음" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< 설정 페이지로 돌아가기" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "열기" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "컨텐츠" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "컨텐츠" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "비활성화됨" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "수정" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "활성화됨" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "빈약도" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "옥타브" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "오프셋" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "플레이어 전송 거리" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "유효한 정수를 입력해주세요." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "유효한 숫자를 입력해주세요." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "기본값 복원" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "스케일" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "찾기" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "경로를 선택하세요" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "파일 선택" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "기술적 이름 보기" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "값은 $1 이상이어야 합니다." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "값이 $1을 초과하면 안 됩니다." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X 분산" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y 분산" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z 분산" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "절댓값" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "기본값" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "맵 부드러움" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (활성화됨)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 모드" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "$1을 $2에 설치하는데 실패했습니다" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "모드 설치: $1를(을) 찾을 수 없습니다" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "모드 설치: 모드 팩 $1 (이)의 올바른 폴더이름을 찾을 수 없습니다" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "설치 모드: 모드 팩 $1 (이)의 올바른 폴더이름을 찾을 수 없습니다" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "$1을 텍스쳐팩으로 설치할 수 없습니다" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "$1을 설치할 수 없습니다" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "$1 모드를 설치할 수 없습니다" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "$1 모드팩을 설치할 수 없습니다" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "불러오는 중..." + +#: builtin/mainmenu/serverlistmgr.lua +#, fuzzy +msgid "Public server list is disabled" +msgstr "클라이언트 스크립트가 비활성화됨" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "인터넷 연결을 확인한 후 서버 목록을 새로 고쳐보세요." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "활동적인 공헌자" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Active renderer:" +msgstr "객체 전달 범위 활성화" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "코어 개발자" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "경로를 선택하세요" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "이전 공헌자들" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "이전 코어 개발자들" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "디버그 정보 보기" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "온라인 컨텐츠 검색" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "컨텐츠" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "비활성화된 텍스쳐 팩" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "정보:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "설치된 패키지:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "요구사항 없음." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "사용 가능한 패키지 설명이 없습니다" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "이름 바꾸기" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "패키지 삭제" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "텍스쳐 팩 사용" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "서버 알리기" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "바인딩 주소" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "크리에이티브 모드" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "데미지 활성화" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "호스트 게임" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "호스트 서버" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "ContentDB에서 게임 설치" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "새로 만들기" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "월드를 만들거나 선택하지 않았습니다!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "게임하기" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "포트" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "월드 선택:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "월드 선택:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "서버 포트" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "게임 시작" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "- 주소: " + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "지우기" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "크리에이티브 모드" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "데미지" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "즐겨찾기" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "게임 참가" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "핑" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "서버 알리기" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "원격 포트" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "서버 설명" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2 x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D 구름 효과" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4 x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8 배속" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "모든 설정" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "매끄럽게 표현하기:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "스크린 크기 자동 저장" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "이중 선형 필터" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "키 변경" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "연결된 유리" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Dynamic shadows" +msgstr "글꼴 그림자" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "글꼴 그림자" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "아름다운 나뭇잎 효과" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "밉 맵" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "밉맵 + Aniso. 필터" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "필터 없음" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "밉 맵 없음" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Node 강조" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Node 설명" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "없음" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "불투명한 나뭇잎 효과" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "불투명한 물 효과" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "입자 효과" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "화면:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "설정" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "쉐이더" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "평평한 땅 (실험용)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "쉐이더 (사용할 수 없음)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "단순한 나뭇잎 효과" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "부드러운 조명 효과" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "질감:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "톤 매핑" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "터치 임계값: (픽셀)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "선형 필터" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "움직이는 나뭇잎 효과" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "물 등의 물결효과" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "움직이는 식물 효과" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "연결 오류 (시간초과)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "연결 시간이 초과했습니다." + +#: src/client/client.cpp +msgid "Done!" +msgstr "완료!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "node 초기값 설정중" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "node 초기값 설정중..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "텍스쳐 로딩중..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "쉐이더 개축중..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "연결 오류 (시간초과)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "게임을 찾지 못했거나 로딩할 수 없습니다\"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "인식할 수 없는 게임 사양입니다." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "주 메뉴" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "월드를 선택하지 않아 주소를 받을 수 없습니다." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "이름이 너무 깁니다." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "이름을 선택하세요!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "패스워드 파일을 여는데 실패했습니다: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "월드 경로가 존재하지 않습니다: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"자세한 내용은 debug.txt을 확인 합니다." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- 주소: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- 모드: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- 포트: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- 공개: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- Player vs Player: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- 서버 이름: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "오류가 발생했습니다:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "자동 전진 비활성화" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "자동 전진 활성화" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "카메라 업데이트 비활성화" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "카메라 업데이트 활성화" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "비밀번호 변경" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "시네마틱 모드 비활성화" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "시네마틱 모드 활성화" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "클라이언트 모딩" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "클라이언트 스크립트가 비활성화됨" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "서버 연결중..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "계속" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"조작:\n" +"-%s: 앞으로 이동\n" +"-%s:뒤로 이동\n" +"-%s:왼쪽으로 이동\n" +"-%s:오른쪽으로 이동\n" +"-%s: 점프/오르기\n" +"-%s:조용히 걷기/내려가기\n" +"-%s:아이템 버리기\n" +"-%s:인벤토리\n" +"-마우스: 돌기/보기\n" +"-마우스 왼쪽 클릭: 땅파기/펀치\n" +"-마우스 오른쪽 클릭: 두기/사용하기\n" +"-마우스 휠:아이템 선택\n" +"-%s: 채팅\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "클라이언트 만드는 중..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "서버 만드는 중..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "디버그 정보 및 프로파일러 그래프 숨기기" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "디버그 정보 표시" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "디버그 정보, 프로파일러 그래프 , 선 표현 숨김" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"기본 컨트롤: \n" +"메뉴 표시 없을 때:\n" +"- 단일 탭: 버튼 활성화\n" +"- 더블 탭: 배치/사용\n" +"- 드래그: 둘러보기\n" +" 메뉴/인벤토리:\n" +"- 더블 탭 (외부):\n" +" -->닫기\n" +"- 무더기(stack) 터치, 슬롯 터치: \n" +" --> 무더기(stack) 이동 \n" +"- 터치 및 드래그, 다른 손가락으로 탭\n" +" --> 슬롯에 한개의 아이템 배치\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "제한없는 시야 범위 비활성화" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "제한없는 시야 범위 활성화" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "클라이언트 만드는 중..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "메뉴로 나가기" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "게임 종료" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "고속 모드 비활성화" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "고속 모드 활성화" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "고속 모드 활성화(참고 : '고속'에 대한 권한 없음)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "비행 모드 비활성화" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "비행 모드 활성화" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "비행 모드 활성화 (참고 : '비행'에 대한 권한 없음)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "안개 비활성화" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "안개 활성화" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "게임 정보:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "게임 일시정지" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "호스팅 서버" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "아이템 정의중..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "미디어..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "게임 또는 모드에 의해 현재 미니맵 비활성화" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "싱글 플레이어" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Noclip 모드 비활성화" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Noclip 모드 활성화" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Noclip 모드 활성화 (참고 : 'noclip'에 대한 권한 없음)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Node 정의중..." + +#: src/client/game.cpp +msgid "Off" +msgstr "끄기" + +#: src/client/game.cpp +msgid "On" +msgstr "켜기" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "피치 이동 모드 비활성화" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "피치 이동 모드 활성화" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "프로파일러 그래프 보이기" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "원격 서버" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "주소 분석중..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "서버가 닫혔습니다..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "싱글 플레이어" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "볼륨 조절" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "음소거" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "사운드 시스템 비활성화" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "본 빌드에서 지원되지 않는 사운드 시스템" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "음소거 해제" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "시야 범위 %d로 바꿈" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "시야 범위 최대치 : %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "시야 범위 최소치 : %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "볼륨 %d%%로 바꿈" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "선 표면 보이기" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "게임 또는 모드에 의해 현재 확대 비활성화" + +#: src/client/game.cpp +msgid "ok" +msgstr "확인" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "채팅 숨기기" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "채팅 보이기" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD 숨기기" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD 보이기" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "프로파일러 숨기기" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "프로파일러 보이기 (%d중 %d 페이지)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "애플리케이션" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "뒤로" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "캡스락" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "컨트롤" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "아래" + +#: src/client/keycode.cpp +msgid "End" +msgstr "끝" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "EOF 지우기" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "실행" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "도움말" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME 확인" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME 변환" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME 종료" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME 모드 변경" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME 변환 안함" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "왼쪽" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "왼쪽 버튼" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "왼쪽 컨트롤" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "왼쪽 메뉴" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "왼쪽 쉬프트" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "왼쪽 창" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "메뉴" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "가운데 버튼" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "숫자 키패드 *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "숫자 키패드 +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "숫자 키패드 -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "숫자 키패드 ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "숫자 키패드 /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "숫자 키패드 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "숫자 키패드 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "숫자 키패드 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "숫자 키패드 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "숫자 키패드 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "숫자 키패드 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "숫자 키패드 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "숫자 키패드 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "숫자 키패드 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "숫자 키패드 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM 초기화" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "페이지 내리기" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "페이지 올리기" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "일시 정지" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "시작" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "출력" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "되돌리기" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "오른쪽" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "오른쪽 버튼" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "오른쪽 컨트롤" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "오른쪽 메뉴" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "오른쪽 쉬프트" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "오른쪽 창" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "스크롤 락" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "선택" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "쉬프트" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "잠자기" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "스냅샷" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "스페이스바" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "탭" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "위" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X 버튼 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X 버튼 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "확대/축소" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "미니맵 숨김" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "레이더 모드의 미니맵, 1배 확대" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "표면 모드의 미니맵, 1배 확대" + +#: src/client/minimap.cpp +#, fuzzy +msgid "Minimap in texture mode" +msgstr "최소 텍스처 크기" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "$1을 다운로드하는 데에 실패했습니다" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "계속하기" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "\"특별함\" = 아래로 타고 내려가기" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "자동전진" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "자동 점프" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "뒤로" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "카메라 변경" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "채팅" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "명령어" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "콘솔" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "범위 감소" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "볼륨 줄이기" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "\"점프\"를 두번 탭하여 비행" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "드롭하기" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "앞으로" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "범위 증가" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "볼륨 늘리기" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "인벤토리" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "점프" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "이미 사용하고 있는 키입니다" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "지역 명령어" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "음소거" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "다음 아이템" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "이전.아이템" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "범위 선택" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "스크린샷" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "살금살금" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "HUD 토글" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "채팅 기록 토글" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "고속 스위치" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "비행 스위치" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "안개 토글" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "미니맵 토글" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "자유시점 스위치" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "피치 이동 토글" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "키를 누르세요" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "변경" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "새로운 비밀번호" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "현재 비밀번호" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "비밀번호가 맞지 않습니다!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "나가기" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "음소거" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "볼륨 조절: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "ko" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "이름을 선택하세요!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) 가상 조이스틱의 위치를 수정합니다.\n" +"비활성화하면, 가상 조이스틱이 첫번째 터치 위치의 중앙에 위치합니다." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) 가상 조이스틱을 사용하여 \"aux\"버튼을 트리거합니다.\n" +"활성화 된 경우 가상 조이스틱은 메인 서클에서 벗어날 때 \"aux\"버튼도 탭합니" +"다." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X, Y, Z) '스케일' 단위로 세계 중심을 기준으로 프랙탈 오프셋을 정합니다.\n" +"원하는 지점을 (0, 0)으로 이동하여 적합한 스폰 지점을 만들거나 \n" +"'스케일'을 늘려 원하는 지점에서 '확대'할 수 있습니다.\n" +"기본값은 기본 매개 변수가있는 Mandelbrot 세트에 적합한 스폰 지점에 맞게 조정" +"되어 있으며 \n" +"다른 상황에서 변경해야 할 수도 있습니다. \n" +"범위는 대략 -2 ~ 2입니다. \n" +"노드의 오프셋에 대해\n" +"'스케일'을 곱합니다." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"노드에서 프랙탈의 (X, Y, Z) 스케일.\n" +"실제 프랙탈 크기는 2 ~ 3 배 더 큽니다.\n" +"이 숫자는 매우 크게 만들 수 있으며 프랙탈은 세계에 맞지 않아도됩니다.\n" +"프랙탈의 세부 사항을 '확대'하도록 늘리십시오.\n" +"기본값은 섬에 적합한 수직으로 쪼개진 모양이며 \n" +"기존 모양에 대해 3 개의 숫자를 \n" +"모두 동일하게 설정합니다." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "산의 모양 / 크기를 제어하는 2D 노이즈." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "언덕의 모양 / 크기를 제어하는 2D 노이즈." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "계단 형태 산의 모양 / 크기를 제어하는 2D 노이즈." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "능선 산맥의 크기 / 발생정도를 제어하는 2D 노이즈." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "언덕의 크기 / 발생정도를 제어하는 2D 노이즈." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "계단 형태의 산맥의 크기 / 발생정도를 제어하는 2D 노이즈." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "강 계곡과 채널에 위치한 2D 노이즈." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D 구름 효과" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D 모드" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "3D 모드 시차 강도" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "거대한 동굴을 정의하는 3D 노이즈." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"산의 구조와 높이를 정의하는 3D 노이즈.\n" +"또한 수상 지형 산악 지형의 구조를 정의합니다." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"플롯랜드의 구조를 정의하는 3D 노이즈.\n" +"기본값에서 변경하면 노이즈 '스케일'(기본값 0.7)이 필요할 수 있습니다.\n" +"이 소음의 값 범위가 약 -2.0 ~ 2.0 일 때 플로 트랜드 테이퍼링이 가장 잘 작동하" +"므로 \n" +"조정해야합니다." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "강 협곡 벽의 구조를 정의하는 3D 노이즈." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "지형을 정의하는 3D 노이즈." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"산 돌출부, 절벽 등에 대한 3D 노이즈. 일반적으로 작은 변화로 나타납니다." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "맵 당 던전 수를 결정하는 3D 노이즈." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3D 지원.\n" +"현재 지원되는 것:\n" +"- 없음: 3d 출력 없음.\n" +"- 입체 사진: 청록색/자홍색 3d.\n" +"- interlaced: odd/even line based polarisation screen support.↵\n" +"- topbottom: split screen top/bottom.↵\n" +"- sidebyside: split screen side by side.↵\n" +"- pageflip: quadbuffer based 3d." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"새로운 맵을 위해 선택할 시드, 빈칸이면 랜덤입니다.\n" +"메인메뉴에서 새로운 월드를 만들때 재정의 될 것입니다." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "서버 충돌 하는 경우 모든 사용자들에게 표시 될 메시지입니다." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "서버가 닫힐 때 모든 사용자들에게 표시 될 메시지입니다." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "ABM 간격" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "대기중인 블록의 절대 한계" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "공중에서 가속" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "중력 가속도, 노드는 초당 노드입니다." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "블록 수식어 활성" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "블록 관리 간격 활성화" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "블록 범위 활성" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "객체 전달 범위 활성화" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"연결할 주소입니다.\n" +"로컬 서버를 시작하려면 공백으로 두십시오.\n" +"주 메뉴의 주소 공간은 이 설정에 중복됩니다." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "node를 부술 때의 파티클 효과를 추가합니다." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"화면에 맞게 dpi 구성을 조정합니다 (X11 미지원 / Android 만 해당). 4k 화면 용." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"플롯랜드 레이어의 밀도를 조정합니다.\n" +"밀도를 높이려면 값을 늘리십시오. 양수 또는 음수입니다.\n" +"값 = 0.0 : 부피의 50 % o가 플롯랜드입니다.\n" +"값 = 2.0 ( 'mgv7_np_floatland'에 따라 더 높을 수 있음, \n" +"항상 확실하게 테스트 후 사용)는 단단한 플롯랜드 레이어를 만듭니다." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "아이템 이름 추가" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "고급" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"'감마 보정'을 적용하여 조명 곡선을 변경합니다.\n" +"값이 높을수록 중간 및 낮은 조명 수준이 더 밝아집니다.\n" +"값 '1.0'은 조명 곡선을 변경하지 않습니다.\n" +"이것은 일광 및 인공 조명에만 중요한 영향을 미칩니다.\n" +"빛은, 자연적인 야간 조명에 거의 영향을 미치지 않습니다." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "항상 비행 및 고속 모드" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "주변 occlusion 감마" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "플레이어가 10 초당 보낼 수있는 메시지의 양." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "계곡 증폭." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "이방성 필터링" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "서버 공지" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "이 서버 목록에 알림." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "아이템 이름 추가" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "툴팁에 아이템 이름 추가." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "사과 나무 노이즈" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "팔 관성" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"팔 관성,보다 현실적인 움직임을 제공합니다.\n" +"카메라가 움직일 때 팔도 함께 움직입니다." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "충돌 후 재연결 요청" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"이 거리에서 서버는 클라이언트로 전송되는 블록의 최적화를\n" +"활성화합니다.\n" +"작은 값은 눈에 띄는 렌더링 결함을 통해 \n" +"잠재적으로 성능을 크게 향상시킵니다 \n" +"(일부 블록은 수중과 동굴, 때로는 육지에서도 렌더링되지 않습니다).\n" +"이 값을 max_block_send_distance보다 큰 값으로 설정하면 \n" +"최적화가 비활성화됩니다.\n" +"맵 블록 (16 개 노드)에 명시되어 있습니다." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "자동 전진 키" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "단일 노드 장애물에 대한 자동 점프." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "서버 목록에 자동으로 보고." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "스크린 크기 자동 저장" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "자동 스케일링 모드" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "점프 키" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key for climbing/descending" +msgstr "오르기/내리기 에 사용되는 특수키" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "뒤로 이동하는 키" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "기본 지면 수준" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "기본 지형 높이." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "기본 권한" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "해변 잡음" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "해변 잡음 임계치" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "이중 선형 필터링" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "바인딩 주소" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Biome API 온도 및 습도 소음 매개 변수" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Biome 노이즈" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "블록 전송 최적화 거리" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "굵은 기울임 꼴 글꼴 경로" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "굵은 기울임 꼴 고정 폭 글꼴 경로" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "굵은 글꼴 경로" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "굵은 고정 폭 글꼴 경로" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "내부 사용자 빌드" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "기본 제공" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "카메라 변경" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"0에서 0.25 사이의 노드에서 카메라 '깎인 평면 근처'거리는 GLES 플랫폼에서만 작" +"동합니다. \n" +"대부분의 사용자는 이것을 변경할 필요가 없습니다.\n" +"값이 증가하면 약한 GPU에서 아티팩트를 줄일 수 있습니다. \n" +"0.1 = 기본값, 0.25 = 약한 태블릿에 적합한 값." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "카메라를 부드럽게" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "시네마틱 모드에서 카메라 부드럽게" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "카메라 업데이트 토글 키" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "동굴 잡음" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "동굴 잡음 #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "동굴 잡음 #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "동굴 너비" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "동굴1 잡음" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "동굴2 잡음" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "동굴 제한" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "동굴 잡음" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "동굴 테이퍼" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "동굴 임계치" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "동굴 상한선" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"빛 굴절 중심 범위 .\n" +"0.0은 최소 조명 수준이고 1.0은 최대 조명 수준입니다." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "채팅 메세지 강제퇴장 임계값" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "채팅 명렁어" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "채팅 글자 크기" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "채팅" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "채팅 기록 수준" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "채팅 메세지 수 제한" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "채팅 메세지 포맷" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "채팅 메세지 강제퇴장 임계값" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "채팅 메세지 최대 길이" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "채팅 스위치" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "채팅 보이기" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "청크 크기" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "시네마틱 모드" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "시네마틱 모드 스위치" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "깨끗하고 투명한 텍스처" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "클라이언트" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "클라이언트와 서버" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "클라이언트 모딩" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "클라이언트 측 모딩 제한" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "클라이언트 측 노드 조회 범위 제한" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "클라이언트 모딩" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "오르는 속도" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "구름 반지름" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "구름" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "구름은 클라이언트에 측면 효과." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "메뉴에 구름" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "색깔있는 안개" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Colored shadows" +msgstr "색깔있는 안개" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"컨텐츠 저장소에서 쉼표로 구분된 숨겨진 플래그 목록입니다.\n" +"\"nonfree\"는 Free Software Foundation에서 정의한대로 '자유 소프트웨어'로 분" +"류되지 않는 패키지를 숨기는 데 사용할 수 있습니다,\n" +"콘텐츠 등급을 지정할 수도 있습니다.\n" +"이 플래그는 Minetest 버전과 독립적이므로. \n" +"https://content.minetest.net/help/content_flags/에서,\n" +"전체 목록을 참조하십시오." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"쉼표로 구분된 모드의 리스트는 HTTP API에 접근 할 수 있습니다,\n" +"인터넷에서 데이터를 다운로드 하거나 업로드 할 수 있습니다." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"mod 보안이 켜져있는 경우에도 안전하지 않은 기능에 액세스 할 수있는 쉼표로 구" +"분 된 신뢰 할 수 있는 모드의 목록입니다\n" +"(request_insecure_environment ()를 통해)." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "명령 키" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "유리를 연결" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "외부 미디어 서버에 연결" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "노드에서 지원하는 경우 유리를 연결합니다." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "콘솔 투명도" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "콘솔 색" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "콘솔 높이" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "콘텐츠DB 블랙리스트 플래그" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "ContentDB URL주소" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "연속 전진" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"연속 전진 이동, 자동 전진 키로 전환.\n" +"비활성화하려면 자동 앞으로 이동 키를 다시 누르거나 뒤로 이동합니다." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "컨트롤" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"낮/밤 주기의 길이를 컨트롤.\n" +"예: \n" +"72 = 20 분, 360 = 4 분, 1 = 24 시간, 0 = 낮/밤/바뀌지 않고 그대로." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "호수 침하의 경사/깊이를 조절." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "산의 높이/경사를 조절." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"터널 너비를 제어하고 값이 작을수록 더 넓은 터널이 생성됩니다.\n" +"값> = 10.0은 터널 생성을 완전히 비활성화하고 집중적인 노이즈 계산을 \n" +"방지합니다." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "충돌 메시지" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "창의적인" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "십자선 투명도" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "십자선 투명도 (불투명 함, 0과 255 사이)." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "십자선 색" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "감도(DPI)" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "데미지" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "디버그 정보 토글 키" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "디버그 로그 파일 크기 임계치" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "디버그 로그 수준" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "볼륨 낮추기 키" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "전용 서버 단계" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "기본 가속" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "기본 게임" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"새로운 월드를 만들 때 기본 게임으로 시작합니다.\n" +"주 메뉴에서 월드를 만들 때 재정의 될 것입니다." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "기본 비밀 번호" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "기본 권한" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "기본 보고서 형식" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "기본 스택 크기" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "나무에 사과가 있는 영역 정의." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "모래 해변이 있는 지역을 정의합니다." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "높은 지형의 분포와 절벽의 가파른 정도를 정의합니다." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "더 높은 지형의 분포를 정의합니다." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "블록에 최대 플레이어 전송 거리를 정의 합니다 (0 = 무제한)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "건축 후 블록 전송 지연" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "도구 설명 표시 지연, 1000분의 1초." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "큰 동굴을 발견할 수 있는 깊이." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "큰 동굴을 발견할 수 있는 깊이." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "플레이어가 서버리스트에서 조인 할때 서버의 설명이 보여질 것입니다." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "블록 애니메이션 비동기화" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "장식" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "오른쪽 키" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "입자 효과" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Anticheat를 사용 안함" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "비밀번호 없으면 불가" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "도메인 서버의 이름은 서버리스트에 표시 됩니다." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "점프를 두번 탭하여 비행" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "점프키를 두번 누르면 비행 모드를 활성화시킵니다." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "아이템 드랍 키" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Mapgen 디버그 정보를 덤프 합니다." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "던전 잡음" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable creative mode for all players" +msgstr "새로 만든 맵에서 creative모드를 활성화시킵니다." + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "조이스틱 활성화" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "모드 채널 지원 활성화." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "모드 보안 적용" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "플레이어는 데미지를 받고 죽을 수 있습니다." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "랜덤 사용자 입력 (테스트에 사용)를 사용 합니다." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"오래된 클라이언트 연결을 허락하지 않는것을 사용.\n" +"이전 클라이언트는 서버에서 당신이 기대하는 새로운 특징들을 지원하지 않는다" +"면 \n" +"새로운 서버로 연결할 때 충돌하지 않을 것입니다." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"원격 미디어 서버 사용 가능(만약 서버에서 제공한다면).\n" +"원격 서버들은 서버에 연결할 때 매우 빠르게 미디어를\n" +"다운로드 할 수 있도록 제공합니다.(예: 텍스처)" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"화면 흔들림 멀티플라이어\n" +"예 : 0은 화면 흔들림 없음; 1.0은 노멀; 2.0은 더블." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"IPv6 서버를 실행 활성화/비활성화.\n" +"IPv6 서버는 IPv6 클라이언트 시스템 구성에 따라 제한 될 수 있습니다.\n" +"만약 Bind_address가 설정 된 경우 무시 됩니다." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "인벤토리 아이템의 애니메이션 적용." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "미니맵 적용." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "계곡 측면" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "엔진 프로 파일링 데이터 출력 간격" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "FPS when unfocused or paused" +msgstr "게임이 일시정지될때의 최대 FPS." + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "낙하 흔들림" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "대체 글꼴 경로" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "빠른 키" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "고속 모드 가속" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "고속 모드 속도" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "빠른 이동" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"빠른 이동 ( \"특수\"키 사용).\n" +"이를 위해서는 서버에 대한 \"빠른\"권한이 필요합니다." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "시야" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "각도에 대한 시야." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"멀티 플레이어 탭에 표시되는 즐겨 찾는 서버가 포함 된 \n" +"client / serverlist /의 파일입니다." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "강 깊이" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "필름 형 톤 맵핑" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "매끄럽게 표현하기:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "수정된 맵 시드" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Floatland의 밀집도" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Floatland의 Y 최대값" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Floatland의 Y 최소값" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Floatland 노이즈" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Floatland의 테이퍼 지수" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Floatland의 테이퍼링 거리" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Floatland의 물 높이" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "비행 키" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "비행" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "안개" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "안개 스위치" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "글꼴 크기" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "글꼴 그림자" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "글꼴 그림자 투명도" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "글꼴 크기" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Screenshots의 형식입니다." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "게임 내에서 채팅 콘솔 배경 색상 (빨강, 초록, 파랑)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "게임 내에서 채팅 콘솔 배경 알파 (불투명 함, 0와 255 사이)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "게임 내에서 채팅 콘솔 배경 색상 (빨강, 초록, 파랑)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "게임 내에서 채팅 콘솔 배경 알파 (불투명 함, 0와 255 사이)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "앞으로 가는 키" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "전체 화면" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "전체 화면 모드." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "GUI 크기 조정" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "GUI 크기 조정 필터" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "GUI 크기 조정 필터 txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "게임" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "글로벌 콜백" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "그래픽" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "그래픽" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "그래픽" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "중력" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "지면 수준" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "지면 노이즈" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP 모드" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "GUI 크기 조정" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "HUD 토글 키" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "용암 잡음" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "초기 창 크기의 높이 구성 요소입니다." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "높이 노이즈" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "언덕1 잡음" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "언덕2 잡음" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "언덕3 잡음" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "언덕4 잡음" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "서버의 홈페이지는 서버 리스트에 나타납니다." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "핫바 슬롯 키 12" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "제작할 강의 깊이." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "움직임에 대한 액체 저항을 높이려면 이 값을 줄입니다." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "제작할 강의 너비." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6 서버" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"활성화시, \"sneak\"키 대신 \"특수\"키가 내려가는데 \n" +"사용됩니다." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "적용할 경우, 멀티플레이어에서 치트 방지를 해제합니다." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "적용할 경우, 새로운 플레이어는 빈 암호로 가입 할 수 없습니다." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"활성화시,\n" +"당신이 서 있는 자리에도 블록을 놓을 수 있습니다." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "적용할 경우, 플레이어는 지정된 위치에 항상 스폰 될 것입니다." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "월드 에러 무시" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "게임 내에서 채팅 콘솔 배경 알파 (불투명 함, 0와 255 사이)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "게임 내에서 채팅 콘솔 배경 색상 (빨,초,파)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "게임 내에서 채팅 콘솔 배경 알파 (불투명 함, 0와 255 사이)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "볼륨 증가 키" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "도구 설명 표시 지연, 1000분의 1초." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "인벤토리 아이템 애니메이션" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "인벤토리 키" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "마우스 반전" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "기울임꼴 경로" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "고정 폭 기울임 글꼴 경로" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "아이템의 TTL(Time To Live)" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "점프 키" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "점프 속도" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"보여지는 범위 감소에 대한 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"볼륨 감소 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"점프키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"현재 선택된 아이템 드롭에 대한 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"보여지는 범위 증가에 대한 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"보여지는 범위 증가에 대한 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"점프키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"고속 모드에서 빠르게 이동하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"플레이어가 \n" +"뒤쪽으로 움직이는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"플레이어가 앞으로 움직이는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"플레이어가 왼쪽으로 움직이는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"플레이어가 오른쪽으로 움직이는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"점프키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"명령어를 입력하기 위해 채팅창을 여는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"로컬 명령어를 입력하기 위해 채팅창을 여는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"채팅창을 여는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"인벤토리를 여는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"점프키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"인벤토리를 여는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"인벤토리를 여는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"13번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"14번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"15번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"16번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"17번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"18번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"19번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"20번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"21번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"22번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"23번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"24번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"25번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"26번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"27번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"28번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"29번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"30번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"31번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"32번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"8번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"5번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"1번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"4번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"다음 아이템 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"9번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"이전 아이템 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"2번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"7번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"6번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"10번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"3번째 hotbar 슬롯을 선택하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"살금살금걷기 키입니다.\n" +"만약 aux1_descends를 사용할 수 없는 경우에 물에서 내려가거나 올라올 수 있습니" +"다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"1인칭에서 3인칭간 카메라 전환키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"스크린샷키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"자동전진 토글에 대한 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"시네마틱 모드 스위치 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"미니 맵 표시 설정/해제 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"고속 모드 스위치 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"비행 모드 스위치 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"자유시점 모드 스위치 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"피치 이동 모드 토글에 대한 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"카메라 업데이트 스위치 키입니다. 개발을 위해서만 사용됩니다. \n" +"참조 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"채팅 디스플레이 토글 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"디버그 정보 표시 스위치 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"안개 디스플레이 토글 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"HUD 표시 스위치 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"채팅 콘솔 디스플레이 토글 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"제한없이 보여지는 범위에 대한 스위치 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"가능한 경우 시야 확대를 사용하는 키입니다.\n" +"Http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3 참조" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "언어" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "큰 동굴 깊이" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "큰 채팅 콘솔 키" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "나뭇잎 스타일" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"나뭇잎 스타일:\n" +"- 아름다운: 모든 면 표시\n" +"- 간단: 외부 면만 표시, special_tiles를 정의 하는 경우만 사용\n" +"- 불투명: 투명도 사용 안 함" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"True로 설정하면 흔들리는 나뭇잎 효과가 적용됩니다.\n" +"쉐이더를 활성화 해야 합니다." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "부드러운 조명 효과" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"(0, 0, 0)에서 모든 6 개 방향의 노드에서 맵 생성 제한.\n" +"mapgen 제한 내에 완전히 포함 된 맵 청크 만 생성됩니다.\n" +"값은 세계별로 저장됩니다." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "하강 속도" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "주 메뉴 스크립트" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "모든 액체를 불투명하게 만들기" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "맵 생성 제한" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "맵 저장 간격" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "맵 블록 생성 지연" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Mapblock 메시 생성기의 MapBlock 캐시 크기 (MB)" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Mapgen 플랫" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Mapgen 형태" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Mapgen 형태 상세 플래그" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "맵젠 V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "맵젠 V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "맵젠 V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "맵젠 디버그" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Mapgen 이름" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "최대 블록 전송 거리" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "최대 FPS" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "게임이 일시정지될때의 최대 FPS." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "최대 강제 로딩 블럭" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "최대 hotbar 폭" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "동시접속 할 수 있는 최대 인원 수." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "블록 당 최대 개체" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"현재 윈도우의 최대 부분은 hotbar를 사용할 것입니다.\n" +"hotbar의 오른쪽이나 왼쪽에 무언가를 나타낼 때 유용합니다." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "클라이언트 당 최대 동시 블록 전송" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"ms 에서 파일을 다운로드하면 (예 : 모드 다운로드) 최대 시간이 걸릴 수 있습니" +"다." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "최대 사용자" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "메쉬 캐시" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "메시지" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "연결하는 플레이어에게 보여지는 메시지." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "선택한 개체를 강조 표시 하는 데 사용 하는 방법입니다." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "미니맵" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "미니맵 키" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "미니맵 스캔 높이" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "최소 텍스처 크기" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "밉매핑(Mipmapping)" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "프로파일러" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "보안" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "고정 폭 글꼴 경로" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "고정 폭 글꼴 크기" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "고정 폭 글꼴 크기" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "산 0 수준" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "마우스 감도" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "마우스 감도 멀티플라이어." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"낙하 흔들림 멀티플라이어\n" +"예 : 0은 화면 흔들림 없음; 1.0은 노말; 2.0은 더블." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "음소거 키" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"플레이어의 이름.\n" +"서버가 열려 있을 때 이 이름으로 연결되는 클라이언트는 관리자입니다.\n" +"메인 메뉴에서 시작할 때 이것은 재정의됩니다." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "서버이름은 플레이어가 서버 리스트에 들어갈 때 나타납니다." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "네트워크" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "신규 사용자는 이 비밀번호를 입력해야 합니다." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "노클립" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "노클립 키" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Node 강조" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Node 강조" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "NodeTimer 간격" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "소리" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "불투명한 액체" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"shader의 경로입니다. 어떠한 경로도 지정되지 않았다면 기본 위치가 쓰입니다." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "텍스처 디렉터리 경로입니다. 모든 텍스처는 여기에서 먼저 검색 됩니다." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "물리학" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "피치 이동 키" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "비행 키" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place repetition interval" +msgstr "오른쪽 클릭 반복 간격" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"플레이어는 중력에 의해 영향을 받지 않고 날 수 있습니다.\n" +"서버에서는 \"fly\" 권한을 필요로 합니다." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "플레이어 전송 거리" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "PVP" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "이중 선형 필터링" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"(UDP)에 연결 하는 포트.\n" +"참고 주 메뉴의 포트 필트는 이 설정으로 재정의 됩니다." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "shell 명령어 실행 같은 안전 하지 않은 것으로부터 모드를 보호합니다." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"엔진의 프로파일링 데이터를 규칙적인 간격(초단위)으로 출력합니다.\n" +"0 = 사용안함. 개발자들에게 유용합니다." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "플레이어와 기본 특권을 부여할 수 있는 권한" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "프로파일러" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "프로파일러 토글 키" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"64node 구름 사각형영역의 반지름.\n" +"26보다 큰 수치들은 구름을 선명하게 만들고 모서리를 잘라낼 것입니다." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "강 주변에 계곡을 만들기 위해 지형을 올립니다." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "임의 입력" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "범위 선택 키" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "보고서 경로" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "원격 미디어" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "원격 포트" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "기본 주 메뉴를 커스텀 메뉴로 바꿉니다." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "보고서 경로" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "능선 노이즈" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "오른쪽 키" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "강 깊이" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "강 너비" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "강 깊이" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "강 소리" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "강 크기" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "강 계곡 폭" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "롤백 레코딩" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "원형 미니맵" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "디스크에 클라이언트에서 받은 맵을 저장 합니다." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "서버로부터 받은 맵을 저장" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "화면:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "화면 높이" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "화면 너비" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "스크린샷 폴더" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "화면 캡처 형식" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "스크린샷 품질" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"화면 캡처 품질입니다. JPEG 형식에만 사용.\n" +"1은 최악의 품질; 100은 최고의 품질을 의미합니다.\n" +"기본 품질을 사용하려면 0을 사용 합니다." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "스크린샷" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "해저 노이즈" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Http://www.sqlite.org/pragma.html#pragma_synchronous 참조" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "선택 박스 테두리 색 (빨, 초, 파)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "선택 박스 컬러" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "선택 박스 너비" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"9가지 공식에서 18 도형을 선택하세요.\n" +"1 = 4 D \"Roundy\" 만델브로트 집합.\n" +"2 = 4 D \"Roundy\" 줄리아 집합.\n" +"3 = 4 D \"Squarry\" 만델브로트 집합.\n" +"4 = 4 D \"Squarry\" 줄리아 집합.\n" +"5 = 4 D \"맨디 사촌\" 만델브로트 집합.\n" +"6 = 4 D \"맨디 사촌\" 줄리아 집합.\n" +"7 = 4 D \"변형\" 만델브로트 집합.\n" +"8 = 4 D \"변형\" 줄리아 집합.\n" +"9 = 3D \"만델브로트/만델바\" 만델브로트 집합.\n" +"10 = 3D \"만델브로트/만델바\" 줄리아 집합.\n" +"11 = 3D \"크리스마스 트리\" 만델브로트 집합.\n" +"12 = 3D \"크리스마스 트리\" 줄리아 집합.\n" +"13 = 3D \"만델벌브\" 만델브로트 집합.\n" +"14 = 3D \"만델벌브\" 줄리아 집합.\n" +"15 = 3D \"코사인 만델벌브\" 만델브로트 집합.\n" +"16 = 3D \"코사인 만델벌브\" 줄리아 집합.\n" +"17 = 4 D \"만델벌브\" 만델브로트 집합.\n" +"18 = 4 D \"만델벌브\" 줄리아 집합." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "서버 URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "서버 이름" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "서버 설명" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "서버 URL" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "서버 주소" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "서버 설명" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "서버 이름" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "서버 포트" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "서버 포트" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "서버리스트 URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "서버리스트 URL" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "서버리스트 파일" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"언어 설정. 시스템 언어를 사용하려면 비워두세요.\n" +"설정 적용 후 재시작이 필요합니다." + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"True로 설정하면 흔들리는 나뭇잎 효과가 적용됩니다.\n" +"쉐이더를 활성화 해야 합니다." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"True로 설정하면 흔들리는 나뭇잎 효과가 적용됩니다.\n" +"쉐이더를 활성화 해야 합니다." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"True로 설정하면 물결효과가 적용됩니다.\n" +"쉐이더를 활성화해야 합니다." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"True로 설정하면 흔들리는 식물 효과가 적용됩니다.\n" +"쉐이더를 활성화 해야 합니다." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "쉐이더 경로" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"쉐이더는 확장된 시각 효과를 제공하고 몇몇 비디오 카드의 성능이 증가할 수도 있" +"습니다.\n" +"이것은 OpenGL video backend에서만 \n" +"작동합니다." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "스크린샷 품질" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map texture size" +msgstr "최소 텍스처 크기" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "글꼴 그림자 오프셋, 만약 0 이면 그림자는 나타나지 않을 것입니다." + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "미니맵 모양. 활성화 = 원형, 비활성화 = 정사각형." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "디버그 정보 보기" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "개체 선택 상자 보기" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"언어 설정. 시스템 언어를 사용하려면 비워두세요.\n" +"설정 적용 후 재시작이 필요합니다." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "서버닫힘 메시지" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "높이 수정을 위해 기울기와 채우기를 함께 작용합니다." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "부드러운 조명효과" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"주위를 돌아볼 때 카메라를 부드럽게 해줍니다. 보기 또는 부드러운 마우스라고도 " +"부릅니다.\n" +"비디오를 녹화하기에 유용합니다." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"시네마틱 모드에서 카메라의 회전을 매끄럽게 만듭니다. 사용 하지 않으려면 0을 " +"입력하세요." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "카메라의 회전을 매끄럽게 만듭니다. 사용 하지 않으려면 0을 입력하세요." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "살금살금걷기 키" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "걷는 속도" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "글꼴 그림자 투명도" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "사운드" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "고정된 스폰포인트" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "계단식 산 높이" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "자동으로 생성되는 노멀맵의 강도." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "엄격한 프로토콜 검사" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "설정" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "지형 높이" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "지형 기초 분산" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "지형 높이" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "지형 높이 분산" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "지형 분산" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "텍스처 경로" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "흙이나 다른 것의 깊이." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"새로운 유저가 자동으로 얻는 권한입니다.\n" +"게임에서 /privs를 입력하여 서버와 모드 환경설정의 전체 권한 목록을 확인하세" +"요." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"드랍된 아이템이 살아 있는 시간입니다.\n" +"-1을 입력하여 비활성화합니다." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "시간 전송 간격" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "시간 속도" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"메모리에서 사용 하지 않는 맵 데이터를 제거하기 위해 클라이언트에 대한 시간 제" +"한입니다." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"플레이어가 무엇을 건설할 때 렉을 줄이기 위해 블럭 전송이 느려집니다.\n" +"이것은 node가 배치되거나 제거된 후 얼마나 오래 느려지는지를 결정합니다." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "카메라모드 스위치 키" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "도구 설명 지연" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "터치임계값 (픽셀)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "터치임계값 (픽셀)" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "삼중 선형 필터링" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256 \n" +"False = 128 \n" +"느린 컴퓨터에서 미니맵을 부드럽게 만들어줍니다." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "신뢰할 수 있는 모드" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "멀티 탭에 표시 된 서버 목록 URL입니다." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "좌표표집(Undersampling)" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "무제한 플레이어 전송 거리" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "사용하지 않은 서버 데이터 삭제" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "평평하게 보는 대신에 3D 구름 효과를 사용합니다." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "주 메뉴 배경에 구름 애니메이션을 사용 합니다." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "각도에 따라 텍스처를 볼 때 이방성 필터링을 사용 합니다." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "이중 선형 필터링은 질감 스케일링을 할 때 사용 합니다." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "삼중 선형 필터링은 질감 스케일링을 할 때 사용 합니다." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "수직동기화 V-Sync" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "계곡 깊이" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "계곡 채우기" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "계곡 측면" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "계곡 경사" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "숫자 의 마우스 설정." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "산의 높이/경사를 조절." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "세로 화면 동기화." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "비디오 드라이버" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "시야의 흔들리는 정도" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "node의 보여지는 거리(최소 = 20)." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "시야 감소 키" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "시야 증가 키" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "확대 키" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "시야 범위" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "볼륨" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"시차 교합 맵핑 적용.\n" +"쉐이더를 활성화 해야 합니다." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "걷는 속도" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "물의 높이" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "월드의 물 표면 높이." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "움직이는 Node" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "흔들리는 나뭇잎 효과" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "물 움직임" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "물결 높이" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "물결 속도" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "물결 길이" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "흔들리는 식물 효과" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "선택 박스 컬러" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Gui_scaling_filter이 true 이면 모든 GUI 이미지 소프트웨어에서 필터링 될 필요" +"가 있습니다. \n" +"하지만 일부 이미지는 바로 하드웨어에 생성됩니다. \n" +"(e.g. render-to-texture for nodes in inventory)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"이중선형/삼중선형/이방성 필터를 사용할 때 \n" +"저해상도 택스쳐는 희미하게 보일 수 있습니다.\n" +"so automatically upscale them with nearest-neighbor interpolation to " +"preserve crisp pixels. \n" +"This sets the minimum texture size for the upscaled textures; \n" +"값이 높을수록 선명하게 보입니다. \n" +"하지만 많은 메모리가 필요합니다. \n" +"Powers of 2 are recommended. \n" +"Setting this higher than 1 may not have a visible effect\n" +"unless bilinear/trilinear/anisotropic filtering is enabled." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "플레이어끼리 서로 공격하고 죽이는 것에 대한 허락 여부." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "폭은 초기 창 크기로 구성되어 있습니다." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" +"node 주위 “selectionbox'” or (if UTF-8 supported) “selectionbox’” 라인의 너비" +"입니다." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"월드 디렉토리 (월드의 모든 것은 여기에 저장됩니다).\n" +"주 메뉴에서 시작 하는 경우 필요 하지 않습니다." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "세계 시작 시간" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "평평한 땅의 Y값." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- 크리에이티브 모드: " + +#~ msgid "- Damage: " +#~ msgstr "- 데미지: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = 경사 정보가 존재 (빠름).\n" +#~ "1 = 릴리프 매핑 (더 느리고 정확함)." + +#~ msgid "Address / Port" +#~ msgstr "주소/포트" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "싱글 플레이어 월드를 리셋하겠습니까?" + +#~ msgid "Back" +#~ msgstr "뒤로" + +#~ msgid "Basic" +#~ msgstr "기본" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "전체 화면 모드에서 (일명 색 농도) 픽셀 당 비트." + +#~ msgid "Bump Mapping" +#~ msgstr "범프 매핑" + +#~ msgid "Bumpmapping" +#~ msgstr "범프맵핑" + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "메인 메뉴 UI 변경 :\n" +#~ "-전체 : 여러 싱글 플레이어 월드, 게임 선택, 텍스처 팩 선택기 등.\n" +#~ "-단순함 : 단일 플레이어 세계, 게임 또는 텍스처 팩 선택기가 없습니다. \n" +#~ "작은 화면에 필요할 수 있습니다." + +#~ msgid "Config mods" +#~ msgstr "모드 설정" + +#~ msgid "Configure" +#~ msgstr "환경설정" + +#~ msgid "Connect" +#~ msgstr "연결" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "액체의 하강 속도 제어." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "터널 너비를 조절, 작은 수치는 넓은 터널을 만듭니다." + +#~ msgid "Credits" +#~ msgstr "만든이" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "십자선 색 (빨, 초, 파)." + +#~ msgid "Damage enabled" +#~ msgstr "데미지 활성화" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "cURL에 대한 기본 제한 시간 (밀리 초 단위).\n" +#~ "cURL로 컴파일 된 경우에만 효과가 있습니다." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "텍스처의 샘플링 단계를 정의합니다.\n" +#~ "일반 맵에 부드럽게 높은 값을 나타냅니다." + +#~ msgid "Del. Favorite" +#~ msgstr "즐겨찾기 삭제" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "minetest.net에서 Minetest Game 같은 서브 게임을 다운로드하세요" + +#~ msgid "Download one from minetest.net" +#~ msgstr "minetest.net에서 다운로드 하세요" + +#, fuzzy +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "$1 를(을) 다운로드중입니다. 기다려주세요..." + +#~ msgid "Enable VBO" +#~ msgstr "VBO 적용" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "텍스처에 bumpmapping을 할 수 있습니다. \n" +#~ "Normalmaps는 텍스쳐 팩에서 받거나 자동 생성될 필요가 있습니다.\n" +#~ "쉐이더를 활성화 해야 합니다." + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "비행 노멀맵 생성 적용 (엠보스 효과).\n" +#~ "Bumpmapping를 활성화 해야 합니다." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "시차 교합 맵핑 적용.\n" +#~ "쉐이더를 활성화 해야 합니다." + +#~ msgid "Enter " +#~ msgstr "들어가기 " + +#~ msgid "FPS in pause menu" +#~ msgstr "일시정지 메뉴에서 FPS" + +#~ msgid "Fallback font shadow" +#~ msgstr "대체 글꼴 그림자" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "대체 글꼴 그림자 투명도" + +#~ msgid "Fallback font size" +#~ msgstr "대체 글꼴 크기" + +#~ msgid "Filtering" +#~ msgstr "필터링" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "글꼴 그림자 투명도 (불투명 함, 0과 255 사이)." + +#~ msgid "FreeType fonts" +#~ msgstr "Freetype 글꼴" + +#~ msgid "Full screen BPP" +#~ msgstr "전체 화면 BPP" + +#~ msgid "Game" +#~ msgstr "게임" + +#~ msgid "Gamma" +#~ msgstr "감마" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Normal maps 생성" + +#~ msgid "Generate normalmaps" +#~ msgstr "Normalmaps 생성" + +#~ msgid "In-Game" +#~ msgstr "인게임" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "모드 설치: 파일: \"$1\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Keybindings. (이 메뉴를 고정하려면 minetest.cof에서 stuff를 제거해야합니" +#~ "다.)" + +#, fuzzy +#~ msgid "Lava depth" +#~ msgstr "큰 동굴 깊이" + +#~ msgid "Main" +#~ msgstr "메인" + +#~ msgid "Main menu style" +#~ msgstr "주 메뉴 스크립트" + +#~ msgid "Menus" +#~ msgstr "메뉴" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "레이더 모드의 미니맵, 2배 확대" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "레이더 모드의 미니맵, 4배 확대" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "표면 모드의 미니맵, 2배 확대" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "표면 모드의 미니맵, 4배 확대" + +#~ msgid "Name / Password" +#~ msgstr "이름/비밀번호" + +#~ msgid "Name/Password" +#~ msgstr "이름/비밀번호" + +#~ msgid "No" +#~ msgstr "아니오" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Normalmaps 샘플링" + +#~ msgid "Normalmaps strength" +#~ msgstr "Normalmaps 강도" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "시차 교합 반복의 수." + +#~ msgid "Ok" +#~ msgstr "확인" + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "일반적인 규모/2의 시차 교합 효과의 전반적인 바이어스." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "시차 교합 효과의 전체 규모." + +#~ msgid "Parallax Occlusion" +#~ msgstr "시차 교합" + +#~ msgid "Parallax occlusion" +#~ msgstr "시차 교합" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "시차 교합 바이어스" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "시차 교합 반복" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "시차 교합 모드" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "시차 교합 규모" + +#, fuzzy +#~ msgid "Parallax occlusion strength" +#~ msgstr "시차 교합 강도" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "TrueTypeFont 또는 비트맵의 경로입니다." + +#~ msgid "Path to save screenshots at." +#~ msgstr "스크린샷 저장 경로입니다." + +#~ msgid "Player name" +#~ msgstr "플레이어 이름" + +#~ msgid "Profiling" +#~ msgstr "프로 파일링" + +#~ msgid "PvP enabled" +#~ msgstr "PvP 가능" + +#~ msgid "Reset singleplayer world" +#~ msgstr "싱글 플레이어 월드 초기화" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "선택한 모드 파일:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "서버 / 싱글 플레이어" + +#~ msgid "Shadow limit" +#~ msgstr "그림자 제한" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "글꼴 그림자 오프셋, 만약 0 이면 그림자는 나타나지 않을 것입니다." + +#~ msgid "Special" +#~ msgstr "특별함" + +#~ msgid "Special key" +#~ msgstr "특수 키" + +#~ msgid "Start Singleplayer" +#~ msgstr "싱글 플레이어 시작" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "자동으로 생성되는 노멀맵의 강도." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "이 글꼴은 특정 언어에 사용 됩니다." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "쉐이더를 사용하려면 OpenGL 드라이버를 사용할 필요가 있습니다." + +#~ msgid "Toggle Cinematic" +#~ msgstr "시네마틱 스위치" + +#~ msgid "View" +#~ msgstr "보기" + +#~ msgid "Waving Water" +#~ msgstr "물결 효과" + +#~ msgid "Waving water" +#~ msgstr "물결 효과" + +#~ msgid "Yes" +#~ msgstr "예" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "당신은 처음 \"%s\"라는 이름으로 이 서버에 참여하려고 합니다. \n" +#~ "계속한다면, 자격이 갖춰진 새 계정이 이 서버에 생성됩니다. \n" +#~ "비밀번호를 다시 입력하고 '등록 하고 참여'를 누르거나 '취소'를 눌러 중단하" +#~ "십시오." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "사망했습니다" + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/ky/minetest.po b/po/ky/minetest.po new file mode 100644 index 0000000..5de3ad5 --- /dev/null +++ b/po/ky/minetest.po @@ -0,0 +1,7167 @@ +msgid "" +msgstr "" +"Project-Id-Version: Kyrgyz (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2019-11-10 15:04+0000\n" +"Last-Translator: Krock <mk939@ymail.com>\n" +"Language-Team: Kyrgyz <https://hosted.weblate.org/projects/minetest/minetest/" +"ky/>\n" +"Language: ky\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.10-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Empty command." +msgstr "Команда" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Менюга чыгуу" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Invalid command: " +msgstr "Команда" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "Бир кишилик" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "Бир кишилик" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Кайтадан жаралуу" + +#: builtin/client/death_formspec.lua src/client/game.cpp +#, fuzzy +msgid "You died" +msgstr "Сиз өлдүңүз." + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "Команда" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "Команда" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "Main menu" +msgstr "Башкы меню" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "Reconnect" +msgstr "Туташуу" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Дүйнөнү тандаңыз:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Жокко чыгаруу" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Dependencies:" +msgstr "көз карандылыктары:" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "Disable all" +msgstr "Баарын өчүрүү" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "Disable modpack" +msgstr "Баарын өчүрүү" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "Enable all" +msgstr "Баарын күйгүзүү" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "Enable modpack" +msgstr "Баарын күйгүзүү" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No hard dependencies" +msgstr "көз карандылыктары:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Сактоо" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "World:" +msgstr "Дүйнөнү тандаңыз:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "күйгүзүлгөн" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "Жүктөлүүдө..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Back to Main Menu" +msgstr "Башкы меню" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "Оюн" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Downloading..." +msgstr "Жүктөлүүдө..." + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Failed to download $1" +msgstr "Дүйнөнү инициалдаштыруу катасы" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Games" +msgstr "Оюн" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Жаратуу" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Rivers" +msgstr "Оң Windows" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Дүйнө аты" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Өчүрүү" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_world.lua +#, fuzzy +msgid "Delete World \"$1\"?" +msgstr "Дүйнөнү өчүрүү" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Сырсөздү аныктоо" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "Жаңы сырсөз" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Сырсөздөр дал келген жок!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Кабыл алуу" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Улантуу" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Улантуу" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Disabled" +msgstr "Баарын өчүрүү" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Enabled" +msgstr "күйгүзүлгөн" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Select directory" +msgstr "Дүйнөнү тандаңыз:" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Select file" +msgstr "Дүйнөнү тандаңыз:" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "$1 (Enabled)" +msgstr "күйгүзүлгөн" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "$1 mods" +msgstr "Ырастоо" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Failed to install $1 to $2" +msgstr "Дүйнөнү инициалдаштыруу катасы" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a $1 as a texture pack" +msgstr "Дүйнөнү инициалдаштыруу катасы" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a game as a $1" +msgstr "Дүйнөнү инициалдаштыруу катасы" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a mod as a $1" +msgstr "Дүйнөнү инициалдаштыруу катасы" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a modpack as a $1" +msgstr "Дүйнөнү инициалдаштыруу катасы" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Жүктөлүүдө..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Дүйнөнү тандаңыз:" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Content" +msgstr "Улантуу" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Disable Texture Pack" +msgstr "Баарын өчүрүү" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Жаратуу режими" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Убалды күйгүзүү" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Host Game" +msgstr "Оюн" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Жаңы" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Play Game" +msgstr "Оюнду баштоо/туташуу" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "Дүйнөнү тандаңыз:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Дүйнөнү тандаңыз:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Start Game" +msgstr "Оюн" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "Дареги/порту" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Тазалоо" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Creative mode" +msgstr "Жаратуу режими" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "Убалды күйгүзүү" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "Тандалмалар:" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Join Game" +msgstr "Оюн" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Тандалмалар:" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "3D Clouds" +msgstr "3D-булуттар" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "All Settings" +msgstr "Ырастоолор" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Bilinear Filter" +msgstr "Экисызык чыпкалоосу" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +#, fuzzy +msgid "Change Keys" +msgstr "Баскычтарды өзгөртүү" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Connected Glass" +msgstr "Туташуу" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Fancy Leaves" +msgstr "Күңүрт суу" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Mipmap" +msgstr "Mip-текстуралоо" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "No Filter" +msgstr "Анизатропия чыпкалоосу" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "No Mipmap" +msgstr "Mip-текстуралоо" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Node Highlighting" +msgstr "Тегиз жарык" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Node Outlining" +msgstr "Тегиз жарык" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Opaque Leaves" +msgstr "Күңүрт суу" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Opaque Water" +msgstr "Күңүрт суу" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Particles" +msgstr "Баарын күйгүзүү" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Screen:" +msgstr "Тез сүрөт" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Ырастоолор" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Көлөкөлөгүчтөр" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Simple Leaves" +msgstr "Күңүрт суу" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Smooth Lighting" +msgstr "Тегиз жарык" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Tone Mapping" +msgstr "Mip-текстуралоо" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Trilinear Filter" +msgstr "Үчсызык чыпкалоосу" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Leaves" +msgstr "Кооз бактар" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Liquids" +msgstr "Кооз бактар" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Plants" +msgstr "Кооз бактар" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Туташтыруу катасы (убактыңыз өтүп кеттиби?)" + +#: src/client/client.cpp src/client/game.cpp +#, fuzzy +msgid "Connection timed out." +msgstr "Туташтыруу катасы (убактыңыз өтүп кеттиби?)" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +#, fuzzy +msgid "Loading textures..." +msgstr "Жүктөлүүдө..." + +#: src/client/client.cpp +#, fuzzy +msgid "Rebuilding shaders..." +msgstr "Дареги чечилүүдө..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Туташтыруу катасы (убактыңыз өтүп кеттиби?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "Оюнду табуу же жүктөө мүмкүн эмес \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Башкы меню" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Дүйнө тандалган жок жана дареги киргизилген жок. Кылууга эч нерсе жок." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Толугураак маалымат үчүн, debug.txt'ти текшериңиз." + +#: src/client/game.cpp +#, fuzzy +msgid "- Address: " +msgstr "Дареги/порту" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "- Public: " +msgstr "Жалпылык" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward disabled" +msgstr "Алга" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward enabled" +msgstr "Алга" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Camera update enabled" +msgstr "күйгүзүлгөн" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Сырсөздү өзгөртүү" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode disabled" +msgstr "Жаратуу режими" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode enabled" +msgstr "Жаратуу режими" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Серверге туташтырылууда..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Улантуу" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Жарыяланбас башкаруу:\n" +"- WASD: басуу\n" +"- Боштугу: секирүү/өйдө чыгуу\n" +"- Shift: уурданып басуу/ылдый түшүү\n" +"- Q: буюмду таштоо\n" +"- I: мүлк-шайман\n" +"- Чычканы: бурулуу/кароо\n" +"- Сол чычкан баскычы: казуу/согуу\n" +"- Оң чычкан баскычы: коюу/колдонуу\n" +"- Чычкан дөңгөлөгү: буюмду тандоо\n" +"- T: маек\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Клиент жаратылууда..." + +#: src/client/game.cpp +#, fuzzy +msgid "Creating server..." +msgstr "Сервер жаратылууда...." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Клиент жаратылууда..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Менюга чыгуу" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Оюндан чыгуу" + +#: src/client/game.cpp +#, fuzzy +msgid "Fast mode disabled" +msgstr "Баарын өчүрүү" + +#: src/client/game.cpp +#, fuzzy +msgid "Fast mode enabled" +msgstr "күйгүзүлгөн" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode disabled" +msgstr "Баарын өчүрүү" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode enabled" +msgstr "күйгүзүлгөн" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog disabled" +msgstr "Баарын өчүрүү" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog enabled" +msgstr "күйгүзүлгөн" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Game paused" +msgstr "Оюн" + +#: src/client/game.cpp +#, fuzzy +msgid "Hosting server" +msgstr "Сервер жаратылууда...." + +#: src/client/game.cpp +#, fuzzy +msgid "Item definitions..." +msgstr "Буюм текстуралары..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "Бир кишилик" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Noclip mode enabled" +msgstr "күйгүзүлгөн" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Дареги чечилүүдө..." + +#: src/client/game.cpp +#, fuzzy +msgid "Shutting down..." +msgstr "Оюн өчүрүлүүдө..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Бир кишилик" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Үн көлөмү" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound muted" +msgstr "Үн көлөмү" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound unmuted" +msgstr "Үн көлөмү" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +#, fuzzy +msgid "Chat hidden" +msgstr "Баскычтарды өзгөртүү" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Тиркемелер" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Backspace" +msgstr "Артка" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Ctrl" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Ылдый" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Аягы" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Аткаруу" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Жардам" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Accept" +msgstr "Кабыл алуу" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Escape" +msgstr "Esc" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Mode Change" +msgstr "Режимди өзгөртүү" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Солго" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Сол баскыч" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Сол Ctrl" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Сол меню" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Сол Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Сол Windows" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Меню" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Ортоңку баскыч" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Кош. клав. *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Кош. клав. +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Кош. клав. -" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad ." +msgstr "Кош. клав. *" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Кош. клав. /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Кош. клав. 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Кош. клав. 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Кош. клав. 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Кош. клав. 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Кош. клав. 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Кош. клав. 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Кош. клав. 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Кош. клав. 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Кош. клав. 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Кош. клав. 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Пауза" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Ойноо" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Басма" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Оңго" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Оң баскыч" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Оң Ctrl" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Оң меню" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Оң Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Оң Windows" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Тандоо" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Уйку" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Тез сүрөт" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Боштук" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Өйдө" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Масштаб" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Дүйнөнү инициалдаштыруу катасы" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Улантуу" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Autoforward" +msgstr "Алга" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Артка" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Change camera" +msgstr "Баскычтарды өзгөртүү" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Маек" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Команда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Консоль" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Ыргытуу" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Алга" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Inc. volume" +msgstr "Үн көлөмү" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Мүлк-шайман" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Секирүү" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Local command" +msgstr "Команда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Next item" +msgstr "Кийинки" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshot" +msgstr "Тез сүрөт" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Уурданып басуу" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle HUD" +msgstr "Учууга которуу" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle chat log" +msgstr "Тез басууга которуу" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Тез басууга которуу" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Учууга которуу" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle fog" +msgstr "Учууга которуу" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle minimap" +msgstr "Тез басууга которуу" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle pitchmove" +msgstr "Тез басууга которуу" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "баскычты басыңыз" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Өзгөртүү" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Жаңы сырсөз" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Эски сырсөз" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Сырсөздөр дал келген жок!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Чыгуу" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy +msgid "Muted" +msgstr "баскычты басыңыз" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Үн көлөмү: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "ky" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "3D clouds" +msgstr "3D-булуттар" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Дүйнө аты" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Кошумча" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Anisotropic filtering" +msgstr "Анизатропия чыпкалоосу" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatic forward key" +msgstr "Алга" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "Секирүү" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Backward key" +msgstr "Артка" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bilinear filtering" +msgstr "Экисызык чыпкалоосу" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bind address" +msgstr "Дареги чечилүүдө..." + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Build inside player" +msgstr "Көп кишилик" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Баскычтарды өзгөртүү" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Команда" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat key" +msgstr "Баскычтарды өзгөртүү" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat log level" +msgstr "Баскычтарды өзгөртүү" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat toggle key" +msgstr "Баскычтарды өзгөртүү" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cinematic mode" +msgstr "Жаратуу режими" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cinematic mode key" +msgstr "Жаратуу режими" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Clouds" +msgstr "3D-булуттар" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Clouds in menu" +msgstr "Башкы меню" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Command key" +msgstr "Команда" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Connect glass" +msgstr "Туташуу" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Connect to external media server" +msgstr "Серверге туташтырылууда..." + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Console alpha" +msgstr "Консоль" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Console color" +msgstr "Консоль" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Console height" +msgstr "Консоль" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ContentDB URL" +msgstr "Улантуу" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Controls" +msgstr "Ctrl" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Creative" +msgstr "Жаратуу" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Damage" +msgstr "Убалды күйгүзүү" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default password" +msgstr "Жаңы сырсөз" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "Оң меню" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Digging particles" +msgstr "Баарын күйгүзүү" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Disable anticheat" +msgstr "Бөлүкчөлөрдү күйгүзүү" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enables minimap." +msgstr "Убалды күйгүзүү" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Forward key" +msgstr "Алга" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Оюн" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Height noise" +msgstr "Оң Windows" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Inc. volume key" +msgstr "Консоль" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Inventory key" +msgstr "Мүлк-шайман" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Jump key" +msgstr "Секирүү" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Large chat console key" +msgstr "Консоль" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Left key" +msgstr "Сол меню" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Тегиз жарык" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Main menu script" +msgstr "Башкы меню" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mipmapping" +msgstr "Mip-текстуралоо" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mute key" +msgstr "баскычты басыңыз" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Тегиз жарык" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move key" +msgstr "Жаратуу режими" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Жаратуу режими" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Экисызык чыпкалоосу" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Regular font path" +msgstr "Тандоо" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Report path" +msgstr "Тандоо" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Right key" +msgstr "Оң меню" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River noise" +msgstr "Оң Windows" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Тез сүрөт" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshot format" +msgstr "Тез сүрөт" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshot quality" +msgstr "Тез сүрөт" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Тез сүрөт" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Жалпылык серверлердин тизмеси:" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Бир кишилик" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist URL" +msgstr "Жалпылык серверлердин тизмеси:" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "Жалпылык серверлердин тизмеси:" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist file" +msgstr "Жалпылык серверлердин тизмеси:" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shader path" +msgstr "Көлөкөлөгүчтөр" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "Тез сүрөт" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Smooth lighting" +msgstr "Тегиз жарык" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneak key" +msgstr "Уурданып басуу" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed" +msgstr "Уурданып басуу" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Ырастоолор" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Trilinear filtering" +msgstr "Үчсызык чыпкалоосу" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Volume" +msgstr "Үн көлөмү" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving leaves" +msgstr "Кооз бактар" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Кооз бактар" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Кооз бактар" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Кооз бактар" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Кооз бактар" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "World start time" +msgstr "Дүйнө аты" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#, fuzzy +#~ msgid "- Creative Mode: " +#~ msgstr "Жаратуу режими" + +#, fuzzy +#~ msgid "- Damage: " +#~ msgstr "Убалды күйгүзүү" + +#, fuzzy +#~ msgid "Address / Port" +#~ msgstr "Дареги/порту" + +#, fuzzy +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Бир кишилик" + +#~ msgid "Back" +#~ msgstr "Артка" + +#, fuzzy +#~ msgid "Bump Mapping" +#~ msgstr "Mip-текстуралоо" + +#, fuzzy +#~ msgid "Bumpmapping" +#~ msgstr "Mip-текстуралоо" + +#, fuzzy +#~ msgid "Config mods" +#~ msgstr "Ырастоо" + +#~ msgid "Configure" +#~ msgstr "Ырастоо" + +#~ msgid "Connect" +#~ msgstr "Туташуу" + +#~ msgid "Credits" +#~ msgstr "Алкыштар" + +#, fuzzy +#~ msgid "Damage enabled" +#~ msgstr "күйгүзүлгөн" + +#, fuzzy +#~ msgid "Enable VBO" +#~ msgstr "Баарын күйгүзүү" + +#, fuzzy +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Убалды күйгүзүү" + +#, fuzzy +#~ msgid "Filtering" +#~ msgstr "Анизатропия чыпкалоосу" + +#~ msgid "Game" +#~ msgstr "Оюн" + +#, fuzzy +#~ msgid "In-Game" +#~ msgstr "Оюн" + +#, fuzzy +#~ msgid "Main" +#~ msgstr "Башкы меню" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "Башкы меню" + +#, fuzzy +#~ msgid "Menus" +#~ msgstr "Меню" + +#, fuzzy +#~ msgid "Name / Password" +#~ msgstr "Аты/сырсөзү" + +#~ msgid "Name/Password" +#~ msgstr "Аты/сырсөзү" + +#~ msgid "No" +#~ msgstr "Жок" + +#, fuzzy +#~ msgid "PvP enabled" +#~ msgstr "күйгүзүлгөн" + +#, fuzzy +#~ msgid "Reset singleplayer world" +#~ msgstr "Бир кишилик" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "Дүйнөнү тандаңыз:" + +#, fuzzy +#~ msgid "Special key" +#~ msgstr "Уурданып басуу" + +#, fuzzy +#~ msgid "Start Singleplayer" +#~ msgstr "Бир кишилик" + +#, fuzzy +#~ msgid "Toggle Cinematic" +#~ msgstr "Тез басууга которуу" + +#~ msgid "Yes" +#~ msgstr "Ооба" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Сиз өлдүңүз." + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/lt/minetest.po b/po/lt/minetest.po new file mode 100644 index 0000000..041611e --- /dev/null +++ b/po/lt/minetest.po @@ -0,0 +1,7199 @@ +msgid "" +msgstr "" +"Project-Id-Version: Lithuanian (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2021-04-10 15:49+0000\n" +"Last-Translator: Kornelijus Tvarijanavičius <kornelitvari@protonmail.com>\n" +"Language-Team: Lithuanian <https://hosted.weblate.org/projects/minetest/" +"minetest/lt/>\n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"(n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Weblate 4.6-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Empty command." +msgstr "Komanda" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Grįžti į meniu" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Invalid command: " +msgstr "Komanda" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "Žaisti vienam" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "Žaisti vienam" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Prisikelti" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Jūs numirėte" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "Komanda" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "Komanda" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Įvyko klaida Lua skripte:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Įvyko klaida:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Pagrindinis meniu" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Prisijungti iš naujo" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Serveris paprašė prisijungti iš naujo:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Pasirinkite pasaulį:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Neatitinka protokolo versija. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Serveris reikalauja naudoti versijos $1 protokolą. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Serveris palaiko protokolo versijas nuo $1 iki $2 " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Mes palaikome tik $1 protokolo versiją." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Mes palaikome protokolo versijas tarp $1 ir $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Atšaukti" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Priklauso nuo:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Išjungti visus papildinius" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Išjungti papildinį" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Įjungti visus" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Aktyvuoti papildinį" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Nepavyko įjungti papildinio „$1“, nes jis turi neleistinų rašmenų. Tik " +"rašmenys [a-z0-9_] yra leidžiami." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Papildinys:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Nepateiktas žaidimo aprašymas." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Nėra būtinų priklausomybių" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Nepateiktas papildinio aprašymas." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Įrašyti" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Pasaulis:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "įjungtas" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 atsiunčiama..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Jau įdiegta" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Atgal į Pagrindinį Meniu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Pagrindinis Žaidimas:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB nėra prieinama, kai Minetest sukompiliuojamas be cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Siunčiama..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Nepavyko parsiųsti $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Žaidimai" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Įdiegti" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "Įdiegti" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "Inicijuojami mazgai" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "" +"Papildinio diegimas: nepalaikomas failo tipas „$1“ arba sugadintas archyvas" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Papildiniai" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "No updates" +msgstr "Atnaujinti" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Texture packs" +msgstr "Tekstūrų paketai" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Uninstall" +msgstr "Įdiegti" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Atnaujinti" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Pasaulis, pavadintas „$1“ jau yra" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Sukurti" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekoracijos" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Dėmesio: Minimalus kūrimo bandymas yra skirtas vystytojams." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Įdiegti" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Žemėlapių generavimas" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mapgen-specific flags" +msgstr "Žemėlapių generavimas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "No game selected" +msgstr "Intervalo pasirinkimas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Rivers" +msgstr "Dešinieji langai" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Sėkla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Pasaulio pavadinimas" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "You have no games installed." +msgstr "Neturite įdiegę sub žaidimų." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Ar tikrai norite ištrinti „$1“?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Ištrinti" + +#: builtin/mainmenu/dlg_delete_content.lua +#, fuzzy +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "Papildtvrk: nepavyko ištrinti „$1“" + +#: builtin/mainmenu/dlg_delete_content.lua +#, fuzzy +msgid "pkgmgr: invalid path \"$1\"" +msgstr "Papildtvrk: netinkamas papildinio kelias „$1“" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Ištrinti pasaulį „$1“?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Patvirtinti slaptažodį" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "Naujas slaptažodis" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Slaptažodžiai nesutampa!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Priimti" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Pervadinti papildinių paką:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Nėra nustatymo aprašymo)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Atgal į Nustatymus" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Naršyti" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Tęsti" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Tęsti" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Disabled" +msgstr "Išjungti papildinį" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Keisti" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Enabled" +msgstr "įjungtas" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Prašome įvesti sveikąjį skaičių." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Prašome įvesti skaičių." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Ieškoti" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Pasirinkite aplanką" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Pasirinkite failą" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "defaults" +msgstr "keisti žaidimą" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "$1 (Enabled)" +msgstr "įjungtas" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "$1 mods" +msgstr "Konfigūruoti papildinius" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Nepavyko įdiegti $1 į $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Papildinio diegimas: nepavyksta rasti tikro pavadinimo skirto: $1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Papildinio diegimas: nepavyksta rasti tinkamo aplanko pavadinimo papildinio " +"paketui $1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to find a valid mod or modpack" +msgstr "" +"Papildinio diegimas: nepavyksta rasti tinkamo aplanko pavadinimo papildinio " +"paketui $1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a $1 as a texture pack" +msgstr "Nepavyko įdiegti $1 į $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a game as a $1" +msgstr "Nepavyko įdiegti $1 į $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a mod as a $1" +msgstr "Nepavyko įdiegti $1 į $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a modpack as a $1" +msgstr "Nepavyko įdiegti $1 į $2" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Įkeliama..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Pabandykite dar kart įjungti viešą serverių sąrašą ir patikrinkite savo " +"interneto ryšį." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktyvūs pagalbininkai" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Pagrindiniai kūrėjai" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Pasirinkite aplanką" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Ankstesni bendradarbiai" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Ankstesni pagrindiniai kūrėjai" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Content" +msgstr "Tęsti" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Pasirinkite tekstūros paketą" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Information:" +msgstr "Papildinio informacija:" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Installed Packages:" +msgstr "Įdiegti papildiniai:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "No package description available" +msgstr "Papildinio aprašymas nepateiktas" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Pervadinti" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Uninstall Package" +msgstr "Pašalinti pasirinktą papildinį" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Use Texture Pack" +msgstr "Tekstūrų paketai" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Paskelbti Serverį" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Susieti adresą" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Kūrybinė veiksena" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Leisti sužeidimus" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Host Game" +msgstr "Slėpti vidinius" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Host Server" +msgstr "Serveris" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Naujas" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Nesukurtas ar pasirinktas joks pasaulis!" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Play Game" +msgstr "Pradėti žaidimą" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Prievadas" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "Pasirinkite pasaulį:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Pasirinkite pasaulį:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Serverio prievadas" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Start Game" +msgstr "Slėpti vidinius" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "- Adresas: " + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Išvalyti" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Kūrybinė veiksena" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "Leisti sužeidimus" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "Mėgiami:" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Join Game" +msgstr "Slėpti vidinius" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "Paskelbti Serverį" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Pašalinti iš mėgiamų" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "Serverio prievadas" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D Debesys" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "All Settings" +msgstr "Nustatymai" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "„Bilinear“ filtras" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Nustatyti klavišus" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Connected Glass" +msgstr "Jungtis" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Fancy Leaves" +msgstr "Nepermatomi lapai" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Node Highlighting" +msgstr "Apšvietimo efektai" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Node Outlining" +msgstr "Apšvietimo efektai" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Joks" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Nepermatomi lapai" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Nepermatomas vanduo" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Particles" +msgstr "Įjungti visus" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Nustatymai" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Šešėliavimai" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Simple Leaves" +msgstr "Nepermatomi lapai" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Smooth Lighting" +msgstr "Apšvietimo efektai" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Leaves" +msgstr "Nepermatomi lapai" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Liquids" +msgstr "Nepermatomi lapai" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Ryšio klaida (baigėsi prijungimo laikas?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Baigėsi prijungimo laikas." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Atlikta!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inicijuojami mazgai" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Inicijuojami mazgai..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Įkeliamos tekstūros..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Perstatomi šešėliavimai..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Ryšio klaida (baigėsi prijungimo laikas?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "Nepavyko rasti ar įkelti žaidimo „" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Klaidingi žaidimo nustatymai." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Pagrindinis meniu" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" +"Nepasirinktas joks pasaulis ir nepateiktas joks adresas. Nėra ką daryti." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Žaidėjo vardas per ilgas." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Pateiktas pasaulio kelias neegzistuoja: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Patikrinkite debug.txt dėl papildomos informacijos." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Adresas: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Prievadas: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Viešas: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Serverio pavadinimas: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Įvyko klaida:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward disabled" +msgstr "Pirmyn" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward enabled" +msgstr "Pirmyn" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Camera update enabled" +msgstr "Žalojimas įjungtas" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Keisti slaptažodį" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode disabled" +msgstr "Kūrybinė veiksena" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode enabled" +msgstr "Kūrybinė veiksena" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "Žaisti tinkle(klientas)" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Jungiamasi prie serverio..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Tęsti" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Numatytas valdymas:\n" +"- %s: judėti į priekį\n" +"- %s: judėti atgal\n" +"- %s: judėti į kairę\n" +"- %s: judėti į dešinę\n" +"- %s: šokti/lipti\n" +"- %s: leistis/eiti žemyn\n" +"- %s: išmesti daiktą\n" +"- %s: inventorius\n" +"- Pelė: sukti/žiūrėti\n" +"- Pelės kairys: kasti/smugiuoti\n" +"- Pelės dešinys: padėti/naudoti\n" +"- Pelės ratukas: pasirinkti elementą\n" +"- %s: kalbėtis\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Kuriamas klientas..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Kuriamas serveris...." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Numatytas valdymas:\n" +"Nematomi meniu:\n" +"- vienas palietimas: mygtukas aktyvuoti\n" +"- dvigubas palietimas: padėti/naudoti\n" +"- slinkti pirštu: žvalgytis aplink\n" +"Meniu/Inventorius matomi:\n" +"- dvigubas palietimas (išorėje):\n" +" -->uždaryti\n" +"- liesti rietuvę, liesti angą:\n" +" --> judinti rietuvę\n" +"- liesti&tempti, liesti antru pirštu\n" +" --> padėti vieną elementą į angą\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Kuriamas klientas..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Grįžti į meniu" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Išeiti iš žaidimo" + +#: src/client/game.cpp +#, fuzzy +msgid "Fast mode disabled" +msgstr "Išjungti papildinį" + +#: src/client/game.cpp +#, fuzzy +msgid "Fast mode enabled" +msgstr "Žalojimas įjungtas" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode disabled" +msgstr "Išjungti papildinį" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode enabled" +msgstr "Žalojimas įjungtas" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog disabled" +msgstr "Išjungti papildinį" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog enabled" +msgstr "įjungtas" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Game paused" +msgstr "Žaidimo pavadinimas" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Kuriamas serveris" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Elemento apibrėžimai..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Medija..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "Žaisti vienam" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Noclip mode enabled" +msgstr "Žalojimas įjungtas" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Mazgo apibrėžimai..." + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Ieškoma adreso..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Išjungiama..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Žaisti vienam" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Garso lygis" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound muted" +msgstr "Garso lygis" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound unmuted" +msgstr "Garso lygis" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "gerai" + +#: src/client/gameui.cpp +#, fuzzy +msgid "Chat hidden" +msgstr "Nustatyti klavišus" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Programos" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Backspace" +msgstr "Atgal" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Valdymas" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Žemyn" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Baigti" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Erase EOF" +msgstr "Ištrinti OEF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Vykdyti" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Pagalba" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Pradžia" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Accept" +msgstr "Priimti" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Convert" +msgstr "Konvertuoti" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Escape" +msgstr "Atšaukti" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Mode Change" +msgstr "Būsenos keitimas" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Įterpti" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Kairėn" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Kairysis mygtukas" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Kairysis Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Kairysis meniu" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Kairysis Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Kairieji langai" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Meniu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Vidurinis mygtukas" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "SkaitKlav *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "SkaitKlav +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "SkaitKlav -" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad ." +msgstr "SkaitKlav *" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "SkaitKlav /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "SkaitKlav 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "SkaitKlav 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "SkaitKlav 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "SkaitKlav 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "SkaitKlav 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "SkaitKlav 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "SkaitKlav 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "SkaitKlav 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "SkaitKlav 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "SkaitKlav 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM valymas" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Žaisti" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Spausdinti" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Grįžti" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Dešinėn" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Dešinysis mygtukas" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Dešinysis Control" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Dešinysis meniu" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Dešinysis Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Dešinieji langai" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Pasirinkti" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift (Lyg2)" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Užmigdyti" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Užlaikymas" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Tarpas" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabuliacija" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Aukštyn" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X mygtukas 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X mygtukas 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Pritraukti" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Nepavyko parsiųsti $1" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Vykdyti" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "„Naudoti“ = kopti žemyn" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Autoforward" +msgstr "Pirmyn" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Atgal" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Change camera" +msgstr "Nustatyti klavišus" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Susirašinėti" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Komanda" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Pultas" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Du kart paliesti „šokti“, kad įjungti skrydį" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Mesti" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Pirmyn" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Inc. volume" +msgstr "Garso lygis" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventorius" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Pašokti" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Klavišas jau naudojamas" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Local command" +msgstr "Komanda" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Next item" +msgstr "Kitas" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Intervalo pasirinkimas" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Sėlinti" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle HUD" +msgstr "Įjungti skrydį" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle chat log" +msgstr "Įjungti greitą" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Įjungti greitą" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Įjungti skrydį" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle fog" +msgstr "Įjungti skrydį" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle minimap" +msgstr "Įjungti noclip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Įjungti noclip" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle pitchmove" +msgstr "Įjungti greitą" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "paspauskite klavišą" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Pakeisti" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Naujas slaptažodis" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Senas slaptažodis" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Slaptažodžiai nesutampa!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Išeiti" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy +msgid "Muted" +msgstr "paspauskite klavišą" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Garso lygis: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "lt" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "3D clouds" +msgstr "Trimačiai debesys" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Pasaulio pavadinimas" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Paskelbti tai serverių sąrašui" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatic forward key" +msgstr "Pirmyn" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "Pašokti" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Backward key" +msgstr "Atgal" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bind address" +msgstr "Ieškoma adreso..." + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Nustatyti klavišus" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Komanda" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat key" +msgstr "Nustatyti klavišus" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat log level" +msgstr "Nustatyti klavišus" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat toggle key" +msgstr "Nustatyti klavišus" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cinematic mode" +msgstr "Kūrybinė veiksena" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cinematic mode key" +msgstr "Kūrybinė veiksena" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Žaisti tinkle(klientas)" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client modding" +msgstr "Žaisti tinkle(klientas)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client side modding restrictions" +msgstr "Žaisti tinkle(klientas)" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Žaisti tinkle(klientas)" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Clouds" +msgstr "Trimačiai debesys" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Clouds in menu" +msgstr "Pagrindinis meniu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Command key" +msgstr "Komanda" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Connect glass" +msgstr "Jungtis" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Prisijungti prie išorinio medijos serverio" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Console height" +msgstr "Nustatyti klavišus" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ContentDB URL" +msgstr "Tęsti" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Controls" +msgstr "Kairysis Control" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Creative" +msgstr "Sukurti" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Damage" +msgstr "Leisti sužeidimus" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default game" +msgstr "keisti žaidimą" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default password" +msgstr "Naujas slaptažodis" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default stack size" +msgstr "keisti žaidimą" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Dekoracijos" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "Dešinėn" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Digging particles" +msgstr "Įjungti visus" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Įjungti papildinių kanalų palaikymą." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable mod security" +msgstr "Papildiniai internete" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Įjungia minimapą." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Matymo laukas" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Forward key" +msgstr "Pirmyn" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Žaidimai" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HTTP mods" +msgstr "Papildiniai" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Height noise" +msgstr "Dešinieji langai" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Inc. volume key" +msgstr "Nustatyti klavišus" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Inventory key" +msgstr "Inventorius" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Jump key" +msgstr "Pašokti" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Large chat console key" +msgstr "Nustatyti klavišus" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Left key" +msgstr "Kairėn" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Apšvietimo efektai" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Main menu script" +msgstr "Pagrindinis meniu" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian" +msgstr "Žemėlapių generavimas" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat" +msgstr "Žemėlapių generavimas" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal" +msgstr "Žemėlapių generavimas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "Žemėlapių generavimas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5" +msgstr "Žemėlapių generavimas" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6" +msgstr "Žemėlapių generavimas" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7" +msgstr "Žemėlapių generavimas" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Valleys" +msgstr "Žemėlapių generavimas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Valleys specific flags" +msgstr "Žemėlapių generavimas" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Papildiniai internete" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mute key" +msgstr "paspauskite klavišą" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Apšvietimo efektai" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move key" +msgstr "Kūrybinė veiksena" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Kūrybinė veiksena" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Right key" +msgstr "Dešinėn" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River noise" +msgstr "Dešinieji langai" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Užlaikymas" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Serveris" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Serveris" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Serverio prievadas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server URL" +msgstr "Serveris" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server address" +msgstr "Serverio prievadas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server description" +msgstr "Serverio prievadas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server name" +msgstr "Serveris" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server port" +msgstr "Serverio prievadas" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Serverio prievadas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist URL" +msgstr "Viešų serverių sąrašas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "Viešų serverių sąrašas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist file" +msgstr "Viešų serverių sąrašas" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shader path" +msgstr "Šešėliavimai" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Smooth lighting" +msgstr "Apšvietimo efektai" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneak key" +msgstr "Nustatyti klavišus" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed" +msgstr "Nustatyti klavišus" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Nustatymai" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Nepermatomi lapai" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Nepermatomi lapai" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Nepermatomi lapai" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Nepermatomi lapai" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "World start time" +msgstr "Pasaulio pavadinimas" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Kūrybinis režimas " + +#~ msgid "- Damage: " +#~ msgstr "- Sužeidimai: " + +#~ msgid "Address / Port" +#~ msgstr "Adresas / Prievadas" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Ar tikrai norite perkurti savo lokalų pasaulį?" + +#~ msgid "Back" +#~ msgstr "Atgal" + +#~ msgid "Config mods" +#~ msgstr "Konfigūruoti papildinius" + +#~ msgid "Configure" +#~ msgstr "Konfigūruoti" + +#~ msgid "Connect" +#~ msgstr "Jungtis" + +#~ msgid "Credits" +#~ msgstr "Padėkos" + +#~ msgid "Damage enabled" +#~ msgstr "Žalojimas įjungtas" + +#, fuzzy +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Atsisiųskite sub žaidimą, tokį kaip minetest_game, iš minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Atsisiųsti vieną iš minetest.net" + +#, fuzzy +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Atsiunčiama $1, prašome palaukti..." + +#, fuzzy +#~ msgid "Enable VBO" +#~ msgstr "Įjungti papildinį" + +#, fuzzy +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Leisti sužeidimus" + +#~ msgid "Enter " +#~ msgstr "Įvesti " + +#~ msgid "Game" +#~ msgstr "Žaidimas" + +#, fuzzy +#~ msgid "In-Game" +#~ msgstr "Žaidimas" + +#, fuzzy +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Įdiegti papildinį: failas: „$1“" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Klavišai. (Jei šis meniu sugenda, pašalinkite įrašus iš minetest.conf)" + +#~ msgid "Main" +#~ msgstr "Pagrindinis" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "Pagrindinis meniu" + +#, fuzzy +#~ msgid "Menus" +#~ msgstr "Meniu" + +#~ msgid "Name / Password" +#~ msgstr "Vardas / Slaptažodis" + +#~ msgid "Name/Password" +#~ msgstr "Vardas/slaptažodis" + +#~ msgid "No" +#~ msgstr "Ne" + +#~ msgid "Ok" +#~ msgstr "Gerai" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Paralaksinė okliuzija" + +#, fuzzy +#~ msgid "Parallax occlusion scale" +#~ msgstr "Paralaksinė okliuzija" + +#~ msgid "PvP enabled" +#~ msgstr "PvP įjungtas" + +#, fuzzy +#~ msgid "Reset singleplayer world" +#~ msgstr "Atstatyti vieno žaidėjo pasaulį" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "Pasirinkite papildinio failą:" + +#, fuzzy +#~ msgid "Server / Singleplayer" +#~ msgstr "Žaisti vienam" + +#, fuzzy +#~ msgid "Special key" +#~ msgstr "Nustatyti klavišus" + +#~ msgid "Start Singleplayer" +#~ msgstr "Atstatyti vieno žaidėjo pasaulį" + +#~ msgid "Toggle Cinematic" +#~ msgstr "Įjungti kinematografinį" + +#~ msgid "Yes" +#~ msgstr "Taip" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Jūs numirėte" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/lv/minetest.po b/po/lv/minetest.po new file mode 100644 index 0000000..b5aabb6 --- /dev/null +++ b/po/lv/minetest.po @@ -0,0 +1,7083 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-14 11:16+0000\n" +"Last-Translator: Cow Boy <cowboylv@tutanota.com>\n" +"Language-Team: Latvian <https://hosted.weblate.org/projects/minetest/" +"minetest/lv/>\n" +"Language: lv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n % 10 == 0 || n % 100 >= 11 && n % 100 <= " +"19) ? 0 : ((n % 10 == 1 && n % 100 != 11) ? 1 : 2);\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Iziet uz izvēlni" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Invalid command: " +msgstr "Lokālā komanda" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "Viena spēlētāja režīms" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "Viena spēlētāja režīms" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Atdzīvoties" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Jūs nomirāt" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "Lokālā komanda" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "Lokālā komanda" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Lua skriptā radās kļūme:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Radās kļūme:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Galvenā izvēlne" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Atjaunot savienojumu" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Serveris ir pieprasījis savienojuma atjaunošanu:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Izvēlieties pasauli:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protokola versiju neatbilstība. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Serveris pieprasa protokola versiju $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Serveris atbalsta protokola versijas starp $1 un $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Mēs atbalstam tikai protokola versiju $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Mēs atbalstam protokola versijas starp $1 un $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Atcelt" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Atkarības:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Atspējot visus" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Atspējot modu komplektu" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Iespējot visus" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Iespējot modu komplektu" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Neizdevās iespējot modu \"$1\", jo tas satur neatļautus simbolus. Tikai " +"sekojošie simboli ir atļauti: [a-z0-9_]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mods:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Nav (neobligāto) atkarību" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Nav atrasts spēles apraksts." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Nav obligāto atkarību" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Nav atrasts modu komplekta apraksts." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Nav neobligāto atkarību" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Neobligātās atkarības:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Saglabāt" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Pasaule:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "iespējots" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "Ielāde..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Visi papildinājumi" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Already installed" +msgstr "Šis taustiņš jau tiek izmantots" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Atpakaļ uz Galveno Izvēlni" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "Spēlēt (kā serveris)" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Downloading..." +msgstr "Ielāde..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Neizdevās lejuplādēt $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Spēles" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instalēt" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "Instalēt" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "Neobligātās atkarības:" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "Instalācija: Neatbalstīts faila tips “$1” vai arī sabojāts arhīvs" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Modi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Nevarēja iegūt papildinājumus" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Nav rezultātu" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "No updates" +msgstr "Atjaunot" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Tekstūru komplekti" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Atinstalēt" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Update" +msgstr "Atjaunināt" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Pasaule ar nosaukumu “$1” jau pastāv" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caves" +msgstr "Oktāvas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Izveidot" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekorācijas" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "" +"Uzmanību: “Minimal development test” ir domāts priekš spēles izstrādātājiem." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Instalēt" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Kartes ģenerators" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Nav izvēlētas spēles" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Sēkla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Pasaules nosaukums" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Jums nav instalēta neviena spēle." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Vai Jūs esat pārliecināts, ka vēlaties izdzēst “$1”?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Izdzēst" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: neizdevās izdzēst “$1”" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: nepieejama atrašanās vieta “$1”" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Vai izdzēst pasauli “$1”?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Apstiprināt paroli" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Vārds" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Parole" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Paroles nesakrīt!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Reģistrēties un pievienoties" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Piekrist" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Pārsaukt modu komplektu:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Šim modu komplektam ir noteikts nosaukums, kas uzdots failā modpack.conf, un " +"tas anulēs jebkādu pārsaukšanu šeit." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Nav iestatījuma apraksta)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D Troksnis" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Atpakaļ uz Iestatījumu lapu" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Pārlūkot" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Saturs" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Saturs" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Atspējots" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Izmainīt" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Iespējots" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktāvas" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Nobīde" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Noturība" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Lūdzu ievadiet derīgu veselu skaitli." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Lūdzu ievadiet derīgu skaitli." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Atiestatīt uz noklusējumu" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Mērogs" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Meklēšana" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Izvēlēties mapi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Izvēlēties failu" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Rādīt tehniskos nosaukumus" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Vērtībai jābūt vismaz $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Vērtībai jābūt ne lielākai par $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Izkaisījums pa X asi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Izkaisījums pa Y asi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Izkaisījums pa Z asi" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "absolūtā vērtība" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "noklusējuma" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "atvieglots" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Iespējots)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 modi" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Neizdevās instalēt $1 uz $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Moda instalācija: Neizdevās atrast īsto moda nosaukumu priekš “$1”" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Moda instalācija: Neizdevās atrast derīgu mapes nosaukumu priekš modu " +"komplekta “$1”" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Neizdevās atrast derīgu modu vai modu komplektu" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Neizdevās ieinstalēt $1 kā tekstūru paku" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Neizdevās instalēt spēli kā $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Neizdevās instalēt modu kā $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Neizdevās instalēt modu komplektu kā $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Ielāde..." + +#: builtin/mainmenu/serverlistmgr.lua +#, fuzzy +msgid "Public server list is disabled" +msgstr "Klienta puses skriptēšana ir atspējota" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Pamēģiniet atkārtoti ieslēgt publisko serveru sarakstu un pārbaudiet " +"interneta savienojumu." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktīvie dalībnieki" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Pamata izstrādātāji" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Izvēlēties mapi" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Bijušie dalībnieki" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Bijušie pamata izstrādātāji" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Pārlūkot tiešsaistes saturu" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Saturs" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Atspējot tekstūru komplektu" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informācija:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Instalētie papildinājumi:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Nav atkarību." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Nav atrasts papildinājuma apraksts" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Pārsaukt" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Atinstalēt papildinājumu" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Iespējot tekstūru komplektu" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Paziņot par serveri" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Piesaistes adrese" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Radošais režīms" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Iespējot bojājumus" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Spēlēt (kā serveris)" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Palaist serveri" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Jauns" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Pasaule nav ne izveidota, ne izvēlēta!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Spēlēt" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Ports" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "Izvēlieties pasauli:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Izvēlieties pasauli:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Servera ports" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Sākt spēli" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "- Adrese: " + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Notīrīt" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Radošais režīms" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "- Bojājumi: " + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "Pievienot izlasei" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Pievienoties spēlei" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Pings" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "Paziņot par serveri" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Izdzēst no izlases" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "Servera ports" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D mākoņi" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Visi iestatījumi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Gludināšana:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Atcerēties ekrāna izmēru" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilineārais filtrs" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Nomainīt kontroles" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Savienots stikls" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Skaistas lapas" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "“Mipmap”" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "“Mipmap” + anizotr. filtrs" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Bez filtra" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Bez “mipmap”" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Bloku izcelšana" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Bloku konturēšana" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Nekas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Necaurredzamas lapas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Necaurredzams ūdens" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Daļiņas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Ekrāns:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Uzstādījumi" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Šeideri" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "Šeideri (nepieejami)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Šeideri (nepieejami)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Vienkāršas lapas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Gluds apgaismojums" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Teksturēšana:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Toņu atbilstība" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Pieskārienslieksnis: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Trilineārais filtrs" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Viļņojošas lapas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Viļņojoši šķidrumi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Viļņojoši augi" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Savienojuma kļūme (noildze?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Savienojuma noildze." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Gatavs!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inicializē blokus" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Inicializē blokus..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Ielādē tekstūras..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Pārbūvē šeiderus..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Savienojuma kļūme (noildze?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "Nevarēja atrast vai ielādēt spēli \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Nederīga spēles specifikācija." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Galvenā izvēlne" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Nav izvēlēta ne pasaule, ne adrese. Nav, ko darīt." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Spēlētāja vārds ir pārāk garš." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Lūdzu, izvēlieties vārdu!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Neizdevās atvērt iestatīto paroļu failu: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Sniegtā pasaules atrašanās vieta neeksistē: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Vairāk informācijas failā debug.txt." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Adrese: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Režīms: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Ports: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Publisks: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Severa nosaukums: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Radās kļūme:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Automātiskā pārvietošanās izslēgta" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Automātiskā pārvietošanās ieslēgta" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Kameras atjaunošana atspējota" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Kameras atjaunošana iespējota" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Nomainīt paroli" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Kino režīms izslēgts" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Kino režīms ieslēgts" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Klienta puses skriptēšana ir atspējota" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Savienojas ar serveri..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Turpināt" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Kontroles:\n" +"- %s: uz priekšu\n" +"- %s: uz atpakaļu\n" +"- %s: pa kreisi\n" +"- %s: pa labi\n" +"- %s: lekt/kāpt\n" +"- %s: lavīties/nolaisties\n" +"- %s: nomest priekšmetu\n" +"- %s: inventārs\n" +"- Pele: griezties/skatīties\n" +"- Peles kreisā poga: rakt/sist\n" +"- Peles labā poga: likt/izmantot\n" +"- Peles rullītis: izvēlēties priekšmetu\n" +"- %s: čats\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Izveido klientu..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Izveido serveri..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Atkļūdošanas informācija un profilēšanas grafiks paslēpti" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Atkļūdošanas informācija parādīta" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" +"Atkļūdošanas informācija, profilēšanas grafiks un karkasattēlojums atspējoti" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Noklusējuma kontroles:\n" +"Ne izvēlnē:\n" +"- pieskāriens: aktivizē pogu\n" +"- dubultpieskāriens: nolikt/izmantot\n" +"- vilkt ar pirksto: skatīties apkārt\n" +"Izvēlnē/inventārā:\n" +"- dubultpieskāriens (ārpus izvēlnes)\n" +" --> aizvērt izvēlni\n" +"- pieskāriens priekšmetiem, pieskāriens kastītei:\n" +" --> pārvietot priekšmetus\n" +"- pieskāriens&vilkšana, ar otru pirkstu pieskāriens:\n" +" --> novietot vienu priekšmetu kastītē\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Atspējots neierobežots redzamības diapazons" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Iespējots neierobežots redzamības diapazons" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Izveido klientu..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Iziet uz izvēlni" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Iziet uz OS" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Ātrais režīms izslēgts" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Ātrais režīms ieslēgts" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Ātrais režīms ieslēgts (bet: nav “fast” privilēģijas)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Lidošanas režīms izslēgts" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Lidošanas režīms ieslēgts" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Lidošanas režīms ieslēgts (bet: nav “fly” privilēģijas)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Migla atspējota" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Migla iespējota" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Spēles informācija:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Spēle nopauzēta" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Lokāls serveris" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Priekšmetu apraksti..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Mēdiji..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Minikarte šobrīd atspējota vai nu spēlei, vai modam" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "Viena spēlētāja režīms" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "“Noclip” režīms izslēgts" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "“Noclip” režīms ieslēgts" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "“Noclip” režīms ieslēgts (bet: nav “noclip” privilēģijas)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Bloku apraksti..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Izslēgts" + +#: src/client/game.cpp +msgid "On" +msgstr "Ieslēgts" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Kustība uz augšu/leju pēc skatīšanās virziena izslēgta" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Kustība uz augšu/leju pēc skatīšanās virziena ieslēgta" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profilēšanas grafiks parādīts" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Attālināts serveris" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Atrisina adresi..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Beidz darbu..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Viena spēlētāja režīms" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Skaņas skaļums" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Skaņa izslēgta" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Skaņa ieslēgta" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Redzamības diapazons nomainīts uz %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Redzamības diapazons ir maksimāls: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Redzamības diapazons ir minimāls: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Skaļums nomainīts uz %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Karkasattēlojums iespējots" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Tuvināšana šobrīd atspējota vai nu spēlei, vai modam" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Čats paslēpts" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Čats parādīts" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "Spēles saskarne paslēpta" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "Spēles saskarne parādīta" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profilētājs paslēpts" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profilētājs parādīts (lapa %d no %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Ctrl" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Uz leju" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Erase EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Execute" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Palīdzība" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME Accept" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME Convert" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME Escape" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME Mode Change" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME Nonconvert" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Pa kreisi" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Kreisā poga" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Kreisais Ctrl" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Kreisais Alt" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Kreisais Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Kreisā Windows poga" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Alt" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Vidējā poga" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Ciparbloka *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Ciparbloka +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Ciparbloka -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Ciparbloka ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Ciparbloka /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Ciparbloka 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Ciparbloka 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Ciparbloka 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Ciparbloka 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Ciparbloka 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Ciparbloka 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Ciparbloka 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Ciparbloka 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Ciparbloka 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Ciparbloka 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Play" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Print Screen" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Return" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Pa labi" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Labā poga" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Labais Ctrl" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Labais Alt" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Labais Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Labā Windows poga" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Select" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Sleep" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Snapshot" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Atstarpe" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Uz augšu" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Poga 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Poga 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Minikarte paslēpta" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minikarte radara režīmā, palielinājums x1" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minikarte virsmas režīmā, palielinājums x1" + +#: src/client/minimap.cpp +#, fuzzy +msgid "Minimap in texture mode" +msgstr "Minikarte virsmas režīmā, palielinājums x1" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Neizdevās lejuplādēt $1" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Turpināt" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "“Speciālais” = kāpt lejā" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Auto-iešana" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Automātiskā lekšana" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Atmuguriski" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Mainīt kameru" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Čats" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Komanda" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsole" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Sam. diapazonu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Sam. skaļumu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Nospied “lekt” divreiz, lai lidotu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Mest" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Uz priekšu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Pal. diapazonu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Pal. skaļumu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventārs" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Lekt" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Šis taustiņš jau tiek izmantots" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Lokālā komanda" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Skaņa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Nāk. priekšmets" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Iepr. priekšmets" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Redzamības diapazons" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Ekrānšāviņš" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Lavīties" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Spēles saskarne" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Čata logs" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Ātrā pārvietošanās" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Lidot" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Migla" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Minikarte" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "“Noclip”" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Pārvietoties pēc skatīšanās leņķa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "nospiediet pogu" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Nomainīt" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Jaunā parole" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Vecā parole" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Paroles nesakrīt!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Iziet" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Apklusināts" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Skaņas skaļums: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "lv" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Lūdzu, izvēlieties vārdu!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Pasaules nosaukums" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Būvēt iekšā spēlētājā" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Mainīt kameru" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Komanda" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Čats parādīts" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Vadība" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Dekorācijas" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Ātrā pārvietošanās" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Spēlētājs var lidot ignorējot gravitāciju.\n" +"Šim ir vajadzīga “fly” privilēģija servera pusē." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Gludināšana:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Lidošana" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Spēles" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Spēles saskarne parādīta" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Ja iespējota, liek visām kustībām peldot un lidojot būt relatīvām pret " +"spēlētāja skatīšanās virziena." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Ja iespējots, varat novietot blokus, kur Jūs stāvat.\n" +"Šis ir noderīgi, kad jābūvē šaurās vietās." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Gluds apgaismojums" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Bloku izcelšana" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Kustība uz augšu/leju pēc skatīšanās virziena" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Spēlētājs var lidot ignorējot gravitāciju.\n" +"Šim ir vajadzīga “fly” privilēģija servera pusē." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Ekrāns:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Ekrānšāviņš" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Palaist serveri" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "- Severa nosaukums: " + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Servera ports" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Servera ports" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Uzstādījumi" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Radošais režīms: " + +#~ msgid "- Damage: " +#~ msgstr "- Bojājumi: " + +#~ msgid "Address / Port" +#~ msgstr "Adrese / Ports" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "" +#~ "Vai esat pārliecināts, ka vēlaties atiestatīt savu viena spēlētāja " +#~ "pasauli?" + +#~ msgid "Back" +#~ msgstr "Atpakaļ" + +#~ msgid "Bump Mapping" +#~ msgstr "“Bump Mapping”" + +#~ msgid "Config mods" +#~ msgstr "Iestatīt modus" + +#~ msgid "Configure" +#~ msgstr "Iestatīt" + +#~ msgid "Connect" +#~ msgstr "Pieslēgties" + +#~ msgid "Credits" +#~ msgstr "Pateicības" + +#~ msgid "Damage enabled" +#~ msgstr "Bojājumi iespējoti" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Lejuplādējiet spēles, kā piemēram, “Minetest Game”, no minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Varat tās lejuplādēt no minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Lejuplādējas un instalējas $1, lūdzu uzgaidiet..." + +#~ msgid "Enter " +#~ msgstr "Ievadiet " + +#~ msgid "Game" +#~ msgstr "Spēle" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Izveidot normāl-kartes" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Instalācija: fails: “$1”" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Taustiņu iestatījumi. (Ja šī izvēlne salūzt, izdzēsiet iestatījumus no " +#~ "minetest.conf)" + +#~ msgid "Main" +#~ msgstr "Galvenā izvēlne" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Minikarte radara režīmā, palielinājums x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Minikarte radara režīmā, palielinājums x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Minikarte virsmas režīmā, palielinājums x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Minikarte virsmas režīmā, palielinājums x4" + +#~ msgid "Name / Password" +#~ msgstr "Vārds / Parole" + +#~ msgid "Name/Password" +#~ msgstr "Vārds/Parole" + +#~ msgid "No" +#~ msgstr "Nē" + +#~ msgid "Ok" +#~ msgstr "Ok" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Tekstūru dziļums" + +#~ msgid "PvP enabled" +#~ msgstr "PvP iespējots" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Atiestatīt viena spēlētāja pasauli" + +#~ msgid "Special" +#~ msgstr "Speciālais" + +#~ msgid "Start Singleplayer" +#~ msgstr "Sākt viena spēlētāja spēli" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Lai iespējotu šeiderus, jāizmanto OpenGL draiveris." + +#~ msgid "Yes" +#~ msgstr "Jā" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Jūs tūlīt pievienosieties šim serverim ar vārdu \"%s\" pirmo reizi.\n" +#~ "Ja Jūs turpināsiet, šajā serverī tiks izveidots jauns lietotājs ar jūsu " +#~ "pierakstīšanās informāciju.\n" +#~ "Lūdzu ievadiet savu paroli vēlreiz un nospiediet “Reģistrēties un " +#~ "pievienoties”, lai apstiprinātu lietotāja izveidi, vai arī nospiediet " +#~ "“Atcelt”, lai pārtrauktu šo darbību." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Jūs nomirāt" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/lzh/minetest.po b/po/lzh/minetest.po new file mode 100644 index 0000000..eae0e20 --- /dev/null +++ b/po/lzh/minetest.po @@ -0,0 +1,6842 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-01-20 14:35+0000\n" +"Last-Translator: Gao Tiesuan <yepifoas@666email.com>\n" +"Language-Team: Chinese (Literary) <https://hosted.weblate.org/projects/" +"minetest/minetest/lzh/>\n" +"Language: lzh\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.11-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "空令。" + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "令之传者: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "复生" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "尔死矣" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "平地" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "泥流" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "川" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "地表之蚀" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "" + +#: src/client/game.cpp +msgid "- Public: " +msgstr "" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "消音" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" diff --git a/po/minetest.pot b/po/minetest.pot new file mode 100644 index 0000000..084a5ff --- /dev/null +++ b/po/minetest.pot @@ -0,0 +1,6840 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Public: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" diff --git a/po/mr/minetest.po b/po/mr/minetest.po new file mode 100644 index 0000000..1c08108 --- /dev/null +++ b/po/mr/minetest.po @@ -0,0 +1,6865 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2021-06-10 14:35+0000\n" +"Last-Translator: Avyukt More <moreavyukt1@outlook.com>\n" +"Language-Team: Marathi <https://hosted.weblate.org/projects/minetest/" +"minetest/mr/>\n" +"Language: mr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.7-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "मुख्य पानावर परत जा" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "पुनर्जन्म" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "तू मेलास" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "ठीक आहे" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "त्रुटी आढळली" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "एक त्रुटी आली:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "मुख्य पान" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "पुन्हा सामील व्हा" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "पुन्हा सामील होण्यासाठी विनंती करीत आहे:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "सर्व्हरची आवृत्ती जुळत नाही " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "सर्व्हर फक्त आवृत्ती $1 वर कार्य करतो " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "सर्व्हर $1 आणि $2 दरम्यान प्रोटोकॉल आवृत्तीचे समर्थन करतो. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "आम्ही केवळ आवृत्ती $1 चे समर्थन करतो." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "आम्ही केवळ आवृत्ती $1 आणि आवृत्ती $2 चे समर्थन करतो." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "रद्द करा" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "अवलंबित्व:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "सर्व काही थांबवा" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "मॉडपॅक वापरणे थांबवा" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "सर्व वापरा" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "मॉडपॅक वापरा" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "मॉड \"$1\" वापरु नाही शकत... कारण त्या नावात चुकीचे अक्षरे आहेत." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "आणखी मॉड शोधा" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "मॉड:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "अवलंबन नाही" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "वर्णन केलेले नाही." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "अवलंबन नाही" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "वर्णन केलेले नाही." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "कोणताही मॉड बदलणार नाही" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "बदलणारे मॉड:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "बदल जतन करा" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "जग:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "वापरा" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "$१ आधीच डाउन्लोआडेड आहे. आपण ते अधिलिखित करू इच्छिता?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 $2 करून" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 डाउनलोड होत आहे..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "सर्व संकुले" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "आधीच स्थापित" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "मुख्य पानावर परत जा" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "मुख्य खेळ:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "जेव्हा मिनटेस्ट सीआरएलशिवाय संकलित केले होते तेव्हा सामग्री डीबी उपलब्ध नाही" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "डाउनलोड करत आहे..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "$१ डाउनलोड करू नाही शकत" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "खेळ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "डाउनलोड" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "डाउनलोड $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "गहाळ अवलंबित्व डाउनलोड करा" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "मॉड" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "काहीच सापडत नाही" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "कोणतीही गोष्ट नाहीत" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "अपडेट नाहीत" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "सापडले नाही" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "अधिलिखित" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "कृपया मुख्य खेळ योग्य आहे याची तपासणी करा." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "रांगेत लागले आहेत" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "टेक्सचर पॅक" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "काढा" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "अपडेट" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "सर्व अपडेट करा [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "अंतर्जाल शोधक वर माहिती काढा" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "\"$1\" नावाचे जग आधीच अस्तित्वात आहे" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "अतिरिक्त भूभाग" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "थंडी" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "कोरडे हवामान" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "हवामान आणि आपत्ती यांच्यात फरक" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "भिन्न हवामान आणि आपत्ती" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "खाण" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "गुहा" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "तयार करा" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "सजावट" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "चेतावणी: Development Test विकासकांसाठी आहे." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "अंधारकोठडी" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "सपाट जमीन" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "हवेत उडणारे जमीन" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "हवेत उडणारे जमीन" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "समुद्र आणि भूमिगत भूभाग" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "टेकड्या" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "दमट नद्या" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "नद्यांच्या आसपास अधिक आर्द्रता" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "डाउनलोड $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "तलाव" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "कमी आर्द्रता आणि जास्त उष्णता यामुळे उथळ किंवा कोरड्या नद्या" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "नकाशा निर्माता" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "नकाशा जनरेटर ध्वज" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "नकाशा जनरेटर विशिष्ट ध्वजांकित करा" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "पर्वत" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "चिखल प्रवाह" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "बोगदे आणि गुहांच्ये जाळे" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "कोणताही खेळ निवडलेला नाही" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "कमी उष्णता" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "कमी आर्द्रता" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "नद्या" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "समुद्र पातळीवरील नद्या" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "सीड" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "भिन्न हवामान आणि आपत्ती यांच्यात सपाट संक्रमण" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "v6 ने तयार केलेल्या झाडे आणि जंगल गवत यावर कोणताही परिणाम होणार नाही" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "भूप्रदेशावर दिसणारी रचना, विशेषत: झाडे" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "समशीतोष्ण, वाळवंट" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "समशीतोष्ण, वाळवंट, जंगल" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "समशीतोष्ण वाळवंट, जंगल, टुंड्रा, तैगा" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "जमीन पृष्ठभाग धूप" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "झाडे आणि गवत" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "नद्यांची खोली बदलते" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "खोल खाण" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "जगाचे नाव" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "आपल्याकडे कोणताही खेळ नाही." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "आपली खात्री आहे की आपण \"$1\" काढू इच्छिता?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "काढा" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: \"$1\" नाही कडू शकत" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: अवैध मार्ग \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "जग \"$1\" काढा?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "स्वीकारा" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "मॉडपॅक पुनर्नामित करा:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "ब्राउझ करा" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "थंबवा" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "वापरा" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "ऑफसेट" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "मोज" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "दमट नद्या" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "" + +#: src/client/game.cpp +msgid "- Public: " +msgstr "" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "एक त्रुटी आली:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "$१ डाउनलोड करू नाही शकत" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "जगाचे नाव" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "सजावट" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "खेळ" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "दमट नद्या" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "minetest.net वरून Minetest Game डाउनलोड करा" + +#~ msgid "Download one from minetest.net" +#~ msgstr "minetest.net वरुन डाउनलोड करा" + +#~ msgid "Game" +#~ msgstr "खेळ" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "तू मेलास" diff --git a/po/ms/minetest.po b/po/ms/minetest.po new file mode 100644 index 0000000..54529e0 --- /dev/null +++ b/po/ms/minetest.po @@ -0,0 +1,8377 @@ +msgid "" +msgstr "" +"Project-Id-Version: Malay (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-24 09:25+0000\n" +"Last-Translator: Yaya - Nurul Azeera Hidayah @ Muhammad Nur Hidayat " +"Yasuyoshi <translation@mnh48.moe>\n" +"Language-Team: Malay <https://hosted.weblate.org/projects/minetest/minetest/" +"ms/>\n" +"Language: ms\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Padam baris gilir sembang keluar" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Perintah kosong." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Keluar ke menu utama" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Perintah tidak sah: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Perintah dikeluarkan: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Senaraikan pemain dalam talian" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Pemain dalam talian: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Baris gilir sembang keluar kini kosong." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Perintah ini dilumpuhkan oleh pelayan." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Jelma semula" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Anda telah meninggal" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Perintah tersedia:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Perintah tersedia: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Perintah tidak tersedia: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Dapatkan bantuan untuk perintah" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Gunakan '.help <perintah>' untuk dapatkan maklumat lanjut, atau '.help all' " +"untuk senaraikan kesemuanya." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <perintah>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<tiada yang tersedia>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Berlakunya ralat dalam skrip Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Telah berlakunya ralat:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menu utama" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Sambung semula" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Pelayan meminta anda untuk menyambung semula:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "Versi $1 baharu kini tersedia" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "Mods Klien" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" +"Versi terpasang: $1\n" +"Versi baharu: $2\n" +"Lawati $3 untuk ketahui cara untuk mendapatkan versi terbaru dan kekal " +"dikemas kini dengan sifat dan pembaikan pepijat." + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "Kemudian" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "Tidak Selamanya" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Versi protokol tidak serasi. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Pelayan menguatkuasakan protokol versi $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Pelayan menyokong protokol versi $1 hingga $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "Lawati laman sesawang" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Kami hanya menyokong protokol versi $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Kami menyokong protokol versi $1 hingga $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "(Dibolehkan, ada ralat)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "(Tidak dipenuhi)" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Batal" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Kebergantungan:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Lumpuhkan semua" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Lumpuhkan pek mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Membolehkan semua" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Bolehkan pek mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Gagal untuk membolehkan mods \"$1\" kerana ia mengandungi aksara yang tidak " +"dibenarkan. Hanya aksara [a-z0-9_] sahaja yang dibenarkan." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Cari Mods Lain" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mods:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Tiada kebergantungan (pilihan)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Tiada perihal permainan tersedia." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Tiada kebergantungan wajib" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Tiada perihal pek mods tersedia." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Tiada kebergantungan pilihan" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Kebergantungan pilihan:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Simpan" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Dunia:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "Dibolehkan" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" sudah wujud. Adakah anda ingin tulis gantinya?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Kebergantungan $1 dan $2 akan dipasangkan." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 oleh $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 sedang muat turun,\n" +"$2 menunggu giliran" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 memuat turun..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 memerlukan kebergantungan yang tidak dijumpai." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 akan dipasangkan, dan kebergantungan $2 akan dilangkau." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Semua pakej" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Sudah dipasang" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Kembali ke Menu Utama" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Permainan Asas:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB tidak tersedia apabila Minetest dikompil tanpa cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Memuat turun..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Gagal memuat turun $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Permainan" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Pasang" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Pasang $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Pasang kebergantungan yang hilang" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Pasang: Jenis fail tidak disokong atau arkib rosak" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mods" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Tiada pakej yang boleh diambil" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Tiada hasil" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Tiada kemas kini" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Tidak dijumpai" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Tulis ganti" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Sila semak dan pastikan permainan asas itu betul." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Menunggu giliran" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Pek tekstur" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Nyahpasang" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Kemas kini" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Kemas Kini Semua [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Lihat maklumat lanjut dalam pelayar sesawang" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Dunia bernama \"$1\" telah wujud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Rupa bumi tambahan" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Kedinginan altitud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Kekeringan altitud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Penyebatian biom" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biom" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Gua besar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Gua" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Cipta" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Hiasan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "Development Test hanyalah untuk kegunaan pembangun." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Kurungan bawah tanah" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Rupa bumi rata" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Jisim bumi terapung atas langit" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Tanah terapung (dalam uji kaji)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Jana rupa bumi bukan-fraktal: Lautan dan bawah tanah" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Bukit" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Sungai lembap" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Tingkatkan kelembapan sekitar sungai" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "Pasang suatu permainan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "Pasang permainan lain" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Tasik" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Kelembapan rendah dan haba tinggi menyebabkan sungai cetek atau kering" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Janaan peta" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Bendera janapeta" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Bendera khusus Janapeta" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Gunung" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Aliran lumpur" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Jaringan terowong dan gua" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Tiada permainan dipilih" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Kurangkan haba mengikut altitud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Kurangkan kelembapan mengikut altitud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Sungai" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Sungai aras laut" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Benih" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Peralihan lembut di antara biom" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Struktur yang muncul atas rupa bumi (tiada kesan pada pokok dan rumput hutan " +"dicipta oleh v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Struktur yang muncul atas rupa bumi, biasanya pokok dan tumbuhan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Iklim Sederhana, Gurun" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Iklim Sederhana, Gurun, Hutan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Iklim Sederhana, Gurun, Hutan, Tundra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Hakisan permukaan rupa bumi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Pokok dan rumput hutan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Kedalaman sungai berbagai" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Gua gergasi yang sangat mendalam bawah tanah" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nama dunia" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Anda tidak memasang sebarang permainan." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Adakah anda pasti anda ingin memadam \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Padam" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: gagal memadam \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: laluan tidak sah \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Padam Dunia \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Sahkan Kata Laluan" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "Menyertai $1" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "Nama tidak ditulis" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nama" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Kata laluan" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "Kata laluan tidak padan" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "Daftar" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Terima" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Namakan semula pek mods:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Pek mods ini mempunyai nama khusus diberikan dalam fail modpack.conf " +"miliknya yang akan mengatasi sebarang penamaan semula di sini." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Tiada perihal untuk tetapan yang diberi)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Hingar 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Kembali ke halaman Tetapan" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Layar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "Kandungan: Permainan" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "Kandungan: Mods" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Dilumpuhkan" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Edit" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Dibolehkan" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lakunariti" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktaf" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Ofset" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Penerusan" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Sila masukkan integer yang sah." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Sila masukkan nombor yang sah." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Pulihkan Tetapan Asal" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Skala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Cari" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Pilih direktori" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Pilih fail" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Tunjukkan nama teknikal" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Nilai mestilah sekurang-kurangnya $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Nilai mestilah tidak lebih daripada $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Sebaran X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Sebaran Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Sebaran Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Nilai mutlak" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "lalai" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "tumpul" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Dibolehkan)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mods" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Gagal memasang $1 pada $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Pasang Mods: Gagal mencari nama mods sebenar untuk: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "Pasang Mods: tidak jumpa nama folder yang sesuai untuk pek mods $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Tidak jumpa mods atau pek mods yang sah" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Gagal memasang $1 sebagai pek tekstur" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Gagal memasang permainan sebagai $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Gagal memasang mods sebagai $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Gagal memasang pek mods sebagai $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Sedang memuatkan..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Senarai pelayan awam dilumpuhkan" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Cuba aktifkan semula senarai pelayan awam dan periksa sambungan internet " +"anda." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Perihal" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Penyumbang Aktif" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Pengemas gabung aktif:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Pembangun Teras" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Buka Direktori Data Pengguna" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Membuka direktori yang mengandungi dunia, permainan, mods, dan pek\n" +"tekstur yang disediakan oleh pengguna, dalam pengurus / pelayar fail." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Penyumbang Terdahulu" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Pembangun Teras Terdahulu" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "Kongsikan log nyahpepijat" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Layari kandungan dalam talian" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Kandungan" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Lumpuhkan Pek Tekstur" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Maklumat:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Pakej Dipasang:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Tiada kebergantungan." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Tiada perihal pakej tersedia" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Namakan Semula" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Nyahpasang Pakej" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Guna Pek Tekstur" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Umumkan Pelayan" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Alamat Ikatan" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Mod Kreatif" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Boleh Cedera" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Hos Permainan" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Hos Pelayan" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Pasangkan permainan daripada ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Buat Baru" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Tiada dunia dicipta atau dipilih!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Mula Main" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Pilih Mods" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Pilih Dunia:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Port Pelayan" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Mulakan Permainan" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Alamat" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Padam" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Mod Kreatif" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Boleh cedera / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Kegemaran" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Pelayan Tidak Serasi" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Sertai Permainan" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "Log Masuk" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Pelayan Awam" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Segarkan semula" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "Buang kegemaran" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Keterangan Pelayan" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "(sokongan permainan diperlukan)" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Awan 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Semua Tetapan" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Antialias:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Autosimpan Saiz Skrin" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Penapisan Bilinear" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Tukar Kekunci" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Kaca Bersambungan" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Bayang dinamik" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "Bayang dinamik:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Daun Beragam" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Tinggi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Rendah" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Sederhana" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Peta Mip" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Peta Mip + Penapisan Aniso" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Tiada Tapisan" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Tiada Peta Mip" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Tonjolan Nod" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Kerangka Nod" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Tiada" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Daun Legap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Air Legap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partikel" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Skrin:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Tetapan" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Pembayang" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Pembayang (dalam uji kaji)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Pembayang (tidak tersedia)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Daun Ringkas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Pencahayaan Lembut" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Jalinan:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Pemetaan Tona" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "Nilai ambang sentuhan (px):" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Penapisan Trilinear" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "Sangat Tinggi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Sangat Rendah" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Daun Bergoyang" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Cecair Bergelora" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Tumbuhan Bergoyang" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "Sambungan digugurkan (ralat protokol?)." + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Sambungan tamat tempoh." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Selesai!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Mengawalkan nod" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Sedang mengawalkan nod..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Sedang memuatkan tekstur..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Sedang membina semula pembayang..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Ralat dalam penyambungan (tamat tempoh?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Tidak jumpa atau tidak boleh muatkan permainan: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Spesifikasi permainan tidak sah." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menu Utama" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" +"Tiada dunia dipilih atau tiada alamat diberi. Tiada apa boleh dilakukan." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Nama pemain terlalu panjang." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Sila pilih suatu nama!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Fail kata laluan yang disediakan gagal dibuka: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Laluan dunia diberi tidak wujud: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Periksa fail debug.txt untuk maklumat lanjut." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Alamat: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Mod: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Awam: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Nama Pelayan: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Telah berlakunya ralat penyirian:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Capaian dinafikan. Sebab: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Pergerakan automatik dilumpuhkan" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Pergerakan automatik dibolehkan" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Batas blok disembunyikan" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Batas blok ditunjukkan untuk semua blok" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Batas blok ditunjukkan untuk blok semasa" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Batas blok ditunjukkan untuk blok berhampiran" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Kemas kini kamera dilumpuhkan" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Kemas kini kamera dibolehkan" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "Tidak boleh tunjuk batas blok (dilumpuhkan oleh mods atau permainan)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Tukar Kata Laluan" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Mod sinematik dilumpuhkan" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Mod sinematik dibolehkan" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Klien dinyahsambung" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Skrip pihak klien dilumpuhkan" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Sedang menyambung kepada pelayan..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Sambungan gagal untuk sebab yang tidak diketahui" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Teruskan" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Controls:\n" +"- %s: bergerak ke depan\n" +"- %s: bergerak ke belakang\n" +"- %s: bergerak ke kiri\n" +"- %s: bergerak ke kanan\n" +"- %s: lompat/naik atas\n" +"- %s: gali/ketuk\n" +"- %s: letak/guna\n" +"- %s: selinap/turun bawah\n" +"- %s: jatuhkan item\n" +"- %s: inventori\n" +"- Tetikus: pusing/lihat sekeliling\n" +"- Roda tetikus: pilih item\n" +"- %s: sembang\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Tidak mampu menyelesaikan alamat: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Sedang mencipta klien..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Sedang mencipta pelayan..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Maklumat nyahpepijat dan graf pembukah disembunyikan" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Maklumat nyahpepijat ditunjukkan" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Maklumat nyahpepijat, graf pembukah, dan rangka dawai disembunyikan" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Kawalan Asal:\n" +"Tiada menu kelihatan:\n" +"- tekan sekali: aktifkan butang\n" +"- tekan dua kali: letak barang/guna sesuatu\n" +"- tarik dengan jari: lihat sekeliling\n" +"Menu/Inventori kelihatan:\n" +"- tekan berganda (luar kawasan inventori):\n" +" -->tutup\n" +"- tekan tindanan, tekan slot:\n" +" --> pindah tindanan\n" +"- sentuh & tarik, tekan skrin pakai jari kedua\n" +" --> letak satu item dari tindanan ke dalam slot\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Jarak pandang tanpa had dilumpuhkan" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Jarak pandang tanpa had dibolehkan" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "Ralat dalam mencipta klien: %s" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Keluar ke Menu" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Keluar Terus Permainan" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Mod pergerakan pantas dilumpuhkan" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Mod pergerakan pantas dibolehkan" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" +"Mod pergerakan pantas dibolehkan (nota: tiada keistimewaan 'pergerakan " +"pantas')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Mod terbang dilumpuhkan" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Mod terbang dibolehkan" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Mod terbang dibolehkan (nota: tiada keistimewaan 'terbang')" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Kabut dilumpuhkan" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Kabut dibolehkan" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Maklumat permainan:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Permainan dijedakan" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Mengehos pelayan" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Sedang mentakrifkan item..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Sedang memuatkan media..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Peta mini dilumpuhkan oleh permainan atau mods" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Pemain Ramai" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Mod tembus blok dilumpuhkan" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Mod tembus blok dibolehkan" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Mod tembus blok dibolehkan (nota: tiada keistimewaan 'tembus blok')" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Sedang mentakrifkan nod..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Tutup" + +#: src/client/game.cpp +msgid "On" +msgstr "Buka" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Mod pergerakan pic dilumpuhkan" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Mod pergerakan pic dibolehkan" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Graf pembukah ditunjukkan" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Pelayan jarak jauh" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Sedang menyelesaikan alamat..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Sedang menutup..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Pemain Perseorangan" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Kekuatan Bunyi" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Bunyi dibisukan" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Sistem bunyi dilumpuhkan" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Sistem bunyi tidak disokong di binaan ini" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Bunyi dinyahbisukan" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Kemungkinan pelayan menjalankan versi %s yang berlainan." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Tidak mampu sambung ke %s kerana IPv6 dilumpuhkan" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Tidak mampu dengar di %s kerana IPv6 dilumpuhkan" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Jarak pandang ditukar ke %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Jarak pandang berada di tahap maksimum: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Jarak pandang berada di tahap minimum: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Kekuatan bunyi diubah kepada %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Rangka dawai ditunjukkan" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zum sedang dilumpuhkan oleh permainan atau mods" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Sembang disembunyikan" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Sembang ditunjukkan" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "Papar pandu (HUD) disembunyikan" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "Papar pandu (HUD) ditunjukkan" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Pembukah disembunyikan" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Pembukah ditunjukkan (halaman %d / %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplikasi" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Kunci Huruf Besar" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Ctrl" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Bawah" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Padam EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Lakukan" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Bantuan" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME - Terima" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME - Tukar" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME - Keluar" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME - Tukar Mod" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME - Tidaktukar" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Ke Kiri" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Butang Kiri" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Ctrl Kiri" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menu Kiri" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Shift Kiri" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Windows Kiri" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Butang Tengah" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Kunci Angka" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Pad Angka *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Pad Angka +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Pad Angka -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Pad Angka ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Pad Angka /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Pad Angka 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Pad Angka 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Pad Angka 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Pad Angka 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Pad Angka 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Pad Angka 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Pad Angka 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Pad Angka 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Pad Angka 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Pad Angka 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Padam OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Mula Main" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Print Screen" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Ke Kanan" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Butang Kanan" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Ctrl Kanan" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menu Kanan" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Shift Kanan" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Windows Kanan" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Select" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Sleep" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Tangkap Gambar Skrin" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Selang" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Atas" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Butang X 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Butang X 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zum" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Peta mini disembunyikan" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Peta mini dalam mod radar, Zum x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Peta mini dalam mod permukaan, Zum x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Peta mini dalam mod tekstur" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Gagal buka laman sesawang" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Membuka laman sesawang" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Teruskan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = panjat turun" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Autopergerakan" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Lompat automatik" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Ke Belakang" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Batas blok" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Tukar kamera" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Sembang" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Perintah" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsol" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Kurangkan jarak" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Perlahankan bunyi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Tekan dua kali \"lompat\" untuk menogol terbang" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Jatuhkan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Ke Depan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Naikkan jarak" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Kuatkan bunyi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventori" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Lompat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Kekunci telah digunakan untuk fungsi lain" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "Ikatan kekunci." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Perintah tempatan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Bisu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Item seterusnya" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Item sebelumnya" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Jarak Pemilihan" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Tangkap layar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Selinap" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Togol papar pandu (HUD)" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Togol log sembang" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Togol pergerakan pantas" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Togol Terbang" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Togol kabut" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Togol peta mini" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Togol tembus blok" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Togol pergerakan mencuram" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "tekan kekunci" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Tukar" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Kata Laluan Baru" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Kata Laluan Lama" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Kata laluan tidak padan!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Keluar" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Dibisukan" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Kekuatan Bunyi: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "ms" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" +"Nama belum berdaftar. Untuk mencipta akaun di pelayan ini, klik 'Daftar'" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "Nama sudah diambil. Sila pilih nama yang lain" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Menetapkan kedudukan kayu bedik maya.\n" +"Jika dilumpuhkan, kedudukan tengah untuk kayu bedik maya akan ditentukan " +"berdasarkan kedudukan sentuhan pertama." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Guna kayu bedik maya untuk picu butang \"Aux1\".\n" +"Jika dibolehkan, kayu bedik maya juga akan menekan butang \"Aux1\" apabila " +"berada di luar bulatan utama." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) Ofset fraktal dari pusat dunia dalam unit 'skala'.\n" +"Boleh guna untuk pindahkan titik yang diingini ke (0, 0)\n" +"untuk cipta titik jelma yang sesuai, atau untuk\n" +"membolehkan 'zum masuk' pada titik yang diinginkan\n" +"dengan menaikkan 'skala'.\n" +"Nilai lalai disesuaikan untuk titik jelma sesuai untuk set Mandelbrot\n" +"dengan parameter lalai, ia mungkin perlu diubah untuk situasi yang lain.\n" +"Julat kasarnya -2 sehingga 2. Darabkan dengan 'skala' untuk ofset dalam nod." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"Skala (X,Y,Z) fraktal dalam nod.\n" +"Saiz fraktal sebenar akan menjadi 2 hingga 3 kali lebih besar.\n" +"Nombor ini boleh dibuat terlebih besar, fraktal tidak semestinya\n" +"muat di dalam dunia.\n" +"Naikkan nilai ini untuk 'zum' perincian fraktal.\n" +"Nilai asal ialah untuk bentuk penyek menegak sesuai untuk pulau,\n" +"tetapkan kesemua 3 nombor yang sama untuk bentuk mentah." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Hingar 2D yang mengawal bentuk/saiz gunung rabung." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Hingar 2D yang mengawal bentuk/saiz bukit." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Hingar 2D yang mengawal bentuk/saiz gunung curam." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "Hingar 2D yang mengawal saiz/kejadian gunung rabung berjarak." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "Hingar 2D yang mengawal saiz/kejadian bukit." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "Hingar 2D yang mengawal saiz/kejadian gunung curam berjarak." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Hingar 2D yang menentukan peletakan lembah dan arus sungai." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Awan 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Mod 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Kekuatan paralaks mod 3D" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Hingar 3D mentakrifkan gua gergasi." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Hingar 3D yang mentakrifkan struktur gunung dan ketinggiannya.\n" +"Ia juga mentakrifkan struktur rupa bumi gunung tanah terapung." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Hingar 3D mentakrifkan struktur tanah terapung.\n" +"Jika diubah dari nilai asal, hingar skala 'scale' (asalnya 0.7) mungkin\n" +"perlu dilaraskan, kerana tirusan tanah terapung berfungsi dengan\n" +"terbaik apabila jarak nilai berada dalam lingkungan -2.0 ke 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Hingar 3D mentakrifkan struktur dinding ngarai sungai." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Hingar 3D mentakrifkan rupa bumi." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "Hingar 3D untuk unjuran, cenuram gunung, dll. Selalunya variasi kecil." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" +"Hingar 3D yang menentukan jumlah kurungan bawah tanah per ketulan peta." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Sokongan 3D.\n" +"Yang disokong pada masa ini:\n" +"- none (tiada): untuk tiada output 3D.\n" +"- anaglyph (anaglif): 3D warna biru/merah.\n" +"- interlaced (selang-seli): garis genap/ganjil berdasarkan sokongan skrin " +"polarisasi.\n" +"- topbottom (atas-bawah): pisah skrin atas/bawah.\n" +"- sidebyside (kiri-kanan): pisah skrin kiri/kanan.\n" +"- crossview (silang lihat): 3D mata bersilang\n" +"- pageflip (selak halaman): 3D berasaskan penimbal kuad.\n" +"Ambil perhatian bahawa mod selang-seli memerlukan pembayang." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "3d" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Benih peta yang dipilih untuk peta baru, biarkan kosong untuk benih rawak.\n" +"Tidak digunapakai sekiranya mencipta dunia baru melalui menu utama." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Mesej yang akan dipaparkan kepada semua klien apabila pelayan runtuh." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Mesej yang akan dipaparkan dekat semua klien apabila pelayan ditutup." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Selang masa ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Peruntukan masa ABM" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Had mutlak untuk blok menunggu giliran untuk timbul" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Pecutan di udara" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Pecutan graviti, dalam unit nod per saat per saat." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Pengubah Blok Aktif" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Selang masa pengurusan blok aktif" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Jarak blok aktif" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Jarak penghantaran objek aktif" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Alamat untuk menyambung.\n" +"Biar kosong untuk memulakan pelayan tempatan.\n" +"Ambil perhatian bahawa medan alamat dalam menu utama mengatasi tetapan ini." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Menambah partikel apabila menggali nod." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Laraskan konfigurasi DPI ke skrin anda (bukan X11/Android sahaja) cth. untuk " +"skrin 4K." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Laraskan ketumpatan paparan yang dikesan, digunakan untuk menyesuaikan " +"elemen UI." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Melaraskan ketumpatan lapisan tanah terapung.\n" +"Tambah nilai untuk tambah ketumpatan. Boleh jadi positif atau negatif.\n" +"Nilai = 0.0: 50% daripada jilid merupakan tanah terapung.\n" +"Nilai = 2.0 mencipta lapisan tanah terapung yang pejal (boleh jadi lebih " +"tinggi\n" +"bergantung kepada tetapan 'mgv7_np_floatland', sentiasa cuba untuk pastikan)." + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "Nama pentadbir" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Tetapan mendalam" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Ubah lengkung cahaya dengan mengenakan 'pembetulan gama'.\n" +"Nilai tinggi buatkan aras cahaya tengah dan rendah lebih terang.\n" +"Nilai '1.0' akan biarkan lengkung cahaya asal tidak berubah.\n" +"Tetapan ini hanya memberi kesan mendalam pada cahaya matahari\n" +"dan cahaya buatan, kesannya pada cahaya malam amat rendah." + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "Sentiasa terbang pantas" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Gama oklusi sekitar" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Jumlah mesej pemain boleh hantar setiap 10 saat." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Memperbesarkan lembah." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Penapisan anisotropik" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Umumkan pelayan" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Umumkan ke senarai pelayan ini." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Tambah nama item" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Tambah nama item ke tip alatan." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Hingar pokok epal" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Inersia lengan" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Inersia lengan, memberikan pergerakan lengan yang\n" +"lebih realistik apabila kamera digerakkan." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Minta sambung semula selepas keruntuhan" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"Pada jarak ini, pelayan akan mengoptimumkan secara agresif blok yang mana\n" +"akan dihantar kepada klien.\n" +"Nilai lebih kecil berkemungkinan boleh meningkatkan prestasi dengan banyak,\n" +"dengan mengorbankan glic kemas gabung tampak (sesetengah blok tidak akan\n" +"dikemas gabung di bawah air dan dalam gua, kekadang turut berlaku atas " +"daratan).\n" +"Menetapkan nilai ini lebih besar daripada nilai max_block_send_distance " +"akan\n" +"melumpuhkan pengoptimuman ini.\n" +"Nyatakan dalam unit blokpeta (16 nod)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "Audio" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Kekunci autopergerakan" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Lompat halangan satu-nod secara automatik." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Melaporkan kepada senarai pelayan secara automatik." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Autosimpan saiz skrin" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Mod skala automatik" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Kekunci Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Kekunci Aux1 untuk memanjat/menurun" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Kekunci ke belakang" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Aras tanah asas" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Ketinggian rupa bumi asas." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Keistimewaan asas" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Hingar pantai" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Nilai ambang hingar pantai" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Penapisan bilinear" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Alamat ikatan" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "Parameter hingar API biom" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Hingar biom" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Jarak optimum penghantaran blok" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "Apungan" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Laluan fon tebal dan italik" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Laluan fon monospace tebal dan italik" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Laluan fon tebal" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Laluan fon monospace tebal" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Bina dalam pemain" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Terbina dalam" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "Kamera" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Jarak kamera 'berhampiran satah ketipan' dalam nilai nod, antara 0 dan 0.5.\n" +"Hanya berkesan di platform GLES. Kebanyakan pengguna tidak perlu mengubah " +"nilai ini.\n" +"Menaikkan nilai boleh kurangkan artifak pada GPU yang lebih lemah.\n" +"0.1 = Asal, 0.25 = Nilai bagus untuk tablet yang lebih lemah." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Pelembutan kamera" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Pelembutan kamera dalam mod sinematik" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Kekunci togol kemas kini kamera" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Hingar gua" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Hingar gua #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Hingar gua #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Lebar gua" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Hingar gua1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Hingar gua2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Had jana gua" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Hingar gua" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Tirusan gua" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Nilai ambang gua" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Had atas jana gua" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Pertengahan julat tolakan lengkung cahaya.\n" +"Di mana 0.0 ialah aras cahaya minimum, 1.0 ialah maksimum." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Nilai ambang mesej masa perintah sembang" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Perintah sembang" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Saiz fon sembang" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Kekunci sembang" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Tahap log sembang" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Had kiraan mesej sembang" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Format mesej sembang" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Nilai ambang tendang mesej sembang" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Panjang maksimum mesej sembang" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Kekunci togol sembang" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Pautan sesawang sembang" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Saiz ketulan" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Mod sinematik" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Kekunci mod sinematik" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Bersihkan tekstur lut sinar" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Pautan sesawang boleh klik (klik-tengah atau Ctrl+klik-kiri) dibolehkan " +"dalam output konsol sembang." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Klien" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Klien dan Pelayan" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Mods klien" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Sekatan mods pihak klien" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Sekatan jarak carian nod pihak klien" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "Mods Pihak Klien" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Kelajuan memanjat" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Jejari awan" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Awan" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Awan itu efek pada pihak klien." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Awan dalam menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Kabut berwarna" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Bayang berwarna" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Senarai bendera yang ingin disembunyikan dalam repositori kandungan " +"dipisahkan dengan koma.\n" +"\"nonfree\" boleh digunakan untuk menyembunyikan pakej yang tidak layak " +"digelar 'perisian bebas',\n" +"seperti ditakrifkan oleh Yayasan Perisian Bebas (Free Software Foundation).\n" +"Anda juga boleh menyatakan klasifikasi kandungan.\n" +"Bendera-bendera ini tidak bersangkut paut dengan versi Minetest tertentu,\n" +"jadi anda boleh lihat senarai penuh di https://content.minetest.net/help/" +"content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Senarai mods yang dibenarkan mencapai API HTTP dipisahkan dengan koma,\n" +"ini membolehkan mereka memuat naik kepada atau muat turun daripada internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Senarai dipisahkan dengan koma untuk mods boleh dipercayai yang dibenarkan " +"mencapai fungsi\n" +"tidak selamat walaupun ketika keselamatan mods diaktifkan (melalui " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Kekunci perintah" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Tahap pemampatan untuk digunakan apabila menyimpan blokpeta ke cakera.\n" +"-1 - guna tahap pemampatan lalai\n" +"0 - pemampatan paling sedikit, paling laju\n" +"9 - pemampatan paling banyak, paling lambat" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Tahap pemampatan untuk digunakan apabila menghantar blokpeta kepada klien.\n" +"-1 - guna tahap pemampatan lalai\n" +"0 - pemampatan paling sedikit, paling laju\n" +"9 - pemampatan paling banyak, paling lambat" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Sambung kaca" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Sambung ke pelayan media luaran" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Sambungkan kaca jika disokong oleh nod." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Nilai alfa konsol" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Warna konsol" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Ketinggian konsol" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "Repositori Kandungan" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Senarai Hitam Bendera ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Muat Turun Serempak Maksimum ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "URL ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Ke depan berterusan" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Pergerakan ke depan berterusan, ditogol oleh kekunci autopergerakan.\n" +"Tekan kekunci autopergerakan lagi atau pergerakan ke belakang untuk " +"melumpuhkannya." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Kawalan" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Mengawal panjang kitaran siang/malam.\n" +"Contohnya:\n" +"72 = 20 minit, 360 = 4 minit, 1 = 24 jam, 0 = siang/malam/lain-lain kekal " +"tidak berubah." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" +"Mengawal kelajuan tenggelam dalam cecair ketika tidak berbuat apa-apa.\n" +"Nilai negatif akan menyebabkan anda timbul." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Mengawal kecuraman/kedalaman tekanan rendah tasik." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Mengawal kecuraman/ketinggian bukit." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Mengawal lebar terowong, nilai kecil mencipta terowong lebih luas.\n" +"Nilai >= 10.0 melumpuhkan penjanaan terowong dan mengelakkan\n" +"pengiraan hingar yang terlalu banyak." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Mesej keruntuhan" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Kreatif" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Nilai alfa rerambut silang" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Nilai alfa rerambut silang (kelegapan, antara 0 dan 255).\n" +"Nilai ini juga memberi kesan kepada rerambut silang objek." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Warna rerambut silang" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Warna rerambut silang (R,G,B).\n" +"Juga mengawal warna rerambut silang objek" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Boleh cedera" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Kekunci togol maklumat nyahpepijat" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Nilai ambang saiz fail log nyahpepijat" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Tahap log nyahpepijat" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "Nyahpepijat" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Kekunci perlahankan bunyi" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Langkah pelayan khusus" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Pecutan lalai" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Permainan lalai" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Permainan lalai yang akan digunakan ketika mencipta dunia baru.\n" +"Tetapan ini akan diatasi apabila membuat dunia dari menu utama." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Kata laluan lalai" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Keistimewaan lalai" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Format laporan lalai" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Saiz tindanan lalai" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Mentakrifkan kualiti penapisan bayang.\n" +"Tetapan ini menyelakukan kesan bayang lembut dengan menggunakan\n" +"PCF atau cakera Poisson tetapi turut menggunakan lebih banyak sumber." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Mentakrifkan kawasan di mana pokok mempunyai epal." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Mentakrifkan kawasan dengan pantai berpasir." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Mentakrifkan taburan rupa bumi lebih tinggi dan kecuraman cenuram." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Mentakrifkan taburan rupa bumi lebih tinggi." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Mentakrifkan saiz penuh gua, nilai lebih kecil mencipta gua lebih besar." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Mentakrifkan struktur saluran sungai berskala besar." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Mentakrifkan kedudukan dan rupa bumi bukit dan tasik pilihan." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Mentakrifkan aras tanah asas." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Mentakrifkan kedalaman saliran sungai." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Mentakrifkan jarak maksimum untuk pemindahan pemain dalam unit blok (0 = " +"tiada had)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Mentakrifkan lebar saluran sungai." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Mentakrifkan lebar lembah sungai." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Mentakrifkan kawasan pokok dan ketumpatan pokok." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Lengah masa di antara kemaskini jejaring dekat klien dalam unit ms. " +"Menaikkan nilai ini akan\n" +"mengurangkan kadar kemaskini jejaring, lalu mengurangkan ketaran dekat klien " +"yang lebih perlahan." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Lengah penghantaran blok selepas pembinaan" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Jumlah lengah untuk menunjukkan tip alatan, dinyatakan dalam milisaat." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Pengendalian API Lua terkecam" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Kedalaman di mana anda akan mula jumpa gua besar." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Kedalaman di mana anda akan mula jumpa gua besar." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Perihal pelayan, untuk dipaparkan apabila pemain masuk dan juga dalam " +"senarai pelayan." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Nilai ambang hingar gurun" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Gurun akan dijana apabila np_biome melebihi nilai ini.\n" +"Apabila bendera 'snowbiomes' dibolehkan, tetapan ini diabaikan." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Menyahsegerakkan animasi blok" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "Pilihan Pembangun" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Kekunci gali" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Partikel ketika menggali" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Melumpuhkan antitipu" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Menolak kata laluan kosong" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Faktor Skala Ketumpatan Paparan" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" +"Jarak dalam nod ketika mana pengisihan kedalaman lut sinar dibolehkan\n" +"Gunakan ini untuk mengehadkan hentaman prestasi akibat pengisihan kedalaman " +"lut sinar" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Nama domain pelayan, untuk dipaparkan dalam senarai pelayan." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Tekan \"lompat\" dua kali untuk terbang" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" +"Tekan butang \"lompat\" secara cepat dua kali untuk menogol mod terbang." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Kekunci jatuhkan item" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Longgokkan maklumat nyahpepijat janapeta." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Y maksimum kurungan bawah tanah" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Y minimum kurungan bawah tanah" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Hingar kurungan bawah tanah" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Membolehkan sokongan IPv6 (untuk kedua-dua klien dan pelayan).\n" +"Diperlukan sekiranya ingin menggunakan sambungan IPv6." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Membolehkan sokongan pembuatan mods Lua dekat klien.\n" +"Sokongan ini dalam uji kaji dan API boleh berubah." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Membolehkan penapisan cakera Poisson.\n" +"Jika dibenarkan, gunakan cakera Poisson untuk membuat \"bayang lembut\". " +"Jika tidak, gunakan penapisan PCF." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Membolehkan bayang berwarna. \n" +"Jika dibenarkan, nod lut cahaya mengeluarkan bayang berwarna. Fungsi ini " +"sangat berat." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Membolehkan tetingkap konsol" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Membolehkan mod kreatif untuk semua pemain" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Membolehkan kayu bedik" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "Membolehkan kayu bedik. Perlu dimulakan semula untuk mengambil kesan" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Membolehkan sokongan saluran mods." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Membolehkan keselamatan mods" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Membolehkan pemain menerima kecederaan dan mati." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Membolehkan input pengguna secara rawak (hanya untuk percubaan)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Membolehkan pencahayaan lembut dengan oklusi sekitar yang ringkas.\n" +"Lumpuhkannya untuk kelajuan atau untuk kelihatan berlainan." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "Membolehkan pemisahan log masuk/daftar" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Bolehkan tetapan untuk melarang klien lama daripada menyambung.\n" +"Klien lama masih sesuai digunakan jika mereka tidak runtuh (crash) apabila " +"cuba untuk menyambung ke pelayan baharu,\n" +"tetapi mereka mungkin tidak mampu menyokong semua sifat baharu yang anda " +"sangkakan." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Membolehkan penggunaan pelayan media jarak jauh (jika diberikan oleh " +"pelayan).\n" +"Pelayan jarak jauh menawarkan cara lebih cepat untuk muat turun media (cth. " +"tekstur)\n" +"apabila menyambung ke pelayan permainan." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Membolehkan objek penimbal bucu.\n" +"Ia patut meningkatkan prestasi grafik dengan banyak." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Pendarab untuk pengapungan pandangan.\n" +"Contohnya: 0 untuk tiada apungan; 1.0 untuk biasa; 2.0 untuk dua kali ganda." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Membolehkan/melumpuhkan penjalanan pelayan IPv6.\n" +"Diabaikan jika tetapan bind_address ditetapkan.\n" +"Memerlukan tetapan enable_ipv6 dibolehkan." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Membolehkan pemetaan tona sinematik 'Uncharted 2' oleh Hable.\n" +"Menyelakukan lengkung tona filem fotografi dan cara ia menganggarkan\n" +"penampilan imej jarak dinamik tinggi. Beza jelas pertengahan julat\n" +"ditingkatkan sedikit, tonjolan dan bayangan dimampatkan secara beransur." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Membolehkan animasi item dalam inventori." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Membolehkan pengagregatan jejaring yang diputar di paksi Y (facedir)." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Membolehkan peta mini." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Membolehkan sistem bunyi.\n" +"Jika dilumpuhkan, ia akan melumpuhkan kesemua bunyi di semua tempat\n" +"dan kawalan bunyi dalam permainan tidak akan berfungsi.\n" +"Pengubahan tetapan ini memerlukan permulaan semula." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Membolehkan keseimbangan yang mengurangkan muatan CPU atau meningkatkan " +"prestasi kemas gabung\n" +"dengan mengorbankan glic visual yang kecil yang tidak memberi kesan kepada " +"kebolehan bermain permainan." + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "Pembukah enjin" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Selang masa cetak data pemprofilan enjin" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Kaedah entiti" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Eksponen penirusan tanah terapung. Mengubah tingkah laku tirusan.\n" +"Nilai = 1.0 mencipta tirusan sekata, lelurus.\n" +"Nilai > 1.0 mencipta tirusan lembut sesuai untuk tanah terapung asal\n" +"yang terpisah antara satu sama lain.\n" +"Nilai < 1.0 (contohnya 0.25) mencipta aras permukaan lebih jelas dengan\n" +"bahagian tanah yang lebih rata, sesuai untuk lapisan tanah terapung pejal." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "FPS" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "Bingkai per saat (FPS) apabila permainan hilang fokus atau dijedakan" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Hingar faktor" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Faktor apungan kejatuhan" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Laluan fon berbalik" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Kekunci pergerakan pantas" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Pecutan mod pergerakan pantas" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Kelajuan mod pergerakan pantas" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Pergerakan pantas" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Bergerak pantas (dengan kekunci \"Aux1\").\n" +"Ini memerlukan keistimewaan \"pergerakan pantas\" di pelayan tersebut." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Medan pandang" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Medan pandang dalam darjah sudut." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Fail dalam laluan client/serverlist/ yang mengandungi senarai\n" +"pelayan kegemaran yang dipaparkan dalam Tab Pemain Ramai." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Kedalaman pengisi" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Hingar kedalaman pengisi" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Pemetaan tona sinematik" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Tekstur yang ditapis boleh sebatikan nilai RGB dengan jiran yang lut sinar " +"sepenuhnya,\n" +"yang mana pengoptimum PNG sering abaikan, kadangkala menyebabkan sisi gelap " +"atau\n" +"terang pada tekstur lut sinar. Guna penapisan ini untuk membersihkan tekstur " +"tersebut\n" +"ketika ia sedang dimuatkan. Ini dibolehkan secara automatik jika pemetaan " +"mip dibolehkan." + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "Tapisan dan Antialias" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Hingar 2D pertama daripada empat yang mentakrifkan ketinggian bukit/gunung." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Hingar 3D pertama daripada dua yang mentakrifkan terowong." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Benih peta tetap" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Kayu bedik maya tetap" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Ketumpatan tanah terapung" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Y maksimum tanah terapung" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Y minimum tanah terapung" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Hingar tanah terapung" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Eksponen tirusan tanah terapung" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Jarak tirusan tanah terapung" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Aras air tanah terapung" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Kekunci terbang" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Terbang" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Kabut" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Mula Kabut" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Kekunci togol kabut" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "Fon" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Fon tebal secara lalainya" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Fon italik secara lalainya" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Bayang fon" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Nilai alfa bayang fon" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Saiz fon" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Saiz fon boleh dibahagikan dengan" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Saiz fon bagi fon lalai di mana 1 unit = 1 piksel pada 96 DPI" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Saiz fon bagi fon monospace di mana 1 unit = 1 piksel pada 96 DPI" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Saiz fon tulisan sembang baru-baru ini dan prom dalam unit titik (pt).\n" +"Nilai 0 akan menggunakan saiz fon lalai." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"Untuk fon gaya piksel yang tidak boleh disesuaikan dengan baik, tetapan ini " +"memastikan saiz fon\n" +"yang digunakan dengan fon ini akan sentiasa boleh dibahagikan dengan nilai " +"ini, dalam piksel.\n" +"Contohnya, sebuah fon piksel dengan tinggi 16 piksel patut tetapkan tetapan " +"ini menjadi 16, supaya\n" +"ia hanya guna saiz 16, 32, 48, dll., jadi jika mods meminta fon bersaiz 25 " +"maka ia akan dapat saiz 32." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Format mesej sembang pemain. Rentetan berikut ialah pemegang tempat yang " +"sah:\n" +"@name (untuk nama), @message (untuk mesej), @timestamp (pilihan, untuk cop " +"masa)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Format yang digunakan untuk tangkap layar." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Warna Latar Belakang Lalai Formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Kelegapan Latar Belakang Lalai Formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Warna Latar Belakang Skrin-Penuh Formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Kelegapan Latar Belakang Skrin-Penuh Formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Warna latar belakang asal formspec (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Kelegapan asal latar belakang formspec (antara 0 dan 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Warna latar belakang skrin-penuh formspec (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "Kelegapan latar belakang skrin-penuh formspec (antara 0 dan 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Kekunci ke depan" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Hingar 2D keempat daripada empat yang mentakrifkan ketinggian jarak bukit/" +"gunung." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Jenis fraktal" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Bahagian daripada jarak boleh lihat di mana kabut mula dikemas gabung" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Sejauh manakah blok akan dijana untuk klien, dinyatakan dalam unit blokpeta " +"(16 nod)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Sejauh manakah blok-blok dihantar kepada klien, dinyatakan dalam unit " +"blokpeta (16 nod)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Daripada jarak klien dapat tahu tentang objek, dinyatakan dalam blokpeta (16 " +"nod).\n" +"\n" +"Menetapkan nilai ini lebih tinggi daripada jarak blok aktif " +"(active_block_range) juga\n" +"akan menyebabkan pelayan untuk mengekalkan objek aktif sehingga ke jarak " +"ini\n" +"dalam arah pandangan pemain. (Ini boleh elakkan mob tiba-tiba hilang dari " +"pandangan)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Skrin penuh" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Mod skrin penuh." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Skala GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Penapis skala GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Penapis skala GUI txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "GUI" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "Pad permainan" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "Umum" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Panggil balik sejagat" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Atribut penjanaan peta sejagat.\n" +"Dalam Janapeta v6, bendera 'decorations' mengawal semua hiasan kecuali " +"pokok\n" +"dan rumput hutan, dalam janapeta lain pula bendera ini mengawal semua hiasan." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Kecerunan lengkung cahaya pada tahap cahaya maksimum.\n" +"Mengawal beza jelas tahap cahaya tertinggi." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Kecerunan lengkung cahaya pada tahap cahaya minimum.\n" +"Mengawal beza jelas tahap cahaya terendah." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafik" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "Kesan Grafik" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "Grafik dan Audio" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Graviti" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Aras laut" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Hingar tanah" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "Mods HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "Papar Pandu (HUD)" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "Skala papar pandu (HUD)" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Kekunci menogol papar pandu (HUD)" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Cara pengendalian panggilan API Lua yang terkecam:\n" +"- none: Jangan log panggilan terkecam\n" +"- log: meniru dan menulis log runut balik bagi panggilan terkecam " +"(lalai).\n" +"- error: gugurkan penggunaan panggilan terkecam (digalakkan untuk " +"pembangun mods)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Membuatkan pembukah memasang diri sendiri:\n" +"* Memasang sebuah fungsi kosong.\n" +"Ini menganggarkan overhed, bahawa pemasangan ditambah (+1 panggilan " +"fungsi).\n" +"* Memasang pensampel yang digunakan untuk mengemaskini statistik." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Hingar penyebatian haba" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Hingar haba" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "Komponen tinggi saiz tetingkap awal. Diabaikan dalam mod skrin penuh." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Hingar ketinggian" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Hingar pilihan ketinggian" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Kecuraman bukit" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Nilai ambang bukit" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Hingar kebukitan1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Hingar kebukitan2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Hingar kebukitan3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Hingar kebukitan4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Laman utama pelayan, untuk dipaparkan dalam senarai pelayan." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Pecutan mendatar di udara apabila melompat atau jatuh,\n" +"dalam unit nod per saat per saat." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Pecutan mendatar dan menegak dalam mod pantas,\n" +"dalam unit nod per saat per saat." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Pecutan mendatar dan menegak atas tanah atau ketika memanjat,\n" +"dalam unit nod per saat per saat." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Kekunci item seterusnya dalam hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Kekunci item sebelumnya dalam hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Kekunci slot hotbar 1" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Kekunci slot hotbar 10" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Kekunci slot hotbar 11" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Kekunci slot hotbar 12" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Kekunci slot hotbar 13" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Kekunci slot hotbar 14" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Kekunci slot hotbar 15" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Kekunci slot hotbar 16" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Kekunci slot hotbar 17" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Kekunci slot hotbar 18" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Kekunci slot hotbar 19" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Kekunci slot hotbar 2" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Kekunci slot hotbar 20" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Kekunci slot hotbar 21" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Kekunci slot hotbar 22" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Kekunci slot hotbar 23" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Kekunci slot hotbar 24" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Kekunci slot hotbar 25" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Kekunci slot hotbar 26" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Kekunci slot hotbar 27" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Kekunci slot hotbar 28" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Kekunci slot hotbar 29" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Kekunci slot hotbar 3" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Kekunci slot hotbar 30" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Kekunci slot hotbar 31" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Kekunci slot hotbar 32" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Kekunci slot hotbar 4" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Kekunci slot hotbar 5" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Kekunci slot hotbar 6" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Kekunci slot hotbar 7" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Kekunci slot hotbar 8" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Kekunci slot hotbar 9" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Kedalaman pembuatan sungai." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Secepat mana gelora cecair akan bergerak. Nilai tinggi = lebih cepat.\n" +"Jika nilai negatif, gelora cecair akan bergerak ke belakang.\n" +"Memerlukan tetapan cecair bergelora dibolehkan." + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Berapa lama pelayan akan tunggu sebelum menyahmuat blokpeta yang tidak " +"digunakan, dinyatakan dalam saat.\n" +"Nilai lebih tinggi lebih lembut, tetapi akan menggunakan lebih banyak RAM." + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" +"Berapa banyak anda diperlahankan ketika bergerak di dalam cecair.\n" +"Kurangkan nilai untuk meningkatkan rintangan cecair terhadap pergerakan." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Keluasan pembuatan sungai." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Hingar penyebatian kelembapan" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Hingar kelembapan" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Variasi kelembapan untuk biom." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "Pelayan IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Jika bingkai per saat (FPS) akan naik lebih tinggi daripada nilai ini, " +"hadkan ia dengan\n" +"tidurkannya supaya tidak bazirkan kuasa CPU dengan sia-sia." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Jika dilumpuhkan, kekunci \"Aux1\" akan digunakan untuk terbang laju\n" +"sekiranya kedua-dua mod terbang dan mod pergerakan pantas dibolehkan." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Jika dibolehkan, pelayan akan membuat penakaian oklusi blok peta\n" +"berdasarkan kedudukan mata pemain. Ini boleh mengurangkan jumlah\n" +"blok dihantar kepada klien sebanyak 50-80%. Klien sudah tidak menerima\n" +"kebanyakan blok tak kelihatan supaya utiliti mod tembus blok dikurangkan." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Jika dibolehkan bersama mod terbang, pemain boleh terbang menerusi nod " +"pepejal.\n" +"Ini memerlukan keistimewaan \"tembus blok\" dalam pelayan tersebut." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Jika dibolehkan, kekunci \"Aux1\" akan digunakan untuk panjat ke bawah dan\n" +"turun dalam mod terbang, menggantikan kekunci \"Selinap\"." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Jika dibolehkan, pendaftaran akaun dipisahkan dari log masuk dalam UI.\n" +"Jika dilumpuhkan, akaun baharu akan didaftarkan secara automatik ketika log " +"masuk." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Jika dibolehkan, semua tindakan akan dirakam untuk gulung balik.\n" +"Pilihan ini hanya dibaca ketika pelayan bermula." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" +"Jika dibolehkan, ia akan melumpuhkan pencegahan penipuan dalam pemain ramai." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Jika dibolehkan, data dunia tidak sah tidak akan menyebabkan pelayan " +"ditutup.\n" +"Hanya bolehkan tetapan ini jika anda tahu apa yang anda lakukan." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Jika dibolehkan, ia membuatkan arah pergerakan relatif dengan pic pemain " +"apabila terbang atau berenang." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Jika dibolehkan, pemain tidak boleh sertai tanpa kata laluan atau tukar " +"kepada kata laluan yang kosong." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Jika dibolehkan, anda boleh meletak blok di kedudukan berdiri (kaki + aras " +"mata).\n" +"Ini sangat berguna apabila bekerja dengan kotak nod di kawasan yang kecil." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Jika sekatan CSM untuk jarak nod dibolehkan, panggulan get_node akan\n" +"dihadkan ke jarak ini daripada pemain kepada nod." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Jika pelaksanaan sesuatu perintah sembang mengambil masa lebih lama daripada " +"yang\n" +"dinyatakan di sini dalam unit saat, tambah maklumat masa ke mesej perintah " +"sembang" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Jika saiz fail debug.txt melebihi jumlah megabait yang dinyatakan dalam\n" +"tetapan ini ketika ia dibuka, fail ini akan dipindahkan ke debug.txt.1,\n" +"memadamkan fail debug.txt.1 yang lama jika wujud.\n" +"debug.txt hanya akan dipindahkan sekiranya tetapan ini positif." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" +"Jika tetapan ini ditetapkan, pemain akan sentiasa jelma (semula) dekat " +"kedudukan yang diberikan." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Abaikan ralat dunia" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Nilai alfa latar belakang konsol sembang dalam permainan (kelegapan, antara " +"0 dan 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Warna latar belakang konsol sembang dalam permainan (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"Nilai ketinggian konsol sembang dalam permainan, antara 0.1 (10%) dan 1.0 " +"(100%)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Kekunci kuatkan bunyi" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Kelajuan menegak awal ketika melompat, dalam unit nod per saat." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Alatan terbina dalam.\n" +"Ini selalunya hanya diperlukan oleh penyumbang teras/terbina dalam" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "Memasang perintah sembang ketika pendaftaran." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Memasang fungsi panggil balik sejagat ketika pendaftaran.\n" +"(semua benda yang anda salurkan kepada fungsi minetest.register_*())" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "Memasang fungsi perbuatan Pengubah Blok Aktif ketika pendaftaran." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "Memasang fungsi perbuatan Pengubah Blok Pemuatan ketika pendaftaran." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Memasang kaedah entiti ketika pendaftaran." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Selang masa di antara penyimpanan perubahan penting dalam dunia, dinyatakan " +"dalam unit saat." + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" +"Selang di antara penghantaran maklumat waktu dalam hari kepada klien, " +"dinyatakan dalam saat." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animasi item inventori" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Kekunci inventori" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Tetikus songsang" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Menyongsangkan pergerakan tetikus menegak." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Laluan fon italik" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Laluan fon monospace italik" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "TTL entiti item" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Lelaran" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Lelaran fungsi rekursif.\n" +"Menaikkan nilai ini meningkatkan jumlah perincian halus, tetapi turut\n" +"meningkatkan muatan pemprosesan.\n" +"Pada lelaran = 20 janapeta ini mempunyai muatan sama dengan janapeta V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID Kayu Bedik" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Selang masa pengulangan butang kayu bedik" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "Zon mati kayu bedik" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Kepekaan frustum kayu bedik" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Jenis kayu bedik" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Set Julia sahaja.\n" +"Komponen W buat pemalar hiperkompleks.\n" +"Mengubah bentuk fraktal.\n" +"Tiada kesan terhadap fraktal 3D.\n" +"Julat kasarnya -2 hingga 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Set Julia sahaja.\n" +"Komponen X buat pemalar hiperkompleks.\n" +"Mengubah bentuk fraktal.\n" +"Julat kasarnya -2 hingga 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Set Julia sahaja.\n" +"Komponen Y buat pemalar hiperkompleks.\n" +"Mengubah bentuk fraktal.\n" +"Julat kasarnya -2 hingga 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Set Julia sahaja.\n" +"Komponen Z buat pemalar hiperkompleks.\n" +"Mengubah bentuk fraktal.\n" +"Julat kasarnya -2 hingga 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "W Julia" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "X Julia" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Y Julia" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Z Julia" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Kekunci lompat" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Kelajuan melompat" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk mengurangkan jarak pandang.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memperlahankan bunyi.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menggali.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menjatuhkan item yang sedang dipilih.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menambah jarak pandang.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menguatkan bunyi.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk melompat.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk bergerak pantas dalam mod pergerakan pantas.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menggerakkan pemain ke belakang.\n" +"Juga akan melumpuhkan autopergerakan, apabila aktif.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menggerakkan pemain ke depan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menggerakkan pemain ke kiri.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menggerakkan pemain ke kanan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk membisukan permainan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk membuka tetingkap sembang untuk menaip perintah.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk membuka tetingkap sembang untuk menaip perintah tempatan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk membuka tetingkap sembang.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk membuka inventori.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk meletak.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-11 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-12 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-13 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-14 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-15 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-16 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-17 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-18 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-19 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-20 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-21 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-22 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-23 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-24 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-25 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-26 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-27 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-28 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-29 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-30 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-31 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-32 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-8 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-5 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot pertama dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-4 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih item seterusnya di dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-9 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih item sebelumnya di dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-2 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-7 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-6 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-10 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk memilih slot ke-3 dalam hotbar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menyelinap.\n" +"Juga digunakan untuk turun bawah ketika memanjat dan dalam air jika tetapan " +"aux1_descends dilumpuhkan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk bertukar antara kamera orang pertama dan ketiga.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menangkap gambar layar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol autopergerakan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol mod sinematik.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol paparan peta mini.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol mod pergerakan pantas.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol mod terbang.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol mod tembus blok.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol mod pergerakan pic.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol pengemaskinian kamera. Hanya digunakan untuk " +"pembangunan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol paparan sembang.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol paparan maklumat nyahpepijat.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol paparan kabut.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol papar pandu (HUD).\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol paparan konsol sembang besar.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol paparan pembukah. Digunakan untuk pembangunan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menogol jarak pandangan tiada had.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kekunci untuk menggunakan pandangan zum apabila dibenarkan.\n" +"Lihat http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "Papan Kekunci dan Tetikus" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "Tendang pemain yang menghantar mesej lebih daripada X setiap 10 saat." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Kecuraman tasik" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Nilai ambang tasik" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Bahasa" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Kedalaman gua besar" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Jumlah maksimum gua besar" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Jumlah minimum gua besar" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Perkadaran gua besar dibanjiri" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Kekunci konsol sembang besar" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Gaya daun" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Gaya daun:\n" +"- Beragam: semua sisi kelihatan\n" +"- Ringkas: hanya sisi luar kelihatan, jika special_tiles yang ditentukan " +"digunakan\n" +"- Legap: melumpuhkan lut sinar" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Kekunci ke kiri" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Panjang setiap detik pelayan dan selang masa ketika mana objek-objek " +"selalunya\n" +"dikemaskini menerusi rangkaian, dinyatakan dalam saat." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Panjang gelora cecair.\n" +"Memerlukan tetapan cecair bergelora dibolehkan." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" +"Panjang masa di antara kitaran pelaksanaan Pengubah Blok Aktif (ABM), " +"dinyatakan dalam saat." + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" +"Panjang masa di antara kitaran pelaksanaan PemasaNod, dinyatakan dalam saat." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" +"Panjang masa di antara kitaran pengurusan blok aktif, dinyatakan dalam saat." + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Tahap pengelogan untuk ditulis ke fail debug.txt:\n" +"- <tidak ada apa-apa> (tidak mengelog)\n" +"- none: tiada (mesej tanpa tahap)\n" +"- error: ralat\n" +"- warning: amaran\n" +"- action: perbuatan\n" +"- info: maklumat\n" +"- verbose: berjela-jela\n" +"- trace: jejak" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Tolakan lengkung cahaya" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Titik tengah tolakan lengkung cahaya" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Sebaran tolakan lengkung cahaya" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Gama lengkung cahaya" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Kecerunan tinggi lengkung cahaya" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Kecerunan rendah lengkung cahaya" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "Pencahayaan" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Had penjanaan peta dalam unit nod, dalam kesemua 6 arah daripada (0, 0, 0).\n" +"Hanya ketulan peta yang berasa sepenuhnya di dalam had janapeta akan " +"dijana.\n" +"Nilai disimpan pada setiap dunia berbeza." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Mengehadkan jumlah permintaan HTTP selari. Memberi kesan:\n" +"- Ambil media sekiranya pelayan menggunakan tetapan remote_media.\n" +"- Muat turun senarai pelayan dan pengumuman pelayan.\n" +"- Muat turun dilakukan oleh menu utama (cth. pengurus mods).\n" +"Hanya mempunyai kesan sekiranya dikompil dengan pilihan cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Kebendaliran cecair" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Pelembutan kebendaliran cecair" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Jumlah gelung cecair maksimum" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Masa pembersihan giliran cecair" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Tenggelam dalam cecair" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Selamg masa kemas kini cecair dalam unit saat." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Detik kemas kini cecair" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Memuatkan pembukah permainan" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Memuatkan pembukah permainan untuk mengutip data pemprofilan permainan.\n" +"Menyediakan perintah /profiler untuk mencapai profil yang dikompil.\n" +"Berguna untuk pembangun mods dan pengendali pelayan." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Memuatkan Pengubah Blok" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Had Y bawah kurungan bawah tanah." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Had Y bawah tanah terapung." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Skrip menu utama" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Buatkan warna kabut dan langit bergantung kepada waktu (fajar/matahari " +"terbenam) dan arah pandang." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Buatkan semua cecair menjadi legap" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Tahap Pemampatan Peta untuk Simpanan Cakera" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Tahap Pemampatan Peta untuk Pemindahan Rangkaian" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Direktori peta" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Atribut penjanaan peta khusus untuk janapeta Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Atribut penjanaan peta khusus untuk janapeta Flat.\n" +"Kadang-kala tasik dan bukit boleh ditambah ke dunia rata." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Atribut penjanaan peta khusus untuk Janapeta Fractal.\n" +"'terrain' membolehkan penjanaan rupa bumi bukan fraktal:\n" +"lautan, kepulauan dan unsur bawah tanah." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Atribut penjanaan peta khusus untuk janapeta Valleys.\n" +"'altitude_chill': Mengurangkan suhu seiring ketinggian.\n" +"'humid_rivers': Menaikkan kelembapan sekitar sungai.\n" +"'vary_river_depth': Jika dibolehkan, kelembapan rendah dan suhu tinggi\n" +"menyebabkan sungai menjadi cetek dan kadang-kala kering.\n" +"'altitude_dry': Mengurangkan kelembapan seiring ketinggian." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Atribut penjanaan peta khusus untuk janapeta v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Atribut penjanaan peta khusus untuk Janapeta v6.\n" +"Bendera 'snowbiomes' membolehkan sistem 5 biom baharu.\n" +"Apabila bendera 'snowbiomes' dibolehkan, hutan akan dibolehkan secara\n" +"automatik dan bendera 'jungles' diabaikan." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Atribut penjanaan peta khusus untuk Janapeta v7.\n" +"'ridges': Sungai.\n" +"'floatlands': Jisim bumi tanah terapung di atmosfera.\n" +"'caverns': Gua gergasi yang mendalam bawah tanah." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Had penjanaan peta" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Selang masa penyimpanan peta" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "Bingkai kemas kini bayang peta" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Had blok peta" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Lengah masa penjanaan jejaring blok peta" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Saiz cache BlokPeta untuk penjana jejaring blokpeta dalam unit MB" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Had masa nyahmuat blok peta" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Janapeta Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Bendera khusus Janapeta Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Janapeta Flat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Bendera khusus Janapeta Flat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Fraktal Janapeta" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Bendera khusus Janapeta Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Janapeta V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Bendera khusus Janapeta V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Janapeta V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Bendera khusus Janapeta V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Janapeta V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Bendera khusus Janapeta V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Janapeta Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Bendera khusus Janapeta Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Nyahpepijat janapeta" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Nama janapeta" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Jarak penjanaan blok maksimum" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Jarak maksimum penghantaran blok" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Jumlah maksimum bagi cecair yang diproses pada setiap langkah." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Jumlah maksimum blok tambahan bersihobjek" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Bingkisan maksima setiap lelaran" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "FPS maksima" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"Bingkai per saat (FPS) maksimum apabila tetingkap tidak difokuskan, atau " +"apabila permainan dijedakan." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Jarak maksimum untuk mengemas gabung bayang." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Jumlah maksimum blok yang dipaksa muat" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Lebar hotbar maksima" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "Had maksimum jumlah rawak gua besar per ketulan peta." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "Had maksimum jumlah rawak gua kecil per ketulan peta." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Rintangan cecair maksimum. Mengawal nyahpecutan apabila memasuki\n" +"cecair pada kelajuan tinggi." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Jumlah blok maksimum yang dihantar serentak per klien.\n" +"Jumlah maksimum dikira secara dinamik:\n" +"jumlah_maks = bulat_naik((#klien + pengguna_maks) * per_klien / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "Jumlah maksimum blok yang boleh menunggu giliran untuk dimuatkan." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Jumlah maksimum blok untuk menunggu giliran untuk dijana.\n" +"Had ini dikuatkuasakan per pemain." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Jumlah maksimum blok untuk menunggu giliran untuk dimuatkan daripada fail.\n" +"Had ini dikuatkuasakan per pemain." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Jumlah maksimum muat turun serempak. Muat turun melebihi had ini akan " +"ditunggu giliran.\n" +"Ini mestilah lebih rendah dari curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Jumlah maksimum blokpeta yang dipaksa muat." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Jumlah blok peta maksimum yang klien boleh simpan dalam ingatan.\n" +"Tetapkan kepada -1 untuk jumlah tanpa had." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Jumlah maksima bingkisan yang dihantar pada setiap langkah penghantaran,\n" +"jika anda mempunyai sambungan yang perlahan maka cuba kurangkannya,\n" +"namun jangan kurangkan kepada nilai di bawah ganda dua jumlah klien sasaran." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Had jumlah pemain maksimum yang boleh menyambung serentak." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Jumlah maksimum mesej sembang terbaru untuk ditunjukkan" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Jumlah maksimum objek yang disimpan secara statik di dalam blok." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Jumlah maksimum objek setiap blok" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Perkadaran maksima untuk tetingkap semasa yang digunakan untuk hotbar.\n" +"Berguna jika ada sesuatu yang akan dipaparkan di sebelah kanan atau kiri " +"hotbar." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Jumlah blok maksimum yang dihantar serentak kepada setiap klien" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Saiz maksimum baris gilir keluar sembang" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Saiz maksimum baris gilir keluar sembang.\n" +"0 untuk lumpuhkan baris gilir dan -1 untuk buatkan saiz baris gilir tiada " +"had." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Masa maksimum yang dibenarkan untuk muat turun fail (cth. muat turun mods), " +"dalam unit milisaat." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Masa maksimum yang dibenarkan untuk permintaan saling tindak (cth. mengambil " +"senarai pelayan), dalam unit milisaat." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Had jumlah pengguna" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Cache jejaring" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Mesej hari ini" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Mesej hari ini yang akan dipaparkan kepada pemain yang menyambung." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Kaedah yang digunakan untuk menonjolkan objek dipilih." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Tahap pengelogan minimum untuk ditulis ke sembang." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Peta mini" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Kekunci peta mini" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Ketinggian imbasan peta mini" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Had minimum jumlah rawak gua besar per ketulan peta." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Had minimum jumlah rawak gua kecil per ketulan peta." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Saiz tekstur minimum" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Pemetaan Mip" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "Lain-lain" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "Pembukah Mods" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "Keselamatan Mods" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Saluran mods" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Mengubah saiz elemen papar pandu (HUD)." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Laluan fon monospace" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Saiz fon monospace" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "Saiz fon monospace boleh dibahagikan dengan" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Hingar ketinggian gunung" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Hingar gunung" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Hingar variasi gunung" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Aras kosong gunung" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Kepekaan tetikus" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Pendarab kepekaan tetikus." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Hingar lumpur" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Pendarab untuk apungan timbul tenggelam.\n" +"Contohnya: 0 untuk tiada apungan; 1.0 untuk biasa; 2.0 untuk dua kali ganda." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Kekunci bisu" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Bisukan bunyi" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Nama penjana peta untuk digunakan apabila mencipta dunia baru.\n" +"Mencipta dunia dalam menu utama akan mengatasi tetapan ini.\n" +"Janapeta semasa yang berada dalam keadaan sangat tidak stabil:\n" +"- Pilihan floatlands di v7 (dilumpuhkan secara asalnya)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Nama pemain.\n" +"Apabila menjalankan pelayan, klien yang menyambung dengan nama ini menjadi " +"pentadbir.\n" +"Apabila memulakan daripada menu utama, nilai ini diatasi dengan nilai dari " +"menu utama." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Nama pelayan, untuk dipaparkan apabila pemain masuk dan juga dalam senarai " +"pelayan." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Dekat satah" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Port rangkaian untuk dengar (UDP).\n" +"Nilai ini akan diatasi apabila memulakan pelayan dari menu utama." + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "Rangkaian" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Pengguna baru mesti memasukkan kata laluan ini." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Tembus blok" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Kekunci tembus blok" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "Tonjolan Nod dan Entiti" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Tonjolan nod" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Selang masa NodeTimer" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Hingar" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Jumlah jalur timbul" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Jumlah jalur timbul untuk digunakan.\n" +"Nilai 0:\n" +"- Pemilihan automatik. Jumlah jalur timbul akan dikira berdasarkan\n" +"- 'jumlah pemproses - 2', dengan had minimum 1.\n" +"Sebarang nilai lain:\n" +"- Menetapkan jumlah jalur timbul, dengan had minimum 1.\n" +"AMARAN: Menaikkan jumlah jalur timbul meningkatkan kelajuan penjanaan peta " +"enjin, tetapi\n" +"ia boleh memberi kesan buruk kepada prestasi permainan dengan mengganggu " +"proses-proses\n" +"lain, terutamanya dalam mod pemain perseorangan dan/atau apabila menjalankan " +"kod Lua\n" +"dalam fungsi 'on_generated'. Untuk kebanyakan pengguna, tetapan optimum " +"ialah '1'." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Jumlah blok-blok tambahan yang boleh dimuatkan oleh /clearobjects pada " +"sesuatu masa.\n" +"Ini merupakan keseimbangan antara overhed urus niaga SQLite\n" +"dan penggunaan ingatan (4096=100MB, mengikut kebiasaan)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Cecair legap" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "Kelegapan (alfa) bayang belakang fon lalai, nilai antara 0 dan 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Buka menu jeda apabila fokus tetingkap hilang.\n" +"Tidak jeda jika formspec dibuka." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Pilihan mengatasi warna pautan sesawang di sembang." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Laluan fon berbalik. Mestilah sebuah fon jenis TrueType.\n" +"Fon ini akan digunakan bagi sesetengah bahasa atau jika fon lalai tidak " +"tersedia." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Laluan untuk simpan tangkapan layar. Boleh jadi laluan mutlak atau relatif.\n" +"Folder akan dicipta sekiranya ia belum wujud." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Laluan ke direktori pembayang. Jika tiada laluan ditakrifkan, lokasi lalai " +"akan digunakan." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "Laluan ke direktori tekstur. Semua tekstur dicari dari sini dahulu." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Laluan fon lalai. Mestilah sebuah fon jenis TrueType.\n" +"Fon berbalik akan digunakan sekiranya fon ini tidak dapat dimuatkan." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Laluan fon monospace. Mestilah sebuah fon jenis TrueType.\n" +"Fon ini digunakan untuk perkara spt. konsol dan skrin pembukah." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Jeda ketika hilang fokus tetingkap" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "Had baris gilir pemuatan blok daripada cakera per pemain" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Had baris gilir penjanaan blok per pemain" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Ikut fizik" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Kekunci pergerakan pic" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Mod pergerakan pic" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Kekunci letak" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Selang pengulangan perbuatan letak" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Pemain boleh terbang tanpa terkesan dengan graviti.\n" +"Ini memerlukan keistimewaan \"terbang\" dalam pelayan tersebut." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Jarak pemindahan pemain" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Pemain lawan pemain" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Penapisan poisson" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Port untuk menyambung (UDP).\n" +"Ambil perhatian bahawa medan port dalam menu utama mengatasi tetapan ini." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Mencegah gali dan peletakan daripada berulang ketika terus menekan butang " +"tetikus.\n" +"Bolehkan tetapan ini apabila anda gali atau letak secara tidak sengaja " +"terlalu kerap." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Mencegah mods daripada melakukan perkara tidak selamat seperti menjalankan " +"perintah cangkerang." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Mencetak data pemprofilan enjin dalam selang masa biasa (dalam unit saat).\n" +"0 = lumpuhkan. Berguna untuk pembangun." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" +"Keistimewaan-keistimewaan yang boleh diberikan oleh pemain yang mempunyai " +"keistimewaan basic_privs" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Pembukah" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Kekunci togol pembukah" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Alamat pendengar Prometheus" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Alamat pendengar Prometheus.\n" +"Jika Minetest dikompil dengan pilihan ENABLE_PROMETHEUS dibolehkan,\n" +"membolehkan pendengar metrik untuk Prometheus pada alamat berkenaan.\n" +"Metrik boleh diambil di http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Perkadaran gua besar yang mempunyai cecair." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Jejari keluasan awan dinyatakan dalam jumlah 64 nod petak awan.\n" +"Nilai lebih besar daripada 26 akan mula menghasilkan pemotongan tajam di " +"sudut kawasan awan." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Menaikkan rupa bumi untuk membuat lembah di sekitar sungai." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Input rawak" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Kekunci jarak pemilihan" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Mesej Sembang Terkini" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Laluan fon biasa" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Media jarak jauh" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Port jarak jauh" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Buang kod warna daripada mesej sembang mendatang\n" +"Gunakan ini untuk hentikan pemain daripada menggunakan warna dalam mesej " +"mereka" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Gantikan menu utama lalai dengan menu yang dibuat lain." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Laluan laporan" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Hadkan capaian sesetengah fungsi pihak klien di pelayan.\n" +"Gabungkan bendera bait di bawah ini untuk mengehadkan ciri-ciri pihak klien, " +"atau\n" +"tetapkan kepada 0 untuk tiada had:\n" +"LOAD_CLIENT_MODS: 1 (melumpuhkan pemuatan mods pihak klien)\n" +"CHAT_MESSAGES: 2 (melumpuhkan panggilan send_chat_message pihak klien)\n" +"READ_ITEMDEFS: 4 (melumpuhkan panggilan get_item_def pihak klien)\n" +"READ_NODEDEFS: 8 (melumpuhkan panggilan get_node_def pihak klien)\n" +"LOOKUP_NODES_LIMIT: 16 (mengehadkan panggilan get_node pihak klien kepada\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (melumpuhkan panggilan get_player_names pihak klien)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Hingar sebar gunung rabung" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Hingar rabung" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Hingar rabung bawah air" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Hingar saiz gunung rabung" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Kekunci ke kanan" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Kedalaman saluran sungai" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Lebar saluran sungai" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Kedalaman sungai" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Hingar sungai" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Saiz sungai" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Lebar lembah sungai" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Rakaman gulung balik" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Hingar saiz bukit" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Hingar sebar bukit" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Peta mini bulat" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Penggalian dan peletakan selamat" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Pantai berpasir terjadi apabila nilai np_beach melebihi nilai ini." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Simpan peta yang diterima oleh klien dalam cakera." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Simpan saiz tetingkap secara automatik ketika diubah." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Simpan peta diterima dari pelayan" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Menyesuaikan GUI dengan nilai ditentukan oleh pengguna.\n" +"Gunakan penapis antialias jiran terdekat untuk menyesuaikan GUI.\n" +"Ini membolehkan sisi tajam dilembutkan, dan sebatikan piksel apabila\n" +"menyesuaiturunkan, namun ia akan mengaburkan sesetengah piksel\n" +"di sisi apabila imej disesuaikan dengan saiz bukan integer." + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "Skrin" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Tinggi skrin" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Lebar skrin" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Folder tangkap layar" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Format tangkap layar" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Kualiti tangkap layar" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Kualiti tangkap layar. Hanya digunakan untuk format JPEG.\n" +"1 maksudnya paling teruk; 100 maksudnya paling bagus.\n" +"Gunakan 0 untuk kualiti lalai." + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "Tangkap layar" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Hingar dasar laut" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Hingar 2D kedua daripada empat yang mentakrifkan ketinggian jarak bukit/" +"gurung." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Hingar 3D kedua daripada dua yang mentakrifkan terowong." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Lihat http://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Warna sempadan kotak pemilihan (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Warna kotak pemilihan" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Lebar kotak pemilihan" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Pilih salah satu daripada 18 jenis fraktal.\n" +"1 = Set Mandelbrot \"Bulatan\" 4D\n" +"2 = Set Julia \"Bulatan\" 4D.\n" +"3 = Set Mandelbrot \"Persegi\" 4D.\n" +"4 = Set Julia \"Persegi\" 4D.\n" +"5 = Set Mandelbrot \"Sepupu Mandy\" 4D.\n" +"6 = Set Julia \"Sepupu Mandy\" 4D.\n" +"7 = Set Mandelbrot \"Variasi\" 4D.\n" +"8 = Set Julia \"Variasi\" 4D.\n" +"9 = Set Mandelbrot jenis \"Mandelbrot/Mandelbar\" 3D.\n" +"10 = Set Julia \"Mandelbrot/Mandelbar\" 3D.\n" +"11 = Set Mandelbrot \"Pokok Krismas\" 3D.\n" +"12 = Set Julia \"Pokok Krismas\" 3D.\n" +"13 = Set Mandelbrot \"Mandelbulb\" 3D.\n" +"14 = Set Julia \"Mandelbulb\" 3D.\n" +"15 = Set Mandelbrot \"Mandelbulb Kosinus\" 3D.\n" +"16 = Set Julia \"Mandelbulb Kosinus\" 3D.\n" +"17 = Set Mandelbrot \"Mandelbulb\" 4D.\n" +"18 = Set Julia \"Mandelbulb\" 4D." + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "Pelayan" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "Gaya Main Pelayan" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "Keselamatan Pelayan" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL pelayan" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Alamat pelayan" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Perihal pelayan" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Nama pelayan" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Port pelayan" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Penakaian oklusi pihak pelayan" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "Prestasi Pelayan/Persekitaran" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL senarai pelayan" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "Senarai Pelayan dan Mesej Harian" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Fail senarai pelayan" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Menetapkan bahasa. Biarkan kosong untuk menggunakan bahasa sistem.\n" +"Sebuah mula semula diperlukan selepas menukar tetapan ini." + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Menetapkan panjang maksimum mesej sembang (dalam jumlah aksara) yang " +"dihantar oleh klien." + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Menetapkan gama kekuatan bayang.\n" +"Melaraskan keamatan bayang dinamik dalam permainan.\n" +"Nilai lebih rendah untuk bayang lebih terang, nilai lebih tinggi untuk " +"bayang lebih gelap." + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Menetapkan saiz jejari bayang lembut.\n" +"Nilai lebih rendah untuk bayang lebih tajam, nilai lebih tinggi untuk bayang " +"lebih lembut.\n" +"Nilai minimum: 1.0; nilai maksimum: 15.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Menetapkan kecondongan orbit Matahari/Bulan dalam unit darjah.\n" +"Nilai 0 untuk tidak condong / tiada orbit menegak.\n" +"Nilai minimum: 0.0; nilai maksimum: 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Tetapkan kepada \"true\" untuk membolehkan Pemetaan Bayang.\n" +"Memerlukan pembayang untuk dibolehkan." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Tetapkan kepada \"true\" untuk membolehkan daun bergoyang.\n" +"Memerlukan pembayang untuk dibolehkan." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Tetapkan kepada \"true\" untuk membolehkan cecair bergelora (macam air).\n" +"Memerlukan pembayang untuk dibolehkan." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Tetapkan kepada \"true\" untuk membolehkan tumbuhan bergoyang.\n" +"Memerlukan pembayang untuk dibolehkan." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Menetapkan kualiti tekstur bayang kepada 32 bit.\n" +"Jika tetapkan kepada \"false\", tekstur 16 bit akan digunakan.\n" +"Tetapan ini boleh menyebabkan lebih banyak artifak pada bayang." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Laluan pembayang" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Pembayang membolehkan kesan visual mendalam dan boleh meningkatkan prestasi\n" +"untuk sesetengah kad video.\n" +"Namun ia hanya berfungsi dengan pembahagian belakang video OpenGL." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Kualiti penapisan bayang" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" +"Jarak maksimum peta bayang untuk mengemas gabung bayang, dalam unit nod" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "Tekstur peta bayang dalam 32 bit" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Saiz tekstur peta bayang" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Ofset bayang fon lalai (dalam unit piksel). Jika 0, maka bayang tidak akan " +"dilukis." + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "Gama kekuatan bayang" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Bentuk peta mini. Dibolehkan = bulat, dilumpuhkan = petak." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Tunjukkan maklumat nyahpepijat" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Tunjukkan kotak pemilihan entiti" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Tunjuk kotak pemilihan entiti\n" +"Anda perlu mulakan semula selepas mengubah tetapan ini." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Tunjuk latar belakang tag nama secara lalainya" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Mesej penutupan" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Saiz potongan peta dijana oleh janapeta, dinyatakan dalam unit\n" +"blokpeta (16 nod). AMARAN!: Tiada manfaat, dan terdapatnya\n" +"bahaya, jika menaikkan nilai ini di atas 5. Mengurangkan nilai ini\n" +"meningkatkan ketumpatan gua dan kurungan bawah tanah.\n" +"Mengubah nilai ini adalah untuk kegunaan istimewa, lebih baik\n" +"biarkan ia tidak berubah." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Saiz cache blokpeta untuk penjana jejaring. Menaikkan nilai ini akan\n" +"meningkatkan jumlah % hit cache, mengurangkan data yang perlu disalin\n" +"daripada jalur utama, lalu mengurangkan ketaran." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Kecondongan Orbit Badan Angkasa" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Hirisan w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Cerun dan pengisian bekerja bersama untuk mengubah ketinggian." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Jumlah maksimum gua kecil" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Jumlah minimum gua kecil" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" +"Variasi kelembapan berskala kecil untuk menyebatikan biom dekat sempadan." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "Variasi suhu berskala kecil untuk menyebatikan biom dekat sempadan." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Pencahayaan lembut" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Melembutkan kamera apabila melihat sekeliling. Juga dikenali sebagai " +"pelembutan penglihatan atau pelembutan tetikus.\n" +"Berguna untuk merakam video." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"Melembutkan pemutaran kamera dalam mod sinematik. Set sebagai 0 untuk " +"melumpuhkannya." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Melembutkan pemutaran kamera. Set sebagai 0 untuk melumpuhkannya." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Kekunci selinap" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Kelajuan menyelinap" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Kelajuan menyelinap, dalam unit nod per saat." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Jejari bayang lembut" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Bunyi" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Menetapkan URL dari mana klien mengambil media, menggantikan UDP.\n" +"$filename mestilah boleh dicapai daripada $remote_media$filename melalui\n" +"cURL (sudah tentu, remote_media mesti berakhir dengan tanda condong).\n" +"Fail yang tidak wujud akan diambil dengan cara biasa." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Menetapkan saiz tindanan lalai bagi nod, item dan alatan.\n" +"Ambil perhatian bahawa mods atau permainan boleh tetapkan secara khusus " +"tindanan untuk sesetengah (atau semua) item." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Sebar kemas kini lengkap peta bayang merentasi jumlah bingkai yang diberi.\n" +"Nilai lebih tinggi mungkin membuatkan bayang lembap bertindak balas,\n" +"nilai lebih rendah akan memakan lebih banyak sumber.\n" +"Nilai minimum: 1; nilai maksimum: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Sebar julat tolakan lengkung cahaya.\n" +"Mengawal lebar julat untuk ditolak.\n" +"Sisihan piawai Gauss tolakan lengkung cahaya." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Titik jelma statik" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Hingar kecuraman" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Hingar saiz gunung curam" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Hingar sebar gunung curam" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Kekuatan paralaks mod 3D." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Kekuatan tolakan lengkung cahaya.\n" +"Tiga parameter 'tolakan' mentakrifkan julat lengkung\n" +"cahaya yang ditolak dalam pencahayaan." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Pemeriksaan protokol ketat" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Buang kod warna" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Aras permukaan untuk air pilihan yang boleh terletak atas lapisan tanah " +"terapung pejal.\n" +"Air dilumpuhkan secara lalai dan hanya akan diletakkan sekiranya nilai ini " +"ditetapkan\n" +"melebihi \"nilai Y maksimum tanah terapung 'mgv7_floatland_ymax' tolak nilai " +"tirusan\n" +"tanah terapung 'mgv7_floatland_taper' (iaitu permulaan tirusan atasan)\".\n" +"***AMARAN, WUJUD POTENSI BAHAYA KEPADA PRESTASI DUNIA DAN PELAYAN***:\n" +"Apabila membolehkan peletakan air, tanah terapung mestilah ditatarajahkan " +"dan dicuba dahulu\n" +"agar ia sentiasa menjadi lapisan pejal dengan menetapkan ketumpatan " +"'mgv7_floatland_density'\n" +"kepada 2.0 (atau nilai lain yang diperlukan bergantung kepada nilai " +"'mgv7_np_floatland'), untuk\n" +"mengelakkan aliran air keterlaluan yang intensif pelayan dan untuk " +"mengelakkan kebanjiran\n" +"besar-besaran air ke permukaan dunia di bawah tanah terapung tersebut." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "SQLite segerak" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Variasi suhu untuk biom." + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "Tetapan Sementara" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Hingar rupa bumi alternatif" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Hingar asas rupa bumi" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Ketinggian rupa bumi" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Hingar rupa bumi lebih tinggi" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Hingar rupa bumi" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Nilai ambang hingar rupa bumi untuk bukit.\n" +"Mengawal perkadaran kawasan dunia dipenuhi bukit.\n" +"Laraskan kepada 0.0 untuk perkadaran lebih besar." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Nilai ambang hingar rupa bumi untuk tasik.\n" +"Mengawal perkadaran untuk kawasan dunia dilitupi laut.\n" +"Laraskan kepada 0.0 untuk perkadaran yang lebih besar." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Hingar penerusan rupa bumi" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Laluan tekstur" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Saiz tekstur yang akan digunakan untuk mengemas gabung peta bayang.\n" +"Nilai ini mestilah hasil kuasa dua.\n" +"Nombor lebih besar mencipta bayang lebih baik tetapi ia juga lebih berat." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Tekstur pada nod boleh dijajarkan sama ada kepada nod atau dunia.\n" +"Mod pertama lebih sesuai untuk benda macam mesin, perabot, dll., manakala\n" +"mod kedua membuatkan tangga dan blok mikro lebih sesuai dengan " +"persekitarannya.\n" +"Namun begitu, kerana ini ciri baru, maka ia mungkin tidak digunakan di " +"pelayan lama,\n" +"pilihan ini membolehkan pemaksaan ia untuk jenis nod tertentu. Ambil " +"perhatian\n" +"bahawa ia dianggap DALAM UJI KAJI dan mungkin tidak berfungsi dengan betul." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "URL untuk repositori kandungan" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "Zon mati bagi kayu bedik yang digunakan" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Format lalai di untuk menyimpan profil,\n" +"apabila memanggil `/profiler save [format]` tanpa format." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "Kedalaman tanah atau nod pengisi biom yang lain." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"Laluan fail relatif kepada laluan dunia anda di mana profil akan disimpan." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "Pengenal pasti kayu bedik yang digunakan" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "Panjang dalam piksel untuk memulakan interaksi skrin sentuh." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"Tinggi maksimum permukaan cecair bergelora.\n" +"4.0 = Tinggi gelora ialah dua nod.\n" +"0.0 = Gelora tidak bergerak langsung.\n" +"Nilai asalnya 1.0 (1/2 nod).\n" +"Memerlukan tetapan cecair bergelora dibolehkan." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "Antaramuka rangkaian yang pelayan dengar." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Keistimewaan yang pengguna-pengguna baru dapat secara automatik.\n" +"Lihat /privs dalam permainan untuk senarai penuh keistimewaan pelayan dan " +"konfigurasi mods." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"Jejari jilid blok di sekitar setiap pemain yang tertakluk kepada benda blok\n" +"aktif, dinyatakan dalam blokpeta (16 nod).\n" +"Dalam blok aktif, objek dimuatkan dan ABM dijalankan.\n" +"Ini juga jarak minimum di mana objek aktif (mob) dikekalkan.\n" +"Ini perlu ditetapkan bersama nilai blok jarak penghantaran objek aktif " +"(active_object_send_range_blocks)." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"Kemas gabung bahagian belakang.\n" +"Anda perlu memulakan semula selepas mengubah tetapan ini.\n" +"Nota: Di Android, kekalkan dengan OGLES1 jika tidak pasti! Apl mungkin gagal " +"dimulakan jika ditukar.\n" +"Di platform lain, OpenGL digalakkan.\n" +"Pembayang disokong oleh OpenGL (komputer sahaja) dan OGLES2 (dalam uji kaji)" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"Kepekaan paksi kayu bedik untuk menggerakkan\n" +"frustum penglihatan dalam permainan." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"Kekuatan (kegelapan) pembayang nod oklusi-sekitar.\n" +"Lebih rendah lebih gelap, lebih tinggi lebih terang. Nilai yang sah\n" +"untuk tetapan ini hanyalah dari 0.25 hingga 4.0. Jika nilai di\n" +"luar julat, ia akan ditetapkan kepada nilai sah yang terdekat." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Jumlah masa (dalam unit saat) yang dibenarkan untuk giliran cecair " +"berkembang\n" +"melebihi kapasiti pemprosesan sehingga percubaan untuk mengurangkan saiznya\n" +"dibuat dengan membuang giliran item yang lama. Nilai 0 melumpuhkan fungsi " +"ini." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"Peruntukan masa yang dibenarkan untuk ABM dilakukan di setiap langkah\n" +"(sebagai pecahan dari selang masa ABM)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Selang masa dalam saat, diambil antara peristiwa yang berulangan\n" +"apabila menekan kombinasi butang kayu bedik." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Jumlah masa dalam saat diambil untuk meletakan nod yang berulang apabila\n" +"pemain menekan butang letak tanpa melepaskannya." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Jenis kayu bedik" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"Jarak menegak di mana suhu turun sebanyak 20 jika tetapan 'altitude_chill'\n" +"dibolehkan. Juga jarak menegak kelembapan turun sebanyak 10 jika tetapan\n" +"'altitude_dry' dibolehkan." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Hingar 2D ketiga daripada empat yang mentakrifkan ketinggian bukit/gunung." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Masa untuk entiti item (iaitu item yang dijatuhkan) terus hidup dalam unit " +"saat.\n" +"Tetapkan kepada -1 untuk melumpuhkan sifat tersebut." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" +"Waktu dalam hari apabila dunia baru dimulakan, dalam milijam (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Selang penghantaran masa" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Kelajuan masa" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Had masa untuk klien membuang data peta yang tidak digunakan dari ingatan, " +"dalam saat." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Untuk mengurangkan lembapnya tindak balas, pemindahan blok diperlahankan " +"apabila pemain membina sesuatu.\n" +"Tetapan ini menetapkan berapa lama ia diperlahankan setelah meletakkan atau " +"mengalihkan sesebuah nod." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Kekunci togol mod kamera" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Lengah tip alatan" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Nilai ambang skrin sentuh" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "Skrin Sentuh" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "Keseimbangan untuk prestasi" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "Jarak Pengisihan Lut Sinar" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Hingar pokok" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Penapisan trilinear" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"Boleh digunakan untuk melancarkan peta mini pada mesin yang perlahan." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Mods yang dipercayai" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL kepada senarai pelayan yang dipaparkan dalam Tab Permainan Ramai." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Pensampelan pengurangan" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Pensampelan pengurangan serupa seperti menggunakan resolusi skrin rendah,\n" +"tetapi ia hanya diaplikasikan kepada dunia permainan sahaja, tidak mengubah " +"GUI.\n" +"Ia boleh meningkatkan prestasi dengan mengorbankan perincian imej.\n" +"Nilai lebih tinggi membuatkan imej yang kurang perincian." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Jarak pemindahan pemain tanpa had" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Nyahmuat data pelayan yang tidak digunakan" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Had Y atas kurungan bawah tanah." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Had Y atas tanah terapung." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Guna paparan awan 3D menggantikan awan rata." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Gunakan animasi awan sebagai latar belakang menu utama." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" +"Gunakan penapisan anisotropik apabila melihat tekstur dari suatu sudut." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Gunakan penapisan bilinear apabila menyesuaikan tekstur." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Gunakan pemetaan mip untuk menyesuaikan tekstur. Boleh meningkatkan\n" +"sedikit prestasi, terutamanya apabila menggunakan pek tekstur resolusi\n" +"tinggi. Penyesuai-turun gama secara tepat tidak disokong." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Gunakan antialias pelbagai sampel (MSAA) untuk melembutkan sisi bongkah.\n" +"Algoritma ini melembutkan port pandangan 3D sambil mengekalkan ketajaman " +"imej,\n" +"tetapi ia tidak memberi kesan bahagian dalam sesuatu tekstur\n" +"(yang mana ia tampak lebih nyata dengan tekstur lutsinar).\n" +"Ruangan kosong akan kelihatan di antara nod apabila pembayang dilumpuhkan.\n" +"Jika ditetapkan ke 0, MSAA akan dilumpuhkan.\n" +"Anda perlu mulakan semula selepas mengubah pilihan ini." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Gunakan penapisan trilinear apabila menyesuaikan tekstur." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "Antara Muka Pengguna" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Segerak Menegak" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Kedalaman lembah" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Isi lembah" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Profil lembah" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Kecerunan lembah" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Variasi kedalaman pengisi biom." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Variasi ketinggian maksimum gunung (dalam unit nod)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Variasi jumlah gua." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Variasi skala menegak rupa bumi.\n" +"Apabila hingar < -0.55 maka rupa bumi hampir rata." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Pelbagai kedalaman nod permukaan biom." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Pelbagai kekasaran rupa bumi.\n" +"Mentakrifkan nilai penerusan 'persistence' untuk hingar terrain_base dan " +"terrain_alt." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Pelbagai kecuraman cenuram." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Kelajuan memanjat menegak, dalam unit nod per saat." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Penyegerakan menegak skrin." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Pemacu video" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Faktor apungan pandang" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Jarak pandang dalam unit nod." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Kekunci mengurang jarak pandang" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Kekunci menambah jarak pandang" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Kekunci zum pandangan" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Jarak pandang" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "Kayu bedik maya memicu butang Aux1" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Kekuatan bunyi" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Kekuatan semua bunyi.\n" +"Memerlukan sistem bunyi dibolehkan." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Koordinat W untuk hirisan 3D yang dijana daripada fraktal 4D.\n" +"Menentukan hirisan 3D yang mana akan dijana daripada bentuk 4D.\n" +"Mengubah bentuk fraktal.\n" +"Tidak memberi kesan kepada fraktal 3D.\n" +"Julat kasarnya -2 sehingga 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Kelajuan berjalan dan terbang, dalam unit nod per saat." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Kelajuan berjalan" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Kelajuan berjalan, terbang dan memanjat dalam mod pantas, dalam unit nod per " +"saat." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Aras air" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Aras permukaan air dunia." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Nod bergoyang" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Daun bergoyang" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Cecair bergelora" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Ketinggian ombak cecair bergelora" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Kelajuan ombak cecair bergelora" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Panjang ombak cecair bergelora" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Tumbuhan bergoyang" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "Warna pautan sesawang" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Apabila penapis skala GUI (gui_scaling_filter) ditetapkan kepada \"true\", " +"semua\n" +"imej GUI perlu ditapis dalam perisian, tetapi sesetengah imej dijana secara " +"terus\n" +"ke perkakasan (contohnya, kemas-gabung-ke-tekstur untuk nod dalam inventori)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Apabila gui_scaling_filter_txr2img ditetapkan kepada \"true\", salin semula " +"kesemua imej\n" +"tersebut dari perkakasan ke perisian untuk disesuaikan. Sekiranya ditetapkan " +"kepada\n" +"\"false\", berbalik kepada kaedah penyesuaian yang lama, untuk pemacu video " +"yang tidak\n" +"mampu menyokong dengan sempurna fungsi muat turun semula tekstur daripada " +"perkakasan." + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Apabila menggunakan tapisan bilinear/trilinear/anisotropik, tekstur " +"resolusi\n" +"rendah boleh jadi kabur, jadi sesuai-naikkannya secara automatik dengan " +"sisipan\n" +"jiran terdekat untuk memelihara piksel keras. Tetapan ini menetapkan saiz " +"tekstur\n" +"minimum untuk tekstur yang disesuai-naikkan; nilai lebih tinggi tampak " +"lebih\n" +"tajam, tetapi memerlukan ingatan yang lebih banyak. Nilai kuasa 2 " +"digalakkan.\n" +"Tetapan ini HANYA digunakan jika penapisan bilinear/trilinear/anisotropik " +"dibolehkan.\n" +"Tetapan ini juga digunakan sebagai saiz tekstur nod asas untuk\n" +"penyesuaian automatik bagi tekstur jajaran dunia." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Sama ada latar belakang tag nama patut ditunjukkan secara lalainya.\n" +"Mods masih boleh menetapkan latar belakang." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"Sama ada animasi tekstur nod perlu dinyahsegerakkan pada setiap blok peta." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Tetapkan sama ada pemain ditunjukkan kepada klien tanpa sebarang had jarak.\n" +"Tetapan ini terkecam, gunakan tetapan player_transfer_distance sebagai ganti." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" +"Menetapkan sama ada ingin membenarkan pemain untuk mencederakan dan membunuh " +"satu sama lain." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Tetapan sama ada untuk meminta klien menyambung semula selepas berlakunya " +"keruntuhan (Lua).\n" +"Tetapkan kepada \"true\" jika pelayan anda ditetapkan untuk mula semula " +"secara automatik." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Sama ada ingin papar kabut di penghujung kawasan yang kelihatan." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Sama ada ingin membisukan bunyi. Anda boleh menyahbisu pada bila-bila\n" +"masa, melainkan sistem bunyi dilumpuhkan (enable_sound=false).\n" +"Dalam permainan, anda boleh menogol keadaan bisu menggunakan kekunci\n" +"bisu atau menggunakan menu jeda." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" +"Sama ada ingin tunjukkan nama teknikal.\n" +"Memberi kesan kepada mods dan pek tekstur dalam menu Kandungan dan Pilih " +"Mods,\n" +"dan juga nama tetapan dalam Semua Tetapan.\n" +"Dikawal oleh kotak pilihan dalam menu \"Semua tetapan\"." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"Sama ada ingin menunjukkan maklumat nyahpepijat (kesannya sama seperti " +"menekan butang F5)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "Komponen lebar saiz tetingkap awal. Diabaikan dalam mod skrin penuh." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Lebar garisan kotak pemilihan sekeliling nod." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Sistem Windows sahaja: Mulakan Minetest dengan tetingkap garis perintah " +"dekat latar belakang.\n" +"Mengandungi maklumat yang sama seperti fail debug.txt (nama lalai)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Direktori dunia (semua benda dalam dunia disimpan di sini).\n" +"Tidak diperlukan jika bermula dari menu utama." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Masa mula dunia" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Tekstur jajaran dunia boleh disesuaikan untuk menjangkau beberapa nod.\n" +"Namun begitu, pelayan mungkin tidak dapat menghantar skala yang anda\n" +"inginkan, terutamanya jika anda gunakan pek tekstur yang direka secara\n" +"khusus; dengan pilihan ini, klien akan cuba untuk menentukan skala secara\n" +"automatik berdasarkan saiz tekstur. Juga lihat texture_min_size.\n" +"Amaran: Pilihan ini DALAM UJI KAJI!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Mod tekstur jajaran dunia" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y untuk tanah rata." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Nilai Y untuk permulaan kecerunan ketumpatan gunung. Digunakan untuk " +"menganjak gunung secara menegak." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Had Y pengatas gua besar." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Jarak Y di mana gua berkembang kepada saiz penuh." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Jarak-Y di mana tanah terapung menirus daripada ketumpatan penuh kepada " +"tiada apa-apa.\n" +"Ketirusan bermula pada jarak ini daripada had Y.\n" +"Untuk lapisan tanah terapung pejal, nilai ini mengawal ketinggian bukit/" +"gunung.\n" +"Mesti kurang atau sama dengan separuh jarak di antara had-had Y." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Aras Y untuk permukaan rupa bumi purata." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Aras Y untuk had pengatas gua." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Aras Y untuk rupa bumi lebih tinggi yang mencipta cenuram." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Aras Y untuk rupa bumi lebih rendah dan dasar laut." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Aras Y untuk dasar laut." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "cURL" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Had masa muat turun fail cURL" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "Had masa saling tindak cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Had cURL selari" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Mod Kreatif: " + +#~ msgid "- Damage: " +#~ msgstr "- Boleh cedera: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = oklusi paralaks dengan maklumat cerun (lebih cepat).\n" +#~ "1 = pemetaan bentuk muka bumi (lebih lambat, lebih tepat)." + +#~ msgid "Address / Port" +#~ msgstr "Alamat / Port" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Laraskan pengekodan gama untuk jadual cahaya. Nombor lebih tinggi lebih " +#~ "cerah.\n" +#~ "Tetapan ini hanya untuk klien dan diabaikan oleh pelayan permainan." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "" +#~ "Ubah cara tanah terapung jenis gunung menirus di atas dan bawah titik " +#~ "tengah." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Adakah anda mahu set semula dunia pemain perseorangan?" + +#~ msgid "Back" +#~ msgstr "Backspace" + +#~ msgid "Basic" +#~ msgstr "Asas" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bit per piksel (atau kedalaman warna) dalam mod skrin penuh." + +#~ msgid "Bump Mapping" +#~ msgstr "Pemetaan Bertompok" + +#~ msgid "Bumpmapping" +#~ msgstr "Pemetaan bertompok" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "Titik tengah tolakan-tengah lengkung cahaya." + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Mengubah antara muka menu utama:\n" +#~ "- Penuh: Banyak dunia pemain perseorangan, pilihan permainan, pek " +#~ "tekstur, dll.\n" +#~ "- Mudah: Satu dunia pemain perseorangan, tiada pilihan permainan atau " +#~ "pek tekstur.\n" +#~ "Mungkin diperlukan untuk skrin yang lebih kecil." + +#~ msgid "Config mods" +#~ msgstr "Konfigurasi mods" + +#~ msgid "Configure" +#~ msgstr "Konfigurasi" + +#~ msgid "Connect" +#~ msgstr "Sambung" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Mengawal kelajuan tenggelam dalam cecair." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Mengawal ketumpatan rupa bumi tanah terapung bergunung.\n" +#~ "Nilainya ialah ofset yang menambah kepada nilai hingar 'mgv7_np_mountain'." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Mengawal lebar terowong, nilai lebih kecil mencipta terowong lebih lebar." + +#~ msgid "Credits" +#~ msgstr "Penghargaan" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Warna bagi kursor rerambut silang (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Boleh Cedera" + +#~ msgid "Darkness sharpness" +#~ msgstr "Ketajaman kegelapan" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Had masa lalai untuk cURL, dinyatakan dalam milisaat.\n" +#~ "Hanya berkesan jika dikompil dengan pilihan cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Mentakrifkan kawasan rupa bumi lembut tanah terapung.\n" +#~ "Tanag terapung lembut berlaku apabila hingar > 0." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Mentakrifkan tahap persampelan tekstur.\n" +#~ "Nilai lebih tinggi menghasilkan peta normal lebih lembut." + +#~ msgid "Del. Favorite" +#~ msgstr "Padam Kegemaran" + +#~ msgid "" +#~ "Deprecated, define and locate cave liquids using biome definitions " +#~ "instead.\n" +#~ "Y of upper limit of lava in large caves." +#~ msgstr "" +#~ "Tetapan terkecam, mentakrifkan dan menetapkan cecair gua menggunakan " +#~ "pentakrifan biom menggantikan cara asal.\n" +#~ "Had Y atasan lava di gua-gua besar." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Muat turun permainan, contohnya Minetest Game, dari minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Muat turun satu dari minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Sedang muat turun dan memasang $1, sila tunggu..." + +#~ msgid "Enable VBO" +#~ msgstr "Membolehkan VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "Bolehkan pengesahan pendaftaran" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Membolehkan pemetaan bertompok pada tekstur. Peta normal perlu disediakan " +#~ "oleh pek\n" +#~ "tekstur atau perlu dijana secara automatik.\n" +#~ "Perlukan pembayang dibolehkan." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Membolehkan pemetaan tona sinematik" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Membolehkan penjanaan peta normal secara layang (Kesan cetak timbul).\n" +#~ "Perlukan pemetaan bertompok untuk dibolehkan." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Membolehkan pemetaan oklusi paralaks.\n" +#~ "Memerlukan pembayang untuk dibolehkan." + +#~ msgid "Enter " +#~ msgstr "Masukkan " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Pilihan percubaan, mungkin menampakkan ruang yang nyata di\n" +#~ "antara blok apabila ditetapkan dengan nombor lebih besar daripada 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS di menu jeda" + +#~ msgid "Fallback font shadow" +#~ msgstr "Bayang fon berbalik" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Nilai alfa bayang fon berbalik" + +#~ msgid "Fallback font size" +#~ msgstr "Saiz fon berbalik" + +#~ msgid "Filtering" +#~ msgstr "Penapisan" + +#~ msgid "Floatland base height noise" +#~ msgstr "Hingar ketinggian asas tanah terapung" + +#~ msgid "Floatland mountain height" +#~ msgstr "Ketinggian gunung tanah terapung" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Nilai alfa bayang fon (kelegapan, antara 0 dan 255)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Saiz fon bagi fon berbalik dalam unit titik (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "Fon FreeType" + +#~ msgid "Full screen BPP" +#~ msgstr "BPP skrin penuh" + +#~ msgid "Game" +#~ msgstr "Permainan" + +#~ msgid "Gamma" +#~ msgstr "Gama" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Jana Peta Normal" + +#~ msgid "Generate normalmaps" +#~ msgstr "Jana peta normal" + +#~ msgid "HUD scale factor" +#~ msgstr "Faktor skala papar pandu (HUD)" + +#~ msgid "High-precision FPU" +#~ msgstr "Unit titik terapung (FPU) ketepatan tinggi" + +#~ msgid "IPv6 support." +#~ msgstr "Sokongan IPv6." + +#~ msgid "In-Game" +#~ msgstr "Dalam Permainan" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Pasang: fail: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Instrumentasi" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Ikatan kekunci. (Jika menu ini berselerak, buang sesetengah benda dari " +#~ "fail minetest.conf)" + +#~ msgid "Lava depth" +#~ msgstr "Kedalaman lava" + +#~ msgid "Lightness sharpness" +#~ msgstr "Ketajaman pencahayaan" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Had baris hilir keluar pada cakera" + +#~ msgid "Main" +#~ msgstr "Utama" + +#~ msgid "Main menu style" +#~ msgstr "Gaya menu utama" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "Membuatkan DirectX bekerja dengan LuaJIT. Lumpuhkan tetapan jika " +#~ "bermasalah." + +#~ msgid "Menus" +#~ msgstr "Menu" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Peta mini dalam mod radar, Zum 2x" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Peta mini dalam mod radar, Zum 4x" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Peta mini dalam mod permukaan, Zum 2x" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Peta mini dalam mod permukaan, Zum 4x" + +#~ msgid "Name / Password" +#~ msgstr "Nama / Kata laluan" + +#~ msgid "Name/Password" +#~ msgstr "Nama/Kata laluan" + +#~ msgid "No" +#~ msgstr "Tidak" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Persampelan peta normal" + +#~ msgid "Normalmaps strength" +#~ msgstr "Kekuatan peta normal" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Jumlah lelaran oklusi paralaks." + +#~ msgid "Ok" +#~ msgstr "Ok" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "" +#~ "Kelegapan (alfa) bayang belakang fon berbalik, nilai antara 0 dan 255." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "" +#~ "Pengaruh kesan oklusi paralaks pada keseluruhannya, kebiasaannya skala/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Skala keseluruhan kesan oklusi paralaks." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Oklusi Paralaks" + +#~ msgid "Parallax occlusion" +#~ msgstr "Oklusi paralaks" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Pengaruh oklusi paralaks" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Lelaran oklusi paralaks" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Mod oklusi paralaks" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Skala oklusi paralaks" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Kekuatan oklusi paralaks" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Laluan ke fon TrueType atau peta bit." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Laluan untuk simpan tangkap layar." + +#~ msgid "Player name" +#~ msgstr "Nama pemain" + +#~ msgid "Profiling" +#~ msgstr "Pemprofilan" + +#~ msgid "Projecting dungeons" +#~ msgstr "Kurungan bawah tanah melunjur" + +#~ msgid "PvP enabled" +#~ msgstr "Boleh Berlawan PvP" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Set semula dunia pemain perseorangan" + +#~ msgid "Select Package File:" +#~ msgstr "Pilih Fail Pakej:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Pelayan / Pemain perseorangan" + +#~ msgid "" +#~ "Set the shadow update time.\n" +#~ "Lower value means shadows and map updates faster, but it consume more " +#~ "resources.\n" +#~ "Minimun value 0.001 seconds max value 0.2 seconds" +#~ msgstr "" +#~ "Menetapkan masa kemas kini bayang.\n" +#~ "Nilai lebih rendah untuk kemas kini peta dan bayang lebih laju, tetapi " +#~ "menggunakan lebih banyak sumber.\n" +#~ "Nilai minimum 0.001 saat dan nilai maksimum 0.2 saat" + +#~ msgid "Shadow limit" +#~ msgstr "Had bayang" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Ofset bayang fon berbalik (dalam unit piksel). Jika 0, maka bayang tidak " +#~ "akan dilukis." + +#~ msgid "Special" +#~ msgstr "Istimewa" + +#~ msgid "Special key" +#~ msgstr "Kekunci istimewa" + +#~ msgid "Start Singleplayer" +#~ msgstr "Mula Main Seorang" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Kekuatan peta normal yang dijana." + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "Kekuatan tolakan tengah lengkung cahaya." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Fon ini akan digunakan untuk sesetengah bahasa." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Untuk membolehkan pembayang, pemacu OpenGL mesti digunakan." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Togol Sinematik" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Ketinggian maksimum biasa, di atas dan bawah titik tengah, untuk gunung " +#~ "tanah terapung." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Variasi ketinggian bukit dan kedalaman tasik rupa bumi lembut tanah " +#~ "terapung." + +#~ msgid "View" +#~ msgstr "Lihat" + +#~ msgid "Waving Water" +#~ msgstr "Air Bergelora" + +#~ msgid "Waving water" +#~ msgstr "Air bergelora" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Menetapkan sama ada fon FreeType digunakan, memerlukan sokongan Freetype\n" +#~ "dikompil bersama. Jika dilumpuhkan, fon peta bit dan vektor XML akan " +#~ "digunakan." + +#~ msgid "Whether dungeons occasionally project from the terrain." +#~ msgstr "" +#~ "Sama ada kurungan bawah tanah kadang-kala terlunjur daripada rupa bumi." + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Had Y pengatas lava dalam gua besar." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "Aras Y untuk titik tengah tanah terapung dan permukaan tasik." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Aras Y di mana bayang tanah terapung diperluaskan." + +#~ msgid "Yes" +#~ msgstr "Ya" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Anda akan sertai pelayan dengan nama \"%s\" untuk kali pertama.\n" +#~ "Jika anda teruskan, akaun baru dengan maklumat anda akan dicipta di " +#~ "pelayan ini.\n" +#~ "Sila taip semula kata laluan anda dan klik 'Daftar dan Sertai' untuk " +#~ "sahkan penciptaan akaun, atau klik 'Batal' untuk membatalkan." + +#~ msgid "You died." +#~ msgstr "Anda telah meninggal." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/ms_Arab/minetest.po b/po/ms_Arab/minetest.po new file mode 100644 index 0000000..39cbfc8 --- /dev/null +++ b/po/ms_Arab/minetest.po @@ -0,0 +1,7824 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-05-19 18:13+0000\n" +"Last-Translator: Niskala Airaha <niskala5570@gmail.com>\n" +"Language-Team: Malay (Jawi) <https://hosted.weblate.org/projects/minetest/" +"minetest/ms_Arab/>\n" +"Language: ms_Arab\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.13-dev\n" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Clear the out chat queue" +msgstr "ساٴيز مکسيموم باريس ݢيلير کلوار سيمبڠ" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "کلوار کمينو" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Invalid command: " +msgstr "ارهن تمڤتن" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "ڤماٴين ڤرسأورڠن" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "ڤماٴين ڤرسأورڠن" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "لاهير سمولا" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "اندا تله منيڠݢل" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "ارهن تمڤتن" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "ارهن تمڤتن" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "برلاکوڽ رالت دالم سکريڤ Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "تله برلاکوڽ رالت:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "مينو اوتام" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "سمبوڠ سمولا" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "ڤلاين ڤرماٴينن ممينت اندا اونتوق مڽمبوڠ سمولا:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "ڤيليه دنيا:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "ۏرسي ڤروتوکول تيدق سراسي. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "ڤلاين ڤرماٴينن مڠواتکواساکن ڤروتوکول ۏرسي $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "ڤلاين ڤرماٴينن مڽوکوڠ ڤروتوکول ۏرسي $1 هيڠݢ $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "کامي هاڽ مڽوکوڠ ڤروتوکول ۏرسي $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "کامي مڽوکوڠ ڤروتوکول ۏرسي $1 هيڠݢ $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "بطل" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "کبرݢنتوڠن:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "لومڤوهکن سموا" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "لومڤوهکن ڤيک مودس" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "ممبوليهکن سموا" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "بوليهکن ڤيک مودس" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"ݢاݢل اونتوق ممبوليهکن مودس \"$1\" کران اي مڠندوڠي اکسارا يڠ تيدق دبنرکن. هاڽ " +"اکسارا [a-z0-9_] سهاج يڠ دبنرکن." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "چاري مودس لاٴين" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "مودس:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "تيادا کبرݢنتوڠن (ڤيليهن)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "تيادا ڤريهل ڤرماٴينن ترسديا." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "تيادا کبرݢنتوڠن واجب" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "تيادا ڤريهل ڤيک مودس ترسديا." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "تيادا کبرݢنتوڠن ڤيليهن" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "کبرݢنتوڠن ڤيليهن:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "سيمڤن" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "دنيا:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "دبوليهکن" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "مموات تورون..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "سموا ڤاکيج" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Already installed" +msgstr "ککونچي تله دݢوناکن اونتوق فوڠسي لاٴين" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "کمبالي کمينو اوتام" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "هوس ڤرماٴينن" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "سيستم ContentDB تيدق ترسديا اڤابيلا Minetest دکومڤيل تنڤ cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "مموات تورون..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "ݢاݢل مموات تورون $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "ڤرماٴينن" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "ڤاسڠ" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "ڤاسڠ" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "کبرݢنتوڠن ڤيليهن:" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "ڤاسڠ: جنيس فايل \"$1\" تيدق دسوکوڠ اتاو ارکيب روسق" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "مودس" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "تيادا ڤاکيج يڠ بوليه دامبيل" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "تيادا حاصيل" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "No updates" +msgstr "کمس کيني" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Not found" +msgstr "بيسوکن بوڽي" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "ڤيک تيکستور" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "ڽهڤاسڠ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "کمس کيني" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "دنيا برنام \"$1\" تله وجود" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "روڤ بومي تمبهن" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "کديڠينن التيتود" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "ککريڠن التيتود" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "ڤڽباتين بيوم" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "بيوم" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "ݢوا بسر" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "ݢوا" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "چيڤت" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "هياسن" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "امرن: The Development Test هاڽله اونتوق کݢوناٴن ڤمباڠون." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "کوروڠن باواه تانه" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "روڤ بومي رات" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "جيسيم بومي تراڤوڠ اتس لاڠيت" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "تانه تراڤوڠ (دالم اوجيکاجي)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "جان روڤ بومي بوکن-فراکتل: لاٴوتن دان باواه تانه" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "بوکيت" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "سوڠاي لمبڤ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "تيڠکتکن کلمبڤن سکيتر سوڠاي" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "ڤاسڠ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "تاسيق" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "کلمبڤن رنده دان هاب تيڠݢي مڽببکن سوڠاي چيتيق اتاو کريڠ" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "جاناٴن ڤتا" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "بنديرا جان ڤتا" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "بنديرا خصوص جان ڤتا" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "ݢونوڠ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "اليرن لومڤور" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "جاريڠن تروووڠ دان ݢوا" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "تيادا ڤرماٴينن دڤيليه" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "کورڠکن هاب مڠيکوت التيتود" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "کورڠکن کلمبڤن مڠيکوت التيتود" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "سوڠاي" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "سوڠاي ارس لاٴوت" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "بنيه" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "ڤراليهن لمبوت دانتارا بيوم" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"ستروکتور يڠ مونچول اتس روڤ بومي (تيادا کسن ڤد ڤوکوق دان رومڤوت هوتن دچيڤت " +"اوليه v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "ستروکتور يڠ مونچول اتس روڤ بومي⹁ بياساڽ ڤوکوق دان تومبوهن" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "اقليم سدرهان⹁ ݢورون" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "اقليم سدرهان⹁ ݢورون⹁ هوتن" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "اقليم سدرهان⹁ ݢورون⹁ هوتن⹁ توندرا⹁ تايݢ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "هاکيسن ڤرموکاٴن روڤ بومي" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "ڤوکوق دان رومڤوت هوتن" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "کدالمن سوڠاي برباݢاي" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "ݢوا ݢرݢاسي يڠ ساڠت مندالم باواه تانه" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "نام دنيا" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "اندا تيدق مماسڠ سبارڠ ڤرماٴينن." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "ادکه امدا ڤستي اندا ايڠين ممادم \"$1\"؟" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "ڤادم" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: ݢاݢل ممادم \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: لالوان تيدق صح \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "ڤادم دنيا \"$1\"؟" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "صحکن کات لالوان" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "کات لالوان لام" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "کات لالوان تيدق ڤادن!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "دفتر دان سرتاٴي" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "تريما" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "نامکن سمولا ڤيک مودس:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"ڤيک مودس اين ممڤوڽاٴي نام خصوص دبريکن دالم فايل modpack.conf ميليقڽ يڠ اکن " +"مڠاتسي سبارڠ ڤناماٴن سمولا دسين." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(تيادا ڤريهل اونتوق تتڤن يڠ دبري)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "هيڠر 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< کمبالي کهلامن تتڤن" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "لاير" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "کندوڠن" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "کندوڠن" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "دلومڤوهکن" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "ايديت" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "دبوليهکن" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "لاکوناريتي" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "اوکتف" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "اوفسيت" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "ڤنروسن" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "سيلا ماسوقکن اينتيݢر يڠ صح." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "سيلا ماسوقکن نومبور يڠ صح." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "ڤوليهکن تتڤن اصل" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "سکال" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "چاري" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "ڤيليه ديريکتوري" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "ڤيليه فايل" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "تونجوقکن نام تيکنيکل" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "نيلاي مستيله سکورڠ-کورڠڽ $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "نيلاي مستيله تيدق لبيه درڤد $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "سيبرن X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "سيبرن Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "سيبرن Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "نيلاي مطلق" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "لالاي" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "تومڤول" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (دبوليهکن)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 مودس" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "ݢاݢل مماسڠ $1 ڤد $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "ڤاسڠ مودس: ݢاݢل منچاري نام مودس سبنر اونتوق: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "ڤاسڠ مودس: تيدق جومڤ نام فولدر يڠ سسواي اونتوق ڤيک مودس $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "تيدق جومڤ مودس اتاو ڤيک مودس يڠ صح" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "ݢاݢل مماسڠ $1 سباݢاي ڤيک تيکستور" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "ݢاݢل مماسڠ ڤرماٴينن سباݢاي $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "ݢاݢل مماسڠ مودس سباݢاي $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "ݢاݢل مماسڠ ڤيک مودس سباݢاي $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "سدڠ ممواتکن..." + +#: builtin/mainmenu/serverlistmgr.lua +#, fuzzy +msgid "Public server list is disabled" +msgstr "سکريڤ ڤيهق کليئن دلومڤوهکن" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "چوب اکتيفکن سمولا سناراي ڤلاين عوام فان ڤريقسا سمبوڠن اينترنيت اندا." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "ڤڽومبڠ اکتيف" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Active renderer:" +msgstr "جارق ڤڠهنترن اوبجيک اکتيف" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "ڤمباڠون تراس" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "ڤيليه ديريکتوري" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "ڤڽومبڠ تردهولو" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "ڤمباڠون تراس تردهولو" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "تونجوقکن معلومت ڽهڤڤيجت" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "لايري کندوڠن دالم تالين" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "کندوڠن" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "لومڤوهکن ڤيک تيکستور" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "معلومت:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "ڤاکيج دڤاسڠ:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "تيادا کبرݢنتوڠن." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "تيادا ڤريهل ڤاکيج ترسديا" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "نامکن سمولا" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "ڽهڤاسڠ ڤاکيج" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "ݢونا ڤيک تيکستور" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "اومومکن ڤلاين" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "علامت ايکتن" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "مود کرياتيف" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "بوليه چدرا" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "هوس ڤرماٴينن" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "هوس ڤلاين" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "ڤاسڠکن ڤرماٴينن درڤد ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "بوات بارو" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "تيادا دنيا دچيڤت اتاو دڤيليه!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "مولا ماٴين" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "ڤورت" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "ڤيليه دنيا:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "ڤيليه دنيا:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "ڤورت ڤلاين" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "مولاکن ڤرماٴينن" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "- علامت: " + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "ڤادم" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "مود کرياتيف" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "بوليه چدرا" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "کݢمرن" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "سرتاٴي ڤرماٴينن" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "ڤيڠ" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "اومومکن ڤلاين" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "ڤورت جارق جاٴوه" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "ڤريهل ڤلاين ڤرماٴينن" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "اوان 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "سموا تتڤن" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "انتيالياس:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "اٴوتوسيمڤن ساٴيز سکرين" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "ڤناڤيسن بيلينيار" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "توکر ککونچي" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "کاچ برسمبوڠن" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Dynamic shadows" +msgstr "بايڠ فون" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "بايڠ فون" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "داون براݢم" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "ڤتا ميڤ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "ڤتا ميڤ + ڤناڤيسن انيسو" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "تيادا تاڤيسن" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "تيادا ڤتا ميڤ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "تونجولن نود" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "کرڠک نود" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "تيادا" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "داون لݢڤ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "اٴير لݢڤ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "ڤرتيکل" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "سکرين:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "تتڤن" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "ڤمبايڠ" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "تانه تراڤوڠ (دالم اوجيکاجي)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "ڤمبايڠ (تيدق ترسديا)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "داون ريڠکس" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "ڤنچهاياٴن لمبوت" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "جالينن:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "ڤمتاٴن تونا" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "نيلاي امبڠ سنتوهن: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "ڤناڤيسن تريلينيار" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "داٴون برݢويڠ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "چچاٴير برݢلورا" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "تومبوهن برݢويڠ" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "رالت دالم ڤڽمبوڠن (تامت تيمڤوه؟)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "سمبوڠن تامت تيمڤوه." + +#: src/client/client.cpp +msgid "Done!" +msgstr "سلساي!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "مڠاولکن نود" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "سدڠ مڠاولکن نود..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "سدڠ ممواتکن تيکستور..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "سدڠ ممبينا سمولا ڤمبايڠ..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "رالت دالم ڤڽمبوڠن (تامت تيمڤوه؟)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "تيدق جومڤ اتاو تيدق بوليه مواتکن ڤرماٴينن \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "سڤيسيفيکاسي ڤرماٴينن تيدق صح." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "مينو اوتام" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "تيادا دنيا دڤيليه اتاو تيادا علامت دبري. تيادا اڤ بوليه دلاکوکن." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "نام ڤماٴين ترلالو ڤنجڠ." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "سيلا ڤيليه سواتو نام!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "فايل کات لالوان يڠ دسدياکن ݢاݢل دبوک: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "لالوان دنيا دبري تيدق وجود: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"ڤريقسا فايل debug.txt اونتوق معلومت لنجوت." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- علامت: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- مود: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- ڤورت: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- عوام: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- نام ڤلاين: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "تله برلاکوڽ رالت:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "ڤرݢرقن اٴوتوماتيک دلومڤوهکن" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "ڤرݢرقن اٴوتوماتيک دبوليهکن" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "کمس کيني کاميرا دلومڤوهکن" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "کمس کيني کاميرا دبوليهکن" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "توکر کات لالوان" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "مود سينماتيک دلومڤوهکن" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "مود سينماتيک دبوليهکن" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "مودس کليئن" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "سکريڤ ڤيهق کليئن دلومڤوهکن" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "سدڠ مڽمبوڠ کڤد ڤلاين..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "تروسکن" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"کاولن:\n" +"- %s: برݢرق کدڤن\n" +"- %s: برݢرق کبلاکڠ\n" +"- %s: برݢرق ککيري\n" +"- %s: برݢرق ککانن\n" +"- %s: لومڤت\\ناٴيق اتس\n" +"- %s: سلينڤ\\تورون باواه\n" +"- %s: جاتوهکن ايتم\n" +"- %s: اينۏينتوري\n" +"- تتيکوس: ڤوسيڠ\\ليهت سکليليڠ\n" +"- تتيکوس کيري: ݢالي\\کتوق\n" +"- تتيکوس کانن: لتق\\ݢونا\n" +"- رودا تتيکوس: ڤيليه ايتم\n" +"- %s: سيمبڠ\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "سدڠ منچيڤت کليئن..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "سدڠ منچيڤت ڤلاين..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "معلومت ڽهڤڤيجت دان ݢراف ڤمبوکه دسمبوڽيکن" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "معلومت ڽهڤڤيجت دتونجوقکن" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "معلومت ڽهڤڤيجت⹁ ݢراف ڤمبوکه⹁ دان رڠک داواي دسمبوڽيکن" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"کاولن اصل:\n" +"تيادا مينو کليهتن:\n" +"- تکن سکالي: اکتيفکن بوتڠ\n" +"- تکن دوا کالي: لتق بارڠ\\ݢونا سسواتو\n" +"- تاريق دڠن جاري: ليهت سکليليڠ\n" +"مينو\\اينۏينتوري کليهتن:\n" +"- تکن برݢندا (لوار کاوسن اينۏينتوري):\n" +" -->توتوڤ\n" +"- تکن تيندنن⹁ تکن سلوت:\n" +" --> ڤينده تيندنن\n" +"- سنتوه دان تاريق⹁ تکن سکرين ڤاکاي جاري کدوا\n" +" --> لتق ساتو ايتم دري تيندنن کدالم سلوت\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "جارق ڤندڠ تنڤ حد دلومڤوهکن" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "جارق ڤندڠ تنڤ حد دبوليهکن" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "سدڠ منچيڤت کليئن..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "کلوار کمينو" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "کلوار تروس ڤرماٴينن" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "مود ڤرݢرقن ڤنتس دلومڤوهکن" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "مود ڤرݢرقن ڤنتس دبوليهکن" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "مود ڤرݢرقن ڤنتس دبوليهکن (نوت: تيادا کأيستيميواٴن 'ڤرݢرقن ڤنتس')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "مود تربڠ دلومڤوهکن" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "مود تربڠ دبوليهکن" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "مود تربڠ دبوليهکن (نوت: تيادا کأيستيميواٴن 'تربڠ')" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "کابوت دلومڤوهکن" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "کابوت دبوليهکن" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "معلومت ڤرماٴينن:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "ڤرماٴينن دجيداکن" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "مڠهوس ڤلاين" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "سدڠ منتعريفکن ايتم..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "سدڠ ممواتکن ميديا..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "ڤتا ميني دلومڤوهکن اوليه ڤرماٴينن اتاو مودس" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "ڤماٴين ڤرسأورڠن" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "مود تمبوس بلوک دلومڤوهکن" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "مود تمبوس بلوک دبوليهکن" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "مود تمبوس بلوک دبوليهکن (نوت: تيادا کأيستيميواٴن 'تمبوس بلوک')" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "سدڠ منتعريفکن نود..." + +#: src/client/game.cpp +msgid "Off" +msgstr "توتوڤ" + +#: src/client/game.cpp +msgid "On" +msgstr "بوک" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "مود ڤرݢرقن ڤيچ دلومڤوهکن" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "مود ڤرݢرقن ڤيچ دبوليهکن" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "ݢراف ڤمبوکه دتونجوقکن" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "ڤلاين جارق جاٴوه" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "سدڠ مڽلسايکن علامت..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "سدڠ منوتوڤ..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "ڤماٴين ڤرسأورڠن" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "ککواتن بوڽي" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "بوڽي دبيسوکن" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "سيستم بوڽي دلومڤوهکن" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "سيستم بوڽي تيدق دسوکوڠ دبيناٴن اين" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "بوڽي دڽهبيسوکن" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "جارق ڤندڠ دتوکر ک%d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "جارق ڤندڠ براد دتاهڤ مکسيموم: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "جارق ڤندڠ براد دتاهڤ مينيموم: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "ککواتن بوڽي داوبه کڤد %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "رڠک داواي دتونجوقکن" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "زوم سدڠ دلومڤوهکن اوليه ڤرماٴينن اتاو مودس" + +#: src/client/game.cpp +msgid "ok" +msgstr "اوکي" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "سيمبڠ دسمبوڽيکن" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "سيمبڠ دتونجوقکن" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "ڤاڤر ڤندو (HUD) دسمبوڽيکن" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "ڤاڤر ڤندو (HUD) دتونجوقکن" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "ڤمبوکه دسمبوڽيکن" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "ڤمبوکه دتونجوقکن (هلامن %d دري %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "اڤليکاسي" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "کونچي حروف بسر" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Ctrl" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "باواه" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "ڤادم EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "لاکوکن" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "بنتوان" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME - تريما" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME - توکر" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME - کلوار" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME - توکر مود" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME - تيدقتوکر" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "ککيري" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "بوتڠ کيري" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Ctrl کيري" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "مينو کيري" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Shift کيري" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Windows کيري" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "بوتڠ تڠه" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "کونچي اڠک" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "ڤد اڠک *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "ڤد اڠک +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "ڤد اڠک -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "ڤد اڠک ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "ڤد اڠک /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "ڤد اڠک 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "ڤد اڠک 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "ڤد اڠک 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "ڤد اڠک 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "ڤد اڠک 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "ڤد اڠک 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "ڤد اڠک 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "ڤد اڠک 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "ڤد اڠک 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "ڤد اڠک 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "ڤادم OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "مولا ماٴين" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Print Screen" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "ککانن" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "بوتڠ کانن" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Ctrl کانن" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "مينو کانن" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Shift کانن" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Windows کانن" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "کونچي تاتل" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Select" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "تيدور" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "تڠکڤ ݢمبر سکرين" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "سلاڠ" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "اتس" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "بوتڠ X نومبور 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "بوتڠ X نومبور 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "زوم" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "ڤتا ميني دسمبوڽيکن" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "ڤتا ميني دالم مود رادر⹁ زوم 1x" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "ڤتا ميني دالم مود ڤرموکاٴن⹁ زوم 1x" + +#: src/client/minimap.cpp +#, fuzzy +msgid "Minimap in texture mode" +msgstr "سايز تيکستور مينيموم" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "ݢاݢل مموات تورون $1" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "تروسکن" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "\"ايستيميوا\" = ڤنجت تورون" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "أوتوڤرݢرقن" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "لومڤت أوتوماتيک" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "کبلاکڠ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "توکر کاميرا" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "سيمبڠ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "ارهن" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "کونسول" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "کورڠکن جارق" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "ڤرلاهنکن بوڽي" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "تکن دوا کالي \"لومڤت\" اونتوق منوݢول تربڠ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "جاتوهکن" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "کدڤن" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "ناٴيقکن جارق" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "کواتکن بوڽي" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "اينۏينتوري" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "لومڤت" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "ککونچي تله دݢوناکن اونتوق فوڠسي لاٴين" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "ارهن تمڤتن" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "بيسو" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "ايتم ستروسڽ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "ايتم سبلومڽ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "جارق ڤميليهن" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "تڠکڤ لاير" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "سلينڤ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "توݢول ڤاڤر ڤندو (HUD)" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "توݢول لوݢ سيمبڠ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "توݢول ڤرݢرقن ڤنتس" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "توݢول تربڠ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "توݢول کابوت" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "توݢول ڤتا ميني" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "توݢول تمبوس بلوک" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "توݢول ڤرݢرقن منچورم" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "تکن ککونچي" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "توکر" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "کات لالوان بارو" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "کات لالوان لام" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "کات لالوان تيدق ڤادن!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "کلوار" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "دبيسوکن" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "ککواتن بوڽي: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "ms_Arab" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "سيلا ڤيليه سواتو نام!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) منتڤکن کدودوقن کايو بديق ماي.\n" +"جيک دلومڤوهکن⹁ کدودوقن تڠه اونتوق کايو بديق ماي اکن دتنتوکن برداسرکن کدودوقن " +"سنتوهن ڤرتام." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) ݢوناکن کايو بديق ماي اونتوق ڤيچو بوتڠ \"aux\".\n" +"جيک دبوليهکن⹁ کايو بديق ماي جوݢ اکن منکن بوتڠ \"aux\" اڤابيلا براد دلوار " +"بولتن اوتام." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) اوفسيت فراکتل دري ڤوست دنيا دالم اونيت 'سکال'.\n" +"بوليه ݢونا اونتوق ڤيندهکن تيتيق يڠ دايڠيني ک(0, 0)\n" +"اونتوق چيڤت تيتيق کلاهيرن يڠ سسواي⹁ اتاو اونتوق\n" +"ممبوليهکن 'زوم ماسوق' ڤد تيتيق يڠ دايڠينکن\n" +"دڠن مناٴيقکن 'سکال'.\n" +"نيلاي لالاي دسسوايکن اونتوق تيتيق کلاهيرن سسواي اونتوق سيت Mandelbrot\n" +"دڠن ڤاراميتر لالاي⹁ اي موڠکين ڤرلو داوبه اونتوق سيتواسي يڠ لاٴين.\n" +"جولت کاسرڽ -2 سهيڠݢ 2. داربکن دڠن 'سکال' اونتوق اوفسيت دالم نود." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "اون 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "مود 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "ککواتن ڤارالکس مود 3D" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"سوکوڠن 3D.\n" +"يڠ دسوکوڠ ڤد ماس اين:\n" +"- تيادا: تيادا اٴوتڤوت 3D.\n" +"- اناݢليف: 3D ورنا بيرو\\موره.\n" +"- سلڠ-سلي: ݢاريس ݢنڤ\\ݢنجيل برداسرکن سوکوڠن سکرين ڤولاريساسي.\n" +"- اتس-باوه: ڤيسه سکرين اتس\\باوه.\n" +"- کيري-کانن: ڤيسه سکرين کيري\\کانن.\n" +"- سيلڠ ليهت: 3D مات برسيلڠ\n" +"- سيلق هلامن: 3D براساسکن ڤنيمبل کواد.\n" +"امبيل ڤرهاتين بهاوا مود سلڠ-سلي ممرلوکن ڤمبايڠ." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"بنيه ڤتا يڠ دڤيليه اونتوق ڤتا بارو⹁ بيارکن کوسوڠ اونتوق بنيه راوق.\n" +"تيدق دݢوناڤاکاي سکيراڽ منچيڤتا دنيا بارو ملالوٴي مينو اوتام." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "ميسيج يڠ اکن دڤاڤرکن کڤد سموا کليئن اڤابيلا ڤلاين رونتوه." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "ميسيج يڠ اکن دڤاڤرکن دکت سموا کليئن اڤابيلا ڤلاين دتوتوڤ." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "ڤچوتن دأودارا" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "جارق بلوک اکتيف" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "جارق ڤڠهنترن اوبجيک اکتيف" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"علامت اونتوق مڽمبوڠ.\n" +"بيار کوسوڠ اونتوق ممولاکن ڤلاين ڤرماٴينن تمڤتن.\n" +"امبيل ڤرهاتيان بهاوا ميدن علامت دالم مينو اوتام مڠاتسي تتڤن اين." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "منمبه ڤرتيکل اڤابيلا مڠݢالي نود." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"لارسکن کونفيݢوراسي DPI کسکرين اندا (بوکن X11/Android سهاج) چونتوه اونتوق " +"سکرين 4K." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "تمبه نام ايتم" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "تتڤن مندالم" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"اوبه لڠکوڠ چهاي دڠن مڠناکن 'ڤمبتولن ݢام'.\n" +"نيلاي تيڠݢي بواتکن اساس چهاي تڠه دان رنده لبيه تراڠ.\n" +"نيلاي '1.0' اکن بيارکن لڠکوڠ چهاي اصل تيدق براوبه.\n" +"تتڤن اين هاڽ ممبري کسن مندالم ڤد چهاي ماتاهاري\n" +"دان چهاي بواتن⹁ کسنڽ ڤد چهاي مالم امت رنده." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "سنتياس تربڠ دان برݢرق ڤنتس" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "ݢام اوکلوسي سکيتر" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "جومله ميسيج ڤماٴين بوليه هنتر ستياڤ 10 ساٴت." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "ڤناڤيسن انيسوتروڤيک" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "عمومکن ڤلاين" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "عمومکن کسناراي ڤلاين اين." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "تمبه نام ايتم" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "تمبه نام ايتم کتيڤ التن." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "اينرسيا لڠن" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"اينرسيا لڠن⹁ ممبريکن ڤرݢرقن لڠن يڠ\n" +"لبيه رياليستيک اڤابيلا کاميرا دݢرقکن." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "مينتا سمبوڠ سمولا سلڤس کرونتوهن" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "ککونچي أوتوڤرݢرقن" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "لومڤت هالڠن ساتو-نود سچارا أوروماتيک." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "ملاڤورکن کڤد سناراي ڤلاين سچارا اٴوتوماتيک." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "أوتوسيمڤن سايز سکرين" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "مود سکال أوتوماتيک" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "ککونچي لومڤت" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key for climbing/descending" +msgstr "ککونچي اونتوق ممنجت\\منورون" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "ککونچي کبلاکڠ" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "کأيستيميواٴن اساس" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "ڤناڤيسن بيلينيار" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "علامت ايکتن" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "لالوان فون تبل دان ايتاليک" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "لالوان فون monospace تبل دان ايتاليک" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "لالوان فون تبل" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "لالوان فون monospace تبل" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "بينا دالم ڤماٴين" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "توکر کاميرا" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"جارق کاميرا 'برهمڤيرن ساته کتيڤن' دالم نيلاي نود⹁ انتارا 0 دان 0.5.\n" +"هاڽ برکسن دڤلاتفورم GLES. کباڽقن ڤڠݢونا تيدق ڤرلو مڠاوبه نيلاي اين.\n" +"مناٴيقکن نيلاي بوليه کورڠکن ارتيفک ڤد GPU يڠ لبيه لمه.\n" +"0.1 = اصل⹁ 0.25 = نيلاي باݢوس اونتوق تابليت يڠ لبيه لمه." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "ڤلمبوتن کاميرا" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "ڤلمبوتن کاميرا دالم مود سينماتيک" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "ککونچي توݢول کمس کيني کاميرا" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"ڤرتڠهن جولت تولقن لڠکوڠ چهاي.\n" +"دمان 0.0 اياله ارس چهاي مينيموم⹁ 1.0 اياله مکسيموم." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "نيلاي امبڠ تندڠ ميسيج سيمبڠ" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "ارهن" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "سايز فون سيمبڠ" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "ککونچي سيمبڠ" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "حد کيراٴن ميسيج سيمبڠ" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "فورمت ميسيج سيمبڠ" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "نيلاي امبڠ تندڠ ميسيج سيمبڠ" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "ڤنجڠ مکسيموم ميسيج سيمبڠ" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "ککونچي توݢول سيمبڠ" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "سيمبڠ دتونجوقکن" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "مود سينماتيک" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "ککونچي مود سينماتيک" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "برسيهکن تيکستور لوت سينر" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "کليئن" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "مودس کليئن" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "مودس کليئن" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "ججاري اون" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "اون" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "اون ايت ايفيک ڤد ڤيهق کليئن." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "اون دالم مينو" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "کابوت برورنا" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Colored shadows" +msgstr "کابوت برورنا" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "ککونچي ارهن" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "سمبوڠ کاچ" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "سمبوڠ کڤلاين ميديا لوارن" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "سمبوڠکن کاچ جيک دسوکوڠ اوليه نود." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "نيلاي الڤا کونسول" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "ورنا کونسول" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "کتيڠݢين کونسول" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "کدڤن برتروسن" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"ڤرݢرقن کدڤن برتروسن⹁ دتوݢول اوليه ککونچي أوتوڤرݢرقن.\n" +"تکن ککونچي أوتوڤرݢرقن لاݢي اتاو ڤرݢرقن کبلاکڠ اونتوق ملومڤوهکنڽ." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "کاولن" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"مڠاول ڤنجڠ کيترن سياڠ\\مالم.\n" +"چونتوهڽ:\n" +"72 اونتوق 20 مينيت⹁ 360 اونتوق 4 مينيت⹁ 1 اونتوق 24 جم⹁ 0 اونتوق " +"سياڠ\\مالم\\لاٴين٢ ککل تيدق بروبه." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "ميسيج کرونتوهن" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "کرياتيف" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "نيلاي الفا ررمبوت سيلڠ" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "نيلاي الفا ررمبوت سيلڠ (کلݢڤن⹁ انتارا 0 دان 255)." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "ورنا ررمبوت سيلڠ" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "بوليه چدرا" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "ککونچي توݢول معلومت ڽهڤڤيجت" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "ککونچي ڤرلاهنکن بوڽي" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "ڤچوتن لالاي" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "ڤرماٴينن لالاي" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"ڤرماٴينن لالاي يڠ اکن دݢوناکن کتيک منچيڤتا دنيا بارو.\n" +"تتڤن اين اکن دأتسي اڤابيلا ممبوات دنيا دري مينو اوتام." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "کات لالوان لالاي" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "کأيستيميواٴن لالاي" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "ساٴيز تيندنن لالاي" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"منتعريفکن جارق مکسيموم اونتوق ڤميندهن ڤماٴين دالم اونيت بلوک (0 = تيادا حد)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"لڠه ماس دانتارا کمسکيني ججاريڠ دکت کليئن دالم اونيت ميليساٴت (ms). مناٴيقکن " +"نيلاي\n" +"اين اکن مڠورڠکن کادر کمسکيني ججاريڠ⹁ لالو مڠورڠکن کترن دکت کليئن يڠ لبيه " +"ڤرلاهن." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "لڠه ڤڠهنترن بلوک سلڤس ڤمبيناٴن" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "جومله لڠه اونتوق منونجوقکن تيڤ التن⹁ دڽاتاکن دالم ميليساٴت." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"ڤريهل ڤلاين ڤرماٴينن⹁ اونتوق دڤاڤرکن اڤابيلا ڤماٴين ماسوق دان جوݢ دالم " +"سناراٴي ڤلاين." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "مڽهسݢرقکن انيماسي بلوک" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "هياسن" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "ککومچي ککانن" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "ڤرتيکل کتيک مڠݢالي" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "ملومڤوهکن انتيتيڤو" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "منولق کات لالوان کوسوڠ" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "نام دوماٴين ڤلاين ڤرماٴينن⹁ اونتوق دڤاڤرکن دالم سناراي ڤلاين ڤرماٴينن." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "تکن \"لومڤت\" دوا کالي اونتوق تربڠ" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "تکن بوتڠ \"لومڤت\" سچارا چڤت دوا کالي اونتوق منوݢول مود تربڠ." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "ککونچي جاتوهکن ايتم" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"ممبوليهکن سوکوڠن ڤمبواتن مودس Lua دکت کليئن.\n" +"سوکوڠن اين دالم اوجيکاجي دان API بوليه براوبه." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "ممبوليهکن تتيڠکڤ کونسول" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable creative mode for all players" +msgstr "ممبوليهکن مود کرياتيف اونتوق ڤتا بارو دچيڤتا." + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "ممبوليهکن کايو بديق" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "ممبوليهکن سوکوڠن سالوران مودس." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "ممبوليهکن ڤماٴين منريما کچدراٴن دان ماتي." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "ممبوليهکن اينڤوت ڤڠݢونا سچارا راوق (هاڽ اونتوق ڤرچوباٴن)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"ممبوليهکن ڤنچهاياٴن لمبوت دڠن اوکلوسي سکيتر يڠ ريڠکس.\n" +"لومڤوهکنڽ اونتوق کلاجوان اتاو اونتوق کليهتن بربيذا." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"بوليهکن تتڤن اونتوق ملارڠ کليئن لام درڤد مڽمبوڠ.\n" +"کليئن لام ماسيه سسواي دݢوناکن جک مريک تيدق رونتوه (کريش) اڤابيلا چوبا اونتوق " +"مڽمبوڠ کڤلاين بهارو⹁\n" +"تتاڤي مريک موڠکين تيدق ممڤو مڽوکوڠ سموا صيفت بهارو يڠ اندا سڠکاکن." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"ممبوليهکن ڤڠݢوناٴن ڤلاين ميديا جارق جاٴوه (جک دبريکن اوليه ڤلاين).\n" +"ڤلاين جارق جاٴوه مناورکن چارا لبيه چڤت اونتوق موات تورون ميديا (چونتوه " +"تيکستور)\n" +"اڤابيلا مڽمبوڠ کڤلاين ڤرماٴينن." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"ممبوليهکن اوبجيک ڤنيمبل بوچو.\n" +"اي ڤاتوت منيڠکتکن ڤريستاسي ݢرافيک دڠن باڽق." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"ڤندارب اونتوق ڤڠاڤوڠن ڤندڠن.\n" +"چونتوهڽ: 0 اونتوق تيادا اڤوڠن⁏ 1.0 اونتوق بياسا⁏ 2.0 اونتوق دوا کالي ݢندا." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"ممبوليهکن\\ملومڤوهکن ڤنجالنن ڤلاين IPv6.\n" +"دأبايکن جک تتڤن bind_address دتتڤکن.\n" +"ممرلوکن تتڤن enable_ipv6 دبوليهکن." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"ممبوليهکن ڤمتاٴن تونا سينماتيک 'Uncharted 2' (انچرتد ثو) اوليه Hable " +"(هيبل).\n" +"مڽلاکوکن لڠکوڠ تونا فيلم فوتوݢرافي دان چارا اي مڠاڠݢرکن ڤنمڤيلن ايميج جارق\n" +"ديناميک تيڠݢي. بيذا جلس ڤرتڠهن جولت دتيڠکتکن سديکيت⹁ تونجولن دان بايڠن\n" +"دممڤتکن سچارا برانسور." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "ممبوليهکن انيماسي ايتم دالم اينۏينتوري." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "ممبوليهکن ڤڠاݢريݢتن ججاريڠ يڠ دڤوتر دڤکسي Y ايايت (facedir)." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "ممبوليهکن ڤتا ميني." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"ممبوليهکن سيستم بوڽي.\n" +"جک دلومڤوهکن⹁ اي اکن ملومڤوهکن کسموا بوڽي دسموا تمڤت\n" +"دان کاولن بوڽي دالم ڤرماٴينن تيدق اکن برفوڠسي.\n" +"ڤڠوبهن تتڤن اين ممرلوکن ڤرمولاٴن سمولا." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "FPS when unfocused or paused" +msgstr "بيڠکاي ڤر ساٴت (FPS) مکسيما اڤابيلا ڤرماٴينن دجيداکن." + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "فکتور اڤوڠن کجاتوهن" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "لالوان فون برباليق" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "ککونچي ڤرݢرقن ڤنتس" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "ڤرݢرقن ڤنتس" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"برݢرق ڤنتس (دڠن ککونچي \"ايستيميوا\").\n" +"اين ممرلوکن کأيستيميواٴن \"ڤرݢرقن ڤنتس\" دالم ڤلاين ترسبوت." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "ميدن ڤندڠ" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "ميدن ڤندڠ دالم درجه سودوت." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"فاٴيل دالم لالوان client/serverlist/ يڠ مڠندوڠي سناراي\n" +"ڤلاين کݢمرن يڠ دڤاڤرکن دالم تب ڤماٴين راماي." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "ڤمتاٴن تونا سينماتيک" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"تيکستور يڠ دتاڤيس بوليه سباتيکن نيلاي RGB دڠن جيرن يڠ لوت سينر سڤنوهڽ⹁\n" +"يڠ مان ڤڠاوڤتيموم PNG سريڠ ابايکن⹁ کادڠکال مڽببکن سيسي ݢلڤ اتاو تراڠ ڤد\n" +"تيکستور لوت سينر. ݢونا ڤناڤيسن اين اونتوق ممبرسيهکن تيکستور ترسبوت کتيک\n" +"اي سدڠ دمواتکن." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "انتيالياس:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "بنيه ڤتا تتڤ" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "کايو بديق ماي تتڤ" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "ککونچي تربڠ" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "تربڠ" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "کابوت" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "مولا کابوت" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "ککونچي توݢول کابوت" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "سايز فون" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "فون تبل سچارا لالايڽ" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "فون ايتاليک سچارا لالايڽ" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "بايڠ فون" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "نيلاي الفا بايڠ فون" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "سايز فون" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "سايز فون باݢي فون لالاي دالم اونيت تيتيق (pt)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "سايز فون باݢي فون monospace دالم اونيت تيتيق (pt)." + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"سايز فون توليسن سيمبڠ بارو٢ اين دان ڤروم دالم اونيت تيتيق (pt).\n" +"نيلاي 0 اکن مڠݢوناکن سايز فون لالاي." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"فورمت ميسيج سيمبڠ ڤماٴين. رينتيتن بريکوت اياله ڤمݢڠ تمڤت يڠ صح:\n" +"@name (اونتوق نام)⹁ @message (اونتوق ميسيج)⹁ @timestamp (ڤيليهن⹁ اونتوق چوڤ " +"ماس)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "فورمت يڠ دݢوناکن اونتوق تڠکڤ لاير." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "ورنا لاتر بلاکڠ لالاي فورمسڤيک" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "کلݢڤن لاتر بلاکڠ لالاي فورمسڤيک" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "ورنا لاتر بلاکڠ سکرين-ڤنوه فورمسڤيک" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "کلݢڤن لاتر بلاکڠ سکرين-ڤنوه فورمسڤيک" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "ورنا لاتر بلاکڠ اصل فورمسڤيک (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "کلݢڤن اصل لاتر بلاکڠ فورمسڤيک (انتارا 0 دان 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "ورنا لاتر بلاکڠ سکرين-ڤنوه فورمسڤيک (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "کلݢڤن لاتر بلاکڠ سکرين-ڤنوه فورمسڤيک (انتارا 0 دان 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "ککونچي کدڤن" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "بهاݢين درڤد جارق بوليه ليهت دمان کابوت مولا دجان" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"سجاٴوه ماناکه بلوک٢ دهنتر کڤد کليئن⹁ دڽاتاکن دالم اونيت بلوکڤتا (16 نود)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"درڤد جارق کليئن داڤت تاهو تنتڠ اوبجيک⹁ دڽاتاکن دالم بلوکڤتا (16 نود).\n" +"\n" +"منتڤکن نيلاي اين لبيه تيڠݢي درڤد جارق بلوک اکتيف (active_block_range) جوݢ\n" +"اکن مڽببکن ڤلاين اونتوق مڠکلکن اوبجيک اکتيف سهيڠݢ کجارق اين\n" +"دالم اره ڤندڠن ڤماٴين. (اين بوليه ايلقکن موب تيبا٢ هيلڠ دري ڤندڠن)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "سکرين ڤنوه" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "مود سکرين ڤنوه." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "سکال GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "ڤناڤيس سکال GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "ڤناڤيس سکال GUI جنيس txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "ڤرماٴينن" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"کچرونن لڠکوڠ چهاي ڤد تاهڤ چهاي مکسيموم.\n" +"مڠاول بيذا جلس تاهڤ چهاي ترتيڠݢي." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"کچرونن لڠکوڠ چهاي ڤد تاهڤ چهاي مينيموم.\n" +"مڠاول بيذا جلس تاهڤ چهاي ترنده." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "ݢرافيک" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "ݢرافيک" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "ݢرافيک" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "سکال GUI" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "ککونچي منوݢول ڤاڤر ڤندو (HUD)" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "کومڤونن تيڠݢي سايز تتيڠکڤ اول." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "لامن اوتام ڤلاين ڤرماٴينن⹁ اونتوق دڤاڤرکن دالم سناراي ڤلاين ڤرماٴينن." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"ڤچوتن منداتر دأودارا اڤابيلا ملومڤت اتاو جاتوه⹁\n" +"دالم اونيت نود ڤر ساٴت ڤر ساٴت." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"ڤچوتن منداتر دان منݢق اتس تانه اتاو کتيک ممنجت⹁\n" +"دالم اونيت نود ڤر ساٴت ڤر ساٴت." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "ککونچي ايتم ستروسڽ دالم هوتبر" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "ککونچي ايتم سبلومڽ دالم هوتبر" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "ککونچي سلوت هوتبر 1" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "ککونچي سلوت هوتبر 10" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "ککونچي سلوت هوتبر 11" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "ککونچي سلوت هوتبر 12" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "ککونچي سلوت هوتبر 13" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "ککونچي سلوت هوتبر 14" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "ککونچي سلوت هوتبر 15" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "ککونچي سلوت هوتبر 16" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "ککونچي سلوت هوتبر 17" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "ککونچي سلوت هوتبر 18" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "ککونچي سلوت هوتبر 19" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "ککونچي سلوت هوتبر 2" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "ککونچي سلوت هوتبر 20" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "ککونچي سلوت هوتبر 21" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "ککونچي سلوت هوتبر 22" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "ککونچي سلوت هوتبر 23" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "ککونچي سلوت هوتبر 24" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "ککونچي سلوت هوتبر 25" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "ککونچي سلوت هوتبر 26" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "ککونچي سلوت هوتبر 27" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "ککونچي سلوت هوتبر 28" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "ککونچي سلوت هوتبر 29" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "ککونچي سلوت هوتبر 3" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "ککونچي سلوت هوتبر 30" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "ککونچي سلوت هوتبر 31" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "ککونچي سلوت هوتبر 32" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "ککونچي سلوت هوتبر 4" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "ککونچي سلوت هوتبر 5" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "ککونچي سلوت هوتبر 6" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "ککونچي سلوت هوتبر 7" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "ککونچي سلوت هوتبر 8" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "ککونچي سلوت هوتبر 9" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"سچڤت مان ݢلورا چچاٴير اکن برݢرق. نيلاي تيڠݢي = لبيه چڤت.\n" +"جيک نيلاي نيݢاتيف⹁ ݢلورا چچاٴير اکن برݢرق کبلاکڠ.\n" +"ممرلوکن تتڤن چچاٴير برݢلورا دبوليهکن." + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "ڤلاين IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"جيک بيڠکاي ڤر ساٴت (FPS) اکن ناٴيق لبيه تيڠݢي درڤد نيلاي اين⹁\n" +"حدکن اي دڠن تيدورکنڽ سوڤايا تيدق بازيرکن کواسا CPU دڠن سيا٢." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"جيک دلومڤوهکن⹁ ککونچي \"ايستيميوا\" اکن دݢوناکن اونتوق تربڠ لاجو\n" +"سکيراڽ کدوا-دوا مود تربڠ دان مود ڤرݢرقن ڤنتس دبوليهکن." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"جيک دبوليهکن برسام مود تربڠ⹁ ڤماٴين بوليه تربڠ منروسي نود ڤڤجل.\n" +"اين ممرلوکن کأيستيميواٴن \"تمبوس بلوک\" دالم ڤلاين ترسبوت." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"جيک دبوليهکن⹁ ککونچي \"ايستيميوا\" اکن دݢوناکن اونتوق ڤنجت کباوه دان\n" +"تورون دالم مود تربڠ⹁ مڠݢنتيکن ککونچي \"سلينڤ\"." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"ممبوليهکن ڤڠصحن ڤندفترن اڤابيلا مڽمبوڠ کڤد ڤلاين.\n" +"جک دلومڤوهکن⹁ اکاٴون بارو اکن ددفترکن سچارا اٴوتوماتيک." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"جک دبوليهکن⹁ سموا تيندقن اکن دراکم اونتوق ݢولوڠ باليق.\n" +"ڤيليهن اين هاڽ دباچ کتيک ڤلاين برمولا." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "جک دبوليهکن⹁ اي اکن ملومڤوهکن ڤنچݢهن ڤنيڤوان دالم ڤماٴين راماي." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"جيک دبوليهکن⹁ اي ممبواتکن اره ڤرݢرقن ريلاتيف دڠن ڤيچ ڤماٴين اڤابيلا تربڠ " +"اتاو برنڠ." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "جک دبوليهکن⹁ ڤماٴين٢ بارو تيدق بوليه ماسوق دڠن کات لالوان يڠ کوسوڠ." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"جيک دبوليهکن⹁ اندا بوليه ملتق بلوک دکدودوقن برديري (کاکي + ارس مات).\n" +"اين ساڠت برݢونا اڤابيلا بکرجا دڠن کوتق نود دکاوسن يڠ کچيل." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" +"جک تتڤن اين دتتڤکن⹁ ڤماٴين اکن سنتياسا دلاهيرکن (سمولا) دکت کدودوقن يڠ " +"دبريکن." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"نيلاي الفا لاتر بلاکڠ کونسول سيمبڠ دالم ڤرماٴينن (کلݢڤن⹁ انتارا 0 دان 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "ورنا لاتر بلاکڠ کونسول سيمبڠ دالم ڤرماٴينن (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"نيلاي کتيڠݢين کونسول سيمبڠ دالم ڤرماٴينن⹁ انتارا 0.1 (10%) دان 1.0 (100%)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "ککونچي کواتکن بوڽي" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"سلڠ ماس دأنتارا ڤڽيمڤنن ڤروبهن ڤنتيڠ دالم دنيا⹁ دڽاتاکن دالم اونيت ساٴت." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "سلڠ دأنتارا ڤڠهنترن معلومت ماس ڤلاين کڤد کليئن." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "انيماسي ايتم اينۏينتوري" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "ککونچي اينۏينتوري" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "تتيکوس سوڠسڠ" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "مڽوڠسڠکن ڤرݢرقن تتيکوس منݢق." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "لالوان فون ايتاليک" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "لالوان فون monospace ايتاليک" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "TTL اينتيتي ايتم" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID کايو بديق" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "سلڠ ماس ڤڠاولڠن بوتڠ کايو بديق" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick dead zone" +msgstr "جنيس کايو بديق" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "کڤيکاٴن فروستوم کايو بديق" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "جنيس کايو بديق" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "ککونچي لومڤت" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مڠورڠکن جارق ڤندڠ.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق ممڤرلاهنکن بوڽي.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق ملومڤت.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منجاتوهکن ايتم يڠ سدڠ دڤيليه.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منمبه جارق ڤندڠ.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مڠواتکن بوڽي.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق ملومڤت.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق برݢرق ڤنتس دالم مود ڤرݢرقن ڤنتس.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مڠݢرقکن ڤماٴين کبلاکڠ.\n" +"جوݢ اکن ملومڤوهکن أوتوڤرݢرقن⹁ اڤابيلا اکتيف.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مڠݢرقکن ڤماٴين کدڤن.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مڠݢرقکن ڤماٴين ککيري.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مڠݢرقکن ڤماٴين ککانن.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق ممبيسوکن ڤرماٴينن.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق ممبوک تتيڠکڤ سيمبڠ اونتوق مناٴيڤ ارهن.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق ممبوک تتيڠکڤ سيمبڠ اونتوق مناٴيڤ ارهن تمڤتن.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق ممبوک تتيڠکڤ سيمبڠ.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق ممبوک اينۏينتوري.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق ملومڤت.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-11 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-12 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-13 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-14 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-15 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-16 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-17 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-18 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-19 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-20 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-21 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-22 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-23 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-24 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-25 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-26 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-27 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-28 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-29 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-30 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-31 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-32 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-8 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-5 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ڤرتام دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-4 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه ايتم ستروسڽ ددالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-9 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه بارڠ سبلومڽ دهوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-2 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-7 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-6 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-10 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مميليه سلوت ک-3 دالم هوتبر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مڽلينڤ.\n" +"جوݢ دݢوناکن اونتوق تورون باواه کتيک ممنجت دان دالم اٴير جيک تتڤن " +"aux1_descends دلومڤوهکن.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق برتوکر انتارا کاميرا اورڠ ڤرتام دان کتيݢ.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منڠکڤ ݢمبر لاير.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول أوتوڤرݢرقن.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول مود سينماتيک.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول ڤاڤرن ڤتا ميني.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول مود ڤرݢرقن ڤنتس.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول مود تربڠ.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول مود تمبوس بلوک.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول مود ڤرݢرقن ڤيچ.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول ڤڠمسکينين کاميرا. هاڽ دݢوناکن اونتوق ڤمباڠونن.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول ڤاڤرن سيمبڠ.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول ڤاڤرن معلومت ڽهڤڤيجت.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول ڤاڤرن کابوت.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول ڤاڤر ڤندو (HUD).\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول ڤاڤرن کونسول سيمبڠ بسر.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول ڤمبوکه. دݢوناکن اونتوق ڤمباڠونن.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق منوݢول جارق ڤندڠن تيادا حد.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ککونچي اونتوق مڠݢوناکن ڤندڠن زوم اڤابيلا دبنرکن.\n" +"ليهت http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "تندڠ ڤماٴين يڠ مڠهنتر ميسيج لبيه درڤد X ستياڤ 10 ساٴت." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "ککونچي کونسول سيمبڠ بسر" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "ݢاي داٴون" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"ݢاي داٴون:\n" +"- براݢم: سموا سيسي کليهتن\n" +"- ريڠکس: هاڽ سيسي لوار کليهتن⹁ جيک special_tiles يڠ دتنتوکن دݢوناکن\n" +"- لݢڤ: ملومڤوهکن لوت سينر" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "ککونچي ککيري" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"ڤنجڠ ݢلورا چچاٴير.\n" +"ممرلوکن تتڤن چچاٴير برݢلورا دبوليهکن." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "تولقن لڠکوڠ چهاي" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "تيتيق تڠه تولقن لڠکوڠ چهاي" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "سيبرن تولقن لڠکوڠ چهاي" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "ݢام لڠکوڠ چهاي" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "کچرونن تيڠݢي لڠکوڠ چهاي" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "کچرونن رنده لڠکوڠ چهاي" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "ڤنچهاياٴن لمبوت" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"بواتکن ورنا کابوت دان لاڠيت برݢنتوڠ کڤد وقتو (فجر\\ماتاهاري) دان اره ڤندڠ." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "بواتکن سموا چچاٴير منجادي لݢڤ" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "ديريکتوري ڤتا" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "سلڠ ماس ڤڽيمڤنن ڤتا" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "حد بلوک ڤتا" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "لڠه ماس ڤنجاناٴن ججاريڠ بلوک ڤتا" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" +"ساٴيز کيش بلوکڤتا اونتوق ڤنجان ججاريڠ بلوکڤتا دالم اونيت ميݢاباٴيت (MB)" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "حد ماس ڽهموات بلوک ڤتا" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "جارق مکسيموم ڤڠهنترن بلوک" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "بيڠکيسن مکسيما ستياڤ للرن" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "FPS مکسيما" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "بيڠکاي ڤر ساٴت (FPS) مکسيما اڤابيلا ڤرماٴينن دجيداکن." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "جومله مکسيموم بلوک يڠ دڤقسا موات" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "ليبر هوتبر مکسيما" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"جومله بلوک مکسيموم يڠ دهنتر سرنتق ڤر کليئن.\n" +"جومله مکسيموم دکيرا سچارا ديناميک:\n" +"جومله_مکس = بولت_ناٴيق((#کليئن + ڤڠݢونا_مکس) * ڤر_کليئن \\ 4 )" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "جومله مکسيموم بلوکڤتا يڠ دڤقسا موات." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"جومله بلوک ڤتا مکسيموم يڠ کليئن بوليه سيمڤن دالم ميموري.\n" +"تتڤکن کڤد -1 اونتوق جومله تنڤ حد." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"جومله مکسيما بيڠکيسن يڠ دهنتر ڤد ستياڤ لڠکه ڤڠهنترن⹁\n" +"جک اندا ممڤوڽاٴي سمبوڠن يڠ ڤرلاهن ماک چوبا کورڠکنڽ⹁\n" +"نامون جاڠن کورڠکن کڤد نيلاي دباوه ݢندا دوا جومله کليئن ساسرن." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "حد جومله ڤماٴين مکسيموم يڠ بوليه مڽمبوڠ سرنتق." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "جومله مکسيموم ميسيج سيمبڠ تربارو اونتوق دتونجوقکن" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"ڤرکادرن مکسيما اونتوق تتيڠکڤ سماس يڠ دݢوناکن اونتوق هوتبر.\n" +"برݢونا جيک اد سسواتو يڠ اکن دڤاڤرکن دسبله کانن اتاو کيري هوتبر." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "جومله بلوک مکسيموم يڠ دهنتر سرنتق کڤد ستياڤ کليئن" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "ساٴيز مکسيموم باريس ݢيلير کلوار سيمبڠ" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"ساٴيز مکسيموم باريس ݢيلير کلوار سيمبڠ.\n" +"0 اونتوق لومڤوهکن باريس ݢيلير دان -1 اونتوق بواتکن ساٴيز باريس ݢيلير تيادا " +"حد." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "حد جومله ڤڠݢونا" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "کيش ججاريڠ" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "ميسيج هاري اين" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "ميسيج هاري اين يڠ اکن دڤاڤرکن کڤد ڤماٴين يڠ مڽمبوڠ." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "قاعده يڠ دݢوناکن اونتوق منونجولکن اوبجيک دڤيليه." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "ڤتا ميني" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "ککونچي ڤتا ميني" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "کتيڠݢين ايمبسن ڤتا ميني" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "سايز تيکستور مينيموم" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "ڤمتاٴن ميڤ" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "سالوران مودس" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Modifies the size of the HUD elements." +msgstr "مڠاوبه سايز ايليمن ڤالڠ ڤاڤر ڤندو (hudbar)." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "لالوان فون monospace" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "سايز فون monospace" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "سايز فون monospace" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "کڤيکاٴن تتيکوس" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "ڤندارب کڤيکاٴن تتيکوس." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"ڤندارب اونتوق اڤوڠن تيمبول تڠݢلم.\n" +"چونتوهڽ: 0 اونتوق تيادا اڤوڠن⁏ 1.0 اونتوق بياسا⁏ 2.0 اونتوق دوا کالي ݢندا." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "ککونچي بيسو" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "بيسوکن بوڽي" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"نام ڤلاين ڤرماٴينن⹁ اونتوق دڤاڤرکن اڤابيلا ڤماٴين ماسوق دان جوݢ دالم سناراي " +"ڤلاين." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "دکت ساته" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"ڤورت رڠکاين اونتوق دڠر (UDP).\n" +"نيلاي اين اکن دأتسي اڤابيلا ممولاکن ڤلاين دري مينو اوتام." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "رڠکاين" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "ڤڠݢونا بارو مستي مماسوقکن کات لالوان اين." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "تمبوس بلوک" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "ککونچي تمبوس بلوک" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "تونجولن نود" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "تونجولن نود" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "چچاٴير لݢڤ" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "کلݢڤن (الفا) بايڠ بلاکڠ فون لالاي⹁ نيلاي انتارا 0 دان 225." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"بوک مينو جيدا اڤابيلا فوکوس تتيڠکڤ هيلڠ.\n" +"تيدق جيدا جيک فورمسڤيک دبوک." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"لالوان فون برباليق.\n" +"جيک تتڤن “freetype” دبوليهکن: اي مستيله فون TrueType.\n" +"جيک تتڤن “freetype” دلومڤوهکن: اي مستيله فون ڤتا بيت اتاو ۏيکتور XML.\n" +"فون اين اکن دݢوناکن باݢي سستڠه بهاس اتاو جيک فون لالاي تيدق ترسديا." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"لالوان اونتوق سيمڤن تڠکڤن لاير. وليه جادي لالوان مطلق اتاو ريلاتيف.\n" +"فولدر اکن دچيڤتا سکيراڽ اي بلوم وجود." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"لالوان کديريکتوري ڤمبايڠ. جيک تيادا لالوان دتعريفکن⹁ لوکاسي لالاي اکن " +"دݢوناکن." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "لالوان کديريکتوري تيکستور. سموا تيکستور دچاري دري سيني داهولو." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"لالوان فون لالاي.\n" +"جيک تتڤن “freetype” دبوليهکن: اي مستيله فون TrueType.\n" +"جيک تتڤن “freetype” دلومڤوهکن: اي مستيله فون ڤتا بيت اتاو ۏيکتور XML.\n" +"فون برباليق اکن دݢوناکن سکيراڽ فون اين تيدق داڤت دمواتکن." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"لالوان فون monospace.\n" +"جيک تتڤن “freetype” دبوليهکن: اي مستيله فون TrueType.\n" +"جيک تتڤن “freetype” دلومڤوهکن: اي مستيله فون ڤتا بيت اتاو ۏيکتور XML.\n" +"فون اين دݢوناکن اونتوق عنصور سڤرتي کونسول دان سکرين ڤمبوکه." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "جيدا کتيک هيلڠ فوکوس تتيڠکڤ" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "ايکوت فيزيک" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "ککونچي ڤرݢرقن ڤيچ" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "مود ڤرݢرقن ڤيچ" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "ککونچي تربڠ" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place repetition interval" +msgstr "سلڠ ڤڠاولڠن کليک کانن" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"ڤماٴين بوليه تربڠ تنڤ ترکسن دڠن ݢراۏيتي.\n" +"اين ممرلوکن کأيستيميواٴن \"تربڠ\" دالم ڤلاين ترسبوت." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "جارق وميندهن ڤماٴين" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "ڤماٴين لاون ڤماٴين" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "ڤناڤيسن بيلينيار" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"ڤورت اونتوق مڽمبوڠ (UDP).\n" +"امبيل ڤرهاتيان بهاوا ميدن ڤورت دالم مينو اوتام مڠاتسي تتڤن اين." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"منچݢه ݢالي دان ڤلتقن درڤد براولڠ کتيک تروس منکن بوتڠ تتيکوس.\n" +"بوليهکن تتڤن اين اڤابيلا اندا ݢالي اتاو لتق سچارا تيدق سڠاج ترلالو کرڤ." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" +"کأيستيميواٴن٢ يڠ بوليه دبريکن اوليه ڤماين يڠ ممڤوڽاٴي کأيستيميواٴن " +"basic_privs" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "ککونچي توݢول ڤمبوکه" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "علامت ڤندڠر Prometheus" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"علامت ڤندڠر Prometheus.\n" +"جک minetest دکومڤيل دڠن تتڤن ENABLE_PROMETHEUS دبوليهکن,\n" +"ممبوليهکن ڤندڠر ميتريک اونتوق Prometheus ڤد علامت برکناٴن.\n" +"ميتريک بوليه دأمبيل د http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"ججاري کلواسن اون دڽاتاکن دالم جومله 64 نود ڤيتق اون.\n" +"نيلاي لبيه دري 26 اکن مولا مڠهاسيلکن ڤموتوڠن تاجم دسودوت کاوسن اون." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "اينڤوت راوق" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "ککونچي جارق ڤميليهن" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "ميسيج سيمبڠ ترکيني" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "لالوان فون بياسا" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "ميديا جارق جاٴوه" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "ڤورت جارق جاٴوه" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"بواڠ کود ورنا درڤد ميسيج سيمبڠ منداتڠ\n" +"ݢوناکن اين اونتوق هنتيکن ڤماٴين درڤد مڠݢوناکن ورنا دالم ميسيج مريک" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "ککومچي ککانن" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "راکمن ݢولوڠ باليق" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "ڤتا ميني بولت" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "ڤڠݢالين دان ڤلتقن سلامت" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "سيمڤن ڤتا يڠ دتريما اوليه کليئن دالم چکرا." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "سيمڤن سايز تتيڠکڤ سچارا أوتوماتيک کتيک داوبه." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "سيمڤن ڤتا دتريما دري ڤلاين ڤرماٴينن" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"مڽسوايکن GUI دڠن نيلاي دتنتوکن اوليه ڤڠݢونا.\n" +"ݢوناکن ڤناڤيس انتيألياس جيرن تردکت اونتوق مڽسوايکن GUI.\n" +"اين ممبوليهکن سيسي تاجم دلمبوتکن⹁ دان سباتيکن ڤيکسل اڤابيلا\n" +"مڽسوايتورونکن⹁ نامون اي اکن مڠابورکن سستڠه ڤيکسل دسيسي\n" +"اڤابيلا ايميج دسسوايکن دڠن سايز بوکن اينتيݢر." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "سکرين:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "تيڠݢي سکرين" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "ليبر سکرين" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "فولدر تڠکڤ لاير" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "فورمت تڠکڤ لاير" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "کواليتي تڠکڤ لاير" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"کواليتي تڠکڤ لاير. هاڽ دݢوناکن اونتوق فورمت JPEG.\n" +"1 مقصودڽ ڤاليڠ تروق⁏ 100 مقصودڽ ڤاليڠ باݢوس.\n" +"ݢوناکن 0 اونتوق کواليتي لالاي." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "تڠکڤ لاير" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "ورنا سمڤادن کوتق ڤميليهن (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "ورنا کوتق ڤميليهن" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "ليبر کوتق ڤميليهن" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL ڤلاين" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "نام ڤلاين ڤرماٴينن" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "ڤريهل ڤلاين ڤرماٴينن" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL ڤلاين" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "علامت ڤلاين" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "ڤريهل ڤلاين ڤرماٴينن" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "نام ڤلاين ڤرماٴينن" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "ڤورت ڤلاين" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "ڤورت ڤلاين" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL سناراي ڤلاين" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "URL سناراي ڤلاين" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "فاٴيل سناراي ڤلاين" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "تتڤکن ڤنجڠ اکسارا مکسيموم ميسيج سيمبڠ دهنتر اوليه کليئن." + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"تتڤکن کڤد \"true\" اونتوق ممبوليهکن داٴون برݢويڠ.\n" +"ممرلوکن ڤمبايڠ اونتوق دبوليهکن." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"تتڤکن کڤد \"true\" اونتوق ممبوليهکن داٴون برݢويڠ.\n" +"ممرلوکن ڤمبايڠ اونتوق دبوليهکن." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"تتڤکن کڤد \"true\" اونتوق ممبوليهکن چچاٴير برݢلورا (ماچم اٴير).\n" +"ممرلوکن ڤمبايڠ اونتوق دبوليهکن." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"تتڤکن کڤد \"true\" اونتوق ممبوليهکن تومبوهن برݢويڠ.\n" +"ممرلوکن ڤمبايڠ اونتوق دبوليهکن." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "لالوان ڤمبايڠ" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"ڤمبايڠ ممبوليهکن کسن ۏيسوال مندالم دان بوليه منيڠکتکن\n" +"ڤريستاسي اونتوق سستڠه کد ۏيديو.\n" +"نامون اي هاڽ برفوڠسي دڠن ڤمبهاݢين بلاکڠ ۏيديو OpenGL." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "کواليتي تڠکڤ لاير" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map texture size" +msgstr "سايز تيکستور مينيموم" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"اوفسيت بايڠ فون لالاي (دالم اونيت ڤيکسل). جيک 0⹁ ماک بايڠ تيدق اکن دلوکيس." + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "بنتوق ڤتا ميني. دبوليهکن = بولت⹁ دلومڤوهکن = ڤيتق." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "تونجوقکن معلومت ڽهڤڤيجت" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "تونجوقکن کوتق ڤميليهن اينتيتي" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Show name tag backgrounds by default" +msgstr "فون تبل سچارا لالايڽ" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "ميسيج ڤنوتوڤن" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"ساٴيز کيش بلوکڤتا اونتوق ڤنجان ججاريڠ. مناٴيقکن نيلاي اين\n" +"اکن منيڠکتکن جومله % هيت کيش⹁ مڠورڠکن داتا يڠ ڤرلو دسالين\n" +"درڤد جالور اوتام⹁ لالو مڠورڠکن کترن." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "ڤنچهاياٴن لمبوت" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"ملمبوتکن کاميرا اڤابيلا مليهت سکليليڠ. جوݢ دکنلي سباݢاي ڤلمبوتن ڤڠليهتن اتاو " +"ڤلمبوتن تتيکوس.\n" +"برݢونا اونتوق مراکم ۏيديو." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"ملمبوتکن ڤموترن کاميرا دالم مود سينماتيک. سيت سباݢاي 0 اونتوق ملومڤوهکنڽ." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "ملمبوتکن ڤموترن کاميرا. سيت سباݢاي 0 اونتوق ملومڤوهکنڽ." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "ککونچي سلينڤ" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "نيلاي الفا بايڠ فون" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "بوڽي" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"منتڤکن URL دري مان کليئن مڠمبيل ميديا⹁ مڠݢنتيکن UDP.\n" +"$filename مستيله بوليه دأکسيس درڤد $remote_media$filename ملالوٴي\n" +"cURL (سوده تنتو⹁ remote_media مستي براخير دڠن تندا چوندوڠ).\n" +"فاٴيل يڠ تيدق وجود اکن دأمبيل دڠن چارا بياسا." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"منتڤکن ساٴيز تيندنن لالاي باݢي نود⹁ ايتم دان التن.\n" +"امبيل ڤرهاتيان بهاوا مودس اتاو ڤرماٴينن بوليه تتڤکن سچارا خصوص تيندنن اونتوق " +"سستڠه (اتاو سموا) ايتم." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"سيبر جولت تولقن لڠکوڠ چهاي.\n" +"مڠاول ليبر جولت اونتوق دتولق.\n" +"سيسيهن ڤياواي Gauss (ݢاٴوس) تولقن لڠکوڠ چهاي." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "تيتيق لاهير ستاتيک" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "ککواتن ڤارالکس مود 3D." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"ککواتن تولقن چهاي.\n" +"تيݢ ڤاراميتر 'تولقن' منتعريفکن جولت لڠکوڠ\n" +"چهاي يڠ دتولق دالم ڤنچهاياٴن." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "ڤمريقساٴن ڤروتوکول کتت" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "بواڠ کود ورنا" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "تتڤن" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "لالوان تيکستور" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"تيکستور ڤد نود بوليه دجاجرکن سام اد کڤد نود اتاو دنيا.\n" +"مود ڤرتام لبيه سسواي اونتوق بندا ماچم ميسين⹁ ڤرابوت⹁ دان لاٴين٢⹁ ماناکال\n" +"مود کدوا ممبواتکن تڠݢ دان بلوک ميکرو لبيه سسواي دڠن ڤرسکيترنڽ.\n" +"نامون بݢيتو⹁ کران اين چيري بارو⹁ ماک اي موڠکين تيدق دݢوناکن دڤلاين لام⹁\n" +"ڤيليهن اين ممبوليهکن ڤمقساٴن اي اونتوق جنيس نود ترتنتو. امبيل ڤرهاتين\n" +"بهاوا اياڽ داڠݢڤ دالم اوجيکاجي دان موڠکين تيدق برفوڠسي دڠن بتول." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The dead zone of the joystick" +msgstr "ڤڠنل ڤستي کايو بديق يڠ دݢوناکن" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "ڤڠنل ڤستي کايو بديق يڠ دݢوناکن" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "ڤنجڠ دالم ڤيکسيل اونتوق ممولاکن اينتراکسي سکرين سنتوه." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"تيڠݢي مکسيموم ڤرموکاٴن چچاٴير برݢلورا.\n" +"4.0 = تيڠݢي ݢلورا اياله دوا نود.\n" +"0.0 = ݢلورا تيدق برݢرق لڠسوڠ.\n" +"نيلاي اصلڽ 1.0 (1/2 نود).\n" +"ممرلوکن تتڤن چچاٴير برݢلورا دبوليهکن." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "انتاراموک رڠکاين يڠ ڤلاين دڠر." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"کأيستيميواٴن يڠ ڤڠݢونا٢ بارو داڤت سچارا اٴوتوماتيک.\n" +"ليهت /privs دالم ڤرماٴينن اونتوق سناراي ڤنوه کأيستيميواٴن ڤلاين دان " +"کونفيݢوراسي مودس." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"راديوس جيليد بلوک دسکيتر ستياڤ ڤماٴين يڠ ترتعلوق کڤد\n" +"بندا بلوک اکتيف⹁ دڽاتاکن دالم بلوکڤتا (16 نود).\n" +"دالم بلوک اکتيف⹁ اوبجيک دمواتکن دان ABM دجالنکن.\n" +"اين جوݢ جارق مينيموم دمان اوبجيک اکتيف (موب) دککلکن.\n" +"اين ڤرلو دتتڤکن برسام نيلاي بلوک جارق ڤڠهنترن اوبجيک اکتيف " +"(active_object_send_range_blocks)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"ترجمهن بهاݢين بلاکڠ اونتوق Irrlicht.\n" +"اندا ڤرلو ممولاکن سمولا سلڤس مڠاوبه تتڤن اين.\n" +"نوت: دAndroid⹁ ککلکن دڠن OGLES1 جيک تيدق ڤستي! اڤليکاسي موڠکين تيدق\n" +"بوليه دمولاکن جيک مڠݢوناکن تتڤن لاٴين. دڤلاتفورم لاٴين⹁ OpenGL دشورکن⹁\n" +"دان اي اياله ساتو-ساتوڽ ڤماچو يڠ ممڤوڽاٴي سوکوڠن ڤمبايڠ کتيک اين." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"کڤيکاٴن ڤکسي کايو بديق اونتوق مڠݢرقکن\n" +"فروستوم ڤڠليهتن دالم ڤرماٴينن." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"ککواتن (کݢلڤن) ڤمبايڠ نود اوکلوسي-سکيتر.\n" +"لبيه رنده لبيه ݢلڤ⹁ لبيه تيڠݢي لبيه تراڠ. نيلاي يڠ صح\n" +"اونتوق تتڤن اين هاڽله دري 0.25 هيڠݢ 4.0. جيک نيلاي\n" +"دلوار جولت⹁ اي اکن دتتڤکن کڤد نيلاي صح يڠ تردکت." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"سلڠ ماس دالم ساٴت⹁ دامبيل انتارا ڤريستيوا يڠ براولڠن\n" +"اڤابيلا منکن کومبيناسي بوتڠ کايو بديق." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"جومله ماس دالم ساٴت دامبيل اونتوق ملاکوکن کليک کانن يڠ براولڠ اڤابيلا\n" +"ڤماٴين منکن بوتڠ تتيکوس کانن تنڤ ملڤسکنڽ." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "جنيس کايو بديق" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"ماس اونتوق اينتيتي ايتم (ايتم يڠ دجاتوهکن) تروس هيدوڤ دالم اونيت ساٴت.\n" +"تتڤکن کڤد -1 اونتوق ملومڤوهکن صيفت ترسبوت." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "وقتو دالم هاري اڤابيلا دنيا بارو دمولاکن⹁ دالم ميليجم (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "سلڠ ڤڠهنترن ماس" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "کلاجوان ماس" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "حد ماس اونتوق کليئن ممبواڠ ڤتا يڠ تيدق دݢوناکن دري ميموري." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"اونتوق مڠورڠکن لمبڤڽ تيندق بالس⹁ ڤميندهن بلوک دڤرلاهنکن اڤابيلا ڤماٴين " +"ممبينا سسوات.\n" +"تتڤن اين منتڤکن براڤ لام اياڽ دڤرلاهنکن ستله ملتقکن اتاٴو مڠاليهکن سسبواه " +"نود." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "ککونچي توݢول مود کاميرا" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "لڠه تيڤ التن" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "نيلاي امبڠ سکرين سنتوه" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "نيلاي امبڠ سکرين سنتوه" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "ڤناڤيسن تريلينيار" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"بوليه دݢوناکن اونتوق ملنچرکن ڤتا ميني ڤد ميسين يڠ ڤرلاهن." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL کڤد سناراي ڤلاين يڠ دڤاڤرکن دالم تب ڤرماٴينن راماي." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "ڤنسمڤلن ڤڠورڠن" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"ڤنسمڤلن ڤڠورڠن سروڤ سڤرتي مڠݢوناکن ريسولوسي سکرين رنده⹁\n" +"تتاڤي اي هاڽ داڤليکاسيکن کڤد دنيا ڤرماٴينن سهاج⹁ تيدق مڠاوبه GUI.\n" +"اي بوليه منيڠکتکن ڤريستاسي دڠن مڠوربنکن ڤراينچين ايميج.\n" +"نيلاي لبيه تيڠݢي ممبواتکن ايميج يڠ کورڠ ڤراينچين." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "جارق ڤميندهن ڤماٴين تنڤ حد" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "ݢونا ڤاڤرن اون 3D مڠݢنتيکن اون رات." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "ݢوناکن انيماسي اون سباݢاي لاتر بلاکڠ مينو اوتام." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "ݢوناکن ڤناڤيسن انيسوتروڤيک اڤابيلا مليهت تيکستور دري سواتو سودوت." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "ݢوناکن ڤناڤيسن بيلينيار اڤابيلا مڽسوايکن تيکستور." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"ݢوناکن ڤمتاٴن ميڤ اونتوق مڽسوايکن تيکستور. بوليه منيڠکتکن\n" +"سديکيت ڤريستاسي⹁ تراوتاماڽ اڤابيلا مڠݢوناکن ڤيک تيکستور\n" +"برديفينيسي تيڠݢي. ڤڽسواي-تورون ݢام سچار تڤت تيدق دسوکوڠ." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "ݢوناکن ڤناڤيسن تريلينيار اڤابيلا مڽسوايکن تيکستور." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "VSync" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "ڤڽݢرقن منݢق سکرين." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "ڤماچو ۏيديو" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "فکتور اڤوڠن ڤندڠ" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "جارق ڤندڠ دالم اونيت نود." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "ککونچي مڠورڠ جارق ڤندڠ" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "ککونچي منمبه جارق ڤندڠ" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "ککونچي زوم ڤندڠن" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "جارق ڤندڠ" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Virtual joystick triggers Aux1 button" +msgstr "کايو بديق ماي مميچو بوتڠ aux" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "کقواتن بوڽي" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"کقواتن سموا بوڽي.\n" +"ممرلوکن سيستم بوڽي دبوليهکن." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "نود برݢويڠ" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "داٴون برݢويڠ" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "چچاٴير برݢلورا" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "کتيڠݢين اومبق چچاٴير برݢلورا" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "کلاجوان اومبق چچاٴير برݢلورا" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "ڤنجڠ اومبق چچاٴير برݢلورا" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "تومبوهن برݢويڠ" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "ورنا کوتق ڤميليهن" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"اڤابيلا ڤناڤيس سکال GUI ايايتgui_scaling_filter دتتڤکن کڤد \"true\"⹁ سموا\n" +"ايميج GUI ڤرلو دتاڤيس دالم ڤرايسين⹁ تتاڤي سستڠه ايميج دجان سچارا تروس\n" +"کڤرکاکسن (چونتوهڽ⹁ ڤنرجمهن-ک-تيکستور اونتوق نود دالم اينۏينتوري)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"اڤابيلا gui_scaling_filter_txr2img دتتڤکن کڤد \"true\"⹁ سالين سمولا کسموا\n" +"ايميج ترسبوت دري ڤرکاکسن کڤرايسين اونتوق دسسوايکن. سکيراڽ دتتڤکن کڤد\n" +"\"false\"⹁ برباليق کڤد قاعده ڤڽسواين يڠ لام⹁ اونتوق ڤماچو ۏيديو يڠ تيدق " +"ممڤو\n" +"مڽوکوڠ دڠن سمڤورنا فوڠسي موات تورون سمولا تيکستور درڤد ڤرکاکسن." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"اڤابيلا مڠݢوناکن تاڤيسن بيلينيار\\تريلينيار\\انيسوتروڤيک⹁ تيکستور\n" +"ريسولوسي رنده بوليه جادي کابور⹁ جادي سسواي-ناٴيقکن مريک\n" +"سچارا أوتوماتيک دڠن سيسيڤن جيرن تردکت اونتوق ممليهارا ڤيکسل\n" +"کراس. تتڤن اين منتڤکن سايز تيکستور مينيما اونتوق تيکستور\n" +"ڤڽسواي-ناٴيقکن⁏ نيلاي لبيه تيڠݢي تمڤق لبيه تاجم⹁ تتاڤي ممرلوکن\n" +"ميموري يڠ لبيه باڽق. نيلاي کواسا 2 دشورکن. منتڤکن نيلاي اين لبيه\n" +"تيڠݢي دري 1 تيدق اکن منمڤقکن کسن يڠ ڽات ملاٴينکن تاڤيسن\n" +"بيلينيار\\تريلينيار\\انيسوتروڤيک دبوليهکن. اين جوݢ دݢوناکن سباݢاي\n" +"سايز تيکستور نود اساس اونتوق أوتوڤڽسواين تيکستور جاجرن دنيا." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "سام اد انيماسي تيکستور نود ڤرلو دڽهسݢرقکن ڤد ستياڤ بلوک ڤتا." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"تتڤکن سام اد ڤماٴين دتونجوقکن کڤد کليئن تنڤا حد جارق.\n" +"تتڤن اين ترکچم⹁ ݢوناکن تتڤن player_transfer_distance سباݢاي ݢنتي." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" +"منتڤکن سام اد ايڠين ممبنرکن ڤماٴين اونتوق منچدراکن دان ممبونوه ساتو سام " +"لاٴين." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"تتڤن سام اد اونتوق ممينتا مڽمبوڠ سمولا سلڤس برلاکوڽ کرونتوهن (Lua).\n" +"تتڤکن کڤد \"true\" جک ڤلاين اندا دتتڤکن اونتوق مولا سمولا سچارا اٴوتوماتيک." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "سام اد اندا هندق مڠکابوتکن ڤڠهوجوڠ کاوسن يڠ کليهتن." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"سام اد ايڠين ممبيسوکن بوڽي. اندا بوليه مڽهبيسو ڤد بيلا٢\n" +"ماس⹁ ملاٴينکن سيستم بوڽي دلومڤوهکن (enable_sound=false).\n" +"دالم ڤرماٴينن⹁ اندا بوليه منوݢول کأداٴن بيسو مڠݢوناکن ککونچي\n" +"بيسو اتاو مڠݢوناکن مينو جيدا." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"تتڤکن سام اد هندق منونجوقکن معلومت ڽهڤڤيجت (کسنڽ سام سڤرتي منکن بوتڠ F5)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "کومڤونن ليبر سايز تتيڠکڤ اول." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "ليبر ݢاريسن کوتق ڤميليهن سکليليڠ نود." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"سيستم Windows سهاج: مولاکن Minetest دڠن تتيڠکڤ ݢاريس ڤرينة دکت لاتر بلاکڠ.\n" +"مڠندوڠي معلومت يڠ سام سڤرتي فاٴيل debug.txt (نام لالاي)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"ديريکتوري دنيا (سموا بندا دالم دنيا دسيمڤن دسيني).\n" +"تيدق دڤرلوکن جک برمولا دري مينو اوتام." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "ماس مولا دنيا" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"تيکستور جاجرن دنيا بوليه دسسوايکن اونتوق منجڠکاو ببراڤ نود.\n" +"نامون بݢيتو⹁ ڤلاين موڠکين تيدق داڤت مڠهنتر سکال يڠ اندا\n" +"ايڠينکن⹁ تراوتاماڽ جيک اندا ݢوناکن ڤيک تيکستور يڠ دريک سچارا\n" +"خصوص⁏ دڠن ڤيليهن اين⹁ کليئن اکن چوبا اونتوق مننتوکن سکال سچارا\n" +"أوتوماتيک برداسرکن سايز تيکستور. جوݢ ليهت texture_min_size.\n" +"امرن: ڤيليهن اين دالم اوجيکاجي!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "مود تيکستور جاجرن دنيا" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- مود کرياتيف: " + +#~ msgid "- Damage: " +#~ msgstr "- بوليه چدرا " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = اوکلوسي ڤارالکس دڠن معلومت چرون (لبيه چڤت).\n" +#~ "1 = ڤمتاٴن بنتوق موک بومي (لبيه لمبت⹁ لبيه تڤت)." + +#~ msgid "Address / Port" +#~ msgstr "علامت \\ ڤورت" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "اداکه اندا ماهو سيت سمولا دنيا ڤماٴين ڤرساورڠن؟" + +#~ msgid "Basic" +#~ msgstr "اساس" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "بيت ڤر ڤيکسيل (اتاو کدالمن ورنا) دالم مود سکرين ڤنوه." + +#~ msgid "Bump Mapping" +#~ msgstr "ڤمتاٴن برتومڤوق" + +#~ msgid "Bumpmapping" +#~ msgstr "ڤمتاٴن برتومڤوق" + +#~ msgid "Config mods" +#~ msgstr "کونفيݢوراسي مودس" + +#~ msgid "Configure" +#~ msgstr "کونفيݢوراسي" + +#~ msgid "Connect" +#~ msgstr "سمبوڠ" + +#~ msgid "Credits" +#~ msgstr "ڤڠهرݢاٴن" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "ورنا باݢي کورسور ررمبوت سيلڠ (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "بوليه چدرا" + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "منتعريفکن تاهڤ ڤرسمڤلن تيکستور.\n" +#~ "نيلاي لبيه تيڠݢي مڠحاصيلکن ڤتا نورمل لبيه لمبوت." + +#~ msgid "Del. Favorite" +#~ msgstr "ڤادم کݢمرن" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "موات تورون ڤرماٴينن⹁ چونتوهڽ Minetest Game⹁ دري minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "موات تورون ساتو دري minetest.net" + +#~ msgid "Enable register confirmation" +#~ msgstr "بوليهکن ڤڠصحن ڤندفترن" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "ممبوليهکن ڤمتاٴن برتومڤوق ڤد تيکستور. ڤتا نورمل ڤرلو دسدياکن\n" +#~ "اوليه ڤيک تيکستور اتاو ڤرلو دجان سچارا أوتوماتيک.\n" +#~ "ڤرلوکن ڤمبايڠ دبوليهکن." + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "ممبوليهکن ڤنجاناٴن ڤتا نورمل سچارا لايڠ (کسن چيتق تيمبول).\n" +#~ "ڤرلوکن ڤمتاٴن برتومڤوق اونتوق دبوليهکن." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "ممبوليهکن ڤمتاٴن اوکلوسي ڤارالکس.\n" +#~ "ممرلوکن ڤمبايڠ اونتوق دبوليهکن." + +#~ msgid "Enter " +#~ msgstr "ماسوقکن " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "ڤيليهن ڤرچوباٴن⹁ موڠکين منمڤقکن رواڠ ڽات دانتارا\n" +#~ "بلوک اڤابيلا دتتڤکن دڠن نومبور لبيه بسر درڤد 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS دمينو جيدا" + +#~ msgid "Fallback font shadow" +#~ msgstr "بايڠ فون برباليق" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "نيلاي الفا بايڠ فون برباليق" + +#~ msgid "Fallback font size" +#~ msgstr "سايز فون برباليق" + +#~ msgid "Filtering" +#~ msgstr "ڤناڤيسن" + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "سايز فون باݢي فون برباليق دالم اونيت تيتيق (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "فون FreeType" + +#~ msgid "Full screen BPP" +#~ msgstr "BPP سکرين ڤنوه" + +#~ msgid "Game" +#~ msgstr "ڤرماٴينن" + +#~ msgid "Generate Normal Maps" +#~ msgstr "جان ڤتا نورمل" + +#~ msgid "Generate normalmaps" +#~ msgstr "جان ڤتا نورمل" + +#~ msgid "HUD scale factor" +#~ msgstr "فکتور سکالا ڤاڤر ڤندو (HUD)" + +#~ msgid "In-Game" +#~ msgstr "دالم ڤرماٴينن" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "ڤاسڠ: فايل: \"$1\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "ايکتن ککونچي. (جيک مينو اين برسليرق⹁ ڤادم سستڠه بندا دري فايل minetest." +#~ "conf)" + +#~ msgid "Main" +#~ msgstr "اوتام" + +#~ msgid "Menus" +#~ msgstr "مينو" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "ڤتا ميني دالم مود رادر⹁ زوم 2x" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "ڤتا ميني دالم مود رادر⹁ زوم 4x" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "ڤتا ميني دالم مود ڤرموکاٴن⹁ زوم 2x" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "ڤتا ميني دالم مود ڤرموکاٴن⹁ زوم 4x" + +#~ msgid "Name / Password" +#~ msgstr "نام \\ کات لالوان" + +#~ msgid "Name/Password" +#~ msgstr "نام\\کات لالوان" + +#~ msgid "No" +#~ msgstr "تيدق" + +#~ msgid "Normalmaps sampling" +#~ msgstr "ڤرسمڤلن ڤتا نورمل" + +#~ msgid "Normalmaps strength" +#~ msgstr "ککواتن ڤتا نورمل" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "جومله للرن اوکلوسي ڤارالکس." + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "کلݢڤن (الفا) بايڠ بلاکڠ فون برباليق⹁ نيلاي انتارا 0 دان 225." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "ڤڠاروه کسن اوکلوسي ڤارالکس ڤد کسلوروهنڽ⹁ کبياساٴنڽ سکال\\2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "سکال کسلوروهن کسن اوکلوسي ڤارالکس." + +#~ msgid "Parallax Occlusion" +#~ msgstr "اوکلوسي ڤارالکس" + +#~ msgid "Parallax occlusion" +#~ msgstr "اوکلوسي ڤارالکس" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "ڤڠاروه اوکلوسي ڤارالکس" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "للرن اوکلوسي ڤارالکس" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "مود اوکلوسي ڤارالکس" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "سکال اوکلوسي ڤارالکس" + +#~ msgid "PvP enabled" +#~ msgstr "بوليه برلاوان PvP" + +#~ msgid "Reset singleplayer world" +#~ msgstr "سيت سمولا دنيا ڤماٴين ڤرساورڠن" + +#~ msgid "Server / Singleplayer" +#~ msgstr "ڤلاين ڤرماٴينن \\ ڤماٴين ڤرسأورڠن" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "اوفسيت بايڠ فون برباليق (دالم اونيت ڤيکسل). جيک 0⹁ ماک بايڠ تيدق اکن " +#~ "دلوکيس." + +#~ msgid "Special" +#~ msgstr "ايستيميوا" + +#~ msgid "Special key" +#~ msgstr "ککونچي ايستيميوا" + +#~ msgid "Start Singleplayer" +#~ msgstr "مولا ماٴين ساورڠ" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "ککواتن ڤتا نورمل يڠ دجان." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "اونتوق ممبوليهکن ڤمبايڠ⹁ ڤماچو OpenGL مستي دݢوناکن." + +#~ msgid "View" +#~ msgstr "ليهت" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "منتڤکن سام اد فون FreeType دݢوناکن⹁ ممرلوکن سوکوڠن Freetype\n" +#~ "دکومڤيل برسام. جيک دلومڤوهکن⹁ فون ڤتا بيت دان ۏيکتور XML اکن دݢوناکن." + +#~ msgid "Yes" +#~ msgstr "ياٴ" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "اندا اکن سرتاٴي ڤلاين دڠن نام \"%s\" اونتوق کالي ڤرتام.\n" +#~ "جيک اندا تروسکن⹁ اکاٴون بهارو دڠن معلومت اندا اکن دچيڤت دڤلاين اين.\n" +#~ "سيلا تايڤ سمولا کات لالوان اندا دان کليک 'دفتر دان سرتاٴي' اونتوق صحکن " +#~ "ڤنچيڤتاٴن اکاٴون⹁ اتاو کليک 'باتل' اونتوق ممباتلکن." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "اندا تله منيڠݢل" + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/nb/minetest.po b/po/nb/minetest.po new file mode 100644 index 0000000..db8baaf --- /dev/null +++ b/po/nb/minetest.po @@ -0,0 +1,7513 @@ +msgid "" +msgstr "" +"Project-Id-Version: Norwegian Bokmål (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-06-11 17:19+0000\n" +"Last-Translator: Kenneth LNOR <kennethlnor@gmail.com>\n" +"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/" +"minetest/minetest/nb_NO/>\n" +"Language: nb\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.13-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Nullstill meldingskøen" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Tom kommando." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Avslutt til hovedmeny" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Ugyldig kommando: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Avgitt kommando: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "List opp påkoblede spillere" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Påkoblede spillere: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Utgående meldingskø er nå tømt." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Denne kommandoen er utkoblet av tjeneren." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Gjenoppstå" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Du døde" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Tilgjengelige kommandoer:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Tilgjengelige kommandoer: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Ikke tilgjengelig kommando: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Få hjelp med kommandoer" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Bruk «.help <kommando>» for å få mer informasjon, eller «.help all» for å " +"liste opp alt." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <kommando>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<ingen tilgjengelig>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Det oppstod en feil i et Lua-skript:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Det oppstod en feil:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Hovedmeny" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Koble til på nytt" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Tjeneren har bedt om ny tilkobling:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Velg endringer" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Avvikende protokollversjon. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Tjener krever protokollversjon $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Tjener støtter protokollversjoner mellom $1 og $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Vi støtter kun protokollversjon $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Vi støtter protokollversjoner mellom versjon $1 og $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Avbryt" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Pakker:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Deaktivere alle" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Deaktiver modpakke" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Aktiver alle" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Aktiver modpakke" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Kunne ikke aktivere modden \"$1\" inneholder ugyldige tegn. Kun tegnene [a-" +"z0-9_] er tillatt." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Finn Flere Mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Ingen (valgfrie) pakker" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Mangler spillbeskrivelse." + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No hard dependencies" +msgstr "Krever ingen andre modder" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Ingen modpakke-beskrivelse tilgjengelig." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Ingen valgfrie pakker" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Valgfrie behov:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Lagre" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Verden:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "aktivert" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "«$1» eksisterer allerede. Ønsker du å skrive over den?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$1 og $2 pakker blir installert." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 av $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 laster ned,\n" +"$2 i kø" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 laster ned..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 påkrevd pakke manglet." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 blir installert, and $2 pakker blir hoppet over." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Alle pakker" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Allerede installert" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Tilbake til hovedmeny" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Grunnspill:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB er ikke tilgjengelig når Minetest kompileres uten cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Laster ned..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Kunne ikke laste ned $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Spill" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Installere" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Installere $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Installasjon mangler pakker" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Installasjon: Ikke-støttet filtype eller ødelagt pakke" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Modder" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Kunne ikke hente pakker" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Ingen resultater" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Ingen oppdateringer" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Ikke funnet" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Overskriv" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Vennligst sjekk at grunnspillet er riktig." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Satt i kø" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Teksturpakker" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Avinstallere" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Oppdatere" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Oppdatere Alle [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Se mer informasjon i nettleseren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "En verden med navn \"$1\" eksisterer allerede" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Ytterligere terreng" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Høydekjøling" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Høyde tørke" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Biom blanding" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomer" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Grotter" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Huler" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Opprett" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekorasjoner" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Advarsel: Utviklingstesten er tiltenkt utviklere." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Fangehull" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Flatt terreng" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Flytende landmasser på himmelen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Flytlandene (eksperimentelt)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Generer ikke-fraktalt terreng: Hav og underjordisk" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Bakker" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Fuktige elver" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Øker fuktigheten rundt elver" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Installere $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Innsjøer" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Lav fuktighet og høy varme fører til små eller tørre elver" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Mapgen" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Mapgen-flagg" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Mapgen-spesifikke flagg" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Fjell" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Gjørmeflyt" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Nettverk av tuneller og huler" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Ingen spill valgt" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Reduserer varmen med høyden" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Reduserer fuktigheten med høyden" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Elver" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Havnivå Elver" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Frø" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Glatt overgang mellom biotoper" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Strukturer som vises i terrenget (ingen effekt på trær og jungelgress skapt " +"av v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Strukturer som dukker opp i terrenget, typisk trær og planter" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Temperert, ørken" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Temperert, ørken, jungel" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Temperert, Ørken, Jungel, Tundra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Terrengoverflate Erosjon" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Trær og jungelgress" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Varier elvedybden" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Svært store huler dypt i undergrunnen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Navn på verden" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Du har ingen spill installert." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Er du sikker på at du vil slette \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Slett" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: mislyktes i å slette \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: ugyldig sti \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Slett verden \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Bekreft passord" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Navn" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Passord" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Passordene samsvarer ikke!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Registrer og logg inn" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Godta" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Gi Modpakke nytt navn:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Denne modpakken har et gitt navn i modpack.conf som vil overstyre enhver " +"omdøping." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Ingen beskrivelse av innstillingen)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D-støy" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Tilbake til innstillinger" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Bla gjennom" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Innhold" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Innhold" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Deaktivert" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Endre" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Aktivert" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Fraktal tekstur" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktaver" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Offset" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Standhaftighet" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Vennligst skriv inn et gyldig heltall." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Vennligst oppgi et gyldig nummer." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Gjenopprette standard" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Skala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Søk" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Velg mappe" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Velg fil" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Vis tekniske navn" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Verdien må være minst $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Verdien må ikke være større enn $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X-spredning" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y-spredning" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z-spredning" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Absoluttverdi" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "Forvalg" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "myknet" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Aktivert)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mods" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Kunne ikke installere $1 til $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Installer Mod: Kan ikke finne ekte modnavn for: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "Install Mod: Kan ikke finne passende mappenavn for modpack $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Kan ikke finne en gyldig mod eller modpakke" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Kan ikke installere en $1 som en teksturpakke" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Kan ikke installere et spill som en $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Kan ikke installere en mod som en $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Kan ikke installere en modpack som en $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Laster inn..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Offentlig serverliste er deaktivert" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Prøv å aktivere offentlig serverliste og sjekk Internett-tilkoblingen din." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Om" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktive bidragsytere" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Active renderer:" +msgstr "Aktiv grafisk tegner:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Kjerneutviklere" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Velg mappe" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Åpner katalogen som inneholder brukerleverte verdener, spill, mods,\n" +"og teksturpakker i en filbehandler/utforsker." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Tidligere bidragsytere" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Tidligere kjerneutviklere" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Vis feilsøkingsinfo" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Utforsk nettbasert innhold" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Innhold" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Deaktiver Teksturpakke" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informasjon:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Installerte pakker:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Ingen datapakker." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Ingen pakkebeskrivelse tilgjengelig" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Gi nytt navn" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Avinstaller pakke" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Bruk teksturpakke" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Kunngjør Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Tildel Adresse" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Kreativt modus" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Aktiver skade" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Spill Tjener" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Vertstjener" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Installer spill fra ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Ny" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Ingen verden opprettet eller valgt!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Spill" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Velg endringer" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Velg verden:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Tjenerport" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Start spill" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adresse" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Tøm" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Kreativ modus" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "Skade" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favoritter" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Inkompatible servere" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Ta del i spill" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Latens" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Offentlige servere" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Oppdater" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Eksterne media" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "Serverbeskrivelse" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D-skyer" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Alle innstillinger" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Kantutjevning:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Lagre skjermstørrelse automatisk" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilineært filter" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Endre taster" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Forbundet glass" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dynamiske skygger" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Dynamiske skygger: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Stilfulle Blader" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Høy" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Lav" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Medium" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + anisotropisk filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Ingen filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Mangler mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Knutepunktsframheving" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Knutepunktsomriss" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Ingen" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Ugjennomsiktige blader" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Ugjennomsiktig vann" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partikler" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Skjerm:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Innstillinger" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shaders" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shaders (eksperimentelt)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Shaders (ikke tilgjengelig)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Enkle Blader" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Jevn belysning" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Teksturering:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Tonemapping" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Berøringsterskel: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Tri-lineært filter" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Ultrahøy" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Veldig lav" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Viftende blader" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Skvulpende væsker" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Viftende planter" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Tilkoblingsfeil (tidsavbrudd?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Tilkoblingen ble tidsavbrutt." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Ferdig!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Initialisering av noder" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Initialiserer noder..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Laster inn teksturer..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Gjenoppbygger shaders..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Tilkoblingsfeil (tidsavbrudd?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Kunne ikke finne eller laste inn spillet: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Ugyldig spillspesifikasjon." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Hovedmeny" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Ingen verden valgt og ingen adresse oppgitt. Ingenting å gjøre." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Spillernavn for langt." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Vennligst velg et navn!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Den oppgitte passordfilen kunne ikke åpnes: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Angitt sti til verdenen finnes ikke: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Sjekk debug.txt for detaljer." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Adresse: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Modus: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Offentlig: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- Alle mot alle (PvP): " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Tjenernavn: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Det oppstod en feil:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Ingen tilgang. På grunn av: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Automatisk forover slått av" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Automatisk forover slått på" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Block bounds gjemt" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Block bounds vist for alle blokker" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Block bounds vist for gjeldende blokk" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Block bounds vist for nærliggende blokker" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Kameraoppdatering slått av" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Kameraoppdatering slått på" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "Kan ikke vise block bounds (trenger 'basic_debug' tillatelser)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Endre passord" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Filmatisk modus avskrudd" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Filmatisk modus påskrudd" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Klienten koblet fra" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Skripting på klientsiden er deaktivert" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Kobler til tjener…" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Tilkoblingen mislyktes av ukjent årsak" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Fortsett" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Kontroller:\n" +"- %s: flytt forover\n" +"- %s: flytt bakover\n" +"- %s: flytt mot venstre\n" +"- %s: flytt mot høyre\n" +"- %s: hopp/klatre oppover\n" +"- %s: grav/slå\n" +"- %s: plasser/bruk\n" +"- %s: snik/klatre nedover\n" +"- %s: slipp ting\n" +"- %s: inventar\n" +"- Mus: snu/se\n" +"- Musehjul: velg ting\n" +"- %s: chat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Kunne ikke løse adressen: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Oppretter klient…" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Oppretter tjener…" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Feilsøkingsinformasjon og profileringsgraf er skjult" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Feilsøkingsinformasjon vises" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Feilsøkingsinformasjon, profileringsgraf og wireframe skjult" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Standardstyring:\n" +"Ved ingen synlig meny:\n" +"- enkel berøring: knapp aktiveres\n" +"- dobbel berøring: legg på plass/bruke\n" +"- glidende berøring: se rundt deg\n" +"Meny/beholdning synlig:\n" +"- dobbel berøring (ute):\n" +" -->lukk\n" +"- berør stabel, berør spor:\n" +" --> flytt stabel\n" +"- berør&trekk, berør med den andre fingeren\n" +" --> legg én enkelt gjenstand i spor\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Ubegrenset visningsområde deaktivert" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Ubegrenset synsrekkevidde aktivert" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Oppretter klient…" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Avslutt til meny" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Avslutt til operativsystem" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Rask modus deaktivert" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Hurtigmodus aktivert" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Hurtigmodus aktivert (merk: ingen \"rask\"-rettigheter)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Flymodus deaktivert" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Flymodus aktivert" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Flymodus aktivert (merk: ingen 'fly'-privilegium)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Tåke deaktivert" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Tåke aktivert" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Spillinfo:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Spillet er satt på pause" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Vertstjener" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Gjenstandsdefinisjoner…" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Media…" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Minimap er for øyeblikket deaktivert av spill eller mod" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Flerspiller" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Noclip-modus deaktivert" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Noclip-modus aktivert" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Noclip-modus aktivert (merk: ingen \"noclip\"-rettigheter)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Blokkdefinisjoner..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Av" + +#: src/client/game.cpp +msgid "On" +msgstr "På" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Pitch flyttemodus deaktivert" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Pitch flyttemodus aktivert" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profil graf vises" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Ekstern server" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Løser adresse ..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Slår av..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Enkeltspiller" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Lydstyrke" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Lyd av" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Lydsystemet er deaktivert" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Lydsystem støttes ikke på denne versjonen" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Lyden er på" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Serveren kjører sannsynligvis en annen versjon av %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Kan ikke koble til %s fordi IPv6 er deaktivert" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Kan ikke lytte på %s fordi IPv6 er deaktivert" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Visningsområde endret til %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Visningsområdet er maksimalt: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Visningsområdet er minimum: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Volumet endret til %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Kantlinjer vises" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zoom er for øyeblikket deaktivert av spill eller mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Chat skjult" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Viser chat" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD skjult" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD vist" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profiler skjult" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profiler vises (side %d av %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Programmer" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Tilbaketast" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Kontroll" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Ned" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Slett EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Kjør" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Hjelp" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Hjem" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME-aksept" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME-konvertering" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME-avbryting" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME-modusendring" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME-ikkekonvertering" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Venstre" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Venstre knapp" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Venstre Ctrl" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Venstre Meny" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Venstre Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Venstre Super" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Meny" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Midtknapp" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numpad *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numpad +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numpad -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numpad ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numpad /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numpad 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numpad 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numpad 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numpad 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numpad 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numpad 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numpad 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numpad 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numpad 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numpad 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Tøm OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Spill" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Skriv ut" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Return" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Høyre" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Høyre knapp" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Høyre Ctrl" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Høyre Meny" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Høyre Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Høyre Super" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Velg" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Søvn" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Øyeblikksbilde" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Mellomrom" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Opp" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X knapp 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X knapp 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Forstørrelse" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Skjuler minikart" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Klarte ikke laste ned $1" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Fortsett" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "«Spesial» = klatre ned" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Automatisk fremover" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Automatisk hopping" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Tilbake" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Endre visning" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Chatte" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Kommando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsoll" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Senk siktavstanden" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Senk lydstyrke" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Trykk raskt på «hopp» to ganger for å starte og slutte å fly" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Dropp" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Framover" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Øk siktavstanden" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Øk lydstyrken" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Beholdning" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Hopp" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Tast allerede i bruk" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Lokal kommando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Demp" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Neste gjenstand" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Forrige gjenstand" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Velg rekkevidde" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Skjermdump" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Snike" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "HUD (hurtigtilgang) av/på" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Chattehistorikk av/på" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Rask forflytning av/på" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Flymodus av/på" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Tåke av/på" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Minikart av/på" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Gjennomtrengelige blokker av/på" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Pitchbevegelse (lateralaksevinkel) av/på" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "trykk tast" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Endre" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nytt passord" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Gammelt passord" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Passordene samsvarer ikke!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Avslutt" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Av" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Lydstyrke: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "nb" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Vennligst velg et navn!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Fastsetter posisjonen for virtuell styrepinne.\n" +"Hvis avskrudd, vil den virtuelle styrepinnen sentreres til posisjon for " +"første berøring." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Bruk virtuell styrepinne til å utløse \"aux\"-knapp.\n" +"Hvis påskrudd, vil virtuell styrepinne ogstå trykke \"aux\"-knapp når den er " +"utenfor hovedsirkelen." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Kan benyttes for å flytte et ønsket punkt til (0, 0) for å opprette et\n" +"passende gjenoppstandelsespunkt, eller for å tillate 'zooming in' on a " +"desired\n" +"point ved å øke 'scale'.\n" +"Standardverdien is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z)-skalering for fraktal i blokker.\n" +"Faktisk fraktalstørrelse blir to til tre ganger større.\n" +"Man kan angi veldig store tall; fraktalen\n" +"behøver ikke passe inn i verdenen.\n" +"Øk disse tallene for å oppskalere på fraktalens detaljer.\n" +"Standardverdien gir en form som er sammenpresset\n" +"i høyden og egner seg til øy. Angi tre like tall for grunnformen." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2D-støytall som styrer form og størrelse på høydedrag." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2D-støytall som styrer form og størrelse på bakkelandskap." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2D-støytall som styrer form og størrelse på trinnvise fjell." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "2D-støytall som styrer fjellkjedestørrelse og -forekomst." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D-støytall som styrer størrelse og forekomst av bakkelandskap." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "2D-støytall som styrer størrelse og forekomst av trinnfjellkjeder." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2D-støytall som plasserer elvedaler og elveleier." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D-skyer" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D-modus" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Parallaksestyrke i 3D-modus" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D-støytall som definerer kjempegrotter." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D-støytall som definerer fjellstruktur og -høyde.\n" +"Definerer også fjellterrengstruktur på luftøyer." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "3D-støytall som definerer strukturen til sidene i en elvekløft." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3D-støytall som definerer terrenget." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"3D-støytall for fjelloverheng, klipper o. l. Vanligvis små variasjoner." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D-støytall som avgjør antall grotter per kartchunk." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3D-støtte.\n" +"For øyeblikket støttes følgende alternativer:\n" +"- none: Ingen 3D-utdata.\n" +"- anaglyph: Cyan/magenta farge-3D.\n" +"- interlaced: Skjermstøtte for partall/oddetall-linjebasert " +"polarisering.\n" +"- topbottom: Del skjermen i topp og bunn.\n" +"- sidebyside: Del skjermen side om side.\n" +"- crossview: Skjele-3d\n" +"- pageflip: Quadbuffer-basert 3d.\n" +"Vær klar over at interlace-modus krever at skyggelegging er påslått." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Velg genereringsfrø for en ny verden. La det stå tomt for et tilfeldig et.\n" +"Blir erstattet når man oppretter en ny verden i hovedmenyen." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Melding som vises til alle klienter når serveren krasjer." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Melding som vises alle klienter når serveren slås av." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "ABM-intervall" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Akselerasjon i luft" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Tyngdeakselerasjon, i blokker per sekund per sekund (b/s^2)." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Aktive blokkendrere (ABM)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Active block management interval" +msgstr "Aktiv blokkeringsrekkevidde" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Rekkevidde for aktive blokker" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Område for sending av aktive objekt" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Kobler til denne adressen.\n" +"La det stå tomt for å starte en lokal server.\n" +"Vær klar over at adressen i feltet i hovedmenyen overkjører denne " +"innstillingen." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Legger på partikler når man graver ut en blokk." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Justér skjermens DPI-innstilling (ikke for X11/kun Android), f. eks. for 4k-" +"skjermer." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Legg til elementnavn" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avansert" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Endrer lyskurven ved å bruke gammakurven (gamma-korreksjon) .\n" +"Høye verdier gjør middels og lave lysnivåer lysere.\n" +"Verdien «1.0» gir ingen endring i lyskurven.\n" +"Dette har reell betydning kun for dagslys og kunstig\n" +"belysning - det har lite å si for naturlig nattelys." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Alltid flymodus og rask forflytning" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Antall meldinger en spiller kan sende hvert 10. sekund." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Forsterker daler." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Antisotropisk filtrering" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Offentliggjør server" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Offentliggjør for denne serverlisten." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Legg til elementnavn" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Legg elementnavn til infoboble." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Støytall for epletrær" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Treghet i armer" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Å gi armene treghet fører til en mer virkelighetsnær\n" +"bevegelse av armene når kameraet flytter seg." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Spør om å koble til igjen etter krasj" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"På denne avstanden vil serveren utføre en kraftig optimalisering\n" +"av hvilke blokker som sendes til klienten.\n" +"En lav verdi kan potensielt føre til en kraftig forbedring i ytelsen, \n" +"på bekostning av synlige gjengivelsesfeil (det kan skje at blokker ikke\n" +"gjengis under vann og i huler, tidvis heller ikke på land).\n" +"Angi denne verdien til høyere enn max_block_send_distance\n" +"for å slå av denne optimaliseringen.\n" +"Målenheten er «mapblocks» (en enhet på 16x16 blokker)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Tast for automatisk fremoverbevegelse" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Hopp automatisk over hindringer med høyde på én blokk." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Rapporter automatisk til serverlisten." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Lagre skjermstørrelse automatisk" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Autoskaleringsmodus" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "Hoppetast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key for climbing/descending" +msgstr "Spesialtast for klatring/nedklatring" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Rettetast" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Bakkens grunnivå" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Terrengets grunnhøyde." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Enkle rettigheter" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Strandlys" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Strandlydsterskel" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilineær filtrering" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Bindingsadresse" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Temperatur- og fuktighetsparametre for biotop-APIet" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Biotoplyd" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Avstand for optimalizering av mapblocksending" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Filsti for fet og kursivert skrifttype" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Filsti for fet og kursivert monospace skrifttype" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Filsti for fet skrifttype" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Filsti for fet monospace skrifttype" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Bygg inni spiller" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Innebygd" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Endre visning" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Kamera 'near clipping plane' avstand i noder, mellom 0 og 0,5.\n" +"Brukere flest vil ikke behøve å endre på dette.\n" +"Økning av verdi vil kunne redusere artefakter fra svakere skjermkort.\n" +"0.1 = standardverdi, 0.25 = grei verdi for svakere nettbrett." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Kamerautjevning" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Kamerautjevning i filmmodus" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Av/på-tast for visningsoppdatning" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Hulelyd" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Hulelyd #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Hulelyd #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Hulebredde" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Grotte1-lyd" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Grotte2-lyd" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Grottegrense" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Grottelyd" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Grotteinnsnevring" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Grotteterskel" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Øvre grottegrense" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Midtpunkt på lysforsterkningskurven,\n" +"der 0.0 er minimumsnivået for lysstyrke mens 1.0 er maksimumsnivået." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "Terskel for utvisning fra chat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Sludrekommandoer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat font size" +msgstr "Skriftstørrelse" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Skydretast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat log level" +msgstr "Loggingsnivå for feilsøking" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Maks antall meldinger i chatten" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Chatmeldingsformat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Terskel for utvisning fra chat" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Maksstørrelse på melding i chatten" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Tast for veksling av sludring" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Viser chat" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Chunk-størrelse" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Filmatisk tilstand" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tast for filmatisk tilstand" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Rene, gjennomsiktige teksturer" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Klient" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Klient og tjener" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Brukermodding" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Moddebegrensninger på brukers side" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Omfangsbegrensning av blokkoppslag hos klienten" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Brukermodding" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Klatrehastighet" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Skyradius" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Skyer" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Skyer er en effekt på klientsiden." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Skyer i meny" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Farget tåke" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Colored shadows" +msgstr "Farget tåke" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Komma-atskilt liste med of flags to hide in the content repository.\n" +"\"nonfree\" kan brukes til å skjule pakker som ikke kvalifiserer som \"fri " +"programvare\"\n" +"som definert av Free Software Foundation.\n" +"Man kan også specify innholdsvurderinger.\n" +"Disse flags are uavhengige av Minetest-versjoner,\n" +"se fullstendig liste på https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Kommaatskilt liste over modder som er gitt tilgang til HTTP-APIer.\n" +"Dette lar dem laste data opp og ned til internett." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Kommainndelt liste med klarerte modder som har tilgang til usikre\n" +"funksjoner selv når moddsikkerhet er på (via request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Tast for chat og kommandoer" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Forbind glass" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Koble til ekstern mediatjener" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Forbinder glass hvis støttet av knutepunkt." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Konsolldekkevne (opasitet)" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Konsollfarge" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Konsollhøyde" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "ContentDBs svarteliste" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "ContentDB-URL" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Kontinuerlig fremoverbevegelse" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Kontinuerlig fremoverbevegelse, slås av/på med tasten for automatisk " +"fremover.\n" +"Trykk på automatisk fremover-tasten igjen eller gå bakover for å slå av." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Kontroller" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Styrer lengden på døgnet.\n" +"Eksempler:\n" +"1 = 24timer, 72 = 20min, 360 = 4min, 0 = dag/natt/hva det skal være, forblir " +"uendret." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Krasjmelding" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Kreativ" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Trådkors-alpha" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Trådkors-alpha (ugjennomsiktighet, mellom 0 og 255).\n" +"Kontrollerer også objektets trådkorsfarge." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Trådkorsfarge" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI (skjermoppløsning)" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Skade" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Tast for å vise/skjule feilsøkingsinfo" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Størrelsesterskel for feilsøkingsloggfil" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Loggingsnivå for feilsøking" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Tast for senking av lydstyrke" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Serverens oppdateringsintervall (servertikk)" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Forvalgt akselerasjon" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Forvalgt spill" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Forvalgt passord" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Forvalgte privilegium" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Forvalgt rapporteringsformat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default stack size" +msgstr "Forvalgt spill" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Definerer område der trær har epler." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Definerer områder med sandstrender." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines the base ground level." +msgstr "Definerer treområder og skogstetthet." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Angir dybden på elveleier." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Angir bredden på elveleiet." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Definerer treområder og skogstetthet." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Avleggs håndtering av Lua-API" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Dekorasjoner" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "Høyre tast" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Gravepartikler" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Skru av antijuksing" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Ikke tillatt tomme passord" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Domenenavn for tjener, som vist i tjenerlisten." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Dobbeltklikk hopp for å fly" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Dobbeltklikking av hoppetasten veksler flyvningsmodus." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Maksimum y-verdi for grotter" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Minimum y-verdi for grotter" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dungeon noise" +msgstr "Grottelyd" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Skru på konsollvindu" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Aktiver kreativt modus for alle spillere" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Bruk joystick" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Aktiverer minikart." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "Maks FPS når spillet ikke har fokus eller er pauset" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Filsti for reserveskrifttype" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Hurtigtast" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Rask bevegelse" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Synsfelt" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Synsfelt i grader." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Fil i klient/serverliste som inneholder yndlingsservere som vist\n" +"i flerspillefanen." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Fylldybde" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Kantutjevning:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "First of two 3D noises that together define tunnels." +msgstr "Det første av to 3D-støytall som sammen definerer tunneler." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland maximum Y" +msgstr "Maksimum y-verdi for grotter" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland minimum Y" +msgstr "Minimum y-verdi for grotter" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland noise" +msgstr "Bakkestøy" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland water level" +msgstr "Vannivå" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Flygingstast" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Flyging" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Tåke" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Tåkegrense" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Tåkevekslingstast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Skriftstørrelse" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Fet skrifttype som forvalg" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Kursiv skrifttype som forvalg" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Skriftskygge" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Skriftstørrelse" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Skjermavbildningsformat." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Forovertast" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Fraktaltype" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Fullskjerm" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Fullskjermsmodus." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Spill" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafikk" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafikk" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafikk" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Tyngdekraft" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Bakkestøy" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "HUD vist" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Varmestøy" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Høydelyd" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Bratthet for ås" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Terskel for ås" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Bakke støy 1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Bakke støy 2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Bakke støy 3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Bakke støy 4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Serverens hjemmeside, som vises i serverlisten." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Neste hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Forrige hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Første hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Tiende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Ellevte hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Tolvte hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Trettende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Fjortende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Femtende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Sekstende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Syttende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Attende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Nittende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Andre hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Tjuende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Tjueførste hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Tjueandre hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Tjuetredje hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Tjuefjerde hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Tjuefemte hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Tjuesjette hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Tjuesjuende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Tjueåttende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Tjueniende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Tredje hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Trettiende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Trettiførste hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Trettiandre hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Fjerde hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Femte hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Sjette hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Syvende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Åttende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Niende hurtigfelttast" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Reduksjon av denne verdien øker bevegelsesmotstanden i væsker." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6-tjener" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Skru på registerbekreftelse ved tilkobling til tjener.\n" +"Hvis avskrudd, vil en ny konto registres automatisk." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Inkluder lydstyrketast" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Tast for beholdning" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Inverter mus" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Inverter vertikale musebevegelser." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Italic font path" +msgstr "Skriftsti" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Ringer" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "Spillstikke-ID" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick dead zone" +msgstr "Spillstikketype" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Kontrollertype" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia-w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia-x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia-y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia-z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Hoppetast" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Hoppehastighet" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for å redusere synsrekkevidde.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for redusering av lydstyrken.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hopping.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for kasting av gjeldende valgt element.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for økning av synsrekkevidde.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for økning av lydstyrken.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hopping.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hurtig gange i raskt modus.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for å bevege spilleren bakover\n" +"Vil også koble ut automatisk foroverbevegelse, hvis aktiv.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for å bevege spilleren fremover.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for å bevege spilleren til venstre.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for å bevege spilleren til høyre.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hopping.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av ellevte hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tolvte hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av trettende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av fjortende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av femtende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging sekstende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av syttende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av attende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av nittende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tjuende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tjueførste hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tjueandre hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tjuetredje hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tjuefjerde hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tjuefemte hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tjuesjette hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tjuesyvende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tjueåttende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tjueniende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av trettiende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av trettiførste hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av trettiandre hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av åttende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av femte hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av første hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av fjerde hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av neste element i hurtigfeltet.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av niende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av forrige element i hurtigfeltet.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av andre hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av syvende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av sjette hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tiende hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for utvelging av tredje hurtigplassfelt.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Sniketast.\n" +"Brukes også for å gå ned på stiger og i vann dersom aux1_descends ikke " +"brukes.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hopping.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hurtig gange i raskt modus.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hurtig gange i raskt modus.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tast for hurtig gange i raskt modus.\n" +"Se http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Språk" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Bladstil" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Bladstil:\n" +"- Stilig: alle sider synes\n" +"- Enkel: kun yttersider synes, dersom special_tiles brukes\n" +"- Tildekket: gjennomsiktighet er av" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Venstretast" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Aktiver for å slå på bølgende blader.\n" +"Krever at dybdeskapere er aktivert." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Jevn belysning" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Liquid sinking" +msgstr "Hoppehastighet" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lower Y limit of floatlands." +msgstr "Y-verdi for store grotters øvre grense." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Skript for hovedmeny" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Mappe for kart" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Lagringsintervall for kart" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat" +msgstr "Mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal" +msgstr "Mapgen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "Mapgen" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5" +msgstr "Mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6" +msgstr "Mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7" +msgstr "Mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Maks FPS («frames» - bilder per sekund)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "Maks FPS når spillet står i pause." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Størst mulige hurtigfeltsbredde" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Maksimumsproposjon av nåværende vindu brukt til hurtigfelt.\n" +"Nyttig hvis det er noe å vise til høyre eller venstre for hurtigfeltet." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Maks antall brukere" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Dagens melding" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Minikart" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Tast for minikart" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Sikkerhet" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Filsti for monospace skrifttype" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Størrelse for monospace skrifttype" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "Størrelse for monospace skrifttype" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Pekerfølsomhet" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Nettverk" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Knutepunktsframheving" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fysikk" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move key" +msgstr "Flygingstast" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Flygingstast" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Bilineær filtrering" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Tilfeldig inndata" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Regular font path" +msgstr "Skriftsti" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Eksterne media" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Ekstern port." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Høyre tast" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Elveleiedybde" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Elveleiebredde" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Elvedybde" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Elvestøy" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Elvestørrelse" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Bredde på elvedal" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Rundt minikart" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Sandstrender dukker opp når nb_beach er større enn denne verdien." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Lagre kartet mottatt av klienten på disk." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Lagre kart mottatt av tjener" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Skjerm:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Skjermhøyde" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Skjermbredde" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Mappe for skjermdumper" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Skjermklippformat" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Skjermklippkvalitet" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Skjermdump" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Se https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Kantfarge på utvalgsfelt (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Farge på utvalgsfelt" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Bredde på utvalgsfelt" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Velger en av 18 fraktaltyper.\n" +"1 = 4D «Rund» Mandelbrot-mengde.\n" +"2 = 4D «Rund» Julia-mengde.\n" +"3 = 4D «Firkantet» Mandelbrot-mengde.\n" +"4 = 4D «Firkantet» Julia-mengde.\n" +"5 = 4D «Mandy Cousin» Mandelbrot-mengde.\n" +"6 = 4D «Mandy Cousin» Julia-mengde.\n" +"7 = 4D «Variasjon» Mandelbrot-mengde.\n" +"8 = 4D «Variasjon» Julia-mengde.\n" +"9 = 3D «Mandelbrot/Mandelbar» Mandelbrot-mengde.\n" +"10 = 3D «Mandelbrot/Mandelbar» Julia-mengde.\n" +"11 = 3D «Juletre» Mandelbrot-mengde.\n" +"12 = 3D «Juletre» Julia-mengde.\n" +"13 = 3D «Mandelbulb» Mandelbrot-mengde.\n" +"14 = 3D «Mandelbulb» Julia-mengde.\n" +"15 = 3D «Cosine Mandelbulb» Mandelbrot-mengde.\n" +"16 = 3D «Cosine Mandelbulb» Julia-mengde.\n" +"17 = 4D «Mandelbulb» Mandelbrot-mengde.\n" +"18 = 4D «Mandelbulb» Julia-mengde." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Server-URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Servernavn" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Serverbeskrivelse" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "Server-URL" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Serveradresse" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Serverbeskrivelse" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Servernavn" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Serverport" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server side occlusion culling" +msgstr "Ikke-synlige blokker blir ikke sendt videre av serveren" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Tjenerport" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "Serverliste-URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "Serverliste-URL" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Serverlistefil" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Angi språk. La stå tom for å bruke operativsystemets språk.\n" +"Krever omstart etter endring." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "Angi maksimalt antall tegn i tekstmelding sendt av klienter." + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Angi som sann for å slå på bladrasling.\n" +"Krever at skyggelegging er påslått." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Angi som sann for å slå på bladrasling.\n" +"Krever at skyggelegging er påslått." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Angi som sann for å slå på væskeskvulping (som vann).\n" +"Krever at skyggelegging er påslått." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Angi som sann for å slå på plantesvaiing.\n" +"Krever at skyggelegging er aktivert." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Vis feilsøkingsinfo" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Angi språk. La stå tom for å bruke operativsystemets språk.\n" +"Krever omstart etter endring." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Show name tag backgrounds by default" +msgstr "Fet skrifttype som forvalg" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Beskjed ved avslutning" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Sniketast" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed" +msgstr "Hoppehastighet" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Skriftskygge" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Lyd" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Angir URL som klienten bruker for å hente media i stedet for å bruke UDP.\n" +"$filename burde være tilgjenglig fra $remote_media$filename via cURL\n" +"(remote_media bør selvfølgelig ende med skråstrek).\n" +"Filer som ikke er til stede hentes på den vanlige måten." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Spread of light curve boost range.\n" +"Styrer the width of the range to be boosted.\n" +"Standardavvik for lyskurvens boost Gaussian." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Fast gjenoppstandelsespunkt" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Bratthetsstøy" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Bratt fjellside-støy" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Spredningsstøy for bratt fjell" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "Synkron SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Temperaturvariasjon for biomer." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Innstillinger" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain height" +msgstr "Grunnleggende terrenghøyde" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Filsti for teksturer" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"Makshøyden for overflaten på væsker som skvulper.\n" +"4,0 = Bølgehøyde er to blokker.\n" +"0,0 = Bølger flytter seg ikke i det hele tatt.\n" +"Forvalgt verdi er 1,0 (1/2 blokk).\n" +"Krever at væskebølger er påslått." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touch screen threshold" +msgstr "Strandlydsterskel" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Strandlydsterskel" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Forsinkelse for infoboble" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"Sann = 256\n" +"Usann = 128\n" +"Kan gjøre at minikartet kjører lettere på trege maskiner." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Klarterte modder" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Upper Y limit of floatlands." +msgstr "Y-verdi for store grotters øvre grense." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Bruk 3D-skyer i stedet for flate." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Bruk animerte skyer som bakgrunn for hovedmenyen." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "VSync" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Videodriver" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Synsrekkevidde" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Volum" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Volum på all lyd. \n" +"Krever påslått lydsystem." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Gangfart" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Vannivå" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Blokksvaiing" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Bladrasling" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Bølgende blader" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Bølgende vann" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Bølgende blader" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Bølgende vann" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Plantesvaiing" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "Farge på utvalgsfelt" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Bredde-delen av vindusstørrelsen ved oppstart. Ignoreres i fullskjerm-modus." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Mappe for verden (alt i verdenen lagres her).\n" +"Trengs ikke hvis den opprettes fra hovedmenyen." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Verdensstarttid" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Verdensjusterte teksturer-modus" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y-koordinat for flatt land." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y for nullnivået for tetthetsgradient til fjell. Brukes for å forskyve fjell " +"i høyden." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Y-verdi for store grotters øvre grense." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Y-avstand som en grotte kan øke i størrelse til full størrelse." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Y-nivå for gjennomsnittlig terrengoverflate." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Y-nivå for øvre grottegrense." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Y-nivå for høytliggende terreng som fører til klipper." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Y-nivå for nedre terreng og sjøbunn." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Y-nivå for havbunn." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Tidsutløp for filnedlasting med cURL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "cURL-tidsgrense" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Maksimal parallellisering i cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Kreativ modus: " + +#~ msgid "- Damage: " +#~ msgstr "- Skade: " + +#~ msgid "Address / Port" +#~ msgstr "Adresse / port" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "" +#~ "Er du sikker på at du ønsker å tilbakestille din enkeltspiller-verden?" + +#~ msgid "Back" +#~ msgstr "Tilbake" + +#~ msgid "Basic" +#~ msgstr "Grunnleggende" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Biter per piksel (dvs. fargedybde) i fullskjermsmodus." + +#~ msgid "Bump Mapping" +#~ msgstr "Teksturtilføyning" + +#~ msgid "Bumpmapping" +#~ msgstr "Teksturpåføring (bump mapping)" + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Endrer hovedmenyens brukergrensesnitt (UI):\n" +#~ "- Fullstendig: Flere enkeltspillerverdener, valg av spill, " +#~ "teksturpakkevalg, osv.\n" +#~ "- Enkel: Én enkeltspillerverden, ingen valg av spill eller " +#~ "teksturpakke. Kan være\n" +#~ "nødvendig på mindre skjermer." + +#~ msgid "Config mods" +#~ msgstr "Sett opp modder" + +#~ msgid "Configure" +#~ msgstr "Sett opp" + +#~ msgid "Connect" +#~ msgstr "Koble til" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Bestemmer synkehastigheten i væsker." + +#~ msgid "Credits" +#~ msgstr "Bidragsytere" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Trådkorsfarge (R, G, B)." + +#~ msgid "Damage enabled" +#~ msgstr "Skade aktivert" + +#~ msgid "Del. Favorite" +#~ msgstr "Slett favoritt" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Last ned et spill, for eksempel Minetest Game, fra minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Last ned fra minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Laster ned og installerer $1, vent…" + +#~ msgid "Enable VBO" +#~ msgstr "Aktiver VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "Skru på registerbekreftelse" + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Aktiver filmatisk toneoversettelse" + +#~ msgid "Enter " +#~ msgstr "Enter " + +#~ msgid "Fallback font shadow" +#~ msgstr "Tilbakefallsskriftsskygge" + +#~ msgid "Fallback font size" +#~ msgstr "Tilbakefallsskriftstørrelse" + +#~ msgid "Filtering" +#~ msgstr "Filtrering" + +#~ msgid "FreeType fonts" +#~ msgstr "FreeType-skrifttyper" + +#~ msgid "Game" +#~ msgstr "Spill" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Generer normale kart" + +#~ msgid "IPv6 support." +#~ msgstr "IPv6-støtte." + +#~ msgid "In-Game" +#~ msgstr "I-spillet" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Installasjon: fil \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Instrumentering" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Tastaturtilknytninger. (Hvis dette byr på problemer, fjern ting fra " +#~ "minetest.conf)" + +#~ msgid "Main" +#~ msgstr "Hovedmeny" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "Hovedmeny" + +#~ msgid "Menus" +#~ msgstr "Menyer" + +#~ msgid "Name / Password" +#~ msgstr "Navn / passord" + +#~ msgid "Name/Password" +#~ msgstr "Navn/passord" + +#~ msgid "No" +#~ msgstr "Nei" + +#~ msgid "Ok" +#~ msgstr "Okei" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallakse Okklusjon" + +#~ msgid "Path to save screenshots at." +#~ msgstr "Filsti til lagring av skjermdumper." + +#~ msgid "Player name" +#~ msgstr "Spillernavn" + +#~ msgid "Profiling" +#~ msgstr "Profilering" + +#~ msgid "PvP enabled" +#~ msgstr "Alle mot alle er på" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Tilbakestill enkeltspillerverden" + +#~ msgid "Select Package File:" +#~ msgstr "Velg pakkefil:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Server/alene" + +#~ msgid "Special" +#~ msgstr "Spesial" + +#~ msgid "Special key" +#~ msgstr "Spesialtast" + +#~ msgid "Start Singleplayer" +#~ msgstr "Start enkeltspiller" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "OpenGL-driveren må brukes for å aktivere skyggelegging." + +#~ msgid "View" +#~ msgstr "Vis" + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Y-verdi for øvre grense for lava i store grotter." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Hvilket Y-nivå som skyggen til luftøyer når." + +#~ msgid "Yes" +#~ msgstr "Ja" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Dette er første gang du kobler deg til serveren «\"%s».\n" +#~ "Om du fortsetter, vil det opprettes en ny konto med ditt navn og passord " +#~ "på denne serveren.\n" +#~ "Vennligst skriv inn et passord og klikk på «Registrer meg og bli med» for " +#~ "å bekrefte opprettelse av konto, eller klikk « Avbryt» for å avbryte." + +#~ msgid "You died." +#~ msgstr "Du døde." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/nl/minetest.po b/po/nl/minetest.po new file mode 100644 index 0000000..958f1d1 --- /dev/null +++ b/po/nl/minetest.po @@ -0,0 +1,8424 @@ +msgid "" +msgstr "" +"Project-Id-Version: Dutch (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2021-12-29 20:51+0000\n" +"Last-Translator: Gert-dev <qnyasgjhapqyuhoibr@kiabws.com>\n" +"Language-Team: Dutch <https://hosted.weblate.org/projects/minetest/minetest/" +"nl/>\n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.10.1\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Wachtrij voor uitgezonden berichten legen" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Instructie voor legen." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Terug naar hoofd menu" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Ongeldige instructie " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Opgegeven instructie: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Online spelers weergeven" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Online spelers: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "De wachtrij voor uitgezonden berichten is nu leeg." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Deze instructie is uitgeschakeld door de server." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Herboren worden" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Je bent gestorven" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Beschikbare instructies:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Beschikbare instructies: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Instructie niet beschikbaar: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Krijg hulp voor instructies" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Gebruik '.help <cmd>' om meer informatie te verkrijgen, of '.help all' om " +"alles weer te geven." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <commando>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Oke" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<geen beschikbaar>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Er is een fout opgetreden in een Lua script:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Er is een fout opgetreden:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Hoofdmenu" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Opnieuw verbinding maken" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "De server heeft gevraagd opnieuw verbinding te maken:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Selecteer Mods" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protocol versie stemt niet overeen. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "De server vereist protocol versie $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "De server ondersteunt protocol versies tussen $1 en $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Wij ondersteunen enkel protocol versie $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Wij ondersteunen protocol versies $1 tot en met $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Annuleer" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Afhankelijkheden:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Allemaal uitschakelen" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Modpack uitschakelen" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Alles aanzetten" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Modpack inschakelen" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Mod \"$1\" kan niet gebruikt worden: de naam bevat ongeldige karakters. " +"Enkel [a-z0-9_] zijn toegestaan." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Zoek Meer Mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Geen (optionele) afhankelijkheden" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Geen spelbeschrijving aanwezig." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Geen afhankelijkheden" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Geen modpack-beschrijving aanwezig." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Geen optionele afhankelijkheden" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Optionele afhankelijkheden:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Opslaan" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Wereld:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "aangeschakeld" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" bestaat al. Wilt u het overschrijven ?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Afhankelijkheden $1 en $2 zullen geïnstalleerd worden." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 door $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 is aan het downloaden,\n" +"$2 is ingepland" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 is aan het downloaden..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 benodigde afhankelijkheden werden niet gevonden." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" +"$1 zal worden geïnstalleerd, en $2 afhankelijkheden worden overgeslagen." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Alle pakketten" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Reeds geïnstalleerd" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Terug naar hoofdmenu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Basis Spel:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" +"ContentDB is niet beschikbaar wanneer Minetest compileert is zonder cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Downloaden..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Installeren van mod $1 is mislukt" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Spellen" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Installeren" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Installeer $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Installeer ontbrekende afhankelijkheden" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Installeren: Niet ondersteund bestandstype of defect archief" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mods" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Er konden geen pakketten geladen worden" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Geen resultaten" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Geen updates" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Niet gevonden" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Overschrijven" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Controleer of het basis spel correct is, aub." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Ingepland" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Textuur verzamelingen" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Verwijder" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Update" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Allemaal bijwerken [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Bekijk meer informatie in een webbrowser" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Een wereld met de naam \"$1\" bestaat al" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Extra terrein" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Temperatuurdaling vanwege hoogte" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Vochtigheidsverschil vanwege hoogte" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Vegetatie mix" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Vegetaties" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Grotten" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Grotten" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Maak aan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Decoraties" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "" +"Waarschuwing: Het minimale ontwikkellaars-test-spel is bedoeld voor " +"ontwikkelaars." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Kerkers" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Vlak terrein" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Zwevende gebergtes" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Zwevende eilanden (experimenteel)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Een niet-fractaal terrein genereren: Oceanen en ondergrond" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Heuvels" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Irrigerende rivier" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Verhoogt de luchtvochtigheid rond rivieren" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Installeer $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Meren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Lage luchtvochtigheid en hoge hitte zorgen voor ondiepe of droge rivieren" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Wereldgenerator" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Wereldgenerator vlaggen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Mapgeneratie-specifieke vlaggen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Bergen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Modderstroom" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Netwerk van tunnels en grotten" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Geen spel geselecteerd" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Verminderen van hitte met hoogte" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Vermindert de luchtvochtigheid met hoogte" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Rivieren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Rivieren op zeeniveau" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Kiemgetal" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Zachte overgang tussen vegetatiezones" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Structuren verschijnen op het terrein (geen effect op bomen en jungle gras " +"gemaakt door v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Structuren verschijnen op het terrein, voornamelijk bomen en planten" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Gematigd, Woestijn" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Gematigd, Woestijn, Oerwoud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Gematigd, Woestijn, Oerwoud, Toendra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Terreinoppervlakte erosie" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Bomen en oerwoudgras" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Wisselende rivierdiepte" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Zeer grote en diepe grotten" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Wereld naam" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Je hebt geen spellen geïnstalleerd." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Weet je zeker dat je \"$1\" wilt verwijderen?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Verwijderen" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: kan mod \"$1\" niet verwijderen" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: ongeldig pad voor mod \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Verwijder wereld \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Herhaal wachtwoord" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Wereldgenerator" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Naam" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Wachtwoord" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "De wachtwoorden zijn niet gelijk!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Registreer en doe mee" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Accepteren" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Modverzameling hernoemen:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Deze modpack heeft een expliciete naam gegeven in zijn modpack.conf die elke " +"hernoeming hier zal overschrijven." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Er is geen beschrijving van deze instelling beschikbaar)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D Ruis" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Terug naar instellingen" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Bladeren" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Inhoud" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Inhoud" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Uitgeschakeld" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Aanpassen" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Ingeschakeld" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lacunaritie" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Octaven" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "afstand" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Persistentie" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Voer een geldig geheel getal in." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Voer een geldig getal in." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Herstel de Standaardwaarde" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Schaal" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Zoeken" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Selecteer map" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Selecteer bestand" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Technische namen weergeven" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "De waarde moet tenminste $1 zijn." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "De waarde mag niet groter zijn dan $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X spreiding" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y spreiding" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z spreiding" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "absolute waarde" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "standaard" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "makkelijker" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Ingeschakeld)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mods" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Installeren van mod $1 in $2 is mislukt" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Mod installeren: kan de echte mod-naam niet vinden voor: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Mod installeren: kan geen geschikte map naam vinden voor mod verzameling $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Niet mogelijk om geschikte map-naam vinden voor modverzameling $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Kan $1 niet als textuurpakket installeren" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Installeren van een spel als $1 mislukt" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Installeren van mod $1 in $2 is mislukt" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Installeren van mod verzameling $1 in $2 is mislukt" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Laden..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Publieke serverlijst is uitgeschakeld" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Probeer de publieke serverlijst opnieuw in te schakelen en controleer de " +"internet verbinding." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Over" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Andere actieve ontwikkelaars" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Actieve renderer:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Hoofdontwikkelaars" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Open de gebruikersdatamap" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Open de map die de door de gebruiker aangeleverde werelden, spellen, mods\n" +"en textuur pakketten bevat in een bestandsbeheer toepassing / verkenner." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Vroegere ontwikkelaars" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Vroegere hoofdontwikkelaars" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Toon debug informatie" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Content op internet bekijken" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Inhoud" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Uitschakelen Textuurverzameling" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informatie:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Geïnstalleerde pakketen:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Geen afhankelijkheden." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Geen pakketbeschrijving beschikbaar" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Hernoemen" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Pakket verwijderen" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Gebruik textuurverzamelingen" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Server aanmelden bij de server-lijst" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Lokaal server-adres" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Creatieve modus" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Verwondingen inschakelen" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Spel Hosten" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Server Hosten" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Installeer spellen van ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Nieuw" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Geen wereldnaam opgegeven of geen wereld aangemaakt!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Spel Starten" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Poort" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Selecteer Mods" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Selecteer Wereld:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Server Poort" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Start spel" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adres" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Wissen" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Creatieve modus" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Schade / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favorieten" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Incompatibele Servers" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Join spel" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Publieke Servers" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Verversen" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Poort van externe server" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Omschrijving van de Server" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D wolken" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Alle Instellingen" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Antialiasing:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Schermafmetingen automatisch bewaren" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilineair filteren" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Toetsen aanpassen" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Verbonden Glas" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dynamische schaduwen" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Dynamische schaduwen: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Mooie bladeren" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Hoog" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Laag" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Gemiddeld" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Anisotropisch filteren" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Geen Filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Geen Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Node licht op" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Node is omlijnd" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Geen" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Ondoorzichtige bladeren" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Ondoorzichtig water" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Effectdeeltjes" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Scherm:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Instellingen" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shaders" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shaders (experimenteel)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Shaders (niet beschikbaar)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Eenvoudige bladeren" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Vloeiende verlichting" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Textuur:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Tone-mapping" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Toetsgrenswaarde: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Trilineair filteren" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Zeer Hoog" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Zeer Laag" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Bewegende bladeren" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Golvende Vloeistoffen" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Bewegende planten" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Fout bij verbinden (time out?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Time-out bij opzetten verbinding." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Klaar!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Nodes initialiseren" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Nodes initialiseren..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Texturen laden..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Shaders herbouwen..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Fout bij verbinden (time out?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Kan het spel niet vinden of laden: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Onjuiste spel-spec." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Hoofdmenu" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Geen wereld geselecteerd en geen adres opgegeven. Niets te doen." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Speler-naam is te lang." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Kies alsjeblieft een naam!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Opgegeven wachtwoordbestand kan niet worden geopend: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Het gespecificeerde wereld-pad bestaat niet: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Kijk in debug.txt voor details." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Adres: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Mode(creatief/overleving): " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Poort: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Openbaar: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Server Naam: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Er is een serialisatie-fout opgetreden:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Toegang geweigerd. Reden: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Automatisch vooruit uitgeschakeld" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Automatisch vooruit ingeschakeld" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Blokgrenzen verborgen" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Blokgrenzen getoond voor alle blokken" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Blokgrenzen getoond voor huidige blok" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Blokgrenzen getoond voor nabije blokken" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Camera-update uitgeschakeld" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Camera-update ingeschakeld" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "Kan blokgrenzen niet tonen (privilege 'basic_debug' is nodig)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Verander wachtwoord" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Filmische modus uitgeschakeld" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Filmische modus ingeschakeld" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Gebruiker heeft verbinding verbroken" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Client-side scripting is uitgeschakeld" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Verbinding met de server wordt gemaakt..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Verbinding mislukt om onbekende reden" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Verder spelen" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Besturing: \n" +"-%s: ga vooruit \n" +"-%s: ga achteruit \n" +"-%s: ga naar links \n" +"-%s: ga naar rechts \n" +"-%s: springen / klimmen \n" +"-%s: graaf/duw\n" +"-%s: plaats/gebruik \n" +"-%s: sluip / ga naar beneden \n" +"-%s: drop item \n" +"-%s: inventaris \n" +"- Muis: draaien / kijken \n" +"- Muiswiel: item selecteren \n" +"-%s: chat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Adres kon niet opgezocht worden: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Gebruiker aanmaken..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Bezig server te maken..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Debug info en profiler grafiek verborgen" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Debug informatie weergegeven" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Debug info, profiler grafiek en wireframe verborgen" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Standaardbesturing:\n" +"Geen menu getoond:\n" +"- enkele tik: activeren\n" +"- dubbele tik: plaats / gebruik\n" +"- vinger schuiven: rondkijken\n" +"Menu of inventaris getoond:\n" +"- dubbele tik buiten menu:\n" +" --> sluiten\n" +"- aanraken stapel of vak:\n" +" --> stapel verplaatsen\n" +"- aanraken & slepen, tik met tweede vinger\n" +" --> plaats enkel object in vak\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Oneindige kijkafstand uitgezet" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Oneindige kijkafstand aangezet" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Gebruiker aanmaken..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Terug naar menu" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Afsluiten" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Snelle modus uitgeschakeld" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Snelle modus ingeschakeld" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Snelle modus ingeschakeld (let op: geen 'fast' recht)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Vlieg modus uitgeschakeld" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Vlieg modus ingeschakeld" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Vliegmodus ingeschakeld (let op: geen 'fly'-privilege)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Mist uitgeschakeld" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Mist ingeschakeld" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Spel info:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Spel gepauzeerd" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Server maken" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Voorwerpdefinities..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Media..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Mini-kaart momenteel uitgeschakeld door spel of mod" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Multiplayer" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Noclip-modus uitgeschakeld" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Noclip-modus ingeschakeld" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Noclip-modus ingeschakeld (opmerking: geen 'noclip' recht)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Node definities..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Uit" + +#: src/client/game.cpp +msgid "On" +msgstr "Aan" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Pitch move-modus uitgeschakeld" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Pitch move-modus ingeschakeld" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profiler-grafiek weergegeven" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Externe server" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Server-adres opzoeken..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Uitschakelen..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Singleplayer" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Geluidsvolume" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Geluid gedempt" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Systeemgeluiden zijn uitgeschakeld" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Geluidssysteem is niet ondersteund in deze versie" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Geluid niet gedempt" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "De server gebruikt waarschijnlijk een andere versie van %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Kon niet verbinden met %s omdat IPv6 uitgeschakeld werd" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Kon niet luisteren naar %s omdat IPv6 uitgeschakeld werd" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Kijkbereik gewijzigd naar %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Het kijkbereik is maximaal: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Het kijkbereik is minimaal: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Volume gewijzigd naar %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Draadframe weergegeven" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zoom momenteel uitgeschakeld door game of mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "oké" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Chat verborgen" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Chat weergegeven" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD verborgen" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD getoond" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profiler verborgen" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profiler getoond (pagina %d van %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Terug" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Hoofdletter vergrendeling" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Omlaag" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Einde" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Verwijder EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Uitvoeren" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Help" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME Accepteren" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME Converteren" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME Ontsnappen" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Modus veranderen" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME Niet-converteren" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Links" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Linkermuisknop" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Linker Ctrl" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Linker Menu" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Linker Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Linker Windowstoets" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Muiswielknop" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numeriek pad *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numeriek pad +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numpad -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numeriek pad ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numpad /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numpad 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numpad 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numpad 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numpad 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numpad 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numpad 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numpad 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numpad 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numpad 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numpad 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM duidelijk" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Pagina omlaag" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Pagina omhoog" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pauze" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Spelen" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Schermafbeelding" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Rechts" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Rechtmuisknop" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Rechter Ctrl" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Rechter Menu" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Rechter Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Rechter Windowstoets" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Selecteren" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Slaapknop" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Screenshot" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Spatie" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Omhoog" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X knop 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X knop 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoomen" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Mini-kaart verborgen" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Mini-kaart in radar modus, Zoom x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimap in oppervlaktemodus, Zoom x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimap textuur modus" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Openen van webpagina mislukt" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Website openen" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Doorgaan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = naar beneden klimmen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Automatisch Vooruit" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Automatisch springen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Achteruit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Blok grenzen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Camera veranderen" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Chatten" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Opdracht" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Console" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Zichtafstand verkleinen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Volume verminderen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "2x \"springen\" schakelt vliegen aan/uit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Weggooien" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Vooruit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Afstand verhogen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Volume verhogen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "inventaris" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Springen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Toets is al in gebruik" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Lokale commando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Dempen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Volgende item" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Vorig element" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Zichtbereik" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Screenshot" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Sluipen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Schakel HUD in/uit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Chatlogboek wisselen" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Snel bewegen aan/uit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Vliegen aan/uit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Schakel mist in/uit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Schakel mini-kaart in/uit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Noclip aan/uit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Schakel pitchmove aan/uit" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "druk op toets" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Veranderen" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nieuw wachtwoord" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Huidig wachtwoord" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "De wachtwoorden zijn niet gelijk!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Terug" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Gedempt" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Geluidsvolume: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "nl" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Kies alsjeblieft een naam!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Corrigeert de positie van virtuele joystick. \n" +"Indien uitgeschakeld, wordt de virtuele joystick gecentreerd op de positie " +"van de eerste aanraking." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Gebruik virtuele joystick om de \"aux\"-knop te activeren.\n" +"Indien ingeschakeld, zal de virtuele joystick ook op de \"aux\"-knop tikken " +"wanneer deze buiten de hoofdcirkel is." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"X, Y, Z) offset van fractal van wereldcentrum in eenheden van 'schaal'. \n" +"Kan worden gebruikt om een gewenst punt naar (0, 0) te verplaatsen om een \n" +"geschikt spawnpunt, of om 'inzoomen' op een gewenst \n" +"punt mogelijk te maken punt door 'schaal' te vergroten. \n" +"De standaard is afgestemd op een geschikt spawn-punt voor Mandelbrot \n" +"sets met standaardparameters, moet deze mogelijk in andere \n" +"worden gewijzigd situaties. \n" +"Bereik ongeveer -2 tot 2. Vermenigvuldig met 'schaal' voor offset in " +"knooppunten." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X, Y, Z) schaal van fractal in knooppunten. \n" +"De werkelijke fractale grootte is 2 tot 3 keer groter. \n" +"Deze getallen kunnen heel groot gemaakt worden, \n" +"de fractal wel hoeven niet in de wereld te passen. \n" +"Verhoog deze om te 'zoomen' tot in de details van de fractal. \n" +"Standaard is voor een verticaal geplette vorm geschikt voor \n" +"een eiland, stel alle 3 getallen gelijk voor de ruwe vorm." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2D-ruis die de vorm/grootte van geribbelde bergen bepaalt." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2D-ruis die de vorm / grootte van glooiende heuvels bepaalt." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2D-ruis die de vorm / grootte van step-bergen regelt." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" +"2D-ruis die de grootte / het voorkomen van geribbelde bergketens regelt." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D-ruis die de grootte / het optreden van glooiende heuvels regelt." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "2D-ruis die de grootte / het optreden van bergketens regelt." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2D-ruis die de rivierdalen en -kanalen lokaliseert." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D wolken" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D modus" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Sterkte van parallax in 3D modus" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D ruis voor grote holtes." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D ruis voor het definiëren van de structuur en de hoogte van gebergtes of " +"hoge toppen.\n" +"Ook voor de structuur van bergachtig terrein om zwevende eilanden." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"3D ruis om de vorm van de zwevende eilanden te bepalen.\n" +"Als de standaardwaarde wordt gewijzigd, dan moet de waarde van de " +"geluidsschaal,\n" +"standaard ingesteld op 0.7 gewijzigd worden, aangezien de afschuinings-" +"functies van de zwevende eilanden\n" +"het beste werkt met een waarde tussen -2.0 en 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "3D ruis voor wanden van diepe rivier kloof." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3D-ruisbepalend terrein." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"3D-ruis voor overhangende bergen, kliffen, etc. Meestal kleine variaties." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D-ruis die het aantal kerkers per mapchunk bepaalt." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3D ondersteuning.\n" +"Op dit moment ondersteund:\n" +"- none: geen 3D.\n" +"- anaglyph: 3D met de kleuren cyaan en magenta.\n" +"- interlaced: 3D voor polariserend scherm (even/oneven beeldlijnen).\n" +"- topbottom: 3D met horizontaal gedeeld scherm (boven/onder).\n" +"- sidebyside: 3D met verticaal gedeeld scherm (links/rechts).\n" +"- crossview: Schele 3d\n" +"- pageflip: 3D met vier buffers ('quad buffer').\n" +"Merk op dat de geïnterlinieerde modus vereist dat shaders zijn ingeschakeld." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Een gekozen kaartzaad voor een nieuwe kaart, laat leeg voor willekeurig. \n" +"Wordt overschreven bij het creëren van een nieuwe wereld in het hoofdmenu." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" +"Een bericht dat wordt getoond aan alle verbonden spelers als de server " +"crasht." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Een bericht dat wordt getoond aan alle verbonden spelers als de server " +"afgesloten wordt." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Interval voor ABM's" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "ABM tijd budget" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Maximaal aantal 'emerge' blokken in de wachtrij" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Versnelling in lucht" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Versnelling van de zwaartekracht, in knopen per seconde per seconde." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Actieve blokken wijzigers (ABMs)" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Actief blokbeheerinterval" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Bereik waarbinnen blokken actief zijn" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Bereik waarbinnen actieve objecten gestuurd worden" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Standaard serveradres waarmee verbinding gemaakt moet worden.\n" +"Indien leeg, wordt een lokale server gestart.\n" +"In het hoofdmenu kan een ander adres opgegeven worden." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Voeg opvliegende deeltjes toe bij het graven." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Pas de dpi-configuratie aan op uw scherm (alleen niet X11 / Android), b.v. " +"voor 4k-schermen." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Pas de gedetecteerde weergavedichtheid aan, gebruikt om elementen uit de " +"gebruikersinterface te schalen." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Past de densiteit van de zwevende eilanden aan.\n" +"De densiteit verhoogt als de waarde verhoogt. Kan positief of negatief " +"zijn.\n" +"Waarde = 0,0 : 50% van het volume is een zwevend eiland.\n" +"Waarde = 2.0 : een laag van massieve zwevende eilanden\n" +"(kan ook hoger zijn, afhankelijk van 'mgv7_np_floatland', altijd testen om " +"zeker te zijn)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Voeg itemnaam toe" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Geavanceerd" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Verandert de lichtcurve door er 'gammacorrectie' op toe te passen. \n" +"Hogere waarden maken het middelste en lagere lichtniveau helderder. \n" +"Waarde '1.0' laat de lichtcurve ongewijzigd. \n" +"Dit heeft alleen een significant effect op daglicht en kunstmatig \n" +"licht, heeft het weinig effect op natuurlijk nachtlicht." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Zet 'snel' altijd aan bij 'vliegen'" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "omringende Occlusie gamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Aantal berichten dat een speler per 10 seconden mag verzenden." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Versterkt de valleien." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Anisotropisch filteren" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Meldt server aan bij de server-lijst" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Kondig aan op deze serverlijst." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Voeg itemnaam toe" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Voeg itemnaam toe aan knopinfo." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Appel boom geluid" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Arm traagheid" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Arm traagheid, geeft een meer realistische beweging van \n" +"de arm wanneer de camera beweegt." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "verbinding herstellen na een server-crash" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"Op deze afstand zal de server agressief optimaliseren naar welke blokken " +"gestuurd worden \n" +"gebruikers. \n" +"Kleine waarden kunnen de prestaties mogelijk aanzienlijk verbeteren, ten " +"koste van zichtbaar \n" +"rendering glitches (sommige blokken worden niet onder water en in grotten " +"weergegeven, \n" +"evenals soms op het land). \n" +"Als u dit instelt op een waarde die groter is dan max_block_send_distance, " +"wordt dit uitgeschakeld \n" +"optimalisatie. \n" +"Vermeld in mapblocks (16 blokken)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Automatisch Vooruit toets" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Spring automatisch op obstakels met één knooppunt." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Server automatisch aan melden bij de serverlijst." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Scherm afmetingen automatisch bewaren" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Automatische schaalmodus" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Aux1-toets" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Aux1-toets voor klimmen/afdalen" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Achteruit" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Basis grondniveau" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Basis terrein hoogte." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Basis rechten" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Strand geluid" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Strand geluid grenswaarde" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilineair filteren" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Lokaal server-adres" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Biome API parameters voor temperatuur- en vochtigheidsruis" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Biome-ruis" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Blok verzend optimalisatie afstand" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Vet en cursief pad" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Vet en cursief monospace-lettertypepad" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Vet lettertypepad" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Vet monospace-lettertypepad" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Bouwen op de plaats van de speler" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Ingebouwd" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Camera veranderen" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Camera 'near clipping plane' afstand in knooppunten, tussen 0 en 0,25 \n" +"Werkt alleen op GLES-platforms. De meeste gebruikers hoeven dit niet te " +"wijzigen. \n" +"Verhogen kan artefacten op zwakkere GPU's verminderen. \n" +"0,1 = standaard, 0,25 = goede waarde voor zwakkere tablets." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Vloeiender camerabeweging" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Vloeiendere camerabeweging (in cinematic modus)" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Toets voor het aan of uit schakelen van cameraverversing" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Grot ruis" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Grot ruispatroon #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Grot ruispatroon #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Grot breedte" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Grot1 ruis" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Grot2 ruis" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Grot limiet" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Grot ruis" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Grot hoogtepunt" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Grot drempel" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Bovengrens grot" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Midden van het lichtcurve-boostbereik. \n" +"Waar 0,0 het minimale lichtniveau is, is 1,0 het maximale lichtniveau." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Tijdsdrempel voor berichten chatcommando's" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Chatcommando's" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Chat lettergrootte" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Chat-toets" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Chat debug logniveau" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Limiet aantal chatberichten" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Chatbericht formaat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Drempel voor kick van chatbericht" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Maximale lengte chatbericht" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Toets voor tonen/verbergen chat" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Weblinks chat" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Chunk-grootte" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Cinematic modus" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Cinematic modus aan/uit toets" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Schone transparante texturen" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Aanklikbare weblinks (middelklik of ctrl+linkermuisklik) ingeschakedl in " +"console-uitvoer chat." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Cliënt" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Cliënt en server" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Cliënt personalisatie (modding)" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Aanpassingen aan clientzijde" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Clientzijde blok opzoekbereikbeperking" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Cliënt personalisatie (modding)" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Klimsnelheid" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Diameter van de wolken" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Wolken" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Wolken bestaan enkel op de cliënt." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Wolken in het menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Gekleurde mist" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Gekleurde schaduwen" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Door komma's gescheiden lijst met vlaggen om te verbergen in de " +"inhoudsbibliotheek. \n" +"\"nonfree\" kan gebruikt worden om pakketten te verbergen die niet " +"kwalificeren als 'vrije software', \n" +"zoals gedefinieerd door de Free Software Foundation. \n" +"U kunt ook inhoudsclassificaties specificeren. \n" +"Deze vlaggen zijn onafhankelijk van Minetest-versies, \n" +"zie dus een volledige lijst op https://content.minetest.net/help/" +"content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Door komma's gescheiden lijst met mods die toegang hebben tot HTTP API's, " +"die \n" +"sta hen toe om gegevens van / naar internet te uploaden en te downloaden." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Komma gescheiden lijst van vertrouwde mods die onveilige functies mogen " +"gebruiken,\n" +"zelfs wanneer mod-beveiliging aan staat (via request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Commando-toets" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Compressieniveau bij bewaren mapblokken op harde schijf.\n" +"-1 - standaardcompressieniveau\n" +"0 - minste compressie, snelst\n" +"9 - meeste compressie, traagst" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Compressieniveau bij versturen mapblokken naar cliënt.\n" +"-1 - standaardcompressieniveau\n" +"0 - minste compressie, snelst\n" +"9 - meeste compressie, traagst" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Verbind glas" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Gebruik van externe media-server toestaan" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" +"Verbind glas-nodes met elkaar (indien ondersteund door het type node/blok)." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Console-alphawaarde" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Console-kleur" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Hoogte console" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Online inhoud repository" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "ContentDB optie: verborgen pakketten lijst" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "ContentDB Maximum Gelijktijdige Downloads" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "ContentDB-URL" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Continu vooruit lopen" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Continue voorwaartse beweging, geschakeld door autoforward-toets. \n" +"Druk nogmaals op de autoforward-toets of de achterwaartse beweging om uit te " +"schakelen." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Besturing" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Regelt de lengte van de dag/nacht-cyclus. \n" +"Voorbeelden: \n" +"72 = 20 min, 360 = 4 min, 1 = 24 uur, 0 = dag nacht /wat dan ook onveranderd " +"blijft." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Bepaalt steilheid/diepte van meer depressies." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Bepaalt steilheid/hoogte van heuvels." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Bepaalt de breedte van tunnels, een kleinere waarde creëert bredere " +"tunnels. \n" +"Waarde> = 10,0 schakelt het genereren van tunnels volledig uit en vermijdt " +"de \n" +"intensieve geluidsberekeningen." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Crashbericht" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Creatief" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Draadkruis-alphawaarde" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Alfawaarde crosshair (ondoorzichtigheid, tussen 0 en 255).\n" +"Ook van toepassing op de crosshair voor objecten." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Draadkruis-kleur" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Draadkruis kleur (R,G,B).\n" +"Controleert ook het object draadkruis kleur" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "Scherm DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Verwondingen/schade" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Toets voor aan/uitzetten debug informatie" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Debug logbestand drempel" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Debug logniveau" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Volume verlagen toets" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Toegewijde serverstap" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Standaardversnelling" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Standaardspel" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Standaardspel bij het maken een nieuwe wereld.\n" +"In het hoofdmenu kan een ander spel geselecteerd worden." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Standaardwachtwoord" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Standaard rechten" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Standaardformaat voor rapport-bestanden" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Standaard voorwerpenstapel grootte" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Definieer kwaliteit schaduwfiltering\n" +"Dit simuleert zachte schaduwen d.m.v. een PCF of Poisson-schijf\n" +"maar is ook gebruiksintensiever." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Bepaalt gebieden met appels in de bomen." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Bepaalt gebieden met zandstranden." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Definieert de verdeling van hoger terrein en steilheid van kliffen." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Definieert de verdeling van hoger terrein." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Bepaalt de grootte van grotten, kleinere waarden geven grotere grotten." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Bepaalt de grootschalige rivierkanaal structuren." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Bepaalt de plaats van bijkomende heuvels en vijvers." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Definieert het basisgrondniveau." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Definieert de diepte van het rivierkanaal." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Maximale afstand (in blokken van 16 nodes) waarbinnen andere spelers " +"zichtbaar zijn (0 = oneindig ver)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Definieert de breedte van het rivierkanaal." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Definieert de breedte van de riviervallei." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Bepaalt de gebieden met bomen en hun dichtheid." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Tussenpauze tussen bijwerkingen van de maas weergave bij de cliënt in ms.\n" +"Dit verhogen zal de bijwerkingen vertragen wat flikkeringen op langzamere " +"cliënten moet verminderen." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Vertraging bij het versturen van blokken na het bouwen" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Vertraging bij het tonen van tooltips, in milliseconden." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Gedrag bij gebruik van verouderde Lua API functies" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Diepte waaronder je gigantische grotten vindt." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Diepte waaronder je grote grotten vind." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Beschrijving van de server. Wordt getoond in de server-lijst, en wanneer " +"spelers inloggen." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Woestijn ruis drempelwaarde" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Woestijnen treden op wanneer np_biome deze waarde overschrijdt. \n" +"Als de vlag 'snowbiomes' is ingeschakeld, wordt dit genegeerd." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Textuur-animaties niet synchroniseren" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Decoraties" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Toets voor graven" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Graaf deeltjes" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Valsspeelbescherming uitschakelen" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Lege wachtwoorden niet toestaan" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Weergavedichtheid-schaalfactor" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Domeinnaam van de server; wordt getoond in de serverlijst." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "2x \"springen\" om te vliegen" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "2x \"springen\" schakelt vlieg-modus aan/uit." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Weggooi-toets" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Dump de mapgen-debug informatie." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Dungeon maximaal Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Dungeon minimaal Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Lawaai in kerkers" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Schakel IPv6-ondersteuning in (voor zowel client als server). \n" +"Vereist om IPv6-verbindingen te laten werken." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Schakel Lua modding ondersteuning op cliënt in.\n" +"Deze ondersteuning is experimenteel en de API kan wijzigen." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Filteren d.m.v. Poisson-schijf inschakelen.\n" +"Indien ingeschakeld, wordt een Poisson-schijf gebruikt om zachte schaduwen " +"te genereren. In het andere geval wordt PCF-filteren toegepast." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Gekleurde schaduwen inschakelen.\n" +"Indien ingeschakeld werpen doorzichtige nodes gekleurde schaduwen af. Dit is " +"arbeidsintensief." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Schakel het console venster in" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Schakel creatieve modus in voor alle spelers" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Schakel joysticks in" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Ondersteuning voor mod-kanalen inschakelen." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Veilige modus voor mods aanzetten" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Schakel verwondingen en sterven van spelers aan." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Schakel willkeurige invoer aan (enkel voor testen)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Vloeiende verlichting met eenvoudige ambient occlusion aanschakelen.\n" +"Schakel dit uit voor minder vertraging, of voor een ander visueel effect." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Zet dit aan om verbindingen van oudere cliënten te weigeren.\n" +"Oudere cliënten zijn compatibel, in de zin dat ze niet crashen als ze " +"verbinding \n" +"maken met nieuwere servers, maar ze ondersteunen wellicht niet alle nieuwere " +"mogelijkheden." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Sta het gebruik van een externe media-server toe (indien opgegeven door de " +"server).\n" +"Het gebruik van externe media-servers versnelt het downloaden van media\n" +"(bijv. texturen) aanzienlijk bij het maken van een verbinding met een server." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Vertex-bufferobjecten inschakelen. \n" +"Dit zou de grafische prestaties aanzienlijk moeten verbeteren." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Vermenigvuldigingsfactor van loopbeweging.\n" +"Bijvoorbeeld:\n" +"0 voor geen loopbeweging.\n" +"1.0 voor normale loopbeweging.\n" +"2.0 voor twee keer grotere loopbeweging." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Schakel het uitvoeren van een IPv6-server in/uit. \n" +"Wordt genegeerd als bind_address is ingesteld. \n" +"Moet inschakelen_ipv6 moet worden ingeschakeld." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Maakt Hable's 'Uncharted 2' filmische tonemapping mogelijk. \n" +"Simuleert de tooncurve van fotografische film en hoe deze de \n" +"uiterlijk van afbeeldingen met een hoog dynamisch bereik. Het contrast in " +"het middenbereik is iets \n" +"verbeterd, worden hooglichten en schaduwen geleidelijk gecomprimeerd." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Schakelt animatie van inventaris items aan." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Schakelt caching van facedir geroteerde meshes." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Schakelt de mini-kaart in." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Schakelt het geluidssysteem in. \n" +"Als deze optie is uitgeschakeld, worden alle geluiden overal en in de game \n" +"volledig uitgeschakeld geluidsbesturingen zullen niet functioneel zijn. \n" +"Het wijzigen van deze instelling vereist een herstart." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Vallei-profiel" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Profilergegevens print interval" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Entiteit-functies" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Exponent voor de afschuining van het zwevende eiland. Wijzigt de " +"afschuining.\n" +"Waarde = 1.0 maakt een uniforme, rechte afschuining.\n" +"Waarde > 1.0 maakt een vloeiende afschuining voor standaard gescheiden\n" +"zwevende eilanden.\n" +"Waarde < 1.0 (bijvoorbeeld 0.25) maakt een meer uitgesproken oppervlak met \n" +"platte laaglanden, geschikt voor een solide zwevende eilanden laag." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS als het spel gepauzeerd of niet gefocussed is" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Ruis factor" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Val dobberende factor" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Terugvallettertype" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Snel toets" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Versnelling in snelle modus" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Snelheid in snelle modus" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Snelle modus" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Snelle beweging (via de \"Aux1\"-toets).\n" +"Dit vereist het recht \"snel bewegen\" op de server." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Zichthoek" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Zichthoek in graden." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Bestand in client / serverlijst / dat uw favoriete servers bevat die worden " +"weergegeven in de \n" +"Tabblad Multiplayer." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Vuldiepte" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Vuldiepte ruis" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Filmisch tone-mapping" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Gefilterde texturen kunnen RGB-waarden mengen met die van volledig\n" +"transparante buren, die door PNG-optimalisatoren vaak verwijderd worden,\n" +"wat vaak voor donkere of lichtere randen bij transparante texturen zorgt.\n" +"Gebruik een filter om dat tijdens het laden van texturen te herstellen. Dit " +"wordt\n" +"automatisch ingeschakeld als mipmapping aan staat." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Antialiasing:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Eerste van vier 2D geluiden die samen de hoogte van een heuvel of berg " +"bepalen." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Eerste van twee 3D geluiden voor tunnels." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Vast kiemgetal" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Vaste virtuele joystick" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Drijvend gebergte densiteit" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Maximaal Y-waarde van zwevende eilanden" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Minimum Y-waarde van zwevende eilanden" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Zwevende eilanden geluid" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Zwevend eiland vormfactor" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Zwevend eiland afschuinings-afstand" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Waterniveau van zwevend eiland" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Vliegen toets" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Vliegen" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Mist" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Begin van de nevel of mist" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Mist aan/uitschakelen toets" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Lettergrootte" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Standaard vetgedrukt" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Standaard cursief" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Fontschaduw" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Fontschaduw alphawaarde" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Lettergrootte" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Lettergrootte van het standaardlettertype in punt (pt)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Lettergrootte van het monospace-lettertype in punt (pt)." + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Tekstgrootte van de chatgeschiedenis en chat prompt in punten (pt).\n" +"Waarde 0 zal de standaard tekstgrootte gebruiken." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Formaat van chatberichten van spelers. De volgende tekenreeksen zijn geldige " +"tijdelijke aanduidingen: \n" +"@name, @message, @timestamp (optioneel)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Formaat van screenshots." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Formspec Standaard achtergrondkleur" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Formspec Standaard achtergronddekking" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Formspec Achtergrondkleur op volledig scherm" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Formspec Achtergronddekking op volledig scherm" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Chat console achtergrondkleur (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" +"Chat console achtergrond alphawaarde (ondoorzichtigheid, tussen 0 en 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Chat console achtergrondkleur (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" +"Chat console achtergrond alphawaarde (ondoorzichtigheid, tussen 0 en 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Vooruit toets" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Vierde van vier 3D geluiden die de hoogte van heuvels en bergen bepalen." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Fractaal type" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Fractie van de zichtbare afstand vanaf waar de nevel wordt getoond" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Tot welke afstand blokken gegenereerd worden voor cliënten. In mapblokken " +"(16 nodes)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Tot welke afstand blokken naar cliënten gestuurd worden. In mapblokken (16 " +"nodes)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Van hoe ver klanten weten over objecten, vermeld in mapblocks (16 " +"knooppunten). \n" +"\n" +"Het instellen van dit groter dan active_block_range zal ook de server \n" +"veroorzaken om actieve objecten tot deze afstand in de richting \n" +"van de speler kijkt. (Dit kan voorkomen dat mobs plotseling uit het zicht " +"verdwijnen)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Volledig scherm" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Volledig scherm modus." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "GUI schaalfactor" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "GUI schalingsfilter" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "GUI schalingsfilter: txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Spellen" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Algemene callbacks" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Algemene wereldgeneratorinstellingen.\n" +"In Mapgen v6 beïnvloedt de vlag \"decorations\" alle decoraties behalve " +"bomen.\n" +"en junglegras. In alle andere generatoren beïnvloedt deze vlag alle " +"decoraties." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Verloop van lichtkromme bij maximaal lichtniveau. \n" +"Regelt het contrast van de hoogste lichtniveaus." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Verloop van lichtkromme bij minimaal lichtniveau. \n" +"Regelt het contrast van de laagste lichtniveaus." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafisch" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafisch" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafisch" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Zwaartekracht" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Grondniveau" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Aarde/Modder geluid" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP Mods" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "GUI schaalfactor" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "HUD aan/uitschakelen toets" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Behandeling van verouderde Lua API aanroepen:\n" +"- none: log geen verouderde aanroepen\n" +"- log: boots het oude gedrag na, en log een backtrace van de aanroep " +"(standaard voor een 'debug' versie).\n" +"- error: stop de server bij gebruik van een verouderde aanroep " +"(aanbevolen voor mod ontwikkelaars)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Laat de profiler zichzelf profileren:\n" +"* Profileer een lege functie.\n" +" Dit geeft een schatting van de CPU-tijd die door de profiler zelf gebruikt " +"wordt (+1 functie-aanroep).\n" +"* Profileer de code die de statistieken ververst." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Geluid van landschapstemperatuurovergangen" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Hitte geluid" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Hoogtecomponent van de initiële grootte van het venster. Wordt genegeerd in " +"fullscreen-modus." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Hoogtegeluid" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Hoogte-selectie geluid" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Steilheid van de heuvels" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Heuvel-grenswaarde" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Heuvelsteilte ruis" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Heuvelachtigheid2 ruis" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Heuvelachtigheid3 ruis" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Heuvelachtigheid4 ruis" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Home-pagina van de server. Wordt getoond in de serverlijst." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Horizontale acceleratie in lucht bij springen of vallen, \n" +"in knooppunten per seconde per seconde." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Horizontale en verticale acceleratie in snelle modus, \n" +"in knooppunten per seconde per seconde." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Horizontale en verticale acceleratie op de grond of bij het klimmen, \n" +"in knooppunten per seconde per seconde." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Toets voor volgend gebruikte tool" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Toets voor vorig gebruikte tool" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Toets voor slot 1 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Toets voor slot 10 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Toets voor slot 11 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Toets voor slot 12 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Toets voor slot 13 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Toets voor slot 14 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Toets voor slot 15 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Toets voor slot 16 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Toets voor slot 17 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Toets voor slot 18 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Toets voor slot 19 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Toets voor slot 2 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Toets voor slot 20 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Toets voor slot 21 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Toets voor slot 22 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Toets voor slot 23 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Toets voor slot 24 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Toets voor slot 25 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Toets voor slot 26 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Toets voor slot 27 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Toets voor slot 28 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Toets voor slot 29 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Toets voor slot 3 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Toets voor slot 30 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Toets voor slot 31 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Toets voor slot 32 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Toets voor slot 4 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Toets voor slot 5 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Toets voor slot 6 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Toets voor slot 7 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Toets voor slot 8 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Toets voor slot 9 van gebruikte tools" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Diepte van de rivieren." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Hoe snel vloeibare golven zullen bewegen. Hoger = sneller. \n" +"Indien negatief, zullen vloeibare golven achteruit bewegen. \n" +"Vereist dat golvende vloeistoffen zijn ingeschakeld." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"De tijd die de server wacht voordat een ongebruikt mapblok vergeten wordt.\n" +"Een hogere waarde zorgt voor een vloeiender spelervaring, maar kost meer " +"geheugen." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Verlaag dit om de vloeistofweerstand te vergroten." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Breedte van rivieren." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Vochtigheid vermenging ruis" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Vochtigheid ruis" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Vochtigheidsvariatie voor biomen." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6 server" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Beperk de FPS tot maximaal deze waarde, zodat geen processor-\n" +"kracht verspild wordt zonder dat het toegevoegde waarde heeft." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Indien uitgeschakeld wordt de \"Aux1\"-toets gebruikt om snel te vliegen\n" +"als modi \"vliegen\" en \"snel\" beide aan staan." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Indien aan zal de server achterliggende map blokken niet tonen afgaande\n" +"op de oog positie van de speler. Dit kan de hoeveelheid blokken die naar de " +"cliënt\n" +"gestuurd worden met 50-80 % verminderen. De cliënt zal niet langer de " +"meeste\n" +"onzichtbare blokken ontvangen zodat noclip mode niet meer nodig is." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Indien deze optie aanstaat, in combinatie met \"vliegen\" modus, dan kan de\n" +"speler door vaste objecten heenvliegen.\n" +"Dit vereist het \"noclip\" voorrecht op de server." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Indien ingeschakeld wordt de \"Aux1\"-toets gebruikt i.p.v. de \"Sneak\"-" +"toets om\n" +"omlaag te klimmen en af te dalen." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Schakel registerbevestiging in wanneer u verbinding maakt met de server. \n" +"Indien uitgeschakeld, wordt een nieuw account automatisch geregistreerd." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Indien aangeschakeld worden speleracties opgeslagen zodat ze teruggerold " +"kunnen worden.\n" +"Deze instelling wordt alleen bij het starten van de server gelezen." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Valsspeelbescherming uitschakelen in multiplayer modus." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Zorg dat de server niet stopt in geval van ongeldige wereld-data.\n" +"Alleen aan te schakelen door spelers / server-beheerders die weten wat de " +"consequenties zijn." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Indien ingeschakeld, maakt verplaatsingsrichtingen ten opzichte van het veld " +"van de speler tijdens het vliegen of zwemmen." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Spelers kunnen zich niet aanmelden zonder wachtwoord indien aangeschakeld." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Indien aangeschakeld, kan een speler blokken plaatsen op de eigen positie\n" +"(het niveau van de voeten en van de ogen).\n" +"Dit vergemakkelijkt het werken in nauwe ruimtes." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Als de CSM-beperking voor het blok is ingeschakeld, zijn get_node-aanroepen " +"beperkt \n" +"tot deze afstand van de speler tot het blok." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Als het uitvoeren van een chatcommando langer duurt dan de opgegeven tijd\n" +"in seconden, voeg dan tijdsinformatie toe aan het bijhorende bericht" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Als de bestandsgrootte van debug.txt groter is dan het aantal megabytes dat " +"is opgegeven in \n" +"deze instelling wanneer het wordt geopend, wordt het bestand verplaatst naar " +"debug.txt.1, \n" +"het verwijderen van een oudere debug.txt.1 als deze bestaat. \n" +"debug.txt wordt alleen verplaatst als deze instelling positief is." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" +"Indien aangeschakeld, dan worden spelers altijd op deze locatie geboren." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Wereldfouten negeren" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Chat console achtergrond alphawaarde (ondoorzichtigheid, tussen 0 en 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Chat console achtergrondkleur (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"Chat console achtergrond alphawaarde (ondoorzichtigheid, tussen 0 en 255)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Verhoog volume toets" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Verticale beginsnelheid tijdens springen, in blokken per seconde." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Profileer 'builtin'.\n" +"Dit is normaal enkel nuttig voor gebruik door ontwikkelaars van\n" +"het core/builtin-gedeelte van de server" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "Profileer chatcommando's bij het registreren." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Profileer algemene callback-functies bij het registreren.\n" +"(alles dat mbv een van de minetest.register_*() functies geregistreerd wordt" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "Profileer de acties van ABMs bij het registreren." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "Profileer de acties van LBMs bij het registreren." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Profileer de acties van objecten bij het registreren." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Interval voor het opslaan van belangrijke veranderingen in de wereld. In " +"seconden." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Interval voor het sturen van de kloktijd naar cliënten." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Inventaris items animaties" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Inventaristoets" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Muisbeweging omkeren" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Vertikale muisbeweging omkeren." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Cursief font pad" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Cursief vaste-breedte font pad" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Bestaansduur van objecten" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Iteraties" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Aantal iteraties van de recursieve functie.\n" +"Het groter maken hiervan zorgt voor een toename in fijne details, maar zorgt " +"ook \n" +"voor een toename in processorgebruik.\n" +"Bij iteraties = 20 heeft deze mapgen een vergelijkbare belasting als mapgen " +"V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "Stuurknuppel ID" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Joystick-knop herhalingsinterval" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "Dode zone Joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Joystick frustrum gevoeligheid" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Joystick type" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Alleen de Julia verzameling: \n" +"W-waarde van de 4D vorm. \n" +"Verandert de vorm van de fractal.\n" +"Heeft geen effect voor 3D-fractals.\n" +"Bereik is ongeveer -2 tot 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Allen de Julia verzameling: \n" +"X-waarde van de 4D vorm.\n" +"Verandert de vorm van de fractal.\n" +"Bereik is ongeveer -2 tot 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Alleen de Julia verzameling: \n" +"Y-waarde van de 4D vorm.\n" +"Verandert de vorm van de fractal.\n" +"Bereik is ongeveer -2 tot 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Alleen de Julia verzameling: \n" +"Z-waarde van de 4D vorm.\n" +"Verandert de vorm van de fractal.\n" +"Bereik is ongeveer -2 tot 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Springen toets" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Sprinsnelheid" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de zichtastand te verminderen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om het volume te verlagen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets voor graven.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets voor het weggooien van het geselecteerde object.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de zichtastand te vergroten.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om het volume te verhogen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets voor springen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om snel te bewegen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de speler achteruit te bewegen.\n" +"Zal ook het automatisch voortbewegen deactiveren, indien actief.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de speler vooruit te bewegen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de speler naar links te bewegen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de speler naar rechts te bewegen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de game te dempen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om het chat-window te openen om commando's te typen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om het chat-window te openen om lokale commando's te typen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om het chat-window te openen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om het rugzak-window te openen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets voor plaatsen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 11de positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 12de positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 13de positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 14de positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 15de positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 16de positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 17de positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 18de positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 19de positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 20ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 21ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 22ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 23ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 24ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 25ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 26ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 27ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 28ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 29ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 30ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 32ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 32ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 8ste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de vijfde positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de eerste positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de vierde positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om het volgende item in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de negende positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om het vorige item in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de tweede positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de zevende positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de zesde positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de 10de positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de derde positie in de hotbar te selecteren.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om te sluipen.\n" +"Wordt ook gebruikt om naar beneden te klimmen en te dalen indien " +"aux1_descends uitstaat.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om tussen 1e-persoon camera en 3e-persoon camera te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om screenshots te maken.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om automatisch lopen aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om cinematic modus aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de mini-kaart aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om snelle modus aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om vliegen aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om 'noclip' modus aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om 'pitch move' modus aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om camera-verversing aan/uit te schakelen. Enkel gebruikt voor " +"ontwikkeling.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om het tonen van chatberichten aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om debug informatie aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om mist aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om de HUD aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om het tonen van de grote chat weergave aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om het tonen van de code-profiler aan/uit te schakelen. Gebruikt voor " +"ontwikkeling.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om oneindige zichtastand aan/uit te schakelen.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Toets om in te zoemen wanneer mogelijk.\n" +"Zie http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" +"Schop spelers die meer dan X berichten per 10 seconden hebben verzonden." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Steilheid van meren" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Meren-grenswaarde" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Taal" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Diepte van grote grotten" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Maximaal aantal grote grotten" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Groot minimumaantal grotten" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Grote grotaandeel overstroomd" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Grote chatconsole-toets" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Type van bladeren" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Type bladeren:\n" +"- Fancy: alle zijden zichtbaar\n" +"- Simple: enkel buitenzijden zichtbaar; special_tiles wordt gebruikt " +"indien gedefiniëerd\n" +"- Opaque: geen doorzichtige bladeren" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Toets voor links" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Lengte van server stap, en interval waarin objecten via het netwerk\n" +"ververst worden." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Lengte van vloeibare golven.\n" +"Dit vereist dat 'golfvloeistoffen' ook aanstaan." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" +"Tijdsinterval waarmee actieve blokken wijzigers (ABMs) geactiveerd worden" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Tijdsinterval waarmee node timerd geactiveerd worden" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Tijd tussen actieve blok beheer(ABM) cycli" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Hoeveelheid logging die geschreven wordt naar debug.txt:\n" +"- <leeg> (geen logging)\n" +"- none (enkel berichten zonder gedefiniëerd niveau)\n" +"- error (alles van minstens fout-niveau)\n" +"- warning (alles van minstens waarschuwings-niveau)\n" +"- action (alles van minstens actie-niveau)\n" +"- info (alles van minstens informatie-niveau)\n" +"- verbose (alles)" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Lichtcurve boost" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Lichtcurve boost centrum" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Lichtcurve boost verspreiding" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Lichtcurve gamma" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Lichtcurve hoog verloop" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Lichtcurve laag verloop" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Vloeiende verlichting" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Limiet van de landkaart generatie in aantal noden van (0,0,0) in alle 6 " +"richtingen.\n" +"Enkel mapchunks die volledig in de limiet vallen worden gegenereerd.\n" +"Deze waarde wordt per wereld bewaard." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Beperking van het aantal parallele HTTP verzoeken. Van toepassing op:\n" +"- Laden van media indien een externe media-server gebruikt wordt.\n" +"- Laden van de serverlijst en server-aankondigingen.\n" +"- Downloads vanuit het hoofdmens (bijv. mods).\n" +"(Alleen van toepassing indien cURL meegecompileerd is)." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Vloeibaarheid van vloeistoffen" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Vloeistof viscositeit gladmaakfactor" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Vloeistof-verspreiding per stap" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Inkortingstijd vloeistof-wachtrij" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Zinksnelheid in vloeistof" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Vloeistof verspreidingssnelheid in seconden." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Vloeistof verspreidingssnelheid" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Gebruik de spel-profiler" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Gebruik de spel-profiler om profileringsgegevens van het spel te " +"verzamelen.\n" +"Hierbij komt ook het server-commando '/profiler' beschikbaar.\n" +"Nuttig voor mod-ontwikkelaars en server-beheerders." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Geladen blokken aanpassers (LBMs)" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Onderste Y-limiet van kerkers." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Onderste Y-limiet van zwevende eilanden." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Hoofdmenu script" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Mist en hemelkleur afhankelijk van tijd van de dag (zonsopkomst/ondergang) " +"en kijkrichting." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Maak alle vloeistoffen ondoorzichtig" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Map compressie niveau voor het bewaren op de harde schijf" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Map compressie niveau voor netwerk transfert" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Wereld map" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Wereldgeneratieattributen specifiek aan Mapgen Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Wereldgenerator instellingen specifiek voor generator 'flat' (vlak).\n" +"Verspreide meren en heuvels kunnen toegevoegd worden." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Wereldgenerator instellingen specifiek voor generator 'fractal'.\n" +"\"terrein\" activeert de generatie van niet-fractale terreinen:\n" +"oceanen, eilanden en ondergrondse ruimtes." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Wereldgeneratieattributen specifiek aan Mapgen Valleys.\n" +"'altitude_chill': Hoe groter de hoogte, hoe lager de temperatuur.\n" +"'humid_rivers': Hogere vochtigheidsgraad rond rivieren.\n" +"'vary_river_depth': Lage vochtigheidsgraad en hoge temperatuur\n" +"zorgen ervoor dat rivieren smaller worden en uiteindelijk uitdrogen.\n" +"'altitude_dry': Hoe groter de hoogte, hoe lager de vochtigheidsgraad." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Wereldgenerator instellingen specifiek voor Mapgen V5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Wereldgenerator instellingen specifiek voor generator v6.\n" +"De sneeuwgebieden optie, activeert de nieuwe 5 vegetaties systeem.\n" +"Indien sneeuwgebieden aanstaan, dan worden oerwouden ook aangezet, en wordt\n" +"de \"jungles\" optie genegeerd." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Wereldgenerator instellingen specifiek voor generator v7.\n" +"'ridges': dit zijn uithollingen in het landschap die rivieren mogelijk " +"maken.\n" +"'floatlands': dit zijn zwevende landmassa's in de atmosfeer.\n" +"'caverns': grote grotten diep onder de grond." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Wereld-grens" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Interval voor opslaan wereld" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "Aantal frames voor bijwerken schaduwmap" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Max aantal wereldblokken" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Mapblock maas generatie vertraging" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Mapblock maas generator's MapBlock cache grootte in MB" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Wereldblok vergeet-tijd" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "wereldgenerator Karpaten" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Wereldgenerator Karpaten specifieke opties" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Wereldgenerator vlak terrein" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Wereldgenerator vlak terrein specifieke opties" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Wereldgenerator Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Wereldgenerator Fractal specifieke opties" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Wereldgenerator v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Wereldgenerator v5 specifieke opties" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Wereldgenerator v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Wereldgenerator v6 specifieke opties" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Wereldgenerator v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Wereldgenerator v7 specifieke opties" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Valleien Wereldgenerator" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Weredgenerator valleien specifieke opties" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Wereldgenerator debug" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Wereldgenerator" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Maximale afstand van te genereren blokken" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Maximale afstand voor te versturen blokken" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" +"Maximaal aantal vloeistof-nodes te verwerken (dwz verspreiden) per server-" +"stap." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Maximaal extra aantal blokken voor clearobjects" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Maximaal aantal pakketten per iteratie" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Maximum FPS" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"Maximum FPS als het venster niet gefocussed is, of wanneer het spel " +"gepauzeerd is." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Maximumafstand bij renderen schaduwen." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Maximaal aantal geforceerd geladen blokken" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Maximale breedte van de 'hotbar'" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "Maximale limiet van willekeurig aantal grote grotten per mapchunk." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "Maximale limiet van willekeurig aantal kleine grotten per mapchunk." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Maximale vloeistofweerstand. Regelt de vertraging bij het invoeren van " +"vloeistof op \n" +"hoge snelheid." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Maximum aantal blokken dat tegelijkertijd verzonden kan worden\n" +"per client. Het totale maximum wordt dynamisch berekend:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "Maximaal aantal blokken in de wachtrij voor laden/genereren." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Maximaal aantal blokken in de wachtrij om gegenereerd te worden.\n" +"Deze limiet is opgelegd per speler." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Maximaal aantal blokken in de wachtrij om van een bestand/harde schijf " +"geladen te worden.\n" +"Deze limiet is opgelegd per speler." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Maximaal aantal gelijktijdige downloads. Downloads die deze limiet " +"overschrijden zullen in de wachtrij geplaats worden.\n" +"Deze instelling zou lager moeten zijn dan curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Maximaal aantal geforceerd geladen blokken." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Maximaal aantal wereldblokken dat door de cliënt in het geheugen gehouden " +"wordt.\n" +"Gebruik -1 voor een onbeperkt aantal." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Maximaal aantal pakketen dat per server-stap verzonden wordt. Verminder dit " +"aantal\n" +"bij een langzame verbinding, maar niet lager dan het gewenste aantal " +"cliënten\n" +"dat gelijk verbonden kan zijn." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Maximaal aantal spelers dat tegelijkertijd verbonden kan zijn." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Maximaal aantal zichtbare recente chatberichten" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Maximaal aantal objecten per blok dat wordt opgeslagen." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Maximaal aantal objecten per blok" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Maximale fractie van de breedte het window dat gebruikt mag worden voor de " +"hotbar.\n" +"Dit is nuttig als er iets links of rechts ervan getoond moet worden." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Maximaal simultaan verzonden blokken per cliënt" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Maximale omvang van de wachtrij uitgezonden berichten" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Maximale omvang van de wachtrij uitgezonden berichten.\n" +"'0' om de wachtrij uit te schakelen en '-1' om de wachtrij oneindig te maken." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Maximale duur voor het downloaden van een bestand (bv. een mod), in " +"milliseconden." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Maximale duur voor het afhandelen van een interactieve aanvraag (bv. ophalen " +"serverlijst), in milliseconden." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Maximaal aantal gebruikers" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Cache voor meshes" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Bericht van de dag" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Toon bericht aan spelers die verbinding maken." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" +"Manier waarop het geselecteerde object zichtbaar wordt gemaakt.\n" +"* box: node wordt omlijnd.\n" +"* halo: node licht op." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Minimaal aantal loggegevens in de chat weergeven." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Mini-kaart" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Mini-kaart toets" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Mini-kaart scan-hoogte" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Minimumlimiet van willekeurig aantal grote grotten per mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Minimale limiet van willekeurig aantal kleine grotten per mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Minimale textuur-grootte" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mip-Mapping" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Profiler" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Veiligheid" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Mod-kanalen" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Verandert de grootte van de HUD-elementen." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Vaste-breedte font pad" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Vaste-breedte font grootte" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "Vaste-breedte font grootte" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Berg-hoogte ruis" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Bergen ruis" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Berg-hoogte ruisvariatie" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Nulniveau bergen" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Muis-gevoeligheid" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Muis-gevoeligheidsfactor." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Modder ruis" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Vermenigvuldigingsfactor van loopbeweging bij vallen.\n" +"Bijvoorbeeld:\n" +"0 voor geen loopbeweging.\n" +"1.0 voor normale loopbeweging.\n" +"2.0 voor twee keer grotere loopbeweging." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Demp toets" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Geluid dempen" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Naam van de wereldgenerator die gebruikt moet worden om een nieuwe wereld " +"aan te maken. \n" +"Een nieuwe wereld aanmaken in het hoofdmenu heeft echter voorrang.\n" +"Huidige wereldgeneratoren in zeer instabiele staat:\n" +"- De optionele zweeflanden van v7 (standaard uitgeschakeld)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Naam van de speler.\n" +"Voor servers: spelers met deze naam krijgen beheerdersrechten.\n" +"Voor cliënten: standaardspelernaam voor verbindingen met een server\n" +"(in het hoofdmenu kan een andere naam gekozen worden)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Naam van de server. Wordt getoond in de serverlijst, en wanneer spelers " +"inloggen." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Dichtbij vliegtuig" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Netwerkpoort van de server (UDP).\n" +"Bij starten vanuit het hoofdmenu kan een andere poort opgegeven worden." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Netwerk" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Nieuwe spelers dienen dit wachtwoord op te geven." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Noclip" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Noclip-toets" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Node licht op" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Geselecteerde node indicatie" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Interval voor node-timers" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Ruis" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Aantal 'emerge' threads" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Aantal te gebruiken emerge-threads. \n" +"WAARSCHUWING: Momenteel zijn er meerdere bugs die crashes kunnen veroorzaken " +"wanneer \n" +"'num_emerge_threads' is groter dan 1. Totdat deze waarschuwing is " +"verwijderd, is dat \n" +"zo sterk aanbevolen deze waarde is ingesteld op de standaard '1'. \n" +"Waarde 0: \n" +"- Automatische selectie. Het aantal emerge threads zal zijn \n" +"- 'aantal processors - 2', met een ondergrens van 1. \n" +"Elke andere waarde: \n" +"- Specificeert het aantal emerge threads, met een ondergrens van 1. \n" +"WAARSCHUWING: Door het aantal emerge threads te vergroten, worden de motor " +"mapgen \n" +"vergroot snelheid, maar dit kan de spelprestaties schaden door interfereren " +"met andere \n" +"processen, vooral in singleplayer en/of bij het uitvoeren van Lua-code in \n" +"'on_generated'. Voor veel gebruikers kan de optimale instelling '1' zijn." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Aantal extra blokken dat '/clearobjects' tegelijk mag laden.\n" +"Dit is een compromis tussen overhead van SQLite-transacties en\n" +"geheugengebruik (als vuistregel is 4096 gelijk aan 100 MB)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Ondoorzichtige vloeistoffen" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" +"Ondoorzichtigheid (alpha) van de schaduw achter het standaardlettertype, " +"tussen 0 en 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Pauzemenu openen als het venster focus verliest. Pauzeert niet als er\n" +"een formspec geopend is." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Optionele overschrijving van de kleur van weblinks in chat." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Pad van het fallback-lettertype. \n" +"Als de instelling \"freetype\" is ingeschakeld: Moet een TrueType-lettertype " +"zijn. \n" +"Als de instelling \"freetype\" is uitgeschakeld: Moet een bitmap- of XML-" +"vectorenlettertype zijn. \n" +"Dit lettertype wordt gebruikt voor bepaalde talen of als het " +"standaardlettertype niet beschikbaar is." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Pad waar screenshots moeten bewaard worden. Kan een absoluut of relatief pad " +"zijn.\n" +"De map zal aangemaakt worden als ze nog niet bestaat." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Pad naar de schader. Indien geen pad wordt gegeven zal de standaard locatie " +"gebruikt worden." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" +"Pad van de texturen-map. Naar texturen wordt gezocht beginnend bij deze map." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Pad naar het standaardlettertype. \n" +"Als de instelling \"freetype\" is ingeschakeld: Moet een TrueType-lettertype " +"zijn. \n" +"Als de instelling \"freetype\" is uitgeschakeld: Moet een bitmap- of XML-" +"vectorenlettertype zijn. \n" +"Het fallback-lettertype wordt gebruikt als het lettertype niet kan worden " +"geladen." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Pad naar het monospace-lettertype. \n" +"Als de instelling \"freetype\" is ingeschakeld: Moet een TrueType-lettertype " +"zijn. \n" +"Als de instelling \"freetype\" is uitgeschakeld: Moet een bitmap- of XML-" +"vectorenlettertype zijn. \n" +"Dit lettertype wordt o.a. gebruikt voor het console- en profilerscherm." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Pauzeer als venster focus verliest" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" +"Per speler limiet van gevraagde blokken om te laden van de harde schijf" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Per speler limiet van de \"te genereren blokken\"-wachtrij" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fysica" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Vrij vliegen toets" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Pitch beweeg modus" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Plaats toets" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Plaats (Rechts-klik) herhalingsinterval" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Speler kan vliegen, zonder invloed van de zwaartekracht.\n" +"De speler moet wel in het bezit zijn van het \"vliegen\" voorrecht." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Speler verplaatsingsafstand" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Speler tegen speler" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Poisson-filteren" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Netwerk-poort (UDP) waarmee verbinding gemaakt moet worden.\n" +"In het hoofdmenu kan een andere waarde opgegeven worden." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Voorkom dat graven en plaatsen zich herhaalt wanneer u de muisknoppen " +"ingedrukt houdt. \n" +"Schakel dit in als u per ongeluk te vaak graaft of plaatst." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Voorkom dat mods onveilige commando's uitvoeren, zoals shell commando's." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Interval waarmee profiler-gegevens geprint worden. \n" +"0 = uitzetten. Dit is nuttig voor ontwikkelaars." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Voorrechten die spelers met 'basic_privs' mogen toekennen" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Profiler" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Profiler aan/uit toets" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Adres om te luisteren naar Prometheus" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Adres om te luisteren naar Prometheus.\n" +"Indien Minetest gecompileerd werd met de optie ENABLE_PROMETHEUS,\n" +"dan zal dit adres gebruikt worden om naar Prometheus te luisteren.\n" +"Meetwaarden kunnen opgehaald worden op http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Aandeel grote grotten die vloeistof bevatten." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Straal van wolken, in 64-node eenheden.\n" +"Waarden groter dan 26 hebben scherpe wolkenranden tot gevolg." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Verhoogt het terrein om rond de rivieren valleien te maken." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Willekeurige invoer" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Zichtafstand toets" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Recente chatberichten" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Standaard lettertype pad" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Externe media" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Poort van externe server" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Verwijder kleurcodes van binnenkomende chatberichten\n" +"Gebruik dit om er voor te zorgen dat spelers geen kleuren kunnen gebruiken " +"in hun berichten" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Vervangt het standaard hoofdmenu door een ander." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Rapport pad" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Beperkt de toegang van bepaalde client-side functies op servers. \n" +"Combineer de onderstaande byteflags om functies aan de clientzijde te " +"beperken of stel deze in op 0 \n" +"voor geen beperkingen: \n" +"LOAD_CLIENT_MODS: 1 (schakel het laden van door de gebruiker geleverde mods " +"uit) \n" +"CHAT_MESSAGES: 2 (schakel send_chat_message call client-side uit) \n" +"READ_ITEMDEFS: 4 (schakel get_item_def call client-side uit) \n" +"READ_NODEDEFS: 8 (schakel get_node_def call client-side uit) \n" +"LOOKUP_NODES_LIMIT: 16 (beperkt get_node call client-side tot \n" +"csm_restriction_noderange) \n" +"READ_PLAYERINFO: 32 (deactiveer get_player_names call client-side)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "\"Berg richel verspreiding\" ruis" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Bergtoppen ruis" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Onderwater richel ruis" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Bergtoppen grootte ruis" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Toets voor rechts" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Diepte van rivieren" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Breedte van rivieren" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Diepte van rivieren" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Rivier ruis" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Grootte van rivieren" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Breedte van vallei waar een rivier stroomt" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Opnemen terugrolgegevens" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Ruis golvende heuvels" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Glooiende heuvels verspreiden ruis" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Ronde mini-kaart" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Veilig breken en plaatsen" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Zandstranden komen voor wanneer np_beach groter is dan deze waarde." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Bewaar de ontvangen wereld lokaal (op de cliënt)." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Onthoud venstergrootte wanneer veranderd." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Lokaal bewaren van de server-wereld" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Schaal de GUI met een door de gebruiker bepaalde factor.\n" +"Er wordt een dichtste-buur-anti-alias filter gebruikt om de GUI te schalen.\n" +"Bij verkleinen worden sommige randen minder duidelijk, en worden\n" +"pixels samengevoegd. Pixels bij randen kunnen vager worden als\n" +"een niet-gehele schaalfactor gebruikt wordt." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Scherm:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Schermhoogte" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Schermbreedte" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Map voor screenshots" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Formaat voor screenshots" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Screenshot kwaliteit" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Kwaliteit van screenshots. Enkel voot JPEG.\n" +"Van 1 (slechtst) tot 100 (best).\n" +"0 = een redelijke standaardwaarde." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Screenshot" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Zeebodem ruis" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Tweede van vier 2D geluiden die samen een heuvel/bergketen grootte bepalen." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Tweede van twee 3D geluiden die samen tunnels definiëren." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Zie http://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Kleur van selectie-randen (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Kleur van selectie-randen" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Breedte van selectie-randen" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Selecteert één van de 18 fractaal types:\n" +"1 = 4D \"Roundy\" mandelbrot verzameling.\n" +"2 = 4D \"Roundy\" julia verzameling.\n" +"3 = 4D \"Squarry\" mandelbrot verzameling.\n" +"4 = 4D \"Squarry\" julia verzameling.\n" +"5 = 4D \"Mandy Cousin\" mandelbrot verzameling.\n" +"6 = 4D \"Mandy Cousin\" julia verzameling.\n" +"7 = 4D \"Variatie\" mandelbrot verzameling.\n" +"8 = 4D \"Variatie\" julia verzameling.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" mandelbrot verzameling.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" julia verzameling.\n" +"11 = 3D \"Kerstboom\" mandelbrot verzameling.\n" +"12 = 3D \"Kerstboom\" julia verzameling.\n" +"13 = 3D \"Mandelbulb\" mandelbrot verzameling.\n" +"14 = 3D \"Mandelbulb\" julia verzameling.\n" +"15 = 3D \"Cosinus Mandelbulb\" mandelbrot verzameling.\n" +"16 = 3D \"Cosinus Mandelbulb\" julia verzameling.\n" +"17 = 4D \"Mandelbulb\" mandelbrot verzameling.\n" +"18 = 4D \"Mandelbulb\" julia verzameling." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Server URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Naam van de server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Omschrijving van de Server" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "Server URL" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Adres van de server" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Omschrijving van de server" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Naam van de server" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Netwerkpoort van de server" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Door server worden onzichtbare nodes niet doorgegeven" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Server Poort" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL van de publieke serverlijst" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "URL van de publieke serverlijst" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Bestand met publieke serverlijst" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Stel de taal in. De systeem-taal wordt gebruikt indien leeg.\n" +"Een herstart is noodzakelijk om de nieuwe taal te activeren." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "Maximaal aantal tekens voor chatberichten van gebruikers instellen." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Schaduwsterkte instellen.\n" +"Een lagere waarde betekent lichtere schaduwen, een hogere waarde donkerdere " +"schaduwen." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Radiusgrootte zachte schaduwen instellen.\n" +"Lagere waarden betekenen scherpere schaduwen, hogere waarden zachtere.\n" +"Minimumwaarde: 1.0; maximumwaarde: 10.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Tilt van baan zon/maan in graden instellen:\n" +"Een waarde van 0 betekent geen tilt / verticale baan.\n" +"Minimumwaarde: 0.0; maximumwaarde: 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Schakel in om schaduwmapping in te schakelen.\n" +"Dit vereist dat 'shaders' ook aan staan." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Bewegende bladeren staan aan indien 'true'.\n" +"Dit vereist dat 'shaders' ook aanstaan." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Golvend water staat aan indien 'true'.\n" +"Dit vereist dat 'shaders' ook aanstaan." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Bewegende planten staan aan indien 'true'.\n" +"Dit vereist dat 'shaders' ook aanstaan." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Schaduwtextuurkwaliteit op 32-bits zetten.\n" +"Indien uitgeschakeld worden 16-bits texturen gebruikt,\n" +"wat voor meer ruis in schaduwen kan zorgen." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Shader pad" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Shaders maken bijzondere visuele effecten mogelijk, en kunnen op sommige\n" +"videokaarten de prestaties verbeteren.\n" +"Alleen mogelijk met OpenGL." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Kwaliteit schaduwfilter" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "Maximumafstand in nodes om schaduwen schaduwmap op te renderen" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "32-bits-schaduwmaptexturen" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Textuurgrootte schaduwmap" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Fontschaduw afstand (in beeldpunten). Indien 0, dan wordt geen schaduw " +"getekend." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "Schaduwsterkte" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Vorm van de mini-kaart. Aan = rond, uit = vierkant." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Toon debug informatie" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Toon selectie-box voor objecten" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Toon selectievakjes voor entiteiten\n" +"Een herstart is noodzakelijk om de wijziging te activeren." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Standaard achtergronden naam-tags tonen" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Afsluitbericht van server" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Grootte van mapchunks gegenereerd door mapgen, vermeld in mapblocks (16 " +"blokken). \n" +"WAARSCHUWING !: Er is geen voordeel en er zijn verschillende gevaren het \n" +"verhogen van deze waarde boven 5. \n" +"Het verlagen van deze waarde verhoogt de dichtheid van grotten en kerkers. \n" +"Het wijzigen van deze waarde is voor speciaal gebruik, maar blijft " +"ongewijzigd \n" +"aanbevolen." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Grootte van de MapBlock cache voor de maas generator. Dit verhogen vergroot\n" +"de kans op een cache hit, waardoor minder data van de main thread\n" +"wordt gekopieerd waardoor flikkeren verminderd." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Tilt baan hemellichaam" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Doorsnede w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Helling en vulling bepalen in combinatie de hoogte." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Maximaal aantal kleine grotten" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Minimaal aantal kleine grotten" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "Kleinschalig vochtigheidsvariatie voor de overgang van biomen." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "Kleinschalig temperatuursvariatie voor de overgang van biomen." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Vloeiende verlichting" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Maakt camerabewegingen vloeiender bij het rondkijken.\n" +"Wordt ook wel zicht- of muis-smoothing genoemd.\n" +"Nuttig bij het opnemen van videos." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"Maakt camera-rotatie vloeiender in cintematic modus. 0 om uit te zetten." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Maakt camera-rotatie vloeiender. O om uit te zetten." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Sluipen toets" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Sluipsnelheid" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Sluipsnelheid, in blokken per seconde." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Radius zachte schaduwen" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Geluid" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"URL waar de cliënt media kan ophalen, in plaats van deze over UDP\n" +"van de server te ontvangen.\n" +"$filenaam moet via cURL beschikbaar zijn met adres $remote_media$filename\n" +"(remote_media moet dus eindigen in een slash ('/')).\n" +"Bestanden die niet gevonden worden, worden op de normale manier opgehaald." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Bepaalt de standaard stack grootte van nodes, items en tools.\n" +"Merk op dat mods of spellen expliciet een stack kunnen maken voor sommige " +"(of alle) items." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Verspeid een volledige update van de schaduwmap over het opgegeven aantal " +"frames.\n" +"Hogere waarden kunnen schaduwen \"laggy\" maken, lagere\n" +"waarden kosten meer moeite.\n" +"Minimumwaarde: 1; maximumwaarde: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Verspreiding van het bereik van de lichtcurve. \n" +"Bepaalt de breedte van het bereik dat moet worden versterkt. \n" +"Standaardafwijking van de lichtcurve boost Gaussian." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Vast geboortepunt" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Steilte ruis" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Trap-Bergen grootte ruis" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Trap-Bergen verspreiding ruis" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Sterkte van de 3D modus parallax." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Kracht van lichtcurve boost. \n" +"De 3 'boost'-parameters bepalen een bereik van het licht \n" +"curve die wordt versterkt in helderheid." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Stricte protocolcontrole" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Kleurcodes weghalen" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Oppervlaktehoogte van optioneel water, geplaatst op een vaste laag van een " +"zwevend eiland.\n" +"Water is standaard uitgeschakeld en zal enkel gemaakt worden als deze waarde " +"is gezet op \n" +"een waarde groter dan 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (het " +"begin van de\n" +"bovenste afschuining).\n" +"***WAARSCHUWING, MOGELIJK GEVAAR VOOR WERELDEN EN SERVER PERFORMANTIE***:\n" +"Als er water geplaatst wordt op zwevende eilanden, dan moet dit " +"geconfigureerd en getest worden,\n" +"dat het een vaste laag betreft met de instelling 'mgv7_floatland_density' op " +"2.0 (of andere waarde\n" +"afhankelijk van de waarde 'mgv7_np_floatland'), om te vermijden \n" +"dat er server-intensieve water verplaatsingen zijn en om ervoor te zorgen " +"dat het wereld oppervlak \n" +"eronder niet overstroomt." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "Sqlite synchrone modus" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Temperatuurvariatie voor biomen." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Instellingen" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Terrein alteratieve ruis" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Terrein basis ruis" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Terrein hoogte" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Terrein hoger ruis" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Terrein ruis" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Terrein ruis-grens voor heuvels.\n" +"Bepaalt hoeveel van de wereld bedekt is met heuvels.\n" +"Een lagere waarde (richting 0.0) geeft meer heuvels." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Terrein ruis-grens voor meren.\n" +"Bepaalt hoeveel van de wereld bedekt is met meren.\n" +"Een lagere waarde (richting 0.0) geeft meer meren." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Terrein persistentie ruis" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Textuur pad" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Grootte textuur om de schaduwmap op te renderen.\n" +"Dit moet een macht van twee zijn.\n" +"Grotere numbers zorgen voor betere schaduwen maar kosten ook meer moeite." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Texturen op een blok kunnen worden uitgelijnd met het blok of met de " +"wereld. \n" +"De eerste modus past bij betere dingen zoals machines, meubels, enz \n" +"dit laatste zorgt ervoor dat trappen en microblokken beter in de omgeving " +"passen. \n" +"Deze mogelijkheid is echter nieuw en mag daarom niet worden gebruikt door " +"oudere servers, \n" +"Met deze optie kan deze voor bepaalde blokkentypen worden afgedwongen. Merk " +"echter op dat \n" +"die als EXPERIMENTEEL wordt beschouwd en mogelijk niet goed werkt." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "De URL voor de inhoudsrepository" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "De dode zone van de joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Het standaardformaat waarin profileringsgegevens worden bewaard,\n" +" als '/profiler save' wordt aangeroepen zonder expliciet formaat." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "De diepte van aarde of andersoortige toplaag." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"Het bestand pad ten opzichte van de wereldfolder waar profilerings-gegevens " +"worden opgeslagen." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "De identificatie van de stuurknuppel die u gebruikt" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"De lengte in pixels die nodig is om een touchscreeninteractie te starten." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"De maximale hoogte van het oppervlak van golvende vloeistoffen. \n" +"4.0 = Golfhoogte is twee knooppunten. \n" +"0.0 = Golf beweegt helemaal niet. \n" +"De standaardwaarde is 1,0 (1/2 blok). \n" +"Vereist dat golvende vloeistoffen zijn ingeschakeld." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "Het netwerk-adres waar de server op verbindingen wacht." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"De voorrechten standaard gegund aan nieuwe spelers.\n" +"Gebruik het server-commando '/privs' in het spel voor een volledige lijst\n" +"van beschikbare voorrechten op de server." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"De straal van het volume van blokken rond elke speler die onderworpen is aan " +"de \n" +"actieve blokspullen, vermeld in mapblocks (16 blokken). \n" +"In actieve blokken worden objecten geladen en ABM's uitgevoerd. \n" +"Dit is ook het minimumbereik waarin actieve objecten (mobs) worden " +"onderhouden. \n" +"Dit moet samen met active_object_send_range_blocks worden geconfigureerd." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"Back-end om mee te renderen.\n" +"Een herstart is vereist om dit definitief te wijzigen.\n" +"Opmerking: Op Android, blijf bij OGLES1 als je het niet zeker weet! Anders " +"start de app mogelijk niet.\n" +"Op andere platformen wordt OpenGL aanbevolen.\n" +"Zowel OpenGL (alleen op desktop) als OGLES2 (experimenteel) ondersteunen " +"shaders" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"De gevoeligheid van de assen van de joystick bij\n" +"het bewegen van de camera-frustum in het spel." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"De sterke van node ambient-occlusie shading effect.\n" +"Lagere waarden geven een donkerder effect. Hoger is lichter.\n" +"Geldige waarden zijn van 0.25 tot 4.0. Een ongeldige waarde wordt\n" +"aangepast naar de dichtstbijzijnde geldige waarde." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Het aantal seconden dat de vloeistof-verspreidingswachtrij mag groeien\n" +"terwijl die al te lang is. Bij overschrijding van deze tijd worden oude " +"items\n" +"uit de rij verwijderd. Gebruik 0 om dit uit te zetten." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"Het tijdsbudget dat toegestaan wordt aan ABM's om elke stap uit te voeren\n" +"(als een deel van het ABM interval)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"De tijd in seconden tussen herhaalde klikken als de joystick-knop\n" +" ingedrukt gehouden wordt." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"De tijd in seconden tussen herhaalde rechts-klikken als de plaats knop " +"(rechter muisknop)\n" +"ingedrukt gehouden wordt." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Het type van stuurknuppel" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"De verticale afstand waarover de warmte met 20 daalt als 'altitude_chill' " +"is \n" +"ingeschakeld. Ook de verticale afstand waarover de vochtigheid met 10 daalt " +"als \n" +"'altitude_dry' is ingeschakeld." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Derde van vier 2D geluiden die samen voor heuvel/bergketens hoogte " +"definiëren." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"De tijd in seconden dat weggegooide of gevallen objecten bestaan.\n" +"Gebruik -1 voor een onbeperkte bestaansduur." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" +"Tijdstip waarop een nieuwe wereld wordt gestart, in mili-uren (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Kloktijd verstuur-interval" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Tijdsnelheid" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Tijdsduur waarna de cliënt ongebruikte wereldgegevens uit het geheugen " +"verwijdert." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Om vertraging te verminderen worden blokken minder snel verstuurd als een\n" +"speler aan het bouwen is.\n" +"Deze instelling bepaalt hoelang ze achtergehouden worden nadat een speler\n" +"een node geplaatst of verwijderd heeft." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Camera-modus veranderen toets" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Tooltip tijdsduur" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Gevoeligheid van het aanraakscherm" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Gevoeligheid van het aanraakscherm" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Bomen ruis" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Trilineair filteren" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"Gebruik dit om de mini-kaart sneller te maken op langzamere machines." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Vertrouwde mods" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL voor de serverlijst in de multiplayer tab." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Rendering" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Onderbemonstering is gelijkaardig aan het gebruik van een lagere " +"schermresolutie,\n" +"maar het behelst enkel de spel wereld. De GUI resolutie blijft intact.\n" +"Dit zou een duidelijke prestatie verbetering moeten geven ten koste van een " +"verminderde detailweergave.\n" +"Hogere waarden resulteren in een minder gedetailleerd beeld." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Onbeperkte speler zichtbaarheidsafstand" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Vergeet ongebruikte server gegevens" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Bovenste Y-limiet van kerkers." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Bovenste Y-limiet van zwevende eilanden." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Toon 3D wolken in plaats van platte wolken." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Toon wolken in de achtergrond van het hoofdmenu." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "Gebruik anisotropisch filteren voor texturen getoond onder een hoek." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Gebruik bilineair filteren bij het schalen van texturen." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Mipmapping gebruiken om texturen te schalen. Kan performantie lichtjes\n" +"verbeteren, vooral in combinatie met textuurpakketten van hoge resolutie.\n" +"Gamma-correcte verkleining wordt niet ondersteund." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Gebruik multi-sample anti-aliasing (MSAA) om de randen van de blokken glad " +"te maken.\n" +"Dit algoritme maakt de 3D viewport glad en houdt intussen het beeld scherp,\n" +"zonder de binnenkant van de texturen te wijzigen\n" +"(wat erg opvalt bij transparante texturen)\n" +"Zichtbare ruimtes verschijnen tussen nodes als de shaders uitgezet zijn.\n" +"Als de waarde op 0 staat, is MSAA uitgeschakeld.\n" +"Een herstart is nodig om deze wijziging te laten functioneren." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Gebruik trilineair filteren om texturen te schalen." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Vertikale synchronisatie (VSync)" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Vallei-diepte" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Vallei-vulling" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Vallei-profiel" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Vallei-helling" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Variatie van de biome vullingsdiepte." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Variatie van de maximum berg hoogte (in noden)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Variatie van het aantal grotten." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Variatie in de verticale schaal van het terrein.\n" +"Indien ruis < -0.55 is het terrein haast vlak." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Varieert de diepte van de biome oppervlakte noden." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Varieert de ruwheid van het terrein.\n" +"Definieert de 'persistence' waarde voor terrain_base en terrain_alt ruis." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Bepaalt steilheid/hoogte van kliffen." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Verticale klimsnelheid, in blokken per seconde." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Vertikale scherm-synchronisatie." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Video driver" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Loopbeweging factor" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Zichtafstand in nodes." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Toets voor verkleinen zichtafstand" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Toets voor vergroten zichtafstand" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Toets voor het inzoomen" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Zichtafstand" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "Virtuele joystick activeert Aux1-toets" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Geluidsniveau" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Volume van alle geluiden.\n" +"Dit vereist dat het geluidssysteem aanstaat." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"W-coördinaat van de 3D doorsnede van de 4D vorm.\n" +"Bepaalt welke 3D-doorsnelde van de 4D-vorm gegenereerd wordt.\n" +"Verandert de vorm van de fractal.\n" +"Heeft geen effect voor 3D-fractals.\n" +"Bereik is ongeveer -2 tot 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Loop- en vliegsnelheid, in blokken per seconde." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Loopsnelheid" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "Loop-, vlieg- en klimsnelheid in snelle modus, in blokken per seconde." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Waterniveau" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Waterniveau van de wereld." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Bewegende nodes" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Bewegende bladeren" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Bewegende vloeistoffen" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Golfhoogte van water/vloeistoffen" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Golfsnelheid van water/vloeistoffen" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Golflengte van water/vloeistoffen" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Bewegende planten" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "Kleur weblinks" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Als gui_scaling_filter aan staat worden alle GUI-plaatjes\n" +"softwarematig gefilterd. Sommige plaatjes worden wel direct\n" +"in hardware gegenereerd (bijv. render-to-texture voor nodes\n" +"in de rugzak)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Als gui_scaling_filter_txr2img aan staat, worden plaatjes\n" +"van de GPU naar het werkgeheugen gekopiëerd voor schalen.\n" +"Anders wordt de oude methode gebruikt, voor video-kaarten\n" +"die geen ondersteuning hebben voor het kopiëren van texturen\n" +"terug naar het werkgeheugen." + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Bij gebruik bilineair/trilineair/anisotropisch filteren kunnen texturen van\n" +"lage resolutie vaag worden; verhoog daardoor hun resolutie d.m.v.\n" +"\"naaste-buur-interpolatie\" om ze scherper te houden. Deze optie bepaalt\n" +"de minimale textuurgrootte na het omhoog schalen; hogere waarden geven\n" +"scherper beeld, maar kosten meer geheugen. Het is aanbevolen machten van\n" +"2 te gebruiken. Deze optie heeft enkel effect als bilineair, trilineair of\n" +"anisotropisch filteren aan staan.\n" +"Deze optie geldt ook als textuurgrootte van basisnodes voor\n" +"automatisch en met de wereld gealigneerd omhoog schalen van texturen." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Of achtergronden van naam-tags standaard getoond moeten worden.\n" +"Mods kunnen alsnog een achtergrond instellen." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "Node-animaties in wereldblokken niet synchroniseren." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Geef de locatie van spelers door aan cliënten ongeacht de afstand.\n" +"Verouderd. Gebruik 'player_transfer_distance'." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Maak het mogelijk dat spelers elkaar kunnen verwonden en doden." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Verzoek de cliënten om na een (Lua) crash automatisch opnieuw te verbinden.\n" +"Zet dit aan als de server na een crash automatisch herstart." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" +"Maak het einde van het zichtbereik mistig, zodat het einde niet opvalt." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Of geluiden moeten worden gedempt. Je kan het dempen van geluiden op elk " +"moment opheffen, tenzij het \n" +"geluidssysteem is uitgeschakeld (enable_sound = false). \n" +"Tijdens het spel kan je de mute-status wijzigen met de mute-toets of door " +"het pauzemenu \n" +"te gebruiken." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"Laat debug informatie zien in de cliënt (heeft hetzelfde effect als de F5 " +"toets)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Breedtecomponent van de initiële grootte van het venster. Wordt genegeerd in " +"fullscreen-modus." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" +"Breedte van de selectie-lijnen die getekend worden rond een geselecteerde " +"node." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Enkel Windows systemen: Start Minetest met een commando (DOS-prompt) window " +"in de achtergrond.\n" +"Bevat dezelfde informatie als het bestand debug.txt (standaard naam)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Wereld-map (alle informatie over de wereld staat in deze map).\n" +"Deze instelling is niet nodig als de server vanuit het hoofdmenu wordt " +"gestart." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Wereld starttijd" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Wereldwijd uitgelijnde texturen kunnen worden geschaald over meerdere " +"knooppunten. Echter, \n" +"de server verzendt mogelijk niet de gewenste weegschaal, vooral als u " +"gebruikt \n" +"een speciaal ontworpen texture pack; met deze optie probeert de gebruiker\n" +"om de schaal automatisch te bepalen op basis van de textuurgrootte. \n" +"Zie ook texture_min_size. \n" +"Waarschuwing: deze optie is EXPERIMENTEEL!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Wereldwijd uitgelijnde texturenmodus" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Niveau van de oppervlakte (Y-coördinaat)." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y van het niveau van de gradiënt nul van de bergdichtheid. Gebruikt om " +"bergen verticaal te verschuiven." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "bovenste limiet Y-waarde van grote grotten." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Y-afstand waar over grotten uitbreiden tot volle grootte." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Y-afstand over dewelke de zwevende eilanden veranderen van volledige " +"densiteit naar niets.\n" +"De verandering start op deze afstand van de Y limiet.\n" +"Voor een solide zwevend eiland, bepaalt deze waarde de hoogte van de heuvels/" +"bergen.\n" +"Deze waarde moet lager zijn of gelijk aan de helft van de afstand tussen de " +"Y limieten." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Y-niveau van gemiddeld terrein oppervlak." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Y-niveau van hoogste limiet voor grotten." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Y-niveau van hoger terrein dat kliffen genereert." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Y-niveau van lager terrein en vijver/zee bodems." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Y-niveau van zee bodem." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "timeout voor cURL download" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "cURL interactieve time-out" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Maximaal parallellisme in cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Creatieve Modus: " + +#~ msgid "- Damage: " +#~ msgstr "- Verwondingen: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = parallax occlusie met helling-informatie (sneller).\n" +#~ "1 = 'reliëf mapping' (lanzamer, nauwkeuriger)." + +#~ msgid "Address / Port" +#~ msgstr "Server adres / Poort" + +#, fuzzy +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Aangepaste gamma voor de licht-tabellen. Lagere waardes zijn helderder.\n" +#~ "Deze instelling wordt enkel gebruikt door de cliënt, en wordt genegeerd " +#~ "door de server." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Weet je zeker dat je jouw wereld wilt resetten?" + +#~ msgid "Back" +#~ msgstr "Terug" + +#~ msgid "Basic" +#~ msgstr "Basis" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Aantal bits per pixel (oftewel: kleurdiepte) in full-screen modus." + +#~ msgid "Bump Mapping" +#~ msgstr "Bumpmapping" + +#~ msgid "Bumpmapping" +#~ msgstr "Bumpmapping" + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Verandert de gebruikersinterface van het hoofdmenu: \n" +#~ "- Volledig: meerdere werelden voor één speler, spelkeuze, de kiezer van " +#~ "textuurpak, etc. \n" +#~ "- Eenvoudig: één wereld voor één speler, geen game- of texture pack-" +#~ "kiezers. Kan zijn \n" +#~ "noodzakelijk voor kleinere schermen." + +#~ msgid "Config mods" +#~ msgstr "Mods configureren" + +#~ msgid "Configure" +#~ msgstr "Instellingen" + +#~ msgid "Connect" +#~ msgstr "Verbinden" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Regelt de zinksnelheid in vloeistof." + +#, fuzzy +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Bepaalt de dichtheid van drijvende bergen.\n" +#~ "Dit wordt bijgevoegd bij de 'np_mountain' ruis waarde." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Bepaalt breedte van tunnels, een kleinere waarde maakt bredere tunnels." + +#~ msgid "Credits" +#~ msgstr "Credits" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Draadkruis-kleur (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Verwondingen ingeschakeld" + +#, fuzzy +#~ msgid "Darkness sharpness" +#~ msgstr "Steilheid Van de meren" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Standaard time-out voor cURL, in milliseconden.\n" +#~ "Wordt alleen gebruikt indien gecompileerd met cURL ingebouwd." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Bepaalt gebieden van drijvend glijdend terrein.\n" +#~ "Drijvend glijdend terrein ontstaat wanneer ruis > 0." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Bemonsterings-interval voor texturen.\n" +#~ "Een hogere waarde geeft vloeiender normal maps." + +#~ msgid "Del. Favorite" +#~ msgstr "Verwijder Favoriete" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Download een subspel, zoals Minetest Game, van minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Laad er een van minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "$1 wordt gedownload, een ogenblik geduld alstublieft..." + +#~ msgid "Enable VBO" +#~ msgstr "VBO aanzetten" + +#~ msgid "Enable register confirmation" +#~ msgstr "Registerbevestiging inschakelen" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Bumpmapping aanzetten voor texturen. Normalmaps moeten al in de texture " +#~ "pack zitten\n" +#~ "of ze moeten automatisch gegenereerd worden.\n" +#~ "Schaduwen moeten aanstaan." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Schakelt filmisch tone-mapping in" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Schakelt het genereren van normal maps in (emboss effect).\n" +#~ "Dit vereist dat bumpmapping ook aan staat." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Schakelt parallax occlusie mappen in.\n" +#~ "Dit vereist dat shaders ook aanstaan." + +#~ msgid "Enter " +#~ msgstr "Enter " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Experimentele optie. Kan bij een waarde groter dan 0 zichtbare\n" +#~ "ruimtes tussen blokken tot gevolg hebben." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS in het pauze-menu" + +#~ msgid "Fallback font shadow" +#~ msgstr "Terugval-font schaduw" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Terugval-font schaduw alphawaarde" + +#~ msgid "Fallback font size" +#~ msgstr "Terugval-fontgrootte" + +#~ msgid "Filtering" +#~ msgstr "Filters" + +#~ msgid "Floatland base height noise" +#~ msgstr "Drijvend land basis hoogte ruis" + +#~ msgid "Floatland mountain height" +#~ msgstr "Drijvend gebergte hoogte" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Fontschaduw alphawaarde (ondoorzichtigheid, tussen 0 en 255)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Lettergrootte van het fallback-lettertype in punt (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "Freetype lettertypes" + +#~ msgid "Full screen BPP" +#~ msgstr "BPP bij volledig scherm" + +#~ msgid "Game" +#~ msgstr "Spel" + +#, fuzzy +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Genereer normale werelden" + +#~ msgid "Generate normalmaps" +#~ msgstr "Genereer normaalmappen" + +#~ msgid "HUD scale factor" +#~ msgstr "HUD schaal factor" + +#~ msgid "High-precision FPU" +#~ msgstr "Hoge-nauwkeurigheid FPU" + +#~ msgid "IPv6 support." +#~ msgstr "IPv6 ondersteuning." + +#~ msgid "In-Game" +#~ msgstr "Spel" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Installeer: bestand: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Per soort" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Sneltoetsen. (Als dit menu stuk gaat, verwijder dan instellingen uit " +#~ "minetest.conf)" + +#, fuzzy +#~ msgid "Lava depth" +#~ msgstr "Diepte van grote grotten" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Emerge-wachtrij voor lezen" + +#~ msgid "Main" +#~ msgstr "Hoofdmenu" + +#~ msgid "Main menu style" +#~ msgstr "Hoofdmenu stijl" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "Maakt dat DirectX werkt met LuaJIT. Schakel dit uit als het problemen " +#~ "geeft." + +#~ msgid "Menus" +#~ msgstr "Menu's" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Mini-kaart in radar modus, Zoom x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Mini-kaart in radar modus, Zoom x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Minimap in oppervlaktemodus, Zoom x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Minimap in oppervlaktemodus, Zoom x4" + +#~ msgid "Name / Password" +#~ msgstr "Naam / Wachtwoord" + +#~ msgid "Name/Password" +#~ msgstr "Naam / Wachtwoord" + +#~ msgid "No" +#~ msgstr "Nee" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Normal-maps bemonstering" + +#~ msgid "Normalmaps strength" +#~ msgstr "Sterkte van normal-maps" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Aantal parallax occlusie iteraties." + +#~ msgid "Ok" +#~ msgstr "Oké" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "" +#~ "Ondoorzichtigheid (alpha) van de schaduw achter het fallback-lettertype, " +#~ "tussen 0 en 255." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "" +#~ "Algemene afwijking van het parallax occlusie effect. Normaal: schaal/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Algemene schaal van het parallax occlusie effect." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallax occlusie" + +#~ msgid "Parallax occlusion" +#~ msgstr "Parallax occlusie" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Parallax occlusie afwijking" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Parallax occlusie iteraties" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Parallax occlusie modus" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Parallax occlusie schaal" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Parallax occlusie sterkte" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Pad van TrueType font of bitmap." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Pad waar screenshots bewaard worden." + +#~ msgid "Player name" +#~ msgstr "Spelernaam" + +#~ msgid "Profiling" +#~ msgstr "Profileren" + +#~ msgid "PvP enabled" +#~ msgstr "Spelergevechten ingeschakeld" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Reset Singleplayer wereld" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "Selecteer Modbestand:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Server / Singleplayer" + +#~ msgid "Shadow limit" +#~ msgstr "Schaduw limiet" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Fontschaduw afstand van het standaard lettertype (in beeldpunten). Indien " +#~ "0, dan wordt geen schaduw getekend." + +#~ msgid "Special" +#~ msgstr "Speciaal" + +#~ msgid "Special key" +#~ msgstr "Speciaal ( Aux ) toets" + +#~ msgid "Start Singleplayer" +#~ msgstr "Start Singleplayer" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Sterkte van de normal-maps." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Dit font wordt gebruikt voor bepaalde talen." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Om schaduwen mogelijk te maken moet OpenGL worden gebruikt." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Cinematic modus aan/uit" + +#, fuzzy +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Typisch maximum hoogte, boven en onder het middelpunt van drijvend berg " +#~ "terrein." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Variatie van de heuvel hoogte en vijver diepte op drijvend egaal terrein." + +#~ msgid "View" +#~ msgstr "Bekijk" + +#~ msgid "Waving Water" +#~ msgstr "Golvend water" + +#~ msgid "Waving water" +#~ msgstr "Golvend water" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Gebruik freetype lettertypes, dit vereist dat freetype lettertype " +#~ "ondersteuning ingecompileerd is.\n" +#~ "Indien uitgeschakeld, zullen bitmap en XML verctor lettertypes gebruikt " +#~ "worden." + +#, fuzzy +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Minimale diepte van grote semi-willekeurige grotten." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "Y-niveau van drijvend land middelpunt en vijver oppervlak." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Y-niveau tot waar de schaduw van drijvend land reikt." + +#~ msgid "Yes" +#~ msgstr "Ja" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "U staat op het punt om voor het eerst lid te worden van deze server met " +#~ "de naam \"%s\". \n" +#~ "Als u doorgaat, wordt op deze server een nieuw account gemaakt met uw " +#~ "inloggegevens. \n" +#~ "Voer uw wachtwoord opnieuw in en klik op 'Registreren en aanmelden' om " +#~ "het aanmaken van een account te bevestigen, of klik op 'Annuleren' om af " +#~ "te breken." + +#~ msgid "You died." +#~ msgstr "Je bent gestorven." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/nn/minetest.po b/po/nn/minetest.po new file mode 100644 index 0000000..d3e8a59 --- /dev/null +++ b/po/nn/minetest.po @@ -0,0 +1,7092 @@ +msgid "" +msgstr "" +"Project-Id-Version: Norwegian Nynorsk (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-16 23:20+0000\n" +"Last-Translator: Tor Egil Hoftun Kvæstad <toregilhk@hotmail.com>\n" +"Language-Team: Norwegian Nynorsk <https://hosted.weblate.org/projects/" +"minetest/minetest/nn/>\n" +"Language: nn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Tom kommando." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Gå ut til hovudmeny" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Ugyldig kommando: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Gitt kommando: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "List opp spelarar som er online" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Spelarar som er online: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Du har kome at" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Du døydde" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Tilgjengelege kommandoar:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Tilgjengelege kommandoar: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Kommandoen er ikkje tilgjengeleg: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Få hjelp med kommandoar" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Nytt '.help <kommando>' for å få meir informasjon, eller '.help all' for å " +"liste opp alt." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<ingen tilgjengeleg>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Ein feil oppstod i eit LUA-skript:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Det har skjedd ein feil:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Hovudmeny" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Kople til igjen" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Tenaren har førespurt å kople til igjen:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Vel modifikasjonar" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protkoll versjon bommert. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Tenaren krev protokoll versjon $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Tenaren støtter protokollversjonar mellom $1 og $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Me støtter berre protokoll versjon $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Me støtter protokollversjonar mellom $1 og $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Avbryt" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Avhengigheiter:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Deaktiver alt" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Deaktiver modifikasjonspakken" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Aktiver alt" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Aktiver modifikasjonspakken" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Klarte ikkje å aktivere modifikasjon «$1», då den inneheld ugyldige teikn. " +"Berre teikna [a-z0-9_] er tillatne." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Finn fleire modifikasjonar" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Modifikasjon:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Ingen (valfrie) avhengigheiter" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Ikkje nokon spill skildring e sørgja for." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Ingen obligatoriske avhengigheiter" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Ikkje noko modifikasjons-pakke skildring e sørgja for." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Ingen valfrie avhengigheiter" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Valfrie avhengigheiter:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Lagre" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Verd:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "aktivert" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "«$1» eksisterer allereie. Vil du overskrive den?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$1 og $2 avhengigheiter vil verte installerte." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 lastar ned,\n" +"$2 i kø" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 lastar ned …" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 obligatoriske avhengigheiter vart ikkje funne." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 vil verte installert, og $2 avhengigheiter vil verte hoppa over." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Alle pakker" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Allereie installert" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Attende til hovudmeny" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Basisspel:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB er ikkje tilgjengeleg når Minetest vart kompilert utan cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Lastar ned …" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Klarte ikkje å laste ned $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Spel" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Installer" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Installer $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Installer manglande avhengigheiter" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Installasjon: Filtypen er ikkje støtta, eller arkivet er korrupt" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Modifikasjonar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Ingen pakkar kunne verte henta" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Ingen resultat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Ingen oppdateringar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Ikkje funnen" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Overskriv" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Ver venleg å sjekke at basisspelet er korrekt." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "I kø" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Teksturpakkar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Avinstaller" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Oppdater" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Oppdater alt [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Sjå meir informasjon i ein nettlesar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Ein verd med namnet «$1» eksisterer allereie" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Ytterlegare terreng" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Biomblanding" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biom" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Holer" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Hòler" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Skap" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekorasjonar" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Åtvaring: Utviklingstesten er meint for utviklarar." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Flatt terreng" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Svevande landmassar på himmelen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Flyteland (eksperimentell)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Generer ikkjefraktalterreng: Hav og undergrunn" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Haugar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Aukar fuktigheita rundt elver" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Installer $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Sjøar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Låg fuktigheit og høg temperatur fører til grunne eller tørre elver" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Kart generator" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Fjell" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Leireflyt" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Nettverk av tunellar og holer" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Ikkje noko spel valgt" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Elver" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Elver på havnivå" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Frø" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Temperert, Ørken" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Temperert, Ørken, Jungel" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Temperert, Ørken, Jungel, Tundra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Overflateerosjon på terreng" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Tre og jungelgras" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Varier elvedjupne" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Svært store holer djupt i undergrunnen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Verdsnamn" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Du har ikkje installert noko spel." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Er du sikker på at du vil slette «$1»?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Slett" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: klarte ikkje å slette «$1»" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: ugyldig sti «$1»" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Slett verd «$1»?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Bekreft passord" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Namn" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Passord" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Passorda passar ikkje!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Registrer og bli med" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Aksepter" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Døyp om modifikasjonspakken:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Denne modifikasjons-pakka har eit eksplisitt namn i sin modpakke.conf som " +"vill overstyre all omdøping her." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Ikkje nokon skildring gjeven)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D-støy" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Tilbake til innstillingssida" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Bla gjennom" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Innhald" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Innhald" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Deaktivert" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Redigér" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Aktivert" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lacunaritet" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktaver" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Forskyvning" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Persistens" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Vennligst putt inn heiltal." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Vennligst putt eit fungerande tal." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Reetabler det normale" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Skala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Søk" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Vel katalog" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Vel fil" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Vis tekniske namn" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Verdien må minst vere $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Verdien må ikkje vere større enn $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "x spreiing" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "y spreiing" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z spreiing" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Absolutt verdi" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "standardar" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "letta" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Aktivert)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 modifikasjonar" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Klarte ikkje å installere $1 til $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" +"Installer modifikasjon: Klarte ikkje å finne det reelle modifikasjonsnamnet " +"for: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Installer modifikasjon: Klarte ikkje å finne ein passande katalog for " +"modifikasjonspakke $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Klarte ikkje å finne ein gyldig modifikasjon eller modifikasjonspakke" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Funka ikkje å installere $1 som ein tekstur pakke" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Funka ikkje å installere $1 som eit spel" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Funka ikkje å installere modifikasjon som ein $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Funka ikkje å installere mod-pakka som ein $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Lastar …" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Den offentlege tenarlista er slått av" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Freist å slå på igjen den offentlege tenarlista, og sjekk Internett-" +"tilkoplinga di." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Om" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktive bidragsytarar" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Kjerne-utviklarar" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Velje ein mappe" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Tidlegare bidragsytarar" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Tidlegare kjerne-utviklarar" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Bla i nett-innhald" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Innhald" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Deaktiver teksturpakke" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informasjon:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Installerte pakker:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Ingen avhengigheiter." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Inga pakkeskildring tilgjengeleg" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Omdøp" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Avinstallér pakka" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Bruk teksturpakke" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Annonsér tenarmaskin" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Blind stad" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Kreativ stode" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Aktivér skading" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Host Game" +msgstr "Bli husvert" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Host Server" +msgstr "Bli tenarmaskin's vert" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Installer spel frå ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Ny" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Inga verd skapt eller valt!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Ha i gang spel" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Vel modifikasjonar" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Vel verd:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Tenarport" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Start spel" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adresse" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Rydd til side" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Kreativ stode" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Skade / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favorittar" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Inkompatible tenarar" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Bli med i spel" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Offentlege tenarar" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Oppdater" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Slett Favoritt" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Tenarbeskriving" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Tre-dimensjonale skyer" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Alle innstillingar" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Kantutjemning:" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Autosave Screen Size" +msgstr "Automatisk sjerm størrelse" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bi-lineært filtréring" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Endre nykeler" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Kopla i hop glass" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dynamiske skuggar" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Dynamiske skuggar: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Fancy blader" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Høg" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Låg" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Medium" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipkart" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipkart + Aniso. filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Inga filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Ingen Mipkart" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Node Highlighting" +msgstr "Knute-fremheving" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Node Outlining" +msgstr "Knute-utlinjing" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Ingen" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Ugjennomsiktige blader" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Ugjennomsiktig vatn" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partiklar" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Skjerm:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Innstillingar" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Shaders" +msgstr "Dybdeskaper" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "Dybdeskaper (ikkje tilgjengelig)" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (unavailable)" +msgstr "Dybdeskaper (ikkje tilgjengelig)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Enkle blader" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Jevn belysning" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Teksturering:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Tone Mapping" +msgstr "Tone kartlegging" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Berøringsterskel: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Tri-lineær filtréring" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Svært høg" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Svært låg" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Vaiande lauv" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Bølgjande væsker" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Vaiande planter" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Tilkoplingsfeil (Tidsavbrot?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Nett-kopling er brutt." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Ferdig!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Førebur noder" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Førebur nodar …" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Lastar teksturar …" + +#: src/client/client.cpp +#, fuzzy +msgid "Rebuilding shaders..." +msgstr "Gjennbygger dybdeskaper..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Tilkoplingsfeil (Tidsavbrot?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Kunne ikkje finne eller laste spel: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Ugyldig spel-spesifikasjonar." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Hovudmeny" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "No world selected and no address provided. Nothing to do." +msgstr "Inga verd er vald og ikkje nokon adresse valg. Ikkje noko å gjere." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Spelarnamn for langt." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Ver venleg å velje eit namn!" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Provided password file failed to open: " +msgstr "Passord dokumentet du ga går ikkje an å åpne: " + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Provided world path doesn't exist: " +msgstr "Verds-ruta du ga finnes ikkje: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Sjekk problemsøkjar.txt for detaljar." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Adresse: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- modus: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Offentleg: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- Spelar mot spelar (PvP): " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Tenarnamn: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Ein serialiseringsfeil har oppstått:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Automatiske framsteg er avtatt" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Automatiske framsteg er i gang" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Kamera oppdatering er deaktivert" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Kamera oppdatering er aktivert" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Byt kodeord" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Filmatisk modus er avtatt" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Filmatisk modus er i gang" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Klienten kopla frå" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Klient side-skildring er av" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Kopler til tenarmaskin..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Tilkoplinga feila av ein ukjent grunn" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Fortset" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Styring:\n" +"- %s: gå framover\n" +"- %s: gå bakover\n" +"- %s: gå mot venstre\n" +"- %s: gå mot høgre\n" +"- %s: hopp/klatre opp\n" +"- %s: grav/slå\n" +"- %s: plasser/nytt\n" +"- %s: snik/klatre ned\n" +"- %s: slepp ting\n" +"- %s: inventar\n" +"- Mus: snu deg/sjå\n" +"- Musehjul: vel ting\n" +"- %s: nettprat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Skapar klient..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Skapar tenarmaskin..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Problemsøkjar informasjon og profilerings graf er gøymt" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Problemsøkjaren visar sin informasjon" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Problemsøkjaren, profilerings grafen, og jern-tråd-rammen er gøymt" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Utgangspunkts Kontroller:\n" +"Ikkje nokon meny synleg:\n" +"- einskild berøring: knapp aktiveres\n" +"- dobbel berøring: plassér/bruk\n" +"- stryk finger: sjå rundt\n" +"Meny/Synleg innhald:\n" +"- dobbel berøring (ute):\n" +" -->lukk\n" +"- berør stokk, berør slott:\n" +" --> flytt stokk\n" +"- berør&dra, berør med den andre finger'n\n" +" --> plassér enkelt-gjenstand til slott\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Ubergensa utsiktsrekkjevidd har avtatt" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Ubergensa utsiktsrekkjevidd er i gang" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Skapar klient..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Gå ut til meny" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Gå ut til data'n" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Ekspressmodus er avtatt" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Ekspress modus er i gang" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Ekspress modus er i gang (notat: ikkje noko \"ekspress\" privilegier)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Flyvemodus er avtatt" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Flyvemodus er i gang" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Flyvemodus er i gang (Notat: Ikkje noko 'flyve' privilegier)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Tåke er deaktivert" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Tåke er aktivert" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Spel info:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Spelet er i avbrot, og er ståande til du kjem tilbake" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Er i gang med vertskap tå tenarmaskin" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Definerér gjennstander..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Medier..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Minikart er for tiden deaktivert tå spelet eller ein modifikasjon" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Fleirspelar" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Ikkjeklipp modus er avtatt" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Ikkjeklipp modus er i gang" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" +"Ikkjeklipp modus er i gang (notat: Ikkje noko 'ikkjeklipp' privilegier)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Definerér noder..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Av" + +#: src/client/game.cpp +msgid "On" +msgstr "På" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Tone bevegingsmodus e avtatt" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Tone bevegingsmodus er i gang" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profilerings graf er vist" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Fjern-tenarmaskin" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Slår opp addressa..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Slår av..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Enkeltspelar oppleving" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Lydvolum" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Lyd e dempa" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Lydsystemet er slått av" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Lydsystemet er ikkje støtta på denne builden" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Lyd e ikkje dempa lengre" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Tenaren køyrer sannsynlegvis ein annan versjon av %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Kunne ikkje kople til %s fordi IPv6 er slått av" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Kunne ikkje lytte på %s fordi IPv6 er slått av" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Utsiktsrekkjevidd er forandra til %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Utsiktsrekkjevidd er på eit maksimum: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Utsiktsrekkjevidd er på eit minimum: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Volum e forandra til %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Jern-tråd-ramma er vist" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zoom er for tiden deaktivert tå spelet eller ein modifikasjon" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Skravlerøret er gøymt" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Skravlerøret er vist" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD er gøymt" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD er vist" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profilering er gøymt" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profilering er vist (side %d av %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Applikasjoner" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Attende" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Kapital-tegn på/av knapp" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Styring" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Ned" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Enden" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Visk ut EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Sett i gang" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Hjelp" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Hjem" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME aksept" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME konvertér" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME slipp avsted" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME modusskifte" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME ikkje-konvertér" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Sett inn" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Venstre" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Venstre knapp" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Venstre kontrol" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Venstre meny knapp" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Venstre skift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Venstre, meta knapp" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Meny" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Mellom knappen" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lokk" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numpad *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numpad +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numpad -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numpad ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numpad /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numpad 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numpad 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numpad 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numpad 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numpad 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numpad 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numpad 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numpad 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numpad 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numpad 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Rydd til side" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Nedover på side" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Oppover på side" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Spel" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Skriv ut" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Attende" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Høgre" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Høgre knapp" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Høgre kontrol" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Høgre meny knapp" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Høgre skift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Høgre, meta knapp" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Skrolle feste" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Velj" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Skifte" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Søvn" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Skjermbilde" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Mellomrom" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabulator" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Opp" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X knapp 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Knapp 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Minikart er gøymt" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minikart i radarmodus, Zoom x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minikart i overflatemodus, Zoom x%d" + +#: src/client/minimap.cpp +#, fuzzy +msgid "Minimap in texture mode" +msgstr "Minikart i overflate modus, Zoom x1" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Klarte ikkje å opne nettside" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Opnar nettside" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Fortset" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "\"Spesiell\" = klatre ned" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Automatiske framsteg" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Automatiske hopp" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Bakover" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Byt kamera" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Skravlerør" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Befaling" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsol" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Senk rekkevidde" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Senk volum" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Dobbel berør \"hopp\" for å ha på flyve løyve" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Slipp" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Fremover" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Øk rekkevidde" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Øk volum" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Hopp" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Knapp er allereie i bruk" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Lokal befaling" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Målbind" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Neste gjenstand" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Forrige gjenstand" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Velj rekkevidde" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Skjermbilde" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Sniking" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Slå av/på HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Slå av/på skravlerør" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Slå på/av ekspress modus" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Slåpå/av flyve løyving" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Slå av/på tåke" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Slå på/av minikart" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Slå på/av ikkjeklipp" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle pitchmove" +msgstr "Slå av/på skravlerør" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "berør knapp" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Byt" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nytt passord" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Gammalt passord" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Passorda passar ikkje!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Avslutt" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Målbindt" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Lydstyrke: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "nn-NO" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Ver venleg å velje eit namn!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D-skyer" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D-modus" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D-støy som definerer gigantiske holer." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D-støy som definerer fjellstruktur og -høgde.\n" +"Definerer og strukturen på fjellterreng for flyteland." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3D-støy som definerer terreng." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Ein beskjed som skal visast til alle klientane når tenaren kræsjar." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Ein beskjed som skal visast til alle klientane når tenaren vert slått av." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Akselerasjon i luft" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Gravitasjonsakselerasjon, i nodar per sekund per sekund." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Aktive blokkmodifikatorar" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Adresse å kople til.\n" +"La dette vere tomt for å starte ein lokal tenar.\n" +"Merk at adressefeltet i hovudmenyen overkøyrer denne innstillinga." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Juster dpi-konfigurasjonen for din skjem (kun system utan X11/Android), f." +"eks. for 4K-skjermar." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Juster den oppdaga skjermtettheita, vert nytta for å skalere " +"brukargrensesnittelement." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Verdsnamn" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avansert" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Antal meldingar ein spelar kan sende per 10 sekund." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Forsterkar dalane." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Annonser tenar" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Annonser til denne tenarlista." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Armtreigheit" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Armtreigheit gir meir realistisk armbevegingar\n" +"når kameraet flyttar seg." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Spør om å kople til igjen etter eit kræsj" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Automatisk framoverknapp" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Rapporter automatisk til tenarlista." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Lagre skjermstørrelsen automatisk" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Autoskaleringsmodus" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Bakoverknapp" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Basisprivilegium" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Bind adresse" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Bygg intern spelar" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Innebygd" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Byt kamera" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Hòlebreidde" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Chatkommandoar" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Tekststørrelse for nettprat" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Nettpratstast" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Loggnivå for chat" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Maksimal lengde på chattemeldingar" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Knapp for å slå chatten av/på" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Nettlenker i chatten" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Klient" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Klient og tenar" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Klatrefart" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Skyradius" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Skyer" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Skyer er ei effekt på klientsida." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Skyer i meny" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Farga tåke" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Farga skuggar" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Kommandoknapp" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Kople saman glas" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Kople til ekstern mediatenar" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Konsollgjennomsiktigheit" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Konsollfarge" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Konsollhøgde" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Største antal samtidige nedlastingar frå ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "URL til ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Styring" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Kontrollerer lengda på dag/natt-syklusen.\n" +"Eksempel:\n" +"72 = 20 min., 360 = 4 min., 1 = 24 timar, 0 = dag/natt/anna forblir uendra." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Kræsjmelding" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Kreativ" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Skade" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Knapp for å slå debuggingsinformasjon av/på" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Standard akselerasjon" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Standard spel" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Standard spel når du lagar ei ny verd.\n" +"Dette vil verte overstyrt når du lagar ei verd frå hovudmenyen." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Standard passord" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Standard privilegium" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Standard rapportformat" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Definerer område der tre har eple." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Definerer område med sandstrender." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Definerer distribusjonen av høgare terreng." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Definerer djupna til elvekanalen." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Dekorasjonar" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Kantutjemning:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Spel" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "HUD er vist" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Jevn belysning" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Knute-fremheving" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Skjerm:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Skjermbilde" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Bli tenarmaskin's vert" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "- Tenarnamn: " + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Tenarbeskriving" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Tenarport" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Skyradius" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Innstillingar" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Raslende lauv" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Bølgete vatn" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Raslende lauv" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Bølgete vatn" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#, fuzzy +#~ msgid "- Creative Mode: " +#~ msgstr "- Gude løyving: " + +#~ msgid "- Damage: " +#~ msgstr "- Skade: " + +#~ msgid "Address / Port" +#~ msgstr "Adresse / port" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Er du sikker på at du vill tilbakestille enkel-spelar verd?" + +#~ msgid "Back" +#~ msgstr "Attende" + +#~ msgid "Basic" +#~ msgstr "Basis" + +#~ msgid "Bump Mapping" +#~ msgstr "Dunke kartlegging" + +#~ msgid "Config mods" +#~ msgstr "Konfigurer modifikasjoner" + +#~ msgid "Configure" +#~ msgstr "Konfigurér" + +#~ msgid "Connect" +#~ msgstr "Kople i hop" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Kontrollerer kor raskt ting synk i væske." + +#~ msgid "Credits" +#~ msgstr "Medvirkende" + +#~ msgid "Damage enabled" +#~ msgstr "Skade aktivert" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Last ned eit spel, slik som Minetest-spelet, frå minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Last ned eit frå minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Henter og installerer $1, ver vennleg og vent..." + +#~ msgid "Enter " +#~ msgstr "Gå " + +#~ msgid "Game" +#~ msgstr "Spel" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Generér normale kart" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Installer: fil: «$1»" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Knappebindinger. (Om denne menyen går galen, ta bort tinga fra \"minetest." +#~ "conf\")" + +#~ msgid "Main" +#~ msgstr "Hovud" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Minikart i radarmodus, Zoom x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Minikart i radarmodus, Zoom x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Minikart i overflate modus, Zoom x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Minikart i overflate modus, Zoom x4" + +#~ msgid "Name / Password" +#~ msgstr "Namn/Passord" + +#~ msgid "Name/Password" +#~ msgstr "Namn/passord" + +#~ msgid "No" +#~ msgstr "Nei" + +#~ msgid "Ok" +#~ msgstr "OK" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parralax okklusjon" + +#~ msgid "PvP enabled" +#~ msgstr "Spelar mot spelar aktivert" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Tilbakegå enkelspelar verd" + +#~ msgid "Select Package File:" +#~ msgstr "Velje eit pakke dokument:" + +#~ msgid "Special" +#~ msgstr "Spesial" + +#~ msgid "Start Singleplayer" +#~ msgstr "Start enkeltspelar oppleving" + +#, fuzzy +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "For å aktivere skumrings-effekt så må OpenGL driveren være i bruk." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Slå på/av kameramodus" + +#~ msgid "Yes" +#~ msgstr "Ja" + +#, fuzzy, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Du er i gang med å hoppe inn i ein tenarmaskin ved %1$s med namnet " +#~ "\"%2$s\" for fyrste gong. Om du går videre, ein ny brukar med dine " +#~ "detaljer vill bli skapt på tenarmaskinen.\n" +#~ "Ver vennleg og skriv passordet, klikk registrer og trykk \"bli med\" for " +#~ "at kontoen skal bli registrert eller klikk avbryt for å ikkje gjere det." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Du døydde" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/oc/minetest.po b/po/oc/minetest.po new file mode 100644 index 0000000..1450730 --- /dev/null +++ b/po/oc/minetest.po @@ -0,0 +1,6859 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-31 17:28+0000\n" +"Last-Translator: Walter Bulbazor <prbulbazor@protonmail.com>\n" +"Language-Team: Occitan <https://hosted.weblate.org/projects/minetest/" +"minetest/oc/>\n" +"Language: oc\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Panar la sortida de messatges" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Comanda voeida." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Quitar au menú principau" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Comanda pas valida: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Comanda mandada: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Listar los jogaires en linha" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Jogaires en linha: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "La sortida de messatges es avora voeida." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Aquesta comanda es pas activada per lo servidor." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Tornar" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Setz mòrt·as" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Comandas disponiblas:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Comandas disponiblas: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Comanda pas disponibla: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Ajuda per las comandas" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Utilizatz '.help <cmd>' per aver mai d'informacions, o '.help all' per tot " +"listar." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "D'accòrdi" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<pas res disponible>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Se presenta una error dins un escrípt Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Se presenta una error:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menú principau" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Tornar Conectar" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Lo servidor demandèt de se tornar conectar:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "Una novèla $1 version es disponible" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "Mòds dau Client" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" +"Version installada: $1\n" +"Version novèla: $2\n" +"Vos chau visitar $3 per sabèr cossí tenèr la novèla version e gardar una " +"version mesa a jorn per los foncionalitats e las reparacions de bugs." + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "Mai Tard" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "Pas Jamai" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "La version dau protocòl correspònda pas. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Lo servidor impausa la version $1 dau protocòl. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Lo servidor pòt suportar de versions dau protocòl entre $1 e $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "Visitar le sit" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Suportem mas la version $1 dau protocòl." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Suportem de versions dau protocòl entre $1 e $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "(Activat, a una error)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "(Insatisfait)" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Annular" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Dependéncias:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Tot desactivar" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Desactivar lo mòdpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Tot activar" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Activar lo mòdpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Error per l'activacion dau mòd \"$1\" per çò qu'a de caractèrs pas " +"autorizats. Mas los caractèrs [a-z0-9_] son autorizats." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Charchar Mai de Mòds" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mòd:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Pas de dependéncias (optionalas)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Lo juòc ten pas de descripcion provesida." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Pas de dependéncias" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Lo mòdpack ten pas de descripcion provesida." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Pas de dependéncias optionalas" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Dependéncias optionalas:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Sauvar" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Monde:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "activat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" exista dejà. Voletz l'espotir?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Las dependéncias $1 e $2 van s'installar." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 per $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 en descharjament,\n" +"$2 en espeita" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "Descharjament de $1..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "Las dependéncias que fasàn besonh per $1 pòdan pas se trobar." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 sera installat, e las dependéncias de $2 seràn ignoradas." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Tot los paquets" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Dejá installat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Tornar au Menú Principau" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Juòc de Basa:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB es pas disponible quand Minetest es compilat sens cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Descharjament..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Error per lo descharjament de $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Juòcs" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Installar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Installar $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Installar las dependéncias mancantas" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Installacion: Tipe de fichèir pas supportat o archiva cassada" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mòds" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Pas ges de paquets poguèron èstre quèrre" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Pas de resultats" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Pas de mesas a jorn" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Pas trobat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Espotir" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Verifiatz que lo juòc de basa es corrèct." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "En espeita" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Pacs de textura" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Desinstallar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Mesa a jorn" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Tot metre a jorn [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Agachar mai d'informacions dins un navegador wèb" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Un monde sona \"$1\" exista dejà" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Tarren en mai" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Freid de nautor" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Nautor sècha" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Mesclar de biòm" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biòms" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Caunas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Cavas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Crear" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Decoracions" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "Test de Desvelopament es per los desvelopair·e·a·s." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Donjons" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Tarren plat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Massas de tarren que flotàn dins lo ciau" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Tarrens flotejants (experimentau)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Generar un tarren pas fractau: Oceans e sostarrens" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Montèls" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Ribèiras mostas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Aumente la mostor a l'entorn de ribèiras" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "Installar un juòc" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "Installar un autre juòc" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Lacs" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Mostor bassa e chalor elevada fan venir las ribèiras pas plòndas e sèchas" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Generator de tarrens" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Drapèls de generator de tarren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Drapèls specifics dau generator de tarren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Montanhas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Rajada de gadòlha" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Ret de tunèls e de gròtas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Pas de juòc selectionat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Redusa la chalor embei l'altitud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Redusa la mostor embei l'altitud" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Ribèiras" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Ribèiras au nivèl de la mar" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Grana" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Transicion doça entre los biòms" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Estructuras aparéisson per le tarren (pas d'efèit per los aubres e l'èrba de " +"jungla creats per la v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Estructuras aparéisson per le tarren, en generau d'aubres e de plantas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Temperat, Desertic" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Temperat, Desertic, Jungla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Temperat, Desertic, Jungla, Tondra, Taïga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erosia de la surfàcia dau tarren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Aubres e èrba de jungla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Variar la plondor de la ribèira" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Mai grandas caunas plondorosas dins lo sostarren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nom dau monde" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Avètz pas ges de juòc installat." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Sètz surat de vaudre suprimar \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Suprimar" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: error per suprimar \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: chamin \"$1\" pas valide" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Suprimar lo Monde \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Acceptar" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Tornar sonar lo Mòdpack:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Pas de descripcion o de paramètre bailat)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Brut 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Tornar a la Paja de Paramètres" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Navegar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Desactivat" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Modifiar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Activat" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lacunaritada" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Octavas" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Descalatge" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Persisténcia" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Bailatz un nombre entèir valide." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Bailatz un nombre valide." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Tornar per defaut" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Eschala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Charchar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Seleccionar un repertòre" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Seleccionar un fichèir" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Mostrar los noms tecnics" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Chau que la valor siáge au mens $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Chau pas que la valor siáge mai granda que $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Escart X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Escart Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Escart Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "valor absoluda" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "defaut" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "polit" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Activat)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mòds" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Error per installar $1 vès $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Installar un Mòd: Pas possible de trobar lo nom reau dau mòd per: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Installar un Mòd: Pas possible de trobar un nom de dorsèir convenant per lo " +"mòdpack $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Se pòt pas trobar un mòd o un mòdpack valide" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Se pòt pas installar $1 coma un pack de texturas" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Se pòt pas installar un juòc coma un $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Se pòt pas installar un mòd coma un $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Se pòt pas installar un mòdpack coma un $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Charjament..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "La lista de servidors publics es pas activada" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Essatjatz de tornar activar la lista de servidors e verifiatz vòstra " +"connexion d'internet." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "A prepaus" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Collaboradors Actius" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Developaires Principaus" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Ancians Collaboradors" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Ancians Developaires Principaus" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shaders" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "" + +#: src/client/game.cpp +msgid "- Public: " +msgstr "" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" diff --git a/po/pl/minetest.po b/po/pl/minetest.po new file mode 100644 index 0000000..39c5704 --- /dev/null +++ b/po/pl/minetest.po @@ -0,0 +1,8645 @@ +msgid "" +msgstr "" +"Project-Id-Version: Polish (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-03-18 02:57+0000\n" +"Last-Translator: Jakub Z <mrkubax10@onet.pl>\n" +"Language-Team: Polish <https://hosted.weblate.org/projects/minetest/minetest/" +"pl/>\n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.12-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Wyczyść kolejkę wiadomości czatu" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Pusta komenda." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Wyjście do menu" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Błędna komenda: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Wydana komenda: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Lista graczy online" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Gracze online: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Kolejka czatu jest teraz pusta." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Ta komenda jest dezaktywowana przez serwer." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Wróć do gry" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Umarłeś" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Dostępne komendy:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Dostępne komendy: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Polecenie nie jest dostępne: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Uzyskaj pomoc dotyczącą poleceń" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Użyj '.help <cmd>', aby uzyskać więcej informacji lub '.help all', aby " +"wyświetlić wszystko." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[wszystko | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<niedostępne>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Wystąpił błąd w skrypcie Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Wystąpił błąd:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menu główne" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Połącz ponownie" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Serwer zażądał ponownego połączenia:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Wybierz Mody" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Niezgodne wersje protokołów. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Serwer żąda użycia protokołu w wersji $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Serwer wspiera protokoły w wersjach od $1 do $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Wspieramy wyłącznie protokół w wersji $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Wspieramy protokoły w wersji od $1 do $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Anuluj" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Zależności:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Wyłącz wszystko" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Wyłącz moda" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Włącz wszystkie" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Aktywuj moda" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Nie udało się aktywować modyfikacji \"$1\", ponieważ zawiera niedozwolone " +"znaki. Tylko znaki od [a-z, 0-9 i _] są dozwolone." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Znajdź Więcej Modów" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Brak (dodatkowych) zależności" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Brak dostępnych informacji o grze." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Brak wymaganych zależności" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Brak dostępnych informacji o modzie." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Brak dodatkowych zależności" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Dodatkowe zależności:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Zapisz" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Świat:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "włączone" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" aktualnie istnieje. Czy chcesz go nadpisać?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Zależności $1 i $2 będą zainstalowane." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 przez $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 pobierany,\n" +"$2 w kolejce" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "Pobieranie $1..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 wymaga zależności, które nie zostały znalezione." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 zostanie zainstalowany, a zależności $2 zostaną pominięte." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Wszystkie zasoby" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Już zainstalowany" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Powrót do menu głównego" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Gra podstawowa:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB nie jest dostępne gdy Minetest był zbudowany bez cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Pobieranie..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Pobieranie $1 do $2 nie powiodło się :(" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Gry" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instaluj" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Zainstaluj $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Zainstaluj brakujące zależności" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Instalacja: nieznany typ pliku lub uszkodzone archiwum" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Modyfikacje" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Nie można pobrać pakietów" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Brak Wyników" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Brak aktualizacji" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Nie znaleziono" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Nadpisz" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Proszę sprawdzić, czy gra podstawowa jest poprawnie zainstalowana." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "W kolejce" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Paczki zasobów" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Odinstaluj" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Aktualizuj" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Zaktualizuj wszystko [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Pokaż więcej informacji w przeglądarce" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Istnieje już świat o nazwie \"$1\"" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Dodatkowy teren" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Wysokość mrozu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Wysokość suchości" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Mieszanie biomów" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomy" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "jaskinie" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Jaskinie" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Utwórz" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekoracje" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Ostrzeżenie: The Development Test jest przeznaczony dla programistów." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Lochy" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Płaski teren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Masywy lądowe unoszące się na niebie" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Latające wyspy (eksperymentalne)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Generuj niefraktalny teren: oceany i podziemia" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Wzgórza" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Wilgotne rzeki" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Zwiększa wilgotność wokół rzek" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Zainstaluj $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Jeziora" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Niska wilgotność i wysoka temperatura wpływa na niski stan rzek lub ich " +"wysychanie" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Generator mapy" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Flagi generatora mapy" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Flagi specyficzne dla Mapgena" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Góry" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Strumień błota" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Sieć jaskiń i korytarzy" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Nie wybrano gry" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Redukuje ciepło wraz z wysokością" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Spadek wilgotności wraz ze wzrostem wysokości" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Rzeki" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Rzeki na poziomie morza" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Ziarno losowości" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Płynne przejście między biomami" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Struktury pojawiające się na terenie (brak wpływu na drzewa i trawę w " +"dżungli stworzone przez v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Struktury pojawiające się na terenie, zazwyczaj drzewa i rośliny" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Umiarkowany, Pustynny" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Umiarkowany, Pustynia, Dżungla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Umiarkowany, Pustynia, Dżungla, Tundra, Tajga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erozja powierzchni terenu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Drzewa i trawa w dżungli" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Zmienna głębokość rzeki" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Bardzo duże jaskinie głęboko w podziemiach" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nazwa świata" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Nie zainstalowano żadnych trybów gry." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Na pewno usunąć \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Usuń" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "Modmgr: nie udało się usunąć \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "Modmgr: nieprawidłowy katalog \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Usunąć świat \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Potwierdź hasło" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Nazwa generatora mapy" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nazwa" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Hasło" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Hasła nie są jednakowe!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Zarejestruj się i dołącz" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Zaakceptuj" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Zmień nazwe Paczki Modów:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Ten mod ma sprecyzowaną nazwę nadaną w pliku konfiguracyjnym modpack.conf, " +"która nadpisze każdą zmienioną tutaj nazwę." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(brak opisu)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Szum 2d" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Wróć do ekranu ustawień" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Przeglądaj" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Zawartość" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Zawartość" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Wyłączone" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Edytuj" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Włączone" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lunarność" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktawy" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Margines" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Trwałość" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Proszę wpisać prawidłową liczbę." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Proszę wpisać prawidłowy numer." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Przywróć domyślne" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Skaluj" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Wyszukaj" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Wybierz katalog" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Wybierz plik" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Pokaż nazwy techniczne" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Wartość musi wynosić co najmniej $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Wartość nie może być większa niż $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Rozrzut X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Rozrzut Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Rozrzut Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "wartość bezwzględna" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "domyślne" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "wygładzony" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Aktywny)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "Modyfikacja $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Instalacja $1 do $2 nie powiodła się" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Instalacja moda: nie można znaleźć nazwy moda $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Instalacja moda: nie można znaleźć odpowiedniego folderu dla paczki modów $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Nie można znaleźć prawidłowego moda lub paczki modów" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Nie można zainstalować $1 jako paczki tekstur" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Nie można zainstalować gry jako $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Nie moźna zainstalować moda jako $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Nie można zainstalować paczki modów jako $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Ładowanie..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Lista serwerów publicznych jest wyłączona" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Spróbuj ponownie włączyć publiczną listę serwerów i sprawdź swoje połączenie " +"z siecią Internet." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "O" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktywni współautorzy" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Aktywny moduł renderowania:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Twórcy" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Otwórz katalog danych użytkownika" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Otwiera katalog, który zawiera światy, gry, mody i tekstury dostarczone " +"przez użytkownika\n" +"oraz pakiety tekstur w menedżerze plików / eksploratorze." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Byli współautorzy" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Poprzedni Główni Deweloperzy" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Pokaż informacje debugowania" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Przeglądaj zawartość online" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Zawartość" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Wyłącz pakiet tekstur" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informacja:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Zainstalowane pakiety:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Brak wymaganych zależności." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Brak opisu pakietu" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Zmień nazwę" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Usuń modyfikację" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Użyj paczki tekstur" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Rozgłoś serwer" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Adres" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Tryb kreatywny" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Włącz obrażenia" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Utwórz grę" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Udostępnij serwer" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Instaluj gry z ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Nowy" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Nie wybrano bądź nie utworzono świata!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Graj" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Wybierz Mody" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Wybierz świat:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Port Serwera" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Rozpocznij grę" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adres" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Delete" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Tryb kreatywny" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Obrażenia / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Ulubione" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Niekompatybilne serwery" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Dołącz do gry" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Publiczne serwery" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Odśwież" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Port zdalny" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Opis serwera" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Chmury 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Wszystkie ustawienia" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Antyaliasing:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Automatyczny zapis rozmiaru okienka" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Filtrowanie dwuliniowe" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Zmień klawisze" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Szkło połączone" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Cienie dynamiczne" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Cienie dynamiczne: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Ozdobne liście" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Wysokie" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Niskie" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Średnie" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmapy" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmapy i Filtr anizotropowe" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Filtrowanie wyłączone" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Mip-Mappowanie wyłączone" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Podświetlanie bloków" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Obramowanie bloków" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Brak" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Nieprzejrzyste liście" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Nieprzejrzysta Woda" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Włącz Efekty Cząsteczkowe" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Ekran:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Ustawienia" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shadery" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shadery (eksperymentalne)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Shadery (Nie dostępne)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Proste Liście" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Płynne oświetlenie" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Teksturowanie:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Tone Mapping" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Próg dotyku (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Filtrowanie trójliniowe" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Bardzo wysokie" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Bardzo niskie" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Falujące liście" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Fale (Ciecze)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Falujące rośliny" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Błąd połączenia (brak odpowiedzi?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Upłynął czas połączenia." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Gotowe!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inicjalizacja elementów" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Inicjalizacja elementów..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Ładowanie tekstur..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Przebudowywanie shaderów..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Błąd połączenia (brak odpowiedzi?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Nie można znaleźć lub załadować gry: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Nieprawidłowa specyfikacja trybu gry." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menu główne" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Nie wybrano świata ani adresu." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Nazwa gracza jest za długa." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Wybierz nazwę!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Nie udało się otworzyć dostarczonego pliku z hasłem " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Podana ścieżka świata nie istnieje: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Sprawdź plik debug.txt by uzyskać więcej informacji." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "Adres " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Tryb: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Publiczne: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "Gracz przeciwko graczowi: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Nazwa serwera: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Wystąpił błąd serializacji:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Odmowa dostępu. Powód: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Automatyczne chodzenie do przodu wyłączone" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Automatyczne chodzenie do przodu włączone" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Ukryte granice bloków" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Granice bloków pokazane dla wszystkich bloków" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Granice bloku wyświetlane dla bieżącego bloku" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Granice bloków pokazane dla pobliskich bloków" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Aktualizowanie kamery wyłączone" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Aktualizowanie kamery włączone" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" +"Nie można wyświetlić granic bloków (wymagane uprawnienie 'basic_debug')" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Zmień hasło" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Tryb kinowy wyłączony" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Tryb kinowy włączony" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Klient został rozłączony" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Skryptowanie po stronie klienta jest wyłączone" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Łączenie z serwerem..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Połączenie nie powiodło się z nieznanego powodu" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Kontynuuj" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Sterowanie:\n" +"- %s: idź do przodu\n" +"- %s: przesuń się do tyłu\n" +"- %s: przesuń się w lewo\n" +"- %s: przesuń w prawo\n" +"- %s: skok/wspinaj się\n" +"- %s: kopanie/cios\n" +"- %s: połóż/użyj\n" +"- %s: skradanie się/schodzenie w dół\n" +"- %s: upuść przedmiot\n" +"- %s: ekwipunek\n" +"- Mysz: obróć / spójrz\n" +"- Kółko myszy: wybierz element\n" +"- %s: czat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Nie można rozwiązać adresu: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Tworzenie klienta..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Tworzenie serwera...." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Informacje debugu oraz wykresy są ukryte" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Informacje debugu widoczne" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Informacje debugu, wykresy oraz tryb siatki są ukryte" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Domyślne sterowanie:\n" +"Brak widocznego menu:\n" +"- pojedyncze dotknięcie: aktywacja\n" +"- podwójne dotknięcie: postaw/użyj\n" +"- przejechanie palcem: rozglądanie się\n" +"Menu/Ekwipunek widoczny:\n" +"- potwójne dotknięcie poza menu:\n" +" -->zamknij\n" +"- dotknięcie stacka, dotknięcie slota:\n" +" --> przenieś stack\n" +"- dotknięcie i przeciągnięcie, dotknięcie drugim palcem\n" +" --> umieść pojedynczy item w slocie\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Wyłączono nieskończony zasięg widoczności" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Włączono nieskończony zasięg widoczności" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Tworzenie klienta..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Wyjście do menu" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Wyjście z gry" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Tryb szybki wyłączony" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Tryb szybki włączony" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Tryb szybki włączony (uwaga: nie masz uprawnień \"trybu szybkiego\")" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Tryb latania wyłączony" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Tryb latania włączony" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Tryb latania włączony (uwaga: nie masz uprawnień \"latania\")" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Mgła wyłączona" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Mgła włączona" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Informacje o grze:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Gra wstrzymana" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Tworzenie serwera" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Definicje przedmiotów..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Media..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Minimapa aktualnie wyłączona przez grę lub mod" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Gra wieloosobowa" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Tryb noclip wyłączony" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Tryb noclip włączony" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Tryb noclip włączony (uwaga: nie masz uprawnień \"noclip\")" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Definicje bloków..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Wyłącz" + +#: src/client/game.cpp +msgid "On" +msgstr "Włącz" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Tryb nachylenia ruchu wyłączony" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Tryb nachylenia ruchu włączony" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Wykresy profilera widoczne" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Serwer zdalny" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Sprawdzanie adresu..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Wyłączanie..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Pojedynczy gracz" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Głośność" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Głośność wyciszona" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "System dźwiękowy jest wyłączony" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "System dźwiękowy nie jest obsługiwany w tej kompilacji" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Głośność włączona ponownie" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Serwer prawdopodobnie pracuje na innej wersji %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Nie można połączyć się z %s, ponieważ IPv6 jest wyłączony" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Nie można nasłuchiwać na %s, ponieważ IPv6 jest wyłączony" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Zmieniono zasięg widoczności na %d%%" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Zasięg widoczności na maksimum:%d1" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Zasięg widoczności na minimum: %d1" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Zmieniono poziom głośności na %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Siatka widoczna" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Powiększenie jest obecnie wyłączone przez grę lub mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Czat ukryty" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Chat widoczny" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD ukryty" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD widoczny" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profiler ukryty" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profiler wyświetlony (strona %d z %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Klawisz Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Dół" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Usuń EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Wykonaj" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Pomoc" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Zaakceptuj IME" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Konwertuj IME" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "Uniknij IME" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Zmiana Trybu IME" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "Niezmienialny" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Lewo" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Lewy przycisk myszy" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Lewy Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Lewy Menu" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Lewy Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Lewy Windows" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Środkowy przycisk myszy" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numeryczna *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numeryczna +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numeryczna -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numeryczna ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numeryczna /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numeryczna 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numeryczna 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numeryczna 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numeryczna 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numeryczna 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numeryczna 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numeryczna 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numeryczna 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numeryczna 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numeryczna 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Graj" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Drukuj" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Prawo" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Prawy przycisk myszy" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Prawy Control" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Prawy Menu" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Prawy Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Prawy Windows" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Wybierz" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Uśpij" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Snapshot" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Spacja" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Góra" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Przycisk X 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Przycisk X 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Minimapa ukryta" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimapa w trybie radaru, Zoom x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimapa w trybie powierzchniowym, powiększenie x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimapa w trybie teksturowym" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Nie udało się otworzyć strony internetowej" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Otwieram stronę internetową" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Kontynuuj" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = schodź" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Automatyczne chodzenie do przodu" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Automatyczne skoki" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Tył" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Granice bloków" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Zmień kamerę" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Czat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Komenda" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsola" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Zmniejsz pole widzenia" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Zmniejsz głośność" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Wciśnij dwukrotnie \"Skok\" by włączyć tryb latania" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Upuść" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Przód" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Zwiększ pole widzenia" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Zwiększ głośność" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Ekwipunek" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Skok" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Klawisz już zdefiniowany" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Lokalne polecenie" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Wycisz" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Następny przedmiot" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Poprzedni przedmiot" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Zasięg widzenia" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Zrzut ekranu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Skradanie" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Przełącz HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Przełącz historię czatu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Przełącz tryb szybki" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Przełącz tryb latania" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Przełącz mgłę" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Przełącz minimapę" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Przełącz tryb noclip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Przełączanie przemieszczania" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "naciśnij klawisz" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Zmień" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nowe hasło" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Stare hasło" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Hasła nie są jednakowe!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Wyjście" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Wyciszony" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Głośność: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "pl" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Wybierz nazwę!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Mocuje pozycję wirtualnego joysticka.\n" +"Gdy jest wyłączona, wirtualny joystick przestawi się do miejsca pierwszego " +"dotknięcia." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Użyj wirtualnego joysticka, aby aktywować przycisk \"Aux1\".\n" +"Gdy jest włączone to wirtualny joystick również naciśnie przycisk \"Aux1\", " +"gdy znajduje się poza głównym okręgiem." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) przesunięcie fraktala od środka świata w jednostkach „skali”.\n" +"Może być użyty do przeniesienia żądanego punktu do (0, 0), aby utworzyć a\n" +"odpowiedni punkt odradzania, lub aby umożliwić „przybliżenie” na żądanym " +"miejscu\n" +"punkt, zwiększając „skalę”.\n" +"Domyślnie ustawiony jest odpowiedni punkt odradzania dla Mandelbrota\n" +"zestawy z domyślnymi parametrami, może wymagać zmiany w innych\n" +"sytuacje.\n" +"Zakres mniej więcej -2 do 2. Pomnóż przez „skalę” dla przesunięcia w węzłach." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"Skala (X.Y.Z) fraktali w węzłach.\n" +"Rzeczywisty rozmiar fraktali będzie 2, 3 raz większy.\n" +"Te wartości mogą być bardzo wysokie, \n" +"fraktal nie musi mieścić się wewnątrz świata.\n" +"Zwiększ je, aby 'przybliżyć' wewnątrz szczegółów fraktalu.\n" +"Domyślna wartość jest ustawiona dla kształtu zgniecionego pionowo " +"odpowiedniego \n" +"dla wyspy, ustaw 3 wartości równe, aby uzyskać surowy kształt." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Szum 2D który wpływa na kształt/rozmiar łańcuchów górskich." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Szum 2D, który wpływa na kształt/rozmiar zaokrąglonych wzgórz." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Szum 2D, który wpływa na kształt/ rozmiar górskich stepów." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "Szum 2D, który wpływa na rozmiar/występowanie grzbietów górskich." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "Szum 2D, który wpływa na rozmiar/występowanie falistych wzgórz." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "Szum 2D, który wpływa na rozmiar/ występowanie stepów górskich." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Szum 2D lokalizuje doliny i kanały rzeczne." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Chmury 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Modele 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Siła paralaksy w trybie 3D" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Szum 3d określający olbrzymie jaskinie." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Szum 3d określający strukturę i wysokość gór.\n" +"Określa również strukturę wznoszącego się terenu górzystego." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Szum 3D określający strukturę terenów pływających.\n" +"Jeśli wartość domyślna zostanie zmieniona, konieczne będzie dostosowanie " +"\"skali\" szumu (domyślnie 0,7), \n" +"ponieważ zwężanie terenów pływających działa najlepiej, \n" +"gdy wartość szumu jest z zakresu od około -2,0 do 2,0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Szum 3d określający strukturę kanionów rzecznych." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Szum 3D określający teren." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "Szum 3D dla nawisów skalnych, klifów, itp. Zwykle mało zróżnicowany." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "Szum 3D, który wpływa na liczbę lochów na jeden mapchunk." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Wsparcie 3D\n" +"Aktualnie wspierane:\n" +"- none: bez wyjścia 3d.\n" +"- anaglyph: Niebieski/karmazynowy kolor 3d.\n" +"- interlaced: bazujący na polaryzacji parzystej/nieparzystej linii.\n" +"- topbottom: podzielony ekran góra/dół.\n" +"- sidebyside: podzielony obok siebie.\n" +"- crossview: obuoczne 3d\n" +"- pageflip: 3D bazujące na quadbuffer.\n" +"Zauważ, że tryb interlaced wymaga włączenia shaderów." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Wybrane ziarno dla nowej mapy, pozostaw puste dla losowego ziarna.\n" +"Będzie nadpisane kiedy tworzy się nowy świat w głównym menu." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" +"Wiadomość wyświetlana wszystkim klientom kiedy serwer zerwie połączenie." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Wiadomość, która będzie wyświetlona wszystkim klientom kiedy serwer zostanie " +"wyłączony." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Interwał ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Budżet czasowy ABM" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Bezwzględny limit kolejki pojawiających się bloków" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Przyspieszenie w powietrzu" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Przyśpieszenie grawitacyjne, w blokach na sekundę do kwadratu." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Modyfikatory aktywnego bloku" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Interwał zarządzania aktywnym blokiem" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Zasięg aktywnego bloku" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Zasięg wysyłania aktywnego obiektu" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Adres połączenia.\n" +"Pozostaw pusty aby utworzyć lokalny serwer.\n" +"Zauważ że pole adresu w głównym menu nadpisuje te ustawienie." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Dodaje efekty cząstkowe podczas wykopywania bloków." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Ustaw konfiguracje DPI dla twojego ekranu (nie X11/Tylko Android) np. dla " +"ekranów 4k." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Dostosuj wykrytą gęstość wyświetlania, używaną do skalowania elementów UI." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Dostosowuje gęstość warstwy pływających wysp.\n" +"Aby zwiększyć gęstość, ustaw wyższą wartość. Może być dodatnia lub ujemna.\n" +"Wartość = 0,0: 50% objętości to pływająca wyspa.\n" +"Wartość = 2,0 (może być wyższa w zależności od 'mgv7_np_floatland', aby mieć " +"pewność,\n" +"zawsze sprawdzaj) tworzy stałą warstwę pływającej wyspy." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Dołącz nazwę przedmiotu" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Zaawansowane" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Modyfikuje krzywą światła przez nałożenie na nią 'korekcji gamma'.\n" +"Im wyższa wartość, tym jaśniejsze światło ze średniego i niskiego zakresu.\n" +"Wartość '1.0' oznacza brak zmian.\n" +"Tylko światło dnia i sztuczne światło są znacząco zmieniane, \n" +"światło nocne podlega zmianie w minimalnym stopniu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Zawsze lataj oraz poruszaj się szybko" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Ambient occlusion gamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Dozwolona liczba wiadomości wysłanych przez gracza w ciągu 10 sekund." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Wzmacnia doliny." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Filtrowanie anizotropowe" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Rozgłoś serwer" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Rozgłoś listę serwerów." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Dołącz nazwę przedmiotu" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Dołącz nazwę przedmiotu do jego opisu." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Szum jabłoni" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Bezwładność ramion" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Bezwładność ramion, daje bardziej realistyczny ruch\n" +"ramion, podczas przesuwania kamery." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Poproś o ponowne połączenie po awarii" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"W tej odległości serwer agresywnie zoptymalizuje, które bloki są wysyłane " +"do\n" +"klientów.\n" +"Małe wartości potencjalnie znacznie poprawiają wydajność, kosztem " +"widocznych\n" +"trzaski renderowania (niektóre bloki nie będą renderowane pod wodą i w " +"jaskiniach,\n" +"jak również czasami na lądzie).\n" +"Ustawienie tego na wartość większą niż max_block_send_distance wyłącza to\n" +"optymalizacja.\n" +"Podane w mapblocks (16 węzłów)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Klawisz automatycznego poruszania się do przodu" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Automatycznie przeskakuj jedno-blokowe przeszkody." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Automatycznie zgłoś do listy serwerów." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Automatyczny zapis rozmiaru okienka" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Tryb automatycznego skalowania" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Klawisz Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Klawisz Aux1 używany do wspinania/schodzenia" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Wstecz" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Poziom ziemi" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Bazowa wysokość terenu." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Podstawowe uprawnienia" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Szum plaży" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Próg szumu plaży" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Filtrowanie dwuliniowe" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Sprawdzanie adresu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Parametry hałasu temperatury i wilgotności API Biome" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Szum biomu" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Dystans optymalizacji wysyłanych bloków" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Ścieżka pogrubionej czcionki oraz kursywy" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Ścieżka czcionki o stałej szerokości i pogrubionej kursywą" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Ścieżka fontu pogrubionego" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Pogrubiona ścieżka czcionki o stałej szerokości" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Buduj w pozycji gracza" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Wbudowany" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Zmień kamerę" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Odległość kamery „w pobliżu płaszczyzny przycinania” w węzłach, od 0 do " +"0.25\n" +"Działa tylko na platformie GLES. Większość użytkowników nie będzie " +"potrzebowała tego zmieniać.\n" +"Zwiększenie może zmniejszyć występowanie artefaktów na słabszych kartach " +"graficznych.\n" +"0.1 = Domyślnie, 0.25 = Dobra wartość dla słabszych tabletów." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Wygładzanie kamery" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Wygładzanie kamery w trybie cinematic" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Klawisz przełączania kamery" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Szum jaskini" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Szum jaskini #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Szum jaskini #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Szerokość jaskini" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Szum jaskini #1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Szum jaskini #1" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Szerokość jaskini" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Szum jaskini #1" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Zwężenie jaskini" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Próg groty" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Górna granica jaskiń" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Środek zakresu wzmocnienia krzywej światła.\n" +"0.0 to minimalny poziom światła, 1.0 to maksymalny poziom światła." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Próg wiadomości czasu polecenia czatu" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Komendy czatu" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Rozmiar czcionki" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Klawisz czatu" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Poziom dziennika czatu" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Limit liczby wiadomości na czacie" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Format wiadomości czatu" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Próg wiadomości wyrzucenia z czatu" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Maksymalna długość wiadomości na czacie" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Klawisz przełączania czatu" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Chat widoczny" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Szerokość fragmentu" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Tryb Cinematic" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Klawisz trybu Cinematic" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Czyste przeźroczyste tekstury" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Klikalne łącza internetowe (kliknięcie środkowym przyciskiem lub Ctrl+lewy " +"przycisk myszy) włączone w danych wyjściowych konsoli czatu." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Klient" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Klient i Serwer" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Modyfikacja klienta" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Ograniczenia modowania po stronie klienta" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Ograniczenie zakresu wyszukiwania węzłów po stronie klienta" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Modyfikacja klienta" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Szybkość wspinania" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Zasięg chmur" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Chmury 3D" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Chmury są efektem po stronie klienta." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Chmury w menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Kolorowa mgła" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Kolorowe cienie" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Lista oddzielonych przecinkami flag do ukrycia w repozytorium treści.\n" +"„niewolne” może służyć do ukrywania pakietów, które nie kwalifikują się jako " +"„wolne oprogramowanie”,\n" +"zgodnie z definicją Free Software Foundation.\n" +"Możesz także określić oceny treści.\n" +"Te flagi są niezależne od wersji Minetest,\n" +"więc zobacz pełną listę na https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Lista oddzielonych przecinkiem modów które mają pozwolenie na dostęp do\n" +"API HTTP, które pozwala im wysyłać i pobierać dane do/z internetu." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Lista oddzielona przecinkiem zaufanych modów które mają dostęp\n" +"do niebezpiecznych funkcji nawet gdy zabezpieczenie modów jest włączone." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Klawisz komend" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Poziom kompresji jaki ma być stosowany przy zapisie bloków mapy na dysk.\n" +"-1 - użyj domyślnego poziomu kompresji\n" +"0 - najmniejsza kompresja, najszybciej\n" +"9 - najlepsza kompresja, najwolniej" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Poziom kompresji jaki ma być użyty podczas wysyłania bloków mapy do " +"klienta.\n" +"-1 - użyj domyślnego poziomu kompresji\n" +"0 - najmniejsza kompresja, najszybciej\n" +"9 - najlepsza kompresja, najwolniej" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Połączone szkło" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Łączenie z zewnętrznym serwerem mediów" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Połącz szkło jeśli wspierane przez blok." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Przeźroczystość konsoli" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Kolor konsoli" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Wysokość konsoli" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Repozytorium Zawartości z Sieci" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Flaga czarnej listy ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Maksymalna liczba jednoczesnych pobrań ContentDB" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ContentDB URL" +msgstr "Adres URL ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Ciągle na przód" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Ciągły ruch naprzód, włączany przez klawisz automatycznego chodzenia w " +"przód.\n" +"Aby go wyłączyć wciśnij klawisz jeszcze raz, albo klawisz w tył." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Sterowanie" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Reguluje długość cyklu dzień/noc.\n" +"Przykłady:\n" +"72 = 20min, 360 = 4min, 1 = 24h, 0 = dzień/noc/wszystko pozostaje bez zmian." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Kontroluje stromość/głębokość depresji jeziora." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Kontroluje stromość/wysokość gór." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Wpływa na szerokość tuneli, mniejsza wartość tworzy szersze tunele.\n" +"Wartość >= 10,0 całkowicie wyłącza tworzenie tuneli i pozwala na uniknięcie\n" +"intensywnych obliczeń hałasu." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Wiadomość awarii" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Kreatywny" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Kanał alfa celownika" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Kanał alfa celownika (pomiędzy 0 a 255).\n" +"Wpływa również na kolor celownika obiektów." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Kolor celownika" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Kolor celownika (R, G,B).\n" +"Wpływa również na kolor celownika" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Włącz obrażenia" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Klawisz przełączania informacji debugowania" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Debug log file size threshold" +msgstr "Próg rozmiaru pliku dziennika debugowania" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Poziom logowania debugowania" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Klawisz zmniejszania głośności" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Krok serwera dedykowanego" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Domyślne przyspieszenie" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Domyślna gra" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Domyślna gra podczas tworzenia nowego świata.\n" +"To zostanie nadpisane jeżeli tworzysz świat z menu głównego." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Domyślne hasło" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Domyślne uprawnienia" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Domyślny format raportu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default stack size" +msgstr "Domyślny rozmiar stosu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Określa jakość filtrowania cieni\n" +"Symuluje to efekt miękkich cieni, stosując dysk PCF lub poisson\n" +"ale także zużywa więcej zasobów." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Określa obszary na których drzewa mają jabłka." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Określa obszary z piaszczystymi plażami." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Określa rozmieszczenie wyższego terenu i stromość klifów." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines distribution of higher terrain." +msgstr "Określa rozmieszczenie wyższych terenów." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "Określa wielkość jaskiń, mniejsze wartości tworzą większe jaskinie." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Określa strukturę kanałów rzecznych." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Określa położenie oraz teren z dodatkowymi górami i jeziorami." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines the base ground level." +msgstr "Określa podstawowy poziom podłoża." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines the depth of the river channel." +msgstr "Określa głębokość kanałów rzecznych." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Definiuje maksymalną odległość przesyłania graczy w blokach (0 = " +"nieskończoność)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines the width of the river channel." +msgstr "Określa szerokość kanałów rzecznych." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Określa szerokość doliny rzecznej." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Określa obszary drzewiaste oraz ich gęstość." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Opóźnienie między aktualizacją siatki na kliencie podawane w milisekundach.\n" +"Zwiększenie zredukuje częstość aktualizacji siatki, ograniczając w ten " +"sposób drgania (jitter) na wolniejszych klientach." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Opóźnienie w przesyłaniu bloków, kiedy gracz buduje" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Opóźnienie wyświetlania dymkmów, w milisekundach." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Wsparcie przestarzałego API Lua" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Głębokość poniżej której znajdziesz duże jaskinie." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Głębokość poniżej której znajdziesz duże jaskinie." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Opis serwera, który będzie wyświetlony gdy gracze dołączają oraz na liście " +"serwerów." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Próg szumu pustyni" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Pustynie pojawią się gdy np_biome przekroczy tą wartość.\n" +"Kiedy flaga 'snowbiomes' jest włączona, ta wartość jest ignorowana." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Odsynchronizuj animację bloków" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Dekoracje" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "Klawisz kopania" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Włącz efekty cząsteczkowe" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Wyłącz anticheat" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Nie zezwalaj na puste hasła" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Display Density Scaling Factor" +msgstr "Wyświetl współczynnik skalowania gęstości" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Serwer DNS, wyświetlany na liście serwerów." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Wciśnij dwukrotnie \"Skok\" by włączyć tryb latania" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Wciśnij dwukrotnie \"Skok\" by włączyć tryb latania." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Klawisz wyrzucenia przedmiotu" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Zrzuć informacje debugowania generatora mapy." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Maksymalna wartość Y lochu" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Minimalna wartość Y lochu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dungeon noise" +msgstr "Hałas lochu" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Włącz protokół sieciowy IPv6 (dla gry oraz dla jej serwera).\n" +"Wymagane dla połączeń z protokołem sieciowym IPv6." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Odblokuj wsparcie modyfikacji Lua.\n" +"To wsparcie jest eksperymentalne i API może ulec zmianie." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Włącz filtrowanie dysku poisson.\n" +"Jeśli włączone, to używa dysku poisson do \"miękkich cieni\". W przeciwnym " +"razie używa filtrowania PCF." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Włącza kolorowe cienie. \n" +"Na rzeczywistych półprzezroczystych węzłach rzuca kolorowe cienie. To " +"kosztowne." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Odblokuj okno konsoli" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable creative mode for all players" +msgstr "Zezwól na tryb kreatywny dla wszystkich graczy" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Włącz joystick" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Włącz wsparcie kanałów z modami." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Włącz tryb mod security" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Włącz obrażenia i umieranie graczy." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Włącz losowe wejście użytkownika (tylko dla testowania)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Włącz gładkie oświetlenie z prostym efektem ambient occlusion.\n" +"Wyłącz dla szybkości lub wyglądu." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Włącz blokadę dla połączenia starych klientów.\n" +"Starsze klienty mogą być kompatybilne w tym sensie że nie będą się " +"zawieszać\n" +"kiedy łączą sę z nowym serwerem, ale mogą nie wspierać wszystkich nowych " +"spodziewanych funkcjonalności." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Włącza używanie zdalnego serwera mediów (jeżeli dostarczany przez serwer).\n" +"Zdalny serwer oferuje znacząco szybszy sposób pobierania mediów (np. " +"tekstur)\n" +"jeżeli następuje połączenie z serwerem." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Uaktywnij \"vertex buffer objects\". \n" +"Powinno to znacznie polepszyć wydajność karty graficznej." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Włącz drganie widoku i ilość tych drgań.\n" +"Dla przykładu: 0 dla braku drgań; 1.0 dla normalnych; 2.0 dla podwójnych." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Włącza/wyłącza uruchamianie serwera IPv6.\n" +"Ignorowane jeśli ustawiony jest bind_address.\n" +"Wymaga włączenia enable_ipv6." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Umożliwia Hable's 'Uncharted 2' filmowe mapowanie tonów.\n" +"Symuluje krzywą tonalną kliszy fotograficznej i sposób, w jaki przybliża " +"ona\n" +"wygląd obrazów o wysokim zakresie dynamiki. Kontrast w średnim zakresie jest " +"lekko wzmocniony\n" +"Wzmocnienie kontrastu w średnich zakresach, stopniowa kompresja świateł i " +"cieni." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Włącz animację inwentarza przedmiotów." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Włącza cachowanie facedir obracanych meshów." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Włącz minimapę." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Włącza dźwięk.\n" +"Jeśli wyłączone, całkowicie wyłącza wszystkie dźwięki wszędzie oraz " +"sterowanie dźwiękiem \n" +"w grze nie będzie działać.\n" +"Zmiana tego ustawienia wymaga ponownego uruchomienia." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Umożliwia kompromisy, które zmniejszają obciążenie procesora lub zwiększają " +"wydajność renderowania\n" +"kosztem drobnych usterek wizualnych, które nie wpływają na grywalność gry." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Profilowanie doliny" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Interwał wyświetlania danych profilowych" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Metody bytów" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Wykładnik zwężenia pływającej wyspy. Zmienia zachowanie zwężenia.\n" +"Wartość = 1.0 tworzy jednolite, liniowe zwężenie.\n" +"Wartości > 1.0 tworzą gładkie zwężenie odpowiednie dla domyślnie " +"odseparowanych\n" +"floatlands.\n" +"Wartości < 1.0 (np. 0.25) tworzą bardziej zdefiniowany poziom powierzchni z\n" +"płaskimi nizinami, odpowiednimi dla jednolitej warstwy pływających wysp." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "FPS when unfocused or paused" +msgstr "Maksymalny FPS gdy gra spauzowana" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Współczynnik szumu" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Współczynnik spadku drgań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Fallback font path" +msgstr "Ścieżka czcionki zastępczej" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Klawisz szybkiego poruszania" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Przyspieszenie trybu szybkiego" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Prędkość trybu szybkiego" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Szybkie poruszanie" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Szybki ruch (za pomocą przycisku „specjalnego”).\n" +"Wymaga to uprawnienia „fast” na serwerze." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Pole widzenia" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Pole widzenia w stopniach." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Plik w kliencie (lista serwerów), który zawiera ulubione serwery " +"wyświetlane \n" +"w zakładce Trybu wieloosobowego." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Głębokość wypełnienia" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Szum wypełnianej głębokości" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Mapowanie Filmic tone" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Filtrowanie tekstur może wymieszać wartości RGB piksela z w pełni " +"przeźroczystymi sąsiadami,\n" +"które optymalizatory PNG najczęściej odrzucają, co czasem powoduje " +"ciemniejsze lub jaśniejsze\n" +"krawędzie w przeźroczystych teksturach. Zastosuj ten filtr aby wyczyścić " +"to \n" +"w czasie ładowania tekstur." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Antyaliasing:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Pierwsze z czterech szumów 2D, które razem wysokość gór/łańcuchów górskich." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Pierwsze z dwóch szumów 3D, które razem określają tunele." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Stałe ziarno mapy" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Ustaw wirtualny joystick" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland density" +msgstr "Gęstość latających wysp" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland maximum Y" +msgstr "Maksymalna wartość Y latających wysp" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland minimum Y" +msgstr "Minimalna wartość Y latających wysp" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland noise" +msgstr "Szum latających wysp" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland taper exponent" +msgstr "Wykładnik zbieżności latających wysp" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland tapering distance" +msgstr "Odległość zwężania latających wysp" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland water level" +msgstr "Poziom wody pływającej wyspy" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Klawisz latania" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Latanie" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Mgła" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Początek mgły" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Klawisz przełączania mgły" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Rozmiar czcionki" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font bold by default" +msgstr "Domyślnie pogrubiona czcionka" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font italic by default" +msgstr "Domyślnie kursywa czcionki" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Cień czcionki" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Przeźroczystość cienia czcionki" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Rozmiar czcionki" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size divisible by" +msgstr "Rozmiar czcionki podzielny przez" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" +"Rozmiar czcionki domyślnej czcionki, gdzie 1 jednostka = 1 piksel przy 96 DPI" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" +"Rozmiar czcionki o stałej szerokości, gdzie 1 jednostka = 1 piksel przy 96 " +"DPI" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Rozmiar czcionki tekstu ostatniej rozmowy i monitu rozmowy w punktach (pt).\n" +"Wartość 0 spowoduje użycie domyślnego rozmiaru czcionki." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"W przypadku czcionek pikselowych, które nie skalują się dobrze, zapewnia to, " +"że ich rozmiary używanych\n" +"z nią będą zawsze podzielne przez tę wartość w pikselach. Na przykład,\n" +"czcionka pikselowa o wysokości 16 pikseli powinna mieć ustawioną tą wartość " +"na 16, więc zawsze będzie tylko\n" +"rozmiar 16, 32, 48, itd., więc mod żądający rozmiaru 25 otrzyma 32." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Format wiadomości czatu graczy. Następujące ciągi są dozwolone: \n" +"@name, @message, @timestamp (opcjonalne)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Format zrzutu ekranu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec Default Background Color" +msgstr "Domyślny kolor tła formspec" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec Default Background Opacity" +msgstr "Domyślna nieprzezroczystość tła formspec" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec Full-Screen Background Color" +msgstr "Kolor formspec tła pełnoekranowego" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec Full-Screen Background Opacity" +msgstr "Pełnoekranowa nieprzezroczystość tła formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Kolor tła konsoli czatu w grze (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Kanał alfa konsoli w grze (od 0 do 255)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Kolor tła konsoli czatu w grze (R,G,B)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "Kanał alfa konsoli w grze (od 0 do 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Do przodu" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Pierwsze z czterech szumów 2D, które razem wysokość gór/łańcuchów górskich." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Typ fraktalny" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Część widocznej odległości w której mgła zaczyna się renderować" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Z jakiej odległości bloki są generowane dla klienta, w blokach mapy (16 " +"węzłów)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Z jakiej odległości bloki są przesyłane do klientów, zapisane w blokach map " +"(16 węzłów)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Maksymalna odległość z której klienci wiedzą o obiektach, podawanych w " +"blokach map (16 węzłów).\n" +"\n" +"Ustawienie wartości większej niż active_block_range spowoduje również, że " +"serwer\n" +"będzie utrzymywał aktywne obiekty do tej odległości w kierunku w\n" +"którym patrzy gracz. (Dzięki temu można uniknąć nagłego zniknięcia mobów z " +"pola widzenia)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Pełny ekran" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Tryb pełnoekranowy." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Skalowanie GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Filtr skalowania GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Filtr skalowania GUI txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Gry" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Globalne wywołania zwrotne" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Globalne właściwości generowania map.\n" +"W generatorze map v6 flaga \"decorations\" kontroluje wszystkie dekoracje z " +"wyjątkiem drzew \n" +"i trawy dżungli. we wszystkich innych generatorach flaga ta kontroluje " +"wszystkie dekoracje." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Gradient krzywej światła w maksymalnej pozycji.\n" +"Wpływa na kontrast najwyższych poziomów jasności." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Gradient krzywej światła w minimalnej pozycji.\n" +"Wpływa na kontrast najniższych poziomów jasności." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Grawitacja" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Poziom ziemi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ground noise" +msgstr "Szum ziemi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HTTP mods" +msgstr "Adres HTTP modów" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Skalowanie GUI" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Klawisz przełączania HUD" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Obsługa przestarzałych wywołań API Lua:\n" +"- brak: nie rejestruje przestarzałych wywołań\n" +"- log: naśladuje i rejestruje backtrace zdeprecjonowanego wywołania " +"(domyślnie).\n" +"- błąd: przerwij przy użyciu przestarzałego wywołania (sugerowane dla " +"twórców modów)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Spraw by profiler instruował się samoczynnie:\n" +"*instruowanie pustych funkcji.\n" +"To estymuje narzut, który instrumentacja dodaje (+1 wywołanie funkcji).\n" +"*instruowanie samplera będącego w użyciu do zaktualizowania statystyk." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Szum mieszania gorąca" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Szum gorąca" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Wysokość początkowego rozmiaru okna. Ignorowana w trybie pełnoekranowym." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Szum wysokości" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Rożnorodność wysokości" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Stromość zbocza" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Granica zbocza" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness1 noise" +msgstr "Hałas górzystości1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness2 noise" +msgstr "Hałas górzystości2" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness3 noise" +msgstr "Hałas górzystości3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness4 noise" +msgstr "Hałas górzystości4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Główna strona serwera, wyświetlana na liście serwerów." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Przyśpieszenie poziome podczas skoku lub upadku,\n" +"w blokach na sekundę do kwadratu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Poziome i pionowe przyśpieszenie w trybie szybkim,\n" +"w blokach na sekundę do kwadratu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Poziome i pionowe przyśpieszenie na ziemi lub podczas wchodzenia,\n" +"w blokach na sekundę do kwadratu." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Poprzedni klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 1 key" +msgstr "Przycisk 1 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 10 key" +msgstr "Przycisk 10 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 11 key" +msgstr "Przycisk 11 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 12 key" +msgstr "Przycisk 12 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 13 key" +msgstr "Przycisk 13 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 14 key" +msgstr "Przycisk 14 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 15 key" +msgstr "Przycisk 15 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 16 key" +msgstr "Przycisk 16 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 17 key" +msgstr "Przycisk 17 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 18 key" +msgstr "Przycisk 18 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 19 key" +msgstr "Przycisk 19 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 2 key" +msgstr "Przycisk 2 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 20 key" +msgstr "Przycisk 20 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 21 key" +msgstr "Przycisk 21 miejsca paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 22 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 23 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 24 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 25 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 26 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 27 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 28 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 29 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 3 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 30 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 31 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 32 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 4 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 5 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 6 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 7 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 8 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hotbar slot 9 key" +msgstr "Następny klawisz paska działań" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "How deep to make rivers." +msgstr "Jak głębokie tworzyć rzeki." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Jak szybko fale cieczy będą się poruszać. Wyższa = szybciej.\n" +"Wartość ujemna, fale cieczy będą poruszać się do tyłu.\n" +"Wymaga włączenia falowania cieczy." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Jak długo serwer będzie czekać do zwolnienia nieużywanych bloków mapy.\n" +"Wyższa wartość jest łagodniejsza ale używa więcej pamięci RAM." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Zmniejsz wartość, aby zwiększyć opór ruchu w cieczy." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "How wide to make rivers." +msgstr "Jak szerokie są rzeki." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Szum wilgotności" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Szum wilgotności" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Różnice w wilgotności biomów." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "Serwer IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Jeżeli FPS będzie wyższy niż to, ogranicz go przez usypianie\n" +"nie marnuj mocy CPU bez znaczących korzyści." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Jeśli wyłączone to klawisz \"Aux1\" jest wykorzystany aby latać szybko jeśli " +"tryb szybkiego poruszania oraz latania jest\n" +"włączony." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Jeśli opcja jest włączona to serwer spowoduje zamknięcie usuwania bloków " +"mapy na podstawie \n" +"pozycji gracza. Zredukuje to o 50-80% liczbę bloków \n" +"wysyłanych na serwer. Klient już nie będzie widział większości ukrytych " +"bloków, \n" +"tak więc zostanie ograniczona przydatność trybu noclip." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Jeżeli włączone razem z trybem latania, gracz może latać przez solidne " +"bloki.\n" +"Wymaga przywileju \"noclip\" na serwerze." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Jeżeli włączone, klawisz \"użycia\" zamiast klawisza \"skradania\" będzie " +"użyty do schodzenia w dół i \n" +"opadania." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Włącz potwierdzanie rejestracji podczas łączenia się z serwerem.\n" +"Jeśli wyłączone, to nowe konto zostanie zarejestrowane automatycznie." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Jeżeli włączone, akcje są nagrywane dla odtwarzania.\n" +"Ta opcja jest czytana tylko podczas startu serwera." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Jeśli włączone, wyłącza ograniczenie oszustw w trybie multiplayer." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Jeżeli włączone, nieprawidłowe dane świata nie będą powodować wyłączenia " +"serwera.\n" +"Włącz tylko jeżeli wiesz co robisz." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Jeśli włączona razem z trybem latania, powoduje, że kierunek poruszania jest " +"zależy do nachylenia gracza." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "Jeśli włączone, nowi gracze nie mogą dołączyć do gry z pustym hasłem." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Jeżeli włączone, możesz położyć bloki w pozycji gdzie stoisz.\n" +"Pomocne gdy pracujesz na małych powierzchniach." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Jeśli ograniczenie CSM dla zasięgu węzła jest włączone, wywołania get_node " +"są ograniczone\n" +"do tej odległości od gracza do węzła." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Jeśli wykonanie polecenia czatu trwa dłużej niż określony czas w sekundach, " +"dodaj informację o czasie do komunikatu polecenia czatu w\n" +"sekundach" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Jeśli rozmiar pliku debug.txt przekroczy liczbę megabajtów określoną w tym " +"ustawieniu, plik zostanie przeniesiony do pliku debug.txt.1.\n" +"w tym ustawieniu, plik jest przenoszony do debug.txt.1,\n" +"usuwając starszy debug.txt.1, jeśli taki istnieje.\n" +"debug.txt jest przenoszony tylko wtedy, gdy wartość tego ustawienia jest " +"dodatnia." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "Jeśli ustawione, gracze zawsze będą się pojawiać w zadanej pozycji." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ignoruj błędy świata" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "Kanał alfa konsoli w grze (od 0 do 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Kolor tła konsoli czatu w grze (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "Przeźroczystość konsoli w grze (od 0.0 do 1.0)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Klawisz zwiększania głośności" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" +"Początkowa prędkość pionowa podczas skoku, w blokach na sekundę do kwadratu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Instrument wbudowany.\n" +"Najczęściej potrzebny tylko dla osób pracujących nad jądrem" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Instrument chat commands on registration." +msgstr "Instrument poleceń czatu przy rejestracji." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Poinstruuj globalne funkcje zwrotne przy rejestracji \n" +"(wszystko co prześlesz do funkcji minetest.register_*() )" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Poinstruuj działanie funkcji aktywnych modyfikatorów bloków przy rejestracji." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Poinstruuj działanie funkcji ładowania modyfikatorów bloków przy rejestracji." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Poinstruuj metody jednostkowe przy rejestracji." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "Interwał zapisywania ważnych zmian w świecie, w sekundach." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Interwał wysyłania czasu gry do klientów." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animacje przedmiotów w ekwipunku" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Ekwipunek" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Odwróć mysz" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Odwróć pionowy ruch myszy." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Italic font path" +msgstr "Ścieżka czcionki typu Monospace" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Italic monospace font path" +msgstr "Ścieżka czcionki typu Monospace" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "TTL przedmiotu" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Iteracje" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Iteracje funkcji rekursywnej.\n" +"Zwiększenie tej wartości zwiększa ilość drobnych szczegółów, ale również\n" +"zwiększa obciążenie przetwarzania.\n" +"Przy iteracjach = 20 ten mapgen ma podobne obciążenie jak mapgen V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "Identyfikator Joystick-a" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Interwał powtarzania przycisku joysticka" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick dead zone" +msgstr "Typ Joysticka" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Czułość drgania joysticka" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick type" +msgstr "Typ Joysticka" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Wyłącznie dla Zbioru Julii: \n" +"komponent W stałej hiperzespolonej, \n" +"która determinuje fraktali.\n" +"Nie ma wpływu na fraktale trójwymiarowe.\n" +"Zakres to w przybliżeniu -2 do 2." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Wyłącznie dla Zbioru Julii: \n" +"komponent X stałej hiperzespolonej, \n" +"która determinuje kształt fraktali.\n" +"Zakres to w przybliżeniu -2 do 2." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Wyłącznie dla Zbioru Julii: komponent Y stałej hiperzespolonej, \n" +"która determinuje kształt fraktali.\n" +"Zakres to w przybliżeniu -2 do 2." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Wyłącznie dla Zbioru Julii: \n" +"komponent Z stałej hiperzespolonej, \n" +"która determinuje kształt fraktali.\n" +"Zakres to w przybliżeniu -2 do 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Skok" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Szybkość skoku" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz zmniejszania zasięgu widzenia.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz zmniejszania głośności.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz skakania.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyrzucenia aktualnie wybranego przedmiotu.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz zwiększania zasięgu widzenia.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz zwiększania głośności.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz skakania.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz szybkiego poruszania się w trybie \"fast\"\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz poruszania się wstecz.\n" +"Gdy jest aktywny to wyłącza również automatyczne chodzenie do przodu.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz poruszania się na przód,\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz poruszania się w lewo.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz poruszania się w prawo.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyciszania gry.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz otwierania okna czatu aby wpisać komendę.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz otwierania okna czatu aby wpisać komendę.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz otwierania okna czatu.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz otwierania inwentarza.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz skakania.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru poprzedniej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru poprzedniej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyboru następnej pozycji na pasku akcji.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz skradania.\n" +"Także używany do schodzenia w dół i opadania w wodzie jeżeli aux1_descends " +"jest wyłączone.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania pomiedzy kamerą z pierwszej i trzeciej osoby.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz do zrobienia zrzutu ekranu.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania trybu szybkiego.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania trybu cinematic.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania wyświetlania minimapy.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania trybu szybkiego.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania latania.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania trybu noclip.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania trybu noclip.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania aktualizacji kamery. Przydatne tylko dla deweloperów.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania wyświetlania czatu.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania informacji debugowania.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania wyświetlania mgły\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania wyświetlania HUD.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania wyświetlania czatu.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania wyświetlania profilera. Przydatne dla deweloperów.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz przełączania nieograniczonego pola widzenia.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Klawisz wyświetlania zoom kiedy to możliwe.\n" +"Zobacz http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" +"Wyrzuca graczy, którzy wysłali więcej niż X wiadomości w ciągu 10 sekund." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Stromość jeziora" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Granica jeziora" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Język" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Głębia dużej jaskini" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Large cave maximum number" +msgstr "Maksymalna liczba dużych jaskiń" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Large cave minimum number" +msgstr "Minimalna liczba dużych jaskiń" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Large cave proportion flooded" +msgstr "Duża część jaskini zalana" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Klawisz wielkiej konsoli" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Styl liści" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Style liści:\n" +"- Fancy: wszystkie ściany widoczne\n" +"- Simple: tylko zewnętrzene ściany, jeżeli special_tiles jest użyty\n" +"- Opaque: wyłącza przeźroczystość" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "W lewo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Długość interwału czasowego serwera w trakcie którego obiekty są ogólnie " +"aktualizowane \n" +"przez sieć." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Ustawienie wartości pozytywnej włącza drganie liści.\n" +"Do włączenia wymagane są shadery." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Długość czasu pomiędzy wykonywanymi cyklami ABM" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Długość czasu pomiędzy wykonywanymi cyklami NodeTimer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Czas pomiędzy cyklami zarządzania aktywnymi blokami" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Poziom logowania zapisywany do pliku debug.txt:\n" +"- <nic> (brak logowania)\n" +"- none (logi bez poziomu)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Light curve boost" +msgstr "Przyśpieszenie środkowe krzywej światła" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Centrum środkowego przyśpieszenia krzywej światła" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Light curve boost spread" +msgstr "Rozrzut przyśpieszenia środkowego krzywej światła" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Light curve gamma" +msgstr "Przyśpieszenie środkowe krzywej światła" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Light curve high gradient" +msgstr "Przyśpieszenie środkowe krzywej światła" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Centrum środkowego przyśpieszenia krzywej światła" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Płynne oświetlenie" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Limit wielkości generowanej mapy, w 6 kierunkach od (0, 0, 0). \n" +"Tylko fragmenty mapy są w tym limicie generowane. \n" +"Wartość jest zapisywana dla każdego świata z osobna." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Liczba limitu współbieżnych zapytań HTTP. Dotyczy:\n" +"- Pobierania mediów jeżeli serwer używa opcji remote_media.\n" +"- Pobierania listy serwerów oraz rozgłoszeń serwera.\n" +"- Pobierań wykonywanych w menu głównym (np. mod manager).\n" +"Działa tylko jeżeli skompilowany z cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Płynność cieczy" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Wygładzanie płynności cieczy" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Maksymalna pętla cieczy" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Czas kolejki czyszczenia cieczy" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Liquid sinking" +msgstr "Zanurzanie w cieczy" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Interwał aktualizacji cieczy podany w sekundach." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Interwał czasowy aktualizacji cieczy" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Wczytaj profiler gry" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Załaduj profiler gry aby zebrać dane. \n" +"Dostępu do skompilowanego profilu dostarcza polecenie /profiler.\n" +" Przydatne dla twórców modów i operatorów serwerów." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Loading Block Modifiers" +msgstr "Interwał modyfikatora aktywnego bloku" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Zmniejsz limit Y dla lochów." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lower Y limit of floatlands." +msgstr "Zmniejsz limit Y dla lochów." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Skrypt głównego menu" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Ustawia mgłę i kolor nieba zależny od pory dnia (świt/zachód słońca) oraz " +"kierunku patrzenia." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Zmienia ciecze w nieprzeźroczyste" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map Compression Level for Disk Storage" +msgstr "Poziom kompresji mapy dla pamięci masowej dysku" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map Compression Level for Network Transfer" +msgstr "Poziom kompresji map dla transferu sieciowego" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Katalog map" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Właściwości generowania mapy określające Mapgen Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Specyficzne cechy dla Mapgen płaskiego terenu.\n" +"Do płaskiego świata mogą być dodane przypadkowe jeziora i wzgórza." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Właściwości generowania mapy określające Mapgen v7.\n" +"\"grzbiety\" aktywują tworzenie niefraktalnego terenu:\n" +"oceanu, wysp oraz podziemi." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Atrybuty generowania mapy specyficzne dla dolin Mapgen.\n" +"'altitude_chill': Zmniejsza ciepło wraz z wysokością nad poziomem morza.\n" +"'humid_rivers': Zwiększa wilgotność wokół rzek.\n" +"'vary_river_depth': Jeżeli włączone, niska wilgotność i wysoka temperatura " +"powoduje, że rzeki\n" +"stają się płytsze i czasami wysychają.\n" +"'altitude_dry': Zmniejsza wilgotność wraz z wysokością." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Właściwości generowania mapy określające Mapgen v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Atrybuty generowania map specyficzne dla Generatora map v6.\n" +"Flaga „biomów śnieżnych” włącza nowy system 5 biomów.\n" +"Gdy flaga „biomy śnieżne” jest włączona, dżungle są automatycznie włączane " +"i\n" +"flaga „dżungli” jest ignorowana." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Atrybuty generowania map specyficzne dla Generatora map v7.\n" +"'grzbiety”: rzeki.\n" +"'latające wyspy': unoszące się w atmosferze masy lądowe.\n" +"'jaskinie': Gigantyczne jaskinie głęboko pod ziemią." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Limit generacji mapy" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Interwał zapisu mapy" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map shadows update frames" +msgstr "Interwał czasowy aktualizacji cieczy" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Limit bloków mapy" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Opóźnienie generacji siatki bloków Mapblock" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Wielkość pamięci podręcznej generatora siatki bloków Mapblock w MB" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Przekroczenie czasu wyładowania bloków mapy" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian" +msgstr "Generator mapy fractal" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian specific flags" +msgstr "Specyficzne flagi dla generatora Mapgen flat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat" +msgstr "Generator mapy flat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat specific flags" +msgstr "Specyficzne flagi dla generatora Mapgen flat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal" +msgstr "Generator mapy fractal" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "Specyficzne flagi dla generatora Mapgen flat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5" +msgstr "Generator mapy v5" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5 specific flags" +msgstr "Generator mapy flat flagi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6" +msgstr "Generator mapy v6" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6 specific flags" +msgstr "Generator mapy flat flagi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7" +msgstr "Generator mapy v7" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7 specific flags" +msgstr "Specyficzne flagi Mapgen v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Generator mapy Valleys" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Valleys specific flags" +msgstr "Specyficzne flagi dla generatora Mapgen flat" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Generator mapy debugowanie" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Nazwa generatora mapy" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Maksymalna odległość generowania bloków" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Maksymalna odległość wysyłania bloków" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Maksymalne przetwarzane podczas chodzenia." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Maksymalna wartość usuwania dodatkowych bloków" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Max. pakietów na iterację" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Maksymalny FPS" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "Maksymalny FPS gdy gra spauzowana." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum distance to render shadows." +msgstr "Maksymalna odległość do renderowania cieni." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Maksymalna ilość bloków załadowanych w sposób wymuszony" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum hotbar width" +msgstr "Maksymalna długość hotbar" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "Maksymalny limit losowej liczby dużych jaskiń na mapchunk." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "Maksymalny limit losowej liczby małych jaskiń na mapchunk." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Maksymalny opór cieczy. Wpływa na spowolnienie przy wejściu w ciecz \n" +"z dużą prędkością." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Maksymalna ilość bloków, które są jednocześnie wysyłane na jednego klienta.\n" +"Maksymalna łączna liczba jest obliczana dynamicznie:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" +"Maksymalna liczba bloków, które mogą być skolejkowane podczas wczytywania." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Maksymalna liczba bloków do skolejkowania, które mają być wygenerowane.\n" +"Pozostaw puste a odpowiednia liczba zostanie dobrana automatycznie." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Maksymalna liczba bloków do skolejkowania które mają być wczytane z pliku.\n" +"Pozostaw puste a odpowiednia liczba zostanie dobrana automatycznie." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Maksymalna liczba jednocześnie pobieranych plików. Pobieranie przekraczające " +"ten limit zostanie umieszczone w kolejce.\n" +"Powinien być niższy niż curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Maksymalna ilość, wczytanych wymuszeniem, bloków mapy." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Maksymalna liczba bloków mapy, które mają być trzymane w pamięci klienta.\n" +"Ustaw -1 dla nieskończonej liczby." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Maksymalna liczba pakietów wysyłanych na krok wysyłania, jeśli masz wolne " +"połączenie\n" +"spróbuj go zmniejszyć, ale nie zmniejszaj go do liczby poniżej podwójnej " +"liczby docelowej\n" +"numer klienta." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Maksymalna liczba graczy, która może się jednocześnie połączyć." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Maksymalna liczba ostatnich wiadomości czatu do wyświetlenia" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Maksymalna liczba statycznie przechowywanych obiektów w bloku." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Maksymalna liczba obiektów na blok" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Maksymalna proporcja obecnego okna paska akcji.\n" +"Przydatne jeśli coś ma być wyświetlane po lewej lub prawej tego paska." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Maksymalny jednoczesny blok wysłany, na każdego klienta" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Maksymalny rozmiar kolejki wiadomości czatu" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Maksymalny rozmiar kolejki wiadomości czatu\n" +"Wartość 0, wyłącza kolejkę, -1 to nieograniczony rozmiar kolejki." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "Maksymalny czas na pobranie pliku (np.: moda) w ms." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Maksymalny czas, jaki może zająć interaktywne żądanie (np. pobranie listy z " +"serwera), podany w milisekundach." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Maksymalna ilość użytkowników" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Pamięć podręczna siatki" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Wiadomość dnia" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Wiadomość dnia wyświetlona dla graczy łączących się z serwerem." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Metoda użyta do podświetlenia wybranego obiektu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimal level of logging to be written to chat." +msgstr "Minimalny poziom logowania, który ma być zapisywany na czacie." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Przycisk Minimapy" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Wysokość skanowania minimapy" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Szum 3D, który wpływa na liczbę lochów na jeden mapchunk." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Minimalny limit losowej liczby małych jaskiń na mapchunk." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimum texture size" +msgstr "Minimalna wielkość tekstury dla filtrów" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mip-Mappowanie" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Profiler" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Bezpieczeństwo" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Kanały modów" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Modifies the size of the HUD elements." +msgstr "Modyfikuje rozmiar elementów paska HUD." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Ścieżka czcionki typu Monospace" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Rozmiar czcionki Monospace" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "Rozmiar czcionki Monospace" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Szum wysokości góry" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Szum góry" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mountain variation noise" +msgstr "Szum wysokości góry" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mountain zero level" +msgstr "Szum góry" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Czułość myszy" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Mnożnik czułości myszy." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Szum błota" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Mnożnik dla drgań upadku.\n" +"Przykład: 0 dla braku drgań widoku; 1.0 dla normalnych; 2.0 dla podwójnych." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Klawisz wyciszenia" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Wycisz dźwięk" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Nazwa generatora map, który ma być użyty podczas tworzenia nowego świata.\n" +"Tworzenie świata w menu głównym nadpisze tę wartość.\n" +"Obecne mapgeny są w bardzo niestabilnym stanie:\n" +"- Opcjonalne floatlands z v7 (domyślnie wyłączone)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Nazwa gracza.\n" +"Gdy serwer działa, klienci połączeni z tą nazwą są adminami.\n" +"Gdy zaczynasz z menu głównego, to ustawienie jest nadpisywane." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Nazwa serwera, wyświetlana gdy gracze dołączają oraz na liście serwerów." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Near plane" +msgstr "Najbliższy wymiar" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Port sieciowy do nasłuchu (UDP).\n" +"Ta wartość będzie nadpisana gdy zaczynasz z menu głównego." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Sieć" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Nowi użytkownicy muszą wpisać to hasło." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Tryb noclip" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Klawisz trybu noclip" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Podświetlanie bloków" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Podświetlanie bloków" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Interwał NodeTimer" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Szumy" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Liczba powstających wątków" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Ilość wątków emerge do wykorzystania.\n" +"Wartość 0:\n" +"- Wybór automatyczny. Liczba wątków emerge będzie wynosić\n" +"- 'liczba procesorów - 2', z dolną granicą 1.\n" +"Dowolna inna wartość:\n" +"- Określa liczbę wątków emerge, z dolnym limitem równym 1.\n" +"OSTRZEŻENIE: Zwiększenie liczby wątków emerge zwiększa szybkość mapgena " +"silnika,\n" +"ale może to wpłynąć na wydajność gry przez zakłócanie innych\n" +"procesami, szczególnie w grze dla pojedynczego gracza i/lub podczas " +"uruchamiania kodu Lua w\n" +"'on_generated'. Dla wielu użytkowników optymalnym ustawieniem może być '1'." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Ilość dodatkowych bloków, które mogą zostać wczytane naraz przez /" +"clearobjects.\n" +"Jest to kompromis między obciążeniem transakcji SQLite a\n" +"konsumpcją pamięci (4096=100MB, praktyczna zasada)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Nieprzeźroczyste ciecze" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" +"Nieprzezroczystość (alfa) cienia za domyślną czcionką, w zakresie od 0 do " +"255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Otwórz menu pauzy, gdy okno jest nieaktywne. Nie zatrzymuje gry jeśli " +"formspec jest\n" +"otwarty." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Optional override for chat weblink color." +msgstr "Opcjonalna zmiana koloru łącza internetowego czatu." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Ścieżka czcionki zastępczej. Musi być czcionką TrueType.\n" +"Ta czcionka będzie używana w niektórych językach lub jeśli domyślna czcionka " +"jest niedostępna." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Ścieżka w której zapisywane są zrzuty ekranu. Może być bezwzględna lub " +"względna.\n" +"Folder zostanie utworzony, jeśli jeszcze nie istnieje." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Ścieżka do shaderów. Jeśli nie jest określona, zostanie wybrana domyślna " +"lokalizacja." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" +"Ścieżka do folderu z teksturami. Wszystkie tekstury są początkowo " +"wyszukiwane z tej lokalizacji." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Ścieżka do domyślnej czcionki. Musi być czcionką TrueType.\n" +"Czcionka rezerwowa zostanie użyta, jeśli nie można załadować czcionki." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Ścieżka do czcionki o stałej szerokości. Musi być czcionką TrueType.\n" +"Ta czcionka jest używana np. w ekranie konsoli i profilera." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Pauza, gdy okno jest nieaktywne" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Per-player limit of queued blocks load from disk" +msgstr "Limit załadowanych bloków z dysku na jednego gracza" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Per-player limit of queued blocks to generate" +msgstr "Limit kolejek oczekujących do wytworzenia" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fizyka" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move key" +msgstr "Klawisz latania" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move mode" +msgstr "Tryb nachylenia ruchu włączony" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Klawisz latania" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place repetition interval" +msgstr "Interwał powtórzenia prawego kliknięcia myszy" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Gracz ma możliwość latania bez wpływu grawitacji.\n" +"Wymaga to przywileju \"fly\" na serwerze." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Odległość przesyłania graczy" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Player versus player" +msgstr "PvP" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Filtrowanie dwuliniowe" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Port do połączeń (UDP).\n" +"Pole portu w menu głównym nadpisuje te ustawienie." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Zapobiegaj powtarzaniu kopania i stawiania bloków podczas przytrzymania " +"przycisków myszy.\n" +"Włącz to jeśli zbyt często kopiesz lub stawiasz obiekty przez przypadek." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Zapobiega wykonywaniu przez mody niezabezpieczonych operacji takich jak " +"wywoływanie komend powłoki." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Drukuj dane profilu silnika w regularnych interwałach (w sekundach).\n" +"0 = wyłączone. Przydatne dla deweloperów." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Przywileje, które gracze z basic_privs mogą przyznać" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Profiler" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Klawisza przełączania profilera" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Prometheus listener address" +msgstr "Adres słuchacza Prometheusa" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Adres listenera Prometheus.\n" +"Jeśli Minetest jest skompilowany z włączoną opcją ENABLE_PROMETHEUS,\n" +"włącz słuchanie metryk dla Prometheusa na tym adresie.\n" +"Metryki mogą być pobierane na stronie http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Proportion of large caves that contain liquid." +msgstr "Proporcja dużych jaskiń, które zawierają ciecz." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Radian obszaru chmury w ilości 64 bloków chmury.\n" +"Wartości większe niż 26 skutkują ostrym odcięciem w rogach chmur." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Podwyższa teren by stworzyć doliny wokół rzek." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Losowe wejście" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Zasięg widzenia" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Najnowsze wiadomości czatu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Regular font path" +msgstr "Ścieżka raportu" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Zdalne media" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Port zdalny" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Usuń oznaczenie kolorami przychodzących wiadomości\n" +"użyj tego, aby gracze nie mogli kolorować swoich wiadomości" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Zamienia domyślne menu główne na niestandardowe." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Ścieżka raportu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Ogranicza dostęp do pewnych funkcji po stronie klienta na serwerach.\n" +"Połącz poniższe flagi bajtów, aby ograniczyć funkcje po stronie klienta, lub " +"ustaw na 0\n" +"bez ograniczeń:\n" +"LOAD_CLIENT_MODS: 1 (wyłączenie ładowania modów dostarczonych przez " +"klienta)\n" +"CHAT_MESSAGES: 2 (wyłączenie wywoływania send_chat_message po stronie " +"klienta)\n" +"READ_ITEMDEFS: 4 (wyłączenie wywoływania get_item_def po stronie klienta)\n" +"READ_NODEDEFS: 8 (wyłączenie wywoływania get_node_def po stronie klienta)\n" +"LOOKUP_NODES_LIMIT: 16 (ogranicza wywoływanie get_node po stronie klienta " +"do\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (wyłącza wywoływanie get_player_names po stronie klienta)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ridge mountain spread noise" +msgstr "Szum podwodnej grani" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Szum grani" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Szum podwodnej grani" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ridged mountain size noise" +msgstr "Szum podwodnej grani" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "W prawo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River channel depth" +msgstr "Głębokość rzeki" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River channel width" +msgstr "Głębokość rzeki" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River depth" +msgstr "Głębokość rzeki" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River noise" +msgstr "Szum rzeki" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River size" +msgstr "Rozmiar rzeki" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River valley width" +msgstr "Głębokość rzeki" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Zapisywanie działań gracza" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Szum rozmiaru zaokrąglonych gór" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Rolling hills spread noise" +msgstr "Szum rozrzutu zaokrąglonych gór" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Okrągła minimapa" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Bezpieczne kopanie i stawianie" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" +"Piaszczyste pustynie pojawiają się, gdy np_beach przekroczy tą wartość." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Zapisz na dysku mapę odebraną przez klienta." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Automatycznie zapisuj okno, gdy zostało zmodyfikowane." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Zapisz mapę otrzymaną z serwera" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Skaluj GUI według wartości określonej przez użytkownika.\n" +"Użyj najbliższego filtru anti-alias aby skalować GUI.\n" +"Spowoduje to wygładzenie niektórych szorstkich krawędzi i wygładzenie\n" +"pikseli przy zmniejszaniu, kosztem rozmycia niektórych\n" +"piksele krawędzi, gdy obrazy są skalowane o rozmiary niecałkowite." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Ekran:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Wysokość ekranu" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Szerokość ekranu" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Folder zrzutu ekranu" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Format zrzutu ekranu" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Jakość zrzutu ekranu" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Jakość zrzutów ekranu. Używane tylko w formacie JPEG.\n" +"1 oznacza najgorszą jakość; 100 najlepszą.\n" +"0 to domyślna jakość." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Zrzut ekranu" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Szum dna morza" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Drugi z czterech szumów 2D które razem określają wysokość gór/łańcuchów " +"górskich." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Drugi z dwóch szumów 3D które razem określają tunele." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Sprawdź http://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Kolor zaznaczenia granicznego (RGB)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Kolor zaznaczenia" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Długość zaznaczenia" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Wybór 18 fraktali z 9 formuł.\n" +"1 = 4D \"Roundy\" zbiór Mandelbrota .\n" +"2 = 4D \"Roundy\" zbiór Julii.\n" +"3 = 4D \"Squarry\" zbiór Mandelbrota.\n" +"4 = 4D \"Squarry\" zbiór Julii.\n" +"5 = 4D \"Mandy Cousin\" zbiór Mandelbrota.\n" +"6 = 4D \"Mandy Cousin\" zbiór Julii.\n" +"7 = 4D \"Variation\" zbiór Mandelbrota.\n" +"8 = 4D \"Variation\" zbiór Julii.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" zbiór Mandelbrota.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" zbiór Julii.\n" +"11 = 3D \"Christmas Tree\" zbiór Mandelbrota.\n" +"12 = 3D \"Christmas Tree\" zbiór Julii.\n" +"13 = 3D \"Mandelbulb\" zbiór Mandelbrota.\n" +"14 = 3D \"Mandelbulb\" zbiór Julii.\n" +"15 = 3D \"Cosine Mandelbulb\" zbiór Mandelbrota.\n" +"16 = 3D \"Cosine Mandelbulb\" zbiór Julii.\n" +"17 = 4D \"Mandelbulb\" zbiór Mandelbrota.\n" +"18 = 4D \"Mandelbulb\" zbiór Julii." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Adres URL serwera" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Nazwa serwera" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Opis serwera" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "Adres URL serwera" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Adres serwera" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Opis serwera" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Nazwa serwera" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Port Serwera" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Occulusion culling po stronie serwera" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Port Serwera" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "Lista publicznych serwerów" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "Lista publicznych serwerów" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Plik listy publicznych serwerów" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Ustaw język. Zostaw puste pole, aby użyć języka systemowego.\n" +"Wymagany restart po zmianie ustawienia." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Ustaw maksymalny ciąg znaków wiadomości czatu wysyłanych przez klientów." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Ustaw siłę cienia.\n" +"Niższa wartość oznacza jaśniejsze cienie, wyższa wartość oznacza ciemniejsze " +"cienie." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Ustaw rozmiar zasięgu gładkiego cienia.\n" +"Niższe wartości oznaczają ostrzejsze cienie, wyższe wartości oznaczają " +"gładsze cienie.\n" +"Minimalna wartość: 1.0; maksymalna wartość: 10.0" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Ustaw nachylenie orbity Słońca/Księżyca w stopniach.\n" +"Wartość 0 oznacza brak nachylenia / orbitę pionową.\n" +"Wartość minimalna: 0.0; wartość maksymalna: 60.0" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Ustawienie wartości pozytywnej włącza drganie liści.\n" +"Do włączenia wymagane są shadery." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Ustawienie wartości pozytywnej włącza drganie liści.\n" +"Do włączenia wymagane są shadery." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Ustawienie wartości pozytywnej włącza falowanie wody.\n" +"Wymaga shaderów." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Ustawienie pozytywnej wartości włącza falowanie roślin.\n" +"Wymaga shaderów." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Ustawia jakość tekstury cienia na 32 bity.\n" +"Jeśli wartość jest fałszywa, używana będzie tekstura 16-bitowa.\n" +"Może to powodować znacznie więcej artefaktów w cieniu." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Shadery" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Shadery pozwalają na zaawansowane efekty wizualne, mogą również zwiększyć " +"wydajność niektórych kart\n" +"graficznych.\n" +"Działa tylko z zapleczem wideo OpenGL ." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "Jakość zrzutu ekranu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map max distance in nodes to render shadows" +msgstr "Maksymalna odległość mapy cieni w węzłach do renderowania cieni" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map texture in 32 bits" +msgstr "Tekstura mapy cieni w 32 bitach" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map texture size" +msgstr "Minimalna wielkość tekstury dla filtrów" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "Offset cienia czcionki, jeżeli 0 to cień nie będzie rysowany." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "Siła cienia" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Kształt mini mapy. Włączony = okrągła, wyłączony = kwadratowa." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Pokaż informacje debugowania" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Pokazuj zaznaczenie wybranych obiektów" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Ustaw język. Zostaw puste pole, aby użyć języka systemowego.\n" +"Wymagany restart po zmianie ustawienia." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Show name tag backgrounds by default" +msgstr "Domyślnie wyświetlaj tła znaczników imiennych" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Komunikat zamknięcia serwera" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Rozmiar mapchunków generowanych przez mapgen, podany w mapblockach (16 " +"węzłów).\n" +"UWAGA!: Nie ma z tego żadnego pożytku, ale występuje kilka zagrożeń, przy\n" +"zwiększaniu tej wartości powyżej 5.\n" +"Zmniejszenie tej wartości podnosi gęstość jaskiń i lochów.\n" +"Zmiana tej wartości ma specjalne zastosowanie, zalecane jest pozostawienie\n" +"jej nietkniętą." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Rozmiar pamięci bloków mapy generatora siatki. Zwiększenie\n" +"zmieni rozmiar % pamięci, ograniczając dane kopiowane z głównego wątku\n" +"oraz ilość drgań." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sky Body Orbit Tilt" +msgstr "Pochylenie orbity ciała niebieskiego" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Kawałek w" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Slope and fill work together to modify the heights." +msgstr "Zbocze oraz wypełnienie działają razem, aby zmodyfikować wysokości." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Small cave maximum number" +msgstr "Maksymalna ilość małych jaskiń" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Small cave minimum number" +msgstr "Minimalna ilość małych jaskiń" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "Zmienność małej skali wilgotności mieszania biomów granicznych." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "Zmienność małej skali temperatury mieszanych biomów granicznych." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Płynne oświetlenie" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Wygładza widok kamery, przy rozglądaniu się. Jest to również wygładzanie " +"widoku lub ruchu myszki.\n" +"Przydatne przy nagrywaniu filmików." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"Wygładza obracanie widoku kamery w trybie kinowym. Wartość 0 wyłącza tą " +"funkcję." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Wygładza obracanie widoku kamery. Wartość 0 wyłącza tą funkcję." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Skradanie" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Szybkość skradania" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed, in nodes per second." +msgstr "Prędkość skradania, w blokach na sekundę." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Przeźroczystość cienia czcionki" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Dźwięk" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Określa adres URL z którego klient pobiera media, zamiast używania UDP.\n" +"$filename powinno być dostępne z $remote_media$filename przez cURL\n" +"(oczywiście, komenda remote_media powinna kończyć się slashem ).\n" +"Pliki nieaktualne będą pobierane standardową metodą." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Określa domyślny rozmiar stosu węzłów, elementów i narzędzi.\n" +"Pamiętaj, że mody lub gry mogą jawnie ustawiać stos dla niektórych (lub " +"wszystkich) przedmiotów." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Rozszerz pełną aktualizację mapy cieni na określoną ilość klatek.\n" +"Wyższe wartości mogą sprawić, że cienie będą lagować,\n" +"niższe wartości powodują zużycie większej ilości zasobów.\n" +"Minimalna wartość: 1; maksymalna wartość: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Rozrzut przyśpieszenia środkowego krzywej światła.\n" +"Steruje szerokością zakresu, który ma być wzmocniony.\n" +"Standardowe zniekształcenie gaussowego przyśpieszenia środkowego." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Statyczny punkt spawnu" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Szum stromości" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Step mountain size noise" +msgstr "Szum góry" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Step mountain spread noise" +msgstr "Szum góry" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Strength of 3D mode parallax." +msgstr "Siła paralaksy." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Siła podbicia krzywej świetlnej.\n" +"3 parametry 'boost' definiują zakres krzywej świetlnej\n" +"który jest wzmacniany pod względem jasności." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Sztywne sprawdzanie protokołu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Strip color codes" +msgstr "Usuń kody kolorów" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Poziom powierzchni opcjonalnej wody umieszczonej na stałej warstwie terenu " +"pływającego.\n" +"Woda domyślnie jest wyłączona i zostanie umieszczona tylko wtedy, gdy " +"wartość ta jest ustawiona\n" +"powyżej 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (początek\n" +"górnego zwężenia).\n" +"***OSTRZEŻENIE, POTENCJALNE ZAGROŻENIE DLA ŚWIATÓW I WYDAJNOŚCI " +"SERWERÓW***:\n" +"Przy włączonym umieszczaniu wody, tereny pływające muszą być ustawione i " +"przetestowane\n" +"oraz być warstwą stałą poprzez ustawienie 'mgv7_floatland_density' na 2.0 " +"(lub innej\n" +"wymaganej wartości w zależności od 'mgv7_np_floatland'), \n" +"aby uniknąć intensywnego przepływu wody na serwerze oraz ogromnego zalania\n" +"powierzchni świata poniżej." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "Synchroniczny SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Zmienność temperatury biomów." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Ustawienia" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain alternative noise" +msgstr "Szum wysokości terenu" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Szum podłoża" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Wysokość terenu" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Szum podwyższanego terenu" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Szum terenu" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Próg szumu terenu górskiego.\n" +"Steruje proporcjami pokrycia świata górami.\n" +"Ustaw około 0.0 aby zwiększyć proporcję." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Próg szumu jezior.\n" +"Steruje proporcjami pokryciem terenu jeziorami.\n" +"Ustaw około 0.0, aby zwiększyć proporcje." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Stały szum terenu" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Paczki tekstur" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Rozmiar tekstury, na której ma być renderowana mapa cieni.\n" +"Wartość musi być potęgą dwójki.\n" +"Większe liczby tworzą lepsze cienie, ale jest to również kosztowniejsze." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Tekstury na węźle mogą być dopasowane albo do niego albo do świata.\n" +"Ten pierwszy tryb bardziej pasuje do rzeczy takich jak maszyny, meble, itp.\n" +"ten drugi sprawia, że schody i mikrobloki lepiej komponują się z " +"otoczeniem.\n" +"Z uwagi na to, że ta możliwość jest nowa, nie może być wykorzystywana przez " +"starsze serwery,\n" +"opcja ta pozwala na wymuszenie jej dla określonych typów węzłów. Zwróć " +"uwagę, że\n" +"to opcja EKSPERYMENTALNA i może nie działać zbyt poprawnie." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The URL for the content repository" +msgstr "Adres URL repozytorium zawartości" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The dead zone of the joystick" +msgstr "Identyfikator użycia joysticka" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Domyślny format w jakim są zapisywane profile,\n" +"gdy wpisujemy `/ profiler save [format]` bez określonego formatu." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "Głębokość ziemi lub innego wypełniacza." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"Ścieżka pliku zbliżona ścieżce twojego świata, w której zapisywane będą " +"profile." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "Identyfikator użycia joysticka" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"Długość w pikselach wymagana do wejścia w interakcję z ekranem dotykowym." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"Maksymalna wysokość powierzchni falujących cieczy.\n" +"4,0 = wysokość fali wynosi dwa węzły.\n" +"0.0 = Fala w ogóle się nie porusza.\n" +"Wartość domyślna to 1.0 (1/2 węzła).\n" +"Wymaga włączenia falujących cieczy." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "Interfejs sieciowy używany na serwerze." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Przywileje nadawane automatycznie nowym użytkownikom.\n" +"Sprawdź /privs w celu wyświetlenia ich listy oraz ustawień modów na serwerze." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"Promień objętości bloków wokół każdego gracza, który podlega\n" +"aktywne bloki, określone w mapblocks (16 węzłów).\n" +"W aktywnych blokach ładowane są obiekty i uruchamiane ABM.\n" +"Jest to również minimalny zakres, w którym utrzymywane są obiekty aktywne " +"(moby).\n" +"Należy to skonfigurować razem z active_object_send_range_blocks." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"Zaplecze renderowania.\n" +"Po zmianie wymagane jest ponowne uruchomienie.\n" +"Uwaga: w Androidzie trzymaj się OGLES1, jeśli nie masz pewności! W " +"przeciwnym razie aplikacja może się nie uruchomić.\n" +"Na innych platformach zalecany jest OpenGL.\n" +"Shadery są obsługiwane przez OpenGL (tylko komputery stacjonarne) i OGLES2 " +"(eksperymentalne)" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"Czułość osi joysticka, wpływa na poruszanie się\n" +"widoku dookoła." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"Siła(ciemność) ambient-occlusion shading bloków.\n" +"Niższa wartość to więcej ciemności, a wyższa wartość to więcej światła.\n" +"Dozwolona wartość obejmuje przedział od 0,25 do 4,0 włącznie. Jeśli wybrana " +"wartość jest z poza skali to\n" +"zostanie zmieniona na najbliższą prawidłową." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Czas (w sekundach), przez który kolejka płynów może wyrosnąć poza " +"przetwarzanie\n" +"pojemności do momentu podjęcia próby zmniejszenia jej rozmiaru poprzez " +"zrzucenie starej kolejki\n" +"przedmiotów. Wartość 0 wyłącza funkcjonalność." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"Budżet czasu, jaki ABM mógł wykonać na każdym kroku\n" +"(jako ułamek interwału ABM)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Czas w sekundach jest brany między powtarzającymi się zdarzeniami\n" +"kiedy przytrzymuje się kombinację przycisków joysticka." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Czas w sekundach między kolejnymi położeniem węzłów po przytrzymaniu\n" +"przycisku umieszczania.." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Typ joysticka" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"Odległość w pionie, powyżej której ciepło spada o 20, jeśli funkcja " +"„altitude_chill” jest\n" +"włączona. Również odległość w pionie, na której wilgotność spada o 10, " +"jeśli\n" +"„altitude_dry” jest włączony." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Pierwsze z czterech szumów 2D, które razem określają wysokość gór/łańcuchów " +"górskich." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Czas żywotności rzeczy upuszczonych na ziemię.\n" +"Ustawienie na -1 wyłącza tą funkcję." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "Pora dnia, gdy stworzono nowy świat, w mili-godzinach (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Interwał czasu wysyłania" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Szybkość upływu czasu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Przekroczono czas oczekiwania usuwania z pamięci danych nieużywanych map " +"klienta." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Aby zredukować opóźnienie, transfery bloków są spowalniane kiedy gracz coś " +"buduje.\n" +"Określa to jak długo są spowalniane po postawieniu lub usunięciu bloku." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Klawisz przełączania trybu widoku kamery" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Opóźnienie wskazówek narzędzi" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Próg ekranu dotykowego" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Próg ekranu dotykowego" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "Kompromisy dla wydajności" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Szum drzew" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Filtrowanie trójliniowe" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True= 256\n" +"False= 128\n" +"Przydatne do wygładzania mapy na wolniejszych urządzeniach." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Zaufane mody" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "Adres URL wyświetlany na liście serwerów w Zakładce Gry Wieloosobowej." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Niedopróbkowanie" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Niedopróbkowanie jest podobne do użycia niższej rozdzielczości ekranu, ale " +"stosuje się tylko do świata gry, zachowując nietknięty GUI.\n" +"Daje to znaczne przyśpieszenie wydajności kosztem mniej szczegółowych " +"obrazów." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Nieskończony transfer odległości gracza" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Usuń nieużywane dane serwera" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Górna granica Y lochów." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Upper Y limit of floatlands." +msgstr "Górna granica Y lochów." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Włącz chmury 3D zamiast płaskich." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Włącz animację chmur w tle menu głównego." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "Włącz filtrowanie anizotropowe dla oglądania tekstur pod kątem." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Włącz filtrowanie bilinearne podczas skalowania tekstur." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Użyj mip mappingu przy skalowaniu tekstur. Może nieznacznie zwiększyć " +"wydajność,\n" +"zwłaszcza przy korzystaniu z tekstur wysokiej rozdzielczości.\n" +"Gamma correct dowscaling nie jest wspierany." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Użyj wielopróbkowego antyaliasingu (MSAA), aby wygładzić krawędzie bloków.\n" +"Algorytm ten wygładza widok 3D, zachowując jednocześnie ostrość obrazu,\n" +"ale nie wpływa na wnętrze tekstur\n" +"(co jest szczególnie widoczne w przypadku przezroczystych tekstur).\n" +"Widoczne odstępy pojawiają się między węzłami, gdy moduły cieniujące są " +"wyłączone.\n" +"Jeśli jest ustawiony na 0, MSAA jest wyłączone.\n" +"Po zmianie tej opcji wymagane jest ponowne uruchomienie." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Użyj filtrowania tri-linearnego podczas skalowania tekstur." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Synchronizacja pionowa" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Głębokość doliny" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Wypełnienie doliny" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Profilowanie doliny" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Stok doliny" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Zmienność głębokości wypełnienia biomu." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Zmienność maksymalnej wysokość gór (podana w blokach)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Zmienność liczby jaskiń." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Zmienność pionowego skalowania terenu.\n" +"Gdy szum wynosi < -0.55 to teren jest prawie płaski." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Zmienność głębokości bloków na powierzchni biomu." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Zmienność poszarpania terenu.\n" +"Określa wartość 'trwałości' terrain_base i szumów terrain_alt." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Kontroluje stromość/wysokość gór." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Vertical climbing speed, in nodes per second." +msgstr "Pionowa prędkość wchodzenia, w blokach na sekundę." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Pionowa synchronizacja ekranu." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Sterownik graficzny" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Współczynnik rozmycia widoku ruchu" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Pole widzenia, wyrażane w blokach." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Klawisz zmniejszania pola widzenia" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Klawisz zwiększania pola widzenia" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Klawisz zoom" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Pole widzenia" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Virtual joystick triggers Aux1 button" +msgstr "Joystick wirtualny aktywuje przycisk aux" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Głośność" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Włącza mapowanie paralaksy.\n" +"Wymaga włączenia shaderów." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Współrzędna W wygenerowanego wycinka 3D fraktala 4D.\n" +"Określa, który wycinek 3D kształtu 4D jest generowany.\n" +"Zmienia kształt fraktala.\n" +"Nie ma wpływu na fraktale 3D.\n" +"Zasięg około -2 do 2." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Walking and flying speed, in nodes per second." +msgstr "Prędkość chodzenia i latania, w blokach na sekundę." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Szybkość chodzenia" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Prędkość chodzenia, latania i wchodzenia w trybie szybkiego chodzenia, w " +"blokach na sekundę." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Poziom wody" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Poziom powierzchni wody na świecie." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Falujące bloki" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Falujące liście" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Falujące bloki" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Wysokość fal wodnych" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Szybkość fal wodnych" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Długość fal wodnych" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Falujące rośliny" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "Kolor zaznaczenia" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Gdy gui_scaling_filter jest aktywny to wszystkie obrazy muszą być\n" +"filtrowane w oprogramowaniu, ale niektóre są generowane bezpośrednio na\n" +"sprzęt ( np. renderuj tekstury do bloków ekwipunku)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Gdy gui_scaling_filter_txr2img jest aktywny, to kopiuj obrazy z komputera \n" +"do Minetesta, żeby je przeskalować. Kiedy jest nieaktywny, użyj starej " +"metody \n" +"skalowania sterowników graficznych, które nieprawidłowo \n" +"wspierają pobieranie tekstur z komputera." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Podczas używania filtrów bilinearnych/ tri-linearnych/ anizotropowych, " +"tekstury niskiej rozdzielczości \n" +"mogą zostać rozmazane, więc automatycznie przeskaluj je z najbliższą " +"interpolacją, \n" +"aby zapobiec poszarpanym pikselom. Określa to minimalny rozmiar tekstur\n" +"do przeskalowania; wyższe wartości wyglądają lepiej, ale wymagają\n" +"więcej pamięci. Zalecane użycie potęg liczby 2. Ustawienie wartości wyższej " +"niż 1\n" +"może nie dawać widocznych rezultatów chyba, że filtrowanie bilinearne/ tri-" +"linearne/ anizotropowe jest włączone.\n" +"Używa się tego również jako rozmiaru tekstur podstawowych bloków " +"przypisanych dla świata przy autoskalowaniu tekstur." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Czy tła tagów nazw mają być domyślnie pokazywane.\n" +"Mody mogą nadal tworzyć tło." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "Określ kiedy animacje tekstur na blok powinny być niesynchronizowane." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Określ widoczność graczy, bez żadnych ograniczeń pola widzenia.\n" +"Zamiast tego użyj polecenia player_transfer_distance ." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Określ możliwość atakowania oraz zabijania innych graczy." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Określ czy klient może się połączyć ponownie po błędzie (Lua).\n" +"Włącz tą wartość jeśli twój serwer będzie restartowany automatycznie." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Określ brak widoczności mgły." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Czy wyciszyć dźwięki. Dźwięki można wyłączyć w dowolnym momencie, chyba że\n" +"system dźwiękowy jest wyłączony (enable_sound=false).\n" +"W grze możesz przełączać stan wyciszenia za pomocą klawisza wyciszania lub " +"używając\n" +"menu pauzy." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"Wyświetlanie efektów debugowania klienta(klawisz F5 ma tą samą funkcję)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "Rozdzielczość pionowa rozmiaru okna gry." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width of the selection box lines around nodes." +msgstr "Szerokość linii zaznaczenia bloków." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Tylko dla systemu Windows: uruchom Minetest z wierszem poleceń w tle.\n" +"Zawiera te same informacje co plik debug.txt (domyślna nazwa)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Katalog świata (wszystko w świecie jest przechowywane tutaj).\n" +"Nie wymagane jeżeli rozpoczyna się z głównego menu." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Dokładny czas stworzenia świata" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Tekstury wyrównane do świata mogą być skalowane tak, aby obejmowały kilka " +"węzłów. Jednakże,\n" +"serwer może nie wysłać żądanej wagi, zwłaszcza jeśli używasz\n" +"specjalnie zaprojektowany pakiet tekstur; z tą opcją klient próbuje\n" +"automatycznie określić skalę na podstawie rozmiaru tekstury.\n" +"Zobacz także texture_min_size.\n" +"Ostrzeżenie: ta opcja jest EKSPERYMENTALNA!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Tryb tekstur przypisanych do świata" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y płaskiego podłoża." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y gęstości góry poziomu zerowego. Używany do pionowego przesunięcia gór." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Y górnej granicy dużych jaskiń." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" +"Dystans zmiennej Y powyżej którego jaskinie rozciągają się do pełnych " +"rozmiarów." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Odległość Y, na której pływające tereny zwężają się od pełnej gęstości do " +"zera.\n" +"Zbieżność rozpoczyna się w tej odległości od granicy Y.\n" +"W przypadku litej warstwy pływów kontroluje wysokość wzgórz/gór.\n" +"Musi być mniejsza lub równa połowie odległości między granicami Y." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Wartość Y przeciętnego terenu." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Limit wysokości jaskiń." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Wysokość terenu górzystego tworzącego klify." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Wysokość dolin oraz dna jezior." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Wysokość dna jezior." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "cURL przekroczono limit pobierania pliku" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "Limit czasu cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Limit równoległy cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "Tryb kreatywny " + +#~ msgid "- Damage: " +#~ msgstr "- Obrażenia: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = parallax occlusion z informacją nachylenia (szybsze).\n" +#~ "1 = relief mapping (wolniejsze, bardziej dokładne)." + +#~ msgid "Address / Port" +#~ msgstr "Adres / Port" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Ustaw kodowanie gamma dla tablic świateł. Wyższe wartości to większa " +#~ "jasność.\n" +#~ "To ustawienie jest tylko dla klientów, ignorowane przez serwer." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "" +#~ "Zmienia sposób w jaki podobne do gór latające wyspy zwężają się ku " +#~ "środkowi nad i pod punktem środkowym." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Jesteś pewny że chcesz zresetować świat singleplayer?" + +#~ msgid "Back" +#~ msgstr "Backspace" + +#~ msgid "Basic" +#~ msgstr "Podstawowy" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bity na piksel (głębia koloru) w trybie pełnoekranowym." + +#~ msgid "Bump Mapping" +#~ msgstr "Mapowanie wypukłości" + +#~ msgid "Bumpmapping" +#~ msgstr "Mapowanie wypukłości" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "Centrum przyśpieszenia środkowego krzywej światła." + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Zmienia interfejs użytkownika menu głównego:\n" +#~ "- Pełny: Wiele światów jednoosobowych, wybór gry, wybór paczki " +#~ "tekstur, itd.\n" +#~ "- Prosty: Jeden świat jednoosobowy, brak wyboru gry lub paczki " +#~ "tekstur. Może być konieczny dla mniejszych ekranów." + +#~ msgid "Config mods" +#~ msgstr "Ustawienia modów" + +#~ msgid "Configure" +#~ msgstr "Ustaw" + +#~ msgid "Connect" +#~ msgstr "Połącz" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Wpływa na prędkość zanurzania w płynie." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Kontroluje gęstość wznoszącego się terenu górzystego.\n" +#~ "Jest to wartość dodana do wartość szumu 'np_mountain'." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Kontroluje szerokość tuneli, mniejsze wartości tworzą szersze tunele." + +#~ msgid "Credits" +#~ msgstr "Autorzy" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Kolor celownika (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Obrażenia włączone" + +#~ msgid "Darkness sharpness" +#~ msgstr "Ostrość ciemności" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Domyślny limit czasu dla cURL, w milisekundach.\n" +#~ "Ma znaczenie tylko gdy skompilowane z cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Określa obszary wznoszącego się gładkiego terenu.\n" +#~ "Wygładzone powierzchnie pojawiają się gdy szum > 0." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Definiuje krok próbkowania tekstury.\n" +#~ "Wyższa wartość reprezentuje łagodniejszą mapę normalnych." + +#~ msgid "Del. Favorite" +#~ msgstr "Usuń ulubiony" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Pobierz tryb gry, taki jak Minetest Game, z minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Ściągnij taką z minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Pobieranie i instalowanie $1, proszę czekaj..." + +#~ msgid "Enable VBO" +#~ msgstr "Włącz VBO" + +#, fuzzy +#~ msgid "Enable register confirmation" +#~ msgstr "Włącz potwierdzanie rejestracji" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Włącza mapowanie wypukłości dla tekstur. Mapy normalnych muszą być dodane " +#~ "w paczce tekstur\n" +#~ "lub muszą być automatycznie wygenerowane.\n" +#~ "Wymaga włączonych shaderów." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Włącz filmic tone mapping" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Włącza generację map normalnych w locie (efekt płaskorzeźby).\n" +#~ "Wymaga włączenia mapowania wypukłości." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Włącza mapowanie paralaksy.\n" +#~ "Wymaga włączenia shaderów." + +#~ msgid "Enter " +#~ msgstr "Enter " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Eksperymentalna opcja, może powodować widoczne przestrzenie\n" +#~ "pomiędzy blokami kiedy ustawiona powyżej 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS podczas pauzy w menu" + +#~ msgid "Fallback font shadow" +#~ msgstr "Zastępczy cień czcionki" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Zastępcza przeźroczystość cienia czcionki" + +#~ msgid "Fallback font size" +#~ msgstr "Zastępczy rozmiar czcionki" + +#~ msgid "Filtering" +#~ msgstr "Filtrowanie anizotropowe" + +#~ msgid "Floatland base height noise" +#~ msgstr "Podstawowy szum wysokości wznoszącego się terenu" + +#~ msgid "Floatland mountain height" +#~ msgstr "Wysokość gór latających wysp" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Kanał alfa cienia czcionki (nieprzeźroczystość, od 0 do 255)." + +#~ msgid "FreeType fonts" +#~ msgstr "Czcionki Freetype" + +#~ msgid "Full screen BPP" +#~ msgstr "Głębia koloru w trybie pełnoekranowym" + +#~ msgid "Game" +#~ msgstr "Gra" + +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Generuj normalne mapy" + +#~ msgid "Generate normalmaps" +#~ msgstr "Generuj mapy normalnych" + +#~ msgid "HUD scale factor" +#~ msgstr "Współczynnik skalowania HUD" + +#~ msgid "High-precision FPU" +#~ msgstr "FPU Wysokiej precyzji" + +#~ msgid "IPv6 support." +#~ msgstr "Wsparcie IPv6." + +#~ msgid "In-Game" +#~ msgstr "Gra" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Zainstaluj mod: plik: \"$1\"" + +#, fuzzy +#~ msgid "Instrumentation" +#~ msgstr "Instrukcja" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Zdefiniowane klawisze. (Jeżeli to menu nie działa, usuń skonfigurowane " +#~ "klawisze z pliku minetest.conf)" + +#, fuzzy +#~ msgid "Lava depth" +#~ msgstr "Głębia dużej jaskini" + +#~ msgid "Lightness sharpness" +#~ msgstr "Ostrość naświetlenia" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Limit oczekiwań na dysku" + +#~ msgid "Main" +#~ msgstr "Menu główne" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "Skrypt głównego menu" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "Sprawia, że DirectX działa z LuaJIT. Wyłącz jeśli występują kłopoty." + +#~ msgid "Menus" +#~ msgstr "Menu" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Minimapa w trybie radaru, Zoom x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Minimapa w trybie radaru, Zoom x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Minimapa w trybie powierzchniowym, powiększenie x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Minimapa w trybie powierzchniowym, powiększenie x4" + +#~ msgid "Name / Password" +#~ msgstr "Nazwa gracza / Hasło" + +#~ msgid "Name/Password" +#~ msgstr "Nazwa gracza/Hasło" + +#~ msgid "No" +#~ msgstr "Nie" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Próbkowanie normalnych map" + +#~ msgid "Normalmaps strength" +#~ msgstr "Siła map normlanych" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Liczba iteracji dla parallax occlusion." + +#~ msgid "Ok" +#~ msgstr "OK" + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "" +#~ "Ogólny błąd systematyczny efektu zamykania paralaksy, zwykle skala/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Całkowity efekt skalowania zamknięcia paralaksy." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Mapowanie paralaksy" + +#~ msgid "Parallax occlusion" +#~ msgstr "Zamknięcie paralaksy" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Błąd systematyczny zamknięcia paralaksy" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Iteracje zamknięcia paralaksy" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Tryb zamknięcia paralaksy" + +#, fuzzy +#~ msgid "Parallax occlusion scale" +#~ msgstr "Skala parallax occlusion" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Siła zamknięcia paralaksy" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Ścieżka do pliku .ttf lub bitmapy." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Ścieżka, pod którą zapisywane są zrzuty ekranu." + +#~ msgid "Player name" +#~ msgstr "Nazwa gracza" + +#, fuzzy +#~ msgid "Profiling" +#~ msgstr "Profilowanie modyfikacji" + +#~ msgid "Projecting dungeons" +#~ msgstr "Projekcja lochów" + +#~ msgid "PvP enabled" +#~ msgstr "PvP włączone" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Resetuj świat pojedynczego gracza" + +#~ msgid "Select Package File:" +#~ msgstr "Wybierz plik paczki:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Pojedynczy gracz" + +#~ msgid "Shadow limit" +#~ msgstr "Limit cieni" + +#, fuzzy +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "Offset cienia czcionki, jeżeli 0 to cień nie będzie rysowany." + +#~ msgid "Special" +#~ msgstr "Specialne" + +#, fuzzy +#~ msgid "Special key" +#~ msgstr "Skradanie" + +#~ msgid "Start Singleplayer" +#~ msgstr "Tryb jednoosobowy" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Siła generowanych zwykłych map." + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "Siłą przyśpieszenia środkowego krzywej światła." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Ta czcionka zostanie użyta w niektórych językach." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Sterownik OpenGL jest wymagany aby włączyć shadery." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Przełącz na tryb Cinematic" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Maksymalna, standardowa wysokość, powyżej lub poniżej średniego punktu " +#~ "górzystego terenu." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Zmienność wysokości wzgórz oraz głębokości jezior na gładkim terenie " +#~ "wznoszącym się." + +#~ msgid "Waving Water" +#~ msgstr "Falująca woda" + +#~ msgid "Waving water" +#~ msgstr "Falująca woda" + +#, fuzzy +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Kiedy tylko czcionki wolnego typu są używane wymagana jest ich kompilacja " +#~ "wspierająca takie czcionki." + +#~ msgid "Whether dungeons occasionally project from the terrain." +#~ msgstr "Określa czy lochy mają być czasem przez generowane teren." + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Y górnej granicy lawy dużych jaskiń." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "" +#~ "Wysokość średniego punktu wznoszącego się terenu oraz powierzchni jezior." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Wysokość do której rozciągają się cienie wznoszącego terenu." + +#~ msgid "Yes" +#~ msgstr "Tak" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Próbujesz wejść na serwer \"%s\" o nazwie \"%2$s2\" po raz pierwszy . " +#~ "Jeśli zdecydujesz się kontynuować na serwerze zostanie utworzone nowe " +#~ "konto z Twoim danymi.\n" +#~ "Wpisz ponownie hasło i wciśnij \"Zarejestruj się i Dołącz\" aby " +#~ "potwierdzić utworzenie konta lub wciśnij \"Anuluj\" aby przerwać ten " +#~ "proces." + +#~ msgid "You died." +#~ msgstr "Umarłeś." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/pt/minetest.po b/po/pt/minetest.po new file mode 100644 index 0000000..0a23415 --- /dev/null +++ b/po/pt/minetest.po @@ -0,0 +1,8365 @@ +msgid "" +msgstr "" +"Project-Id-Version: Portuguese (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-31 17:28+0000\n" +"Last-Translator: Fábio Rodrigues Ribeiro <farribeiro@gmail.com>\n" +"Language-Team: Portuguese <https://hosted.weblate.org/projects/minetest/" +"minetest/pt/>\n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Limpe a fila de espera do chat" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Comando vazio." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Sair para o menu principal" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Comando inválido: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Comando emitido: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Liste os jogadores online" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Jogadores online: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "A fila de espera do chat agora está vazia." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Este comando está desativado pelo servidor." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Renascer" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Você morreu" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Comandos disponíveis:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Comandos disponíveis: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Comando não disponível: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Obtenha ajuda para comandos" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Use '.help <cmd>' para conseguir mais informação, ou '.help all' para listar " +"tudo." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all| <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<Comando não disponível>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Ocorreu um erro em um script Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Ocorreu um erro:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menu principal" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Reconectar" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "O servidor solicitou uma reconexão:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "Uma nova versão de $1 está disponível" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "Mods de cliente" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" +"Versão instalada: $1\n" +"Nova versão: $ 2\n" +"Visite $3 para descobrir como obter a versão mais recente e manter-se " +"atualizado com recursos e correções de bugs." + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "Depois" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "Nunca" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "A versão do protocolo não coincide. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "O servidor requer o protocolo versão $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "O servidor suporta versões de protocolo entre $1 e $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "Visite o website" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Nós suportamos apenas o protocolo versão $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Nós suportamos as versões de protocolo entre $1 e $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "(Ativado, tem erro)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "(Insatisfeito)" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Cancelar" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Dependências:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Desativar tudo" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Desativar modpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Ativar tudo" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Ativar modpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Falha ao carregar mod \"$1\" devido ao fato de seu nome possuir caracteres " +"inválidos. Apenas caracteres de \"a\" até \"z\" e algarismos de 0 até 9 são " +"permitidos." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Encontre Mais Mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Sem dependências (opcionais)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Nenhuma descrição de jogo disponível." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Sem dependências fortes" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Nenhuma descrição de modpack disponível." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Sem dependências opcionais" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Dependências opcionais:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Guardar" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Mundo:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "ativado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" já existe. Gostaria de sobrescrevê-lo?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "As dependências de $1 e $2 serão instaladas." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 por $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"A descarregar $1,\n" +"$2 na fila" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "A descarregar $1..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 dependências necessárias não foram encontradas." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 serão instalados e $2 dependências serão ignoradas." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Todos os pacotes" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Já instalado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Voltar ao menu principal" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Jogo base:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB não está disponível quando Minetest é compilado sem cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "A descarregar..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Falhou em descarregar $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Jogos" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instalar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Instalar $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Instalar dependências ausentes" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Instalação: Tipo de arquivo não suportado ou corrompido" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mods" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Nenhum pacote pode ser recuperado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Sem resultados" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Sem atualizações" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Não encontrado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Sobrescrever" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Verifique se o jogo base está correto." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Enfileirado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Pacotes de texturas" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Desinstalar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Atualizar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Atualizar tudo [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Exibir mais informações num navegador da Web" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "O mundo com o nome \"$1\" já existe" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Terreno adicional" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Frio de altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Altitude seca" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Mistura de biomas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Cavernas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Cavernas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Criar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Decorações" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "O Development Test destina-se apenas a programadores." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Masmorras" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Terreno plano" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Terrenos flutuantes no céu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Terrenos flutuantes (experimental)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Gerar terreno não-fractal: Oceanos e subsolo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Montanhas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Rios húmidos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Aumenta a humidade perto de rios" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "Instalar um jogo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "Instalar outro jogo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Lagos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Baixa humidade e calor elevado resultam em rios rasos ou secos" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Geração de Mapa" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Flags do mapgen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Flags específicas do mapgen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Montanhas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Fluxo de lama" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Conectar túneis e cavernas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Nenhum jogo selecionado" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Reduz calor com altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Reduz humidade com altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Rios" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Rios ao nível do mar" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Seed" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Transição suave entre biomas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Estruturas que aparecem no terreno (sem efeito em árvores e grama da selva " +"criada pelo v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Estruturas que aparecem no terreno, geralmente árvores e plantas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Temperado, Deserto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Temperado, Deserto, Selva" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Temperado, Deserto, Selva, Tundra, Floresta Boreal" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erosão superficial do terreno" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Árvores e relva da selva" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Variar a profundidade do rio" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Cavernas bastante profundas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nome do mundo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Você não possui jogos instalados." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Tem a certeza que pretende eliminar \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Eliminar" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: não foi possível apagar \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: caminho inválido \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Eliminar mundo \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Confirmar palavra-passe" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "Juntando-se a $1" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "Nome em falta" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nome" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Palavra-passe" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "As senhas não coincidem" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "Registe-se" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Aceitar" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Renomear ModPack:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Esse modpack possui um nome explícito em seu modpack.conf que vai " +"sobrescrever qualquer renomeio aqui." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Não há descrição para esta configuração)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Ruído 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Voltar para as definições" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Navegar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "Conteúdo: Jogos" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "Conteúdo: Mods" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Desativado" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Editar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Ativado" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lacunaridade" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Octavos" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Deslocamento" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Persistência" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Por favor, insira um número inteiro válido." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Por favor, insira um número válido." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Restaurar valores por defeito" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Escala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Procurar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Selecione o diretório" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Selecione o ficheiro" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Mostrar nomes técnicos" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "O valor deve ser pelo menos $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "O valor deve ser menor do que $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "amplitude X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "amplitude Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "amplitude Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "valor absoluto" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "Padrões" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "amenizado" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Ativado)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 módulos" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Falha ao instalar de $1 ao $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" +"Instalação de módulo: não foi possível encontrar o nome real do módulo: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Instalação do Mod: não foi possível encontrar o nome da pasta adequado para " +"o modpack $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Incapaz de encontrar um módulo ou modpack válido" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Não foi possível instalar $1 como pacote de texturas" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Não foi possível instalar um jogo como um $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Não foi possível instalar um módulo como um $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Não foi possível instalar um modpack como um $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "A carregar..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "A lista de servidores públicos está desativada" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Tente reativar a lista de servidores públicos e verifique sua conexão com a " +"Internet." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Sobre" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Contribuidores Ativos" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Renderizador ativo:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Desenvolvedores Principais" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Abrir o diretório de dados do utilizador" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Abre o diretório que contém mundos, jogos, mods fornecidos pelo utilizador,\n" +"e pacotes de textura num gestor de ficheiros / explorador." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Antigos Contribuidores" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Desenvolvedores principais anteriores" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "Compartilhar log de depuração" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Procurar conteúdo online" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Conteúdo" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Desativar pacote de texturas" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informação:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Pacotes instalados:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Sem dependências." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Nenhuma descrição do pacote disponível" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Renomear" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Desinstalar o pacote" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Usar pacote de texturas" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Anunciar servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Endereço de ligação" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Modo Criativo" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Ativar Dano" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Hospedar Jogo" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Instalar jogos do ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Novo" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Nenhum mundo criado ou seleccionado!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Jogar Jogo" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Porta" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Selecionar mods" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Seleccionar Mundo:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Porta do servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Iniciar o jogo" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Endereço" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Limpar" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Modo Criativo" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Dano / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favoritos" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Servidores incompatíveis" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Juntar-se ao jogo" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "Login" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Servidores Públicos" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Atualizar" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "Remover favorito" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Descrição do servidor" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "(Suporte de jogo necessário)" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Nuvens 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Todas as configurações" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Antialiasing:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Auto salvar tamanho do ecrã" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Filtro bilinear" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Mudar teclas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Vidro conectado" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Sombras dinâmicas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "Sombras dinâmicas:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Folhas detalhadas" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Alto" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Baixo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Médio" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Filtro Anisotrópico" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Sem Filtro" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Sem Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Destaque dos Cubos" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Destaque dos Nós" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Nenhum" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Folhas Opacas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Água Opaca" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Particles" +msgstr "Partículas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Ecrã:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Definições" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Sombras" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shaders (experimental)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Sombreadores(indisponível)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Folhas simples" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Iluminação Suave" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Texturização:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Mapeamento de tons" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "Nível de sensibilidade ao toque (px):" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Filtro trilinear" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "Muito Alto" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Muito Baixo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Folhas ondulantes" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Líquidos ondulantes" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Plantas ondulantes" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "Conexão abortada (erro de protocolo?)." + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Erro de ligação (tempo excedido)." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Feito!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inicializando cubos" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Inicializando cubos..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "A carregar texturas..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "A reconstruir sombras..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Erro de ligação (excedeu tempo?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Não foi possível localizar ou carregar jogo " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Especificação de jogo inválida." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menu Principal" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Nenhum mundo seleccionado e nenhum endereço fornecido. Nada a fazer." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Nome de jogador demasiado longo." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Por favor escolha um nome!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Ficheiro de palavra-passe fornecido falhou em abrir : " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "O caminho fornecido do mundo não existe: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Consulte debug.txt para mais detalhes." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Endereço: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Modo: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "-Porta: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Público: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "Nome do servidor: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Ocorreu um erro:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Acesso negado. Razão:%s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Avanço automático desativado" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Avanço automático para frente ativado" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Limites de bloco ocultos" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Limites de bloco mostrados para todos os blocos" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Limites de bloco mostrados para o bloco atual" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Limites de bloco mostrados para blocos próximos" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Atualização da camera desativada" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Atualização da camera habilitada" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "Não é possível mostrar limites de bloco (desativado por mod ou jogo)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Mudar palavra-passe" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Modo cinemático desativado" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Modo cinemático ativado" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Cliente desconectado" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "O scripting de cliente está desativado" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "A conectar ao servidor..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "A conexão falhou por motivo desconhecido" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Continuar" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Controles:\n" +"- %s: mover para a frente\n" +"- %s: mover para trás\n" +"- %s: mover para a esquerda\n" +"- %s: mover para a direita\n" +"- %s: saltar/escalar\n" +"- %s: cavar/socar\n" +"- %s: colocar/usar\n" +"- %s: esgueirar/descer\n" +"- %s: soltar item\n" +"- %s: inventário\n" +"- Rato: virar/ver\n" +"- Roda do rato: selecionar item\n" +"- %s: bate-papo\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Não foi possível resolver o endereço:%s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "A criar cliente..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "A criar servidor..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Informação de debug e gráfico de perfil escondido" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Informação de debug mostrada" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Informação de debug, gráfico de perfil e wireframe escondidos" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Controles por defeito:\n" +"Se não há nenhum menu visível:\n" +"- Um toque: ativa botão\n" +"- Duplo toque: colocar/usar\n" +"- Deslizar dedo: Olhar em redor\n" +"Se menu/inventário visível:\n" +"- Duplo toque: (fora do menu/inventário):\n" +" -->fechar\n" +"- Tocar Item e depois tocar num compartimento:\n" +" --> mover item\n" +"- Tocar e arrastar, e depois tocar com o 2º dedo\n" +" --> Coloca apenas um item no compartimento\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Alcance de visualização ilimitado desativado" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Alcance de visualização ilimitado ativado" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "A criar cliente: %s" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Sair para o Menu" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Sair para o S.O" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Modo rápido desativado" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Modo rápido ativado" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Modo rápido ativado (note: sem privilégio 'fast')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Modo voo desativado" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Modo voo ativado" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Modo voo ativado (note: sem privilégio 'fly')" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Névoa desativada" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Névoa habilitada" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Info do jogo:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Jogo parado" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Criando o servidor" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Definições dos Itens..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Media..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Minipapa atualmente desativado por jogo ou mod" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Multi-jogador" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Modo de atravessar paredes desativado" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Modo atravessar paredes ativado" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Modo atravessar paredes ativado (note: sem privilégio 'noclip')" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "A definir cubos..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Desligado" + +#: src/client/game.cpp +msgid "On" +msgstr "Ligado" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Modo movimento pitch desativado" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Modo movimento pitch ativado" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Gráfico de perfil mostrado" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Servidor remoto" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "A resolver endereço..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "A desligar..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Um Jogador" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Volume do som" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Som mutado" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Som do sistema está desativado" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Som do sistema não é suportado nesta versão" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Som desmutado" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "O servidor provavelmente está executando uma versão diferente de%s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Não foi possível conectar a%s porque o IPv6 está desativado" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Incapaz de escutar em%s porque IPv6 está desativado" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Distancia de visualização alterado pra %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Distancia de visualização está no máximo:%d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Distancia de visualização está no mínimo: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Som alterado para %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Mostrar wireframe" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zoom atualmente desativado por jogo ou mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Conversa oculta" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Conversa mostrada" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "Interface escondida" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "Interface mostrada" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Analisador ocultado" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Analisador mostrado(página %d de %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplicações" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Tecla voltar" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Baixo" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Tecla End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Apagar OEF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Executar" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Ajuda" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Aceitar Método de Entrada" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Converter Método de Entrada" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "Sair do Editor de Método de Entrada" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Mudar Modo de Método de Entrada" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "Nãoconverter" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Esquerda" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Botão Esquerdo" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Control Esquerdo" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menu Esquerdo" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Shift Esquerdo" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Tecla WINDOWS esquerda" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Roda do Rato" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Tecla numérica *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Tecla numérica +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Tecla numérica -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Tecl.num. ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Tecla numérica /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Tecla numérica 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Tecla numérica 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Tecla numérica 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Tecla numérica 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Tecla numérica 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Tecla numérica 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Tecla numérica 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Tecla numérica 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Tecla numérica 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Tecla numérica 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Limpar OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pausa" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Jogar" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Tecla Print Screen" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Direita" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Botão Direito" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Control Direito" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menu Direito" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Shift Direito" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Tecla WINDOWS direita" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Seleccionar" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Suspender" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Screenshot" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Espaço" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabulação" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Cima" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Botão X 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Botão X 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Minimapa escondido" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimapa em modo radar, ampliação %dx" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimapa em modo de superfície, ampliação %dx" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimapa em modo de textura" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Falha ao abrir página da web" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Abrindo página da web" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Continuar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Especial\" = descer" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Avanço frontal automático" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Pulo automático" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Especial" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Recuar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Limites de bloco" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Mudar camera" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Comando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Consola" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Alcance dec" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Diminuir som" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Carregue duas vezes em \"saltar\" para voar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Largar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Avançar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Alcance inc" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Aumentar Volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventário" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Saltar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Tecla já em uso" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "Combinações de teclas." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Comandos do Chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Mudo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Próximo item" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Item anterior" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Seleccionar Distância" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Captura de ecrã" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Agachar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Ativar interface" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Ativar histórico de conversa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Ativar/Desativar correr" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Ativar/Desativar vôo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Ativar névoa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Ativar minimapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Ativar/Desativar noclip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Alternar pitchmove" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "pressione a tecla" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Mudar" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Palavra-passe nova" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Palavra-passe antiga" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "As palavra-passes não correspondem!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Sair" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Mutado" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Volume do som: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "pt" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" +"O nome não está registrado. Para criar uma conta neste servidor, clique em " +"'Registrar'" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "O nome foi tomado. Por favor, escolha outro nome" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Corrige a posição do joystick virtual.\n" +"Se desativado, o joystick virtual vai centralizar na posição do primeiro " +"toque." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Use joystick virtual para ativar botão \"especial\".\n" +"Se ativado, o joystick virtual vai também clicar no botão \"especial\" " +"quando estiver fora do circulo principal." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) compensação de fractal do centro mundial em unidades de 'escala'.\n" +"Pode ser usado para mover um ponto desejado para (0, 0) para criar um\n" +"ponto de desova adequado ou para permitir o \"zoom in\" sobre um\n" +"ponto por aumentar a \"escala\".\n" +"O padrão é sintonizado para um ponto de desova adequado para Mandelbrot\n" +"com parâmetros padrão, pode precisar ser alterado em outras\n" +"situações.\n" +"Gama aproximadamente -2 a 2. Multiplicar por 'escala' para compensar em nós." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z) Escala fractal em nós.\n" +"Tamanho fractal atual será de 2 a 3 vezes maior.\n" +"Esses números podem ser muito grandes, o fractal não \n" +"tem que encaixar dentro do mundo.\n" +"Aumente estes para 'ampliar' nos detalhes do fractal.\n" +"Predefinição é para uma forma espremida verticalmente para uma ilha,\n" +"ponha todos os 3 números iguais para a forma crua." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Ruído 2D que controla a forma/tamanho de montanhas acidentadas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Ruído 2D que controla o formato/tamanho de colinas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Ruído 2D que controla o formato/tamanho de montanhas de etapa." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "Ruído 2D que controla o tamanho/ocorrência de montanhas sulcadas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D noise que controla o tamanho/ocorrência de colinas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "Ruído 2D que controla o tamanho/ocorrência de montanhas de passo." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Ruído 2D que localiza os vales e canais dos rios." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Nuvens 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Modo 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Força de paralaxe do modo 3D" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Ruído 3D a definir cavernas gigantes." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Ruído 3D a definir estrutura montanhosa e altura.\n" +"Também define estrutura de terra flutuante e terreno montanhoso." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Ruído 3D definindo as estruturas de terras flutuantes\n" +"Se alterar da predefinição, a 'escala' do ruído (0.7 por predefinição) pode " +"precisar\n" +"ser ajustada, já que o afunilamento das terras flutuantes funciona melhor " +"quando o ruído tem\n" +"um valor entre -2.0 e 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Ruído 3D a definir estrutura do rio e paredes do desfiladeiro." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Ruído 3D que define o terreno." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"3D noise para saliências de montanhas, penhascos, etc. Geralmente variações " +"pequenas." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "Ruído 3D que determina o número de masmorras por mapchunk." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Suporte de 3D.\n" +"Modos atualmente suportados:\n" +"- none: nenhum efeito 3D.\n" +"- anaglyph: sistema de cor Ciano/Magenta (Óculos 3D azul vermelho).\n" +"- interlaced: sistema interlaçado (Óculos com lentes polarizadas).\n" +"- topbottom: divide o ecrã em dois: um em cima e outro em baixo.\n" +"- sidebyside: divide o ecrã em dois: lado a lado.\n" +" - crossview: 3D de olhos cruzados.\n" +" - pageflip: quadbuffer baseado em 3D.\n" +"Note que o modo interlaçado requer que sombreamentos estejam ativados." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "3d" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Seed aleatória para um novo mundo (em branco para ser aleatória).\n" +"Será anulada quando for criado um outro novo mundo no menu principal." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" +"Mensagem a ser mostrada a todos os clientes do servidor quando o servidor " +"crasha." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Uma mensagem para ser mostrada a todos os clientes quando o servidor se " +"desliga." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Intervalo do ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Orçamento de tempo do ABM" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Limite absoluto de blocos em fila de espera a emergir" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Aceleração no ar" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Aceleração da gravidade, em nós por segundo por segundo." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Modificadores de Blocos Ativos" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Intervalo de Gestão de Blocos Ativos" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Alcance de blocos ativos" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Distância de envio de objetos ativos" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Endereço para ligação.\n" +"Deixe em branco para iniciar um servidor local.\n" +"Note que o campo de endereço no menu principal sobrescreve esta configuração." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Adiciona partículas quando escava um node." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Ajustar configuração de dpi ao seu ecrã (não aplicável a X11/Android) ex: " +"para ecrãs 4K." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Ajuste a densidade de exibição detectada, usada para dimensionar os " +"elementos da IU." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Ajusta a densidade da camada de terrenos flutuantes.\n" +"Aumenta o valor para aumentar a densidade. Pode ser positivo ou negativo.\n" +"Valor = 0,0: 50% do volume são terrenos flutuantes.\n" +"Valor = 2,0 (pode ser maior dependendo de 'mgv7_np_floatland', teste sempre\n" +"para ter certeza) cria uma camada sólida de terrenos flutuantes." + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "Nome do administrador" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avançado" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Altera a curva da luz, aplicando-lhe a 'correção gama'.\n" +"Valores altos tornam os níveis médios e inferiores de luz mais brilhantes.\n" +"O valor '1.0' deixa a curva de luz inalterada.\n" +"Isto só tem um efeito significativo sobre a luz do dia e a luz artificial,\n" +"tem muito pouco efeito na luz natural da noite." + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "Sempre voe rápido" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Gama de oclusão de ambiente" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Quantidade de mensagens que um jogador pode enviar por 10 segundos." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Amplifica os vales." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Filtro anisotrópico" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Anunciar servidor" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Anuncie para esta lista de servidor." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Concatenar nome do item" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Concatenar nome do item a descrição." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Ruído de Macieiras" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Inercia dos braços" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Inercia dos braços fornece um movimento mais \n" +"realista dos braços quando a câmara se move." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Pedir para reconectar após de bloqueio de sistema" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"Nesta distância, o servidor otimizará agressivamente quais blocos são " +"enviados aos \n" +"clientes.\n" +"Pequenos valores potencialmente melhoram muito o desempenho, à custa de \n" +"falhas de renderização visíveis (alguns blocos não serão processados debaixo " +"da \n" +"água e nas cavernas, bem como às vezes em terra).\n" +"Configure isso como um valor maior do que a " +"distância_máxima_de_envio_do_bloco \n" +"para desativar essa otimização.\n" +"Especificado em barreiras do mapa (16 nós)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "Áudio" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Tecla para frente automática" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Automaticamente pula obstáculos de um só nó." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Informar para a lista de servidores automaticamente." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Auto salvar tamanho do ecrã" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Modo de alto escalamento" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Tecla especial" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Tecla Aux1 pra escalar/descer" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tecla para andar para trás" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Nível de solo base" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Altura base do terreno." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Privilégios básicos" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Ruído de praia" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Limite do ruído da praia" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Filtro bi-linear" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Endereço de bind" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "Parâmetros de ruído da API do bioma" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Ruído da Biome" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Distância otimizada de envio de bloco" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Caminho de fonte para negrito e itálico" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Caminho de fonte monoespacial negrito e itálico" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Caminho da fonte negrito" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Caminho de fonte monoespaçada" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Construir com o jogador dentro do cubo" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Integrado" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "Câmera" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Distancia do plano próximo da câmara em nós, entre 0 e 0.5\n" +"A maioria dos utilizadores não precisará mudar isto.\n" +"Aumentar pode reduzir a ocorrência de artefactos em GPUs mais fracas.\n" +"0.1 = Predefinição, 0.25 = Bom valor para tablets fracos." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Suavização da camera" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Suavização da câmara no modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Tecla para ativar/desativar atualização da câmara" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Barulho nas caverna" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Ruído para cavernas #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Ruído para cavernas #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Largura da caverna" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Barulho na caverna1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Barulho na caverna2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Limite da caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Barulho da caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Taper da Caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Limite da caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Limite do topo da caverna" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Faixa de aumento do centro da curva de luz.\n" +"0,0 é o nível mínimo de luz, 1,0 é o nível máximo de luz." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Limite de mensagem de tempo de comando de bate-papo" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Comandos de Chat" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Tamanho da fonte do chat" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Tecla de conversação" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Nível de log do chat" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Limite do contador de mensagens de bate-papo" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Formato da mensagem de chat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Limite da mensagem de expulsão" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Tamanho máximo da mensagem de conversa" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Tecla mostra/esconde conversação" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Ligações de bate-papo" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Dimensão das parcelas" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tecla para modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Limpar texturas transparentes" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Ligações da web clicáveis (clique do meio ou Ctrl + botão esquerdo) ativados " +"na saída do console de bate-papo." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Cliente" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Cliente e servidor" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Cliente" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Restrição de modificação no lado do cliente" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Restrição do alcançe da visão superior de nós no lado do cliente" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "Modding do lado do cliente" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Velocidade de escalada" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Raio das nuvens" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Nuvens" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "As nuvens são um efeito do lado do cliente." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Nuvens no menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Névoa colorida" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Sombra colorida" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Lista de flags separadas por vírgula para esconder no repositório de " +"conteúdos.\n" +"\"não livre\" pode ser usada para esconder pacotes que não se qualificam " +"como software livre,\n" +"como definido pela Free Software Foundation.\n" +"Você também pode especificar classificação de conteúdo.\n" +"Essas flags são independentes das versões do minetest,\n" +"veja a lista completa em https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Lista separada por vírgulas de extras que podem usar APIs de requisição " +"HTTP, \n" +"que lhes permitem enviar e descarregar dados para/da internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Lista separada por vírgulas de extras de confiança que podem utilizar " +"funções inseguras \n" +"mesmo quando a segurança de extras está ativada (via " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Tecla de comando" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Nível de compressão ZLib a ser usada ao gravar mapblocks no disco.\n" +"-1 - Nível de compressão padrão do Zlib\n" +"0 - Nenhuma compressão; o mais rápido\n" +"9 - Melhor compressão; o mais devagar (níveis 1-3 usam método \"rápido\" do " +"Zlib, enquanto que 4-9 usam método normal)" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Nível de compressão ZLib a ser usada ao mandar mapblocks para o cliente.\n" +"-1 - Nível de compressão padrão do Zlib\n" +"0 - Nenhuma compressão; o mais rápido\n" +"9 - Melhor compressão; o mais devagar (níveis 1-3 usam método \"rápido\" do " +"Zlib, enquanto que 4-9 usam método normal)" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Vidro conectado" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Conectar a servidor media externo" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Conecta o vidro se suportado pelo cubo." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Opacidade da consola" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Cor da consola" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Tecla da consola" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "Repositório de conteúdo" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Lista negra de flags do ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Máximo de descargas simultâneas de ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "Url do ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Avançar continuamente" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Movimento para frente contínuo, ativado pela tecla de avanço automático.\n" +"Pressione a tecla de avanço frontal novamente ou a tecla de movimento para " +"trás para desativar." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Controles" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Controla a duração do ciclo de dia/noite.\n" +"Exemplos:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = Dia/noite permanece inalterado." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" +"Controla a velocidade de afundamento em líquido quando em marcha lenta. " +"Valores negativos causarão\n" +"você a subir em vez disso." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Controla a inclinação/profundidade dos lagos." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Controla a inclinação/altura das colinas." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Controla a largura de túneis, um valor mais baixo cria túneis mais largos.\n" +"Valores >= 10,0 desativam completamente a geração de túneis e evitam\n" +"cálculos intensos de ruído." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Mensagem de erro" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Criar" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Opacidade do cursor" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Alpha do cursor (quanto ele é opaco, níveis entre 0 e 255).\n" +"Também controla a cor da cruz do objeto." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Cor do cursor" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Cor da cruz (R, G, B).\n" +"Também controla a cor da cruz do objeto" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Ativar dano" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Tecla para alternar modo de depuração" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Limite do tamanho do ficheiro de log de depuração" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Nível de log de depuração" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "Debugging" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Tecla de dimin. de som" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Intervalo de atualização do servidor" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Aceleração por defeito" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Jogo por defeito" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Jogo por defeito aquando da criação de um mundo novo.\n" +"É anulado quando o mundo é criado através do menu principal." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Palavra-passe predefinida" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Privilégios por defeito" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Formato de report predefinido" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Tamanho de pilha predefinido" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Define a qualidade de filtragem de sombreamento\n" +"Isso simula um efeito de sombras suaves aplicando um PCF ou um Poisson disk\n" +"mas também usa mais recursos." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Define áreas onde árvores têm maçãs." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Define áreas com praias arenosas." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" +"Define a distribuição de terrenos elevados e a inclinação de penhascos." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Define a distribuição de terrenos elevados." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Define o tamanho completo de cavernas, valores menores criam cavernas " +"maiores." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Define estruturas de canais de grande porte (rios)." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Define localizações e terrenos de morros e lagos opcionais." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Define o nível base do solo." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Define a profundidade do canal do rio." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Define distância máxima de transferência de jogadores em blocos (0 = " +"ilimitado)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Define a largura do canal do rio." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Define a largura do vale do rio." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Define áreas de árvores e densidade das árvores." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Tempo entre atualizações das malhas 3D no cliente em milissegundos. Aumentar " +"isso\n" +"vai retardar a taxa de atualização das malhas, por isso reduz travamentos em " +"clientes lentos." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Atraso no envio de blocos após construção" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Latência de apresentação de dicas de ferramentas, em milissegundos." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Tratamento de API Lua obsoleto" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Profundidade em que você encontrará cavernas gigantes." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Profundidade a partir da qual você encontrará grandes cavernas." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Descrição do servidor, a ser exibida quando jogadores se conectam e na lista " +"de servidores." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Limite do ruído de deserto" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Os desertos ocorrem quando np_biome excede este valor.\n" +"Quando a marcação 'snowbiomes' está ativada, isto é ignorado." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Dessincroniza animação de blocos" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "Opções de desenvolvedor" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Tecla para escavar" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Ativar Particulas" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Desativar anti-batota" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Não permitir palavra-passes vazias" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Fator de escala de densidade de exibição" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Nome de domínio do servidor, para ser mostrado na lista de servidores." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Carregue duas vezes em saltar para voar" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Carregar duas vezes em saltar ativa/desativa o vôo." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Tecla para largar item" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Mostrar informações de depuração do Gerador de mapa." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Y máximo da dungeon" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Y mínimo da dungeon" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Ruído de masmorra" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Ativar suporte de IPv6 (tanto para cliente como para servidor).\n" +"Necessário para que conexões de IPv6 funcionem." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Ativar suporte a mods LUA locais no cliente.\n" +"Esse suporte é experimental e a API pode mudar." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Ativa filtragem de Poisson disk.\n" +"Quando em true usa o Poisson disk para fazer \"sombras suaves\". Caso " +"contrário, usa filtragem PCF." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Ativa sombras coloridas.\n" +"Quando em true, nodes translúcidos podem projetar sombras coloridas. Requer " +"o uso de muitos recursos." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Ativar janela de console" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Ativar modo criativo para todos os jogadores" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Ativar Joysticks" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Ativar suporte a canais de módulos." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Ativar segurança de extras" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Ativar dano e morte dos jogadores." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Ativa a entrada de comandos aleatória (apenas usado para testes)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Ativar a iluminação suave com oclusão de ambiente simples.\n" +"Desativar para velocidade ou vistas diferentes." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Ativar para impedir a conexão de clientes antigos.\n" +"Clientes antigos são compatíveis no sentido em que não bloquearão quando " +"conectam \n" +"a servidores recentes, mas poderão não suportar todos as funcionalidades " +"esperadas." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Ativar a utilização de um servidor media remoto (se fornecido pelo " +"servidor).\n" +"Servidores remotos oferecem uma maneira mais rápida de descarregar media\n" +"(ex. texturas) quando se estiver a conectar ao servidor." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Ativar os objectos buffer de vértice.\n" +"Isto deve melhorar muito o desempenho gráfico." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Multiplicador para sacudir a exibição.\n" +"Por exemplo: 0 para não ver balançando; 1.0 para normal; 2.0 para duplo." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Ativar/desativar a execução de um servidor IPv6.\n" +"Ignorado se bind_address estiver definido.\n" +"Necessita de habilitar_ipv6." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Permite o mapeamento de tom de filme 'Uncharted 2' de Hable.\n" +"Simula a curva de tonalidade do filme fotográfico e como esta se aproxima " +"da\n" +"aparência de imagens de alta gama dinâmica. O contraste de gama média é " +"ligeiramente\n" +"melhorada, os destaques e as sombras são gradualmente comprimidos." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Ativa animação de itens no inventário." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Ativar armazenamento em cache para os meshes das faces." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Ativa mini-mapa." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Possibilita o sistema de som.\n" +"Se desativado, desativa completamente todos os sons em todo o lado e \n" +"os controles de som no jogo não funcionarão.\n" +"A alteração desta configuração requer um reinício." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "Perfil do motor" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Intervalo de exibição dos dados das analizes do motor" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Metodos de entidade" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Expoente do afunilamento do terreno flutuante. Altera o comportamento de " +"afunilamento.\n" +"Valor = 1.0 cria um afunilamento linear e uniforme.\n" +"Valores > 1.0 criam um afunilamento suave, adequado para a separação " +"padrão.\n" +"terras flutuantes.\n" +"Valores < 1,0 (por exemplo, 0,25) criam um nível de superfície mais definido " +"com\n" +"terrenos flutuantes mais planos, adequados para uma camada sólida de " +"terrenos flutuantes." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS quando desfocado ou pausado" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA (Antialiasing de ecrã inteiro)" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Fator de ruído" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Cair balançando" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Caminho da fonte reserva" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Tecla de correr" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Aceleração no modo rápido" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Velocidade no modo rápido" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Modo rápido" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Movimento rápido (através da tecla \"Aux1\").\n" +"Isso requer o privilegio \"fast\" no servidor." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Campo de visão" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Campo de visão em graus." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Ficheiro na pasta client/serverlist/ que contém seus servidores favoritos, " +"que são mostrados na\n" +"aba Multijogador." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Profundidade de preenchimento" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Profundidade de enchimento de ruído" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Mapeamento de tom fílmico" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Texturas filtradas podem misturar valores RGB com os vizinhos totalmente " +"transparentes,\n" +"o qual otimizadores PNG geralmente descartam, por vezes resultando numa " +"linha escura ou\n" +"em texturas transparentes. Aplique esse filtro para limpar isso no momento " +"de carregamento\n" +"da textura. Esse filtro será ativo automaticamente ao ativar \"mipmapping\"." + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "Filtragem e Antialiasing" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Primeiro de 4 ruídos 2D que juntos definem a altura de colinas/montanhas." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Primeiro de 2 ruídos 3D que juntos definem túneis." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Semente aleatória do mapa fixa" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Joystick virtual fixo" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Densidade do terreno flutuante" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Y máximo do terreno flutuante" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Y mínimo do terreno flutuante" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Ruído no terreno flutuante" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Expoente de conicidade de terrenos flutuantes" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Distância de afilamento da ilha flutuante" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Nível da água em terreno flutuante" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Tecla de voar" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Voar" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Nevoeiro" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Início da névoa" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Tecla de ativar/desativar nevoeiro" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "Fonte" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Fonte em negrito por predefinição" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Fonte em itálico por predefinição" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Sombra da fonte" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Opacidade da sombra da fonte" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Tamanho da fonte" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Tamanho da fonte padrão onde 1 unidade = 1 pixel a 96 DPI" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" +"Tamanho da fonte da fonte monoespaçada onde 1 unidade = 1 pixel a 96 DPI" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Tamanho da fonte do texto de bate-papo recente e do prompt do bate-papo em " +"pontos (pt).\n" +"O valor 0 irá utilizar o tamanho padrão de fonte." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Formato das mensagens de chat do jogador. As seguintes cadeias são espaços " +"reservados válidos:\n" +"@name, @message, @timestamp (opcional)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Formato das capturas de ecrã." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Cor de fundo padrão do formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Opacidade de fundo padrão do formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Cores de fundo de ecrã cheia de formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Opacidade de fundo de ecrã cheia do Formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Cor de fundo padrão do Formspec (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Opacidade de fundo padrão do formspec (entre 0 e 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Cor de fundo (R,G,B) do formspec em ecrã cheio." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "Opacidade de fundo do formspec em ecrã cheio (entre 0 e 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Tecla para avançar" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Quarto de 4 ruídos 2D que juntos definem a altura de colinas/montanhas." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Tipo fractal" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Fração da distância visível em que a névoa começa a aparecer" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Distância máxima de geração de blocos para clientes, em mapblocks (16^3 " +"cubos)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Distância máxima de envio de blocos para clientes, em mapblocks (16^3 cubos)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"De quão longe clientes sabem sobre objetos declarados em mapblocks (16 nós)." +"\n" +"\n" +"Configurando isto maior do que o alcance de bloco ativo vai fazer com que o " +"servidor\n" +"mantenha objetos ativos na distancia que o jogador\n" +"está olhando.(Isso pode evitar que mobs desapareçam da visão de repente)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Ecrã inteiro" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Modo de ecrã inteiro." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Escala do interface gráfico" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Filtro de redimensionamento do interface gráfico" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Filtro txr2img de redimensionamento do interface gráfico" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "Gamepads" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Chamadas de retorno Globais" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Atributos de geração de mapa globais.\n" +"No gerador de mapa v6 a flag 'decorations' controla todas as decorações, " +"exceto árvores\n" +"e gramas da selva, em todos os outros geradores de mapa essa flag controla " +"todas as decorações." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Gradiente da curva de luz no nível de luz máximo.\n" +"Controla o contraste dos níveis de luz mais altos." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Gradiente da curva de luz no nível de luz mínimo.\n" +"Controla o contraste dos níveis de luz mais baixos." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Gráficos" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "Efeitos Gráficos" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "Gráficos e Áudio" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravidade" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Nível do terreno para o gerador de mapa plano" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Ruído do solo" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "Módulos HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "Dimensionamento do HUD" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Tecla de comutação HUD" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Lidando com funções obsoletas da API Lua:\n" +"-...none: não regista funções obsoletas.\n" +"-...log: imita e regista as funções obsoletas chamadas (padrão).\n" +"-...error: aborta quando chama uma função obsoleta (sugerido para " +"programadores de mods)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Fazer que o profiler instrumente si próprio:\n" +"* Monitorar uma função vazia.\n" +"Isto estima a sobrecarga, que o instrumento está a adicionar (+1 chamada de " +"função).\n" +"* Monitorar o sampler que está a ser usado para atualizar as estatísticas." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Parâmetros de mistura de ruido do gerador de mundo \"heat\"" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Ruído para cavernas #1" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Componente de altura do tamanho da janela inicial. Ignorado em modo de ecrã " +"cheio." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Ruído de altura" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Parâmetros de ruido de seleção de altura do gerador de mundo v6" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Inclinação dos lagos no gerador de mapa plano" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Limite de lagos no gerador de mapa plano" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Ruído de declive1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Ruído de declive2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Ruído de declive3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Ruído de declive4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Página web do servidor, a ser exibido na lista de servidores." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Aceleração horizontal no ar ao saltar ou cair,\n" +"em nós por segundo por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Aceleração horizontal e vertical em modo rápido,\n" +"em nós por segundo por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Aceleração horizontal e vertical no solo ou ao subir,\n" +"em nós por segundo por segundo." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Tecla de próximo item na barra principal" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Tecla de item anterior na barra principal" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Tecla do slot 1 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Tecla do slot 10 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Tecla do slot 11 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Tecla do slot 12 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Tecla do slot 13 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Tecla do slot 14 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Tecla do slot 15 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Tecla do slot 16 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Tecla do slot 17 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Tecla do slot 18 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Tecla do slot 19 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Tecla do slot 2 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Tecla do slot 20 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Tecla do slot 21 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Tecla do slot 22 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Tecla do slot 23 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Tecla do slot 24 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Tecla do slot 25 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Tecla do slot 26 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Tecla do slot 27 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Tecla do slot 29 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Tecla do slot 29 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Tecla do slot 3 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Tecla do slot 30 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Tecla do slot 31 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Tecla do slot 32 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Tecla do slot 4 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Tecla do slot 5 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Tecla do slot 6 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Tecla do slot 7 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Tecla do slot 8 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Tecla do slot 9 da hotbar" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Quão profundo serão os rios." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"A velocidade com que as ondas líquidas se movem. Maior = mais rápido.\n" +"Se negativo, as ondas líquidas se moverão para trás.\n" +"Requer que a ondulação de líquidos esteja ativada." + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Quanto tempo o servidor esperará antes de descarregar mapblocks não usados, " +"declarados em segundos.\n" +"O valor mais alto é mais suave, mas usará mais RAM." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" +"O quanto se é atrasado ao mover-se dentro de um líquido.\n" +"Diminua isto para aumentar a resistência do líquido ao movimento." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Quão largos serão os rios." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Ruído de mistura de umidade" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Ruído de umidade" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Variação de umidade dos biomas." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "Servidor IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Se o FPS for mais elevado do que isso, limitá-lo dormindo\n" +"para não gastar a potência da CPU desnecessariamente." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Se estiver desativado, a tecla \"especial\" será usada para voar rápido se " +"modo voo e rápido estiverem\n" +"ativados." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Se ativado, o servidor executará a seleção de oclusão de bloco de mapa com " +"base \n" +"na posição do olho do jogador. Isso pode reduzir o número de blocos enviados " +"ao \n" +"cliente de 50 a 80%. O cliente ja não será invisível, de modo que a " +"utilidade do \n" +"modo \"noclip\" (modo intangível) será reduzida." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Se ativado com o modo de vôo, o jogador é capaz de voar através de cubos " +"sólidos.\n" +"Isto requer o privilégio \"noclip\" no servidor." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Se ativado, a tecla \"especial\" em vez de \"esgueirar\" servirá para\n" +"descer." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Se ativado, o registro da conta será separado do login na interface do " +"usuário.\n" +"Se desativadas, novas contas serão registradas automaticamente ao fazer " +"login." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Se ativado, as ações são registadas para reversão.\n" +"Esta opção só é lido quando o servidor é iniciado." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Se ativado, desativa prevenção de fraude no modo mult-ijogador." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Se ativado, dados inválidos do mundo não vão fazer o servidor desligar.\n" +"Só ative isto, se souber o que está a fazer." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Se ativado, faz com que os movimentos sejam relativos ao pitch do jogador " +"quando a voar ou a nadar." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Se ativado, novos jogadores não podem entrar com uma palavra-passe vazia." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Se ativado, você pode colocar blocos na posição (pés + nível dos olhos) onde " +"você está.\n" +"Isto é útil quando se trabalha com nodeboxes em pequenas áreas." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Se a restrição de CSM para o alcançe de nós está ativado, chamadas get_node " +"são \n" +"limitadas a está distancia do jogador até o nó." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Se a execução de um comando de chat demorar mais do que o tempo especificado " +"em\n" +"segundos, adicione a informação do tempo na mensagem-comando" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Se o tamanho do ficheiro do debug.txt exceder a quantidade de megabytes " +"especificado \n" +"nesta configuração quando é aberta, o ficheiro é movido para debug.txt.1,\n" +"apagando um debug.txt.1 mais antigo, se existir.\n" +"debug.txt só é movido se esta configuração for positiva." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" +"Se isso for definido, os jogadores vão sempre (re)desovar na posição " +"determinada." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ignorar erros do mundo" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Valor alfa do fundo do console do bate-papo no jogo (opacidade, entre 0 e " +"255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Côr de fundo da consola de conversação (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"Valor alfa do fundo do console do bate-papo no jogo (opacidade, entre 0 e " +"255)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Tecla da consola" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Velocidade vertical inicial ao saltar, em nós por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Monitoração imbutida.\n" +"Isto é usualmente apenas nessesário por contribuidores core/builtin" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "Comandos de chat de instrumentos no registro." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Monitorar de chamadas de retorno globais durante a registração.\n" +"(qualquer coisa que você passar ao minetest.register_*() function)" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Monitorar a ação de ação do Active Block Modifiers durante a registração." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Monitorar a ação de ação do Loading Block Modifiers durante a registração." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Monitorar os métodos das entidades durante a registração." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Intervalo para cada salvamento de alterações importantes no mundo, indicado " +"em segundos." + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" +"Intervalo de envio de hora do dia para os clientes, indicados em segundos." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animações dos itens do inventário" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Tecla de inventário" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Inverter rato" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Inverte o movimento vertical do rato." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Caminho da fonte em itálico" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Caminho da fonte em itálico monoespaçada" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Tempo de vida de itens largados" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Monitorização" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Iterações da função recursiva.\n" +"Aumentando isso aumenta a quantidade de detalhes, mas também\n" +"aumenta o tempo de processamento.\n" +"Com iterações = 20, esse gerador de mapa tem um tempo de carregamento " +"similar ao gerador V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID do Joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Intervalo de repetição do botão do Joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "\"Zona morta\" do joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Sensibilidade do frustum do Joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Tipo do Joystick" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Apenas para a configuração de Julia.\n" +"Componente W da constante hipercomplexa.\n" +"Determinando o formato do fractal.\n" +"Não tem nenhum efeito em fractais 3D.\n" +"varia aproximadamente entre -2 e 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Apenas para configuração de Julia.\n" +"Componente X da constante hipercomplexa.\n" +"Altera o formato do fractal.\n" +"Varia aproximadamente entre -2 e 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Apenas para configuração de Julia.\n" +"Componente em Y da constante hipercomplexa.\n" +"Altera a forma do fractal.\n" +"Alcance aproximado de -2 a 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Apenas para configuração de Julia.\n" +"Componente Z da constante hipercomplexa.\n" +"Altera o formato do fractal.\n" +"Varia aproximadamente entre -2 e 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Tecla de saltar" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Velocidade de Pulo" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para diminuir o alcance de visão.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a esquerda.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para escavar. \n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para deixar cair o item atualmente selecionado.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para aumentar o alcance de visão.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a esquerda.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para pular. \n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover-se rápido no modo rápido. \n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para trás.\n" +"Também ira desativar o andar para frente automático quando ativo.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a frente.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a esquerda.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a direita.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a esquerda.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir a janela de bate-papo para digitar comandos.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a frente.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir a janela de bate-papo.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir o inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para pôr objetos. \n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 11th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 12th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 13th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 14th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 15th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 16th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 17th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 18th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 19th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 20th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 21st slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 22nd slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 23rd slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 24th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 25th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 26th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 27th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 28th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 29th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 30th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 31st slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 32nd slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o oitavo slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o quinto slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o primeiro slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o quarto slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a esquerda.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o nono slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a esquerda.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o segundo slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o sétimo slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o sexto slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o décimo slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o terceiro slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla por esgueirar.\n" +"Também usado para descer e descendente na água se aux1_descends está " +"desativado.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para comutação entre câmara de primeira e terceira pessoa.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para tirar fotos do ecrã.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar o modo avanço automático.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar modo cinematográfico.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar a exibição do mini-mapa.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar o modo rápido.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar a voar.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar modo noclip.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar o modo pitch.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar a atualização da câmara. Usado para desenvolvimento.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar a exibição do bate-papo.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar a exibição de informações de depuração.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar a exibição da névoa.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar a a exibição do HUD.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar exibição do bate-papo.\n" +"Ver http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar a exibição do profiler. Usado para o " +"desenvolvimento.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar o alcance de visão ilimitado.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a esquerda.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "Expulsar jogadores que enviaram mais de X mensagem por 10 segundos." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Inclinação dos lagos no gerador de mapa plano" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Limite de lagos no gerador de mapa plano" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Linguagem" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Profundidade de cavernas grandes" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Quantidade máxima de cavernas grandes" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Quantidade mínima de cavernas grandes" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Proporção inundada de cavernas grandes" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Tecla da consola" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Estilo de folhas" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Estilo de folhas:\n" +"- Fancy: todas as faces visíveis\n" +"- Simple: apenas faces externas, se definidos special_tiles são usados\n" +"- Opaque: desativa transparência" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Tecla para a esquerda" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Duração de um tick do servidor e o intervalo no qual os objetos são " +"geralmente atualizados ao longo\n" +"rede, declarada em segundos." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Comprimento das ondas líquidas.\n" +"Requer que a ondulação de líquidos esteja ativada." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" +"Duração do tempo entre ciclos de execução do Active Block Modifier (ABM), " +"indicado em segundos." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" +"Duração do tempo entre ciclos de execução do NodeTimer, indicado em segundos." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" +"Duração do tempo entre ciclos ativos de gestão de blocos, indicado em " +"segundos." + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Nível de registro log a ser guardado em debug.txt:\n" +"- <nothing> (nada registrado)\n" +"- none (mensagens sem nível de log)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Aumento da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Centro do aumento da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Extensão do aumento da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Gamma da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Gradiente alto da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Gradiente baixo da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "Iluminação" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Limite de geração de mapas, em nós, em todas as 6 direções de (0, 0, 0).\n" +"Apenas áreas completas de mapa dentro do limite do mapgen são gerados.\n" +"O valor é armazenado por mundo." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Limite quantidade de solicitações HTTP paralelas. afeta:\n" +"- Media buscar se servidor usa configuração de remote_media.\n" +"- Descarrega de lista de servidores e anúncio do servidor.\n" +"- Transferências realizadas pelo menu principal (por exemplo, gerência de " +"mods).\n" +"Só tem efeito se compilado com cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Fluidez líquida" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Suavização do fluido líquido" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Limite de iteração do liquido" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Tempo para limpar a lista de espera para a atualização de líquidos" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Afundamento de líquidos" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Intervalo de atualização de líquido em segundos." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Período de atualização dos Líquidos" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Carregar o analizador do jogo" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Carregar o analizador do jogo para coletar dados de analize do jogo\n" +"Providencia o comando /profiler para acessar a analize compiliada.\n" +"Muito util para desenvolvedores de mods e operadores de servidores." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "A carregar modificadores de blocos" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Menor limite Y de dungeons." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Menor limite Y de ilhas flutuantes." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Menu principal de scripts" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Fazer cores de névoa e céu dependerem do dia (amanhecer/pôr do sol) e exibir " +"a direção." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Torna todos os líquidos opacos" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Nível de Compressão de Mapa no Armazenamento em Disco" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Nível de Compressão do Mapa na Transferência em Rede" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Diretório do mapa" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Atributos de geração de mapa específicos ao gerador Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Atributos de geração de mapas específicos para o Gerador de mundo Plano.\n" +"Lagos e colinas ocasionalmente podem ser adicionados ao mundo plano." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Atributos de geração de mapas específicos para o Gerador de mundo Fractal.\n" +"'terreno' permite a geração de terreno não fractal:\n" +"oceano, ilhas e subterrâneos." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Atributos de geração de mapa específicos ao gerador Valleys.\n" +"'altitude_chill': Reduz o calor com a altitude.\n" +"'humid_rivers': Aumenta a humidade à volta de rios.\n" +"'profundidade_variada_rios': se ativado, baixa a humidade e alto calor faz \n" +"com que rios se tornem mais rasos e eventualmente sumam.\n" +"'altitude_dry': reduz a humidade com a altitude." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Atributos de geração de mapa específicos ao gerador V5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Atributos de geração de mapas específicos do Mapgen v6.\n" +"A marcação \"snowbiomes\" ativa o novo sistema de 5 biomas.\n" +"Quando a marcação 'snowbiomes' está ativada, as selvas são automaticamente " +"ativadas e\n" +"a marcação 'selvas' é ignorada." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Atributos de geração de mapas específicos para Gerador de mapas v7.\n" +"'ridges': rios.\n" +"'floatlands': massas de terra flutuantes na atmosfera.\n" +"'caverns': cavernas gigantes no subsolo." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Limite de geração de mapa" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Intervalo de salvamento de mapa" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "Quadros de atualização de sombras do mapa" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Limite de mapblock" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Limite de geração de mapa" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" +"Tamanho em MB da memória cache de MapBlock para o gerador de Malha de " +"Mapblock" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Tempo limite de descarregamento do mapblock" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Gerador de mundo Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Flags específicas do gerador do mundo Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Gerador de mundo plano" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Flags específicas do gerador de mundo plano" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Gerador de mundo Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Marcações específicas do Mapgen Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Gerador de mundo V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Flags específicas do gerador de mundo V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Gerador de mundo V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Flags específicas do gerador de mundo V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Gerador de mundo V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Flags específicas do gerador de mundo V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Vales do mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Flags específicas do gerador de mundo Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Depuração do gerador de mapa" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Nome do gerador de mapa" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Distância máxima de geração de bloco" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Distância máxima de envio de bloco" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Máximo de líquidos processados por etapa." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Max. clearobjects blocos extras" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Max. pacotes por iteração" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "FPS máximo" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"FPS máximo quando a janela não está com foco, ou quando o jogo é pausado." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Máximo de blocos carregados forçadamente" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Largura máxima da hotbar" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" +"Limite máximo da quantidade aleatória de cavernas grandes por mapchunk." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" +"Limite máximo da quantidade aleatória de cavernas pequenas por mapchunk." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Resistência líquida máxima. Controla desaceleração ao entrar num líquido\n" +"em alta velocidade." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Número máximo de blocos que são enviados simultaneamente por cliente.\n" +"O total máximo é calculado dinamicamente:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" +"Número máximo de blocos que podem ser enfileirados para o carregamento." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Quantidade máxima de blocos a serem enfileirados, dos que estão para ser " +"gerados.\n" +"Esse limite é forçado para cada jogador." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Quantdade máxima de blocos a serem enfileirados, dos que estão para ser " +"carregados do ficheiro.\n" +"Esse limite é forçado para cada jogador." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Quantidade máxima de descarregas paralelas. Descarregas a exceder esse " +"limite esperarão numa fila.\n" +"Deve ser menor que curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Número máximo de chunks carregados forçadamente." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Número máximo de mapblocks para o cliente para ser mantido na memória.\n" +"Definido como -1 para quantidade ilimitada." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Número máximo de pacotes enviados por etapa de envio, se tiver uma conexão " +"lenta\n" +"tente reduzi-lo, mas não o reduza para um número abaixo do dobro do alvo\n" +"número de cliente." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Número máximo de jogadores que podem se conectar simultaneamente." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Número máximo de mensagens recentes mostradas" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Número máximo de objetos estaticamente armazenados num bloco." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Limite maximo de objetos por bloco" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Proporção máxima da janela atual a ser usada para hotbar.\n" +"Útil se houver algo para ser exibido a direito ou esquerda do hotbar." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Máximo de blocos enviados simultaneamente por cliente" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Tamanho máximo da fila do chat" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Tamanho máximo da fila do chat.\n" +"0 para desativar a fila e -1 para a tornar ilimitada." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Tempo máximo em ms para descarregar ficheiros (por exemplo, um mod) pode " +"tomar." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Tempo máximo que um pedido interativo (ex: busca de lista de servidores) " +"pode levar, em milissegundos." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Limite de utilizadores" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Cache de malha" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Mensagem do dia" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Mensagem do dia exibida aos jogadores ao conectar." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Método usado para destacar o objeto selecionado." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Nível mínimo de registo a ser impresso no chat." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Mini-mapa" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Tecla mini-mapa" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Altura de varredura do mini-mapa" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" +"Limite mínimo da quantidade aleatória de grandes cavernas por mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" +"Limite mínimo da quantidade aleatória de cavernas pequenas por mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Tamanho mínimo da textura" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mapeamento MIP" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "Mod Profiler" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "Segurança do Mod" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Canais de mod" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Modifica o tamanho dos elementos do hudbar." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Caminho de fonte monoespaçada" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Tamanho da fonte monoespaçada" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "Tamanho de letra monoespaçada divisível por" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Parâmetros ruido da altura de montagem do gerador de mundo v7" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Ruído da montanha" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Ruído de variação da montanha" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Nível zero da montanha" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Sensibilidade do rato" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Multiplicador de sensibilidade do rato." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Ruído de Lama" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Multiplicador para cair balançando.\n" +"Por exemplo: 0 para não ver balançando; 1.0 para normal; 2.0 para duplo." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Tecla de usar" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Mutar som" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Nome do gerador de mapas a ser usado na criação de um novo mundo.\n" +"Criar um mundo no menu principal irá sobrepor-se a isto.\n" +"Mapgens atuais num estado altamente instável:\n" +"- As floatlands opcionais da v7 (desativadas por padrão)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Nome do jogador.\n" +"Quando executando um servidor, os clientes com este nome são " +"administradores.\n" +"Quando iniciado pelo menu principal, este é substituido." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Nome do servidor, a ser exibido quando os jogadores abrem a lista de " +"servidores." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Plano próximo" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Porta de rede para receber dados (UDP).\n" +"Esse valor será substituído se for definido a partir do menu principal." + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "Rede" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Novos jogadores precisam de introduzir esta palavra-passe." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Atravessar blocos" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Tecla Noclip" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "Nó e Entidade em Destaque" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Destacando cubos" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Intervalo de NodeTimer" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Ruidos" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Número de seguimentos de emersão" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Quantidade de threads de emersão a serem usadas.\n" +"Valor 0:\n" +"- Seleção automática. A quantidade de threads de emersão será\n" +"- 'quantidade de processadores - 2', com um limite inferior de 1.\n" +"Qualquer outro valor:\n" +"- Especifica a quantidade de threads de emersão, com um limite inferior de " +"1.\n" +"AVISO: Aumentar a quantidade de threads de emersão aumenta a velocidade do " +"motor de\n" +"geração de mapas, mas isso pode prejudicar o desempenho do jogo, a " +"interferir com outros\n" +"processos, especialmente em singleplayer e / ou ao executar código Lua em " +"eventos\n" +"'on_generated'. Para muitos utilizadores, a configuração ideal pode ser '1'." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Quantidde de blocos adicionais que podem ser carregados por /clearobjects ao " +"mesmo tempo.\n" +"Esta é uma troca entre sobrecarga de transação do sqlite e\n" +"consumo de memória (4096 = 100 MB, como uma regra de ouro)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Líquidos Opacos" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "Opacidade (alpha) das sombras atrás da fonte padrão, entre 0 e 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Abre o menu de pausa quando o foco da janela é perdido.Não pausa se um " +"formspec está\n" +"aberto." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Substituição opcional da cor de ligações do bate-papo." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Caminho da fonte de fallback. Deve ser uma fonte TrueType.\n" +"Essa fonte será usada para determinados idiomas ou se a fonte padrão não " +"estiver disponível." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Caminho para gravar capturas de ecrã. Pode ser absoluto ou relativo.\n" +"A pasta será criada se já não existe." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Caminho para o diretório \"shader\". Se nenhum caminho estiver definido, o " +"local padrão será usado." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" +"Caminho para o diretório de texturas. Todas as texturas são pesquisadas " +"primeiro daqui." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Caminho para a fonte padrão. Deve ser uma fonte TrueType.\n" +"A fonte de fallback será usada se a fonte não puder ser carregada." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Caminho para a fonte monoespaçada. Deve ser uma fonte TrueType.\n" +"Esta fonte é usada para, por exemplo, a tela do console e do profiler." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Pausa quando o foco da janela é perdido" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" +"Limite de blocos na fila de espera de carregamento do disco por jogador" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Limite por jogador de blocos enfileirados para gerar" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Física" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Tecla de movimento pitch" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Modo movimento pitch" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Tecla de pôr" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Intervalo de repetição da ação pôr" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"O jogador é capaz de voar sem ser afetado pela gravidade.\n" +"Isso requer o privilégio \"fly\" no servidor." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Distância de transferência do jogador" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Jogador contra jogador" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Filtragem de Poisson" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Porta para conectar (UDP).\n" +"Note que o campo Porta no menu principal substitui essa configuração." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Evita remoção e colocação de blocos repetidos quando os botoes do rato são " +"seguros.\n" +"Ative isto quando cava ou põe blocos constantemente por acidente." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Impede que mods façam coisas inseguras como executar comandos do shell." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Intervalo de impressão de dados do analisador (em segundos).\n" +"0 = desativado. Útil para desenvolvedores." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Privilégios que jogadores com basic_privs podem conceder" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Analizador" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Tecla de alternância do Analizador" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Endereço do Prometheus" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Endereço do Prometheus\n" +"Se o minetest for compilado com a opção ENABLE_PROMETHEUS ativa,\n" +"ativa a obtenção de métricas do Prometheus neste endereço.\n" +"As métricas podem ser obtidas em http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Proporção de cavernas grandes que contém líquido." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Raio da área de nuvens indicado em número de 64 cubos de nuvem.\n" +"Valores superiores a 26 produzem arestas acentuadas nos cantos das nuvens." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Eleva o terreno para fazer vales em torno dos rios." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Entrada aleatória" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Tecla para modo de visão ilimitado" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Mensagens de chat recentes" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Caminho da fonte regular" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Mídia remota" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Porta remota" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Remove códigos de cor de futuras mensagens do chat.\n" +"Use isto para impedir que jogadores usem cor em suas mensagens" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Substitui o menu principal padrão por um personalizado." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Diretório para logs" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Restringe o acesso de certas funções a nível de cliente em servidores.\n" +"Combine os byflags abaixo par restringir recursos de nível de cliente, ou " +"coloque 0\n" +"para nenhuma restrição:\n" +"LOAD_CLIENT_MODS: 1 (desativa o carregamento de mods de cliente)\n" +"CHAT_MESSAGES: 2 (desativa a chamada send_chat_message no lado do cliente)\n" +"READ_ITEMDEFS: 4 (desativa a chamada get_item_def no lado do cliente)\n" +"READ_NODEDEFS: 8 (desativa a chamada get_node_def no lado do cliente)\n" +"LOOKUP_NODES_LIMIT: 16 (limita a chamada get_node no lado do cliente para\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (desativa a chamada get_player_names no lado do cliente)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Ruído de extensão do cume de montanhas" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Ruido do Rio" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Ruído Subaquático" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Ruído do tamanho de montanhas acidentadas" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Tecla para a direita" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Profundidade do canal do rio" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Largura do canal do rio" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Profundidade do Rio" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Ruido do Rio" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Tamanho do Rio" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Largura do vale do rio" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Gravação de reversão" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Tamanho do ruído de colinas rolantes" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Extensão do ruído de colinas rolantes" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Mini-map redondo" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Remoção e colocação segura" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Praias de areia ocorrem quando \"np_beach\" excede esse valor." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Salvar o mapa recebido pelo cliente no disco." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Salve automaticamente o tamanho da janela quando modificado." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Salvado mapa recebido do servidor" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Escala de GUI por um valor especificado pelo utilizador.\n" +"Use um filtro nearest-neighbor-anti-alias para escala do GUI.\n" +"Isso irá suavizar algumas das arestas e misturar pixels \n" +"quando a escala é reduzida, ao custo de borrar alguns pixels da borda \n" +"quando as imagens são dimensionadas em tamanhos não inteiros." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Ecrã" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Altura do ecrã" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Largura do ecrã" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Pasta de screenshot" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Formato da captura de ecrã" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Qualidade da Captura de ecrã" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Qualidade de imagem. Usado somente para o formato JPEG.\n" +"1 significa pior qualidade; 100 significa melhor qualidade.\n" +"Use 0 para qualidade padrão." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Captura de ecrã" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Ruído para cavernas #1" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Segundo de 4 ruídos 2D que juntos definem a altura de colinas/montanhas." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Segundo de 2 ruídos 3D que juntos definem tunéis." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Consulte http://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Cor da borda da caixa de seleção (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Cor da caixa de seleção" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Largura da caixa de seleção" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Escolha um dos 18 tipos de fractais.\n" +"1 = Conjunto de mandelbrot \"Roundy\" 4D.\n" +"2 = Conjunto de julia \"Roundy\" 4D.\n" +"3 = Conjunto de mandelbrot \"Squarry\" 4D.\n" +"4 = Conjunto de julia \"Squarry\" 4D.\n" +"5 = Conjunto de mandelbrot \"Mandy Cousin\" 4D.\n" +"6 = Conjunto de julia \"Mandy Cousin\" 4D.\n" +"7 = Conjunto de mandelbrot \"Variation\" 4D.\n" +"8 = Conjunto de julia \"Variation\" 4D.\n" +"9 = Conjunto de mandelbrot \"Mandelbrot/Mandelbar\" 3D.\n" +"10 = Conjunto de julia \"Mandelbrot/Mandelbar\" 3D.\n" +"11 = Conjunto de mandelbrot \"Árvore de natal\" 3D.\n" +"12 = Conjunto de julia \"Árvore de natal\" 3D..\n" +"13 = Conjunto de mandelbrot \"Bulbo de Mandelbrot\" 3D.\n" +"14 = Conjunto de julia \"Bulbo de Mandelbrot\" 3D.\n" +"15 = Conjunto de mandelbrot \"Bulbo de Mandelbrot Cosseno\" 3D.\n" +"16 = Conjunto de julia \"Bulbo de Mandelbrot Cosseno\" 3D.\n" +"17 = Conjunto de mandelbrot \"Bulbo de Mandelbrot\" 4D.\n" +"18 = Conjunto de julia \"Bulbo de Mandelbrot\" 4D." + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "Servidor" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "Jogabilidade do servidor" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "Segurança do Servidor" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL do servidor" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Endereço do servidor" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Descrição do servidor" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Nome do servidor" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Porta do servidor" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Separação de oclusão no lado do servidor" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "Desempenho do Servidor/Env" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL da lista de servidores" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "Lista de servidores e MOTD" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Ficheiro da lista de servidores" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Defina o idioma. Deixe vazio para usar a linguagem do sistema.\n" +"Apos mudar isso uma reinicialização é necessária." + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Defina o comprimento máximo de uma mensagem de chat (em caracteres) enviada " +"por clientes." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Coloque a força da sombra gama.\n" +"Ajusta a intensidade das sombras dinâmicas no jogo.\n" +"Valor mais baixo significa sombras mais claras, maior valor significa " +"sombras mais escuras." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Defina o tamanho do raio de sombras suaves.\n" +"Valores mais baixos significam sombras mais nítidas e valores altos sombras " +"suaves.\n" +"Valor mínimo 1.0 e valor máximo 10.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Defina a inclinação da órbita do Sol/Lua em graus\n" +"Valor 0 significa sem inclinação/ órbita vertical.\n" +"Valor mínimo de 0.0 e máximo de 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Defina para true para ativar o Mapeamento de Sombras.\n" +"Requer sombreadores para ser ativado." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Definido como true ativa o balanço das folhas.\n" +"Requer que os sombreadores estejam ativados." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Definido como true permite ondulação de líquidos (como a água).\n" +"Requer que os sombreadores estejam ativados." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Definido como true permite balanço de plantas.\n" +"Requer que os sombreadores estejam ativados." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Define a qualidade da textura das sombras para 32 bits.\n" +"Quando false, a textura de 16 bits será usada\n" +"Isso pode fazer com que muito mais coisas aparecam nas sombras." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Sombras" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Sombreadores permitem efeitos visuais avançados e podem aumentar a " +"performance em algumas placas de\n" +"vídeo.\n" +"Só funcionam com o modo de vídeo OpenGL." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Qualidade do filtro de sombras" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "Distância do mapa de sombras em nodes para renderizar sombras" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "Textura do mapa de sombras em 32 bits" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Tamanho da textura do mapa de sombras" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Distância (em pixels) da sombra da fonte padrão. Se 0, então a sombra não " +"será desenhada." + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "Força da sombra gamma" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Formato do mini-mapa. Ativado = redondo, desativado = quadrado." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Mostrar informação de depuração" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Mostrar as caixas de seleção entidades" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Mostrar caixas de seleção de entidades\n" +"É necessário reiniciar após alterar isso." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Mostrar plano de fundo da nametag por padrão" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Mensagem de desligamento" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Tamanho dos mapchunks gerados pelo gerador de mapa, em mapblocks(16 nós).\n" +"ALERTA!: Não há benefício e existem diversos perigos em\n" +"aumentar este valor acima de 5.\n" +"Reduzir este valor aumenta a densidade de dungeons e cavernas.\n" +"Alterar este valor é para uso especial, é recomendado deixar\n" +"inalterado." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Tamanho da memória cache do MapBlock do gerador de malha. Aumentar isso " +"aumentará\n" +"o percentual de hit do cache %, a reduzir os dados que são copiados do " +"encadeamento principal,\n" +"e assim reduz o jitter." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Inclinação Da Órbita Do Céu" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Fatia w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Inclinação e preenchimento trabalham juntos para modificar as alturas." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Quantidade máxima de cavernas pequenas" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Quantidade mínima de cavernas pequenas" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" +"Variação de umidade em pequena escala para misturar biomas nas fronteiras." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" +"Variação de temperatura em pequena escala para misturar biomas nas bordas." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Iluminação suave" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Suaviza o movimento da câmara quando olhando ao redor. Também chamado de " +"olhar ou suavização do rato.\n" +"Útil para gravar vídeos." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "Suaviza a rotação da câmara no modo cinemático. 0 para desativar." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Suaviza a rotação da câmara. 0 para desativar." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Tecla para agachar" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Velocidade da furtividade" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Velocidade furtiva, em nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Raio das sombras suaves" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Som" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Especifica a URL no qual os clientes buscam a mídia ao em vez de usar o " +"UDP.\n" +"$filename deve ser acessível de $remote_media$filename via cURL \n" +"(obviamente, remote_media deve terminar com uma barra \"/\").\n" +"Ficheiros que não estão presentes serão obtidos da maneira usual por UDP." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Especifica o tamanho padrão da pilha de nós, items e ferramentas.\n" +"Note que mods e games talvez definam explicitamente um tamanho para certos " +"(ou todos) os itens." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Ampliação da faixa de aumento da curva de luz.\n" +"Controla a largura do intervalo a ser aumentado.\n" +"O desvio padrão da gaussiana do aumento da curva de luz." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Ponto de spawn estático" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Ruído de declive" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Tamanho do ruído da montanha de passo" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Extensão do ruído da montanha de passo" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Força da paralaxe do modo 3D." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Aumento da força da curva de luz.\n" +"Os 3 parâmetros de 'aumento' definem uma faixa\n" +"da curva de luz que é aumentada em brilho." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Verificação rígida de protocolo" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Códigos de faixa de cor" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Nível de superfície de água opcional posta numa camada sólida de flutuação.\n" +"A água está desativada por padrão e só será posta se este valor for " +"definido\n" +"acima de 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (o início do\n" +"afilamento superior).\n" +"*** AVISO, POTENCIAL PERIGO PARA OS MUNDOS E DESEMPENHO DO SERVIDOR ***:\n" +"Ao ativar a colocação de água, as áreas flutuantes devem ser configuradas e " +"testadas\n" +"para ser uma camada sólida, a definir 'mgv7_floatland_density' para 2.0 (ou " +"outro\n" +"valor necessário a depender de 'mgv7_np_floatland'), para evitar\n" +"fluxo de água extremo intensivo do servidor e para evitar grandes inundações " +"do\n" +"superfície do mundo abaixo." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "SQLite síncrono" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Variação de temperatura para biomas." + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "Configurações Temporárias" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Ruído alternativo do terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Altura do terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Altura do terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Altura do terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Altura do terreno" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Limite de ruido de terreno para colinas.\n" +"Proporção de controles da área de mundo coberta pelas colinas.\n" +"Ajuste no sentido 0,0 para uma proporção maior." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Limite de ruido de terreno para Lagos.\n" +"Proporção de controles da área de mundo coberta por lagos.\n" +"Ajuste no sentido 0,0 para uma proporção maior." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Ruído de persistência do terreno" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Caminho para a pasta de texturas" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Tamanho da textura em que o mapa de sombras será renderizado em.\n" +"Deve ser um múltiplo de dois.\n" +"Números maiores criam sombras melhores mas também esvazia a conta do banco." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Texturas num nó podem ser alinhadas ao próprio nó ou ao mundo.\n" +"O modo antigo serve melhor para coisas como maquinas, móveis, etc, enquanto\n" +"o novo faz com que escadas e microblocos encaixem melhor a sua volta.\n" +"Entretanto, como essa é uma possibilidade nova, não deve ser usada em " +"servidores antigos,\n" +"essa opção pode ser forçada para certos tipos de nós. Note que esta\n" +"opção é considerada EXPERIMENTAL e pode não funcionar adequadamente." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "A url para o repositório de conteúdo" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "A zona morta do joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"O formato padrão no qual as análises estão a ser gravadas,\n" +"Quando chamado `/profiler save [formato]` sem formato." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "A profundidade do preenchimento de terra ou outro enchimento de bioma." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"O caminho de ficheiro relativo ao sua pasta do mundo no qual as analises " +"serão salvas." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "O identificador do joystick para usar" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"A largura em pixels necessária para a interação de ecrã de toque começar." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"A altura máxima da superfície de líquidos com ondas.\n" +"4.0 = Altura da onda é dois nós.\n" +"0.0 = Onda nem se move.\n" +"O padrão é 1.0 (meio nó).\n" +"Requer ondas em líquidos ativada." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "A interface de rede no qual o servidor escuta (aguarda conexão)." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Os privilégios que novos utilizadores obtém automaticamente.\n" +"Consulte /privs no jogo para obter uma lista completa na configuração do seu " +"servidor e dos modificadores." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"O raio do volume dos blocos em torno de cada jogador que está sujeito ao\n" +"material de bloco ativo, declarado em mapblocks (16 nós).\n" +"Nos blocos ativos, os objetos são carregados e os ABMs executados.\n" +"Este também é o intervalo mínimo no qual os objetos ativos (mobs) são " +"mantidos.\n" +"Isso deve ser configurado junto com active_object_send_range_blocks." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"O back-end de renderização.\n" +"É necessário reiniciar após alterar isso.\n" +"Nota: No Android, use OGLES1 se não tiver certeza! A app pode falhar ao " +"iniciar de outra forma.\n" +"Em outras plataformas, OpenGL é recomendado.\n" +"Shaders são suportados por OpenGL (somente desktop) e OGLES2 (experimental)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"A sensibilidade dos eixos do joystick para movimentar o \n" +"frustum de exibição no jogo." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"A intensidade (escuridão) de sombreamento da oclusão de ambiente no bloco.\n" +"Inferior é mais escura, superior é mais clara. O intervalo válido de valores " +"para esta\n" +"configuração é 0.25 a 4.0. Se o valor está fora do intervalo ele será \n" +"definido o valor válido mais próximo." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"O tempo (em segundos) que a fila de líquidos pode crescer além da " +"capacidade \n" +"de processamento até que é feita uma tentativa para diminuir o seu tamanho " +"pelo despejo \n" +"de antigas filas de itens. Um valor 0 desativa a funcionalidade." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"O tempo em segundos que leva entre eventos repetidos \n" +"quando pressionando uma combinação de botão no joystick." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"O tempo em segundos que leva entre as colocações de nó repetidas ao segurar\n" +"o botão de pôr." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "O tipo do joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"A distância vertical onde o calor cai por 20 caso 'altitude_chill' esteja \n" +"ativado. Também é a distância vertical onde a humidade cai por 10 se \n" +"'altitude_dry' estiver ativado." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Terceiro de 4 ruídos 2D que juntos definem a altura de colinas/montanhas." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Durabilidade em segundos de objectos largados.\n" +"Definir como -1 para desativar funcionalidade." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "Hora do dia quando um novo mundo é iniciado, em milihoras (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Intervalo de tempo de envio" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Velocidade de tempo" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Tempo limite para o cliente remover dados de mapa não utilizados da memória, " +"em segundos." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Para reduzir a latência, a transferência de blocos é abrandada quando um " +"jogador está \n" +"a construir. Isto determina o quanto é abrandado após a colocação de um cubo." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Tecla de alternância do modo de câmara" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Atraso de dica de ferramenta" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Limiar o ecrã de toque" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "Tela sensível ao toque" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Ruido de árvores" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Filtro tri-linear" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"Útil para suavizar o minimapa em máquinas mais lentas." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Modulos confiáveis" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL da lista de servidores exibida no separador multi-jogador." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Subamostragem" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"A subamostragem é semelhante à utilização de uma resolução de ecrã mais " +"baixa, mas aplica-se\n" +"apenas para o mundo do jogo, mantendo a GUI intacta.\n" +"Deve dar um impulso significativo de desempenho ao custo de uma imagem menos " +"detalhada.\n" +"Valores mais altos resultam numa imagem menos detalhada." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Distância de transferência do jogador ilimitada" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Descarregar os dados do servidor não utilizados" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Limite topo Y de dungeons." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Limite máximo Y para as ilhas flutuantes." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Usar nuvens 3D em vez de planas." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Usar uma animação de nuvem para o fundo do menu principal." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "Usar filtragem anisotrópica quando visualizar texturas de um ângulo." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Usar filtragem bilinear ao dimensionamento de texturas." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Usar mip mapping para escalar texturas. Pode aumentar a performance " +"levemente,\n" +"especialmente quando usando um pacote de texturas em alta resolução.\n" +"O downscaling correto de gama não é suportado." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Use o anti-serrilhamento de várias amostras (MSAA) para suavizar as bordas " +"do bloco.\n" +"Este algoritmo suaviza a janela de visualização 3D enquanto mantém a imagem " +"nítida,\n" +"mas não afeta o interior das texturas\n" +"(que é especialmente perceptível com texturas transparentes).\n" +"Espaços visíveis aparecem entre os nós quando os sombreadores são " +"desativados.\n" +"Se definido como 0, MSAA é desativado.\n" +"É necessário reiniciar após alterar esta opção." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Use a filtragem trilinear ao dimensionamento de texturas." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Sincronização Vertical" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Profundidade do vale" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Preenchimento do vale" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Perfil do vale" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Encosta do vale" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Variação da profundidade de preenchimento do bioma." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Variação da altura máxima da montanha (nos nós)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Variação do número de cavernas." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Variação da escala vertical do terreno.\n" +"Quando o ruído é menor que -0,55 o terreno é quase plano." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Varia a profundidade dos nós da superfície do bioma." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Varia a aspereza do terreno.\n" +"Define o valor de 'persistência' para os ruídos \"terrain_base\" e " +"\"terrain_alt\"." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Controla a inclinação/altura das colinas." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Velocidade de subida vertical, em nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Sincronização vertical do ecrã." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Driver de vídeo" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Visualização de balanço" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Distância de visualização, em cubos." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Tecla de diminuição do raio de exibição" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Tecla de aumento do intervalo de exibição" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Tecla de visão em zoom" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Intervalo de visualização" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "Joystick virtual ativa botão especial" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Volume do som" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Volume de todos os sons.\n" +"Requer que o sistema de som esteja ativado." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Coordenada W da fatia 3D gerada de um fractal 4D.\n" +"Determina qual fatia 3D da forma 4D é gerada.\n" +"Altera a forma do fractal.\n" +"Não tem efeito sobre fractais 3D.\n" +"Varia aproximadamente de -2 a 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Velocidade de marcha e de voo, em nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Velocidade de caminhada" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Velocidade de caminhada, vôo e escalada em modo rápido, em nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Nível de água" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Nível de superfície de água do mundo." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Cubos Ondulantes" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Folhas ondulantes" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Líquidos ondulantes" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Altura da onda nos líquidos ondulantes" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Velocidade de balanço da água" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Comprimento de balanço da água" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Balançar das Plantas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "Cor da caixa de seleção" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Quando gui_scaling_filter está ativado, todas as imagens do interface \n" +"gráfico são filtradas por software, mas algumas imagens são geradas \n" +"directamente para o hardware (e.g. texturas de cubos no inventário)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Quando gui_scaling_filter_txr2img é true, copie essas imagens\n" +"de hardware para software para dimensionamento. Quando false,\n" +"voltará para o velho método de dimensionamento, para drivers de\n" +"vídeo que não suportem propriedades baixas de texturas voltam do hardware." + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Ao usar filtros bilineares/trilinear/anisotrópica, texturas de baixa " +"resolução\n" +"podem ficar borradas, então automaticamente aumenta a escala deles com a " +"interpolação\n" +"de nearest-neighbor para preservar os pixels nítidos. Isto define o tamanho\n" +"mínimo da textura para as texturas melhoradas; valores mais altos parecem\n" +"mais nítidos, mas requerem mais memória. Potências de 2 são recomendadas.\n" +"Essa configuração superior a 1 pode não ter um efeito visível, a menos que a " +"\n" +"filtragem bilineares/trilinear/anisotrópica estejam habilitadas.\n" +"Isso também é usado como tamanho base da textura para auto-escalamento de " +"texturas." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"Determina se animações das texturas dos cubos devem ser dessincronizadas " +"entre mapblocks." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Se os jogadores são mostrados para os clientes sem qualquer limite de " +"distância.\n" +"Caso não desejar, use a configuração player_transfer_distance." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Se deseja permitir aos jogadores causar dano e matar uns aos outros." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Se deverá pedir ao cliente para se reconectar após um bloqueio de sistema " +"(Lua).\n" +"Defina como TRUE se o seu servidor está configurado para recomeçar " +"automaticamente." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Se for usar névoa no fim da área visível." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Quando mutar os sons. Pode mutar os sons a qualquer hora, a não ser\n" +"que o sistema de som esteja desativado (enable_sound=false).\n" +"No jogo, pode ativar o estado de mutado com o botão de mutar\n" +"ou a usar o menu de pausa." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"Se deve mostrar ao cliente informação de depuração (tem o mesmo efeito que " +"premir F5)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Componente de tamanho da janela inicial. Ignorado em modo de ecrã cheio." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Largura das linhas do bloco de seleção em torno de nodes." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Somente no sistemas Windows: Inicie o Minetest com a janela da linha de " +"comando em segundo plano.\n" +"Contém as mesmas informações que o ficheiro debug.txt (nome padrão)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Diretório de mundo (tudo no mundo está armazenado aqui).\n" +"Não é necessário se for iniciado a partir do menu principal." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Horário inicial do mundo" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Texturas alinhadas ao mundo podem ser escaladas em vários nós. Entretanto,\n" +"o servidor pode não enviar a escala desejada, especialmente se você usa\n" +"um pacote de textura especialmente projetado; com está opção, o cliente " +"tenta\n" +"determinar a escala automaticamente baseado no tamanho da textura.\n" +"Veja também texture_min_size.\n" +"Alerta: Esta opção é EXPERIMENTAL!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Modo de texturas alinhadas ao mundo" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Componente Y de terreno plano." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y da densidade gradiente zero de montanhas. Usado para deslocar montanhas " +"verticalmente." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Limite Y máximo de grandes cavernas." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" +"Distância em Y sobre a qual as cavernas se expandem até o tamanho total." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Distância de Y sobre a qual as ilhas flutuantes diminuem de densidade total " +"para nenhuma densidade.\n" +"O afunilamento começa nesta distância do limite Y.\n" +"Para uma ilha flutuante sólida, isso controla a altura das colinas / " +"montanhas.\n" +"Deve ser menor ou igual a metade da distância entre os limites Y." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Nível em Y da superfície média do terreno." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Nível em Y do limite superior da caverna." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Nível Y de terreno que cria penhascos." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Nível Y de terreno inferior e solo oceânico." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Nível Y do fundo do mar." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Tempo limite de descarregamento de ficheiro via cURL" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "tempo limite interativo cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "limite paralelo de cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "Modo Criativo: " + +#~ msgid "- Damage: " +#~ msgstr "-Dano: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = oclusão paralaxe com dados de inclinação (mais rápido).\n" +#~ "1 = mapeamento de relevo (mais lento, mais preciso)." + +#~ msgid "Address / Port" +#~ msgstr "Endereço / Porta" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Ajustar a gama de codificação para a tabela de claridade. Os números mais " +#~ "elevados são mais brilhantes.\n" +#~ "Esta configuração é somente para o cliente e é ignorada pelo servidor." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "" +#~ "Altera como terras flutuantes montanhosas afunilam acima e abaixo do " +#~ "ponto médio." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Tem a certeza que deseja reiniciar o seu mundo?" + +#~ msgid "Back" +#~ msgstr "Voltar" + +#~ msgid "Basic" +#~ msgstr "Básico" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bits por pixel (profundidade de cor) no modo de ecrã inteiro." + +#~ msgid "Bump Mapping" +#~ msgstr "Bump mapping" + +#~ msgid "Bumpmapping" +#~ msgstr "Bump mapping" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "Centro do aumento da curva de luz." + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Mudanças para a interface do menu principal:\n" +#~ "- Total: Múltiplos mundos de um jogador, escolha de jogo, escolha de " +#~ "pacote de texturas, etc.\n" +#~ "- Simples: Um mundo de um jogador, sem escolha de jogo ou pacote de " +#~ "texturas. Pode ser \n" +#~ "necessário para ecrãs menores." + +#~ msgid "Config mods" +#~ msgstr "Configurar mods" + +#~ msgid "Configure" +#~ msgstr "Configurar" + +#~ msgid "Connect" +#~ msgstr "Ligar" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Controla a velocidade de afundamento em líquido." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Controla a densidade do terreno montanhoso nas ilhas flutuantes.\n" +#~ "É um parâmetro adicionado ao valor de ruído 'mgv7_np_mountain'." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "Controla a largura dos túneis, um valor menor cria túneis maiores." + +#~ msgid "Credits" +#~ msgstr "Méritos" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Cor do cursor (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Dano ativado" + +#~ msgid "Darkness sharpness" +#~ msgstr "Nitidez da escuridão" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Tempo limite por defeito para cURL, em milissegundos.\n" +#~ "Só tem efeito se compilado com cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Define áreas de terra flutuante em terreno suavizado.\n" +#~ "Terrenos suavizados ocorrem quando o ruído é menor que zero." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Define nível de amostragem de textura.\n" +#~ "Um valor mais alto resulta em mapas normais mais suaves." + +#~ msgid "Del. Favorite" +#~ msgstr "Rem. Favorito" + +#~ msgid "" +#~ "Deprecated, define and locate cave liquids using biome definitions " +#~ "instead.\n" +#~ "Y of upper limit of lava in large caves." +#~ msgstr "" +#~ "Depreciar, definir e localizar líquidos de cavernas usando definições de " +#~ "biomas.\n" +#~ "Y do limite superior de lava em grandes cavernas." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Baixe um jogo, como Minetest Game, do site minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Descarregue um do site minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Descarregando e instalando $1, por favor aguarde..." + +#~ msgid "Enable VBO" +#~ msgstr "Ativar VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "Ativar registo de confirmação" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Ativa o bumpmapping para texturas. Mapas normais devem ser fornecidos " +#~ "pelo pack de\n" +#~ "texturas ou gerado automaticamente.\n" +#~ "Requer que as sombras sejam ativadas." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Ativa mapeamento de tons fílmico" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Ativa geração de normalmap (efeito de relevo) ao voar.\n" +#~ "Requer texturização bump mapping para ser ativado." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Ativa mapeamento de oclusão de paralaxe.\n" +#~ "Requer sombreadores ativados." + +#~ msgid "Enter " +#~ msgstr "Enter " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Opção experimental, pode causar espaços visíveis entre blocos\n" +#~ "quando definido com num úmero superior a 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS em menu de pausa" + +#~ msgid "Fallback font shadow" +#~ msgstr "Sombra da fonte alternativa" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Canal de opacidade sombra da fonte alternativa" + +#~ msgid "Fallback font size" +#~ msgstr "Tamanho da fonte alternativa" + +#~ msgid "Filtering" +#~ msgstr "Filtros" + +#~ msgid "Floatland base height noise" +#~ msgstr "Altura base de ruído de terra flutuante" + +#~ msgid "Floatland mountain height" +#~ msgstr "Altura da terra flutuante montanhosa" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Opacidade da sombra da fonte (entre 0 e 255)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Tamanho da fonte reserva em pontos (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "Fontes Freetype" + +#~ msgid "Full screen BPP" +#~ msgstr "BPP em ecrã inteiro" + +#~ msgid "Game" +#~ msgstr "Jogo" + +#~ msgid "Gamma" +#~ msgstr "Gama" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Gerar Normal maps" + +#~ msgid "Generate normalmaps" +#~ msgstr "Gerar mapa de normais" + +#~ msgid "HUD scale factor" +#~ msgstr "Fator de escalonamento do painel de interface" + +#~ msgid "High-precision FPU" +#~ msgstr "FPU de alta precisão" + +#~ msgid "IPv6 support." +#~ msgstr "Suporte IPv6." + +#~ msgid "In-Game" +#~ msgstr "No jogo" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Instalar: ficheiro: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Monitorização" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Teclas. (Se este menu se estragar, remova as linhas do minetest.conf)" + +#~ msgid "Lava depth" +#~ msgstr "Profundidade da lava" + +#~ msgid "Lightness sharpness" +#~ msgstr "Nitidez da iluminação" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Limite de filas emerge no disco" + +#~ msgid "Main" +#~ msgstr "Principal" + +#~ msgid "Main menu style" +#~ msgstr "Estilo do menu principal" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "Faz o DirectX trabalhar com LuaJIT. Desative se causa problemas." + +#~ msgid "Menus" +#~ msgstr "Opções para menus" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Minimapa em modo radar, zoom 2x" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Minimapa em modo radar, zoom 4x" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Minimapa em modo de superfície, zoom 2x" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Minimapa em modo de superfície, zoom 4x" + +#~ msgid "Name / Password" +#~ msgstr "Nome / Palavra-passe" + +#~ msgid "Name/Password" +#~ msgstr "Nome/palavra-passe" + +#~ msgid "No" +#~ msgstr "Não" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Amostragem de normalmaps" + +#~ msgid "Normalmaps strength" +#~ msgstr "Intensidade de normalmaps" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Número de iterações de oclusão de paralaxe." + +#~ msgid "Ok" +#~ msgstr "Ok" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "" +#~ "Opacidade (alpha) da sombra atrás da fonte alternativa, entre 0 e 255." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "" +#~ "Enviesamento do efeito de oclusão de paralaxe, normalmente escala/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Escala do efeito de oclusão de paralaxe." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Oclusão de paralaxe" + +#~ msgid "Parallax occlusion" +#~ msgstr "Oclusão de paralaxe" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Enviesamento de oclusão paralaxe" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Iterações de oclusão paralaxe" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Modo de oclusão paralaxe" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Escala de Oclusão de paralaxe" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Força da oclusão paralaxe" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Caminho para TrueTypeFont ou bitmap." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Caminho para onde salvar screenshots." + +#~ msgid "Player name" +#~ msgstr "Nome do Jogador" + +#~ msgid "Profiling" +#~ msgstr "Analizando" + +#~ msgid "Projecting dungeons" +#~ msgstr "Projetando dungeons" + +#~ msgid "PvP enabled" +#~ msgstr "PvP ativado" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Reiniciar mundo singleplayer" + +#~ msgid "Select Package File:" +#~ msgstr "Selecionar o ficheiro do pacote:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Servidor / Um jogador" + +#~ msgid "Shadow limit" +#~ msgstr "Limite de mapblock" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Distância (em pixels) da sombra da fonte de backup. Se 0, então nenhuma " +#~ "sombra será desenhada." + +#~ msgid "Special" +#~ msgstr "Especial" + +#~ msgid "Special key" +#~ msgstr "Tecla especial" + +#~ msgid "Start Singleplayer" +#~ msgstr "Iniciar Um Jogador" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Intensidade de normalmaps gerados." + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "Força do aumento médio da curva de luz." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Esta fonte será usada para determinados idiomas." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Para ativar as sombras é necessário usar o controlador OpenGL." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Ativar/Desativar câmera cinemática" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Altura máxima típica, acima e abaixo do ponto médio, do terreno da " +#~ "montanha flutuante." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Variação da altura da colina e profundidade do lago no terreno liso da " +#~ "Terra Flutuante." + +#~ msgid "View" +#~ msgstr "Vista" + +#~ msgid "Waving Water" +#~ msgstr "Água ondulante" + +#~ msgid "Waving water" +#~ msgstr "Balançar das Ondas" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Se as fontes FreeType são usadas, requer que suporte FreeType tenha sido " +#~ "compilado.\n" +#~ "Se desativado, fontes de bitmap e de vetores XML são usadas em vez disso." + +#~ msgid "Whether dungeons occasionally project from the terrain." +#~ msgstr "Se dungeons ocasionalmente se projetam do terreno." + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Limite Y máximo de lava em grandes cavernas." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "" +#~ "Nível em Y do ponto médio da montanha flutuante e da superfície do lago." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Nível Y para o qual as sombras de ilhas flutuantes se estendem." + +#~ msgid "Yes" +#~ msgstr "Sim" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Está prestes a entrar neste servidor com o nome \"%s\" pela primeira " +#~ "vez.\n" +#~ "Se prosseguir, uma nova conta usando suas credenciais será criada neste " +#~ "servidor.\n" +#~ "Por favor, digite novamente a sua palavra-passe e clique em 'Registrar e " +#~ "se cadastrar' para confirmar a criação da conta ou clique em 'Cancelar' " +#~ "para cancelar." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Você morreu" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/pt_BR/minetest.po b/po/pt_BR/minetest.po new file mode 100644 index 0000000..2b295d3 --- /dev/null +++ b/po/pt_BR/minetest.po @@ -0,0 +1,8434 @@ +msgid "" +msgstr "" +"Project-Id-Version: Portuguese (Brazil) (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-06-12 18:17+0000\n" +"Last-Translator: Igor Vinoski <igor.vinoski2@gmail.com>\n" +"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" +"minetest/minetest/pt_BR/>\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.13-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Limpe a fila de espera do chat" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Comando vazio." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Sair para o menu principal" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Comando inválido: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Comando emitido: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Liste os jogadores online" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Jogadores online: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "A fila de espera do chat agora está vazia." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Este comando está desabilitado pelo servidor." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Reviver" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Você morreu" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Comandos disponíveis:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Comandos disponíveis: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Comando não disponível: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Obtenha ajuda para comandos" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Use '.help <cmd>' para conseguir mais informação, ou '.help all' para listar " +"tudo." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all| <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Ok" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<Comando não disponível>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Ocorreu um erro em um script Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Ocorreu um erro:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menu principal" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Reconectar" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "O servidor solicitou uma nova conexão:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Selecione Mods" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Versão do protocolo incompatível. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "O servidor obriga o uso do protocolo versão $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "O servidor suporta versões de protocolo entre $1 e $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Nós só suportamos a versão do protocolo $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Suportamos protocolos com versões entre $1 e $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Cancelar" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Dependências:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Desabilitar todos" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Desabilitar modpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Habilitar todos" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Habilitar modpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Falha ao carregar mod \"$1\" devido ao fato de seu nome possuir caracteres " +"inválidos. Apenas caracteres de \"a\" até \"z\" e algarismos de 0 até 9 são " +"permitidos." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Encontre Mais Mods" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Nenhuma dependência (opcional)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Nenhuma descrição de jogo disponível." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Sem dependências rígidas" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Nenhuma descrição do modpack fornecida." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Sem dependências opcionais" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Dependências opcionais:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Salvar" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Mundo:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "habilitado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" já existe. Gostaria de sobrescrevê-lo?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "As dependências $1 e $2 serão instaladas." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 por $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 baixando,\n" +"$2 na fila" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 baixando..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 dependências obrigatórias não puderam ser encontradas." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 será instalado, e $2 dependências serão ignoradas." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Todos os pacotes" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Já instalado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Voltar ao menu principal" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Jogo Base:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB não está disponível quando Minetest é compilado sem cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Baixando..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Falha ao baixar $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Jogos" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instalar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Instalar $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Instalar dependências ausentes" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Instalação: Tipo de arquivo não suportado ou corrompido" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Modulos (Mods)" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Nenhum pacote pôde ser recuperado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Sem resultados" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Sem atualizações" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Não encontrado" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Sobrescrever" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Verifique se o jogo base está correto." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Na fila" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Pacotes de texturas" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Desinstalar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Atualizar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Atualizar tudo [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Veja mais informações em um navegador da web" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Já existe um mundo com o nome \"$1\"" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Terreno adicional" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Altitude fria" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Altitude seca" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Transição de bioma" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Cavernas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Cavernas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Criar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Decorações" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Aviso: O jogo Development Test é projetado para desenvolvedores." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Masmorras (Dungeons)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Terreno plano" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Ilhas flutuantes no céu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Ilhas flutuantes (experimental)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Gera terrenos não fractais: Oceanos e subterrâneos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Colinas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Rios húmidos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Aumenta a umidade perto de rios" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Instalar $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Lagos" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Baixa humidade e calor elevado resultam em rios rasos ou secos" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Gerador de mapa" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Opções do gerador de mapas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Parâmetros específicos do gerador de mapas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Montanhas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Fluxo de lama" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Conectar túneis e cavernas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Nenhum jogo selecionado" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Reduz calor com a altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Reduz humidade com a altitude" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Rios" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Rios ao nível do mar" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Semente (Seed)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Transição suave entre biomas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Estruturas que aparecem no terreno (sem efeito em árvores e grama da selva " +"criada pelo v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Estruturas que aparecem no terreno, geralmente árvores e plantas" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Temperado, Deserto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Temperado, Deserto, Selva" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Temperado, Deserto, Selva, Tundra, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erosão na superfície do terreno" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Árvores e relva da selva" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Variar altura dos rios" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Cavernas muito grandes nas profundezas do subsolo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Nome do mundo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Você não possui jogos instalados." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Tem certeza que deseja excluir \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Excluir" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: não foi possível excluir \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: caminho inválido \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Excluir o mundo \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Confirmar a senha" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Nome do gerador de mundo" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nome" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Senha" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "As senhas não correspondem!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Registrar e entrar" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Aceitar" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Renomear Modpack:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Esse modpack possui um nome explícito em seu modpack.conf que vai " +"sobrescrever qualquer nome aqui." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Não há uma descrição para esta configuração)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Ruído 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Voltar para as configurações" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Procurar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Conteúdo" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Conteúdo" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Desabilitado" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Editar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Habilitado" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lacunaridade" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Octavos" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Deslocamento" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Persistência" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Por favor, insira um inteiro válido." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Por favor, insira um número válido." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Restaurar Padrão" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Escala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Buscar" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Selecione o diretório" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Selecione o arquivo" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Mostrar nomes técnicos" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "O valor deve ser pelo menos $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "O valor não deve ser maior do que $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "amplitude X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "amplitude Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "amplitude Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "valor absoluto" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "padrão" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "amenizado" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Habilitado)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mods" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Não foi possível instalar $1 em $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Instalação de mod: não foi possível encontrar o nome real do mod: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Instalação de mod: não foi possível encontrar o nome da pasta adequado para " +"o modpack $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Incapaz de encontrar um mod ou modpack válido" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Não foi possível instalar $1 como pacote de texturas" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Não foi possível instalar um jogo como um $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Não foi possível instalar um mod como um $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Não foi possível instalar um modpack como um $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Carregando..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "A lista de servidores públicos está desabilitada" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Tente reativar a lista de servidores públicos e verifique sua conexão com a " +"internet." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Sobre" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Colaboradores Ativos" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Renderizador ativo:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Desenvolvedores Principais" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Abrir diretório de dados do usuário" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Abre o diretório que contém mundos, jogos, mods fornecidos pelo usuário,\n" +"e pacotes de textura em um gerenciador / navegador de arquivos." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Colaboradores Anteriores" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Desenvolvedores Principais Anteriores" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Mostrar informações de depuração" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Procurar conteúdo online" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Conteúdo" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Desabilitar Pacote de Texturas" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informação:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Pacotes Instalados:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Sem dependências." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Nenhuma descrição de pacote disponível" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Renomear" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Desinstalar Pacote" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Usar Pacote de Texturas" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Anunciar Servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Endereço" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Modo Criativo" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Habilitar Dano" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Hospedar Jogo" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Hospedar Servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Instalar jogos do ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Novo" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Nenhum mundo criado ou selecionado!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Jogar" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Porta" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Selecione Mods" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Selecione um mundo:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Porta do Servidor" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Iniciar Jogo" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Endereço" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Limpar" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Modo criativo" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Dano / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favoritos" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Servidores incompatíveis" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Entrar em um Jogo" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Servidores Públicos" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Atualizar" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Porta remota" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Descrição do servidor" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Nuvens 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Todas as configurações" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Anti-aliasing:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Salvar automaticamente o tamanho da tela" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Filtragem bi-linear" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Mudar teclas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Vidro conectado" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Sombras dinâmicas" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Sombras dinâmicas: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Folhas com transparência" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Alto" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Baixo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Médio" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap (filtro)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Filtro Anisotrópico" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Sem filtros" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Sem Mipmapping" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Destaque nos Blocos" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Bloco Delineado" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Nenhum" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Folhas Opacas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Água opaca" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partículas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Tela:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Configurações" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Sombreadores" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Sombreadores (experimental)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Sombreadores(indisponível)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Folhas Simples" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Iluminação suave" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Texturização:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Tone mapping" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Nível de sensibilidade ao toque (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Filtragem tri-linear" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Muito Alto" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Muito Baixo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Folhas Balançam" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Líquidos com ondas" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Plantas balançam" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Erro de conexão (tempo excedido?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Erro de conexão (tempo excedido)." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Pronto!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inicializando nodes" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Inicializando nodes..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Carregando texturas..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Reconstruindo sombreadores..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Erro de conexão (tempo excedido?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Não foi possível localizar ou carregar jogo " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Especificação do jogo inválida." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menu principal" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" +"Nenhum mundo foi selecionado e nenhum endereço fornecido. Nada a ser feito." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Nome de jogador muito longo." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Por favor, escolha um nome!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Arquivo de senha fornecido falhou em abrir : " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Caminho informado para o mundo não existe: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Verifique o debug.txt para mais detalhes." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Endereço: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Modo: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "-Porta: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Público: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "Nome do servidor: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Ocorreu um erro:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Acesso negado. Razão:%s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Avanço automático para frente desabilitado" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Avanço automático para frente habilitado" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Limites de bloco ocultos" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Limites de bloco mostrados para todos os blocos" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Limites de bloco mostrados para o bloco atual" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Limites de bloco mostrados para blocos próximos" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Atualização da camera desabilitada" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Atualização da camera habilitada" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" +"Não é possível mostrar limites de bloco (precisa do privilégio 'basic_debug')" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Alterar a senha" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Modo cinemático desabilitado" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Modo cinemático habilitado" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Cliente desconectado" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Scripting de cliente está desabilitado" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Conectando ao servidor..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "A conexão falhou por motivo desconhecido" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Continuar" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Controles:\n" +"- %s: mover para frente\n" +"- %s: mover para trás\n" +"- %s: mover para esquerda\n" +"- %s: mover para direita\n" +"- %s: pular/subir\n" +"- %s: cavar/socar\n" +"- %s: colocar/usar\n" +"- %s: andar furtivamente/descer\n" +"- %s: soltar item\n" +"- %s: inventário\n" +"- Mouse: virar/olhar\n" +"- Roda do mouse: selecionar item\n" +"- %s: bate-papo\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Não foi possível resolver o endereço:%s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Criando o cliente..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Criando o servidor..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Informação de debug e gráfico de perfil escondido" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Informação de debug mostrada" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Informação de debug, gráfico de perfil e wireframe escondidos" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Controles:\n" +"Se não há nenhum menu visível:\n" +"- Um toque: ativa botão\n" +"- Duplo toque: place/use\n" +"- Deslizar dedo: Olhar ao redor\n" +"Menu/Inventário visível:\n" +"- Duplo toque: (Fora do menu):\n" +" -->Fechar\n" +"- Tocar Item e depois tocar em um slot:\n" +" --> move item\n" +"- Tocar e arrastar, e depois tocar com o 2º dedo\n" +" --> Coloca apenas um item no slot\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Alcance de visualização ilimitado desabilitado" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Alcance de visualização ilimitado habilitado" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Criando o cliente..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Sair para o menu" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Sair do Minetest" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Modo rápido desabilitado" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Modo rápido habilitado" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Modo rápido habilitado (nota: sem o privilégio 'fast')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Modo voo desabilitado" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Modo voo habilitado" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Modo voo habilitado(note: sem privilegio 'fly')" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Névoa desabilitada" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Névoa habilitada" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Informação do jogo:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Jogo parado" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Criando o servidor" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Carregando itens..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Mídia..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Minipapa atualmente desabilitado por jogo ou mod" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Multi-jogador" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Modo atravessar paredes desabilitado" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Modo atravessar paredes habilitado" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Modo atravessar paredes habilitado(note: sem privilégio 'noclip')" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Carregando blocos..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Desligado" + +#: src/client/game.cpp +msgid "On" +msgstr "Ligado" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Modo movimento pitch desabilitado" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Modo movimento pitch habilitado" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Gráfico de perfil mostrado" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Servidor remoto" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Resolvendo os endereços..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Desligando tudo..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Um jogador" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Volume do som" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Som mutado" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Sistema de som está desativado" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Sistema de som não é suportado nesta versão" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Som desmutado" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "O servidor provavelmente está executando uma versão diferente de%s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Não foi possível conectar a%s porque o IPv6 está desativado" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Incapaz de escutar em%s porque IPv6 está desabilitado" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Distancia de visualização alterado pra %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Distancia de visualização está no máximo:%d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Alcance de visualização é no mínimo: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Volume mudado para %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Mostrar wireframe" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zoom atualmente desabilitado por jogo ou mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "Ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Conversa oculta" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Conversa mostrada" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "Interface escondida" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "Interface mostrada" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Analisador ocultado" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Analisador mostrado(página %d de %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplicativos" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Tecla voltar" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Ctrl" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Abaixo" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Tecla End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Apagar EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Executar" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Ajuda" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Aceitar Método de Entrada" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Converter Método de Entrada" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "Sair do Método de Entrada" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Mudar Modo de Método de Entrada" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "Método de Entrada Inconversível" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Inserir" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Esquerda" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Botão esquerdo" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Ctrl esquerdo" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menu esquerdo" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Shift esquerdo" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Windows esquerdo" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Roda do mouse" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Tecl.num. *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Tecl.num. +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Tecl.num. -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Tecl.num. ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Tecl.num. /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Tecl.num. 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Tecl.num. 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Tecl.num. 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Tecl.num. 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Tecl.num. 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Tecl.num. 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Tecl.num. 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Tecl.num. 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Tecl.num. 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Tecl.num. 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Limpar OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pausar" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Jogar" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Print Screen" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Direita" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Botão direito" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Ctrl direito" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menu direito" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Shift direito" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Windows direito" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Tecla Select" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Tecla Sleep" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Captura de tela" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Espaço" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Acima" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Botão X 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Botão X 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Minimapa escondido" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimapa em modo radar, Zoom %dx" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimapa em modo de superfície, Zoom %dx" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimapa em modo de textura" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Falha ao abrir página da web" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Abrindo página da web" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Continuar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Especial\" = descer" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Avanço frontal automático" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Pulo automático" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Especial" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Voltar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Limites de bloco" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Mudar camera" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Bate-papo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Comando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Console" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Alcance dec" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Abaixar volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "\"Pular\" duas vezes para ativar o voo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Soltar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Avançar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Alcance inc" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Aumentar Volume" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventário" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Pular" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Essa tecla já está em uso" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Comando local" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Mudo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Próximo item" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Item anterior" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Selecionar distância" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Captura de tela" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Esgueirar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Ativar interface" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Ativar histórico de conversa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Alternar corrida" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Alternar voo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Ativar névoa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Ativar minimapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Alternar noclip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Ativar Voar seguindo a câmera" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "pressione uma tecla" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Alterar" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nova senha" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Senha antiga" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "As senhas não correspondem!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Sair" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Mutado" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Volume do som: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "pt_BR" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Por favor, escolha um nome!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Corrige a posição do joystick virtual.\n" +"Se desabilitado, o joystick virtual vai centralizar na posição do primeiro " +"toque." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Use joystick virtual para ativar botão \"especial\".\n" +"Se habilitado, o joystick virtual vai também clicar no botão \"especial\" " +"quando estiver fora do circulo principal." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) compensação do fractal a partir centro do mundo em unidades de " +"'escala'.\n" +"Pode ser usado para mover um ponto desejado para (0, 0) para criar um\n" +"ponto de spawn flexível ou para permitir zoom em um ponto desejado,\n" +"aumentando 'escala'.\n" +"O padrão é ajustado para um ponto de spawn adequado para conjuntos de\n" +"Mandelbrot com parâmetros padrão, podendo ser necessário alterá-lo em " +"outras \n" +"situações.\n" +"Variam aproximadamente de -2 a 2. Multiplique por 'escala' para compensar em " +"nodes." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z) Escala fractal em nós.\n" +"Tamanho fractal atual será de 2 a 3 vezes maior.\n" +"Esses números podem ser muito grandes, o fractal\n" +"não tem que encaixar dentro do mundo.\n" +"Aumente estes para 'ampliar' nos detalhes do fractal.\n" +"Padrão é para uma forma espremida verticalmente para\n" +"uma ilha, coloque todos os 3 números iguais para a forma crua." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Ruído 2D que controla a forma/tamanho de montanhas acidentadas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Ruído 2D que controla o formato/tamanho de colinas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Ruído 2D que controla o formato/tamanho de montanhas de caminhada." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "Ruído 2D que controla o tamanho/ocorrência de montanhas sulcadas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D noise que controla o tamanho/ocorrência de colinas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" +"Ruído 2D que controla o tamanho/ocorrência de intervalos de montanhas de " +"caminhar." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Ruído 2D que localiza os vales e canais dos rios." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Nuvens 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "modo 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Força de paralaxe do modo 3D" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Ruído 3D que define cavernas gigantes." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Ruído 3D que define estrutura de montanha e altura.\n" +"Também define a estrutura do terreno da montanha das ilhas flutuantes." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Ruído 3D definindo as estruturas de terras flutuantes\n" +"Se alterar da predefinição, a 'escala' do ruído (0.7 por predefinição) pode " +"precisar\n" +"ser ajustada, já que o afunilamento das terras flutuantes funciona melhor " +"quando o ruído tem\n" +"um valor entre -2.0 e 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Ruído 3D definindo a estrutura das paredes dos cânions dos rios." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Ruído 3D que define o terreno." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"3D noise para saliências de montanhas, penhascos, etc. Geralmente variações " +"pequenas." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "Ruído 3D que determina o número de cavernas por pedaço de mapa." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Suporte 3D.\n" +"Modos atualmente suportados:\n" +"- none: Nenhum efeito 3D.\n" +"- anaglyph: Sistema de cor Ciano/Magenta (Óculos 3D azul vermelho).\n" +"- interlaced: Sistema interlaçado (Óculos com lentes polarizadas).\n" +"- topbottom: Divide a tela em duas: uma em cima e outra em baixo.\n" +"- sidebyside: Divide a tela em duas: lado a lado.\n" +" - crossview: 3D de olhos cruzados.\n" +" - pageflip: Quadbuffer baseado em 3D.\n" +"Note que o modo interlaçado requer que o sombreamento esteja habilitado." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Seed do mundo, deixe em branco para uma seed aleatória.\n" +"Será sobrescrita quando for criada um novo mundo no menu principal." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" +"Uma mensagem para ser mostrada a todos os clientes do seu servidor quando " +"ele travar." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Uma mensagem para ser mostrada a todos os clientes quando o servidor " +"desligar." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Intervalo do ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Alocação de tempo do ABM" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Limite absoluto de filas de blocos para emergir" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Aceleração no ar" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Aceleração da gravidade, em nós por segundo por segundo." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Modificadores de Bloco Ativo (ABM)" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Intervalo de Gestão de Blocos Ativos" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Limite para blocos ativos" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Alcance para envio de objetos ativos" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Endereço para conexão.\n" +"Deixe em branco para iniciar um servidor local.\n" +"Note que o campo de endereço no menu principal sobrescreve essa configuração." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Adiciona partículas quando cavando um node." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Ajustar configuração de dpi (profundidade de cor) para sua tela (apenas para " +"quem não usa X11/Android) Ex para telas 4K." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Ajuste a densidade de exibição detectada, usada para dimensionar os " +"elementos da IU." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Ajusta a densidade da camada de ilhas flutuantes.\n" +"Aumente o valor para aumentar a densidade. Pode ser positivo ou negativo.\n" +"Valor = 0.0: 50% do volume é ilhas flutuantes.\n" +"Valor = 2.0 (pode ser maior dependendo do 'mgv7_np_floatland', sempre teste\n" +"para ter certeza) cria uma camada sólida de ilhas flutuantes." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Concatenar nome do item" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avançado" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Altera a curva da luz aplicando-lhe a 'correção gama'.\n" +"Valores altos tornam os níveis médios e baixos de luminosidade mais " +"brilhantes.\n" +"O valor '1.0' mantêm a curva de luz inalterada.\n" +"Isto só tem um efeito significativo sobre a luz do dia e a luz\n" +"artificial, tem pouquíssimo efeito na luz natural da noite." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Sempre voar e correr" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Gama de oclusão de ambiente" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Quantidade de mensagens que um jogador pode enviar por 10 segundos." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Amplifica os vales." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Filtragem anisotrópica" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Anunciar servidor" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Anuncie para esta lista de servidor." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Concatenar nome do item" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Concatenar nome do item a descrição." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Ruído de Árvores de Macieira" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Inercia dos braços" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Inercia dos braços, fornece um movimento mais realista dos\n" +"braços quando movimenta a câmera." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Peça para reconectar depois de queda" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"Nesta distância, o servidor otimizará agressivamente quais blocos serão " +"enviados\n" +"aos clientes.\n" +"Pequenos valores potencialmente melhoram muito o desempenho, à custa de " +"falhas\n" +"de renderização visíveis (alguns blocos não serão processados debaixo da " +"água e nas\n" +"cavernas, bem como às vezes em terra).\n" +"Configurando isso para um valor maior do que a " +"distância_máxima_de_envio_do_bloco\n" +"para desabilitar essa otimização.\n" +"Especificado em barreiras do mapa (16 nodes)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Tecla para frente automática" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Automaticamente pula obstáculos de um só nó." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Informar para a lista de servidores automaticamente." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Salvar automaticamente o tamanho da tela" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Modo de alto escalamento" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Tecla Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Tecla Aux1 pra escalar/descer" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tecla para andar para trás" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Nível de solo base" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Altura base do terreno." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Privilégios básicos" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Ruído de praias" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Limiar do ruído de praias" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Filtragem bi-linear" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Endereço de bind" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Parâmetros de ruído e umidade da API de Bioma" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Ruído do bioma" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Distância otimizada de envio de bloco" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Caminho de fonte em negrito e itálico" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Caminho de fonte monoespaçada para negrito e itálico" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Caminho da fonte em negrito" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Caminho de fonte monoespaçada em negrito" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Construir com o jogador dentro do bloco" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Embutido" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Mudar camera" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Distancia do plano próximo da câmera em nós, entre 0 e 0.25\n" +"Só funciona em plataformas GLES. A maioria dos usuários não precisarão mudar " +"isto.\n" +"Aumentar pode reduzir a ocorrencia de artefatos em GPUs mais fracas.\n" +"0.1 = Padrão, 0.25 = Bom valor para tablets fracos." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Suavização da camera" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Suavização da câmera no modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Tecla para alternar atualização da câmera" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Ruído de cavernas" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Ruído de cavernas #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Ruído de cavernas #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Largura da caverna" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Ruídos de Cave1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Ruídos de Cave2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Limite da caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Ruído de cavernas" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Cone da caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Limite da caverna" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Limite do topo da caverna" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Centro da faixa de aumento da curva de luz.\n" +"Onde 0.0 é o nível mínimo de luz, 1.0 é o nível máximo de luz." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Limite de mensagem de tempo de comando de bate-papo" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Comandos de Chat" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Tamanho da fonte do chat" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Tecla de Chat" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Nível de log do chat" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Limite do contador de mensagens de bate-papo" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Formato da mensagem de chat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Limite da mensagem de expulsão" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Tamanho máximo da mensagem de conversa" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Tecla comutadora de chat" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Links de bate-papo" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Tamanho do chunk" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tecla para modo cinematográfico" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Limpe as texturas transparentes" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Links da web clicáveis (clique do meio ou Ctrl + botão esquerdo) ativados na " +"saída do console de bate-papo." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Cliente" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Cliente e servidor" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Mods de Cliente Local" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Restrição de modificação no lado do cliente" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Restrição do alcançe da visão superior de nós no lado do cliente" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Mods de Cliente Local" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Velocidade de subida (em escadas e outros)" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Raio das nuvens" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Nuvens" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Conf. das nuvens apenas afetam seu jogo local." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Nuvens no menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Névoa colorida" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Sombra colorida" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Lista de flags separadas por vírgula para esconder no repositório de " +"conteúdos.\n" +"\"não livre\" pode ser usada para esconder pacotes que não se qualificam " +"como software livre,\n" +"como definido pela fundação do software livre.\n" +"Você também pode especificar classificação de conteúdo.\n" +"Essas flags são independentes das versões do minetest,\n" +"veja a lista completa em https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Lista de mods, separados por vírgulas, que tem acesso a APIs HTTP, que\n" +"os permitem enviar e baixar informações para/da internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Lista separada por vírgulas dos mods confiáveis que podem utilizar funções " +"inseguras \n" +"mesmo quando o a opção de Mod Seguro está ativada (via " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Tecla de Comando" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Nível de compressão ZLib a ser usada ao salvar mapblocks no disco.\n" +"-1 - Nível de compressão padrão do Zlib\n" +"0 - Nenhuma compressão; o mais rápido\n" +"9 - Melhor compressão; o mais devagar" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Nível de compressão ZLib a ser usada ao mandar mapblocks para o cliente.\n" +"-1 - Nível de compressão padrão do Zlib\n" +"0 - Nenhuma compressão; o mais rápido\n" +"9 - Melhor compressão; o mais devagar\n" +"(níveis 1-3 usam método \"rápido\" do Zlib, enquanto que 4-9 usam método " +"normal)" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Vidro conectado" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Conecta ao servidor de mídia externo" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Conecta o vidro se isso for suportado pelo bloco." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Console Alpha" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Cor do console" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Tamanho vertical do console" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Repositório de conteúdo online" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Lista negra de flags do ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Máximo de downloads simultâneos de ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "Url do ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Para frente continuamente" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Movimento para frente contínuo, ativado pela tela de avanço automático.\n" +"Pressione a tecla de avanço frontal novamente, ou a tecla de movimento para " +"trás para desabilitar." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Controles" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Controla a duração do ciclo de dia/noite.\n" +"Exemplos:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = Dia/noite permanece inalterado." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Controla o esparsamento/profundidade dos lagos." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Controla o esparsamento/altura das colinas." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Controla a largura dos túneis, um valor menor cria túneis mais largos.\n" +"Valor >= 10,0 desabilita completamente a geração de túneis e evita os\n" +"cálculos intensivos de ruído." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Mensagem de travamento" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Criativo" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Alpha do cursor" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Alpha do cursor (quanto ele é opaco, níveis entre 0 e 255).\n" +"Também controla a cor da cruz do objeto." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Cor do cursor" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Cor da cruz (R, G, B).\n" +"Também controla a cor da cruz do objeto" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "dpi" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Dano" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Tecla para alternar modo de Depuração" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Limite de tamanho do arquivo de log de depuração" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Nível de log do Debug" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Tecla de abaixar volume" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Passo do servidor dedicado" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Aceleração padrão" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Jogo padrão" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Padrões de jogo para quando criar um novo mundo.\n" +"Isso será sobrescrito quando criar um mundo no menu principal." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Senha padrão" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Privilégios por padrão" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Formato de reporte padrão" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Tamanho padrão de stack" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Define a qualidade de filtragem de sombreamento\n" +"Isso simula um efeito de sombras suaves aplicando um PCF ou um Poisson disk\n" +"mas também usa mais recursos." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Define áreas onde na árvores têm maçãs." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Define áreas com praias arenosas." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" +"Define a distribuição de terrenos elevados e a inclinação de penhascos." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Define a distribuição de terrenos elevados." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Define o tamanho completo de cavernas, valores menores criam cavernas " +"maiores." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Define estruturas de canais de grande porte (rios)." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Define localizações e terrenos de morros e lagos opcionais." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Define o nível base do solo." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Define a profundidade do canal do rio." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Define a distância máxima de transferência de jogadores em blocos (0 = " +"ilimitado)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Define a largura do canal do rio." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Define a largura do vale do rio." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Define áreas de árvores e densidade das árvores." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Tempo entre atualizações das malhas 3D no cliente em milissegundos.\n" +"Aumentar isso vai retardar a taxa de atualização das malhas, sendo assim, " +"reduzindo travamentos em clientes lentos." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Atraso em enviar blocos depois da construção" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Dicas de ferramenta mostrando atraso. indicado em milissegundos." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Tratamento de API Lua rejeitada" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Profundidade em que você encontrará cavernas gigantes." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Profundidade em que você encontrará cavernas enormes." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Descrição do servidor, a ser exibida quando os jogadores se conectarem e na " +"lista de servidores." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Limite do ruído de deserto" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Os desertos ocorrem quando np_biome excede este valor.\n" +"Quando a marcação 'snowbiomes' está ativada, isto é ignorado." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Dessincronizar animação do bloco" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Decorações" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Tecla para escavar" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Partículas de Escavação" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Habilitar Anti-Hack" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Não permitir logar sem senha" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Display Density Scaling Factor" +msgstr "Fator de escala de densidade de exibição" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Domínio do servidor, para ser mostrado na lista de servidores." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "\"Pular\" duas vezes ativa o vôo" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "\"Pular\" duas vezes alterna o modo vôo." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Tecla para largar item" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Mostrar informações de depuração do Gerador de mapa." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Y máximo da dungeon" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Y mínimo da dungeon" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Ruído de masmorra" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Habilitar suporte IPv6 (tanto para cliente quanto para servidor).\n" +"Necessário para que as conexões IPv6 funcionem." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Habilitar suporte a mods de LuaScript no cliente.\n" +"Esse suporte é experimental e a API pode mudar." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Ativa filtragem de Poisson disk.\n" +"Quando em true usa o Poisson disk para fazer \"sombras suaves\". Caso " +"contrário, usa filtragem PCF." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Ativa sombras coloridas.\n" +"Quando em true, nodes translúcidos podem projetar sombras coloridas. Requer " +"o uso de muitos recursos." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Habilitar janela de console" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Habilitar modo criativo para todos os jogadores" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Habilitar Joysticks" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Habilitar suporte a canais de módulos." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Habilitar Mod Security (Segurança nos mods)" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Permitir que os jogadores possam sofrer dano e morrer." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Habilitar entrada de comandos aleatórios (apenas usado para testes)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Ativar iluminação suave com oclusão de ambiente simples.\n" +"Desativada para andar rápido ou para visões diferentes." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Habilitar recurso de não permitir que jogadores usando versões antigas do " +"cliente possam se conectar.\n" +"Essas versões são compatíveis no sentido de não travar quando conectam a " +"servidores com versões mais atuais,\n" +"porém eles podem não suportar todos os recursos que você está esperando." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Permitir o uso de servidor de mídia remoto (se fornecido pelo servidor).\n" +"Servidores remotos oferecem uma maneira significativamente mais rápida\n" +"para fazer o download de mídia (por exemplo texturas) ao se conectar ao " +"servidor." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Ativa vertex buffer objects.\n" +"Isso deve melhorar muito a performance gráfica." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Multiplicador para sacudir a exibição.\n" +"Por exemplo: 0 para não ver balançando; 1.0 para normal; 2.0 para duplo." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Habilitar/desabilitar a execução de um IPv6 do servidor. \n" +"Ignorado se bind_address estiver definido.\n" +"Precisa de enable_ipv6 para ser ativado." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Permite o mapeamento de tom do filme 'Uncharted 2', de Hable.\n" +"Simula a curva de tons do filme fotográfico e como isso se aproxima da\n" +"aparência de imagens de alto alcance dinâmico (HDR). O contraste de médio " +"alcance é ligeiramente\n" +"melhorado, os destaques e as sombras são gradualmente comprimidos." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Habilita itens animados no inventário." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Ativar armazenamento em cache de direção de face girada das malhas." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Habilitar minimapa." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Ativa o sistema de som.\n" +"Se desativado, isso desabilita completamente todos os sons em todos os " +"lugares\n" +"e os controles de som dentro do jogo se tornarão não funcionais.\n" +"Mudar esta configuração requer uma reinicialização." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Permite compensações que reduzem a carga da CPU ou aumentam o desempenho de " +"renderização\n" +"à custa de pequenas falhas visuais que não afetam a jogabilidade do jogo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Perfil do vale" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Intervalo de exibição dos dados das analizes do motor" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Metodos de entidade" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Expoente de estreitamento das ilhas flutuantes. Altera o comportamento de " +"afilamento.\n" +"Valor = 1.0 cria um afunilamento linear uniforme.\n" +"Valores> 1.0 criam um estreitamento suave adequado para as ilhas flutuantes\n" +"padrão (separadas).\n" +"Valores <1.0 (por exemplo 0.25) criam um nível de superfície mais definido " +"com\n" +"planícies mais planas, adequadas para uma camada sólida de ilhas flutuantes." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS quando o jogo é pausado ou perde o foco" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "Anti-Aliasing de Tela Cheia (FSAA)" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Fator de ruído" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Fator de balanço em queda" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Fonte reserva" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Tecla de correr" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Aceleração no modo rápido" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Velocidade no modo rápido" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Modo rápido" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Movimento rápido (através da tecla \"Aux1\").\n" +"Isso requer o privilegio \"fast\" no servidor." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Campo de visão" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Campo de visão em graus." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Arquivo na pasta client/serverlist/ que contém seus servidores favoritos, " +"que são mostrados na\n" +"aba Multijogador." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Profundidade de preenchimento" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Profundidade de enchimento de ruído" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Filmic Tone Mapping" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Texturas filtradas podem misturar valores RGB com os vizinhos totalmente \n" +"transparentes, o qual otimizadores PNG geralmente descartam, por vezes \n" +"resultando em uma linha escura em texturas transparentes.\n" +"Aplique esse filtro para limpar isso no momento de carregamento da textura.\n" +"Esse filtro será ativo automaticamente ao ativar \"mipmapping\"." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Anti-aliasing:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Primeiro de 4 ruídos 2D que juntos definem a altura de colinas/montanhas." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Primeiro de 2 ruídos 3D que juntos definem túneis." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Semente do mapa fixa" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Joystick virtual fixo" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Densidade das terras flutuantes" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Y máximo das terras flutuantes" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Y mínimo das terras flutuantes" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Ruído das terras flutuantes" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Expoente de conicidade das ilhas flutuantes" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Distância de afilamento da ilha flutuante" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Nível de água da ilha flutuante" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Tecla de voar" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Voando" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Névoa" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Início da névoa" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Tecla de comutação de névoa" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Tamanho da fonte" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Fonte em negrito por padrão" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Fonte em itálico por padrão" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Fonte de sombra" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Fonte alpha de sombra" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Tamanho da fonte" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Tamanho da fonte divisível por" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Tamanho da fonte padrão onde 1 unidade = 1 pixel em 96 DPI" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Tamanho da fonte monoespacial onde 1 unidade = 1 pixel em 96 DPI" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Tamanho da fonte do texto de bate-papo recente e do prompt do bate-papo em " +"pontos (pt).\n" +"O valor 0 irá utilizar o tamanho padrão de fonte." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"Para fontes de estilo de pixel que não são bem dimensionadas, isso garante " +"que os tamanhos de fonte usados\n" +"com esta fonte será sempre divisível por este valor, em pixels. Por " +"exemplo,\n" +"uma fonte de 16 pixels de altura deve ter isso definido como 16, então só " +"será\n" +"tamanho 16, 32, 48, etc., então um mod solicitando um tamanho de 25 receberá " +"32." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Formato das mensagem de bate-papo dos jogadores. Os textos abaixo são " +"palavras-chave válidas:\n" +"@name, @message, @timestamp (opcional)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Formato das screenshots." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Cor de fundo padrão do formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Opacidade de fundo padrão do formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Cor de fundo em tela cheia do formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Opacidade de fundo em tela cheia do formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Cor de fundo(R,G,B) padrão do formspec padrão." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Opacidade de fundo padrão do formspec (entre 0 e 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Cor de fundo(R,G,B) do formspec padrão em tela cheia." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "Opacidade de fundo do formspec em tela cheia (entre 0 e 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Tecla para frente" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Quarto de 4 ruídos 2D que juntos definem a altura de colinas/montanhas." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Tipo fractal" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Fração da distância visível em que a névoa começa a aparecer" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"De quão longe blocos são gerados para os clientes, indicado em chunks (16 " +"blocos)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"De quão longe blocos são enviados aos clientes, indicado em chunks (16 " +"blocos)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"De quão longe clientes sabem sobre objetos declarados em mapblocks (16 " +"nós).\n" +"\n" +"Configurando isto maior do que o alcançe de bloco ativo vai fazer com que o " +"sevidor\n" +"mantenha objetos ativos na distancia na direção que o\n" +"jogador está olhando.(Isso pode evitar que mobs desapareçam da visão de " +"repente)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Tela cheia" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Modo tela cheia." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Escala da GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Filtro de escala da GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Filtro txr2img de escala da GUI" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Jogos" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Chamadas de retorno Globais" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Atributos de geração de mapa globais.\n" +"No gerador de mapa v6 a flag 'decorations' controla todas as decorações, " +"exceto árvores\n" +"e gramas da selva, em todos os outros geradores de mapa essa flag controla " +"todas as decorações." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Gradiente da curva de luz no nível de luz máximo.\n" +"Controla o contraste dos níveis de luz mais altos." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Gradiente da curva de luz no nível de luz mínimo.\n" +"Controla o contraste dos níveis de luz mais baixos." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Gráficos" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Gráficos" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Gráficos" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravidade" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Nível do terreno para o gerador de mundo plano" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Ruído do solo" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "Módulos HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Escala da GUI" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Tecla de comutação HUD" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Lidando com funções obsoletas da API Lua:\n" +"-...none: não registra funções obsoletas.\n" +"-...log: imita e registra as funções obsoletas chamadas (padrão).\n" +"-...error: aborta quando chama uma função obsoleta (sugerido para " +"desenvolvedores de mods)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Tem o instrumento de registro em si:\n" +"* Monitorar uma função vazia.\n" +"Isto estima a sobrecarga, que o instrumento está adicionando (+1 Chamada de " +"função).\n" +"* Monitorar o amostrador que está sendo usado para atualizar as estatísticas." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Parâmetros de mistura de ruido do gerador de mundo \"heat\"" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Ruído nas cavernas #1" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Componente de altura do tamanho da janela inicial. Ignorado em modo de tela " +"cheia." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Ruído de altura" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Parâmetros de ruido de seleção de altura" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Inclinação dos morros" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Limite das colinas no gerador de mundo plano" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Ruído de declive1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Ruído de declive2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Ruído de declive3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Ruído de declive4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Pagina principal do servidor, a ser exibido na lista de servidores." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Aceleração horizontal no ar ao saltar ou cair,\n" +"em nós por segundo por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Aceleração horizontal e vertical no modo rápido,\n" +"em nós por segundo por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Aceleração horizontal e vertical no solo ou ao escalar,\n" +"em nós por segundo por segundo." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Tecla de próximo item na barra principal" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Tecla de item anterior na barra principal" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Tecla do slot 1 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Tecla do slot 10 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Tecla do slot 11 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Tecla do slot 12 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Tecla do slot 13 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Tecla do slot 14 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Tecla do slot 15 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Tecla do slot 16 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Tecla do slot 17 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Tecla do slot 18 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Tecla do slot 19 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Tecla do slot 2 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Tecla do slot 20 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Tecla do slot 21 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Tecla do slot 22 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Tecla do slot 23 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Tecla do slot 24 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Tecla do slot 25 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Tecla do slot 26 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Tecla do slot 27 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Tecla do slot 29 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Tecla do slot 29 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Tecla do slot 3 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Tecla do slot 30 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Tecla do slot 31 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Tecla do slot 32 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Tecla do slot 4 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Tecla do slot 5 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Tecla do slot 6 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Tecla do slot 7 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Tecla do slot 8 da hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Tecla do slot 9 da hotbar" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Quão profundo serão os rios." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"A velocidade com que as ondas líquidas se movem. Maior = mais rápido.\n" +"Se negativo, as ondas líquidas se moverão para trás.\n" +"Requer que a ondulação de líquidos esteja ativada." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Quanto o servidor aguardará antes de descarregar chunks não utilizados. \n" +"Um valor mais elevado é mais suave, mas vai usar mais memória RAM." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Diminua isto para aumentar a resistência do líquido ao movimento." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Quão largos serão os rios." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Ruído de mistura de umidade" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Ruído de umidade" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Variação de umidade dos biomas." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "Protocolo IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "Servidor de IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Se o FPS for mais elevado do que isso, limitá-lo dormindo\n" +"para não gastar a potência da CPU desnecessariamente." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Se estiver desabilitado, a tecla \"especial\" será usada para voar rápido se " +"modo voo e rápido estiverem\n" +"habilitados." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Se habilitado, o servidor executará a seleção de oclusão de bloco de mapa " +"com base\n" +"na posição do olho do jogador. Isso pode reduzir o número de blocos\n" +"enviados ao cliente de 50 a 80%. O cliente não receberá mais invisível\n" +"para que a utilidade do modo noclip é reduzida." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Se habilitado juntamente com o modo de vôo, o jogador é capaz de voar " +"através de nós de sólidos.\n" +"Isso requer o privilégio \"noclip\" no servidor." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Se habilitado, a tecla \"especial\" em vez de \"esgueirar\" servirá para\n" +"descer." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Habilitar confirmação de registro quando conectar ao servidor.\n" +"Caso desabilitado, uma nova conta será registrada automaticamente." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Se habilitado, as ações são registradas para reversão.\n" +"Esta opção só é lido quando o servidor é iniciado." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Se habilitado, desabilita prevenção de fraude no modo multijogador." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Se habilitado, dados inválidos do mundo não vão fazer o servidor desligar.\n" +"Só habilite isso, se você souber o que está fazendo." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Se habilitado, faz com que os movimentos sejam relativos ao pitch do jogador " +"quando voando ou nadando." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "Se habilitado, novos jogadores não podem entrar com uma senha vazia." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Se habilitado, você pode colocar os blocos na posição (pés + nível dos " +"olhos) onde você está.\n" +"Isto é útil quando se trabalha com nodeboxes em pequenas áreas." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Se a restrição de CSM para alcançe de nós está habilitado, chamadas get_node " +"são limitadas\n" +"a esta distancia do player até o node." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Se a execução de um comando de chat demorar mais do que o tempo especificado " +"em\n" +"segundos, adicione a informação do tempo na mensagem-comando" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Se o tamanho do arquivo debug.txt exceder o número de megabytes " +"especificado\n" +"nesta configuração quando ele for aberto, o arquivo é movido para debug." +"txt.1,\n" +"excluindo um debug.txt.1 mais antigo, se houver.\n" +"debug.txt só é movido se esta configuração for positiva." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" +"Se isso for definido, os jogadores vão sempre (re)desovar na posição " +"determinada." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ignorar erros do mundo" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Valor alfa do fundo do console do bate-papo no jogo (opacidade, entre 0 e " +"255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Cor de fundo do Bate-papo no jogo (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"Valor alfa do fundo do console do bate-papo no jogo (opacidade, entre 0 e " +"255)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Tecla de aumentar volume" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Velocidade vertical inicial ao saltar, em nós por segundo." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Monitoração embutida.\n" +"Isto é necessário apenas por contribuidores core/builtin" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Instrument chat commands on registration." +msgstr "Monitoração de comandos de chat quando registrados." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Monitorar de chamadas de retorno globais durante a registração.\n" +"(qualquer coisa que você passar ao minetest.register_*() function)" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Monitorar a ação de ação do Active Block Modifiers durante a registração." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Monitorar a ação de ação do Loading Block Modifiers durante a registração." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Monitorar os métodos das entidades durante a registração." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Intervalo para cada salvamento de alterações importantes no mundo, indicado " +"em segundos." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Intervalo de envio de hora do dia para os clientes." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animações nos itens do inventário" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Inventário" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Mouse invertido" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Inverta o movimento vertical do mouse." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Caminho da fonte em itálico" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Caminho da fonte em itálico monoespaçada" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Entidade item TTL" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Monitorização" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Iterações da função recursiva.\n" +"Aumentando isso aumenta a quantidade de detalhes, mas também\n" +"aumenta o tempo de processamento.\n" +"Com iterações = 20, esse gerador de mapa tem um tempo de carregamento " +"similar ao gerador V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID do Joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Intervalo de repetição do botão do Joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "\"Zona morta\" do joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Sensibilidade do frustum do Joystick" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Tipo do Joystick" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Apenas para a configuração de Julia.\n" +"Componente W da constante hipercomplexa.\n" +"Altera o formato do fractal.\n" +"Não tem nenhum efeito em fractais 3D.\n" +"varia aproximadamente entre -2 e 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Apenas para configuração de Julia.\n" +"Componente X da constante hipercomplexa.\n" +"Altera o formato do fractal.\n" +"Varia aproximadamente entre -2 e 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Apenas para configuração de Julia.\n" +"Componente Y da constante hipercomplexa.\n" +"Altera o formato do fractal.\n" +"Varia aproximadamente entre -2 e 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Apenas para configuração de Julia.\n" +"Componente Z da constante hipercomplexa.\n" +"Altera o formato do fractal.\n" +"Varia aproximadamente entre -2 e 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Tecla para Pular" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Velocidade de Pulo" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para diminuir o alcance de visão.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para diminuir o volume.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para escavar. \n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para deixar cair o item atualmente selecionado.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para aumentar o alcance de visão.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para aumentar o volume.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para pular. \n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover-se rápido no modo rápido. \n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para trás.\n" +"Também ira desabilitar o andar para frente automático quando ativo.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a frente.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador à esquerda.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para mover o jogador para a direita.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para por o som em mudo. \n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir a janela de bate-papo para digitar comandos.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir a janela de bate-papo para digitar comandos.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir a janela de bate-papo.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir o inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para colocar objetos. \n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 11th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 12th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 13th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 14th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 15th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 16th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 17th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 18th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 19th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 20th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 21st slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 22nd slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 23rd slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 24th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 25th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 26th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 27th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 28th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 29th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 30th slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 31st slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o 32nd slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o oitavo slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o quinto slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o primeiro slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o quarto slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir o inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o nono slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para abrir o inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o segundo slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o sétimo slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o sexto slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o décimo slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para selecionar o terceiro slot do inventário.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla por esgueirar.\n" +"Também usado para descer e descendente na água se aux1_descends está " +"desativado.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para comutação entre câmera de primeira e terceira pessoa.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para tirar fotos da tela.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar o modo avanço automático.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar modo cinematográfico.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Chave para ativar/desativar a exibição do minimapa.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar o modo rápido.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar a voar.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar modo noclip.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar o modo pitch.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar a atualização da câmera. Usado somente para " +"desenvolvimento\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar a exibição do bate-papo.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar a exibição de informações de depuração.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar a exibição da névoa.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar a exibição do HUD.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar a exibição do bate-papo.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para ativar/desativar a exibição do profiler. Usado para o " +"desenvolvimento.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para alternar o alcance de visão ilimitado.\n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tecla para pular. \n" +"Consulte http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "Expulsar jogadores que enviaram mais de X mensagem por 10 segundos." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Esparsamento de lagos no gerador de mundo plano" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Threshold dos lagos no gerador de mundo plano" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Linguagem" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Profundidade de cavernas grandes" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Número máximo de cavernas grandes" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Número mínimo de cavernas grandes" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Proporção inundada de cavernas grandes" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Tecla do console" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Estilo de folhas" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Folhas de estilo:\n" +"- Fancy: todas as faces visíveis\n" +"- Simple: apenas faces externas, se definidos special_tiles\n" +"- Opaque: desativar transparência" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Tecla para a esquerda" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Comprimento do tick do servidor e o intervalo no qual os objetos são " +"geralmente atualizados em\n" +"rede." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Comprimento das ondas líquidas.\n" +"Requer que a ondulação de líquidos esteja ativada." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Período de tempo entre os ciclos de execução de ABMs" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Período de tempo entre ciclos de execução de NodeTimer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Período de tempo entre os ciclos de gerenciamento de blocos" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Nível de registro a serem gravados em debug.txt:\n" +"- <nothing> (nenhum)\n" +"- none (mensagens sem nível de log)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Aumento da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Centro do aumento da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Extensão do aumento da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Gamma da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Gradiente alto da curva de luz" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Gradiente baixo da curva de luz" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Iluminação suave" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Limite de geração de mapas, em nós, em todas as 6 direções de (0, 0, 0).\n" +"Apenas áreas completas de mapa dentro do limite do mapgen são gerados.\n" +"O valor é armazenado por mundo." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Limites número de solicitações HTTP paralelas. afeta:\n" +"- Media buscar se servidor usa configuração de remote_media.\n" +"- Download de lista de servidores e anúncio do servidor.\n" +"- Transferências realizadas pelo menu principal (por exemplo gerência de " +"mods).\n" +"Só tem efeito se compilado com cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Fluidez líquida" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Suavização do fluido líquido" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Limite de iteração do liquido" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Tempo para limpar a lista de espera para a atualização de líquidos" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Afundamento do líquido" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Intervalo de atualização de líquido em segundos." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Período de atualização dos Líquidos" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Carregar o analizador do jogo" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Carregar o analizador do jogo para coletar dados de analize do jogo\n" +"Providencia o comando /profiler para acessar a analize compiliada.\n" +"Muito util para desenvolvedores de mods e operadores de servidores." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Carregado Block Modifiers" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Menor limite Y de dungeons." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Menor limite Y de ilhas flutuantes." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Menu principal do script" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Fazer cores de névoa e céu dependerem do dia (amanhecer/pôr do sol) e exibir " +"a direção." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Torna todos os líquidos opacos" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Nível de Compressão de Mapa no Armazenamento em Disco" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Nível de Compressão do Mapa na Transferência em Rede" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Diretório do mapa" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Atributos de geração de mapa específicos ao gerador Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Atributos de geração de mapas específicos para o Gerador de mundo Plano.\n" +"Lagos e colinas ocasionalmente podem ser adicionados ao mundo plano." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Atributos de geração de mapas específicos para o Gerador de mundo Fractal.\n" +"'terreno' permite a geração de terreno não fractal:\n" +"oceano, ilhas e subterrâneos." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Atributos de geração de mapa específicos ao gerador Valleys.\n" +"'altitude_chill':Reduz o calor com a altitude.\n" +"'humid_rivers':Aumenta a umidade em volta dos rios.\n" +"'profundidade_variada_rios': Se habilitado, baixa umidade e alto calor faz " +"com que rios\n" +"se tornem mais rasos e eventualmente sumam.\n" +"'altitude_dry': Reduz a umidade com a altitude." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Atributos de geração de mapa específicos ao gerador V5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Atributos de geração de mapas específicos para Gerador de mapas v6.\n" +"A opção 'snowbiomes' habilita o novo sistema de 5 biomas.\n" +"Quando a opção 'snowbiomes' está ativada, as selvas são ativadas " +"automaticamente e\n" +"a opção 'jungles' é ignorada." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Atributos de geração de mapas específicos para Gerador de mapas v7.\n" +"'ridges': rios.\n" +"'floatlands': massas de terra flutuantes na atmosfera.\n" +"'caverns': cavernas gigantes no subsolo." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Limite de geração de mapa" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Intervalo de salvamento de mapa" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map shadows update frames" +msgstr "Tempo de atualização do mapa" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Limite de mapblock" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Intervalo de geração de mapa" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" +"Tamanho em MB da memória cache de MapBlock para o gerador de Malha de " +"Mapblock" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Tempo limite de descarregamento do mapblock" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Gerador de mundo Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Flags específicas do gerador de mundo Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Gerador de mundo plano" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Flags específicas do gerador de mundo plano" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Gerador de mundo Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Opções específicas do Gerador de mapas Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Gerador de mundo V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Flags específicas do gerador de mundo V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Gerador de mundo V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Flags específicas do gerador de mundo V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Gerador de mundo V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Flags específicas do gerador de mundo V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Vales do Mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Flags específicas do gerador de mundo Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Debug do mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Nome do gerador de mundo" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Distância máxima de geração de bloco" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Distância máxima de envio de bloco" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Máximo de líquidos processados por etapa." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Max. clearobjects blocos extras" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Max. pacotes por iteração" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "FPS máximo" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"FPS máximo quando a janela não está com foco, ou quando o jogo é pausado." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Distância máxima para renderizar sombras." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Máximo de blocos carregados forçadamente" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Largura máxima da hotbar" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "Limite máximo do número aleatório de cavernas grandes por mapchunk." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "Limite máximo do número aleatório de cavernas pequenas por mapchunk." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Resistência líquida máxima. Controla desaceleração ao entrar num líquido\n" +"em alta velocidade." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Número máximo de blocos que são enviados simultaneamente por cliente.\n" +"O total máximo é calculado dinamicamente:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" +"Número máximo de blocos que podem ser enfileirados para o carregamento." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Número máximo de blocos para serem enfileirado, dos que estão para ser " +"gerados.\n" +"Esse limite é forçado para cada jogador." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Número máximo de blocos para serem enfileirado, dos que estão para ser " +"carregados do arquivo.\n" +"Esse limite é forçado para cada jogador." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Número máximo de downloads paralelos. Downloads excedendo esse limite " +"esperarão numa fila.\n" +"Deve ser menor que curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Número máximo de chunks carregados forçadamente." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Número máximo de mapblocks para o cliente para ser mantido na memória.\n" +"Definido como -1 para quantidade ilimitada." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Número máximo de pacotes enviados por etapa de envio, se você tem uma " +"conexão lenta\n" +"tente reduzir isso, mas não reduza a um número abaixo do dobro do\n" +"número de cliente alvo." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Número máximo de jogadores que podem se conectar simultaneamente." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Número máximo de mensagens recentes mostradas" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Número máximo de objetos estaticamente armazenados em um bloco." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Limite maximo de objetos por bloco" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Proporção máxima da janela atual a ser usada para hotbar.\n" +"Útil se houver algo para ser exibido a direito ou esquerda do hotbar." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Máximo de blocos enviados simultaneamente por cliente" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Tamanho máximo da fila do chat" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Tamanho máximo da fila do chat.\n" +"0 para desabilitar a fila e -1 para a tornar ilimitada." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Tempo máximo em ms para download de arquivo (por exemplo, um mod) pode tomar." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Tempo máximo que um pedido interativo (ex: busca de lista de servidores) " +"pode levar, em milissegundos." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Limite de usuários" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Cache de malha" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Mensagem do dia" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Mensagem do dia exibida aos jogadores ao conectar." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Método usado para destacar o objeto selecionado." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Nível mínimo de registro a ser impresso no chat." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Tecla do Minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Altura de escaneamento do minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Limite mínimo do número aleatório de grandes cavernas por mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Limite mínimo do número aleatório de cavernas pequenas por mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Tamanho mínimo da textura" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mipmapping (filtro)" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Analizador" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Segurança" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Canais de mod" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Modifica o tamanho dos elementos do hudbar." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Caminho de fonte monoespaçada" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Tamanho da fonte monoespaçada" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "Tamanho da fonte monoespaçada" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Parâmetros ruido da altura de montagem do gerador de mundo v7" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Ruído da montanha" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Ruído de variação da montanha" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Nível zero da montanha" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Sensibilidade do mouse" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Multiplicador de sensibilidade do mouse." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Ruído de Lama" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Multiplicador para cair balançando.\n" +"Por exemplo: 0 para não ver balançando; 1.0 para normal; 2.0 para duplo." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Tecla de Emudecer" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Mutar som" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Nome do gerador de mapas a ser usado ao criar um novo mundo.\n" +"Criar um mundo no menu principal substituirá isso.\n" +"Geradores de mapa atuais em um estado altamente instável:\n" +"- A opção de ilhas flutuantes do Gerador de mapas de v7 (desabilitado por " +"padrão)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Nome do jogador.\n" +"Quando executando um servidor, os clientes com este nome são " +"administradores.\n" +"Quando iniciado pelo menu principal, este é substituido." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Nome do servidor, a ser exibido quando os jogadores abrem a lista de " +"servidores." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Plano próximo" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Porta de rede para receber dados (UDP).\n" +"Esse valor será substituído se for definido a partir do menu principal." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Rede" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Novos usuários precisam inserir esta senha." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Atravessar blocos" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Tecla Noclip" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Destaque nos Blocos" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Destacamento do bloco" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Intervalo de NodeTimer" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Ruidos" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Número de seguimentos de emersão" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Número de threads de emersão a serem usadas.\n" +"Valor 0:\n" +"- Seleção automática. O número de threads de emersão será\n" +"- 'número de processadores - 2', com um limite inferior de 1.\n" +"Qualquer outro valor:\n" +"- Especifica o número de threads de emersão, com um limite inferior de 1.\n" +"AVISO: Aumentar o número de threads de emersão aumenta a velocidade do motor " +"de\n" +"geração de mapas, mas isso pode prejudicar o desempenho do jogo, " +"interferindo com outros\n" +"processos, especialmente em singleplayer e / ou ao executar código Lua em " +"eventos\n" +"'on_generated'. Para muitos usuários, a configuração ideal pode ser '1'." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Número de blocos extras que pode ser carregados por /clearobjects ao mesmo " +"tempo.\n" +"Esta é uma troca entre sobrecarga de transação do sqlite e\n" +"consumo de memória (4096 = 100 MB, como uma regra de ouro)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Líquidos Opacos" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "Opacidade (alpha) das sombras atrás da fonte padrão, entre 0 e 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Abre o menu de pausa quando o foco da janela é perdido.Não pausa se um " +"formspec está\n" +"aberto." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Substituição opcional da cor do link do bate-papo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Caminho da fonte de fallback. Deve ser uma fonte TrueType.\n" +"Essa fonte será usada para determinados idiomas ou se a fonte padrão não " +"estiver disponível." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Caminho para salvar capturas de tela. Pode ser absoluto ou relativo.\n" +"A pasta será criada se já não existe." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Caminho para o diretório \"shader\". Se nenhum caminho estiver definido, o " +"local padrão será usado." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" +"Caminho para o diretório de texturas. Todas as texturas são pesquisadas " +"primeiro daqui." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Caminho para a fonte padrão. Deve ser uma fonte TrueType.\n" +"A fonte de fallback será usada se a fonte não puder ser carregada." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Caminho para a fonte monoespaçada. Deve ser uma fonte TrueType.\n" +"Esta fonte é usada para, por exemplo, a tela do console e do criador de " +"perfil." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Pausa quando o foco da janela é perdido" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" +"Limite de blocos na fila de espera de carregamento do disco por jogador" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Limite por jogador de blocos enfileirados para gerar" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Física" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Tecla de movimento pitch" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Modo movimento pitch" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Tecla de colocar" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Intervalo de repetição da ação colocar" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"O jogador é capaz de voar sem ser afetado pela gravidade.\n" +"Isso requer o privilégio \"fly\" no servidor." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Distância de transferência do jogador" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Jogador contra jogador" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Filtragem de Poisson" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Porta para conectar (UDP).\n" +"Note que o campo Porta no menu principal substitui essa configuração." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Evita remoção e colocação de blocos repetidos quando os botoes do mouse são " +"segurados.\n" +"Habilite isto quando você cava ou coloca blocos constantemente por acidente." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Impede que mods façam coisas inseguras como executar comandos do shell." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Intervalo de impressão de dados do analisador (em segundos).\n" +"0 = desabilitado. Útil para desenvolvedores." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Privilégios que jogadores com basic_privs podem conceder" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Analizador" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Tecla de alternância do Analizador" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Endereço do Prometheus" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Endereço do Prometheus\n" +"Se o minetest for compilado com a opção ENABLE_PROMETHEUS ativa,\n" +"habilita a obtenção de métricas do Prometheus neste endereço.\n" +"As métricas podem ser obtidas em http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Proporção de cavernas grandes que contém líquido." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Raio da área de nuvem afirmada em número de 64 nós de quadrados de nuvem.\n" +"Valores maiores que 26 vão começar a produzir cortes afiados nos cantos de " +"área de nuvem." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Eleva o terreno para fazer vales em torno dos rios." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Entrada aleatória" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Tecla para modo de visão ilimitado" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Mensagens de chat recentes" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Caminho da fonte regular" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Mídia remota" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Porta remota" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Remove códigos de cor de futuras mensagens do chat.\n" +"Use isto para impedir que jogadores usem cor em suas mensagens" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Substitui o menu principal padrão por um personalizado." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Diretorio de reporte" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Restringe o acesso de certas funções a nível de cliente em servidores.\n" +"Combine os byflags abaixo par restringir recursos de nível de cliente, ou " +"coloque 0\n" +"para nenhuma restrição:\n" +"LOAD_CLIENT_MODS: 1 (desabilita o carregamento de mods de cliente)\n" +"CHAT_MESSAGES: 2 (desabilita a chamada send_chat_message no lado do " +"cliente)\n" +"READ_ITEMDEFS: 4 (desabilita a chamada get_item_def no lado do cliente)\n" +"READ_NODEDEFS: 8 (desabilita a chamada get_node_def no lado do cliente)\n" +"LOOKUP_NODES_LIMIT: 16 (limita a chamada get_node no lado do cliente para\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (desabilita a chamada get_player_names no lado do " +"cliente)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Ruído de extensão do cume de montanhas" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Ruido do Rio" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Ruído Subaquático" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Ruído do tamanho de montanhas acidentadas" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Tecla direita" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Profundidade do canal do rio" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Largura do canal do rio" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Profundidade do Rio" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Ruido do Rio" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Tamanho do Rio" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Largura do vale do rio" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Gravação de reversão" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Tamanho do ruído de colinas rolantes" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Extensão do ruído de colinas rolantes" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Minimapa redondo" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Remoção e colocação segura" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Praias de areia ocorrem quando \"np_beach\" excede esse valor." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Salvar o mapa recebido pelo cliente no disco." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Salve automaticamente o tamanho da janela quando modificado." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Salvado mapa recebido do servidor" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Escala de GUI por um valor especificado pelo usuário.\n" +"Use um filtro nearest-neighbor-anti-alias para escala do GUI.\n" +"Isso irá suavizar algumas das arestas e misturar pixels \n" +"quando a escala é reduzida, ao custo de borrar alguns pixels da borda \n" +"quando as imagens são dimensionadas em tamanhos não-inteiros." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Tela:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Altura da tela" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Largura da tela" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Pasta de screenshot" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Formato da Captura de tela" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Qualidade da Captura de tela" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Qualidade de imagem. Usado somente para o formato JPEG.\n" +"1 significa pior qualidade; 100 significa melhor qualidade.\n" +"Use 0 para qualidade padrão." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Captura de tela" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Ruído nas cavernas #1" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Segundo de 4 ruídos 2D que juntos definem a altura de colinas/montanhas." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Segundo de 2 ruídos 3D que juntos definem tunéis." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Consulte http://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Cor da borda da caixa de seleção (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Cor da caixa de seleção" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Largura da caixa de seleção" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Escolha um dos 18 tipos de fractais.\n" +"1 = Conjunto de mandelbrot \"Roundy\" 4D.\n" +"2 = Conjunto de julia \"Roundy\" 4D.\n" +"3 = Conjunto de mandelbrot \"Squarry\" 4D.\n" +"4 = Conjunto de julia \"Squarry\" 4D.\n" +"5 = Conjunto de mandelbrot \"Mandy Cousin\" 4D.\n" +"6 = Conjunto de julia \"Mandy Cousin\" 4D.\n" +"7 = Conjunto de mandelbrot \"Variation\" 4D.\n" +"8 = Conjunto de julia \"Variation\" 4D.\n" +"9 = Conjunto de mandelbrot \"Mandelbrot/Mandelbar\" 3D.\n" +"10 = Conjunto de julia \"Mandelbrot/Mandelbar\" 3D.\n" +"11 = Conjunto de mandelbrot \"Árvore de natal\" 3D.\n" +"12 = Conjunto de julia \"Árvore de natal\" 3D..\n" +"13 = Conjunto de mandelbrot \"Bulbo de Mandelbrot\" 3D.\n" +"14 = Conjunto de julia \"Bulbo de Mandelbrot\" 3D.\n" +"15 = Conjunto de mandelbrot \"Bulbo de Mandelbrot Cosseno\" 3D.\n" +"16 = Conjunto de julia \"Bulbo de Mandelbrot Cosseno\" 3D.\n" +"17 = Conjunto de mandelbrot \"Bulbo de Mandelbrot\" 4D.\n" +"18 = Conjunto de julia \"Bulbo de Mandelbrot\" 4D." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL do servidor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Nome do servidor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Descrição do servidor" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL do servidor" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Endereço do servidor" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Descrição do servidor" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Nome do servidor" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Porta do servidor" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Separação de oclusão no lado do servidor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Porta do Servidor" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL da lista de servidores" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "URL da lista de servidores" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Arquivo da lista de servidores" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Defina o idioma. Deixe vazio para usar a linguagem do sistema.\n" +"Apos mudar isso uma reinicialização é necessária." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Configura o tamanho máximo de caracteres de uma mensagem enviada por " +"clientes." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Defina a força da sombra.\n" +"Valores mais baixo significam sombras mais brandas, valores mais altos " +"significam sombras mais fortes." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Defina o tamanho do raio de sombras suaves.\n" +"Valores mais baixos significam sombras mais nítidas e valores altos sombras " +"suaves.\n" +"Valor mínimo 1.0 e valor máximo 10.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Defina a inclinação da órbita do Sol/Lua em graus\n" +"Valor 0 significa sem inclinação/ órbita vertical.\n" +"Valor mínimo de 0.0 e máximo de 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Defina para true para ativar o Mapeamento de Sombras.\n" +"Requer sombreadores para ser ativado." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Definido como true habilita o balanço das folhas.\n" +"Requer que os sombreadores estejam ativados." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Definido como true permite ondulação de líquidos (como a água).\n" +"Requer que os sombreadores estejam ativados." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Definido como true permite balanço de plantas.\n" +"Requer que os sombreadores estejam ativados." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Define a qualidade da textura das sombras para 32 bits.\n" +"Quando false, a textura de 16 bits será usada\n" +"Isso pode fazer com que muito mais coisas aparecam nas sombras." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Sombreadores" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Sombreadores permitem efeitos visuais avançados e podem aumentar a " +"performance em algumas\n" +"placas de vídeo.\n" +"Só funcionam com o modo de vídeo OpenGL." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Qualidade do filtro de sombras" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "Distância do mapa de sombras em nodes para renderizar sombras" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "Textura do mapa de sombras em 32 bits" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Tamanho da textura do mapa de sombras" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Distância (em pixels) da sombra da fonte padrão. Se 0, então a sombra não " +"será desenhada." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "Força da sombra" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Forma do minimapa. Ativado = redondo, Desativado = quadrado." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Mostrar informações de depuração" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Mostrar as caixas de seleção entidades" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Mostrar caixas de seleção de entidades\n" +"É necessário reiniciar após alterar isso." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Mostrar plano de fundo da nametag por padrão" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Mensagem de desligamento" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Tamanho dos mapchunks gerados pelo gerador de mapa, em mapblocks(16 nós).\n" +"ALERTA!: Não há benefício e existem diversos perigos em\n" +"aumentar este valor acima de 5.\n" +"Reduzir este valor aumenta a densidade de dungeons e cavernas.\n" +"Alterar este valor é para uso especial, é recomendado deixar\n" +"inalterado." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Tamanho da memória cache do MapBlock do gerador de malha. Aumentar isso " +"aumentará\n" +"o percentual de hit do cache, reduzindo os dados sendo copiados do " +"encadeamento principal\n" +", reduzindo assim o jitter." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Inclinação Da Órbita Do Céu" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Fatia w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Inclinação e preenchimento trabalham juntos para modificar as alturas." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Número máximo de cavernas pequenas" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Número mínimo de cavernas pequenas" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" +"Variação de umidade em pequena escala para misturar biomas nas fronteiras." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" +"Variação de temperatura em pequena escala para misturar biomas nas bordas." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Iluminação suave" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Suaviza o movimento da câmera quando olhando ao redor. Também chamado de " +"olhar ou suavização do mouse.\n" +"Útil para gravar vídeos." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "Suaviza a rotação da câmera no modo cinemático. 0 para desativar." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Suaviza a rotação da câmera. 0 para desativar." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Esgueirar" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Velocidade da furtividade" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Velocidade ao esgueirar-se, em nós (blocos) por segundo." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Raio das sombras suaves" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Som" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Especifica a URL no qual os clientes buscam a mídia ao em vez de usar o " +"UDP.\n" +"$filename deve ser acessível a partir de $remote_media$filename via cURL \n" +"(obviamente, remote_media deve terminar com uma barra \"/\").\n" +"Arquivos que não estão presentes serão obtidos da maneira usual por UDP." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Especifica o tamanho padrão da pilha de nós, items e ferramentas.\n" +"Note que mods e games talvez definam explicitamente um tamanho para certos " +"(ou todos) os itens." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Espalhe uma atualização completa do mapa de sombras em uma determinada " +"quantidade de quadros.\n" +"Valores mais altos podem tornar as sombras lentas, valores mais baixos\n" +"consumirá mais recursos.\n" +"Valor mínimo: 1; valor máximo: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Ampliação da faixa de aumento da curva de luz.\n" +"Controla a largura do intervalo a ser aumentado.\n" +"O desvio padrão da gaussiana do aumento da curva de luz." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Ponto de spawn estático" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Ruído de declive" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Tamanho do ruído da montanha de passo" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Extensão do ruído da montanha de passo" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Força da paralaxe do modo 3D." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Aumento da força da curva de luz.\n" +"Os 3 parâmetros de 'aumento' definem uma faixa\n" +"da curva de luz que é aumentada em brilho." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Verificação rígida de protocolo" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Códigos de faixa de cor" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Nível de superfície de água opcional colocada em uma camada sólida de " +"flutuação.\n" +"A água está desativada por padrão e só será colocada se este valor for " +"definido\n" +"acima de 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (o início do\n" +"afilamento superior).\n" +"*** AVISO, POTENCIAL PERIGO PARA OS MUNDOS E DESEMPENHO DO SERVIDOR ***:\n" +"Ao habilitar a colocação de água, as áreas flutuantes devem ser configuradas " +"e testadas\n" +"para ser uma camada sólida, definindo 'mgv7_floatland_density' para 2.0 (ou " +"outro\n" +"valor necessário dependendo de 'mgv7_np_floatland'), para evitar\n" +"fluxo de água extremo intensivo do servidor e para evitar grandes inundações " +"do\n" +"superfície do mundo abaixo." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "SQLite síncrono" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Variação de temperatura para biomas." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Configurações" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Ruído alternativo do terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Altura do terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Altura do terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Altura do terreno" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Altura do terreno" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Limite de ruido de terreno para colinas.\n" +"Proporção de controles da área de mundo coberta pelas colinas.\n" +"Ajuste no sentido 0,0 para uma proporção maior." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Limite de ruido de terreno para Lagos.\n" +"Proporção de controles da área de mundo coberta por lagos.\n" +"Ajuste no sentido 0,0 para uma proporção maior." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Ruído de persistência do terreno" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Diretorio da textura" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Tamanho da textura em que o mapa de sombras será renderizado em.\n" +"Deve ser um múltiplo de dois.\n" +"Números maiores criam sombras melhores mas também esvazia a conta do banco." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Texturas em um nó podem ser alinhadas ao próprio nó ou ao mundo.\n" +"O modo antigo serve melhor para coisas como maquinas, móveis, etc, enquanto\n" +"o novo faz com que escadas e microblocos encaixem melhor a sua volta.\n" +"Entretanto, como essa é uma possibilidade nova, não deve ser usada em " +"servidores antigos,\n" +"essa opção pode ser forçada para certos tipos de nós. Note que esta opção\n" +"é considerada EXPERIMENTAL e pode não funcionar adequadamente." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "A url para o repositório de conteúdo" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "A zona morta do joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"O formato padrão no qual as analises estão sendo salvas,\n" +"Quando chamado `/profiler save [formato]` sem formato." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "A profundidade do preenchimento de terra ou outro enchimento de bioma." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"O caminho de arquivo relativo ao sua pasta do mundo no qual as analises " +"serão salvas." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "O identificador do joystick para usar" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"A largura em pixels necessária para interação de tela de toque começar." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"A altura máxima da superfície de líquidos com ondas.\n" +"4.0 = Altura da onda é dois nós.\n" +"0.0 = Onda nem se move.\n" +"O padrão é 1.0 (meio nó).\n" +"Requer ondas em líquidos habilitada." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "A interface de rede no qual o servidor escuta (aguarda conexão)." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Os privilégios que novos usuários obtém automaticamente.\n" +"Consulte /privs no jogo para obter uma lista completa na configuração do seu " +"servidor e dos modificadores." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"O raio do volume dos blocos em torno de cada jogador que está sujeito ao\n" +"material de bloco ativo, declarado em mapblocks (16 nós).\n" +"Nos blocos ativos, os objetos são carregados e os ABMs executados.\n" +"Este também é o intervalo mínimo no qual os objetos ativos (mobs) são " +"mantidos.\n" +"Isso deve ser configurado junto com active_object_send_range_blocks." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"O back-end de renderização.\n" +"É necessário reiniciar após alterar isso.\n" +"Nota: No Android, use OGLES1 se não tiver certeza! O aplicativo pode falhar " +"ao iniciar de outra forma.\n" +"Em outras plataformas, OpenGL é recomendado.\n" +"Shaders são suportados por OpenGL (somente desktop) e OGLES2 (experimental)" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"A sensibilidade dos eixos do joystick para movimentar o\n" +"frustum de exibição no jogo." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"A intensidade (escuridão) de sombreamento da oclusão de ambiente no bloco.\n" +"Inferior é mais escura, superior é mais clara. O intervalo válido de valores " +"para esta\n" +"configuração é 0.25 a 4.0. Se o valor está fora do intervalo ele será \n" +"definido o valor válido mais próximo." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"O tempo (em segundos) que a fila de líquidos pode crescer além da " +"capacidade \n" +"de processamento até que é feita uma tentativa para diminuir o seu tamanho " +"pelo despejo \n" +"de antigas filas de itens. Um valor 0 desativa a funcionalidade." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"O tempo disponível permitido para ABMs executarem em cada passo\n" +"(como uma fração do intervalo do ABM)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"O tempo em segundos que leva entre eventos repetidos \n" +"quando pressionando uma combinação de botão no joystick." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"O tempo em segundos que leva entre as colocações de nó repetidas ao segurar\n" +"o botão de colocar." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "O tipo do joystick" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"A distancia vertical onde o calor cai por 20 caso 'altitude_chill' esteja\n" +"habilitado. Também é a distancia vertical onde a umidade cai por 10 se\n" +"'altitude_dry' estiver habilitado." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Terceiro de 4 ruídos 2D que juntos definem a altura de colinas/montanhas." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Tempo em segundos para manter entidade de item (itens caídos/dropados).\n" +"Definindo-o como -1 desabilita o recurso." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "Hora do dia quando um novo mundo é iniciado, em milihoras (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Intervalo de tempo de envio" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Velocidade de tempo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Tempo de espera para o cliente remover dados de mapa não utilizados da " +"memória." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Para reduzir o lag, transferências de blocos são desaceleradas quando um " +"jogador está construindo algo.\n" +"Isto determina por quanto tempo eles são desacelerados após a colocação ou " +"remoção de um node." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Tecla de alternância do modo de câmera" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Atraso de dica de ferramenta" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Limiar a tela de toque" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Limiar a tela de toque" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Tradeoffs for performance" +msgstr "Trocas por desempenho" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Ruido de árvores" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Filtragem tri-linear" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"Útil para suavizar o minimapa em máquinas mais lentas." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Modulos confiáveis" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL para a lista de servidores exibida na guia Multiplayer." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Subamostragem" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"A subamostragem é semelhante a usar uma resolução de tela inferior, mas se " +"aplica\n" +"apenas para o mundo do jogo, mantendo a GUI intacta.\n" +"Deve dar um aumento significativo de desempenho ao custo de uma imagem menos " +"detalhada.\n" +"Valores mais altos resultam em uma imagem menos detalhada." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Distância de transferência do jogador ilimitada" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Descarregar os dados do servidor não utilizados" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Limite topo Y de dungeons." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Limite máximo Y para as ilhas flutuantes." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Usar nuvens 3D em vez de planas." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Usar uma animação de nuvem para o fundo do menu principal." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "Usar filtragem anisotrópica quando visualizar texturas de um ângulo." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Usar filtragem bilinear ao dimensionamento de texturas." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Usar mip mapping para escalar texturas. Pode aumentar a performance " +"levemente,\n" +"especialmente quando usando um pacote de texturas em alta resolução.\n" +"O downscaling correto de gama não é suportado." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Use o anti-serrilhamento de várias amostras (MSAA) para suavizar as bordas " +"do bloco.\n" +"Este algoritmo suaviza a janela de visualização 3D enquanto mantém a imagem " +"nítida,\n" +"mas não afeta o interior das texturas\n" +"(que é especialmente perceptível com texturas transparentes).\n" +"Espaços visíveis aparecem entre os nós quando os sombreadores são " +"desativados.\n" +"Se definido como 0, MSAA é desativado.\n" +"É necessário reiniciar após alterar esta opção." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Use a filtragem trilinear ao dimensionamento de texturas." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Sincronização Vertical" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Profundidade do vale" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Preenchimento do vale" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Perfil do vale" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Encosta do vale" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Variação da profundidade de preenchimento do bioma." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Variação da altura máxima da montanha (nos nós)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Variação do número de cavernas." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Variação da escala vertical do terreno.\n" +"Quando o ruído é menor que -0,55 o terreno é quase plano." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Varia a profundidade dos nós da superfície do bioma." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Varia a aspereza do terreno.\n" +"Define o valor de 'persistência' para os ruídos \"terrain_base\" e " +"\"terrain_alt\"." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Controla o esparsamento/altura das colinas." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Velocidade vertical de escalda, em nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Sincronização vertical da tela." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Driver de vídeo" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Visualização de balanço" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Distância de visão (em nós)." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Tecla de diminuição do raio de exibição" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Tecla de aumento do intervalo de exibição" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Tecla de visão em zoom" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Intervalo de visualização" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "Joystick virtual ativa botão especial" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Volume do som" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Volume de todos os sons.\n" +"Requer que o sistema de som esteja ativado." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"W coordenada da fatia 3D gerada de um fractal 4D.\n" +"Determina qual a fatia 3D da forma 4D que é gerada.\n" +"Altera a forma do fractal.\n" +"Não tem efeito sobre os fractais 3D.\n" +"Alcance aproximado de -2 a 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Velocidade do andar e voar, em nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Velocidade de caminhada" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Velocidade do caminhar, voar e escalar no modo rápido, em nós por segundo." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Nível de água" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Nível de superfície de água do mundo." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Nós que balancam" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Balanço das árvores" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Líquidos ondulantes" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Altura da onda nos líquidos ondulantes" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Velocidade de balanço da água" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Comprimento de balanço da água" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Balanço das plantas" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "Cor da caixa de seleção" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Quando gui_scaling_filter é true, todas as imagens de GUI precisam ser\n" +"filtrado no software, porém algumas imagens são geradas diretamente ao\n" +"hardware (por exemplo render-to-texture para nodes no inventário)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Quando gui_scaling_filter_txr2img é true, copie essas imagens\n" +"de hardware para software para dimensionamento. Quando false,\n" +"voltará para o velho método de dimensionamento, para drivers de\n" +"vídeo que não suportem propriedades baixas de texturas voltam do hardware." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Ao usar filtros bilineares/trilinear/anisotrópica, texturas de baixa " +"resolução\n" +"podem ficar borradas, então automaticamente aumenta a escala deles com a " +"interpolação\n" +"de nearest-neighbor para preservar os pixels nítidos. Isto define o tamanho\n" +"mínimo da textura para as texturas melhoradas; valores mais altos parecem\n" +"mais nítidos, mas requerem mais memória. Potências de 2 são recomendadas.\n" +"Essa configuração superior a 1 pode não ter um efeito visível, a menos que " +"a \n" +"filtragem bilineares/trilinear/anisotrópica estejam habilitadas.\n" +"Isso também é usado como tamanho base da textura para autoescalamento de " +"texturas." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Se os planos de fundo das nametags devem ser mostradas por padrão.\n" +"Mods ainda poderão definir um plano de fundo." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"Se as animações de textura do nodes devem ser dessincronizadas por mapblock." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Se os jogadores são mostrados para os clientes sem qualquer limite de " +"distância.\n" +"Caso não desejar, use a configuração player_transfer_distance." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Se deseja permitir aos jogadores causar dano e matar uns aos outros." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Se deseja perguntar aos clientes para reconectarem depois de uma queda " +"(Lua).\n" +"Defina como true se o servidor está configurado para reiniciar " +"automaticamente." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Se for usar névoa no fim da área visível." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Quando mutar os sons. Você pode mutar os sons a qualquer hora, a não ser\n" +"que o sistema de som esteja desabilitado (enable_sound=false).\n" +"No jogo, você pode habilitar o estado de mutado com o botão de mutar\n" +"ou usando o menu de pausa." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"Se deseja mostrar informação de depuração ao cliente (tem o mesmo efeito " +"como teclar F5)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Componente de tamanho da janela inicial. Ignorado em modo de tela cheia." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Largura das linhas do bloco de seleção em torno de nodes." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Somente no sistemas Windows: Inicie o Minetest com a janela da linha de " +"comando em segundo plano.\n" +"Contém as mesmas informações que o arquivo debug.txt (nome padrão)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Diretório de mundo (tudo no mundo está armazenado aqui).\n" +"Não é necessário se for iniciado a partir do menu principal." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Horário inicial do mundo" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Texturas alinhadas ao mundo podem ser escaladas em vários nós. Entretanto,\n" +"o servidor pode não enviar a escala desejada, especialmente se você usa\n" +"um pacote de textura especialmente projetado; com está opção, o cliente " +"tenta\n" +"determinar a escala automaticamente baseado no tamanho da textura.\n" +"Veja também texture_min_size.\n" +"Alerta: Esta opção é EXPERIMENTAL!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Modo de texturas alinhadas ao mundo" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Componente Y de terreno plano." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y da densidade gradiente zero de montanhas. Usado para deslocar montanhas " +"verticalmente." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Limite Y máximo de grandes cavernas." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" +"Distância em Y sobre a qual as cavernas se expandem até o tamanho total." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Distância de Y sobre a qual as ilhas flutuantes diminuem de densidade total " +"para nenhuma densidade.\n" +"O afunilamento começa nesta distância do limite Y.\n" +"Para uma ilha flutuante sólida, isso controla a altura das colinas / " +"montanhas.\n" +"Deve ser menor ou igual a metade da distância entre os limites Y." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Nível em Y da superfície média do terreno." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Nível em Y do limite superior da caverna." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Nível Y de terreno que cria penhascos." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Nível Y de terreno inferior e solo oceânico." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Nível Y do fundo do mar." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Tempo limite de download de arquivo via cURL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "Tempo limite de cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "limite paralelo de cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Modo Criativo: " + +#~ msgid "- Damage: " +#~ msgstr "-Dano: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = oclusão paralaxe com dados de inclinação (mais rápido).\n" +#~ "1 = mapeamento de relevo (mais lento, mais preciso)." + +#~ msgid "Address / Port" +#~ msgstr "Endereço / Porta" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Ajustar a gama de codificação para a tabela de claridade. Os números mais " +#~ "elevados são mais brilhantes.\n" +#~ "Esta configuração é somente para o cliente e é ignorada pelo servidor." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "" +#~ "Altera como terras flutuantes montanhosas afunilam acima e abaixo do " +#~ "ponto médio." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Você tem certeza que deseja resetar seu mundo um-jogador?" + +#~ msgid "Back" +#~ msgstr "Backspace" + +#~ msgid "Basic" +#~ msgstr "Básico" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "" +#~ "Bits por pixel (Também conhecido como profundidade de cor) no modo de " +#~ "tela cheia." + +#~ msgid "Bump Mapping" +#~ msgstr "Bump mapping" + +#~ msgid "Bumpmapping" +#~ msgstr "Bump mapping" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "Centro do aumento da curva de luz." + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Mudanças para a interface do menu principal:\n" +#~ " - Total: Múltiplos mundos de um jogador, escolha de jogo, escolha de " +#~ "pacote de texturas, etc.\n" +#~ "- Simples: Um mundo de um jogador, sem escolha de jogo ou pacote de " +#~ "texturas. Pode ser necessário para telas menores." + +#~ msgid "Config mods" +#~ msgstr "Configurar Mods" + +#~ msgid "Configure" +#~ msgstr "Configurar" + +#~ msgid "Connect" +#~ msgstr "Conectar" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Controla a velocidade de afundamento em líquidos." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Controla a densidade do terreno montanhoso nas ilhas flutuantes.\n" +#~ "É um parâmetro adicionado ao valor de ruído 'mgv7_np_mountain'." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Controla a largura dos túneis, um valor menor cria túneis mais largos." + +#~ msgid "Credits" +#~ msgstr "Créditos" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Cor do cursor (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Dano habilitado" + +#~ msgid "Darkness sharpness" +#~ msgstr "Nitidez da escuridão" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Tempo limite padrão para cURL, indicado em milissegundos.\n" +#~ "Só tem efeito se compilado com cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Define áreas de Ilha Flutuante em terreno suavizado.\n" +#~ "Terrenos suavizados ocorrem quando o ruído é menor que zero." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Define processo amostral de textura.\n" +#~ "Um valor mais alto resulta em mapas de normais mais suaves." + +#~ msgid "Del. Favorite" +#~ msgstr "Rem. Favorito" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Baixe um jogo, como Minetest Game, do site minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Baixe um a partir do site minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Baixando e instalando $1, por favor aguarde..." + +#~ msgid "Enable VBO" +#~ msgstr "Habilitar VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "Habilitar registro de confirmação" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Ativar texturização bump mapping para texturas. Normalmaps precisam ser " +#~ "fornecidos pelo\n" +#~ "pacote de textura ou a necessidade de ser auto-gerada.\n" +#~ "Requer shaders a serem ativados." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Habilitar efeito \"filmic tone mapping\"" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Ativa geração de normalmap (efeito de relevo) ao voar.\n" +#~ "Requer texturização bump mapping para ser ativado." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Ativar mapeamento de oclusão de paralaxe.\n" +#~ "Requer shaders a serem ativados." + +#~ msgid "Enter " +#~ msgstr "Entrar " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Opção experimental, pode causar espaços visíveis entre blocos\n" +#~ "quando definido como número maior do que 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS no menu de pausa" + +#~ msgid "Fallback font shadow" +#~ msgstr "Sombra da fonte alternativa" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Alpha da sombra da fonte alternativa" + +#~ msgid "Fallback font size" +#~ msgstr "Tamanho da fonte alternativa" + +#~ msgid "Filtering" +#~ msgstr "Filtros" + +#~ msgid "Floatland base height noise" +#~ msgstr "Altura base de ruído de Ilha Flutuante" + +#~ msgid "Floatland mountain height" +#~ msgstr "Altura da Ilha Flutuante montanhosa" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Fonte alpha de sombra (opacidade, entre 0 e 255)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Tamanho da fonte reserva em pontos (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "Fontes Freetype" + +#~ msgid "Full screen BPP" +#~ msgstr "Tela cheia BPP" + +#~ msgid "Game" +#~ msgstr "Jogo" + +#~ msgid "Gamma" +#~ msgstr "Gama" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Gerar Normal maps" + +#~ msgid "Generate normalmaps" +#~ msgstr "Gerar mapa de normais" + +#~ msgid "HUD scale factor" +#~ msgstr "Fator de escalonamento do painel de interface" + +#~ msgid "High-precision FPU" +#~ msgstr "FPU de alta precisão" + +#~ msgid "IPv6 support." +#~ msgstr "Suporte a IPv6." + +#~ msgid "In-Game" +#~ msgstr "No jogo" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Instalação: arquivo: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Monitorização" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Teclas (se este menu estiver com problema, remova itens do arquivo " +#~ "minetest.conf)" + +#~ msgid "Lava depth" +#~ msgstr "Profundidade da lava" + +#~ msgid "Lightness sharpness" +#~ msgstr "Nitidez da iluminação" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Limite de filas emerge no disco" + +#~ msgid "Main" +#~ msgstr "Principal" + +#~ msgid "Main menu style" +#~ msgstr "Estilo do menu principal" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "Faz o DirectX trabalhar com LuaJIT. Desative se causa problemas." + +#~ msgid "Menus" +#~ msgstr "Opções para menus" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Minimapa em modo radar, zoom 2x" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Minimapa em modo radar, zoom 4x" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Minimapa em modo de superfície, zoom 2x" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Minimapa em modo de superfície, zoom 4x" + +#~ msgid "Name / Password" +#~ msgstr "Nome / Senha" + +#~ msgid "Name/Password" +#~ msgstr "Nome / Senha" + +#~ msgid "No" +#~ msgstr "Não" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Amostragem de normalmaps" + +#~ msgid "Normalmaps strength" +#~ msgstr "Intensidade de normalmaps" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Número de iterações de oclusão de paralaxe." + +#~ msgid "Ok" +#~ msgstr "Ok" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "" +#~ "Opacidade (alpha) da sombra atrás da fonte alternativa, entre 0 e 255." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "" +#~ "Viés geral do efeito de oclusão de paralaxe, geralmente de escala/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Escala global do efeito de oclusão de paralaxe." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Oclusão de paralaxe" + +#~ msgid "Parallax occlusion" +#~ msgstr "Oclusão de paralaxe" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Viés de oclusão de paralaxe" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Iterações de oclusão de paralaxe" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Modo de oclusão de paralaxe" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Escala de Oclusão de paralaxe" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Insinsidade de oclusão de paralaxe" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Caminho para TrueTypeFont ou bitmap." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Caminho para onde salvar screenshots." + +#~ msgid "Player name" +#~ msgstr "Nome do Jogador" + +#~ msgid "Profiling" +#~ msgstr "Analizando" + +#~ msgid "Projecting dungeons" +#~ msgstr "Projetando dungeons" + +#~ msgid "PvP enabled" +#~ msgstr "PvP habilitado" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Resetar mundo um-jogador" + +#~ msgid "Select Package File:" +#~ msgstr "Selecionar o arquivo do pacote:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Servidor / Um jogador" + +#~ msgid "" +#~ "Set the shadow update time.\n" +#~ "Lower value means shadows and map updates faster, but it consume more " +#~ "resources.\n" +#~ "Minimun value 0.001 seconds max value 0.2 seconds" +#~ msgstr "" +#~ "Defina o tempo de atualização das sombras.\n" +#~ "Valores mais baixos significam que sombras e mapa atualizam mais rápido, " +#~ "mas consume mais recursos.\n" +#~ "Valor mínimo 0.001 segundos e valor máximo 0.2 segundos" + +#~ msgid "Shadow limit" +#~ msgstr "Limite de mapblock" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Distância (em pixels) da sombra da fonte de backup. Se 0, então nenhuma " +#~ "sombra será desenhada." + +#~ msgid "Special" +#~ msgstr "Especial" + +#~ msgid "Special key" +#~ msgstr "Tecla especial" + +#~ msgid "Start Singleplayer" +#~ msgstr "Iniciar Um jogador" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Intensidade de normalmaps gerados." + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "Força do aumento médio da curva de luz." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Esta fonte será usada para determinados idiomas." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Para habilitar os sombreadores é necessário usar o driver OpenGL." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Alternar modo de câmera cinemática" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Altura máxima típica, acima e abaixo do ponto médio, do terreno da " +#~ "montanha flutuante." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Variação da altura da colina e profundidade do lago no terreno liso da " +#~ "Terra Flutuante." + +#~ msgid "View" +#~ msgstr "Vista" + +#~ msgid "Waving Water" +#~ msgstr "Ondas na água" + +#~ msgid "Waving water" +#~ msgstr "Balanço da água" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Se as fontes FreeType são usadas, requer que suporte FreeType tenha sido " +#~ "compilado.\n" +#~ "Se desativado, fontes de bitmap e de vetores XML são usadas em seu lugar." + +#~ msgid "Whether dungeons occasionally project from the terrain." +#~ msgstr "Se dungeons ocasionalmente se projetam do terreno." + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Limite Y máximo de lava em grandes cavernas." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "" +#~ "Nível em Y do ponto médio da montanha flutuante e da superfície do lago." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Nível Y para o qual as sombras de ilhas flutuantes se estendem." + +#~ msgid "Yes" +#~ msgstr "Sim" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Você está prestes a entrar no servidor com o nome \"%s\" pela primeira " +#~ "vez. \n" +#~ "Se continuar, uma nova conta usando suas credenciais será criada neste " +#~ "servidor.\n" +#~ "Por favor, confirme sua senha e clique em \"Registrar e Entrar\" para " +#~ "confirmar a criação da conta, ou clique em \"Cancelar\" para abortar." + +#~ msgid "You died." +#~ msgstr "Você morreu." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/ro/minetest.po b/po/ro/minetest.po new file mode 100644 index 0000000..909b33d --- /dev/null +++ b/po/ro/minetest.po @@ -0,0 +1,7233 @@ +msgid "" +msgstr "" +"Project-Id-Version: Romanian (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2021-07-25 23:36+0000\n" +"Last-Translator: Nicolae Crefelean <kneekoo@yahoo.com>\n" +"Language-Team: Romanian <https://hosted.weblate.org/projects/minetest/" +"minetest/ro/>\n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " +"20)) ? 1 : 2;\n" +"X-Generator: Weblate 4.7.2-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Golește coada mesajelor de chat" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Comenzi de chat." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Ieși în meniul principal" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Comandă greșită: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Comanda dată: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Arată jucătorii conectați" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Jucători conectați: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Coada mesajelor de chat a fost golită." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Această comandă este dezactivată de server." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Reînviere" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Ai murit" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Comenzi disponibile:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Comenzi disponibile: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Comandă indisponibilă: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Obține ajutor pentru comenzi" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Folosește „.help <cmd>” pentru detalii sau „.help all” pentru informații " +"complete." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "<none available>" +msgstr "Comandă indisponibilă: " + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "A apărut o eroare într-un script Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "A apărut o eroare:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Meniul principal" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Reconectare" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Serverul cere o reconectare:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Alege modificările" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Nepotrivire versiune protocol. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Serverul forțează versiunea protocolului $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Serverul permite versiuni ale protocolului între $1 și $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Permitem doar versiunea de protocol $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Acceptăm versiuni de protocol între versiunea 1$ și 2$." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Anulează" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Dependențe:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Dezactivează toate" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Dezactivează modpack-ul" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Activează tot" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Activează modpack-ul" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Nu a reușit activarea modului „$ 1”, deoarece conține caractere " +"neautorizate. Doar caracterele [a-z0-9_] sunt permise." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Găsește mai multe modificări" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Nu există dependențe (opționale)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Nu este oferită nicio descriere a jocului." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Nu există dependențe dure" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Nici o descriere a pachetului de moduri nu este furnizată." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Nu există dependențe opționale" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Dependențe opționale:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Salvează" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Lume:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "activat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "„$1” există deja. Doriți s-o suprascrieți?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Dependențele $1 și $2 vor fi instalate." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1, de $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 în descărcare,\n" +"$2 în așteptare" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 se descarcă..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 are dependințe care nu sunt disponibile." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 va fi instalat, iar $2 dependințe vor fi ignorate." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Toate pachetele" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Deja instalată" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Meniul principal" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Jocul de bază:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB nu este disponibilă când Minetest e compilat fără cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Descărcare..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Nu s-a putut descărca $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Jocuri" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instalează" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Instalează $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Instalează dependințele opționale" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "Instalare: tipul de fișier neacceptat „$ 1” sau arhiva ruptă" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Modificări" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Nu s-au putut prelua pachete" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Fără rezultate" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Nu există actualizări" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Indisponibile" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Suprascrie" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Verificați dacă jocul de bază este corect." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "În așteptare" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Pachete de texturi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Dezinstalare" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Actualizare" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Actualizează tot [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Vezi detalii într-un navigator web" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Deja există o lume numită \"$1\"" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Teren suplimentar" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Răcire la altitudine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Ariditate la altitudine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Amestec de biom" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomuri" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Caverne" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Peșteri" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Creează" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Decorațiuni" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Avertisment: Testul de dezvoltare este destinat dezvoltatorilor." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Temnițe" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Teren plat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Mase de teren plutitoare în cer" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Terenuri plutitoare (experimental)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Generare terenuri fără fracturi: Oceane și sub pământ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Dealuri" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Râuri umede" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Mărește umiditea în jurul râurilor" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Instalează $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Lacuri" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Umiditatea redusă și căldura ridicată cauzează râuri superficiale sau uscate" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Gen de hartă" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Steagurile Mapgen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Steaguri specifice Mapgen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Munți" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Curgere de noroi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Rețea de tunele și peșteri" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Nici un joc selectat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Reduce căldura cu altitudinea" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Reduce umiditatea cu altitudinea" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Râuri" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Râuri la nivelul mării" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Seminţe" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Tranziție lină între biomi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Structuri care apar pe teren (fără efect asupra copacilor și a ierbii de " +"junglă creați de v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Structuri care apar pe teren, tipic copaci și plante" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Temperat, Deșert" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Temperat, Deșert, Junglă" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Temperat, Deșert, Junglă, Tundră, Taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Eroziunea suprafeței terenului" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Copaci și iarbă de junglă" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Adâncimea râului variază" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Caverne foarte mari adânc în pământ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Numele lumii" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Nu aveți jocuri instalate." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Ești sigur că vrei să ștergi \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Șterge" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: nu a reușit să ștergeți \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "Pkgmgr: calea nevalidă '$ 1'" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Ștergi lumea \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Confirmarea parolei" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Numele Mapgen" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Nume" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Parola" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Parolele nu se potrivesc!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Înregistrează-te și Alătură-te" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Acceptă" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Redenumiți Pachetul de moduri:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Acest modpack are un nume explicit dat în modpack.conf, care va înlocui " +"orice redenumire aici." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Nicio descriere a setării date)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D Zgomot" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Înapoi la pagina de setări" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Navighează" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Conţinut" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Conţinut" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Dezactivat" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Editează" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Activat" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lacunaritate" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Octava" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Decalaj" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Persistență" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Vă rugăm să introduceți un număr întreg valid." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Vă rugăm să introduceți un număr valid." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Restabilește valori implicite" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Scală" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Caută" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Selectează directorul" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Selectează fila" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Afișați numele tehnice" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Valoarea trebuie să fie de cel puțin $ 1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Valoarea nu trebuie să fie mai mare de $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "expansiunea X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y răspândit" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z răspândit" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "valoareabs" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "implicite" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "uşura" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Activat)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 moduri" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Eșuare la instalarea $1 în $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Instalare mod: nu se poate găsi numele real pentru: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Instalare Mod: nu se poate găsi nume de folder potrivit pentru pachetul de " +"moduri $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Nu se poate găsi un mod sau un pachet de moduri valid" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Imposibil de instalat un $1 ca pachet de textură" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Imposibil de instalat un joc ca $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Imposibil de instalat un mod ca $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Imposibil de instalat un pachet de moduri ca $ 1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Se încarcă..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Lista de servere publice este dezactivată" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Încercați să activați lista de servere publică și să vă verificați " +"conexiunea la internet." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Despre" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Contribuitori activi" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Tipul curent de randare:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Dezvoltatori de bază" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Deschide directorul cu datele utilizatorului" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Deschide într-un manager de fișiere directorul care conține lumile,\n" +"jocurile, modificările și texturile furnizate de utilizator." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Foști contribuitori" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Dezvoltatori de bază precedenți" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Căutați conținut online" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Conţinut" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Dezactivați pachetul de textură" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informații:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Pachete instalate:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Fără dependențe." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Nu există descriere a pachetului disponibilă" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Redenumiți" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Dezinstalați pachetul" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Folosiți pachetul de textură" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Anunțare server" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Adresa legată" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Modul Creativ" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Activează Daune" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Găzduiește joc" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Găzduiește Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Instalarea jocurilor din ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Nou" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Nicio lume creată sau selectată!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Joacă jocul" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Alege modificările" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Selectează lumea:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Port server" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Începe Jocul" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adresă" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Șterge" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Modul Creativ" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Daune / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favorite" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Servere incompatibile" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Alatură-te jocului" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Servere publice" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Actualizează" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Şterge Favorit" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Descrierea serverului" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Nori 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Toate setările" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Antialiasing:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Salvează automat dimensiunea ecranului" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Filtrare Biliniară" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Modifică tastele" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Sticlă conectată" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Umbre dinamice" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Umbre dinamice: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Frunze detaliate" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Hartă mip" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Hartă mip + filtru aniso." + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Fără Filtru" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Fără hartă mip" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Evidenţiere Nod" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Conturează Nod" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Niciunul" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Frunze opace" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Apă opacă" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Particule" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Ecran:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Setări" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Umbră" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shadere (experimental)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Shaders (indisponibil)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Frunze simple" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Lumină fină" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Texturare:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Mapare ton" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "PragulAtingerii: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Filtrare Triliniară" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Frunze legănătoare" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Fluturarea lichidelor" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Plante legănătoare" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Eroare de conexiune (timeout?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Conexiunea a expirat." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Terminat!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inițializarea nodurilor" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Se inițializează nodurile..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Se încarcă texturi ..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Reconstruirea shaderelor..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Eroare de conexiune (timeout?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "Nu se poate găsi sau încărca jocul \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Jocul este nevalid." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Meniul Principal" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Nici un cuvânt selectat și nici o adresă scrisă. Nimic de făcut." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Numele jucătorului prea lung." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Vă rugăm să alegeți un nume!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Fișierul cu parolă nu a putut fi deschis: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Calea aprovizionată a lumii nu există: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Verifică deug.txt pentru detalii." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Adresa: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Modul: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Public: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- Jucător vs jucător: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Numele serverului: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "A apărut o eroare:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Redirecționare automată dezactivată" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Redirecționare automată activată" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Actualizarea camerei este dezactivată" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Actualizarea camerei este activată" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Schimbă Parola" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Modul cinematografic este dezactivat" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Modul cinematografic activat" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "Modare la client" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Scripturile din partea clientului sunt dezactivate" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Se conectează la server..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Continuă" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Controale:\n" +"- %s: deplasare înainte\n" +"- %s: deplasare înapoi\n" +"- %s: deplasare stânga\n" +"- %s: deplasare dreapta\n" +"- %s: salt/urcare\n" +"- %s: săpare/lovire\n" +"- %s: plasare/utilizare\n" +"- %s: furișare/coborâre\n" +"- %s: aruncare obiect\n" +"- %s: inventar\n" +"- Maus: rotire/privire\n" +"- Roata mausului: selectare obiect\n" +"- %s: chat\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Se creează clientul..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Se crează serverul..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Informațiile de depanare și graficul profilului sunt ascunse" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Informații de depanare afișate" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Informații de depanare, grafic de profil și ascuns" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Controale implicite:\n" +"Niciun meniu vizibil:\n" +"- apăsare unică: activare buton\n" +"- apăsare dublă: plasare / utilizare\n" +"- deget glisant: privește în jur\n" +"Meniu / Inventar vizibil:\n" +"- apăsare dublă (exterior):\n" +" -> close\n" +"- touch stack, slot pentru atingere:\n" +" -> mută stiva\n" +"- atingeți și trageți, atingeți al doilea deget\n" +" -> plasați un singur element în slot\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Interval de vizualizare nelimitat dezactivat" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Interval de vizualizare nelimitat activat" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Se creează clientul..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Ieși în Meniu" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Ieși din joc" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Modul rapid este dezactivat" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Modul rapid activat" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Modul rapid activat (notă: niciun privilegiu „rapid”)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Modul zburat dezactivat" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Modul zburat activat" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Modul de zbor este activat (notă: niciun privilegiu „zboară”)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Ceață dezactivată" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Ceață activată" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Informatii despre joc:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Joc întrerupt" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Găzduind un server" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Definițiile obiectelor..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB / s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Media..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB / s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Hartă mip dezactivată de joc sau mod" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "Jucător singur" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Modul Noclip este dezactivat" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Modul Noclip activat" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Modul Noclip activat (notă: nu este privilegiat „noclip”)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Definițiile Blocurilor..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Oprit" + +#: src/client/game.cpp +msgid "On" +msgstr "Pornit" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Mod mutare pitch dezactivat" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Mod de mutare pitch activat" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Graficul profilului este afișat" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Server de la distanță" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Se rezolvă adresa..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Se închide..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Jucător singur" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Volum Sunet" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Sunet dezactivat" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Sistem audio dezactivat" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Sistemul audio nu e suportat în această construcție" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Sunet activat" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Intervalul de vizualizare s-a modificat la %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Intervalul de vizualizare este maxim: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Intervalul de vizualizare este cel puțin: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Volum modificat la %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Cadru de sârmă afișat" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zoom dezactivat în prezent de joc sau mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "O.K" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Chat ascuns" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Chat afișat" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD ascuns" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD afișat" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profiler ascuns" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profiler afișat (pagina %d din %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplicații" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Înapoi" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Majuscule" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Jos" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Sfârșit" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Ștergere EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Execută" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Ajutor" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Acceptare IME" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Conversie IME" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME de Evacuare" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Schimbare mod IME" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME Nonconvertit" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Stânga" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Stânga" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Ctrl Stânga" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Meniu Stânga" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Shift Stânga" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Windows Stânga" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Meniu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Rotiță" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Num pad *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Num pad +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Num pad -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numpad." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Num pad /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Num pad 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Num pad 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Num pad 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Num pad 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Num pad 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Num pad 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Num pad 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Num pad 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Num pad 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Num pad 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Curățare OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Pagină în jos" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Pagină sus" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pauză" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Joacă" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Imprimare" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Înapoi" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Dreapta" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Drepata" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Ctrl Dreapta" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Meniu Drepata" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Shift Dreapta" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Windows Dreapta" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Selectează" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Somn" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "PrintScreen" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Spațiu" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Sus" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Butonul 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Butonul 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Mărire" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Hartă mip ascunsă" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Mini hartă în modul radar, Zoom %dx" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Mini hartă în modul de suprafață, Zoom %dx" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Mini hartă în modul de textură" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Nu s-a putut descărca $1" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Continuă" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "\"Special\" = coborâți" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Redirecționare înainte" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Salt automat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Înapoi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Schimba camera" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Comandă" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Consloă" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Interval dec" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Dec. volum" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Apasă de 2 ori \"sari\" pentru a zbura" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Aruncă" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Înainte" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Interval Inc" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Volumul inc" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventar" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Sari" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Tastă deja folosită" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Comandă locală" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Mut" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Următorul element" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Elementul anterior" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Selectare distanță" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Captură de ecran" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Furișează" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Comutați HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Comutați jurnalul de chat" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Intră pe rapid" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Intră pe zbor" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Comutați ceața" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Comutați minimap" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Intră pe noclip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Comutați pitchmove" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "apasă o tastă" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Schimbă" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Noua parolă" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Vechea parolă" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Parolele nu se potrivesc!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Ieșire" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Amuțit" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Volum sunet: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "ro" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Vă rugăm să alegeți un nume!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Fixează poziția joystick-ului virtual.\n" +"Dacă este dezactivat, joystick-ul virtual se va orienta către poziția la " +"prima atingere." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Utilizați joystick-ul virtual pentru a declanșa butonul \"aux\".\n" +"Dacă este activat, joystick-ul virtual va atinge, de asemenea, butonul " +"\"aux\" atunci când este în afara cercului principal." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X, Y, Z) compensarea fractalului din centrul lumii în unități de „scară”.\n" +"Poate fi folosit pentru a muta un punct dorit la (0, 0) pentru a crea o\n" +"punct de reproducere adecvat sau pentru a permite „mărirea” pe un dorit\n" +"punct prin creșterea „scară”.\n" +"Valoarea implicită este reglată pentru un punct de reproducere adecvat " +"pentru Mandelbrot\n" +"setează cu parametrii prestabili, este posibil să fie nevoie de modificări " +"în alte\n" +"situații.\n" +"Intervalul aproximativ -2 până la 2. Înmulțiți cu „scala” pentru compensarea " +"în noduri." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X, Y, Z) scara fractalului în noduri.\n" +"Mărimea efectivă a fractalului va fi de 2 până la 3 ori mai mare.\n" +"Aceste numere pot fi făcute foarte mari, fractal\n" +"nu trebuie să se încadreze în interiorul lumii.\n" +"Măriți acestea pentru a „mări” detaliile fractalei.\n" +"Valoarea implicită este pentru o formă ghemuită vertical, potrivită pentru\n" +"o insulă, setați toate cele 3 numere egale pentru forma brută." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Zgomot 2D care controlează forma/dimensiunea munților crestați." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Zgomot 2D care controlează forma/dimensiune de dealuri." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Zgomot 2D care controlează forma / dimensiunea munților pas." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "Zgomot 2D care controlează mărimea / apariția lanțurilor montate." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "Zgomot 2D care controlează dimensiunea / apariția de dealuri rulate." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" +"Zgomot 2D care controlează mărimea/apariția intervalelor de munți de pas." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Zgomot 2D, care localizează văile râurilor și canalelor." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Nori 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Mod 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Mod 3D putere paralaxă" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Zgomot 3D care definește caverne gigantice." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Zgomot 3D care definește structura și înălțimea muntelui.\n" +"De asemenea, definește structura terenului montan floatland." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Zgomot 3D care definește structura insulelor plutitoare (floatlands).\n" +"Dacă este modificată valoarea implicită, 'scala' (0.7) ar putea trebui\n" +"să fie ajustată, formarea floatland funcționează optim cu un zgomot\n" +"în intervalul aproximativ -2.0 până la 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Zgomot 3D care definește structura pereților canionului cu râu." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Zgomot 3D care definește terenul." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"Zgomot 3D pentru hangare de munte, stânci, etc. De obicei, mici variante." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "Zgomot 3D care determină numărul de temnițe pe bucată de hartă." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Suport 3D.\n" +"În prezent, suportate:\n" +"- Nici unul: nici o ieșire 3d.\n" +"- anaglyph: cyan / magenta culoare 3d.\n" +"- întrețesut: ciudat / par linie pe bază de suport ecran de polarizare.\n" +"- partea de sus: split screen sus / jos.\n" +"- sidebyside: split ecran unul lângă altul.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer pe bază de 3d.\n" +"Rețineți că modul între țesutnecesită umbrire pentru a fi activat." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Un seed de hartă aleasă pentru o hartă nouă, lăsa goală pentru a fii " +"întâmplătoare.\n" +"Va fi înlocuit atunci când se creează o lume nouă în meniul principal." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" +"Un mesaj care va fi afișat tuturor clienților în momentul blocării " +"serverului." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Un mesaj care va fi afișat tuturor clienților la închiderea serverului." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Interval ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Limita absolută a cozilor de blocuri procesate" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Accelerare în aer" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Accelerarea gravitației, în noduri pe secundă pe secundă." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Modificatori de bloc activi" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Interval de gestionare a blocurilor activ" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Interval de bloc activ" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Interval de trimitere obiect e activ" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Adresa la care să vă conectați.\n" +"Lăsați necompletat pentru a porni un server local.\n" +"Rețineți că, câmpul de adresă din meniul principal suprascrie această setare." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Adăuga particule atunci când săpați un nod." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Ajustați configurația dpi pe ecran (numai pentru x11/Android), de exemplu " +"pentru ecrane 4k." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Ajustează densitatea stratului de insule plutitoare.\n" +"Mărește valoarea pentru creșterea densității. Poate fi pozitivă sau " +"negativă.\n" +"Valoarea = 0.0: 50% din volum este insulă plutitoare.\n" +"Valoarea = 2.0 (poate fi mai mare în funcție de 'mgv7_np_floatland'; " +"testați\n" +"pentru siguranță) va crea un strat solid de insulă plutitoare." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Adăugare nume element" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avansat" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Modifică curba luminii prin aplicarea 'corecția gamma' la ea.\n" +"Valori mai mari de a face de mijloc și de jos niveluri de lumină " +"strălucitoare.\n" +"Valoarea '1.0' lasă lumina curba nealterată.\n" +"Aceasta are doar un efect semnificativ asupra lumină naturală și " +"artificială\n" +"lumina, are un efect foarte mic asupra naturală lumina de noapte." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Întotdeauna zboară și rapid" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Gamma ocluziei ambientală" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Cantitatea de mesaje pe care un jucător poate trimite la 10 secunde." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Amplifică văile." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Filtru Anizotropic" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Anunță serverul" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Anunțați pe această listă de servere." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Adăugare nume element" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Adăugați numele articolului la sugestia de instrumente." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Zgomotul merilor" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Inerție braț" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Inerția brațului, oferă o mișcare mai realistă a\n" +"brațul când camera se mișcă." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Solicitați să vă reconectați după cădere" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"La această distanță serverul va optimiza agresiv care blocuri sunt trimise " +"la\n" +"Clientii.\n" +"Valorile mici pot îmbunătăți performanța foarte mult, în detrimentul\n" +"glitches de redare (unele blocuri nu vor fi redate sub apă și în peșteri,\n" +"precum și, uneori, pe teren).\n" +"Setarea acesteia la o valoare mai mare decât max_block_send_distance " +"dezactivează această\n" +"Optimizare.\n" +"În scrise în mapblocks (16 noduri)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Tasta de avans automată" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Săriți automat obstacolele cu un singur nod." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Raportați automat la lista de server." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Salvează automat dimensiunea ecranului" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Mod scalare automată" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "Tasta de salt" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tastă înapoi" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Nivelul solului de bază" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Înălțimea terenului de bază." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Privilegii de bază" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Zgomot de plajă" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Pragul de zgomot de plajă" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Filtrare Biliniară" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Adresa de legare" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Parametrii de zgomot de temperatură și umiditate Biome API" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Biome zgomot" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Distanță de optimizare trimitere bloc" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Cale font aldin și cursiv" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Cale de font monospațiu aldin și cursiv" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Calea cu caractere îngroșate" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Calea cu caractere monospațiale îngroșate" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Construiți în interiorul jucătorului" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Incorporat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Schimba camera" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Camera \"aproape de tăiere plan\" distanta în noduri, între 0 și 0.25\n" +"Funcționează numai pe platforme LeS. Majoritatea utilizatorilor nu vor " +"trebui să schimbe acest lucru.\n" +"Creșterea poate reduce artefacte pe gpu-uri mai slabe.\n" +"0.1 = Implicit, 0,25 = Valoare bună pentru tabletele mai slabe." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Netezirea camerei" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Cameră fluidă în modul cinematic" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Tasta de comutare a actualizării camerei" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Zgomotul peșterilor" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Zgomotul 1 al peșterilor" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Zgomotul 2 al peșterilor" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Lățime peșteri" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Zgomot peșteri1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Zgomot peșteri2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Limita cavernelor" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Zgomotul cavernelor" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Subțiere caverne" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Pragul cavernelor" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Limita superioară a cavernelor" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Centrul razei de amplificare a curbei de lumină.\n" +"Aici 0.0 este nivelul minim de lumină, iar 1.0 este nivelul maxim." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "Pragul de lansare a mesajului de chat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Comenzi de chat" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Dimensiunea fontului din chat" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Tasta de chat" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Nivelul de raportare în chat" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Limita mesajelor din chat" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Formatul mesajului de chat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Pragul de lansare a mesajului de chat" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Lungimea maximă a unui mesaj din chat" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Cheia de comutare a chatului" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Chat afișat" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Dimensiunea unui chunk" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Modul cinematografic" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tasta modului cinematografic" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Texturi transparente curate" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Client" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Client și server" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Modare la client" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Restricții de modificare de partea clientului" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Restricția razei de căutare a nodurilor în clienți" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Modare la client" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Viteza escaladării" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Rază nori" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Nori" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Norii sunt un efect pe client." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Nori in meniu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Ceaţă colorată" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Colored shadows" +msgstr "Ceaţă colorată" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Listă separată de virgule cu etichete de ascuns din depozitul de conținut.\n" +"\"nonfree\" se poate folosi pentru ascunderea pachetelor care nu sunt " +"'software liber',\n" +"conform definiției Free Software Foundation.\n" +"Puteți specifica și clasificarea conținutului.\n" +"Aceste etichete nu depind de versiunile Minetest.\n" +"Puteți vedea lista completă la https://content.minetest.net/help/" +"content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Listă separată de virgule, cu modificări care au acces la API-uri HTTP,\n" +"care la permit încărcarea și descărcarea de date în/din internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Tasta de comandă" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Sticla conectată" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Se conectează la server media extern" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Unește sticla dacă nodul permite asta." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Consola alfa" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Culoare consolă" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Înalţime consolă" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "Maximul de descărcări simultane din ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "URL-ul ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "În continuare înainte" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Comenzi" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Creativ" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Daune" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Jocul implicit" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Parolă implicită" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Dimensiunea implicită a stivei" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Decorațiuni" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Tasta pentru săpat" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Particule pentru săpare" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Dezactivează anticheatul" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Apasă de 2 ori \"sari\" pentru a zbura" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Apăsând de 2 ori tasta Salt pentru a comuta modul de zburat." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Zgomotul temnițelor" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Activați suportul pentru canale mod." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Activați securitatea modului" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Activează minimap." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Cale font de rezervă" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Antialiasing:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Sunetul insulelor plutitoare" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Tasta înainte" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Jocuri" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Nivelul solului" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Zgomotul solului" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "Moduri HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "HUD afișat" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Zgomot de înălțime" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Abruptul dealului" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Pragul dealului" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Inc. tastă de volum" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Tasta pentru inventar" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Tasta de salt" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Abruptitatea lacului" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Pragul lacului" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Tasta de consolă de chat mare" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Tasta stângă" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Lumină fină" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Scriptul meniului principal" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Gen de mapă carpatin" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Mapgen Drapele specifice carpatin" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Mapgen Plat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Mapgen Plat steaguri specifice" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Fractal Mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Steaguri specifice Mapgen Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Genul de mapă V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Steaguri specifice Mapgen V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Gen de mapă V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Steaguri specifice Mapgen V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Gen de mapă V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Steaguri specifice Mapgen V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Mapgen Văi" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Mapgen Văi specifice steaguri" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Debug Mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Numele Mapgen" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Cartografierea mip" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Activați securitatea modului" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Tasta pentru mut" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Evidenţiere Nod" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Tasta de mutare a pitch" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Tasta de plasare" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Filtrare Biliniară" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Tasta de selectare a intervalului" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Calea regulată a fontului" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Calea raportului" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Tasta dreapta" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Zgomotul râului" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Ecran:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Formatul de captură de ecran" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Calitatea capturii de ecran" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Captură de ecran" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL-ul serverului" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Numele serverului" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Descrierea serverului" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL-ul serverului" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Adresa serverului" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Descrierea serverului" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Numele serverului" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Port server" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Port server" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL listă server" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "URL listă server" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Fișier listă pentru servere" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Calea shaderului" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "Calitatea capturii de ecran" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Lumină fină" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Cheie pentru furiș" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Viteza de furișare" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Rază nori" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Setări" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Calea texturii" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Prag ecran tactil" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Prag ecran tactil" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Filtrare Triliniară" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Volum" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Frunze legănătoare" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Fluturarea lichidelor" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Ridicând înălțimea valurilor lichidelor" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Viteza undelor lichide" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Lungirea undei lichide" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Ora de începere a lumii" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Modul creativ: " + +#~ msgid "- Damage: " +#~ msgstr "- Daune: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = ocluzia de paralax cu informații despre panta (mai rapid).\n" +#~ "1 = mapare în relief (mai lentă, mai exactă)." + +#~ msgid "Address / Port" +#~ msgstr "Adresă / Port" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Eşti sigur că vrei să resetezi lumea proprie ?" + +#~ msgid "Back" +#~ msgstr "Înapoi" + +#~ msgid "Basic" +#~ msgstr "De bază" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Biți per pixel (aka adâncime de culoare) în modul ecran complet." + +#~ msgid "Bump Mapping" +#~ msgstr "Cartografiere cu denivelări" + +#~ msgid "Bumpmapping" +#~ msgstr "Hartă pentru Denivelări" + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Modifică interfața meniului principal:\n" +#~ "- Complet: Lumi multiple singleplayer, selector de joc, selector de " +#~ "texturi etc.\n" +#~ "- Simplu: Doar o lume singleplayer, fără selectoare de joc sau " +#~ "texturi.\n" +#~ "Poate fi necesar pentru ecrane mai mici." + +#~ msgid "Config mods" +#~ msgstr "Configurează moduri" + +#~ msgid "Configure" +#~ msgstr "Configurează" + +#~ msgid "Connect" +#~ msgstr "Conectează" + +#~ msgid "Credits" +#~ msgstr "Credite" + +#~ msgid "Damage enabled" +#~ msgstr "Daune activate" + +#, fuzzy +#~ msgid "Darkness sharpness" +#~ msgstr "Mapgen" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Descărcați un joc, precum Minetest Game, de pe minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Descărcați unul de pe minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Se descarca si se instaleaza $ 1, vă rugăm să așteptați ..." + +#, fuzzy +#~ msgid "Enable VBO" +#~ msgstr "Activează MP" + +#, fuzzy +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Activează Daune" + +#~ msgid "Enter " +#~ msgstr "Introduceţi " + +#~ msgid "Filtering" +#~ msgstr "Filtrarea" + +#~ msgid "Game" +#~ msgstr "Joc" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Generați Hărți Normale" + +#~ msgid "In-Game" +#~ msgstr "În joc" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Instalare: fișier: \"$1\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Keybindings. (Dacă acest meniu apare, șterge lucrurile din minetest.conf)" + +#~ msgid "Main" +#~ msgstr "Principal" + +#~ msgid "Main menu style" +#~ msgstr "Stilul meniului principal" + +#~ msgid "Menus" +#~ msgstr "Meniuri" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Hartă mip în modul radar, Zoom x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Hartă mip în modul radar, Zoom x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Hartă mip în modul de suprafață, Zoom x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Hartă mip în modul de suprafață, Zoom x4" + +#~ msgid "Name / Password" +#~ msgstr "Nume / Parolă" + +#~ msgid "Name/Password" +#~ msgstr "Nume/Parolă" + +#~ msgid "No" +#~ msgstr "Nu" + +#~ msgid "Ok" +#~ msgstr "Ok" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Ocluzie Parallax" + +#~ msgid "PvP enabled" +#~ msgstr "PvP activat" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Resetează lume proprie" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "Selectează Fișierul Modului:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Server / Jucător singur" + +#~ msgid "Special" +#~ msgstr "Special" + +#~ msgid "Special key" +#~ msgstr "Cheie specială" + +#~ msgid "Start Singleplayer" +#~ msgstr "Începeți Jucător singur" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Pentru a permite shadere OpenGL trebuie să fie folosite." + +#, fuzzy +#~ msgid "Toggle Cinematic" +#~ msgstr "Intră pe rapid" + +#~ msgid "View" +#~ msgstr "Vizualizare" + +#~ msgid "Yes" +#~ msgstr "Da" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Sunteți pe cale să vă asociați pentru prima dată la acest server cu " +#~ "numele \"%s\".\n" +#~ "Dacă continuați, se va crea un cont nou utilizând acreditările pe acest " +#~ "server.\n" +#~ "Reintroduceți parola și faceți clic pe \"Înregistrare și asociere\" " +#~ "pentru a confirma crearea contului sau faceți clic pe \"Revocare\" pentru " +#~ "a abandona." + +#~ msgid "You died." +#~ msgstr "Ai murit." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/ru/minetest.po b/po/ru/minetest.po new file mode 100644 index 0000000..1129594 --- /dev/null +++ b/po/ru/minetest.po @@ -0,0 +1,8523 @@ +msgid "" +msgstr "" +"Project-Id-Version: Russian (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-06-27 03:16+0000\n" +"Last-Translator: Темак <artemkotlubai@yandex.ru>\n" +"Language-Team: Russian <https://hosted.weblate.org/projects/minetest/" +"minetest/ru/>\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.13.1-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Очистить очередь чата" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Пустая команда." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Выход в главное меню" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Неверная команда: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Выданная команда: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Список игроков в сети" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Игроки в сети: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Очередь в чате теперь пуста." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Эта команда отключена сервером." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Возродиться" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Вы умерли" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Доступные команды:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Доступные команды: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Команда недоступна: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Получить справку по командам" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Используйте '.help <cmd>' для получения дополнительной информации, или '." +"help all' для перечисления всего списка." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <команда>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "ОК" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<недоступно>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Произошла ошибка в скрипте Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Произошла ошибка:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Главное меню" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Переподключиться" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Сервер запросил переподключение:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Выберите моды" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Несоответствие версии протокола. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Сервер требует протокол версии $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Сервер поддерживает версии протокола с $1 по $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Мы поддерживаем только протокол версии $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Поддерживаются только протоколы версий с $1 по $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Отмена" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Зависимости:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Отключить все" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Отключить набор модов" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Включить все" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Включить набор модов" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Не удалось включить мод «$1», так как он содержит недопустимые символы. " +"Разрешены только следующие символы: [a-z0-9_]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Больше Модов" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Мод:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Нет (необязательных) зависимостей" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Описание игры недоступно." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Нет жёстких зависимостей" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No modpack description provided." +msgstr "Описание набора модов недоступно." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Нет необязательных зависимостей" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Необязательные зависимости:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Сохранить" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Мир:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "включено" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" уже существует. Перезаписать?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Зависимости $1 и $2 будут установлены." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 из $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 скачивается,\n" +"$2 в очереди" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 скачивается…" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "Не удалось найти требуемые зависимости $1." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "Будет установлен $1, а зависимости $2 будут пропущены." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Все дополнения" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Уже установлено" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Назад в главное меню" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Основная игра:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB недоступен, когда Minetest скомпилирован без cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Загрузка..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Не удалось загрузить $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Игры" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Установить" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Установить $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Установить недостающие зависимости" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Установка мода: неподдерживаемый тип файла или повреждённый архив" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Моды" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "No packages could be retrieved" +msgstr "Дополнения не могут быть получены" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Ничего не найдено" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Нет обновлений" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Не найдено" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Перезаписать" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Please check that the base game is correct." +msgstr "Пожалуйста, убедитесь, что основная игра верна." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "В очереди" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Texture packs" +msgstr "Наборы текстур" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Удалить" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Обновить" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Обновить все [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Посмотреть дополнительную информацию в веб-браузере" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Мир с названием «$1» уже существует" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Дополнительная местность" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Высота над уровнем моря" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Высота нивального пояса" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Смешивание биомов" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Биомы" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Пещеры" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Пещеры" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Создать" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Украшения" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Внимание: «The Development Test» предназначен для разработчиков." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Подземелья" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Плоская местность" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Парящие острова на небе" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Парящие острова (экспериментальный)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Создать нефрактальную местность: океаны и подземелья" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Холмы" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Влажность рек" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Увеличивает влажность вокруг рек" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Установить $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Озёра" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Пониженную влажность и высокую температуру вызывают отмель или высыхание рек" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Картогенератор" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Флаги картогенератора" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mapgen-specific flags" +msgstr "Особые флаги картогенератора" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Горы" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Грязевой поток" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Сеть туннелей и пещер" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Игра не выбрана" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Уменьшает жару с высотой" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Уменьшает влажность с высотой" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Реки" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Реки на уровне моря" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Зерно" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Плавный переход между биомами" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Строения, появляющиеся на поверхности (не влияет на деревья и тропическую " +"траву, сгенерированные v6)" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Строения, появляющиеся на поверхности, обычно деревья и растения" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Умеренный пояс, Пустыня" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Умеренный пояс, Пустыня, Джунгли" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Умеренный пояс, Пустыня, Джунгли, Тундра, Тайга" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Разрушение поверхности местности" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Деревья и Джунгли-трава" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Изменить глубину рек" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Очень большие пещеры глубоко под землей" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Название мира" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "У вас не установлено ни одной игры." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Уверены, что хотите удалить «$1»?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Удалить" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: невозможно удалить «$1»" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: недопустимый путь «$1»" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Удалить мир «$1»?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Подтверждение пароля" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Название картогенератора" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Имя" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Пароль" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Пароли не совпадают!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Регистрация и подключение" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Принять" + +#: builtin/mainmenu/dlg_rename_modpack.lua +#, fuzzy +msgid "Rename Modpack:" +msgstr "Переименовать набор модов:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +#, fuzzy +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Этот набор модов имеет имя, явно указанное в modpack.conf, которое изменится " +"от переименования здесь." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Нет описания настройки)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D-шум" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Назад к странице настроек" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Обзор" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Дополнения" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Дополнения" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Отключено" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Править" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Включено" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Лакунарность" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Октавы" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Смещение" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Упорство" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Пожалуйста, введите целое число." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Пожалуйста, введите допустимое число." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Сбросить значения" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Масштаб" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Поиск" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Select directory" +msgstr "Выбрать папку" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Выбрать файл" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Показывать технические названия" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Значение должно быть больше или равно $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Значение не должно быть больше, чем $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Разброс по X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Разброс по Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Разброс по Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "абсолютная величина" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "Базовый" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "облегчённый" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (включено)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 модов" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Невозможно установить $1 в $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Установка мода: не удаётся определить название мода для «$1»" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Установка мода: не удаётся найти подходящую папку для набора модов «$1»" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" +"Установка мода: не удаётся найти подходящий каталог для мода или пакета модов" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a $1 as a texture pack" +msgstr "Не удаётся установить $1 как набор текстур" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Не удаётся установить игру как $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Не удаётся установить мод как $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Не удаётся установить пакет модов как $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Загрузка..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Публичный список серверов отключён" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Попробуйте обновить список публичных серверов и проверьте связь с Интернетом." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Об игре" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Активные участники" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Активный визуализатор:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Основные разработчики" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Открыть папку данных пользователя" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Открывает папку, содержащую пользовательские миры, игры, моды,\n" +"и наборы текстур в файловом менеджере / проводнике." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Прошлые участники" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Прошлые основные разработчики" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Показывать отладочную информацию" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Поиск дополнений в сети" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Дополнения" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Disable Texture Pack" +msgstr "Отключить набор текстур" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Информация:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Установленные дополнения:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Нет зависимостей." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Описание дополнения недоступно" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Переименовать" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Удалить дополнение" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Use Texture Pack" +msgstr "Использовать набор текстур" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Публичный сервер" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Привязать Адрес" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Режим творчества" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Включить урон" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Играть (хост)" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Запустить сервер" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Установить игры из ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Новый" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Мир не создан или не выбран!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Играть" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Порт" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Выберите моды" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Выберите мир:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Порт сервера" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Начать игру" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Адрес" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Очистить" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Режим творчества" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Урон / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Избранное" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Несовместимые серверы" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Подключиться к игре" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Ping" +msgstr "Задержка" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Публичные серверы" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Обновить" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Удалённый порт" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Описание сервера" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Объёмные облака" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Все настройки" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Сглаживание:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Запоминать размер окна" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Билинейная фильтрация" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Смена управления" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Стёкла без швов" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Динамические тени" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Динамические тени: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Красивая листва" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Высокое" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Низкое" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Среднее" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Mipmap" +msgstr "Размытие текстур" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Mipmap + Aniso. Filter" +msgstr "Размытие текстур + анизотр. фильтр" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Без фильтрации" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "No Mipmap" +msgstr "Без размытия текстур" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Подсветка нод" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Обводка нод" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Ничего" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Непрозрачная листва" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Непрозрачная вода" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Частицы" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Экран:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Настройки" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Шейдеры" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Шейдеры (экспериментально)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Шейдеры (недоступно)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Упрощённая листва" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Мягкое освещение" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Текстурирование:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Тональное отображение" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Чувствительность: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Трилинейная фильтрация" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Сверхвысокое" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Очень низкое" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Покачивание листвы" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Волнистые жидкости" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Покачивание растений" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Ошибка соединения (время вышло?)" + +#: src/client/client.cpp src/client/game.cpp +#, fuzzy +msgid "Connection timed out." +msgstr "Время ожидания соединения истекло." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Готово!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Инициализация нод" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Инициализация нод..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Загрузка текстур..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Сборка шейдеров..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Ошибка соединения (время вышло?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Не удалось найти или загрузить игру: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Неправильная конфигурация игры." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Главное меню" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Не выбран мир и не введён адрес. Нечего выполнять." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Имя игрока слишком длинное." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Пожалуйста, выберите имя!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Не удалось открыть указанный файл с паролем: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "По этому пути мира нет: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Подробная информация в debug.txt." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Адрес: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Режим: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Порт: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Публичность: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +#, fuzzy +msgid "- PvP: " +msgstr "- Режим сражения: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Имя сервера: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Произошла ошибка сериализации:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Доступ запрещен. Причина: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Автобег отключён" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Автобег включён" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Границы блока скрыты" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Границы показаны для всех блоков" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Границы показаны для текущего блока" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Границы показаны для блоков рядом" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Обновление камеры выключено" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Обновление камеры включено" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "Нельзя показать границы блока (нужна привилегия 'basic_debug')" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Изменить пароль" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Режим кино отключён" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Режим кино включён" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Клиент отключился" + +#: src/client/game.cpp +#, fuzzy +msgid "Client side scripting is disabled" +msgstr "Пользовательские моды отключены" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Подключение к серверу..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Сбой соединения по неизвестной причине" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Продолжить" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Управление:\n" +"- %s: вперёд\n" +"- %s: назад\n" +"- %s: влево\n" +"- %s: вправо\n" +"- %s: прыжок/подъём\n" +"- %s: копать/удар\n" +"- %s: разместить/использовать\n" +"- %s: красться/спуск\n" +"- %s: бросить предмет\n" +"- %s: инвентарь\n" +"- Мышь: поворот/обзор\n" +"- Колесо мыши: выбор предмета\n" +"- %s: чат\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Не удалось разрешить адрес: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Создание клиента..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Создание сервера..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Отладочная информация и график профилировщика скрыты" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Отладочная информация отображена" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Отладочная информация, график профилировщика и каркас скрыты" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Управление по умолчанию:\n" +"Не в меню:\n" +"- одно нажатие: кнопка активаций\n" +"- двойное нажатие: положить/использовать\n" +"- скольжение пальцем: осмотреться\n" +"В меню/инвентаре:\n" +"- двойное нажатие (вне меню)\n" +"--> закрыть меню\n" +"- Нажать на стопку, затем на ячейку:\n" +"--> Двигать стопку\n" +"- Потащить одним пальцем стопку в нужную ячейку, нажать вторым пальцем на " +"экран:\n" +"--> Положить один предмет в ячейку\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Ограничение видимости включено" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Ограничение видимости отключено" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Создание клиента..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Выход в меню" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Выход в систему" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Режим быстрого перемещения отключён" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Режим быстрого перемещения включён" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Режим быстрого перемещения включён (но: нет привилегии 'fast')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Режим полёта отключён" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Режим полёта включён" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Режим полёта включён (но нет привилегии «fly»)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Туман отключён" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Туман включён" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Информация об игре:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Игра приостановлена" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Локальный сервер" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Описания предметов..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "КиБ/с" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Медиафайлы..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "МиБ/с" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Миникарта сейчас отключена игрой или модом" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Мультиплеер" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Режим прохождения сквозь стены отключён" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Режим прохождения сквозь стены включён" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Режим прохождения сквозь стены включён (но нет привилегии «noclip»)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Описания нод..." + +#: src/client/game.cpp +msgid "Off" +msgstr "отключено" + +#: src/client/game.cpp +msgid "On" +msgstr "включено" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Режим движения вниз/вверх по направлению взгляда отключён" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Режим движения вниз/вверх по направлению взгляда включён" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "График профилировщика отображён" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Удалённый сервер" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Получение адреса..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Завершение..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Одиночная игра" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Громкость звука" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Звук отключён" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Звук отключён" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Звук не поддерживается в этой сборке" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Звук включён" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Вероятно, на сервере используется другая версия %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Не удаётся подключиться к %s, так как IPv6 отключён" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Не удаётся прослушать %s, так как IPv6 отключён" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Установлена видимость %dм" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Видимость установлена на максимум: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Видимость установлена на минимум: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Громкость установлена на %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Отображение каркаса включено" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Приближение в настоящее время отключено игрой или модом" + +#: src/client/game.cpp +msgid "ok" +msgstr "OK" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Чат скрыт" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Отображение чата включено" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "Игровой интерфейс скрыт" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "Игровой интерфейс отображается" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Профилировщик скрыт" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Профилировщик (страница %d из %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Приложения" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Ctrl" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Вниз" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Стереть EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Выполнить" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Помощь" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Принять IME" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Конвертировать IME" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "Экранировать IME" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Изменить режим IME" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "Неконвертируемый IME" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Лево" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Левая кнопка" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Левый Ctrl" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Левый Alt" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Левый Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Левый Win" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Контекстное меню" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Средняя кнопка" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Доп. клав. *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Доп. клав. +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Доп. клав. -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Цифр. кл. ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Доп. клав. /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Доп. клав. 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Доп. клав. 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Доп. клав. 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Доп. клав. 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Доп. клав. 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Доп. клав. 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Доп. клав. 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Доп. клав. 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Доп. клав. 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Доп. клав. 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Очистить OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page Down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page Up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Пауза" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Играть" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "PrtSc" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Вернуться" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Вправо" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Правая кнопка" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Правый Ctrl" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Правый Alt" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Правый Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Правый Win" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Выбор" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Спать" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Cнимок" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Пробел" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Вверх" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Доп. кнопка 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Доп. кнопка 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Приближение" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Миникарта скрыта" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Миникарта в режиме радара, увеличение x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Миникарта в поверхностном режиме, увеличение x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Минимальный размер текстуры" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Не удалось открыть веб-страницу" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Открытие страницы" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Продолжить" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = спуск" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Автобег" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Автопрыжок" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Назад" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Границы блока" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Change camera" +msgstr "Сменить угол" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Чат" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Команда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Консоль" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Видимость -" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Громкость -" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Двойной прыжок = полёт" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Бросить" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Вперёд" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Увеличить видимость" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Увеличить громкость" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Инвентарь" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Прыжок" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Клавиша уже используется" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Локальная команда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Заглушить" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "След. предмет" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Пред. предмет" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Дальность прорисовки" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Снимок экрана" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Красться" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Вкл/выкл игровой интерфейс" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Вкл/выкл историю чата" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Ускорение" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Полёт" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Туман" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Миникарта" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Сквозь стены" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "По наклону взгляда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "нажмите клавишу" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Изменить" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Новый пароль" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Старый пароль" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Пароли не совпадают!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Выход" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Заглушить" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Громкость звука: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "ru" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Пожалуйста, выберите имя!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Фиксирует положение виртуального джойстика.\n" +"Если отключено, виртуальный джойстик будет появляться в месте первого " +"касания." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Использовать виртуальный джойстик для активации кнопки \"Aux1\".\n" +"Если включено, виртуальный джойстик также будет нажимать кнопку \"Aux1\", " +"когда будет находиться за пределами основного колеса." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"Смещение (X, Y, Z) фрактала от центра мира в единицах «масштаба».\n" +"Используется для перемещения зоны возрождения ближе к (0, 0),\n" +"для создания подходящей точки возрождения или для разрешения\n" +"«приближения» в нужную точку посредством «масштаба».\n" +"Значение по умолчанию подходит для множеств Мандельброта\n" +"со стандартными параметрами, для других ситуаций его нужно\n" +"отредактировать.\n" +"Диапазон примерно от -2 до 2. Умножьте на «масштаб», чтобы получить смещение " +"в нодах." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(Х,Y,Z) масштаб фрактала в нодах.\n" +"Фактический размер фрактала будет в 2-3 раза больше.\n" +"Эти числа могут быть очень большими, фракталу нет нужды\n" +"заполнять мир. Увеличьте их, чтобы увеличить «масштаб»\n" +"детали фрактала. По умолчанию значения подходят для\n" +"вертикально сжатой фигуры, что подходит острову, для\n" +"необработанной формы сделайте все 3 значения равными." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2D-шум, управляющий формой и размером горных хребтов." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2D-шум, контролирующий форму и размер холмов." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2D-шум, контролирующий форму и размер ступенчатых гор." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" +"2D-шум, контролирующий размер и распространение складчатых горных хребтов." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D-шум, контролирующий размер и распространение холмистой местности." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" +"2D-шум, контролирующий размер и распространение ступенчатых горных хребтов." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2D-шум, определяющие расположение пойм рек и их русел." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Объёмные облака" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D-режим" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Сила параллакса в 3D-режиме" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D-шум, определяющий огромные пещеры." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D-шум, определяющий строение гор и их высоту.\n" +"Также определяет строение гор на парящих островах." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"3D шум, определяющий строение парящих островов.\n" +"Если изменен по-умолчанию, 'уровень' шума (0.7 по-умолчанию) возможно " +"необходимо установить,\n" +"так как функции сужения парящих островов лучше всего работают, \n" +"когда значение шума находиться в диапазоне от -2.0 до 2.0." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "3D noise defining structure of river canyon walls." +msgstr "3D-шум, определяющий строение стен речного каньона." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Трёхмерный шум, определяющий рельеф местности." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"3D шум для горных выступов, скал и т. д. В основном небольшие вариации." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D-шум, определяющий количество подземелий в куске карты." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Поддержка 3D.\n" +"Сейчас поддерживаются:\n" +"- none: Нет.\n" +"- anaglyph: Анаглифные очки.\n" +"- interlaced: Поляризационные 3d-очки.\n" +"- topbottom: Разделение экрана по горизонтали.\n" +"- sidebyside: Разделение экрана по диагонали.\n" +"- crossview: 3D на основе автостереограммы.\n" +"- pageflip: Четырёхкратная буферизация.\n" +"Примечание: в режиме interlaced шейдеры должны быть включены." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Выбранное зерно для новой карты, оставьте пустым для случайного.\n" +"Будет переопределено при создании нового мира в главном меню." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Сообщение, которое будет отображаться для всех при падении сервера." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Сообщение, которое будет показано всем при отключении сервера." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ABM interval" +msgstr "ABM промежуток" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Лимит времени ABM" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Абсолютный предел появления блоков в очереди" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Ускорение в воздухе" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Ускорение свободного падения в нодах в секунду." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Модификаторы активных блоков" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Active block management interval" +msgstr "Промежуток управления активным блоком" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Дальность взаимодействия с блоками" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Дальность отправляемого активного объекта" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Адрес, к которому нужно присоединиться.\n" +"Оставьте это поле пустым, чтобы запустить локальный сервер.\n" +"Обратите внимание, что поле адреса в главном меню перезапишет эту настройку." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Добавляет частицы при раскопке ноды." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Настройка dpi (плотности точек на дюйм) для вашего экрана (не для X11, " +"только для Android). Например для мониторов с разрешением в 4k." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Настройка обнаруженной плотности дисплея, используется для масштабирования " +"элементов интерфейса." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Регулирует плотность слоя парящих островов.\n" +"Увеличьте значение, чтобы увеличить плотность. Может быть положительным или " +"отрицательным.\n" +"Значение = 0,0: 50% o объема парящих островов.\n" +"Значение = 2,0 (может быть выше в зависимости от 'mgv7_np_floatland', всегда " +"проверяйте)\n" +"создает сплошной слой парящих островов." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Добавлять названия предметов" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Дополнительно" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Изменяет кривую света, применяя к ней гамма-коррекцию.\n" +"Более высокие значения делают средние и низкие уровни света более яркими.\n" +"Значение 1.0 оставляет кривую света без изменений.\n" +"Это значительно влияет только на дневной и искусственный\n" +"свет, но имеет очень слабый эффект на естественный ночной свет." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Всегда включены полёт и ускорение" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Гамма глобального затенения" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" +"Задаёт предельное количество сообщений, которые клиент может отправить в чат " +"в течении 10 секунд." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Усиливает долины." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Анизотропная фильтрация" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "О сервере" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Оповещение в этот сервер-лист." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Добавлять названия предметов" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Добавлять названия предметов во всплывающих подсказках." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Шум яблонь" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Инерция руки" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Делает более правдоподобным движение руки\n" +"персонажа при движении камеры." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Запрашивать переподключение после аварийного завершения" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"На этом расстоянии сервер будет агрессивно оптимизировать то, какие\n" +"блоки будут отправлены клиентам.\n" +"Малые значения могут увеличить производительность за счёт заметных\n" +"проблем визуализации (некоторые фрагменты не будут отрисовываться\n" +"под водой, в пещерах, а иногда и на суше).\n" +"Установка этого значения больше, чем max_block_send_distance\n" +"отключит эту оптимизацию.\n" +"Указывается в блоках карты (16 нод)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Автоматическая кнопка вперед" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Автоматический подъем на одиночные ноды." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Автоматическая жалоба на сервер-лист." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Запоминать размер окна" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Режим автоматического масштабирования" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Клавиша Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Клавиша Aux1 для подъема/спуска" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Клавиша назад" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Базовый уровень земли" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Высота основной местности." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Basic privileges" +msgstr "Основные привилегии" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Шум пляжей" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Порог шума пляжей" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Билинейная фильтрация" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Адрес привязки" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Параметры температуры и влажности для API биомов" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Шум биомов" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Оптимизированное расстояние отправки блока" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Путь к жирному и курсивному шрифту" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Путь к жирному и курсивному моноширинному шрифту" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Путь к жирному шрифту" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Путь к жирному моноширинному шрифту" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Разрешить ставить блоки на месте игрока" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Встроенный" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Сменить угол" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Расстояние между камерой и плоскостью отсечения в нодах от 0 до 0.5.\n" +"Работает только на платформах с GLES. Большинству пользователей не требуется " +"менять его.\n" +"Его увеличение может уменьшить количество артефактов на слабых графических " +"процессорах.\n" +"0.1 — по умолчанию; 0.25 — хорошее значение для слабых планшетов." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Сглаживание камеры" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Сглаживание камеры в кинематографическом режиме" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Кнопка обновления камеры" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Шум пещеры" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Шум пещеры #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Шум пещеры #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Ширина пещеры" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Шум пещеры #1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Шум пещеры #2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Предел пещеры" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Шум пещеры" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Конусность пещер" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Порог пещеры" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Верхнее ограничение пещер" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Центр диапазона увеличения кривой света,\n" +"где 0.0 — минимальный уровень света, а 1.0 — максимальный." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Порог cообщения команды чата" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Команды чата" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Размер шрифта чата" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Кнопка чата" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Уровень журнала чата" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Максимальное количество сообщений в чате" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Формат сообщений в чате" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat message kick threshold" +msgstr "Предельное количество сообщений в чате (для отключения)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat message max length" +msgstr "Предельная длина сообщения в чате" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Кнопка переключения чата" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Сетевые ссылки в чате" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Размер куска" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Кинематографический режим" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Кнопка переключения в кинематографический режим" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Очистить прозрачные текстуры" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "Нажимающиеся ссылки (СКМ или Ctrl+ЛКМ) включены в консоли." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Клиент" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Клиент и сервер" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Моддинг клиента" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Ограничения моддинга на стороне клиента" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Ограничение диапазона клиентского поиска нод" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Моддинг клиента" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Скорость подъёма" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Радиус облаков" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Облака" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Клиентские эффекты для облаков." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Облака в меню" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Цветной туман" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Цветные тени" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Разделённый запятыми список меток, которые можно скрывать в репозитории.\n" +"\"nonfree\" можно использовать, чтобы скрыть пакеты, которые не являются " +"'свободным программным обеспечением'\n" +" по определению Free Software Foundation.\n" +"Также вы можете назначить рейтинг.\n" +"Метки не зависят от версии Minetest,\n" +"узнать полный список можно на https://content.minetest.net/help/" +"content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Разделённый запятыми список модов, у которых есть доступ к HTTP API,\n" +"что позволяет им загружать и отдавать данные по интернету." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Разделённый запятыми список доверенных модов, которым разрешён\n" +"доступ к небезопасным функциям, даже когда включена защита модов (через " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Команда" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Уровень сжатия для использования при сохранении картографических блоков на " +"диске.\n" +"-1 - уровень сжатия по умолчанию\n" +"0 - без сжатия, самый быстрый\n" +"9 - лучшее сжатие, самое медленное\n" +"(уровни 1-3 используют \"быстрый\" метод Zlib, 4-9 используют обычный метод)" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Уровень сжатия для использования при отправке блоков карты клиенту.\n" +"-1 - уровень сжатия по умолчанию\n" +"0 - без компрессора, самый быстрый\n" +"9 - лучшее сжатие, самое медленное\n" +"(уровни 1-3 используют \"быстрый\" метод Zlib, 4-9 используют обычный метод)" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Стёкла без швов" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Подключение к внешнему медиасерверу" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Соединяет стекло, если поддерживается нодой." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Консоль" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Цвет в консоли" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Высота консоли" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Сетевое хранилище" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Чёрный список флагов ContentDB" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ContentDB Max Concurrent Downloads" +msgstr "Предельное количество одновременных загрузок ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "Адрес ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Непрерывная ходьба" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Непрерывное движение вперёд, переключаемое клавишей «автобег».\n" +"Нажмите автобег ещё раз либо движение назад, чтобы выключить." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Управление" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Задает скорость смены времени суток.\n" +"Примеры:\n" +"72 = 20 минут, 360 = 4 минуты, 1 = 24 часа, 0 = статичное время суток." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Регулирует крутизну и глубину впадин в озёрах." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Регулирует крутизну и высоту холмов." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Контролирует ширину туннелей, меньшее значение создаёт более широкие " +"туннели.\n" +"Значение >= 10.0 полностью отключает генерацию туннелей и позволяют " +"избежать\n" +"интенсивного расчёта шумов." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Сообщение при падении" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Творческий" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Прозрачность перекрестия" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Прозрачность прицела (от 0 (прозрачно) до 255 (непрозрачно)).\n" +"Также контролирует цвет перекрестия объекта." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Цвет перекрестия" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Цвет прицела (R, G, B).\n" +"Также контролирует цвет перекрестия объекта" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Урон" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Клавиша переключения показа отладочной информации" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Порог размера файла журнала отладки" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Отладочный уровень" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Клавиша уменьшения громкости" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Шаг выделенного сервера" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Ускорение по умолчанию" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Стандартная игра" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Игра по умолчанию при создании нового мира.\n" +"Будет переопределена при создании мира из главного меню." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Стандартный пароль" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Начальные привилегии" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Формат отчёта по умолчанию" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default stack size" +msgstr "Размер стопки по умолчанию" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Определите качество фильтрации теней.\n" +"Это имитирует эффект мягких теней, применяя PCF или пуассоновский диск\n" +"но также использует больше ресурсов." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Определяет области, где у деревьев есть яблоки." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Определяет области с песчаными пляжами." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" +"Определяет распределение поверхности на возвышенностях и влияет на крутизну " +"скал." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Определяет распределение поверхности на возвышенностях." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Определяет полный размер пещер, меньшие значения создают большие пещеры." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines large-scale river channel structure." +msgstr "Определяет крупномасштабное строение каналов рек." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Определяет расположение и поверхность дополнительных холмов и озёр." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Определяет базовый уровень земли." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Определяет глубину русла реки." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Определяет предельное расстояние перемещения игрока в блоках (0 = " +"неограниченное)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Определяет ширину русла реки." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Определяет ширину поймы реки." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Определяет области и плотность деревьев." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Задержка между обновлением мешей на клиенте в миллисекундах. Увеличение " +"этого значения\n" +"замедлит скорость обновления мешей, тем самым уменьшая колебания кадровой " +"частоты на медленных клиентах." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Задержка отправки блоков после строительства" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Задержка показа подсказок(в миллисекундах)." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Обработка устаревшего Lua API" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Depth below which you'll find giant caverns." +msgstr "Глубина, ниже которой встречаются крупные пещеры." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Глубина, ниже которой встречаются крупные пещеры." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Описание сервера, которое будет показано при входе игрока и в списке " +"серверов." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Порог шума пустынь" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Пустыни появляются, когда np_biome превышает это значение.\n" +"Игнорируется, когда включён флаг 'snowbiomes'." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Рассинхронизация анимации блоков" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Украшения" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Кнопка копать" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Частицы при рытье" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Отключить анти-чит" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Запретить пустой пароль" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Коэффициент масштабирования плотности отображения" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Доменное имя сервера, отображаемое в списке серверов." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Полёт по двойному прыжку" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Двойное нажатие на прыжок включает режим полёта." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Кнопка выброса блока" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Записывать отладочные данные картогенератора." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Максимальная Y подземелья" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Минимальная Y подземелья" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Шум подземелья" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Включить поддержку IPv6 (для клиента и сервера).\n" +"Требуется для того, чтобы вообще соединяться по IPv6." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Включить поддержку Lua-моддинга на клиенте.\n" +"Эта поддержка является экспериментальной и API может измениться." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Включить фильтрацию диска Пуассона.\n" +"По истине использует диск Пуассона для создания \"мягких теней\". Иначе " +"используется фильтрация PCF." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Включить цветные тени.\n" +"На истинно полупрозрачных узлах отбрасываются цветные тени. Это ресурсоёмко." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Включить окно консоли" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Включить творческий режим для всех игроков" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Включить джойстики" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Включить поддержку каналов модов." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Включить защиту модов" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Включить получение игроками урона и их смерть." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Включить случайный ввод пользователя (только для тестов)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Включить мягкое освещение с простым глобальным затенением.\n" +"Отключите для более высокой скорости или другого внешнего вида." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Включите, чтобы запретить подключение старых клиентов.\n" +"Старые клиенты совместимы в том смысле, что они не будут сбоить при " +"подключении\n" +"к новым серверам, однако они могут не поддерживать всех новых функций, " +"которые вы ожидаете." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Включить использование удалённого медиасервера (если предоставляется " +"сервером).\n" +"Удалённые сервера позволяют намного быстрее скачивать медиафайлы (напр. " +"текстуры)\n" +"во время подключения к серверу." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Включить объекты буфера вершин.\n" +"Это должно значительно улучшить графическую производительность." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Включить покачивание камеры и установить его значение.\n" +"Например: 0 отключает покачивание, 1.0 для обычного, 2.0 для двойного." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Включить/отключить запуск IPv6-сервера.\n" +"Игнорируется, если задан «bind_address».\n" +"Для включения необходим «enable_ipv6»." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Включает кинематографическое отображение тонов «Uncharted 2».\n" +"Имитирует кривую тона фотопленки и приближает\n" +"изображение к большему динамическому диапазону. Средний контраст слегка\n" +"усиливается, блики и тени постепенно сжимаются." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Включить анимацию предметов в инвентаре." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Включает кэширование повёрнутых мешей." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Включить мини-карту." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Включает звуковую систему.\n" +"Если её отключить, то это полностью уберёт все звуки, а внутриигровые\n" +"настройки звука не будут работать.\n" +"Изменение этого параметра требует перезапуска." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Обеспечивает компромисс, который снижает использование ЦП или увеличивает " +"производительность рендеринга\n" +"ценой мелких визуальных дефектов, не влияющих на геймплей." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Профиль долины" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiling data print interval" +msgstr "Промежуток печати данных профилирования движка" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Методы сущностей" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Степень сужения парящих островов. Изменяет характер сужения.\n" +"Значение = 1.0 задает равномерное, линейное сужение.\n" +"Значения > 1.0 задают гладкое сужение, подходит для отдельных\n" +" парящих островов по-умолчанию.\n" +"Значения < 1.0 (например, 0.25) задают более точный уровень поверхности\n" +"с более плоскими низинами, подходит для массивного уровня парящих островов." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "Максимум кадровой частоты при паузе или когда окно вне фокуса" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "Полноэкранное сглаживание (FSAA)" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Коэффициент шума" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Коэффициент покачивания при падении" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Путь к резервному шрифту" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Клавиша ускорения" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Ускорение быстрого перемещения" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Скорость быстрого перемещения" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Быстрое перемещение" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Быстрое перемещение (с помощью клавиши \"Aux1\").\n" +"Это требует привилегию 'fast' на сервере." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Угол обзора" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Угол обзора в градусах." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Файл в папке client/serverlist/, содержащий ваши избранные серверы\n" +"из вкладки Мультиплеер." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Глубина наполнителя" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Шум глубины наполнителя" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Кинематографическое тональное отображение" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Фильтрованные текстуры могут смешивать значения RGB с полностью прозрачными " +"соседними,\n" +"которые оптимизаторы PNG обычно отбрасывают, что часто приводит к темным " +"или\n" +"светлым краям прозрачных текстур. Примените фильтр для очистки\n" +"во время загрузки текстуры. Это автоматически включается, если включен " +"mipmapping." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Сглаживание:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "Первый из четырёх 2D-шумов, определяющий диапазон высоты холмов и гор." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Первый из двух 3D-шумов, которые вместе определяют туннели." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Фиксированное зерно мира" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Фиксация виртуального джойстика" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Плотность парящих островов" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Максимальная Y парящих островов" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Минимальная Y парящих островов" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Шум парящих островов" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Экспонента конуса на парящих островах" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Расстояние сужения парящих островов" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Уровень воды на парящих островах" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Клавиша полёта" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Полёт" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Туман" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Граница тумана" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Клавиша переключения тумана" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Размер шрифта" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Жирный шрифт по умолчанию" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Курсивный шрифт по умолчанию" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Тень шрифта" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Прозрачность тени шрифта" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Размер шрифта" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Размер шрифта, кратный" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Размер стандартного шрифта в пунктах (pt)" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Размер моноширинного шрифта в пунктах (pt)" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Размер шрифта последнего чата и подсказки чата в точке (pt).\n" +"Значение 0 будет использовать размер шрифта по умолчанию." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"Для шрифтов пиксельного стиля, которые плохо масштабируются, это " +"гарантирует, что размеры шрифта, используемые\n" +"с этим шрифтом всегда будут кратны этому значению в пикселях. Например,\n" +"пиксельный шрифт высотой 16 пикселей должен иметь значение 16, поэтому он " +"всегда будет иметь только\n" +"16, 32, 48 и т.д., поэтому мод, запрашивающий размер 25, получит 32." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Формат сообщений игрока в чате. В качестве заполнителей доступны следующие " +"строки:\n" +"@name, @message, @timestamp (необязательно)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Format of screenshots." +msgstr "Формат снимков экрана." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Стандартный цвет фона формы" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Стандартная непрозрачность фона формы" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Цвет фона формы в полноэкранном режиме" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Непрозрачность фона формы в полноэкранном режиме" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Стандартный цвет фона формы (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Стандартная непрозрачность фона формы (от 0 до 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Цвет фона формы в полноэкранном режиме (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "Непрозрачность фона формы в полноэкранном режиме (от 0 до 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Клавиша вперёд" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Четвёртый из четырёх 2D-шумов, определяющий диапазон высоты холмов и гор." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Тип фрактала" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Часть видимого расстояния, на которой начинает появляться туман" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Насколько далеко блоки генерируются для клиентов. Указывается в блоках карты " +"(16 нод)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"С какого расстояния блоки отправляются клиентам, в блоках карты (16 нод)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Расстояние в блоках карты, на котором клиенты распознают объекты (16 нод).\n" +"\n" +"Если указать значение более active_block_range, то сервер будет запоминать\n" +"движущиеся объекты на этом расстоянии в направлении взгляда игрока.\n" +"(Это поможет избежать внезапного исчезновения мобов из поля зрения)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Полный экран" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Полноэкранный режим." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Масштабирование интерфейса" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Фильтр масштабирования интерфейса" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Фильтр txr2img для масштабирования интерфейса" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Игры" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Глобальные обратные вызовы" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Глобальные атрибуты генерации карт.\n" +"В картогенераторе v6 флаг «decorations» не влияет на деревья и траву\n" +"в джунглях, в остальных генераторах этот флаг контролирует все декорации." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Градиент кривой света на максимальном уровне освещённости.\n" +"Контролирует контрастность самых высоких уровней освещенности." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Градиент кривой света на минимальном уровне освещённости.\n" +"Контролирует контрастность самых низких уровней освещенности." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Графика" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Графика" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Графика" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gravity" +msgstr "Притяжение" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Уровень земли" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Шум земли" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "Моды HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Масштабирование интерфейса" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Клавиша переключения игрового интерфейса" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Обработка устаревших вызовов Lua API:\n" +"- none: не записывать устаревшие вызовы\n" +"- log: имитировать и журналировать устаревшие вызовы (по умолчанию для " +"отладки).\n" +"- error: прерывание при использовании устаревших вызовов (рекомендовано " +"для разработчиков модов)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Профилировать сам профилировщик:\n" +"* Замерять пустую функцию.\n" +"Это оценит накладные расходы, добавляемые замерами (+1 вызов функции).\n" +"* Замерять сэмплер, используемый для обновления статистики." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Шум смешивания теплоты" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Шум теплоты" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Компонент высоты начального размера окна. Игнорируется в полноэкранном " +"режиме." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Шум высоты" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Шум выбора высоты" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Крутизна холмов" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Порог холмов" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Шум холмистости 1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Шум холмистости 2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Шум холмистости 3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Шум холмистости 4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Домашняя страница сервера, отображаемая в списке серверов." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Горизонтальное ускорение в воздухе при прыжке или падении\n" +"в нодах в секунду." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Горизонтальное и вертикальное ускорение в режиме \n" +"быстрого перемещения в нодах в секунду." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Горизонтальное и вертикальное ускорение на земле или при лазании\n" +"в нодах за секунду." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Следующий предмет на горячей панели" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Предыдущий предмет на горячей панели" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Быстрая кнопка 1" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Быстрая кнопка 10" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Быстрая кнопка 11" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Быстрая кнопка 12" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Быстрая кнопка 13" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Быстрая кнопка 14" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Быстрая кнопка 15" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Быстрая кнопка 16" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Быстрая кнопка 17" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Быстрая кнопка 18" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Быстрая кнопка 19" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Быстрая кнопка 2" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Быстрая кнопка 20" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Быстрая кнопка 21" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Быстрая кнопка 22" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Быстрая кнопка 23" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Быстрая кнопка 24" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Быстрая кнопка 25" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Быстрая кнопка 26" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Быстрая кнопка 27" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Быстрая кнопка 28" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Быстрая кнопка 29" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Быстрая кнопка 3" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Быстрая кнопка 30" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Быстрая кнопка 31" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Быстрая кнопка 32" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Быстрая кнопка 4" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Быстрая кнопка 5" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Быстрая кнопка 6" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Быстрая кнопка 7" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Быстрая кнопка 8" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Быстрая кнопка 9" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Насколько глубоко делать реки." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Как быстро будут покачиваться волны жидкостей. Выше = быстрее\n" +"Если отрицательно, жидкие волны будут двигаться назад.\n" +"Требует, чтобы волнистые жидкости были включены." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Время ожидания сервера до выгрузки неиспользуемых блоков.\n" +"Высокие значения более плавные, но используют больше оперативной памяти." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Уменьшите значение, чтобы увеличить сопротивление жидкости движению." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Насколько широко делать реки." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Шум смешивания влажности" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Шум влажности" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Вариация влажности в биомах." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6-сервер" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Если кадровая частота превысит это значение, ограничить её простоем,\n" +"чтобы не тратить мощность процессора впустую." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Если отключено, кнопка \"Aux1\" используется для быстрого полета, если режим " +"полёта и быстрый режим\n" +"включены." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Если включено, то сервер будет выполнять отсечение фрагментов, основываясь\n" +"на положении глаз игрока. Это может уменьшить количество пересылаемых\n" +"блоков на 50-80%. Клиент не будет получать большую часть невидимого,\n" +"поэтому режим прохождения сквозь стены станет менее полезным." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Если включено одновременно с режимом полёта, игрок может пролетать сквозь " +"твёрдые ноды.\n" +"Требует наличие привилегии «noclip» на сервере." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Если включено, клавиша \"Aux1\" вместо клавиши \"Sneak\" используется для " +"подъема вниз и\n" +"спуска." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Включить подтверждение регистрации при подключении к серверу.\n" +"Если отключено, то новый аккаунт будет зарегистрирован автоматически." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Если включено, действия записываются для отката.\n" +"Этот параметр считывается только при запуске сервера." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Если включено, отключается защита от читерства в сетевой игре." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Если включено, то сервер не выключится из-за повреждённых данных о мире.\n" +"Включайте только в том случае, если знаете, что делаете." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Если включено, определяет направления движения вверх/вниз в зависимости от " +"взгляда игрока во время полёта или плавания." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Если включено, то новые игроки не смогут подключаться с пустым паролем." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Если включено, то вы можете размещать новые блоки на месте игрока.\n" +"Это может быть полезно при строительстве в узких местах." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Если ограничение CSM для диапазона нод включено, вызовы\n" +"get_node ограничиваются на это расстояние от игрока до ноды." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Если выполнение команды чата занимает больше указанного времени в\n" +"секундах, добавьте информацию о времени в сообщение команды чата" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Если размер файла debug.txt при открытии превысит количество мегабайтов,\n" +"указанных в этой настройке, файл будет перемещён в debug.txt.1,\n" +"а старый debug.txt.1 будет удалён.\n" +"debug.txt перемещается только тогда, когда это значение положительное." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "Если установлено, то игроки будут возрождаться в указанном месте." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Игнорировать ошибки мира" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "Прозрачность фона внутриигровой консоли (непрозрачность от 0 до 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Цвет фона внутриигровой консоли (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "Высота внутриигрового чата, между 0.1 (10%) и 1.0 (100%)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Клавиша увеличения громкости" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Начальная вертикальная скорость при прыжках в нодах в секунду." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Замерять встроенные функции.\n" +"Обычно это нужно тем, кто пишет код для движка" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "Выполнять команды в чате при регистрации." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Замерять глобальные обратные вызовы\n" +"(всё, что вы передаёте в функции вида minetest.register_*())" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "Замерять действие функции модификаторов активных блоков." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "Замерять действие функции модификатора загружающихся блоков." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Замерять методы сущностей." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Промежуток сохранения важных изменений в мире, установленный в секундах." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Промежуток отправки клиентам сведений о времени дня." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Анимация предметов в инвентаре" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Кнопка открытия инвентаря" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Инвертировать мышь" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Инвертировать мышь по вертикали." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Путь к курсивному шрифту" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Путь к курсивному моноширинному шрифту" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Время жизни выброшенной вещи" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Итерации" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Количество итераций рекурсивной функции.\n" +"Большее количество итераций улучшает детализацию фрактала,\n" +"но увеличивает вычислительную нагрузку.\n" +"При 20 итерациях нагрузка сравнима с картогенератором V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "Идентификатор джойстика" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Интервал повторного клика кнопкой джойстика" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "Мертвая зона джойстика" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Чувствительность джойстика" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Тип джойстика" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Только для множества Жюлиа:\n" +"компонент W гиперкомплексной константы,\n" +"определяющий форму фрактала Жюлиа.\n" +"Не влияет на 3D-фракталы.\n" +"Диапазон примерно от -2 до 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Только для множества Жюлиа:\n" +"компонент Х гиперкомплексной константы,\n" +"определяющий форму фрактала Жюлиа.\n" +"Диапазон примерно от -2 до 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Только для множества Жюлиа:\n" +"компонент Y гиперкомплексной константы,\n" +"определяющий форму фрактала Жюлиа.\n" +"Диапазон примерно от -2 до 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Только для множества Жюлиа:\n" +"компонент Z гиперкомплексной константы,\n" +"определяющий форму фрактала Жюлиа.\n" +"Диапазон примерно от -2 до 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Жюлиа w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Жюлиа x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Жюлиа y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Жюлиа z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Кнопка прыжка" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Скорость прыжков" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша уменьшения зоны видимости.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша уменьшения громкости.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша копания.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша, чтобы выбросить выбранный предмет.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша увеличения зоны видимости.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша увеличения громкости.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша прыжка.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша, включающая режим быстрого перемещения.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша движения назад.\n" +"При активации также отключает автобег.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша движения вперёд.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша движения влево.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша движения вправо.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша отключения звука в игре.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша открытия окна чата для ввода команды.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша открытия окна чата для ввода локальных команд.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша открытия окна чата.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша открытия инвентаря.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша размещения.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 11 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 12 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 13 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 14 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 15 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 16 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 17 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 18 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 19 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 20 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 21 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 22 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 23 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 24 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 25 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 26 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 27 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 28 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 29 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 30 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 31 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 32 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 8 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 5 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 1 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 4 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора следующего предмета на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 9 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предыдущего предмета на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 2 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 7 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 6 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 10 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выбора предмета 3 на горячей панели.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша, чтобы красться.\n" +"Также используется для спуска и погружения под воду, если параметр " +"aux1_descends отключён.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения вида от первого или от третьего лица.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша для создания снимка экрана .\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения автобега.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения кинематографического режима.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения отображения миникарты.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения режима быстрого перемещения.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения режима полёта.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения режима прохождения сквозь стены.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения режима движение вниз/вверх по направлению взгляда.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша выключения обновлений камеры. Используется только для разработки\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения отображения чата.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения отображения отладочной информации.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения отображения тумана.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения отображения игрового интерфейса.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша переключения отображения большого чата.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша для переключения отображения профилировщика. Используется для " +"разработки.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша отключения ограничения зоны видимости.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавиша режима увеличения.\n" +"См. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" +"Если клиент отправит в чат столько сообщений в течении 10 секунд, то будет " +"отключён от сервера." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Крутизна озёр" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Порог озёр" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Язык" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Глубина больших пещер" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Large cave maximum number" +msgstr "Предельное количество больших пещер" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Large cave minimum number" +msgstr "Наименьшее количество больших пещер" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Пропорция затопленных больших пещер" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Кнопка вызова консоли" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Стиль листвы" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Стили листвы:\n" +"- Fancy: включена прозрачность, все стороны видны\n" +"- Simple: прозрачность включена, видны только внешние стороны, если " +"используются special_tiles\n" +"- Opaque: прозрачность отключена" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Кнопка выхода" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Длина серверного тика и промежуток, на котором объекты обычно\n" +"обновляются по сети." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Длина волн жидкостей.\n" +"Требуется включение волнистых жидкостей." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Время между циклами выполнения модификаторов активных блоков (ABM)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Время между циклами выполнения таймеров нод" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Время между циклами управления активными блоками (ABM)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Уровень логов для записи в debug.txt:\n" +"- <nothing> (нет логов)\n" +"- none (сообщения без уровня)\n" +"- error (ошибки)\n" +"- warning (предупреждения)\n" +"- action (действия)\n" +"- info (информация)\n" +"- verbose (подробности)" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Усиление кривой света" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Центр усиления кривой света" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Распространение усиления роста кривой света" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Гамма кривой света" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Высокий градиент кривой света" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Низкий градиент кривой света" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Мягкое освещение" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Предел генерации карты, в нодах, во всех шести направлениях, начиная от (0, " +"0, 0).\n" +"Генерируются только куски карты, которые умещаются в заданном пределе " +"полностью.\n" +"Значение сохраняется отдельно для каждого мира." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Ограничивает количество параллельных HTTP-запросов. Влияет на:\n" +"- Загрузку медиаданных, если сервер использует параметр remote_media.\n" +"- Загрузку списка серверов и их анонсирование.\n" +"- Загрузки, выполняемые в главном меню (например, в менеджере модов).\n" +"Действует только при компиляции с включённой поддержкой cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Текучесть жидкости" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Сглаживание текучести жидкостей" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Liquid loop max" +msgstr "Предельное количество зацикленных жидкостей" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Время очистки очереди жидкостей" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Стекание жидкости" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Liquid update interval in seconds." +msgstr "Промежуток обновления жидкостей в секундах." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Liquid update tick" +msgstr "Промежуток обновления жидкостей" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Загружать профилировщик игры" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Загружать профилировщик игры для собирания профилирующей информации.\n" +"Предоставляет команду /profiler для доступа к скомпилированному профилю.\n" +"Полезно для разработчиков модов и операторов сервера." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Модификаторы загружающихся блоков" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Нижний лимит Y для подземелий." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Нижний лимит Y для парящих островов." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Скрипт главного меню" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Включить зависимость цвета тумана и облаков от времени суток (рассвет/закат)." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Сделать все жидкости непрозрачными" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Уровень сжатия карты для дискового хранилища" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Уровень сжатия карты для передачи по сети" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map directory" +msgstr "Папка сохранения карт" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Атрибуты генерации карт для Mapgen Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Атрибуты генерации для картогенератора плоскости.\n" +"Иногда озера и холмы могут добавляться в плоский мир." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Атрибуты генерации для картогенератора плоскости.\n" +"'terrain' включает генерацию нефрактального рельефа:\n" +"океаны, острова и подземелья." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Атрибуты генерации карты для генератора долин.\n" +"«altitude_chill»: уменьшает теплоту с ростом высоты.\n" +"«humid_rivers»: увеличивает влажность по обе стороны рек.\n" +"«vary_river_depth»: если включено, то низкая влажность и высокая\n" +"температура влияют на уровень воды в реках.\n" +"«altitude_dry»: уменьшает влажность с ростом высоты." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Атрибуты генерации карт для Mapgen v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Атрибуты генерации для капртогенератора v6.\n" +"Параметр «snowbiomes» (снежные биомы) включает новую систему с 5 \n" +"биомами. Если «snowbiomes» включён, то автоматически\n" +"активируются джунгли, а флаг «jungles» игнорируется." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Атрибуты генерации карт, специфичные для Mapgen v7.\n" +"'ridges': Реки.\n" +"'floatlands': Парящие острова суши в атмосфере.\n" +"'caverns': Крупные пещеры глубоко под землей." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Предел генерации карты" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map save interval" +msgstr "Промежуток сохранения карты" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "Время обновления карты" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Предел блока" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Задержка в генерации мешей блоков" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Размер кэша блоков карты в генераторе мешей в МБ" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapblock unload timeout" +msgstr "Время ожидания выгрузки блоков" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Картогенератор Карпаты" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian specific flags" +msgstr "Особые флаги генератора Карпаты" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Картогенератор плоскости" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat specific flags" +msgstr "Особые флаги картогенератора плоскости" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Картогенератор Фрактал" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "Особые флаги картогенератора Фрактал" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Картогенератор V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Специальные флаги картогенератора V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Картогенератор V6" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6 specific flags" +msgstr "Особые флаги картогенератора V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Картогенератор V7" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7 specific flags" +msgstr "Особые флаги картогенератора V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Картогенератор долин" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Valleys specific flags" +msgstr "Особые флаги картогенератора долин" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Отладка картогенератора" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Название картогенератора" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Max block generate distance" +msgstr "Предельное расстояние генерации блоков" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Max block send distance" +msgstr "Предельное расстояние отправки блоков" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Max liquids processed per step." +msgstr "Предельное количество обработанных жидкостей за шаг." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Количество дополнительно загружаемых блоков clearobjects" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Max. packets per iteration" +msgstr "Предельное количество пакетов за итерацию" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum FPS" +msgstr "Предел кадровой частоты (FPS)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"Предел кадровой частоты, когда окно не сфокусировано, или когда игра " +"приостановлена." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum distance to render shadows." +msgstr "Предельное расстояние для отрисовки теней." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum forceloaded blocks" +msgstr "Предельное количество принудительно загруженных блоков" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum hotbar width" +msgstr "Предельная ширина горячей панели" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" +"Предельное ограничение случайного количества больших пещер на кусок карты." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" +"Предельное ограничение случайного количества маленьких пещер на кусок карты." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Предельное сопротивление жидкости. Контролирует замедление\n" +"при погружении в жидкость на высокой скорости." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Предельное количество одновременно отправляемых каждому клиенту блоков.\n" +"Общее максимальное количество вычисляется динамически:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" +"Предельное количество блоков, которые могут быть помещены в очередь для " +"загрузки." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Предельное количество блоков в очередь, которые должны быть образованы.\n" +"Это ограничение применяется для каждого игрока." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Предельное количество блоков в очередь, которые должны быть загружены из " +"файла.\n" +"Это ограничение применяется для каждого игрока." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Предельное количество одновременных загрузок. Загрузки, превышающие это " +"ограничение, будут поставлены в очередь.\n" +"Это должно быть меньше curl_parallel_limit." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum number of forceloaded mapblocks." +msgstr "Предельное количество принудительно загруженных блоков." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Предельное количество блоков в памяти клиента.\n" +"Установите в -1 для бесконечного количества." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Предельное количество пакетов, отправляемых за раз. Если у вас медленное " +"подключение,\n" +"попробуйте уменьшить его, но не устанавливайте ниже значения клиента,\n" +"умноженного на два." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Предельное количество одновременно подключённых игроков." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum number of recent chat messages to show" +msgstr "Предельное количество последних отображаемых сообщений чата" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum number of statically stored objects in a block." +msgstr "Предельное количество статически хранимых объектов в блоке." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum objects per block" +msgstr "Предельное количество объектов на блок" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Предельная доля окна, используемая для горячей панели.\n" +"Полезно, если что-то будет отображаться справа или слева от него." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum simultaneous block sends per client" +msgstr "Предельное число одновременно отправляемых блоков на клиент" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum size of the out chat queue" +msgstr "Предельный размер очереди исходящих сообщений" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Предельный размер очереди исходящих сообщений.\n" +"0 для отключения очереди и -1 для неограниченного размера." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Предельное время загрузки файла (например, загрузки мода), указанное в " +"миллисекундах." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Предельное время, которое может занять интерактивный запрос (например, " +"получение списка серверов), указывается в миллисекундах." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum users" +msgstr "Предельное количество пользователей" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Кэш мешей" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Сообщение дня" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Сообщение, отображаемое подключившимся игрокам." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Method used to highlight selected object." +msgstr "Способ подсветки выделенного объекта." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimal level of logging to be written to chat." +msgstr "Наименьший уровень записи в чат." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Миникарта" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Клавиша переключения миникарты" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Высота сканирования миникарты" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Наименьший предел случайного количества больших пещер на кусок карты." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Наименьшее количество маленьких пещер на кусок карты." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimum texture size" +msgstr "Наименьший размер текстуры" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mipmapping" +msgstr "Размытие текстур (MIP-текстурирование)" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Профилировщик" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Безопасность" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Каналы модификаций" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Изменяет размер элементов игрового интерфейса." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Путь к моноширинному шрифту" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Размер моноширинного шрифта" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "Размер моноширинного шрифта, кратный" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Шум высоты гор" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Шум гор" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Шум вариации гор" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Нулевой уровень гор" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Чувствительность мыши" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Множитель чувствительности мыши." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Шум грязи" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Множитель для покачивания при падении.\n" +"Например: 0 отключает покачивание; 1.0 для обычного; 2.0 для двойного." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Клавиша отключения звука" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Заглушить звук" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Название генератора карты, который будет использоваться при создании нового " +"мира.\n" +"Это значение переопределяется при создании мира через главное меню.\n" +"Текущие крайне нестабильные картогенераторы:\n" +"- Дополнительные парящие острова из v7 (выключено по умолчанию)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Имя игрока.\n" +"При запуске сервера клиенты с этим именем будут администраторами.\n" +"Будет переопределено при запуске из главного меню." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "Имя сервера, отображаемое при входе и в списке серверов." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Ближняя плоскость" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Сетевой порт для прослушивания (UDP).\n" +"Этот параметр будет переопределён, если запустить сервер из главного меню." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Сеть" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Новым пользователям нужно вводить этот пароль." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Проходить сквозь стены" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Клавиша прохождения сквозь стены" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Подсветка нод" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Подсветка нод" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "NodeTimer interval" +msgstr "Промежуток таймера нод" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Шумы" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Количество emerge-потоков" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Количество возникающих потоков для использования.\n" +"Значение 0:\n" +"- Автоматический выбор. Количество потоков будет\n" +"- 'число процессоров - 2', минимально — 1.\n" +"Любое другое значение:\n" +"- Указывает количество потоков, минимально — 1.\n" +"ВНИМАНИЕ: Увеличение числа потоков улучшает быстродействие движка\n" +"картогенератора, но может снижать производительность игры, мешая другим\n" +"процессам, особенно в одиночной игре и при запуске кода Lua в " +"'on_generated'.\n" +"Для большинства пользователей наилучшим значением может быть '1'." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Количество дополнительных блоков, которые могут сразу быть загружены /" +"clearobjects.\n" +"Это компромисс между накладными расходами на транзакции SQLite и " +"потреблением\n" +"памяти (4096=100 MБ, как правило)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Непрозрачные жидкости" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "Прозрачность тени сзади стандартного шрифта, между 0 и 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Открыть меню паузы при потере окном фокуса. Не срабатывает, если какая-либо\n" +"форма уже открыта." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Необязательное переопределение цвета ссылки в чате." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Путь к резервному шрифту.\n" +"Если параметр «freetype» включён: должен быть шрифтом TrueType.\n" +"Если параметр «freetype» отключён: должен быть векторным XML-шрифтом.\n" +"Этот шрифт будет использоваться для некоторых языков или если стандартный " +"шрифт недоступен." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Путь для сохранения снимков экрана. Может быть абсолютным или относительным " +"путем.\n" +"Папка будет создана, если она еще не существует." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Путь к папке с шейдерами. Если не задан, то будет использоваться путь по " +"умолчанию." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" +"Путь к папке с текстурами. Все текстуры в первую очередь берутся отсюда." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Путь к шрифту по умолчанию.\n" +"Если параметр «freetype» включен: должен быть шрифт TrueType.\n" +"Если параметр «freetype» отключен: это должен быть растровый или векторный " +"шрифт XML.\n" +"Резервный шрифт будет использоваться, если шрифт не может быть загружен." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Путь к моноширинному шрифту.\n" +"Если параметр «freetype» включен: должен быть шрифт TrueType.\n" +"Если параметр «freetype» отключен: это должен быть растровый или векторный " +"шрифт XML.\n" +"Этот шрифт используется, например, для экран консоли и экрана профилей." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Пауза при потере фокуса" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "Ограничение поочередной загрузки блоков с диска на игрока" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Ограничение для каждого игрока в очереди блоков для генерации" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Физика" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Кнопка движение вниз/вверх по направлению взгляда" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Режим движения вниз/вверх по направлению взгляда" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Клавиша положить" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place repetition interval" +msgstr "Промежуток повторного размещения" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Игрок может летать без влияния притяжения.\n" +"Это требует привилегии 'fly' на сервере." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Расстояние передачи игрока" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Режим «Игрок против игрока» (PvP)" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Пуассоновская фильтрация" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Порт, к которому подключиться (UDP).\n" +"Имейте ввиду, что поле ввода порта в главном меню переопределяет эту " +"настройку." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Предотвращает повторное копание и размещение блоков при удержании кнопки " +"мыши.\n" +"Включите это, если слишком часто случайно копаете или строите лишнее." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Не допускать модам выполнение небезопасных вещей, например выполнение " +"консольных команд." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Печатать информацию о профилировании через заданные промежутки (в " +"секундах).\n" +"0 = отключить. Полезно для разработчиков." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Привилегии, доступные игрокам с basic_privs" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Профилировщик" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Клавиша переключения профилировщика" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "адрес приёмника Prometheus" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Адрес приёмника Prometheus.\n" +"Если мой тест скомпилирован с включенной опцией ENABLE_PROMETHEUS,\n" +"включить приемник метрик для Prometheus по этому адресу.\n" +"Метрики можно получить на http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Доля больших пещер, которые содержат жидкость." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Радиус зоны облаков представляет из себя 64 квадратных ноды облаков\n" +"Значения больше чем 26 вызывают резкое обрезание углов зоны облаков." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Поднимает местность, чтобы образовывать поймы вдоль рек." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Случайный ввод" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Кнопка настройки дальности видимости" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Недавние сообщения чата" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Путь к обычному шрифту" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Удалённый медиасервер" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Удалённый порт" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Удаляет коды цветов из входящих сообщений чата\n" +"Используйте, чтобы запретить игрокам применять цвета в своих сообщениях" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Заменять главное меню на пользовательское." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Путь для сохранения отчётов" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Ограничивает доступ к определённым клиентским функциям на серверах.\n" +"Суммируйте отметки байтов ниже для ограничения функций, либо введите 0,\n" +"чтобы ничего не ограничивать:\n" +"LOAD_CLIENT_MODS: 1 (отключить загрузку пользовательских модификаций)\n" +"CHAT_MESSAGES: 2 (отключить вызов send_chat_message со стороны клиента)\n" +"READ_ITEMDEFS: 4 (отключить вызов get_item_def со стороны клиента)\n" +"READ_NODEDEFS: 8 (отключить вызов get_node_def со стороны клиента)\n" +"LOOKUP_NODES_LIMIT: 16 (ограничивает вызов get_node со стороны клиента\n" +"до csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (отключить вызов get_player_names со стороны клиента)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Шум распространения горных хребтов" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Шум хребтов" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Шум подводных хребтов" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Размер шума подводных хребтов" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Правая клавиша меню" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Глубина русла реки" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Ширина русла реки" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Глубина рек" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Шум рек" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Размер рек" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Ширина поймы реки" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Запись отката" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Размер шума холмов" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Шум распространения холмов" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Круглая миникарта" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Аккуратное копание и размещение" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Песчаные пляжи появляются, когда np_beach превышает это значение." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Сохранение карты, полученной от клиента на диск." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Сохранять размер окна при изменении автоматически." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Сохранение карты, полученной с сервера" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Масштабировать интерфейс, используя заданное пользователем значение.\n" +"Использовать метод ближайшего соседа и антиалиасинг, чтобы масштабировать " +"интерфейс.\n" +"Это сгладит некоторые острые углы и смешает\n" +"пиксели при уменьшении масштаба за счёт размывания\n" +"пикселей на гранях при масштабировании на нецелые размеры." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Экран:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Высота экрана" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Ширина экрана" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshot folder" +msgstr "Папка для снимков экрана" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshot format" +msgstr "Формат снимка экрана" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshot quality" +msgstr "Качество снимка экрана" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Качество снимка экрана. Используется только для изображений в формате JPEG.\n" +"1 означает худшее качество; 100 означает лучшее качество.\n" +"Используйте 0 для настроек по умолчанию." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Снимок экрана" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Шум морского дна" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Второй из четырёх 2D-шумов, которые вместе определяют диапазон высот холмов " +"и гор." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Второй из двух 3D-шумов, которые вместе определяют туннели." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "См. http://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Цвет рамки выделения (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Цвет выделения" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Толщина рамки выделения" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Выбирает один из 18 типов фракталов.\n" +"1 = 4D \"Круглое\" множество Мандельброта.\n" +"2 = 4D \"Круглое\" множество Жюлиа.\n" +"3 = 4D \"Квадратное\" множество Мандельброта.\n" +"4 = 4D \"Квадратное\" множество Жюлиа.\n" +"5 = 4D \"Mandy Cousin\" множество Мандельброта.\n" +"6 = 4D \"Mandy Cousin\" множество Жюлиа.\n" +"7 = 4D \"Variation\" множество Мандельброта.\n" +"8 = 4D \"Variation\" множество Жюлиа.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" множество Мандельброта.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" множество Жюлиа.\n" +"11 = 3D \"Christmas Tree\" множество Мандельброта.\n" +"12 = 3D \"Christmas Tree\" множество Жюлиа.\n" +"13 = 3D \"Mandelbulb\" множество Мандельброта.\n" +"14 = 3D \"Mandelbulb\" множество Жюлиа.\n" +"15 = 3D \"Cosine Mandelbulb\" множество Мандельброта.\n" +"16 = 3D \"Cosine Mandelbulb\" множество Жюлиа.\n" +"17 = 4D \"Mandelbulb\" множество Мандельброта.\n" +"18 = 4D \"Mandelbulb\" множество Жюлиа." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL сервера" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Имя сервера" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Описание сервера" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL сервера" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Адрес сервера" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Описание сервера" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Имя сервера" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Порт сервера" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Отсечение невидимой геометрии на стороне сервера" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Порт сервера" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "Адрес списка серверов" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "Адрес списка серверов" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Файл списка серверов" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Установка языка. Оставьте пустым для использования языка системы.\n" +"Требует перезапуска после изменения." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"Задаёт предельное количество символов в сообщении, отправляемом клиентами в " +"чат." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Установите силу тени.\n" +"Меньшее значение означает более светлые тени, большее значение означает " +"более тёмные тени." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Установить размер радиуса мягкой тени.\n" +"Меньшие значения означают более резкие тени, большие значения более мягкие.\n" +"Минимальное значение 1,0 и максимальное 10,0" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Установка наклона орбиты Солнца/Луны в градусах.\n" +"Значение 0 означает отсутствие наклона / вертикальную орбиту.\n" +"Наименьшее значение 0.0 и максимальное значение 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Установка в true включает покачивание листвы.\n" +"Требует, чтобы шейдеры были включены." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Установка в true включает покачивание листвы.\n" +"Требует, чтобы шейдеры были включены." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Установка в true включает волнистые жидкости (например, вода).\n" +"Требует, чтобы шейдеры были включены." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Установка в true включает покачивание растений.\n" +"Требует, чтобы шейдеры были включены." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Устанавливает качество текстуры тени в 32 бита.\n" +"При значении false будет использоваться 16-битная текстура.\n" +"Это может вызвать гораздо больше артефактов в тени." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Путь к шейдерам" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Шейдеры позволяют использовать дополнительные визуальные эффекты и могут " +"увеличить\n" +"производительность на некоторых видеокартах.\n" +"Работают только с видео-бэкендом OpenGL." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Качество теневого фильтра" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map max distance in nodes to render shadows" +msgstr "Предельное расстояние карты теней в нодах для рендеринга теней" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "Текстура карты теней в 32 битах" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Размер текстуры карты теней" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Смещение тени стандартного шрифта (в пикселях). Если указан 0, то тень не " +"будет показана." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "Сила тени" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Форма миникарты. Включено = круг, выключено = квадрат." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Показывать отладочную информацию" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Показывать область выделения объектов" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Показывать область выделения объектов\n" +"Требует перезапуска после изменения." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Отображать задний план у табличек с именами" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Сообщение о выключении" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Размер кусков карты, выдаваемых картогенератором, указывается в блоках карты " +"(16 нод).\n" +"ВНИМАНИЕ!: От изменения этого значения нет никакой пользы, а значение больше " +"5\n" +"может быть вредным.\n" +"С уменьшением этого значения увеличится плотность расположения пещер и " +"подземелий.\n" +"Изменять его нужно только в особых ситуациях, а в обычных рекомендуется\n" +"оставить как есть." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Размер кэша блоков карты в генераторе мешей. Увеличение этого значения\n" +"увеличит процент попаданий в кэш, предотвращая копирование информации\n" +"из основного потока игры, тем самым уменьшая колебания кадровой частоты." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Наклон орбиты небесного тела" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Разрез w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Склон и заполнение работают совместно для изменения высот." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Small cave maximum number" +msgstr "Предельное количество маленьких пещер" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Small cave minimum number" +msgstr "Наименьшее количество маленьких пещер" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "Мелкие вариации влажности для смешивания биомов на границах." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "Мелкие вариации температуры для смешивания биомов на границах." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Мягкое освещение" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Сглаживать движения камеры при её повороте. Также называется сглаживанием " +"движений мыши.\n" +"Это может быть полезно при записи видео." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"Плавное вращение камеры в кинематографическом режиме. 0 для отключения." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Плавное вращение камеры. 0 для отключения." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Красться" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Скорость скрытной ходьбы" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Скорость ходьбы украдкой в нодах в секунду." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Радиус мягкой тени" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Звук" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Указывает URL с которого клиент будет качать медиа-файлы вместо " +"использования UDP.\n" +"$filename должен быть доступен по адресу $remote_demia$filename через cURL\n" +"(remote_media должен заканчиваться слешем).\n" +"Файлы, которых не будет, будут скачены обычным путём." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Устанавливает размер стопки блоков, предметов и инструментов по умолчанию.\n" +"Обратите внимание, что моды или игры могут явно установить стопку для " +"определенных (или всех) предметов." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Распространяет полное обновление карты теней на заданное количество кадров.\n" +"Более высокие значения могут сделать тени нестабильными, более низкие " +"значения\n" +"будут потреблять больше ресурсов.\n" +"Наименьшее значение: 1; Предельное значение: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Диапазон увеличения кривой света.\n" +"Регулирует ширину увеличиваемого диапазона.\n" +"Стандартное отклонение усиления кривой света по Гауссу." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Постоянная точка возрождения" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Шум крутизны" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Шаг шума размера гор" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Шаг шума распространения гор" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Сила параллакса в 3D режиме." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Сила искажения света.\n" +"3 параметра 'усиления' определяют предел искажения света,\n" +"который увеличивается в освещении." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Строгая проверка протокола" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Прятать коды цветов" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Уровень поверхности необязательной воды размещенной на твердом слое парящих " +"островов. \n" +"Вода по умолчанию отключена и будет размещена только в том случае, если это " +"значение \n" +"будет установлено выше «mgv7_floatland_ymax» - «mgv7_floatland_taper» \n" +"(начало верхнего сужения).\n" +"*** ПРЕДУПРЕЖДЕНИЕ, ПОТЕНЦИАЛЬНАЯ ОПАСНОСТЬ ДЛЯ МИРОВ И РАБОТЫ СЕРВЕРА ***:\n" +"При включении размещения воды парящих островов должны быть сконфигурированы " +"и проверены \n" +"на наличие сплошного слоя, установив «mgv7_floatland_density» на 2,0 (или " +"другое \n" +"требуемое значение в зависимости от «mgv7_np_floatland»), чтобы избежать \n" +"чрезмерного интенсивного потока воды на сервере и избежать обширного " +"затопления\n" +"поверхности мира внизу." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "Синхронный SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Вариация температур в биомах." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Настройки" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Альтернативный шум рельефа" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain base noise" +msgstr "Основной шум поверхности" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Высота рельефа" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Шум высокой местности" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Шум поверхности" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Порог шума ландшафта для холмов\n" +"Управление пропорциями области мира, покрытой холмами\n" +"Регулируйте в направлении 0.0 для увеличения пропорций." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Порог шума ландшафта для озёр\n" +"Управление пропорциями области, покрытой озёрами\n" +"Изменяйте в сторону 0.0 для больших пропорций." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Шум постоянности ландшафта" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Путь к текстурам" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Размер текстуры для рендеринга карты теней.\n" +"Это должно быть число, кратное двум.\n" +"Большие числа создают более качественные тени, но они и более затратные." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Текстуры ноды можно выровнять либо относительно самой ноды, либо " +"относительно мира.\n" +"Первый режим лучше подходит к таким вещам, как машины, мебель и т. д.,\n" +"а во втором лестницы и микроблоки становятся более соответствующими среде.\n" +"Однако это новая возможность, и её нельзя использовать на старых серверах,\n" +"данный параметр позволяет принудительно применять к определённым типам нод.\n" +"Замечание: этот режим ЭКСПЕРИМЕНТАЛЬНЫЙ и может работать ненадлежащим " +"образом." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The URL for the content repository" +msgstr "Адрес сетевого хранилища" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The dead zone of the joystick" +msgstr "Мертвая зона джойстика" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Стандартный формат, в котором профили будут сохранены,\n" +"когда вызывают '/profiler save [формат]' без формата." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "Глубина грунта или иной ноды-заполнителя." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"Путь к файлу относительно пути к вашему миру, в который будут сохранены " +"профили." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "Идентификатор используемого джойстика" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"Расстояние в пикселях, с которого начинается взаимодействие с сенсорным " +"экраном." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"Предельная высота поверхности волнистых жидкостей.\n" +"4.0 = высота волны равна двум нодам.\n" +"0.0 = волна не двигается вообще.\n" +"Значение по умолчанию — 1.0 (1/2 ноды).\n" +"Требует, чтобы волнистые жидкости были включены." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "Сетевой интерфейс, который слушает сервер." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Привилегии, автоматически получаемые новым пользователем.\n" +"См. /privs для получения полного списка привилегий на своём сервере и при " +"настройке мода." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"Радиус объёма блоков вокруг каждого игрока, на которого распространяется " +"действие\n" +"активного материала блока, указанного в mapblocks (16 узлов).\n" +"В активные блоки загружаются объекты и запускаются ПРО.\n" +"Это также минимальный диапазон, в котором поддерживаются активные объекты " +"(мобы).\n" +"Это должно быть настроено вместе с active_object_send_range_blocks." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"Бэкэнд рендеринга.\n" +"После изменения этого параметра требуется перезагрузка.\n" +"Примечание: На Android, если вы не уверены, используйте OGLES1! В противном " +"случае приложение может не запуститься.\n" +"На других платформах рекомендуется использовать OpenGL.\n" +"Шейдеры поддерживаются OpenGL (только для настольных компьютеров) и OGLES2 " +"(экспериментальный)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"Чувствительность осей джойстика для перемещения\n" +"взгляда в игре." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"Сила глобального затенения нод. Чем меньше, тем темнее,\n" +"и наоборот. Возможные значения параметра - от 0.25 до 4.0\n" +"включительно. Если значение находится вне этого диапазона,\n" +"то оно будет округлено до ближайшего подходящего." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Время (в секундах) за которое очередь жидкости может превысить обработку\n" +"до тех пор, пока не будет предпринята попытка уменьшить её размер, сбросив " +"старые элементы очереди\n" +"Значение 0 отключает этот функционал." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"Бюджет времени для выполнения ABM на каждом шаге\n" +"(как часть ABM-промежутка)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Время в секундах между повторяющимися событиями,\n" +"когда зажато сочетание кнопок на джойстике." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Задержка перед повторным размещением ноды в секундах\n" +"при удержании клавиши размещения." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Тип джойстика" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"Вертикальное расстояние, на котором температура падает на 20, когда\n" +"«altitude_chill» включён. Также вертикальная расстояние,\n" +"на котором влажность падает на 10, когда «altitude_dry» включён." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Третий из четырёх 2D-шумов, которые вместе определяют диапазон высот холмов " +"и гор." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Время жизни выброшенных предметов в секундах.\n" +"Установите в -1 для отключения этой функции." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" +"Время суток во вновь созданном мире, в милличасах (значение от 0 до 23999)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Time send interval" +msgstr "Промежуток отправки времени" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Скорость хода времени" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Время, после которого клиент удаляет из памяти неиспользуемую информацию о " +"карте." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Чтобы уменьшить задержку, передача блоков карты замедляется, когда игрок что-" +"то\n" +"строит. Этот параметр определяет замедление после размещения или удаления " +"ноды." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Клавиша переключения режима камеры" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Задержка подсказки" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Порог сенсорного экрана" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Порог сенсорного экрана" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "Компромиссы для производительности" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Шум деревьев" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Трилинейная фильтрация" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"Полезно для обеспечения плавности миникарты на медленных машинах." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Доверенные моды" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "Адрес списка серверов, отображающийся во вкладке Мультиплеер." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Субдискретизация" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Субдискретизация аналогична использованию низкого разрешения экрана,\n" +"но она применяется только к игровому миру, графический интерфейс не " +"затрагивается.\n" +"Значительно увеличивает производительность за счёт вывода менее подробного " +"изображения.\n" +"Высокие значения приводят к менее проработанному изображению." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Неограниченное расстояние перемещения игрока" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Выгружать неиспользуемые сервером данные" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Верхний лимит Y для подземелий." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Верхний лимит Y для парящих островов." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Объёмные облака вместо плоских." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Анимированные облака в главном меню." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" +"Использовать анизотропную фильтрацию про взгляде на текстуры под углом." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Использовать билинейную фильтрацию для масштабирования текстур." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Использовать MIP-текстурирование для масштабирования текстур. Может немного " +"увеличить производительность,\n" +"особенно при использовании набора текстур высокого разрешения.\n" +"Гамма-коррекция при уменьшении масштаба не поддерживается." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Используйте многовыборочное сглаживание (MSAA) для сглаживания краев " +"блоков.\n" +"Этот алгоритм сглаживает область просмотра 3D, сохраняя резкость " +"изображения,\n" +"но это не влияет на внутренности текстур\n" +"(что особенно заметно на прозрачных текстурах).\n" +"Когда шейдеры отключены, между узлами появляются видимые пробелы.\n" +"Если установлено значение 0, MSAA отключено.\n" +"После изменения этой опции требуется перезагрузка." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Использовать трилинейную фильтрацию для масштабирования текстур." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "Объекты буфера вершин (VBO)" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "Вертикальная синхронизация" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Глубина долин" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Заполнение долин" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Профиль долины" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Склон долин" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Вариация глубины наполнителя биома." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Вариация предельной высоты гор (в нодах)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Вариация количества пещер." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Вариация вертикального масштабирования поверхности.\n" +"Поверхность становится почти плоской, когда шум меньше -0.55." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Меняет глубину поверхностных нод биома." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Варьирует неровность поверхности.\n" +"Определяет значение 'persistence' для шумов terrain_base и terrain_alt." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Регулирует крутизну утёсов." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Скорость вертикального лазания в нодах в секунду." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Вертикальная синхронизация." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Видеодрайвер" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Коэффициент покачивания" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Дальность отрисовки в нодах." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Клавиша уменьшения видимого диапазона" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Клавиша увеличения видимого диапазона" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Клавиша режима увеличения" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Viewing range" +msgstr "Дальность отрисовки" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "Виртуальный джойстик нажимает кнопку Aux1" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Громкость" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Громкость всех звуков.\n" +"Требует включенной звуковой системы." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Координата W генерируемого 3D-среза 4D-фрактала.\n" +"Определяет, какой из 3D-срезов 4D-формы будет сгенерирован.\n" +"Изменяет форму фрактала.\n" +"Не оказывает влияния на 3D-фракталы.\n" +"Диапазон примерно от -2 до 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Скорость ходьбы и полёта в нодах в секунду." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Скорость ходьбы" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Скорость ходьбы, полёта и лазания в режиме быстрого перемещения в нодах в " +"секунду." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Уровень воды" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Уровень поверхности воды мира." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Покачивание нод" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Покачивание листвы" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Волнистые жидкости" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Высота волн волнистых жидкостей" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Скорость волн волнистых жидкостей" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Длина волн на воде" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Покачивание растений" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "Цвет выделения" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Когда gui_scaling_filter установлен на true все изображения интерфейса " +"должны быть\n" +"отфильтрованы программно, но некоторые изображения генерируются напрямую\n" +"аппаратно (прим. render-to-texture для нод в инвентаре)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Когда gui_scaling_filter_txr2img истинно, изображения копируются\n" +"от аппаратного обеспечения до программного для масштабирования. Когда ложно, " +"возвращается\n" +"к старому методу масштабирования, для видеодрайверов, которые не\n" +"правильно поддерживают загрузку текстур с аппаратного обеспечения." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"При использовании билинейных/трилинейных/анизотропных фильтров текстуры с " +"низким разрешением\n" +"могут быть размыты, поэтому автоматически повышайте их масштаб с помощью " +"ближайших соседей\n" +"интерполяцией, чтобы сохранить чёткие пиксели. Здесь задается минимальный " +"размер текстуры\n" +"для увеличенных текстур; более высокие значения выглядят более чёткими, но " +"требуют больше\n" +"памяти. Рекомендуется использовать значения, кратные 2. Эта настройка " +"применяется ТОЛЬКО в том случае, если\n" +"включена билинейная/трилинейная/анизотропная фильтрация.\n" +"Это значение также используется в качестве базового размера текстуры узла " +"для автомасштабирования текстур с выравниванием по миру\n" +"автомасштабирования текстуры." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Должен ли отображаться задний план бирки по умолчанию.\n" +"Моды в любом случае могут задать задний план." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"Определяет необходимость рассинхронизации анимации текстур нод между блоками " +"карты." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Показываются ли клиентам игроки без ограничения расстояния.\n" +"Устарело, используйте параметр player_transfer_distance." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Разрешено ли игрокам наносить урон и убивать друг друга." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Просить ли клиентов переподключиться после сбоя Lua.\n" +"Установите это, если ваш сервер настроен на автоматический перезапуск." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Затуманивать ли конец видимой области." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Нужно ли выключить звуки? Вы можете включить звуки в любое время, если\n" +"звуковая система не отключена (enable_sound=false).\n" +"Внутри игры, вы можете включить режим отключения звуков, нажав на клавишу " +"отключения звуков или используя\n" +"меню паузы." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "Показывать данные отладки (аналогично нажатию F5)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"Компонент ширины начального размера окна. Игнорируется в полноэкранном " +"режиме." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Толщина обводки выделенных нод." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Только для систем на Windows: запускать Minetest с окном командной строки на " +"заднем плане\n" +"Содержит ту же информацию, что и файл debug.txt (имя файла может отличаться)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Папка мира (всё в мире хранится в ней).\n" +"Не требуется при запуске из главного меню." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Начальное время мира" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Текстуры с выравниванием по миру могут быть масштабированы так, чтобы " +"охватить несколько узлов. Однако,\n" +"сервер может не передать нужный масштаб, особенно если вы используете\n" +"специально разработанный набор текстур; при использовании этой опции клиент " +"пытается\n" +"определить масштаб автоматически, основываясь на размере текстуры.\n" +"См. также texture_min_size.\n" +"Предупреждение: Эта опция является ЭКСПЕРИМЕНТАЛЬНОЙ!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Режим текстур, выровненных глобально" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y плоской поверхности." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y нулевого уровня градиента плотности гор. Используется для вертикального " +"сдвига гор." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Y верхнего предела больших пещер." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Y-расстояние, над которым пещеры расширяются до полного размера." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Y-расстояние, на котором равнины сужаются от полной плотности до нуля.\n" +"Сужение начинается на этом расстоянии от предела Y.\n" +"Для твердого слоя парящих островов это контролирует высоту холмов/гор.\n" +"Должно быть меньше или равно половине расстояния между пределами Y." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Y-уровень средней поверхности рельефа." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Y-уровень верхнего предела пещеры." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Y-уровень высокого рельефа, формирующего горы." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Y-уровень нижнего рельефа и морского дна." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Y-уровень морского дна." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL file download timeout" +msgstr "Превышено время ожидания загрузки файла с помощью cURL" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "Превышено время ожидания для взаимодействия с cURL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL parallel limit" +msgstr "Предел одновременных соединений cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Режим творчества: " + +#~ msgid "- Damage: " +#~ msgstr "- Урон: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = Параллакс окклюзии с информацией о склоне (быстро).\n" +#~ "1 = Рельефный маппинг (медленно, но качественно)." + +#~ msgid "Address / Port" +#~ msgstr "Адрес / Порт" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Регулирует гамма-кодировку таблиц освещения. Более высокие значения " +#~ "ярче.\n" +#~ "Этот параметр предназначен только для клиента и игнорируется сервером." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "Управляет сужением островов горного типа ниже средней точки." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Уверены, что хотите сбросить мир одиночной игры?" + +#~ msgid "Back" +#~ msgstr "Назад" + +#, fuzzy +#~ msgid "Basic" +#~ msgstr "Основной" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Бит на пиксель (глубина цвета) в полноэкранном режиме." + +#~ msgid "Bump Mapping" +#~ msgstr "Бампмаппинг" + +#~ msgid "Bumpmapping" +#~ msgstr "Бампмаппинг" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "Центр среднего подъёма кривой света." + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Изменение интерфейса в главном меню:\n" +#~ "- Full: несколько однопользовательских миров, выбор игры, выбор пакета " +#~ "текстур и т. д.\n" +#~ "- Simple: один однопользовательский мир без выбора игр или текстур. " +#~ "Может быть полезно для небольших экранов." + +#~ msgid "Config mods" +#~ msgstr "Настройка модов" + +#~ msgid "Configure" +#~ msgstr "Настроить" + +#~ msgid "Connect" +#~ msgstr "Подключиться" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Контролирует скорость погружения в жидкости." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Контролирует плотность горной местности парящих островов.\n" +#~ "Является смещением, добавляемым к значению шума 'mgv7_np_mountain'." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Контролирует ширину тоннелей. Меньшие значения создают более широкие " +#~ "тоннели." + +#~ msgid "Credits" +#~ msgstr "Благодарности" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Цвет перекрестия (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Урон включён" + +#~ msgid "Darkness sharpness" +#~ msgstr "Резкость темноты" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Стандартный тайм-аут для cURL, заданный в миллисекундах.\n" +#~ "Работает только на сборках с cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Определяет области гладкой поверхности на парящих островах.\n" +#~ "Гладкие парящие острова появляются, когда шум больше ноля." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Определяет шаг выборки текстуры.\n" +#~ "Более высокое значение приводит к более гладким картам нормалей." + +#~ msgid "Del. Favorite" +#~ msgstr "Убрать из избранного" + +#~ msgid "" +#~ "Deprecated, define and locate cave liquids using biome definitions " +#~ "instead.\n" +#~ "Y of upper limit of lava in large caves." +#~ msgstr "" +#~ "Устарело, определяет и располагает жидкости в пещерах с использованием " +#~ "определений биома.\n" +#~ "Y верхней границы лавы в больших пещерах." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Скачивайте игры, такие как Minetest Game, на minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Вы можете скачать их на minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "" +#~ "Загружается и устанавливается $1.\n" +#~ "Пожалуйста, подождите..." + +#~ msgid "Enable VBO" +#~ msgstr "Включить объекты буфера вершин (VBO)" + +#~ msgid "Enable register confirmation" +#~ msgstr "Включить подтверждение регистрации" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Включает бампмаппинг для текстур. Карты нормалей должны быть " +#~ "предоставлены\n" +#~ "пакетом текстур или сгенерированы автоматически.\n" +#~ "Требует, чтобы шейдеры были включены." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Включить кинематографическое тональное отображение" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Включает генерацию карт нормалей \"на лету\" (эффект тиснения).\n" +#~ "Требует, чтобы бампмаппинг был включён." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Включает Parallax Occlusion.\n" +#~ "Требует, чтобы шейдеры были включены." + +#~ msgid "Enter " +#~ msgstr "Введите " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Экспериментальная опция, может привести к видимым зазорам\n" +#~ "между блоками, когда значение больше, чем 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "Кадровая частота во время паузы" + +#~ msgid "Fallback font shadow" +#~ msgstr "Тень резервного шрифта" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Прозрачность тени резервного шрифта" + +#~ msgid "Fallback font size" +#~ msgstr "Размер резервного шрифта" + +#~ msgid "Filtering" +#~ msgstr "Фильтрация" + +#~ msgid "Floatland base height noise" +#~ msgstr "Шум базовой высоты парящих островов" + +#~ msgid "Floatland mountain height" +#~ msgstr "Высота гор на парящих островах" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Прозрачность тени шрифта (непрозрачность от 0 до 255)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Размер резервного шрифта в пунктах (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "Шрифты FreeType" + +#~ msgid "Full screen BPP" +#~ msgstr "Глубина цвета в полноэкранном режиме" + +#~ msgid "Game" +#~ msgstr "Игра" + +#~ msgid "Gamma" +#~ msgstr "Гамма" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Создавать карты нормалей" + +#~ msgid "Generate normalmaps" +#~ msgstr "Генерировать карты нормалей" + +#~ msgid "HUD scale factor" +#~ msgstr "Масштаб игрового интерфейса" + +#~ msgid "High-precision FPU" +#~ msgstr "Высокоточный FPU" + +#~ msgid "IPv6 support." +#~ msgstr "Поддержка IPv6." + +#~ msgid "In-Game" +#~ msgstr "В игре" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Установка мода: файл \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Замеры" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Привязки клавиш. (Если это меню сломается, удалите настройки из minetest." +#~ "conf)" + +#~ msgid "Lava depth" +#~ msgstr "Глубина лавы" + +#~ msgid "Lightness sharpness" +#~ msgstr "Резкость освещённости" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Ограничение очередей emerge на диске" + +#~ msgid "Main" +#~ msgstr "Главное меню" + +#~ msgid "Main menu style" +#~ msgstr "Стиль главного меню" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "Заставляет DirectX работать с LuaJIT. Отключите, если это вызывает " +#~ "проблемы." + +#~ msgid "Menus" +#~ msgstr "Меню" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Миникарта в режиме радара, увеличение x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Миникарта в режиме радара, увеличение x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Миникарта в поверхностном режиме, увеличение x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Миникарта в поверхностном режиме, увеличение x4" + +#~ msgid "Name / Password" +#~ msgstr "Имя / Пароль" + +#~ msgid "Name/Password" +#~ msgstr "Имя/Пароль" + +#~ msgid "No" +#~ msgstr "Нет" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Выборка карт нормалей" + +#~ msgid "Normalmaps strength" +#~ msgstr "Сила карт нормалей" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Количество итераций Parallax Occlusion." + +#~ msgid "Ok" +#~ msgstr "Oк" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "Непрозрачность (альфа) тени за резервным шрифтом, между 0 и 255." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "Общее смещение эффекта Parallax Occlusion, обычно масштаб/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Общее смещение эффекта Parallax Occlusion." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Объёмные текстуры" + +#~ msgid "Parallax occlusion" +#~ msgstr "Включить параллакс" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Смещение параллакса" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Повторение параллакса" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Режим параллакса" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Масштаб параллаксной окклюзии" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Сила параллакса" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Путь к шрифту TrueType или картинке со шрифтом." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Путь для сохранения скриншотов." + +#~ msgid "Player name" +#~ msgstr "Имя игрока" + +#~ msgid "Profiling" +#~ msgstr "Профилирование" + +#~ msgid "Projecting dungeons" +#~ msgstr "Проступающие подземелья" + +#~ msgid "PvP enabled" +#~ msgstr "PvP разрешён" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Сброс одиночной игры" + +#~ msgid "Select Package File:" +#~ msgstr "Выберите файл дополнения:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Сервер / одиночная игра" + +#~ msgid "" +#~ "Set the shadow update time.\n" +#~ "Lower value means shadows and map updates faster, but it consume more " +#~ "resources.\n" +#~ "Minimun value 0.001 seconds max value 0.2 seconds" +#~ msgstr "" +#~ "Установить время обновления теней.\n" +#~ "Меньшее значение означает, что тени и карта обновляются быстрее, но это " +#~ "потребляет больше ресурсов.\n" +#~ "Минимальное значение 0,001 секунды, максимальное 0,2 секунды" + +#~ msgid "Shadow limit" +#~ msgstr "Лимит теней" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Смещение тени резервного шрифта (в пикселях). Если указан 0, то тень не " +#~ "будет показана." + +#~ msgid "Special" +#~ msgstr "Особенный" + +#~ msgid "Special key" +#~ msgstr "Клавиша использовать" + +#~ msgid "Start Singleplayer" +#~ msgstr "Начать одиночную игру" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Сила сгенерированных карт нормалей." + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "Сила среднего подъёма кривой света." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Этот шрифт будет использован для некоторых языков." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Для включения шейдеров необходим драйвер OpenGL." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Кино" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Типичная максимальная высота, выше и ниже средней точки гор парящих " +#~ "островов." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Вариация высоты холмов и глубин озёр на гладкой местности парящих " +#~ "островов." + +#~ msgid "View" +#~ msgstr "Вид" + +#~ msgid "Waving Water" +#~ msgstr "Волны на воде" + +#~ msgid "Waving water" +#~ msgstr "Волны на воде" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Использовать ли шрифты FreeType. Поддержка FreeType должна быть включена " +#~ "при сборке.\n" +#~ "Если отключено, используются растровые и XML-векторные изображения." + +#, fuzzy +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Верхний предел по Y для больших псевдослучайных пещер." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "Y-уровень середины поплавка и поверхности озера." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Y-уровень, на который распространяются тени с плавающей точкой." + +#~ msgid "Yes" +#~ msgstr "Да" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Вы собираетесь впервые присоединиться к серверу под именем «%s».\n" +#~ "Если вы продолжите, на этом сервере будет создан новый аккаунт с вашими " +#~ "учётными данными.\n" +#~ "Пожалуйста, введите пароль ещё раз и нажмите «Регистрация и подключение», " +#~ "чтобы подтвердить создание аккаунта, либо нажмите «Отмена», чтобы " +#~ "прервать операцию." + +#~ msgid "You died." +#~ msgstr "Ты умер." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/sk/minetest.po b/po/sk/minetest.po new file mode 100644 index 0000000..878e86a --- /dev/null +++ b/po/sk/minetest.po @@ -0,0 +1,8151 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-24 09:25+0000\n" +"Last-Translator: Marian <daretmavi@gmail.com>\n" +"Language-Team: Slovak <https://hosted.weblate.org/projects/minetest/minetest/" +"sk/>\n" +"Language: sk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Vyprázdniť výstupný komunikačný poradovník" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Prázdny príkaz." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Návrat do hlavnej ponuky" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Chybný príkaz: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Spustený príkaz: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Vypísať pripojených hráčov" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Pripojení hráči: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Výstupný komunikačný poradovník je teraz prázdny." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Tento príkaz je zakázaný serverom." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Oživiť" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Zomrel si" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Dostupné príkazy:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Dostupné príkazy: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Príkaz nie je k dispozícií: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Zobraz pomocníka k príkazom" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Použi '.help <cmd>' aby si získal viac informácií, alebo '.help all' pre " +"zobrazenie všetkého." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <príkaz>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "V poriadku" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<nie je k dispozícií>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Objavila sa chyba v lua skripte:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Objavila sa chyba:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Hlavná ponuka" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Znova pripojiť" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Server požiadal o obnovu spojenia:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "K dispozícií je nová verzia $1" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "Užívateľské módy" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" +"Nainštalovaná verzia: $1\n" +"Nová verzia: $2\n" +"Navštív $3 pre informácie ako získať najnovšiu verziu a maj prehľad o " +"funkciách a opravách chýb." + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "Neskôr" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "Nikdy" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Verzie protokolov sa nezhodujú. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Server vyžaduje protokol verzie $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Server podporuje verzie protokolov medzi $1 a $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "Navštív webovú stránku" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Podporujeme iba protokol verzie $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Podporujeme verzie protokolov medzi $1 a $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "(Povolené, s chybou)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "(Neuspokojivé)" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Zrušiť" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Nevyhnutné doplnky:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Zakázať všetko" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Deaktivuj balíček modifikácií" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Povoliť všetko" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Povoliť balíček modifikácií" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Nepodarilo sa povoliť modifikáciu \"$1\" pretože obsahuje nepovolené znaky. " +"Povolené sú len znaky [a-z0-9_]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Nájdi viac modifikácií" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Bez (voliteľných) nevyhnutných doplnkov" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Popis hry nie je k dispozícií." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Bez povinných nevyhnutných doplnkov" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Popis balíka rozšírení nie je k dispozícií." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Bez voliteľných nevuhnutných doplnkov" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Voliteľné nevyhnutné doplnky:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Uložiť" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Svet:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "povolené" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" už exituje. Chcel by si ho prepísať?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Nevyhnutné doplnky $1 a $2 budú nainštalované." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 od $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 sa sťahuje,\n" +"$2 čaká v rade" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 sťahujem..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 požadované nevyhnutné doplnky nie je možné nájsť." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 bude nainštalovaný a $2 nevyhnutné doplnky budú vynechané." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Všetky balíky" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Už nainštalované" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Späť na Hlavnú ponuku" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Základná hra:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB nie je k dispozícií ak bol Minetest skompilovaný bez cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Sťahujem..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Nepodarilo sa stiahnuť $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Hry" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Nainštalovať" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Nainštalovať $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Nainštalovať chýbajúce nevyhnutné doplnky (závislosti)" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Inštalácia: Nepodporovaný typ súboru, alebo poškodený archív" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Rozšírenia" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Nepodarilo sa stiahnuť žiadne balíčky" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Bez výsledkov" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Bez aktualizácií" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Nenájdené" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Prepísať" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Prosím skontroluj či je základná hra v poriadku." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Čaká v rade" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Balíky textúr" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Odinštalovať" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Aktualizácia" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Aktualizovať všetky [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Pozri si viac informácií vo webovom prehliadači" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Svet s názvom \"$1\" už existuje" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Dodatočný terén" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Ochladenie s nadmorskou výškou" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Sucho v nadmorskej výške" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Miešanie ekosystémov" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Ekosystémy" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Jaskyne" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Jaskyne" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Vytvoriť" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekorácie" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "Vývojový Test je určený vývojárom." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Kobky" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Rovný terén" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Poletujúce pevniny na oblohe" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Lietajúce krajiny (experimentálne)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Generuj nefragmentovaný terén: oceány a podzemie" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Kopce" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Vlhkosť riek" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Zvyšuje vlhkosť v okolí riek" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "Nainštalovať hru" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "Nainštalovať inú hru" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Jazerá" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" +"Nízka vlhkosť a vysoké teploty spôsobujú znižovanie hladín, alebo vysychanie " +"riek" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Generátor mapy" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Príznaky generátora máp" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Špecifické príznaky generátora máp" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Hory" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Prúd bahna" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Sieť tunelov a jaskýň" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Nie je zvolená hra" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Znižuje teplotu s nadmorskou výškou" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Znižuje vlhkosť s nadmorskou výškou" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Rieky" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Rieky na úrovni hladiny mora" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Semienko" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Plynulý prechod medzi ekosystémami" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Štruktúry objavujúce sa na povrchu (nemá vplyv na stromy a vysokú trávu " +"vytvorenú verziou v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Štruktúry objavujúce sa na povrchu, typicky stromy a rastliny" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Mierne pásmo, Púšť" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Mierne pásmo, Púšť, Džungľa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Mierne pásmo, Púšť, Džungľa, Tundra, Tajga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erózia terénu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Stromy a vysoká tráva" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Premenlivá hĺbka riek" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Obrovské jaskyne hlboko v podzemí" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Meno sveta" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Nie je nainštalovaná žiadna hra." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Si si istý, že chceš zmazať \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Vymazať" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: neúspech pri mazaní \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: nesprávna cesta \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Zmazať svet \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Potvrď heslo" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "Pripája sa $1" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "Chýba meno" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Meno" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Heslo" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "Heslá sa nezhodujú" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "Registrovať sa" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Prijať" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Premenuj balíček rozšírení:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Tento balíček rozšírení má vo svojom modpack.conf explicitne zadané meno, " +"ktoré prepíše akékoľvek tunajšie premenovanie." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Nie je zadaný popis nastavenia)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D šum" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Späť na nastavenia" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Prehliadaj" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "Doplnky: Hry" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "Doplnky: Rozšírenia (módy)" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Vypnuté" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Upraviť" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Aktivované" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lakunarita" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktávy" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Ofset" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Vytrvalosť" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Prosím zadaj platné celé číslo." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Prosím vlož platné číslo." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Obnov štand. hodnoty" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Mierka" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Hľadaj" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Zvoľ adresár" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Zvoľ súbor" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Zobraz technické názvy" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Hodnota musí byť najmenej $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Hodnota nesmie byť vyššia ako $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Rozptyl X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Rozptyl Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Rozptyl Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Absolútna hodnota (absvalue)" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "štandardné hodnoty (defaults)" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "zjemnené (eased)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Aktivované)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 rozšírenia" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Zlyhala inštalácia $1 na $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" +"Inštalácia rozšírenia: Nie je možné nájsť skutočné meno rozšírenia pre: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Inštalácia rozšírenia: Nie je možné nájsť vhodný adresár pre balíček " +"rozšírení $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Nie je možné nájsť platné rozšírenie, alebo balíček rozšírení" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Nie je možné nainštalovať $1 ako balíček textúr" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Nie je možné nainštalovať hru $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Nie je možné nainštalovať rozšírenie $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Nie je možné nainštalovať balíček rozšírení $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Nahrávam..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Zoznam verejných serverov je zakázaný" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Skús znova povoliť verejný zoznam serverov a skontroluj internetové " +"pripojenie." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "O" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktívny prispievatelia" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Aktívny renderer:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Hlavný vývojari" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Otvor adresár užívateľa" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Otvor adresár, ktorý obsahuje svety, hry, mody a textúry\n" +"od užívateľov v správcovi/prieskumníkovi súborov." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Predchádzajúci prispievatelia" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Predchádzajúci hlavný vývojári" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "Zdieľaj ladiaci záznam (debug log)" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Hľadaj nový obsah na internete" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Doplnky" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Deaktivuj balíček textúr" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informácie:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Nainštalované balíčky:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Bez závislostí." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Nie je k dispozícií popis balíčka" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Premenuj" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Odinštaluj balíček" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Použi balíček textúr" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Zverejni server" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Priraď adresu" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Kreatívny mód" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Aktivuj zranenie" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Hosťuj hru" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Hosťuj server" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Inštaluj hry z ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Nový" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Nie je vytvorený ani zvolený svet!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Hraj hru" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Zvoľ mody" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Zvoľ si svet:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Port servera" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Spusti hru" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adresa" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Zmaž" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Kreatívny mód" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Zranenie / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Obľúbené" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Nekompatibilné servery" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Pripoj sa do hry" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "Prihlásiť sa" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Verejné servery" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Obnov" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "Odstráň z obľúbených" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Popis servera" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "(vyžaduje sa podpora hry)" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D mraky" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Všetky nastavenia" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Vyhladzovanie:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Automat. ulož. veľkosti okna" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilineárny filter" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Zmeň ovládacie klávesy" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Prepojené sklo" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dynamické tiene" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "Dynamické tiene:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Ozdobné listy" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Vysoké" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Nízke" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Stredné" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmapy" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmapy + Aniso. filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Žiaden filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Žiadne Mipmapy" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Nasvietenie kocky" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Obrys kocky" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Žiadne" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Nepriehľadné listy" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Nepriehľadná voda" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Častice" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Zobrazenie:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Nastavenia" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shadery" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shadery (experimentálne)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Shadery (nedostupné)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Jednoduché listy" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Jemné osvetlenie" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Textúrovanie:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Optim. farieb" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "Dotykový prah (px):" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Trilineárny filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "Veľmi vysoké" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Veľmi nízke" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Vlniace sa listy" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Vlniace sa kvapaliny" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Vlniace sa rastliny" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "Spojenie zrušené (chyba protokolu?)." + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Časový limit pripojenia vypršal." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Hotovo!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inicializujem kocky" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Inicializujem kocky..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Nahrávam textúry..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Obnovujem shadery..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Chyba spojenia (časový limit?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Nie je možné nájsť alebo nahrať hru: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Chybná špec. hry." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Hlavné menu" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Nie je zvolený svet ani poskytnutá adresa. Niet čo robiť." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Meno hráča je príliš dlhé." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Prosím zvoľ si meno!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Dodaný súbor s heslom nie je možné otvoriť: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Zadaná cesta k svetu neexistuje: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Pozri detaily v debug.txt." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Adresa: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Mode: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Verejný: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Meno servera: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Chyba pri serializácií:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Prístup zamietnutý. Dôvod: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Automatický pohyb vpred je zakázaný" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Automatický pohyb vpred je aktivovaný" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Hranice bloku sú skryté" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Hranice bloku sú zobrazené pre všetky bloky" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Hranice bloku sú zobrazené pre aktuálny blok" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Hranice bloku sú zobrazené pre blízke bloky" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Aktualizácia kamery je zakázaná" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Aktualizácia kamery je aktivovaná" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "Hranice bloku nie je možné zobraziť (zakázané rozšírením, alebo hrou)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Zmeniť heslo" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Filmový režim je zakázaný" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Filmový režim je aktivovaný" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Klient je odpojený" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Skriptovanie na strane klienta je zakázané" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Pripájam sa k serveru..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Spojenie sa z neznámeho dôvodu nepodarilo" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Pokračuj" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Ovládanie:\n" +"- %s: pohyb vpred\n" +"- %s: pohyb vzad\n" +"- %s: pohyb doľava\n" +"- %s: pohyb doprava\n" +"- %s: skoč/vylez\n" +"- %s: kop/udri\n" +"- %s: polož/použi\n" +"- %s: zakrádaj sa/choď dole\n" +"- %s: odhoď vec\n" +"- %s: inventár\n" +"- Myš: otoč sa/obzeraj sa\n" +"- Myš koliesko: zvoľ si vec\n" +"- %s: komunikácia\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Nepodarilo za vyhodnotiť adresu: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Vytváram klienta..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Vytváram server..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Ladiace informácie a Profilový graf sú skryté" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Ladiace informácie zobrazené" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Ladiace informácie, Profilový graf a Obrysy sú skryté" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Štandardné ovládanie:\n" +"Menu nie je zobrazené:\n" +"- jeden klik: tlačidlo aktivuj\n" +"- dvojklik: polož/použi\n" +"- posun prstom: pozeraj sa dookola\n" +"Menu/Inventár je zobrazené/ý:\n" +"- dvojklik (mimo):\n" +" -->zatvor\n" +"- klik na kôpku, klik na pozíciu:\n" +" --> presuň kôpku \n" +"- chyť a prenes, klik druhým prstom\n" +" --> polož jednu vec na pozíciu\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Neobmedzená dohľadnosť je zakázaná" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Neobmedzená dohľadnosť je aktivovaná" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "Chyba pri vytváraní klienta: %s" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Návrat do menu" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Ukončiť hru" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Rýchly režim je zakázaný" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Rýchly režim je aktívny" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Rýchly režim je aktivovaný (poznámka: chýba právo 'fast')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Režim lietania je zakázaný" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Režim lietania je aktívny" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Režim lietania je aktívny (poznámka: chýba právo 'fly')" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Hmla je vypnutá" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Hmla je aktivovaná" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Informácie o hre:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Hra je pozastavená" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Beží server" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Definície vecí..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Média..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Minimapa je aktuálne zakázaná hrou, alebo rozšírením" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Hra pre viacerých hráčov" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Režim prechádzania stenami je zakázaný" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Režim prechádzania stenami je aktivovaný" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" +"Režim prechádzania stenami je aktivovaný (poznámka: chýba právo 'noclip')" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Definície kocky..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Vypnutý" + +#: src/client/game.cpp +msgid "On" +msgstr "Aktívny" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Režim pohybu podľa sklonu je zakázaný" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Režim pohybu podľa sklonu je aktívny" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profilový graf je zobrazený" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Vzdialený server" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Prekladám adresu..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Vypínam..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Hra pre jedného hráča" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Hlasitosť" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Zvuk je stlmený" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Zvukový systém je zakázaný" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Zvukový systém nie je podporovaný v tomto zostavení" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Zvuk je obnovený" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Na serveri pravdepodobne beží iná verzia %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Nemôžem sa pripojiť na %s, lebo IPv6 je zakázané" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Nemôžem sa spojiť s %s, lebo IPv6 je zakázané" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Dohľadnosť je zmenená na %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Dohľadnosť je na maxime: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Dohľadnosť je na minime: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Hlasitosť zmenená na %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Obrysy zobrazené" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zväčšenie je zakázané hrou, alebo rozšírením" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Komunikačná konzola je skrytá" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Komunikačná konzola je zobrazená" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD je skryrý" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD je zobrazený" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profilovanie je skryté" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profilovanie je zobrazené (strana %d z %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplikácie" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "CTRL" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Dole" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Zmaž EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Spustiť" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Pomoc" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME Súhlas" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME Konvertuj" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME Escape" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME Zmena módu" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME Nekonvertuj" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Vlož" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Vľavo" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Ľavé tlačítko" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Ľavý CRTL" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Ľavé Menu" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Ľavý Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Ľavá klávesa Windows" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Stredné tlačítko" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numerická klávesnica *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numerická klávesnica +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numerická klávesnica -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numerická klávesnica ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numerická klávesnica /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numerická klávesnica 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numerická klávesnica 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numerická klávesnica 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numerická klávesnica 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numerická klávesnica 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numerická klávesnica 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numerická klávesnica 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numerická klávesnica 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numerická klávesnica 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numerická klávesnica 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Hraj" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "PrtSc" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Enter" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Vpravo" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Pravé tlačítko" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Pravý CRTL" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Pravé Menu" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Pravý Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Pravá klávesa Windows" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Vybrať" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Spánok" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Snímka" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Medzera" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Hore" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X tlačidlo 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X tlačidlo 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Priblíž" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Minimapa je skrytá" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimapa v radarovom režime, priblíženie x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimapa v povrchovom režime, priblíženie x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimapa v móde textúry" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Nepodarilo sa otvoriť web stránku" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Otváram web stránku" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Pokračuj" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\"=šplhaj dole" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Automaticky pohyb vpred" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Automatické skákanie" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Vzad" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Hranice bloku" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Zmeň pohľad" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Komunikácia" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Príkaz" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konzola" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Zníž dohľad" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Zníž hlasitosť" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "2x stlač \"skok\" pre prepnutie lietania" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Zahodiť" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Vpred" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Zvýš dohľad" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Zvýš hlasitosť" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Inventár" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Skok" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Klávesa sa už používa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "Priradenie kláves." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Lokálny príkaz" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Vypni zvuk" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Ďalšia vec" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Pred. vec" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Zmena dohľadu" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Fotka obrazovky" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Zakrádať sa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Prepni HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Prepni logovanie komunikácie" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Prepni rýchly režim" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Prepni lietanie" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Prepni hmlu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Prepni minimapu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Prepni režim prechádzania stenami" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Prepni režim pohybu podľa sklonu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "stlač klávesu" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Zmeniť" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nové heslo" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Staré heslo" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Hesla sa nezhodujú!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Odísť" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Zvuk stlmený" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Hlasitosť: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "sk" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" +"Meno nie je zaregistrované. Pre vytvorenie účtu na tomto serveri klikni na " +"'Registrovať' ('Register')" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "Meno už je použité. Prosím zvoľ si iné meno" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Zafixuje pozíciu virtuálneho joysticku.\n" +"Ak je vypnuté, virtuálny joystick sa vycentruje na pozícií prvého dotyku." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Použije virtuálny joystick na stlačenie tlačidla \"Aux1\".\n" +"Ak je aktivované, virtuálny joystick stlačí tlačidlo \"Aux1\" keď je mimo " +"hlavný kruh." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) posun fraktálu od stredu sveta v jednotkách 'mierky'.\n" +"Môže byť použité pre posun požadovaného bodu do (0, 0) pre\n" +"vytvorenie vhodného bodu pre ožitie, alebo pre povolenie 'priblíženia'\n" +"na želaný bod zväčšením 'mierky'.\n" +"Štandardne je to vyladené na vhodný bod oživenia pre Mandelbrot\n" +"sadu so štandardnými parametrami, je možné, že bude potrebná úprava\n" +"v iných situáciach.\n" +"Rozsah je približne -2 to 2. Zväčší podľa 'mierky' pre posun v kockách." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z) mierka fraktálu v kockách.\n" +"Skutočná veľkosť fraktálu bude 2 až 3 krát väčšia.\n" +"Tieto čísla môžu byť veľmi veľké, fraktál sa nemusí\n" +"zmestiť do sveta.\n" +"Zvýš pre 'priblíženie' detailu fraktálu.\n" +"Štandardne je vertikálne stlačený tvar vhodný pre\n" +"ostrov, nastav všetky 3 čísla rovnaké pre nezmenený tvar." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2D šum, ktorý riadi tvar/veľkosť hrebeňa hôr." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2D šum, ktorý riadi tvar/veľkosť vlnitosti kopcov." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2D šum, ktorý riadi tvar/veľkosť horských stepí." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "2D šum, ktorý riadi veľkosť/výskyt hrebeňa kopcov." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D šum, ktorý riadi veľkosť/výskyt zvlnenia kopcov." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "2D šum, ktorý riadi veľkosť/výskyt horských stepí." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2D šum, ktorý určuje údolia a kanály riek." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D mraky" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D režim" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "3D režim stupeň paralaxy" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D šum definujúci gigantické dutiny/jaskyne." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D šum definujúci štruktúru a výšku hôr.\n" +"Takisto definuje štruktúru pohorí lietajúcich pevnín." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"3D šum definujúci štruktúru lietajúcich pevnín.\n" +"Ak je zmenený zo štandardného, 'mierka' šumu (štandardne 0.7) môže\n" +"potrebovať nastavenie, keďže zošpicaťovanie lietajúcej pevniny funguje " +"najlepšie,\n" +"keď tento šum má hodnotu približne v rozsahu -2.0 až 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "3D šum definujúci štruktúru stien kaňona rieky." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3D šum definujúci terén." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "3D šum pre previsy, útesy, atď. hôr. Obvykle malé odchýlky." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D šum definujúci počet kobiek na časť mapy (mapchunk)." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Podpora 3D.\n" +"Aktuálne sú podporované:\n" +"- none: žiaden 3D režim.\n" +"- anaglyph: tyrkysovo/purpurová farba 3D.\n" +"- interlaced: podpora polarizácie založenej na párnych/nepárnych riadkoch " +"obrazu.\n" +"- topbottom: rozdelená obrazovka hore/dole.\n" +"- sidebyside: rozdelená obrazovka vedľa seba.\n" +"- crossview: 3D prekrížených očí (Cross-eyed)\n" +"- pageflip: 3D založené na quadbuffer\n" +"Režim interlaced požaduje, aby boli aktivované shadery." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "3d" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Zvolené semienko pre novú mapu, ponechaj prázdne pre náhodné.\n" +"Pri vytvorení nového sveta z hlavného menu, bude prepísané." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Správa, ktorá sa zobrazí všetkým klientom pri páde servera." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Správa, ktorá sa zobrazí všetkým klientom, keď sa server vypína." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Interval Aktívnej Blokovej Modifikácie (ABM)" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "Vyhradená doba ABM" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Absolútny limit kociek vo fronte" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Zrýchlenie vo vzduchu" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Gravitačné zrýchlenie, v kockách za sekundu na druhú." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Aktívne modifikátory blokov (ABM)" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Riadiaci interval aktívnych blokov" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Rozsah aktívnych blokov" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Zasielaný rozsah aktívnych objektov" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Adresa pre pripojenie sa.\n" +"Ponechaj prázdne pre spustenie lokálneho servera.\n" +"Adresné políčko v hlavnom menu prepíše toto nastavenie." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Pridá časticové efekty pri vykopávaní kocky." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Nastav dpi konfiguráciu podľa svojej obrazovky (nie pre X11/len pre Android) " +"napr. pre 4k obrazovky." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Uprav zistenú hustotu zobrazenia, použitú pre zmenu veľkosti prvkov " +"grafického rozhrania." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Nastav hustotu vrstvy lietajúcej pevniny.\n" +"Zvýš hodnotu pre zvýšenie hustoty. Môže byť kladná, alebo záporná.\n" +"Hodnota = 0.0: 50% objemu je lietajúca pevnina.\n" +"Hodnota = 2.0 (môže byť vyššie v závislosti od 'mgv7_np_floatland', vždy " +"otestuj\n" +"aby si si bol istý) vytvorí pevnú úroveň lietajúcej pevniny." + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "Meno správcu" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Pokročilé" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Zmení svetelnú krivku aplikovaním 'gamma korekcie'.\n" +"Vyššie hodnoty robia stredné a nižšie tóny svetlejšími.\n" +"Hodnota '1.0' ponechá svetelnú krivku nezmenenú.\n" +"Toto má vplyv len na denné a umelé svetlo,\n" +"ma len veľmi malý vplyv na prirodzené nočné svetlo." + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "Vždy lietaj rýchlo" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Ambient occlusion gamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Počet správ, ktoré môže hráč poslať za 10 sekúnd." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Zväčšuje údolia." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Anisotropné filtrovanie" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Zverejni server" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Zverejni v zozname serverov." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Pridaj názov položky/veci" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Pridaj názov veci do popisku." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Šum jabloní" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Zotrvačnosť ruky" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Zotrvačnosť ruky, vytvára realistickejší pohyb ruky\n" +"pri pohybe kamery." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Ponúkni obnovu pripojenia po páde" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"V tento vzdialenosti bude server agresívne optimalizovať, ktoré\n" +"bloky pošle klientovi.\n" +"Malé hodnoty potenciálne výrazne zvýšia výkon, za cenu viditeľných\n" +"chýb renderovania (niektoré bloky nebudú vyrenderované pod vodou a v " +"jaskyniach,\n" +"prípadne niekedy aj na súši).\n" +"Nastavenie hodnoty vyššej ako max_block_send_distance deaktivuje túto\n" +"optimalizáciu.\n" +"Udávane v blokoch mapy (16 kociek)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "Zvuk" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Tlačidlo Automatický pohyb vpred" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Automaticky vyskočí na prekážku vysokú jedna kocka." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Automaticky zápis do zoznamu serverov." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Pamätať si veľkosť obrazovky" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Režim automatickej zmeny mierky" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Tlačidlo Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Klávesa Aux1 pre šplhanie hore/dole" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tlačidlo Vzad" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Základná úroveň dna" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Základná výška terénu." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Základné práva" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Šum pláže" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Hraničná hodnota šumu pláže" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilineárne filtrovanie" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Spájacia adresa" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "Parametre šumu pre Biome API" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Šum biómu" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Vzdialenosť pre optimalizáciu posielania blokov" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "Nadskakovanie" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Cesta k tučnému šikmému písmu" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Cesta k tučnému šikmému písmu s pevnou šírkou" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Cesta k tučnému písmu" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Cesta k tučnému písmu s pevnou šírkou" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Stavanie vnútri hráča" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Vstavané (Builtin)" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "Pohľad" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Vzdialenosť kamery 'blízko orezanej roviny' v kockách, medzi 0 a 0.25\n" +"Funguje len na GLES platformách. Väčšina toto nepotrebuje meniť.\n" +"Zvýšenie môže zredukovať artefakty na slabších GPU.\n" +"0.1 = Štandardná hodnota, 0.25 = Dobrá hodnota pre slabé tablety." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Plynulý pohyb kamery" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Plynulý pohyb kamery vo filmovom režime" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Tlačidlo Aktualizácia pohľadu" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Šum jaskyne" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Šum jaskýň #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Šum jaskýň #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Šírka jaskyne" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Cave1 šum" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Cave2 šum" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Limit dutín" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Šum dutín" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Zbiehavosť dutín" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Hraničná hodnota dutín" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Horný limit dutín" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Centrum rozsahu zosilnenia svetelnej krivky.\n" +"Kde 0.0 je minimálna úroveň, 1.0 je maximálna úroveň ." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Časové obmedzenie príkazu v správe" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Komunikačné príkazy" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Veľkosť komunikačného písma" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Tlačidlo Komunikácia" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Úroveň komunikačného logu" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Limit počtu správ" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Formát komunikačných správ" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Hranica správ pre vylúčenie" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Max dĺžka správy" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Tlačidlo Prepnutie komunikácie" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Komunikačná webové odkazy" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Veľkosť časti (chunk)" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Filmový mód" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tlačidlo Filmový režim" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Vyčisti priehľadné textúry" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Spustiteľné webové odkazy (kliknutie stredným tlačítkom, alebo CTRL+ľave " +"kliknutie) sú v komunikačnej konzole povolené." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Klient" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Klient a Server" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Úpravy (modding) cez klienta" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Obmedzenia úprav na strane klienta" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Obmedzenie vyhľadávania dosahu kociek na strane klienta" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "Úpravy (módovanie) na strane klienta" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Rýchlosť šplhania" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Polomer mrakov" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Mraky" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Mraky sú efektom na strane klienta." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Mraky v menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Farebná hmla" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Farebné tiene" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Čiarkou oddelený zoznam príznakov, ktoré sa skryjú v zozname doplnkov.\n" +"\"nonfree\" môže byť využité na skrytie doplnkov, ktoré nie je možné " +"považovať za 'voľný softvér',\n" +"tak ako je definovaný Free Software Foundation.\n" +"Môžeš definovať aj hodnotenie obsahu.\n" +"Tie to príznaky sú nezávislé od verzie Minetestu,\n" +"viď. aj kompletný zoznam na https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Čiarkou oddelený zoznam rozšírení, ktoré majú povolené prístup na HTTP API,\n" +"ktoré im dovolia posielať a sťahovať dáta z/na internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Čiarkou oddelený zoznam dôveryhodných rozšírení, ktoré majú povolené\n" +"nebezpečné funkcie aj keď je bezpečnosť rozšírení aktívna (cez " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Tlačidlo Príkaz" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Úroveň kompresie použitej pri ukladaní blokov mapy na disk.\n" +"-1 - predvolená úroveň kompresie\n" +"0 - najmenšia kompresia, najrýchlejšie\n" +"9 - najlepšia kompresia, najpomalšie" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Úroveň kompresie použitej pri posielaní blokov mapy klientom.\n" +"-1 - predvolená úroveň kompresie\n" +"0 - najmenšia kompresia, najrýchlejšie\n" +"9 - najlepšia kompresia, najpomalšie" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Prepojené sklo" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Pripoj sa na externý média server" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Prepojí sklo, ak je to podporované kockou." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Priehľadnosť konzoly" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Farba konzoly" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Výška konzoly" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "Úložisko doplnkov" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "Čierna listina príznakov z ContentDB" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "ContentDB Maximum súbežných sťahovaní" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "Cesta (URL) ku ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Neustály pohyb vpred" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Neustály pohyb vpred, prepína sa klávesou pre \"Automatický pohyb vpred\".\n" +"Opätovne stlač klávesu pre \"Automatický pohyb vpred\", alebo pohyb vzad pre " +"vypnutie." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Ovládanie" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Riadi dĺžku dňa a noci.\n" +"Príklad:\n" +"72 = 20min, 360 = 4min, 1 = 24hodín, 0 = deň/noc/čokoľvek ostáva nezmenený." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" +"Riadi rýchlosť klesania v kvapaline pri nečinnosti. Negatívne hodnoty\n" +"spôsobia, že budeš namiesto klesania stúpať." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Riadi strmosť/hĺbku jazier." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Riadi strmosť/výšku kopcov." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Riadi šírku tunelov, menšia hodnota vytvára širšie tunely.\n" +"Hodnota >= 10.0 úplne vypne generovanie tunelov, čím sa vyhne\n" +"náročným prepočtom šumu." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Správa pri páde" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Kreatívny režim" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Priehľadnosť zameriavača" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Priehľadnosť zameriavača (nepriehľadnosť, medzi 0 a 255).\n" +"Tiež nastavuje farbu objektu zameriavača." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Farba zameriavača" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Farba zameriavača (R,G,B).\n" +"Nastavuje farbu objektu zameriavača" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Zranenie" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Tlačidlo Ladiace informácie" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Hraničná veľkosť ladiaceho log súboru" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Úroveň ladiacich info" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "Ladenie" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Tlačidlo Zníž hlasitosť" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Určený krok servera" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Štandardné zrýchlenie" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Štandardná hra" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Štandardná hra pri vytváraní nového sveta.\n" +"Toto bude prepísané pri vytvorení nového sveta z hlavného menu." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Štandardné heslo" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Štandardné práva" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Štandardný formát záznamov" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Štandardná veľkosť kôpky" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Definuje kvalitu filtrovania tieňov\n" +"Toto simuluje efekt jemných tieňov použitím PCF alebo poisson disk\n" +"zároveň ale spotrebováva viac zdrojov." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Definuje oblasti, kde stromy majú jablká." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Definuje oblasti s pieskovými plážami." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Definuje rozdelenie vyššieho terénu a strmosť útesov." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Definuje rozdelenie vyššieho terénu." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "Definuje plnú šírku dutín, menšie hodnoty vytvoria väčšie dutiny." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Vo veľkom merítku definuje štruktúru kanálov riek." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Definuje umiestnenie a terén voliteľných kopcov a jazier." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Definuje úroveň dna." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Definuje hĺbku koryta rieky." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Určuje maximálnu vzdialenosť zobrazenia hráča v blokoch (0 = neobmedzená)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Definuje šírku pre koryto rieky." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Definuje šírku údolia rieky." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Definuje oblasti so stromami a hustotu stromov." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Oneskorenie, kým sa Mesh aktualizuje na strane klienta v ms.\n" +"Zvýšenie spomalí množstvo aktualizácie Mesh objektov, teda zníži chvenie na " +"pomalších klientoch." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Oneskorenie posielania blokov po výstavbe" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Oneskorenie zobrazenia popisku, zadané v milisekundách." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Zastaralé Lua API spracovanie" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Hĺbka pod ktorou nájdeš gigantické dutiny/jaskyne." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Hĺbka pod ktorou nájdeš veľké jaskyne." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Zobrazovaný popis servera, keď sa hráč na server pripojí a v zozname " +"serverov." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Hraničná hodnota šumu púšte" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Púšte sa objavia keď np_biome presiahne túto hodnotu.\n" +"Ak je aktívny príznak 'snowbiomes', tak toto je ignorované." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Nesynchronizuj animáciu blokov" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "Nastavenia pre vývojárov" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Tlačidlo Kopanie" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Časticové efekty pri kopaní" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Zakáž anticheat" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Zakáž prázdne heslá" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Faktor škálovania hustoty zobrazenia" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" +"Vzdialenosť v kockách do ktorej sa ešte spracúva hĺbka priesvitnosti\n" +"Používa sa obmedzenie dopadu na výkon pri spracovaní hĺbky priesvitnosti" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Doménové meno servera, ktoré bude zobrazené v zozname serverov." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Dvakrát skok pre lietanie" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Dvojnásobné stlačenie klávesy pre skok prepne režim lietania." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Tlačidlo Zahoď vec" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Získaj ladiace informácie generátora máp." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Maximálne Y kobky" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Minimálne Y kobky" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Šum kobky" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Aktivuj IPv6 podporu (pre klienta ako i server).\n" +"Požadované aby IPv6 spojenie vôbec mohlo fungovať." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Aktivuj podporu úprav na klientovi pomocou Lua skriptov.\n" +"Táto podpora je experimentálna a API sa môže zmeniť." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Aktivuj poisson disk filtrovanie.\n" +"Ak je aktivované použije poisson disk pre vytvorenie \"mäkkých tieňov\". V " +"opačnom prípade sa použije PCF filtrovanie." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Aktivuje farebné tiene.\n" +"Ak je aktivovaný, tak priesvitné kocky dávajú farebné tiene. Toto je náročné." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Aktivuj okno konzoly" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Aktivuj kreatívny režim pre všetkých hráčov" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Aktivuj joysticky" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "Povoľ joystick. Vyžaduje sa reštart hry" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Aktivuj podporu komunikačných kanálov rozšírení (mod channels)." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Aktivuj rozšírenie pre zabezpečenie" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Aktivuje aby mohol byť hráč zranený a zomrieť." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Aktivuje náhodný užívateľský vstup (používa sa len pre testovanie)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Aktivuj jemné nasvietenie pomocou jednoduchej \"ambient occlusion\".\n" +"Vypni pre zrýchlenie, alebo iný vzhľad." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "Povoľ rozdielné prihlásenie/registráciu" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Aktivuj zakázanie pripojenia starých klientov.\n" +"Starší klienti sú kompatibilný v tom zmysle, že nepadnú pri pripájaní\n" +"k novým serverom, ale nemusia podporovať nové funkcie, ktoré očakávaš." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Aktivuj použitie vzdialeného média servera (ak je poskytovaný serverom).\n" +"Vzdialený server poskytuje výrazne rýchlejší spôsob pre sťahovanie médií " +"(napr. textúr)\n" +"pri pripojení na server." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Aktivuj \"vertex buffer objects\".\n" +"Toto by malo viditeľne zvýšiť grafický výkon." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Aktivuj pohupovanie sa a hodnotu pohupovania.\n" +"Napr.: 0 pre žiadne pohupovanie; 1.0 pre normálne; 2.0 pre dvojnásobné." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Aktivuj/vypni IPv6 server.\n" +"Ignorované, ak je nastavená bind_address .\n" +"Vyžaduje povolené enable_ipv6." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Aktivuje Hablov 'Uncharted 2' filmový tone mapping.\n" +"Simuluje farebnú krivku fotografického filmu a ako sa približuje\n" +"vzhľadu obrázku s veľkým dynamickým rozsahom. Stredový kontrast je mierne\n" +"zlepšený, nasvietenie a tiene sú postupne zhustené." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Aktivuje animáciu vecí v inventári." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Aktivuje ukladanie tvárou rotovaných Mesh objektov do medzipamäti." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Aktivuje minimapu." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Aktivuje zvukový systém.\n" +"Ak je zakázaný, tak kompletne zakáže všetky zvuky\n" +"a ovládanie hlasitosti v hre bude nefunkčné.\n" +"Zmena tohto nastavenia si vyžaduje reštart hry." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Povolí kompromis, ktorý zníži zaťaženie CPU, alebo zvýši výkon renderovania\n" +"za cenu drobných vizuálnych chýb, ktoré neovplyvnia hrateľnosť." + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "Profil enginu" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Interval tlače profilových dát enginu" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Metódy bytostí" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Exponent zošpicatenia lietajúcej pevniny. Pozmeňuje fungovanie " +"zošpicatenia.\n" +"Hodnota = 1.0 vytvorí stále, lineárne zošpicatenie.\n" +"Hodnoty > 1.0 vytvoria plynulé zošpicatenie, vhodné pre štandardné oddelené\n" +"lietajúce pevniny.\n" +"Hodnoty < 1.0 (napríklad 0.25) vytvoria viac vymedzený povrch s\n" +"rovnejšími nížinami, vhodné ako pevná základná vrstva lietajúcej pevniny." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "FPS" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS ak je hra nezameraná, alebo pozastavená" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Faktor šumu" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Faktor pohupovania sa pri pádu" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Cesta k záložnému písmu" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Tlačidlo Rýchlosť" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Zrýchlenie v rýchlom režime" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Rýchlosť v rýchlom režime" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Rýchly pohyb" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Rýchly pohyb (cez \"Aux1\" klávesu).\n" +"Toto si na serveri vyžaduje privilégium \"fast\"." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Zorné pole" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Zorné pole v stupňoch." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Súbor v client/serverlist ktorý obsahuje obľúbené servery, ktoré\n" +"sa zobrazujú v záložke Multiplayer." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Hĺbka výplne" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Šum hĺbky výplne" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Filmový tone mapping" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Filtrované textúry môžu zmiešať svoje RGB hodnoty s plne priehľadnými " +"susedmi,\n" +"ktoré sú PNG optimizérmi obvykle zmazané, niekdy môžu viesť k tmavým " +"oblastiam\n" +"alebo svetlým rohom na priehľadnej textúre. Aplikuj tento filter na ich " +"vyčistenie\n" +"pri nahrávaní textúry. Toto je automaticky aktivované, ak je aktivovaný " +"mipmapping." + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "Filtrovanie a vyhladzovanie" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "Prvý zo 4 2D šumov, ktoré spolu definujú rozsah výšok kopcov/hôr." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Prvý z dvoch 3D šumov, ktoré spolu definujú tunely." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Predvolené semienko mapy" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Pevný virtuálny joystick" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Hustota lietajúcej pevniny" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Maximálne Y lietajúcich pevnín" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Minimálne Y lietajúcich pevnín" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Šum lietajúcich krajín" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Exponent kužeľovitosti lietajúcej pevniny" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Vzdialenosť špicatosti lietajúcich krajín" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Úroveň vody lietajúcich pevnín" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Tlačidlo Lietanie" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Lietanie" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Hmla" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Začiatok hmly" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Tlačidlo Prepnutie hmly" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "Písmo" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Štandardne tučné písmo" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Štandardne šikmé písmo" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Tieň písma" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Priehľadnosť tieňa písma" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Veľkosť písma" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Veľkosť písma deliteľná" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Veľkosť písma štandardného fontu, kde 1jednotka = 1 pixel pri 96 DPI" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Veľkosť písma s pevnou šírkou, kde 1jednotka = 1 pixel pri 96 DPI" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Veľkosť písma aktuálneho komunikačného textu a príkazového riadku v bodoch " +"(pt).\n" +"Pri hodnote 0 bude použitá štandardná veľkosť písma." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"Pre pixelové písma, ktoré sa zle škálujú, toto zabezpečí, že použité " +"veľkosti písma\n" +"s týmto fontom budú vždy deliteľné touto hodnotou v pixeloch. Napríklad,\n" +"pixelové písmo vysoké 16 pixelov, by malo mať toto nastavené na 16, aby sa " +"veľkosť\n" +"menila len na hodnoty 16, 32, 48, atď., takže rozšírenie požadujúce veľkosť " +"25 dostane 32." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Formát komunikačných správ hráča. Nasledujúce reťazce sú platné zástupné " +"symboly:\n" +"@name, @message, @timestamp (voliteľné)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Formát obrázkov snímok obrazovky." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Formspec štandardná farba pozadia" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Formspec štandardná nepriehľadnosť pozadia" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Formspec Celo-obrazovková farba pozadia" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Formspec Celo-obrazovková nepriehľadnosť pozadia" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Štandardná farba pozadia (R,G,B) v definícii formulára (Formspec)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" +"Štandardná nepriehľadnosť pozadia (medzi 0 a 255) v definícii formulára " +"(Formspec)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" +"Farba pozadia (R,G,B) v režime celej obrazovky v definícii formulára " +"(Formspec)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" +"Nepriehľadnosť pozadia (0-255) v režime celej obrazovky v definícii " +"formulára (Formspec)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Tlačidlo Vpred" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "Štvrtý zo 4 2D šumov, ktoré spolu definujú rozsah výšok kopcov/hôr." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Typ fraktálu" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Zlomok viditeľnej vzdialenosti od ktorej začne byť vykresľovaná hmla" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Z akej vzdialeností sú klientovi generované bloky, zadané v blokoch mapy (16 " +"kociek)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Z akej vzdialenosti sú bloky posielané klientovi, uvádzané v blokoch mapy " +"(16 kociek)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"Do akej vzdialenosti vedia klienti o objektoch, uvádzané v blokoch mapy (16 " +"kociek).\n" +"\n" +"Nastavenie vyššie ako active_block_range spôsobí, že server bude\n" +"uchovávať objekty až do udanej vzdialenosti v smere v ktorom sa\n" +"hráč pozerá. (Toto môže zabrániť tomu aby mobovia zrazu zmizli z pohľadu)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Celá obrazovka" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Režim celej obrazovky." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Mierka GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Filter mierky GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Filter mierky GUI txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "Užívateľské rozhrania" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "Gamepady" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "Všeobecné" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Globálne odozvy" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Globálne atribúty pre generovanie máp.\n" +"V generátore v6 príznak 'decorations' riadi všetky dekorácie okrem stromov\n" +"a vysokej trávy, vo všetkých ostatných generátoroch tento príznak riadi " +"všetky dekorácie." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Gradient svetelnej krivky na maximálnych úrovniach svetlosti.\n" +"Upravuje kontrast najvyšších úrovni svetlosti." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Gradient svetelnej krivky na minimálnych úrovniach svetlosti.\n" +"Upravuje kontrast najnižších úrovni svetlosti." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "Grafické efekty" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "Grafika a zvuk" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravitácia" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Základná úroveň" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Šum terénu" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP rozšírenia" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "HUD" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "Mierka HUD" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Tlačidlo Prepínanie HUD" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Spracovanie zastaralých Lua API volaní:\n" +"- none: Zastarané funkcie neukladaj do logu\n" +"- log: napodobni log backtrace zastaralého volania (štandardne).\n" +"- error: preruš spracovanie zastaralého volania (odporúčané pre vývojárov " +"rozšírení)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Ako má profiler inštrumentovať sám seba:\n" +"* Inštrumentuj prázdnu funkciu.\n" +"Toto odhaduje režijné náklady, táto inštrumentácia pridáva (+1 funkčné " +"volanie).\n" +"* Instrument the sampler being used to update the statistics." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Šum miešania teplôt" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Teplotný šum" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "Výška okna po spustení. Ignorované v móde plnej obrazovky." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Výškový šum" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Šum výšok" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Strmosť kopcov" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Hranica kopcov" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Šum Kopcovitosť1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Šum Kopcovitosť2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Šum Kopcovitosť3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Šum Kopcovitosť4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Domovská stránka servera, ktorá bude zobrazená v zozname serverov." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Horizontálne zrýchlenie vo vzduchu pri skákaní alebo padaní,\n" +"v kockách za sekundu na druhú." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Horizontálne a vertikálne zrýchlenie v rýchlom režime,\n" +"v kockách za sekundu na druhú." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Horizontálne a vertikálne zrýchlenie na zemi, alebo pri šplhaní,\n" +"v kockách za sekundu na druhú." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Tlačidlo Nasledujúca vec na opasku" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Tlačidlo Predchádzajúcu vec na opasku" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Tlačidlo Opasok pozícia 1" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Tlačidlo Opasok pozícia 10" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Tlačidlo Opasok pozícia 11" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Tlačidlo Opasok pozícia 12" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Tlačidlo Opasok pozícia 13" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Tlačidlo Opasok pozícia 14" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Tlačidlo Opasok pozícia 15" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Tlačidlo Opasok pozícia 16" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Tlačidlo Opasok pozícia 17" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Tlačidlo Opasok pozícia 18" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Tlačidlo Opasok pozícia 19" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Tlačidlo Opasok pozícia 2" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Tlačidlo Opasok pozícia 20" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Tlačidlo Opasok pozícia 21" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Tlačidlo Opasok pozícia 22" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Tlačidlo Opasok pozícia 23" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Tlačidlo Opasok pozícia 24" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Tlačidlo Opasok pozícia 25" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Tlačidlo Opasok pozícia 26" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Tlačidlo Opasok pozícia 27" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Tlačidlo Opasok pozícia 28" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Tlačidlo Opasok pozícia 29" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Tlačidlo Opasok pozícia 3" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Tlačidlo Opasok pozícia 30" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Tlačidlo Opasok pozícia 31" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Tlačidlo Opasok pozícia 32" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Tlačidlo Opasok pozícia 4" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Tlačidlo Opasok pozícia 5" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Tlačidlo Opasok pozícia 6" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Tlačidlo Opasok pozícia 7" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Tlačidlo Opasok pozícia 8" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Tlačidlo Opasok pozícia 9" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Aké hlboké majú byť rieky." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Ako rýchlo sa budú pohybovať vlny tekutín. Vyššia hodnota = rýchlejšie.\n" +"Ak je záporná, tekutina sa bude pohybovať naspäť.\n" +"Požaduje, aby boli aktivované vlniace sa tekutiny." + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Koľko bude server čakať kým uvoľní nepoužívané bloky mapy, v sekundách.\n" +"Vyššia hodnota je plynulejšia, ale použije sa viac RAM." + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" +"Ako veľmi budeš spomalený pri pohybe v tekutine.\n" +"Znížením zvýšiš odpor tekutiny pri pohybe." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Aké široké majú byť rieky." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Šum miešania vlhkostí" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Šum vlhkosti" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Odchýlky vlhkosti pre biómy." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6 server" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Ak by malo byt FPS vyššie, bude obmedzené, aby\n" +"sa bezvýznamne, bez úžitku neplytvalo výkonom CPU." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Ak nie je aktivované, použije sa \"Aux1\" klávesa na rýchle lietanie, v " +"prípade,\n" +"že je povolený režim lietania aj rýchlosti." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Ak je aktivovaný, server bude realizovať occlusion culling blokov mapy " +"založený\n" +"na pozícií oka hráča. Toto môže znížiť počet blokov posielaných klientovi\n" +"o 50-80%. Klient už nebude dostávať takmer neviditeľné bloky,\n" +"takže funkčnosť režim prechádzania stenami je obmedzená." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Ak je aktivovaný spolu s režimom lietania, tak je hráč schopný letieť cez " +"pevné kocky.\n" +"Toto si na serveri vyžaduje privilégium \"noclip\"." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Ak je aktivované, použije sa namiesto klávesy pre \"zakrádanie\" \"Aux1\" " +"klávesu\n" +"pre klesanie a šplhanie dole." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Ak je aktivované, tak registrácia účtu je oddelená od prihlásenia v UI.\n" +"Ak je zakázané, nové konto sa zaregistruje automaticky pri prihlásení." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Ak je aktivované, akcie sa nahrávajú pre účely obnovenia.\n" +"Toto nastavenie sa prečíta len pri štarte servera." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" +"Ak je aktivované, zruší ochranu pred podvodmi (cheatmi) v multiplayeri." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Ak je aktivované, chybné dáta nespôsobia vypnutie servera.\n" +"Povoľ len ak vieš čo robíš." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Ak je aktivované, tak je smer pohybu pri lietaní, alebo plávaní daný sklonom " +"hráča." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" +"Ak je aktivované, nový hráči sa nemôžu prihlásiť bez zadaného hesla, ani si " +"nemôžu heslo vymazať." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Ak je aktivované, môžeš dať bloky na miesto kde stojíš (v úrovni päta + " +"oči).\n" +"Je to užitočné ak pracuješ s kockami v stiesnených priestoroch." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Ak sú CSM obmedzenia pre dohľad kocky aktívne, volania get_node sú\n" +"obmedzené touto vzdialenosťou od hráča ku kocke." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Ak vykonanie príkazu trvá dlhšie ako zadaný čas v sekundách,\n" +"tak pridá informáciu o čase do komunikačného správy príkazu" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Ak veľkosť súboru debug.txt prekročí zadanú veľkosť v megabytoch,\n" +"keď bude otvorený, súbor bude presunutý do debug.txt.1,\n" +"ak existuje starší debug.txt.1, tak tento bude zmazaný.\n" +"debug.txt bude presunutý, len ak je toto nastavenie kladné." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "Ak je povolený, hráči vždy ožijú (obnovia sa) na zadanej pozícií." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ignoruj chyby vo svete" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "Priehľadnosť pozadia konzoly v hre (nepriehľadnosť, medzi 0 a 255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Pozadie (R,G,B) komunikačnej konzoly v hre." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "Výška komunikačnej konzoly v hre, medzi 0.1 (10%) a 1.0 (100%)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Tlačidlo Zvýš hlasitosť" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Počiatočná vertikálna rýchlosť pri skákaní, v kockách za sekundu." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Inštrumentuj vstavané (builtin).\n" +"Toto je obvykle potrebné len pre core/builtin prispievateľov" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "Inštrumentuj komunikačné príkazy pri registrácií." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Inštrumentuj globálne odozvy volaní funkcií pri registrácií.\n" +"(čokoľvek je poslané minetest.register_*() funkcií)" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "Inštrumentuj funkcie ABM pri registrácií." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "Inštrumentuj funkcie nahrávania modifikátorov blokov pri registrácií." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Inštrumentuj metódy bytostí pri registrácií." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "Interval ukladania dôležitých zmien vo svete, uvádzaný v sekundách." + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Interval v akom sa posiela denný čas klientom, v sekundách." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Animácia vecí v inventári" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Tlačidlo Inventár" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Obrátiť smer myši" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Obráti vertikálny pohyb myši." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Cesta k šikmému písmu" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Cesta k šikmému písmu s pevnou šírkou" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Životnosť odložených vecí" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Iterácie" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Iterácie rekurzívnej funkcie.\n" +"Zvýšenie zvýši úroveň jemnosti detailov, ale tiež\n" +"zvýši zaťaženie pri spracovaní.\n" +"Pri iteráciach = 20 má tento generátor podobné zaťaženie ako generátor V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ID joysticku" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Interval opakovania tlačidla joysticku" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "Mŕtva zóna joysticku" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Citlivosť otáčania pohľadu joystickom" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Typ joysticku" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Len pre sadu Julia.\n" +"W komponent hyperkomplexnej konštanty.\n" +"Zmení tvar fraktálu.\n" +"Nemá vplyv na 3D fraktály.\n" +"Rozsah zhruba -2 až 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Len pre sadu Julia.\n" +"X komponent hyperkomplexnej konštanty.\n" +"Zmení tvar fraktálu.\n" +"Rozsah zhruba -2 až 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Len pre sadu Julia.\n" +"Y komponent hyperkomplexnej konštanty.\n" +"Zmení tvar fraktálu.\n" +"Rozsah zhruba -2 až 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Len pre sadu Julia.\n" +"Z komponent hyperkomplexnej konštanty.\n" +"Zmení tvar fraktálu.\n" +"Rozsah zhruba -2 až 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Tlačidlo Skok" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Rýchlosť skákania" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre zníženie dohľadu.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre zníženie hlasitosti.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre kopanie.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre zahodenie aktuálne vybranej veci.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre zvýšenie dohľadu.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre zvýšenie hlasitosti.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre skákanie.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre rýchly pohyb hráča v rýchlom móde.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre pohyb hráča vzad.\n" +"Zároveň vypne automatický pohyb hráča dopredu, ak je aktívny.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre pohyb hráča vpred.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre pohyb hráča vľavo.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre pohyb hráča vpravo.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre vypnutie hlasitosti v hre.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre otvorenie komunikačného okna pre zadávanie príkazov.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre otvorenie komunikačného okna pre zadávanie lokálnych príkazov.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre otvorenie komunikačného okna.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre otvorenie inventára.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre pokladanie.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber jedenástej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber dvanástej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber trinástej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber štrnástej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber pätnástej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber šestnástej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber sedemnástej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber osemnástej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber devätnástej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 20. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 21. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 22. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 23. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 24. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 25. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 26. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 27. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 28. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 29. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 30. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 31. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber 32. pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber ôsmej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber piatej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber prvej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber štvrtej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber ďalšej veci na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber deviatej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber predchádzajúcej veci na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber druhej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber siedmej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber šiestej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber desiatej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre výber tretej pozície na opasku.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre utajený pohyb (zakrádanie) hráča.\n" +"Tiež sa používa pre zliezanie a ponáranie vo vode ak aux1_descends je " +"vypnutý.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepínanie medzi pohľadom z prvej a tretej osoby.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre snímanie obrazovky.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie režimu automatického pohybu vpred.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie filmového režimu.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie zobrazenia minimapy.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie režimu rýchlosť.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie lietania.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie režimu prechádzania stenami.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie režimu pohyb podľa sklonu.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie aktualizácie pohľadu. Používa sa len pre vývoj.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie zobrazenia komunikácie.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie zobrazenia ladiacich informácií.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie zobrazenia hmly.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie zobrazenia HUD (Head-Up Display - výhľadový " +"displej).\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie zobrazenia veľkej konzoly na komunikáciu.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie zobrazenia profileru. Používa sa pri vývoji.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre prepnutie neobmedzeného dohľadu.\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Tlačidlo pre použitie priblíženia pokiaľ je to možné .\n" +"Viď. http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "Klávesnica a myš" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "Vylúč hráča, ktorý pošle viac ako X správ za 10 sekúnd." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Strmosť jazier" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Hranica jazier" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Jazyk" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Hĺbka veľkých jaskýň" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Minimálny počet veľkých jaskýň" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Minimálny počet veľkých jaskýň" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Pomer zaplavených častí veľkých jaskýň" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Tlačidlo Veľká komunikačná konzola" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Štýl listov" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Štýly listov:\n" +"- Ozdobné: všetky plochy sú viditeľné\n" +"- Jednoduché: sú použité len vonkajšie plochy, ak sú použité definované " +"\"special_tiles\"\n" +"- Nepriehľadné: vypne priehliadnosť" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Tlačidlo Vľavo" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Dĺžka kroku servera a interval v ktorom sú objekty štandardne aktualizované\n" +"cez sieť, uvedené v sekundách." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Dĺžka vĺn tekutín.\n" +"Požaduje, aby boli aktivované vlniace sa tekutiny." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" +"Časový interval medzi jednotlivými vykonávacími cyklami ABM (Active Block " +"Modifier), v sekundách." + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" +"Časový interval medzi jednotlivými vykonávacími cyklami časovača kociek " +"(NodeTimer), v sekundách." + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" +"Časový interval medzi jednotlivými riadiacimi cyklami aktívnych blokov, v " +"sekundách." + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Úroveň ladiacich informácií, ktoré budú zapísané do debug.txt:\n" +"- <nič> (bez logovania)\n" +"- none - žiadna (správy bez úrovne)\n" +"- error - chyby\n" +"- warning - varovania\n" +"- akcie\n" +"- info - informácie\n" +"- verbose - všetko\n" +"- trace - krokovanie" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Zosilnenie svetelnej krivky" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Stred zosilnenia svetelnej krivky" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Rozptyl zosilnenia svetelnej krivky" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Svetelná gamma krivka" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Horný gradient svetelnej krivky" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Spodný gradient svetelnej krivky" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "Osvetlenie" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Limit pre generovanie mapy, v kockách, vo všetkých 6 smeroch (0, 0, 0).\n" +"Len časti mapy (mapchunks) kompletne v rámci limitu generátora máp sú " +"generované.\n" +"Hodnota sa ukladá pre každý svet." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Maximálny počet paralelných HTTP požiadavok. Ovplyvňuje:\n" +"- Získavanie médií ak server používa nastavenie remote_media.\n" +"- Sťahovanie zoznamu serverov a zverejňovanie servera.\n" +"- Sťahovania vykonávané z hlavného menu (napr. správca rozšírení).\n" +"Má efekt len ak je skompilovaný s cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Tekutosť kvapalín" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Zjemnenie tekutosti kvapalín" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Max sprac. tekutín" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Čas do uvolnenia fronty tekutín" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Ponáranie v tekutinách" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Aktualizačný interval tekutín v sekundách." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Aktualizačný interval tekutín" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Nahraj profiler hry" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Nahraj profiler hry pre získanie profilových dát.\n" +"Poskytne príkaz /profiler pre prístup k skompilovanému profilu.\n" +"Užitočné pre vývojárov rozšírení a správcov serverov." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Nahrávam modifikátory blokov" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Dolný Y limit kobiek." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Spodný Y limit lietajúcich pevnín." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Skript hlavného menu" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Prispôsob farbu hmly a oblohy dennej dobe (svitanie/súmrak) a uhlu pohľadu." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Všetky tekutiny budú nepriehľadné" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Úroveň kompresie mapy pre diskové úložisko" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Úroveň kompresie mapy pre sieťový prenos" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Adresár máp" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Špecifické príznaky pre generátor máp Karpaty." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Špecifické atribúty pre plochý generátor mapy.\n" +"Príležitostne môžu byť na plochý svet pridané jazerá a kopce." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Špecifické príznaky generátora máp Fraktál.\n" +"'terrain' aktivuje generovanie nie-fraktálneho terénu:\n" +"oceán, ostrovy and podzemie." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Špecifické príznaky pre generovanie mapy generátora Údolia.\n" +"'altitude_chill': Znižuje teplotu s nadmorskou výškou.\n" +"'humid_rivers': Zvyšuje vlhkosť okolo riek.\n" +"'vary_river_depth': ak je aktívne, nízka vlhkosť a vysoké teploty\n" +"spôsobia, že hladina rieky poklesne, niekdy aj vyschne.\n" +"'altitude_dry': Znižuje vlhkosť s nadmorskou výškou." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Príznaky pre generovanie špecifické pre generátor V5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Špecifické atribúty pre generátor V6.\n" +"Príznak 'snowbiomes' aktivuje nový systém 5 biómov.\n" +"Ak je aktívny prźnak 'snowbiomes', džungle sú automaticky povolené a\n" +"príznak 'jungles' je ignorovaný." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Špecifické príznaky pre generátor máp V7.\n" +"'ridges': Rieky.\n" +"'floatlands': Lietajúce masy pevnín v atmosfére.\n" +"'caverns': Gigantické jaskyne hlboko v podzemí." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Limit generovania mapy" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Interval ukladania mapy" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "Aktualizačný čas mapy tieňov" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Limit blokov mapy" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Oneskorenie generovania Mesh blokov" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Medzipamäť Mapblock Mesh generátora blokov v MB" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Čas odstránenia bloku mapy" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Generátor mapy Karpaty" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Špecifické príznaky generátora máp Karpaty" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Generátor mapy plochý" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Špecifické príznaky plochého generátora mapy" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Generátor mapy Fraktál" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Špecifické príznaky generátora máp Fraktál" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Generátor mapy V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Špecifické príznaky pre generátor mapy V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Generátor mapy V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Špecifické príznaky generátora mapy V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Generátor mapy V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Špecifické príznaky generátora V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Generátor mapy Údolia" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Špecifické príznaky pre generátor Údolia" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Ladenie generátora máp" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Meno generátora mapy" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Maximálna vzdialenosť generovania blokov" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Max vzdialenosť posielania objektov" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Maximálny počet tekutín spracovaný v jednom kroku." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Max. extra blokov clearobjects" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Max. paketov za opakovanie" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Maximálne FPS" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" +"Maximálne FPS, ak je hra nie je v aktuálnom okne, alebo je pozastavená." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Maximálna vzdialenosť pre renderovanie tieňov." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Maximum vynútene nahraných blokov" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Maximálna šírka opaska" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" +"Maximálny limit náhodného počtu veľkých jaskýň v danej časti mapy (mapchunk)." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" +"Maximálny limit náhodného počtu malých jaskýň v danej časti mapy (mapchunk)." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Maximálny odpor tekutín. Riadi spomalenie ak sa tekutina\n" +"vlieva vysokou rýchlosťou." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"Maximálny počet súčasne posielaných blokov na klienta.\n" +"Maximálny počet sa prepočítava dynamicky:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "Maximálny limit kociek, ktoré môžu byť vo fronte pre nahrávanie." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Maximálny limit kociek vo fronte, ktoré budú generované.\n" +"Tento limit je vynútený pre každého hráča." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Maximálny limit kociek vo fronte, ktoré budú nahrané zo súboru.\n" +"Tento limit je vynútený pre každého hráča." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Maximálny počet súčasných sťahovaní. Sťahovania presahujúce tento limit budú " +"čakať v rade.\n" +"Mal by byť nižší ako curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Maximálny počet vynútene nahraných blokov mapy." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Maximálny počet blokov u klienta, ktoré ostávajú v pamäti.\n" +"Nastav -1 pre neobmedzené množstvo." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Maximálny počet paketov poslaný pri jednom kroku posielania,\n" +"ak máš pomalé pripojenie skús ho znížiť, ale\n" +"neznižuj ho pod dvojnásobok cieľového počtu klientov." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Maximálny počet hráčov, ktorí sa môžu súčasne pripojiť." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Maximálny počet nedávnych správ v komunikácií, ktoré budú zobrazované" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Maximálny počet staticky uložených objektov v bloku." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Max. počet objektov na blok" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Maximálny pomer aktuálneho okna, ktorý sa použije pre opasok.\n" +"Užitočné, ak treba zobraziť niečo vpravo, alebo vľavo od opaska." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Maximum súčasných odoslaní bloku na klienta" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Maximálna veľkosť výstupnej komunikačnej fronty" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Maximálna veľkosť výstupnej komunikačnej fronty.\n" +"0 pre zakázanie fronty a -1 pre neobmedzenú frontu." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Maximálny čas v ms, ktorý môže zabrať sťahovanie súboru (napr. sťahovanie " +"rozšírenia)." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Maximálny čas v ms, ktorý môže zabrať interaktívna požiadavka (napr. " +"sťahovanie zoznamu serverov)." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Maximálny počet hráčov" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Medzipamäť Mesh" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Správa dňa" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Správa dňa sa zobrazí hráčom pri pripájaní." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Metóda použitá pre zvýraznenie vybraných objektov." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Minimálna úroveň záznamov, ktoré budú vypísané do komunikačného okna." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Tlačidlo Minimapa" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Minimapa výška skenovania" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" +"Minimálny limit náhodného počtu veľkých jaskýň v danej časti mapy (mapchunk)." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" +"Minimálny limit náhodného počtu malých jaskýň v danej časti mapy (mapchunk)." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Minimálna veľkosť textúry" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mip-mapovanie" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "Rôzne" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "Profiler rozšírení" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "Bezpečnosť rozšírení" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Komunikačné kanály rozšírení" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Upraví veľkosť elementov v užívateľskom rozhraní." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Cesta k písmu s pevnou šírkou" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Veľkosť písmo s pevnou šírkou" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "Veľkosť písma s pevnou šírkou deliteľná" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Šum pre výšku hôr" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Šum hôr" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Odchýlka šumu hôr" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Základná úroveň hôr" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Citlivosť myši" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Multiplikátor citlivosti myši." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Šum bahna" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Násobiteľ pre pohupovanie sa pri pádu.\n" +"Napr.: 0 pre žiadne pohupovanie; 1.0 pre normálne; 2.0 pre dvojnásobné." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Tlačidlo Ticho" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Stíš hlasitosť" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Meno generátora mapy, ktorý sa použije pri vytváraní nového sveta.\n" +"Vytvorenie sveta cez hlavné menu toto prepíše.\n" +"Aktuálne nestabilné generátory:\n" +"- Voliteľné lietajúce pevniny (floatlands) vo v7 (štandardne vypnuté)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Meno hráča.\n" +"Ak je spustený server, klienti s týmto menom sú administrátori.\n" +"Pri štarte z hlavného menu, toto bude prepísané." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Zobrazované meno servera, keď sa hráč na server pripojí a v zozname serverov." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Blízkosť roviny" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Sieťový port (UDP).\n" +"Táto hodnota bude prepísaná pri spustení z hlavného menu." + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "Sieťové nastavenia" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Noví hráči musia zadať toto heslo." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Prechádzanie stenami" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Tlačidlo Prechádzanie stenami" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "Nasvietenie kocky a bytosti" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Zvýrazňovanie kociek" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Interval časovača kociek" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Šumy" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Počet použitých vlákien" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Počet použitých vlákien.\n" +"Hodnota 0:\n" +"- Automatický určenie. Počet použitých vlákien bude\n" +"- 'počet procesorov - 2', s dolným limitom 1.\n" +"Akákoľvek iná hodnota:\n" +"- Definuje počet vlákien, s dolným limitom 1.\n" +"VAROVANIE: Zvýšenie počtu vlákien zvýši rýchlosť generátora máp,\n" +"ale môže to uškodiť hernému výkonu interferenciou s inými\n" +"procesmi, obzvlášť pri hre jedného hráča a/alebo ak beží Lua kód\n" +"v 'on_generated'. Pre mnohých hráčov môže byť optimálne nastavenie '1'." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Počet extra blokov, ktoré môžu byť naraz nahrané pomocou /clearobjects.\n" +"Toto je kompromis medzi vyťažením SQLite transakciami\n" +"a spotrebou pamäti (4096=100MB, ako približné pravidlo)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Nepriehľadné tekutiny" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "Nepriehľadnosť tieňa za štandardným písmom, medzi 0 a 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Otvorí menu pozastavenia, ak aktuálne okno hry nie je vybrané.\n" +"Nepozastaví sa ak je otvorený formspec." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "Voliteľná zmena farby webového odkazu v komunikačnej konzole." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Cesta k záložnému písmu. Musí to byť TrueType font.\n" +"Toto písmo bude použité pre určité jazyky, alebo ak nie je štandardné písmo " +"k dispozícií." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Cesta, kam sa budú ukladať snímky obrazovky. Môže to byť ako absolútna, tak " +"relatívna cesta.\n" +"Adresár bude vytvorený ak neexistuje." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Cesta do adresára so shadermi. Ak nie je definovaná, použije sa predvolená " +"lokácia." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "Cesta do adresára s textúrami. Všetky textúry sú najprv hľadané tu." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Cesta k štandardnému písmu. Musí to byť TrueType font.\n" +"Bude použité záložné písmo, ak nebude možné písmo nahrať." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Cesta k písmu s pevnou šírkou. Musí to byť TrueType font.\n" +"Toto písmo je použité pre napr. konzolu a okno profilera." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Pozastav hru, pri strate zamerania okna" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "Limit kociek vo fronte na každého hráča nahrávaných z disku" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Limit kociek vo fronte na každého hráča pre generovanie" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fyzika" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Tlačidlo Pohyb podľa sklonu" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Režim pohybu podľa sklonu" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Tlačidlo na pokladanie" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Interval opakovania pokladania" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Hráč je schopný lietať bez ovplyvnenia gravitáciou.\n" +"Toto si na serveri vyžaduje privilégium \"fly\"." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Vzdialenosť zobrazenia hráča" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Hráč proti hráčovi (PvP)" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Poisson filtrovanie" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Port pre pripojenie sa (UDP).\n" +"Políčko pre nastavenie Portu v hlavnom menu prepíše toto nastavenie." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Zabráni opakovanému kopaniu a ukladaniu blokov pri držaní tlačítka myši.\n" +"Aktivuj, ak príliš často omylom niečo vykopeš, alebo položíš blok." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Zabráni rozšíreniam aby robili nebezpečné veci ako spúšťanie systémových " +"príkazov." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Vytlačí profilové dáta enginu v pravidelných intervaloch (v sekundách).\n" +"0 = vypnuté. Užitočné pre vývojárov." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Oprávnenia, ktoré môže udeliť hráč s basic_privs" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Profilátor" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Tlačidlo Prepínanie profileru" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Odpočúvacia adresa Promethea" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Odpočúvacia adresa Promethea.\n" +"Ak je Minetest skompilovaný s nastaveným ENABLE_PROMETHEUS,\n" +"aktivuj odpočúvanie metriky pre Prometheus na zadanej adrese.\n" +"Metrika môže byť získaná na http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Pomer častí veľkých jaskýň, ktoré obsahujú tekutinu." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Polomer oblasti mrakov zadaný v počtoch 64 kociek na štvorcový mrak.\n" +"Hodnoty vyššie než 26 budú produkovať ostré hranice na rohoch oblasti mrakov." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Zvýši terén aby vznikli údolia okolo riek." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Náhodný vstup" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Tlačidlo Dohľad" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Posledné správy v komunikácií" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Štandardná cesta k písmam" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Vzdialené média" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Vzdialený port" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Odstráň farby z prichádzajúcich komunikačných správ\n" +"Použi pre zabránenie používaniu farieb hráčmi v ich správach" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Nahradí štandardné hlavné menu vlastným." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Cesta k záznamom" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Obmedzi prístup k určitým klientským funkciám na serveroch.\n" +"Skombinuj bajtové príznaky dole pre obmedzenie jednotlivých\n" +"fukncii u klienta, alebo nastav 0 pre funkcie bez obmedzení:\n" +"LOAD_CLIENT_MODS: 1 (zakáže nahrávanie rozšírení u klienta)\n" +"CHAT_MESSAGES: 2 (zakáže send_chat_message volania u klienta)\n" +"READ_ITEMDEFS: 4 (zakáže get_item_def volania u klienta)\n" +"READ_NODEDEFS: 8 (zakáže get_node_def volania u klienta)\n" +"LOOKUP_NODES_LIMIT: 16 (obmedzí get_node volania u klienta na\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (zakáže get_player_names volania u klienta)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Rozptyl šumu hrebeňa hôr" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Šum hrebeňa" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Šum podmorského hrebeňa" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Veľkosť šumu hrebeňa hôr" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Tlačidlo Vpravo" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Hĺbka riečneho kanála" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Šírka kanála rieky" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Hĺbka rieky" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Šum riek" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Veľkosť riek" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Šírka údolia rieky" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Nahrávanie pre obnovenie" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Veľkosť šumu vlnitosti kopcov" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Rozptyl šumu vlnitosti kopcov" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Okrúhla minimapa" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Bezpečné kopanie a ukladanie" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Pieskové pláže sa objavia keď np_beach presiahne túto hodnotu." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Ulož mapu získanú klientom na disk." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Automaticky ulož veľkosť okna po úprave." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Ukladanie mapy získanej zo servera" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Zmeň mierku užívateľského rozhrania (GUI) podľa zadanej hodnoty.\n" +"Pre zmenu mierky GUI použi antialias filter podľa-najbližšieho-suseda.\n" +"Toto zjemní niektoré hrubé hrany a zmieša pixely pri zmenšení,\n" +"za cenu rozmazania niektorých okrajových pixelov ak sa mierka\n" +"obrázkov mení podľa neceločíselných hodnôt." + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "Zobrazenie" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Výška obrazovky" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Šírka obrazovky" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Adresár pre snímky obrazovky" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Formát snímok obrazovky" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Kvalita snímok obrazovky" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Kvalita snímok obrazovky. Používa sa len pre JPEG formát.\n" +"1 znamená najhoršiu kvalitu; 100 znamená najlepšiu kvalitu.\n" +"Použi 0 pre štandardnú kvalitu." + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "Fotky obrazovky" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Šum morského dna" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "Druhý zo 4 2D šumov, ktoré spolu definujú rozsah výšok kopcov/hôr." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Druhý z dvoch 3D šumov, ktoré spolu definujú tunely." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Viď. https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Farba obrysu bloku (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Farba obrysu bloku" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Šírka obrysu bloku" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Zvoľ si jeden z 18 typov fraktálu.\n" +"1 = 4D \"Roundy\" sada Mandelbrot.\n" +"2 = 4D \"Roundy\" sada Julia.\n" +"3 = 4D \"Squarry\" sada Mandelbrot.\n" +"4 = 4D \"Squarry\" sada Julia.\n" +"5 = 4D \"Mandy Cousin\" sada Mandelbrot.\n" +"6 = 4D \"Mandy Cousin\" sada Julia.\n" +"7 = 4D \"Variation\" sada Mandelbrot.\n" +"8 = 4D \"Variation\" sada Julia.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" sada Mandelbrot.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" sada Julia.\n" +"11 = 3D \"Christmas Tree\" sada Mandelbrot.\n" +"12 = 3D \"Christmas Tree\" sada Julia.\n" +"13 = 3D \"Mandelbulb\" sada Mandelbrot.\n" +"14 = 3D \"Mandelbulb\" sada Julia.\n" +"15 = 3D \"Cosine Mandelbulb\" sada Mandelbrot.\n" +"16 = 3D \"Cosine Mandelbulb\" sada Julia.\n" +"17 = 4D \"Mandelbulb\" sada Mandelbrot.\n" +"18 = 4D \"Mandelbulb\" sada Julia." + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "Server" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "Hra na serveri" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "Bezpečnosť servera" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL servera" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Adresa servera" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Popis servera" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Meno servera" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Port servera" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Occlusion culling na strane servera" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "Výkon servera/prostredia" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL zoznamu serverov" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "Zoznam serverov a hláška dňa" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Súbor so zoznamom serverov" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Nastav jazyk. Ponechaj prázdne pre systémové nastavenie.\n" +"Po zmene je požadovaný reštart." + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "Nastav maximálny počet znakov komunikačnej správy posielanej klientmi." + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Nastav gammu tieňov.\n" +"Vylaď intenzitu dynamických tieňov v hre.\n" +"Nižšia hodnota znamená svetlejšie tiene, vyššia hodnota znamená tmavšie " +"tiene." + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Nastav dosah mäkkých tieňov.\n" +"Nižšia hodnota znamená ostrejšie a vyššia jemnejšie tiene.\n" +"Minimálna hodnota: 1.0; Maximálna hodnota: 15.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Nastav sklon orbity slnka/mesiaca v stupňoch\n" +"Hodnota 0 znamená bez vertikálneho sklonu orbity.\n" +"Minimálna hodnota: 0.0; max. hodnota: 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Nastav true pre povolenie mapovania tieňov.\n" +"Požaduje aby boli aktivované shadery." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Nastav true pre povolenie vlniacich sa listov.\n" +"Požaduje aby boli aktivované shadery." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Nastav true pre aktivovanie vlniacich sa tekutín (ako napr. voda).\n" +"Požaduje aby boli aktivované shadery." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Nastav true pre aktivovanie vlniacich sa rastlín.\n" +"Požaduje aby boli aktivované shadery." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Nastav kvalitu textúr tieňov na 32 bitov.\n" +"Ak je false, použijú sa 16 bitové textúry.\n" +"Toto môže spôsobiť v tieňoch viac artefaktov." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Cesta k shaderom" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Shadery umožňujú pokročilé vizuálne efekty a na niektorých grafických " +"kartách\n" +"môžu zvýšiť výkon.\n" +"Toto funguje len s OpenGL." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Kvalita filtra pre tiene" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" +"Maximálna vzdialenosť v kockách, pre mapu tieňov na renderovanie tieňov" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "32 bitové textúry pre mapovanie tieňov" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Veľkosť textúry pre mapovanie tieňov" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Posun tieňa (v pixeloch) štandardného písma. Ak je 0, tak tieň nebude " +"vykreslený." + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "Úroveň gamma tieňov" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Tvar minimapy. Aktivované = okrúhla, vypnuté = štvorcová." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Zobraz ladiace informácie" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Zobraz obrys bytosti" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Zobraz obrysy bytosti\n" +"Po zmene je požadovaný reštart." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "Štandardne zobraz menovku pozadia" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Správa pri vypínaní" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Veľkosť časti mapy generovanej generátorom mapy, zadaný v blokoch mapy (16 " +"kociek).\n" +"VAROVANIE!: Neexistuje žiadna výhoda, a je tu pár rizík,\n" +"pri zvýšení tejto hodnoty nad 5.\n" +"Zníženie tejto hodnoty zvýši hustotu jaskýň a kobiek.\n" +"Zmena tejto hodnoty slúži k špeciálnym účelom, odporúča sa ponechať\n" +"to nezmenené." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Veľkosť medzipamäte blokov v Mesh generátori.\n" +"Zvýšenie zvýši využitie medzipamäte %, zníži sa množstvo dát kopírovaných\n" +"z hlavnej vetvy a tým sa zníži chvenie." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Sklon orbity na oblohe" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Plátok w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Sklon a výplň spolupracujú aby upravili výšky." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Maximálny počet malých jaskýň" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Minimálny počet malých jaskýň" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "Drobné odchýlky vlhkosti pre zjemnenie prechodu na hraniciach biómov." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "Drobné odchýlky teplôt pre zjemnenie prechodu na hraniciach biómov." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Jemné osvetlenie" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Zjemňuje pohyb kamery pri pohľade po okolí. Tiež sa nazýva zjemnenie " +"pohľady, alebo pohybu myši.\n" +"Užitočné pri nahrávaní videí." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "Zjemní rotáciu kamery vo filmovom režime. 0 je pre vypnuté." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Zjemní rotáciu kamery. 0 je pre vypnuté." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Tlačidlo zakrádania sa" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Rýchlosť zakrádania" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Rýchlosť zakrádania sa, v kockách za sekundu." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Dosah mäkkých tieňov" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Zvuk" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Špecifikuje URL s ktorého klient stiahne média namiesto použitia UDP.\n" +"$filename by mal byt dostupný z $remote_media$filename cez cURL\n" +"(samozrejme, remote_media by mal končiť lomítkom).\n" +"Súbory, ktoré nie sú dostupné budú získané štandardným spôsobom." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Definuje štandardnú veľkosť kôpky kociek, vecí a nástrojov.\n" +"Ber v úvahu, že rozšírenia, alebo hry môžu explicitne nastaviť veľkosť pre " +"určité (alebo všetky) typy." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"Rozptýľ celkovú aktualizáciu mapy tieňov cez zadané množstvo snímok.\n" +"Vyššie hodnoty môžu spôsobiť trhanie tieňov, nižšie hodnoty\n" +"spotrebujú viac zdrojov.\n" +"Minimálna hodnota: 1; maximálna hodnota: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Rozptyl zosilnenia svetelnej krivky.\n" +"Určuje šírku rozsahu , ktorý bude zosilnený.\n" +"Štandardné gausovo rozdelenie odchýlky svetelnej krivky." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Pevný bod obnovy" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Šum zrázov" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Veľkosť šumu horských stepí" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Rozptyl šumu horských stepí" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "Stupeň paralaxy 3D režimu." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Sila zosilnenia svetelnej krivky.\n" +"Tri 'zosilňujúce' parametre definujú ktorý rozsah\n" +"svetelnej krivky je zosilnený v jasu." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Prísna kontrola protokolu" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Odstráň farby" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Povrchová úroveň voliteľnej vody umiestnená na pevnej vrstve lietajúcej " +"krajiny.\n" +"Štandardne je voda deaktivovaná a bude umiestnená len ak je táto voľba " +"nastavená\n" +"nad 'mgv7_floatland_ymax' - 'mgv7_floatland_taper'\n" +"(štart horného zašpicaťovania).\n" +"***VAROVANIE, POTENCIÁLNE RIZIKO PRE VÝKON SVETOV A SERVEROV***:\n" +"Pri aktivovaní vody na lietajúcich pevninách musí byť nastavený\n" +"a otestovaný pevný povrch nastavením 'mgv7_floatland_density' na 2.0 ( alebo " +"inú\n" +"požadovanú hodnotu v závislosti na 'mgv7_np_floatland'), aby sa zabránilo\n" +"pre server náročnému extrémnemu toku vody a rozsiahlym záplavám\n" +"na svet pod nimi." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "Synchrónne SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Odchýlky teplôt pre biómy." + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "Dočasné nastavenia" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Alternatívny šum terénu" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Základný šum terénu" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Výška terénu" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Horný šum terénu" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Šum terénu" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Prah šumu terénu pre kopce.\n" +"Riadi pomer plochy sveta pokrytého kopcami.\n" +"Uprav smerom k 0.0 pre väčší pomer." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Prah šumu terénu pre jazerá.\n" +"Riadi pomer plochy sveta pokrytého jazerami.\n" +"Uprav smerom k 0.0 pre väčší pomer." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Stálosť šumu terénu" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Cesta k textúram" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Veľkosť textúry pre renderovanie mapy tieňov.\n" +"Toto musí byť mocnina dvoch.\n" +"Väčšie čísla vytvoria lepšie tiene, ale sú aj náročnejšie." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Textúry na kocke môžu byť zarovnané buď podľa kocky, alebo sveta.\n" +"Kým prvý režim poslúži lepšie veciam ako sú stroje, nábytok, atď.,\n" +"tak s druhým režimom zapadnú schody a mikrobloky lepšie do svojho okolia.\n" +"Keďže je táto možnosť nová, nemusí byť použitá na starších serveroch,\n" +"toto nastavenie povolí jeho vynútenie pre určité typy kociek. Je potrebné\n" +"si uvedomiť, že táto funkcia je EXPERIMENTÁLNA a nemusí fungovať korektne." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "Webová adresa (URL) k úložisku doplnkov" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "Mŕtva zóna joysticku" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Štandardný formát v ktorom sa ukladajú profily,\n" +"pri volaní `/profiler save [format]` bez udania formátu." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "Hĺbka zeminy, alebo inej výplne kocky." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"Relatívna cesta k súboru vzhľadom na svet z ktorého budú profily uložené." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "Identifikátor joysticku na použitie" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"Dĺžka v pixloch, ktorú potrebuje dotyková obrazovka pre začiatok interakcie." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"Maximálna výška povrchu vlniacich sa tekutín.\n" +"4.0 = Výška vlny sú dve kocky.\n" +"0.0 = Vlna sa vôbec nehýbe.\n" +"Štandardná hodnota je 1.0 (1/2 kocky).\n" +"Požaduje, aby boli aktivované vlniace sa tekutiny." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "Sieťové rozhranie, na ktorom server načúva." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Oprávnenia, ktoré automaticky dostane nový hráč.\n" +"Pozri si /privs v hre pre kompletný zoznam pre daný server a konfigurácie " +"rozšírení." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"Polomer objemu blokov okolo každého hráča, ktoré sú predmetom\n" +"záležitostí okolo aktívnych objektov, uvádzané v blokoch mapy (16 kociek).\n" +"V objektoch aktívnych blokov sú nahrávané a spúšťané ABM.\n" +"Toto je tiež minimálna vzdialenosť v ktorej sú aktívne objekty (mobovia) " +"zachovávaný.\n" +"Malo by to byť konfigurované spolu s active_object_send_range_blocks." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"Renderovací back-end.\n" +"Po zmene je vyžadovaný reštart.\n" +"Poznámka: Na Androide, ak si nie si istý, ponechaj OGLES1! Aplikácia by " +"nemusela naštartovať.\n" +"Na iných platformách, sa odporúča OpenGL.\n" +"Shadery sú podporované v OpenGL (len pre desktop) a v OGLES2 (experimentálne)" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"Citlivosť osí joysticku pre pohyb\n" +"otáčania pohľadu v hre." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"Úroveň tieňovania ambient-occlusion kocky (tmavosť).\n" +"Nižšia hodnota je tmavšie, vyššia svetlejšie.\n" +"Platý rozsah hodnôt je od 0.25 po 0.4 vrátane.\n" +"Ak je hodnota mimo rozsah, bude nastavená na najbližšiu platnú hodnotu." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Čas (c sekundách) kedy fronta tekutín môže narastať nad kapacitu\n" +"spracovania než bude urobený pokus o jej zníženie zrušením starých\n" +"vecí z fronty. Hodnota 0 vypne túto funkciu." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"Vyhradená doba pre ABM na vykonanie v každom kroku\n" +"(ako zlomok ABM imtervalu)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Čas v sekundách medzi opakovanými udalosťami\n" +"pri stlačenej kombinácií tlačidiel na joysticku." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Čas v sekundách pre opakované položenie kocky\n" +"ak je držané tlačítko pokladania." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Typ joysticku" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"Vertikálna vzdialenosť kedy poklesne teplota o 20 ak je 'altitude_chill'\n" +"aktívne. Tiež je to vertikálna vzdialenosť kedy poklesne vlhkosť o 10,\n" +"ak je 'altitude_dry' aktívne." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "Tretí zo 4 2D šumov, ktoré spolu definujú rozsah výšok kopcov/hôr." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Čas existencie odložený (odhodených) vecí v sekundách.\n" +"Nastavené na -1 vypne túto vlastnosť." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "Čas pri spustení nového sveta, v milihodinách (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Interval posielania času" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Rýchlosť času" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Časový limit klienta, pre odstránenie nepoužívaných mapových dát z pamäte, v " +"sekundách." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Pre zníženie lagu, prenos blokov je spomalený, keď hráč niečo stavia.\n" +"Toto určuje ako dlho je spomalený po vložení, alebo zmazaní kocky." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Tlačidlo Prepnutie režimu zobrazenia" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Oneskorenie popisku" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Prah citlivosti dotykovej obrazovky" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "Dotyková obrazovka" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "Kompromisy za výkon" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "Vzdialenosť spracovania priehľadnosti" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Šum stromov" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Trilineárne filtrovanie" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"Pravda = 256\n" +"Nepravda = 128\n" +"Užitočné pre plynulejšiu minimapu na pomalších strojoch." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Dôveryhodné rozšírenia" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" +"Adresa (URL) k zoznamu serverov, ktorý sa zobrazuje v záložke Multiplayer." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Podvzorkovanie" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Podvzorkovanie je podobné ako použiť obrazovku s nižším rozlíšením, ale\n" +"aplikuje sa len na samotný svet, pričom GUI ostáva nezmenené.\n" +"Malo by poskytnúť výrazné zvýšenie výkonu za cenu nižších detailov obrazu.\n" +"Vyššie hodnotu vedú k menej detailnému obrazu." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Neobmedzená vzdialenosť zobrazenia hráča" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Uvoľni nepoužívané serverové dáta" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Horný Y limit kobiek." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Horný Y limit lietajúcich pevnín." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Použi 3D mraky namiesto plochých." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Použi animáciu mrakov pre pozadie hlavného menu." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "Použi anisotropné filtrovanie pri pohľade na textúry zo strany." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Použi bilineárne filtrovanie pri zmene mierky textúr." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Použi mip mapy pre zmenu veľkosti textúr. Môže jemne zvýšiť výkon,\n" +"obzvlášť pri použití balíčka textúr s vysokým rozlíšením.\n" +"Gama korektné podvzorkovanie nie je podporované." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Použi multi-sample antialiasing (MSAA) pre zjemnenie hrán blokov.\n" +"Tento algoritmus zjemní 3D vzhľad zatiaľ čo zachová ostrosť obrazu,\n" +"ale neovplyvní vnútro textúr\n" +"(čo je obzvlášť viditeľné pri priesvitných textúrach).\n" +"Ak sú shadery zakázané, objavia sa viditeľné medzery medzi kockami.\n" +"Ak sú nastavené na 0, MSAA je zakázané.\n" +"Po zmene tohto nastavenia je požadovaný reštart." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Použi trilineárne filtrovanie pri zmene mierky textúr." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "Užívateľské rozhranie" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "VSync" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Hĺbka údolia" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Výplň údolí" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Profil údolia" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Sklon údolia" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Odchýlka hĺbky výplne biómu." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Obmieňa maximálnu výšku hôr (v kockách)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Rôznosť počtu jaskýň." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Rozptyl vertikálnej mierky terénu.\n" +"Ak je šum <-0.55, terén je takmer rovný." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Pozmeňuje hĺbku povrchových kociek biómu." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Mení rôznorodosť terénu.\n" +"Definuje hodnotu 'stálosti' pre terrain_base a terrain_alt noises." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Pozmeňuje strmosť útesov." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Vertikálna rýchlosť šplhania, v kockách za sekundu." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Vertikálna synchronizácia obrazovky." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Grafický ovládač" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Faktor pohupovania sa" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Vzdialenosť dohľadu v kockách." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Tlačidlo Zníž dohľad" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Tlačidlo Zvýš dohľad" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Tlačidlo Priblíženie pohľadu" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Vzdialenosť dohľadu" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "Virtuálny joystick aktivuje tlačidlo Aux1" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Hlasitosť" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Hlasitosť všetkých zvukov.\n" +"Požaduje aby bol zvukový systém aktivovaný." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"W koordináty generovaného 3D plátku v 4D fraktáli.\n" +"Určuje, ktorý 3D plátok z 4D tvaru je generovaný.\n" +"Zmení tvar fraktálu.\n" +"Nemá vplyv na 3D fraktály.\n" +"Rozsah zhruba -2 až 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Rýchlosť chôdze a lietania, v kockách za sekundu." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Rýchlosť chôdze" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Rýchlosť chôdze, lietania a šplhania v rýchlom režime, v kockách za sekundu." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Úroveň vody" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Hladina povrchovej vody vo svete." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Vlniace sa kocky" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Vlniace sa listy" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Vlniace sa tekutiny" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Výška vlnenia sa tekutín" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Rýchlosť vlny tekutín" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Vlnová dĺžka vlniacich sa tekutín" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Vlniace sa rastliny" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "Farba webového odkazu" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Ake je gui_scaling_filter povolený, všetky GUI obrázky potrebujú byť\n" +"filtrované softvérom, ale niektoré obrázky sú generované priamo\n" +"pre hardvér (napr. render-to-texture pre kocky v inventári)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Ake je gui_scaling_filter_txr2img povolený, nakopíruj tieto obrázky\n" +"z hardvéru do softvéru pre zmenu mierky. Ak za vypnutý, vráť sa\n" +"k starej metóde zmeny mierky, pre grafické ovládače, ktoré dostatočne\n" +"nepodporujú sťahovanie textúr z hardvéru." + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Pri použití bilineárneho/trilineárneho/anisotropného filtra, textúry s " +"nízkym\n" +"rozlíšením môžu byť rozmazané, tak sa automaticky upravia interpoláciou\n" +"s najbližším susedom aby bola zachovaná ostrosť pixelov.\n" +"Toto nastaví minimálnu veľkosť pre upravenú textúru;\n" +"vyššia hodnota znamená ostrejší vzhľad, ale potrebuje viac pamäti.\n" +"Odporúčané sú mocniny 2. Nastavenie sa aplikuje len ak je použité bilineárne/" +"trilineárne/anisotropné filtrovanie.\n" +"Toto sa tiež používa ako základná veľkosť textúry kociek pre\n" +"\"world-aligned autoscaling\" textúr." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Či sa má štandardne zobraziť menovka pozadia.\n" +"Rozšírenia stále môžu pozadie nastaviť." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "Či sa nemá animácia textúry kocky synchronizovať." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Či sa hráči zobrazia klientom bez obmedzenia vzdialenosti.\n" +"Zastarané, namiesto tohto použi player_transfer_distance." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Či sa môžu hráči navzájom poškodzovať a zabiť." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Či ná ponúknuť klientom obnovenie spojenia po páde (Lua).\n" +"Povoľ, ak je tvoj server nastavený na automatický reštart." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Či zamlžiť okraj viditeľnej oblasti." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Vypnutie zvukov. Zapnúť zvuky môžeš kedykoľvek, pokiaľ\n" +"nie je zakázaný zvukový systém (enable_sound=false).\n" +"V hre môžeš zapnúť/vypnúť zvuk tlačidlom pre stíšenie zvuku, alebo\n" +"pozastavením hry." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" +"Zobrazovanie technických názvov.\n" +"Ovplyvní rozšírenia a balíčky textúr v Doplnkoch a pri výbere rozšírení, ako " +"aj\n" +"názvy nastavení v menu všetkých nastavení.\n" +"Nastavuje sa zaškrtávacím políčkom v menu \"Všetky nastavenia\"." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "Zobrazenie ladiaceho okna na klientovi (má rovnaký efekt ako F5)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "Šírka okna po spustení. Ignorované v móde celej obrazovky." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Šírka línií obrysu kocky." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Len pre systémy s Windows: Spusti Minetest s oknom príkazovej riadky na " +"pozadí.\n" +"Obsahuje tie isté informácie ako súbor debug.txt (štandardný názov)." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Adresár sveta (všetko na svete je uložené tu).\n" +"Nie je potrebné ak sa spúšťa z hlavného menu." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Počiatočný čas sveta" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Textúry zarovnané podľa sveta môžu byť zväčšené aby pokryli niekoľko " +"kociek.\n" +"Avšak server nemusí poslať mierku akú potrebuješ, obzvlášť ak používaš\n" +"špeciálne dizajnovaný balíček textúr; s týmto nastavením, sa klient pokúsi\n" +"určiť mierku automaticky na základe veľkosti textúry.\n" +"Viď. tiež texture_min_size.\n" +"Varovanie: Toto nastavenie je EXPERIMENTÁLNE!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Režim zarovnaných textúr podľa sveta" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y plochej zeme." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Y hustotný gradient hladiny nula pre hory. Používa sa pre vertikálny posun " +"hôr." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Horný Y limit veľkých jaskýň." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Y-nová vzdialenosť nad ktorou dutiny expandujú do plnej veľkosti." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Y-vzdialenosť kde sa lietajúce pevniny zužujú od plnej hustoty po nič.\n" +"Zužovanie začína na tejto vzdialenosti z Y limitu.\n" +"Pre jednoznačnosť vrstvy lietajúcej krajiny, toto riadi výšku kopcov/hôr.\n" +"Musí byť menej ako, alebo rovnako ako polovica vzdialenosti medzi Y limitami." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Y-úroveň priemeru povrchu terénu." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Y-úroveň horného limitu dutín." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Y-úroveň horného terénu, ktorý tvorí útesy/skaly." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Y-úroveň dolnej časti terénu a morského dna." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Y-úroveň morského dna." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "cURL" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "cURL časový rámec sťahovania súborov" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "Časový rámec interakcie cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Paralelný limit cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Kreatívny mód: " + +#~ msgid "- Damage: " +#~ msgstr "- Poškodenie: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = parallax occlusion s informácia o sklone (rýchlejšie).\n" +#~ "1 = mapovanie reliéfu (pomalšie, presnejšie)." + +#~ msgid "Address / Port" +#~ msgstr "Adresa / Port" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Si si istý, že chceš vynulovať svoj svet jedného hráča?" + +#~ msgid "Basic" +#~ msgstr "Základné" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Počet bitov na pixel (farebná hĺbka) v režime celej obrazovky." + +#~ msgid "Bump Mapping" +#~ msgstr "Bump Mapping (Ilúzia nerovnosti)" + +#~ msgid "Bumpmapping" +#~ msgstr "Bumpmapping" + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Zmení užívateľské rozhranie (UI) hlavného menu:\n" +#~ "- Plné: Viacero svetov, voľby hry, voľba balíčka textúr, atď.\n" +#~ "- Jednoduché: Jeden svet, bez herných volieb, alebo voľby textúr. Môže " +#~ "byť\n" +#~ "nevyhnutné pre malé obrazovky." + +#~ msgid "Config mods" +#~ msgstr "Nastav rozšírenia" + +#~ msgid "Configure" +#~ msgstr "Konfigurácia" + +#~ msgid "Connect" +#~ msgstr "Pripojiť sa" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Riadi rýchlosť ponárania v tekutinách." + +#~ msgid "Credits" +#~ msgstr "Poďakovanie" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Farba zameriavača (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Poškodenie je aktivované" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Štandardný časový rámec pre cURL, zadaný v milisekundách.\n" +#~ "Má efekt len ak je skompilovaný s cURL." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Definuje vzorkovací krok pre textúry.\n" +#~ "Vyššia hodnota vedie k jemnejším normálovým mapám." + +#~ msgid "Del. Favorite" +#~ msgstr "Zmaž obľúbené" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Stiahni si hru, ako napr. Minetest Game z minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Stiahni jednu z minetest.net" + +#~ msgid "Enable register confirmation" +#~ msgstr "Aktivuj potvrdenie registrácie" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Aktivuje bumpmapping pre textúry. Normálové mapy musia byť dodané v " +#~ "balíčku textúr.\n" +#~ "alebo musia byť automaticky generované.\n" +#~ "Vyžaduje aby boli shadery aktivované." + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Aktivuje generovanie normálových máp za behu (efekt reliéfu).\n" +#~ "Požaduje aby bol aktivovaný bumpmapping." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Aktivuj parallax occlusion mapping.\n" +#~ "Požaduje aby boli aktivované shadery." + +#~ msgid "Enter " +#~ msgstr "Vlož " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Experimentálne nastavenie, môže spôsobiť viditeľné medzery\n" +#~ "medzi blokmi, ak je nastavené väčšie než 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS v menu pozastavenia hry" + +#~ msgid "Fallback font shadow" +#~ msgstr "Tieň záložného písma" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Priehľadnosť tieňa záložného fontu" + +#~ msgid "Fallback font size" +#~ msgstr "Veľkosť záložného písma" + +#~ msgid "Filtering" +#~ msgstr "Filtrovanie" + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Veľkosť písma záložného písma v bodoch (pt)." + +#~ msgid "FreeType fonts" +#~ msgstr "FreeType písma" + +#~ msgid "Full screen BPP" +#~ msgstr "BPP v režime celej obrazovky" + +#~ msgid "Game" +#~ msgstr "Hra" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Normal Maps (nerovnosti)" + +#~ msgid "Generate normalmaps" +#~ msgstr "Generuj normálové mapy" + +#~ msgid "HUD scale factor" +#~ msgstr "Mierka HUD" + +#~ msgid "High-precision FPU" +#~ msgstr "Vysoko-presné FPU" + +#~ msgid "In-Game" +#~ msgstr "V hre" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Inštalácia: súbor: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Výstroj" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Priradenie kláves. (ak je toto menu rozbité, zmaž zbytočnosti z minetest." +#~ "conf)" + +#~ msgid "Main" +#~ msgstr "Hlavné" + +#~ msgid "Main menu style" +#~ msgstr "Štýl hlavného menu" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "Umožní DirectX pracovať s LuaJIT. Vypni ak to spôsobuje problémy." + +#~ msgid "Menus" +#~ msgstr "Menu" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Minimapa v radarovom režime, priblíženie x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Minimapa v radarovom režime, priblíženie x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Minimapa v povrchovom režime, priblíženie x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Minimapa v povrchovom režime, priblíženie x4" + +#~ msgid "Name / Password" +#~ msgstr "Meno / Heslo" + +#~ msgid "Name/Password" +#~ msgstr "Meno/Heslo" + +#~ msgid "No" +#~ msgstr "Nie" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Vzorkovanie normálových máp" + +#~ msgid "Normalmaps strength" +#~ msgstr "Intenzita normálových máp" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Počet opakovaní výpočtu parallax occlusion." + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "Nepriehľadnosť tieňa za záložným písmom, medzi 0 a 255." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "Celkové skreslenie parallax occlusion efektu, obvykle mierka/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Celková mierka parallax occlusion efektu." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallax Occlusion (nerovnosti)" + +#~ msgid "Parallax occlusion" +#~ msgstr "Parallax occlusion" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Skreslenie parallax occlusion" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Opakovania parallax occlusion" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Režim parallax occlusion" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Mierka parallax occlusion" + +#~ msgid "Player name" +#~ msgstr "Meno hráča" + +#~ msgid "Profiling" +#~ msgstr "Profilovanie" + +#~ msgid "PvP enabled" +#~ msgstr "PvP je aktívne" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Vynuluj svet jedného hráča" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Server / Hra pre jedného hráča" + +#~ msgid "" +#~ "Set the shadow update time.\n" +#~ "Lower value means shadows and map updates faster, but it consume more " +#~ "resources.\n" +#~ "Minimun value 0.001 seconds max value 0.2 seconds" +#~ msgstr "" +#~ "Nastav aktualizačný čas tieňov.\n" +#~ "Nižšia hodnota znamená. že sa mapa a tiene aktualizujú rýchlejšie, ale " +#~ "spotrebuje sa viac zdrojov.\n" +#~ "Minimálna hodnota je 0.001 sekúnd max. hodnota je 0.2 sekundy" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Posun tieňa (v pixeloch) záložného písma. Ak je 0, tak tieň nebude " +#~ "vykreslený." + +#~ msgid "Special" +#~ msgstr "Špeciál" + +#~ msgid "Special key" +#~ msgstr "Špeciálne tlačidlo" + +#~ msgid "Start Singleplayer" +#~ msgstr "Spusti hru pre jedného hráča" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Intenzita generovaných normálových máp." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Aby mohli byť aktivované shadery, musí sa použiť OpenGL." + +#~ msgid "View" +#~ msgstr "Zobraziť" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Aby boli FreeType písma použité, je nutné aby bola podpora FreeType " +#~ "zakompilovaná.\n" +#~ "Ak je zakázané, budú použité bitmapové a XML vektorové písma." + +#~ msgid "Yes" +#~ msgstr "Áno" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Chystáš sa pripojiť k serveru \"%s\" po prvý krát.\n" +#~ "Ak budeš pokračovať, bude na tomto serveri vytvorený nový účet s tvojimi " +#~ "údajmi.\n" +#~ "Zapíš znova prosím svoje heslo a klikni 'Registrovať a pripojiť sa' pre " +#~ "potvrdenie súhlasu s vytvorením účtu, alebo klikni 'Zrušiť' pre návrat." + +#~ msgid "You died." +#~ msgstr "Zomrel si." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/sl/minetest.po b/po/sl/minetest.po new file mode 100644 index 0000000..5412dd0 --- /dev/null +++ b/po/sl/minetest.po @@ -0,0 +1,7323 @@ +msgid "" +msgstr "" +"Project-Id-Version: Slovenian (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2020-09-30 19:41+0000\n" +"Last-Translator: Iztok Bajcar <iztok.bajcar@gmail.com>\n" +"Language-Team: Slovenian <https://hosted.weblate.org/projects/minetest/" +"minetest/sl/>\n" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || " +"n%100==4 ? 2 : 3;\n" +"X-Generator: Weblate 4.3-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Izhod na meni" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Invalid command: " +msgstr "Krajevni ukaz" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "samostojna igra" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "samostojna igra" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Ponovno oživi" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Umrl si" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "Krajevni ukaz" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "Krajevni ukaz" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "V redu" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Prišlo je do napake v Lua skripti:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Prišlo je do napake:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Glavni meni" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Ponovna povezava" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Strežnik zahteva ponovno povezavo:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Izbor sveta:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Različice protokola niso skladne. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Strežnik vsiljuje različico protokola $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Strežnik podpira različice protokolov med $1 in $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Podporta je le različica protokola $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Podprte so različice protokolov med $1 in $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Prekliči" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Odvisnosti:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Onemogoči vse" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Onemogoči paket prilagoditev" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Omogoči vse" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Omogoči paket prilagoditev" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Zagon prilagoditve »$1« je spodletel zaradi uporabljenih nedovoljenih " +"znakov. Dovoljeni so le [a-z0-9_] znaki." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Poišči več razširitev" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Prilagoditev:" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No (optional) dependencies" +msgstr "Izbirne možnosti:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Opis igre ni na voljo." + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No hard dependencies" +msgstr "Ni zaznanih odvisnosti." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Opis prilagoditve ni na voljo." + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No optional dependencies" +msgstr "Ni izbirnih odvisnosti" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Izbirne možnosti:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Shrani" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Svet:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "omogočeno" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "Poteka nalaganje ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Vsi paketi" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Already installed" +msgstr "Tipka je že v uporabi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Nazaj na glavni meni" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "Gosti igro" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB ni na voljo, če je bil Minetest narejen brez podpore cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Downloading..." +msgstr "Poteka nalaganje ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Prenos $1 je spodletel" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Igre" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Namesti" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "Namesti" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "Izbirne možnosti:" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "Nameščanje: nepodprta vrsta datoteke \"$1\" oziroma okvarjen arhiv" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Prilagoditve (mods)" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Ni mogoče pridobiti nobenega paketa" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Ni rezultatov" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "No updates" +msgstr "Posodobi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Paketi tekstur" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Odstrani" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Posodobi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Svet z imenom »$1« že obstaja" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Additional terrain" +msgstr "Dodatni teren" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biome blending" +msgstr "Zlivanje biomov" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biomes" +msgstr "Biomi" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caverns" +msgstr "Šum votline" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Jame" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Ustvari" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Decorations" +msgstr "Dekoracije" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Opozorilo: okrnjena razvojna različica je namenjena razvijalcem." + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Dungeons" +msgstr "Ječe" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Flat terrain" +msgstr "Raven teren" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Floating landmasses in the sky" +msgstr "Lebdeče kopenske mase na nebu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Generiraj nefraktalen teren: oceani in podzemlje" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Hribi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Vlažne reke" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Poveča vlažnost v bližini rek" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Namesti" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Jezera" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Nizka vlažnost in visoka vročina povzročita plitve ali izsušene reke" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Oblika sveta (mapgen)" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Možnosti generatorja zemljevida" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mapgen-specific flags" +msgstr "Oblika sveta (mapgen) Fractal" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Gore" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Tok blata" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Omrežje predorov in jam" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Niste izbrali igre" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Vročina pojema z višino" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Vlažnost pojema z višino" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Reke" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Reke na višini morja" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Seme" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Gladek prehod med biomi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Strukture, ki se pojavijo na terenu (nima vpliva na drevesa in džungelsko " +"travo, ustvarjeno z mapgenom v6)" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Strukture, ki se pojavljajo na terenu, npr. drevesa in rastline" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erozija terena" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Drevesa in džungelska trava" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Vary river depth" +msgstr "Globina polnila" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Zelo velike jame globoko v podzemlju" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Ime sveta" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Ni nameščenih iger." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Ali res želiš zbrisati »$1«?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Izbriši" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "Package manager: brisanje \"$1\" je spodletelo" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "Package manager: neveljavna pot \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Ali res želiš izbrisati svet »$1«?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Potrditev gesla" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "Novo geslo" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Gesli se ne ujemata!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Registriraj in prijavi se" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Sprejmi" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Preimenuj paket prilagoditev:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Ta paket prilagoditev ima jasno ime, določeno v svojem modpack.conf, ki bo " +"preprečilo kakršnakoli preimenovanja tukaj." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(ni podanega opisa nastavitve)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D šum" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Nazaj do Nastavitev" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Prebrskaj" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Vsebina" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Vsebina" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Onemogočeno" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Uredi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Omogočeno" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Lacunarity" +msgstr "lacunarnost" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktave" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Odmik" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Trajanje" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Vpisati je treba veljavno celo število." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Vpisati je treba veljavno število." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Obnovi privzeto" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Skala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Poišči" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Izberi mapo" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Izberi datoteko" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Prikaži tehnična imena" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Vrednost mora biti vsaj $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Vrednost ne sme biti večja od $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X širjenje" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y širjenje" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z širjenje" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Absolutna vrednost" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "Privzeta/standardna vrednost (defaults)" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "eased" +msgstr "sproščeno" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (omogočeno)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 prilagoditve" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Namestitev $1 na $2 je spodletela" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Namestitev prilagoditve: ni mogoče najti pravega imena za: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Namestitev prilagoditve: ni mogoče najti ustreznega imena mape za paket " +"prilagoditev $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Ni mogoče najti ustrezne prilagoditve ali paketa prilagoditev" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Ni mogoče namestiti $1 kot paket tekstur" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Ni mogoče namestiti igre kot $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Ni mogoče namestiti prilagoditve kot $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Ni mogoče namestiti paketa prilagoditev kot $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Poteka nalaganje ..." + +#: builtin/mainmenu/serverlistmgr.lua +#, fuzzy +msgid "Public server list is disabled" +msgstr "Skriptiranje s strani odjemalca je onemogočeno" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Morda je treba ponovno omogočiti javni seznam strežnikov oziroma preveriti " +"internetno povezavo." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Dejavni sodelavci" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Glavni razvijalci" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Izberi mapo" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Predhodni sodelavci" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Predhodni razvajalci" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Brskaj po spletnih vsebinah" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Vsebina" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Onemogoči paket tekstur" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Informacije:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Nameščeni paketi:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Ni zaznanih odvisnosti." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Opis paketa ni na voljo" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Preimenuj" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Odstrani paket" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Uporabi paket tekstur" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Objavi strežnik" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Vezani naslov" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Ustvarjalni način" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Omogoči poškodbe" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Gosti igro" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Gostiteljski strežnik" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Namesti igre iz ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Novo" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Ni ustvarjenega oziroma izbranega sveta!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Zaženi igro" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Vrata" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "Izbor sveta:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Izbor sveta:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Vrata strežnika" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Začni igro" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "– Naslov: " + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Počisti" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Ustvarjalni način" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "Poškodbe" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "Priljubljeno" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Prijavi se v igro" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "Objavi strežnik" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Izbriši priljubljeno" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "Vrata strežnika" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Prostorski, 3D prikaz oblakov" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Vse nastavitve" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Glajenje:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Samodejno shrani velikost zaslona" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilinearni filter" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Spremeni tipke" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Povezano steklo" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Dynamic shadows" +msgstr "Senca pisave" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Senca pisave" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Olepšani listi" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Zemljevid (minimap)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Zemljevid (minimap) s filtrom Aniso" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Brez filtra" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Brez zemljevida (minimap)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Poudarjanje vozlišč" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Obrobljanje vozlišč" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Brez" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Neprosojni listi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Neprosojna površina vode" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Delci" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Zaslon:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Nastavitve" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Senčenje" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "Senčenje (ni na voljo)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Senčenje (ni na voljo)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Preprosti listi" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Gladko osvetljevanje" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Tekstura:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Barvno preslikavanje" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Občutljivost dotika (v pikslih):" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Trilinearni filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Pokaži premikanje listov" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Valovanje tekočin" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Pokaži nihanje rastlin" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Napaka povezave (ali je dejanje časovno preteklo?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Povezava je potekla." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Končano!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Zaganjanje vozlišč" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Zaganjanje vozlišč ..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Poteka nalaganje tekstur ..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Preračunavanje senčenja ..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Napaka povezave (ali je dejanje časovno preteklo?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "Ni mogoče najti oziroma naložiti igre »" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Neveljavna določila igre." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Glavni Meni" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" +"Ni izbranega sveta in ni podanega naslova. Podatka sta ključna za " +"nadaljevanje." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Ime igralca je predolgo." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Izbrati je treba ime!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Ni bilo mogoče odpreti datoteke z geslom: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Podana pot do sveta ne obstaja: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Več podrobnosti je zapisanih v datoteki debug.txt." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "– Naslov: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "– Način: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "– Vrata: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "– Javno: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "– Igra PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "– Ime strežnika: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Prišlo je do napake:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Samodejno premikanje naprej je onemogočeno" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Samodejno premikanje naprej je omogočeno" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Posodabljanje kamere je onemogočeno" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Posodabljanje kamere je omogočeno" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Spremeni geslo" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Filmski način(Cinematic mode) je onemogočen" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Filmski način (Cinematic mode) je omogočen" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Skriptiranje s strani odjemalca je onemogočeno" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Poteka povezovanje s strežnikom ..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Nadaljuj" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Tipkovne bližnjice:\n" +"- %s 1: premakne se naprej\n" +"- %s 2: premakne se nazaj\n" +"- %s 3: premakne se levo\n" +"- %s 4: premakne se desno\n" +"- %s 5: skakanje / plezanje\n" +"- %s 6: plazenje / premikanje dol\n" +"- %s 7: vrže predmet stran\n" +"- %s 8: pokaže zalogo\n" +"- Miška: obrne / pogleda\n" +"- levi gumb miške: koplje / udari\n" +"- desni gumb miške: postavi/uporabi\n" +"- kolesce miške: izbere orodje iz zaloge\n" +"- %s 9: omogoči klepet\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Ustvarjanje odjemalca ..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Poteka zagon strežnika ..." + +#: src/client/game.cpp +#, fuzzy +msgid "Debug info and profiler graph hidden" +msgstr "Podatki za razhroščevanje in graf skriti" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Prikazani so podatki o odpravljanju napak" + +#: src/client/game.cpp +#, fuzzy +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Podatki za razhroščevanje, graf, in žičnati prikaz skriti" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Privzete tipkovne bližnjice:\n" +"S skritim menijem:\n" +"- enojni klik: postavi gumb v žarišče\n" +"- dvojni klik: postavi / uporabi\n" +"- drsanje: pogled naokoli\n" +"S prikazanim menijem / zalogo:\n" +"- dvojni klik (izven polja):\n" +" -->Zapre\n" +"- izbira polja:\n" +" --> premakne zalogo\n" +"- klik in poteg, tap z dvema prstoma\n" +" --> postavi predmet v polje\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Onemogočen neomejen doseg pogleda" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Omogočen neomejen doseg pogleda" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Ustvarjanje odjemalca ..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Izhod na meni" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Zapri minetest" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Hitri način je onemogočen" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Hitri način je omogočen" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Hitri način je omogočen (opozorilo: nimate 'fast' privilegija)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Način letenja je onemogočen" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Način letenja je omogočen" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Način letenja je omogočen (opozorilo: nimate 'fly' privilegija)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Megla onemogočena" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Megla omogočena" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Podrobnosti o igri:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Igra je začasno ustavljena" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Gostiteljski strežnik" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Določila predmetov ..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Medij..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" +"Zemljevid (minimap) je trenutno onemogočen zaradi igre ali prilagoditve" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "samostojna igra" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Prehod skozi zid (način duha) je onemogočen" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Prehod skozi zid (način duha) je omogočen" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" +"Prehod skozi zid (način duha) je omogočen (opozorilo: nimate 'noclip' " +"privilegija)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Določila vozlišč ..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Izklopljeno" + +#: src/client/game.cpp +msgid "On" +msgstr "Vklopljeno" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Prostorsko premikanje (pitch mode) je onemogočeno" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Prostorsko premikanje (pitch mode) je omogočeno" + +#: src/client/game.cpp +#, fuzzy +msgid "Profiler graph shown" +msgstr "Profiler prikazan" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Oddaljeni strežnik" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Poteka razreševanje naslova ..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Poteka zaustavljanje ..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "samostojna igra" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Glasnost zvoka" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Zvok je utišan" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Zvočni sistem je onemogočen" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Zvočni sistem v tej izdaji Minetesta ni podprt" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Zvok ni utišan" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Doseg pogleda je nastavljena na %d %%" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Doseg pogleda je na maksimumu: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Doseg pogleda je na minimumu: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Glasnost zvoka je nastavljena na %d %%" + +#: src/client/game.cpp +#, fuzzy +msgid "Wireframe shown" +msgstr "Žičnati prikaz omogočen" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Približanje (zoom) je trenutno onemogočen zaradi igre ali prilagoditve" + +#: src/client/game.cpp +msgid "ok" +msgstr "v redu" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Pogovor je skrit" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Pogovor je prikazan" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD je skrit" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD je prikazan" + +#: src/client/gameui.cpp +#, fuzzy +msgid "Profiler hidden" +msgstr "Profiler skrit" + +#: src/client/gameui.cpp +#, fuzzy, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profiler prikazan (stran %d od %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Aplikacije" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Velike črke" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Dol" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Konec" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Izbriši EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Izvedi" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Pomoč" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Začetno mesto" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Accept" +msgstr "IME Sprejem" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Convert" +msgstr "IME Pretvorba" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Escape" +msgstr "IME Pobeg" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Mode Change" +msgstr "IME sprememba načina" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Nonconvert" +msgstr "IME Nepretvorba" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Vstavi" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Levo" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Leva tipka" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Leva tipka Ctrl" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Leva tipka Meni" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Leva tipka Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Leva tipka Win" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Meni" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Srednji gumb" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Tipka zaklepa številčnice" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Tipka * na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Tipka + na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Tipka – na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Tipka , na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Tipka / na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Tipka 0 na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Tipka 1 na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Tipka 2 na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Tipka 3 na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Tipka 4 na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Tipka 5 na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Tipka 6 na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Tipka 7 na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Tipka 8 na številčnici" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Tipka 9 na številčnici" + +#: src/client/keycode.cpp +#, fuzzy +msgid "OEM Clear" +msgstr "OEM Clear" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Stran nižje" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Stran višje" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Premor" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Igraj" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Natisni" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Vrnitev" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Desno" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Desna tipka" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Desna tipka Ctrl" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Desna tipka Meni" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Desna tipka Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Desna tipka Win" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Tipka zaklepa drsnika" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Izberi" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Spanje" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Posnetek" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Preslednica" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tabulator" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Gor" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Gumb 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Gumb 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Približanje" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Zemljevid (minimap) je skrit" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Zemljevid (minimap) je v radar načinu, Zoom x1" + +#: src/client/minimap.cpp +#, fuzzy, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Zemljevid (minimap) je v načinu prikazovanja površja, Zoom x1" + +#: src/client/minimap.cpp +#, fuzzy +msgid "Minimap in texture mode" +msgstr "Zemljevid (minimap) je v načinu prikazovanja površja, Zoom x1" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Prenos $1 je spodletel" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Nadaljuj" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "\"Special\" = plezanje dol" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Samodejno premikanje naprej" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Samodejno skakanje" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Nazaj" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Sprememba kamere" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Klepet" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Ukaz" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konzola" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Zmanjšaj doseg pogleda" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Zmanjšaj glasnost" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Dvojni klik »skoka« omogoči letenje" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Izvrzi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Naprej" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Povečaj doseg pogleda" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Povečaj glasnonst" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Zaloga" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Skoči" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Tipka je že v uporabi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Krajevni ukaz" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Utišaj" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Naslednji predmet" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Predhodni predmet" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Izberi obseg" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Posnetek zaslona" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Plaziti se" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Preklopi HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Preklopi beleženje pogovora" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Preklopi hitro premikanje" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Preklopi letenje" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Preklopi meglo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Preklopi zemljevid (minimap)" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Preklopi premikanje skozi kocke" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle pitchmove" +msgstr "Preklopi beleženje pogovora" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "pritisni tipko" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Spremeni" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Novo geslo" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Staro geslo" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Gesli se ne ujemata!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Izhod" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Utišano" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Glasnost zvoka: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "sl" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Izbrati je treba ime!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Popravi položaj virtualne igralne palice.\n" +"Če je onemogočeno, se bo sredina igralne palice nastavila na položaj prvega " +"pritiska na ekran." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Uporabi virtualno igralno palico za pritisk gumba \"aux\".\n" +"Če je omogočeno, bo igralna palica sprožila gumb \"aux\", ko bo zunaj " +"glavnega kroga." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X, Y, Z) Zamik fraktala od središča sveta v enotah 'scale'.\n" +"Uporabno za premik določene točke na (0, 0) za ustvarjanje\n" +"primerne začetne točke (spawn point) ali za 'zumiranje' na določeno\n" +"točko, tako da povečate 'scale'.\n" +"Privzeta vrednost je prirejena za primerno začetno točko za Mandelbrotovo\n" +"množico s privzetimi parametri, v ostalih situacijah jo bo morda treba\n" +"spremeniti.\n" +"Obseg je približno od -2 do 2. Pomnožite s 'scale', da določite zamik v " +"enoti ene kocke." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X, Y, Z) skala (razteg) fraktala v enoti ene kocke.\n" +"Resnična velikost fraktala bo 2- do 3-krat večja.\n" +"Te vrednosti so lahko zelo velike; ni potrebno,\n" +"da se fraktal prilega velikosti sveta.\n" +"Povečajte te vrednosti, da 'zumirate' na podrobnosti fraktala.\n" +"Privzeta vrednost določa vertikalno stisnjeno obliko, primerno za\n" +"otok; nastavite vse tri vrednosti na isto število za neobdelano obliko." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2D šum, ki nadzoruje obliko/velikost gorskih verig." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2D šum, ki nadzira obliko in velikost hribov." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2D šum, ki nadzira obliko/velikost gora." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "2D šum, ki nadzira velikost/pojavljanje gorskih verig." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D šum, ki nadzira veliokst/pojavljanje hribov." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "2D šum, ki nadzira velikost/pojavljanje gorskih verig." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2D šum, ki določa položaj rečnih dolin in kanalov." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D oblaki" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D način" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Moč 3D parallax načina" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D šum, ki določa večje jame." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D šum, ki določa strukturo in višino gora\n" +"ter strukturo terena lebdečih gora." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"3D šum, ki določa strukturo lebdeče pokrajine.\n" +"Po spremembi s privzete vrednosti bo 'skalo' šuma (privzeto 0,7) morda " +"treba\n" +"prilagoditi, saj program za generiranje teh pokrajin najbolje deluje\n" +"z vrednostjo v območju med -2,0 in 2,0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "3D šum, ki določa strukturo sten rečnih kanjonov." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3D šum za določanje terena." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "3D šum za gorske previse, klife, itd. Ponavadi so variacije majhne." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D šum, ki določa število ječ na posamezen kos zemljevida." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Izbrano seme zemljevida, pustite prazno za izbor naključnega semena.\n" +"Ta nastavitev bo povožena v primeru ustvarjanja novega sveta iz glavnega " +"menija." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" +"Sporočilo, ki bo prikazano vsem odjemalcem (igralcem), ko se strežnik sesuje." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" +"Sporočilo, ki bo prikazano vsem odjemalcem (igralcem), ko se strežnik " +"zaustavi/izklopi." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Interval ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Pospešek v zraku" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Pospešek gravitacije v kockah na kvadratno sekundo." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Modifikatorji aktivnih blokov" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Interval upravljanja aktivnih blokov" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Doseg aktivnih blokov" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Naslov strežnika.\n" +"Pustite prazno za zagon lokalnega strežnika.\n" +"Polje za vpis naslova v glavnem meniju povozi to nastavitev." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Adds particles when digging a node." +msgstr "Doda partikle pri kopanju kocke." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Nastavite dpi konfiguracijo (gostoto prikaza) svojemu ekranu (samo za ne-X11/" +"Android), npr. za 4K ekrane." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Dodaj ime elementa" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Naprednejše" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Vedno leti in bodi hiter (fly and fast mode)" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Največja količina sporočil, ki jih igralec sme poslati v 10 sekundah." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Ojača doline." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Objavi strežnik" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Objavi strežnik na seznamu strežnikov." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Dodaj ime elementa" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Apple trees noise" +msgstr "Šum jablan" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Vztrajnost roke" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Vztrajnost roke; daje bolj realistično gibanje\n" +"roke, ko se kamera premika." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Vprašaj za ponovno povezavo po sesutju" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"Na tej razdalji bo strežnik agresivno optimiziral, kateri bloki bodo " +"poslani\n" +"igralcem.\n" +"Manjše vrednosti lahko močno pospešijo delovanje na račun napak\n" +"pri izrisovanju (nekateri bloki se ne bodo izrisali pod vodo in v jamah,\n" +"včasih pa tudi na kopnem).\n" +"Nastavljanje na vrednost, večjo od max_block_send_distance, onemogoči to\n" +"optimizacijo.\n" +"Navedena vrednost ima enoto 'mapchunk' (16 blokov)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Tipka za avtomatsko premikanje naprej" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Avtomatsko skoči čez ovire, visoke eno vozlišče." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatically report to the serverlist." +msgstr "Samodejno sporoči na seznam strežnikov." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Samodejno shrani velikost zaslona" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key for climbing/descending" +msgstr "Posebna tipka, ki se uporablja za plezanje in spuščanje" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Tipka backward" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Base ground level" +msgstr "Osnovna podlaga" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Višina osnovnega terena." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Osnovni privilegiji" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilinearno filtriranje" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome noise" +msgstr "Šum bioma" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Pot do krepke in poševne pisave" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Pot do krepke in ležeče pisave konstantne širine" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bold font path" +msgstr "Pot pisave" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Pot do krepke pisave konstantne širine" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Postavljanje blokov znotraj igralca" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Vgrajeno" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Sprememba kamere" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"'Bližnja ravnina' kamere - najmanjša razdalja, na kateri kamera vidi objekte " +"- v blokih, med 0 in 0,25.\n" +"Deluje samo na platformah GLES. Večini uporabnikov te nastavitve ni treba " +"spreminjati.\n" +"Povečanje vrednosti lahko odpravi anomalije na šibkejših grafičnih " +"procesorjih.\n" +"0.1 = privzeto, 0.25 = dobra vrednost za šibkejše naprave" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Glajenje premikanja kamere" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Glajenje premikanja kamere v filmskem načinu" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave noise" +msgstr "Šum jame" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave noise #1" +msgstr "Šum jame #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave noise #2" +msgstr "Šum jame #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Širina jame" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Šum Cave1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Šum Cave2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Omejitev votline" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern noise" +msgstr "Šum votline" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Zoženje votline" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Vhod v jamo" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Zgornja meja jam" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Središče območja povečave svetlobne krivulje.\n" +"0.0 je minimalna raven svetlobe, 1.0 maksimalna." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Ukaz" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat font size" +msgstr "Velikost pisave" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Tipka za pogovor" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat log level" +msgstr "Tipka za preklop na klepet" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Omejitev števila sporočil pogovora" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat message format" +msgstr "Maksimalna dolžina pogovornega sporočila" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Maksimalna dolžina pogovornega sporočila" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Tipka za preklop na klepet" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat weblinks" +msgstr "Pogovor je prikazan" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chunk size" +msgstr "Velikost 'chunka'" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Filmski način (Cinematic mode)" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tipka za filmski način" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Clean transparent textures" +msgstr "Čiste prosojne teksture" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Odjemalec" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Odjemalec in strežnik" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Hitrost plezanja" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Polmer oblaka" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Oblaki" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Oblaki v meniju" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Barvna megla" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Colored shadows" +msgstr "Barvna megla" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Tipka Command" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Poveži steklo" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Poveži se z zunanjim medijskim strežnikom" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Connects glass if supported by node." +msgstr "Povezuje steklo, če ga vozlišče podpira." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Barva konzole" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Višina konzole" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ContentDB URL" +msgstr "ContentDB URL" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Neprekinjeno naprej" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Controls" +msgstr "Kontrole" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Nadzira strmost/globino jezerskih depresij." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Nadzira strmost/višino hribov." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Sporočilo o sesutju" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Ustvarjalen" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Poškodbe" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Tipka za zmanjševanje glasnosti" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Privzet pospešek" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Privzeta igra" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Privzeta igra pri ustvarjanju novega sveta.\n" +"To ne bo upoštevano pri ustvarjanju sveta iz glavnega menija." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Privzeto geslo" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Privzeti privilegiji" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Privzeta oblika poročanja" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default stack size" +msgstr "Privzeta igra" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Določa območja, kjer imajo drevesa jabolka." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Določa območja s peščenimi plažami." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Določa porazdelitev višjega terena in strmino klifov." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Določa porazdelitev višjega terena." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Določa polno velikost votlin, manjše vrednosti ustvarjajo večje votline." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Določa obsežno strukturo rečnega kanala." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Določa lokacijo in teren neobveznih gričev in jezer." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Določa osnovno podlago." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Določa globino rečne struge." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "Določa maksimalno razdaljo prenosa igralcev v blokih (0 = neomejeno)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Določa širino rečne struge." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Določa širino rečne doline." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Določa področja dreves in gostoto dreves." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Globina pod katero boš našel ogromne votline." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Globina pod katero boš našel velike jame." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Opis strežnika, ki bo prikazan na seznamu strežnikov in, ko se igralci " +"prijavijo v igro." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Dekoracije" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "Tipka za met predmeta" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Kopanje delcev" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Onemogoči preprečevanje goljufanja" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Ne dovoli praznih gesel" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Ime domene strežnika, ki se prikaže na seznamu strežnikov." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Dvojni klik tipke »skoči« za letenje" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Dvoklik tipke za skok preklopi način letenja." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Tipka za met predmeta" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Šum ječe" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable creative mode for all players" +msgstr "Omogoči ustvarjalni način za novo ustvarjene svetove." + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Omogoči joystick" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Omogoči, da igralci dobijo poškodbo in umrejo." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Omogoči zemljevid (minimap)." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Fallback font path" +msgstr "Pot pisave" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Tipka za hitro premikanje" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Hitro premikanje" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Možnost omogoča hitro premikanje (s tipko »uporabi«).\n" +"Delovanje zahteva omogočeno podporo za »hitro premikanje (fast)« na " +"strežniku." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Vidno polje" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Vidno polje v stopinjah." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filler depth" +msgstr "Globina polnila" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Glajenje:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Fiksno seme karte" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Fiksen virtualni joystick" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Tipka za letenje" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Letenje" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Megla" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Začetek megle" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Tipka za preklop na meglo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Velikost pisave" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font shadow" +msgstr "Senca pisave" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size" +msgstr "Velikost pisave" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Format of screenshots." +msgstr "Oblika posnetkov zaslona." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec Default Background Color" +msgstr "Formspec privzeta barva ozadja" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Formspec privzeta neprosojnost ozadja" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Formspec barva ozadja v celozaslonskem načinu" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Formspec neprosojnost ozadja v celozaslonskem načinu" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Formspec privzeta barva ozadja (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Formspec privzeta neprosojnost ozadja (med 0 in 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Formspec barva ozadja v celozaslonskem načinu (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" +"Formspec neprosojnost ozadja v celozaslonskem načinu (between 0 and 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Tipka naprej" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Celozaslonski način" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Celozaslonski način." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Igre" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafika" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravitacija" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "HUD je prikazan" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Strmina hriba" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Tipka za naslednji prostor v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Tipka za prejšnji prostor v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Tipka za prostor 1 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Tipka za prostor 10 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Tipka za prostor 11 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Tipka za prostor 12 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Tipka za prostor 13 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Tipka za prostor 14 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Tipka za prostor 15 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Tipka za prostor 17 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Tipka za prostor 17 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Tipka za prostor 18 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Tipka za prostor 19 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Tipka za prostor 2 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Tipka za prostor 20 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Tipka za prostor 21 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Tipka za prostor 22 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Tipka za prostor 23 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Tipka za prostor 24 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Tipka za prostor 25 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Tipka za prostor 26 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Tipka za prostor 27 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Tipka za prostor 28 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Tipka za prostor 29 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Tipka za prostor 3 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Tipka za prostor 30 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Tipka za prostor 31 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Tipka za prostor 32 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Tipka za prostor 4 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Tipka za prostor 5 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Tipka za prostor 6 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Tipka za prostor 7 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Tipka za prostor 8 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Tipka za prostor 9 v hotbar-u" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Kako globoke naredi reke." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Kako široke naredi reke." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6 strežnik" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Če bi FPS presegel to, jo omeji s spanjem,\n" +" da ne porablja moči CPU brez koristi." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Če je omogočen skupaj z letečim načinom, lahko igralec leti skozi trdna " +"vozlišča.\n" +"To zahteva privilegij \"noclip\" na strežniku." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Izbrana možnost omogoči delovanje \"posebne\" tipke namesto tipke \"plaziti " +"se\" za spuščanja in plezanje navzdol." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Če je omogočeno, onemogoči preprečevanje goljufij v multiplayer-u." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Če je omogočeno, neveljavni podatki o svetu ne bodo povzročili zaustavitve " +"strežnika.\n" +"To omogočite le, če veste, kaj počnete." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Če je omogočeno, naredi igralčevo smer premikanja odvisno od igralčeve smeri " +"pri letenju ali plavanju (premikaš se tja, kamor si obrnjen)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "Če je omogočeno, se novi igralci ne morejo prijaviti s praznim geslom." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Če je omogočeno, lahko postavite bloke na položaj (stopala + višina oči), " +"kjer stojiš.\n" +"To je koristno pri delu z vozlišči v majhnih območjih." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" +"Če je to nastavljeno, se bodo igralci vedno (ponovno) pojavili na danem " +"položaju." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Prezri napake svetov" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Barva ozadja konzole za klepet v igri (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "Višina konzole za klepet med igro, med 0,1 (10%) in 1,0 (100%)." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Tipka za povečanje glasnosti" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Obrni delovanje miške" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Obrne navpično gibanje med premikanjem miške." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Italic font path" +msgstr "Pot pisave" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia W" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia X" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia Y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia Z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Gladko osvetljevanje" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Oblika sveta (mapgen) Ravnina" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Oblika sveta (mapgen) Fractal" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "Oblika sveta (mapgen) Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Oblika sveta (mapgen) V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Oblika sveta (mapgen) V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Oblika sveta (mapgen) V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Občutljivost miške" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Števnik občutljivosti premikanja miške." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Poudarjanje vozlišč" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Tipka za letenje" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Možnost omogoča letenje brez učinkovanja težnosti.\n" +"Delovanje zahteva omogočeno podporo za »letenje (fly)« na strežniku." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Bilinearno filtriranje" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Regular font path" +msgstr "Pot pisave" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Zaslon:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Posnetek zaslona" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Gostiteljski strežnik" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "– Ime strežnika: " + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Vrata strežnika" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Vrata strežnika" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Možnost omogoča gladko drsenje kamere med premikanjem.\n" +"Lahko je uporabno pri snemanju videa igre." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" +"Možnost omogoča glajenje pogleda kamere med obračanjem v filmskem načinu. " +"Vrednost 0 možnost onemogoči." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" +"Možnost omogoča glajenje pogleda kamere med obračanjem. Vrednost 0 možnost " +"onemogoči." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Senca pisave" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Nastavitve" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Celozaslonski način" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Valovanje tekočin" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Pokaži valovanje vode" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Pokaži premikanje listov" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Pokaži valovanje vode" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Ali dovoliš igralcem da poškodujejo in ubijejo drug drugega." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Čas začetka sveta" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "– Ustvarjalni način: " + +#~ msgid "- Damage: " +#~ msgstr "– Poškodbe: " + +#, fuzzy +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = \"parallax occlusion\" s podatki o nagibih (hitrejše)\n" +#~ "1 = mapiranje reliefa (počasnejše, a bolj natančno)" + +#~ msgid "Address / Port" +#~ msgstr "Naslov / Vrata" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Ali res želiš ponastaviti samostojno igro?" + +#~ msgid "Back" +#~ msgstr "Nazaj" + +#~ msgid "Basic" +#~ msgstr "Osnovno" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Biti na piksel (barvna globina) v celozaslonskem načinu." + +#~ msgid "Bump Mapping" +#~ msgstr "Površinsko preslikavanje" + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Spremeni uporabniški vmesnik glavnega menija:\n" +#~ "- Polno: več enoigralskih svetov, izbira igre, izbirnik paketov " +#~ "tekstur, itd.\n" +#~ "- Preprosto: en enoigralski svet, izbirnika iger in paketov tekstur se " +#~ "ne prikažeta. Morda bo za manjše\n" +#~ "ekrane potrebna ta nastavitev." + +#~ msgid "Config mods" +#~ msgstr "Nastavitve prilagoditev" + +#~ msgid "Configure" +#~ msgstr "Nastavi" + +#~ msgid "Connect" +#~ msgstr "Poveži" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Nadzira hitrost potapljanja v tekočinah." + +#~ msgid "Credits" +#~ msgstr "Zasluge" + +#~ msgid "Damage enabled" +#~ msgstr "Poškodbe so omogočene" + +#~ msgid "Darkness sharpness" +#~ msgstr "Ostrina teme" + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Določa korak vzorčenja teksture.\n" +#~ "Višja vrednost povzroči bolj gladke normalne zemljevide." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Prenesi igro, kot na primer Minetest Game, s spletišča minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Na voljo so na spletišču minetest.net/customize" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Prenašanje in nameščanje $1, prosimo počakajte..." + +#, fuzzy +#~ msgid "Enable VBO" +#~ msgstr "Omogoči VBO" + +#~ msgid "Enter " +#~ msgstr "Vpis " + +#~ msgid "Filtering" +#~ msgstr "Filtriranje" + +#~ msgid "Game" +#~ msgstr "Igra" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Generiranje normalnih svetov" + +#~ msgid "IPv6 support." +#~ msgstr "IPv6 podpora." + +#~ msgid "In-Game" +#~ msgstr "V igri" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Namesti: datoteka: »$1«" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Vloge tipk (če ta meni preneha delovati, odstranite nastavitve tipk iz " +#~ "datoteke minetest.conf)" + +#~ msgid "Main" +#~ msgstr "Glavni" + +#~ msgid "Main menu style" +#~ msgstr "Slog glavnega menija" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Zemljevid (minimap) je v radar načinu, Zoom x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Zemljevid (minimap) je v radar načinu, Zoom x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Zemljevid (minimap) je v načinu prikazovanja površja, Zoom x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Zemljevid (minimap) je v načinu prikazovanja površja, Zoom x4" + +#~ msgid "Name / Password" +#~ msgstr "Ime / Geslo" + +#~ msgid "Name/Password" +#~ msgstr "Ime / Geslo" + +#~ msgid "No" +#~ msgstr "Ne" + +#~ msgid "Ok" +#~ msgstr "V redu" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Paralaksa" + +#, fuzzy +#~ msgid "Parallax occlusion scale" +#~ msgstr "Lestvica okluzije paralakse" + +#~ msgid "PvP enabled" +#~ msgstr "Igra PvP je omogočena" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Ponastavi samostojno igro" + +#~ msgid "Select Package File:" +#~ msgstr "Izberi datoteko paketa:" + +#~ msgid "Special" +#~ msgstr "Specialen" + +#~ msgid "Special key" +#~ msgstr "Posebna tipka" + +#~ msgid "Start Singleplayer" +#~ msgstr "Zaženi samostojno igro" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Za prikaz senčenja mora biti omogočen gonilnik OpenGL." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Preklopi gladek pogled" + +#, fuzzy +#~ msgid "View" +#~ msgstr "Pogled" + +#~ msgid "Yes" +#~ msgstr "Da" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Prvič se boste prijavili v strežnik z imenom \"%s\".\n" +#~ "Če nadaljujete, bo na tem strežniku ustvarjen nov račun z vašimi " +#~ "prijavnimi podatki.\n" +#~ "Prosimo, znova vnesite svoje geslo in kliknite \"Registriraj in prijavi " +#~ "se\", da potrdite ustvarjanje računa ali kliknite \"Prekliči\" za " +#~ "prekinitev." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Umrl si" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/sr_Cyrl/minetest.po b/po/sr_Cyrl/minetest.po new file mode 100644 index 0000000..f50dc7a --- /dev/null +++ b/po/sr_Cyrl/minetest.po @@ -0,0 +1,7256 @@ +msgid "" +msgstr "" +"Project-Id-Version: Serbian (cyrillic) (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-12 16:18+0000\n" +"Last-Translator: OrbitalPetrol <ccorporation981@gmail.com>\n" +"Language-Team: Serbian (cyrillic) <https://hosted.weblate.org/projects/" +"minetest/minetest/sr_Cyrl/>\n" +"Language: sr_Cyrl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Празна команда." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Врати се на главни мени" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Неважећа команда: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Издата команда: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Излистај мрежне играче" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Мрежни играчи: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Излазни ред са ћаскање је сада празан." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Ова команда није дозвољена од стране сервера." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Врати се у живот" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Умро си" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Доступне команде:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Доступне команде: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Команда није доступна: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Нађите помоћ за команде" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Користите '.help <komanda>' да бисте добили више информација или '.help all' " +"да бисте све набројали." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <команда>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "У реду" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<ни једна није доступна>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Догодила се грешка у Lua скрипти:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Догодила се грешка:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Главни мени" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Поновно повезивање" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Сервер тражи поновно повезивање:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Одабери свет:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Неслагање верзија протокола. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Сервер примењује $1 верзију протокола. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Сервер подржава верзије протокола између $1 и $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Ми подржавамо само $1 верзију протокола." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Ми подржавамо верзије протокола између верзије $1 и $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Прекини" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Зависи од:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Онемогући све" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Онемогући групу модова" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Укључи све" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Укључи групу модова" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Неуспело укључивање мода \"$1\" зато што садржи неподржане симболе.Само " +"симболи [a-z0-9_] су дозвољени." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Нађи још модова" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Мод:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Нема (необавезних) зависности" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Није пружен опис мода." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Нема обавезних зависности." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Није пружен опис групе модова." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Нема необавезних зависности" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Необавезне зависности:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Сачувај" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Свет:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "укључено" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" већ постоји. Да ли желите да га препишете?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$1 и $2 зависности ће бити инсталиране." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 од $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 се преузима,\n" +"$2 чекају преузимање" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 се преузима..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 неопходних зависности није могло бити нађено." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 зависности ће бити инсталирано, и $2 зависности ће бити прескочено." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Сви пакети" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Већ инсталирано" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Назад у главни мени" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Основна игра:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" +"ContentDB није доступан када је Minetest компајлиран без cURL библиотеке" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Преузимање..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Неуспело преузимање $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Игре" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Инсталирај" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Инсталирај $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Инсталирај недостајуће зависности" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "Инсталирај мод: неподржан тип фајла \"$1\" или оштећена архива" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Модови" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Ниједан пакет није било могуће преузети" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Нема резултата" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Нема ажурирања" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Није пронађено" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Препиши" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Молим проверите да ли је основна игра исправна." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "На чекању" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Сетови текстура" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Деинсталирај" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Ажурирај" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Ажурирај све [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Погледај још информација у веб претраживачу" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Свет \"$1\" већ постоји" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Додатни терен" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Висинска хладноћа" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Висинска сувоћа" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Склапање биома" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Биоми" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Пећине" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Јама" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Направи" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Украси" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Упозорење: Минимални развојни тест је намењен развијачима." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Тамнице" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Раван терен" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Плутајуће копнене масе на небу" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Floatlands (експериментални)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Створи нефрактални терен: Океани и подземље" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Брда" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Влажне реке" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Повећава влажност око река" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Инсталирај $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Језера" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Ниска влажност и велика врућина узрокују плитке или суве реке" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Генератор мапе" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Опције генератора мапа" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Специфичне опције генератора мапа" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Планине" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Проток блата" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Мрежа тунела и пећина" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Није одабрана игра" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Смањује топлоту висином" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Смањује влагу висином" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Реке" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Реке на нивоу мора" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Семе" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Глатка транзиција између биома" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Структуре које се појављују на терену (нема утицаја на дрвеће и траву џунгле " +"коју је створила v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Структуре које се појављују на терену, обично дрвеће и биљке" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Умерено, пустиња" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Умерено, пустиња, џунгла" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Умерено, пустиња, џунгла, тундра, тајга" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Ерозија површине терена" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Дрвеће и трава џунгле" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Варирај дубину реке" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Веома велике пећине дубоко у подземљу" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Име света" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Нема инсталираних подигара." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Да ли сте сигурни да желите да обришете \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Обриши" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: неуспело брисање \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: локација мода \"$1\" није валидна" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Обриши свет \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Потврди шифру" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "Нова шифра" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Шифре се не поклапају!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Прихвати" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Преименуј групу модова:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Ова група модова има специфично име дато у свом modpack.conf које ће " +"преписати било које име дато овде." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Није дат опис поставке)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "2D Noise" +msgstr "2D бука" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Назад на страну са поставкама" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Прегледај" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Настави" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Настави" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Онемогућено" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Промени" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Омогућено" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Лакунарност" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Октаве" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Помак" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Упорност" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Молим вас унесите дозвољен цео број." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Молим вас унесите валидан број." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Поврати подразумевано" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Скала" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Тражи" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Select directory" +msgstr "Изаберите фајл мода:" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Select file" +msgstr "Изаберите фајл мода:" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Прикажи техничка имена" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Вредност мора бити најмање $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Вредност не сме бити већа од $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "defaults" +msgstr "Уобичајена игра" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "$1 (Enabled)" +msgstr "Омогућено" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "$1 mods" +msgstr "Тродимензионални мод" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Неуспела инсталација $1 у $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Инсталирај мод: не може се пронаћи право име за: $1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Инсталирај мод: не може се пронаћи одговарајуће име за фасциклу мод-паковања " +"$1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to find a valid mod or modpack" +msgstr "" +"Инсталирај мод: не може се пронаћи одговарајуће име за фасциклу мод-паковања " +"$1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a $1 as a texture pack" +msgstr "Неуспела инсталација $1 у $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a game as a $1" +msgstr "Неуспела инсталација $1 у $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a mod as a $1" +msgstr "Неуспела инсталација $1 у $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a modpack as a $1" +msgstr "Неуспела инсталација $1 у $2" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Учитавање..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Покушајте да поновно укључите листу сервера и проверите вашу интернет " +"конекцију." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Активни сарадници" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Active renderer:" +msgstr "Даљина слања активног блока" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Главни развијачи" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Изаберите фајл мода:" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Предходни сарадници" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Предходни главни развијачи" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Content" +msgstr "Настави" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Disable Texture Pack" +msgstr "Одабери сет текстура:" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Information:" +msgstr "Информације о моду:" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Installed Packages:" +msgstr "Инсталирани модови:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Нема зависности." + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "No package description available" +msgstr "Није доступан опис мода" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Преименуј" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Uninstall Package" +msgstr "Уклони изабрани мод" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Use Texture Pack" +msgstr "Сетови текстура" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Пријави сервер" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Вежи адресу" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Слободни мод" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Омогући оштећење" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Направи игру" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Направи сервер" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Нови" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Ниједан свет није направљен или изабран!" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Play Game" +msgstr "Почни игру" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Порт" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "Одабери свет:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Одабери свет:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Серверски порт" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Start Game" +msgstr "Направи игру" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "- Адреса: " + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Очисти" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Слободни мод" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "Штета" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "Омиљени" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Join Game" +msgstr "Направи игру" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Одзив" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "Пријави сервер" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Обриши Омиљени" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "Серверски порт" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3Д Облаци" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "All Settings" +msgstr "Поставке" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Гланчање текстура:" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Autosave Screen Size" +msgstr "Аутоматски сачувај величину екрана" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Билинеарни филтер" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Подеси контроле" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Спојено стакло" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Елегантно лишће" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Мипмап" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Анизотропни филтер" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Без филтера" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Без Mipmap-а" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Истицање блокова" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Обцртавање блокова" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Ништа" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Непровидно лишће" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Непрозирна вода" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Честице" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Екран:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Поставке" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Шејдери" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Једноставно лишће" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Глатко осветљење" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Филтери за текстуре:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Тонско Мапирање" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Праг додиривања (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Трилинеарни филтер" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Лепршајуће лишће" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Liquids" +msgstr "Лепршајуће лишће" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Лепршајуће биљке" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Грешка у конекцији (истекло време?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Конекцији је истекло време." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Готово!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Припремам блокове" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Припремам блокове..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Учитавам текстуре..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Обнављам шејдере..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Грешка у конекцији (истекло време?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "Немогу пронаћи или учитати игру \"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Неважећи gamespec." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Главни мени" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" +"Ниједан свет није изабран и ниједна адреса није дата. Немогу ништа да урадим." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Име играча је предуачко." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Молим одаберите име!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Дата локација света не постоји: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Проверите debug.txt за више детаља." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Адреса: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Мод: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Порт: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Јавни: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- Играч против играча: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Име сервера: " + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Догодила се грешка:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward disabled" +msgstr "Кључ за синематски мод" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward enabled" +msgstr "Кључ за синематски мод" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Camera update disabled" +msgstr "Кључ за укључивање/искључивање освежавања камере" + +#: src/client/game.cpp +#, fuzzy +msgid "Camera update enabled" +msgstr "Кључ за укључивање/искључивање освежавања камере" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Промени шифру" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode disabled" +msgstr "Кључ за синематски мод" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode enabled" +msgstr "Кључ за синематски мод" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "Модификовање клијента" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Повезујем се на сервер..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Настави" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Уобичајене контроле:\n" +"- %s: иди напред\n" +"- %s: иди назад\n" +"- %s: иди лево\n" +"- %s: иди десно\n" +"- %s: скакање/пењање\n" +"- %s: шуњање/силажење\n" +"- %s: баци ставку\n" +"- %s: инвентар\n" +"- Миш: окретање/гледање\n" +"- Леви клик: копање/ударање\n" +"- Десни клик: постављање/коришћење\n" +"- Точкић миша: одабирање ставке\n" +"- %s: причање\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Правим клијента..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Правим сервер..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Debug info shown" +msgstr "Кључ за укључивање debug информација" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Подразумеване контроле:\n" +"Ни један приказан мени:\n" +"- један тап: копај\n" +"- дупли тап: постави блок/користи\n" +"- превуци прстом: гледај около\n" +"Мени/Инвертар приказан:\n" +"- дупли тап (изван):\n" +" -->Искључи\n" +"- додирни ствари, додирни празно место:\n" +" --> помери ствари\n" +"- држи и превлачи, тапни другим прстом:\n" +" --> пребаци само једну ствар из групе\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Правим клијента..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Изађи у мени" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Изађи из програма" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fast mode enabled" +msgstr "Оштећење омогућено" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode enabled" +msgstr "Оштећење омогућено" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog disabled" +msgstr "Онемогућено" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog enabled" +msgstr "укључено" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Информације о игри:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Игра паузирана" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Локални сервер" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Дефиниције предмета..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "КиБ/с" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Медија..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "МиБ/с" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "Један играч" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Noclip mode enabled" +msgstr "Оштећење омогућено" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Дефиниције блокова..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Искључено" + +#: src/client/game.cpp +msgid "On" +msgstr "Укључено" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Удаљен сервер" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Разлучујем адресу..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Искључивање..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Један играч" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Јачина звука" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound muted" +msgstr "Јачина звука" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound unmuted" +msgstr "Јачина звука" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Viewing range changed to %d" +msgstr "Јачина звука промењена на %d%%" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Јачина звука промењена на %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "уреду" + +#: src/client/gameui.cpp +#, fuzzy +msgid "Chat hidden" +msgstr "Кључ за чет" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Апликације" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Backspace" +msgstr "Назад" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Велика слова" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Контрола" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Доле" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Крај" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Избриши до краја поља" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Изврши" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Помоћ" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Кућа" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "ИМЕ Прихвати" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "ИМЕ Конвертуј" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "ИМЕ Побегни" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "ИМЕ Промена мода" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "ИМЕ Не конвертуј" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Убаци" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Лево" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Лево дугме" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Леви Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Леви мени" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Леви Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Леви Windows" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Мени" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Средње дугме" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Закључавање нумеричке тастатуре" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Нумеричка тастатура *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Нумеричка тастатура +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Нумеричка тастатура -" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad ." +msgstr "Нумеричка тастатура *" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Нумеричка тастатура /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Нумеричка тастатура 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Нумеричка тастатура 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Нумеричка тастатура 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Нумеричка тастатура 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Нумеричка тастатура 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Нумеричка тастатура 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Нумеричка тастатура 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Нумеричка тастатура 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Нумеричка тастатура 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Нумеричка тастатура 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "ОЕМ очисти" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Заустави" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Играј" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Прикажи" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Повратак" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Десно" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Десно дугме" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Десни Control" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Десни мени" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Десни Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Десни Windows" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Закључавање скроловања" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Одабери" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Шифт" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Спавај" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Сачувана слика" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Простор" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Таб" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Горе" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Дугме 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Дугме 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Зумирај" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Неуспело преузимање $1" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Настави" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "\"Користи\" = Силажење" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Autoforward" +msgstr "Напред" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Назад" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Change camera" +msgstr "Промени дугмад" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Чет" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Команда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Конзола" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Смањи звук" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Дупли скок за летење" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Бацање" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Напред" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Појачај звук" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Инвентар" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Скакање" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Дугме се већ користи" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Локална команда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Изкључи звук" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Next item" +msgstr "Следеће" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Претходно" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Одабир домета" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Шуњање" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle HUD" +msgstr "Укључи/Искључи летење" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle chat log" +msgstr "Укључи/Искључи трчање" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Укључи/Искључи трчање" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Укључи/Искључи летење" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle fog" +msgstr "Укључи/Искључи летење" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle minimap" +msgstr "Укључи/искључи пролажење кроз препреке" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Укључи/искључи пролажење кроз препреке" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle pitchmove" +msgstr "Укључи/Искључи трчање" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "притисните дугме" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Промени" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Нова шифра" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Стара шифра" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Шифре се не поклапају!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Изађи" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy +msgid "Muted" +msgstr "Изкључи звук" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Јачина звука: " + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "sr_Cyrl" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Молим одаберите име!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) офсет фрактала од центра света у мерној јединици 'скала'.\n" +"Користи се за пребацивање стартне позиције што ближе (0, 0).\n" +"Подразумевани је добар за манделброт сетове, али мора се наместити за јулија " +"сетове.\n" +"Даљина је око -2 до 2. Помножити са 'скалом' да би се добио офсет у " +"блоковима." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Тродимензионални облаци" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Тродимензионални мод" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3D подршка.\n" +"Тренутно подржано:\n" +"- none: Никакав тродимензионални излаз\n" +"- anaglyph: Цијан/Магента боја 3D\n" +"- interlaced: Парна/Непарна линија базирана поларизација\n" +"- topbottom: Подели екран горе/доле.\n" +"- sidebyside: Лево/Десно подела екрана.\n" +"- pageflip: Четвородупли буфер 3D." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Изабрано семе за нову мапу, оставите празно за насумично.\n" +"Биће преписано када се прави нови свет у менију." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Порука приказана свим играчима када се сервер обори." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Порука приказана свим играчима када се сервер искључи." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Absolute limit of queued blocks to emerge" +msgstr "Абсолутни лимит emerge токова." + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Убрзање у ваздуху" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Модификатори активног блока" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Active block management interval" +msgstr "Интервал менаџмента активног блока" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Даљина активног блока" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Даљина слања активног блока" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Адреса за конекцију.\n" +"Оставите ово празно за локални сервер.\n" +"Пазите да поље за адресу у менију преписује ово подешавање." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Додаје честице када се блок ископа." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Подеси dpi конфигурацију за твој екран (само за оне који нису X11/Android) " +"нпр. за 4k екране." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Име света" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Напредно" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Увек летење и брзина" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Јавни сервер" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Announce to this serverlist." +msgstr "Јавни сервер" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Насумично семе за генерисање јабукових дрвећа" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Питај за реконекцију после пада" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"При овој раздаљини сервер ће агресивно оптимизовати који блокови се шаљу " +"клијенту\n" +"Мање вредности ће потенцијално пролично побољшати преформансе, по цену " +"видљивих грешака на приказаној слици.\n" +"(неки блокови се неће приказивати под водом и у пећинама, као ни понеки на " +"земљи)\n" +"Постављање овога на вредност већу од max_block_send_distance искључује ову " +"оптимизацију.\n" +"Постављено у мапа-блоковима (16 блокова)" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatic forward key" +msgstr "Кључ за синематски мод" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatically report to the serverlist." +msgstr "Аутоматски пријави сервер-листи." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Аутоматски сачувај величину екрана" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Кључ за назад" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Basic privileges" +msgstr "Основне привилегије" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Семе за плаже" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Граница семена за плаже" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Билинеарно филтрирање" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Вежи адресу" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Параметри семена температуре и влажности API-ја за биоме" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Семе биома" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Градња унутар играча" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Уграђено" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Промени дугмад" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Изглађивање камере" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Изглађивање камере у синематском моду" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Кључ за укључивање/искључивање освежавања камере" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Семе пећина" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Семе пећина #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Семе пећина #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Ширина пећина" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Cave1 семе" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Cave2 семе" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Граница пећина" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Семе пећина" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Конус пећине" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Граница пећине" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern upper limit" +msgstr "Граница пећина" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "Граница пећине" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Чат команде" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat font size" +msgstr "Величина комада" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Кључ за чет" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat log level" +msgstr "Ниво записивања у debug" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat message format" +msgstr "Порука после пада" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat message kick threshold" +msgstr "Граница пећине" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Кључ за укључивање чета" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Величина комада" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Синематски мод" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Кључ за синематски мод" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Очисти провидне трекстуре" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Клијент" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Клијент и Сервер" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Модификовање клијента" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client side modding restrictions" +msgstr "Модификовање клијента" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Модификовање клијента" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Брзина успона" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Величина облака" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Облаци" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Облаци су ефекат од стране клијента." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Облаци у менију" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Обојена магла" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Colored shadows" +msgstr "Обојена магла" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Зарезом одвојена листа модова којима је дозвољено да приступе HTTP API-јима, " +"који\n" +"им дозвољавају да узимају и шаљу податке од/према интернету." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Зарезом одвојена листа поверених модова којима је дозвољено да приступе " +"несигурним\n" +"функцијама чак и када је сигурност модова укључена (путем " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Кључ за команду" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Споји стакло" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Споји са спољашњим медија сервером" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Спаја стакло ако је то подржано од стране блока." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Провидност козоле" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Боја конзоле" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Висина конзоле" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ContentDB URL" +msgstr "Настави" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Непрекидно напред" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Контроле" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Контролна дужина трајања даноноћног циклуса.\n" +"Примери: 72 = 20 минута, 360 = 4 минута, 1 = 24 сата, 0 = дан/ноћ/штагод " +"остаје непромењено." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Контролише стрмину/дубину језерских депресија." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Контролише стрмину/висину брда." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Порука после пада" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Креативни мод" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Провидност нишана" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "Провидност нишана (видљивост, између 0 и 255)." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Боја нишана" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Штета" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Кључ за укључивање debug информација" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Debug log file size threshold" +msgstr "Граница семена за плаже" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Ниво записивања у debug" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Корак на посвећеном серверу" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Уобичајено убрзање" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Уобичајена игра" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Уобичајена игра при стварању новог света.\n" +"Ово се може премостити при стварању новог света из главног менија." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Уобичајена лозинка" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Уобичајене привилегије" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Уобичајен формат рапорта" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default stack size" +msgstr "Уобичајена игра" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Украси" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Digging particles" +msgstr "Честице" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dungeon noise" +msgstr "Семе пећина" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Брзо кретање" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Видно поље за време увеличавања.\n" +"Ово захрева \"zoom\" привилегију на серверу." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Гланчање текстура:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland noise" +msgstr "Семе пећина" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Летење" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Игре" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ground noise" +msgstr "Семе пећина" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Height noise" +msgstr "Десни Windows" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Ако је укључено, можете стављати блокове унутар позиције где стојите.\n" +"Ово је корисно при раду са nodebox-евима у малим местима." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Глатко осветљење" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lower Y limit of floatlands." +msgstr "Абсолутни лимит emerge токова." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat" +msgstr "Генератор мапе" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal" +msgstr "Генератор мапе" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "Генератор мапе" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5" +msgstr "Генератор мапе" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6" +msgstr "Генератор мапе" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7" +msgstr "Генератор мапе" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Истицање блокова" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move key" +msgstr "Кључ за синематски мод" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Кључ за синематски мод" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Играч је у могућности д лети без утицаја гравитације.\n" +"Ово захтева \"fly\" привилегију на серверима." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Билинеарно филтрирање" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Regular font path" +msgstr "Одабери локацију за пријаве" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Одабери локацију за пријаве" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River noise" +msgstr "Семе пећина" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Екран:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Екран:" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Избор 18 фрактала из 9 формула.\n" +"1 = 4Д \"Округласти\" манделбротов скуп.\n" +"2 = 4Д \"Округласти\" жулијин скуп.\n" +"3 = 4Д \"Коцкасти\" манделбротов скуп.\n" +"4 = 4Д \"Коцкасти\" жулијин скуп.\n" +"5 = 4Д \"Mandy Cousin\" манделбротов скуп.\n" +"6 = 4Д \"Mandy Cousin\" жулијин скуп.\n" +"7 = 4Д \"Варијација\" манделбротов скуп.\n" +"8 = 4Д \"Варијација\" жулијин скуп.\n" +"9 = 3Д \"Mandelbrot/Mandelbar\" манделбротов скуп.\n" +"10 = 3Д \"Mandelbrot/Mandelbar\" жулијин скуп.\n" +"11 = 3Д \"Новогодишње Дрво\" манделбротоб скуп.\n" +"12 = 3Д \"Новогодишње Дрво\" жулијин скуп.\n" +"13 = 3Д \"Mandelbulb\" манделбротов скуп.\n" +"14 = 3Д \"Mandelbulb\" жулијин скуп.\n" +"15 = 3Д \"Косинусни Mandelbulb\" манделбротов скуп.\n" +"16 = 3Д \"Косинусни Mandelbulb\" жулијин скуп.\n" +"17 = 4Д \"Mandelbulb\" манделбротов скуп.\n" +"18 = 4Д \"Mandelbulb\" жулијин скуп." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Направи сервер" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "- Име сервера: " + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Серверски порт" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Серверски порт" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shader path" +msgstr "Шејдери" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed" +msgstr "Брзина успона" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Величина облака" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Поставке" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touch screen threshold" +msgstr "Граница семена за плаже" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Граница семена за плаже" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Upper Y limit of floatlands." +msgstr "Абсолутни лимит emerge токова." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Лепршајуће лишће" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Веслајућа вода" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Лепршајуће лишће" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Веслајућа вода" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "World start time" +msgstr "Име света" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Y of upper limit of large caves." +msgstr "Абсолутни лимит emerge токова." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Слободни мод: " + +#~ msgid "- Damage: " +#~ msgstr "- Оштећење: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = parallax occlusion са информацијама о нагибима (брже)\n" +#~ "1 = мапирање рељефа (спорије, прецизније)." + +#~ msgid "Address / Port" +#~ msgstr "Адреса / Порт" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Подеси осветљење унутар игре. Веће вредности су светлије.\n" +#~ "Ово подешавање је само за клијента, сервер га игнорише." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Да ли сте сигурни да желите да ресетујете ваш свет?" + +#~ msgid "Back" +#~ msgstr "Назад" + +#~ msgid "Basic" +#~ msgstr "Основно" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Битови по пикселу (или дубина боје) у моду целог екрана." + +#~ msgid "Bump Mapping" +#~ msgstr "Bump-Мапирање" + +#~ msgid "Bumpmapping" +#~ msgstr "Рељефна тектура" + +#~ msgid "Config mods" +#~ msgstr "Подеси модове" + +#~ msgid "Configure" +#~ msgstr "Подеси" + +#~ msgid "Connect" +#~ msgstr "Прикључи се" + +#, fuzzy +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Контролише густину планинског терена на лебдећим острвима.\n" +#~ "Као одступање се додаје на вредност 'np_mountain' семена." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "Контролише ширину тунела, мања вредност ствара шире тунеле." + +#~ msgid "Credits" +#~ msgstr "Заслуге" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Боја нишана (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Оштећење омогућено" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Преузми подигру, као што је minetest_game, са minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Преузми једну са minetest.net" + +#, fuzzy +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Преузима се $1, молим вас сачекајте..." + +#~ msgid "Enter " +#~ msgstr "Уреду " + +#~ msgid "Game" +#~ msgstr "Игра" + +#, fuzzy +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Инсталирај мод: фајл: \"$1\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Подешавање контрола.(Ако овај мени нешто поквари, обришите ствари из " +#~ "minetest.conf)" + +#~ msgid "Main" +#~ msgstr "Главно" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "Главни мени" + +#~ msgid "Name / Password" +#~ msgstr "Име / Шифра" + +#~ msgid "Name/Password" +#~ msgstr "Име/Шифра" + +#~ msgid "No" +#~ msgstr "Не" + +#~ msgid "Ok" +#~ msgstr "Уреду" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallax Occlusion Мапирање" + +#, fuzzy +#~ msgid "Parallax occlusion scale" +#~ msgstr "Parallax Occlusion Мапирање" + +#~ msgid "PvP enabled" +#~ msgstr "Туча омогућена" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Ресетуј свет" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "Изаберите фајл мода:" + +#, fuzzy +#~ msgid "Special key" +#~ msgstr "притисните дугме" + +#~ msgid "Start Singleplayer" +#~ msgstr "Започни игру за једног играча" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Да би се омогућили шејдери мора се користити OpenGL драјвер." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Укључи/Искључи Cinematic мод" + +#~ msgid "Yes" +#~ msgstr "Да" + +#~ msgid "You died." +#~ msgstr "Умро/ла си." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/sr_Latn/minetest.po b/po/sr_Latn/minetest.po new file mode 100644 index 0000000..91a698d --- /dev/null +++ b/po/sr_Latn/minetest.po @@ -0,0 +1,6875 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2020-08-15 23:32+0000\n" +"Last-Translator: Milos <milosfilic97@gmail.com>\n" +"Language-Team: Serbian (latin) <https://hosted.weblate.org/projects/minetest/" +"minetest/sr_Latn/>\n" +"Language: sr_Latn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.2-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Nazad na Glavni meni" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Vrati se u zivot" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Umro/la si." + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Doslo je do greske u Lua skripti:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Doslo je do greske:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Glavni meni" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Ponovno povezivanje" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Server je zahtevao ponovno povezivanje:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protokol verzija neuskladjena. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Server primenjuje protokol verzije $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Server podrzava protokol verzije izmedju $1 ili $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Mi samo podrzavamo protokol verzije $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Mi podrzavamo protokol verzija izmedju verzije $1 i $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Ponisti" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Zavisnosti:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Onemoguci sve" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Onemoguci modpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Omoguci sve" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Omoguci modpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Nije omogucen mod \"$1\" jer sadrzi nedozvoljene simbole. Samo simboli [a-z, " +"0-9_] su dozvoljeni." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Nadji jos modova" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Nema (opcionih) zavisnosti" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Opis igre nije prilozen." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Bez teskih zavisnosti" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Opis modpack-a nije prilozen." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Bez neobaveznih zavisnosti" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Neobavezne zavisnosti:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Sacuvaj" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Svet:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "Omoguceno" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "Preuzimanje..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Svi paketi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Nazad na Glavni meni" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB je nedostupan kada je Minetest sastavljen bez cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Preuzimanje..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Neuspelo preuzimanje $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Igre" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Instalirati" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "Instalirati" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "Neobavezne zavisnosti:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Modovi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Nema paketa za preuzeti" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Bez rezultata" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "No updates" +msgstr "Azuriranje" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Pakovanja tekstura" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Deinstaliraj" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Azuriranje" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Dodatni teren" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Nadmorska visina" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Visina suva" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Mesanje bioma" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biomi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Pecine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Pecine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekoracije" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Tamnice" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Ravan teren" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Lebdece zemaljske mase na nebu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Lebdece zemlje (eksperimentalno)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Stvaranje ne-fraktalnog terena: Okeani i podzemlje" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Brda" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Vlazne reke" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Povecana vlaznost oko reka" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Instalirati" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Jezera" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Niska vlaga i visoka toplota uzrokuju plitke ili suve reke" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Mapgen zastave" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Planine" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Protok blata" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Mreza tunela i pecina" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Smanjuje toplotu sa visinom" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Smanjuje vlaznost sa visinom" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Reke" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Reke na nivou mora" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Glatki prelaz izmedju bioma" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Konstrukcije koje se pojavljuju na terenu (nema efekta na drveca i travu " +"dzungle koje je stvorio v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Konstrukcije koje se pojavljuju na terenu , obicno drvece i biljke" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Umereno,Pustinja" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Umereno,Pustinja,Dzungla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Umereno,Pustinja,Dzungla,Tundra,Tajga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Povrsinska erozija terena" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Drveca i trava dzungle" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Razlicita dubina reke" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Veoma velike pecine duboko ispod zemlje" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Nema instaliranih igara." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Trazi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Ucitavanje..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Pokusajte ponovo omoguciti javnu listu servera i proverite vasu internet " +"vezu." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "Vlazne reke" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "Lebdece zemlje (eksperimentalno)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "" + +#: src/client/game.cpp +msgid "- Public: " +msgstr "" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Doslo je do greske:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Neuspelo preuzimanje $1" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "sr_Latn" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Dekoracije" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Igre" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Vlazne reke" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Preuzmi jednu sa minetest.net" + +#~ msgid "View" +#~ msgstr "Pogled" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Umro/la si." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/sv/minetest.po b/po/sv/minetest.po new file mode 100644 index 0000000..ccf9a1c --- /dev/null +++ b/po/sv/minetest.po @@ -0,0 +1,7332 @@ +msgid "" +msgstr "" +"Project-Id-Version: Swedish (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-24 09:25+0000\n" +"Last-Translator: ROllerozxa <temporaryemail4meh+github@gmail.com>\n" +"Language-Team: Swedish <https://hosted.weblate.org/projects/minetest/" +"minetest/sv/>\n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Rensa chattkön" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Tomt kommando." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Avsluta till huvudmeny" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Ogiltigt kommando: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Utfärdat kommando: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Lista över spelare online" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Spelare online: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Den utgående chattkön är nu tom." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Detta kommando är inaktiverat av servern." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Återuppstå" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Du dog" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Tillgängliga kommandon:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Tillgängliga kommandon: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Kommando inte tillgängligt: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Få hjälp med kommandon" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Använd '.help <cmd>' för att få mer information, eller '.help all' för att " +"visa allt." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<inget tillgängligt>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Ett fel uppstod i ett Lua-skript:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Ett fel uppstod:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Huvudmeny" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Återanslut" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Servern har begärt en återanslutning:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "En ny $1version är tillgänglig" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "Klientmoddar" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" +"Installerad version: $1\n" +"Ny version: $2\n" +"Besök $3 och se hur man får den nyaste versionen och håller en uppdaterad " +"med funktioner och buggfixar." + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "Senare" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "Aldrig" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protokollversionen matchar inte. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Servern tvingar protokollversion $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Servern stöder protokollversioner mellan $1 och $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "Besök hemsida" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Vi stöder endast protokollversion $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Vi stöder protokollversioner mellan version $1 och $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "(Aktiverad, har fel)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "(Ej nöjd)" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Avbryt" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Beroenden:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Avaktivera alla" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Avaktivera modpaket" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Aktivera allt" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Aktivera modpaket" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Misslyckades aktivera mod \"$1\" eftersom den innehåller otillåtna tecken. " +"Endast tecknen [a-z0-9_] är tillåtna." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Hitta Fler Moddar" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Inga (valfria) beroenden" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Ingen spelbeskrivning tillgänglig." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Inga hårda beroenden" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Ingen modpaketsbeskrivning tillgänglig." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Inga valfria beroenden" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Valfria beroenden:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Spara" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Värld:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "aktiverad" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" finns redan. Vill du skriva över den?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$1 och $2 beroende paket kommer installeras." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 till $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 laddas ner,\n" +"$2 köad" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 laddas ner..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 nödvändiga beroenden kunde inte hittas." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 kommer att installeras och $2 beroenden hoppas över." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Alla paket" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Redan installerad" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Tillbaka till huvudmeny" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Basspel:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB är inte tillgänglig när Minetest är kompilerad utan cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Laddar ner..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Misslyckades ladda ner $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Spel" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Installera" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Installera $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Installera saknade beroenden" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Installation: Filtyp stöds inte eller trasigt arkiv" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Moddar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Inga paket kunde hämtas" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Inga resultat" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Inga uppdateringar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Hittades inte" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Skriv över" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Var snäll se att basspelet är korrekt." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Köad" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Texturpaket" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Avnstallera" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Uppdatera" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Uppdatera Alla [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Visa mer information i en webbläsare" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "En värld med namnet \"$1\" finns redan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Ytterligare terräng" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Altitudkyla" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Altitudtorka" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Biotopblandning" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biotoper" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Grottor" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Grottor" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Skapa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekorationer" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "Development Test är avsett för utvecklare." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Fängelsehålor" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Platt terräng" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Svävande landmassor i himlen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Floatlands (experimentellt)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Generera icke-fraktal terräng: Oceaner och underjord" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Kullar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Fuktiga floder" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Ökar luftfuktigheten runt floderna" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "Installera ett spel" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "Installera ett annat spel" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Sjöar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Låg luftfuktighet och hög värme orsakar grunda eller torra floder" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Kartgenerator" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Kartgenerator-flaggor" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Kartgenerator-specifika flaggor" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Berg" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Lerflöde" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Nätverk med tunnlar och grottor" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Inget spel valt" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Minskar värmen efter höjd" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Minskar luftfuktigheten efter höjd" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Floder" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Havsnivåfloder" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Frö" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Smidig övergång mellan biotoper" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Strukturer som förekommer i terrängen (ingen effekt på träd och djungelgräs " +"som skapats av v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Strukturer som förekommer i terrängen, vanligtvis träd och växter" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Tempererad, Öken" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Tempererad, Öken, Djungel" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Tempererad, Öken, Djungel, Tundra, Tajga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Erosion av terrängytan" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Träd- och djungelgräs" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Varierande floddjup" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Mycket stora grottor djupt ner i underjorden" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Världnamn" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Du har inga spel installerade." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Är du säker på att du vill radera \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Ta bort" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: misslyckades att radera \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: ogiltig sökväg \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Radera värld \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Bekräfta Lösenord" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "Ansluter till $1" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "Namn saknas" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Namn" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Lösenord" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "Lösenorden passar inte" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "Registrera" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Acceptera" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Döp om modpaket:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Detta moddpaket har ett uttryckligt namn angett i modpack.conf vilket går " +"före namnändring här." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Ingen beskrivning av inställning angiven)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D-Brus" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Tillbaka till inställningssidan" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Bläddra" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "Innehåll: Spel" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "Innehåll: Moddar" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Inaktiverad" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Redigera" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Aktiverad" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Lacunaritet" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktaver" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Förskjutning" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Persistens" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Var vänligen ange ett giltigt heltal." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Var vänligen ange ett giltigt nummer." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Återställ till Ursprungsvärden" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Skala" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Sök" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Välj katalog" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Välj fil" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Visa tekniska namn" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Värdet måste minst $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Värdet får vara högst $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X-spridning" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y-spridning" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z-spridning" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "absolutvärde" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "standarder" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "lättad" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Aktiverad)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 moddar" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Misslyckades installera $1 till $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Moddinstallation: Lyckades ej hitta riktiga moddnamnet för: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "Moddinstallation: lyckas ej hitta lämpligt mappnamn för moddpaket $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Lyckades ej hitta lämplig modd eller moddpaket" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Misslyckades att installera $1 som ett texturpaket" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Misslyckades installera ett spel som en $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Misslyckades installera en modd som en $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Misslyckades installera moddpaket som en $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Laddar..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Den offentliga serverlistan är inaktiverad" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Försök återaktivera allmän serverlista och kolla din internetanslutning." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Om" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Aktiva bidragande" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Aktiv renderer:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Huvudutvecklare" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Öppna Användardatamappen" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Öppnar mappen som innehåller världar, spel, moddar,\n" +"och texturpaket i en filhanterare." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Före detta bidragande" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Före detta huvudutvecklare" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "Dela felsökningslogg" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Bläddra bland onlineinnehåll" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Innehåll" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Inaktivera Texturpaket" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Information:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Installerade paket:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Inga beroenden." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Ingen paketbeskrivning tillgänglig" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Byt namn" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Avinstallera Paket" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Använd Texturpaket" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Offentliggör Server" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Bindningsadress" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Kreativt läge" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Aktivera skada" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Hosta spel" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Hosta server" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Installera spel från ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Ny" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Ingen värld skapad eller vald!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Starta spel" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Välj moddar" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Välj värld:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Serverport" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Starta spel" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adress" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Rensa" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Kreativt läge" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Skada / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Favoriter" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Inkompatibla servrar" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Anslut till spel" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "Logga in" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Offentliga servrar" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Uppdatera" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "Radera favorit" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Serverbeskrivning" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "(kräver spelstöd)" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D-moln" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Alla inställningar" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Kantutjämning:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Spara fönsterstorlek automatiskt" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilinjärt filter" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Ändra Tangenter" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Sammanfogat glas" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dynamiska skuggor" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "Dynamiska skuggor:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Sofistikerade löv" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Hög" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Låg" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Medium" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Aniso-filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Inget filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Ingen Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Nodmarkering" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Nodkontur" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Inget" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Ogenomskinliga löv" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Ogenomskinligt vatten" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Partiklar" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Skärm:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Inställningar" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shaders" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Shaders (experimentella)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Shaders (otillgängliga)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Enkla löv" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Utjämnad Belysning" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Texturering:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Tonmappning" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "Touch-tröskel (px):" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Trilinjärt filter" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "Extremt hög" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Väldigt Låg" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Vajande löv" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Vajande vätskor" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Vajande växter" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "Anslutningsfel (protokollfel?)." + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Anslutningens tidsgräns nådd." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Klart!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Förbereder noder" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Förbereder noder..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Laddar texturer..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Rekonstruerar shaders..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Anslutningsfel (tidsgräns nådd?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Kunde inte hitta eller ladda spel: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Ogiltig spelspecifikation." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Huvudmeny" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Ingen värld vald och ingen adress anginven. Inget att göra." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Spelarnamn för långt." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Vänligen välj ett namn!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Den angivna lösenordsfilen kunde inte öppnas: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Angiven världssökväg existerar inte: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Se debug.txt för detaljer." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Bindningsadress: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Läge: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "Offentlig " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Servernamn: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Ett serialiseringsfel uppstod:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Åtkomst nekad. Anledning: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Automatiskt framåt inaktiverad" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Automatiskt framåt aktiverat" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Blockgränser dolda" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Blockgränser visas för alla block" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Blockgränser visas för det aktuella blocket" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Blockgränser visas för närliggande block" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Kamerauppdatering inaktiverad" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Kamerauppdatering aktiverat" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "Kan inte visa blockgränser (avaktiverad av modd eller spel)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Ändra lösenord" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Filmiskt länge inaktiverad" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Filmiskt länge aktiverat" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Klienten frånkopplades" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Klientsidiga skriptar är inaktiverade" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Ansluter till server..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Anslutningen misslyckades av okänd anledning" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Fortsätt" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Kontroller:\n" +"- %s: rör dig framåt\n" +"- %s: rör dig bakåt\n" +"- %s: rör dig åt vänster\n" +"- %s: rör dig åt höger\n" +"- %s: hoppa/klättra\n" +"- %s: gräv/slå\n" +"- %s: använd\n" +"- %s: smyg/rör dig nedåt\n" +"- %s: släpp föremål\n" +"- %s: förråd\n" +"- Mus: vänd/titta\n" +"- Mushjul: välj föremål\n" +"- %s: chatt\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Kunde inte lösa adressen: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Skapar klient..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Skapar server..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Felsökningsinfo och profileringsgraf gömd" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Felsökningsinfo visas" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Felsökningsinfo, profileringsgraf och wireframe gömd" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Standardkontroller:\n" +"Ingen meny syns:\n" +"- tryck en gång: aktivera knapp\n" +"- tryck två gånger: placera/använd\n" +"- dra finger: titta omkring\n" +"Meny/Förråd syns:\n" +"- tryck två gånger (utanför):\n" +" -->stäng\n" +"- rör trave, rör låda:\n" +" --> flytta trave\n" +"- tryck&dra, tryck med andra fingret\n" +" --> placera ett föremål i låda\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Inaktiverat obegränsat visningsområde" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Aktiverat obegränsat visningsområde" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "Fel vid skapande av klient: %s" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Avsluta till Meny" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Avsluta till OS" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Snabbt läge inaktiverat" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Snabbläge aktiverat" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Snabbt läge aktiverat (notera: inget 'fast'-tillstånd)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Flygläge inaktiverat" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Flygläge aktiverat" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Flygläge aktiverat (notera: inget 'fast'-tillstånd)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Dimma inaktiverad" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Dimma aktiverat" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Spelinformation:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Spel pausat" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Arrangerar server" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Föremålsdefinitioner..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Media..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Minimapp för närvarande inaktiverad av spel eller modd" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Flerspelarläge" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Noclipläge inaktiverat" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Noclipläge aktiverat" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Noclipläge aktiverat (notera: inget 'noclip'-tillstånd)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Noddefinitioner..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Av" + +#: src/client/game.cpp +msgid "On" +msgstr "På" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Höjdförändringsläge avaktiverad" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Höjdförändringsläge aktiverad" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profileringsgraf visas" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Avlägsen server" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Kollar upp address...." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Stänger av..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Enspelarläge" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Ljudvolym" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Ljudvolym avstängd" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Ljudsystem är inaktiverad" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Ljudsystem stöds inte i detta bygge" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Ljud påsatt" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Servern kör troligtvist en annan version av %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Kan inte ansluta till %s eftersom IPv6 är inaktiverad" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "Kan inte lyssna på %s eftersom IPv6 är inaktiverad" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Visningsområde ändrad till %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Visningsområde är vid sitt maximala: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Visningsområde är vid sitt minimala: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Volym ändrad till to %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Wireframe visas" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Zoom är för närvarande inaktiverad av spel eller modd" + +#: src/client/game.cpp +msgid "ok" +msgstr "ok" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Chatt gömd" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Chatt visas" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD gömd" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD visas" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profilering gömd" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profilering visas (sida %d av %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Appar" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Kontroll" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Ner" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Slut" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Radera EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Kör" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Hjälp" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Hem" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "Acceptera IME" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "Konvertera IME" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "Avbryt IME" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "Ändra IME Läge" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "Ickekonvertera IME" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Vänster" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Vänster Knapp" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Vänster Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Vänster Meny" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Vänster Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Vänster Windowstangent" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Meny" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Mittknappen" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Numpad *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Numpad +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numpad -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Numpad ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Numpad /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Numpad 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Numpad 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Numpad 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Numpad 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Numpad 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Numpad 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Numpad 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Numpad 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Numpad 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Numpad 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Rensa OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Sida ner" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Sida upp" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Paus" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Spela" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Skriv ut" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Retur" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Höger" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Höger Knapp" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Höger Control" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Höger Meny" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Höger Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Höger Windowstangent" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Välj" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Sov" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Snapshot" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Mellanslag" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Upp" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Knapp 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Knapp 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Zoom" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Minimapp gömd" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimapp i radarläge, Zoom x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimapp i ytläge, Zoom x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimapp i texturläge" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Misslyckades att öppna hemsida" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Öppnar hemsida" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Fortsätt" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = klättra neråt" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Autoframåt" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Automatiskt hopp" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Bakåt" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Blockgränser" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Ändra kamera" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Chatta" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Kommando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsol" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Min. räckvidd" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Sänk volym" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Dubbeltr. \"hoppa\" för att växla flygläge" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Släpp" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Framåt" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Höj räckvidd" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Öka volym" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Förråd" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Hoppa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Tangent används redan" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "Tagentbordsbindningar." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Lokalt kommando" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Tysta" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Nästa föremål" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Tidigare föremål" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Välj räckvidd" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Skärmdump" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Smyg" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Växla HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Växla chattlog" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Växla snabbläge" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Växla flygläge" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Växla dimma" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Växla minimapp" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Växla noclip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Växla höjdförändr." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "tryck på knapp" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Ändra" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nytt Lösenord" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Gammalt Lösenord" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Lösenorden matchar inte!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Avsluta" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Tyst" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Ljudvolym: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "sv" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" +"Namnet är inte registrerat. För att skapa ett konto på servern, tryck " +"'Registrera'" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "Namnet är redan taget. Var snäll välj ett annat namn" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Fastställer den virtuella joystickens position.\n" +"Om inaktiverad centreras den virtuella joysticken till det första " +"fingertryckets position." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Använd den virtuella joysticken för \"Aux1\"-knappen.\n" +"Om aktiverad kommer den virtuella joysticken att aktivera \"Aux1\"-knappen " +"när den är utanför huvudcirkeln." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) förskjutning av fraktal från världscenter i enheten 'skala'.\n" +"Kan användas för att förflytta en punkt till (0, 0) för att skapa en\n" +"passande spawnpunkt, eller för att tillåta inzoomning på en specifik\n" +"punkt genom att höja 'scale'.\n" +"Ursprungsvärdena passar en spawnpunkt för mandelbrotmängder,\n" +"den kan behöva ändras i andra situationer.\n" +"Värdegräns mellan -2 och 2. Multiplicera med 'skala för avvikelse\n" +"i noder." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z) fraktalens skala i noder.\n" +"Den riktiga storleken kommer att vara 2 till 3 gånger större.\n" +"Siffrorna kan göras mycket stora, men fraktalen\n" +"behöver inte rymmas i världen.\n" +"Öka dessa för att 'zooma' in i fraktalens detaljer.\n" +"Standardvärdet är för en vertikalt mosad form som passar för\n" +"en ö, ställ in alla 3 siffrorna lika för den ursprungliga formen." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2D-brus som styr formen/storleken på berg." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2D-brus som styr formen/storleken av rullande kullar." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2D-brus som styr formen/storleken på steppberg." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "2D-brus som styr storleken/förekomsten av bergskedjor med rågångar." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D-brus som styr storleken/förekomsten av rullande kullar." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "2D-brus som styr storleken/förekomsten av bergskedjor med rågångar." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2D-brus som lokaliserar floddalar och kanaler." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D-moln" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D-läge" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Parallaxstyrka i 3D-läge" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D oljudsdefinierade jättegrottor." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D oljudsdefinierade bergstrukturer och höjd.\n" +"Definierar också strukturen av bergsterrängen på luftöar." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"3D-brus som definierar strukturen hos floatlands.\n" +"Om det ändras från standardvärdet kan brusets 'skala' (vanligtvist 0.7) " +"behöva\n" +"justeras, eftersom avsmalningen av floatlands fungerar bäst när detta brus " +"har\n" +"ett värdeintervall på ungefär -2.0 till 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "3D oljudsdefiniering av strukturen av floddalsväggar." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3D brusdefinierad terräng." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "3D-brus för bergsöverhäng, klippor osv. Vanligtvist små variationer." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D-brus som bestämmer antalet fängelsehålor per mappchunk." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3D stöd.\n" +"Stöds för tillfället:\n" +"- inga: ingen 3d output.\n" +"- anaglyph: cyan/magenta färg 3d.\n" +"- interlaced: skärmstöd för ojämn/jämn linjebaserad polarisering.\n" +"- topbottom: split screen över/under.\n" +"- sidebyside: split screen sida vid sida.\n" +"- crossview: Korsögad 3d\n" +"- pageflip: quadbufferbaserad 3d.\n" +"Notera att 'interlaced'-läget kräver shaders." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "3D" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Ett valt kartfrö för en ny karta, lämnas tom för slumpmässig.\n" +"Kommer ersättas när ny värld skapas i huvudmenyn." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Ett meddelande som visas för alla klienter när servern krashar." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Ett meddelande som visas för alla klienter när servern stängs ner." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "ABM-intervall" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "ABM-tidsbudget" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Absolut gräns för köade block att framträda" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Acceleration i luften" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Accelerering av gravitation, i noder per sekund per sekund." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Aktiva Blockmodifierare" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Aktivt blockhanteringsintervall" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Aktiv blockräckvidd" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Aktivt avstånd för objektsändning" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Adress att koppla upp till.\n" +"Lämna detta tomt för att starta en lokal server.\n" +"Notera att adressen i fältet på huvudmenyn gör att denna inställning " +"ignoreras." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Lägger till partiklar när en nod grävs." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Justera dpi-konfigurationen för din skärm (endast icke X11/Android) t.ex. " +"för 4k-skärmar." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Justera den identifierade skärmdensiteten, vilket används för skalning av " +"gränssnittet." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Justerar tätheten hos floatlandslagret.\n" +"Öka värdet för att öka tätheten. Kan vara positiv eller negativ.\n" +"Värde = 0.0: 50% av volymen är floatland.\n" +"Värde = 2.0 (kan vara högre beroende på 'mgv7_np_floatland', testa alltid\n" +"för att vara säker) skapar ett fast floatlandslager." + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "Administratörsnamn" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Avancerat" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Ändrar ljuskurvan genom att tillämpa 'gammakorrigering' på den.\n" +"Högre värden leder till att de mellersta och lägre ljusnivåerna blir " +"ljusare.\n" +"Värdet '1.0' lämnar ljuskurvan oförändrad. Detta har endast betydande\n" +"effekt på dagsljus och konstgjort ljus, det har väldigt liten effekt på\n" +"naturligt nattljus." + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "Flyg alltid snabbt" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Ambient ocklusion gamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Antal meddelanden en spelare får skicka per 10 sekunder." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Amplifierar dalgångarna." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Anisotrop filtrering" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Offentliggör server" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Annonsera till serverlistan." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Infoga objektnamn" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Infoga objektnamn till verktygstips." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Äppelträdlojud" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Armtröghet" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Armtröghet, ger mer realistisk rörelse av armen\n" +"när kameran förflyttar sig." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Förfråga att återkoppla efter krash" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"Vid detta avstånd kommer servern att aggressivt optimera vilka block som " +"skickas till\n" +"klienterna.\n" +"Små värden kan potentiellt förbättra prestandan avsevärt, på bekostnaden av " +"synliga\n" +"renderingsglitchar (vissa block kommer inte att renderas under vatten och i " +"grottor,\n" +"ibland även på land).\n" +"Sätts detta till ett värde större än max_block_send_distance inaktiveras " +"denna\n" +"optimering.\n" +"Angiven i mapblocks (16 noder)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "Ljud" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Automatisk framåtknapp" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Hoppa automatiskt upp över enstaka noder hinder." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Rapportera automatiskt till serverlistan." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Spara fönsterstorlek automatiskt" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Automatiskt skalningsläge" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Aux1-knappen" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Aux1-knappen för klättring/sjunkning" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Bakåttangent" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Grundnivå" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Bas för terränghöjd." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Grundläggande privilegier" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Strandoljud" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Strandoljudströskel" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilinjär filtrering" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Bindesadress" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "API temperatur- och fuktighetsoljudsparametrar för biotoper" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Biotopoljud" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Distans för optimering av blockskickning" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "Guppande" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Fet och kursiv typsnittssökväg" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Fet och kursiv monospace-typsnittssökväg" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Fet typsnittssökväg" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Fet monospace-typsnittssökväg" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Bygg inuti spelare" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Inbyggd" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "Kamera" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Kameraavståndet 'nära urklippsplan' i noder, mellan 0 och 0.25\n" +"Fungerar bara på GLES-plattformar. De flesta användare behöver inte ändra " +"detta.\n" +"Ökning kan minska artefakter på svagare GPU:er.\n" +"0.1 = Standard, 0.25 = Bra värde för svagare tabletter." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Kamerautjämning" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Kamerautjämning i filmiskt läge" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Växeltagent för kamerauppdatering" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Grottoljud" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Grottoljud #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Grottoljud #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Grottbredd" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Grotta1 oljud" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Grotta2 oljud" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Grottbegränsning" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Grottoljud" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Grottavtagande" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Grottröskel" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Övre grottbegränsning" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Center för ljuskurvans förstärkningsområde.\n" +"0.0 är minsta ljusnivå, 1.0 är högsta ljusnivå." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Chattkommando tidströskel" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Chattkommandon" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Chattens typsnittsstorlek" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Chattangent" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Chattens loggnivå" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Gräns för antalet chattmeddelanden" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Chattmeddelandeformat" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Chattmeddelandens sparkningströskel" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Högsta längd för chattmeddelande" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Tagent för växling av chattangent" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Weblänkar i chatt" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Chunkstorlek" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Filmiskt läge" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Tangent för filmiskt länge" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Rena transparenta texturer" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Klickbara weblänkar (mellanklicka eller Ctrl+vänsterklicka) aktiverad i " +"chattkonsolens utdata." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Klient" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Klient och Server" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Klientmoddande" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Begränsningar för klientmoddning" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "Begränsing av klientsidig nodsökningsområde" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "Klientmoddande" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Klätterfart" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Molnradie" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Moln" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Moln är en effekt på klientsidan." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Moln i meny" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Färgad dimma" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Färgad dimma" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"Kommaseparerad lista av flaggar som ska döljas i innehållsdatabasen.\n" +"\"nonfree\" kan användas för att gömma paket som inte kvalifieras som 'fri " +"programvara',\n" +"per Free Software Foundations definition.\n" +"Du kan även specifiera innehållsvarningar.\n" +"Dessa flaggor är oberoende från Minetest-versioner,\n" +"så en full lista finns på https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Kommaseparerad lista av moddar som är tillåtna åtkomst till HTTP API:er, " +"vilket\n" +"tillåter dem att ladda upp och ned data till och från internet." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Kommaseparerad lista av tilltrodda moddar som är tillåtna åtkomst till " +"osäkra\n" +"funktioner även när modsäkerhet är på (via request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Kommandotangent" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Komprimeringsnivå att använda när mappblock sparas till disk.\n" +"-1 - använd standardnivå\n" +"0 - minst komprimering, snabbast\n" +"9 - bäst komprimering, långsammast" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Komprimeringsnivå att använda när mappblock skickas till klienten.\n" +"-1 - använd standardnivå\n" +"0 - minst komprimering, snabbast\n" +"9 - bäst komprimering, långsammast" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Sammankoppla glas" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Anslut till extern mediaserver" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Sammankopplar glas om noden stödjer det." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Konsolalpha" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Konsolfärg" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Konsolhöjd" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "Innehållsdatabas" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "ContentDB Flaggsvartlista" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "ContentDB Högsta Parallella Nedladdningar" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "ContentDB URL" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Fortlöpande framåt" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Kontinuerlig framåtgående rörelse, växlas med hjälp av autoforward-" +"tagenten.\n" +"Tryck på autoforward-knappen igen eller på bakåtknappen för att inaktivera." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Kontrollerar" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Kontrollerar längden av cyklerna för dag/natt.\n" +"Exempel:\n" +"72 = 20min, 360 = 4min, 1 = 24timme, 0 = dag/natt/någonting förblir " +"oförändrat." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" +"Styr hastigheten för sjunkande när man står stilla. Negativa värden leder " +"till att\n" +"du flyter upp istället." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Kontrollerar sluttningen/djupet av sjöfördjupningar." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Kontrollerar sluttningen/höjden av kullar." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Kontrollerar tunnlarnas bredd, ett mindre värde ger bredare tunnlar.\n" +"Värde >= 10.0 inaktiverar helt generering av tunnlar och undviker\n" +"intensiva brusberäkningar." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Krashmeddelande" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Kreativt" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Hårkorsalpha" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Hårkorsalpha (ogenomskinlighet, mellan 0 och 255).\n" +"Kontrollerar även objektets hårkorsfärg." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Hårkorsfärg" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Hårkorsfärg (R,G,B).\n" +"Styr även hårkorsets färg på objektet" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Skada" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Av/På tangent för debuginformation" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Felsökningslogg storlekströskel" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Nivå av debuglogg" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "Felsökning" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Tangent för volymsänkning" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Steg för dedikerad server" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Standardvärde för acceleration" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Standardspel" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Standardspel när ny värld skapas.\n" +"Detta kommer ersättas när en ny värld skapas ifrån huvudmenyn." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Standardslösenord" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Standardprivilegier" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Standardformat för rapporter" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Standardstapelstorlekar" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Definiera kvaliteten på skuggfiltrering.\n" +"Detta simulerar den mjuka skuggeffekten genom att tillämpa en PCF- eller " +"Poisson-skiva\n" +"men använder också mer resurser." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Definierar områden där träd har äpplen." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Definierar områden med sandstränder." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Definierar distribuering för högre terräng och sluttningen av klippor." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Definierar områden för högre terräng." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Definierar total storlek av grottor, mindre värden skapar större grottor." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Definierar strukturen för storskaliga älvkanaler." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "Definierar plats och terräng för valfria kullar och sjöar." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Definierar basnivån." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Definierar djupet av älvkanalen." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Definierar maximal distans för spelarförflyttning i block (0 = oändligt)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Definierar bredden för älvkanaler." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Definierar bredden för floddalar." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Definierar trädområden och trädtäthet." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"Fördröjning mellan meshuppdateringar hos klienten i ms. Att öka denna kommer " +"sakta\n" +"ner takten för meshuppdateringar och således reducera darr på långsammare " +"klienter." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Fördröjning av att skicka block efter byggande" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Fördröjning för att visa informationsrutor, i millisekunder." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Obruklig Lua API hantering" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Djup neråt där du kan hitta enorma grottor." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Djup inunder du kan hitta stora grottor." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Beskrivning av servern, visas på serverlistan och när spelare kommer in." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Oljudströskel för öken" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Öknar förekommer när np_biome överskrider detta värde.\n" +"Detta ignoreras när 'snowbiomes' flaggen är aktiverad." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Desynkronisera blockanimation" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "Utvecklarinställningar" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Gräv-knapp" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Grävpartiklar" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Inaktivera antifusk" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Tillåt inte tomma lösenord" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Skalningsfaktor för displaytäthet" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Domännamn för server, att visas i serverlistan." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Dubbeltryck på hoppknapp för att flyga" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Om du trycker på hoppknappen aktiveras flygläge." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Släpp objekt-tagent" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Dumpa felsökningsinformation för kartgeneratorn." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Maximalt Y för fängelsehålor" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Minimalt Y för fängelsehålor" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Grottbrus" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Aktivera IPv6-stöd (för både klient och server).\n" +"Krävs för att IPv6-anslutningar ska fungera." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Aktivera stöd för Lua-modifiering på klienten.\n" +"Detta är experimentellt och API:et kan ändras." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Aktivera Poisson-diskfiltrering.\n" +"När aktiverad används Poisson-disk för att göra \"mjuka skuggor\". Annars " +"används PCF-filtrering." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Aktivera färgade skuggor.\n" +"När aktiverad kastar genomskinliga noder färgade skuggor. Detta är intensivt." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Aktivera konsollfönster" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Aktivera kreativt läge för alla spelare" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Aktivera joysticks" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Aktivera stöd för mod-kanaler." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Aktivera modsäkerhet" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Gör det möjligt för spelare att skadas och dö." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Aktivera slumpmässig användarinmatning (används endast för testning)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Möjliggör mjuk belysning med enkel omgivande ocklusion.\n" +"Inaktivera för prestanda eller för ett annat utseende." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Aktivera för att hindra gamla klienter från att ansluta.\n" +"Äldre klienter är kompatibla i och med att de inte krashar när de ansluter\n" +"till nya servrar, men de kanske inte stöder alla nya funktioner du förväntar " +"dig." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Aktivera användning av fjärrmedieserver (om tillhandahålld av servern).\n" +"Fjärrservrar är ett betydligt snabbare sätt att hämta media (t.ex. " +"texturer)\n" +"när du ansluter till servern." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Aktivera vertexbuffertobjekt.\n" +"Detta bör avsevärt förbättra grafikprestandan." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Aktivera guppande och mängden guppande.\n" +"Till exempel: 0 för inget guppande, 1.0 för normalt, 2.0 för dubbla." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Aktivera/avaktivera en IPv6-server.\n" +"Ignoreras om bind_address är angedd.\n" +"Kräver att enable_ipv6 är aktiverat." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Aktiverar Hable's 'Uncharted 2' filmisk tonmappning.\n" +"Simulerar tonkurvan hos fotografisk film och hur den liknar utseendet\n" +"på bilder med högt dynamiskt omfång. Kontrasten i mitten av intervallet\n" +"förstärks något, ljuspunkter och skuggor komprimeras gradvis." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Aktiverar animering av lagerföremål." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Aktiverar cachning av facedirroterade mesher." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Aktiverar minimap." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Aktiverar ljudsystemet.\n" +"När inaktiverat inaktiveras alla ljud överallt och spelets\n" +"ljudkontroller kommer inte fungera.\n" +"Omstart krävs för att ändra den här inställningen." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"Aktiverar kompromisser som reducerar CPU-belastning eller förbättrar " +"prestanda\n" +"fast som introducerar små visuella fel som inte påverkar spelbarheten." + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Intervall för utskrift av motorprofileringsdata" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Entitetsmetoder" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS när ofokuserad eller pausad" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Faktorbrus" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Fallets bobbingfaktor" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Sökväg för reservtypsnitt" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Snabbknapp" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Acceleration i snabbt läge" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Hastighet i snabbt läge" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Snabb rörelse" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Snabb rörelse (via \"Aux1\"-tagenten).\n" +"Detta kräver \"snabb\"-privilegiet på servern." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Synfält" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Synfält i grader." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Filen i client/serverlist/ som innehåller dina favoritservrar som visas i\n" +"fliken Anslut Spel." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Fyllnadsdjup" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Fyllnadsdjupbrus" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Filmisk tonmappning" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "Filtrering och kantutjämning" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Första av 4 2D-brus som tillsammans definierar höjden på kullar och berg." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Första av två 3D-brus som tillsammans definierar tunnlar." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Fastställd kartseed" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Fast virtuell joystick" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Floatlanddensitet" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Floatlands högsta Y" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Floatlands minsta Y" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Floatlandbrus" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Floatlands avsmalningsexponent" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Floatlands avsmalningsdistans" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Floatlands vattennivå" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Flygknapp" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Flyga" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Dimma" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Start av dimma" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Växlingstagent för dimma" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "Typsnitt" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Fetstilat typsnitt som standard" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Kursivt typsnitt som standard" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Typsnittsskugga" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Genomskinlighet för typsnittsskugga" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Typsnittsstorlek" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "Typsnittsstorlek delbar med" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Storleken för standardtypsnittet där 1 enhet = 1 pixel när DPI är 96" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Storleken för monospacetypsnittet där 1 enhet = 1 pixel när DPI är 96" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Typsnittsstorlek för den senaste chattexten och chattprompten i punkter " +"(pt).\n" +"Värdet 0 använder standardstorleken." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Formatet för spelares chattmeddelanden. De följande strängar är giltiga " +"platshållare:\n" +"@name, @message, @timestamp (ej obligatoriskt)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Format för skärmdumpar." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Formspec Standardbakgrundsfärg" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Formspec Standardbakgrundsopacitet" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Formspec Standardbakgrundsfärg för fullskärm" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Formspec Standardbakgrundsopacitet för fullskärm" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Formspec Standardbakgrundsfärg (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Formspec standardbakgrundsopacitet (mellan 0 och 255)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Formspec bakgrundsfärg för fullskärm (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "Formspec bakgrundsopacitet för fullskärm (mellan 0 och 255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Framåtknapp" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Fyra av 4 2D-brus som tillsammans definerar höjden för kullar och berg." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Fraktaltyp" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Bråkdel av den synliga distansen som dimma börjar" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Hur långt bort block genereras för klienter, mätt i mappblock (16 noder)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Från hur långt block skickas till klienten, mätt i mappblock (16 noder)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Fullskärm" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Fullskärmsläge." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Gränssnittsskalning" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Filter för Gränssnittsskalning" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Filter för Gränssnittsskalning txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "Gamepads" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Globala återkallelser" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Globala kartgeneratorattribut.\n" +"I kartgeneratorn v6 kontrollerar 'decorations'-flaggan alla dekorationer " +"förutom träd\n" +"och djungelgräd, i alla andra kartgeneratorer styr flaggan alla dekorationer." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Gradienten av ljuskurvan vid högsta ljusnivå.\n" +"Styr kontrasten av de högsta ljusnivåerna." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Gradienten av ljuskurvan vid minsta ljusnivå.\n" +"Styr kontrasten av de minsta ljusnivåerna." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafik" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "Grafikeffekter" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "Grafik och ljud" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Gravitation" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Marknivå" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Ytbrus" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP-moddar" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "HUD-skalning" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "HUD-växlingsknapp" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Värmeblandingsbrus" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Värmebrus" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "Höjden av den inledande fönsterstorleken. Ignorerad i fullskärmsläge." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Höjdbrus" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Höjdvalbrus" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Kullslättning" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Kulltröskel" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Kullig1 brus" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Kullig2 brus" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Kullig3 brus" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Kullig4 brus" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Hemsida för servern, som visas i serverlistan." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Horisontell acceleration i luften vid hopp eller fall,\n" +"i noder per sekund per sekund." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Horisontell och vertikal acceleration i snabbläge,\n" +"i noder per sekund per sekund." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Horisontell och vertikal acceleration på marken eller klättrande\n" +"i noder per sekund per sekund." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Hur djupt floder ska gå." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Hur snabbt vätskevågor förflyttas. Högre = snabbare.\n" +"Om negativt kommer vågorna förflyttas bakåt.\n" +"Kräver vajande vätskor för att aktiveras." + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Hur länge servern kommer vänta innan den urladdar oanvända mappblock, i " +"sekunder.\n" +"Högre värde är smidigare, men använder mer RAM." + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" +"Hur mycket du saktas ner när du rör dig genom en vätska.\n" +"Minska detta för att öka vätskans motstånd mot rörelser." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Hur bred floder ska vara." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Luftfuktighetsblandbrus" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Luftfuktighetsbrus" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Variationen i luftfuktighet för biotoper." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6-server" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Om FPS skulle gå högre än detta begränsas den genom\n" +"att sova för att inte slösa på resurser utan någon anledning." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Om avaktiverad används \"Aux1\"-knappen för att flyga snabbt om både flyg- " +"och snabbläge\n" +"är aktiverade." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"När aktiverad är kontoregistrering separat från login i gränsnittet.\n" +"När inaktiverad registreras ett nytt konto automatiskt." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ignorera världfel" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Intervall för att skicka tiden på dagen för klienter, i sekunder." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "Belysning" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Vätskesjunkning" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Nedre Y-gräns för floatlands." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Mapgen Platt" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Mapgen Fraktal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Specifika flaggar för fraktal" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Kartgenerator V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Kartgenerator V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Kartgenerator V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "Moddsäkerhet" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "Nod- och väsenmarkering" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Placeraknapp" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Poissonfiltrering" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Flodbrus" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "Skärm" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "Skärmdumpar" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Val av 18 fraktaler.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "Server" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "Servergameplay" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "Serversäkerhet" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "Server/Miljöprestanda" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Shader-sökväg" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Smyghastighet" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Radie för mjuk skugga" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "Temporära inställningar" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Terränghöjd" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Tröskelvärde för pekskärm" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "Pekskärm" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Övre Y-gräns för floatlands." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Vajande vätskor" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Våghöjd för vajande vätskor" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Våghastighet för vajande vätskor" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Våglängd för vajande vätskor" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Världsstarttid" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Y-nivå för högre gräns av stora grottor." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Y-nivå för högre terräng som skapar klippor." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Y-nivå för lägre terräng och sjöbottnar." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Y-nivå av sjöbotten." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "cURL filhemladdning tidsgräns" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "cURL-interaktivtimeout" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "cURL parallellgräns" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Kreativt läge: " + +#~ msgid "- Damage: " +#~ msgstr "- Aktivera skada: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = parallax ocklusion med sluttningsinformation (snabbare).\n" +#~ "1 = reliefmappning (långsammare, noggrannare)." + +#~ msgid "Address / Port" +#~ msgstr "Adress / Port" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Justera gammakodningen för ljustabeller. Högre tal är ljusare.\n" +#~ "Denna inställning påverkar endast klienten och ignoreras av servern." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Är du säker på att du vill starta om din enspelarvärld?" + +#~ msgid "Back" +#~ msgstr "Tillbaka" + +#~ msgid "Basic" +#~ msgstr "Grundläggande" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Bits per pixel (dvs färgdjup) i fullskärmsläge." + +#~ msgid "Bump Mapping" +#~ msgstr "Stötkartläggning" + +#~ msgid "Bumpmapping" +#~ msgstr "Bumpmappning" + +#~ msgid "Config mods" +#~ msgstr "Konfigurera moddar" + +#~ msgid "Configure" +#~ msgstr "Konfigurera" + +#~ msgid "Connect" +#~ msgstr "Anslut" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Styr sjunkhastigheten i vätska." + +#, fuzzy +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Kontrollerar densiteten av luftöars bergsterräng.\n" +#~ "Är en förskjutning adderad till oljudsvärdet för 'np_mountain'." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Kontrollerar bredd av tunnlar, mindre värden skapar bredare tunnlar." + +#~ msgid "Credits" +#~ msgstr "Medverkande" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Hårkorsförg (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Skada aktiverat" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Standardtimeout för cURL, i millisekunder.\n" +#~ "Har bara en effekt om kompilerat med cURL." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Definierar områden för luftöars jämna terräng.\n" +#~ "Jämna luftöar förekommer när oljud > 0." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Definierar samplingssteg av textur.\n" +#~ "Högre värden resulterar i jämnare normalmappning." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Ladda ner ett spel, såsom Minetest Game, från minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Ladda ner ett från minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Laddar ner och installerar $1, vänligen vänta..." + +#~ msgid "Enable register confirmation" +#~ msgstr "Aktivera registreringsbekräftelse" + +#~ msgid "Enter " +#~ msgstr "Enter " + +#~ msgid "Filtering" +#~ msgstr "Filtrering" + +#~ msgid "FreeType fonts" +#~ msgstr "FreeType-typsnitt" + +#~ msgid "Game" +#~ msgstr "Spel" + +#~ msgid "HUD scale factor" +#~ msgstr "HUD-skalningsfaktor" + +#~ msgid "In-Game" +#~ msgstr "In-game" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Installera: fil: \"$1\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Tangentbindningar. (Om den här menyn strular, radera saker från minetest." +#~ "conf)" + +#~ msgid "Main" +#~ msgstr "Huvudsaklig" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "Huvudmeny" + +#~ msgid "Name / Password" +#~ msgstr "Namn / Lösenord" + +#~ msgid "Name/Password" +#~ msgstr "Namn/Lösenord" + +#~ msgid "No" +#~ msgstr "Nej" + +#~ msgid "Ok" +#~ msgstr "Ok" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parrallax Ocklusion" + +#, fuzzy +#~ msgid "Parallax occlusion scale" +#~ msgstr "Parrallax Ocklusion" + +#~ msgid "PvP enabled" +#~ msgstr "PvP aktiverat" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Starta om enspelarvärld" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "Välj modfil:" + +#, fuzzy +#~ msgid "Special key" +#~ msgstr "tryck på tangent" + +#~ msgid "Start Singleplayer" +#~ msgstr "Starta Enspelarläge" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "För att aktivera shaders behöver OpenGL-drivern användas." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Slå av/på Filmisk Kamera" + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Y-nivå till vilket luftöars skuggor når." + +#~ msgid "Yes" +#~ msgstr "Ja" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Du håller på att ansluta till den här servern med namnet \"%s\" för den " +#~ "första gången.\n" +#~ "Om du fortsätter kommer ett nytt konto med dina uppgifter skapas på " +#~ "servern.\n" +#~ "Var snäll och fyll i ditt lösenord och tryck på 'Registrera och Anslut' " +#~ "för att bekräfta kontoregistrering, eller tryck \"Avbryt\" för att " +#~ "avbryta." + +#~ msgid "You died." +#~ msgstr "Du dog." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/sw/minetest.po b/po/sw/minetest.po new file mode 100644 index 0000000..ef3a237 --- /dev/null +++ b/po/sw/minetest.po @@ -0,0 +1,8189 @@ +msgid "" +msgstr "" +"Project-Id-Version: Swahili (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: Swahili <https://hosted.weblate.org/projects/minetest/" +"minetest/sw/>\n" +"Language: sw\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.9-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Empty command." +msgstr "Amri majadiliano" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Exit to main menu" +msgstr "Toka kwenye menyu" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Invalid command: " +msgstr "Amri majadiliano" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "List online players" +msgstr "Singleplayer" + +#: builtin/client/chatcommands.lua +#, fuzzy +msgid "Online players: " +msgstr "Singleplayer" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Respawn" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Umekufa." + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands:" +msgstr "Amri majadiliano" + +#: builtin/common/chatcommands.lua +#, fuzzy +msgid "Available commands: " +msgstr "Amri majadiliano" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "An error occurred in a Lua script:" +msgstr "Kosa limetokea katika hati Lua, kama vile Moduli na:" + +#: builtin/fstk/ui.lua +#, fuzzy +msgid "An error occurred:" +msgstr "Kosa limetokea:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Menyu kuu" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Unganisha upya" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Seva imeomba na Unganisha upya:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Teua ulimwengu:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Itifaki ya toleo haifanani." + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Seva anahimiza itifaki toleo $1." + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Seva inasaidia matoleo ya itifaki kati ya $1 na $2." + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Sisi tu mkono itifaki toleo la $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Tunaunga mkono matoleo ya itifaki kati ya toleo la $1 na $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Katisha" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Mategemezi:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Lemeza yote" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "lemeza modpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Wezesha yote" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "Enable modpack" +msgstr "Ita jina jipya Modpack:" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Minetest imeshindwa kuwezesha moduli \"$1\" ila kuna vibambo zilizo " +"kataliwa. Tu vibambo [a-z0-9_] wanaruhusiwa." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Moduli:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No game description provided." +msgstr "Hakuna maelezo Moduli inapatikana" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No hard dependencies" +msgstr "Mategemezi:" + +#: builtin/mainmenu/dlg_config_world.lua +#, fuzzy +msgid "No modpack description provided." +msgstr "Hakuna maelezo Moduli inapatikana" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Hifadhi" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Ulimwengu:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "kuwezeshwa" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "$1 downloading..." +msgstr "Inapakia..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Already installed" +msgstr "Muhimu tayari katika matumizi" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Back to Main Menu" +msgstr "Menyu kuu" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Base Game:" +msgstr "Ficha mchezo" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Downloading..." +msgstr "Inapakia..." + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Failed to download $1" +msgstr "Imeshindwa kusakinisha $1 hadi $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Michezo" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Sakinisha" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install $1" +msgstr "Sakinisha" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install missing dependencies" +msgstr "Inaanzilisha fundo" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "" +"\n" +"Sakinisha Moduli: filetype visivyotegemezwa \"$1\" au nyaraka kuvunjwa" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mods" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Texture packs" +msgstr "Texturepacks" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Uninstall" +msgstr "Sakinisha" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Ulimwengu inayoitwa \"$1\" tayari ipo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Altitude chill" +msgstr "Chill ya mwinuko" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Altitude dry" +msgstr "Chill ya mwinuko" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biome blending" +msgstr "Kelele za mto" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biomes" +msgstr "Kelele za mto" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caverns" +msgstr "Pango kelele #1" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Caves" +msgstr "Pango kelele #1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Kuunda" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Decorations" +msgstr "Instrumentation" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Tahadhari: Mtihani wa maendeleo ndogo ni maana kwa watengenezaji." + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Dungeons" +msgstr "Kelele za mto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Floatlands (experimental)" +msgstr "Kiwango cha maji" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Humid rivers" +msgstr "Kiendeshaji video" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "Sakinisha" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Mwandishi ramani" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Bendera ya Mwandishi ramani" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mapgen-specific flags" +msgstr "Mwandishi ramani v6 bendera" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mountains" +msgstr "Mwandishi ramani v7 mlima urefu kelele vigezo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "No game selected" +msgstr "Teua masafa" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Rivers" +msgstr "Ukubwa wa mto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Mbegu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Terrain surface erosion" +msgstr "Urefu wa ardhi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Vary river depth" +msgstr "Kina wa mto" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Jina la ulimwengu" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "You have no games installed." +msgstr "Una subgames hakuna imewekwa." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Una uhakika unataka kufuta \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Futa" + +#: builtin/mainmenu/dlg_delete_content.lua +#, fuzzy +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "Modmgr: imeshindwa kufuta \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +#, fuzzy +msgid "pkgmgr: invalid path \"$1\"" +msgstr "Modmgr: batili modpath \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Futa ulimwengu \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Thibitisha nywila" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Mwandishi ramani jina" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Password" +msgstr "Nywila mpya" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "MaNenotambulishi hayaoani!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Kukubali" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Ita jina jipya Modpack:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Hakuna maelezo ya kuweka kupewa)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "2D Noise" +msgstr "Kila" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Vinjari" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "Kuendelea" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "Kuendelea" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Walemavu" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Hariri" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Kuwezeshwa" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Lacunarity" +msgstr "Usalama" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "Umbali wa uhamisho wa mchezaji" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Tafadhali ingiza namba kamili halali." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Tafadhali ingiza namba halali." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Rejesha chaguo-msingi" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Utafutaji" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Select directory" +msgstr "Orodha ya ramani" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Select file" +msgstr "Teua faili ya Moduli:" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Onyesha majina ya kiufundi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "The value must be at least $1." +msgstr "Thamani lazima iwe kubwa kuliko $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "The value must not be larger than $1." +msgstr "Thamani lazima iwe chini kuliko $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "defaults" +msgstr "Chaguo-msingi mchezo" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "$1 (Enabled)" +msgstr "Kuwezeshwa" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "$1 mods" +msgstr "Hali ya 3D" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Imeshindwa kusakinisha $1 hadi $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Sakinisha Moduli: haiwezi kupata modname halisi kwa: $1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Sakinisha Moduli: haiwezi kupata foldername ya kufaa kwa ajili ya modpack $1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to find a valid mod or modpack" +msgstr "" +"Sakinisha Moduli: haiwezi kupata foldername ya kufaa kwa ajili ya modpack $1" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a $1 as a texture pack" +msgstr "Imeshindwa kusakinisha $1 hadi $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a game as a $1" +msgstr "Imeshindwa kusakinisha $1 hadi $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a mod as a $1" +msgstr "Imeshindwa kusakinisha $1 hadi $2" + +#: builtin/mainmenu/pkgmgr.lua +#, fuzzy +msgid "Unable to install a modpack as a $1" +msgstr "Imeshindwa kusakinisha $1 hadi $2" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Inapakia..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "Jaribu reenabling serverlist umma na Kagua muunganisho wako wa tovuti." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Wachangiaji amilifu" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Active renderer:" +msgstr "Kiolwa amilifu Tuma masafa" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Watengenezaji wa msingi" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Open User Data Directory" +msgstr "Orodha ya ramani" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Wachangiaji wa awali" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Awali msingi watengenezaji" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Onyesha maelezo kuhusu marekebisho" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Content" +msgstr "Kuendelea" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Disable Texture Pack" +msgstr "Chagua Kipeto cha unamu:" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Information:" +msgstr "Taarifa Moduli:" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Installed Packages:" +msgstr "Mods zilizosakinishwa:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "No package description available" +msgstr "Hakuna maelezo Moduli inapatikana" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Ita jina jipya" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Uninstall Package" +msgstr "Sakinusha Moduli teuliwa" + +#: builtin/mainmenu/tab_content.lua +#, fuzzy +msgid "Use Texture Pack" +msgstr "Texturepacks" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Announce Server" +msgstr "Kutangaza seva" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Kumfunga anwani" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Hali ya ubunifu" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Wezesha uharibifu" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Host Game" +msgstr "Ficha mchezo" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Host Server" +msgstr "Seva" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Mpya" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Duniani hakuna kuundwa au kuteuliwa!" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Play Game" +msgstr "Jina la mchezaji" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Bandari" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Select Mods" +msgstr "Teua ulimwengu:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Teua ulimwengu:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Kituo tarishi cha seva" + +#: builtin/mainmenu/tab_local.lua +#, fuzzy +msgid "Start Game" +msgstr "Ficha mchezo" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Address" +msgstr "Kumfunga anwani" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Wazi" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Hali ya ubunifu" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Damage / PvP" +msgstr "Uharibifu" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Favorites" +msgstr "Kipendwa" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Join Game" +msgstr "Ficha mchezo" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Public Servers" +msgstr "Kutangaza seva" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Bandari ya mbali" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Server Description" +msgstr "Maelezo ya seva" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2 x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Mawingu ya 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4 x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8 x" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "All Settings" +msgstr "Vipimo vya" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Antialiasing:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Kichujio bilinear" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Badilisha funguo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Kioo kushikamana" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Dynamic shadows" +msgstr "Kivuli cha fonti" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Kivuli cha fonti" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Majani ya dhana" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Aniso. Kichujio" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Kichujio hakuna" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Hakuna Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Fundo udhulisho" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Fundo Ufupisho" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Hakuna" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Majani opaque" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Maji opaque" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Chembe" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Screen:" +msgstr "Screenshot" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Vipimo vya" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Shaders" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Shaders (experimental)" +msgstr "Kiwango cha maji" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Rahisi majani" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Taa laini" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Texturing:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Ramani ya toni" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Touchthreshold (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Kichujio trilinear" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Waving majani" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Waving Liquids" +msgstr "Waving fundo" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Waving mimea" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Kosa la muunganisho (wakati muafaka?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Muunganisho limekatika." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Kufanyika!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Inaanzilisha fundo" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Inaanzilisha fundo..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Kupakia unamu..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Kuijenga upya shaders..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Kosa la muunganisho (wakati muafaka?)" + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Could not find or load game: " +msgstr "Haikuweza kupata wala kupakia mchezo\"" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Gamespec batili." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Menyu kuu" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" +"Duniani hakuna iliyoteuliwa na hakuna anwani iliyotolewa. Kitu cha kufanya." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Mchezaji jina refu." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Njia ya dunia iliyotolewa haipo:" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Angalia debug.txt kwa maelezo." + +#: src/client/game.cpp +#, fuzzy +msgid "- Address: " +msgstr "Kumfunga anwani" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "- Port: " +msgstr "Bandari" + +#: src/client/game.cpp +#, fuzzy +msgid "- Public: " +msgstr "Umma" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "- Server Name: " +msgstr "Jina la seva" + +#: src/client/game.cpp +#, fuzzy +msgid "A serialization error occurred:" +msgstr "Kosa limetokea:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward disabled" +msgstr "Ufunguo wa mbele" + +#: src/client/game.cpp +#, fuzzy +msgid "Automatic forward enabled" +msgstr "Ufunguo wa mbele" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Camera update disabled" +msgstr "Kibonye guro Usasishaji wa kamera" + +#: src/client/game.cpp +#, fuzzy +msgid "Camera update enabled" +msgstr "Kibonye guro Usasishaji wa kamera" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Badilisha nywila" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode disabled" +msgstr "Hali ya cinematic ufunguo" + +#: src/client/game.cpp +#, fuzzy +msgid "Cinematic mode enabled" +msgstr "Hali ya cinematic ufunguo" + +#: src/client/game.cpp +#, fuzzy +msgid "Client disconnected" +msgstr "Mteja" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Inaunganisha seva..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Kuendelea" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Vidhibiti vya chaguo-msingi:\n" +"-WASD: hoja\n" +"- nafasi: kuruka/kupanda\n" +"- Hamisha:taarifa/kwenda chini\n" +"- q: tone kipengee\n" +"- nikasema hesabu\n" +"- kipanya: kugeuka/kuangalia\n" +"- kipanya kushoto: kuchimba/punch\n" +"- kipanya kulia: mahali/matumizi\n" +"- kipanya gurudumu: Teua kipengee\n" +"- T: mazungumzo\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Inaunda mteja..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Inaunda seva..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Debug info shown" +msgstr "Rekebisha taarifa kibonye" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Vidhibiti vya chaguo-msingi:\n" +"Hakuna Menyu kuonekana:\n" +"- bomba moja: kitufe kuamilisha\n" +"- mara mbili bomba: mahali/matumizi\n" +"- slaidi kidole: kuangalia kote\n" +"Menyu/hesabu dhahiri:\n" +"- mara mbili bomba (nje):--> Funga - kugusa \n" +"mpororo, kugusa mpenyo:--> hoja mpororo\n" +"- kugusa & buruta, bomba kidole 2--> \n" +"kipengee kimoja mahali kwa yanayopangwa\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "Inaunda mteja..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Toka kwenye menyu" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Toka kwa OS" + +#: src/client/game.cpp +#, fuzzy +msgid "Fast mode disabled" +msgstr "Kasi ya hali ya haraka" + +#: src/client/game.cpp +#, fuzzy +msgid "Fast mode enabled" +msgstr "Kasi ya hali ya haraka" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode disabled" +msgstr "Kasi ya hali ya haraka" + +#: src/client/game.cpp +#, fuzzy +msgid "Fly mode enabled" +msgstr "Uharibifu kuwezeshwa" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog disabled" +msgstr "Walemavu" + +#: src/client/game.cpp +#, fuzzy +msgid "Fog enabled" +msgstr "kuwezeshwa" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Game paused" +msgstr "Michezo" + +#: src/client/game.cpp +#, fuzzy +msgid "Hosting server" +msgstr "Inaunda seva..." + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Fasili ya kipengele..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "Kibu/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Vyombo vya habari..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Multiplayer" +msgstr "Singleplayer" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Noclip mode enabled" +msgstr "Uharibifu kuwezeshwa" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Fundo Fasili..." + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Remote server" +msgstr "Bandari ya mbali" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Kusuluhisha anwani..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Inazima..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Singleplayer" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Kiwango cha sauti" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound muted" +msgstr "Kiwango cha sauti" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +#, fuzzy +msgid "Sound unmuted" +msgstr "Kiwango cha sauti" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Viewing range changed to %d" +msgstr "Kuonyesha masafa" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "Sawa kabisa" + +#: src/client/gameui.cpp +#, fuzzy +msgid "Chat hidden" +msgstr "Ufunguo wa mazungumzo" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +#, fuzzy +msgid "Profiler hidden" +msgstr "Profiler" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Programu" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Backspace" +msgstr "Nyuma" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Udhibiti" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Chini" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Mwisho" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Erase EOF" +msgstr "Futa OEF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Kutekeleza" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Msaada" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Nyumbani" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Accept" +msgstr "Kukubali" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Convert" +msgstr "Geuza" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Escape" +msgstr "Kutoroka" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Mode Change" +msgstr "Mabadiliko ya hali ya" + +#: src/client/keycode.cpp +#, fuzzy +msgid "IME Nonconvert" +msgstr "Nonconvert" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Chomeka" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Kushoto" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Kitufe kushoto" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Udhibiti wa kushoto" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menyu ya kushoto" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Kisogezi kushoto" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Windows kushoto" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menyu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Kitufe kati" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Kinanda *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Kinanda +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Numpad-" + +#: src/client/keycode.cpp +#, fuzzy +msgid "Numpad ." +msgstr "Kinanda *" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Kinanda /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Kinanda 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Kinanda 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Kinanda 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Kinanda 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Kinanda 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Kinanda 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Kinanda 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Kinanda 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Kinanda 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Kinanda 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Wazi ya OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Sitisha" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Kucheza" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Chapa" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Kurudi" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Kulia" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Kitufe kulia" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Udhibiti sahihi" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menyu kulia" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Kisogezi kulia" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Windows kulia" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Teua" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Usingizi" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Taswira tuli" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Nafasi" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Kichupo" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Juu" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X kitufe 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X kitufe 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Kuza" + +#: src/client/minimap.cpp +#, fuzzy +msgid "Minimap hidden" +msgstr "Ufunguo wa minimap" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, fuzzy +msgid "Minimap in texture mode" +msgstr "Unamu wa kima cha chini cha ukubwa wa Vichujio" + +#: src/gui/guiChatConsole.cpp +#, fuzzy +msgid "Failed to open webpage" +msgstr "Imeshindwa kusakinisha $1 hadi $2" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Kuendelea" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "\"Aux1\" = climb down" +msgstr "\"Matumizi\" = kupanda chini" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Autoforward" +msgstr "Mbele" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Nyuma" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Change camera" +msgstr "Badilisha funguo" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Kuzungumza" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Amri" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Kiweko" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Dec. range" +msgstr "Kuonyesha masafa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Mara mbili bomba \"Ruka\" hadi Togo kuruka" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Achia" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Mbele" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Inc. range" +msgstr "Kuonyesha masafa" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Inc. volume" +msgstr "Kiwango cha sauti" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Hesabu" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Kuruka" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Muhimu tayari katika matumizi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Local command" +msgstr "Amri majadiliano" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Next item" +msgstr "Ijayo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Teua masafa" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Screenshot" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Taarifa" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle HUD" +msgstr "Togoa kuruka" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle chat log" +msgstr "Togoa haraka" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Togoa haraka" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Togoa kuruka" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle fog" +msgstr "Togoa kuruka" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle minimap" +msgstr "Togoa noclip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Togoa noclip" + +#: src/gui/guiKeyChangeMenu.cpp +#, fuzzy +msgid "Toggle pitchmove" +msgstr "Togoa haraka" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "Bonyeza Kibonye" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Mabadiliko" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Nywila mpya" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Nywila ya zamani" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "MaNenotambulishi hayaoani!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Toka" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy +msgid "Muted" +msgstr "Ufunguo wa matumizi" + +#: src/gui/guiVolumeChange.cpp +#, fuzzy, c-format +msgid "Sound Volume: %d%%" +msgstr "Kiwango sauti:" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "sw" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X, Y, Z) fidia ya fractal kutoka kituo cha dunia katika vitengo vya " +"'kipimo'.\n" +"Kutumika ili kuhamisha eneo la spawn ya kufaa ya ardhi chini karibu (0, 0).\n" +"Chaguo-msingi ni mzuri kwa ajili ya seti ya mandelbrot, inahitaji kuhaririwa " +"kwa ajili ya julia seti.\n" +"Masafa ya takribani-2 hadi 2. Kuzidisha kwa 'Skeli' kwa Sawazisha katika " +"fundo." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Mawingu ya 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Hali ya 3D" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "3D mode parallax strength" +msgstr "Nguvu ya Normalmaps" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Msaada ya 3D.\n" +"Tegemeza kwa sasa:-Hakuna: Hakuna towe 3d.\n" +"-anaglyph: Bluu-kijani/rangi nzee rangi 3d.\n" +"-sokotana: witiri/shufwa mstari msingi polarisation kiwamba msaada.\n" +"-topbottom: Baidisha skrini juu/chini.\n" +"-sidebyside: Baidisha skrini upande kwa upande.\n" +"-pageflip: quadbuffer msingi 3d." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Mbegu ramani waliochaguliwa kwa ajili ya ramani mpya, kuondoka tupu kwa " +"nasibu.\n" +"Itakuwa kuuharibu wakati wa kuunda dunia mpya katika Menyu kuu." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Ujumbe kuonyeshwa kwa wateja wote wakati seva yaanguka." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Ujumbe kuonyeshwa kwa wateja wote wakati seva huzima." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ABM interval" +msgstr "Ramani hifadhi muda" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Absolute limit of queued blocks to emerge" +msgstr "Kikomo halisi ya foleni ya emerge" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Kuongeza kasi katika hewa" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Modifiers fungu amilifu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Active block management interval" +msgstr "Nafasi kazi ya usimamizi wa umbo" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Masafa ya fungu amilifu" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Kiolwa amilifu Tuma masafa" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Anwani ya kuunganishwa.\n" +"Acha hii wazi kuanzisha seva ya ndani.\n" +"Kumbuka kwamba uga wa anwani katika Menyu kuu Puuza kipimo hiki." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Rekebisha usakinishaji wa dpi kwenye kiwamba chako (yasiyo X11/Android tu) " +"mfano kwa 4 k skrini." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Jina la ulimwengu" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Pevu" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Daima kuruka na kufunga" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Occlusion iliyoko gamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Amplifies the valleys." +msgstr "Inaangazia mabonde" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Uchujaji wa anisotropic" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Kutangaza seva" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Announce to this serverlist." +msgstr "Kutangaza seva" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Uliza kuunganisha baada ya ajali" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatic forward key" +msgstr "Ufunguo wa mbele" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Automatically report to the serverlist." +msgstr "Automaticaly ripoti ya serverlist." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key" +msgstr "Ufunguo wa kuruka" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Aux1 key for climbing/descending" +msgstr "Matumizi muhimu kwa ajili ya kupanda/kushuka" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Ufunguo wa nyuma" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Base ground level" +msgstr "Mwandishi ramani gorofa ngazi ya chini" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Base terrain height." +msgstr "Mandhari ya msingi urefu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Basic privileges" +msgstr "Haki za msingi" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Uchujaji wa bilinear" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Kumfunga anwani" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Mwandishi ramani v6 unyevu kelele vigezo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome noise" +msgstr "Kelele za mto" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Block send optimize distance" +msgstr "Umbo la Max Tuma umbali" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bold and italic font path" +msgstr "Monospace njia ya fonti" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bold and italic monospace font path" +msgstr "Monospace njia ya fonti" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bold font path" +msgstr "Njia ya fonti" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Bold monospace font path" +msgstr "Monospace njia ya fonti" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Kujenga ndani ya mchezaji" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Pamoja" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Badilisha funguo" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Kamera unyooshaji" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Kamera unyooshaji hali cinematic" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Kibonye guro Usasishaji wa kamera" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave noise" +msgstr "Pango kelele #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Pango kelele #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Pango kelele #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Pango upana" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave1 noise" +msgstr "Pango kelele #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cave2 noise" +msgstr "Pango kelele #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern limit" +msgstr "Pango upana" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern noise" +msgstr "Pango kelele #1" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern threshold" +msgstr "Kilele cha mlima gorofa Mwandishi ramani" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Cavern upper limit" +msgstr "Pango upana" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "Kilele cha mlima gorofa Mwandishi ramani" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat commands" +msgstr "Amri majadiliano" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat font size" +msgstr "Ukubwa wa fonti" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Ufunguo wa mazungumzo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat log level" +msgstr "Rekebisha kiwango cha logi" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat message format" +msgstr "Ajali ujumbe" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat message kick threshold" +msgstr "Kilele cha mlima gorofa Mwandishi ramani" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Kibonye guro wa mazungumzo" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Ukubwa wa fungu" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Hali ya cinematic" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Hali ya cinematic ufunguo" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Unamu angavu safi" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Mteja" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Mteja na seva" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client modding" +msgstr "Mteja" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client side modding restrictions" +msgstr "Mteja" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Mteja" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Kasi ya upandaji" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Wingu eneo" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Mawingu" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Mawingu ni mteja upande athari." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Mawingu katika Menyu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Ukungu wa rangi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Colored shadows" +msgstr "Ukungu wa rangi" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Iliyotenganishwa orodha ya mods kwamba wanaruhusiwa kufikia HTTP APIs, " +"ambayo kuwaruhusu kupakia na kupakua data/toka kwenye tovuti." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Iliyotenganishwa orodha ya mods kuaminika kwamba wanaruhusiwa kufikia kazi " +"zisizo hata wakati usalama Moduli ni juu (kupitia " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Ufunguo wa amri" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Kuunganisha kioo" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Unganisha kwenye seva ya midia za nje" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Huunganisha kioo kama mkono na fundo." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Alfa ya Kiweko" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Rangi ya Kiweko" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Console height" +msgstr "Muhimu ya Kiweko" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "ContentDB URL" +msgstr "Kuendelea" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Kuendelea mbele" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Vidhibiti" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Vidhibiti vya urefu wa mzunguko wa siku/usiku.\n" +"Mifano: 72 = 20 min, 360 = 4 min, 1 = 24 saa, 0 = anakaa siku/usiku/whatever " +"unchanged." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Udhibiti mwinuko/kina cha ziwa depressions." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Udhibiti mwinuko/urefu wa milima." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Ajali ujumbe" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Creative" +msgstr "Kuunda" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Crosshair Alfa" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "Crosshair Alfa (opaqueness kati ya 0 na 255)." + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Rangi ya crosshair" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Uharibifu" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Rekebisha taarifa kibonye" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Debug log file size threshold" +msgstr "Rekebisha kiwango cha logi" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Rekebisha kiwango cha logi" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dec. volume key" +msgstr "HUD kibonye" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Hatua ya seva ya kujitolea" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Kichapuzi Chaguo-msingi" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Chaguo-msingi mchezo" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Chaguo-msingi mchezo wakati wa kuunda dunia mpya.\n" +"Hii itakuwa kuwa kuuharibu wakati kutengeneza ulimwengu kutoka kwenye menyu " +"kuu." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Nywila ya chaguo-msingi" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Upendeleo wa chaguo-msingi" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Umbizo wa ripoti wa chaguo-msingi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Default stack size" +msgstr "Chaguo-msingi mchezo" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Inafasili umbali wa uhamisho wa mchezaji maximal katika vitalu (0 = ukomo)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "Kuchelewa katika kutuma vitalu baada ya jengo" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Kuchelewa kuonyesha vidokezozana, alisema katika milisekunde." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Deprecated Lua API utunzaji" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Depth below which you'll find giant caverns." +msgstr "Kina chini ambayo utapata mapango kubwa." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Kina chini ambayo utapata mapango kubwa." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Maelezo ya seva, kuonyeshwa wakati wachezaji kujiunga na katika serverlist " +"ya." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Desynchronize umbo la uhuishaji" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Instrumentation" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dig key" +msgstr "Ufunguo sahihi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Digging particles" +msgstr "Chembe" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Lemaza anticheat" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Usiruhusu nywila tupu" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Kikoa jina la seva, kuonyeshwa katika serverlist ya." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Mara mbili ya bomba kuruka kwa kuruka" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Mbili-tapping ufunguo wa kuruka Inatogoa hali ya kuruka." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Tone kipengee muhimu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dump the mapgen debug information." +msgstr "Bwaga mwandishi ramani rekebishi infos." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dungeon noise" +msgstr "Kelele za mto" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable joysticks" +msgstr "Wezesha vifimbocheza" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Enable mod channels support." +msgstr "Kuwezesha usalama Moduli" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Kuwezesha usalama Moduli" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Wezesha wachezaji kupata uharibifu na kufa." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Wezesha ingizo la mtumiaji nasibu (kutumika tu kwa ajili ya kupima)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Wezesha taa laini na rahisi iliyoko occlusion.\n" +"Lemaza kwa kasi au kwa ajili ya inaonekana tofauti." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Wezesha Usiruhusu wateja wa zamani kutoka kuunganisha.\n" +"Wateja wakubwa ni patanifu katika maana ya kwamba wao si mapenzi ajali " +"wakati wa kuunganisha kwenye seva mpya, lakini inaweza kusaidia nduni zote " +"mpya ambayo ni kutarajia." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"Kuwezesha matumizi ya seva ya midia ya mbali (kama zinazotolewa na seva).\n" +"Seva ya mbali kutoa njia kwa kiasi kikubwa kasi ya kupakua midia (k.m unamu) " +"wakati wa kuunganisha kwenye seva." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Mengi kwa ajili ya Mwoneko kando.\n" +"Kwa mfano: 0 kwa ajili ya Mwoneko hakuna kando; 1.0 kwa ajili ya kawaida; " +"2.0 kwa mara mbili." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"Wezesha/Lemaza kuendesha seva ya IPv6. Seva ya IPv6 unaweza kuzuiliwa kwa " +"wateja IPv6, kutegemea usanidi mfumo.\n" +"Kupuuzwa kama bind_address kuweka." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Huwezesha uhuishaji wa vitu inventering." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Huwezesha uwekaji kache kwa facedir Iliyozungushwa meshes." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Inawezesha minimap." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Maelezo mafupi ya Bonde" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Injini ubainishaji wa data ya uchapaji nafasi" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Mbinu ya chombo" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "FPS when unfocused or paused" +msgstr "Ramprogrammen juu wakati mchezo umesitishwa." + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Fall bobbing factor" +msgstr "Kuanguka bobbing" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Fallback font path" +msgstr "Fonti amebadilisha" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Ufunguo kasi" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Kuongeza kasi hali ya haraka" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Kasi ya hali ya haraka" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Kutembea haraka" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Harakati haraka (kupitia matumizi muhimu).\n" +"Hii inahitaji upendeleo \"haraka\" kwenye seva." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Uga wa Mwoneko" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Uga wa Mwoneko katika nyuzi." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Faili katika mteja/serverlist/yenye seva zako Pendwa kuonyeshwa katika " +"kichupo cha Multiplayer." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filler depth" +msgstr "Kina ya Filler" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filler depth noise" +msgstr "Kina ya Filler" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Ramani ya toni filmic" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Unamu kuchujwa wanaweza kujichanganya RGB thamani na majirani kikamilifu-" +"uwazi, ambayo PNG optimizers kawaida Tupa, wakati mwingine kusababisha " +"katika ukingo wa giza au mwanga angavu ya unamu. Tekeleza Kichujio hii " +"kusafisha kwamba wakati mzigo, unamu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Antialiasing:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Mbegu ya ramani fasta" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland density" +msgstr "Kiwango cha maji" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland noise" +msgstr "Kiwango cha maji" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland taper exponent" +msgstr "Kiwango cha maji" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland tapering distance" +msgstr "Umbali wa uhamisho wa mchezaji" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland water level" +msgstr "Kiwango cha maji" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Kuruka ufunguo" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Kuruka" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Ukungu" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Kibonye guro wa ukungu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Ukubwa wa fonti" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Kivuli cha fonti" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Fonti kivuli Alfa" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Ukubwa wa fonti" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Umbizo la viwambo." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec default background color (R,G,B)." +msgstr "Mazungumzo katika mchezo console mandharinyuma rangi (R, G, B)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" +"Mazungumzo katika mchezo console mandharinyuma Alfa (opaqueness kati ya 0 na " +"255)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Mazungumzo katika mchezo console mandharinyuma rangi (R, G, B)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" +"Mazungumzo katika mchezo console mandharinyuma Alfa (opaqueness kati ya 0 na " +"255)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Ufunguo wa mbele" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Kutoka vitalu mbali kiasi gani hutolewa kwa wateja, alisema katika mapblocks " +"(fundo 16)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Kutoka vitalu mbali jinsi hutumwa kwa wateja, alisema katika mapblocks " +"(fundo 16)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Kiwamba kizima" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Hali-tumizi ya skrini nzima." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "GUI kurekebisha" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "GUI kipimo Kichujio" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "GUI kipimo Kichujio txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Michezo" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Callbacks ya kimataifa" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Ramani ya kimataifa kizazi sifa.\n" +"Katika Mwandishi ramani v6 bendera ya 'kienyeji' udhibiti mapambo yote " +"isipokuwa miti na junglegrass, katika mapgens mengine yote bendera hii " +"udhibiti mapambo yote.\n" +"Bendera ambayo haijabainishwa katika Tungo ya bendera ni hayakubadilishwa " +"kutoka chaguo-msingi.\n" +"Bendera kuanzia na 'hapana' hutumiwa kidhahiri Lemaza yao." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Michoro" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Michoro" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Michoro" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Mvutano" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ground level" +msgstr "Mwandishi ramani gorofa ngazi ya chini" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ground noise" +msgstr "Mwandishi ramani gorofa ngazi ya chini" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HTTP mods" +msgstr "HTTP Mods" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "GUI kurekebisha" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "HUD kibonye" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Utunzaji kwa deprecated lua ya API: - Rithi: (jaribu kwa) mimic zamani tabia " +"(chaguo-msingi kwa ajili ya kutolewa).\n" +"-logi: kuiga na kuingia backtrace wa deprecated wito (chaguo-msingi kwa " +"ajili ya rekebishi).\n" +"-Kosa: tusiseme juu ya matumizi ya simu deprecated (alipendekeza kwa " +"watengenezaji Moduli)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Kuwa profiler instrument yenyewe: * Instrument kazi tupu.\n" +"Hii makadirio vimezingirwa, kwamba instrumentation ni kuongeza (+ 1 kazi " +"simu).\n" +"* Chombo sampler kutumika ili kusasisha takwimu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Heat blend noise" +msgstr "Mwandishi ramani joto mchanganyiko kelele vigezo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Heat noise" +msgstr "Pango kelele #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "Kijenzi cha urefu wa ukubwa cha kidirisha awali." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Height noise" +msgstr "Windows kulia" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Height select noise" +msgstr "Mwandishi ramani v6 urefu Teua vigezo kelele" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hill steepness" +msgstr "Mwandishi ramani gorofa kilima mwinuko" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hill threshold" +msgstr "Kilele cha mlima gorofa Mwandishi ramani" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness1 noise" +msgstr "Pango kelele #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness2 noise" +msgstr "Pango kelele #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness3 noise" +msgstr "Pango kelele #1" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Hilliness4 noise" +msgstr "Pango kelele #1" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Homepage ya seva, kuonyeshwa katika serverlist ya." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "How deep to make rivers." +msgstr "Kina jinsi kufanya mito" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Seva kiasi kusubiri kabla ya kupakua mapblocks zisizotumika.\n" +"Thamani ya juu zaidi ni laini, lakini kutumia RAM zaidi." + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "How wide to make rivers." +msgstr "Upana gani kufanya mito" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6 Seva" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"Kama Ramprogrammen angekwenda juu kuliko hii, kikomo kwa kulala si kupoteza " +"nguvu ya CPU kwa faida yoyote." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Ikiwa kimelemazwa \"kutumia\" ufunguo ni kutumika kwa kuruka haraka kama " +"hali-tumizi ya kuruka na ya haraka ni kuwezeshwa." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Kama kuwezeshwa pamoja na hali ya kuruka, mchezaji ni uwezo wa kuruka kwa " +"fundo imara.\n" +"Hii inahitaji upendeleo wa \"noclip\" kwenye seva." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Ikiwa imewezeshwa, ufunguo wa \"kutumia\" badala ya \"sneak\" ufunguo ni " +"kutumika kwa ajili ya kupanda na kushuka." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Ikiwa imewezeshwa, matendo ni kumbukumbu kwa ajili ya mserereko.\n" +"Chaguo hili ni soma tu wakati wa kuanza kwa seva." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Ikiwa imewezeshwa, kulemaza uzuiaji wa soka katika multiplayer." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Ikiwa imewezeshwa, data ya dunia batili si kusababisha seva kuzima.\n" +"Tu kuwezesha hii kama unajua nini unafanya." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "Ikiwa imewezeshwa, wachezaji wapya haiwezi kujiunga na nywila wazi." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Ikiwa imewezeshwa, unaweza mahali vitalu katika nafasi (miguu + jicho " +"kiwango) ambako kusimama.\n" +"Hii ni kusaidia unapofanya kazi na nodeboxes katika maeneo madogo." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "Kama hii ni kuweka, wachezaji mapenzi daima (re) spawn mahali fulani." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Kupuuza makosa ya ulimwengu" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Mazungumzo katika mchezo console mandharinyuma Alfa (opaqueness kati ya 0 na " +"255)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Mazungumzo katika mchezo console mandharinyuma rangi (R, G, B)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" +"Mazungumzo katika mchezo console mandharinyuma Alfa (opaqueness kati ya 0 na " +"255)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Inc. volume key" +msgstr "Muhimu ya Kiweko" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Chombo builtin.\n" +"Hii ni kawaida tu zinazohitajika kwa wachangiaji wa msingi/builtin" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Instrument chat commands on registration." +msgstr "Chombo chatcommands kwenye usajili." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Chombo mwito-rejeshi kimataifa kazi kwenye usajili.\n" +"(kitu chochote unaweza kupita kwa kazi minetest.register_*())" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "Ala ya kazi hatua ya Modifiers Amilifu wa fungu kwenye usajili." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "Ala ya kazi hatua ya kupakia fungu Modifiers kwenye usajili." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Instrument mbinu za vyombo kwenye usajili." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" +"Muda wa kuhifadhi mabadiliko muhimu katika ulimwengu, alisema katika sekunde." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Muda wa kutuma wakati wa siku kwa wateja." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Hesabu vitu uhuishaji" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Ufunguo wa hesabu" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Pindua kipanya" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Pindua harakati ya kipanya wima." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Italic font path" +msgstr "Monospace njia ya fonti" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Italic monospace font path" +msgstr "Monospace njia ya fonti" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Kipengee chombo TTL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Iterations" +msgstr "Instrumentation" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Kifimbocheza kitufe marudio nafasi" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Kifimbocheza frustum unyeti" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Julia kuweka tu: W sehemu ya hypercomplex mara kwa mara umbo julia kukazia.\n" +"Ina athari 3D fractals.\n" +"Masafa ya takribani-2 hadi 2." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Julia kuweka tu: X sehemu ya hypercomplex mara kwa mara umbo julia kukazia.\n" +"Masafa ya takribani-2 hadi 2." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Julia kuweka tu: sehemu Y ya hypercomplex mara kwa mara umbo julia kukazia.\n" +"Masafa ya takribani-2 hadi 2." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Julia kuweka tu: Z sehemu ya hypercomplex mara kwa mara umbo julia kukazia.\n" +"Masafa ya takribani-2 hadi 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Ufunguo wa kuruka" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Kuruka kasi" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kupunguza kiwango cha kuonyesha.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kupunguza kiwango cha kuonyesha.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuruka.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuacha kipengee kilichoteuliwa kwa sasa.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuongeza kiwango cha kuonyesha.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuongeza kiwango cha kuonyesha.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuruka.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kusonga haraka katika hali ya haraka.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuhamia mchezaji nyuma.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuhamia mchezaji mbele.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuhamia mchezaji kushoto.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kusonga mchezaji haki.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuruka.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua dirisha la soga kuchapa amri.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua dirisha la soga kuchapa amri.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua dirisha la soga.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuruka.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kufungua hesabu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya sneaking.\n" +"Pia kutumika kwa ajili ya kupanda na kushuka katika maji kama aux1_descends " +"imelemazwa.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kubadili kati ya kamera ya kwanza - na -mtu wa tatu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuchukua viwambo.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling autorun.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling hali ya cinematic.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling onyesho la minimap.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling hali ya haraka.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling kuruka.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling hali ya noclip.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling hali ya noclip.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling sasaishi ya kamera. Tu kutumika kwa ajili ya " +"maendeleo ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling onyesho la kuzungumza.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling onyesho la maelezo kuhusu marekebisho.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling onyesho la ukungu.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling onyesho la ya HUD.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling onyesho la kuzungumza.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling onyesho la profiler ya. Kutumika kwa ajili ya " +"maendeleo.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya toggling masafa ya Mwoneko ukomo.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Muhimu kwa ajili ya kuruka.\n" +"Ona http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lake steepness" +msgstr "Mwandishi ramani ziwa gorofa mwinuko" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lake threshold" +msgstr "Mwandishi ramani ziwa gorofa kizingiti" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Lugha" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Kina ya pango kubwa" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Large chat console key" +msgstr "Muhimu ya Kiweko" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Mtindo wa majani" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Majani mtindo: - dhana: nyuso zote kuonekana - rahisi: tu nyuso nje, kama " +"inavyoelezwa special_tiles ni kutumika - Opaque: Lemaza uwazi" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Ufunguo wa kushoto" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Urefu wa alama ya tiki seva na nafasi ambayo vitu ni kwa ujumla kusasaishwa " +"kwenye mtandao." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Kuweka huwezesha kweli waving majani.\n" +"Inahitaji shaders kwa kuwezeshwa." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Urefu wa muda kati ya ABM utekelezaji mizunguko" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "Urefu wa muda kati ya mzunguko wa utekelezaji wa NodeTimer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Muda kati ya mizunguko ya usimamizi ya fungu amilifu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"Kiwango cha ufunguaji kuandikwa kwa debug.txt:- <nothing>(Hakuna ufunguaji) " +"- Hakuna (ujumbe na hakuna kiwango) - kosa - tahadhari - hatua - taarifa - " +"verbose</nothing>" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Taa laini" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Mipaka idadi ya maombi HTTP sambamba. Huathiri: - vyombo vya habari kuchota " +"kama seva hutumia kipimo cha remote_media.\n" +"-Serverlist kupakua na seva tangazo.\n" +"-Downloads zifanywe Menyu kuu (k.m Meneja Moduli).\n" +"Tu ina athari kama alikusanya na Mkunjo." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Fluidity kioevu" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Fluidity kioevu unyooshaji" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Kitanzi kioevu upeo" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Wakati wa usafishaji wa foleni ya kioevu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Liquid sinking" +msgstr "Kuzama kioevu" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Sasisha kioevu nafasi katika sekunde." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Pata sasishi kioevu" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Kupakia profiler mchezo" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Kupakia profiler mchezo kukusanya data ya ubainishaji wa mchezo.\n" +"Hutoa amri /profiler kufikia umbo Kusanyo.\n" +"Muhimu kwa watengenezaji Moduli na waendeshaji wa seva." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Inapakiza umbo Modifiers" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lower Y limit of floatlands." +msgstr "Y ya upper kikomo ya kubwa pseudorandom cellars." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Hati ya Menyu kuu" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Kufanya rangi wa ukungu na anga hutegemea mchana (alfajiri/machweo) na " +"kuonyesha mwelekeo." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Orodha ya ramani" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Ramani kizazi sifa maalum kwa Mwandishi ramani gorofa.\n" +"Maziwa mara kwa mara na vilima vinaweza kuongezwa kwa ulimwengu gorofa.\n" +"Bendera ambayo haijabainishwa katika Tungo ya bendera ni hayakubadilishwa " +"kutoka chaguo-msingi.\n" +"Bendera kuanzia na 'hapana' hutumiwa kidhahiri Lemaza yao." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Ramani kizazi sifa maalum kwa Mwandishi ramani gorofa.\n" +"Maziwa mara kwa mara na vilima vinaweza kuongezwa kwa ulimwengu gorofa.\n" +"Bendera ambayo haijabainishwa katika Tungo ya bendera ni hayakubadilishwa " +"kutoka chaguo-msingi.\n" +"Bendera kuanzia na 'hapana' hutumiwa kidhahiri Lemaza yao." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Ramani kizazi sifa maalum ya Mwandishi ramani v6.\n" +"Wakati snowbiomes vimewezeshwa misitu otomatiki imewezeshwa, bendera ya " +"'misitu' ni kupuuzwa.\n" +"Bendera ambayo haijabainishwa katika Tungo ya bendera ni hayakubadilishwa " +"kutoka chaguo-msingi.\n" +"Bendera kuanzia na 'hapana' hutumiwa kidhahiri Lemaza yao." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Ramani kizazi sifa maalum kwa Mwandishi ramani gorofa.\n" +"Maziwa mara kwa mara na vilima vinaweza kuongezwa kwa ulimwengu gorofa.\n" +"Bendera ambayo haijabainishwa katika Tungo ya bendera ni hayakubadilishwa " +"kutoka chaguo-msingi.\n" +"Bendera kuanzia na 'hapana' hutumiwa kidhahiri Lemaza yao." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Kikomo cha kizazi cha ramani" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Ramani hifadhi muda" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map shadows update frames" +msgstr "Pata sasishi kioevu" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Kikomo cha Mapblock" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapblock mesh generation delay" +msgstr "Kikomo cha kizazi cha ramani" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Kikomo cha kizazi cha ramani" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Mkatiko Muda Mapblock wakipakua" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian" +msgstr "Fractal ya Mwandishi ramani" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian specific flags" +msgstr "Mwandishi ramani gorofa bendera" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat" +msgstr "Mwandishi ramani gorofa" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat specific flags" +msgstr "Mwandishi ramani gorofa bendera" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal" +msgstr "Fractal ya Mwandishi ramani" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "Mwandishi ramani gorofa bendera" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5" +msgstr "Mwandishi ramani v5" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5 specific flags" +msgstr "Mwandishi ramani v6 bendera" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6" +msgstr "Mwandishi ramani v6" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6 specific flags" +msgstr "Mwandishi ramani v6 bendera" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7" +msgstr "Mwandishi ramani v7" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7 specific flags" +msgstr "Mwandishi ramani v7 bendera" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Mwandishi ramani mabonde" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Valleys specific flags" +msgstr "Mwandishi ramani gorofa bendera" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Utatuaji wa Mwandishi ramani" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Mwandishi ramani jina" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Umbo la Max kuzalisha umbali" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Umbo la Max Tuma umbali" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Max viowevu kusindika kwa kila hatua." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Max. clearobjects vitalu vya ziada" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Max. pakiti kila Marudiorudio" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Ramprogrammen juu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "Ramprogrammen juu wakati mchezo umesitishwa." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Forceloaded upeo vitalu" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Hotbar kiwango cha juu cha upana" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" +"Namba ya juu ya vitalu kwamba unaweza kwenye foleni kwa ajili ya kupakia." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Namba ya juu ya vitalu kwa kuwa kwenye foleni kwamba ni kutengenezwa.\n" +"Seti kwa wazi kwa kiasi sahihi ili uweze kuchaguliwa moja kwa moja." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Namba ya juu ya vitalu kwa kuwa kwenye foleni kwamba ni kupakiwa kutoka " +"faili.\n" +"Seti kwa wazi kwa kiasi sahihi ili uweze kuchaguliwa moja kwa moja." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Namba ya juu ya forceloaded mapblocks." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"Namba ya juu ya mapblocks kwa mteja kwa kuwekwa katika kumbukumbu.\n" +"Seti -1 kwa kiasi ukomo." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Namba ya juu ya pakiti iliyotumwa kwa hatua ya kutuma, kama una muunganisho " +"polepole jaribu kupunguza ni, lakini si ya kupunguza kadhaa chini ya mara " +"mbili ya idadi ya mteja lengwa." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Namba ya juu ya wachezaji ambao wanaweza kuunganisha wakati huo huo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum number of recent chat messages to show" +msgstr "Namba ya juu ya forceloaded mapblocks." + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Namba ya juu ya vipengee statically kuhifadhiwa katika umbo la." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Vipengee juu kwa kila fungu" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Uwiano juu ya dirisha la sasa kutumika kwa ajili ya hotbar.\n" +"Muhimu kama kuna kitu cha kuonyeshwa kulia au kushoto wa hotbar." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "Fungu juu ya samtidiga hutuma kwa mteja" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Muda wa juu zaidi katika ms kupakua faili (kwa mfano upakuaji na Moduli) " +"inaweza kuchukua." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Watumiaji wa kiwango cha juu" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Kirudufu cha matundu" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Ujumbe wa siku ya" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Ujumbe wa siku ya kuonyeshwa kwa wachezaji kuunganisha." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Mbinu inayotumiwa kuonyesha kipengee kilichoteuliwa." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Ramani" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Ufunguo wa minimap" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Ramani tambazo urefu" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimum texture size" +msgstr "Unamu wa kima cha chini cha ukubwa wa Vichujio" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mipmapping" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Profiler" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Usalama" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Monospace njia ya fonti" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Ukubwa wa fonti wa Monospace" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "Ukubwa wa fonti wa Monospace" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mountain height noise" +msgstr "Mwandishi ramani v7 mlima urefu kelele vigezo" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mountain variation noise" +msgstr "Mwandishi ramani v7 mlima urefu kelele vigezo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mountain zero level" +msgstr "Mwandishi ramani v7 mlima urefu kelele vigezo" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Unyeti wa kipanya" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Mengi ya unyeti wa kipanya." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Mengi kwa ajili ya kuanguka kando.\n" +"Kwa mfano: 0 kwa ajili ya Mwoneko hakuna kando; 1.0 kwa ajili ya kawaida; " +"2.0 kwa mara mbili." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mute key" +msgstr "Ufunguo wa matumizi" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Jina la mchezaji.\n" +"Wakati kuendesha seva, wateja kuunganisha kwa jina hili ni admins.\n" +"Wakati kuanzia Menyu kuu, hii ni kuuharibu." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Jina la seva, kuonyeshwa wakati wachezaji kujiunga na katika serverlist ya." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Mtandao bandari kusikiliza (UDP).\n" +"Thamani hii itakuwa kuuharibu wakati kuanzia Menyu kuu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Mtandao" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Watumiaji wapya haja Ingiza nywila hii." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Noclip" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Ufunguo wa Noclip" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Fundo udhulisho" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Fundo udhulisho" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "Nafasi ya NodeTimer" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Kila" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Idadi ya nyuzi emerge" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"Idadi ya vitalu ziada ambayo inaweza kupakiwa na /clearobjects mara moja.\n" +"Hii ni mikinzano kati sqlite shughuli uendeshaji na matumizi ya kumbukumbu " +"(4096 = 100 MB, kama kanuni ya thumb)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "Njia ya orodha ya unamu. Unamu wote vinatafutizwa kwanza kutoka hapa." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Per-player limit of queued blocks to generate" +msgstr "Kikomo ya foleni emerge kuzalisha" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fizikia" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move key" +msgstr "Kuruka ufunguo" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "Kuruka ufunguo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place repetition interval" +msgstr "Bofya kulia marudio nafasi" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Mchezaji ni uwezo wa kuruka bila kuwa walioathirika na mvuto.\n" +"Hii inahitaji upendeleo \"kuruka\" kwenye seva." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Umbali wa uhamisho wa mchezaji" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Player versus player" +msgstr "Mchezaji dhidi ya mchezaji" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "Uchujaji wa bilinear" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Bandari ya kuunganishwa (UDP).\n" +"Kumbuka kwamba uwanja wa bandari katika Menyu kuu Puuza kipimo hiki." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "Kuzuia mods kufanya mambo zisizo kama kuendesha amri ya Sheli." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Chapisha injini ya ubainishaji data katika vipindi vya kawaida (katika " +"sekunde). 0 = Lemaza. Muhimu kwa watengenezaji." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "Marupurupu ya wachezaji na basic_privs unaweza ruzuku" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Profiler" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Profiler kibonye" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Eneo la eneo la wingu alisema katika idadi ya 64 fundo wingu miraba.\n" +"Thamani kubwa kuliko 26 itaanza kuzalisha cutoffs mkali katika wingu eneo la " +"pembe." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Raises terrain to make valleys around the rivers." +msgstr "Huwafufua ardhi kufanya mabonde kuzunguka mito" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Ingizo la nasibu" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Kibonye Teua masafa" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Regular font path" +msgstr "Njia ya ripoti" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Midia ya mbali" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Bandari ya mbali" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Kinabadilisha chaguo-msingi Menyu kuu kwa moja maalum." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Njia ya ripoti" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ridge mountain spread noise" +msgstr "Mwandishi ramani v7 mlima urefu kelele vigezo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ridge noise" +msgstr "Kelele za mto" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Ridged mountain size noise" +msgstr "Mwandishi ramani v7 mlima urefu kelele vigezo" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Ufunguo sahihi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River channel depth" +msgstr "Kina wa mto" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River channel width" +msgstr "Kina wa mto" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River depth" +msgstr "Kina wa mto" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River noise" +msgstr "Kelele za mto" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River size" +msgstr "Ukubwa wa mto" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River valley width" +msgstr "Kina wa mto" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Mserereko kurekodi" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Ramani pande zote" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "Hifadhi ramani kupokelewa na mteja kwenye diski." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Ramani kuokoa kupokea kutoka seva" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Rekebisha gui kwa mtumiaji maalum thamani.\n" +"Tumia kichujio karibu-jirani-Waanti-Lakabu Rekebisha GUI ya.\n" +"Hii laini baadhi ya kingo mbaya, na mchanganyiko pikseli wakati upimaji " +"chini, wanatengeneza ukungu wa jinsia pikseli baadhi makali wakati picha ni " +"yamesimamisha na ukubwa wa yasiyo ya takwimu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Screenshot" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Urefu wa kiwamba" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Upana wa kiwamba" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Screenshot kabrasha" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Screenshot umbizo" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Screenshot ubora" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Screenshot ubora. Tu kutumika kwa ajili ya Umbiza JPEG.\n" +"1 maana ubora mbaya; 100 humaanisha ubora.\n" +"Tumia 0 kwa ubora wa chaguo-msingi." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Screenshot" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Seabed noise" +msgstr "Pango kelele #1" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Ona http://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Uteuzi kikasha mpaka rangi (R, G, B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Uteuzi kikasha rangi" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Uteuzi kikasha upana" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"Uchaguzi wa fractals 18 kutoka fomula 9.\n" +"1 = 4 D \"Roundy\" mandelbrot seti.\n" +"2 = 4 D seti ya julia \"Roundy\".\n" +"3 = 4 D \"Squarry\" mandelbrot seti.\n" +"4 = 4 D seti ya julia \"Squarry\".\n" +"5 = 4 D \"Binamu Mandy\" mandelbrot seti.\n" +"6 = 4 D \"Binamu Mandy\" julia seti.\n" +"7 = 4 D \"Tofauti\" mandelbrot seti.\n" +"8 = 4 D seti ya julia \"Tofauti\".\n" +"9 = 3D \"Mandelbrot/Mandelbar\" mandelbrot seti.\n" +"10 = 3D julia \"Mandelbrot/Mandelbar\" seti.\n" +"11 = 3D \"Mti wa Krismasi\" mandelbrot seti.\n" +"12 = 3D \"Mti wa Krismasi\" julia seti.\n" +"13 = 3D \"Mandelbulb\" mandelbrot seti.\n" +"14 = 3D julia \"Mandelbulb\" seti.\n" +"15 = 3D \"Kosaini Mandelbulb\" mandelbrot seti.\n" +"16 = 3D julia \"Kosaini Mandelbulb\" seti.\n" +"17 = 4 D \"Mandelbulb\" mandelbrot seti.\n" +"18 = 4 D seti ya julia \"Mandelbulb\"." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL ya seva" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Jina la seva" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Maelezo ya seva" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL ya seva" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Anwani ya seva" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Maelezo ya seva" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Jina la seva" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Kituo tarishi cha seva" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Kituo tarishi cha seva" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL ya Serverlist" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "URL ya Serverlist" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Faili ya Serverlist" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Seti lugha. Acha tupu kwa kutumia lugha ya mfumo.\n" +"Kuanza upya inahitajika baada ya kubadilisha hii." + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Kuweka huwezesha kweli waving majani.\n" +"Inahitaji shaders kwa kuwezeshwa." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Kuweka huwezesha kweli waving majani.\n" +"Inahitaji shaders kwa kuwezeshwa." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Kuweka huwezesha kweli waving maji.\n" +"Inahitaji shaders kwa kuwezeshwa." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Kuweka huwezesha kweli waving mimea.\n" +"Inahitaji shaders kwa kuwezeshwa." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shader path" +msgstr "Shaders" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Shaders kuruhusu athari pevu onekana na inaweza kuongeza utendaji wa baadhi " +"ya kadi ya video.\n" +"Kazi yako tu na OpenGL video backend." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "Screenshot ubora" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map texture size" +msgstr "Unamu wa kima cha chini cha ukubwa wa Vichujio" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "Fonti kivuli Sawazisha, kama 0 basi kivuli itakuwa kuchukuliwa." + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Sura ya minimap ya. Kuwezeshwa = pande zote, walemavu = mraba." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Onyesha maelezo kuhusu marekebisho" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Onyesha chombo masanduku ya uteuzi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Seti lugha. Acha tupu kwa kutumia lugha ya mfumo.\n" +"Kuanza upya inahitajika baada ya kubadilisha hii." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Uzimaji ujumbe" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Slope and fill work together to modify the heights." +msgstr "Mteremko na Jaza kazi pamoja kurekebisha urefu" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Taa laini" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Smooths kamera wakati wa kutafuta karibu. Pia huitwa kuangalia au kipanya " +"unyooshaji.\n" +"Muhimu kwa ajili ya kurekodi video." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "Smooths mzunguko wa kamera katika hali-tumizi cinematic. 0 kulemaza." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Smooths mzunguko wa kamera. 0 kulemaza." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Zawadi muhimu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed" +msgstr "Kutembea kasi" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "Fonti kivuli Alfa" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Sauti" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Inabainisha URL kutoka ambayo mteja fetches vyombo vya habari badala ya " +"kutumia UDP.\n" +"$filename lazima kupatikana kutoka $remote_media$ JinaFaili kupitia cURL (ni " +"wazi, remote_media lazima kumaliza na kufyeka na).\n" +"Faili ambayo sasa itakuwa kuwa fetched njia ya kawaida." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Spawnpoint tuli" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Step mountain size noise" +msgstr "Mwandishi ramani v7 mlima urefu kelele vigezo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Step mountain spread noise" +msgstr "Mwandishi ramani v7 mlima urefu kelele vigezo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Strength of 3D mode parallax." +msgstr "Nguvu ya parallax." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Itifaki ya kali kukagua" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "SQLite Uvingirizi" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Vipimo vya" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain alternative noise" +msgstr "Urefu wa ardhi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain base noise" +msgstr "Urefu wa ardhi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain height" +msgstr "Urefu wa ardhi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain higher noise" +msgstr "Urefu wa ardhi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain noise" +msgstr "Urefu wa ardhi" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Ardhi kelele kizingiti kwa milima.\n" +"Vidhibiti vya uwiano wa dunia eneo lililofunikwa na milima.\n" +"Rekebisha kuelekea 0.0 kwa sehemu kubwa." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Ardhi kelele kizingiti kwa ajili ya maziwa.\n" +"Vidhibiti vya uwiano wa dunia eneo lililofunikwa na maziwa.\n" +"Rekebisha kuelekea 0.0 kwa sehemu kubwa." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Njia ya unamu" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"Umbizo wa chaguo-msingi ambayo maumbo ni kuokoka, wakati wito '/ profiler\n" +"Hifadhi [umbizo]' bila umbizo." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The depth of dirt or other biome filler node." +msgstr "Kina cha uchafu au filler nyingine" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" +"Kijia cha faili jamaa yako worldpath ambayo maumbo utaakibishwa kwenye.\n" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "Interface mtandao kwamba seva husikiliza juu." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Upendeleo kwamba watumiaji wapya otomatiki kupata.\n" +"Ona /privs katika mchezo kwa ajili ya orodha kamili kwenye msabidi wa seva " +"na Moduli." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "Unyeti wa Jira kifimbocheza kwa kuzunguka Mwoneko ingame frustum." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"Nguvu (giza) ya fundo iliyoko occlusion kivuli.\n" +"Chini ni nyeusi, juu ni hafifu. Masafa halali ya thamani kwa ajili ya kipimo " +"hiki ni 0.25 kwa 4.0 jumuishi. Kama thamani iko nje ya masafa ni itasetiwa " +"kwenye ya karibu Thamani halali." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Muda (katika sekunde) kuwa foleni ya viowevu inaweza kukua zaidi usindikaji " +"uwezo hadi jaribio ni alifanya kupungua ukubwa wake na utupaji vipengee " +"kongwe ya foleni. Thamani ya 0 Hulemaza utendaji." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Wakati katika sekunde inachukua kati ya matukio ya mara kwa mara wakati " +"kushikilia chini kifimbocheza kitufe mchanganyiko." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Wakati katika sekunde inachukua kati ya vibonyezo mara kwa mara sahihi " +"wakati wa kufanya kitufe cha kulia." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Wakati katika sekunde kwa kipengee chombo (vitu chopo) kuishi.\n" +"Kuweka kwa -1 Hulemaza kipengele." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Wakati kutuma nafasi" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Kasi ya muda" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"Muda wa kuisha kwa mteja kuondoa data ya ramani zisizotumika kutoka kwa " +"kumbukumbu." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Kupunguza bakia, uhamisho wa fungu ni sjunkit wakati mchezaji ni kujenga " +"kitu.\n" +"Hii huamua lini wao ni sjunkit baada ya kuweka au kuondoa fundo." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Togoa kamera hali muhimu" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "Kidokezozana kuchelewa" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touch screen threshold" +msgstr "Touchthreshold (px)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Touchthreshold (px)" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Uchujaji wa trilinear" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"Kweli = 256 bandia = Useable 128 kufanya minimap laini juu ya mashine " +"polepole." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Mods aminifu" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" +"URL kwenye orodha ya seva iliyoonyeshwa katika kichupo cha Multiplayer." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Umbali wa uhamisho wa mchezaji ukomo" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Wakipakua zisizotumika seva ya data" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Upper Y limit of floatlands." +msgstr "Y ya upper kikomo ya kubwa pseudorandom cellars." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Matumizi wingu 3D kuangalia badala ya gorofa." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Tumia uhuishaji wa wingu ya mandharinyuma ya Menyu kuu." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "Tumia uchujaji anisotropic wakati unatazama katika unamu kutoka pembe." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Tumia uchujaji bilinear wakati upimaji unamu." + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Tumia uchujaji trilinear wakati upimaji unamu." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "VSync" +msgstr "V-ulandanishi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Valley depth" +msgstr "Kina wa Bonde" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Valley fill" +msgstr "Jaza ya Bonde" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Valley profile" +msgstr "Maelezo mafupi ya Bonde" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Valley slope" +msgstr "Mteremko wa Bonde" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Varies steepness of cliffs." +msgstr "Udhibiti mwinuko/urefu wa milima." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Ulandanishi wa kiwamba wima." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Kiendeshaji video" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "View bobbing factor" +msgstr "Mwoneko kando" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "View distance in nodes." +msgstr "" +"Onyesha umbali katika fundo.\n" +"Min = 20" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Mwoneko masafa Punguza ufunguo" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Mwoneko masafa ongezeko muhimu" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Kuonyesha masafa" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Kiasi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Huwezesha parallax occlusion uramanishi.\n" +"Inahitaji shaders kwa kuwezeshwa." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"W kuratibu ya yanayotokana 3D kisu wa fractal wa 4 D.\n" +"Huamua kisu ambayo 3D wa umbo 4D huundwa.\n" +"Ina athari 3D fractals.\n" +"Masafa ya takribani-2 hadi 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Kutembea kasi" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Kiwango cha maji" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Maji ngazi ya uso wa dunia." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Waving fundo" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Waving majani" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "Waving fundo" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "Waving maji urefu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "Waving kasi ya maji" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "Waving maji urefu" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Waving mimea" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "Uteuzi kikasha rangi" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"Wakati gui_scaling_filter ni kweli, yote GUI picha haja ya kuchujwa katika " +"programu, lakini taswira zingine hutolewa moja kwa moja kwa maunzi (k.m " +"kutoa-kwa-unamu kwa fundo katika hesabu)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"Wakati gui_scaling_filter_txr2img ni kweli, kunakili picha hizo kutoka " +"maunzi na programu kwa ajili ya kurekebisha. Wakati uongo, kuanguka nyuma " +"kwa mbinu ya zamani ya kipimo, kwa madereva video vizuri siungi mkono unamu " +"Inapakua nyuma kutoka maunzi." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Wakati wa kutumia Vichujio bilinear/trilinear/anisotropic, unamu low-" +"resolution unaweza kizunguzungu, hivyo otomatiki upscale yao na karibu " +"jirani interpolation kuhifadhi pikseli hubainisha. Hii Seti Ukubwa wa unamu " +"chini kwa ajili ya unamu upscaled; thamani ya juu kuangalia kali, lakini " +"zinahitaji kumbukumbu zaidi. Nguvu ya 2 ni ilipendekeza. Kuweka hii zaidi " +"1 usiwe na athari inayoonekana isipokuwa uchujaji wa bilinear/trilinear/" +"anisotropic ni kuwezeshwa." + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "Kama fundo unamu uhuishaji lazima desynchronized kwa mapblock." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Kama wachezaji huonyeshwa kwa wateja bila kikomo yoyote mbalimbali.\n" +"Deprecated, Tumia kipimo player_transfer_distance badala yake." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Kama kuruhusu wachezaji kuharibu na kuua kila mmoja." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"Kama kuuliza wateja kuunganisha baada (Lua) ajali.\n" +"Seti hii kweli kama seva yako ni kuanzisha kuwasha upya otomatiki." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Kama ukungu nje mwisho wa eneo hili dhahiri." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"Kama kuonyesha mteja Rekebisha taarifa (ina athari sawa kama kupiga F5)." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "Upana sehemu ya ukubwa cha kidirisha awali." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width of the selection box lines around nodes." +msgstr "Upana wa mistari ya selectionbox karibu fundo." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Mpangilio orodha ulimwengu (kila kitu ulimwenguni kuhifadhiwa hapa).\n" +"Si zinahitajika kama kuanzia Menyu kuu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "World start time" +msgstr "Jina la ulimwengu" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y ya ardhi tambarare." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Y of upper limit of large caves." +msgstr "Y ya upper kikomo ya kubwa pseudorandom cellars." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "cURL muda wa upakuzi wa faili" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "muda wa kuisha wa cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "cURL kikomo sambamba" + +#, fuzzy +#~ msgid "- Creative Mode: " +#~ msgstr "Hali ya ubunifu" + +#, fuzzy +#~ msgid "- Damage: " +#~ msgstr "Uharibifu" + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = parallax occlusion na taarifa ya mteremko (haraka).\n" +#~ "1 = ramani ya misaada (polepole, sahihi zaidi)." + +#~ msgid "Address / Port" +#~ msgstr "Kushughulikia / bandari" + +#, fuzzy +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Rekebisha simbiko gamma kwa majedwali mwanga. Idadi ya chini ni mkali.\n" +#~ "Kipimo hiki ni kwa ajili ya mteja tu na ni kupuuzwa na seva." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Je, una hakika upya ulimwengu wako singleplayer?" + +#~ msgid "Back" +#~ msgstr "Nyuma" + +#~ msgid "Basic" +#~ msgstr "Msingi" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "" +#~ "Biti kwa pikseli (a.k.a rangi kina) katika hali-tumizi ya skrini nzima." + +#~ msgid "Bump Mapping" +#~ msgstr "Mapema ramani" + +#~ msgid "Bumpmapping" +#~ msgstr "Bumpmapping" + +#~ msgid "Config mods" +#~ msgstr "Mods Now" + +#~ msgid "Configure" +#~ msgstr "Sanidi" + +#~ msgid "Connect" +#~ msgstr "Kuunganisha" + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Vidhibiti vya upana wa vichuguu, thamani ndogo huunda vichuguu pana." + +#~ msgid "Credits" +#~ msgstr "Mikopo" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Rangi ya crosshair (R, G, B)." + +#~ msgid "Damage enabled" +#~ msgstr "Uharibifu kuwezeshwa" + +#, fuzzy +#~ msgid "Darkness sharpness" +#~ msgstr "Mwandishi ramani ziwa gorofa mwinuko" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "Chaguo-msingi muda wa kuisha kwa cURL, alisema katika milisekunde.\n" +#~ "Tu ina athari kama alikusanya na Mkunjo." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Inafasili hatua ya sampuli ya unamu.\n" +#~ "Thamani ya juu zaidi matokeo katika ramani ya laini ya kawaida." + +#~ msgid "Del. Favorite" +#~ msgstr "Del. kipendwa" + +#, fuzzy +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Pakua subgame, kama vile minetest_game, kutoka minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Pakua moja kutoka minetest.net" + +#, fuzzy +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Inapakua $1, Tafadhali subiri..." + +#~ msgid "Enable VBO" +#~ msgstr "Wezesha VBO" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Inawezesha bumpmapping kwa ajili ya unamu. Normalmaps haja iwekwe kwa " +#~ "pakiti ya unamu au haja ya kuwa yaliyozalishwa na otomatiki.\n" +#~ "Inahitaji shaders kwa kuwezeshwa." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Huwezesha toni filmic ramani" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Huwezesha kwenye kizazi cha normalmap kuruka (Emboss athari).\n" +#~ "Inahitaji bumpmapping kwa kuwezeshwa." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Huwezesha parallax occlusion uramanishi.\n" +#~ "Inahitaji shaders kwa kuwezeshwa." + +#~ msgid "Enter " +#~ msgstr "Ingiza" + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Chaguo majaribio, inaweza kusababisha nafasi inayoonekana kati ya vitalu " +#~ "wakati kuweka namba ya juu zaidi kuliko 0." + +#~ msgid "FPS in pause menu" +#~ msgstr "Ramprogrammen katika Menyu ya mapumziko" + +#~ msgid "Fallback font shadow" +#~ msgstr "Fonti amebadilisha kivuli" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Fonti amebadilisha kivuli Alfa" + +#~ msgid "Fallback font size" +#~ msgstr "Ukubwa fonti amebadilisha" + +#~ msgid "Filtering" +#~ msgstr "Uchujaji" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Fonti kivuli Alfa (opaqueness kati ya 0 na 255)." + +#, fuzzy +#~ msgid "FreeType fonts" +#~ msgstr "Fonti Freetype" + +#~ msgid "Full screen BPP" +#~ msgstr "Skrini BPP" + +#~ msgid "Game" +#~ msgstr "Mchezo" + +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#, fuzzy +#~ msgid "Generate Normal Maps" +#~ msgstr "Kuzalisha normalmaps" + +#~ msgid "Generate normalmaps" +#~ msgstr "Kuzalisha normalmaps" + +#~ msgid "High-precision FPU" +#~ msgstr "FPU kuu-usahihi" + +#~ msgid "IPv6 support." +#~ msgstr "IPv6 msaada." + +#~ msgid "In-Game" +#~ msgstr "Katika mchezo" + +#, fuzzy +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Sakinisha Moduli: faili: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Instrumentation" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Keybindings. (Kama Menyu hii screws, Ondoa vitu kutoka minetest.conf)" + +#, fuzzy +#~ msgid "Lava depth" +#~ msgstr "Kina ya pango kubwa" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Kikomo ya foleni emerge kwenye diski" + +#~ msgid "Main" +#~ msgstr "Kuu" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "Hati ya Menyu kuu" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "Hufanya DirectX kazi na LuaJIT. Lemaza ikiwa husababisha matatizo." + +#~ msgid "Menus" +#~ msgstr "Menyu" + +#~ msgid "Name / Password" +#~ msgstr "Jina / nenosiri" + +#~ msgid "Name/Password" +#~ msgstr "Jina/nenosiri" + +#~ msgid "No" +#~ msgstr "La" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Sampuli ya Normalmaps" + +#~ msgid "Normalmaps strength" +#~ msgstr "Nguvu ya Normalmaps" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Idadi ya parallax occlusion Marudiorudio." + +#~ msgid "Ok" +#~ msgstr "Sawa kabisa" + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "Upendeleo wa jumla wa parallax occlusion athari, kawaida kipimo/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Kipimo cha jumla ya parallax occlusion athari." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallax Occlusion" + +#~ msgid "Parallax occlusion" +#~ msgstr "Parallax occlusion" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Parallax occlusion upendeleo" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Parallax occlusion Marudiorudio" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Parallax occlusion hali" + +#, fuzzy +#~ msgid "Parallax occlusion scale" +#~ msgstr "Parallax occlusion wadogo" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Parallax occlusion nguvu" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "Njia ya TrueTypeFont au vitone michoro." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Njia ya kuokoa viwambo katika." + +#~ msgid "Player name" +#~ msgstr "Jina la mchezaji" + +#~ msgid "Profiling" +#~ msgstr "Ubainishaji wa" + +#~ msgid "PvP enabled" +#~ msgstr "PvP kuwezeshwa" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Weka upya singleplayer ulimwengu" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "Teua faili ya Moduli:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Seva / Singleplayer" + +#, fuzzy +#~ msgid "Shadow limit" +#~ msgstr "Kikomo cha Mapblock" + +#, fuzzy +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "Fonti kivuli Sawazisha, kama 0 basi kivuli itakuwa kuchukuliwa." + +#, fuzzy +#~ msgid "Special key" +#~ msgstr "Zawadi muhimu" + +#~ msgid "Start Singleplayer" +#~ msgstr "Kuanza Singleplayer" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Nguvu ya normalmaps inayozalishwa." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Fonti hii itatumika kwa lugha fulani." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Ili kuwezesha shaders OpenGL ya kiendeshaji inahitaji kutumiwa." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Togoa Cinematic" + +#~ msgid "Waving Water" +#~ msgstr "Waving maji" + +#~ msgid "Waving water" +#~ msgstr "Waving maji" + +#, fuzzy +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Kama freetype fonti hutumiwa, inahitaji msaada wa freetype kuwa " +#~ "alikusanya katika." + +#, fuzzy +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Y ya upper kikomo ya kubwa pseudorandom cellars." + +#~ msgid "Yes" +#~ msgstr "Ndio" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Umekufa." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/th/minetest.po b/po/th/minetest.po new file mode 100644 index 0000000..03ce5e4 --- /dev/null +++ b/po/th/minetest.po @@ -0,0 +1,8085 @@ +msgid "" +msgstr "" +"Project-Id-Version: Thai (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-03-18 01:05+0000\n" +"Last-Translator: Thomas Wiegand <weblate.org@wiegand.info>\n" +"Language-Team: Thai <https://hosted.weblate.org/projects/minetest/minetest/" +"th/>\n" +"Language: th\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.12-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "ขนาดสูงสุดของคิวการแชทนอก" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "คำสั่งว่างเปล่า" + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "ออกไปยังเมนูหลัก" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "คำสั่งไม่ถูกต้อง: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "คำสั่งที่มีปัญหา: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "รายชื่อผู้เล่นที่ออนไลน์" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "ผู้เล่นที่ออนไลน์: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "คิวนอกแชทว่างเปล่า" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "คำสั่งนี้ถูกปิดการใช้งานโดยเซิร์ฟเวอร์" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "เกิดใหม่" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "คุณตายแล้ว" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "คำสั่งที่ใช้ได้:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "คำสั่งที่ใช้ได้: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "ไม่มีคำสั่ง: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "รับความช่วยเหลือสำหรับการพิมพ์คำสั่ง" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"ใช้ '.help <cmd>' เพื่อรับข้อมูลเพิ่มเติม หรือใช้ '.help all' เพื่อแสดงรายการคำสั่งทั้งหมด" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[ทั้งหมด | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "ตกลง" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<ไม่มี>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "เกิดข้อผิดพลาดในสคริปต์ลูอา เช่น ม็อด:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "เกิดข้อผิดพลาดขึ้น:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "เมนูหลัก" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "เชื่อมต่อใหม่" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "เซิร์ฟเวอร์ได้ร้องขอการเชื่อมต่อใหม่:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "เลือก Mods" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "เวอร์ชันโปรโทคอลไม่ตรงกัน " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "เซิร์ฟเวอร์บังคับใช้โปรโตคอลเวอร์ชัน $1 " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "เซิร์ฟเวอร์ที่สนับสนุนเวอร์ชันโพรโทคอลระหว่าง $1 และ $2 " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "เราสนับสนุนโพรโทคอลเวอร์ชัน $1 เท่านั้น" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "เราสนับสนุนโพรโทคอลระหว่างเวอร์ชัน $1 และ $2" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "ยกเลิก" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "ไฟล์อ้างอิง:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "ปิดใช้งานทั้งหมด" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "ปิดใช้งานม็อดแพ็ค" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "เปิดใช้งานทั้งหมด" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "เปิดใช้งานม็อดแพ็ค" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"ไม่สามารถเปิดใช้งานม็อด '$1' ซึ่งประกอบด้วยตัวอักษรที่ไม่ได้รับอนุญาต ตัวอักษร [a-z0-9_] " +"เท่านั้นที่ได้รับอนุญาต" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "ค้นหา Mods เพิ่มเติม" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "ม็อด:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "ไม่มีการพึ่งพา (ไม่จำเป็น)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "ไม่มีคำอธิบายของเกมที่ให้มา" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "ไม่มีการอ้างอิง" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "ไม่มีคำอธิบายของม็อดแพ็คที่ให้มา" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "เสริม อ้างอิง" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "ไฟล์อ้างอิงที่เลือกใช้ได้:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "บันทึก" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "โลก:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "เปิดใช้งานแล้ว" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "มี \"$1\" อยู่แล้ว คุณต้องการเขียนทับหรือไม่ ?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "การอ้างอิง $1 และ $2 จะถูกติดตั้ง." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 โดย $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 กำลังดาวน์โหลด,\n" +"$2 เข้าคิว" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 โหลด ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 ไม่พบการพึ่งพาที่จำเป็น." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 จะถูกติดตั้ง และการขึ้นต่อกัน $2 จะถูกข้ามไป." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "แพคเกจทั้งหมด" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "ติดตั้งแล้ว" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "กลับไปยังเมนูหลัก" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "เกมพื้นฐาน:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB ไม่พร้อมใช้งานเมื่อรวบรวม Minetest โดยไม่มี cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "โหลด ..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "ไม่สามารถดาวน์โหลด $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "เกม" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "ติดตั้ง" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "ติดตั้ง $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "ไฟล์อ้างอิงที่เลือกใช้ได้" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "ติดตั้ง: ประเภทไฟล์ที่ไม่รองรับหรือไฟล์เก็บถาวรที่ใช้งานไม่ได้" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "ม็อด" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "ไม่สามารถเรียกแพคเกจได้" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "ไม่มีผลลัพธ์" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "ไม่มีการปรับปรุง" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "ไม่พบ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "เขียนทับ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "โปรดตรวจสอบว่าเกมหลักถูกต้อง." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "เข้าคิว" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "เทกซ์เจอร์แพ็ค" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "ถอนการติดตั้ง" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "อัปเดต" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "อัปเดต All [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "ดูข้อมูลเพิ่มเติมในเว็บเบราว์เซอร์" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "โลกที่ชื่อว่า '$1' มีอยู่แล้ว" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "ภูมิประเทศเพิ่มเติม" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "ระดับความสูงที่หนาวเย็น" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "ระดับความสูงแห้ง" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "การผสมไบโอม" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "ไบโอมส์" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "ถ้ำ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "ถ้ำ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "สร้าง" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "ของตกแต่ง" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "คำเตือน: การทดสอบพัฒนาน้อยที่สุดมีความหมายสำหรับนักพัฒนา." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "ดันเจี้ยน" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "ภูมิประเทศเรียบ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "ผืนดินที่ลอยอยู่บนท้องฟ้า" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Floatlands (ทดลอง)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "สร้างภูมิประเทศที่ไม่เป็นเศษส่วน: มหาสมุทรและใต้ดิน" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "ฮิลส์" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "แม่น้ำชื้น" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "เพิ่มความชื้นรอบแม่น้ำ" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "ติดตั้ง $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "ทะเลสาบ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "ความชื้นต่ำและความร้อนสูงทำให้แม่น้ำตื้นหรือแห้ง" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "การสร้างแผนที่" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "แผนที่สร้างธง" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "แผนที่สร้างธงเฉพาะ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "ภูเขา" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "โคลนไหล" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "เครือข่ายอุโมงค์และถ้ำ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "ไม่มีเกมที่ถูกเลือก" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "ลดความร้อนด้วยระดับความสูง" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "ลดความชื้นด้วยระดับความสูง" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "แม่น้ำ" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "แม่น้ำระดับน้ำทะเล" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "เมล็ดพันธุ์" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "การเปลี่ยนแปลงที่ราบรื่นระหว่างไบโอม" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "โครงสร้างที่ปรากฏบนภูมิประเทศ (ไม่มีผลต่อต้นไม้และหญ้าป่าที่สร้างโดย v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "โครงสร้างที่ปรากฏบนภูมิประเทศ โดยทั่วไปแล้วจะเป็นต้นไม้และพืช" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "อบอุ่น, ทะเลทราย" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "อบอุ่น, ทะเลทราย, ป่า" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "อบอุ่น, ทะเลทราย, ป่า, ทุนดรา, ไทกา" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "การพังทลายของพื้นผิวดิน" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "ต้นไม้และหญ้าป่า" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "ความลึกของแม่น้ำที่แตกต่างกัน" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "ถ้ำขนาดใหญ่ที่อยู่ลึกลงไปใต้ดิน" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "ชื่อโลก" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "คุณไม่มีเกมที่ติดตั้ง" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "คุณแน่ใจหรือไม่ที่จะต้องการลบ '$1' ?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "ลบ" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: ไม่สามารถลบ \"$1\" ได้" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: พาธของ \"$1\" ไม่ถูกต้อง" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "ลบโลก \"$1\" หรือไม่ ?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "ยืนยันรหัสผ่าน" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "ชื่อแมพเก็น" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "ชื่อ" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "รหัสผ่าน" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "รหัสผ่านไม่ตรงกับ!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "ลงทะเบียน และเข้าร่วม" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "ยอมรับ" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "เปลี่ยนชื่อม็อดแพ็ค:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "ม็อดแพ็คมีชื่อชื่อที่ถูกตั้งในไฟล์ modpack.conf ซึ่งจะแทนที่ชื่อที่เปลี่ยนตรงนี้" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(ไม่มีคำอธิบายของการตั้งค่าที่ให้มา)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D นอยส์" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< กลับไปที่หน้าการตั้งค่า" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "เรียกดู" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "เนื้อหา" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "เนื้อหา" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "ปิดการใช้งานแล้ว" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "แก้ไข" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "เปิดใช้งานแล้ว" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "ความไม่ชัดเจน" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Octaves" +msgstr "ความละเอียดของการสุ่ม" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "ค่าชดเชย" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "วิริยะ" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "โปรดใส่ค่าเป็นตัวเลขในรูปแบบที่ถูกต้อง" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "กรุณาใส่หมายเลขที่ถูกต้อง" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "คืนค่าเริ่มต้น" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "ขนาด" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "ค้นหา" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "เลือกไดเรกทอรี" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "เลือกไฟล์" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "แสดงชื่อทางเทคนิค" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "ต้องมีค่าอย่างน้อย $1" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "ค่าต้องไม่มากกว่า $1" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X กระจาย" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y กระจาย" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z กระจาย" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "ค่าผันแปรการสุ่มสร้างแผนที่" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "เริ่มต้น" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "ความนุ่มนวลของพื้นผิวบนทางลาด" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (เปิดใช้งาน)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 Mods" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "ไม่สามารถติดตั้ง $1 ถึง $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "ติดตั้ง Mod: ไม่สามารถค้นหาชื่อจริงของ mod: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "ติดตั้ง Mod: ไม่สามารถค้นหาชื่อของโฟลเดอร์ที่เหมาะสมสำหรับ modpack $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "ค้าหาไม่พบ mod หรือ modpack" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "ไม่สามารถติดตั้งพื้นผิว Texture $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "ไม่สามารถติดตั้งเกม $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "ไม่สามารถติดตั้ง mod $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "ไม่สามารถติดตั้ง modpack ที่ $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "กำลังโหลด..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "รายชื่อเซิร์ฟเวอร์สาธารณะถูกปิดใช้งาน" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "ลองเปิดใช้งานเซิร์ฟเวอร์ลิสต์สาธารณะอีกครั้งและตรวจสอบการเชื่อมต่ออินเทอร์เน็ต" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "เกี่ยวกับ" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "ผู้ร่วมให้ข้อมูล" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "ตัวแสดงผลที่ใช้งานอยู่:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "นักพัฒนาหลัก" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "เปิดไดเรกทอรีข้อมูลผู้ใช้" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"เปิดไดเร็กทอรีที่มีโลก เกม ม็อด\n" +"และแพ็คพื้นผิวในตัวจัดการไฟล์ / ตัวสำรวจ" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "ผู้สนับสนุนก่อนหน้า" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "นักพัฒนาหลักก่อนหน้า" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "แสดงข้อมูลการดีบัก" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "เรียกดูเนื้อหาออนไลน์" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "เนื้อหา" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "ปิดการใช้งานพื้นผิว Texture" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "ข้อมูล:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "ติดตั้งแพคเกจ:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "ไม่มีการอ้างอิง." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "ไม่มีแพคเกจมีคำอธิบาย" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "เปลี่ยนชื่อ" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "ถอนการติดตั้งแพคเกจ" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "ใช้พื้นผิว Texture" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "ประกาศ เซิร์ฟเวอร์" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "ผูกที่อยู่" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "โหมดสร้างสรรค์" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "เปิดใช้งานความเสียหาย" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "โฮสต์เกม" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "เซิร์ฟเวอร์" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "ติดตั้งเกมจาก ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "ใหม่" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "ยังไม่มีการสร้างโลก หรือยังไม่ได้เลือก!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "เล่นเกม" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "พอร์ต" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "เลือก Mods" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "เลือกโลก:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "เซิร์ฟเวอร์ พอร์ต" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "เริ่มเกม" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "ที่อยู่" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "ล้าง" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "โหมดสร้างสรรค์" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "ดาเมจ / ผู้เล่นผ่านเครื่องเล่น" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "รายการโปรด" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "เซิร์ฟเวอร์ที่เข้ากันไม่ได้" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "เข้าร่วมเกม" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "เวลาตอบสนอง" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "เซิฟเวอร์สาธารณะ" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "รีเฟรช" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "รีโมตพอร์ต" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "คำอธิบายเซิร์ฟเวอร์" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D เมฆ" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "การตั้งค่าทั้งหมด" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "ลบรอยหยัก:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "ขนาดหน้าจอบันทึกอัตโนมัติ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "กรอง bilinear" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "เปลี่ยนคีย์" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "เชื่อมต่อแก้ว" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "เงาแบบไดนามิก" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "เงาแบบไดนามิก: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "ใบไม้" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "สูง" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "ต่ำ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "ปานกลาง" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "แผนที่ย่อ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "แผนที่ย่อ + Aniso.กรอง" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "ไม่มีตัวกรอง" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "ไม่ Mipmap (แผนที่ย่อ)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "โหนที่เน้น" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "สรุป โหน" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "ไม่มี" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "ใบทึบ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "น้ำขุ่น" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "อนุภาค" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "หน้าจอ:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "การตั้งค่า" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "เฉดสี" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "เฉดสี (ไม่พร้อมใช้งาน)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "เฉดสี (ไม่พร้อมใช้งาน)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "ใบเรียบง่าย" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "โคมไฟเรียบ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "พื้นผิว:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "การแมปโทน" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "ขีด จำกัด: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "กรอง trilinear" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "สูงเป็นพิเศษ" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "ต่ำมาก" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "ใบโบก" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "โบกของเหลว" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "โบกไม้" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "ข้อผิดพลาดการเชื่อมต่อ (หมดเวลา?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "การเชื่อมต่อหมดเวลา" + +#: src/client/client.cpp +msgid "Done!" +msgstr "ทำ!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "เริ่มต้นโหน" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "เริ่มต้นโหน..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "โหลดพื้นผิว..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "บูรณะ shaders..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "ข้อผิดพลาดการเชื่อมต่อ (หมดเวลา?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "ไม่พบหรือโหลดเกม: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "ข้อมูลจำเพาะเกี่ยวกับเกม ไม่ถูกต้อง." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "เมนูหลัก" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "โลกไม่เลือกและไม่มีที่อยู่ที่ให้ไว้. ไม่มีอะไรทำ." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "ชื่อเล่นนานเกินไป." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "กรุณาเลือกชื่อ!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "รหัสผ่านให้ไฟล์ไม่สามารถเปิด " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "โลกมีเส้นไม่มี: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"ตรวจสอบรายละเอียด debug.txt." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "-ที่อยู่: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "-โหมด: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "-พอร์ต: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "-ประชาชน: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- ผู้เล่นวีซ่าผู้เล่น: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "-ชื่อเซิร์ฟเวอร์: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "เกิดข้อผิดพลาดในการทำให้เป็นอันดับ:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "ปฏิเสธการเข้าใช้. เหตุผล: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "ปิดใช้งานการส่งต่ออัตโนมัติ" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "เปิดใช้งานการส่งต่ออัตโนมัติ" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "บล็อกขอบเขตที่ซ่อนอยู่" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "แสดงขอบเขตบล็อกสำหรับบล็อกทั้งหมด" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "ขอบเขตบล็อกที่แสดงสำหรับบล็อกปัจจุบัน" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "แสดงขอบเขตบล็อกสำหรับบล็อกใกล้เคียง" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "ปิดใช้งานการอัปเดตกล้องแล้ว" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "เปิดใช้งานการอัปเดตกล้องแล้ว" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "ไม่สามารถแสดงขอบเขตการบล็อก (ต้องการสิทธิ์ 'basic_debug')" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "เปลี่ยนรหัสผ่าน" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "ปิดใช้งานโหมดภาพยนตร์" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "เปิดใช้งานโหมดภาพยนตร์" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "ไคลเอ็นต์ถูกตัดการเชื่อมต่อ" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "การเขียนสคริปต์ฝั่งไคลเอ็นต์ถูกปิดใช้งาน" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "เชื่อมต่อกับเซิร์ฟเวอร์" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "การเชื่อมต่อล้มเหลวโดยไม่ทราบสาเหตุ" + +#: src/client/game.cpp +msgid "Continue" +msgstr "ต่อ" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"การควบคุม:\n" +"- %s: เคลื่อนที่ไปข้างหน้า\n" +"- %s: เคลื่อนที่ไปข้างหลัง\n" +"- %s: เคลื่อนที่ไปทางซ้าย\n" +"- %s: เคลื่อนที่ไปทางขวา\n" +"- %s: กระโดด/ปีนขึ้น\n" +"- %s: ขุด/ชก\n" +"- %s: วาง/ใช้\n" +"- %s: ช่องเก็บของ\n" +"- %s: เมาส์: หัน/มอง\n" +"- %s: เมาส์ซ้าย: ขุด/ชก\n" +"- เมาส์ขวา: วาง/ใช้\n" +"- ลูกกลิ้งเมาส์: เลือกไอเทม\n" +"- %s: เปิดช่องแชท\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "ไม่สามารถแก้ไขที่อยู่: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "สร้างไคลเอ็นต์..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "การสร้างเซิร์ฟเวอร์..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "ข้อมูลการดีบักและกราฟตัวสร้างโปรไฟล์ถูกซ่อน" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "แสดงข้อมูลการดีบัก" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "ข้อมูลการแก้ปัญหากราฟ profiler และ wireframe ซ่อนอยู่" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"การควบคุมเริ่มต้น:\n" +"ไม่ปรากฏเมนู:\n" +"- แตะเพียงครั้งเดียว: เปิดใช้งานปุ่ม\n" +"- แตะสองครั้ง: สถานที่ / การใช้งาน\n" +"- นิ้วสไลด์: มองไปรอบ ๆ\n" +"เมนู / คลังโฆษณาปรากฏ:\n" +"- แตะสองครั้ง (นอก):\n" +"-> ใกล้\n" +"- สแต็กสัมผัส, สล็อตสัมผัส:\n" +"-> ย้ายสแต็ก\n" +"- แตะแล้วลากแตะนิ้วที่สอง\n" +"-> วางรายการเดียวไปยังสล็อต\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "ปิดใช้งานช่วงการดูไม่ จำกัด" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "เปิดใช้งานช่วงการดูที่ไม่ จำกัด" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "สร้างไคลเอ็นต์..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "ออกจากเมนู" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "อธิบายระบบปฏิบัติการ" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "ปิดใช้งานโหมดเร็ว" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "เปิดใช้งานโหมดรวดเร็ว" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "เปิดใช้งานโหมดเร็ว (หมายเหตุ: ไม่มีสิทธิ์ 'เร็ว')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "โหมดการบินปิด" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "โหมดการบินเปิดใช้งาน" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "โหมดการบินเปิดใช้งาน (หมายเหตุ: ไม่มีสิทธิ์ 'บิน' )" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "หมอกปิดการใช้งาน" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "หมอกเปิดใช้งาน" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "ข้อมูลเกม:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "เกมหยุดชั่วคราว" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "เซิร์ฟเวอร์ที่โฮสต์" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "ข้อกำหนดของสินค้า..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "สื่อ..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "แผนที่ย่อในปัจจุบันถูกปิดใช้งานโดยเกมหรือตัวดัดแปลง" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "ผู้เล่นหลายคน" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "ปิดใช้งานโหมด Noclip" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "เปิดใช้งานโหมด Noclip" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "เปิดใช้งานโหมด Noclip (หมายเหตุ: ไม่มีสิทธิ์ 'noclip')" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "กำหนดโหน..." + +#: src/client/game.cpp +msgid "Off" +msgstr "ปิด" + +#: src/client/game.cpp +msgid "On" +msgstr "บน" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "ปิดใช้งานโหมดย้ายสนาม" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "สนามย้ายเปิดใช้โหมด" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "แสดงกราฟ Profiler" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "เซิร์ฟเวอร์ระยะไกล" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "การแก้ไขที่อยู่..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "ปิด..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "เล่นคนเดียว" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "ระดับเสียง" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "เสียงเสียง" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "ระบบเสียงปิดอยู่" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "ไม่รองรับระบบเสียงในบิลด์นี้" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "เสียงไม่ปิดเสียง" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "เซิร์ฟเวอร์อาจใช้งานเวอร์ชันอื่นของ %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "ไม่สามารถเชื่อมต่อกับ %s เนื่องจาก IPv6 ถูกปิดใช้งาน" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "ไม่สามารถฟังบน %s เพราะ IPv6 ถูกปิดใช้งาน" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "ช่วงการดูเปลี่ยนเป็น %d1" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "ระยะการดูสูงสุดที่: %d1" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "ช่วงการดูเป็นอย่างน้อย: %d1" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "ปริมาตรที่เปลี่ยนไป %d1%%2" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "แสดงโครงลวด" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "ซูมถูกปิดใช้งานในปัจจุบันโดยเกมหรือตัวดัดแปลง" + +#: src/client/game.cpp +msgid "ok" +msgstr "ตกลง" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "สนทนาซ่อนอยู่" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "สนทนาแสดง" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "ผิวที่ซ่อน" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "ผิวแสดง" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "สร้างโปรไฟล์ซ่อน" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "สร้างโปรไฟล์ที่แสดง (หน้า %d1 of %d2)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "แอ" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "แบ็คสเปซ" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "แคปล็อค" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "ควบคุม" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "ลง" + +#: src/client/keycode.cpp +msgid "End" +msgstr "สิ้นสุด" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "ลบ EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "ดำเนินการ" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "ช่วย" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "บ้าน" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME รับ" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME แปลง" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME หนี" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "การเปลี่ยนโหมด IME" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME ไม่แปลง" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "ใส่" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "ด้านซ้าย" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "ปุ่มซ้าย" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "ด้านซ้าย Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "ด้านซ้าย Menu" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "ข้อกะ" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "หน้าต่างซ้าย" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "เมนู" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "ปุ่มกลาง" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "ล็อคหมายเลข" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "ตัวเลข *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "ตัวเลข +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "ตัวเลข -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "ตัวเลข ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "ตัวเลข /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "ตัวเลข 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "ตัวเลข 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "ตัวเลข 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "ตัวเลข 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "ตัวเลข 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "ตัวเลข 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "ตัวเลข 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "ตัวเลข 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "ตัวเลข 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "ตัวเลข 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM ล้าง" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "เพลง" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "หน้าขึ้น" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "หยุด" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "เล่น" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "พิมพ์" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "กลับ" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "สิทธิ" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "ปุ่มขวา" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "สิทธิ Control" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "สิทธิ Menu" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "สิทธิ Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "หน้าต่างขวา" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "ล็อคเลื่อน" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "เลือก" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "กะ" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "สลี" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "ภาพรวม" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "ช่องว่าง" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "แท็บ" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "ค่า" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X ปุ่ม 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X ปุ่ม 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "ซูม" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "แผนที่ย่อซ่อนอยู่" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "แผนที่ย่อในโหมดเรดาร์, ซูม x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "แผนที่ย่อในโหมด surface, ซูม x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "แผนที่ย่อในโหมดพื้นผิว" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "ไม่สามารถเปิดหน้าเว็บ" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "เปิดหน้าเว็บ" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "ดำเนินการ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = ปีนลง" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "ส่งต่ออัตโนมัติ" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "กระโดด อัตโนมัติ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "ย้อนหลัง" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "บล็อกขอบเขต" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "เปลี่ยนกล้อง" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "แช" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "คำสั่ง" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "คอนโซล" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "ลดลงช่วง" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "ปริมาณลดลง" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "แตะสองครั้งกระโดดสลับบิน" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "ปล่อย" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "ไปข้างหน้า" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "เพิ่มช่วง" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "เพิ่มระดับเสียง" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "สินค้าคงคลัง" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "กระโดด" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "คีย์ใช้" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "ท้องถิ่นคำสั่ง" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "ปิด" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "รายการถัดไป" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "รายการก่อนหน้า" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "ช่วงเลือก" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "ภาพหน้าจอ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "แอบ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "สลับ HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "บันทึกสนทนาสลับ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "สลับอย่างรวดเร็ว" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "สลับบิน" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "สลับหมอก" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "แผนที่ย่อสลับ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "สลับ noclip" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "สลับ pitchmove" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "กดปุ่ม" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "เปลี่ยน" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "รหัสผ่านใหม่" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "รหัสผ่านเก่า" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "รหัสผ่านไม่ตรงกับ!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "ออก" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "เสียง" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "ระดับเสียง: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "th" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "กรุณาเลือกชื่อ!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) แก้ไขตำแหน่งของจอยสติ๊กเสมือน\n" +"หากปิดใช้งานจอยสติกเสมือนจะอยู่ที่ตำแหน่งแรกของสัมผัส" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) ใช้จอยสติ๊กเสมือนเพื่อเรียกปุ่ม \"aux\"\n" +"หากเปิดใช้งานจอยสติกเสมือนจริงก็จะแตะปุ่ม \"aux\" เมื่ออยู่นอกวงกลมหลัก" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) ออฟเซ็ตของเศษส่วนจากศูนย์กลางโลกในหน่วยของ 'มาตราส่วน'\n" +"สามารถใช้เพื่อย้ายจุดที่ต้องการไปที่ (0, 0) เพื่อสร้าง a\n" +"จุดวางไข่ที่เหมาะสม หรือเพื่อให้ 'ซูมเข้า' ได้ตามต้องการ\n" +"ชี้โดยการเพิ่ม 'มาตราส่วน'.\n" +"ค่าดีฟอลต์ได้รับการปรับแต่งสำหรับจุดเกิดที่เหมาะสมสำหรับ Mandelbrot\n" +"ตั้งค่าด้วยพารามิเตอร์เริ่มต้น อาจต้องแก้ไขใน other\n" +"สถานการณ์.\n" +"ช่วงประมาณ -2 ถึง 2 คูณด้วย 'มาตราส่วน' สำหรับออฟเซ็ตในโหนด." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z) มาตราส่วนของเศษส่วนในโหนด.\n" +"ขนาดแฟร็กทัลจริงจะใหญ่กว่า 2 ถึง 3 เท่า.\n" +"ตัวเลขเหล่านี้สามารถสร้างได้มาก, เศษส่วนทำให้\n" +"ไม่จำเป็นต้องอยู่ในโลก.\n" +"เพิ่มสิ่งเหล่านี้เพื่อ 'ซูม' เข้าไปในรายละเอียดของเศษส่วน\n" +"ค่าเริ่มต้นคือสำหรับรูปร่างที่ถูกบีบอัดในแนวตั้งซึ่งเหมาะสำหรับ\n" +"เกาะตั้งทั้ง 3 ตัว เท่ากับรูปร่างดิบ." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "เสียง 2D ที่ควบคุมรูปร่าง/ขนาดของสันเขา." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "เสียง 2D ที่ควบคุมรูปร่าง/ขนาดของเนินเขา." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "เสียง 2D ที่ควบคุมรูปร่าง/ขนาดของขั้นบันได." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "เสียง 2D ที่ควบคุมขนาด/การเกิดขึ้นของทิวเขาที่เป็นแนวสันเขา." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "เสียง 2D ที่ควบคุมขนาด/การเกิดขึ้นของเนินเขา." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "เสียง 2D ที่ควบคุมขนาด/การเกิดของทิวเขาขั้นบันได." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "เสียง 2D ที่ระบุตำแหน่งหุบเขาและช่องแคบของแม่น้ำ." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "เมฆ 3 มิติ" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "โหมด 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "ความแรงของพารัลแลกซ์โหมด 3 มิติ" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "เสียง 3 มิติที่กำหนดถ้ำยักษ์." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"เสียงรบกวน 3 มิติที่กำหนดโครงสร้างและความสูงของภูเขา\n" +"ยังกำหนดโครงสร้างของภูมิประเทศภูเขาลอย." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"โครงสร้างการกำหนดสัญญาณรบกวน 3 มิติของพื้นที่ลอยน้ำ.\n" +"หากเปลี่ยนจากค่าเริ่มต้น อาจจำเป็นต้องใช้ 'มาตราส่วน' ของเสียง (0.7 โดยค่าเริ่มต้น)\n" +"ที่จะปรับเปลี่ยนได้เนื่องจากการเรียวของทุ่นลอยน้ำทำงานได้ดีที่สุดเมื่อมีเสียงนี้\n" +"ช่วงค่าประมาณ -2.0 ถึง 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "โครงสร้างกำหนดสัญญาณรบกวน 3 มิติของผนังหุบเขาแม่น้ำ." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "ภูมิประเทศที่กำหนดเสียงรบกวน 3 มิติ" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"เสียงรบกวน 3 มิติสำหรับส่วนที่ยื่นออกมาจากภูเขา หน้าผา ฯลฯ โดยปกติแล้วจะมีความแตกต่างเล็กน้อย." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "เสียง 3 มิติที่กำหนดจำนวนดันเจี้ยนต่อแมปชังค์." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"รองรับ 3D\n" +"รองรับในปัจจุบัน:\n" +"- ไม่มี: ไม่มีเอาต์พุต 3d\n" +"- anaglyph: cyan / magenta color 3d\n" +"- interlaced: การสนับสนุนหน้าจอโพลาไรเซชันแบบอิงเส้นคี่ / คู่\n" +"- topbottom: หน้าจอแยกด้านบน / ล่าง\n" +"- sidebyside: แบ่งหน้าจอทีละด้าน\n" +"- crossview: 3d สามมิติ\n" +"- pageflip: 3d จาก quadbuffer\n" +"โปรดทราบว่าโหมด interlaced จะต้องเปิดใช้ shaders" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"เมล็ดแผนที่ที่เลือกสำหรับแผนที่ใหม่ปล่อยว่างไว้สำหรับการสุ่ม.\n" +"จะถูกแทนที่เมื่อสร้างโลกใหม่ในเมนูหลัก." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "ข้อความที่จะแสดงต่อลูกค้าทั้งหมดเมื่อเซิร์ฟเวอร์ล่ม." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "ข้อความที่จะแสดงต่อไคลเอนต์ทั้งหมดเมื่อเซิร์ฟเวอร์ปิดตัวลง." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "ABM ช่วงเวลา" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "งบประมาณเวลาของ ABM" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "ขีด จำกัด ที่แน่นอนของบล็อกที่เข้าคิวที่จะเกิดขึ้น" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "ความเร่งในอากาศ" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "ความเร่งของแรงโน้มถ่วง เป็นโหนดต่อวินาทีต่อวินาที" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "ตัวดัดแปลงบล็อกที่ใช้งานอยู่" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "ช่วงการจัดการบล็อกที่ใช้งานอยู่" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "ช่วงบล็อกที่ใช้งานอยู่" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "ช่วงการส่งวัตถุที่ใช้งานอยู่" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"ที่อยู่เพื่อเชื่อมต่อ\n" +"เว้นว่างไว้เพื่อเริ่มเซิร์ฟเวอร์ภายใน\n" +"โปรดทราบว่าฟิลด์ที่อยู่ในเมนูหลักจะแทนที่การตั้งค่านี้" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "เพิ่มอนุภาคเมื่อขุดโหนด." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"ปรับการกำหนดค่า dpi ให้กับหน้าจอของคุณ (ไม่ใช่ X11 / Android เท่านั้น) เช่น สำหรับหน้าจอ " +"4k." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "ปรับความหนาแน่นของการแสดงผลที่ตรวจพบ ซึ่งใช้สำหรับปรับขนาดองค์ประกอบ UI" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"ปรับความหนาแน่นของชั้นทุ่นลอยน้ำ.\n" +"เพิ่มมูลค่าเพื่อเพิ่มความหนาแน่น บวกหรือลบก็ได้.\n" +"มูลค่า = 0.0: 50% ของปริมาตรเป็นพื้นที่ลอยน้ำ.\n" +"ค่า = 2.0 (อาจสูงกว่านี้ขึ้นอยู่กับ 'mgv7_np_floatland' ให้ทดสอบเสมอ\n" +"เพื่อให้แน่ใจว่า) สร้างชั้นทุ่นลอยน้ำที่มั่นคง." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "ผนวกชื่อรายการ" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "สูง" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"เปลี่ยนเส้นโค้งแสงโดยใช้ 'การแก้ไขแกมมา'.\n" +"ค่าที่สูงขึ้นจะทำให้ระดับแสงกลางและแสงล่างสว่างขึ้น.\n" +"ค่า '1.0' ปล่อยให้เส้นโค้งแสงไม่เปลี่ยนแปลง.\n" +"สิ่งนี้มีผลอย่างมากต่อแสงแดดและประดิษฐ์\n" +"แสงมีผลน้อยมากต่อแสงธรรมชาติในตอนกลางคืน." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "บินเสมอ และรวดเร็ว" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "แกมมาบดเคี้ยวโดยรอบ" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "จำนวนข้อความที่ผู้เล่นสามารถส่งได้ต่อ 10 วินาที" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "ขยายหุบเขา." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "ตัวกรอง Anisotropic" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "ประกาศเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "ประกาศไปยังรายการเซิร์ฟเวอร์นี้." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "ผนวกชื่อรายการ" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "ต่อท้ายชื่อรายการในคำแนะนำเครื่องมือ." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "เสียงต้นแอปเปิ้ล" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "แขนเฉื่อย" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"แขนความเฉื่อยทำให้เกิดการเคลื่อนไหวที่สมจริงยิ่งขึ้น\n" +"แขนเมื่อกล้องเคลื่อนไหว" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "ขอให้เชื่อมต่ออีกครั้งหลังจากเกิดข้อผิดพลาด" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"ในระยะนี้เซิร์ฟเวอร์จะปรับให้เหมาะสมที่สุดว่าจะส่งบล็อกใดบ้าง\n" +"ลูกค้า.\n" +"ค่าเล็กน้อยอาจช่วยปรับปรุงประสิทธิภาพได้มาก โดยที่ค่าใช้จ่ายที่มองเห็นได้\n" +"ข้อผิดพลาดในการแสดงผล (บางช่วงจะไม่แสดงใต้น้ำและในถ้ำ\n" +"และบางครั้งบนบก).\n" +"การตั้งค่านี้เป็นค่าที่มากกว่า max_block_send_distance ปิดการใช้งานนี้\n" +"การเพิ่มประสิทธิภาพ.\n" +"ระบุไว้ใน mapblocks (16 โหนด)." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "ปุ่มส่งต่ออัตโนมัติ" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "กระโดดขึ้นอุปสรรคเดียวโหน โดยอัตโนมัติ." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "รายงานโดยอัตโนมัติไปยังรายการเซิร์ฟเวอร์." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "บันทึกขนาดหน้าจออัตโนมัติ" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "โหมดปรับอัตโนมัติ" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "ปุ่มกระโดด" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "คีย์พิเศษสำหรับการปีนขึ้น/ลง" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "ปุ่มย้อนกลับ" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "ระดับพื้นฐาน" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "ความสูงของภูมิประเทศฐาน." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "สิทธิพิเศษพื้นฐาน" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "เสียงชายหาด" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "เกณฑ์เสียงชายหาด" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "การกรอง Bilinear" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "ผูกที่อยู่" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "พารามิเตอร์เสียงอุณหภูมิและความชื้นของ Biome API" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "เสียงไบโอม" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "บล็อกส่งระยะทางเพิ่มประสิทธิภาพ" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "ไดเรกเตอรีฟอนต์หนาเอียง" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "ไดเรกเตอรีฟอนต์หนาเอียงสำหรับฟอนต์ขนาดคงที่" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "ไดเรกเตอรีฟอนต์หนา" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "ไดเรกเตอรีฟอนต์หนาแบบขนาดคงที่" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "สร้างภายในเครื่องเล่น" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "ในตัว" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "เปลี่ยนกล้อง" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"กล้องอยู่ใกล้ระยะทางระนาบในโหนดระหว่าง 0 ถึง 0.5\n" +"ผู้ใช้ส่วนใหญ่ไม่จำเป็นต้องเปลี่ยนแปลงสิ่งนี้.\n" +"การเพิ่มขึ้นสามารถลดสิ่งประดิษฐ์ใน GPU ที่อ่อนแอกว่าได้.\n" +"0.1 = ค่าเริ่มต้น, 0.25 = คุ้มค่าสำหรับแท็บเล็ตที่อ่อนแอกว่า." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "กล้องเรียบ" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "กล้องที่ปรับในโหมดภาพยนตร์" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "ปุ่มสลับการอัพเดตกล้อง" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "เสียงถ้ำ" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "เสียงถ้ำ #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "เสียงถ้ำ #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "ความกว้างของถ้ำ" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "ถ้ำ1เสียง" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "ถ้ำ2เสียง" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "ขีดจำกัดของถ้ำ" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "เสียงถ้ำ" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "ถ้ำเทเปอร์" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "ธรณีประตูถ้ำ" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "ขีดจำกัดบนของถ้ำ" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"ศูนย์กลางของช่วงเพิ่มส่วนโค้งของแสง.\n" +"โดยที่ 0.0 คือระดับแสงต่ำสุด 1.0 คือระดับแสงสูงสุด." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "เกณฑ์ข้อความเวลาคำสั่งแชท" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "คำสั่งแชท" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "ขนาดฟอนต์ในแชท" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "รหัสแชท" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "ปุ่มสลับการแชท" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "ขีด จำกัด จำนวนข้อความแชท" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "ข้อความขัดข้อง" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "เกณฑ์การเตะข้อความแชท" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "ความยาวสูงสุดของข้อความแชท" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "ปุ่มสลับการแชท" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "สนทนาแสดง" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "ขนาดก้อน" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "โหมดภาพยนตร์" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "ปุ่มโหมดโรงภาพยนตร์" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "ทำความสะอาดพื้นผิวโปร่งใส" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "เว็บลิงก์ที่คลิกได้ (คลิกกลางหรือ Ctrl+คลิกซ้าย) เปิดใช้งานในเอาต์พุตคอนโซลแชท." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "ไคลเอนต์" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "ไคลเอนต์และเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "ลูกค้า modding" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "ข้อจำกัดในการปรับแต่งฝั่งไคลเอ็นต์" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "ข้อจำกัดช่วงการค้นหาโหนดฝั่งไคลเอ็นต์" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "ลูกค้า modding" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "ความเร็วในการปีนเขา" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "รัศมีเมฆ" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "เมฆ" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "เมฆเป็นผลข้างเคียงของลูกค้า" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "มีเมฆในเมนู" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "หมอกสี" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "หมอกสี" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"รายการแฟล็กที่คั่นด้วยเครื่องหมายจุลภาคเพื่อซ่อนในที่เก็บเนื้อหา.\n" +"สามารถใช้ \"nonfree\" เพื่อซ่อนแพ็คเกจที่ไม่เข้าข่ายเป็น 'ซอฟต์แวร์ฟรี'\n" +"ตามที่กำหนดโดยมูลนิธิซอฟต์แวร์เสรี.\n" +"คุณยังสามารถระบุการจัดประเภทเนื้อหา.\n" +"แฟล็กเหล่านี้ไม่ขึ้นกับเวอร์ชัน Minetest\n" +"เพื่อดูรายการทั้งหมดที่ https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"รายการม็อดคั่นด้วยเครื่องหมายจุลภาคที่อนุญาตให้เข้าถึง HTTP API ซึ่ง\n" +"อนุญาตให้อัปโหลดและดาวน์โหลดข้อมูลไปยัง/จากอินเทอร์เน็ต" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"รายการที่คั่นด้วยเครื่องหมายจุลภาคของม็อดที่เชื่อถือได้ซึ่งได้รับอนุญาตให้เข้าถึงที่ไม่ปลอดภัย\n" +"ทำงานแม้ในขณะที่การรักษาความปลอดภัย mod เปิดอยู่ (ผ่าน " +"request_insecure_environment())." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "คีย์คำสั่ง" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"ระดับการบีบอัดที่จะใช้เมื่อบันทึก mapblocks ไปยังดิสก์.\n" +"-1 - ใช้ระดับการบีบอัดเริ่มต้น\n" +"0 - บีบอัดน้อยที่สุด เร็วที่สุด\n" +"9 - การบีบอัดที่ดีที่สุด ช้าที่สุด" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"ระดับการบีบอัดที่จะใช้เมื่อส่ง mapblock ไปยังไคลเอนต์.\n" +"-1 - ใช้ระดับการบีบอัดเริ่มต้น\n" +"0 - บีบอัดน้อยที่สุด เร็วที่สุด\n" +"9 - การบีบอัดที่ดีที่สุด ช้าที่สุด" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "เชื่อมกระจก" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "เชื่อมต่อกับเซิร์ฟเวอร์สื่อภายนอก" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "เชื่อมต่อ glass ถ้าสนับสนุนโดยโหนด" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "คอนโซลอัลฟ่า" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "สีคอนโซล" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "ความสูงของคอนโซล" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "ที่เก็บเนื้อหาออนไลน์" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "ContentDB ตั้งค่าสถานะบัญชีดำ" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "ดาวน์โหลด ContentDB Max พร้อมกัน" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "url ฐานข้อมูลเนื้อหา" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "ไปข้างหน้าอย่างต่อเนื่อง" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"การเคลื่อนที่ไปข้างหน้าอย่างต่อเนื่องสลับโดยคีย์ autoforward.\n" +"กดปุ่ม autoforward อีกครั้งหรือเคลื่อนไหวไปข้างหลังเพื่อปิดการใช้งาน." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "ควบคุม" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"ควบคุมความยาวของรอบกลางวัน/กลางคืน.\n" +"ตัวอย่าง:\n" +"72 = 20 นาที 360 = 4 นาที 1 = 24 ชั่วโมง 0 = วัน/คืน/อะไรก็ตามที่ไม่เปลี่ยนแปลง." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "ควบคุมความชัน/ความลึกของความกดอากาศต่ำในทะเลสาบ." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "ควบคุมความชัน/ความสูงของเนินเขา." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"ควบคุมความกว้างของอุโมงค์ ค่าที่น้อยกว่าจะสร้างอุโมงค์ที่กว้างกว่า.\n" +"ค่า >= 10.0 ปิดใช้งานการสร้างช่องสัญญาณโดยสมบูรณ์และหลีกเลี่ยง\n" +"การคำนวณเสียงรบกวนอย่างเข้มข้น." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "ข้อความขัดข้อง" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "ความคิดสร้างสรรค์" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Crosshair อัลฟา" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Crosshair อัลฟา (ความทึบแสงระหว่าง 0 ถึง 255).\n" +"สิ่งนี้ใช้กับเป้าเล็งของวัตถุด้วย" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "สีของครอสแฮร์" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"สีเป้า (R,G,B).\n" +"ยังควบคุมสีเป้าเล็งของวัตถุ" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "ความเสียหาย" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "แก้ไขคีย์การสลับข้อมูล" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "เกณฑ์ขนาดไฟล์บันทึกการดีบัก" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "ระดับบันทึกดีบัก" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "ลดระดับเสียงที่สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "ขั้นตอนเซิร์ฟเวอร์เฉพาะ" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "ค่าความเร่งเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "เกมเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"เกมเริ่มต้นเมื่อสร้างโลกใหม่.\n" +"สิ่งนี้จะถูกแทนที่เมื่อสร้างโลกจากเมนูหลัก." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "รหัสผ่านเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "สิทธิพิเศษเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "รูปแบบรายงานเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "ค่าขนาดสแต็คเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"กำหนดคุณภาพการกรองเงา\n" +"สิ่งนี้จำลองเอฟเฟกต์เงาอ่อนโดยใช้ PCF หรือดิสก์ปัวซอง\n" +"แต่ยังใช้ทรัพยากรมากขึ้น" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "กำหนดพื้นที่ที่ต้นไม้มีแอปเปิ้ล." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "กำหนดพื้นที่ที่มีหาดทราย." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "กำหนดการกระจายของภูมิประเทศที่สูงขึ้นและความชันของหน้าผา." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "กำหนดการกระจายของภูมิประเทศที่สูงขึ้น." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "กำหนดขนาดเต็มของถ้ำ ค่าที่น้อยกว่าจะสร้างถ้ำที่ใหญ่ขึ้น." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "กำหนดโครงสร้างช่องน้ำขนาดใหญ่." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "กำหนดตำแหน่งและภูมิประเทศของเนินเขาและทะเลสาบที่เป็นตัวเลือก." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "กำหนดระดับพื้นดินฐาน." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "กำหนดความลึกของช่องแม่น้ำ." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "กำหนดระยะถ่ายโอนผู้เล่นสูงสุดในบล็อก (0 = ไม่ จำกัด )." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "กำหนดความกว้างของช่องแม่น้ำ." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "กำหนดความกว้างของหุบเขาแม่น้ำ." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "กำหนดพื้นที่ต้นไม้และความหนาแน่นของต้นไม้." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"การหน่วงเวลาระหว่างการอัพเดตเมชบนไคลเอ็นต์เป็นมิลลิวินาที การเพิ่มสิ่งนี้จะทำให้ช้าลง\n" +"ลดอัตราการอัพเดทของ mesh ซึ่งจะช่วยลดความกระวนกระวายใจของไคลเอนต์ที่ช้าลง" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "ความล่าช้าในการส่งบล็อกหลังการสร้าง" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "ความล่าช้าแสดงคำแนะนำเครื่องมือตามที่ระบุไว้ในมิลลิวินาที," + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "การจัดการ Lua API ที่เลิกใช้แล้ว" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "ความลึกด้านล่างซึ่งคุณจะพบถ้ำขนาดยักษ์." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "ความลึกด้านล่างซึ่งคุณจะพบถ้ำขนาดใหญ่." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "คำอธิบายของเซิร์ฟเวอร์ที่จะแสดงเมื่อผู้เล่นเข้าร่วมและในรายการเซิร์ฟเวอร์." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "ธรณีประตูเสียงทะเลทราย" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"ทะเลทรายเกิดขึ้นเมื่อ np_biome เกินค่านี้.\n" +"เมื่อเปิดใช้งานแฟล็ก 'snowbiomes' สิ่งนี้จะถูกละเว้น." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Desynchronize บล็อกภาพเคลื่อนไหว" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "ของตกแต่ง" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "ปุ่มขวา" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "ขุดอนุภาค" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "ปิดใช้งาน anticheat" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "ไม่อนุญาตรหัสผ่านที่ว่างเปล่า" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "ปัจจัยการปรับขนาดความหนาแน่นของจอแสดงผล" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "ชื่อโดเมนของเซิร์ฟเวอร์ที่จะแสดงในรายการเซิร์ฟเวอร์." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "แตะสองครั้งที่กระโดดสำหรับบิน" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "สำเร็จกระโดดปุ่มสลับโหมดการบิน." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "วางรหัสรายการ" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "ดัมพ์ข้อมูลการดีบัก mapgen." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "ดันเจี้ยนสูงสุด Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "ดันเจี้ยนขั้นต่ำ Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "เสียงดันเจี้ยน" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"เปิดใช้งานการสนับสนุน IPv6 (สำหรับทั้งไคลเอนต์และเซิร์ฟเวอร์).\n" +"จำเป็นสำหรับการเชื่อมต่อ IPv6 เพื่อให้ทำงานได้ทั้งหมด." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"เปิดใช้งานการสนับสนุน Lua modding บนไคลเอนต์\n" +"การสนับสนุนนี้เป็นการทดลองและ API สามารถเปลี่ยนแปลงได้" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"เปิดใช้งานการกรองดิสก์ปัวซอง.\n" +"บนทรูใช้ดิสก์ปัวซองเพื่อสร้าง \"เงาอ่อน\" มิฉะนั้นจะใช้การกรอง PCF." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +".เปิดใช้งานเงาสี\n" +"บนโหนดโปร่งแสงที่แท้จริงจะทำให้เกิดเงาสี. นี้มีราคาแพง." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "เปิดใช้งานหน้าต่างคอนโซล" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "เปิดใช้งานโหมดสร้างสรรค์สำหรับผู้เล่นทั้งหมด" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "เปิดใช้งานจอยสติ๊ก" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "เปิดใช้งานการรองรับช่องสัญญาณ mod." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "เปิดใช้งานการรักษาความปลอดภัยม็อด" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "ช่วยให้ผู้เล่นได้รับความเสียหายและกำลังจะตาย." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "เปิดใช้งานการป้อนข้อมูลผู้ใช้แบบสุ่ม (ใช้สำหรับการทดสอบเท่านั้น)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"เปิดใช้งานแสงที่ราบรื่นด้วยการบดเคี้ยวอย่างง่าย.\n" +"ปิดใช้งานสำหรับความเร็วหรือลักษณะที่แตกต่างกัน." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"เปิดใช้งานเพื่อไม่อนุญาตให้ลูกค้าเก่าเชื่อมต่อ.\n" +"ลูกค้าที่เก่ากว่าเข้ากันได้ในแง่ที่ว่าพวกเขาจะไม่ผิดพลาดเมื่อเชื่อมต่อ.\n" +"ไปยังเซิร์ฟเวอร์ใหม่ แต่อาจไม่รองรับคุณสมบัติใหม่ทั้งหมดที่คุณคาดหวัง." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"เปิดใช้งานการใช้เซิร์ฟเวอร์สื่อระยะไกล (ถ้ามีให้โดยเซิร์ฟเวอร์)\n" +"เซิร์ฟเวอร์ระยะไกลนำเสนอวิธีดาวน์โหลดสื่อที่รวดเร็วยิ่งขึ้น (เช่นพื้นผิว)\n" +"เมื่อเชื่อมต่อกับเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"เปิดใช้งานวัตถุบัฟเฟอร์จุดยอด.\n" +"สิ่งนี้ควรปรับปรุงประสิทธิภาพกราฟิกอย่างมาก." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"เปิดใช้งานการ จำกัด การดูและจำนวนการดาวน์โหลดที่ จำกัด\n" +"ตัวอย่างเช่น: 0 ที่ไม่มีการสั่น 1.0 สำหรับปกติ 2.0 สำหรับสองเท่า" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"เปิดใช้งาน / ปิดการใช้งานเซิร์ฟเวอร์ IPv6.\n" +"ข้ามไปหากตั้งค่า bind_address.\n" +"ต้องการ enable_ipv6 เพื่อเปิดใช้งาน" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"เปิดใช้งานการจับคู่โทนภาพยนตร์ 'Uncharted 2' ของ Hable.\n" +"จำลองเส้นโทนสีของฟิล์มถ่ายภาพและค่านี้ใกล้เคียงกับ\n" +"ลักษณะของภาพช่วงไดนามิกสูง ความเปรียบต่างระดับกลางเล็กน้อย\n" +"ปรับปรุง ไฮไลท์และเงาจะค่อยๆ บีบอัด." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "เปิดใช้งานภาพเคลื่อนไหวของรายการสินค้าคงคลัง." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "เปิดใช้งานการแคชของตาข่ายที่หมุนได้." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "เปิดใช้งานย่อแผนที่." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"เปิดใช้งานระบบเสียง.\n" +"หากปิดใช้งาน จะเป็นการปิดเสียงทั้งหมดในทุกที่และในเกม\n" +"การควบคุมเสียงจะไม่ทำงาน.\n" +"การเปลี่ยนการตั้งค่านี้ต้องรีสตาร์ท." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" +"เปิดใช้งานการแลกเปลี่ยนที่ลดโหลด CPU หรือเพิ่มประสิทธิภาพการเรนเดอร์\n" +"เนื่องจากความบกพร่องของภาพเล็กน้อยที่ไม่ส่งผลต่อการเล่นเกม." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "โปรไฟล์หุบเขา" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "ช่วงเวลาการพิมพ์ข้อมูลโปรไฟล์เครื่องยนต์" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "วิธีการนิติบุคคล" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"เลขชี้กำลังของการเรียวของทุ่นลอยน้ำ เปลี่ยนพฤติกรรมการเรียว.\n" +"ค่า = 1.0 สร้างการเรียวเชิงเส้นที่สม่ำเสมอ.\n" +"ค่า > 1.0 สร้างการเรียวที่ราบรื่นเหมาะสำหรับการแยกค่าเริ่มต้น\n" +"ทุ่นลอยน้ำ.\n" +"ค่า < 1.0 (เช่น 0.25) สร้างระดับพื้นผิวที่กำหนดมากขึ้นด้วย\n" +"ที่ราบลุ่มที่ราบเรียบเหมาะสำหรับชั้นทุ่นลอยน้ำที่เป็นของแข็ง." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "เฟรมต่อวินาที (FPS) สูงสุดเมื่อเกมหยุดชั่วคราว" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "ปัจจัยเสียง" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "ตกปัจจัยผลุบๆโผล่ๆ" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "แบบอักษรสำรอง" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "ปุ่มลัด" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "การเร่งความเร็วในโหมดเร็ว" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "ความเร็วโหมดเร็ว" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "การเคลื่อนไหวเร็ว" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"การเคลื่อนไหวที่รวดเร็ว (ผ่านคีย์ 'พิเศษ').\n" +"ต้องมีสิทธิ์ 'รวดเร็ว' บนเซิร์ฟเวอร์." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "สาขาดู" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "สาขาดูในองศา" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"ไฟล์ในไคลเอนต์ / เซิร์ฟเวอร์ / / ที่มีเซิร์ฟเวอร์โปรดของคุณแสดงอยู่ใน\n" +"แท็บผู้เล่นหลายคน" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "ความลึกของฟิลเลอร์" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "เสียงความลึกของฟิลเลอร์" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "การทำแผนที่โทนภาพยนตร์" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"พื้นผิวที่ถูกกรองสามารถผสมผสานค่า RGB กับเพื่อนบ้านที่โปร่งใสได้อย่างสมบูรณ์.\n" +"เครื่องมือเพิ่มประสิทธิภาพ PNG ใดที่มักจะละทิ้งซึ่งบางครั้งส่งผลให้มืดหรือ\n" +"ขอบแสงเป็นพื้นผิวโปร่งใส ใช้ตัวกรองนี้เพื่อล้างข้อมูล\n" +"ที่เวลาโหลดพื้นผิว." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "ลบรอยหยัก:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "เสียง 2D แรกจาก 4 เสียงที่ร่วมกันกำหนดความสูงของช่วงเนินเขา/ภูเขา." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "เสียง 3D สองรายการแรกที่กำหนดอุโมงค์ร่วมกัน." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "แก้ไขแผนที่เมล็ด" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "แก้ไขจอยสติ๊กเสมือนจริง" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "ความหนาแน่นของพื้นที่ลุ่มน้ำ" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Floatland สูงสุด Y" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Floatland ขั้นต่ำ Y" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "เสียงทุ่นลอยน้ำ" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "เลขชี้กำลังของ Floatland Taper" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "ระยะถ่ายโอนผู้เล่น" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "ระดับน้ำลอยน้ำ" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "ปุ่มบิน" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "บิน" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "หมอก" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "หมอกเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "ปุ่มสลับ Fog" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "ขนาดตัวอักษร" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "ตัวหนาตามค่าเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "ตัวเอียงโดยค่าเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "เงาตัวอักษร" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "ตัวอักษรเงาอัลฟา" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "ขนาดตัวอักษร" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "ขนาดตัวอักษรหารด้วย" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "ขนาดแบบอักษรของแบบอักษรเริ่มต้นโดยที่ 1 หน่วย = 1 พิกเซลที่ 96 DPI" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "ขนาดแบบอักษรของแบบอักษร monospace โดยที่ 1 หน่วย = 1 พิกเซลที่ 96 DPI" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"ขนาดตัวอักษรของข้อความแชทล่าสุดและข้อความแจ้งการแชทในจุด (pt).\n" +"ค่า 0 จะใช้ขนาดตัวอักษรเริ่มต้น." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" +"สำหรับฟอนต์สไตล์พิกเซลที่ปรับขนาดได้ไม่ดี วิธีนี้จะช่วยให้ใช้ขนาดฟอนต์ได้\n" +"ด้วยแบบอักษรนี้จะหารด้วยค่านี้เป็นพิกเซลเสมอ ตัวอย่างเช่น.\n" +"แบบอักษรพิกเซลสูง 16 พิกเซลควรตั้งค่านี้เป็น 16 ดังนั้นมันจะเป็นเท่านั้น\n" +"ขนาด 16, 32, 48 เป็นต้น ดังนั้นม็อดที่ขอขนาด 25 จะได้รับ 32." + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"รูปแบบของข้อความแชทของผู้เล่น สตริงต่อไปนี้เป็นตัวยึดที่ถูกต้อง:\n" +"@name, @message, @timestamp (ไม่บังคับ)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "รูปแบบของภาพหน้าจอ." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "สีพื้นหลังเริ่มต้นของ Formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "ความทึบพื้นหลังเริ่มต้นของ Formspec" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Formspec สีพื้นหลังแบบเต็มหน้าจอ" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Formspec ความทึบพื้นหลังแบบเต็มหน้าจอ" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "สีพื้นหลังเริ่มต้นของ Formspec (R, G, B)" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "ความทึบพื้นหลังเริ่มต้นของ Formspec (ระหว่าง 0 ถึง 255)" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Formspec สีพื้นหลังแบบเต็มหน้าจอ (R, G, B)" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "ความทึบของพื้นหลังแบบเต็มหน้าจอ Formspec (ระหว่าง 0 ถึง 255)" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "ปุ่มส่งต่อ" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "เสียง 2D ที่สี่จากทั้งหมด 4 แบบที่ร่วมกันกำหนดความสูงของช่วงเนินเขา/ภูเขา." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "ประเภทเศษส่วน" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "เศษส่วนของระยะทางที่มองเห็นซึ่งมีหมอกเริ่มแสดง" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "จากระยะการสร้างบล็อคสำหรับไคลเอนต์ ระบุไว้ใน mapblock (16 โหนด)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "จากระยะทางที่บล็อกถูกส่งไปยังไคลเอนต์ ระบุไว้ใน mapblock (16 โหนด)." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"ไคลเอ็นต์รู้เกี่ยวกับอ็อบเจ็กต์มากแค่ไหน ระบุไว้ใน mapblock (16 โหนด).\n" +"\n" +"การตั้งค่านี้มีขนาดใหญ่กว่า active_block_range จะทำให้เซิร์ฟเวอร์\n" +"เพื่อรักษาวัตถุออกฤทธิ์ให้อยู่ในระยะนี้ในทิศทางที่\n" +"ผู้เล่นกำลังมองหา (สิ่งนี้สามารถหลีกเลี่ยงฝูงชนที่หายไปจากการมองเห็นทันที)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "เต็มจอ" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "โหมดเต็มหน้าจอ" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "การปรับขนาด GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "ตัวกรองมาตราส่วน GUI" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "ตัวกรองการปรับขนาด GUI txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "เกม" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "โทรกลับทั่วโลก" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"คุณลักษณะการสร้างแผนที่โลก.\n" +"ใน Mapgen v6 ธง 'การตกแต่ง' จะควบคุมการตกแต่งทั้งหมดยกเว้นต้นไม้\n" +"และหญ้าป่า ในแผนที่อื่นๆ ธงนี้ควบคุมการตกแต่งทั้งหมด." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"การไล่ระดับสีของเส้นโค้งแสงที่ระดับแสงสูงสุด\n" +"ควบคุมคอนทราสต์ของระดับแสงสูงสุด" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"การไล่ระดับสีของเส้นโค้งแสงที่ระดับแสงต่ำสุด\n" +"ควบคุมคอนทราสต์ของระดับแสงต่ำสุด" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "กราฟิก" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "กราฟิก" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "กราฟิก" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "แรงโน้มถ่วง" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "ระดับพื้นดิน" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "เสียงดิน" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "ม็อด HTTP" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "การปรับขนาด GUI" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "ปุ่มสลับ HUD" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"การจัดการสำหรับการเรียก Lua API ที่เลิกใช้แล้ว:\n" +"- ไม่มี: อย่าบันทึกการโทรที่เลิกใช้แล้ว\n" +"- บันทึก: เลียนแบบและบันทึก backtrace ของการโทรที่เลิกใช้แล้ว (ค่าเริ่มต้น).\n" +"- ข้อผิดพลาด: ยกเลิกการใช้งานการโทรที่เลิกใช้แล้ว (แนะนำสำหรับนักพัฒนา mod)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"มีเครื่องมือสร้างโปรไฟล์เอง:\n" +"* เครื่องมือฟังก์ชันว่าง.\n" +"ค่านี้ประมาณค่าโสหุ้ย ที่เครื่องมือวัดกำลังเพิ่ม (การเรียกใช้ฟังก์ชัน +1).\n" +"* เครื่องมือสุ่มตัวอย่างที่ใช้ในการอัปเดตสถิติ." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "เสียงผสมความร้อน" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "เสียงความร้อน" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "องค์ประกอบความสูงของขนาดหน้าต่างเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "เสียงสูง" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "ความสูงเลือกเสียง" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "ลาดชัน" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "ธรณีสัณฐาน Hill" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Hilliness1 เสียง" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Hilliness2 เสียง" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Hilliness3 เสียง" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Hilliness4 เสียง" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "โฮมเพจของเซิร์ฟเวอร์ที่จะแสดงในรายการเซิร์ฟเวอร์." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"การเร่งความเร็วในอากาศในแนวนอนเมื่อกระโดดหรือล้ม,\n" +"ในโหนดต่อวินาทีต่อวินาที." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"การเร่งความเร็วในแนวนอนและแนวตั้งในโหมดเร็ว,\n" +"ในโหนดต่อวินาทีต่อวินาที." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"การเร่งความเร็วในแนวนอนและแนวตั้งบนพื้นดินหรือเมื่อปีนเขา,\n" +"ในโหนดต่อวินาทีต่อวินาที." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "ปุ่มลัดต่อไป Hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "คีย์ก่อนหน้าของ Hotbar" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Hotbar สล็อต 1 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Hotbar สล็อต 10 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Hotbar สล็อต 11 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Hotbar สล็อต 12 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Hotbar สล็อต 13 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Hotbar สล็อต 14 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Hotbar สล็อต 15 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Hotbar สล็อต 16 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Hotbar สล็อต 17 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Hotbar สล็อต 18 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Hotbar สล็อต 19 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Hotbar สล็อต 2 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Hotbar สล็อต 20 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Hotbar สล็อต 21 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Hotbar สล็อต 22 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Hotbar สล็อต 23 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Hotbar สล็อต 24 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Hotbar สล็อต 25 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Hotbar สล็อต 26 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Hotbar สล็อต 27 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Hotbar สล็อต 28 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Hotbar สล็อต 29 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Hotbar สล็อต 3 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Hotbar สล็อต 30 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Hotbar สล็อต 31 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Hotbar สล็อต 32 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Hotbar สล็อต 4 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Hotbar สล็อต 5 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Hotbar สล็อต 6 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Hotbar สล็อต 7 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Hotbar สล็อต 8 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Hotbar สล็อต 9 สำคัญ" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "สร้างแม่น้ำได้ลึกแค่ไหน." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"คลื่นของเหลวจะเคลื่อนที่เร็วแค่ไหน สูงขึ้น = เร็วขึ้น.\n" +"หากเป็นลบ คลื่นของเหลวจะเคลื่อนที่ถอยหลัง.\n" +"ต้องเปิดใช้งานโบกของเหลว." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"เซิร์ฟเวอร์จะรอนานเท่าใดก่อนที่จะยกเลิกการโหลด mapblock ที่ไม่ได้ใช้.\n" +"ค่าที่สูงกว่านั้นราบรื่นกว่า แต่จะใช้ RAM มากกว่า." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "ลดค่านี้เพื่อเพิ่มแรงต้านทานของของเหลวต่อการเคลื่อนที่" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "กว้างแค่ไหนจึงจะสร้างแม่น้ำได้." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "เสียงผสมความชื้น" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "เสียงความชื้น" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "การเปลี่ยนแปลงความชื้นของไบโอม." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "เซิร์ฟเวอร์ IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"ถ้า FPS สูงกว่านี้ให้ จำกัด ด้วยการนอน\n" +"เพื่อไม่ให้สิ้นเปลืองพลังงานของ CPU อย่างไม่มีประโยชน์" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"ถ้าปิดใช้งาน ใช้คีย์ 'พิเศษ' บินถ้าทั้งบิน และโหมดที่รวดเร็วเป็น \n" +"ใช้งาน." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"หากเปิดใช้งานเซิร์ฟเวอร์จะดำเนินการคัดแยกการบล็อกแผนที่ตาม\n" +"ในตำแหน่งสายตาของผู้เล่น ซึ่งสามารถลดจำนวนบล็อคได้\n" +"ส่งให้ลูกค้า 50-80% ลูกค้าจะไม่ได้รับการล่องหนอีกต่อไป\n" +"เพื่อให้อรรถประโยชน์ของโหมด noclip ลดลง." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"ถ้าเปิดใช้งานร่วมกับโหมดการบิน ผู้เล่นสามารถบินผ่านโหนไม้ได้.\n" +"ต้องมีสิทธิ์ 'noclip' บนเซิร์ฟเวอร์." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"หากเปิดใช้งาน ปุ่ม \"Aux1\" แทนปุ่ม \"แอบ\" จะใช้สำหรับการปีนลงและ\n" +"จากมากไปน้อย" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"เปิดใช้งานการยืนยันการลงทะเบียนเมื่อเชื่อมต่อกับเซิร์ฟเวอร์.\n" +"หากปิดใช้งานบัญชีใหม่จะถูกลงทะเบียนโดยอัตโนมัติ." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"หากเปิดใช้งานจะมีการบันทึกการดำเนินการย้อนกลับ.\n" +"ตัวเลือกนี้จะอ่านก็ต่อเมื่อเซิร์ฟเวอร์เริ่มต้น." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "หากเปิดใช้งานให้ปิดใช้งานการป้องกันการโกงในผู้เล่นหลายคน." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"หากเปิดใช้งาน ข้อมูลโลกที่ไม่ถูกต้องจะไม่ทำให้เซิร์ฟเวอร์ปิดตัวลง\n" +"เปิดใช้งานสิ่งนี้ก็ต่อเมื่อคุณรู้ว่าคุณกำลังทำอะไรอยู่." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "ถ้าเปิดใช้งาน ทำให้ย้ายทิศทางสัมพันธ์กับระยะห่างของผู้เล่นเมื่อบิน หรือว่ายน้ำ." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "หากเปิดใช้งานผู้เล่นใหม่จะไม่สามารถเข้าร่วมด้วยรหัสผ่านที่ว่างเปล่าได้." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"ถ้าเปิดใช้งาน คุณสามารถทำบล็อกที่ตำแหน่ง (ระดับเท้าสายตา) คุณยืน . \n" +"นี้มีประโยชน์เมื่อทำงานกับ nodeboxes ในพื้นที่ขนาดเล็ก." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"หากเปิดใช้งานข้อจำกัด CSM สำหรับช่วงโหนด การเรียก get_node จะถูกจำกัด\n" +"ถึงระยะนี้จากผู้เล่นไปยังโหนด." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"หากการดำเนินการคำสั่งแชทใช้เวลานานกว่าเวลาที่ระบุใน\n" +"วินาที เพิ่มข้อมูลเวลาในข้อความคำสั่งแชท" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"หากขนาดไฟล์ของ debug.txt เกินจำนวนเมกะไบต์ที่ระบุใน\n" +"เมื่อเปิดการตั้งค่านี้ ไฟล์จะถูกย้ายไปยัง debug.txt.1,\n" +"การลบ debug.txt.1 ที่เก่ากว่า หากมี.\n" +"debug.txt จะถูกย้ายก็ต่อเมื่อการตั้งค่านี้เป็นค่าบวก." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "หากตั้งค่าไว้ผู้เล่นจะวางไข่ที่ตำแหน่งที่กำหนดเสมอ." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "ละเว้นข้อผิดพลาดของโลก" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "อัลฟ่าพื้นหลังคอนโซลการแชทในเกม (ความทึบระหว่าง 0 ถึง 255)" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "สีพื้นหลังของคอนโซลแชทในเกม (R, G, B)" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "ความสูงของแชทคอนโซลในเกมระหว่าง 0.1 (10%) และ 1.0 (100%)" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "เพิ่มปุ่มปรับระดับเสียง" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "ความเร็วแนวตั้งเริ่มต้นเมื่อกระโดด เป็นโหนดต่อวินาที." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"เครื่องมือในตัว.\n" +"โดยปกติแล้วสิ่งนี้จำเป็นสำหรับผู้สนับสนุนหลัก/ในตัวเท่านั้น." + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "คำสั่งเครื่องมือแชทในการลงทะเบียน." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"ฟังก์ชั่นโทรกลับทั่วโลกในการลงทะเบียน.\n" +"(ทุกสิ่งที่คุณส่งผ่านไปยังฟังก์ชัน minetest.register_*() function)" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "ควบคุมฟังก์ชันการทำงานของ Active Block Modifiers ในการลงทะเบียน." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "ควบคุมฟังก์ชันการทำงานของ Loading Block Modifiers ในการลงทะเบียน." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "เครื่องมือวิธีการของหน่วยงานในการลงทะเบียน." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "ช่วงเวลาของการบันทึกการเปลี่ยนแปลงที่สำคัญในโลก ระบุเป็นวินาที." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "ช่วงเวลาในการส่งช่วงเวลาของวันให้กับลูกค้า." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "ภาพเคลื่อนไหวรายการสินค้าคงคลัง" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "รหัสสินค้าคงคลัง" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "สลับเมาส์" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "กลับเคลื่อนไหวเมาส์แนวตั้ง." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "ไดเรกเตอรีฟอนต์ตัวเอียง" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "ไดเรกเตอรีฟอนต์ตัวเอียงแบบขนาดคงที่" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "รายการนิติบุคคล TTL" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "การทำซ้ำ" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"การวนซ้ำของฟังก์ชันแบบเรียกซ้ำ.\n" +"การเพิ่มสิ่งนี้จะเพิ่มปริมาณของรายละเอียดเล็กๆ น้อยๆ แต่ยัง\n" +"เพิ่มภาระการประมวลผล.\n" +"เมื่อวนซ้ำ = 20 mapgen นี้มีภาระคล้ายกับ mapgen V7." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "จอยสติ๊ก ID" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "ช่วงเวลาการทำซ้ำปุ่มจอยสติ๊ก" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "ประเภทของจอยสติ๊ก" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "ความไวของจอยสติ๊ก frustum" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "ประเภทของจอยสติ๊ก" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"จูเลียตั้งเท่านั้น.\n" +"ส่วนประกอบ W ของค่าคงที่ไฮเปอร์คอมเพล็กซ์.\n" +"เปลี่ยนรูปร่างของเศษส่วน.\n" +"ไม่มีผลกับแฟร็กทัล 3 มิติ.\n" +"ช่วงประมาณ -2 ถึง 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"จูเลียตั้งเท่านั้น.\n" +"องค์ประกอบ X ของค่าคงที่ไฮเปอร์คอมเพล็กซ์.\n" +"เปลี่ยนรูปร่างของเศษส่วน.\n" +"ช่วงประมาณ -2 ถึง 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"จูเลียตั้งเท่านั้น.\n" +"ส่วนประกอบ Y ของค่าคงที่ไฮเปอร์คอมเพล็กซ์.\n" +"เปลี่ยนรูปร่างของเศษส่วน.\n" +"ช่วงประมาณ -2 ถึง 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"จูเลียตั้งเท่านั้น\n" +"ส่วนประกอบ Z ของค่าคงที่ไฮเปอร์คอมเพล็กซ์\n" +"เปลี่ยนรูปร่างของเศษส่วน\n" +"ช่วงประมาณ -2 ถึง 2" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "ปุ่มกระโดด" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "ความเร็วในการกระโดด" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับลดช่วงการรับชม.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับลดระดับเสียง.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำหรับการกระโดด.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญในการวางรายการที่เลือกในปัจจุบัน.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเพิ่มช่วงการรับชม.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มกดสำหรับเพิ่มระดับเสียง.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำหรับการกระโดด.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มกดสำหรับการเคลื่อนที่อย่างรวดเร็วในโหมดเร็ว.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มกดสำหรับเลื่อนเครื่องเล่นถอยหลัง.\n" +"จะปิดใช้งานการป้อนอัตโนมัติอัตโนมัติเมื่อเปิดใช้งาน.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญสำหรับการย้ายผู้เล่นไปข้างหน้า.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับย้ายผู้เล่นไปทางซ้าย.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มกดสำหรับเลื่อนเครื่องเล่นไปทางขวา.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำหรับการปิดเสียงเกม.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเปิดหน้าต่างแชทเพื่อพิมพ์คำสั่ง.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเปิดหน้าต่างแชทเพื่อพิมพ์คำสั่งในเครื่อง.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"รหัสสำหรับเปิดหน้าต่างแชท.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญในการเปิดสินค้าคงคลัง.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำหรับการกระโดด.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 11.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 12.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 13.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 14.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 15.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 16.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 17.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 18.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 19.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 20.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 21.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 22.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 23.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 24.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 25.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 26.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 27.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 28.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 29.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 30.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 31.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ 32.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่แปด.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่ห้า.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar แรก.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่สี่.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"แป้นสำหรับเลือกรายการถัดไปในแถบร้อน.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่เก้า.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"แป้นสำหรับเลือกรายการก่อนหน้าในแถบร้อน.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่สอง.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"คีย์สำหรับการเลือกสล็อต hotbar ที่เจ็ด.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่หก.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกช่องเสียบที่สิบ.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับเลือกสล็อต hotbar ที่สาม.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ที่สำคัญสำหรับการด้อม.\n" +"นอกจากนี้ยังใช้สำหรับการปีนลงและลงไปในน้ำหากปิดการใช้งาน aux1_descends.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับสลับระหว่างกล้องตัวแรกและตัวที่สาม.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญสำหรับการจับภาพหน้าจอ.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญในการสลับ autoforward.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับสลับโหมดโรงภาพยนตร์.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญในการสลับการแสดงผลของแผนที่ย่อ.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับสลับโหมดอย่างรวดเร็ว.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญในการสลับการบิน.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"คีย์สำหรับสลับโหมด noclip.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญในการสลับโหมด pitch.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับสลับการอัปเดตกล้อง ใช้สำหรับการพัฒนาเท่านั้น\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญในการสลับการแสดงผลของการแชท.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"คีย์สำหรับสลับการแสดงข้อมูลการดีบัก.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญในการสลับการแสดงผลของหมอก.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญในการสลับการแสดงผลของ HUD.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับสลับการแสดงผลของแชทคอนโซลขนาดใหญ่.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"ปุ่มสำหรับสลับการแสดงผลของตัวสร้างโปรไฟล์ ใช้สำหรับการพัฒนา.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญในการสลับช่วงมุมมองไม่ จำกัด.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"กุญแจสำคัญในการใช้มุมมองซูมเมื่อเป็นไปได้.\n" +"ดู http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "เตะผู้เล่นที่ส่งข้อความมากกว่า X ต่อ 10 วินาที." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "ความชันของทะเลสาบ" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "ทะเลสาบธรณีประตู" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "ภาษา" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "ความลึกของถ้ำขนาดใหญ่" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "ถ้ำขนาดใหญ่จำนวนสูงสุด" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "จำนวนขั้นต่ำของถ้ำขนาดใหญ่" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "น้ำท่วมสัดส่วนถ้ำใหญ่" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "คีย์คอนโซลแชทขนาดใหญ่" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "สไตล์ใบ" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"สไตล์ใบ:\n" +"- แฟนซี: มองเห็นใบหน้าทั้งหมดได้\n" +"- ง่าย: มีเพียงใบหน้าด้านนอกหากกำหนด special_tiles ไว้\n" +"- ทึบแสง: ปิดการใช้งานความโปร่งใส" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "ปุ่มซ้าย" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"ความยาวของขีดเซิร์ฟเวอร์และช่วงเวลาที่อ็อบเจ็กต์โดยทั่วไปจะอัปเดตมากกว่า\n" +"เครือข่าย" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"ตั้งค่าเป็นจริงช่วยให้ใบโบก.\n" +"ต้องมี shaders เพื่อเปิดใช้งาน." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "ระยะเวลาระหว่างรอบการดำเนินการ Active Block Modifier (ABM)" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "ระยะเวลาระหว่างรอบการดำเนินการ NodeTimer" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "ระยะเวลาระหว่างรอบการจัดการบล็อกที่ใช้งานอยู่" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"ระดับการบันทึกที่จะเขียนไปยัง debug.txt:\n" +"- <ไม่มีอะไร> (ไม่มีการบันทึก)\n" +"- ไม่มี (ข้อความที่ไม่มีระดับ)\n" +"- ข้อผิดพลาด\n" +"- คำเตือน\n" +"- หนังบู๊\n" +"- ข้อมูล\n" +"- ละเอียด" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "การเพิ่มความโค้งกลางของแสง" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "ส่วนโค้งของแสงตรงกลางเพิ่ม" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "ส่วนโค้งเว้าเพิ่มระดับกลางแสง" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "การเพิ่มความโค้งกลางของแสง" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "การเพิ่มความโค้งกลางของแสง" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "ส่วนโค้งของแสงตรงกลางเพิ่ม" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "โคมไฟเรียบ" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"ขีด จำกัด ของการสร้างแผนที่ในโหนดทั้ง 6 ทิศทางตั้งแต่ (0, 0, 0).\n" +"สร้างเฉพาะ mapchunks ภายในขีดจำกัด mapgen เท่านั้น.\n" +"ค่าจะถูกเก็บไว้สำหรับแต่ละโลก." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"จำกัดจำนวนคำขอ HTTP แบบขนาน ส่งผลกระทบต่อ:\n" +"- ดึงสื่อหากเซิร์ฟเวอร์ใช้การตั้งค่า remote_media.\n" +"- ดาวน์โหลดรายชื่อเซิร์ฟเวอร์และประกาศเซิร์ฟเวอร์.\n" +"- การดาวน์โหลดดำเนินการโดยเมนูหลัก (เช่น mod manager).\n" +"จะมีผลก็ต่อเมื่อคอมไพล์ด้วย cURL." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "สภาพคล่อง" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "การปรับความลื่นไหลของของเหลว" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "ลูปของเหลว max" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "เวลาล้างคิวของเหลว" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "ของเหลวจม" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "ช่วงเวลาการอัปเดตของเหลวในหน่วยวินาที." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "ติ๊กอัพเดทของเหลว" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "โหลดตัวสร้างโปรไฟล์เกม" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"โหลดตัวสร้างโปรไฟล์เกมเพื่อรวบรวมข้อมูลโปรไฟล์เกม.\n" +"จัดเตรียมคำสั่ง /profiler เพื่อเข้าถึงโปรไฟล์ที่คอมไพล์.\n" +"มีประโยชน์สำหรับนักพัฒนา mod และตัวดำเนินการเซิร์ฟเวอร์." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "กำลังโหลดตัวดัดแปลงบล็อก" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "ขีด จำกัด Y ล่างของดันเจี้ยน." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "ขีด จำกัด Y ล่างของทุ่นลอยน้ำ." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "สคริปต์เมนูหลัก" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"ทำให้หมอกและสีของท้องฟ้าขึ้นอยู่กับเวลากลางวัน (รุ่งอรุณ / พระอาทิตย์ตก) และทิศทางการดู." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "ทำให้ของเหลวทั้งหมดขุ่น" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "ระดับการบีบอัดแผนที่สำหรับการจัดเก็บดิสก์" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "ระดับการบีบอัดแผนที่สำหรับการถ่ายโอนเครือข่าย" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "ไดเรกทอรีแผนที่" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "คุณลักษณะการสร้างแผนที่เฉพาะสำหรับ Mapgen Carpathian." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"แอตทริบิวต์การสร้างแผนที่เฉพาะสำหรับ Mapgen Flat.\n" +"สามารถเพิ่มทะเลสาบและเนินเขาเป็นครั้งคราวในโลกที่ราบเรียบได้." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"คุณลักษณะการสร้างแผนที่เฉพาะสำหรับ Mapgen Fractal.\n" +"'ภูมิประเทศ' ทำให้เกิดภูมิประเทศที่ไม่เป็นเศษส่วน:\n" +"มหาสมุทร หมู่เกาะ และใต้ดิน." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"คุณลักษณะการสร้างแผนที่เฉพาะสำหรับหุบเขา Mapgen Valleys.\n" +"'altitude_chill': ลดความร้อนด้วยระดับความสูง.\n" +"'humid_rivers': เพิ่มความชื้นรอบแม่น้ำ.\n" +"'vary_river_depth': หากเปิดใช้งาน ความชื้นต่ำและความร้อนสูงจะทำให้เกิดแม่น้ำ.\n" +"ให้ตื้นขึ้นและแห้งในบางครั้ง.\n" +"'altitude_dry': ลดความชื้นด้วยระดับความสูง." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "แอตทริบิวต์การสร้างแผนที่เฉพาะสำหรับ Mapgen v5." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"แอตทริบิวต์การสร้างแผนที่เฉพาะสำหรับ Mapgen v6.\n" +"ธง 'สโนว์ไบโอม' เปิดใช้งาน 5 ระบบไบโอมใหม่.\n" +"เมื่อเปิดใช้งานแฟล็ก 'snowbiomes' ป่าจะถูกเปิดใช้งานโดยอัตโนมัติและ.\n" +"ธง 'ป่า' จะถูกละเว้น." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"แอตทริบิวต์การสร้างแผนที่เฉพาะสำหรับ Mapgen v7.\n" +"'สันเขา': แม่น้ำ.\n" +"'ทุ่นลอยน้ำ': มวลดินที่ลอยอยู่ในชั้นบรรยากาศ.\n" +"'ถ้ำ': ถ้ำยักษ์ที่อยู่ลึกลงไปใต้ดิน." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "ขีด จำกัด การสร้างแผนที่" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "ช่วงเวลาการบันทึกแผนที่" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "แผนที่เงาอัปเดตเฟรม" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "ข้อ จำกัด Mapblock" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "การสร้างตาข่าย Mapblock ล่าช้า" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "ขนาดแคช MapBlock ของตัวสร้างตาข่าย Mapblock เป็น MB" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Mapblock ยกเลิกการโหลดหมดเวลา" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "แมพเก้น คาร์พาเทียน (Carpathian)" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "ธงเฉพาะ Mapgen Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "แผนที่แบน (Mapgen Flat)" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "mapgen แบนธงเฉพาะ" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Mapgen Fractal (แผนที่สร้างเศษส่วน)" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "แฟล็กเฉพาะ Mapgen Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Mapgen V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "แฟล็กเฉพาะ Mapgen V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Mapgen V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "แฟล็กเฉพาะ Mapgen V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Mapgen V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "แฟล็กเฉพาะ Mapgen V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Mapgen หุบเขา (Valleys)" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "ธงเฉพาะหุบเขา Mapgen (Valleys)" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "ดีบัก Mapgen" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "ชื่อแมพเก็น" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "บล็อกสูงสุดสร้างระยะทาง" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "ระยะการส่งบล็อคสูงสุด" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "ของเหลวสูงสุดที่ประมวลผลต่อขั้นตอน." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "แม็กซ์ ล้างวัตถุบล็อกพิเศษ" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "แม็กซ์ แพ็คเก็ตต่อการทำซ้ำ" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "FPS สูงสุด" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "เฟรมต่อวินาที (FPS) สูงสุดเมื่อเกมหยุดชั่วคราว" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "ระยะทางสูงสุดในการแสดงเงา." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "บล็อกบังคับสูงสุด" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "ความกว้างของบาร์สูงสุด" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "ขีดจำกัดสูงสุดของจำนวนถ้ำขนาดใหญ่แบบสุ่มต่อ mapchunk." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "ขีดจำกัดสูงสุดของจำนวนถ้ำขนาดเล็กแบบสุ่มต่อ mapchunk." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"ความต้านทานของเหลวสูงสุด ควบคุมการชะลอตัวเมื่อเข้าสู่ของเหลวที่\n" +"ความเร็วสูง." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"จำนวนบล็อกสูงสุดที่ส่งพร้อมกันต่อไคลเอนต์.\n" +"การนับรวมสูงสุดจะถูกคำนวณแบบไดนามิก:\n" +"max_total = ceil ((# ลูกค้า + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "จำนวนบล็อกสูงสุดที่สามารถเข้าคิวเพื่อโหลดได้." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"จำนวนสูงสุดของบล็อกที่จะเข้าคิวที่จะสร้าง\n" +"ขีดจำกัดนี้บังคับใช้ต่อผู้เล่น." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"จำนวนบล็อกสูงสุดที่จะเข้าคิวที่จะโหลดจากไฟล์.\n" +"ขีดจำกัดนี้บังคับใช้ต่อผู้เล่น." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"จำนวนการดาวน์โหลดพร้อมกันสูงสุด การดาวน์โหลดที่เกินขีดจำกัดนี้จะถูกจัดคิว.\n" +"ควรต่ำกว่า curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "จำนวนสูงสุดของ mapblock ที่ถูกบังคับ." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"จำนวนสูงสุดของ mapblocks สำหรับไคลเอ็นต์ที่จะเก็บไว้ในหน่วยความจำ.\n" +"ตั้งค่าเป็น -1 สำหรับจำนวนไม่ จำกัด." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"จำนวนแพ็กเก็ตสูงสุดที่ส่งต่อขั้นตอนการส่งหากคุณมีการเชื่อมต่อที่ช้า\n" +"ลองลดมัน แต่อย่าลดลงให้ต่ำกว่าเป้าหมายสองเท่า\n" +"หมายเลขลูกค้า" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "จำนวนผู้เล่นสูงสุดที่สามารถเชื่อมต่อได้พร้อมกัน." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "จำนวนสูงสุดของข้อความแชทล่าสุดที่จะแสดง" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "จำนวนสูงสุดของวัตถุที่จัดเก็บแบบคงที่ในบล็อก." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "วัตถุสูงสุดต่อบล็อก" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"สัดส่วนสูงสุดของหน้าต่างปัจจุบันที่จะใช้กับ hotbar\n" +"มีประโยชน์หากมีสิ่งที่จะแสดงทางด้านขวาหรือด้านซ้ายของแถบร้อน" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "จำนวนบล็อกสูงสุดพร้อมกันส่งต่อไคลเอ็นต์" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "ขนาดสูงสุดของคิวการแชทนอก" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"ขนาดสูงสุดของคิวการแชทนอก.\n" +"0 เพื่อปิดใช้งานการจัดคิวและ -1 เพื่อทำให้ขนาดของคิวไม่ จำกัด." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"เวลาสูงสุดในการดาวน์โหลดไฟล์ (เช่น การดาวน์โหลดไฟล์ม็อด) อาจใช้เวลา โดยระบุเป็นมิลลิวินาที." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"เวลาสูงสุดที่คำขอแบบโต้ตอบ (เช่น การดึงข้อมูลรายการเซิร์ฟเวอร์) อาจใช้ โดยระบุเป็นมิลลิวินาที." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "ผู้ใช้สูงสุด" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "แคชตาข่าย" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "ข้อความประจำวัน" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "ข้อความของวันที่แสดงต่อผู้เล่นที่เชื่อมต่อ." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "วิธีการใช้เพื่อเน้นวัตถุที่เลือก" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "ระดับการบันทึกขั้นต่ำที่จะเขียนในการแชท." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "แผนที่ขนาดเล็ก" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "คีย์แผนที่ย่อ" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "ความสูงการสแกนแผนที่ขั้นต่ำ" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "ขีดจำกัดขั้นต่ำของการสุ่มจำนวนถ้ำขนาดใหญ่ต่อ mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "ขีดจำกัดขั้นต่ำของจำนวนถ้ำขนาดเล็กแบบสุ่มต่อ mapchunk." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "ขนาดพื้นผิวขั้นต่ำ" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mipmapping (แมงป่อง)" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "ผู้สร้างโปรไฟล์" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "ความปลอดภัย" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "ช่องทาง Mod" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "ปรับเปลี่ยนขนาดขององค์ประกอบ Hudbar." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "เส้นทางฟอนต์ monospace" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "ขนาดตัวอักษร Monospace" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "ขนาดตัวอักษร Monospace" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "เสียงรบกวนจากความสูงของภูเขา" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "เสียงภูเขา" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "เสียงแปรผันของภูเขา" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "ระดับศูนย์ภูเขา" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "ความไวของเมาส์" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "คูณความไวเมาส์." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "เสียงโคลน" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"ตัวคูณสำหรับการร่วงหล่น\n" +"ตัวอย่างเช่น: 0 ที่ไม่มีการสั่น 1.0 สำหรับปกติ 2.0 สำหรับสองเท่า" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "ปุ่มปิดเสียง" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "ปิดเสียง" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"ชื่อของตัวสร้างแผนที่ที่จะใช้ในการสร้างโลกใหม่.\n" +"การสร้างโลกในเมนูหลักจะแทนที่สิ่งนี้\n" +"mapgens ปัจจุบันอยู่ในสถานะที่ไม่เสถียรสูง:\n" +"- floatlands เสริมของ v7 (ปิดใช้งานโดยค่าเริ่มต้น)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"ชื่อผู้เล่น.\n" +"เมื่อใช้งานเซิร์ฟเวอร์ ไคลเอ็นต์ที่เชื่อมต่อกับชื่อนี้คือผู้ดูแลระบบ.\n" +"เมื่อเริ่มต้นจากเมนูหลัก สิ่งนี้จะถูกแทนที่." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "ชื่อของเซิร์ฟเวอร์ที่จะแสดงเมื่อผู้เล่นเข้าร่วมและในรายการเซิร์ฟเวอร์." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "ระนาบใกล้" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"พอร์ตเครือข่ายเพื่อฟัง (UDP).\n" +"ค่านี้จะถูกแทนที่เมื่อเริ่มต้นจากเมนูหลัก." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "เครือข่าย" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "ผู้ใช้ใหม่ต้องป้อนรหัสผ่านนี้." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "โนคลิป (ทะลุผ่านบล็อก)" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "คีย์ Noclip" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "โหนที่เน้น" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "การเน้นโหนด" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "ช่วงเวลา NodeTimer" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "เสียงรบกวน" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "จำนวนเธรดที่โผล่ออกมา" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"จำนวนเธรดที่โผล่ออกมาที่จะใช้.\n" +"ค่า 0:\n" +"- การเลือกอัตโนมัติ จำนวนเธรดที่โผล่ออกมาจะเป็น\n" +"- 'จำนวนโปรเซสเซอร์ - 2' โดยมีขีดจำกัดล่างที่ 1.\n" +"ค่าอื่นๆ:\n" +"- ระบุจำนวนเธรดที่โผล่ออกมา โดยมีขีดจำกัดล่างที่ 1.\n" +"คำเตือน: การเพิ่มจำนวนของเธรดที่โผล่ออกมาจะเพิ่มการแมปของเครื่องยนต์\n" +"ความเร็ว แต่อาจส่งผลเสียต่อประสิทธิภาพของเกมโดยการรบกวนผู้อื่น\n" +"กระบวนการ โดยเฉพาะอย่างยิ่งใน singleplayer และ/หรือเมื่อรันโค้ด Lua ใน\n" +"'on_generated' สำหรับผู้ใช้หลายคน การตั้งค่าที่เหมาะสมที่สุดอาจเป็น '1'." + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"จำนวนบล็อกพิเศษที่สามารถโหลดได้โดย /clear ออบเจ็กต์ในครั้งเดียว.\n" +"นี่คือการแลกเปลี่ยนระหว่างโอเวอร์เฮดของธุรกรรม SQLite และ\n" +"การใช้หน่วยความจำ (4096=100MB ตามหลักการทั่วไป)." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "ของเหลวทึบแสง" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "ความทึบ (อัลฟา) ของเงาด้านหลังแบบอักษรเริ่มต้น ระหว่าง 0 ถึง 255." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"เปิดเมนูหยุดชั่วคราวเมื่อโฟกัสของหน้าต่างหายไป ไม่หยุดถ้า formspec เป็น\n" +"เปิด." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "ตัวเลือกการแทนที่สำหรับสีของเว็บลิงค์แชท." + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"เส้นทางของแบบอักษรทางเลือก ต้องเป็นแบบอักษร TrueType.\n" +"แบบอักษรนี้จะใช้สำหรับบางภาษาหรือหากไม่มีแบบอักษรเริ่มต้น." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"เส้นทางบันทึกภาพหน้าจอได้ที่ สามารถเป็นเส้นทางสัมบูรณ์หรือสัมพัทธ์.\n" +"โฟลเดอร์จะถูกสร้างขึ้นหากไม่มีอยู่." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "พา ธ ไปยังไดเร็กทอรี shader หากไม่มีการกำหนดเส้นทางจะใช้ตำแหน่งเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "เส้นทางไปยังไดเรกทอรีพื้นผิว พื้นผิวทั้งหมดจะถูกค้นหาครั้งแรกจากที่นี่" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"เส้นทางไปยังแบบอักษรเริ่มต้น ต้องเป็นแบบอักษร TrueType.\n" +"ระบบจะใช้แบบอักษรสำรองหากไม่สามารถโหลดแบบอักษรได้." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"เส้นทางไปยังแบบอักษร monospace ต้องเป็นแบบอักษร TrueType.\n" +"แบบอักษรนี้ใช้สำหรับเช่น หน้าจอคอนโซลและตัวสร้างโปรไฟล์." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "หยุดการโฟกัสของหน้าต่างที่หายไปชั่วคราว" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "ขีด จำกัด ต่อผู้เล่นของบล็อกที่เข้าคิวโหลดจากดิสก์" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "ขีด จำกัด ต่อผู้เล่นของบล็อกที่เข้าคิวเพื่อสร้าง" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "ฟิสิกส์" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "ปุ่มเลื่อนระดับเสียง" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "โหมดย้ายสนาม" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "ปุ่มวาง" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "กระแทกซ้ำช่วง" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"ผู้เล่นสามารถบินโดยไม่ได้รับผลกระทบโดยแรงโน้มถ่วงได้.\n" +"ต้องมีสิทธิ์ 'บิน' บนเซิร์ฟเวอร์." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "ระยะถ่ายโอนผู้เล่น" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "ผู้เล่นกับผู้เล่น" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "การกรองปัวซอง" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"พอร์ตที่จะเชื่อมต่อกับ (UDP)\n" +"โปรดทราบว่าฟิลด์พอร์ตในเมนูหลักจะแทนที่การตั้งค่านี้" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"ป้องกันการขุดและวางจากการทำซ้ำเมื่อถือปุ่มเมาส์.\n" +"เปิดใช้งานสิ่งนี้เมื่อคุณขุดหรือวางบ่อยเกินไปโดยไม่ได้ตั้งใจ." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "ป้องกันไม่ให้ม็อดทำสิ่งต่าง ๆ ที่ไม่ปลอดภัย เช่น การรันคำสั่งเชลล์." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"พิมพ์ข้อมูลโปรไฟล์ของเครื่องยนต์ในช่วงเวลาปกติ (เป็นวินาที).\n" +"0 = ปิดการใช้งาน มีประโยชน์สำหรับนักพัฒนา." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "สิทธิพิเศษที่ผู้เล่นที่มีพื้นฐาน _privs สามารถให้สิทธิ์ได้." + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "ผู้สร้างโปรไฟล์" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "ปุ่มสลับ Profiler" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "ที่อยู่ผู้ฟัง Prometheus" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"ที่อยู่ผู้ฟังโพรมีธีอุส.\n" +"หาก Minetest ถูกคอมไพล์โดยเปิดใช้งานตัวเลือก ENABLE_PROMETHEUS,\n" +"เปิดใช้งานตัวฟังเมตริกสำหรับ Prometheus บนที่อยู่นั้น.\n" +"สามารถดึงข้อมูลเมตริกได้ที่ http://127.0.0.1:30000/metrics" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "สัดส่วนของถ้ำขนาดใหญ่ที่มีของเหลว." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"รัศมีของพื้นที่คลาวด์ที่ระบุไว้ในจำนวนคลาวด์สแควร์ 64 โหนด\n" +"ค่าที่มากกว่า 26 จะเริ่มก่อให้เกิดการตัดที่คมชัดที่มุมพื้นที่เมฆ" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "ยกระดับภูมิประเทศให้เป็นหุบเขารอบแม่น้ำ." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "อินพุตสุ่ม" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "ปุ่มเลือกช่วง" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "ข้อความแชทล่าสุด" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "ไดเรกเตอรีฟอนต์แบบปกติ" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "รีโมตสื่อบันทึก" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "รีโมตพอร์ต" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"ลบรหัสสีออกจากข้อความแชทที่เข้ามา.\n" +"ใช้สิ่งนี้เพื่อหยุดผู้เล่นไม่สามารถใช้สีในข้อความของพวกเขา." + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "แทนที่เมนูหลักที่เป็นค่าเริ่มต้นด้วยเมนูแบบกำหนดเอง." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "รายงานเส้นทาง" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"จำกัดการเข้าถึงฟังก์ชันฝั่งไคลเอ็นต์บางอย่างบนเซิร์ฟเวอร์.\n" +"รวม byteflags ด้านล่างเพื่อจำกัดคุณลักษณะฝั่งไคลเอ็นต์ หรือตั้งค่าเป็น0\n" +"โดยไม่มีข้อจำกัด:\n" +"LOAD_CLIENT_MODS: 1 (ปิดใช้งานการโหลดม็อดที่ไคลเอ็นต์ให้มา)\n" +"CHAT_MESSAGES: 2 (ปิดการใช้งาน send_chat_message โทรฝั่งไคลเอ็นต์)\n" +"READ_ITEMDEFS: 4 (ปิดใช้งานการโทรฝั่งไคลเอ็นต์ get_item_def)\n" +"READ_NODEDEFS: 8 (ปิดใช้งานการโทรฝั่งไคลเอ็นต์ get_node_def)\n" +"LOOKUP_NODES_LIMIT: 16 (จำกัด get_node โทรฝั่งไคลเอ็นต์เป็น\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (ปิดการใช้งาน get_player_names โทรฝั่งไคลเอ็นต์)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "สันเขากระจายเสียง" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "เสียงสันเขา" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "เสียงใต้น้ำของสันเขา" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "เสียงดังขนาดสันเขา" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "ปุ่มขวา" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "ความลึกของช่องแม่น้ำ" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "ความกว้างของช่องแม่น้ำ" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "ความลึกของแม่น้ำ" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "เสียงแม่น้ำ" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "ขนาดแม่น้ำ" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "ความกว้างหุบเขาแม่น้ำ" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "บันทึกย้อนกลับ" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "เสียงขนาดเนินกลิ้ง" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "ภูเขากลิ้งกระจายเสียง" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "แผนที่ย่อ" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "การขุดและการวางที่ปลอดภัย" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "หาดทรายเกิดขึ้นเมื่อ np_beach มีค่าเกินกว่านี้." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "บันทึกแผนที่ที่ลูกค้าได้รับบนดิสก์." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "บันทึกขนาดหน้าต่างโดยอัตโนมัติเมื่อแก้ไข" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "บันทึกแผนที่ที่ได้รับจากเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"ปรับขนาด GUI ตามค่าที่ผู้ใช้ระบุ\n" +"ใช้ตัวกรองนามแฝงที่ใกล้เคียงที่สุดเพื่อปรับมาตราส่วน GUI\n" +"สิ่งนี้จะทำให้ขอบมุมขรุขระเรียบเนียนและผสมผสานกัน\n" +"พิกเซลเมื่อลดขนาดลงทำให้มีการเบลอบ้าง\n" +"พิกเซลขอบเมื่อปรับขนาดรูปภาพด้วยขนาดที่ไม่ใช่จำนวนเต็ม" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "หน้าจอ:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "ความสูงของหน้าจอ" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "ความกว้างของหน้าจอ" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "โฟลเดอร์ภาพหน้าจอ" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "รูปแบบหน้าจอ" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "คุณภาพของภาพหน้าจอ" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"คุณภาพของภาพหน้าจอ ใช้สำหรับรูปแบบ JPEG เท่านั้น\n" +"1 หมายถึงคุณภาพที่แย่ที่สุด 100 หมายถึงคุณภาพที่ดีที่สุด\n" +"ใช้ 0 สำหรับคุณภาพเริ่มต้น" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "ภาพหน้าจอ" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "เสียงท้องทะเล" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "เสียง 2D จากทั้งหมด 4 เสียงที่ร่วมกันกำหนดความสูงของช่วงเนินเขา/ภูเขา." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "เสียง 3D ที่สองจากสองเสียงที่กำหนดอุโมงค์ร่วมกัน" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "ดู https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "สีขอบของส่วนที่เลือก (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "สีของกล่องที่เลือก" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "ความกว้างของกล่องการเลือก" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"เลือกหนึ่งใน 18 ประเภทเศษส่วน\n" +"1 = 4D ชุด \"Roundy\" Mandelbrot\n" +"2 = 4D ชุด \"กลม\" จูเลีย\n" +"3 = 4D \"Squarry\" ชุด Mandelbrot\n" +"4 = 4D \"Squarry\" ชุดจูเลีย\n" +"5 = 4D ชุด \"ลูกพี่ลูกน้องแมนดี้\" แมนเดลบรอต\n" +"6 = 4D \"ลูกพี่ลูกน้องแมนดี้\" จูเลียตั้ง\n" +"7 = 4D \"รูปแบบ\" ชุด Mandelbrot\n" +"8 = 4D \"รูปแบบ\" ชุดจูเลีย\n" +"9 = 3D \"Mandelbrot/Mandelbar\" ชุด Mandelbrot\n" +"10 = 3D \"Mandelbrot/Mandelbar\" ชุดจูเลีย\n" +"11 = 3D \"ต้นคริสต์มาส\" ชุด Mandelbrot\n" +"12 = 3D \"ต้นคริสต์มาส\" ชุดจูเลีย\n" +"13 = 3D \"Mandelbulb\" ชุด Mandelbrot\n" +"14 = 3D \"Mandelbulb\" ชุดจูเลีย\n" +"15 = ชุด \"Cosine Mandelbulb\" 3 มิติ Mandelbrot\n" +"16 = 3D \"Cosine Mandelbulb\" ชุดจูเลีย\n" +"17 = 4D \"Mandelbulb\" ชุด Mandelbrot\n" +"18 = 4D \"Mandelbulb\" ชุดจูเลีย" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "URL เซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "ชื่อเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "คำอธิบายเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "URL เซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "ที่อยู่เซิฟเวอร์" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "คำอธิบายเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "ชื่อเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "พอร์ตเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "การคัดแยกการบดเคี้ยวทางฝั่งเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "เซิร์ฟเวอร์ พอร์ต" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "URL รายการเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "URL รายการเซิร์ฟเวอร์" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "ไฟล์เซิร์ฟเวอร์รายการ" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"ตั้งค่าภาษา เว้นว่างไว้เพื่อใช้ภาษาของระบบ.\n" +"จำเป็นต้องรีสตาร์ทหลังจากเปลี่ยนแปลงสิ่งนี้." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "กำหนดความยาวอักขระสูงสุดของข้อความแชทที่ส่งโดยลูกค้า." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"กำหนดความแรงของเงา.\n" +"ค่าที่ต่ำกว่าหมายถึงเงาที่สว่างกว่า ค่าที่สูงกว่าหมายถึงเงาที่เข้มกว่า." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"กำหนดขนาดรัศมีเงาที่นุ่มนวล.\n" +"ค่าที่ต่ำกว่าหมายถึงเงาที่คมชัดกว่า ค่าที่มากขึ้นหมายถึงเงาที่นุ่มนวลกว่า.\n" +"ค่าต่ำสุด: 1.0; มูลค่าสูงสุด: 10.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"ตั้งค่าความเอียงของวงโคจรของดวงอาทิตย์/ดวงจันทร์เป็นองศา.\n" +"ค่า 0 หมายถึงไม่มีวงโคจรเอียง/แนวตั้ง.\n" +"ค่าต่ำสุด: 0.0; ค่าสูงสุด: 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"ตั้งค่าเป็นจริงช่วยให้ใบโบก.\n" +"ต้องมี shaders เพื่อเปิดใช้งาน." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"ตั้งค่าเป็นจริงช่วยให้ใบโบก.\n" +"ต้องมี shaders เพื่อเปิดใช้งาน." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"ตั้งค่าเป็นจริงช่วยให้น้ำโบก.\n" +"ต้องมี shaders เพื่อเปิดใช้งาน." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"การตั้งค่าเป็นจริงช่วยให้พืชโบก.\n" +"ต้องมี shaders เพื่อเปิดใช้งาน." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"ตั้งค่าคุณภาพพื้นผิวเงาเป็น 32 บิต.\n" +"เท็จจะใช้พื้นผิว 16 บิต.\n" +"สิ่งนี้สามารถทำให้เกิดสิ่งประดิษฐ์จำนวนมากขึ้นในเงามืด." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "เส้นทาง Shader" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Shaders อนุญาตเอฟเฟกต์ภาพขั้นสูงและอาจเพิ่มประสิทธิภาพในวิดีโอบางรายการ\n" +"บัตร\n" +"ใช้งานได้กับแบ็กเอนด์วิดีโอ OpenGL เท่านั้น" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "คุณภาพของภาพหน้าจอ" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "แผนที่เงาระยะทางสูงสุดในโหนดเพื่อแสดงเงา" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "พื้นผิวแผนที่เงาใน 32 บิต" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "ขนาดพื้นผิวขั้นต่ำ" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "เงาแบบอักษรชดเชยถ้า 0 แล้วเงาจะไม่ถูกวาด." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "ความแข็งแกร่งของเงา" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "รูปร่างของแผนที่ย่อ Enabled = round, disabled = square" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "แสดงข้อมูลการดีบัก" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "แสดงกล่องการเลือกเอนทิตี" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"แสดงกล่องการเลือกเอนทิตี\n" +"จำเป็นต้องรีสตาร์ทหลังจากเปลี่ยนแปลงสิ่งนี้." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "แสดงพื้นหลังแท็กชื่อโดยค่าเริ่มต้น" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "ข้อความปิดเครื่อง" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"ขนาดของ mapchunks ที่สร้างโดย mapgen ระบุไว้ใน mapblock (16 โหนด).\n" +"คำเตือน!: ไม่มีประโยชน์และมีอันตรายหลายประการใน\n" +"เพิ่มค่านี้ให้สูงกว่า 5.\n" +"การลดค่านี้จะเพิ่มความหนาแน่นของถ้ำและดันเจี้ยน.\n" +"การเปลี่ยนแปลงค่านี้มีไว้เพื่อการใช้งานพิเศษ ไม่เปลี่ยนแปลงคือ\n" +"ที่แนะนำ.." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"ขนาดของแคช MapBlock ของตัวสร้างตาข่าย การเพิ่มความประสงค์นี้\n" +"เพิ่มแคชการเข้าชม% ลดการคัดลอกข้อมูลจากหลัก\n" +"ด้ายจึงลดกระวนกระวายใจ" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "วงโคจรของท้องฟ้าเอียง" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "ฝาน w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "ลาดและเติมทำงานร่วมกันเพื่อปรับเปลี่ยนความสูง." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "จำนวนสูงสุดของถ้ำขนาดเล็ก" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "จำนวนขั้นต่ำของถ้ำขนาดเล็ก" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "การเปลี่ยนแปลงความชื้นขนาดเล็กสำหรับการผสมไบโอมบนพรมแดน" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "ความแปรผันของอุณหภูมิขนาดเล็กสำหรับการผสมไบโอมบนพรมแดน." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "แสงที่ราบรื่น" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"กล้องมากเมื่อมองไปรอบ ๆ เรียกว่ามองหรือเมาส์เรียบ.\n" +"มีประโยชน์สำหรับการบันทึกวิดีโอ." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "มากการหมุนของกล้องในโหมดโรงภาพยนตร์ 0 เพื่อปิดใช้งาน." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "มากการหมุนของกล้อง 0 เพื่อปิดใช้งาน" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "กุญแจแอบ" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "ด้อมความเร็ว" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "ความเร็วในการด้อม ในโหนดต่อวินาที." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "ตัวอักษรเงาอัลฟา" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "เสียง" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"ระบุ URL ที่ไคลเอ็นต์ดึงสื่อแทนการใช้ UDP.\n" +"$ filename ควรสามารถเข้าถึงได้จาก $ remote_media $ filename ผ่าน cURL.\n" +"(ชัด ๆ remote_media ควรลงท้ายด้วยเครื่องหมายทับ).\n" +"ไฟล์ที่ไม่ปรากฏจะถูกดึงข้อมูลตามปกติ." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"ระบุขนาดสแต็กเริ่มต้นของโหนด รายการ และเครื่องมือ.\n" +"โปรดทราบว่าม็อดหรือเกมอาจตั้งค่าสแต็กสำหรับบางรายการ (หรือทั้งหมด) อย่างชัดเจน." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"อัปเดตแผนที่เงาโดยสมบูรณ์ตามจำนวนเฟรมที่กำหนด.\n" +"ค่าที่สูงขึ้นอาจทำให้เงาล้าหลัง ค่าที่ต่ำกว่า\n" +"จะใช้ทรัพยากรมากขึ้น.\n" +"ค่าต่ำสุด: 1; ค่าสูงสุด: 16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"การแพร่กระจายของช่วงการเพิ่มของเส้นโค้งแสง\n" +"ควบคุมความกว้างของช่วงที่จะขยาย\n" +"ส่วนเบี่ยงเบนมาตรฐานของเส้นโค้งแสงเพิ่มค่าเกาส์เซียน" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "จุดกำเนิดแบบคงที่" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "เสียงสูงชัน" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "เสียงรบกวนขนาดขั้นบันได" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "สเต็ปภูเขากระจายเสียง" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "ความแข็งแกร่งของพารัลแลกซ์." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"เพิ่มความแรงของเส้นโค้งแสง.\n" +"พารามิเตอร์ 'บูสต์' 3 ตัวกำหนดช่วงของแสง\n" +"เส้นโค้งที่เพิ่มขึ้นในความสว่าง." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "การตรวจสอบโปรโตคอลที่เข้มงวด" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "แถบรหัสสี" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"ระดับพื้นผิวของน้ำเสริมที่วางอยู่บนชั้นลอยตัวที่เป็นของแข็ง.\n" +"น้ำถูกปิดใช้งานโดยค่าเริ่มต้นและจะถูกวางไว้ก็ต่อเมื่อค่านี้ถูกตั้งค่าไว้.\n" +"ไปด้านบน 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' \n" +"(จุดเริ่มต้นของการเรียวบน).\n" +"***คำเตือน อันตรายที่อาจเกิดขึ้นกับโลกและประสิทธิภาพของเซิร์ฟเวอร์***:\n" +"เมื่อเปิดใช้งานการวางน้ำจะต้องกำหนดค่าและทดสอบพื้นที่ลอยน้ำ\n" +"ให้เป็นชั้นทึบโดยตั้งค่า 'mgv7_floatland_density' เป็น 2.0 (หรืออื่น ๆ\n" +"ค่าที่ต้องการขึ้นอยู่กับ 'mgv7_np_floatland') เพื่อหลีกเลี่ยง\n" +"การไหลของน้ำที่รุนแรงโดยเซิร์ฟเวอร์และเพื่อหลีกเลี่ยงน้ำท่วมใหญ่ของ\n" +"พื้นผิวโลกด้านล่าง." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "SQLite แบบซิงโครนัส" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "การเปลี่ยนแปลงอุณหภูมิสำหรับไบโอม." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "การตั้งค่า" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "เสียงรบกวนทางเลือกของภูมิประเทศ" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "เสียงฐานภูมิประเทศ" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "ความสูงของภูมิประเทศ" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "ภูมิประเทศเสียงที่สูงขึ้น" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "เสียงภูมิประเทศ" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"ธรณีประตูเสียงภูมิประเทศสำหรับเนินเขา.\n" +"ควบคุมสัดส่วนพื้นที่โลกที่ปกคลุมด้วยเนินเขา.\n" +"ปรับไปที่ 0.0 สำหรับสัดส่วนที่มากขึ้น." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"ธรณีประตูเสียงภูมิประเทศสำหรับทะเลสาบ.\n" +"ควบคุมสัดส่วนพื้นที่โลกที่ปกคลุมด้วยทะเลสาบ.\n" +"ปรับไปที่ 0.0 สำหรับสัดส่วนที่มากขึ้น." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "เสียงคงอยู่ของภูมิประเทศ" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "เส้นทางพื้นผิว" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"ขนาดพื้นผิวเพื่อแสดงแผนที่เงา.\n" +"นี่ต้องเป็นกำลังสอง.\n" +"ตัวเลขที่ใหญ่กว่าจะสร้างเงาที่ดีกว่า แต่ก็มีราคาแพงกว่าเช่นกัน." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"พื้นผิวบนโหนดอาจถูกจัดตำแหน่งอย่างใดอย่างหนึ่งกับโหนดหรือกับโลก\n" +"โหมดก่อนหน้านี้เหมาะสมกับสิ่งที่ดีกว่าเช่นเครื่องจักรเฟอร์นิเจอร์ ฯลฯ ในขณะที่\n" +"หลังทำให้บันไดและไมโครบล็อกพอดีกับสภาพแวดล้อมดีขึ้น\n" +"อย่างไรก็ตามเนื่องจากความเป็นไปได้นี้เป็นเรื่องใหม่ดังนั้นจึงไม่สามารถใช้งานได้โดยเซิร์ฟเวอร์รุ่นเก่า\n" +"ตัวเลือกนี้อนุญาตให้บังคับใช้สำหรับโหนดบางชนิด โปรดทราบว่า\n" +"ที่ถูกพิจารณาว่าเป็นประสบการณ์และอาจทำงานไม่ถูกต้อง" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "URL สำหรับที่เก็บเนื้อหา" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "ตัวระบุของจอยสติ๊กที่จะใช้" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"รูปแบบเริ่มต้นที่จะบันทึกโปรไฟล์,\n" +"เมื่อเรียก `/profiler save [รูปแบบ]` โดยไม่มีรูปแบบ." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "ความลึกของสิ่งสกปรกหรือโหนดเติมไบโอมอื่นๆ." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "เส้นทางของไฟล์ที่สัมพันธ์กับ worldpath ของคุณซึ่งโปรไฟล์จะถูกบันทึกไว้." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "ตัวระบุของจอยสติ๊กที่จะใช้" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "ความยาวเป็นพิกเซลที่ใช้ในการเริ่มทำงานบนหน้าจอสัมผัส." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"ความสูงสูงสุดของพื้นผิวของเหลวโบก.\n" +"4.0 = ความสูงของคลื่นคือสองโหนด.\n" +"0.0 = คลื่นไม่เคลื่อนที่เลย.\n" +"ค่าเริ่มต้นคือ 1.0 (1/2 โหนด).\n" +"ต้องเปิดใช้งานโบกของเหลว." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "อินเทอร์เฟซเครือข่ายที่เซิร์ฟเวอร์ฟัง." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"สิทธิพิเศษที่ผู้ใช้ใหม่จะได้รับโดยอัตโนมัติ.\n" +"ดู / privs ในเกมสำหรับรายการทั้งหมดในเซิร์ฟเวอร์และการกำหนดค่า mod ของคุณ." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"รัศมีของปริมาตรของบล็อครอบ ๆ ผู้เล่นทุกคนที่อยู่ภายใต้\n" +"สิ่งที่บล็อกที่ใช้งานอยู่ระบุไว้ใน mapblocks (16 โหนด).\n" +"ในวัตถุบล็อกที่ใช้งานอยู่จะถูกโหลดและ ABMs ทำงาน.\n" +"นี่ยังเป็นช่วงขั้นต่ำที่วัตถุที่ใช้งานอยู่ (ม็อบ) ถูกรักษาไว้.\n" +"ควรกำหนดค่านี้ร่วมกับ active_object_send_range_blocks." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"แบ็กเอนด์การเรนเดอร์.\n" +"จำเป็นต้องรีสตาร์ทหลังจากเปลี่ยนแปลงสิ่งนี้.\n" +"หมายเหตุ: บน Android ให้ใช้ OGLES1 หากไม่แน่ใจ! แอปอาจไม่สามารถเริ่มต้นได้.\n" +"บนแพลตฟอร์มอื่น แนะนำให้ใช้ OpenGL.\n" +"Shaders ได้รับการสนับสนุนโดย OpenGL (เดสก์ท็อปเท่านั้น) และ OGLES2 (ทดลอง)" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"ความไวของแกนจอยสติ๊กสำหรับการเลื่อน\n" +"มุมมอง ingame frustum รอบ ๆ." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"ความเข้ม (ความมืด) ของการแรเงารอบโหนด - การบัง\n" +"ด้านล่างมืดกว่าและสูงกว่าเบากว่า ช่วงของค่าที่ใช้ได้สำหรับสิ่งนี้\n" +"การตั้งค่าเป็น 0.25 ถึง 4.0 รวม หากค่าอยู่นอกช่วงจะเป็น\n" +"ตั้งเป็นค่าที่ถูกต้องที่ใกล้ที่สุด" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"เวลา (เป็นวินาที) ที่คิวของเหลวอาจขยายเกินการประมวลผล.\n" +"ความจุจนกว่าจะพยายามลดขนาดโดยการดัมพ์คิวเก่า\n" +"รายการ ค่า 0 ปิดใช้งานฟังก์ชันการทำงาน." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"งบประมาณเวลาที่อนุญาตให้ ABM ดำเนินการในแต่ละขั้นตอน\n" +"(เป็นส่วนหนึ่งของช่วง ABM)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"เวลาในหน่วยวินาทีที่ใช้ระหว่างเหตุการณ์ที่เกิดซ้ำ\n" +"เมื่อกดปุ่มจอยสติ๊กค้างไว้" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"เวลาเป็นวินาทีที่ใช้ระหว่างตำแหน่งโหนดที่เกิดซ้ำเมื่อกดค้างไว้\n" +"ปุ่มสถานที่" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "ประเภทของจอยสติ๊ก" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"ระยะทางแนวตั้งที่ความร้อนลดลง 20 หาก 'altitude_chill' คือ\n" +"เปิดใช้งาน ระยะทางแนวตั้งที่ความชื้นลดลง 10 ถ้า\n" +"'altitude_dry' เปิดใช้งานอยู่." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "เสียง 2D จำนวน 3 จาก 4 เสียงที่ร่วมกันกำหนดความสูงของช่วงเนินเขา/ภูเขา." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"เวลาเป็นวินาทีสำหรับเอนทิตีไอเท็ม (ดร็อปไอเท็ม) เพื่อแสดงสด.\n" +"การตั้งค่าเป็น -1 จะปิดใช้งานคุณสมบัตินี้." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "เวลาของวันที่เริ่มต้นโลกใหม่ หน่วยเป็นมิลลิชั่วโมง (0-23999)." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "ช่วงเวลาการส่ง" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "ความเร็วของเวลา" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "หมดเวลาสำหรับไคลเอ็นต์เพื่อลบข้อมูลแผนที่ที่ไม่ได้ใช้ออกจากหน่วยความจำ." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"เพื่อลดความล่าช้าการถ่ายโอนบล็อกจะช้าลงเมื่อผู้เล่นสร้างบางสิ่งบางอย่าง.\n" +"สิ่งนี้จะกำหนดระยะเวลาที่จะชะลอตัวลงหลังจากทำการวางหรือลบโหนด." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "สลับปุ่มโหมดกล้อง" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "เคล็ดลับเครื่องมือล่าช้า" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "ขีด จำกัด หน้าจอสัมผัส" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "ขีด จำกัด หน้าจอสัมผัส" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "การประนีประนอมเพื่อประสิทธิภาพ" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "เสียงต้นไม้" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "การกรอง Trilinear" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"จริง (True) = 256\n" +"เท็จ (False) = 128\n" +"ใช้เพื่อทำให้แผนที่ย่อเรียบขึ้นบนเครื่องที่ช้าลง." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "ม็อดที่เชื่อถือได้" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "URL ไปยังรายการเซิร์ฟเวอร์ที่แสดงในแท็บผู้เล่นหลายคน." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "สุ่มตัวอย่าง" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"การสุ่มตัวอย่างต่ำจะคล้ายกับการใช้ความละเอียดหน้าจอที่ต่ำกว่า แต่ใช้ได้\n" +"ให้กับโลกของเกมเท่านั้น โดยรักษา GUI ไว้เหมือนเดิม\n" +"ควรเพิ่มประสิทธิภาพอย่างมากโดยเสียภาพที่มีรายละเอียดน้อย\n" +"ค่าที่สูงขึ้นส่งผลให้ภาพมีรายละเอียดน้อยลง" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "ระยะถ่ายโอนผู้เล่นไม่ จำกัด" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "ยกเลิกการโหลดข้อมูลเซิร์ฟเวอร์ที่ไม่ได้ใช้" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "ขีด จำกัด Y บนของดันเจี้ยน." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "ขีด จำกัด Y บนของทุ่นลอยน้ำ." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "ใช้รูปลักษณ์คลาวด์ 3D แทนที่จะเป็นแนวราบ" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "ใช้ภาพเคลื่อนไหวคลาวด์สำหรับพื้นหลังเมนูหลัก." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "ใช้ตัวกรอง anisotropic เมื่อดูที่พื้นผิวจากมุม" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "ใช้การกรอง bilinear เมื่อปรับขนาดพื้นผิว" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"ใช้การทำแผนที่ mip เพื่อปรับขนาดพื้นผิว อาจเพิ่มประสิทธิภาพเล็กน้อย,\n" +"โดยเฉพาะอย่างยิ่งเมื่อใช้แพ็คพื้นผิวที่มีความละเอียดสูง.\n" +"ไม่รองรับการลดขนาดแกมมาแกมมาที่ถูกต้อง." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"ใช้การลบรอยหยักหลายตัวอย่าง (MSAA) เพื่อทำให้ขอบบล็อกเรียบ.\n" +"อัลกอริธึมนี้ทำให้วิวพอร์ต 3 มิติเรียบขึ้นในขณะที่รักษาความคมชัดของภาพ,\n" +"แต่ไม่ส่งผลต่อเนื้อใน\n" +"(ซึ่งเห็นได้ชัดเจนเป็นพิเศษกับพื้นผิวโปร่งใส).\n" +"ช่องว่างที่มองเห็นได้ปรากฏขึ้นระหว่างโหนดเมื่อปิดใช้ shaders.\n" +"หากตั้งค่าเป็น 0 MSAA จะถูกปิดใช้งาน.\n" +"จำเป็นต้องรีสตาร์ทหลังจากเปลี่ยนตัวเลือกนี้." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "ใช้การกรอง trilinear เมื่อปรับขนาดพื้นผิว" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "VSync / การซิงโครไนซ์แนวตั้ง" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "ความลึกของหุบเขา" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "เติมหุบเขา" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "โปรไฟล์หุบเขา" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "ความลาดชันของหุบเขา" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "การเปลี่ยนแปลงความลึกของสารเติมแต่งไบโอม." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "ความสูงของภูเขาสูงสุด (เป็นโหนด)." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "ความหลากหลายของจำนวนถ้ำ." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"การเปลี่ยนแปลงของมาตราส่วนแนวตั้งของภูมิประเทศ.\n" +"เมื่อเสียงรบกวน < -0.55 ภูมิประเทศใกล้จะราบเรียบ." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "ความลึกของโหนดพื้นผิวไบโอมแตกต่างกัน." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"ความขรุขระของภูมิประเทศแตกต่างกันไป.\n" +"กำหนดค่า 'การคงอยู่' สำหรับเสียง terrain_base และ terrain_alt." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "ความชันของหน้าผาแตกต่างกันไป." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "ความเร็วในการปีนแนวตั้ง เป็นโหนดต่อวินาที." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "การซิงโครไนซ์หน้าจอแนวตั้ง" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "ไดรเวอร์วิดีโอ" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "ดูปัจจัยผลุบๆโผล่ๆ" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "ดูระยะทางในโหนด" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "ปุ่มลดช่วงการมอง" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "ปุ่มเพิ่มช่วงการมอง" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "ดูปุ่มซูม" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "ดูช่วง" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "จอยสติกเสมือนเรียกใช้ปุ่ม aux" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "ปริมาณ" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"เปิดใช้งานการแมปการบดเคี้ยวของรัลแลกซ์.\n" +"ต้องมี shaders เพื่อเปิดใช้งาน." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"พิกัด W ของชิ้นส่วน 3D ที่สร้างขึ้นของเศษส่วน 4D.\n" +"กำหนดส่วน 3D ของรูปร่าง 4D ที่ถูกสร้างขึ้น.\n" +"เปลี่ยนรูปร่างของเศษส่วน.\n" +"ไม่มีผลกับแฟร็กทัล 3 มิติ.\n" +"ช่วงประมาณ -2 ถึง 2." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "ความเร็วในการเดินและบิน เป็นโหนดต่อวินาที." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "ความเร็วในการเดิน" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "ความเร็วในการเดิน บิน และปีนเขาในโหมดเร็ว ในโหนดต่อวินาที." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "ระดับน้ำ" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "ระดับผิวน้ำของโลก" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "โบกโหนด" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "โบกใบไม้" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "โบกโหนด" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "โบกน้ำสูง" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "โบกความเร็วน้ำ" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "โบกมือกันยาว" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "โบกต้นไม้" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "สีของกล่องที่เลือก" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"เมื่อ gui_scaling_filter เป็นจริงรูปภาพ GUI ทั้งหมดจะต้องเป็น\n" +"กรองในซอฟต์แวร์ แต่บางภาพถูกสร้างขึ้นโดยตรง\n" +"เป็นฮาร์ดแวร์ (เช่น render-to-texture สำหรับโหนดในคลังโฆษณา)" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"เมื่อ gui_scaling_filter_txr2img เป็นจริงให้คัดลอกภาพเหล่านั้น\n" +"จากฮาร์ดแวร์ซอฟต์แวร์เพื่อการปรับขนาด เมื่อเท็จถอยกลับ\n" +"กับวิธีการปรับขนาดแบบเก่าสำหรับไดรเวอร์วิดีโอที่ไม่ต้องการ\n" +"รองรับการดาวน์โหลดพื้นผิวอย่างถูกต้องจากฮาร์ดแวร์" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"เมื่อใช้ฟิลเตอร์ bilinear/trilinear/anisotropic พื้นผิวความละเอียดต่ำ\n" +"สามารถเบลอได้ดังนั้นจึงเพิ่มขนาดโดยอัตโนมัติกับเพื่อนบ้านที่ใกล้ที่สุด\n" +"การแก้ไขเพื่อรักษาพิกเซลที่คมชัด กำหนดขนาดพื้นผิวขั้นต่ำ\n" +"สำหรับพื้นผิวที่ยกระดับ; ค่าที่สูงกว่าจะดูคมชัดกว่าแต่ต้องการมากกว่า\n" +"หน่วยความจำ. แนะนำให้ใช้กำลัง 2 การตั้งค่านี้ใช้เฉพาะในกรณีที่\n" +"เปิดใช้งานการกรอง bilinear/trilinear/anisotropic\n" +"นอกจากนี้ยังใช้เป็นขนาดพื้นผิวของโหนดฐานสำหรับการจัดตำแหน่งโลก\n" +"การปรับขนาดพื้นผิวอัตโนมัติ" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"ควรแสดงพื้นหลังแท็กชื่อโดยค่าเริ่มต้นหรือไม่.\n" +"Mods อาจยังคงตั้งค่าพื้นหลัง." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "ระบุว่าควรสร้างการซิงโครไนซ์ภาพเคลื่อนไหวพื้นผิวของโหนดต่อแม็ปบล็อกหรือไม่" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"ผู้เล่นจะแสดงให้ลูกค้าเห็นหรือไม่โดยไม่ จำกัด ช่วง.\n" +"เลิกใช้แล้วใช้การตั้งค่า player_transfer_distance แทน." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "ไม่ว่าจะอนุญาตให้ผู้เล่นสร้างความเสียหายและสังหารกัน." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"ไม่ว่าจะขอให้ลูกค้าเชื่อมต่อใหม่หลังจากที่ (Lua) ผิดพลาด.\n" +"ตั้งค่านี้เป็นจริงหากเซิร์ฟเวอร์ของคุณตั้งค่าให้รีสตาร์ทโดยอัตโนมัติ." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "ไม่ว่าจะเป็นการพ่นหมอกออกในตอนท้ายของพื้นที่มองเห็น" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"ไม่ว่าจะปิดเสียง คุณสามารถเปิดเสียงได้ตลอดเวลา เว้นแต่\n" +"ระบบเสียงถูกปิดใช้งาน (enable_sound=false).\n" +"ในเกม คุณสามารถสลับสถานะปิดเสียงด้วยปุ่มปิดเสียงหรือโดยใช้ปุ่ม\n" +"เมนูหยุดชั่วคราว." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "ไม่ว่าจะแสดงข้อมูลการแก้ปัญหาลูกค้า (มีผลเช่นเดียวกับการกดปุ่ม F5)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "องค์ประกอบความกว้างของขนาดหน้าต่างเริ่มต้น." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "ความกว้างของเส้นกล่องเลือกรอบ ๆ โหนด." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"ระบบ Windows เท่านั้น: เริ่ม Minetest ด้วยหน้าต่างบรรทัดคำสั่งในพื้นหลัง\n" +"มีข้อมูลเดียวกันกับไฟล์ debug.txt (ชื่อเริ่มต้น)" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"ไดเรกทอรีโลก (ทุกสิ่งในโลกถูกเก็บไว้ที่นี่).\n" +"ไม่จำเป็นถ้าเริ่มจากเมนูหลัก." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "เวลาเริ่มต้นของโลก" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"เทกซ์เจอร์ที่จัดแนวโลกอาจถูกปรับสัดส่วนเพื่อขยายหลายโหนด อย่างไรก็ตาม\n" +"เซิร์ฟเวอร์อาจไม่ส่งสเกลที่คุณต้องการโดยเฉพาะถ้าคุณใช้\n" +"เทกซ์เจอร์แพ็คที่ออกแบบเป็นพิเศษ ด้วยตัวเลือกนี้ไคลเอนต์พยายาม\n" +"เพื่อกำหนดขนาดโดยอัตโนมัติตามขนาดเทกซ์เจอร์\n" +"ดูเพิ่มเติมที่ texture_min_size\n" +"คำเตือน: ตัวเลือกนี้เป็นการทดลอง!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "โหมดพื้นผิวที่จัดชิดโลก" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Y ของพื้นเรียบ." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "Y ของระดับการไล่ระดับความหนาแน่นของภูเขาเป็นศูนย์ ใช้ในการเลื่อนภูเขาในแนวตั้ง." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Y ของขอบบนของถ้ำขนาดใหญ่." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "ระยะ Y ซึ่งถ้ำจะขยายเป็นขนาดเต็ม." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"ระยะ Y ที่พื้นที่ลอยน้ำลดลงจากความหนาแน่นเต็มที่จนไม่มีเลย.\n" +"การเรียวเริ่มที่ระยะนี้จากขีด จำกัด Y.\n" +"สำหรับชั้นทุ่นลอยน้ำที่เป็นของแข็ง สิ่งนี้จะควบคุมความสูงของเนินเขา/ภูเขา.\n" +"ต้องน้อยกว่าหรือเท่ากับครึ่งหนึ่งของระยะห่างระหว่างขีดจำกัด Y." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "ระดับ Y ของพื้นผิวภูมิประเทศโดยเฉลี่ย." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "ระดับ Y ของขีดจำกัดบนของถ้ำ." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "ระดับ Y ของภูมิประเทศที่สูงขึ้นซึ่งทำให้เกิดหน้าผา." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "ระดับ Y ของภูมิประเทศด้านล่างและก้นทะเล." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "ระดับ Y ของก้นทะเล." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "ไฟล์ cURL หมดเวลาดาวน์โหลดไฟล์" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "cURL หมดเวลาโต้ตอบ" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "cURL ขีด จำกัด ขนาน" + +#~ msgid "- Creative Mode: " +#~ msgstr "-โหมดสร้างสรรค์: " + +#~ msgid "- Damage: " +#~ msgstr "-ความเสียหาย: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = การบดบังพารัลแลกซ์พร้อมข้อมูลความชัน (เร็วกว่า)\n" +#~ "1 = การทำแผนที่นูน (ช้ากว่าแม่นยำกว่า)" + +#~ msgid "Address / Port" +#~ msgstr "ที่อยู่ / พอร์ต" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "ปรับการเข้ารหัสแกมม่าสำหรับตารางแสง ตัวเลขที่สูงกว่านั้นจะสว่างกว่า\n" +#~ "การตั้งค่านี้มีไว้สำหรับไคลเอ็นต์เท่านั้นและเซิร์ฟเวอร์จะเพิกเฉย" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "การตั้งค่าของคุณโลก singleplayer แน่ใจหรือไม่?" + +#~ msgid "Back" +#~ msgstr "หลัง" + +#~ msgid "Basic" +#~ msgstr "ขั้นพื้นฐาน" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "บิตต่อพิกเซล (ความลึกของสี aka) ในโหมดเต็มหน้าจอ." + +#~ msgid "Bump Mapping" +#~ msgstr "การแม็ป ชน" + +#, fuzzy +#~ msgid "Bumpmapping" +#~ msgstr "Bumpmapping" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "กึ่งกลางของเส้นโค้งแสง - กลางเพิ่ม" + +#~ msgid "Config mods" +#~ msgstr "กำหนดค่าวัยรุ่น" + +#~ msgid "Configure" +#~ msgstr "กำหนดค่า" + +#~ msgid "Connect" +#~ msgstr "เชื่อมต่อ" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "ควบคุมความเร็วการจมในของเหลว." + +#~ msgid "Credits" +#~ msgstr "เครดิต" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "สีของครอสแฮร์ (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "ความเสียหาย ที่เปิดใช้งาน" + +#~ msgid "Darkness sharpness" +#~ msgstr "ความมืดมิด" + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "กำหนดขั้นตอนการสุ่มตัวอย่างของพื้นผิว\n" +#~ "ค่าที่สูงกว่าจะทำให้แผนที่ปกติราบรื่นขึ้น" + +#~ msgid "Del. Favorite" +#~ msgstr "ลบรายการโปรด" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "ดาวน์โหลดเกม อย่างเช่น ไมน์เทสต์เกม ได้จาก minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "ดาวน์โหลดจาก minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "ดาวน์โหลด และติดตั้ง $1 กรุณารอสักครู่..." + +#~ msgid "Enable VBO" +#~ msgstr "ทำให้สามารถ VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "เปิดใช้งานการยืนยันการลงทะเบียน" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "เปิดใช้งานการแมป bump สำหรับพื้นผิว แผนที่ปกติจะต้องมีการจัดหาโดยแพ็คพื้นผิว\n" +#~ "หรือจำเป็นต้องสร้างขึ้นอัตโนมัติ\n" +#~ "ต้องมี shaders เพื่อเปิดใช้งาน" + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "เปิดใช้งานการจับคู่โทนภาพยนตร์" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "เปิดใช้งานการสร้างแผนที่ปกติแบบลอยตัว (เอฟเฟกต์นูน)\n" +#~ "ต้องมีการเปิดใช้งาน bumpmapping" + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "เปิดใช้งานการแมปการบดเคี้ยวของรัลแลกซ์\n" +#~ "ต้องมี shaders เพื่อเปิดใช้งาน" + +#~ msgid "Enter " +#~ msgstr "ป้อน " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "ตัวเลือกการทดลองอาจทำให้เกิดช่องว่างระหว่างบล็อก\n" +#~ "เมื่อตั้งค่าเป็นจำนวนที่สูงกว่า 0" + +#~ msgid "FPS in pause menu" +#~ msgstr "FPS ในเมนูหยุดชั่วคราว" + +#~ msgid "Fallback font shadow" +#~ msgstr "เงาแบบอักษรทางเลือก" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "เงาตัวอักษรทางเลือกอัลฟา" + +#~ msgid "Fallback font size" +#~ msgstr "ขนาดตัวอักษรทางเลือก" + +#~ msgid "Filtering" +#~ msgstr "กรอง" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "ตัวอักษรเงาอัลฟา (ความทึบระหว่าง 0 และ 255)." + +#~ msgid "FreeType fonts" +#~ msgstr "แบบอักษรประเภท FreeType" + +#~ msgid "Full screen BPP" +#~ msgstr "BPP เต็มหน้าจอ" + +#~ msgid "Game" +#~ msgstr "เกม" + +#~ msgid "Gamma" +#~ msgstr "แกมมา" + +#~ msgid "Generate Normal Maps" +#~ msgstr "สร้างแผนที่ปกติ" + +#~ msgid "Generate normalmaps" +#~ msgstr "สร้างแผนที่ปกติ" + +#~ msgid "HUD scale factor" +#~ msgstr "เครื่องชั่ง HUD" + +#~ msgid "In-Game" +#~ msgstr "ในเกมส์" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "ติดตั้ง: ไฟล์: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "เครื่องมือวัด" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "โหวต. (ถ้าเมนูนี้สกรูขึ้น เอาข้อมูลจาก minetest.conf)" + +#~ msgid "Lightness sharpness" +#~ msgstr "ความคมชัดของแสง" + +#~ msgid "Main" +#~ msgstr "หลัก" + +#~ msgid "Menus" +#~ msgstr "เมนู" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "แผนที่ย่อในโหมดเรดาร์, ซูม x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "แผนที่ย่อในโหมดเรดาร์, ซูม x4" + +#, fuzzy +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "แผนที่ย่อในโหมด surface, ซูม x2" + +#, fuzzy +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "แผนที่ย่อในโหมด surface, ซูม x4" + +#~ msgid "Name / Password" +#~ msgstr "ชื่อ / รหัสผ่าน" + +#~ msgid "Name/Password" +#~ msgstr "ชื่อ/รหัสผ่าน" + +#~ msgid "No" +#~ msgstr "ไม่" + +#~ msgid "Normalmaps sampling" +#~ msgstr "การสุ่มตัวอย่าง Normalmaps" + +#~ msgid "Normalmaps strength" +#~ msgstr "Normalmaps แข็งแรง" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "จำนวนการวนซ้ำของการปิดกั้น parallax" + +#~ msgid "Ok" +#~ msgstr "ตกลง" + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "ความเอนเอียงโดยรวมของเอฟเฟ็กต์การบดเคี้ยวของ Parallax มักเป็นสเกล / 2" + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "ขนาดโดยรวมของผลการบดเคี้ยวของรัลแลกซ์" + +#, fuzzy +#~ msgid "Parallax Occlusion" +#~ msgstr "Parallax อุดตัน" + +#~ msgid "Parallax occlusion" +#~ msgstr "การบดเคี้ยวของ Parallax" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "อคติการบดเคี้ยวของ Parallax" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "การวนซ้ำของ Parallax" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "โหมดการบดเคี้ยวของ Parallax" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "ขนาดการบดเคี้ยวของ Parallax" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "กำลังบดเคี้ยวของ Parallax" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "เส้นทางแบบอักษร." + +#~ msgid "Path to save screenshots at." +#~ msgstr "พา ธ เพื่อบันทึกภาพหน้าจอที่ ..." + +#~ msgid "Player name" +#~ msgstr "ชื่อผู้เล่น" + +#~ msgid "Profiling" +#~ msgstr "โปรไฟล์" + +#~ msgid "PvP enabled" +#~ msgstr "PvP เปิดใช้งาน" + +#~ msgid "Reset singleplayer world" +#~ msgstr "รีเซ็ต singleplayer โลก" + +#~ msgid "Select Package File:" +#~ msgstr "เลือกแฟ้มแพคเกจ:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "เซิร์ฟเวอร์ / ผู้เล่นเดี่ยว" + +#, fuzzy +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "เงาแบบอักษรชดเชยถ้า 0 แล้วเงาจะไม่ถูกวาด." + +#~ msgid "Special" +#~ msgstr "พิเศษ" + +#~ msgid "Special key" +#~ msgstr "รหัสพิเศษ" + +#~ msgid "Start Singleplayer" +#~ msgstr "เริ่มเล่นเดี่ยว" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "ความแข็งแกร่งของแผนที่ปกติที่สร้างขึ้น" + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "ความแข็งแรงของแสงโค้งกลาง - เพิ่ม" + +#~ msgid "This font will be used for certain languages." +#~ msgstr "แบบอักษรนี้จะใช้สำหรับบางภาษา" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "การเปิดใช้งานต้องมีโปรแกรมควบคุม OpenGL ของ shaders ใช้." + +#~ msgid "Toggle Cinematic" +#~ msgstr "สลับโรงภาพยนตร์" + +#~ msgid "Waving Water" +#~ msgstr "น้ำโบก" + +#~ msgid "Waving water" +#~ msgstr "โบกน้ำ" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "ไม่ว่าจะใช้ฟอนต์ FreeType ต้องมีการสนับสนุน FreeType เพื่อรวบรวม\n" +#~ "หากปิดใช้งาน ฟอนต์บิตแมปและเอ็กซ์เอ็มแอลเวกเตอร์จะใช้แทน" + +#~ msgid "Yes" +#~ msgstr "ใช่" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "คุณกำลังจะเข้าร่วมเซิร์ฟเวอร์นี้ในชื่อ \"%s\" เป็นครั้งแรก\n" +#~ "หากคุณดำเนินการต่อ บัญชีใหม่ที่ใช้ข้อมูลประจำตัวของคุณจะถูกสร้างขึ้นบนเซิร์ฟเวอร์นี้\n" +#~ "โปรดพิมพ์รหัสผ่านของคุณอีกครั้งแล้วคลิก 'ลงทะเบียนและเข้าร่วม' เพื่อยืนยันการสร้างบัญชี " +#~ "หรือคลิก 'ยกเลิก' เพื่อยกเลิก" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "คุณตายแล้ว" + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/tr/minetest.po b/po/tr/minetest.po new file mode 100644 index 0000000..bc2b5a9 --- /dev/null +++ b/po/tr/minetest.po @@ -0,0 +1,8353 @@ +msgid "" +msgstr "" +"Project-Id-Version: Turkish (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-02-01 11:39+0000\n" +"Last-Translator: Metehan Özyürek <metehanc8s9@yandex.com>\n" +"Language-Team: Turkish <https://hosted.weblate.org/projects/minetest/" +"minetest/tr/>\n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.11-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Dış sohbet kuyruğunu temizle" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Boş komut." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Ana menüye çık" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Geçersiz komut: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Verilen komut: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Çevrim içi oyuncuları listele" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Çevrim içi oyuncular: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Dış sohbet kuyruğu artık boş." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Bu komut sunucu tarafından devre dışı bırakıldı." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Yeniden Canlan" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Öldün" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Kullanılabilir komutlar:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Kullanılabilir komutlar: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Komut kullanılamıyor: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Komutlar için yardım alın" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Daha fazla bilgi almak için '.help <komut>' veya her şeyi listelemek için '." +"help all' kullanın." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <komut>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Tamam" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<mevcut değil>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Lua betiğinde bir hata oluştu:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Bir hata oluştu:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Ana menü" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Bağlan" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Bu sunucu yeniden bağlanma isteğinde bulundu:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Mod seçin" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Protokol sürümü uyumsuz. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Sunucu protokol sürümü $1 istiyor. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Bu sunucu $1 ve $2 arası tüm protokol sürümlerini destekler. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Yalnızca $1 protokol sürümü desteklenmektedir." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Yalnızca $1 ve $2 arası protokol sürümleri desteklenmektedir." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "İptal" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Bağımlılıklar:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Tümü devre dışı" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Mod paketi devre dışı" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Hepsini etkinleştir" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Mod paketini etkinleştir" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"İzin verilmeyen karakterler içerdiği için \"$1\" modu etkinleştirilemedi. " +"Yalnızca [a-z0-9_] karakterlerine izin verilir." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Daha Çok Mod Bul" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "(İsteğe bağlı) bağımlılık yok" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Verilen oyun açıklaması yok." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Katı bağımlılık yok" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Verilen mod paketi açıklaması yok." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "İsteğe bağlı bağımlılık yok" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "İsteğe bağlı bağımlılıklar:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Kaydet" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Dünya:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "etkin" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" zaten var.Değiştirilsin mi?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$ 1 ve $ 2 destek dosyaları yüklenecek." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 'e $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 indiriliyor,\n" +"$2 sırada" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 indiriliyor..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 için destek dosyaları bulanamadı." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 indirilecek, ve $2 destek dosyaları atlanacak." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Tüm paketler" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Zaten kuruldu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Ana Menüye Dön" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Yerel oyun:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "Minetest cURL olmadan derlendiğinde ContentDB kullanılamaz" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "İndiriliyor..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "$1 indirilemedi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Oyunlar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Kur" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "$1 kur" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Eksik bağımlılıkları kur" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Kur: Desteklenmeyen dosya türü veya bozuk arşiv" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Modlar" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Paket alınamadı" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Sonuç yok" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Güncelleme yok" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Bulunamadı" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Üzerine yaz" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Lütfen asıl oyunun doğru olup olmadığını gözden geçirin." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Sıraya alındı" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Doku paketleri" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Kaldır" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Güncelleme" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Hepsini güncelle [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Tarayıcı'da daha fazla bilgi edinin" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "\"$1\" adlı dünya zaten var" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Ek arazi" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Yükseklik soğukluğu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Yükseklik kuruluğu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Biyom karıştırma" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Biyomlar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Oyuklar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Mağaralar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Yarat" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Dekorasyonlar" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Uyarı : Geliştirici testi geliştiriciler içindir." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Zindanlar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Düz arazi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Gökyüzünde yüzenkara kütleleri" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Yüzenkaralar (deneysel)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Fraktal olmayan arazi üret: Okyanuslar ve yeraltı" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Tepeler" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Nemli nehirler" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Nehirler etrafındaki nemi artırır" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "$1 kur" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Göller" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Düşük nem ve yüksek ısı, sığ ve kuru nehirler oluşturur" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Mapgen" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Mapgen bayrakları" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Mapgen'e özgü bayraklar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Dağlar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Çamur akışı" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Tüneller ve mağaralar ağı" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Seçilen oyun yok" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Yükseklikle ısıyı azaltır" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Yükseklik ile nemi azaltır" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Nehirler" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Deniz seviyesi nehirleri" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Tohum" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Biyomlar arası yumuşak geçiş" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Arazide görülen yapılar (v6 ile oluşturulan ağaçlar ve jangıl çimi üzerinde " +"etkisizdir)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Arazide görülen yapılar, genellikle ağaçlar ve bitkiler" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Ilıman, Çöl" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Ilıman, Çöl, Jangıl" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Ilıman, Çöl, Jangıl, Tundra, Tayga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Arazi yüzey erozyonu" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Ağaçlar ve jangıl çimi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Nehir derinliğini değiştir" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Yerin derinliklerinde çok büyük oyuklar" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Dünya adı" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Kurulu oyununuz yok." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "\"$1\" 'i silmek istediğinizden emin misiniz?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Sil" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: \"$1\" dosyası silinemedi" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: \"$1\" konumu geçersiz" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "\"$1\" dünyasını sil?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Parolayı Doğrula" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Mapgen adı" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Ad" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Parola" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "Parolalar eşleşmiyor!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "Kaydol ve Katıl" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Kabul et" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Mod paketini yeniden adlandır:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Bu mod paketinin buradaki yeniden adlandırmayı geçersiz kılacak, modpack." +"conf dosyasında verilen açık bir adı var." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Ayarın verilen açıklaması yok)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D Gürültü" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Ayarlar sayfasına geri dön" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Gözat" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "İçerik" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "İçerik" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Devre dışı" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Düzenle" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Etkin" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Aralılık" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Oktavlar" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Kaydırma" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Süreklilik" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Lütfen geçerli bir tamsayı girin." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Lütfen geçerli bir sayı girin." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Öntanımlıyı Geri Yükle" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Boyut" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Ara" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Dizin seç" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Dosya seç" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Teknik adları göster" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Değer en az $1 olmalı." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Değer $1'den büyük olmamalı." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X yayılması" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y yayılması" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z yayılması" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "mutlak değer" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "öntanımlılar" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "rahat" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Etkin)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mod" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "$1'den $2'ye kurma başarısız" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Mod Kur: $1 için gerçek mod adı bulunamadı" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "Mod Kur:$1 mod paketi için uygun bir klasör adı bulunamadı" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Geçerli bir mod veya mod paketi bulunamadı" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "$1 bir doku paketi olarak kurulamadı" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Bir oyun bir $1 olarak kurulamadı" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Bir mod bir $1 olarak kurulamadı" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Bir mod paketi bir $1 olarak kurulamadı" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Yükleniyor..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Herkese açık sunucu listesi devre dışı" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Herkese açık sunucu listesini tekrar etkinleştirmeyi deneyin ve internet " +"bağlantınızı gözden geçirin." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Hakkında" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Etkin Katkıda Bulunanlar" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Etkin işleyici:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Çekirdek Geliştiriciler" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Kullanıcı Veri Dizinini Aç" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Bir dosya yöneticisi / gezgininde kullanıcı tarafından sağlanan dünyaları,\n" +"oyunları, modları ve doku paketlerini içeren dizini açar." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Önceki Katkıda Bulunanlar" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Önceki Çekirdek Geliştiriciler" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "Hata ayıklama bilgisini göster" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Çevrim içi içeriğe göz at" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "İçerik" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Doku paketini devre dışı bırak" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Bilgi:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Kurulu Paketler:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Bağımlılık yok." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Bulunan paket açıklaması yok" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Yeniden adlandır" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Paketi Kaldır" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Doku Paketleri Kullan" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Sunucuyu Duyur" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Bağlı Adres" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Yaratıcı Kip" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Hasar Etkin" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Oyun Barındır" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Sunucu Barındır" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "ContentDB'den oyunlar yükle" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Yeni" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Dünya seçilmedi ya da yaratılmadı!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Oyunu Oyna" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Port" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Mod seçin" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Dünya Seç:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Sunucu Portu" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Oyun Başlat" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Adres" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Temizle" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Yaratıcı kip" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Hasar / Savaş (PvP)" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Sık Kullanılanlar" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Uyumsuz Sunucular" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Oyuna Katıl" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Herkese Açık Sunucular" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Yenile" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "Uzak port" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Sunucu Açıklaması" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D Bulutlar" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Tüm Ayarlar" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Düzgünleştirme:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Ekran Boyutunu Hatırla" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bilineer Filtre" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Tuşları değiştir" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Bitişik Cam" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Dinamik gölgeler" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "Dinamik gölgeler: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Şık Yapraklar" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Yüksek" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Düşük" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Orta" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mip eşleme" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mip eşleme + Aniso. Filtre" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Filtre yok" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Mip eşleme yok" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Nod Vurgulama" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Nod Anahatlama" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Yok" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Opak Yapraklar" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Opak Su" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Parçacıklar" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Ekran:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Ayarlar" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Gölgelemeler" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Gölgelendirme (deneysel)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Gölgelemeler (kullanılamaz)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Basit Yapraklar" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Yumuşak Aydınlatma" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Doku:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Ton Eşleme" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "Dokunuş eşiği: (px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Trilineer Filtre" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "Çok Yüksek" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Çok Düşük" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Dalgalanan Yapraklar" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Dalgalanan Sıvılar" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Dalgalanan Bitkiler" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "Bağlantı hatası (zaman aşımı?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Bağlantı zaman aşımına uğradı." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Tamam!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Nodlar başlatılıyor" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Nodlar başlatılıyor..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Dokular yükleniyor..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Gölgelemeler yeniden oluşturuluyor..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Bağlantı hatası (zaman aşımı?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Oyun bulunamadı veya yüklenemedi: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Geçersiz oyun özellikleri." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Ana Menü" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Dünya seçilmedi veya adres yok. Yapılacak bir şey yok." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Kullanıcı adı çok uzun." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Lütfen bir ad seçin!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Sağlanan parola dosyası açılamadı: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Belirtilen dünya konumu yok: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Hata ayrıntıları için debug.txt dosyasına bakın." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Adres: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Kip: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Port: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Herkese Açık: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- Savaş (PvP): " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Sunucu Adı: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Serileştirme hatası oluştu:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Erişim reddedildi. Neden: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Kendiliğinden ileri devre dışı" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Kendiliğinden ileri etkin" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Blok sınırları gizli" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Blok sınırları tüm bloklar için gösteriliyor" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Blok sınırları geçerli blok için gösteriliyor" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Blok sınırları yakındaki bloklar için gösteriliyor" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Kamera güncelleme devre dışı" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Kamera güncelleme etkin" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "Blok sınırları gösterilemiyor ('basic_debug' ayrıcalığına ihtiyaç var)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Parola değiştir" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Sinematik kip devre dışı" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Sinematik kip etkin" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "İstemci bağlantısı kesildi" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "İstemci tarafı betik devre dışı" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Sunucuya bağlanılıyor..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Bilinmeyen bir nedenle bağlantı başarısız oldu" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Devam et" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Kontroller:\n" +"- %s: ileri hareket\n" +"- %s: geri hareket\n" +"- %s: sola hareket\n" +"- %s: sağa hareket\n" +"- %s: zıpla/tırman\n" +"- %s: kaz/vur\n" +"- %s: yerleştir/kullan\n" +"- %s: sız/aşağı in\n" +"- %s: ögeyi at\n" +"- %s: envanter\n" +"- Fare: dön/bak\n" +"- Fare tekerleği: öge seç\n" +"- %s: sohbet\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Adres çözümlenemedi: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "İstemci yaratılıyor..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Sunucu yaratılıyor..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Hata ayıklama bilgisi ve profilci grafiği gizli" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Hata ayıklama bilgisi gösteriliyor" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Hata ayıklama bilgisi, profilci grafiği ve tel kafes gizli" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Öntanımlı Kontroller:\n" +"Tüm menüler gizli:\n" +"- tek tık: tuş etkin\n" +"- çift tık: yerleştir/kullan\n" +"- parmağı kaydır: etrafa bak\n" +"Menü/Envanter görünür:\n" +"- çift tık (dışarda):\n" +" -->kapat\n" +"- yığına dokun, bölmeye dokun:\n" +" --> yığını taşı\n" +"- dokun&sürükle, iki parmakla dokun\n" +" --> bölmeye tek bir öge yerleştir\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Sınırsız görüntüleme uzaklığı devre dışı" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Sınırsız görüntüleme uzaklığı etkin" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "İstemci yaratılıyor..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Menüye Çık" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Oyundan Çık" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Hızlı kip devre dışı" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Hızlı kip etkin" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Hızlı kip etkin (not: 'hızlı' yetkisi yok)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Uçma kipi devre dışı" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Uçma kipi etkin" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Uçma kipi etkin (not: 'uçma' yetkisi yok)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Sis devre dışı" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Sis etkin" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Oyun Bilgisi:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Oyun duraklatıldı" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Sunucu barındırılıyor" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Öge tanımları..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Medya..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Mini harita şu anda, oyun veya mod tarafından devre dışı" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Çok oyunculu" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Hayalet kipi devre dışı" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Hayalet kipi etkin" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Hayalet kipi etkin (not: 'hayalet' yetkisi yok)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Nod tanımları..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Kapalı" + +#: src/client/game.cpp +msgid "On" +msgstr "Açık" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Eğim hareket kipi devre dışı" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Eğim hareket kipi etkin" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Profilci grafiği gösteriliyor" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Uzak sunucu" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Adres çözümleniyor..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Kapatılıyor..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Tek oyunculu" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Ses Seviyesi" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Ses kısık" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Ses sistemi devre dışı" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Bu inşada ses sistemi desteklenmiyor" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Ses açık" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Sunucu muhtemelen farklı bir %s sürümü çalıştırıyor." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "IPv6 devre dışı bırakıldığı için %s bağlantısı kurulamıyor" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "IPv6 devre dışı bırakıldığından %s adresinde dinlenemiyor" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Görüntüleme uzaklığı değişti: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Görüntüleme uzaklığı maksimumda: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Görüntüleme uzaklığı minimumda: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Ses %d/100'e değişti" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Telkafes gösteriliyor" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Yakınlaştırma şu anda oyun veya mod tarafından devre dışı" + +#: src/client/game.cpp +msgid "ok" +msgstr "tamam" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Sohbet gizli" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Sohbet gösteriliyor" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD gizli" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD gösteriliyor" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Profilci gizli" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Profilci gösteriliyor (sayfa %d / %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Uygulamalar" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "CTRL" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Aşağı" + +#: src/client/keycode.cpp +msgid "End" +msgstr "Son" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "EOF'yi Sil" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Çalıştır" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Yardım" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Ev" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME Kabul" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME Dönüştür" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME Çıkış" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME Kip Değiştir" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME Dönüştürme" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Ekle" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Sol" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Sol Tuş" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Sol CTRL" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Sol Menü" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Sol Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Sol Windows" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menü" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Orta Tuş" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Sayısal Tuş Takımı *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Sayısal Tuş Takımı +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Sayısal Tuş Takımı -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Sayısal Tuş Takımı ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Sayısal Tuş Takımı /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Sayısal Tuş Takımı 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Sayısal Tuş Takımı 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Sayısal Tuş Takımı 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Sayısal Tuş Takımı 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Sayısal Tuş Takımı 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Sayısal Tuş Takımı 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Sayısal Tuş Takımı 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Sayısal Tuş Takımı 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Sayısal Tuş Takımı 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Sayısal Tuş Takımı 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Temizle" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Sayfa aşağı" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Sayfa yukarı" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Duraklat" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Oyna" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Yazdır" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Return" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Sağ" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Sağ Tuş" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Sağ CTRL" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Sağ Menü" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Sağ Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Sağ Windows" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Seç" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Uyku" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Ekran Resmi" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Boşluk" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Yukarı" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X Düğme 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X Düğme 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Yakınlaştır" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Mini harita gizli" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Radar kipinde mini harita, Yakınlaştırma x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Yüzey kipinde mini harita, Yakınlaştırma x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Doku kipinde mini harita" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Web sayfası açılamadı" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Web sayfası açılıyor" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "İlerle" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = aşağı in" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Kendiliğinden-ileri" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Kendiliğinden zıplama" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Geri" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Blok sınırları" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Kamera değiştir" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Sohbet" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Komut" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Konsol" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Uzaklığı Artır" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Sesi alçalt" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "\"zıpla\" ya çift dokunarak uçmayı aç/kapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "At" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "İleri" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Uzaklığı Azalt" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Sesi yükselt" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Envanter" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Zıpla" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Tuş zaten kullanımda" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Yerel komut" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Sesi Kıs" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Sonraki öge" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Önceki öge" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Uzaklık seçimi" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Ekran yakala" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Sız" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "HUD'ı aç/kapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Sohbet günlüğünü aç/kapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Hızlıyı aç/kapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Uçmayı aç/kapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Sisi aç/kapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Mini haritayı aç/kapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Hayalet aç/kapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Eğim hareketi aç/kapa" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "tuşa bas" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Değiştir" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Yeni Parola" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Eski Parola" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Parolalar eşleşmiyor!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Çıkış" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Ses Kısık" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Ses Seviyesi: %%%d" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "tr" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "Lütfen bir ad seçin!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) sanal joystick'in konumunu sabitler.\n" +"Devre dışı bırakılırsa, sanal joystick merkezi, ilk dokunuş konumu olur." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) \"Aux1\" düğmesini tetiklemek için sanal joystick kullanın.\n" +"Etkinleştirilirse, sanal joystick, ana çemberin dışındayken \"Aux1\" " +"düğmesini de dinler." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"Fraktalın dünya merkezinden 'scale' biriminde (X,Y,Z) kaydırması.\n" +"Uygun canlanma noktası yaratmak için istenen noktayı (0,0)'a\n" +"taşımada veya 'scale'ı artırarak istenen bir\n" +"noktaya yakınlaşmaya izin vermede kullanılabilir.\n" +"Öntanımlı olan öntanımlı parametreli Mandelbrot setleri için\n" +"uygun bir canlanma noktası için ayarlanmıştır, diğer durumlar\n" +"için değiştirme gerektirebilir.\n" +"Kabaca -2 ile 2 arası . Nodlardaki kaydırmalar için 'scale' ile çarpın." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"Nodlardaki fraktalın (X,Y,Z) boyutu.\n" +"Gerçek fraktal boyutu 2-3 kat büyük olur.\n" +"Bu sayılar çok büyük olabilir, fraktal dünyanın içine\n" +"sığmak zorunda değildir.\n" +"Fraktalın ayrıntısına yakınlaştırma için bunları artırın.\n" +"Öntanımlı, bir ada için uygun olan bir dikey-basık şekil\n" +"içindir, kaba şekil için 3 sayıyı da eşit ayarlayın." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Sırt dağların şeklini/boyutunu denetleyen 2D gürültü." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Yuvarlanan tepelerin şeklini/boyutunu denetleyen 2D gürültü." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Step dağların şeklini/boyutunu denetleyen 2D gürültü." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "Sırt dağ aralıklarının boyutunu/oluşumunu denetleyen 2D gürültü." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "Yuvarlanan tepelerin boyutunu/oluşumunu denetleyen 2D gürültü." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "Step dağ aralıklarının boyutunu/oluşumunu denetleyen 2D gürültü." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Nehir vadilerini ve kanallarını belirleyen 2B gürültü." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D bulutlar" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D kipi" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "3D kipi paralaks gücü" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Dev oyukları belirleyen 3D gürültü." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Dağ yapısını ve yüksekliğini belirleyen 3D gürültü.\n" +"Ayrıca yüzenkara dağ arazi yapısını da belirler." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"Yüzenkaraların yapısını tanımlayan 3D gürültü.\n" +"Öntanımlıdan değiştirildiğinde, 'scale' (öntanımlı 0.7) gürültüsünün\n" +"ayarlanması gerekebilir. Gürültü yaklaşık -2.0 ve 2.0 aralığındayken\n" +"yüzenkara koniklik fonksiyonları en iyidir." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "Nehir kanyon duvarlarının yapısını belirleyen 3D gürültü." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "Araziyi belirleyen 3D gürültü." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" +"Dağ çıkıntıları, uçurumlar, vb için 3D gürültü. Genellikle küçük " +"farklılıklar." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "Harita yığını başına zindan sayısını belirleyen 3B gürültü." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3D desteği.\n" +"Şu an desteklenen:\n" +"- none: 3d çıkışı yok.\n" +"- anaglyph: cyan/magenta renkli 3d.\n" +"- interlaced: tek/çift çizgi tabanlı polarizasyon ekran desteği.\n" +"- topbottom: ayrık ekran üst/alt.\n" +"- sidebyside: ayrık ekran yan yana.\n" +"- crossview: Şaşı 3d\n" +"- pageflip: quadbuffer tabanlı 3d.\n" +"Unutmayın ki interlaced kipi, gölgelendirmelerin etkin olmasını gerektirir." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Yeni bir harita için seçilmiş bir harita tohumu, rastgele için boş bırakın.\n" +"Ana menüden yeni bir dünya yaratırken geçersiz kılınır." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Sunucu çökerse tüm istemcilere görüntülenecek bir ileti." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Sunucu kapatıldığında tüm istemcilere görüntülenecek bir ileti." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "ABM aralığı" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "ABM zаman gideri" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Emerge için sıralanmış blokların mutlak sınırı" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Havada hızlanma" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Yerçekimi hızlanması, saniye başına nod cinsinden." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Etkin Blok Değiştiricileri" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Etkin blok yönetimi aralığı" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Etkin blok uzaklığı" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Etkin nesne gönderme uzaklığı" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Bağlanılacak adres.\n" +"Yerel bir sunucu başlatmak için bunu boş bırakın.\n" +"Ana menüdeki adres alanının bu ayarı geçersiz kılacağını unutmayın." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Nodları kazarken parçacıklar ekler." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Ekranınızın (yalnızca Android/X11 olmayan) dpi yapılandırmasını ayarlayın " +"ör: 4k ekranlar için." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Kullanıcı arayüzü öğelerini ölçeklemek için kullanılan algılanan görüntü " +"yoğunluğunu ayarlayın." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Yüzenkara katmanının yoğunluğunu ayarlar\n" +"Yoğunluğu artırmak için değeri artırın. Pozitif ve negatif olabilir.\n" +"Değer = 0.0: hacmin %50'si yüzenkaradır\n" +"Değer = 2.0 ('mgv7_np_floatland' de daha yüksek olabilir, emin olmak\n" +"için her zaman test edin) katı yüzenkara katmanı yaratır." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "Öge adını ekle" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Gelişmiş" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Işık eğrisini 'gama düzeltmesi' uygulayarak değiştirir.\n" +"Yüksek değerler orta ve düşük ışık seviyelerini daha parlak hale getirir.\n" +"'1.0' değeri ışık eğrisini değiştirmeden bırakır.\n" +"Bunun sadece gün ışığı ve suni ışık üstünde önemli bir etkisi vardır.\n" +"doğal gece ışığı üzerinde çok az etkisi vardır." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "Daima uçma ve hızlı" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "Ortam oklüzyon gama" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Bir oyuncunun her 10 saniyede bir gönderebileceği ileti sayısı." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Vadileri güçlendirir." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Anisotropik filtreleme" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Sunucuyu duyur" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Bu sunucu listesine duyur." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Öge adını ekle" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Öge adını araç ipucuna ekle." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Elma ağaçları gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Kol eylemsizliği" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Kol eylemsizliği, kamera hareket ettiğinde, \n" +"daha gerçekçi kol hareketi sunar." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Çökmeden sonra yeniden bağlanmak için sor" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"Bu uzaklıkta sunucu istemcilere gönderilecek blokları agresifçe\n" +"iyileştirecektir.\n" +"Küçük değerler potansiyel olarak görülebilir işleyici hataları pahasına " +"(bazı bloklar\n" +"su altında, mağaralarda ve de bazen karada işlenmeyecek) performansı " +"oldukça\n" +"iyileştirecektir. \n" +"Bu değeri max_block_send_distance değerinden yükseğe ayarlamak bu\n" +"iyileştirmeyi devre dışı kılar.\n" +"Harita bloğu (16 nod) cinsinden." + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Kendiliğinden ileri tuşu" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Tek-nod engellere kendiliğinden zıpla." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Sunucu listesine kendiliğinden bildir." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Ekran boyutunu hatırla" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Kendiliğinden boyutlandırma kipi" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Aux1 tuşu" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Tırmanma/alçalma için Aux1 tuşu" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Geri tuşu" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Taban yer seviyesi" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Taban arazi yüksekliği." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Temel yetkiler" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Sahil gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Sahil gürültü eşiği" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Bilineer filtreleme" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Bağlı adres" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Biyom API sıcaklık ve nem gürültü parametreleri" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Biyom Gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "Blok gönderme iyileştirme uzaklığı" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Kalın ve italik yazı tipi konumu" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Kalın ve italik eş aralıklı yazı tipi konumu" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Kalın yazı tipi konumu" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Kalın eş aralıklı yazı tipi konumu" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Oyuncu içinde inşa" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Yerleşik" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "Kamera değiştir" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"Nodlar arasındaki, kamera 'yakın kırpma düzlem' uzaklığı, 0 ile 0,25 " +"arasında.\n" +"Yalnızca GLES platformlarında çalışır. Çoğu kullanıcının bunu değiştirmesi " +"gerekmez.\n" +"Artırma, zayıf GPU'larda görüntü bozulmalarını azaltabilir.\n" +"0,1 = Öntanımlı, 0,25 = Zayıf tabletler için iyi değer." + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Kamera yumuşatma" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Sinematik kipte kamera yumuşatma" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Kamera güncelleme açma/kapama tuşu" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Mağara gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Mağara gürültü #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Mağara gürültü #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Mağara genişliği" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Mağara1 gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Mağara2 gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Oyuk sınırı" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Oyuk gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "Oyuk konikliği" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "Oyuk eşiği" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Oyuk üst sınırı" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"Işık eğrisi artırma aralığının merkezi.\n" +"0.0 minimum, 1.0 maksimum ışık seviyesidir." + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "Sohbet komutu zaman iletisi eşiği" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Sohbet komutları" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Sohbet yazı tipi boyutu" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Sohbet tuşu" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Sohbet günlük düzeyi" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Sohbet ileti sayısı sınırı" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Sohbet ileti biçimi" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "Sohbet iletisi vurma eşiği" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Sohbet iletisi maksimum uzunluğu" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Sohbet açma/kapama tuşu" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Sohbet web bağlantıları" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Yığın boyutu" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Sinematik kip" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Sinematik kip tuşu" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Saydam dokuları temizle" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"Sohbet konsolu çıktısında etkinleştirilen tıklanabilir (orta tıklama veya " +"Ctrl+sol tıklama) web bağlantıları." + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "İstemci" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "İstemci ve Sunucu" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "İstemci modlama" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "İstemci tarafı modlama kısıtlamaları" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "İstemci tarafı nod arama aralığı kısıtlaması" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "İstemci modlama" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Tırmanma hızı" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Bulut yarıçapı" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Bulutlar" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Bulutlar istemci tarafı bir efekttir." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Ana menüde bulutlar" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Renkli sis" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Renkli gölgeler" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"İçerik deposunda gizlemek için bayrakların virgülle ayrılmış listesi.\n" +"\"nonfree\" Özgür Yazılım Vakfının tanımına göre 'özgür yazılım' olarak\n" +"nitelenemeyecek paketleri gizler.\n" +"İçerik puanlarını da belirleyebilirsiniz.\n" +"Bu bayraklar Minetest sürümlerinden bağımsızdır,\n" +"tam listeyi görmek için: https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"Modların internet üstünden veri yüklemesine ve indirmesine izin veren HTTP " +"API'lerine,\n" +"erişim izni verilen modların virgülle ayrılmış listesi." + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"Mod güvenliği açık olsa bile (request_insecure_environment() ile) güvensiz\n" +"fonksiyonlara erişimine izin verilen güvenilen modların virgülle ayrılmış " +"listesi." + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Komut tuşu" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Harita kütlerini diske kaydederken kullanılacak sıkıştırma düzeyi.\n" +"-1 - öntanımlı sıkıştırma düzeyini kullan\n" +"0 - hiçbir sıkıştırma yok, en hızlı\n" +"9 - en iyi sıkıştırma, en yavaş" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"Harita kütlerini istemciye(client) gönderirken kullanılacak sıkıştırma " +"düzeyi.\n" +"-1 - öntanımlı sıkıştırma düzeyini kullan\n" +"0 - hiçbir sıkıştırma yok, en hızlı\n" +"9 - en iyi sıkıştırma, en yavaş" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Bitişik cam" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Dış medya sunucusuna bağlan" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "Nod tarafından destekleniyorsa camı bitiştir." + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Konsol saydamlığı" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Konsol rengi" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Konsol yüksekliği" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "Çevrim İçi İçerik Deposu" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "ContentDB: Kara Liste" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "ContentDB aşırı eşzamanlı indirmeler" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "ContentDB URL" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "Sürekli ileri" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"Sürekli ileri hareket, kendiliğinden ileri tuşuyla açılır/kapanır.\n" +"Kapamak için kendiliğinden ileriye tekrar veya geri harekete basın." + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Kontroller" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Gündüz/gece döngüsü uzunluğunu denetler.\n" +"Örnekler:\n" +"72 = 20dk, 360 = 4dk, 1 = 24saat, 0 = gündüz/gece/herşey değişmeden kalır." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "Göl çöküklerinin diklik/çukurluğunu denetler." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "Tepelerin dikliğini/yüksekliğini denetler." + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"Tünellerin genişliğini kontrol eder, daha küçük bir değer daha geniş " +"tüneller oluşturur.\n" +"Değer >= 10.0, tünellerin oluşumunu tamamen devre dışı kılar ve yoğun " +"gürültü\n" +"hesaplamaları önler." + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Çökme iletisi" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Yaratıcı" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Artı saydamlığı" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"Artı saydamlığı (solukluk, 0 ile 255 arasında).\n" +"Ayrıca nesne artı rengi için de geçerlidir" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Artı rengi" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"Artı rengi (R,G,B).\n" +"Ayrıca nesne artı rengini de değiştirir" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Hasar" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Hata ayıklama bilgisi açma/kapama tuşu" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "Hata ayıklama günlük dosyası boyut eşiği" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Hata ayıklama günlük düzeyi" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Ses alçaltma tuşu" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "Adanmış sunucu adımı" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Öntanımlı hızlanma" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Öntanımlı oyun" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Yeni bir dünya yaratırken öntanımlı oyun.\n" +"Ana menüden bir dünya yaratırken geçersiz kılınır." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Öntanımlı parola" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Öntanımlı yetkiler" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Öntanımlı rapor biçimi" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Öntanımlı yığın boyutu" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"Gölge filtreleme kalitesini tanımla.\n" +"Bu, bir PCF veya Poisson diski uygulayarak yumuşak gölge efektini taklit " +"eder,\n" +"ancak aynı zamanda daha fazla kaynak kullanır." + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "Ağaçların elması olacağı alanları belirler." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "Kumlu sahilleri olan alanları belirler." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "Daha yüksek arazinin dağılımını ve uçurumların dikliğini belirler." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "Daha yüksek arazinin dağılımını belirler." + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" +"Oyukların tam boyutunu belirler, daha küçük değerler daha büyük oyuklar " +"yaratır." + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "Geniş çaplı nehir kanal yapısını belirler." + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "İsteğe bağlı tepelerin ve göllerin konumunu ve arazisini belirler." + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "Taban yer seviyesini belirler." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "Nehir kanalının derinliğini tanımlar." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" +"Maksimal oyuncu transfer uzaklığını bloklar cinsinden tanımlar (0 = " +"sınırsız)." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "Nehir kanalının genişliğini tanımlar." + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "Nehir vadisinin genişliğini tanımlar." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "Ağaç alanlarını ve ağaç yoğunluğunu belirler." + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"İstemcide ızgara güncellemeri arasındaki ms cinsinde gecikme. Bunu artırmak " +"ızgara\n" +"güncelleme hızını yavaşlatacaktır, bu yüzden yavaş istemcilerde kararsızlığı " +"azaltır." + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "İnşa sonrası blokları göndermedeki gecikme" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "Milisaniye cinsinden ipuçlarını gösterme gecikmesi." + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "Kaldırılan Lua API işleme" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "Altında dev oyuklar bulabileceğiniz derinlik." + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "Aşağısında büyük mağaralar bulabileceğiniz derinlik." + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Oyuncular bağlandığında ve sunucu listesinde görüntülenecek sunucu " +"açıklaması." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "Çöl gürültü eşiği" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"Çöller, np_biome bu değeri aştığında gerçekleşir.\n" +"'Snowbiomes' bayrağı etkinleştirildiğinde, bu yok sayılır." + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Blok animasyonlarını eşzamansız yap" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "Dekorasyonlar" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Kazma tuşu" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Kazı parçacıkları" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Hile önleme devre dışı" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Boş parolalara izin verme" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "Ekran Yoğunluğu Ölçekleme Faktörü" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Sunucu listesinde görüntülenecek sunucu alan adı." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Uçma için zıplamaya çift dokun" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Zıplama tuşuna çift dokunmak uçma kipini açar/kapar." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Öge atma tuşu" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "Mapgen hata ayıklama bilgisini dökümle." + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Zindan maksimum Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Zindan minimum Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Zindan gürültüsü" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"IPv6 desteğini etkinleştirin (hem istemci hem de sunucu için).\n" +"IPv6 bağlantılarının çalışması için gereklidir." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"İstemcide Lua modlama desteğini etkinleştir.\n" +"Bu destek deneyseldir ve API değişebilir." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"Poisson disk filtrelemeyi etkinleştir.\n" +"Doğru ise \"yumuşak gölgeler\" yapmak için Poisson diski kullanır. Değilse " +"PCF filtreleme kullanır." + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"Renkli gölgeleri etkinleştir.\n" +"Doğru ise yarı saydam düğümlerde renkli gölgeler oluşturur. Bu fazla kaynak " +"kullanır." + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Konsol penceresini etkinleştir" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Tüm oyuncular için yaratıcı kipi etkinleştir" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Joystick'leri etkinleştir" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "Mod kanalları desteğini etkinleştir." + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Mod güvenliğini etkinleştir" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Oyuncuların hasar almasını ve ölmesini etkinleştir." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Rastgele kullanıcı girişini etkinleştir (yalnızca test için)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"Basit ortam oklüzyon ile yumuşak aydınlatmayı etkinleştirir.\n" +"Farklı görünüm veya hız için devre dışı bırakın." + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Eski istemcilerin bağlanmasına izin vermemek için etkinleştirin.\n" +"Eski istemciler yeni sunuculara bağlanırken çökmeyecek kadar uyumludur,\n" +"ancak beklediğiniz tüm yeni özellikleri desteklemiyor olabilir." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"(Sunucu tarafından sağlanan) uzak medya sunucu kullanımını etkinleştirin.\n" +"Sunucuya bağlanırken uzak sunucular medya (ör: dokular) indirmek için daha\n" +"hızlı bir yol sunar." + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"Köşe arabellek nesnelerini etkinleştirin.\n" +"Bu grafik performansını büyük ölçüde artırır." + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Görüntü sallanması için çarpan.\n" +"Örneğin: 0 ise görüntü sallanması yok; 1.0 ise normal; 2.0 ise çift." + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"IPv6 sunucu çalıştırmayı etkin/devre dışı kılar.\n" +"Eğer bind_address ayarlı ise yok sayılır.\n" +"enable_ipv6 etkin kılınmalıdır." + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"Hable'ın 'Uncharted 2' film ton eşlemesini etkinleştirir.\n" +"Fotoğrafsal film ton eğrisini taklit eder ve bu\n" +"yüksek dinamik aralıklı görüntülerin görünümü yakınlaştırır. Orta-aralık\n" +"karşıtlık biraz geliştirilir, vurgular ve gölgeler kademeli olarak " +"sıkıştırılır." + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Envanter ögelerinin animasyonunu etkinleştirir." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "Yüz yönü döndürülmüş kafeslerin önbelleklenmesini etkinleştirir." + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Mini haritayı etkinleştirir." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Ses sistemini etkinleştirir.\n" +"Devre dışı bırakılırsa, bu tüm sesleri devre dışı kılar ve oyun içindeki\n" +"ses denetimlerinin işlevi olmaz.\n" +"Bu ayarı değiştirmek, yeniden başlatma gerektirir." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "Vadi profili" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "Motor profilleme veri yazdırma aralığı" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Varlık yöntemleri" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"Yüzenkara konikliğinin eksponenti. Koniklik davranışını değiştirir.\n" +"Değer = 1.0 düzgün, doğrusal bir koniklik oluşturur.\n" +"Değerler > 1.0, öntanımlı ayrılmış yüzenkaralar için uygun pürüzsüz bir\n" +"koniklik oluşturur.\n" +"Değerler <1.0 (örneğin 0.25) Daha düz aşağı karalarla daha tanımlı bir " +"yüzey\n" +"seviyesi oluşturur: katı bir yüzenkara katmanı için uygundur." + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "Odaklanmadığında veya duraklatıldığında FPS" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "Çarpan gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "Düşme sallanması çarpanı" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Yedek yazı tipi konumu" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Hızlı tuşu" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "Hızlı kip hızlanması" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Hızlı kip hızı" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Hızlı hareket" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"Hızlı hareket (\"Aux1\" tuşu ile).\n" +"Bu, sunucu üzerinde \"hızlı\" yetkisi gerektirir." + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "Görüş alanı" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "Derece cinsinden görüş alanı." + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"Çok Oyunculu Sekmesinde görüntülenen sık kullanılan sunucularızı içeren\n" +"istemci/sunucu listesi/ içindeki dosya." + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "Dolgu derinliği" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "Dolgu derinlik gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "Filmsel ton eşleme" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"Filtrelenmiş dokular, genellikle PNG iyileştiricilerin dikkate almadığı, " +"tamamen\n" +"şeffaf komşuları ile RGB değerlerini kaynaştırabilir, bazen şeffaf " +"dokularda\n" +"karanlık veya aydınlık kenarlara neden olabilir. Bunu temizlemek için bu\n" +"filtreyi doku yükleme zamanında uygulayın. Bu, mip eşleme etkinleştirilirse\n" +"otomatik olarak etkinleştirilir." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "Düzgünleştirme:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "Birlikte tepe/dağ aralık yüksekliğini belirleyen 4 2D gürültüden ilki." + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "Birlikte tünelleri belirleyen iki 3D gürültüden ilki." + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "Sabit harita tohumu" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "Sabit sanal joystick" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "Yüzenkara yoğunluğu" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "Yüzenkara maksimum Y" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "Yüzenkara minimum Y" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "Yüzenkara gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "Yüzenkara koniklik eksponenti" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "Yüzenkara koniklik uzaklığı" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "Yüzenkara su seviyesi" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Uçma tuşu" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Uçma" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Sis" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "Sis başlangıcı" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Sis açma/kapama tuşu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "Yazı tipi boyutu" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Öntanımlı kalın yazı tipi" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Öntanımlı italik yazı tipi" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Yazı tipi gölgesi" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Yazı tipi gölge saydamlığı" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Yazı tipi boyutu" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "Öntanımlı yazı tipinin nokta (pt) olarak boyutu." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "Eş aralıklı yazı tipinin nokta (pt) olarak boyutu." + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"Son sohbet metninin ve sohbet isteminin nokta(pt) cinsinden yazı tipi " +"boyutu.\n" +"0 değer öntanımlı yazı tipi boyutunu kullanır." + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"Oyuncu sohbet ileti biçimi. Aşağıdaki dizgiler geçerli yer tutuculardır:\n" +"@name, @message, @timestamp (isteğe bağlı)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Ekran yakalama biçimi." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "Öntanımlı Formspec Arkaplan Rengi" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "Öntanımlı Formspec Arkaplan Donukluğu" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "Tam-Ekran Formspec Arkaplan Rengi" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "Tam-Ekran Formspec Arkaplan Donukluğu" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "Formspec öntanımlı arka plan rengi (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "Öntanımlı formspec arkaplan donukluğu (0 ile 255 arasında)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "Formspec tam-ekran arka plan rengi (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "Tam-ekran formspec arkaplan donukluğu (0 ile 255 arasında)." + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "İleri tuşu" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Birlikte tepe/dağ aralık yüksekliğini belirleyen 4 2D gürültüden dördüncüsü." + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "Fraktal türü" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "Sisin işlenmeye başlayacağı görünebilir uzaklığın kesiri" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" +"Harita blokları (16 nod) cinsinden istemciler için blokların ne kadar " +"uzaklıktan üretileceği." + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" +"Harita blokları (16 nod) cinsinden blokların ne kadar uzaklıktan istemciye " +"gönderileceği." + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"İstemcilerin nesneleri ne kadar uzaktan bileceği, harita bloğu (16 nod) " +"cinsinden.\n" +"\n" +"Bunu active_block_range daha büyük ayarlamak, sunucunun etkin nesneleri\n" +"oyuncunun baktığı yöndeki bu uzaklığa kadar korumasına neden olur.\n" +"(Bu mobların görüntüden aniden yok olmasını engelleyebilir)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Tam ekran" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Tam ekran kipi." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "Arayüz boyutlandırma" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Arayüz boyutlandırma filtresi" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "Arayüz boyutlandırma filtresi txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Oyunlar" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "Genel geri çağrılar" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"Genel harita üretim özellikleri.\n" +"Mapgen v6'da 'decorations' bayrağı ağaçlar ve cangıl çimi hariç tüm " +"dekorasyonları\n" +"denetler, diğer mapgenlerde bu bayrak tüm dekorasyonları denetler." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"Azami ışık seviyesinde ışık eğrisinin gradyantı.\n" +"En yüksek ışık düzeylerinin karşıtlığını denetler." + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"Asgari ışık seviyesinde ışık eğrisinin gradyantı.\n" +"En düşük ışık düzeylerinin karşıtlığını denetler." + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Grafik" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "Grafik" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "Grafik" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Yerçekimi" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "Yer seviyesi" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "Yer gürültüsü" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP modları" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "Arayüz boyutlandırma" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "HUD açma/kapama tuşu" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"Kullanım dışı Lua API çağrılarının ele alınması:\n" +"- none: (yok) kullanım dışı çağrıları günlüğe kaydetmez.\n" +"- log: (günlük) kullanım dışı çağrıları taklit eder ve geri izlemesini " +"günlüğe kaydeder (öntanımlı).\n" +"- error: (hata) kullanım dışı çağrılar kullanıldığında iptal eder (mod " +"geliştiricileri için önerilen)." + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"Profilcinin kendini belgelemesini sağla\n" +"* boş bir fonksiyonu belgele\n" +"Bu belgelemenin eklediği (+1 donksiyon çağrısı) yükü tahmin eder.\n" +"* istatistikleri güncellemek için kullanılan örnekleyiciyi belgelendir." + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "Isı kaynaşma gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "Isı gürültüsü" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"İlk pencere boyutunun yükseklik bileşeni. Tam ekran kipinde yok sayılır." + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Yükseklik gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "Yükseklik seçme gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "Tepe dikliği" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "Tepe eşiği" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "Hilliness1 gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "Hilliness2 gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "Hilliness3 gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "Hilliness4 gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "Sunucu listesinde görüntülenecek sunucunun ana sayfası ." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"Zıplarken veya düşerken havada yatay hızlanma,\n" +"saniye başına nod cinsinden." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"Hızlı kipte yatay ve dikey hızlanma,\n" +"saniye başına nod cinsinden." + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"Yerdeyken veya tırmanırken yatay ve dikey hızlanma,\n" +"saniye başına nod cinsinden." + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "Hotbar sonraki tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "Hotbar önceki tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Hotbar bölme 1 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Hotbar bölme 10 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Hotbar bölme 11 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Hotbar bölme 12 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Hotbar bölme 13 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Hotbar bölme 14 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Hotbar bölme 15 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Hotbar bölme 16 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Hotbar bölme 17 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Hotbar bölme 18 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Hotbar bölme 19 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Hotbar bölme 2 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Hotbar bölme 20 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Hotbar bölme 21 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Hotbar bölme 22 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Hotbar bölme 23 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Hotbar bölme 24 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Hotbar bölme 25 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Hotbar bölme 26 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Hotbar bölme 27 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Hotbar bölme 28 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Hotbar bölme 29 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Hotbar bölme 3 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Hotbar bölme 30 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Hotbar bölme 31 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Hotbar bölme 32 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Hotbar bölme 4 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Hotbar bölme 5 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Hotbar bölme 6 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Hotbar bölme 7 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Hotbar bölme 8 tuşu" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Hotbar bölme 9 tuşu" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Nehirlerin ne kadar derin yapılacağı." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Sıvı dalgalarının ne kadar hızlı hareket edeceğini belirler . Daha yüksek = " +"daha hızlı.\n" +"Negatif ise, sıvı dalgalar geriye hareket edecektir.\n" +"Dalgalanan sıvılar etkin kılınmalıdır." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"Sunucunun kullanılmayan harita bloklarını boşaltmadan önce ne kadar " +"bekleyeceği.\n" +"Daha yüksek değer daha düzgün olsa da daha çok RAM kullanır." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "Harekete karşı sıvı direncini artırmak için bunu azaltın." + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Nehirlerin ne kadar geniş yapılacağı." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "Nem kaynaşma gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "Nem gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "Biyomlar için nem değişimi." + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6 sunucu" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"FPS bundan daha fazla yükselecekse, CPU gücünü boşa\n" +"tüketmemek için, uykuya dalarak sınırla." + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" +"Devre dışı bırakılırsa \"Aux1\" tuşu, hem uçma hem de hızlı kipi etkin ise,\n" +"hızlı uçma için kullanılır." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"Etkinleştirilirse sunucu oyuncunun göz konumuna göre harita bloğu\n" +"oklüzyon ayırma yapacaktır. Bu istemciye gönderilen block sayısını\n" +"%50-80 azaltabilir. İstemci artık en görünmeyenleri almayacağından\n" +"hayalet kipinin kullanışı azalacaktır." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"Uçma kipi ile birlikte etkinleştirilirse, oyuncu katı nodlardan uçarak " +"geçebilir.\n" +"Bu, sunucuda \"hayalet\" yetkisi gerektirir." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"Etkinleştirilirse, \"sızma\" tuşu yerine \"Aux1\" tuşu aşağı inme ve " +"alçalma\n" +"için kullanılır." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"Sunucuya bağlanırken kayıt onayını etkinleştir.\n" +"Devre dışı bırakılırsa, yeni hesap kendiliğinden kaydedilir." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"Etkinleştirilirse, eylemler geri alma için kaydedilebilir.\n" +"Bu seçenek yalnızca sunucu yeniden başlatıldığında okunur." + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "Etkinleştirilirse, çok oyunculuda hile önleme devre dışı bırakılır." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"Etkinleştirilirse, geçersiz dünya verisi sunucunun kapanmasına neden olmaz.\n" +"Yalnızca ne yaptığınızı biliyorsanız bunu etkinleştirin." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" +"Etkinleştirilirse, uçarken veya yüzerken hareket yönünü oyuncunun eğimine " +"göre değiştirir." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "Etkinleştirilirse, yeni oyuncular boş bir parola ile katılamaz." + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"Etkinleştirilirse, bulunduğunuz yerin konumuna (ayak + göz seviyesi) " +"blokları yerleştirebilirsiniz.\n" +"Küçük alanlarda nodkutuları ile çalışırken, bu yararlıdır." + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"Nod uzaklığı için CSM sınırlaması etkinse, get_node çağrıları noddan\n" +"oyuncuya olan bu uzaklığa sınırlanır." + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"Bir sohbet komutunun yürütülmesi, saniye cinsinden bu belirtilen süreden " +"daha\n" +"uzun sürerse, zaman bilgisini sohbet komut iletisine ekle" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"Debug.txt dosyasının boyutu, açıldığında bu ayarda belirtilen megabayt\n" +"sayısını aşıyorsa, dosya varsa eski bir debug.txt.1 dosyasını\n" +"silerek debug.txt.1 dosyasına taşınır.\n" +"debug.txt yalnızca bu ayar pozitifse taşınır." + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" +"Bu ayarlanırsa, oyuncular her zaman verilen konumdan (yeniden) canlanacaktır." + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Dünya hatalarını yok say" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" +"Oyun-içi sohbet konsolu arka plan saydamlığı (solukluk, 0 ile 255 arasında)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "Oyun-içi sohbet konsolu arka plan rengi (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "Oyun-içi sohbet konsolu yüksekliği 0.1 (%10) ve 1.0 (%100) arası." + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Ses yükseltme tuşu" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "Zıplarken ilk dikey hız, saniye başına nod cinsinden." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"Yerleşiği belgele.\n" +"Genellikle bu yalnızca çekirdek/yerleşik katkıda bulunanlar için gereklidir" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Instrument chat commands on registration." +msgstr "Kayıt sırasında sohbet komutlarını belgele." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"Kayıt sırasında global geri çağrı fonksiyonlarını belgele.\n" +"(minetest.register_*() fonksiyonuna gönderdiğiniz herşey)" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" +"Kayıt sırasında Etkin Blok Değiştiricilerin eylem fonksiyonlarını belgele." + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" +"Kayıt sırasında Yükleme Blok Değiştiricilerin eylem fonksiyonlarını belgele." + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "Kayıt sırasında varlık yöntemlerini belgele." + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "Dünyadaki önemli değişiklikleri kaydetme aralığı, saniye cinsinden." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "Günün saatini istemcilere gönderme aralığı." + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Envanter ögeleri animasyonu" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Envanter tuşu" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Ters fare" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Ters dikey fare hareketi." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "İtalik yazı tipi konumu" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "İtalik eş aralıklı yazı tipi konumu" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "Öge varlık TTL" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Yinelemeler" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"Özyinelemeli fonksiyon yinelemeleri.\n" +"Bunu artırmak ince ayrıntı miktarını artırır, fakat işleme\n" +"yükünü de artırır.\n" +"Yineleme = 20'de bu mapgenin, mapgen v7'ye benzer bir yükü vardır." + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "Joystick ID" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "Joystick düğmesi tekrarlama aralığı" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "Joystick ölü bölgesi" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "Joystick frustum duyarlılığı" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Joystick türü" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Yalnızca Julia set.\n" +"Hypercomplex sabitin W bileşeni.\n" +"Fraktalın şeklini değiştirir.\n" +"3D Fraktallarda etkisi yoktur.\n" +"Aralığı kabaca -2 ile 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Yalnızca Julia set.\n" +"Hypercomplex sabitin X bileşeni.\n" +"Fraktalın şeklini değiştirir.\n" +"Aralığı kabaca -2 ile 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Yalnızca Julia set.\n" +"Hypercomplex sabitin Y bileşeni.\n" +"Fraktalın şeklini değiştirir.\n" +"Aralığı kabaca -2 ile 2." + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"Yalnızca Julia set.\n" +"Hypercomplex sabitin Z bileşeni.\n" +"Fraktalın şeklini değiştirir.\n" +"Aralığı kabaca -2 ile 2." + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Zıplama tuşu" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Zıplama hızı" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Görüntüleme uzaklığını azaltma tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Ses alçaltma tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kazma tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"O anki seçili ögeyi atma tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Görüntüleme uzaklığını artırma tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Ses yükseltme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Zıplama tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Hızlı kipte hızlı hareket tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Oyuncuyu geriye hareket ettirme tuşu.\n" +"Etkinken, kendiliğinden ileriyi de devre dışı kılar\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Oyuncuyu ileri hareket ettirme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Oyuncuyu sola hareket ettirme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Oyuncuyu sağa hareket ettirme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Ses kısma tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Komut yazmak için sohbet penceresini açma tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Yerel komutlar yazmak için sohbet penceresini açma tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Sohbet penceresini açma tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Envanteri açma tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Yerleştirme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"11. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"12. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"13. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"14. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"15. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"16. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"17. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"18. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"19. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"20. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"21. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"22. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"23. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"24. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"25. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"26. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"27. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"28. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"29. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"30. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"31. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"32. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"8. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"5. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"1. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"4. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Hotbar'da sonraki ögeyi seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"9. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Hotbar'da önceki ögeyi seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"2. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"7. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"6. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"10. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"3. hotbar bölmesini seçme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Sızma tuşu.\n" +"Aynı zamanda aşağı inmek ve, aux1_descends kapalı ise, suda alçalmak için " +"kullanılır.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Birinci ve üçüncü kişi kamerası arası geçiş tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Ekran yakalama tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kendiliğinden ileriyi açma/kapama tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Sinematik kipi açma/kapama tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Mini harita gösterme/gizleme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Hızlı kipi açma/kapama tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Uçma açma/kapama tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Hayalet kipi açma/kapama tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Eğim hareket kipi açma/kapama tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Kamera güncelleme açma/kapama tuşu. Yalnızca geliştirme için kullanılır.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Sohbet gösterme/gizleme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Hata ayıklama bilgisi gösterme/gizleme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Sis gösterme/gizleme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"HUD gösterme/gizleme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Büyük sohbet konsolunu gösterme/gizleme tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Profilciyi gösterme/gizleme tuşu. Geliştirme için kullanılır.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Sınırsız görüş uzaklığı açma/kapama tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Mümkün olduğunda görünüm yakınlaştırmayı kullanma tuşu.\n" +"Bakın: http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "10 saniyede bir X iletiden çok gönderen oyuncuları at." + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "Göl dikliği" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "Göl eşiği" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Dil" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Büyük mağara derinliği" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "Büyük mağara maksimum sayısı" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "Büyük mağara minimum sayısı" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "Büyük mağara su alma oranı" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Büyük sohbet konsolu tuşu" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Yaprak stili" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"Yaprak stili:\n" +"- Fancy: tüm yüzler görünür\n" +"- Simple: yalnızca dış yüzler, tanımlı special_tiles kullanılıyorsa\n" +"- Opaque: saydamlık devre dışı" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Sol tuş" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"Sunucunun tık uzunluğu ve nesnelerin genellikle ağ üzerinden güncelleneceği\n" +"aralık." + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"Sıvı dalgalarının uzunluğu.\n" +"Dalgalanan sıvılar etkin kılınmalı." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "Etkin Blok Değiştirici (ABM) yürütme döngüleri arasındaki süre" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "NodeTimer yürütme döngüleri arasındaki sürenin uzunluğunu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "Etkin blok yönetimi döngüleri arasındaki süre" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"debug.txt'e yazılacak günlük düzeyi:\n" +"- <nothing> (günlük yok)\n" +"- none (düzeyi olmayan iletiler)\n" +"- error (hata)\n" +"- warning (uyarı)\n" +"- action (eylem)\n" +"- info (bilgi)\n" +"- verbose (ayrıntılı)" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "Işık eğrisi artırma" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "Işık eğrisi artırma merkezi" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "Işık eğrisi artırma yayılması" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "Işık eğrisi gama" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "Işık eğrisi yüksek gradyan" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "Işık eğrisi düşük gradyan" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Yumuşak Aydınlatma" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"Harita üretim sınırı, nodlar cinsinden, (0, 0, 0)'dan tüm 6 doğrultuda.\n" +"Yalnızca tamamen mapgen sınırı içindeki harita yığınları üretilir.\n" +"Değer dünya-başına saklanır." + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"Paralel HTTP isteklerinin sayısını sınırlar. Etkilediği:\n" +"- Medya alma, sunucu remote_media ayarını kullanıyorsa\n" +"- Sunucu listesi indirme ve sunucu duyurusu.\n" +"- Ana menü (ör: mod yöneticisi) tarafından uygulanan indirmeler.\n" +"Yalnızca cURL ile derlenmiş ise etkiye sahiptir." + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "Sıvı akışkanlığı" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "Sıvı akışkanlığı yumuşatma" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "Maksimum sıvı döngüsü" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "Sıvı sırası silme zamanı" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "Sıvı batışı" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "Saniye cinsinden sıvı güncelleme aralığı." + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "Sıvı güncelleme tıkı" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "Oyun profilciyi yükle" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"Oyun profil verisini toplamak için oyun profilcisini yükler.\n" +"Derlenmiş profile erişmek için /profiler komutu sağlar.\n" +"Mod geliştiricileri ve sunucu operatörleri için yararlıdır." + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "Blok Değiştiriciler Yükleniyor" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "Zindanların alt Y sınırı." + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "Yüzenkaraların alt Y sınırı." + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Ana menü betiği" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" +"Sis ve gökyüzü renklerini gün saatine (şafak/günbatımı) ve bakış yönüne " +"bağlı değiştir." + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "Tüm sıvıları opak yapar" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "Hafıza deposu için harita sıkıştırma düzeyi" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "Ağ aktarma hızı için harita sıkıştırma düzeyi" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Harita dizini" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "Mapgen Karpat'a özgü harita üretim değerleri." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"Mapgen Düz'e özgü harita üretim değerleri.\n" +"Ara sıra göller ve tepeler düz dünyaya eklenebilir." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"Mapgen Fraktal'a özgü harita üretim değerleri.\n" +"'terrain' fraktal olmayan arazi üretimini etkinleştirir:\n" +"okyanus, adalar ve yeraltı." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"Mapgen Vadiler'e özgü harita üretim değerleri. \n" +"'altitude_chill': Isıyı yükseklikle azaltır.\n" +"'humid_rivers': Nehirlerin etrafında nemi artırır.\n" +"'vary_river_depth': Etkinse, düşük nem ve yüksek ısı nehirlerin sığ ve\n" +"bazen kuru olmasına neden olur\n" +"'altitude_dry': Nemi yükseklikle azaltır." + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "Mapgen v5'e özgü harita üretim değerleri." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"Mapgen v6'ya özgü harita üretim değerleri.\n" +"'snowbiomes' bayrağı yeni 5 biyom sistemini etkinleştirir.\n" +"'snowbiomes' bayrağı etkinleştirildiğinde, ormanlar kendiliğinden " +"etkinleştirilir ve\n" +"'jungles' bayrağı yok sayılır." + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"Mapgen v7'ye özgü harita oluşturma özellikleri.\n" +"'ridges': Nehirler.\n" +"'floatlands': Atmosferde yüzen kara kütleleri.\n" +"'caverns:' Dev derin yeraltı mağaraları." + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Harita üretim sınırı" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Harita kaydetme aralığı" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map shadows update frames" +msgstr "Harita güncelleme zamanı" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "Harita bloğu sınırı" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "Harita bloğu ızgara üretim gecikmesi" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "Harita Bloğu ızgara üretecinin Harita Bloğu önbellek boyutu MB" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "Harita bloğu boşaltma zaman aşımı" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "Mapgen Karpat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "Mapgen Karpat'a özgü bayraklar" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Mapgen Düz" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "Mapgen Düz'e özgü bayraklar" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Mapgen Fraktal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Mapgen Fraktal'a özgü bayraklar" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Mapgen V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "Mapgen V5'e özgü bayraklar" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Mapgen V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "Mapgen V6'ya özgü bayraklar" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Mapgen V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "Mapgen V7'ye özgü bayraklar" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Mapgen Vadiler" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "Mapgen Vadiler'e özgü bayraklar" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Mapgen hata ayıklama" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Mapgen adı" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Maksimum blok üretme uzaklığı" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "Maksimum blok gönderme uzaklığı" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Adım başına işlenen maksimum sıvı." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "Maksimum clearobjects ek bloğu" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Yineleme başına maksimum paket" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Maksimum FPS" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "Pencere odaklanmadığında veya oyun duraklatıldığında en yüksek FPS." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "Gölgeleri işlemek için azami mesafe." + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "Maksimum zorla yüklenen blok" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "Maksimum hotbar genişliği" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "Her harita yığını için rastgele büyük mağara sayısının üst sınırı." + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "Her harita yığını için rastgele küçük mağara sayısının üst sınırı." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"Maksimum sıvı direnci. Sıvıya, yüksek hızda girerken yavaşlamayı\n" +"denetler." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"İstemci başına eş zamanlı gönderilen blokların maksimum sayısı.\n" +"Maksimum toplam sayı dinamik olarak hesaplanır.\n" +"max_toplam = tavan((#istemciler + max_kullanıcı) * istemci_başına / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "Yükleme için sıraya alınabilecek maksimum blok sayısı." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"Üretilmesi için sıralanacak maksimum blok sayısı.\n" +"Bu sınır her oyuncu için zorunlu kılınır." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"Bir dosyadan yüklenmesi için sıraya koyulacak maksimum blok sayısı.\n" +"Bu sınır her oyuncu için zorunlu kılınır." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"En yüksek eşzamanlı indirme sayısı.Bu sınırı aşan indirmeler sıraya " +"alınacaktır.\n" +"Bu curl_parallel_limit den daha az olmalıdır." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "Zorla yüklenen harita bloklarının maksimum sayısı." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"İstemcinin hafızada tutacağı maksimum harita bloğu sayısı.\n" +"Sınırsız miktar için -1'e ayarlayın." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"Gönderme adımı başına gönderilecek maksimum paket sayısı, bağlantınız\n" +"yavaş ise azaltmayı deneyin, fakat hedeflenen istemci sayısının iki " +"katından\n" +"düşük bir sayıya azaltmayın." + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "Aynı anda bağlanabilen maksimum oyuncu sayısı." + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "Gösterilen son sohbet iletilerinin maksimum sayısı" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "Bir blokta statik olarak saklı nesnelerin maksimum sayısı." + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Blok başına maksimum nesne" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"Hotbar için kullanılacak geçerli pencerinin maksimum oranı.\n" +"Sağ veya sol hotbar'da gösterilecek bir şey varsa yararlıdır." + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "İstemci başına maksimum eşzamanlı blok gönderimi" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "Dış sohbet kuyruğunun maksimum boyutu" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"Dış sohbet kuyruğunun maksimum boyutu\n" +"Kuyruğa almayı kapamak için 0 ve sınırsız kuyruk boyutu için -1." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" +"Bir dosya indirmesinin (ör: mod indirme) alabileceği azami süre, milisaniye " +"cinsinden belirtilir." + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" +"Etkileşimli bir isteğin (ör: sunucu listesi getirme) alabileceği azami süre, " +"milisaniye cinsinden belirtilir." + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Maksimum kullanıcı" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Kafes önbelleği" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Günün iletisi" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "Bağlanan oyunculara görüntülenecek günün iletisi." + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "Seçili nesneyi vurgulamak için kullanılan yöntem." + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "Sohbete yazılacak en az günlük düzeyi." + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Mini harita" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Mini harita tuşu" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "Mini harita tarama yüksekliği" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "Her harita yığını için rastgele büyük mağara sayısının alt sınırı." + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "Her harita yığını için rastgele küçük mağara sayısının alt sınırı." + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "Minimum doku boyutu" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mip eşleme" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "Profilci" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "Güvenlik" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "Mod kanalları" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "HUD ögelerinin boyutunu değiştirir." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Eş aralıklı yazı tipi konumu" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Eş aralıklı yazı tipi boyutu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "Eş aralıklı yazı tipi boyutu" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "Dağ yükseklik gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "Dağ gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "Dağ varyasyon gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "Dağ sıfır seviyesi" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Fare hassasiyeti" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "Fare hassasiyet çarpanı." + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "Çamur gürültüsü" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"Düşme sallanması için çarpan.\n" +"Örneğin: 0 ise görüntü sallanması yok; 1.0 ise normal; 2.0 ise çift." + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Ses kısma tuşu" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Sesi kapat" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"Yeni bir dünya oluştururken kullanılacak harita üretecinin adı.\n" +"Ana menüde bir dünya oluşturmak bunu geçersiz kılacaktır.\n" +"Şu anda aşırı dengesiz durumdaki harita üreteçleri:\n" +"- v7'nin isteğe bağlı yüzenkaraları (öntanımlı olarak devre dışı)." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"Oyuncunun adı.\n" +"Bir sunucu çalışırken, bu adla bağlanan istemciler yöneticidir.\n" +"Ana menüden başlatırken, bu geçersiz kılınır." + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" +"Oyuncular katılındığında ve sunucu listesinde görüntülenecek sunucu adı." + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "Yakın kırpma düzlemi" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"Dinlenecek ağ portu (UDP).\n" +"Bu değer ana menüden başlatırken geçersiz kılınır." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "Ağ" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "Yeni kullanıcıların bu parolayı girmesi gerekir." + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Hayalet" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Hayalet tuşu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Nod Vurgulama" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "Nod vurgulama" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "NodeTimer aralığı" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Gürültüler" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "Emerge iş sayısı" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"Kullanılacak emerge iş parçacıklarının sayısı.\n" +"Değer 0:\n" +"- Kendiliğinden seçim. Ortaya çıkan emerge iş parçacıklarının sayısı\n" +"- alt limit 1 olmak üzere 'işlemci sayısı - 2' olacaktır.\n" +"Başka bir değer:\n" +"- Emerge iş parçacıklarının sayısını, alt sınır 1 olmak üzere belirtir.\n" +"UYARI: Emerge iş parçacığı sayısının artırılması, motor mapgen hızını " +"arttırır, ancak\n" +"bu, özellikle tek oyunculu ve/veya Lua kodunu 'on_generated' çalıştırırken,\n" +"diğer işlemlere etki ederek oyun performansına zarar verebilir.\n" +"Birçok kullanıcı için en iyi ayar '1' olabilir." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"/clearobjects tarafında tek seferde yüklenebilecek ek blokların sayısı.\n" +"Bu sqlite işlem yükü ve bellek tüketimi (4096=100MB)\n" +"arasında bir dengedir." + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "Opak sıvılar" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" +"0 ile 255 arasında öntanımlı yazı tipinin arkasındaki gölgenin opaklığı " +"(alfa)." + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"Pencere odağı kaybolduğunda duraklat menüsünü aç. Bir formspec açıksa\n" +"duraklamaz." + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"Yedek yazı tipi konumu.\n" +"“freetype” ayarı etkinse: TrueType yazı tipi olmalı.\n" +"“freetype” ayarı devre dışıysa: bitmap veya XML vektör yazı tipi olmalı.\n" +"Bu yazı tipi belirli diller için veya öntanımlı yazı tipi kullanılamıyorsa " +"kullanılır." + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"Ekran görüntülerini kaydetme konumu. Mutlak veya göreli bir konum olabilir.\n" +"Klasör henüz yoksa oluşturulur." + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" +"Gölgeleme dizininin konumu. Bir konum belirtilmediyse, öntanımlı yer " +"kullanılacak." + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "Doku dizini konumu. Tüm dokular ilk burada aranır." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"Öntanımlı yazı tipi konumu.\n" +"“freetype” ayarı etkinse: TrueType yazı tipi olmalı.\n" +"“freetype” ayarı devre dışıysa: bitmap veya XML vektör yazı tipi olmalı.\n" +"Yazı tipi yüklenemiyorsa yedek yazı tipi kullanılır." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"Eş aralıklı yazı tipi konumu.\n" +"“freetype” ayarı etkinse: TrueType yazı tipi olmalı.\n" +"“freetype” ayarı devre dışıysa: bitmap veya XML vektör yazı tipi olmalı.\n" +"Bu yazı tipi konsol, profil ekranı v.b. için kullanılır." + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "Pencere odağı kaybolunca duraklat" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "Diskten yüklenen sıralanmış blokların oyuncu başına sınırı" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "Üretilecek sıralanmış blokların, oyuncu başına sınırı" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Fizik" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Eğim hareket tuşu" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "Eğim hareket kipi" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Yerleştirme tuşu" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "Yerleştirme tekrarlama aralığı" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"Oyuncu yerçekimi tarafından etkilenmeden uçabilir.\n" +"Bu, sunucuda \"uçma\" yetkisi gerektirir." + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "Oyuncu transfer uzaklığı" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Oyuncu oyuncuya karşı" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Poisson filtreleme" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"Bağlanılacak port (UDP).\n" +"Ana menüdeki port alanının bunu geçersiz kılacağını unutmayın." + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"Fare düğmeleri tutulurken, kazmanın ve yerleştirmenin tekrarlanmasını önle.\n" +"Çok sık yanlışlıkla kazıyor veya yerleştiriyorsanız bunu etkinleştirin." + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" +"Modların bir kabuk komutu çalıştırmak gibi güvensiz şeyler yapmasını önle." + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"Motorun profilleme verilerini düzenli aralıklarla (saniye cinsinden) " +"yazdır.\n" +"0 = devre dışı. Geliştiriciler için yararlıdır." + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "basic_privs sahibi oyuncuların verebileceği yetkiler" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "Profilci" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "Profilciyi açma/kapama tuşu" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Prometheus dinleyici adresi" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Prometheus dinleyici adresi.\n" +"Minetest ENABLE_PROMETHEUS seçeneği etkin olarak derlenmişse,\n" +"bu adreste Prometheus için metrik dinleyicisini etkinleştirin.\n" +"Metrikler http://127.0.0.1:30000/metrics adresinden alınabilir" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "Sıvı içeren büyük mağaraların oranı." + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"Bulut alanı yarıçapı, 64 nod bulut kareleri sayısı cinsinden.\n" +"26'dan büyük değerler bulut alanı köşelerinde keskin kesimler üretmeye " +"başlar." + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "Nehirler etrafında vadiler yapmak için araziyi yükseltir." + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "Rasgele giriş" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Uzaklık seçim tuşu" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Son Sohbet İletileri" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Normal yazı tipi konumu" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Uzak medya" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Uzak port" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"Gelen sohbet iletilerinden renk kodlarını kaldır\n" +"Bunu oyuncuların iletilerinde renk kullanmalarını durdurmak için kullanın" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "Öntanımlı ana menüyü özel olanı ile değiştirir." + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Rapor konumu" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"Sunucularda belirli istemci tarafı fonksiyonların erişimini sınırlar\n" +"Bu byte bayraklarını birleştirerek istemci tarafı özellikleri sınırlayın,\n" +"veya sınırlama olmaması için 0'a ayarlayın:\n" +"LOAD_CLIENT_MODS: 1 (istemci modu yüklemeyi kapat)\n" +"CHAT_MESSAGES: 2 (send_chat_message çağrısını istemci-tarafı kapat)\n" +"READ_ITEMDEFS: 4 (get_item_def çağrısını istemci-tarafı kapat)\n" +"READ_NODEDEFS: 8 (get_node_def çağrısını istemci-tarafı kapat)\n" +"LOOKUP_NODES_LIMIT: 16 (get_node çağrısını istemci-tarafı\n" +"csm_restriction_noderange'e sınırla)\n" +"READ_PLAYERINFO: 32 (get_player_names çağrısını istemci-tarafı kapat)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "Sırt dağ yayılma gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "Sırt gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "Sırt su altı gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "Sırt dağ boyut gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Sağ tuş" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Nehir kanal derinliği" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "Nehir kanal genişliği" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Nehir derinliği" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Nehir gürültüsü" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Nehir boyutu" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "Nehir vadisi genişliği" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "Geri alma kaydı" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "Yuvarlanan tepe boyut gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "Yuvarlanan tepeler yayılma gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "Yuvarlak mini harita" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "Güvenli kazma ve yerleştirme" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "Kumlu sahiller np_beach bu değeri aştığında oluşur." + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "İstemci tarafından alınan haritayı diske kaydet." + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "Değiştiğinde pencere boyutunu kendiliğinden kaydet." + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "Sunucudan alınan harita kaydediliyor" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"Kullanıcı tanımlı bir değerle arayüzü boyutlandır.\n" +"Arayüzü boyutlandırırken en-yakın-komşu-kenar-yumuşatma\n" +"filtresi kullan. Bu bazı pürüzlü kenarları yumuşatır ve küçültürken\n" +"pikselleri kaynaştırır, görüntüler tam sayı olmayan boyutlarla\n" +"ölçeklendiğinde bazı kenar piksellerde bulanıklığa neden olur." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Ekran:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Ekran yüksekliği" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Ekran genişliği" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Ekran yakalama klasörü" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Ekran yakalama biçimi" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Ekran yakalama kalitesi" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"Ekran yakalama kalitesi. Yalnızca JPEG biçimi için kullanılır.\n" +"1 en kötü kalite; 100 en iyi kalite.\n" +"Öntanımlı kalite için 0 kullanın." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Ekran yakala" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "Deniz yatağı gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Birlikte tepe/dağ aralık yüksekliğini belirleyen 4 2D gürültüden ikincisi." + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "Birlikte tünelleri belirleyen iki 3D gürültüden ikincisi." + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "Bakın: https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "Seçim kutusu kenar rengi (R,G,B)." + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "Seçim kutusunu rengi" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "Seçim kutusu genişliği" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"18 fraktal türünden birini seçer.\n" +"1 = 4D \"Roundy\" Mandelbrot seti.\n" +"2 = 4D \"Roundy\" Julia seti.\n" +"3 = 4D \"Squarry\" Mandelbrot seti.\n" +"4 = 4D \"Squarry\" Julia seti.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot seti.\n" +"6 = 4D \"Mandy Cousin\" Julia seti.\n" +"7 = 4D \"Variation\" Mandelbrot seti.\n" +"8 = 4D \"Variation\" Julia seti.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot seti.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia seti.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot seti.\n" +"12 = 3D \"Christmas Tree\" Julia seti.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot seti.\n" +"14 = 3D \"Mandelbulb\" Julia seti.\n" +"15 = 3D \"Cosine Mandelbulb\" mandelbrot seti.\n" +"16 = 3D \"Cosine Mandelbulb\" julia seti.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot seti.\n" +"18 = 4D \"Mandelbulb\" Julia seti." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Sunucu URL'si" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Sunucu adı" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Sunucu Açıklaması" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "Sunucu URL'si" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Sunucu adresi" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Sunucu açıklaması" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Sunucu adı" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Sunucu portu" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "Sunucu tarafı oklüzyon ayırma" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Sunucu Portu" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "Sunucu liste URL'si" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "Sunucu liste URL'si" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Sunucu liste dosyası" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Dili ayarlayın. Sistem dilini kullanmak için boş bırakın.\n" +"Bunu değiştirdikten sonra yeniden başlatmak gerekir." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" +"İstemcilerin gönderdiği sohbet iletilerinin maksimum karakter uzunluğunu " +"ayarla." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"Gölge gücünü ayarla.\n" +"Daha düşük değer daha açık gölgeler, daha yüksek değer daha koyu gölgeler " +"anlamına gelir." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"Yumuşak gölge yarıçapı boyutunu ayarla.\n" +"Daha düşük değerler daha keskin, daha büyük değerler daha yumuşak gölgeler " +"anlamına gelir.\n" +"En düşük değer 1.0 ve en yüksek değer 10.0" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"Güneş/Ay yörüngesinin eğimini derece olarak ayarla\n" +"0 değeri, eğim / dikey yörünge olmadığı anlamına gelir.\n" +"En düşük değer 0.0 ve en yüksek değer 60.0" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"Gölge Eşlemeyi etkinleştirmek için doğru olarak ayarlayın.\n" +"Gölgelemelerin etkinleştirilmesini gerektirir." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"Dalgalanan yaprakları için doğru'ya ayarlayın.\n" +"Gölgelemeler etkin kılınmalıdır." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"Dalgalanan sıvılar (su gibi) için doğru'ya ayarlayın.\n" +"Gölgelemeler etkin kılınmalıdır." + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"Dalgalanan bitkiler için doğru'ya ayarlayın.\n" +"Gölgelemeler etkin kılınmalıdır." + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"Gölge dokusu kalitesini 32 bit olarak ayarlar.\n" +"Yanlış ise 16 bit doku kullanılacaktır.\n" +"Bu, gölgede çok daha fazla bozulmalara neden olabilir." + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Gölgeleme konumu" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"Gölgelemeler gelişmiş görsel efektlere izin verir ve bazı ekran kartlarında " +"performansı\n" +"artırabilir.\n" +"Bu yalnızca OpenGL video arka ucu ile çalışır." + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Gölge filtresi kalitesi" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "Gölgeleri işlemek için nodlardaki gölge eşleme azami mesafesi" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "32 bitte gölge eşleme dokusu" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "Gölge eşleme dokusu boyutu" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" +"Öntanımlı yazı tipinin gölge uzaklığı (piksel olarak). 0 ise, gölge çizilmez." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "Gölge gücü" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "Mini harita şekli. Etkin = Yuvarlak, devre dışı = kare." + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Hata ayıklama bilgisini göster" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "Varlık seçim kutularını göster" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Varlık seçim kutularını göster.\n" +"Bunu değiştirdikten sonra yeniden başlatma gerekir." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Show name tag backgrounds by default" +msgstr "Ad etiketi arka planlarını öntanımlı olarak göster" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Kapatma iletisi" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"Mapgen tarafından üretilen harita yığınlarının boyutu, harita bloğu\n" +"(16 nod) cinsinden.\n" +"UYARI! Bu değeri 5'in üstüne çıkarmanın faydası yoktur ve birçok\n" +"tehlikesi vardır\n" +"Bu değeri düşürmek mağara ve zindan yoğunluğunu azaltır.\n" +"Bu değerin, değiştirilmesi özel kullanım içindir, değiştirilmemesi önerilir." + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"Izgara üretecinin Harita Bloğu önbellek boyutu. Bunu artırmak önbellek\n" +"vuruş yüzdesini artırır, ana işlem parçasından kopyalanan veriyi azaltır,\n" +"sonuç olarak yırtılmayı azaltır." + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "Gökyüzü Gövdesi Yörünge Eğimi" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "Dilim w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "Yükseklikleri değiştirmek için eğim ve dolgu birlikte işler." + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "Küçük mağara maksimum sayısı" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "Küçük mağara minimum sayısı" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "Biyomların sınırlarda kaynaşması için düşük çaplı nem değişimi." + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "Biyomların sınırlarda kaynaşması için düşük çaplı sıcaklık değişimi." + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Yumuşak aydınlatma" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"Etrafa bakarken kamerayı yumuşatır. Bakış veya fare yumuşatma olarak da " +"bilinir.\n" +"Videoların kaydı için yararlıdır." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "Sinematik kipte kamera dönüşünü yumuşatır. 0 devre dışı bırakır." + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "Kamera dönüşünü yumuşatır. 0 devre dışı bırakır." + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Sızma tuşu" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Sızma hızı" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "Sızma hızı, saniye başına nod cinsinden." + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Yumuşak gölge yarıçapı" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Ses" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"İstemcinin UDP kullanmak yerine medyayı hangi URL'den alacağını belirtir.\n" +"$filename cURL ile $remote_media$filename den erişilebilir olmalıdır\n" +"(tabi ki, remote_media eğik çizgi ile bitmelidir).\n" +"Var olmayan dosyalar her zamanki yoldan alınır." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"Nodların, ögelerin ve araçların öntanımlı yığın boyutunu belirtir.\n" +"Modların veya oyunların belirli (veya tüm) ögeler için açıkça bir yığın " +"ayarlayabileceğini unutmayın." + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"Işık eğrisi artırma aralığının yayılması.\n" +"Artırılacak aralığın genişliğini denetler.\n" +"Işık eğrisi artırma Gaussian'ın standart sapması." + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "Sabit canlanma noktası" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "Diklik gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "Step dağ boyut gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "Step dağ yayılma gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "3D kipi paralaksın gücü." + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"Işık eğrisi artırmanın gücü.\n" +"3 'boost' parametresi parlaklık artırılan\n" +"bir ışık eğrisi aralığı tanımlar." + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "Katı protokol denetleme" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "Renk kodlarını kaldır" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"Katı yüzenkara katmanına yerleştirilmiş isteğe bağlı suyun yüzey seviyesi.\n" +"Su öntanımlı olarak devre dışıdır ve yalnızca bu değer,\n" +"'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (üst koniklik başlangıcı)\n" +"üstünde ayarlandığında yerleştirilir.\n" +"***UYARI, DÜNYA VE SUNUCU PERFORMANSI İÇİN POTANSİYEL TEHLİKE***:\n" +"Su yerleşimi etkinleştirilirken, sunucuyu yoracak aşırı su akışını ve " +"aşağıdaki\n" +"dünya yüzeyine büyük taşkınları önlemek için, yüzenkaralar katı bir katman\n" +"olması için, 'mgv7_floatland_density' 2.0'a (veya 'mgv7_np_floatland' e " +"bağlı\n" +"olarak başka zorunlu değere) ayarlanarak\n" +"yapılandırılmalı ve test edilmelidir." + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "Eşzamanlı SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "Biyomlar için sıcaklık değişimi." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Ayarlar" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "Arazi alternatif gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "Arazi taban gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Arazi yüksekliği" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "Arazi üst gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "Arazi gürültüsü" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Tepeler için arazi gürültü eşiği.\n" +"Dünyanın tepelerle kaplı alanının oranını denetler.\n" +"Daha büyük oranlar için 0.0'a doğru ayarlayın." + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"Göller için arazi gürültü eşiği.\n" +"Dünyanın göllerle kaplı alanının oranını denetler.\n" +"Daha büyük oranlar için 0.0'a doğru ayarlayın." + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "Arazi süreklilik gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Doku konumu" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"Gölge eşlemenin işleneceği doku boyutu.\n" +"Bu, 2'nin bir kuvveti olmalıdır.\n" +"Daha büyük sayılar daha iyi gölgeler oluşturur ama aynı zamanda daha fazla " +"kaynak kullanır." + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" +"Bir nod üstündeki dokular nod'a ya da dünyaya göre hizalanabilir.\n" +"İlk kip, makineler, mobilyalar v.b. için uygunken ikinci kip medivenlerin\n" +"ve mikro blokların çevreye daha iyi uymasını sağlar.\n" +"Ancak, bu seçenek yeni olduğundan, eski sunucularda kullanılamayabilir,\n" +"bu seçenek onu belirli nod türleri için zorunlu kılmaya izin verir. Bunun\n" +"DENEYSEL olduğunu ve düzgün çalışmayabileceğini unutmayın." + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "İçerik deposu için URL" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "Joystick'in ölü bölgesi" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"`/profiler save [biçim]` biçim olmadan çağırıldığında,\n" +"profillerin kayıt edileceği öntanımlı biçim." + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "Toprak veya başka biyom doldurucu nodun derinliği." + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "Profillerin içine kaydedileceği, dünya konumuna bağlı dosya konumu." + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "Kullanılacak joystick'in tanımlayıcısı" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" +"Dokunmatik ekran etkileşiminin başlaması için gereken piksel cinsinde " +"uzunluk." + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" +"Dalgalanan sıvıların yüzeyinin maksimum yüksekliği.\n" +"4.0 = Dalga yüksekliği iki nod.\n" +"0.0 = Dalga hiç hareket etmez.\n" +"Öntanımlı 1.0'dır (1/2 nod).\n" +"Dalgalanan sıvılar etkin kılınmalıdır." + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "Sunucunun dinlediği ağ arayüzü." + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"Yeni kullanıcıların kendiliğinden aldığı yetkiler.\n" +"Sunucunuzda ve mod yapılandırmanızda tam bir liste için oyun içinde /privs " +"komutuna bakın." + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" +"Her oyuncu çevresinde, etkin blok işlemleri uygulanacak, bloklarının " +"hacminin\n" +"yarıçapı, harita blokları (16 nod) cinsinden.\n" +"Etkin bloklarda neseneler yüklenir ve ABMler çalışır.\n" +"Bu ayrıca etkin nesnelerin (moblar) korunacağı minimum uzaklıktır.\n" +"Bu active_object_send_range_blocks ile birlikte ayarlanmalıdır." + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" +"İşleme arka ucu.\n" +"Bunu değiştirdikten sonra yeniden başlatma gerekir.\n" +"Not: Android'de, emin değilseniz OGLES1 kullanın! Başka türlü, uygulama " +"başlayamayabilir.\n" +"Diğer platformlarda, OpenGL önerilir.\n" +"Gölgelendiriciler OpenGL (yalnızca masaüstü) ve OGLES2 (deneysel) tarafından " +"desteklenmektedir" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"Oyun-içi görünüm frustum'unu hareket ettirirken\n" +"joystick eksenlerinin hassasiyeti." + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"Nod ortam-oklüzyon gölgelemenin gücü (koyuluğu).\n" +"Daha düşük daha karanlık, daha yüksek daha aydınlıktır. Geçerli\n" +"değer aralığı 0.25 ile 4.0 dahil. Değer aralık dışında ise en yakın\n" +"geçerli değere ayarlanır." + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"Eski sıra ögeleri atılarak boyutunun düşürülmesine çalışılana kadar, " +"sıvılar\n" +"sırasının işleme kapasitesinin ötesine büyüyebileceği süre (saniye " +"cinsinden)\n" +"0 değeri bu özelliği devre dışı bırakır." + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" +"ABM'lerin her adımda yürütülmesi için izin verilen zaman gideri\n" +"(ABM aralığının bir parçası olarak)" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"Bir joystick tuş kombinasyonuna basılı tutarken, saniye\n" +"cinsinden tekrar eden olaylar arasında geçen süre." + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" +"Yerleştirme tuşuna basılı tutarken tekrarlanan düğüm yerleşimleri arasında " +"geçen\n" +"saniye cinsinden süre." + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Joystick'in türü" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"'altitude_chill' etkinse, ısının 20 azalacağı dikey uzaklık.\n" +"Ayrıca, 'altitude_dry' etkinse, nemin 10 azalacağı dikey\n" +"uzaklık." + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" +"Birlikte tepe/dağ aralık yüksekliğini belirleyen 4 2D gürültüden üçüncüsü." + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"Saniye cinsinde öge varlığının (atılan ögeler) yaşayacağı süre.\n" +"-1'e ayarlamak bu özelliği devre dışı bırakır." + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" +"Yeni bir Dünya başlatıldığında, milisaat cinsinden (0-23999), günün saati." + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Zaman gönderme aralığı" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Zaman hızı" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" +"İstemcinin kullanılmayan harita verilerini bellekten kaldırması için zaman " +"aşımı." + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"Gecikmeyi azaltmak için, oyuncu birşey inşa ederken blok transferleri " +"yavaşlatılır.\n" +"Bu bir nod yerleştirildikten veya kaldırıldıktan sonra ne kadar süre " +"yavaşlayacaklarını belirler." + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "Kamera kipi değiştirme tuşu" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "İpucu gecikmesi" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Dokunmatik ekran eşiği" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "Dokunmatik ekran eşiği" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Ağaçlar gürültüsü" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Trilineer filtreleme" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True (Doğru) = 256\n" +"False (Yanlış) = 128\n" +"Yavaş makinelerde mini haritayı daha düzgün yapmak için kullanılabilir." + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "Güvenilen modlar" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "Çok oyunculu sekmesinde görüntülenen sunucu listesinin URL'si." + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Aşağı örnekleme" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Alt örnekleme, daha düşük bir ekran çözünürlüğü kullanmaya benzer, ancak\n" +"GUI'yi koruyarak, yalnızca oyun dünyasına uygulanır.\n" +"Daha az ayrıntılı görüntü karşılığında önemli bir performans artışı " +"sağlamalıdır.\n" +"Daha yüksek değerler daha az ayrıntılı bir görüntü sağlar." + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Sınırsız oyuncu transfer uzaklığı" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "Kullanılmayan sunucu verilerini boşalt" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Zindanların üst Y sınırı." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "Yüzenkaraların üst Y sınırı." + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "Düz yerine 3D bulut görünümünü kullanın." + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "Ana menü arka planı için bir bulut animasyonu kullan." + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "Dokulara bir açıdan bakarken anisotropik filtreleme kullan." + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "Dokuları boyutlandırırken bilineer filtreleme kullan." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" +"Dokuları boyutlandırmak için mip haritalama kullan. Özellikle yüksek\n" +"çözünürlüklü bir doku paketi kullanırken, performans biraz artabilir.\n" +"Gamma doğruluklu küçültme desteklenmez." + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" +"Öbek/Küme kenarlarını düzeltmek için çok örnekli düzgünleştirmeyi(anti-" +"aliasing) kullanın.\n" +"Bu işlem görüntüyü keskinleştirirken 3 boyutlu görüş alanını düzeltir.\n" +"ama doku(texture) içindeki görüntüyü etkilemez.\n" +"(Saydam dokularda etkisi daha belirgindir)\n" +"Gölgelendirme kapalı ise düğüm arası(nod) boşluk görülür.\n" +"0'da ise düzgünleştirme kapalıdır.\n" +"Ayarları değiştirdikten sonra yenileme gereklidir." + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "Dokuları boyutlandırırken trilineer filtreleme kullan." + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "VSync" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "Vadi derinliği" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "Vadi dolgu" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "Vadi profili" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "Vadi eğimi" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "Biyom doldurma derinliğinin değişimi." + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "Maksimum dağ yüksekliğinin (nod cinsinden) değişimi." + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "Mağraların sayısının değişimi." + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"Arazi dikey boyutunun değişimi.\n" +"Gürültü < -0.55 iken arazi neredeyse düzdür." + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "Biyom yüzey nodlarının derinliğini değiştirir." + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"Arazinin engebeliliğni değiştirir.\n" +"terrain_base ve terrain_alt gürültüleri için 'persistence' değerini belirler." + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "Uçurumların dikliğini değiştirir." + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "Dikey tırmanma hızı, saniye başına nod cinsinden." + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "Dikey ekran eşzamanlılığı." + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "Video sürücüsü" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "Görünüm sallanması çarpanı" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "Nodlar cinsinden görünüm uzaklığı." + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "Görüş uzaklığı azaltma tuşu" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "Görüş uzaklığı artırma tuşu" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "Görünüm yakınlaştırma tuşu" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Görüntüleme uzaklığı" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "Sanal joystick Aux1 düğmesini tetikler" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Ses" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Tüm seslerin yüksekliği.\n" +"Ses sistemi etkin kılınmalıdır." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"Bir 4D fraktalın üretilen 3D diliminin W kordinatı.\n" +"4D şeklin hangi 3D diliminin üretileceğini belirler.\n" +"Fraktalın şeklini değiştirir.\n" +"3D fraktallarda etkisizdir.\n" +"Kabaca -2 ile 2 arası." + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Yürüme ve uçma hızı, saniye başına nod cinsinden." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Yürüme hızı" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" +"Hızlı kipte yürüme, uçma ve tırmanma hızı, saniye başına nod cinsinden." + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Su seviyesi" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "Dünyanın su yüzey seviyesi." + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Dalgalanan Nodlar" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Dalgalanan yapraklar" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Dalgalanan sıvılar" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Dalgalanan sıvılar dalga yüksekliği" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Dalgalanan sıvılar dalga hızı" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Dalgalanan sıvılar dalga-boyu" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Dalgalanan bitkiler" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "Web bağlantısı rengi" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"gui_scaling_filter true (doğru) olduğunda, tüm arayüz görüntülerinin\n" +"yazılım ile filtrelenmesi gerekir, ama bazı görüntüler doğrudan\n" +"donanımda üretilir (ör: envanterdeki nodlar için dokuya-işleme)." + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"gui_scaling_filter_txr2img true (doğru) olduğunda, görüntüleri\n" +"boyutlandırmak için donanımdan yazılıma kopyala. False (yanlış) ise,\n" +"dokuları donanımdan geri indirmeyi düzgün desteklemeyen video\n" +"sürücüleri için, eski boyutlandırma yöntemini kullan." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"Bilineer/trilineer/anisotropik filtreler kullanılırken, düşük çözünürlüklü " +"dokular\n" +"bulanık olabilir, bu yüzden en yakın komşu aradeğerleme ile keskin " +"pikselleri\n" +"korumak için kendiliğinden büyütme yapılır. Bu minimum doku boyutunu\n" +"büyütülmüş dokular için ayarlar; daha yüksek değerler daha net görünür,\n" +"ama daha fazla bellek gerektirir. 2'nin kuvvetleri tavsiye edilir. Bu ayar " +"YALNIZCA\n" +"bilineer/trilineer/anisotropik filtreler etkinse uygulanır.\n" +"Bu, dünya hizalı doku kendiliğinden boyutlandırmada taban nod doku boyutu\n" +"olarak da kullanılır." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" +"Ad etiketi arka planlarının öntanımlı olarak gösterilip gösterilmeyileceği.\n" +"Modlar yine de bir arka plan ayarlayabilir." + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" +"Harita bloğu başına nod doku animasyonlarının eşzamansız yapılıp " +"yapılmayacağı." + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"Bir uzaklık sınırı olmadan oyuncuların istemcilere gösterilip " +"gösterilmeyeceği.\n" +"Kaldırıldı, bunun yerine player_transfer_distance ayarını kullanın." + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" +"Oyuncuların birbirini öldürmesine veya zarar vermesine izin verilip " +"verilmeyeceği." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"İstemcilere bir (lua) çökmesinden sonra yeniden bağlanmanın sorulup " +"sorulmayacağı.\n" +"Eğer sunucu kendiliğinden yeniden başlamak için ayarlı ise bunu true (doğru) " +"olarak ayarlayın." + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "Görünebilir alanın sonunun sislendirilip sislendirilmeyeceği." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" +"Seslerin kısılıp kısılmayacağı. Ses sistemi devre dışı değilse \n" +"(enable_sound = false) sesleri istediğiniz zaman açabilirsiniz.\n" +"Oyunda, ses kısma durumunu, ses kısma tuşuyla veya duraklatma menüsünü\n" +"kullanarak belirleyebilirsiniz." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" +"İstemciye hata ayıklama bilgisinin gösterilip gösterilmeyeceği (F5'e basmak " +"ile aynı etkiye sahiptir)." + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" +"İlk pencere boyutunun genişlik bileşeni. Tam ekran kipinde yok sayılır." + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "Nodlar etrafındaki seçim kutusu çizgilerinin genişliği." + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"Yalnızca Windows sistemleri: Minetest'i komut satırı arka planda olarak " +"başlat.\n" +"debug.txt (öntanımlı ad) dosyası ile aynı bilgileri içerir." + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"Dünya dizini (dünyadaki her şey burada saklanır).\n" +"Ana menüden başlatıldığında gerekli değildir." + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Dünya başlangıc zamanı" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" +"Dünya hizalı dokular birçok noda kapsaması için boyutlandırılabilir.\n" +"Ancak sunucu istediğiniz boyutu göndermeyebilir, özellikle de özel\n" +"tasarlanmış bir doku paketi kullanıyorsanız; bu seçenekle, istemci\n" +"doku boyutunu temel alarak boyutu kendiliğinden belirlemeye çalışır.\n" +"Ayrıca bakın: texture_min_size\n" +"Uyarı: Bu seçenek DENEYSELdir!" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "Dünya-hizalı doku modu" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "Düz zemin Y'si." + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" +"Dağ yoğunluk gradyanı sıfır seviyesinin Y'si. Dağları dikey kaydırmada " +"kullanılır." + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "Büyük mağaraların üst sınırının Y'si." + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "Oyukların üstünden tam boyuta uzanacağı Y-uzaklığı." + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" +"Yüzenkaraların tam yoğunluktan hiçliğe konikleştiği Y-uzaklığı.\n" +"Konikleşme Y sınırından bu uzaklıkta başlar.\n" +"Katı bir yüzenkara katmanı için tepelerin/dağların yüksekliğini denetler.\n" +"Y sınırları arasındaki uzaklığın yarısına eşit veya az olmalıdır." + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "Ortalama arazi yüzeyinin Y-seviyesi." + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "Oyuk üst sınırının Y-seviyesi." + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "Uçurumlar yaratan daha yüksek arazinin Y-seviyesi." + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Daha alt arazinin ve göl yatağının Y-seviyesi." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Deniz yatağının Y-seviyesi." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "cURL dosya indirme zaman aşımı" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "cURL etkileşimli zaman aşımı" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "cURL paralel sınırı" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Yaratıcı Kip: " + +#~ msgid "- Damage: " +#~ msgstr "- Hasar: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = eğim bilgili paralaks oklüzyon (daha hızlı).\n" +#~ "1 = kabartma eşleme (daha yavaş, daha doğru)." + +#~ msgid "Address / Port" +#~ msgstr "Adres / Port" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "Işık tabloları için gama kodlamayı ayarlayın. Daha yüksek sayılar daha " +#~ "aydınlıktır.\n" +#~ "Bu ayar yalnızca istemci içindir ve sunucu tarafından yok sayılır." + +#~ msgid "Alters how mountain-type floatlands taper above and below midpoint." +#~ msgstr "" +#~ "Dağ-türü yüzerkaraların orta noktanın üstünde ve altında nasıl " +#~ "konikleştiğini değiştirir." + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Tek oyunculu dünyayı sıfırlamak istediğinizden emin misiniz ?" + +#~ msgid "Back" +#~ msgstr "Geri" + +#~ msgid "Basic" +#~ msgstr "Temel" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Tam ekran kipinde piksel başına bit (renk derinliği)." + +#~ msgid "Bump Mapping" +#~ msgstr "Tümsek Eşleme" + +#~ msgid "Bumpmapping" +#~ msgstr "Tümsek eşleme" + +#~ msgid "Center of light curve mid-boost." +#~ msgstr "Işık eğrisi orta-artırmanın merkezi." + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "Ana Menü arayüzünü değiştirir:\n" +#~ "- Full: Çoklu tek oyunculu dünyalar, oyun seçimi, doku paketi seçici, " +#~ "vb.\n" +#~ "- Simple: Bir tek oyunculu dünya, oyun veya doku paketi seçiciler yok.\n" +#~ "Küçük ekranlar için gerekli olabilir." + +#~ msgid "Config mods" +#~ msgstr "Modları yapılandır" + +#~ msgid "Configure" +#~ msgstr "Yapılandır" + +#~ msgid "Connect" +#~ msgstr "Bağlan" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "Sıvıdaki batma hızını denetler." + +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "Dağ-türü yüzenkaraların yoğunluğunu denetler.\n" +#~ "'mgv7_np_mountain' gürültü değerine eklenen bir gürültü kaydırmadır." + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "" +#~ "Tünellerin genişliğini denetler, daha küçük bir değer daha geniş tüneller " +#~ "yaratır." + +#~ msgid "Credits" +#~ msgstr "Hakkında" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "Artı rengi (R,G,B)." + +#~ msgid "Damage enabled" +#~ msgstr "Hasar etkin" + +#~ msgid "Darkness sharpness" +#~ msgstr "Karanlık keskinliği" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "CURL için öntanımlı zaman aşımı, milisaniye cinsinden.\n" +#~ "Yalnızca cURL ile derlenmiş ise bir etkisi vardır." + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "Yüzenkara düz arazilerin alanlarını belirler.\n" +#~ "Gürültü > 0 iken düz yüzenkaralar oluşur." + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "Dokuların örnekleme adımını tanımlar.\n" +#~ "Yüksek bir değer daha yumuşak normal eşlemeler verir." + +#~ msgid "Del. Favorite" +#~ msgstr "Sık Kullanılanı Sil" + +#~ msgid "" +#~ "Deprecated, define and locate cave liquids using biome definitions " +#~ "instead.\n" +#~ "Y of upper limit of lava in large caves." +#~ msgstr "" +#~ "Kullanılmıyor, bunun yerine biyom tanımlarını kullanarak mağara " +#~ "sıvılarını tanımlayın ve bulun.\n" +#~ "Büyük mağaralarda lav üst sınırının Y'si." + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "minetest.net'den , Minetest Game gibi, bir oyun indirin" + +#~ msgid "Download one from minetest.net" +#~ msgstr "minetest.net adresinden indirin" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "$1 indiriliyor ve kuruluyor, lütfen bekleyin..." + +#~ msgid "Enable VBO" +#~ msgstr "VBO'yu etkinleştir" + +#~ msgid "Enable register confirmation" +#~ msgstr "Kayıt onayını etkinleştir" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Tümsek eşlemeyi dokular için etkinleştirir. Normal eşlemelerin doku " +#~ "paketi tarafından sağlanması\n" +#~ "veya kendiliğinden üretilmesi gerekir\n" +#~ "Gölgelemelerin etkin olmasını gerektirir." + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "Filmsel ton eşlemeyi etkinleştirir" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "Çalışma anı dikey eşleme üretimini (kabartma efekti) etkinleştirir.\n" +#~ "Tümsek eşlemenin etkin olmasını gerektirir." + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "Paralaks oklüzyon eşlemeyi etkinleştirir.\n" +#~ "Gölgelemelerin etkin olmasını gerektirir." + +#~ msgid "Enter " +#~ msgstr "Gir " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "Deneysel seçenek, 0'dan daha büyük bir sayıya ayarlandığında\n" +#~ "bloklar arasında görünür boşluklara neden olabilir." + +#~ msgid "FPS in pause menu" +#~ msgstr "Duraklat menüsünde FPS" + +#~ msgid "Fallback font shadow" +#~ msgstr "Geri dönüş yazı tipi gölgesi" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "Geri dönüş yazı tipi gölge saydamlığı" + +#~ msgid "Fallback font size" +#~ msgstr "Geri dönüş yazı tipi boyutu" + +#~ msgid "Filtering" +#~ msgstr "Filtreleme" + +#~ msgid "Floatland base height noise" +#~ msgstr "Yüzenkara taban yükseklik gürültüsü" + +#~ msgid "Floatland mountain height" +#~ msgstr "Yüzenkara dağ yüksekliği" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "Yazı tipi gölge saydamlığı (solukluk, 0 ve 255 arası)." + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "Yedek yazı tipinin nokta (pt) olarak boyutu." + +#~ msgid "FreeType fonts" +#~ msgstr "Freetype yazı tipleri" + +#~ msgid "Full screen BPP" +#~ msgstr "Tam ekran BPP" + +#~ msgid "Game" +#~ msgstr "Oyun" + +#~ msgid "Gamma" +#~ msgstr "Gama" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Normal Eşlemeleri Üret" + +#~ msgid "Generate normalmaps" +#~ msgstr "Normal eşlemeleri üret" + +#~ msgid "HUD scale factor" +#~ msgstr "HUD boyut çarpanı" + +#~ msgid "High-precision FPU" +#~ msgstr "Yüksek hassasiyetli FPU" + +#~ msgid "IPv6 support." +#~ msgstr "IPv6 desteği." + +#~ msgid "In-Game" +#~ msgstr "Oyun içi" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Kur: dosya: \"$1\"" + +#~ msgid "Instrumentation" +#~ msgstr "Belgeleme" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Tuş ayaları. (Eğer bu menü çalışmaz ise, minetest.conf 'tan kaldırın)" + +#~ msgid "Lava depth" +#~ msgstr "Lav derinliği" + +#~ msgid "Lightness sharpness" +#~ msgstr "Aydınlık keskinliği" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "Diskte emerge sıralarının sınırı" + +#~ msgid "Main" +#~ msgstr "Ana" + +#~ msgid "Main menu style" +#~ msgstr "Ana menü stili" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "" +#~ "DirectX'in LuaJIT ile çalışmasını sağlar. Sorunlara neden olursa devre " +#~ "dışı bırakın." + +#~ msgid "Menus" +#~ msgstr "Menüler" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Radar kipinde mini harita, Yakınlaştırma x2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Radar kipinde mini harita, Yakınlaştırma x4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Yüzey kipinde mini harita, Yakınlaştırma x2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Yüzey kipinde mini harita, Yakınlaştırma x4" + +#~ msgid "Name / Password" +#~ msgstr "Ad / Parola" + +#~ msgid "Name/Password" +#~ msgstr "Ad/Şifre" + +#~ msgid "No" +#~ msgstr "Hayır" + +#~ msgid "Normalmaps sampling" +#~ msgstr "Normal eşleme örnekleme" + +#~ msgid "Normalmaps strength" +#~ msgstr "Normal eşleme gücü" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "Paralaks oklüzyon yineleme sayısı." + +#~ msgid "Ok" +#~ msgstr "Tamam" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "" +#~ "0 ile 255 arasında yedek yazı tipinin arkasındaki gölgenin opaklığı " +#~ "(alfa)." + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "Paralaks oklüzyon efektinin genel sapması, genellikle boyut/2." + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "Paralaks oklüzyon efektinin genel boyutu." + +#~ msgid "Parallax Occlusion" +#~ msgstr "Paralaks Oklüzyon" + +#~ msgid "Parallax occlusion" +#~ msgstr "Paralaks oklüzyon" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "Paralaks oklüzyon sapması" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "Paralaks oklüzyon yinelemesi" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "Paralaks oklüzyon kipi" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Paralaks oklüzyon boyutu" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "Paralaks oklüzyon gücü" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "TrueTypeFont veya bitmap konumu." + +#~ msgid "Path to save screenshots at." +#~ msgstr "Ekran yakalamaların kaydedileceği konum." + +#~ msgid "Player name" +#~ msgstr "Oyuncu adı" + +#~ msgid "Profiling" +#~ msgstr "Profilleme" + +#~ msgid "Projecting dungeons" +#~ msgstr "İzdüşüm zindanlar" + +#~ msgid "PvP enabled" +#~ msgstr "Savaş etkin" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Tek oyunculu dünyayı sıfırla" + +#~ msgid "Select Package File:" +#~ msgstr "Paket Dosyası Seç:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Sunucu / Tek oyunculu" + +#~ msgid "" +#~ "Set the shadow update time.\n" +#~ "Lower value means shadows and map updates faster, but it consume more " +#~ "resources.\n" +#~ "Minimun value 0.001 seconds max value 0.2 seconds" +#~ msgstr "" +#~ "Gölge güncelleme zamanını ayarla.\n" +#~ "Daha düşük değer, gölgeler ve harita güncellemelerinin daha hızlı olması " +#~ "anlamına gelir, ancak daha fazla kaynak tüketir.\n" +#~ "En düşük değer 0,001 saniye, en yüksek değer 0,2 saniyedir" + +#~ msgid "Shadow limit" +#~ msgstr "Gölge sınırı" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "" +#~ "Yedek yazı tipinin gölge uzaklığı (piksel olarak). 0 ise, gölge çizilmez." + +#~ msgid "Special" +#~ msgstr "Özel" + +#~ msgid "Special key" +#~ msgstr "Özel tuşu" + +#~ msgid "Start Singleplayer" +#~ msgstr "Tek oyunculu başlat" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "Üretilen normal eşlemelerin gücü." + +#~ msgid "Strength of light curve mid-boost." +#~ msgstr "Işık eğrisi orta-artırmanın kuvveti." + +#~ msgid "This font will be used for certain languages." +#~ msgstr "Belirli diller için bu yazı tipi kullanılacak." + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "OpenGL sürücüleri seçilmeden gölgelemeler etkinleştirilemez." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Sinematik Aç/Kapa" + +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "" +#~ "Yüzenkara dağların, orta noktanın altındaki ve üstündeki, tipik maksimum " +#~ "yüksekliği." + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "" +#~ "Tepe yüksekliğinin ve göl derinliğinin yüzenkara düz arazide değişimi." + +#~ msgid "View" +#~ msgstr "Görüntüle" + +#~ msgid "Waving Water" +#~ msgstr "Dalgalanan Su" + +#~ msgid "Waving water" +#~ msgstr "Dalgalanan su" + +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "" +#~ "Freetype yazı tiplerinin kullanılıp kullanılmayacağını, freetype desteği " +#~ "ile derlenmiş olmalıdır.\n" +#~ "Devre dışı kılınırsa, yerine bitmap ve XML vektör yazı tipleri kullanılır." + +#~ msgid "Whether dungeons occasionally project from the terrain." +#~ msgstr "Zindanların bazen araziden yansıyıp yansımayacağı." + +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "Büyük mağaralardaki lavın üst sınırının Y'si." + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "Yüzenkara orta noktasının ve göl yüzeyinin Y-seviyesi." + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "Yüzenkara gölgelerinin uzanacağı Y-seviyesi." + +#~ msgid "Yes" +#~ msgstr "Evet" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Bu sunucuya \"%s\" adıyla ilk kez katılmak üzeresiniz.\n" +#~ "Devam ederseniz, kimlik bilgilerinizi kullanarak yeni bir hesap bu " +#~ "sunucuda oluşturulur.\n" +#~ "Lütfen parolanızı tekrar yazın ve hesap oluşturmayı onaylamak için 'Kayıt " +#~ "Ol ve Katıl' düğmesini tıklayın veya iptal etmek için 'İptal'i tıklayın." + +#~ msgid "You died." +#~ msgstr "Öldün." + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/tt/minetest.po b/po/tt/minetest.po new file mode 100644 index 0000000..a755c05 --- /dev/null +++ b/po/tt/minetest.po @@ -0,0 +1,6846 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2021-04-08 18:26+0000\n" +"Last-Translator: Timur Seber <seber.tatsoft@gmail.com>\n" +"Language-Team: Tatar <https://hosted.weblate.org/projects/minetest/minetest/" +"tt/>\n" +"Language: tt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.6-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Тергезелергә" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Сез үлдегез" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Ярый" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Баш тарту" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Саклау" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Дөнья:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Эзләү" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "" + +#: src/client/game.cpp +msgid "- Public: " +msgstr "" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Сез үлдегез" diff --git a/po/uk/minetest.po b/po/uk/minetest.po new file mode 100644 index 0000000..b6240e3 --- /dev/null +++ b/po/uk/minetest.po @@ -0,0 +1,7234 @@ +msgid "" +msgstr "" +"Project-Id-Version: Ukrainian (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-31 17:28+0000\n" +"Last-Translator: Fixer <artem.brz@gmail.com>\n" +"Language-Team: Ukrainian <https://hosted.weblate.org/projects/minetest/" +"minetest/uk/>\n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Очистити чергу чату" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Порожня команда." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Вихід в основне меню" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Неправильна команда: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Введена команда: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Список гравців у мережі" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Гравці в мережі: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Ця команда вимкнена на сервері." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Переродитися" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Ви загинули" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Доступні команди:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Доступні команди: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Команда не доступна: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Отримати довідку для команд" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "Добре" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Трапилася помилка в скрипті Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Трапилася помилка:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Основне меню" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Перезʼєднання" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Сервер запросив перезʼєднання:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "Клієнтські моди" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Версія протоколу не співпадає. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Сервер працює за протоколом версії $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Сервер підтримує версії протоколу між $1 і $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Ми підтримуємо тільки протокол версії $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Ми підтримуємо протокол між версіями $1 і $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Скасувати" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Залежності:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Вимкнути все" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Вимкнути пакмод" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Дозволити все" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Дозволити пакмод" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Не вдалося ввімкнути мод \"$1\", тому що він містить не дозволені знаки. " +"Дозволяються такі знаки: [a-z0-9_]." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Знайти більше модів" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Мод:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Відсутні (необовʼязкові) залежності" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Опис гри відсутній." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Без обовʼязкових залежностей" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Опис пакмода відсутній." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Відсутні необовʼязкові залежності" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Необовʼязкові залежності:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Зберегти" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Світ:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "дозволено" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" вже існує. Бажаєте перезаписати?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Встановиться $1 і $2 залежностей." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 від $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 завантажується,\n" +"$2 у черзі" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "$1 завантажується..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "$1 необхідних залежностей не знайдено." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 встановиться, і $2 залежностей буде пропущено." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Усі пакунки" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Уже встановлено" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Назад до головного меню" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Базова гра:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB недоступний, коли Minetest скомпільований без CURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Завантаження..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Не вдалося завантажити $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Ігри" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Встановити" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Встановити $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Встановити відсутні залежності" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Установлення: Непідтримуваний тип файлу або пошкоджений архів" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Моди" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Не вдалося отримати пакунки" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Нічого не знайдено" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Нема оновлень" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Не знайдено" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Перезаписати" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Перевірте чи основна гра є правильною." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "У черзі" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Набори текстур" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Видалити" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Оновити" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Оновити все [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Переглянути більше інформації у вебоглядачі" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Світ з назвою \"$1\" вже існує" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Додаткова місцевість" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Висота снігового поясу" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Пояс посухи" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Змішування біомів" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Біоми" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Печери" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Печери" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Створити" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Декорації" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "Увага: тестова розробка призначена для розробників." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Підземелля" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Рівнина" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Плаваючі земельні масиви в небі" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Висячі острови (експериментальне)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Ґенерувати нефрактальну місцевість: океани і підземелля" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Пагорби" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Вологі ріки" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Підвищує вологість навколо річок" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "Встановити гру" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Озера" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Низька вологість і велика спека спричиняють мілководні або сухі річки" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Ґенератор світу" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "Мітки ґенератора світу" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "Мітки для ґенератора світу" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Гори" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Болотяний потік" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Мережа тунелів і печер" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Не вибрано гру" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Зменшує тепло з висотою" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Зменшує вологість з висотою" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Річки" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Річки на рівні моря" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Зерно" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Плавний перехід між біомами" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Споруди, що з’являються на місцевості (не впливає на дерева та траву " +"джунглів створені у v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Споруди, що з’являються на місцевості, зазвичай дерева та рослини" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Помірний, пустеля" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Помірний, пустелі, джунглі" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Помірний, пустеля, джунглі, тундра, тайга" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Ерозія поверхні місцевості" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Дерева і трава джунглів" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Змінювати глибину річок" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Дуже великі печери глибоко під землею" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Назва світу" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Ви не маєте встановлених ігор." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Ви впевнені, що бажаєте видалити \"$1\"?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Видалити" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: не вдалося видалити \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: недійсний шлях \"$1\"" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Видалити світ \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Підтвердіть пароль" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "Недоступна назва" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Назва" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Пароль" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "Паролі не збігаються" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "Зареєструватися" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Прийняти" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Перейменувати пакмод:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Цей пакмод має явну назву в modpack.conf, на що не вплине перейменування." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(не задані описи налаштувань)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D-шум" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Назад до налаштувань" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Оглянути" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "Вміст: Ігри" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "Вміст: Моди" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Заборонено" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Правити" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Дозволено" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Порожнистість" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Октави" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "Зсув" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Постійність" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Введіть коректне ціле число." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Введіть коректне число." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Відновити типові" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Шкала" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Пошук" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Виберіть каталог" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Виберіть файл" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Показувати технічні назви" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Значенням має бути щонайменше $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Значення має бути не більше $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "Х" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "Поширення по X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Поширення по Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Поширення по Z" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Абс. величина" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "За замовчанням" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "полегшений" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (Дозволено)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 модів" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Не вдалося встановити $1 в $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Встановлення мода: не вдається знайти справжню назву для: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" +"Встановлення мода: неможливо знайти відповідну назву теки для пакмоду $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Неможливо знайти правильний мод або пакмод" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Не вдалося встановити $1 як набір текстур" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Не вдалося встановити гру як $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Не вдалося встановити мод як $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Не вдалося встановити модпак як $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Завантаження..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Список публічних серверів вимкнено" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Спробуйте оновити список публічних серверів та перевірте своє Інтернет-" +"з'єднання." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Про" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Активні співрозробники" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Активний промальовувач:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Основні розробники" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Відкрити каталог користувацьких даних" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Відкриває каталог, що містить надані користувачем світи, ігри, моди,\n" +"і набори текстур у файловому керівнику / оглядачі." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Попередні співрозробники" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Попередні основні розробники" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "Ділитися даними зневадження" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Оглянути вміст у мережі" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Вміст" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Вимкнути набір текстур" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Інформація:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Встановлені пакунки:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Без залежностей." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Опис пакунку відсутній" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Перейменувати" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Видалити пакунок" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Викор. набір текстур" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Анонсувати сервер" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Закріпити адресу" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Творчий режим" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Дозволити пошкодження" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Грати (сервер)" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Сервер" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Встановити ігри з ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Новий" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Світ не створено або не обрано!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Грати гру" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Порт" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Виберіть моди" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Виберіть світ:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Порт сервера" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Почати гру" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Адреса" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Очистити" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Творчий режим" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Пошкодження / ГпГ" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Відібрані" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Несумісні сервери" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Долучитися до гри" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Пінґ" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Публічні сервери" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Оновити" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "Видалити улюблений" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Опис сервера" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D хмари" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Усі налаштування" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Згладжування:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Зберігати розмір вікна" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Дволінійне фільтрування" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Змінити клавіші" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Зʼєднане скло" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Динамічні тіні" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "Динамічні тіні:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Гарне листя" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Міпмапи" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Міпмапи і анізотропний фільтр" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Без фільтрування" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Без міпмап" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "Підсвічувати блок" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "Виділяти блок рамкою" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Нічого" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Непрозоре листя" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Непрозора вода" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Часточки" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Екран:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Налаштування" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Відтінювачі" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Відтінювачі (експериментальне)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Відтінювачі (недоступно)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Просте листя" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Згладжене освітлення" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Текстурування:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Тоновий шейдер" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "Чутливість дотику (пкс):" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Трилінійна фільтрація" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Коливати листя" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Хвилясті Рідини" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Коливати квіти" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "Зʼєднання зупинено (помилка протоколу?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Час очікування вийшов." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Готово!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "Ініціалізування блоків" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "Ініціалізування блоків..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Завантаження текстур..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Перебудова шейдерів..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Помилка зʼєднання (час вийшов?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Неможливо знайти або завантажити гру: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "Помилкова конфігурація gamespec." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Основне меню" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "Жоден світ не вибрано та не надано адреси. Немає чого робити." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Імʼя гравця задовге." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Будь-ласка, оберіть імʼя!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Не вдалося відкрити файл паролю: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Вказаний шлях до світу не існує: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Подробиці у файлі debug.txt." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Адреса: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Режим: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Порт: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Публічний: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- ГпГ (бої): " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Назва сервера: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Трапилася помилка серіалізації:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Доступ відхилено. Причина: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Автоматичний рух вперед вимкнено" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Автоматичний рух вперед увімкнено" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Оновлення камери вимкнено" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Оновлення камери увімкнено" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Змінити пароль" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Кінорежим вимкнено" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Кінорежим увімкнено" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Клієнта відʼєднано" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "Клієнтосторонні скрипти на клієнті вимкнено" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Підключення до сервера..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Невдале зʼєднання з невідомих причин" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Продовжити" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Керування:\n" +"- %s: рухатися вперед\n" +"- %s: рухатися назад\n" +"- %s: рухатися вліво\n" +"- %s: рухатися вправо\n" +"- %s: стрибок/лізти вгору\n" +"- %s: копати/удар\n" +"- %s: поставити/використати\n" +"- %s: крастися/лізти вниз\n" +"- %s: кинути предмет\n" +"- %s: інвентар\n" +"- Миша: поворот/дивитися\n" +"- Коліщатко миші: вибір предмета\n" +"- %s: чат\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Створення клієнта..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Створення сервера..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Інформація по швидкодії, налагодженню вимкнена" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Інформація для налагодження увімкнена" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Інформація по швидкодії, налагодженню і показ трикутників вимкнено" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Стандартне керування дотиком:\n" +"Коли меню не відображається:\n" +"- один дотик: активувати кнопку\n" +"- дотикнутися двічі: встановити/використати\n" +"- провести пальцем: роззирнутися\n" +"Коли відображається меню або інвертар:\n" +"- дотикнутися двічі (поза межами):\n" +" --> закрити\n" +"- Торкнутися купи, торкнутися комірки:\n" +" --> перемістити купу\n" +"- Торкнутися і тягнути, дотикнутися лругим пальцем\n" +" --> помістити один предмет у комірку\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Обмежена видимість" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Необмежена видимість (повільно)" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "Помилка створення клієнта: %s" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Вихід у меню" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Вихід із гри" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Швидкий рух вимкнено" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Швидкий рух увімкнено" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Швидкий рух увімкнено (немає дозволу \"fast\")" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Політ вимкнено" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Політ увімкнено" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Політ увімкнено (немає дозволу \"fly\")" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Туман вимкнено" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Туман увімкнено" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Інформація про гру:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Гра на паузі" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Сервер (хост)" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Визначення предметів..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "КіБ/сек" + +#: src/client/game.cpp +msgid "Media..." +msgstr "Ресурси..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "МіБ/сек" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Мінімапа вимкнена грою або модифікацією" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Багатокористувацька гра" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "Прохід крізь стіни вимкнено" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "Прохід крізь стіни увімкнено" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "Прохід крізь стіни увімкнено (немає дозволу \"noclip\")" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "Визначення блоків..." + +#: src/client/game.cpp +msgid "Off" +msgstr "Вимк." + +#: src/client/game.cpp +msgid "On" +msgstr "Увім." + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "Осьовий політ вимкнено" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "Осьовий політ увімкнено" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Інформація з швидкодії" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Віддалений сервер" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Отримання адреси..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Вимкнення..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Одиночна гра" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Гучність звуку" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Звук вимкнено" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Звукова система вимкнена" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Звукова система не підтримується у цій збірці" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Звук увімкнено" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Видимість змінено до %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Видимість на максимумі: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Видимість на мінімумі: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Гучність звуку змінено на %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Показ трикутників" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Наближення (бінокль) вимкнено грою або модифікацією" + +#: src/client/game.cpp +msgid "ok" +msgstr "добре" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Чат сховано" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Чат показано" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD приховано" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD показано" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Інформація по швидкодії вимкнена" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Інформація по швидкодії (сторінка %d з %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Додатки" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Ctrl" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Вниз" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Стерти EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Виконати" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Довідка" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME Прийняти" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME Конвертувати" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME Esc" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME Змінити режим" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME Не обернено" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Ліворуч" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Ліва кнопка" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Лівий Ctrl" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Лівий Menu" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Лівий Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Лівий Win" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Меню" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Середня кнопка" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "Num *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "Num +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "Num -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "Num ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "Num /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "Num 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "Num 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "Num 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "Num 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "Num 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "Num 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "Num 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "Num 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "Num 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "Num 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "Очистити OEM" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Сторінка вниз" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Сторінка вгору" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Пауза" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Грати" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Print Screen" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Ввід" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Праворуч" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Права кнопка" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Правий Ctrl" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Правий Menu" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Правий Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Правий Win" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "Вибрати" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Сон" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Зріз" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Пробіл" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Вгору" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Додаткова кнопка 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Додаткова кнопка 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Збільшити" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Мінімапа вимкнена" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Мінімапа в режимі радара. Наближення x%d" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Мінімапа в режимі поверхні. Наближення x%d" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Мінімапа в текстурному режимі" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Не вдалося завантажити вебсторінку" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Відкривання вебсторінки" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Далі" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = лізти вниз" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Автохід" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Автоматичне перестрибування" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Назад" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Змінити камеру" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Чат" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Команда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "Консоль" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Зменш. видимість" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Зменшити звук" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Подвійний стрибок вмикає політ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Викинути" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Вперед" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Збільш. видимість" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Збільшити звук" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Інвентар" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Стрибок" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Клавіша вже використовується" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Локальна команда" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Вимкнути звук" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Наступний предмет" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Попередній предмет" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Вибір діапазону" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Знімок екрана" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Крастися" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Увімкнути HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Увімкнути журнал чату" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Прискорення" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Політ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Увімкнути туман" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Увімкнути мінімапу" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "Прохід крізь стіни" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "Увімкнути висотний рух" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "натисніть клавішу" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Змінити" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Новий пароль" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Старий пароль" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Паролі не збігаються!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Вихід" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Звук вимкнено" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Гучність звуку: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "uk" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "Будь-ласка оберіть інше імʼя!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Закріплює позицію віртуального джойстика.\n" +"Якщо вимкнено, віртуальний джойстик буде відцентровано до першого місця " +"дотику." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Використовувати віртуальний джойстик для активації кнопки " +"\"Aux1\".\n" +"Якщо ввімкнено, віртуальний джойстик також натисне \"Aux1\", коли поза " +"межами головного кола." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"(X,Y,Z) зміщення фракталу від центру світа у одиницях 'масшабу'. \n" +"Використовується для пересування бажаної точки до (0, 0) щоб \n" +"створити придатну точку переродження або для 'наближення' \n" +"до бажаної точки шляхом збільшення 'масштабу'. Значення за \n" +"замовчанням налаштоване для придатної точки переродження \n" +"для множин Мандельбро з параметрами за замовчанням; може \n" +"потребувати зміни у інших ситуаціях. Діапазон приблизно від -2 \n" +"до 2. Помножте на 'масштаб' щоб отримати зміщення у блоках." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"(X,Y,Z) масштаб фракталу у блоках.\n" +"Фактичний розмір фракталу буде у 2-3 рази більшим. Ці \n" +"числа можуть бути дуже великими, фрактал не обов'язково \n" +"має поміститися у світі. Збільшіть їх щоб 'наблизити' деталі \n" +"фракталу. Числа за замовчанням підходять для вертикально \n" +"стисненої форми, придатної для острова, встановіть усі три \n" +"числа рівними для форми без трансформації." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "2D шум що контролює форму/розмір гребенів гір." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "2D шум що контролює форму/розмір невисоких пагорбів." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "2D шум що контролює форму/розмір ступінчастих гір." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "2D шум що контролює розмір/імовірність гребенів гірських масивів." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "2D шум що контролює розмір/імовірність невисоких пагорбів." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "2D шум що контролює розмір/імовірність ступінчастих гір." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "2D шум що розміщує долини та русла річок." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Обʼємні хмари" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D режим" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Величина паралаксу у 3D режимі" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "3D шум що визначає гігантські каверни." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"3D шум що визначає структуру та висоті гір. \n" +"Також визначає структуру висячих островів." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"3D шум що визначає структуру висячих островів.\n" +"Якщо змінити значення за замовчаням, 'масштаб' шуму (0.7 за замовчанням)\n" +"може потребувати корекції, оскільки функція конічної транформації висячих\n" +"островів має діапазон значень приблизно від -2.0 до 2.0." + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "3D шум що визначає структуру стін каньйонів річок." + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "3D шум що визначає місцевість." + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "3D шум для виступів гір, скель та ін. Зазвичай невеликі варіації." + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "3D шум що визначає кількість підземель на фрагмент карти." + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"Підтримка 3D.\n" +"Зараз підтримуються:\n" +"- none: 3d вимкнено.\n" +"- anaglyph: 3d з блакитно-пурпурними кольорами.\n" +"- interlaced: підтримка полярізаційних екранів з непарними/парним " +"лініями.\n" +"- topbottom: поділ екрану вертикально.\n" +"- sidebyside: поділ екрану горизонтально.\n" +"- crossview: 3d на основі автостереограми.\n" +"- pageflip: 3d на основі quadbuffer.\n" +"Зверніть увагу що режим interlaced потребує ввімкнення шейдерів." + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Вибране зерно карти для нової карти, залиште порожнім для випадково " +"вибраного числа.\n" +"Буде проігноровано якщо новий світ створюється з головного меню." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Повідомлення що показується усім клієнтам якщо сервер зазнає збою." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Повідомлення що показується усім клієнтам при вимкненні серверу." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "Інтервал ABM" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Абсолютний ліміт відображення блоків з черги" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Прискорення в повітрі" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "Прискорення гравітації, у блоках на секунду у квадраті." + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "Модифікатори активних блоків" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "Інтервал керування активним блоком" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "Діапазон активних блоків" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "Діапазон відправлення активних блоків" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"Адреса для приєднання.\n" +"Залиште порожнім щоб запустити локальний сервер.\n" +"Зауважте що поле адреси у головному меню має пріоритет над цим налаштуванням." + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "Додавати часточки при копанні блока." + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Налаштувати dpi на вашому екрані (тільки не X11/Android), напр. для 4k-" +"екранів." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"Налаштувати щільність плавучого шару.\n" +"Збільшуйте значення, щоб збільшити щільність. Може бути позитивним або " +"негативним.\n" +"Значення = 0.0: 50% від обсягу плавучого острова.\n" +"Значення = 2.0 (можна збільшувати залежно від 'mgv7_np_floatland', завжди " +"перевіряйте,\n" +"щоб бути певними) створює твердий шар плавучої землі." + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "Ім'я адміністратора" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Додатково" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"Змінює криву світла застосовуючи до неї 'гамма-корекцію'.\n" +"Більше значення робить середній і нижчий рівень яскравості освітлення.\n" +"Значення '1.0' залишає криву світла незмінною.\n" +"Це впливає лише на денне і штучне світло,\n" +"воно мало впливає на природне нічне світло." + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "Завжди літати швидко" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "К-сть повідомлень, які гравець може надіслати протягом 10 секунд." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Анізотропна фільтрація" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Публічний сервер" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Анонсувати сервер в цей перелік серверів." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "Додавати назви предметів" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "Додавати назви предметів до підказок." + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Шум яблунь" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Інерція руки" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Інерція руки забезпечує реалістичніші рухи\n" +"під час руху камери." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Запитувати про перезʼєднання під час збою" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Клавіша автоматичного руху вперед" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "Автоматично стрибати на блок вище." + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Автоматично звітувати у список серверів." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Зберігати розмір вікна" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Режим автомасштабування" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Клавіша Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Клавіша Aux1 для піднімання/спуску" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Клавіша Назад" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "Базовий рівень землі" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Висота основної поверхні." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Стандартні права" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Шум пляжу" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "Поріг пляжного шуму" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Білінійна фільтрація" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Закріплення адреси" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Шум біому" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Шлях до жирного і курсивного шрифту" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "Шлях до жирного і курсивного моноширного шрифту" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Шлях до жирного шрифту" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "Шлях до жирного моноширного шрифту" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "Будувати в межах гравця" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "Камера" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Згладжування руху камери" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Згладжування руху камери у кінорежимі" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Контроль оновлення камери" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Шум печери" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Шум печери #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Шум печери #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Ширина печери" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Шум для Печера1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Шум для Печера2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "Обмеження каверни" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "Шум каверни" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "Верхнє обмеження каверни" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Команди чату" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "Розмір шрифту чату" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Клавіша чату" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "Рівень журналу чату" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "Обмеження к-сті повідомлень чату" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Формат повідомлень чату" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Максимальна довжина повідомлення чату" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Клавіша увімкнення чату" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "Вебпосилання чату" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Кінорежим" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Клавіша кінорежиму" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Клієнт" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Клієнт і сервер" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "Клієнт-моди" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "Обмеження можливостей клієнт-модифікацій" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "Клієнт-моди" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Радіус хмар" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Хмари" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Хмари в меню" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Кольоровий туман" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Кольорові тіні" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Клавіша команди" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "З'єднувати скло" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Підключення до зовнішнього медіасервера" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "Консоль (альфа)" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "Колір консолі" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "Висота консолі" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "Репозиторій додатків" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "URL ContentDB" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Керування" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Повідомлення збою" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Творчість" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Поранення" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Клавіша увімкнення даних налагодження" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "Рівень журналу зневадження" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Клавіша зменш. гучності" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "Стандартне прискорення" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Стандартна гра" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Стандартна гра, коли створюєте новий світ.\n" +"Буде перезаписана при створені світу з головного меню." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Стандартний пароль" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Стандартні права" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Типовий формат звіту" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "Типовий розмір стеку" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "Налаштування для розробників" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Клавіша Копати" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Часточки при копанні" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Вимкнути античіт" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Заборонити порожні паролі" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Доменне ім'я сервера, яке буде показуватися у списку серверів." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Подвійне натискання стрибка для польоту" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Подвійне натискання кнопки стрибка вмикає режим польоту." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Клавіша викидання предметів" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "Дозволити вікно консолі" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Дозволити режим творчості для всіх гравців" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Увімкнути джойстики" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Дозволити анімацію предметів інвентаря." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Вмикає мінімапу." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS, коли призупинено або поза фокусом" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "Шлях до резервного шрифту" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "Швидка клавіша" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "Швидкість швидкого режиму" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Швидкі рухи" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "Фільтрування і Згладжування:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "Клавіша польоту" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Політ" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "Туман" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "Клавіша ввімкнення туману" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "Шрифт" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "Типовий грубий шрифт" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "Типовий похилий шрифт" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "Тінь шрифту" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "Альфа-тінь шрифту" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "Розмір шрифту" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "Формат знімків екрана." + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "Клавіша Вперед" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "Повний екран" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "Повноекранний режим." + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "Масштаб інтерфейсу" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "Контролер" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Графіка" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "Графічні ефекти" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "Графіка та Аудіо" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "Гравітація" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP модифікації" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "Масштаб інтерфейсу" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "Клавіша ввімкнення HUD" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "Висотний шум" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "Клавіша слоту 1 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "Клавіша слоту 10 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "Клавіша слоту 11 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "Клавіша слоту 12 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "Клавіша слоту 13 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "Клавіша слоту 14 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "Клавіша слоту 15 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "Клавіша слоту 16 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "Клавіша слоту 17 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "Клавіша слоту 18 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "Клавіша слоту 19 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "Клавіша слоту 2 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "Клавіша слоту 20 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "Клавіша слоту 21 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "Клавіша слоту 22 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "Клавіша слоту 23 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "Клавіша слоту 24 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "Клавіша слоту 25 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "Клавіша слоту 26 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "Клавіша слоту 27 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "Клавіша слоту 28 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "Клавіша слоту 29 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "Клавіша слоту 3 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "Клавіша слоту 30 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "Клавіша слоту 31 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "Клавіша слоту 32 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "Клавіша слоту 4 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "Клавіша слоту 5 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "Клавіша слоту 6 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "Клавіша слоту 7 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "Клавіша слоту 8 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "Клавіша слоту 9 швидкої панелі" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "Як глибоко робити ріки." + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "Як широко робити ріки." + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "Сервер IPv6" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "Ігнорувати помилки світу" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Клавіша збільш. гучності" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "Анімація предметів інвентаря" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "Клавіша інвентаря" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Інвертувати мишку" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "Інвертувати вертикальні рухи мишки." + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "Шлях до похилого шрифту" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "Шлях до похилого моноширного шрифту" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "Ітерації" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "ІД джойстика" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "Тип джойстика" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "Клавіша Стрибок" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "Швидкість стрибання" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для зменшення видимості.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для зменшення гучності.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для копання.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для кидання поточного предмета.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для збільшення видимості.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для збільшення гучності.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для стрибання.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для швидкого руху у швидкому режимі.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для руху гравця вперед.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для руху гравця вліво.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для руху гравця вправо.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для приглушення гри.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для відкривання вікна чату для введення команд.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для відкривання вікна чату для набирання локальних команд.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для відкривання вікна чату.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для відкривання інвентаря.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша покласти.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для вибору 11-го слоту швидкої панелі.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для вибору 12-го слоту швидкої панелі.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для вибору 13-го слоту швидкої панелі.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для вибору 14-го слоту швидкої панелі.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для вибору 15-го слоту швидкої панелі.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для вибору 16-го слоту швидкої панелі.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для вибору 17-го слоту швидкої панелі.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для вибору 18-го слоту швидкої панелі.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для вибору 19-го слоту швидкої панелі.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша для вибору 20-го слоту швидкої панелі.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"Клавіша ввімкнення відображення HUD.\n" +"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "Мова" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "Глибина великих печер" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "Консоль (повна)" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "Стиль листя" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "Ліва клавіша" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "Освітлення" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "Скрипт основного меню" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "Каталог мапи" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "Межі генерації мапи" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "Інтервал збереження мапи" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "Генератор світу: рівний" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "Генератор світу: фрактальний" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "Мітки для фрактального ґенератора світу" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "Генератор світу: V5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "Генератор світу: V6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "Генератор світу: V7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Налагодження ґенератора світу" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Назва ґенератора світу" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "Максимальна відстань генерації блоків" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "Найбільша кількість рідини на крок." + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "Найбільша кількість пакетів на ітерацію" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "Найбільша кількість FPS" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "Найбільша кількість FPS, коли вікно поза фокусом або гру призупинено." + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "Найбільша кількість обʼєктів на блок" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "Найбільше користувачів" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "Повідомлення дня" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "Мінімапа" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "Клавіша мінімапи" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mіп-текстурування" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "Безпека модів" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "Змінює розмір елементів HUD." + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "Шлях до моноширного шрифту" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "Розмір моноширного шрифту" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "Вимкнути звук" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "Заглушити звук" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "Мережа" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "Прохід крізь стіни" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "Клавіша проходу крізь стіни" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "Підсвічування блоків і предметів" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "Шуми" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "Шлях до теки з текстурами. Всі текстури спочатку шукаються тут." + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "Фізика" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "Клавіша зміни висоти" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "Клавіша покласти" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "Гравець проти гравця" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "Фільтрування Пуасона" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "Вибір діапазону" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "Останні повідомлення чату" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "Шлях до звичайного шрифту" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "Віддалені ресурси" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "Віддалений порт" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "Шлях для звіту" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "Права клавіша" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "Глибина каналу річки" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "Глибина річки" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "Річковий шум" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "Розмір річки" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "Екран" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "Висота екрана" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "Ширина екрана" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "Тека для знімків екрана" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "Формат знімку" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "Якість знімку" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "Знімки екрана" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "Сервер" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "Геймплей Сервера" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "Безпека Сервера" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "Адреса сервера" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "Адреса сервера" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "Опис сервера" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "Назва сервера" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "Порт сервера" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Швидкість Сервера/Env" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "Адреса списку серверів" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "Список серверів і Повідомлення Дня" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "Файл списку серверів" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"Вказати мову. Залиште порожнім, щоб використовувати системну мову.\n" +"Потрібен перезапуск після цієї зміни." + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "Шлях до шейдерів" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "Якість фільтру тіні" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "Показати дані зневадження" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"Показати поле виділення обʼєктів\n" +"Після зміни потрібно перезапустити." + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "Вимкнути повідомлення" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "Згладжене освітлення" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "Крастися" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "Швидкість підкрадання" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "Радіус легких тіней" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "Звук" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "Тимчасові Налаштування" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "Висота рельєфу" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "Шлях до текстури" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "Мертва зона джойстика" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "Тип джойстика" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "Період надсилання часу" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "Швидкість часу" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "Межа чутливості дотику" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "Сенсорний екран" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "Шум дерев" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "Трилінійна фільтрація" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "Необмежена відстань передачі гравця" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "Верхня межа р підземель." + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "Видимість" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "Гучність" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"Гучність усіх звуків.\n" +"Вимагає увімкнення системи звуку." + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "Швидкість ходьби і польоту, в блоках за секунду." + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "Швидкість ходьби" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "Рівень води" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "Коливання блоків" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "Коливання листя" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "Хвилясті рідини" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "Висота хвилі хвилястих рідин" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "Швидкість хвилі хвилястих рідин" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "Довжина хвилі хвилястих рідин" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "Коливання рослин" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "Колір вебпосилання" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Початковий час гри" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "Y-Рівень нижнього рельєфу та морського дна." + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "Y-Рівень морського дна." + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Творчість: " + +#~ msgid "- Damage: " +#~ msgstr "- Ушкодження: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = технологія \"parallax occlusion\" з інформацією про криві (швидше).\n" +#~ "1 = технологія \"relief mapping\" (повільніше, більш акуратніше)." + +#~ msgid "Address / Port" +#~ msgstr "Адреса / Порт" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "Ви впевнені, що бажаєте скинути свій світ одиночної гри?" + +#~ msgid "Back" +#~ msgstr "Назад" + +#~ msgid "Basic" +#~ msgstr "Основи" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "Бітів на піксель (глибина кольору) в повноекранному режимі." + +#~ msgid "Bump Mapping" +#~ msgstr "Бамп-маппінг" + +#~ msgid "Bumpmapping" +#~ msgstr "Бамп-маппінг" + +#~ msgid "Config mods" +#~ msgstr "Налаштувати модифікації" + +#~ msgid "Configure" +#~ msgstr "Налаштувати" + +#~ msgid "Connect" +#~ msgstr "Зʼєднатися" + +#~ msgid "Content Store" +#~ msgstr "Додатки" + +#~ msgid "Credits" +#~ msgstr "Подяки" + +#~ msgid "Damage enabled" +#~ msgstr "Ушкодження ввімкнено" + +#~ msgid "Del. Favorite" +#~ msgstr "Видалити зі закладок" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "Завантажте гру, наприклад, Minetest Game з minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Завантажте з minetest.net" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "Завантаження і встановлення $1, зачекайте..." + +#~ msgid "Enable VBO" +#~ msgstr "Увімкнути VBO" + +#~ msgid "Enter " +#~ msgstr "Ввід " + +#~ msgid "Filtering" +#~ msgstr "Фільтрація" + +#~ msgid "Game" +#~ msgstr "Гра" + +#~ msgid "Generate Normal Maps" +#~ msgstr "Генерувати мапи нормалів" + +#~ msgid "Generate normalmaps" +#~ msgstr "Генерувати карти нормалів" + +#~ msgid "IPv6 support." +#~ msgstr "Підтримка IPv6." + +#~ msgid "In-Game" +#~ msgstr "У грі" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "Встановлення: файл: \"$1\"" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "" +#~ "Комбінації клавіш. (Якщо це меню зламалося, видаліть налаштування з " +#~ "minetest.conf)" + +#~ msgid "Lava depth" +#~ msgstr "Глибина лави" + +#~ msgid "Main" +#~ msgstr "Головне Меню" + +#~ msgid "Main menu style" +#~ msgstr "Стиль головного меню" + +#~ msgid "Menus" +#~ msgstr "Меню" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "Мінімапа в режимі радар. Наближення х2" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "Мінімапа в режимі радар. Наближення х4" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "Мінімапа в режимі поверхня. Наближення х2" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "Мінімапа в режимі поверхня. Наближення х4" + +#~ msgid "Name / Password" +#~ msgstr "Ім'я / Пароль" + +#~ msgid "Name/Password" +#~ msgstr "Ім'я/Пароль" + +#~ msgid "No" +#~ msgstr "Ні" + +#~ msgid "Ok" +#~ msgstr "Добре" + +#~ msgid "Parallax Occlusion" +#~ msgstr "Паралаксова оклюзія" + +#~ msgid "Parallax occlusion" +#~ msgstr "Паралаксова оклюзія" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "Ступінь паралаксової оклюзії" + +#~ msgid "Player name" +#~ msgstr "Імʼя гравця" + +#~ msgid "PvP enabled" +#~ msgstr "Бої увімкнено" + +#~ msgid "Reset singleplayer world" +#~ msgstr "Скинути світ одиночної гри" + +#~ msgid "Select Package File:" +#~ msgstr "Виберіть файл пакунку:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "Сервер / Одиночна гра" + +#~ msgid "Special" +#~ msgstr "Спеціальна" + +#~ msgid "Special key" +#~ msgstr "Спеціальна клавіша" + +#~ msgid "Start Singleplayer" +#~ msgstr "Почати одиночну гру" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "Для того, щоб увімкнути шейдери, потрібно мати драйвер OpenGL." + +#~ msgid "Toggle Cinematic" +#~ msgstr "Кінематографічний режим" + +#~ msgid "View" +#~ msgstr "Вид" + +#~ msgid "Yes" +#~ msgstr "Так" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "Ви збираєтеся вперше підключитися до сервера з іменем \"%s\". \n" +#~ "Якщо ви продовжите, буде створено новий ігровий профіль на даному сервері " +#~ "з вашим іменем/паролем.\n" +#~ "Будь-ласка введіть повторно ваш пароль і натисніть \"Зареєструватися і " +#~ "увійти\", або \"Скасувати\", якщо ви проти." + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Ви загинули" + +#~ msgid "needs_fallback_font" +#~ msgstr "no" diff --git a/po/vi/minetest.po b/po/vi/minetest.po new file mode 100644 index 0000000..aaaf891 --- /dev/null +++ b/po/vi/minetest.po @@ -0,0 +1,6983 @@ +msgid "" +msgstr "" +"Project-Id-Version: Vietnamese (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-07-31 17:28+0000\n" +"Last-Translator: Hùng Nguyễn <www.thuphan@gmail.com>\n" +"Language-Team: Vietnamese <https://hosted.weblate.org/projects/minetest/" +"minetest/vi/>\n" +"Language: vi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.14-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "Xóa hàng đợi trò chuyện" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "Lệnh trống." + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "Thoát ra màn hình chính" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "Lệnh không hợp lệ: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "Lệnh đã dùng: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "Liệt kê người chơi đang trực tuyến" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "Người chơi đang trực tuyến: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "Hàng đợi trò chuyện đã trống." + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "Lệnh này đã bị cấm bởi máy chủ." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "Hồi sinh" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "Bạn đã bị chết" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "Lệnh có sẵn:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "Lệnh có sẵn: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "Lệnh không có sẵn: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "Trợ giúp về lệnh" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"Dùng '.help <câu lệnh>' để có thêm thông tin về một câu lệnh hoặc dùng '." +"help all' để xem danh sách về những câu lệnh có sẵn." + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <câu lệnh>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<không có sẵn>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Một lỗi đã xảy ra trong tập lệnh Lua:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "Đã xảy ra lỗi:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "Màn hình chính" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "Kết nối lại" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "Máy chủ đã yêu cầu kết nối lại:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "Phiên bản mới $1 hiện có sẵn" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "Mod đã chọn" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" +"Phiên bản đã cài đặt: $1\n" +"Phiên bản mới: $2\n" +"Truy cập $3 để biết cách tải phiên bản mới nhất với các tính năng mới và bản " +"sửa lỗi." + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "Để sau" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "Không bao giờ" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "Phiên bản giao thức không khớp. " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "Máy chủ thực thi phiên bản giao thức $1. " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "Máy chủ hỗ trợ các phiên bản giao thức trong khoảng từ $1 đến $2. " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "Truy cập website" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "Chúng tôi chỉ hỗ trợ phiên bản giao thức $1." + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "Chúng tôi hỗ trợ các phiên bản giao thức giữa phiên bản $1 đến $2." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "(Đã kích hoạt, có lỗi)" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "Hủy bỏ" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "Phụ thuộc:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "Vô hiệu hóa tất cả" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "Vô hiệu hóa modpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "Kích hoạt tất cả" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "Kích hoạt modpack" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" +"Không thể kích hoạt mod \"$1\" vì chứa các ký tự không được phép. Các ký tự " +"được phép bao gồm chữ cái Latin, chữ số và ký tự \"_\"." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "Tìm thêm mod" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "Không có phần phụ thuộc (tùy chọn) nào" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "Không có mô tả trò chơi được cung cấp." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "Không có phần phụ thuộc bắt buộc nào" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "Không có mô tả modpack được cung cấp." + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "Không có phần phụ thuộc tùy chọn nào" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "Phần phụ thuộc tùy chọn:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "Lưu" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "Thế giới:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "đã kích hoạt" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\" đã tồn tại. Bạn có muốn ghi đè nó không?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "Phần phụ thuộc $1 và $2 sẽ được cài đặt." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 đang tải xuống,\n" +"$2 đã thêm vào hàng chờ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "Đang tải xuống $1..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "Không tìm thấy phần phụ thuộc cần cho $1." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 sẽ được cài đặt, phần phụ thuộc $2 sẽ bị bỏ qua." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "Tất cả các gói" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "Đã được cài đặt" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "Trở về màn hình chính" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "Trò chơi cơ bản:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "ContentDB không có sẵn khi Minetest được biên dịch mà không có cURL" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "Đang tải xuống..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "Đã xảy ra lỗi khi tải xuống $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "Trò chơi" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "Cài đặt" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "Cài đặt $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "Cài đặt phần phụ thuộc bị thiếu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "Cài đặt: Loại tệp không được hỗ trợ hoặc tệp lưu trữ bị hỏng" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mod" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "Không nhận được gói nào" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "Không có kết quả" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "Không có cập nhật mới" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "Không tìm thấy" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "Ghi đè" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "Vui lòng kiểm tra xem trò chơi này có đúng không." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "Đã thêm vào hàng chờ" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "Gói kết cấu" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "Gỡ cài đặt" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "Cập nhật" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "Cập nhật tất cả [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "Xem thêm thông tin trên trình duyệt web của bạn" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "Thế giới với tên \"$1\" đã tồn tại" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "Địa hình bổ sung" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "Độ cao lạnh" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "Độ cao khô ráo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "Pha trộn quần xã" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "Quần xã" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "Hang động lớn" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "Hang động" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "Tạo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "Vật trang trí" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "Cảnh báo: Kiểm tra Phát triển chỉ dành cho các nhà phát triển." + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "Ngục tối" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "Địa hình phẳng" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "Vùng đất lơ lửng trên trời" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "Vùng đất lơ lửng (thử nghiệm)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "Tạo địa hình không phân dạng: Đại dương và lòng đất" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "Đồi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "Sông ẩm ướt" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "Tăng độ ẩm xung quanh sông" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "Cài đặt một trò chơi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "Cài đặt một trò chơi khác" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "Hồ nước" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "Độ ẩm thấp và nhiệt độ cao làm cho sông cạn hoặc khô" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "Thế hệ bản đồ" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen flags" +msgstr "Cờ của Mapgen" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Mapgen-specific flags" +msgstr "Cờ cụ thể của Mapgen" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "Núi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "Suối bùn" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "Mạng lưới đường hầm và hang động" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "Không có trò chơi nào được chọn" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "Giảm nhiệt theo độ cao" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "Giảm độ ẩm theo độ cao" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "Sông" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "Sông theo mực nước biển" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "Mã khởi tạo" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "Chuyển đổi mượt mà giữa các quần xã" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" +"Các cấu trúc xuất hiện trên địa hình (không ảnh hưởng đến cây cối, cỏ rừng " +"và được tạo bởi v6)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "Các cấu trúc xuất hiện trên địa hình, điển hình là cây cối và thực vật" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "Ôn đới, sa mạc" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "Ôn đới, sa mạc, rừng rậm" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "Ôn đới, sa mạc, rừng rậm, đồng cỏ, rừng taiga" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "Xói mòn bề mặt địa hình" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "Cây và cỏ rừng" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "Độ sâu sông thay đổi" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "Các hang động lớn nằm sâu trong lòng đất" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "Tên thế giới" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "Bạn chưa cài đặt trò chơi nào." + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "Bạn có chắc chắn muốn xóa \"$1\" không?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "Xóa" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr: đã xảy ra lỗi khi xóa \"$1\"" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr: đường dẫn \"$1\" không hợp lệ" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "Xóa thế giới \"$1\"?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "Xác nhận mật khẩu" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "Đang tham gia $1" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "Thiếu tên" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "Tên" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "Mật khẩu" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "Mật khẩu không khớp" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "Đăng kí" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "Chấp nhận" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "Đổi tên mod:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"Modpack này có một tên rõ ràng được đưa ra trong tệp modpack.conf của nó, " +"tên này sẽ ghi đè bất kỳ sự đổi tên nào ở đây." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(Không có mô tả về Cài đặt nào được đưa ra)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "Nhiễu 2D" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< Về trang Cài đặt" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "Duyệt" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "Nội dung: Trò chơi" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "Nội dung: Mod" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "Đã vô hiệu" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "Chỉnh sửa" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "Đã kích hoạt" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "Khoảng cách" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "Quãng tám" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +#, fuzzy +msgid "Offset" +msgstr "Độ bù" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "Sự bền bỉ" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "Vui lòng nhập một số nguyên hợp lệ." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "Vui lòng nhập một số hợp lệ." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "Phục hồi Cài đặt mặc định" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "Tỉ lệ" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "Tìm kiếm" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "Chọn thư mục" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "Chọn tệp" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "Hiển thị tên kỹ thuật" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "Giá trị ít nhất phải là $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "Giá trị không được lớn hơn $1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "Giá trị tuyệt đối" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "Mặc định" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "Nới lỏng" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 (đã kích hoạt)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mod" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "Đã xảy ra lỗi khi cài đặt $1 đến $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "Cài đặt mod: Không thể tìm thấy tên mod thật cho: $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "Cài đặt mod: Không thể tìm thấy tên thư mục phù hợp cho modpack $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "Không thể tìm thấy một mod hoặc modpack hợp lệ" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "Không thể cài đặt $1 dưới dạng gói kết cấu" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "Không thể cài đặt trò chơi dưới dạng $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "Không thể cài đặt mod dưới dạng $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "Không thể cài đặt modpack dưới dạng $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "Đang tải..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "Danh sách máy chủ công cộng đã bị vô hiệu" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" +"Hãy thử kích hoạt lại danh sách máy chủ công cộng và kiểm tra kết nối mạng " +"của bạn." + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "Giới thiệu" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "Những người đóng góp tích cực" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "Trình kết xuất hiện hoạt:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "Các nhà phát triển cốt lõi" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "Mở thư mục Dữ liệu người dùng" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"Mở thư mục chứa thế giới, trò chơi, bản mod do người dùng cung cấp\n" +"và các gói kết cấu trong trình quản lý tệp." + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "Những người đóng góp trước đây" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "Các nhà phát triển cốt lõi trước đây" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "Chia sẻ nhật kí gỡ lỗi" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "Duyệt nội dung trực tuyến" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "Nội dung" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "Vô hiệu gói kết cấu" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "Thông tin:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "Các gói đã cài đặt:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "Không có phần phụ thuộc nào." + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "Không có mô tả gói" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "Đổi tên" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "Gỡ cài đặt gói" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "Dùng gói kết cấu này" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "Thông báo máy chủ" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "Địa chỉ bắt buộc" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "Chế độ sáng tạo" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "Kích hoạt sát thương" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "Lưu trữ trò chơi" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "Lưu trữ máy chủ" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "Cài đặt trò chơi từ ContentDB" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "Mới" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "Không có thế giới nào được tạo hoặc được chọn." + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "Chơi trò chơi" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "Cổng" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "Chọn Mod" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "Chọn thế giới:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "Cổng máy chủ" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "Bắt đầu trò chơi" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "Địa chỉ" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Xóa" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "Chế độ sáng tạo" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "Sát thương / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "Yêu thích" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "Máy chủ không tương thích" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "Tham gia trò chơi" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "Đăng nhập" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "Máy chủ công cộng" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "Làm mới" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "Xóa yêu thích" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "Mô tả Máy chủ" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "Mây dạng 3D" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "Tất cả cài đặt" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "Khử răng cưa:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "Tự động lưu kích cỡ màn hình" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "Bộ lọc song tuyến" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "Thay đổi khóa" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "Kính kết nối với nhau" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "Bóng kiểu động lực học" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "Bóng kiểu động lực học:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "Lá đẹp" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "Cao" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "Thấp" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "Trung bình" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mipmap" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mipmap + Bộ lọc bất đẳng hướng" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "Không dùng bộ lọc" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "Không dùng Mipmap" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Node Highlighting" +msgstr "Đánh dấu node" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Node Outlining" +msgstr "Phác thảo node" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "Không" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "Lá đục" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "Nước đục" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "Hạt hiệu ứng" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "Màn hình:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "Cài đặt" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "Trình đổ bóng" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "Trình đổ bóng (thử nghiệm)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "Trình đổ bóng (không tồn tại)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "Lá đơn giản" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "Ánh sáng mịn" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "Kết cấu:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "Tông màu" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "Ngưỡng chạm (px):" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "Bộ lọc tam song" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "Cực cao" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "Cực thấp" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "Lá đung đưa" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "Sóng" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "Thực vật đung đưa" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "Lỗi kết nối (vấn đề với giao thức?)." + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "Hết thời gian chờ kết nối." + +#: src/client/client.cpp +msgid "Done!" +msgstr "Đã xong!" + +#: src/client/client.cpp +#, fuzzy +msgid "Initializing nodes" +msgstr "Đang khởi tạo các node" + +#: src/client/client.cpp +#, fuzzy +msgid "Initializing nodes..." +msgstr "Đang khởi tạo các node..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "Đang tải kết cấu..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "Đang xây dựng lại trình đổ bóng..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "Lỗi kết nối (hết thời gian chờ?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "Không tìm thấy hoặc tải trò chơi: " + +#: src/client/clientlauncher.cpp +#, fuzzy +msgid "Invalid gamespec." +msgstr "Gamespec không hợp lệ." + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "Màn hình chính" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" +"Không có thế giới nào được chọn và không có địa chỉ nào được cung cấp. Không " +"có gì để thực hiên." + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "Tên người chơi quá dài." + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "Vui lòng chọn một tên!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "Không mở được tệp mật khẩu được cung cấp: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "Đường dẫn thế giới được cung cấp không tồn tại: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"Hãy kiểm tra debug.txt để có thông tin chi tiết." + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- Địa chỉ: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- Chế độ: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- Cổng: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- Công cộng: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- Tên máy chủ: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "Đã xảy ra lỗi tuần tự hóa:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "Quyền truy cập bị từ chối với lý do: %s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "Tự động chuyển tiếp bị tắt" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "Tự động chuyển tiếp đã bật" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "Các ranh giới khối đã ẩn" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "Đã hiển thị ranh giới cho tất cả các khối" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "Đã hiển thị ranh giới hiển thị cho khối hiện tại" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "Đã hiển thị ranh giới cho các khối gần bạn" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "Cập nhật máy ảnh đã tắt" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "Cập nhật máy ảnh đã bật" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "Không thể hiển thị ranh giới khối (bị tắt bởi mod hoặc trò chơi)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "Đổi mật khẩu" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "Chế độ điện ảnh đã tắt" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "Chế độ điện ảnh đã bật" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "Máy khách đã ngắt kết nối" + +#: src/client/game.cpp +#, fuzzy +msgid "Client side scripting is disabled" +msgstr "Chạy kịch bản phía máy khách đã tắt" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "Đang kết nối tới máy chủ..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "Kết nối không thành công vì lý do không xác định" + +#: src/client/game.cpp +msgid "Continue" +msgstr "Tiếp tục" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"Điền khiển:\n" +"- %s: tiến lên\n" +"- %s: lùi xuống\n" +"- %s: sang trái\n" +"- %s: sang phải\n" +"- %s: nhảy / leo lên\n" +"- %s: đào / đấm\n" +"- %s: đặt khối / sử dụng\n" +"- %s: đi rón rén / leo xuống\n" +"- %s: thả vật phẩm\n" +"- %s: túi đồ\n" +"- Di chuột: xoay / nhìn\n" +"- Lăn chuột: chọn vật phẩm\n" +"- %s: trò chuyện\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "Không thể giải mã địa chỉ: %s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "Đang tạo máy khách..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "Đang tạo máy chủ..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "Thông tin gỡ lỗi và biểu đồ hồ sơ đã ẩn" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "Thông tin gỡ lỗi đã hiển thị" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "Thông tin gỡ lỗi, biểu đồ hồ sơ và khung dây đã ẩn" + +#: src/client/game.cpp +#, fuzzy +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"Điều khiển mặc định:\n" +"Khi menu không hiển thị:\n" +"- một lần nhấn: nút kích hoạt\n" +"- nhấn đúp: đặt khối / sử dụng\n" +"- trượt ngón tay: nhìn xung quanh\n" +"Khi Menu / Túi đồ hiển thị:\n" +"- nhấn đúp (bên ngoài):\n" +" -> đóng\n" +"- chạm ngăn xếp, chạm ô:\n" +" -> di chuyển ngăn xếp\n" +"- chạm và kéo, chạm vào ngón tay thứ 2\n" +" -> đặt một mục duy nhất vào vị trí\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "Đã tắt phạm vi nhìn không giới hạn" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "Đã bật phạm vi nhìn không giới hạn" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "Đã xảy ra lỗi khi tạo máy khách: %s" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "Thoát ra màn hình chính" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "Thoát Minetest" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "Chế độ nhanh đã tắt" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "Chế độ nhanh đã bật" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "Chế độ nhanh đã bật (ghi chú: không có ưu tiên cho 'nhanh')" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "Chế độ bay đã tắt" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "Chế độ bay đã bật" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "Chế độ bay đã bật (ghi chú: không có ưu tiên cho 'bay')" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "Sương mù đã tắt" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "Sương mù đã bật" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "Thông tin trò chơi:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "Trò chơi đã được tạm dừng" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "Đang tải máy chủ" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "Định nghĩa vật phẩm..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "Minimap đã bị vô hiệu bởi trò chơi hoặc mod" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "Chơi mạng" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "Tắt" + +#: src/client/game.cpp +msgid "On" +msgstr "Bật" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "Biểu đồ hồ sơ đã hiện" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "Máy chủ từ xa" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "Đang giải mã địa chỉ..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "Đang thoát..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "Chơi đơn" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "Âm lượng" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "Đã tắt tiếng" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "Hệ thống âm thanh đã bị vô hiệu" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "Hệ thống âm thanh không được hỗ trợ trong bản dựng này" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "Đã bật tiếng" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "Có vẻ như máy chủ đang chạy một phiên bản khác của %s." + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "Không thể kết nối đến %s vì IPv6 đã bị vô hiệu" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "Phạm vi nhìn được đặt thành %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "Phạm vi nhìn đang ở mức tối đa: %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "Phạm vi nhìn đang ở mức tối thiểu: %d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "Âm lượng được đặt thành %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "Hiện khung dây" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "Thu phóng đã bị vô hiệu bởi trò chơi hoặc mod" + +#: src/client/game.cpp +msgid "ok" +msgstr "OK" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "Trò chuyện đã bị ẩn" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "Trò chuyện đã được hiển thị" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD đã bị ẩn" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD đã được hiển thị" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "Hồ sơ đã bị ẩn" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "Hồ sơ đã được hiển thị (trang thứ %d trên %d)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "Ứng dụng" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "Backspace" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "Caps Lock" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "Xuống" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "Xóa bỏ EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "Thực thi" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "Trợ giúp" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Trang chủ" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Chèn" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "Sang trái" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "Nút trái" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "Control trái" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "Menu trái" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "Shift trái" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "Windows trái" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "Menu" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "Nút giữa" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "Num Lock" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "* trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "+ trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "- trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr ". trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "/ trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "0 trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "1 trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "2 trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "3 trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "4 trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "5 trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "6 trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "7 trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "8 trên b.phím số" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "9 trên b.phím số" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "Play" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "Print Screen" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Return" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "Sang phải" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "Nút phải" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "Control phải" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "Menu phải" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "Shift phải" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "Windows phải" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "Ngủ" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "Ảnh chụp nhanh" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "Phím cách" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "Lên" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "Nút X 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "Nút X 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "Thu phóng" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "Ẩn Minimap" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "Minimap ở chế độ ra-đa, mức thu phóng %dx" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "Minimap ở chế độ mặt nền, mức thu phóng %dx" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "Minimap ở chế độ kết cấu" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "Đã xảy ra lỗi khi mở trang web" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "Đang mở trang web" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "Tiến hành" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = leo xuống" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "Tự động tiến" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "Tự động nhảy" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "Lùi xuống" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "Ranh giới khối" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "Thay đổi camera" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "Trò chuyện" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "Lệnh" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "Giảm phạm vi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "Giảm âm lượng" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "Nhấn đúp nút \"nhảy\" để chuyển đổi chế độ bay" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "Thả" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "Tiến lên" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "Tăng phạm vi" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "Tăng âm lượng" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "Túi đồ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "Nhảy" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "Phím đã được sử dụng" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "Liên kết phím." + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "Lệnh cục bộ" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "Tắt tiếng" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "Vật phẩm tiếp theo" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "Vật phẩm trước" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "Lựa chọn phạm vi" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "Chụp màn hình" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "Đi rón rén" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "Chuyển đổi HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "Chuyển đổi nhật kí trò chuyện" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "Chuyển đổi chạy nhanh" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "Chuyển đổi bay" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "Chuyển đổi sương mù" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "Chuyển đổi minimap" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "bấm phím" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "Thay đổi" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "Mật khẩu mới" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "Mật khẩu cũ" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "Mật khẩu không khớp!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "Thoát" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "Đã tắt tiếng" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "Âm lượng: %d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "vi" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" +"Tên chưa được đăng kí. Để tạo một tài khoản trên máy chủ này, hãy bấm \"Đăng " +"kí\"" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "Tên đã được sử dụng. Vui lòng chọn một tên khác" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) Sửa vị trí của joystick ảo.\n" +"Nếu vô hiệu, joystick ảo sẽ ở vị trị giữa của lần chạm đầu tiên." + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) Dùng joystick ảo để kích hoạt nút \"Aux1\".\n" +"Khi kích hoạt, joystick ảo cũng sẽ nhấn nút \"Aux1\" khi ra khỏi vòng tròn " +"chính." + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "Nhiễu 2D điều khiển hình dạng / kích thước của các sống núi." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "Nhiễu 2D điều khiển hình dạng / kích thước của các ngọn đồi." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "Nhiễu 2D điều khiển hình dạng / kích thước của các núi bậc thang." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" +"Nhiễu 2D điều khiển hình dạng / tần suất xuất hiện của các dãy sống núi." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "Nhiễu 2D điều khiển hình dạng / tần suất xuất hiện của các ngọn đồi." + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" +"Nhiễu 2D điều khiển hình dạng / tần suất xuất hiện của các dãy núi bậc thang." + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "Nhiễu 2D tạo vị trí cho các sông, thung lũng và kênh mương." + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "Mây dạng 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "Chế độ 3D" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "Cường độ thị sai của Chế độ 3D" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "Nhiễu 3D tạo ra các hang động lớn." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"Nhiễu 3D xác địch cấu trúc và độ cao của núi.\n" +"Nó cũng xác định cấu trúc của các địa hình đảo lơ lửng." + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "3D" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"Một mã được chọn để tạo một thế giới mới, để trống để tạo mã ngẫu nhiên.\n" +"Nó sẽ được ghi đè khi tạo một thế giới mới trong màn hình chính." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "Một tin nhắn được hiển thị ở các máy khách khi máy chủ gặp sự cố." + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "Một tin nhắn được hiển thị ở các máy khách khi máy chủ tắt." + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "Giới hạn tuyệt đối của các khối ở hàng chờ để xuất hiện" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "Tăng tốc trong không trung" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" +"Điều chỉnh cấu hình DPI cho màn hình của bạn (chỉ cho Android/không phải X11)" +", VD: cho màn hình 4K." + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" +"Điều chỉnh mật độ điểm ảnh đã phát hiện, sử dụng để thu phóng các yếu tố UI." + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "Tên quản trị viên" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "Nâng cao" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "Luôn bay nhanh" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "Số lượng tin nhắn của một người chơi có thể gửi trong 10 giây." + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "Khuếch đại các thung lũng." + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "Lọc bất đẳng hướng" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "Thông báo máy chủ" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "Thông báo đến danh sách máy chủ này." + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "Nhiễu cho các cây táo" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "Quán tính của cánh tay" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"Quán tính của cánh tay, mang lại chuyển động\n" +"chân thực hơn cho cánh tay khi máy ảnh di chuyển." + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "Hỏi để kết nối lại sau khi gặp sự cố" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "Âm thanh" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "Phím tự động tiến" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "Tự động báo cáo đến danh sách máy chủ." + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "Tự động lưu kích thước màn hình" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "Chế độ tự động thay đổi tỉ lệ" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Phím Aux1" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "Phím Aux1 cho việc leo lên/leo xuống" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "Phím lùi" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "Độ cao của địa hình cơ bản." + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "Các quyền cơ bản" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "Nhiễu cho biển" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "Lọc song tuyến" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "Liên kết địa chỉ" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "Nhiễu quần xã" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "Lay động" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "Đường dẫn đến phông đậm và nghiêng" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "Đường dẫn đến phông đậm" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "Được dựng sẵn" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "Máy ảnh" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "Máy ảnh mượt mà" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "Máy ảnh mượt mà trong chế độ điện ảnh" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "Nút chuyển đổi cập nhật máy ảnh" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "Nhiễu hang động" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "Nhiễu hang động #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "Nhiễu hang động #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "Độ rộng của hang" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "Nhiễu Hang 1" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "Nhiễu Hang 2" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "Lệnh trò chuyện" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "K.thước phông chữ tr.chuyện" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "Phím trò chuyện" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "Định dạng tin nhắn trò chuyện" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "Độ dài tin nhắn trò chuyện tối đa" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "Phím chuyển đổi trò chuyện" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "Kích thước đoạn khúc" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "Chế độ điện ảnh" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "Phím chế độ điện ảnh" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "Xóa các kết cấu trong suốt" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "Máy khách" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "Máy khách và máy chủ" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "Tốc độ leo" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "Bán kính mây" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "Mây" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "Mây là một hiệu ứng ở máy khách." + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "Mây trong menu" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "Sương mù có màu" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "Bóng có màu" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "Phím lệnh" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "Kính kết nối với nhau" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "Kết nối đến máy chủ phương tiện bên ngoài" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "Kho lưu trữ nội dung" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "Điều khiển" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"Điều chỉnh độ dài vòng lặp ngày/đêm.\n" +"Ví dụ:\n" +"72 = 20 phút, 360 = 4 phút, 1 = 24 giờ, 0 = day/night/whatever stays " +"unchanged." + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" +"Kiểm soát tốc độ chìm trong chất lỏng khi bạn đứng im. Trong khi đó,\n" +"giá trị âm sẽ làm bạn nổi lên." + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "Tin nhắn sự cố" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "Sáng tạo" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "Độ trong suốt của tâm" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "Màu tâm" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "Sát thương" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "Phím chuyển đổi thông tin gỡ lỗi" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "Gỡ lỗi" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "Phím giảm âm lượng" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "Trò chơi mặc định" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"Trò chơi mặc định khi tạo thế giới mới.\n" +"Nó sẽ bị ghi đè khi tạo một thế giới từ màn hình chính." + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "Mật khẩu mặc định" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "Quyền mặc định" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "Định dạng báo cáo mặc định" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" +"Mô tả của máy chú, để hiển thị khi người chơi tham gia hay trong danh sách " +"máy chủ." + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "Không đồng bộ hoạt ảnh khối" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "Tùy chọn nhà phát triển" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "Phím đào" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "Hạt hiệu ứng khi đào" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "Vô hiệu trình chống gian lận" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "Không cho phép mật khẩu trống" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "Tên miền của máy chủ, để hiển thị trong danh sách máy chủ." + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "Nhấn đúp nút nhảy để bay" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "Nhấn đúp phím nhảy để chuyển đổi chế độ bay." + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "Phím thả vật phẩm" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "Y lớn nhất của ngục tối" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "Y nhỏ nhất của ngục tối" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "Nhiễu ngục tối" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"Kích hoạt hỗ trợ IPv6 (cho cả máy khách và máy chủ).\n" +"Cần để việc kết nối IPv6 hoạt động." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"Kích hoạt hỗ trợ mod bằng Lua.\n" +"Đấy là tính năng thử nghiệm và API có thể sẽ thay đổi." + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "Kích hoạt chế độ sáng tạo cho tất cả người chơi" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "Kích hoạt joystick" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "Kích hoạt joystick. Cần khởi động lại để có hiệu lực" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "Kích hoạt bảo mật mod" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "Cho phép người chơi nhận sát thương và chết." + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "Kích hoạt dữ liệu nhập ngẫu nhiên (chỉ cho việc thử nghiệm)." + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "Kích hoạt đăng nhập / đăng kí riêng lẻ" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"Kích hoạt để ngăn các máy khách sử dụng phiên bản cũ kết nối. Các máy khách " +"\n" +"cũ hơn tương thích trong trường hợp chúng không gặp sự cố khi kết nối vàomáy " +"chủ mới,\n" +"tuy nhiên chúng có thể không hỗ trợ tất cả các tính năng mới như bạn mong " +"đợi." + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "Kích hoạt hoạt ảnh của các vật phẩm trong túi đồ." + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "Kích hoạt minimap." + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"Kích hoạt hệ thống âm thanh.\n" +"Nếu vô hiệu hóa, điều này sẽ tắt hoàn toàn tất cả âm thanh trong trò chơi\n" +"điều khiển âm thanh sẽ không có tác dụng.\n" +"Thay đổi cài đặt này sẽ cần khởi động lại." + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "Phương thức thực thể" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "FPS" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "FPS khi cửa sổ đang hiện hoạt hoặc tạm dừng" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "Đi nhanh" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "Bay" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "Trò chơi" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "Đồ họa" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "Phím tăng âm lượng" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "Đảo ngược chuột" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "Ánh sáng mịn" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"Số lượt tải xuống đồng thời tối đa. Tải xuống vượt quá giới hạn sẽ được xếp " +"hàng đợi.\n" +"Giá trị này phải thấp hơn curl_parallel_limit." + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "Độ nhạy chuột" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "Đánh dấu node" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "Màn hình:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "Màn hình:" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "Lưu trữ máy chủ" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "- Tên máy chủ: " + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "Mô tả Máy chủ" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "Cổng máy chủ" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"Chỉ định URL mà từ đó ứng dụng khách tìm phương tiện thay vì sử dụng UDP.\n" +"$filename có thể truy cập được từ $remote_media$filename qua cURL\n" +"(trong đó, remote_media phải kết thúc bằng dấu gạch chéo).\n" +"Các tệp không có mặt sẽ được tìm theo cách thông thường." + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "Cài đặt" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "Có cho phép người chơi sát thương và giết lẫn nhau hay không." + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "Thời gian khởi động thế giới" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "cURL" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "Hết thời gian chờ tải xuống tệp trong cURL" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "Hết thời gian tương tác với cURL" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "Gặp giới hạn số lượng tệp tải xuống trong cURL" + +#~ msgid "- Creative Mode: " +#~ msgstr "- Chế độ sáng tạo: " + +#~ msgid "- Damage: " +#~ msgstr "- Tổn hại: " + +#~ msgid "Connect" +#~ msgstr "Kết nối" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "" +#~ "Tải xuống một trò chơi, chẳng hạn như trò chơi Minetest, từ minetest.net" + +#~ msgid "Download one from minetest.net" +#~ msgstr "Tải xuống một trò chơi từ minetest.net" + +#~ msgid "Game" +#~ msgstr "Trò chơi" + +#~ msgid "Ok" +#~ msgstr "Được" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "Bạn đã chết" diff --git a/po/yue/minetest.po b/po/yue/minetest.po new file mode 100644 index 0000000..536ba0e --- /dev/null +++ b/po/yue/minetest.po @@ -0,0 +1,6839 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the minetest package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: minetest\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: yue\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Client Mods" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Development Test is meant for developers." +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install a game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Missing name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +msgid "Passwords do not match" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +msgid "Register" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Games" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Content: Mods" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "" + +#: builtin/mainmenu/tab_about.lua +msgid "Share debug log" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Remove favorite" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Dynamic shadows:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Touch threshold (px):" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very High" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "" + +#: src/client/client.cpp +msgid "Connection aborted (protocol error?)." +msgstr "" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "" + +#: src/client/client.cpp +msgid "Done!" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "" + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "" + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "" + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "" + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "" + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "" + +#: src/client/game.cpp +msgid "- Port: " +msgstr "" + +#: src/client/game.cpp +msgid "- Public: " +msgstr "" + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "" + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "" + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "" + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "" + +#: src/client/game.cpp +msgid "Continue" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "" + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "" + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Error creating client: %s" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Media..." +msgstr "" + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "" + +#: src/client/game.cpp +msgid "Off" +msgstr "" + +#: src/client/game.cpp +msgid "On" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "" + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "" + +#: src/client/game.cpp +msgid "ok" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "" + +#: src/client/keycode.cpp +msgid "End" +msgstr "" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +msgid "Name is taken. Please choose another name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Admin name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Always fly fast" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome API noise parameters" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Client-side Modding" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Developer Options" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Filtering and Antialiasing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gamepads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics Effects" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics and Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD scaling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument chat commands on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick dead zone" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map shadows update frames" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Modifies the size of the HUD elements." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Monospace font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Networking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node and Entity Highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Poisson filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Screenshots" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Gameplay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server Security" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Server/Env Performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist and MOTD" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow filter quality" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture size" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Soft shadow radius" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Temporary Settings" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The dead zone of the joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The depth of dirt or other biome filler node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Touchscreen" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley fill" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Weblink color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Width of the selection box lines around nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of upper limit of large caves." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL interactive timeout" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "" diff --git a/po/zh_CN/minetest.po b/po/zh_CN/minetest.po new file mode 100644 index 0000000..9bca847 --- /dev/null +++ b/po/zh_CN/minetest.po @@ -0,0 +1,8079 @@ +msgid "" +msgstr "" +"Project-Id-Version: Chinese (Simplified) (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-05-19 18:13+0000\n" +"Last-Translator: GT-610 <myddz1005@163.com>\n" +"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" +"minetest/minetest/zh_Hans/>\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.13-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "清除聊天发送队列" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "空命令。" + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "退出至主菜单" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "无效命令 " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "发送的命令 " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "列出联机玩家" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "在线玩家: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "聊天发送队列现在为空。" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "服务器已禁用该命令." + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "重生" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "您已死亡" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "可用命令:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "可用命令: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "命令不可用: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "获取命令帮助" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "" +"使用 '.help <cmd>' 获取该命令的更多信息,或使用 '.help all' 列出所有内容。" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <命令>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<无可用命令>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Lua 脚本发生错误:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "发生了错误:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "主菜单" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "重新连接" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "服务器已请求重新连接:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "选择Mod" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "协议版本不匹配。 " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "服务器强制协议版本为 $1。 " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "服务器支持协议版本为 $1 至 $2。 " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "我们只支持协议版本 $1。" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "我们支持的协议版本为 $1 至 $2。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "取消" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "依赖项:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "全部禁用" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "禁用 mod 包" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "全部启用" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "启用 mod 包" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "无法启用 mod \"$1\":因为包含有不支持的字符。只允许 [a-z0-9_] 字符。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "寻找更多mod" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "无(可选)依赖项" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "未提供游戏描述。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "无依赖项" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "未提供 mod 包描述。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "无可选依赖项" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "可选依赖项:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "保存" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "世界:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "启用" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "\"$1\"已经存在,你想覆写吗?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$1 和 $2 依赖项将被安装." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 作者: $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 正在下载,\n" +"$2 排队中" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "正在下载 $1 ……" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "有$1个依赖项没有找到。" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "$1 将被安装, $2 依赖项将被跳过." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "所有包" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "已安装" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "返回主菜单" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "基础游戏:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "在没有cURL的情况下编译Minetest时,ContentDB不可用" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "下载中..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "下载 $1 失败" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "子游戏" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "安装" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "安装$1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "安装缺失的依赖项" + +#: builtin/mainmenu/dlg_contentstore.lua +#, fuzzy +msgid "Install: Unsupported file type or broken archive" +msgstr "安装:文件类型不支持或档案已损坏" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mod" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "无法检索任何包" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "无结果" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "没有更新" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "未找到" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "覆写" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "请查看游戏是否正确。" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "已加入队列" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "材质包" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "卸载" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "更新" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "更新所有 [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "在网络浏览器中查看更多信息" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "名为 \"$1\" 的世界已经存在" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "额外地形" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "高地寒冷" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Altitude dry" +msgstr "高地干燥" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biome blending" +msgstr "生物群系融合" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Biomes" +msgstr "生物群系" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "大型洞穴" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "洞穴" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "创建" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "装饰" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "警告:开发测试是为开发者提供的。" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "地窖" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "平坦地形" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floating landmasses in the sky" +msgstr "空中漂浮的陆地" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "悬空岛(实验性)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "生成非分形地形:海洋和地底" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "丘陵" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "潮湿河流" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "增加河流周边湿度" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "安装$1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "湖" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "低湿度和高温导致浅而干燥的河流" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "地图生成器" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "地图生成器标志" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "地图生成器专用标签" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "山" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "泥流" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "通道和洞穴网络" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "未选择游戏" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "随海拔高度降低热量" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "随海拔高度降低湿度" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "河流" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "海平面河流" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "种子" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "生物群落之间的平滑过渡" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "出现在地形上的结构(对v6创建的树木和丛林草没有影响)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "出现在地形上的结构,通常是树木和植物" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "温带,沙漠" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "温带,沙漠,丛林" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "温带,沙漠,丛林,苔原,泰加林带" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "地形表面侵蚀" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "树木和丛林草" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "变化河流深度" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "地下深处的大型洞穴" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "世界名称" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "你没有安装任何子游戏。" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "你确认要删除“$1”吗?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "删除" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr:无法删除“$1”" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr:MOD 路径 “$1” 无效" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "删除世界“$1”?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "确认密码" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "地图生成器名称" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "名称" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "密码" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "密码不匹配!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "注册并加入" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "接受" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "重命名MOD包:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "" +"此 mod 包在它的 modpack.conf 中有一个明确的名称,它将覆盖这里的任何重命名。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(没有关于此设置的信息)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "2D 噪声" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< 返回设置页面" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "浏览" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "内容" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "内容" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "禁用" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "编辑" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "启用" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "空白" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Octaves" +msgstr "八音" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "补偿" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Persistence" +msgstr "持续性" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "请输入一个整数类型。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "请输入一个合法的数字。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "恢复初始设置" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "比例" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "搜索" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "选择目录" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "选择文件" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "显示高级名称" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "这个值必须至少为 $1。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "这个值必须不大于$1." + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "x 点差" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "y 点差" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "z 点差" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "绝对值" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "默认值" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "缓解" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1 已启用" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 mod" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "无法把$1安装到$2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "安装mod:无法找到$1的真实mod名称" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "安装mod:无法找到mod包$1的合适文件夹名" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "无法找到mod或mod包" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "无法将$1安装为材质包" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "无法将$1安装为子游戏" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "无法将$1安装为mod" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "无法将$1安装为mod包" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "载入中..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "已禁用公共服务器列表" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "请尝试重新启用公共服务器列表并检查您的网络连接。" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "关于" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "积极贡献者" + +#: builtin/mainmenu/tab_about.lua +msgid "Active renderer:" +msgstr "主动渲染器:" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "核心开发者" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "打开用户数据目录" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"在文件(资源)管理器中打开含有用户提供的世界,游戏,mods\n" +"和纹理包的目录。" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "前贡献者" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "前核心开发者" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "显示调试信息" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "浏览在线内容" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "内容" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "禁用材质包" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "信息:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "已安装包:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "无依赖项。" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "该包无描述信息" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "重命名" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "删除包" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "使用材质包" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "公开服务器" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "绑定地址" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "创造模式" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "开启伤害" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "主持游戏" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "建立服务器" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "从 ContentDB 安装游戏" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "新建" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "未创建或选择世界!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "开始游戏" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "端口" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "选择Mod" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "选择世界:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "服务器端口" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "启动游戏" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "地址" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "Clear键" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "创造模式" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "伤害 / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "我的收藏" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "不兼容的服务器" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "加入游戏" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "应答速度" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "公开服务器" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "刷新" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "远程端口" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "服务器描述" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "两倍" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "3D 云彩" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "四倍" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "八倍" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "所有设置" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "抗锯齿:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "自动保存屏幕尺寸" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "双线性过滤" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "更改键位设置" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "连通玻璃" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "动态阴影" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "动态阴影: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "华丽树叶" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "高" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "低" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "中" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mip 贴图" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mip 贴图 + 各向异性过滤" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "无过滤" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "无 Mip 贴图" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "方块高亮" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "方块轮廓" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "无" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "不透明树叶" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "不透明水" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "粒子效果" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "屏幕:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "设置" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "着色器" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "着色器(实验性)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "着色器 (不可用)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "简单树叶" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "平滑光照" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "材质:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "色调映射" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "触控阈值:(px)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "三线性过滤" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "超出高度限制" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "过于低" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "飘动树叶" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "摇动流体" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "摇摆植物" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "连接出错(超时?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "连接超时。" + +#: src/client/client.cpp +msgid "Done!" +msgstr "完成!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "初始化方块中" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "初始化方块..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "载入材质..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "重建着色器..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "连接出错(超时?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "找不到子游戏或者无法载入子游戏: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "非法游戏信息。" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "主菜单" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "没有选择世界或提供地址。无可用操作。" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "玩家名称过长。" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "请选择名称!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "提供的密码文件无法打开: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "提供的世界路径不存在: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"查看 debug.txt 以获得详细信息。" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- 地址: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- 模式: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- 端口: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- 公共服务器: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- 玩家对战: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- 服务器名称: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "序列化发生了错误:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "访问被拒绝。原因:%s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "自动前进已禁用" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "自动前进已启用" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "已隐藏方块边界" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "已为所有方块描边" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "已为当前方块描边" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "已为周围方块描边" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "已禁用镜头更新" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "已启用镜头更新" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "无法显示方块的边界 (需要“basic_debug”权限)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "更改密码" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "电影模式已禁用" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "电影模式已启用" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "与客户端的连接已断开" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "客户端脚本已禁用" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "正在连接服务器..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "连接失败,原因不明" + +#: src/client/game.cpp +msgid "Continue" +msgstr "继续" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"控制:\n" +"- %s:向前移动\n" +"- %s:向后移动\n" +"- %s:向左移动\n" +"- %s:向右移动\n" +"- %s:跳/向上(攀爬)\n" +"- %s:挖/打\n" +"- %s:放/使用\n" +"- %s:潜行/向下(攀爬)\n" +"- %s:丢弃物品\n" +"- %s:物品清单\n" +"- 鼠标:转身/环顾\n" +"- 鼠标滚轮: 选择物品\n" +"- %s:聊天\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "地址无法解析:%s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "正在建立客户端..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "建立服务器...." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "调试信息和性能分析图已隐藏" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "调试信息已显示" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "调试信息、性能分析图和线框已隐藏" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"默认控制:\n" +"菜单不可见时:\n" +"- 单击: 激活按钮\n" +"- 双击: 放置/使用\n" +"- 滑动手指: 改变视角\n" +"菜单/物品栏可见时:\n" +"- 双击 (界面区域外):\n" +" --> 关闭\n" +"- 点击物品, 然后点击栏位:\n" +" --> 移动一组物品\n" +"- 点击物品并拖动, 然后另一手指点击\n" +" --> 移动一个物品\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "禁用无限视野" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "启用无限视野" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "正在建立客户端..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "退出至菜单" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "退出至操作系统" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "快速模式已禁用" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "快速模式已启用" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "快速模式已启用(注:无 'fast' 权限)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "飞行模式已禁用" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "飞行模式已启用" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "飞行模式已启用(注:无 'fly' 权限)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "雾气已禁用" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "雾气已启用" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "游戏信息:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "游戏暂停" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "建立服务器" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "物品定义..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/s" + +#: src/client/game.cpp +msgid "Media..." +msgstr "媒体..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/s" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "小地图被当前子游戏或者 mod 禁用" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "多人游戏" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "穿墙模式已禁用" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "穿墙模式已启用" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "穿墙模式已启用 (注:无 'noclip' 权限)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "方块定义..." + +#: src/client/game.cpp +msgid "Off" +msgstr "关" + +#: src/client/game.cpp +msgid "On" +msgstr "开" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "俯仰移动模式已禁用" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "俯仰移动模式已启用" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "性能分析图已显示" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "远程服务器" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "正在解析地址..." + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "关闭中..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "单人游戏" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "音量" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "已静音" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "声音系统已禁用" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "此编译版本不支持声音系统" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "已取消静音" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "此服务器运行的可能是别的版本,%s。" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "无法连接到 %s,因为 IPv6 已禁用" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "无法监听 %s,因为 IPv6 已禁用" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "视野范围已改变至%d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "视野范围已达到最大:%d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "视野范围已达到最小:%d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "音量改到%d1%%2" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "线框已显示" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "缩放被当前子游戏或 mod 禁用" + +#: src/client/game.cpp +msgid "ok" +msgstr "确定" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "聊天已隐藏" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "聊天已显示" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "HUD 已隐藏" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "HUD 已显示" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "性能分析图已隐藏" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "性能分析图已显示 (第 %d 页 共 %d 页)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "应用" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "退格" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "大写锁定键" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Ctrl键" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "向下" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End键" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "擦除EOF键" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "执行" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "帮助" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home键" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "IME接受" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "IME转换" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "IME脱离" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME模式更改" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME无转换" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "Insert键" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "向左" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "左键" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "左Control键" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "左菜单键" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "左Shift键" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "左Windows键" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "菜单" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "中键" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "数字锁定键" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "小键盘*" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "小键盘+" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "小键盘-" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "小键盘." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "小键盘/" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "小键盘0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "小键盘1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "小键盘2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "小键盘3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "小键盘4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "小键盘5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "小键盘6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "小键盘7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "小键盘8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "小键盘9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM Clear键" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "下一页" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "上一页" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "Pause键" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "开始游戏" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "打印" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "回车键" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "向右" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "右键" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "右Control键" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "右菜单键" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "右Shift键" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "右Windows键" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "Scroll Lock键" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "选择键" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift键" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "睡眠" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "快照" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "空格" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab键" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "向上" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X键1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X键2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "缩放" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "小地图已隐藏" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "雷达小地图,放大至%d倍" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "地表模式小地图, 放大至%d倍" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "材质模式小地图" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "网页打不开" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "正在打开网页" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "继续" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "“Aux1” = 向下爬" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "自动向前" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "自动跳跃" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "向后" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "地图块边界" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "改变相机" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "聊天" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "命令" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "控制台" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "减少可视范围" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "减小音量" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "连按两次“跳”启用/禁用飞行模式" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "丢弃" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "向前" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "增加可视范围" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "增大音量" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "物品栏" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "跳" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "按键已被占用" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "本地命令" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "静音" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "下一个" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "上一个物品" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "选择范围" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "截图" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "潜行" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "启用/禁用HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "启用/禁用聊天记录" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "启用/禁用快速模式" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "启用/禁用飞行模式" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "启用/禁用雾" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "启用/禁用小地图" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "启用/禁用穿墙模式" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "启用/禁用仰角移动模式" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "按键" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "更改" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "新密码" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "旧密码" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "密码不匹配!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "退出" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "静音" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "音量:%d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "zh_CN" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "请选择名称!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android)修复虚拟操纵杆的位置。\n" +"如果禁用,虚拟操纵杆将居中至第一次触摸的位置。" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(安卓)使用虚拟操纵杆触发\"Aux1\"按钮。\n" +"如果启用,虚拟操纵杆在主圆圈外会点击\"Aux1\"按钮。" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"分形图形距世界中心的(X, Y, Z)偏移\n" +"以『比例』为单位。\n" +"可用于移动给定点至(0, 0)以创建生成\n" +"点,或通过增加『比例』来放大给定点。\n" +"默认值适合曼德尔布罗特集合,若要用于其\n" +"他情形则可能需要修改。\n" +"范围大约在 -2 至 2 间。\n" +"乘以『比例』。" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" +"节点的分形的(X,Y,Z)比例。\n" +"实际分形大小将是2到3倍。\n" +"这些数字可以做得非常大,\n" +"分形不一定要适合世界。\n" +"增加这些以“放大”到分形的细节。\n" +"默认值为适合\n" +"孤岛的垂直压扁形状,将所有3个数字设置为相等以呈现原始形状。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "控制山脊形状/大小的2D噪声。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "控制波状丘陵形状/大小的2D噪声。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "控制平缓山形状/大小的2D噪声。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "控制山脊区域的大小/频率的2D噪声。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "控制波状丘陵的大小/频率的2D噪声。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "控制平缓山的大小/频率的2D噪声。" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "确定河谷及河道位置的2D噪声。" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D 云彩" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D 模式" + +#: src/settings_translation_file.cpp +msgid "3D mode parallax strength" +msgstr "3D模式视差强度" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "定义巨型洞穴的3D噪声。" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"定义山丘结构和高度的3D噪声。\n" +"也定义悬空岛山丘地形。" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" +"悬空岛的3D噪波定义结构。\n" +"如果改变了默认值,噪波“scale”(默认为0.7)可能需要\n" +"调整,因为当这个噪波的值范围大约为-2.0到2.0时,\n" +"悬空岛逐渐变窄的函数最好。" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "定义河谷壁的结构的3D噪声。" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "定义地形的3D噪声。" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "用于突出崖、悬崖等的3D噪声。通常变化小。" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "确定每个地图块的地窖数量的3D噪声。" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3D 支持。\n" +"目前已支持:\n" +"- 无(none): 无 3D 输出。\n" +"- 立体影片(anaglyph):青红/品红色彩色 3D。\n" +"- 交错(interlaced):基于奇偶行的偏振屏支持。\n" +"- 顶底(topbottom):上下分屏。\n" +"- 并列(sidebyside):左右分屏。\n" +"- 内斜视(crossview):内斜视左右分屏3D。\n" +"- 翻页(pageflip):基于四重缓冲的 3D。\n" +"注意交错模式需要启用着色器。" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"输入新地图的随机种子值,不填则随机生成。\n" +"在主菜单中创建新地图时将被覆盖。" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "当服务器崩溃的时候,发送给所有客户端的信息。" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "当关闭服务器时,发送给所有客户端的信息。" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "ABM间隔" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "ABM 时间预算" + +#: src/settings_translation_file.cpp +msgid "Absolute limit of queued blocks to emerge" +msgstr "待显示方块队列的绝对限制" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "空中加速" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "重力加速度,单位为方块每秒二次方。" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "活动方块修改器" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "活动方块管理间隔" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "活动方块范围" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "活动目标发送范围" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"服务器连接地址。\n" +"留空则启动一个本地服务器。\n" +"注意,主菜单的地址栏将会覆盖这里的设置。" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "挖方块时添加粒子。" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "为支持4K等屏幕,调节像素点密度(非 X11/Android 环境才有效)。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "调整检测到的显示密度,用来缩放 UI 元素。" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" +"调整悬空岛层的密度。\n" +"增加值,就增加密度。可以是正值或负值。\n" +"值等于 0.0, 容积的 50% 是悬空岛。\n" +"值等于 2.0,(值可以更高,取决于“mgv7_np_floatland”,但一定要测试确定)\n" +"创建一个密实的悬空岛层。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "添加物品名称" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "高级" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" +"通过“gamma修正”调整亮度曲线。\n" +"更大的gamma值使得低亮度区域更亮。\n" +"值为'1.0'时亮度曲线。\n" +"这只在白天和人工光源下有较大作用,\n" +"在夜晚的自然光照下作用很小。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "保持飞行和快速模式" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "环境遮蔽gamma" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "每10秒发送给玩家的消息量。" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "放大山谷。" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "各向异性过滤" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "公开服务器" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "向服务器表公开服务器。" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "添加物品名称" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "添加物品名称至工具栏。" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "苹果树噪声" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "手臂惯性" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"手臂惯性,使摄像机移动时手臂时\n" +"更真实地运动。" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "崩溃后询问重新连接" + +#: src/settings_translation_file.cpp +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"在此距离下,服务器将积极优化将哪些块发送到客户端。\n" +"小数值可能会极大地提高性能,\n" +"却会造成可见的渲染故障。\n" +"(有些方块将不会在水和洞穴中呈现,\n" +"有时在陆地上也不会呈现)\n" +"将其设置为大于 max_block_send_distance 的值\n" +"将禁用此优化。\n" +"在 mapblocks中声明(16 个节点)。" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "自动前进键" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "自动跳跃一方块高度。" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "自动报告到服务器列表。" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "自动保存屏幕大小" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "自动缩放模式" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Aux1键" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "用于攀登/降落的Aux1键" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "后退键" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "平地级别" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "基础地形高度。" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "基本权限" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "海滩噪声" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "海滩噪声阈值" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "双线性过滤" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "绑定地址" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "生物群系 API 温度和湿度噪声参数" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "生物群系噪声" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "最优方块发送距离" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "粗斜体字体路径" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "粗斜体等宽字体路径" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "粗体字体路径" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "粗体等宽字体路径" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "在玩家站着的地方搭建" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "内置" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "改变相机" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" +"相机在节点附近的“剪切平面附近”距离,介于0到0.25之间。\n" +"大多数用户不需要更改此设置。\n" +"增加可以减少较弱GPU上的伪影。\n" +"0.1 =默认值,0.25 =对于较弱的平板电脑来说是不错的值。" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "镜头平滑" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "电影模式下镜头平滑" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "镜头更新启用/禁用键" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "洞穴噪声" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "洞穴噪声 #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "洞穴噪声 #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "洞穴宽度" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "洞穴1噪声" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "洞穴2噪声" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "大型洞穴界限" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "大型洞穴噪声" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "大型洞穴锥度" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "大型洞穴阈值" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "大型洞穴上界" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" +"亮度曲线范围中心。\n" +"0.0为最小值时1.0为最大值。" + +#: src/settings_translation_file.cpp +msgid "Chat command time message threshold" +msgstr "显示聊天消息执行时间的阀值(秒)" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "聊天指令" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "聊天字体大小" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "聊天键" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "聊天日志级别" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "聊天消息计数限制" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "聊天消息格式" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "聊天消息踢出阈值" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "聊天消息最大长度" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "聊天启用/禁用键" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "聊天网页链接" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "块大小" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "电影模式" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "电影模式键" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "干净透明材质" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "" +"在聊天控制台输出中启用了可点击的网页链接(中键单击或 Ctrl + 左键单击)。" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "客户端" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "客户端和服务端" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "客户端mod" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "客户端mod限制" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "客户端方块查询范围限制" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "客户端mod" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "攀登速度" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "云半径" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "云彩" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "云是客户端效果。" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "主菜单显示云彩" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "彩色雾" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "彩色阴影" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" +"逗号分隔用于在仓库中隐藏内容的标签列表。\n" +"\"nonfree\"可用于隐藏根据自由软件基金会\n" +"不符合“自由软件”标准的包。\n" +"你也可以为仓库内容指定评分。\n" +"这些评分独立于Minetest版本,\n" +"完整列表见https://content.minetest.net/help/content_flags/" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"以逗号分隔可以存取 HTTP API的mod列表,\n" +"这些mod可与互联网交互,上传及下载数据。" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"受信任的 Mod 列表,以逗号分隔,其可访问不安全的\n" +"函数,即便 mod 安全性已启用(经由 request_insecure_environment())。" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "命令键" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" +"欲用来节约地图块占用的磁盘空间,所要使用的压缩等级。\n" +"-1 - 使用默认值\n" +"0 - 最小压缩,最快\n" +"9 - 最佳压缩,最慢" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "连接玻璃" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "连接到外部媒体服务器" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "如果方块支持则连通玻璃。" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "控制台透明度" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "控制台颜色" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "控制台高度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Content Repository" +msgstr "在线内容仓库(ContentDB)" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "ContentDB标签黑名单" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "ContentDB 最大并发下载量" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "ContentDB网址" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "自动前进" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"自动前进,通过自动前进键启用/禁用。\n" +"再次按下自动前进键或后退以关闭。" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "控制" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"控制日夜循环的长度。\n" +"示例:\n" +"72 = 20分钟,360 = 4分钟,1 = 24小时,0 = 锁定日夜循环。" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "控制湖泊洼地的坡度/深度。" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "控制山丘的坡度/高度。" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"控制洞穴通道宽度,设置较小值以创建较宽通道。\n" +"值>=10.0则完全关闭通道生成,避免大量噪声\n" +"计算。" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "崩溃信息" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "创造" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "准星透明" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"准星不透明度(0-255)。\n" +"实体准星的不透明度也会使用此值。" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "准星颜色" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"准星颜色(R,G,B).\n" +"还控制对象准星颜色" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "伤害" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "调试信息启用/禁用键" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "沙漠噪声阈值" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "调试日志级别" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "音量减小键" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "专用服务器步骤" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "默认加速度" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "默认游戏" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"创建新世界时的默认游戏。\n" +"从主菜单创建一个新世界时这将被覆盖。" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "默认密码" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "默认权限" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "默认报告格式" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "默认栈大小" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" +"设定阴影滤镜的质量。\n" +"使用 PCF 或 泊松盘(Poisson disk)算法模拟软阴影效果\n" +"但也会使用更多的硬件资源。" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "定义树上长苹果的区域." + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "定义沙质海滩区域." + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "定义高地形的分布情况和悬崖陡峭程度。" + +#: src/settings_translation_file.cpp +msgid "Defines distribution of higher terrain." +msgstr "定义悬崖顶部地形的分布。" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "定义大型洞穴的尺寸,数值越小洞穴越大。" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "定义大尺寸的河道结构。" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "定义所选的山和湖的位置与地形。" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "定义基准地面高度." + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "定义水道深度." + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "定义玩家可传送的最大距离,以方块为单位 (0 = 不限制)。" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "定义河道宽度。" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "定义河谷宽度." + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "定义森林面积和森林密度。" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"客户端网格更新的延迟(以毫秒计)。增大该数值将降低\n" +"网格更新速率,从而减少较慢客户端的抖动现象。" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "建造后发送方块的延迟时间" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "工具栏显示延迟,按毫秒计算。" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "已弃用 Lua API 处理" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find giant caverns." +msgstr "巨型洞穴的最浅深度。" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "大型洞穴的最浅深度。" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "服务器描述,将在玩家加入时发送给玩家,并显示在服务器列表。" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "沙漠噪声阈值" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"当np_biome超过该值时将产生沙漠。\n" +"当‘snowbiomes’启用时,该项将被忽略。" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "去同步块动画" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "装饰" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "挖掘键" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "挖掘粒子效果" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "禁用反作弊" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "禁止使用空密码" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "显示密度比例系数" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "服务器域名,将显示在服务器列表。" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "双击“跳跃”键飞行" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "连按两次“跳跃”键启用/禁用飞行模式。" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "丢弃物品键" + +#: src/settings_translation_file.cpp +msgid "Dump the mapgen debug information." +msgstr "转储地图生成器调试信息。" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "地窖最大Y坐标" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "地窖最小Y坐标" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "地窖噪声" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"为客户端和服务端启用IPv6支持。\n" +"需要IPv6网络连接可用。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"启用客户端Lua mod支持。\n" +"该功能是实验性的,且API会变动。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" +"启用泊松盘(Poisson disk)滤镜。\n" +"使用泊松盘算法来产生“软阴影”。不启用的话就会使用 PCF 滤镜。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" +"启用彩色阴影。\n" +"在半透明节点上投射彩色阴影。会消耗超多的资源。" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "启用控制台窗口" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "为所有玩家启用创造模式" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "启用摇杆" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "启用 mod 频道支持。" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "启用 mod 安全" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "启用玩家受到伤害和死亡。" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "启用随机用户输入(仅用于测试)。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"启用简单环境光闭塞的平滑光照。\n" +"禁用可影响速度或得到不同外观。" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"启用禁止旧版客户端连接模式。\n" +"兼容旧版客户端是指它们不会在连接新版服务器时\n" +"崩溃,但可能不支持某些您所期望的新特性。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"允许使用远程媒体服务器 (如果由服务器提供)。\n" +"连接到服务器时,远程服务器会提供一种更快的方式\n" +"下载媒体信息 (如材质)。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" +"启用顶点缓冲对象。\n" +"这会极大改善图像性能。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"启用视角摇动和视角摇动幅度。\n" +"例如:0是不摇动;1.0正常摇动;2.0双倍。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"允许/禁止运行 IPv6 服务器。\n" +"如果设置了 bind_address 则本项被忽略。\n" +"需要开启 enable_ipv6。" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" +"开启Hable的“神秘海域2”电影式的色调映射。\n" +"模拟电影色调曲线及其实现高动态范围图像的方式。\n" +"略微改善中等范围对比度。\n" +"逐步压缩高亮和阴影。" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "启用物品清单动画。" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "启用翻转网状物facedir的缓存。" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "启用小地图。" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" +"启用声音系统。\n" +"如果禁用,则完全禁用游戏中所有声音。\n" +"游戏内声音控制将失效。\n" +"改变此设置需要重启。" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "允许不影响可玩性的轻微视觉错误,以此减少 CPU 负载,或提高渲染性能。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "山谷轮廓" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "打印引擎性能分析数据间隔" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "实体方法" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" +"悬空岛锥度的指数,更改锥度的行为。\n" +"值等于1.0,创建一个统一的,线性锥度。\n" +"值大于1.0,创建一个平滑的、合适的锥度,默认分隔的悬空岛。\n" +"值小于1.0,(例如0.25)创建一个带有平坦低地的更加轮廓分明的表面级别,\n" +"适用于固体悬空岛层。" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS when unfocused or paused" +msgstr "游戏暂停时最高 FPS" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "系数噪声" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "坠落上下摆动系数" + +#: src/settings_translation_file.cpp +msgid "Fallback font path" +msgstr "后备字体路径" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "快速键" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "快速模式加速度" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "快速模式速度" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "快速移动" + +#: src/settings_translation_file.cpp +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"快速移动(通过“Aux1”键)。\n" +"这需要服务器的“fast”权限。" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "视野" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "视野角度。" + +#: src/settings_translation_file.cpp +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"客户端/服务器列表/ 中的文件,包含显示在“多人游戏”选项卡中的您\n" +"收藏的服务器。" + +#: src/settings_translation_file.cpp +msgid "Filler depth" +msgstr "填充深度" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "填充深度噪声" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "电影色调映射" + +#: src/settings_translation_file.cpp +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"经过滤的材质会与邻近的全透明材质混合RGB值,\n" +"该值通常会被PNG优化器丢弃,某些时候会给透明材质产生暗色或\n" +"亮色的边缘。应用该过滤器将在材质加载时移除该效果。\n" +"该过滤器将在启用mipmapping的时候被自动应用。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "抗锯齿:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "定义决定丘陵/山地范围高度的4个2D噪声的第一项。" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "定义决定通道的2个3D噪声的第一项。" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "固定地图种子" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "固定虚拟摇杆" + +#: src/settings_translation_file.cpp +msgid "Floatland density" +msgstr "悬空岛密度" + +#: src/settings_translation_file.cpp +msgid "Floatland maximum Y" +msgstr "悬空岛最大Y坐标" + +#: src/settings_translation_file.cpp +msgid "Floatland minimum Y" +msgstr "悬空岛最小Y坐标" + +#: src/settings_translation_file.cpp +msgid "Floatland noise" +msgstr "悬空岛噪声" + +#: src/settings_translation_file.cpp +msgid "Floatland taper exponent" +msgstr "悬空岛尖锐指数" + +#: src/settings_translation_file.cpp +msgid "Floatland tapering distance" +msgstr "悬空岛尖锐距离" + +#: src/settings_translation_file.cpp +msgid "Floatland water level" +msgstr "悬空岛水位" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "飞行键" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "飞行" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "雾" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "雾开始" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "雾启用/禁用键" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "字体大小" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "默认粗体" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "默认斜体" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "字体阴影" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "字体阴影透明度" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "字体大小" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "默认字体大小,单位pt。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "等宽字体大小,单位pt。" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" +"最近聊天文本和聊天提示的字体大小(pt)。\n" +"值为0将使用默认字体大小。" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"玩家聊天消息格式。以下字符串是合法占位符:\n" +"@name, @message, @timestamp (可选)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "屏幕截图格式。" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "窗口默认背景色" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "窗口默认背景不透明度" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "窗口全屏背景色" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "窗口全屏背景不透明度" + +#: src/settings_translation_file.cpp +msgid "Formspec default background color (R,G,B)." +msgstr "窗口默认背景色(红,绿,蓝)。" + +#: src/settings_translation_file.cpp +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "窗口默认背景不透明度(0~255)。" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background color (R,G,B)." +msgstr "窗口全屏背景色(红,绿,蓝)。" + +#: src/settings_translation_file.cpp +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "窗口全屏背景不透明度(0~255)。" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "前进键" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "定义决定丘陵/山地范围高度的4个2D噪声的第四项。" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "分形类型" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "从雾起始点开始雾的可见距离分数" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "为客户端生成方块的距离多远,以地图区块(16 方块)为单位。" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "为客户端发送方块的距离多远,以地图区块(16 方块)为单位。" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" +"客户端得知对象的距离多远,以地图区块(16 方块)为单位。\n" +"\n" +"将此值设定为大于active_block_range的值也会导致服务器向\n" +"玩家注视方向维护活跃对象至此距离(这可以避免mob突然从\n" +"视野中消失)" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "全屏" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "全屏模式。" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "GUI缩放" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "GUI缩放过滤器" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "GUI缩放过滤器 txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "子游戏" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "全局回调" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"全局地图生成属性。\n" +"在地图生成器 v6 中‘decorations’标签控制除树木和丛林草外所有装饰物。\n" +"在其他地图生成器中此标签控制所有装饰物。" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" +"最大光照下的光曲线梯度。\n" +"控制最高光照级别的对比度。" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" +"最低亮度下亮度曲线的梯度。\n" +"控制最低亮度下的对比度。" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "图形" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "图形" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "图形" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "重力" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "地面高度" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "地面噪声" + +#: src/settings_translation_file.cpp +msgid "HTTP mods" +msgstr "HTTP Mods" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "GUI缩放" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "HUD启用/禁用键" + +#: src/settings_translation_file.cpp +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"处理已弃用的 Lua API 调用:\n" +"- none:不记录废弃的调用。\n" +"- log:模拟并记录已弃用的调用的回溯(调试的默认值)。\n" +"- error:停止使用已弃用的调用(Mod 开发人员推荐)。" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"使性能分析计数器自身:\n" +"* 计数空函数。\n" +"估测计数器增加的性能开支。\n" +"* 计数被用于更新统计的取样器。" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "热混合噪声" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "热噪声" + +#: src/settings_translation_file.cpp +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "初始窗口高度,全屏模式下忽略该值。" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "高度噪声" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "高度选择噪声" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "山丘坡度" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "山丘阈值" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "山丘噪声 #1" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "山丘噪声 #2" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "山丘噪声 #3" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "山丘噪声 #4" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "服务器首页,将会显示在服务器列表中。" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" +"跳跃和掉落的水平加速度。\n" +"单位为方块每二次方秒。" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" +"快速模式的水平和竖直加速度。\n" +"单位为方块每二次方秒。" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" +"行走或攀爬的水平和竖直加速度。\n" +"单位为方块每二次方秒。" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "快捷栏下一个键" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "快捷栏上一个键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "快捷栏1键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "快捷栏10键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "快捷栏11键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "快捷栏12键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "快捷栏13键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "快捷栏14键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "快捷栏15键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "快捷栏16键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "快捷栏17键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "快捷栏18键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "快捷栏19键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "快捷栏2键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "快捷栏20键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "快捷栏21键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "快捷栏22键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "快捷栏23键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "快捷栏24键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "快捷栏25键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "快捷栏26键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "快捷栏27键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "快捷栏28键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "快捷栏29键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "快捷栏3键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "快捷栏30键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "快捷栏31键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "快捷栏32键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "快捷栏4键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "快捷栏5键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "快捷栏6键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "快捷栏7键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "快捷栏8键" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "快捷栏9键" + +#: src/settings_translation_file.cpp +msgid "How deep to make rivers." +msgstr "生成河流多深。" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" +"液体波移动多快。更高值=更快。\n" +"如果为负,液体波向后移动。\n" +"需要波动液体启用。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"在卸载不使用的地图区块前,服务器要等待多少时间。\n" +"值越高越平滑,但是会使用更多内存。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "减小此值以增加液体对运动的阻力。" + +#: src/settings_translation_file.cpp +msgid "How wide to make rivers." +msgstr "生成河流多宽。" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "湿度混合噪声" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "湿度噪声" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "生物群系的湿度变化。" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6 服务器" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"如果 FPS 可以超过此值,通过睡眠限制它以\n" +"节省无效 CPU 功耗。" + +#: src/settings_translation_file.cpp +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "如果禁用,“Aux1”键将用于快速飞行(飞行和快速模式同时启用)。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"如果启用,服务器会根据玩家的视野遮挡\n" +"剔除地图区块。这可以减少向客户端发送\n" +"的 50-80% 的区块。客户端将不会收到最\n" +"不可见的内容,降低 noclip 模式的实用性。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"使玩家可以在飞行启用时飞过固体方块。\n" +"这需要服务器的“noclip”权限。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "" +"如果启用,“Aux1”键将代替潜行键的向下攀爬和\n" +"下降。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"在连接到服务器时启用注册确认。\n" +"如果禁用,新账号会自动注册。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"如果启用,则会记录操作以进行回滚。\n" +"仅在服务器启动时读取此选项。" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "如果启用,在多人游戏中禁用防止作弊。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"如果启用,无效的世界数据将不会导致服务器关闭。\n" +"只有在你知道自己在做什么的情况下才能启用它。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "如果启用,则在飞行或游泳时相对于玩家的仰角来移动方向。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "如果启用,新玩家将无法使用空密码加入。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"如果启用,您可以将方块放置在您站立的位置(脚+视线水平)。\n" +"在小区域中使用方块框型方块时,这很有用。" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" +"如果客户端mod方块范围限制启用,限制get_node至玩家\n" +"到方块的距离。" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" +"如果聊天命令的执行时间长于此指定以秒为单位时间,请将时间信息添加到聊天命令消" +"息中。" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" +"如果 debug.txt 的文件大小在 打开时超过设置,\n" +"这个文件将被移动到debug.txt.1, \n" +"如果存在较旧的debug.txt.1,则旧的将被删除。 \n" +"仅当此设置为正时,才会移动 debug.txt。" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "如果设置了此选项,玩家将始终在指定位置出(重)生。" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "忽略世界错误" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "游戏内聊天控制台背景 alpha 值(不透明度,0~255)。" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "游戏内聊天控制台背景色(红,绿,蓝)。" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "游戏内聊天控制台高度,0.1(10%)~1.0(100%)。" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "音量增大键" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "初始垂直速度,单位为方块每二次方秒。" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"内置计数器。\n" +"通常只有核心/内部构建者需要" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Instrument chat commands on registration." +msgstr "登录时的聊天命令。" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"注册时计数全局回调函数。\n" +"(传递给 minetest.register_*() 函数的任何内容)" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "注册时计数ABM的行为函数。" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "注册时计数LBM的行为函数。" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "注册时计数实体的方法。" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "保存世界重要变化的时间间隔,以秒为单位。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "向客户端发送时间的间隔。" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "物品清单物品动画" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "物品清单键" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "反转鼠标" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "反转垂直鼠标移动。" + +#: src/settings_translation_file.cpp +msgid "Italic font path" +msgstr "斜体字体路径" + +#: src/settings_translation_file.cpp +msgid "Italic monospace font path" +msgstr "斜体等宽字体路径" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "物品实体 TTL" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "迭代" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" +"递归函数迭代数。\n" +"增加此值会增加细节量,但也会\n" +"增加处理器负荷。\n" +"在迭代数=20时地图生成器有与地图生成器v4相似的负荷。" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "摇杆 ID" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "摇杆按钮重复间隔" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick dead zone" +msgstr "摇杆无效区" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "摇杆头灵敏度" + +#: src/settings_translation_file.cpp +msgid "Joystick type" +msgstr "摇杆类型" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"仅朱莉亚集合。\n" +"超复数常数的W成分。\n" +"改变分形图形形状。\n" +"对3D分形无影响。\n" +"大致在-2到2之间。" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"仅朱莉亚集合。\n" +"超复数常数的X成分。\n" +"改变分形图形形状。\n" +"大致在-2到2之间。" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"仅朱莉亚集合。\n" +"超复数常数的Y成分。\n" +"改变分形图形形状。\n" +"大致在-2到2之间。" + +#: src/settings_translation_file.cpp +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"仅朱莉亚集合。\n" +"超复数常数的Z成分。\n" +"改变分形图形形状。\n" +"大致在-2到2之间。" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "朱莉亚w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "朱莉亚x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "朱莉亚y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "朱莉亚z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "跳跃键" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "跳跃速度" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"视野缩小键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"音量减小键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"跳跃键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"丢弃所选物品键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"视野扩大键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"音量增大键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"跳跃键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"快速模式快速移动键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"后退键。\n" +"在按下时也会取消自动前进。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"前进键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"左方向键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"右方向键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"静音键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"打开聊天窗口输入命令键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"打开聊天窗口输入本地命令键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"打开聊天窗口键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"打开物品清单键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"跳跃键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第11个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第12个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第13个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第14个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第15个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第16个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第17个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第18个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第19个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第20个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第21个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第22个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第23个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第24个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第25个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第26个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第27个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第28个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第29个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第30个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第31个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第32个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第8个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第5个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第1个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第4个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏下一个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第9个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏上一个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第2个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第7个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第6个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第10个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"选择快捷栏第3个位置键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"下蹲键。\n" +"若aux1_descends禁用,也可用于向下攀爬、在水中向下游。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"第一人称第三人称镜头切换键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"截屏键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用自动前进键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用电影模式键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用小地图键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用快速移动键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用飞行键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用穿墙模式键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用俯仰移动模式键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用相机更新键。仅用于开发。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用聊天显示键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用调试信息键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用雾显示键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用HUD显示键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用大型聊天控制台显示键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用性能分析图显示键。仅用于开发。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用无限视野键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"启用/禁用缩放(如有可能)键。\n" +"见http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "提出在10秒内发送超过X条消息的玩家。" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "湖坡度" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "湖阈值" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "语言" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "大型洞穴深度" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "大型洞穴最大数量" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "大型洞穴最小数量" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "大型洞穴淹没比" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "大型聊天控制台键" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "树叶风格" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"树叶风格:\n" +"- 华丽: 所有面可见\n" +"- 简单: 若special_tiles已定义,仅外表面可见\n" +"- 不透明: 取消树叶透明度" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "左方向键" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "" +"服务器时钟节拍长度,通常也是对象通过网络更新的\n" +"时间间隔。" + +#: src/settings_translation_file.cpp +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"液体波长度。\n" +"需要波动液体启用。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "ABM执行循环时长" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "NodeTimer执行循环时长" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "活动方块管理循环时长" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"写入debug.txt的日志等级:\n" +"- <无>(无日志)\n" +"- 无等级(none)(无等级的消息)\n" +"- 错误(error)\n" +"- 警告(warning)\n" +"- 行为(action)\n" +"- 信息(info)\n" +"- 冗长调试信息(verbose)" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "亮度曲线提升" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "亮度曲线提升中心" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "亮度曲线提升点差" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "亮度曲线gamma" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "亮度曲线高梯度" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "亮度曲线低梯度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "平滑光照" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"从(0,0,0)向全部6个方向的地图生成限制,单位为方块。\n" +"地图生成器只生成完全在此限制的地图块。\n" +"此值为每个世界单独保存。" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"并行HTTP请求数限制。\n" +"- 如果服务器使用remote_media设置,影响媒体信息获取。\n" +"- 影响服务器列表下载和服务器公开。\n" +"- 主菜单下载(例如mod管理器)\n" +"仅在编译时启用cURL时起作用。" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "液体流动性" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "液体流动性平滑" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "液体循环最大值" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "液体队列清除时间" + +#: src/settings_translation_file.cpp +msgid "Liquid sinking" +msgstr "液体下沉" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "液体更新间隔,单位秒。" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "液体更新时钟间隔" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "加载游戏性能分析图" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"读取游戏性能分析图以收集游戏性能分析数据。\n" +"提供/profiler命令用于访问编译的性能分析图。\n" +"对mod开发者和服务器管理员有用。" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "加载时区块修改间隔" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "地窖的Y值下限。" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of floatlands." +msgstr "悬空岛的Y值下限。" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "主菜单脚本" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "使雾和天空颜色依赖于一天中的时间(黎明/傍晚)和视线方向。" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "使所有液体不透明" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "磁盘存储的映射压缩级别" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "网络传输的地图压缩级别" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "地图目录" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "针对Carpathian地图生成器的属性。" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"针对Flat地图生成器的属性。\n" +"有时湖泊和丘陵可加入平坦的世界。" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"针对Fractal地图生成器的属性。\n" +"'terrain'启用非分形地图的生成:\n" +"海洋,岛屿和地下地形。" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" +"针对Valley地图生成器的属性。\n" +"'altitude_chill':随海拔高度减小热量。\n" +"'humid_rivers':增加河流周围的湿度。\n" +"'vary_river_depth':如果启用,高热量低湿度导致河流\n" +"变浅甚至干枯。\n" +"'altitude_dry':随海拔高度减小湿度。" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "针对v5地图生成器的属性。" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"针对v6地图生成器的属性。\n" +"'snowboimes'启用新版5生物群系系统。\n" +"当'snowbiomes'开启使丛林自动启用,\n" +"忽略'jungles'标签。" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"针对v7地图生成器的属性。\n" +"'ridges':启用河流。\n" +"'floatlands':漂浮于大气中的陆块。\n" +"'caverns':地下深处的巨大洞穴。" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "地图生成限制" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "地图保存间隔" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map shadows update frames" +msgstr "液体更新时钟间隔" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "地图块限制" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "地图生成延时" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "地图生成缓存大小" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "地图块卸载时限" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian" +msgstr "地图生成器Carpathian" + +#: src/settings_translation_file.cpp +msgid "Mapgen Carpathian specific flags" +msgstr "地图生成器Carpathian标签" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat" +msgstr "地图生成器Flat" + +#: src/settings_translation_file.cpp +msgid "Mapgen Flat specific flags" +msgstr "地图生成器Flat标签" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal" +msgstr "地图生成器Fractal" + +#: src/settings_translation_file.cpp +msgid "Mapgen Fractal specific flags" +msgstr "地图生成器Fractal标签" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5" +msgstr "地图生成器 v5" + +#: src/settings_translation_file.cpp +msgid "Mapgen V5 specific flags" +msgstr "地图生成器 v5 标签" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6" +msgstr "地图生成器 v6" + +#: src/settings_translation_file.cpp +msgid "Mapgen V6 specific flags" +msgstr "地图生成器 v6 标签" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7" +msgstr "地图生成器 v7" + +#: src/settings_translation_file.cpp +msgid "Mapgen V7 specific flags" +msgstr "地图生成器 v7 标签" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "地图生成器Valleys" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys specific flags" +msgstr "地图生成器Valleys标签" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "地图生成器调试" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "地图生成器名称" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "最大方块生成距离" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "最大方块发送距离" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "每个时钟间隔内液体的最大处理速度。" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "最大clearobjects额外方块数" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "每次迭代最大包" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "最大 FPS" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "窗口未聚焦或游戏暂停时的最大 FPS。" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "最大渲染阴影距离。" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "最大强制载入块" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "最大快捷栏宽度" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "每个地图块中随机的大型洞穴数的最大值。" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "每个地图块中随机的小型洞穴数的最大值。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" +"最大液体阻力。控制快速进入液体时\n" +"的减速度。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" +"同时发送至每个客户端的方块最大数。\n" +"最大总数按以下式子自动计算:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "可在加载时加入队列的最大方块数。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"在生成时加入队列的最大方块数。\n" +"此限制对每位玩家强制执行。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"在从文件中加载时加入队列的最大方块数。\n" +"此限制对每位玩家强制执行。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" +"最大并发下载数。 超过此限制的下载将排队。 这应该低于 curl_parallel_limit(卷" +"曲平行限制)。" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "强制载入地图块最大数量。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"客户端保存在内存中的最大地图块数量。\n" +"设置为-1则无限量。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"每个发送间隔之间发送的最大包数,如果你网络连接慢\n" +"尝试减小它,但不要把它减小到小雨目标客户端数的\n" +"两倍。" + +#: src/settings_translation_file.cpp +msgid "Maximum number of players that can be connected simultaneously." +msgstr "同时连接的玩家最大数量。" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "显示的最近消息最大数量" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "方块内静态存储的对象最大数。" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "方块内最大对象数" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"窗口内用于显示快捷栏的最大比例。\n" +"有需要在快捷栏左右两侧显示的内容时该设置有用。" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "给每个客户端发送方块的最大次数" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "显示最大聊天记录的行度" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" +"外出聊天队列的最大大小。\n" +"0取消队列,-1使队列大小无限。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "单个文件下载(如mod下载)的最大时间。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "交互式请求(例如服务器列表获取)可能需要的最长时间,以毫秒为单位。" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "最大用户数" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "Mesh 缓存" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "今日消息" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "发送给连接中玩家的今日消息。" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "用于高亮选定的对象的方法。" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "写入聊天的最小日志级别。" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "小地图" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "小地图键" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "小地图扫描高度" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "每个地图块的随机大型洞穴数的上限。" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "每个地图块的随机大型洞穴数的下限。" + +#: src/settings_translation_file.cpp +msgid "Minimum texture size" +msgstr "最小材质大小" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "Mip 贴图" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "性能分析" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "安全" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "mod频道" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Modifies the size of the HUD elements." +msgstr "更改hud栏元素大小。" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "等宽字体路径" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "等宽字体大小" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "等宽字体大小" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "山高度噪声" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "山噪声" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "山变化噪声" + +#: src/settings_translation_file.cpp +msgid "Mountain zero level" +msgstr "山起点高度" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "鼠标灵敏度" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "鼠标灵敏度倍数。" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "泥土噪声" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"掉落摇动倍数。\n" +"例如:设为0则不摇动;1.0则正常;2.0则两倍。" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "静音按键" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "静音" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" +"创建新世界时使用的地图生成器名称。\n" +"在主菜单中创建一个世界会覆盖此属性。\n" +"目前以下地图生成器非常不稳定:\n" +"- v7悬空岛(默认禁用)。" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"玩家名称。\n" +"当运行服务器时,用此名称连接的客户端是管理员。\n" +"从主菜单开始时,此项将被覆盖。" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "服务器名称,将显示在提供给玩家的服务器列表。" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "近平面" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"监听网络端口 (UDP)。\n" +"从主菜单开始时此值将被覆盖。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "网络" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "新用户需要输入此密码。" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "穿墙" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "穿墙键" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "方块高亮" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "方块高亮" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "NodeTimer间隔" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "噪声" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "生产线程数" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" +"使用的生产线程数。\n" +"值0:\n" +"- 自动选择。生产线程数会是‘处理器数-2’,\n" +"- 下限为1。\n" +"任何其他值:\n" +"- 指定生产线程数,下限为1。\n" +"警告:增大此值会提高引擎地图生成器速度,但会由于\n" +"干扰其他进程而影响游戏体验,尤其是单人模式或运行\n" +"‘on_generated’中的Lua代码。对于大部分用户来说,最\n" +"佳值为'1'。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"/clearobjects每次能加载的额外方块数。\n" +"这是与sqlite交互和内存消耗的平衡。\n" +"(4096=100MB,按经验法则)。" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "不透明液体" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "默认字体后阴影的透明度(alpha),取值范围0~255。" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" +"当窗口焦点丢失是打开暂停菜单。如果游戏内窗口打开,\n" +"则不暂停。" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "替换聊天网页链接的颜色,可用可不用。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" +"后备字体路径。\n" +"如果“freetype”设置启用:必须为TrueType字体。\n" +"如果“freetype”设置禁用:必须为位图或XML矢量字体。\n" +"此字体用于不可用默认字体的语言。" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" +"路径保存截图。可以是绝对路径或相对路径。\n" +"如果该文件夹不存在,将创建它。" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "着色器目录路径。如果未定义路径,则使用默认路径。" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "材质目录路径。所有材质都首先从此路径搜索。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" +"默认字体路径。\n" +"如果“freetype”设置启用:必须为TrueType字体。\n" +"如果“freetype”设置禁用:必须为位图或XML矢量字体。\n" +"后备字体用于不可用默认字体的语言。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" +"等宽字体路径。\n" +"如果“freetype”设置启用:必须为TrueType字体。\n" +"如果“freetype”设置禁用:必须为位图或XML矢量字体。\n" +"此字体用于控制台、性能分析图界面等。" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "丢失窗口焦点时暂停" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "每个玩家从磁盘加载的队列块的限制" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks to generate" +msgstr "每个玩家要生成的生产队列限制" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "物理" + +#: src/settings_translation_file.cpp +msgid "Pitch move key" +msgstr "俯仰移动键" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "俯仰移动模式" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "飞行键" + +#: src/settings_translation_file.cpp +msgid "Place repetition interval" +msgstr "放置重复间隔" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"使玩家可以不受重力飞起。\n" +"这需要服务器的“fly”权限。" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "玩家转移距离" + +#: src/settings_translation_file.cpp +msgid "Player versus player" +msgstr "玩家对战" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "双线性过滤" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"要连接到的端口(UDP)。 \n" +"请注意,主菜单中的端口字段将覆盖此设置。" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" +"按住鼠标时,防止重复破坏和重复放置。 \n" +"当您意外地频繁破坏或放置方块时启用此功能。" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "阻止 mod 执行不安全操作,如运行 shell 命令。" + +#: src/settings_translation_file.cpp +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "" +"以固定间隔(以秒为单位)打印引擎的性能分析数据。 \n" +"0 = 禁用。对开发人员很有用。" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "有\"basic_privs\"的玩家可以授予的权限" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "性能分析" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "性能分析启用/禁用键" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "Prometheus 监听器地址" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" +"Prometheus 监听器地址。\n" +"如果minetest是在启用ENABLE_PROMETHEUS选项的情况下编译的,\n" +"在该地址上为 Prometheus 启用指标侦听器。\n" +"可以从 http://127.0.0.1:30000/metrics 获取指标" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "包含液体的大洞穴的比例。" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"以64个节点的云立方体的数目表示的云区域半径。\n" +"大于26的值将开始在云区域的拐角处产生尖锐的边界。" + +#: src/settings_translation_file.cpp +msgid "Raises terrain to make valleys around the rivers." +msgstr "抬高地形使河流周围形成山谷。" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "随机输入" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "范围选择键" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "最近聊天消息" + +#: src/settings_translation_file.cpp +msgid "Regular font path" +msgstr "常规字体路径" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "远程媒体" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "远程端口" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"移除传入聊天消息的色彩码\n" +"使用该设置来防止玩家在消息中使用颜色" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "将默认主菜单替换为自定义主菜单。" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "报告路径" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" +"在服务器上限制一些客户端上的功能。\n" +"将下面的标志位结合来限制客户端功能,设置为0为\n" +"无限制:\n" +"LOAD_CLIENT_MODS:1(禁止加载客户端 mod)\n" +"CHAT_MESSAGES:2(禁止客户端调用 send_chat_message)\n" +"READ_ITEMDEFS:4(禁止客户端调用 get_item_def)\n" +"READ_NODEDEFS:8(禁止客户端调用 get_node_def)\n" +"LOOKUP_NODES_LIMIT:16(禁止客户端 get_node 调用限制为\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO:32(禁止客户端调用 get_player_names)" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "山脊扩散噪声" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "山脊噪声" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "水下山脊噪声" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "山脊大小噪声" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "右方向键" + +#: src/settings_translation_file.cpp +msgid "River channel depth" +msgstr "河道深度" + +#: src/settings_translation_file.cpp +msgid "River channel width" +msgstr "河道宽度" + +#: src/settings_translation_file.cpp +msgid "River depth" +msgstr "河流深度" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "河流噪声" + +#: src/settings_translation_file.cpp +msgid "River size" +msgstr "河流大小" + +#: src/settings_translation_file.cpp +msgid "River valley width" +msgstr "河谷深度" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "回滚记录" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "波状丘陵大小噪声" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "波状丘陵扩散噪声" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "圆形小地图" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "安全挖掘和放置" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "当 np_beach 超过这个值时会出现沙滩。" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "将客户端接收到的地图保存在磁盘上。" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "当窗口大小改变时自动保存。" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "正在保存从服务器收到的地图" + +#: src/settings_translation_file.cpp +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"根据用户指定值缩放GUI。\n" +"使用最近的邻近抗锯齿滤镜缩放GUI。\n" +"这会将粗边处理光滑,并且在缩小时,\n" +"以在非整数缩放大小下模糊化部分边界\n" +"为代价混合像素。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "屏幕:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "屏幕高度" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "屏幕宽度" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "截图文件夹" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "截图格式" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "截图品质" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"截图品质。仅用于JPEG格式。\n" +"1 代表最差品质,100 代表最佳品质。\n" +"使用 0 来使用预设品质。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "截图" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "海底噪声" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "定义山/山丘范围高度的4个2D噪声的第二项。" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "定义通道的2个3D噪音的第二项。" + +#: src/settings_translation_file.cpp +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "见 https://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "边框颜色 (红,绿,蓝) 选择框。" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "选择框颜色" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "选择框宽度" + +#: src/settings_translation_file.cpp +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"从 9 种公式里选取 18 种分形。\n" +"1 = 4D \"Roundy\" 曼德尔布罗特集.\n" +"2 = 4D \"Roundy\" 朱利亚集.\n" +"3 = 4D \"Squarry\" 曼德尔布罗特集.\n" +"4 = 4D \"Squarry\" 朱利亚集.\n" +"5 = 4D \"Mandy Cousin\" 曼德尔布罗特集.\n" +"6 = 4D \"Mandy Cousin\" 朱利亚集.\n" +"7 = 4D \"Variation\" 曼德尔布罗特集.\n" +"8 = 4D \"Variation\" 朱利亚集.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" 曼德尔布罗特集.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" 朱利亚集.\n" +"11 = 3D \"Christmas Tree\" 曼德尔布罗特集.\n" +"12 = 3D \"Christmas Tree\" 朱利亚集.\n" +"13 = 3D \"Mandelbulb\" 曼德尔布罗特集.\n" +"14 = 3D \"Mandelbulb\" 朱利亚集.\n" +"15 = 3D \"Cosine Mandelbulb\" 曼德尔布罗特集.\n" +"16 = 3D \"Cosine Mandelbulb\" 朱利亚集.\n" +"17 = 4D \"Mandelbulb\" 曼德尔布罗特集.\n" +"18 = 4D \"Mandelbulb\" 朱利亚集." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "服务器 URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "服务器名称" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "服务器描述" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "服务器 URL" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "服务器地址" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "服务器描述" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "服务器名称" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "服务器端口" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "服务器端遮挡删除" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "服务器端口" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "服务器列表 URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "服务器列表 URL" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "服务器列表文件" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"设定语言。留空以使用系统语言。\n" +"变更后须重新启动。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "设定客户端传送的聊天讯息的最大字符长度。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" +"设置阴影强度。\n" +"较低的值表示较亮的阴影,较高的值表示较暗的阴影。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" +"设置软阴影半径大小。\n" +"较低的值意味着更清晰的阴影更大的值更柔和。\n" +"最小值 1.0 和最大值 10.0" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" +"以度为单位设置太阳/月亮轨道的倾斜度\n" +"值 0 表示没有倾斜/垂直轨道。\n" +"最小值 0.0 和最大值 60.0" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"设置为真以启用飘动树叶。\n" +"需要启用着色器。" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"设置为真以启用飘动树叶。\n" +"需要启用着色器。" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"设置为真以启用摇动流体(例如水)。\n" +"需要启用着色器。" + +#: src/settings_translation_file.cpp +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"设置为真以启用摆动植物。\n" +"需要启用着色器。" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" +"将阴影纹理质量设置为 32 位。\n" +"如果为 false(否),将使用 16 位纹理。\n" +"这可能会导致阴影中出现更多阴影。" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "着色器路径" + +#: src/settings_translation_file.cpp +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"着色器允许高级视觉效果并且在一些显卡上可能会提高\n" +"性能。\n" +"仅用于OpenGL视频后端。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "截图品质" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "渲染阴影的节点中的阴影贴图最大距离" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "32 位阴影贴图纹理" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map texture size" +msgstr "最小材质大小" + +#: src/settings_translation_file.cpp +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "默认字体阴影偏移(单位为像素),0 表示不绘制阴影。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow strength gamma" +msgstr "阴影强度" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "小地图的形状。启用 = 圆形,停用 = 方形。" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "显示调试信息" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "显示实体选择框" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"设定语言。留空以使用系统语言。\n" +"变更后须重新启动。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Show name tag backgrounds by default" +msgstr "默认显示名称标签背景" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "关闭消息" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" +"地图生成器生成的地图块的大小,以地图区块(16方块)表示。\n" +"警告!:将此值增加到大于5没有益处,而且有\n" +"多种危险。\n" +"减少此值增加洞穴和地窖密度。\n" +"修改此值适用于特殊用途,建议不改变\n" +"此值。" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"网格生成器的地图区块缓存大小。增加此值将会\n" +"增加缓存命中率,减少从主线程复制数据,从而\n" +"减少抖动。" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "天体轨道倾斜" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "切片 w" + +#: src/settings_translation_file.cpp +msgid "Slope and fill work together to modify the heights." +msgstr "斜率和填充共同工作来修改高度。" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "小型洞穴最大数" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "小型洞穴最小数" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "在边界上的混合生物群系的湿度变化。" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "在边界上的混合生物群系的温度变化。" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "平滑光照" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"当转动视角时让摄影机变流畅。也称为观看或鼠标流畅。\n" +"对录影很有用。" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "在电影模式中让摄影机旋转变流畅。设为 0 以停用。" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "让旋转摄影机时较流畅。设为 0 以停用。" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "潜行键" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed" +msgstr "潜行速度" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "潜行速度,以方块每秒为单位。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "字体阴影透明度" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "音效" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"客户端从指定的 URL 而不是使用 UDP 获取媒体。\n" +"$filename 应该可以通过 cURL 从 $remote_media$filename 访问。\n" +"(显然,remote_media 部份应以斜线结束)。\n" +"没有在其中的文件将会以通常的方式获取。" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" +"指定节点、物品和工具的默认堆叠数量。\n" +"请注意,mod或游戏可能会为某些(或所有)项目明确设置堆栈。" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" +"把完整地更新一次阴影贴图这项任务分配给多少帧去完成。\n" +"较高的值可能会使阴影滞后,较低的值\n" +"将消耗更多硬件资源。\n" +"最小值:1;最大值:16" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" +"光曲线提升范围的分布。\n" +"控制要提升的范围的宽度。\n" +"光曲线的标准偏差可提升高斯。" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "静态重生点" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "陡度噪声" + +#: src/settings_translation_file.cpp +msgid "Step mountain size noise" +msgstr "单步山峰高度噪声" + +#: src/settings_translation_file.cpp +msgid "Step mountain spread noise" +msgstr "单步山峰广度噪声" + +#: src/settings_translation_file.cpp +msgid "Strength of 3D mode parallax." +msgstr "3D 模式视差的强度。" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" +"光照曲线提升的强度。\n" +"3 个'boost'参数定义了在亮度上提升的\n" +"光照曲线的范围。" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "严格协议检查" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "条形颜色代码" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" +"放置在固体浮地层的可选水的表面水平。\n" +"默认情况下,水处于禁用状态,并且仅在设置此值时才放置\n" +"在'mgv7_floatland_ymax' - 'mgv7_floatland_taper'上(\n" +"上部逐渐变细的开始)。\n" +"***警告,世界存档和服务器性能的潜在危险***:\n" +"启用水放置时,必须配置和测试悬空岛\n" +"通过将\"mgv7_floatland_density\"设置为 2.0(或其他\n" +"所需的值,具体取决于mgv7_np_floatland\"),确保是固体层,\n" +"以避免服务器密集的极端水流,\n" +"并避免地表的巨大的洪水。" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "同步 SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "生物群系的温度变化。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "设置" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "地形替代噪声" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "地形基准高度噪声" + +#: src/settings_translation_file.cpp +msgid "Terrain height" +msgstr "地形高度" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "地形增高噪声" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "地形噪声" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"丘陵的地形噪声阈值。\n" +"控制山丘覆盖的世界区域的比例。\n" +"朝0.0调整较大的比例。" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"湖泊的地形噪声阈值。\n" +"控制被湖泊覆盖的世界区域的比例。\n" +"朝0.0调整较大的比例。" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "地形持久性噪声" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "材质路径" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" +"用于渲染阴影贴图的材质尺寸。\n" +"数值必须是 2 的幂。\n" +"数值更大,阴影更好,但运算也更加复杂。" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "内容存储库的 URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The dead zone of the joystick" +msgstr "摇杆的无效区" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The depth of dirt or other biome filler node." +msgstr "泥土深度或其他生物群系过滤节点。" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "开始触摸屏交互所需的长度(以像素为单位)。" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "服务器监听的网络接口。" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"新玩家自动获得的权限。\n" +"在游戏中查看/privs以获得完整列表和mod配置。" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"摇杆轴灵敏度(用于移动子游戏中棱台体形状的\n" +"可见区域的摇杆轴)。" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "摇杆类型" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" +"如果'altitude_chill'开启,则热量下降20的垂直距离\n" +"已启用。如果湿度下降的垂直距离也是10\n" +"已启用“ altitude_dry”。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "定义tunnels的最初2个3D噪音。" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"项目实体(删除的项目)生存的时间(以秒为单位)。\n" +"将其设置为 -1 将禁用该功能。" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "一天中开始一个新世界的时间,以毫小时为单位(0-23999)。" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "发送间隔时间" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "速度时间" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "客户端从内存中移除未用地图数据的超时。" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "启用/禁用拍照模式键" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "工具提示延迟" + +#: src/settings_translation_file.cpp +msgid "Touch screen threshold" +msgstr "触屏阈值" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "触屏阈值" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "性能权衡" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "树木噪声" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "三线性过滤" + +#: src/settings_translation_file.cpp +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"可用于在较慢的机器上使最小地图更平滑。" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "可信 mod" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "显示在“多人游戏”选项卡中的服务器列表的URL。" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "欠采样" + +#: src/settings_translation_file.cpp +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "无限的玩家转移距离" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "卸载未用服务器数据" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "地窖的Y值上限。" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of floatlands." +msgstr "悬空岛的Y值上限。" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "使用 3D 云彩,而不是看起来是平面的。" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "主菜单背景使用云动画。" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "缩放材质时使用双线过滤。" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "缩放材质时使用三线过滤。" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +msgid "VSync" +msgstr "垂直同步" + +#: src/settings_translation_file.cpp +msgid "Valley depth" +msgstr "山谷深度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Valley fill" +msgstr "山谷弥漫" + +#: src/settings_translation_file.cpp +msgid "Valley profile" +msgstr "山谷轮廓" + +#: src/settings_translation_file.cpp +msgid "Valley slope" +msgstr "山谷坡度" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "生物群落填充物深度的变化。" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "最大山体高度的变化(以节点为单位)。" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "洞口数量的变化。" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Varies steepness of cliffs." +msgstr "控制山丘的坡度/高度。" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "屏幕垂直同步。" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "视频驱动程序" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "视野晃动系数" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "可视距离(以节点方块为单位)。" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "可视范围减小键" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "可视范围增加键" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "检视缩放键" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "可视范围" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "音量" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"启用视差闭塞映射。\n" +"需要着色器已启用。" + +#: src/settings_translation_file.cpp +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "步行和飞行速度,单位为方块每秒。" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "步行速度" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "快速模式下的步行、飞行和攀爬速度,单位为方块每秒。" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "水位" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Water surface level of the world." +msgstr "世界水平面级别。" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "摇动节点" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "摇动树叶" + +#: src/settings_translation_file.cpp +msgid "Waving liquids" +msgstr "波动流体" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave height" +msgstr "波动液体波动高度" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wave speed" +msgstr "波动液体波动速度" + +#: src/settings_translation_file.cpp +msgid "Waving liquids wavelength" +msgstr "波动液体波动长度" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "摇动植物" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "选择框颜色" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"是否在一次 (Lua) 崩溃后询问客户端是否重新连接。\n" +"如果你的服务器设为自动重连,将此项设为真。" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "是否让雾出现在可视范围末端。" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "是否显示客户端调试信息(与按 F5 的效果相同)。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "初始窗口大小的宽度。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width of the selection box lines around nodes." +msgstr "结点周围的选择框的线宽。" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"世界目录(世界里的所有东西都存在这里)。\n" +"如果从主菜单开始游戏就不需要。" + +#: src/settings_translation_file.cpp +msgid "World start time" +msgstr "世界开始时间" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "平地的 Y。" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Y of upper limit of large caves." +msgstr "大型随机洞穴的Y轴最大值。" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of higher terrain that creates cliffs." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of lower terrain and seabed." +msgstr "较低地形与海底的Y坐标。" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "海底的Y坐标。" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "cURL 文件下载超时" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "cURL 超时" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "cURL 并发限制" + +#~ msgid "- Creative Mode: " +#~ msgstr "- 创造模式: " + +#~ msgid "- Damage: " +#~ msgstr "- 伤害: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = 利用梯度信息进行视差遮蔽 (较快).\n" +#~ "1 = 浮雕映射 (较慢, 但准确)." + +#~ msgid "Address / Port" +#~ msgstr "地址/端口" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "调整亮度表的伽玛编码。较高的数值会较亮。\n" +#~ "这个设定是给客户端使用的,会被服务器忽略。" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "你确定要重置你的单人世界吗?" + +#~ msgid "Back" +#~ msgstr "后退" + +#~ msgid "Basic" +#~ msgstr "基础" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "全屏模式中的位每像素(又称色彩深度)。" + +#~ msgid "Bump Mapping" +#~ msgstr "凹凸贴图" + +#~ msgid "Bumpmapping" +#~ msgstr "凹凸贴图" + +#~ msgid "" +#~ "Changes the main menu UI:\n" +#~ "- Full: Multiple singleplayer worlds, game choice, texture pack " +#~ "chooser, etc.\n" +#~ "- Simple: One singleplayer world, no game or texture pack choosers. May " +#~ "be\n" +#~ "necessary for smaller screens." +#~ msgstr "" +#~ "主菜单UI的变化:\n" +#~ "- 完整 多个单人世界,子游戏选择,材质包选择器等。\n" +#~ "- 简单:单个单人世界,无子游戏材质包选择器。可能\n" +#~ "需要用于小屏幕。" + +#~ msgid "Config mods" +#~ msgstr "配置 mod" + +#~ msgid "Configure" +#~ msgstr "配置" + +#~ msgid "Connect" +#~ msgstr "连接" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "控制在液体中的下沉速度。" + +#, fuzzy +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "控制 floatland 地形的密度。\n" +#~ "是添加到 \"np_mountain\" 噪声值的偏移量。" + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "控制隧道宽度,较小的值创建更宽的隧道。" + +#~ msgid "Credits" +#~ msgstr "贡献者" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "准星颜色(红,绿,蓝)。" + +#~ msgid "Damage enabled" +#~ msgstr "伤害已启用" + +#, fuzzy +#~ msgid "Darkness sharpness" +#~ msgstr "地图生成器平面湖坡度" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "cURL 的默认时限,单位毫秒。\n" +#~ "仅使用 cURL 编译时有效果。" + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "定义 floatland 平滑地形的区域。\n" +#~ "当噪音0时, 平滑的 floatlands 发生。" + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "定义材质采样步骤。\n" +#~ "数值越高常态贴图越平滑。" + +#~ msgid "Del. Favorite" +#~ msgstr "删除收藏项" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "从 minetest.net 下载一个子游戏,例如 minetest_game" + +#~ msgid "Download one from minetest.net" +#~ msgstr "从 minetest.net 下载一个" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "正在下载和安装 $1,请稍等..." + +#~ msgid "Enable VBO" +#~ msgstr "启用 VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "启用注册确认" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "启用材质的凹凸贴图效果。需要材质包支持法线贴图,\n" +#~ "否则将自动生成法线。\n" +#~ "需要启用着色器。" + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "启用电影基调映射" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "启用即时法线贴图生成(浮雕效果)。\n" +#~ "需要启用凹凸贴图。" + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "启用视差遮蔽贴图。\n" +#~ "需要启用着色器。" + +#~ msgid "Enter " +#~ msgstr "输入 " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "实验性选项,设为大于 0 的数字时可能导致\n" +#~ "块之间出现可见空间。" + +#~ msgid "FPS in pause menu" +#~ msgstr "暂停菜单 FPS" + +#~ msgid "Fallback font shadow" +#~ msgstr "后备字体阴影" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "后备字体阴影透明度" + +#~ msgid "Fallback font size" +#~ msgstr "后备字体大小" + +#~ msgid "Filtering" +#~ msgstr "过滤" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "字体阴影不透明度(0-255)。" + +#~ msgid "Font size of the fallback font in point (pt)." +#~ msgstr "后备字体大小,单位pt。" + +#~ msgid "FreeType fonts" +#~ msgstr "FreeType 字体" + +#~ msgid "Full screen BPP" +#~ msgstr "全屏 BPP" + +#~ msgid "Game" +#~ msgstr "子游戏" + +#~ msgid "Gamma" +#~ msgstr "伽马" + +#~ msgid "Generate Normal Maps" +#~ msgstr "生成法线贴图" + +#~ msgid "Generate normalmaps" +#~ msgstr "生成发现贴图" + +#~ msgid "HUD scale factor" +#~ msgstr "HUD 缩放比例系数" + +#~ msgid "High-precision FPU" +#~ msgstr "高精度 FPU" + +#~ msgid "IPv6 support." +#~ msgstr "IPv6 支持。" + +#~ msgid "In-Game" +#~ msgstr "游戏中" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "安装:文件:”$1“" + +#~ msgid "Instrumentation" +#~ msgstr "计数器" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "键位配置。(如果这个菜单被弄乱,从 minetest.conf 中删掉点东西)" + +#, fuzzy +#~ msgid "Lava depth" +#~ msgstr "巨大洞穴深度" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "磁盘上的生产队列限制" + +#~ msgid "Main" +#~ msgstr "主菜单" + +#~ msgid "Main menu style" +#~ msgstr "主菜单样式" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "使DirectX和LuaJIT一起工作。如果这导致了问题禁用它。" + +#~ msgid "Menus" +#~ msgstr "菜单" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "雷达小地图,放大至两倍" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "雷达小地图, 放大至四倍" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "地表模式小地图, 放大至两倍" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "地表模式小地图, 放大至四倍" + +#~ msgid "Name / Password" +#~ msgstr "用户名/密码" + +#~ msgid "Name/Password" +#~ msgstr "用户名/密码" + +#~ msgid "No" +#~ msgstr "否" + +#~ msgid "Normalmaps sampling" +#~ msgstr "法线贴图采样" + +#~ msgid "Normalmaps strength" +#~ msgstr "法线贴图强度" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "视差遮蔽迭代数。" + +#~ msgid "Ok" +#~ msgstr "确定" + +#~ msgid "" +#~ "Opaqueness (alpha) of the shadow behind the fallback font, between 0 and " +#~ "255." +#~ msgstr "后备字体后阴影的透明度(alpha),取值范围0~255。" + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "视差遮蔽效果的整体斜纹,通常为比例/2。" + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "视差遮蔽效果的总体比例。" + +#~ msgid "Parallax Occlusion" +#~ msgstr "视差遮蔽" + +#~ msgid "Parallax occlusion" +#~ msgstr "视差遮蔽" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "视差遮蔽偏移" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "视差遮蔽迭代" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "视差遮蔽模式" + +#~ msgid "Parallax occlusion scale" +#~ msgstr "视差遮蔽比例" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "视差遮蔽强度" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "TrueType 字体或位图的路径。" + +#~ msgid "Path to save screenshots at." +#~ msgstr "屏幕截图保存路径。" + +#~ msgid "Player name" +#~ msgstr "玩家名称" + +#~ msgid "Profiling" +#~ msgstr "性能分析" + +#~ msgid "PvP enabled" +#~ msgstr "启用玩家对战" + +#~ msgid "Reset singleplayer world" +#~ msgstr "重置单人世界" + +#~ msgid "Select Package File:" +#~ msgstr "选择包文件:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "服务器 / 单人游戏" + +#~ msgid "" +#~ "Set the shadow update time.\n" +#~ "Lower value means shadows and map updates faster, but it consume more " +#~ "resources.\n" +#~ "Minimun value 0.001 seconds max value 0.2 seconds" +#~ msgstr "" +#~ "设置阴影更新时间。\n" +#~ "较低的值意味着阴影和贴图更新更快,但会消耗更多资源。\n" +#~ "最小值 0.001 秒 最大值 0.2 秒" + +#, fuzzy +#~ msgid "Shadow limit" +#~ msgstr "地图块限制" + +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "后备字体阴影偏移(单位为像素),0 表示不绘制阴影。" + +#~ msgid "Special" +#~ msgstr "特殊" + +#~ msgid "Special key" +#~ msgstr "特殊键" + +#~ msgid "Start Singleplayer" +#~ msgstr "单人游戏" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "生成的一般地图强度。" + +#~ msgid "This font will be used for certain languages." +#~ msgstr "用于特定语言的字体。" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "启用着色器需要使用OpenGL驱动。" + +#~ msgid "Toggle Cinematic" +#~ msgstr "切换电影模式" + +#~ msgid "View" +#~ msgstr "视野" + +#~ msgid "Waving Water" +#~ msgstr "流动的水面" + +#~ msgid "Waving water" +#~ msgstr "摇动水" + +#, fuzzy +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "大型随机洞穴的Y轴最大值。" + +#~ msgid "Yes" +#~ msgstr "是" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "这是你第一次用“%s”加入服务器。\n" +#~ "如果要继续,一个新的用户将在服务器上创建。\n" +#~ "请重新输入你的密码然后点击“注册”来创建用户或点击“取消”退出。" + +#~ msgid "You died." +#~ msgstr "您已经死亡." + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/po/zh_TW/minetest.po b/po/zh_TW/minetest.po new file mode 100644 index 0000000..0c7081a --- /dev/null +++ b/po/zh_TW/minetest.po @@ -0,0 +1,8007 @@ +msgid "" +msgstr "" +"Project-Id-Version: Chinese (Traditional) (Minetest)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-20 21:43+0200\n" +"PO-Revision-Date: 2022-06-20 09:52+0000\n" +"Last-Translator: Ivon Huang <qj985n2@protonmail.com>\n" +"Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/" +"minetest/minetest/zh_Hant/>\n" +"Language: zh_TW\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.13.1-dev\n" + +#: builtin/client/chatcommands.lua +msgid "Clear the out chat queue" +msgstr "清除聊天佇列" + +#: builtin/client/chatcommands.lua +msgid "Empty command." +msgstr "清空指令。" + +#: builtin/client/chatcommands.lua +msgid "Exit to main menu" +msgstr "離開並回到選單" + +#: builtin/client/chatcommands.lua +msgid "Invalid command: " +msgstr "無效的指令: " + +#: builtin/client/chatcommands.lua +msgid "Issued command: " +msgstr "發送的指令: " + +#: builtin/client/chatcommands.lua +msgid "List online players" +msgstr "列出線上玩家" + +#: builtin/client/chatcommands.lua +msgid "Online players: " +msgstr "線上玩家: " + +#: builtin/client/chatcommands.lua +msgid "The out chat queue is now empty." +msgstr "對外聊天佇列現在為空。" + +#: builtin/client/chatcommands.lua +msgid "This command is disabled by server." +msgstr "這個指令被伺服器停用。" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "Respawn" +msgstr "重生" + +#: builtin/client/death_formspec.lua src/client/game.cpp +msgid "You died" +msgstr "您已死亡" + +#: builtin/common/chatcommands.lua +msgid "Available commands:" +msgstr "可用的指令:" + +#: builtin/common/chatcommands.lua +msgid "Available commands: " +msgstr "可用的指令: " + +#: builtin/common/chatcommands.lua +msgid "Command not available: " +msgstr "指令無法使用: " + +#: builtin/common/chatcommands.lua +msgid "Get help for commands" +msgstr "取得指令的說明" + +#: builtin/common/chatcommands.lua +msgid "" +"Use '.help <cmd>' to get more information, or '.help all' to list everything." +msgstr "使用「.help <cmd>」來取得更多資訊,或使用「.help all」來列出所有指令。" + +#: builtin/common/chatcommands.lua +msgid "[all | <cmd>]" +msgstr "[all | <cmd>]" + +#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp +msgid "OK" +msgstr "OK" + +#: builtin/fstk/ui.lua +msgid "<none available>" +msgstr "<沒有可用的>" + +#: builtin/fstk/ui.lua +msgid "An error occurred in a Lua script:" +msgstr "Lua 指令稿發生錯誤:" + +#: builtin/fstk/ui.lua +msgid "An error occurred:" +msgstr "發生錯誤:" + +#: builtin/fstk/ui.lua +msgid "Main menu" +msgstr "主選單" + +#: builtin/fstk/ui.lua +msgid "Reconnect" +msgstr "重新連線" + +#: builtin/fstk/ui.lua +msgid "The server has requested a reconnect:" +msgstr "伺服器已要求重新連線:" + +#: builtin/mainmenu/common.lua +msgid "A new $1 version is available" +msgstr "" + +#: builtin/mainmenu/common.lua +#, fuzzy +msgid "Client Mods" +msgstr "選擇模組:" + +#: builtin/mainmenu/common.lua +msgid "" +"Installed version: $1\n" +"New version: $2\n" +"Visit $3 to find out how to get the newest version and stay up to date with " +"features and bugfixes." +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Later" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Never" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "Protocol version mismatch. " +msgstr "協定版本不符合。 " + +#: builtin/mainmenu/common.lua +msgid "Server enforces protocol version $1. " +msgstr "伺服器強制協定版本 $1。 " + +#: builtin/mainmenu/common.lua +msgid "Server supports protocol versions between $1 and $2. " +msgstr "伺服器支援協定版本 $1 到 $2。 " + +#: builtin/mainmenu/common.lua +msgid "Visit website" +msgstr "" + +#: builtin/mainmenu/common.lua +msgid "We only support protocol version $1." +msgstr "我們只支援協定版本 $1。" + +#: builtin/mainmenu/common.lua +msgid "We support protocol versions between version $1 and $2." +msgstr "我們支援協定版本 $1 到 $2。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Enabled, has error)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "(Unsatisfied)" +msgstr "" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/dlg_register.lua +#: builtin/mainmenu/dlg_rename_modpack.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp +#: src/gui/guiKeyChangeMenu.cpp src/gui/guiPasswordChange.cpp +msgid "Cancel" +msgstr "取消" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua +#: builtin/mainmenu/tab_content.lua +msgid "Dependencies:" +msgstr "相依元件:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable all" +msgstr "全部停用" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Disable modpack" +msgstr "停用 Mod 包" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable all" +msgstr "全部啟用" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Enable modpack" +msgstr "啟用 Mod 包" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "" +"Failed to enable mod \"$1\" as it contains disallowed characters. Only " +"characters [a-z0-9_] are allowed." +msgstr "無法啟用 Mod「$1」,因為其包含了不允許的字元。只能有 [a-z0-9_] 字元。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Find More Mods" +msgstr "搜尋更多 Mod" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "Mod:" +msgstr "Mod:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No (optional) dependencies" +msgstr "沒有 (選用的) 相依元件" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No game description provided." +msgstr "未提供遊戲描述。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No hard dependencies" +msgstr "沒有強制相依元件" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No modpack description provided." +msgstr "未提供 Mod 包描述。" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "No optional dependencies" +msgstr "沒有可選相依元件" + +#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua +msgid "Optional dependencies:" +msgstr "可選相依元件:" + +#: builtin/mainmenu/dlg_config_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp +msgid "Save" +msgstr "儲存" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "World:" +msgstr "世界:" + +#: builtin/mainmenu/dlg_config_world.lua +msgid "enabled" +msgstr "已啟用" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "\"$1\" already exists. Would you like to overwrite it?" +msgstr "“$1”已經存在。您要覆蓋它嗎?" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 and $2 dependencies will be installed." +msgstr "$1 和他的 $2 個依賴將會被安裝。" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 by $2" +msgstr "$1 作者: $2" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "" +"$1 downloading,\n" +"$2 queued" +msgstr "" +"$1 個正在下載,\n" +"$2 個正在等待" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 downloading..." +msgstr "正在下載 $1..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 required dependencies could not be found." +msgstr "找不到 $1 所需的依賴項。" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "$1 will be installed, and $2 dependencies will be skipped." +msgstr "將安裝 $1,並且將跳過他的 $2 個依賴項。" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "All packages" +msgstr "所有套件" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Already installed" +msgstr "已安裝" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Back to Main Menu" +msgstr "返回主選單" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Base Game:" +msgstr "主遊戲:" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "ContentDB is not available when Minetest was compiled without cURL" +msgstr "在沒有 cURL 的情況下編譯 Minetest 時,ContentDB 不可用" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Downloading..." +msgstr "正在下載..." + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Failed to download $1" +msgstr "無法下載 $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Games" +msgstr "遊戲" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install" +msgstr "安裝" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install $1" +msgstr "安裝 $1" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install missing dependencies" +msgstr "安裝缺少的依賴" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Install: Unsupported file type or broken archive" +msgstr "安裝:檔案類型不支援,或是封存檔損壞" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Mods" +msgstr "Mods" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No packages could be retrieved" +msgstr "無法取得套件" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No results" +msgstr "無結果" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "No updates" +msgstr "無更新" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Not found" +msgstr "找不到" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Overwrite" +msgstr "覆蓋" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Please check that the base game is correct." +msgstr "請檢查基礎遊戲是否正確。" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Queued" +msgstr "已排程" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Texture packs" +msgstr "材質包" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Uninstall" +msgstr "解除安裝" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update" +msgstr "更新" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "Update All [$1]" +msgstr "全部更新 [$1]" + +#: builtin/mainmenu/dlg_contentstore.lua +msgid "View more information in a web browser" +msgstr "在網絡瀏覽器中查看更多信息" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "A world named \"$1\" already exists" +msgstr "名為「$1」的世界已經存在" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Additional terrain" +msgstr "更多地形" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Altitude chill" +msgstr "寒冷海拔" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Altitude dry" +msgstr "寒冷海拔" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biome blending" +msgstr "生物雜訊" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Biomes" +msgstr "生物雜訊" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caverns" +msgstr "大洞穴" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Caves" +msgstr "洞穴" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Create" +msgstr "建立" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Decorations" +msgstr "裝飾物" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Development Test is meant for developers." +msgstr "警告:Development Test 僅供開發者使用。" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Dungeons" +msgstr "地牢" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Flat terrain" +msgstr "超平坦世界" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Floating landmasses in the sky" +msgstr "浮地山密度" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Floatlands (experimental)" +msgstr "空島(實驗性)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Generate non-fractal terrain: Oceans and underground" +msgstr "生成非破碎地形: 海洋與地底" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Hills" +msgstr "山" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Humid rivers" +msgstr "潮濕的河流" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Increases humidity around rivers" +msgstr "增加河流周圍的濕度" + +#: builtin/mainmenu/dlg_create_world.lua +#, fuzzy +msgid "Install a game" +msgstr "安裝 $1" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Install another game" +msgstr "" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Lakes" +msgstr "河流" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Low humidity and high heat causes shallow or dry rivers" +msgstr "因低濕度和高熱度而導致河流淺或乾燥" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen" +msgstr "地圖產生器" + +#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp +msgid "Mapgen flags" +msgstr "地圖產生器旗標" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mapgen-specific flags" +msgstr "v5 地圖產生器特別旗標" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mountains" +msgstr "山脈" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Mud flow" +msgstr "泥石流" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Network of tunnels and caves" +msgstr "隧道和洞穴網絡" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "No game selected" +msgstr "未選擇遊戲" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces heat with altitude" +msgstr "隨海拔降低熱度" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Reduces humidity with altitude" +msgstr "濕度隨海拔升高而降低" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Rivers" +msgstr "河流" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Sea level rivers" +msgstr "生成在海平面的河流" + +#: builtin/mainmenu/dlg_create_world.lua +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Seed" +msgstr "種子碼" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Smooth transition between biomes" +msgstr "生態域之間的平穩過渡" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "" +"Structures appearing on the terrain (no effect on trees and jungle grass " +"created by v6)" +msgstr "出現在地形上的結構(對v6地圖生成器創建的樹木和叢林草無影響)" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Structures appearing on the terrain, typically trees and plants" +msgstr "出現在世界上的結構,通常是樹木和植物" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert" +msgstr "溫帶沙漠" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle" +msgstr "溫帶、沙漠、叢林" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Temperate, Desert, Jungle, Tundra, Taiga" +msgstr "溫帶,沙漠,叢林,苔原,針葉林" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Terrain surface erosion" +msgstr "地形表面侵蝕" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Trees and jungle grass" +msgstr "樹木和叢林草" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Vary river depth" +msgstr "變化的河流深度" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "Very large caverns deep in the underground" +msgstr "地下深處的巨大洞穴" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "World name" +msgstr "世界名稱" + +#: builtin/mainmenu/dlg_create_world.lua +msgid "You have no games installed." +msgstr "您未安裝任何遊戲。" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "Are you sure you want to delete \"$1\"?" +msgstr "您確定要刪除「$1」嗎?" + +#: builtin/mainmenu/dlg_delete_content.lua +#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua +#: src/client/keycode.cpp +msgid "Delete" +msgstr "刪除" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: failed to delete \"$1\"" +msgstr "pkgmgr:無法刪除「$1」" + +#: builtin/mainmenu/dlg_delete_content.lua +msgid "pkgmgr: invalid path \"$1\"" +msgstr "pkgmgr:「$1」路徑無效" + +#: builtin/mainmenu/dlg_delete_world.lua +msgid "Delete World \"$1\"?" +msgstr "刪除世界「$1」?" + +#: builtin/mainmenu/dlg_register.lua src/gui/guiPasswordChange.cpp +msgid "Confirm Password" +msgstr "確認密碼" + +#: builtin/mainmenu/dlg_register.lua +msgid "Joining $1" +msgstr "" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Missing name" +msgstr "Mapgen 名稱" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Name" +msgstr "名字" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_local.lua +#: builtin/mainmenu/tab_online.lua +msgid "Password" +msgstr "密碼" + +#: builtin/mainmenu/dlg_register.lua +#, fuzzy +msgid "Passwords do not match" +msgstr "密碼不符合!" + +#: builtin/mainmenu/dlg_register.lua builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Register" +msgstr "註冊並加入" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Accept" +msgstr "接受" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "Rename Modpack:" +msgstr "重新命名 Mod 包:" + +#: builtin/mainmenu/dlg_rename_modpack.lua +msgid "" +"This modpack has an explicit name given in its modpack.conf which will " +"override any renaming here." +msgstr "這個 Mod 包有在其 modpack.conf 提供明確的名稱,會覆蓋此處的重新命名。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "(No description of setting given)" +msgstr "(未提供設定描述)" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "2D Noise" +msgstr "二維雜訊值" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "< Back to Settings page" +msgstr "< 回到設定頁面" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Browse" +msgstr "瀏覽" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Games" +msgstr "內容" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Content: Mods" +msgstr "內容" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua +msgid "Disabled" +msgstr "已停用" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Edit" +msgstr "編輯" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Enabled" +msgstr "已啟用" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Lacunarity" +msgstr "空隙" + +#: builtin/mainmenu/dlg_settings_advanced.lua +#, fuzzy +msgid "Octaves" +msgstr "倍頻程" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Offset" +msgstr "補償" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Persistence" +msgstr "持續性" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid integer." +msgstr "請輸入有效的整數。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Please enter a valid number." +msgstr "請輸入一個有效的數字。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Restore Default" +msgstr "還原至預設值" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Scale" +msgstr "規模" + +#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua +msgid "Search" +msgstr "搜尋" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select directory" +msgstr "選擇目錄" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Select file" +msgstr "選擇檔案" + +#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp +msgid "Show technical names" +msgstr "顯示技術名稱" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must be at least $1." +msgstr "數值必須大於 $1。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "The value must not be larger than $1." +msgstr "數值必須小於 $1。" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X" +msgstr "X" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "X spread" +msgstr "X 點差" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y" +msgstr "Y" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Y spread" +msgstr "Y 點差" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z" +msgstr "Z" + +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "Z spread" +msgstr "Z 點差" + +#. ~ "absvalue" is a noise parameter flag. +#. It is short for "absolute value". +#. It can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "absvalue" +msgstr "絕對值" + +#. ~ "defaults" is a noise parameter flag. +#. It describes the default processing options +#. for noise settings in main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "defaults" +msgstr "預設值" + +#. ~ "eased" is a noise parameter flag. +#. It is used to make the map smoother and +#. can be enabled in noise settings in +#. main menu -> "All Settings". +#: builtin/mainmenu/dlg_settings_advanced.lua +msgid "eased" +msgstr "緩解 (eased)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 (Enabled)" +msgstr "$1(已啟用)" + +#: builtin/mainmenu/pkgmgr.lua +msgid "$1 mods" +msgstr "$1 個 Mod" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Failed to install $1 to $2" +msgstr "無法安裝 $1 至 $2" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find real mod name for: $1" +msgstr "安裝 Mod:找不到下述項目的真實 Mod 名稱:$1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Install Mod: Unable to find suitable folder name for modpack $1" +msgstr "安裝 Mod:找不到 $1 Mod 包適合的資料夾名稱" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to find a valid mod or modpack" +msgstr "找不到有效的 Mod 或 Mod 包" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a $1 as a texture pack" +msgstr "無法將 $1 安裝為材質包" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a game as a $1" +msgstr "無法將遊戲安裝為 $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a mod as a $1" +msgstr "無法將 Mod 安裝為 $1" + +#: builtin/mainmenu/pkgmgr.lua +msgid "Unable to install a modpack as a $1" +msgstr "無法將 Mod 包安裝為 $1" + +#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp +msgid "Loading..." +msgstr "正在載入..." + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Public server list is disabled" +msgstr "已停用公開伺服器列表" + +#: builtin/mainmenu/serverlistmgr.lua +msgid "Try reenabling public serverlist and check your internet connection." +msgstr "請嘗試重新啟用公共伺服器清單並檢查您的網際網路連線。" + +#: builtin/mainmenu/tab_about.lua +msgid "About" +msgstr "關於" + +#: builtin/mainmenu/tab_about.lua +msgid "Active Contributors" +msgstr "活躍的貢獻者" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Active renderer:" +msgstr "活動目標傳送範圍" + +#: builtin/mainmenu/tab_about.lua +msgid "Core Developers" +msgstr "核心開發者" + +#: builtin/mainmenu/tab_about.lua +msgid "Open User Data Directory" +msgstr "打開用戶資料目錄" + +#: builtin/mainmenu/tab_about.lua +msgid "" +"Opens the directory that contains user-provided worlds, games, mods,\n" +"and texture packs in a file manager / explorer." +msgstr "" +"在文件管理器/文件瀏覽器中打開包含\n" +"用戶提供的世界、遊戲、mod、材質包的目錄。" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Contributors" +msgstr "先前的貢獻者" + +#: builtin/mainmenu/tab_about.lua +msgid "Previous Core Developers" +msgstr "先前的核心開發者" + +#: builtin/mainmenu/tab_about.lua +#, fuzzy +msgid "Share debug log" +msgstr "顯示除錯資訊" + +#: builtin/mainmenu/tab_content.lua +msgid "Browse online content" +msgstr "瀏覽線上內容" + +#: builtin/mainmenu/tab_content.lua +msgid "Content" +msgstr "內容" + +#: builtin/mainmenu/tab_content.lua +msgid "Disable Texture Pack" +msgstr "停用材質包" + +#: builtin/mainmenu/tab_content.lua +msgid "Information:" +msgstr "資訊:" + +#: builtin/mainmenu/tab_content.lua +msgid "Installed Packages:" +msgstr "已安裝套件:" + +#: builtin/mainmenu/tab_content.lua +msgid "No dependencies." +msgstr "無相依元件。" + +#: builtin/mainmenu/tab_content.lua +msgid "No package description available" +msgstr "沒有可用的套件描述" + +#: builtin/mainmenu/tab_content.lua +msgid "Rename" +msgstr "重新命名" + +#: builtin/mainmenu/tab_content.lua +msgid "Uninstall Package" +msgstr "解除安裝套件" + +#: builtin/mainmenu/tab_content.lua +msgid "Use Texture Pack" +msgstr "使用材質包" + +#: builtin/mainmenu/tab_local.lua +msgid "Announce Server" +msgstr "公佈伺服器" + +#: builtin/mainmenu/tab_local.lua +msgid "Bind Address" +msgstr "綁定地址" + +#: builtin/mainmenu/tab_local.lua +msgid "Creative Mode" +msgstr "創造模式" + +#: builtin/mainmenu/tab_local.lua +msgid "Enable Damage" +msgstr "啟用傷害" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Game" +msgstr "主持遊戲" + +#: builtin/mainmenu/tab_local.lua +msgid "Host Server" +msgstr "主機伺服器" + +#: builtin/mainmenu/tab_local.lua +msgid "Install games from ContentDB" +msgstr "從 ContentDB 安裝遊戲" + +#: builtin/mainmenu/tab_local.lua +msgid "New" +msgstr "新增" + +#: builtin/mainmenu/tab_local.lua +msgid "No world created or selected!" +msgstr "未建立或選取世界!" + +#: builtin/mainmenu/tab_local.lua +msgid "Play Game" +msgstr "遊玩遊戲" + +#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua +msgid "Port" +msgstr "連線埠" + +#: builtin/mainmenu/tab_local.lua +msgid "Select Mods" +msgstr "選擇模組:" + +#: builtin/mainmenu/tab_local.lua +msgid "Select World:" +msgstr "選取世界:" + +#: builtin/mainmenu/tab_local.lua +msgid "Server Port" +msgstr "伺服器埠" + +#: builtin/mainmenu/tab_local.lua +msgid "Start Game" +msgstr "開始遊戲" + +#: builtin/mainmenu/tab_online.lua +msgid "Address" +msgstr "地址" + +#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp +msgid "Clear" +msgstr "清除" + +#: builtin/mainmenu/tab_online.lua +msgid "Creative mode" +msgstr "創造模式" + +#. ~ PvP = Player versus Player +#: builtin/mainmenu/tab_online.lua +msgid "Damage / PvP" +msgstr "傷害 / PvP" + +#: builtin/mainmenu/tab_online.lua +msgid "Favorites" +msgstr "收藏" + +#: builtin/mainmenu/tab_online.lua +msgid "Incompatible Servers" +msgstr "不相容的伺服器" + +#: builtin/mainmenu/tab_online.lua +msgid "Join Game" +msgstr "加入遊戲" + +#: builtin/mainmenu/tab_online.lua +msgid "Login" +msgstr "" + +#: builtin/mainmenu/tab_online.lua +msgid "Ping" +msgstr "Ping" + +#: builtin/mainmenu/tab_online.lua +msgid "Public Servers" +msgstr "公開伺服器" + +#: builtin/mainmenu/tab_online.lua +msgid "Refresh" +msgstr "重新整理" + +#: builtin/mainmenu/tab_online.lua +#, fuzzy +msgid "Remove favorite" +msgstr "遠端埠" + +#: builtin/mainmenu/tab_online.lua +msgid "Server Description" +msgstr "伺服器描述" + +#: builtin/mainmenu/tab_settings.lua +msgid "(game support required)" +msgstr "" + +#: builtin/mainmenu/tab_settings.lua +msgid "2x" +msgstr "2x" + +#: builtin/mainmenu/tab_settings.lua +msgid "3D Clouds" +msgstr "三維雲朵" + +#: builtin/mainmenu/tab_settings.lua +msgid "4x" +msgstr "4x" + +#: builtin/mainmenu/tab_settings.lua +msgid "8x" +msgstr "8x" + +#: builtin/mainmenu/tab_settings.lua +msgid "All Settings" +msgstr "所有設定" + +#: builtin/mainmenu/tab_settings.lua +msgid "Antialiasing:" +msgstr "反鋸齒:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Autosave Screen Size" +msgstr "自動儲存螢幕大小" + +#: builtin/mainmenu/tab_settings.lua +msgid "Bilinear Filter" +msgstr "雙線性過濾器" + +#: builtin/mainmenu/tab_settings.lua src/client/game.cpp +msgid "Change Keys" +msgstr "變更按鍵" + +#: builtin/mainmenu/tab_settings.lua +msgid "Connected Glass" +msgstr "連接玻璃" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Dynamic shadows" +msgstr "動態陰影" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Dynamic shadows:" +msgstr "動態陰影: " + +#: builtin/mainmenu/tab_settings.lua +msgid "Fancy Leaves" +msgstr "華麗葉子" + +#: builtin/mainmenu/tab_settings.lua +msgid "High" +msgstr "高" + +#: builtin/mainmenu/tab_settings.lua +msgid "Low" +msgstr "低" + +#: builtin/mainmenu/tab_settings.lua +msgid "Medium" +msgstr "中" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap" +msgstr "Mip 貼圖" + +#: builtin/mainmenu/tab_settings.lua +msgid "Mipmap + Aniso. Filter" +msgstr "Mip 貼圖 + Aniso. 過濾器" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Filter" +msgstr "沒有過濾器" + +#: builtin/mainmenu/tab_settings.lua +msgid "No Mipmap" +msgstr "沒有 Mip 貼圖" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Highlighting" +msgstr "突顯方塊" + +#: builtin/mainmenu/tab_settings.lua +msgid "Node Outlining" +msgstr "加入方塊外框" + +#: builtin/mainmenu/tab_settings.lua +msgid "None" +msgstr "無" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Leaves" +msgstr "不透明葉子" + +#: builtin/mainmenu/tab_settings.lua +msgid "Opaque Water" +msgstr "不透明水" + +#: builtin/mainmenu/tab_settings.lua +msgid "Particles" +msgstr "粒子" + +#: builtin/mainmenu/tab_settings.lua +msgid "Screen:" +msgstr "螢幕:" + +#: builtin/mainmenu/tab_settings.lua +msgid "Settings" +msgstr "設定" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Shaders" +msgstr "著色器" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (experimental)" +msgstr "著色器(實驗性)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Shaders (unavailable)" +msgstr "著色器(無法使用)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Simple Leaves" +msgstr "簡易葉子" + +#: builtin/mainmenu/tab_settings.lua +msgid "Smooth Lighting" +msgstr "平滑光線" + +#: builtin/mainmenu/tab_settings.lua +msgid "Texturing:" +msgstr "紋理:" + +#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp +msgid "Tone Mapping" +msgstr "色調映射" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Touch threshold (px):" +msgstr "觸控閾值:(像素)" + +#: builtin/mainmenu/tab_settings.lua +msgid "Trilinear Filter" +msgstr "三線性過濾器" + +#: builtin/mainmenu/tab_settings.lua +#, fuzzy +msgid "Very High" +msgstr "超高" + +#: builtin/mainmenu/tab_settings.lua +msgid "Very Low" +msgstr "很低" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Leaves" +msgstr "葉子擺動" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Liquids" +msgstr "擺動液體" + +#: builtin/mainmenu/tab_settings.lua +msgid "Waving Plants" +msgstr "植物擺動" + +#: src/client/client.cpp +#, fuzzy +msgid "Connection aborted (protocol error?)." +msgstr "連線錯誤(逾時?)" + +#: src/client/client.cpp src/client/game.cpp +msgid "Connection timed out." +msgstr "連線逾時。" + +#: src/client/client.cpp +msgid "Done!" +msgstr "完成!" + +#: src/client/client.cpp +msgid "Initializing nodes" +msgstr "正在初始化節點" + +#: src/client/client.cpp +msgid "Initializing nodes..." +msgstr "正在初始化節點..." + +#: src/client/client.cpp +msgid "Loading textures..." +msgstr "正在載入材質..." + +#: src/client/client.cpp +msgid "Rebuilding shaders..." +msgstr "正在重新組建著色器..." + +#: src/client/clientlauncher.cpp +msgid "Connection error (timed out?)" +msgstr "連線錯誤(逾時?)" + +#: src/client/clientlauncher.cpp +msgid "Could not find or load game: " +msgstr "找不到或無法載入遊戲: " + +#: src/client/clientlauncher.cpp +msgid "Invalid gamespec." +msgstr "遊戲規格無效。" + +#: src/client/clientlauncher.cpp +msgid "Main Menu" +msgstr "主選單" + +#: src/client/clientlauncher.cpp +msgid "No world selected and no address provided. Nothing to do." +msgstr "未有已被選取的世界,且未提供地址。無事可做。" + +#: src/client/clientlauncher.cpp +msgid "Player name too long." +msgstr "玩家名稱太長。" + +#: src/client/clientlauncher.cpp +msgid "Please choose a name!" +msgstr "請選擇名稱!" + +#: src/client/clientlauncher.cpp +msgid "Provided password file failed to open: " +msgstr "無法開啟提供的密碼檔案: " + +#: src/client/clientlauncher.cpp +msgid "Provided world path doesn't exist: " +msgstr "提供的世界路徑不存在: " + +#: src/client/game.cpp +msgid "" +"\n" +"Check debug.txt for details." +msgstr "" +"\n" +"檢視 debug.txt 以取得更多資訊。" + +#: src/client/game.cpp +msgid "- Address: " +msgstr "- 地址: " + +#: src/client/game.cpp +msgid "- Mode: " +msgstr "- 模式: " + +#: src/client/game.cpp +msgid "- Port: " +msgstr "- 連線埠: " + +#: src/client/game.cpp +msgid "- Public: " +msgstr "- 公開: " + +#. ~ PvP = Player versus Player +#: src/client/game.cpp +msgid "- PvP: " +msgstr "- PvP: " + +#: src/client/game.cpp +msgid "- Server Name: " +msgstr "- 伺服器名稱: " + +#: src/client/game.cpp +msgid "A serialization error occurred:" +msgstr "序列化時發生錯誤:" + +#: src/client/game.cpp +#, c-format +msgid "Access denied. Reason: %s" +msgstr "存取被拒絕。原因︰%s" + +#: src/client/game.cpp +msgid "Automatic forward disabled" +msgstr "已停用自動前進" + +#: src/client/game.cpp +msgid "Automatic forward enabled" +msgstr "已啟用自動前進" + +#: src/client/game.cpp +msgid "Block bounds hidden" +msgstr "區塊邊界隱藏" + +#: src/client/game.cpp +msgid "Block bounds shown for all blocks" +msgstr "區塊邊界顯示所有區塊" + +#: src/client/game.cpp +msgid "Block bounds shown for current block" +msgstr "區塊邊界顯示目前區塊" + +#: src/client/game.cpp +msgid "Block bounds shown for nearby blocks" +msgstr "區塊邊界顯示鄰接區塊" + +#: src/client/game.cpp +msgid "Camera update disabled" +msgstr "已停用相機更新" + +#: src/client/game.cpp +msgid "Camera update enabled" +msgstr "已啟用相機更新" + +#: src/client/game.cpp +#, fuzzy +msgid "Can't show block bounds (disabled by mod or game)" +msgstr "不能顯示區塊邊界 (需要「basic_debug」權限)" + +#: src/client/game.cpp +msgid "Change Password" +msgstr "變更密碼" + +#: src/client/game.cpp +msgid "Cinematic mode disabled" +msgstr "已停用電影模式" + +#: src/client/game.cpp +msgid "Cinematic mode enabled" +msgstr "已啟用電影模式" + +#: src/client/game.cpp +msgid "Client disconnected" +msgstr "用戶端已斷線" + +#: src/client/game.cpp +msgid "Client side scripting is disabled" +msgstr "已停用用戶端指令稿" + +#: src/client/game.cpp +msgid "Connecting to server..." +msgstr "正在連線至伺服器..." + +#: src/client/game.cpp +msgid "Connection failed for unknown reason" +msgstr "連線失敗,原因不明" + +#: src/client/game.cpp +msgid "Continue" +msgstr "繼續" + +#: src/client/game.cpp +#, c-format +msgid "" +"Controls:\n" +"- %s: move forwards\n" +"- %s: move backwards\n" +"- %s: move left\n" +"- %s: move right\n" +"- %s: jump/climb up\n" +"- %s: dig/punch\n" +"- %s: place/use\n" +"- %s: sneak/climb down\n" +"- %s: drop item\n" +"- %s: inventory\n" +"- Mouse: turn/look\n" +"- Mouse wheel: select item\n" +"- %s: chat\n" +msgstr "" +"控制:\n" +"- %s:向前移動\n" +"- %s:向後移動\n" +"- %s:向左移動\n" +"- %s:向右移動\n" +"- %s:跳躍/向上攀爬\n" +"- %s:挖/打\n" +"- %s:放置/使用\n" +"- %s:潛行/向下攀爬\n" +"- %s:丟棄物品\n" +"- %s:物品欄\n" +"- 滑鼠:旋轉/觀看\n" +"- 滑鼠滾輪:選取物品\n" +"- %s:聊天\n" + +#: src/client/game.cpp +#, c-format +msgid "Couldn't resolve address: %s" +msgstr "無法解析位址︰%s" + +#: src/client/game.cpp +msgid "Creating client..." +msgstr "正在建立用戶端..." + +#: src/client/game.cpp +msgid "Creating server..." +msgstr "正在建立伺服器..." + +#: src/client/game.cpp +msgid "Debug info and profiler graph hidden" +msgstr "已隱藏除錯資訊及分析圖" + +#: src/client/game.cpp +msgid "Debug info shown" +msgstr "已顯示除錯資訊" + +#: src/client/game.cpp +msgid "Debug info, profiler graph, and wireframe hidden" +msgstr "已隱藏除錯資訊、分析圖及線框" + +#: src/client/game.cpp +msgid "" +"Default Controls:\n" +"No menu visible:\n" +"- single tap: button activate\n" +"- double tap: place/use\n" +"- slide finger: look around\n" +"Menu/Inventory visible:\n" +"- double tap (outside):\n" +" -->close\n" +"- touch stack, touch slot:\n" +" --> move stack\n" +"- touch&drag, tap 2nd finger\n" +" --> place single item to slot\n" +msgstr "" +"預設控制:\n" +"無可見選單:\n" +"- 輕擊一次:啟動按鈕\n" +"- 輕擊兩次:放置/使用\n" +"- 滑動手指:轉動視角\n" +"檢視選單/物品欄:\n" +"- 輕擊兩次(外面):\n" +" -->關閉\n" +"- 碰觸堆疊,碰觸槽:\n" +" --> 移動堆疊\n" +"- 碰觸並拖曳,以第二隻手指輕擊\n" +" --> 放置單一物品到槽中\n" + +#: src/client/game.cpp +msgid "Disabled unlimited viewing range" +msgstr "已停用無限視野" + +#: src/client/game.cpp +msgid "Enabled unlimited viewing range" +msgstr "已啟用無限視野" + +#: src/client/game.cpp +#, fuzzy, c-format +msgid "Error creating client: %s" +msgstr "正在建立用戶端..." + +#: src/client/game.cpp +msgid "Exit to Menu" +msgstr "離開,回到選單" + +#: src/client/game.cpp +msgid "Exit to OS" +msgstr "離開,回到作業系統" + +#: src/client/game.cpp +msgid "Fast mode disabled" +msgstr "已停用快速模式" + +#: src/client/game.cpp +msgid "Fast mode enabled" +msgstr "已啟用快速模式" + +#: src/client/game.cpp +msgid "Fast mode enabled (note: no 'fast' privilege)" +msgstr "已啟用快速模式(註:沒有「fast」權限)" + +#: src/client/game.cpp +msgid "Fly mode disabled" +msgstr "已停用飛行模式" + +#: src/client/game.cpp +msgid "Fly mode enabled" +msgstr "已啟用飛行模式" + +#: src/client/game.cpp +msgid "Fly mode enabled (note: no 'fly' privilege)" +msgstr "已啟用飛行模式(註:沒有「fly」權限)" + +#: src/client/game.cpp +msgid "Fog disabled" +msgstr "已停用霧氣" + +#: src/client/game.cpp +msgid "Fog enabled" +msgstr "已啟用霧氣" + +#: src/client/game.cpp +msgid "Game info:" +msgstr "遊戲資訊:" + +#: src/client/game.cpp +msgid "Game paused" +msgstr "遊戲暫停" + +#: src/client/game.cpp +msgid "Hosting server" +msgstr "正在主持伺服器" + +#: src/client/game.cpp +msgid "Item definitions..." +msgstr "定義物品..." + +#: src/client/game.cpp +msgid "KiB/s" +msgstr "KiB/秒" + +#: src/client/game.cpp +msgid "Media..." +msgstr "媒體..." + +#: src/client/game.cpp +msgid "MiB/s" +msgstr "MiB/秒" + +#: src/client/game.cpp +msgid "Minimap currently disabled by game or mod" +msgstr "迷你地圖目前已被遊戲或 Mod 停用" + +#: src/client/game.cpp +msgid "Multiplayer" +msgstr "多人遊戲" + +#: src/client/game.cpp +msgid "Noclip mode disabled" +msgstr "已停用穿牆模式" + +#: src/client/game.cpp +msgid "Noclip mode enabled" +msgstr "已啟用穿牆模式" + +#: src/client/game.cpp +msgid "Noclip mode enabled (note: no 'noclip' privilege)" +msgstr "已啟用穿牆模式(註:沒有「noclip」權限)" + +#: src/client/game.cpp +msgid "Node definitions..." +msgstr "節點定義..." + +#: src/client/game.cpp +msgid "Off" +msgstr "關閉" + +#: src/client/game.cpp +msgid "On" +msgstr "開啟" + +#: src/client/game.cpp +msgid "Pitch move mode disabled" +msgstr "已停用 Pitch 移動模式" + +#: src/client/game.cpp +msgid "Pitch move mode enabled" +msgstr "已啟用 Pitch 移動模式" + +#: src/client/game.cpp +msgid "Profiler graph shown" +msgstr "已顯示分析圖" + +#: src/client/game.cpp +msgid "Remote server" +msgstr "遠端伺服器" + +#: src/client/game.cpp +msgid "Resolving address..." +msgstr "正在解析地址……" + +#: src/client/game.cpp +msgid "Shutting down..." +msgstr "正在關閉..." + +#: src/client/game.cpp +msgid "Singleplayer" +msgstr "單人遊戲" + +#: src/client/game.cpp +msgid "Sound Volume" +msgstr "音量" + +#: src/client/game.cpp +msgid "Sound muted" +msgstr "已靜音" + +#: src/client/game.cpp +msgid "Sound system is disabled" +msgstr "聲音系統已被禁用" + +#: src/client/game.cpp +msgid "Sound system is not supported on this build" +msgstr "此編譯版本不支持聲音系統" + +#: src/client/game.cpp +msgid "Sound unmuted" +msgstr "已取消靜音" + +#: src/client/game.cpp +#, c-format +msgid "The server is probably running a different version of %s." +msgstr "此伺服器可能執行的是不同版本的 %s。" + +#: src/client/game.cpp +#, c-format +msgid "Unable to connect to %s because IPv6 is disabled" +msgstr "無法連線至 %s 因為 IPv6 已停用" + +#: src/client/game.cpp +#, c-format +msgid "Unable to listen on %s because IPv6 is disabled" +msgstr "無法聽取 %s 因為 IPv6 已停用" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range changed to %d" +msgstr "已調整視野至 %d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at maximum: %d" +msgstr "視野已為最大值:%d" + +#: src/client/game.cpp +#, c-format +msgid "Viewing range is at minimum: %d" +msgstr "視野已為最小值:%d" + +#: src/client/game.cpp +#, c-format +msgid "Volume changed to %d%%" +msgstr "音量已調整為 %d%%" + +#: src/client/game.cpp +msgid "Wireframe shown" +msgstr "已顯示線框" + +#: src/client/game.cpp +msgid "Zoom currently disabled by game or mod" +msgstr "遠近調整目前已被遊戲或模組停用" + +#: src/client/game.cpp +msgid "ok" +msgstr "確定" + +#: src/client/gameui.cpp +msgid "Chat hidden" +msgstr "隱藏聊天室" + +#: src/client/gameui.cpp +msgid "Chat shown" +msgstr "顯示聊天室" + +#: src/client/gameui.cpp +msgid "HUD hidden" +msgstr "已隱藏 HUD" + +#: src/client/gameui.cpp +msgid "HUD shown" +msgstr "已顯示 HUD" + +#: src/client/gameui.cpp +msgid "Profiler hidden" +msgstr "已隱藏分析器" + +#: src/client/gameui.cpp +#, c-format +msgid "Profiler shown (page %d of %d)" +msgstr "已顯示分析器(第 %d 頁,共 %d 頁)" + +#: src/client/keycode.cpp +msgid "Apps" +msgstr "應用程式" + +#: src/client/keycode.cpp +msgid "Backspace" +msgstr "退格鍵" + +#: src/client/keycode.cpp +msgid "Caps Lock" +msgstr "大寫鎖定鍵" + +#: src/client/keycode.cpp +msgid "Control" +msgstr "Control" + +#: src/client/keycode.cpp +msgid "Down" +msgstr "下" + +#: src/client/keycode.cpp +msgid "End" +msgstr "End" + +#: src/client/keycode.cpp +msgid "Erase EOF" +msgstr "抹除 EOF" + +#: src/client/keycode.cpp +msgid "Execute" +msgstr "執行" + +#: src/client/keycode.cpp +msgid "Help" +msgstr "說明" + +#: src/client/keycode.cpp +msgid "Home" +msgstr "Home" + +#: src/client/keycode.cpp +msgid "IME Accept" +msgstr "接受 IME" + +#: src/client/keycode.cpp +msgid "IME Convert" +msgstr "轉換 IME" + +#: src/client/keycode.cpp +msgid "IME Escape" +msgstr "跳脫 IME" + +#: src/client/keycode.cpp +msgid "IME Mode Change" +msgstr "IME 模式變更" + +#: src/client/keycode.cpp +msgid "IME Nonconvert" +msgstr "IME 不轉換" + +#: src/client/keycode.cpp +msgid "Insert" +msgstr "插入" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Left" +msgstr "左" + +#: src/client/keycode.cpp +msgid "Left Button" +msgstr "左鍵" + +#: src/client/keycode.cpp +msgid "Left Control" +msgstr "左 Control" + +#: src/client/keycode.cpp +msgid "Left Menu" +msgstr "左選單鍵" + +#: src/client/keycode.cpp +msgid "Left Shift" +msgstr "左 Shift" + +#: src/client/keycode.cpp +msgid "Left Windows" +msgstr "左 Windows 鍵" + +#. ~ Key name, common on Windows keyboards +#: src/client/keycode.cpp +msgid "Menu" +msgstr "選單" + +#: src/client/keycode.cpp +msgid "Middle Button" +msgstr "中鍵" + +#: src/client/keycode.cpp +msgid "Num Lock" +msgstr "數字鎖定鍵" + +#: src/client/keycode.cpp +msgid "Numpad *" +msgstr "數字鍵 *" + +#: src/client/keycode.cpp +msgid "Numpad +" +msgstr "數字鍵 +" + +#: src/client/keycode.cpp +msgid "Numpad -" +msgstr "數字鍵 -" + +#: src/client/keycode.cpp +msgid "Numpad ." +msgstr "數字鍵 ." + +#: src/client/keycode.cpp +msgid "Numpad /" +msgstr "數字鍵 /" + +#: src/client/keycode.cpp +msgid "Numpad 0" +msgstr "數字鍵 0" + +#: src/client/keycode.cpp +msgid "Numpad 1" +msgstr "數字鍵 1" + +#: src/client/keycode.cpp +msgid "Numpad 2" +msgstr "數字鍵 2" + +#: src/client/keycode.cpp +msgid "Numpad 3" +msgstr "數字鍵 3" + +#: src/client/keycode.cpp +msgid "Numpad 4" +msgstr "數字鍵 4" + +#: src/client/keycode.cpp +msgid "Numpad 5" +msgstr "數字鍵 5" + +#: src/client/keycode.cpp +msgid "Numpad 6" +msgstr "數字鍵 6" + +#: src/client/keycode.cpp +msgid "Numpad 7" +msgstr "數字鍵 7" + +#: src/client/keycode.cpp +msgid "Numpad 8" +msgstr "數字鍵 8" + +#: src/client/keycode.cpp +msgid "Numpad 9" +msgstr "數字鍵 9" + +#: src/client/keycode.cpp +msgid "OEM Clear" +msgstr "OEM 清除" + +#: src/client/keycode.cpp +msgid "Page down" +msgstr "Page down" + +#: src/client/keycode.cpp +msgid "Page up" +msgstr "Page up" + +#: src/client/keycode.cpp +msgid "Pause" +msgstr "暫停" + +#: src/client/keycode.cpp +msgid "Play" +msgstr "遊玩" + +#. ~ "Print screen" key +#: src/client/keycode.cpp +msgid "Print" +msgstr "列印" + +#: src/client/keycode.cpp +msgid "Return" +msgstr "Return" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Right" +msgstr "右" + +#: src/client/keycode.cpp +msgid "Right Button" +msgstr "右鍵" + +#: src/client/keycode.cpp +msgid "Right Control" +msgstr "右 Control" + +#: src/client/keycode.cpp +msgid "Right Menu" +msgstr "右選單鍵" + +#: src/client/keycode.cpp +msgid "Right Shift" +msgstr "右 Shift" + +#: src/client/keycode.cpp +msgid "Right Windows" +msgstr "右 Windows 鍵" + +#: src/client/keycode.cpp +msgid "Scroll Lock" +msgstr "捲動鎖定鍵" + +#. ~ Key name +#: src/client/keycode.cpp +msgid "Select" +msgstr "選擇" + +#: src/client/keycode.cpp +msgid "Shift" +msgstr "Shift" + +#: src/client/keycode.cpp +msgid "Sleep" +msgstr "睡眠" + +#: src/client/keycode.cpp +msgid "Snapshot" +msgstr "快照" + +#: src/client/keycode.cpp +msgid "Space" +msgstr "空白鍵" + +#: src/client/keycode.cpp +msgid "Tab" +msgstr "Tab" + +#: src/client/keycode.cpp +msgid "Up" +msgstr "上" + +#: src/client/keycode.cpp +msgid "X Button 1" +msgstr "X 按鈕 1" + +#: src/client/keycode.cpp +msgid "X Button 2" +msgstr "X 按鈕 2" + +#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp +msgid "Zoom" +msgstr "遠近調整" + +#: src/client/minimap.cpp +msgid "Minimap hidden" +msgstr "已隱藏迷你地圖" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in radar mode, Zoom x%d" +msgstr "雷達模式的迷你地圖,放大 %d 倍" + +#: src/client/minimap.cpp +#, c-format +msgid "Minimap in surface mode, Zoom x%d" +msgstr "表面模式的迷你地圖,放大 %d 倍" + +#: src/client/minimap.cpp +msgid "Minimap in texture mode" +msgstr "材質模式的迷你地圖" + +#: src/gui/guiChatConsole.cpp +msgid "Failed to open webpage" +msgstr "無法開啟網頁" + +#: src/gui/guiChatConsole.cpp +msgid "Opening webpage" +msgstr "正在開啟網頁" + +#: src/gui/guiFormSpecMenu.cpp +msgid "Proceed" +msgstr "繼續" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "\"Aux1\" = climb down" +msgstr "\"Aux1\" = 向下攀爬" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Autoforward" +msgstr "自動前進" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Automatic jumping" +msgstr "自動跳躍" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Aux1" +msgstr "Aux1" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Backward" +msgstr "後退" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Block bounds" +msgstr "區塊邊界" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Change camera" +msgstr "變更相機" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Chat" +msgstr "聊天" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Command" +msgstr "指令" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Console" +msgstr "終端機" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. range" +msgstr "降低視野" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Dec. volume" +msgstr "降低音量" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Double tap \"jump\" to toggle fly" +msgstr "輕擊兩次「跳躍」以切換成飛行" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Drop" +msgstr "丟棄" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Forward" +msgstr "前進" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. range" +msgstr "提高視野" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inc. volume" +msgstr "提高音量" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Inventory" +msgstr "物品欄" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Jump" +msgstr "跳躍" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Key already in use" +msgstr "已使用此按鍵" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Keybindings." +msgstr "" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Local command" +msgstr "本機指令" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Mute" +msgstr "靜音" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Next item" +msgstr "下一個物品" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Prev. item" +msgstr "上一個物品" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Range select" +msgstr "選擇範圍" + +#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp +msgid "Screenshot" +msgstr "螢幕擷取" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Sneak" +msgstr "潛行" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle HUD" +msgstr "切換 HUD" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle chat log" +msgstr "切換聊天記錄" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fast" +msgstr "切換快速模式" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fly" +msgstr "切換飛行模式" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle fog" +msgstr "切換霧氣" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle minimap" +msgstr "切換迷你地圖" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle noclip" +msgstr "切換穿牆模式" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "Toggle pitchmove" +msgstr "切換 Pitch 移動模式" + +#: src/gui/guiKeyChangeMenu.cpp +msgid "press key" +msgstr "按下按鍵" + +#: src/gui/guiPasswordChange.cpp +msgid "Change" +msgstr "變更" + +#: src/gui/guiPasswordChange.cpp +msgid "New Password" +msgstr "新密碼" + +#: src/gui/guiPasswordChange.cpp +msgid "Old Password" +msgstr "舊密碼" + +#: src/gui/guiPasswordChange.cpp +msgid "Passwords do not match!" +msgstr "密碼不符合!" + +#: src/gui/guiVolumeChange.cpp +msgid "Exit" +msgstr "離開" + +#: src/gui/guiVolumeChange.cpp +msgid "Muted" +msgstr "已靜音" + +#: src/gui/guiVolumeChange.cpp +#, c-format +msgid "Sound Volume: %d%%" +msgstr "音量:%d%%" + +#. ~ DO NOT TRANSLATE THIS LITERALLY! +#. This is a special string which needs to contain the translation's +#. language code (e.g. "de" for German). +#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp +msgid "LANG_CODE" +msgstr "zh_TW" + +#: src/network/clientpackethandler.cpp +msgid "" +"Name is not registered. To create an account on this server, click 'Register'" +msgstr "" + +#: src/network/clientpackethandler.cpp +#, fuzzy +msgid "Name is taken. Please choose another name" +msgstr "請選擇名稱!" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Fixes the position of virtual joystick.\n" +"If disabled, virtual joystick will center to first-touch's position." +msgstr "" +"(Android) 修正虛擬搖桿的位置。\n" +"如停用,虛擬搖桿將會置中於第一個觸碰的位置。" + +#: src/settings_translation_file.cpp +msgid "" +"(Android) Use virtual joystick to trigger \"Aux1\" button.\n" +"If enabled, virtual joystick will also tap \"Aux1\" button when out of main " +"circle." +msgstr "" +"(Android) 使用虛擬搖桿觸發 \"Aux1\" 按鍵。\n" +"如果啟用,虛擬搖桿在離開主圓圈時也會觸發 \"Aux1\" 按鍵。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n" +"Can be used to move a desired point to (0, 0) to create a\n" +"suitable spawn point, or to allow 'zooming in' on a desired\n" +"point by increasing 'scale'.\n" +"The default is tuned for a suitable spawn point for Mandelbrot\n" +"sets with default parameters, it may need altering in other\n" +"situations.\n" +"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes." +msgstr "" +"在「比例尺」中單位的 (X,Y,Z) 偏移。\n" +"用於移動適合的低地生成區域靠近 (0, 0)。\n" +"預設值適合曼德博集合,若要用於朱利亞集合則必須修改。\n" +"範圍大約在 -2 至 2 間。乘以節點的偏移值。" + +#: src/settings_translation_file.cpp +msgid "" +"(X,Y,Z) scale of fractal in nodes.\n" +"Actual fractal size will be 2 to 3 times larger.\n" +"These numbers can be made very large, the fractal does\n" +"not have to fit inside the world.\n" +"Increase these to 'zoom' into the detail of the fractal.\n" +"Default is for a vertically-squashed shape suitable for\n" +"an island, set all 3 numbers equal for the raw shape." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of ridged mountains." +msgstr "控制山脊之形狀或大小的 2D 雜訊值。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of rolling hills." +msgstr "控制波狀丘陵地之形狀或大小的 2D 雜訊值。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the shape/size of step mountains." +msgstr "控制階梯山脈之形狀或大小的 2D 雜訊值。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of ridged mountain ranges." +msgstr "控制山脊範圍之大小或產狀的 2D 雜訊值。" + +#: src/settings_translation_file.cpp +msgid "2D noise that controls the size/occurrence of rolling hills." +msgstr "控制波狀丘陵地之大小或產狀的 2D 雜訊值。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "2D noise that controls the size/occurrence of step mountain ranges." +msgstr "控制 Step mountains 範圍之形狀或大小的 2D 雜訊值。" + +#: src/settings_translation_file.cpp +msgid "2D noise that locates the river valleys and channels." +msgstr "定位河谷及河道的 2D 雜訊值。" + +#: src/settings_translation_file.cpp +msgid "3D clouds" +msgstr "3D 雲朵" + +#: src/settings_translation_file.cpp +msgid "3D mode" +msgstr "3D 模式" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "3D mode parallax strength" +msgstr "法線貼圖強度" + +#: src/settings_translation_file.cpp +msgid "3D noise defining giant caverns." +msgstr "定義大型洞穴時用的雜訊值。" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining mountain structure and height.\n" +"Also defines structure of floatland mountain terrain." +msgstr "" +"定義高山結構與高度所用的 3D 雜訊值。\n" +"同時用來定義空島山地形結構。" + +#: src/settings_translation_file.cpp +msgid "" +"3D noise defining structure of floatlands.\n" +"If altered from the default, the noise 'scale' (0.7 by default) may need\n" +"to be adjusted, as floatland tapering functions best when this noise has\n" +"a value range of approximately -2.0 to 2.0." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "3D noise defining structure of river canyon walls." +msgstr "定義河流峽谷結構所用的 3D 雜訊值。" + +#: src/settings_translation_file.cpp +msgid "3D noise defining terrain." +msgstr "定義地形所用的 3D 雜訊值。" + +#: src/settings_translation_file.cpp +msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations." +msgstr "懸空、懸崖等山丘的 3D 雜訊值。通常是小變異。" + +#: src/settings_translation_file.cpp +msgid "3D noise that determines number of dungeons per mapchunk." +msgstr "決定每個地圖區塊中地城數量的 3D 雜訊值。" + +#: src/settings_translation_file.cpp +msgid "" +"3D support.\n" +"Currently supported:\n" +"- none: no 3d output.\n" +"- anaglyph: cyan/magenta color 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side.\n" +"- crossview: Cross-eyed 3d\n" +"- pageflip: quadbuffer based 3d.\n" +"Note that the interlaced mode requires shaders to be enabled." +msgstr "" +"3D 支援。\n" +"目前已支援:\n" +"- none:無 3D 輸出。\n" +"- anaglyph:青色/品紅色彩色 3D。\n" +"- interlaced:基於偏振螢幕的奇/偶行支援。\n" +"- topbottom:將螢幕分成頂/底部。\n" +"- sidebyside:將螢幕分離為一邊一個。\n" +"- crossview: 鬥雞眼式 3D\n" +"- pageflip:基於四重緩衝的 3D。\n" +"註:interlaced 模式需要啟用著色器。" + +#: src/settings_translation_file.cpp +msgid "3d" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"A chosen map seed for a new map, leave empty for random.\n" +"Will be overridden when creating a new world in the main menu." +msgstr "" +"新地圖的已選取種子,留空則為隨機。\n" +"當在主選單中建立新世界的時候將會被覆寫。" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server crashes." +msgstr "當伺服器當機時要顯示在所有用戶端上的訊息。" + +#: src/settings_translation_file.cpp +msgid "A message to be displayed to all clients when the server shuts down." +msgstr "當伺服器關機時要顯示在所有用戶端上的訊息。" + +#: src/settings_translation_file.cpp +msgid "ABM interval" +msgstr "ABM 間隔" + +#: src/settings_translation_file.cpp +msgid "ABM time budget" +msgstr "ABM 時間預算" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Absolute limit of queued blocks to emerge" +msgstr "發生佇列的絕對限制" + +#: src/settings_translation_file.cpp +msgid "Acceleration in air" +msgstr "空氣中的加速度" + +#: src/settings_translation_file.cpp +msgid "Acceleration of gravity, in nodes per second per second." +msgstr "每秒中每秒節點的重力加速度。" + +#: src/settings_translation_file.cpp +msgid "Active Block Modifiers" +msgstr "活動區塊調整器" + +#: src/settings_translation_file.cpp +msgid "Active block management interval" +msgstr "活動區塊管理間隔" + +#: src/settings_translation_file.cpp +msgid "Active block range" +msgstr "活動區塊範圍" + +#: src/settings_translation_file.cpp +msgid "Active object send range" +msgstr "活動目標傳送範圍" + +#: src/settings_translation_file.cpp +msgid "" +"Address to connect to.\n" +"Leave this blank to start a local server.\n" +"Note that the address field in the main menu overrides this setting." +msgstr "" +"要連線到的地址。\n" +"把這個留空以啟動本機伺服器。\n" +"注意在主選單中的地址欄會覆寫這個設定。" + +#: src/settings_translation_file.cpp +msgid "Adds particles when digging a node." +msgstr "當挖掘節點時加入一些粒子。" + +#: src/settings_translation_file.cpp +msgid "" +"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " +"screens." +msgstr "調整您螢幕的 DPI 設定(並不只有 X11/Android)例如 4K 螢幕。" + +#: src/settings_translation_file.cpp +msgid "Adjust the detected display density, used for scaling UI elements." +msgstr "調整偵測到的顯示密度,用來縮放 UI 元件。" + +#: src/settings_translation_file.cpp +#, c-format +msgid "" +"Adjusts the density of the floatland layer.\n" +"Increase value to increase density. Can be positive or negative.\n" +"Value = 0.0: 50% of volume is floatland.\n" +"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n" +"to be sure) creates a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Admin name" +msgstr "將物品名稱加至末尾" + +#: src/settings_translation_file.cpp +msgid "Advanced" +msgstr "進階" + +#: src/settings_translation_file.cpp +msgid "" +"Alters the light curve by applying 'gamma correction' to it.\n" +"Higher values make middle and lower light levels brighter.\n" +"Value '1.0' leaves the light curve unaltered.\n" +"This only has significant effect on daylight and artificial\n" +"light, it has very little effect on natural night light." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Always fly fast" +msgstr "總是啟用飛行與快速模式" + +#: src/settings_translation_file.cpp +msgid "Ambient occlusion gamma" +msgstr "環境遮蔽光" + +#: src/settings_translation_file.cpp +msgid "Amount of messages a player may send per 10 seconds." +msgstr "玩家每 10 秒能傳送的訊息量" + +#: src/settings_translation_file.cpp +msgid "Amplifies the valleys." +msgstr "放大山谷。" + +#: src/settings_translation_file.cpp +msgid "Anisotropic filtering" +msgstr "各向異性過濾" + +#: src/settings_translation_file.cpp +msgid "Announce server" +msgstr "公佈伺服器" + +#: src/settings_translation_file.cpp +msgid "Announce to this serverlist." +msgstr "公佈至此伺服器清單。" + +#: src/settings_translation_file.cpp +msgid "Append item name" +msgstr "將物品名稱加至末尾" + +#: src/settings_translation_file.cpp +msgid "Append item name to tooltip." +msgstr "將物品名稱加至工具提示的末尾。" + +#: src/settings_translation_file.cpp +msgid "Apple trees noise" +msgstr "蘋果樹雜訊" + +#: src/settings_translation_file.cpp +msgid "Arm inertia" +msgstr "慣性手臂" + +#: src/settings_translation_file.cpp +msgid "" +"Arm inertia, gives a more realistic movement of\n" +"the arm when the camera moves." +msgstr "" +"慣性手臂,當相機移動時提供\n" +"更加真實的手臂運動。" + +#: src/settings_translation_file.cpp +msgid "Ask to reconnect after crash" +msgstr "詢問是否在當機後重新連線" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"At this distance the server will aggressively optimize which blocks are sent " +"to\n" +"clients.\n" +"Small values potentially improve performance a lot, at the expense of " +"visible\n" +"rendering glitches (some blocks will not be rendered under water and in " +"caves,\n" +"as well as sometimes on land).\n" +"Setting this to a value greater than max_block_send_distance disables this\n" +"optimization.\n" +"Stated in mapblocks (16 nodes)." +msgstr "" +"在這樣的距離下,伺服器將積極最佳化那些要傳送給用戶端的方塊。\n" +"較小的值可能會提升效能,但代價是一些可見的彩現問題。\n" +"(有一些在水中與洞穴中的方塊將不會被彩現,以及有時在陸地上)\n" +"將此值設定為大於 max_block_send_distance 將會停用這個最佳化。\n" +"在地圖區塊中顯示(16 個節點)" + +#: src/settings_translation_file.cpp +msgid "Audio" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Automatic forward key" +msgstr "自動前進鍵" + +#: src/settings_translation_file.cpp +msgid "Automatically jump up single-node obstacles." +msgstr "自動跳過單個障礙物。" + +#: src/settings_translation_file.cpp +msgid "Automatically report to the serverlist." +msgstr "自動回報到伺服器列表。" + +#: src/settings_translation_file.cpp +msgid "Autosave screen size" +msgstr "自動儲存視窗大小" + +#: src/settings_translation_file.cpp +msgid "Autoscaling mode" +msgstr "自動縮放模式" + +#: src/settings_translation_file.cpp +msgid "Aux1 key" +msgstr "Aux1 鍵" + +#: src/settings_translation_file.cpp +msgid "Aux1 key for climbing/descending" +msgstr "用於攀爬/下降的 Aux1 按鍵" + +#: src/settings_translation_file.cpp +msgid "Backward key" +msgstr "後退鍵" + +#: src/settings_translation_file.cpp +msgid "Base ground level" +msgstr "基礎地平面" + +#: src/settings_translation_file.cpp +msgid "Base terrain height." +msgstr "基礎地形高度。" + +#: src/settings_translation_file.cpp +msgid "Basic privileges" +msgstr "基礎特權" + +#: src/settings_translation_file.cpp +msgid "Beach noise" +msgstr "海灘雜訊" + +#: src/settings_translation_file.cpp +msgid "Beach noise threshold" +msgstr "海灘雜訊閾值" + +#: src/settings_translation_file.cpp +msgid "Bilinear filtering" +msgstr "雙線性過濾器" + +#: src/settings_translation_file.cpp +msgid "Bind address" +msgstr "綁定地址" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Biome API noise parameters" +msgstr "Biome API 溫度與濕度 雜訊 參數" + +#: src/settings_translation_file.cpp +msgid "Biome noise" +msgstr "生物雜訊" + +#: src/settings_translation_file.cpp +msgid "Block send optimize distance" +msgstr "區塊傳送最佳化距離" + +#: src/settings_translation_file.cpp +msgid "Bobbing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Bold and italic font path" +msgstr "粗體與斜體字型路徑" + +#: src/settings_translation_file.cpp +msgid "Bold and italic monospace font path" +msgstr "粗體與斜體等寬字型路徑" + +#: src/settings_translation_file.cpp +msgid "Bold font path" +msgstr "粗體字型路徑" + +#: src/settings_translation_file.cpp +msgid "Bold monospace font path" +msgstr "粗體等寬字型路徑" + +#: src/settings_translation_file.cpp +msgid "Build inside player" +msgstr "在玩家內構建" + +#: src/settings_translation_file.cpp +msgid "Builtin" +msgstr "內建" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Camera" +msgstr "變更相機" + +#: src/settings_translation_file.cpp +msgid "" +"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n" +"Only works on GLES platforms. Most users will not need to change this.\n" +"Increasing can reduce artifacting on weaker GPUs.\n" +"0.1 = Default, 0.25 = Good value for weaker tablets." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing" +msgstr "攝影機平滑" + +#: src/settings_translation_file.cpp +msgid "Camera smoothing in cinematic mode" +msgstr "在電影模式中攝影機平滑" + +#: src/settings_translation_file.cpp +msgid "Camera update toggle key" +msgstr "攝影機切換更新按鍵" + +#: src/settings_translation_file.cpp +msgid "Cave noise" +msgstr "洞穴雜訊" + +#: src/settings_translation_file.cpp +msgid "Cave noise #1" +msgstr "洞穴雜訊 #1" + +#: src/settings_translation_file.cpp +msgid "Cave noise #2" +msgstr "洞穴雜訊 #2" + +#: src/settings_translation_file.cpp +msgid "Cave width" +msgstr "洞穴寬度" + +#: src/settings_translation_file.cpp +msgid "Cave1 noise" +msgstr "洞穴1 雜訊" + +#: src/settings_translation_file.cpp +msgid "Cave2 noise" +msgstr "洞穴2 雜訊" + +#: src/settings_translation_file.cpp +msgid "Cavern limit" +msgstr "洞穴極限" + +#: src/settings_translation_file.cpp +msgid "Cavern noise" +msgstr "洞穴雜訊" + +#: src/settings_translation_file.cpp +msgid "Cavern taper" +msgstr "洞穴錐形程度" + +#: src/settings_translation_file.cpp +msgid "Cavern threshold" +msgstr "洞穴閾值" + +#: src/settings_translation_file.cpp +msgid "Cavern upper limit" +msgstr "洞穴上層極限" + +#: src/settings_translation_file.cpp +msgid "" +"Center of light curve boost range.\n" +"Where 0.0 is minimum light level, 1.0 is maximum light level." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Chat command time message threshold" +msgstr "聊天訊息踢出閾值" + +#: src/settings_translation_file.cpp +msgid "Chat commands" +msgstr "聊天指令" + +#: src/settings_translation_file.cpp +msgid "Chat font size" +msgstr "聊天字型大小" + +#: src/settings_translation_file.cpp +msgid "Chat key" +msgstr "聊天按鍵" + +#: src/settings_translation_file.cpp +msgid "Chat log level" +msgstr "聊天記錄等級" + +#: src/settings_translation_file.cpp +msgid "Chat message count limit" +msgstr "聊天訊息數上限" + +#: src/settings_translation_file.cpp +msgid "Chat message format" +msgstr "聊天訊息格式" + +#: src/settings_translation_file.cpp +msgid "Chat message kick threshold" +msgstr "聊天訊息踢出閾值" + +#: src/settings_translation_file.cpp +msgid "Chat message max length" +msgstr "聊天訊息長度上限" + +#: src/settings_translation_file.cpp +msgid "Chat toggle key" +msgstr "聊天切換按鍵" + +#: src/settings_translation_file.cpp +msgid "Chat weblinks" +msgstr "顯示網頁連結" + +#: src/settings_translation_file.cpp +msgid "Chunk size" +msgstr "方塊大小" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode" +msgstr "電影模式" + +#: src/settings_translation_file.cpp +msgid "Cinematic mode key" +msgstr "電影模式按鍵" + +#: src/settings_translation_file.cpp +msgid "Clean transparent textures" +msgstr "清除透明材質" + +#: src/settings_translation_file.cpp +msgid "" +"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console " +"output." +msgstr "在聊天室主控台輸出中可以點選網頁連結 (滑鼠中鍵或 Ctrl+left-單擊)。" + +#: src/settings_translation_file.cpp +msgid "Client" +msgstr "用戶端" + +#: src/settings_translation_file.cpp +msgid "Client and Server" +msgstr "用戶端與伺服器" + +#: src/settings_translation_file.cpp +msgid "Client modding" +msgstr "用戶端修改" + +#: src/settings_translation_file.cpp +msgid "Client side modding restrictions" +msgstr "用戶端修改限制" + +#: src/settings_translation_file.cpp +msgid "Client side node lookup range restriction" +msgstr "用戶端節點查詢範圍限制" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Client-side Modding" +msgstr "用戶端修改" + +#: src/settings_translation_file.cpp +msgid "Climbing speed" +msgstr "攀爬速度" + +#: src/settings_translation_file.cpp +msgid "Cloud radius" +msgstr "雲朵範圍" + +#: src/settings_translation_file.cpp +msgid "Clouds" +msgstr "雲朵" + +#: src/settings_translation_file.cpp +msgid "Clouds are a client side effect." +msgstr "雲朵是用戶端的特效。" + +#: src/settings_translation_file.cpp +msgid "Clouds in menu" +msgstr "選單中的雲朵" + +#: src/settings_translation_file.cpp +msgid "Colored fog" +msgstr "彩色迷霧" + +#: src/settings_translation_file.cpp +msgid "Colored shadows" +msgstr "彩色陰影" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of flags to hide in the content repository.\n" +"\"nonfree\" can be used to hide packages which do not qualify as 'free " +"software',\n" +"as defined by the Free Software Foundation.\n" +"You can also specify content ratings.\n" +"These flags are independent from Minetest versions,\n" +"so see a full list at https://content.minetest.net/help/content_flags/" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of mods that are allowed to access HTTP APIs, which\n" +"allow them to upload and download data to/from the internet." +msgstr "" +"以逗號分隔的 mod 清單,允許其存取 HTTP API,\n" +"從而網際網路上傳及下載資料。" + +#: src/settings_translation_file.cpp +msgid "" +"Comma-separated list of trusted mods that are allowed to access insecure\n" +"functions even when mod security is on (via request_insecure_environment())." +msgstr "" +"受信任的 Mod 列表,以逗號分隔,其可存取不安全的\n" +"功能,即便 mod 安全性是(經由 request_insecure_environment())。" + +#: src/settings_translation_file.cpp +msgid "Command key" +msgstr "指令按鍵" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when saving mapblocks to disk.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Compression level to use when sending mapblocks to the client.\n" +"-1 - use default compression level\n" +"0 - least compression, fastest\n" +"9 - best compression, slowest" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Connect glass" +msgstr "連接玻璃" + +#: src/settings_translation_file.cpp +msgid "Connect to external media server" +msgstr "連線至外部媒體伺服器" + +#: src/settings_translation_file.cpp +msgid "Connects glass if supported by node." +msgstr "若節點支援則連接玻璃。" + +#: src/settings_translation_file.cpp +msgid "Console alpha" +msgstr "終端機 alpha 值" + +#: src/settings_translation_file.cpp +msgid "Console color" +msgstr "終端機顏色" + +#: src/settings_translation_file.cpp +msgid "Console height" +msgstr "終端機高度" + +#: src/settings_translation_file.cpp +msgid "Content Repository" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "ContentDB Flag Blacklist" +msgstr "ContentDB 旗標黑名單列表" + +#: src/settings_translation_file.cpp +msgid "ContentDB Max Concurrent Downloads" +msgstr "ContentDB 最大並行下載數" + +#: src/settings_translation_file.cpp +msgid "ContentDB URL" +msgstr "ContentDB URL" + +#: src/settings_translation_file.cpp +msgid "Continuous forward" +msgstr "連續前進" + +#: src/settings_translation_file.cpp +msgid "" +"Continuous forward movement, toggled by autoforward key.\n" +"Press the autoforward key again or the backwards movement to disable." +msgstr "" +"連續前進,通過自動前進鍵切換。\n" +"再次按自動前進鍵或向後移動即可禁用。" + +#: src/settings_translation_file.cpp +msgid "Controls" +msgstr "控制" + +#: src/settings_translation_file.cpp +msgid "" +"Controls length of day/night cycle.\n" +"Examples:\n" +"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged." +msgstr "" +"控制日/夜循環的長度。\n" +"範例:\n" +"72 = 20分鐘,360 = 4分鐘,1 = 24小時,0 = 日/夜/一切保持不變。" + +#: src/settings_translation_file.cpp +msgid "" +"Controls sinking speed in liquid when idling. Negative values will cause\n" +"you to rise instead." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/depth of lake depressions." +msgstr "控制湖泊窪地的陡度/深度。" + +#: src/settings_translation_file.cpp +msgid "Controls steepness/height of hills." +msgstr "控制山丘的陡度/深度。" + +#: src/settings_translation_file.cpp +msgid "" +"Controls width of tunnels, a smaller value creates wider tunnels.\n" +"Value >= 10.0 completely disables generation of tunnels and avoids the\n" +"intensive noise calculations." +msgstr "" +"控制隧道的寬度,較小的值將創建較寬的隧道。\n" +"數值 > = 10.0 完全禁用了隧道的生成,並避免了\n" +"密集的噪聲計算。" + +#: src/settings_translation_file.cpp +msgid "Crash message" +msgstr "當機訊息" + +#: src/settings_translation_file.cpp +msgid "Creative" +msgstr "創造" + +#: src/settings_translation_file.cpp +msgid "Crosshair alpha" +msgstr "十字 alpha 值" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair alpha (opaqueness, between 0 and 255).\n" +"This also applies to the object crosshair." +msgstr "" +"十字 alpha 值(不透明,0 至 255間)。\n" +"這也會套用到物件十字。" + +#: src/settings_translation_file.cpp +msgid "Crosshair color" +msgstr "十字色彩" + +#: src/settings_translation_file.cpp +msgid "" +"Crosshair color (R,G,B).\n" +"Also controls the object crosshair color" +msgstr "" +"十字準線顏色(R,G,B)。\n" +"還控制物件的十字線顏色" + +#: src/settings_translation_file.cpp +msgid "DPI" +msgstr "DPI" + +#: src/settings_translation_file.cpp +msgid "Damage" +msgstr "傷害" + +#: src/settings_translation_file.cpp +msgid "Debug info toggle key" +msgstr "除錯資訊切換按鍵" + +#: src/settings_translation_file.cpp +msgid "Debug log file size threshold" +msgstr "除錯紀錄檔案大小閾值" + +#: src/settings_translation_file.cpp +msgid "Debug log level" +msgstr "除錯記錄等級" + +#: src/settings_translation_file.cpp +msgid "Debugging" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Dec. volume key" +msgstr "音量減少鍵" + +#: src/settings_translation_file.cpp +msgid "Dedicated server step" +msgstr "專用伺服器步驟" + +#: src/settings_translation_file.cpp +msgid "Default acceleration" +msgstr "預設加速" + +#: src/settings_translation_file.cpp +msgid "Default game" +msgstr "預設遊戲" + +#: src/settings_translation_file.cpp +msgid "" +"Default game when creating a new world.\n" +"This will be overridden when creating a world from the main menu." +msgstr "" +"當建立新世界時的預設遊戲。\n" +"當從主選單建立世界時將會被覆寫。" + +#: src/settings_translation_file.cpp +msgid "Default password" +msgstr "預設密碼" + +#: src/settings_translation_file.cpp +msgid "Default privileges" +msgstr "預設特權" + +#: src/settings_translation_file.cpp +msgid "Default report format" +msgstr "缺省報告格式" + +#: src/settings_translation_file.cpp +msgid "Default stack size" +msgstr "預設堆疊大小" + +#: src/settings_translation_file.cpp +msgid "" +"Define shadow filtering quality.\n" +"This simulates the soft shadows effect by applying a PCF or Poisson disk\n" +"but also uses more resources." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Defines areas where trees have apples." +msgstr "定義樹上有蘋果的區域。" + +#: src/settings_translation_file.cpp +msgid "Defines areas with sandy beaches." +msgstr "定義沙灘區。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines distribution of higher terrain and steepness of cliffs." +msgstr "定義較高的地形區(懸崖頂部)並影響懸崖的陡峭程度。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Defines distribution of higher terrain." +msgstr "定義 'terrain_higher'(懸崖頂部地形)的區域。" + +#: src/settings_translation_file.cpp +msgid "Defines full size of caverns, smaller values create larger caverns." +msgstr "定義洞穴的完整大小,較小的值會建立較大的洞穴。" + +#: src/settings_translation_file.cpp +msgid "Defines large-scale river channel structure." +msgstr "定義大型河道結構。" + +#: src/settings_translation_file.cpp +msgid "Defines location and terrain of optional hills and lakes." +msgstr "定義可選的山丘與湖泊的位置與地形。" + +#: src/settings_translation_file.cpp +msgid "Defines the base ground level." +msgstr "定義基礎地面高度。" + +#: src/settings_translation_file.cpp +msgid "Defines the depth of the river channel." +msgstr "定義河道的深度。" + +#: src/settings_translation_file.cpp +msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)." +msgstr "定義玩家最大可傳送的距離,以方塊計(0 = 不限制)。" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river channel." +msgstr "定義河道寬度。" + +#: src/settings_translation_file.cpp +msgid "Defines the width of the river valley." +msgstr "定義河谷的寬度。" + +#: src/settings_translation_file.cpp +msgid "Defines tree areas and tree density." +msgstr "定義樹木區與樹木密度。" + +#: src/settings_translation_file.cpp +msgid "" +"Delay between mesh updates on the client in ms. Increasing this will slow\n" +"down the rate of mesh updates, thus reducing jitter on slower clients." +msgstr "" +"在用戶端上的網格間更新延遲,以毫秒為單位。增加它就會減慢\n" +"網格更新速率,從而減少在較慢用戶端上的抖動。" + +#: src/settings_translation_file.cpp +msgid "Delay in sending blocks after building" +msgstr "建造后傳送區塊前延遲的時間" + +#: src/settings_translation_file.cpp +msgid "Delay showing tooltips, stated in milliseconds." +msgstr "顯示工具提示前的延遲,以毫秒計算。" + +#: src/settings_translation_file.cpp +msgid "Deprecated Lua API handling" +msgstr "不推薦使用 Lua API 處理" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Depth below which you'll find giant caverns." +msgstr "您會發現大型洞穴的深度。" + +#: src/settings_translation_file.cpp +msgid "Depth below which you'll find large caves." +msgstr "您會發現大型洞穴的深度。" + +#: src/settings_translation_file.cpp +msgid "" +"Description of server, to be displayed when players join and in the " +"serverlist." +msgstr "伺服器的描述,會在玩家加入時顯示,也會顯示在伺服器列表上。" + +#: src/settings_translation_file.cpp +msgid "Desert noise threshold" +msgstr "沙漠雜訊閾值" + +#: src/settings_translation_file.cpp +msgid "" +"Deserts occur when np_biome exceeds this value.\n" +"When the 'snowbiomes' flag is enabled, this is ignored." +msgstr "" +"當 np_biome 超過此值時,會產生沙漠。\n" +"當啟用新的生物群系統'snowbiomes'時,這個將會被忽略。" + +#: src/settings_translation_file.cpp +msgid "Desynchronize block animation" +msgstr "異步化方塊動畫" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Developer Options" +msgstr "裝飾物" + +#: src/settings_translation_file.cpp +msgid "Dig key" +msgstr "挖掘鍵" + +#: src/settings_translation_file.cpp +msgid "Digging particles" +msgstr "挖掘粒子" + +#: src/settings_translation_file.cpp +msgid "Disable anticheat" +msgstr "停用反作弊" + +#: src/settings_translation_file.cpp +msgid "Disallow empty passwords" +msgstr "不允許空密碼" + +#: src/settings_translation_file.cpp +msgid "Display Density Scaling Factor" +msgstr "顯示密度縮放因子" + +#: src/settings_translation_file.cpp +msgid "" +"Distance in nodes at which transparency depth sorting is enabled\n" +"Use this to limit the performance impact of transparency depth sorting" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Domain name of server, to be displayed in the serverlist." +msgstr "伺服器的域名,將會在伺服器列表中顯示。" + +#: src/settings_translation_file.cpp +msgid "Double tap jump for fly" +msgstr "輕擊兩次跳躍以飛行" + +#: src/settings_translation_file.cpp +msgid "Double-tapping the jump key toggles fly mode." +msgstr "輕擊兩次跳躍鍵以切換成飛行模式。" + +#: src/settings_translation_file.cpp +msgid "Drop item key" +msgstr "丟棄物品鍵" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Dump the mapgen debug information." +msgstr "轉儲 mapgen 的除錯資訊。" + +#: src/settings_translation_file.cpp +msgid "Dungeon maximum Y" +msgstr "地城最大 X" + +#: src/settings_translation_file.cpp +msgid "Dungeon minimum Y" +msgstr "地城最大 Y" + +#: src/settings_translation_file.cpp +msgid "Dungeon noise" +msgstr "地城雜訊" + +#: src/settings_translation_file.cpp +msgid "" +"Enable IPv6 support (for both client and server).\n" +"Required for IPv6 connections to work at all." +msgstr "" +"啟用 IPv6 支援(針對客戶端和伺服器)。\n" +"IPv6 連線需要它才能運作。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Lua modding support on client.\n" +"This support is experimental and API can change." +msgstr "" +"在用戶端上啟用 Lua 修改支援。\n" +"這個支援是實驗性的,且 API 可能會變動。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable Poisson disk filtering.\n" +"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF " +"filtering." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable colored shadows.\n" +"On true translucent nodes cast colored shadows. This is expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable console window" +msgstr "啟用終端機視窗" + +#: src/settings_translation_file.cpp +msgid "Enable creative mode for all players" +msgstr "為所有的玩家啟用創造模式" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks" +msgstr "啟用搖桿" + +#: src/settings_translation_file.cpp +msgid "Enable joysticks. Requires a restart to take effect" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enable mod channels support." +msgstr "啟用 mod 頻道支援。" + +#: src/settings_translation_file.cpp +msgid "Enable mod security" +msgstr "啟用 mod 安全性" + +#: src/settings_translation_file.cpp +msgid "Enable players getting damage and dying." +msgstr "啟用玩家傷害及瀕死。" + +#: src/settings_translation_file.cpp +msgid "Enable random user input (only used for testing)." +msgstr "啟用隨機使用者輸入(僅供測試使用)。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable smooth lighting with simple ambient occlusion.\n" +"Disable for speed or for different looks." +msgstr "" +"啟用包含簡易環境光遮蔽的平滑光。\n" +"停用以取得速度或不同的外觀。" + +#: src/settings_translation_file.cpp +msgid "Enable split login/register" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable to disallow old clients from connecting.\n" +"Older clients are compatible in the sense that they will not crash when " +"connecting\n" +"to new servers, but they may not support all new features that you are " +"expecting." +msgstr "" +"啟用以讓舊的用戶端無法連線。\n" +"較舊的用戶端在這個意義上相容,它們不會在連線至\n" +"新伺服器時當掉,但它們可能會不支援一些您預期會有的新功能。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable usage of remote media server (if provided by server).\n" +"Remote servers offer a significantly faster way to download media (e.g. " +"textures)\n" +"when connecting to the server." +msgstr "" +"啟用遠端媒體伺服器的使用(若由伺服器提供的話)。\n" +"當連線到伺服器時,遠端伺服器提供了一個\n" +"顯著較快的下載媒體(如材質)的方式。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable vertex buffer objects.\n" +"This should greatly improve graphics performance." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enable view bobbing and amount of view bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"視野晃動的倍數。\n" +"舉例來說:設為 0 就不會有視野晃動;1.0 是一般情況;2.0 為雙倍。" + +#: src/settings_translation_file.cpp +msgid "" +"Enable/disable running an IPv6 server.\n" +"Ignored if bind_address is set.\n" +"Needs enable_ipv6 to be enabled." +msgstr "" +"啟用/停用執行 IPv6 伺服器。\n" +"當 bind_address 被設定時將會被忽略。\n" +"需要啟用 enable_ipv6。" + +#: src/settings_translation_file.cpp +msgid "" +"Enables Hable's 'Uncharted 2' filmic tone mapping.\n" +"Simulates the tone curve of photographic film and how this approximates the\n" +"appearance of high dynamic range images. Mid-range contrast is slightly\n" +"enhanced, highlights and shadows are gradually compressed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Enables animation of inventory items." +msgstr "啟用物品欄物品動畫。" + +#: src/settings_translation_file.cpp +msgid "Enables caching of facedir rotated meshes." +msgstr "啟用面旋轉方向的網格快取。" + +#: src/settings_translation_file.cpp +msgid "Enables minimap." +msgstr "啟用小地圖。" + +#: src/settings_translation_file.cpp +msgid "" +"Enables the sound system.\n" +"If disabled, this completely disables all sounds everywhere and the in-game\n" +"sound controls will be non-functional.\n" +"Changing this setting requires a restart." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Enables tradeoffs that reduce CPU load or increase rendering performance\n" +"at the expense of minor visual glitches that do not impact game playability." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Engine profiler" +msgstr "山谷分析" + +#: src/settings_translation_file.cpp +msgid "Engine profiling data print interval" +msgstr "引擎性能資料印出間隔" + +#: src/settings_translation_file.cpp +msgid "Entity methods" +msgstr "主體方法" + +#: src/settings_translation_file.cpp +msgid "" +"Exponent of the floatland tapering. Alters the tapering behaviour.\n" +"Value = 1.0 creates a uniform, linear tapering.\n" +"Values > 1.0 create a smooth tapering suitable for the default separated\n" +"floatlands.\n" +"Values < 1.0 (for example 0.25) create a more defined surface level with\n" +"flatter lowlands, suitable for a solid floatland layer." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "FPS" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "FPS when unfocused or paused" +msgstr "當遊戲暫停時的最高 FPS。" + +#: src/settings_translation_file.cpp +msgid "FSAA" +msgstr "FSAA" + +#: src/settings_translation_file.cpp +msgid "Factor noise" +msgstr "雜訊係數" + +#: src/settings_translation_file.cpp +msgid "Fall bobbing factor" +msgstr "墜落晃動因素" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Fallback font path" +msgstr "備用字型" + +#: src/settings_translation_file.cpp +msgid "Fast key" +msgstr "快速按鍵" + +#: src/settings_translation_file.cpp +msgid "Fast mode acceleration" +msgstr "快速模式加速" + +#: src/settings_translation_file.cpp +msgid "Fast mode speed" +msgstr "快速模式速度" + +#: src/settings_translation_file.cpp +msgid "Fast movement" +msgstr "快速移動" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Fast movement (via the \"Aux1\" key).\n" +"This requires the \"fast\" privilege on the server." +msgstr "" +"快速移動(透過使用鍵)。\n" +"這需要伺服器上的「快速」特權。" + +#: src/settings_translation_file.cpp +msgid "Field of view" +msgstr "視野" + +#: src/settings_translation_file.cpp +msgid "Field of view in degrees." +msgstr "以度計算的視野。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"File in client/serverlist/ that contains your favorite servers displayed in " +"the\n" +"Multiplayer Tab." +msgstr "" +"在 用戶端/伺服器清單/ 中的檔案包含了顯示在多人遊戲分頁中您最愛的伺服器。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filler depth" +msgstr "填充深度" + +#: src/settings_translation_file.cpp +msgid "Filler depth noise" +msgstr "填充深度雜訊" + +#: src/settings_translation_file.cpp +msgid "Filmic tone mapping" +msgstr "電影色調映射" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Filtered textures can blend RGB values with fully-transparent neighbors,\n" +"which PNG optimizers usually discard, often resulting in dark or\n" +"light edges to transparent textures. Apply a filter to clean that up\n" +"at texture load time. This is automatically enabled if mipmapping is enabled." +msgstr "" +"已過濾的材質會與完全透明的鄰居混合 RGB 值,\n" +"PNG 最佳化器通常會丟棄,有時候會導致透明材質\n" +"會有黑邊或亮邊。套用這個過濾器以在材質載入時\n" +"清理這些東西。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Filtering and Antialiasing" +msgstr "反鋸齒:" + +#: src/settings_translation_file.cpp +msgid "First of 4 2D noises that together define hill/mountain range height." +msgstr "四之一 一同定義山丘範圍高度的 2D 雜訊。" + +#: src/settings_translation_file.cpp +msgid "First of two 3D noises that together define tunnels." +msgstr "二之一 一同定義隧道的 3D 雜訊。" + +#: src/settings_translation_file.cpp +msgid "Fixed map seed" +msgstr "固定的地圖種子" + +#: src/settings_translation_file.cpp +msgid "Fixed virtual joystick" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland density" +msgstr "浮地山密度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland maximum Y" +msgstr "浮地山高度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland minimum Y" +msgstr "浮地山高度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland noise" +msgstr "浮地基礎噪音" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland taper exponent" +msgstr "浮地山密度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland tapering distance" +msgstr "浮地基礎噪音" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Floatland water level" +msgstr "浮地高度" + +#: src/settings_translation_file.cpp +msgid "Fly key" +msgstr "飛行按鍵" + +#: src/settings_translation_file.cpp +msgid "Flying" +msgstr "飛行" + +#: src/settings_translation_file.cpp +msgid "Fog" +msgstr "霧" + +#: src/settings_translation_file.cpp +msgid "Fog start" +msgstr "霧氣開始" + +#: src/settings_translation_file.cpp +msgid "Fog toggle key" +msgstr "霧氣切換鍵" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Font" +msgstr "字型大小" + +#: src/settings_translation_file.cpp +msgid "Font bold by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font italic by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font shadow" +msgstr "字型陰影" + +#: src/settings_translation_file.cpp +msgid "Font shadow alpha" +msgstr "字型陰影 alpha 值" + +#: src/settings_translation_file.cpp +msgid "Font size" +msgstr "字型大小" + +#: src/settings_translation_file.cpp +msgid "Font size divisible by" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Font size of the recent chat text and chat prompt in point (pt).\n" +"Value 0 will use the default font size." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"For pixel-style fonts that do not scale well, this ensures that font sizes " +"used\n" +"with this font will always be divisible by this value, in pixels. For " +"instance,\n" +"a pixel font 16 pixels tall should have this set to 16, so it will only ever " +"be\n" +"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Format of player chat messages. The following strings are valid " +"placeholders:\n" +"@name, @message, @timestamp (optional)" +msgstr "" +"玩家聊天訊息的格式,以下字串皆是有效的佔位符號:\n" +"@name、@message、@timestamp(可選)" + +#: src/settings_translation_file.cpp +msgid "Format of screenshots." +msgstr "螢幕截圖的格式。" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Default Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Color" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Formspec Full-Screen Background Opacity" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec default background color (R,G,B)." +msgstr "遊戲內聊天視窗背景顏色 (R,G,B)。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec default background opacity (between 0 and 255)." +msgstr "遊戲內聊天視窗背景 alpha 值(不透明度,介於 0 到 255 間)。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec full-screen background color (R,G,B)." +msgstr "遊戲內聊天視窗背景顏色 (R,G,B)。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Formspec full-screen background opacity (between 0 and 255)." +msgstr "遊戲內聊天視窗背景 alpha 值(不透明度,介於 0 到 255 間)。" + +#: src/settings_translation_file.cpp +msgid "Forward key" +msgstr "前進鍵" + +#: src/settings_translation_file.cpp +msgid "Fourth of 4 2D noises that together define hill/mountain range height." +msgstr "四之四 一同定義山丘範圍高度的 2D 雜訊。" + +#: src/settings_translation_file.cpp +msgid "Fractal type" +msgstr "碎形類型" + +#: src/settings_translation_file.cpp +msgid "Fraction of the visible distance at which fog starts to be rendered" +msgstr "開始呈現霧氣的可見距離分數" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are generated for clients, stated in mapblocks (16 " +"nodes)." +msgstr "要在用戶端上從多遠的區塊開始生成,以地圖區塊計算(16 個節點)。" + +#: src/settings_translation_file.cpp +msgid "" +"From how far blocks are sent to clients, stated in mapblocks (16 nodes)." +msgstr "要把多遠的區塊送到用戶端,以地圖區塊計算(16 個節點)。" + +#: src/settings_translation_file.cpp +msgid "" +"From how far clients know about objects, stated in mapblocks (16 nodes).\n" +"\n" +"Setting this larger than active_block_range will also cause the server\n" +"to maintain active objects up to this distance in the direction the\n" +"player is looking. (This can avoid mobs suddenly disappearing from view)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Full screen" +msgstr "全螢幕" + +#: src/settings_translation_file.cpp +msgid "Fullscreen mode." +msgstr "全螢幕模式。" + +#: src/settings_translation_file.cpp +msgid "GUI scaling" +msgstr "圖形使用者介面縮放比例" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter" +msgstr "圖形使用者介面縮放過濾器" + +#: src/settings_translation_file.cpp +msgid "GUI scaling filter txr2img" +msgstr "圖形使用者介面縮放比例過濾器 txr2img" + +#: src/settings_translation_file.cpp +msgid "GUIs" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Gamepads" +msgstr "遊戲" + +#: src/settings_translation_file.cpp +msgid "General" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Global callbacks" +msgstr "全域回呼" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Global map generation attributes.\n" +"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n" +"and jungle grass, in all other mapgens this flag controls all decorations." +msgstr "" +"全域地圖產生屬性。\n" +"在 Mapgen v6 中,「decorations」旗標控制所有除了樹木\n" +"與叢林以外的裝飾,在其他所有的 mapgen 中,這個旗標控制所有裝飾。\n" +"未在旗標字串中指定的旗標將不會自預設值修改。\n" +"以「no」開頭的旗標字串將會用於明確的停用它們。" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at maximum light level.\n" +"Controls the contrast of the highest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Gradient of light curve at minimum light level.\n" +"Controls the contrast of the lowest light levels." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Graphics" +msgstr "圖形" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics Effects" +msgstr "圖形" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Graphics and Audio" +msgstr "圖形" + +#: src/settings_translation_file.cpp +msgid "Gravity" +msgstr "重力" + +#: src/settings_translation_file.cpp +msgid "Ground level" +msgstr "地面高度" + +#: src/settings_translation_file.cpp +msgid "Ground noise" +msgstr "地面雜訊" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HTTP mods" +msgstr "HTTP Mod" + +#: src/settings_translation_file.cpp +msgid "HUD" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "HUD scaling" +msgstr "圖形使用者介面縮放比例" + +#: src/settings_translation_file.cpp +msgid "HUD toggle key" +msgstr "HUD 切換鍵" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Handling for deprecated Lua API calls:\n" +"- none: Do not log deprecated calls\n" +"- log: mimic and log backtrace of deprecated call (default).\n" +"- error: abort on usage of deprecated call (suggested for mod developers)." +msgstr "" +"處理已棄用的 Lua API 呼叫:\n" +"- 舊式:(嘗試)模仿舊的行為(release 模式預設值)。\n" +"- 紀錄:模仿並記錄已棄用呼叫的反向追蹤(debug 模式預設值)\n" +"- 錯誤:在使用到棄用的呼叫時中止(建議 mod 開發者使用)。" + +#: src/settings_translation_file.cpp +msgid "" +"Have the profiler instrument itself:\n" +"* Instrument an empty function.\n" +"This estimates the overhead, that instrumentation is adding (+1 function " +"call).\n" +"* Instrument the sampler being used to update the statistics." +msgstr "" +"使用分析器工具本身:\n" +"* 分析空函數。\n" +"這會讓消耗增加,儀表增加(+1 函式呼叫)。\n" +"* 採樣工具會被用於更新統計。" + +#: src/settings_translation_file.cpp +msgid "Heat blend noise" +msgstr "熱 混合 雜訊" + +#: src/settings_translation_file.cpp +msgid "Heat noise" +msgstr "熱 雜訊" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Height component of the initial window size. Ignored in fullscreen mode." +msgstr "初始視窗大小的高度組件。" + +#: src/settings_translation_file.cpp +msgid "Height noise" +msgstr "高度雜訊" + +#: src/settings_translation_file.cpp +msgid "Height select noise" +msgstr "高度 選擇 雜訊" + +#: src/settings_translation_file.cpp +msgid "Hill steepness" +msgstr "山丘坡度" + +#: src/settings_translation_file.cpp +msgid "Hill threshold" +msgstr "山丘閾值" + +#: src/settings_translation_file.cpp +msgid "Hilliness1 noise" +msgstr "多丘陵1 雜訊" + +#: src/settings_translation_file.cpp +msgid "Hilliness2 noise" +msgstr "多丘陵2 雜訊" + +#: src/settings_translation_file.cpp +msgid "Hilliness3 noise" +msgstr "多丘陵3 雜訊" + +#: src/settings_translation_file.cpp +msgid "Hilliness4 noise" +msgstr "多丘陵4 雜訊" + +#: src/settings_translation_file.cpp +msgid "Homepage of server, to be displayed in the serverlist." +msgstr "伺服器的首頁,會在伺服器清單中顯示。" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal acceleration in air when jumping or falling,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration in fast mode,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Horizontal and vertical acceleration on ground or when climbing,\n" +"in nodes per second per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Hotbar next key" +msgstr "快捷列下一個鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar previous key" +msgstr "快捷列上一個鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 1 key" +msgstr "快捷列第 1 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 10 key" +msgstr "快捷列第 10 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 11 key" +msgstr "快捷列第 11 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 12 key" +msgstr "快捷列第 12 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 13 key" +msgstr "快捷列第 13 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 14 key" +msgstr "快捷列第 14 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 15 key" +msgstr "快捷列第 15 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 16 key" +msgstr "快捷列第 16 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 17 key" +msgstr "快捷列第 17 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 18 key" +msgstr "快捷列第 18 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 19 key" +msgstr "快捷列第 19 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 2 key" +msgstr "快捷列第 2 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 20 key" +msgstr "快捷列第 20 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 21 key" +msgstr "快捷列第 21 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 22 key" +msgstr "快捷列第 22 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 23 key" +msgstr "快捷列第 23 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 24 key" +msgstr "快捷列第 24 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 25 key" +msgstr "快捷列第 25 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 26 key" +msgstr "快捷列第 26 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 27 key" +msgstr "快捷列第 27 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 28 key" +msgstr "快捷列第 28 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 29 key" +msgstr "快捷列第 29 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 3 key" +msgstr "快捷列第 3 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 30 key" +msgstr "快捷列第 30 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 31 key" +msgstr "快捷列第 31 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 32 key" +msgstr "快捷列第 32 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 4 key" +msgstr "快捷列第 4 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 5 key" +msgstr "快捷列第 5 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 6 key" +msgstr "快捷列第 6 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 7 key" +msgstr "快捷列第 7 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 8 key" +msgstr "快捷列第 8 個槽的按鍵" + +#: src/settings_translation_file.cpp +msgid "Hotbar slot 9 key" +msgstr "快捷列第 9 個槽的按鍵" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "How deep to make rivers." +msgstr "河流多深" + +#: src/settings_translation_file.cpp +msgid "" +"How fast liquid waves will move. Higher = faster.\n" +"If negative, liquid waves will move backwards.\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How long the server will wait before unloading unused mapblocks, stated in " +"seconds.\n" +"Higher value is smoother, but will use more RAM." +msgstr "" +"在取消載入前要有多少未使用的地圖區塊。\n" +"較高的值會較平滑,但會使用更多的記憶體。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"How much you are slowed down when moving inside a liquid.\n" +"Decrease this to increase liquid resistance to movement." +msgstr "減少此值可增加液體的運動阻力。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "How wide to make rivers." +msgstr "河流多寬" + +#: src/settings_translation_file.cpp +msgid "Humidity blend noise" +msgstr "溼度 混合 雜訊" + +#: src/settings_translation_file.cpp +msgid "Humidity noise" +msgstr "溼度 雜訊" + +#: src/settings_translation_file.cpp +msgid "Humidity variation for biomes." +msgstr "生物群落的溼度變化。" + +#: src/settings_translation_file.cpp +msgid "IPv6" +msgstr "IPv6" + +#: src/settings_translation_file.cpp +msgid "IPv6 server" +msgstr "IPv6 伺服器" + +#: src/settings_translation_file.cpp +msgid "" +"If FPS would go higher than this, limit it by sleeping\n" +"to not waste CPU power for no benefit." +msgstr "" +"若 FPS 高於此,以休眠的方式限制它\n" +"以避免無謂的浪費 CPU 的電力。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n" +"enabled." +msgstr "若停用,在飛行與快速模式皆啟用時,「使用」鍵將用於快速飛行。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled the server will perform map block occlusion culling based on\n" +"on the eye position of the player. This can reduce the number of blocks\n" +"sent to the client 50-80%. The client will not longer receive most " +"invisible\n" +"so that the utility of noclip mode is reduced." +msgstr "" +"若啟用,伺服器將會執行基於玩家眼睛位置的\n" +"地圖區塊阻擋剔除。這樣可以減少向用戶端發\n" +"送 50-80% 的區塊數。用戶端將不會收到最\n" +"不可能看見的內容,而使穿牆模式的效用降低。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled together with fly mode, player is able to fly through solid " +"nodes.\n" +"This requires the \"noclip\" privilege on the server." +msgstr "" +"若與飛行模式一同啟用,玩家就可以飛過固體節點。\n" +"這需要在伺服器上的「noclip」權限。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down " +"and\n" +"descending." +msgstr "若啟用,向下爬與下降將使用「使用」鍵而非「潛行」鍵。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, account registration is separate from login in the UI.\n" +"If disabled, new accounts will be registered automatically when logging in." +msgstr "" +"連線到伺服器時啟用註冊確認。\n" +"如果停用,會自動註冊新的帳號。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, actions are recorded for rollback.\n" +"This option is only read when server starts." +msgstr "" +"若啟用,動作會被記錄以供復原。\n" +"這個選項只會在伺服器啟動時讀取。" + +#: src/settings_translation_file.cpp +msgid "If enabled, disable cheat prevention in multiplayer." +msgstr "若啟用,將會停用在多人遊戲中的防止作弊。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, invalid world data won't cause the server to shut down.\n" +"Only enable this if you know what you are doing." +msgstr "" +"若啟用,無效的世界資訊將不會造成伺服器關機。\n" +"只在您知道您在幹嘛時才啟用這個選項。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, makes move directions relative to the player's pitch when flying " +"or swimming." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"If enabled, players cannot join without a password or change theirs to an " +"empty password." +msgstr "若啟用,新玩家將無法以空密碼加入。" + +#: src/settings_translation_file.cpp +msgid "" +"If enabled, you can place blocks at the position (feet + eye level) where " +"you stand.\n" +"This is helpful when working with nodeboxes in small areas." +msgstr "" +"若啟用,您可以在您站立的位置(腳與眼睛的高度)放置方塊。當在小區域裡與節點盒" +"一同工作時非常有用。" + +#: src/settings_translation_file.cpp +msgid "" +"If the CSM restriction for node range is enabled, get_node calls are " +"limited\n" +"to this distance from the player to the node." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the execution of a chat command takes longer than this specified time in\n" +"seconds, add the time information to the chat command message" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"If the file size of debug.txt exceeds the number of megabytes specified in\n" +"this setting when it is opened, the file is moved to debug.txt.1,\n" +"deleting an older debug.txt.1 if it exists.\n" +"debug.txt is only moved if this setting is positive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "If this is set, players will always (re)spawn at the given position." +msgstr "如果設定了這個,玩家將會總是在指定的位置重生。" + +#: src/settings_translation_file.cpp +msgid "Ignore world errors" +msgstr "忽略世界錯誤" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." +msgstr "遊戲內聊天視窗背景 alpha 值(不透明度,介於 0 到 255 間)。" + +#: src/settings_translation_file.cpp +msgid "In-game chat console background color (R,G,B)." +msgstr "遊戲內聊天視窗背景顏色 (R,G,B)。" + +#: src/settings_translation_file.cpp +msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)." +msgstr "遊戲中的聊天終端機高度,介於 0.1 (10%) 至 1.0 (100%) 間。" + +#: src/settings_translation_file.cpp +msgid "Inc. volume key" +msgstr "提高音量鍵" + +#: src/settings_translation_file.cpp +msgid "Initial vertical speed when jumping, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument builtin.\n" +"This is usually only needed by core/builtin contributors" +msgstr "" +"內建工具。\n" +"這通常僅被核心/內建貢獻者需要" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Instrument chat commands on registration." +msgstr "分析登錄的聊天指令。" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument global callback functions on registration.\n" +"(anything you pass to a minetest.register_*() function)" +msgstr "" +"在登錄上分析全域回呼。\n" +"(任何您想要傳遞給 minetest.register_*() 函數的東西)" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Active Block Modifiers on registration." +msgstr "分析登錄的活躍區塊修飾器的動作函數。" + +#: src/settings_translation_file.cpp +msgid "" +"Instrument the action function of Loading Block Modifiers on registration." +msgstr "分析登錄的載入中區塊修飾器的動作函數。" + +#: src/settings_translation_file.cpp +msgid "Instrument the methods of entities on registration." +msgstr "分析登錄的實體方法。" + +#: src/settings_translation_file.cpp +msgid "Interval of saving important changes in the world, stated in seconds." +msgstr "儲存世界中的重要變更的間隔,以秒計。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Interval of sending time of day to clients, stated in seconds." +msgstr "傳送當日時間至用戶端的間隔。" + +#: src/settings_translation_file.cpp +msgid "Inventory items animations" +msgstr "物品欄物品動畫" + +#: src/settings_translation_file.cpp +msgid "Inventory key" +msgstr "物品欄按鍵" + +#: src/settings_translation_file.cpp +msgid "Invert mouse" +msgstr "滑鼠反相" + +#: src/settings_translation_file.cpp +msgid "Invert vertical mouse movement." +msgstr "反轉滑鼠移動的方向。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Italic font path" +msgstr "等寬字型路徑" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Italic monospace font path" +msgstr "等寬字型路徑" + +#: src/settings_translation_file.cpp +msgid "Item entity TTL" +msgstr "物品主體 TTL" + +#: src/settings_translation_file.cpp +msgid "Iterations" +msgstr "迭代" + +#: src/settings_translation_file.cpp +msgid "" +"Iterations of the recursive function.\n" +"Increasing this increases the amount of fine detail, but also\n" +"increases processing load.\n" +"At iterations = 20 this mapgen has a similar load to mapgen V7." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Joystick ID" +msgstr "搖桿 ID" + +#: src/settings_translation_file.cpp +msgid "Joystick button repetition interval" +msgstr "搖桿按鈕重覆間隔" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick dead zone" +msgstr "搖桿類型" + +#: src/settings_translation_file.cpp +msgid "Joystick frustum sensitivity" +msgstr "搖桿靈敏度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Joystick type" +msgstr "搖桿類型" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"W component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"僅朱利亞集合:可交換超複數的 W 元素決定了 朱利亞形狀。\n" +"在 3D 碎形上沒有效果。\n" +"範圍約在 -2 至 2 間。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"X component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"僅朱利亞集合:可交換超複數的 X 元素決定了 朱利亞形狀。\n" +"在 3D 碎形上沒有效果。\n" +"範圍約在 -2 至 2 間。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"Y component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"僅朱利亞集合:可交換超複數的 Y 元素決定了 朱利亞形狀。\n" +"在 3D 碎形上沒有效果。\n" +"範圍約在 -2 至 2 間。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Julia set only.\n" +"Z component of hypercomplex constant.\n" +"Alters the shape of the fractal.\n" +"Range roughly -2 to 2." +msgstr "" +"僅朱利亞集合:可交換超複數的 Z 元素決定了 朱利亞形狀。\n" +"在 3D 碎形上沒有效果。\n" +"範圍約在 -2 至 2 間。" + +#: src/settings_translation_file.cpp +msgid "Julia w" +msgstr "Julia w" + +#: src/settings_translation_file.cpp +msgid "Julia x" +msgstr "Julia x" + +#: src/settings_translation_file.cpp +msgid "Julia y" +msgstr "Julia y" + +#: src/settings_translation_file.cpp +msgid "Julia z" +msgstr "Julia z" + +#: src/settings_translation_file.cpp +msgid "Jump key" +msgstr "跳躍鍵" + +#: src/settings_translation_file.cpp +msgid "Jumping speed" +msgstr "跳躍速度" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"降低視野範圍的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for decreasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"降低音量的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for digging.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"跳躍的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for dropping the currently selected item.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"丟棄目前選定物品的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the viewing range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"增加視野範圍的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for increasing the volume.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"增加音量的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for jumping.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"跳躍的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving fast in fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"在快速模式中快速移動的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for moving the player backward.\n" +"Will also disable autoforward, when active.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"將玩家往後方移動的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player forward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"將玩家往前方移動的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player left.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"將玩家往左方移動的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for moving the player right.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"將玩家往右方移動的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for muting the game.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"遊戲靜音的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"開啟對話視窗以供輸入指令的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window to type local commands.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"開啟對話視窗以供輸入本機指令的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the chat window.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"開啟對話視窗的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for opening the inventory.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"開啟物品欄的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for placing.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"跳躍的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 11th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 11 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 12th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 12 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 13th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 13 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 14th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 14 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 15th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 15 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 16th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 16 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 17th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 17 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 18th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 18 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 19th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 19 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 20th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 20 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 21st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 21 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 22nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 22 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 23rd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 23 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 24th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 24 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 25th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 25 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 26th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 26 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 27th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 27 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 28th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 28 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 29th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 29 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 30th hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 30 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 31st hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 31 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the 32nd hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 32 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the eighth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 8 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fifth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 5 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the first hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 1 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the fourth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 4 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the next item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"在快捷列選取下一個物品的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the ninth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 9 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the previous item in the hotbar.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"在快捷列選取上一個物品的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the second hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 2 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the seventh hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 7 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the sixth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 6 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the tenth hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 10 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for selecting the third hotbar slot.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"選取快捷列中第 3 個槽的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for sneaking.\n" +"Also used for climbing down and descending in water if aux1_descends is " +"disabled.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"潛行的按鍵。\n" +"若 aux1_ 降低停用時,也會用於向下攀爬與在水中下潛。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for switching between first- and third-person camera.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"用來切換第一與第三人稱視角的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for taking screenshots.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"拍攝螢幕截圖的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Key for toggling autoforward.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換自動奔跑的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling cinematic mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換電影模式的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling display of minimap.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換顯示迷你地圖的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling fast mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換快速模式的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling flying.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換飛行的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling noclip mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換穿牆模式的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling pitch move mode.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換 Pitch Move 模式的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the camera update. Only used for development\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換視角更新的按鍵。僅對開發有用。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of chat.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"用來切換聊天顯示的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of debug info.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換顯示除錯資訊的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of fog.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換顯示霧氣的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the HUD.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換顯示 HUD 的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the large chat console.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換顯示大聊天終端機的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling the display of the profiler. Used for development.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換顯示輪廓的按鍵。對開發有用。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key for toggling unlimited view range.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"切換無限視野的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "" +"Key to use view zoom when possible.\n" +"See http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" +msgstr "" +"當可能時用來縮放的按鍵。\n" +"請見 http://irrlicht.sourceforge.net/docu/namespaceirr." +"html#a54da2a0e231901735e3da1b0edf72eb3" + +#: src/settings_translation_file.cpp +msgid "Keyboard and Mouse" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Kick players who sent more than X messages per 10 seconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Lake steepness" +msgstr "湖泊坡度" + +#: src/settings_translation_file.cpp +msgid "Lake threshold" +msgstr "湖泊閾值" + +#: src/settings_translation_file.cpp +msgid "Language" +msgstr "語言" + +#: src/settings_translation_file.cpp +msgid "Large cave depth" +msgstr "大型洞穴深度" + +#: src/settings_translation_file.cpp +msgid "Large cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large cave proportion flooded" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Large chat console key" +msgstr "大聊天終端機按鍵" + +#: src/settings_translation_file.cpp +msgid "Leaves style" +msgstr "樹葉樣式" + +#: src/settings_translation_file.cpp +msgid "" +"Leaves style:\n" +"- Fancy: all faces visible\n" +"- Simple: only outer faces, if defined special_tiles are used\n" +"- Opaque: disable transparency" +msgstr "" +"樹葉樣式:\n" +"- 花俏:所有表面均可見\n" +"- 簡單:只有外部表面,若有已定義的 special_tiles,則會使用它\n" +"- 不透明:停用透明度" + +#: src/settings_translation_file.cpp +msgid "Left key" +msgstr "左鍵" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of a server tick and the interval at which objects are generally " +"updated over\n" +"network, stated in seconds." +msgstr "伺服器 tick 的長度與相關物件的間隔通常透過網路更新。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of liquid waves.\n" +"Requires waving liquids to be enabled." +msgstr "" +"設定為真以啟用擺動的樹葉。\n" +"必須同時啟用著色器。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between Active Block Modifier (ABM) execution cycles, stated " +"in seconds." +msgstr "在 ABM 執行循環間的時間長度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Length of time between NodeTimer execution cycles, stated in seconds." +msgstr "在 Node 計時器執行循環間的時間長度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Length of time between active block management cycles, stated in seconds." +msgstr "在活躍方塊管理循環的時間中間" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Level of logging to be written to debug.txt:\n" +"- <nothing> (no logging)\n" +"- none (messages with no level)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose\n" +"- trace" +msgstr "" +"要被寫入到 debug.txt 的紀錄等級:\n" +"- <nothing> (不記錄)\n" +"- none(無等級的訊息)\n" +"- error\n" +"- warning\n" +"- action\n" +"- info\n" +"- verbose" + +#: src/settings_translation_file.cpp +msgid "Light curve boost" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost center" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve boost spread" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve high gradient" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Light curve low gradient" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lighting" +msgstr "平滑光線" + +#: src/settings_translation_file.cpp +msgid "" +"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n" +"Only mapchunks completely within the mapgen limit are generated.\n" +"Value is stored per-world." +msgstr "" +"地圖生成限制,以節點,以從 (0, 0, 0) 開始的全部六個方向。\n" +"僅有在 mapgen 限制內的 mapchunks 會完成生成。\n" +"每個世界的值分開儲存。" + +#: src/settings_translation_file.cpp +msgid "" +"Limits number of parallel HTTP requests. Affects:\n" +"- Media fetch if server uses remote_media setting.\n" +"- Serverlist download and server announcement.\n" +"- Downloads performed by main menu (e.g. mod manager).\n" +"Only has an effect if compiled with cURL." +msgstr "" +"限制平行的 HTTP 請求數量。影響:\n" +"- 媒體擷取,若伺服器使用 remote_media 設定。\n" +"- 伺服器清單下載與伺服器公告。\n" +"- 從主選單下載的東西(例如 mod 管理員)。\n" +"只會在包含 cURL 進行編譯時有影響。" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity" +msgstr "液體流動性" + +#: src/settings_translation_file.cpp +msgid "Liquid fluidity smoothing" +msgstr "液體流動平滑" + +#: src/settings_translation_file.cpp +msgid "Liquid loop max" +msgstr "液體迴路最大值" + +#: src/settings_translation_file.cpp +msgid "Liquid queue purge time" +msgstr "液體佇列清除時間" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Liquid sinking" +msgstr "液體下沉" + +#: src/settings_translation_file.cpp +msgid "Liquid update interval in seconds." +msgstr "液體更新間隔,以秒計。" + +#: src/settings_translation_file.cpp +msgid "Liquid update tick" +msgstr "液體更新 tick" + +#: src/settings_translation_file.cpp +msgid "Load the game profiler" +msgstr "載入遊戲分析器" + +#: src/settings_translation_file.cpp +msgid "" +"Load the game profiler to collect game profiling data.\n" +"Provides a /profiler command to access the compiled profile.\n" +"Useful for mod developers and server operators." +msgstr "" +"載入遊戲分析器以收集遊戲分析資料。\n" +"提供一個 /profiler 指令以存取已編譯的設定檔。\n" +"對 mod 開發者與伺服器提供者有用。" + +#: src/settings_translation_file.cpp +msgid "Loading Block Modifiers" +msgstr "正在載入方塊調整器" + +#: src/settings_translation_file.cpp +msgid "Lower Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Lower Y limit of floatlands." +msgstr "大型偽隨機洞穴的 Y 上限。" + +#: src/settings_translation_file.cpp +msgid "Main menu script" +msgstr "主選單指令稿" + +#: src/settings_translation_file.cpp +msgid "" +"Make fog and sky colors depend on daytime (dawn/sunset) and view direction." +msgstr "讓霧與天空的顏色取決於時間(黎明/日落)與觀看方向。" + +#: src/settings_translation_file.cpp +msgid "Makes all liquids opaque" +msgstr "讓所有的液體不透明" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Disk Storage" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map Compression Level for Network Transfer" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map directory" +msgstr "地圖目錄" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen Carpathian." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen Flat.\n" +"Occasional lakes and hills can be added to the flat world." +msgstr "" +"專用於 Mapgen flat 的地圖生成屬性。\n" +"可能會有少數的湖泊或是丘陵會在扁平的世界中生成。\n" +"未在旗標字串中指定的旗標將不會自預設值修改。\n" +"以「no」開頭的旗標字串將會用於明確的停用它們。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen Fractal.\n" +"'terrain' enables the generation of non-fractal terrain:\n" +"ocean, islands and underground." +msgstr "" +"專用於 Mapgen flat 的地圖生成屬性。\n" +"可能會有少數的湖泊或是丘陵會在扁平的世界中生成。\n" +"未在旗標字串中指定的旗標將不會自預設值修改。\n" +"以「no」開頭的旗標字串將會用於明確的停用它們。" + +#: src/settings_translation_file.cpp +msgid "" +"Map generation attributes specific to Mapgen Valleys.\n" +"'altitude_chill': Reduces heat with altitude.\n" +"'humid_rivers': Increases humidity around rivers.\n" +"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n" +"to become shallower and occasionally dry.\n" +"'altitude_dry': Reduces humidity with altitude." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Map generation attributes specific to Mapgen v5." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen v6.\n" +"The 'snowbiomes' flag enables the new 5 biome system.\n" +"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n" +"the 'jungles' flag is ignored." +msgstr "" +"專用於 Mapgen v6 的地圖生成屬性。\n" +"'snowbiomes' 旗標啟用了五個新的生態系。\n" +"當新的生態系啟用時,叢林生態系會自動啟用,\n" +"而 'jungles' 會被忽略。\n" +"未在旗標字串中指定的旗標將不會自預設值修改。\n" +"以「no」開頭的旗標字串將會用於明確的停用它們。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Map generation attributes specific to Mapgen v7.\n" +"'ridges': Rivers.\n" +"'floatlands': Floating land masses in the atmosphere.\n" +"'caverns': Giant caves deep underground." +msgstr "" +"專用於 Mapgen flat 的地圖生成屬性。\n" +"可能會有少數的湖泊或是丘陵會在扁平的世界中生成。\n" +"未在旗標字串中指定的旗標將不會自預設值修改。\n" +"以「no」開頭的旗標字串將會用於明確的停用它們。" + +#: src/settings_translation_file.cpp +msgid "Map generation limit" +msgstr "地圖生成限制" + +#: src/settings_translation_file.cpp +msgid "Map save interval" +msgstr "地圖儲存間隔" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Map shadows update frames" +msgstr "液體更新 tick" + +#: src/settings_translation_file.cpp +msgid "Mapblock limit" +msgstr "地圖區塊限制" + +#: src/settings_translation_file.cpp +msgid "Mapblock mesh generation delay" +msgstr "地圖區塊網格生成延遲" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapblock mesh generator's MapBlock cache size in MB" +msgstr "地圖區塊網格生成器的地圖區塊快取大小 MB" + +#: src/settings_translation_file.cpp +msgid "Mapblock unload timeout" +msgstr "地圖區塊卸除逾時" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian" +msgstr "地圖產生器分形" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Carpathian specific flags" +msgstr "Mapgen flat 特別旗標" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat" +msgstr "Mapgen flat" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Flat specific flags" +msgstr "Mapgen flat 特別旗標" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal" +msgstr "地圖產生器分形" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Fractal specific flags" +msgstr "Mapgen flat 特別旗標" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5" +msgstr "Mapgen v5" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V5 specific flags" +msgstr "Mapgen v5 特別旗標" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6" +msgstr "Mapgen v6" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V6 specific flags" +msgstr "Mapgen v6 特別旗標" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7" +msgstr "地圖產生器 v7" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen V7 specific flags" +msgstr "Mapgen v7 特別旗標" + +#: src/settings_translation_file.cpp +msgid "Mapgen Valleys" +msgstr "Mapgen 山谷" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mapgen Valleys specific flags" +msgstr "Mapgen flat 特別旗標" + +#: src/settings_translation_file.cpp +msgid "Mapgen debug" +msgstr "Mapgen 除錯" + +#: src/settings_translation_file.cpp +msgid "Mapgen name" +msgstr "Mapgen 名稱" + +#: src/settings_translation_file.cpp +msgid "Max block generate distance" +msgstr "最大區塊產生距離" + +#: src/settings_translation_file.cpp +msgid "Max block send distance" +msgstr "最大區塊傳送距離" + +#: src/settings_translation_file.cpp +msgid "Max liquids processed per step." +msgstr "最大按步驟處理液體。" + +#: src/settings_translation_file.cpp +msgid "Max. clearobjects extra blocks" +msgstr "最大清晰物件額外區塊" + +#: src/settings_translation_file.cpp +msgid "Max. packets per iteration" +msgstr "每個迭代最大封包" + +#: src/settings_translation_file.cpp +msgid "Maximum FPS" +msgstr "最高 FPS" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum FPS when the window is not focused, or when the game is paused." +msgstr "當遊戲暫停時的最高 FPS。" + +#: src/settings_translation_file.cpp +msgid "Maximum distance to render shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum forceloaded blocks" +msgstr "強制載入區塊的最大值" + +#: src/settings_translation_file.cpp +msgid "Maximum hotbar width" +msgstr "快捷列最大寬度" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum liquid resistance. Controls deceleration when entering liquid at\n" +"high speed." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of blocks that are simultaneously sent per client.\n" +"The maximum total count is calculated dynamically:\n" +"max_total = ceil((#clients + max_users) * per_client / 4)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of blocks that can be queued for loading." +msgstr "可被放進佇列內等待載入的最大區塊數。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks to be queued that are to be generated.\n" +"This limit is enforced per player." +msgstr "" +"可被放進佇列內等待生成的最大區塊數。\n" +"將其設定留空則會自動選擇適當的值。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum number of blocks to be queued that are to be loaded from file.\n" +"This limit is enforced per player." +msgstr "" +"可被放進佇列內等待從檔案載入的最大區塊數。\n" +"將其設定留空則會自動選擇適當的值。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of concurrent downloads. Downloads exceeding this limit will " +"be queued.\n" +"This should be lower than curl_parallel_limit." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum number of forceloaded mapblocks." +msgstr "強制載入地圖區塊的最大數量。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of mapblocks for client to be kept in memory.\n" +"Set to -1 for unlimited amount." +msgstr "" +"要保留在記憶體中的用戶端地圖區塊最大值。\n" +"設定為 -1 則不限制數量。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum number of packets sent per send step, if you have a slow connection\n" +"try reducing it, but don't reduce it to a number below double of targeted\n" +"client number." +msgstr "" +"每個傳送步驟要傳送的最大封包數,若您的網路連線緩慢\n" +"請試著降低它,但請不要降低到低於兩倍的目標\n" +"用戶端數。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Maximum number of players that can be connected simultaneously." +msgstr "最大可同時連線的玩家數。" + +#: src/settings_translation_file.cpp +msgid "Maximum number of recent chat messages to show" +msgstr "最多顯示幾個最近聊天訊息" + +#: src/settings_translation_file.cpp +msgid "Maximum number of statically stored objects in a block." +msgstr "最大靜態儲存於一個區塊中的物件數量。" + +#: src/settings_translation_file.cpp +msgid "Maximum objects per block" +msgstr "每個區塊最大物件數" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum proportion of current window to be used for hotbar.\n" +"Useful if there's something to be displayed right or left of hotbar." +msgstr "" +"要用於目前視窗的最大比例,放在快捷列中。\n" +"如果有東西要顯示在快捷列左邊或右邊時很有用。" + +#: src/settings_translation_file.cpp +msgid "Maximum simultaneous block sends per client" +msgstr "每個用戶端最大同時傳送區塊數" + +#: src/settings_translation_file.cpp +msgid "Maximum size of the out chat queue" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum size of the out chat queue.\n" +"0 to disable queueing and -1 to make the queue size unlimited." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Maximum time a file download (e.g. a mod download) may take, stated in " +"milliseconds." +msgstr "檔案下載(例如下載 mod)可花費的最大時間,以毫秒計。" + +#: src/settings_translation_file.cpp +msgid "" +"Maximum time an interactive request (e.g. server list fetch) may take, " +"stated in milliseconds." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Maximum users" +msgstr "最多使用者" + +#: src/settings_translation_file.cpp +msgid "Mesh cache" +msgstr "網狀快取" + +#: src/settings_translation_file.cpp +msgid "Message of the day" +msgstr "每日訊息" + +#: src/settings_translation_file.cpp +msgid "Message of the day displayed to players connecting." +msgstr "每日訊息會在玩家連線時顯示。" + +#: src/settings_translation_file.cpp +msgid "Method used to highlight selected object." +msgstr "用於突顯物件的方法。" + +#: src/settings_translation_file.cpp +msgid "Minimal level of logging to be written to chat." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimap" +msgstr "迷你地圖" + +#: src/settings_translation_file.cpp +msgid "Minimap key" +msgstr "迷你地圖按鍵" + +#: src/settings_translation_file.cpp +msgid "Minimap scan height" +msgstr "迷你地圖掃描高度" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of large caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Minimum limit of random number of small caves per mapchunk." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Minimum texture size" +msgstr "過濾器的最大材質大小" + +#: src/settings_translation_file.cpp +msgid "Mipmapping" +msgstr "映射貼圖" + +#: src/settings_translation_file.cpp +msgid "Misc" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Profiler" +msgstr "分析器" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mod Security" +msgstr "安全" + +#: src/settings_translation_file.cpp +msgid "Mod channels" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Modifies the size of the HUD elements." +msgstr "修改 hudbar 元素的大小。" + +#: src/settings_translation_file.cpp +msgid "Monospace font path" +msgstr "等寬字型路徑" + +#: src/settings_translation_file.cpp +msgid "Monospace font size" +msgstr "等寬字型大小" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Monospace font size divisible by" +msgstr "等寬字型大小" + +#: src/settings_translation_file.cpp +msgid "Mountain height noise" +msgstr "山高度 雜訊" + +#: src/settings_translation_file.cpp +msgid "Mountain noise" +msgstr "山雜訊" + +#: src/settings_translation_file.cpp +msgid "Mountain variation noise" +msgstr "山變異 雜訊" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Mountain zero level" +msgstr "山雜訊" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity" +msgstr "滑鼠靈敏度" + +#: src/settings_translation_file.cpp +msgid "Mouse sensitivity multiplier." +msgstr "滑鼠靈敏度倍數。" + +#: src/settings_translation_file.cpp +msgid "Mud noise" +msgstr "泥土雜訊" + +#: src/settings_translation_file.cpp +msgid "" +"Multiplier for fall bobbing.\n" +"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double." +msgstr "" +"落差晃動的倍數。\n" +"舉例來說:設為 0 就不會有視野晃動;1.0 是一般情況;2.0 為雙倍。" + +#: src/settings_translation_file.cpp +msgid "Mute key" +msgstr "靜音按鍵" + +#: src/settings_translation_file.cpp +msgid "Mute sound" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of map generator to be used when creating a new world.\n" +"Creating a world in the main menu will override this.\n" +"Current mapgens in a highly unstable state:\n" +"- The optional floatlands of v7 (disabled by default)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the player.\n" +"When running a server, clients connecting with this name are admins.\n" +"When starting from the main menu, this is overridden." +msgstr "" +"玩家名稱。\n" +"當執行伺服器時,以此名稱連線的用戶端即為管理員。\n" +"當從主選單啟動時,這個將會被覆寫。" + +#: src/settings_translation_file.cpp +msgid "" +"Name of the server, to be displayed when players join and in the serverlist." +msgstr "伺服器名稱,當玩家加入時會顯示,也會顯示在伺服器清單中。" + +#: src/settings_translation_file.cpp +msgid "Near plane" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Network port to listen (UDP).\n" +"This value will be overridden when starting from the main menu." +msgstr "" +"要監聽的網路埠 (UDP)。\n" +"當從主選單啟動時,這個值將會被覆寫。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Networking" +msgstr "網路" + +#: src/settings_translation_file.cpp +msgid "New users need to input this password." +msgstr "新使用這需要輸入這個密碼。" + +#: src/settings_translation_file.cpp +msgid "Noclip" +msgstr "穿牆" + +#: src/settings_translation_file.cpp +msgid "Noclip key" +msgstr "穿牆按鍵" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Node and Entity Highlighting" +msgstr "突顯方塊" + +#: src/settings_translation_file.cpp +msgid "Node highlighting" +msgstr "突顯節點" + +#: src/settings_translation_file.cpp +msgid "NodeTimer interval" +msgstr "NodeTimer 間隔" + +#: src/settings_translation_file.cpp +msgid "Noises" +msgstr "雜訊" + +#: src/settings_translation_file.cpp +msgid "Number of emerge threads" +msgstr "出現的執行緒數" + +#: src/settings_translation_file.cpp +msgid "" +"Number of emerge threads to use.\n" +"Value 0:\n" +"- Automatic selection. The number of emerge threads will be\n" +"- 'number of processors - 2', with a lower limit of 1.\n" +"Any other value:\n" +"- Specifies the number of emerge threads, with a lower limit of 1.\n" +"WARNING: Increasing the number of emerge threads increases engine mapgen\n" +"speed, but this may harm game performance by interfering with other\n" +"processes, especially in singleplayer and/or when running Lua code in\n" +"'on_generated'. For many users the optimum setting may be '1'." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Number of extra blocks that can be loaded by /clearobjects at once.\n" +"This is a trade-off between SQLite transaction overhead and\n" +"memory consumption (4096=100MB, as a rule of thumb)." +msgstr "" +"可被 /clearobjects 一次載入的額外區塊數量。\n" +"這是與 sqlite 處理耗費的折衷與\n" +"記憶體耗費(根據經驗,4096=100MB)。" + +#: src/settings_translation_file.cpp +msgid "Opaque liquids" +msgstr "不透明液體" + +#: src/settings_translation_file.cpp +msgid "" +"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Open the pause menu when the window's focus is lost. Does not pause if a " +"formspec is\n" +"open." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Optional override for chat weblink color." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path of the fallback font. Must be a TrueType font.\n" +"This font will be used for certain languages or if the default font is " +"unavailable." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to save screenshots at. Can be an absolute or relative path.\n" +"The folder will be created if it doesn't already exist." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to shader directory. If no path is defined, default location will be " +"used." +msgstr "著色器目錄路徑。若未定義路徑,將會使用預設的位置。" + +#: src/settings_translation_file.cpp +msgid "Path to texture directory. All textures are first searched from here." +msgstr "材質目錄的路徑。所有材質都會先從這裡搜尋。" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the default font. Must be a TrueType font.\n" +"The fallback font will be used if the font cannot be loaded." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Path to the monospace font. Must be a TrueType font.\n" +"This font is used for e.g. the console and profiler screen." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Pause on lost window focus" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Per-player limit of queued blocks load from disk" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Per-player limit of queued blocks to generate" +msgstr "要生成的出現佇列的限制" + +#: src/settings_translation_file.cpp +msgid "Physics" +msgstr "物理" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Pitch move key" +msgstr "飛行按鍵" + +#: src/settings_translation_file.cpp +msgid "Pitch move mode" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place key" +msgstr "飛行按鍵" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Place repetition interval" +msgstr "右鍵點擊重覆間隔" + +#: src/settings_translation_file.cpp +msgid "" +"Player is able to fly without being affected by gravity.\n" +"This requires the \"fly\" privilege on the server." +msgstr "" +"玩家可以不受重力影響飛行。\n" +"這需要在伺服器上啟用「飛行」特權。" + +#: src/settings_translation_file.cpp +msgid "Player transfer distance" +msgstr "玩家傳送距離" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Player versus player" +msgstr "玩家對玩家" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Poisson filtering" +msgstr "雙線性過濾器" + +#: src/settings_translation_file.cpp +msgid "" +"Port to connect to (UDP).\n" +"Note that the port field in the main menu overrides this setting." +msgstr "" +"要連線至的埠 (UDP)。\n" +"注意在主選單中的埠欄位會覆蓋這個設定。" + +#: src/settings_translation_file.cpp +msgid "" +"Prevent digging and placing from repeating when holding the mouse buttons.\n" +"Enable this when you dig or place too often by accident." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Prevent mods from doing insecure things like running shell commands." +msgstr "避免 mod 做出不安全的舉動,像是執行 shell 指令等。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Print the engine's profiling data in regular intervals (in seconds).\n" +"0 = disable. Useful for developers." +msgstr "引擎性能資料印出間隔的秒數。0 = 停用。對開發者有用。" + +#: src/settings_translation_file.cpp +msgid "Privileges that players with basic_privs can grant" +msgstr "有 basic_privs 的玩家可以提升特權" + +#: src/settings_translation_file.cpp +msgid "Profiler" +msgstr "分析器" + +#: src/settings_translation_file.cpp +msgid "Profiler toggle key" +msgstr "分析器切換鍵" + +#: src/settings_translation_file.cpp +msgid "Prometheus listener address" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Prometheus listener address.\n" +"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n" +"enable metrics listener for Prometheus on that address.\n" +"Metrics can be fetched on http://127.0.0.1:30000/metrics" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Proportion of large caves that contain liquid." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Radius of cloud area stated in number of 64 node cloud squares.\n" +"Values larger than 26 will start to produce sharp cutoffs at cloud area " +"corners." +msgstr "" +"雲區的半徑,以雲立方體的 64 個節點的數目計算。\n" +"大於 26 的值將會在雲的角落有銳角的產生。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Raises terrain to make valleys around the rivers." +msgstr "提升地形以讓山谷在河流周圍" + +#: src/settings_translation_file.cpp +msgid "Random input" +msgstr "隨機輸入" + +#: src/settings_translation_file.cpp +msgid "Range select key" +msgstr "範圍選擇鍵" + +#: src/settings_translation_file.cpp +msgid "Recent Chat Messages" +msgstr "最近聊天訊息" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Regular font path" +msgstr "報告路徑" + +#: src/settings_translation_file.cpp +msgid "Remote media" +msgstr "遠端媒體" + +#: src/settings_translation_file.cpp +msgid "Remote port" +msgstr "遠端埠" + +#: src/settings_translation_file.cpp +msgid "" +"Remove color codes from incoming chat messages\n" +"Use this to stop players from being able to use color in their messages" +msgstr "" +"移除傳入聊天訊息的色彩碼\n" +"使用這個能防止玩家在訊息中使用色彩" + +#: src/settings_translation_file.cpp +msgid "Replaces the default main menu with a custom one." +msgstr "以自訂選單取代預設主選單。" + +#: src/settings_translation_file.cpp +msgid "Report path" +msgstr "報告路徑" + +#: src/settings_translation_file.cpp +msgid "" +"Restricts the access of certain client-side functions on servers.\n" +"Combine the byteflags below to restrict client-side features, or set to 0\n" +"for no restrictions:\n" +"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n" +"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n" +"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n" +"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n" +"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n" +"csm_restriction_noderange)\n" +"READ_PLAYERINFO: 32 (disable get_player_names call client-side)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Ridge mountain spread noise" +msgstr "山脊展開雜訊" + +#: src/settings_translation_file.cpp +msgid "Ridge noise" +msgstr "山脊雜訊" + +#: src/settings_translation_file.cpp +msgid "Ridge underwater noise" +msgstr "水下山脊雜訊" + +#: src/settings_translation_file.cpp +msgid "Ridged mountain size noise" +msgstr "山脊大小雜訊" + +#: src/settings_translation_file.cpp +msgid "Right key" +msgstr "右鍵" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River channel depth" +msgstr "河流深度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River channel width" +msgstr "河流深度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River depth" +msgstr "河流深度" + +#: src/settings_translation_file.cpp +msgid "River noise" +msgstr "河流雜訊" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River size" +msgstr "河流大小" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "River valley width" +msgstr "河流深度" + +#: src/settings_translation_file.cpp +msgid "Rollback recording" +msgstr "返回記錄" + +#: src/settings_translation_file.cpp +msgid "Rolling hill size noise" +msgstr "波狀丘陵地大小雜訊" + +#: src/settings_translation_file.cpp +msgid "Rolling hills spread noise" +msgstr "波狀丘陵地展開雜訊" + +#: src/settings_translation_file.cpp +msgid "Round minimap" +msgstr "圓形小地圖" + +#: src/settings_translation_file.cpp +msgid "Safe digging and placing" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Sandy beaches occur when np_beach exceeds this value." +msgstr "當 np_beach 超過此值時,會生成沙灘。" + +#: src/settings_translation_file.cpp +msgid "Save the map received by the client on disk." +msgstr "由用戶端儲存接收到的地圖到磁碟上。" + +#: src/settings_translation_file.cpp +msgid "Save window size automatically when modified." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Saving map received from server" +msgstr "儲存從伺服器接收到的地圖" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Scale GUI by a user specified value.\n" +"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n" +"This will smooth over some of the rough edges, and blend\n" +"pixels when scaling down, at the cost of blurring some\n" +"edge pixels when images are scaled by non-integer sizes." +msgstr "" +"由使用者指定一個值來作為放大圖形使用者介面的比例。\n" +"使用最近相鄰與反鋸齒過濾器以放大圖形使用者介面。\n" +"這將可以讓一些粗糙的邊緣變得較圓滑,並當\n" +"比例縮小時會混合像素,代價是在模糊一些\n" +"邊緣的像素時會以非整數的大小縮放。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screen" +msgstr "螢幕:" + +#: src/settings_translation_file.cpp +msgid "Screen height" +msgstr "螢幕高度" + +#: src/settings_translation_file.cpp +msgid "Screen width" +msgstr "螢幕寬度" + +#: src/settings_translation_file.cpp +msgid "Screenshot folder" +msgstr "螢幕截圖資料夾" + +#: src/settings_translation_file.cpp +msgid "Screenshot format" +msgstr "螢幕截圖格式" + +#: src/settings_translation_file.cpp +msgid "Screenshot quality" +msgstr "螢幕截圖品質" + +#: src/settings_translation_file.cpp +msgid "" +"Screenshot quality. Only used for JPEG format.\n" +"1 means worst quality; 100 means best quality.\n" +"Use 0 for default quality." +msgstr "" +"螢幕截圖的品質。僅用於 JPEG 格式。\n" +"1 代表最差的品質,100 代表最佳品質。\n" +"使用 0 來使用預設品質。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Screenshots" +msgstr "螢幕擷取" + +#: src/settings_translation_file.cpp +msgid "Seabed noise" +msgstr "海底雜訊" + +#: src/settings_translation_file.cpp +msgid "Second of 4 2D noises that together define hill/mountain range height." +msgstr "四之二 一同定義山丘範圍高度的 2D 雜訊。" + +#: src/settings_translation_file.cpp +msgid "Second of two 3D noises that together define tunnels." +msgstr "二之二 一同定義隧道的 3D 雜訊。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous" +msgstr "請見 http://www.sqlite.org/pragma.html#pragma_synchronous" + +#: src/settings_translation_file.cpp +msgid "Selection box border color (R,G,B)." +msgstr "邊框顏色 (R,G,B) 選取框。" + +#: src/settings_translation_file.cpp +msgid "Selection box color" +msgstr "色彩選取框" + +#: src/settings_translation_file.cpp +msgid "Selection box width" +msgstr "寬度選取框" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Selects one of 18 fractal types.\n" +"1 = 4D \"Roundy\" Mandelbrot set.\n" +"2 = 4D \"Roundy\" Julia set.\n" +"3 = 4D \"Squarry\" Mandelbrot set.\n" +"4 = 4D \"Squarry\" Julia set.\n" +"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" Julia set.\n" +"7 = 4D \"Variation\" Mandelbrot set.\n" +"8 = 4D \"Variation\" Julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n" +"11 = 3D \"Christmas Tree\" Mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" Julia set.\n" +"13 = 3D \"Mandelbulb\" Mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" Julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" Julia set.\n" +"17 = 4D \"Mandelbulb\" Mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" Julia set." +msgstr "" +"從 9 種公式裡選取 18 種碎形。\n" +"1 = 4D \"Roundy\" mandelbrot set.\n" +"2 = 4D \"Roundy\" julia set.\n" +"3 = 4D \"Squarry\" mandelbrot set.\n" +"4 = 4D \"Squarry\" julia set.\n" +"5 = 4D \"Mandy Cousin\" mandelbrot set.\n" +"6 = 4D \"Mandy Cousin\" julia set.\n" +"7 = 4D \"Variation\" mandelbrot set.\n" +"8 = 4D \"Variation\" julia set.\n" +"9 = 3D \"Mandelbrot/Mandelbar\" mandelbrot set.\n" +"10 = 3D \"Mandelbrot/Mandelbar\" julia set.\n" +"11 = 3D \"Christmas Tree\" mandelbrot set.\n" +"12 = 3D \"Christmas Tree\" julia set.\n" +"13 = 3D \"Mandelbulb\" mandelbrot set.\n" +"14 = 3D \"Mandelbulb\" julia set.\n" +"15 = 3D \"Cosine Mandelbulb\" mandelbrot set.\n" +"16 = 3D \"Cosine Mandelbulb\" julia set.\n" +"17 = 4D \"Mandelbulb\" mandelbrot set.\n" +"18 = 4D \"Mandelbulb\" julia set." + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server" +msgstr "伺服器 URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Gameplay" +msgstr "伺服器名稱" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server Security" +msgstr "伺服器描述" + +#: src/settings_translation_file.cpp +msgid "Server URL" +msgstr "伺服器 URL" + +#: src/settings_translation_file.cpp +msgid "Server address" +msgstr "伺服器地址" + +#: src/settings_translation_file.cpp +msgid "Server description" +msgstr "伺服器描述" + +#: src/settings_translation_file.cpp +msgid "Server name" +msgstr "伺服器名稱" + +#: src/settings_translation_file.cpp +msgid "Server port" +msgstr "伺服器埠" + +#: src/settings_translation_file.cpp +msgid "Server side occlusion culling" +msgstr "伺服器端遮擋剔除" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Server/Env Performance" +msgstr "伺服器埠" + +#: src/settings_translation_file.cpp +msgid "Serverlist URL" +msgstr "伺服器清單 URL" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Serverlist and MOTD" +msgstr "伺服器清單 URL" + +#: src/settings_translation_file.cpp +msgid "Serverlist file" +msgstr "伺服器清單檔" + +#: src/settings_translation_file.cpp +msgid "" +"Set the language. Leave empty to use the system language.\n" +"A restart is required after changing this." +msgstr "" +"設定語言。留空以使用系統語言。\n" +"變更後必須重新啟動以使其生效。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set the maximum length of a chat message (in characters) sent by clients." +msgstr "設定用戶端傳送之聊天訊息的最大字元長度。" + +#: src/settings_translation_file.cpp +msgid "" +"Set the shadow strength gamma.\n" +"Adjusts the intensity of in-game dynamic shadows.\n" +"Lower value means lighter shadows, higher value means darker shadows." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the soft shadow radius size.\n" +"Lower values mean sharper shadows, bigger values mean softer shadows.\n" +"Minimum value: 1.0; maximum value: 15.0" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Set the tilt of Sun/Moon orbit in degrees.\n" +"Value of 0 means no tilt / vertical orbit.\n" +"Minimum value: 0.0; maximum value: 60.0" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable Shadow Mapping.\n" +"Requires shaders to be enabled." +msgstr "" +"設定為真以啟用擺動的樹葉。\n" +"必須同時啟用著色器。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving leaves.\n" +"Requires shaders to be enabled." +msgstr "" +"設定為真以啟用擺動的樹葉。\n" +"必須同時啟用著色器。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving liquids (like water).\n" +"Requires shaders to be enabled." +msgstr "" +"設定為真以啟用波動的水。\n" +"必須同時啟用著色器。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Set to true to enable waving plants.\n" +"Requires shaders to be enabled." +msgstr "" +"設定為真以啟用擺動的植物。\n" +"必須同時啟用著色器。" + +#: src/settings_translation_file.cpp +msgid "" +"Sets shadow texture quality to 32 bits.\n" +"On false, 16 bits texture will be used.\n" +"This can cause much more artifacts in the shadow." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shader path" +msgstr "著色器路徑" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Shaders allow advanced visual effects and may increase performance on some " +"video\n" +"cards.\n" +"This only works with the OpenGL video backend." +msgstr "" +"著色器讓您可以有進階視覺效果並可能會在某些顯示卡上增強效能。\n" +"這僅在 OpenGL 視訊後端上才能運作。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow filter quality" +msgstr "螢幕截圖品質" + +#: src/settings_translation_file.cpp +msgid "Shadow map max distance in nodes to render shadows" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shadow map texture in 32 bits" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Shadow map texture size" +msgstr "過濾器的最大材質大小" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Shadow offset (in pixels) of the default font. If 0, then shadow will not be " +"drawn." +msgstr "字型陰影偏移,若為 0 則陰影將不會被繪製。" + +#: src/settings_translation_file.cpp +msgid "Shadow strength gamma" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shape of the minimap. Enabled = round, disabled = square." +msgstr "迷你地圖的形狀。啟用 = 圓形,停用 = 方形。" + +#: src/settings_translation_file.cpp +msgid "Show debug info" +msgstr "顯示除錯資訊" + +#: src/settings_translation_file.cpp +msgid "Show entity selection boxes" +msgstr "顯示物體選取方塊" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Show entity selection boxes\n" +"A restart is required after changing this." +msgstr "" +"設定語言。留空以使用系統語言。\n" +"變更後必須重新啟動以使其生效。" + +#: src/settings_translation_file.cpp +msgid "Show name tag backgrounds by default" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Shutdown message" +msgstr "關閉訊息" + +#: src/settings_translation_file.cpp +msgid "" +"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n" +"WARNING!: There is no benefit, and there are several dangers, in\n" +"increasing this value above 5.\n" +"Reducing this value increases cave and dungeon density.\n" +"Altering this value is for special usage, leaving it unchanged is\n" +"recommended." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Size of the MapBlock cache of the mesh generator. Increasing this will\n" +"increase the cache hit %, reducing the data being copied from the main\n" +"thread, thus reducing jitter." +msgstr "" +"網格生成器的地圖區塊快取大小。增加這個將會\n" +"增加快取命中率,減少從主執行緒複製資料,從\n" +"而減少抖動。" + +#: src/settings_translation_file.cpp +msgid "Sky Body Orbit Tilt" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Slice w" +msgstr "切片 w" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Slope and fill work together to modify the heights." +msgstr "坡度與填充一同運作來修改高度" + +#: src/settings_translation_file.cpp +msgid "Small cave maximum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small cave minimum number" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Small-scale humidity variation for blending biomes on borders." +msgstr "在邊界上的混合生態的溼度變化。" + +#: src/settings_translation_file.cpp +msgid "Small-scale temperature variation for blending biomes on borders." +msgstr "在邊界上的混合生態的溫度變化。" + +#: src/settings_translation_file.cpp +msgid "Smooth lighting" +msgstr "平滑光" + +#: src/settings_translation_file.cpp +msgid "" +"Smooths camera when looking around. Also called look or mouse smoothing.\n" +"Useful for recording videos." +msgstr "" +"當移動與東張西望時讓攝影機變流暢。也稱為觀看或滑鼠流暢。\n" +"對錄影很有用。" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera in cinematic mode. 0 to disable." +msgstr "在電影模式中讓攝影機旋轉變流暢。設為 0 以停用。" + +#: src/settings_translation_file.cpp +msgid "Smooths rotation of camera. 0 to disable." +msgstr "讓旋轉攝影機時較流暢。設為 0 以停用。" + +#: src/settings_translation_file.cpp +msgid "Sneak key" +msgstr "潛行按鍵" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Sneaking speed" +msgstr "走路速度" + +#: src/settings_translation_file.cpp +msgid "Sneaking speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Soft shadow radius" +msgstr "字型陰影 alpha 值" + +#: src/settings_translation_file.cpp +msgid "Sound" +msgstr "聲音" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies URL from which client fetches media instead of using UDP.\n" +"$filename should be accessible from $remote_media$filename via cURL\n" +"(obviously, remote_media should end with a slash).\n" +"Files that are not present will be fetched the usual way." +msgstr "" +"用戶端從指定的 URL 而不是使用 UDP 抓取媒體。\n" +"$filename 應該可以透過 cURL 從 $remote_media$filename 存取。\n" +"(當然,remote_media 部份應以斜線結束)。\n" +"沒有在其中的檔案將會以平常的方式抓取。" + +#: src/settings_translation_file.cpp +msgid "" +"Specifies the default stack size of nodes, items and tools.\n" +"Note that mods or games may explicitly set a stack for certain (or all) " +"items." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread a complete update of shadow map over given amount of frames.\n" +"Higher values might make shadows laggy, lower values\n" +"will consume more resources.\n" +"Minimum value: 1; maximum value: 16" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Spread of light curve boost range.\n" +"Controls the width of the range to be boosted.\n" +"Standard deviation of the light curve boost Gaussian." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Static spawnpoint" +msgstr "靜態重生點" + +#: src/settings_translation_file.cpp +msgid "Steepness noise" +msgstr "坡度雜訊" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Step mountain size noise" +msgstr "山雜訊" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Step mountain spread noise" +msgstr "山雜訊" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Strength of 3D mode parallax." +msgstr "視差強度。" + +#: src/settings_translation_file.cpp +msgid "" +"Strength of light curve boost.\n" +"The 3 'boost' parameters define a range of the light\n" +"curve that is boosted in brightness." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Strict protocol checking" +msgstr "嚴格協議檢查" + +#: src/settings_translation_file.cpp +msgid "Strip color codes" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Surface level of optional water placed on a solid floatland layer.\n" +"Water is disabled by default and will only be placed if this value is set\n" +"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n" +"upper tapering).\n" +"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n" +"When enabling water placement the floatlands must be configured and tested\n" +"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n" +"required value depending on 'mgv7_np_floatland'), to avoid\n" +"server-intensive extreme water flow and to avoid vast flooding of the\n" +"world surface below." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Synchronous SQLite" +msgstr "同步的 SQLite" + +#: src/settings_translation_file.cpp +msgid "Temperature variation for biomes." +msgstr "生態的溫度變化。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Temporary Settings" +msgstr "設定" + +#: src/settings_translation_file.cpp +msgid "Terrain alternative noise" +msgstr "地形替代雜訊" + +#: src/settings_translation_file.cpp +msgid "Terrain base noise" +msgstr "地形基礎高度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Terrain height" +msgstr "地形高度" + +#: src/settings_translation_file.cpp +msgid "Terrain higher noise" +msgstr "地形高處雜訊" + +#: src/settings_translation_file.cpp +msgid "Terrain noise" +msgstr "地形雜訊" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for hills.\n" +"Controls proportion of world area covered by hills.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"山丘的地形雜訊閾值。\n" +"控制山丘覆蓋世界的比例。\n" +"往 0.0 調整一取得較大的比例。" + +#: src/settings_translation_file.cpp +msgid "" +"Terrain noise threshold for lakes.\n" +"Controls proportion of world area covered by lakes.\n" +"Adjust towards 0.0 for a larger proportion." +msgstr "" +"湖泊的地形雜訊閾值。\n" +"控制湖泊覆蓋世界的比例。\n" +"往 0.0 調整一取得較大的比例。" + +#: src/settings_translation_file.cpp +msgid "Terrain persistence noise" +msgstr "地形持續性雜訊" + +#: src/settings_translation_file.cpp +msgid "Texture path" +msgstr "材質路徑" + +#: src/settings_translation_file.cpp +msgid "" +"Texture size to render the shadow map on.\n" +"This must be a power of two.\n" +"Bigger numbers create better shadows but it is also more expensive." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Textures on a node may be aligned either to the node or to the world.\n" +"The former mode suits better things like machines, furniture, etc., while\n" +"the latter makes stairs and microblocks fit surroundings better.\n" +"However, as this possibility is new, thus may not be used by older servers,\n" +"this option allows enforcing it for certain node types. Note though that\n" +"that is considered EXPERIMENTAL and may not work properly." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The URL for the content repository" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The dead zone of the joystick" +msgstr "要使用的搖桿的識別碼" + +#: src/settings_translation_file.cpp +msgid "" +"The default format in which profiles are being saved,\n" +"when calling `/profiler save [format]` without format." +msgstr "" +"設定被儲存為預設格式。\n" +"當呼叫「/profiler save [格式]」但不包含格式時。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "The depth of dirt or other biome filler node." +msgstr "塵土或其他填充物的深度" + +#: src/settings_translation_file.cpp +msgid "" +"The file path relative to your worldpath in which profiles will be saved to." +msgstr "設定檔將儲存於相對於您的全域路徑的檔案路徑。" + +#: src/settings_translation_file.cpp +msgid "The identifier of the joystick to use" +msgstr "要使用的搖桿的識別碼" + +#: src/settings_translation_file.cpp +msgid "The length in pixels it takes for touch screen interaction to start." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The maximum height of the surface of waving liquids.\n" +"4.0 = Wave height is two nodes.\n" +"0.0 = Wave doesn't move at all.\n" +"Default is 1.0 (1/2 node).\n" +"Requires waving liquids to be enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "The network interface that the server listens on." +msgstr "伺服器要監聽的網路介面。" + +#: src/settings_translation_file.cpp +msgid "" +"The privileges that new users automatically get.\n" +"See /privs in game for a full list on your server and mod configuration." +msgstr "" +"新使用者會自動取得的特權。\n" +"在遊戲中請見 /privs 以取得在您的伺服器上與 mod 設定的完整清單。" + +#: src/settings_translation_file.cpp +msgid "" +"The radius of the volume of blocks around every player that is subject to " +"the\n" +"active block stuff, stated in mapblocks (16 nodes).\n" +"In active blocks objects are loaded and ABMs run.\n" +"This is also the minimum range in which active objects (mobs) are " +"maintained.\n" +"This should be configured together with active_object_send_range_blocks." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The rendering back-end.\n" +"A restart is required after changing this.\n" +"Note: On Android, stick with OGLES1 if unsure! App may fail to start " +"otherwise.\n" +"On other platforms, OpenGL is recommended.\n" +"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)" +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The sensitivity of the joystick axes for moving the\n" +"in-game view frustum around." +msgstr "" +"在遊戲中,視野四處移動時的\n" +"搖桿靈敏度。" + +#: src/settings_translation_file.cpp +msgid "" +"The strength (darkness) of node ambient-occlusion shading.\n" +"Lower is darker, Higher is lighter. The valid range of values for this\n" +"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n" +"set to the nearest valid value." +msgstr "" +"節點環境光遮蔽的強度(暗度)。\n" +"愈低愈暗,愈高愈亮。這個設定的\n" +"值的有效範圍是 0.25 到 4.0 間。如果\n" +"值超出範圍,其將會被設定為最近的有效值。" + +#: src/settings_translation_file.cpp +msgid "" +"The time (in seconds) that the liquids queue may grow beyond processing\n" +"capacity until an attempt is made to decrease its size by dumping old queue\n" +"items. A value of 0 disables the functionality." +msgstr "" +"液體佇列可能會超出處理容量的時間(以秒計)\n" +"超過時將會嘗試透過傾倒舊佇列項目減少其\n" +"大小。將值設為 0 以停用此功能。" + +#: src/settings_translation_file.cpp +msgid "" +"The time budget allowed for ABMs to execute on each step\n" +"(as a fraction of the ABM Interval)" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"The time in seconds it takes between repeated events\n" +"when holding down a joystick button combination." +msgstr "" +"在重複的事件間以秒計的時間\n" +"當按住搖桿的組合。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"The time in seconds it takes between repeated node placements when holding\n" +"the place button." +msgstr "當按住滑鼠右鍵時,重覆右鍵點選的間隔以秒計。" + +#: src/settings_translation_file.cpp +msgid "The type of joystick" +msgstr "搖桿類型" + +#: src/settings_translation_file.cpp +msgid "" +"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n" +"enabled. Also the vertical distance over which humidity drops by 10 if\n" +"'altitude_dry' is enabled." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Third of 4 2D noises that together define hill/mountain range height." +msgstr "四之三 一同定義山丘範圍高度的 2D 雜訊。" + +#: src/settings_translation_file.cpp +msgid "" +"Time in seconds for item entity (dropped items) to live.\n" +"Setting it to -1 disables the feature." +msgstr "" +"物品物體(丟棄的物品)可以存活多久,以秒計。\n" +"設定其為 -1 以停用這個功能。" + +#: src/settings_translation_file.cpp +msgid "Time of day when a new world is started, in millihours (0-23999)." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Time send interval" +msgstr "時間傳送間隔" + +#: src/settings_translation_file.cpp +msgid "Time speed" +msgstr "時間速度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Timeout for client to remove unused map data from memory, in seconds." +msgstr "用戶端從記憶體移除未使用的地圖資料的逾時時間。" + +#: src/settings_translation_file.cpp +msgid "" +"To reduce lag, block transfers are slowed down when a player is building " +"something.\n" +"This determines how long they are slowed down after placing or removing a " +"node." +msgstr "" +"為了降低延遲,區塊傳送將會在玩家建造東西時減速。\n" +"這將會決定放置或移除節點後減速多久。" + +#: src/settings_translation_file.cpp +msgid "Toggle camera mode key" +msgstr "切換攝影機模式按鍵" + +#: src/settings_translation_file.cpp +msgid "Tooltip delay" +msgstr "工具提示延遲" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touch screen threshold" +msgstr "海灘雜訊閾值" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Touchscreen" +msgstr "海灘雜訊閾值" + +#: src/settings_translation_file.cpp +msgid "Tradeoffs for performance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Transparency Sorting Distance" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Trees noise" +msgstr "樹林雜訊" + +#: src/settings_translation_file.cpp +msgid "Trilinear filtering" +msgstr "三線性過濾器" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"True = 256\n" +"False = 128\n" +"Usable to make minimap smoother on slower machines." +msgstr "" +"True = 256\n" +"False = 128\n" +"對於讓迷你地圖在較慢的機器上變得流暢有效。" + +#: src/settings_translation_file.cpp +msgid "Trusted mods" +msgstr "信任的 mod" + +#: src/settings_translation_file.cpp +msgid "URL to the server list displayed in the Multiplayer Tab." +msgstr "會在多人遊戲分頁中顯示的伺服器清單的 URL。" + +#: src/settings_translation_file.cpp +msgid "Undersampling" +msgstr "Undersampling" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Undersampling is similar to using a lower screen resolution, but it applies\n" +"to the game world only, keeping the GUI intact.\n" +"It should give a significant performance boost at the cost of less detailed " +"image.\n" +"Higher values result in a less detailed image." +msgstr "" +"Undersampling 類似於較低的螢幕解析度,但其\n" +"僅適用於遊戲世界,保持圖形使用者介面完好無損。\n" +"它應該有顯著的效能提升,代價是細節較差的圖片。" + +#: src/settings_translation_file.cpp +msgid "Unlimited player transfer distance" +msgstr "不限制玩家傳送距離" + +#: src/settings_translation_file.cpp +msgid "Unload unused server data" +msgstr "卸除未使用的伺服器資料" + +#: src/settings_translation_file.cpp +msgid "Upper Y limit of dungeons." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Upper Y limit of floatlands." +msgstr "大型偽隨機洞穴的 Y 上限。" + +#: src/settings_translation_file.cpp +msgid "Use 3D cloud look instead of flat." +msgstr "使用 3D 立體而非扁平的雲朵外觀。" + +#: src/settings_translation_file.cpp +msgid "Use a cloud animation for the main menu background." +msgstr "在主選單的背景使用雲朵動畫。" + +#: src/settings_translation_file.cpp +msgid "Use anisotropic filtering when viewing at textures from an angle." +msgstr "當從某個角度觀看時啟用各向異性過濾。" + +#: src/settings_translation_file.cpp +msgid "Use bilinear filtering when scaling textures." +msgstr "當縮放材質時使用雙線性過濾。" + +#: src/settings_translation_file.cpp +msgid "" +"Use mipmapping to scale textures. May slightly increase performance,\n" +"especially when using a high resolution texture pack.\n" +"Gamma correct downscaling is not supported." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n" +"This algorithm smooths out the 3D viewport while keeping the image sharp,\n" +"but it doesn't affect the insides of textures\n" +"(which is especially noticeable with transparent textures).\n" +"Visible spaces appear between nodes when shaders are disabled.\n" +"If set to 0, MSAA is disabled.\n" +"A restart is required after changing this option." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Use trilinear filtering when scaling textures." +msgstr "當縮放材質時使用三線性過濾。" + +#: src/settings_translation_file.cpp +msgid "User Interfaces" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "VBO" +msgstr "VBO" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "VSync" +msgstr "垂直同步" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Valley depth" +msgstr "山谷深度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Valley fill" +msgstr "山谷填充" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Valley profile" +msgstr "山谷分析" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Valley slope" +msgstr "山谷坡度" + +#: src/settings_translation_file.cpp +msgid "Variation of biome filler depth." +msgstr "生物群填充深度變化。" + +#: src/settings_translation_file.cpp +msgid "Variation of maximum mountain height (in nodes)." +msgstr "最大山高變化(以節點計)。" + +#: src/settings_translation_file.cpp +msgid "Variation of number of caves." +msgstr "洞穴數量的變化。" + +#: src/settings_translation_file.cpp +msgid "" +"Variation of terrain vertical scale.\n" +"When noise is < -0.55 terrain is near-flat." +msgstr "" +"垂直地形大小的變化。\n" +"當雜訊 < -0.55 則地形近乎平坦。" + +#: src/settings_translation_file.cpp +msgid "Varies depth of biome surface nodes." +msgstr "生物群表面節點的深度變化。" + +#: src/settings_translation_file.cpp +msgid "" +"Varies roughness of terrain.\n" +"Defines the 'persistence' value for terrain_base and terrain_alt noises." +msgstr "" +"地形粗糙度變化。\n" +"為 terrain_base 與 terrain_alt 雜訊定義 'persistence' 值。" + +#: src/settings_translation_file.cpp +msgid "Varies steepness of cliffs." +msgstr "懸崖坡度變化。" + +#: src/settings_translation_file.cpp +msgid "Vertical climbing speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Vertical screen synchronization." +msgstr "垂直螢幕同步。" + +#: src/settings_translation_file.cpp +msgid "Video driver" +msgstr "顯示卡驅動程式" + +#: src/settings_translation_file.cpp +msgid "View bobbing factor" +msgstr "視野晃動因子" + +#: src/settings_translation_file.cpp +msgid "View distance in nodes." +msgstr "以節點數計算的視野距離。" + +#: src/settings_translation_file.cpp +msgid "View range decrease key" +msgstr "降低視野的按鍵" + +#: src/settings_translation_file.cpp +msgid "View range increase key" +msgstr "增加視野的按鍵" + +#: src/settings_translation_file.cpp +msgid "View zoom key" +msgstr "檢視縮放鍵" + +#: src/settings_translation_file.cpp +msgid "Viewing range" +msgstr "視野" + +#: src/settings_translation_file.cpp +msgid "Virtual joystick triggers Aux1 button" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Volume" +msgstr "音量" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"Volume of all sounds.\n" +"Requires the sound system to be enabled." +msgstr "" +"啟用視差遮蔽貼圖。\n" +"必須啟用著色器。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"W coordinate of the generated 3D slice of a 4D fractal.\n" +"Determines which 3D slice of the 4D shape is generated.\n" +"Alters the shape of the fractal.\n" +"Has no effect on 3D fractals.\n" +"Range roughly -2 to 2." +msgstr "" +"4D 碎形生成的 3D 切片的 W 座標。\n" +"決定了會生成怎樣的 4D 形狀的 3D 切片。\n" +"對 3D 碎形沒有影響。\n" +"範圍約在 -2 至 2 間。" + +#: src/settings_translation_file.cpp +msgid "Walking and flying speed, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Walking speed" +msgstr "走路速度" + +#: src/settings_translation_file.cpp +msgid "Walking, flying and climbing speed in fast mode, in nodes per second." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Water level" +msgstr "水位" + +#: src/settings_translation_file.cpp +msgid "Water surface level of the world." +msgstr "世界的水面高度。" + +#: src/settings_translation_file.cpp +msgid "Waving Nodes" +msgstr "擺動節點" + +#: src/settings_translation_file.cpp +msgid "Waving leaves" +msgstr "葉子擺動" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids" +msgstr "擺動節點" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave height" +msgstr "波動的水高度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wave speed" +msgstr "波動的水速度" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Waving liquids wavelength" +msgstr "波動的水長度" + +#: src/settings_translation_file.cpp +msgid "Waving plants" +msgstr "植物擺動" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Weblink color" +msgstr "色彩選取框" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter is true, all GUI images need to be\n" +"filtered in software, but some images are generated directly\n" +"to hardware (e.g. render-to-texture for nodes in inventory)." +msgstr "" +"當 gui_scaling_filter 被設定為真時,所有的圖形使用者介面的圖片\n" +"都必須被軟體過濾,但是有一些圖片會被直接生成到\n" +"硬體(例如在物品欄中節點的繪圖至材質)。" + +#: src/settings_translation_file.cpp +msgid "" +"When gui_scaling_filter_txr2img is true, copy those images\n" +"from hardware to software for scaling. When false, fall back\n" +"to the old scaling method, for video drivers that don't\n" +"properly support downloading textures back from hardware." +msgstr "" +"當 gui_scaling_filter_txr2img 被設定為真,複製這些圖片\n" +"從硬體到軟體以供縮放。當為假時,退回\n" +"至舊的縮放方法,供從硬體下載材質回\n" +"來軟體支援不佳的顯示卡驅動程式使用。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "" +"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" +"can be blurred, so automatically upscale them with nearest-neighbor\n" +"interpolation to preserve crisp pixels. This sets the minimum texture size\n" +"for the upscaled textures; higher values look sharper, but require more\n" +"memory. Powers of 2 are recommended. This setting is ONLY applied if\n" +"bilinear/trilinear/anisotropic filtering is enabled.\n" +"This is also used as the base node texture size for world-aligned\n" +"texture autoscaling." +msgstr "" +"當使用雙線性/三線性/各向異性過濾器時,低解析度材質\n" +"會被模糊,所以會自動將大小縮放至最近的內插值\n" +"以讓像素保持清晰。這會設定最小材質大小\n" +"供放大材質使用;較高的值看起來較銳利,但需要更多的\n" +"記憶體。建議為 2 的次方。將這個值設定高於 1 不會\n" +"有任何視覺效果,除非雙線性/三線性/各向異性過濾\n" +"已啟用。" + +#: src/settings_translation_file.cpp +msgid "" +"Whether name tag backgrounds should be shown by default.\n" +"Mods may still set a background." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Whether node texture animations should be desynchronized per mapblock." +msgstr "是否每個地圖區塊的節點材質動畫可以不同步。" + +#: src/settings_translation_file.cpp +msgid "" +"Whether players are shown to clients without any range limit.\n" +"Deprecated, use the setting player_transfer_distance instead." +msgstr "" +"玩家是否應該在用戶端無距離限制地顯示。\n" +"已棄用,請用 setting player_transfer_distance 代替。" + +#: src/settings_translation_file.cpp +msgid "Whether to allow players to damage and kill each other." +msgstr "是否允許玩家傷害並殺害其他人。" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to ask clients to reconnect after a (Lua) crash.\n" +"Set this to true if your server is set up to restart automatically." +msgstr "" +"是否要在 (Lua) 當掉後詢問用戶端是否重新連線。\n" +"如果您的伺服器被設定為會自動重新開啟,將這個設定為真。" + +#: src/settings_translation_file.cpp +msgid "Whether to fog out the end of the visible area." +msgstr "是否將可視區域外模糊。" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to mute sounds. You can unmute sounds at any time, unless the\n" +"sound system is disabled (enable_sound=false).\n" +"In-game, you can toggle the mute state with the mute key or by using the\n" +"pause menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show technical names.\n" +"Affects mods and texture packs in the Content and Select Mods menus, as well " +"as\n" +"setting names in All Settings.\n" +"Controlled by the checkbox in the \"All settings\" menu." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "" +"Whether to show the client debug info (has the same effect as hitting F5)." +msgstr "是否顯示用戶端除錯資訊(與按下 F5 有同樣的效果)。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width component of the initial window size. Ignored in fullscreen mode." +msgstr "初始視窗大小的寬度元素。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Width of the selection box lines around nodes." +msgstr "選取框在節點周邊的選取框線。" + +#: src/settings_translation_file.cpp +msgid "" +"Windows systems only: Start Minetest with the command line window in the " +"background.\n" +"Contains the same information as the file debug.txt (default name)." +msgstr "" +"僅 Windows 系統:以在背景的命令列視窗啟動 Minetest。\n" +"包含與 debug.txt(預設名稱)檔案相同的的資訊。" + +#: src/settings_translation_file.cpp +msgid "" +"World directory (everything in the world is stored here).\n" +"Not needed if starting from the main menu." +msgstr "" +"世界目錄(在世界中的每個東西都儲存在這裡)。\n" +"若從主選單啟動則不需要。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "World start time" +msgstr "世界遊戲" + +#: src/settings_translation_file.cpp +msgid "" +"World-aligned textures may be scaled to span several nodes. However,\n" +"the server may not send the scale you want, especially if you use\n" +"a specially-designed texture pack; with this option, the client tries\n" +"to determine the scale automatically basing on the texture size.\n" +"See also texture_min_size.\n" +"Warning: This option is EXPERIMENTAL!" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "World-aligned textures mode" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y of flat ground." +msgstr "扁平地面的 Y。" + +#: src/settings_translation_file.cpp +msgid "" +"Y of mountain density gradient zero level. Used to shift mountains " +"vertically." +msgstr "" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Y of upper limit of large caves." +msgstr "大型偽隨機洞穴的 Y 上限。" + +#: src/settings_translation_file.cpp +msgid "Y-distance over which caverns expand to full size." +msgstr "洞穴拓展至全尺寸的 Y 距離。" + +#: src/settings_translation_file.cpp +msgid "" +"Y-distance over which floatlands taper from full density to nothing.\n" +"Tapering starts at this distance from the Y limit.\n" +"For a solid floatland layer, this controls the height of hills/mountains.\n" +"Must be less than or equal to half the distance between the Y limits." +msgstr "" + +#: src/settings_translation_file.cpp +msgid "Y-level of average terrain surface." +msgstr "平均地形表面的 Y 高度。" + +#: src/settings_translation_file.cpp +msgid "Y-level of cavern upper limit." +msgstr "洞穴上限的 Y 高度。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Y-level of higher terrain that creates cliffs." +msgstr "較低地形與湖底的 Y 高度。" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "Y-level of lower terrain and seabed." +msgstr "較低地形與湖底的 Y 高度。" + +#: src/settings_translation_file.cpp +msgid "Y-level of seabed." +msgstr "海底的 Y 高度。" + +#: src/settings_translation_file.cpp +msgid "cURL" +msgstr "" + +#: src/settings_translation_file.cpp +msgid "cURL file download timeout" +msgstr "cURL 檔案下載逾時" + +#: src/settings_translation_file.cpp +#, fuzzy +msgid "cURL interactive timeout" +msgstr "cURL 逾時" + +#: src/settings_translation_file.cpp +msgid "cURL parallel limit" +msgstr "cURL 並行限制" + +#~ msgid "- Creative Mode: " +#~ msgstr "- 創造模式: " + +#~ msgid "- Damage: " +#~ msgstr "- 傷害: " + +#~ msgid "" +#~ "0 = parallax occlusion with slope information (faster).\n" +#~ "1 = relief mapping (slower, more accurate)." +#~ msgstr "" +#~ "0 = 包含斜率資訊的視差遮蔽(較快)。\n" +#~ "1 = 替換貼圖(較慢,較準確)。" + +#~ msgid "Address / Port" +#~ msgstr "地址/連線埠" + +#~ msgid "" +#~ "Adjust the gamma encoding for the light tables. Higher numbers are " +#~ "brighter.\n" +#~ "This setting is for the client only and is ignored by the server." +#~ msgstr "" +#~ "調整亮度表的伽瑪編碼。較高的數值會較亮。\n" +#~ "這個設定是給客戶端使用的,會被伺服器忽略。" + +#~ msgid "Are you sure to reset your singleplayer world?" +#~ msgstr "您確定要重設您的單人遊戲世界嗎?" + +#~ msgid "Back" +#~ msgstr "返回" + +#~ msgid "Basic" +#~ msgstr "基礎" + +#~ msgid "Bits per pixel (aka color depth) in fullscreen mode." +#~ msgstr "全螢幕模式中的位元/像素(又稱色彩深度)。" + +#~ msgid "Bump Mapping" +#~ msgstr "映射貼圖" + +#~ msgid "Bumpmapping" +#~ msgstr "映射貼圖" + +#~ msgid "Config mods" +#~ msgstr "設定 Mod" + +#~ msgid "Configure" +#~ msgstr "設定" + +#~ msgid "Connect" +#~ msgstr "連線" + +#~ msgid "Controls sinking speed in liquid." +#~ msgstr "控制在液體中的下沉速度。" + +#, fuzzy +#~ msgid "" +#~ "Controls the density of mountain-type floatlands.\n" +#~ "Is a noise offset added to the 'mgv7_np_mountain' noise value." +#~ msgstr "" +#~ "控制山地的浮地密度。\n" +#~ "是加入到 'np_mountain' 噪音值的補償。" + +#~ msgid "Controls width of tunnels, a smaller value creates wider tunnels." +#~ msgstr "控制隧道的寬度,較小的值會創造出較寬的隧道。" + +#~ msgid "Credits" +#~ msgstr "感謝" + +#~ msgid "Crosshair color (R,G,B)." +#~ msgstr "十字色彩 (R,G,B)。" + +#~ msgid "Damage enabled" +#~ msgstr "已啟用傷害" + +#, fuzzy +#~ msgid "Darkness sharpness" +#~ msgstr "湖泊坡度" + +#~ msgid "" +#~ "Default timeout for cURL, stated in milliseconds.\n" +#~ "Only has an effect if compiled with cURL." +#~ msgstr "" +#~ "cURL 的預設逾時,以毫秒計算。\n" +#~ "只會在與 cURL 一同編譯的情況下才會有影響。" + +#~ msgid "" +#~ "Defines areas of floatland smooth terrain.\n" +#~ "Smooth floatlands occur when noise > 0." +#~ msgstr "" +#~ "定義浮地的平整地形區。\n" +#~ "平整的浮地會在噪音 > 0 時產生。" + +#~ msgid "" +#~ "Defines sampling step of texture.\n" +#~ "A higher value results in smoother normal maps." +#~ msgstr "" +#~ "定義材質的採樣步驟。\n" +#~ "較高的值會有較平滑的一般地圖。" + +#~ msgid "Del. Favorite" +#~ msgstr "刪除收藏" + +#~ msgid "Download a game, such as Minetest Game, from minetest.net" +#~ msgstr "從 minetest.net 下載遊戲,例如 Minetest Game" + +#~ msgid "Download one from minetest.net" +#~ msgstr "從 minetest.net 下載一個" + +#~ msgid "Downloading and installing $1, please wait..." +#~ msgstr "正在下載並安裝 $1,請稍候……" + +#~ msgid "Enable VBO" +#~ msgstr "啟用 VBO" + +#~ msgid "Enable register confirmation" +#~ msgstr "啟用註冊確認" + +#~ msgid "" +#~ "Enables bumpmapping for textures. Normalmaps need to be supplied by the " +#~ "texture pack\n" +#~ "or need to be auto-generated.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "為材質啟用貼圖轉儲。普通地圖需要材質包的支援\n" +#~ "或是自動生成。\n" +#~ "必須啟用著色器。" + +#~ msgid "Enables filmic tone mapping" +#~ msgstr "啟用電影色調映射" + +#~ msgid "" +#~ "Enables on the fly normalmap generation (Emboss effect).\n" +#~ "Requires bumpmapping to be enabled." +#~ msgstr "" +#~ "啟用忙碌的一般地圖生成(浮雕效果)。\n" +#~ "必須啟用貼圖轉儲。" + +#~ msgid "" +#~ "Enables parallax occlusion mapping.\n" +#~ "Requires shaders to be enabled." +#~ msgstr "" +#~ "啟用視差遮蔽貼圖。\n" +#~ "必須啟用著色器。" + +#~ msgid "Enter " +#~ msgstr "輸入 " + +#~ msgid "" +#~ "Experimental option, might cause visible spaces between blocks\n" +#~ "when set to higher number than 0." +#~ msgstr "" +#~ "實驗性選項,當設定到大於零的值時\n" +#~ "也許會造成在方塊間有視覺空隙。" + +#~ msgid "FPS in pause menu" +#~ msgstr "在暫停選單中的 FPS" + +#~ msgid "Fallback font shadow" +#~ msgstr "後備字型陰影" + +#~ msgid "Fallback font shadow alpha" +#~ msgstr "後備字型陰影 alpha 值" + +#~ msgid "Fallback font size" +#~ msgstr "後備字型大小" + +#~ msgid "Filtering" +#~ msgstr "過濾器" + +#~ msgid "Floatland base height noise" +#~ msgstr "浮地基礎高度噪音" + +#~ msgid "Font shadow alpha (opaqueness, between 0 and 255)." +#~ msgstr "字型陰影 alpha(不透明度,介於 0 到 255)。" + +#, fuzzy +#~ msgid "FreeType fonts" +#~ msgstr "Freetype 字型" + +#~ msgid "Full screen BPP" +#~ msgstr "全螢幕 BPP" + +#~ msgid "Game" +#~ msgstr "遊戲" + +#~ msgid "Gamma" +#~ msgstr "Gamma" + +#~ msgid "Generate Normal Maps" +#~ msgstr "產生一般地圖" + +#~ msgid "Generate normalmaps" +#~ msgstr "生成一般地圖" + +#~ msgid "HUD scale factor" +#~ msgstr "HUD 縮放係數" + +#~ msgid "High-precision FPU" +#~ msgstr "高精度 FPU" + +#~ msgid "IPv6 support." +#~ msgstr "IPv6 支援。" + +#~ msgid "In-Game" +#~ msgstr "遊戲中" + +#~ msgid "Install: file: \"$1\"" +#~ msgstr "安裝:檔案:「$1」" + +#~ msgid "Instrumentation" +#~ msgstr "儀表" + +#~ msgid "" +#~ "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" +#~ msgstr "按鍵綁定。(若此選單鎖住了,從 minetest.conf 移除相關參數)" + +#, fuzzy +#~ msgid "Lava depth" +#~ msgstr "大型洞穴深度" + +#~ msgid "Limit of emerge queues on disk" +#~ msgstr "在磁碟上出現佇列的限制" + +#~ msgid "Main" +#~ msgstr "主要" + +#, fuzzy +#~ msgid "Main menu style" +#~ msgstr "主選單指令稿" + +#~ msgid "Makes DirectX work with LuaJIT. Disable if it causes troubles." +#~ msgstr "讓 DirectX 與 LuaJIT 一同運作。若其造成麻煩則請停用。" + +#~ msgid "Menus" +#~ msgstr "選單" + +#~ msgid "Minimap in radar mode, Zoom x2" +#~ msgstr "雷達模式的迷你地圖,放大 2 倍" + +#~ msgid "Minimap in radar mode, Zoom x4" +#~ msgstr "雷達模式的迷你地圖,放大 4 倍" + +#~ msgid "Minimap in surface mode, Zoom x2" +#~ msgstr "表面模式的迷你地圖,放大 2 倍" + +#~ msgid "Minimap in surface mode, Zoom x4" +#~ msgstr "表面模式的迷你地圖,放大 4 倍" + +#~ msgid "Name / Password" +#~ msgstr "名稱/密碼" + +#~ msgid "Name/Password" +#~ msgstr "名稱/密碼" + +#~ msgid "No" +#~ msgstr "否" + +#~ msgid "Normalmaps sampling" +#~ msgstr "法線貼圖採樣" + +#~ msgid "Normalmaps strength" +#~ msgstr "法線貼圖強度" + +#~ msgid "Number of parallax occlusion iterations." +#~ msgstr "視差遮蔽迭代次數。" + +#~ msgid "Ok" +#~ msgstr "確定" + +#~ msgid "Overall bias of parallax occlusion effect, usually scale/2." +#~ msgstr "視差遮蔽效果的總偏差,通常是規模/2。" + +#~ msgid "Overall scale of parallax occlusion effect." +#~ msgstr "視差遮蔽效果的總規模。" + +#~ msgid "Parallax Occlusion" +#~ msgstr "視差遮蔽" + +#~ msgid "Parallax occlusion" +#~ msgstr "視差遮蔽" + +#~ msgid "Parallax occlusion bias" +#~ msgstr "視差遮蔽偏差" + +#~ msgid "Parallax occlusion iterations" +#~ msgstr "視差遮蔽迭代" + +#~ msgid "Parallax occlusion mode" +#~ msgstr "視差遮蔽模式" + +#, fuzzy +#~ msgid "Parallax occlusion scale" +#~ msgstr "視差遮蔽係數" + +#~ msgid "Parallax occlusion strength" +#~ msgstr "視差遮蔽強度" + +#~ msgid "Path to TrueTypeFont or bitmap." +#~ msgstr "TrueType 字型或點陣字的路徑。" + +#~ msgid "Path to save screenshots at." +#~ msgstr "儲存螢幕截圖的路徑。" + +#~ msgid "Player name" +#~ msgstr "玩家名稱" + +#~ msgid "Profiling" +#~ msgstr "分析" + +#~ msgid "PvP enabled" +#~ msgstr "已啟用玩家對戰" + +#~ msgid "Reset singleplayer world" +#~ msgstr "重設單人遊戲世界" + +#, fuzzy +#~ msgid "Select Package File:" +#~ msgstr "選取 Mod 檔案:" + +#~ msgid "Server / Singleplayer" +#~ msgstr "伺服器/單人遊戲" + +#~ msgid "Shadow limit" +#~ msgstr "陰影限制" + +#, fuzzy +#~ msgid "" +#~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will " +#~ "not be drawn." +#~ msgstr "字型陰影偏移,若為 0 則陰影將不會被繪製。" + +#~ msgid "Special" +#~ msgstr "特殊" + +#, fuzzy +#~ msgid "Special key" +#~ msgstr "潛行按鍵" + +#~ msgid "Start Singleplayer" +#~ msgstr "開始單人遊戲" + +#~ msgid "Strength of generated normalmaps." +#~ msgstr "生成之一般地圖的強度。" + +#~ msgid "This font will be used for certain languages." +#~ msgstr "這個字型將會被用於特定的語言。" + +#~ msgid "To enable shaders the OpenGL driver needs to be used." +#~ msgstr "要啟用著色器,必須使用 OpenGL 驅動程式。" + +#~ msgid "Toggle Cinematic" +#~ msgstr "切換過場動畫" + +#, fuzzy +#~ msgid "" +#~ "Typical maximum height, above and below midpoint, of floatland mountains." +#~ msgstr "浮地山區域的典型最大高度,高於與低於中點。" + +#~ msgid "Variation of hill height and lake depth on floatland smooth terrain." +#~ msgstr "在平整浮地地形的山丘高度與湖泊深度變化。" + +#~ msgid "View" +#~ msgstr "查看" + +#~ msgid "Waving Water" +#~ msgstr "波動的水" + +#~ msgid "Waving water" +#~ msgstr "波動的水" + +#, fuzzy +#~ msgid "" +#~ "Whether FreeType fonts are used, requires FreeType support to be compiled " +#~ "in.\n" +#~ "If disabled, bitmap and XML vectors fonts are used instead." +#~ msgstr "是否使用 freetype 字型,需要將 freetype 支援編譯進來。" + +#, fuzzy +#~ msgid "Y of upper limit of lava in large caves." +#~ msgstr "大型偽隨機洞穴的 Y 上限。" + +#~ msgid "Y-level of floatland midpoint and lake surface." +#~ msgstr "浮地中點與湖表面的 Y 高度。" + +#~ msgid "Y-level to which floatland shadows extend." +#~ msgstr "浮地陰影擴展的 Y 高度。" + +#~ msgid "Yes" +#~ msgstr "是" + +#, c-format +#~ msgid "" +#~ "You are about to join this server with the name \"%s\" for the first " +#~ "time.\n" +#~ "If you proceed, a new account using your credentials will be created on " +#~ "this server.\n" +#~ "Please retype your password and click 'Register and Join' to confirm " +#~ "account creation, or click 'Cancel' to abort." +#~ msgstr "" +#~ "您第一次使用「%s」名稱加入這個伺服器。\n" +#~ "如您繼續,即會在這台伺服器使用你的憑證建立新帳戶。\n" +#~ "請重新輸入您的密碼,後按下「註冊並加入」確認帳戶建立,或按「取消」中止。" + +#, fuzzy +#~ msgid "You died." +#~ msgstr "您已死亡" + +#~ msgid "needs_fallback_font" +#~ msgstr "yes" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..c068be5 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,910 @@ +project(minetest) + +INCLUDE(CheckIncludeFiles) +INCLUDE(CheckLibraryExists) + +# Add custom SemiDebug build mode +set(CMAKE_CXX_FLAGS_SEMIDEBUG "-O1 -g -Wall" CACHE STRING + "Flags used by the C++ compiler during semidebug builds." + FORCE +) +set(CMAKE_C_FLAGS_SEMIDEBUG "-O1 -g -Wall -pedantic" CACHE STRING + "Flags used by the C compiler during semidebug builds." + FORCE +) +mark_as_advanced( + CMAKE_CXX_FLAGS_SEMIDEBUG + CMAKE_C_FLAGS_SEMIDEBUG +) +set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING + "Choose the type of build. Options are: None Debug SemiDebug RelWithDebInfo MinSizeRel." + FORCE +) + + +# Set some random things default to not being visible in the GUI +mark_as_advanced(EXECUTABLE_OUTPUT_PATH LIBRARY_OUTPUT_PATH) + + +if(NOT (BUILD_CLIENT OR BUILD_SERVER)) + message(WARNING "Neither BUILD_CLIENT nor BUILD_SERVER is set! Setting BUILD_SERVER=true") + set(BUILD_SERVER TRUE) +endif() + + +option(ENABLE_CURL "Enable cURL support for fetching media" TRUE) +set(USE_CURL FALSE) + +if(ENABLE_CURL) + find_package(CURL) + if (CURL_FOUND) + message(STATUS "cURL support enabled.") + set(USE_CURL TRUE) + endif() +else() + mark_as_advanced(CLEAR CURL_LIBRARY CURL_INCLUDE_DIR) +endif() + +if(NOT USE_CURL) + if(BUILD_CLIENT) + message(WARNING "cURL is required to load the server list") + endif() + if(BUILD_SERVER) + message(WARNING "cURL is required to announce to the server list") + endif() +endif() + + +option(ENABLE_GETTEXT "Use GetText for internationalization" ${BUILD_CLIENT}) +set(USE_GETTEXT FALSE) + +if(ENABLE_GETTEXT) + find_package(GettextLib) + if(GETTEXTLIB_FOUND) + if(WIN32) + message(STATUS "GetText library: ${GETTEXT_LIBRARY}") + message(STATUS "GetText DLL(s): ${GETTEXT_DLL}") + endif() + set(USE_GETTEXT TRUE) + message(STATUS "GetText enabled; locales found: ${GETTEXT_AVAILABLE_LOCALES}") + endif(GETTEXTLIB_FOUND) +else() + mark_as_advanced(GETTEXT_INCLUDE_DIR GETTEXT_LIBRARY GETTEXT_MSGFMT) + message(STATUS "GetText disabled.") +endif() + + +option(ENABLE_SOUND "Enable sound" TRUE) +set(USE_SOUND FALSE) + +if(BUILD_CLIENT AND ENABLE_SOUND) + # Sound libraries + find_package(OpenAL) + find_package(Vorbis) + if(NOT OPENAL_FOUND) + message(STATUS "Sound enabled, but OpenAL not found!") + mark_as_advanced(CLEAR OPENAL_LIBRARY OPENAL_INCLUDE_DIR) + endif() + if(NOT VORBIS_FOUND) + message(STATUS "Sound enabled, but Vorbis libraries not found!") + mark_as_advanced(CLEAR OGG_INCLUDE_DIR VORBIS_INCLUDE_DIR OGG_LIBRARY VORBIS_LIBRARY VORBISFILE_LIBRARY) + endif() + if(OPENAL_FOUND AND VORBIS_FOUND) + set(USE_SOUND TRUE) + message(STATUS "Sound enabled.") + else() + message(FATAL_ERROR "Sound enabled, but cannot be used.\n" + "To continue, either fill in the required paths or disable sound. (-DENABLE_SOUND=0)") + endif() +endif() + +# TODO: this should be removed one day, we can enable it unconditionally +option(ENABLE_GLES "Enable extra support code for OpenGL ES" FALSE) +mark_as_advanced(ENABLE_GLES) + +option(ENABLE_TOUCH "Enable Touchscreen support" FALSE) +if(ENABLE_TOUCH) + add_definitions(-DHAVE_TOUCHSCREENGUI) +endif() + +if(BUILD_CLIENT) + find_package(Freetype REQUIRED) +endif() + +option(ENABLE_CURSES "Enable ncurses console" TRUE) +set(USE_CURSES FALSE) + +if(ENABLE_CURSES) + find_package(Ncursesw) + if(CURSES_FOUND) + set(USE_CURSES TRUE) + message(STATUS "ncurses console enabled.") + include_directories(${CURSES_INCLUDE_DIRS}) + else() + message(STATUS "ncurses not found!") + endif() +endif(ENABLE_CURSES) + +option(ENABLE_POSTGRESQL "Enable PostgreSQL backend" TRUE) +set(USE_POSTGRESQL FALSE) + +if(ENABLE_POSTGRESQL) + if(CMAKE_VERSION VERSION_LESS "3.20") + find_package(PostgreSQL QUIET) + # Before CMake 3.20 FindPostgreSQL.cmake always looked for server includes + # but we don't need them, so continue anyway if only those are missing. + if(PostgreSQL_INCLUDE_DIR AND PostgreSQL_LIBRARY) + set(PostgreSQL_FOUND TRUE) + set(PostgreSQL_INCLUDE_DIRS ${PostgreSQL_INCLUDE_DIR}) + set(PostgreSQL_LIBRARIES ${PostgreSQL_LIBRARY}) + endif() + else() + find_package(PostgreSQL) + endif() + + if(PostgreSQL_FOUND) + set(USE_POSTGRESQL TRUE) + message(STATUS "PostgreSQL backend enabled") + # This variable is case sensitive, don't try to change it to POSTGRESQL_INCLUDE_DIR + message(STATUS "PostgreSQL includes: ${PostgreSQL_INCLUDE_DIRS}") + include_directories(${PostgreSQL_INCLUDE_DIRS}) + else() + message(STATUS "PostgreSQL not found!") + endif() +endif(ENABLE_POSTGRESQL) + +option(ENABLE_LEVELDB "Enable LevelDB backend" TRUE) +set(USE_LEVELDB FALSE) + +if(ENABLE_LEVELDB) + find_library(LEVELDB_LIBRARY NAMES leveldb libleveldb) + find_path(LEVELDB_INCLUDE_DIR db.h PATH_SUFFIXES leveldb) + if(LEVELDB_LIBRARY AND LEVELDB_INCLUDE_DIR) + set(USE_LEVELDB TRUE) + message(STATUS "LevelDB backend enabled.") + include_directories(${LEVELDB_INCLUDE_DIR}) + else() + message(STATUS "LevelDB not found!") + endif() +endif(ENABLE_LEVELDB) + + +OPTION(ENABLE_REDIS "Enable Redis backend" TRUE) +set(USE_REDIS FALSE) + +if(ENABLE_REDIS) + find_library(REDIS_LIBRARY hiredis) + find_path(REDIS_INCLUDE_DIR hiredis.h PATH_SUFFIXES hiredis) + if(REDIS_LIBRARY AND REDIS_INCLUDE_DIR) + set(USE_REDIS TRUE) + message(STATUS "Redis backend enabled.") + include_directories(${REDIS_INCLUDE_DIR}) + else(REDIS_LIBRARY AND REDIS_INCLUDE_DIR) + message(STATUS "Redis not found!") + endif(REDIS_LIBRARY AND REDIS_INCLUDE_DIR) +endif(ENABLE_REDIS) + + +find_package(SQLite3 REQUIRED) + + +OPTION(ENABLE_PROMETHEUS "Enable prometheus client support" FALSE) +set(USE_PROMETHEUS FALSE) + +if(ENABLE_PROMETHEUS) + find_path(PROMETHEUS_CPP_INCLUDE_DIR NAMES prometheus/counter.h) + find_library(PROMETHEUS_PULL_LIBRARY NAMES prometheus-cpp-pull) + find_library(PROMETHEUS_CORE_LIBRARY NAMES prometheus-cpp-core) + if(PROMETHEUS_CPP_INCLUDE_DIR AND PROMETHEUS_PULL_LIBRARY AND PROMETHEUS_CORE_LIBRARY) + set(PROMETHEUS_LIBRARIES ${PROMETHEUS_PULL_LIBRARY} ${PROMETHEUS_CORE_LIBRARY}) + set(USE_PROMETHEUS TRUE) + include_directories(${PROMETHEUS_CPP_INCLUDE_DIR}) + endif(PROMETHEUS_CPP_INCLUDE_DIR AND PROMETHEUS_PULL_LIBRARY AND PROMETHEUS_CORE_LIBRARY) +endif(ENABLE_PROMETHEUS) + +if(USE_PROMETHEUS) + message(STATUS "Prometheus client enabled.") +else(USE_PROMETHEUS) + message(STATUS "Prometheus client disabled.") +endif(USE_PROMETHEUS) + +OPTION(ENABLE_SPATIAL "Enable SpatialIndex AreaStore backend" TRUE) +set(USE_SPATIAL FALSE) + +if(ENABLE_SPATIAL) + find_library(SPATIAL_LIBRARY spatialindex) + find_path(SPATIAL_INCLUDE_DIR spatialindex/SpatialIndex.h) + if(SPATIAL_LIBRARY AND SPATIAL_INCLUDE_DIR) + set(USE_SPATIAL TRUE) + message(STATUS "SpatialIndex AreaStore backend enabled.") + include_directories(${SPATIAL_INCLUDE_DIR}) + else(SPATIAL_LIBRARY AND SPATIAL_INCLUDE_DIR) + message(STATUS "SpatialIndex not found!") + endif(SPATIAL_LIBRARY AND SPATIAL_INCLUDE_DIR) +endif(ENABLE_SPATIAL) + + +find_package(ZLIB REQUIRED) +find_package(Zstd REQUIRED) + + +if(NOT MSVC) + set(USE_GPROF FALSE CACHE BOOL "Use -pg flag for g++") +endif() + +# Haiku endian support +if(HAIKU) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_BSD_SOURCE") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_BSD_SOURCE") +endif() + +# Use cmake_config.h +add_definitions(-DUSE_CMAKE_CONFIG_H) + +if(WIN32) + # Windows + if(MSVC) # MSVC Specifics + set(PLATFORM_LIBS dbghelp.lib ${PLATFORM_LIBS}) + # Surpress some useless warnings + add_definitions ( /D "_CRT_SECURE_NO_DEPRECATE" /W1 ) + # Get M_PI to work + add_definitions(/D "_USE_MATH_DEFINES") + # Dont define min/max macros in minwindef.h + add_definitions(/D "NOMINMAX") + else() # Probably MinGW = GCC + set(PLATFORM_LIBS "") + endif() + set(PLATFORM_LIBS ws2_32.lib version.lib shlwapi.lib winmm.lib ${PLATFORM_LIBS}) + + set(EXTRA_DLL "" CACHE FILEPATH "Optional paths to additional DLLs that should be packaged") + + # DLLs are automatically copied to the output directory by vcpkg when VCPKG_APPLOCAL_DEPS=ON + if(NOT VCPKG_APPLOCAL_DEPS) + set(ZLIB_DLL "" CACHE FILEPATH "Path to Zlib DLL for installation (optional)") + set(ZSTD_DLL "" CACHE FILEPATH "Path to Zstd DLL for installation (optional)") + if(ENABLE_SOUND) + set(OPENAL_DLL "" CACHE FILEPATH "Path to OpenAL32.dll for installation (optional)") + set(OGG_DLL "" CACHE FILEPATH "Path to libogg.dll for installation (optional)") + set(VORBIS_DLL "" CACHE FILEPATH "Path to Vorbis DLLs for installation (optional)") + endif() + if(USE_GETTEXT) + set(GETTEXT_DLL "" CACHE FILEPATH "Path to Intl/Iconv DLLs for installation (optional)") + endif() + if(USE_LUAJIT) + set(LUA_DLL "" CACHE FILEPATH "Path to luajit-5.1.dll for installation (optional)") + endif() + endif() +else() + # Unix probably + if(BUILD_CLIENT) + if(NOT HAIKU AND NOT APPLE) + find_package(X11 REQUIRED) + endif(NOT HAIKU AND NOT APPLE) + endif() + + set(PLATFORM_LIBS -lpthread ${CMAKE_DL_LIBS}) + if(APPLE) + set(PLATFORM_LIBS "-framework CoreFoundation" ${PLATFORM_LIBS}) + else() + check_library_exists(rt clock_gettime "" HAVE_LIBRT) + if (HAVE_LIBRT) + set(PLATFORM_LIBS -lrt ${PLATFORM_LIBS}) + endif(HAVE_LIBRT) + endif(APPLE) + + # Prefer local iconv if installed + find_library(ICONV_LIBRARY iconv) + mark_as_advanced(ICONV_LIBRARY) + if (ICONV_LIBRARY) + set(PLATFORM_LIBS ${PLATFORM_LIBS} ${ICONV_LIBRARY}) + endif() + if (HAIKU) + set(PLATFORM_LIBS ${PLATFORM_LIBS} intl network) + endif() + +endif() + +check_include_files(endian.h HAVE_ENDIAN_H) + +configure_file( + "${PROJECT_SOURCE_DIR}/cmake_config.h.in" + "${PROJECT_BINARY_DIR}/cmake_config.h" +) + + +# Add a target that always rebuilds cmake_config_githash.h +add_custom_target(GenerateVersion + COMMAND ${CMAKE_COMMAND} + -D "GENERATE_VERSION_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}" + -D "GENERATE_VERSION_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}" + -D "VERSION_STRING=${VERSION_STRING}" + -D "DEVELOPMENT_BUILD=${DEVELOPMENT_BUILD}" + -P "${CMAKE_SOURCE_DIR}/cmake/Modules/GenerateVersion.cmake" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") + + +add_subdirectory(threading) +add_subdirectory(content) +add_subdirectory(database) +add_subdirectory(gui) +add_subdirectory(mapgen) +add_subdirectory(network) +add_subdirectory(script) +add_subdirectory(unittest) +add_subdirectory(benchmark) +add_subdirectory(util) +add_subdirectory(irrlicht_changes) +add_subdirectory(server) + +set(common_SRCS + ${database_SRCS} + ${mapgen_SRCS} + ${server_SRCS} + ${content_SRCS} + ban.cpp + chat.cpp + clientiface.cpp + collision.cpp + content_mapnode.cpp + content_nodemeta.cpp + convert_json.cpp + craftdef.cpp + debug.cpp + defaultsettings.cpp + emerge.cpp + environment.cpp + face_position_cache.cpp + filesys.cpp + gettext.cpp + httpfetch.cpp + hud.cpp + inventory.cpp + inventorymanager.cpp + itemdef.cpp + itemstackmetadata.cpp + light.cpp + log.cpp + main.cpp + map.cpp + map_settings_manager.cpp + mapblock.cpp + mapnode.cpp + mapsector.cpp + metadata.cpp + modchannels.cpp + nameidmapping.cpp + nodedef.cpp + nodemetadata.cpp + nodetimer.cpp + noise.cpp + objdef.cpp + object_properties.cpp + particles.cpp + pathfinder.cpp + player.cpp + porting.cpp + profiler.cpp + raycast.cpp + reflowscan.cpp + remoteplayer.cpp + rollback.cpp + rollback_interface.cpp + serialization.cpp + server.cpp + serverenvironment.cpp + serverlist.cpp + settings.cpp + staticobject.cpp + terminal_chat_console.cpp + texture_override.cpp + tileanimation.cpp + tool.cpp + translation.cpp + version.cpp + voxel.cpp + voxelalgorithms.cpp + hud.cpp + ${common_network_SRCS} + ${JTHREAD_SRCS} + ${common_SCRIPT_SRCS} + ${UTIL_SRCS} +) + +if(BUILD_UNITTESTS) + set(common_SRCS ${common_SRCS} ${UNITTEST_SRCS}) +endif() + +if(BUILD_BENCHMARKS) + set(common_SRCS ${common_SRCS} ${BENCHMARK_SRCS}) +endif() + +# This gives us the icon and file version information +if(WIN32) + set(WINRESOURCE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../misc/winresource.rc") + set(MINETEST_EXE_MANIFEST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../misc/minetest.exe.manifest") + if(MINGW) + if(NOT CMAKE_RC_COMPILER) + set(CMAKE_RC_COMPILER "windres.exe") + endif() + ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o + COMMAND ${CMAKE_RC_COMPILER} -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_BINARY_DIR} + -i${WINRESOURCE_FILE} + -o ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${WINRESOURCE_FILE} ${MINETEST_EXE_MANIFEST_FILE}) + SET(extra_windows_SRCS ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o) + else(MINGW) # Probably MSVC + set(extra_windows_SRCS ${WINRESOURCE_FILE} ${MINETEST_EXE_MANIFEST_FILE}) + endif(MINGW) +endif() + + +# Client sources +if (BUILD_CLIENT) + add_subdirectory(client) +endif(BUILD_CLIENT) + +set(client_SRCS + ${client_SRCS} + ${common_SRCS} + ${gui_SRCS} + ${client_network_SRCS} + ${client_irrlicht_changes_SRCS} + ${client_SCRIPT_SRCS} +) + +if(BUILD_UNITTESTS) + set(client_SRCS ${client_SRCS} ${UNITTEST_CLIENT_SRCS}) +endif() + +if(BUILD_BENCHMARKS) + set(client_SRCS ${client_SRCS} ${BENCHMARK_CLIENT_SRCS}) +endif() + +list(SORT client_SRCS) + +# Server sources +set(server_SRCS + ${common_SRCS} +) +list(SORT server_SRCS) + +# Avoid source_group on broken CMake version. +# see issue #7074 #7075 +if (CMAKE_VERSION VERSION_GREATER 3.8.1) + source_group(TREE ${PROJECT_SOURCE_DIR} PREFIX "Source Files" FILES ${client_SRCS}) + source_group(TREE ${PROJECT_SOURCE_DIR} PREFIX "Source Files" FILES ${server_SRCS}) +endif() + +include_directories( + ${PROJECT_BINARY_DIR} + ${PROJECT_SOURCE_DIR} + ${PROJECT_SOURCE_DIR}/script +) +include_directories(SYSTEM + ${ZLIB_INCLUDE_DIR} + ${ZSTD_INCLUDE_DIR} + ${SQLITE3_INCLUDE_DIR} + ${LUA_INCLUDE_DIR} + ${GMP_INCLUDE_DIR} + ${JSON_INCLUDE_DIR} + ${LUA_BIT_INCLUDE_DIR} +) + +if(USE_GETTEXT) + include_directories(${GETTEXT_INCLUDE_DIR}) +endif() + +if(BUILD_CLIENT) + include_directories(SYSTEM + ${FREETYPE_INCLUDE_DIRS} + ${SOUND_INCLUDE_DIRS} + ${X11_INCLUDE_DIR} + ) +endif() + +if(USE_CURL) + include_directories(${CURL_INCLUDE_DIR}) +endif() + + +# When cross-compiling assume the user doesn't want to run the executable anyway, +# otherwise place it in <source dir>/bin/ since Minetest can only run from there. +if(NOT CMAKE_CROSSCOMPILING) + set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin") +endif() + +if(BUILD_CLIENT) + add_executable(${PROJECT_NAME} ${client_SRCS} ${extra_windows_SRCS}) + add_dependencies(${PROJECT_NAME} GenerateVersion) + target_link_libraries( + ${PROJECT_NAME} + ${ZLIB_LIBRARIES} + IrrlichtMt::IrrlichtMt + ${ZSTD_LIBRARY} + ${X11_LIBRARIES} + ${SOUND_LIBRARIES} + ${SQLITE3_LIBRARY} + ${LUA_LIBRARY} + ${GMP_LIBRARY} + ${JSON_LIBRARY} + ${LUA_BIT_LIBRARY} + ${FREETYPE_LIBRARY} + ${PLATFORM_LIBS} + ) + if(NOT USE_LUAJIT) + set_target_properties(${PROJECT_NAME} PROPERTIES + # This is necessary for dynamic Lua modules + # to work when Lua is statically linked (issue #10806) + ENABLE_EXPORTS 1 + ) + endif() + + if(USE_GETTEXT) + target_link_libraries( + ${PROJECT_NAME} + ${GETTEXT_LIBRARY} + ) + endif() + if(USE_CURL) + target_link_libraries( + ${PROJECT_NAME} + ${CURL_LIBRARY} + ) + endif() + if(FREETYPE_PKGCONFIG_FOUND) + set_target_properties(${PROJECT_NAME} + PROPERTIES + COMPILE_FLAGS "${FREETYPE_CFLAGS_STR}" + ) + endif() + if (USE_CURSES) + target_link_libraries(${PROJECT_NAME} ${CURSES_LIBRARIES}) + endif() + if (USE_POSTGRESQL) + target_link_libraries(${PROJECT_NAME} ${PostgreSQL_LIBRARIES}) + endif() + if (USE_LEVELDB) + target_link_libraries(${PROJECT_NAME} ${LEVELDB_LIBRARY}) + endif() + if (USE_REDIS) + target_link_libraries(${PROJECT_NAME} ${REDIS_LIBRARY}) + endif() + if (USE_PROMETHEUS) + target_link_libraries(${PROJECT_NAME} ${PROMETHEUS_LIBRARIES}) + endif() + if (USE_SPATIAL) + target_link_libraries(${PROJECT_NAME} ${SPATIAL_LIBRARY}) + endif() + if(BUILD_BENCHMARKS) + target_link_libraries(${PROJECT_NAME} catch2) + endif() +endif(BUILD_CLIENT) + + +if(BUILD_SERVER) + add_executable(${PROJECT_NAME}server ${server_SRCS} ${extra_windows_SRCS}) + add_dependencies(${PROJECT_NAME}server GenerateVersion) + + get_target_property( + IRRLICHT_INCLUDES IrrlichtMt::IrrlichtMt INTERFACE_INCLUDE_DIRECTORIES) + # Doesn't work without PRIVATE/PUBLIC/INTERFACE mode specified. + target_include_directories(${PROJECT_NAME}server PRIVATE ${IRRLICHT_INCLUDES}) + target_link_libraries( + ${PROJECT_NAME}server + ${ZLIB_LIBRARIES} + ${ZSTD_LIBRARY} + ${SQLITE3_LIBRARY} + ${JSON_LIBRARY} + ${LUA_LIBRARY} + ${LUA_BIT_LIBRARY} + ${GMP_LIBRARY} + ${PLATFORM_LIBS} + ) + set_target_properties(${PROJECT_NAME}server PROPERTIES + COMPILE_DEFINITIONS "SERVER") + if(NOT USE_LUAJIT) + set_target_properties(${PROJECT_NAME}server PROPERTIES + # This is necessary for dynamic Lua modules + # to work when Lua is statically linked (issue #10806) + ENABLE_EXPORTS 1 + ) + endif() + + if (USE_GETTEXT) + target_link_libraries(${PROJECT_NAME}server ${GETTEXT_LIBRARY}) + endif() + if (USE_CURSES) + target_link_libraries(${PROJECT_NAME}server ${CURSES_LIBRARIES}) + endif() + if (USE_POSTGRESQL) + target_link_libraries(${PROJECT_NAME}server ${PostgreSQL_LIBRARIES}) + endif() + if (USE_LEVELDB) + target_link_libraries(${PROJECT_NAME}server ${LEVELDB_LIBRARY}) + endif() + if (USE_REDIS) + target_link_libraries(${PROJECT_NAME}server ${REDIS_LIBRARY}) + endif() + if (USE_PROMETHEUS) + target_link_libraries(${PROJECT_NAME}server ${PROMETHEUS_LIBRARIES}) + endif() + if (USE_SPATIAL) + target_link_libraries(${PROJECT_NAME}server ${SPATIAL_LIBRARY}) + endif() + if(USE_CURL) + target_link_libraries( + ${PROJECT_NAME}server + ${CURL_LIBRARY} + ) + endif() + if(BUILD_BENCHMARKS) + target_link_libraries(${PROJECT_NAME}server catch2) + endif() +endif(BUILD_SERVER) + +# Blacklisted locales that don't work. +# see issue #4638 +set(GETTEXT_BLACKLISTED_LOCALES + ar + dv + he + hi + kn + ms_Arab + th +) + +option(APPLY_LOCALE_BLACKLIST "Use a blacklist to avoid known broken locales" TRUE) + +if (GETTEXTLIB_FOUND AND APPLY_LOCALE_BLACKLIST) + set(GETTEXT_USED_LOCALES "") + foreach(LOCALE ${GETTEXT_AVAILABLE_LOCALES}) + if (NOT "${LOCALE}" IN_LIST GETTEXT_BLACKLISTED_LOCALES) + list(APPEND GETTEXT_USED_LOCALES ${LOCALE}) + endif() + endforeach() + message(STATUS "Locale blacklist applied; Locales used: ${GETTEXT_USED_LOCALES}") +elseif (GETTEXTLIB_FOUND) + set(GETTEXT_USED_LOCALES ${GETTEXT_AVAILABLE_LOCALES}) +endif() + +# Set some optimizations and tweaks + +include(CheckCSourceCompiles) + +if(MSVC) + # Visual Studio + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D WIN32_LEAN_AND_MEAN") + # EHa enables SEH exceptions (used for catching segfaults) + set(CMAKE_CXX_FLAGS_RELEASE "/EHa /Ox /MD /GS- /Zi /fp:fast /D NDEBUG /D _HAS_ITERATOR_DEBUGGING=0") + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /arch:SSE") + endif() + + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/INCREMENTAL:NO /DEBUG /OPT:REF /OPT:ICF /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup") + + set(CMAKE_CXX_FLAGS_SEMIDEBUG "/MDd /Zi /Ob0 /O1 /RTC1") + + # Debug build doesn't catch exceptions by itself + # Add some optimizations because otherwise it's VERY slow + set(CMAKE_CXX_FLAGS_DEBUG "/MDd /Zi /Ob0 /Od /RTC1") + + # Flags for C files (sqlite) + # /MD = dynamically link to MSVCRxxx.dll + set(CMAKE_C_FLAGS_RELEASE "/O2 /Ob2 /MD") + + # Flags that cannot be shared between cl and clang-cl + # https://clang.llvm.org/docs/UsersManual.html#clang-cl + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=lld") + + # Disable pragma-pack warning + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wno-pragma-pack") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /TP /FD /GL") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG") + endif() +else() + # GCC or compatible compilers such as Clang + set(WARNING_FLAGS "-Wall -Wextra") + set(WARNING_FLAGS "${WARNING_FLAGS} -Wno-unused-parameter -Wno-implicit-fallthrough") + if(WARN_ALL) + set(RELEASE_WARNING_FLAGS "${WARNING_FLAGS}") + else() + set(RELEASE_WARNING_FLAGS "") + endif() + + if(APPLE AND USE_LUAJIT) + # required per http://luajit.org/install.html + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pagezero_size 10000 -image_base 100000000") + elseif(UNIX AND USE_LUAJIT) + check_c_source_compiles("#ifndef __aarch64__\n#error\n#endif\nint main(){}" IS_AARCH64) + if(IS_AARCH64) + # Move text segment below LuaJIT's 47-bit limit (see issue #9367) + if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + # FreeBSD uses lld, and lld does not support -Ttext-segment, suggesting + # --image-base instead. Not sure if it's equivalent change for the purpose + # but at least if fixes build on FreeBSD/aarch64 + # XXX: the condition should also be changed to check for lld regardless of + # os, bit CMake doesn't have anything like CMAKE_LINKER_IS_LLD yet + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--image-base=0x200000000") + else() + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Ttext-segment=0x200000000") + endif() + endif() + endif() + + if(MINGW) + set(OTHER_FLAGS "${OTHER_FLAGS} -mthreads -fexceptions") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32_LEAN_AND_MEAN") + endif() + + # Use a safe subset of flags to speed up math calculations: + # - we don't need errno or math exceptions + # - we don't deal with Inf/NaN or signed zero + set(MATH_FLAGS "-fno-math-errno -fno-trapping-math -ffinite-math-only -fno-signed-zeros") + + # Enable SSE for floating point math on 32-bit x86 by default + # reasoning see minetest issue #11810 and https://gcc.gnu.org/wiki/FloatingPointMath + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + check_c_source_compiles("#ifndef __i686__\n#error\n#endif\nint main(){}" IS_I686) + if(IS_I686) + message(STATUS "Detected Intel x86: using SSE instead of x87 FPU") + set(OTHER_FLAGS "${OTHER_FLAGS} -mfpmath=sse -msse") + endif() + endif() + + set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${RELEASE_WARNING_FLAGS} ${OTHER_FLAGS} -pipe -funroll-loops") + if(CMAKE_SYSTEM_NAME MATCHES "(Darwin|BSD|DragonFly)") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Os") + else() + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -fomit-frame-pointer") + if(CMAKE_SYSTEM_NAME STREQUAL "Linux" + AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + AND CMAKE_CXX_COMPILER_VERSION MATCHES "^9\\.") + # Clang 9 has broken -ffast-math on glibc + else() + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MATH_FLAGS}") + endif() + endif() + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -g") + set(CMAKE_CXX_FLAGS_SEMIDEBUG "-g -O1 ${WARNING_FLAGS} ${OTHER_FLAGS}") + set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 ${WARNING_FLAGS} ${OTHER_FLAGS}") + + if(USE_GPROF) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg") + endif() + + if(MINGW) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mwindows") + endif() +endif() + + +# Installation + +if(WIN32) + if(EXTRA_DLL) + install(FILES ${EXTRA_DLL} DESTINATION ${BINDIR}) + endif() + if(VCPKG_APPLOCAL_DEPS) + # Collect the dll's from the output path + install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/Release/ + DESTINATION ${BINDIR} + CONFIGURATIONS Release + FILES_MATCHING PATTERN "*.dll") + install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/Debug/ + DESTINATION ${BINDIR} + CONFIGURATIONS Debug + FILES_MATCHING PATTERN "*.dll") + install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/RelWithDebInfo/ + DESTINATION ${BINDIR} + CONFIGURATIONS RelWithDebInfo + FILES_MATCHING PATTERN "*.dll") + install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/MinSizeRel/ + DESTINATION ${BINDIR} + CONFIGURATIONS MinSizeRel + FILES_MATCHING PATTERN "*.dll") + else() + # Use the old-style way to install dll's + if(BUILD_CLIENT AND USE_SOUND) + if(OPENAL_DLL) + install(FILES ${OPENAL_DLL} DESTINATION ${BINDIR}) + endif() + if(OGG_DLL) + install(FILES ${OGG_DLL} DESTINATION ${BINDIR}) + endif() + if(VORBIS_DLL) + install(FILES ${VORBIS_DLL} DESTINATION ${BINDIR}) + endif() + endif() + if(CURL_DLL) + install(FILES ${CURL_DLL} DESTINATION ${BINDIR}) + endif() + if(ZLIB_DLL) + install(FILES ${ZLIB_DLL} DESTINATION ${BINDIR}) + endif() + if(ZSTD_DLL) + install(FILES ${ZSTD_DLL} DESTINATION ${BINDIR}) + endif() + if(BUILD_CLIENT AND FREETYPE_DLL) + install(FILES ${FREETYPE_DLL} DESTINATION ${BINDIR}) + endif() + if(SQLITE3_DLL) + install(FILES ${SQLITE3_DLL} DESTINATION ${BINDIR}) + endif() + if(LEVELDB_DLL) + install(FILES ${LEVELDB_DLL} DESTINATION ${BINDIR}) + endif() + if(LUA_DLL) + install(FILES ${LUA_DLL} DESTINATION ${BINDIR}) + endif() + if(BUILD_CLIENT AND USE_GETTEXT AND GETTEXT_DLL) + install(FILES ${GETTEXT_DLL} DESTINATION ${BINDIR}) + endif() + endif() + + if(BUILD_CLIENT AND IRRLICHT_DLL) + install(FILES ${IRRLICHT_DLL} DESTINATION ${BINDIR}) + endif() +endif() + +if(BUILD_CLIENT) + install(TARGETS ${PROJECT_NAME} + RUNTIME DESTINATION ${BINDIR} + LIBRARY DESTINATION ${BINDIR} + ARCHIVE DESTINATION ${BINDIR} + BUNDLE DESTINATION . + ) + + if(APPLE) + install(CODE " + set(BU_CHMOD_BUNDLE_ITEMS ON) + include(BundleUtilities) + fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/${BUNDLE_PATH}\" \"\" \"\${CMAKE_INSTALL_PREFIX}/${BINDIR}\") + " COMPONENT Runtime) + endif() + + if(USE_GETTEXT) + foreach(LOCALE ${GETTEXT_USED_LOCALES}) + set_mo_paths(MO_BUILD_PATH MO_DEST_PATH ${LOCALE}) + set(MO_BUILD_PATH "${MO_BUILD_PATH}/${PROJECT_NAME}.mo") + install(FILES ${MO_BUILD_PATH} DESTINATION ${MO_DEST_PATH}) + endforeach() + endif() + + install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../fonts" DESTINATION "${SHAREDIR}" + FILES_MATCHING PATTERN "*.ttf" PATTERN "*.txt") +endif(BUILD_CLIENT) + +if(BUILD_SERVER) + install(TARGETS ${PROJECT_NAME}server DESTINATION ${BINDIR}) +endif() + +if (USE_GETTEXT) + set(MO_FILES) + + foreach(LOCALE ${GETTEXT_USED_LOCALES}) + set(PO_FILE_PATH "${GETTEXT_PO_PATH}/${LOCALE}/${PROJECT_NAME}.po") + set_mo_paths(MO_BUILD_PATH MO_DEST_PATH ${LOCALE}) + set(MO_FILE_PATH "${MO_BUILD_PATH}/${PROJECT_NAME}.mo") + + add_custom_command(OUTPUT ${MO_BUILD_PATH} + COMMAND ${CMAKE_COMMAND} -E make_directory ${MO_BUILD_PATH} + COMMENT "mo-update [${LOCALE}]: Creating locale directory.") + + add_custom_command( + OUTPUT ${MO_FILE_PATH} + COMMAND ${GETTEXT_MSGFMT} -o ${MO_FILE_PATH} ${PO_FILE_PATH} + DEPENDS ${MO_BUILD_PATH} ${PO_FILE_PATH} + WORKING_DIRECTORY "${GETTEXT_PO_PATH}/${LOCALE}" + COMMENT "mo-update [${LOCALE}]: Creating mo file." + ) + + set(MO_FILES ${MO_FILES} ${MO_FILE_PATH}) + endforeach() + + add_custom_target(translations ALL COMMENT "mo update" DEPENDS ${MO_FILES}) +endif() diff --git a/src/activeobject.h b/src/activeobject.h new file mode 100644 index 0000000..1d8a371 --- /dev/null +++ b/src/activeobject.h @@ -0,0 +1,132 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_aabb3d.h" +#include "irr_v3d.h" +#include <string> + + +enum ActiveObjectType { + ACTIVEOBJECT_TYPE_INVALID = 0, + ACTIVEOBJECT_TYPE_TEST = 1, +// Obsolete stuff +// ACTIVEOBJECT_TYPE_ITEM = 2, +// ACTIVEOBJECT_TYPE_RAT = 3, +// ACTIVEOBJECT_TYPE_OERKKI1 = 4, +// ACTIVEOBJECT_TYPE_FIREFLY = 5, +// ACTIVEOBJECT_TYPE_MOBV2 = 6, +// End obsolete stuff + ACTIVEOBJECT_TYPE_LUAENTITY = 7, +// Special type, not stored as a static object + ACTIVEOBJECT_TYPE_PLAYER = 100, +// Special type, only exists as CAO + ACTIVEOBJECT_TYPE_GENERIC = 101, +}; +// Other types are defined in content_object.h + +struct ActiveObjectMessage +{ + ActiveObjectMessage(u16 id_, bool reliable_=true, const std::string &data_ = "") : + id(id_), + reliable(reliable_), + datastring(data_) + {} + + u16 id; + bool reliable; + std::string datastring; +}; + +enum ActiveObjectCommand { + AO_CMD_SET_PROPERTIES, + AO_CMD_UPDATE_POSITION, + AO_CMD_SET_TEXTURE_MOD, + AO_CMD_SET_SPRITE, + AO_CMD_PUNCHED, + AO_CMD_UPDATE_ARMOR_GROUPS, + AO_CMD_SET_ANIMATION, + AO_CMD_SET_BONE_POSITION, + AO_CMD_ATTACH_TO, + AO_CMD_SET_PHYSICS_OVERRIDE, + AO_CMD_OBSOLETE1, + // ^ UPDATE_NAMETAG_ATTRIBUTES deprecated since 0.4.14, removed in 5.3.0 + AO_CMD_SPAWN_INFANT, + AO_CMD_SET_ANIMATION_SPEED +}; + +/* + Parent class for ServerActiveObject and ClientActiveObject +*/ +class ActiveObject +{ +public: + ActiveObject(u16 id): + m_id(id) + { + } + + u16 getId() const + { + return m_id; + } + + void setId(u16 id) + { + m_id = id; + } + + virtual ActiveObjectType getType() const = 0; + + + /*! + * Returns the collision box of the object. + * This box is translated by the object's + * location. + * The box's coordinates are world coordinates. + * @returns true if the object has a collision box. + */ + virtual bool getCollisionBox(aabb3f *toset) const = 0; + + + /*! + * Returns the selection box of the object. + * This box is not translated when the + * object moves. + * The box's coordinates are world coordinates. + * @returns true if the object has a selection box. + */ + virtual bool getSelectionBox(aabb3f *toset) const = 0; + + + virtual bool collideWithObjects() const = 0; + + + virtual void setAttachment(int parent_id, const std::string &bone, v3f position, + v3f rotation, bool force_visible) {} + virtual void getAttachment(int *parent_id, std::string *bone, v3f *position, + v3f *rotation, bool *force_visible) const {} + virtual void clearChildAttachments() {} + virtual void clearParentAttachment() {} + virtual void addAttachmentChild(int child_id) {} + virtual void removeAttachmentChild(int child_id) {} +protected: + u16 m_id; // 0 is invalid, "no id" +}; diff --git a/src/activeobjectmgr.h b/src/activeobjectmgr.h new file mode 100644 index 0000000..aa0538e --- /dev/null +++ b/src/activeobjectmgr.h @@ -0,0 +1,66 @@ +/* +Minetest +Copyright (C) 2010-2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <unordered_map> +#include "irrlichttypes.h" + +class TestClientActiveObjectMgr; +class TestServerActiveObjectMgr; + +template <typename T> +class ActiveObjectMgr +{ + friend class ::TestClientActiveObjectMgr; + friend class ::TestServerActiveObjectMgr; + +public: + virtual void step(float dtime, const std::function<void(T *)> &f) = 0; + virtual bool registerObject(T *obj) = 0; + virtual void removeObject(u16 id) = 0; + + T *getActiveObject(u16 id) + { + typename std::unordered_map<u16, T *>::const_iterator n = + m_active_objects.find(id); + return (n != m_active_objects.end() ? n->second : nullptr); + } + +protected: + u16 getFreeId() const + { + // try to reuse id's as late as possible + static thread_local u16 last_used_id = 0; + u16 startid = last_used_id; + while (!isFreeId(++last_used_id)) { + if (last_used_id == startid) + return 0; + } + + return last_used_id; + } + + bool isFreeId(u16 id) const + { + return id != 0 && m_active_objects.find(id) == m_active_objects.end(); + } + + std::unordered_map<u16, T *> m_active_objects; +}; diff --git a/src/ban.cpp b/src/ban.cpp new file mode 100644 index 0000000..3decc96 --- /dev/null +++ b/src/ban.cpp @@ -0,0 +1,142 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "ban.h" +#include <fstream> +#include "threading/mutex_auto_lock.h" +#include <sstream> +#include <set> +#include "util/strfnd.h" +#include "util/string.h" +#include "log.h" +#include "filesys.h" + +BanManager::BanManager(const std::string &banfilepath): + m_banfilepath(banfilepath) +{ + try { + load(); + } catch(SerializationError &e) { + infostream << "BanManager: creating " + << m_banfilepath << std::endl; + } +} + +BanManager::~BanManager() +{ + save(); +} + +void BanManager::load() +{ + MutexAutoLock lock(m_mutex); + infostream<<"BanManager: loading from "<<m_banfilepath<<std::endl; + std::ifstream is(m_banfilepath.c_str(), std::ios::binary); + if (!is.good()) { + infostream<<"BanManager: failed loading from "<<m_banfilepath<<std::endl; + throw SerializationError("BanManager::load(): Couldn't open file"); + } + + while (!is.eof() && is.good()) { + std::string line; + std::getline(is, line, '\n'); + Strfnd f(line); + std::string ip = trim(f.next("|")); + std::string name = trim(f.next("|")); + if(!ip.empty()) { + m_ips[ip] = name; + } + } + m_modified = false; +} + +void BanManager::save() +{ + MutexAutoLock lock(m_mutex); + infostream << "BanManager: saving to " << m_banfilepath << std::endl; + std::ostringstream ss(std::ios_base::binary); + + for (const auto &ip : m_ips) + ss << ip.first << "|" << ip.second << "\n"; + + if (!fs::safeWriteToFile(m_banfilepath, ss.str())) { + infostream << "BanManager: failed saving to " << m_banfilepath << std::endl; + throw SerializationError("BanManager::save(): Couldn't write file"); + } + + m_modified = false; +} + +bool BanManager::isIpBanned(const std::string &ip) +{ + MutexAutoLock lock(m_mutex); + return m_ips.find(ip) != m_ips.end(); +} + +std::string BanManager::getBanDescription(const std::string &ip_or_name) +{ + MutexAutoLock lock(m_mutex); + std::string s; + for (const auto &ip : m_ips) { + if (ip.first == ip_or_name || ip.second == ip_or_name + || ip_or_name.empty()) { + s += ip.first + "|" + ip.second + ", "; + } + } + s = s.substr(0, s.size() - 2); + return s; +} + +std::string BanManager::getBanName(const std::string &ip) +{ + MutexAutoLock lock(m_mutex); + StringMap::iterator it = m_ips.find(ip); + if (it == m_ips.end()) + return ""; + return it->second; +} + +void BanManager::add(const std::string &ip, const std::string &name) +{ + MutexAutoLock lock(m_mutex); + m_ips[ip] = name; + m_modified = true; +} + +void BanManager::remove(const std::string &ip_or_name) +{ + MutexAutoLock lock(m_mutex); + for (StringMap::iterator it = m_ips.begin(); it != m_ips.end();) { + if ((it->first == ip_or_name) || (it->second == ip_or_name)) { + m_ips.erase(it++); + m_modified = true; + } else { + ++it; + } + } +} + + +bool BanManager::isModified() +{ + MutexAutoLock lock(m_mutex); + return m_modified; +} + diff --git a/src/ban.h b/src/ban.h new file mode 100644 index 0000000..3e2ab7a --- /dev/null +++ b/src/ban.h @@ -0,0 +1,49 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "util/string.h" +#include "threading/thread.h" +#include "exceptions.h" +#include <map> +#include <string> +#include <mutex> + +class BanManager +{ +public: + BanManager(const std::string &banfilepath); + ~BanManager(); + void load(); + void save(); + bool isIpBanned(const std::string &ip); + // Supplying ip_or_name = "" lists all bans. + std::string getBanDescription(const std::string &ip_or_name); + std::string getBanName(const std::string &ip); + void add(const std::string &ip, const std::string &name); + void remove(const std::string &ip_or_name); + bool isModified(); + +private: + std::mutex m_mutex; + std::string m_banfilepath = ""; + StringMap m_ips; + bool m_modified = false; +}; diff --git a/src/benchmark/CMakeLists.txt b/src/benchmark/CMakeLists.txt new file mode 100644 index 0000000..5feba34 --- /dev/null +++ b/src/benchmark/CMakeLists.txt @@ -0,0 +1,7 @@ +set (BENCHMARK_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/benchmark.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/benchmark_serialize.cpp + PARENT_SCOPE) + +set (BENCHMARK_CLIENT_SRCS + PARENT_SCOPE) diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp new file mode 100644 index 0000000..0bc2af3 --- /dev/null +++ b/src/benchmark/benchmark.cpp @@ -0,0 +1,32 @@ +/* +Minetest +Copyright (C) 2022 Minetest Authors + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "benchmark/benchmark.h" + +// This must be set in just this file +#define CATCH_CONFIG_RUNNER +#include "benchmark_setup.h" + +int run_benchmarks() +{ + int argc = 1; + const char *argv[] = { "MinetestBenchmark", NULL }; + int errCount = Catch::Session().run(argc, argv); + return errCount ? 1 : 0; +} diff --git a/src/benchmark/benchmark.h b/src/benchmark/benchmark.h new file mode 100644 index 0000000..45dd9b6 --- /dev/null +++ b/src/benchmark/benchmark.h @@ -0,0 +1,26 @@ +/* +Minetest +Copyright (C) 2022 Minetest Authors + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "config.h" + +#if BUILD_BENCHMARKS +extern int run_benchmarks(); +#endif diff --git a/src/benchmark/benchmark_serialize.cpp b/src/benchmark/benchmark_serialize.cpp new file mode 100644 index 0000000..97cc7d5 --- /dev/null +++ b/src/benchmark/benchmark_serialize.cpp @@ -0,0 +1,71 @@ +/* +Minetest +Copyright (C) 2022 Minetest Authors + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "benchmark_setup.h" +#include "util/serialize.h" +#include <sstream> +#include <ios> + +// Builds a string of exactly `length` characters by repeating `s` (rest cut off) +static std::string makeRepeatTo(const std::string &s, size_t length) +{ + std::string v; + v.reserve(length + s.size()); + for (size_t i = 0; i < length; i += s.size()) { + v += s; + } + v.resize(length); + return v; +} + +#define BENCH3(_label, _chars, _length, _lengthlabel) \ + BENCHMARK_ADVANCED("serializeJsonStringIfNeeded_" _lengthlabel "_" _label)(Catch::Benchmark::Chronometer meter) { \ + std::string s = makeRepeatTo(_chars, _length); \ + meter.measure([&] { return serializeJsonStringIfNeeded(s); }); \ + }; \ + BENCHMARK_ADVANCED("deSerializeJsonStringIfNeeded_" _lengthlabel "_" _label)(Catch::Benchmark::Chronometer meter) { \ + std::string s = makeRepeatTo(_chars, _length); \ + std::string serialized = serializeJsonStringIfNeeded(s); \ + std::istringstream is(serialized, std::ios::binary); \ + meter.measure([&] { \ + is.clear(); \ + is.seekg(0, std::ios::beg); \ + return deSerializeJsonStringIfNeeded(is); \ + }); \ + }; + +/* Both with and without a space character (' ') */ +#define BENCH2(_label, _chars, _length, _lengthlabel) \ + BENCH3(_label, _chars, _length, _lengthlabel) \ + BENCH3(_label "_with_space", " " _chars, _length, _lengthlabel) \ + +/* Iterate over input lengths */ +#define BENCH1(_label, _chars) \ + BENCH2(_label, _chars, 10, "small") \ + BENCH2(_label, _chars, 10000, "large") + +/* Iterate over character sets */ +#define BENCH_ALL() \ + BENCH1("alpha", "abcdefghijklmnopqrstuvwxyz") \ + BENCH1("escaped", "\"\\/\b\f\n\r\t") \ + BENCH1("nonascii", "\xf0\xff") + +TEST_CASE("benchmark_serialize") { + BENCH_ALL() +} diff --git a/src/benchmark/benchmark_setup.h b/src/benchmark/benchmark_setup.h new file mode 100644 index 0000000..34a4eca --- /dev/null +++ b/src/benchmark/benchmark_setup.h @@ -0,0 +1,22 @@ +/* +Minetest +Copyright (C) 2022 Minetest Authors + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#define CATCH_CONFIG_ENABLE_BENCHMARKING +#define CATCH_CONFIG_CONSOLE_WIDTH 160 +#include <catch.hpp> diff --git a/src/chat.cpp b/src/chat.cpp new file mode 100644 index 0000000..9483fb9 --- /dev/null +++ b/src/chat.cpp @@ -0,0 +1,845 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "chat.h" + +#include <algorithm> +#include <cctype> +#include <sstream> + +#include "config.h" +#include "debug.h" +#include "util/strfnd.h" +#include "util/string.h" +#include "util/numeric.h" + +ChatBuffer::ChatBuffer(u32 scrollback): + m_scrollback(scrollback) +{ + if (m_scrollback == 0) + m_scrollback = 1; + m_empty_formatted_line.first = true; + + m_cache_clickable_chat_weblinks = false; + // Curses mode cannot access g_settings here + if (g_settings != nullptr) { + m_cache_clickable_chat_weblinks = g_settings->getBool("clickable_chat_weblinks"); + if (m_cache_clickable_chat_weblinks) { + std::string colorval = g_settings->get("chat_weblink_color"); + parseColorString(colorval, m_cache_chat_weblink_color, false, 255); + m_cache_chat_weblink_color.setAlpha(255); + } + } +} + +void ChatBuffer::addLine(const std::wstring &name, const std::wstring &text) +{ + m_lines_modified = true; + + ChatLine line(name, text); + m_unformatted.push_back(line); + + if (m_rows > 0) { + // m_formatted is valid and must be kept valid + bool scrolled_at_bottom = (m_scroll == getBottomScrollPos()); + u32 num_added = formatChatLine(line, m_cols, m_formatted); + if (scrolled_at_bottom) + m_scroll += num_added; + } + + // Limit number of lines by m_scrollback + if (m_unformatted.size() > m_scrollback) { + deleteOldest(m_unformatted.size() - m_scrollback); + } +} + +void ChatBuffer::clear() +{ + m_unformatted.clear(); + m_formatted.clear(); + m_scroll = 0; + m_lines_modified = true; +} + +u32 ChatBuffer::getLineCount() const +{ + return m_unformatted.size(); +} + +const ChatLine& ChatBuffer::getLine(u32 index) const +{ + assert(index < getLineCount()); // pre-condition + return m_unformatted[index]; +} + +void ChatBuffer::step(f32 dtime) +{ + for (ChatLine &line : m_unformatted) { + line.age += dtime; + } +} + +void ChatBuffer::deleteOldest(u32 count) +{ + bool at_bottom = (m_scroll == getBottomScrollPos()); + + u32 del_unformatted = 0; + u32 del_formatted = 0; + + while (count > 0 && del_unformatted < m_unformatted.size()) { + ++del_unformatted; + + // keep m_formatted in sync + if (del_formatted < m_formatted.size()) { + sanity_check(m_formatted[del_formatted].first); + ++del_formatted; + while (del_formatted < m_formatted.size() && + !m_formatted[del_formatted].first) + ++del_formatted; + } + + --count; + } + + m_unformatted.erase(m_unformatted.begin(), m_unformatted.begin() + del_unformatted); + m_formatted.erase(m_formatted.begin(), m_formatted.begin() + del_formatted); + + if (del_unformatted > 0) + m_lines_modified = true; + + if (at_bottom) + m_scroll = getBottomScrollPos(); + else + scrollAbsolute(m_scroll - del_formatted); +} + +void ChatBuffer::deleteByAge(f32 maxAge) +{ + u32 count = 0; + while (count < m_unformatted.size() && m_unformatted[count].age > maxAge) + ++count; + deleteOldest(count); +} + +u32 ChatBuffer::getRows() const +{ + return m_rows; +} + +void ChatBuffer::reformat(u32 cols, u32 rows) +{ + if (cols == 0 || rows == 0) + { + // Clear formatted buffer + m_cols = 0; + m_rows = 0; + m_scroll = 0; + m_formatted.clear(); + } + else if (cols != m_cols || rows != m_rows) + { + // TODO: Avoid reformatting ALL lines (even invisible ones) + // each time the console size changes. + + // Find out the scroll position in *unformatted* lines + u32 restore_scroll_unformatted = 0; + u32 restore_scroll_formatted = 0; + bool at_bottom = (m_scroll == getBottomScrollPos()); + if (!at_bottom) + { + for (s32 i = 0; i < m_scroll; ++i) + { + if (m_formatted[i].first) + ++restore_scroll_unformatted; + } + } + + // If number of columns change, reformat everything + if (cols != m_cols) + { + m_formatted.clear(); + for (u32 i = 0; i < m_unformatted.size(); ++i) + { + if (i == restore_scroll_unformatted) + restore_scroll_formatted = m_formatted.size(); + formatChatLine(m_unformatted[i], cols, m_formatted); + } + } + + // Update the console size + m_cols = cols; + m_rows = rows; + + // Restore the scroll position + if (at_bottom) + { + scrollBottom(); + } + else + { + scrollAbsolute(restore_scroll_formatted); + } + } +} + +const ChatFormattedLine& ChatBuffer::getFormattedLine(u32 row) const +{ + s32 index = m_scroll + (s32) row; + if (index >= 0 && index < (s32) m_formatted.size()) + return m_formatted[index]; + + return m_empty_formatted_line; +} + +void ChatBuffer::scroll(s32 rows) +{ + scrollAbsolute(m_scroll + rows); +} + +void ChatBuffer::scrollAbsolute(s32 scroll) +{ + s32 top = getTopScrollPos(); + s32 bottom = getBottomScrollPos(); + + m_scroll = scroll; + if (m_scroll < top) + m_scroll = top; + if (m_scroll > bottom) + m_scroll = bottom; +} + +void ChatBuffer::scrollBottom() +{ + m_scroll = getBottomScrollPos(); +} + +u32 ChatBuffer::formatChatLine(const ChatLine& line, u32 cols, + std::vector<ChatFormattedLine>& destination) const +{ + u32 num_added = 0; + std::vector<ChatFormattedFragment> next_frags; + ChatFormattedLine next_line; + ChatFormattedFragment temp_frag; + u32 out_column = 0; + u32 in_pos = 0; + u32 hanging_indentation = 0; + + // Format the sender name and produce fragments + if (!line.name.empty()) { + temp_frag.text = L"<"; + temp_frag.column = 0; + //temp_frag.bold = 0; + next_frags.push_back(temp_frag); + temp_frag.text = line.name; + temp_frag.column = 0; + //temp_frag.bold = 1; + next_frags.push_back(temp_frag); + temp_frag.text = L"> "; + temp_frag.column = 0; + //temp_frag.bold = 0; + next_frags.push_back(temp_frag); + } + + std::wstring name_sanitized = line.name.c_str(); + + // Choose an indentation level + if (line.name.empty()) { + // Server messages + hanging_indentation = 0; + } else if (name_sanitized.size() + 3 <= cols/2) { + // Names shorter than about half the console width + hanging_indentation = line.name.size() + 3; + } else { + // Very long names + hanging_indentation = 2; + } + //EnrichedString line_text(line.text); + + next_line.first = true; + // Set/use forced newline after the last frag in each line + bool mark_newline = false; + + // Produce fragments and layout them into lines + while (!next_frags.empty() || in_pos < line.text.size()) { + mark_newline = false; // now using this to USE line-end frag + + // Layout fragments into lines + while (!next_frags.empty()) { + ChatFormattedFragment& frag = next_frags[0]; + + // Force newline after this frag, if marked + if (frag.column == INT_MAX) + mark_newline = true; + + if (frag.text.size() <= cols - out_column) { + // Fragment fits into current line + frag.column = out_column; + next_line.fragments.push_back(frag); + out_column += frag.text.size(); + next_frags.erase(next_frags.begin()); + } else { + // Fragment does not fit into current line + // So split it up + temp_frag.text = frag.text.substr(0, cols - out_column); + temp_frag.column = out_column; + temp_frag.weblink = frag.weblink; + + next_line.fragments.push_back(temp_frag); + frag.text = frag.text.substr(cols - out_column); + frag.column = 0; + out_column = cols; + } + + if (out_column == cols || mark_newline) { + // End the current line + destination.push_back(next_line); + num_added++; + next_line.fragments.clear(); + next_line.first = false; + + out_column = hanging_indentation; + mark_newline = false; + } + } + + // Produce fragment(s) for next formatted line + if (!(in_pos < line.text.size())) + continue; + + const std::wstring &linestring = line.text.getString(); + u32 remaining_in_output = cols - out_column; + size_t http_pos = std::wstring::npos; + mark_newline = false; // now using this to SET line-end frag + + // Construct all frags for next output line + while (!mark_newline) { + // Determine a fragment length <= the minimum of + // remaining_in_{in,out}put. Try to end the fragment + // on a word boundary. + u32 frag_length = 0, space_pos = 0; + u32 remaining_in_input = line.text.size() - in_pos; + + if (m_cache_clickable_chat_weblinks) { + // Note: unsigned(-1) on fail + http_pos = linestring.find(L"https://", in_pos); + if (http_pos == std::wstring::npos) + http_pos = linestring.find(L"http://", in_pos); + if (http_pos != std::wstring::npos) + http_pos -= in_pos; + } + + while (frag_length < remaining_in_input && + frag_length < remaining_in_output) { + if (iswspace(linestring[in_pos + frag_length])) + space_pos = frag_length; + ++frag_length; + } + + if (http_pos >= remaining_in_output) { + // Http not in range, grab until space or EOL, halt as normal. + // Note this works because (http_pos = npos) is unsigned(-1) + + mark_newline = true; + } else if (http_pos == 0) { + // At http, grab ALL until FIRST whitespace or end marker. loop. + // If at end of string, next loop will be empty string to mark end of weblink. + + frag_length = 6; // Frag is at least "http://" + + // Chars to mark end of weblink + // TODO? replace this with a safer (slower) regex whitelist? + static const std::wstring delim_chars = L"\'\";"; + wchar_t tempchar = linestring[in_pos+frag_length]; + while (frag_length < remaining_in_input && + !iswspace(tempchar) && + delim_chars.find(tempchar) == std::wstring::npos) { + ++frag_length; + tempchar = linestring[in_pos+frag_length]; + } + + space_pos = frag_length - 1; + // This frag may need to be force-split. That's ok, urls aren't "words" + if (frag_length >= remaining_in_output) { + mark_newline = true; + } + } else { + // Http in range, grab until http, loop + + space_pos = http_pos - 1; + frag_length = http_pos; + } + + // Include trailing space in current frag + if (space_pos != 0 && frag_length < remaining_in_input) + frag_length = space_pos + 1; + + temp_frag.text = line.text.substr(in_pos, frag_length); + // A hack so this frag remembers mark_newline for the layout phase + temp_frag.column = mark_newline ? INT_MAX : 0; + + if (http_pos == 0) { + // Discard color stuff from the source frag + temp_frag.text = EnrichedString(temp_frag.text.getString()); + temp_frag.text.setDefaultColor(m_cache_chat_weblink_color); + // Set weblink in the frag meta + temp_frag.weblink = wide_to_utf8(temp_frag.text.getString()); + } else { + temp_frag.weblink.clear(); + } + next_frags.push_back(temp_frag); + in_pos += frag_length; + remaining_in_output -= std::min(frag_length, remaining_in_output); + } + } + + // End the last line + if (num_added == 0 || !next_line.fragments.empty()) { + destination.push_back(next_line); + num_added++; + } + + return num_added; +} + +s32 ChatBuffer::getTopScrollPos() const +{ + s32 formatted_count = (s32) m_formatted.size(); + s32 rows = (s32) m_rows; + if (rows == 0) + return 0; + + if (formatted_count <= rows) + return formatted_count - rows; + + return 0; +} + +s32 ChatBuffer::getBottomScrollPos() const +{ + s32 formatted_count = (s32) m_formatted.size(); + s32 rows = (s32) m_rows; + if (rows == 0) + return 0; + + return formatted_count - rows; +} + +void ChatBuffer::resize(u32 scrollback) +{ + m_scrollback = scrollback; + if (m_unformatted.size() > m_scrollback) + deleteOldest(m_unformatted.size() - m_scrollback); +} + + +ChatPrompt::ChatPrompt(const std::wstring &prompt, u32 history_limit): + m_prompt(prompt), + m_history_limit(history_limit) +{ +} + +void ChatPrompt::input(wchar_t ch) +{ + m_line.insert(m_cursor, 1, ch); + m_cursor++; + clampView(); + m_nick_completion_start = 0; + m_nick_completion_end = 0; +} + +void ChatPrompt::input(const std::wstring &str) +{ + m_line.insert(m_cursor, str); + m_cursor += str.size(); + clampView(); + m_nick_completion_start = 0; + m_nick_completion_end = 0; +} + +void ChatPrompt::addToHistory(const std::wstring &line) +{ + if (!line.empty() && + (m_history.size() == 0 || m_history.back() != line)) { + // Remove all duplicates + m_history.erase(std::remove(m_history.begin(), m_history.end(), + line), m_history.end()); + // Push unique line + m_history.push_back(line); + } + if (m_history.size() > m_history_limit) + m_history.erase(m_history.begin()); + m_history_index = m_history.size(); +} + +void ChatPrompt::clear() +{ + m_line.clear(); + m_view = 0; + m_cursor = 0; + m_nick_completion_start = 0; + m_nick_completion_end = 0; +} + +std::wstring ChatPrompt::replace(const std::wstring &line) +{ + std::wstring old_line = m_line; + m_line = line; + m_view = m_cursor = line.size(); + clampView(); + m_nick_completion_start = 0; + m_nick_completion_end = 0; + return old_line; +} + +void ChatPrompt::historyPrev() +{ + if (m_history_index != 0) + { + --m_history_index; + replace(m_history[m_history_index]); + } +} + +void ChatPrompt::historyNext() +{ + if (m_history_index + 1 >= m_history.size()) + { + m_history_index = m_history.size(); + replace(L""); + } + else + { + ++m_history_index; + replace(m_history[m_history_index]); + } +} + +void ChatPrompt::nickCompletion(const std::list<std::string>& names, bool backwards) +{ + // Two cases: + // (a) m_nick_completion_start == m_nick_completion_end == 0 + // Then no previous nick completion is active. + // Get the word around the cursor and replace with any nick + // that has that word as a prefix. + // (b) else, continue a previous nick completion. + // m_nick_completion_start..m_nick_completion_end are the + // interval where the originally used prefix was. Cycle + // through the list of completions of that prefix. + u32 prefix_start = m_nick_completion_start; + u32 prefix_end = m_nick_completion_end; + bool initial = (prefix_end == 0); + if (initial) + { + // no previous nick completion is active + prefix_start = prefix_end = m_cursor; + while (prefix_start > 0 && !iswspace(m_line[prefix_start-1])) + --prefix_start; + while (prefix_end < m_line.size() && !iswspace(m_line[prefix_end])) + ++prefix_end; + if (prefix_start == prefix_end) + return; + } + std::wstring prefix = m_line.substr(prefix_start, prefix_end - prefix_start); + + // find all names that start with the selected prefix + std::vector<std::wstring> completions; + for (const std::string &name : names) { + std::wstring completion = utf8_to_wide(name); + if (str_starts_with(completion, prefix, true)) { + if (prefix_start == 0) + completion += L": "; + completions.push_back(completion); + } + } + + if (completions.empty()) + return; + + // find a replacement string and the word that will be replaced + u32 word_end = prefix_end; + u32 replacement_index = 0; + if (!initial) + { + while (word_end < m_line.size() && !iswspace(m_line[word_end])) + ++word_end; + std::wstring word = m_line.substr(prefix_start, word_end - prefix_start); + + // cycle through completions + for (u32 i = 0; i < completions.size(); ++i) + { + if (str_equal(word, completions[i], true)) + { + if (backwards) + replacement_index = i + completions.size() - 1; + else + replacement_index = i + 1; + replacement_index %= completions.size(); + break; + } + } + } + std::wstring replacement = completions[replacement_index]; + if (word_end < m_line.size() && iswspace(m_line[word_end])) + ++word_end; + + // replace existing word with replacement word, + // place the cursor at the end and record the completion prefix + m_line.replace(prefix_start, word_end - prefix_start, replacement); + m_cursor = prefix_start + replacement.size(); + clampView(); + m_nick_completion_start = prefix_start; + m_nick_completion_end = prefix_end; +} + +void ChatPrompt::reformat(u32 cols) +{ + if (cols <= m_prompt.size()) + { + m_cols = 0; + m_view = m_cursor; + } + else + { + s32 length = m_line.size(); + bool was_at_end = (m_view + m_cols >= length + 1); + m_cols = cols - m_prompt.size(); + if (was_at_end) + m_view = length; + clampView(); + } +} + +std::wstring ChatPrompt::getVisiblePortion() const +{ + return m_prompt + m_line.substr(m_view, m_cols); +} + +s32 ChatPrompt::getVisibleCursorPosition() const +{ + return m_cursor - m_view + m_prompt.size(); +} + +void ChatPrompt::cursorOperation(CursorOp op, CursorOpDir dir, CursorOpScope scope) +{ + s32 old_cursor = m_cursor; + s32 new_cursor = m_cursor; + + s32 length = m_line.size(); + s32 increment = (dir == CURSOROP_DIR_RIGHT) ? 1 : -1; + + switch (scope) { + case CURSOROP_SCOPE_CHARACTER: + new_cursor += increment; + break; + case CURSOROP_SCOPE_WORD: + if (dir == CURSOROP_DIR_RIGHT) { + // skip one word to the right + while (new_cursor < length && iswspace(m_line[new_cursor])) + new_cursor++; + while (new_cursor < length && !iswspace(m_line[new_cursor])) + new_cursor++; + while (new_cursor < length && iswspace(m_line[new_cursor])) + new_cursor++; + } else { + // skip one word to the left + while (new_cursor >= 1 && iswspace(m_line[new_cursor - 1])) + new_cursor--; + while (new_cursor >= 1 && !iswspace(m_line[new_cursor - 1])) + new_cursor--; + } + break; + case CURSOROP_SCOPE_LINE: + new_cursor += increment * length; + break; + case CURSOROP_SCOPE_SELECTION: + break; + } + + new_cursor = MYMAX(MYMIN(new_cursor, length), 0); + + switch (op) { + case CURSOROP_MOVE: + m_cursor = new_cursor; + m_cursor_len = 0; + break; + case CURSOROP_DELETE: + if (m_cursor_len > 0) { // Delete selected text first + m_line.erase(m_cursor, m_cursor_len); + } else { + m_cursor = MYMIN(new_cursor, old_cursor); + m_line.erase(m_cursor, abs(new_cursor - old_cursor)); + } + m_cursor_len = 0; + break; + case CURSOROP_SELECT: + if (scope == CURSOROP_SCOPE_LINE) { + m_cursor = 0; + m_cursor_len = length; + } else { + m_cursor = MYMIN(new_cursor, old_cursor); + m_cursor_len += abs(new_cursor - old_cursor); + m_cursor_len = MYMIN(m_cursor_len, length - m_cursor); + } + break; + } + + clampView(); + + m_nick_completion_start = 0; + m_nick_completion_end = 0; +} + +void ChatPrompt::clampView() +{ + s32 length = m_line.size(); + if (length + 1 <= m_cols) + { + m_view = 0; + } + else + { + m_view = MYMIN(m_view, length + 1 - m_cols); + m_view = MYMIN(m_view, m_cursor); + m_view = MYMAX(m_view, m_cursor - m_cols + 1); + m_view = MYMAX(m_view, 0); + } +} + + + +ChatBackend::ChatBackend(): + m_console_buffer(500), + m_recent_buffer(6), + m_prompt(L"]", 500) +{ +} + +void ChatBackend::addMessage(const std::wstring &name, std::wstring text) +{ + // Note: A message may consist of multiple lines, for example the MOTD. + text = translate_string(text); + WStrfnd fnd(text); + while (!fnd.at_end()) + { + std::wstring line = fnd.next(L"\n"); + m_console_buffer.addLine(name, line); + m_recent_buffer.addLine(name, line); + } +} + +void ChatBackend::addUnparsedMessage(std::wstring message) +{ + // TODO: Remove the need to parse chat messages client-side, by sending + // separate name and text fields in TOCLIENT_CHAT_MESSAGE. + + if (message.size() >= 2 && message[0] == L'<') + { + std::size_t closing = message.find_first_of(L'>', 1); + if (closing != std::wstring::npos && + closing + 2 <= message.size() && + message[closing+1] == L' ') + { + std::wstring name = message.substr(1, closing - 1); + std::wstring text = message.substr(closing + 2); + addMessage(name, text); + return; + } + } + + // Unable to parse, probably a server message. + addMessage(L"", message); +} + +ChatBuffer& ChatBackend::getConsoleBuffer() +{ + return m_console_buffer; +} + +ChatBuffer& ChatBackend::getRecentBuffer() +{ + return m_recent_buffer; +} + +EnrichedString ChatBackend::getRecentChat() const +{ + EnrichedString result; + for (u32 i = 0; i < m_recent_buffer.getLineCount(); ++i) { + const ChatLine& line = m_recent_buffer.getLine(i); + if (i != 0) + result += L"\n"; + if (!line.name.empty()) { + result += L"<"; + result += line.name; + result += L"> "; + } + result += line.text; + } + return result; +} + +ChatPrompt& ChatBackend::getPrompt() +{ + return m_prompt; +} + +void ChatBackend::reformat(u32 cols, u32 rows) +{ + m_console_buffer.reformat(cols, rows); + + // no need to reformat m_recent_buffer, its formatted lines + // are not used + + m_prompt.reformat(cols); +} + +void ChatBackend::clearRecentChat() +{ + m_recent_buffer.clear(); +} + + +void ChatBackend::applySettings() +{ + u32 recent_lines = g_settings->getU32("recent_chat_messages"); + recent_lines = rangelim(recent_lines, 2, 20); + m_recent_buffer.resize(recent_lines); +} + +void ChatBackend::step(float dtime) +{ + m_recent_buffer.step(dtime); + m_recent_buffer.deleteByAge(60.0); + + // no need to age messages in anything but m_recent_buffer +} + +void ChatBackend::scroll(s32 rows) +{ + m_console_buffer.scroll(rows); +} + +void ChatBackend::scrollPageDown() +{ + m_console_buffer.scroll(m_console_buffer.getRows()); +} + +void ChatBackend::scrollPageUp() +{ + m_console_buffer.scroll(-(s32)m_console_buffer.getRows()); +} diff --git a/src/chat.h b/src/chat.h new file mode 100644 index 0000000..fc080f6 --- /dev/null +++ b/src/chat.h @@ -0,0 +1,309 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <vector> +#include <list> + +#include "irrlichttypes.h" +#include "util/enriched_string.h" +#include "settings.h" + +// Chat console related classes + +struct ChatLine +{ + // age in seconds + f32 age = 0.0f; + // name of sending player, or empty if sent by server + EnrichedString name; + // message text + EnrichedString text; + + ChatLine(const std::wstring &a_name, const std::wstring &a_text): + name(a_name), + text(a_text) + { + } + + ChatLine(const EnrichedString &a_name, const EnrichedString &a_text): + name(a_name), + text(a_text) + { + } +}; + +struct ChatFormattedFragment +{ + // text string + EnrichedString text; + // starting column + u32 column; + // web link is empty for most frags + std::string weblink; + // formatting + //u8 bold:1; +}; + +struct ChatFormattedLine +{ + // Array of text fragments + std::vector<ChatFormattedFragment> fragments; + // true if first line of one formatted ChatLine + bool first; +}; + +class ChatBuffer +{ +public: + ChatBuffer(u32 scrollback); + ~ChatBuffer() = default; + + // Append chat line + // Removes oldest chat line if scrollback size is reached + void addLine(const std::wstring &name, const std::wstring &text); + + // Remove all chat lines + void clear(); + + // Get number of lines currently in buffer. + u32 getLineCount() const; + // Get reference to i-th chat line. + const ChatLine& getLine(u32 index) const; + + // Increase each chat line's age by dtime. + void step(f32 dtime); + // Delete oldest N chat lines. + void deleteOldest(u32 count); + // Delete lines older than maxAge. + void deleteByAge(f32 maxAge); + + // Get number of rows, 0 if reformat has not been called yet. + u32 getRows() const; + // Update console size and reformat all formatted lines. + void reformat(u32 cols, u32 rows); + // Get formatted line for a given row (0 is top of screen). + // Only valid after reformat has been called at least once + const ChatFormattedLine& getFormattedLine(u32 row) const; + // Scrolling in formatted buffer (relative) + // positive rows == scroll up, negative rows == scroll down + void scroll(s32 rows); + // Scrolling in formatted buffer (absolute) + void scrollAbsolute(s32 scroll); + // Scroll to bottom of buffer (newest) + void scrollBottom(); + + // Functions for keeping track of whether the lines were modified by any + // preceding operations + // If they were not changed, getLineCount() and getLine() output the same as + // before + bool getLinesModified() const { return m_lines_modified; } + void resetLinesModified() { m_lines_modified = false; } + + // Format a chat line for the given number of columns. + // Appends the formatted lines to the destination array and + // returns the number of formatted lines. + u32 formatChatLine(const ChatLine& line, u32 cols, + std::vector<ChatFormattedLine>& destination) const; + + void resize(u32 scrollback); + +protected: + s32 getTopScrollPos() const; + s32 getBottomScrollPos() const; + +private: + // Scrollback size + u32 m_scrollback; + // Array of unformatted chat lines + std::vector<ChatLine> m_unformatted; + + // Number of character columns in console + u32 m_cols = 0; + // Number of character rows in console + u32 m_rows = 0; + // Scroll position (console's top line index into m_formatted) + s32 m_scroll = 0; + // Array of formatted lines + std::vector<ChatFormattedLine> m_formatted; + // Empty formatted line, for error returns + ChatFormattedLine m_empty_formatted_line; + + // Enable clickable chat weblinks + bool m_cache_clickable_chat_weblinks; + // Color of clickable chat weblinks + irr::video::SColor m_cache_chat_weblink_color; + + // Whether the lines were modified since last markLinesUnchanged() + // Is always set to true when m_unformatted is modified, because that's what + // determines the output of getLineCount() and getLine() + bool m_lines_modified = true; +}; + +class ChatPrompt +{ +public: + ChatPrompt(const std::wstring &prompt, u32 history_limit); + ~ChatPrompt() = default; + + // Input character or string + void input(wchar_t ch); + void input(const std::wstring &str); + + // Add a string to the history + void addToHistory(const std::wstring &line); + + // Get current line + std::wstring getLine() const { return m_line; } + + // Get section of line that is currently selected + std::wstring getSelection() const { return m_line.substr(m_cursor, m_cursor_len); } + + // Clear the current line + void clear(); + + // Replace the current line with the given text + std::wstring replace(const std::wstring &line); + + // Select previous command from history + void historyPrev(); + // Select next command from history + void historyNext(); + + // Nick completion + void nickCompletion(const std::list<std::string>& names, bool backwards); + + // Update console size and reformat the visible portion of the prompt + void reformat(u32 cols); + // Get visible portion of the prompt. + std::wstring getVisiblePortion() const; + // Get cursor position (relative to visible portion). -1 if invalid + s32 getVisibleCursorPosition() const; + // Get length of cursor selection + s32 getCursorLength() const { return m_cursor_len; } + + // Cursor operations + enum CursorOp { + CURSOROP_MOVE, + CURSOROP_SELECT, + CURSOROP_DELETE + }; + + // Cursor operation direction + enum CursorOpDir { + CURSOROP_DIR_LEFT, + CURSOROP_DIR_RIGHT + }; + + // Cursor operation scope + enum CursorOpScope { + CURSOROP_SCOPE_CHARACTER, + CURSOROP_SCOPE_WORD, + CURSOROP_SCOPE_LINE, + CURSOROP_SCOPE_SELECTION + }; + + // Cursor operation + // op specifies whether it's a move or delete operation + // dir specifies whether the operation goes left or right + // scope specifies how far the operation will reach (char/word/line) + // Examples: + // cursorOperation(CURSOROP_MOVE, CURSOROP_DIR_RIGHT, CURSOROP_SCOPE_LINE) + // moves the cursor to the end of the line. + // cursorOperation(CURSOROP_DELETE, CURSOROP_DIR_LEFT, CURSOROP_SCOPE_WORD) + // deletes the word to the left of the cursor. + void cursorOperation(CursorOp op, CursorOpDir dir, CursorOpScope scope); + +protected: + // set m_view to ensure that 0 <= m_view <= m_cursor < m_view + m_cols + // if line can be fully shown, set m_view to zero + // else, also ensure m_view <= m_line.size() + 1 - m_cols + void clampView(); + +private: + // Prompt prefix + std::wstring m_prompt = L""; + // Currently edited line + std::wstring m_line = L""; + // History buffer + std::vector<std::wstring> m_history; + // History index (0 <= m_history_index <= m_history.size()) + u32 m_history_index = 0; + // Maximum number of history entries + u32 m_history_limit; + + // Number of columns excluding columns reserved for the prompt + s32 m_cols = 0; + // Start of visible portion (index into m_line) + s32 m_view = 0; + // Cursor (index into m_line) + s32 m_cursor = 0; + // Cursor length (length of selected portion of line) + s32 m_cursor_len = 0; + + // Last nick completion start (index into m_line) + s32 m_nick_completion_start = 0; + // Last nick completion start (index into m_line) + s32 m_nick_completion_end = 0; +}; + +class ChatBackend +{ +public: + ChatBackend(); + ~ChatBackend() = default; + + // Add chat message + void addMessage(const std::wstring &name, std::wstring text); + // Parse and add unparsed chat message + void addUnparsedMessage(std::wstring line); + + // Get the console buffer + ChatBuffer& getConsoleBuffer(); + // Get the recent messages buffer + ChatBuffer& getRecentBuffer(); + // Concatenate all recent messages + EnrichedString getRecentChat() const; + // Get the console prompt + ChatPrompt& getPrompt(); + + // Reformat all buffers + void reformat(u32 cols, u32 rows); + + // Clear all recent messages + void clearRecentChat(); + + // Age recent messages + void step(float dtime); + + // Scrolling + void scroll(s32 rows); + void scrollPageDown(); + void scrollPageUp(); + + // Resize recent buffer based on settings + void applySettings(); + +private: + ChatBuffer m_console_buffer; + ChatBuffer m_recent_buffer; + ChatPrompt m_prompt; +}; diff --git a/src/chat_interface.h b/src/chat_interface.h new file mode 100644 index 0000000..5dc3d38 --- /dev/null +++ b/src/chat_interface.h @@ -0,0 +1,79 @@ +/* +Minetest +Copyright (C) 2015 est31 <MTest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "util/container.h" +#include <string> +#include <queue> +#include "irrlichttypes.h" + +enum ChatEventType { + CET_CHAT, + CET_NICK_ADD, + CET_NICK_REMOVE, + CET_TIME_INFO, +}; + +class ChatEvent { +protected: + ChatEvent(ChatEventType a_type) { type = a_type; } +public: + ChatEventType type; +}; + +struct ChatEventTimeInfo : public ChatEvent { + ChatEventTimeInfo( + u64 a_game_time, + u32 a_time) : + ChatEvent(CET_TIME_INFO), + game_time(a_game_time), + time(a_time) + {} + + u64 game_time; + u32 time; +}; + +struct ChatEventNick : public ChatEvent { + ChatEventNick(ChatEventType a_type, + const std::string &a_nick) : + ChatEvent(a_type), // one of CET_NICK_ADD, CET_NICK_REMOVE + nick(a_nick) + {} + + std::string nick; +}; + +struct ChatEventChat : public ChatEvent { + ChatEventChat(const std::string &a_nick, + const std::wstring &an_evt_msg) : + ChatEvent(CET_CHAT), + nick(a_nick), + evt_msg(an_evt_msg) + {} + + std::string nick; + std::wstring evt_msg; +}; + +struct ChatInterface { + MutexedQueue<ChatEvent *> command_queue; // chat backend --> server + MutexedQueue<ChatEvent *> outgoing_queue; // server --> chat backend +}; diff --git a/src/chatmessage.h b/src/chatmessage.h new file mode 100644 index 0000000..f4ecd63 --- /dev/null +++ b/src/chatmessage.h @@ -0,0 +1,49 @@ +/* +Minetest +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <ctime> + +enum ChatMessageType +{ + CHATMESSAGE_TYPE_RAW = 0, + CHATMESSAGE_TYPE_NORMAL = 1, + CHATMESSAGE_TYPE_ANNOUNCE = 2, + CHATMESSAGE_TYPE_SYSTEM = 3, + CHATMESSAGE_TYPE_MAX = 4, +}; + +struct ChatMessage +{ + ChatMessage(const std::wstring &m = L"") : message(m) {} + + ChatMessage(ChatMessageType t, const std::wstring &m, const std::wstring &s = L"", + std::time_t ts = std::time(0)) : + type(t), + message(m), sender(s), timestamp(ts) + { + } + + ChatMessageType type = CHATMESSAGE_TYPE_RAW; + std::wstring message = L""; + std::wstring sender = L""; + std::time_t timestamp = std::time(0); +}; diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt new file mode 100644 index 0000000..656ad45 --- /dev/null +++ b/src/client/CMakeLists.txt @@ -0,0 +1,66 @@ +set(sound_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/sound.cpp) + +if(USE_SOUND) + set(sound_SRCS ${sound_SRCS} + ${CMAKE_CURRENT_SOURCE_DIR}/sound_openal.cpp) + set(SOUND_INCLUDE_DIRS + ${OPENAL_INCLUDE_DIR} + ${VORBIS_INCLUDE_DIR} + ${OGG_INCLUDE_DIR} + PARENT_SCOPE) + set(SOUND_LIBRARIES + ${OPENAL_LIBRARY} + ${VORBIS_LIBRARIES} + PARENT_SCOPE) +endif() + +set(client_SRCS + ${sound_SRCS} + ${CMAKE_CURRENT_SOURCE_DIR}/meshgen/collector.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/render/anaglyph.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/render/core.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/render/factory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/render/interlaced.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/render/pageflip.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/render/plain.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/render/sidebyside.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/render/stereo.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/activeobjectmgr.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/camera.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/client.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/clientenvironment.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/clientlauncher.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/clientmap.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/clientmedia.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/clientobject.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/clouds.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/content_cao.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/content_cso.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/content_mapblock.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/filecache.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/fontengine.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/game.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/gameui.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiscalingfilter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/hud.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/imagefilters.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/inputhandler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/joystick_controller.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keycode.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/localplayer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mapblock_mesh.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mesh.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mesh_generator_thread.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/minimap.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/particles.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/renderingengine.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/shader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/sky.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/wieldmesh.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/shadows/dynamicshadows.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/shadows/dynamicshadowsrender.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/shadows/shadowsshadercallbacks.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/shadows/shadowsScreenQuad.cpp + PARENT_SCOPE +) diff --git a/src/client/activeobjectmgr.cpp b/src/client/activeobjectmgr.cpp new file mode 100644 index 0000000..82f3cb9 --- /dev/null +++ b/src/client/activeobjectmgr.cpp @@ -0,0 +1,109 @@ +/* +Minetest +Copyright (C) 2010-2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <log.h> +#include "profiler.h" +#include "activeobjectmgr.h" + +namespace client +{ + +void ActiveObjectMgr::clear() +{ + // delete active objects + for (auto &active_object : m_active_objects) { + delete active_object.second; + // Object must be marked as gone when children try to detach + active_object.second = nullptr; + } + m_active_objects.clear(); +} + +void ActiveObjectMgr::step( + float dtime, const std::function<void(ClientActiveObject *)> &f) +{ + g_profiler->avg("ActiveObjectMgr: CAO count [#]", m_active_objects.size()); + for (auto &ao_it : m_active_objects) { + f(ao_it.second); + } +} + +// clang-format off +bool ActiveObjectMgr::registerObject(ClientActiveObject *obj) +{ + assert(obj); // Pre-condition + if (obj->getId() == 0) { + u16 new_id = getFreeId(); + if (new_id == 0) { + infostream << "Client::ActiveObjectMgr::registerObject(): " + << "no free id available" << std::endl; + + delete obj; + return false; + } + obj->setId(new_id); + } + + if (!isFreeId(obj->getId())) { + infostream << "Client::ActiveObjectMgr::registerObject(): " + << "id is not free (" << obj->getId() << ")" << std::endl; + delete obj; + return false; + } + infostream << "Client::ActiveObjectMgr::registerObject(): " + << "added (id=" << obj->getId() << ")" << std::endl; + m_active_objects[obj->getId()] = obj; + return true; +} + +void ActiveObjectMgr::removeObject(u16 id) +{ + verbosestream << "Client::ActiveObjectMgr::removeObject(): " + << "id=" << id << std::endl; + ClientActiveObject *obj = getActiveObject(id); + if (!obj) { + infostream << "Client::ActiveObjectMgr::removeObject(): " + << "id=" << id << " not found" << std::endl; + return; + } + + m_active_objects.erase(id); + + obj->removeFromScene(true); + delete obj; +} + +// clang-format on +void ActiveObjectMgr::getActiveObjects(const v3f &origin, f32 max_d, + std::vector<DistanceSortedActiveObject> &dest) +{ + f32 max_d2 = max_d * max_d; + for (auto &ao_it : m_active_objects) { + ClientActiveObject *obj = ao_it.second; + + f32 d2 = (obj->getPosition() - origin).getLengthSQ(); + + if (d2 > max_d2) + continue; + + dest.emplace_back(obj, d2); + } +} + +} // namespace client diff --git a/src/client/activeobjectmgr.h b/src/client/activeobjectmgr.h new file mode 100644 index 0000000..510b2d6 --- /dev/null +++ b/src/client/activeobjectmgr.h @@ -0,0 +1,41 @@ +/* +Minetest +Copyright (C) 2010-2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <functional> +#include <vector> +#include "../activeobjectmgr.h" +#include "clientobject.h" + +namespace client +{ +class ActiveObjectMgr : public ::ActiveObjectMgr<ClientActiveObject> +{ +public: + void clear(); + void step(float dtime, + const std::function<void(ClientActiveObject *)> &f) override; + bool registerObject(ClientActiveObject *obj) override; + void removeObject(u16 id) override; + + void getActiveObjects(const v3f &origin, f32 max_d, + std::vector<DistanceSortedActiveObject> &dest); +}; +} // namespace client diff --git a/src/client/camera.cpp b/src/client/camera.cpp new file mode 100644 index 0000000..df75c52 --- /dev/null +++ b/src/client/camera.cpp @@ -0,0 +1,708 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "camera.h" +#include "debug.h" +#include "client.h" +#include "config.h" +#include "map.h" +#include "clientmap.h" // MapDrawControl +#include "player.h" +#include <cmath> +#include "client/renderingengine.h" +#include "client/content_cao.h" +#include "settings.h" +#include "wieldmesh.h" +#include "noise.h" // easeCurve +#include "sound.h" +#include "mtevent.h" +#include "nodedef.h" +#include "util/numeric.h" +#include "constants.h" +#include "fontengine.h" +#include "script/scripting_client.h" +#include "gettext.h" + +#define CAMERA_OFFSET_STEP 200 +#define WIELDMESH_OFFSET_X 55.0f +#define WIELDMESH_OFFSET_Y -35.0f +#define WIELDMESH_AMPLITUDE_X 7.0f +#define WIELDMESH_AMPLITUDE_Y 10.0f + +Camera::Camera(MapDrawControl &draw_control, Client *client, RenderingEngine *rendering_engine): + m_draw_control(draw_control), + m_client(client), + m_player_light_color(0xFFFFFFFF) +{ + auto smgr = rendering_engine->get_scene_manager(); + // note: making the camera node a child of the player node + // would lead to unexpected behaviour, so we don't do that. + m_playernode = smgr->addEmptySceneNode(smgr->getRootSceneNode()); + m_headnode = smgr->addEmptySceneNode(m_playernode); + m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode()); + m_cameranode->bindTargetAndRotation(true); + + // This needs to be in its own scene manager. It is drawn after + // all other 3D scene nodes and before the GUI. + m_wieldmgr = smgr->createNewSceneManager(); + m_wieldmgr->addCameraSceneNode(); + m_wieldnode = new WieldMeshSceneNode(m_wieldmgr, -1, false); + m_wieldnode->setItem(ItemStack(), m_client); + m_wieldnode->drop(); // m_wieldmgr grabbed it + + /* TODO: Add a callback function so these can be updated when a setting + * changes. At this point in time it doesn't matter (e.g. /set + * is documented to change server settings only) + * + * TODO: Local caching of settings is not optimal and should at some stage + * be updated to use a global settings object for getting thse values + * (as opposed to the this local caching). This can be addressed in + * a later release. + */ + m_cache_fall_bobbing_amount = g_settings->getFloat("fall_bobbing_amount", 0.0f, 100.0f); + m_cache_view_bobbing_amount = g_settings->getFloat("view_bobbing_amount", 0.0f, 7.9f); + // 45 degrees is the lowest FOV that doesn't cause the server to treat this + // as a zoom FOV and load world beyond the set server limits. + m_cache_fov = g_settings->getFloat("fov", 45.0f, 160.0f); + m_arm_inertia = g_settings->getBool("arm_inertia"); + m_nametags.clear(); + m_show_nametag_backgrounds = g_settings->getBool("show_nametag_backgrounds"); +} + +Camera::~Camera() +{ + m_wieldmgr->drop(); +} + +void Camera::notifyFovChange() +{ + LocalPlayer *player = m_client->getEnv().getLocalPlayer(); + assert(player); + + PlayerFovSpec spec = player->getFov(); + + /* + * Update m_old_fov_degrees first - it serves as the starting point of the + * upcoming transition. + * + * If an FOV transition is already active, mark current FOV as the start of + * the new transition. If not, set it to the previous transition's target FOV. + */ + if (m_fov_transition_active) + m_old_fov_degrees = m_curr_fov_degrees; + else + m_old_fov_degrees = m_server_sent_fov ? m_target_fov_degrees : m_cache_fov; + + /* + * Update m_server_sent_fov next - it corresponds to the target FOV of the + * upcoming transition. + * + * Set it to m_cache_fov, if server-sent FOV is 0. Otherwise check if + * server-sent FOV is a multiplier, and multiply it with m_cache_fov instead + * of overriding. + */ + if (spec.fov == 0.0f) { + m_server_sent_fov = false; + m_target_fov_degrees = m_cache_fov; + } else { + m_server_sent_fov = true; + m_target_fov_degrees = spec.is_multiplier ? m_cache_fov * spec.fov : spec.fov; + } + + if (spec.transition_time > 0.0f) + m_fov_transition_active = true; + + // If FOV smooth transition is active, initialize required variables + if (m_fov_transition_active) { + m_transition_time = spec.transition_time; + m_fov_diff = m_target_fov_degrees - m_old_fov_degrees; + } +} + +// Returns the fractional part of x +inline f32 my_modf(f32 x) +{ + double dummy; + return modf(x, &dummy); +} + +void Camera::step(f32 dtime) +{ + if(m_view_bobbing_fall > 0) + { + m_view_bobbing_fall -= 3 * dtime; + if(m_view_bobbing_fall <= 0) + m_view_bobbing_fall = -1; // Mark the effect as finished + } + + bool was_under_zero = m_wield_change_timer < 0; + m_wield_change_timer = MYMIN(m_wield_change_timer + dtime, 0.125); + + if (m_wield_change_timer >= 0 && was_under_zero) { + m_wieldnode->setItem(m_wield_item_next, m_client); + m_wieldnode->setNodeLightColor(m_player_light_color); + } + + if (m_view_bobbing_state != 0) + { + //f32 offset = dtime * m_view_bobbing_speed * 0.035; + f32 offset = dtime * m_view_bobbing_speed * 0.030; + if (m_view_bobbing_state == 2) { + // Animation is getting turned off + if (m_view_bobbing_anim < 0.25) { + m_view_bobbing_anim -= offset; + } else if (m_view_bobbing_anim > 0.75) { + m_view_bobbing_anim += offset; + } else if (m_view_bobbing_anim < 0.5) { + m_view_bobbing_anim += offset; + if (m_view_bobbing_anim > 0.5) + m_view_bobbing_anim = 0.5; + } else { + m_view_bobbing_anim -= offset; + if (m_view_bobbing_anim < 0.5) + m_view_bobbing_anim = 0.5; + } + + if (m_view_bobbing_anim <= 0 || m_view_bobbing_anim >= 1 || + fabs(m_view_bobbing_anim - 0.5) < 0.01) { + m_view_bobbing_anim = 0; + m_view_bobbing_state = 0; + } + } + else { + float was = m_view_bobbing_anim; + m_view_bobbing_anim = my_modf(m_view_bobbing_anim + offset); + bool step = (was == 0 || + (was < 0.5f && m_view_bobbing_anim >= 0.5f) || + (was > 0.5f && m_view_bobbing_anim <= 0.5f)); + if(step) { + m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::VIEW_BOBBING_STEP)); + } + } + } + + if (m_digging_button != -1) { + f32 offset = dtime * 3.5f; + float m_digging_anim_was = m_digging_anim; + m_digging_anim += offset; + if (m_digging_anim >= 1) + { + m_digging_anim = 0; + m_digging_button = -1; + } + float lim = 0.15; + if(m_digging_anim_was < lim && m_digging_anim >= lim) + { + if (m_digging_button == 0) { + m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::CAMERA_PUNCH_LEFT)); + } else if(m_digging_button == 1) { + m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::CAMERA_PUNCH_RIGHT)); + } + } + } +} + +static inline v2f dir(const v2f &pos_dist) +{ + f32 x = pos_dist.X - WIELDMESH_OFFSET_X; + f32 y = pos_dist.Y - WIELDMESH_OFFSET_Y; + + f32 x_abs = std::fabs(x); + f32 y_abs = std::fabs(y); + + if (x_abs >= y_abs) { + y *= (1.0f / x_abs); + x /= x_abs; + } + + if (y_abs >= x_abs) { + x *= (1.0f / y_abs); + y /= y_abs; + } + + return v2f(std::fabs(x), std::fabs(y)); +} + +void Camera::addArmInertia(f32 player_yaw) +{ + m_cam_vel.X = std::fabs(rangelim(m_last_cam_pos.X - player_yaw, + -100.0f, 100.0f) / 0.016f) * 0.01f; + m_cam_vel.Y = std::fabs((m_last_cam_pos.Y - m_camera_direction.Y) / 0.016f); + f32 gap_X = std::fabs(WIELDMESH_OFFSET_X - m_wieldmesh_offset.X); + f32 gap_Y = std::fabs(WIELDMESH_OFFSET_Y - m_wieldmesh_offset.Y); + + if (m_cam_vel.X > 1.0f || m_cam_vel.Y > 1.0f) { + /* + The arm moves relative to the camera speed, + with an acceleration factor. + */ + + if (m_cam_vel.X > 1.0f) { + if (m_cam_vel.X > m_cam_vel_old.X) + m_cam_vel_old.X = m_cam_vel.X; + + f32 acc_X = 0.12f * (m_cam_vel.X - (gap_X * 0.1f)); + m_wieldmesh_offset.X += m_last_cam_pos.X < player_yaw ? acc_X : -acc_X; + + if (m_last_cam_pos.X != player_yaw) + m_last_cam_pos.X = player_yaw; + + m_wieldmesh_offset.X = rangelim(m_wieldmesh_offset.X, + WIELDMESH_OFFSET_X - (WIELDMESH_AMPLITUDE_X * 0.5f), + WIELDMESH_OFFSET_X + (WIELDMESH_AMPLITUDE_X * 0.5f)); + } + + if (m_cam_vel.Y > 1.0f) { + if (m_cam_vel.Y > m_cam_vel_old.Y) + m_cam_vel_old.Y = m_cam_vel.Y; + + f32 acc_Y = 0.12f * (m_cam_vel.Y - (gap_Y * 0.1f)); + m_wieldmesh_offset.Y += + m_last_cam_pos.Y > m_camera_direction.Y ? acc_Y : -acc_Y; + + if (m_last_cam_pos.Y != m_camera_direction.Y) + m_last_cam_pos.Y = m_camera_direction.Y; + + m_wieldmesh_offset.Y = rangelim(m_wieldmesh_offset.Y, + WIELDMESH_OFFSET_Y - (WIELDMESH_AMPLITUDE_Y * 0.5f), + WIELDMESH_OFFSET_Y + (WIELDMESH_AMPLITUDE_Y * 0.5f)); + } + + m_arm_dir = dir(m_wieldmesh_offset); + } else { + /* + Now the arm gets back to its default position when the camera stops, + following a vector, with a smooth deceleration factor. + */ + + f32 dec_X = 0.35f * (std::min(15.0f, m_cam_vel_old.X) * (1.0f + + (1.0f - m_arm_dir.X))) * (gap_X / 20.0f); + + f32 dec_Y = 0.25f * (std::min(15.0f, m_cam_vel_old.Y) * (1.0f + + (1.0f - m_arm_dir.Y))) * (gap_Y / 15.0f); + + if (gap_X < 0.1f) + m_cam_vel_old.X = 0.0f; + + m_wieldmesh_offset.X -= + m_wieldmesh_offset.X > WIELDMESH_OFFSET_X ? dec_X : -dec_X; + + if (gap_Y < 0.1f) + m_cam_vel_old.Y = 0.0f; + + m_wieldmesh_offset.Y -= + m_wieldmesh_offset.Y > WIELDMESH_OFFSET_Y ? dec_Y : -dec_Y; + } +} + +void Camera::update(LocalPlayer* player, f32 frametime, f32 tool_reload_ratio) +{ + // Get player position + // Smooth the movement when walking up stairs + v3f old_player_position = m_playernode->getPosition(); + v3f player_position = player->getPosition(); + + // This is worse than `LocalPlayer::getPosition()` but + // mods expect the player head to be at the parent's position + // plus eye height. + if (player->getParent()) + player_position = player->getParent()->getPosition(); + + // Smooth the camera movement after the player instantly moves upward due to stepheight. + // The smoothing usually continues until the camera position reaches the player position. + float player_stepheight = player->getCAO() ? player->getCAO()->getStepHeight() : HUGE_VALF; + float upward_movement = player_position.Y - old_player_position.Y; + if (upward_movement < 0.01f || upward_movement > player_stepheight) { + m_stepheight_smooth_active = false; + } else if (player->touching_ground) { + m_stepheight_smooth_active = true; + } + if (m_stepheight_smooth_active) { + f32 oldy = old_player_position.Y; + f32 newy = player_position.Y; + f32 t = std::exp(-23 * frametime); + player_position.Y = oldy * t + newy * (1-t); + } + + // Set player node transformation + m_playernode->setPosition(player_position); + m_playernode->setRotation(v3f(0, -1 * player->getYaw(), 0)); + m_playernode->updateAbsolutePosition(); + + // Get camera tilt timer (hurt animation) + float cameratilt = fabs(fabs(player->hurt_tilt_timer-0.75)-0.75); + + // Fall bobbing animation + float fall_bobbing = 0; + if(player->camera_impact >= 1 && m_camera_mode < CAMERA_MODE_THIRD) + { + if(m_view_bobbing_fall == -1) // Effect took place and has finished + player->camera_impact = m_view_bobbing_fall = 0; + else if(m_view_bobbing_fall == 0) // Initialize effect + m_view_bobbing_fall = 1; + + // Convert 0 -> 1 to 0 -> 1 -> 0 + fall_bobbing = m_view_bobbing_fall < 0.5 ? m_view_bobbing_fall * 2 : -(m_view_bobbing_fall - 0.5) * 2 + 1; + // Smoothen and invert the above + fall_bobbing = sin(fall_bobbing * 0.5 * M_PI) * -1; + // Amplify according to the intensity of the impact + if (player->camera_impact > 0.0f) + fall_bobbing *= (1 - rangelim(50 / player->camera_impact, 0, 1)) * 5; + + fall_bobbing *= m_cache_fall_bobbing_amount; + } + + // Calculate and translate the head SceneNode offsets + { + v3f eye_offset = player->getEyeOffset(); + if (m_camera_mode == CAMERA_MODE_FIRST) + eye_offset += player->eye_offset_first; + else + eye_offset += player->eye_offset_third; + + // Set head node transformation + eye_offset.Y += cameratilt * -player->hurt_tilt_strength + fall_bobbing; + m_headnode->setPosition(eye_offset); + m_headnode->setRotation(v3f(player->getPitch(), 0, + cameratilt * player->hurt_tilt_strength)); + m_headnode->updateAbsolutePosition(); + } + + // Compute relative camera position and target + v3f rel_cam_pos = v3f(0,0,0); + v3f rel_cam_target = v3f(0,0,1); + v3f rel_cam_up = v3f(0,1,0); + + if (m_cache_view_bobbing_amount != 0.0f && m_view_bobbing_anim != 0.0f && + m_camera_mode < CAMERA_MODE_THIRD) { + f32 bobfrac = my_modf(m_view_bobbing_anim * 2); + f32 bobdir = (m_view_bobbing_anim < 0.5) ? 1.0 : -1.0; + + f32 bobknob = 1.2; + f32 bobtmp = sin(pow(bobfrac, bobknob) * M_PI); + + v3f bobvec = v3f( + 0.3 * bobdir * sin(bobfrac * M_PI), + -0.28 * bobtmp * bobtmp, + 0.); + + rel_cam_pos += bobvec * m_cache_view_bobbing_amount; + rel_cam_target += bobvec * m_cache_view_bobbing_amount; + rel_cam_up.rotateXYBy(-0.03 * bobdir * bobtmp * M_PI * m_cache_view_bobbing_amount); + } + + // Compute absolute camera position and target + m_headnode->getAbsoluteTransformation().transformVect(m_camera_position, rel_cam_pos); + m_headnode->getAbsoluteTransformation().rotateVect(m_camera_direction, rel_cam_target - rel_cam_pos); + + v3f abs_cam_up; + m_headnode->getAbsoluteTransformation().rotateVect(abs_cam_up, rel_cam_up); + + // Seperate camera position for calculation + v3f my_cp = m_camera_position; + + // Reposition the camera for third person view + if (m_camera_mode > CAMERA_MODE_FIRST) + { + if (m_camera_mode == CAMERA_MODE_THIRD_FRONT) + m_camera_direction *= -1; + + my_cp.Y += 2; + + // Calculate new position + bool abort = false; + for (int i = BS; i <= BS * 2.75; i++) { + my_cp.X = m_camera_position.X + m_camera_direction.X * -i; + my_cp.Z = m_camera_position.Z + m_camera_direction.Z * -i; + if (i > 12) + my_cp.Y = m_camera_position.Y + (m_camera_direction.Y * -i); + + // Prevent camera positioned inside nodes + const NodeDefManager *nodemgr = m_client->ndef(); + MapNode n = m_client->getEnv().getClientMap() + .getNode(floatToInt(my_cp, BS)); + + const ContentFeatures& features = nodemgr->get(n); + if (features.walkable) { + my_cp.X += m_camera_direction.X*-1*-BS/2; + my_cp.Z += m_camera_direction.Z*-1*-BS/2; + my_cp.Y += m_camera_direction.Y*-1*-BS/2; + abort = true; + break; + } + } + + // If node blocks camera position don't move y to heigh + if (abort && my_cp.Y > player_position.Y+BS*2) + my_cp.Y = player_position.Y+BS*2; + } + + // Update offset if too far away from the center of the map + m_camera_offset.X += CAMERA_OFFSET_STEP* + (((s16)(my_cp.X/BS) - m_camera_offset.X)/CAMERA_OFFSET_STEP); + m_camera_offset.Y += CAMERA_OFFSET_STEP* + (((s16)(my_cp.Y/BS) - m_camera_offset.Y)/CAMERA_OFFSET_STEP); + m_camera_offset.Z += CAMERA_OFFSET_STEP* + (((s16)(my_cp.Z/BS) - m_camera_offset.Z)/CAMERA_OFFSET_STEP); + + // Set camera node transformation + m_cameranode->setPosition(my_cp-intToFloat(m_camera_offset, BS)); + m_cameranode->setUpVector(abs_cam_up); + // *100.0 helps in large map coordinates + m_cameranode->setTarget(my_cp-intToFloat(m_camera_offset, BS) + 100 * m_camera_direction); + + // update the camera position in third-person mode to render blocks behind player + // and correctly apply liquid post FX. + if (m_camera_mode != CAMERA_MODE_FIRST) + m_camera_position = my_cp; + + /* + * Apply server-sent FOV, instantaneous or smooth transition. + * If not, check for zoom and set to zoom FOV. + * Otherwise, default to m_cache_fov. + */ + if (m_fov_transition_active) { + // Smooth FOV transition + // Dynamically calculate FOV delta based on frametimes + f32 delta = (frametime / m_transition_time) * m_fov_diff; + m_curr_fov_degrees += delta; + + // Mark transition as complete if target FOV has been reached + if ((m_fov_diff > 0.0f && m_curr_fov_degrees >= m_target_fov_degrees) || + (m_fov_diff < 0.0f && m_curr_fov_degrees <= m_target_fov_degrees)) { + m_fov_transition_active = false; + m_curr_fov_degrees = m_target_fov_degrees; + } + } else if (m_server_sent_fov) { + // Instantaneous FOV change + m_curr_fov_degrees = m_target_fov_degrees; + } else if (player->getPlayerControl().zoom && player->getZoomFOV() > 0.001f) { + // Player requests zoom, apply zoom FOV + m_curr_fov_degrees = player->getZoomFOV(); + } else { + // Set to client's selected FOV + m_curr_fov_degrees = m_cache_fov; + } + m_curr_fov_degrees = rangelim(m_curr_fov_degrees, 1.0f, 160.0f); + + // FOV and aspect ratio + const v2u32 &window_size = RenderingEngine::getWindowSize(); + m_aspect = (f32) window_size.X / (f32) window_size.Y; + m_fov_y = m_curr_fov_degrees * M_PI / 180.0; + // Increase vertical FOV on lower aspect ratios (<16:10) + m_fov_y *= core::clamp(sqrt(16./10. / m_aspect), 1.0, 1.4); + m_fov_x = 2 * atan(m_aspect * tan(0.5 * m_fov_y)); + m_cameranode->setAspectRatio(m_aspect); + m_cameranode->setFOV(m_fov_y); + + if (m_arm_inertia) + addArmInertia(player->getYaw()); + + // Position the wielded item + //v3f wield_position = v3f(45, -35, 65); + v3f wield_position = v3f(m_wieldmesh_offset.X, m_wieldmesh_offset.Y, 65); + //v3f wield_rotation = v3f(-100, 120, -100); + v3f wield_rotation = v3f(-100, 120, -100); + wield_position.Y += fabs(m_wield_change_timer)*320 - 40; + if(m_digging_anim < 0.05 || m_digging_anim > 0.5) + { + f32 frac = 1.0; + if(m_digging_anim > 0.5) + frac = 2.0 * (m_digging_anim - 0.5); + // This value starts from 1 and settles to 0 + f32 ratiothing = std::pow((1.0f - tool_reload_ratio), 0.5f); + //f32 ratiothing2 = pow(ratiothing, 0.5f); + f32 ratiothing2 = (easeCurve(ratiothing*0.5))*2.0; + wield_position.Y -= frac * 25.0 * pow(ratiothing2, 1.7f); + //wield_position.Z += frac * 5.0 * ratiothing2; + wield_position.X -= frac * 35.0 * pow(ratiothing2, 1.1f); + wield_rotation.Y += frac * 70.0 * pow(ratiothing2, 1.4f); + //wield_rotation.X -= frac * 15.0 * pow(ratiothing2, 1.4f); + //wield_rotation.Z += frac * 15.0 * pow(ratiothing2, 1.0f); + } + if (m_digging_button != -1) + { + f32 digfrac = m_digging_anim; + wield_position.X -= 50 * sin(pow(digfrac, 0.8f) * M_PI); + wield_position.Y += 24 * sin(digfrac * 1.8 * M_PI); + wield_position.Z += 25 * 0.5; + + // Euler angles are PURE EVIL, so why not use quaternions? + core::quaternion quat_begin(wield_rotation * core::DEGTORAD); + core::quaternion quat_end(v3f(80, 30, 100) * core::DEGTORAD); + core::quaternion quat_slerp; + quat_slerp.slerp(quat_begin, quat_end, sin(digfrac * M_PI)); + quat_slerp.toEuler(wield_rotation); + wield_rotation *= core::RADTODEG; + } else { + f32 bobfrac = my_modf(m_view_bobbing_anim); + wield_position.X -= sin(bobfrac*M_PI*2.0) * 3.0; + wield_position.Y += sin(my_modf(bobfrac*2.0)*M_PI) * 3.0; + } + m_wieldnode->setPosition(wield_position); + m_wieldnode->setRotation(wield_rotation); + + m_player_light_color = player->light_color; + m_wieldnode->setNodeLightColor(m_player_light_color); + + // Set render distance + updateViewingRange(); + + // If the player is walking, swimming, or climbing, + // view bobbing is enabled and free_move is off, + // start (or continue) the view bobbing animation. + const v3f &speed = player->getSpeed(); + const bool movement_XZ = hypot(speed.X, speed.Z) > BS; + const bool movement_Y = fabs(speed.Y) > BS; + + const bool walking = movement_XZ && player->touching_ground; + const bool swimming = (movement_XZ || player->swimming_vertical) && player->in_liquid; + const bool climbing = movement_Y && player->is_climbing; + const bool flying = g_settings->getBool("free_move") + && m_client->checkLocalPrivilege("fly"); + if ((walking || swimming || climbing) && !flying) { + // Start animation + m_view_bobbing_state = 1; + m_view_bobbing_speed = MYMIN(speed.getLength(), 70); + } else if (m_view_bobbing_state == 1) { + // Stop animation + m_view_bobbing_state = 2; + m_view_bobbing_speed = 60; + } +} + +void Camera::updateViewingRange() +{ + f32 viewing_range = g_settings->getFloat("viewing_range"); + + // Ignore near_plane setting on all other platforms to prevent abuse +#if ENABLE_GLES + m_cameranode->setNearValue(rangelim( + g_settings->getFloat("near_plane"), 0.0f, 0.25f) * BS); +#else + m_cameranode->setNearValue(0.1f * BS); +#endif + + m_draw_control.wanted_range = std::fmin(adjustDist(viewing_range, getFovMax()), 4000); + if (m_draw_control.range_all) { + m_cameranode->setFarValue(100000.0); + return; + } + m_cameranode->setFarValue((viewing_range < 2000) ? 2000 * BS : viewing_range * BS); +} + +void Camera::setDigging(s32 button) +{ + if (m_digging_button == -1) + m_digging_button = button; +} + +void Camera::wield(const ItemStack &item) +{ + if (item.name != m_wield_item_next.name || + item.metadata != m_wield_item_next.metadata) { + m_wield_item_next = item; + if (m_wield_change_timer > 0) + m_wield_change_timer = -m_wield_change_timer; + else if (m_wield_change_timer == 0) + m_wield_change_timer = -0.001; + } +} + +void Camera::drawWieldedTool(irr::core::matrix4* translation) +{ + // Clear Z buffer so that the wielded tool stays in front of world geometry + m_wieldmgr->getVideoDriver()->clearBuffers(video::ECBF_DEPTH); + + // Draw the wielded node (in a separate scene manager) + scene::ICameraSceneNode* cam = m_wieldmgr->getActiveCamera(); + cam->setAspectRatio(m_cameranode->getAspectRatio()); + cam->setFOV(72.0*M_PI/180.0); + cam->setNearValue(10); + cam->setFarValue(1000); + if (translation != NULL) + { + irr::core::matrix4 startMatrix = cam->getAbsoluteTransformation(); + irr::core::vector3df focusPoint = (cam->getTarget() + - cam->getAbsolutePosition()).setLength(1) + + cam->getAbsolutePosition(); + + irr::core::vector3df camera_pos = + (startMatrix * *translation).getTranslation(); + cam->setPosition(camera_pos); + cam->setTarget(focusPoint); + } + m_wieldmgr->drawAll(); +} + +void Camera::drawNametags() +{ + core::matrix4 trans = m_cameranode->getProjectionMatrix(); + trans *= m_cameranode->getViewMatrix(); + + gui::IGUIFont *font = g_fontengine->getFont(); + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + v2u32 screensize = driver->getScreenSize(); + + for (const Nametag *nametag : m_nametags) { + // Nametags are hidden in GenericCAO::updateNametag() + + v3f pos = nametag->parent_node->getAbsolutePosition() + nametag->pos * BS; + f32 transformed_pos[4] = { pos.X, pos.Y, pos.Z, 1.0f }; + trans.multiplyWith1x4Matrix(transformed_pos); + if (transformed_pos[3] > 0) { + std::wstring nametag_colorless = + unescape_translate(utf8_to_wide(nametag->text)); + core::dimension2d<u32> textsize = font->getDimension( + nametag_colorless.c_str()); + f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f : + core::reciprocal(transformed_pos[3]); + v2s32 screen_pos; + screen_pos.X = screensize.X * + (0.5 * transformed_pos[0] * zDiv + 0.5) - textsize.Width / 2; + screen_pos.Y = screensize.Y * + (0.5 - transformed_pos[1] * zDiv * 0.5) - textsize.Height / 2; + core::rect<s32> size(0, 0, textsize.Width, textsize.Height); + core::rect<s32> bg_size(-2, 0, textsize.Width+2, textsize.Height); + + auto bgcolor = nametag->getBgColor(m_show_nametag_backgrounds); + if (bgcolor.getAlpha() != 0) + driver->draw2DRectangle(bgcolor, bg_size + screen_pos); + + font->draw( + translate_string(utf8_to_wide(nametag->text)).c_str(), + size + screen_pos, nametag->textcolor); + } + } +} + +Nametag *Camera::addNametag(scene::ISceneNode *parent_node, + const std::string &text, video::SColor textcolor, + Optional<video::SColor> bgcolor, const v3f &pos) +{ + Nametag *nametag = new Nametag(parent_node, text, textcolor, bgcolor, pos); + m_nametags.push_back(nametag); + return nametag; +} + +void Camera::removeNametag(Nametag *nametag) +{ + m_nametags.remove(nametag); + delete nametag; +} diff --git a/src/client/camera.h b/src/client/camera.h new file mode 100644 index 0000000..cbf248d --- /dev/null +++ b/src/client/camera.h @@ -0,0 +1,270 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "inventory.h" +#include "client/tile.h" +#include <ICameraSceneNode.h> +#include <ISceneNode.h> +#include <list> +#include "util/Optional.h" + +class LocalPlayer; +struct MapDrawControl; +class Client; +class RenderingEngine; +class WieldMeshSceneNode; + +struct Nametag +{ + scene::ISceneNode *parent_node; + std::string text; + video::SColor textcolor; + Optional<video::SColor> bgcolor; + v3f pos; + + Nametag(scene::ISceneNode *a_parent_node, + const std::string &text, + const video::SColor &textcolor, + const Optional<video::SColor> &bgcolor, + const v3f &pos): + parent_node(a_parent_node), + text(text), + textcolor(textcolor), + bgcolor(bgcolor), + pos(pos) + { + } + + video::SColor getBgColor(bool use_fallback) const + { + if (bgcolor) + return bgcolor.value(); + else if (!use_fallback) + return video::SColor(0, 0, 0, 0); + else if (textcolor.getLuminance() > 186) + // Dark background for light text + return video::SColor(50, 50, 50, 50); + else + // Light background for dark text + return video::SColor(50, 255, 255, 255); + } +}; + +enum CameraMode {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT}; + +/* + Client camera class, manages the player and camera scene nodes, the viewing distance + and performs view bobbing etc. It also displays the wielded tool in front of the + first-person camera. +*/ +class Camera +{ +public: + Camera(MapDrawControl &draw_control, Client *client, RenderingEngine *rendering_engine); + ~Camera(); + + // Get camera scene node. + // It has the eye transformation, pitch and view bobbing applied. + inline scene::ICameraSceneNode* getCameraNode() const + { + return m_cameranode; + } + + // Get the camera position (in absolute scene coordinates). + // This has view bobbing applied. + inline v3f getPosition() const + { + return m_camera_position; + } + + // Returns the absolute position of the head SceneNode in the world + inline v3f getHeadPosition() const + { + return m_headnode->getAbsolutePosition(); + } + + // Get the camera direction (in absolute camera coordinates). + // This has view bobbing applied. + inline v3f getDirection() const + { + return m_camera_direction; + } + + // Get the camera offset + inline v3s16 getOffset() const + { + return m_camera_offset; + } + + // Horizontal field of view + inline f32 getFovX() const + { + return m_fov_x; + } + + // Vertical field of view + inline f32 getFovY() const + { + return m_fov_y; + } + + // Get maximum of getFovX() and getFovY() + inline f32 getFovMax() const + { + return MYMAX(m_fov_x, m_fov_y); + } + + // Notify about new server-sent FOV and initialize smooth FOV transition + void notifyFovChange(); + + // Step the camera: updates the viewing range and view bobbing. + void step(f32 dtime); + + // Update the camera from the local player's position. + void update(LocalPlayer* player, f32 frametime, f32 tool_reload_ratio); + + // Update render distance + void updateViewingRange(); + + // Start digging animation + // Pass 0 for left click, 1 for right click + void setDigging(s32 button); + + // Replace the wielded item mesh + void wield(const ItemStack &item); + + // Draw the wielded tool. + // This has to happen *after* the main scene is drawn. + // Warning: This clears the Z buffer. + void drawWieldedTool(irr::core::matrix4* translation=NULL); + + // Toggle the current camera mode + void toggleCameraMode() { + if (m_camera_mode == CAMERA_MODE_FIRST) + m_camera_mode = CAMERA_MODE_THIRD; + else if (m_camera_mode == CAMERA_MODE_THIRD) + m_camera_mode = CAMERA_MODE_THIRD_FRONT; + else + m_camera_mode = CAMERA_MODE_FIRST; + } + + // Set the current camera mode + inline void setCameraMode(CameraMode mode) + { + m_camera_mode = mode; + } + + //read the current camera mode + inline CameraMode getCameraMode() + { + return m_camera_mode; + } + + Nametag *addNametag(scene::ISceneNode *parent_node, + const std::string &text, video::SColor textcolor, + Optional<video::SColor> bgcolor, const v3f &pos); + + void removeNametag(Nametag *nametag); + + void drawNametags(); + + inline void addArmInertia(f32 player_yaw); + +private: + // Nodes + scene::ISceneNode *m_playernode = nullptr; + scene::ISceneNode *m_headnode = nullptr; + scene::ICameraSceneNode *m_cameranode = nullptr; + + scene::ISceneManager *m_wieldmgr = nullptr; + WieldMeshSceneNode *m_wieldnode = nullptr; + + // draw control + MapDrawControl& m_draw_control; + + Client *m_client; + + // Default Client FOV (as defined by the "fov" setting) + f32 m_cache_fov; + + // Absolute camera position + v3f m_camera_position; + // Absolute camera direction + v3f m_camera_direction; + // Camera offset + v3s16 m_camera_offset; + + bool m_stepheight_smooth_active = false; + + // Server-sent FOV variables + bool m_server_sent_fov = false; + f32 m_curr_fov_degrees, m_old_fov_degrees, m_target_fov_degrees; + + // FOV transition variables + bool m_fov_transition_active = false; + f32 m_fov_diff, m_transition_time; + + v2f m_wieldmesh_offset = v2f(55.0f, -35.0f); + v2f m_arm_dir; + v2f m_cam_vel; + v2f m_cam_vel_old; + v2f m_last_cam_pos; + + // Field of view and aspect ratio stuff + f32 m_aspect = 1.0f; + f32 m_fov_x = 1.0f; + f32 m_fov_y = 1.0f; + + // View bobbing animation frame (0 <= m_view_bobbing_anim < 1) + f32 m_view_bobbing_anim = 0.0f; + // If 0, view bobbing is off (e.g. player is standing). + // If 1, view bobbing is on (player is walking). + // If 2, view bobbing is getting switched off. + s32 m_view_bobbing_state = 0; + // Speed of view bobbing animation + f32 m_view_bobbing_speed = 0.0f; + // Fall view bobbing + f32 m_view_bobbing_fall = 0.0f; + + // Digging animation frame (0 <= m_digging_anim < 1) + f32 m_digging_anim = 0.0f; + // If -1, no digging animation + // If 0, left-click digging animation + // If 1, right-click digging animation + s32 m_digging_button = -1; + + // Animation when changing wielded item + f32 m_wield_change_timer = 0.125f; + ItemStack m_wield_item_next; + + CameraMode m_camera_mode = CAMERA_MODE_FIRST; + + f32 m_cache_fall_bobbing_amount; + f32 m_cache_view_bobbing_amount; + bool m_arm_inertia; + + std::list<Nametag *> m_nametags; + bool m_show_nametag_backgrounds; + + // Last known light color of the player + video::SColor m_player_light_color; +}; diff --git a/src/client/client.cpp b/src/client/client.cpp new file mode 100644 index 0000000..b7d1cbf --- /dev/null +++ b/src/client/client.cpp @@ -0,0 +1,2065 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <iostream> +#include <algorithm> +#include <sstream> +#include <cmath> +#include <IFileSystem.h> +#include "client.h" +#include "network/clientopcodes.h" +#include "network/connection.h" +#include "network/networkpacket.h" +#include "threading/mutex_auto_lock.h" +#include "client/clientevent.h" +#include "client/gameui.h" +#include "client/renderingengine.h" +#include "client/sound.h" +#include "client/tile.h" +#include "util/auth.h" +#include "util/directiontables.h" +#include "util/pointedthing.h" +#include "util/serialize.h" +#include "util/string.h" +#include "util/srp.h" +#include "filesys.h" +#include "mapblock_mesh.h" +#include "mapblock.h" +#include "minimap.h" +#include "modchannels.h" +#include "content/mods.h" +#include "profiler.h" +#include "shader.h" +#include "gettext.h" +#include "clientmap.h" +#include "clientmedia.h" +#include "version.h" +#include "database/database-files.h" +#include "database/database-sqlite3.h" +#include "serialization.h" +#include "guiscalingfilter.h" +#include "script/scripting_client.h" +#include "game.h" +#include "chatmessage.h" +#include "translation.h" +#include "content/mod_configuration.h" + +extern gui::IGUIEnvironment* guienv; + +/* + Utility classes +*/ + +u32 PacketCounter::sum() const +{ + u32 n = 0; + for (const auto &it : m_packets) + n += it.second; + return n; +} + +void PacketCounter::print(std::ostream &o) const +{ + for (const auto &it : m_packets) { + auto name = it.first >= TOCLIENT_NUM_MSG_TYPES ? "?" + : toClientCommandTable[it.first].name; + o << "cmd " << it.first << " (" << name << ") count " + << it.second << std::endl; + } +} + +/* + Client +*/ + +Client::Client( + const char *playername, + const std::string &password, + const std::string &address_name, + MapDrawControl &control, + IWritableTextureSource *tsrc, + IWritableShaderSource *shsrc, + IWritableItemDefManager *itemdef, + NodeDefManager *nodedef, + ISoundManager *sound, + MtEventManager *event, + RenderingEngine *rendering_engine, + bool ipv6, + GameUI *game_ui, + ELoginRegister allow_login_or_register +): + m_tsrc(tsrc), + m_shsrc(shsrc), + m_itemdef(itemdef), + m_nodedef(nodedef), + m_sound(sound), + m_event(event), + m_rendering_engine(rendering_engine), + m_mesh_update_thread(this), + m_env( + new ClientMap(this, rendering_engine, control, 666), + tsrc, this + ), + m_particle_manager(&m_env), + m_con(new con::Connection(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, ipv6, this)), + m_address_name(address_name), + m_allow_login_or_register(allow_login_or_register), + m_server_ser_ver(SER_FMT_VER_INVALID), + m_last_chat_message_sent(time(NULL)), + m_password(password), + m_chosen_auth_mech(AUTH_MECHANISM_NONE), + m_media_downloader(new ClientMediaDownloader()), + m_state(LC_Created), + m_game_ui(game_ui), + m_modchannel_mgr(new ModChannelMgr()) +{ + // Add local player + m_env.setLocalPlayer(new LocalPlayer(this, playername)); + + // Make the mod storage database and begin the save for later + m_mod_storage_database = + new ModMetadataDatabaseSQLite3(porting::path_user + DIR_DELIM + "client"); + m_mod_storage_database->beginSave(); + + if (g_settings->getBool("enable_minimap")) { + m_minimap = new Minimap(this); + } + + m_cache_save_interval = g_settings->getU16("server_map_save_interval"); +} + +void Client::migrateModStorage() +{ + std::string mod_storage_dir = porting::path_user + DIR_DELIM + "client"; + std::string old_mod_storage = mod_storage_dir + DIR_DELIM + "mod_storage"; + if (fs::IsDir(old_mod_storage)) { + infostream << "Migrating client mod storage to SQLite3 database" << std::endl; + { + ModMetadataDatabaseFiles files_db(mod_storage_dir); + std::vector<std::string> mod_list; + files_db.listMods(&mod_list); + for (const std::string &modname : mod_list) { + infostream << "Migrating client mod storage for mod " << modname << std::endl; + StringMap meta; + files_db.getModEntries(modname, &meta); + for (const auto &pair : meta) { + m_mod_storage_database->setModEntry(modname, pair.first, pair.second); + } + } + } + if (!fs::Rename(old_mod_storage, old_mod_storage + ".bak")) { + // Execution cannot move forward if the migration does not complete. + throw BaseException("Could not finish migrating client mod storage"); + } + infostream << "Finished migration of client mod storage" << std::endl; + } +} + +void Client::loadMods() +{ + // Don't load mods twice. + // If client scripting is disabled by the client, don't load builtin or + // client-provided mods. + if (m_mods_loaded || !g_settings->getBool("enable_client_modding")) + return; + + // If client scripting is disabled by the server, don't load builtin or + // client-provided mods. + // TODO Delete this code block when server-sent CSM and verifying of builtin are + // complete. + if (checkCSMRestrictionFlag(CSMRestrictionFlags::CSM_RF_LOAD_CLIENT_MODS)) { + warningstream << "Client-provided mod loading is disabled by server." << + std::endl; + return; + } + + m_script = new ClientScripting(this); + m_env.setScript(m_script); + m_script->setEnv(&m_env); + + // Load builtin + scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath()); + m_script->loadModFromMemory(BUILTIN_MOD_NAME); + + ModConfiguration modconf; + { + std::unordered_map<std::string, std::string> paths; + std::string path_user = porting::path_user + DIR_DELIM + "clientmods"; + const auto modsPath = getClientModsLuaPath(); + if (modsPath != path_user) { + paths["share"] = modsPath; + } + paths["mods"] = path_user; + + std::string settings_path = path_user + DIR_DELIM + "mods.conf"; + modconf.addModsFromConfig(settings_path, paths); + modconf.checkConflictsAndDeps(); + } + + m_mods = modconf.getMods(); + // complain about mods with unsatisfied dependencies + if (!modconf.isConsistent()) { + modconf.printUnsatisfiedModsError(); + return; + } + + // Print mods + infostream << "Client loading mods: "; + for (const ModSpec &mod : m_mods) + infostream << mod.name << " "; + infostream << std::endl; + + // Load "mod" scripts + for (const ModSpec &mod : m_mods) { + mod.checkAndLog(); + scanModIntoMemory(mod.name, mod.path); + } + + // Run them + for (const ModSpec &mod : m_mods) + m_script->loadModFromMemory(mod.name); + + // Mods are done loading. Unlock callbacks + m_mods_loaded = true; + + // Run a callback when mods are loaded + m_script->on_mods_loaded(); + + // Create objects if they're ready + if (m_state == LC_Ready) + m_script->on_client_ready(m_env.getLocalPlayer()); + if (m_camera) + m_script->on_camera_ready(m_camera); + if (m_minimap) + m_script->on_minimap_ready(m_minimap); +} + +void Client::scanModSubfolder(const std::string &mod_name, const std::string &mod_path, + std::string mod_subpath) +{ + std::string full_path = mod_path + DIR_DELIM + mod_subpath; + std::vector<fs::DirListNode> mod = fs::GetDirListing(full_path); + for (const fs::DirListNode &j : mod) { + if (j.name[0] == '.') + continue; + + if (j.dir) { + scanModSubfolder(mod_name, mod_path, mod_subpath + j.name + DIR_DELIM); + continue; + } + std::replace(mod_subpath.begin(), mod_subpath.end(), DIR_DELIM_CHAR, '/'); + + std::string real_path = full_path + j.name; + std::string vfs_path = mod_name + ":" + mod_subpath + j.name; + infostream << "Client::scanModSubfolder(): Loading \"" << real_path + << "\" as \"" << vfs_path << "\"." << std::endl; + + std::string contents; + if (!fs::ReadFile(real_path, contents)) { + errorstream << "Client::scanModSubfolder(): Can't read file \"" + << real_path << "\"." << std::endl; + continue; + } + + m_mod_vfs.emplace(vfs_path, contents); + } +} + +const std::string &Client::getBuiltinLuaPath() +{ + static const std::string builtin_dir = porting::path_share + DIR_DELIM + "builtin"; + return builtin_dir; +} + +const std::string &Client::getClientModsLuaPath() +{ + static const std::string clientmods_dir = porting::path_share + DIR_DELIM + "clientmods"; + return clientmods_dir; +} + +const std::vector<ModSpec>& Client::getMods() const +{ + static std::vector<ModSpec> client_modspec_temp; + return client_modspec_temp; +} + +const ModSpec* Client::getModSpec(const std::string &modname) const +{ + return NULL; +} + +void Client::Stop() +{ + m_shutdown = true; + if (m_mods_loaded) + m_script->on_shutdown(); + //request all client managed threads to stop + m_mesh_update_thread.stop(); + // Save local server map + if (m_localdb) { + infostream << "Local map saving ended." << std::endl; + m_localdb->endSave(); + } + + if (m_mods_loaded) + delete m_script; +} + +bool Client::isShutdown() +{ + return m_shutdown || !m_mesh_update_thread.isRunning(); +} + +Client::~Client() +{ + m_shutdown = true; + m_con->Disconnect(); + + deleteAuthData(); + + m_mesh_update_thread.stop(); + m_mesh_update_thread.wait(); + while (!m_mesh_update_thread.m_queue_out.empty()) { + MeshUpdateResult r = m_mesh_update_thread.m_queue_out.pop_frontNoEx(); + delete r.mesh; + } + + + delete m_inventory_from_server; + + // Delete detached inventories + for (auto &m_detached_inventorie : m_detached_inventories) { + delete m_detached_inventorie.second; + } + + // cleanup 3d model meshes on client shutdown + m_rendering_engine->cleanupMeshCache(); + + guiScalingCacheClear(); + + delete m_minimap; + m_minimap = nullptr; + + delete m_media_downloader; + + // Write the changes and delete + if (m_mod_storage_database) + m_mod_storage_database->endSave(); + delete m_mod_storage_database; +} + +void Client::connect(Address address, bool is_local_server) +{ + initLocalMapSaving(address, m_address_name, is_local_server); + + // Since we use TryReceive() a timeout here would be ineffective anyway + m_con->SetTimeoutMs(0); + m_con->Connect(address); +} + +void Client::step(float dtime) +{ + // Limit a bit + if (dtime > 2.0) + dtime = 2.0; + + m_animation_time += dtime; + if(m_animation_time > 60.0) + m_animation_time -= 60.0; + + m_time_of_day_update_timer += dtime; + + ReceiveAll(); + + /* + Packet counter + */ + { + float &counter = m_packetcounter_timer; + counter -= dtime; + if(counter <= 0.0f) + { + counter = 30.0f; + u32 sum = m_packetcounter.sum(); + float avg = sum / counter; + + infostream << "Client packetcounter (" << counter << "s): " + << "sum=" << sum << " avg=" << avg << "/s" << std::endl; + m_packetcounter.print(infostream); + m_packetcounter.clear(); + } + } + + // UGLY hack to fix 2 second startup delay caused by non existent + // server client startup synchronization in local server or singleplayer mode + static bool initial_step = true; + if (initial_step) { + initial_step = false; + } + else if(m_state == LC_Created) { + float &counter = m_connection_reinit_timer; + counter -= dtime; + if(counter <= 0.0) { + counter = 2.0; + + LocalPlayer *myplayer = m_env.getLocalPlayer(); + FATAL_ERROR_IF(myplayer == NULL, "Local player not found in environment."); + + sendInit(myplayer->getName()); + } + + // Not connected, return + return; + } + + /* + Do stuff if connected + */ + + /* + Run Map's timers and unload unused data + */ + const float map_timer_and_unload_dtime = 5.25; + if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) { + std::vector<v3s16> deleted_blocks; + m_env.getMap().timerUpdate(map_timer_and_unload_dtime, + std::max(g_settings->getFloat("client_unload_unused_data_timeout"), 0.0f), + g_settings->getS32("client_mapblock_limit"), + &deleted_blocks); + + /* + Send info to server + NOTE: This loop is intentionally iterated the way it is. + */ + + std::vector<v3s16>::iterator i = deleted_blocks.begin(); + std::vector<v3s16> sendlist; + for(;;) { + if(sendlist.size() == 255 || i == deleted_blocks.end()) { + if(sendlist.empty()) + break; + /* + [0] u16 command + [2] u8 count + [3] v3s16 pos_0 + [3+6] v3s16 pos_1 + ... + */ + + sendDeletedBlocks(sendlist); + + if(i == deleted_blocks.end()) + break; + + sendlist.clear(); + } + + sendlist.push_back(*i); + ++i; + } + } + + /* + Send pending messages on out chat queue + */ + if (!m_out_chat_queue.empty() && canSendChatMessage()) { + sendChatMessage(m_out_chat_queue.front()); + m_out_chat_queue.pop(); + } + + /* + Handle environment + */ + LocalPlayer *player = m_env.getLocalPlayer(); + + // Step environment (also handles player controls) + m_env.step(dtime); + m_sound->step(dtime); + + /* + Get events + */ + while (m_env.hasClientEnvEvents()) { + ClientEnvEvent envEvent = m_env.getClientEnvEvent(); + + if (envEvent.type == CEE_PLAYER_DAMAGE) { + u16 damage = envEvent.player_damage.amount; + + if (envEvent.player_damage.send_to_server) + sendDamage(damage); + + // Add to ClientEvent queue + ClientEvent *event = new ClientEvent(); + event->type = CE_PLAYER_DAMAGE; + event->player_damage.amount = damage; + event->player_damage.effect = true; + m_client_event_queue.push(event); + } + } + + /* + Print some info + */ + float &counter = m_avg_rtt_timer; + counter += dtime; + if(counter >= 10) { + counter = 0.0; + // connectedAndInitialized() is true, peer exists. + float avg_rtt = getRTT(); + infostream << "Client: avg_rtt=" << avg_rtt << std::endl; + } + + /* + Send player position to server + */ + { + float &counter = m_playerpos_send_timer; + counter += dtime; + if((m_state == LC_Ready) && (counter >= m_recommended_send_interval)) + { + counter = 0.0; + sendPlayerPos(); + } + } + + /* + Replace updated meshes + */ + { + int num_processed_meshes = 0; + std::vector<v3s16> blocks_to_ack; + bool force_update_shadows = false; + while (!m_mesh_update_thread.m_queue_out.empty()) + { + num_processed_meshes++; + + MinimapMapblock *minimap_mapblock = NULL; + bool do_mapper_update = true; + + MeshUpdateResult r = m_mesh_update_thread.m_queue_out.pop_frontNoEx(); + MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(r.p); + if (block) { + // Delete the old mesh + delete block->mesh; + block->mesh = nullptr; + + if (r.mesh) { + minimap_mapblock = r.mesh->moveMinimapMapblock(); + if (minimap_mapblock == NULL) + do_mapper_update = false; + + bool is_empty = true; + for (int l = 0; l < MAX_TILE_LAYERS; l++) + if (r.mesh->getMesh(l)->getMeshBufferCount() != 0) + is_empty = false; + + if (is_empty) + delete r.mesh; + else { + // Replace with the new mesh + block->mesh = r.mesh; + if (r.urgent) + force_update_shadows = true; + } + } + } else { + delete r.mesh; + } + + if (m_minimap && do_mapper_update) + m_minimap->addBlock(r.p, minimap_mapblock); + + if (r.ack_block_to_server) { + if (blocks_to_ack.size() == 255) { + sendGotBlocks(blocks_to_ack); + blocks_to_ack.clear(); + } + + blocks_to_ack.emplace_back(r.p); + } + } + if (blocks_to_ack.size() > 0) { + // Acknowledge block(s) + sendGotBlocks(blocks_to_ack); + } + + if (num_processed_meshes > 0) + g_profiler->graphAdd("num_processed_meshes", num_processed_meshes); + + auto shadow_renderer = RenderingEngine::get_shadow_renderer(); + if (shadow_renderer && force_update_shadows) + shadow_renderer->setForceUpdateShadowMap(); + } + + /* + Load fetched media + */ + if (m_media_downloader && m_media_downloader->isStarted()) { + m_media_downloader->step(this); + if (m_media_downloader->isDone()) { + delete m_media_downloader; + m_media_downloader = NULL; + } + } + { + // Acknowledge dynamic media downloads to server + std::vector<u32> done; + for (auto it = m_pending_media_downloads.begin(); + it != m_pending_media_downloads.end();) { + assert(it->second->isStarted()); + it->second->step(this); + if (it->second->isDone()) { + done.emplace_back(it->first); + + it = m_pending_media_downloads.erase(it); + } else { + it++; + } + + if (done.size() == 255) { // maximum in one packet + sendHaveMedia(done); + done.clear(); + } + } + if (!done.empty()) + sendHaveMedia(done); + } + + /* + If the server didn't update the inventory in a while, revert + the local inventory (so the player notices the lag problem + and knows something is wrong). + */ + if (m_inventory_from_server) { + float interval = 10.0f; + float count_before = std::floor(m_inventory_from_server_age / interval); + + m_inventory_from_server_age += dtime; + + float count_after = std::floor(m_inventory_from_server_age / interval); + + if (count_after != count_before) { + // Do this every <interval> seconds after TOCLIENT_INVENTORY + // Reset the locally changed inventory to the authoritative inventory + player->inventory = *m_inventory_from_server; + m_update_wielded_item = true; + } + } + + /* + Update positions of sounds attached to objects + */ + { + for (auto &m_sounds_to_object : m_sounds_to_objects) { + int client_id = m_sounds_to_object.first; + u16 object_id = m_sounds_to_object.second; + ClientActiveObject *cao = m_env.getActiveObject(object_id); + if (!cao) + continue; + m_sound->updateSoundPosition(client_id, cao->getPosition()); + } + } + + /* + Handle removed remotely initiated sounds + */ + m_removed_sounds_check_timer += dtime; + if(m_removed_sounds_check_timer >= 2.32) { + m_removed_sounds_check_timer = 0; + // Find removed sounds and clear references to them + std::vector<s32> removed_server_ids; + for (std::unordered_map<s32, int>::iterator i = m_sounds_server_to_client.begin(); + i != m_sounds_server_to_client.end();) { + s32 server_id = i->first; + int client_id = i->second; + ++i; + if(!m_sound->soundExists(client_id)) { + m_sounds_server_to_client.erase(server_id); + m_sounds_client_to_server.erase(client_id); + m_sounds_to_objects.erase(client_id); + removed_server_ids.push_back(server_id); + } + } + + // Sync to server + if(!removed_server_ids.empty()) { + sendRemovedSounds(removed_server_ids); + } + } + + // Write changes to the mod storage + m_mod_storage_save_timer -= dtime; + if (m_mod_storage_save_timer <= 0.0f) { + m_mod_storage_save_timer = g_settings->getFloat("server_map_save_interval"); + m_mod_storage_database->endSave(); + m_mod_storage_database->beginSave(); + } + + // Write server map + if (m_localdb && m_localdb_save_interval.step(dtime, + m_cache_save_interval)) { + m_localdb->endSave(); + m_localdb->beginSave(); + } +} + +bool Client::loadMedia(const std::string &data, const std::string &filename, + bool from_media_push) +{ + std::string name; + + const char *image_ext[] = { + ".png", ".jpg", ".bmp", ".tga", + ".pcx", ".ppm", ".psd", ".wal", ".rgb", + NULL + }; + name = removeStringEnd(filename, image_ext); + if (!name.empty()) { + TRACESTREAM(<< "Client: Attempting to load image " + << "file \"" << filename << "\"" << std::endl); + + io::IFileSystem *irrfs = m_rendering_engine->get_filesystem(); + video::IVideoDriver *vdrv = m_rendering_engine->get_video_driver(); + + io::IReadFile *rfile = irrfs->createMemoryReadFile( + data.c_str(), data.size(), "_tempreadfile"); + + FATAL_ERROR_IF(!rfile, "Could not create irrlicht memory file."); + + // Read image + video::IImage *img = vdrv->createImageFromFile(rfile); + if (!img) { + errorstream<<"Client: Cannot create image from data of " + <<"file \""<<filename<<"\""<<std::endl; + rfile->drop(); + return false; + } + + m_tsrc->insertSourceImage(filename, img); + img->drop(); + rfile->drop(); + return true; + } + + const char *sound_ext[] = { + ".0.ogg", ".1.ogg", ".2.ogg", ".3.ogg", ".4.ogg", + ".5.ogg", ".6.ogg", ".7.ogg", ".8.ogg", ".9.ogg", + ".ogg", NULL + }; + name = removeStringEnd(filename, sound_ext); + if (!name.empty()) { + TRACESTREAM(<< "Client: Attempting to load sound " + << "file \"" << filename << "\"" << std::endl); + return m_sound->loadSoundData(name, data); + } + + const char *model_ext[] = { + ".x", ".b3d", ".md2", ".obj", + NULL + }; + name = removeStringEnd(filename, model_ext); + if (!name.empty()) { + verbosestream<<"Client: Storing model into memory: " + <<"\""<<filename<<"\""<<std::endl; + if(m_mesh_data.count(filename)) + errorstream<<"Multiple models with name \""<<filename.c_str() + <<"\" found; replacing previous model"<<std::endl; + m_mesh_data[filename] = data; + return true; + } + + const char *translate_ext[] = { + ".tr", NULL + }; + name = removeStringEnd(filename, translate_ext); + if (!name.empty()) { + if (from_media_push) + return false; + TRACESTREAM(<< "Client: Loading translation: " + << "\"" << filename << "\"" << std::endl); + g_client_translations->loadTranslation(data); + return true; + } + + errorstream << "Client: Don't know how to load file \"" + << filename << "\"" << std::endl; + return false; +} + +// Virtual methods from con::PeerHandler +void Client::peerAdded(con::Peer *peer) +{ + infostream << "Client::peerAdded(): peer->id=" + << peer->id << std::endl; +} + +void Client::deletingPeer(con::Peer *peer, bool timeout) +{ + infostream << "Client::deletingPeer(): " + "Server Peer is getting deleted " + << "(timeout=" << timeout << ")" << std::endl; + + m_access_denied = true; + if (timeout) + m_access_denied_reason = gettext("Connection timed out."); + else if (m_access_denied_reason.empty()) + m_access_denied_reason = gettext("Connection aborted (protocol error?)."); +} + +/* + u16 command + u16 number of files requested + for each file { + u16 length of name + string name + } +*/ +void Client::request_media(const std::vector<std::string> &file_requests) +{ + std::ostringstream os(std::ios_base::binary); + writeU16(os, TOSERVER_REQUEST_MEDIA); + size_t file_requests_size = file_requests.size(); + + FATAL_ERROR_IF(file_requests_size > 0xFFFF, "Unsupported number of file requests"); + + // Packet dynamicly resized + NetworkPacket pkt(TOSERVER_REQUEST_MEDIA, 2 + 0); + + pkt << (u16) (file_requests_size & 0xFFFF); + + for (const std::string &file_request : file_requests) { + pkt << file_request; + } + + Send(&pkt); + + infostream << "Client: Sending media request list to server (" + << file_requests.size() << " files, packet size " + << pkt.getSize() << ")" << std::endl; +} + +void Client::initLocalMapSaving(const Address &address, + const std::string &hostname, + bool is_local_server) +{ + if (!g_settings->getBool("enable_local_map_saving") || is_local_server) { + return; + } + + std::string world_path; +#define set_world_path(hostname) \ + world_path = porting::path_user \ + + DIR_DELIM + "worlds" \ + + DIR_DELIM + "server_" \ + + hostname + "_" + std::to_string(address.getPort()); + + set_world_path(hostname); + if (!fs::IsDir(world_path)) { + std::string hostname_escaped = hostname; + str_replace(hostname_escaped, ':', '_'); + set_world_path(hostname_escaped); + } +#undef set_world_path + fs::CreateAllDirs(world_path); + + m_localdb = new MapDatabaseSQLite3(world_path); + m_localdb->beginSave(); + actionstream << "Local map saving started, map will be saved at '" << world_path << "'" << std::endl; +} + +void Client::ReceiveAll() +{ + NetworkPacket pkt; + u64 start_ms = porting::getTimeMs(); + const u64 budget = 100; + for(;;) { + // Limit time even if there would be huge amounts of data to + // process + if (porting::getTimeMs() > start_ms + budget) { + infostream << "Client::ReceiveAll(): " + "Packet processing budget exceeded." << std::endl; + break; + } + + pkt.clear(); + try { + if (!m_con->TryReceive(&pkt)) + break; + ProcessData(&pkt); + } catch (const con::InvalidIncomingDataException &e) { + infostream << "Client::ReceiveAll(): " + "InvalidIncomingDataException: what()=" + << e.what() << std::endl; + } + } +} + +inline void Client::handleCommand(NetworkPacket* pkt) +{ + const ToClientCommandHandler& opHandle = toClientCommandTable[pkt->getCommand()]; + (this->*opHandle.handler)(pkt); +} + +/* + sender_peer_id given to this shall be quaranteed to be a valid peer +*/ +void Client::ProcessData(NetworkPacket *pkt) +{ + ToClientCommand command = (ToClientCommand) pkt->getCommand(); + u32 sender_peer_id = pkt->getPeerId(); + + //infostream<<"Client: received command="<<command<<std::endl; + m_packetcounter.add((u16)command); + g_profiler->graphAdd("client_received_packets", 1); + + /* + If this check is removed, be sure to change the queue + system to know the ids + */ + if(sender_peer_id != PEER_ID_SERVER) { + infostream << "Client::ProcessData(): Discarding data not " + "coming from server: peer_id=" << sender_peer_id << " command=" << pkt->getCommand() + << std::endl; + return; + } + + // Command must be handled into ToClientCommandHandler + if (command >= TOCLIENT_NUM_MSG_TYPES) { + infostream << "Client: Ignoring unknown command " + << command << std::endl; + return; + } + + /* + * Those packets are handled before m_server_ser_ver is set, it's normal + * But we must use the new ToClientConnectionState in the future, + * as a byte mask + */ + if(toClientCommandTable[command].state == TOCLIENT_STATE_NOT_CONNECTED) { + handleCommand(pkt); + return; + } + + if(m_server_ser_ver == SER_FMT_VER_INVALID) { + infostream << "Client: Server serialization" + " format invalid or not initialized." + " Skipping incoming command=" << command << std::endl; + return; + } + + /* + Handle runtime commands + */ + + handleCommand(pkt); +} + +void Client::Send(NetworkPacket* pkt) +{ + m_con->Send(PEER_ID_SERVER, + serverCommandFactoryTable[pkt->getCommand()].channel, + pkt, + serverCommandFactoryTable[pkt->getCommand()].reliable); +} + +// Will fill up 12 + 12 + 4 + 4 + 4 bytes +void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *pkt) +{ + v3f pf = myplayer->getPosition() * 100; + v3f sf = myplayer->getSpeed() * 100; + s32 pitch = myplayer->getPitch() * 100; + s32 yaw = myplayer->getYaw() * 100; + u32 keyPressed = myplayer->control.getKeysPressed(); + // scaled by 80, so that pi can fit into a u8 + u8 fov = clientMap->getCameraFov() * 80; + u8 wanted_range = MYMIN(255, + std::ceil(clientMap->getControl().wanted_range / MAP_BLOCKSIZE)); + + v3s32 position(pf.X, pf.Y, pf.Z); + v3s32 speed(sf.X, sf.Y, sf.Z); + + /* + Format: + [0] v3s32 position*100 + [12] v3s32 speed*100 + [12+12] s32 pitch*100 + [12+12+4] s32 yaw*100 + [12+12+4+4] u32 keyPressed + [12+12+4+4+4] u8 fov*80 + [12+12+4+4+4+1] u8 ceil(wanted_range / MAP_BLOCKSIZE) + */ + *pkt << position << speed << pitch << yaw << keyPressed; + *pkt << fov << wanted_range; +} + +void Client::interact(InteractAction action, const PointedThing& pointed) +{ + if(m_state != LC_Ready) { + errorstream << "Client::interact() " + "Canceled (not connected)" + << std::endl; + return; + } + + LocalPlayer *myplayer = m_env.getLocalPlayer(); + if (myplayer == NULL) + return; + + /* + [0] u16 command + [2] u8 action + [3] u16 item + [5] u32 length of the next item (plen) + [9] serialized PointedThing + [9 + plen] player position information + */ + + NetworkPacket pkt(TOSERVER_INTERACT, 1 + 2 + 0); + + pkt << (u8)action; + pkt << myplayer->getWieldIndex(); + + std::ostringstream tmp_os(std::ios::binary); + pointed.serialize(tmp_os); + + pkt.putLongString(tmp_os.str()); + + writePlayerPos(myplayer, &m_env.getClientMap(), &pkt); + + Send(&pkt); +} + +void Client::deleteAuthData() +{ + if (!m_auth_data) + return; + + switch (m_chosen_auth_mech) { + case AUTH_MECHANISM_FIRST_SRP: + break; + case AUTH_MECHANISM_SRP: + case AUTH_MECHANISM_LEGACY_PASSWORD: + srp_user_delete((SRPUser *) m_auth_data); + m_auth_data = NULL; + break; + case AUTH_MECHANISM_NONE: + break; + } + m_chosen_auth_mech = AUTH_MECHANISM_NONE; +} + + +AuthMechanism Client::choseAuthMech(const u32 mechs) +{ + if (mechs & AUTH_MECHANISM_SRP) + return AUTH_MECHANISM_SRP; + + if (mechs & AUTH_MECHANISM_FIRST_SRP) + return AUTH_MECHANISM_FIRST_SRP; + + if (mechs & AUTH_MECHANISM_LEGACY_PASSWORD) + return AUTH_MECHANISM_LEGACY_PASSWORD; + + return AUTH_MECHANISM_NONE; +} + +void Client::sendInit(const std::string &playerName) +{ + NetworkPacket pkt(TOSERVER_INIT, 1 + 2 + 2 + (1 + playerName.size())); + + // we don't support network compression yet + u16 supp_comp_modes = NETPROTO_COMPRESSION_NONE; + + pkt << (u8) SER_FMT_VER_HIGHEST_READ << (u16) supp_comp_modes; + pkt << (u16) CLIENT_PROTOCOL_VERSION_MIN << (u16) CLIENT_PROTOCOL_VERSION_MAX; + pkt << playerName; + + Send(&pkt); +} + +void Client::startAuth(AuthMechanism chosen_auth_mechanism) +{ + m_chosen_auth_mech = chosen_auth_mechanism; + + switch (chosen_auth_mechanism) { + case AUTH_MECHANISM_FIRST_SRP: { + // send srp verifier to server + std::string verifier; + std::string salt; + generate_srp_verifier_and_salt(getPlayerName(), m_password, + &verifier, &salt); + + NetworkPacket resp_pkt(TOSERVER_FIRST_SRP, 0); + resp_pkt << salt << verifier << (u8)((m_password.empty()) ? 1 : 0); + + Send(&resp_pkt); + break; + } + case AUTH_MECHANISM_SRP: + case AUTH_MECHANISM_LEGACY_PASSWORD: { + u8 based_on = 1; + + if (chosen_auth_mechanism == AUTH_MECHANISM_LEGACY_PASSWORD) { + m_password = translate_password(getPlayerName(), m_password); + based_on = 0; + } + + std::string playername_u = lowercase(getPlayerName()); + m_auth_data = srp_user_new(SRP_SHA256, SRP_NG_2048, + getPlayerName().c_str(), playername_u.c_str(), + (const unsigned char *) m_password.c_str(), + m_password.length(), NULL, NULL); + char *bytes_A = 0; + size_t len_A = 0; + SRP_Result res = srp_user_start_authentication( + (struct SRPUser *) m_auth_data, NULL, NULL, 0, + (unsigned char **) &bytes_A, &len_A); + FATAL_ERROR_IF(res != SRP_OK, "Creating local SRP user failed."); + + NetworkPacket resp_pkt(TOSERVER_SRP_BYTES_A, 0); + resp_pkt << std::string(bytes_A, len_A) << based_on; + Send(&resp_pkt); + break; + } + case AUTH_MECHANISM_NONE: + break; // not handled in this method + } +} + +void Client::sendDeletedBlocks(std::vector<v3s16> &blocks) +{ + NetworkPacket pkt(TOSERVER_DELETEDBLOCKS, 1 + sizeof(v3s16) * blocks.size()); + + pkt << (u8) blocks.size(); + + for (const v3s16 &block : blocks) { + pkt << block; + } + + Send(&pkt); +} + +void Client::sendGotBlocks(const std::vector<v3s16> &blocks) +{ + NetworkPacket pkt(TOSERVER_GOTBLOCKS, 1 + 6 * blocks.size()); + pkt << (u8) blocks.size(); + for (const v3s16 &block : blocks) + pkt << block; + + Send(&pkt); +} + +void Client::sendRemovedSounds(std::vector<s32> &soundList) +{ + size_t server_ids = soundList.size(); + assert(server_ids <= 0xFFFF); + + NetworkPacket pkt(TOSERVER_REMOVED_SOUNDS, 2 + server_ids * 4); + + pkt << (u16) (server_ids & 0xFFFF); + + for (s32 sound_id : soundList) + pkt << sound_id; + + Send(&pkt); +} + +void Client::sendNodemetaFields(v3s16 p, const std::string &formname, + const StringMap &fields) +{ + size_t fields_size = fields.size(); + + FATAL_ERROR_IF(fields_size > 0xFFFF, "Unsupported number of nodemeta fields"); + + NetworkPacket pkt(TOSERVER_NODEMETA_FIELDS, 0); + + pkt << p << formname << (u16) (fields_size & 0xFFFF); + + StringMap::const_iterator it; + for (it = fields.begin(); it != fields.end(); ++it) { + const std::string &name = it->first; + const std::string &value = it->second; + pkt << name; + pkt.putLongString(value); + } + + Send(&pkt); +} + +void Client::sendInventoryFields(const std::string &formname, + const StringMap &fields) +{ + size_t fields_size = fields.size(); + FATAL_ERROR_IF(fields_size > 0xFFFF, "Unsupported number of inventory fields"); + + NetworkPacket pkt(TOSERVER_INVENTORY_FIELDS, 0); + pkt << formname << (u16) (fields_size & 0xFFFF); + + StringMap::const_iterator it; + for (it = fields.begin(); it != fields.end(); ++it) { + const std::string &name = it->first; + const std::string &value = it->second; + pkt << name; + pkt.putLongString(value); + } + + Send(&pkt); +} + +void Client::sendInventoryAction(InventoryAction *a) +{ + std::ostringstream os(std::ios_base::binary); + + a->serialize(os); + + // Make data buffer + std::string s = os.str(); + + NetworkPacket pkt(TOSERVER_INVENTORY_ACTION, s.size()); + pkt.putRawString(s.c_str(),s.size()); + + Send(&pkt); +} + +bool Client::canSendChatMessage() const +{ + u32 now = time(NULL); + float time_passed = now - m_last_chat_message_sent; + + float virt_chat_message_allowance = m_chat_message_allowance + time_passed * + (CLIENT_CHAT_MESSAGE_LIMIT_PER_10S / 8.0f); + + if (virt_chat_message_allowance < 1.0f) + return false; + + return true; +} + +void Client::sendChatMessage(const std::wstring &message) +{ + const s16 max_queue_size = g_settings->getS16("max_out_chat_queue_size"); + if (canSendChatMessage()) { + u32 now = time(NULL); + float time_passed = now - m_last_chat_message_sent; + m_last_chat_message_sent = now; + + m_chat_message_allowance += time_passed * (CLIENT_CHAT_MESSAGE_LIMIT_PER_10S / 8.0f); + if (m_chat_message_allowance > CLIENT_CHAT_MESSAGE_LIMIT_PER_10S) + m_chat_message_allowance = CLIENT_CHAT_MESSAGE_LIMIT_PER_10S; + + m_chat_message_allowance -= 1.0f; + + NetworkPacket pkt(TOSERVER_CHAT_MESSAGE, 2 + message.size() * sizeof(u16)); + + pkt << message; + + Send(&pkt); + } else if (m_out_chat_queue.size() < (u16) max_queue_size || max_queue_size < 0) { + m_out_chat_queue.push(message); + } else { + infostream << "Could not queue chat message because maximum out chat queue size (" + << max_queue_size << ") is reached." << std::endl; + } +} + +void Client::clearOutChatQueue() +{ + m_out_chat_queue = std::queue<std::wstring>(); +} + +void Client::sendChangePassword(const std::string &oldpassword, + const std::string &newpassword) +{ + LocalPlayer *player = m_env.getLocalPlayer(); + if (player == NULL) + return; + + // get into sudo mode and then send new password to server + m_password = oldpassword; + m_new_password = newpassword; + startAuth(choseAuthMech(m_sudo_auth_methods)); +} + + +void Client::sendDamage(u16 damage) +{ + NetworkPacket pkt(TOSERVER_DAMAGE, sizeof(u16)); + pkt << damage; + Send(&pkt); +} + +void Client::sendRespawn() +{ + NetworkPacket pkt(TOSERVER_RESPAWN, 0); + Send(&pkt); +} + +void Client::sendReady() +{ + NetworkPacket pkt(TOSERVER_CLIENT_READY, + 1 + 1 + 1 + 1 + 2 + sizeof(char) * strlen(g_version_hash) + 2); + + pkt << (u8) VERSION_MAJOR << (u8) VERSION_MINOR << (u8) VERSION_PATCH + << (u8) 0 << (u16) strlen(g_version_hash); + + pkt.putRawString(g_version_hash, (u16) strlen(g_version_hash)); + pkt << (u16)FORMSPEC_API_VERSION; + Send(&pkt); +} + +void Client::sendPlayerPos() +{ + LocalPlayer *player = m_env.getLocalPlayer(); + if (!player) + return; + + // Save bandwidth by only updating position when + // player is not dead and something changed + + if (m_activeobjects_received && player->isDead()) + return; + + ClientMap &map = m_env.getClientMap(); + u8 camera_fov = map.getCameraFov(); + u8 wanted_range = map.getControl().wanted_range; + + u32 keyPressed = player->control.getKeysPressed(); + + if ( + player->last_position == player->getPosition() && + player->last_speed == player->getSpeed() && + player->last_pitch == player->getPitch() && + player->last_yaw == player->getYaw() && + player->last_keyPressed == keyPressed && + player->last_camera_fov == camera_fov && + player->last_wanted_range == wanted_range) + return; + + player->last_position = player->getPosition(); + player->last_speed = player->getSpeed(); + player->last_pitch = player->getPitch(); + player->last_yaw = player->getYaw(); + player->last_keyPressed = keyPressed; + player->last_camera_fov = camera_fov; + player->last_wanted_range = wanted_range; + + NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4 + 1 + 1); + + writePlayerPos(player, &map, &pkt); + + Send(&pkt); +} + +void Client::sendHaveMedia(const std::vector<u32> &tokens) +{ + NetworkPacket pkt(TOSERVER_HAVE_MEDIA, 1 + tokens.size() * 4); + + sanity_check(tokens.size() < 256); + + pkt << static_cast<u8>(tokens.size()); + for (u32 token : tokens) + pkt << token; + + Send(&pkt); +} + +void Client::removeNode(v3s16 p) +{ + std::map<v3s16, MapBlock*> modified_blocks; + + try { + m_env.getMap().removeNodeAndUpdate(p, modified_blocks); + } + catch(InvalidPositionException &e) { + } + + for (const auto &modified_block : modified_blocks) { + addUpdateMeshTaskWithEdge(modified_block.first, false, true); + } +} + +/** + * Helper function for Client Side Modding + * CSM restrictions are applied there, this should not be used for core engine + * @param p + * @param is_valid_position + * @return + */ +MapNode Client::CSMGetNode(v3s16 p, bool *is_valid_position) +{ + if (checkCSMRestrictionFlag(CSMRestrictionFlags::CSM_RF_LOOKUP_NODES)) { + v3s16 ppos = floatToInt(m_env.getLocalPlayer()->getPosition(), BS); + if ((u32) ppos.getDistanceFrom(p) > m_csm_restriction_noderange) { + *is_valid_position = false; + return {}; + } + } + return m_env.getMap().getNode(p, is_valid_position); +} + +int Client::CSMClampRadius(v3s16 pos, int radius) +{ + if (!checkCSMRestrictionFlag(CSMRestrictionFlags::CSM_RF_LOOKUP_NODES)) + return radius; + // This is approximate and will cause some allowed nodes to be excluded + v3s16 ppos = floatToInt(m_env.getLocalPlayer()->getPosition(), BS); + u32 distance = ppos.getDistanceFrom(pos); + if (distance >= m_csm_restriction_noderange) + return 0; + return std::min<int>(radius, m_csm_restriction_noderange - distance); +} + +v3s16 Client::CSMClampPos(v3s16 pos) +{ + if (!checkCSMRestrictionFlag(CSMRestrictionFlags::CSM_RF_LOOKUP_NODES)) + return pos; + v3s16 ppos = floatToInt(m_env.getLocalPlayer()->getPosition(), BS); + const int range = m_csm_restriction_noderange; + return v3s16( + core::clamp<int>(pos.X, (int)ppos.X - range, (int)ppos.X + range), + core::clamp<int>(pos.Y, (int)ppos.Y - range, (int)ppos.Y + range), + core::clamp<int>(pos.Z, (int)ppos.Z - range, (int)ppos.Z + range) + ); +} + +void Client::addNode(v3s16 p, MapNode n, bool remove_metadata) +{ + //TimeTaker timer1("Client::addNode()"); + + std::map<v3s16, MapBlock*> modified_blocks; + + try { + //TimeTaker timer3("Client::addNode(): addNodeAndUpdate"); + m_env.getMap().addNodeAndUpdate(p, n, modified_blocks, remove_metadata); + } + catch(InvalidPositionException &e) { + } + + for (const auto &modified_block : modified_blocks) { + addUpdateMeshTaskWithEdge(modified_block.first, false, true); + } +} + +void Client::setPlayerControl(PlayerControl &control) +{ + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player); + player->control = control; +} + +void Client::setPlayerItem(u16 item) +{ + m_env.getLocalPlayer()->setWieldIndex(item); + m_update_wielded_item = true; + + NetworkPacket pkt(TOSERVER_PLAYERITEM, 2); + pkt << item; + Send(&pkt); +} + +// Returns true once after the inventory of the local player +// has been updated from the server. +bool Client::updateWieldedItem() +{ + if (!m_update_wielded_item) + return false; + + m_update_wielded_item = false; + + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player); + if (auto *list = player->inventory.getList("main")) + list->setModified(false); + if (auto *list = player->inventory.getList("hand")) + list->setModified(false); + + return true; +} + +scene::ISceneManager* Client::getSceneManager() +{ + return m_rendering_engine->get_scene_manager(); +} + +Inventory* Client::getInventory(const InventoryLocation &loc) +{ + switch(loc.type){ + case InventoryLocation::UNDEFINED: + {} + break; + case InventoryLocation::CURRENT_PLAYER: + { + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player); + return &player->inventory; + } + break; + case InventoryLocation::PLAYER: + { + // Check if we are working with local player inventory + LocalPlayer *player = m_env.getLocalPlayer(); + if (!player || strcmp(player->getName(), loc.name.c_str()) != 0) + return NULL; + return &player->inventory; + } + break; + case InventoryLocation::NODEMETA: + { + NodeMetadata *meta = m_env.getMap().getNodeMetadata(loc.p); + if(!meta) + return NULL; + return meta->getInventory(); + } + break; + case InventoryLocation::DETACHED: + { + if (m_detached_inventories.count(loc.name) == 0) + return NULL; + return m_detached_inventories[loc.name]; + } + break; + default: + FATAL_ERROR("Invalid inventory location type."); + break; + } + return NULL; +} + +void Client::inventoryAction(InventoryAction *a) +{ + /* + Send it to the server + */ + sendInventoryAction(a); + + /* + Predict some local inventory changes + */ + a->clientApply(this, this); + + // Remove it + delete a; +} + +float Client::getAnimationTime() +{ + return m_animation_time; +} + +int Client::getCrackLevel() +{ + return m_crack_level; +} + +v3s16 Client::getCrackPos() +{ + return m_crack_pos; +} + +void Client::setCrack(int level, v3s16 pos) +{ + int old_crack_level = m_crack_level; + v3s16 old_crack_pos = m_crack_pos; + + m_crack_level = level; + m_crack_pos = pos; + + if(old_crack_level >= 0 && (level < 0 || pos != old_crack_pos)) + { + // remove old crack + addUpdateMeshTaskForNode(old_crack_pos, false, true); + } + if(level >= 0 && (old_crack_level < 0 || pos != old_crack_pos)) + { + // add new crack + addUpdateMeshTaskForNode(pos, false, true); + } +} + +u16 Client::getHP() +{ + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player); + return player->hp; +} + +bool Client::getChatMessage(std::wstring &res) +{ + if (m_chat_queue.empty()) + return false; + + ChatMessage *chatMessage = m_chat_queue.front(); + m_chat_queue.pop(); + + res = L""; + + switch (chatMessage->type) { + case CHATMESSAGE_TYPE_RAW: + case CHATMESSAGE_TYPE_ANNOUNCE: + case CHATMESSAGE_TYPE_SYSTEM: + res = chatMessage->message; + break; + case CHATMESSAGE_TYPE_NORMAL: { + if (!chatMessage->sender.empty()) + res = L"<" + chatMessage->sender + L"> " + chatMessage->message; + else + res = chatMessage->message; + break; + } + default: + break; + } + + delete chatMessage; + return true; +} + +void Client::typeChatMessage(const std::wstring &message) +{ + // Discard empty line + if (message.empty()) + return; + + // If message was consumed by script API, don't send it to server + if (m_mods_loaded && m_script->on_sending_message(wide_to_utf8(message))) + return; + + // Send to others + sendChatMessage(message); +} + +void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server, bool urgent) +{ + // Check if the block exists to begin with. In the case when a non-existing + // neighbor is automatically added, it may not. In that case we don't want + // to tell the mesh update thread about it. + MapBlock *b = m_env.getMap().getBlockNoCreateNoEx(p); + if (b == NULL) + return; + + m_mesh_update_thread.updateBlock(&m_env.getMap(), p, ack_to_server, urgent); +} + +void Client::addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server, bool urgent) +{ + m_mesh_update_thread.updateBlock(&m_env.getMap(), blockpos, ack_to_server, urgent, true); +} + +void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool urgent) +{ + { + v3s16 p = nodepos; + infostream<<"Client::addUpdateMeshTaskForNode(): " + <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")" + <<std::endl; + } + + v3s16 blockpos = getNodeBlockPos(nodepos); + v3s16 blockpos_relative = blockpos * MAP_BLOCKSIZE; + m_mesh_update_thread.updateBlock(&m_env.getMap(), blockpos, ack_to_server, urgent, false); + // Leading edge + if (nodepos.X == blockpos_relative.X) + addUpdateMeshTask(blockpos + v3s16(-1, 0, 0), false, urgent); + if (nodepos.Y == blockpos_relative.Y) + addUpdateMeshTask(blockpos + v3s16(0, -1, 0), false, urgent); + if (nodepos.Z == blockpos_relative.Z) + addUpdateMeshTask(blockpos + v3s16(0, 0, -1), false, urgent); +} + +ClientEvent *Client::getClientEvent() +{ + FATAL_ERROR_IF(m_client_event_queue.empty(), + "Cannot getClientEvent, queue is empty."); + + ClientEvent *event = m_client_event_queue.front(); + m_client_event_queue.pop(); + return event; +} + +const Address Client::getServerAddress() +{ + return m_con->GetPeerAddress(PEER_ID_SERVER); +} + +float Client::mediaReceiveProgress() +{ + if (m_media_downloader) + return m_media_downloader->getProgress(); + + return 1.0; // downloader only exists when not yet done +} + +struct TextureUpdateArgs { + gui::IGUIEnvironment *guienv; + u64 last_time_ms; + u16 last_percent; + const wchar_t* text_base; + ITextureSource *tsrc; +}; + +void Client::showUpdateProgressTexture(void *args, u32 progress, u32 max_progress) +{ + TextureUpdateArgs* targs = (TextureUpdateArgs*) args; + u16 cur_percent = ceil(progress / (double) max_progress * 100.); + + // update the loading menu -- if neccessary + bool do_draw = false; + u64 time_ms = targs->last_time_ms; + if (cur_percent != targs->last_percent) { + targs->last_percent = cur_percent; + time_ms = porting::getTimeMs(); + // only draw when the user will notice something: + do_draw = (time_ms - targs->last_time_ms > 100); + } + + if (do_draw) { + targs->last_time_ms = time_ms; + std::wostringstream strm; + strm << targs->text_base << L" " << targs->last_percent << L"%..."; + m_rendering_engine->draw_load_screen(strm.str(), targs->guienv, targs->tsrc, 0, + 72 + (u16) ((18. / 100.) * (double) targs->last_percent), true); + } +} + +void Client::afterContentReceived() +{ + infostream<<"Client::afterContentReceived() started"<<std::endl; + assert(m_itemdef_received); // pre-condition + assert(m_nodedef_received); // pre-condition + assert(mediaReceived()); // pre-condition + + const wchar_t* text = wgettext("Loading textures..."); + + // Clear cached pre-scaled 2D GUI images, as this cache + // might have images with the same name but different + // content from previous sessions. + guiScalingCacheClear(); + + // Rebuild inherited images and recreate textures + infostream<<"- Rebuilding images and textures"<<std::endl; + m_rendering_engine->draw_load_screen(text, guienv, m_tsrc, 0, 70); + m_tsrc->rebuildImagesAndTextures(); + delete[] text; + + // Rebuild shaders + infostream<<"- Rebuilding shaders"<<std::endl; + text = wgettext("Rebuilding shaders..."); + m_rendering_engine->draw_load_screen(text, guienv, m_tsrc, 0, 71); + m_shsrc->rebuildShaders(); + delete[] text; + + // Update node aliases + infostream<<"- Updating node aliases"<<std::endl; + text = wgettext("Initializing nodes..."); + m_rendering_engine->draw_load_screen(text, guienv, m_tsrc, 0, 72); + m_nodedef->updateAliases(m_itemdef); + for (const auto &path : getTextureDirs()) { + TextureOverrideSource override_source(path + DIR_DELIM + "override.txt"); + m_nodedef->applyTextureOverrides(override_source.getNodeTileOverrides()); + m_itemdef->applyTextureOverrides(override_source.getItemTextureOverrides()); + } + m_nodedef->setNodeRegistrationStatus(true); + m_nodedef->runNodeResolveCallbacks(); + delete[] text; + + // Update node textures and assign shaders to each tile + infostream<<"- Updating node textures"<<std::endl; + TextureUpdateArgs tu_args; + tu_args.guienv = guienv; + tu_args.last_time_ms = porting::getTimeMs(); + tu_args.last_percent = 0; + tu_args.text_base = wgettext("Initializing nodes"); + tu_args.tsrc = m_tsrc; + m_nodedef->updateTextures(this, &tu_args); + delete[] tu_args.text_base; + + // Start mesh update thread after setting up content definitions + infostream<<"- Starting mesh update thread"<<std::endl; + m_mesh_update_thread.start(); + + m_state = LC_Ready; + sendReady(); + + if (m_mods_loaded) + m_script->on_client_ready(m_env.getLocalPlayer()); + + text = wgettext("Done!"); + m_rendering_engine->draw_load_screen(text, guienv, m_tsrc, 0, 100); + infostream<<"Client::afterContentReceived() done"<<std::endl; + delete[] text; +} + +float Client::getRTT() +{ + return m_con->getPeerStat(PEER_ID_SERVER,con::AVG_RTT); +} + +float Client::getCurRate() +{ + return (m_con->getLocalStat(con::CUR_INC_RATE) + + m_con->getLocalStat(con::CUR_DL_RATE)); +} + +void Client::makeScreenshot() +{ + irr::video::IVideoDriver *driver = m_rendering_engine->get_video_driver(); + irr::video::IImage* const raw_image = driver->createScreenShot(); + + if (!raw_image) + return; + + const struct tm tm = mt_localtime(); + + char timetstamp_c[64]; + strftime(timetstamp_c, sizeof(timetstamp_c), "%Y%m%d_%H%M%S", &tm); + + std::string screenshot_dir; + + if (fs::IsPathAbsolute(g_settings->get("screenshot_path"))) + screenshot_dir = g_settings->get("screenshot_path"); + else + screenshot_dir = porting::path_user + DIR_DELIM + g_settings->get("screenshot_path"); + + std::string filename_base = screenshot_dir + + DIR_DELIM + + std::string("screenshot_") + + std::string(timetstamp_c); + std::string filename_ext = "." + g_settings->get("screenshot_format"); + std::string filename; + + // Create the directory if it doesn't already exist. + // Otherwise, saving the screenshot would fail. + fs::CreateDir(screenshot_dir); + + u32 quality = (u32)g_settings->getS32("screenshot_quality"); + quality = MYMIN(MYMAX(quality, 0), 100) / 100.0 * 255; + + // Try to find a unique filename + unsigned serial = 0; + + while (serial < SCREENSHOT_MAX_SERIAL_TRIES) { + filename = filename_base + (serial > 0 ? ("_" + itos(serial)) : "") + filename_ext; + std::ifstream tmp(filename.c_str()); + if (!tmp.good()) + break; // File did not apparently exist, we'll go with it + serial++; + } + + if (serial == SCREENSHOT_MAX_SERIAL_TRIES) { + infostream << "Could not find suitable filename for screenshot" << std::endl; + } else { + irr::video::IImage* const image = + driver->createImage(video::ECF_R8G8B8, raw_image->getDimension()); + + if (image) { + raw_image->copyTo(image); + + std::ostringstream sstr; + if (driver->writeImageToFile(image, filename.c_str(), quality)) { + sstr << "Saved screenshot to '" << filename << "'"; + } else { + sstr << "Failed to save screenshot '" << filename << "'"; + } + pushToChatQueue(new ChatMessage(CHATMESSAGE_TYPE_SYSTEM, + utf8_to_wide(sstr.str()))); + infostream << sstr.str() << std::endl; + image->drop(); + } + } + + raw_image->drop(); +} + +bool Client::shouldShowMinimap() const +{ + return !m_minimap_disabled_by_server; +} + +void Client::pushToEventQueue(ClientEvent *event) +{ + m_client_event_queue.push(event); +} + +void Client::showMinimap(const bool show) +{ + m_game_ui->showMinimap(show); +} + +// IGameDef interface +// Under envlock +IItemDefManager* Client::getItemDefManager() +{ + return m_itemdef; +} +const NodeDefManager* Client::getNodeDefManager() +{ + return m_nodedef; +} +ICraftDefManager* Client::getCraftDefManager() +{ + return NULL; + //return m_craftdef; +} +ITextureSource* Client::getTextureSource() +{ + return m_tsrc; +} +IWritableShaderSource* Client::getShaderSource() +{ + return m_shsrc; +} + +u16 Client::allocateUnknownNodeId(const std::string &name) +{ + errorstream << "Client::allocateUnknownNodeId(): " + << "Client cannot allocate node IDs" << std::endl; + FATAL_ERROR("Client allocated unknown node"); + + return CONTENT_IGNORE; +} +ISoundManager* Client::getSoundManager() +{ + return m_sound; +} +MtEventManager* Client::getEventManager() +{ + return m_event; +} + +ParticleManager* Client::getParticleManager() +{ + return &m_particle_manager; +} + +scene::IAnimatedMesh* Client::getMesh(const std::string &filename, bool cache) +{ + StringMap::const_iterator it = m_mesh_data.find(filename); + if (it == m_mesh_data.end()) { + errorstream << "Client::getMesh(): Mesh not found: \"" << filename + << "\"" << std::endl; + return NULL; + } + const std::string &data = it->second; + + // Create the mesh, remove it from cache and return it + // This allows unique vertex colors and other properties for each instance + io::IReadFile *rfile = m_rendering_engine->get_filesystem()->createMemoryReadFile( + data.c_str(), data.size(), filename.c_str()); + FATAL_ERROR_IF(!rfile, "Could not create/open RAM file"); + + scene::IAnimatedMesh *mesh = m_rendering_engine->get_scene_manager()->getMesh(rfile); + rfile->drop(); + if (!mesh) + return nullptr; + mesh->grab(); + if (!cache) + m_rendering_engine->removeMesh(mesh); + return mesh; +} + +const std::string* Client::getModFile(std::string filename) +{ + // strip dir delimiter from beginning of path + auto pos = filename.find_first_of(':'); + if (pos == std::string::npos) + return nullptr; + pos++; + auto pos2 = filename.find_first_not_of('/', pos); + if (pos2 > pos) + filename.erase(pos, pos2 - pos); + + StringMap::const_iterator it = m_mod_vfs.find(filename); + if (it == m_mod_vfs.end()) + return nullptr; + return &it->second; +} + +bool Client::registerModStorage(ModMetadata *storage) +{ + if (m_mod_storages.find(storage->getModName()) != m_mod_storages.end()) { + errorstream << "Unable to register same mod storage twice. Storage name: " + << storage->getModName() << std::endl; + return false; + } + + m_mod_storages[storage->getModName()] = storage; + return true; +} + +void Client::unregisterModStorage(const std::string &name) +{ + std::unordered_map<std::string, ModMetadata *>::const_iterator it = + m_mod_storages.find(name); + if (it != m_mod_storages.end()) + m_mod_storages.erase(name); +} + +/* + * Mod channels + */ + +bool Client::joinModChannel(const std::string &channel) +{ + if (m_modchannel_mgr->channelRegistered(channel)) + return false; + + NetworkPacket pkt(TOSERVER_MODCHANNEL_JOIN, 2 + channel.size()); + pkt << channel; + Send(&pkt); + + m_modchannel_mgr->joinChannel(channel, 0); + return true; +} + +bool Client::leaveModChannel(const std::string &channel) +{ + if (!m_modchannel_mgr->channelRegistered(channel)) + return false; + + NetworkPacket pkt(TOSERVER_MODCHANNEL_LEAVE, 2 + channel.size()); + pkt << channel; + Send(&pkt); + + m_modchannel_mgr->leaveChannel(channel, 0); + return true; +} + +bool Client::sendModChannelMessage(const std::string &channel, const std::string &message) +{ + if (!m_modchannel_mgr->canWriteOnChannel(channel)) + return false; + + if (message.size() > STRING_MAX_LEN) { + warningstream << "ModChannel message too long, dropping before sending " + << " (" << message.size() << " > " << STRING_MAX_LEN << ", channel: " + << channel << ")" << std::endl; + return false; + } + + // @TODO: do some client rate limiting + NetworkPacket pkt(TOSERVER_MODCHANNEL_MSG, 2 + channel.size() + 2 + message.size()); + pkt << channel << message; + Send(&pkt); + return true; +} + +ModChannel* Client::getModChannel(const std::string &channel) +{ + return m_modchannel_mgr->getModChannel(channel); +} diff --git a/src/client/client.h b/src/client/client.h new file mode 100644 index 0000000..bdcc2a3 --- /dev/null +++ b/src/client/client.h @@ -0,0 +1,609 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "clientenvironment.h" +#include "irrlichttypes_extrabloated.h" +#include <ostream> +#include <map> +#include <set> +#include <vector> +#include <unordered_set> +#include "clientobject.h" +#include "gamedef.h" +#include "inventorymanager.h" +#include "localplayer.h" +#include "client/hud.h" +#include "particles.h" +#include "mapnode.h" +#include "tileanimation.h" +#include "mesh_generator_thread.h" +#include "network/address.h" +#include "network/peerhandler.h" +#include "gameparams.h" +#include <fstream> + +#define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f + +struct ClientEvent; +struct MeshMakeData; +struct ChatMessage; +class MapBlockMesh; +class RenderingEngine; +class IWritableTextureSource; +class IWritableShaderSource; +class IWritableItemDefManager; +class ISoundManager; +class NodeDefManager; +//class IWritableCraftDefManager; +class ClientMediaDownloader; +class SingleMediaDownloader; +struct MapDrawControl; +class ModChannelMgr; +class MtEventManager; +struct PointedThing; +class MapDatabase; +class Minimap; +struct MinimapMapblock; +class Camera; +class NetworkPacket; +namespace con { +class Connection; +} + +enum LocalClientState { + LC_Created, + LC_Init, + LC_Ready +}; + +/* + Packet counter +*/ + +class PacketCounter +{ +public: + PacketCounter() = default; + + void add(u16 command) + { + auto n = m_packets.find(command); + if (n == m_packets.end()) + m_packets[command] = 1; + else + n->second++; + } + + void clear() + { + m_packets.clear(); + } + + u32 sum() const; + void print(std::ostream &o) const; + +private: + // command, count + std::map<u16, u32> m_packets; +}; + +class ClientScripting; +class GameUI; + +class Client : public con::PeerHandler, public InventoryManager, public IGameDef +{ +public: + /* + NOTE: Nothing is thread-safe here. + */ + + Client( + const char *playername, + const std::string &password, + const std::string &address_name, + MapDrawControl &control, + IWritableTextureSource *tsrc, + IWritableShaderSource *shsrc, + IWritableItemDefManager *itemdef, + NodeDefManager *nodedef, + ISoundManager *sound, + MtEventManager *event, + RenderingEngine *rendering_engine, + bool ipv6, + GameUI *game_ui, + ELoginRegister allow_login_or_register + ); + + ~Client(); + DISABLE_CLASS_COPY(Client); + + // Load local mods into memory + void scanModSubfolder(const std::string &mod_name, const std::string &mod_path, + std::string mod_subpath); + inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path) + { + scanModSubfolder(mod_name, mod_path, ""); + } + + /* + request all threads managed by client to be stopped + */ + void Stop(); + + + bool isShutdown(); + + /* + The name of the local player should already be set when + calling this, as it is sent in the initialization. + */ + void connect(Address address, bool is_local_server); + + /* + Stuff that references the environment is valid only as + long as this is not called. (eg. Players) + If this throws a PeerNotFoundException, the connection has + timed out. + */ + void step(float dtime); + + /* + * Command Handlers + */ + + void handleCommand(NetworkPacket* pkt); + + void handleCommand_Null(NetworkPacket* pkt) {}; + void handleCommand_Deprecated(NetworkPacket* pkt); + void handleCommand_Hello(NetworkPacket* pkt); + void handleCommand_AuthAccept(NetworkPacket* pkt); + void handleCommand_AcceptSudoMode(NetworkPacket* pkt); + void handleCommand_DenySudoMode(NetworkPacket* pkt); + void handleCommand_AccessDenied(NetworkPacket* pkt); + void handleCommand_RemoveNode(NetworkPacket* pkt); + void handleCommand_AddNode(NetworkPacket* pkt); + void handleCommand_NodemetaChanged(NetworkPacket *pkt); + void handleCommand_BlockData(NetworkPacket* pkt); + void handleCommand_Inventory(NetworkPacket* pkt); + void handleCommand_TimeOfDay(NetworkPacket* pkt); + void handleCommand_ChatMessage(NetworkPacket *pkt); + void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt); + void handleCommand_ActiveObjectMessages(NetworkPacket* pkt); + void handleCommand_Movement(NetworkPacket* pkt); + void handleCommand_Fov(NetworkPacket *pkt); + void handleCommand_HP(NetworkPacket* pkt); + void handleCommand_Breath(NetworkPacket* pkt); + void handleCommand_MovePlayer(NetworkPacket* pkt); + void handleCommand_DeathScreen(NetworkPacket* pkt); + void handleCommand_AnnounceMedia(NetworkPacket* pkt); + void handleCommand_Media(NetworkPacket* pkt); + void handleCommand_NodeDef(NetworkPacket* pkt); + void handleCommand_ItemDef(NetworkPacket* pkt); + void handleCommand_PlaySound(NetworkPacket* pkt); + void handleCommand_StopSound(NetworkPacket* pkt); + void handleCommand_FadeSound(NetworkPacket *pkt); + void handleCommand_Privileges(NetworkPacket* pkt); + void handleCommand_InventoryFormSpec(NetworkPacket* pkt); + void handleCommand_DetachedInventory(NetworkPacket* pkt); + void handleCommand_ShowFormSpec(NetworkPacket* pkt); + void handleCommand_SpawnParticle(NetworkPacket* pkt); + void handleCommand_AddParticleSpawner(NetworkPacket* pkt); + void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt); + void handleCommand_HudAdd(NetworkPacket* pkt); + void handleCommand_HudRemove(NetworkPacket* pkt); + void handleCommand_HudChange(NetworkPacket* pkt); + void handleCommand_HudSetFlags(NetworkPacket* pkt); + void handleCommand_HudSetParam(NetworkPacket* pkt); + void handleCommand_HudSetSky(NetworkPacket* pkt); + void handleCommand_HudSetSun(NetworkPacket* pkt); + void handleCommand_HudSetMoon(NetworkPacket* pkt); + void handleCommand_HudSetStars(NetworkPacket* pkt); + void handleCommand_CloudParams(NetworkPacket* pkt); + void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt); + void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt); + void handleCommand_EyeOffset(NetworkPacket* pkt); + void handleCommand_UpdatePlayerList(NetworkPacket* pkt); + void handleCommand_ModChannelMsg(NetworkPacket *pkt); + void handleCommand_ModChannelSignal(NetworkPacket *pkt); + void handleCommand_SrpBytesSandB(NetworkPacket *pkt); + void handleCommand_FormspecPrepend(NetworkPacket *pkt); + void handleCommand_CSMRestrictionFlags(NetworkPacket *pkt); + void handleCommand_PlayerSpeed(NetworkPacket *pkt); + void handleCommand_MediaPush(NetworkPacket *pkt); + void handleCommand_MinimapModes(NetworkPacket *pkt); + void handleCommand_SetLighting(NetworkPacket *pkt); + + void ProcessData(NetworkPacket *pkt); + + void Send(NetworkPacket* pkt); + + void interact(InteractAction action, const PointedThing &pointed); + + void sendNodemetaFields(v3s16 p, const std::string &formname, + const StringMap &fields); + void sendInventoryFields(const std::string &formname, + const StringMap &fields); + void sendInventoryAction(InventoryAction *a); + void sendChatMessage(const std::wstring &message); + void clearOutChatQueue(); + void sendChangePassword(const std::string &oldpassword, + const std::string &newpassword); + void sendDamage(u16 damage); + void sendRespawn(); + void sendReady(); + void sendHaveMedia(const std::vector<u32> &tokens); + + ClientEnvironment& getEnv() { return m_env; } + ITextureSource *tsrc() { return getTextureSource(); } + ISoundManager *sound() { return getSoundManager(); } + static const std::string &getBuiltinLuaPath(); + static const std::string &getClientModsLuaPath(); + + const std::vector<ModSpec> &getMods() const override; + const ModSpec* getModSpec(const std::string &modname) const override; + + // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent) + void removeNode(v3s16 p); + + // helpers to enforce CSM restrictions + MapNode CSMGetNode(v3s16 p, bool *is_valid_position); + int CSMClampRadius(v3s16 pos, int radius); + v3s16 CSMClampPos(v3s16 pos); + + void addNode(v3s16 p, MapNode n, bool remove_metadata = true); + + void setPlayerControl(PlayerControl &control); + + // Returns true if the inventory of the local player has been + // updated from the server. If it is true, it is set to false. + bool updateWieldedItem(); + + /* InventoryManager interface */ + Inventory* getInventory(const InventoryLocation &loc) override; + void inventoryAction(InventoryAction *a) override; + + // Send the item number 'item' as player item to the server + void setPlayerItem(u16 item); + + const std::list<std::string> &getConnectedPlayerNames() + { + return m_env.getPlayerNames(); + } + + float getAnimationTime(); + + int getCrackLevel(); + v3s16 getCrackPos(); + void setCrack(int level, v3s16 pos); + + u16 getHP(); + + bool checkPrivilege(const std::string &priv) const + { return (m_privileges.count(priv) != 0); } + + const std::unordered_set<std::string> &getPrivilegeList() const + { return m_privileges; } + + bool getChatMessage(std::wstring &message); + void typeChatMessage(const std::wstring& message); + + u64 getMapSeed(){ return m_map_seed; } + + void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false); + // Including blocks at appropriate edges + void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false); + void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false); + + void updateCameraOffset(v3s16 camera_offset) + { m_mesh_update_thread.m_camera_offset = camera_offset; } + + bool hasClientEvents() const { return !m_client_event_queue.empty(); } + // Get event from queue. If queue is empty, it triggers an assertion failure. + ClientEvent * getClientEvent(); + + bool accessDenied() const { return m_access_denied; } + + bool reconnectRequested() const { return m_access_denied_reconnect; } + + void setFatalError(const std::string &reason) + { + m_access_denied = true; + m_access_denied_reason = reason; + } + inline void setFatalError(const LuaError &e) + { + setFatalError(std::string("Lua: ") + e.what()); + } + + // Renaming accessDeniedReason to better name could be good as it's used to + // disconnect client when CSM failed. + const std::string &accessDeniedReason() const { return m_access_denied_reason; } + + bool itemdefReceived() const + { return m_itemdef_received; } + bool nodedefReceived() const + { return m_nodedef_received; } + bool mediaReceived() const + { return !m_media_downloader; } + bool activeObjectsReceived() const + { return m_activeobjects_received; } + + u16 getProtoVersion() + { return m_proto_ver; } + + bool m_simple_singleplayer_mode; + + float mediaReceiveProgress(); + + void afterContentReceived(); + void showUpdateProgressTexture(void *args, u32 progress, u32 max_progress); + + float getRTT(); + float getCurRate(); + + Minimap* getMinimap() { return m_minimap; } + void setCamera(Camera* camera) { m_camera = camera; } + + Camera* getCamera () { return m_camera; } + scene::ISceneManager *getSceneManager(); + + bool shouldShowMinimap() const; + + // IGameDef interface + IItemDefManager* getItemDefManager() override; + const NodeDefManager* getNodeDefManager() override; + ICraftDefManager* getCraftDefManager() override; + ITextureSource* getTextureSource(); + virtual IWritableShaderSource* getShaderSource(); + u16 allocateUnknownNodeId(const std::string &name) override; + virtual ISoundManager* getSoundManager(); + MtEventManager* getEventManager(); + virtual ParticleManager* getParticleManager(); + bool checkLocalPrivilege(const std::string &priv) + { return checkPrivilege(priv); } + virtual scene::IAnimatedMesh* getMesh(const std::string &filename, bool cache = false); + const std::string* getModFile(std::string filename); + ModMetadataDatabase *getModStorageDatabase() override { return m_mod_storage_database; } + + bool registerModStorage(ModMetadata *meta) override; + void unregisterModStorage(const std::string &name) override; + + // Migrates away old files-based mod storage if necessary + void migrateModStorage(); + + // The following set of functions is used by ClientMediaDownloader + // Insert a media file appropriately into the appropriate manager + bool loadMedia(const std::string &data, const std::string &filename, + bool from_media_push = false); + + // Send a request for conventional media transfer + void request_media(const std::vector<std::string> &file_requests); + + LocalClientState getState() { return m_state; } + + void makeScreenshot(); + + inline void pushToChatQueue(ChatMessage *cec) + { + m_chat_queue.push(cec); + } + + ClientScripting *getScript() { return m_script; } + bool modsLoaded() const { return m_mods_loaded; } + + void pushToEventQueue(ClientEvent *event); + + void showMinimap(bool show = true); + + const Address getServerAddress(); + + const std::string &getAddressName() const + { + return m_address_name; + } + + inline u64 getCSMRestrictionFlags() const + { + return m_csm_restriction_flags; + } + + inline bool checkCSMRestrictionFlag(CSMRestrictionFlags flag) const + { + return m_csm_restriction_flags & flag; + } + + bool joinModChannel(const std::string &channel) override; + bool leaveModChannel(const std::string &channel) override; + bool sendModChannelMessage(const std::string &channel, + const std::string &message) override; + ModChannel *getModChannel(const std::string &channel) override; + + const std::string &getFormspecPrepend() const + { + return m_env.getLocalPlayer()->formspec_prepend; + } +private: + void loadMods(); + + // Virtual methods from con::PeerHandler + void peerAdded(con::Peer *peer) override; + void deletingPeer(con::Peer *peer, bool timeout) override; + + void initLocalMapSaving(const Address &address, + const std::string &hostname, + bool is_local_server); + + void ReceiveAll(); + + void sendPlayerPos(); + + void deleteAuthData(); + // helper method shared with clientpackethandler + static AuthMechanism choseAuthMech(const u32 mechs); + + void sendInit(const std::string &playerName); + void startAuth(AuthMechanism chosen_auth_mechanism); + void sendDeletedBlocks(std::vector<v3s16> &blocks); + void sendGotBlocks(const std::vector<v3s16> &blocks); + void sendRemovedSounds(std::vector<s32> &soundList); + + // Helper function + inline std::string getPlayerName() + { return m_env.getLocalPlayer()->getName(); } + + bool canSendChatMessage() const; + + float m_packetcounter_timer = 0.0f; + float m_connection_reinit_timer = 0.1f; + float m_avg_rtt_timer = 0.0f; + float m_playerpos_send_timer = 0.0f; + IntervalLimiter m_map_timer_and_unload_interval; + + IWritableTextureSource *m_tsrc; + IWritableShaderSource *m_shsrc; + IWritableItemDefManager *m_itemdef; + NodeDefManager *m_nodedef; + ISoundManager *m_sound; + MtEventManager *m_event; + RenderingEngine *m_rendering_engine; + + + MeshUpdateThread m_mesh_update_thread; + ClientEnvironment m_env; + ParticleManager m_particle_manager; + std::unique_ptr<con::Connection> m_con; + std::string m_address_name; + ELoginRegister m_allow_login_or_register = ELoginRegister::Any; + Camera *m_camera = nullptr; + Minimap *m_minimap = nullptr; + bool m_minimap_disabled_by_server = false; + + // Server serialization version + u8 m_server_ser_ver; + + // Used version of the protocol with server + // Values smaller than 25 only mean they are smaller than 25, + // and aren't accurate. We simply just don't know, because + // the server didn't send the version back then. + // If 0, server init hasn't been received yet. + u16 m_proto_ver = 0; + + bool m_update_wielded_item = false; + Inventory *m_inventory_from_server = nullptr; + float m_inventory_from_server_age = 0.0f; + PacketCounter m_packetcounter; + // Block mesh animation parameters + float m_animation_time = 0.0f; + int m_crack_level = -1; + v3s16 m_crack_pos; + // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT + //s32 m_daynight_i; + //u32 m_daynight_ratio; + std::queue<std::wstring> m_out_chat_queue; + u32 m_last_chat_message_sent; + float m_chat_message_allowance = 5.0f; + std::queue<ChatMessage *> m_chat_queue; + + // The authentication methods we can use to enter sudo mode (=change password) + u32 m_sudo_auth_methods; + + // The seed returned by the server in TOCLIENT_INIT is stored here + u64 m_map_seed = 0; + + // Auth data + std::string m_playername; + std::string m_password; + // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE + std::string m_new_password; + // Usable by auth mechanisms. + AuthMechanism m_chosen_auth_mech; + void *m_auth_data = nullptr; + + bool m_access_denied = false; + bool m_access_denied_reconnect = false; + std::string m_access_denied_reason = ""; + std::queue<ClientEvent *> m_client_event_queue; + bool m_itemdef_received = false; + bool m_nodedef_received = false; + bool m_activeobjects_received = false; + bool m_mods_loaded = false; + + std::vector<std::string> m_remote_media_servers; + // Media downloader, only exists during init + ClientMediaDownloader *m_media_downloader; + // Set of media filenames pushed by server at runtime + std::unordered_set<std::string> m_media_pushed_files; + // Pending downloads of dynamic media (key: token) + std::vector<std::pair<u32, std::shared_ptr<SingleMediaDownloader>>> m_pending_media_downloads; + + // time_of_day speed approximation for old protocol + bool m_time_of_day_set = false; + float m_last_time_of_day_f = -1.0f; + float m_time_of_day_update_timer = 0.0f; + + // An interval for generally sending object positions and stuff + float m_recommended_send_interval = 0.1f; + + // Sounds + float m_removed_sounds_check_timer = 0.0f; + // Mapping from server sound ids to our sound ids + std::unordered_map<s32, int> m_sounds_server_to_client; + // And the other way! + std::unordered_map<int, s32> m_sounds_client_to_server; + // Relation of client id to object id + std::unordered_map<int, u16> m_sounds_to_objects; + + // Privileges + std::unordered_set<std::string> m_privileges; + + // Detached inventories + // key = name + std::unordered_map<std::string, Inventory*> m_detached_inventories; + + // Storage for mesh data for creating multiple instances of the same mesh + StringMap m_mesh_data; + + // own state + LocalClientState m_state; + + GameUI *m_game_ui; + + // Used for saving server map to disk client-side + MapDatabase *m_localdb = nullptr; + IntervalLimiter m_localdb_save_interval; + u16 m_cache_save_interval; + + // Client modding + ClientScripting *m_script = nullptr; + std::unordered_map<std::string, ModMetadata *> m_mod_storages; + ModMetadataDatabase *m_mod_storage_database = nullptr; + float m_mod_storage_save_timer = 10.0f; + std::vector<ModSpec> m_mods; + StringMap m_mod_vfs; + + bool m_shutdown = false; + + // CSM restrictions byteflag + u64 m_csm_restriction_flags = CSMRestrictionFlags::CSM_RF_NONE; + u32 m_csm_restriction_noderange = 8; + + std::unique_ptr<ModChannelMgr> m_modchannel_mgr; +}; diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp new file mode 100644 index 0000000..183a950 --- /dev/null +++ b/src/client/clientenvironment.cpp @@ -0,0 +1,515 @@ +/* +Minetest +Copyright (C) 2010-2017 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "util/serialize.h" +#include "util/pointedthing.h" +#include "client.h" +#include "clientenvironment.h" +#include "clientsimpleobject.h" +#include "clientmap.h" +#include "scripting_client.h" +#include "mapblock_mesh.h" +#include "mtevent.h" +#include "collision.h" +#include "nodedef.h" +#include "profiler.h" +#include "raycast.h" +#include "voxelalgorithms.h" +#include "settings.h" +#include "shader.h" +#include "content_cao.h" +#include <algorithm> +#include "client/renderingengine.h" + +/* + CAOShaderConstantSetter +*/ + +//! Shader constant setter for passing material emissive color to the CAO object_shader +class CAOShaderConstantSetter : public IShaderConstantSetter +{ +public: + CAOShaderConstantSetter(): + m_emissive_color_setting("emissiveColor") + {} + + ~CAOShaderConstantSetter() override = default; + + void onSetConstants(video::IMaterialRendererServices *services) override + { + // Ambient color + video::SColorf emissive_color(m_emissive_color); + + float as_array[4] = { + emissive_color.r, + emissive_color.g, + emissive_color.b, + emissive_color.a, + }; + m_emissive_color_setting.set(as_array, services); + } + + void onSetMaterial(const video::SMaterial& material) override + { + m_emissive_color = material.EmissiveColor; + } + +private: + video::SColor m_emissive_color; + CachedPixelShaderSetting<float, 4> m_emissive_color_setting; +}; + +class CAOShaderConstantSetterFactory : public IShaderConstantSetterFactory +{ +public: + CAOShaderConstantSetterFactory() + {} + + virtual IShaderConstantSetter* create() + { + return new CAOShaderConstantSetter(); + } +}; + +/* + ClientEnvironment +*/ + +ClientEnvironment::ClientEnvironment(ClientMap *map, + ITextureSource *texturesource, Client *client): + Environment(client), + m_map(map), + m_texturesource(texturesource), + m_client(client) +{ + auto *shdrsrc = m_client->getShaderSource(); + shdrsrc->addShaderConstantSetterFactory(new CAOShaderConstantSetterFactory()); +} + +ClientEnvironment::~ClientEnvironment() +{ + m_ao_manager.clear(); + + for (auto &simple_object : m_simple_objects) { + delete simple_object; + } + + // Drop/delete map + m_map->drop(); + + delete m_local_player; +} + +Map & ClientEnvironment::getMap() +{ + return *m_map; +} + +ClientMap & ClientEnvironment::getClientMap() +{ + return *m_map; +} + +void ClientEnvironment::setLocalPlayer(LocalPlayer *player) +{ + /* + It is a failure if already is a local player + */ + FATAL_ERROR_IF(m_local_player != NULL, + "Local player already allocated"); + + m_local_player = player; +} + +void ClientEnvironment::step(float dtime) +{ + /* Step time of day */ + stepTimeOfDay(dtime); + + // Get some settings + bool fly_allowed = m_client->checkLocalPrivilege("fly"); + bool free_move = fly_allowed && g_settings->getBool("free_move"); + + // Get local player + LocalPlayer *lplayer = getLocalPlayer(); + assert(lplayer); + // collision info queue + std::vector<CollisionInfo> player_collisions; + + /* + Get the speed the player is going + */ + bool is_climbing = lplayer->is_climbing; + + f32 player_speed = lplayer->getSpeed().getLength(); + + /* + Maximum position increment + */ + //f32 position_max_increment = 0.05*BS; + f32 position_max_increment = 0.1*BS; + + // Maximum time increment (for collision detection etc) + // time = distance / speed + f32 dtime_max_increment = 1; + if(player_speed > 0.001) + dtime_max_increment = position_max_increment / player_speed; + + // Maximum time increment is 10ms or lower + if(dtime_max_increment > 0.01) + dtime_max_increment = 0.01; + + // Don't allow overly huge dtime + if(dtime > 0.5) + dtime = 0.5; + + /* + Stuff that has a maximum time increment + */ + + u32 steps = ceil(dtime / dtime_max_increment); + f32 dtime_part = dtime / steps; + for (; steps > 0; --steps) { + /* + Local player handling + */ + + // Control local player + lplayer->applyControl(dtime_part, this); + + // Apply physics + if (!free_move) { + // Gravity + v3f speed = lplayer->getSpeed(); + if (!is_climbing && !lplayer->in_liquid) + speed.Y -= lplayer->movement_gravity * + lplayer->physics_override_gravity * dtime_part * 2.0f; + + // Liquid floating / sinking + if (!is_climbing && lplayer->in_liquid && + !lplayer->swimming_vertical && + !lplayer->swimming_pitch) + speed.Y -= lplayer->movement_liquid_sink * dtime_part * 2.0f; + + // Movement resistance + if (lplayer->move_resistance > 0) { + // How much the node's move_resistance blocks movement, ranges + // between 0 and 1. Should match the scale at which liquid_viscosity + // increase affects other liquid attributes. + static const f32 resistance_factor = 0.3f; + + v3f d_wanted; + bool in_liquid_stable = lplayer->in_liquid_stable || lplayer->in_liquid; + if (in_liquid_stable) { + d_wanted = -speed / lplayer->movement_liquid_fluidity; + } else { + d_wanted = -speed / BS; + } + f32 dl = d_wanted.getLength(); + if (in_liquid_stable) { + if (dl > lplayer->movement_liquid_fluidity_smooth) + dl = lplayer->movement_liquid_fluidity_smooth; + } + + dl *= (lplayer->move_resistance * resistance_factor) + + (1 - resistance_factor); + v3f d = d_wanted.normalize() * (dl * dtime_part * 100.0f); + speed += d; + } + + lplayer->setSpeed(speed); + } + + /* + Move the lplayer. + This also does collision detection. + */ + lplayer->move(dtime_part, this, position_max_increment, + &player_collisions); + } + + bool player_immortal = false; + f32 player_fall_factor = 1.0f; + GenericCAO *playercao = lplayer->getCAO(); + if (playercao) { + player_immortal = playercao->isImmortal(); + int addp_p = itemgroup_get(playercao->getGroups(), + "fall_damage_add_percent"); + // convert armor group into an usable fall damage factor + player_fall_factor = 1.0f + (float)addp_p / 100.0f; + } + + for (const CollisionInfo &info : player_collisions) { + v3f speed_diff = info.new_speed - info.old_speed;; + // Handle only fall damage + // (because otherwise walking against something in fast_move kills you) + if (speed_diff.Y < 0 || info.old_speed.Y >= 0) + continue; + // Get rid of other components + speed_diff.X = 0; + speed_diff.Z = 0; + f32 pre_factor = 1; // 1 hp per node/s + f32 tolerance = BS*14; // 5 without damage + if (info.type == COLLISION_NODE) { + const ContentFeatures &f = m_client->ndef()-> + get(m_map->getNode(info.node_p)); + // Determine fall damage modifier + int addp_n = itemgroup_get(f.groups, "fall_damage_add_percent"); + // convert node group to an usable fall damage factor + f32 node_fall_factor = 1.0f + (float)addp_n / 100.0f; + // combine both player fall damage modifiers + pre_factor = node_fall_factor * player_fall_factor; + } + float speed = pre_factor * speed_diff.getLength(); + + if (speed > tolerance && !player_immortal && pre_factor > 0.0f) { + f32 damage_f = (speed - tolerance) / BS; + u16 damage = (u16)MYMIN(damage_f + 0.5, U16_MAX); + if (damage != 0) { + damageLocalPlayer(damage, true); + m_client->getEventManager()->put( + new SimpleTriggerEvent(MtEvent::PLAYER_FALLING_DAMAGE)); + } + } + } + + if (m_client->modsLoaded()) + m_script->environment_step(dtime); + + // Update lighting on local player (used for wield item) + u32 day_night_ratio = getDayNightRatio(); + { + // Get node at head + + // On InvalidPositionException, use this as default + // (day: LIGHT_SUN, night: 0) + MapNode node_at_lplayer(CONTENT_AIR, 0x0f, 0); + + v3s16 p = lplayer->getLightPosition(); + node_at_lplayer = m_map->getNode(p); + + u16 light = getInteriorLight(node_at_lplayer, 0, m_client->ndef()); + lplayer->light_color = encode_light(light, 0); // this transfers light.alpha + final_color_blend(&lplayer->light_color, light, day_night_ratio); + } + + /* + Step active objects and update lighting of them + */ + + bool update_lighting = m_active_object_light_update_interval.step(dtime, 0.21); + auto cb_state = [this, dtime, update_lighting, day_night_ratio] (ClientActiveObject *cao) { + // Step object + cao->step(dtime, this); + + if (update_lighting) + cao->updateLight(day_night_ratio); + }; + + m_ao_manager.step(dtime, cb_state); + + /* + Step and handle simple objects + */ + g_profiler->avg("ClientEnv: CSO count [#]", m_simple_objects.size()); + for (auto i = m_simple_objects.begin(); i != m_simple_objects.end();) { + ClientSimpleObject *simple = *i; + + simple->step(dtime); + if(simple->m_to_be_removed) { + delete simple; + i = m_simple_objects.erase(i); + } + else { + ++i; + } + } +} + +void ClientEnvironment::addSimpleObject(ClientSimpleObject *simple) +{ + m_simple_objects.push_back(simple); +} + +GenericCAO* ClientEnvironment::getGenericCAO(u16 id) +{ + ClientActiveObject *obj = getActiveObject(id); + if (obj && obj->getType() == ACTIVEOBJECT_TYPE_GENERIC) + return (GenericCAO*) obj; + + return NULL; +} + +u16 ClientEnvironment::addActiveObject(ClientActiveObject *object) +{ + // Register object. If failed return zero id + if (!m_ao_manager.registerObject(object)) + return 0; + + object->addToScene(m_texturesource, m_client->getSceneManager()); + + // Update lighting immediately + object->updateLight(getDayNightRatio()); + return object->getId(); +} + +void ClientEnvironment::addActiveObject(u16 id, u8 type, + const std::string &init_data) +{ + ClientActiveObject* obj = + ClientActiveObject::create((ActiveObjectType) type, m_client, this); + if(obj == NULL) + { + infostream<<"ClientEnvironment::addActiveObject(): " + <<"id="<<id<<" type="<<type<<": Couldn't create object" + <<std::endl; + return; + } + + obj->setId(id); + + try + { + obj->initialize(init_data); + } + catch(SerializationError &e) + { + errorstream<<"ClientEnvironment::addActiveObject():" + <<" id="<<id<<" type="<<type + <<": SerializationError in initialize(): " + <<e.what() + <<": init_data="<<serializeJsonString(init_data) + <<std::endl; + } + + u16 new_id = addActiveObject(obj); + // Object initialized: + if ((obj = getActiveObject(new_id))) { + // Final step is to update all children which are already known + // Data provided by AO_CMD_SPAWN_INFANT + const auto &children = obj->getAttachmentChildIds(); + for (auto c_id : children) { + if (auto *o = getActiveObject(c_id)) + o->updateAttachments(); + } + } +} + + +void ClientEnvironment::removeActiveObject(u16 id) +{ + // Get current attachment childs to detach them visually + std::unordered_set<int> attachment_childs; + if (auto *obj = getActiveObject(id)) + attachment_childs = obj->getAttachmentChildIds(); + + m_ao_manager.removeObject(id); + + // Perform a proper detach in Irrlicht + for (auto c_id : attachment_childs) { + if (ClientActiveObject *child = getActiveObject(c_id)) + child->updateAttachments(); + } +} + +void ClientEnvironment::processActiveObjectMessage(u16 id, const std::string &data) +{ + ClientActiveObject *obj = getActiveObject(id); + if (obj == NULL) { + infostream << "ClientEnvironment::processActiveObjectMessage():" + << " got message for id=" << id << ", which doesn't exist." + << std::endl; + return; + } + + try { + obj->processMessage(data); + } catch (SerializationError &e) { + errorstream<<"ClientEnvironment::processActiveObjectMessage():" + << " id=" << id << " type=" << obj->getType() + << " SerializationError in processMessage(): " << e.what() + << std::endl; + } +} + +/* + Callbacks for activeobjects +*/ + +void ClientEnvironment::damageLocalPlayer(u16 damage, bool handle_hp) +{ + LocalPlayer *lplayer = getLocalPlayer(); + assert(lplayer); + + if (handle_hp) { + if (lplayer->hp > damage) + lplayer->hp -= damage; + else + lplayer->hp = 0; + } + + ClientEnvEvent event; + event.type = CEE_PLAYER_DAMAGE; + event.player_damage.amount = damage; + event.player_damage.send_to_server = handle_hp; + m_client_event_queue.push(event); +} + +/* + Client likes to call these +*/ + +ClientEnvEvent ClientEnvironment::getClientEnvEvent() +{ + FATAL_ERROR_IF(m_client_event_queue.empty(), + "ClientEnvironment::getClientEnvEvent(): queue is empty"); + + ClientEnvEvent event = m_client_event_queue.front(); + m_client_event_queue.pop(); + return event; +} + +void ClientEnvironment::getSelectedActiveObjects( + const core::line3d<f32> &shootline_on_map, + std::vector<PointedThing> &objects) +{ + std::vector<DistanceSortedActiveObject> allObjects; + getActiveObjects(shootline_on_map.start, + shootline_on_map.getLength() + 10.0f, allObjects); + const v3f line_vector = shootline_on_map.getVector(); + + for (const auto &allObject : allObjects) { + ClientActiveObject *obj = allObject.obj; + aabb3f selection_box; + if (!obj->getSelectionBox(&selection_box)) + continue; + + const v3f &pos = obj->getPosition(); + aabb3f offsetted_box(selection_box.MinEdge + pos, + selection_box.MaxEdge + pos); + + v3f current_intersection; + v3s16 current_normal; + if (boxLineCollision(offsetted_box, shootline_on_map.start, line_vector, + ¤t_intersection, ¤t_normal)) { + objects.emplace_back((s16) obj->getId(), current_intersection, current_normal, + (current_intersection - shootline_on_map.start).getLengthSQ()); + } + } +} diff --git a/src/client/clientenvironment.h b/src/client/clientenvironment.h new file mode 100644 index 0000000..864496a --- /dev/null +++ b/src/client/clientenvironment.h @@ -0,0 +1,156 @@ +/* +Minetest +Copyright (C) 2010-2017 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "environment.h" +#include <ISceneManager.h> +#include "clientobject.h" +#include "util/numeric.h" +#include "activeobjectmgr.h" + +class ClientSimpleObject; +class ClientMap; +class ClientScripting; +class ClientActiveObject; +class GenericCAO; +class LocalPlayer; + +/* + The client-side environment. + + This is not thread-safe. + Must be called from main (irrlicht) thread (uses the SceneManager) + Client uses an environment mutex. +*/ + +enum ClientEnvEventType +{ + CEE_NONE, + CEE_PLAYER_DAMAGE +}; + +struct ClientEnvEvent +{ + ClientEnvEventType type; + union { + //struct{ + //} none; + struct{ + u16 amount; + bool send_to_server; + } player_damage; + }; +}; + +typedef std::unordered_map<u16, ClientActiveObject*> ClientActiveObjectMap; +class ClientEnvironment : public Environment +{ +public: + ClientEnvironment(ClientMap *map, ITextureSource *texturesource, Client *client); + ~ClientEnvironment(); + + Map & getMap(); + ClientMap & getClientMap(); + + Client *getGameDef() { return m_client; } + void setScript(ClientScripting *script) { m_script = script; } + + void step(f32 dtime); + + virtual void setLocalPlayer(LocalPlayer *player); + LocalPlayer *getLocalPlayer() const { return m_local_player; } + + /* + ClientSimpleObjects + */ + + void addSimpleObject(ClientSimpleObject *simple); + + /* + ActiveObjects + */ + + GenericCAO* getGenericCAO(u16 id); + ClientActiveObject* getActiveObject(u16 id) + { + return m_ao_manager.getActiveObject(id); + } + + /* + Adds an active object to the environment. + Environment handles deletion of object. + Object may be deleted by environment immediately. + If id of object is 0, assigns a free id to it. + Returns the id of the object. + Returns 0 if not added and thus deleted. + */ + u16 addActiveObject(ClientActiveObject *object); + + void addActiveObject(u16 id, u8 type, const std::string &init_data); + void removeActiveObject(u16 id); + + void processActiveObjectMessage(u16 id, const std::string &data); + + /* + Callbacks for activeobjects + */ + + void damageLocalPlayer(u16 damage, bool handle_hp=true); + + /* + Client likes to call these + */ + + // Get all nearby objects + void getActiveObjects(const v3f &origin, f32 max_d, + std::vector<DistanceSortedActiveObject> &dest) + { + return m_ao_manager.getActiveObjects(origin, max_d, dest); + } + + bool hasClientEnvEvents() const { return !m_client_event_queue.empty(); } + + // Get event from queue. If queue is empty, it triggers an assertion failure. + ClientEnvEvent getClientEnvEvent(); + + virtual void getSelectedActiveObjects( + const core::line3d<f32> &shootline_on_map, + std::vector<PointedThing> &objects + ); + + const std::list<std::string> &getPlayerNames() { return m_player_names; } + void addPlayerName(const std::string &name) { m_player_names.push_back(name); } + void removePlayerName(const std::string &name) { m_player_names.remove(name); } + void updateCameraOffset(const v3s16 &camera_offset) + { m_camera_offset = camera_offset; } + v3s16 getCameraOffset() const { return m_camera_offset; } +private: + ClientMap *m_map; + LocalPlayer *m_local_player = nullptr; + ITextureSource *m_texturesource; + Client *m_client; + ClientScripting *m_script = nullptr; + client::ActiveObjectMgr m_ao_manager; + std::vector<ClientSimpleObject*> m_simple_objects; + std::queue<ClientEnvEvent> m_client_event_queue; + IntervalLimiter m_active_object_light_update_interval; + std::list<std::string> m_player_names; + v3s16 m_camera_offset; +}; diff --git a/src/client/clientevent.h b/src/client/clientevent.h new file mode 100644 index 0000000..243a945 --- /dev/null +++ b/src/client/clientevent.h @@ -0,0 +1,148 @@ +/* +Minetest +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include "irrlichttypes_bloated.h" + +struct ParticleParameters; +struct ParticleSpawnerParameters; +struct SkyboxParams; +struct SunParams; +struct MoonParams; +struct StarParams; + +enum ClientEventType : u8 +{ + CE_NONE, + CE_PLAYER_DAMAGE, + CE_PLAYER_FORCE_MOVE, + CE_DEATHSCREEN, + CE_SHOW_FORMSPEC, + CE_SHOW_LOCAL_FORMSPEC, + CE_SPAWN_PARTICLE, + CE_ADD_PARTICLESPAWNER, + CE_DELETE_PARTICLESPAWNER, + CE_HUDADD, + CE_HUDRM, + CE_HUDCHANGE, + CE_SET_SKY, + CE_SET_SUN, + CE_SET_MOON, + CE_SET_STARS, + CE_OVERRIDE_DAY_NIGHT_RATIO, + CE_CLOUD_PARAMS, + CLIENTEVENT_MAX, +}; + +struct ClientEventHudAdd +{ + u32 server_id; + u8 type; + v2f pos, scale; + std::string name; + std::string text, text2; + u32 number, item, dir, style; + v2f align, offset; + v3f world_pos; + v2s32 size; + s16 z_index; +}; + +struct ClientEventHudChange +{ + u32 id; + HudElementStat stat; + v2f v2fdata; + std::string sdata; + u32 data; + v3f v3fdata; + v2s32 v2s32data; +}; + +struct ClientEvent +{ + ClientEventType type; + union + { + // struct{ + //} none; + struct + { + u16 amount; + bool effect; + } player_damage; + struct + { + f32 pitch; + f32 yaw; + } player_force_move; + struct + { + bool set_camera_point_target; + f32 camera_point_target_x; + f32 camera_point_target_y; + f32 camera_point_target_z; + } deathscreen; + struct + { + std::string *formspec; + std::string *formname; + } show_formspec; + // struct{ + //} textures_updated; + ParticleParameters *spawn_particle; + struct + { + ParticleSpawnerParameters *p; + u16 attached_id; + u64 id; + } add_particlespawner; + struct + { + u32 id; + } delete_particlespawner; + ClientEventHudAdd *hudadd; + struct + { + u32 id; + } hudrm; + ClientEventHudChange *hudchange; + SkyboxParams *set_sky; + struct + { + bool do_override; + float ratio_f; + } override_day_night_ratio; + struct + { + f32 density; + u32 color_bright; + u32 color_ambient; + f32 height; + f32 thickness; + f32 speed_x; + f32 speed_y; + } cloud_params; + SunParams *sun_params; + MoonParams *moon_params; + StarParams *star_params; + }; +}; diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp new file mode 100644 index 0000000..60c9525 --- /dev/null +++ b/src/client/clientlauncher.cpp @@ -0,0 +1,662 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "gui/mainmenumanager.h" +#include "clouds.h" +#include "server.h" +#include "filesys.h" +#include "gui/guiMainMenu.h" +#include "game.h" +#include "player.h" +#include "chat.h" +#include "gettext.h" +#include "profiler.h" +#include "serverlist.h" +#include "gui/guiEngine.h" +#include "fontengine.h" +#include "clientlauncher.h" +#include "version.h" +#include "renderingengine.h" +#include "network/networkexceptions.h" + +#if USE_SOUND + #include "sound_openal.h" +#endif + +/* mainmenumanager.h + */ +gui::IGUIEnvironment *guienv = nullptr; +gui::IGUIStaticText *guiroot = nullptr; +MainMenuManager g_menumgr; + +bool isMenuActive() +{ + return g_menumgr.menuCount() != 0; +} + +// Passed to menus to allow disconnecting and exiting +MainGameCallback *g_gamecallback = nullptr; + +#if 0 +// This can be helpful for the next code cleanup +static void dump_start_data(const GameStartData &data) +{ + std::cout << + "\ndedicated " << (int)data.is_dedicated_server << + "\nport " << data.socket_port << + "\nworld_path " << data.world_spec.path << + "\nworld game " << data.world_spec.gameid << + "\ngame path " << data.game_spec.path << + "\nplayer name " << data.name << + "\naddress " << data.address << std::endl; +} +#endif + +ClientLauncher::~ClientLauncher() +{ + delete input; + + delete receiver; + + delete g_fontengine; + delete g_gamecallback; + + delete m_rendering_engine; + +#if USE_SOUND + g_sound_manager_singleton.reset(); +#endif +} + + +bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args) +{ + /* This function is called when a client must be started. + * Covered cases: + * - Singleplayer (address but map provided) + * - Join server (no map but address provided) + * - Local server (for main menu only) + */ + + init_args(start_data, cmd_args); + +#if USE_SOUND + if (g_settings->getBool("enable_sound")) + g_sound_manager_singleton = createSoundManagerSingleton(); +#endif + + if (!init_engine()) { + errorstream << "Could not initialize game engine." << std::endl; + return false; + } + + // Speed tests (done after irrlicht is loaded to get timer) + if (cmd_args.getFlag("speedtests")) { + dstream << "Running speed tests" << std::endl; + speed_tests(); + return true; + } + + if (m_rendering_engine->get_video_driver() == NULL) { + errorstream << "Could not initialize video driver." << std::endl; + return false; + } + + m_rendering_engine->setupTopLevelWindow(PROJECT_NAME_C); + + /* + This changes the minimum allowed number of vertices in a VBO. + Default is 500. + */ + //driver->setMinHardwareBufferVertexCount(50); + + // Create game callback for menus + g_gamecallback = new MainGameCallback(); + + m_rendering_engine->setResizable(true); + + init_input(); + + m_rendering_engine->get_scene_manager()->getParameters()-> + setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); + + guienv = m_rendering_engine->get_gui_env(); + skin = guienv->getSkin(); + skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255)); + skin->setColor(gui::EGDC_3D_LIGHT, video::SColor(0, 0, 0, 0)); + skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 30, 30, 30)); + skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255, 0, 0, 0)); + skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255, 70, 120, 50)); + skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255, 255, 255, 255)); +#ifdef HAVE_TOUCHSCREENGUI + float density = RenderingEngine::getDisplayDensity(); + skin->setSize(gui::EGDS_CHECK_BOX_WIDTH, (s32)(17.0f * density)); + skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(14.0f * density)); + skin->setSize(gui::EGDS_WINDOW_BUTTON_WIDTH, (s32)(15.0f * density)); + if (density > 1.5f) { + std::string sprite_path = porting::path_user + "/textures/base/pack/"; + if (density > 3.5f) + sprite_path.append("checkbox_64.png"); + else if (density > 2.0f) + sprite_path.append("checkbox_32.png"); + else + sprite_path.append("checkbox_16.png"); + // Texture dimensions should be a power of 2 + gui::IGUISpriteBank *sprites = skin->getSpriteBank(); + video::IVideoDriver *driver = m_rendering_engine->get_video_driver(); + video::ITexture *sprite_texture = driver->getTexture(sprite_path.c_str()); + if (sprite_texture) { + s32 sprite_id = sprites->addTextureAsSprite(sprite_texture); + if (sprite_id != -1) + skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, sprite_id); + } + } +#endif + g_fontengine = new FontEngine(guienv); + FATAL_ERROR_IF(g_fontengine == NULL, "Font engine creation failed."); + + // Irrlicht 1.8 input colours + skin->setColor(gui::EGDC_EDITABLE, video::SColor(255, 128, 128, 128)); + skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255, 96, 134, 49)); + + // Create the menu clouds + if (!g_menucloudsmgr) + g_menucloudsmgr = m_rendering_engine->get_scene_manager()->createNewSceneManager(); + if (!g_menuclouds) + g_menuclouds = new Clouds(g_menucloudsmgr, -1, rand()); + g_menuclouds->setHeight(100.0f); + g_menuclouds->update(v3f(0, 0, 0), video::SColor(255, 240, 240, 255)); + scene::ICameraSceneNode* camera; + camera = g_menucloudsmgr->addCameraSceneNode(NULL, v3f(0, 0, 0), v3f(0, 60, 100)); + camera->setFarValue(10000); + + /* + GUI stuff + */ + + ChatBackend chat_backend; + + // If an error occurs, this is set to something by menu(). + // It is then displayed before the menu shows on the next call to menu() + std::string error_message; + bool reconnect_requested = false; + + bool first_loop = true; + + /* + Menu-game loop + */ + bool retval = true; + bool *kill = porting::signal_handler_killstatus(); + + while (m_rendering_engine->run() && !*kill && + !g_gamecallback->shutdown_requested) { + // Set the window caption + const wchar_t *text = wgettext("Main Menu"); + m_rendering_engine->get_raw_device()-> + setWindowCaption((utf8_to_wide(PROJECT_NAME_C) + + L" " + utf8_to_wide(g_version_hash) + + L" [" + text + L"]").c_str()); + delete[] text; + + try { // This is used for catching disconnects + + m_rendering_engine->get_gui_env()->clear(); + + /* + We need some kind of a root node to be able to add + custom gui elements directly on the screen. + Otherwise they won't be automatically drawn. + */ + guiroot = m_rendering_engine->get_gui_env()->addStaticText(L"", + core::rect<s32>(0, 0, 10000, 10000)); + + bool game_has_run = launch_game(error_message, reconnect_requested, + start_data, cmd_args); + + // Reset the reconnect_requested flag + reconnect_requested = false; + + // If skip_main_menu, we only want to startup once + if (skip_main_menu && !first_loop) + break; + + first_loop = false; + + if (!game_has_run) { + if (skip_main_menu) + break; + + continue; + } + + // Break out of menu-game loop to shut down cleanly + if (!m_rendering_engine->run() || *kill) { + if (!g_settings_path.empty()) + g_settings->updateConfigFile(g_settings_path.c_str()); + break; + } + + m_rendering_engine->get_video_driver()->setTextureCreationFlag( + video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map")); + +#ifdef HAVE_TOUCHSCREENGUI + receiver->m_touchscreengui = new TouchScreenGUI(m_rendering_engine->get_raw_device(), receiver); + g_touchscreengui = receiver->m_touchscreengui; +#endif + + the_game( + kill, + input, + m_rendering_engine, + start_data, + error_message, + chat_backend, + &reconnect_requested + ); + } //try + catch (con::PeerNotFoundException &e) { + error_message = gettext("Connection error (timed out?)"); + errorstream << error_message << std::endl; + } + +#ifdef NDEBUG + catch (std::exception &e) { + std::string error_message = "Some exception: \""; + error_message += e.what(); + error_message += "\""; + errorstream << error_message << std::endl; + } +#endif + + m_rendering_engine->get_scene_manager()->clear(); + +#ifdef HAVE_TOUCHSCREENGUI + delete g_touchscreengui; + g_touchscreengui = NULL; + receiver->m_touchscreengui = NULL; +#endif + + // If no main menu, show error and exit + if (skip_main_menu) { + if (!error_message.empty()) { + verbosestream << "error_message = " + << error_message << std::endl; + retval = false; + } + break; + } + } // Menu-game loop + + g_menuclouds->drop(); + g_menucloudsmgr->drop(); + + return retval; +} + +void ClientLauncher::init_args(GameStartData &start_data, const Settings &cmd_args) +{ + skip_main_menu = cmd_args.getFlag("go"); + + start_data.address = g_settings->get("address"); + if (cmd_args.exists("address")) { + // Join a remote server + start_data.address = cmd_args.get("address"); + start_data.world_path.clear(); + start_data.name = g_settings->get("name"); + } + if (!start_data.world_path.empty()) { + // Start a singleplayer instance + start_data.address = ""; + } + + if (cmd_args.exists("name")) + start_data.name = cmd_args.get("name"); + + random_input = g_settings->getBool("random_input") + || cmd_args.getFlag("random-input"); +} + +bool ClientLauncher::init_engine() +{ + receiver = new MyEventReceiver(); + m_rendering_engine = new RenderingEngine(receiver); + return m_rendering_engine->get_raw_device() != nullptr; +} + +void ClientLauncher::init_input() +{ + if (random_input) + input = new RandomInputHandler(); + else + input = new RealInputHandler(receiver); + + if (g_settings->getBool("enable_joysticks")) { + irr::core::array<irr::SJoystickInfo> infos; + std::vector<irr::SJoystickInfo> joystick_infos; + + // Make sure this is called maximum once per + // irrlicht device, otherwise it will give you + // multiple events for the same joystick. + if (m_rendering_engine->get_raw_device()->activateJoysticks(infos)) { + infostream << "Joystick support enabled" << std::endl; + joystick_infos.reserve(infos.size()); + for (u32 i = 0; i < infos.size(); i++) { + joystick_infos.push_back(infos[i]); + } + input->joystick.onJoystickConnect(joystick_infos); + } else { + errorstream << "Could not activate joystick support." << std::endl; + } + } +} + +bool ClientLauncher::launch_game(std::string &error_message, + bool reconnect_requested, GameStartData &start_data, + const Settings &cmd_args) +{ + // Prepare and check the start data to launch a game + std::string error_message_lua = error_message; + error_message.clear(); + + if (cmd_args.exists("password")) + start_data.password = cmd_args.get("password"); + + if (cmd_args.exists("password-file")) { + std::ifstream passfile(cmd_args.get("password-file")); + if (passfile.good()) { + getline(passfile, start_data.password); + } else { + error_message = gettext("Provided password file " + "failed to open: ") + + cmd_args.get("password-file"); + errorstream << error_message << std::endl; + return false; + } + } + + // If a world was commanded, append and select it + // This is provieded by "get_world_from_cmdline()", main.cpp + if (!start_data.world_path.empty()) { + auto &spec = start_data.world_spec; + + spec.path = start_data.world_path; + spec.gameid = getWorldGameId(spec.path, true); + spec.name = _("[--world parameter]"); + + if (spec.gameid.empty()) { // Create new + spec.gameid = g_settings->get("default_game"); + spec.name += " [new]"; + } + } + + /* Show the GUI menu + */ + std::string server_name, server_description; + if (!skip_main_menu) { + // Initialize menu data + // TODO: Re-use existing structs (GameStartData) + MainMenuData menudata; + menudata.address = start_data.address; + menudata.name = start_data.name; + menudata.password = start_data.password; + menudata.port = itos(start_data.socket_port); + menudata.script_data.errormessage = error_message_lua; + menudata.script_data.reconnect_requested = reconnect_requested; + + main_menu(&menudata); + + // Skip further loading if there was an exit signal. + if (*porting::signal_handler_killstatus()) + return false; + + if (!menudata.script_data.errormessage.empty()) { + /* The calling function will pass this back into this function upon the + * next iteration (if any) causing it to be displayed by the GUI + */ + error_message = menudata.script_data.errormessage; + return false; + } + + int newport = stoi(menudata.port); + if (newport != 0) + start_data.socket_port = newport; + + // Update world information using main menu data + std::vector<WorldSpec> worldspecs = getAvailableWorlds(); + + int world_index = menudata.selected_world; + if (world_index >= 0 && world_index < (int)worldspecs.size()) { + g_settings->set("selected_world_path", + worldspecs[world_index].path); + start_data.world_spec = worldspecs[world_index]; + } + + start_data.name = menudata.name; + start_data.password = menudata.password; + start_data.address = std::move(menudata.address); + start_data.allow_login_or_register = menudata.allow_login_or_register; + server_name = menudata.servername; + server_description = menudata.serverdescription; + + start_data.local_server = !menudata.simple_singleplayer_mode && + start_data.address.empty(); + } else { + start_data.local_server = !start_data.world_path.empty() && + start_data.address.empty() && !start_data.name.empty(); + } + + if (!m_rendering_engine->run()) + return false; + + if (!start_data.isSinglePlayer() && start_data.name.empty()) { + error_message = gettext("Please choose a name!"); + errorstream << error_message << std::endl; + return false; + } + + // If using simple singleplayer mode, override + if (start_data.isSinglePlayer()) { + start_data.name = "singleplayer"; + start_data.password = ""; + start_data.socket_port = myrand_range(49152, 65535); + } else { + g_settings->set("name", start_data.name); + } + + if (start_data.name.length() > PLAYERNAME_SIZE - 1) { + error_message = gettext("Player name too long."); + start_data.name.resize(PLAYERNAME_SIZE); + g_settings->set("name", start_data.name); + return false; + } + + auto &worldspec = start_data.world_spec; + infostream << "Selected world: " << worldspec.name + << " [" << worldspec.path << "]" << std::endl; + + if (start_data.address.empty()) { + // For singleplayer and local server + if (worldspec.path.empty()) { + error_message = gettext("No world selected and no address " + "provided. Nothing to do."); + errorstream << error_message << std::endl; + return false; + } + + if (!fs::PathExists(worldspec.path)) { + error_message = gettext("Provided world path doesn't exist: ") + + worldspec.path; + errorstream << error_message << std::endl; + return false; + } + + // Load gamespec for required game + start_data.game_spec = findWorldSubgame(worldspec.path); + if (!start_data.game_spec.isValid()) { + error_message = gettext("Could not find or load game: ") + + worldspec.gameid; + errorstream << error_message << std::endl; + return false; + } + + if (porting::signal_handler_killstatus()) + return true; + + if (!start_data.game_spec.isValid()) { + error_message = gettext("Invalid gamespec."); + error_message += " (world.gameid=" + worldspec.gameid + ")"; + errorstream << error_message << std::endl; + return false; + } + } + + start_data.world_path = start_data.world_spec.path; + return true; +} + +void ClientLauncher::main_menu(MainMenuData *menudata) +{ + bool *kill = porting::signal_handler_killstatus(); + video::IVideoDriver *driver = m_rendering_engine->get_video_driver(); + + infostream << "Waiting for other menus" << std::endl; + while (m_rendering_engine->run() && !*kill) { + if (!isMenuActive()) + break; + driver->beginScene(true, true, video::SColor(255, 128, 128, 128)); + m_rendering_engine->get_gui_env()->drawAll(); + driver->endScene(); + // On some computers framerate doesn't seem to be automatically limited + sleep_ms(25); + } + infostream << "Waited for other menus" << std::endl; + + // Cursor can be non-visible when coming from the game +#ifndef ANDROID + m_rendering_engine->get_raw_device()->getCursorControl()->setVisible(true); +#endif + + /* show main menu */ + GUIEngine mymenu(&input->joystick, guiroot, m_rendering_engine, &g_menumgr, menudata, *kill); + + /* leave scene manager in a clean state */ + m_rendering_engine->get_scene_manager()->clear(); +} + +void ClientLauncher::speed_tests() +{ + // volatile to avoid some potential compiler optimisations + volatile static s16 temp16; + volatile static f32 tempf; + // Silence compiler warning + (void)temp16; + static v3f tempv3f1; + static v3f tempv3f2; + static std::string tempstring; + static std::string tempstring2; + + tempv3f1 = v3f(); + tempv3f2 = v3f(); + tempstring.clear(); + tempstring2.clear(); + + { + infostream << "The following test should take around 20ms." << std::endl; + TimeTaker timer("Testing std::string speed"); + const u32 jj = 10000; + for (u32 j = 0; j < jj; j++) { + tempstring = ""; + tempstring2 = ""; + const u32 ii = 10; + for (u32 i = 0; i < ii; i++) { + tempstring2 += "asd"; + } + for (u32 i = 0; i < ii+1; i++) { + tempstring += "asd"; + if (tempstring == tempstring2) + break; + } + } + } + + infostream << "All of the following tests should take around 100ms each." + << std::endl; + + { + TimeTaker timer("Testing floating-point conversion speed"); + tempf = 0.001; + for (u32 i = 0; i < 4000000; i++) { + temp16 += tempf; + tempf += 0.001; + } + } + + { + TimeTaker timer("Testing floating-point vector speed"); + + tempv3f1 = v3f(1, 2, 3); + tempv3f2 = v3f(4, 5, 6); + for (u32 i = 0; i < 10000000; i++) { + tempf += tempv3f1.dotProduct(tempv3f2); + tempv3f2 += v3f(7, 8, 9); + } + } + + { + TimeTaker timer("Testing std::map speed"); + + std::map<v2s16, f32> map1; + tempf = -324; + const s16 ii = 300; + for (s16 y = 0; y < ii; y++) { + for (s16 x = 0; x < ii; x++) { + map1[v2s16(x, y)] = tempf; + tempf += 1; + } + } + for (s16 y = ii - 1; y >= 0; y--) { + for (s16 x = 0; x < ii; x++) { + tempf = map1[v2s16(x, y)]; + } + } + } + + { + infostream << "Around 5000/ms should do well here." << std::endl; + TimeTaker timer("Testing mutex speed"); + + std::mutex m; + u32 n = 0; + u32 i = 0; + do { + n += 10000; + for (; i < n; i++) { + m.lock(); + m.unlock(); + } + } + // Do at least 10ms + while(timer.getTimerTime() < 10); + + u32 dtime = timer.stop(); + u32 per_ms = n / dtime; + infostream << "Done. " << dtime << "ms, " << per_ms << "/ms" << std::endl; + } +} diff --git a/src/client/clientlauncher.h b/src/client/clientlauncher.h new file mode 100644 index 0000000..d1fd9a2 --- /dev/null +++ b/src/client/clientlauncher.h @@ -0,0 +1,55 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "client/inputhandler.h" +#include "gameparams.h" + +class RenderingEngine; + +class ClientLauncher +{ +public: + ClientLauncher() = default; + + ~ClientLauncher(); + + bool run(GameStartData &start_data, const Settings &cmd_args); + +private: + void init_args(GameStartData &start_data, const Settings &cmd_args); + bool init_engine(); + void init_input(); + + bool launch_game(std::string &error_message, bool reconnect_requested, + GameStartData &start_data, const Settings &cmd_args); + + void main_menu(MainMenuData *menudata); + + void speed_tests(); + + bool skip_main_menu = false; + bool random_input = false; + RenderingEngine *m_rendering_engine = nullptr; + InputHandler *input = nullptr; + MyEventReceiver *receiver = nullptr; + gui::IGUISkin *skin = nullptr; +}; diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp new file mode 100644 index 0000000..c5ba98f --- /dev/null +++ b/src/client/clientmap.cpp @@ -0,0 +1,964 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "clientmap.h" +#include "client.h" +#include "mapblock_mesh.h" +#include <IMaterialRenderer.h> +#include <matrix4.h> +#include "mapsector.h" +#include "mapblock.h" +#include "profiler.h" +#include "settings.h" +#include "camera.h" // CameraModes +#include "util/basic_macros.h" +#include <algorithm> +#include "client/renderingengine.h" + +// struct MeshBufListList +void MeshBufListList::clear() +{ + for (auto &list : lists) + list.clear(); +} + +void MeshBufListList::add(scene::IMeshBuffer *buf, v3s16 position, u8 layer) +{ + // Append to the correct layer + std::vector<MeshBufList> &list = lists[layer]; + const video::SMaterial &m = buf->getMaterial(); + for (MeshBufList &l : list) { + // comparing a full material is quite expensive so we don't do it if + // not even first texture is equal + if (l.m.TextureLayer[0].Texture != m.TextureLayer[0].Texture) + continue; + + if (l.m == m) { + l.bufs.emplace_back(position, buf); + return; + } + } + MeshBufList l; + l.m = m; + l.bufs.emplace_back(position, buf); + list.emplace_back(l); +} + +// ClientMap + +ClientMap::ClientMap( + Client *client, + RenderingEngine *rendering_engine, + MapDrawControl &control, + s32 id +): + Map(client), + scene::ISceneNode(rendering_engine->get_scene_manager()->getRootSceneNode(), + rendering_engine->get_scene_manager(), id), + m_client(client), + m_rendering_engine(rendering_engine), + m_control(control), + m_drawlist(MapBlockComparer(v3s16(0,0,0))) +{ + + /* + * @Liso: Sadly C++ doesn't have introspection, so the only way we have to know + * the class is whith a name ;) Name property cames from ISceneNode base class. + */ + Name = "ClientMap"; + m_box = aabb3f(-BS*1000000,-BS*1000000,-BS*1000000, + BS*1000000,BS*1000000,BS*1000000); + + /* TODO: Add a callback function so these can be updated when a setting + * changes. At this point in time it doesn't matter (e.g. /set + * is documented to change server settings only) + * + * TODO: Local caching of settings is not optimal and should at some stage + * be updated to use a global settings object for getting thse values + * (as opposed to the this local caching). This can be addressed in + * a later release. + */ + m_cache_trilinear_filter = g_settings->getBool("trilinear_filter"); + m_cache_bilinear_filter = g_settings->getBool("bilinear_filter"); + m_cache_anistropic_filter = g_settings->getBool("anisotropic_filter"); + m_cache_transparency_sorting_distance = g_settings->getU16("transparency_sorting_distance"); + +} + +void ClientMap::updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset) +{ + v3s16 previous_node = floatToInt(m_camera_position, BS) + m_camera_offset; + v3s16 previous_block = getContainerPos(previous_node, MAP_BLOCKSIZE); + + m_camera_position = pos; + m_camera_direction = dir; + m_camera_fov = fov; + m_camera_offset = offset; + + v3s16 current_node = floatToInt(m_camera_position, BS) + m_camera_offset; + v3s16 current_block = getContainerPos(current_node, MAP_BLOCKSIZE); + + // reorder the blocks when camera crosses block boundary + if (previous_block != current_block) + m_needs_update_drawlist = true; + + // reorder transparent meshes when camera crosses node boundary + if (previous_node != current_node) + m_needs_update_transparent_meshes = true; +} + +MapSector * ClientMap::emergeSector(v2s16 p2d) +{ + // Check that it doesn't exist already + MapSector *sector = getSectorNoGenerate(p2d); + + // Create it if it does not exist yet + if (!sector) { + sector = new MapSector(this, p2d, m_gamedef); + m_sectors[p2d] = sector; + } + + return sector; +} + +void ClientMap::OnRegisterSceneNode() +{ + if(IsVisible) + { + SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); + SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); + } + + ISceneNode::OnRegisterSceneNode(); + + if (!m_added_to_shadow_renderer) { + m_added_to_shadow_renderer = true; + if (auto shadows = m_rendering_engine->get_shadow_renderer()) + shadows->addNodeToShadowList(this); + } +} + +void ClientMap::getBlocksInViewRange(v3s16 cam_pos_nodes, + v3s16 *p_blocks_min, v3s16 *p_blocks_max, float range) +{ + if (range <= 0.0f) + range = m_control.wanted_range; + + v3s16 box_nodes_d = range * v3s16(1, 1, 1); + // Define p_nodes_min/max as v3s32 because 'cam_pos_nodes -/+ box_nodes_d' + // can exceed the range of v3s16 when a large view range is used near the + // world edges. + v3s32 p_nodes_min( + cam_pos_nodes.X - box_nodes_d.X, + cam_pos_nodes.Y - box_nodes_d.Y, + cam_pos_nodes.Z - box_nodes_d.Z); + v3s32 p_nodes_max( + cam_pos_nodes.X + box_nodes_d.X, + cam_pos_nodes.Y + box_nodes_d.Y, + cam_pos_nodes.Z + box_nodes_d.Z); + // Take a fair amount as we will be dropping more out later + // Umm... these additions are a bit strange but they are needed. + *p_blocks_min = v3s16( + p_nodes_min.X / MAP_BLOCKSIZE - 3, + p_nodes_min.Y / MAP_BLOCKSIZE - 3, + p_nodes_min.Z / MAP_BLOCKSIZE - 3); + *p_blocks_max = v3s16( + p_nodes_max.X / MAP_BLOCKSIZE + 1, + p_nodes_max.Y / MAP_BLOCKSIZE + 1, + p_nodes_max.Z / MAP_BLOCKSIZE + 1); +} + +void ClientMap::updateDrawList() +{ + ScopeProfiler sp(g_profiler, "CM::updateDrawList()", SPT_AVG); + + m_needs_update_drawlist = false; + + for (auto &i : m_drawlist) { + MapBlock *block = i.second; + block->refDrop(); + } + m_drawlist.clear(); + + const v3f camera_position = m_camera_position; + const v3f camera_direction = m_camera_direction; + + // Use a higher fov to accomodate faster camera movements. + // Blocks are cropped better when they are drawn. + const f32 camera_fov = m_camera_fov * 1.1f; + + v3s16 cam_pos_nodes = floatToInt(camera_position, BS); + + v3s16 p_blocks_min; + v3s16 p_blocks_max; + getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max); + + // Read the vision range, unless unlimited range is enabled. + float range = m_control.range_all ? 1e7 : m_control.wanted_range; + + // Number of blocks currently loaded by the client + u32 blocks_loaded = 0; + // Number of blocks with mesh in rendering range + u32 blocks_in_range_with_mesh = 0; + // Number of blocks occlusion culled + u32 blocks_occlusion_culled = 0; + + // No occlusion culling when free_move is on and camera is inside ground + bool occlusion_culling_enabled = true; + if (m_control.allow_noclip) { + MapNode n = getNode(cam_pos_nodes); + if (n.getContent() == CONTENT_IGNORE || m_nodedef->get(n).solidness == 2) + occlusion_culling_enabled = false; + } + + v3s16 camera_block = getContainerPos(cam_pos_nodes, MAP_BLOCKSIZE); + m_drawlist = std::map<v3s16, MapBlock*, MapBlockComparer>(MapBlockComparer(camera_block)); + + // Uncomment to debug occluded blocks in the wireframe mode + // TODO: Include this as a flag for an extended debugging setting + //if (occlusion_culling_enabled && m_control.show_wireframe) + // occlusion_culling_enabled = porting::getTimeS() & 1; + + for (const auto §or_it : m_sectors) { + MapSector *sector = sector_it.second; + v2s16 sp = sector->getPos(); + + blocks_loaded += sector->size(); + if (!m_control.range_all) { + if (sp.X < p_blocks_min.X || sp.X > p_blocks_max.X || + sp.Y < p_blocks_min.Z || sp.Y > p_blocks_max.Z) + continue; + } + + MapBlockVect sectorblocks; + sector->getBlocks(sectorblocks); + + /* + Loop through blocks in sector + */ + + u32 sector_blocks_drawn = 0; + + for (MapBlock *block : sectorblocks) { + /* + Compare block position to camera position, skip + if not seen on display + */ + + if (!block->mesh) { + // Ignore if mesh doesn't exist + continue; + } + + v3s16 block_coord = block->getPos(); + v3s16 block_position = block->getPosRelative() + MAP_BLOCKSIZE / 2; + + // First, perform a simple distance check, with a padding of one extra block. + if (!m_control.range_all && + block_position.getDistanceFrom(cam_pos_nodes) > range + MAP_BLOCKSIZE) + continue; // Out of range, skip. + + // Keep the block alive as long as it is in range. + block->resetUsageTimer(); + blocks_in_range_with_mesh++; + + // Frustum culling + float d = 0.0; + if (!isBlockInSight(block_coord, camera_position, + camera_direction, camera_fov, range * BS, &d)) + continue; + + // Occlusion culling + if ((!m_control.range_all && d > m_control.wanted_range * BS) || + (occlusion_culling_enabled && isBlockOccluded(block, cam_pos_nodes))) { + blocks_occlusion_culled++; + continue; + } + + // Add to set + block->refGrab(); + m_drawlist[block_coord] = block; + + sector_blocks_drawn++; + } // foreach sectorblocks + + if (sector_blocks_drawn != 0) + m_last_drawn_sectors.insert(sp); + } + + g_profiler->avg("MapBlock meshes in range [#]", blocks_in_range_with_mesh); + g_profiler->avg("MapBlocks occlusion culled [#]", blocks_occlusion_culled); + g_profiler->avg("MapBlocks drawn [#]", m_drawlist.size()); + g_profiler->avg("MapBlocks loaded [#]", blocks_loaded); +} + +void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) +{ + bool is_transparent_pass = pass == scene::ESNRP_TRANSPARENT; + + std::string prefix; + if (pass == scene::ESNRP_SOLID) + prefix = "renderMap(SOLID): "; + else + prefix = "renderMap(TRANSPARENT): "; + + /* + This is called two times per frame, reset on the non-transparent one + */ + if (pass == scene::ESNRP_SOLID) + m_last_drawn_sectors.clear(); + + /* + Get animation parameters + */ + const float animation_time = m_client->getAnimationTime(); + const int crack = m_client->getCrackLevel(); + const u32 daynight_ratio = m_client->getEnv().getDayNightRatio(); + + const v3f camera_position = m_camera_position; + + /* + Get all blocks and draw all visible ones + */ + + u32 vertex_count = 0; + u32 drawcall_count = 0; + + // For limiting number of mesh animations per frame + u32 mesh_animate_count = 0; + //u32 mesh_animate_count_far = 0; + + /* + Update transparent meshes + */ + if (is_transparent_pass) + updateTransparentMeshBuffers(); + + /* + Draw the selected MapBlocks + */ + + MeshBufListList grouped_buffers; + std::vector<DrawDescriptor> draw_order; + video::SMaterial previous_material; + + for (auto &i : m_drawlist) { + v3s16 block_pos = i.first; + MapBlock *block = i.second; + + // If the mesh of the block happened to get deleted, ignore it + if (!block->mesh) + continue; + + v3f block_pos_r = intToFloat(block->getPosRelative() + MAP_BLOCKSIZE / 2, BS); + float d = camera_position.getDistanceFrom(block_pos_r); + d = MYMAX(0,d - BLOCK_MAX_RADIUS); + + // Mesh animation + if (pass == scene::ESNRP_SOLID) { + MapBlockMesh *mapBlockMesh = block->mesh; + assert(mapBlockMesh); + // Pretty random but this should work somewhat nicely + bool faraway = d >= BS * 50; + if (mapBlockMesh->isAnimationForced() || !faraway || + mesh_animate_count < (m_control.range_all ? 200 : 50)) { + + bool animated = mapBlockMesh->animate(faraway, animation_time, + crack, daynight_ratio); + if (animated) + mesh_animate_count++; + } else { + mapBlockMesh->decreaseAnimationForceTimer(); + } + } + + /* + Get the meshbuffers of the block + */ + if (is_transparent_pass) { + // In transparent pass, the mesh will give us + // the partial buffers in the correct order + for (auto &buffer : block->mesh->getTransparentBuffers()) + draw_order.emplace_back(block_pos, &buffer); + } + else { + // otherwise, group buffers across meshes + // using MeshBufListList + MapBlockMesh *mapBlockMesh = block->mesh; + assert(mapBlockMesh); + + for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) { + scene::IMesh *mesh = mapBlockMesh->getMesh(layer); + assert(mesh); + + u32 c = mesh->getMeshBufferCount(); + for (u32 i = 0; i < c; i++) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); + + video::SMaterial& material = buf->getMaterial(); + video::IMaterialRenderer* rnd = + driver->getMaterialRenderer(material.MaterialType); + bool transparent = (rnd && rnd->isTransparent()); + if (!transparent) { + if (buf->getVertexCount() == 0) + errorstream << "Block [" << analyze_block(block) + << "] contains an empty meshbuf" << std::endl; + + grouped_buffers.add(buf, block_pos, layer); + } + } + } + } + } + + // Capture draw order for all solid meshes + for (auto &lists : grouped_buffers.lists) { + for (MeshBufList &list : lists) { + // iterate in reverse to draw closest blocks first + for (auto it = list.bufs.rbegin(); it != list.bufs.rend(); ++it) { + draw_order.emplace_back(it->first, it->second, it != list.bufs.rbegin()); + } + } + } + + TimeTaker draw("Drawing mesh buffers"); + + core::matrix4 m; // Model matrix + v3f offset = intToFloat(m_camera_offset, BS); + u32 material_swaps = 0; + + // Render all mesh buffers in order + drawcall_count += draw_order.size(); + + for (auto &descriptor : draw_order) { + scene::IMeshBuffer *buf = descriptor.getBuffer(); + + // Check and abort if the machine is swapping a lot + if (draw.getTimerTime() > 2000) { + infostream << "ClientMap::renderMap(): Rendering took >2s, " << + "returning." << std::endl; + return; + } + + if (!descriptor.m_reuse_material) { + auto &material = buf->getMaterial(); + + // Apply filter settings + material.setFlag(video::EMF_TRILINEAR_FILTER, + m_cache_trilinear_filter); + material.setFlag(video::EMF_BILINEAR_FILTER, + m_cache_bilinear_filter); + material.setFlag(video::EMF_ANISOTROPIC_FILTER, + m_cache_anistropic_filter); + material.setFlag(video::EMF_WIREFRAME, + m_control.show_wireframe); + + // pass the shadow map texture to the buffer texture + ShadowRenderer *shadow = m_rendering_engine->get_shadow_renderer(); + if (shadow && shadow->is_active()) { + auto &layer = material.TextureLayer[ShadowRenderer::TEXTURE_LAYER_SHADOW]; + layer.Texture = shadow->get_texture(); + layer.TextureWrapU = video::E_TEXTURE_CLAMP::ETC_CLAMP_TO_EDGE; + layer.TextureWrapV = video::E_TEXTURE_CLAMP::ETC_CLAMP_TO_EDGE; + // Do not enable filter on shadow texture to avoid visual artifacts + // with colored shadows. + // Filtering is done in shader code anyway + layer.BilinearFilter = false; + layer.AnisotropicFilter = false; + layer.TrilinearFilter = false; + } + driver->setMaterial(material); + ++material_swaps; + material.TextureLayer[ShadowRenderer::TEXTURE_LAYER_SHADOW].Texture = nullptr; + } + + v3f block_wpos = intToFloat(descriptor.m_pos * MAP_BLOCKSIZE, BS); + m.setTranslation(block_wpos - offset); + + driver->setTransform(video::ETS_WORLD, m); + descriptor.draw(driver); + vertex_count += buf->getIndexCount(); + } + + g_profiler->avg(prefix + "draw meshes [ms]", draw.stop(true)); + + // Log only on solid pass because values are the same + if (pass == scene::ESNRP_SOLID) { + g_profiler->avg("renderMap(): animated meshes [#]", mesh_animate_count); + } + + if (pass == scene::ESNRP_TRANSPARENT) { + g_profiler->avg("renderMap(): transparent buffers [#]", draw_order.size()); + } + + g_profiler->avg(prefix + "vertices drawn [#]", vertex_count); + g_profiler->avg(prefix + "drawcalls [#]", drawcall_count); + g_profiler->avg(prefix + "material swaps [#]", material_swaps); +} + +static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step, + float step_multiplier, float start_distance, float end_distance, + const NodeDefManager *ndef, u32 daylight_factor, float sunlight_min_d, + int *result, bool *sunlight_seen) +{ + int brightness_sum = 0; + int brightness_count = 0; + float distance = start_distance; + dir.normalize(); + v3f pf = p0; + pf += dir * distance; + int noncount = 0; + bool nonlight_seen = false; + bool allow_allowing_non_sunlight_propagates = false; + bool allow_non_sunlight_propagates = false; + // Check content nearly at camera position + { + v3s16 p = floatToInt(p0 /*+ dir * 3*BS*/, BS); + MapNode n = map->getNode(p); + if(ndef->get(n).param_type == CPT_LIGHT && + !ndef->get(n).sunlight_propagates) + allow_allowing_non_sunlight_propagates = true; + } + // If would start at CONTENT_IGNORE, start closer + { + v3s16 p = floatToInt(pf, BS); + MapNode n = map->getNode(p); + if(n.getContent() == CONTENT_IGNORE){ + float newd = 2*BS; + pf = p0 + dir * 2*newd; + distance = newd; + sunlight_min_d = 0; + } + } + for (int i=0; distance < end_distance; i++) { + pf += dir * step; + distance += step; + step *= step_multiplier; + + v3s16 p = floatToInt(pf, BS); + MapNode n = map->getNode(p); + if (allow_allowing_non_sunlight_propagates && i == 0 && + ndef->get(n).param_type == CPT_LIGHT && + !ndef->get(n).sunlight_propagates) { + allow_non_sunlight_propagates = true; + } + + if (ndef->get(n).param_type != CPT_LIGHT || + (!ndef->get(n).sunlight_propagates && + !allow_non_sunlight_propagates)){ + nonlight_seen = true; + noncount++; + if(noncount >= 4) + break; + continue; + } + + if (distance >= sunlight_min_d && !*sunlight_seen && !nonlight_seen) + if (n.getLight(LIGHTBANK_DAY, ndef) == LIGHT_SUN) + *sunlight_seen = true; + noncount = 0; + brightness_sum += decode_light(n.getLightBlend(daylight_factor, ndef)); + brightness_count++; + } + *result = 0; + if(brightness_count == 0) + return false; + *result = brightness_sum / brightness_count; + /*std::cerr<<"Sampled "<<brightness_count<<" points; result=" + <<(*result)<<std::endl;*/ + return true; +} + +int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor, + int oldvalue, bool *sunlight_seen_result) +{ + ScopeProfiler sp(g_profiler, "CM::getBackgroundBrightness", SPT_AVG); + static v3f z_directions[50] = { + v3f(-100, 0, 0) + }; + static f32 z_offsets[50] = { + -1000, + }; + + if (z_directions[0].X < -99) { + for (u32 i = 0; i < ARRLEN(z_directions); i++) { + // Assumes FOV of 72 and 16/9 aspect ratio + z_directions[i] = v3f( + 0.02 * myrand_range(-100, 100), + 1.0, + 0.01 * myrand_range(-100, 100) + ).normalize(); + z_offsets[i] = 0.01 * myrand_range(0,100); + } + } + + int sunlight_seen_count = 0; + float sunlight_min_d = max_d*0.8; + if(sunlight_min_d > 35*BS) + sunlight_min_d = 35*BS; + std::vector<int> values; + values.reserve(ARRLEN(z_directions)); + for (u32 i = 0; i < ARRLEN(z_directions); i++) { + v3f z_dir = z_directions[i]; + core::CMatrix4<f32> a; + a.buildRotateFromTo(v3f(0,1,0), z_dir); + v3f dir = m_camera_direction; + a.rotateVect(dir); + int br = 0; + float step = BS*1.5; + if(max_d > 35*BS) + step = max_d / 35 * 1.5; + float off = step * z_offsets[i]; + bool sunlight_seen_now = false; + bool ok = getVisibleBrightness(this, m_camera_position, dir, + step, 1.0, max_d*0.6+off, max_d, m_nodedef, daylight_factor, + sunlight_min_d, + &br, &sunlight_seen_now); + if(sunlight_seen_now) + sunlight_seen_count++; + if(!ok) + continue; + values.push_back(br); + // Don't try too much if being in the sun is clear + if(sunlight_seen_count >= 20) + break; + } + int brightness_sum = 0; + int brightness_count = 0; + std::sort(values.begin(), values.end()); + u32 num_values_to_use = values.size(); + if(num_values_to_use >= 10) + num_values_to_use -= num_values_to_use/2; + else if(num_values_to_use >= 7) + num_values_to_use -= num_values_to_use/3; + u32 first_value_i = (values.size() - num_values_to_use) / 2; + + for (u32 i=first_value_i; i < first_value_i + num_values_to_use; i++) { + brightness_sum += values[i]; + brightness_count++; + } + + int ret = 0; + if(brightness_count == 0){ + MapNode n = getNode(floatToInt(m_camera_position, BS)); + if(m_nodedef->get(n).param_type == CPT_LIGHT){ + ret = decode_light(n.getLightBlend(daylight_factor, m_nodedef)); + } else { + ret = oldvalue; + } + } else { + ret = brightness_sum / brightness_count; + } + + *sunlight_seen_result = (sunlight_seen_count > 0); + return ret; +} + +void ClientMap::renderPostFx(CameraMode cam_mode) +{ + // Sadly ISceneManager has no "post effects" render pass, in that case we + // could just register for that and handle it in renderMap(). + + MapNode n = getNode(floatToInt(m_camera_position, BS)); + + const ContentFeatures& features = m_nodedef->get(n); + video::SColor post_effect_color = features.post_effect_color; + + // If the camera is in a solid node, make everything black. + // (first person mode only) + if (features.solidness == 2 && cam_mode == CAMERA_MODE_FIRST && + !m_control.allow_noclip) { + post_effect_color = video::SColor(255, 0, 0, 0); + } + + if (post_effect_color.getAlpha() != 0) { + // Draw a full-screen rectangle + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + v2u32 ss = driver->getScreenSize(); + core::rect<s32> rect(0,0, ss.X, ss.Y); + driver->draw2DRectangle(post_effect_color, rect); + } +} + +void ClientMap::PrintInfo(std::ostream &out) +{ + out<<"ClientMap: "; +} + +void ClientMap::renderMapShadows(video::IVideoDriver *driver, + const video::SMaterial &material, s32 pass, int frame, int total_frames) +{ + bool is_transparent_pass = pass != scene::ESNRP_SOLID; + std::string prefix; + if (is_transparent_pass) + prefix = "renderMap(SHADOW TRANS): "; + else + prefix = "renderMap(SHADOW SOLID): "; + + u32 drawcall_count = 0; + u32 vertex_count = 0; + + MeshBufListList grouped_buffers; + std::vector<DrawDescriptor> draw_order; + + + int count = 0; + int low_bound = is_transparent_pass ? 0 : m_drawlist_shadow.size() / total_frames * frame; + int high_bound = is_transparent_pass ? m_drawlist_shadow.size() : m_drawlist_shadow.size() / total_frames * (frame + 1); + + // transparent pass should be rendered in one go + if (is_transparent_pass && frame != total_frames - 1) { + return; + } + + for (auto &i : m_drawlist_shadow) { + // only process specific part of the list & break early + ++count; + if (count <= low_bound) + continue; + if (count > high_bound) + break; + + v3s16 block_pos = i.first; + MapBlock *block = i.second; + + // If the mesh of the block happened to get deleted, ignore it + if (!block->mesh) + continue; + + /* + Get the meshbuffers of the block + */ + if (is_transparent_pass) { + // In transparent pass, the mesh will give us + // the partial buffers in the correct order + for (auto &buffer : block->mesh->getTransparentBuffers()) + draw_order.emplace_back(block_pos, &buffer); + } + else { + // otherwise, group buffers across meshes + // using MeshBufListList + MapBlockMesh *mapBlockMesh = block->mesh; + assert(mapBlockMesh); + + for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) { + scene::IMesh *mesh = mapBlockMesh->getMesh(layer); + assert(mesh); + + u32 c = mesh->getMeshBufferCount(); + for (u32 i = 0; i < c; i++) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); + + video::SMaterial &mat = buf->getMaterial(); + auto rnd = driver->getMaterialRenderer(mat.MaterialType); + bool transparent = rnd && rnd->isTransparent(); + if (!transparent) + grouped_buffers.add(buf, block_pos, layer); + } + } + } + } + + u32 buffer_count = 0; + for (auto &lists : grouped_buffers.lists) + for (MeshBufList &list : lists) + buffer_count += list.bufs.size(); + + draw_order.reserve(draw_order.size() + buffer_count); + + // Capture draw order for all solid meshes + for (auto &lists : grouped_buffers.lists) { + for (MeshBufList &list : lists) { + // iterate in reverse to draw closest blocks first + for (auto it = list.bufs.rbegin(); it != list.bufs.rend(); ++it) + draw_order.emplace_back(it->first, it->second, it != list.bufs.rbegin()); + } + } + + TimeTaker draw("Drawing shadow mesh buffers"); + + core::matrix4 m; // Model matrix + v3f offset = intToFloat(m_camera_offset, BS); + u32 material_swaps = 0; + + // Render all mesh buffers in order + drawcall_count += draw_order.size(); + + for (auto &descriptor : draw_order) { + scene::IMeshBuffer *buf = descriptor.getBuffer(); + + // Check and abort if the machine is swapping a lot + if (draw.getTimerTime() > 1000) { + infostream << "ClientMap::renderMapShadows(): Rendering " + "took >1s, returning." << std::endl; + break; + } + + if (!descriptor.m_reuse_material) { + // override some material properties + video::SMaterial local_material = buf->getMaterial(); + local_material.MaterialType = material.MaterialType; + local_material.BackfaceCulling = material.BackfaceCulling; + local_material.FrontfaceCulling = material.FrontfaceCulling; + local_material.BlendOperation = material.BlendOperation; + local_material.Lighting = false; + driver->setMaterial(local_material); + ++material_swaps; + } + + v3f block_wpos = intToFloat(descriptor.m_pos * MAP_BLOCKSIZE, BS); + m.setTranslation(block_wpos - offset); + + driver->setTransform(video::ETS_WORLD, m); + descriptor.draw(driver); + vertex_count += buf->getIndexCount(); + } + + // restore the driver material state + video::SMaterial clean; + clean.BlendOperation = video::EBO_ADD; + driver->setMaterial(clean); // reset material to defaults + driver->draw3DLine(v3f(), v3f(), video::SColor(0)); + + g_profiler->avg(prefix + "draw meshes [ms]", draw.stop(true)); + g_profiler->avg(prefix + "vertices drawn [#]", vertex_count); + g_profiler->avg(prefix + "drawcalls [#]", drawcall_count); + g_profiler->avg(prefix + "material swaps [#]", material_swaps); +} + +/* + Custom update draw list for the pov of shadow light. +*/ +void ClientMap::updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir, float radius, float length) +{ + ScopeProfiler sp(g_profiler, "CM::updateDrawListShadow()", SPT_AVG); + + v3s16 cam_pos_nodes = floatToInt(shadow_light_pos, BS); + v3s16 p_blocks_min; + v3s16 p_blocks_max; + getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max, radius + length); + + std::vector<v2s16> blocks_in_range; + + for (auto &i : m_drawlist_shadow) { + MapBlock *block = i.second; + block->refDrop(); + } + m_drawlist_shadow.clear(); + + // Number of blocks currently loaded by the client + u32 blocks_loaded = 0; + // Number of blocks with mesh in rendering range + u32 blocks_in_range_with_mesh = 0; + // Number of blocks occlusion culled + u32 blocks_occlusion_culled = 0; + + for (auto §or_it : m_sectors) { + MapSector *sector = sector_it.second; + if (!sector) + continue; + blocks_loaded += sector->size(); + + MapBlockVect sectorblocks; + sector->getBlocks(sectorblocks); + + /* + Loop through blocks in sector + */ + for (MapBlock *block : sectorblocks) { + if (!block->mesh) { + // Ignore if mesh doesn't exist + continue; + } + + v3f block_pos = intToFloat(block->getPos() * MAP_BLOCKSIZE, BS); + v3f projection = shadow_light_pos + shadow_light_dir * shadow_light_dir.dotProduct(block_pos - shadow_light_pos); + if (projection.getDistanceFrom(block_pos) > radius) + continue; + + blocks_in_range_with_mesh++; + + // This block is in range. Reset usage timer. + block->resetUsageTimer(); + + // Add to set + if (m_drawlist_shadow.find(block->getPos()) == m_drawlist_shadow.end()) { + block->refGrab(); + m_drawlist_shadow[block->getPos()] = block; + } + } + } + + g_profiler->avg("SHADOW MapBlock meshes in range [#]", blocks_in_range_with_mesh); + g_profiler->avg("SHADOW MapBlocks occlusion culled [#]", blocks_occlusion_culled); + g_profiler->avg("SHADOW MapBlocks drawn [#]", m_drawlist_shadow.size()); + g_profiler->avg("SHADOW MapBlocks loaded [#]", blocks_loaded); +} + +void ClientMap::updateTransparentMeshBuffers() +{ + ScopeProfiler sp(g_profiler, "CM::updateTransparentMeshBuffers", SPT_AVG); + u32 sorted_blocks = 0; + u32 unsorted_blocks = 0; + f32 sorting_distance_sq = pow(m_cache_transparency_sorting_distance * BS, 2.0f); + + + // Update the order of transparent mesh buffers in each mesh + for (auto it = m_drawlist.begin(); it != m_drawlist.end(); it++) { + MapBlock* block = it->second; + if (!block->mesh) + continue; + + if (m_needs_update_transparent_meshes || + block->mesh->getTransparentBuffers().size() == 0) { + + v3s16 block_pos = block->getPos(); + v3f block_pos_f = intToFloat(block_pos * MAP_BLOCKSIZE + MAP_BLOCKSIZE / 2, BS); + f32 distance = m_camera_position.getDistanceFromSQ(block_pos_f); + if (distance <= sorting_distance_sq) { + block->mesh->updateTransparentBuffers(m_camera_position, block_pos); + ++sorted_blocks; + } + else { + block->mesh->consolidateTransparentBuffers(); + ++unsorted_blocks; + } + } + } + + g_profiler->avg("CM::Transparent Buffers - Sorted", sorted_blocks); + g_profiler->avg("CM::Transparent Buffers - Unsorted", unsorted_blocks); + m_needs_update_transparent_meshes = false; +} + +scene::IMeshBuffer* ClientMap::DrawDescriptor::getBuffer() +{ + return m_use_partial_buffer ? m_partial_buffer->getBuffer() : m_buffer; +} + +void ClientMap::DrawDescriptor::draw(video::IVideoDriver* driver) +{ + if (m_use_partial_buffer) { + m_partial_buffer->beforeDraw(); + driver->drawMeshBuffer(m_partial_buffer->getBuffer()); + m_partial_buffer->afterDraw(); + } else { + driver->drawMeshBuffer(m_buffer); + } +} diff --git a/src/client/clientmap.h b/src/client/clientmap.h new file mode 100644 index 0000000..8c45b53 --- /dev/null +++ b/src/client/clientmap.h @@ -0,0 +1,209 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "map.h" +#include "camera.h" +#include <set> +#include <map> + +struct MapDrawControl +{ + // Wanted drawing range + float wanted_range = 0.0f; + // Overrides limits by drawing everything + bool range_all = false; + // Allow rendering out of bounds + bool allow_noclip = false; + // show a wire frame for debugging + bool show_wireframe = false; +}; + +struct MeshBufList +{ + video::SMaterial m; + std::vector<std::pair<v3s16,scene::IMeshBuffer*>> bufs; +}; + +struct MeshBufListList +{ + /*! + * Stores the mesh buffers of the world. + * The array index is the material's layer. + * The vector part groups vertices by material. + */ + std::vector<MeshBufList> lists[MAX_TILE_LAYERS]; + + void clear(); + void add(scene::IMeshBuffer *buf, v3s16 position, u8 layer); +}; + +class Client; +class ITextureSource; +class PartialMeshBuffer; + +/* + ClientMap + + This is the only map class that is able to render itself on screen. +*/ + +class ClientMap : public Map, public scene::ISceneNode +{ +public: + ClientMap( + Client *client, + RenderingEngine *rendering_engine, + MapDrawControl &control, + s32 id + ); + + virtual ~ClientMap() = default; + + bool maySaveBlocks() override + { + return false; + } + + void drop() override + { + ISceneNode::drop(); // calls destructor + } + + void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset); + + /* + Forcefully get a sector from somewhere + */ + MapSector * emergeSector(v2s16 p) override; + + /* + ISceneNode methods + */ + + virtual void OnRegisterSceneNode() override; + + virtual void render() override + { + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + renderMap(driver, SceneManager->getSceneNodeRenderPass()); + } + + virtual const aabb3f &getBoundingBox() const override + { + return m_box; + } + + void getBlocksInViewRange(v3s16 cam_pos_nodes, + v3s16 *p_blocks_min, v3s16 *p_blocks_max, float range=-1.0f); + void updateDrawList(); + void updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir, float radius, float length); + // Returns true if draw list needs updating before drawing the next frame. + bool needsUpdateDrawList() { return m_needs_update_drawlist; } + void renderMap(video::IVideoDriver* driver, s32 pass); + + void renderMapShadows(video::IVideoDriver *driver, + const video::SMaterial &material, s32 pass, int frame, int total_frames); + + int getBackgroundBrightness(float max_d, u32 daylight_factor, + int oldvalue, bool *sunlight_seen_result); + + void renderPostFx(CameraMode cam_mode); + + // For debug printing + void PrintInfo(std::ostream &out) override; + + const MapDrawControl & getControl() const { return m_control; } + f32 getWantedRange() const { return m_control.wanted_range; } + f32 getCameraFov() const { return m_camera_fov; } + +private: + + // update the vertex order in transparent mesh buffers + void updateTransparentMeshBuffers(); + + // Orders blocks by distance to the camera + class MapBlockComparer + { + public: + MapBlockComparer(const v3s16 &camera_block) : m_camera_block(camera_block) {} + + bool operator() (const v3s16 &left, const v3s16 &right) const + { + auto distance_left = left.getDistanceFromSQ(m_camera_block); + auto distance_right = right.getDistanceFromSQ(m_camera_block); + return distance_left > distance_right || (distance_left == distance_right && left > right); + } + + private: + v3s16 m_camera_block; + }; + + + // reference to a mesh buffer used when rendering the map. + struct DrawDescriptor { + v3s16 m_pos; + union { + scene::IMeshBuffer *m_buffer; + const PartialMeshBuffer *m_partial_buffer; + }; + bool m_reuse_material:1; + bool m_use_partial_buffer:1; + + DrawDescriptor(v3s16 pos, scene::IMeshBuffer *buffer, bool reuse_material) : + m_pos(pos), m_buffer(buffer), m_reuse_material(reuse_material), m_use_partial_buffer(false) + {} + + DrawDescriptor(v3s16 pos, const PartialMeshBuffer *buffer) : + m_pos(pos), m_partial_buffer(buffer), m_reuse_material(false), m_use_partial_buffer(true) + {} + + scene::IMeshBuffer* getBuffer(); + void draw(video::IVideoDriver* driver); + }; + + Client *m_client; + RenderingEngine *m_rendering_engine; + + aabb3f m_box = aabb3f(-BS * 1000000, -BS * 1000000, -BS * 1000000, + BS * 1000000, BS * 1000000, BS * 1000000); + + MapDrawControl &m_control; + + v3f m_camera_position = v3f(0,0,0); + v3f m_camera_direction = v3f(0,0,1); + f32 m_camera_fov = M_PI; + v3s16 m_camera_offset; + bool m_needs_update_transparent_meshes = true; + + std::map<v3s16, MapBlock*, MapBlockComparer> m_drawlist; + std::map<v3s16, MapBlock*> m_drawlist_shadow; + bool m_needs_update_drawlist; + + std::set<v2s16> m_last_drawn_sectors; + + bool m_cache_trilinear_filter; + bool m_cache_bilinear_filter; + bool m_cache_anistropic_filter; + bool m_added_to_shadow_renderer{false}; + u16 m_cache_transparency_sorting_distance; +}; diff --git a/src/client/clientmedia.cpp b/src/client/clientmedia.cpp new file mode 100644 index 0000000..6c5d4a8 --- /dev/null +++ b/src/client/clientmedia.cpp @@ -0,0 +1,792 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "clientmedia.h" +#include "httpfetch.h" +#include "client.h" +#include "filecache.h" +#include "filesys.h" +#include "log.h" +#include "porting.h" +#include "settings.h" +#include "util/hex.h" +#include "util/serialize.h" +#include "util/sha1.h" +#include "util/string.h" + +static std::string getMediaCacheDir() +{ + return porting::path_cache + DIR_DELIM + "media"; +} + +bool clientMediaUpdateCache(const std::string &raw_hash, const std::string &filedata) +{ + FileCache media_cache(getMediaCacheDir()); + std::string sha1_hex = hex_encode(raw_hash); + if (!media_cache.exists(sha1_hex)) + return media_cache.update(sha1_hex, filedata); + return true; +} + +/* + ClientMediaDownloader +*/ + +ClientMediaDownloader::ClientMediaDownloader(): + m_httpfetch_caller(HTTPFETCH_DISCARD) +{ +} + +ClientMediaDownloader::~ClientMediaDownloader() +{ + if (m_httpfetch_caller != HTTPFETCH_DISCARD) + httpfetch_caller_free(m_httpfetch_caller); + + for (auto &file_it : m_files) + delete file_it.second; + + for (auto &remote : m_remotes) + delete remote; +} + +bool ClientMediaDownloader::loadMedia(Client *client, const std::string &data, + const std::string &name) +{ + return client->loadMedia(data, name); +} + +void ClientMediaDownloader::addFile(const std::string &name, const std::string &sha1) +{ + assert(!m_initial_step_done); // pre-condition + + // if name was already announced, ignore the new announcement + if (m_files.count(name) != 0) { + errorstream << "Client: ignoring duplicate media announcement " + << "sent by server: \"" << name << "\"" + << std::endl; + return; + } + + // if name is empty or contains illegal characters, ignore the file + if (name.empty() || !string_allowed(name, TEXTURENAME_ALLOWED_CHARS)) { + errorstream << "Client: ignoring illegal file name " + << "sent by server: \"" << name << "\"" + << std::endl; + return; + } + + // length of sha1 must be exactly 20 (160 bits), else ignore the file + if (sha1.size() != 20) { + errorstream << "Client: ignoring illegal SHA1 sent by server: " + << hex_encode(sha1) << " \"" << name << "\"" + << std::endl; + return; + } + + FileStatus *filestatus = new FileStatus(); + filestatus->received = false; + filestatus->sha1 = sha1; + filestatus->current_remote = -1; + m_files.insert(std::make_pair(name, filestatus)); +} + +void ClientMediaDownloader::addRemoteServer(const std::string &baseurl) +{ + assert(!m_initial_step_done); // pre-condition + +#ifdef USE_CURL + + if (g_settings->getBool("enable_remote_media_server")) { + infostream << "Client: Adding remote server \"" + << baseurl << "\" for media download" << std::endl; + + RemoteServerStatus *remote = new RemoteServerStatus(); + remote->baseurl = baseurl; + remote->active_count = 0; + m_remotes.push_back(remote); + } + +#else + + infostream << "Client: Ignoring remote server \"" + << baseurl << "\" because cURL support is not compiled in" + << std::endl; + +#endif +} + +void ClientMediaDownloader::step(Client *client) +{ + if (!m_initial_step_done) { + initialStep(client); + m_initial_step_done = true; + } + + // Remote media: check for completion of fetches + if (m_httpfetch_active) { + bool fetched_something = false; + HTTPFetchResult fetch_result; + + while (httpfetch_async_get(m_httpfetch_caller, fetch_result)) { + m_httpfetch_active--; + fetched_something = true; + + // Is this a hashset (index.mth) or a media file? + if (fetch_result.request_id < m_remotes.size()) + remoteHashSetReceived(fetch_result); + else + remoteMediaReceived(fetch_result, client); + } + + if (fetched_something) + startRemoteMediaTransfers(); + + // Did all remote transfers end and no new ones can be started? + // If so, request still missing files from the minetest server + // (Or report that we have all files.) + if (m_httpfetch_active == 0) { + if (m_uncached_received_count < m_uncached_count) { + infostream << "Client: Failed to remote-fetch " + << (m_uncached_count-m_uncached_received_count) + << " files. Requesting them" + << " the usual way." << std::endl; + } + startConventionalTransfers(client); + } + } +} + +void ClientMediaDownloader::initialStep(Client *client) +{ + // Check media cache + m_uncached_count = m_files.size(); + for (auto &file_it : m_files) { + const std::string &name = file_it.first; + FileStatus *filestatus = file_it.second; + const std::string &sha1 = filestatus->sha1; + + if (tryLoadFromCache(name, sha1, client)) { + filestatus->received = true; + m_uncached_count--; + } + } + + assert(m_uncached_received_count == 0); + + // Create the media cache dir if we are likely to write to it + if (m_uncached_count != 0) + createCacheDirs(); + + // If we found all files in the cache, report this fact to the server. + // If the server reported no remote servers, immediately start + // conventional transfers. Note: if cURL support is not compiled in, + // m_remotes is always empty, so "!USE_CURL" is redundant but may + // reduce the size of the compiled code + if (!USE_CURL || m_uncached_count == 0 || m_remotes.empty()) { + startConventionalTransfers(client); + } + else { + // Otherwise start off by requesting each server's sha1 set + + // This is the first time we use httpfetch, so alloc a caller ID + m_httpfetch_caller = httpfetch_caller_alloc(); + + // Set the active fetch limit to curl_parallel_limit or 84, + // whichever is greater. This gives us some leeway so that + // inefficiencies in communicating with the httpfetch thread + // don't slow down fetches too much. (We still want some limit + // so that when the first remote server returns its hash set, + // not all files are requested from that server immediately.) + // One such inefficiency is that ClientMediaDownloader::step() + // is only called a couple times per second, while httpfetch + // might return responses much faster than that. + // Note that httpfetch strictly enforces curl_parallel_limit + // but at no inter-thread communication cost. This however + // doesn't help with the aforementioned inefficiencies. + // The signifance of 84 is that it is 2*6*9 in base 13. + m_httpfetch_active_limit = g_settings->getS32("curl_parallel_limit"); + m_httpfetch_active_limit = MYMAX(m_httpfetch_active_limit, 84); + + // Write a list of hashes that we need. This will be POSTed + // to the server using Content-Type: application/octet-stream + std::string required_hash_set = serializeRequiredHashSet(); + + // minor fixme: this loop ignores m_httpfetch_active_limit + + // another minor fixme, unlikely to matter in normal usage: + // these index.mth fetches do (however) count against + // m_httpfetch_active_limit when starting actual media file + // requests, so if there are lots of remote servers that are + // not responding, those will stall new media file transfers. + + for (u32 i = 0; i < m_remotes.size(); ++i) { + assert(m_httpfetch_next_id == i); + + RemoteServerStatus *remote = m_remotes[i]; + actionstream << "Client: Contacting remote server \"" + << remote->baseurl << "\"" << std::endl; + + HTTPFetchRequest fetch_request; + fetch_request.url = + remote->baseurl + MTHASHSET_FILE_NAME; + fetch_request.caller = m_httpfetch_caller; + fetch_request.request_id = m_httpfetch_next_id; // == i + fetch_request.method = HTTP_POST; + fetch_request.raw_data = required_hash_set; + fetch_request.extra_headers.emplace_back( + "Content-Type: application/octet-stream"); + + // Encapsulate possible IPv6 plain address in [] + std::string addr = client->getAddressName(); + if (addr.find(':', 0) != std::string::npos) + addr = '[' + addr + ']'; + fetch_request.extra_headers.emplace_back( + std::string("Referer: minetest://") + + addr + ":" + + std::to_string(client->getServerAddress().getPort())); + + httpfetch_async(fetch_request); + + m_httpfetch_active++; + m_httpfetch_next_id++; + m_outstanding_hash_sets++; + } + } +} + +void ClientMediaDownloader::remoteHashSetReceived( + const HTTPFetchResult &fetch_result) +{ + u32 remote_id = fetch_result.request_id; + assert(remote_id < m_remotes.size()); + RemoteServerStatus *remote = m_remotes[remote_id]; + + m_outstanding_hash_sets--; + + if (fetch_result.succeeded) { + try { + // Server sent a list of file hashes that are + // available on it, try to parse the list + + std::set<std::string> sha1_set; + deSerializeHashSet(fetch_result.data, sha1_set); + + // Parsing succeeded: For every file that is + // available on this server, add this server + // to the available_remotes array + + for(auto it = m_files.upper_bound(m_name_bound); + it != m_files.end(); ++it) { + FileStatus *f = it->second; + if (!f->received && sha1_set.count(f->sha1)) + f->available_remotes.push_back(remote_id); + } + } + catch (SerializationError &e) { + infostream << "Client: Remote server \"" + << remote->baseurl << "\" sent invalid hash set: " + << e.what() << std::endl; + } + } +} + +void ClientMediaDownloader::remoteMediaReceived( + const HTTPFetchResult &fetch_result, + Client *client) +{ + // Some remote server sent us a file. + // -> decrement number of active fetches + // -> mark file as received if fetch succeeded + // -> try to load media + + std::string name; + { + auto it = m_remote_file_transfers.find(fetch_result.request_id); + assert(it != m_remote_file_transfers.end()); + name = it->second; + m_remote_file_transfers.erase(it); + } + + sanity_check(m_files.count(name) != 0); + + FileStatus *filestatus = m_files[name]; + sanity_check(!filestatus->received); + sanity_check(filestatus->current_remote >= 0); + + RemoteServerStatus *remote = m_remotes[filestatus->current_remote]; + + filestatus->current_remote = -1; + remote->active_count--; + + // If fetch succeeded, try to load media file + + if (fetch_result.succeeded) { + bool success = checkAndLoad(name, filestatus->sha1, + fetch_result.data, false, client); + if (success) { + filestatus->received = true; + assert(m_uncached_received_count < m_uncached_count); + m_uncached_received_count++; + } + } +} + +s32 ClientMediaDownloader::selectRemoteServer(FileStatus *filestatus) +{ + // Pre-conditions + assert(filestatus != NULL); + assert(!filestatus->received); + assert(filestatus->current_remote < 0); + + if (filestatus->available_remotes.empty()) + return -1; + + // Of all servers that claim to provide the file (and haven't + // been unsuccessfully tried before), find the one with the + // smallest number of currently active transfers + + s32 best = 0; + s32 best_remote_id = filestatus->available_remotes[best]; + s32 best_active_count = m_remotes[best_remote_id]->active_count; + + for (u32 i = 1; i < filestatus->available_remotes.size(); ++i) { + s32 remote_id = filestatus->available_remotes[i]; + s32 active_count = m_remotes[remote_id]->active_count; + if (active_count < best_active_count) { + best = i; + best_remote_id = remote_id; + best_active_count = active_count; + } + } + + filestatus->available_remotes.erase( + filestatus->available_remotes.begin() + best); + + return best_remote_id; + +} + +void ClientMediaDownloader::startRemoteMediaTransfers() +{ + bool changing_name_bound = true; + + for (auto files_iter = m_files.upper_bound(m_name_bound); + files_iter != m_files.end(); ++files_iter) { + + // Abort if active fetch limit is exceeded + if (m_httpfetch_active >= m_httpfetch_active_limit) + break; + + const std::string &name = files_iter->first; + FileStatus *filestatus = files_iter->second; + + if (!filestatus->received && filestatus->current_remote < 0) { + // File has not been received yet and is not currently + // being transferred. Choose a server for it. + s32 remote_id = selectRemoteServer(filestatus); + if (remote_id >= 0) { + // Found a server, so start fetching + RemoteServerStatus *remote = + m_remotes[remote_id]; + + std::string url = remote->baseurl + + hex_encode(filestatus->sha1); + verbosestream << "Client: " + << "Requesting remote media file " + << "\"" << name << "\" " + << "\"" << url << "\"" << std::endl; + + HTTPFetchRequest fetch_request; + fetch_request.url = url; + fetch_request.caller = m_httpfetch_caller; + fetch_request.request_id = m_httpfetch_next_id; + fetch_request.timeout = + g_settings->getS32("curl_file_download_timeout"); + httpfetch_async(fetch_request); + + m_remote_file_transfers.insert(std::make_pair( + m_httpfetch_next_id, + name)); + + filestatus->current_remote = remote_id; + remote->active_count++; + m_httpfetch_active++; + m_httpfetch_next_id++; + } + } + + if (filestatus->received || + (filestatus->current_remote < 0 && + !m_outstanding_hash_sets)) { + // If we arrive here, we conclusively know that we + // won't fetch this file from a remote server in the + // future. So update the name bound if possible. + if (changing_name_bound) + m_name_bound = name; + } + else + changing_name_bound = false; + } + +} + +void ClientMediaDownloader::startConventionalTransfers(Client *client) +{ + assert(m_httpfetch_active == 0); // pre-condition + + if (m_uncached_received_count != m_uncached_count) { + // Some media files have not been received yet, use the + // conventional slow method (minetest protocol) to get them + std::vector<std::string> file_requests; + for (auto &file : m_files) { + if (!file.second->received) + file_requests.push_back(file.first); + } + assert((s32) file_requests.size() == + m_uncached_count - m_uncached_received_count); + client->request_media(file_requests); + } +} + +bool ClientMediaDownloader::conventionalTransferDone( + const std::string &name, + const std::string &data, + Client *client) +{ + // Check that file was announced + auto file_iter = m_files.find(name); + if (file_iter == m_files.end()) { + errorstream << "Client: server sent media file that was" + << "not announced, ignoring it: \"" << name << "\"" + << std::endl; + return false; + } + FileStatus *filestatus = file_iter->second; + assert(filestatus != NULL); + + // Check that file hasn't already been received + if (filestatus->received) { + errorstream << "Client: server sent media file that we already" + << "received, ignoring it: \"" << name << "\"" + << std::endl; + return true; + } + + // Mark file as received, regardless of whether loading it works and + // whether the checksum matches (because at this point there is no + // other server that could send a replacement) + filestatus->received = true; + assert(m_uncached_received_count < m_uncached_count); + m_uncached_received_count++; + + // Check that received file matches announced checksum + // If so, load it + checkAndLoad(name, filestatus->sha1, data, false, client); + + return true; +} + +/* + IClientMediaDownloader +*/ + +IClientMediaDownloader::IClientMediaDownloader(): + m_media_cache(getMediaCacheDir()), m_write_to_cache(true) +{ +} + +void IClientMediaDownloader::createCacheDirs() +{ + if (!m_write_to_cache) + return; + + std::string path = getMediaCacheDir(); + if (!fs::CreateAllDirs(path)) { + errorstream << "Client: Could not create media cache directory: " + << path << std::endl; + } +} + +bool IClientMediaDownloader::tryLoadFromCache(const std::string &name, + const std::string &sha1, Client *client) +{ + std::ostringstream tmp_os(std::ios_base::binary); + bool found_in_cache = m_media_cache.load(hex_encode(sha1), tmp_os); + + // If found in cache, try to load it from there + if (found_in_cache) + return checkAndLoad(name, sha1, tmp_os.str(), true, client); + + return false; +} + +bool IClientMediaDownloader::checkAndLoad( + const std::string &name, const std::string &sha1, + const std::string &data, bool is_from_cache, Client *client) +{ + const char *cached_or_received = is_from_cache ? "cached" : "received"; + const char *cached_or_received_uc = is_from_cache ? "Cached" : "Received"; + std::string sha1_hex = hex_encode(sha1); + + // Compute actual checksum of data + std::string data_sha1; + { + SHA1 data_sha1_calculator; + data_sha1_calculator.addBytes(data.c_str(), data.size()); + unsigned char *data_tmpdigest = data_sha1_calculator.getDigest(); + data_sha1.assign((char*) data_tmpdigest, 20); + free(data_tmpdigest); + } + + // Check that received file matches announced checksum + if (data_sha1 != sha1) { + std::string data_sha1_hex = hex_encode(data_sha1); + infostream << "Client: " + << cached_or_received_uc << " media file " + << sha1_hex << " \"" << name << "\" " + << "mismatches actual checksum " << data_sha1_hex + << std::endl; + return false; + } + + // Checksum is ok, try loading the file + bool success = loadMedia(client, data, name); + if (!success) { + infostream << "Client: " + << "Failed to load " << cached_or_received << " media: " + << sha1_hex << " \"" << name << "\"" + << std::endl; + return false; + } + + verbosestream << "Client: " + << "Loaded " << cached_or_received << " media: " + << sha1_hex << " \"" << name << "\"" + << std::endl; + + // Update cache (unless we just loaded the file from the cache) + if (!is_from_cache && m_write_to_cache) + m_media_cache.update(sha1_hex, data); + + return true; +} + +/* + Minetest Hashset File Format + + All values are stored in big-endian byte order. + [u32] signature: 'MTHS' + [u16] version: 1 + For each hash in set: + [u8*20] SHA1 hash + + Version changes: + 1 - Initial version +*/ + +std::string ClientMediaDownloader::serializeRequiredHashSet() +{ + std::ostringstream os(std::ios::binary); + + writeU32(os, MTHASHSET_FILE_SIGNATURE); // signature + writeU16(os, 1); // version + + // Write list of hashes of files that have not been + // received (found in cache) yet + for (const auto &it : m_files) { + if (!it.second->received) { + FATAL_ERROR_IF(it.second->sha1.size() != 20, "Invalid SHA1 size"); + os << it.second->sha1; + } + } + + return os.str(); +} + +void ClientMediaDownloader::deSerializeHashSet(const std::string &data, + std::set<std::string> &result) +{ + if (data.size() < 6 || data.size() % 20 != 6) { + throw SerializationError( + "ClientMediaDownloader::deSerializeHashSet: " + "invalid hash set file size"); + } + + const u8 *data_cstr = (const u8*) data.c_str(); + + u32 signature = readU32(&data_cstr[0]); + if (signature != MTHASHSET_FILE_SIGNATURE) { + throw SerializationError( + "ClientMediaDownloader::deSerializeHashSet: " + "invalid hash set file signature"); + } + + u16 version = readU16(&data_cstr[4]); + if (version != 1) { + throw SerializationError( + "ClientMediaDownloader::deSerializeHashSet: " + "unsupported hash set file version"); + } + + for (u32 pos = 6; pos < data.size(); pos += 20) { + result.insert(data.substr(pos, 20)); + } +} + +/* + SingleMediaDownloader +*/ + +SingleMediaDownloader::SingleMediaDownloader(bool write_to_cache): + m_httpfetch_caller(HTTPFETCH_DISCARD) +{ + m_write_to_cache = write_to_cache; +} + +SingleMediaDownloader::~SingleMediaDownloader() +{ + if (m_httpfetch_caller != HTTPFETCH_DISCARD) + httpfetch_caller_free(m_httpfetch_caller); +} + +bool SingleMediaDownloader::loadMedia(Client *client, const std::string &data, + const std::string &name) +{ + return client->loadMedia(data, name, true); +} + +void SingleMediaDownloader::addFile(const std::string &name, const std::string &sha1) +{ + assert(m_stage == STAGE_INIT); // pre-condition + + assert(!name.empty()); + assert(sha1.size() == 20); + + FATAL_ERROR_IF(!m_file_name.empty(), "Cannot add a second file"); + m_file_name = name; + m_file_sha1 = sha1; +} + +void SingleMediaDownloader::addRemoteServer(const std::string &baseurl) +{ + assert(m_stage == STAGE_INIT); // pre-condition + + if (g_settings->getBool("enable_remote_media_server")) + m_remotes.emplace_back(baseurl); +} + +void SingleMediaDownloader::step(Client *client) +{ + if (m_stage == STAGE_INIT) { + m_stage = STAGE_CACHE_CHECKED; + initialStep(client); + } + + // Remote media: check for completion of fetches + if (m_httpfetch_caller != HTTPFETCH_DISCARD) { + HTTPFetchResult fetch_result; + while (httpfetch_async_get(m_httpfetch_caller, fetch_result)) { + remoteMediaReceived(fetch_result, client); + } + } +} + +bool SingleMediaDownloader::conventionalTransferDone(const std::string &name, + const std::string &data, Client *client) +{ + if (name != m_file_name) + return false; + + // Mark file as received unconditionally and try to load it + m_stage = STAGE_DONE; + checkAndLoad(name, m_file_sha1, data, false, client); + return true; +} + +void SingleMediaDownloader::initialStep(Client *client) +{ + if (tryLoadFromCache(m_file_name, m_file_sha1, client)) + m_stage = STAGE_DONE; + if (isDone()) + return; + + createCacheDirs(); + + // If the server reported no remote servers, immediately fall back to + // conventional transfer. + if (!USE_CURL || m_remotes.empty()) { + startConventionalTransfer(client); + } else { + // Otherwise start by requesting the file from the first remote media server + m_httpfetch_caller = httpfetch_caller_alloc(); + m_current_remote = 0; + startRemoteMediaTransfer(); + } +} + +void SingleMediaDownloader::remoteMediaReceived( + const HTTPFetchResult &fetch_result, Client *client) +{ + sanity_check(!isDone()); + sanity_check(m_current_remote >= 0); + + // If fetch succeeded, try to load it + if (fetch_result.succeeded) { + bool success = checkAndLoad(m_file_name, m_file_sha1, + fetch_result.data, false, client); + if (success) { + m_stage = STAGE_DONE; + return; + } + } + + // Otherwise try the next remote server or fall back to conventional transfer + m_current_remote++; + if (m_current_remote >= (int)m_remotes.size()) { + infostream << "Client: Failed to remote-fetch \"" << m_file_name + << "\". Requesting it the usual way." << std::endl; + m_current_remote = -1; + startConventionalTransfer(client); + } else { + startRemoteMediaTransfer(); + } +} + +void SingleMediaDownloader::startRemoteMediaTransfer() +{ + std::string url = m_remotes.at(m_current_remote) + hex_encode(m_file_sha1); + verbosestream << "Client: Requesting remote media file " + << "\"" << m_file_name << "\" " << "\"" << url << "\"" << std::endl; + + HTTPFetchRequest fetch_request; + fetch_request.url = url; + fetch_request.caller = m_httpfetch_caller; + fetch_request.request_id = m_httpfetch_next_id; + fetch_request.timeout = g_settings->getS32("curl_file_download_timeout"); + httpfetch_async(fetch_request); + + m_httpfetch_next_id++; +} + +void SingleMediaDownloader::startConventionalTransfer(Client *client) +{ + std::vector<std::string> requests; + requests.emplace_back(m_file_name); + client->request_media(requests); +} diff --git a/src/client/clientmedia.h b/src/client/clientmedia.h new file mode 100644 index 0000000..c297d73 --- /dev/null +++ b/src/client/clientmedia.h @@ -0,0 +1,250 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "filecache.h" +#include "util/basic_macros.h" +#include <ostream> +#include <map> +#include <set> +#include <vector> +#include <unordered_map> + +class Client; +struct HTTPFetchResult; + +#define MTHASHSET_FILE_SIGNATURE 0x4d544853 // 'MTHS' +#define MTHASHSET_FILE_NAME "index.mth" + +// Store file into media cache (unless it exists already) +// Validating the hash is responsibility of the caller +bool clientMediaUpdateCache(const std::string &raw_hash, + const std::string &filedata); + +// more of a base class than an interface but this name was most convenient... +class IClientMediaDownloader +{ +public: + DISABLE_CLASS_COPY(IClientMediaDownloader) + + virtual bool isStarted() const = 0; + + // If this returns true, the downloader is done and can be deleted + virtual bool isDone() const = 0; + + // Add a file to the list of required file (but don't fetch it yet) + virtual void addFile(const std::string &name, const std::string &sha1) = 0; + + // Add a remote server to the list; ignored if not built with cURL + virtual void addRemoteServer(const std::string &baseurl) = 0; + + // Steps the media downloader: + // - May load media into client by calling client->loadMedia() + // - May check media cache for files + // - May add files to media cache + // - May start remote transfers by calling httpfetch_async + // - May check for completion of current remote transfers + // - May start conventional transfers by calling client->request_media() + // - May inform server that all media has been loaded + // by calling client->received_media() + // After step has been called once, don't call addFile/addRemoteServer. + virtual void step(Client *client) = 0; + + // Must be called for each file received through TOCLIENT_MEDIA + // returns true if this file belongs to this downloader + virtual bool conventionalTransferDone(const std::string &name, + const std::string &data, Client *client) = 0; + +protected: + IClientMediaDownloader(); + virtual ~IClientMediaDownloader() = default; + + // Forwards the call to the appropriate Client method + virtual bool loadMedia(Client *client, const std::string &data, + const std::string &name) = 0; + + void createCacheDirs(); + + bool tryLoadFromCache(const std::string &name, const std::string &sha1, + Client *client); + + bool checkAndLoad(const std::string &name, const std::string &sha1, + const std::string &data, bool is_from_cache, Client *client); + + // Filesystem-based media cache + FileCache m_media_cache; + bool m_write_to_cache; +}; + +class ClientMediaDownloader : public IClientMediaDownloader +{ +public: + ClientMediaDownloader(); + ~ClientMediaDownloader(); + + float getProgress() const { + if (m_uncached_count >= 1) + return 1.0f * m_uncached_received_count / + m_uncached_count; + + return 0.0f; + } + + bool isStarted() const override { + return m_initial_step_done; + } + + bool isDone() const override { + return m_initial_step_done && + m_uncached_received_count == m_uncached_count; + } + + void addFile(const std::string &name, const std::string &sha1) override; + + void addRemoteServer(const std::string &baseurl) override; + + void step(Client *client) override; + + bool conventionalTransferDone( + const std::string &name, + const std::string &data, + Client *client) override; + +protected: + bool loadMedia(Client *client, const std::string &data, + const std::string &name) override; + +private: + struct FileStatus { + bool received; + std::string sha1; + s32 current_remote; + std::vector<s32> available_remotes; + }; + + struct RemoteServerStatus { + std::string baseurl; + s32 active_count; + }; + + void initialStep(Client *client); + void remoteHashSetReceived(const HTTPFetchResult &fetch_result); + void remoteMediaReceived(const HTTPFetchResult &fetch_result, + Client *client); + s32 selectRemoteServer(FileStatus *filestatus); + void startRemoteMediaTransfers(); + void startConventionalTransfers(Client *client); + + static void deSerializeHashSet(const std::string &data, + std::set<std::string> &result); + std::string serializeRequiredHashSet(); + + // Maps filename to file status + std::map<std::string, FileStatus*> m_files; + + // Array of remote media servers + std::vector<RemoteServerStatus*> m_remotes; + + // Has an attempt been made to load media files from the file cache? + // Have hash sets been requested from remote servers? + bool m_initial_step_done = false; + + // Total number of media files to load + s32 m_uncached_count = 0; + + // Number of media files that have been received + s32 m_uncached_received_count = 0; + + // Status of remote transfers + u64 m_httpfetch_caller; + u64 m_httpfetch_next_id = 0; + s32 m_httpfetch_active = 0; + s32 m_httpfetch_active_limit = 0; + s32 m_outstanding_hash_sets = 0; + std::unordered_map<u64, std::string> m_remote_file_transfers; + + // All files up to this name have either been received from a + // remote server or failed on all remote servers, so those files + // don't need to be looked at again + // (use m_files.upper_bound(m_name_bound) to get an iterator) + std::string m_name_bound = ""; + +}; + +// A media downloader that only downloads a single file. +// It does/doesn't do several things the normal downloader does: +// - won't fetch hash sets from remote servers +// - will mark loaded media as coming from file push +// - writing to file cache is optional +class SingleMediaDownloader : public IClientMediaDownloader +{ +public: + SingleMediaDownloader(bool write_to_cache); + ~SingleMediaDownloader(); + + bool isStarted() const override { + return m_stage > STAGE_INIT; + } + + bool isDone() const override { + return m_stage >= STAGE_DONE; + } + + void addFile(const std::string &name, const std::string &sha1) override; + + void addRemoteServer(const std::string &baseurl) override; + + void step(Client *client) override; + + bool conventionalTransferDone(const std::string &name, + const std::string &data, Client *client) override; + +protected: + bool loadMedia(Client *client, const std::string &data, + const std::string &name) override; + +private: + void initialStep(Client *client); + void remoteMediaReceived(const HTTPFetchResult &fetch_result, Client *client); + void startRemoteMediaTransfer(); + void startConventionalTransfer(Client *client); + + enum Stage { + STAGE_INIT, + STAGE_CACHE_CHECKED, // we have tried to load the file from cache + STAGE_DONE + }; + + // Information about the one file we want to fetch + std::string m_file_name; + std::string m_file_sha1; + s32 m_current_remote; + + // Array of remote media servers + std::vector<std::string> m_remotes; + + enum Stage m_stage = STAGE_INIT; + + // Status of remote transfers + unsigned long m_httpfetch_caller; + unsigned long m_httpfetch_next_id = 0; + +}; diff --git a/src/client/clientobject.cpp b/src/client/clientobject.cpp new file mode 100644 index 0000000..f4b6920 --- /dev/null +++ b/src/client/clientobject.cpp @@ -0,0 +1,66 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "clientobject.h" +#include "debug.h" +#include "porting.h" + +/* + ClientActiveObject +*/ + +ClientActiveObject::ClientActiveObject(u16 id, Client *client, + ClientEnvironment *env): + ActiveObject(id), + m_client(client), + m_env(env) +{ +} + +ClientActiveObject::~ClientActiveObject() +{ + removeFromScene(true); +} + +ClientActiveObject* ClientActiveObject::create(ActiveObjectType type, + Client *client, ClientEnvironment *env) +{ + // Find factory function + auto n = m_types.find(type); + if (n == m_types.end()) { + // If factory is not found, just return. + warningstream << "ClientActiveObject: No factory for type=" + << (int)type << std::endl; + return NULL; + } + + Factory f = n->second; + ClientActiveObject *object = (*f)(client, env); + return object; +} + +void ClientActiveObject::registerType(u16 type, Factory f) +{ + auto n = m_types.find(type); + if (n != m_types.end()) + return; + m_types[type] = f; +} + + diff --git a/src/client/clientobject.h b/src/client/clientobject.h new file mode 100644 index 0000000..b192f0d --- /dev/null +++ b/src/client/clientobject.h @@ -0,0 +1,116 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "activeobject.h" +#include <unordered_map> +#include <unordered_set> + + +class ClientEnvironment; +class ITextureSource; +class Client; +class IGameDef; +class LocalPlayer; +struct ItemStack; +class WieldMeshSceneNode; + +class ClientActiveObject : public ActiveObject +{ +public: + ClientActiveObject(u16 id, Client *client, ClientEnvironment *env); + virtual ~ClientActiveObject(); + + virtual void addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr) = 0; + virtual void removeFromScene(bool permanent) {} + + virtual void updateLight(u32 day_night_ratio) {} + + virtual bool getCollisionBox(aabb3f *toset) const { return false; } + virtual bool getSelectionBox(aabb3f *toset) const { return false; } + virtual bool collideWithObjects() const { return false; } + virtual const v3f getPosition() const { return v3f(0.0f); } + virtual scene::ISceneNode *getSceneNode() const + { return NULL; } + virtual scene::IAnimatedMeshSceneNode *getAnimatedMeshSceneNode() const + { return NULL; } + virtual bool isLocalPlayer() const { return false; } + + virtual ClientActiveObject *getParent() const { return nullptr; }; + virtual const std::unordered_set<int> &getAttachmentChildIds() const + { static std::unordered_set<int> rv; return rv; } + virtual void updateAttachments() {}; + + virtual bool doShowSelectionBox() { return true; } + + // Step object in time + virtual void step(float dtime, ClientEnvironment *env) {} + + // Process a message sent by the server side object + virtual void processMessage(const std::string &data) {} + + virtual std::string infoText() { return ""; } + virtual std::string debugInfoText() { return ""; } + + /* + This takes the return value of + ServerActiveObject::getClientInitializationData + */ + virtual void initialize(const std::string &data) {} + + // Create a certain type of ClientActiveObject + static ClientActiveObject *create(ActiveObjectType type, Client *client, + ClientEnvironment *env); + + // If returns true, punch will not be sent to the server + virtual bool directReportPunch(v3f dir, const ItemStack *punchitem = nullptr, + float time_from_last_punch = 1000000) { return false; } + +protected: + // Used for creating objects based on type + typedef ClientActiveObject *(*Factory)(Client *client, ClientEnvironment *env); + static void registerType(u16 type, Factory f); + Client *m_client; + ClientEnvironment *m_env; +private: + // Used for creating objects based on type + static std::unordered_map<u16, Factory> m_types; +}; + +class DistanceSortedActiveObject +{ +public: + ClientActiveObject *obj; + + DistanceSortedActiveObject(ClientActiveObject *a_obj, f32 a_d) + { + obj = a_obj; + d = a_d; + } + + bool operator < (const DistanceSortedActiveObject &other) const + { + return d < other.d; + } + +private: + f32 d; +}; diff --git a/src/client/clientsimpleobject.h b/src/client/clientsimpleobject.h new file mode 100644 index 0000000..f4a40bc --- /dev/null +++ b/src/client/clientsimpleobject.h @@ -0,0 +1,35 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +class ClientEnvironment; + +class ClientSimpleObject +{ +protected: +public: + bool m_to_be_removed = false; + + ClientSimpleObject() = default; + virtual ~ClientSimpleObject() = default; + + virtual void step(float dtime) {} +}; diff --git a/src/client/clouds.cpp b/src/client/clouds.cpp new file mode 100644 index 0000000..c84c030 --- /dev/null +++ b/src/client/clouds.cpp @@ -0,0 +1,385 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "client/renderingengine.h" +#include "clouds.h" +#include "noise.h" +#include "constants.h" +#include "debug.h" +#include "profiler.h" +#include "settings.h" +#include <cmath> + + +// Menu clouds are created later +class Clouds; +Clouds *g_menuclouds = NULL; +scene::ISceneManager *g_menucloudsmgr = NULL; + +// Constant for now +static constexpr const float cloud_size = BS * 64.0f; + +static void cloud_3d_setting_changed(const std::string &settingname, void *data) +{ + ((Clouds *)data)->readSettings(); +} + +Clouds::Clouds(scene::ISceneManager* mgr, + s32 id, + u32 seed +): + scene::ISceneNode(mgr->getRootSceneNode(), mgr, id), + m_seed(seed) +{ + m_material.setFlag(video::EMF_LIGHTING, false); + //m_material.setFlag(video::EMF_BACK_FACE_CULLING, false); + m_material.setFlag(video::EMF_BACK_FACE_CULLING, true); + m_material.setFlag(video::EMF_BILINEAR_FILTER, false); + m_material.setFlag(video::EMF_FOG_ENABLE, true); + m_material.setFlag(video::EMF_ANTI_ALIASING, true); + //m_material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + + m_params.height = 120; + m_params.density = 0.4f; + m_params.thickness = 16.0f; + m_params.color_bright = video::SColor(229, 240, 240, 255); + m_params.color_ambient = video::SColor(255, 0, 0, 0); + m_params.speed = v2f(0.0f, -2.0f); + + readSettings(); + g_settings->registerChangedCallback("enable_3d_clouds", + &cloud_3d_setting_changed, this); + + updateBox(); +} + +Clouds::~Clouds() +{ + g_settings->deregisterChangedCallback("enable_3d_clouds", + &cloud_3d_setting_changed, this); +} + +void Clouds::OnRegisterSceneNode() +{ + if(IsVisible) + { + SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); + //SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); + } + + ISceneNode::OnRegisterSceneNode(); +} + +void Clouds::render() +{ + + if (m_params.density <= 0.0f) + return; // no need to do anything + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT) + //if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SOLID) + return; + + ScopeProfiler sp(g_profiler, "Clouds::render()", SPT_AVG); + + int num_faces_to_draw = m_enable_3d ? 6 : 1; + + m_material.setFlag(video::EMF_BACK_FACE_CULLING, m_enable_3d); + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + driver->setMaterial(m_material); + + /* + Clouds move from Z+ towards Z- + */ + + const float cloud_full_radius = cloud_size * m_cloud_radius_i; + + v2f camera_pos_2d(m_camera_pos.X, m_camera_pos.Z); + // Position of cloud noise origin from the camera + v2f cloud_origin_from_camera_f = m_origin - camera_pos_2d; + // The center point of drawing in the noise + v2f center_of_drawing_in_noise_f = -cloud_origin_from_camera_f; + // The integer center point of drawing in the noise + v2s16 center_of_drawing_in_noise_i( + std::floor(center_of_drawing_in_noise_f.X / cloud_size), + std::floor(center_of_drawing_in_noise_f.Y / cloud_size) + ); + + // The world position of the integer center point of drawing in the noise + v2f world_center_of_drawing_in_noise_f = v2f( + center_of_drawing_in_noise_i.X * cloud_size, + center_of_drawing_in_noise_i.Y * cloud_size + ) + m_origin; + + /*video::SColor c_top(128,b*240,b*240,b*255); + video::SColor c_side_1(128,b*230,b*230,b*255); + video::SColor c_side_2(128,b*220,b*220,b*245); + video::SColor c_bottom(128,b*205,b*205,b*230);*/ + video::SColorf c_top_f(m_color); + video::SColorf c_side_1_f(m_color); + video::SColorf c_side_2_f(m_color); + video::SColorf c_bottom_f(m_color); + c_side_1_f.r *= 0.95; + c_side_1_f.g *= 0.95; + c_side_1_f.b *= 0.95; + c_side_2_f.r *= 0.90; + c_side_2_f.g *= 0.90; + c_side_2_f.b *= 0.90; + c_bottom_f.r *= 0.80; + c_bottom_f.g *= 0.80; + c_bottom_f.b *= 0.80; + video::SColor c_top = c_top_f.toSColor(); + video::SColor c_side_1 = c_side_1_f.toSColor(); + video::SColor c_side_2 = c_side_2_f.toSColor(); + video::SColor c_bottom = c_bottom_f.toSColor(); + + // Get fog parameters for setting them back later + video::SColor fog_color(0,0,0,0); + video::E_FOG_TYPE fog_type = video::EFT_FOG_LINEAR; + f32 fog_start = 0; + f32 fog_end = 0; + f32 fog_density = 0; + bool fog_pixelfog = false; + bool fog_rangefog = false; + driver->getFog(fog_color, fog_type, fog_start, fog_end, fog_density, + fog_pixelfog, fog_rangefog); + + // Set our own fog + driver->setFog(fog_color, fog_type, cloud_full_radius * 0.5, + cloud_full_radius*1.2, fog_density, fog_pixelfog, fog_rangefog); + + // Read noise + + std::vector<bool> grid(m_cloud_radius_i * 2 * m_cloud_radius_i * 2); + std::vector<video::S3DVertex> vertices; + vertices.reserve(16 * m_cloud_radius_i * m_cloud_radius_i); + + for(s16 zi = -m_cloud_radius_i; zi < m_cloud_radius_i; zi++) { + u32 si = (zi + m_cloud_radius_i) * m_cloud_radius_i * 2 + m_cloud_radius_i; + + for (s16 xi = -m_cloud_radius_i; xi < m_cloud_radius_i; xi++) { + u32 i = si + xi; + + grid[i] = gridFilled( + xi + center_of_drawing_in_noise_i.X, + zi + center_of_drawing_in_noise_i.Y + ); + } + } + +#define GETINDEX(x, z, radius) (((z)+(radius))*(radius)*2 + (x)+(radius)) +#define INAREA(x, z, radius) \ + ((x) >= -(radius) && (x) < (radius) && (z) >= -(radius) && (z) < (radius)) + + for (s16 zi0= -m_cloud_radius_i; zi0 < m_cloud_radius_i; zi0++) + for (s16 xi0= -m_cloud_radius_i; xi0 < m_cloud_radius_i; xi0++) + { + s16 zi = zi0; + s16 xi = xi0; + // Draw from back to front for proper transparency + if(zi >= 0) + zi = m_cloud_radius_i - zi - 1; + if(xi >= 0) + xi = m_cloud_radius_i - xi - 1; + + u32 i = GETINDEX(xi, zi, m_cloud_radius_i); + + if (!grid[i]) + continue; + + v2f p0 = v2f(xi,zi)*cloud_size + world_center_of_drawing_in_noise_f; + + video::S3DVertex v[4] = { + video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 1), + video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 1), + video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 0), + video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 0) + }; + + const f32 rx = cloud_size / 2.0f; + // if clouds are flat, the top layer should be at the given height + const f32 ry = m_enable_3d ? m_params.thickness * BS : 0.0f; + const f32 rz = cloud_size / 2; + + for(int i=0; i<num_faces_to_draw; i++) + { + switch(i) + { + case 0: // top + for (video::S3DVertex &vertex : v) { + vertex.Normal.set(0,1,0); + } + v[0].Pos.set(-rx, ry,-rz); + v[1].Pos.set(-rx, ry, rz); + v[2].Pos.set( rx, ry, rz); + v[3].Pos.set( rx, ry,-rz); + break; + case 1: // back + if (INAREA(xi, zi - 1, m_cloud_radius_i)) { + u32 j = GETINDEX(xi, zi - 1, m_cloud_radius_i); + if(grid[j]) + continue; + } + for (video::S3DVertex &vertex : v) { + vertex.Color = c_side_1; + vertex.Normal.set(0,0,-1); + } + v[0].Pos.set(-rx, ry,-rz); + v[1].Pos.set( rx, ry,-rz); + v[2].Pos.set( rx, 0,-rz); + v[3].Pos.set(-rx, 0,-rz); + break; + case 2: //right + if (INAREA(xi + 1, zi, m_cloud_radius_i)) { + u32 j = GETINDEX(xi+1, zi, m_cloud_radius_i); + if(grid[j]) + continue; + } + for (video::S3DVertex &vertex : v) { + vertex.Color = c_side_2; + vertex.Normal.set(1,0,0); + } + v[0].Pos.set( rx, ry,-rz); + v[1].Pos.set( rx, ry, rz); + v[2].Pos.set( rx, 0, rz); + v[3].Pos.set( rx, 0,-rz); + break; + case 3: // front + if (INAREA(xi, zi + 1, m_cloud_radius_i)) { + u32 j = GETINDEX(xi, zi + 1, m_cloud_radius_i); + if(grid[j]) + continue; + } + for (video::S3DVertex &vertex : v) { + vertex.Color = c_side_1; + vertex.Normal.set(0,0,-1); + } + v[0].Pos.set( rx, ry, rz); + v[1].Pos.set(-rx, ry, rz); + v[2].Pos.set(-rx, 0, rz); + v[3].Pos.set( rx, 0, rz); + break; + case 4: // left + if (INAREA(xi-1, zi, m_cloud_radius_i)) { + u32 j = GETINDEX(xi-1, zi, m_cloud_radius_i); + if(grid[j]) + continue; + } + for (video::S3DVertex &vertex : v) { + vertex.Color = c_side_2; + vertex.Normal.set(-1,0,0); + } + v[0].Pos.set(-rx, ry, rz); + v[1].Pos.set(-rx, ry,-rz); + v[2].Pos.set(-rx, 0,-rz); + v[3].Pos.set(-rx, 0, rz); + break; + case 5: // bottom + for (video::S3DVertex &vertex : v) { + vertex.Color = c_bottom; + vertex.Normal.set(0,-1,0); + } + v[0].Pos.set( rx, 0, rz); + v[1].Pos.set(-rx, 0, rz); + v[2].Pos.set(-rx, 0,-rz); + v[3].Pos.set( rx, 0,-rz); + break; + } + + v3f pos(p0.X, m_params.height * BS, p0.Y); + pos -= intToFloat(m_camera_offset, BS); + + for (video::S3DVertex &vertex : v) { + vertex.Pos += pos; + vertices.push_back(vertex); + } + } + } + int quad_count = vertices.size() / 4; + std::vector<u16> indices; + indices.reserve(quad_count * 6); + for (int k = 0; k < quad_count; k++) { + indices.push_back(4 * k + 0); + indices.push_back(4 * k + 1); + indices.push_back(4 * k + 2); + indices.push_back(4 * k + 2); + indices.push_back(4 * k + 3); + indices.push_back(4 * k + 0); + } + driver->drawVertexPrimitiveList(vertices.data(), vertices.size(), indices.data(), 2 * quad_count, + video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT); + + // Restore fog settings + driver->setFog(fog_color, fog_type, fog_start, fog_end, fog_density, + fog_pixelfog, fog_rangefog); +} + +void Clouds::step(float dtime) +{ + m_origin = m_origin + dtime * BS * m_params.speed; +} + +void Clouds::update(const v3f &camera_p, const video::SColorf &color_diffuse) +{ + video::SColorf ambient(m_params.color_ambient); + video::SColorf bright(m_params.color_bright); + m_camera_pos = camera_p; + m_color.r = core::clamp(color_diffuse.r * bright.r, ambient.r, 1.0f); + m_color.g = core::clamp(color_diffuse.g * bright.g, ambient.g, 1.0f); + m_color.b = core::clamp(color_diffuse.b * bright.b, ambient.b, 1.0f); + m_color.a = bright.a; + + // is the camera inside the cloud mesh? + m_camera_inside_cloud = false; // default + if (m_enable_3d) { + float camera_height = camera_p.Y - BS * m_camera_offset.Y; + if (camera_height >= m_box.MinEdge.Y && + camera_height <= m_box.MaxEdge.Y) { + v2f camera_in_noise; + camera_in_noise.X = floor((camera_p.X - m_origin.X) / cloud_size + 0.5); + camera_in_noise.Y = floor((camera_p.Z - m_origin.Y) / cloud_size + 0.5); + bool filled = gridFilled(camera_in_noise.X, camera_in_noise.Y); + m_camera_inside_cloud = filled; + } + } +} + +void Clouds::readSettings() +{ + // Upper limit was chosen due to posible render bugs + m_cloud_radius_i = rangelim(g_settings->getU16("cloud_radius"), 1, 62); + m_enable_3d = g_settings->getBool("enable_3d_clouds"); +} + +bool Clouds::gridFilled(int x, int y) const +{ + float cloud_size_noise = cloud_size / (BS * 200.f); + float noise = noise2d_perlin( + (float)x * cloud_size_noise, + (float)y * cloud_size_noise, + m_seed, 3, 0.5); + // normalize to 0..1 (given 3 octaves) + static constexpr const float noise_bound = 1.0f + 0.5f + 0.25f; + float density = noise / noise_bound * 0.5f + 0.5f; + return (density < m_params.density); +} diff --git a/src/client/clouds.h b/src/client/clouds.h new file mode 100644 index 0000000..6db88d9 --- /dev/null +++ b/src/client/clouds.h @@ -0,0 +1,143 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include <iostream> +#include "constants.h" +#include "skyparams.h" + +// Menu clouds +class Clouds; +extern Clouds *g_menuclouds; + +// Scene manager used for menu clouds +extern scene::ISceneManager *g_menucloudsmgr; + +class Clouds : public scene::ISceneNode +{ +public: + Clouds(scene::ISceneManager* mgr, + s32 id, + u32 seed + ); + + ~Clouds(); + + /* + ISceneNode methods + */ + + virtual void OnRegisterSceneNode(); + + virtual void render(); + + virtual const aabb3f &getBoundingBox() const + { + return m_box; + } + + virtual u32 getMaterialCount() const + { + return 1; + } + + virtual video::SMaterial& getMaterial(u32 i) + { + return m_material; + } + + /* + Other stuff + */ + + void step(float dtime); + + void update(const v3f &camera_p, const video::SColorf &color); + + void updateCameraOffset(const v3s16 &camera_offset) + { + m_camera_offset = camera_offset; + updateBox(); + } + + void readSettings(); + + void setDensity(float density) + { + m_params.density = density; + // currently does not need bounding + } + + void setColorBright(const video::SColor &color_bright) + { + m_params.color_bright = color_bright; + } + + void setColorAmbient(const video::SColor &color_ambient) + { + m_params.color_ambient = color_ambient; + } + + void setHeight(float height) + { + m_params.height = height; // add bounding when necessary + updateBox(); + } + + void setSpeed(v2f speed) + { + m_params.speed = speed; + } + + void setThickness(float thickness) + { + m_params.thickness = thickness; + updateBox(); + } + + bool isCameraInsideCloud() const { return m_camera_inside_cloud; } + + const video::SColor getColor() const { return m_color.toSColor(); } + +private: + void updateBox() + { + float height_bs = m_params.height * BS; + float thickness_bs = m_params.thickness * BS; + m_box = aabb3f(-BS * 1000000.0f, height_bs - BS * m_camera_offset.Y, -BS * 1000000.0f, + BS * 1000000.0f, height_bs + thickness_bs - BS * m_camera_offset.Y, BS * 1000000.0f); + } + + bool gridFilled(int x, int y) const; + + video::SMaterial m_material; + aabb3f m_box; + u16 m_cloud_radius_i; + bool m_enable_3d; + u32 m_seed; + v3f m_camera_pos; + v2f m_origin; + v3s16 m_camera_offset; + video::SColorf m_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); + CloudParams m_params; + bool m_camera_inside_cloud = false; + +}; diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp new file mode 100644 index 0000000..ac4a8f6 --- /dev/null +++ b/src/client/content_cao.cpp @@ -0,0 +1,1988 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "content_cao.h" +#include <IBillboardSceneNode.h> +#include <ICameraSceneNode.h> +#include <IMeshManipulator.h> +#include <IAnimatedMeshSceneNode.h> +#include "client/client.h" +#include "client/renderingengine.h" +#include "client/sound.h" +#include "client/tile.h" +#include "util/basic_macros.h" +#include "util/numeric.h" +#include "util/serialize.h" +#include "camera.h" // CameraModes +#include "collision.h" +#include "content_cso.h" +#include "environment.h" +#include "itemdef.h" +#include "localplayer.h" +#include "map.h" +#include "mesh.h" +#include "nodedef.h" +#include "settings.h" +#include "tool.h" +#include "wieldmesh.h" +#include <algorithm> +#include <cmath> +#include "client/shader.h" +#include "client/minimap.h" + +class Settings; +struct ToolCapabilities; + +std::unordered_map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types; + +template<typename T> +void SmoothTranslator<T>::init(T current) +{ + val_old = current; + val_current = current; + val_target = current; + anim_time = 0; + anim_time_counter = 0; + aim_is_end = true; +} + +template<typename T> +void SmoothTranslator<T>::update(T new_target, bool is_end_position, float update_interval) +{ + aim_is_end = is_end_position; + val_old = val_current; + val_target = new_target; + if (update_interval > 0) { + anim_time = update_interval; + } else { + if (anim_time < 0.001 || anim_time > 1.0) + anim_time = anim_time_counter; + else + anim_time = anim_time * 0.9 + anim_time_counter * 0.1; + } + anim_time_counter = 0; +} + +template<typename T> +void SmoothTranslator<T>::translate(f32 dtime) +{ + anim_time_counter = anim_time_counter + dtime; + T val_diff = val_target - val_old; + f32 moveratio = 1.0; + if (anim_time > 0.001) + moveratio = anim_time_counter / anim_time; + f32 move_end = aim_is_end ? 1.0 : 1.5; + + // Move a bit less than should, to avoid oscillation + moveratio = std::min(moveratio * 0.8f, move_end); + val_current = val_old + val_diff * moveratio; +} + +void SmoothTranslatorWrapped::translate(f32 dtime) +{ + anim_time_counter = anim_time_counter + dtime; + f32 val_diff = std::abs(val_target - val_old); + if (val_diff > 180.f) + val_diff = 360.f - val_diff; + + f32 moveratio = 1.0; + if (anim_time > 0.001) + moveratio = anim_time_counter / anim_time; + f32 move_end = aim_is_end ? 1.0 : 1.5; + + // Move a bit less than should, to avoid oscillation + moveratio = std::min(moveratio * 0.8f, move_end); + wrappedApproachShortest(val_current, val_target, + val_diff * moveratio, 360.f); +} + +void SmoothTranslatorWrappedv3f::translate(f32 dtime) +{ + anim_time_counter = anim_time_counter + dtime; + + v3f val_diff_v3f; + val_diff_v3f.X = std::abs(val_target.X - val_old.X); + val_diff_v3f.Y = std::abs(val_target.Y - val_old.Y); + val_diff_v3f.Z = std::abs(val_target.Z - val_old.Z); + + if (val_diff_v3f.X > 180.f) + val_diff_v3f.X = 360.f - val_diff_v3f.X; + + if (val_diff_v3f.Y > 180.f) + val_diff_v3f.Y = 360.f - val_diff_v3f.Y; + + if (val_diff_v3f.Z > 180.f) + val_diff_v3f.Z = 360.f - val_diff_v3f.Z; + + f32 moveratio = 1.0; + if (anim_time > 0.001) + moveratio = anim_time_counter / anim_time; + f32 move_end = aim_is_end ? 1.0 : 1.5; + + // Move a bit less than should, to avoid oscillation + moveratio = std::min(moveratio * 0.8f, move_end); + wrappedApproachShortest(val_current.X, val_target.X, + val_diff_v3f.X * moveratio, 360.f); + + wrappedApproachShortest(val_current.Y, val_target.Y, + val_diff_v3f.Y * moveratio, 360.f); + + wrappedApproachShortest(val_current.Z, val_target.Z, + val_diff_v3f.Z * moveratio, 360.f); +} + +/* + Other stuff +*/ + +static void setBillboardTextureMatrix(scene::IBillboardSceneNode *bill, + float txs, float tys, int col, int row) +{ + video::SMaterial& material = bill->getMaterial(0); + core::matrix4& matrix = material.getTextureMatrix(0); + matrix.setTextureTranslate(txs*col, tys*row); + matrix.setTextureScale(txs, tys); +} + +// Evaluate transform chain recursively; irrlicht does not do this for us +static void updatePositionRecursive(scene::ISceneNode *node) +{ + scene::ISceneNode *parent = node->getParent(); + if (parent) + updatePositionRecursive(parent); + node->updateAbsolutePosition(); +} + +static bool logOnce(const std::ostringstream &from, std::ostream &log_to) +{ + thread_local std::vector<u64> logged; + + std::string message = from.str(); + u64 hash = murmur_hash_64_ua(message.data(), message.length(), 0xBADBABE); + + if (std::find(logged.begin(), logged.end(), hash) != logged.end()) + return false; + logged.push_back(hash); + log_to << message << std::endl; + return true; +} + +/* + TestCAO +*/ + +class TestCAO : public ClientActiveObject +{ +public: + TestCAO(Client *client, ClientEnvironment *env); + virtual ~TestCAO() = default; + + ActiveObjectType getType() const + { + return ACTIVEOBJECT_TYPE_TEST; + } + + static ClientActiveObject* create(Client *client, ClientEnvironment *env); + + void addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr); + void removeFromScene(bool permanent); + void updateLight(u32 day_night_ratio); + void updateNodePos(); + + void step(float dtime, ClientEnvironment *env); + + void processMessage(const std::string &data); + + bool getCollisionBox(aabb3f *toset) const { return false; } +private: + scene::IMeshSceneNode *m_node; + v3f m_position; +}; + +// Prototype +TestCAO proto_TestCAO(NULL, NULL); + +TestCAO::TestCAO(Client *client, ClientEnvironment *env): + ClientActiveObject(0, client, env), + m_node(NULL), + m_position(v3f(0,10*BS,0)) +{ + ClientActiveObject::registerType(getType(), create); +} + +ClientActiveObject* TestCAO::create(Client *client, ClientEnvironment *env) +{ + return new TestCAO(client, env); +} + +void TestCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr) +{ + if(m_node != NULL) + return; + + //video::IVideoDriver* driver = smgr->getVideoDriver(); + + scene::SMesh *mesh = new scene::SMesh(); + scene::IMeshBuffer *buf = new scene::SMeshBuffer(); + video::SColor c(255,255,255,255); + video::S3DVertex vertices[4] = + { + video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1), + video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1), + video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0), + video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0), + }; + u16 indices[] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + // Set material + buf->getMaterial().setFlag(video::EMF_LIGHTING, false); + buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); + buf->getMaterial().setTexture(0, tsrc->getTextureForMesh("rat.png")); + buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); + buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + // Add to mesh + mesh->addMeshBuffer(buf); + buf->drop(); + m_node = smgr->addMeshSceneNode(mesh, NULL); + mesh->drop(); + updateNodePos(); +} + +void TestCAO::removeFromScene(bool permanent) +{ + if (!m_node) + return; + + m_node->remove(); + m_node = NULL; +} + +void TestCAO::updateLight(u32 day_night_ratio) +{ +} + +void TestCAO::updateNodePos() +{ + if (!m_node) + return; + + m_node->setPosition(m_position); + //m_node->setRotation(v3f(0, 45, 0)); +} + +void TestCAO::step(float dtime, ClientEnvironment *env) +{ + if(m_node) + { + v3f rot = m_node->getRotation(); + //infostream<<"dtime="<<dtime<<", rot.Y="<<rot.Y<<std::endl; + rot.Y += dtime * 180; + m_node->setRotation(rot); + } +} + +void TestCAO::processMessage(const std::string &data) +{ + infostream<<"TestCAO: Got data: "<<data<<std::endl; + std::istringstream is(data, std::ios::binary); + u16 cmd; + is>>cmd; + if(cmd == 0) + { + v3f newpos; + is>>newpos.X; + is>>newpos.Y; + is>>newpos.Z; + m_position = newpos; + updateNodePos(); + } +} + +/* + GenericCAO +*/ + +#include "clientobject.h" + +GenericCAO::GenericCAO(Client *client, ClientEnvironment *env): + ClientActiveObject(0, client, env) +{ + if (client == NULL) { + ClientActiveObject::registerType(getType(), create); + } else { + m_client = client; + } +} + +bool GenericCAO::getCollisionBox(aabb3f *toset) const +{ + if (m_prop.physical) + { + //update collision box + toset->MinEdge = m_prop.collisionbox.MinEdge * BS; + toset->MaxEdge = m_prop.collisionbox.MaxEdge * BS; + + toset->MinEdge += m_position; + toset->MaxEdge += m_position; + + return true; + } + + return false; +} + +bool GenericCAO::collideWithObjects() const +{ + return m_prop.collideWithObjects; +} + +void GenericCAO::initialize(const std::string &data) +{ + infostream<<"GenericCAO: Got init data"<<std::endl; + processInitData(data); + + m_enable_shaders = g_settings->getBool("enable_shaders"); +} + +void GenericCAO::processInitData(const std::string &data) +{ + std::istringstream is(data, std::ios::binary); + const u8 version = readU8(is); + + if (version < 1) { + errorstream << "GenericCAO: Unsupported init data version" + << std::endl; + return; + } + + // PROTOCOL_VERSION >= 37 + m_name = deSerializeString16(is); + m_is_player = readU8(is); + m_id = readU16(is); + m_position = readV3F32(is); + m_rotation = readV3F32(is); + m_hp = readU16(is); + + if (m_is_player) { + // Check if it's the current player + LocalPlayer *player = m_env->getLocalPlayer(); + if (player && strcmp(player->getName(), m_name.c_str()) == 0) { + m_is_local_player = true; + m_is_visible = false; + player->setCAO(this); + } + } + + const u8 num_messages = readU8(is); + + for (int i = 0; i < num_messages; i++) { + std::string message = deSerializeString32(is); + processMessage(message); + } + + m_rotation = wrapDegrees_0_360_v3f(m_rotation); + pos_translator.init(m_position); + rot_translator.init(m_rotation); + updateNodePos(); +} + +GenericCAO::~GenericCAO() +{ + removeFromScene(true); +} + +bool GenericCAO::getSelectionBox(aabb3f *toset) const +{ + if (!m_prop.is_visible || !m_is_visible || m_is_local_player + || !m_prop.pointable) { + return false; + } + *toset = m_selection_box; + return true; +} + +const v3f GenericCAO::getPosition() const +{ + if (!getParent()) + return pos_translator.val_current; + + // Calculate real position in world based on MatrixNode + if (m_matrixnode) { + v3s16 camera_offset = m_env->getCameraOffset(); + return m_matrixnode->getAbsolutePosition() + + intToFloat(camera_offset, BS); + } + + return m_position; +} + +bool GenericCAO::isImmortal() const +{ + return itemgroup_get(getGroups(), "immortal"); +} + +scene::ISceneNode *GenericCAO::getSceneNode() const +{ + if (m_meshnode) { + return m_meshnode; + } + + if (m_animated_meshnode) { + return m_animated_meshnode; + } + + if (m_wield_meshnode) { + return m_wield_meshnode; + } + + if (m_spritenode) { + return m_spritenode; + } + return NULL; +} + +scene::IAnimatedMeshSceneNode *GenericCAO::getAnimatedMeshSceneNode() const +{ + return m_animated_meshnode; +} + +void GenericCAO::setChildrenVisible(bool toset) +{ + for (u16 cao_id : m_attachment_child_ids) { + GenericCAO *obj = m_env->getGenericCAO(cao_id); + if (obj) { + // Check if the entity is forced to appear in first person. + obj->setVisible(obj->m_force_visible ? true : toset); + } + } +} + +void GenericCAO::setAttachment(int parent_id, const std::string &bone, + v3f position, v3f rotation, bool force_visible) +{ + int old_parent = m_attachment_parent_id; + m_attachment_parent_id = parent_id; + m_attachment_bone = bone; + m_attachment_position = position; + m_attachment_rotation = rotation; + m_force_visible = force_visible; + + ClientActiveObject *parent = m_env->getActiveObject(parent_id); + + if (parent_id != old_parent) { + if (auto *o = m_env->getActiveObject(old_parent)) + o->removeAttachmentChild(m_id); + if (parent) + parent->addAttachmentChild(m_id); + } + updateAttachments(); + + // Forcibly show attachments if required by set_attach + if (m_force_visible) { + m_is_visible = true; + } else if (!m_is_local_player) { + // Objects attached to the local player should be hidden in first person + m_is_visible = !m_attached_to_local || + m_client->getCamera()->getCameraMode() != CAMERA_MODE_FIRST; + m_force_visible = false; + } else { + // Local players need to have this set, + // otherwise first person attachments fail. + m_is_visible = true; + } +} + +void GenericCAO::getAttachment(int *parent_id, std::string *bone, v3f *position, + v3f *rotation, bool *force_visible) const +{ + *parent_id = m_attachment_parent_id; + *bone = m_attachment_bone; + *position = m_attachment_position; + *rotation = m_attachment_rotation; + *force_visible = m_force_visible; +} + +void GenericCAO::clearChildAttachments() +{ + // Cannot use for-loop here: setAttachment() modifies 'm_attachment_child_ids'! + while (!m_attachment_child_ids.empty()) { + int child_id = *m_attachment_child_ids.begin(); + + if (ClientActiveObject *child = m_env->getActiveObject(child_id)) + child->setAttachment(0, "", v3f(), v3f(), false); + + removeAttachmentChild(child_id); + } +} + +void GenericCAO::clearParentAttachment() +{ + if (m_attachment_parent_id) + setAttachment(0, "", m_attachment_position, m_attachment_rotation, false); + else + setAttachment(0, "", v3f(), v3f(), false); +} + +void GenericCAO::addAttachmentChild(int child_id) +{ + m_attachment_child_ids.insert(child_id); +} + +void GenericCAO::removeAttachmentChild(int child_id) +{ + m_attachment_child_ids.erase(child_id); +} + +ClientActiveObject* GenericCAO::getParent() const +{ + return m_attachment_parent_id ? m_env->getActiveObject(m_attachment_parent_id) : + nullptr; +} + +void GenericCAO::removeFromScene(bool permanent) +{ + // Should be true when removing the object permanently + // and false when refreshing (eg: updating visuals) + if (m_env && permanent) { + // The client does not know whether this object does re-appear to + // a later time, thus do not clear child attachments. + + clearParentAttachment(); + } + + if (auto shadow = RenderingEngine::get_shadow_renderer()) + shadow->removeNodeFromShadowList(getSceneNode()); + + if (m_meshnode) { + m_meshnode->remove(); + m_meshnode->drop(); + m_meshnode = nullptr; + } else if (m_animated_meshnode) { + m_animated_meshnode->remove(); + m_animated_meshnode->drop(); + m_animated_meshnode = nullptr; + } else if (m_wield_meshnode) { + m_wield_meshnode->remove(); + m_wield_meshnode->drop(); + m_wield_meshnode = nullptr; + } else if (m_spritenode) { + m_spritenode->remove(); + m_spritenode->drop(); + m_spritenode = nullptr; + } + + if (m_matrixnode) { + m_matrixnode->remove(); + m_matrixnode->drop(); + m_matrixnode = nullptr; + } + + if (m_nametag) { + m_client->getCamera()->removeNametag(m_nametag); + m_nametag = nullptr; + } + + if (m_marker && m_client->getMinimap()) + m_client->getMinimap()->removeMarker(&m_marker); +} + +void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr) +{ + m_smgr = smgr; + + if (getSceneNode() != NULL) { + return; + } + + m_visuals_expired = false; + + if (!m_prop.is_visible) + return; + + infostream << "GenericCAO::addToScene(): " << m_prop.visual << std::endl; + + if (m_enable_shaders) { + IShaderSource *shader_source = m_client->getShaderSource(); + MaterialType material_type; + + if (m_prop.shaded && m_prop.glow == 0) + material_type = (m_prop.use_texture_alpha) ? + TILE_MATERIAL_ALPHA : TILE_MATERIAL_BASIC; + else + material_type = (m_prop.use_texture_alpha) ? + TILE_MATERIAL_PLAIN_ALPHA : TILE_MATERIAL_PLAIN; + + u32 shader_id = shader_source->getShader("object_shader", material_type, NDT_NORMAL); + m_material_type = shader_source->getShaderInfo(shader_id).material; + } else { + m_material_type = (m_prop.use_texture_alpha) ? + video::EMT_TRANSPARENT_ALPHA_CHANNEL : video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + } + + auto grabMatrixNode = [this] { + m_matrixnode = m_smgr->addDummyTransformationSceneNode(); + m_matrixnode->grab(); + }; + + auto setSceneNodeMaterial = [this] (scene::ISceneNode *node) { + node->setMaterialFlag(video::EMF_LIGHTING, false); + node->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); + node->setMaterialFlag(video::EMF_FOG_ENABLE, true); + node->setMaterialType(m_material_type); + + if (m_enable_shaders) { + node->setMaterialFlag(video::EMF_GOURAUD_SHADING, false); + node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true); + } + }; + + if (m_prop.visual == "sprite") { + grabMatrixNode(); + m_spritenode = m_smgr->addBillboardSceneNode( + m_matrixnode, v2f(1, 1), v3f(0,0,0), -1); + m_spritenode->grab(); + m_spritenode->setMaterialTexture(0, + tsrc->getTextureForMesh("no_texture.png")); + + setSceneNodeMaterial(m_spritenode); + + m_spritenode->setSize(v2f(m_prop.visual_size.X, + m_prop.visual_size.Y) * BS); + { + const float txs = 1.0 / 1; + const float tys = 1.0 / 1; + setBillboardTextureMatrix(m_spritenode, + txs, tys, 0, 0); + } + } else if (m_prop.visual == "upright_sprite") { + grabMatrixNode(); + scene::SMesh *mesh = new scene::SMesh(); + double dx = BS * m_prop.visual_size.X / 2; + double dy = BS * m_prop.visual_size.Y / 2; + video::SColor c(0xFFFFFFFF); + + { // Front + scene::IMeshBuffer *buf = new scene::SMeshBuffer(); + video::S3DVertex vertices[4] = { + video::S3DVertex(-dx, -dy, 0, 0,0,1, c, 1,1), + video::S3DVertex( dx, -dy, 0, 0,0,1, c, 0,1), + video::S3DVertex( dx, dy, 0, 0,0,1, c, 0,0), + video::S3DVertex(-dx, dy, 0, 0,0,1, c, 1,0), + }; + if (m_is_player) { + // Move minimal Y position to 0 (feet position) + for (video::S3DVertex &vertex : vertices) + vertex.Pos.Y += dy; + } + u16 indices[] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + // Set material + buf->getMaterial().setFlag(video::EMF_LIGHTING, false); + buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); + buf->getMaterial().MaterialType = m_material_type; + + if (m_enable_shaders) { + buf->getMaterial().EmissiveColor = c; + buf->getMaterial().setFlag(video::EMF_GOURAUD_SHADING, false); + buf->getMaterial().setFlag(video::EMF_NORMALIZE_NORMALS, true); + } + + // Add to mesh + mesh->addMeshBuffer(buf); + buf->drop(); + } + { // Back + scene::IMeshBuffer *buf = new scene::SMeshBuffer(); + video::S3DVertex vertices[4] = { + video::S3DVertex( dx,-dy, 0, 0,0,-1, c, 1,1), + video::S3DVertex(-dx,-dy, 0, 0,0,-1, c, 0,1), + video::S3DVertex(-dx, dy, 0, 0,0,-1, c, 0,0), + video::S3DVertex( dx, dy, 0, 0,0,-1, c, 1,0), + }; + if (m_is_player) { + // Move minimal Y position to 0 (feet position) + for (video::S3DVertex &vertex : vertices) + vertex.Pos.Y += dy; + } + u16 indices[] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + // Set material + buf->getMaterial().setFlag(video::EMF_LIGHTING, false); + buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); + buf->getMaterial().MaterialType = m_material_type; + + if (m_enable_shaders) { + buf->getMaterial().EmissiveColor = c; + buf->getMaterial().setFlag(video::EMF_GOURAUD_SHADING, false); + buf->getMaterial().setFlag(video::EMF_NORMALIZE_NORMALS, true); + } + + // Add to mesh + mesh->addMeshBuffer(buf); + buf->drop(); + } + m_meshnode = m_smgr->addMeshSceneNode(mesh, m_matrixnode); + m_meshnode->grab(); + mesh->drop(); + } else if (m_prop.visual == "cube") { + grabMatrixNode(); + scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS)); + m_meshnode = m_smgr->addMeshSceneNode(mesh, m_matrixnode); + m_meshnode->grab(); + mesh->drop(); + + m_meshnode->setScale(m_prop.visual_size); + m_meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, + m_prop.backface_culling); + + setSceneNodeMaterial(m_meshnode); + } else if (m_prop.visual == "mesh") { + grabMatrixNode(); + scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh, true); + if (mesh) { + if (!checkMeshNormals(mesh)) { + infostream << "GenericCAO: recalculating normals for mesh " + << m_prop.mesh << std::endl; + m_smgr->getMeshManipulator()-> + recalculateNormals(mesh, true, false); + } + + m_animated_meshnode = m_smgr->addAnimatedMeshSceneNode(mesh, m_matrixnode); + m_animated_meshnode->grab(); + mesh->drop(); // The scene node took hold of it + m_animated_meshnode->animateJoints(); // Needed for some animations + m_animated_meshnode->setScale(m_prop.visual_size); + + // set vertex colors to ensure alpha is set + setMeshColor(m_animated_meshnode->getMesh(), video::SColor(0xFFFFFFFF)); + + setAnimatedMeshColor(m_animated_meshnode, video::SColor(0xFFFFFFFF)); + + setSceneNodeMaterial(m_animated_meshnode); + + m_animated_meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, + m_prop.backface_culling); + } else + errorstream<<"GenericCAO::addToScene(): Could not load mesh "<<m_prop.mesh<<std::endl; + } else if (m_prop.visual == "wielditem" || m_prop.visual == "item") { + grabMatrixNode(); + ItemStack item; + if (m_prop.wield_item.empty()) { + // Old format, only textures are specified. + infostream << "textures: " << m_prop.textures.size() << std::endl; + if (!m_prop.textures.empty()) { + infostream << "textures[0]: " << m_prop.textures[0] + << std::endl; + IItemDefManager *idef = m_client->idef(); + item = ItemStack(m_prop.textures[0], 1, 0, idef); + } + } else { + infostream << "serialized form: " << m_prop.wield_item << std::endl; + item.deSerialize(m_prop.wield_item, m_client->idef()); + } + m_wield_meshnode = new WieldMeshSceneNode(m_smgr, -1); + m_wield_meshnode->setItem(item, m_client, + (m_prop.visual == "wielditem")); + + m_wield_meshnode->setScale(m_prop.visual_size / 2.0f); + m_wield_meshnode->setColor(video::SColor(0xFFFFFFFF)); + } else { + infostream<<"GenericCAO::addToScene(): \""<<m_prop.visual + <<"\" not supported"<<std::endl; + } + + /* don't update while punch texture modifier is active */ + if (m_reset_textures_timer < 0) + updateTextures(m_current_texture_modifier); + + if (scene::ISceneNode *node = getSceneNode()) { + if (m_matrixnode) + node->setParent(m_matrixnode); + + if (auto shadow = RenderingEngine::get_shadow_renderer()) + shadow->addNodeToShadowList(node); + } + + updateNametag(); + updateMarker(); + updateNodePos(); + updateAnimation(); + updateBonePosition(); + updateAttachments(); + setNodeLight(m_last_light); + updateMeshCulling(); + + if (m_animated_meshnode) { + u32 mat_count = m_animated_meshnode->getMaterialCount(); + if (mat_count == 0 || m_prop.textures.empty()) { + // nothing + } else if (mat_count > m_prop.textures.size()) { + std::ostringstream oss; + oss << "GenericCAO::addToScene(): Model " + << m_prop.mesh << " loaded with " << mat_count + << " mesh buffers but only " << m_prop.textures.size() + << " texture(s) specifed, this is deprecated."; + logOnce(oss, warningstream); + + video::ITexture *last = m_animated_meshnode->getMaterial(0).TextureLayer[0].Texture; + for (u32 i = 1; i < mat_count; i++) { + auto &layer = m_animated_meshnode->getMaterial(i).TextureLayer[0]; + if (!layer.Texture) + layer.Texture = last; + last = layer.Texture; + } + } + } +} + +void GenericCAO::updateLight(u32 day_night_ratio) +{ + if (m_prop.glow < 0) + return; + + u16 light_at_pos = 0; + u8 light_at_pos_intensity = 0; + bool pos_ok = false; + + v3s16 pos[3]; + u16 npos = getLightPosition(pos); + for (u16 i = 0; i < npos; i++) { + bool this_ok; + MapNode n = m_env->getMap().getNode(pos[i], &this_ok); + if (this_ok) { + u16 this_light = getInteriorLight(n, 0, m_client->ndef()); + u8 this_light_intensity = MYMAX(this_light & 0xFF, this_light >> 8); + if (this_light_intensity > light_at_pos_intensity) { + light_at_pos = this_light; + light_at_pos_intensity = this_light_intensity; + } + pos_ok = true; + } + } + if (!pos_ok) + light_at_pos = LIGHT_SUN; + + video::SColor light = encode_light(light_at_pos, decode_light(m_prop.glow)); + if (!m_enable_shaders) + final_color_blend(&light, light_at_pos, day_night_ratio); + + if (light != m_last_light) { + m_last_light = light; + setNodeLight(light); + } +} + +void GenericCAO::setNodeLight(const video::SColor &light_color) +{ + if (m_prop.visual == "wielditem" || m_prop.visual == "item") { + if (m_wield_meshnode) + m_wield_meshnode->setNodeLightColor(light_color); + return; + } + + if (m_enable_shaders) { + if (m_prop.visual == "upright_sprite") { + if (!m_meshnode) + return; + for (u32 i = 0; i < m_meshnode->getMaterialCount(); ++i) + m_meshnode->getMaterial(i).EmissiveColor = light_color; + } else { + scene::ISceneNode *node = getSceneNode(); + if (!node) + return; + + for (u32 i = 0; i < node->getMaterialCount(); ++i) { + video::SMaterial &material = node->getMaterial(i); + material.EmissiveColor = light_color; + } + } + } else { + if (m_meshnode) { + setMeshColor(m_meshnode->getMesh(), light_color); + } else if (m_animated_meshnode) { + setAnimatedMeshColor(m_animated_meshnode, light_color); + } else if (m_spritenode) { + m_spritenode->setColor(light_color); + } + } +} + +u16 GenericCAO::getLightPosition(v3s16 *pos) +{ + const auto &box = m_prop.collisionbox; + pos[0] = floatToInt(m_position + box.MinEdge * BS, BS); + pos[1] = floatToInt(m_position + box.MaxEdge * BS, BS); + + // Skip center pos if it falls into the same node as Min or MaxEdge + if ((box.MaxEdge - box.MinEdge).getLengthSQ() < 3.0f) + return 2; + pos[2] = floatToInt(m_position + box.getCenter() * BS, BS); + return 3; +} + +void GenericCAO::updateMarker() +{ + if (!m_client->getMinimap()) + return; + + if (!m_prop.show_on_minimap) { + if (m_marker) + m_client->getMinimap()->removeMarker(&m_marker); + return; + } + + if (m_marker) + return; + + scene::ISceneNode *node = getSceneNode(); + if (!node) + return; + m_marker = m_client->getMinimap()->addMarker(node); +} + +void GenericCAO::updateNametag() +{ + if (m_is_local_player) // No nametag for local player + return; + + if (m_prop.nametag.empty() || m_prop.nametag_color.getAlpha() == 0) { + // Delete nametag + if (m_nametag) { + m_client->getCamera()->removeNametag(m_nametag); + m_nametag = nullptr; + } + return; + } + + scene::ISceneNode *node = getSceneNode(); + if (!node) + return; + + v3f pos; + pos.Y = m_prop.selectionbox.MaxEdge.Y + 0.3f; + if (!m_nametag) { + // Add nametag + m_nametag = m_client->getCamera()->addNametag(node, + m_prop.nametag, m_prop.nametag_color, + m_prop.nametag_bgcolor, pos); + } else { + // Update nametag + m_nametag->text = m_prop.nametag; + m_nametag->textcolor = m_prop.nametag_color; + m_nametag->bgcolor = m_prop.nametag_bgcolor; + m_nametag->pos = pos; + } +} + +void GenericCAO::updateNodePos() +{ + if (getParent() != NULL) + return; + + scene::ISceneNode *node = getSceneNode(); + + if (node) { + v3s16 camera_offset = m_env->getCameraOffset(); + v3f pos = pos_translator.val_current - + intToFloat(camera_offset, BS); + getPosRotMatrix().setTranslation(pos); + if (node != m_spritenode) { // rotate if not a sprite + v3f rot = m_is_local_player ? -m_rotation : -rot_translator.val_current; + setPitchYawRoll(getPosRotMatrix(), rot); + } + } +} + +void GenericCAO::step(float dtime, ClientEnvironment *env) +{ + // Handle model animations and update positions instantly to prevent lags + if (m_is_local_player) { + LocalPlayer *player = m_env->getLocalPlayer(); + m_position = player->getPosition(); + pos_translator.val_current = m_position; + m_rotation.Y = wrapDegrees_0_360(player->getYaw()); + rot_translator.val_current = m_rotation; + + if (m_is_visible) { + int old_anim = player->last_animation; + float old_anim_speed = player->last_animation_speed; + m_velocity = v3f(0,0,0); + m_acceleration = v3f(0,0,0); + const PlayerControl &controls = player->getPlayerControl(); + f32 new_speed = player->local_animation_speed; + + bool walking = false; + if (controls.movement_speed > 0.001f) { + new_speed *= controls.movement_speed; + walking = true; + } + + v2s32 new_anim = v2s32(0,0); + bool allow_update = false; + + // increase speed if using fast or flying fast + if((g_settings->getBool("fast_move") && + m_client->checkLocalPrivilege("fast")) && + (controls.aux1 || + (!player->touching_ground && + g_settings->getBool("free_move") && + m_client->checkLocalPrivilege("fly")))) + new_speed *= 1.5; + // slowdown speed if sneaking + if (controls.sneak && walking) + new_speed /= 2; + + if (walking && (controls.dig || controls.place)) { + new_anim = player->local_animations[3]; + player->last_animation = WD_ANIM; + } else if (walking) { + new_anim = player->local_animations[1]; + player->last_animation = WALK_ANIM; + } else if (controls.dig || controls.place) { + new_anim = player->local_animations[2]; + player->last_animation = DIG_ANIM; + } + + // Apply animations if input detected and not attached + // or set idle animation + if ((new_anim.X + new_anim.Y) > 0 && !getParent()) { + allow_update = true; + m_animation_range = new_anim; + m_animation_speed = new_speed; + player->last_animation_speed = m_animation_speed; + } else { + player->last_animation = NO_ANIM; + + if (old_anim != NO_ANIM) { + m_animation_range = player->local_animations[0]; + updateAnimation(); + } + } + + // Update local player animations + if ((player->last_animation != old_anim || + m_animation_speed != old_anim_speed) && + player->last_animation != NO_ANIM && allow_update) + updateAnimation(); + + } + } + + if (m_visuals_expired && m_smgr) { + m_visuals_expired = false; + + // Attachments, part 1: All attached objects must be unparented first, + // or Irrlicht causes a segmentation fault + for (u16 cao_id : m_attachment_child_ids) { + ClientActiveObject *obj = m_env->getActiveObject(cao_id); + if (obj) { + scene::ISceneNode *child_node = obj->getSceneNode(); + // The node's parent is always an IDummyTraformationSceneNode, + // so we need to reparent that one instead. + if (child_node) + child_node->getParent()->setParent(m_smgr->getRootSceneNode()); + } + } + + removeFromScene(false); + addToScene(m_client->tsrc(), m_smgr); + + // Attachments, part 2: Now that the parent has been refreshed, put its attachments back + for (u16 cao_id : m_attachment_child_ids) { + ClientActiveObject *obj = m_env->getActiveObject(cao_id); + if (obj) + obj->updateAttachments(); + } + } + + // Make sure m_is_visible is always applied + scene::ISceneNode *node = getSceneNode(); + if (node) + node->setVisible(m_is_visible); + + if(getParent() != NULL) // Attachments should be glued to their parent by Irrlicht + { + // Set these for later + m_position = getPosition(); + m_velocity = v3f(0,0,0); + m_acceleration = v3f(0,0,0); + pos_translator.val_current = m_position; + pos_translator.val_target = m_position; + } else { + rot_translator.translate(dtime); + v3f lastpos = pos_translator.val_current; + + if(m_prop.physical) + { + aabb3f box = m_prop.collisionbox; + box.MinEdge *= BS; + box.MaxEdge *= BS; + collisionMoveResult moveresult; + f32 pos_max_d = BS*0.125; // Distance per iteration + v3f p_pos = m_position; + v3f p_velocity = m_velocity; + moveresult = collisionMoveSimple(env,env->getGameDef(), + pos_max_d, box, m_prop.stepheight, dtime, + &p_pos, &p_velocity, m_acceleration, + this, m_prop.collideWithObjects); + // Apply results + m_position = p_pos; + m_velocity = p_velocity; + + bool is_end_position = moveresult.collides; + pos_translator.update(m_position, is_end_position, dtime); + } else { + m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration; + m_velocity += dtime * m_acceleration; + pos_translator.update(m_position, pos_translator.aim_is_end, + pos_translator.anim_time); + } + pos_translator.translate(dtime); + updateNodePos(); + + float moved = lastpos.getDistanceFrom(pos_translator.val_current); + m_step_distance_counter += moved; + if (m_step_distance_counter > 1.5f * BS) { + m_step_distance_counter = 0.0f; + if (!m_is_local_player && m_prop.makes_footstep_sound) { + const NodeDefManager *ndef = m_client->ndef(); + v3s16 p = floatToInt(getPosition() + + v3f(0.0f, (m_prop.collisionbox.MinEdge.Y - 0.5f) * BS, 0.0f), BS); + MapNode n = m_env->getMap().getNode(p); + SimpleSoundSpec spec = ndef->get(n).sound_footstep; + // Reduce footstep gain, as non-local-player footsteps are + // somehow louder. + spec.gain *= 0.6f; + m_client->sound()->playSoundAt(spec, getPosition()); + } + } + } + + m_anim_timer += dtime; + if(m_anim_timer >= m_anim_framelength) + { + m_anim_timer -= m_anim_framelength; + m_anim_frame++; + if(m_anim_frame >= m_anim_num_frames) + m_anim_frame = 0; + } + + updateTexturePos(); + + if(m_reset_textures_timer >= 0) + { + m_reset_textures_timer -= dtime; + if(m_reset_textures_timer <= 0) { + m_reset_textures_timer = -1; + updateTextures(m_previous_texture_modifier); + } + } + + if (node && fabs(m_prop.automatic_rotate) > 0.001f) { + // This is the child node's rotation. It is only used for automatic_rotate. + v3f local_rot = node->getRotation(); + local_rot.Y = modulo360f(local_rot.Y - dtime * core::RADTODEG * + m_prop.automatic_rotate); + node->setRotation(local_rot); + } + + if (!getParent() && m_prop.automatic_face_movement_dir && + (fabs(m_velocity.Z) > 0.001f || fabs(m_velocity.X) > 0.001f)) { + float target_yaw = atan2(m_velocity.Z, m_velocity.X) * 180 / M_PI + + m_prop.automatic_face_movement_dir_offset; + float max_rotation_per_sec = + m_prop.automatic_face_movement_max_rotation_per_sec; + + if (max_rotation_per_sec > 0) { + wrappedApproachShortest(m_rotation.Y, target_yaw, + dtime * max_rotation_per_sec, 360.f); + } else { + // Negative values of max_rotation_per_sec mean disabled. + m_rotation.Y = target_yaw; + } + + rot_translator.val_current = m_rotation; + updateNodePos(); + } + + if (m_animated_meshnode) { + // Everything must be updated; the whole transform + // chain as well as the animated mesh node. + // Otherwise, bone attachments would be relative to + // a position that's one frame old. + if (m_matrixnode) + updatePositionRecursive(m_matrixnode); + m_animated_meshnode->updateAbsolutePosition(); + m_animated_meshnode->animateJoints(); + updateBonePosition(); + } +} + +void GenericCAO::updateTexturePos() +{ + if(m_spritenode) + { + scene::ICameraSceneNode* camera = + m_spritenode->getSceneManager()->getActiveCamera(); + if(!camera) + return; + v3f cam_to_entity = m_spritenode->getAbsolutePosition() + - camera->getAbsolutePosition(); + cam_to_entity.normalize(); + + int row = m_tx_basepos.Y; + int col = m_tx_basepos.X; + + // Yawpitch goes rightwards + if (m_tx_select_horiz_by_yawpitch) { + if (cam_to_entity.Y > 0.75) + col += 5; + else if (cam_to_entity.Y < -0.75) + col += 4; + else { + float mob_dir = + atan2(cam_to_entity.Z, cam_to_entity.X) / M_PI * 180.; + float dir = mob_dir - m_rotation.Y; + dir = wrapDegrees_180(dir); + if (std::fabs(wrapDegrees_180(dir - 0)) <= 45.1f) + col += 2; + else if(std::fabs(wrapDegrees_180(dir - 90)) <= 45.1f) + col += 3; + else if(std::fabs(wrapDegrees_180(dir - 180)) <= 45.1f) + col += 0; + else if(std::fabs(wrapDegrees_180(dir + 90)) <= 45.1f) + col += 1; + else + col += 4; + } + } + + // Animation goes downwards + row += m_anim_frame; + + float txs = m_tx_size.X; + float tys = m_tx_size.Y; + setBillboardTextureMatrix(m_spritenode, txs, tys, col, row); + } + + else if (m_meshnode) { + if (m_prop.visual == "upright_sprite") { + int row = m_tx_basepos.Y; + int col = m_tx_basepos.X; + + // Animation goes downwards + row += m_anim_frame; + + const auto &tx = m_tx_size; + v2f t[4] = { // cf. vertices in GenericCAO::addToScene() + tx * v2f(col+1, row+1), + tx * v2f(col, row+1), + tx * v2f(col, row), + tx * v2f(col+1, row), + }; + auto mesh = m_meshnode->getMesh(); + setMeshBufferTextureCoords(mesh->getMeshBuffer(0), t, 4); + setMeshBufferTextureCoords(mesh->getMeshBuffer(1), t, 4); + } + } +} + +// Do not pass by reference, see header. +void GenericCAO::updateTextures(std::string mod) +{ + ITextureSource *tsrc = m_client->tsrc(); + + bool use_trilinear_filter = g_settings->getBool("trilinear_filter"); + bool use_bilinear_filter = g_settings->getBool("bilinear_filter"); + bool use_anisotropic_filter = g_settings->getBool("anisotropic_filter"); + + m_previous_texture_modifier = m_current_texture_modifier; + m_current_texture_modifier = mod; + + if (m_spritenode) { + if (m_prop.visual == "sprite") { + std::string texturestring = "no_texture.png"; + if (!m_prop.textures.empty()) + texturestring = m_prop.textures[0]; + texturestring += mod; + m_spritenode->getMaterial(0).MaterialType = m_material_type; + m_spritenode->getMaterial(0).MaterialTypeParam = 0.5f; + m_spritenode->setMaterialTexture(0, + tsrc->getTextureForMesh(texturestring)); + + // This allows setting per-material colors. However, until a real lighting + // system is added, the code below will have no effect. Once MineTest + // has directional lighting, it should work automatically. + if (!m_prop.colors.empty()) { + m_spritenode->getMaterial(0).AmbientColor = m_prop.colors[0]; + m_spritenode->getMaterial(0).DiffuseColor = m_prop.colors[0]; + m_spritenode->getMaterial(0).SpecularColor = m_prop.colors[0]; + } + + m_spritenode->getMaterial(0).setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter); + m_spritenode->getMaterial(0).setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter); + m_spritenode->getMaterial(0).setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter); + } + } + + else if (m_animated_meshnode) { + if (m_prop.visual == "mesh") { + for (u32 i = 0; i < m_prop.textures.size() && + i < m_animated_meshnode->getMaterialCount(); ++i) { + std::string texturestring = m_prop.textures[i]; + if (texturestring.empty()) + continue; // Empty texture string means don't modify that material + texturestring += mod; + video::ITexture* texture = tsrc->getTextureForMesh(texturestring); + if (!texture) { + errorstream<<"GenericCAO::updateTextures(): Could not load texture "<<texturestring<<std::endl; + continue; + } + + // Set material flags and texture + video::SMaterial& material = m_animated_meshnode->getMaterial(i); + material.MaterialType = m_material_type; + material.MaterialTypeParam = 0.5f; + material.TextureLayer[0].Texture = texture; + material.setFlag(video::EMF_LIGHTING, true); + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setFlag(video::EMF_BACK_FACE_CULLING, m_prop.backface_culling); + + // don't filter low-res textures, makes them look blurry + // player models have a res of 64 + const core::dimension2d<u32> &size = texture->getOriginalSize(); + const u32 res = std::min(size.Height, size.Width); + use_trilinear_filter &= res > 64; + use_bilinear_filter &= res > 64; + + m_animated_meshnode->getMaterial(i) + .setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter); + m_animated_meshnode->getMaterial(i) + .setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter); + m_animated_meshnode->getMaterial(i) + .setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter); + } + for (u32 i = 0; i < m_prop.colors.size() && + i < m_animated_meshnode->getMaterialCount(); ++i) + { + // This allows setting per-material colors. However, until a real lighting + // system is added, the code below will have no effect. Once MineTest + // has directional lighting, it should work automatically. + m_animated_meshnode->getMaterial(i).AmbientColor = m_prop.colors[i]; + m_animated_meshnode->getMaterial(i).DiffuseColor = m_prop.colors[i]; + m_animated_meshnode->getMaterial(i).SpecularColor = m_prop.colors[i]; + } + } + } + + else if (m_meshnode) { + if(m_prop.visual == "cube") + { + for (u32 i = 0; i < 6; ++i) + { + std::string texturestring = "no_texture.png"; + if(m_prop.textures.size() > i) + texturestring = m_prop.textures[i]; + texturestring += mod; + + + // Set material flags and texture + video::SMaterial& material = m_meshnode->getMaterial(i); + material.MaterialType = m_material_type; + material.MaterialTypeParam = 0.5f; + material.setFlag(video::EMF_LIGHTING, false); + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setTexture(0, + tsrc->getTextureForMesh(texturestring)); + material.getTextureMatrix(0).makeIdentity(); + + // This allows setting per-material colors. However, until a real lighting + // system is added, the code below will have no effect. Once MineTest + // has directional lighting, it should work automatically. + if(m_prop.colors.size() > i) + { + m_meshnode->getMaterial(i).AmbientColor = m_prop.colors[i]; + m_meshnode->getMaterial(i).DiffuseColor = m_prop.colors[i]; + m_meshnode->getMaterial(i).SpecularColor = m_prop.colors[i]; + } + + m_meshnode->getMaterial(i).setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter); + m_meshnode->getMaterial(i).setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter); + m_meshnode->getMaterial(i).setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter); + } + } else if (m_prop.visual == "upright_sprite") { + scene::IMesh *mesh = m_meshnode->getMesh(); + { + std::string tname = "no_texture.png"; + if (!m_prop.textures.empty()) + tname = m_prop.textures[0]; + tname += mod; + auto& material = m_meshnode->getMaterial(0); + material.setTexture(0, + tsrc->getTextureForMesh(tname)); + + // This allows setting per-material colors. However, until a real lighting + // system is added, the code below will have no effect. Once MineTest + // has directional lighting, it should work automatically. + if(!m_prop.colors.empty()) { + material.AmbientColor = m_prop.colors[0]; + material.DiffuseColor = m_prop.colors[0]; + material.SpecularColor = m_prop.colors[0]; + } + + material.setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter); + material.setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter); + material.setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter); + } + { + std::string tname = "no_texture.png"; + if (m_prop.textures.size() >= 2) + tname = m_prop.textures[1]; + else if (!m_prop.textures.empty()) + tname = m_prop.textures[0]; + tname += mod; + auto& material = m_meshnode->getMaterial(1); + material.setTexture(0, + tsrc->getTextureForMesh(tname)); + + // This allows setting per-material colors. However, until a real lighting + // system is added, the code below will have no effect. Once MineTest + // has directional lighting, it should work automatically. + if (m_prop.colors.size() >= 2) { + material.AmbientColor = m_prop.colors[1]; + material.DiffuseColor = m_prop.colors[1]; + material.SpecularColor = m_prop.colors[1]; + } else if (!m_prop.colors.empty()) { + material.AmbientColor = m_prop.colors[0]; + material.DiffuseColor = m_prop.colors[0]; + material.SpecularColor = m_prop.colors[0]; + } + + material.setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter); + material.setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter); + material.setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter); + } + // Set mesh color (only if lighting is disabled) + if (!m_prop.colors.empty() && m_prop.glow < 0) + setMeshColor(mesh, m_prop.colors[0]); + } + } + // Prevent showing the player after changing texture + if (m_is_local_player) + updateMeshCulling(); +} + +void GenericCAO::updateAnimation() +{ + if (!m_animated_meshnode) + return; + + if (m_animated_meshnode->getStartFrame() != m_animation_range.X || + m_animated_meshnode->getEndFrame() != m_animation_range.Y) + m_animated_meshnode->setFrameLoop(m_animation_range.X, m_animation_range.Y); + if (m_animated_meshnode->getAnimationSpeed() != m_animation_speed) + m_animated_meshnode->setAnimationSpeed(m_animation_speed); + m_animated_meshnode->setTransitionTime(m_animation_blend); + if (m_animated_meshnode->getLoopMode() != m_animation_loop) + m_animated_meshnode->setLoopMode(m_animation_loop); +} + +void GenericCAO::updateAnimationSpeed() +{ + if (!m_animated_meshnode) + return; + + m_animated_meshnode->setAnimationSpeed(m_animation_speed); +} + +void GenericCAO::updateBonePosition() +{ + if (m_bone_position.empty() || !m_animated_meshnode) + return; + + m_animated_meshnode->setJointMode(scene::EJUOR_CONTROL); // To write positions to the mesh on render + for (auto &it : m_bone_position) { + std::string bone_name = it.first; + scene::IBoneSceneNode* bone = m_animated_meshnode->getJointNode(bone_name.c_str()); + if (bone) { + bone->setPosition(it.second.X); + bone->setRotation(it.second.Y); + } + } + + // search through bones to find mistakenly rotated bones due to bug in Irrlicht + for (u32 i = 0; i < m_animated_meshnode->getJointCount(); ++i) { + scene::IBoneSceneNode *bone = m_animated_meshnode->getJointNode(i); + if (!bone) + continue; + + //If bone is manually positioned there is no need to perform the bug check + bool skip = false; + for (auto &it : m_bone_position) { + if (it.first == bone->getName()) { + skip = true; + break; + } + } + if (skip) + continue; + + // Workaround for Irrlicht bug + // We check each bone to see if it has been rotated ~180deg from its expected position due to a bug in Irricht + // when using EJUOR_CONTROL joint control. If the bug is detected we update the bone to the proper position + // and update the bones transformation. + v3f bone_rot = bone->getRelativeTransformation().getRotationDegrees(); + float offset = fabsf(bone_rot.X - bone->getRotation().X); + if (offset > 179.9f && offset < 180.1f) { + bone->setRotation(bone_rot); + bone->updateAbsolutePosition(); + } + } + // The following is needed for set_bone_pos to propagate to + // attached objects correctly. + // Irrlicht ought to do this, but doesn't when using EJUOR_CONTROL. + for (u32 i = 0; i < m_animated_meshnode->getJointCount(); ++i) { + auto bone = m_animated_meshnode->getJointNode(i); + // Look for the root bone. + if (bone && bone->getParent() == m_animated_meshnode) { + // Update entire skeleton. + bone->updateAbsolutePositionOfAllChildren(); + break; + } + } +} + +void GenericCAO::updateAttachments() +{ + ClientActiveObject *parent = getParent(); + + m_attached_to_local = parent && parent->isLocalPlayer(); + + /* + Following cases exist: + m_attachment_parent_id == 0 && !parent + This object is not attached + m_attachment_parent_id != 0 && parent + This object is attached + m_attachment_parent_id != 0 && !parent + This object will be attached as soon the parent is known + m_attachment_parent_id == 0 && parent + Impossible case + */ + + if (!parent) { // Detach or don't attach + if (m_matrixnode) { + v3s16 camera_offset = m_env->getCameraOffset(); + v3f old_pos = getPosition(); + + m_matrixnode->setParent(m_smgr->getRootSceneNode()); + getPosRotMatrix().setTranslation(old_pos - intToFloat(camera_offset, BS)); + m_matrixnode->updateAbsolutePosition(); + } + } + else // Attach + { + parent->updateAttachments(); + scene::ISceneNode *parent_node = parent->getSceneNode(); + scene::IAnimatedMeshSceneNode *parent_animated_mesh_node = + parent->getAnimatedMeshSceneNode(); + if (parent_animated_mesh_node && !m_attachment_bone.empty()) { + parent_node = parent_animated_mesh_node->getJointNode(m_attachment_bone.c_str()); + } + + if (m_matrixnode && parent_node) { + m_matrixnode->setParent(parent_node); + parent_node->updateAbsolutePosition(); + getPosRotMatrix().setTranslation(m_attachment_position); + //setPitchYawRoll(getPosRotMatrix(), m_attachment_rotation); + // use Irrlicht eulers instead + getPosRotMatrix().setRotationDegrees(m_attachment_rotation); + m_matrixnode->updateAbsolutePosition(); + } + } +} + +bool GenericCAO::visualExpiryRequired(const ObjectProperties &new_) const +{ + const ObjectProperties &old = m_prop; + /* Visuals do not need to be expired for: + * - nametag props: handled by updateNametag() + * - textures: handled by updateTextures() + * - sprite props: handled by updateTexturePos() + * - glow: handled by updateLight() + * - any other properties that do not change appearance + */ + + bool uses_legacy_texture = new_.wield_item.empty() && + (new_.visual == "wielditem" || new_.visual == "item"); + // Ordered to compare primitive types before std::vectors + return old.backface_culling != new_.backface_culling || + old.is_visible != new_.is_visible || + old.mesh != new_.mesh || + old.shaded != new_.shaded || + old.use_texture_alpha != new_.use_texture_alpha || + old.visual != new_.visual || + old.visual_size != new_.visual_size || + old.wield_item != new_.wield_item || + old.colors != new_.colors || + (uses_legacy_texture && old.textures != new_.textures); +} + +void GenericCAO::processMessage(const std::string &data) +{ + //infostream<<"GenericCAO: Got message"<<std::endl; + std::istringstream is(data, std::ios::binary); + // command + u8 cmd = readU8(is); + if (cmd == AO_CMD_SET_PROPERTIES) { + ObjectProperties newprops; + newprops.show_on_minimap = m_is_player; // default + + newprops.deSerialize(is); + + // Check what exactly changed + bool expire_visuals = visualExpiryRequired(newprops); + bool textures_changed = m_prop.textures != newprops.textures; + + // Apply changes + m_prop = std::move(newprops); + + m_selection_box = m_prop.selectionbox; + m_selection_box.MinEdge *= BS; + m_selection_box.MaxEdge *= BS; + + m_tx_size.X = 1.0f / m_prop.spritediv.X; + m_tx_size.Y = 1.0f / m_prop.spritediv.Y; + + if(!m_initial_tx_basepos_set){ + m_initial_tx_basepos_set = true; + m_tx_basepos = m_prop.initial_sprite_basepos; + } + if (m_is_local_player) { + LocalPlayer *player = m_env->getLocalPlayer(); + player->makes_footstep_sound = m_prop.makes_footstep_sound; + aabb3f collision_box = m_prop.collisionbox; + collision_box.MinEdge *= BS; + collision_box.MaxEdge *= BS; + player->setCollisionbox(collision_box); + player->setEyeHeight(m_prop.eye_height); + player->setZoomFOV(m_prop.zoom_fov); + } + + if ((m_is_player && !m_is_local_player) && m_prop.nametag.empty()) + m_prop.nametag = m_name; + if (m_is_local_player) + m_prop.show_on_minimap = false; + + if (expire_visuals) { + expireVisuals(); + } else { + infostream << "GenericCAO: properties updated but expiring visuals" + << " not necessary" << std::endl; + if (textures_changed) { + // don't update while punch texture modifier is active + if (m_reset_textures_timer < 0) + updateTextures(m_current_texture_modifier); + } + updateNametag(); + updateMarker(); + } + } else if (cmd == AO_CMD_UPDATE_POSITION) { + // Not sent by the server if this object is an attachment. + // We might however get here if the server notices the object being detached before the client. + m_position = readV3F32(is); + m_velocity = readV3F32(is); + m_acceleration = readV3F32(is); + m_rotation = readV3F32(is); + + m_rotation = wrapDegrees_0_360_v3f(m_rotation); + bool do_interpolate = readU8(is); + bool is_end_position = readU8(is); + float update_interval = readF32(is); + + // Place us a bit higher if we're physical, to not sink into + // the ground due to sucky collision detection... + if(m_prop.physical) + m_position += v3f(0,0.002,0); + + if(getParent() != NULL) // Just in case + return; + + if(do_interpolate) + { + if(!m_prop.physical) + pos_translator.update(m_position, is_end_position, update_interval); + } else { + pos_translator.init(m_position); + } + rot_translator.update(m_rotation, false, update_interval); + updateNodePos(); + } else if (cmd == AO_CMD_SET_TEXTURE_MOD) { + std::string mod = deSerializeString16(is); + + // immediately reset a engine issued texture modifier if a mod sends a different one + if (m_reset_textures_timer > 0) { + m_reset_textures_timer = -1; + updateTextures(m_previous_texture_modifier); + } + updateTextures(mod); + } else if (cmd == AO_CMD_SET_SPRITE) { + v2s16 p = readV2S16(is); + int num_frames = readU16(is); + float framelength = readF32(is); + bool select_horiz_by_yawpitch = readU8(is); + + m_tx_basepos = p; + m_anim_num_frames = num_frames; + m_anim_frame = 0; + m_anim_framelength = framelength; + m_tx_select_horiz_by_yawpitch = select_horiz_by_yawpitch; + + updateTexturePos(); + } else if (cmd == AO_CMD_SET_PHYSICS_OVERRIDE) { + float override_speed = readF32(is); + float override_jump = readF32(is); + float override_gravity = readF32(is); + // these are sent inverted so we get true when the server sends nothing + bool sneak = !readU8(is); + bool sneak_glitch = !readU8(is); + bool new_move = !readU8(is); + + + if(m_is_local_player) + { + LocalPlayer *player = m_env->getLocalPlayer(); + player->physics_override_speed = override_speed; + player->physics_override_jump = override_jump; + player->physics_override_gravity = override_gravity; + player->physics_override_sneak = sneak; + player->physics_override_sneak_glitch = sneak_glitch; + player->physics_override_new_move = new_move; + } + } else if (cmd == AO_CMD_SET_ANIMATION) { + // TODO: change frames send as v2s32 value + v2f range = readV2F32(is); + if (!m_is_local_player) { + m_animation_range = v2s32((s32)range.X, (s32)range.Y); + m_animation_speed = readF32(is); + m_animation_blend = readF32(is); + // these are sent inverted so we get true when the server sends nothing + m_animation_loop = !readU8(is); + updateAnimation(); + } else { + LocalPlayer *player = m_env->getLocalPlayer(); + if(player->last_animation == NO_ANIM) + { + m_animation_range = v2s32((s32)range.X, (s32)range.Y); + m_animation_speed = readF32(is); + m_animation_blend = readF32(is); + // these are sent inverted so we get true when the server sends nothing + m_animation_loop = !readU8(is); + } + // update animation only if local animations present + // and received animation is unknown (except idle animation) + bool is_known = false; + for (int i = 1;i<4;i++) + { + if(m_animation_range.Y == player->local_animations[i].Y) + is_known = true; + } + if(!is_known || + (player->local_animations[1].Y + player->local_animations[2].Y < 1)) + { + updateAnimation(); + } + // FIXME: ^ This code is trash. It's also broken. + } + } else if (cmd == AO_CMD_SET_ANIMATION_SPEED) { + m_animation_speed = readF32(is); + updateAnimationSpeed(); + } else if (cmd == AO_CMD_SET_BONE_POSITION) { + std::string bone = deSerializeString16(is); + v3f position = readV3F32(is); + v3f rotation = readV3F32(is); + m_bone_position[bone] = core::vector2d<v3f>(position, rotation); + + // updateBonePosition(); now called every step + } else if (cmd == AO_CMD_ATTACH_TO) { + u16 parent_id = readS16(is); + std::string bone = deSerializeString16(is); + v3f position = readV3F32(is); + v3f rotation = readV3F32(is); + bool force_visible = readU8(is); // Returns false for EOF + + setAttachment(parent_id, bone, position, rotation, force_visible); + } else if (cmd == AO_CMD_PUNCHED) { + u16 result_hp = readU16(is); + + // Use this instead of the send damage to not interfere with prediction + s32 damage = (s32)m_hp - (s32)result_hp; + + m_hp = result_hp; + + if (m_is_local_player) + m_env->getLocalPlayer()->hp = m_hp; + + if (damage > 0) + { + if (m_hp == 0) + { + // TODO: Execute defined fast response + // As there is no definition, make a smoke puff + ClientSimpleObject *simple = createSmokePuff( + m_smgr, m_env, m_position, + v2f(m_prop.visual_size.X, m_prop.visual_size.Y) * BS); + m_env->addSimpleObject(simple); + } else if (m_reset_textures_timer < 0 && !m_prop.damage_texture_modifier.empty()) { + m_reset_textures_timer = 0.05; + if(damage >= 2) + m_reset_textures_timer += 0.05 * damage; + // Cap damage overlay to 1 second + m_reset_textures_timer = std::min(m_reset_textures_timer, 1.0f); + updateTextures(m_current_texture_modifier + m_prop.damage_texture_modifier); + } + } + + if (m_hp == 0) { + // Same as 'Server::DiePlayer' + clearParentAttachment(); + // Same as 'ObjectRef::l_remove' + if (!m_is_player) + clearChildAttachments(); + } + } else if (cmd == AO_CMD_UPDATE_ARMOR_GROUPS) { + m_armor_groups.clear(); + int armor_groups_size = readU16(is); + for(int i=0; i<armor_groups_size; i++) + { + std::string name = deSerializeString16(is); + int rating = readS16(is); + m_armor_groups[name] = rating; + } + } else if (cmd == AO_CMD_SPAWN_INFANT) { + u16 child_id = readU16(is); + u8 type = readU8(is); // maybe this will be useful later + (void)type; + + addAttachmentChild(child_id); + } else if (cmd == AO_CMD_OBSOLETE1) { + // Don't do anything and also don't log a warning + } else { + warningstream << FUNCTION_NAME + << ": unknown command or outdated client \"" + << +cmd << "\"" << std::endl; + } +} + +/* \pre punchitem != NULL + */ +bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem, + float time_from_last_punch) +{ + assert(punchitem); // pre-condition + const ToolCapabilities *toolcap = + &punchitem->getToolCapabilities(m_client->idef()); + PunchDamageResult result = getPunchDamage( + m_armor_groups, + toolcap, + punchitem, + time_from_last_punch, + punchitem->wear); + + if(result.did_punch && result.damage != 0) + { + if(result.damage < m_hp) + { + m_hp -= result.damage; + } else { + m_hp = 0; + // TODO: Execute defined fast response + // As there is no definition, make a smoke puff + ClientSimpleObject *simple = createSmokePuff( + m_smgr, m_env, m_position, + v2f(m_prop.visual_size.X, m_prop.visual_size.Y) * BS); + m_env->addSimpleObject(simple); + } + if (m_reset_textures_timer < 0 && !m_prop.damage_texture_modifier.empty()) { + m_reset_textures_timer = 0.05; + if (result.damage >= 2) + m_reset_textures_timer += 0.05 * result.damage; + // Cap damage overlay to 1 second + m_reset_textures_timer = std::min(m_reset_textures_timer, 1.0f); + updateTextures(m_current_texture_modifier + m_prop.damage_texture_modifier); + } + } + + return false; +} + +std::string GenericCAO::debugInfoText() +{ + std::ostringstream os(std::ios::binary); + os<<"GenericCAO hp="<<m_hp<<"\n"; + os<<"armor={"; + for(ItemGroupList::const_iterator i = m_armor_groups.begin(); + i != m_armor_groups.end(); ++i) + { + os<<i->first<<"="<<i->second<<", "; + } + os<<"}"; + return os.str(); +} + +void GenericCAO::updateMeshCulling() +{ + if (!m_is_local_player) + return; + + const bool hidden = m_client->getCamera()->getCameraMode() == CAMERA_MODE_FIRST; + + scene::ISceneNode *node = getSceneNode(); + + if (!node) + return; + + if (m_prop.visual == "upright_sprite") { + // upright sprite has no backface culling + node->setMaterialFlag(video::EMF_FRONT_FACE_CULLING, hidden); + return; + } + + if (hidden) { + // Hide the mesh by culling both front and + // back faces. Serious hackyness but it works for our + // purposes. This also preserves the skeletal armature. + node->setMaterialFlag(video::EMF_BACK_FACE_CULLING, + true); + node->setMaterialFlag(video::EMF_FRONT_FACE_CULLING, + true); + } else { + // Restore mesh visibility. + node->setMaterialFlag(video::EMF_BACK_FACE_CULLING, + m_prop.backface_culling); + node->setMaterialFlag(video::EMF_FRONT_FACE_CULLING, + false); + } +} + +// Prototype +GenericCAO proto_GenericCAO(NULL, NULL); diff --git a/src/client/content_cao.h b/src/client/content_cao.h new file mode 100644 index 0000000..5a8116c --- /dev/null +++ b/src/client/content_cao.h @@ -0,0 +1,282 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <map> +#include "irrlichttypes_extrabloated.h" +#include "clientobject.h" +#include "object_properties.h" +#include "itemgroup.h" +#include "constants.h" +#include <cassert> + +class Camera; +class Client; +struct Nametag; +struct MinimapMarker; + +/* + SmoothTranslator +*/ + +template<typename T> +struct SmoothTranslator +{ + T val_old; + T val_current; + T val_target; + f32 anim_time = 0; + f32 anim_time_counter = 0; + bool aim_is_end = true; + + SmoothTranslator() = default; + + void init(T current); + + void update(T new_target, bool is_end_position = false, + float update_interval = -1); + + void translate(f32 dtime); +}; + +struct SmoothTranslatorWrapped : SmoothTranslator<f32> +{ + void translate(f32 dtime); +}; + +struct SmoothTranslatorWrappedv3f : SmoothTranslator<v3f> +{ + void translate(f32 dtime); +}; + +class GenericCAO : public ClientActiveObject +{ +private: + // Only set at initialization + std::string m_name = ""; + bool m_is_player = false; + bool m_is_local_player = false; + // Property-ish things + ObjectProperties m_prop; + // + scene::ISceneManager *m_smgr = nullptr; + Client *m_client = nullptr; + aabb3f m_selection_box = aabb3f(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.); + scene::IMeshSceneNode *m_meshnode = nullptr; + scene::IAnimatedMeshSceneNode *m_animated_meshnode = nullptr; + WieldMeshSceneNode *m_wield_meshnode = nullptr; + scene::IBillboardSceneNode *m_spritenode = nullptr; + scene::IDummyTransformationSceneNode *m_matrixnode = nullptr; + Nametag *m_nametag = nullptr; + MinimapMarker *m_marker = nullptr; + v3f m_position = v3f(0.0f, 10.0f * BS, 0); + v3f m_velocity; + v3f m_acceleration; + v3f m_rotation; + u16 m_hp = 1; + SmoothTranslator<v3f> pos_translator; + SmoothTranslatorWrappedv3f rot_translator; + // Spritesheet/animation stuff + v2f m_tx_size = v2f(1,1); + v2s16 m_tx_basepos; + bool m_initial_tx_basepos_set = false; + bool m_tx_select_horiz_by_yawpitch = false; + v2s32 m_animation_range; + float m_animation_speed = 15.0f; + float m_animation_blend = 0.0f; + bool m_animation_loop = true; + // stores position and rotation for each bone name + std::unordered_map<std::string, core::vector2d<v3f>> m_bone_position; + + int m_attachment_parent_id = 0; + std::unordered_set<int> m_attachment_child_ids; + std::string m_attachment_bone = ""; + v3f m_attachment_position; + v3f m_attachment_rotation; + bool m_attached_to_local = false; + bool m_force_visible = false; + + int m_anim_frame = 0; + int m_anim_num_frames = 1; + float m_anim_framelength = 0.2f; + float m_anim_timer = 0.0f; + ItemGroupList m_armor_groups; + float m_reset_textures_timer = -1.0f; + // stores texture modifier before punch update + std::string m_previous_texture_modifier = ""; + // last applied texture modifier + std::string m_current_texture_modifier = ""; + bool m_visuals_expired = false; + float m_step_distance_counter = 0.0f; + video::SColor m_last_light = video::SColor(0xFFFFFFFF); + bool m_is_visible = false; + // Material + video::E_MATERIAL_TYPE m_material_type; + // Settings + bool m_enable_shaders = false; + + bool visualExpiryRequired(const ObjectProperties &newprops) const; + +public: + GenericCAO(Client *client, ClientEnvironment *env); + + ~GenericCAO(); + + static ClientActiveObject* create(Client *client, ClientEnvironment *env) + { + return new GenericCAO(client, env); + } + + inline ActiveObjectType getType() const + { + return ACTIVEOBJECT_TYPE_GENERIC; + } + inline const ItemGroupList &getGroups() const + { + return m_armor_groups; + } + void initialize(const std::string &data); + + void processInitData(const std::string &data); + + bool getCollisionBox(aabb3f *toset) const; + + bool collideWithObjects() const; + + virtual bool getSelectionBox(aabb3f *toset) const; + + const v3f getPosition() const; + + inline const v3f &getRotation() const { return m_rotation; } + + bool isImmortal() const; + + inline const ObjectProperties &getProperties() const { return m_prop; } + + scene::ISceneNode *getSceneNode() const; + + scene::IAnimatedMeshSceneNode *getAnimatedMeshSceneNode() const; + + // m_matrixnode controls the position and rotation of the child node + // for all scene nodes, as a workaround for an Irrlicht problem with + // rotations. The child node's position can't be used because it's + // rotated, and must remain as 0. + // Note that m_matrixnode.setPosition() shouldn't be called. Use + // m_matrixnode->getRelativeTransformationMatrix().setTranslation() + // instead (aka getPosRotMatrix().setTranslation()). + inline core::matrix4 &getPosRotMatrix() + { + assert(m_matrixnode); + return m_matrixnode->getRelativeTransformationMatrix(); + } + + inline const core::matrix4 *getAbsolutePosRotMatrix() const + { + if (!m_matrixnode) + return nullptr; + return &m_matrixnode->getAbsoluteTransformation(); + } + + inline f32 getStepHeight() const + { + return m_prop.stepheight; + } + + inline bool isLocalPlayer() const + { + return m_is_local_player; + } + + inline bool isVisible() const + { + return m_is_visible; + } + + inline void setVisible(bool toset) + { + m_is_visible = toset; + } + + void setChildrenVisible(bool toset); + void setAttachment(int parent_id, const std::string &bone, v3f position, + v3f rotation, bool force_visible); + void getAttachment(int *parent_id, std::string *bone, v3f *position, + v3f *rotation, bool *force_visible) const; + void clearChildAttachments(); + void clearParentAttachment(); + void addAttachmentChild(int child_id); + void removeAttachmentChild(int child_id); + ClientActiveObject *getParent() const; + const std::unordered_set<int> &getAttachmentChildIds() const + { return m_attachment_child_ids; } + void updateAttachments(); + + void removeFromScene(bool permanent); + + void addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr); + + inline void expireVisuals() + { + m_visuals_expired = true; + } + + void updateLight(u32 day_night_ratio); + + void setNodeLight(const video::SColor &light); + + /* Get light position(s). + * returns number of positions written into pos[], which must have space + * for at least 3 vectors. */ + u16 getLightPosition(v3s16 *pos); + + void updateNametag(); + + void updateMarker(); + + void updateNodePos(); + + void step(float dtime, ClientEnvironment *env); + + void updateTexturePos(); + + // ffs this HAS TO BE a string copy! See #5739 if you think otherwise + // Reason: updateTextures(m_previous_texture_modifier); + void updateTextures(std::string mod); + + void updateAnimation(); + + void updateAnimationSpeed(); + + void updateBonePosition(); + + void processMessage(const std::string &data); + + bool directReportPunch(v3f dir, const ItemStack *punchitem=NULL, + float time_from_last_punch=1000000); + + std::string debugInfoText(); + + std::string infoText() + { + return m_prop.infotext; + } + + void updateMeshCulling(); +}; diff --git a/src/client/content_cso.cpp b/src/client/content_cso.cpp new file mode 100644 index 0000000..f9641af --- /dev/null +++ b/src/client/content_cso.cpp @@ -0,0 +1,77 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "content_cso.h" +#include <IBillboardSceneNode.h> +#include "client/tile.h" +#include "clientenvironment.h" +#include "client.h" +#include "map.h" + +class SmokePuffCSO: public ClientSimpleObject +{ + float m_age = 0.0f; + scene::IBillboardSceneNode *m_spritenode = nullptr; +public: + SmokePuffCSO(scene::ISceneManager *smgr, + ClientEnvironment *env, const v3f &pos, const v2f &size) + { + infostream<<"SmokePuffCSO: constructing"<<std::endl; + m_spritenode = smgr->addBillboardSceneNode( + NULL, v2f(1,1), pos, -1); + m_spritenode->setMaterialTexture(0, + env->getGameDef()->tsrc()->getTextureForMesh("smoke_puff.png")); + m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false); + m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); + //m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); + m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL); + m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true); + m_spritenode->setColor(video::SColor(255,0,0,0)); + m_spritenode->setVisible(true); + m_spritenode->setSize(size); + /* Update brightness */ + u8 light; + bool pos_ok; + MapNode n = env->getMap().getNode(floatToInt(pos, BS), &pos_ok); + light = pos_ok ? decode_light(n.getLightBlend(env->getDayNightRatio(), + env->getGameDef()->ndef())) + : 64; + video::SColor color(255,light,light,light); + m_spritenode->setColor(color); + } + virtual ~SmokePuffCSO() + { + infostream<<"SmokePuffCSO: destructing"<<std::endl; + m_spritenode->remove(); + } + void step(float dtime) + { + m_age += dtime; + if(m_age > 1.0){ + m_to_be_removed = true; + } + } +}; + +ClientSimpleObject* createSmokePuff(scene::ISceneManager *smgr, + ClientEnvironment *env, v3f pos, v2f size) +{ + return new SmokePuffCSO(smgr, env, pos, size); +} + diff --git a/src/client/content_cso.h b/src/client/content_cso.h new file mode 100644 index 0000000..cc92131 --- /dev/null +++ b/src/client/content_cso.h @@ -0,0 +1,26 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "clientsimpleobject.h" + +ClientSimpleObject* createSmokePuff(scene::ISceneManager *smgr, + ClientEnvironment *env, v3f pos, v2f size); diff --git a/src/client/content_mapblock.cpp b/src/client/content_mapblock.cpp new file mode 100644 index 0000000..0bac5e8 --- /dev/null +++ b/src/client/content_mapblock.cpp @@ -0,0 +1,1635 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <cmath> +#include "content_mapblock.h" +#include "util/numeric.h" +#include "util/directiontables.h" +#include "mapblock_mesh.h" +#include "settings.h" +#include "nodedef.h" +#include "client/tile.h" +#include "mesh.h" +#include <IMeshManipulator.h> +#include "client/meshgen/collector.h" +#include "client/renderingengine.h" +#include "client.h" +#include "noise.h" + +// Distance of light extrapolation (for oversized nodes) +// After this distance, it gives up and considers light level constant +#define SMOOTH_LIGHTING_OVERSIZE 1.0 + +// Node edge count (for glasslike-framed) +#define FRAMED_EDGE_COUNT 12 + +// Node neighbor count, including edge-connected, but not vertex-connected +// (for glasslike-framed) +// Corresponding offsets are listed in g_27dirs +#define FRAMED_NEIGHBOR_COUNT 18 + +static const v3s16 light_dirs[8] = { + v3s16(-1, -1, -1), + v3s16(-1, -1, 1), + v3s16(-1, 1, -1), + v3s16(-1, 1, 1), + v3s16( 1, -1, -1), + v3s16( 1, -1, 1), + v3s16( 1, 1, -1), + v3s16( 1, 1, 1), +}; + +// Standard index set to make a quad on 4 vertices +static constexpr u16 quad_indices[] = {0, 1, 2, 2, 3, 0}; + +const std::string MapblockMeshGenerator::raillike_groupname = "connect_to_raillike"; + +MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output, + scene::IMeshManipulator *mm): + data(input), + collector(output), + nodedef(data->m_client->ndef()), + meshmanip(mm), + blockpos_nodes(data->m_blockpos * MAP_BLOCKSIZE) +{ + enable_mesh_cache = g_settings->getBool("enable_mesh_cache") && + !data->m_smooth_lighting; // Mesh cache is not supported with smooth lighting +} + +void MapblockMeshGenerator::useTile(int index, u8 set_flags, u8 reset_flags, bool special) +{ + if (special) + getSpecialTile(index, &tile, p == data->m_crack_pos_relative); + else + getTile(index, &tile); + if (!data->m_smooth_lighting) + color = encode_light(light, f->light_source); + + for (auto &layer : tile.layers) { + layer.material_flags |= set_flags; + layer.material_flags &= ~reset_flags; + } +} + +// Returns a tile, ready for use, non-rotated. +void MapblockMeshGenerator::getTile(int index, TileSpec *tile) +{ + getNodeTileN(n, p, index, data, *tile); +} + +// Returns a tile, ready for use, rotated according to the node facedir. +void MapblockMeshGenerator::getTile(v3s16 direction, TileSpec *tile) +{ + getNodeTile(n, p, direction, data, *tile); +} + +// Returns a special tile, ready for use, non-rotated. +void MapblockMeshGenerator::getSpecialTile(int index, TileSpec *tile, bool apply_crack) +{ + *tile = f->special_tiles[index]; + TileLayer *top_layer = nullptr; + + for (auto &layernum : tile->layers) { + TileLayer *layer = &layernum; + if (layer->texture_id == 0) + continue; + top_layer = layer; + if (!layer->has_color) + n.getColor(*f, &layer->color); + } + + if (apply_crack) + top_layer->material_flags |= MATERIAL_FLAG_CRACK; +} + +void MapblockMeshGenerator::drawQuad(v3f *coords, const v3s16 &normal, + float vertical_tiling) +{ + const v2f tcoords[4] = {v2f(0.0, 0.0), v2f(1.0, 0.0), + v2f(1.0, vertical_tiling), v2f(0.0, vertical_tiling)}; + video::S3DVertex vertices[4]; + bool shade_face = !f->light_source && (normal != v3s16(0, 0, 0)); + v3f normal2(normal.X, normal.Y, normal.Z); + for (int j = 0; j < 4; j++) { + vertices[j].Pos = coords[j] + origin; + vertices[j].Normal = normal2; + if (data->m_smooth_lighting) + vertices[j].Color = blendLightColor(coords[j]); + else + vertices[j].Color = color; + if (shade_face) + applyFacesShading(vertices[j].Color, normal2); + vertices[j].TCoords = tcoords[j]; + } + collector->append(tile, vertices, 4, quad_indices, 6); +} + +// Create a cuboid. +// tiles - the tiles (materials) to use (for all 6 faces) +// tilecount - number of entries in tiles, 1<=tilecount<=6 +// lights - vertex light levels. The order is the same as in light_dirs. +// NULL may be passed if smooth lighting is disabled. +// txc - texture coordinates - this is a list of texture coordinates +// for the opposite corners of each face - therefore, there +// should be (2+2)*6=24 values in the list. The order of +// the faces in the list is up-down-right-left-back-front +// (compatible with ContentFeatures). +// mask - a bit mask that suppresses drawing of tiles. +// tile i will not be drawn if mask & (1 << i) is 1 +void MapblockMeshGenerator::drawCuboid(const aabb3f &box, + TileSpec *tiles, int tilecount, const LightInfo *lights, const f32 *txc, u8 mask) +{ + assert(tilecount >= 1 && tilecount <= 6); // pre-condition + + v3f min = box.MinEdge; + v3f max = box.MaxEdge; + + video::SColor colors[6]; + if (!data->m_smooth_lighting) { + for (int face = 0; face != 6; ++face) { + colors[face] = encode_light(light, f->light_source); + } + if (!f->light_source) { + applyFacesShading(colors[0], v3f(0, 1, 0)); + applyFacesShading(colors[1], v3f(0, -1, 0)); + applyFacesShading(colors[2], v3f(1, 0, 0)); + applyFacesShading(colors[3], v3f(-1, 0, 0)); + applyFacesShading(colors[4], v3f(0, 0, 1)); + applyFacesShading(colors[5], v3f(0, 0, -1)); + } + } + + video::S3DVertex vertices[24] = { + // top + video::S3DVertex(min.X, max.Y, max.Z, 0, 1, 0, colors[0], txc[0], txc[1]), + video::S3DVertex(max.X, max.Y, max.Z, 0, 1, 0, colors[0], txc[2], txc[1]), + video::S3DVertex(max.X, max.Y, min.Z, 0, 1, 0, colors[0], txc[2], txc[3]), + video::S3DVertex(min.X, max.Y, min.Z, 0, 1, 0, colors[0], txc[0], txc[3]), + // bottom + video::S3DVertex(min.X, min.Y, min.Z, 0, -1, 0, colors[1], txc[4], txc[5]), + video::S3DVertex(max.X, min.Y, min.Z, 0, -1, 0, colors[1], txc[6], txc[5]), + video::S3DVertex(max.X, min.Y, max.Z, 0, -1, 0, colors[1], txc[6], txc[7]), + video::S3DVertex(min.X, min.Y, max.Z, 0, -1, 0, colors[1], txc[4], txc[7]), + // right + video::S3DVertex(max.X, max.Y, min.Z, 1, 0, 0, colors[2], txc[ 8], txc[9]), + video::S3DVertex(max.X, max.Y, max.Z, 1, 0, 0, colors[2], txc[10], txc[9]), + video::S3DVertex(max.X, min.Y, max.Z, 1, 0, 0, colors[2], txc[10], txc[11]), + video::S3DVertex(max.X, min.Y, min.Z, 1, 0, 0, colors[2], txc[ 8], txc[11]), + // left + video::S3DVertex(min.X, max.Y, max.Z, -1, 0, 0, colors[3], txc[12], txc[13]), + video::S3DVertex(min.X, max.Y, min.Z, -1, 0, 0, colors[3], txc[14], txc[13]), + video::S3DVertex(min.X, min.Y, min.Z, -1, 0, 0, colors[3], txc[14], txc[15]), + video::S3DVertex(min.X, min.Y, max.Z, -1, 0, 0, colors[3], txc[12], txc[15]), + // back + video::S3DVertex(max.X, max.Y, max.Z, 0, 0, 1, colors[4], txc[16], txc[17]), + video::S3DVertex(min.X, max.Y, max.Z, 0, 0, 1, colors[4], txc[18], txc[17]), + video::S3DVertex(min.X, min.Y, max.Z, 0, 0, 1, colors[4], txc[18], txc[19]), + video::S3DVertex(max.X, min.Y, max.Z, 0, 0, 1, colors[4], txc[16], txc[19]), + // front + video::S3DVertex(min.X, max.Y, min.Z, 0, 0, -1, colors[5], txc[20], txc[21]), + video::S3DVertex(max.X, max.Y, min.Z, 0, 0, -1, colors[5], txc[22], txc[21]), + video::S3DVertex(max.X, min.Y, min.Z, 0, 0, -1, colors[5], txc[22], txc[23]), + video::S3DVertex(min.X, min.Y, min.Z, 0, 0, -1, colors[5], txc[20], txc[23]), + }; + + static const u8 light_indices[24] = { + 3, 7, 6, 2, + 0, 4, 5, 1, + 6, 7, 5, 4, + 3, 2, 0, 1, + 7, 3, 1, 5, + 2, 6, 4, 0 + }; + + for (int face = 0; face < 6; face++) { + int tileindex = MYMIN(face, tilecount - 1); + const TileSpec &tile = tiles[tileindex]; + for (int j = 0; j < 4; j++) { + video::S3DVertex &vertex = vertices[face * 4 + j]; + v2f &tcoords = vertex.TCoords; + switch (tile.rotation) { + case 0: + break; + case 1: // R90 + tcoords.rotateBy(90, irr::core::vector2df(0, 0)); + break; + case 2: // R180 + tcoords.rotateBy(180, irr::core::vector2df(0, 0)); + break; + case 3: // R270 + tcoords.rotateBy(270, irr::core::vector2df(0, 0)); + break; + case 4: // FXR90 + tcoords.X = 1.0 - tcoords.X; + tcoords.rotateBy(90, irr::core::vector2df(0, 0)); + break; + case 5: // FXR270 + tcoords.X = 1.0 - tcoords.X; + tcoords.rotateBy(270, irr::core::vector2df(0, 0)); + break; + case 6: // FYR90 + tcoords.Y = 1.0 - tcoords.Y; + tcoords.rotateBy(90, irr::core::vector2df(0, 0)); + break; + case 7: // FYR270 + tcoords.Y = 1.0 - tcoords.Y; + tcoords.rotateBy(270, irr::core::vector2df(0, 0)); + break; + case 8: // FX + tcoords.X = 1.0 - tcoords.X; + break; + case 9: // FY + tcoords.Y = 1.0 - tcoords.Y; + break; + default: + break; + } + } + } + + if (data->m_smooth_lighting) { + for (int j = 0; j < 24; ++j) { + video::S3DVertex &vertex = vertices[j]; + vertex.Color = encode_light( + lights[light_indices[j]].getPair(MYMAX(0.0f, vertex.Normal.Y)), + f->light_source); + if (!f->light_source) + applyFacesShading(vertex.Color, vertex.Normal); + } + } + + // Add to mesh collector + for (int k = 0; k < 6; ++k) { + if (mask & (1 << k)) + continue; + int tileindex = MYMIN(k, tilecount - 1); + collector->append(tiles[tileindex], vertices + 4 * k, 4, quad_indices, 6); + } +} + +// Gets the base lighting values for a node +void MapblockMeshGenerator::getSmoothLightFrame() +{ + for (int k = 0; k < 8; ++k) + frame.sunlight[k] = false; + for (int k = 0; k < 8; ++k) { + LightPair light(getSmoothLightTransparent(blockpos_nodes + p, light_dirs[k], data)); + frame.lightsDay[k] = light.lightDay; + frame.lightsNight[k] = light.lightNight; + // If there is direct sunlight and no ambient occlusion at some corner, + // mark the vertical edge (top and bottom corners) containing it. + if (light.lightDay == 255) { + frame.sunlight[k] = true; + frame.sunlight[k ^ 2] = true; + } + } +} + +// Calculates vertex light level +// vertex_pos - vertex position in the node (coordinates are clamped to [0.0, 1.0] or so) +LightInfo MapblockMeshGenerator::blendLight(const v3f &vertex_pos) +{ + // Light levels at (logical) node corners are known. Here, + // trilinear interpolation is used to calculate light level + // at a given point in the node. + f32 x = core::clamp(vertex_pos.X / BS + 0.5, 0.0 - SMOOTH_LIGHTING_OVERSIZE, 1.0 + SMOOTH_LIGHTING_OVERSIZE); + f32 y = core::clamp(vertex_pos.Y / BS + 0.5, 0.0 - SMOOTH_LIGHTING_OVERSIZE, 1.0 + SMOOTH_LIGHTING_OVERSIZE); + f32 z = core::clamp(vertex_pos.Z / BS + 0.5, 0.0 - SMOOTH_LIGHTING_OVERSIZE, 1.0 + SMOOTH_LIGHTING_OVERSIZE); + f32 lightDay = 0.0; // daylight + f32 lightNight = 0.0; + f32 lightBoosted = 0.0; // daylight + direct sunlight, if any + for (int k = 0; k < 8; ++k) { + f32 dx = (k & 4) ? x : 1 - x; + f32 dy = (k & 2) ? y : 1 - y; + f32 dz = (k & 1) ? z : 1 - z; + // Use direct sunlight (255), if any; use daylight otherwise. + f32 light_boosted = frame.sunlight[k] ? 255 : frame.lightsDay[k]; + lightDay += dx * dy * dz * frame.lightsDay[k]; + lightNight += dx * dy * dz * frame.lightsNight[k]; + lightBoosted += dx * dy * dz * light_boosted; + } + return LightInfo{lightDay, lightNight, lightBoosted}; +} + +// Calculates vertex color to be used in mapblock mesh +// vertex_pos - vertex position in the node (coordinates are clamped to [0.0, 1.0] or so) +// tile_color - node's tile color +video::SColor MapblockMeshGenerator::blendLightColor(const v3f &vertex_pos) +{ + LightInfo light = blendLight(vertex_pos); + return encode_light(light.getPair(), f->light_source); +} + +video::SColor MapblockMeshGenerator::blendLightColor(const v3f &vertex_pos, + const v3f &vertex_normal) +{ + LightInfo light = blendLight(vertex_pos); + video::SColor color = encode_light(light.getPair(MYMAX(0.0f, vertex_normal.Y)), f->light_source); + if (!f->light_source) + applyFacesShading(color, vertex_normal); + return color; +} + +void MapblockMeshGenerator::generateCuboidTextureCoords(const aabb3f &box, f32 *coords) +{ + f32 tx1 = (box.MinEdge.X / BS) + 0.5; + f32 ty1 = (box.MinEdge.Y / BS) + 0.5; + f32 tz1 = (box.MinEdge.Z / BS) + 0.5; + f32 tx2 = (box.MaxEdge.X / BS) + 0.5; + f32 ty2 = (box.MaxEdge.Y / BS) + 0.5; + f32 tz2 = (box.MaxEdge.Z / BS) + 0.5; + f32 txc[24] = { + tx1, 1 - tz2, tx2, 1 - tz1, // up + tx1, tz1, tx2, tz2, // down + tz1, 1 - ty2, tz2, 1 - ty1, // right + 1 - tz2, 1 - ty2, 1 - tz1, 1 - ty1, // left + 1 - tx2, 1 - ty2, 1 - tx1, 1 - ty1, // back + tx1, 1 - ty2, tx2, 1 - ty1, // front + }; + for (int i = 0; i != 24; ++i) + coords[i] = txc[i]; +} + +void MapblockMeshGenerator::drawAutoLightedCuboid(aabb3f box, const f32 *txc, + TileSpec *tiles, int tile_count, u8 mask) +{ + bool scale = std::fabs(f->visual_scale - 1.0f) > 1e-3f; + f32 texture_coord_buf[24]; + f32 dx1 = box.MinEdge.X; + f32 dy1 = box.MinEdge.Y; + f32 dz1 = box.MinEdge.Z; + f32 dx2 = box.MaxEdge.X; + f32 dy2 = box.MaxEdge.Y; + f32 dz2 = box.MaxEdge.Z; + if (scale) { + if (!txc) { // generate texture coords before scaling + generateCuboidTextureCoords(box, texture_coord_buf); + txc = texture_coord_buf; + } + box.MinEdge *= f->visual_scale; + box.MaxEdge *= f->visual_scale; + } + box.MinEdge += origin; + box.MaxEdge += origin; + if (!txc) { + generateCuboidTextureCoords(box, texture_coord_buf); + txc = texture_coord_buf; + } + if (!tiles) { + tiles = &tile; + tile_count = 1; + } + if (data->m_smooth_lighting) { + LightInfo lights[8]; + for (int j = 0; j < 8; ++j) { + v3f d; + d.X = (j & 4) ? dx2 : dx1; + d.Y = (j & 2) ? dy2 : dy1; + d.Z = (j & 1) ? dz2 : dz1; + lights[j] = blendLight(d); + } + drawCuboid(box, tiles, tile_count, lights, txc, mask); + } else { + drawCuboid(box, tiles, tile_count, nullptr, txc, mask); + } +} + +u8 MapblockMeshGenerator::getNodeBoxMask(aabb3f box, u8 solid_neighbors, u8 sametype_neighbors) const +{ + const f32 NODE_BOUNDARY = 0.5 * BS; + + // For an oversized nodebox, return immediately + if (box.MaxEdge.X > NODE_BOUNDARY || + box.MinEdge.X < -NODE_BOUNDARY || + box.MaxEdge.Y > NODE_BOUNDARY || + box.MinEdge.Y < -NODE_BOUNDARY || + box.MaxEdge.Z > NODE_BOUNDARY || + box.MinEdge.Z < -NODE_BOUNDARY) + return 0; + + // We can skip faces at node boundary if the matching neighbor is solid + u8 solid_mask = + (box.MaxEdge.Y == NODE_BOUNDARY ? 1 : 0) | + (box.MinEdge.Y == -NODE_BOUNDARY ? 2 : 0) | + (box.MaxEdge.X == NODE_BOUNDARY ? 4 : 0) | + (box.MinEdge.X == -NODE_BOUNDARY ? 8 : 0) | + (box.MaxEdge.Z == NODE_BOUNDARY ? 16 : 0) | + (box.MinEdge.Z == -NODE_BOUNDARY ? 32 : 0); + + u8 sametype_mask = 0; + if (f->alpha == AlphaMode::ALPHAMODE_OPAQUE) { + // In opaque nodeboxes, faces on opposite sides can cancel + // each other out if there is a matching neighbor of the same type + sametype_mask = + ((solid_mask & 3) == 3 ? 3 : 0) | + ((solid_mask & 12) == 12 ? 12 : 0) | + ((solid_mask & 48) == 48 ? 48 : 0); + } + + // Combine masks with actual neighbors to get the faces to be skipped + return (solid_mask & solid_neighbors) | (sametype_mask & sametype_neighbors); +} + + +void MapblockMeshGenerator::prepareLiquidNodeDrawing() +{ + getSpecialTile(0, &tile_liquid_top); + getSpecialTile(1, &tile_liquid); + + MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(p.X, p.Y + 1, p.Z)); + MapNode nbottom = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(p.X, p.Y - 1, p.Z)); + c_flowing = f->liquid_alternative_flowing_id; + c_source = f->liquid_alternative_source_id; + top_is_same_liquid = (ntop.getContent() == c_flowing) || (ntop.getContent() == c_source); + draw_liquid_bottom = (nbottom.getContent() != c_flowing) && (nbottom.getContent() != c_source); + if (draw_liquid_bottom) { + const ContentFeatures &f2 = nodedef->get(nbottom.getContent()); + if (f2.solidness > 1) + draw_liquid_bottom = false; + } + + if (data->m_smooth_lighting) + return; // don't need to pre-compute anything in this case + + if (f->light_source != 0) { + // If this liquid emits light and doesn't contain light, draw + // it at what it emits, for an increased effect + u8 e = decode_light(f->light_source); + light = LightPair(std::max(e, light.lightDay), std::max(e, light.lightNight)); + } else if (nodedef->get(ntop).param_type == CPT_LIGHT) { + // Otherwise, use the light of the node on top if possible + light = LightPair(getInteriorLight(ntop, 0, nodedef)); + } + + color_liquid_top = encode_light(light, f->light_source); + color = encode_light(light, f->light_source); +} + +void MapblockMeshGenerator::getLiquidNeighborhood() +{ + u8 range = rangelim(nodedef->get(c_flowing).liquid_range, 1, 8); + + for (int w = -1; w <= 1; w++) + for (int u = -1; u <= 1; u++) { + NeighborData &neighbor = liquid_neighbors[w + 1][u + 1]; + v3s16 p2 = p + v3s16(u, 0, w); + MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); + neighbor.content = n2.getContent(); + neighbor.level = -0.5 * BS; + neighbor.is_same_liquid = false; + neighbor.top_is_same_liquid = false; + + if (neighbor.content == CONTENT_IGNORE) + continue; + + if (neighbor.content == c_source) { + neighbor.is_same_liquid = true; + neighbor.level = 0.5 * BS; + } else if (neighbor.content == c_flowing) { + neighbor.is_same_liquid = true; + u8 liquid_level = (n2.param2 & LIQUID_LEVEL_MASK); + if (liquid_level <= LIQUID_LEVEL_MAX + 1 - range) + liquid_level = 0; + else + liquid_level -= (LIQUID_LEVEL_MAX + 1 - range); + neighbor.level = (-0.5 + (liquid_level + 0.5) / range) * BS; + } + + // Check node above neighbor. + // NOTE: This doesn't get executed if neighbor + // doesn't exist + p2.Y++; + n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); + if (n2.getContent() == c_source || n2.getContent() == c_flowing) + neighbor.top_is_same_liquid = true; + } +} + +void MapblockMeshGenerator::calculateCornerLevels() +{ + for (int k = 0; k < 2; k++) + for (int i = 0; i < 2; i++) + corner_levels[k][i] = getCornerLevel(i, k); +} + +f32 MapblockMeshGenerator::getCornerLevel(int i, int k) +{ + float sum = 0; + int count = 0; + int air_count = 0; + for (int dk = 0; dk < 2; dk++) + for (int di = 0; di < 2; di++) { + NeighborData &neighbor_data = liquid_neighbors[k + dk][i + di]; + content_t content = neighbor_data.content; + + // If top is liquid, draw starting from top of node + if (neighbor_data.top_is_same_liquid) + return 0.5 * BS; + + // Source always has the full height + if (content == c_source) + return 0.5 * BS; + + // Flowing liquid has level information + if (content == c_flowing) { + sum += neighbor_data.level; + count++; + } else if (content == CONTENT_AIR) { + air_count++; + } + } + if (air_count >= 2) + return -0.5 * BS + 0.2; + if (count > 0) + return sum / count; + return 0; +} + +namespace { + struct LiquidFaceDesc { + v3s16 dir; // XZ + v3s16 p[2]; // XZ only; 1 means +, 0 means - + }; + struct UV { + int u, v; + }; + static const LiquidFaceDesc liquid_base_faces[4] = { + {v3s16( 1, 0, 0), {v3s16(1, 0, 1), v3s16(1, 0, 0)}}, + {v3s16(-1, 0, 0), {v3s16(0, 0, 0), v3s16(0, 0, 1)}}, + {v3s16( 0, 0, 1), {v3s16(0, 0, 1), v3s16(1, 0, 1)}}, + {v3s16( 0, 0, -1), {v3s16(1, 0, 0), v3s16(0, 0, 0)}}, + }; + static const UV liquid_base_vertices[4] = { + {0, 1}, + {1, 1}, + {1, 0}, + {0, 0} + }; +} + +void MapblockMeshGenerator::drawLiquidSides() +{ + for (const auto &face : liquid_base_faces) { + const NeighborData &neighbor = liquid_neighbors[face.dir.Z + 1][face.dir.X + 1]; + + // No face between nodes of the same liquid, unless there is node + // at the top to which it should be connected. Again, unless the face + // there would be inside the liquid + if (neighbor.is_same_liquid) { + if (!top_is_same_liquid) + continue; + if (neighbor.top_is_same_liquid) + continue; + } + + const ContentFeatures &neighbor_features = nodedef->get(neighbor.content); + // Don't draw face if neighbor is blocking the view + if (neighbor_features.solidness == 2) + continue; + + video::S3DVertex vertices[4]; + for (int j = 0; j < 4; j++) { + const UV &vertex = liquid_base_vertices[j]; + const v3s16 &base = face.p[vertex.u]; + float v = vertex.v; + + v3f pos; + pos.X = (base.X - 0.5f) * BS; + pos.Z = (base.Z - 0.5f) * BS; + if (vertex.v) { + pos.Y = neighbor.is_same_liquid ? corner_levels[base.Z][base.X] : -0.5f * BS; + } else if (top_is_same_liquid) { + pos.Y = 0.5f * BS; + } else { + pos.Y = corner_levels[base.Z][base.X]; + v += (0.5f * BS - corner_levels[base.Z][base.X]) / BS; + } + + if (data->m_smooth_lighting) + color = blendLightColor(pos); + pos += origin; + vertices[j] = video::S3DVertex(pos.X, pos.Y, pos.Z, 0, 0, 0, color, vertex.u, v); + }; + collector->append(tile_liquid, vertices, 4, quad_indices, 6); + } +} + +void MapblockMeshGenerator::drawLiquidTop() +{ + // To get backface culling right, the vertices need to go + // clockwise around the front of the face. And we happened to + // calculate corner levels in exact reverse order. + static const int corner_resolve[4][2] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}}; + + video::S3DVertex vertices[4] = { + video::S3DVertex(-BS / 2, 0, BS / 2, 0, 0, 0, color_liquid_top, 0, 1), + video::S3DVertex( BS / 2, 0, BS / 2, 0, 0, 0, color_liquid_top, 1, 1), + video::S3DVertex( BS / 2, 0, -BS / 2, 0, 0, 0, color_liquid_top, 1, 0), + video::S3DVertex(-BS / 2, 0, -BS / 2, 0, 0, 0, color_liquid_top, 0, 0), + }; + + for (int i = 0; i < 4; i++) { + int u = corner_resolve[i][0]; + int w = corner_resolve[i][1]; + vertices[i].Pos.Y += corner_levels[w][u]; + if (data->m_smooth_lighting) + vertices[i].Color = blendLightColor(vertices[i].Pos); + vertices[i].Pos += origin; + } + + // Default downwards-flowing texture animation goes from + // -Z towards +Z, thus the direction is +Z. + // Rotate texture to make animation go in flow direction + // Positive if liquid moves towards +Z + f32 dz = (corner_levels[0][0] + corner_levels[0][1]) - + (corner_levels[1][0] + corner_levels[1][1]); + // Positive if liquid moves towards +X + f32 dx = (corner_levels[0][0] + corner_levels[1][0]) - + (corner_levels[0][1] + corner_levels[1][1]); + f32 tcoord_angle = atan2(dz, dx) * core::RADTODEG; + v2f tcoord_center(0.5, 0.5); + v2f tcoord_translate(blockpos_nodes.Z + p.Z, blockpos_nodes.X + p.X); + tcoord_translate.rotateBy(tcoord_angle); + tcoord_translate.X -= floor(tcoord_translate.X); + tcoord_translate.Y -= floor(tcoord_translate.Y); + + for (video::S3DVertex &vertex : vertices) { + vertex.TCoords.rotateBy(tcoord_angle, tcoord_center); + vertex.TCoords += tcoord_translate; + } + + std::swap(vertices[0].TCoords, vertices[2].TCoords); + + collector->append(tile_liquid_top, vertices, 4, quad_indices, 6); +} + +void MapblockMeshGenerator::drawLiquidBottom() +{ + video::S3DVertex vertices[4] = { + video::S3DVertex(-BS / 2, -BS / 2, -BS / 2, 0, 0, 0, color_liquid_top, 0, 0), + video::S3DVertex( BS / 2, -BS / 2, -BS / 2, 0, 0, 0, color_liquid_top, 1, 0), + video::S3DVertex( BS / 2, -BS / 2, BS / 2, 0, 0, 0, color_liquid_top, 1, 1), + video::S3DVertex(-BS / 2, -BS / 2, BS / 2, 0, 0, 0, color_liquid_top, 0, 1), + }; + + for (int i = 0; i < 4; i++) { + if (data->m_smooth_lighting) + vertices[i].Color = blendLightColor(vertices[i].Pos); + vertices[i].Pos += origin; + } + + collector->append(tile_liquid_top, vertices, 4, quad_indices, 6); +} + +void MapblockMeshGenerator::drawLiquidNode() +{ + prepareLiquidNodeDrawing(); + getLiquidNeighborhood(); + calculateCornerLevels(); + drawLiquidSides(); + if (!top_is_same_liquid) + drawLiquidTop(); + if (draw_liquid_bottom) + drawLiquidBottom(); +} + +void MapblockMeshGenerator::drawGlasslikeNode() +{ + useTile(0, 0, 0); + + for (int face = 0; face < 6; face++) { + // Check this neighbor + v3s16 dir = g_6dirs[face]; + v3s16 neighbor_pos = blockpos_nodes + p + dir; + MapNode neighbor = data->m_vmanip.getNodeNoExNoEmerge(neighbor_pos); + // Don't make face if neighbor is of same type + if (neighbor.getContent() == n.getContent()) + continue; + // Face at Z- + v3f vertices[4] = { + v3f(-BS / 2, BS / 2, -BS / 2), + v3f( BS / 2, BS / 2, -BS / 2), + v3f( BS / 2, -BS / 2, -BS / 2), + v3f(-BS / 2, -BS / 2, -BS / 2), + }; + + for (v3f &vertex : vertices) { + switch (face) { + case D6D_ZP: + vertex.rotateXZBy(180); break; + case D6D_YP: + vertex.rotateYZBy( 90); break; + case D6D_XP: + vertex.rotateXZBy( 90); break; + case D6D_ZN: + vertex.rotateXZBy( 0); break; + case D6D_YN: + vertex.rotateYZBy(-90); break; + case D6D_XN: + vertex.rotateXZBy(-90); break; + } + } + drawQuad(vertices, dir); + } +} + +void MapblockMeshGenerator::drawGlasslikeFramedNode() +{ + TileSpec tiles[6]; + for (int face = 0; face < 6; face++) + getTile(g_6dirs[face], &tiles[face]); + + if (!data->m_smooth_lighting) + color = encode_light(light, f->light_source); + + TileSpec glass_tiles[6]; + for (auto &glass_tile : glass_tiles) + glass_tile = tiles[4]; + + // Only respect H/V merge bits when paramtype2 = "glasslikeliquidlevel" (liquid tank) + u8 param2 = (f->param_type_2 == CPT2_GLASSLIKE_LIQUID_LEVEL) ? n.getParam2() : 0; + bool H_merge = !(param2 & 128); + bool V_merge = !(param2 & 64); + param2 &= 63; + + static const float a = BS / 2.0f; + static const float g = a - 0.03f; + static const float b = 0.876f * (BS / 2.0f); + + static const aabb3f frame_edges[FRAMED_EDGE_COUNT] = { + aabb3f( b, b, -a, a, a, a), // y+ + aabb3f(-a, b, -a, -b, a, a), // y+ + aabb3f( b, -a, -a, a, -b, a), // y- + aabb3f(-a, -a, -a, -b, -b, a), // y- + aabb3f( b, -a, b, a, a, a), // x+ + aabb3f( b, -a, -a, a, a, -b), // x+ + aabb3f(-a, -a, b, -b, a, a), // x- + aabb3f(-a, -a, -a, -b, a, -b), // x- + aabb3f(-a, b, b, a, a, a), // z+ + aabb3f(-a, -a, b, a, -b, a), // z+ + aabb3f(-a, -a, -a, a, -b, -b), // z- + aabb3f(-a, b, -a, a, a, -b), // z- + }; + + // tables of neighbour (connect if same type and merge allowed), + // checked with g_26dirs + + // 1 = connect, 0 = face visible + bool nb[FRAMED_NEIGHBOR_COUNT] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + // 1 = check + static const bool check_nb_vertical [FRAMED_NEIGHBOR_COUNT] = + {0,1,0,0,1,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; + static const bool check_nb_horizontal [FRAMED_NEIGHBOR_COUNT] = + {1,0,1,1,0,1, 0,0,0,0, 1,1,1,1, 0,0,0,0}; + static const bool check_nb_all [FRAMED_NEIGHBOR_COUNT] = + {1,1,1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}; + const bool *check_nb = check_nb_all; + + // neighbours checks for frames visibility + if (H_merge || V_merge) { + if (!H_merge) + check_nb = check_nb_vertical; // vertical-only merge + if (!V_merge) + check_nb = check_nb_horizontal; // horizontal-only merge + content_t current = n.getContent(); + for (int i = 0; i < FRAMED_NEIGHBOR_COUNT; i++) { + if (!check_nb[i]) + continue; + v3s16 n2p = blockpos_nodes + p + g_26dirs[i]; + MapNode n2 = data->m_vmanip.getNodeNoEx(n2p); + content_t n2c = n2.getContent(); + if (n2c == current) + nb[i] = 1; + } + } + + // edge visibility + + static const u8 nb_triplet[FRAMED_EDGE_COUNT][3] = { + {1, 2, 7}, {1, 5, 6}, {4, 2, 15}, {4, 5, 14}, + {2, 0, 11}, {2, 3, 13}, {5, 0, 10}, {5, 3, 12}, + {0, 1, 8}, {0, 4, 16}, {3, 4, 17}, {3, 1, 9}, + }; + + tile = tiles[1]; + for (int edge = 0; edge < FRAMED_EDGE_COUNT; edge++) { + bool edge_invisible; + if (nb[nb_triplet[edge][2]]) + edge_invisible = nb[nb_triplet[edge][0]] & nb[nb_triplet[edge][1]]; + else + edge_invisible = nb[nb_triplet[edge][0]] ^ nb[nb_triplet[edge][1]]; + if (edge_invisible) + continue; + drawAutoLightedCuboid(frame_edges[edge]); + } + + for (int face = 0; face < 6; face++) { + if (nb[face]) + continue; + + tile = glass_tiles[face]; + // Face at Z- + v3f vertices[4] = { + v3f(-a, a, -g), + v3f( a, a, -g), + v3f( a, -a, -g), + v3f(-a, -a, -g), + }; + + for (v3f &vertex : vertices) { + switch (face) { + case D6D_ZP: + vertex.rotateXZBy(180); break; + case D6D_YP: + vertex.rotateYZBy( 90); break; + case D6D_XP: + vertex.rotateXZBy( 90); break; + case D6D_ZN: + vertex.rotateXZBy( 0); break; + case D6D_YN: + vertex.rotateYZBy(-90); break; + case D6D_XN: + vertex.rotateXZBy(-90); break; + } + } + v3s16 dir = g_6dirs[face]; + drawQuad(vertices, dir); + } + + // Optionally render internal liquid level defined by param2 + // Liquid is textured with 1 tile defined in nodedef 'special_tiles' + if (param2 > 0 && f->param_type_2 == CPT2_GLASSLIKE_LIQUID_LEVEL && + f->special_tiles[0].layers[0].texture) { + // Internal liquid level has param2 range 0 .. 63, + // convert it to -0.5 .. 0.5 + float vlev = (param2 / 63.0f) * 2.0f - 1.0f; + getSpecialTile(0, &tile); + drawAutoLightedCuboid(aabb3f(-(nb[5] ? g : b), + -(nb[4] ? g : b), + -(nb[3] ? g : b), + (nb[2] ? g : b), + (nb[1] ? g : b) * vlev, + (nb[0] ? g : b))); + } +} + +void MapblockMeshGenerator::drawAllfacesNode() +{ + static const aabb3f box(-BS / 2, -BS / 2, -BS / 2, BS / 2, BS / 2, BS / 2); + useTile(0, 0, 0); + drawAutoLightedCuboid(box); +} + +void MapblockMeshGenerator::drawTorchlikeNode() +{ + u8 wall = n.getWallMounted(nodedef); + u8 tileindex = 0; + switch (wall) { + case DWM_YP: tileindex = 1; break; // ceiling + case DWM_YN: tileindex = 0; break; // floor + default: tileindex = 2; // side (or invalid—should we care?) + } + useTile(tileindex, MATERIAL_FLAG_CRACK_OVERLAY, MATERIAL_FLAG_BACKFACE_CULLING); + + float size = BS / 2 * f->visual_scale; + v3f vertices[4] = { + v3f(-size, size, 0), + v3f( size, size, 0), + v3f( size, -size, 0), + v3f(-size, -size, 0), + }; + + for (v3f &vertex : vertices) { + switch (wall) { + case DWM_YP: + vertex.Y += -size + BS/2; + vertex.rotateXZBy(-45); + break; + case DWM_YN: + vertex.Y += size - BS/2; + vertex.rotateXZBy(45); + break; + case DWM_XP: + vertex.X += -size + BS/2; + break; + case DWM_XN: + vertex.X += -size + BS/2; + vertex.rotateXZBy(180); + break; + case DWM_ZP: + vertex.X += -size + BS/2; + vertex.rotateXZBy(90); + break; + case DWM_ZN: + vertex.X += -size + BS/2; + vertex.rotateXZBy(-90); + } + } + drawQuad(vertices); +} + +void MapblockMeshGenerator::drawSignlikeNode() +{ + u8 wall = n.getWallMounted(nodedef); + useTile(0, MATERIAL_FLAG_CRACK_OVERLAY, MATERIAL_FLAG_BACKFACE_CULLING); + static const float offset = BS / 16; + float size = BS / 2 * f->visual_scale; + // Wall at X+ of node + v3f vertices[4] = { + v3f(BS / 2 - offset, size, size), + v3f(BS / 2 - offset, size, -size), + v3f(BS / 2 - offset, -size, -size), + v3f(BS / 2 - offset, -size, size), + }; + + for (v3f &vertex : vertices) { + switch (wall) { + case DWM_YP: + vertex.rotateXYBy( 90); break; + case DWM_YN: + vertex.rotateXYBy(-90); break; + case DWM_XP: + vertex.rotateXZBy( 0); break; + case DWM_XN: + vertex.rotateXZBy(180); break; + case DWM_ZP: + vertex.rotateXZBy( 90); break; + case DWM_ZN: + vertex.rotateXZBy(-90); break; + } + } + drawQuad(vertices); +} + +void MapblockMeshGenerator::drawPlantlikeQuad(float rotation, float quad_offset, + bool offset_top_only) +{ + v3f vertices[4] = { + v3f(-scale, -BS / 2 + 2.0 * scale * plant_height, 0), + v3f( scale, -BS / 2 + 2.0 * scale * plant_height, 0), + v3f( scale, -BS / 2, 0), + v3f(-scale, -BS / 2, 0), + }; + if (random_offset_Y) { + PseudoRandom yrng(face_num++ | p.X << 16 | p.Z << 8 | p.Y << 24); + offset.Y = -BS * ((yrng.next() % 16 / 16.0) * 0.125); + } + int offset_count = offset_top_only ? 2 : 4; + for (int i = 0; i < offset_count; i++) + vertices[i].Z += quad_offset; + + for (v3f &vertex : vertices) { + vertex.rotateXZBy(rotation + rotate_degree); + vertex += offset; + } + + u8 wall = n.getWallMounted(nodedef); + if (wall != DWM_YN) { + for (v3f &vertex : vertices) { + switch (wall) { + case DWM_YP: + vertex.rotateYZBy(180); + vertex.rotateXZBy(180); + break; + case DWM_XP: + vertex.rotateXYBy(90); + break; + case DWM_XN: + vertex.rotateXYBy(-90); + vertex.rotateYZBy(180); + break; + case DWM_ZP: + vertex.rotateYZBy(-90); + vertex.rotateXYBy(90); + break; + case DWM_ZN: + vertex.rotateYZBy(90); + vertex.rotateXYBy(90); + break; + } + } + } + + drawQuad(vertices, v3s16(0, 0, 0), plant_height); +} + +void MapblockMeshGenerator::drawPlantlike(bool is_rooted) +{ + draw_style = PLANT_STYLE_CROSS; + scale = BS / 2 * f->visual_scale; + offset = v3f(0, 0, 0); + rotate_degree = 0.0f; + random_offset_Y = false; + face_num = 0; + plant_height = 1.0; + + switch (f->param_type_2) { + case CPT2_MESHOPTIONS: + draw_style = PlantlikeStyle(n.param2 & MO_MASK_STYLE); + if (n.param2 & MO_BIT_SCALE_SQRT2) + scale *= 1.41421; + if (n.param2 & MO_BIT_RANDOM_OFFSET) { + PseudoRandom rng(p.X << 8 | p.Z | p.Y << 16); + offset.X = BS * ((rng.next() % 16 / 16.0) * 0.29 - 0.145); + offset.Z = BS * ((rng.next() % 16 / 16.0) * 0.29 - 0.145); + } + if (n.param2 & MO_BIT_RANDOM_OFFSET_Y) + random_offset_Y = true; + break; + + case CPT2_DEGROTATE: + case CPT2_COLORED_DEGROTATE: + rotate_degree = 1.5f * n.getDegRotate(nodedef); + break; + + case CPT2_LEVELED: + plant_height = n.param2 / 16.0; + break; + + default: + break; + } + + if (is_rooted) { + u8 wall = n.getWallMounted(nodedef); + switch (wall) { + case DWM_YP: + offset.Y += BS*2; + break; + case DWM_XN: + case DWM_XP: + case DWM_ZN: + case DWM_ZP: + offset.X += -BS; + offset.Y += BS; + break; + } + } + + switch (draw_style) { + case PLANT_STYLE_CROSS: + drawPlantlikeQuad(46); + drawPlantlikeQuad(-44); + break; + + case PLANT_STYLE_CROSS2: + drawPlantlikeQuad(91); + drawPlantlikeQuad(1); + break; + + case PLANT_STYLE_STAR: + drawPlantlikeQuad(121); + drawPlantlikeQuad(241); + drawPlantlikeQuad(1); + break; + + case PLANT_STYLE_HASH: + drawPlantlikeQuad( 1, BS / 4); + drawPlantlikeQuad( 91, BS / 4); + drawPlantlikeQuad(181, BS / 4); + drawPlantlikeQuad(271, BS / 4); + break; + + case PLANT_STYLE_HASH2: + drawPlantlikeQuad( 1, -BS / 2, true); + drawPlantlikeQuad( 91, -BS / 2, true); + drawPlantlikeQuad(181, -BS / 2, true); + drawPlantlikeQuad(271, -BS / 2, true); + break; + } +} + +void MapblockMeshGenerator::drawPlantlikeNode() +{ + useTile(); + drawPlantlike(); +} + +void MapblockMeshGenerator::drawPlantlikeRootedNode() +{ + useTile(0, MATERIAL_FLAG_CRACK_OVERLAY, 0, true); + origin += v3f(0.0, BS, 0.0); + p.Y++; + if (data->m_smooth_lighting) { + getSmoothLightFrame(); + } else { + MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + p); + light = LightPair(getInteriorLight(ntop, 1, nodedef)); + } + drawPlantlike(true); + p.Y--; +} + +void MapblockMeshGenerator::drawFirelikeQuad(float rotation, float opening_angle, + float offset_h, float offset_v) +{ + v3f vertices[4] = { + v3f(-scale, -BS / 2 + scale * 2, 0), + v3f( scale, -BS / 2 + scale * 2, 0), + v3f( scale, -BS / 2, 0), + v3f(-scale, -BS / 2, 0), + }; + + for (v3f &vertex : vertices) { + vertex.rotateYZBy(opening_angle); + vertex.Z += offset_h; + vertex.rotateXZBy(rotation); + vertex.Y += offset_v; + } + drawQuad(vertices); +} + +void MapblockMeshGenerator::drawFirelikeNode() +{ + useTile(); + scale = BS / 2 * f->visual_scale; + + // Check for adjacent nodes + bool neighbors = false; + bool neighbor[6] = {0, 0, 0, 0, 0, 0}; + content_t current = n.getContent(); + for (int i = 0; i < 6; i++) { + v3s16 n2p = blockpos_nodes + p + g_6dirs[i]; + MapNode n2 = data->m_vmanip.getNodeNoEx(n2p); + content_t n2c = n2.getContent(); + if (n2c != CONTENT_IGNORE && n2c != CONTENT_AIR && n2c != current) { + neighbor[i] = true; + neighbors = true; + } + } + bool drawBasicFire = neighbor[D6D_YN] || !neighbors; + bool drawBottomFire = neighbor[D6D_YP]; + + if (drawBasicFire || neighbor[D6D_ZP]) + drawFirelikeQuad(0, -10, 0.4 * BS); + else if (drawBottomFire) + drawFirelikeQuad(0, 70, 0.47 * BS, 0.484 * BS); + + if (drawBasicFire || neighbor[D6D_XN]) + drawFirelikeQuad(90, -10, 0.4 * BS); + else if (drawBottomFire) + drawFirelikeQuad(90, 70, 0.47 * BS, 0.484 * BS); + + if (drawBasicFire || neighbor[D6D_ZN]) + drawFirelikeQuad(180, -10, 0.4 * BS); + else if (drawBottomFire) + drawFirelikeQuad(180, 70, 0.47 * BS, 0.484 * BS); + + if (drawBasicFire || neighbor[D6D_XP]) + drawFirelikeQuad(270, -10, 0.4 * BS); + else if (drawBottomFire) + drawFirelikeQuad(270, 70, 0.47 * BS, 0.484 * BS); + + if (drawBasicFire) { + drawFirelikeQuad(45, 0, 0.0); + drawFirelikeQuad(-45, 0, 0.0); + } +} + +void MapblockMeshGenerator::drawFencelikeNode() +{ + useTile(0, 0, 0); + TileSpec tile_nocrack = tile; + + for (auto &layer : tile_nocrack.layers) + layer.material_flags &= ~MATERIAL_FLAG_CRACK; + + // Put wood the right way around in the posts + TileSpec tile_rot = tile; + tile_rot.rotation = 1; + + static const f32 post_rad = BS / 8; + static const f32 bar_rad = BS / 16; + static const f32 bar_len = BS / 2 - post_rad; + + // The post - always present + static const aabb3f post(-post_rad, -BS / 2, -post_rad, + post_rad, BS / 2, post_rad); + static const f32 postuv[24] = { + 0.375, 0.375, 0.625, 0.625, + 0.375, 0.375, 0.625, 0.625, + 0.000, 0.000, 0.250, 1.000, + 0.250, 0.000, 0.500, 1.000, + 0.500, 0.000, 0.750, 1.000, + 0.750, 0.000, 1.000, 1.000, + }; + tile = tile_rot; + drawAutoLightedCuboid(post, postuv); + + tile = tile_nocrack; + + // Now a section of fence, +X, if there's a post there + v3s16 p2 = p; + p2.X++; + MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); + const ContentFeatures *f2 = &nodedef->get(n2); + if (f2->drawtype == NDT_FENCELIKE) { + static const aabb3f bar_x1(BS / 2 - bar_len, BS / 4 - bar_rad, -bar_rad, + BS / 2 + bar_len, BS / 4 + bar_rad, bar_rad); + static const aabb3f bar_x2(BS / 2 - bar_len, -BS / 4 - bar_rad, -bar_rad, + BS / 2 + bar_len, -BS / 4 + bar_rad, bar_rad); + static const f32 xrailuv[24] = { + 0.000, 0.125, 1.000, 0.250, + 0.000, 0.250, 1.000, 0.375, + 0.375, 0.375, 0.500, 0.500, + 0.625, 0.625, 0.750, 0.750, + 0.000, 0.500, 1.000, 0.625, + 0.000, 0.875, 1.000, 1.000, + }; + drawAutoLightedCuboid(bar_x1, xrailuv); + drawAutoLightedCuboid(bar_x2, xrailuv); + } + + // Now a section of fence, +Z, if there's a post there + p2 = p; + p2.Z++; + n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); + f2 = &nodedef->get(n2); + if (f2->drawtype == NDT_FENCELIKE) { + static const aabb3f bar_z1(-bar_rad, BS / 4 - bar_rad, BS / 2 - bar_len, + bar_rad, BS / 4 + bar_rad, BS / 2 + bar_len); + static const aabb3f bar_z2(-bar_rad, -BS / 4 - bar_rad, BS / 2 - bar_len, + bar_rad, -BS / 4 + bar_rad, BS / 2 + bar_len); + static const f32 zrailuv[24] = { + 0.1875, 0.0625, 0.3125, 0.3125, // cannot rotate; stretch + 0.2500, 0.0625, 0.3750, 0.3125, // for wood texture instead + 0.0000, 0.5625, 1.0000, 0.6875, + 0.0000, 0.3750, 1.0000, 0.5000, + 0.3750, 0.3750, 0.5000, 0.5000, + 0.6250, 0.6250, 0.7500, 0.7500, + }; + drawAutoLightedCuboid(bar_z1, zrailuv); + drawAutoLightedCuboid(bar_z2, zrailuv); + } +} + +bool MapblockMeshGenerator::isSameRail(v3s16 dir) +{ + MapNode node2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p + dir); + if (node2.getContent() == n.getContent()) + return true; + const ContentFeatures &def2 = nodedef->get(node2); + return ((def2.drawtype == NDT_RAILLIKE) && + (def2.getGroup(raillike_groupname) == raillike_group)); +} + +namespace { + static const v3s16 rail_direction[4] = { + v3s16( 0, 0, 1), + v3s16( 0, 0, -1), + v3s16(-1, 0, 0), + v3s16( 1, 0, 0), + }; + static const int rail_slope_angle[4] = {0, 180, 90, -90}; + + enum RailTile { + straight, + curved, + junction, + cross, + }; + struct RailDesc { + int tile_index; + int angle; + }; + static const RailDesc rail_kinds[16] = { + // +x -x -z +z + //------------- + {straight, 0}, // . . . . + {straight, 0}, // . . . +Z + {straight, 0}, // . . -Z . + {straight, 0}, // . . -Z +Z + {straight, 90}, // . -X . . + { curved, 180}, // . -X . +Z + { curved, 270}, // . -X -Z . + {junction, 180}, // . -X -Z +Z + {straight, 90}, // +X . . . + { curved, 90}, // +X . . +Z + { curved, 0}, // +X . -Z . + {junction, 0}, // +X . -Z +Z + {straight, 90}, // +X -X . . + {junction, 90}, // +X -X . +Z + {junction, 270}, // +X -X -Z . + { cross, 0}, // +X -X -Z +Z + }; +} + +void MapblockMeshGenerator::drawRaillikeNode() +{ + raillike_group = nodedef->get(n).getGroup(raillike_groupname); + + int code = 0; + int angle; + int tile_index; + bool sloped = false; + for (int dir = 0; dir < 4; dir++) { + bool rail_above = isSameRail(rail_direction[dir] + v3s16(0, 1, 0)); + if (rail_above) { + sloped = true; + angle = rail_slope_angle[dir]; + } + if (rail_above || + isSameRail(rail_direction[dir]) || + isSameRail(rail_direction[dir] + v3s16(0, -1, 0))) + code |= 1 << dir; + } + + if (sloped) { + tile_index = straight; + } else { + tile_index = rail_kinds[code].tile_index; + angle = rail_kinds[code].angle; + } + + useTile(tile_index, MATERIAL_FLAG_CRACK_OVERLAY, MATERIAL_FLAG_BACKFACE_CULLING); + + static const float offset = BS / 64; + static const float size = BS / 2; + float y2 = sloped ? size : -size; + v3f vertices[4] = { + v3f(-size, y2 + offset, size), + v3f( size, y2 + offset, size), + v3f( size, -size + offset, -size), + v3f(-size, -size + offset, -size), + }; + if (angle) + for (v3f &vertex : vertices) + vertex.rotateXZBy(angle); + drawQuad(vertices); +} + +namespace { + static const v3s16 nodebox_tile_dirs[6] = { + v3s16(0, 1, 0), + v3s16(0, -1, 0), + v3s16(1, 0, 0), + v3s16(-1, 0, 0), + v3s16(0, 0, 1), + v3s16(0, 0, -1) + }; + + // we have this order for some reason... + static const v3s16 nodebox_connection_dirs[6] = { + v3s16( 0, 1, 0), // top + v3s16( 0, -1, 0), // bottom + v3s16( 0, 0, -1), // front + v3s16(-1, 0, 0), // left + v3s16( 0, 0, 1), // back + v3s16( 1, 0, 0), // right + }; +} + +void MapblockMeshGenerator::drawNodeboxNode() +{ + TileSpec tiles[6]; + for (int face = 0; face < 6; face++) { + // Handles facedir rotation for textures + getTile(nodebox_tile_dirs[face], &tiles[face]); + } + + bool param2_is_rotation = + f->param_type_2 == CPT2_COLORED_FACEDIR || + f->param_type_2 == CPT2_COLORED_WALLMOUNTED || + f->param_type_2 == CPT2_FACEDIR || + f->param_type_2 == CPT2_WALLMOUNTED; + + bool param2_is_level = + f->param_type_2 == CPT2_LEVELED; + + // locate possible neighboring nodes to connect to + u8 neighbors_set = 0; + u8 solid_neighbors = 0; + u8 sametype_neighbors = 0; + for (int dir = 0; dir != 6; dir++) { + u8 flag = 1 << dir; + v3s16 p2 = blockpos_nodes + p + nodebox_tile_dirs[dir]; + MapNode n2 = data->m_vmanip.getNodeNoEx(p2); + + // mark neighbors that are the same node type + // and have the same rotation or higher level stored as param2 + if (n2.param0 == n.param0 && + (!param2_is_rotation || n.param2 == n2.param2) && + (!param2_is_level || n.param2 <= n2.param2)) + sametype_neighbors |= flag; + + // mark neighbors that are simple solid blocks + if (nodedef->get(n2).drawtype == NDT_NORMAL) + solid_neighbors |= flag; + + if (f->node_box.type == NODEBOX_CONNECTED) { + p2 = blockpos_nodes + p + nodebox_connection_dirs[dir]; + n2 = data->m_vmanip.getNodeNoEx(p2); + if (nodedef->nodeboxConnects(n, n2, flag)) + neighbors_set |= flag; + } + } + + std::vector<aabb3f> boxes; + n.getNodeBoxes(nodedef, &boxes, neighbors_set); + + bool isTransparent = false; + + for (const TileSpec &tile : tiles) { + if (tile.layers[0].isTransparent()) { + isTransparent = true; + break; + } + } + + if (isTransparent) { + std::vector<float> sections; + // Preallocate 8 default splits + Min&Max for each nodebox + sections.reserve(8 + 2 * boxes.size()); + + for (int axis = 0; axis < 3; axis++) { + // identify sections + + if (axis == 0) { + // Default split at node bounds, up to 3 nodes in each direction + for (float s = -3.5f * BS; s < 4.0f * BS; s += 1.0f * BS) + sections.push_back(s); + } + else { + // Avoid readding the same 8 default splits for Y and Z + sections.resize(8); + } + + // Add edges of existing node boxes, rounded to 1E-3 + for (size_t i = 0; i < boxes.size(); i++) { + sections.push_back(std::floor(boxes[i].MinEdge[axis] * 1E3) * 1E-3); + sections.push_back(std::floor(boxes[i].MaxEdge[axis] * 1E3) * 1E-3); + } + + // split the boxes at recorded sections + // limit splits to avoid runaway crash if inner loop adds infinite splits + // due to e.g. precision problems. + // 100 is just an arbitrary, reasonably high number. + for (size_t i = 0; i < boxes.size() && i < 100; i++) { + aabb3f *box = &boxes[i]; + for (float section : sections) { + if (box->MinEdge[axis] < section && box->MaxEdge[axis] > section) { + aabb3f copy(*box); + copy.MinEdge[axis] = section; + box->MaxEdge[axis] = section; + boxes.push_back(copy); + box = &boxes[i]; // find new address of the box in case of reallocation + } + } + } + } + } + + for (auto &box : boxes) { + u8 mask = getNodeBoxMask(box, solid_neighbors, sametype_neighbors); + drawAutoLightedCuboid(box, nullptr, tiles, 6, mask); + } +} + +void MapblockMeshGenerator::drawMeshNode() +{ + u8 facedir = 0; + scene::IMesh* mesh; + bool private_mesh; // as a grab/drop pair is not thread-safe + int degrotate = 0; + + if (f->param_type_2 == CPT2_FACEDIR || + f->param_type_2 == CPT2_COLORED_FACEDIR) { + facedir = n.getFaceDir(nodedef); + } else if (f->param_type_2 == CPT2_WALLMOUNTED || + f->param_type_2 == CPT2_COLORED_WALLMOUNTED) { + // Convert wallmounted to 6dfacedir. + // When cache enabled, it is already converted. + facedir = n.getWallMounted(nodedef); + if (!enable_mesh_cache) + facedir = wallmounted_to_facedir[facedir]; + } else if (f->param_type_2 == CPT2_DEGROTATE || + f->param_type_2 == CPT2_COLORED_DEGROTATE) { + degrotate = n.getDegRotate(nodedef); + } + + if (!data->m_smooth_lighting && f->mesh_ptr[facedir] && !degrotate) { + // use cached meshes + private_mesh = false; + mesh = f->mesh_ptr[facedir]; + } else if (f->mesh_ptr[0]) { + // no cache, clone and rotate mesh + private_mesh = true; + mesh = cloneMesh(f->mesh_ptr[0]); + if (facedir) + rotateMeshBy6dFacedir(mesh, facedir); + else if (degrotate) + rotateMeshXZby(mesh, 1.5f * degrotate); + recalculateBoundingBox(mesh); + meshmanip->recalculateNormals(mesh, true, false); + } else + return; + + int mesh_buffer_count = mesh->getMeshBufferCount(); + for (int j = 0; j < mesh_buffer_count; j++) { + useTile(j); + scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); + video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices(); + int vertex_count = buf->getVertexCount(); + + if (data->m_smooth_lighting) { + // Mesh is always private here. So the lighting is applied to each + // vertex right here. + for (int k = 0; k < vertex_count; k++) { + video::S3DVertex &vertex = vertices[k]; + vertex.Color = blendLightColor(vertex.Pos, vertex.Normal); + vertex.Pos += origin; + } + collector->append(tile, vertices, vertex_count, + buf->getIndices(), buf->getIndexCount()); + } else { + // Don't modify the mesh, it may not be private here. + // Instead, let the collector process colors, etc. + collector->append(tile, vertices, vertex_count, + buf->getIndices(), buf->getIndexCount(), origin, + color, f->light_source); + } + } + if (private_mesh) + mesh->drop(); +} + +// also called when the drawtype is known but should have been pre-converted +void MapblockMeshGenerator::errorUnknownDrawtype() +{ + infostream << "Got drawtype " << f->drawtype << std::endl; + FATAL_ERROR("Unknown drawtype"); +} + +void MapblockMeshGenerator::drawNode() +{ + // skip some drawtypes early + switch (f->drawtype) { + case NDT_NORMAL: // Drawn by MapBlockMesh + case NDT_AIRLIKE: // Not drawn at all + case NDT_LIQUID: // Drawn by MapBlockMesh + return; + default: + break; + } + origin = intToFloat(p, BS); + if (data->m_smooth_lighting) + getSmoothLightFrame(); + else + light = LightPair(getInteriorLight(n, 1, nodedef)); + switch (f->drawtype) { + case NDT_FLOWINGLIQUID: drawLiquidNode(); break; + case NDT_GLASSLIKE: drawGlasslikeNode(); break; + case NDT_GLASSLIKE_FRAMED: drawGlasslikeFramedNode(); break; + case NDT_ALLFACES: drawAllfacesNode(); break; + case NDT_TORCHLIKE: drawTorchlikeNode(); break; + case NDT_SIGNLIKE: drawSignlikeNode(); break; + case NDT_PLANTLIKE: drawPlantlikeNode(); break; + case NDT_PLANTLIKE_ROOTED: drawPlantlikeRootedNode(); break; + case NDT_FIRELIKE: drawFirelikeNode(); break; + case NDT_FENCELIKE: drawFencelikeNode(); break; + case NDT_RAILLIKE: drawRaillikeNode(); break; + case NDT_NODEBOX: drawNodeboxNode(); break; + case NDT_MESH: drawMeshNode(); break; + default: errorUnknownDrawtype(); break; + } +} + +/* + TODO: Fix alpha blending for special nodes + Currently only the last element rendered is blended correct +*/ +void MapblockMeshGenerator::generate() +{ + for (p.Z = 0; p.Z < MAP_BLOCKSIZE; p.Z++) + for (p.Y = 0; p.Y < MAP_BLOCKSIZE; p.Y++) + for (p.X = 0; p.X < MAP_BLOCKSIZE; p.X++) { + n = data->m_vmanip.getNodeNoEx(blockpos_nodes + p); + f = &nodedef->get(n); + drawNode(); + } +} + +void MapblockMeshGenerator::renderSingle(content_t node, u8 param2) +{ + p = {0, 0, 0}; + n = MapNode(node, 0xff, param2); + f = &nodedef->get(n); + drawNode(); +} diff --git a/src/client/content_mapblock.h b/src/client/content_mapblock.h new file mode 100644 index 0000000..b13748c --- /dev/null +++ b/src/client/content_mapblock.h @@ -0,0 +1,180 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "nodedef.h" +#include <IMeshManipulator.h> + +struct MeshMakeData; +struct MeshCollector; + +struct LightPair { + u8 lightDay; + u8 lightNight; + + LightPair() = default; + explicit LightPair(u16 value) : lightDay(value & 0xff), lightNight(value >> 8) {} + LightPair(u8 valueA, u8 valueB) : lightDay(valueA), lightNight(valueB) {} + LightPair(float valueA, float valueB) : + lightDay(core::clamp(core::round32(valueA), 0, 255)), + lightNight(core::clamp(core::round32(valueB), 0, 255)) {} + operator u16() const { return lightDay | lightNight << 8; } +}; + +struct LightInfo { + float light_day; + float light_night; + float light_boosted; + + LightPair getPair(float sunlight_boost = 0.0) const + { + return LightPair( + (1 - sunlight_boost) * light_day + + sunlight_boost * light_boosted, + light_night); + } +}; + +struct LightFrame { + f32 lightsDay[8]; + f32 lightsNight[8]; + bool sunlight[8]; +}; + +class MapblockMeshGenerator +{ +public: + MeshMakeData *data; + MeshCollector *collector; + + const NodeDefManager *nodedef; + scene::IMeshManipulator *meshmanip; + +// options + bool enable_mesh_cache; + +// current node + v3s16 blockpos_nodes; + v3s16 p; + v3f origin; + MapNode n; + const ContentFeatures *f; + LightPair light; + LightFrame frame; + video::SColor color; + TileSpec tile; + float scale; + +// lighting + void getSmoothLightFrame(); + LightInfo blendLight(const v3f &vertex_pos); + video::SColor blendLightColor(const v3f &vertex_pos); + video::SColor blendLightColor(const v3f &vertex_pos, const v3f &vertex_normal); + + void useTile(int index = 0, u8 set_flags = MATERIAL_FLAG_CRACK_OVERLAY, + u8 reset_flags = 0, bool special = false); + void getTile(int index, TileSpec *tile); + void getTile(v3s16 direction, TileSpec *tile); + void getSpecialTile(int index, TileSpec *tile, bool apply_crack = false); + +// face drawing + void drawQuad(v3f *vertices, const v3s16 &normal = v3s16(0, 0, 0), + float vertical_tiling = 1.0); + +// cuboid drawing! + void drawCuboid(const aabb3f &box, TileSpec *tiles, int tilecount, + const LightInfo *lights , const f32 *txc, u8 mask = 0); + void generateCuboidTextureCoords(aabb3f const &box, f32 *coords); + void drawAutoLightedCuboid(aabb3f box, const f32 *txc = NULL, + TileSpec *tiles = NULL, int tile_count = 0, u8 mask = 0); + u8 getNodeBoxMask(aabb3f box, u8 solid_neighbors, u8 sametype_neighbors) const; + +// liquid-specific + bool top_is_same_liquid; + bool draw_liquid_bottom; + TileSpec tile_liquid; + TileSpec tile_liquid_top; + content_t c_flowing; + content_t c_source; + video::SColor color_liquid_top; + struct NeighborData { + f32 level; + content_t content; + bool is_same_liquid; + bool top_is_same_liquid; + }; + NeighborData liquid_neighbors[3][3]; + f32 corner_levels[2][2]; + + void prepareLiquidNodeDrawing(); + void getLiquidNeighborhood(); + void calculateCornerLevels(); + f32 getCornerLevel(int i, int k); + void drawLiquidSides(); + void drawLiquidTop(); + void drawLiquidBottom(); + +// raillike-specific + // name of the group that enables connecting to raillike nodes of different kind + static const std::string raillike_groupname; + int raillike_group; + bool isSameRail(v3s16 dir); + +// plantlike-specific + PlantlikeStyle draw_style; + v3f offset; + float rotate_degree; + bool random_offset_Y; + int face_num; + float plant_height; + + void drawPlantlikeQuad(float rotation, float quad_offset = 0, + bool offset_top_only = false); + void drawPlantlike(bool is_rooted = false); + +// firelike-specific + void drawFirelikeQuad(float rotation, float opening_angle, + float offset_h, float offset_v = 0.0); + +// drawtypes + void drawLiquidNode(); + void drawGlasslikeNode(); + void drawGlasslikeFramedNode(); + void drawAllfacesNode(); + void drawTorchlikeNode(); + void drawSignlikeNode(); + void drawPlantlikeNode(); + void drawPlantlikeRootedNode(); + void drawFirelikeNode(); + void drawFencelikeNode(); + void drawRaillikeNode(); + void drawNodeboxNode(); + void drawMeshNode(); + +// common + void errorUnknownDrawtype(); + void drawNode(); + +public: + MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output, + scene::IMeshManipulator *mm); + void generate(); + void renderSingle(content_t node, u8 param2 = 0x00); +}; diff --git a/src/client/event_manager.h b/src/client/event_manager.h new file mode 100644 index 0000000..16f7bcf --- /dev/null +++ b/src/client/event_manager.h @@ -0,0 +1,86 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "mtevent.h" +#include <list> +#include <map> + +class EventManager : public MtEventManager +{ + static void receiverReceive(MtEvent *e, void *data) + { + MtEventReceiver *r = (MtEventReceiver *)data; + r->onEvent(e); + } + struct FuncSpec + { + event_receive_func f; + void *d; + FuncSpec(event_receive_func f, void *d) : f(f), d(d) {} + }; + + struct Dest + { + std::list<FuncSpec> funcs{}; + }; + std::map<MtEvent::Type, Dest> m_dest{}; + +public: + ~EventManager() override = default; + + void put(MtEvent *e) override + { + std::map<MtEvent::Type, Dest>::iterator i = m_dest.find(e->getType()); + if (i != m_dest.end()) { + std::list<FuncSpec> &funcs = i->second.funcs; + for (FuncSpec &func : funcs) { + (*(func.f))(e, func.d); + } + } + delete e; + } + void reg(MtEvent::Type type, event_receive_func f, void *data) override + { + std::map<MtEvent::Type, Dest>::iterator i = m_dest.find(type); + if (i != m_dest.end()) { + i->second.funcs.emplace_back(f, data); + } else { + Dest dest; + dest.funcs.emplace_back(f, data); + m_dest[type] = dest; + } + } + void dereg(MtEvent::Type type, event_receive_func f, void *data) override + { + std::map<MtEvent::Type, Dest>::iterator i = m_dest.find(type); + if (i != m_dest.end()) { + std::list<FuncSpec> &funcs = i->second.funcs; + auto j = funcs.begin(); + while (j != funcs.end()) { + bool remove = (j->f == f && (!data || j->d == data)); + if (remove) + funcs.erase(j++); + else + ++j; + } + } + } +}; diff --git a/src/client/filecache.cpp b/src/client/filecache.cpp new file mode 100644 index 0000000..46bbe40 --- /dev/null +++ b/src/client/filecache.cpp @@ -0,0 +1,97 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013 Jonathan Neuschäfer <j.neuschaefer@gmx.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "filecache.h" + +#include "network/networkprotocol.h" +#include "log.h" +#include "filesys.h" +#include <string> +#include <iostream> +#include <fstream> +#include <cstdlib> + +bool FileCache::loadByPath(const std::string &path, std::ostream &os) +{ + std::ifstream fis(path.c_str(), std::ios_base::binary); + + if(!fis.good()){ + verbosestream<<"FileCache: File not found in cache: " + <<path<<std::endl; + return false; + } + + bool bad = false; + for(;;){ + char buf[1024]; + fis.read(buf, 1024); + std::streamsize len = fis.gcount(); + os.write(buf, len); + if(fis.eof()) + break; + if(!fis.good()){ + bad = true; + break; + } + } + if(bad){ + errorstream<<"FileCache: Failed to read file from cache: \"" + <<path<<"\""<<std::endl; + } + + return !bad; +} + +bool FileCache::updateByPath(const std::string &path, const std::string &data) +{ + std::ofstream file(path.c_str(), std::ios_base::binary | + std::ios_base::trunc); + + if(!file.good()) + { + errorstream<<"FileCache: Can't write to file at " + <<path<<std::endl; + return false; + } + + file.write(data.c_str(), data.length()); + file.close(); + + return !file.fail(); +} + +bool FileCache::update(const std::string &name, const std::string &data) +{ + std::string path = m_dir + DIR_DELIM + name; + return updateByPath(path, data); +} + +bool FileCache::load(const std::string &name, std::ostream &os) +{ + std::string path = m_dir + DIR_DELIM + name; + return loadByPath(path, os); +} + +bool FileCache::exists(const std::string &name) +{ + std::string path = m_dir + DIR_DELIM + name; + std::ifstream fis(path.c_str(), std::ios_base::binary); + return fis.good(); +} diff --git a/src/client/filecache.h b/src/client/filecache.h new file mode 100644 index 0000000..ea6afc4 --- /dev/null +++ b/src/client/filecache.h @@ -0,0 +1,43 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013 Jonathan Neuschäfer <j.neuschaefer@gmx.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <iostream> +#include <string> + +class FileCache +{ +public: + /* + 'dir' is the file cache directory to use. + */ + FileCache(const std::string &dir) : m_dir(dir) {} + + bool update(const std::string &name, const std::string &data); + bool load(const std::string &name, std::ostream &os); + bool exists(const std::string &name); + +private: + std::string m_dir; + + bool loadByPath(const std::string &path, std::ostream &os); + bool updateByPath(const std::string &path, const std::string &data); +}; diff --git a/src/client/fontengine.cpp b/src/client/fontengine.cpp new file mode 100644 index 0000000..0ae50df --- /dev/null +++ b/src/client/fontengine.cpp @@ -0,0 +1,270 @@ +/* +Minetest +Copyright (C) 2010-2014 sapier <sapier at gmx dot net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "fontengine.h" +#include <cmath> +#include "client/renderingengine.h" +#include "config.h" +#include "porting.h" +#include "filesys.h" +#include "gettext.h" +#include "irrlicht_changes/CGUITTFont.h" +#include "util/numeric.h" // rangelim + +/** maximum size distance for getting a "similar" font size */ +#define MAX_FONT_SIZE_OFFSET 10 + +/** reference to access font engine, has to be initialized by main */ +FontEngine* g_fontengine = NULL; + +/** callback to be used on change of font size setting */ +static void font_setting_changed(const std::string &name, void *userdata) +{ + g_fontengine->readSettings(); +} + +/******************************************************************************/ +FontEngine::FontEngine(gui::IGUIEnvironment* env) : + m_env(env) +{ + for (u32 &i : m_default_size) { + i = FONT_SIZE_UNSPECIFIED; + } + + assert(g_settings != NULL); // pre-condition + assert(m_env != NULL); // pre-condition + assert(m_env->getSkin() != NULL); // pre-condition + + readSettings(); + + const char *settings[] = { + "font_size", "font_bold", "font_italic", "font_size_divisible_by", + "mono_font_size", "mono_font_size_divisible_by", + "font_shadow", "font_shadow_alpha", + "font_path", "font_path_bold", "font_path_italic", "font_path_bold_italic", + "mono_font_path", "mono_font_path_bold", "mono_font_path_italic", + "mono_font_path_bold_italic", + "fallback_font_path", + "screen_dpi", "gui_scaling", + }; + + for (auto name : settings) + g_settings->registerChangedCallback(name, font_setting_changed, NULL); +} + +/******************************************************************************/ +FontEngine::~FontEngine() +{ + cleanCache(); +} + +/******************************************************************************/ +void FontEngine::cleanCache() +{ + RecursiveMutexAutoLock l(m_font_mutex); + + for (auto &font_cache_it : m_font_cache) { + + for (auto &font_it : font_cache_it) { + font_it.second->drop(); + font_it.second = nullptr; + } + font_cache_it.clear(); + } +} + +/******************************************************************************/ +irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec) +{ + return getFont(spec, false); +} + +irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail) +{ + if (spec.mode == FM_Unspecified) { + spec.mode = m_currentMode; + } else if (spec.mode == _FM_Fallback) { + // Fallback font doesn't support these + spec.bold = false; + spec.italic = false; + } + + // Fallback to default size + if (spec.size == FONT_SIZE_UNSPECIFIED) + spec.size = m_default_size[spec.mode]; + + RecursiveMutexAutoLock l(m_font_mutex); + + const auto &cache = m_font_cache[spec.getHash()]; + auto it = cache.find(spec.size); + if (it != cache.end()) + return it->second; + + // Font does not yet exist + gui::IGUIFont *font = initFont(spec); + + if (!font && !may_fail) { + errorstream << "Minetest cannot continue without a valid font. " + "Please correct the 'font_path' setting or install the font " + "file in the proper location." << std::endl; + abort(); + } + + m_font_cache[spec.getHash()][spec.size] = font; + + return font; +} + +/******************************************************************************/ +unsigned int FontEngine::getTextHeight(const FontSpec &spec) +{ + gui::IGUIFont *font = getFont(spec); + + return font->getDimension(L"Some unimportant example String").Height; +} + +/******************************************************************************/ +unsigned int FontEngine::getTextWidth(const std::wstring &text, const FontSpec &spec) +{ + gui::IGUIFont *font = getFont(spec); + + return font->getDimension(text.c_str()).Width; +} + +/** get line height for a specific font (including empty room between lines) */ +unsigned int FontEngine::getLineHeight(const FontSpec &spec) +{ + gui::IGUIFont *font = getFont(spec); + + return font->getDimension(L"Some unimportant example String").Height + + font->getKerningHeight(); +} + +/******************************************************************************/ +unsigned int FontEngine::getDefaultFontSize() +{ + return m_default_size[m_currentMode]; +} + +unsigned int FontEngine::getFontSize(FontMode mode) +{ + if (mode == FM_Unspecified) + return m_default_size[FM_Standard]; + + return m_default_size[mode]; +} + +/******************************************************************************/ +void FontEngine::readSettings() +{ + m_default_size[FM_Standard] = rangelim(g_settings->getU16("font_size"), 5, 72); + m_default_size[_FM_Fallback] = m_default_size[FM_Standard]; + m_default_size[FM_Mono] = rangelim(g_settings->getU16("mono_font_size"), 5, 72); + + m_default_bold = g_settings->getBool("font_bold"); + m_default_italic = g_settings->getBool("font_italic"); + + cleanCache(); + updateFontCache(); + updateSkin(); +} + +/******************************************************************************/ +void FontEngine::updateSkin() +{ + gui::IGUIFont *font = getFont(); + assert(font); + + m_env->getSkin()->setFont(font); +} + +/******************************************************************************/ +void FontEngine::updateFontCache() +{ + /* the only font to be initialized is default one, + * all others are re-initialized on demand */ + getFont(FONT_SIZE_UNSPECIFIED, FM_Unspecified); +} + +/******************************************************************************/ +gui::IGUIFont *FontEngine::initFont(const FontSpec &spec) +{ + assert(spec.mode != FM_Unspecified); + assert(spec.size != FONT_SIZE_UNSPECIFIED); + + std::string setting_prefix = ""; + if (spec.mode == FM_Mono) + setting_prefix = "mono_"; + + std::string setting_suffix = ""; + if (spec.bold) + setting_suffix.append("_bold"); + if (spec.italic) + setting_suffix.append("_italic"); + + // Font size in pixels for FreeType + u32 size = rangelim(spec.size * RenderingEngine::getDisplayDensity() * + g_settings->getFloat("gui_scaling"), 1U, 500U); + + // Constrain the font size to a certain multiple, if necessary + u16 divisible_by = g_settings->getU16(setting_prefix + "font_size_divisible_by"); + if (divisible_by > 1) { + size = std::max<u32>( + std::round((double)size / divisible_by) * divisible_by, divisible_by); + } + + sanity_check(size != 0); + + u16 font_shadow = 0; + u16 font_shadow_alpha = 0; + g_settings->getU16NoEx(setting_prefix + "font_shadow", font_shadow); + g_settings->getU16NoEx(setting_prefix + "font_shadow_alpha", + font_shadow_alpha); + + std::string path_setting; + if (spec.mode == _FM_Fallback) + path_setting = "fallback_font_path"; + else + path_setting = setting_prefix + "font_path" + setting_suffix; + + std::string fallback_settings[] = { + g_settings->get(path_setting), + Settings::getLayer(SL_DEFAULTS)->get(path_setting) + }; + + for (const std::string &font_path : fallback_settings) { + gui::CGUITTFont *font = gui::CGUITTFont::createTTFont(m_env, + font_path.c_str(), size, true, true, font_shadow, + font_shadow_alpha); + + if (!font) { + errorstream << "FontEngine: Cannot load '" << font_path << + "'. Trying to fall back to another path." << std::endl; + continue; + } + + if (spec.mode != _FM_Fallback) { + FontSpec spec2(spec); + spec2.mode = _FM_Fallback; + font->setFallback(getFont(spec2, true)); + } + return font; + } + return nullptr; +} diff --git a/src/client/fontengine.h b/src/client/fontengine.h new file mode 100644 index 0000000..78608e5 --- /dev/null +++ b/src/client/fontengine.h @@ -0,0 +1,170 @@ +/* +Minetest +Copyright (C) 2010-2014 sapier <sapier at gmx dot net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <map> +#include "util/basic_macros.h" +#include "irrlichttypes.h" +#include <IGUIFont.h> +#include <IGUISkin.h> +#include <IGUIEnvironment.h> +#include "settings.h" +#include "threading/mutex_auto_lock.h" + +#define FONT_SIZE_UNSPECIFIED 0xFFFFFFFF + +enum FontMode : u8 { + FM_Standard = 0, + FM_Mono, + _FM_Fallback, // do not use directly + FM_MaxMode, + FM_Unspecified +}; + +struct FontSpec { + FontSpec(unsigned int font_size, FontMode mode, bool bold, bool italic) : + size(font_size), + mode(mode), + bold(bold), + italic(italic) {} + + u16 getHash() const + { + return (mode << 2) | (static_cast<u8>(bold) << 1) | static_cast<u8>(italic); + } + + unsigned int size; + FontMode mode; + bool bold; + bool italic; +}; + +class FontEngine +{ +public: + + FontEngine(gui::IGUIEnvironment* env); + + ~FontEngine(); + + // Get best possible font specified by FontSpec + irr::gui::IGUIFont *getFont(FontSpec spec); + + irr::gui::IGUIFont *getFont(unsigned int font_size=FONT_SIZE_UNSPECIFIED, + FontMode mode=FM_Unspecified) + { + FontSpec spec(font_size, mode, m_default_bold, m_default_italic); + return getFont(spec); + } + + /** get text height for a specific font */ + unsigned int getTextHeight(const FontSpec &spec); + + /** get text width if a text for a specific font */ + unsigned int getTextHeight( + unsigned int font_size=FONT_SIZE_UNSPECIFIED, + FontMode mode=FM_Unspecified) + { + FontSpec spec(font_size, mode, m_default_bold, m_default_italic); + return getTextHeight(spec); + } + + unsigned int getTextWidth(const std::wstring &text, const FontSpec &spec); + + /** get text width if a text for a specific font */ + unsigned int getTextWidth(const std::wstring& text, + unsigned int font_size=FONT_SIZE_UNSPECIFIED, + FontMode mode=FM_Unspecified) + { + FontSpec spec(font_size, mode, m_default_bold, m_default_italic); + return getTextWidth(text, spec); + } + + unsigned int getTextWidth(const std::string &text, const FontSpec &spec) + { + return getTextWidth(utf8_to_wide(text), spec); + } + + unsigned int getTextWidth(const std::string& text, + unsigned int font_size=FONT_SIZE_UNSPECIFIED, + FontMode mode=FM_Unspecified) + { + FontSpec spec(font_size, mode, m_default_bold, m_default_italic); + return getTextWidth(utf8_to_wide(text), spec); + } + + /** get line height for a specific font (including empty room between lines) */ + unsigned int getLineHeight(const FontSpec &spec); + + unsigned int getLineHeight(unsigned int font_size=FONT_SIZE_UNSPECIFIED, + FontMode mode=FM_Unspecified) + { + FontSpec spec(font_size, mode, m_default_bold, m_default_italic); + return getLineHeight(spec); + } + + /** get default font size */ + unsigned int getDefaultFontSize(); + + /** get font size for a specific mode */ + unsigned int getFontSize(FontMode mode); + + /** update internal parameters from settings */ + void readSettings(); + +private: + irr::gui::IGUIFont *getFont(FontSpec spec, bool may_fail); + + /** update content of font cache in case of a setting change made it invalid */ + void updateFontCache(); + + /** initialize a new TTF font */ + gui::IGUIFont *initFont(const FontSpec &spec); + + /** update current minetest skin with font changes */ + void updateSkin(); + + /** clean cache */ + void cleanCache(); + + /** pointer to irrlicht gui environment */ + gui::IGUIEnvironment* m_env = nullptr; + + /** mutex used to protect font init and cache */ + std::recursive_mutex m_font_mutex; + + /** internal storage for caching fonts of different size */ + std::map<unsigned int, irr::gui::IGUIFont*> m_font_cache[FM_MaxMode << 2]; + + /** default font size to use */ + unsigned int m_default_size[FM_MaxMode]; + + /** default bold and italic */ + bool m_default_bold = false; + bool m_default_italic = false; + + /** default font engine mode (fixed) */ + static const FontMode m_currentMode = FM_Standard; + + DISABLE_CLASS_COPY(FontEngine); +}; + +/** interface to access main font engine*/ +extern FontEngine* g_fontengine; diff --git a/src/client/game.cpp b/src/client/game.cpp new file mode 100644 index 0000000..c34e3a4 --- /dev/null +++ b/src/client/game.cpp @@ -0,0 +1,4376 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "game.h" + +#include <iomanip> +#include <cmath> +#include "client/renderingengine.h" +#include "camera.h" +#include "client.h" +#include "client/clientevent.h" +#include "client/gameui.h" +#include "client/inputhandler.h" +#include "client/tile.h" // For TextureSource +#include "client/keys.h" +#include "client/joystick_controller.h" +#include "clientmap.h" +#include "clouds.h" +#include "config.h" +#include "content_cao.h" +#include "content/subgames.h" +#include "client/event_manager.h" +#include "fontengine.h" +#include "itemdef.h" +#include "log.h" +#include "filesys.h" +#include "gameparams.h" +#include "gettext.h" +#include "gui/guiChatConsole.h" +#include "gui/guiFormSpecMenu.h" +#include "gui/guiKeyChangeMenu.h" +#include "gui/guiPasswordChange.h" +#include "gui/guiVolumeChange.h" +#include "gui/mainmenumanager.h" +#include "gui/profilergraph.h" +#include "mapblock.h" +#include "minimap.h" +#include "nodedef.h" // Needed for determining pointing to nodes +#include "nodemetadata.h" +#include "particles.h" +#include "porting.h" +#include "profiler.h" +#include "raycast.h" +#include "server.h" +#include "settings.h" +#include "shader.h" +#include "sky.h" +#include "translation.h" +#include "util/basic_macros.h" +#include "util/directiontables.h" +#include "util/pointedthing.h" +#include "util/quicktune_shortcutter.h" +#include "irrlicht_changes/static_text.h" +#include "irr_ptr.h" +#include "version.h" +#include "script/scripting_client.h" +#include "hud.h" + +#if USE_SOUND + #include "client/sound_openal.h" +#else + #include "client/sound.h" +#endif +/* + Text input system +*/ + +struct TextDestNodeMetadata : public TextDest +{ + TextDestNodeMetadata(v3s16 p, Client *client) + { + m_p = p; + m_client = client; + } + // This is deprecated I guess? -celeron55 + void gotText(const std::wstring &text) + { + std::string ntext = wide_to_utf8(text); + infostream << "Submitting 'text' field of node at (" << m_p.X << "," + << m_p.Y << "," << m_p.Z << "): " << ntext << std::endl; + StringMap fields; + fields["text"] = ntext; + m_client->sendNodemetaFields(m_p, "", fields); + } + void gotText(const StringMap &fields) + { + m_client->sendNodemetaFields(m_p, "", fields); + } + + v3s16 m_p; + Client *m_client; +}; + +struct TextDestPlayerInventory : public TextDest +{ + TextDestPlayerInventory(Client *client) + { + m_client = client; + m_formname = ""; + } + TextDestPlayerInventory(Client *client, const std::string &formname) + { + m_client = client; + m_formname = formname; + } + void gotText(const StringMap &fields) + { + m_client->sendInventoryFields(m_formname, fields); + } + + Client *m_client; +}; + +struct LocalFormspecHandler : public TextDest +{ + LocalFormspecHandler(const std::string &formname) + { + m_formname = formname; + } + + LocalFormspecHandler(const std::string &formname, Client *client): + m_client(client) + { + m_formname = formname; + } + + void gotText(const StringMap &fields) + { + if (m_formname == "MT_PAUSE_MENU") { + if (fields.find("btn_sound") != fields.end()) { + g_gamecallback->changeVolume(); + return; + } + + if (fields.find("btn_key_config") != fields.end()) { + g_gamecallback->keyConfig(); + return; + } + + if (fields.find("btn_exit_menu") != fields.end()) { + g_gamecallback->disconnect(); + return; + } + + if (fields.find("btn_exit_os") != fields.end()) { + g_gamecallback->exitToOS(); +#ifndef __ANDROID__ + RenderingEngine::get_raw_device()->closeDevice(); +#endif + return; + } + + if (fields.find("btn_change_password") != fields.end()) { + g_gamecallback->changePassword(); + return; + } + + return; + } + + if (m_formname == "MT_DEATH_SCREEN") { + assert(m_client != 0); + m_client->sendRespawn(); + return; + } + + if (m_client->modsLoaded()) + m_client->getScript()->on_formspec_input(m_formname, fields); + } + + Client *m_client = nullptr; +}; + +/* Form update callback */ + +class NodeMetadataFormSource: public IFormSource +{ +public: + NodeMetadataFormSource(ClientMap *map, v3s16 p): + m_map(map), + m_p(p) + { + } + const std::string &getForm() const + { + static const std::string empty_string = ""; + NodeMetadata *meta = m_map->getNodeMetadata(m_p); + + if (!meta) + return empty_string; + + return meta->getString("formspec"); + } + + virtual std::string resolveText(const std::string &str) + { + NodeMetadata *meta = m_map->getNodeMetadata(m_p); + + if (!meta) + return str; + + return meta->resolveString(str); + } + + ClientMap *m_map; + v3s16 m_p; +}; + +class PlayerInventoryFormSource: public IFormSource +{ +public: + PlayerInventoryFormSource(Client *client): + m_client(client) + { + } + + const std::string &getForm() const + { + LocalPlayer *player = m_client->getEnv().getLocalPlayer(); + return player->inventory_formspec; + } + + Client *m_client; +}; + +class NodeDugEvent: public MtEvent +{ +public: + v3s16 p; + MapNode n; + + NodeDugEvent(v3s16 p, MapNode n): + p(p), + n(n) + {} + MtEvent::Type getType() const + { + return MtEvent::NODE_DUG; + } +}; + +class SoundMaker +{ + ISoundManager *m_sound; + const NodeDefManager *m_ndef; +public: + bool makes_footstep_sound; + float m_player_step_timer; + float m_player_jump_timer; + + SimpleSoundSpec m_player_step_sound; + SimpleSoundSpec m_player_leftpunch_sound; + SimpleSoundSpec m_player_rightpunch_sound; + + SoundMaker(ISoundManager *sound, const NodeDefManager *ndef): + m_sound(sound), + m_ndef(ndef), + makes_footstep_sound(true), + m_player_step_timer(0.0f), + m_player_jump_timer(0.0f) + { + } + + void playPlayerStep() + { + if (m_player_step_timer <= 0 && m_player_step_sound.exists()) { + m_player_step_timer = 0.03; + if (makes_footstep_sound) + m_sound->playSound(m_player_step_sound); + } + } + + void playPlayerJump() + { + if (m_player_jump_timer <= 0.0f) { + m_player_jump_timer = 0.2f; + m_sound->playSound(SimpleSoundSpec("player_jump", 0.5f)); + } + } + + static void viewBobbingStep(MtEvent *e, void *data) + { + SoundMaker *sm = (SoundMaker *)data; + sm->playPlayerStep(); + } + + static void playerRegainGround(MtEvent *e, void *data) + { + SoundMaker *sm = (SoundMaker *)data; + sm->playPlayerStep(); + } + + static void playerJump(MtEvent *e, void *data) + { + SoundMaker *sm = (SoundMaker *)data; + sm->playPlayerJump(); + } + + static void cameraPunchLeft(MtEvent *e, void *data) + { + SoundMaker *sm = (SoundMaker *)data; + sm->m_sound->playSound(sm->m_player_leftpunch_sound); + } + + static void cameraPunchRight(MtEvent *e, void *data) + { + SoundMaker *sm = (SoundMaker *)data; + sm->m_sound->playSound(sm->m_player_rightpunch_sound); + } + + static void nodeDug(MtEvent *e, void *data) + { + SoundMaker *sm = (SoundMaker *)data; + NodeDugEvent *nde = (NodeDugEvent *)e; + sm->m_sound->playSound(sm->m_ndef->get(nde->n).sound_dug); + } + + static void playerDamage(MtEvent *e, void *data) + { + SoundMaker *sm = (SoundMaker *)data; + sm->m_sound->playSound(SimpleSoundSpec("player_damage", 0.5)); + } + + static void playerFallingDamage(MtEvent *e, void *data) + { + SoundMaker *sm = (SoundMaker *)data; + sm->m_sound->playSound(SimpleSoundSpec("player_falling_damage", 0.5)); + } + + void registerReceiver(MtEventManager *mgr) + { + mgr->reg(MtEvent::VIEW_BOBBING_STEP, SoundMaker::viewBobbingStep, this); + mgr->reg(MtEvent::PLAYER_REGAIN_GROUND, SoundMaker::playerRegainGround, this); + mgr->reg(MtEvent::PLAYER_JUMP, SoundMaker::playerJump, this); + mgr->reg(MtEvent::CAMERA_PUNCH_LEFT, SoundMaker::cameraPunchLeft, this); + mgr->reg(MtEvent::CAMERA_PUNCH_RIGHT, SoundMaker::cameraPunchRight, this); + mgr->reg(MtEvent::NODE_DUG, SoundMaker::nodeDug, this); + mgr->reg(MtEvent::PLAYER_DAMAGE, SoundMaker::playerDamage, this); + mgr->reg(MtEvent::PLAYER_FALLING_DAMAGE, SoundMaker::playerFallingDamage, this); + } + + void step(float dtime) + { + m_player_step_timer -= dtime; + m_player_jump_timer -= dtime; + } +}; + +// Locally stored sounds don't need to be preloaded because of this +class GameOnDemandSoundFetcher: public OnDemandSoundFetcher +{ + std::set<std::string> m_fetched; +private: + void paths_insert(std::set<std::string> &dst_paths, + const std::string &base, + const std::string &name) + { + dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".ogg"); + dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".0.ogg"); + dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".1.ogg"); + dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".2.ogg"); + dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".3.ogg"); + dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".4.ogg"); + dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".5.ogg"); + dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".6.ogg"); + dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".7.ogg"); + dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".8.ogg"); + dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".9.ogg"); + } +public: + void fetchSounds(const std::string &name, + std::set<std::string> &dst_paths, + std::set<std::string> &dst_datas) + { + if (m_fetched.count(name)) + return; + + m_fetched.insert(name); + + paths_insert(dst_paths, porting::path_share, name); + paths_insert(dst_paths, porting::path_user, name); + } +}; + + +typedef s32 SamplerLayer_t; + + +class GameGlobalShaderConstantSetter : public IShaderConstantSetter +{ + Sky *m_sky; + bool *m_force_fog_off; + f32 *m_fog_range; + bool m_fog_enabled; + CachedPixelShaderSetting<float, 4> m_sky_bg_color; + CachedPixelShaderSetting<float> m_fog_distance; + CachedVertexShaderSetting<float> m_animation_timer_vertex; + CachedPixelShaderSetting<float> m_animation_timer_pixel; + CachedPixelShaderSetting<float, 3> m_day_light; + CachedPixelShaderSetting<float, 4> m_star_color; + CachedPixelShaderSetting<float, 3> m_eye_position_pixel; + CachedVertexShaderSetting<float, 3> m_eye_position_vertex; + CachedPixelShaderSetting<float, 3> m_minimap_yaw; + CachedPixelShaderSetting<float, 3> m_camera_offset_pixel; + CachedPixelShaderSetting<float, 3> m_camera_offset_vertex; + CachedPixelShaderSetting<SamplerLayer_t> m_base_texture; + CachedPixelShaderSetting<SamplerLayer_t> m_normal_texture; + CachedPixelShaderSetting<SamplerLayer_t> m_texture_flags; + Client *m_client; + +public: + void onSettingsChange(const std::string &name) + { + if (name == "enable_fog") + m_fog_enabled = g_settings->getBool("enable_fog"); + } + + static void settingsCallback(const std::string &name, void *userdata) + { + reinterpret_cast<GameGlobalShaderConstantSetter*>(userdata)->onSettingsChange(name); + } + + void setSky(Sky *sky) { m_sky = sky; } + + GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off, + f32 *fog_range, Client *client) : + m_sky(sky), + m_force_fog_off(force_fog_off), + m_fog_range(fog_range), + m_sky_bg_color("skyBgColor"), + m_fog_distance("fogDistance"), + m_animation_timer_vertex("animationTimer"), + m_animation_timer_pixel("animationTimer"), + m_day_light("dayLight"), + m_star_color("starColor"), + m_eye_position_pixel("eyePosition"), + m_eye_position_vertex("eyePosition"), + m_minimap_yaw("yawVec"), + m_camera_offset_pixel("cameraOffset"), + m_camera_offset_vertex("cameraOffset"), + m_base_texture("baseTexture"), + m_normal_texture("normalTexture"), + m_texture_flags("textureFlags"), + m_client(client) + { + g_settings->registerChangedCallback("enable_fog", settingsCallback, this); + m_fog_enabled = g_settings->getBool("enable_fog"); + } + + ~GameGlobalShaderConstantSetter() + { + g_settings->deregisterChangedCallback("enable_fog", settingsCallback, this); + } + + void onSetConstants(video::IMaterialRendererServices *services) override + { + // Background color + video::SColor bgcolor = m_sky->getBgColor(); + video::SColorf bgcolorf(bgcolor); + float bgcolorfa[4] = { + bgcolorf.r, + bgcolorf.g, + bgcolorf.b, + bgcolorf.a, + }; + m_sky_bg_color.set(bgcolorfa, services); + + // Fog distance + float fog_distance = 10000 * BS; + + if (m_fog_enabled && !*m_force_fog_off) + fog_distance = *m_fog_range; + + m_fog_distance.set(&fog_distance, services); + + u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio(); + video::SColorf sunlight; + get_sunlight_color(&sunlight, daynight_ratio); + float dnc[3] = { + sunlight.r, + sunlight.g, + sunlight.b }; + m_day_light.set(dnc, services); + + video::SColorf star_color = m_sky->getCurrentStarColor(); + float clr[4] = {star_color.r, star_color.g, star_color.b, star_color.a}; + m_star_color.set(clr, services); + + u32 animation_timer = porting::getTimeMs() % 1000000; + float animation_timer_f = (float)animation_timer / 100000.f; + m_animation_timer_vertex.set(&animation_timer_f, services); + m_animation_timer_pixel.set(&animation_timer_f, services); + + float eye_position_array[3]; + v3f epos = m_client->getEnv().getLocalPlayer()->getEyePosition(); + epos.getAs3Values(eye_position_array); + m_eye_position_pixel.set(eye_position_array, services); + m_eye_position_vertex.set(eye_position_array, services); + + if (m_client->getMinimap()) { + float minimap_yaw_array[3]; + v3f minimap_yaw = m_client->getMinimap()->getYawVec(); + minimap_yaw.getAs3Values(minimap_yaw_array); + m_minimap_yaw.set(minimap_yaw_array, services); + } + + float camera_offset_array[3]; + v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS); + offset.getAs3Values(camera_offset_array); + m_camera_offset_pixel.set(camera_offset_array, services); + m_camera_offset_vertex.set(camera_offset_array, services); + + SamplerLayer_t base_tex = 0, + normal_tex = 1, + flags_tex = 2; + m_base_texture.set(&base_tex, services); + m_normal_texture.set(&normal_tex, services); + m_texture_flags.set(&flags_tex, services); + } +}; + + +class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactory +{ + Sky *m_sky; + bool *m_force_fog_off; + f32 *m_fog_range; + Client *m_client; + std::vector<GameGlobalShaderConstantSetter *> created_nosky; +public: + GameGlobalShaderConstantSetterFactory(bool *force_fog_off, + f32 *fog_range, Client *client) : + m_sky(NULL), + m_force_fog_off(force_fog_off), + m_fog_range(fog_range), + m_client(client) + {} + + void setSky(Sky *sky) { + m_sky = sky; + for (GameGlobalShaderConstantSetter *ggscs : created_nosky) { + ggscs->setSky(m_sky); + } + created_nosky.clear(); + } + + virtual IShaderConstantSetter* create() + { + auto *scs = new GameGlobalShaderConstantSetter( + m_sky, m_force_fog_off, m_fog_range, m_client); + if (!m_sky) + created_nosky.push_back(scs); + return scs; + } +}; + +#ifdef HAVE_TOUCHSCREENGUI +#define SIZE_TAG "size[11,5.5]" +#else +#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop +#endif + +/**************************************************************************** + ****************************************************************************/ + +const static float object_hit_delay = 0.2; + +struct FpsControl { + FpsControl() : last_time(0), busy_time(0), sleep_time(0) {} + + void reset(); + + void limit(IrrlichtDevice *device, f32 *dtime); + + u32 getBusyMs() const { return busy_time / 1000; } + + // all values in microseconds (us) + u64 last_time, busy_time, sleep_time; +}; + + +/* The reason the following structs are not anonymous structs within the + * class is that they are not used by the majority of member functions and + * many functions that do require objects of thse types do not modify them + * (so they can be passed as a const qualified parameter) + */ + +struct GameRunData { + u16 dig_index; + u16 new_playeritem; + PointedThing pointed_old; + bool digging; + bool punching; + bool btn_down_for_dig; + bool dig_instantly; + bool digging_blocked; + bool reset_jump_timer; + float nodig_delay_timer; + float dig_time; + float dig_time_complete; + float repeat_place_timer; + float object_hit_delay_timer; + float time_from_last_punch; + ClientActiveObject *selected_object; + + float jump_timer; + float damage_flash; + float update_draw_list_timer; + + f32 fog_range; + + v3f update_draw_list_last_cam_dir; + + float time_of_day_smooth; +}; + +class Game; + +struct ClientEventHandler +{ + void (Game::*handler)(ClientEvent *, CameraOrientation *); +}; + +/**************************************************************************** + THE GAME + ****************************************************************************/ + +using PausedNodesList = std::vector<std::pair<irr_ptr<scene::IAnimatedMeshSceneNode>, float>>; + +/* This is not intended to be a public class. If a public class becomes + * desirable then it may be better to create another 'wrapper' class that + * hides most of the stuff in this class (nothing in this class is required + * by any other file) but exposes the public methods/data only. + */ +class Game { +public: + Game(); + ~Game(); + + bool startup(bool *kill, + InputHandler *input, + RenderingEngine *rendering_engine, + const GameStartData &game_params, + std::string &error_message, + bool *reconnect, + ChatBackend *chat_backend); + + void run(); + void shutdown(); + +protected: + + // Basic initialisation + bool init(const std::string &map_dir, const std::string &address, + u16 port, const SubgameSpec &gamespec); + bool initSound(); + bool createSingleplayerServer(const std::string &map_dir, + const SubgameSpec &gamespec, u16 port); + + // Client creation + bool createClient(const GameStartData &start_data); + bool initGui(); + + // Client connection + bool connectToServer(const GameStartData &start_data, + bool *connect_ok, bool *aborted); + bool getServerContent(bool *aborted); + + // Main loop + + void updateInteractTimers(f32 dtime); + bool checkConnection(); + bool handleCallbacks(); + void processQueues(); + void updateProfilers(const RunStats &stats, const FpsControl &draw_times, f32 dtime); + void updateDebugState(); + void updateStats(RunStats *stats, const FpsControl &draw_times, f32 dtime); + void updateProfilerGraphs(ProfilerGraph *graph); + + // Input related + void processUserInput(f32 dtime); + void processKeyInput(); + void processItemSelection(u16 *new_playeritem); + + void dropSelectedItem(bool single_item = false); + void openInventory(); + void openConsole(float scale, const wchar_t *line=NULL); + void toggleFreeMove(); + void toggleFreeMoveAlt(); + void togglePitchMove(); + void toggleFast(); + void toggleNoClip(); + void toggleCinematic(); + void toggleBlockBounds(); + void toggleAutoforward(); + + void toggleMinimap(bool shift_pressed); + void toggleFog(); + void toggleDebug(); + void toggleUpdateCamera(); + + void increaseViewRange(); + void decreaseViewRange(); + void toggleFullViewRange(); + void checkZoomEnabled(); + + void updateCameraDirection(CameraOrientation *cam, float dtime); + void updateCameraOrientation(CameraOrientation *cam, float dtime); + void updatePlayerControl(const CameraOrientation &cam); + void step(f32 *dtime); + void processClientEvents(CameraOrientation *cam); + void updateCamera(f32 dtime); + void updateSound(f32 dtime); + void processPlayerInteraction(f32 dtime, bool show_hud); + /*! + * Returns the object or node the player is pointing at. + * Also updates the selected thing in the Hud. + * + * @param[in] shootline the shootline, starting from + * the camera position. This also gives the maximal distance + * of the search. + * @param[in] liquids_pointable if false, liquids are ignored + * @param[in] look_for_object if false, objects are ignored + * @param[in] camera_offset offset of the camera + * @param[out] selected_object the selected object or + * NULL if not found + */ + PointedThing updatePointedThing( + const core::line3d<f32> &shootline, bool liquids_pointable, + bool look_for_object, const v3s16 &camera_offset); + void handlePointingAtNothing(const ItemStack &playerItem); + void handlePointingAtNode(const PointedThing &pointed, + const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime); + void handlePointingAtObject(const PointedThing &pointed, const ItemStack &playeritem, + const v3f &player_position, bool show_debug); + void handleDigging(const PointedThing &pointed, const v3s16 &nodepos, + const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime); + void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime, + const CameraOrientation &cam); + void updateShadows(); + + // Misc + void showOverlayMessage(const char *msg, float dtime, int percent, + bool draw_clouds = true); + + static void settingChangedCallback(const std::string &setting_name, void *data); + void readSettings(); + + inline bool isKeyDown(GameKeyType k) + { + return input->isKeyDown(k); + } + inline bool wasKeyDown(GameKeyType k) + { + return input->wasKeyDown(k); + } + inline bool wasKeyPressed(GameKeyType k) + { + return input->wasKeyPressed(k); + } + inline bool wasKeyReleased(GameKeyType k) + { + return input->wasKeyReleased(k); + } + +#ifdef __ANDROID__ + void handleAndroidChatInput(); +#endif + +private: + struct Flags { + bool force_fog_off = false; + bool disable_camera_update = false; + }; + + void showDeathFormspec(); + void showPauseMenu(); + + void pauseAnimation(); + void resumeAnimation(); + + // ClientEvent handlers + void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_HandleParticleEvent(ClientEvent *event, + CameraOrientation *cam); + void handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_SetSun(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_SetMoon(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_SetStars(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_OverrideDayNigthRatio(ClientEvent *event, + CameraOrientation *cam); + void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam); + + void updateChat(f32 dtime); + + bool nodePlacement(const ItemDefinition &selected_def, const ItemStack &selected_item, + const v3s16 &nodepos, const v3s16 &neighbourpos, const PointedThing &pointed, + const NodeMetadata *meta); + static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX]; + + f32 getSensitivityScaleFactor() const; + + InputHandler *input = nullptr; + + Client *client = nullptr; + Server *server = nullptr; + + IWritableTextureSource *texture_src = nullptr; + IWritableShaderSource *shader_src = nullptr; + + // When created, these will be filled with data received from the server + IWritableItemDefManager *itemdef_manager = nullptr; + NodeDefManager *nodedef_manager = nullptr; + + GameOnDemandSoundFetcher soundfetcher; // useful when testing + ISoundManager *sound = nullptr; + bool sound_is_dummy = false; + SoundMaker *soundmaker = nullptr; + + ChatBackend *chat_backend = nullptr; + LogOutputBuffer m_chat_log_buf; + + EventManager *eventmgr = nullptr; + QuicktuneShortcutter *quicktune = nullptr; + + std::unique_ptr<GameUI> m_game_ui; + GUIChatConsole *gui_chat_console = nullptr; // Free using ->Drop() + MapDrawControl *draw_control = nullptr; + Camera *camera = nullptr; + Clouds *clouds = nullptr; // Free using ->Drop() + Sky *sky = nullptr; // Free using ->Drop() + Hud *hud = nullptr; + Minimap *mapper = nullptr; + + // Map server hud ids to client hud ids + std::unordered_map<u32, u32> m_hud_server_to_client; + + GameRunData runData; + Flags m_flags; + + /* 'cache' + This class does take ownership/responsibily for cleaning up etc of any of + these items (e.g. device) + */ + IrrlichtDevice *device; + RenderingEngine *m_rendering_engine; + video::IVideoDriver *driver; + scene::ISceneManager *smgr; + bool *kill; + std::string *error_message; + bool *reconnect_requested; + scene::ISceneNode *skybox; + PausedNodesList paused_animated_nodes; + + bool simple_singleplayer_mode; + /* End 'cache' */ + + /* Pre-calculated values + */ + int crack_animation_length; + + IntervalLimiter profiler_interval; + + /* + * TODO: Local caching of settings is not optimal and should at some stage + * be updated to use a global settings object for getting thse values + * (as opposed to the this local caching). This can be addressed in + * a later release. + */ + bool m_cache_doubletap_jump; + bool m_cache_enable_clouds; + bool m_cache_enable_joysticks; + bool m_cache_enable_particles; + bool m_cache_enable_fog; + bool m_cache_enable_noclip; + bool m_cache_enable_free_move; + f32 m_cache_mouse_sensitivity; + f32 m_cache_joystick_frustum_sensitivity; + f32 m_repeat_place_time; + f32 m_cache_cam_smoothing; + f32 m_cache_fog_start; + + bool m_invert_mouse = false; + bool m_first_loop_after_window_activation = false; + bool m_camera_offset_changed = false; + + bool m_does_lost_focus_pause_game = false; + +#if IRRLICHT_VERSION_MT_REVISION < 5 + int m_reset_HW_buffer_counter = 0; +#endif + +#ifdef HAVE_TOUCHSCREENGUI + bool m_cache_hold_aux1; +#endif +#ifdef __ANDROID__ + bool m_android_chat_open; +#endif +}; + +Game::Game() : + m_chat_log_buf(g_logger), + m_game_ui(new GameUI()) +{ + g_settings->registerChangedCallback("doubletap_jump", + &settingChangedCallback, this); + g_settings->registerChangedCallback("enable_clouds", + &settingChangedCallback, this); + g_settings->registerChangedCallback("doubletap_joysticks", + &settingChangedCallback, this); + g_settings->registerChangedCallback("enable_particles", + &settingChangedCallback, this); + g_settings->registerChangedCallback("enable_fog", + &settingChangedCallback, this); + g_settings->registerChangedCallback("mouse_sensitivity", + &settingChangedCallback, this); + g_settings->registerChangedCallback("joystick_frustum_sensitivity", + &settingChangedCallback, this); + g_settings->registerChangedCallback("repeat_place_time", + &settingChangedCallback, this); + g_settings->registerChangedCallback("noclip", + &settingChangedCallback, this); + g_settings->registerChangedCallback("free_move", + &settingChangedCallback, this); + g_settings->registerChangedCallback("cinematic", + &settingChangedCallback, this); + g_settings->registerChangedCallback("cinematic_camera_smoothing", + &settingChangedCallback, this); + g_settings->registerChangedCallback("camera_smoothing", + &settingChangedCallback, this); + + readSettings(); + +#ifdef HAVE_TOUCHSCREENGUI + m_cache_hold_aux1 = false; // This is initialised properly later +#endif + +} + + + +/**************************************************************************** + MinetestApp Public + ****************************************************************************/ + +Game::~Game() +{ + delete client; + delete soundmaker; + if (!sound_is_dummy) + delete sound; + + delete server; // deleted first to stop all server threads + + delete hud; + delete camera; + delete quicktune; + delete eventmgr; + delete texture_src; + delete shader_src; + delete nodedef_manager; + delete itemdef_manager; + delete draw_control; + + clearTextureNameCache(); + + g_settings->deregisterChangedCallback("doubletap_jump", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("enable_clouds", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("enable_particles", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("enable_fog", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("mouse_sensitivity", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("repeat_place_time", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("noclip", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("free_move", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("cinematic", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("cinematic_camera_smoothing", + &settingChangedCallback, this); + g_settings->deregisterChangedCallback("camera_smoothing", + &settingChangedCallback, this); +} + +bool Game::startup(bool *kill, + InputHandler *input, + RenderingEngine *rendering_engine, + const GameStartData &start_data, + std::string &error_message, + bool *reconnect, + ChatBackend *chat_backend) +{ + + // "cache" + m_rendering_engine = rendering_engine; + device = m_rendering_engine->get_raw_device(); + this->kill = kill; + this->error_message = &error_message; + reconnect_requested = reconnect; + this->input = input; + this->chat_backend = chat_backend; + simple_singleplayer_mode = start_data.isSinglePlayer(); + + input->keycache.populate(); + + driver = device->getVideoDriver(); + smgr = m_rendering_engine->get_scene_manager(); + + smgr->getParameters()->setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true); + + // Reinit runData + runData = GameRunData(); + runData.time_from_last_punch = 10.0; + + m_game_ui->initFlags(); + + m_invert_mouse = g_settings->getBool("invert_mouse"); + m_first_loop_after_window_activation = true; + + g_client_translations->clear(); + + // address can change if simple_singleplayer_mode + if (!init(start_data.world_spec.path, start_data.address, + start_data.socket_port, start_data.game_spec)) + return false; + + if (!createClient(start_data)) + return false; + + m_rendering_engine->initialize(client, hud); + + return true; +} + + +void Game::run() +{ + ProfilerGraph graph; + RunStats stats = {}; + CameraOrientation cam_view_target = {}; + CameraOrientation cam_view = {}; + FpsControl draw_times; + f32 dtime; // in seconds + + /* Clear the profiler */ + Profiler::GraphValues dummyvalues; + g_profiler->graphGet(dummyvalues); + + draw_times.reset(); + + set_light_table(g_settings->getFloat("display_gamma")); + +#ifdef HAVE_TOUCHSCREENGUI + m_cache_hold_aux1 = g_settings->getBool("fast_move") + && client->checkPrivilege("fast"); +#endif + + irr::core::dimension2d<u32> previous_screen_size(g_settings->getU16("screen_w"), + g_settings->getU16("screen_h")); + + while (m_rendering_engine->run() + && !(*kill || g_gamecallback->shutdown_requested + || (server && server->isShutdownRequested()))) { + + const irr::core::dimension2d<u32> ¤t_screen_size = + m_rendering_engine->get_video_driver()->getScreenSize(); + // Verify if window size has changed and save it if it's the case + // Ensure evaluating settings->getBool after verifying screensize + // First condition is cheaper + if (previous_screen_size != current_screen_size && + current_screen_size != irr::core::dimension2d<u32>(0,0) && + g_settings->getBool("autosave_screensize")) { + g_settings->setU16("screen_w", current_screen_size.Width); + g_settings->setU16("screen_h", current_screen_size.Height); + previous_screen_size = current_screen_size; + } + + // Calculate dtime = + // m_rendering_engine->run() from this iteration + // + Sleep time until the wanted FPS are reached + draw_times.limit(device, &dtime); + + // Prepare render data for next iteration + + updateStats(&stats, draw_times, dtime); + updateInteractTimers(dtime); + + if (!checkConnection()) + break; + if (!handleCallbacks()) + break; + + processQueues(); + + m_game_ui->clearInfoText(); + hud->resizeHotbar(); + + + updateProfilers(stats, draw_times, dtime); + processUserInput(dtime); + // Update camera before player movement to avoid camera lag of one frame + updateCameraDirection(&cam_view_target, dtime); + cam_view.camera_yaw += (cam_view_target.camera_yaw - + cam_view.camera_yaw) * m_cache_cam_smoothing; + cam_view.camera_pitch += (cam_view_target.camera_pitch - + cam_view.camera_pitch) * m_cache_cam_smoothing; + updatePlayerControl(cam_view); + step(&dtime); + processClientEvents(&cam_view_target); + updateDebugState(); + updateCamera(dtime); + updateSound(dtime); + processPlayerInteraction(dtime, m_game_ui->m_flags.show_hud); + updateFrame(&graph, &stats, dtime, cam_view); + updateProfilerGraphs(&graph); + + // Update if minimap has been disabled by the server + m_game_ui->m_flags.show_minimap &= client->shouldShowMinimap(); + + if (m_does_lost_focus_pause_game && !device->isWindowFocused() && !isMenuActive()) { + showPauseMenu(); + } + } +} + + +void Game::shutdown() +{ + m_rendering_engine->finalize(); +#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 8 + if (g_settings->get("3d_mode") == "pageflip") { + driver->setRenderTarget(irr::video::ERT_STEREO_BOTH_BUFFERS); + } +#endif + auto formspec = m_game_ui->getFormspecGUI(); + if (formspec) + formspec->quitMenu(); + +#ifdef HAVE_TOUCHSCREENGUI + g_touchscreengui->hide(); +#endif + + showOverlayMessage(N_("Shutting down..."), 0, 0, false); + + if (clouds) + clouds->drop(); + + if (gui_chat_console) + gui_chat_console->drop(); + + if (sky) + sky->drop(); + + /* cleanup menus */ + while (g_menumgr.menuCount() > 0) { + g_menumgr.m_stack.front()->setVisible(false); + g_menumgr.deletingMenu(g_menumgr.m_stack.front()); + } + + m_game_ui->deleteFormspec(); + + chat_backend->addMessage(L"", L"# Disconnected."); + chat_backend->addMessage(L"", L""); + m_chat_log_buf.clear(); + + if (client) { + client->Stop(); + while (!client->isShutdown()) { + assert(texture_src != NULL); + assert(shader_src != NULL); + texture_src->processQueue(); + shader_src->processQueue(); + sleep_ms(100); + } + } +} + + +/****************************************************************************/ +/**************************************************************************** + Startup + ****************************************************************************/ +/****************************************************************************/ + +bool Game::init( + const std::string &map_dir, + const std::string &address, + u16 port, + const SubgameSpec &gamespec) +{ + texture_src = createTextureSource(); + + showOverlayMessage(N_("Loading..."), 0, 0); + + shader_src = createShaderSource(); + + itemdef_manager = createItemDefManager(); + nodedef_manager = createNodeDefManager(); + + eventmgr = new EventManager(); + quicktune = new QuicktuneShortcutter(); + + if (!(texture_src && shader_src && itemdef_manager && nodedef_manager + && eventmgr && quicktune)) + return false; + + if (!initSound()) + return false; + + // Create a server if not connecting to an existing one + if (address.empty()) { + if (!createSingleplayerServer(map_dir, gamespec, port)) + return false; + } + + return true; +} + +bool Game::initSound() +{ +#if USE_SOUND + if (g_settings->getBool("enable_sound") && g_sound_manager_singleton.get()) { + infostream << "Attempting to use OpenAL audio" << std::endl; + sound = createOpenALSoundManager(g_sound_manager_singleton.get(), &soundfetcher); + if (!sound) + infostream << "Failed to initialize OpenAL audio" << std::endl; + } else + infostream << "Sound disabled." << std::endl; +#endif + + if (!sound) { + infostream << "Using dummy audio." << std::endl; + sound = &dummySoundManager; + sound_is_dummy = true; + } + + soundmaker = new SoundMaker(sound, nodedef_manager); + if (!soundmaker) + return false; + + soundmaker->registerReceiver(eventmgr); + + return true; +} + +bool Game::createSingleplayerServer(const std::string &map_dir, + const SubgameSpec &gamespec, u16 port) +{ + showOverlayMessage(N_("Creating server..."), 0, 5); + + std::string bind_str = g_settings->get("bind_address"); + Address bind_addr(0, 0, 0, 0, port); + + if (g_settings->getBool("ipv6_server")) { + bind_addr.setAddress((IPv6AddressBytes *) NULL); + } + + try { + bind_addr.Resolve(bind_str.c_str()); + } catch (ResolveError &e) { + infostream << "Resolving bind address \"" << bind_str + << "\" failed: " << e.what() + << " -- Listening on all addresses." << std::endl; + } + + if (bind_addr.isIPv6() && !g_settings->getBool("enable_ipv6")) { + *error_message = fmtgettext("Unable to listen on %s because IPv6 is disabled", + bind_addr.serializeString().c_str()); + errorstream << *error_message << std::endl; + return false; + } + + server = new Server(map_dir, gamespec, simple_singleplayer_mode, bind_addr, + false, nullptr, error_message); + server->start(); + + return true; +} + +bool Game::createClient(const GameStartData &start_data) +{ + showOverlayMessage(N_("Creating client..."), 0, 10); + + draw_control = new MapDrawControl(); + if (!draw_control) + return false; + + bool could_connect, connect_aborted; +#ifdef HAVE_TOUCHSCREENGUI + if (g_touchscreengui) { + g_touchscreengui->init(texture_src); + g_touchscreengui->hide(); + } +#endif + if (!connectToServer(start_data, &could_connect, &connect_aborted)) + return false; + + if (!could_connect) { + if (error_message->empty() && !connect_aborted) { + // Should not happen if error messages are set properly + *error_message = gettext("Connection failed for unknown reason"); + errorstream << *error_message << std::endl; + } + return false; + } + + if (!getServerContent(&connect_aborted)) { + if (error_message->empty() && !connect_aborted) { + // Should not happen if error messages are set properly + *error_message = gettext("Connection failed for unknown reason"); + errorstream << *error_message << std::endl; + } + return false; + } + + auto *scsf = new GameGlobalShaderConstantSetterFactory( + &m_flags.force_fog_off, &runData.fog_range, client); + shader_src->addShaderConstantSetterFactory(scsf); + + // Update cached textures, meshes and materials + client->afterContentReceived(); + + /* Camera + */ + camera = new Camera(*draw_control, client, m_rendering_engine); + if (client->modsLoaded()) + client->getScript()->on_camera_ready(camera); + client->setCamera(camera); + + /* Clouds + */ + if (m_cache_enable_clouds) + clouds = new Clouds(smgr, -1, time(0)); + + /* Skybox + */ + sky = new Sky(-1, m_rendering_engine, texture_src, shader_src); + scsf->setSky(sky); + skybox = NULL; // This is used/set later on in the main run loop + + /* Pre-calculated values + */ + video::ITexture *t = texture_src->getTexture("crack_anylength.png"); + if (t) { + v2u32 size = t->getOriginalSize(); + crack_animation_length = size.Y / size.X; + } else { + crack_animation_length = 5; + } + + if (!initGui()) + return false; + + /* Set window caption + */ + std::wstring str = utf8_to_wide(PROJECT_NAME_C); + str += L" "; + str += utf8_to_wide(g_version_hash); + { + const wchar_t *text = nullptr; + if (simple_singleplayer_mode) + text = wgettext("Singleplayer"); + else + text = wgettext("Multiplayer"); + str += L" ["; + str += text; + str += L"]"; + delete[] text; + } + str += L" ["; + str += driver->getName(); + str += L"]"; + + device->setWindowCaption(str.c_str()); + + LocalPlayer *player = client->getEnv().getLocalPlayer(); + player->hurt_tilt_timer = 0; + player->hurt_tilt_strength = 0; + + hud = new Hud(client, player, &player->inventory); + + mapper = client->getMinimap(); + + if (mapper && client->modsLoaded()) + client->getScript()->on_minimap_ready(mapper); + + return true; +} + +bool Game::initGui() +{ + m_game_ui->init(); + + // Remove stale "recent" chat messages from previous connections + chat_backend->clearRecentChat(); + + // Make sure the size of the recent messages buffer is right + chat_backend->applySettings(); + + // Chat backend and console + gui_chat_console = new GUIChatConsole(guienv, guienv->getRootGUIElement(), + -1, chat_backend, client, &g_menumgr); + +#ifdef HAVE_TOUCHSCREENGUI + + if (g_touchscreengui) + g_touchscreengui->show(); + +#endif + + return true; +} + +bool Game::connectToServer(const GameStartData &start_data, + bool *connect_ok, bool *connection_aborted) +{ + *connect_ok = false; // Let's not be overly optimistic + *connection_aborted = false; + bool local_server_mode = false; + + showOverlayMessage(N_("Resolving address..."), 0, 15); + + Address connect_address(0, 0, 0, 0, start_data.socket_port); + + try { + connect_address.Resolve(start_data.address.c_str()); + + if (connect_address.isZero()) { // i.e. INADDR_ANY, IN6ADDR_ANY + if (connect_address.isIPv6()) { + IPv6AddressBytes addr_bytes; + addr_bytes.bytes[15] = 1; + connect_address.setAddress(&addr_bytes); + } else { + connect_address.setAddress(127, 0, 0, 1); + } + local_server_mode = true; + } + } catch (ResolveError &e) { + *error_message = fmtgettext("Couldn't resolve address: %s", e.what()); + + errorstream << *error_message << std::endl; + return false; + } + + if (connect_address.isIPv6() && !g_settings->getBool("enable_ipv6")) { + *error_message = fmtgettext("Unable to connect to %s because IPv6 is disabled", connect_address.serializeString().c_str()); + errorstream << *error_message << std::endl; + return false; + } + + try { + client = new Client(start_data.name.c_str(), + start_data.password, start_data.address, + *draw_control, texture_src, shader_src, + itemdef_manager, nodedef_manager, sound, eventmgr, + m_rendering_engine, connect_address.isIPv6(), m_game_ui.get(), + start_data.allow_login_or_register); + client->migrateModStorage(); + } catch (const BaseException &e) { + *error_message = fmtgettext("Error creating client: %s", e.what()); + errorstream << *error_message << std::endl; + return false; + } + + client->m_simple_singleplayer_mode = simple_singleplayer_mode; + + infostream << "Connecting to server at "; + connect_address.print(infostream); + infostream << std::endl; + + client->connect(connect_address, + simple_singleplayer_mode || local_server_mode); + + /* + Wait for server to accept connection + */ + + try { + input->clear(); + + FpsControl fps_control; + f32 dtime; + f32 wait_time = 0; // in seconds + + fps_control.reset(); + + while (m_rendering_engine->run()) { + + fps_control.limit(device, &dtime); + + // Update client and server + client->step(dtime); + + if (server != NULL) + server->step(dtime); + + // End condition + if (client->getState() == LC_Init) { + *connect_ok = true; + break; + } + + // Break conditions + if (*connection_aborted) + break; + + if (client->accessDenied()) { + *error_message = fmtgettext("Access denied. Reason: %s", client->accessDeniedReason().c_str()); + *reconnect_requested = client->reconnectRequested(); + errorstream << *error_message << std::endl; + break; + } + + if (input->cancelPressed()) { + *connection_aborted = true; + infostream << "Connect aborted [Escape]" << std::endl; + break; + } + + wait_time += dtime; + // Only time out if we aren't waiting for the server we started + if (!start_data.address.empty() && wait_time > 10) { + *error_message = gettext("Connection timed out."); + errorstream << *error_message << std::endl; + break; + } + + // Update status + showOverlayMessage(N_("Connecting to server..."), dtime, 20); + } + } catch (con::PeerNotFoundException &e) { + // TODO: Should something be done here? At least an info/error + // message? + return false; + } + + return true; +} + +bool Game::getServerContent(bool *aborted) +{ + input->clear(); + + FpsControl fps_control; + f32 dtime; // in seconds + + fps_control.reset(); + + while (m_rendering_engine->run()) { + + fps_control.limit(device, &dtime); + + // Update client and server + client->step(dtime); + + if (server != NULL) + server->step(dtime); + + // End condition + if (client->mediaReceived() && client->itemdefReceived() && + client->nodedefReceived()) { + break; + } + + // Error conditions + if (!checkConnection()) + return false; + + if (client->getState() < LC_Init) { + *error_message = gettext("Client disconnected"); + errorstream << *error_message << std::endl; + return false; + } + + if (input->cancelPressed()) { + *aborted = true; + infostream << "Connect aborted [Escape]" << std::endl; + return false; + } + + // Display status + int progress = 25; + + if (!client->itemdefReceived()) { + const wchar_t *text = wgettext("Item definitions..."); + progress = 25; + m_rendering_engine->draw_load_screen(text, guienv, texture_src, + dtime, progress); + delete[] text; + } else if (!client->nodedefReceived()) { + const wchar_t *text = wgettext("Node definitions..."); + progress = 30; + m_rendering_engine->draw_load_screen(text, guienv, texture_src, + dtime, progress); + delete[] text; + } else { + std::ostringstream message; + std::fixed(message); + message.precision(0); + float receive = client->mediaReceiveProgress() * 100; + message << gettext("Media..."); + if (receive > 0) + message << " " << receive << "%"; + message.precision(2); + + if ((USE_CURL == 0) || + (!g_settings->getBool("enable_remote_media_server"))) { + float cur = client->getCurRate(); + std::string cur_unit = gettext("KiB/s"); + + if (cur > 900) { + cur /= 1024.0; + cur_unit = gettext("MiB/s"); + } + + message << " (" << cur << ' ' << cur_unit << ")"; + } + + progress = 30 + client->mediaReceiveProgress() * 35 + 0.5; + m_rendering_engine->draw_load_screen(utf8_to_wide(message.str()), guienv, + texture_src, dtime, progress); + } + } + + return true; +} + + +/****************************************************************************/ +/**************************************************************************** + Run + ****************************************************************************/ +/****************************************************************************/ + +inline void Game::updateInteractTimers(f32 dtime) +{ + if (runData.nodig_delay_timer >= 0) + runData.nodig_delay_timer -= dtime; + + if (runData.object_hit_delay_timer >= 0) + runData.object_hit_delay_timer -= dtime; + + runData.time_from_last_punch += dtime; +} + + +/* returns false if game should exit, otherwise true + */ +inline bool Game::checkConnection() +{ + if (client->accessDenied()) { + *error_message = fmtgettext("Access denied. Reason: %s", client->accessDeniedReason().c_str()); + *reconnect_requested = client->reconnectRequested(); + errorstream << *error_message << std::endl; + return false; + } + + return true; +} + + +/* returns false if game should exit, otherwise true + */ +inline bool Game::handleCallbacks() +{ + if (g_gamecallback->disconnect_requested) { + g_gamecallback->disconnect_requested = false; + return false; + } + + if (g_gamecallback->changepassword_requested) { + (new GUIPasswordChange(guienv, guiroot, -1, + &g_menumgr, client, texture_src))->drop(); + g_gamecallback->changepassword_requested = false; + } + + if (g_gamecallback->changevolume_requested) { + (new GUIVolumeChange(guienv, guiroot, -1, + &g_menumgr, texture_src))->drop(); + g_gamecallback->changevolume_requested = false; + } + + if (g_gamecallback->keyconfig_requested) { + (new GUIKeyChangeMenu(guienv, guiroot, -1, + &g_menumgr, texture_src))->drop(); + g_gamecallback->keyconfig_requested = false; + } + + if (g_gamecallback->keyconfig_changed) { + input->keycache.populate(); // update the cache with new settings + g_gamecallback->keyconfig_changed = false; + } + + return true; +} + + +void Game::processQueues() +{ + texture_src->processQueue(); + itemdef_manager->processQueue(client); + shader_src->processQueue(); +} + +void Game::updateDebugState() +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + // debug UI and wireframe + bool has_debug = client->checkPrivilege("debug"); + bool has_basic_debug = has_debug || (player->hud_flags & HUD_FLAG_BASIC_DEBUG); + + if (m_game_ui->m_flags.show_basic_debug) { + if (!has_basic_debug) + m_game_ui->m_flags.show_basic_debug = false; + } else if (m_game_ui->m_flags.show_minimal_debug) { + if (has_basic_debug) + m_game_ui->m_flags.show_basic_debug = true; + } + if (!has_basic_debug) + hud->disableBlockBounds(); + if (!has_debug) + draw_control->show_wireframe = false; + + // noclip + draw_control->allow_noclip = m_cache_enable_noclip && client->checkPrivilege("noclip"); +} + +void Game::updateProfilers(const RunStats &stats, const FpsControl &draw_times, + f32 dtime) +{ + float profiler_print_interval = + g_settings->getFloat("profiler_print_interval"); + bool print_to_log = true; + + if (profiler_print_interval == 0) { + print_to_log = false; + profiler_print_interval = 3; + } + + if (profiler_interval.step(dtime, profiler_print_interval)) { + if (print_to_log) { + infostream << "Profiler:" << std::endl; + g_profiler->print(infostream); + } + + m_game_ui->updateProfiler(); + g_profiler->clear(); + } + + // Update update graphs + g_profiler->graphAdd("Time non-rendering [us]", + draw_times.busy_time - stats.drawtime); + + g_profiler->graphAdd("Sleep [us]", draw_times.sleep_time); + g_profiler->graphAdd("FPS", 1.0f / dtime); +} + +void Game::updateStats(RunStats *stats, const FpsControl &draw_times, + f32 dtime) +{ + + f32 jitter; + Jitter *jp; + + /* Time average and jitter calculation + */ + jp = &stats->dtime_jitter; + jp->avg = jp->avg * 0.96 + dtime * 0.04; + + jitter = dtime - jp->avg; + + if (jitter > jp->max) + jp->max = jitter; + + jp->counter += dtime; + + if (jp->counter > 0.0) { + jp->counter -= 3.0; + jp->max_sample = jp->max; + jp->max_fraction = jp->max_sample / (jp->avg + 0.001); + jp->max = 0.0; + } + + /* Busytime average and jitter calculation + */ + jp = &stats->busy_time_jitter; + jp->avg = jp->avg + draw_times.getBusyMs() * 0.02; + + jitter = draw_times.getBusyMs() - jp->avg; + + if (jitter > jp->max) + jp->max = jitter; + if (jitter < jp->min) + jp->min = jitter; + + jp->counter += dtime; + + if (jp->counter > 0.0) { + jp->counter -= 3.0; + jp->max_sample = jp->max; + jp->min_sample = jp->min; + jp->max = 0.0; + jp->min = 0.0; + } +} + + + +/**************************************************************************** + Input handling + ****************************************************************************/ + +void Game::processUserInput(f32 dtime) +{ + // Reset input if window not active or some menu is active + if (!device->isWindowActive() || isMenuActive() || guienv->hasFocus(gui_chat_console)) { + input->clear(); +#ifdef HAVE_TOUCHSCREENGUI + g_touchscreengui->hide(); +#endif + } +#ifdef HAVE_TOUCHSCREENGUI + else if (g_touchscreengui) { + /* on touchscreengui step may generate own input events which ain't + * what we want in case we just did clear them */ + g_touchscreengui->show(); + g_touchscreengui->step(dtime); + } +#endif + + if (!guienv->hasFocus(gui_chat_console) && gui_chat_console->isOpen()) { + gui_chat_console->closeConsoleAtOnce(); + } + + // Input handler step() (used by the random input generator) + input->step(dtime); + +#ifdef __ANDROID__ + auto formspec = m_game_ui->getFormspecGUI(); + if (formspec) + formspec->getAndroidUIInput(); + else + handleAndroidChatInput(); +#endif + + // Increase timer for double tap of "keymap_jump" + if (m_cache_doubletap_jump && runData.jump_timer <= 0.2f) + runData.jump_timer += dtime; + + processKeyInput(); + processItemSelection(&runData.new_playeritem); +} + + +void Game::processKeyInput() +{ + if (wasKeyDown(KeyType::DROP)) { + dropSelectedItem(isKeyDown(KeyType::SNEAK)); + } else if (wasKeyDown(KeyType::AUTOFORWARD)) { + toggleAutoforward(); + } else if (wasKeyDown(KeyType::BACKWARD)) { + if (g_settings->getBool("continuous_forward")) + toggleAutoforward(); + } else if (wasKeyDown(KeyType::INVENTORY)) { + openInventory(); + } else if (input->cancelPressed()) { +#ifdef __ANDROID__ + m_android_chat_open = false; +#endif + if (!gui_chat_console->isOpenInhibited()) { + showPauseMenu(); + } + } else if (wasKeyDown(KeyType::CHAT)) { + openConsole(0.2, L""); + } else if (wasKeyDown(KeyType::CMD)) { + openConsole(0.2, L"/"); + } else if (wasKeyDown(KeyType::CMD_LOCAL)) { + if (client->modsLoaded()) + openConsole(0.2, L"."); + else + m_game_ui->showTranslatedStatusText("Client side scripting is disabled"); + } else if (wasKeyDown(KeyType::CONSOLE)) { + openConsole(core::clamp(g_settings->getFloat("console_height"), 0.1f, 1.0f)); + } else if (wasKeyDown(KeyType::FREEMOVE)) { + toggleFreeMove(); + } else if (wasKeyDown(KeyType::JUMP)) { + toggleFreeMoveAlt(); + } else if (wasKeyDown(KeyType::PITCHMOVE)) { + togglePitchMove(); + } else if (wasKeyDown(KeyType::FASTMOVE)) { + toggleFast(); + } else if (wasKeyDown(KeyType::NOCLIP)) { + toggleNoClip(); +#if USE_SOUND + } else if (wasKeyDown(KeyType::MUTE)) { + if (g_settings->getBool("enable_sound")) { + bool new_mute_sound = !g_settings->getBool("mute_sound"); + g_settings->setBool("mute_sound", new_mute_sound); + if (new_mute_sound) + m_game_ui->showTranslatedStatusText("Sound muted"); + else + m_game_ui->showTranslatedStatusText("Sound unmuted"); + } else { + m_game_ui->showTranslatedStatusText("Sound system is disabled"); + } + } else if (wasKeyDown(KeyType::INC_VOLUME)) { + if (g_settings->getBool("enable_sound")) { + float new_volume = g_settings->getFloat("sound_volume", 0.0f, 0.9f) + 0.1f; + g_settings->setFloat("sound_volume", new_volume); + std::wstring msg = fwgettext("Volume changed to %d%%", myround(new_volume * 100)); + m_game_ui->showStatusText(msg); + } else { + m_game_ui->showTranslatedStatusText("Sound system is disabled"); + } + } else if (wasKeyDown(KeyType::DEC_VOLUME)) { + if (g_settings->getBool("enable_sound")) { + float new_volume = g_settings->getFloat("sound_volume", 0.1f, 1.0f) - 0.1f; + g_settings->setFloat("sound_volume", new_volume); + std::wstring msg = fwgettext("Volume changed to %d%%", myround(new_volume * 100)); + m_game_ui->showStatusText(msg); + } else { + m_game_ui->showTranslatedStatusText("Sound system is disabled"); + } +#else + } else if (wasKeyDown(KeyType::MUTE) || wasKeyDown(KeyType::INC_VOLUME) + || wasKeyDown(KeyType::DEC_VOLUME)) { + m_game_ui->showTranslatedStatusText("Sound system is not supported on this build"); +#endif + } else if (wasKeyDown(KeyType::CINEMATIC)) { + toggleCinematic(); + } else if (wasKeyDown(KeyType::SCREENSHOT)) { + client->makeScreenshot(); + } else if (wasKeyDown(KeyType::TOGGLE_BLOCK_BOUNDS)) { + toggleBlockBounds(); + } else if (wasKeyDown(KeyType::TOGGLE_HUD)) { + m_game_ui->toggleHud(); + } else if (wasKeyDown(KeyType::MINIMAP)) { + toggleMinimap(isKeyDown(KeyType::SNEAK)); + } else if (wasKeyDown(KeyType::TOGGLE_CHAT)) { + m_game_ui->toggleChat(); + } else if (wasKeyDown(KeyType::TOGGLE_FOG)) { + toggleFog(); + } else if (wasKeyDown(KeyType::TOGGLE_UPDATE_CAMERA)) { + toggleUpdateCamera(); + } else if (wasKeyDown(KeyType::TOGGLE_DEBUG)) { + toggleDebug(); + } else if (wasKeyDown(KeyType::TOGGLE_PROFILER)) { + m_game_ui->toggleProfiler(); + } else if (wasKeyDown(KeyType::INCREASE_VIEWING_RANGE)) { + increaseViewRange(); + } else if (wasKeyDown(KeyType::DECREASE_VIEWING_RANGE)) { + decreaseViewRange(); + } else if (wasKeyDown(KeyType::RANGESELECT)) { + toggleFullViewRange(); + } else if (wasKeyDown(KeyType::ZOOM)) { + checkZoomEnabled(); + } else if (wasKeyDown(KeyType::QUICKTUNE_NEXT)) { + quicktune->next(); + } else if (wasKeyDown(KeyType::QUICKTUNE_PREV)) { + quicktune->prev(); + } else if (wasKeyDown(KeyType::QUICKTUNE_INC)) { + quicktune->inc(); + } else if (wasKeyDown(KeyType::QUICKTUNE_DEC)) { + quicktune->dec(); + } + + if (!isKeyDown(KeyType::JUMP) && runData.reset_jump_timer) { + runData.reset_jump_timer = false; + runData.jump_timer = 0.0f; + } + + if (quicktune->hasMessage()) { + m_game_ui->showStatusText(utf8_to_wide(quicktune->getMessage())); + } +} + +void Game::processItemSelection(u16 *new_playeritem) +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + /* Item selection using mouse wheel + */ + *new_playeritem = player->getWieldIndex(); + + s32 wheel = input->getMouseWheel(); + u16 max_item = MYMIN(PLAYER_INVENTORY_SIZE - 1, + player->hud_hotbar_itemcount - 1); + + s32 dir = wheel; + + if (wasKeyDown(KeyType::HOTBAR_NEXT)) + dir = -1; + + if (wasKeyDown(KeyType::HOTBAR_PREV)) + dir = 1; + + if (dir < 0) + *new_playeritem = *new_playeritem < max_item ? *new_playeritem + 1 : 0; + else if (dir > 0) + *new_playeritem = *new_playeritem > 0 ? *new_playeritem - 1 : max_item; + // else dir == 0 + + /* Item selection using hotbar slot keys + */ + for (u16 i = 0; i <= max_item; i++) { + if (wasKeyDown((GameKeyType) (KeyType::SLOT_1 + i))) { + *new_playeritem = i; + break; + } + } +} + + +void Game::dropSelectedItem(bool single_item) +{ + IDropAction *a = new IDropAction(); + a->count = single_item ? 1 : 0; + a->from_inv.setCurrentPlayer(); + a->from_list = "main"; + a->from_i = client->getEnv().getLocalPlayer()->getWieldIndex(); + client->inventoryAction(a); +} + + +void Game::openInventory() +{ + /* + * Don't permit to open inventory is CAO or player doesn't exists. + * This prevent showing an empty inventory at player load + */ + + LocalPlayer *player = client->getEnv().getLocalPlayer(); + if (!player || !player->getCAO()) + return; + + infostream << "Game: Launching inventory" << std::endl; + + PlayerInventoryFormSource *fs_src = new PlayerInventoryFormSource(client); + + InventoryLocation inventoryloc; + inventoryloc.setCurrentPlayer(); + + if (client->modsLoaded() && client->getScript()->on_inventory_open(fs_src->m_client->getInventory(inventoryloc))) { + delete fs_src; + return; + } + + if (fs_src->getForm().empty()) { + delete fs_src; + return; + } + + TextDest *txt_dst = new TextDestPlayerInventory(client); + auto *&formspec = m_game_ui->updateFormspec(""); + GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(), + &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound); + + formspec->setFormSpec(fs_src->getForm(), inventoryloc); +} + + +void Game::openConsole(float scale, const wchar_t *line) +{ + assert(scale > 0.0f && scale <= 1.0f); + +#ifdef __ANDROID__ + porting::showInputDialog(gettext("ok"), "", "", 2); + m_android_chat_open = true; +#else + if (gui_chat_console->isOpenInhibited()) + return; + gui_chat_console->openConsole(scale); + if (line) { + gui_chat_console->setCloseOnEnter(true); + gui_chat_console->replaceAndAddToHistory(line); + } +#endif +} + +#ifdef __ANDROID__ +void Game::handleAndroidChatInput() +{ + if (m_android_chat_open && porting::getInputDialogState() == 0) { + std::string text = porting::getInputDialogValue(); + client->typeChatMessage(utf8_to_wide(text)); + m_android_chat_open = false; + } +} +#endif + + +void Game::toggleFreeMove() +{ + bool free_move = !g_settings->getBool("free_move"); + g_settings->set("free_move", bool_to_cstr(free_move)); + + if (free_move) { + if (client->checkPrivilege("fly")) { + m_game_ui->showTranslatedStatusText("Fly mode enabled"); + } else { + m_game_ui->showTranslatedStatusText("Fly mode enabled (note: no 'fly' privilege)"); + } + } else { + m_game_ui->showTranslatedStatusText("Fly mode disabled"); + } +} + +void Game::toggleFreeMoveAlt() +{ + if (m_cache_doubletap_jump && runData.jump_timer < 0.2f) + toggleFreeMove(); + + runData.reset_jump_timer = true; +} + + +void Game::togglePitchMove() +{ + bool pitch_move = !g_settings->getBool("pitch_move"); + g_settings->set("pitch_move", bool_to_cstr(pitch_move)); + + if (pitch_move) { + m_game_ui->showTranslatedStatusText("Pitch move mode enabled"); + } else { + m_game_ui->showTranslatedStatusText("Pitch move mode disabled"); + } +} + + +void Game::toggleFast() +{ + bool fast_move = !g_settings->getBool("fast_move"); + bool has_fast_privs = client->checkPrivilege("fast"); + g_settings->set("fast_move", bool_to_cstr(fast_move)); + + if (fast_move) { + if (has_fast_privs) { + m_game_ui->showTranslatedStatusText("Fast mode enabled"); + } else { + m_game_ui->showTranslatedStatusText("Fast mode enabled (note: no 'fast' privilege)"); + } + } else { + m_game_ui->showTranslatedStatusText("Fast mode disabled"); + } + +#ifdef HAVE_TOUCHSCREENGUI + m_cache_hold_aux1 = fast_move && has_fast_privs; +#endif +} + + +void Game::toggleNoClip() +{ + bool noclip = !g_settings->getBool("noclip"); + g_settings->set("noclip", bool_to_cstr(noclip)); + + if (noclip) { + if (client->checkPrivilege("noclip")) { + m_game_ui->showTranslatedStatusText("Noclip mode enabled"); + } else { + m_game_ui->showTranslatedStatusText("Noclip mode enabled (note: no 'noclip' privilege)"); + } + } else { + m_game_ui->showTranslatedStatusText("Noclip mode disabled"); + } +} + +void Game::toggleCinematic() +{ + bool cinematic = !g_settings->getBool("cinematic"); + g_settings->set("cinematic", bool_to_cstr(cinematic)); + + if (cinematic) + m_game_ui->showTranslatedStatusText("Cinematic mode enabled"); + else + m_game_ui->showTranslatedStatusText("Cinematic mode disabled"); +} + +void Game::toggleBlockBounds() +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + if (!(client->checkPrivilege("debug") || (player->hud_flags & HUD_FLAG_BASIC_DEBUG))) { + m_game_ui->showTranslatedStatusText("Can't show block bounds (disabled by mod or game)"); + return; + } + enum Hud::BlockBoundsMode newmode = hud->toggleBlockBounds(); + switch (newmode) { + case Hud::BLOCK_BOUNDS_OFF: + m_game_ui->showTranslatedStatusText("Block bounds hidden"); + break; + case Hud::BLOCK_BOUNDS_CURRENT: + m_game_ui->showTranslatedStatusText("Block bounds shown for current block"); + break; + case Hud::BLOCK_BOUNDS_NEAR: + m_game_ui->showTranslatedStatusText("Block bounds shown for nearby blocks"); + break; + case Hud::BLOCK_BOUNDS_MAX: + m_game_ui->showTranslatedStatusText("Block bounds shown for all blocks"); + break; + default: + break; + } +} + +// Autoforward by toggling continuous forward. +void Game::toggleAutoforward() +{ + bool autorun_enabled = !g_settings->getBool("continuous_forward"); + g_settings->set("continuous_forward", bool_to_cstr(autorun_enabled)); + + if (autorun_enabled) + m_game_ui->showTranslatedStatusText("Automatic forward enabled"); + else + m_game_ui->showTranslatedStatusText("Automatic forward disabled"); +} + +void Game::toggleMinimap(bool shift_pressed) +{ + if (!mapper || !m_game_ui->m_flags.show_hud || !g_settings->getBool("enable_minimap")) + return; + + if (shift_pressed) + mapper->toggleMinimapShape(); + else + mapper->nextMode(); + + // TODO: When legacy minimap is deprecated, keep only HUD minimap stuff here + + // Not so satisying code to keep compatibility with old fixed mode system + // --> + u32 hud_flags = client->getEnv().getLocalPlayer()->hud_flags; + + if (!(hud_flags & HUD_FLAG_MINIMAP_VISIBLE)) { + m_game_ui->m_flags.show_minimap = false; + } else { + + // If radar is disabled, try to find a non radar mode or fall back to 0 + if (!(hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE)) + while (mapper->getModeIndex() && + mapper->getModeDef().type == MINIMAP_TYPE_RADAR) + mapper->nextMode(); + + m_game_ui->m_flags.show_minimap = mapper->getModeDef().type != + MINIMAP_TYPE_OFF; + } + // <-- + // End of 'not so satifying code' + if ((hud_flags & HUD_FLAG_MINIMAP_VISIBLE) || + (hud && hud->hasElementOfType(HUD_ELEM_MINIMAP))) + m_game_ui->showStatusText(utf8_to_wide(mapper->getModeDef().label)); + else + m_game_ui->showTranslatedStatusText("Minimap currently disabled by game or mod"); +} + +void Game::toggleFog() +{ + bool fog_enabled = g_settings->getBool("enable_fog"); + g_settings->setBool("enable_fog", !fog_enabled); + if (fog_enabled) + m_game_ui->showTranslatedStatusText("Fog disabled"); + else + m_game_ui->showTranslatedStatusText("Fog enabled"); +} + + +void Game::toggleDebug() +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + bool has_debug = client->checkPrivilege("debug"); + bool has_basic_debug = has_debug || (player->hud_flags & HUD_FLAG_BASIC_DEBUG); + // Initial: No debug info + // 1x toggle: Debug text + // 2x toggle: Debug text with profiler graph + // 3x toggle: Debug text and wireframe (needs "debug" priv) + // Next toggle: Back to initial + // + // The debug text can be in 2 modes: minimal and basic. + // * Minimal: Only technical client info that not gameplay-relevant + // * Basic: Info that might give gameplay advantage, e.g. pos, angle + // Basic mode is used when player has the debug HUD flag set, + // otherwise the Minimal mode is used. + if (!m_game_ui->m_flags.show_minimal_debug) { + m_game_ui->m_flags.show_minimal_debug = true; + if (has_basic_debug) + m_game_ui->m_flags.show_basic_debug = true; + m_game_ui->m_flags.show_profiler_graph = false; + draw_control->show_wireframe = false; + m_game_ui->showTranslatedStatusText("Debug info shown"); + } else if (!m_game_ui->m_flags.show_profiler_graph && !draw_control->show_wireframe) { + if (has_basic_debug) + m_game_ui->m_flags.show_basic_debug = true; + m_game_ui->m_flags.show_profiler_graph = true; + m_game_ui->showTranslatedStatusText("Profiler graph shown"); + } else if (!draw_control->show_wireframe && client->checkPrivilege("debug")) { + if (has_basic_debug) + m_game_ui->m_flags.show_basic_debug = true; + m_game_ui->m_flags.show_profiler_graph = false; + draw_control->show_wireframe = true; + m_game_ui->showTranslatedStatusText("Wireframe shown"); + } else { + m_game_ui->m_flags.show_minimal_debug = false; + m_game_ui->m_flags.show_basic_debug = false; + m_game_ui->m_flags.show_profiler_graph = false; + draw_control->show_wireframe = false; + if (has_debug) { + m_game_ui->showTranslatedStatusText("Debug info, profiler graph, and wireframe hidden"); + } else { + m_game_ui->showTranslatedStatusText("Debug info and profiler graph hidden"); + } + } +} + + +void Game::toggleUpdateCamera() +{ + m_flags.disable_camera_update = !m_flags.disable_camera_update; + if (m_flags.disable_camera_update) + m_game_ui->showTranslatedStatusText("Camera update disabled"); + else + m_game_ui->showTranslatedStatusText("Camera update enabled"); +} + + +void Game::increaseViewRange() +{ + s16 range = g_settings->getS16("viewing_range"); + s16 range_new = range + 10; + + if (range_new > 4000) { + range_new = 4000; + std::wstring msg = fwgettext("Viewing range is at maximum: %d", range_new); + m_game_ui->showStatusText(msg); + } else { + std::wstring msg = fwgettext("Viewing range changed to %d", range_new); + m_game_ui->showStatusText(msg); + } + g_settings->set("viewing_range", itos(range_new)); +} + + +void Game::decreaseViewRange() +{ + s16 range = g_settings->getS16("viewing_range"); + s16 range_new = range - 10; + + if (range_new < 20) { + range_new = 20; + std::wstring msg = fwgettext("Viewing range is at minimum: %d", range_new); + m_game_ui->showStatusText(msg); + } else { + std::wstring msg = fwgettext("Viewing range changed to %d", range_new); + m_game_ui->showStatusText(msg); + } + g_settings->set("viewing_range", itos(range_new)); +} + + +void Game::toggleFullViewRange() +{ + draw_control->range_all = !draw_control->range_all; + if (draw_control->range_all) + m_game_ui->showTranslatedStatusText("Enabled unlimited viewing range"); + else + m_game_ui->showTranslatedStatusText("Disabled unlimited viewing range"); +} + + +void Game::checkZoomEnabled() +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + if (player->getZoomFOV() < 0.001f || player->getFov().fov > 0.0f) + m_game_ui->showTranslatedStatusText("Zoom currently disabled by game or mod"); +} + +void Game::updateCameraDirection(CameraOrientation *cam, float dtime) +{ + if ((device->isWindowActive() && device->isWindowFocused() + && !isMenuActive()) || input->isRandom()) { + +#ifndef __ANDROID__ + if (!input->isRandom()) { + // Mac OSX gets upset if this is set every frame + if (device->getCursorControl()->isVisible()) + device->getCursorControl()->setVisible(false); + } +#endif + + if (m_first_loop_after_window_activation) { + m_first_loop_after_window_activation = false; + + input->setMousePos(driver->getScreenSize().Width / 2, + driver->getScreenSize().Height / 2); + } else { + updateCameraOrientation(cam, dtime); + } + + } else { + +#ifndef ANDROID + // Mac OSX gets upset if this is set every frame + if (!device->getCursorControl()->isVisible()) + device->getCursorControl()->setVisible(true); +#endif + + m_first_loop_after_window_activation = true; + + } +} + +// Get the factor to multiply with sensitivity to get the same mouse/joystick +// responsiveness independently of FOV. +f32 Game::getSensitivityScaleFactor() const +{ + f32 fov_y = client->getCamera()->getFovY(); + + // Multiply by a constant such that it becomes 1.0 at 72 degree FOV and + // 16:9 aspect ratio to minimize disruption of existing sensitivity + // settings. + return tan(fov_y / 2.0f) * 1.3763818698f; +} + +void Game::updateCameraOrientation(CameraOrientation *cam, float dtime) +{ +#ifdef HAVE_TOUCHSCREENGUI + if (g_touchscreengui) { + cam->camera_yaw += g_touchscreengui->getYawChange(); + cam->camera_pitch = g_touchscreengui->getPitch(); + } else { +#endif + v2s32 center(driver->getScreenSize().Width / 2, driver->getScreenSize().Height / 2); + v2s32 dist = input->getMousePos() - center; + + if (m_invert_mouse || camera->getCameraMode() == CAMERA_MODE_THIRD_FRONT) { + dist.Y = -dist.Y; + } + + f32 sens_scale = getSensitivityScaleFactor(); + cam->camera_yaw -= dist.X * m_cache_mouse_sensitivity * sens_scale; + cam->camera_pitch += dist.Y * m_cache_mouse_sensitivity * sens_scale; + + if (dist.X != 0 || dist.Y != 0) + input->setMousePos(center.X, center.Y); +#ifdef HAVE_TOUCHSCREENGUI + } +#endif + + if (m_cache_enable_joysticks) { + f32 sens_scale = getSensitivityScaleFactor(); + f32 c = m_cache_joystick_frustum_sensitivity * dtime * sens_scale; + cam->camera_yaw -= input->joystick.getAxisWithoutDead(JA_FRUSTUM_HORIZONTAL) * c; + cam->camera_pitch += input->joystick.getAxisWithoutDead(JA_FRUSTUM_VERTICAL) * c; + } + + cam->camera_pitch = rangelim(cam->camera_pitch, -89.5, 89.5); +} + + +void Game::updatePlayerControl(const CameraOrientation &cam) +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + //TimeTaker tt("update player control", NULL, PRECISION_NANO); + + PlayerControl control( + isKeyDown(KeyType::FORWARD), + isKeyDown(KeyType::BACKWARD), + isKeyDown(KeyType::LEFT), + isKeyDown(KeyType::RIGHT), + isKeyDown(KeyType::JUMP) || player->getAutojump(), + isKeyDown(KeyType::AUX1), + isKeyDown(KeyType::SNEAK), + isKeyDown(KeyType::ZOOM), + isKeyDown(KeyType::DIG), + isKeyDown(KeyType::PLACE), + cam.camera_pitch, + cam.camera_yaw, + input->getMovementSpeed(), + input->getMovementDirection() + ); + + // autoforward if set: move at maximum speed + if (player->getPlayerSettings().continuous_forward && + client->activeObjectsReceived() && !player->isDead()) { + control.movement_speed = 1.0f; + // sideways movement only + float dx = sin(control.movement_direction); + control.movement_direction = atan2(dx, 1.0f); + } + +#ifdef HAVE_TOUCHSCREENGUI + /* For touch, simulate holding down AUX1 (fast move) if the user has + * the fast_move setting toggled on. If there is an aux1 key defined for + * touch then its meaning is inverted (i.e. holding aux1 means walk and + * not fast) + */ + if (m_cache_hold_aux1) { + control.aux1 = control.aux1 ^ true; + } +#endif + + client->setPlayerControl(control); + + //tt.stop(); +} + + +inline void Game::step(f32 *dtime) +{ + bool can_be_and_is_paused = + (simple_singleplayer_mode && g_menumgr.pausesGame()); + + if (can_be_and_is_paused) { // This is for a singleplayer server + *dtime = 0; // No time passes + } else { + if (simple_singleplayer_mode && !paused_animated_nodes.empty()) + resumeAnimation(); + + if (server) + server->step(*dtime); + + client->step(*dtime); + } +} + +static void pauseNodeAnimation(PausedNodesList &paused, scene::ISceneNode *node) { + if (!node) + return; + for (auto &&child: node->getChildren()) + pauseNodeAnimation(paused, child); + if (node->getType() != scene::ESNT_ANIMATED_MESH) + return; + auto animated_node = static_cast<scene::IAnimatedMeshSceneNode *>(node); + float speed = animated_node->getAnimationSpeed(); + if (!speed) + return; + paused.push_back({grab(animated_node), speed}); + animated_node->setAnimationSpeed(0.0f); +} + +void Game::pauseAnimation() +{ + pauseNodeAnimation(paused_animated_nodes, smgr->getRootSceneNode()); +} + +void Game::resumeAnimation() +{ + for (auto &&pair: paused_animated_nodes) + pair.first->setAnimationSpeed(pair.second); + paused_animated_nodes.clear(); +} + +const ClientEventHandler Game::clientEventHandler[CLIENTEVENT_MAX] = { + {&Game::handleClientEvent_None}, + {&Game::handleClientEvent_PlayerDamage}, + {&Game::handleClientEvent_PlayerForceMove}, + {&Game::handleClientEvent_Deathscreen}, + {&Game::handleClientEvent_ShowFormSpec}, + {&Game::handleClientEvent_ShowLocalFormSpec}, + {&Game::handleClientEvent_HandleParticleEvent}, + {&Game::handleClientEvent_HandleParticleEvent}, + {&Game::handleClientEvent_HandleParticleEvent}, + {&Game::handleClientEvent_HudAdd}, + {&Game::handleClientEvent_HudRemove}, + {&Game::handleClientEvent_HudChange}, + {&Game::handleClientEvent_SetSky}, + {&Game::handleClientEvent_SetSun}, + {&Game::handleClientEvent_SetMoon}, + {&Game::handleClientEvent_SetStars}, + {&Game::handleClientEvent_OverrideDayNigthRatio}, + {&Game::handleClientEvent_CloudParams}, +}; + +void Game::handleClientEvent_None(ClientEvent *event, CameraOrientation *cam) +{ + FATAL_ERROR("ClientEvent type None received"); +} + +void Game::handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam) +{ + if (client->modsLoaded()) + client->getScript()->on_damage_taken(event->player_damage.amount); + + if (!event->player_damage.effect) + return; + + // Damage flash and hurt tilt are not used at death + if (client->getHP() > 0) { + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + f32 hp_max = player->getCAO() ? + player->getCAO()->getProperties().hp_max : PLAYER_MAX_HP_DEFAULT; + f32 damage_ratio = event->player_damage.amount / hp_max; + + runData.damage_flash += 95.0f + 64.f * damage_ratio; + runData.damage_flash = MYMIN(runData.damage_flash, 127.0f); + + player->hurt_tilt_timer = 1.5f; + player->hurt_tilt_strength = + rangelim(damage_ratio * 5.0f, 1.0f, 4.0f); + } + + // Play damage sound + client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_DAMAGE)); +} + +void Game::handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam) +{ + cam->camera_yaw = event->player_force_move.yaw; + cam->camera_pitch = event->player_force_move.pitch; +} + +void Game::handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam) +{ + // If client scripting is enabled, deathscreen is handled by CSM code in + // builtin/client/init.lua + if (client->modsLoaded()) + client->getScript()->on_death(); + else + showDeathFormspec(); + + /* Handle visualization */ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + runData.damage_flash = 0; + player->hurt_tilt_timer = 0; + player->hurt_tilt_strength = 0; +} + +void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam) +{ + if (event->show_formspec.formspec->empty()) { + auto formspec = m_game_ui->getFormspecGUI(); + if (formspec && (event->show_formspec.formname->empty() + || *(event->show_formspec.formname) == m_game_ui->getFormspecName())) { + formspec->quitMenu(); + } + } else { + FormspecFormSource *fs_src = + new FormspecFormSource(*(event->show_formspec.formspec)); + TextDestPlayerInventory *txt_dst = + new TextDestPlayerInventory(client, *(event->show_formspec.formname)); + + auto *&formspec = m_game_ui->updateFormspec(*(event->show_formspec.formname)); + GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(), + &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound); + } + + delete event->show_formspec.formspec; + delete event->show_formspec.formname; +} + +void Game::handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam) +{ + FormspecFormSource *fs_src = new FormspecFormSource(*event->show_formspec.formspec); + LocalFormspecHandler *txt_dst = + new LocalFormspecHandler(*event->show_formspec.formname, client); + GUIFormSpecMenu::create(m_game_ui->getFormspecGUI(), client, m_rendering_engine->get_gui_env(), + &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound); + + delete event->show_formspec.formspec; + delete event->show_formspec.formname; +} + +void Game::handleClientEvent_HandleParticleEvent(ClientEvent *event, + CameraOrientation *cam) +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + client->getParticleManager()->handleParticleEvent(event, client, player); +} + +void Game::handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam) +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + u32 server_id = event->hudadd->server_id; + // ignore if we already have a HUD with that ID + auto i = m_hud_server_to_client.find(server_id); + if (i != m_hud_server_to_client.end()) { + delete event->hudadd; + return; + } + + HudElement *e = new HudElement; + e->type = static_cast<HudElementType>(event->hudadd->type); + e->pos = event->hudadd->pos; + e->name = event->hudadd->name; + e->scale = event->hudadd->scale; + e->text = event->hudadd->text; + e->number = event->hudadd->number; + e->item = event->hudadd->item; + e->dir = event->hudadd->dir; + e->align = event->hudadd->align; + e->offset = event->hudadd->offset; + e->world_pos = event->hudadd->world_pos; + e->size = event->hudadd->size; + e->z_index = event->hudadd->z_index; + e->text2 = event->hudadd->text2; + e->style = event->hudadd->style; + m_hud_server_to_client[server_id] = player->addHud(e); + + delete event->hudadd; +} + +void Game::handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam) +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + auto i = m_hud_server_to_client.find(event->hudrm.id); + if (i != m_hud_server_to_client.end()) { + HudElement *e = player->removeHud(i->second); + delete e; + m_hud_server_to_client.erase(i); + } + +} + +void Game::handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *cam) +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + HudElement *e = nullptr; + + auto i = m_hud_server_to_client.find(event->hudchange->id); + if (i != m_hud_server_to_client.end()) { + e = player->getHud(i->second); + } + + if (e == nullptr) { + delete event->hudchange; + return; + } + +#define CASE_SET(statval, prop, dataprop) \ + case statval: \ + e->prop = event->hudchange->dataprop; \ + break + + switch (event->hudchange->stat) { + CASE_SET(HUD_STAT_POS, pos, v2fdata); + + CASE_SET(HUD_STAT_NAME, name, sdata); + + CASE_SET(HUD_STAT_SCALE, scale, v2fdata); + + CASE_SET(HUD_STAT_TEXT, text, sdata); + + CASE_SET(HUD_STAT_NUMBER, number, data); + + CASE_SET(HUD_STAT_ITEM, item, data); + + CASE_SET(HUD_STAT_DIR, dir, data); + + CASE_SET(HUD_STAT_ALIGN, align, v2fdata); + + CASE_SET(HUD_STAT_OFFSET, offset, v2fdata); + + CASE_SET(HUD_STAT_WORLD_POS, world_pos, v3fdata); + + CASE_SET(HUD_STAT_SIZE, size, v2s32data); + + CASE_SET(HUD_STAT_Z_INDEX, z_index, data); + + CASE_SET(HUD_STAT_TEXT2, text2, sdata); + + CASE_SET(HUD_STAT_STYLE, style, data); + } + +#undef CASE_SET + + delete event->hudchange; +} + +void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam) +{ + sky->setVisible(false); + // Whether clouds are visible in front of a custom skybox. + sky->setCloudsEnabled(event->set_sky->clouds); + + if (skybox) { + skybox->remove(); + skybox = NULL; + } + // Clear the old textures out in case we switch rendering type. + sky->clearSkyboxTextures(); + // Handle according to type + if (event->set_sky->type == "regular") { + // Shows the mesh skybox + sky->setVisible(true); + // Update mesh based skybox colours if applicable. + sky->setSkyColors(event->set_sky->sky_color); + sky->setHorizonTint( + event->set_sky->fog_sun_tint, + event->set_sky->fog_moon_tint, + event->set_sky->fog_tint_type + ); + } else if (event->set_sky->type == "skybox" && + event->set_sky->textures.size() == 6) { + // Disable the dyanmic mesh skybox: + sky->setVisible(false); + // Set fog colors: + sky->setFallbackBgColor(event->set_sky->bgcolor); + // Set sunrise and sunset fog tinting: + sky->setHorizonTint( + event->set_sky->fog_sun_tint, + event->set_sky->fog_moon_tint, + event->set_sky->fog_tint_type + ); + // Add textures to skybox. + for (int i = 0; i < 6; i++) + sky->addTextureToSkybox(event->set_sky->textures[i], i, texture_src); + } else { + // Handle everything else as plain color. + if (event->set_sky->type != "plain") + infostream << "Unknown sky type: " + << (event->set_sky->type) << std::endl; + sky->setVisible(false); + sky->setFallbackBgColor(event->set_sky->bgcolor); + // Disable directional sun/moon tinting on plain or invalid skyboxes. + sky->setHorizonTint( + event->set_sky->bgcolor, + event->set_sky->bgcolor, + "custom" + ); + } + + delete event->set_sky; +} + +void Game::handleClientEvent_SetSun(ClientEvent *event, CameraOrientation *cam) +{ + sky->setSunVisible(event->sun_params->visible); + sky->setSunTexture(event->sun_params->texture, + event->sun_params->tonemap, texture_src); + sky->setSunScale(event->sun_params->scale); + sky->setSunriseVisible(event->sun_params->sunrise_visible); + sky->setSunriseTexture(event->sun_params->sunrise, texture_src); + delete event->sun_params; +} + +void Game::handleClientEvent_SetMoon(ClientEvent *event, CameraOrientation *cam) +{ + sky->setMoonVisible(event->moon_params->visible); + sky->setMoonTexture(event->moon_params->texture, + event->moon_params->tonemap, texture_src); + sky->setMoonScale(event->moon_params->scale); + delete event->moon_params; +} + +void Game::handleClientEvent_SetStars(ClientEvent *event, CameraOrientation *cam) +{ + sky->setStarsVisible(event->star_params->visible); + sky->setStarCount(event->star_params->count); + sky->setStarColor(event->star_params->starcolor); + sky->setStarScale(event->star_params->scale); + sky->setStarDayOpacity(event->star_params->day_opacity); + delete event->star_params; +} + +void Game::handleClientEvent_OverrideDayNigthRatio(ClientEvent *event, + CameraOrientation *cam) +{ + client->getEnv().setDayNightRatioOverride( + event->override_day_night_ratio.do_override, + event->override_day_night_ratio.ratio_f * 1000.0f); +} + +void Game::handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam) +{ + if (!clouds) + return; + + clouds->setDensity(event->cloud_params.density); + clouds->setColorBright(video::SColor(event->cloud_params.color_bright)); + clouds->setColorAmbient(video::SColor(event->cloud_params.color_ambient)); + clouds->setHeight(event->cloud_params.height); + clouds->setThickness(event->cloud_params.thickness); + clouds->setSpeed(v2f(event->cloud_params.speed_x, event->cloud_params.speed_y)); +} + +void Game::processClientEvents(CameraOrientation *cam) +{ + while (client->hasClientEvents()) { + std::unique_ptr<ClientEvent> event(client->getClientEvent()); + FATAL_ERROR_IF(event->type >= CLIENTEVENT_MAX, "Invalid clientevent type"); + const ClientEventHandler& evHandler = clientEventHandler[event->type]; + (this->*evHandler.handler)(event.get(), cam); + } +} + +void Game::updateChat(f32 dtime) +{ + // Get new messages from error log buffer + while (!m_chat_log_buf.empty()) + chat_backend->addMessage(L"", utf8_to_wide(m_chat_log_buf.get())); + + // Get new messages from client + std::wstring message; + while (client->getChatMessage(message)) { + chat_backend->addUnparsedMessage(message); + } + + // Remove old messages + chat_backend->step(dtime); + + // Display all messages in a static text element + auto &buf = chat_backend->getRecentBuffer(); + if (buf.getLinesModified()) { + buf.resetLinesModified(); + m_game_ui->setChatText(chat_backend->getRecentChat(), buf.getLineCount()); + } + + // Make sure that the size is still correct + m_game_ui->updateChatSize(); +} + +void Game::updateCamera(f32 dtime) +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + /* + For interaction purposes, get info about the held item + - What item is it? + - Is it a usable item? + - Can it point to liquids? + */ + ItemStack playeritem; + { + ItemStack selected, hand; + playeritem = player->getWieldedItem(&selected, &hand); + } + + ToolCapabilities playeritem_toolcap = + playeritem.getToolCapabilities(itemdef_manager); + + v3s16 old_camera_offset = camera->getOffset(); + + if (wasKeyDown(KeyType::CAMERA_MODE)) { + GenericCAO *playercao = player->getCAO(); + + // If playercao not loaded, don't change camera + if (!playercao) + return; + + camera->toggleCameraMode(); + + // Make the player visible depending on camera mode. + playercao->updateMeshCulling(); + playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST); + } + + float full_punch_interval = playeritem_toolcap.full_punch_interval; + float tool_reload_ratio = runData.time_from_last_punch / full_punch_interval; + + tool_reload_ratio = MYMIN(tool_reload_ratio, 1.0); + camera->update(player, dtime, tool_reload_ratio); + camera->step(dtime); + + v3f camera_position = camera->getPosition(); + v3f camera_direction = camera->getDirection(); + f32 camera_fov = camera->getFovMax(); + v3s16 camera_offset = camera->getOffset(); + + m_camera_offset_changed = (camera_offset != old_camera_offset); + + if (!m_flags.disable_camera_update) { + client->getEnv().getClientMap().updateCamera(camera_position, + camera_direction, camera_fov, camera_offset); + + if (m_camera_offset_changed) { + client->updateCameraOffset(camera_offset); + client->getEnv().updateCameraOffset(camera_offset); + + if (clouds) + clouds->updateCameraOffset(camera_offset); + } + } +} + + +void Game::updateSound(f32 dtime) +{ + // Update sound listener + v3s16 camera_offset = camera->getOffset(); + sound->updateListener(camera->getCameraNode()->getPosition() + intToFloat(camera_offset, BS), + v3f(0, 0, 0), // velocity + camera->getDirection(), + camera->getCameraNode()->getUpVector()); + + bool mute_sound = g_settings->getBool("mute_sound"); + if (mute_sound) { + sound->setListenerGain(0.0f); + } else { + // Check if volume is in the proper range, else fix it. + float old_volume = g_settings->getFloat("sound_volume"); + float new_volume = rangelim(old_volume, 0.0f, 1.0f); + sound->setListenerGain(new_volume); + + if (old_volume != new_volume) { + g_settings->setFloat("sound_volume", new_volume); + } + } + + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + // Tell the sound maker whether to make footstep sounds + soundmaker->makes_footstep_sound = player->makes_footstep_sound; + + // Update sound maker + if (player->makes_footstep_sound) + soundmaker->step(dtime); + + ClientMap &map = client->getEnv().getClientMap(); + MapNode n = map.getNode(player->getFootstepNodePos()); + soundmaker->m_player_step_sound = nodedef_manager->get(n).sound_footstep; +} + + +void Game::processPlayerInteraction(f32 dtime, bool show_hud) +{ + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + const v3f camera_direction = camera->getDirection(); + const v3s16 camera_offset = camera->getOffset(); + + /* + Calculate what block is the crosshair pointing to + */ + + ItemStack selected_item, hand_item; + const ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item); + + const ItemDefinition &selected_def = selected_item.getDefinition(itemdef_manager); + f32 d = getToolRange(selected_def, hand_item.getDefinition(itemdef_manager)); + + core::line3d<f32> shootline; + + switch (camera->getCameraMode()) { + case CAMERA_MODE_FIRST: + // Shoot from camera position, with bobbing + shootline.start = camera->getPosition(); + break; + case CAMERA_MODE_THIRD: + // Shoot from player head, no bobbing + shootline.start = camera->getHeadPosition(); + break; + case CAMERA_MODE_THIRD_FRONT: + shootline.start = camera->getHeadPosition(); + // prevent player pointing anything in front-view + d = 0; + break; + } + shootline.end = shootline.start + camera_direction * BS * d; + +#ifdef HAVE_TOUCHSCREENGUI + + if ((g_settings->getBool("touchtarget")) && (g_touchscreengui)) { + shootline = g_touchscreengui->getShootline(); + // Scale shootline to the acual distance the player can reach + shootline.end = shootline.start + + shootline.getVector().normalize() * BS * d; + shootline.start += intToFloat(camera_offset, BS); + shootline.end += intToFloat(camera_offset, BS); + } + +#endif + + PointedThing pointed = updatePointedThing(shootline, + selected_def.liquids_pointable, + !runData.btn_down_for_dig, + camera_offset); + + if (pointed != runData.pointed_old) + infostream << "Pointing at " << pointed.dump() << std::endl; + + // Note that updating the selection mesh every frame is not particularly efficient, + // but the halo rendering code is already inefficient so there's no point in optimizing it here + hud->updateSelectionMesh(camera_offset); + + // Allow digging again if button is not pressed + if (runData.digging_blocked && !isKeyDown(KeyType::DIG)) + runData.digging_blocked = false; + + /* + Stop digging when + - releasing dig button + - pointing away from node + */ + if (runData.digging) { + if (wasKeyReleased(KeyType::DIG)) { + infostream << "Dig button released (stopped digging)" << std::endl; + runData.digging = false; + } else if (pointed != runData.pointed_old) { + if (pointed.type == POINTEDTHING_NODE + && runData.pointed_old.type == POINTEDTHING_NODE + && pointed.node_undersurface + == runData.pointed_old.node_undersurface) { + // Still pointing to the same node, but a different face. + // Don't reset. + } else { + infostream << "Pointing away from node (stopped digging)" << std::endl; + runData.digging = false; + hud->updateSelectionMesh(camera_offset); + } + } + + if (!runData.digging) { + client->interact(INTERACT_STOP_DIGGING, runData.pointed_old); + client->setCrack(-1, v3s16(0, 0, 0)); + runData.dig_time = 0.0; + } + } else if (runData.dig_instantly && wasKeyReleased(KeyType::DIG)) { + // Remove e.g. torches faster when clicking instead of holding dig button + runData.nodig_delay_timer = 0; + runData.dig_instantly = false; + } + + if (!runData.digging && runData.btn_down_for_dig && !isKeyDown(KeyType::DIG)) + runData.btn_down_for_dig = false; + + runData.punching = false; + + soundmaker->m_player_leftpunch_sound.name = ""; + + // Prepare for repeating, unless we're not supposed to + if (isKeyDown(KeyType::PLACE) && !g_settings->getBool("safe_dig_and_place")) + runData.repeat_place_timer += dtime; + else + runData.repeat_place_timer = 0; + + if (selected_def.usable && isKeyDown(KeyType::DIG)) { + if (wasKeyPressed(KeyType::DIG) && (!client->modsLoaded() || + !client->getScript()->on_item_use(selected_item, pointed))) + client->interact(INTERACT_USE, pointed); + } else if (pointed.type == POINTEDTHING_NODE) { + handlePointingAtNode(pointed, selected_item, hand_item, dtime); + } else if (pointed.type == POINTEDTHING_OBJECT) { + v3f player_position = player->getPosition(); + bool basic_debug_allowed = client->checkPrivilege("debug") || (player->hud_flags & HUD_FLAG_BASIC_DEBUG); + handlePointingAtObject(pointed, tool_item, player_position, + m_game_ui->m_flags.show_basic_debug && basic_debug_allowed); + } else if (isKeyDown(KeyType::DIG)) { + // When button is held down in air, show continuous animation + runData.punching = true; + // Run callback even though item is not usable + if (wasKeyPressed(KeyType::DIG) && client->modsLoaded()) + client->getScript()->on_item_use(selected_item, pointed); + } else if (wasKeyPressed(KeyType::PLACE)) { + handlePointingAtNothing(selected_item); + } + + runData.pointed_old = pointed; + + if (runData.punching || wasKeyPressed(KeyType::DIG)) + camera->setDigging(0); // dig animation + + input->clearWasKeyPressed(); + input->clearWasKeyReleased(); + // Ensure DIG & PLACE are marked as handled + wasKeyDown(KeyType::DIG); + wasKeyDown(KeyType::PLACE); + + input->joystick.clearWasKeyPressed(KeyType::DIG); + input->joystick.clearWasKeyPressed(KeyType::PLACE); + + input->joystick.clearWasKeyReleased(KeyType::DIG); + input->joystick.clearWasKeyReleased(KeyType::PLACE); +} + + +PointedThing Game::updatePointedThing( + const core::line3d<f32> &shootline, + bool liquids_pointable, + bool look_for_object, + const v3s16 &camera_offset) +{ + std::vector<aabb3f> *selectionboxes = hud->getSelectionBoxes(); + selectionboxes->clear(); + hud->setSelectedFaceNormal(v3f(0.0, 0.0, 0.0)); + static thread_local const bool show_entity_selectionbox = g_settings->getBool( + "show_entity_selectionbox"); + + ClientEnvironment &env = client->getEnv(); + ClientMap &map = env.getClientMap(); + const NodeDefManager *nodedef = map.getNodeDefManager(); + + runData.selected_object = NULL; + hud->pointing_at_object = false; + + RaycastState s(shootline, look_for_object, liquids_pointable); + PointedThing result; + env.continueRaycast(&s, &result); + if (result.type == POINTEDTHING_OBJECT) { + hud->pointing_at_object = true; + + runData.selected_object = client->getEnv().getActiveObject(result.object_id); + aabb3f selection_box; + if (show_entity_selectionbox && runData.selected_object->doShowSelectionBox() && + runData.selected_object->getSelectionBox(&selection_box)) { + v3f pos = runData.selected_object->getPosition(); + selectionboxes->push_back(aabb3f(selection_box)); + hud->setSelectionPos(pos, camera_offset); + } + } else if (result.type == POINTEDTHING_NODE) { + // Update selection boxes + MapNode n = map.getNode(result.node_undersurface); + std::vector<aabb3f> boxes; + n.getSelectionBoxes(nodedef, &boxes, + n.getNeighbors(result.node_undersurface, &map)); + + f32 d = 0.002 * BS; + for (std::vector<aabb3f>::const_iterator i = boxes.begin(); + i != boxes.end(); ++i) { + aabb3f box = *i; + box.MinEdge -= v3f(d, d, d); + box.MaxEdge += v3f(d, d, d); + selectionboxes->push_back(box); + } + hud->setSelectionPos(intToFloat(result.node_undersurface, BS), + camera_offset); + hud->setSelectedFaceNormal(v3f( + result.intersection_normal.X, + result.intersection_normal.Y, + result.intersection_normal.Z)); + } + + // Update selection mesh light level and vertex colors + if (!selectionboxes->empty()) { + v3f pf = hud->getSelectionPos(); + v3s16 p = floatToInt(pf, BS); + + // Get selection mesh light level + MapNode n = map.getNode(p); + u16 node_light = getInteriorLight(n, -1, nodedef); + u16 light_level = node_light; + + for (const v3s16 &dir : g_6dirs) { + n = map.getNode(p + dir); + node_light = getInteriorLight(n, -1, nodedef); + if (node_light > light_level) + light_level = node_light; + } + + u32 daynight_ratio = client->getEnv().getDayNightRatio(); + video::SColor c; + final_color_blend(&c, light_level, daynight_ratio); + + // Modify final color a bit with time + u32 timer = porting::getTimeMs() % 5000; + float timerf = (float) (irr::core::PI * ((timer / 2500.0) - 0.5)); + float sin_r = 0.08f * std::sin(timerf); + float sin_g = 0.08f * std::sin(timerf + irr::core::PI * 0.5f); + float sin_b = 0.08f * std::sin(timerf + irr::core::PI); + c.setRed(core::clamp(core::round32(c.getRed() * (0.8 + sin_r)), 0, 255)); + c.setGreen(core::clamp(core::round32(c.getGreen() * (0.8 + sin_g)), 0, 255)); + c.setBlue(core::clamp(core::round32(c.getBlue() * (0.8 + sin_b)), 0, 255)); + + // Set mesh final color + hud->setSelectionMeshColor(c); + } + return result; +} + + +void Game::handlePointingAtNothing(const ItemStack &playerItem) +{ + infostream << "Attempted to place item while pointing at nothing" << std::endl; + PointedThing fauxPointed; + fauxPointed.type = POINTEDTHING_NOTHING; + client->interact(INTERACT_ACTIVATE, fauxPointed); +} + + +void Game::handlePointingAtNode(const PointedThing &pointed, + const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime) +{ + v3s16 nodepos = pointed.node_undersurface; + v3s16 neighbourpos = pointed.node_abovesurface; + + /* + Check information text of node + */ + + ClientMap &map = client->getEnv().getClientMap(); + + if (runData.nodig_delay_timer <= 0.0 && isKeyDown(KeyType::DIG) + && !runData.digging_blocked + && client->checkPrivilege("interact")) { + handleDigging(pointed, nodepos, selected_item, hand_item, dtime); + } + + // This should be done after digging handling + NodeMetadata *meta = map.getNodeMetadata(nodepos); + + if (meta) { + m_game_ui->setInfoText(unescape_translate(utf8_to_wide( + meta->getString("infotext")))); + } else { + MapNode n = map.getNode(nodepos); + + if (nodedef_manager->get(n).name == "unknown") { + m_game_ui->setInfoText(L"Unknown node"); + } + } + + if ((wasKeyPressed(KeyType::PLACE) || + runData.repeat_place_timer >= m_repeat_place_time) && + client->checkPrivilege("interact")) { + runData.repeat_place_timer = 0; + infostream << "Place button pressed while looking at ground" << std::endl; + + // Placing animation (always shown for feedback) + camera->setDigging(1); + + soundmaker->m_player_rightpunch_sound = SimpleSoundSpec(); + + // If the wielded item has node placement prediction, + // make that happen + // And also set the sound and send the interact + // But first check for meta formspec and rightclickable + auto &def = selected_item.getDefinition(itemdef_manager); + bool placed = nodePlacement(def, selected_item, nodepos, neighbourpos, + pointed, meta); + + if (placed && client->modsLoaded()) + client->getScript()->on_placenode(pointed, def); + } +} + +bool Game::nodePlacement(const ItemDefinition &selected_def, + const ItemStack &selected_item, const v3s16 &nodepos, const v3s16 &neighbourpos, + const PointedThing &pointed, const NodeMetadata *meta) +{ + const auto &prediction = selected_def.node_placement_prediction; + + const NodeDefManager *nodedef = client->ndef(); + ClientMap &map = client->getEnv().getClientMap(); + MapNode node; + bool is_valid_position; + + node = map.getNode(nodepos, &is_valid_position); + if (!is_valid_position) { + soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed; + return false; + } + + // formspec in meta + if (meta && !meta->getString("formspec").empty() && !input->isRandom() + && !isKeyDown(KeyType::SNEAK)) { + // on_rightclick callbacks are called anyway + if (nodedef_manager->get(map.getNode(nodepos)).rightclickable) + client->interact(INTERACT_PLACE, pointed); + + infostream << "Launching custom inventory view" << std::endl; + + InventoryLocation inventoryloc; + inventoryloc.setNodeMeta(nodepos); + + NodeMetadataFormSource *fs_src = new NodeMetadataFormSource( + &client->getEnv().getClientMap(), nodepos); + TextDest *txt_dst = new TextDestNodeMetadata(nodepos, client); + + auto *&formspec = m_game_ui->updateFormspec(""); + GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(), + &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound); + + formspec->setFormSpec(meta->getString("formspec"), inventoryloc); + return false; + } + + // on_rightclick callback + if (prediction.empty() || (nodedef->get(node).rightclickable && + !isKeyDown(KeyType::SNEAK))) { + // Report to server + client->interact(INTERACT_PLACE, pointed); + return false; + } + + verbosestream << "Node placement prediction for " + << selected_def.name << " is " << prediction << std::endl; + v3s16 p = neighbourpos; + + // Place inside node itself if buildable_to + MapNode n_under = map.getNode(nodepos, &is_valid_position); + if (is_valid_position) { + if (nodedef->get(n_under).buildable_to) { + p = nodepos; + } else { + node = map.getNode(p, &is_valid_position); + if (is_valid_position && !nodedef->get(node).buildable_to) { + soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed; + // Report to server + client->interact(INTERACT_PLACE, pointed); + return false; + } + } + } + + // Find id of predicted node + content_t id; + bool found = nodedef->getId(prediction, id); + + if (!found) { + errorstream << "Node placement prediction failed for " + << selected_def.name << " (places " << prediction + << ") - Name not known" << std::endl; + // Handle this as if prediction was empty + // Report to server + client->interact(INTERACT_PLACE, pointed); + return false; + } + + const ContentFeatures &predicted_f = nodedef->get(id); + + // Predict param2 for facedir and wallmounted nodes + // Compare core.item_place_node() for what the server does + u8 param2 = 0; + + const u8 place_param2 = selected_def.place_param2; + + if (place_param2) { + param2 = place_param2; + } else if (predicted_f.param_type_2 == CPT2_WALLMOUNTED || + predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED) { + v3s16 dir = nodepos - neighbourpos; + + if (abs(dir.Y) > MYMAX(abs(dir.X), abs(dir.Z))) { + param2 = dir.Y < 0 ? 1 : 0; + } else if (abs(dir.X) > abs(dir.Z)) { + param2 = dir.X < 0 ? 3 : 2; + } else { + param2 = dir.Z < 0 ? 5 : 4; + } + } else if (predicted_f.param_type_2 == CPT2_FACEDIR || + predicted_f.param_type_2 == CPT2_COLORED_FACEDIR) { + v3s16 dir = nodepos - floatToInt(client->getEnv().getLocalPlayer()->getPosition(), BS); + + if (abs(dir.X) > abs(dir.Z)) { + param2 = dir.X < 0 ? 3 : 1; + } else { + param2 = dir.Z < 0 ? 2 : 0; + } + } + + // Check attachment if node is in group attached_node + if (itemgroup_get(predicted_f.groups, "attached_node") != 0) { + const static v3s16 wallmounted_dirs[8] = { + v3s16(0, 1, 0), + v3s16(0, -1, 0), + v3s16(1, 0, 0), + v3s16(-1, 0, 0), + v3s16(0, 0, 1), + v3s16(0, 0, -1), + }; + v3s16 pp; + + if (predicted_f.param_type_2 == CPT2_WALLMOUNTED || + predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED) + pp = p + wallmounted_dirs[param2]; + else + pp = p + v3s16(0, -1, 0); + + if (!nodedef->get(map.getNode(pp)).walkable) { + soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed; + // Report to server + client->interact(INTERACT_PLACE, pointed); + return false; + } + } + + // Apply color + if (!place_param2 && (predicted_f.param_type_2 == CPT2_COLOR + || predicted_f.param_type_2 == CPT2_COLORED_FACEDIR + || predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) { + const auto &indexstr = selected_item.metadata. + getString("palette_index", 0); + if (!indexstr.empty()) { + s32 index = mystoi(indexstr); + if (predicted_f.param_type_2 == CPT2_COLOR) { + param2 = index; + } else if (predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED) { + // param2 = pure palette index + other + param2 = (index & 0xf8) | (param2 & 0x07); + } else if (predicted_f.param_type_2 == CPT2_COLORED_FACEDIR) { + // param2 = pure palette index + other + param2 = (index & 0xe0) | (param2 & 0x1f); + } + } + } + + // Add node to client map + MapNode n(id, 0, param2); + + try { + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + // Dont place node when player would be inside new node + // NOTE: This is to be eventually implemented by a mod as client-side Lua + if (!nodedef->get(n).walkable || + g_settings->getBool("enable_build_where_you_stand") || + (client->checkPrivilege("noclip") && g_settings->getBool("noclip")) || + (nodedef->get(n).walkable && + neighbourpos != player->getStandingNodePos() + v3s16(0, 1, 0) && + neighbourpos != player->getStandingNodePos() + v3s16(0, 2, 0))) { + // This triggers the required mesh update too + client->addNode(p, n); + // Report to server + client->interact(INTERACT_PLACE, pointed); + // A node is predicted, also play a sound + soundmaker->m_player_rightpunch_sound = selected_def.sound_place; + return true; + } else { + soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed; + return false; + } + } catch (const InvalidPositionException &e) { + errorstream << "Node placement prediction failed for " + << selected_def.name << " (places " + << prediction << ") - Position not loaded" << std::endl; + soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed; + return false; + } +} + +void Game::handlePointingAtObject(const PointedThing &pointed, + const ItemStack &tool_item, const v3f &player_position, bool show_debug) +{ + std::wstring infotext = unescape_translate( + utf8_to_wide(runData.selected_object->infoText())); + + if (show_debug) { + if (!infotext.empty()) { + infotext += L"\n"; + } + infotext += utf8_to_wide(runData.selected_object->debugInfoText()); + } + + m_game_ui->setInfoText(infotext); + + if (isKeyDown(KeyType::DIG)) { + bool do_punch = false; + bool do_punch_damage = false; + + if (runData.object_hit_delay_timer <= 0.0) { + do_punch = true; + do_punch_damage = true; + runData.object_hit_delay_timer = object_hit_delay; + } + + if (wasKeyPressed(KeyType::DIG)) + do_punch = true; + + if (do_punch) { + infostream << "Punched object" << std::endl; + runData.punching = true; + } + + if (do_punch_damage) { + // Report direct punch + v3f objpos = runData.selected_object->getPosition(); + v3f dir = (objpos - player_position).normalize(); + + bool disable_send = runData.selected_object->directReportPunch( + dir, &tool_item, runData.time_from_last_punch); + runData.time_from_last_punch = 0; + + if (!disable_send) + client->interact(INTERACT_START_DIGGING, pointed); + } + } else if (wasKeyDown(KeyType::PLACE)) { + infostream << "Pressed place button while pointing at object" << std::endl; + client->interact(INTERACT_PLACE, pointed); // place + } +} + + +void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos, + const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime) +{ + // See also: serverpackethandle.cpp, action == 2 + LocalPlayer *player = client->getEnv().getLocalPlayer(); + ClientMap &map = client->getEnv().getClientMap(); + MapNode n = client->getEnv().getClientMap().getNode(nodepos); + + // NOTE: Similar piece of code exists on the server side for + // cheat detection. + // Get digging parameters + DigParams params = getDigParams(nodedef_manager->get(n).groups, + &selected_item.getToolCapabilities(itemdef_manager), + selected_item.wear); + + // If can't dig, try hand + if (!params.diggable) { + params = getDigParams(nodedef_manager->get(n).groups, + &hand_item.getToolCapabilities(itemdef_manager)); + } + + if (!params.diggable) { + // I guess nobody will wait for this long + runData.dig_time_complete = 10000000.0; + } else { + runData.dig_time_complete = params.time; + + if (m_cache_enable_particles) { + const ContentFeatures &features = client->getNodeDefManager()->get(n); + client->getParticleManager()->addNodeParticle(client, + player, nodepos, n, features); + } + } + + if (!runData.digging) { + infostream << "Started digging" << std::endl; + runData.dig_instantly = runData.dig_time_complete == 0; + if (client->modsLoaded() && client->getScript()->on_punchnode(nodepos, n)) + return; + client->interact(INTERACT_START_DIGGING, pointed); + runData.digging = true; + runData.btn_down_for_dig = true; + } + + if (!runData.dig_instantly) { + runData.dig_index = (float)crack_animation_length + * runData.dig_time + / runData.dig_time_complete; + } else { + // This is for e.g. torches + runData.dig_index = crack_animation_length; + } + + SimpleSoundSpec sound_dig = nodedef_manager->get(n).sound_dig; + + if (sound_dig.exists() && params.diggable) { + if (sound_dig.name == "__group") { + if (!params.main_group.empty()) { + soundmaker->m_player_leftpunch_sound.gain = 0.5; + soundmaker->m_player_leftpunch_sound.name = + std::string("default_dig_") + + params.main_group; + } + } else { + soundmaker->m_player_leftpunch_sound = sound_dig; + } + } + + // Don't show cracks if not diggable + if (runData.dig_time_complete >= 100000.0) { + } else if (runData.dig_index < crack_animation_length) { + //TimeTaker timer("client.setTempMod"); + //infostream<<"dig_index="<<dig_index<<std::endl; + client->setCrack(runData.dig_index, nodepos); + } else { + infostream << "Digging completed" << std::endl; + client->setCrack(-1, v3s16(0, 0, 0)); + + runData.dig_time = 0; + runData.digging = false; + // we successfully dug, now block it from repeating if we want to be safe + if (g_settings->getBool("safe_dig_and_place")) + runData.digging_blocked = true; + + runData.nodig_delay_timer = + runData.dig_time_complete / (float)crack_animation_length; + + // We don't want a corresponding delay to very time consuming nodes + // and nodes without digging time (e.g. torches) get a fixed delay. + if (runData.nodig_delay_timer > 0.3) + runData.nodig_delay_timer = 0.3; + else if (runData.dig_instantly) + runData.nodig_delay_timer = 0.15; + + bool is_valid_position; + MapNode wasnode = map.getNode(nodepos, &is_valid_position); + if (is_valid_position) { + if (client->modsLoaded() && + client->getScript()->on_dignode(nodepos, wasnode)) { + return; + } + + const ContentFeatures &f = client->ndef()->get(wasnode); + if (f.node_dig_prediction == "air") { + client->removeNode(nodepos); + } else if (!f.node_dig_prediction.empty()) { + content_t id; + bool found = client->ndef()->getId(f.node_dig_prediction, id); + if (found) + client->addNode(nodepos, id, true); + } + // implicit else: no prediction + } + + client->interact(INTERACT_DIGGING_COMPLETED, pointed); + + if (m_cache_enable_particles) { + const ContentFeatures &features = + client->getNodeDefManager()->get(wasnode); + client->getParticleManager()->addDiggingParticles(client, + player, nodepos, wasnode, features); + } + + + // Send event to trigger sound + client->getEventManager()->put(new NodeDugEvent(nodepos, wasnode)); + } + + if (runData.dig_time_complete < 100000.0) { + runData.dig_time += dtime; + } else { + runData.dig_time = 0; + client->setCrack(-1, nodepos); + } + + camera->setDigging(0); // Dig animation +} + +void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime, + const CameraOrientation &cam) +{ + TimeTaker tt_update("Game::updateFrame()"); + LocalPlayer *player = client->getEnv().getLocalPlayer(); + + /* + Fog range + */ + + if (draw_control->range_all) { + runData.fog_range = 100000 * BS; + } else { + runData.fog_range = draw_control->wanted_range * BS; + } + + /* + Calculate general brightness + */ + u32 daynight_ratio = client->getEnv().getDayNightRatio(); + float time_brightness = decode_light_f((float)daynight_ratio / 1000.0); + float direct_brightness; + bool sunlight_seen; + + // When in noclip mode force same sky brightness as above ground so you + // can see properly + if (draw_control->allow_noclip && m_cache_enable_free_move && + client->checkPrivilege("fly")) { + direct_brightness = time_brightness; + sunlight_seen = true; + } else { + float old_brightness = sky->getBrightness(); + direct_brightness = client->getEnv().getClientMap() + .getBackgroundBrightness(MYMIN(runData.fog_range * 1.2, 60 * BS), + daynight_ratio, (int)(old_brightness * 255.5), &sunlight_seen) + / 255.0; + } + + float time_of_day_smooth = runData.time_of_day_smooth; + float time_of_day = client->getEnv().getTimeOfDayF(); + + static const float maxsm = 0.05f; + static const float todsm = 0.05f; + + if (std::fabs(time_of_day - time_of_day_smooth) > maxsm && + std::fabs(time_of_day - time_of_day_smooth + 1.0) > maxsm && + std::fabs(time_of_day - time_of_day_smooth - 1.0) > maxsm) + time_of_day_smooth = time_of_day; + + if (time_of_day_smooth > 0.8 && time_of_day < 0.2) + time_of_day_smooth = time_of_day_smooth * (1.0 - todsm) + + (time_of_day + 1.0) * todsm; + else + time_of_day_smooth = time_of_day_smooth * (1.0 - todsm) + + time_of_day * todsm; + + runData.time_of_day_smooth = time_of_day_smooth; + + sky->update(time_of_day_smooth, time_brightness, direct_brightness, + sunlight_seen, camera->getCameraMode(), player->getYaw(), + player->getPitch()); + + /* + Update clouds + */ + if (clouds) { + if (sky->getCloudsVisible()) { + clouds->setVisible(true); + clouds->step(dtime); + // camera->getPosition is not enough for 3rd person views + v3f camera_node_position = camera->getCameraNode()->getPosition(); + v3s16 camera_offset = camera->getOffset(); + camera_node_position.X = camera_node_position.X + camera_offset.X * BS; + camera_node_position.Y = camera_node_position.Y + camera_offset.Y * BS; + camera_node_position.Z = camera_node_position.Z + camera_offset.Z * BS; + clouds->update(camera_node_position, + sky->getCloudColor()); + if (clouds->isCameraInsideCloud() && m_cache_enable_fog) { + // if inside clouds, and fog enabled, use that as sky + // color(s) + video::SColor clouds_dark = clouds->getColor() + .getInterpolated(video::SColor(255, 0, 0, 0), 0.9); + sky->overrideColors(clouds_dark, clouds->getColor()); + sky->setInClouds(true); + runData.fog_range = std::fmin(runData.fog_range * 0.5f, 32.0f * BS); + // do not draw clouds after all + clouds->setVisible(false); + } + } else { + clouds->setVisible(false); + } + } + + /* + Update particles + */ + client->getParticleManager()->step(dtime); + + /* + Fog + */ + + if (m_cache_enable_fog) { + driver->setFog( + sky->getBgColor(), + video::EFT_FOG_LINEAR, + runData.fog_range * m_cache_fog_start, + runData.fog_range * 1.0, + 0.01, + false, // pixel fog + true // range fog + ); + } else { + driver->setFog( + sky->getBgColor(), + video::EFT_FOG_LINEAR, + 100000 * BS, + 110000 * BS, + 0.01f, + false, // pixel fog + false // range fog + ); + } + + /* + Damage camera tilt + */ + if (player->hurt_tilt_timer > 0.0f) { + player->hurt_tilt_timer -= dtime * 6.0f; + + if (player->hurt_tilt_timer < 0.0f) + player->hurt_tilt_strength = 0.0f; + } + + /* + Update minimap pos and rotation + */ + if (mapper && m_game_ui->m_flags.show_hud) { + mapper->setPos(floatToInt(player->getPosition(), BS)); + mapper->setAngle(player->getYaw()); + } + + /* + Get chat messages from client + */ + + updateChat(dtime); + + /* + Inventory + */ + + if (player->getWieldIndex() != runData.new_playeritem) + client->setPlayerItem(runData.new_playeritem); + + if (client->updateWieldedItem()) { + // Update wielded tool + ItemStack selected_item, hand_item; + ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item); + camera->wield(tool_item); + } + + /* + Update block draw list every 200ms or when camera direction has + changed much + */ + runData.update_draw_list_timer += dtime; + + float update_draw_list_delta = 0.2f; + + v3f camera_direction = camera->getDirection(); + if (runData.update_draw_list_timer >= update_draw_list_delta + || runData.update_draw_list_last_cam_dir.getDistanceFrom(camera_direction) > 0.2 + || m_camera_offset_changed + || client->getEnv().getClientMap().needsUpdateDrawList()) { + runData.update_draw_list_timer = 0; + client->getEnv().getClientMap().updateDrawList(); + runData.update_draw_list_last_cam_dir = camera_direction; + } + + if (RenderingEngine::get_shadow_renderer()) { + updateShadows(); + } + + m_game_ui->update(*stats, client, draw_control, cam, runData.pointed_old, gui_chat_console, dtime); + + /* + make sure menu is on top + 1. Delete formspec menu reference if menu was removed + 2. Else, make sure formspec menu is on top + */ + auto formspec = m_game_ui->getFormspecGUI(); + do { // breakable. only runs for one iteration + if (!formspec) + break; + + if (formspec->getReferenceCount() == 1) { + m_game_ui->deleteFormspec(); + break; + } + + auto &loc = formspec->getFormspecLocation(); + if (loc.type == InventoryLocation::NODEMETA) { + NodeMetadata *meta = client->getEnv().getClientMap().getNodeMetadata(loc.p); + if (!meta || meta->getString("formspec").empty()) { + formspec->quitMenu(); + break; + } + } + + if (isMenuActive()) + guiroot->bringToFront(formspec); + } while (false); + + /* + ==================== Drawing begins ==================== + */ + const video::SColor skycolor = sky->getSkyColor(); + + TimeTaker tt_draw("Draw scene", nullptr, PRECISION_MICRO); + driver->beginScene(true, true, skycolor); + + bool draw_wield_tool = (m_game_ui->m_flags.show_hud && + (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) && + (camera->getCameraMode() == CAMERA_MODE_FIRST)); + bool draw_crosshair = ( + (player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) && + (camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT)); +#ifdef HAVE_TOUCHSCREENGUI + try { + draw_crosshair = !g_settings->getBool("touchtarget"); + } catch (SettingNotFoundException) { + } +#endif + m_rendering_engine->draw_scene(skycolor, m_game_ui->m_flags.show_hud, + m_game_ui->m_flags.show_minimap, draw_wield_tool, draw_crosshair); + + /* + Profiler graph + */ + v2u32 screensize = driver->getScreenSize(); + + if (m_game_ui->m_flags.show_profiler_graph) + graph->draw(10, screensize.Y - 10, driver, g_fontengine->getFont()); + + /* + Damage flash + */ + if (runData.damage_flash > 0.0f) { + video::SColor color(runData.damage_flash, 180, 0, 0); + driver->draw2DRectangle(color, + core::rect<s32>(0, 0, screensize.X, screensize.Y), + NULL); + + runData.damage_flash -= 384.0f * dtime; + } + + /* + ==================== End scene ==================== + */ +#if IRRLICHT_VERSION_MT_REVISION < 5 + if (++m_reset_HW_buffer_counter > 500) { + /* + Periodically remove all mesh HW buffers. + + Work around for a quirk in Irrlicht where a HW buffer is only + released after 20000 iterations (triggered from endScene()). + + Without this, all loaded but unused meshes will retain their HW + buffers for at least 5 minutes, at which point looking up the HW buffers + becomes a bottleneck and the framerate drops (as much as 30%). + + Tests showed that numbers between 50 and 1000 are good, so picked 500. + There are no other public Irrlicht APIs that allow interacting with the + HW buffers without tracking the status of every individual mesh. + + The HW buffers for _visible_ meshes will be reinitialized in the next frame. + */ + infostream << "Game::updateFrame(): Removing all HW buffers." << std::endl; + driver->removeAllHardwareBuffers(); + m_reset_HW_buffer_counter = 0; + } +#endif + + driver->endScene(); + + stats->drawtime = tt_draw.stop(true); + g_profiler->graphAdd("Draw scene [us]", stats->drawtime); + g_profiler->avg("Game::updateFrame(): update frame [ms]", tt_update.stop(true)); +} + +/* Log times and stuff for visualization */ +inline void Game::updateProfilerGraphs(ProfilerGraph *graph) +{ + Profiler::GraphValues values; + g_profiler->graphGet(values); + graph->put(values); +} + +/**************************************************************************** + * Shadows + *****************************************************************************/ +void Game::updateShadows() +{ + ShadowRenderer *shadow = RenderingEngine::get_shadow_renderer(); + if (!shadow) + return; + + float in_timeofday = fmod(runData.time_of_day_smooth, 1.0f); + + float timeoftheday = getWickedTimeOfDay(in_timeofday); + bool is_day = timeoftheday > 0.25 && timeoftheday < 0.75; + bool is_shadow_visible = is_day ? sky->getSunVisible() : sky->getMoonVisible(); + shadow->setShadowIntensity(is_shadow_visible ? client->getEnv().getLocalPlayer()->getLighting().shadow_intensity : 0.0f); + + timeoftheday = fmod(timeoftheday + 0.75f, 0.5f) + 0.25f; + const float offset_constant = 10000.0f; + + v3f light(0.0f, 0.0f, -1.0f); + light.rotateXZBy(90); + light.rotateXYBy(timeoftheday * 360 - 90); + light.rotateYZBy(sky->getSkyBodyOrbitTilt()); + + v3f sun_pos = light * offset_constant; + + if (shadow->getDirectionalLightCount() == 0) + shadow->addDirectionalLight(); + shadow->getDirectionalLight().setDirection(sun_pos); + shadow->setTimeOfDay(in_timeofday); + + shadow->getDirectionalLight().update_frustum(camera, client, m_camera_offset_changed); +} + +/**************************************************************************** + Misc + ****************************************************************************/ + +void FpsControl::reset() +{ + last_time = porting::getTimeUs(); +} + +/* + * On some computers framerate doesn't seem to be automatically limited + */ +void FpsControl::limit(IrrlichtDevice *device, f32 *dtime) +{ + const float fps_limit = (device->isWindowFocused() && !g_menumgr.pausesGame()) + ? g_settings->getFloat("fps_max") + : g_settings->getFloat("fps_max_unfocused"); + const u64 frametime_min = 1000000.0f / std::max(fps_limit, 1.0f); + + u64 time = porting::getTimeUs(); + + if (time > last_time) // Make sure time hasn't overflowed + busy_time = time - last_time; + else + busy_time = 0; + + if (busy_time < frametime_min) { + sleep_time = frametime_min - busy_time; + if (sleep_time > 1000) + sleep_ms(sleep_time / 1000); + } else { + sleep_time = 0; + } + + // Read the timer again to accurately determine how long we actually slept, + // rather than calculating it by adding sleep_time to time. + time = porting::getTimeUs(); + + if (time > last_time) // Make sure last_time hasn't overflowed + *dtime = (time - last_time) / 1000000.0f; + else + *dtime = 0; + + last_time = time; +} + +void Game::showOverlayMessage(const char *msg, float dtime, int percent, bool draw_clouds) +{ + const wchar_t *wmsg = wgettext(msg); + m_rendering_engine->draw_load_screen(wmsg, guienv, texture_src, dtime, percent, + draw_clouds); + delete[] wmsg; +} + +void Game::settingChangedCallback(const std::string &setting_name, void *data) +{ + ((Game *)data)->readSettings(); +} + +void Game::readSettings() +{ + m_cache_doubletap_jump = g_settings->getBool("doubletap_jump"); + m_cache_enable_clouds = g_settings->getBool("enable_clouds"); + m_cache_enable_joysticks = g_settings->getBool("enable_joysticks"); + m_cache_enable_particles = g_settings->getBool("enable_particles"); + m_cache_enable_fog = g_settings->getBool("enable_fog"); + m_cache_mouse_sensitivity = g_settings->getFloat("mouse_sensitivity", 0.001f, 10.0f); + m_cache_joystick_frustum_sensitivity = std::max(g_settings->getFloat("joystick_frustum_sensitivity"), 0.001f); + m_repeat_place_time = g_settings->getFloat("repeat_place_time", 0.25f, 2.0); + + m_cache_enable_noclip = g_settings->getBool("noclip"); + m_cache_enable_free_move = g_settings->getBool("free_move"); + + m_cache_fog_start = g_settings->getFloat("fog_start"); + + m_cache_cam_smoothing = 0; + if (g_settings->getBool("cinematic")) + m_cache_cam_smoothing = 1 - g_settings->getFloat("cinematic_camera_smoothing"); + else + m_cache_cam_smoothing = 1 - g_settings->getFloat("camera_smoothing"); + + m_cache_fog_start = rangelim(m_cache_fog_start, 0.0f, 0.99f); + m_cache_cam_smoothing = rangelim(m_cache_cam_smoothing, 0.01f, 1.0f); + m_cache_mouse_sensitivity = rangelim(m_cache_mouse_sensitivity, 0.001, 100.0); + + m_does_lost_focus_pause_game = g_settings->getBool("pause_on_lost_focus"); +} + +/****************************************************************************/ +/**************************************************************************** + Shutdown / cleanup + ****************************************************************************/ +/****************************************************************************/ + +void Game::showDeathFormspec() +{ + static std::string formspec_str = + std::string("formspec_version[1]") + + SIZE_TAG + "bgcolor[#320000b4;true]" + "label[4.85,1.35;" + gettext("You died") + "]" + "button_exit[4,3;3,0.5;btn_respawn;" + gettext("Respawn") + "]" + ; + + /* Create menu */ + /* Note: FormspecFormSource and LocalFormspecHandler * + * are deleted by guiFormSpecMenu */ + FormspecFormSource *fs_src = new FormspecFormSource(formspec_str); + LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client); + + auto *&formspec = m_game_ui->getFormspecGUI(); + GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(), + &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound); + formspec->setFocus("btn_respawn"); +} + +#define GET_KEY_NAME(KEY) gettext(getKeySetting(#KEY).name()) +void Game::showPauseMenu() +{ +#ifdef HAVE_TOUCHSCREENGUI + static const std::string control_text = strgettext("Default Controls:\n" + "No menu visible:\n" + "- single tap: button activate\n" + "- double tap: place/use\n" + "- slide finger: look around\n" + "Menu/Inventory visible:\n" + "- double tap (outside):\n" + " -->close\n" + "- touch stack, touch slot:\n" + " --> move stack\n" + "- touch&drag, tap 2nd finger\n" + " --> place single item to slot\n" + ); +#else + static const std::string control_text_template = strgettext("Controls:\n" + "- %s: move forwards\n" + "- %s: move backwards\n" + "- %s: move left\n" + "- %s: move right\n" + "- %s: jump/climb up\n" + "- %s: dig/punch\n" + "- %s: place/use\n" + "- %s: sneak/climb down\n" + "- %s: drop item\n" + "- %s: inventory\n" + "- Mouse: turn/look\n" + "- Mouse wheel: select item\n" + "- %s: chat\n" + ); + + char control_text_buf[600]; + + porting::mt_snprintf(control_text_buf, sizeof(control_text_buf), control_text_template.c_str(), + GET_KEY_NAME(keymap_forward), + GET_KEY_NAME(keymap_backward), + GET_KEY_NAME(keymap_left), + GET_KEY_NAME(keymap_right), + GET_KEY_NAME(keymap_jump), + GET_KEY_NAME(keymap_dig), + GET_KEY_NAME(keymap_place), + GET_KEY_NAME(keymap_sneak), + GET_KEY_NAME(keymap_drop), + GET_KEY_NAME(keymap_inventory), + GET_KEY_NAME(keymap_chat) + ); + + std::string control_text = std::string(control_text_buf); + str_formspec_escape(control_text); +#endif + + float ypos = simple_singleplayer_mode ? 0.7f : 0.1f; + std::ostringstream os; + + os << "formspec_version[1]" << SIZE_TAG + << "button_exit[4," << (ypos++) << ";3,0.5;btn_continue;" + << strgettext("Continue") << "]"; + + if (!simple_singleplayer_mode) { + os << "button_exit[4," << (ypos++) << ";3,0.5;btn_change_password;" + << strgettext("Change Password") << "]"; + } else { + os << "field[4.95,0;5,1.5;;" << strgettext("Game paused") << ";]"; + } + +#ifndef __ANDROID__ +#if USE_SOUND + if (g_settings->getBool("enable_sound")) { + os << "button_exit[4," << (ypos++) << ";3,0.5;btn_sound;" + << strgettext("Sound Volume") << "]"; + } +#endif + os << "button_exit[4," << (ypos++) << ";3,0.5;btn_key_config;" + << strgettext("Change Keys") << "]"; +#endif + os << "button_exit[4," << (ypos++) << ";3,0.5;btn_exit_menu;" + << strgettext("Exit to Menu") << "]"; + os << "button_exit[4," << (ypos++) << ";3,0.5;btn_exit_os;" + << strgettext("Exit to OS") << "]" + << "textarea[7.5,0.25;3.9,6.25;;" << control_text << ";]" + << "textarea[0.4,0.25;3.9,6.25;;" << PROJECT_NAME_C " " VERSION_STRING "\n" + << "\n" + << strgettext("Game info:") << "\n"; + const std::string &address = client->getAddressName(); + static const std::string mode = strgettext("- Mode: "); + if (!simple_singleplayer_mode) { + Address serverAddress = client->getServerAddress(); + if (!address.empty()) { + os << mode << strgettext("Remote server") << "\n" + << strgettext("- Address: ") << address; + } else { + os << mode << strgettext("Hosting server"); + } + os << "\n" << strgettext("- Port: ") << serverAddress.getPort() << "\n"; + } else { + os << mode << strgettext("Singleplayer") << "\n"; + } + if (simple_singleplayer_mode || address.empty()) { + static const std::string on = strgettext("On"); + static const std::string off = strgettext("Off"); + // Note: Status of enable_damage and creative_mode settings is intentionally + // NOT shown here because the game might roll its own damage system and/or do + // a per-player Creative Mode, in which case writing it here would mislead. + bool damage = g_settings->getBool("enable_damage"); + const std::string &announced = g_settings->getBool("server_announce") ? on : off; + if (!simple_singleplayer_mode) { + if (damage) { + const std::string &pvp = g_settings->getBool("enable_pvp") ? on : off; + //~ PvP = Player versus Player + os << strgettext("- PvP: ") << pvp << "\n"; + } + os << strgettext("- Public: ") << announced << "\n"; + std::string server_name = g_settings->get("server_name"); + str_formspec_escape(server_name); + if (announced == on && !server_name.empty()) + os << strgettext("- Server Name: ") << server_name; + + } + } + os << ";]"; + + /* Create menu */ + /* Note: FormspecFormSource and LocalFormspecHandler * + * are deleted by guiFormSpecMenu */ + FormspecFormSource *fs_src = new FormspecFormSource(os.str()); + LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU"); + + auto *&formspec = m_game_ui->getFormspecGUI(); + GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(), + &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound); + formspec->setFocus("btn_continue"); + formspec->doPause = true; + + if (simple_singleplayer_mode) + pauseAnimation(); +} + +/****************************************************************************/ +/**************************************************************************** + extern function for launching the game + ****************************************************************************/ +/****************************************************************************/ + +void the_game(bool *kill, + InputHandler *input, + RenderingEngine *rendering_engine, + const GameStartData &start_data, + std::string &error_message, + ChatBackend &chat_backend, + bool *reconnect_requested) // Used for local game +{ + Game game; + + /* Make a copy of the server address because if a local singleplayer server + * is created then this is updated and we don't want to change the value + * passed to us by the calling function + */ + + try { + + if (game.startup(kill, input, rendering_engine, start_data, + error_message, reconnect_requested, &chat_backend)) { + game.run(); + } + + } catch (SerializationError &e) { + const std::string ver_err = fmtgettext("The server is probably running a different version of %s.", PROJECT_NAME_C); + error_message = strgettext("A serialization error occurred:") +"\n" + + e.what() + "\n\n" + ver_err; + errorstream << error_message << std::endl; + } catch (ServerError &e) { + error_message = e.what(); + errorstream << "ServerError: " << error_message << std::endl; + } catch (ModError &e) { + // DO NOT TRANSLATE the `ModError`, it's used by ui.lua + error_message = std::string("ModError: ") + e.what() + + strgettext("\nCheck debug.txt for details."); + errorstream << error_message << std::endl; + } + game.shutdown(); +} diff --git a/src/client/game.h b/src/client/game.h new file mode 100644 index 0000000..d87e747 --- /dev/null +++ b/src/client/game.h @@ -0,0 +1,53 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include <string> + +class InputHandler; +class ChatBackend; +class RenderingEngine; +struct SubgameSpec; +struct GameStartData; + +struct Jitter { + f32 max, min, avg, counter, max_sample, min_sample, max_fraction; +}; + +struct RunStats { + u64 drawtime; // (us) + + Jitter dtime_jitter, busy_time_jitter; +}; + +struct CameraOrientation { + f32 camera_yaw; // "right/left" + f32 camera_pitch; // "up/down" +}; + + +void the_game(bool *kill, + InputHandler *input, + RenderingEngine *rendering_engine, + const GameStartData &start_data, + std::string &error_message, + ChatBackend &chat_backend, + bool *reconnect_requested); diff --git a/src/client/gameui.cpp b/src/client/gameui.cpp new file mode 100644 index 0000000..909719b --- /dev/null +++ b/src/client/gameui.cpp @@ -0,0 +1,331 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "gameui.h" +#include <irrlicht_changes/static_text.h> +#include <gettext.h> +#include "gui/mainmenumanager.h" +#include "gui/guiChatConsole.h" +#include "util/pointedthing.h" +#include "client.h" +#include "clientmap.h" +#include "fontengine.h" +#include "nodedef.h" +#include "profiler.h" +#include "renderingengine.h" +#include "version.h" + +inline static const char *yawToDirectionString(int yaw) +{ + static const char *direction[4] = + {"North +Z", "West -X", "South -Z", "East +X"}; + + yaw = wrapDegrees_0_360(yaw); + yaw = (yaw + 45) % 360 / 90; + + return direction[yaw]; +} + +GameUI::GameUI() +{ + if (guienv && guienv->getSkin()) + m_statustext_initial_color = guienv->getSkin()->getColor(gui::EGDC_BUTTON_TEXT); + else + m_statustext_initial_color = video::SColor(255, 0, 0, 0); + +} +void GameUI::init() +{ + // First line of debug text + m_guitext = gui::StaticText::add(guienv, utf8_to_wide(PROJECT_NAME_C).c_str(), + core::rect<s32>(0, 0, 0, 0), false, false, guiroot); + + // Second line of debug text + m_guitext2 = gui::StaticText::add(guienv, L"", core::rect<s32>(0, 0, 0, 0), false, + false, guiroot); + + // Chat text + m_guitext_chat = gui::StaticText::add(guienv, L"", core::rect<s32>(0, 0, 0, 0), + //false, false); // Disable word wrap as of now + false, true, guiroot); + u16 chat_font_size = g_settings->getU16("chat_font_size"); + if (chat_font_size != 0) { + m_guitext_chat->setOverrideFont(g_fontengine->getFont( + rangelim(chat_font_size, 5, 72), FM_Unspecified)); + } + + + // Infotext of nodes and objects. + // If in debug mode, object debug infos shown here, too. + // Located on the left on the screen, below chat. + u32 chat_font_height = m_guitext_chat->getActiveFont()->getDimension(L"Ay").Height; + m_guitext_info = gui::StaticText::add(guienv, L"", + // Size is limited; text will be truncated after 6 lines. + core::rect<s32>(0, 0, 400, g_fontengine->getTextHeight() * 6) + + v2s32(100, chat_font_height * + (g_settings->getU16("recent_chat_messages") + 3)), + false, true, guiroot); + + // Status text (displays info when showing and hiding GUI stuff, etc.) + m_guitext_status = gui::StaticText::add(guienv, L"<Status>", + core::rect<s32>(0, 0, 0, 0), false, false, guiroot); + m_guitext_status->setVisible(false); + + // Profiler text (size is updated when text is updated) + m_guitext_profiler = gui::StaticText::add(guienv, L"<Profiler>", + core::rect<s32>(0, 0, 0, 0), false, false, guiroot); + m_guitext_profiler->setOverrideFont(g_fontengine->getFont( + g_fontengine->getDefaultFontSize() * 0.9f, FM_Mono)); + m_guitext_profiler->setVisible(false); +} + +void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_control, + const CameraOrientation &cam, const PointedThing &pointed_old, + const GUIChatConsole *chat_console, float dtime) +{ + v2u32 screensize = RenderingEngine::getWindowSize(); + + // Minimal debug text must only contain info that can't give a gameplay advantage + if (m_flags.show_minimal_debug) { + const u16 fps = 1.0 / stats.dtime_jitter.avg; + m_drawtime_avg *= 0.95f; + m_drawtime_avg += 0.05f * (stats.drawtime / 1000); + + std::ostringstream os(std::ios_base::binary); + os << std::fixed + << PROJECT_NAME_C " " << g_version_hash + << " | FPS: " << fps + << std::setprecision(0) + << " | drawtime: " << m_drawtime_avg << "ms" + << std::setprecision(1) + << " | dtime jitter: " + << (stats.dtime_jitter.max_fraction * 100.0) << "%" + << std::setprecision(1) + << " | view range: " + << (draw_control->range_all ? "All" : itos(draw_control->wanted_range)) + << std::setprecision(2) + << " | RTT: " << (client->getRTT() * 1000.0f) << "ms"; + setStaticText(m_guitext, utf8_to_wide(os.str()).c_str()); + + m_guitext->setRelativePosition(core::rect<s32>(5, 5, screensize.X, + 5 + g_fontengine->getTextHeight())); + } + + // Finally set the guitext visible depending on the flag + m_guitext->setVisible(m_flags.show_minimal_debug); + + // Basic debug text also shows info that might give a gameplay advantage + if (m_flags.show_basic_debug) { + LocalPlayer *player = client->getEnv().getLocalPlayer(); + v3f player_position = player->getPosition(); + + std::ostringstream os(std::ios_base::binary); + os << std::setprecision(1) << std::fixed + << "pos: (" << (player_position.X / BS) + << ", " << (player_position.Y / BS) + << ", " << (player_position.Z / BS) + << ") | yaw: " << (wrapDegrees_0_360(cam.camera_yaw)) << "° " + << yawToDirectionString(cam.camera_yaw) + << " | pitch: " << (-wrapDegrees_180(cam.camera_pitch)) << "°" + << " | seed: " << ((u64)client->getMapSeed()); + + if (pointed_old.type == POINTEDTHING_NODE) { + ClientMap &map = client->getEnv().getClientMap(); + const NodeDefManager *nodedef = client->getNodeDefManager(); + MapNode n = map.getNode(pointed_old.node_undersurface); + + if (n.getContent() != CONTENT_IGNORE) { + if (nodedef->get(n).name == "unknown") { + os << ", pointed: <unknown node>"; + } else { + os << ", pointed: " << nodedef->get(n).name; + } + os << ", param2: " << (u64) n.getParam2(); + } + } + + setStaticText(m_guitext2, utf8_to_wide(os.str()).c_str()); + + m_guitext2->setRelativePosition(core::rect<s32>(5, + 5 + g_fontengine->getTextHeight(), screensize.X, + 5 + g_fontengine->getTextHeight() * 2 + )); + } + + m_guitext2->setVisible(m_flags.show_basic_debug); + + setStaticText(m_guitext_info, m_infotext.c_str()); + m_guitext_info->setVisible(m_flags.show_hud && g_menumgr.menuCount() == 0); + + static const float statustext_time_max = 1.5f; + + if (!m_statustext.empty()) { + m_statustext_time += dtime; + + if (m_statustext_time >= statustext_time_max) { + clearStatusText(); + m_statustext_time = 0.0f; + } + } + + setStaticText(m_guitext_status, m_statustext.c_str()); + m_guitext_status->setVisible(!m_statustext.empty()); + + if (!m_statustext.empty()) { + s32 status_width = m_guitext_status->getTextWidth(); + s32 status_height = m_guitext_status->getTextHeight(); + s32 status_y = screensize.Y - 150; + s32 status_x = (screensize.X - status_width) / 2; + + m_guitext_status->setRelativePosition(core::rect<s32>(status_x , + status_y - status_height, status_x + status_width, status_y)); + + // Fade out + video::SColor final_color = m_statustext_initial_color; + final_color.setAlpha(0); + video::SColor fade_color = m_statustext_initial_color.getInterpolated_quadratic( + m_statustext_initial_color, final_color, m_statustext_time / statustext_time_max); + m_guitext_status->setOverrideColor(fade_color); + m_guitext_status->enableOverrideColor(true); + } + + // Hide chat when console is visible + m_guitext_chat->setVisible(isChatVisible() && !chat_console->isVisible()); +} + +void GameUI::initFlags() +{ + m_flags = GameUI::Flags(); + m_flags.show_minimal_debug = g_settings->getBool("show_debug"); +} + +void GameUI::showMinimap(bool show) +{ + m_flags.show_minimap = show; +} + +void GameUI::showTranslatedStatusText(const char *str) +{ + const wchar_t *wmsg = wgettext(str); + showStatusText(wmsg); + delete[] wmsg; +} + +void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count) +{ + setStaticText(m_guitext_chat, chat_text); + + m_recent_chat_count = recent_chat_count; +} + +void GameUI::updateChatSize() +{ + // Update gui element size and position + s32 chat_y = 5; + + if (m_flags.show_minimal_debug) + chat_y += g_fontengine->getLineHeight(); + if (m_flags.show_basic_debug) + chat_y += g_fontengine->getLineHeight(); + + const v2u32 &window_size = RenderingEngine::getWindowSize(); + + core::rect<s32> chat_size(10, chat_y, window_size.X - 20, 0); + chat_size.LowerRightCorner.Y = std::min((s32)window_size.Y, + m_guitext_chat->getTextHeight() + chat_y); + + if (chat_size == m_current_chat_size) + return; + m_current_chat_size = chat_size; + + m_guitext_chat->setRelativePosition(chat_size); +} + +void GameUI::updateProfiler() +{ + if (m_profiler_current_page != 0) { + std::ostringstream os(std::ios_base::binary); + os << " Profiler page " << (int)m_profiler_current_page << + ", elapsed: " << g_profiler->getElapsedMs() << " ms)" << std::endl; + + int lines = g_profiler->print(os, m_profiler_current_page, m_profiler_max_page); + ++lines; + + EnrichedString str(utf8_to_wide(os.str())); + str.setBackground(video::SColor(120, 0, 0, 0)); + setStaticText(m_guitext_profiler, str); + + core::dimension2d<u32> size = m_guitext_profiler->getOverrideFont()-> + getDimension(str.c_str()); + core::position2di upper_left(6, 50); + core::position2di lower_right = upper_left; + lower_right.X += size.Width + 10; + lower_right.Y += size.Height; + + m_guitext_profiler->setRelativePosition(core::rect<s32>(upper_left, lower_right)); + } + + m_guitext_profiler->setVisible(m_profiler_current_page != 0); +} + +void GameUI::toggleChat() +{ + m_flags.show_chat = !m_flags.show_chat; + if (m_flags.show_chat) + showTranslatedStatusText("Chat shown"); + else + showTranslatedStatusText("Chat hidden"); +} + +void GameUI::toggleHud() +{ + m_flags.show_hud = !m_flags.show_hud; + if (m_flags.show_hud) + showTranslatedStatusText("HUD shown"); + else + showTranslatedStatusText("HUD hidden"); +} + +void GameUI::toggleProfiler() +{ + m_profiler_current_page = (m_profiler_current_page + 1) % (m_profiler_max_page + 1); + + // FIXME: This updates the profiler with incomplete values + updateProfiler(); + + if (m_profiler_current_page != 0) { + std::wstring msg = fwgettext("Profiler shown (page %d of %d)", + m_profiler_current_page, m_profiler_max_page); + showStatusText(msg); + } else { + showTranslatedStatusText("Profiler hidden"); + } +} + + +void GameUI::deleteFormspec() +{ + if (m_formspec) { + m_formspec->drop(); + m_formspec = nullptr; + } + + m_formname.clear(); +} diff --git a/src/client/gameui.h b/src/client/gameui.h new file mode 100644 index 0000000..cc9377b --- /dev/null +++ b/src/client/gameui.h @@ -0,0 +1,138 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include <IGUIEnvironment.h> +#include "gui/guiFormSpecMenu.h" +#include "util/enriched_string.h" +#include "util/pointedthing.h" +#include "game.h" + +using namespace irr; +class Client; +class GUIChatConsole; +struct MapDrawControl; + +/* + * This object intend to contain the core UI elements + * It includes: + * - status texts + * - debug texts + * - chat texts + * - hud flags + */ +class GameUI +{ + // Temporary between coding time to move things here + friend class Game; + + // Permit unittests to access members directly + friend class TestGameUI; + +public: + GameUI(); + ~GameUI() = default; + + // Flags that can, or may, change during main game loop + struct Flags + { + bool show_chat = true; + bool show_hud = true; + bool show_minimap = false; + bool show_minimal_debug = false; + bool show_basic_debug = false; + bool show_profiler_graph = false; + }; + + void init(); + void update(const RunStats &stats, Client *client, MapDrawControl *draw_control, + const CameraOrientation &cam, const PointedThing &pointed_old, + const GUIChatConsole *chat_console, float dtime); + + void initFlags(); + const Flags &getFlags() const { return m_flags; } + + void showMinimap(bool show); + + inline void setInfoText(const std::wstring &str) { m_infotext = str; } + inline void clearInfoText() { m_infotext.clear(); } + + inline void showStatusText(const std::wstring &str) + { + m_statustext = str; + m_statustext_time = 0.0f; + } + void showTranslatedStatusText(const char *str); + inline void clearStatusText() { m_statustext.clear(); } + + bool isChatVisible() + { + return m_flags.show_chat && m_recent_chat_count != 0 && m_profiler_current_page == 0; + } + void setChatText(const EnrichedString &chat_text, u32 recent_chat_count); + void updateChatSize(); + + void updateProfiler(); + + void toggleChat(); + void toggleHud(); + void toggleProfiler(); + + GUIFormSpecMenu *&updateFormspec(const std::string &formname) + { + m_formname = formname; + return m_formspec; + } + + const std::string &getFormspecName() { return m_formname; } + GUIFormSpecMenu *&getFormspecGUI() { return m_formspec; } + void deleteFormspec(); + +private: + Flags m_flags; + + float m_drawtime_avg = 0; + + gui::IGUIStaticText *m_guitext = nullptr; // First line of debug text + gui::IGUIStaticText *m_guitext2 = nullptr; // Second line of debug text + + gui::IGUIStaticText *m_guitext_info = nullptr; // At the middle of the screen + std::wstring m_infotext; + + gui::IGUIStaticText *m_guitext_status = nullptr; + std::wstring m_statustext; + float m_statustext_time = 0.0f; + video::SColor m_statustext_initial_color; + + gui::IGUIStaticText *m_guitext_chat = nullptr; // Chat text + u32 m_recent_chat_count = 0; + core::rect<s32> m_current_chat_size{0, 0, 0, 0}; + + gui::IGUIStaticText *m_guitext_profiler = nullptr; // Profiler text + u8 m_profiler_current_page = 0; + const u8 m_profiler_max_page = 3; + + // Default: "". If other than "": Empty show_formspec packets will only + // close the formspec when the formname matches + std::string m_formname; + GUIFormSpecMenu *m_formspec = nullptr; +}; diff --git a/src/client/guiscalingfilter.cpp b/src/client/guiscalingfilter.cpp new file mode 100644 index 0000000..4250825 --- /dev/null +++ b/src/client/guiscalingfilter.cpp @@ -0,0 +1,240 @@ +/* +Copyright (C) 2015 Aaron Suen <warr1024@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiscalingfilter.h" +#include "imagefilters.h" +#include "porting.h" +#include "settings.h" +#include "util/numeric.h" +#include <cstdio> +#include "client/renderingengine.h" + +/* Maintain a static cache to store the images that correspond to textures + * in a format that's manipulable by code. Some platforms exhibit issues + * converting textures back into images repeatedly, and some don't even + * allow it at all. + */ +std::map<io::path, video::IImage *> g_imgCache; + +/* Maintain a static cache of all pre-scaled textures. These need to be + * cleared as well when the cached images. + */ +std::map<io::path, video::ITexture *> g_txrCache; + +/* Manually insert an image into the cache, useful to avoid texture-to-image + * conversion whenever we can intercept it. + */ +void guiScalingCache(const io::path &key, video::IVideoDriver *driver, video::IImage *value) +{ + if (!g_settings->getBool("gui_scaling_filter")) + return; + + if (g_imgCache.find(key) != g_imgCache.end()) + return; // Already cached. + + video::IImage *copied = driver->createImage(value->getColorFormat(), + value->getDimension()); + value->copyTo(copied); + g_imgCache[key] = copied; +} + +// Manually clear the cache, e.g. when switching to different worlds. +void guiScalingCacheClear() +{ + for (auto &it : g_imgCache) { + if (it.second) + it.second->drop(); + } + g_imgCache.clear(); + for (auto &it : g_txrCache) { + if (it.second) + RenderingEngine::get_video_driver()->removeTexture(it.second); + } + g_txrCache.clear(); +} + +/* Get a cached, high-quality pre-scaled texture for display purposes. If the + * texture is not already cached, attempt to create it. Returns a pre-scaled texture, + * or the original texture if unable to pre-scale it. + */ +video::ITexture *guiScalingResizeCached(video::IVideoDriver *driver, + video::ITexture *src, const core::rect<s32> &srcrect, + const core::rect<s32> &destrect) +{ + if (src == NULL) + return src; + if (!g_settings->getBool("gui_scaling_filter")) + return src; + + // Calculate scaled texture name. + char rectstr[200]; + porting::mt_snprintf(rectstr, sizeof(rectstr), "%d:%d:%d:%d:%d:%d", + srcrect.UpperLeftCorner.X, + srcrect.UpperLeftCorner.Y, + srcrect.getWidth(), + srcrect.getHeight(), + destrect.getWidth(), + destrect.getHeight()); + io::path origname = src->getName().getPath(); + io::path scalename = origname + "@guiScalingFilter:" + rectstr; + + // Search for existing scaled texture. + auto it_txr = g_txrCache.find(scalename); + video::ITexture *scaled = (it_txr != g_txrCache.end()) ? it_txr->second : nullptr; + if (scaled) + return scaled; + + // Try to find the texture converted to an image in the cache. + // If the image was not found, try to extract it from the texture. + auto it_img = g_imgCache.find(origname); + video::IImage *srcimg = (it_img != g_imgCache.end()) ? it_img->second : nullptr; + if (!srcimg) { + if (!g_settings->getBool("gui_scaling_filter_txr2img")) + return src; + srcimg = driver->createImageFromData(src->getColorFormat(), + src->getSize(), src->lock(video::ETLM_READ_ONLY), false); + src->unlock(); + g_imgCache[origname] = srcimg; + } + + // Create a new destination image and scale the source into it. + imageCleanTransparent(srcimg, 0); + video::IImage *destimg = driver->createImage(src->getColorFormat(), + core::dimension2d<u32>((u32)destrect.getWidth(), + (u32)destrect.getHeight())); + imageScaleNNAA(srcimg, srcrect, destimg); + +#if ENABLE_GLES + // Some platforms are picky about textures being powers of 2, so expand + // the image dimensions to the next power of 2, if necessary. + if (!driver->queryFeature(video::EVDF_TEXTURE_NPOT)) { + video::IImage *po2img = driver->createImage(src->getColorFormat(), + core::dimension2d<u32>(npot2((u32)destrect.getWidth()), + npot2((u32)destrect.getHeight()))); + po2img->fill(video::SColor(0, 0, 0, 0)); + destimg->copyTo(po2img); + destimg->drop(); + destimg = po2img; + } +#endif + + // Convert the scaled image back into a texture. + scaled = driver->addTexture(scalename, destimg); + destimg->drop(); + g_txrCache[scalename] = scaled; + + return scaled; +} + +/* Convenience wrapper for guiScalingResizeCached that accepts parameters that + * are available at GUI imagebutton creation time. + */ +video::ITexture *guiScalingImageButton(video::IVideoDriver *driver, + video::ITexture *src, s32 width, s32 height) +{ + if (src == NULL) + return src; + return guiScalingResizeCached(driver, src, + core::rect<s32>(0, 0, src->getSize().Width, src->getSize().Height), + core::rect<s32>(0, 0, width, height)); +} + +/* Replacement for driver->draw2DImage() that uses the high-quality pre-scaled + * texture, if configured. + */ +void draw2DImageFilterScaled(video::IVideoDriver *driver, video::ITexture *txr, + const core::rect<s32> &destrect, const core::rect<s32> &srcrect, + const core::rect<s32> *cliprect, const video::SColor *const colors, + bool usealpha) +{ + // Attempt to pre-scale image in software in high quality. + video::ITexture *scaled = guiScalingResizeCached(driver, txr, srcrect, destrect); + if (scaled == NULL) + return; + + // Correct source rect based on scaled image. + const core::rect<s32> mysrcrect = (scaled != txr) + ? core::rect<s32>(0, 0, destrect.getWidth(), destrect.getHeight()) + : srcrect; + + driver->draw2DImage(scaled, destrect, mysrcrect, cliprect, colors, usealpha); +} + +void draw2DImage9Slice(video::IVideoDriver *driver, video::ITexture *texture, + const core::rect<s32> &destrect, const core::rect<s32> &srcrect, + const core::rect<s32> &middlerect, const core::rect<s32> *cliprect, + const video::SColor *const colors) +{ + // `-x` is interpreted as `w - x` + core::rect<s32> middle = middlerect; + + if (middlerect.LowerRightCorner.X < 0) + middle.LowerRightCorner.X += srcrect.getWidth(); + if (middlerect.LowerRightCorner.Y < 0) + middle.LowerRightCorner.Y += srcrect.getHeight(); + + core::vector2di lower_right_offset = core::vector2di(srcrect.getWidth(), + srcrect.getHeight()) - middle.LowerRightCorner; + + for (int y = 0; y < 3; ++y) { + for (int x = 0; x < 3; ++x) { + core::rect<s32> src = srcrect; + core::rect<s32> dest = destrect; + + switch (x) { + case 0: + dest.LowerRightCorner.X = destrect.UpperLeftCorner.X + middle.UpperLeftCorner.X; + src.LowerRightCorner.X = srcrect.UpperLeftCorner.X + middle.UpperLeftCorner.X; + break; + + case 1: + dest.UpperLeftCorner.X += middle.UpperLeftCorner.X; + dest.LowerRightCorner.X -= lower_right_offset.X; + src.UpperLeftCorner.X += middle.UpperLeftCorner.X; + src.LowerRightCorner.X -= lower_right_offset.X; + break; + + case 2: + dest.UpperLeftCorner.X = destrect.LowerRightCorner.X - lower_right_offset.X; + src.UpperLeftCorner.X = srcrect.LowerRightCorner.X - lower_right_offset.X; + break; + } + + switch (y) { + case 0: + dest.LowerRightCorner.Y = destrect.UpperLeftCorner.Y + middle.UpperLeftCorner.Y; + src.LowerRightCorner.Y = srcrect.UpperLeftCorner.Y + middle.UpperLeftCorner.Y; + break; + + case 1: + dest.UpperLeftCorner.Y += middle.UpperLeftCorner.Y; + dest.LowerRightCorner.Y -= lower_right_offset.Y; + src.UpperLeftCorner.Y += middle.UpperLeftCorner.Y; + src.LowerRightCorner.Y -= lower_right_offset.Y; + break; + + case 2: + dest.UpperLeftCorner.Y = destrect.LowerRightCorner.Y - lower_right_offset.Y; + src.UpperLeftCorner.Y = srcrect.LowerRightCorner.Y - lower_right_offset.Y; + break; + } + + draw2DImageFilterScaled(driver, texture, dest, src, cliprect, colors, true); + } + } +} diff --git a/src/client/guiscalingfilter.h b/src/client/guiscalingfilter.h new file mode 100644 index 0000000..f2d2fce --- /dev/null +++ b/src/client/guiscalingfilter.h @@ -0,0 +1,58 @@ +/* +Copyright (C) 2015 Aaron Suen <warr1024@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" + +/* Manually insert an image into the cache, useful to avoid texture-to-image + * conversion whenever we can intercept it. + */ +void guiScalingCache(const io::path &key, video::IVideoDriver *driver, video::IImage *value); + +// Manually clear the cache, e.g. when switching to different worlds. +void guiScalingCacheClear(); + +/* Get a cached, high-quality pre-scaled texture for display purposes. If the + * texture is not already cached, attempt to create it. Returns a pre-scaled texture, + * or the original texture if unable to pre-scale it. + */ +video::ITexture *guiScalingResizeCached(video::IVideoDriver *driver, video::ITexture *src, + const core::rect<s32> &srcrect, const core::rect<s32> &destrect); + +/* Convenience wrapper for guiScalingResizeCached that accepts parameters that + * are available at GUI imagebutton creation time. + */ +video::ITexture *guiScalingImageButton(video::IVideoDriver *driver, video::ITexture *src, + s32 width, s32 height); + +/* Replacement for driver->draw2DImage() that uses the high-quality pre-scaled + * texture, if configured. + */ +void draw2DImageFilterScaled(video::IVideoDriver *driver, video::ITexture *txr, + const core::rect<s32> &destrect, const core::rect<s32> &srcrect, + const core::rect<s32> *cliprect = nullptr, + const video::SColor *const colors = nullptr, bool usealpha = false); + +/* + * 9-slice / segment drawing + */ +void draw2DImage9Slice(video::IVideoDriver *driver, video::ITexture *texture, + const core::rect<s32> &destrect, const core::rect<s32> &srcrect, + const core::rect<s32> &middlerect, const core::rect<s32> *cliprect = nullptr, + const video::SColor *const colors = nullptr); diff --git a/src/client/hud.cpp b/src/client/hud.cpp new file mode 100644 index 0000000..c0c2896 --- /dev/null +++ b/src/client/hud.cpp @@ -0,0 +1,1260 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2010-2013 blue42u, Jonathon Anderson <anderjon@umail.iu.edu> +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "client/hud.h" +#include <string> +#include <iostream> +#include <cmath> +#include "settings.h" +#include "util/numeric.h" +#include "log.h" +#include "client.h" +#include "inventory.h" +#include "shader.h" +#include "client/tile.h" +#include "localplayer.h" +#include "camera.h" +#include "porting.h" +#include "fontengine.h" +#include "guiscalingfilter.h" +#include "mesh.h" +#include "wieldmesh.h" +#include "client/renderingengine.h" +#include "client/minimap.h" + +#ifdef HAVE_TOUCHSCREENGUI +#include "gui/touchscreengui.h" +#endif + +#define OBJECT_CROSSHAIR_LINE_SIZE 8 +#define CROSSHAIR_LINE_SIZE 10 + +Hud::Hud(Client *client, LocalPlayer *player, + Inventory *inventory) +{ + driver = RenderingEngine::get_video_driver(); + this->client = client; + this->player = player; + this->inventory = inventory; + + m_hud_scaling = g_settings->getFloat("hud_scaling", 0.5f, 20.0f); + m_scale_factor = m_hud_scaling * RenderingEngine::getDisplayDensity(); + m_hotbar_imagesize = std::floor(HOTBAR_IMAGE_SIZE * + RenderingEngine::getDisplayDensity() + 0.5f); + m_hotbar_imagesize *= m_hud_scaling; + m_padding = m_hotbar_imagesize / 12; + + for (auto &hbar_color : hbar_colors) + hbar_color = video::SColor(255, 255, 255, 255); + + tsrc = client->getTextureSource(); + + v3f crosshair_color = g_settings->getV3F("crosshair_color"); + u32 cross_r = rangelim(myround(crosshair_color.X), 0, 255); + u32 cross_g = rangelim(myround(crosshair_color.Y), 0, 255); + u32 cross_b = rangelim(myround(crosshair_color.Z), 0, 255); + u32 cross_a = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255); + crosshair_argb = video::SColor(cross_a, cross_r, cross_g, cross_b); + + v3f selectionbox_color = g_settings->getV3F("selectionbox_color"); + u32 sbox_r = rangelim(myround(selectionbox_color.X), 0, 255); + u32 sbox_g = rangelim(myround(selectionbox_color.Y), 0, 255); + u32 sbox_b = rangelim(myround(selectionbox_color.Z), 0, 255); + selectionbox_argb = video::SColor(255, sbox_r, sbox_g, sbox_b); + + use_crosshair_image = tsrc->isKnownSourceImage("crosshair.png"); + use_object_crosshair_image = tsrc->isKnownSourceImage("object_crosshair.png"); + + m_selection_boxes.clear(); + m_halo_boxes.clear(); + + std::string mode_setting = g_settings->get("node_highlighting"); + + if (mode_setting == "halo") { + m_mode = HIGHLIGHT_HALO; + } else if (mode_setting == "none") { + m_mode = HIGHLIGHT_NONE; + } else { + m_mode = HIGHLIGHT_BOX; + } + + m_selection_material.Lighting = false; + + if (g_settings->getBool("enable_shaders")) { + IShaderSource *shdrsrc = client->getShaderSource(); + u16 shader_id = shdrsrc->getShader( + m_mode == HIGHLIGHT_HALO ? "selection_shader" : "default_shader", TILE_MATERIAL_ALPHA); + m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material; + } else { + m_selection_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + } + + if (m_mode == HIGHLIGHT_BOX) { + m_selection_material.Thickness = + rangelim(g_settings->getS16("selectionbox_width"), 1, 5); + } else if (m_mode == HIGHLIGHT_HALO) { + m_selection_material.setTexture(0, tsrc->getTextureForMesh("halo.png")); + m_selection_material.setFlag(video::EMF_BACK_FACE_CULLING, true); + } else { + m_selection_material.MaterialType = video::EMT_SOLID; + } + + // Prepare mesh for compass drawing + m_rotation_mesh_buffer.Vertices.set_used(4); + m_rotation_mesh_buffer.Indices.set_used(6); + + video::SColor white(255, 255, 255, 255); + v3f normal(0.f, 0.f, 1.f); + + m_rotation_mesh_buffer.Vertices[0] = video::S3DVertex(v3f(-1.f, -1.f, 0.f), normal, white, v2f(0.f, 1.f)); + m_rotation_mesh_buffer.Vertices[1] = video::S3DVertex(v3f(-1.f, 1.f, 0.f), normal, white, v2f(0.f, 0.f)); + m_rotation_mesh_buffer.Vertices[2] = video::S3DVertex(v3f( 1.f, 1.f, 0.f), normal, white, v2f(1.f, 0.f)); + m_rotation_mesh_buffer.Vertices[3] = video::S3DVertex(v3f( 1.f, -1.f, 0.f), normal, white, v2f(1.f, 1.f)); + + m_rotation_mesh_buffer.Indices[0] = 0; + m_rotation_mesh_buffer.Indices[1] = 1; + m_rotation_mesh_buffer.Indices[2] = 2; + m_rotation_mesh_buffer.Indices[3] = 2; + m_rotation_mesh_buffer.Indices[4] = 3; + m_rotation_mesh_buffer.Indices[5] = 0; + + m_rotation_mesh_buffer.getMaterial().Lighting = false; + m_rotation_mesh_buffer.getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; +} + +Hud::~Hud() +{ + if (m_selection_mesh) + m_selection_mesh->drop(); +} + +void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect, + bool selected) +{ + if (selected) { + /* draw hihlighting around selected item */ + if (use_hotbar_selected_image) { + core::rect<s32> imgrect2 = rect; + imgrect2.UpperLeftCorner.X -= (m_padding*2); + imgrect2.UpperLeftCorner.Y -= (m_padding*2); + imgrect2.LowerRightCorner.X += (m_padding*2); + imgrect2.LowerRightCorner.Y += (m_padding*2); + video::ITexture *texture = tsrc->getTexture(hotbar_selected_image); + core::dimension2di imgsize(texture->getOriginalSize()); + draw2DImageFilterScaled(driver, texture, imgrect2, + core::rect<s32>(core::position2d<s32>(0,0), imgsize), + NULL, hbar_colors, true); + } else { + video::SColor c_outside(255,255,0,0); + //video::SColor c_outside(255,0,0,0); + //video::SColor c_inside(255,192,192,192); + s32 x1 = rect.UpperLeftCorner.X; + s32 y1 = rect.UpperLeftCorner.Y; + s32 x2 = rect.LowerRightCorner.X; + s32 y2 = rect.LowerRightCorner.Y; + // Black base borders + driver->draw2DRectangle(c_outside, + core::rect<s32>( + v2s32(x1 - m_padding, y1 - m_padding), + v2s32(x2 + m_padding, y1) + ), NULL); + driver->draw2DRectangle(c_outside, + core::rect<s32>( + v2s32(x1 - m_padding, y2), + v2s32(x2 + m_padding, y2 + m_padding) + ), NULL); + driver->draw2DRectangle(c_outside, + core::rect<s32>( + v2s32(x1 - m_padding, y1), + v2s32(x1, y2) + ), NULL); + driver->draw2DRectangle(c_outside, + core::rect<s32>( + v2s32(x2, y1), + v2s32(x2 + m_padding, y2) + ), NULL); + /*// Light inside borders + driver->draw2DRectangle(c_inside, + core::rect<s32>( + v2s32(x1 - padding/2, y1 - padding/2), + v2s32(x2 + padding/2, y1) + ), NULL); + driver->draw2DRectangle(c_inside, + core::rect<s32>( + v2s32(x1 - padding/2, y2), + v2s32(x2 + padding/2, y2 + padding/2) + ), NULL); + driver->draw2DRectangle(c_inside, + core::rect<s32>( + v2s32(x1 - padding/2, y1), + v2s32(x1, y2) + ), NULL); + driver->draw2DRectangle(c_inside, + core::rect<s32>( + v2s32(x2, y1), + v2s32(x2 + padding/2, y2) + ), NULL); + */ + } + } + + video::SColor bgcolor2(128, 0, 0, 0); + if (!use_hotbar_image) + driver->draw2DRectangle(bgcolor2, rect, NULL); + drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL, + client, selected ? IT_ROT_SELECTED : IT_ROT_NONE); +} + +//NOTE: selectitem = 0 -> no selected; selectitem 1-based +// mainlist can be NULL, but draw the frame anyway. +void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount, + s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction) +{ +#ifdef HAVE_TOUCHSCREENGUI + if (g_touchscreengui && inv_offset == 0) + g_touchscreengui->resetHud(); +#endif + + s32 height = m_hotbar_imagesize + m_padding * 2; + s32 width = (itemcount - inv_offset) * (m_hotbar_imagesize + m_padding * 2); + + if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) { + s32 tmp = height; + height = width; + width = tmp; + } + + // Position of upper left corner of bar + v2s32 pos = screen_offset * m_scale_factor; + pos += upperleftpos; + + // Store hotbar_image in member variable, used by drawItem() + if (hotbar_image != player->hotbar_image) { + hotbar_image = player->hotbar_image; + use_hotbar_image = !hotbar_image.empty(); + } + + // Store hotbar_selected_image in member variable, used by drawItem() + if (hotbar_selected_image != player->hotbar_selected_image) { + hotbar_selected_image = player->hotbar_selected_image; + use_hotbar_selected_image = !hotbar_selected_image.empty(); + } + + // draw customized item background + if (use_hotbar_image) { + core::rect<s32> imgrect2(-m_padding/2, -m_padding/2, + width+m_padding/2, height+m_padding/2); + core::rect<s32> rect2 = imgrect2 + pos; + video::ITexture *texture = tsrc->getTexture(hotbar_image); + core::dimension2di imgsize(texture->getOriginalSize()); + draw2DImageFilterScaled(driver, texture, rect2, + core::rect<s32>(core::position2d<s32>(0,0), imgsize), + NULL, hbar_colors, true); + } + + // Draw items + core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize); + const s32 list_size = mainlist ? mainlist->getSize() : 0; + for (s32 i = inv_offset; i < itemcount && i < list_size; i++) { + s32 fullimglen = m_hotbar_imagesize + m_padding * 2; + + v2s32 steppos; + switch (direction) { + case HUD_DIR_RIGHT_LEFT: + steppos = v2s32(-(m_padding + (i - inv_offset) * fullimglen), m_padding); + break; + case HUD_DIR_TOP_BOTTOM: + steppos = v2s32(m_padding, m_padding + (i - inv_offset) * fullimglen); + break; + case HUD_DIR_BOTTOM_TOP: + steppos = v2s32(m_padding, -(m_padding + (i - inv_offset) * fullimglen)); + break; + default: + steppos = v2s32(m_padding + (i - inv_offset) * fullimglen, m_padding); + break; + } + + drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i + 1) == selectitem); + +#ifdef HAVE_TOUCHSCREENGUI + if (g_touchscreengui) + g_touchscreengui->registerHudItem(i, (imgrect + pos + steppos)); +#endif + } +} + +bool Hud::hasElementOfType(HudElementType type) +{ + for (size_t i = 0; i != player->maxHudId(); i++) { + HudElement *e = player->getHud(i); + if (!e) + continue; + if (e->type == type) + return true; + } + return false; +} + +// Calculates screen position of waypoint. Returns true if waypoint is visible (in front of the player), else false. +bool Hud::calculateScreenPos(const v3s16 &camera_offset, HudElement *e, v2s32 *pos) +{ + v3f w_pos = e->world_pos * BS; + scene::ICameraSceneNode* camera = + client->getSceneManager()->getActiveCamera(); + w_pos -= intToFloat(camera_offset, BS); + core::matrix4 trans = camera->getProjectionMatrix(); + trans *= camera->getViewMatrix(); + f32 transformed_pos[4] = { w_pos.X, w_pos.Y, w_pos.Z, 1.0f }; + trans.multiplyWith1x4Matrix(transformed_pos); + if (transformed_pos[3] < 0) + return false; + f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f : + core::reciprocal(transformed_pos[3]); + pos->X = m_screensize.X * (0.5 * transformed_pos[0] * zDiv + 0.5); + pos->Y = m_screensize.Y * (0.5 - transformed_pos[1] * zDiv * 0.5); + return true; +} + +void Hud::drawLuaElements(const v3s16 &camera_offset) +{ + const u32 text_height = g_fontengine->getTextHeight(); + gui::IGUIFont *const font = g_fontengine->getFont(); + + // Reorder elements by z_index + std::vector<HudElement*> elems; + elems.reserve(player->maxHudId()); + + for (size_t i = 0; i != player->maxHudId(); i++) { + HudElement *e = player->getHud(i); + if (!e) + continue; + + auto it = elems.begin(); + while (it != elems.end() && (*it)->z_index <= e->z_index) + ++it; + + elems.insert(it, e); + } + + for (HudElement *e : elems) { + + v2s32 pos(floor(e->pos.X * (float) m_screensize.X + 0.5), + floor(e->pos.Y * (float) m_screensize.Y + 0.5)); + switch (e->type) { + case HUD_ELEM_TEXT: { + unsigned int font_size = g_fontengine->getDefaultFontSize(); + + if (e->size.X > 0) + font_size *= e->size.X; + +#ifdef __ANDROID__ + // The text size on Android is not proportional with the actual scaling + // FIXME: why do we have such a weird unportable hack?? + if (font_size > 3 && e->offset.X < -20) + font_size -= 3; +#endif + auto textfont = g_fontengine->getFont(FontSpec(font_size, + (e->style & HUD_STYLE_MONO) ? FM_Mono : FM_Unspecified, + e->style & HUD_STYLE_BOLD, e->style & HUD_STYLE_ITALIC)); + + video::SColor color(255, (e->number >> 16) & 0xFF, + (e->number >> 8) & 0xFF, + (e->number >> 0) & 0xFF); + std::wstring text = unescape_translate(utf8_to_wide(e->text)); + core::dimension2d<u32> textsize = textfont->getDimension(text.c_str()); + + v2s32 offset(0, (e->align.Y - 1.0) * (textsize.Height / 2)); + core::rect<s32> size(0, 0, e->scale.X * m_scale_factor, + text_height * e->scale.Y * m_scale_factor); + v2s32 offs(e->offset.X * m_scale_factor, + e->offset.Y * m_scale_factor); + std::wstringstream wss(text); + std::wstring line; + while (std::getline(wss, line, L'\n')) + { + core::dimension2d<u32> linesize = textfont->getDimension(line.c_str()); + v2s32 line_offset((e->align.X - 1.0) * (linesize.Width / 2), 0); + textfont->draw(line.c_str(), size + pos + offset + offs + line_offset, color); + offset.Y += linesize.Height; + } + break; } + case HUD_ELEM_STATBAR: { + v2s32 offs(e->offset.X, e->offset.Y); + drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->text2, + e->number, e->item, offs, e->size); + break; } + case HUD_ELEM_INVENTORY: { + InventoryList *inv = inventory->getList(e->text); + if (!inv) + warningstream << "HUD: Unknown inventory list. name=" << e->text << std::endl; + drawItems(pos, v2s32(e->offset.X, e->offset.Y), e->number, 0, + inv, e->item, e->dir); + break; } + case HUD_ELEM_WAYPOINT: { + if (!calculateScreenPos(camera_offset, e, &pos)) + break; + v3f p_pos = player->getPosition() / BS; + pos += v2s32(e->offset.X, e->offset.Y); + video::SColor color(255, (e->number >> 16) & 0xFF, + (e->number >> 8) & 0xFF, + (e->number >> 0) & 0xFF); + std::wstring text = unescape_translate(utf8_to_wide(e->name)); + const std::string &unit = e->text; + // waypoints reuse the item field to store precision, item = precision + 1 + u32 item = e->item; + float precision = (item == 0) ? 10.0f : (item - 1.f); + bool draw_precision = precision > 0; + + core::rect<s32> bounds(0, 0, font->getDimension(text.c_str()).Width, (draw_precision ? 2:1) * text_height); + pos.Y += (e->align.Y - 1.0) * bounds.getHeight() / 2; + bounds += pos; + font->draw(text.c_str(), bounds + v2s32((e->align.X - 1.0) * bounds.getWidth() / 2, 0), color); + if (draw_precision) { + std::ostringstream os; + float distance = std::floor(precision * p_pos.getDistanceFrom(e->world_pos)) / precision; + os << distance << unit; + text = unescape_translate(utf8_to_wide(os.str())); + bounds.LowerRightCorner.X = bounds.UpperLeftCorner.X + font->getDimension(text.c_str()).Width; + font->draw(text.c_str(), bounds + v2s32((e->align.X - 1.0f) * bounds.getWidth() / 2, text_height), color); + } + break; } + case HUD_ELEM_IMAGE_WAYPOINT: { + if (!calculateScreenPos(camera_offset, e, &pos)) + break; + } + case HUD_ELEM_IMAGE: { + video::ITexture *texture = tsrc->getTexture(e->text); + if (!texture) + continue; + + const video::SColor color(255, 255, 255, 255); + const video::SColor colors[] = {color, color, color, color}; + core::dimension2di imgsize(texture->getOriginalSize()); + v2s32 dstsize(imgsize.Width * e->scale.X * m_scale_factor, + imgsize.Height * e->scale.Y * m_scale_factor); + if (e->scale.X < 0) + dstsize.X = m_screensize.X * (e->scale.X * -0.01); + if (e->scale.Y < 0) + dstsize.Y = m_screensize.Y * (e->scale.Y * -0.01); + v2s32 offset((e->align.X - 1.0) * dstsize.X / 2, + (e->align.Y - 1.0) * dstsize.Y / 2); + core::rect<s32> rect(0, 0, dstsize.X, dstsize.Y); + rect += pos + offset + v2s32(e->offset.X * m_scale_factor, + e->offset.Y * m_scale_factor); + draw2DImageFilterScaled(driver, texture, rect, + core::rect<s32>(core::position2d<s32>(0,0), imgsize), + NULL, colors, true); + break; } + case HUD_ELEM_COMPASS: { + video::ITexture *texture = tsrc->getTexture(e->text); + if (!texture) + continue; + + // Positionning : + v2s32 dstsize(e->size.X, e->size.Y); + if (e->size.X < 0) + dstsize.X = m_screensize.X * (e->size.X * -0.01); + if (e->size.Y < 0) + dstsize.Y = m_screensize.Y * (e->size.Y * -0.01); + + if (dstsize.X <= 0 || dstsize.Y <= 0) + return; // Avoid zero divides + + // Angle according to camera view + v3f fore(0.f, 0.f, 1.f); + scene::ICameraSceneNode *cam = client->getSceneManager()->getActiveCamera(); + cam->getAbsoluteTransformation().rotateVect(fore); + int angle = - fore.getHorizontalAngle().Y; + + // Limit angle and ajust with given offset + angle = (angle + (int)e->number) % 360; + + core::rect<s32> dstrect(0, 0, dstsize.X, dstsize.Y); + dstrect += pos + v2s32( + (e->align.X - 1.0) * dstsize.X / 2, + (e->align.Y - 1.0) * dstsize.Y / 2) + + v2s32(e->offset.X * m_hud_scaling, e->offset.Y * m_hud_scaling); + + switch (e->dir) { + case HUD_COMPASS_ROTATE: + drawCompassRotate(e, texture, dstrect, angle); + break; + case HUD_COMPASS_ROTATE_REVERSE: + drawCompassRotate(e, texture, dstrect, -angle); + break; + case HUD_COMPASS_TRANSLATE: + drawCompassTranslate(e, texture, dstrect, angle); + break; + case HUD_COMPASS_TRANSLATE_REVERSE: + drawCompassTranslate(e, texture, dstrect, -angle); + break; + default: + break; + } + break; } + case HUD_ELEM_MINIMAP: { + if (e->size.X <= 0 || e->size.Y <= 0) + break; + if (!client->getMinimap()) + break; + // Draw a minimap of size "size" + v2s32 dstsize(e->size.X * m_scale_factor, + e->size.Y * m_scale_factor); + // (no percent size as minimap would likely be anamorphosed) + v2s32 offset((e->align.X - 1.0) * dstsize.X / 2, + (e->align.Y - 1.0) * dstsize.Y / 2); + core::rect<s32> rect(0, 0, dstsize.X, dstsize.Y); + rect += pos + offset + v2s32(e->offset.X * m_scale_factor, + e->offset.Y * m_scale_factor); + client->getMinimap()->drawMinimap(rect); + break; } + default: + infostream << "Hud::drawLuaElements: ignoring drawform " << e->type + << " due to unrecognized type" << std::endl; + } + } +} + +void Hud::drawCompassTranslate(HudElement *e, video::ITexture *texture, + const core::rect<s32> &rect, int angle) +{ + const video::SColor color(255, 255, 255, 255); + const video::SColor colors[] = {color, color, color, color}; + + // Compute source image scaling + core::dimension2di imgsize(texture->getOriginalSize()); + core::rect<s32> srcrect(0, 0, imgsize.Width, imgsize.Height); + + v2s32 dstsize(rect.getHeight() * e->scale.X * imgsize.Width / imgsize.Height, + rect.getHeight() * e->scale.Y); + + // Avoid infinite loop + if (dstsize.X <= 0 || dstsize.Y <= 0) + return; + + core::rect<s32> tgtrect(0, 0, dstsize.X, dstsize.Y); + tgtrect += v2s32( + (rect.getWidth() - dstsize.X) / 2, + (rect.getHeight() - dstsize.Y) / 2) + + rect.UpperLeftCorner; + + int offset = angle * dstsize.X / 360; + + tgtrect += v2s32(offset, 0); + + // Repeat image as much as needed + while (tgtrect.UpperLeftCorner.X > rect.UpperLeftCorner.X) + tgtrect -= v2s32(dstsize.X, 0); + + draw2DImageFilterScaled(driver, texture, tgtrect, srcrect, &rect, colors, true); + tgtrect += v2s32(dstsize.X, 0); + + while (tgtrect.UpperLeftCorner.X < rect.LowerRightCorner.X) { + draw2DImageFilterScaled(driver, texture, tgtrect, srcrect, &rect, colors, true); + tgtrect += v2s32(dstsize.X, 0); + } +} + +void Hud::drawCompassRotate(HudElement *e, video::ITexture *texture, + const core::rect<s32> &rect, int angle) +{ + core::rect<s32> oldViewPort = driver->getViewPort(); + core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION); + core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW); + + core::matrix4 Matrix; + Matrix.makeIdentity(); + Matrix.setRotationDegrees(v3f(0.f, 0.f, angle)); + + driver->setViewPort(rect); + driver->setTransform(video::ETS_PROJECTION, core::matrix4()); + driver->setTransform(video::ETS_VIEW, core::matrix4()); + driver->setTransform(video::ETS_WORLD, Matrix); + + video::SMaterial &material = m_rotation_mesh_buffer.getMaterial(); + material.TextureLayer[0].Texture = texture; + driver->setMaterial(material); + driver->drawMeshBuffer(&m_rotation_mesh_buffer); + + driver->setTransform(video::ETS_WORLD, core::matrix4()); + driver->setTransform(video::ETS_VIEW, oldViewMat); + driver->setTransform(video::ETS_PROJECTION, oldProjMat); + + // restore the view area + driver->setViewPort(oldViewPort); +} + +void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, + const std::string &texture, const std::string &bgtexture, + s32 count, s32 maxcount, v2s32 offset, v2s32 size) +{ + const video::SColor color(255, 255, 255, 255); + const video::SColor colors[] = {color, color, color, color}; + + video::ITexture *stat_texture = tsrc->getTexture(texture); + if (!stat_texture) + return; + + video::ITexture *stat_texture_bg = nullptr; + if (!bgtexture.empty()) { + stat_texture_bg = tsrc->getTexture(bgtexture); + } + + core::dimension2di srcd(stat_texture->getOriginalSize()); + core::dimension2di dstd; + if (size == v2s32()) { + dstd = srcd; + dstd.Height *= m_scale_factor; + dstd.Width *= m_scale_factor; + offset.X *= m_scale_factor; + offset.Y *= m_scale_factor; + } else { + dstd.Height = size.Y * m_scale_factor; + dstd.Width = size.X * m_scale_factor; + offset.X *= m_scale_factor; + offset.Y *= m_scale_factor; + } + + v2s32 p = pos; + if (corner & HUD_CORNER_LOWER) + p -= dstd.Height; + + p += offset; + + v2s32 steppos; + switch (drawdir) { + case HUD_DIR_RIGHT_LEFT: + steppos = v2s32(-1, 0); + break; + case HUD_DIR_TOP_BOTTOM: + steppos = v2s32(0, 1); + break; + case HUD_DIR_BOTTOM_TOP: + steppos = v2s32(0, -1); + break; + default: + // From left to right + steppos = v2s32(1, 0); + break; + } + + auto calculate_clipping_rect = [] (core::dimension2di src, + v2s32 steppos) -> core::rect<s32> { + + // Create basic rectangle + core::rect<s32> rect(0, 0, + src.Width - std::abs(steppos.X) * src.Width / 2, + src.Height - std::abs(steppos.Y) * src.Height / 2 + ); + // Move rectangle left or down + if (steppos.X == -1) + rect += v2s32(src.Width / 2, 0); + if (steppos.Y == -1) + rect += v2s32(0, src.Height / 2); + return rect; + }; + // Rectangles for 1/2 the actual value to display + core::rect<s32> srchalfrect, dsthalfrect; + // Rectangles for 1/2 the "off state" texture + core::rect<s32> srchalfrect2, dsthalfrect2; + + if (count % 2 == 1 || maxcount % 2 == 1) { + // Need to draw halves: Calculate rectangles + srchalfrect = calculate_clipping_rect(srcd, steppos); + dsthalfrect = calculate_clipping_rect(dstd, steppos); + srchalfrect2 = calculate_clipping_rect(srcd, steppos * -1); + dsthalfrect2 = calculate_clipping_rect(dstd, steppos * -1); + } + + steppos.X *= dstd.Width; + steppos.Y *= dstd.Height; + + // Draw full textures + for (s32 i = 0; i < count / 2; i++) { + core::rect<s32> srcrect(0, 0, srcd.Width, srcd.Height); + core::rect<s32> dstrect(0, 0, dstd.Width, dstd.Height); + + dstrect += p; + draw2DImageFilterScaled(driver, stat_texture, + dstrect, srcrect, NULL, colors, true); + p += steppos; + } + + if (count % 2 == 1) { + // Draw half a texture + draw2DImageFilterScaled(driver, stat_texture, + dsthalfrect + p, srchalfrect, NULL, colors, true); + + if (stat_texture_bg && maxcount > count) { + draw2DImageFilterScaled(driver, stat_texture_bg, + dsthalfrect2 + p, srchalfrect2, + NULL, colors, true); + p += steppos; + } + } + + if (stat_texture_bg && maxcount > count) { + // Draw "off state" textures + s32 start_offset; + if (count % 2 == 1) + start_offset = count / 2 + 1; + else + start_offset = count / 2; + for (s32 i = start_offset; i < maxcount / 2; i++) { + core::rect<s32> srcrect(0, 0, srcd.Width, srcd.Height); + core::rect<s32> dstrect(0, 0, dstd.Width, dstd.Height); + + dstrect += p; + draw2DImageFilterScaled(driver, stat_texture_bg, + dstrect, srcrect, + NULL, colors, true); + p += steppos; + } + + if (maxcount % 2 == 1) { + draw2DImageFilterScaled(driver, stat_texture_bg, + dsthalfrect + p, srchalfrect, NULL, colors, true); + } + } +} + + +void Hud::drawHotbar(u16 playeritem) { + + v2s32 centerlowerpos(m_displaycenter.X, m_screensize.Y); + + InventoryList *mainlist = inventory->getList("main"); + if (mainlist == NULL) { + //silently ignore this we may not be initialized completely + return; + } + + s32 hotbar_itemcount = player->hud_hotbar_itemcount; + s32 width = hotbar_itemcount * (m_hotbar_imagesize + m_padding * 2); + v2s32 pos = centerlowerpos - v2s32(width / 2, m_hotbar_imagesize + m_padding * 3); + + const v2u32 &window_size = RenderingEngine::getWindowSize(); + if ((float) width / (float) window_size.X <= + g_settings->getFloat("hud_hotbar_max_width")) { + if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) { + drawItems(pos, v2s32(0, 0), hotbar_itemcount, 0, mainlist, playeritem + 1, 0); + } + } else { + pos.X += width/4; + + v2s32 secondpos = pos; + pos = pos - v2s32(0, m_hotbar_imagesize + m_padding); + + if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) { + drawItems(pos, v2s32(0, 0), hotbar_itemcount / 2, 0, + mainlist, playeritem + 1, 0); + drawItems(secondpos, v2s32(0, 0), hotbar_itemcount, + hotbar_itemcount / 2, mainlist, playeritem + 1, 0); + } + } +} + + +void Hud::drawCrosshair() +{ + if (pointing_at_object) { + if (use_object_crosshair_image) { + video::ITexture *object_crosshair = tsrc->getTexture("object_crosshair.png"); + v2u32 size = object_crosshair->getOriginalSize(); + v2s32 lsize = v2s32(m_displaycenter.X - (size.X / 2), + m_displaycenter.Y - (size.Y / 2)); + driver->draw2DImage(object_crosshair, lsize, + core::rect<s32>(0, 0, size.X, size.Y), + nullptr, crosshair_argb, true); + } else { + driver->draw2DLine( + m_displaycenter - v2s32(OBJECT_CROSSHAIR_LINE_SIZE, + OBJECT_CROSSHAIR_LINE_SIZE), + m_displaycenter + v2s32(OBJECT_CROSSHAIR_LINE_SIZE, + OBJECT_CROSSHAIR_LINE_SIZE), crosshair_argb); + driver->draw2DLine( + m_displaycenter + v2s32(OBJECT_CROSSHAIR_LINE_SIZE, + -OBJECT_CROSSHAIR_LINE_SIZE), + m_displaycenter + v2s32(-OBJECT_CROSSHAIR_LINE_SIZE, + OBJECT_CROSSHAIR_LINE_SIZE), crosshair_argb); + } + + return; + } + + if (use_crosshair_image) { + video::ITexture *crosshair = tsrc->getTexture("crosshair.png"); + v2u32 size = crosshair->getOriginalSize(); + v2s32 lsize = v2s32(m_displaycenter.X - (size.X / 2), + m_displaycenter.Y - (size.Y / 2)); + driver->draw2DImage(crosshair, lsize, + core::rect<s32>(0, 0, size.X, size.Y), + nullptr, crosshair_argb, true); + } else { + driver->draw2DLine(m_displaycenter - v2s32(CROSSHAIR_LINE_SIZE, 0), + m_displaycenter + v2s32(CROSSHAIR_LINE_SIZE, 0), crosshair_argb); + driver->draw2DLine(m_displaycenter - v2s32(0, CROSSHAIR_LINE_SIZE), + m_displaycenter + v2s32(0, CROSSHAIR_LINE_SIZE), crosshair_argb); + } +} + +void Hud::setSelectionPos(const v3f &pos, const v3s16 &camera_offset) +{ + m_camera_offset = camera_offset; + m_selection_pos = pos; + m_selection_pos_with_offset = pos - intToFloat(camera_offset, BS); +} + +void Hud::drawSelectionMesh() +{ + if (m_mode == HIGHLIGHT_BOX) { + // Draw 3D selection boxes + video::SMaterial oldmaterial = driver->getMaterial2D(); + driver->setMaterial(m_selection_material); + for (auto & selection_box : m_selection_boxes) { + aabb3f box = aabb3f( + selection_box.MinEdge + m_selection_pos_with_offset, + selection_box.MaxEdge + m_selection_pos_with_offset); + + u32 r = (selectionbox_argb.getRed() * + m_selection_mesh_color.getRed() / 255); + u32 g = (selectionbox_argb.getGreen() * + m_selection_mesh_color.getGreen() / 255); + u32 b = (selectionbox_argb.getBlue() * + m_selection_mesh_color.getBlue() / 255); + driver->draw3DBox(box, video::SColor(255, r, g, b)); + } + driver->setMaterial(oldmaterial); + } else if (m_mode == HIGHLIGHT_HALO && m_selection_mesh) { + // Draw selection mesh + video::SMaterial oldmaterial = driver->getMaterial2D(); + driver->setMaterial(m_selection_material); + setMeshColor(m_selection_mesh, m_selection_mesh_color); + video::SColor face_color(0, + MYMIN(255, m_selection_mesh_color.getRed() * 1.5), + MYMIN(255, m_selection_mesh_color.getGreen() * 1.5), + MYMIN(255, m_selection_mesh_color.getBlue() * 1.5)); + setMeshColorByNormal(m_selection_mesh, m_selected_face_normal, + face_color); + scene::IMesh* mesh = cloneMesh(m_selection_mesh); + translateMesh(mesh, m_selection_pos_with_offset); + u32 mc = m_selection_mesh->getMeshBufferCount(); + for (u32 i = 0; i < mc; i++) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); + driver->drawMeshBuffer(buf); + } + mesh->drop(); + driver->setMaterial(oldmaterial); + } +} + +enum Hud::BlockBoundsMode Hud::toggleBlockBounds() +{ + m_block_bounds_mode = static_cast<BlockBoundsMode>(m_block_bounds_mode + 1); + + if (m_block_bounds_mode >= BLOCK_BOUNDS_MAX) { + m_block_bounds_mode = BLOCK_BOUNDS_OFF; + } + return m_block_bounds_mode; +} + +void Hud::disableBlockBounds() +{ + m_block_bounds_mode = BLOCK_BOUNDS_OFF; +} + +void Hud::drawBlockBounds() +{ + if (m_block_bounds_mode == BLOCK_BOUNDS_OFF) { + return; + } + + video::SMaterial old_material = driver->getMaterial2D(); + driver->setMaterial(m_selection_material); + + v3s16 pos = player->getStandingNodePos(); + + v3s16 blockPos( + floorf((float) pos.X / MAP_BLOCKSIZE), + floorf((float) pos.Y / MAP_BLOCKSIZE), + floorf((float) pos.Z / MAP_BLOCKSIZE) + ); + + v3f offset = intToFloat(client->getCamera()->getOffset(), BS); + + s8 radius = m_block_bounds_mode == BLOCK_BOUNDS_NEAR ? 2 : 0; + + v3f halfNode = v3f(BS, BS, BS) / 2.0f; + + for (s8 x = -radius; x <= radius; x++) + for (s8 y = -radius; y <= radius; y++) + for (s8 z = -radius; z <= radius; z++) { + v3s16 blockOffset(x, y, z); + + aabb3f box( + intToFloat((blockPos + blockOffset) * MAP_BLOCKSIZE, BS) - offset - halfNode, + intToFloat(((blockPos + blockOffset) * MAP_BLOCKSIZE) + (MAP_BLOCKSIZE - 1), BS) - offset + halfNode + ); + + driver->draw3DBox(box, video::SColor(255, 255, 0, 0)); + } + + driver->setMaterial(old_material); +} + +void Hud::updateSelectionMesh(const v3s16 &camera_offset) +{ + m_camera_offset = camera_offset; + if (m_mode != HIGHLIGHT_HALO) + return; + + if (m_selection_mesh) { + m_selection_mesh->drop(); + m_selection_mesh = NULL; + } + + if (m_selection_boxes.empty()) { + // No pointed object + return; + } + + // New pointed object, create new mesh. + + // Texture UV coordinates for selection boxes + static f32 texture_uv[24] = { + 0,0,1,1, + 0,0,1,1, + 0,0,1,1, + 0,0,1,1, + 0,0,1,1, + 0,0,1,1 + }; + + // Use single halo box instead of multiple overlapping boxes. + // Temporary solution - problem can be solved with multiple + // rendering targets, or some method to remove inner surfaces. + // Thats because of halo transparency. + + aabb3f halo_box(100.0, 100.0, 100.0, -100.0, -100.0, -100.0); + m_halo_boxes.clear(); + + for (const auto &selection_box : m_selection_boxes) { + halo_box.addInternalBox(selection_box); + } + + m_halo_boxes.push_back(halo_box); + m_selection_mesh = convertNodeboxesToMesh( + m_halo_boxes, texture_uv, 0.5); +} + +void Hud::resizeHotbar() { + const v2u32 &window_size = RenderingEngine::getWindowSize(); + + if (m_screensize != window_size) { + m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * + RenderingEngine::getDisplayDensity() + 0.5); + m_hotbar_imagesize *= m_hud_scaling; + m_padding = m_hotbar_imagesize / 12; + m_screensize = window_size; + m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2); + } +} + +struct MeshTimeInfo { + u64 time; + scene::IMesh *mesh = nullptr; +}; + +void drawItemStack( + video::IVideoDriver *driver, + gui::IGUIFont *font, + const ItemStack &item, + const core::rect<s32> &rect, + const core::rect<s32> *clip, + Client *client, + ItemRotationKind rotation_kind, + const v3s16 &angle, + const v3s16 &rotation_speed) +{ + static MeshTimeInfo rotation_time_infos[IT_ROT_NONE]; + + if (item.empty()) { + if (rotation_kind < IT_ROT_NONE && rotation_kind != IT_ROT_OTHER) { + rotation_time_infos[rotation_kind].mesh = NULL; + } + return; + } + + const static thread_local bool enable_animations = + g_settings->getBool("inventory_items_animations"); + + const ItemDefinition &def = item.getDefinition(client->idef()); + + bool draw_overlay = false; + + bool has_mesh = false; + ItemMesh *imesh; + + core::rect<s32> viewrect = rect; + if (clip != nullptr) + viewrect.clipAgainst(*clip); + + // Render as mesh if animated or no inventory image + if ((enable_animations && rotation_kind < IT_ROT_NONE) || def.inventory_image.empty()) { + imesh = client->idef()->getWieldMesh(def.name, client); + has_mesh = imesh && imesh->mesh; + } + if (has_mesh) { + scene::IMesh *mesh = imesh->mesh; + driver->clearBuffers(video::ECBF_DEPTH); + s32 delta = 0; + if (rotation_kind < IT_ROT_NONE) { + MeshTimeInfo &ti = rotation_time_infos[rotation_kind]; + if (mesh != ti.mesh && rotation_kind != IT_ROT_OTHER) { + ti.mesh = mesh; + ti.time = porting::getTimeMs(); + } else { + delta = porting::getDeltaMs(ti.time, porting::getTimeMs()) % 100000; + } + } + core::rect<s32> oldViewPort = driver->getViewPort(); + core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION); + core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW); + + core::matrix4 ProjMatrix; + ProjMatrix.buildProjectionMatrixOrthoLH(2.0f, 2.0f, -1.0f, 100.0f); + + core::matrix4 ViewMatrix; + ViewMatrix.buildProjectionMatrixOrthoLH( + 2.0f * viewrect.getWidth() / rect.getWidth(), + 2.0f * viewrect.getHeight() / rect.getHeight(), + -1.0f, + 100.0f); + ViewMatrix.setTranslation(core::vector3df( + 1.0f * (rect.LowerRightCorner.X + rect.UpperLeftCorner.X - + viewrect.LowerRightCorner.X - viewrect.UpperLeftCorner.X) / + viewrect.getWidth(), + 1.0f * (viewrect.LowerRightCorner.Y + viewrect.UpperLeftCorner.Y - + rect.LowerRightCorner.Y - rect.UpperLeftCorner.Y) / + viewrect.getHeight(), + 0.0f)); + + driver->setTransform(video::ETS_PROJECTION, ProjMatrix); + driver->setTransform(video::ETS_VIEW, ViewMatrix); + + core::matrix4 matrix; + matrix.makeIdentity(); + + if (enable_animations) { + float timer_f = (float) delta / 5000.f; + matrix.setRotationDegrees(v3f( + angle.X + rotation_speed.X * 3.60f * timer_f, + angle.Y + rotation_speed.Y * 3.60f * timer_f, + angle.Z + rotation_speed.Z * 3.60f * timer_f) + ); + } + + driver->setTransform(video::ETS_WORLD, matrix); + driver->setViewPort(viewrect); + + video::SColor basecolor = + client->idef()->getItemstackColor(item, client); + + u32 mc = mesh->getMeshBufferCount(); + for (u32 j = 0; j < mc; ++j) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); + // we can modify vertices relatively fast, + // because these meshes are not buffered. + assert(buf->getHardwareMappingHint_Vertex() == scene::EHM_NEVER); + video::SColor c = basecolor; + + if (imesh->buffer_colors.size() > j) { + ItemPartColor *p = &imesh->buffer_colors[j]; + if (p->override_base) + c = p->color; + } + + if (imesh->needs_shading) + colorizeMeshBuffer(buf, &c); + else + setMeshBufferColor(buf, c); + + video::SMaterial &material = buf->getMaterial(); + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + material.Lighting = false; + driver->setMaterial(material); + driver->drawMeshBuffer(buf); + } + + driver->setTransform(video::ETS_VIEW, oldViewMat); + driver->setTransform(video::ETS_PROJECTION, oldProjMat); + driver->setViewPort(oldViewPort); + + draw_overlay = def.type == ITEM_NODE && def.inventory_image.empty(); + } else { // Otherwise just draw as 2D + video::ITexture *texture = client->idef()->getInventoryTexture(def.name, client); + video::SColor color; + if (texture) { + color = client->idef()->getItemstackColor(item, client); + } else { + color = video::SColor(255, 255, 255, 255); + ITextureSource *tsrc = client->getTextureSource(); + texture = tsrc->getTexture("no_texture.png"); + if (!texture) + return; + } + + const video::SColor colors[] = { color, color, color, color }; + + draw2DImageFilterScaled(driver, texture, rect, + core::rect<s32>({0, 0}, core::dimension2di(texture->getOriginalSize())), + clip, colors, true); + + draw_overlay = true; + } + + // draw the inventory_overlay + if (!def.inventory_overlay.empty() && draw_overlay) { + ITextureSource *tsrc = client->getTextureSource(); + video::ITexture *overlay_texture = tsrc->getTexture(def.inventory_overlay); + core::dimension2d<u32> dimens = overlay_texture->getOriginalSize(); + core::rect<s32> srcrect(0, 0, dimens.Width, dimens.Height); + draw2DImageFilterScaled(driver, overlay_texture, rect, srcrect, clip, 0, true); + } + + if (def.type == ITEM_TOOL && item.wear != 0) { + // Draw a progressbar + float barheight = static_cast<float>(rect.getHeight()) / 16; + float barpad_x = static_cast<float>(rect.getWidth()) / 16; + float barpad_y = static_cast<float>(rect.getHeight()) / 16; + + core::rect<s32> progressrect( + rect.UpperLeftCorner.X + barpad_x, + rect.LowerRightCorner.Y - barpad_y - barheight, + rect.LowerRightCorner.X - barpad_x, + rect.LowerRightCorner.Y - barpad_y); + + // Shrink progressrect by amount of tool damage + float wear = item.wear / 65535.0f; + int progressmid = + wear * progressrect.UpperLeftCorner.X + + (1 - wear) * progressrect.LowerRightCorner.X; + + // Compute progressbar color + // wear = 0.0: green + // wear = 0.5: yellow + // wear = 1.0: red + video::SColor color(255, 255, 255, 255); + int wear_i = MYMIN(std::floor(wear * 600), 511); + wear_i = MYMIN(wear_i + 10, 511); + + if (wear_i <= 255) + color.set(255, wear_i, 255, 0); + else + color.set(255, 255, 511 - wear_i, 0); + + core::rect<s32> progressrect2 = progressrect; + progressrect2.LowerRightCorner.X = progressmid; + driver->draw2DRectangle(color, progressrect2, clip); + + color = video::SColor(255, 0, 0, 0); + progressrect2 = progressrect; + progressrect2.UpperLeftCorner.X = progressmid; + driver->draw2DRectangle(color, progressrect2, clip); + } + + const std::string &count_text = item.metadata.getString("count_meta"); + if (font != nullptr && (item.count >= 2 || !count_text.empty())) { + // Get the item count as a string + std::string text = count_text.empty() ? itos(item.count) : count_text; + v2u32 dim = font->getDimension(utf8_to_wide(unescape_enriched(text)).c_str()); + v2s32 sdim(dim.X, dim.Y); + + core::rect<s32> rect2( + rect.LowerRightCorner - sdim, + rect.LowerRightCorner + ); + + // get the count alignment + s32 count_alignment = stoi(item.metadata.getString("count_alignment")); + if (count_alignment != 0) { + s32 a_x = count_alignment & 3; + s32 a_y = (count_alignment >> 2) & 3; + + s32 x1, x2, y1, y2; + switch (a_x) { + case 1: // left + x1 = rect.UpperLeftCorner.X; + x2 = x1 + sdim.X; + break; + case 2: // middle + x1 = (rect.UpperLeftCorner.X + rect.LowerRightCorner.X - sdim.X) / 2; + x2 = x1 + sdim.X; + break; + case 3: // right + x2 = rect.LowerRightCorner.X; + x1 = x2 - sdim.X; + break; + default: // 0 = default + x1 = rect2.UpperLeftCorner.X; + x2 = rect2.LowerRightCorner.X; + break; + } + + switch (a_y) { + case 1: // up + y1 = rect.UpperLeftCorner.Y; + y2 = y1 + sdim.Y; + break; + case 2: // middle + y1 = (rect.UpperLeftCorner.Y + rect.LowerRightCorner.Y - sdim.Y) / 2; + y2 = y1 + sdim.Y; + break; + case 3: // down + y2 = rect.LowerRightCorner.Y; + y1 = y2 - sdim.Y; + break; + default: // 0 = default + y1 = rect2.UpperLeftCorner.Y; + y2 = rect2.LowerRightCorner.Y; + break; + } + + rect2 = core::rect<s32>(x1, y1, x2, y2); + } + + video::SColor color(255, 255, 255, 255); + font->draw(utf8_to_wide(text).c_str(), rect2, color, false, false, &viewrect); + } +} + +void drawItemStack( + video::IVideoDriver *driver, + gui::IGUIFont *font, + const ItemStack &item, + const core::rect<s32> &rect, + const core::rect<s32> *clip, + Client *client, + ItemRotationKind rotation_kind) +{ + drawItemStack(driver, font, item, rect, clip, client, rotation_kind, + v3s16(0, 0, 0), v3s16(0, 100, 0)); +} diff --git a/src/client/hud.h b/src/client/hud.h new file mode 100644 index 0000000..fd79183 --- /dev/null +++ b/src/client/hud.h @@ -0,0 +1,173 @@ +/* +Minetest +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2017 red-001 <red-001@outlook.ie> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <vector> +#include <IGUIFont.h> +#include "irr_aabb3d.h" +#include "../hud.h" + +class Client; +class ITextureSource; +class Inventory; +class InventoryList; +class LocalPlayer; +struct ItemStack; + +class Hud +{ +public: + enum BlockBoundsMode + { + BLOCK_BOUNDS_OFF, + BLOCK_BOUNDS_CURRENT, + BLOCK_BOUNDS_NEAR, + BLOCK_BOUNDS_MAX + } m_block_bounds_mode = BLOCK_BOUNDS_OFF; + + video::SColor crosshair_argb; + video::SColor selectionbox_argb; + + bool use_crosshair_image = false; + bool use_object_crosshair_image = false; + std::string hotbar_image = ""; + bool use_hotbar_image = false; + std::string hotbar_selected_image = ""; + bool use_hotbar_selected_image = false; + + bool pointing_at_object = false; + + Hud(Client *client, LocalPlayer *player, + Inventory *inventory); + ~Hud(); + + enum BlockBoundsMode toggleBlockBounds(); + void disableBlockBounds(); + void drawBlockBounds(); + + void drawHotbar(u16 playeritem); + void resizeHotbar(); + void drawCrosshair(); + void drawSelectionMesh(); + void updateSelectionMesh(const v3s16 &camera_offset); + + std::vector<aabb3f> *getSelectionBoxes() { return &m_selection_boxes; } + + void setSelectionPos(const v3f &pos, const v3s16 &camera_offset); + + v3f getSelectionPos() const { return m_selection_pos; } + + void setSelectionMeshColor(const video::SColor &color) + { + m_selection_mesh_color = color; + } + + void setSelectedFaceNormal(const v3f &face_normal) + { + m_selected_face_normal = face_normal; + } + + bool hasElementOfType(HudElementType type); + + void drawLuaElements(const v3s16 &camera_offset); + +private: + bool calculateScreenPos(const v3s16 &camera_offset, HudElement *e, v2s32 *pos); + void drawStatbar(v2s32 pos, u16 corner, u16 drawdir, + const std::string &texture, const std::string& bgtexture, + s32 count, s32 maxcount, v2s32 offset, v2s32 size = v2s32()); + + void drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount, + s32 inv_offset, InventoryList *mainlist, u16 selectitem, + u16 direction); + + void drawItem(const ItemStack &item, const core::rect<s32> &rect, bool selected); + + void drawCompassTranslate(HudElement *e, video::ITexture *texture, + const core::rect<s32> &rect, int way); + + void drawCompassRotate(HudElement *e, video::ITexture *texture, + const core::rect<s32> &rect, int way); + + Client *client = nullptr; + video::IVideoDriver *driver = nullptr; + LocalPlayer *player = nullptr; + Inventory *inventory = nullptr; + ITextureSource *tsrc = nullptr; + + float m_hud_scaling; // cached minetest setting + float m_scale_factor; + v3s16 m_camera_offset; + v2u32 m_screensize; + v2s32 m_displaycenter; + s32 m_hotbar_imagesize; // Takes hud_scaling into account, updated by resizeHotbar() + s32 m_padding; // Takes hud_scaling into account, updated by resizeHotbar() + video::SColor hbar_colors[4]; + + std::vector<aabb3f> m_selection_boxes; + std::vector<aabb3f> m_halo_boxes; + v3f m_selection_pos; + v3f m_selection_pos_with_offset; + + scene::IMesh *m_selection_mesh = nullptr; + video::SColor m_selection_mesh_color; + v3f m_selected_face_normal; + + video::SMaterial m_selection_material; + + scene::SMeshBuffer m_rotation_mesh_buffer; + + enum + { + HIGHLIGHT_BOX, + HIGHLIGHT_HALO, + HIGHLIGHT_NONE + } m_mode; +}; + +enum ItemRotationKind +{ + IT_ROT_SELECTED, + IT_ROT_HOVERED, + IT_ROT_DRAGGED, + IT_ROT_OTHER, + IT_ROT_NONE, // Must be last, also serves as number +}; + +void drawItemStack(video::IVideoDriver *driver, + gui::IGUIFont *font, + const ItemStack &item, + const core::rect<s32> &rect, + const core::rect<s32> *clip, + Client *client, + ItemRotationKind rotation_kind); + +void drawItemStack( + video::IVideoDriver *driver, + gui::IGUIFont *font, + const ItemStack &item, + const core::rect<s32> &rect, + const core::rect<s32> *clip, + Client *client, + ItemRotationKind rotation_kind, + const v3s16 &angle, + const v3s16 &rotation_speed); + diff --git a/src/client/imagefilters.cpp b/src/client/imagefilters.cpp new file mode 100644 index 0000000..c9d1504 --- /dev/null +++ b/src/client/imagefilters.cpp @@ -0,0 +1,249 @@ +/* +Copyright (C) 2015 Aaron Suen <warr1024@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "imagefilters.h" +#include "util/numeric.h" +#include <cmath> +#include <cassert> +#include <vector> +#include <algorithm> + +// Simple 2D bitmap class with just the functionality needed here +class Bitmap { + u32 linesize, lines; + std::vector<u8> data; + + static inline u32 bytepos(u32 index) { return index >> 3; } + static inline u8 bitpos(u32 index) { return index & 7; } + +public: + Bitmap(u32 width, u32 height) : linesize(width), lines(height), + data(bytepos(width * height) + 1) {} + + inline bool get(u32 x, u32 y) const { + u32 index = y * linesize + x; + return data[bytepos(index)] & (1 << bitpos(index)); + } + + inline void set(u32 x, u32 y) { + u32 index = y * linesize + x; + data[bytepos(index)] |= 1 << bitpos(index); + } + + inline bool all() const { + for (u32 i = 0; i < data.size() - 1; i++) { + if (data[i] != 0xff) + return false; + } + // last byte not entirely filled + for (u8 i = 0; i < bitpos(linesize * lines); i++) { + bool value_of_bit = data.back() & (1 << i); + if (!value_of_bit) + return false; + } + return true; + } + + inline void copy(Bitmap &to) const { + assert(to.linesize == linesize && to.lines == lines); + to.data = data; + } +}; + +/* Fill in RGB values for transparent pixels, to correct for odd colors + * appearing at borders when blending. This is because many PNG optimizers + * like to discard RGB values of transparent pixels, but when blending then + * with non-transparent neighbors, their RGB values will show up nonetheless. + * + * This function modifies the original image in-place. + * + * Parameter "threshold" is the alpha level below which pixels are considered + * transparent. Should be 127 when the texture is used with ALPHA_CHANNEL_REF, + * 0 when alpha blending is used. + */ +void imageCleanTransparent(video::IImage *src, u32 threshold) +{ + core::dimension2d<u32> dim = src->getDimension(); + + Bitmap bitmap(dim.Width, dim.Height); + + // First pass: Mark all opaque pixels + // Note: loop y around x for better cache locality. + for (u32 ctry = 0; ctry < dim.Height; ctry++) + for (u32 ctrx = 0; ctrx < dim.Width; ctrx++) { + if (src->getPixel(ctrx, ctry).getAlpha() > threshold) + bitmap.set(ctrx, ctry); + } + + // Exit early if all pixels opaque + if (bitmap.all()) + return; + + Bitmap newmap = bitmap; + + // Cap iterations to keep runtime reasonable, for higher-res textures we can + // get away with filling less pixels. + int iter_max = 11 - std::max(dim.Width, dim.Height) / 16; + iter_max = std::max(iter_max, 2); + + // Then repeatedly look for transparent pixels, filling them in until + // we're finished. + for (int iter = 0; iter < iter_max; iter++) { + + for (u32 ctry = 0; ctry < dim.Height; ctry++) + for (u32 ctrx = 0; ctrx < dim.Width; ctrx++) { + // Skip pixels we have already processed + if (bitmap.get(ctrx, ctry)) + continue; + + video::SColor c = src->getPixel(ctrx, ctry); + + // Sample size and total weighted r, g, b values + u32 ss = 0, sr = 0, sg = 0, sb = 0; + + // Walk each neighbor pixel (clipped to image bounds) + for (u32 sy = (ctry < 1) ? 0 : (ctry - 1); + sy <= (ctry + 1) && sy < dim.Height; sy++) + for (u32 sx = (ctrx < 1) ? 0 : (ctrx - 1); + sx <= (ctrx + 1) && sx < dim.Width; sx++) { + // Ignore pixels we haven't processed + if (!bitmap.get(sx, sy)) + continue; + + // Add RGB values weighted by alpha IF the pixel is opaque, otherwise + // use full weight since we want to propagate colors. + video::SColor d = src->getPixel(sx, sy); + u32 a = d.getAlpha() <= threshold ? 255 : d.getAlpha(); + ss += a; + sr += a * d.getRed(); + sg += a * d.getGreen(); + sb += a * d.getBlue(); + } + + // Set pixel to average weighted by alpha + if (ss > 0) { + c.setRed(sr / ss); + c.setGreen(sg / ss); + c.setBlue(sb / ss); + src->setPixel(ctrx, ctry, c); + newmap.set(ctrx, ctry); + } + } + + if (newmap.all()) + return; + + // Apply changes to bitmap for next run. This is done so we don't introduce + // a bias in color propagation in the direction pixels are processed. + newmap.copy(bitmap); + + } +} + +/* Scale a region of an image into another image, using nearest-neighbor with + * anti-aliasing; treat pixels as crisp rectangles, but blend them at boundaries + * to prevent non-integer scaling ratio artifacts. Note that this may cause + * some blending at the edges where pixels don't line up perfectly, but this + * filter is designed to produce the most accurate results for both upscaling + * and downscaling. + */ +void imageScaleNNAA(video::IImage *src, const core::rect<s32> &srcrect, video::IImage *dest) +{ + double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa; + u32 dy, dx; + video::SColor pxl; + + // Cache rectangle boundaries. + double sox = srcrect.UpperLeftCorner.X * 1.0; + double soy = srcrect.UpperLeftCorner.Y * 1.0; + double sw = srcrect.getWidth() * 1.0; + double sh = srcrect.getHeight() * 1.0; + + // Walk each destination image pixel. + // Note: loop y around x for better cache locality. + core::dimension2d<u32> dim = dest->getDimension(); + for (dy = 0; dy < dim.Height; dy++) + for (dx = 0; dx < dim.Width; dx++) { + + // Calculate floating-point source rectangle bounds. + // Do some basic clipping, and for mirrored/flipped rects, + // make sure min/max are in the right order. + minsx = sox + (dx * sw / dim.Width); + minsx = rangelim(minsx, 0, sox + sw); + maxsx = minsx + sw / dim.Width; + maxsx = rangelim(maxsx, 0, sox + sw); + if (minsx > maxsx) + SWAP(double, minsx, maxsx); + minsy = soy + (dy * sh / dim.Height); + minsy = rangelim(minsy, 0, soy + sh); + maxsy = minsy + sh / dim.Height; + maxsy = rangelim(maxsy, 0, soy + sh); + if (minsy > maxsy) + SWAP(double, minsy, maxsy); + + // Total area, and integral of r, g, b values over that area, + // initialized to zero, to be summed up in next loops. + area = 0; + ra = 0; + ga = 0; + ba = 0; + aa = 0; + + // Loop over the integral pixel positions described by those bounds. + for (sy = floor(minsy); sy < maxsy; sy++) + for (sx = floor(minsx); sx < maxsx; sx++) { + + // Calculate width, height, then area of dest pixel + // that's covered by this source pixel. + pw = 1; + if (minsx > sx) + pw += sx - minsx; + if (maxsx < (sx + 1)) + pw += maxsx - sx - 1; + ph = 1; + if (minsy > sy) + ph += sy - minsy; + if (maxsy < (sy + 1)) + ph += maxsy - sy - 1; + pa = pw * ph; + + // Get source pixel and add it to totals, weighted + // by covered area and alpha. + pxl = src->getPixel((u32)sx, (u32)sy); + area += pa; + ra += pa * pxl.getRed(); + ga += pa * pxl.getGreen(); + ba += pa * pxl.getBlue(); + aa += pa * pxl.getAlpha(); + } + + // Set the destination image pixel to the average color. + if (area > 0) { + pxl.setRed(ra / area + 0.5); + pxl.setGreen(ga / area + 0.5); + pxl.setBlue(ba / area + 0.5); + pxl.setAlpha(aa / area + 0.5); + } else { + pxl.setRed(0); + pxl.setGreen(0); + pxl.setBlue(0); + pxl.setAlpha(0); + } + dest->setPixel(dx, dy, pxl); + } +} diff --git a/src/client/imagefilters.h b/src/client/imagefilters.h new file mode 100644 index 0000000..c9bdefb --- /dev/null +++ b/src/client/imagefilters.h @@ -0,0 +1,43 @@ +/* +Copyright (C) 2015 Aaron Suen <warr1024@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" + +/* Fill in RGB values for transparent pixels, to correct for odd colors + * appearing at borders when blending. This is because many PNG optimizers + * like to discard RGB values of transparent pixels, but when blending then + * with non-transparent neighbors, their RGB values will show up nonetheless. + * + * This function modifies the original image in-place. + * + * Parameter "threshold" is the alpha level below which pixels are considered + * transparent. Should be 127 when the texture is used with ALPHA_CHANNEL_REF, + * 0 when alpha blending is used. + */ +void imageCleanTransparent(video::IImage *src, u32 threshold); + +/* Scale a region of an image into another image, using nearest-neighbor with + * anti-aliasing; treat pixels as crisp rectangles, but blend them at boundaries + * to prevent non-integer scaling ratio artifacts. Note that this may cause + * some blending at the edges where pixels don't line up perfectly, but this + * filter is designed to produce the most accurate results for both upscaling + * and downscaling. + */ +void imageScaleNNAA(video::IImage *src, const core::rect<s32> &srcrect, video::IImage *dest); diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp new file mode 100644 index 0000000..a6ba87e --- /dev/null +++ b/src/client/inputhandler.cpp @@ -0,0 +1,278 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "util/numeric.h" +#include "inputhandler.h" +#include "gui/mainmenumanager.h" +#include "hud.h" + +void KeyCache::populate_nonchanging() +{ + key[KeyType::ESC] = EscapeKey; +} + +void KeyCache::populate() +{ + key[KeyType::FORWARD] = getKeySetting("keymap_forward"); + key[KeyType::BACKWARD] = getKeySetting("keymap_backward"); + key[KeyType::LEFT] = getKeySetting("keymap_left"); + key[KeyType::RIGHT] = getKeySetting("keymap_right"); + key[KeyType::JUMP] = getKeySetting("keymap_jump"); + key[KeyType::AUX1] = getKeySetting("keymap_aux1"); + key[KeyType::SNEAK] = getKeySetting("keymap_sneak"); + key[KeyType::DIG] = getKeySetting("keymap_dig"); + key[KeyType::PLACE] = getKeySetting("keymap_place"); + + key[KeyType::AUTOFORWARD] = getKeySetting("keymap_autoforward"); + + key[KeyType::DROP] = getKeySetting("keymap_drop"); + key[KeyType::INVENTORY] = getKeySetting("keymap_inventory"); + key[KeyType::CHAT] = getKeySetting("keymap_chat"); + key[KeyType::CMD] = getKeySetting("keymap_cmd"); + key[KeyType::CMD_LOCAL] = getKeySetting("keymap_cmd_local"); + key[KeyType::CONSOLE] = getKeySetting("keymap_console"); + key[KeyType::MINIMAP] = getKeySetting("keymap_minimap"); + key[KeyType::FREEMOVE] = getKeySetting("keymap_freemove"); + key[KeyType::PITCHMOVE] = getKeySetting("keymap_pitchmove"); + key[KeyType::FASTMOVE] = getKeySetting("keymap_fastmove"); + key[KeyType::NOCLIP] = getKeySetting("keymap_noclip"); + key[KeyType::HOTBAR_PREV] = getKeySetting("keymap_hotbar_previous"); + key[KeyType::HOTBAR_NEXT] = getKeySetting("keymap_hotbar_next"); + key[KeyType::MUTE] = getKeySetting("keymap_mute"); + key[KeyType::INC_VOLUME] = getKeySetting("keymap_increase_volume"); + key[KeyType::DEC_VOLUME] = getKeySetting("keymap_decrease_volume"); + key[KeyType::CINEMATIC] = getKeySetting("keymap_cinematic"); + key[KeyType::SCREENSHOT] = getKeySetting("keymap_screenshot"); + key[KeyType::TOGGLE_BLOCK_BOUNDS] = getKeySetting("keymap_toggle_block_bounds"); + key[KeyType::TOGGLE_HUD] = getKeySetting("keymap_toggle_hud"); + key[KeyType::TOGGLE_CHAT] = getKeySetting("keymap_toggle_chat"); + key[KeyType::TOGGLE_FOG] = getKeySetting("keymap_toggle_fog"); + key[KeyType::TOGGLE_UPDATE_CAMERA] = getKeySetting("keymap_toggle_update_camera"); + key[KeyType::TOGGLE_DEBUG] = getKeySetting("keymap_toggle_debug"); + key[KeyType::TOGGLE_PROFILER] = getKeySetting("keymap_toggle_profiler"); + key[KeyType::CAMERA_MODE] = getKeySetting("keymap_camera_mode"); + key[KeyType::INCREASE_VIEWING_RANGE] = + getKeySetting("keymap_increase_viewing_range_min"); + key[KeyType::DECREASE_VIEWING_RANGE] = + getKeySetting("keymap_decrease_viewing_range_min"); + key[KeyType::RANGESELECT] = getKeySetting("keymap_rangeselect"); + key[KeyType::ZOOM] = getKeySetting("keymap_zoom"); + + key[KeyType::QUICKTUNE_NEXT] = getKeySetting("keymap_quicktune_next"); + key[KeyType::QUICKTUNE_PREV] = getKeySetting("keymap_quicktune_prev"); + key[KeyType::QUICKTUNE_INC] = getKeySetting("keymap_quicktune_inc"); + key[KeyType::QUICKTUNE_DEC] = getKeySetting("keymap_quicktune_dec"); + + for (int i = 0; i < HUD_HOTBAR_ITEMCOUNT_MAX; i++) { + std::string slot_key_name = "keymap_slot" + std::to_string(i + 1); + key[KeyType::SLOT_1 + i] = getKeySetting(slot_key_name.c_str()); + } + + if (handler) { + // First clear all keys, then re-add the ones we listen for + handler->dontListenForKeys(); + for (const KeyPress &k : key) { + handler->listenForKey(k); + } + handler->listenForKey(EscapeKey); + handler->listenForKey(CancelKey); + } +} + +bool MyEventReceiver::OnEvent(const SEvent &event) +{ + /* + React to nothing here if a menu is active + */ + if (isMenuActive()) { +#ifdef HAVE_TOUCHSCREENGUI + if (m_touchscreengui) { + m_touchscreengui->Toggle(false); + } +#endif + return g_menumgr.preprocessEvent(event); + } + + // Remember whether each key is down or up + if (event.EventType == irr::EET_KEY_INPUT_EVENT) { + const KeyPress &keyCode = event.KeyInput; + if (keysListenedFor[keyCode]) { + if (event.KeyInput.PressedDown) { + if (!IsKeyDown(keyCode)) + keyWasPressed.set(keyCode); + + keyIsDown.set(keyCode); + keyWasDown.set(keyCode); + } else { + if (IsKeyDown(keyCode)) + keyWasReleased.set(keyCode); + + keyIsDown.unset(keyCode); + } + + return true; + } + +#ifdef HAVE_TOUCHSCREENGUI + } else if (m_touchscreengui && event.EventType == irr::EET_TOUCH_INPUT_EVENT) { + // In case of touchscreengui, we have to handle different events + m_touchscreengui->translateEvent(event); + return true; +#endif + + } else if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT) { + // joystick may be nullptr if game is launched with '--random-input' parameter + return joystick && joystick->handleEvent(event.JoystickEvent); + } else if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) { + // Handle mouse events + KeyPress key; + switch (event.MouseInput.Event) { + case EMIE_LMOUSE_PRESSED_DOWN: + key = "KEY_LBUTTON"; + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); + break; + case EMIE_MMOUSE_PRESSED_DOWN: + key = "KEY_MBUTTON"; + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); + break; + case EMIE_RMOUSE_PRESSED_DOWN: + key = "KEY_RBUTTON"; + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); + break; + case EMIE_LMOUSE_LEFT_UP: + key = "KEY_LBUTTON"; + keyIsDown.unset(key); + keyWasReleased.set(key); + break; + case EMIE_MMOUSE_LEFT_UP: + key = "KEY_MBUTTON"; + keyIsDown.unset(key); + keyWasReleased.set(key); + break; + case EMIE_RMOUSE_LEFT_UP: + key = "KEY_RBUTTON"; + keyIsDown.unset(key); + keyWasReleased.set(key); + break; + case EMIE_MOUSE_WHEEL: + mouse_wheel += event.MouseInput.Wheel; + break; + default: break; + } + } else if (event.EventType == irr::EET_LOG_TEXT_EVENT) { + static const LogLevel irr_loglev_conv[] = { + LL_VERBOSE, // ELL_DEBUG + LL_INFO, // ELL_INFORMATION + LL_WARNING, // ELL_WARNING + LL_ERROR, // ELL_ERROR + LL_NONE, // ELL_NONE + }; + assert(event.LogEvent.Level < ARRLEN(irr_loglev_conv)); + g_logger.log(irr_loglev_conv[event.LogEvent.Level], + std::string("Irrlicht: ") + event.LogEvent.Text); + return true; + } + /* always return false in order to continue processing events */ + return false; +} + +/* + * RandomInputHandler + */ +s32 RandomInputHandler::Rand(s32 min, s32 max) +{ + return (myrand() % (max - min + 1)) + min; +} + +struct RandomInputHandlerSimData { + std::string key; + float counter; + int time_max; +}; + +void RandomInputHandler::step(float dtime) +{ + static RandomInputHandlerSimData rnd_data[] = { + { "keymap_jump", 0.0f, 40 }, + { "keymap_aux1", 0.0f, 40 }, + { "keymap_forward", 0.0f, 40 }, + { "keymap_left", 0.0f, 40 }, + { "keymap_dig", 0.0f, 30 }, + { "keymap_place", 0.0f, 15 } + }; + + for (auto &i : rnd_data) { + i.counter -= dtime; + if (i.counter < 0.0) { + i.counter = 0.1 * Rand(1, i.time_max); + keydown.toggle(getKeySetting(i.key.c_str())); + } + } + { + static float counter1 = 0; + counter1 -= dtime; + if (counter1 < 0.0) { + counter1 = 0.1 * Rand(1, 20); + mousespeed = v2s32(Rand(-20, 20), Rand(-15, 20)); + } + } + mousepos += mousespeed; + static bool useJoystick = false; + { + static float counterUseJoystick = 0; + counterUseJoystick -= dtime; + if (counterUseJoystick < 0.0) { + counterUseJoystick = 5.0; // switch between joystick and keyboard direction input + useJoystick = !useJoystick; + } + } + if (useJoystick) { + static float counterMovement = 0; + counterMovement -= dtime; + if (counterMovement < 0.0) { + counterMovement = 0.1 * Rand(1, 40); + movementSpeed = Rand(0,100)*0.01; + movementDirection = Rand(-100, 100)*0.01 * M_PI; + } + } else { + bool f = keydown[keycache.key[KeyType::FORWARD]], + l = keydown[keycache.key[KeyType::LEFT]]; + if (f || l) { + movementSpeed = 1.0f; + if (f && !l) + movementDirection = 0.0; + else if (!f && l) + movementDirection = -M_PI_2; + else if (f && l) + movementDirection = -M_PI_4; + else + movementDirection = 0.0; + } else { + movementSpeed = 0.0; + movementDirection = 0.0; + } + } +} diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h new file mode 100644 index 0000000..3db105c --- /dev/null +++ b/src/client/inputhandler.h @@ -0,0 +1,435 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "joystick_controller.h" +#include <list> +#include "keycode.h" +#include "renderingengine.h" + +#ifdef HAVE_TOUCHSCREENGUI +#include "gui/touchscreengui.h" +#endif + +class InputHandler; + +/**************************************************************************** + Fast key cache for main game loop + ****************************************************************************/ + +/* This is faster than using getKeySetting with the tradeoff that functions + * using it must make sure that it's initialised before using it and there is + * no error handling (for example bounds checking). This is really intended for + * use only in the main running loop of the client (the_game()) where the faster + * (up to 10x faster) key lookup is an asset. Other parts of the codebase + * (e.g. formspecs) should continue using getKeySetting(). + */ +struct KeyCache +{ + + KeyCache() + { + handler = NULL; + populate(); + populate_nonchanging(); + } + + void populate(); + + // Keys that are not settings dependent + void populate_nonchanging(); + + KeyPress key[KeyType::INTERNAL_ENUM_COUNT]; + InputHandler *handler; +}; + +class KeyList : private std::list<KeyPress> +{ + typedef std::list<KeyPress> super; + typedef super::iterator iterator; + typedef super::const_iterator const_iterator; + + virtual const_iterator find(const KeyPress &key) const + { + const_iterator f(begin()); + const_iterator e(end()); + + while (f != e) { + if (*f == key) + return f; + + ++f; + } + + return e; + } + + virtual iterator find(const KeyPress &key) + { + iterator f(begin()); + iterator e(end()); + + while (f != e) { + if (*f == key) + return f; + + ++f; + } + + return e; + } + +public: + void clear() { super::clear(); } + + void set(const KeyPress &key) + { + if (find(key) == end()) + push_back(key); + } + + void unset(const KeyPress &key) + { + iterator p(find(key)); + + if (p != end()) + erase(p); + } + + void toggle(const KeyPress &key) + { + iterator p(this->find(key)); + + if (p != end()) + erase(p); + else + push_back(key); + } + + bool operator[](const KeyPress &key) const { return find(key) != end(); } +}; + +class MyEventReceiver : public IEventReceiver +{ +public: + // This is the one method that we have to implement + virtual bool OnEvent(const SEvent &event); + + bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown[keyCode]; } + + // Checks whether a key was down and resets the state + bool WasKeyDown(const KeyPress &keyCode) + { + bool b = keyWasDown[keyCode]; + if (b) + keyWasDown.unset(keyCode); + return b; + } + + // Checks whether a key was just pressed. State will be cleared + // in the subsequent iteration of Game::processPlayerInteraction + bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed[keycode]; } + + // Checks whether a key was just released. State will be cleared + // in the subsequent iteration of Game::processPlayerInteraction + bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased[keycode]; } + + void listenForKey(const KeyPress &keyCode) + { + keysListenedFor.set(keyCode); + } + void dontListenForKeys() + { + keysListenedFor.clear(); + } + + s32 getMouseWheel() + { + s32 a = mouse_wheel; + mouse_wheel = 0; + return a; + } + + void clearInput() + { + keyIsDown.clear(); + keyWasDown.clear(); + keyWasPressed.clear(); + keyWasReleased.clear(); + + mouse_wheel = 0; + } + + void clearWasKeyPressed() + { + keyWasPressed.clear(); + } + + void clearWasKeyReleased() + { + keyWasReleased.clear(); + } + + MyEventReceiver() + { +#ifdef HAVE_TOUCHSCREENGUI + m_touchscreengui = NULL; +#endif + } + + JoystickController *joystick = nullptr; + +#ifdef HAVE_TOUCHSCREENGUI + TouchScreenGUI *m_touchscreengui; +#endif + +private: + s32 mouse_wheel = 0; + + // The current state of keys + KeyList keyIsDown; + + // Like keyIsDown but only reset when that key is read + KeyList keyWasDown; + + // Whether a key has just been pressed + KeyList keyWasPressed; + + // Whether a key has just been released + KeyList keyWasReleased; + + // List of keys we listen for + // TODO perhaps the type of this is not really + // performant as KeyList is designed for few but + // often changing keys, and keysListenedFor is expected + // to change seldomly but contain lots of keys. + KeyList keysListenedFor; +}; + +class InputHandler +{ +public: + InputHandler() + { + keycache.handler = this; + keycache.populate(); + } + + virtual ~InputHandler() = default; + + virtual bool isRandom() const + { + return false; + } + + virtual bool isKeyDown(GameKeyType k) = 0; + virtual bool wasKeyDown(GameKeyType k) = 0; + virtual bool wasKeyPressed(GameKeyType k) = 0; + virtual bool wasKeyReleased(GameKeyType k) = 0; + virtual bool cancelPressed() = 0; + + virtual float getMovementSpeed() = 0; + virtual float getMovementDirection() = 0; + + virtual void clearWasKeyPressed() {} + virtual void clearWasKeyReleased() {} + + virtual void listenForKey(const KeyPress &keyCode) {} + virtual void dontListenForKeys() {} + + virtual v2s32 getMousePos() = 0; + virtual void setMousePos(s32 x, s32 y) = 0; + + virtual s32 getMouseWheel() = 0; + + virtual void step(float dtime) {} + + virtual void clear() {} + + JoystickController joystick; + KeyCache keycache; +}; +/* + Separated input handler +*/ + +class RealInputHandler : public InputHandler +{ +public: + RealInputHandler(MyEventReceiver *receiver) : m_receiver(receiver) + { + m_receiver->joystick = &joystick; + } + + virtual ~RealInputHandler() + { + m_receiver->joystick = nullptr; + } + + virtual bool isKeyDown(GameKeyType k) + { + return m_receiver->IsKeyDown(keycache.key[k]) || joystick.isKeyDown(k); + } + virtual bool wasKeyDown(GameKeyType k) + { + return m_receiver->WasKeyDown(keycache.key[k]) || joystick.wasKeyDown(k); + } + virtual bool wasKeyPressed(GameKeyType k) + { + return m_receiver->WasKeyPressed(keycache.key[k]) || joystick.wasKeyPressed(k); + } + virtual bool wasKeyReleased(GameKeyType k) + { + return m_receiver->WasKeyReleased(keycache.key[k]) || joystick.wasKeyReleased(k); + } + + virtual float getMovementSpeed() + { + bool f = m_receiver->IsKeyDown(keycache.key[KeyType::FORWARD]), + b = m_receiver->IsKeyDown(keycache.key[KeyType::BACKWARD]), + l = m_receiver->IsKeyDown(keycache.key[KeyType::LEFT]), + r = m_receiver->IsKeyDown(keycache.key[KeyType::RIGHT]); + if (f || b || l || r) + { + // if contradictory keys pressed, stay still + if (f && b && l && r) + return 0.0f; + else if (f && b && !l && !r) + return 0.0f; + else if (!f && !b && l && r) + return 0.0f; + return 1.0f; // If there is a keyboard event, assume maximum speed + } + return joystick.getMovementSpeed(); + } + + virtual float getMovementDirection() + { + float x = 0, z = 0; + + /* Check keyboard for input */ + if (m_receiver->IsKeyDown(keycache.key[KeyType::FORWARD])) + z += 1; + if (m_receiver->IsKeyDown(keycache.key[KeyType::BACKWARD])) + z -= 1; + if (m_receiver->IsKeyDown(keycache.key[KeyType::RIGHT])) + x += 1; + if (m_receiver->IsKeyDown(keycache.key[KeyType::LEFT])) + x -= 1; + + if (x != 0 || z != 0) /* If there is a keyboard event, it takes priority */ + return atan2(x, z); + else + return joystick.getMovementDirection(); + } + + virtual bool cancelPressed() + { + return wasKeyDown(KeyType::ESC) || m_receiver->WasKeyDown(CancelKey); + } + + virtual void clearWasKeyPressed() + { + m_receiver->clearWasKeyPressed(); + } + virtual void clearWasKeyReleased() + { + m_receiver->clearWasKeyReleased(); + } + + virtual void listenForKey(const KeyPress &keyCode) + { + m_receiver->listenForKey(keyCode); + } + virtual void dontListenForKeys() + { + m_receiver->dontListenForKeys(); + } + + virtual v2s32 getMousePos() + { + auto control = RenderingEngine::get_raw_device()->getCursorControl(); + if (control) { + return control->getPosition(); + } + + return m_mousepos; + } + + virtual void setMousePos(s32 x, s32 y) + { + auto control = RenderingEngine::get_raw_device()->getCursorControl(); + if (control) { + control->setPosition(x, y); + } else { + m_mousepos = v2s32(x, y); + } + } + + virtual s32 getMouseWheel() + { + return m_receiver->getMouseWheel(); + } + + void clear() + { + joystick.clear(); + m_receiver->clearInput(); + } + +private: + MyEventReceiver *m_receiver = nullptr; + v2s32 m_mousepos; +}; + +class RandomInputHandler : public InputHandler +{ +public: + RandomInputHandler() = default; + + bool isRandom() const + { + return true; + } + + virtual bool isKeyDown(GameKeyType k) { return keydown[keycache.key[k]]; } + virtual bool wasKeyDown(GameKeyType k) { return false; } + virtual bool wasKeyPressed(GameKeyType k) { return false; } + virtual bool wasKeyReleased(GameKeyType k) { return false; } + virtual bool cancelPressed() { return false; } + virtual float getMovementSpeed() { return movementSpeed; } + virtual float getMovementDirection() { return movementDirection; } + virtual v2s32 getMousePos() { return mousepos; } + virtual void setMousePos(s32 x, s32 y) { mousepos = v2s32(x, y); } + + virtual s32 getMouseWheel() { return 0; } + + virtual void step(float dtime); + + s32 Rand(s32 min, s32 max); + +private: + KeyList keydown; + v2s32 mousepos; + v2s32 mousespeed; + float movementSpeed; + float movementDirection; +}; diff --git a/src/client/joystick_controller.cpp b/src/client/joystick_controller.cpp new file mode 100644 index 0000000..9e58b9f --- /dev/null +++ b/src/client/joystick_controller.cpp @@ -0,0 +1,330 @@ +/* +Minetest +Copyright (C) 2016 est31, <MTest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "joystick_controller.h" +#include "irrlichttypes_extrabloated.h" +#include "keys.h" +#include "settings.h" +#include "gettime.h" +#include "porting.h" +#include "util/string.h" +#include "util/numeric.h" + +bool JoystickButtonCmb::isTriggered(const irr::SEvent::SJoystickEvent &ev) const +{ + u32 buttons = ev.ButtonStates; + + buttons &= filter_mask; + return buttons == compare_mask; +} + +bool JoystickAxisCmb::isTriggered(const irr::SEvent::SJoystickEvent &ev) const +{ + s16 ax_val = ev.Axis[axis_to_compare]; + + return (ax_val * direction < -thresh); +} + +// spares many characters +#define JLO_B_PB(A, B, C) jlo.button_keys.emplace_back(A, B, C) +#define JLO_A_PB(A, B, C, D) jlo.axis_keys.emplace_back(A, B, C, D) + +JoystickLayout create_default_layout() +{ + JoystickLayout jlo; + + jlo.axes_deadzone = g_settings->getU16("joystick_deadzone"); + + const JoystickAxisLayout axes[JA_COUNT] = { + {0, 1}, // JA_SIDEWARD_MOVE + {1, 1}, // JA_FORWARD_MOVE + {3, 1}, // JA_FRUSTUM_HORIZONTAL + {4, 1}, // JA_FRUSTUM_VERTICAL + }; + memcpy(jlo.axes, axes, sizeof(jlo.axes)); + + u32 sb = 1 << 7; // START button mask + u32 fb = 1 << 3; // FOUR button mask + u32 bm = sb | fb; // Mask for Both Modifiers + + // The back button means "ESC". + JLO_B_PB(KeyType::ESC, 1 << 6, 1 << 6); + + // The start button counts as modifier as well as use key. + // JLO_B_PB(KeyType::USE, sb, sb)); + + // Accessible without start modifier button pressed + // regardless whether four is pressed or not + JLO_B_PB(KeyType::SNEAK, sb | 1 << 2, 1 << 2); + + // Accessible without four modifier button pressed + // regardless whether start is pressed or not + JLO_B_PB(KeyType::DIG, fb | 1 << 4, 1 << 4); + JLO_B_PB(KeyType::PLACE, fb | 1 << 5, 1 << 5); + + // Accessible without any modifier pressed + JLO_B_PB(KeyType::JUMP, bm | 1 << 0, 1 << 0); + JLO_B_PB(KeyType::AUX1, bm | 1 << 1, 1 << 1); + + // Accessible with start button not pressed, but four pressed + // TODO find usage for button 0 + JLO_B_PB(KeyType::DROP, bm | 1 << 1, fb | 1 << 1); + JLO_B_PB(KeyType::HOTBAR_PREV, bm | 1 << 4, fb | 1 << 4); + JLO_B_PB(KeyType::HOTBAR_NEXT, bm | 1 << 5, fb | 1 << 5); + + // Accessible with start button and four pressed + // TODO find usage for buttons 0, 1 and 4, 5 + + // Now about the buttons simulated by the axes + + // Movement buttons, important for vessels + JLO_A_PB(KeyType::FORWARD, 1, 1, jlo.axes_deadzone); + JLO_A_PB(KeyType::BACKWARD, 1, -1, jlo.axes_deadzone); + JLO_A_PB(KeyType::LEFT, 0, 1, jlo.axes_deadzone); + JLO_A_PB(KeyType::RIGHT, 0, -1, jlo.axes_deadzone); + + // Scroll buttons + JLO_A_PB(KeyType::HOTBAR_PREV, 2, -1, jlo.axes_deadzone); + JLO_A_PB(KeyType::HOTBAR_NEXT, 5, -1, jlo.axes_deadzone); + + return jlo; +} + +JoystickLayout create_xbox_layout() +{ + JoystickLayout jlo; + + jlo.axes_deadzone = 7000; + + const JoystickAxisLayout axes[JA_COUNT] = { + {0, 1}, // JA_SIDEWARD_MOVE + {1, 1}, // JA_FORWARD_MOVE + {2, 1}, // JA_FRUSTUM_HORIZONTAL + {3, 1}, // JA_FRUSTUM_VERTICAL + }; + memcpy(jlo.axes, axes, sizeof(jlo.axes)); + + // The back button means "ESC". + JLO_B_PB(KeyType::ESC, 1 << 8, 1 << 8); // back + JLO_B_PB(KeyType::ESC, 1 << 9, 1 << 9); // start + + // 4 Buttons + JLO_B_PB(KeyType::JUMP, 1 << 0, 1 << 0); // A/green + JLO_B_PB(KeyType::ESC, 1 << 1, 1 << 1); // B/red + JLO_B_PB(KeyType::AUX1, 1 << 2, 1 << 2); // X/blue + JLO_B_PB(KeyType::INVENTORY, 1 << 3, 1 << 3); // Y/yellow + + // Analog Sticks + JLO_B_PB(KeyType::AUX1, 1 << 11, 1 << 11); // left + JLO_B_PB(KeyType::SNEAK, 1 << 12, 1 << 12); // right + + // Triggers + JLO_B_PB(KeyType::DIG, 1 << 6, 1 << 6); // lt + JLO_B_PB(KeyType::PLACE, 1 << 7, 1 << 7); // rt + JLO_B_PB(KeyType::HOTBAR_PREV, 1 << 4, 1 << 4); // lb + JLO_B_PB(KeyType::HOTBAR_NEXT, 1 << 5, 1 << 5); // rb + + // D-PAD + JLO_B_PB(KeyType::ZOOM, 1 << 15, 1 << 15); // up + JLO_B_PB(KeyType::DROP, 1 << 13, 1 << 13); // left + JLO_B_PB(KeyType::SCREENSHOT, 1 << 14, 1 << 14); // right + JLO_B_PB(KeyType::FREEMOVE, 1 << 16, 1 << 16); // down + + // Movement buttons, important for vessels + JLO_A_PB(KeyType::FORWARD, 1, 1, jlo.axes_deadzone); + JLO_A_PB(KeyType::BACKWARD, 1, -1, jlo.axes_deadzone); + JLO_A_PB(KeyType::LEFT, 0, 1, jlo.axes_deadzone); + JLO_A_PB(KeyType::RIGHT, 0, -1, jlo.axes_deadzone); + + return jlo; +} + +JoystickLayout create_dragonrise_gamecube_layout() +{ + JoystickLayout jlo; + + jlo.axes_deadzone = 7000; + + const JoystickAxisLayout axes[JA_COUNT] = { + // Control Stick + {0, 1}, // JA_SIDEWARD_MOVE + {1, 1}, // JA_FORWARD_MOVE + + // C-Stick + {3, 1}, // JA_FRUSTUM_HORIZONTAL + {4, 1}, // JA_FRUSTUM_VERTICAL + }; + memcpy(jlo.axes, axes, sizeof(jlo.axes)); + + // The center button + JLO_B_PB(KeyType::ESC, 1 << 9, 1 << 9); // Start/Pause Button + + // Front right buttons + JLO_B_PB(KeyType::JUMP, 1 << 2, 1 << 2); // A Button + JLO_B_PB(KeyType::SNEAK, 1 << 3, 1 << 3); // B Button + JLO_B_PB(KeyType::DROP, 1 << 0, 1 << 0); // Y Button + JLO_B_PB(KeyType::AUX1, 1 << 1, 1 << 1); // X Button + + // Triggers + JLO_B_PB(KeyType::DIG, 1 << 4, 1 << 4); // L Trigger + JLO_B_PB(KeyType::PLACE, 1 << 5, 1 << 5); // R Trigger + JLO_B_PB(KeyType::INVENTORY, 1 << 6, 1 << 6); // Z Button + + // D-Pad + JLO_A_PB(KeyType::HOTBAR_PREV, 5, 1, jlo.axes_deadzone); // left + JLO_A_PB(KeyType::HOTBAR_NEXT, 5, -1, jlo.axes_deadzone); // right + // Axis are hard to actuate independantly, best to leave up and down unused. + //JLO_A_PB(0, 6, 1, jlo.axes_deadzone); // up + //JLO_A_PB(0, 6, -1, jlo.axes_deadzone); // down + + // Movements tied to Control Stick, important for vessels + JLO_A_PB(KeyType::LEFT, 0, 1, jlo.axes_deadzone); + JLO_A_PB(KeyType::RIGHT, 0, -1, jlo.axes_deadzone); + JLO_A_PB(KeyType::FORWARD, 1, 1, jlo.axes_deadzone); + JLO_A_PB(KeyType::BACKWARD, 1, -1, jlo.axes_deadzone); + + return jlo; +} + + +JoystickController::JoystickController() +{ + doubling_dtime = std::max(g_settings->getFloat("repeat_joystick_button_time"), 0.001f); + for (float &i : m_past_pressed_time) { + i = 0; + } + m_layout.axes_deadzone = 0; + clear(); +} + +void JoystickController::onJoystickConnect(const std::vector<irr::SJoystickInfo> &joystick_infos) +{ + s32 id = g_settings->getS32("joystick_id"); + std::string layout = g_settings->get("joystick_type"); + + if (id < 0 || id >= (s32)joystick_infos.size()) { + // TODO: auto detection + id = 0; + } + + if (id >= 0 && id < (s32)joystick_infos.size()) { + if (layout.empty() || layout == "auto") + setLayoutFromControllerName(joystick_infos[id].Name.c_str()); + else + setLayoutFromControllerName(layout); + } + + // Irrlicht restriction. + m_joystick_id = rangelim(id, 0, UINT8_MAX); +} + +void JoystickController::setLayoutFromControllerName(const std::string &name) +{ + if (lowercase(name).find("xbox") != std::string::npos) { + m_layout = create_xbox_layout(); + } else if (lowercase(name).find("dragonrise_gamecube") != std::string::npos) { + m_layout = create_dragonrise_gamecube_layout(); + } else { + m_layout = create_default_layout(); + } +} + +bool JoystickController::handleEvent(const irr::SEvent::SJoystickEvent &ev) +{ + if (ev.Joystick != m_joystick_id) + return false; + + m_internal_time = porting::getTimeMs() / 1000.f; + + std::bitset<KeyType::INTERNAL_ENUM_COUNT> keys_pressed; + + // First generate a list of keys pressed + + for (const auto &button_key : m_layout.button_keys) { + if (button_key.isTriggered(ev)) { + keys_pressed.set(button_key.key); + } + } + + for (const auto &axis_key : m_layout.axis_keys) { + if (axis_key.isTriggered(ev)) { + keys_pressed.set(axis_key.key); + } + } + + // Then update the values + + for (size_t i = 0; i < KeyType::INTERNAL_ENUM_COUNT; i++) { + if (keys_pressed[i]) { + if (!m_past_keys_pressed[i] && + m_past_pressed_time[i] < m_internal_time - doubling_dtime) { + m_past_keys_pressed[i] = true; + m_past_pressed_time[i] = m_internal_time; + } + } else if (m_keys_down[i]) { + m_keys_released[i] = true; + } + + if (keys_pressed[i] && !(m_keys_down[i])) + m_keys_pressed[i] = true; + + m_keys_down[i] = keys_pressed[i]; + } + + for (size_t i = 0; i < JA_COUNT; i++) { + const JoystickAxisLayout &ax_la = m_layout.axes[i]; + m_axes_vals[i] = ax_la.invert * ev.Axis[ax_la.axis_id]; + } + + return true; +} + +void JoystickController::clear() +{ + m_keys_pressed.reset(); + m_keys_down.reset(); + m_past_keys_pressed.reset(); + m_keys_released.reset(); + memset(m_axes_vals, 0, sizeof(m_axes_vals)); +} + +float JoystickController::getAxisWithoutDead(JoystickAxis axis) +{ + s16 v = m_axes_vals[axis]; + + if (abs(v) < m_layout.axes_deadzone) + return 0.0f; + + v += (v < 0 ? m_layout.axes_deadzone : -m_layout.axes_deadzone); + + return (float)v / ((float)(INT16_MAX - m_layout.axes_deadzone)); +} + +float JoystickController::getMovementDirection() +{ + return atan2(getAxisWithoutDead(JA_SIDEWARD_MOVE), -getAxisWithoutDead(JA_FORWARD_MOVE)); +} + +float JoystickController::getMovementSpeed() +{ + float speed = sqrt(pow(getAxisWithoutDead(JA_FORWARD_MOVE), 2) + pow(getAxisWithoutDead(JA_SIDEWARD_MOVE), 2)); + if (speed > 1.0f) + speed = 1.0f; + return speed; +} diff --git a/src/client/joystick_controller.h b/src/client/joystick_controller.h new file mode 100644 index 0000000..cbc6088 --- /dev/null +++ b/src/client/joystick_controller.h @@ -0,0 +1,172 @@ +/* +Minetest +Copyright (C) 2016 est31, <MTest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "keys.h" +#include <bitset> +#include <vector> + +enum JoystickAxis { + JA_SIDEWARD_MOVE, + JA_FORWARD_MOVE, + + JA_FRUSTUM_HORIZONTAL, + JA_FRUSTUM_VERTICAL, + + // To know the count of enum values + JA_COUNT, +}; + +struct JoystickAxisLayout { + u16 axis_id; + // -1 if to invert, 1 if to keep it. + int invert; +}; + + +struct JoystickCombination { + + virtual bool isTriggered(const irr::SEvent::SJoystickEvent &ev) const=0; + + GameKeyType key; +}; + +struct JoystickButtonCmb : public JoystickCombination { + + JoystickButtonCmb() = default; + + JoystickButtonCmb(GameKeyType key, u32 filter_mask, u32 compare_mask) : + filter_mask(filter_mask), + compare_mask(compare_mask) + { + this->key = key; + } + + virtual ~JoystickButtonCmb() = default; + + virtual bool isTriggered(const irr::SEvent::SJoystickEvent &ev) const; + + u32 filter_mask; + u32 compare_mask; +}; + +struct JoystickAxisCmb : public JoystickCombination { + + JoystickAxisCmb() = default; + + JoystickAxisCmb(GameKeyType key, u16 axis_to_compare, int direction, s16 thresh) : + axis_to_compare(axis_to_compare), + direction(direction), + thresh(thresh) + { + this->key = key; + } + + virtual ~JoystickAxisCmb() = default; + + bool isTriggered(const irr::SEvent::SJoystickEvent &ev) const override; + + u16 axis_to_compare; + + // if -1, thresh must be smaller than the axis value in order to trigger + // if 1, thresh must be bigger than the axis value in order to trigger + int direction; + s16 thresh; +}; + +struct JoystickLayout { + std::vector<JoystickButtonCmb> button_keys; + std::vector<JoystickAxisCmb> axis_keys; + JoystickAxisLayout axes[JA_COUNT]; + s16 axes_deadzone; +}; + +class JoystickController { + +public: + JoystickController(); + + void onJoystickConnect(const std::vector<irr::SJoystickInfo> &joystick_infos); + + bool handleEvent(const irr::SEvent::SJoystickEvent &ev); + void clear(); + + bool wasKeyDown(GameKeyType b) + { + bool r = m_past_keys_pressed[b]; + m_past_keys_pressed[b] = false; + return r; + } + + bool wasKeyReleased(GameKeyType b) + { + return m_keys_released[b]; + } + void clearWasKeyReleased(GameKeyType b) + { + m_keys_released[b] = false; + } + + bool wasKeyPressed(GameKeyType b) + { + return m_keys_pressed[b]; + } + void clearWasKeyPressed(GameKeyType b) + { + m_keys_pressed[b] = false; + } + + bool isKeyDown(GameKeyType b) + { + return m_keys_down[b]; + } + + s16 getAxis(JoystickAxis axis) + { + return m_axes_vals[axis]; + } + + float getAxisWithoutDead(JoystickAxis axis); + + float getMovementDirection(); + float getMovementSpeed(); + + f32 doubling_dtime; + +private: + void setLayoutFromControllerName(const std::string &name); + + JoystickLayout m_layout; + + s16 m_axes_vals[JA_COUNT]; + + u8 m_joystick_id = 0; + + std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_keys_down; + std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_keys_pressed; + + f32 m_internal_time; + + f32 m_past_pressed_time[KeyType::INTERNAL_ENUM_COUNT]; + + std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_past_keys_pressed; + std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_keys_released; +}; diff --git a/src/client/keycode.cpp b/src/client/keycode.cpp new file mode 100644 index 0000000..fac077f --- /dev/null +++ b/src/client/keycode.cpp @@ -0,0 +1,386 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "keycode.h" +#include "exceptions.h" +#include "settings.h" +#include "log.h" +#include "debug.h" +#include "util/hex.h" +#include "util/string.h" +#include "util/basic_macros.h" + +class UnknownKeycode : public BaseException +{ +public: + UnknownKeycode(const char *s) : + BaseException(s) {}; +}; + +struct table_key { + const char *Name; + irr::EKEY_CODE Key; + wchar_t Char; // L'\0' means no character assigned + const char *LangName; // NULL means it doesn't have a human description +}; + +#define DEFINEKEY1(x, lang) /* Irrlicht key without character */ \ + { #x, irr::x, L'\0', lang }, +#define DEFINEKEY2(x, ch, lang) /* Irrlicht key with character */ \ + { #x, irr::x, ch, lang }, +#define DEFINEKEY3(ch) /* single Irrlicht key (e.g. KEY_KEY_X) */ \ + { "KEY_KEY_" TOSTRING(ch), irr::KEY_KEY_ ## ch, (wchar_t) *TOSTRING(ch), TOSTRING(ch) }, +#define DEFINEKEY4(ch) /* single Irrlicht function key (e.g. KEY_F3) */ \ + { "KEY_F" TOSTRING(ch), irr::KEY_F ## ch, L'\0', "F" TOSTRING(ch) }, +#define DEFINEKEY5(ch) /* key without Irrlicht keycode */ \ + { ch, irr::KEY_KEY_CODES_COUNT, (wchar_t) *ch, ch }, + +#define N_(text) text + +static const struct table_key table[] = { + // Keys that can be reliably mapped between Char and Key + DEFINEKEY3(0) + DEFINEKEY3(1) + DEFINEKEY3(2) + DEFINEKEY3(3) + DEFINEKEY3(4) + DEFINEKEY3(5) + DEFINEKEY3(6) + DEFINEKEY3(7) + DEFINEKEY3(8) + DEFINEKEY3(9) + DEFINEKEY3(A) + DEFINEKEY3(B) + DEFINEKEY3(C) + DEFINEKEY3(D) + DEFINEKEY3(E) + DEFINEKEY3(F) + DEFINEKEY3(G) + DEFINEKEY3(H) + DEFINEKEY3(I) + DEFINEKEY3(J) + DEFINEKEY3(K) + DEFINEKEY3(L) + DEFINEKEY3(M) + DEFINEKEY3(N) + DEFINEKEY3(O) + DEFINEKEY3(P) + DEFINEKEY3(Q) + DEFINEKEY3(R) + DEFINEKEY3(S) + DEFINEKEY3(T) + DEFINEKEY3(U) + DEFINEKEY3(V) + DEFINEKEY3(W) + DEFINEKEY3(X) + DEFINEKEY3(Y) + DEFINEKEY3(Z) + DEFINEKEY2(KEY_PLUS, L'+', "+") + DEFINEKEY2(KEY_COMMA, L',', ",") + DEFINEKEY2(KEY_MINUS, L'-', "-") + DEFINEKEY2(KEY_PERIOD, L'.', ".") + + // Keys without a Char + DEFINEKEY1(KEY_LBUTTON, N_("Left Button")) + DEFINEKEY1(KEY_RBUTTON, N_("Right Button")) + DEFINEKEY1(KEY_CANCEL, N_("Cancel")) + DEFINEKEY1(KEY_MBUTTON, N_("Middle Button")) + DEFINEKEY1(KEY_XBUTTON1, N_("X Button 1")) + DEFINEKEY1(KEY_XBUTTON2, N_("X Button 2")) + DEFINEKEY1(KEY_BACK, N_("Backspace")) + DEFINEKEY1(KEY_TAB, N_("Tab")) + DEFINEKEY1(KEY_CLEAR, N_("Clear")) + DEFINEKEY1(KEY_RETURN, N_("Return")) + DEFINEKEY1(KEY_SHIFT, N_("Shift")) + DEFINEKEY1(KEY_CONTROL, N_("Control")) + //~ Key name, common on Windows keyboards + DEFINEKEY1(KEY_MENU, N_("Menu")) + DEFINEKEY1(KEY_PAUSE, N_("Pause")) + DEFINEKEY1(KEY_CAPITAL, N_("Caps Lock")) + DEFINEKEY1(KEY_SPACE, N_("Space")) + DEFINEKEY1(KEY_PRIOR, N_("Page up")) + DEFINEKEY1(KEY_NEXT, N_("Page down")) + DEFINEKEY1(KEY_END, N_("End")) + DEFINEKEY1(KEY_HOME, N_("Home")) + DEFINEKEY1(KEY_LEFT, N_("Left")) + DEFINEKEY1(KEY_UP, N_("Up")) + DEFINEKEY1(KEY_RIGHT, N_("Right")) + DEFINEKEY1(KEY_DOWN, N_("Down")) + //~ Key name + DEFINEKEY1(KEY_SELECT, N_("Select")) + //~ "Print screen" key + DEFINEKEY1(KEY_PRINT, N_("Print")) + DEFINEKEY1(KEY_EXECUT, N_("Execute")) + DEFINEKEY1(KEY_SNAPSHOT, N_("Snapshot")) + DEFINEKEY1(KEY_INSERT, N_("Insert")) + DEFINEKEY1(KEY_DELETE, N_("Delete")) + DEFINEKEY1(KEY_HELP, N_("Help")) + DEFINEKEY1(KEY_LWIN, N_("Left Windows")) + DEFINEKEY1(KEY_RWIN, N_("Right Windows")) + DEFINEKEY1(KEY_NUMPAD0, N_("Numpad 0")) // These are not assigned to a char + DEFINEKEY1(KEY_NUMPAD1, N_("Numpad 1")) // to prevent interference with KEY_KEY_[0-9]. + DEFINEKEY1(KEY_NUMPAD2, N_("Numpad 2")) + DEFINEKEY1(KEY_NUMPAD3, N_("Numpad 3")) + DEFINEKEY1(KEY_NUMPAD4, N_("Numpad 4")) + DEFINEKEY1(KEY_NUMPAD5, N_("Numpad 5")) + DEFINEKEY1(KEY_NUMPAD6, N_("Numpad 6")) + DEFINEKEY1(KEY_NUMPAD7, N_("Numpad 7")) + DEFINEKEY1(KEY_NUMPAD8, N_("Numpad 8")) + DEFINEKEY1(KEY_NUMPAD9, N_("Numpad 9")) + DEFINEKEY1(KEY_MULTIPLY, N_("Numpad *")) + DEFINEKEY1(KEY_ADD, N_("Numpad +")) + DEFINEKEY1(KEY_SEPARATOR, N_("Numpad .")) + DEFINEKEY1(KEY_SUBTRACT, N_("Numpad -")) + DEFINEKEY1(KEY_DECIMAL, NULL) + DEFINEKEY1(KEY_DIVIDE, N_("Numpad /")) + DEFINEKEY4(1) + DEFINEKEY4(2) + DEFINEKEY4(3) + DEFINEKEY4(4) + DEFINEKEY4(5) + DEFINEKEY4(6) + DEFINEKEY4(7) + DEFINEKEY4(8) + DEFINEKEY4(9) + DEFINEKEY4(10) + DEFINEKEY4(11) + DEFINEKEY4(12) + DEFINEKEY4(13) + DEFINEKEY4(14) + DEFINEKEY4(15) + DEFINEKEY4(16) + DEFINEKEY4(17) + DEFINEKEY4(18) + DEFINEKEY4(19) + DEFINEKEY4(20) + DEFINEKEY4(21) + DEFINEKEY4(22) + DEFINEKEY4(23) + DEFINEKEY4(24) + DEFINEKEY1(KEY_NUMLOCK, N_("Num Lock")) + DEFINEKEY1(KEY_SCROLL, N_("Scroll Lock")) + DEFINEKEY1(KEY_LSHIFT, N_("Left Shift")) + DEFINEKEY1(KEY_RSHIFT, N_("Right Shift")) + DEFINEKEY1(KEY_LCONTROL, N_("Left Control")) + DEFINEKEY1(KEY_RCONTROL, N_("Right Control")) + DEFINEKEY1(KEY_LMENU, N_("Left Menu")) + DEFINEKEY1(KEY_RMENU, N_("Right Menu")) + + // Rare/weird keys + DEFINEKEY1(KEY_KANA, "Kana") + DEFINEKEY1(KEY_HANGUEL, "Hangul") + DEFINEKEY1(KEY_HANGUL, "Hangul") + DEFINEKEY1(KEY_JUNJA, "Junja") + DEFINEKEY1(KEY_FINAL, "Final") + DEFINEKEY1(KEY_KANJI, "Kanji") + DEFINEKEY1(KEY_HANJA, "Hanja") + DEFINEKEY1(KEY_ESCAPE, N_("IME Escape")) + DEFINEKEY1(KEY_CONVERT, N_("IME Convert")) + DEFINEKEY1(KEY_NONCONVERT, N_("IME Nonconvert")) + DEFINEKEY1(KEY_ACCEPT, N_("IME Accept")) + DEFINEKEY1(KEY_MODECHANGE, N_("IME Mode Change")) + DEFINEKEY1(KEY_APPS, N_("Apps")) + DEFINEKEY1(KEY_SLEEP, N_("Sleep")) + DEFINEKEY1(KEY_OEM_1, "OEM 1") // KEY_OEM_[0-9] and KEY_OEM_102 are assigned to multiple + DEFINEKEY1(KEY_OEM_2, "OEM 2") // different chars (on different platforms too) and thus w/o char + DEFINEKEY1(KEY_OEM_3, "OEM 3") + DEFINEKEY1(KEY_OEM_4, "OEM 4") + DEFINEKEY1(KEY_OEM_5, "OEM 5") + DEFINEKEY1(KEY_OEM_6, "OEM 6") + DEFINEKEY1(KEY_OEM_7, "OEM 7") + DEFINEKEY1(KEY_OEM_8, "OEM 8") + DEFINEKEY1(KEY_OEM_AX, "OEM AX") + DEFINEKEY1(KEY_OEM_102, "OEM 102") + DEFINEKEY1(KEY_ATTN, "Attn") + DEFINEKEY1(KEY_CRSEL, "CrSel") + DEFINEKEY1(KEY_EXSEL, "ExSel") + DEFINEKEY1(KEY_EREOF, N_("Erase EOF")) + DEFINEKEY1(KEY_PLAY, N_("Play")) + DEFINEKEY1(KEY_ZOOM, N_("Zoom")) + DEFINEKEY1(KEY_PA1, "PA1") + DEFINEKEY1(KEY_OEM_CLEAR, N_("OEM Clear")) + + // Keys without Irrlicht keycode + DEFINEKEY5("!") + DEFINEKEY5("\"") + DEFINEKEY5("#") + DEFINEKEY5("$") + DEFINEKEY5("%") + DEFINEKEY5("&") + DEFINEKEY5("'") + DEFINEKEY5("(") + DEFINEKEY5(")") + DEFINEKEY5("*") + DEFINEKEY5("/") + DEFINEKEY5(":") + DEFINEKEY5(";") + DEFINEKEY5("<") + DEFINEKEY5("=") + DEFINEKEY5(">") + DEFINEKEY5("?") + DEFINEKEY5("@") + DEFINEKEY5("[") + DEFINEKEY5("\\") + DEFINEKEY5("]") + DEFINEKEY5("^") + DEFINEKEY5("_") +}; + +#undef N_ + + +struct table_key lookup_keyname(const char *name) +{ + for (const auto &table_key : table) { + if (strcmp(table_key.Name, name) == 0) + return table_key; + } + + throw UnknownKeycode(name); +} + +struct table_key lookup_keykey(irr::EKEY_CODE key) +{ + for (const auto &table_key : table) { + if (table_key.Key == key) + return table_key; + } + + std::ostringstream os; + os << "<Keycode " << (int) key << ">"; + throw UnknownKeycode(os.str().c_str()); +} + +struct table_key lookup_keychar(wchar_t Char) +{ + for (const auto &table_key : table) { + if (table_key.Char == Char) + return table_key; + } + + std::ostringstream os; + os << "<Char " << hex_encode((char*) &Char, sizeof(wchar_t)) << ">"; + throw UnknownKeycode(os.str().c_str()); +} + +KeyPress::KeyPress(const char *name) +{ + if (strlen(name) == 0) { + Key = irr::KEY_KEY_CODES_COUNT; + Char = L'\0'; + m_name = ""; + return; + } + + if (strlen(name) <= 4) { + // Lookup by resulting character + int chars_read = mbtowc(&Char, name, 1); + FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character"); + try { + struct table_key k = lookup_keychar(Char); + m_name = k.Name; + Key = k.Key; + return; + } catch (UnknownKeycode &e) {}; + } else { + // Lookup by name + m_name = name; + try { + struct table_key k = lookup_keyname(name); + Key = k.Key; + Char = k.Char; + return; + } catch (UnknownKeycode &e) {}; + } + + // It's not a known key, complain and try to do something + Key = irr::KEY_KEY_CODES_COUNT; + int chars_read = mbtowc(&Char, name, 1); + FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character"); + m_name = ""; + warningstream << "KeyPress: Unknown key '" << name + << "', falling back to first char." << std::endl; +} + +KeyPress::KeyPress(const irr::SEvent::SKeyInput &in, bool prefer_character) +{ + if (prefer_character) + Key = irr::KEY_KEY_CODES_COUNT; + else + Key = in.Key; + Char = in.Char; + + try { + if (valid_kcode(Key)) + m_name = lookup_keykey(Key).Name; + else + m_name = lookup_keychar(Char).Name; + } catch (UnknownKeycode &e) { + m_name = ""; + }; +} + +const char *KeyPress::sym() const +{ + return m_name.c_str(); +} + +const char *KeyPress::name() const +{ + if (m_name.empty()) + return ""; + const char *ret; + if (valid_kcode(Key)) + ret = lookup_keykey(Key).LangName; + else + ret = lookup_keychar(Char).LangName; + return ret ? ret : "<Unnamed key>"; +} + +const KeyPress EscapeKey("KEY_ESCAPE"); +const KeyPress CancelKey("KEY_CANCEL"); + +/* + Key config +*/ + +// A simple cache for quicker lookup +std::unordered_map<std::string, KeyPress> g_key_setting_cache; + +KeyPress getKeySetting(const char *settingname) +{ + std::unordered_map<std::string, KeyPress>::iterator n; + n = g_key_setting_cache.find(settingname); + if (n != g_key_setting_cache.end()) + return n->second; + + KeyPress k(g_settings->get(settingname).c_str()); + g_key_setting_cache[settingname] = k; + return k; +} + +void clearKeyCache() +{ + g_key_setting_cache.clear(); +} + +irr::EKEY_CODE keyname_to_keycode(const char *name) +{ + return lookup_keyname(name).Key; +} diff --git a/src/client/keycode.h b/src/client/keycode.h new file mode 100644 index 0000000..7036705 --- /dev/null +++ b/src/client/keycode.h @@ -0,0 +1,67 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "Keycodes.h" +#include <IEventReceiver.h> +#include <string> + +/* A key press, consisting of either an Irrlicht keycode + or an actual char */ + +class KeyPress +{ +public: + KeyPress() = default; + + KeyPress(const char *name); + + KeyPress(const irr::SEvent::SKeyInput &in, bool prefer_character = false); + + bool operator==(const KeyPress &o) const + { + return (Char > 0 && Char == o.Char) || (valid_kcode(Key) && Key == o.Key); + } + + const char *sym() const; + const char *name() const; + +protected: + static bool valid_kcode(irr::EKEY_CODE k) + { + return k > 0 && k < irr::KEY_KEY_CODES_COUNT; + } + + irr::EKEY_CODE Key = irr::KEY_KEY_CODES_COUNT; + wchar_t Char = L'\0'; + std::string m_name = ""; +}; + +extern const KeyPress EscapeKey; +extern const KeyPress CancelKey; + +// Key configuration getter +KeyPress getKeySetting(const char *settingname); + +// Clear fast lookup cache +void clearKeyCache(); + +irr::EKEY_CODE keyname_to_keycode(const char *name); diff --git a/src/client/keys.h b/src/client/keys.h new file mode 100644 index 0000000..e120a2d --- /dev/null +++ b/src/client/keys.h @@ -0,0 +1,120 @@ +/* +Minetest +Copyright (C) 2016 est31, <MTest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <list> + +class KeyType +{ +public: + enum T + { + // Player movement + FORWARD, + BACKWARD, + LEFT, + RIGHT, + JUMP, + AUX1, + SNEAK, + AUTOFORWARD, + DIG, + PLACE, + + ESC, + + // Other + DROP, + INVENTORY, + CHAT, + CMD, + CMD_LOCAL, + CONSOLE, + MINIMAP, + FREEMOVE, + PITCHMOVE, + FASTMOVE, + NOCLIP, + HOTBAR_PREV, + HOTBAR_NEXT, + MUTE, + INC_VOLUME, + DEC_VOLUME, + CINEMATIC, + SCREENSHOT, + TOGGLE_BLOCK_BOUNDS, + TOGGLE_HUD, + TOGGLE_CHAT, + TOGGLE_FOG, + TOGGLE_UPDATE_CAMERA, + TOGGLE_DEBUG, + TOGGLE_PROFILER, + CAMERA_MODE, + INCREASE_VIEWING_RANGE, + DECREASE_VIEWING_RANGE, + RANGESELECT, + ZOOM, + + QUICKTUNE_NEXT, + QUICKTUNE_PREV, + QUICKTUNE_INC, + QUICKTUNE_DEC, + + // hotbar + SLOT_1, + SLOT_2, + SLOT_3, + SLOT_4, + SLOT_5, + SLOT_6, + SLOT_7, + SLOT_8, + SLOT_9, + SLOT_10, + SLOT_11, + SLOT_12, + SLOT_13, + SLOT_14, + SLOT_15, + SLOT_16, + SLOT_17, + SLOT_18, + SLOT_19, + SLOT_20, + SLOT_21, + SLOT_22, + SLOT_23, + SLOT_24, + SLOT_25, + SLOT_26, + SLOT_27, + SLOT_28, + SLOT_29, + SLOT_30, + SLOT_31, + SLOT_32, + + // Fake keycode for array size and internal checks + INTERNAL_ENUM_COUNT + + }; +}; + +typedef KeyType::T GameKeyType; diff --git a/src/client/localplayer.cpp b/src/client/localplayer.cpp new file mode 100644 index 0000000..79fe2cb --- /dev/null +++ b/src/client/localplayer.cpp @@ -0,0 +1,1138 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "localplayer.h" +#include <cmath> +#include "mtevent.h" +#include "collision.h" +#include "nodedef.h" +#include "settings.h" +#include "environment.h" +#include "map.h" +#include "client.h" +#include "content_cao.h" + +/* + LocalPlayer +*/ + +LocalPlayer::LocalPlayer(Client *client, const char *name): + Player(name, client->idef()), + m_client(client) +{ +} + +static aabb3f getNodeBoundingBox(const std::vector<aabb3f> &nodeboxes) +{ + if (nodeboxes.empty()) + return aabb3f(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + + aabb3f b_max; + + std::vector<aabb3f>::const_iterator it = nodeboxes.begin(); + b_max = aabb3f(it->MinEdge, it->MaxEdge); + + ++it; + for (; it != nodeboxes.end(); ++it) + b_max.addInternalBox(*it); + + return b_max; +} + +bool LocalPlayer::updateSneakNode(Map *map, const v3f &position, + const v3f &sneak_max) +{ + static const v3s16 dir9_center[9] = { + v3s16( 0, 0, 0), + v3s16( 1, 0, 0), + v3s16(-1, 0, 0), + v3s16( 0, 0, 1), + v3s16( 0, 0, -1), + v3s16( 1, 0, 1), + v3s16(-1, 0, 1), + v3s16( 1, 0, -1), + v3s16(-1, 0, -1) + }; + + const NodeDefManager *nodemgr = m_client->ndef(); + MapNode node; + bool is_valid_position; + bool new_sneak_node_exists = m_sneak_node_exists; + + // We want the top of the sneak node to be below the players feet + f32 position_y_mod = 0.05f * BS; + if (m_sneak_node_exists) + position_y_mod = m_sneak_node_bb_top.MaxEdge.Y - position_y_mod; + + // Get position of current standing node + const v3s16 current_node = floatToInt(position - v3f(0.0f, position_y_mod, 0.0f), BS); + + if (current_node != m_sneak_node) { + new_sneak_node_exists = false; + } else { + node = map->getNode(current_node, &is_valid_position); + if (!is_valid_position || !nodemgr->get(node).walkable) + new_sneak_node_exists = false; + } + + // Keep old sneak node + if (new_sneak_node_exists) + return true; + + // Get new sneak node + m_sneak_ladder_detected = false; + f32 min_distance_f = 100000.0f * BS; + + for (const auto &d : dir9_center) { + const v3s16 p = current_node + d; + const v3f pf = intToFloat(p, BS); + const v2f diff(position.X - pf.X, position.Z - pf.Z); + f32 distance_f = diff.getLength(); + + if (distance_f > min_distance_f || + fabs(diff.X) > (0.5f + 0.1f) * BS + sneak_max.X || + fabs(diff.Y) > (0.5f + 0.1f) * BS + sneak_max.Z) + continue; + + + // The node to be sneaked on has to be walkable + node = map->getNode(p, &is_valid_position); + if (!is_valid_position || !nodemgr->get(node).walkable) + continue; + // And the node(s) above have to be nonwalkable + bool ok = true; + if (!physics_override_sneak_glitch) { + u16 height = + ceilf((m_collisionbox.MaxEdge.Y - m_collisionbox.MinEdge.Y) / BS); + for (u16 y = 1; y <= height; y++) { + node = map->getNode(p + v3s16(0, y, 0), &is_valid_position); + if (!is_valid_position || nodemgr->get(node).walkable) { + ok = false; + break; + } + } + } else { + // legacy behaviour: check just one node + node = map->getNode(p + v3s16(0, 1, 0), &is_valid_position); + ok = is_valid_position && !nodemgr->get(node).walkable; + } + if (!ok) + continue; + + min_distance_f = distance_f; + m_sneak_node = p; + new_sneak_node_exists = true; + } + + if (!new_sneak_node_exists) + return false; + + // Update saved top bounding box of sneak node + node = map->getNode(m_sneak_node); + std::vector<aabb3f> nodeboxes; + node.getCollisionBoxes(nodemgr, &nodeboxes); + m_sneak_node_bb_top = getNodeBoundingBox(nodeboxes); + + if (physics_override_sneak_glitch) { + // Detect sneak ladder: + // Node two meters above sneak node must be solid + node = map->getNode(m_sneak_node + v3s16(0, 2, 0), + &is_valid_position); + if (is_valid_position && nodemgr->get(node).walkable) { + // Node three meters above: must be non-solid + node = map->getNode(m_sneak_node + v3s16(0, 3, 0), + &is_valid_position); + m_sneak_ladder_detected = is_valid_position && + !nodemgr->get(node).walkable; + } + } + return true; +} + +void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, + std::vector<CollisionInfo> *collision_info) +{ + // Node at feet position, update each ClientEnvironment::step() + if (!collision_info || collision_info->empty()) + m_standing_node = floatToInt(m_position, BS); + + // Temporary option for old move code + if (!physics_override_new_move) { + old_move(dtime, env, pos_max_d, collision_info); + return; + } + + Map *map = &env->getMap(); + const NodeDefManager *nodemgr = m_client->ndef(); + + v3f position = getPosition(); + + // Copy parent position if local player is attached + if (getParent()) { + setPosition(m_cao->getPosition()); + added_velocity = v3f(0.0f); // ignored + return; + } + + PlayerSettings &player_settings = getPlayerSettings(); + + // Skip collision detection if noclip mode is used + bool fly_allowed = m_client->checkLocalPrivilege("fly"); + bool noclip = m_client->checkLocalPrivilege("noclip") && player_settings.noclip; + bool free_move = player_settings.free_move && fly_allowed; + + if (noclip && free_move) { + position += m_speed * dtime; + setPosition(position); + + touching_ground = false; + added_velocity = v3f(0.0f); // ignored + return; + } + + m_speed += added_velocity; + added_velocity = v3f(0.0f); + + /* + Collision detection + */ + + bool is_valid_position; + MapNode node; + v3s16 pp; + + /* + Check if player is in liquid (the oscillating value) + */ + + // If in liquid, the threshold of coming out is at higher y + if (in_liquid) + { + pp = floatToInt(position + v3f(0.0f, BS * 0.1f, 0.0f), BS); + node = map->getNode(pp, &is_valid_position); + if (is_valid_position) { + const ContentFeatures &cf = nodemgr->get(node.getContent()); + in_liquid = cf.liquid_move_physics; + move_resistance = cf.move_resistance; + } else { + in_liquid = false; + } + } else { + // If not in liquid, the threshold of going in is at lower y + + pp = floatToInt(position + v3f(0.0f, BS * 0.5f, 0.0f), BS); + node = map->getNode(pp, &is_valid_position); + if (is_valid_position) { + const ContentFeatures &cf = nodemgr->get(node.getContent()); + in_liquid = cf.liquid_move_physics; + move_resistance = cf.move_resistance; + } else { + in_liquid = false; + } + } + + + /* + Check if player is in liquid (the stable value) + */ + pp = floatToInt(position + v3f(0.0f), BS); + node = map->getNode(pp, &is_valid_position); + if (is_valid_position) { + in_liquid_stable = nodemgr->get(node.getContent()).liquid_move_physics; + } else { + in_liquid_stable = false; + } + + /* + Check if player is climbing + */ + + pp = floatToInt(position + v3f(0.0f, 0.5f * BS, 0.0f), BS); + v3s16 pp2 = floatToInt(position + v3f(0.0f, -0.2f * BS, 0.0f), BS); + node = map->getNode(pp, &is_valid_position); + bool is_valid_position2; + MapNode node2 = map->getNode(pp2, &is_valid_position2); + + if (!(is_valid_position && is_valid_position2)) { + is_climbing = false; + } else { + is_climbing = (nodemgr->get(node.getContent()).climbable || + nodemgr->get(node2.getContent()).climbable) && !free_move; + } + + /* + Collision uncertainty radius + Make it a bit larger than the maximum distance of movement + */ + //f32 d = pos_max_d * 1.1; + // A fairly large value in here makes moving smoother + f32 d = 0.15f * BS; + + // This should always apply, otherwise there are glitches + sanity_check(d > pos_max_d); + + // Player object property step height is multiplied by BS in + // /src/script/common/c_content.cpp and /src/content_sao.cpp + float player_stepheight = (m_cao == nullptr) ? 0.0f : + (touching_ground ? m_cao->getStepHeight() : (0.2f * BS)); + + v3f accel_f; + const v3f initial_position = position; + const v3f initial_speed = m_speed; + + collisionMoveResult result = collisionMoveSimple(env, m_client, + pos_max_d, m_collisionbox, player_stepheight, dtime, + &position, &m_speed, accel_f); + + bool could_sneak = control.sneak && !free_move && !in_liquid && + !is_climbing && physics_override_sneak; + + // Add new collisions to the vector + if (collision_info && !free_move) { + v3f diff = intToFloat(m_standing_node, BS) - position; + f32 distance = diff.getLength(); + // Force update each ClientEnvironment::step() + bool is_first = collision_info->empty(); + + for (const auto &colinfo : result.collisions) { + collision_info->push_back(colinfo); + + if (colinfo.type != COLLISION_NODE || + colinfo.axis != COLLISION_AXIS_Y || + (could_sneak && m_sneak_node_exists)) + continue; + + diff = intToFloat(colinfo.node_p, BS) - position; + + // Find nearest colliding node + f32 len = diff.getLength(); + if (is_first || len < distance) { + m_standing_node = colinfo.node_p; + distance = len; + is_first = false; + } + } + } + + /* + If the player's feet touch the topside of any node, this is + set to true. + + Player is allowed to jump when this is true. + */ + bool touching_ground_was = touching_ground; + touching_ground = result.touching_ground; + bool sneak_can_jump = false; + + // Max. distance (X, Z) over border for sneaking determined by collision box + // * 0.49 to keep the center just barely on the node + v3f sneak_max = m_collisionbox.getExtent() * 0.49; + + if (m_sneak_ladder_detected) { + // restore legacy behaviour (this makes the m_speed.Y hack necessary) + sneak_max = v3f(0.4f * BS, 0.0f, 0.4f * BS); + } + + /* + If sneaking, keep on top of last walked node and don't fall off + */ + if (could_sneak && m_sneak_node_exists) { + const v3f sn_f = intToFloat(m_sneak_node, BS); + const v3f bmin = sn_f + m_sneak_node_bb_top.MinEdge; + const v3f bmax = sn_f + m_sneak_node_bb_top.MaxEdge; + const v3f old_pos = position; + const v3f old_speed = m_speed; + f32 y_diff = bmax.Y - position.Y; + m_standing_node = m_sneak_node; + + // (BS * 0.6f) is the basic stepheight while standing on ground + if (y_diff < BS * 0.6f) { + // Only center player when they're on the node + position.X = rangelim(position.X, + bmin.X - sneak_max.X, bmax.X + sneak_max.X); + position.Z = rangelim(position.Z, + bmin.Z - sneak_max.Z, bmax.Z + sneak_max.Z); + + if (position.X != old_pos.X) + m_speed.X = 0.0f; + if (position.Z != old_pos.Z) + m_speed.Z = 0.0f; + } + + if (y_diff > 0 && m_speed.Y <= 0.0f && + (physics_override_sneak_glitch || y_diff < BS * 0.6f)) { + // Move player to the maximal height when falling or when + // the ledge is climbed on the next step. + + // Smoothen the movement (based on 'position.Y = bmax.Y') + position.Y += y_diff * dtime * 22.0f + BS * 0.01f; + position.Y = std::min(position.Y, bmax.Y); + m_speed.Y = 0.0f; + } + + // Allow jumping on node edges while sneaking + if (m_speed.Y == 0.0f || m_sneak_ladder_detected) + sneak_can_jump = true; + + if (collision_info && + m_speed.Y - old_speed.Y > BS) { + // Collide with sneak node, report fall damage + CollisionInfo sn_info; + sn_info.node_p = m_sneak_node; + sn_info.old_speed = old_speed; + sn_info.new_speed = m_speed; + collision_info->push_back(sn_info); + } + } + + /* + Find the next sneak node if necessary + */ + bool new_sneak_node_exists = false; + + if (could_sneak) + new_sneak_node_exists = updateSneakNode(map, position, sneak_max); + + /* + Set new position but keep sneak node set + */ + setPosition(position); + m_sneak_node_exists = new_sneak_node_exists; + + /* + Report collisions + */ + + if (!result.standing_on_object && !touching_ground_was && touching_ground) { + m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_REGAIN_GROUND)); + + // Set camera impact value to be used for view bobbing + camera_impact = getSpeed().Y * -1; + } + + /* + Check properties of the node on which the player is standing + */ + const ContentFeatures &f = nodemgr->get(map->getNode(m_standing_node)); + const ContentFeatures &f1 = nodemgr->get(map->getNode(m_standing_node + v3s16(0, 1, 0))); + + // Determine if jumping is possible + m_disable_jump = itemgroup_get(f.groups, "disable_jump") || + itemgroup_get(f1.groups, "disable_jump"); + m_can_jump = ((touching_ground && !is_climbing) || sneak_can_jump) && !m_disable_jump; + + // Jump key pressed while jumping off from a bouncy block + if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") && + m_speed.Y >= -0.5f * BS) { + float jumpspeed = movement_speed_jump * physics_override_jump; + if (m_speed.Y > 1.0f) { + // Reduce boost when speed already is high + m_speed.Y += jumpspeed / (1.0f + (m_speed.Y / 16.0f)); + } else { + m_speed.Y += jumpspeed; + } + setSpeed(m_speed); + m_can_jump = false; + } + + // Autojump + handleAutojump(dtime, env, result, initial_position, initial_speed, pos_max_d); +} + +void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d) +{ + move(dtime, env, pos_max_d, NULL); +} + +void LocalPlayer::applyControl(float dtime, Environment *env) +{ + // Clear stuff + swimming_vertical = false; + swimming_pitch = false; + + setPitch(control.pitch); + setYaw(control.yaw); + + // Nullify speed and don't run positioning code if the player is attached + if (getParent()) { + setSpeed(v3f(0.0f)); + return; + } + + PlayerSettings &player_settings = getPlayerSettings(); + + // All vectors are relative to the player's yaw, + // (and pitch if pitch move mode enabled), + // and will be rotated at the end + v3f speedH, speedV; // Horizontal (X, Z) and Vertical (Y) + + bool fly_allowed = m_client->checkLocalPrivilege("fly"); + bool fast_allowed = m_client->checkLocalPrivilege("fast"); + + bool free_move = fly_allowed && player_settings.free_move; + bool fast_move = fast_allowed && player_settings.fast_move; + bool pitch_move = (free_move || in_liquid) && player_settings.pitch_move; + // When aux1_descends is enabled the fast key is used to go down, so fast isn't possible + bool fast_climb = fast_move && control.aux1 && !player_settings.aux1_descends; + bool always_fly_fast = player_settings.always_fly_fast; + + // Whether superspeed mode is used or not + bool superspeed = false; + + if (always_fly_fast && free_move && fast_move) + superspeed = true; + + // Old descend control + if (player_settings.aux1_descends) { + // If free movement and fast movement, always move fast + if (free_move && fast_move) + superspeed = true; + + // Auxiliary button 1 (E) + if (control.aux1) { + if (free_move) { + // In free movement mode, aux1 descends + if (fast_move) + speedV.Y = -movement_speed_fast; + else + speedV.Y = -movement_speed_walk; + } else if (in_liquid || in_liquid_stable) { + speedV.Y = -movement_speed_walk; + swimming_vertical = true; + } else if (is_climbing) { + speedV.Y = -movement_speed_climb; + } else { + // If not free movement but fast is allowed, aux1 is + // "Turbo button" + if (fast_move) + superspeed = true; + } + } + } else { + // New minecraft-like descend control + + // Auxiliary button 1 (E) + if (control.aux1) { + if (!is_climbing) { + // aux1 is "Turbo button" + if (fast_move) + superspeed = true; + } + } + + if (control.sneak) { + if (free_move) { + // In free movement mode, sneak descends + if (fast_move && (control.aux1 || always_fly_fast)) + speedV.Y = -movement_speed_fast; + else + speedV.Y = -movement_speed_walk; + } else if (in_liquid || in_liquid_stable) { + if (fast_climb) + speedV.Y = -movement_speed_fast; + else + speedV.Y = -movement_speed_walk; + swimming_vertical = true; + } else if (is_climbing) { + if (fast_climb) + speedV.Y = -movement_speed_fast; + else + speedV.Y = -movement_speed_climb; + } + } + } + + speedH = v3f(sin(control.movement_direction), 0.0f, cos(control.movement_direction)); + + if (m_autojump) { + // release autojump after a given time + m_autojump_time -= dtime; + if (m_autojump_time <= 0.0f) + m_autojump = false; + } + + if (control.jump) { + if (free_move) { + if (player_settings.aux1_descends || always_fly_fast) { + if (fast_move) + speedV.Y = movement_speed_fast; + else + speedV.Y = movement_speed_walk; + } else { + if (fast_move && control.aux1) + speedV.Y = movement_speed_fast; + else + speedV.Y = movement_speed_walk; + } + } else if (m_can_jump) { + /* + NOTE: The d value in move() affects jump height by + raising the height at which the jump speed is kept + at its starting value + */ + v3f speedJ = getSpeed(); + if (speedJ.Y >= -0.5f * BS) { + speedJ.Y = movement_speed_jump * physics_override_jump; + setSpeed(speedJ); + m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_JUMP)); + } + } else if (in_liquid && !m_disable_jump) { + if (fast_climb) + speedV.Y = movement_speed_fast; + else + speedV.Y = movement_speed_walk; + swimming_vertical = true; + } else if (is_climbing && !m_disable_jump) { + if (fast_climb) + speedV.Y = movement_speed_fast; + else + speedV.Y = movement_speed_climb; + } + } + + // The speed of the player (Y is ignored) + if (superspeed || (is_climbing && fast_climb) || + ((in_liquid || in_liquid_stable) && fast_climb)) + speedH = speedH.normalize() * movement_speed_fast; + else if (control.sneak && !free_move && !in_liquid && !in_liquid_stable) + speedH = speedH.normalize() * movement_speed_crouch; + else + speedH = speedH.normalize() * movement_speed_walk; + + speedH *= control.movement_speed; /* Apply analog input */ + + // Acceleration increase + f32 incH = 0.0f; // Horizontal (X, Z) + f32 incV = 0.0f; // Vertical (Y) + if ((!touching_ground && !free_move && !is_climbing && !in_liquid) || + (!free_move && m_can_jump && control.jump)) { + // Jumping and falling + if (superspeed || (fast_move && control.aux1)) + incH = movement_acceleration_fast * BS * dtime; + else + incH = movement_acceleration_air * BS * dtime; + incV = 0.0f; // No vertical acceleration in air + } else if (superspeed || (is_climbing && fast_climb) || + ((in_liquid || in_liquid_stable) && fast_climb)) { + incH = incV = movement_acceleration_fast * BS * dtime; + } else { + incH = incV = movement_acceleration_default * BS * dtime; + } + + float slip_factor = 1.0f; + if (!free_move && !in_liquid && !in_liquid_stable) + slip_factor = getSlipFactor(env, speedH); + + // Don't sink when swimming in pitch mode + if (pitch_move && in_liquid) { + v3f controlSpeed = speedH + speedV; + if (controlSpeed.getLength() > 0.01f) + swimming_pitch = true; + } + + // Accelerate to target speed with maximum increment + accelerate((speedH + speedV) * physics_override_speed, + incH * physics_override_speed * slip_factor, incV * physics_override_speed, + pitch_move); +} + +v3s16 LocalPlayer::getStandingNodePos() +{ + if (m_sneak_node_exists) + return m_sneak_node; + + return m_standing_node; +} + +v3s16 LocalPlayer::getFootstepNodePos() +{ + v3f feet_pos = getPosition() + v3f(0.0f, m_collisionbox.MinEdge.Y, 0.0f); + + // Emit swimming sound if the player is in liquid + if (in_liquid_stable) + return floatToInt(feet_pos, BS); + + // BS * 0.05 below the player's feet ensures a 1/16th height + // nodebox is detected instead of the node below it. + if (touching_ground) + return floatToInt(feet_pos - v3f(0.0f, BS * 0.05f, 0.0f), BS); + + // A larger distance below is necessary for a footstep sound + // when landing after a jump or fall. BS * 0.5 ensures water + // sounds when swimming in 1 node deep water. + return floatToInt(feet_pos - v3f(0.0f, BS * 0.5f, 0.0f), BS); +} + +v3s16 LocalPlayer::getLightPosition() const +{ + return floatToInt(m_position + v3f(0.0f, BS * 1.5f, 0.0f), BS); +} + +v3f LocalPlayer::getEyeOffset() const +{ + return v3f(0.0f, BS * m_eye_height, 0.0f); +} + +ClientActiveObject *LocalPlayer::getParent() const +{ + return m_cao ? m_cao->getParent() : nullptr; +} + +bool LocalPlayer::isDead() const +{ + FATAL_ERROR_IF(!getCAO(), "LocalPlayer's CAO isn't initialized"); + return !getCAO()->isImmortal() && hp == 0; +} + +// 3D acceleration +void LocalPlayer::accelerate(const v3f &target_speed, const f32 max_increase_H, + const f32 max_increase_V, const bool use_pitch) +{ + const f32 yaw = getYaw(); + const f32 pitch = getPitch(); + v3f flat_speed = m_speed; + // Rotate speed vector by -yaw and -pitch to make it relative to the player's yaw and pitch + flat_speed.rotateXZBy(-yaw); + if (use_pitch) + flat_speed.rotateYZBy(-pitch); + + v3f d_wanted = target_speed - flat_speed; + v3f d; + + // Then compare the horizontal and vertical components with the wanted speed + if (max_increase_H > 0.0f) { + v3f d_wanted_H = d_wanted * v3f(1.0f, 0.0f, 1.0f); + if (d_wanted_H.getLength() > max_increase_H) + d += d_wanted_H.normalize() * max_increase_H; + else + d += d_wanted_H; + } + + if (max_increase_V > 0.0f) { + f32 d_wanted_V = d_wanted.Y; + if (d_wanted_V > max_increase_V) + d.Y += max_increase_V; + else if (d_wanted_V < -max_increase_V) + d.Y -= max_increase_V; + else + d.Y += d_wanted_V; + } + + // Finally rotate it again + if (use_pitch) + d.rotateYZBy(pitch); + d.rotateXZBy(yaw); + + m_speed += d; +} + +// Temporary option for old move code +void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d, + std::vector<CollisionInfo> *collision_info) +{ + Map *map = &env->getMap(); + const NodeDefManager *nodemgr = m_client->ndef(); + + v3f position = getPosition(); + + // Copy parent position if local player is attached + if (getParent()) { + setPosition(m_cao->getPosition()); + m_sneak_node_exists = false; + added_velocity = v3f(0.0f); + return; + } + + PlayerSettings &player_settings = getPlayerSettings(); + + // Skip collision detection if noclip mode is used + bool fly_allowed = m_client->checkLocalPrivilege("fly"); + bool noclip = m_client->checkLocalPrivilege("noclip") && player_settings.noclip; + bool free_move = noclip && fly_allowed && player_settings.free_move; + if (free_move) { + position += m_speed * dtime; + setPosition(position); + + touching_ground = false; + m_sneak_node_exists = false; + added_velocity = v3f(0.0f); + return; + } + + m_speed += added_velocity; + added_velocity = v3f(0.0f); + + /* + Collision detection + */ + bool is_valid_position; + MapNode node; + v3s16 pp; + + /* + Check if player is in liquid (the oscillating value) + */ + if (in_liquid) { + // If in liquid, the threshold of coming out is at higher y + pp = floatToInt(position + v3f(0.0f, BS * 0.1f, 0.0f), BS); + node = map->getNode(pp, &is_valid_position); + if (is_valid_position) { + const ContentFeatures &cf = nodemgr->get(node.getContent()); + in_liquid = cf.liquid_move_physics; + move_resistance = cf.move_resistance; + } else { + in_liquid = false; + } + } else { + // If not in liquid, the threshold of going in is at lower y + pp = floatToInt(position + v3f(0.0f, BS * 0.5f, 0.0f), BS); + node = map->getNode(pp, &is_valid_position); + if (is_valid_position) { + const ContentFeatures &cf = nodemgr->get(node.getContent()); + in_liquid = cf.liquid_move_physics; + move_resistance = cf.move_resistance; + } else { + in_liquid = false; + } + } + + /* + Check if player is in liquid (the stable value) + */ + pp = floatToInt(position + v3f(0.0f), BS); + node = map->getNode(pp, &is_valid_position); + if (is_valid_position) + in_liquid_stable = nodemgr->get(node.getContent()).liquid_move_physics; + else + in_liquid_stable = false; + + /* + Check if player is climbing + */ + pp = floatToInt(position + v3f(0.0f, 0.5f * BS, 0.0f), BS); + v3s16 pp2 = floatToInt(position + v3f(0.0f, -0.2f * BS, 0.0f), BS); + node = map->getNode(pp, &is_valid_position); + bool is_valid_position2; + MapNode node2 = map->getNode(pp2, &is_valid_position2); + + if (!(is_valid_position && is_valid_position2)) + is_climbing = false; + else + is_climbing = (nodemgr->get(node.getContent()).climbable || + nodemgr->get(node2.getContent()).climbable) && !free_move; + + /* + Collision uncertainty radius + Make it a bit larger than the maximum distance of movement + */ + //f32 d = pos_max_d * 1.1; + // A fairly large value in here makes moving smoother + f32 d = 0.15f * BS; + // This should always apply, otherwise there are glitches + sanity_check(d > pos_max_d); + // Maximum distance over border for sneaking + f32 sneak_max = BS * 0.4f; + + /* + If sneaking, keep in range from the last walked node and don't + fall off from it + */ + if (control.sneak && m_sneak_node_exists && + !(fly_allowed && player_settings.free_move) && !in_liquid && + physics_override_sneak) { + f32 maxd = 0.5f * BS + sneak_max; + v3f lwn_f = intToFloat(m_sneak_node, BS); + position.X = rangelim(position.X, lwn_f.X - maxd, lwn_f.X + maxd); + position.Z = rangelim(position.Z, lwn_f.Z - maxd, lwn_f.Z + maxd); + + if (!is_climbing) { + // Move up if necessary + f32 new_y = (lwn_f.Y - 0.5f * BS) + m_sneak_node_bb_ymax; + if (position.Y < new_y) + position.Y = new_y; + /* + Collision seems broken, since player is sinking when + sneaking over the edges of current sneaking_node. + TODO (when fixed): Set Y-speed only to 0 when position.Y < new_y. + */ + if (m_speed.Y < 0.0f) + m_speed.Y = 0.0f; + } + } + + // TODO: This shouldn't be hardcoded but decided by the server + float player_stepheight = touching_ground ? (BS * 0.6f) : (BS * 0.2f); + + v3f accel_f; + const v3f initial_position = position; + const v3f initial_speed = m_speed; + + collisionMoveResult result = collisionMoveSimple(env, m_client, + pos_max_d, m_collisionbox, player_stepheight, dtime, + &position, &m_speed, accel_f); + + // Positition was slightly changed; update standing node pos + if (touching_ground) + m_standing_node = floatToInt(m_position - v3f(0.0f, 0.1f * BS, 0.0f), BS); + else + m_standing_node = floatToInt(m_position, BS); + + /* + If the player's feet touch the topside of any node, this is + set to true. + + Player is allowed to jump when this is true. + */ + bool touching_ground_was = touching_ground; + touching_ground = result.touching_ground; + + //bool standing_on_unloaded = result.standing_on_unloaded; + + /* + Check the nodes under the player to see from which node the + player is sneaking from, if any. If the node from under + the player has been removed, the player falls. + */ + f32 position_y_mod = 0.05f * BS; + if (m_sneak_node_bb_ymax > 0.0f) + position_y_mod = m_sneak_node_bb_ymax - position_y_mod; + v3s16 current_node = floatToInt(position - v3f(0.0f, position_y_mod, 0.0f), BS); + if (m_sneak_node_exists && + nodemgr->get(map->getNode(m_old_node_below)).name == "air" && + m_old_node_below_type != "air") { + // Old node appears to have been removed; that is, + // it wasn't air before but now it is + m_need_to_get_new_sneak_node = false; + m_sneak_node_exists = false; + } else if (nodemgr->get(map->getNode(current_node)).name != "air") { + // We are on something, so make sure to recalculate the sneak + // node. + m_need_to_get_new_sneak_node = true; + } + + if (m_need_to_get_new_sneak_node && physics_override_sneak) { + m_sneak_node_bb_ymax = 0.0f; + v3s16 pos_i_bottom = floatToInt(position - v3f(0.0f, position_y_mod, 0.0f), BS); + v2f player_p2df(position.X, position.Z); + f32 min_distance_f = 100000.0f * BS; + // If already seeking from some node, compare to it. + v3s16 new_sneak_node = m_sneak_node; + for (s16 x= -1; x <= 1; x++) + for (s16 z= -1; z <= 1; z++) { + v3s16 p = pos_i_bottom + v3s16(x, 0, z); + v3f pf = intToFloat(p, BS); + v2f node_p2df(pf.X, pf.Z); + f32 distance_f = player_p2df.getDistanceFrom(node_p2df); + f32 max_axis_distance_f = MYMAX( + std::fabs(player_p2df.X - node_p2df.X), + std::fabs(player_p2df.Y - node_p2df.Y)); + + if (distance_f > min_distance_f || + max_axis_distance_f > 0.5f * BS + sneak_max + 0.1f * BS) + continue; + + // The node to be sneaked on has to be walkable + node = map->getNode(p, &is_valid_position); + if (!is_valid_position || !nodemgr->get(node).walkable) + continue; + // And the node above it has to be nonwalkable + node = map->getNode(p + v3s16(0, 1, 0), &is_valid_position); + if (!is_valid_position || nodemgr->get(node).walkable) + continue; + // If not 'sneak_glitch' the node 2 nodes above it has to be nonwalkable + if (!physics_override_sneak_glitch) { + node = map->getNode(p + v3s16(0, 2, 0), &is_valid_position); + if (!is_valid_position || nodemgr->get(node).walkable) + continue; + } + + min_distance_f = distance_f; + new_sneak_node = p; + } + + bool sneak_node_found = (min_distance_f < 100000.0f * BS * 0.9f); + + m_sneak_node = new_sneak_node; + m_sneak_node_exists = sneak_node_found; + + if (sneak_node_found) { + f32 cb_max = 0.0f; + MapNode n = map->getNode(m_sneak_node); + std::vector<aabb3f> nodeboxes; + n.getCollisionBoxes(nodemgr, &nodeboxes); + for (const auto &box : nodeboxes) { + if (box.MaxEdge.Y > cb_max) + cb_max = box.MaxEdge.Y; + } + m_sneak_node_bb_ymax = cb_max; + } + + /* + If sneaking, the player's collision box can be in air, so + this has to be set explicitly + */ + if (sneak_node_found && control.sneak) + touching_ground = true; + } + + /* + Set new position but keep sneak node set + */ + bool sneak_node_exists = m_sneak_node_exists; + setPosition(position); + m_sneak_node_exists = sneak_node_exists; + + /* + Report collisions + */ + // Don't report if flying + if (collision_info && !(player_settings.free_move && fly_allowed)) { + for (const auto &info : result.collisions) { + collision_info->push_back(info); + } + } + + if (!result.standing_on_object && !touching_ground_was && touching_ground) { + m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_REGAIN_GROUND)); + // Set camera impact value to be used for view bobbing + camera_impact = getSpeed().Y * -1.0f; + } + + /* + Update the node last under the player + */ + m_old_node_below = floatToInt(position - v3f(0.0f, BS / 2.0f, 0.0f), BS); + m_old_node_below_type = nodemgr->get(map->getNode(m_old_node_below)).name; + + /* + Check properties of the node on which the player is standing + */ + const ContentFeatures &f = nodemgr->get(map->getNode(getStandingNodePos())); + + // Determine if jumping is possible + m_disable_jump = itemgroup_get(f.groups, "disable_jump"); + m_can_jump = touching_ground && !m_disable_jump; + + // Jump key pressed while jumping off from a bouncy block + if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") && + m_speed.Y >= -0.5f * BS) { + float jumpspeed = movement_speed_jump * physics_override_jump; + if (m_speed.Y > 1.0f) { + // Reduce boost when speed already is high + m_speed.Y += jumpspeed / (1.0f + (m_speed.Y / 16.0f)); + } else { + m_speed.Y += jumpspeed; + } + setSpeed(m_speed); + m_can_jump = false; + } + + // Autojump + handleAutojump(dtime, env, result, initial_position, initial_speed, pos_max_d); +} + +float LocalPlayer::getSlipFactor(Environment *env, const v3f &speedH) +{ + // Slip on slippery nodes + const NodeDefManager *nodemgr = env->getGameDef()->ndef(); + Map *map = &env->getMap(); + const ContentFeatures &f = nodemgr->get(map->getNode(getStandingNodePos())); + int slippery = 0; + if (f.walkable) + slippery = itemgroup_get(f.groups, "slippery"); + + if (slippery >= 1) { + if (speedH == v3f(0.0f)) + slippery *= 2; + + return core::clamp(1.0f / (slippery + 1), 0.001f, 1.0f); + } + return 1.0f; +} + +void LocalPlayer::handleAutojump(f32 dtime, Environment *env, + const collisionMoveResult &result, const v3f &initial_position, + const v3f &initial_speed, f32 pos_max_d) +{ + PlayerSettings &player_settings = getPlayerSettings(); + if (!player_settings.autojump) + return; + + if (m_autojump) + return; + + bool could_autojump = + m_can_jump && !control.jump && !control.sneak && control.isMoving(); + + if (!could_autojump) + return; + + bool horizontal_collision = false; + for (const auto &colinfo : result.collisions) { + if (colinfo.type == COLLISION_NODE && colinfo.plane != 1) { + horizontal_collision = true; + break; // one is enough + } + } + + // must be running against something to trigger autojumping + if (!horizontal_collision) + return; + + // check for nodes above + v3f headpos_min = m_position + m_collisionbox.MinEdge * 0.99f; + v3f headpos_max = m_position + m_collisionbox.MaxEdge * 0.99f; + headpos_min.Y = headpos_max.Y; // top face of collision box + v3s16 ceilpos_min = floatToInt(headpos_min, BS) + v3s16(0, 1, 0); + v3s16 ceilpos_max = floatToInt(headpos_max, BS) + v3s16(0, 1, 0); + const NodeDefManager *ndef = env->getGameDef()->ndef(); + bool is_position_valid; + for (s16 z = ceilpos_min.Z; z <= ceilpos_max.Z; ++z) { + for (s16 x = ceilpos_min.X; x <= ceilpos_max.X; ++x) { + MapNode n = env->getMap().getNode(v3s16(x, ceilpos_max.Y, z), &is_position_valid); + + if (!is_position_valid) + break; // won't collide with the void outside + if (n.getContent() == CONTENT_IGNORE) + return; // players collide with ignore blocks -> same as walkable + const ContentFeatures &f = ndef->get(n); + if (f.walkable) + return; // would bump head, don't jump + } + } + + float jump_height = 1.1f; // TODO: better than a magic number + v3f jump_pos = initial_position + v3f(0.0f, jump_height * BS, 0.0f); + v3f jump_speed = initial_speed; + + // try at peak of jump, zero step height + collisionMoveResult jump_result = collisionMoveSimple(env, m_client, pos_max_d, + m_collisionbox, 0.0f, dtime, &jump_pos, &jump_speed, v3f(0.0f)); + + // see if we can get a little bit farther horizontally if we had + // jumped + v3f run_delta = m_position - initial_position; + run_delta.Y = 0.0f; + v3f jump_delta = jump_pos - initial_position; + jump_delta.Y = 0.0f; + if (jump_delta.getLengthSQ() > run_delta.getLengthSQ() * 1.01f) { + m_autojump = true; + m_autojump_time = 0.1f; + } +} diff --git a/src/client/localplayer.h b/src/client/localplayer.h new file mode 100644 index 0000000..650a015 --- /dev/null +++ b/src/client/localplayer.h @@ -0,0 +1,215 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "player.h" +#include "environment.h" +#include "constants.h" +#include "settings.h" +#include "lighting.h" +#include <list> + +class Client; +class Environment; +class GenericCAO; +class ClientActiveObject; +class ClientEnvironment; +class IGameDef; +struct collisionMoveResult; + +enum LocalPlayerAnimations +{ + NO_ANIM, + WALK_ANIM, + DIG_ANIM, + WD_ANIM +}; // no local animation, walking, digging, both + +class LocalPlayer : public Player +{ +public: + LocalPlayer(Client *client, const char *name); + virtual ~LocalPlayer() = default; + + // Initialize hp to 0, so that no hearts will be shown if server + // doesn't support health points + u16 hp = 0; + bool touching_ground = false; + // This oscillates so that the player jumps a bit above the surface + bool in_liquid = false; + // This is more stable and defines the maximum speed of the player + bool in_liquid_stable = false; + // Slows down the player when moving through + u8 move_resistance = 0; + bool is_climbing = false; + bool swimming_vertical = false; + bool swimming_pitch = false; + + float physics_override_speed = 1.0f; + float physics_override_jump = 1.0f; + float physics_override_gravity = 1.0f; + bool physics_override_sneak = true; + bool physics_override_sneak_glitch = false; + // Temporary option for old move code + bool physics_override_new_move = true; + + void move(f32 dtime, Environment *env, f32 pos_max_d); + void move(f32 dtime, Environment *env, f32 pos_max_d, + std::vector<CollisionInfo> *collision_info); + // Temporary option for old move code + void old_move(f32 dtime, Environment *env, f32 pos_max_d, + std::vector<CollisionInfo> *collision_info); + + void applyControl(float dtime, Environment *env); + + v3s16 getStandingNodePos(); + v3s16 getFootstepNodePos(); + + // Used to check if anything changed and prevent sending packets if not + v3f last_position; + v3f last_speed; + float last_pitch = 0.0f; + float last_yaw = 0.0f; + u32 last_keyPressed = 0; + u8 last_camera_fov = 0; + u8 last_wanted_range = 0; + + float camera_impact = 0.0f; + + bool makes_footstep_sound = true; + + int last_animation = NO_ANIM; + float last_animation_speed = 0.0f; + + std::string hotbar_image = ""; + std::string hotbar_selected_image = ""; + + video::SColor light_color = video::SColor(255, 255, 255, 255); + + float hurt_tilt_timer = 0.0f; + float hurt_tilt_strength = 0.0f; + + GenericCAO *getCAO() const { return m_cao; } + + ClientActiveObject *getParent() const; + + void setCAO(GenericCAO *toset) + { + assert(!m_cao); // Pre-condition + m_cao = toset; + } + + u32 maxHudId() const { return hud.size(); } + + u16 getBreath() const { return m_breath; } + void setBreath(u16 breath) { m_breath = breath; } + + v3s16 getLightPosition() const; + + void setYaw(f32 yaw) { m_yaw = yaw; } + f32 getYaw() const { return m_yaw; } + + void setPitch(f32 pitch) { m_pitch = pitch; } + f32 getPitch() const { return m_pitch; } + + inline void setPosition(const v3f &position) + { + m_position = position; + m_sneak_node_exists = false; + } + + v3f getPosition() const { return m_position; } + + // Non-transformed eye offset getters + // For accurate positions, use the Camera functions + v3f getEyePosition() const { return m_position + getEyeOffset(); } + v3f getEyeOffset() const; + void setEyeHeight(float eye_height) { m_eye_height = eye_height; } + + void setCollisionbox(const aabb3f &box) { m_collisionbox = box; } + + const aabb3f& getCollisionbox() const { return m_collisionbox; } + + float getZoomFOV() const { return m_zoom_fov; } + void setZoomFOV(float zoom_fov) { m_zoom_fov = zoom_fov; } + + bool getAutojump() const { return m_autojump; } + + bool isDead() const; + + inline void addVelocity(const v3f &vel) + { + added_velocity += vel; + } + + inline Lighting& getLighting() { return m_lighting; } + +private: + void accelerate(const v3f &target_speed, const f32 max_increase_H, + const f32 max_increase_V, const bool use_pitch); + bool updateSneakNode(Map *map, const v3f &position, const v3f &sneak_max); + float getSlipFactor(Environment *env, const v3f &speedH); + void handleAutojump(f32 dtime, Environment *env, + const collisionMoveResult &result, + const v3f &position_before_move, const v3f &speed_before_move, + f32 pos_max_d); + + v3f m_position; + v3s16 m_standing_node; + + v3s16 m_sneak_node = v3s16(32767, 32767, 32767); + // Stores the top bounding box of m_sneak_node + aabb3f m_sneak_node_bb_top = aabb3f(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + // Whether the player is allowed to sneak + bool m_sneak_node_exists = false; + // Whether a "sneak ladder" structure is detected at the players pos + // see detectSneakLadder() in the .cpp for more info (always false if disabled) + bool m_sneak_ladder_detected = false; + + // ***** Variables for temporary option of the old move code ***** + // Stores the max player uplift by m_sneak_node + f32 m_sneak_node_bb_ymax = 0.0f; + // Whether recalculation of m_sneak_node and its top bbox is needed + bool m_need_to_get_new_sneak_node = true; + // Node below player, used to determine whether it has been removed, + // and its old type + v3s16 m_old_node_below = v3s16(32767, 32767, 32767); + std::string m_old_node_below_type = "air"; + // ***** End of variables for temporary option ***** + + bool m_can_jump = false; + bool m_disable_jump = false; + u16 m_breath = PLAYER_MAX_BREATH_DEFAULT; + f32 m_yaw = 0.0f; + f32 m_pitch = 0.0f; + aabb3f m_collisionbox = aabb3f(-BS * 0.30f, 0.0f, -BS * 0.30f, BS * 0.30f, + BS * 1.75f, BS * 0.30f); + float m_eye_height = 1.625f; + float m_zoom_fov = 0.0f; + bool m_autojump = false; + float m_autojump_time = 0.0f; + + v3f added_velocity = v3f(0.0f); // cleared on each move() + // TODO: Rename to adhere to convention: added_velocity --> m_added_velocity + + GenericCAO *m_cao = nullptr; + Client *m_client; + Lighting m_lighting; +}; diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp new file mode 100644 index 0000000..c730b9b --- /dev/null +++ b/src/client/mapblock_mesh.cpp @@ -0,0 +1,1581 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mapblock_mesh.h" +#include "client.h" +#include "mapblock.h" +#include "map.h" +#include "profiler.h" +#include "shader.h" +#include "mesh.h" +#include "minimap.h" +#include "content_mapblock.h" +#include "util/directiontables.h" +#include "client/meshgen/collector.h" +#include "client/renderingengine.h" +#include <array> +#include <algorithm> + +/* + MeshMakeData +*/ + +MeshMakeData::MeshMakeData(Client *client, bool use_shaders): + m_client(client), + m_use_shaders(use_shaders) +{} + +void MeshMakeData::fillBlockDataBegin(const v3s16 &blockpos) +{ + m_blockpos = blockpos; + + v3s16 blockpos_nodes = m_blockpos*MAP_BLOCKSIZE; + + m_vmanip.clear(); + VoxelArea voxel_area(blockpos_nodes - v3s16(1,1,1) * MAP_BLOCKSIZE, + blockpos_nodes + v3s16(1,1,1) * MAP_BLOCKSIZE*2-v3s16(1,1,1)); + m_vmanip.addArea(voxel_area); +} + +void MeshMakeData::fillBlockData(const v3s16 &block_offset, MapNode *data) +{ + v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE); + VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1)); + + v3s16 bp = m_blockpos + block_offset; + v3s16 blockpos_nodes = bp * MAP_BLOCKSIZE; + m_vmanip.copyFrom(data, data_area, v3s16(0,0,0), blockpos_nodes, data_size); +} + +void MeshMakeData::fill(MapBlock *block) +{ + fillBlockDataBegin(block->getPos()); + + fillBlockData(v3s16(0,0,0), block->getData()); + + // Get map for reading neighbor blocks + Map *map = block->getParent(); + + for (const v3s16 &dir : g_26dirs) { + v3s16 bp = m_blockpos + dir; + MapBlock *b = map->getBlockNoCreateNoEx(bp); + if(b) + fillBlockData(dir, b->getData()); + } +} + +void MeshMakeData::setCrack(int crack_level, v3s16 crack_pos) +{ + if (crack_level >= 0) + m_crack_pos_relative = crack_pos - m_blockpos*MAP_BLOCKSIZE; +} + +void MeshMakeData::setSmoothLighting(bool smooth_lighting) +{ + m_smooth_lighting = smooth_lighting; +} + +/* + Light and vertex color functions +*/ + +/* + Calculate non-smooth lighting at interior of node. + Single light bank. +*/ +static u8 getInteriorLight(enum LightBank bank, MapNode n, s32 increment, + const NodeDefManager *ndef) +{ + u8 light = n.getLight(bank, ndef); + if (light > 0) + light = rangelim(light + increment, 0, LIGHT_SUN); + return decode_light(light); +} + +/* + Calculate non-smooth lighting at interior of node. + Both light banks. +*/ +u16 getInteriorLight(MapNode n, s32 increment, const NodeDefManager *ndef) +{ + u16 day = getInteriorLight(LIGHTBANK_DAY, n, increment, ndef); + u16 night = getInteriorLight(LIGHTBANK_NIGHT, n, increment, ndef); + return day | (night << 8); +} + +/* + Calculate non-smooth lighting at face of node. + Single light bank. +*/ +static u8 getFaceLight(enum LightBank bank, MapNode n, MapNode n2, + v3s16 face_dir, const NodeDefManager *ndef) +{ + u8 light; + u8 l1 = n.getLight(bank, ndef); + u8 l2 = n2.getLight(bank, ndef); + if(l1 > l2) + light = l1; + else + light = l2; + + // Boost light level for light sources + u8 light_source = MYMAX(ndef->get(n).light_source, + ndef->get(n2).light_source); + if(light_source > light) + light = light_source; + + return decode_light(light); +} + +/* + Calculate non-smooth lighting at face of node. + Both light banks. +*/ +u16 getFaceLight(MapNode n, MapNode n2, const v3s16 &face_dir, + const NodeDefManager *ndef) +{ + u16 day = getFaceLight(LIGHTBANK_DAY, n, n2, face_dir, ndef); + u16 night = getFaceLight(LIGHTBANK_NIGHT, n, n2, face_dir, ndef); + return day | (night << 8); +} + +/* + Calculate smooth lighting at the XYZ- corner of p. + Both light banks +*/ +static u16 getSmoothLightCombined(const v3s16 &p, + const std::array<v3s16,8> &dirs, MeshMakeData *data) +{ + const NodeDefManager *ndef = data->m_client->ndef(); + + u16 ambient_occlusion = 0; + u16 light_count = 0; + u8 light_source_max = 0; + u16 light_day = 0; + u16 light_night = 0; + bool direct_sunlight = false; + + auto add_node = [&] (u8 i, bool obstructed = false) -> bool { + if (obstructed) { + ambient_occlusion++; + return false; + } + MapNode n = data->m_vmanip.getNodeNoExNoEmerge(p + dirs[i]); + if (n.getContent() == CONTENT_IGNORE) + return true; + const ContentFeatures &f = ndef->get(n); + if (f.light_source > light_source_max) + light_source_max = f.light_source; + // Check f.solidness because fast-style leaves look better this way + if (f.param_type == CPT_LIGHT && f.solidness != 2) { + u8 light_level_day = n.getLightNoChecks(LIGHTBANK_DAY, &f); + u8 light_level_night = n.getLightNoChecks(LIGHTBANK_NIGHT, &f); + if (light_level_day == LIGHT_SUN) + direct_sunlight = true; + light_day += decode_light(light_level_day); + light_night += decode_light(light_level_night); + light_count++; + } else { + ambient_occlusion++; + } + return f.light_propagates; + }; + + bool obstructed[4] = { true, true, true, true }; + add_node(0); + bool opaque1 = !add_node(1); + bool opaque2 = !add_node(2); + bool opaque3 = !add_node(3); + obstructed[0] = opaque1 && opaque2; + obstructed[1] = opaque1 && opaque3; + obstructed[2] = opaque2 && opaque3; + for (u8 k = 0; k < 3; ++k) + if (add_node(k + 4, obstructed[k])) + obstructed[3] = false; + if (add_node(7, obstructed[3])) { // wrap light around nodes + ambient_occlusion -= 3; + for (u8 k = 0; k < 3; ++k) + add_node(k + 4, !obstructed[k]); + } + + if (light_count == 0) { + light_day = light_night = 0; + } else { + light_day /= light_count; + light_night /= light_count; + } + + // boost direct sunlight, if any + if (direct_sunlight) + light_day = 0xFF; + + // Boost brightness around light sources + bool skip_ambient_occlusion_day = false; + if (decode_light(light_source_max) >= light_day) { + light_day = decode_light(light_source_max); + skip_ambient_occlusion_day = true; + } + + bool skip_ambient_occlusion_night = false; + if(decode_light(light_source_max) >= light_night) { + light_night = decode_light(light_source_max); + skip_ambient_occlusion_night = true; + } + + if (ambient_occlusion > 4) { + static thread_local const float ao_gamma = rangelim( + g_settings->getFloat("ambient_occlusion_gamma"), 0.25, 4.0); + + // Table of gamma space multiply factors. + static thread_local const float light_amount[3] = { + powf(0.75, 1.0 / ao_gamma), + powf(0.5, 1.0 / ao_gamma), + powf(0.25, 1.0 / ao_gamma) + }; + + //calculate table index for gamma space multiplier + ambient_occlusion -= 5; + + if (!skip_ambient_occlusion_day) + light_day = rangelim(core::round32( + light_day * light_amount[ambient_occlusion]), 0, 255); + if (!skip_ambient_occlusion_night) + light_night = rangelim(core::round32( + light_night * light_amount[ambient_occlusion]), 0, 255); + } + + return light_day | (light_night << 8); +} + +/* + Calculate smooth lighting at the given corner of p. + Both light banks. + Node at p is solid, and thus the lighting is face-dependent. +*/ +u16 getSmoothLightSolid(const v3s16 &p, const v3s16 &face_dir, const v3s16 &corner, MeshMakeData *data) +{ + return getSmoothLightTransparent(p + face_dir, corner - 2 * face_dir, data); +} + +/* + Calculate smooth lighting at the given corner of p. + Both light banks. + Node at p is not solid, and the lighting is not face-dependent. +*/ +u16 getSmoothLightTransparent(const v3s16 &p, const v3s16 &corner, MeshMakeData *data) +{ + const std::array<v3s16,8> dirs = {{ + // Always shine light + v3s16(0,0,0), + v3s16(corner.X,0,0), + v3s16(0,corner.Y,0), + v3s16(0,0,corner.Z), + + // Can be obstructed + v3s16(corner.X,corner.Y,0), + v3s16(corner.X,0,corner.Z), + v3s16(0,corner.Y,corner.Z), + v3s16(corner.X,corner.Y,corner.Z) + }}; + return getSmoothLightCombined(p, dirs, data); +} + +void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio){ + f32 rg = daynight_ratio / 1000.0f - 0.04f; + f32 b = (0.98f * daynight_ratio) / 1000.0f + 0.078f; + sunlight->r = rg; + sunlight->g = rg; + sunlight->b = b; +} + +void final_color_blend(video::SColor *result, + u16 light, u32 daynight_ratio) +{ + video::SColorf dayLight; + get_sunlight_color(&dayLight, daynight_ratio); + final_color_blend(result, + encode_light(light, 0), dayLight); +} + +void final_color_blend(video::SColor *result, + const video::SColor &data, const video::SColorf &dayLight) +{ + static const video::SColorf artificialColor(1.04f, 1.04f, 1.04f); + + video::SColorf c(data); + f32 n = 1 - c.a; + + f32 r = c.r * (c.a * dayLight.r + n * artificialColor.r) * 2.0f; + f32 g = c.g * (c.a * dayLight.g + n * artificialColor.g) * 2.0f; + f32 b = c.b * (c.a * dayLight.b + n * artificialColor.b) * 2.0f; + + // Emphase blue a bit in darker places + // Each entry of this array represents a range of 8 blue levels + static const u8 emphase_blue_when_dark[32] = { + 1, 4, 6, 6, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + b += emphase_blue_when_dark[irr::core::clamp((s32) ((r + g + b) / 3 * 255), + 0, 255) / 8] / 255.0f; + + result->setRed(core::clamp((s32) (r * 255.0f), 0, 255)); + result->setGreen(core::clamp((s32) (g * 255.0f), 0, 255)); + result->setBlue(core::clamp((s32) (b * 255.0f), 0, 255)); +} + +/* + Mesh generation helpers +*/ + +// This table is moved outside getNodeVertexDirs to avoid the compiler using +// a mutex to initialize this table at runtime right in the hot path. +// For details search the internet for "cxa_guard_acquire". +static const v3s16 vertex_dirs_table[] = { + // ( 1, 0, 0) + v3s16( 1,-1, 1), v3s16( 1,-1,-1), + v3s16( 1, 1,-1), v3s16( 1, 1, 1), + // ( 0, 1, 0) + v3s16( 1, 1,-1), v3s16(-1, 1,-1), + v3s16(-1, 1, 1), v3s16( 1, 1, 1), + // ( 0, 0, 1) + v3s16(-1,-1, 1), v3s16( 1,-1, 1), + v3s16( 1, 1, 1), v3s16(-1, 1, 1), + // invalid + v3s16(), v3s16(), v3s16(), v3s16(), + // ( 0, 0,-1) + v3s16( 1,-1,-1), v3s16(-1,-1,-1), + v3s16(-1, 1,-1), v3s16( 1, 1,-1), + // ( 0,-1, 0) + v3s16( 1,-1, 1), v3s16(-1,-1, 1), + v3s16(-1,-1,-1), v3s16( 1,-1,-1), + // (-1, 0, 0) + v3s16(-1,-1,-1), v3s16(-1,-1, 1), + v3s16(-1, 1, 1), v3s16(-1, 1,-1) +}; + +/* + vertex_dirs: v3s16[4] +*/ +static void getNodeVertexDirs(const v3s16 &dir, v3s16 *vertex_dirs) +{ + /* + If looked from outside the node towards the face, the corners are: + 0: bottom-right + 1: bottom-left + 2: top-left + 3: top-right + */ + + // Direction must be (1,0,0), (-1,0,0), (0,1,0), (0,-1,0), + // (0,0,1), (0,0,-1) + assert(dir.X * dir.X + dir.Y * dir.Y + dir.Z * dir.Z == 1); + + // Convert direction to single integer for table lookup + u8 idx = (dir.X + 2 * dir.Y + 3 * dir.Z) & 7; + idx = (idx - 1) * 4; + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#if __GNUC__ > 7 +#pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif +#endif + memcpy(vertex_dirs, &vertex_dirs_table[idx], 4 * sizeof(v3s16)); +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif +} + +static void getNodeTextureCoords(v3f base, const v3f &scale, const v3s16 &dir, float *u, float *v) +{ + if (dir.X > 0 || dir.Y != 0 || dir.Z < 0) + base -= scale; + if (dir == v3s16(0,0,1)) { + *u = -base.X; + *v = -base.Y; + } else if (dir == v3s16(0,0,-1)) { + *u = base.X + 1; + *v = -base.Y - 1; + } else if (dir == v3s16(1,0,0)) { + *u = base.Z + 1; + *v = -base.Y - 1; + } else if (dir == v3s16(-1,0,0)) { + *u = -base.Z; + *v = -base.Y; + } else if (dir == v3s16(0,1,0)) { + *u = base.X + 1; + *v = -base.Z - 1; + } else if (dir == v3s16(0,-1,0)) { + *u = base.X + 1; + *v = base.Z + 1; + } +} + +struct FastFace +{ + TileSpec tile; + video::S3DVertex vertices[4]; // Precalculated vertices + /*! + * The face is divided into two triangles. If this is true, + * vertices 0 and 2 are connected, othervise vertices 1 and 3 + * are connected. + */ + bool vertex_0_2_connected; +}; + +static void makeFastFace(const TileSpec &tile, u16 li0, u16 li1, u16 li2, u16 li3, + const v3f &tp, const v3f &p, const v3s16 &dir, const v3f &scale, std::vector<FastFace> &dest) +{ + // Position is at the center of the cube. + v3f pos = p * BS; + + float x0 = 0.0f; + float y0 = 0.0f; + float w = 1.0f; + float h = 1.0f; + + v3f vertex_pos[4]; + v3s16 vertex_dirs[4]; + getNodeVertexDirs(dir, vertex_dirs); + if (tile.world_aligned) + getNodeTextureCoords(tp, scale, dir, &x0, &y0); + + v3s16 t; + u16 t1; + switch (tile.rotation) { + case 0: + break; + case 1: //R90 + t = vertex_dirs[0]; + vertex_dirs[0] = vertex_dirs[3]; + vertex_dirs[3] = vertex_dirs[2]; + vertex_dirs[2] = vertex_dirs[1]; + vertex_dirs[1] = t; + t1 = li0; + li0 = li3; + li3 = li2; + li2 = li1; + li1 = t1; + break; + case 2: //R180 + t = vertex_dirs[0]; + vertex_dirs[0] = vertex_dirs[2]; + vertex_dirs[2] = t; + t = vertex_dirs[1]; + vertex_dirs[1] = vertex_dirs[3]; + vertex_dirs[3] = t; + t1 = li0; + li0 = li2; + li2 = t1; + t1 = li1; + li1 = li3; + li3 = t1; + break; + case 3: //R270 + t = vertex_dirs[0]; + vertex_dirs[0] = vertex_dirs[1]; + vertex_dirs[1] = vertex_dirs[2]; + vertex_dirs[2] = vertex_dirs[3]; + vertex_dirs[3] = t; + t1 = li0; + li0 = li1; + li1 = li2; + li2 = li3; + li3 = t1; + break; + case 4: //FXR90 + t = vertex_dirs[0]; + vertex_dirs[0] = vertex_dirs[3]; + vertex_dirs[3] = vertex_dirs[2]; + vertex_dirs[2] = vertex_dirs[1]; + vertex_dirs[1] = t; + t1 = li0; + li0 = li3; + li3 = li2; + li2 = li1; + li1 = t1; + y0 += h; + h *= -1; + break; + case 5: //FXR270 + t = vertex_dirs[0]; + vertex_dirs[0] = vertex_dirs[1]; + vertex_dirs[1] = vertex_dirs[2]; + vertex_dirs[2] = vertex_dirs[3]; + vertex_dirs[3] = t; + t1 = li0; + li0 = li1; + li1 = li2; + li2 = li3; + li3 = t1; + y0 += h; + h *= -1; + break; + case 6: //FYR90 + t = vertex_dirs[0]; + vertex_dirs[0] = vertex_dirs[3]; + vertex_dirs[3] = vertex_dirs[2]; + vertex_dirs[2] = vertex_dirs[1]; + vertex_dirs[1] = t; + t1 = li0; + li0 = li3; + li3 = li2; + li2 = li1; + li1 = t1; + x0 += w; + w *= -1; + break; + case 7: //FYR270 + t = vertex_dirs[0]; + vertex_dirs[0] = vertex_dirs[1]; + vertex_dirs[1] = vertex_dirs[2]; + vertex_dirs[2] = vertex_dirs[3]; + vertex_dirs[3] = t; + t1 = li0; + li0 = li1; + li1 = li2; + li2 = li3; + li3 = t1; + x0 += w; + w *= -1; + break; + case 8: //FX + y0 += h; + h *= -1; + break; + case 9: //FY + x0 += w; + w *= -1; + break; + default: + break; + } + + for (u16 i = 0; i < 4; i++) { + vertex_pos[i] = v3f( + BS / 2 * vertex_dirs[i].X, + BS / 2 * vertex_dirs[i].Y, + BS / 2 * vertex_dirs[i].Z + ); + } + + for (v3f &vpos : vertex_pos) { + vpos.X *= scale.X; + vpos.Y *= scale.Y; + vpos.Z *= scale.Z; + vpos += pos; + } + + f32 abs_scale = 1.0f; + if (scale.X < 0.999f || scale.X > 1.001f) abs_scale = scale.X; + else if (scale.Y < 0.999f || scale.Y > 1.001f) abs_scale = scale.Y; + else if (scale.Z < 0.999f || scale.Z > 1.001f) abs_scale = scale.Z; + + v3f normal(dir.X, dir.Y, dir.Z); + + u16 li[4] = { li0, li1, li2, li3 }; + u16 day[4]; + u16 night[4]; + + for (u8 i = 0; i < 4; i++) { + day[i] = li[i] >> 8; + night[i] = li[i] & 0xFF; + } + + bool vertex_0_2_connected = abs(day[0] - day[2]) + abs(night[0] - night[2]) + < abs(day[1] - day[3]) + abs(night[1] - night[3]); + + v2f32 f[4] = { + core::vector2d<f32>(x0 + w * abs_scale, y0 + h), + core::vector2d<f32>(x0, y0 + h), + core::vector2d<f32>(x0, y0), + core::vector2d<f32>(x0 + w * abs_scale, y0) }; + + // equivalent to dest.push_back(FastFace()) but faster + dest.emplace_back(); + FastFace& face = *dest.rbegin(); + + for (u8 i = 0; i < 4; i++) { + video::SColor c = encode_light(li[i], tile.emissive_light); + if (!tile.emissive_light) + applyFacesShading(c, normal); + + face.vertices[i] = video::S3DVertex(vertex_pos[i], normal, c, f[i]); + } + + /* + Revert triangles for nicer looking gradient if the + brightness of vertices 1 and 3 differ less than + the brightness of vertices 0 and 2. + */ + face.vertex_0_2_connected = vertex_0_2_connected; + face.tile = tile; +} + +/* + Nodes make a face if contents differ and solidness differs. + Return value: + 0: No face + 1: Face uses m1's content + 2: Face uses m2's content + equivalent: Whether the blocks share the same face (eg. water and glass) + + TODO: Add 3: Both faces drawn with backface culling, remove equivalent +*/ +static u8 face_contents(content_t m1, content_t m2, bool *equivalent, + const NodeDefManager *ndef) +{ + *equivalent = false; + + if (m1 == m2 || m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE) + return 0; + + const ContentFeatures &f1 = ndef->get(m1); + const ContentFeatures &f2 = ndef->get(m2); + + // Contents don't differ for different forms of same liquid + if (f1.sameLiquid(f2)) + return 0; + + u8 c1 = f1.solidness; + u8 c2 = f2.solidness; + + if (c1 == c2) + return 0; + + if (c1 == 0) + c1 = f1.visual_solidness; + else if (c2 == 0) + c2 = f2.visual_solidness; + + if (c1 == c2) { + *equivalent = true; + // If same solidness, liquid takes precense + if (f1.isLiquid()) + return 1; + if (f2.isLiquid()) + return 2; + } + + if (c1 > c2) + return 1; + + return 2; +} + +/* + Gets nth node tile (0 <= n <= 5). +*/ +void getNodeTileN(MapNode mn, const v3s16 &p, u8 tileindex, MeshMakeData *data, TileSpec &tile) +{ + const NodeDefManager *ndef = data->m_client->ndef(); + const ContentFeatures &f = ndef->get(mn); + tile = f.tiles[tileindex]; + bool has_crack = p == data->m_crack_pos_relative; + for (TileLayer &layer : tile.layers) { + if (layer.texture_id == 0) + continue; + if (!layer.has_color) + mn.getColor(f, &(layer.color)); + // Apply temporary crack + if (has_crack) + layer.material_flags |= MATERIAL_FLAG_CRACK; + } +} + +/* + Gets node tile given a face direction. +*/ +void getNodeTile(MapNode mn, const v3s16 &p, const v3s16 &dir, MeshMakeData *data, TileSpec &tile) +{ + const NodeDefManager *ndef = data->m_client->ndef(); + + // Direction must be (1,0,0), (-1,0,0), (0,1,0), (0,-1,0), + // (0,0,1), (0,0,-1) or (0,0,0) + assert(dir.X * dir.X + dir.Y * dir.Y + dir.Z * dir.Z <= 1); + + // Convert direction to single integer for table lookup + // 0 = (0,0,0) + // 1 = (1,0,0) + // 2 = (0,1,0) + // 3 = (0,0,1) + // 4 = invalid, treat as (0,0,0) + // 5 = (0,0,-1) + // 6 = (0,-1,0) + // 7 = (-1,0,0) + u8 dir_i = ((dir.X + 2 * dir.Y + 3 * dir.Z) & 7) * 2; + + // Get rotation for things like chests + u8 facedir = mn.getFaceDir(ndef, true); + + static const u16 dir_to_tile[24 * 16] = + { + // 0 +X +Y +Z -Z -Y -X -> value=tile,rotation + 0,0, 2,0 , 0,0 , 4,0 , 0,0, 5,0 , 1,0 , 3,0 , // rotate around y+ 0 - 3 + 0,0, 4,0 , 0,3 , 3,0 , 0,0, 2,0 , 1,1 , 5,0 , + 0,0, 3,0 , 0,2 , 5,0 , 0,0, 4,0 , 1,2 , 2,0 , + 0,0, 5,0 , 0,1 , 2,0 , 0,0, 3,0 , 1,3 , 4,0 , + + 0,0, 2,3 , 5,0 , 0,2 , 0,0, 1,0 , 4,2 , 3,1 , // rotate around z+ 4 - 7 + 0,0, 4,3 , 2,0 , 0,1 , 0,0, 1,1 , 3,2 , 5,1 , + 0,0, 3,3 , 4,0 , 0,0 , 0,0, 1,2 , 5,2 , 2,1 , + 0,0, 5,3 , 3,0 , 0,3 , 0,0, 1,3 , 2,2 , 4,1 , + + 0,0, 2,1 , 4,2 , 1,2 , 0,0, 0,0 , 5,0 , 3,3 , // rotate around z- 8 - 11 + 0,0, 4,1 , 3,2 , 1,3 , 0,0, 0,3 , 2,0 , 5,3 , + 0,0, 3,1 , 5,2 , 1,0 , 0,0, 0,2 , 4,0 , 2,3 , + 0,0, 5,1 , 2,2 , 1,1 , 0,0, 0,1 , 3,0 , 4,3 , + + 0,0, 0,3 , 3,3 , 4,1 , 0,0, 5,3 , 2,3 , 1,3 , // rotate around x+ 12 - 15 + 0,0, 0,2 , 5,3 , 3,1 , 0,0, 2,3 , 4,3 , 1,0 , + 0,0, 0,1 , 2,3 , 5,1 , 0,0, 4,3 , 3,3 , 1,1 , + 0,0, 0,0 , 4,3 , 2,1 , 0,0, 3,3 , 5,3 , 1,2 , + + 0,0, 1,1 , 2,1 , 4,3 , 0,0, 5,1 , 3,1 , 0,1 , // rotate around x- 16 - 19 + 0,0, 1,2 , 4,1 , 3,3 , 0,0, 2,1 , 5,1 , 0,0 , + 0,0, 1,3 , 3,1 , 5,3 , 0,0, 4,1 , 2,1 , 0,3 , + 0,0, 1,0 , 5,1 , 2,3 , 0,0, 3,1 , 4,1 , 0,2 , + + 0,0, 3,2 , 1,2 , 4,2 , 0,0, 5,2 , 0,2 , 2,2 , // rotate around y- 20 - 23 + 0,0, 5,2 , 1,3 , 3,2 , 0,0, 2,2 , 0,1 , 4,2 , + 0,0, 2,2 , 1,0 , 5,2 , 0,0, 4,2 , 0,0 , 3,2 , + 0,0, 4,2 , 1,1 , 2,2 , 0,0, 3,2 , 0,3 , 5,2 + + }; + u16 tile_index = facedir * 16 + dir_i; + getNodeTileN(mn, p, dir_to_tile[tile_index], data, tile); + tile.rotation = tile.world_aligned ? 0 : dir_to_tile[tile_index + 1]; +} + +static void getTileInfo( + // Input: + MeshMakeData *data, + const v3s16 &p, + const v3s16 &face_dir, + // Output: + bool &makes_face, + v3s16 &p_corrected, + v3s16 &face_dir_corrected, + u16 *lights, + u8 &waving, + TileSpec &tile + ) +{ + VoxelManipulator &vmanip = data->m_vmanip; + const NodeDefManager *ndef = data->m_client->ndef(); + v3s16 blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE; + + const MapNode &n0 = vmanip.getNodeRefUnsafe(blockpos_nodes + p); + + // Don't even try to get n1 if n0 is already CONTENT_IGNORE + if (n0.getContent() == CONTENT_IGNORE) { + makes_face = false; + return; + } + + const MapNode &n1 = vmanip.getNodeRefUnsafeCheckFlags(blockpos_nodes + p + face_dir); + + if (n1.getContent() == CONTENT_IGNORE) { + makes_face = false; + return; + } + + // This is hackish + bool equivalent = false; + u8 mf = face_contents(n0.getContent(), n1.getContent(), + &equivalent, ndef); + + if (mf == 0) { + makes_face = false; + return; + } + + makes_face = true; + + MapNode n = n0; + + if (mf == 1) { + p_corrected = p; + face_dir_corrected = face_dir; + } else { + n = n1; + p_corrected = p + face_dir; + face_dir_corrected = -face_dir; + } + + getNodeTile(n, p_corrected, face_dir_corrected, data, tile); + const ContentFeatures &f = ndef->get(n); + waving = f.waving; + tile.emissive_light = f.light_source; + + // eg. water and glass + if (equivalent) { + for (TileLayer &layer : tile.layers) + layer.material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; + } + + if (!data->m_smooth_lighting) { + lights[0] = lights[1] = lights[2] = lights[3] = + getFaceLight(n0, n1, face_dir, ndef); + } else { + v3s16 vertex_dirs[4]; + getNodeVertexDirs(face_dir_corrected, vertex_dirs); + + v3s16 light_p = blockpos_nodes + p_corrected; + for (u16 i = 0; i < 4; i++) + lights[i] = getSmoothLightSolid(light_p, face_dir_corrected, vertex_dirs[i], data); + } +} + +/* + startpos: + translate_dir: unit vector with only one of x, y or z + face_dir: unit vector with only one of x, y or z +*/ +static void updateFastFaceRow( + MeshMakeData *data, + const v3s16 &&startpos, + v3s16 translate_dir, + const v3f &&translate_dir_f, + const v3s16 &&face_dir, + std::vector<FastFace> &dest) +{ + static thread_local const bool waving_liquids = + g_settings->getBool("enable_shaders") && + g_settings->getBool("enable_waving_water"); + + static thread_local const bool force_not_tiling = + g_settings->getBool("enable_dynamic_shadows"); + + v3s16 p = startpos; + + u16 continuous_tiles_count = 1; + + bool makes_face = false; + v3s16 p_corrected; + v3s16 face_dir_corrected; + u16 lights[4] = {0, 0, 0, 0}; + u8 waving = 0; + TileSpec tile; + + // Get info of first tile + getTileInfo(data, p, face_dir, + makes_face, p_corrected, face_dir_corrected, + lights, waving, tile); + + // Unroll this variable which has a significant build cost + TileSpec next_tile; + for (u16 j = 0; j < MAP_BLOCKSIZE; j++) { + // If tiling can be done, this is set to false in the next step + bool next_is_different = true; + + bool next_makes_face = false; + v3s16 next_p_corrected; + v3s16 next_face_dir_corrected; + u16 next_lights[4] = {0, 0, 0, 0}; + + // If at last position, there is nothing to compare to and + // the face must be drawn anyway + if (j != MAP_BLOCKSIZE - 1) { + p += translate_dir; + + getTileInfo(data, p, face_dir, + next_makes_face, next_p_corrected, + next_face_dir_corrected, next_lights, + waving, + next_tile); + + if (!force_not_tiling + && next_makes_face == makes_face + && next_p_corrected == p_corrected + translate_dir + && next_face_dir_corrected == face_dir_corrected + && memcmp(next_lights, lights, sizeof(lights)) == 0 + // Don't apply fast faces to waving water. + && (waving != 3 || !waving_liquids) + && next_tile.isTileable(tile)) { + next_is_different = false; + continuous_tiles_count++; + } + } + if (next_is_different) { + /* + Create a face if there should be one + */ + if (makes_face) { + // Floating point conversion of the position vector + v3f pf(p_corrected.X, p_corrected.Y, p_corrected.Z); + // Center point of face (kind of) + v3f sp = pf - ((f32)continuous_tiles_count * 0.5f - 0.5f) + * translate_dir_f; + v3f scale(1, 1, 1); + + if (translate_dir.X != 0) + scale.X = continuous_tiles_count; + if (translate_dir.Y != 0) + scale.Y = continuous_tiles_count; + if (translate_dir.Z != 0) + scale.Z = continuous_tiles_count; + + makeFastFace(tile, lights[0], lights[1], lights[2], lights[3], + pf, sp, face_dir_corrected, scale, dest); + g_profiler->avg("Meshgen: Tiles per face [#]", continuous_tiles_count); + } + + continuous_tiles_count = 1; + } + + makes_face = next_makes_face; + p_corrected = next_p_corrected; + face_dir_corrected = next_face_dir_corrected; + memcpy(lights, next_lights, sizeof(lights)); + if (next_is_different) + tile = std::move(next_tile); // faster than copy + } +} + +static void updateAllFastFaceRows(MeshMakeData *data, + std::vector<FastFace> &dest) +{ + /* + Go through every y,z and get top(y+) faces in rows of x+ + */ + for (s16 y = 0; y < MAP_BLOCKSIZE; y++) + for (s16 z = 0; z < MAP_BLOCKSIZE; z++) + updateFastFaceRow(data, + v3s16(0, y, z), + v3s16(1, 0, 0), //dir + v3f (1, 0, 0), + v3s16(0, 1, 0), //face dir + dest); + + /* + Go through every x,y and get right(x+) faces in rows of z+ + */ + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) + for (s16 y = 0; y < MAP_BLOCKSIZE; y++) + updateFastFaceRow(data, + v3s16(x, y, 0), + v3s16(0, 0, 1), //dir + v3f (0, 0, 1), + v3s16(1, 0, 0), //face dir + dest); + + /* + Go through every y,z and get back(z+) faces in rows of x+ + */ + for (s16 z = 0; z < MAP_BLOCKSIZE; z++) + for (s16 y = 0; y < MAP_BLOCKSIZE; y++) + updateFastFaceRow(data, + v3s16(0, y, z), + v3s16(1, 0, 0), //dir + v3f (1, 0, 0), + v3s16(0, 0, 1), //face dir + dest); +} + +static void applyTileColor(PreMeshBuffer &pmb) +{ + video::SColor tc = pmb.layer.color; + if (tc == video::SColor(0xFFFFFFFF)) + return; + for (video::S3DVertex &vertex : pmb.vertices) { + video::SColor *c = &vertex.Color; + c->set(c->getAlpha(), + c->getRed() * tc.getRed() / 255, + c->getGreen() * tc.getGreen() / 255, + c->getBlue() * tc.getBlue() / 255); + } +} + +/* + MapBlockBspTree +*/ + +void MapBlockBspTree::buildTree(const std::vector<MeshTriangle> *triangles) +{ + this->triangles = triangles; + + nodes.clear(); + + // assert that triangle index can fit into s32 + assert(triangles->size() <= 0x7FFFFFFFL); + std::vector<s32> indexes; + indexes.reserve(triangles->size()); + for (u32 i = 0; i < triangles->size(); i++) + indexes.push_back(i); + + if (!indexes.empty()) { + // Start in the center of the block with increment of one quarter in each direction + root = buildTree(v3f(1, 0, 0), v3f((MAP_BLOCKSIZE + 1) * 0.5f * BS), MAP_BLOCKSIZE * 0.25f * BS, indexes, 0); + } else { + root = -1; + } +} + +/** + * @brief Find a candidate plane to split a set of triangles in two + * + * The candidate plane is represented by one of the triangles from the set. + * + * @param list Vector of indexes of the triangles in the set + * @param triangles Vector of all triangles in the BSP tree + * @return Address of the triangle that represents the proposed split plane + */ +static const MeshTriangle *findSplitCandidate(const std::vector<s32> &list, const std::vector<MeshTriangle> &triangles) +{ + // find the center of the cluster. + v3f center(0, 0, 0); + size_t n = list.size(); + for (s32 i : list) { + center += triangles[i].centroid / n; + } + + // find the triangle with the largest area and closest to the center + const MeshTriangle *candidate_triangle = &triangles[list[0]]; + const MeshTriangle *ith_triangle; + for (s32 i : list) { + ith_triangle = &triangles[i]; + if (ith_triangle->areaSQ > candidate_triangle->areaSQ || + (ith_triangle->areaSQ == candidate_triangle->areaSQ && + ith_triangle->centroid.getDistanceFromSQ(center) < candidate_triangle->centroid.getDistanceFromSQ(center))) { + candidate_triangle = ith_triangle; + } + } + return candidate_triangle; +} + +s32 MapBlockBspTree::buildTree(v3f normal, v3f origin, float delta, const std::vector<s32> &list, u32 depth) +{ + // if the list is empty, don't bother + if (list.empty()) + return -1; + + // if there is only one triangle, or the delta is insanely small, this is a leaf node + if (list.size() == 1 || delta < 0.01) { + nodes.emplace_back(normal, origin, list, -1, -1); + return nodes.size() - 1; + } + + std::vector<s32> front_list; + std::vector<s32> back_list; + std::vector<s32> node_list; + + // split the list + for (s32 i : list) { + const MeshTriangle &triangle = (*triangles)[i]; + float factor = normal.dotProduct(triangle.centroid - origin); + if (factor == 0) + node_list.push_back(i); + else if (factor > 0) + front_list.push_back(i); + else + back_list.push_back(i); + } + + // define the new split-plane + v3f candidate_normal(normal.Z, normal.X, normal.Y); + float candidate_delta = delta; + if (depth % 3 == 2) + candidate_delta /= 2; + + s32 front_index = -1; + s32 back_index = -1; + + if (!front_list.empty()) { + v3f next_normal = candidate_normal; + v3f next_origin = origin + delta * normal; + float next_delta = candidate_delta; + if (next_delta < 5) { + const MeshTriangle *candidate = findSplitCandidate(front_list, *triangles); + next_normal = candidate->getNormal(); + next_origin = candidate->centroid; + } + front_index = buildTree(next_normal, next_origin, next_delta, front_list, depth + 1); + + // if there are no other triangles, don't create a new node + if (back_list.empty() && node_list.empty()) + return front_index; + } + + if (!back_list.empty()) { + v3f next_normal = candidate_normal; + v3f next_origin = origin - delta * normal; + float next_delta = candidate_delta; + if (next_delta < 5) { + const MeshTriangle *candidate = findSplitCandidate(back_list, *triangles); + next_normal = candidate->getNormal(); + next_origin = candidate->centroid; + } + + back_index = buildTree(next_normal, next_origin, next_delta, back_list, depth + 1); + + // if there are no other triangles, don't create a new node + if (front_list.empty() && node_list.empty()) + return back_index; + } + + nodes.emplace_back(normal, origin, node_list, front_index, back_index); + + return nodes.size() - 1; +} + +void MapBlockBspTree::traverse(s32 node, v3f viewpoint, std::vector<s32> &output) const +{ + if (node < 0) return; // recursion break; + + const TreeNode &n = nodes[node]; + float factor = n.normal.dotProduct(viewpoint - n.origin); + + if (factor > 0) + traverse(n.back_ref, viewpoint, output); + else + traverse(n.front_ref, viewpoint, output); + + if (factor != 0) + for (s32 i : n.triangle_refs) + output.push_back(i); + + if (factor > 0) + traverse(n.front_ref, viewpoint, output); + else + traverse(n.back_ref, viewpoint, output); +} + + + +/* + PartialMeshBuffer +*/ + +void PartialMeshBuffer::beforeDraw() const +{ + // Patch the indexes in the mesh buffer before draw + m_buffer->Indices = std::move(m_vertex_indexes); + m_buffer->setDirty(scene::EBT_INDEX); +} + +void PartialMeshBuffer::afterDraw() const +{ + // Take the data back + m_vertex_indexes = m_buffer->Indices.steal(); +} + +/* + MapBlockMesh +*/ + +MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): + m_minimap_mapblock(NULL), + m_tsrc(data->m_client->getTextureSource()), + m_shdrsrc(data->m_client->getShaderSource()), + m_animation_force_timer(0), // force initial animation + m_last_crack(-1), + m_last_daynight_ratio((u32) -1) +{ + for (auto &m : m_mesh) + m = new scene::SMesh(); + m_enable_shaders = data->m_use_shaders; + m_enable_vbo = g_settings->getBool("enable_vbo"); + + if (data->m_client->getMinimap()) { + m_minimap_mapblock = new MinimapMapblock; + m_minimap_mapblock->getMinimapNodes( + &data->m_vmanip, data->m_blockpos * MAP_BLOCKSIZE); + } + + // 4-21ms for MAP_BLOCKSIZE=16 (NOTE: probably outdated) + // 24-155ms for MAP_BLOCKSIZE=32 (NOTE: probably outdated) + //TimeTaker timer1("MapBlockMesh()"); + + std::vector<FastFace> fastfaces_new; + fastfaces_new.reserve(512); + + /* + We are including the faces of the trailing edges of the block. + This means that when something changes, the caller must + also update the meshes of the blocks at the leading edges. + + NOTE: This is the slowest part of this method. + */ + { + // 4-23ms for MAP_BLOCKSIZE=16 (NOTE: probably outdated) + //TimeTaker timer2("updateAllFastFaceRows()"); + updateAllFastFaceRows(data, fastfaces_new); + } + // End of slow part + + /* + Convert FastFaces to MeshCollector + */ + + MeshCollector collector; + + { + // avg 0ms (100ms spikes when loading textures the first time) + // (NOTE: probably outdated) + //TimeTaker timer2("MeshCollector building"); + + for (const FastFace &f : fastfaces_new) { + static const u16 indices[] = {0, 1, 2, 2, 3, 0}; + static const u16 indices_alternate[] = {0, 1, 3, 2, 3, 1}; + const u16 *indices_p = + f.vertex_0_2_connected ? indices : indices_alternate; + collector.append(f.tile, f.vertices, 4, indices_p, 6); + } + } + + /* + Add special graphics: + - torches + - flowing water + - fences + - whatever + */ + + { + MapblockMeshGenerator(data, &collector, + data->m_client->getSceneManager()->getMeshManipulator()).generate(); + } + + /* + Convert MeshCollector to SMesh + */ + + const bool desync_animations = g_settings->getBool( + "desynchronize_mapblock_texture_animation"); + + for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) { + for(u32 i = 0; i < collector.prebuffers[layer].size(); i++) + { + PreMeshBuffer &p = collector.prebuffers[layer][i]; + + applyTileColor(p); + + // Generate animation data + // - Cracks + if (p.layer.material_flags & MATERIAL_FLAG_CRACK) { + // Find the texture name plus ^[crack:N: + std::ostringstream os(std::ios::binary); + os << m_tsrc->getTextureName(p.layer.texture_id) << "^[crack"; + if (p.layer.material_flags & MATERIAL_FLAG_CRACK_OVERLAY) + os << "o"; // use ^[cracko + u8 tiles = p.layer.scale; + if (tiles > 1) + os << ":" << (u32)tiles; + os << ":" << (u32)p.layer.animation_frame_count << ":"; + m_crack_materials.insert(std::make_pair( + std::pair<u8, u32>(layer, i), os.str())); + // Replace tile texture with the cracked one + p.layer.texture = m_tsrc->getTextureForMesh( + os.str() + "0", + &p.layer.texture_id); + } + // - Texture animation + if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) { + // Add to MapBlockMesh in order to animate these tiles + auto &info = m_animation_info[{layer, i}]; + info.tile = p.layer; + info.frame = 0; + if (desync_animations) { + // Get starting position from noise + info.frame_offset = + 100000 * (2.0 + noise3d( + data->m_blockpos.X, data->m_blockpos.Y, + data->m_blockpos.Z, 0)); + } else { + // Play all synchronized + info.frame_offset = 0; + } + // Replace tile texture with the first animation frame + p.layer.texture = (*p.layer.frames)[0].texture; + } + + if (!m_enable_shaders) { + // Extract colors for day-night animation + // Dummy sunlight to handle non-sunlit areas + video::SColorf sunlight; + get_sunlight_color(&sunlight, 0); + + std::map<u32, video::SColor> colors; + const u32 vertex_count = p.vertices.size(); + for (u32 j = 0; j < vertex_count; j++) { + video::SColor *vc = &p.vertices[j].Color; + video::SColor copy = *vc; + if (vc->getAlpha() == 0) // No sunlight - no need to animate + final_color_blend(vc, copy, sunlight); // Finalize color + else // Record color to animate + colors[j] = copy; + + // The sunlight ratio has been stored, + // delete alpha (for the final rendering). + vc->setAlpha(255); + } + if (!colors.empty()) + m_daynight_diffs[{layer, i}] = std::move(colors); + } + + // Create material + video::SMaterial material; + material.setFlag(video::EMF_LIGHTING, false); + material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setFlag(video::EMF_FOG_ENABLE, true); + material.setTexture(0, p.layer.texture); + + if (m_enable_shaders) { + material.MaterialType = m_shdrsrc->getShaderInfo( + p.layer.shader_id).material; + p.layer.applyMaterialOptionsWithShaders(material); + if (p.layer.normal_texture) + material.setTexture(1, p.layer.normal_texture); + material.setTexture(2, p.layer.flags_texture); + } else { + p.layer.applyMaterialOptions(material); + } + + scene::SMesh *mesh = (scene::SMesh *)m_mesh[layer]; + + scene::SMeshBuffer *buf = new scene::SMeshBuffer(); + buf->Material = material; + if (p.layer.isTransparent()) { + buf->append(&p.vertices[0], p.vertices.size(), nullptr, 0); + + MeshTriangle t; + t.buffer = buf; + m_transparent_triangles.reserve(p.indices.size() / 3); + for (u32 i = 0; i < p.indices.size(); i += 3) { + t.p1 = p.indices[i]; + t.p2 = p.indices[i + 1]; + t.p3 = p.indices[i + 2]; + t.updateAttributes(); + m_transparent_triangles.push_back(t); + } + } else { + buf->append(&p.vertices[0], p.vertices.size(), + &p.indices[0], p.indices.size()); + } + mesh->addMeshBuffer(buf); + buf->drop(); + } + + if (m_mesh[layer]) { + // Use VBO for mesh (this just would set this for ever buffer) + if (m_enable_vbo) + m_mesh[layer]->setHardwareMappingHint(scene::EHM_STATIC); + } + } + + //std::cout<<"added "<<fastfaces.getSize()<<" faces."<<std::endl; + m_bsp_tree.buildTree(&m_transparent_triangles); + + // Check if animation is required for this mesh + m_has_animation = + !m_crack_materials.empty() || + !m_daynight_diffs.empty() || + !m_animation_info.empty(); +} + +MapBlockMesh::~MapBlockMesh() +{ + for (scene::IMesh *m : m_mesh) { +#if IRRLICHT_VERSION_MT_REVISION < 5 + if (m_enable_vbo) { + for (u32 i = 0; i < m->getMeshBufferCount(); i++) { + scene::IMeshBuffer *buf = m->getMeshBuffer(i); + RenderingEngine::get_video_driver()->removeHardwareBuffer(buf); + } + } +#endif + m->drop(); + } + delete m_minimap_mapblock; +} + +bool MapBlockMesh::animate(bool faraway, float time, int crack, + u32 daynight_ratio) +{ + if (!m_has_animation) { + m_animation_force_timer = 100000; + return false; + } + + m_animation_force_timer = myrand_range(5, 100); + + // Cracks + if (crack != m_last_crack) { + for (auto &crack_material : m_crack_materials) { + scene::IMeshBuffer *buf = m_mesh[crack_material.first.first]-> + getMeshBuffer(crack_material.first.second); + + // Create new texture name from original + std::string s = crack_material.second + itos(crack); + u32 new_texture_id = 0; + video::ITexture *new_texture = + m_tsrc->getTextureForMesh(s, &new_texture_id); + buf->getMaterial().setTexture(0, new_texture); + + // If the current material is also animated, update animation info + auto anim_it = m_animation_info.find(crack_material.first); + if (anim_it != m_animation_info.end()) { + TileLayer &tile = anim_it->second.tile; + tile.texture = new_texture; + tile.texture_id = new_texture_id; + // force animation update + anim_it->second.frame = -1; + } + } + + m_last_crack = crack; + } + + // Texture animation + for (auto &it : m_animation_info) { + const TileLayer &tile = it.second.tile; + // Figure out current frame + int frameno = (int)(time * 1000 / tile.animation_frame_length_ms + + it.second.frame_offset) % tile.animation_frame_count; + // If frame doesn't change, skip + if (frameno == it.second.frame) + continue; + + it.second.frame = frameno; + + scene::IMeshBuffer *buf = m_mesh[it.first.first]->getMeshBuffer(it.first.second); + + const FrameSpec &frame = (*tile.frames)[frameno]; + buf->getMaterial().setTexture(0, frame.texture); + if (m_enable_shaders) { + if (frame.normal_texture) + buf->getMaterial().setTexture(1, frame.normal_texture); + buf->getMaterial().setTexture(2, frame.flags_texture); + } + } + + // Day-night transition + if (!m_enable_shaders && (daynight_ratio != m_last_daynight_ratio)) { + // Force reload mesh to VBO + if (m_enable_vbo) + for (scene::IMesh *m : m_mesh) + m->setDirty(); + video::SColorf day_color; + get_sunlight_color(&day_color, daynight_ratio); + + for (auto &daynight_diff : m_daynight_diffs) { + scene::IMeshBuffer *buf = m_mesh[daynight_diff.first.first]-> + getMeshBuffer(daynight_diff.first.second); + video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices(); + for (const auto &j : daynight_diff.second) + final_color_blend(&(vertices[j.first].Color), j.second, + day_color); + } + m_last_daynight_ratio = daynight_ratio; + } + + return true; +} + +void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos) +{ + // nothing to do if the entire block is opaque + if (m_transparent_triangles.empty()) + return; + + v3f block_posf = intToFloat(block_pos * MAP_BLOCKSIZE, BS); + v3f rel_camera_pos = camera_pos - block_posf; + + std::vector<s32> triangle_refs; + m_bsp_tree.traverse(rel_camera_pos, triangle_refs); + + // arrange index sequences into partial buffers + m_transparent_buffers.clear(); + + scene::SMeshBuffer *current_buffer = nullptr; + std::vector<u16> current_strain; + for (auto i : triangle_refs) { + const auto &t = m_transparent_triangles[i]; + if (current_buffer != t.buffer) { + if (current_buffer) { + m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain)); + current_strain.clear(); + } + current_buffer = t.buffer; + } + current_strain.push_back(t.p1); + current_strain.push_back(t.p2); + current_strain.push_back(t.p3); + } + + if (!current_strain.empty()) + m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain)); +} + +void MapBlockMesh::consolidateTransparentBuffers() +{ + m_transparent_buffers.clear(); + + scene::SMeshBuffer *current_buffer = nullptr; + std::vector<u16> current_strain; + + // use the fact that m_transparent_triangles is already arranged by buffer + for (const auto &t : m_transparent_triangles) { + if (current_buffer != t.buffer) { + if (current_buffer != nullptr) { + this->m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain)); + current_strain.clear(); + } + current_buffer = t.buffer; + } + current_strain.push_back(t.p1); + current_strain.push_back(t.p2); + current_strain.push_back(t.p3); + } + + if (!current_strain.empty()) { + this->m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain)); + } +} + +video::SColor encode_light(u16 light, u8 emissive_light) +{ + // Get components + u32 day = (light & 0xff); + u32 night = (light >> 8); + // Add emissive light + night += emissive_light * 2.5f; + if (night > 255) + night = 255; + // Since we don't know if the day light is sunlight or + // artificial light, assume it is artificial when the night + // light bank is also lit. + if (day < night) + day = 0; + else + day = day - night; + u32 sum = day + night; + // Ratio of sunlight: + u32 r; + if (sum > 0) + r = day * 255 / sum; + else + r = 0; + // Average light: + float b = (day + night) / 2; + return video::SColor(r, b, b, b); +} diff --git a/src/client/mapblock_mesh.h b/src/client/mapblock_mesh.h new file mode 100644 index 0000000..169b3a8 --- /dev/null +++ b/src/client/mapblock_mesh.h @@ -0,0 +1,332 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "client/tile.h" +#include "voxel.h" +#include <array> +#include <map> + +class Client; +class IShaderSource; + +/* + Mesh making stuff +*/ + + +class MapBlock; +struct MinimapMapblock; + +struct MeshMakeData +{ + VoxelManipulator m_vmanip; + v3s16 m_blockpos = v3s16(-1337,-1337,-1337); + v3s16 m_crack_pos_relative = v3s16(-1337,-1337,-1337); + bool m_smooth_lighting = false; + + Client *m_client; + bool m_use_shaders; + + MeshMakeData(Client *client, bool use_shaders); + + /* + Copy block data manually (to allow optimizations by the caller) + */ + void fillBlockDataBegin(const v3s16 &blockpos); + void fillBlockData(const v3s16 &block_offset, MapNode *data); + + /* + Copy central data directly from block, and other data from + parent of block. + */ + void fill(MapBlock *block); + + /* + Set the (node) position of a crack + */ + void setCrack(int crack_level, v3s16 crack_pos); + + /* + Enable or disable smooth lighting + */ + void setSmoothLighting(bool smooth_lighting); +}; + +// represents a triangle as indexes into the vertex buffer in SMeshBuffer +class MeshTriangle +{ +public: + scene::SMeshBuffer *buffer; + u16 p1, p2, p3; + v3f centroid; + float areaSQ; + + void updateAttributes() + { + v3f v1 = buffer->getPosition(p1); + v3f v2 = buffer->getPosition(p2); + v3f v3 = buffer->getPosition(p3); + + centroid = (v1 + v2 + v3) / 3; + areaSQ = (v2-v1).crossProduct(v3-v1).getLengthSQ() / 4; + } + + v3f getNormal() const { + v3f v1 = buffer->getPosition(p1); + v3f v2 = buffer->getPosition(p2); + v3f v3 = buffer->getPosition(p3); + + return (v2-v1).crossProduct(v3-v1); + } +}; + +/** + * Implements a binary space partitioning tree + * See also: https://en.wikipedia.org/wiki/Binary_space_partitioning + */ +class MapBlockBspTree +{ +public: + MapBlockBspTree() {} + + void buildTree(const std::vector<MeshTriangle> *triangles); + + void traverse(v3f viewpoint, std::vector<s32> &output) const + { + traverse(root, viewpoint, output); + } + +private: + // Tree node definition; + struct TreeNode + { + v3f normal; + v3f origin; + std::vector<s32> triangle_refs; + s32 front_ref; + s32 back_ref; + + TreeNode() = default; + TreeNode(v3f normal, v3f origin, const std::vector<s32> &triangle_refs, s32 front_ref, s32 back_ref) : + normal(normal), origin(origin), triangle_refs(triangle_refs), front_ref(front_ref), back_ref(back_ref) + {} + }; + + + s32 buildTree(v3f normal, v3f origin, float delta, const std::vector<s32> &list, u32 depth); + void traverse(s32 node, v3f viewpoint, std::vector<s32> &output) const; + + const std::vector<MeshTriangle> *triangles = nullptr; // this reference is managed externally + std::vector<TreeNode> nodes; // list of nodes + s32 root = -1; // index of the root node +}; + +/* + * PartialMeshBuffer + * + * Attach alternate `Indices` to an existing mesh buffer, to make it possible to use different + * indices with the same vertex buffer. + * + * Irrlicht does not currently support this: `CMeshBuffer` ties together a single vertex buffer + * and a single index buffer. There's no way to share these between mesh buffers. + * + */ +class PartialMeshBuffer +{ +public: + PartialMeshBuffer(scene::SMeshBuffer *buffer, std::vector<u16> &&vertex_indexes) : + m_buffer(buffer), m_vertex_indexes(std::move(vertex_indexes)) + {} + + scene::IMeshBuffer *getBuffer() const { return m_buffer; } + const std::vector<u16> &getVertexIndexes() const { return m_vertex_indexes; } + + void beforeDraw() const; + void afterDraw() const; +private: + scene::SMeshBuffer *m_buffer; + mutable std::vector<u16> m_vertex_indexes; +}; + +/* + Holds a mesh for a mapblock. + + Besides the SMesh*, this contains information used for animating + the vertex positions, colors and texture coordinates of the mesh. + For example: + - cracks [implemented] + - day/night transitions [implemented] + - animated flowing liquids [not implemented] + - animating vertex positions for e.g. axles [not implemented] +*/ +class MapBlockMesh +{ +public: + // Builds the mesh given + MapBlockMesh(MeshMakeData *data, v3s16 camera_offset); + ~MapBlockMesh(); + + // Main animation function, parameters: + // faraway: whether the block is far away from the camera (~50 nodes) + // time: the global animation time, 0 .. 60 (repeats every minute) + // daynight_ratio: 0 .. 1000 + // crack: -1 .. CRACK_ANIMATION_LENGTH-1 (-1 for off) + // Returns true if anything has been changed. + bool animate(bool faraway, float time, int crack, u32 daynight_ratio); + + scene::IMesh *getMesh() + { + return m_mesh[0]; + } + + scene::IMesh *getMesh(u8 layer) + { + return m_mesh[layer]; + } + + MinimapMapblock *moveMinimapMapblock() + { + MinimapMapblock *p = m_minimap_mapblock; + m_minimap_mapblock = NULL; + return p; + } + + bool isAnimationForced() const + { + return m_animation_force_timer == 0; + } + + void decreaseAnimationForceTimer() + { + if(m_animation_force_timer > 0) + m_animation_force_timer--; + } + + /// update transparent buffers to render towards the camera + void updateTransparentBuffers(v3f camera_pos, v3s16 block_pos); + void consolidateTransparentBuffers(); + + /// get the list of transparent buffers + const std::vector<PartialMeshBuffer> &getTransparentBuffers() const + { + return this->m_transparent_buffers; + } + +private: + struct AnimationInfo { + int frame; // last animation frame + int frame_offset; + TileLayer tile; + }; + + scene::IMesh *m_mesh[MAX_TILE_LAYERS]; + MinimapMapblock *m_minimap_mapblock; + ITextureSource *m_tsrc; + IShaderSource *m_shdrsrc; + + bool m_enable_shaders; + bool m_enable_vbo; + + // Must animate() be called before rendering? + bool m_has_animation; + int m_animation_force_timer; + + // Animation info: cracks + // Last crack value passed to animate() + int m_last_crack; + // Maps mesh and mesh buffer (i.e. material) indices to base texture names + std::map<std::pair<u8, u32>, std::string> m_crack_materials; + + // Animation info: texture animation + // Maps mesh and mesh buffer indices to TileSpecs + // Keys are pairs of (mesh index, buffer index in the mesh) + std::map<std::pair<u8, u32>, AnimationInfo> m_animation_info; + + // Animation info: day/night transitions + // Last daynight_ratio value passed to animate() + u32 m_last_daynight_ratio; + // For each mesh and mesh buffer, stores pre-baked colors + // of sunlit vertices + // Keys are pairs of (mesh index, buffer index in the mesh) + std::map<std::pair<u8, u32>, std::map<u32, video::SColor > > m_daynight_diffs; + + // list of all semitransparent triangles in the mapblock + std::vector<MeshTriangle> m_transparent_triangles; + // Binary Space Partitioning tree for the block + MapBlockBspTree m_bsp_tree; + // Ordered list of references to parts of transparent buffers to draw + std::vector<PartialMeshBuffer> m_transparent_buffers; +}; + +/*! + * Encodes light of a node. + * The result is not the final color, but a + * half-baked vertex color. + * You have to multiply the resulting color + * with the node's color. + * + * \param light the first 8 bits are day light, + * the last 8 bits are night light + * \param emissive_light amount of light the surface emits, + * from 0 to LIGHT_SUN. + */ +video::SColor encode_light(u16 light, u8 emissive_light); + +// Compute light at node +u16 getInteriorLight(MapNode n, s32 increment, const NodeDefManager *ndef); +u16 getFaceLight(MapNode n, MapNode n2, const v3s16 &face_dir, + const NodeDefManager *ndef); +u16 getSmoothLightSolid(const v3s16 &p, const v3s16 &face_dir, const v3s16 &corner, MeshMakeData *data); +u16 getSmoothLightTransparent(const v3s16 &p, const v3s16 &corner, MeshMakeData *data); + +/*! + * Returns the sunlight's color from the current + * day-night ratio. + */ +void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio); + +/*! + * Gives the final SColor shown on screen. + * + * \param result output color + * \param light first 8 bits are day light, second 8 bits are + * night light + */ +void final_color_blend(video::SColor *result, + u16 light, u32 daynight_ratio); + +/*! + * Gives the final SColor shown on screen. + * + * \param result output color + * \param data the half-baked vertex color + * \param dayLight color of the sunlight + */ +void final_color_blend(video::SColor *result, + const video::SColor &data, const video::SColorf &dayLight); + +// Retrieves the TileSpec of a face of a node +// Adds MATERIAL_FLAG_CRACK if the node is cracked +// TileSpec should be passed as reference due to the underlying TileFrame and its vector +// TileFrame vector copy cost very much to client +void getNodeTileN(MapNode mn, const v3s16 &p, u8 tileindex, MeshMakeData *data, TileSpec &tile); +void getNodeTile(MapNode mn, const v3s16 &p, const v3s16 &dir, MeshMakeData *data, TileSpec &tile); diff --git a/src/client/mesh.cpp b/src/client/mesh.cpp new file mode 100644 index 0000000..4bf07ef --- /dev/null +++ b/src/client/mesh.cpp @@ -0,0 +1,499 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mesh.h" +#include "debug.h" +#include "log.h" +#include <cmath> +#include <iostream> +#include <IAnimatedMesh.h> +#include <SAnimatedMesh.h> +#include <IAnimatedMeshSceneNode.h> + +inline static void applyShadeFactor(video::SColor& color, float factor) +{ + color.setRed(core::clamp(core::round32(color.getRed()*factor), 0, 255)); + color.setGreen(core::clamp(core::round32(color.getGreen()*factor), 0, 255)); + color.setBlue(core::clamp(core::round32(color.getBlue()*factor), 0, 255)); +} + +void applyFacesShading(video::SColor &color, const v3f &normal) +{ + /* + Some drawtypes have normals set to (0, 0, 0), this must result in + maximum brightness: shade factor 1.0. + Shade factors for aligned cube faces are: + +Y 1.000000 sqrt(1.0) + -Y 0.447213 sqrt(0.2) + +-X 0.670820 sqrt(0.45) + +-Z 0.836660 sqrt(0.7) + */ + float x2 = normal.X * normal.X; + float y2 = normal.Y * normal.Y; + float z2 = normal.Z * normal.Z; + if (normal.Y < 0) + applyShadeFactor(color, 0.670820f * x2 + 0.447213f * y2 + 0.836660f * z2); + else if ((x2 > 1e-3) || (z2 > 1e-3)) + applyShadeFactor(color, 0.670820f * x2 + 1.000000f * y2 + 0.836660f * z2); +} + +scene::IAnimatedMesh* createCubeMesh(v3f scale) +{ + video::SColor c(255,255,255,255); + video::S3DVertex vertices[24] = + { + // Up + video::S3DVertex(-0.5,+0.5,-0.5, 0,1,0, c, 0,1), + video::S3DVertex(-0.5,+0.5,+0.5, 0,1,0, c, 0,0), + video::S3DVertex(+0.5,+0.5,+0.5, 0,1,0, c, 1,0), + video::S3DVertex(+0.5,+0.5,-0.5, 0,1,0, c, 1,1), + // Down + video::S3DVertex(-0.5,-0.5,-0.5, 0,-1,0, c, 0,0), + video::S3DVertex(+0.5,-0.5,-0.5, 0,-1,0, c, 1,0), + video::S3DVertex(+0.5,-0.5,+0.5, 0,-1,0, c, 1,1), + video::S3DVertex(-0.5,-0.5,+0.5, 0,-1,0, c, 0,1), + // Right + video::S3DVertex(+0.5,-0.5,-0.5, 1,0,0, c, 0,1), + video::S3DVertex(+0.5,+0.5,-0.5, 1,0,0, c, 0,0), + video::S3DVertex(+0.5,+0.5,+0.5, 1,0,0, c, 1,0), + video::S3DVertex(+0.5,-0.5,+0.5, 1,0,0, c, 1,1), + // Left + video::S3DVertex(-0.5,-0.5,-0.5, -1,0,0, c, 1,1), + video::S3DVertex(-0.5,-0.5,+0.5, -1,0,0, c, 0,1), + video::S3DVertex(-0.5,+0.5,+0.5, -1,0,0, c, 0,0), + video::S3DVertex(-0.5,+0.5,-0.5, -1,0,0, c, 1,0), + // Back + video::S3DVertex(-0.5,-0.5,+0.5, 0,0,1, c, 1,1), + video::S3DVertex(+0.5,-0.5,+0.5, 0,0,1, c, 0,1), + video::S3DVertex(+0.5,+0.5,+0.5, 0,0,1, c, 0,0), + video::S3DVertex(-0.5,+0.5,+0.5, 0,0,1, c, 1,0), + // Front + video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1), + video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0), + video::S3DVertex(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0), + video::S3DVertex(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1), + }; + + u16 indices[6] = {0,1,2,2,3,0}; + + scene::SMesh *mesh = new scene::SMesh(); + for (u32 i=0; i<6; ++i) + { + scene::IMeshBuffer *buf = new scene::SMeshBuffer(); + buf->append(vertices + 4 * i, 4, indices, 6); + // Set default material + buf->getMaterial().setFlag(video::EMF_LIGHTING, false); + buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + // Add mesh buffer to mesh + mesh->addMeshBuffer(buf); + buf->drop(); + } + + scene::SAnimatedMesh *anim_mesh = new scene::SAnimatedMesh(mesh); + mesh->drop(); + scaleMesh(anim_mesh, scale); // also recalculates bounding box + return anim_mesh; +} + +void scaleMesh(scene::IMesh *mesh, v3f scale) +{ + if (mesh == NULL) + return; + + aabb3f bbox; + bbox.reset(0, 0, 0); + + u32 mc = mesh->getMeshBufferCount(); + for (u32 j = 0; j < mc; j++) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) + ((video::S3DVertex *)(vertices + i * stride))->Pos *= scale; + + buf->recalculateBoundingBox(); + + // calculate total bounding box + if (j == 0) + bbox = buf->getBoundingBox(); + else + bbox.addInternalBox(buf->getBoundingBox()); + } + mesh->setBoundingBox(bbox); +} + +void translateMesh(scene::IMesh *mesh, v3f vec) +{ + if (mesh == NULL) + return; + + aabb3f bbox; + bbox.reset(0, 0, 0); + + u32 mc = mesh->getMeshBufferCount(); + for (u32 j = 0; j < mc; j++) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) + ((video::S3DVertex *)(vertices + i * stride))->Pos += vec; + + buf->recalculateBoundingBox(); + + // calculate total bounding box + if (j == 0) + bbox = buf->getBoundingBox(); + else + bbox.addInternalBox(buf->getBoundingBox()); + } + mesh->setBoundingBox(bbox); +} + +void setMeshBufferColor(scene::IMeshBuffer *buf, const video::SColor &color) +{ + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *) buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) + ((video::S3DVertex *) (vertices + i * stride))->Color = color; +} + +void setAnimatedMeshColor(scene::IAnimatedMeshSceneNode *node, const video::SColor &color) +{ + for (u32 i = 0; i < node->getMaterialCount(); ++i) { + node->getMaterial(i).EmissiveColor = color; + } +} + +void setMeshColor(scene::IMesh *mesh, const video::SColor &color) +{ + if (mesh == NULL) + return; + + u32 mc = mesh->getMeshBufferCount(); + for (u32 j = 0; j < mc; j++) + setMeshBufferColor(mesh->getMeshBuffer(j), color); +} + +void setMeshBufferTextureCoords(scene::IMeshBuffer *buf, const v2f *uv, u32 count) +{ + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + assert(buf->getVertexCount() >= count); + u8 *vertices = (u8 *) buf->getVertices(); + for (u32 i = 0; i < count; i++) + ((video::S3DVertex*) (vertices + i * stride))->TCoords = uv[i]; +} + +template <typename F> +static void applyToMesh(scene::IMesh *mesh, const F &fn) +{ + u16 mc = mesh->getMeshBufferCount(); + for (u16 j = 0; j < mc; j++) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + char *vertices = reinterpret_cast<char *>(buf->getVertices()); + for (u32 i = 0; i < vertex_count; i++) + fn(reinterpret_cast<video::S3DVertex *>(vertices + i * stride)); + } +} + +void colorizeMeshBuffer(scene::IMeshBuffer *buf, const video::SColor *buffercolor) +{ + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *) buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) { + video::S3DVertex *vertex = (video::S3DVertex *) (vertices + i * stride); + video::SColor *vc = &(vertex->Color); + // Reset color + *vc = *buffercolor; + // Apply shading + applyFacesShading(*vc, vertex->Normal); + } +} + +void setMeshColorByNormalXYZ(scene::IMesh *mesh, + const video::SColor &colorX, + const video::SColor &colorY, + const video::SColor &colorZ) +{ + if (!mesh) + return; + auto colorizator = [=] (video::S3DVertex *vertex) { + f32 x = fabs(vertex->Normal.X); + f32 y = fabs(vertex->Normal.Y); + f32 z = fabs(vertex->Normal.Z); + if (x >= y && x >= z) + vertex->Color = colorX; + else if (y >= z) + vertex->Color = colorY; + else + vertex->Color = colorZ; + }; + applyToMesh(mesh, colorizator); +} + +void setMeshColorByNormal(scene::IMesh *mesh, const v3f &normal, + const video::SColor &color) +{ + if (!mesh) + return; + auto colorizator = [normal, color] (video::S3DVertex *vertex) { + if (vertex->Normal == normal) + vertex->Color = color; + }; + applyToMesh(mesh, colorizator); +} + +template <float v3f::*U, float v3f::*V> +static void rotateMesh(scene::IMesh *mesh, float degrees) +{ + degrees *= M_PI / 180.0f; + float c = std::cos(degrees); + float s = std::sin(degrees); + auto rotator = [c, s] (video::S3DVertex *vertex) { + float u = vertex->Pos.*U; + float v = vertex->Pos.*V; + vertex->Pos.*U = c * u - s * v; + vertex->Pos.*V = s * u + c * v; + }; + applyToMesh(mesh, rotator); +} + +void rotateMeshXYby(scene::IMesh *mesh, f64 degrees) +{ + rotateMesh<&v3f::X, &v3f::Y>(mesh, degrees); +} + +void rotateMeshXZby(scene::IMesh *mesh, f64 degrees) +{ + rotateMesh<&v3f::X, &v3f::Z>(mesh, degrees); +} + +void rotateMeshYZby(scene::IMesh *mesh, f64 degrees) +{ + rotateMesh<&v3f::Y, &v3f::Z>(mesh, degrees); +} + +void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir) +{ + int axisdir = facedir >> 2; + facedir &= 0x03; + switch (facedir) { + case 1: rotateMeshXZby(mesh, -90); break; + case 2: rotateMeshXZby(mesh, 180); break; + case 3: rotateMeshXZby(mesh, 90); break; + } + switch (axisdir) { + case 1: rotateMeshYZby(mesh, 90); break; // z+ + case 2: rotateMeshYZby(mesh, -90); break; // z- + case 3: rotateMeshXYby(mesh, -90); break; // x+ + case 4: rotateMeshXYby(mesh, 90); break; // x- + case 5: rotateMeshXYby(mesh, -180); break; + } +} + +void recalculateBoundingBox(scene::IMesh *src_mesh) +{ + aabb3f bbox; + bbox.reset(0,0,0); + for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) { + scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j); + buf->recalculateBoundingBox(); + if (j == 0) + bbox = buf->getBoundingBox(); + else + bbox.addInternalBox(buf->getBoundingBox()); + } + src_mesh->setBoundingBox(bbox); +} + +bool checkMeshNormals(scene::IMesh *mesh) +{ + u32 buffer_count = mesh->getMeshBufferCount(); + + for (u32 i = 0; i < buffer_count; i++) { + scene::IMeshBuffer *buffer = mesh->getMeshBuffer(i); + + // Here we intentionally check only first normal, assuming that if buffer + // has it valid, then most likely all other ones are fine too. We can + // check all of the normals to have length, but it seems like an overkill + // hurting the performance and covering only really weird broken models. + f32 length = buffer->getNormal(0).getLength(); + + if (!std::isfinite(length) || length < 1e-10f) + return false; + } + + return true; +} + +scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer) +{ + switch (mesh_buffer->getVertexType()) { + case video::EVT_STANDARD: { + video::S3DVertex *v = (video::S3DVertex *) mesh_buffer->getVertices(); + u16 *indices = mesh_buffer->getIndices(); + scene::SMeshBuffer *cloned_buffer = new scene::SMeshBuffer(); + cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices, + mesh_buffer->getIndexCount()); + return cloned_buffer; + } + case video::EVT_2TCOORDS: { + video::S3DVertex2TCoords *v = + (video::S3DVertex2TCoords *) mesh_buffer->getVertices(); + u16 *indices = mesh_buffer->getIndices(); + scene::SMeshBufferLightMap *cloned_buffer = + new scene::SMeshBufferLightMap(); + cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices, + mesh_buffer->getIndexCount()); + return cloned_buffer; + } + case video::EVT_TANGENTS: { + video::S3DVertexTangents *v = + (video::S3DVertexTangents *) mesh_buffer->getVertices(); + u16 *indices = mesh_buffer->getIndices(); + scene::SMeshBufferTangents *cloned_buffer = + new scene::SMeshBufferTangents(); + cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices, + mesh_buffer->getIndexCount()); + return cloned_buffer; + } + } + // This should not happen. + sanity_check(false); + return NULL; +} + +scene::SMesh* cloneMesh(scene::IMesh *src_mesh) +{ + scene::SMesh* dst_mesh = new scene::SMesh(); + for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) { + scene::IMeshBuffer *temp_buf = cloneMeshBuffer( + src_mesh->getMeshBuffer(j)); + dst_mesh->addMeshBuffer(temp_buf); + temp_buf->drop(); + + } + return dst_mesh; +} + +scene::IMesh* convertNodeboxesToMesh(const std::vector<aabb3f> &boxes, + const f32 *uv_coords, float expand) +{ + scene::SMesh* dst_mesh = new scene::SMesh(); + + for (u16 j = 0; j < 6; j++) + { + scene::IMeshBuffer *buf = new scene::SMeshBuffer(); + buf->getMaterial().setFlag(video::EMF_LIGHTING, false); + buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + dst_mesh->addMeshBuffer(buf); + buf->drop(); + } + + video::SColor c(255,255,255,255); + + for (aabb3f box : boxes) { + box.repair(); + + box.MinEdge.X -= expand; + box.MinEdge.Y -= expand; + box.MinEdge.Z -= expand; + box.MaxEdge.X += expand; + box.MaxEdge.Y += expand; + box.MaxEdge.Z += expand; + + // Compute texture UV coords + f32 tx1 = (box.MinEdge.X / BS) + 0.5; + f32 ty1 = (box.MinEdge.Y / BS) + 0.5; + f32 tz1 = (box.MinEdge.Z / BS) + 0.5; + f32 tx2 = (box.MaxEdge.X / BS) + 0.5; + f32 ty2 = (box.MaxEdge.Y / BS) + 0.5; + f32 tz2 = (box.MaxEdge.Z / BS) + 0.5; + + f32 txc_default[24] = { + // up + tx1, 1 - tz2, tx2, 1 - tz1, + // down + tx1, tz1, tx2, tz2, + // right + tz1, 1 - ty2, tz2, 1 - ty1, + // left + 1 - tz2, 1 - ty2, 1 - tz1, 1 - ty1, + // back + 1 - tx2, 1 - ty2, 1 - tx1, 1 - ty1, + // front + tx1, 1 - ty2, tx2, 1 - ty1, + }; + + // use default texture UV mapping if not provided + const f32 *txc = uv_coords ? uv_coords : txc_default; + + v3f min = box.MinEdge; + v3f max = box.MaxEdge; + + video::S3DVertex vertices[24] = + { + // up + video::S3DVertex(min.X,max.Y,max.Z, 0,1,0, c, txc[0],txc[1]), + video::S3DVertex(max.X,max.Y,max.Z, 0,1,0, c, txc[2],txc[1]), + video::S3DVertex(max.X,max.Y,min.Z, 0,1,0, c, txc[2],txc[3]), + video::S3DVertex(min.X,max.Y,min.Z, 0,1,0, c, txc[0],txc[3]), + // down + video::S3DVertex(min.X,min.Y,min.Z, 0,-1,0, c, txc[4],txc[5]), + video::S3DVertex(max.X,min.Y,min.Z, 0,-1,0, c, txc[6],txc[5]), + video::S3DVertex(max.X,min.Y,max.Z, 0,-1,0, c, txc[6],txc[7]), + video::S3DVertex(min.X,min.Y,max.Z, 0,-1,0, c, txc[4],txc[7]), + // right + video::S3DVertex(max.X,max.Y,min.Z, 1,0,0, c, txc[ 8],txc[9]), + video::S3DVertex(max.X,max.Y,max.Z, 1,0,0, c, txc[10],txc[9]), + video::S3DVertex(max.X,min.Y,max.Z, 1,0,0, c, txc[10],txc[11]), + video::S3DVertex(max.X,min.Y,min.Z, 1,0,0, c, txc[ 8],txc[11]), + // left + video::S3DVertex(min.X,max.Y,max.Z, -1,0,0, c, txc[12],txc[13]), + video::S3DVertex(min.X,max.Y,min.Z, -1,0,0, c, txc[14],txc[13]), + video::S3DVertex(min.X,min.Y,min.Z, -1,0,0, c, txc[14],txc[15]), + video::S3DVertex(min.X,min.Y,max.Z, -1,0,0, c, txc[12],txc[15]), + // back + video::S3DVertex(max.X,max.Y,max.Z, 0,0,1, c, txc[16],txc[17]), + video::S3DVertex(min.X,max.Y,max.Z, 0,0,1, c, txc[18],txc[17]), + video::S3DVertex(min.X,min.Y,max.Z, 0,0,1, c, txc[18],txc[19]), + video::S3DVertex(max.X,min.Y,max.Z, 0,0,1, c, txc[16],txc[19]), + // front + video::S3DVertex(min.X,max.Y,min.Z, 0,0,-1, c, txc[20],txc[21]), + video::S3DVertex(max.X,max.Y,min.Z, 0,0,-1, c, txc[22],txc[21]), + video::S3DVertex(max.X,min.Y,min.Z, 0,0,-1, c, txc[22],txc[23]), + video::S3DVertex(min.X,min.Y,min.Z, 0,0,-1, c, txc[20],txc[23]), + }; + + u16 indices[] = {0,1,2,2,3,0}; + + for(u16 j = 0; j < 24; j += 4) + { + scene::IMeshBuffer *buf = dst_mesh->getMeshBuffer(j / 4); + buf->append(vertices + j, 4, indices, 6); + } + } + return dst_mesh; +} diff --git a/src/client/mesh.h b/src/client/mesh.h new file mode 100644 index 0000000..1ed753c --- /dev/null +++ b/src/client/mesh.h @@ -0,0 +1,135 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "nodedef.h" + +/*! + * Applies shading to a color based on the surface's + * normal vector. + */ +void applyFacesShading(video::SColor &color, const v3f &normal); + +/* + Create a new cube mesh. + Vertices are at (+-scale.X/2, +-scale.Y/2, +-scale.Z/2). + + The resulting mesh has 6 materials (up, down, right, left, back, front) + which must be defined by the caller. +*/ +scene::IAnimatedMesh* createCubeMesh(v3f scale); + +/* + Multiplies each vertex coordinate by the specified scaling factors + (componentwise vector multiplication). +*/ +void scaleMesh(scene::IMesh *mesh, v3f scale); + +/* + Translate each vertex coordinate by the specified vector. +*/ +void translateMesh(scene::IMesh *mesh, v3f vec); + +/*! + * Sets a constant color for all vertices in the mesh buffer. + */ +void setMeshBufferColor(scene::IMeshBuffer *buf, const video::SColor &color); + +/* + Set a constant color for all vertices in the mesh +*/ +void setMeshColor(scene::IMesh *mesh, const video::SColor &color); + + +/* + Sets texture coords for vertices in the mesh buffer. + `uv[]` must have `count` elements +*/ +void setMeshBufferTextureCoords(scene::IMeshBuffer *buf, const v2f *uv, u32 count); + +/* + Set a constant color for an animated mesh +*/ +void setAnimatedMeshColor(scene::IAnimatedMeshSceneNode *node, const video::SColor &color); + +/*! + * Overwrites the color of a mesh buffer. + * The color is darkened based on the normal vector of the vertices. + */ +void colorizeMeshBuffer(scene::IMeshBuffer *buf, const video::SColor *buffercolor); + +/* + Set the color of all vertices in the mesh. + For each vertex, determine the largest absolute entry in + the normal vector, and choose one of colorX, colorY or + colorZ accordingly. +*/ +void setMeshColorByNormalXYZ(scene::IMesh *mesh, + const video::SColor &colorX, + const video::SColor &colorY, + const video::SColor &colorZ); + +void setMeshColorByNormal(scene::IMesh *mesh, const v3f &normal, + const video::SColor &color); + +/* + Rotate the mesh by 6d facedir value. + Method only for meshnodes, not suitable for entities. +*/ +void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir); + +/* + Rotate the mesh around the axis and given angle in degrees. +*/ +void rotateMeshXYby (scene::IMesh *mesh, f64 degrees); +void rotateMeshXZby (scene::IMesh *mesh, f64 degrees); +void rotateMeshYZby (scene::IMesh *mesh, f64 degrees); + +/* + * Clone the mesh buffer. + * The returned pointer should be dropped. + */ +scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer); + +/* + Clone the mesh. +*/ +scene::SMesh* cloneMesh(scene::IMesh *src_mesh); + +/* + Convert nodeboxes to mesh. Each tile goes into a different buffer. + boxes - set of nodeboxes to be converted into cuboids + uv_coords[24] - table of texture uv coords for each cuboid face + expand - factor by which cuboids will be resized +*/ +scene::IMesh* convertNodeboxesToMesh(const std::vector<aabb3f> &boxes, + const f32 *uv_coords = NULL, float expand = 0); + +/* + Update bounding box for a mesh. +*/ +void recalculateBoundingBox(scene::IMesh *src_mesh); + +/* + Check if mesh has valid normals and return true if it does. + We assume normal to be valid when it's 0 < length < Inf. and not NaN + */ +bool checkMeshNormals(scene::IMesh *mesh); diff --git a/src/client/mesh_generator_thread.cpp b/src/client/mesh_generator_thread.cpp new file mode 100644 index 0000000..ec567c8 --- /dev/null +++ b/src/client/mesh_generator_thread.cpp @@ -0,0 +1,321 @@ +/* +Minetest +Copyright (C) 2013, 2017 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mesh_generator_thread.h" +#include "settings.h" +#include "profiler.h" +#include "client.h" +#include "mapblock.h" +#include "map.h" +#include "util/directiontables.h" + +/* + CachedMapBlockData +*/ + +CachedMapBlockData::~CachedMapBlockData() +{ + assert(refcount_from_queue == 0); + + delete[] data; +} + +/* + QueuedMeshUpdate +*/ + +QueuedMeshUpdate::~QueuedMeshUpdate() +{ + delete data; +} + +/* + MeshUpdateQueue +*/ + +MeshUpdateQueue::MeshUpdateQueue(Client *client): + m_client(client), + m_next_cache_cleanup(0) +{ + m_cache_enable_shaders = g_settings->getBool("enable_shaders"); + m_cache_smooth_lighting = g_settings->getBool("smooth_lighting"); + m_meshgen_block_cache_size = g_settings->getS32("meshgen_block_cache_size"); +} + +MeshUpdateQueue::~MeshUpdateQueue() +{ + MutexAutoLock lock(m_mutex); + + for (auto &i : m_cache) { + delete i.second; + } + + for (QueuedMeshUpdate *q : m_queue) { + delete q; + } +} + +bool MeshUpdateQueue::addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent) +{ + MutexAutoLock lock(m_mutex); + + cleanupCache(); + + /* + Cache the block data (force-update the center block, don't update the + neighbors but get them if they aren't already cached) + */ + std::vector<CachedMapBlockData*> cached_blocks; + size_t cache_hit_counter = 0; + CachedMapBlockData *cached_block = cacheBlock(map, p, FORCE_UPDATE); + if (!cached_block->data) + return false; // nothing to update + cached_blocks.reserve(3*3*3); + cached_blocks.push_back(cached_block); + for (v3s16 dp : g_26dirs) + cached_blocks.push_back(cacheBlock(map, p + dp, + SKIP_UPDATE_IF_ALREADY_CACHED, + &cache_hit_counter)); + g_profiler->avg("MeshUpdateQueue: MapBlocks from cache [%]", + 100.0f * cache_hit_counter / cached_blocks.size()); + + /* + Mark the block as urgent if requested + */ + if (urgent) + m_urgents.insert(p); + + /* + Find if block is already in queue. + If it is, update the data and quit. + */ + for (QueuedMeshUpdate *q : m_queue) { + if (q->p == p) { + // NOTE: We are not adding a new position to the queue, thus + // refcount_from_queue stays the same. + if(ack_block_to_server) + q->ack_block_to_server = true; + q->crack_level = m_client->getCrackLevel(); + q->crack_pos = m_client->getCrackPos(); + q->urgent |= urgent; + return true; + } + } + + /* + Add the block + */ + QueuedMeshUpdate *q = new QueuedMeshUpdate; + q->p = p; + q->ack_block_to_server = ack_block_to_server; + q->crack_level = m_client->getCrackLevel(); + q->crack_pos = m_client->getCrackPos(); + q->urgent = urgent; + m_queue.push_back(q); + + // This queue entry is a new reference to the cached blocks + for (CachedMapBlockData *cached_block : cached_blocks) { + cached_block->refcount_from_queue++; + } + return true; +} + +// Returned pointer must be deleted +// Returns NULL if queue is empty +QueuedMeshUpdate *MeshUpdateQueue::pop() +{ + MutexAutoLock lock(m_mutex); + + bool must_be_urgent = !m_urgents.empty(); + for (std::vector<QueuedMeshUpdate*>::iterator i = m_queue.begin(); + i != m_queue.end(); ++i) { + QueuedMeshUpdate *q = *i; + if(must_be_urgent && m_urgents.count(q->p) == 0) + continue; + m_queue.erase(i); + m_urgents.erase(q->p); + fillDataFromMapBlockCache(q); + return q; + } + return NULL; +} + +CachedMapBlockData* MeshUpdateQueue::cacheBlock(Map *map, v3s16 p, UpdateMode mode, + size_t *cache_hit_counter) +{ + CachedMapBlockData *cached_block = nullptr; + auto it = m_cache.find(p); + + if (it != m_cache.end()) { + cached_block = it->second; + + if (mode == SKIP_UPDATE_IF_ALREADY_CACHED) { + if (cache_hit_counter) + (*cache_hit_counter)++; + return cached_block; + } + } + + if (!cached_block) { + // Not yet in cache + cached_block = new CachedMapBlockData(); + m_cache[p] = cached_block; + } + + MapBlock *b = map->getBlockNoCreateNoEx(p); + if (b) { + if (!cached_block->data) + cached_block->data = + new MapNode[MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE]; + memcpy(cached_block->data, b->getData(), + MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE * sizeof(MapNode)); + } else { + delete[] cached_block->data; + cached_block->data = nullptr; + } + return cached_block; +} + +CachedMapBlockData* MeshUpdateQueue::getCachedBlock(const v3s16 &p) +{ + auto it = m_cache.find(p); + if (it != m_cache.end()) { + return it->second; + } + return NULL; +} + +void MeshUpdateQueue::fillDataFromMapBlockCache(QueuedMeshUpdate *q) +{ + MeshMakeData *data = new MeshMakeData(m_client, m_cache_enable_shaders); + q->data = data; + + data->fillBlockDataBegin(q->p); + + std::time_t t_now = std::time(0); + + // Collect data for 3*3*3 blocks from cache + for (v3s16 dp : g_27dirs) { + v3s16 p = q->p + dp; + CachedMapBlockData *cached_block = getCachedBlock(p); + if (cached_block) { + cached_block->refcount_from_queue--; + cached_block->last_used_timestamp = t_now; + if (cached_block->data) + data->fillBlockData(dp, cached_block->data); + } + } + + data->setCrack(q->crack_level, q->crack_pos); + data->setSmoothLighting(m_cache_smooth_lighting); +} + +void MeshUpdateQueue::cleanupCache() +{ + const int mapblock_kB = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE * + sizeof(MapNode) / 1000; + g_profiler->avg("MeshUpdateQueue MapBlock cache size kB", + mapblock_kB * m_cache.size()); + + // Iterating the entire cache can get pretty expensive so don't do it too often + { + constexpr int cleanup_interval = 250; + const u64 now = porting::getTimeMs(); + if (m_next_cache_cleanup > now) + return; + m_next_cache_cleanup = now + cleanup_interval; + } + + // The cache size is kept roughly below cache_soft_max_size, not letting + // anything get older than cache_seconds_max or deleted before 2 seconds. + const int cache_seconds_max = 10; + const int cache_soft_max_size = m_meshgen_block_cache_size * 1000 / mapblock_kB; + int cache_seconds = MYMAX(2, cache_seconds_max - + m_cache.size() / (cache_soft_max_size / cache_seconds_max)); + + int t_now = time(0); + + for (auto it = m_cache.begin(); it != m_cache.end(); ) { + CachedMapBlockData *cached_block = it->second; + if (cached_block->refcount_from_queue == 0 && + cached_block->last_used_timestamp < t_now - cache_seconds) { + it = m_cache.erase(it); + delete cached_block; + } else { + ++it; + } + } +} + +/* + MeshUpdateThread +*/ + +MeshUpdateThread::MeshUpdateThread(Client *client): + UpdateThread("Mesh"), + m_queue_in(client) +{ + m_generation_interval = g_settings->getU16("mesh_generation_interval"); + m_generation_interval = rangelim(m_generation_interval, 0, 50); +} + +void MeshUpdateThread::updateBlock(Map *map, v3s16 p, bool ack_block_to_server, + bool urgent, bool update_neighbors) +{ + static thread_local const bool many_neighbors = + g_settings->getBool("smooth_lighting") + && !g_settings->getFlag("performance_tradeoffs"); + if (!m_queue_in.addBlock(map, p, ack_block_to_server, urgent)) { + warningstream << "Update requested for non-existent block at (" + << p.X << ", " << p.Y << ", " << p.Z << ")" << std::endl; + return; + } + if (update_neighbors) { + if (many_neighbors) { + for (v3s16 dp : g_26dirs) + m_queue_in.addBlock(map, p + dp, false, urgent); + } else { + for (v3s16 dp : g_6dirs) + m_queue_in.addBlock(map, p + dp, false, urgent); + } + } + deferUpdate(); +} + +void MeshUpdateThread::doUpdate() +{ + QueuedMeshUpdate *q; + while ((q = m_queue_in.pop())) { + if (m_generation_interval) + sleep_ms(m_generation_interval); + ScopeProfiler sp(g_profiler, "Client: Mesh making (sum)"); + + MapBlockMesh *mesh_new = new MapBlockMesh(q->data, m_camera_offset); + + MeshUpdateResult r; + r.p = q->p; + r.mesh = mesh_new; + r.ack_block_to_server = q->ack_block_to_server; + r.urgent = q->urgent; + + m_queue_out.push_back(r); + + delete q; + } +} diff --git a/src/client/mesh_generator_thread.h b/src/client/mesh_generator_thread.h new file mode 100644 index 0000000..0940019 --- /dev/null +++ b/src/client/mesh_generator_thread.h @@ -0,0 +1,135 @@ +/* +Minetest +Copyright (C) 2013, 2017 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <ctime> +#include <mutex> +#include <unordered_map> +#include <unordered_set> +#include "mapblock_mesh.h" +#include "threading/mutex_auto_lock.h" +#include "util/thread.h" + +struct CachedMapBlockData +{ + v3s16 p = v3s16(-1337, -1337, -1337); + MapNode *data = nullptr; // A copy of the MapBlock's data member + int refcount_from_queue = 0; + std::time_t last_used_timestamp = std::time(0); + + CachedMapBlockData() = default; + ~CachedMapBlockData(); +}; + +struct QueuedMeshUpdate +{ + v3s16 p = v3s16(-1337, -1337, -1337); + bool ack_block_to_server = false; + int crack_level = -1; + v3s16 crack_pos; + MeshMakeData *data = nullptr; // This is generated in MeshUpdateQueue::pop() + bool urgent = false; + + QueuedMeshUpdate() = default; + ~QueuedMeshUpdate(); +}; + +/* + A thread-safe queue of mesh update tasks and a cache of MapBlock data +*/ +class MeshUpdateQueue +{ + enum UpdateMode + { + FORCE_UPDATE, + SKIP_UPDATE_IF_ALREADY_CACHED, + }; + +public: + MeshUpdateQueue(Client *client); + + ~MeshUpdateQueue(); + + // Caches the block at p and its neighbors (if needed) and queues a mesh + // update for the block at p + bool addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent); + + // Returned pointer must be deleted + // Returns NULL if queue is empty + QueuedMeshUpdate *pop(); + + u32 size() + { + MutexAutoLock lock(m_mutex); + return m_queue.size(); + } + +private: + Client *m_client; + std::vector<QueuedMeshUpdate *> m_queue; + std::unordered_set<v3s16> m_urgents; + std::unordered_map<v3s16, CachedMapBlockData *> m_cache; + u64 m_next_cache_cleanup; // milliseconds + std::mutex m_mutex; + + // TODO: Add callback to update these when g_settings changes + bool m_cache_enable_shaders; + bool m_cache_smooth_lighting; + int m_meshgen_block_cache_size; + + CachedMapBlockData *cacheBlock(Map *map, v3s16 p, UpdateMode mode, + size_t *cache_hit_counter = NULL); + CachedMapBlockData *getCachedBlock(const v3s16 &p); + void fillDataFromMapBlockCache(QueuedMeshUpdate *q); + void cleanupCache(); +}; + +struct MeshUpdateResult +{ + v3s16 p = v3s16(-1338, -1338, -1338); + MapBlockMesh *mesh = nullptr; + bool ack_block_to_server = false; + bool urgent = false; + + MeshUpdateResult() = default; +}; + +class MeshUpdateThread : public UpdateThread +{ +public: + MeshUpdateThread(Client *client); + + // Caches the block at p and its neighbors (if needed) and queues a mesh + // update for the block at p + void updateBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent, + bool update_neighbors = false); + + v3s16 m_camera_offset; + MutexedQueue<MeshUpdateResult> m_queue_out; + +private: + MeshUpdateQueue m_queue_in; + + // TODO: Add callback to update these when g_settings changes + int m_generation_interval; + +protected: + virtual void doUpdate(); +}; diff --git a/src/client/meshgen/collector.cpp b/src/client/meshgen/collector.cpp new file mode 100644 index 0000000..25457c8 --- /dev/null +++ b/src/client/meshgen/collector.cpp @@ -0,0 +1,104 @@ +/* +Minetest +Copyright (C) 2018 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "collector.h" +#include <stdexcept> +#include "log.h" +#include "client/mesh.h" + +void MeshCollector::append(const TileSpec &tile, const video::S3DVertex *vertices, + u32 numVertices, const u16 *indices, u32 numIndices) +{ + for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) { + const TileLayer *layer = &tile.layers[layernum]; + if (layer->texture_id == 0) + continue; + append(*layer, vertices, numVertices, indices, numIndices, layernum, + tile.world_aligned); + } +} + +void MeshCollector::append(const TileLayer &layer, const video::S3DVertex *vertices, + u32 numVertices, const u16 *indices, u32 numIndices, u8 layernum, + bool use_scale) +{ + PreMeshBuffer &p = findBuffer(layer, layernum, numVertices); + + f32 scale = 1.0f; + if (use_scale) + scale = 1.0f / layer.scale; + + u32 vertex_count = p.vertices.size(); + for (u32 i = 0; i < numVertices; i++) + p.vertices.emplace_back(vertices[i].Pos, vertices[i].Normal, + vertices[i].Color, scale * vertices[i].TCoords); + + for (u32 i = 0; i < numIndices; i++) + p.indices.push_back(indices[i] + vertex_count); +} + +void MeshCollector::append(const TileSpec &tile, const video::S3DVertex *vertices, + u32 numVertices, const u16 *indices, u32 numIndices, v3f pos, + video::SColor c, u8 light_source) +{ + for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) { + const TileLayer *layer = &tile.layers[layernum]; + if (layer->texture_id == 0) + continue; + append(*layer, vertices, numVertices, indices, numIndices, pos, c, + light_source, layernum, tile.world_aligned); + } +} + +void MeshCollector::append(const TileLayer &layer, const video::S3DVertex *vertices, + u32 numVertices, const u16 *indices, u32 numIndices, v3f pos, + video::SColor c, u8 light_source, u8 layernum, bool use_scale) +{ + PreMeshBuffer &p = findBuffer(layer, layernum, numVertices); + + f32 scale = 1.0f; + if (use_scale) + scale = 1.0f / layer.scale; + + u32 vertex_count = p.vertices.size(); + for (u32 i = 0; i < numVertices; i++) { + video::SColor color = c; + if (!light_source) + applyFacesShading(color, vertices[i].Normal); + p.vertices.emplace_back(vertices[i].Pos + pos, vertices[i].Normal, color, + scale * vertices[i].TCoords); + } + + for (u32 i = 0; i < numIndices; i++) + p.indices.push_back(indices[i] + vertex_count); +} + +PreMeshBuffer &MeshCollector::findBuffer( + const TileLayer &layer, u8 layernum, u32 numVertices) +{ + if (numVertices > U16_MAX) + throw std::invalid_argument( + "Mesh can't contain more than 65536 vertices"); + std::vector<PreMeshBuffer> &buffers = prebuffers[layernum]; + for (PreMeshBuffer &p : buffers) + if (p.layer == layer && p.vertices.size() + numVertices <= U16_MAX) + return p; + buffers.emplace_back(layer); + return buffers.back(); +} diff --git a/src/client/meshgen/collector.h b/src/client/meshgen/collector.h new file mode 100644 index 0000000..e418908 --- /dev/null +++ b/src/client/meshgen/collector.h @@ -0,0 +1,65 @@ +/* +Minetest +Copyright (C) 2018 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include <array> +#include <vector> +#include "irrlichttypes.h" +#include <S3DVertex.h> +#include "client/tile.h" + +struct PreMeshBuffer +{ + TileLayer layer; + std::vector<u16> indices; + std::vector<video::S3DVertex> vertices; + + PreMeshBuffer() = default; + explicit PreMeshBuffer(const TileLayer &layer) : layer(layer) {} +}; + +struct MeshCollector +{ + std::array<std::vector<PreMeshBuffer>, MAX_TILE_LAYERS> prebuffers; + + // clang-format off + void append(const TileSpec &material, + const video::S3DVertex *vertices, u32 numVertices, + const u16 *indices, u32 numIndices); + void append(const TileSpec &material, + const video::S3DVertex *vertices, u32 numVertices, + const u16 *indices, u32 numIndices, + v3f pos, video::SColor c, u8 light_source); + // clang-format on + +private: + // clang-format off + void append(const TileLayer &material, + const video::S3DVertex *vertices, u32 numVertices, + const u16 *indices, u32 numIndices, + u8 layernum, bool use_scale = false); + void append(const TileLayer &material, + const video::S3DVertex *vertices, u32 numVertices, + const u16 *indices, u32 numIndices, + v3f pos, video::SColor c, u8 light_source, + u8 layernum, bool use_scale = false); + // clang-format on + + PreMeshBuffer &findBuffer(const TileLayer &layer, u8 layernum, u32 numVertices); +}; diff --git a/src/client/minimap.cpp b/src/client/minimap.cpp new file mode 100644 index 0000000..320621d --- /dev/null +++ b/src/client/minimap.cpp @@ -0,0 +1,762 @@ +/* +Minetest +Copyright (C) 2010-2015 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "minimap.h" +#include <cmath> +#include "client.h" +#include "clientmap.h" +#include "settings.h" +#include "shader.h" +#include "mapblock.h" +#include "client/renderingengine.h" +#include "gettext.h" + +//// +//// MinimapUpdateThread +//// + +MinimapUpdateThread::~MinimapUpdateThread() +{ + for (auto &it : m_blocks_cache) { + delete it.second; + } + + for (auto &q : m_update_queue) { + delete q.data; + } +} + +bool MinimapUpdateThread::pushBlockUpdate(v3s16 pos, MinimapMapblock *data) +{ + MutexAutoLock lock(m_queue_mutex); + + // Find if block is already in queue. + // If it is, update the data and quit. + for (QueuedMinimapUpdate &q : m_update_queue) { + if (q.pos == pos) { + delete q.data; + q.data = data; + return false; + } + } + + // Add the block + QueuedMinimapUpdate q; + q.pos = pos; + q.data = data; + m_update_queue.push_back(q); + + return true; +} + +bool MinimapUpdateThread::popBlockUpdate(QueuedMinimapUpdate *update) +{ + MutexAutoLock lock(m_queue_mutex); + + if (m_update_queue.empty()) + return false; + + *update = m_update_queue.front(); + m_update_queue.pop_front(); + + return true; +} + +void MinimapUpdateThread::enqueueBlock(v3s16 pos, MinimapMapblock *data) +{ + pushBlockUpdate(pos, data); + deferUpdate(); +} + + +void MinimapUpdateThread::doUpdate() +{ + QueuedMinimapUpdate update; + + while (popBlockUpdate(&update)) { + if (update.data) { + // Swap two values in the map using single lookup + std::pair<std::map<v3s16, MinimapMapblock*>::iterator, bool> + result = m_blocks_cache.insert(std::make_pair(update.pos, update.data)); + if (!result.second) { + delete result.first->second; + result.first->second = update.data; + } + } else { + std::map<v3s16, MinimapMapblock *>::iterator it; + it = m_blocks_cache.find(update.pos); + if (it != m_blocks_cache.end()) { + delete it->second; + m_blocks_cache.erase(it); + } + } + } + + + if (data->map_invalidated && ( + data->mode.type == MINIMAP_TYPE_RADAR || + data->mode.type == MINIMAP_TYPE_SURFACE)) { + getMap(data->pos, data->mode.map_size, data->mode.scan_height); + data->map_invalidated = false; + } +} + +void MinimapUpdateThread::getMap(v3s16 pos, s16 size, s16 height) +{ + v3s16 pos_min(pos.X - size / 2, pos.Y - height / 2, pos.Z - size / 2); + v3s16 pos_max(pos_min.X + size - 1, pos.Y + height / 2, pos_min.Z + size - 1); + v3s16 blockpos_min = getNodeBlockPos(pos_min); + v3s16 blockpos_max = getNodeBlockPos(pos_max); + +// clear the map + for (int z = 0; z < size; z++) + for (int x = 0; x < size; x++) { + MinimapPixel &mmpixel = data->minimap_scan[x + z * size]; + mmpixel.air_count = 0; + mmpixel.height = 0; + mmpixel.n = MapNode(CONTENT_AIR); + } + +// draw the map + v3s16 blockpos; + for (blockpos.Z = blockpos_min.Z; blockpos.Z <= blockpos_max.Z; ++blockpos.Z) + for (blockpos.Y = blockpos_min.Y; blockpos.Y <= blockpos_max.Y; ++blockpos.Y) + for (blockpos.X = blockpos_min.X; blockpos.X <= blockpos_max.X; ++blockpos.X) { + std::map<v3s16, MinimapMapblock *>::const_iterator pblock = + m_blocks_cache.find(blockpos); + if (pblock == m_blocks_cache.end()) + continue; + const MinimapMapblock &block = *pblock->second; + + v3s16 block_node_min(blockpos * MAP_BLOCKSIZE); + v3s16 block_node_max(block_node_min + MAP_BLOCKSIZE - 1); + // clip + v3s16 range_min = componentwise_max(block_node_min, pos_min); + v3s16 range_max = componentwise_min(block_node_max, pos_max); + + v3s16 pos; + pos.Y = range_min.Y; + for (pos.Z = range_min.Z; pos.Z <= range_max.Z; ++pos.Z) + for (pos.X = range_min.X; pos.X <= range_max.X; ++pos.X) { + v3s16 inblock_pos = pos - block_node_min; + const MinimapPixel &in_pixel = + block.data[inblock_pos.Z * MAP_BLOCKSIZE + inblock_pos.X]; + + v3s16 inmap_pos = pos - pos_min; + MinimapPixel &out_pixel = + data->minimap_scan[inmap_pos.X + inmap_pos.Z * size]; + + out_pixel.air_count += in_pixel.air_count; + if (in_pixel.n.param0 != CONTENT_AIR) { + out_pixel.n = in_pixel.n; + out_pixel.height = inmap_pos.Y + in_pixel.height; + } + } + } +} + +//// +//// Mapper +//// + +Minimap::Minimap(Client *client) +{ + this->client = client; + this->driver = RenderingEngine::get_video_driver(); + this->m_tsrc = client->getTextureSource(); + this->m_shdrsrc = client->getShaderSource(); + this->m_ndef = client->getNodeDefManager(); + + m_angle = 0.f; + m_current_mode_index = 0; + + // Initialize static settings + m_enable_shaders = g_settings->getBool("enable_shaders"); + m_surface_mode_scan_height = + g_settings->getBool("minimap_double_scan_height") ? 256 : 128; + + // Initialize minimap modes + addMode(MINIMAP_TYPE_OFF); + addMode(MINIMAP_TYPE_SURFACE, 256); + addMode(MINIMAP_TYPE_SURFACE, 128); + addMode(MINIMAP_TYPE_SURFACE, 64); + addMode(MINIMAP_TYPE_RADAR, 512); + addMode(MINIMAP_TYPE_RADAR, 256); + addMode(MINIMAP_TYPE_RADAR, 128); + + // Initialize minimap data + data = new MinimapData; + data->map_invalidated = true; + + data->minimap_shape_round = g_settings->getBool("minimap_shape_round"); + + // Get round minimap textures + data->minimap_mask_round = driver->createImage( + m_tsrc->getTexture("minimap_mask_round.png"), + core::position2d<s32>(0, 0), + core::dimension2d<u32>(MINIMAP_MAX_SX, MINIMAP_MAX_SY)); + data->minimap_overlay_round = m_tsrc->getTexture("minimap_overlay_round.png"); + + // Get square minimap textures + data->minimap_mask_square = driver->createImage( + m_tsrc->getTexture("minimap_mask_square.png"), + core::position2d<s32>(0, 0), + core::dimension2d<u32>(MINIMAP_MAX_SX, MINIMAP_MAX_SY)); + data->minimap_overlay_square = m_tsrc->getTexture("minimap_overlay_square.png"); + + // Create player marker texture + data->player_marker = m_tsrc->getTexture("player_marker.png"); + // Create object marker texture + data->object_marker_red = m_tsrc->getTexture("object_marker_red.png"); + + setModeIndex(0); + + // Create mesh buffer for minimap + m_meshbuffer = getMinimapMeshBuffer(); + + // Initialize and start thread + m_minimap_update_thread = new MinimapUpdateThread(); + m_minimap_update_thread->data = data; + m_minimap_update_thread->start(); +} + +Minimap::~Minimap() +{ + m_minimap_update_thread->stop(); + m_minimap_update_thread->wait(); + + m_meshbuffer->drop(); + + data->minimap_mask_round->drop(); + data->minimap_mask_square->drop(); + + driver->removeTexture(data->texture); + driver->removeTexture(data->heightmap_texture); + driver->removeTexture(data->minimap_overlay_round); + driver->removeTexture(data->minimap_overlay_square); + driver->removeTexture(data->object_marker_red); + + for (MinimapMarker *m : m_markers) + delete m; + m_markers.clear(); + + delete data; + delete m_minimap_update_thread; +} + +void Minimap::addBlock(v3s16 pos, MinimapMapblock *data) +{ + m_minimap_update_thread->enqueueBlock(pos, data); +} + +void Minimap::toggleMinimapShape() +{ + MutexAutoLock lock(m_mutex); + + data->minimap_shape_round = !data->minimap_shape_round; + g_settings->setBool("minimap_shape_round", data->minimap_shape_round); + m_minimap_update_thread->deferUpdate(); +} + +void Minimap::setMinimapShape(MinimapShape shape) +{ + MutexAutoLock lock(m_mutex); + + if (shape == MINIMAP_SHAPE_SQUARE) + data->minimap_shape_round = false; + else if (shape == MINIMAP_SHAPE_ROUND) + data->minimap_shape_round = true; + + g_settings->setBool("minimap_shape_round", data->minimap_shape_round); + m_minimap_update_thread->deferUpdate(); +} + +MinimapShape Minimap::getMinimapShape() +{ + if (data->minimap_shape_round) { + return MINIMAP_SHAPE_ROUND; + } + + return MINIMAP_SHAPE_SQUARE; +} + +void Minimap::setModeIndex(size_t index) +{ + MutexAutoLock lock(m_mutex); + + if (index < m_modes.size()) { + data->mode = m_modes[index]; + m_current_mode_index = index; + } else { + data->mode = {MINIMAP_TYPE_OFF, gettext("Minimap hidden"), 0, 0, "", 0}; + m_current_mode_index = 0; + } + + data->map_invalidated = true; + + if (m_minimap_update_thread) + m_minimap_update_thread->deferUpdate(); +} + +void Minimap::addMode(MinimapModeDef mode) +{ + // Check validity + if (mode.type == MINIMAP_TYPE_TEXTURE) { + if (mode.texture.empty()) + return; + if (mode.scale < 1) + mode.scale = 1; + } + + int zoom = -1; + + // Build a default standard label + if (mode.label == "") { + switch (mode.type) { + case MINIMAP_TYPE_OFF: + mode.label = gettext("Minimap hidden"); + break; + case MINIMAP_TYPE_SURFACE: + mode.label = gettext("Minimap in surface mode, Zoom x%d"); + if (mode.map_size > 0) + zoom = 256 / mode.map_size; + break; + case MINIMAP_TYPE_RADAR: + mode.label = gettext("Minimap in radar mode, Zoom x%d"); + if (mode.map_size > 0) + zoom = 512 / mode.map_size; + break; + case MINIMAP_TYPE_TEXTURE: + mode.label = gettext("Minimap in texture mode"); + break; + default: + break; + } + } + // else: Custom labels need mod-provided client-side translation + + if (zoom >= 0) { + char label_buf[1024]; + porting::mt_snprintf(label_buf, sizeof(label_buf), + mode.label.c_str(), zoom); + mode.label = label_buf; + } + + m_modes.push_back(mode); +} + +void Minimap::addMode(MinimapType type, u16 size, std::string label, + std::string texture, u16 scale) +{ + MinimapModeDef mode; + mode.type = type; + mode.label = label; + mode.map_size = size; + mode.texture = texture; + mode.scale = scale; + switch (type) { + case MINIMAP_TYPE_SURFACE: + mode.scan_height = m_surface_mode_scan_height; + break; + case MINIMAP_TYPE_RADAR: + mode.scan_height = 32; + break; + default: + mode.scan_height = 0; + } + addMode(mode); +} + +void Minimap::nextMode() +{ + if (m_modes.empty()) + return; + m_current_mode_index++; + if (m_current_mode_index >= m_modes.size()) + m_current_mode_index = 0; + + setModeIndex(m_current_mode_index); +} + +void Minimap::setPos(v3s16 pos) +{ + bool do_update = false; + + { + MutexAutoLock lock(m_mutex); + + if (pos != data->old_pos) { + data->old_pos = data->pos; + data->pos = pos; + do_update = true; + } + } + + if (do_update) + m_minimap_update_thread->deferUpdate(); +} + +void Minimap::setAngle(f32 angle) +{ + m_angle = angle; +} + +void Minimap::blitMinimapPixelsToImageRadar(video::IImage *map_image) +{ + video::SColor c(240, 0, 0, 0); + for (s16 x = 0; x < data->mode.map_size; x++) + for (s16 z = 0; z < data->mode.map_size; z++) { + MinimapPixel *mmpixel = &data->minimap_scan[x + z * data->mode.map_size]; + + if (mmpixel->air_count > 0) + c.setGreen(core::clamp(core::round32(32 + mmpixel->air_count * 8), 0, 255)); + else + c.setGreen(0); + + map_image->setPixel(x, data->mode.map_size - z - 1, c); + } +} + +void Minimap::blitMinimapPixelsToImageSurface( + video::IImage *map_image, video::IImage *heightmap_image) +{ + // This variable creation/destruction has a 1% cost on rendering minimap + video::SColor tilecolor; + for (s16 x = 0; x < data->mode.map_size; x++) + for (s16 z = 0; z < data->mode.map_size; z++) { + MinimapPixel *mmpixel = &data->minimap_scan[x + z * data->mode.map_size]; + + const ContentFeatures &f = m_ndef->get(mmpixel->n); + const TileDef *tile = &f.tiledef[0]; + + // Color of the 0th tile (mostly this is the topmost) + if(tile->has_color) + tilecolor = tile->color; + else + mmpixel->n.getColor(f, &tilecolor); + + tilecolor.setRed(tilecolor.getRed() * f.minimap_color.getRed() / 255); + tilecolor.setGreen(tilecolor.getGreen() * f.minimap_color.getGreen() / 255); + tilecolor.setBlue(tilecolor.getBlue() * f.minimap_color.getBlue() / 255); + tilecolor.setAlpha(240); + + map_image->setPixel(x, data->mode.map_size - z - 1, tilecolor); + + u32 h = mmpixel->height; + heightmap_image->setPixel(x,data->mode.map_size - z - 1, + video::SColor(255, h, h, h)); + } +} + +video::ITexture *Minimap::getMinimapTexture() +{ + // update minimap textures when new scan is ready + if (data->map_invalidated && data->mode.type != MINIMAP_TYPE_TEXTURE) + return data->texture; + + // create minimap and heightmap images in memory + core::dimension2d<u32> dim(data->mode.map_size, data->mode.map_size); + video::IImage *map_image = driver->createImage(video::ECF_A8R8G8B8, dim); + video::IImage *heightmap_image = driver->createImage(video::ECF_A8R8G8B8, dim); + video::IImage *minimap_image = driver->createImage(video::ECF_A8R8G8B8, + core::dimension2d<u32>(MINIMAP_MAX_SX, MINIMAP_MAX_SY)); + + // Blit MinimapPixels to images + switch(data->mode.type) { + case MINIMAP_TYPE_OFF: + break; + case MINIMAP_TYPE_SURFACE: + blitMinimapPixelsToImageSurface(map_image, heightmap_image); + break; + case MINIMAP_TYPE_RADAR: + blitMinimapPixelsToImageRadar(map_image); + break; + case MINIMAP_TYPE_TEXTURE: + // Want to use texture source, to : 1 find texture, 2 cache it + video::ITexture* texture = m_tsrc->getTexture(data->mode.texture); + video::IImage* image = driver->createImageFromData( + texture->getColorFormat(), texture->getSize(), + texture->lock(video::ETLM_READ_ONLY), true, false); + texture->unlock(); + + auto dim = image->getDimension(); + + map_image->fill(video::SColor(255, 0, 0, 0)); + + image->copyTo(map_image, + irr::core::vector2d<int> { + ((data->mode.map_size - (static_cast<int>(dim.Width))) >> 1) + - data->pos.X / data->mode.scale, + ((data->mode.map_size - (static_cast<int>(dim.Height))) >> 1) + + data->pos.Z / data->mode.scale + }); + image->drop(); + } + + map_image->copyToScaling(minimap_image); + map_image->drop(); + + video::IImage *minimap_mask = data->minimap_shape_round ? + data->minimap_mask_round : data->minimap_mask_square; + + if (minimap_mask) { + for (s16 y = 0; y < MINIMAP_MAX_SY; y++) + for (s16 x = 0; x < MINIMAP_MAX_SX; x++) { + const video::SColor &mask_col = minimap_mask->getPixel(x, y); + if (!mask_col.getAlpha()) + minimap_image->setPixel(x, y, video::SColor(0,0,0,0)); + } + } + + if (data->texture) + driver->removeTexture(data->texture); + if (data->heightmap_texture) + driver->removeTexture(data->heightmap_texture); + + data->texture = driver->addTexture("minimap__", minimap_image); + data->heightmap_texture = + driver->addTexture("minimap_heightmap__", heightmap_image); + minimap_image->drop(); + heightmap_image->drop(); + + data->map_invalidated = true; + + return data->texture; +} + +v3f Minimap::getYawVec() +{ + if (data->minimap_shape_round) { + return v3f( + std::cos(m_angle * core::DEGTORAD), + std::sin(m_angle * core::DEGTORAD), + 1.0); + } + + return v3f(1.0, 0.0, 1.0); +} + +scene::SMeshBuffer *Minimap::getMinimapMeshBuffer() +{ + scene::SMeshBuffer *buf = new scene::SMeshBuffer(); + buf->Vertices.set_used(4); + buf->Indices.set_used(6); + static const video::SColor c(255, 255, 255, 255); + + buf->Vertices[0] = video::S3DVertex(-1, -1, 0, 0, 0, 1, c, 0, 1); + buf->Vertices[1] = video::S3DVertex(-1, 1, 0, 0, 0, 1, c, 0, 0); + buf->Vertices[2] = video::S3DVertex( 1, 1, 0, 0, 0, 1, c, 1, 0); + buf->Vertices[3] = video::S3DVertex( 1, -1, 0, 0, 0, 1, c, 1, 1); + + buf->Indices[0] = 0; + buf->Indices[1] = 1; + buf->Indices[2] = 2; + buf->Indices[3] = 2; + buf->Indices[4] = 3; + buf->Indices[5] = 0; + + return buf; +} + +void Minimap::drawMinimap() +{ + // Non hud managed minimap drawing (legacy minimap) + v2u32 screensize = RenderingEngine::getWindowSize(); + const u32 size = 0.25 * screensize.Y; + + drawMinimap(core::rect<s32>( + screensize.X - size - 10, 10, + screensize.X - 10, size + 10)); +} + +void Minimap::drawMinimap(core::rect<s32> rect) { + + video::ITexture *minimap_texture = getMinimapTexture(); + if (!minimap_texture) + return; + + if (data->mode.type == MINIMAP_TYPE_OFF) + return; + + updateActiveMarkers(); + + core::rect<s32> oldViewPort = driver->getViewPort(); + core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION); + core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW); + + driver->setViewPort(rect); + driver->setTransform(video::ETS_PROJECTION, core::matrix4()); + driver->setTransform(video::ETS_VIEW, core::matrix4()); + + core::matrix4 matrix; + matrix.makeIdentity(); + + video::SMaterial &material = m_meshbuffer->getMaterial(); + material.setFlag(video::EMF_TRILINEAR_FILTER, true); + material.Lighting = false; + material.TextureLayer[0].Texture = minimap_texture; + material.TextureLayer[1].Texture = data->heightmap_texture; + + if (m_enable_shaders && data->mode.type == MINIMAP_TYPE_SURFACE) { + u16 sid = m_shdrsrc->getShader("minimap_shader", TILE_MATERIAL_ALPHA); + material.MaterialType = m_shdrsrc->getShaderInfo(sid).material; + } else { + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + } + + if (data->minimap_shape_round) + matrix.setRotationDegrees(core::vector3df(0, 0, 360 - m_angle)); + + // Draw minimap + driver->setTransform(video::ETS_WORLD, matrix); + driver->setMaterial(material); + driver->drawMeshBuffer(m_meshbuffer); + + // Draw overlay + video::ITexture *minimap_overlay = data->minimap_shape_round ? + data->minimap_overlay_round : data->minimap_overlay_square; + material.TextureLayer[0].Texture = minimap_overlay; + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + driver->setMaterial(material); + driver->drawMeshBuffer(m_meshbuffer); + + // Draw player marker on minimap + if (data->minimap_shape_round) { + matrix.setRotationDegrees(core::vector3df(0, 0, 0)); + } else { + matrix.setRotationDegrees(core::vector3df(0, 0, m_angle)); + } + + material.TextureLayer[0].Texture = data->player_marker; + driver->setTransform(video::ETS_WORLD, matrix); + driver->setMaterial(material); + driver->drawMeshBuffer(m_meshbuffer); + + // Reset transformations + driver->setTransform(video::ETS_VIEW, oldViewMat); + driver->setTransform(video::ETS_PROJECTION, oldProjMat); + driver->setViewPort(oldViewPort); + + // Draw player markers + v2s32 s_pos(rect.UpperLeftCorner.X, rect.UpperLeftCorner.Y); + core::dimension2di imgsize(data->object_marker_red->getOriginalSize()); + core::rect<s32> img_rect(0, 0, imgsize.Width, imgsize.Height); + static const video::SColor col(255, 255, 255, 255); + static const video::SColor c[4] = {col, col, col, col}; + f32 sin_angle = std::sin(m_angle * core::DEGTORAD); + f32 cos_angle = std::cos(m_angle * core::DEGTORAD); + s32 marker_size2 = 0.025 * (float)rect.getWidth();; + for (std::list<v2f>::const_iterator + i = m_active_markers.begin(); + i != m_active_markers.end(); ++i) { + v2f posf = *i; + if (data->minimap_shape_round) { + f32 t1 = posf.X * cos_angle - posf.Y * sin_angle; + f32 t2 = posf.X * sin_angle + posf.Y * cos_angle; + posf.X = t1; + posf.Y = t2; + } + posf.X = (posf.X + 0.5) * (float)rect.getWidth(); + posf.Y = (posf.Y + 0.5) * (float)rect.getHeight(); + core::rect<s32> dest_rect( + s_pos.X + posf.X - marker_size2, + s_pos.Y + posf.Y - marker_size2, + s_pos.X + posf.X + marker_size2, + s_pos.Y + posf.Y + marker_size2); + driver->draw2DImage(data->object_marker_red, dest_rect, + img_rect, &dest_rect, &c[0], true); + } +} + +MinimapMarker* Minimap::addMarker(scene::ISceneNode *parent_node) +{ + MinimapMarker *m = new MinimapMarker(parent_node); + m_markers.push_back(m); + return m; +} + +void Minimap::removeMarker(MinimapMarker **m) +{ + m_markers.remove(*m); + delete *m; + *m = nullptr; +} + +void Minimap::updateActiveMarkers() +{ + video::IImage *minimap_mask = data->minimap_shape_round ? + data->minimap_mask_round : data->minimap_mask_square; + + m_active_markers.clear(); + v3f cam_offset = intToFloat(client->getCamera()->getOffset(), BS); + v3s16 pos_offset = data->pos - v3s16(data->mode.map_size / 2, + data->mode.scan_height / 2, + data->mode.map_size / 2); + + for (MinimapMarker *marker : m_markers) { + v3s16 pos = floatToInt(marker->parent_node->getAbsolutePosition() + + cam_offset, BS) - pos_offset; + if (pos.X < 0 || pos.X > data->mode.map_size || + pos.Y < 0 || pos.Y > data->mode.scan_height || + pos.Z < 0 || pos.Z > data->mode.map_size) { + continue; + } + pos.X = ((float)pos.X / data->mode.map_size) * MINIMAP_MAX_SX; + pos.Z = ((float)pos.Z / data->mode.map_size) * MINIMAP_MAX_SY; + const video::SColor &mask_col = minimap_mask->getPixel(pos.X, pos.Z); + if (!mask_col.getAlpha()) { + continue; + } + + m_active_markers.emplace_back(((float)pos.X / (float)MINIMAP_MAX_SX) - 0.5, + (1.0 - (float)pos.Z / (float)MINIMAP_MAX_SY) - 0.5); + } +} + +//// +//// MinimapMapblock +//// + +void MinimapMapblock::getMinimapNodes(VoxelManipulator *vmanip, const v3s16 &pos) +{ + + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) + for (s16 z = 0; z < MAP_BLOCKSIZE; z++) { + s16 air_count = 0; + bool surface_found = false; + MinimapPixel *mmpixel = &data[z * MAP_BLOCKSIZE + x]; + + for (s16 y = MAP_BLOCKSIZE -1; y >= 0; y--) { + v3s16 p(x, y, z); + MapNode n = vmanip->getNodeNoEx(pos + p); + if (!surface_found && n.getContent() != CONTENT_AIR) { + mmpixel->height = y; + mmpixel->n = n; + surface_found = true; + } else if (n.getContent() == CONTENT_AIR) { + air_count++; + } + } + + if (!surface_found) + mmpixel->n = MapNode(CONTENT_AIR); + + mmpixel->air_count = air_count; + } +} diff --git a/src/client/minimap.h b/src/client/minimap.h new file mode 100644 index 0000000..87c9668 --- /dev/null +++ b/src/client/minimap.h @@ -0,0 +1,176 @@ +/* +Minetest +Copyright (C) 2010-2015 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "../hud.h" +#include "irrlichttypes_extrabloated.h" +#include "util/thread.h" +#include "voxel.h" +#include <map> +#include <string> +#include <vector> + +class Client; +class ITextureSource; +class IShaderSource; + +#define MINIMAP_MAX_SX 512 +#define MINIMAP_MAX_SY 512 + +enum MinimapShape { + MINIMAP_SHAPE_SQUARE, + MINIMAP_SHAPE_ROUND, +}; + +struct MinimapModeDef { + MinimapType type; + std::string label; + u16 scan_height; + u16 map_size; + std::string texture; + u16 scale; +}; + +struct MinimapMarker { + MinimapMarker(scene::ISceneNode *parent_node): + parent_node(parent_node) + { + } + scene::ISceneNode *parent_node; +}; +struct MinimapPixel { + //! The topmost node that the minimap displays. + MapNode n; + u16 height; + u16 air_count; +}; + +struct MinimapMapblock { + void getMinimapNodes(VoxelManipulator *vmanip, const v3s16 &pos); + + MinimapPixel data[MAP_BLOCKSIZE * MAP_BLOCKSIZE]; +}; + +struct MinimapData { + MinimapModeDef mode; + v3s16 pos; + v3s16 old_pos; + MinimapPixel minimap_scan[MINIMAP_MAX_SX * MINIMAP_MAX_SY]; + bool map_invalidated; + bool minimap_shape_round; + video::IImage *minimap_mask_round = nullptr; + video::IImage *minimap_mask_square = nullptr; + video::ITexture *texture = nullptr; + video::ITexture *heightmap_texture = nullptr; + video::ITexture *minimap_overlay_round = nullptr; + video::ITexture *minimap_overlay_square = nullptr; + video::ITexture *player_marker = nullptr; + video::ITexture *object_marker_red = nullptr; +}; + +struct QueuedMinimapUpdate { + v3s16 pos; + MinimapMapblock *data = nullptr; +}; + +class MinimapUpdateThread : public UpdateThread { +public: + MinimapUpdateThread() : UpdateThread("Minimap") {} + virtual ~MinimapUpdateThread(); + + void getMap(v3s16 pos, s16 size, s16 height); + void enqueueBlock(v3s16 pos, MinimapMapblock *data); + bool pushBlockUpdate(v3s16 pos, MinimapMapblock *data); + bool popBlockUpdate(QueuedMinimapUpdate *update); + + MinimapData *data = nullptr; + +protected: + virtual void doUpdate(); + +private: + std::mutex m_queue_mutex; + std::deque<QueuedMinimapUpdate> m_update_queue; + std::map<v3s16, MinimapMapblock *> m_blocks_cache; +}; + +class Minimap { +public: + Minimap(Client *client); + ~Minimap(); + + void addBlock(v3s16 pos, MinimapMapblock *data); + + v3f getYawVec(); + + void setPos(v3s16 pos); + v3s16 getPos() const { return data->pos; } + void setAngle(f32 angle); + f32 getAngle() const { return m_angle; } + void toggleMinimapShape(); + void setMinimapShape(MinimapShape shape); + MinimapShape getMinimapShape(); + + void clearModes() { m_modes.clear(); }; + void addMode(MinimapModeDef mode); + void addMode(MinimapType type, u16 size = 0, std::string label = "", + std::string texture = "", u16 scale = 1); + + void setModeIndex(size_t index); + size_t getModeIndex() const { return m_current_mode_index; }; + size_t getMaxModeIndex() const { return m_modes.size() - 1; }; + void nextMode(); + + MinimapModeDef getModeDef() const { return data->mode; } + + video::ITexture *getMinimapTexture(); + + void blitMinimapPixelsToImageRadar(video::IImage *map_image); + void blitMinimapPixelsToImageSurface(video::IImage *map_image, + video::IImage *heightmap_image); + + scene::SMeshBuffer *getMinimapMeshBuffer(); + + MinimapMarker* addMarker(scene::ISceneNode *parent_node); + void removeMarker(MinimapMarker **marker); + + void updateActiveMarkers(); + void drawMinimap(); + void drawMinimap(core::rect<s32> rect); + + video::IVideoDriver *driver; + Client* client; + MinimapData *data; + +private: + ITextureSource *m_tsrc; + IShaderSource *m_shdrsrc; + const NodeDefManager *m_ndef; + MinimapUpdateThread *m_minimap_update_thread = nullptr; + scene::SMeshBuffer *m_meshbuffer; + bool m_enable_shaders; + std::vector<MinimapModeDef> m_modes; + size_t m_current_mode_index; + u16 m_surface_mode_scan_height; + f32 m_angle; + std::mutex m_mutex; + std::list<MinimapMarker*> m_markers; + std::list<v2f> m_active_markers; +}; diff --git a/src/client/particles.cpp b/src/client/particles.cpp new file mode 100644 index 0000000..248f461 --- /dev/null +++ b/src/client/particles.cpp @@ -0,0 +1,927 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "particles.h" +#include <cmath> +#include "client.h" +#include "collision.h" +#include "client/content_cao.h" +#include "client/clientevent.h" +#include "client/renderingengine.h" +#include "util/numeric.h" +#include "light.h" +#include "environment.h" +#include "clientmap.h" +#include "mapnode.h" +#include "nodedef.h" +#include "client.h" +#include "settings.h" + +/* + Particle +*/ + +Particle::Particle( + IGameDef *gamedef, + LocalPlayer *player, + ClientEnvironment *env, + const ParticleParameters &p, + const ClientTexRef& texture, + v2f texpos, + v2f texsize, + video::SColor color +): + scene::ISceneNode(((Client *)gamedef)->getSceneManager()->getRootSceneNode(), + ((Client *)gamedef)->getSceneManager()), + m_texture(texture) +{ + // Misc + m_gamedef = gamedef; + m_env = env; + + // translate blend modes to GL blend functions + video::E_BLEND_FACTOR bfsrc, bfdst; + video::E_BLEND_OPERATION blendop; + const auto blendmode = texture.tex != nullptr + ? texture.tex -> blendmode + : ParticleParamTypes::BlendMode::alpha; + + switch (blendmode) { + case ParticleParamTypes::BlendMode::add: + bfsrc = video::EBF_SRC_ALPHA; + bfdst = video::EBF_DST_ALPHA; + blendop = video::EBO_ADD; + break; + + case ParticleParamTypes::BlendMode::sub: + bfsrc = video::EBF_SRC_ALPHA; + bfdst = video::EBF_DST_ALPHA; + blendop = video::EBO_REVSUBTRACT; + break; + + case ParticleParamTypes::BlendMode::screen: + bfsrc = video::EBF_ONE; + bfdst = video::EBF_ONE_MINUS_SRC_COLOR; + blendop = video::EBO_ADD; + break; + + default: // includes ParticleParamTypes::BlendMode::alpha + bfsrc = video::EBF_SRC_ALPHA; + bfdst = video::EBF_ONE_MINUS_SRC_ALPHA; + blendop = video::EBO_ADD; + break; + } + + // Texture + m_material.setFlag(video::EMF_LIGHTING, false); + m_material.setFlag(video::EMF_BACK_FACE_CULLING, false); + m_material.setFlag(video::EMF_BILINEAR_FILTER, false); + m_material.setFlag(video::EMF_FOG_ENABLE, true); + + // correctly render layered transparent particles -- see #10398 + m_material.setFlag(video::EMF_ZWRITE_ENABLE, true); + + // enable alpha blending and set blend mode + m_material.MaterialType = video::EMT_ONETEXTURE_BLEND; + m_material.MaterialTypeParam = video::pack_textureBlendFunc( + bfsrc, bfdst, + video::EMFN_MODULATE_1X, + video::EAS_TEXTURE | video::EAS_VERTEX_COLOR); + m_material.BlendOperation = blendop; + m_material.setTexture(0, m_texture.ref); + m_texpos = texpos; + m_texsize = texsize; + m_animation = p.animation; + + // Color + m_base_color = color; + m_color = color; + + // Particle related + m_pos = p.pos; + m_velocity = p.vel; + m_acceleration = p.acc; + m_drag = p.drag; + m_jitter = p.jitter; + m_bounce = p.bounce; + m_expiration = p.expirationtime; + m_player = player; + m_size = p.size; + m_collisiondetection = p.collisiondetection; + m_collision_removal = p.collision_removal; + m_object_collision = p.object_collision; + m_vertical = p.vertical; + m_glow = p.glow; + m_alpha = 0; + m_parent = nullptr; + + // Irrlicht stuff + const float c = p.size / 2; + m_collisionbox = aabb3f(-c, -c, -c, c, c, c); + this->setAutomaticCulling(scene::EAC_OFF); + + // Init lighting + updateLight(); + + // Init model + updateVertices(); +} + +Particle::~Particle() +{ + /* if our textures aren't owned by a particlespawner, we need to clean + * them up ourselves when the particle dies */ + if (m_parent == nullptr) + delete m_texture.tex; +} + +void Particle::OnRegisterSceneNode() +{ + if (IsVisible) + SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT_EFFECT); + + ISceneNode::OnRegisterSceneNode(); +} + +void Particle::render() +{ + video::IVideoDriver *driver = SceneManager->getVideoDriver(); + driver->setMaterial(m_material); + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + + u16 indices[] = {0,1,2, 2,3,0}; + driver->drawVertexPrimitiveList(m_vertices, 4, + indices, 2, video::EVT_STANDARD, + scene::EPT_TRIANGLES, video::EIT_16BIT); +} + +void Particle::step(float dtime) +{ + m_time += dtime; + + // apply drag (not handled by collisionMoveSimple) and brownian motion + v3f av = vecAbsolute(m_velocity); + av -= av * (m_drag * dtime); + m_velocity = av*vecSign(m_velocity) + v3f(m_jitter.pickWithin())*dtime; + + if (m_collisiondetection) { + aabb3f box = m_collisionbox; + v3f p_pos = m_pos * BS; + v3f p_velocity = m_velocity * BS; + collisionMoveResult r = collisionMoveSimple(m_env, m_gamedef, BS * 0.5f, + box, 0.0f, dtime, &p_pos, &p_velocity, m_acceleration * BS, nullptr, + m_object_collision); + + f32 bounciness = m_bounce.pickWithin(); + if (r.collides && (m_collision_removal || bounciness > 0)) { + if (m_collision_removal) { + // force expiration of the particle + m_expiration = -1.0f; + } else if (bounciness > 0) { + /* cheap way to get a decent bounce effect is to only invert the + * largest component of the velocity vector, so e.g. you don't + * have a rock immediately bounce back in your face when you try + * to skip it across the water (as would happen if we simply + * downscaled and negated the velocity vector). this means + * bounciness will work properly for cubic objects, but meshes + * with diagonal angles and entities will not yield the correct + * visual. this is probably unavoidable */ + if (av.Y > av.X && av.Y > av.Z) { + m_velocity.Y = -(m_velocity.Y * bounciness); + } else if (av.X > av.Y && av.X > av.Z) { + m_velocity.X = -(m_velocity.X * bounciness); + } else if (av.Z > av.Y && av.Z > av.X) { + m_velocity.Z = -(m_velocity.Z * bounciness); + } else { // well now we're in a bit of a pickle + m_velocity = -(m_velocity * bounciness); + } + } + } else { + m_velocity = p_velocity / BS; + } + m_pos = p_pos / BS; + } else { + // apply acceleration + m_velocity += m_acceleration * dtime; + m_pos += m_velocity * dtime; + } + + if (m_animation.type != TAT_NONE) { + m_animation_time += dtime; + int frame_length_i, frame_count; + m_animation.determineParams( + m_material.getTexture(0)->getSize(), + &frame_count, &frame_length_i, NULL); + float frame_length = frame_length_i / 1000.0; + while (m_animation_time > frame_length) { + m_animation_frame++; + m_animation_time -= frame_length; + } + } + + // animate particle alpha in accordance with settings + if (m_texture.tex != nullptr) + m_alpha = m_texture.tex -> alpha.blend(m_time / (m_expiration+0.1f)); + else + m_alpha = 1.f; + + // Update lighting + updateLight(); + + // Update model + updateVertices(); + + // Update position -- see #10398 + v3s16 camera_offset = m_env->getCameraOffset(); + setPosition(m_pos*BS - intToFloat(camera_offset, BS)); +} + +void Particle::updateLight() +{ + u8 light = 0; + bool pos_ok; + + v3s16 p = v3s16( + floor(m_pos.X+0.5), + floor(m_pos.Y+0.5), + floor(m_pos.Z+0.5) + ); + MapNode n = m_env->getClientMap().getNode(p, &pos_ok); + if (pos_ok) + light = n.getLightBlend(m_env->getDayNightRatio(), m_gamedef->ndef()); + else + light = blend_light(m_env->getDayNightRatio(), LIGHT_SUN, 0); + + u8 m_light = decode_light(light + m_glow); + m_color.set(m_alpha*255, + m_light * m_base_color.getRed() / 255, + m_light * m_base_color.getGreen() / 255, + m_light * m_base_color.getBlue() / 255); +} + +void Particle::updateVertices() +{ + f32 tx0, tx1, ty0, ty1; + v2f scale; + + if (m_texture.tex != nullptr) + scale = m_texture.tex -> scale.blend(m_time / (m_expiration+0.1)); + else + scale = v2f(1.f, 1.f); + + if (m_animation.type != TAT_NONE) { + const v2u32 texsize = m_material.getTexture(0)->getSize(); + v2f texcoord, framesize_f; + v2u32 framesize; + texcoord = m_animation.getTextureCoords(texsize, m_animation_frame); + m_animation.determineParams(texsize, NULL, NULL, &framesize); + framesize_f = v2f(framesize.X / (float) texsize.X, framesize.Y / (float) texsize.Y); + + tx0 = m_texpos.X + texcoord.X; + tx1 = m_texpos.X + texcoord.X + framesize_f.X * m_texsize.X; + ty0 = m_texpos.Y + texcoord.Y; + ty1 = m_texpos.Y + texcoord.Y + framesize_f.Y * m_texsize.Y; + } else { + tx0 = m_texpos.X; + tx1 = m_texpos.X + m_texsize.X; + ty0 = m_texpos.Y; + ty1 = m_texpos.Y + m_texsize.Y; + } + + auto half = m_size * .5f, + hx = half * scale.X, + hy = half * scale.Y; + m_vertices[0] = video::S3DVertex(-hx, -hy, + 0, 0, 0, 0, m_color, tx0, ty1); + m_vertices[1] = video::S3DVertex(hx, -hy, + 0, 0, 0, 0, m_color, tx1, ty1); + m_vertices[2] = video::S3DVertex(hx, hy, + 0, 0, 0, 0, m_color, tx1, ty0); + m_vertices[3] = video::S3DVertex(-hx, hy, + 0, 0, 0, 0, m_color, tx0, ty0); + + + // see #10398 + // v3s16 camera_offset = m_env->getCameraOffset(); + // particle position is now handled by step() + m_box.reset(v3f()); + + for (video::S3DVertex &vertex : m_vertices) { + if (m_vertical) { + v3f ppos = m_player->getPosition()/BS; + vertex.Pos.rotateXZBy(std::atan2(ppos.Z - m_pos.Z, ppos.X - m_pos.X) / + core::DEGTORAD + 90); + } else { + vertex.Pos.rotateYZBy(m_player->getPitch()); + vertex.Pos.rotateXZBy(m_player->getYaw()); + } + m_box.addInternalPoint(vertex.Pos); + } +} + +/* + ParticleSpawner +*/ + +ParticleSpawner::ParticleSpawner( + IGameDef *gamedef, + LocalPlayer *player, + const ParticleSpawnerParameters &p, + u16 attached_id, + std::unique_ptr<ClientTexture[]>& texpool, + size_t texcount, + ParticleManager *p_manager +): + m_particlemanager(p_manager), p(p) +{ + m_gamedef = gamedef; + m_player = player; + m_attached_id = attached_id; + m_texpool = std::move(texpool); + m_texcount = texcount; + m_time = 0; + m_active = 0; + m_dying = false; + + m_spawntimes.reserve(p.amount + 1); + for (u16 i = 0; i <= p.amount; i++) { + float spawntime = myrand_float() * p.time; + m_spawntimes.push_back(spawntime); + } + + size_t max_particles = 0; // maximum number of particles likely to be visible at any given time + if (p.time != 0) { + auto maxGenerations = p.time / std::min(p.exptime.start.min, p.exptime.end.min); + max_particles = p.amount / maxGenerations; + } else { + auto longestLife = std::max(p.exptime.start.max, p.exptime.end.max); + max_particles = p.amount * longestLife; + } + + p_manager->reserveParticleSpace(max_particles * 1.2); +} + +namespace { + GenericCAO *findObjectByID(ClientEnvironment *env, u16 id) { + if (id == 0) + return nullptr; + return env->getGenericCAO(id); + } +} + +void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius, + const core::matrix4 *attached_absolute_pos_rot_matrix) +{ + float fac = 0; + if (p.time != 0) { // ensure safety from divide-by-zeroes + fac = m_time / (p.time+0.1f); + } + + auto r_pos = p.pos.blend(fac); + auto r_vel = p.vel.blend(fac); + auto r_acc = p.acc.blend(fac); + auto r_drag = p.drag.blend(fac); + auto r_radius = p.radius.blend(fac); + auto r_jitter = p.jitter.blend(fac); + auto r_bounce = p.bounce.blend(fac); + v3f attractor_origin = p.attractor_origin.blend(fac); + v3f attractor_direction = p.attractor_direction.blend(fac); + auto attractor_obj = findObjectByID(env, p.attractor_attachment); + auto attractor_direction_obj = findObjectByID(env, p.attractor_direction_attachment); + + auto r_exp = p.exptime.blend(fac); + auto r_size = p.size.blend(fac); + auto r_attract = p.attract.blend(fac); + auto attract = r_attract.pickWithin(); + + v3f ppos = m_player->getPosition() / BS; + v3f pos = r_pos.pickWithin(); + v3f sphere_radius = r_radius.pickWithin(); + + // Need to apply this first or the following check + // will be wrong for attached spawners + if (attached_absolute_pos_rot_matrix) { + pos *= BS; + attached_absolute_pos_rot_matrix->transformVect(pos); + pos /= BS; + v3s16 camera_offset = m_particlemanager->m_env->getCameraOffset(); + pos.X += camera_offset.X; + pos.Y += camera_offset.Y; + pos.Z += camera_offset.Z; + } + + if (pos.getDistanceFromSQ(ppos) > radius*radius) + return; + + // Parameters for the single particle we're about to spawn + ParticleParameters pp; + pp.pos = pos; + + pp.vel = r_vel.pickWithin(); + pp.acc = r_acc.pickWithin(); + pp.drag = r_drag.pickWithin(); + pp.jitter = r_jitter; + pp.bounce = r_bounce; + + if (attached_absolute_pos_rot_matrix) { + // Apply attachment rotation + attached_absolute_pos_rot_matrix->rotateVect(pp.vel); + attached_absolute_pos_rot_matrix->rotateVect(pp.acc); + } + + if (attractor_obj) + attractor_origin += attractor_obj->getPosition() / BS; + if (attractor_direction_obj) { + auto *attractor_absolute_pos_rot_matrix = attractor_direction_obj->getAbsolutePosRotMatrix(); + if (attractor_absolute_pos_rot_matrix) + attractor_absolute_pos_rot_matrix->rotateVect(attractor_direction); + } + + pp.expirationtime = r_exp.pickWithin(); + + if (sphere_radius != v3f()) { + f32 l = sphere_radius.getLength(); + v3f mag = sphere_radius; + mag.normalize(); + + v3f ofs = v3f(l,0,0); + ofs.rotateXZBy(myrand_range(0.f,360.f)); + ofs.rotateYZBy(myrand_range(0.f,360.f)); + ofs.rotateXYBy(myrand_range(0.f,360.f)); + + pp.pos += ofs * mag; + } + + if (p.attractor_kind != ParticleParamTypes::AttractorKind::none && attract != 0) { + v3f dir; + f32 dist = 0; /* =0 necessary to silence warning */ + switch (p.attractor_kind) { + case ParticleParamTypes::AttractorKind::none: + break; + + case ParticleParamTypes::AttractorKind::point: { + dist = pp.pos.getDistanceFrom(attractor_origin); + dir = pp.pos - attractor_origin; + dir.normalize(); + break; + } + + case ParticleParamTypes::AttractorKind::line: { + // https://github.com/minetest/minetest/issues/11505#issuecomment-915612700 + const auto& lorigin = attractor_origin; + v3f ldir = attractor_direction; + ldir.normalize(); + auto origin_to_point = pp.pos - lorigin; + auto scalar_projection = origin_to_point.dotProduct(ldir); + auto point_on_line = lorigin + (ldir * scalar_projection); + + dist = pp.pos.getDistanceFrom(point_on_line); + dir = (point_on_line - pp.pos); + dir.normalize(); + dir *= -1; // flip it around so strength=1 attracts, not repulses + break; + } + + case ParticleParamTypes::AttractorKind::plane: { + // https://github.com/minetest/minetest/issues/11505#issuecomment-915612700 + const v3f& porigin = attractor_origin; + v3f normal = attractor_direction; + normal.normalize(); + v3f point_to_origin = porigin - pp.pos; + f32 factor = normal.dotProduct(point_to_origin); + if (numericAbsolute(factor) == 0.0f) { + dir = normal; + } else { + factor = numericSign(factor); + dir = normal * factor; + } + dist = numericAbsolute(normal.dotProduct(pp.pos - porigin)); + dir *= -1; // flip it around so strength=1 attracts, not repulses + break; + } + } + + f32 speedTowards = numericAbsolute(attract) * dist; + v3f avel = dir * speedTowards; + if (attract > 0 && speedTowards > 0) { + avel *= -1; + if (p.attractor_kill) { + // make sure the particle dies after crossing the attractor threshold + f32 timeToCenter = dist / speedTowards; + if (timeToCenter < pp.expirationtime) + pp.expirationtime = timeToCenter; + } + } + pp.vel += avel; + } + + p.copyCommon(pp); + + ClientTexRef texture; + v2f texpos, texsize; + video::SColor color(0xFFFFFFFF); + + if (p.node.getContent() != CONTENT_IGNORE) { + const ContentFeatures &f = + m_particlemanager->m_env->getGameDef()->ndef()->get(p.node); + if (!ParticleManager::getNodeParticleParams(p.node, f, pp, &texture.ref, + texpos, texsize, &color, p.node_tile)) + return; + } else { + if (m_texcount == 0) + return; + texture = decltype(texture)(m_texpool[m_texcount == 1 ? 0 : myrand_range(0,m_texcount-1)]); + texpos = v2f(0.0f, 0.0f); + texsize = v2f(1.0f, 1.0f); + if (texture.tex->animated) + pp.animation = texture.tex->animation; + } + + // synchronize animation length with particle life if desired + if (pp.animation.type != TAT_NONE) { + // FIXME: this should be moved into a TileAnimationParams class method + if (pp.animation.type == TAT_VERTICAL_FRAMES && + pp.animation.vertical_frames.length < 0) { + auto& a = pp.animation.vertical_frames; + // we add a tiny extra value to prevent the first frame + // from flickering back on just before the particle dies + a.length = (pp.expirationtime / -a.length) + 0.1; + } else if (pp.animation.type == TAT_SHEET_2D && + pp.animation.sheet_2d.frame_length < 0) { + auto& a = pp.animation.sheet_2d; + auto frames = a.frames_w * a.frames_h; + auto runtime = (pp.expirationtime / -a.frame_length) + 0.1; + pp.animation.sheet_2d.frame_length = frames / runtime; + } + } + + // Allow keeping default random size + if (p.size.start.max > 0.0f || p.size.end.max > 0.0f) + pp.size = r_size.pickWithin(); + + ++m_active; + auto pa = new Particle( + m_gamedef, + m_player, + env, + pp, + texture, + texpos, + texsize, + color + ); + pa->m_parent = this; + m_particlemanager->addParticle(pa); +} + +void ParticleSpawner::step(float dtime, ClientEnvironment *env) +{ + m_time += dtime; + + static thread_local const float radius = + g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE; + + bool unloaded = false; + const core::matrix4 *attached_absolute_pos_rot_matrix = nullptr; + if (m_attached_id) { + if (GenericCAO *attached = env->getGenericCAO(m_attached_id)) { + attached_absolute_pos_rot_matrix = attached->getAbsolutePosRotMatrix(); + } else { + unloaded = true; + } + } + + if (p.time != 0) { + // Spawner exists for a predefined timespan + for (auto i = m_spawntimes.begin(); i != m_spawntimes.end(); ) { + if ((*i) <= m_time && p.amount > 0) { + --p.amount; + + // Pretend to, but don't actually spawn a particle if it is + // attached to an unloaded object or distant from player. + if (!unloaded) + spawnParticle(env, radius, attached_absolute_pos_rot_matrix); + + i = m_spawntimes.erase(i); + } else { + ++i; + } + } + } else { + // Spawner exists for an infinity timespan, spawn on a per-second base + + // Skip this step if attached to an unloaded object + if (unloaded) + return; + + for (int i = 0; i <= p.amount; i++) { + if (myrand_float() < dtime) + spawnParticle(env, radius, attached_absolute_pos_rot_matrix); + } + } +} + +/* + ParticleManager +*/ + +ParticleManager::ParticleManager(ClientEnvironment *env) : + m_env(env) +{} + +ParticleManager::~ParticleManager() +{ + clearAll(); +} + +void ParticleManager::step(float dtime) +{ + stepParticles (dtime); + stepSpawners (dtime); +} + +void ParticleManager::stepSpawners(float dtime) +{ + MutexAutoLock lock(m_spawner_list_lock); + for (auto i = m_particle_spawners.begin(); i != m_particle_spawners.end();) { + if (i->second->getExpired()) { + // the particlespawner owns the textures, so we need to make + // sure there are no active particles before we free it + if (i->second->m_active == 0) { + delete i->second; + m_particle_spawners.erase(i++); + } else { + ++i; + } + } else { + i->second->step(dtime, m_env); + ++i; + } + } +} + +void ParticleManager::stepParticles(float dtime) +{ + MutexAutoLock lock(m_particle_list_lock); + for (auto i = m_particles.begin(); i != m_particles.end();) { + if ((*i)->get_expired()) { + if ((*i)->m_parent) { + assert((*i)->m_parent->m_active != 0); + --(*i)->m_parent->m_active; + } + (*i)->remove(); + delete *i; + i = m_particles.erase(i); + } else { + (*i)->step(dtime); + ++i; + } + } +} + +void ParticleManager::clearAll() +{ + MutexAutoLock lock(m_spawner_list_lock); + MutexAutoLock lock2(m_particle_list_lock); + for (auto i = m_particle_spawners.begin(); i != m_particle_spawners.end();) { + delete i->second; + m_particle_spawners.erase(i++); + } + + for(auto i = m_particles.begin(); i != m_particles.end();) + { + (*i)->remove(); + delete *i; + i = m_particles.erase(i); + } +} + +void ParticleManager::handleParticleEvent(ClientEvent *event, Client *client, + LocalPlayer *player) +{ + switch (event->type) { + case CE_DELETE_PARTICLESPAWNER: { + deleteParticleSpawner(event->delete_particlespawner.id); + // no allocated memory in delete event + break; + } + case CE_ADD_PARTICLESPAWNER: { + deleteParticleSpawner(event->add_particlespawner.id); + + const ParticleSpawnerParameters &p = *event->add_particlespawner.p; + + // texture pool + std::unique_ptr<ClientTexture[]> texpool = nullptr; + size_t txpsz = 0; + if (!p.texpool.empty()) { + txpsz = p.texpool.size(); + texpool = decltype(texpool)(new ClientTexture [txpsz]); + + for (size_t i = 0; i < txpsz; ++i) { + texpool[i] = ClientTexture(p.texpool[i], client->tsrc()); + } + } else { + // no texpool in use, use fallback texture + txpsz = 1; + texpool = decltype(texpool)(new ClientTexture[1] { + ClientTexture(p.texture, client->tsrc()) + }); + } + + auto toadd = new ParticleSpawner(client, player, + p, + event->add_particlespawner.attached_id, + texpool, + txpsz, + this); + + addParticleSpawner(event->add_particlespawner.id, toadd); + + delete event->add_particlespawner.p; + break; + } + case CE_SPAWN_PARTICLE: { + ParticleParameters &p = *event->spawn_particle; + + ClientTexRef texture; + v2f texpos, texsize; + video::SColor color(0xFFFFFFFF); + + f32 oldsize = p.size; + + if (p.node.getContent() != CONTENT_IGNORE) { + const ContentFeatures &f = m_env->getGameDef()->ndef()->get(p.node); + getNodeParticleParams(p.node, f, p, &texture.ref, texpos, + texsize, &color, p.node_tile); + } else { + /* with no particlespawner to own the texture, we need + * to save it on the heap. it will be freed when the + * particle is destroyed */ + auto texstore = new ClientTexture(p.texture, client->tsrc()); + + texture = ClientTexRef(*texstore); + texpos = v2f(0.0f, 0.0f); + texsize = v2f(1.0f, 1.0f); + } + + // Allow keeping default random size + if (oldsize > 0.0f) + p.size = oldsize; + + if (texture.ref) { + Particle *toadd = new Particle(client, player, m_env, + p, texture, texpos, texsize, color); + + addParticle(toadd); + } + + delete event->spawn_particle; + break; + } + default: break; + } +} + +bool ParticleManager::getNodeParticleParams(const MapNode &n, + const ContentFeatures &f, ParticleParameters &p, video::ITexture **texture, + v2f &texpos, v2f &texsize, video::SColor *color, u8 tilenum) +{ + // No particles for "airlike" nodes + if (f.drawtype == NDT_AIRLIKE) + return false; + + // Texture + u8 texid; + if (tilenum > 0 && tilenum <= 6) + texid = tilenum - 1; + else + texid = myrand_range(0,5); + const TileLayer &tile = f.tiles[texid].layers[0]; + p.animation.type = TAT_NONE; + + // Only use first frame of animated texture + if (tile.material_flags & MATERIAL_FLAG_ANIMATION) + *texture = (*tile.frames)[0].texture; + else + *texture = tile.texture; + + float size = (myrand_range(0,8)) / 64.0f; + p.size = BS * size; + if (tile.scale) + size /= tile.scale; + texsize = v2f(size * 2.0f, size * 2.0f); + texpos.X = (myrand_range(0,64)) / 64.0f - texsize.X; + texpos.Y = (myrand_range(0,64)) / 64.0f - texsize.Y; + + if (tile.has_color) + *color = tile.color; + else + n.getColor(f, color); + + return true; +} + +// The final burst of particles when a node is finally dug, *not* particles +// spawned during the digging of a node. + +void ParticleManager::addDiggingParticles(IGameDef *gamedef, + LocalPlayer *player, v3s16 pos, const MapNode &n, const ContentFeatures &f) +{ + // No particles for "airlike" nodes + if (f.drawtype == NDT_AIRLIKE) + return; + + for (u16 j = 0; j < 16; j++) { + addNodeParticle(gamedef, player, pos, n, f); + } +} + +// During the digging of a node particles are spawned individually by this +// function, called from Game::handleDigging() in game.cpp. + +void ParticleManager::addNodeParticle(IGameDef *gamedef, + LocalPlayer *player, v3s16 pos, const MapNode &n, const ContentFeatures &f) +{ + ParticleParameters p; + video::ITexture *ref = nullptr; + v2f texpos, texsize; + video::SColor color; + + if (!getNodeParticleParams(n, f, p, &ref, texpos, texsize, &color)) + return; + + p.expirationtime = myrand_range(0, 100) / 100.0f; + + // Physics + p.vel = v3f( + myrand_range(-1.5f,1.5f), + myrand_range(0.f,3.f), + myrand_range(-1.5f,1.5f) + ); + p.acc = v3f( + 0.0f, + -player->movement_gravity * player->physics_override_gravity / BS, + 0.0f + ); + p.pos = v3f( + (f32)pos.X + myrand_range(0.f, .5f) - .25f, + (f32)pos.Y + myrand_range(0.f, .5f) - .25f, + (f32)pos.Z + myrand_range(0.f, .5f) - .25f + ); + + Particle *toadd = new Particle( + gamedef, + player, + m_env, + p, + ClientTexRef(ref), + texpos, + texsize, + color); + + addParticle(toadd); +} + +void ParticleManager::reserveParticleSpace(size_t max_estimate) +{ + MutexAutoLock lock(m_particle_list_lock); + m_particles.reserve(m_particles.size() + max_estimate); +} + +void ParticleManager::addParticle(Particle *toadd) +{ + MutexAutoLock lock(m_particle_list_lock); + m_particles.push_back(toadd); +} + + +void ParticleManager::addParticleSpawner(u64 id, ParticleSpawner *toadd) +{ + MutexAutoLock lock(m_spawner_list_lock); + m_particle_spawners[id] = toadd; +} + +void ParticleManager::deleteParticleSpawner(u64 id) +{ + MutexAutoLock lock(m_spawner_list_lock); + auto it = m_particle_spawners.find(id); + if (it != m_particle_spawners.end()) { + it->second->setDying(); + } +} diff --git a/src/client/particles.h b/src/client/particles.h new file mode 100644 index 0000000..0818b79 --- /dev/null +++ b/src/client/particles.h @@ -0,0 +1,242 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <iostream> +#include "irrlichttypes_extrabloated.h" +#include "client/tile.h" +#include "localplayer.h" +#include "../particles.h" + +struct ClientEvent; +class ParticleManager; +class ClientEnvironment; +struct MapNode; +struct ContentFeatures; + +struct ClientTexture +{ + /* per-spawner structure used to store the ParticleTexture structs + * that spawned particles will refer to through ClientTexRef */ + ParticleTexture tex; + video::ITexture *ref = nullptr; + + ClientTexture() = default; + ClientTexture(const ServerParticleTexture& p, ITextureSource *t): + tex(p), + ref(t->getTextureForMesh(p.string)) {}; +}; + +struct ClientTexRef +{ + /* per-particle structure used to avoid massively duplicating the + * fairly large ParticleTexture struct */ + ParticleTexture* tex = nullptr; + video::ITexture* ref = nullptr; + ClientTexRef() = default; + + /* constructor used by particles spawned from a spawner */ + ClientTexRef(ClientTexture& t): + tex(&t.tex), ref(t.ref) {}; + + /* constructor used for node particles */ + ClientTexRef(decltype(ref) tp): ref(tp) {}; +}; + +class ParticleSpawner; + +class Particle : public scene::ISceneNode +{ +public: + Particle( + IGameDef *gamedef, + LocalPlayer *player, + ClientEnvironment *env, + const ParticleParameters &p, + const ClientTexRef &texture, + v2f texpos, + v2f texsize, + video::SColor color + ); + ~Particle(); + + virtual const aabb3f &getBoundingBox() const + { + return m_box; + } + + virtual u32 getMaterialCount() const + { + return 1; + } + + virtual video::SMaterial& getMaterial(u32 i) + { + return m_material; + } + + virtual void OnRegisterSceneNode(); + virtual void render(); + + void step(float dtime); + + bool get_expired () + { return m_expiration < m_time; } + + ParticleSpawner *m_parent; + +private: + void updateLight(); + void updateVertices(); + void setVertexAlpha(float a); + + video::S3DVertex m_vertices[4]; + float m_time = 0.0f; + float m_expiration; + + ClientEnvironment *m_env; + IGameDef *m_gamedef; + aabb3f m_box; + aabb3f m_collisionbox; + ClientTexRef m_texture; + video::SMaterial m_material; + v2f m_texpos; + v2f m_texsize; + v3f m_pos; + v3f m_velocity; + v3f m_acceleration; + v3f m_drag; + ParticleParamTypes::v3fRange m_jitter; + ParticleParamTypes::f32Range m_bounce; + LocalPlayer *m_player; + float m_size; + + //! Color without lighting + video::SColor m_base_color; + //! Final rendered color + video::SColor m_color; + bool m_collisiondetection; + bool m_collision_removal; + bool m_object_collision; + bool m_vertical; + v3s16 m_camera_offset; + struct TileAnimationParams m_animation; + float m_animation_time = 0.0f; + int m_animation_frame = 0; + u8 m_glow; + float m_alpha = 0.0f; +}; + +class ParticleSpawner +{ +public: + ParticleSpawner(IGameDef *gamedef, + LocalPlayer *player, + const ParticleSpawnerParameters &p, + u16 attached_id, + std::unique_ptr<ClientTexture[]> &texpool, + size_t texcount, + ParticleManager* p_manager); + + void step(float dtime, ClientEnvironment *env); + + size_t m_active; + + bool getExpired() const + { return m_dying || (p.amount <= 0 && p.time != 0); } + void setDying() { m_dying = true; } + +private: + void spawnParticle(ClientEnvironment *env, float radius, + const core::matrix4 *attached_absolute_pos_rot_matrix); + + ParticleManager *m_particlemanager; + float m_time; + bool m_dying; + IGameDef *m_gamedef; + LocalPlayer *m_player; + ParticleSpawnerParameters p; + std::unique_ptr<ClientTexture[]> m_texpool; + size_t m_texcount; + std::vector<float> m_spawntimes; + u16 m_attached_id; +}; + +/** + * Class doing particle as well as their spawners handling + */ +class ParticleManager +{ +friend class ParticleSpawner; +public: + ParticleManager(ClientEnvironment* env); + ~ParticleManager(); + + void step (float dtime); + + void handleParticleEvent(ClientEvent *event, Client *client, + LocalPlayer *player); + + void addDiggingParticles(IGameDef *gamedef, LocalPlayer *player, v3s16 pos, + const MapNode &n, const ContentFeatures &f); + + void addNodeParticle(IGameDef *gamedef, LocalPlayer *player, v3s16 pos, + const MapNode &n, const ContentFeatures &f); + + void reserveParticleSpace(size_t max_estimate); + + /** + * This function is only used by client particle spawners + * + * We don't need to check the particle spawner list because client ID will + * never overlap (u64) + * @return new id + */ + u64 generateSpawnerId() + { + return m_next_particle_spawner_id++; + } + +protected: + static bool getNodeParticleParams(const MapNode &n, const ContentFeatures &f, + ParticleParameters &p, video::ITexture **texture, v2f &texpos, + v2f &texsize, video::SColor *color, u8 tilenum = 0); + + void addParticle(Particle* toadd); + +private: + void addParticleSpawner(u64 id, ParticleSpawner *toadd); + void deleteParticleSpawner(u64 id); + + void stepParticles(float dtime); + void stepSpawners(float dtime); + + void clearAll(); + + std::vector<Particle*> m_particles; + std::unordered_map<u64, ParticleSpawner*> m_particle_spawners; + // Start the particle spawner ids generated from here after u32_max. lower values are + // for server sent spawners. + u64 m_next_particle_spawner_id = U32_MAX + 1; + + ClientEnvironment* m_env; + std::mutex m_particle_list_lock; + std::mutex m_spawner_list_lock; +}; diff --git a/src/client/render/anaglyph.cpp b/src/client/render/anaglyph.cpp new file mode 100644 index 0000000..2571f73 --- /dev/null +++ b/src/client/render/anaglyph.cpp @@ -0,0 +1,52 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "anaglyph.h" + +void RenderingCoreAnaglyph::drawAll() +{ + renderBothImages(); + drawPostFx(); + drawHUD(); +} + +void RenderingCoreAnaglyph::setupMaterial(int color_mask) +{ + video::SOverrideMaterial &mat = driver->getOverrideMaterial(); + mat.reset(); + mat.Material.ColorMask = color_mask; + mat.EnableFlags = video::EMF_COLOR_MASK; + mat.EnablePasses = scene::ESNRP_SKY_BOX | scene::ESNRP_SOLID | + scene::ESNRP_TRANSPARENT | scene::ESNRP_TRANSPARENT_EFFECT | + scene::ESNRP_SHADOW; +} + +void RenderingCoreAnaglyph::useEye(bool right) +{ + RenderingCoreStereo::useEye(right); + driver->clearBuffers(video::ECBF_DEPTH); + setupMaterial(right ? video::ECP_GREEN | video::ECP_BLUE : video::ECP_RED); +} + +void RenderingCoreAnaglyph::resetEye() +{ + setupMaterial(video::ECP_ALL); + RenderingCoreStereo::resetEye(); +} diff --git a/src/client/render/anaglyph.h b/src/client/render/anaglyph.h new file mode 100644 index 0000000..a03b7dc --- /dev/null +++ b/src/client/render/anaglyph.h @@ -0,0 +1,34 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "stereo.h" + +class RenderingCoreAnaglyph : public RenderingCoreStereo +{ +protected: + void setupMaterial(int color_mask); + void useEye(bool right) override; + void resetEye() override; + +public: + using RenderingCoreStereo::RenderingCoreStereo; + void drawAll() override; +}; diff --git a/src/client/render/core.cpp b/src/client/render/core.cpp new file mode 100644 index 0000000..ca5d3c6 --- /dev/null +++ b/src/client/render/core.cpp @@ -0,0 +1,129 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "core.h" +#include "client/camera.h" +#include "client/client.h" +#include "client/clientmap.h" +#include "client/hud.h" +#include "client/minimap.h" +#include "client/shadows/dynamicshadowsrender.h" + +RenderingCore::RenderingCore(IrrlichtDevice *_device, Client *_client, Hud *_hud) + : device(_device), driver(device->getVideoDriver()), smgr(device->getSceneManager()), + guienv(device->getGUIEnvironment()), client(_client), camera(client->getCamera()), + mapper(client->getMinimap()), hud(_hud), + shadow_renderer(nullptr) +{ + screensize = driver->getScreenSize(); + virtual_size = screensize; + + // disable if unsupported + if (g_settings->getBool("enable_dynamic_shadows") && ( + g_settings->get("video_driver") != "opengl" || + !g_settings->getBool("enable_shaders"))) { + g_settings->setBool("enable_dynamic_shadows", false); + } + + if (g_settings->getBool("enable_shaders") && + g_settings->getBool("enable_dynamic_shadows")) { + shadow_renderer = new ShadowRenderer(device, client); + } +} + +RenderingCore::~RenderingCore() +{ + clearTextures(); + delete shadow_renderer; +} + +void RenderingCore::initialize() +{ + // have to be called late as the VMT is not ready in the constructor: + initTextures(); + if (shadow_renderer) + shadow_renderer->initialize(); +} + +void RenderingCore::updateScreenSize() +{ + virtual_size = screensize; + clearTextures(); + initTextures(); +} + +void RenderingCore::draw(video::SColor _skycolor, bool _show_hud, bool _show_minimap, + bool _draw_wield_tool, bool _draw_crosshair) +{ + v2u32 ss = driver->getScreenSize(); + if (screensize != ss) { + screensize = ss; + updateScreenSize(); + } + skycolor = _skycolor; + show_hud = _show_hud; + show_minimap = _show_minimap; + draw_wield_tool = _draw_wield_tool; + draw_crosshair = _draw_crosshair; + + if (shadow_renderer) { + // This is necessary to render shadows for animations correctly + smgr->getRootSceneNode()->OnAnimate(device->getTimer()->getTime()); + shadow_renderer->update(); + } + + beforeDraw(); + drawAll(); +} + +void RenderingCore::draw3D() +{ + smgr->drawAll(); + if (shadow_renderer) + shadow_renderer->drawDebug(); + + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + if (!show_hud) + return; + hud->drawBlockBounds(); + hud->drawSelectionMesh(); + if (draw_wield_tool) + camera->drawWieldedTool(); +} + +void RenderingCore::drawHUD() +{ + if (show_hud) { + if (draw_crosshair) + hud->drawCrosshair(); + + hud->drawHotbar(client->getEnv().getLocalPlayer()->getWieldIndex()); + hud->drawLuaElements(camera->getOffset()); + camera->drawNametags(); + if (mapper && show_minimap) + mapper->drawMinimap(); + } + guienv->drawAll(); +} + +void RenderingCore::drawPostFx() +{ + client->getEnv().getClientMap().renderPostFx(camera->getCameraMode()); +} diff --git a/src/client/render/core.h b/src/client/render/core.h new file mode 100644 index 0000000..cabfbbf --- /dev/null +++ b/src/client/render/core.h @@ -0,0 +1,80 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "irrlichttypes_extrabloated.h" + +class ShadowRenderer; +class Camera; +class Client; +class Hud; +class Minimap; + +class RenderingCore +{ +protected: + v2u32 screensize; + v2u32 virtual_size; + video::SColor skycolor; + bool show_hud; + bool show_minimap; + bool draw_wield_tool; + bool draw_crosshair; + + IrrlichtDevice *device; + video::IVideoDriver *driver; + scene::ISceneManager *smgr; + gui::IGUIEnvironment *guienv; + + Client *client; + Camera *camera; + Minimap *mapper; + Hud *hud; + + ShadowRenderer *shadow_renderer; + + void updateScreenSize(); + virtual void initTextures() {} + virtual void clearTextures() {} + + virtual void beforeDraw() {} + virtual void drawAll() = 0; + + void draw3D(); + void drawHUD(); + void drawPostFx(); + +public: + RenderingCore(IrrlichtDevice *_device, Client *_client, Hud *_hud); + RenderingCore(const RenderingCore &) = delete; + RenderingCore(RenderingCore &&) = delete; + virtual ~RenderingCore(); + + RenderingCore &operator=(const RenderingCore &) = delete; + RenderingCore &operator=(RenderingCore &&) = delete; + + void initialize(); + void draw(video::SColor _skycolor, bool _show_hud, bool _show_minimap, + bool _draw_wield_tool, bool _draw_crosshair); + + inline v2u32 getVirtualSize() const { return virtual_size; } + + ShadowRenderer *get_shadow_renderer() { return shadow_renderer; }; +}; diff --git a/src/client/render/factory.cpp b/src/client/render/factory.cpp new file mode 100644 index 0000000..7fcec40 --- /dev/null +++ b/src/client/render/factory.cpp @@ -0,0 +1,52 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "factory.h" +#include "log.h" +#include "plain.h" +#include "anaglyph.h" +#include "interlaced.h" +#include "pageflip.h" +#include "sidebyside.h" + +RenderingCore *createRenderingCore(const std::string &stereo_mode, IrrlichtDevice *device, + Client *client, Hud *hud) +{ + if (stereo_mode == "none") + return new RenderingCorePlain(device, client, hud); + if (stereo_mode == "anaglyph") + return new RenderingCoreAnaglyph(device, client, hud); + if (stereo_mode == "interlaced") + return new RenderingCoreInterlaced(device, client, hud); +#ifdef STEREO_PAGEFLIP_SUPPORTED + if (stereo_mode == "pageflip") + return new RenderingCorePageflip(device, client, hud); +#endif + if (stereo_mode == "sidebyside") + return new RenderingCoreSideBySide(device, client, hud); + if (stereo_mode == "topbottom") + return new RenderingCoreSideBySide(device, client, hud, true); + if (stereo_mode == "crossview") + return new RenderingCoreSideBySide(device, client, hud, false, true); + + // fallback to plain renderer + errorstream << "Invalid rendering mode: " << stereo_mode << std::endl; + return new RenderingCorePlain(device, client, hud); +} diff --git a/src/client/render/factory.h b/src/client/render/factory.h new file mode 100644 index 0000000..e3339a8 --- /dev/null +++ b/src/client/render/factory.h @@ -0,0 +1,27 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include "core.h" + +RenderingCore *createRenderingCore(const std::string &stereo_mode, IrrlichtDevice *device, + Client *client, Hud *hud); diff --git a/src/client/render/interlaced.cpp b/src/client/render/interlaced.cpp new file mode 100644 index 0000000..3f79a8e --- /dev/null +++ b/src/client/render/interlaced.cpp @@ -0,0 +1,120 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "interlaced.h" +#include "client/client.h" +#include "client/shader.h" +#include "client/tile.h" + +RenderingCoreInterlaced::RenderingCoreInterlaced( + IrrlichtDevice *_device, Client *_client, Hud *_hud) + : RenderingCoreStereo(_device, _client, _hud) +{ + initMaterial(); +} + +void RenderingCoreInterlaced::initMaterial() +{ + IShaderSource *s = client->getShaderSource(); + mat.UseMipMaps = false; + mat.ZBuffer = false; +#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8 + mat.ZWriteEnable = video::EZW_OFF; +#else + mat.ZWriteEnable = false; +#endif + u32 shader = s->getShader("3d_interlaced_merge", TILE_MATERIAL_BASIC); + mat.MaterialType = s->getShaderInfo(shader).material; + for (int k = 0; k < 3; ++k) { + mat.TextureLayer[k].AnisotropicFilter = false; + mat.TextureLayer[k].BilinearFilter = false; + mat.TextureLayer[k].TrilinearFilter = false; + mat.TextureLayer[k].TextureWrapU = video::ETC_CLAMP_TO_EDGE; + mat.TextureLayer[k].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + } +} + +void RenderingCoreInterlaced::initTextures() +{ + v2u32 image_size{screensize.X, screensize.Y / 2}; + left = driver->addRenderTargetTexture( + image_size, "3d_render_left", video::ECF_A8R8G8B8); + right = driver->addRenderTargetTexture( + image_size, "3d_render_right", video::ECF_A8R8G8B8); + mask = driver->addTexture(screensize, "3d_render_mask", video::ECF_A8R8G8B8); + initMask(); + mat.TextureLayer[0].Texture = left; + mat.TextureLayer[1].Texture = right; + mat.TextureLayer[2].Texture = mask; +} + +void RenderingCoreInterlaced::clearTextures() +{ + driver->removeTexture(left); + driver->removeTexture(right); + driver->removeTexture(mask); +} + +void RenderingCoreInterlaced::initMask() +{ + u8 *data = reinterpret_cast<u8 *>(mask->lock()); + for (u32 j = 0; j < screensize.Y; j++) { + u8 val = j % 2 ? 0xff : 0x00; + memset(data, val, 4 * screensize.X); + data += 4 * screensize.X; + } + mask->unlock(); +} + +void RenderingCoreInterlaced::drawAll() +{ + renderBothImages(); + merge(); + drawHUD(); +} + +void RenderingCoreInterlaced::merge() +{ + static const video::S3DVertex vertices[4] = { + video::S3DVertex(1.0, -1.0, 0.0, 0.0, 0.0, -1.0, + video::SColor(255, 0, 255, 255), 1.0, 0.0), + video::S3DVertex(-1.0, -1.0, 0.0, 0.0, 0.0, -1.0, + video::SColor(255, 255, 0, 255), 0.0, 0.0), + video::S3DVertex(-1.0, 1.0, 0.0, 0.0, 0.0, -1.0, + video::SColor(255, 255, 255, 0), 0.0, 1.0), + video::S3DVertex(1.0, 1.0, 0.0, 0.0, 0.0, -1.0, + video::SColor(255, 255, 255, 255), 1.0, 1.0), + }; + static const u16 indices[6] = {0, 1, 2, 2, 3, 0}; + driver->setMaterial(mat); + driver->drawVertexPrimitiveList(&vertices, 4, &indices, 2); +} + +void RenderingCoreInterlaced::useEye(bool _right) +{ + driver->setRenderTarget(_right ? right : left, true, true, skycolor); + RenderingCoreStereo::useEye(_right); +} + +void RenderingCoreInterlaced::resetEye() +{ + driver->setRenderTarget(nullptr, false, false, skycolor); + RenderingCoreStereo::resetEye(); +} diff --git a/src/client/render/interlaced.h b/src/client/render/interlaced.h new file mode 100644 index 0000000..71815fd --- /dev/null +++ b/src/client/render/interlaced.h @@ -0,0 +1,43 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "stereo.h" + +class RenderingCoreInterlaced : public RenderingCoreStereo +{ +protected: + video::ITexture *left = nullptr; + video::ITexture *right = nullptr; + video::ITexture *mask = nullptr; + video::SMaterial mat; + + void initMaterial(); + void initTextures() override; + void clearTextures() override; + void initMask(); + void useEye(bool right) override; + void resetEye() override; + void merge(); + +public: + RenderingCoreInterlaced(IrrlichtDevice *_device, Client *_client, Hud *_hud); + void drawAll() override; +}; diff --git a/src/client/render/pageflip.cpp b/src/client/render/pageflip.cpp new file mode 100644 index 0000000..f3a2190 --- /dev/null +++ b/src/client/render/pageflip.cpp @@ -0,0 +1,59 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "pageflip.h" + +#ifdef STEREO_PAGEFLIP_SUPPORTED + +void RenderingCorePageflip::initTextures() +{ + hud = driver->addRenderTargetTexture( + screensize, "3d_render_hud", video::ECF_A8R8G8B8); +} + +void RenderingCorePageflip::clearTextures() +{ + driver->removeTexture(hud); +} + +void RenderingCorePageflip::drawAll() +{ + driver->setRenderTarget(hud, true, true, video::SColor(0, 0, 0, 0)); + drawHUD(); + driver->setRenderTarget(nullptr, false, false, skycolor); + renderBothImages(); +} + +void RenderingCorePageflip::useEye(bool _right) +{ + driver->setRenderTarget(_right ? video::ERT_STEREO_RIGHT_BUFFER + : video::ERT_STEREO_LEFT_BUFFER, + true, true, skycolor); + RenderingCoreStereo::useEye(_right); +} + +void RenderingCorePageflip::resetEye() +{ + driver->draw2DImage(hud, v2s32(0, 0)); + driver->setRenderTarget(video::ERT_FRAME_BUFFER, false, false, skycolor); + RenderingCoreStereo::resetEye(); +} + +#endif // STEREO_PAGEFLIP_SUPPORTED diff --git a/src/client/render/pageflip.h b/src/client/render/pageflip.h new file mode 100644 index 0000000..17711b0 --- /dev/null +++ b/src/client/render/pageflip.h @@ -0,0 +1,43 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "stereo.h" + +// The support is absent in 1.9.0 (dropped in r5068) +#if (IRRLICHT_VERSION_MAJOR == 1) && (IRRLICHT_VERSION_MINOR <= 8) +#define STEREO_PAGEFLIP_SUPPORTED + +class RenderingCorePageflip : public RenderingCoreStereo +{ +protected: + video::ITexture *hud = nullptr; + + void initTextures() override; + void clearTextures() override; + void useEye(bool right) override; + void resetEye() override; + +public: + using RenderingCoreStereo::RenderingCoreStereo; + void drawAll() override; +}; + +#endif diff --git a/src/client/render/plain.cpp b/src/client/render/plain.cpp new file mode 100644 index 0000000..a130a14 --- /dev/null +++ b/src/client/render/plain.cpp @@ -0,0 +1,76 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "plain.h" +#include "settings.h" + +inline u32 scaledown(u32 coef, u32 size) +{ + return (size + coef - 1) / coef; +} + +RenderingCorePlain::RenderingCorePlain( + IrrlichtDevice *_device, Client *_client, Hud *_hud) + : RenderingCore(_device, _client, _hud) +{ + scale = g_settings->getU16("undersampling"); +} + +void RenderingCorePlain::initTextures() +{ + if (scale <= 1) + return; + v2u32 size{scaledown(scale, screensize.X), scaledown(scale, screensize.Y)}; + lowres = driver->addRenderTargetTexture( + size, "render_lowres", video::ECF_A8R8G8B8); +} + +void RenderingCorePlain::clearTextures() +{ + if (scale <= 1) + return; + driver->removeTexture(lowres); +} + +void RenderingCorePlain::beforeDraw() +{ + if (scale <= 1) + return; + driver->setRenderTarget(lowres, true, true, skycolor); +} + +void RenderingCorePlain::upscale() +{ + if (scale <= 1) + return; + driver->setRenderTarget(0, true, true); + v2u32 size{scaledown(scale, screensize.X), scaledown(scale, screensize.Y)}; + v2u32 dest_size{scale * size.X, scale * size.Y}; + driver->draw2DImage(lowres, core::rect<s32>(0, 0, dest_size.X, dest_size.Y), + core::rect<s32>(0, 0, size.X, size.Y)); +} + +void RenderingCorePlain::drawAll() +{ + draw3D(); + drawPostFx(); + upscale(); + drawHUD(); +} diff --git a/src/client/render/plain.h b/src/client/render/plain.h new file mode 100644 index 0000000..80c17ed --- /dev/null +++ b/src/client/render/plain.h @@ -0,0 +1,38 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "core.h" + +class RenderingCorePlain : public RenderingCore +{ +protected: + int scale = 0; + video::ITexture *lowres = nullptr; + + void initTextures() override; + void clearTextures() override; + void beforeDraw() override; + void upscale(); + +public: + RenderingCorePlain(IrrlichtDevice *_device, Client *_client, Hud *_hud); + void drawAll() override; +}; diff --git a/src/client/render/sidebyside.cpp b/src/client/render/sidebyside.cpp new file mode 100644 index 0000000..ed08810 --- /dev/null +++ b/src/client/render/sidebyside.cpp @@ -0,0 +1,74 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "sidebyside.h" +#include <ICameraSceneNode.h> +#include "client/hud.h" + +RenderingCoreSideBySide::RenderingCoreSideBySide( + IrrlichtDevice *_device, Client *_client, Hud *_hud, bool _horizontal, bool _flipped) + : RenderingCoreStereo(_device, _client, _hud), horizontal(_horizontal), flipped(_flipped) +{ +} + +void RenderingCoreSideBySide::initTextures() +{ + if (horizontal) { + image_size = {screensize.X, screensize.Y / 2}; + rpos = v2s32(0, screensize.Y / 2); + } else { + image_size = {screensize.X / 2, screensize.Y}; + rpos = v2s32(screensize.X / 2, 0); + } + virtual_size = image_size; + left = driver->addRenderTargetTexture( + image_size, "3d_render_left", video::ECF_A8R8G8B8); + right = driver->addRenderTargetTexture( + image_size, "3d_render_right", video::ECF_A8R8G8B8); +} + +void RenderingCoreSideBySide::clearTextures() +{ + driver->removeTexture(left); + driver->removeTexture(right); +} + +void RenderingCoreSideBySide::drawAll() +{ + driver->OnResize(image_size); // HACK to make GUI smaller + renderBothImages(); + driver->OnResize(screensize); + driver->draw2DImage(left, {}); + driver->draw2DImage(right, rpos); +} + +void RenderingCoreSideBySide::useEye(bool _right) +{ + driver->setRenderTarget(_right ? right : left, true, true, skycolor); + RenderingCoreStereo::useEye(_right ^ flipped); +} + +void RenderingCoreSideBySide::resetEye() +{ + hud->resizeHotbar(); + drawHUD(); + driver->setRenderTarget(nullptr, false, false, skycolor); + RenderingCoreStereo::resetEye(); +} diff --git a/src/client/render/sidebyside.h b/src/client/render/sidebyside.h new file mode 100644 index 0000000..f8ed256 --- /dev/null +++ b/src/client/render/sidebyside.h @@ -0,0 +1,43 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "stereo.h" + +class RenderingCoreSideBySide : public RenderingCoreStereo +{ +protected: + video::ITexture *left = nullptr; + video::ITexture *right = nullptr; + bool horizontal = false; + bool flipped = false; + core::dimension2du image_size; + v2s32 rpos; + + void initTextures() override; + void clearTextures() override; + void useEye(bool right) override; + void resetEye() override; + +public: + RenderingCoreSideBySide(IrrlichtDevice *_device, Client *_client, Hud *_hud, + bool _horizontal = false, bool _flipped = false); + void drawAll() override; +}; diff --git a/src/client/render/stereo.cpp b/src/client/render/stereo.cpp new file mode 100644 index 0000000..0f54e16 --- /dev/null +++ b/src/client/render/stereo.cpp @@ -0,0 +1,60 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "stereo.h" +#include "client/camera.h" +#include "constants.h" +#include "settings.h" + +RenderingCoreStereo::RenderingCoreStereo( + IrrlichtDevice *_device, Client *_client, Hud *_hud) + : RenderingCore(_device, _client, _hud) +{ + eye_offset = BS * g_settings->getFloat("3d_paralax_strength", -0.087f, 0.087f); +} + +void RenderingCoreStereo::beforeDraw() +{ + cam = camera->getCameraNode(); + base_transform = cam->getRelativeTransformation(); +} + +void RenderingCoreStereo::useEye(bool right) +{ + core::matrix4 move; + move.setTranslation( + core::vector3df(right ? eye_offset : -eye_offset, 0.0f, 0.0f)); + cam->setPosition((base_transform * move).getTranslation()); +} + +void RenderingCoreStereo::resetEye() +{ + cam->setPosition(base_transform.getTranslation()); +} + +void RenderingCoreStereo::renderBothImages() +{ + useEye(false); + draw3D(); + resetEye(); + useEye(true); + draw3D(); + resetEye(); +} diff --git a/src/client/render/stereo.h b/src/client/render/stereo.h new file mode 100644 index 0000000..c8b07e1 --- /dev/null +++ b/src/client/render/stereo.h @@ -0,0 +1,38 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "core.h" + +class RenderingCoreStereo : public RenderingCore +{ +protected: + scene::ICameraSceneNode *cam; + core::matrix4 base_transform; + float eye_offset; + + void beforeDraw() override; + virtual void useEye(bool right); + virtual void resetEye(); + void renderBothImages(); + +public: + RenderingCoreStereo(IrrlichtDevice *_device, Client *_client, Hud *_hud); +}; diff --git a/src/client/renderingengine.cpp b/src/client/renderingengine.cpp new file mode 100644 index 0000000..9698b63 --- /dev/null +++ b/src/client/renderingengine.cpp @@ -0,0 +1,652 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <IrrlichtDevice.h> +#include "fontengine.h" +#include "client.h" +#include "clouds.h" +#include "util/numeric.h" +#include "guiscalingfilter.h" +#include "localplayer.h" +#include "client/hud.h" +#include "camera.h" +#include "minimap.h" +#include "clientmap.h" +#include "renderingengine.h" +#include "render/core.h" +#include "render/factory.h" +#include "inputhandler.h" +#include "gettext.h" +#include "../gui/guiSkin.h" + +#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__ANDROID__) && \ + !defined(SERVER) && !defined(__HAIKU__) +#define XORG_USED +#endif +#ifdef XORG_USED +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#endif + +#ifdef _WIN32 +#include <windows.h> +#include <winuser.h> +#endif + +#if ENABLE_GLES +#include "filesys.h" +#endif + +RenderingEngine *RenderingEngine::s_singleton = nullptr; + + +static gui::GUISkin *createSkin(gui::IGUIEnvironment *environment, + gui::EGUI_SKIN_TYPE type, video::IVideoDriver *driver) +{ + gui::GUISkin *skin = new gui::GUISkin(type, driver); + + gui::IGUIFont *builtinfont = environment->getBuiltInFont(); + gui::IGUIFontBitmap *bitfont = nullptr; + if (builtinfont && builtinfont->getType() == gui::EGFT_BITMAP) + bitfont = (gui::IGUIFontBitmap*)builtinfont; + + gui::IGUISpriteBank *bank = 0; + skin->setFont(builtinfont); + + if (bitfont) + bank = bitfont->getSpriteBank(); + + skin->setSpriteBank(bank); + + return skin; +} + + +RenderingEngine::RenderingEngine(IEventReceiver *receiver) +{ + sanity_check(!s_singleton); + + // Resolution selection + bool fullscreen = g_settings->getBool("fullscreen"); +#ifdef __ANDROID__ + u16 screen_w = 0, screen_h = 0; +#else + u16 screen_w = std::max<u16>(g_settings->getU16("screen_w"), 1); + u16 screen_h = std::max<u16>(g_settings->getU16("screen_h"), 1); +#endif + + // bpp, fsaa, vsync + bool vsync = g_settings->getBool("vsync"); + u16 fsaa = g_settings->getU16("fsaa"); + + // stereo buffer required for pageflip stereo + bool stereo_buffer = g_settings->get("3d_mode") == "pageflip"; + + // Determine driver + video::E_DRIVER_TYPE driverType = video::EDT_OPENGL; + const std::string &driverstring = g_settings->get("video_driver"); + std::vector<video::E_DRIVER_TYPE> drivers = + RenderingEngine::getSupportedVideoDrivers(); + u32 i; + for (i = 0; i != drivers.size(); i++) { + if (!strcasecmp(driverstring.c_str(), + RenderingEngine::getVideoDriverInfo(drivers[i]).name.c_str())) { + driverType = drivers[i]; + break; + } + } + if (i == drivers.size()) { + errorstream << "Invalid video_driver specified; " + "defaulting to opengl" + << std::endl; + } + + SIrrlichtCreationParameters params = SIrrlichtCreationParameters(); + if (tracestream) + params.LoggingLevel = irr::ELL_DEBUG; + params.DriverType = driverType; + params.WindowSize = core::dimension2d<u32>(screen_w, screen_h); + params.AntiAlias = fsaa; + params.Fullscreen = fullscreen; + params.Stencilbuffer = false; + params.Stereobuffer = stereo_buffer; + params.Vsync = vsync; + params.EventReceiver = receiver; + params.HighPrecisionFPU = true; +#ifdef __ANDROID__ + params.PrivateData = porting::app_global; +#endif +#if ENABLE_GLES + // there is no standardized path for these on desktop + std::string rel_path = std::string("client") + DIR_DELIM + + "shaders" + DIR_DELIM + "Irrlicht"; + params.OGLES2ShaderPath = (porting::path_share + DIR_DELIM + rel_path + DIR_DELIM).c_str(); +#endif + + m_device = createDeviceEx(params); + driver = m_device->getVideoDriver(); + + s_singleton = this; + + auto skin = createSkin(m_device->getGUIEnvironment(), + gui::EGST_WINDOWS_METALLIC, driver); + m_device->getGUIEnvironment()->setSkin(skin); + skin->drop(); +} + +RenderingEngine::~RenderingEngine() +{ + core.reset(); + m_device->closeDevice(); + s_singleton = nullptr; +} + +v2u32 RenderingEngine::_getWindowSize() const +{ + if (core) + return core->getVirtualSize(); + return m_device->getVideoDriver()->getScreenSize(); +} + +void RenderingEngine::setResizable(bool resize) +{ + m_device->setResizable(resize); +} + +void RenderingEngine::removeMesh(const scene::IMesh* mesh) +{ + m_device->getSceneManager()->getMeshCache()->removeMesh(mesh); +} + +void RenderingEngine::cleanupMeshCache() +{ + auto mesh_cache = m_device->getSceneManager()->getMeshCache(); + while (mesh_cache->getMeshCount() != 0) { + if (scene::IAnimatedMesh *mesh = mesh_cache->getMeshByIndex(0)) + mesh_cache->removeMesh(mesh); + } +} + +bool RenderingEngine::setupTopLevelWindow(const std::string &name) +{ + // FIXME: It would make more sense for there to be a switch of some + // sort here that would call the correct toplevel setup methods for + // the environment Minetest is running in. + + /* Setting Xorg properties for the top level window */ + setupTopLevelXorgWindow(name); + + /* Setting general properties for the top level window */ + verbosestream << "Client: Configuring general top level" + << " window properties" + << std::endl; + bool result = setWindowIcon(); + + return result; +} + +void RenderingEngine::setupTopLevelXorgWindow(const std::string &name) +{ +#ifdef XORG_USED + const video::SExposedVideoData exposedData = driver->getExposedVideoData(); + + Display *x11_dpl = reinterpret_cast<Display *>(exposedData.OpenGLLinux.X11Display); + if (x11_dpl == NULL) { + warningstream << "Client: Could not find X11 Display in ExposedVideoData" + << std::endl; + return; + } + + verbosestream << "Client: Configuring X11-specific top level" + << " window properties" + << std::endl; + + + Window x11_win = reinterpret_cast<Window>(exposedData.OpenGLLinux.X11Window); + + // Set application name and class hints. For now name and class are the same. + XClassHint *classhint = XAllocClassHint(); + classhint->res_name = const_cast<char *>(name.c_str()); + classhint->res_class = const_cast<char *>(name.c_str()); + + XSetClassHint(x11_dpl, x11_win, classhint); + XFree(classhint); + + // FIXME: In the future WMNormalHints should be set ... e.g see the + // gtk/gdk code (gdk/x11/gdksurface-x11.c) for the setup_top_level + // method. But for now (as it would require some significant changes) + // leave the code as is. + + // The following is borrowed from the above gdk source for setting top + // level windows. The source indicates and the Xlib docs suggest that + // this will set the WM_CLIENT_MACHINE and WM_LOCAL_NAME. This will not + // set the WM_CLIENT_MACHINE to a Fully Qualified Domain Name (FQDN) which is + // required by the Extended Window Manager Hints (EWMH) spec when setting + // the _NET_WM_PID (see further down) but running Minetest in an env + // where the window manager is on another machine from Minetest (therefore + // making the PID useless) is not expected to be a problem. Further + // more, using gtk/gdk as the model it would seem that not using a FQDN is + // not an issue for modern Xorg window managers. + + verbosestream << "Client: Setting Xorg window manager Properties" + << std::endl; + + XSetWMProperties (x11_dpl, x11_win, NULL, NULL, NULL, 0, NULL, NULL, NULL); + + // Set the _NET_WM_PID window property according to the EWMH spec. _NET_WM_PID + // (in conjunction with WM_CLIENT_MACHINE) can be used by window managers to + // force a shutdown of an application if it doesn't respond to the destroy + // window message. + + verbosestream << "Client: Setting Xorg _NET_WM_PID extended window manager property" + << std::endl; + + Atom NET_WM_PID = XInternAtom(x11_dpl, "_NET_WM_PID", false); + + pid_t pid = getpid(); + + XChangeProperty(x11_dpl, x11_win, NET_WM_PID, + XA_CARDINAL, 32, PropModeReplace, + reinterpret_cast<unsigned char *>(&pid),1); + + // Set the WM_CLIENT_LEADER window property here. Minetest has only one + // window and that window will always be the leader. + + verbosestream << "Client: Setting Xorg WM_CLIENT_LEADER property" + << std::endl; + + Atom WM_CLIENT_LEADER = XInternAtom(x11_dpl, "WM_CLIENT_LEADER", false); + + XChangeProperty (x11_dpl, x11_win, WM_CLIENT_LEADER, + XA_WINDOW, 32, PropModeReplace, + reinterpret_cast<unsigned char *>(&x11_win), 1); +#endif +} + +#ifdef _WIN32 +static bool getWindowHandle(irr::video::IVideoDriver *driver, HWND &hWnd) +{ + const video::SExposedVideoData exposedData = driver->getExposedVideoData(); + + switch (driver->getDriverType()) { +#if ENABLE_GLES + case video::EDT_OGLES1: + case video::EDT_OGLES2: +#endif + case video::EDT_OPENGL: + hWnd = reinterpret_cast<HWND>(exposedData.OpenGLWin32.HWnd); + break; + default: + return false; + } + + return true; +} +#endif + +bool RenderingEngine::setWindowIcon() +{ +#if defined(XORG_USED) +#if RUN_IN_PLACE + return setXorgWindowIconFromPath( + porting::path_share + "/misc/" PROJECT_NAME "-xorg-icon-128.png"); +#else + // We have semi-support for reading in-place data if we are + // compiled with RUN_IN_PLACE. Don't break with this and + // also try the path_share location. + return setXorgWindowIconFromPath( + ICON_DIR "/hicolor/128x128/apps/" PROJECT_NAME ".png") || + setXorgWindowIconFromPath(porting::path_share + "/misc/" PROJECT_NAME + "-xorg-icon-128.png"); +#endif +#elif defined(_WIN32) + HWND hWnd; // Window handle + if (!getWindowHandle(driver, hWnd)) + return false; + + // Load the ICON from resource file + const HICON hicon = LoadIcon(GetModuleHandle(NULL), + MAKEINTRESOURCE(130) // The ID of the ICON defined in + // winresource.rc + ); + + if (hicon) { + SendMessage(hWnd, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(hicon)); + SendMessage(hWnd, WM_SETICON, ICON_SMALL, + reinterpret_cast<LPARAM>(hicon)); + return true; + } + return false; +#else + return false; +#endif +} + +bool RenderingEngine::setXorgWindowIconFromPath(const std::string &icon_file) +{ +#ifdef XORG_USED + + video::IImageLoader *image_loader = NULL; + u32 cnt = driver->getImageLoaderCount(); + for (u32 i = 0; i < cnt; i++) { + if (driver->getImageLoader(i)->isALoadableFileExtension( + icon_file.c_str())) { + image_loader = driver->getImageLoader(i); + break; + } + } + + if (!image_loader) { + warningstream << "Could not find image loader for file '" << icon_file + << "'" << std::endl; + return false; + } + + io::IReadFile *icon_f = + m_device->getFileSystem()->createAndOpenFile(icon_file.c_str()); + + if (!icon_f) { + warningstream << "Could not load icon file '" << icon_file << "'" + << std::endl; + return false; + } + + video::IImage *img = image_loader->loadImage(icon_f); + + if (!img) { + warningstream << "Could not load icon file '" << icon_file << "'" + << std::endl; + icon_f->drop(); + return false; + } + + u32 height = img->getDimension().Height; + u32 width = img->getDimension().Width; + + size_t icon_buffer_len = 2 + height * width; + long *icon_buffer = new long[icon_buffer_len]; + + icon_buffer[0] = width; + icon_buffer[1] = height; + + for (u32 x = 0; x < width; x++) { + for (u32 y = 0; y < height; y++) { + video::SColor col = img->getPixel(x, y); + long pixel_val = 0; + pixel_val |= (u8)col.getAlpha() << 24; + pixel_val |= (u8)col.getRed() << 16; + pixel_val |= (u8)col.getGreen() << 8; + pixel_val |= (u8)col.getBlue(); + icon_buffer[2 + x + y * width] = pixel_val; + } + } + + img->drop(); + icon_f->drop(); + + const video::SExposedVideoData &video_data = driver->getExposedVideoData(); + + Display *x11_dpl = (Display *)video_data.OpenGLLinux.X11Display; + + if (x11_dpl == NULL) { + warningstream << "Could not find x11 display for setting its icon." + << std::endl; + delete[] icon_buffer; + return false; + } + + Window x11_win = (Window)video_data.OpenGLLinux.X11Window; + + Atom net_wm_icon = XInternAtom(x11_dpl, "_NET_WM_ICON", False); + Atom cardinal = XInternAtom(x11_dpl, "CARDINAL", False); + XChangeProperty(x11_dpl, x11_win, net_wm_icon, cardinal, 32, PropModeReplace, + (const unsigned char *)icon_buffer, icon_buffer_len); + + delete[] icon_buffer; + +#endif + return true; +} + +/* + Draws a screen with a single text on it. + Text will be removed when the screen is drawn the next time. + Additionally, a progressbar can be drawn when percent is set between 0 and 100. +*/ +void RenderingEngine::draw_load_screen(const std::wstring &text, + gui::IGUIEnvironment *guienv, ITextureSource *tsrc, float dtime, + int percent, bool clouds) +{ + v2u32 screensize = getWindowSize(); + + v2s32 textsize(g_fontengine->getTextWidth(text), g_fontengine->getLineHeight()); + v2s32 center(screensize.X / 2, screensize.Y / 2); + core::rect<s32> textrect(center - textsize / 2, center + textsize / 2); + + gui::IGUIStaticText *guitext = + guienv->addStaticText(text.c_str(), textrect, false, false); + guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT); + + bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds"); + if (cloud_menu_background) { + g_menuclouds->step(dtime * 3); + g_menuclouds->render(); + get_video_driver()->beginScene( + true, true, video::SColor(255, 140, 186, 250)); + g_menucloudsmgr->drawAll(); + } else + get_video_driver()->beginScene(true, true, video::SColor(255, 0, 0, 0)); + + // draw progress bar + if ((percent >= 0) && (percent <= 100)) { + video::ITexture *progress_img = tsrc->getTexture("progress_bar.png"); + video::ITexture *progress_img_bg = + tsrc->getTexture("progress_bar_bg.png"); + + if (progress_img && progress_img_bg) { +#ifndef __ANDROID__ + const core::dimension2d<u32> &img_size = + progress_img_bg->getSize(); + u32 imgW = rangelim(img_size.Width, 200, 600); + u32 imgH = rangelim(img_size.Height, 24, 72); +#else + const core::dimension2d<u32> img_size(256, 48); + float imgRatio = (float)img_size.Height / img_size.Width; + u32 imgW = screensize.X / 2.2f; + u32 imgH = floor(imgW * imgRatio); +#endif + v2s32 img_pos((screensize.X - imgW) / 2, + (screensize.Y - imgH) / 2); + + draw2DImageFilterScaled(get_video_driver(), progress_img_bg, + core::rect<s32>(img_pos.X, img_pos.Y, + img_pos.X + imgW, + img_pos.Y + imgH), + core::rect<s32>(0, 0, img_size.Width, + img_size.Height), + 0, 0, true); + + draw2DImageFilterScaled(get_video_driver(), progress_img, + core::rect<s32>(img_pos.X, img_pos.Y, + img_pos.X + (percent * imgW) / 100, + img_pos.Y + imgH), + core::rect<s32>(0, 0, + (percent * img_size.Width) / 100, + img_size.Height), + 0, 0, true); + } + } + + guienv->drawAll(); + get_video_driver()->endScene(); + guitext->remove(); +} + +/* + Draws the menu scene including (optional) cloud background. +*/ +void RenderingEngine::draw_menu_scene(gui::IGUIEnvironment *guienv, + float dtime, bool clouds) +{ + bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds"); + if (cloud_menu_background) { + g_menuclouds->step(dtime * 3); + g_menuclouds->render(); + get_video_driver()->beginScene( + true, true, video::SColor(255, 140, 186, 250)); + g_menucloudsmgr->drawAll(); + } else + get_video_driver()->beginScene(true, true, video::SColor(255, 0, 0, 0)); + + guienv->drawAll(); + get_video_driver()->endScene(); +} + +std::vector<irr::video::E_DRIVER_TYPE> RenderingEngine::getSupportedVideoDrivers() +{ + // Only check these drivers. + // We do not support software and D3D in any capacity. + static const irr::video::E_DRIVER_TYPE glDrivers[4] = { + irr::video::EDT_NULL, + irr::video::EDT_OPENGL, + irr::video::EDT_OGLES1, + irr::video::EDT_OGLES2, + }; + std::vector<irr::video::E_DRIVER_TYPE> drivers; + + for (int i = 0; i < 4; i++) { + if (irr::IrrlichtDevice::isDriverSupported(glDrivers[i])) + drivers.push_back(glDrivers[i]); + } + + return drivers; +} + +void RenderingEngine::initialize(Client *client, Hud *hud) +{ + const std::string &draw_mode = g_settings->get("3d_mode"); + core.reset(createRenderingCore(draw_mode, m_device, client, hud)); + core->initialize(); +} + +void RenderingEngine::finalize() +{ + core.reset(); +} + +void RenderingEngine::draw_scene(video::SColor skycolor, bool show_hud, + bool show_minimap, bool draw_wield_tool, bool draw_crosshair) +{ + core->draw(skycolor, show_hud, show_minimap, draw_wield_tool, draw_crosshair); +} + +const VideoDriverInfo &RenderingEngine::getVideoDriverInfo(irr::video::E_DRIVER_TYPE type) +{ + static const std::unordered_map<int, VideoDriverInfo> driver_info_map = { + {(int)video::EDT_NULL, {"null", "NULL Driver"}}, + {(int)video::EDT_OPENGL, {"opengl", "OpenGL"}}, + {(int)video::EDT_OGLES1, {"ogles1", "OpenGL ES1"}}, + {(int)video::EDT_OGLES2, {"ogles2", "OpenGL ES2"}}, + }; + return driver_info_map.at((int)type); +} + +#ifndef __ANDROID__ +#if defined(XORG_USED) + +static float calcDisplayDensity() +{ + const char *current_display = getenv("DISPLAY"); + + if (current_display != NULL) { + Display *x11display = XOpenDisplay(current_display); + + if (x11display != NULL) { + /* try x direct */ + int dh = DisplayHeight(x11display, 0); + int dw = DisplayWidth(x11display, 0); + int dh_mm = DisplayHeightMM(x11display, 0); + int dw_mm = DisplayWidthMM(x11display, 0); + XCloseDisplay(x11display); + + if (dh_mm != 0 && dw_mm != 0) { + float dpi_height = floor(dh / (dh_mm * 0.039370) + 0.5); + float dpi_width = floor(dw / (dw_mm * 0.039370) + 0.5); + return std::max(dpi_height, dpi_width) / 96.0; + } + } + } + + /* return manually specified dpi */ + return g_settings->getFloat("screen_dpi") / 96.0; +} + +float RenderingEngine::getDisplayDensity() +{ + static float cached_display_density = calcDisplayDensity(); + return std::max(cached_display_density * g_settings->getFloat("display_density_factor"), 0.5f); +} + +#elif defined(_WIN32) + + +static float calcDisplayDensity(irr::video::IVideoDriver *driver) +{ + HWND hWnd; + if (getWindowHandle(driver, hWnd)) { + HDC hdc = GetDC(hWnd); + float dpi = GetDeviceCaps(hdc, LOGPIXELSX); + ReleaseDC(hWnd, hdc); + return dpi / 96.0f; + } + + /* return manually specified dpi */ + return g_settings->getFloat("screen_dpi") / 96.0f; +} + +float RenderingEngine::getDisplayDensity() +{ + static bool cached = false; + static float display_density; + if (!cached) { + display_density = calcDisplayDensity(get_video_driver()); + cached = true; + } + return std::max(display_density * g_settings->getFloat("display_density_factor"), 0.5f); +} + +#else + +float RenderingEngine::getDisplayDensity() +{ + return std::max(g_settings->getFloat("screen_dpi") / 96.0f * + g_settings->getFloat("display_density_factor"), 0.5f); +} + +#endif + +#else // __ANDROID__ +float RenderingEngine::getDisplayDensity() +{ + return porting::getDisplayDensity(); +} + +#endif // __ANDROID__ diff --git a/src/client/renderingengine.h b/src/client/renderingengine.h new file mode 100644 index 0000000..3842001 --- /dev/null +++ b/src/client/renderingengine.h @@ -0,0 +1,138 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <vector> +#include <memory> +#include <string> +#include "irrlichttypes_extrabloated.h" +#include "debug.h" +#include "client/render/core.h" +// include the shadow mapper classes too +#include "client/shadows/dynamicshadowsrender.h" + +struct VideoDriverInfo { + std::string name; + std::string friendly_name; +}; + +class ITextureSource; +class Camera; +class Client; +class LocalPlayer; +class Hud; +class Minimap; + +class RenderingCore; + +class RenderingEngine +{ +public: + RenderingEngine(IEventReceiver *eventReceiver); + ~RenderingEngine(); + + void setResizable(bool resize); + + video::IVideoDriver *getVideoDriver() { return driver; } + + static const VideoDriverInfo &getVideoDriverInfo(irr::video::E_DRIVER_TYPE type); + static float getDisplayDensity(); + + bool setupTopLevelWindow(const std::string &name); + void setupTopLevelXorgWindow(const std::string &name); + bool setWindowIcon(); + bool setXorgWindowIconFromPath(const std::string &icon_file); + static bool print_video_modes(); + void cleanupMeshCache(); + + void removeMesh(const scene::IMesh* mesh); + + static v2u32 getWindowSize() + { + sanity_check(s_singleton); + return s_singleton->_getWindowSize(); + } + + io::IFileSystem *get_filesystem() + { + return m_device->getFileSystem(); + } + + static video::IVideoDriver *get_video_driver() + { + sanity_check(s_singleton && s_singleton->m_device); + return s_singleton->m_device->getVideoDriver(); + } + + scene::ISceneManager *get_scene_manager() + { + return m_device->getSceneManager(); + } + + static irr::IrrlichtDevice *get_raw_device() + { + sanity_check(s_singleton && s_singleton->m_device); + return s_singleton->m_device; + } + + u32 get_timer_time() + { + return m_device->getTimer()->getTime(); + } + + gui::IGUIEnvironment *get_gui_env() + { + return m_device->getGUIEnvironment(); + } + + void draw_load_screen(const std::wstring &text, + gui::IGUIEnvironment *guienv, ITextureSource *tsrc, + float dtime = 0, int percent = 0, bool clouds = true); + + void draw_menu_scene(gui::IGUIEnvironment *guienv, float dtime, bool clouds); + void draw_scene(video::SColor skycolor, bool show_hud, + bool show_minimap, bool draw_wield_tool, bool draw_crosshair); + + void initialize(Client *client, Hud *hud); + void finalize(); + + bool run() + { + return m_device->run(); + } + + // FIXME: this is still global when it shouldn't be + static ShadowRenderer *get_shadow_renderer() + { + if (s_singleton && s_singleton->core) + return s_singleton->core->get_shadow_renderer(); + return nullptr; + } + static std::vector<irr::video::E_DRIVER_TYPE> getSupportedVideoDrivers(); + +private: + v2u32 _getWindowSize() const; + + std::unique_ptr<RenderingCore> core; + irr::IrrlichtDevice *m_device = nullptr; + irr::video::IVideoDriver *driver; + static RenderingEngine *s_singleton; +}; diff --git a/src/client/shader.cpp b/src/client/shader.cpp new file mode 100644 index 0000000..009a4b3 --- /dev/null +++ b/src/client/shader.cpp @@ -0,0 +1,829 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013 Kahrl <kahrl@gmx.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <fstream> +#include <iterator> +#include "shader.h" +#include "irrlichttypes_extrabloated.h" +#include "irr_ptr.h" +#include "debug.h" +#include "filesys.h" +#include "util/container.h" +#include "util/thread.h" +#include "settings.h" +#include <ICameraSceneNode.h> +#include <IGPUProgrammingServices.h> +#include <IMaterialRenderer.h> +#include <IMaterialRendererServices.h> +#include <IShaderConstantSetCallBack.h> +#include "client/renderingengine.h" +#include "EShaderTypes.h" +#include "log.h" +#include "gamedef.h" +#include "client/tile.h" +#include "config.h" + +#include <mt_opengl.h> + +/* + A cache from shader name to shader path +*/ +MutexedMap<std::string, std::string> g_shadername_to_path_cache; + +/* + Gets the path to a shader by first checking if the file + name_of_shader/filename + exists in shader_path and if not, using the data path. + + If not found, returns "". + + Utilizes a thread-safe cache. +*/ +std::string getShaderPath(const std::string &name_of_shader, + const std::string &filename) +{ + std::string combined = name_of_shader + DIR_DELIM + filename; + std::string fullpath; + /* + Check from cache + */ + bool incache = g_shadername_to_path_cache.get(combined, &fullpath); + if(incache) + return fullpath; + + /* + Check from shader_path + */ + std::string shader_path = g_settings->get("shader_path"); + if (!shader_path.empty()) { + std::string testpath = shader_path + DIR_DELIM + combined; + if(fs::PathExists(testpath)) + fullpath = testpath; + } + + /* + Check from default data directory + */ + if (fullpath.empty()) { + std::string rel_path = std::string("client") + DIR_DELIM + + "shaders" + DIR_DELIM + + name_of_shader + DIR_DELIM + + filename; + std::string testpath = porting::path_share + DIR_DELIM + rel_path; + if(fs::PathExists(testpath)) + fullpath = testpath; + } + + // Add to cache (also an empty result is cached) + g_shadername_to_path_cache.set(combined, fullpath); + + // Finally return it + return fullpath; +} + +/* + SourceShaderCache: A cache used for storing source shaders. +*/ + +class SourceShaderCache +{ +public: + void insert(const std::string &name_of_shader, const std::string &filename, + const std::string &program, bool prefer_local) + { + std::string combined = name_of_shader + DIR_DELIM + filename; + // Try to use local shader instead if asked to + if(prefer_local){ + std::string path = getShaderPath(name_of_shader, filename); + if(!path.empty()){ + std::string p = readFile(path); + if (!p.empty()) { + m_programs[combined] = p; + return; + } + } + } + m_programs[combined] = program; + } + + std::string get(const std::string &name_of_shader, + const std::string &filename) + { + std::string combined = name_of_shader + DIR_DELIM + filename; + StringMap::iterator n = m_programs.find(combined); + if (n != m_programs.end()) + return n->second; + return ""; + } + + // Primarily fetches from cache, secondarily tries to read from filesystem + std::string getOrLoad(const std::string &name_of_shader, + const std::string &filename) + { + std::string combined = name_of_shader + DIR_DELIM + filename; + StringMap::iterator n = m_programs.find(combined); + if (n != m_programs.end()) + return n->second; + std::string path = getShaderPath(name_of_shader, filename); + if (path.empty()) { + infostream << "SourceShaderCache::getOrLoad(): No path found for \"" + << combined << "\"" << std::endl; + return ""; + } + infostream << "SourceShaderCache::getOrLoad(): Loading path \"" + << path << "\"" << std::endl; + std::string p = readFile(path); + if (!p.empty()) { + m_programs[combined] = p; + return p; + } + return ""; + } +private: + StringMap m_programs; + + std::string readFile(const std::string &path) + { + std::ifstream is(path.c_str(), std::ios::binary); + if(!is.is_open()) + return ""; + std::ostringstream tmp_os; + tmp_os << is.rdbuf(); + return tmp_os.str(); + } +}; + + +/* + ShaderCallback: Sets constants that can be used in shaders +*/ + +class ShaderCallback : public video::IShaderConstantSetCallBack +{ + std::vector<std::unique_ptr<IShaderConstantSetter>> m_setters; + +public: + template <typename Factories> + ShaderCallback(const Factories &factories) + { + for (auto &&factory : factories) + m_setters.push_back(std::unique_ptr<IShaderConstantSetter>(factory->create())); + } + + virtual void OnSetConstants(video::IMaterialRendererServices *services, s32 userData) override + { + video::IVideoDriver *driver = services->getVideoDriver(); + sanity_check(driver != NULL); + + for (auto &&setter : m_setters) + setter->onSetConstants(services); + } + + virtual void OnSetMaterial(const video::SMaterial& material) override + { + for (auto &&setter : m_setters) + setter->onSetMaterial(material); + } +}; + + +/* + MainShaderConstantSetter: Set basic constants required for almost everything +*/ + +class MainShaderConstantSetter : public IShaderConstantSetter +{ + CachedVertexShaderSetting<f32, 16> m_world_view_proj; + CachedVertexShaderSetting<f32, 16> m_world; + + // Shadow-related + CachedPixelShaderSetting<f32, 16> m_shadow_view_proj; + CachedPixelShaderSetting<f32, 3> m_light_direction; + CachedPixelShaderSetting<f32> m_texture_res; + CachedPixelShaderSetting<f32> m_shadow_strength; + CachedPixelShaderSetting<f32> m_time_of_day; + CachedPixelShaderSetting<f32> m_shadowfar; + CachedPixelShaderSetting<f32, 4> m_camera_pos; + CachedPixelShaderSetting<s32> m_shadow_texture; + CachedVertexShaderSetting<f32> m_perspective_bias0_vertex; + CachedPixelShaderSetting<f32> m_perspective_bias0_pixel; + CachedVertexShaderSetting<f32> m_perspective_bias1_vertex; + CachedPixelShaderSetting<f32> m_perspective_bias1_pixel; + CachedVertexShaderSetting<f32> m_perspective_zbias_vertex; + CachedPixelShaderSetting<f32> m_perspective_zbias_pixel; + +#if ENABLE_GLES + // Modelview matrix + CachedVertexShaderSetting<float, 16> m_world_view; + // Texture matrix + CachedVertexShaderSetting<float, 16> m_texture; + // Normal matrix + CachedVertexShaderSetting<float, 9> m_normal; +#endif + +public: + MainShaderConstantSetter() : + m_world_view_proj("mWorldViewProj") + , m_world("mWorld") + , m_shadow_view_proj("m_ShadowViewProj") + , m_light_direction("v_LightDirection") + , m_texture_res("f_textureresolution") + , m_shadow_strength("f_shadow_strength") + , m_time_of_day("f_timeofday") + , m_shadowfar("f_shadowfar") + , m_camera_pos("CameraPos") + , m_shadow_texture("ShadowMapSampler") + , m_perspective_bias0_vertex("xyPerspectiveBias0") + , m_perspective_bias0_pixel("xyPerspectiveBias0") + , m_perspective_bias1_vertex("xyPerspectiveBias1") + , m_perspective_bias1_pixel("xyPerspectiveBias1") + , m_perspective_zbias_vertex("zPerspectiveBias") + , m_perspective_zbias_pixel("zPerspectiveBias") +#if ENABLE_GLES + , m_world_view("mWorldView") + , m_texture("mTexture") + , m_normal("mNormal") +#endif + {} + ~MainShaderConstantSetter() = default; + + virtual void onSetConstants(video::IMaterialRendererServices *services) override + { + video::IVideoDriver *driver = services->getVideoDriver(); + sanity_check(driver); + + // Set world matrix + core::matrix4 world = driver->getTransform(video::ETS_WORLD); + m_world.set(*reinterpret_cast<float(*)[16]>(world.pointer()), services); + + // Set clip matrix + core::matrix4 worldView; + worldView = driver->getTransform(video::ETS_VIEW); + worldView *= world; + + core::matrix4 worldViewProj; + worldViewProj = driver->getTransform(video::ETS_PROJECTION); + worldViewProj *= worldView; + m_world_view_proj.set(*reinterpret_cast<float(*)[16]>(worldViewProj.pointer()), services); + +#if ENABLE_GLES + core::matrix4 texture = driver->getTransform(video::ETS_TEXTURE_0); + m_world_view.set(*reinterpret_cast<float(*)[16]>(worldView.pointer()), services); + m_texture.set(*reinterpret_cast<float(*)[16]>(texture.pointer()), services); + + core::matrix4 normal; + worldView.getTransposed(normal); + sanity_check(normal.makeInverse()); + float m[9] = { + normal[0], normal[1], normal[2], + normal[4], normal[5], normal[6], + normal[8], normal[9], normal[10], + }; + m_normal.set(m, services); +#endif + + // Set uniforms for Shadow shader + if (ShadowRenderer *shadow = RenderingEngine::get_shadow_renderer()) { + const auto &light = shadow->getDirectionalLight(); + + core::matrix4 shadowViewProj = light.getProjectionMatrix(); + shadowViewProj *= light.getViewMatrix(); + m_shadow_view_proj.set(shadowViewProj.pointer(), services); + + f32 v_LightDirection[3]; + light.getDirection().getAs3Values(v_LightDirection); + m_light_direction.set(v_LightDirection, services); + + f32 TextureResolution = light.getMapResolution(); + m_texture_res.set(&TextureResolution, services); + + f32 ShadowStrength = shadow->getShadowStrength(); + m_shadow_strength.set(&ShadowStrength, services); + + f32 timeOfDay = shadow->getTimeOfDay(); + m_time_of_day.set(&timeOfDay, services); + + f32 shadowFar = shadow->getMaxShadowFar(); + m_shadowfar.set(&shadowFar, services); + + f32 cam_pos[4]; + shadowViewProj.transformVect(cam_pos, light.getPlayerPos()); + m_camera_pos.set(cam_pos, services); + + // I dont like using this hardcoded value. maybe something like + // MAX_TEXTURE - 1 or somthing like that?? + s32 TextureLayerID = 3; + m_shadow_texture.set(&TextureLayerID, services); + + f32 bias0 = shadow->getPerspectiveBiasXY(); + m_perspective_bias0_vertex.set(&bias0, services); + m_perspective_bias0_pixel.set(&bias0, services); + f32 bias1 = 1.0f - bias0 + 1e-5f; + m_perspective_bias1_vertex.set(&bias1, services); + m_perspective_bias1_pixel.set(&bias1, services); + f32 zbias = shadow->getPerspectiveBiasZ(); + m_perspective_zbias_vertex.set(&zbias, services); + m_perspective_zbias_pixel.set(&zbias, services); + } + } +}; + + +class MainShaderConstantSetterFactory : public IShaderConstantSetterFactory +{ +public: + virtual IShaderConstantSetter* create() + { return new MainShaderConstantSetter(); } +}; + + +/* + ShaderSource +*/ + +class ShaderSource : public IWritableShaderSource +{ +public: + ShaderSource(); + + /* + - If shader material specified by name is found from cache, + return the cached id. + - Otherwise generate the shader material, add to cache and return id. + + The id 0 points to a null shader. Its material is EMT_SOLID. + */ + u32 getShaderIdDirect(const std::string &name, + MaterialType material_type, NodeDrawType drawtype) override; + + /* + If shader specified by the name pointed by the id doesn't + exist, create it, then return id. + + Can be called from any thread. If called from some other thread + and not found in cache, the call is queued to the main thread + for processing. + */ + + u32 getShader(const std::string &name, + MaterialType material_type, NodeDrawType drawtype) override; + + ShaderInfo getShaderInfo(u32 id) override; + + // Processes queued shader requests from other threads. + // Shall be called from the main thread. + void processQueue() override; + + // Insert a shader program into the cache without touching the + // filesystem. Shall be called from the main thread. + void insertSourceShader(const std::string &name_of_shader, + const std::string &filename, const std::string &program) override; + + // Rebuild shaders from the current set of source shaders + // Shall be called from the main thread. + void rebuildShaders() override; + + void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) override + { + m_setter_factories.push_back(std::unique_ptr<IShaderConstantSetterFactory>(setter)); + } + +private: + + // The id of the thread that is allowed to use irrlicht directly + std::thread::id m_main_thread; + + // Cache of source shaders + // This should be only accessed from the main thread + SourceShaderCache m_sourcecache; + + // A shader id is index in this array. + // The first position contains a dummy shader. + std::vector<ShaderInfo> m_shaderinfo_cache; + // The former container is behind this mutex + std::mutex m_shaderinfo_cache_mutex; + + // Queued shader fetches (to be processed by the main thread) + RequestQueue<std::string, u32, u8, u8> m_get_shader_queue; + + // Global constant setter factories + std::vector<std::unique_ptr<IShaderConstantSetterFactory>> m_setter_factories; + + // Generate shader given the shader name. + ShaderInfo generateShader(const std::string &name, + MaterialType material_type, NodeDrawType drawtype); +}; + +IWritableShaderSource *createShaderSource() +{ + return new ShaderSource(); +} + +ShaderSource::ShaderSource() +{ + m_main_thread = std::this_thread::get_id(); + + // Add a dummy ShaderInfo as the first index, named "" + m_shaderinfo_cache.emplace_back(); + + // Add main global constant setter + addShaderConstantSetterFactory(new MainShaderConstantSetterFactory()); +} + +u32 ShaderSource::getShader(const std::string &name, + MaterialType material_type, NodeDrawType drawtype) +{ + /* + Get shader + */ + + if (std::this_thread::get_id() == m_main_thread) { + return getShaderIdDirect(name, material_type, drawtype); + } + + /*errorstream<<"getShader(): Queued: name=\""<<name<<"\""<<std::endl;*/ + + // We're gonna ask the result to be put into here + + static ResultQueue<std::string, u32, u8, u8> result_queue; + + // Throw a request in + m_get_shader_queue.add(name, 0, 0, &result_queue); + + /* infostream<<"Waiting for shader from main thread, name=\"" + <<name<<"\""<<std::endl;*/ + + while(true) { + GetResult<std::string, u32, u8, u8> + result = result_queue.pop_frontNoEx(); + + if (result.key == name) { + return result.item; + } + + errorstream << "Got shader with invalid name: " << result.key << std::endl; + } + + infostream << "getShader(): Failed" << std::endl; + + return 0; +} + +/* + This method generates all the shaders +*/ +u32 ShaderSource::getShaderIdDirect(const std::string &name, + MaterialType material_type, NodeDrawType drawtype) +{ + //infostream<<"getShaderIdDirect(): name=\""<<name<<"\""<<std::endl; + + // Empty name means shader 0 + if (name.empty()) { + infostream<<"getShaderIdDirect(): name is empty"<<std::endl; + return 0; + } + + // Check if already have such instance + for(u32 i=0; i<m_shaderinfo_cache.size(); i++){ + ShaderInfo *info = &m_shaderinfo_cache[i]; + if(info->name == name && info->material_type == material_type && + info->drawtype == drawtype) + return i; + } + + /* + Calling only allowed from main thread + */ + if (std::this_thread::get_id() != m_main_thread) { + errorstream<<"ShaderSource::getShaderIdDirect() " + "called not from main thread"<<std::endl; + return 0; + } + + ShaderInfo info = generateShader(name, material_type, drawtype); + + /* + Add shader to caches (add dummy shaders too) + */ + + MutexAutoLock lock(m_shaderinfo_cache_mutex); + + u32 id = m_shaderinfo_cache.size(); + m_shaderinfo_cache.push_back(info); + + infostream<<"getShaderIdDirect(): " + <<"Returning id="<<id<<" for name \""<<name<<"\""<<std::endl; + + return id; +} + + +ShaderInfo ShaderSource::getShaderInfo(u32 id) +{ + MutexAutoLock lock(m_shaderinfo_cache_mutex); + + if(id >= m_shaderinfo_cache.size()) + return ShaderInfo(); + + return m_shaderinfo_cache[id]; +} + +void ShaderSource::processQueue() +{ + + +} + +void ShaderSource::insertSourceShader(const std::string &name_of_shader, + const std::string &filename, const std::string &program) +{ + /*infostream<<"ShaderSource::insertSourceShader(): " + "name_of_shader=\""<<name_of_shader<<"\", " + "filename=\""<<filename<<"\""<<std::endl;*/ + + sanity_check(std::this_thread::get_id() == m_main_thread); + + m_sourcecache.insert(name_of_shader, filename, program, true); +} + +void ShaderSource::rebuildShaders() +{ + MutexAutoLock lock(m_shaderinfo_cache_mutex); + + /*// Oh well... just clear everything, they'll load sometime. + m_shaderinfo_cache.clear(); + m_name_to_id.clear();*/ + + /* + FIXME: Old shader materials can't be deleted in Irrlicht, + or can they? + (This would be nice to do in the destructor too) + */ + + // Recreate shaders + for (ShaderInfo &i : m_shaderinfo_cache) { + ShaderInfo *info = &i; + if (!info->name.empty()) { + *info = generateShader(info->name, info->material_type, info->drawtype); + } + } +} + + +ShaderInfo ShaderSource::generateShader(const std::string &name, + MaterialType material_type, NodeDrawType drawtype) +{ + ShaderInfo shaderinfo; + shaderinfo.name = name; + shaderinfo.material_type = material_type; + shaderinfo.drawtype = drawtype; + switch (material_type) { + case TILE_MATERIAL_OPAQUE: + case TILE_MATERIAL_LIQUID_OPAQUE: + case TILE_MATERIAL_WAVING_LIQUID_OPAQUE: + shaderinfo.base_material = video::EMT_SOLID; + break; + case TILE_MATERIAL_ALPHA: + case TILE_MATERIAL_PLAIN_ALPHA: + case TILE_MATERIAL_LIQUID_TRANSPARENT: + case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT: + shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + break; + case TILE_MATERIAL_BASIC: + case TILE_MATERIAL_PLAIN: + case TILE_MATERIAL_WAVING_LEAVES: + case TILE_MATERIAL_WAVING_PLANTS: + case TILE_MATERIAL_WAVING_LIQUID_BASIC: + shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + break; + } + shaderinfo.material = shaderinfo.base_material; + + bool enable_shaders = g_settings->getBool("enable_shaders"); + if (!enable_shaders) + return shaderinfo; + + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + if (!driver->queryFeature(video::EVDF_ARB_GLSL)) { + errorstream << "Shaders are enabled but GLSL is not supported by the driver\n"; + return shaderinfo; + } + video::IGPUProgrammingServices *gpu = driver->getGPUProgrammingServices(); + + // Create shaders header + bool use_gles = false; +#if ENABLE_GLES + use_gles = driver->getDriverType() == video::EDT_OGLES2; +#endif + std::stringstream shaders_header; + shaders_header + << std::noboolalpha + << std::showpoint // for GLSL ES + ; + std::string vertex_header, fragment_header, geometry_header; + if (use_gles) { + shaders_header << R"( + #version 100 + )"; + vertex_header = R"( + precision mediump float; + + uniform highp mat4 mWorldView; + uniform highp mat4 mWorldViewProj; + uniform mediump mat4 mTexture; + uniform mediump mat3 mNormal; + + attribute highp vec4 inVertexPosition; + attribute lowp vec4 inVertexColor; + attribute mediump vec4 inTexCoord0; + attribute mediump vec3 inVertexNormal; + attribute mediump vec4 inVertexTangent; + attribute mediump vec4 inVertexBinormal; + )"; + fragment_header = R"( + precision mediump float; + )"; + } else { + shaders_header << R"( + #version 120 + #define lowp + #define mediump + #define highp + )"; + vertex_header = R"( + #define mWorldView gl_ModelViewMatrix + #define mWorldViewProj gl_ModelViewProjectionMatrix + #define mTexture (gl_TextureMatrix[0]) + #define mNormal gl_NormalMatrix + + #define inVertexPosition gl_Vertex + #define inVertexColor gl_Color + #define inTexCoord0 gl_MultiTexCoord0 + #define inVertexNormal gl_Normal + #define inVertexTangent gl_MultiTexCoord1 + #define inVertexBinormal gl_MultiTexCoord2 + )"; + } + + // Since this is the first time we're using the GL bindings be extra careful. + // This should be removed before 5.6.0 or similar. + if (!GL.GetString) { + errorstream << "OpenGL procedures were not loaded correctly, " + "please open a bug report with details about your platform/OS." << std::endl; + abort(); + } + + bool use_discard = use_gles; + // For renderers that should use discard instead of GL_ALPHA_TEST + const char *renderer = reinterpret_cast<const char*>(GL.GetString(GL.RENDERER)); + if (strstr(renderer, "GC7000")) + use_discard = true; + if (use_discard) { + if (shaderinfo.base_material == video::EMT_TRANSPARENT_ALPHA_CHANNEL) + shaders_header << "#define USE_DISCARD 1\n"; + else if (shaderinfo.base_material == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF) + shaders_header << "#define USE_DISCARD_REF 1\n"; + } + +#define PROVIDE(constant) shaders_header << "#define " #constant " " << (int)constant << "\n" + + PROVIDE(NDT_NORMAL); + PROVIDE(NDT_AIRLIKE); + PROVIDE(NDT_LIQUID); + PROVIDE(NDT_FLOWINGLIQUID); + PROVIDE(NDT_GLASSLIKE); + PROVIDE(NDT_ALLFACES); + PROVIDE(NDT_ALLFACES_OPTIONAL); + PROVIDE(NDT_TORCHLIKE); + PROVIDE(NDT_SIGNLIKE); + PROVIDE(NDT_PLANTLIKE); + PROVIDE(NDT_FENCELIKE); + PROVIDE(NDT_RAILLIKE); + PROVIDE(NDT_NODEBOX); + PROVIDE(NDT_GLASSLIKE_FRAMED); + PROVIDE(NDT_FIRELIKE); + PROVIDE(NDT_GLASSLIKE_FRAMED_OPTIONAL); + PROVIDE(NDT_PLANTLIKE_ROOTED); + + PROVIDE(TILE_MATERIAL_BASIC); + PROVIDE(TILE_MATERIAL_ALPHA); + PROVIDE(TILE_MATERIAL_LIQUID_TRANSPARENT); + PROVIDE(TILE_MATERIAL_LIQUID_OPAQUE); + PROVIDE(TILE_MATERIAL_WAVING_LEAVES); + PROVIDE(TILE_MATERIAL_WAVING_PLANTS); + PROVIDE(TILE_MATERIAL_OPAQUE); + PROVIDE(TILE_MATERIAL_WAVING_LIQUID_BASIC); + PROVIDE(TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT); + PROVIDE(TILE_MATERIAL_WAVING_LIQUID_OPAQUE); + PROVIDE(TILE_MATERIAL_PLAIN); + PROVIDE(TILE_MATERIAL_PLAIN_ALPHA); + +#undef PROVIDE + + shaders_header << "#define MATERIAL_TYPE " << (int)material_type << "\n"; + shaders_header << "#define DRAW_TYPE " << (int)drawtype << "\n"; + + bool enable_waving_water = g_settings->getBool("enable_waving_water"); + shaders_header << "#define ENABLE_WAVING_WATER " << enable_waving_water << "\n"; + if (enable_waving_water) { + shaders_header << "#define WATER_WAVE_HEIGHT " << g_settings->getFloat("water_wave_height") << "\n"; + shaders_header << "#define WATER_WAVE_LENGTH " << g_settings->getFloat("water_wave_length") << "\n"; + shaders_header << "#define WATER_WAVE_SPEED " << g_settings->getFloat("water_wave_speed") << "\n"; + } + + shaders_header << "#define ENABLE_WAVING_LEAVES " << g_settings->getBool("enable_waving_leaves") << "\n"; + shaders_header << "#define ENABLE_WAVING_PLANTS " << g_settings->getBool("enable_waving_plants") << "\n"; + shaders_header << "#define ENABLE_TONE_MAPPING " << g_settings->getBool("tone_mapping") << "\n"; + + shaders_header << "#define FOG_START " << core::clamp(g_settings->getFloat("fog_start"), 0.0f, 0.99f) << "\n"; + + if (g_settings->getBool("enable_dynamic_shadows")) { + shaders_header << "#define ENABLE_DYNAMIC_SHADOWS 1\n"; + if (g_settings->getBool("shadow_map_color")) + shaders_header << "#define COLORED_SHADOWS 1\n"; + + if (g_settings->getBool("shadow_poisson_filter")) + shaders_header << "#define POISSON_FILTER 1\n"; + + s32 shadow_filter = g_settings->getS32("shadow_filters"); + shaders_header << "#define SHADOW_FILTER " << shadow_filter << "\n"; + + float shadow_soft_radius = g_settings->getFloat("shadow_soft_radius"); + if (shadow_soft_radius < 1.0f) + shadow_soft_radius = 1.0f; + shaders_header << "#define SOFTSHADOWRADIUS " << shadow_soft_radius << "\n"; + } + + shaders_header << "#line 0\n"; // reset the line counter for meaningful diagnostics + + std::string common_header = shaders_header.str(); + + std::string vertex_shader = m_sourcecache.getOrLoad(name, "opengl_vertex.glsl"); + std::string fragment_shader = m_sourcecache.getOrLoad(name, "opengl_fragment.glsl"); + std::string geometry_shader = m_sourcecache.getOrLoad(name, "opengl_geometry.glsl"); + + vertex_shader = common_header + vertex_header + vertex_shader; + fragment_shader = common_header + fragment_header + fragment_shader; + const char *geometry_shader_ptr = nullptr; // optional + if (!geometry_shader.empty()) { + geometry_shader = common_header + geometry_header + geometry_shader; + geometry_shader_ptr = geometry_shader.c_str(); + } + + irr_ptr<ShaderCallback> cb{new ShaderCallback(m_setter_factories)}; + infostream<<"Compiling high level shaders for "<<name<<std::endl; + s32 shadermat = gpu->addHighLevelShaderMaterial( + vertex_shader.c_str(), nullptr, video::EVST_VS_1_1, + fragment_shader.c_str(), nullptr, video::EPST_PS_1_1, + geometry_shader_ptr, nullptr, video::EGST_GS_4_0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLES, 0, + cb.get(), shaderinfo.base_material, 1); + if (shadermat == -1) { + errorstream<<"generate_shader(): " + "failed to generate \""<<name<<"\", " + "addHighLevelShaderMaterial failed." + <<std::endl; + dumpShaderProgram(warningstream, "Vertex", vertex_shader); + dumpShaderProgram(warningstream, "Fragment", fragment_shader); + dumpShaderProgram(warningstream, "Geometry", geometry_shader); + return shaderinfo; + } + + // Apply the newly created material type + shaderinfo.material = (video::E_MATERIAL_TYPE) shadermat; + return shaderinfo; +} + +void dumpShaderProgram(std::ostream &output_stream, + const std::string &program_type, const std::string &program) +{ + output_stream << program_type << " shader program:" << std::endl << + "----------------------------------" << std::endl; + size_t pos = 0; + size_t prev = 0; + s16 line = 1; + while ((pos = program.find('\n', prev)) != std::string::npos) { + output_stream << line++ << ": "<< program.substr(prev, pos - prev) << + std::endl; + prev = pos + 1; + } + output_stream << line << ": " << program.substr(prev) << std::endl << + "End of " << program_type << " shader program." << std::endl << + " " << std::endl; +} diff --git a/src/client/shader.h b/src/client/shader.h new file mode 100644 index 0000000..49a5631 --- /dev/null +++ b/src/client/shader.h @@ -0,0 +1,156 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013 Kahrl <kahrl@gmx.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +#include <IMaterialRendererServices.h> +#include <string> +#include "tile.h" +#include "nodedef.h" + +class IGameDef; + +/* + shader.{h,cpp}: Shader handling stuff. +*/ + +/* + Gets the path to a shader by first checking if the file + name_of_shader/filename + exists in shader_path and if not, using the data path. + + If not found, returns "". + + Utilizes a thread-safe cache. +*/ +std::string getShaderPath(const std::string &name_of_shader, + const std::string &filename); + +struct ShaderInfo { + std::string name = ""; + video::E_MATERIAL_TYPE base_material = video::EMT_SOLID; + video::E_MATERIAL_TYPE material = video::EMT_SOLID; + NodeDrawType drawtype = NDT_NORMAL; + MaterialType material_type = TILE_MATERIAL_BASIC; + + ShaderInfo() = default; + virtual ~ShaderInfo() = default; +}; + +/* + Setter of constants for shaders +*/ + +namespace irr { namespace video { + class IMaterialRendererServices; +} } + + +class IShaderConstantSetter { +public: + virtual ~IShaderConstantSetter() = default; + virtual void onSetConstants(video::IMaterialRendererServices *services) = 0; + virtual void onSetMaterial(const video::SMaterial& material) + { } +}; + + +class IShaderConstantSetterFactory { +public: + virtual ~IShaderConstantSetterFactory() = default; + virtual IShaderConstantSetter* create() = 0; +}; + + +template <typename T, std::size_t count=1> +class CachedShaderSetting { + const char *m_name; + T m_sent[count]; + bool has_been_set = false; + bool is_pixel; +protected: + CachedShaderSetting(const char *name, bool is_pixel) : + m_name(name), is_pixel(is_pixel) + {} +public: + void set(const T value[count], video::IMaterialRendererServices *services) + { + if (has_been_set && std::equal(m_sent, m_sent + count, value)) + return; + if (is_pixel) + services->setPixelShaderConstant(services->getPixelShaderConstantID(m_name), value, count); + else + services->setVertexShaderConstant(services->getVertexShaderConstantID(m_name), value, count); + + std::copy(value, value + count, m_sent); + has_been_set = true; + } +}; + +template <typename T, std::size_t count = 1> +class CachedPixelShaderSetting : public CachedShaderSetting<T, count> { +public: + CachedPixelShaderSetting(const char *name) : + CachedShaderSetting<T, count>(name, true){} +}; + +template <typename T, std::size_t count = 1> +class CachedVertexShaderSetting : public CachedShaderSetting<T, count> { +public: + CachedVertexShaderSetting(const char *name) : + CachedShaderSetting<T, count>(name, false){} +}; + + +/* + ShaderSource creates and caches shaders. +*/ + +class IShaderSource { +public: + IShaderSource() = default; + virtual ~IShaderSource() = default; + + virtual u32 getShaderIdDirect(const std::string &name, + MaterialType material_type, NodeDrawType drawtype = NDT_NORMAL){return 0;} + virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();} + virtual u32 getShader(const std::string &name, + MaterialType material_type, NodeDrawType drawtype = NDT_NORMAL){return 0;} +}; + +class IWritableShaderSource : public IShaderSource { +public: + IWritableShaderSource() = default; + virtual ~IWritableShaderSource() = default; + + virtual void processQueue()=0; + virtual void insertSourceShader(const std::string &name_of_shader, + const std::string &filename, const std::string &program)=0; + virtual void rebuildShaders()=0; + + /// @note Takes ownership of @p setter. + virtual void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) = 0; +}; + +IWritableShaderSource *createShaderSource(); + +void dumpShaderProgram(std::ostream &output_stream, + const std::string &program_type, const std::string &program); diff --git a/src/client/shadows/dynamicshadows.cpp b/src/client/shadows/dynamicshadows.cpp new file mode 100644 index 0000000..9f26ba9 --- /dev/null +++ b/src/client/shadows/dynamicshadows.cpp @@ -0,0 +1,191 @@ +/* +Minetest +Copyright (C) 2021 Liso <anlismon@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <cmath> + +#include "client/shadows/dynamicshadows.h" +#include "client/client.h" +#include "client/clientenvironment.h" +#include "client/clientmap.h" +#include "client/camera.h" + +using m4f = core::matrix4; + +static v3f quantizeDirection(v3f direction, float step) +{ + + float yaw = std::atan2(direction.Z, direction.X); + float pitch = std::asin(direction.Y); // assume look is normalized + + yaw = std::floor(yaw / step) * step; + pitch = std::floor(pitch / step) * step; + + return v3f(std::cos(yaw)*std::cos(pitch), std::sin(pitch), std::sin(yaw)*std::cos(pitch)); +} + +void DirectionalLight::createSplitMatrices(const Camera *cam) +{ + const float DISTANCE_STEP = BS * 2.0; // 2 meters + v3f newCenter; + v3f look = cam->getDirection(); + look = quantizeDirection(look, M_PI / 12.0); // 15 degrees + + // camera view tangents + float tanFovY = tanf(cam->getFovY() * 0.5f); + float tanFovX = tanf(cam->getFovX() * 0.5f); + + // adjusted frustum boundaries + float sfNear = future_frustum.zNear; + float sfFar = adjustDist(future_frustum.zFar, cam->getFovY()); + + // adjusted camera positions + v3f cam_pos_world = cam->getPosition(); + cam_pos_world = v3f( + floor(cam_pos_world.X / DISTANCE_STEP) * DISTANCE_STEP, + floor(cam_pos_world.Y / DISTANCE_STEP) * DISTANCE_STEP, + floor(cam_pos_world.Z / DISTANCE_STEP) * DISTANCE_STEP); + v3f cam_pos_scene = v3f(cam_pos_world.X - cam->getOffset().X * BS, + cam_pos_world.Y - cam->getOffset().Y * BS, + cam_pos_world.Z - cam->getOffset().Z * BS); + cam_pos_scene += look * sfNear; + cam_pos_world += look * sfNear; + + // center point of light frustum + v3f center_scene = cam_pos_scene + look * 0.35 * (sfFar - sfNear); + v3f center_world = cam_pos_world + look * 0.35 * (sfFar - sfNear); + + // Create a vector to the frustum far corner + const v3f &viewUp = cam->getCameraNode()->getUpVector(); + v3f viewRight = look.crossProduct(viewUp); + + v3f farCorner = (look + viewRight * tanFovX + viewUp * tanFovY).normalize(); + // Compute the frustumBoundingSphere radius + v3f boundVec = (cam_pos_scene + farCorner * sfFar) - center_scene; + float radius = boundVec.getLength(); + float length = radius * 3.0f; + v3f eye_displacement = quantizeDirection(direction, M_PI / 2880 /*15 seconds*/) * length; + + // we must compute the viewmat with the position - the camera offset + // but the future_frustum position must be the actual world position + v3f eye = center_scene - eye_displacement; + future_frustum.player = cam_pos_scene; + future_frustum.position = center_world - eye_displacement; + future_frustum.length = length; + future_frustum.radius = radius; + future_frustum.ViewMat.buildCameraLookAtMatrixLH(eye, center_scene, v3f(0.0f, 1.0f, 0.0f)); + future_frustum.ProjOrthMat.buildProjectionMatrixOrthoLH(radius, radius, + 0.0f, length, false); + future_frustum.camera_offset = cam->getOffset(); +} + +DirectionalLight::DirectionalLight(const u32 shadowMapResolution, + const v3f &position, video::SColorf lightColor, + f32 farValue) : + diffuseColor(lightColor), + farPlane(farValue), mapRes(shadowMapResolution), pos(position) +{} + +void DirectionalLight::update_frustum(const Camera *cam, Client *client, bool force) +{ + if (dirty && !force) + return; + + float zNear = cam->getCameraNode()->getNearValue(); + float zFar = getMaxFarValue(); + if (!client->getEnv().getClientMap().getControl().range_all) + zFar = MYMIN(zFar, client->getEnv().getClientMap().getControl().wanted_range * BS); + + /////////////////////////////////// + // update splits near and fars + future_frustum.zNear = zNear; + future_frustum.zFar = zFar; + + // update shadow frustum + createSplitMatrices(cam); + // get the draw list for shadows + client->getEnv().getClientMap().updateDrawListShadow( + getPosition(), getDirection(), future_frustum.radius, future_frustum.length); + should_update_map_shadow = true; + dirty = true; + + // when camera offset changes, adjust the current frustum view matrix to avoid flicker + v3s16 cam_offset = cam->getOffset(); + if (cam_offset != shadow_frustum.camera_offset) { + v3f rotated_offset; + shadow_frustum.ViewMat.rotateVect(rotated_offset, intToFloat(cam_offset - shadow_frustum.camera_offset, BS)); + shadow_frustum.ViewMat.setTranslation(shadow_frustum.ViewMat.getTranslation() + rotated_offset); + shadow_frustum.player += intToFloat(shadow_frustum.camera_offset - cam->getOffset(), BS); + shadow_frustum.camera_offset = cam_offset; + } +} + +void DirectionalLight::commitFrustum() +{ + if (!dirty) + return; + + shadow_frustum = future_frustum; + dirty = false; +} + +void DirectionalLight::setDirection(v3f dir) +{ + direction = -dir; + direction.normalize(); +} + +v3f DirectionalLight::getPosition() const +{ + return shadow_frustum.position; +} + +v3f DirectionalLight::getPlayerPos() const +{ + return shadow_frustum.player; +} + +v3f DirectionalLight::getFuturePlayerPos() const +{ + return future_frustum.player; +} + +const m4f &DirectionalLight::getViewMatrix() const +{ + return shadow_frustum.ViewMat; +} + +const m4f &DirectionalLight::getProjectionMatrix() const +{ + return shadow_frustum.ProjOrthMat; +} + +const m4f &DirectionalLight::getFutureViewMatrix() const +{ + return future_frustum.ViewMat; +} + +const m4f &DirectionalLight::getFutureProjectionMatrix() const +{ + return future_frustum.ProjOrthMat; +} + +m4f DirectionalLight::getViewProjMatrix() +{ + return shadow_frustum.ProjOrthMat * shadow_frustum.ViewMat; +} diff --git a/src/client/shadows/dynamicshadows.h b/src/client/shadows/dynamicshadows.h new file mode 100644 index 0000000..6e9d96b --- /dev/null +++ b/src/client/shadows/dynamicshadows.h @@ -0,0 +1,120 @@ +/* +Minetest +Copyright (C) 2021 Liso <anlismon@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +#include <matrix4.h> +#include "util/basic_macros.h" +#include "constants.h" + +class Camera; +class Client; + +struct shadowFrustum +{ + f32 zNear{0.0f}; + f32 zFar{0.0f}; + f32 length{0.0f}; + f32 radius{0.0f}; + core::matrix4 ProjOrthMat; + core::matrix4 ViewMat; + v3f position; + v3f player; + v3s16 camera_offset; +}; + +class DirectionalLight +{ +public: + DirectionalLight(const u32 shadowMapResolution, + const v3f &position, + video::SColorf lightColor = video::SColor(0xffffffff), + f32 farValue = 100.0f); + ~DirectionalLight() = default; + + //DISABLE_CLASS_COPY(DirectionalLight) + + void update_frustum(const Camera *cam, Client *client, bool force = false); + + // when set direction is updated to negative normalized(direction) + void setDirection(v3f dir); + v3f getDirection() const{ + return direction; + }; + v3f getPosition() const; + v3f getPlayerPos() const; + v3f getFuturePlayerPos() const; + + /// Gets the light's matrices. + const core::matrix4 &getViewMatrix() const; + const core::matrix4 &getProjectionMatrix() const; + const core::matrix4 &getFutureViewMatrix() const; + const core::matrix4 &getFutureProjectionMatrix() const; + core::matrix4 getViewProjMatrix(); + + /// Gets the light's maximum far value, i.e. the shadow boundary + f32 getMaxFarValue() const + { + return farPlane * BS; + } + + /// Gets the current far value of the light + f32 getFarValue() const + { + return shadow_frustum.zFar; + } + + + /// Gets the light's color. + const video::SColorf &getLightColor() const + { + return diffuseColor; + } + + /// Sets the light's color. + void setLightColor(const video::SColorf &lightColor) + { + diffuseColor = lightColor; + } + + /// Gets the shadow map resolution for this light. + u32 getMapResolution() const + { + return mapRes; + } + + bool should_update_map_shadow{true}; + + void commitFrustum(); + +private: + void createSplitMatrices(const Camera *cam); + + video::SColorf diffuseColor; + + f32 farPlane; + u32 mapRes; + + v3f pos; + v3f direction{0}; + shadowFrustum shadow_frustum; + shadowFrustum future_frustum; + bool dirty{false}; +}; diff --git a/src/client/shadows/dynamicshadowsrender.cpp b/src/client/shadows/dynamicshadowsrender.cpp new file mode 100644 index 0000000..944deb8 --- /dev/null +++ b/src/client/shadows/dynamicshadowsrender.cpp @@ -0,0 +1,709 @@ +/* +Minetest +Copyright (C) 2021 Liso <anlismon@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <cstring> +#include <cmath> +#include "client/shadows/dynamicshadowsrender.h" +#include "client/shadows/shadowsScreenQuad.h" +#include "client/shadows/shadowsshadercallbacks.h" +#include "settings.h" +#include "filesys.h" +#include "util/string.h" +#include "client/shader.h" +#include "client/client.h" +#include "client/clientmap.h" +#include "profiler.h" + +ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) : + m_smgr(device->getSceneManager()), m_driver(device->getVideoDriver()), + m_client(client), m_current_frame(0), + m_perspective_bias_xy(0.8), m_perspective_bias_z(0.5) +{ + (void) m_client; + + m_shadows_supported = true; // assume shadows supported. We will check actual support in initialize + m_shadows_enabled = true; + + m_shadow_strength_gamma = g_settings->getFloat("shadow_strength_gamma"); + if (std::isnan(m_shadow_strength_gamma)) + m_shadow_strength_gamma = 1.0f; + m_shadow_strength_gamma = core::clamp(m_shadow_strength_gamma, 0.1f, 10.0f); + + m_shadow_map_max_distance = g_settings->getFloat("shadow_map_max_distance"); + + m_shadow_map_texture_size = g_settings->getFloat("shadow_map_texture_size"); + + m_shadow_map_texture_32bit = g_settings->getBool("shadow_map_texture_32bit"); + m_shadow_map_colored = g_settings->getBool("shadow_map_color"); + m_shadow_samples = g_settings->getS32("shadow_filters"); + m_map_shadow_update_frames = g_settings->getS16("shadow_update_frames"); +} + +ShadowRenderer::~ShadowRenderer() +{ + // call to disable releases dynamically allocated resources + disable(); + + if (m_shadow_depth_cb) + delete m_shadow_depth_cb; + if (m_shadow_depth_entity_cb) + delete m_shadow_depth_entity_cb; + if (m_shadow_depth_trans_cb) + delete m_shadow_depth_trans_cb; + if (m_shadow_mix_cb) + delete m_shadow_mix_cb; + m_shadow_node_array.clear(); + m_light_list.clear(); +} + +void ShadowRenderer::disable() +{ + m_shadows_enabled = false; + if (shadowMapTextureFinal) { + m_driver->setRenderTarget(shadowMapTextureFinal, true, true, + video::SColor(255, 255, 255, 255)); + m_driver->setRenderTarget(0, false, false); + } + + if (shadowMapTextureDynamicObjects) { + m_driver->removeTexture(shadowMapTextureDynamicObjects); + shadowMapTextureDynamicObjects = nullptr; + } + + if (shadowMapTextureFinal) { + m_driver->removeTexture(shadowMapTextureFinal); + shadowMapTextureFinal = nullptr; + } + + if (shadowMapTextureColors) { + m_driver->removeTexture(shadowMapTextureColors); + shadowMapTextureColors = nullptr; + } + + if (shadowMapClientMap) { + m_driver->removeTexture(shadowMapClientMap); + shadowMapClientMap = nullptr; + } + + if (shadowMapClientMapFuture) { + m_driver->removeTexture(shadowMapClientMapFuture); + shadowMapClientMapFuture = nullptr; + } + + for (auto node : m_shadow_node_array) + if (node.shadowMode & E_SHADOW_MODE::ESM_RECEIVE) + node.node->setMaterialTexture(TEXTURE_LAYER_SHADOW, nullptr); +} + +void ShadowRenderer::initialize() +{ + auto *gpu = m_driver->getGPUProgrammingServices(); + + // we need glsl + if (m_shadows_supported && gpu && m_driver->queryFeature(video::EVDF_ARB_GLSL)) { + createShaders(); + } else { + m_shadows_supported = false; + + warningstream << "Shadows: GLSL Shader not supported on this system." + << std::endl; + return; + } + + m_texture_format = m_shadow_map_texture_32bit + ? video::ECOLOR_FORMAT::ECF_R32F + : video::ECOLOR_FORMAT::ECF_R16F; + + m_texture_format_color = m_shadow_map_texture_32bit + ? video::ECOLOR_FORMAT::ECF_G32R32F + : video::ECOLOR_FORMAT::ECF_G16R16F; + + m_shadows_enabled &= m_shadows_supported; +} + + +size_t ShadowRenderer::addDirectionalLight() +{ + m_light_list.emplace_back(m_shadow_map_texture_size, + v3f(0.f, 0.f, 0.f), + video::SColor(255, 255, 255, 255), m_shadow_map_max_distance); + return m_light_list.size() - 1; +} + +DirectionalLight &ShadowRenderer::getDirectionalLight(u32 index) +{ + return m_light_list[index]; +} + +size_t ShadowRenderer::getDirectionalLightCount() const +{ + return m_light_list.size(); +} + +f32 ShadowRenderer::getMaxShadowFar() const +{ + if (!m_light_list.empty()) { + float zMax = m_light_list[0].getFarValue(); + return zMax; + } + return 0.0f; +} + +void ShadowRenderer::setShadowIntensity(float shadow_intensity) +{ + m_shadow_strength = pow(shadow_intensity, 1.0f / m_shadow_strength_gamma); + if (m_shadow_strength > 1E-2) + enable(); + else + disable(); +} + +void ShadowRenderer::addNodeToShadowList( + scene::ISceneNode *node, E_SHADOW_MODE shadowMode) +{ + if (!node) + return; + m_shadow_node_array.emplace_back(node, shadowMode); + if (shadowMode == ESM_RECEIVE || shadowMode == ESM_BOTH) + node->setMaterialTexture(TEXTURE_LAYER_SHADOW, shadowMapTextureFinal); +} + +void ShadowRenderer::removeNodeFromShadowList(scene::ISceneNode *node) +{ + if (!node) + return; + node->setMaterialTexture(TEXTURE_LAYER_SHADOW, nullptr); + for (auto it = m_shadow_node_array.begin(); it != m_shadow_node_array.end();) { + if (it->node == node) { + it = m_shadow_node_array.erase(it); + break; + } else { + ++it; + } + } +} + +void ShadowRenderer::updateSMTextures() +{ + if (!m_shadows_enabled || m_smgr->getActiveCamera() == nullptr) { + return; + } + + if (!shadowMapTextureDynamicObjects) { + + shadowMapTextureDynamicObjects = getSMTexture( + std::string("shadow_dynamic_") + itos(m_shadow_map_texture_size), + m_texture_format, true); + assert(shadowMapTextureDynamicObjects != nullptr); + } + + if (!shadowMapClientMap) { + + shadowMapClientMap = getSMTexture( + std::string("shadow_clientmap_") + itos(m_shadow_map_texture_size), + m_shadow_map_colored ? m_texture_format_color : m_texture_format, + true); + assert(shadowMapClientMap != nullptr); + } + + if (!shadowMapClientMapFuture && m_map_shadow_update_frames > 1) { + shadowMapClientMapFuture = getSMTexture( + std::string("shadow_clientmap_bb_") + itos(m_shadow_map_texture_size), + m_shadow_map_colored ? m_texture_format_color : m_texture_format, + true); + assert(shadowMapClientMapFuture != nullptr); + } + + if (m_shadow_map_colored && !shadowMapTextureColors) { + shadowMapTextureColors = getSMTexture( + std::string("shadow_colored_") + itos(m_shadow_map_texture_size), + m_shadow_map_colored ? m_texture_format_color : m_texture_format, + true); + assert(shadowMapTextureColors != nullptr); + } + + // The merge all shadowmaps texture + if (!shadowMapTextureFinal) { + video::ECOLOR_FORMAT frt; + if (m_shadow_map_texture_32bit) { + if (m_shadow_map_colored) + frt = video::ECOLOR_FORMAT::ECF_A32B32G32R32F; + else + frt = video::ECOLOR_FORMAT::ECF_R32F; + } else { + if (m_shadow_map_colored) + frt = video::ECOLOR_FORMAT::ECF_A16B16G16R16F; + else + frt = video::ECOLOR_FORMAT::ECF_R16F; + } + shadowMapTextureFinal = getSMTexture( + std::string("shadowmap_final_") + itos(m_shadow_map_texture_size), + frt, true); + assert(shadowMapTextureFinal != nullptr); + + for (auto &node : m_shadow_node_array) + if (node.shadowMode == ESM_RECEIVE || node.shadowMode == ESM_BOTH) + node.node->setMaterialTexture(TEXTURE_LAYER_SHADOW, shadowMapTextureFinal); + } + + if (!m_shadow_node_array.empty() && !m_light_list.empty()) { + bool reset_sm_texture = false; + + // detect if SM should be regenerated + for (DirectionalLight &light : m_light_list) { + if (light.should_update_map_shadow || m_force_update_shadow_map) { + light.should_update_map_shadow = false; + m_current_frame = 0; + reset_sm_texture = true; + } + } + + video::ITexture* shadowMapTargetTexture = shadowMapClientMapFuture; + if (shadowMapTargetTexture == nullptr) + shadowMapTargetTexture = shadowMapClientMap; + + // Update SM incrementally: + for (DirectionalLight &light : m_light_list) { + // Static shader values. + for (auto cb : {m_shadow_depth_cb, m_shadow_depth_entity_cb, m_shadow_depth_trans_cb}) + if (cb) { + cb->MapRes = (f32)m_shadow_map_texture_size; + cb->MaxFar = (f32)m_shadow_map_max_distance * BS; + cb->PerspectiveBiasXY = getPerspectiveBiasXY(); + cb->PerspectiveBiasZ = getPerspectiveBiasZ(); + cb->CameraPos = light.getFuturePlayerPos(); + } + + // set the Render Target + // right now we can only render in usual RTT, not + // Depth texture is available in irrlicth maybe we + // should put some gl* fn here + + + if (m_current_frame < m_map_shadow_update_frames || m_force_update_shadow_map) { + m_driver->setRenderTarget(shadowMapTargetTexture, reset_sm_texture, true, + video::SColor(255, 255, 255, 255)); + renderShadowMap(shadowMapTargetTexture, light); + + // Render transparent part in one pass. + // This is also handled in ClientMap. + if (m_current_frame == m_map_shadow_update_frames - 1 || m_force_update_shadow_map) { + if (m_shadow_map_colored) { + m_driver->setRenderTarget(0, false, false); + m_driver->setRenderTarget(shadowMapTextureColors, + true, false, video::SColor(255, 255, 255, 255)); + } + renderShadowMap(shadowMapTextureColors, light, + scene::ESNRP_TRANSPARENT); + } + m_driver->setRenderTarget(0, false, false); + } + + reset_sm_texture = false; + } // end for lights + + // move to the next section + if (m_current_frame <= m_map_shadow_update_frames) + ++m_current_frame; + + // pass finished, swap textures and commit light changes + if (m_current_frame == m_map_shadow_update_frames || m_force_update_shadow_map) { + if (shadowMapClientMapFuture != nullptr) + std::swap(shadowMapClientMapFuture, shadowMapClientMap); + + // Let all lights know that maps are updated + for (DirectionalLight &light : m_light_list) + light.commitFrustum(); + } + m_force_update_shadow_map = false; + } +} + +void ShadowRenderer::update(video::ITexture *outputTarget) +{ + if (!m_shadows_enabled || m_smgr->getActiveCamera() == nullptr) { + return; + } + + updateSMTextures(); + + if (shadowMapTextureFinal == nullptr) { + return; + } + + + if (!m_shadow_node_array.empty() && !m_light_list.empty()) { + + for (DirectionalLight &light : m_light_list) { + // Static shader values for entities are set in updateSMTextures + // SM texture for entities is not updated incrementally and + // must by updated using current player position. + m_shadow_depth_entity_cb->CameraPos = light.getPlayerPos(); + + // render shadows for the n0n-map objects. + m_driver->setRenderTarget(shadowMapTextureDynamicObjects, true, + true, video::SColor(255, 255, 255, 255)); + renderShadowObjects(shadowMapTextureDynamicObjects, light); + // clear the Render Target + m_driver->setRenderTarget(0, false, false); + + // in order to avoid too many map shadow renders, + // we should make a second pass to mix clientmap shadows and + // entities shadows :( + m_screen_quad->getMaterial().setTexture(0, shadowMapClientMap); + // dynamic objs shadow texture. + if (m_shadow_map_colored) + m_screen_quad->getMaterial().setTexture(1, shadowMapTextureColors); + m_screen_quad->getMaterial().setTexture(2, shadowMapTextureDynamicObjects); + + m_driver->setRenderTarget(shadowMapTextureFinal, false, false, + video::SColor(255, 255, 255, 255)); + m_screen_quad->render(m_driver); + m_driver->setRenderTarget(0, false, false); + + } // end for lights + } +} + +void ShadowRenderer::drawDebug() +{ + /* this code just shows shadows textures in screen and in ONLY for debugging*/ + #if 0 + // this is debug, ignore for now. + if (shadowMapTextureFinal) + m_driver->draw2DImage(shadowMapTextureFinal, + core::rect<s32>(0, 50, 128, 128 + 50), + core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize())); + + if (shadowMapClientMap) + m_driver->draw2DImage(shadowMapClientMap, + core::rect<s32>(0, 50 + 128, 128, 128 + 50 + 128), + core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize())); + + if (shadowMapTextureDynamicObjects) + m_driver->draw2DImage(shadowMapTextureDynamicObjects, + core::rect<s32>(0, 128 + 50 + 128, 128, + 128 + 50 + 128 + 128), + core::rect<s32>({0, 0}, shadowMapTextureDynamicObjects->getSize())); + + if (m_shadow_map_colored && shadowMapTextureColors) { + + m_driver->draw2DImage(shadowMapTextureColors, + core::rect<s32>(128,128 + 50 + 128 + 128, + 128 + 128, 128 + 50 + 128 + 128 + 128), + core::rect<s32>({0, 0}, shadowMapTextureColors->getSize())); + } + #endif +} + + +video::ITexture *ShadowRenderer::getSMTexture(const std::string &shadow_map_name, + video::ECOLOR_FORMAT texture_format, bool force_creation) +{ + if (force_creation) { + return m_driver->addRenderTargetTexture( + core::dimension2du(m_shadow_map_texture_size, + m_shadow_map_texture_size), + shadow_map_name.c_str(), texture_format); + } + + return m_driver->getTexture(shadow_map_name.c_str()); +} + +void ShadowRenderer::renderShadowMap(video::ITexture *target, + DirectionalLight &light, scene::E_SCENE_NODE_RENDER_PASS pass) +{ + m_driver->setTransform(video::ETS_VIEW, light.getFutureViewMatrix()); + m_driver->setTransform(video::ETS_PROJECTION, light.getFutureProjectionMatrix()); + + // Operate on the client map + for (const auto &shadow_node : m_shadow_node_array) { + if (strcmp(shadow_node.node->getName(), "ClientMap") != 0) + continue; + + ClientMap *map_node = static_cast<ClientMap *>(shadow_node.node); + + video::SMaterial material; + if (map_node->getMaterialCount() > 0) { + // we only want the first material, which is the one with the albedo info + material = map_node->getMaterial(0); + } + + material.BackfaceCulling = false; + material.FrontfaceCulling = true; + + if (m_shadow_map_colored && pass != scene::ESNRP_SOLID) { + material.MaterialType = (video::E_MATERIAL_TYPE) depth_shader_trans; + } + else { + material.MaterialType = (video::E_MATERIAL_TYPE) depth_shader; + material.BlendOperation = video::EBO_MIN; + } + + m_driver->setTransform(video::ETS_WORLD, + map_node->getAbsoluteTransformation()); + + int frame = m_force_update_shadow_map ? 0 : m_current_frame; + int total_frames = m_force_update_shadow_map ? 1 : m_map_shadow_update_frames; + + map_node->renderMapShadows(m_driver, material, pass, frame, total_frames); + break; + } +} + +void ShadowRenderer::renderShadowObjects( + video::ITexture *target, DirectionalLight &light) +{ + m_driver->setTransform(video::ETS_VIEW, light.getViewMatrix()); + m_driver->setTransform(video::ETS_PROJECTION, light.getProjectionMatrix()); + + for (const auto &shadow_node : m_shadow_node_array) { + // we only take care of the shadow casters + if (shadow_node.shadowMode == ESM_RECEIVE || + strcmp(shadow_node.node->getName(), "ClientMap") == 0) + continue; + + // render other objects + u32 n_node_materials = shadow_node.node->getMaterialCount(); + std::vector<s32> BufferMaterialList; + std::vector<std::pair<bool, bool>> BufferMaterialCullingList; + std::vector<video::E_BLEND_OPERATION> BufferBlendOperationList; + BufferMaterialList.reserve(n_node_materials); + BufferMaterialCullingList.reserve(n_node_materials); + BufferBlendOperationList.reserve(n_node_materials); + + // backup materialtype for each material + // (aka shader) + // and replace it by our "depth" shader + for (u32 m = 0; m < n_node_materials; m++) { + auto ¤t_mat = shadow_node.node->getMaterial(m); + + BufferMaterialList.push_back(current_mat.MaterialType); + current_mat.MaterialType = + (video::E_MATERIAL_TYPE)depth_shader_entities; + + BufferMaterialCullingList.emplace_back( + (bool)current_mat.BackfaceCulling, (bool)current_mat.FrontfaceCulling); + BufferBlendOperationList.push_back(current_mat.BlendOperation); + + current_mat.BackfaceCulling = true; + current_mat.FrontfaceCulling = false; + } + + m_driver->setTransform(video::ETS_WORLD, + shadow_node.node->getAbsoluteTransformation()); + shadow_node.node->render(); + + // restore the material. + + for (u32 m = 0; m < n_node_materials; m++) { + auto ¤t_mat = shadow_node.node->getMaterial(m); + + current_mat.MaterialType = (video::E_MATERIAL_TYPE) BufferMaterialList[m]; + + current_mat.BackfaceCulling = BufferMaterialCullingList[m].first; + current_mat.FrontfaceCulling = BufferMaterialCullingList[m].second; + current_mat.BlendOperation = BufferBlendOperationList[m]; + } + + } // end for caster shadow nodes +} + +void ShadowRenderer::mixShadowsQuad() +{ +} + +/* + * @Liso's disclaimer ;) This function loads the Shadow Mapping Shaders. + * I used a custom loader because I couldn't figure out how to use the base + * Shaders system with custom IShaderConstantSetCallBack without messing up the + * code too much. If anyone knows how to integrate this with the standard MT + * shaders, please feel free to change it. + */ + +void ShadowRenderer::createShaders() +{ + video::IGPUProgrammingServices *gpu = m_driver->getGPUProgrammingServices(); + + if (depth_shader == -1) { + std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl"); + if (depth_shader_vs.empty()) { + m_shadows_supported = false; + errorstream << "Error shadow mapping vs shader not found." << std::endl; + return; + } + std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl"); + if (depth_shader_fs.empty()) { + m_shadows_supported = false; + errorstream << "Error shadow mapping fs shader not found." << std::endl; + return; + } + m_shadow_depth_cb = new ShadowDepthShaderCB(); + + depth_shader = gpu->addHighLevelShaderMaterial( + readShaderFile(depth_shader_vs).c_str(), "vertexMain", + video::EVST_VS_1_1, + readShaderFile(depth_shader_fs).c_str(), "pixelMain", + video::EPST_PS_1_2, m_shadow_depth_cb, video::EMT_ONETEXTURE_BLEND); + + if (depth_shader == -1) { + // upsi, something went wrong loading shader. + delete m_shadow_depth_cb; + m_shadow_depth_cb = nullptr; + m_shadows_enabled = false; + m_shadows_supported = false; + errorstream << "Error compiling shadow mapping shader." << std::endl; + return; + } + + // HACK, TODO: investigate this better + // Grab the material renderer once more so minetest doesn't crash + // on exit + m_driver->getMaterialRenderer(depth_shader)->grab(); + } + + // This creates a clone of depth_shader with base material set to EMT_SOLID, + // because entities won't render shadows with base material EMP_ONETEXTURE_BLEND + if (depth_shader_entities == -1) { + std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl"); + if (depth_shader_vs.empty()) { + m_shadows_supported = false; + errorstream << "Error shadow mapping vs shader not found." << std::endl; + return; + } + std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl"); + if (depth_shader_fs.empty()) { + m_shadows_supported = false; + errorstream << "Error shadow mapping fs shader not found." << std::endl; + return; + } + m_shadow_depth_entity_cb = new ShadowDepthShaderCB(); + + depth_shader_entities = gpu->addHighLevelShaderMaterial( + readShaderFile(depth_shader_vs).c_str(), "vertexMain", + video::EVST_VS_1_1, + readShaderFile(depth_shader_fs).c_str(), "pixelMain", + video::EPST_PS_1_2, m_shadow_depth_entity_cb); + + if (depth_shader_entities == -1) { + // upsi, something went wrong loading shader. + delete m_shadow_depth_entity_cb; + m_shadow_depth_entity_cb = nullptr; + m_shadows_enabled = false; + m_shadows_supported = false; + errorstream << "Error compiling shadow mapping shader (dynamic)." << std::endl; + return; + } + + // HACK, TODO: investigate this better + // Grab the material renderer once more so minetest doesn't crash + // on exit + m_driver->getMaterialRenderer(depth_shader_entities)->grab(); + } + + if (mixcsm_shader == -1) { + std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass2_vertex.glsl"); + if (depth_shader_vs.empty()) { + m_shadows_supported = false; + errorstream << "Error cascade shadow mapping fs shader not found." << std::endl; + return; + } + + std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass2_fragment.glsl"); + if (depth_shader_fs.empty()) { + m_shadows_supported = false; + errorstream << "Error cascade shadow mapping fs shader not found." << std::endl; + return; + } + m_shadow_mix_cb = new shadowScreenQuadCB(); + m_screen_quad = new shadowScreenQuad(); + mixcsm_shader = gpu->addHighLevelShaderMaterial( + readShaderFile(depth_shader_vs).c_str(), "vertexMain", + video::EVST_VS_1_1, + readShaderFile(depth_shader_fs).c_str(), "pixelMain", + video::EPST_PS_1_2, m_shadow_mix_cb); + + m_screen_quad->getMaterial().MaterialType = + (video::E_MATERIAL_TYPE)mixcsm_shader; + + if (mixcsm_shader == -1) { + // upsi, something went wrong loading shader. + delete m_shadow_mix_cb; + delete m_screen_quad; + m_shadows_supported = false; + errorstream << "Error compiling cascade shadow mapping shader." << std::endl; + return; + } + + // HACK, TODO: investigate this better + // Grab the material renderer once more so minetest doesn't crash + // on exit + m_driver->getMaterialRenderer(mixcsm_shader)->grab(); + } + + if (m_shadow_map_colored && depth_shader_trans == -1) { + std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_trans_vertex.glsl"); + if (depth_shader_vs.empty()) { + m_shadows_supported = false; + errorstream << "Error shadow mapping vs shader not found." << std::endl; + return; + } + std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_trans_fragment.glsl"); + if (depth_shader_fs.empty()) { + m_shadows_supported = false; + errorstream << "Error shadow mapping fs shader not found." << std::endl; + return; + } + m_shadow_depth_trans_cb = new ShadowDepthShaderCB(); + + depth_shader_trans = gpu->addHighLevelShaderMaterial( + readShaderFile(depth_shader_vs).c_str(), "vertexMain", + video::EVST_VS_1_1, + readShaderFile(depth_shader_fs).c_str(), "pixelMain", + video::EPST_PS_1_2, m_shadow_depth_trans_cb); + + if (depth_shader_trans == -1) { + // upsi, something went wrong loading shader. + delete m_shadow_depth_trans_cb; + m_shadow_depth_trans_cb = nullptr; + m_shadow_map_colored = false; + m_shadows_supported = false; + errorstream << "Error compiling colored shadow mapping shader." << std::endl; + return; + } + + // HACK, TODO: investigate this better + // Grab the material renderer once more so minetest doesn't crash + // on exit + m_driver->getMaterialRenderer(depth_shader_trans)->grab(); + } +} + +std::string ShadowRenderer::readShaderFile(const std::string &path) +{ + std::string prefix; + if (m_shadow_map_colored) + prefix.append("#define COLORED_SHADOWS 1\n"); + prefix.append("#line 0\n"); + + std::string content; + fs::ReadFile(path, content); + + return prefix + content; +} diff --git a/src/client/shadows/dynamicshadowsrender.h b/src/client/shadows/dynamicshadowsrender.h new file mode 100644 index 0000000..bd27f6f --- /dev/null +++ b/src/client/shadows/dynamicshadowsrender.h @@ -0,0 +1,162 @@ +/* +Minetest +Copyright (C) 2021 Liso <anlismon@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <vector> +#include "irrlichttypes_extrabloated.h" +#include "client/shadows/dynamicshadows.h" + +class ShadowDepthShaderCB; +class shadowScreenQuad; +class shadowScreenQuadCB; + +enum E_SHADOW_MODE : u8 +{ + ESM_RECEIVE = 0, + ESM_BOTH, +}; + +struct NodeToApply +{ + NodeToApply(scene::ISceneNode *n, + E_SHADOW_MODE m = E_SHADOW_MODE::ESM_BOTH) : + node(n), + shadowMode(m){}; + bool operator<(const NodeToApply &other) const { return node < other.node; }; + + scene::ISceneNode *node; + + E_SHADOW_MODE shadowMode{E_SHADOW_MODE::ESM_BOTH}; + bool dirty{false}; +}; + +class ShadowRenderer +{ +public: + static const int TEXTURE_LAYER_SHADOW = 3; + + ShadowRenderer(IrrlichtDevice *device, Client *client); + + ~ShadowRenderer(); + + void initialize(); + + /// Adds a directional light shadow map (Usually just one (the sun) except in + /// Tattoine ). + size_t addDirectionalLight(); + DirectionalLight &getDirectionalLight(u32 index = 0); + size_t getDirectionalLightCount() const; + f32 getMaxShadowFar() const; + + /// Adds a shadow to the scene node. + /// The shadow mode can be ESM_BOTH, or ESM_RECEIVE. + /// ESM_BOTH casts and receives shadows + /// ESM_RECEIVE only receives but does not cast shadows. + /// + void addNodeToShadowList(scene::ISceneNode *node, + E_SHADOW_MODE shadowMode = ESM_BOTH); + void removeNodeFromShadowList(scene::ISceneNode *node); + + void update(video::ITexture *outputTarget = nullptr); + void setForceUpdateShadowMap() { m_force_update_shadow_map = true; } + void drawDebug(); + + video::ITexture *get_texture() + { + return shadowMapTextureFinal; + } + + + bool is_active() const { return m_shadows_enabled && shadowMapTextureFinal != nullptr; } + void setTimeOfDay(float isDay) { m_time_day = isDay; }; + void setShadowIntensity(float shadow_intensity); + + s32 getShadowSamples() const { return m_shadow_samples; } + float getShadowStrength() const { return m_shadows_enabled ? m_shadow_strength : 0.0f; } + float getTimeOfDay() const { return m_time_day; } + + f32 getPerspectiveBiasXY() { return m_perspective_bias_xy; } + f32 getPerspectiveBiasZ() { return m_perspective_bias_z; } + +private: + video::ITexture *getSMTexture(const std::string &shadow_map_name, + video::ECOLOR_FORMAT texture_format, + bool force_creation = false); + + void renderShadowMap(video::ITexture *target, DirectionalLight &light, + scene::E_SCENE_NODE_RENDER_PASS pass = + scene::ESNRP_SOLID); + void renderShadowObjects(video::ITexture *target, DirectionalLight &light); + void mixShadowsQuad(); + void updateSMTextures(); + + void disable(); + void enable() { m_shadows_enabled = m_shadows_supported; } + + // a bunch of variables + scene::ISceneManager *m_smgr{nullptr}; + video::IVideoDriver *m_driver{nullptr}; + Client *m_client{nullptr}; + video::ITexture *shadowMapClientMap{nullptr}; + video::ITexture *shadowMapClientMapFuture{nullptr}; + video::ITexture *shadowMapTextureFinal{nullptr}; + video::ITexture *shadowMapTextureDynamicObjects{nullptr}; + video::ITexture *shadowMapTextureColors{nullptr}; + + std::vector<DirectionalLight> m_light_list; + std::vector<NodeToApply> m_shadow_node_array; + + float m_shadow_strength; + float m_shadow_strength_gamma; + float m_shadow_map_max_distance; + float m_shadow_map_texture_size; + float m_time_day{0.0f}; + int m_shadow_samples; + bool m_shadow_map_texture_32bit; + bool m_shadows_enabled; + bool m_shadows_supported; + bool m_shadow_map_colored; + bool m_force_update_shadow_map; + u8 m_map_shadow_update_frames; /* Use this number of frames to update map shaodw */ + u8 m_current_frame{0}; /* Current frame */ + f32 m_perspective_bias_xy; + f32 m_perspective_bias_z; + + video::ECOLOR_FORMAT m_texture_format{video::ECOLOR_FORMAT::ECF_R16F}; + video::ECOLOR_FORMAT m_texture_format_color{video::ECOLOR_FORMAT::ECF_R16G16}; + + // Shadow Shader stuff + + void createShaders(); + std::string readShaderFile(const std::string &path); + + s32 depth_shader{-1}; + s32 depth_shader_entities{-1}; + s32 depth_shader_trans{-1}; + s32 mixcsm_shader{-1}; + + ShadowDepthShaderCB *m_shadow_depth_cb{nullptr}; + ShadowDepthShaderCB *m_shadow_depth_entity_cb{nullptr}; + ShadowDepthShaderCB *m_shadow_depth_trans_cb{nullptr}; + + shadowScreenQuad *m_screen_quad{nullptr}; + shadowScreenQuadCB *m_shadow_mix_cb{nullptr}; +}; diff --git a/src/client/shadows/shadowsScreenQuad.cpp b/src/client/shadows/shadowsScreenQuad.cpp new file mode 100644 index 0000000..5f6d381 --- /dev/null +++ b/src/client/shadows/shadowsScreenQuad.cpp @@ -0,0 +1,61 @@ +/* +Minetest +Copyright (C) 2021 Liso <anlismon@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "shadowsScreenQuad.h" + +shadowScreenQuad::shadowScreenQuad() +{ + Material.Wireframe = false; + Material.Lighting = false; + + video::SColor color(0x0); + Vertices[0] = video::S3DVertex( + -1.0f, -1.0f, 0.0f, 0, 0, 1, color, 0.0f, 1.0f); + Vertices[1] = video::S3DVertex( + -1.0f, 1.0f, 0.0f, 0, 0, 1, color, 0.0f, 0.0f); + Vertices[2] = video::S3DVertex( + 1.0f, 1.0f, 0.0f, 0, 0, 1, color, 1.0f, 0.0f); + Vertices[3] = video::S3DVertex( + 1.0f, -1.0f, 0.0f, 0, 0, 1, color, 1.0f, 1.0f); + Vertices[4] = video::S3DVertex( + -1.0f, -1.0f, 0.0f, 0, 0, 1, color, 0.0f, 1.0f); + Vertices[5] = video::S3DVertex( + 1.0f, 1.0f, 0.0f, 0, 0, 1, color, 1.0f, 0.0f); +} + +void shadowScreenQuad::render(video::IVideoDriver *driver) +{ + u16 indices[6] = {0, 1, 2, 3, 4, 5}; + driver->setMaterial(Material); + driver->setTransform(video::ETS_WORLD, core::matrix4()); + driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2); +} + +void shadowScreenQuadCB::OnSetConstants( + video::IMaterialRendererServices *services, s32 userData) +{ + s32 TextureId = 0; + m_sm_client_map_setting.set(&TextureId, services); + + TextureId = 1; + m_sm_client_map_trans_setting.set(&TextureId, services); + + TextureId = 2; + m_sm_dynamic_sampler_setting.set(&TextureId, services); +} diff --git a/src/client/shadows/shadowsScreenQuad.h b/src/client/shadows/shadowsScreenQuad.h new file mode 100644 index 0000000..c18be9a --- /dev/null +++ b/src/client/shadows/shadowsScreenQuad.h @@ -0,0 +1,54 @@ +/* +Minetest +Copyright (C) 2021 Liso <anlismon@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "irrlichttypes_extrabloated.h" +#include <IMaterialRendererServices.h> +#include <IShaderConstantSetCallBack.h> +#include "client/shader.h" + +class shadowScreenQuad +{ +public: + shadowScreenQuad(); + + void render(video::IVideoDriver *driver); + video::SMaterial &getMaterial() { return Material; } + +private: + video::S3DVertex Vertices[6]; + video::SMaterial Material; +}; + +class shadowScreenQuadCB : public video::IShaderConstantSetCallBack +{ +public: + shadowScreenQuadCB() : + m_sm_client_map_setting("ShadowMapClientMap"), + m_sm_client_map_trans_setting("ShadowMapClientMapTraslucent"), + m_sm_dynamic_sampler_setting("ShadowMapSamplerdynamic") + {} + + virtual void OnSetConstants(video::IMaterialRendererServices *services, + s32 userData); +private: + CachedPixelShaderSetting<s32> m_sm_client_map_setting; + CachedPixelShaderSetting<s32> m_sm_client_map_trans_setting; + CachedPixelShaderSetting<s32> m_sm_dynamic_sampler_setting; +}; diff --git a/src/client/shadows/shadowsshadercallbacks.cpp b/src/client/shadows/shadowsshadercallbacks.cpp new file mode 100644 index 0000000..b571ea9 --- /dev/null +++ b/src/client/shadows/shadowsshadercallbacks.cpp @@ -0,0 +1,48 @@ +/* +Minetest +Copyright (C) 2021 Liso <anlismon@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "client/shadows/shadowsshadercallbacks.h" + +void ShadowDepthShaderCB::OnSetConstants( + video::IMaterialRendererServices *services, s32 userData) +{ + video::IVideoDriver *driver = services->getVideoDriver(); + + core::matrix4 lightMVP = driver->getTransform(video::ETS_PROJECTION); + lightMVP *= driver->getTransform(video::ETS_VIEW); + + f32 cam_pos[4]; + lightMVP.transformVect(cam_pos, CameraPos); + + lightMVP *= driver->getTransform(video::ETS_WORLD); + + m_light_mvp_setting.set(lightMVP.pointer(), services); + m_map_resolution_setting.set(&MapRes, services); + m_max_far_setting.set(&MaxFar, services); + s32 TextureId = 0; + m_color_map_sampler_setting.set(&TextureId, services); + f32 bias0 = PerspectiveBiasXY; + m_perspective_bias0.set(&bias0, services); + f32 bias1 = 1.0f - bias0 + 1e-5f; + m_perspective_bias1.set(&bias1, services); + f32 zbias = PerspectiveBiasZ; + m_perspective_zbias.set(&zbias, services); + + m_cam_pos_setting.set(cam_pos, services); +} diff --git a/src/client/shadows/shadowsshadercallbacks.h b/src/client/shadows/shadowsshadercallbacks.h new file mode 100644 index 0000000..87833c0 --- /dev/null +++ b/src/client/shadows/shadowsshadercallbacks.h @@ -0,0 +1,58 @@ +/* +Minetest +Copyright (C) 2021 Liso <anlismon@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "irrlichttypes_extrabloated.h" +#include <IMaterialRendererServices.h> +#include <IShaderConstantSetCallBack.h> +#include "client/shader.h" + +class ShadowDepthShaderCB : public video::IShaderConstantSetCallBack +{ +public: + ShadowDepthShaderCB() : + m_light_mvp_setting("LightMVP"), + m_map_resolution_setting("MapResolution"), + m_max_far_setting("MaxFar"), + m_color_map_sampler_setting("ColorMapSampler"), + m_perspective_bias0("xyPerspectiveBias0"), + m_perspective_bias1("xyPerspectiveBias1"), + m_perspective_zbias("zPerspectiveBias"), + m_cam_pos_setting("CameraPos") + {} + + void OnSetMaterial(const video::SMaterial &material) override {} + + void OnSetConstants(video::IMaterialRendererServices *services, + s32 userData) override; + + f32 MaxFar{2048.0f}, MapRes{1024.0f}; + f32 PerspectiveBiasXY {0.9f}, PerspectiveBiasZ {0.5f}; + v3f CameraPos; + +private: + CachedVertexShaderSetting<f32, 16> m_light_mvp_setting; + CachedVertexShaderSetting<f32> m_map_resolution_setting; + CachedVertexShaderSetting<f32> m_max_far_setting; + CachedPixelShaderSetting<s32> m_color_map_sampler_setting; + CachedVertexShaderSetting<f32> m_perspective_bias0; + CachedVertexShaderSetting<f32> m_perspective_bias1; + CachedVertexShaderSetting<f32> m_perspective_zbias; + CachedVertexShaderSetting<f32, 4> m_cam_pos_setting; +}; diff --git a/src/client/sky.cpp b/src/client/sky.cpp new file mode 100644 index 0000000..ca56889 --- /dev/null +++ b/src/client/sky.cpp @@ -0,0 +1,898 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2020 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <cmath> +#include "sky.h" +#include <ITexture.h> +#include <IVideoDriver.h> +#include <ISceneManager.h> +#include <ICameraSceneNode.h> +#include <S3DVertex.h> +#include "client/tile.h" +#include "noise.h" // easeCurve +#include "profiler.h" +#include "util/numeric.h" +#include "client/renderingengine.h" +#include "settings.h" +#include "camera.h" // CameraModes + +using namespace irr::core; + +static video::SMaterial baseMaterial() +{ + video::SMaterial mat; + mat.Lighting = false; +#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8 + mat.ZBuffer = video::ECFN_DISABLED; + mat.ZWriteEnable = video::EZW_OFF; +#else + mat.ZWriteEnable = false; + mat.ZBuffer = video::ECFN_NEVER; +#endif + mat.AntiAliasing = 0; + mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; + mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + mat.BackfaceCulling = false; + return mat; +} + +static inline void disableTextureFiltering(video::SMaterial &mat) +{ + mat.setFlag(video::E_MATERIAL_FLAG::EMF_BILINEAR_FILTER, false); + mat.setFlag(video::E_MATERIAL_FLAG::EMF_TRILINEAR_FILTER, false); + mat.setFlag(video::E_MATERIAL_FLAG::EMF_ANISOTROPIC_FILTER, false); +} + +Sky::Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShaderSource *ssrc) : + scene::ISceneNode(rendering_engine->get_scene_manager()->getRootSceneNode(), + rendering_engine->get_scene_manager(), id) +{ + m_seed = (u64)myrand() << 32 | myrand(); + + setAutomaticCulling(scene::EAC_OFF); + m_box.MaxEdge.set(0, 0, 0); + m_box.MinEdge.set(0, 0, 0); + + m_enable_shaders = g_settings->getBool("enable_shaders"); + + m_sky_params = SkyboxDefaults::getSkyDefaults(); + m_sun_params = SkyboxDefaults::getSunDefaults(); + m_moon_params = SkyboxDefaults::getMoonDefaults(); + m_star_params = SkyboxDefaults::getStarDefaults(); + + // Create materials + + m_materials[0] = baseMaterial(); + m_materials[0].MaterialType = ssrc->getShaderInfo(ssrc->getShader("stars_shader", TILE_MATERIAL_ALPHA)).material; + m_materials[0].Lighting = true; + m_materials[0].ColorMaterial = video::ECM_NONE; + + m_materials[1] = baseMaterial(); + m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + + m_materials[2] = baseMaterial(); + m_materials[2].setTexture(0, tsrc->getTextureForMesh("sunrisebg.png")); + m_materials[2].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + + setSunTexture(m_sun_params.texture, m_sun_params.tonemap, tsrc); + + setMoonTexture(m_moon_params.texture, m_moon_params.tonemap, tsrc); + + for (int i = 5; i < 11; i++) { + m_materials[i] = baseMaterial(); + m_materials[i].Lighting = true; + m_materials[i].MaterialType = video::EMT_SOLID; + } + + m_directional_colored_fog = g_settings->getBool("directional_colored_fog"); + + if (g_settings->getBool("enable_dynamic_shadows")) { + float val = g_settings->getFloat("shadow_sky_body_orbit_tilt"); + m_sky_body_orbit_tilt = rangelim(val, 0.0f, 60.0f); + } + + setStarCount(1000); +} + +void Sky::OnRegisterSceneNode() +{ + if (IsVisible) + SceneManager->registerNodeForRendering(this, scene::ESNRP_SKY_BOX); + + scene::ISceneNode::OnRegisterSceneNode(); +} + +void Sky::render() +{ + video::IVideoDriver *driver = SceneManager->getVideoDriver(); + scene::ICameraSceneNode *camera = SceneManager->getActiveCamera(); + + if (!camera || !driver) + return; + + ScopeProfiler sp(g_profiler, "Sky::render()", SPT_AVG); + + // Draw perspective skybox + + core::matrix4 translate(AbsoluteTransformation); + translate.setTranslation(camera->getAbsolutePosition()); + + // Draw the sky box between the near and far clip plane + const f32 viewDistance = (camera->getNearValue() + camera->getFarValue()) * 0.5f; + core::matrix4 scale; + scale.setScale(core::vector3df(viewDistance, viewDistance, viewDistance)); + + driver->setTransform(video::ETS_WORLD, translate * scale); + + if (m_sunlight_seen) { + float sunsize = 0.07; + video::SColorf suncolor_f(1, 1, 0, 1); + //suncolor_f.r = 1; + //suncolor_f.g = MYMAX(0.3, MYMIN(1.0, 0.7 + m_time_brightness * 0.5)); + //suncolor_f.b = MYMAX(0.0, m_brightness * 0.95); + video::SColorf suncolor2_f(1, 1, 1, 1); + // The values below were probably meant to be suncolor2_f instead of a + // reassignment of suncolor_f. However, the resulting colour was chosen + // and is our long-running classic colour. So preserve, but comment-out + // the unnecessary first assignments above. + suncolor_f.r = 1; + suncolor_f.g = MYMAX(0.3, MYMIN(1.0, 0.85 + m_time_brightness * 0.5)); + suncolor_f.b = MYMAX(0.0, m_brightness); + + float moonsize = 0.04; + video::SColorf mooncolor_f(0.50, 0.57, 0.65, 1); + video::SColorf mooncolor2_f(0.85, 0.875, 0.9, 1); + + float wicked_time_of_day = getWickedTimeOfDay(m_time_of_day); + + video::SColor suncolor = suncolor_f.toSColor(); + video::SColor suncolor2 = suncolor2_f.toSColor(); + video::SColor mooncolor = mooncolor_f.toSColor(); + video::SColor mooncolor2 = mooncolor2_f.toSColor(); + + // Calculate offset normalized to the X dimension of a 512x1 px tonemap + float offset = (1.0 - fabs(sin((m_time_of_day - 0.5) * irr::core::PI))) * 511; + + if (m_sun_tonemap) { + u8 * texels = (u8 *)m_sun_tonemap->lock(); + video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4); + video::SColor texel_color (255, texel->getRed(), + texel->getGreen(), texel->getBlue()); + m_sun_tonemap->unlock(); + m_materials[3].EmissiveColor = texel_color; + } + + if (m_moon_tonemap) { + u8 * texels = (u8 *)m_moon_tonemap->lock(); + video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4); + video::SColor texel_color (255, texel->getRed(), + texel->getGreen(), texel->getBlue()); + m_moon_tonemap->unlock(); + m_materials[4].EmissiveColor = texel_color; + } + + const f32 t = 1.0f; + const f32 o = 0.0f; + static const u16 indices[6] = {0, 1, 2, 0, 2, 3}; + video::S3DVertex vertices[4]; + + driver->setMaterial(m_materials[1]); + + video::SColor cloudyfogcolor = m_bgcolor; + + // Abort rendering if we're in the clouds. + // Stops rendering a pure white hole in the bottom of the skybox. + if (m_in_clouds) + return; + + // Draw the six sided skybox, + if (m_sky_params.textures.size() == 6) { + for (u32 j = 5; j < 11; j++) { + video::SColor c(255, 255, 255, 255); + driver->setMaterial(m_materials[j]); + // Use 1.05 rather than 1.0 to avoid colliding with the + // sun, moon and stars, as this is a background skybox. + vertices[0] = video::S3DVertex(-1.05, -1.05, -1.05, 0, 0, 1, c, t, t); + vertices[1] = video::S3DVertex( 1.05, -1.05, -1.05, 0, 0, 1, c, o, t); + vertices[2] = video::S3DVertex( 1.05, 1.05, -1.05, 0, 0, 1, c, o, o); + vertices[3] = video::S3DVertex(-1.05, 1.05, -1.05, 0, 0, 1, c, t, o); + for (video::S3DVertex &vertex : vertices) { + if (j == 5) { // Top texture + vertex.Pos.rotateYZBy(90); + vertex.Pos.rotateXZBy(90); + } else if (j == 6) { // Bottom texture + vertex.Pos.rotateYZBy(-90); + vertex.Pos.rotateXZBy(90); + } else if (j == 7) { // Left texture + vertex.Pos.rotateXZBy(90); + } else if (j == 8) { // Right texture + vertex.Pos.rotateXZBy(-90); + } else if (j == 9) { // Front texture, do nothing + // Irrlicht doesn't like it when vertexes are left + // alone and not rotated for some reason. + vertex.Pos.rotateXZBy(0); + } else {// Back texture + vertex.Pos.rotateXZBy(180); + } + } + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); + } + } + + // Draw far cloudy fog thing blended with skycolor + if (m_visible) { + driver->setMaterial(m_materials[1]); + for (u32 j = 0; j < 4; j++) { + vertices[0] = video::S3DVertex(-1, -0.02, -1, 0, 0, 1, m_bgcolor, t, t); + vertices[1] = video::S3DVertex( 1, -0.02, -1, 0, 0, 1, m_bgcolor, o, t); + vertices[2] = video::S3DVertex( 1, 0.45, -1, 0, 0, 1, m_skycolor, o, o); + vertices[3] = video::S3DVertex(-1, 0.45, -1, 0, 0, 1, m_skycolor, t, o); + for (video::S3DVertex &vertex : vertices) { + if (j == 0) + // Don't switch + {} + else if (j == 1) + // Switch from -Z (south) to +X (east) + vertex.Pos.rotateXZBy(90); + else if (j == 2) + // Switch from -Z (south) to -X (west) + vertex.Pos.rotateXZBy(-90); + else + // Switch from -Z (south) to +Z (north) + vertex.Pos.rotateXZBy(-180); + } + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); + } + } + + // Draw stars before sun and moon to be behind them + if (m_star_params.visible) + draw_stars(driver, wicked_time_of_day); + + // Draw sunrise/sunset horizon glow texture + // (textures/base/pack/sunrisebg.png) + if (m_sun_params.sunrise_visible) { + driver->setMaterial(m_materials[2]); + float mid1 = 0.25; + float mid = wicked_time_of_day < 0.5 ? mid1 : (1.0 - mid1); + float a_ = 1.0f - std::fabs(wicked_time_of_day - mid) * 35.0f; + float a = easeCurve(MYMAX(0, MYMIN(1, a_))); + //std::cerr<<"a_="<<a_<<" a="<<a<<std::endl; + video::SColor c(255, 255, 255, 255); + float y = -(1.0 - a) * 0.22; + vertices[0] = video::S3DVertex(-1, -0.05 + y, -1, 0, 0, 1, c, t, t); + vertices[1] = video::S3DVertex( 1, -0.05 + y, -1, 0, 0, 1, c, o, t); + vertices[2] = video::S3DVertex( 1, 0.2 + y, -1, 0, 0, 1, c, o, o); + vertices[3] = video::S3DVertex(-1, 0.2 + y, -1, 0, 0, 1, c, t, o); + for (video::S3DVertex &vertex : vertices) { + if (wicked_time_of_day < 0.5) + // Switch from -Z (south) to +X (east) + vertex.Pos.rotateXZBy(90); + else + // Switch from -Z (south) to -X (west) + vertex.Pos.rotateXZBy(-90); + } + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); + } + + // Draw sun + if (m_sun_params.visible) + draw_sun(driver, sunsize, suncolor, suncolor2, wicked_time_of_day); + + // Draw moon + if (m_moon_params.visible) + draw_moon(driver, moonsize, mooncolor, mooncolor2, wicked_time_of_day); + + // Draw far cloudy fog thing below all horizons in front of sun, moon + // and stars. + if (m_visible) { + driver->setMaterial(m_materials[1]); + + for (u32 j = 0; j < 4; j++) { + video::SColor c = cloudyfogcolor; + vertices[0] = video::S3DVertex(-1, -1.0, -1, 0, 0, 1, c, t, t); + vertices[1] = video::S3DVertex( 1, -1.0, -1, 0, 0, 1, c, o, t); + vertices[2] = video::S3DVertex( 1, -0.02, -1, 0, 0, 1, c, o, o); + vertices[3] = video::S3DVertex(-1, -0.02, -1, 0, 0, 1, c, t, o); + for (video::S3DVertex &vertex : vertices) { + if (j == 0) + // Don't switch + {} + else if (j == 1) + // Switch from -Z (south) to +X (east) + vertex.Pos.rotateXZBy(90); + else if (j == 2) + // Switch from -Z (south) to -X (west) + vertex.Pos.rotateXZBy(-90); + else + // Switch from -Z (south) to +Z (north) + vertex.Pos.rotateXZBy(-180); + } + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); + } + + // Draw bottom far cloudy fog thing in front of sun, moon and stars + video::SColor c = cloudyfogcolor; + vertices[0] = video::S3DVertex(-1, -1.0, -1, 0, 1, 0, c, t, t); + vertices[1] = video::S3DVertex( 1, -1.0, -1, 0, 1, 0, c, o, t); + vertices[2] = video::S3DVertex( 1, -1.0, 1, 0, 1, 0, c, o, o); + vertices[3] = video::S3DVertex(-1, -1.0, 1, 0, 1, 0, c, t, o); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); + } + } +} + +void Sky::update(float time_of_day, float time_brightness, + float direct_brightness, bool sunlight_seen, + CameraMode cam_mode, float yaw, float pitch) +{ + // Stabilize initial brightness and color values by flooding updates + if (m_first_update) { + /*dstream<<"First update with time_of_day="<<time_of_day + <<" time_brightness="<<time_brightness + <<" direct_brightness="<<direct_brightness + <<" sunlight_seen="<<sunlight_seen<<std::endl;*/ + m_first_update = false; + for (u32 i = 0; i < 100; i++) { + update(time_of_day, time_brightness, direct_brightness, + sunlight_seen, cam_mode, yaw, pitch); + } + return; + } + + m_time_of_day = time_of_day; + m_time_brightness = time_brightness; + m_sunlight_seen = sunlight_seen; + m_in_clouds = false; + + bool is_dawn = (time_brightness >= 0.20 && time_brightness < 0.35); + + video::SColorf bgcolor_bright_normal_f = m_sky_params.sky_color.day_horizon; + video::SColorf bgcolor_bright_indoor_f = m_sky_params.sky_color.indoors; + video::SColorf bgcolor_bright_dawn_f = m_sky_params.sky_color.dawn_horizon; + video::SColorf bgcolor_bright_night_f = m_sky_params.sky_color.night_horizon; + + video::SColorf skycolor_bright_normal_f = m_sky_params.sky_color.day_sky; + video::SColorf skycolor_bright_dawn_f = m_sky_params.sky_color.dawn_sky; + video::SColorf skycolor_bright_night_f = m_sky_params.sky_color.night_sky; + + video::SColorf cloudcolor_bright_normal_f = m_cloudcolor_day_f; + video::SColorf cloudcolor_bright_dawn_f = m_cloudcolor_dawn_f; + + float cloud_color_change_fraction = 0.95; + if (sunlight_seen) { + if (std::fabs(time_brightness - m_brightness) < 0.2f) { + m_brightness = m_brightness * 0.95 + time_brightness * 0.05; + } else { + m_brightness = m_brightness * 0.80 + time_brightness * 0.20; + cloud_color_change_fraction = 0.0; + } + } else { + if (direct_brightness < m_brightness) + m_brightness = m_brightness * 0.95 + direct_brightness * 0.05; + else + m_brightness = m_brightness * 0.98 + direct_brightness * 0.02; + } + + m_clouds_visible = true; + float color_change_fraction = 0.98f; + if (sunlight_seen) { + if (is_dawn) { // Dawn + m_bgcolor_bright_f = m_bgcolor_bright_f.getInterpolated( + bgcolor_bright_dawn_f, color_change_fraction); + m_skycolor_bright_f = m_skycolor_bright_f.getInterpolated( + skycolor_bright_dawn_f, color_change_fraction); + m_cloudcolor_bright_f = m_cloudcolor_bright_f.getInterpolated( + cloudcolor_bright_dawn_f, color_change_fraction); + } else { + if (time_brightness < 0.13f) { // Night + m_bgcolor_bright_f = m_bgcolor_bright_f.getInterpolated( + bgcolor_bright_night_f, color_change_fraction); + m_skycolor_bright_f = m_skycolor_bright_f.getInterpolated( + skycolor_bright_night_f, color_change_fraction); + } else { // Day + m_bgcolor_bright_f = m_bgcolor_bright_f.getInterpolated( + bgcolor_bright_normal_f, color_change_fraction); + m_skycolor_bright_f = m_skycolor_bright_f.getInterpolated( + skycolor_bright_normal_f, color_change_fraction); + } + + m_cloudcolor_bright_f = m_cloudcolor_bright_f.getInterpolated( + cloudcolor_bright_normal_f, color_change_fraction); + } + } else { + m_bgcolor_bright_f = m_bgcolor_bright_f.getInterpolated( + bgcolor_bright_indoor_f, color_change_fraction); + m_skycolor_bright_f = m_skycolor_bright_f.getInterpolated( + bgcolor_bright_indoor_f, color_change_fraction); + m_cloudcolor_bright_f = m_cloudcolor_bright_f.getInterpolated( + cloudcolor_bright_normal_f, color_change_fraction); + m_clouds_visible = false; + } + + video::SColor bgcolor_bright = m_bgcolor_bright_f.toSColor(); + m_bgcolor = video::SColor( + 255, + bgcolor_bright.getRed() * m_brightness, + bgcolor_bright.getGreen() * m_brightness, + bgcolor_bright.getBlue() * m_brightness + ); + + video::SColor skycolor_bright = m_skycolor_bright_f.toSColor(); + m_skycolor = video::SColor( + 255, + skycolor_bright.getRed() * m_brightness, + skycolor_bright.getGreen() * m_brightness, + skycolor_bright.getBlue() * m_brightness + ); + + // Horizon coloring based on sun and moon direction during sunset and sunrise + video::SColor pointcolor = video::SColor(m_bgcolor.getAlpha(), 255, 255, 255); + if (m_directional_colored_fog) { + if (m_horizon_blend() != 0) { + // Calculate hemisphere value from yaw, (inverted in third person front view) + s8 dir_factor = 1; + if (cam_mode > CAMERA_MODE_THIRD) + dir_factor = -1; + f32 pointcolor_blend = wrapDegrees_0_360(yaw * dir_factor + 90); + if (pointcolor_blend > 180) + pointcolor_blend = 360 - pointcolor_blend; + pointcolor_blend /= 180; + // Bound view angle to determine where transition starts and ends + pointcolor_blend = rangelim(1 - pointcolor_blend * 1.375, 0, 1 / 1.375) * + 1.375; + // Combine the colors when looking up or down, otherwise turning looks weird + pointcolor_blend += (0.5 - pointcolor_blend) * + (1 - MYMIN((90 - std::fabs(pitch)) / 90 * 1.5, 1)); + // Invert direction to match where the sun and moon are rising + if (m_time_of_day > 0.5) + pointcolor_blend = 1 - pointcolor_blend; + // Horizon colors of sun and moon + f32 pointcolor_light = rangelim(m_time_brightness * 3, 0.2, 1); + + video::SColorf pointcolor_sun_f(1, 1, 1, 1); + // Use tonemap only if default sun/moon tinting is used + // which keeps previous behaviour. + if (m_sun_tonemap && m_default_tint) { + pointcolor_sun_f.r = pointcolor_light * + (float)m_materials[3].EmissiveColor.getRed() / 255; + pointcolor_sun_f.b = pointcolor_light * + (float)m_materials[3].EmissiveColor.getBlue() / 255; + pointcolor_sun_f.g = pointcolor_light * + (float)m_materials[3].EmissiveColor.getGreen() / 255; + } else if (!m_default_tint) { + pointcolor_sun_f = m_sky_params.fog_sun_tint; + } else { + pointcolor_sun_f.r = pointcolor_light * 1; + pointcolor_sun_f.b = pointcolor_light * + (0.25 + (rangelim(m_time_brightness, 0.25, 0.75) - 0.25) * 2 * 0.75); + pointcolor_sun_f.g = pointcolor_light * (pointcolor_sun_f.b * 0.375 + + (rangelim(m_time_brightness, 0.05, 0.15) - 0.05) * 10 * 0.625); + } + + video::SColorf pointcolor_moon_f; + if (m_default_tint) { + pointcolor_moon_f = video::SColorf( + 0.5 * pointcolor_light, + 0.6 * pointcolor_light, + 0.8 * pointcolor_light, + 1 + ); + } else { + pointcolor_moon_f = video::SColorf( + (m_sky_params.fog_moon_tint.getRed() / 255) * pointcolor_light, + (m_sky_params.fog_moon_tint.getGreen() / 255) * pointcolor_light, + (m_sky_params.fog_moon_tint.getBlue() / 255) * pointcolor_light, + 1 + ); + } + if (m_moon_tonemap && m_default_tint) { + pointcolor_moon_f.r = pointcolor_light * + (float)m_materials[4].EmissiveColor.getRed() / 255; + pointcolor_moon_f.b = pointcolor_light * + (float)m_materials[4].EmissiveColor.getBlue() / 255; + pointcolor_moon_f.g = pointcolor_light * + (float)m_materials[4].EmissiveColor.getGreen() / 255; + } + + video::SColor pointcolor_sun = pointcolor_sun_f.toSColor(); + video::SColor pointcolor_moon = pointcolor_moon_f.toSColor(); + // Calculate the blend color + pointcolor = m_mix_scolor(pointcolor_moon, pointcolor_sun, pointcolor_blend); + } + m_bgcolor = m_mix_scolor(m_bgcolor, pointcolor, m_horizon_blend() * 0.5); + m_skycolor = m_mix_scolor(m_skycolor, pointcolor, m_horizon_blend() * 0.25); + } + + float cloud_direct_brightness = 0.0f; + if (sunlight_seen) { + if (!m_directional_colored_fog) { + cloud_direct_brightness = time_brightness; + // Boost cloud brightness relative to sky, at dawn, dusk and at night + if (time_brightness < 0.7f) + cloud_direct_brightness *= 1.3f; + } else { + cloud_direct_brightness = std::fmin(m_horizon_blend() * 0.15f + + m_time_brightness, 1.0f); + // Set the same minimum cloud brightness at night + if (time_brightness < 0.5f) + cloud_direct_brightness = std::fmax(cloud_direct_brightness, + time_brightness * 1.3f); + } + } else { + cloud_direct_brightness = direct_brightness; + } + + m_cloud_brightness = m_cloud_brightness * cloud_color_change_fraction + + cloud_direct_brightness * (1.0 - cloud_color_change_fraction); + m_cloudcolor_f = video::SColorf( + m_cloudcolor_bright_f.r * m_cloud_brightness, + m_cloudcolor_bright_f.g * m_cloud_brightness, + m_cloudcolor_bright_f.b * m_cloud_brightness, + 1.0 + ); + if (m_directional_colored_fog) { + m_cloudcolor_f = m_mix_scolorf(m_cloudcolor_f, + video::SColorf(pointcolor), m_horizon_blend() * 0.25); + } +} + +void Sky::draw_sun(video::IVideoDriver *driver, float sunsize, const video::SColor &suncolor, + const video::SColor &suncolor2, float wicked_time_of_day) + /* Draw sun in the sky. + * driver: Video driver object used to draw + * sunsize: the default size of the sun + * suncolor: main sun color + * suncolor2: second sun color + * wicked_time_of_day: current time of day, to know where should be the sun in the sky + */ +{ + static const u16 indices[] = {0, 1, 2, 0, 2, 3}; + std::array<video::S3DVertex, 4> vertices; + if (!m_sun_texture) { + driver->setMaterial(m_materials[1]); + const float sunsizes[4] = { + (sunsize * 1.7f) * m_sun_params.scale, + (sunsize * 1.2f) * m_sun_params.scale, + (sunsize) * m_sun_params.scale, + (sunsize * 0.7f) * m_sun_params.scale + }; + video::SColor c1 = suncolor; + video::SColor c2 = suncolor; + c1.setAlpha(0.05 * 255); + c2.setAlpha(0.15 * 255); + const video::SColor colors[4] = {c1, c2, suncolor, suncolor2}; + for (int i = 0; i < 4; i++) { + draw_sky_body(vertices, -sunsizes[i], sunsizes[i], colors[i]); + place_sky_body(vertices, 90, wicked_time_of_day * 360 - 90); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); + } + } else { + driver->setMaterial(m_materials[3]); + float d = (sunsize * 1.7) * m_sun_params.scale; + video::SColor c; + if (m_sun_tonemap) + c = video::SColor(0, 0, 0, 0); + else + c = video::SColor(255, 255, 255, 255); + draw_sky_body(vertices, -d, d, c); + place_sky_body(vertices, 90, wicked_time_of_day * 360 - 90); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); + } +} + + +void Sky::draw_moon(video::IVideoDriver *driver, float moonsize, const video::SColor &mooncolor, + const video::SColor &mooncolor2, float wicked_time_of_day) +/* + * Draw moon in the sky. + * driver: Video driver object used to draw + * moonsize: the default size of the moon + * mooncolor: main moon color + * mooncolor2: second moon color + * wicked_time_of_day: current time of day, to know where should be the moon in + * the sky + */ +{ + static const u16 indices[] = {0, 1, 2, 0, 2, 3}; + std::array<video::S3DVertex, 4> vertices; + if (!m_moon_texture) { + driver->setMaterial(m_materials[1]); + const float moonsizes_1[4] = { + (-moonsize * 1.9f) * m_moon_params.scale, + (-moonsize * 1.3f) * m_moon_params.scale, + (-moonsize) * m_moon_params.scale, + (-moonsize) * m_moon_params.scale + }; + const float moonsizes_2[4] = { + (moonsize * 1.9f) * m_moon_params.scale, + (moonsize * 1.3f) * m_moon_params.scale, + (moonsize) *m_moon_params.scale, + (moonsize * 0.6f) * m_moon_params.scale + }; + video::SColor c1 = mooncolor; + video::SColor c2 = mooncolor; + c1.setAlpha(0.05 * 255); + c2.setAlpha(0.15 * 255); + const video::SColor colors[4] = {c1, c2, mooncolor, mooncolor2}; + for (int i = 0; i < 4; i++) { + draw_sky_body(vertices, moonsizes_1[i], moonsizes_2[i], colors[i]); + place_sky_body(vertices, -90, wicked_time_of_day * 360 - 90); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); + } + } else { + driver->setMaterial(m_materials[4]); + float d = (moonsize * 1.9) * m_moon_params.scale; + video::SColor c; + if (m_moon_tonemap) + c = video::SColor(0, 0, 0, 0); + else + c = video::SColor(255, 255, 255, 255); + draw_sky_body(vertices, -d, d, c); + place_sky_body(vertices, -90, wicked_time_of_day * 360 - 90); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); + } +} + +void Sky::draw_stars(video::IVideoDriver * driver, float wicked_time_of_day) +{ + // Tune values so that stars first appear just after the sun + // disappears over the horizon, and disappear just before the sun + // appears over the horizon. + // Also tune so that stars are at full brightness from time 20000 + // to time 4000. + + float tod = wicked_time_of_day < 0.5f ? wicked_time_of_day : (1.0f - wicked_time_of_day); + float day_opacity = clamp(m_star_params.day_opacity, 0.0f, 1.0f); + float starbrightness = (0.25f - fabs(tod)) * 20.0f; + float alpha = clamp(starbrightness, day_opacity, 1.0f); + + m_star_color = m_star_params.starcolor; + m_star_color.a *= alpha; + if (m_star_color.a <= 0.0f) // Stars are only drawn when not fully transparent + return; + m_materials[0].DiffuseColor = m_materials[0].EmissiveColor = m_star_color.toSColor(); + auto sky_rotation = core::matrix4().setRotationAxisRadians(2.0f * M_PI * (wicked_time_of_day - 0.25f), v3f(0.0f, 0.0f, 1.0f)); + auto world_matrix = driver->getTransform(video::ETS_WORLD); + driver->setTransform(video::ETS_WORLD, world_matrix * sky_rotation); + driver->setMaterial(m_materials[0]); + driver->drawMeshBuffer(m_stars.get()); + driver->setTransform(video::ETS_WORLD, world_matrix); +} + +void Sky::draw_sky_body(std::array<video::S3DVertex, 4> &vertices, float pos_1, float pos_2, const video::SColor &c) +{ + /* + * Create an array of vertices with the dimensions specified. + * pos_1, pos_2: position of the body's vertices + * c: color of the body + */ + + const f32 t = 1.0f; + const f32 o = 0.0f; + vertices[0] = video::S3DVertex(pos_1, pos_1, -1, 0, 0, 1, c, t, t); + vertices[1] = video::S3DVertex(pos_2, pos_1, -1, 0, 0, 1, c, o, t); + vertices[2] = video::S3DVertex(pos_2, pos_2, -1, 0, 0, 1, c, o, o); + vertices[3] = video::S3DVertex(pos_1, pos_2, -1, 0, 0, 1, c, t, o); +} + + +void Sky::place_sky_body( + std::array<video::S3DVertex, 4> &vertices, float horizon_position, float day_position) + /* + * Place body in the sky. + * vertices: The body as a rectangle of 4 vertices + * horizon_position: turn the body around the Y axis + * day_position: turn the body around the Z axis, to place it depending of the time of the day + */ +{ + v3f centrum(0, 0, -1); + centrum.rotateXZBy(horizon_position); + centrum.rotateXYBy(day_position); + centrum.rotateYZBy(m_sky_body_orbit_tilt); + for (video::S3DVertex &vertex : vertices) { + // Body is directed to -Z (south) by default + vertex.Pos.rotateXZBy(horizon_position); + vertex.Pos.rotateXYBy(day_position); + vertex.Pos.Z += centrum.Z; + } +} + +void Sky::setSunTexture(const std::string &sun_texture, + const std::string &sun_tonemap, ITextureSource *tsrc) +{ + // Ignore matching textures (with modifiers) entirely, + // but lets at least update the tonemap before hand. + m_sun_params.tonemap = sun_tonemap; + m_sun_tonemap = tsrc->isKnownSourceImage(sun_tonemap) ? + tsrc->getTexture(sun_tonemap) : nullptr; + m_materials[3].Lighting = !!m_sun_tonemap; + + if (m_sun_params.texture == sun_texture && !m_first_update) + return; + m_sun_params.texture = sun_texture; + + m_sun_texture = nullptr; + if (sun_texture == "sun.png") { + // Dumb compatibility fix: sun.png transparently falls back to no texture + m_sun_texture = tsrc->isKnownSourceImage(sun_texture) ? + tsrc->getTexture(sun_texture) : nullptr; + } else if (!sun_texture.empty()) { + m_sun_texture = tsrc->getTextureForMesh(sun_texture); + } + + if (m_sun_texture) { + m_materials[3] = baseMaterial(); + m_materials[3].setTexture(0, m_sun_texture); + m_materials[3].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + disableTextureFiltering(m_materials[3]); + m_materials[3].Lighting = !!m_sun_tonemap; + } +} + +void Sky::setSunriseTexture(const std::string &sunglow_texture, + ITextureSource* tsrc) +{ + // Ignore matching textures (with modifiers) entirely. + if (m_sun_params.sunrise == sunglow_texture) + return; + m_sun_params.sunrise = sunglow_texture; + m_materials[2].setTexture(0, tsrc->getTextureForMesh( + sunglow_texture.empty() ? "sunrisebg.png" : sunglow_texture) + ); +} + +void Sky::setMoonTexture(const std::string &moon_texture, + const std::string &moon_tonemap, ITextureSource *tsrc) +{ + // Ignore matching textures (with modifiers) entirely, + // but lets at least update the tonemap before hand. + m_moon_params.tonemap = moon_tonemap; + m_moon_tonemap = tsrc->isKnownSourceImage(moon_tonemap) ? + tsrc->getTexture(moon_tonemap) : nullptr; + m_materials[4].Lighting = !!m_moon_tonemap; + + if (m_moon_params.texture == moon_texture && !m_first_update) + return; + m_moon_params.texture = moon_texture; + + m_moon_texture = nullptr; + if (moon_texture == "moon.png") { + // Dumb compatibility fix: moon.png transparently falls back to no texture + m_moon_texture = tsrc->isKnownSourceImage(moon_texture) ? + tsrc->getTexture(moon_texture) : nullptr; + } else if (!moon_texture.empty()) { + m_moon_texture = tsrc->getTextureForMesh(moon_texture); + } + + if (m_moon_texture) { + m_materials[4] = baseMaterial(); + m_materials[4].setTexture(0, m_moon_texture); + m_materials[4].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + disableTextureFiltering(m_materials[4]); + m_materials[4].Lighting = !!m_moon_tonemap; + } +} + +void Sky::setStarCount(u16 star_count) +{ + // Allow force updating star count at game init. + if (m_star_params.count != star_count || m_first_update) { + m_star_params.count = star_count; + updateStars(); + } +} + +void Sky::updateStars() +{ + m_stars.reset(new scene::SMeshBuffer()); + // Stupid IrrLicht doesn’t allow non-indexed rendering, and indexed quad + // rendering is slow due to lack of hardware support. So as indices are + // 16-bit and there are 4 vertices per star... the limit is 2^16/4 = 0x4000. + // That should be well enough actually. + if (m_star_params.count > 0x4000) { + warningstream << "Requested " << m_star_params.count << " stars but " << 0x4000 << " is the max\n"; + m_star_params.count = 0x4000; + } + m_stars->Vertices.reallocate(4 * m_star_params.count); + m_stars->Indices.reallocate(6 * m_star_params.count); + + video::SColor fallback_color = m_star_params.starcolor; // used on GLES 2 “without shaders” + PcgRandom rgen(m_seed); + float d = (0.006 / 2) * m_star_params.scale; + for (u16 i = 0; i < m_star_params.count; i++) { + v3f r = v3f( + rgen.range(-10000, 10000), + rgen.range(-10000, 10000), + rgen.range(-10000, 10000) + ); + core::CMatrix4<f32> a; + a.buildRotateFromTo(v3f(0, 1, 0), r); + v3f p = v3f(-d, 1, -d); + v3f p1 = v3f(d, 1, -d); + v3f p2 = v3f(d, 1, d); + v3f p3 = v3f(-d, 1, d); + a.rotateVect(p); + a.rotateVect(p1); + a.rotateVect(p2); + a.rotateVect(p3); + m_stars->Vertices.push_back(video::S3DVertex(p, {}, fallback_color, {})); + m_stars->Vertices.push_back(video::S3DVertex(p1, {}, fallback_color, {})); + m_stars->Vertices.push_back(video::S3DVertex(p2, {}, fallback_color, {})); + m_stars->Vertices.push_back(video::S3DVertex(p3, {}, fallback_color, {})); + } + for (u16 i = 0; i < m_star_params.count; i++) { + m_stars->Indices.push_back(i * 4 + 0); + m_stars->Indices.push_back(i * 4 + 1); + m_stars->Indices.push_back(i * 4 + 2); + m_stars->Indices.push_back(i * 4 + 2); + m_stars->Indices.push_back(i * 4 + 3); + m_stars->Indices.push_back(i * 4 + 0); + } + m_stars->setHardwareMappingHint(scene::EHM_STATIC); +} + +void Sky::setSkyColors(const SkyColor &sky_color) +{ + m_sky_params.sky_color = sky_color; +} + +void Sky::setHorizonTint(video::SColor sun_tint, video::SColor moon_tint, + const std::string &use_sun_tint) +{ + // Change sun and moon tinting: + m_sky_params.fog_sun_tint = sun_tint; + m_sky_params.fog_moon_tint = moon_tint; + // Faster than comparing strings every rendering frame + if (use_sun_tint == "default") + m_default_tint = true; + else if (use_sun_tint == "custom") + m_default_tint = false; + else + m_default_tint = true; +} + +void Sky::addTextureToSkybox(const std::string &texture, int material_id, + ITextureSource *tsrc) +{ + // Sanity check for more than six textures. + if (material_id + 5 >= SKY_MATERIAL_COUNT) + return; + // Keep a list of texture names handy. + m_sky_params.textures.emplace_back(texture); + video::ITexture *result = tsrc->getTextureForMesh(texture); + m_materials[material_id+5] = baseMaterial(); + m_materials[material_id+5].setTexture(0, result); + m_materials[material_id+5].MaterialType = video::EMT_SOLID; +} + +float getWickedTimeOfDay(float time_of_day) +{ + float nightlength = 0.415f; + float wn = nightlength / 2; + float wicked_time_of_day = 0; + if (time_of_day > wn && time_of_day < 1.0f - wn) + wicked_time_of_day = (time_of_day - wn) / (1.0f - wn * 2) * 0.5f + 0.25f; + else if (time_of_day < 0.5f) + wicked_time_of_day = time_of_day / wn * 0.25f; + else + wicked_time_of_day = 1.0f - ((1.0f - time_of_day) / wn * 0.25f); + return wicked_time_of_day; +} diff --git a/src/client/sky.h b/src/client/sky.h new file mode 100644 index 0000000..cbb1186 --- /dev/null +++ b/src/client/sky.h @@ -0,0 +1,216 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include <ISceneNode.h> +#include <array> +#include "camera.h" +#include "irr_ptr.h" +#include "shader.h" +#include "skyparams.h" + +#define SKY_MATERIAL_COUNT 12 + +class ITextureSource; + +// Skybox, rendered with zbuffer turned off, before all other nodes. +class Sky : public scene::ISceneNode +{ +public: + //! constructor + Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShaderSource *ssrc); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + virtual const aabb3f &getBoundingBox() const { return m_box; } + + // Used by Irrlicht for optimizing rendering + virtual video::SMaterial &getMaterial(u32 i) { return m_materials[i]; } + virtual u32 getMaterialCount() const { return SKY_MATERIAL_COUNT; } + + void update(float m_time_of_day, float time_brightness, float direct_brightness, + bool sunlight_seen, CameraMode cam_mode, float yaw, float pitch); + + float getBrightness() { return m_brightness; } + + const video::SColor &getBgColor() const + { + return m_visible ? m_bgcolor : m_fallback_bg_color; + } + + const video::SColor &getSkyColor() const + { + return m_visible ? m_skycolor : m_fallback_bg_color; + } + + void setSunVisible(bool sun_visible) { m_sun_params.visible = sun_visible; } + bool getSunVisible() const { return m_sun_params.visible; } + void setSunTexture(const std::string &sun_texture, + const std::string &sun_tonemap, ITextureSource *tsrc); + void setSunScale(f32 sun_scale) { m_sun_params.scale = sun_scale; } + void setSunriseVisible(bool glow_visible) { m_sun_params.sunrise_visible = glow_visible; } + void setSunriseTexture(const std::string &sunglow_texture, ITextureSource* tsrc); + + void setMoonVisible(bool moon_visible) { m_moon_params.visible = moon_visible; } + bool getMoonVisible() const { return m_moon_params.visible; } + void setMoonTexture(const std::string &moon_texture, + const std::string &moon_tonemap, ITextureSource *tsrc); + void setMoonScale(f32 moon_scale) { m_moon_params.scale = moon_scale; } + + void setStarsVisible(bool stars_visible) { m_star_params.visible = stars_visible; } + void setStarCount(u16 star_count); + void setStarColor(video::SColor star_color) { m_star_params.starcolor = star_color; } + void setStarScale(f32 star_scale) { m_star_params.scale = star_scale; updateStars(); } + void setStarDayOpacity(f32 day_opacity) { m_star_params.day_opacity = day_opacity; } + + bool getCloudsVisible() const { return m_clouds_visible && m_clouds_enabled; } + const video::SColorf &getCloudColor() const { return m_cloudcolor_f; } + + void setVisible(bool visible) { m_visible = visible; } + // Set only from set_sky API + void setCloudsEnabled(bool clouds_enabled) { m_clouds_enabled = clouds_enabled; } + void setFallbackBgColor(video::SColor fallback_bg_color) + { + m_fallback_bg_color = fallback_bg_color; + } + void overrideColors(video::SColor bgcolor, video::SColor skycolor) + { + m_bgcolor = bgcolor; + m_skycolor = skycolor; + } + void setSkyColors(const SkyColor &sky_color); + void setHorizonTint(video::SColor sun_tint, video::SColor moon_tint, + const std::string &use_sun_tint); + void setInClouds(bool clouds) { m_in_clouds = clouds; } + void clearSkyboxTextures() { m_sky_params.textures.clear(); } + void addTextureToSkybox(const std::string &texture, int material_id, + ITextureSource *tsrc); + const video::SColorf &getCurrentStarColor() const { return m_star_color; } + + float getSkyBodyOrbitTilt() const { return m_sky_body_orbit_tilt; } + +private: + aabb3f m_box; + video::SMaterial m_materials[SKY_MATERIAL_COUNT]; + // How much sun & moon transition should affect horizon color + float m_horizon_blend() + { + if (!m_sunlight_seen) + return 0; + float x = m_time_of_day >= 0.5 ? (1 - m_time_of_day) * 2 + : m_time_of_day * 2; + + if (x <= 0.3) + return 0; + if (x <= 0.4) // when the sun and moon are aligned + return (x - 0.3) * 10; + if (x <= 0.5) + return (0.5 - x) * 10; + return 0; + } + + // Mix two colors by a given amount + static video::SColor m_mix_scolor(video::SColor col1, video::SColor col2, f32 factor) + { + video::SColor result = video::SColor( + col1.getAlpha() * (1 - factor) + col2.getAlpha() * factor, + col1.getRed() * (1 - factor) + col2.getRed() * factor, + col1.getGreen() * (1 - factor) + col2.getGreen() * factor, + col1.getBlue() * (1 - factor) + col2.getBlue() * factor); + return result; + } + static video::SColorf m_mix_scolorf(video::SColorf col1, video::SColorf col2, f32 factor) + { + video::SColorf result = + video::SColorf(col1.r * (1 - factor) + col2.r * factor, + col1.g * (1 - factor) + col2.g * factor, + col1.b * (1 - factor) + col2.b * factor, + col1.a * (1 - factor) + col2.a * factor); + return result; + } + + bool m_visible = true; + // Used when m_visible=false + video::SColor m_fallback_bg_color = video::SColor(255, 255, 255, 255); + bool m_first_update = true; // Set before the sky is updated for the first time + float m_time_of_day; + float m_time_brightness; + bool m_sunlight_seen; + float m_brightness = 0.5f; + float m_cloud_brightness = 0.5f; + bool m_clouds_visible; // Whether clouds are disabled due to player underground + bool m_clouds_enabled = true; // Initialised to true, reset only by set_sky API + bool m_directional_colored_fog; + bool m_in_clouds = true; // Prevent duplicating bools to remember old values + bool m_enable_shaders = false; + float m_sky_body_orbit_tilt = 0.0f; + + video::SColorf m_bgcolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); + video::SColorf m_skycolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); + video::SColorf m_cloudcolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); + video::SColor m_bgcolor; + video::SColor m_skycolor; + video::SColorf m_cloudcolor_f; + + // pure white: becomes "diffuse light component" for clouds + video::SColorf m_cloudcolor_day_f = video::SColorf(1, 1, 1, 1); + // dawn-factoring version of pure white (note: R is above 1.0) + video::SColorf m_cloudcolor_dawn_f = video::SColorf( + 255.0f/240.0f, + 223.0f/240.0f, + 191.0f/255.0f + ); + + SkyboxParams m_sky_params; + SunParams m_sun_params; + MoonParams m_moon_params; + StarParams m_star_params; + + bool m_default_tint = true; + + u64 m_seed = 0; + irr_ptr<scene::SMeshBuffer> m_stars; + video::SColorf m_star_color; + + video::ITexture *m_sun_texture; + video::ITexture *m_moon_texture; + video::ITexture *m_sun_tonemap; + video::ITexture *m_moon_tonemap; + + void updateStars(); + + void draw_sun(video::IVideoDriver *driver, float sunsize, const video::SColor &suncolor, + const video::SColor &suncolor2, float wicked_time_of_day); + void draw_moon(video::IVideoDriver *driver, float moonsize, const video::SColor &mooncolor, + const video::SColor &mooncolor2, float wicked_time_of_day); + void draw_sky_body(std::array<video::S3DVertex, 4> &vertices, + float pos_1, float pos_2, const video::SColor &c); + void draw_stars(video::IVideoDriver *driver, float wicked_time_of_day); + void place_sky_body(std::array<video::S3DVertex, 4> &vertices, + float horizon_position, float day_position); +}; + +// calculates value for sky body positions for the given observed time of day +// this is used to draw both Sun/Moon and shadows +float getWickedTimeOfDay(float time_of_day); diff --git a/src/client/sound.cpp b/src/client/sound.cpp new file mode 100644 index 0000000..44a96dd --- /dev/null +++ b/src/client/sound.cpp @@ -0,0 +1,23 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "sound.h" + +// Global DummySoundManager singleton +DummySoundManager dummySoundManager; diff --git a/src/client/sound.h b/src/client/sound.h new file mode 100644 index 0000000..213d208 --- /dev/null +++ b/src/client/sound.h @@ -0,0 +1,93 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <set> +#include <string> +#include "irr_v3d.h" +#include "../sound.h" + +class OnDemandSoundFetcher +{ +public: + virtual void fetchSounds(const std::string &name, + std::set<std::string> &dst_paths, + std::set<std::string> &dst_datas) = 0; +}; + +class ISoundManager +{ +public: + virtual ~ISoundManager() = default; + + // Multiple sounds can be loaded per name; when played, the sound + // should be chosen randomly from alternatives + // Return value determines success/failure + virtual bool loadSoundFile( + const std::string &name, const std::string &filepath) = 0; + virtual bool loadSoundData( + const std::string &name, const std::string &filedata) = 0; + + virtual void updateListener( + const v3f &pos, const v3f &vel, const v3f &at, const v3f &up) = 0; + virtual void setListenerGain(float gain) = 0; + + // playSound functions return -1 on failure, otherwise a handle to the + // sound. If name=="", call should be ignored without error. + virtual int playSound(const SimpleSoundSpec &spec) = 0; + virtual int playSoundAt(const SimpleSoundSpec &spec, const v3f &pos) = 0; + virtual void stopSound(int sound) = 0; + virtual bool soundExists(int sound) = 0; + virtual void updateSoundPosition(int sound, v3f pos) = 0; + virtual bool updateSoundGain(int id, float gain) = 0; + virtual float getSoundGain(int id) = 0; + virtual void step(float dtime) = 0; + virtual void fadeSound(int sound, float step, float gain) = 0; +}; + +class DummySoundManager : public ISoundManager +{ +public: + virtual bool loadSoundFile(const std::string &name, const std::string &filepath) + { + return true; + } + virtual bool loadSoundData(const std::string &name, const std::string &filedata) + { + return true; + } + void updateListener(const v3f &pos, const v3f &vel, const v3f &at, const v3f &up) + { + } + void setListenerGain(float gain) {} + + int playSound(const SimpleSoundSpec &spec) { return -1; } + int playSoundAt(const SimpleSoundSpec &spec, const v3f &pos) { return -1; } + void stopSound(int sound) {} + bool soundExists(int sound) { return false; } + void updateSoundPosition(int sound, v3f pos) {} + bool updateSoundGain(int id, float gain) { return false; } + float getSoundGain(int id) { return 0; } + void step(float dtime) {} + void fadeSound(int sound, float step, float gain) {} +}; + +// Global DummySoundManager singleton +extern DummySoundManager dummySoundManager; diff --git a/src/client/sound_openal.cpp b/src/client/sound_openal.cpp new file mode 100644 index 0000000..b015aba --- /dev/null +++ b/src/client/sound_openal.cpp @@ -0,0 +1,734 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +OpenAL support based on work by: +Copyright (C) 2011 Sebastian 'Bahamada' Rühl +Copyright (C) 2011 Cyriaque 'Cisoun' Skrapits <cysoun@gmail.com> +Copyright (C) 2011 Giuseppe Bilotta <giuseppe.bilotta@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; either version 2.1 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; ifnot, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "sound_openal.h" + +#if defined(_WIN32) + #include <al.h> + #include <alc.h> + //#include <alext.h> +#elif defined(__APPLE__) + #define OPENAL_DEPRECATED + #include <OpenAL/al.h> + #include <OpenAL/alc.h> + //#include <OpenAL/alext.h> +#else + #include <AL/al.h> + #include <AL/alc.h> + #include <AL/alext.h> +#endif +#include <cmath> +#include <vorbis/vorbisfile.h> +#include <cassert> +#include "log.h" +#include "util/numeric.h" // myrand() +#include "porting.h" +#include <vector> +#include <fstream> +#include <unordered_map> +#include <unordered_set> + +#define BUFFER_SIZE 30000 + +std::shared_ptr<SoundManagerSingleton> g_sound_manager_singleton; + +typedef std::unique_ptr<ALCdevice, void (*)(ALCdevice *p)> unique_ptr_alcdevice; +typedef std::unique_ptr<ALCcontext, void(*)(ALCcontext *p)> unique_ptr_alccontext; + +static void delete_alcdevice(ALCdevice *p) +{ + if (p) + alcCloseDevice(p); +} + +static void delete_alccontext(ALCcontext *p) +{ + if (p) { + alcMakeContextCurrent(nullptr); + alcDestroyContext(p); + } +} + +static const char *alErrorString(ALenum err) +{ + switch (err) { + case AL_NO_ERROR: + return "no error"; + case AL_INVALID_NAME: + return "invalid name"; + case AL_INVALID_ENUM: + return "invalid enum"; + case AL_INVALID_VALUE: + return "invalid value"; + case AL_INVALID_OPERATION: + return "invalid operation"; + case AL_OUT_OF_MEMORY: + return "out of memory"; + default: + return "<unknown OpenAL error>"; + } +} + +static ALenum warn_if_error(ALenum err, const char *desc) +{ + if(err == AL_NO_ERROR) + return err; + warningstream<<desc<<": "<<alErrorString(err)<<std::endl; + return err; +} + +void f3_set(ALfloat *f3, v3f v) +{ + f3[0] = v.X; + f3[1] = v.Y; + f3[2] = v.Z; +} + +struct SoundBuffer +{ + ALenum format; + ALsizei freq; + ALuint buffer_id; + std::vector<char> buffer; +}; + +SoundBuffer *load_opened_ogg_file(OggVorbis_File *oggFile, + const std::string &filename_for_logging) +{ + int endian = 0; // 0 for Little-Endian, 1 for Big-Endian + int bitStream; + long bytes; + char array[BUFFER_SIZE]; // Local fixed size array + vorbis_info *pInfo; + + SoundBuffer *snd = new SoundBuffer; + + // Get some information about the OGG file + pInfo = ov_info(oggFile, -1); + + // Check the number of channels... always use 16-bit samples + if(pInfo->channels == 1) + snd->format = AL_FORMAT_MONO16; + else + snd->format = AL_FORMAT_STEREO16; + + // The frequency of the sampling rate + snd->freq = pInfo->rate; + + // Keep reading until all is read + do + { + // Read up to a buffer's worth of decoded sound data + bytes = ov_read(oggFile, array, BUFFER_SIZE, endian, 2, 1, &bitStream); + + if(bytes < 0) + { + ov_clear(oggFile); + infostream << "Audio: Error decoding " + << filename_for_logging << std::endl; + delete snd; + return nullptr; + } + + // Append to end of buffer + snd->buffer.insert(snd->buffer.end(), array, array + bytes); + } while (bytes > 0); + + alGenBuffers(1, &snd->buffer_id); + alBufferData(snd->buffer_id, snd->format, + &(snd->buffer[0]), snd->buffer.size(), + snd->freq); + + ALenum error = alGetError(); + + if(error != AL_NO_ERROR){ + infostream << "Audio: OpenAL error: " << alErrorString(error) + << "preparing sound buffer" << std::endl; + } + + //infostream << "Audio file " + // << filename_for_logging << " loaded" << std::endl; + + // Clean up! + ov_clear(oggFile); + + return snd; +} + +SoundBuffer *load_ogg_from_file(const std::string &path) +{ + OggVorbis_File oggFile; + + // Try opening the given file. + // This requires libvorbis >= 1.3.2, as + // previous versions expect a non-const char * + if (ov_fopen(path.c_str(), &oggFile) != 0) { + infostream << "Audio: Error opening " << path + << " for decoding" << std::endl; + return nullptr; + } + + return load_opened_ogg_file(&oggFile, path); +} + +struct BufferSource { + const char *buf; + size_t cur_offset; + size_t len; +}; + +size_t buffer_sound_read_func(void *ptr, size_t size, size_t nmemb, void *datasource) +{ + BufferSource *s = (BufferSource *)datasource; + size_t copied_size = MYMIN(s->len - s->cur_offset, size); + memcpy(ptr, s->buf + s->cur_offset, copied_size); + s->cur_offset += copied_size; + return copied_size; +} + +int buffer_sound_seek_func(void *datasource, ogg_int64_t offset, int whence) +{ + BufferSource *s = (BufferSource *)datasource; + if (whence == SEEK_SET) { + if (offset < 0 || (size_t)MYMAX(offset, 0) >= s->len) { + // offset out of bounds + return -1; + } + s->cur_offset = offset; + return 0; + } else if (whence == SEEK_CUR) { + if ((size_t)MYMIN(-offset, 0) > s->cur_offset + || s->cur_offset + offset > s->len) { + // offset out of bounds + return -1; + } + s->cur_offset += offset; + return 0; + } + // invalid whence param (SEEK_END doesn't have to be supported) + return -1; +} + +long BufferSourceell_func(void *datasource) +{ + BufferSource *s = (BufferSource *)datasource; + return s->cur_offset; +} + +static ov_callbacks g_buffer_ov_callbacks = { + &buffer_sound_read_func, + &buffer_sound_seek_func, + nullptr, + &BufferSourceell_func +}; + +SoundBuffer *load_ogg_from_buffer(const std::string &buf, const std::string &id_for_log) +{ + OggVorbis_File oggFile; + + BufferSource s; + s.buf = buf.c_str(); + s.cur_offset = 0; + s.len = buf.size(); + + if (ov_open_callbacks(&s, &oggFile, nullptr, 0, g_buffer_ov_callbacks) != 0) { + infostream << "Audio: Error opening " << id_for_log + << " for decoding" << std::endl; + return nullptr; + } + + return load_opened_ogg_file(&oggFile, id_for_log); +} + +struct PlayingSound +{ + ALuint source_id; + bool loop; +}; + +class SoundManagerSingleton +{ +public: + unique_ptr_alcdevice m_device; + unique_ptr_alccontext m_context; +public: + SoundManagerSingleton() : + m_device(nullptr, delete_alcdevice), + m_context(nullptr, delete_alccontext) + { + } + + bool init() + { + if (!(m_device = unique_ptr_alcdevice(alcOpenDevice(nullptr), delete_alcdevice))) { + errorstream << "Audio: Global Initialization: Failed to open device" << std::endl; + return false; + } + + if (!(m_context = unique_ptr_alccontext( + alcCreateContext(m_device.get(), nullptr), delete_alccontext))) { + errorstream << "Audio: Global Initialization: Failed to create context" << std::endl; + return false; + } + + if (!alcMakeContextCurrent(m_context.get())) { + errorstream << "Audio: Global Initialization: Failed to make current context" << std::endl; + return false; + } + + alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); + + if (alGetError() != AL_NO_ERROR) { + errorstream << "Audio: Global Initialization: OpenAL Error " << alGetError() << std::endl; + return false; + } + + infostream << "Audio: Global Initialized: OpenAL " << alGetString(AL_VERSION) + << ", using " << alcGetString(m_device.get(), ALC_DEVICE_SPECIFIER) + << std::endl; + + return true; + } + + ~SoundManagerSingleton() + { + infostream << "Audio: Global Deinitialized." << std::endl; + } +}; + +class OpenALSoundManager: public ISoundManager +{ +private: + OnDemandSoundFetcher *m_fetcher; + ALCdevice *m_device; + ALCcontext *m_context; + u16 m_last_used_id = 0; // only access within getFreeId() ! + std::unordered_map<std::string, std::vector<SoundBuffer*>> m_buffers; + std::unordered_map<int, PlayingSound*> m_sounds_playing; + struct FadeState { + FadeState() = default; + + FadeState(float step, float current_gain, float target_gain): + step(step), + current_gain(current_gain), + target_gain(target_gain) {} + float step; + float current_gain; + float target_gain; + }; + + std::unordered_map<int, FadeState> m_sounds_fading; +public: + OpenALSoundManager(SoundManagerSingleton *smg, OnDemandSoundFetcher *fetcher): + m_fetcher(fetcher), + m_device(smg->m_device.get()), + m_context(smg->m_context.get()) + { + infostream << "Audio: Initialized: OpenAL " << std::endl; + } + + ~OpenALSoundManager() + { + infostream << "Audio: Deinitializing..." << std::endl; + + std::unordered_set<int> source_del_list; + + for (const auto &sp : m_sounds_playing) + source_del_list.insert(sp.first); + + for (const auto &id : source_del_list) + deleteSound(id); + + for (auto &buffer : m_buffers) { + for (SoundBuffer *sb : buffer.second) { + alDeleteBuffers(1, &sb->buffer_id); + + ALenum error = alGetError(); + if (error != AL_NO_ERROR) { + warningstream << "Audio: Failed to free stream for " + << buffer.first << ": " << alErrorString(error) << std::endl; + } + + delete sb; + } + buffer.second.clear(); + } + m_buffers.clear(); + + infostream << "Audio: Deinitialized." << std::endl; + } + + u16 getFreeId() + { + u16 startid = m_last_used_id; + while (!isFreeId(++m_last_used_id)) { + if (m_last_used_id == startid) + return 0; + } + + return m_last_used_id; + } + + inline bool isFreeId(int id) const + { + return id > 0 && m_sounds_playing.find(id) == m_sounds_playing.end(); + } + + void step(float dtime) + { + doFades(dtime); + } + + void addBuffer(const std::string &name, SoundBuffer *buf) + { + std::unordered_map<std::string, std::vector<SoundBuffer*>>::iterator i = + m_buffers.find(name); + if(i != m_buffers.end()){ + i->second.push_back(buf); + return; + } + std::vector<SoundBuffer*> bufs; + bufs.push_back(buf); + m_buffers[name] = bufs; + } + + SoundBuffer* getBuffer(const std::string &name) + { + std::unordered_map<std::string, std::vector<SoundBuffer*>>::iterator i = + m_buffers.find(name); + if(i == m_buffers.end()) + return nullptr; + std::vector<SoundBuffer*> &bufs = i->second; + int j = myrand() % bufs.size(); + return bufs[j]; + } + + PlayingSound* createPlayingSound(SoundBuffer *buf, bool loop, + float volume, float pitch) + { + infostream << "OpenALSoundManager: Creating playing sound" << std::endl; + assert(buf); + PlayingSound *sound = new PlayingSound; + assert(sound); + warn_if_error(alGetError(), "before createPlayingSound"); + alGenSources(1, &sound->source_id); + alSourcei(sound->source_id, AL_BUFFER, buf->buffer_id); + alSourcei(sound->source_id, AL_SOURCE_RELATIVE, true); + alSource3f(sound->source_id, AL_POSITION, 0, 0, 0); + alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0); + alSourcei(sound->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); + volume = std::fmax(0.0f, volume); + alSourcef(sound->source_id, AL_GAIN, volume); + alSourcef(sound->source_id, AL_PITCH, pitch); + alSourcePlay(sound->source_id); + warn_if_error(alGetError(), "createPlayingSound"); + return sound; + } + + PlayingSound* createPlayingSoundAt(SoundBuffer *buf, bool loop, + float volume, v3f pos, float pitch) + { + infostream << "OpenALSoundManager: Creating positional playing sound" + << std::endl; + assert(buf); + PlayingSound *sound = new PlayingSound; + + warn_if_error(alGetError(), "before createPlayingSoundAt"); + alGenSources(1, &sound->source_id); + alSourcei(sound->source_id, AL_BUFFER, buf->buffer_id); + alSourcei(sound->source_id, AL_SOURCE_RELATIVE, false); + alSource3f(sound->source_id, AL_POSITION, pos.X, pos.Y, pos.Z); + alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0); + // Use alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED) and set reference + // distance to clamp gain at <1 node distance, to avoid excessive + // volume when closer + alSourcef(sound->source_id, AL_REFERENCE_DISTANCE, 10.0f); + alSourcei(sound->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); + // Multiply by 3 to compensate for reducing AL_REFERENCE_DISTANCE from + // the previous value of 30 to the new value of 10 + volume = std::fmax(0.0f, volume * 3.0f); + alSourcef(sound->source_id, AL_GAIN, volume); + alSourcef(sound->source_id, AL_PITCH, pitch); + alSourcePlay(sound->source_id); + warn_if_error(alGetError(), "createPlayingSoundAt"); + return sound; + } + + int playSoundRaw(SoundBuffer *buf, bool loop, float volume, float pitch) + { + assert(buf); + PlayingSound *sound = createPlayingSound(buf, loop, volume, pitch); + if (!sound) + return -1; + + int handle = getFreeId(); + m_sounds_playing[handle] = sound; + return handle; + } + + void deleteSound(int id) + { + auto i = m_sounds_playing.find(id); + if(i == m_sounds_playing.end()) + return; + PlayingSound *sound = i->second; + + alDeleteSources(1, &sound->source_id); + + delete sound; + m_sounds_playing.erase(id); + } + + /* If buffer does not exist, consult the fetcher */ + SoundBuffer* getFetchBuffer(const std::string &name) + { + SoundBuffer *buf = getBuffer(name); + if(buf) + return buf; + if(!m_fetcher) + return nullptr; + std::set<std::string> paths; + std::set<std::string> datas; + m_fetcher->fetchSounds(name, paths, datas); + for (const std::string &path : paths) { + loadSoundFile(name, path); + } + for (const std::string &data : datas) { + loadSoundData(name, data); + } + return getBuffer(name); + } + + // Remove stopped sounds + void maintain() + { + if (!m_sounds_playing.empty()) { + verbosestream << "OpenALSoundManager::maintain(): " + << m_sounds_playing.size() <<" playing sounds, " + << m_buffers.size() <<" sound names loaded"<<std::endl; + } + std::unordered_set<int> del_list; + for (const auto &sp : m_sounds_playing) { + int id = sp.first; + PlayingSound *sound = sp.second; + // If not playing, remove it + { + ALint state; + alGetSourcei(sound->source_id, AL_SOURCE_STATE, &state); + if(state != AL_PLAYING){ + del_list.insert(id); + } + } + } + if(!del_list.empty()) + verbosestream<<"OpenALSoundManager::maintain(): deleting " + <<del_list.size()<<" playing sounds"<<std::endl; + for (int i : del_list) { + deleteSound(i); + } + } + + /* Interface */ + + bool loadSoundFile(const std::string &name, + const std::string &filepath) + { + SoundBuffer *buf = load_ogg_from_file(filepath); + if (buf) + addBuffer(name, buf); + return !!buf; + } + + bool loadSoundData(const std::string &name, + const std::string &filedata) + { + SoundBuffer *buf = load_ogg_from_buffer(filedata, name); + if (buf) + addBuffer(name, buf); + return !!buf; + } + + void updateListener(const v3f &pos, const v3f &vel, const v3f &at, const v3f &up) + { + alListener3f(AL_POSITION, pos.X, pos.Y, pos.Z); + alListener3f(AL_VELOCITY, vel.X, vel.Y, vel.Z); + ALfloat f[6]; + f3_set(f, at); + f3_set(f+3, -up); + alListenerfv(AL_ORIENTATION, f); + warn_if_error(alGetError(), "updateListener"); + } + + void setListenerGain(float gain) + { + alListenerf(AL_GAIN, gain); + } + + int playSound(const SimpleSoundSpec &spec) + { + maintain(); + if (spec.name.empty()) + return 0; + SoundBuffer *buf = getFetchBuffer(spec.name); + if(!buf){ + infostream << "OpenALSoundManager: \"" << spec.name << "\" not found." + << std::endl; + return -1; + } + + int handle = -1; + if (spec.fade > 0) { + handle = playSoundRaw(buf, spec.loop, 0.0f, spec.pitch); + fadeSound(handle, spec.fade, spec.gain); + } else { + handle = playSoundRaw(buf, spec.loop, spec.gain, spec.pitch); + } + return handle; + } + + int playSoundAt(const SimpleSoundSpec &spec, const v3f &pos) + { + maintain(); + if (spec.name.empty()) + return 0; + SoundBuffer *buf = getFetchBuffer(spec.name); + if (!buf) { + infostream << "OpenALSoundManager: \"" << spec.name << "\" not found." + << std::endl; + return -1; + } + + PlayingSound *sound = createPlayingSoundAt(buf, spec.loop, spec.gain, pos, spec.pitch); + if (!sound) + return -1; + int handle = getFreeId(); + m_sounds_playing[handle] = sound; + return handle; + } + + void stopSound(int sound) + { + maintain(); + deleteSound(sound); + } + + void fadeSound(int soundid, float step, float gain) + { + // Ignore the command if step isn't valid. + if (step == 0 || soundid < 0) + return; + + float current_gain = getSoundGain(soundid); + step = gain - current_gain > 0 ? abs(step) : -abs(step); + if (m_sounds_fading.find(soundid) != m_sounds_fading.end()) { + auto current_fade = m_sounds_fading[soundid]; + // Do not replace the fade if it's equivalent. + if (current_fade.target_gain == gain && current_fade.step == step) + return; + m_sounds_fading.erase(soundid); + } + gain = rangelim(gain, 0, 1); + m_sounds_fading[soundid] = FadeState(step, current_gain, gain); + } + + void doFades(float dtime) + { + for (auto i = m_sounds_fading.begin(); i != m_sounds_fading.end();) { + FadeState& fade = i->second; + assert(fade.step != 0); + fade.current_gain += (fade.step * dtime); + + if (fade.step < 0.f) + fade.current_gain = std::max(fade.current_gain, fade.target_gain); + else + fade.current_gain = std::min(fade.current_gain, fade.target_gain); + + if (fade.current_gain <= 0.f) + stopSound(i->first); + else + updateSoundGain(i->first, fade.current_gain); + + // The increment must happen during the erase call, or else it'll segfault. + if (fade.current_gain == fade.target_gain) + m_sounds_fading.erase(i++); + else + i++; + } + } + + bool soundExists(int sound) + { + maintain(); + return (m_sounds_playing.count(sound) != 0); + } + + void updateSoundPosition(int id, v3f pos) + { + auto i = m_sounds_playing.find(id); + if (i == m_sounds_playing.end()) + return; + PlayingSound *sound = i->second; + + alSourcei(sound->source_id, AL_SOURCE_RELATIVE, false); + alSource3f(sound->source_id, AL_POSITION, pos.X, pos.Y, pos.Z); + alSource3f(sound->source_id, AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSourcef(sound->source_id, AL_REFERENCE_DISTANCE, 10.0f); + } + + bool updateSoundGain(int id, float gain) + { + auto i = m_sounds_playing.find(id); + if (i == m_sounds_playing.end()) + return false; + + PlayingSound *sound = i->second; + alSourcef(sound->source_id, AL_GAIN, gain); + return true; + } + + float getSoundGain(int id) + { + auto i = m_sounds_playing.find(id); + if (i == m_sounds_playing.end()) + return 0; + + PlayingSound *sound = i->second; + ALfloat gain; + alGetSourcef(sound->source_id, AL_GAIN, &gain); + return gain; + } +}; + +std::shared_ptr<SoundManagerSingleton> createSoundManagerSingleton() +{ + auto smg = std::make_shared<SoundManagerSingleton>(); + if (!smg->init()) { + smg.reset(); + } + return smg; +} + +ISoundManager *createOpenALSoundManager(SoundManagerSingleton *smg, OnDemandSoundFetcher *fetcher) +{ + return new OpenALSoundManager(smg, fetcher); +}; diff --git a/src/client/sound_openal.h b/src/client/sound_openal.h new file mode 100644 index 0000000..f04ad7c --- /dev/null +++ b/src/client/sound_openal.h @@ -0,0 +1,31 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <memory> + +#include "sound.h" + +class SoundManagerSingleton; +extern std::shared_ptr<SoundManagerSingleton> g_sound_manager_singleton; + +std::shared_ptr<SoundManagerSingleton> createSoundManagerSingleton(); +ISoundManager *createOpenALSoundManager( + SoundManagerSingleton *smg, OnDemandSoundFetcher *fetcher); diff --git a/src/client/tile.cpp b/src/client/tile.cpp new file mode 100644 index 0000000..87d2818 --- /dev/null +++ b/src/client/tile.cpp @@ -0,0 +1,2333 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "tile.h" + +#include <algorithm> +#include <ICameraSceneNode.h> +#include <IrrCompileConfig.h> +#include "util/string.h" +#include "util/container.h" +#include "util/thread.h" +#include "filesys.h" +#include "settings.h" +#include "mesh.h" +#include "gamedef.h" +#include "util/strfnd.h" +#include "imagefilters.h" +#include "guiscalingfilter.h" +#include "renderingengine.h" +#include "util/base64.h" + +/* + A cache from texture name to texture path +*/ +MutexedMap<std::string, std::string> g_texturename_to_path_cache; + +/* + Replaces the filename extension. + eg: + std::string image = "a/image.png" + replace_ext(image, "jpg") + -> image = "a/image.jpg" + Returns true on success. +*/ +static bool replace_ext(std::string &path, const char *ext) +{ + if (ext == NULL) + return false; + // Find place of last dot, fail if \ or / found. + s32 last_dot_i = -1; + for (s32 i=path.size()-1; i>=0; i--) + { + if (path[i] == '.') + { + last_dot_i = i; + break; + } + + if (path[i] == '\\' || path[i] == '/') + break; + } + // If not found, return an empty string + if (last_dot_i == -1) + return false; + // Else make the new path + path = path.substr(0, last_dot_i+1) + ext; + return true; +} + +/* + Find out the full path of an image by trying different filename + extensions. + + If failed, return "". +*/ +std::string getImagePath(std::string path) +{ + // A NULL-ended list of possible image extensions + const char *extensions[] = { "png", "jpg", "bmp", "tga", NULL }; + // If there is no extension, assume PNG + if (removeStringEnd(path, extensions).empty()) + path = path + ".png"; + // Check paths until something is found to exist + const char **ext = extensions; + do{ + bool r = replace_ext(path, *ext); + if (!r) + return ""; + if (fs::PathExists(path)) + return path; + } + while((++ext) != NULL); + + return ""; +} + +/* + Gets the path to a texture by first checking if the texture exists + in texture_path and if not, using the data path. + + Checks all supported extensions by replacing the original extension. + + If not found, returns "". + + Utilizes a thread-safe cache. +*/ +std::string getTexturePath(const std::string &filename, bool *is_base_pack) +{ + std::string fullpath; + + // This can set a wrong value on cached textures, but is irrelevant because + // is_base_pack is only passed when initializing the textures the first time + if (is_base_pack) + *is_base_pack = false; + /* + Check from cache + */ + bool incache = g_texturename_to_path_cache.get(filename, &fullpath); + if (incache) + return fullpath; + + /* + Check from texture_path + */ + for (const auto &path : getTextureDirs()) { + std::string testpath = path + DIR_DELIM; + testpath.append(filename); + // Check all filename extensions. Returns "" if not found. + fullpath = getImagePath(testpath); + if (!fullpath.empty()) + break; + } + + /* + Check from default data directory + */ + if (fullpath.empty()) + { + std::string base_path = porting::path_share + DIR_DELIM + "textures" + + DIR_DELIM + "base" + DIR_DELIM + "pack"; + std::string testpath = base_path + DIR_DELIM + filename; + // Check all filename extensions. Returns "" if not found. + fullpath = getImagePath(testpath); + if (is_base_pack && !fullpath.empty()) + *is_base_pack = true; + } + + // Add to cache (also an empty result is cached) + g_texturename_to_path_cache.set(filename, fullpath); + + // Finally return it + return fullpath; +} + +void clearTextureNameCache() +{ + g_texturename_to_path_cache.clear(); +} + +/* + Stores internal information about a texture. +*/ + +struct TextureInfo +{ + std::string name; + video::ITexture *texture; + + TextureInfo( + const std::string &name_, + video::ITexture *texture_=NULL + ): + name(name_), + texture(texture_) + { + } +}; + +/* + SourceImageCache: A cache used for storing source images. +*/ + +class SourceImageCache +{ +public: + ~SourceImageCache() { + for (auto &m_image : m_images) { + m_image.second->drop(); + } + m_images.clear(); + } + void insert(const std::string &name, video::IImage *img, bool prefer_local) + { + assert(img); // Pre-condition + // Remove old image + std::map<std::string, video::IImage*>::iterator n; + n = m_images.find(name); + if (n != m_images.end()){ + if (n->second) + n->second->drop(); + } + + video::IImage* toadd = img; + bool need_to_grab = true; + + // Try to use local texture instead if asked to + if (prefer_local) { + bool is_base_pack; + std::string path = getTexturePath(name, &is_base_pack); + // Ignore base pack + if (!path.empty() && !is_base_pack) { + video::IImage *img2 = RenderingEngine::get_video_driver()-> + createImageFromFile(path.c_str()); + if (img2){ + toadd = img2; + need_to_grab = false; + } + } + } + + if (need_to_grab) + toadd->grab(); + m_images[name] = toadd; + } + video::IImage* get(const std::string &name) + { + std::map<std::string, video::IImage*>::iterator n; + n = m_images.find(name); + if (n != m_images.end()) + return n->second; + return NULL; + } + // Primarily fetches from cache, secondarily tries to read from filesystem + video::IImage *getOrLoad(const std::string &name) + { + std::map<std::string, video::IImage*>::iterator n; + n = m_images.find(name); + if (n != m_images.end()){ + n->second->grab(); // Grab for caller + return n->second; + } + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + std::string path = getTexturePath(name); + if (path.empty()) { + infostream<<"SourceImageCache::getOrLoad(): No path found for \"" + <<name<<"\""<<std::endl; + return NULL; + } + infostream<<"SourceImageCache::getOrLoad(): Loading path \""<<path + <<"\""<<std::endl; + video::IImage *img = driver->createImageFromFile(path.c_str()); + + if (img){ + m_images[name] = img; + img->grab(); // Grab for caller + } + return img; + } +private: + std::map<std::string, video::IImage*> m_images; +}; + +/* + TextureSource +*/ + +class TextureSource : public IWritableTextureSource +{ +public: + TextureSource(); + virtual ~TextureSource(); + + /* + Example case: + Now, assume a texture with the id 1 exists, and has the name + "stone.png^mineral1". + Then a random thread calls getTextureId for a texture called + "stone.png^mineral1^crack0". + ...Now, WTF should happen? Well: + - getTextureId strips off stuff recursively from the end until + the remaining part is found, or nothing is left when + something is stripped out + + But it is slow to search for textures by names and modify them + like that? + - ContentFeatures is made to contain ids for the basic plain + textures + - Crack textures can be slow by themselves, but the framework + must be fast. + + Example case #2: + - Assume a texture with the id 1 exists, and has the name + "stone.png^mineral_coal.png". + - Now getNodeTile() stumbles upon a node which uses + texture id 1, and determines that MATERIAL_FLAG_CRACK + must be applied to the tile + - MapBlockMesh::animate() finds the MATERIAL_FLAG_CRACK and + has received the current crack level 0 from the client. It + finds out the name of the texture with getTextureName(1), + appends "^crack0" to it and gets a new texture id with + getTextureId("stone.png^mineral_coal.png^crack0"). + + */ + + /* + Gets a texture id from cache or + - if main thread, generates the texture, adds to cache and returns id. + - if other thread, adds to request queue and waits for main thread. + + The id 0 points to a NULL texture. It is returned in case of error. + */ + u32 getTextureId(const std::string &name); + + // Finds out the name of a cached texture. + std::string getTextureName(u32 id); + + /* + If texture specified by the name pointed by the id doesn't + exist, create it, then return the cached texture. + + Can be called from any thread. If called from some other thread + and not found in cache, the call is queued to the main thread + for processing. + */ + video::ITexture* getTexture(u32 id); + + video::ITexture* getTexture(const std::string &name, u32 *id = NULL); + + /* + Get a texture specifically intended for mesh + application, i.e. not HUD, compositing, or other 2D + use. This texture may be a different size and may + have had additional filters applied. + */ + video::ITexture* getTextureForMesh(const std::string &name, u32 *id); + + virtual Palette* getPalette(const std::string &name); + + bool isKnownSourceImage(const std::string &name) + { + bool is_known = false; + bool cache_found = m_source_image_existence.get(name, &is_known); + if (cache_found) + return is_known; + // Not found in cache; find out if a local file exists + is_known = (!getTexturePath(name).empty()); + m_source_image_existence.set(name, is_known); + return is_known; + } + + // Processes queued texture requests from other threads. + // Shall be called from the main thread. + void processQueue(); + + // Insert an image into the cache without touching the filesystem. + // Shall be called from the main thread. + void insertSourceImage(const std::string &name, video::IImage *img); + + // Rebuild images and textures from the current set of source images + // Shall be called from the main thread. + void rebuildImagesAndTextures(); + + video::ITexture* getNormalTexture(const std::string &name); + video::SColor getTextureAverageColor(const std::string &name); + video::ITexture *getShaderFlagsTexture(bool normamap_present); + +private: + + // The id of the thread that is allowed to use irrlicht directly + std::thread::id m_main_thread; + + // Cache of source images + // This should be only accessed from the main thread + SourceImageCache m_sourcecache; + + // Generate a texture + u32 generateTexture(const std::string &name); + + // Generate image based on a string like "stone.png" or "[crack:1:0". + // if baseimg is NULL, it is created. Otherwise stuff is made on it. + bool generateImagePart(std::string part_of_name, video::IImage *& baseimg); + + /*! Generates an image from a full string like + * "stone.png^mineral_coal.png^[crack:1:0". + * Shall be called from the main thread. + * The returned Image should be dropped. + */ + video::IImage* generateImage(const std::string &name); + + // Thread-safe cache of what source images are known (true = known) + MutexedMap<std::string, bool> m_source_image_existence; + + // A texture id is index in this array. + // The first position contains a NULL texture. + std::vector<TextureInfo> m_textureinfo_cache; + // Maps a texture name to an index in the former. + std::map<std::string, u32> m_name_to_id; + // The two former containers are behind this mutex + std::mutex m_textureinfo_cache_mutex; + + // Queued texture fetches (to be processed by the main thread) + RequestQueue<std::string, u32, u8, u8> m_get_texture_queue; + + // Textures that have been overwritten with other ones + // but can't be deleted because the ITexture* might still be used + std::vector<video::ITexture*> m_texture_trash; + + // Maps image file names to loaded palettes. + std::unordered_map<std::string, Palette> m_palettes; + + // Cached settings needed for making textures from meshes + bool m_setting_mipmap; + bool m_setting_trilinear_filter; + bool m_setting_bilinear_filter; +}; + +IWritableTextureSource *createTextureSource() +{ + return new TextureSource(); +} + +TextureSource::TextureSource() +{ + m_main_thread = std::this_thread::get_id(); + + // Add a NULL TextureInfo as the first index, named "" + m_textureinfo_cache.emplace_back(""); + m_name_to_id[""] = 0; + + // Cache some settings + // Note: Since this is only done once, the game must be restarted + // for these settings to take effect + m_setting_mipmap = g_settings->getBool("mip_map"); + m_setting_trilinear_filter = g_settings->getBool("trilinear_filter"); + m_setting_bilinear_filter = g_settings->getBool("bilinear_filter"); +} + +TextureSource::~TextureSource() +{ + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + + unsigned int textures_before = driver->getTextureCount(); + + for (const auto &iter : m_textureinfo_cache) { + //cleanup texture + if (iter.texture) + driver->removeTexture(iter.texture); + } + m_textureinfo_cache.clear(); + + for (auto t : m_texture_trash) { + //cleanup trashed texture + driver->removeTexture(t); + } + + infostream << "~TextureSource() before cleanup: "<< textures_before + << " after: " << driver->getTextureCount() << std::endl; +} + +u32 TextureSource::getTextureId(const std::string &name) +{ + //infostream<<"getTextureId(): \""<<name<<"\""<<std::endl; + + { + /* + See if texture already exists + */ + MutexAutoLock lock(m_textureinfo_cache_mutex); + std::map<std::string, u32>::iterator n; + n = m_name_to_id.find(name); + if (n != m_name_to_id.end()) + { + return n->second; + } + } + + /* + Get texture + */ + if (std::this_thread::get_id() == m_main_thread) { + return generateTexture(name); + } + + + infostream<<"getTextureId(): Queued: name=\""<<name<<"\""<<std::endl; + + // We're gonna ask the result to be put into here + static ResultQueue<std::string, u32, u8, u8> result_queue; + + // Throw a request in + m_get_texture_queue.add(name, 0, 0, &result_queue); + + try { + while(true) { + // Wait result for a second + GetResult<std::string, u32, u8, u8> + result = result_queue.pop_front(1000); + + if (result.key == name) { + return result.item; + } + } + } catch(ItemNotFoundException &e) { + errorstream << "Waiting for texture " << name << " timed out." << std::endl; + return 0; + } + + infostream << "getTextureId(): Failed" << std::endl; + + return 0; +} + +// Draw an image on top of an another one, using the alpha channel of the +// source image +static void blit_with_alpha(video::IImage *src, video::IImage *dst, + v2s32 src_pos, v2s32 dst_pos, v2u32 size); + +// Like blit_with_alpha, but only modifies destination pixels that +// are fully opaque +static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst, + v2s32 src_pos, v2s32 dst_pos, v2u32 size); + +// Apply a color to an image. Uses an int (0-255) to calculate the ratio. +// If the ratio is 255 or -1 and keep_alpha is true, then it multiples the +// color alpha with the destination alpha. +// Otherwise, any pixels that are not fully transparent get the color alpha. +static void apply_colorize(video::IImage *dst, v2u32 dst_pos, v2u32 size, + const video::SColor &color, int ratio, bool keep_alpha); + +// paint a texture using the given color +static void apply_multiplication(video::IImage *dst, v2u32 dst_pos, v2u32 size, + const video::SColor &color); + +// Apply a mask to an image +static void apply_mask(video::IImage *mask, video::IImage *dst, + v2s32 mask_pos, v2s32 dst_pos, v2u32 size); + +// Draw or overlay a crack +static void draw_crack(video::IImage *crack, video::IImage *dst, + bool use_overlay, s32 frame_count, s32 progression, + video::IVideoDriver *driver, u8 tiles = 1); + +// Brighten image +void brighten(video::IImage *image); +// Parse a transform name +u32 parseImageTransform(const std::string& s); +// Apply transform to image dimension +core::dimension2d<u32> imageTransformDimension(u32 transform, core::dimension2d<u32> dim); +// Apply transform to image data +void imageTransform(u32 transform, video::IImage *src, video::IImage *dst); + +/* + This method generates all the textures +*/ +u32 TextureSource::generateTexture(const std::string &name) +{ + //infostream << "generateTexture(): name=\"" << name << "\"" << std::endl; + + // Empty name means texture 0 + if (name.empty()) { + infostream<<"generateTexture(): name is empty"<<std::endl; + return 0; + } + + { + /* + See if texture already exists + */ + MutexAutoLock lock(m_textureinfo_cache_mutex); + std::map<std::string, u32>::iterator n; + n = m_name_to_id.find(name); + if (n != m_name_to_id.end()) { + return n->second; + } + } + + /* + Calling only allowed from main thread + */ + if (std::this_thread::get_id() != m_main_thread) { + errorstream<<"TextureSource::generateTexture() " + "called not from main thread"<<std::endl; + return 0; + } + + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + sanity_check(driver); + + video::IImage *img = generateImage(name); + + video::ITexture *tex = NULL; + + if (img != NULL) { +#if ENABLE_GLES + img = Align2Npot2(img, driver); +#endif + // Create texture from resulting image + tex = driver->addTexture(name.c_str(), img); + guiScalingCache(io::path(name.c_str()), driver, img); + img->drop(); + } + + /* + Add texture to caches (add NULL textures too) + */ + + MutexAutoLock lock(m_textureinfo_cache_mutex); + + u32 id = m_textureinfo_cache.size(); + TextureInfo ti(name, tex); + m_textureinfo_cache.push_back(ti); + m_name_to_id[name] = id; + + return id; +} + +std::string TextureSource::getTextureName(u32 id) +{ + MutexAutoLock lock(m_textureinfo_cache_mutex); + + if (id >= m_textureinfo_cache.size()) + { + errorstream<<"TextureSource::getTextureName(): id="<<id + <<" >= m_textureinfo_cache.size()=" + <<m_textureinfo_cache.size()<<std::endl; + return ""; + } + + return m_textureinfo_cache[id].name; +} + +video::ITexture* TextureSource::getTexture(u32 id) +{ + MutexAutoLock lock(m_textureinfo_cache_mutex); + + if (id >= m_textureinfo_cache.size()) + return NULL; + + return m_textureinfo_cache[id].texture; +} + +video::ITexture* TextureSource::getTexture(const std::string &name, u32 *id) +{ + u32 actual_id = getTextureId(name); + if (id){ + *id = actual_id; + } + return getTexture(actual_id); +} + +video::ITexture* TextureSource::getTextureForMesh(const std::string &name, u32 *id) +{ + static thread_local bool filter_needed = + g_settings->getBool("texture_clean_transparent") || m_setting_mipmap || + ((m_setting_trilinear_filter || m_setting_bilinear_filter) && + g_settings->getS32("texture_min_size") > 1); + // Avoid duplicating texture if it won't actually change + if (filter_needed) + return getTexture(name + "^[applyfiltersformesh", id); + return getTexture(name, id); +} + +Palette* TextureSource::getPalette(const std::string &name) +{ + // Only the main thread may load images + sanity_check(std::this_thread::get_id() == m_main_thread); + + if (name.empty()) + return NULL; + + auto it = m_palettes.find(name); + if (it == m_palettes.end()) { + // Create palette + video::IImage *img = generateImage(name); + if (!img) { + warningstream << "TextureSource::getPalette(): palette \"" << name + << "\" could not be loaded." << std::endl; + return NULL; + } + Palette new_palette; + u32 w = img->getDimension().Width; + u32 h = img->getDimension().Height; + // Real area of the image + u32 area = h * w; + if (area == 0) + return NULL; + if (area > 256) { + warningstream << "TextureSource::getPalette(): the specified" + << " palette image \"" << name << "\" is larger than 256" + << " pixels, using the first 256." << std::endl; + area = 256; + } else if (256 % area != 0) + warningstream << "TextureSource::getPalette(): the " + << "specified palette image \"" << name << "\" does not " + << "contain power of two pixels." << std::endl; + // We stretch the palette so it will fit 256 values + // This many param2 values will have the same color + u32 step = 256 / area; + // For each pixel in the image + for (u32 i = 0; i < area; i++) { + video::SColor c = img->getPixel(i % w, i / w); + // Fill in palette with 'step' colors + for (u32 j = 0; j < step; j++) + new_palette.push_back(c); + } + img->drop(); + // Fill in remaining elements + while (new_palette.size() < 256) + new_palette.emplace_back(0xFFFFFFFF); + m_palettes[name] = new_palette; + it = m_palettes.find(name); + } + if (it != m_palettes.end()) + return &((*it).second); + return NULL; +} + +void TextureSource::processQueue() +{ + /* + Fetch textures + */ + //NOTE this is only thread safe for ONE consumer thread! + if (!m_get_texture_queue.empty()) + { + GetRequest<std::string, u32, u8, u8> + request = m_get_texture_queue.pop(); + + /*infostream<<"TextureSource::processQueue(): " + <<"got texture request with " + <<"name=\""<<request.key<<"\"" + <<std::endl;*/ + + m_get_texture_queue.pushResult(request, generateTexture(request.key)); + } +} + +void TextureSource::insertSourceImage(const std::string &name, video::IImage *img) +{ + //infostream<<"TextureSource::insertSourceImage(): name="<<name<<std::endl; + + sanity_check(std::this_thread::get_id() == m_main_thread); + + m_sourcecache.insert(name, img, true); + m_source_image_existence.set(name, true); +} + +void TextureSource::rebuildImagesAndTextures() +{ + MutexAutoLock lock(m_textureinfo_cache_mutex); + + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + sanity_check(driver); + + infostream << "TextureSource: recreating " << m_textureinfo_cache.size() + << " textures" << std::endl; + + // Recreate textures + for (TextureInfo &ti : m_textureinfo_cache) { + if (ti.name.empty()) + continue; // Skip dummy entry + + video::IImage *img = generateImage(ti.name); +#if ENABLE_GLES + img = Align2Npot2(img, driver); +#endif + // Create texture from resulting image + video::ITexture *t = NULL; + if (img) { + t = driver->addTexture(ti.name.c_str(), img); + guiScalingCache(io::path(ti.name.c_str()), driver, img); + img->drop(); + } + video::ITexture *t_old = ti.texture; + // Replace texture + ti.texture = t; + + if (t_old) + m_texture_trash.push_back(t_old); + } +} + +inline static void applyShadeFactor(video::SColor &color, u32 factor) +{ + u32 f = core::clamp<u32>(factor, 0, 256); + color.setRed(color.getRed() * f / 256); + color.setGreen(color.getGreen() * f / 256); + color.setBlue(color.getBlue() * f / 256); +} + +static video::IImage *createInventoryCubeImage( + video::IImage *top, video::IImage *left, video::IImage *right) +{ + core::dimension2du size_top = top->getDimension(); + core::dimension2du size_left = left->getDimension(); + core::dimension2du size_right = right->getDimension(); + + u32 size = npot2(std::max({ + size_top.Width, size_top.Height, + size_left.Width, size_left.Height, + size_right.Width, size_right.Height, + })); + + // It must be divisible by 4, to let everything work correctly. + // But it is a power of 2, so being at least 4 is the same. + // And the resulting texture should't be too large as well. + size = core::clamp<u32>(size, 4, 64); + + // With such parameters, the cube fits exactly, touching each image line + // from `0` to `cube_size - 1`. (Note that division is exact here). + u32 cube_size = 9 * size; + u32 offset = size / 2; + + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + + auto lock_image = [size, driver] (video::IImage *&image) -> const u32 * { + image->grab(); + core::dimension2du dim = image->getDimension(); + video::ECOLOR_FORMAT format = image->getColorFormat(); + if (dim.Width != size || dim.Height != size || format != video::ECF_A8R8G8B8) { + video::IImage *scaled = driver->createImage(video::ECF_A8R8G8B8, {size, size}); + image->copyToScaling(scaled); + image->drop(); + image = scaled; + } + sanity_check(image->getPitch() == 4 * size); + return reinterpret_cast<u32 *>(image->getData()); + }; + auto free_image = [] (video::IImage *image) -> void { + image->drop(); + }; + + video::IImage *result = driver->createImage(video::ECF_A8R8G8B8, {cube_size, cube_size}); + sanity_check(result->getPitch() == 4 * cube_size); + result->fill(video::SColor(0x00000000u)); + u32 *target = reinterpret_cast<u32 *>(result->getData()); + + // Draws single cube face + // `shade_factor` is face brightness, in range [0.0, 1.0] + // (xu, xv, x1; yu, yv, y1) form coordinate transformation matrix + // `offsets` list pixels to be drawn for single source pixel + auto draw_image = [=] (video::IImage *image, float shade_factor, + s16 xu, s16 xv, s16 x1, + s16 yu, s16 yv, s16 y1, + std::initializer_list<v2s16> offsets) -> void { + u32 brightness = core::clamp<u32>(256 * shade_factor, 0, 256); + const u32 *source = lock_image(image); + for (u16 v = 0; v < size; v++) { + for (u16 u = 0; u < size; u++) { + video::SColor pixel(*source); + applyShadeFactor(pixel, brightness); + s16 x = xu * u + xv * v + x1; + s16 y = yu * u + yv * v + y1; + for (const auto &off : offsets) + target[(y + off.Y) * cube_size + (x + off.X) + offset] = pixel.color; + source++; + } + } + free_image(image); + }; + + draw_image(top, 1.000000f, + 4, -4, 4 * (size - 1), + 2, 2, 0, + { + {2, 0}, {3, 0}, {4, 0}, {5, 0}, + {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, + {2, 2}, {3, 2}, {4, 2}, {5, 2}, + }); + + draw_image(left, 0.836660f, + 4, 0, 0, + 2, 5, 2 * size, + { + {0, 0}, {1, 0}, + {0, 1}, {1, 1}, {2, 1}, {3, 1}, + {0, 2}, {1, 2}, {2, 2}, {3, 2}, + {0, 3}, {1, 3}, {2, 3}, {3, 3}, + {0, 4}, {1, 4}, {2, 4}, {3, 4}, + {2, 5}, {3, 5}, + }); + + draw_image(right, 0.670820f, + 4, 0, 4 * size, + -2, 5, 4 * size - 2, + { + {2, 0}, {3, 0}, + {0, 1}, {1, 1}, {2, 1}, {3, 1}, + {0, 2}, {1, 2}, {2, 2}, {3, 2}, + {0, 3}, {1, 3}, {2, 3}, {3, 3}, + {0, 4}, {1, 4}, {2, 4}, {3, 4}, + {0, 5}, {1, 5}, + }); + + return result; +} + +video::IImage* TextureSource::generateImage(const std::string &name) +{ + // Get the base image + + const char separator = '^'; + const char escape = '\\'; + const char paren_open = '('; + const char paren_close = ')'; + + // Find last separator in the name + s32 last_separator_pos = -1; + u8 paren_bal = 0; + for (s32 i = name.size() - 1; i >= 0; i--) { + if (i > 0 && name[i-1] == escape) + continue; + switch (name[i]) { + case separator: + if (paren_bal == 0) { + last_separator_pos = i; + i = -1; // break out of loop + } + break; + case paren_open: + if (paren_bal == 0) { + errorstream << "generateImage(): unbalanced parentheses" + << "(extranous '(') while generating texture \"" + << name << "\"" << std::endl; + return NULL; + } + paren_bal--; + break; + case paren_close: + paren_bal++; + break; + default: + break; + } + } + if (paren_bal > 0) { + errorstream << "generateImage(): unbalanced parentheses" + << "(missing matching '(') while generating texture \"" + << name << "\"" << std::endl; + return NULL; + } + + + video::IImage *baseimg = NULL; + + /* + If separator was found, make the base image + using a recursive call. + */ + if (last_separator_pos != -1) { + baseimg = generateImage(name.substr(0, last_separator_pos)); + } + + /* + Parse out the last part of the name of the image and act + according to it + */ + + std::string last_part_of_name = name.substr(last_separator_pos + 1); + + /* + If this name is enclosed in parentheses, generate it + and blit it onto the base image + */ + if (last_part_of_name[0] == paren_open + && last_part_of_name[last_part_of_name.size() - 1] == paren_close) { + std::string name2 = last_part_of_name.substr(1, + last_part_of_name.size() - 2); + video::IImage *tmp = generateImage(name2); + if (!tmp) { + errorstream << "generateImage(): " + "Failed to generate \"" << name2 << "\"" + << std::endl; + return NULL; + } + core::dimension2d<u32> dim = tmp->getDimension(); + if (baseimg) { + blit_with_alpha(tmp, baseimg, v2s32(0, 0), v2s32(0, 0), dim); + tmp->drop(); + } else { + baseimg = tmp; + } + } else if (!generateImagePart(last_part_of_name, baseimg)) { + // Generate image according to part of name + errorstream << "generateImage(): " + "Failed to generate \"" << last_part_of_name << "\"" + << std::endl; + } + + // If no resulting image, print a warning + if (baseimg == NULL) { + errorstream << "generateImage(): baseimg is NULL (attempted to" + " create texture \"" << name << "\")" << std::endl; + } + + return baseimg; +} + +#if ENABLE_GLES + +/** + * Check and align image to npot2 if required by hardware + * @param image image to check for npot2 alignment + * @param driver driver to use for image operations + * @return image or copy of image aligned to npot2 + */ +video::IImage *Align2Npot2(video::IImage *image, + video::IVideoDriver *driver) +{ + if (image == NULL) + return image; + + if (driver->queryFeature(video::EVDF_TEXTURE_NPOT)) + return image; + + core::dimension2d<u32> dim = image->getDimension(); + unsigned int height = npot2(dim.Height); + unsigned int width = npot2(dim.Width); + + if (dim.Height == height && dim.Width == width) + return image; + + if (dim.Height > height) + height *= 2; + if (dim.Width > width) + width *= 2; + + video::IImage *targetimage = + driver->createImage(video::ECF_A8R8G8B8, + core::dimension2d<u32>(width, height)); + + if (targetimage != NULL) + image->copyToScaling(targetimage); + image->drop(); + return targetimage; +} + +#endif + +static std::string unescape_string(const std::string &str, const char esc = '\\') +{ + std::string out; + size_t pos = 0, cpos; + out.reserve(str.size()); + while (1) { + cpos = str.find_first_of(esc, pos); + if (cpos == std::string::npos) { + out += str.substr(pos); + break; + } + out += str.substr(pos, cpos - pos) + str[cpos + 1]; + pos = cpos + 2; + } + return out; +} + +void blitBaseImage(video::IImage* &src, video::IImage* &dst) +{ + //infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl; + // Size of the copied area + core::dimension2d<u32> dim = src->getDimension(); + //core::dimension2d<u32> dim(16,16); + // Position to copy the blitted to in the base image + core::position2d<s32> pos_to(0,0); + // Position to copy the blitted from in the blitted image + core::position2d<s32> pos_from(0,0); + // Blit + /*image->copyToWithAlpha(baseimg, pos_to, + core::rect<s32>(pos_from, dim), + video::SColor(255,255,255,255), + NULL);*/ + + core::dimension2d<u32> dim_dst = dst->getDimension(); + if (dim == dim_dst) { + blit_with_alpha(src, dst, pos_from, pos_to, dim); + } else if (dim.Width * dim.Height < dim_dst.Width * dim_dst.Height) { + // Upscale overlying image + video::IImage *scaled_image = RenderingEngine::get_video_driver()-> + createImage(video::ECF_A8R8G8B8, dim_dst); + src->copyToScaling(scaled_image); + + blit_with_alpha(scaled_image, dst, pos_from, pos_to, dim_dst); + scaled_image->drop(); + } else { + // Upscale base image + video::IImage *scaled_base = RenderingEngine::get_video_driver()-> + createImage(video::ECF_A8R8G8B8, dim); + dst->copyToScaling(scaled_base); + dst->drop(); + dst = scaled_base; + + blit_with_alpha(src, dst, pos_from, pos_to, dim); + } +} + +bool TextureSource::generateImagePart(std::string part_of_name, + video::IImage *& baseimg) +{ + const char escape = '\\'; // same as in generateImage() + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + sanity_check(driver); + + // Stuff starting with [ are special commands + if (part_of_name.empty() || part_of_name[0] != '[') { + video::IImage *image = m_sourcecache.getOrLoad(part_of_name); + if (image == NULL) { + if (!part_of_name.empty()) { + + // Do not create normalmap dummies + if (part_of_name.find("_normal.png") != std::string::npos) { + warningstream << "generateImage(): Could not load normal map \"" + << part_of_name << "\"" << std::endl; + return true; + } + + errorstream << "generateImage(): Could not load image \"" + << part_of_name << "\" while building texture; " + "Creating a dummy image" << std::endl; + } + + // Just create a dummy image + //core::dimension2d<u32> dim(2,2); + core::dimension2d<u32> dim(1,1); + image = driver->createImage(video::ECF_A8R8G8B8, dim); + sanity_check(image != NULL); + /*image->setPixel(0,0, video::SColor(255,255,0,0)); + image->setPixel(1,0, video::SColor(255,0,255,0)); + image->setPixel(0,1, video::SColor(255,0,0,255)); + image->setPixel(1,1, video::SColor(255,255,0,255));*/ + image->setPixel(0,0, video::SColor(255,myrand()%256, + myrand()%256,myrand()%256)); + /*image->setPixel(1,0, video::SColor(255,myrand()%256, + myrand()%256,myrand()%256)); + image->setPixel(0,1, video::SColor(255,myrand()%256, + myrand()%256,myrand()%256)); + image->setPixel(1,1, video::SColor(255,myrand()%256, + myrand()%256,myrand()%256));*/ + } + + // If base image is NULL, load as base. + if (baseimg == NULL) + { + //infostream<<"Setting "<<part_of_name<<" as base"<<std::endl; + /* + Copy it this way to get an alpha channel. + Otherwise images with alpha cannot be blitted on + images that don't have alpha in the original file. + */ + core::dimension2d<u32> dim = image->getDimension(); + baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); + image->copyTo(baseimg); + } + // Else blit on base. + else + { + blitBaseImage(image, baseimg); + } + //cleanup + image->drop(); + } + else + { + // A special texture modification + + /*infostream<<"generateImage(): generating special " + <<"modification \""<<part_of_name<<"\"" + <<std::endl;*/ + + /* + [crack:N:P + [cracko:N:P + Adds a cracking texture + N = animation frame count, P = crack progression + */ + if (str_starts_with(part_of_name, "[crack")) + { + if (baseimg == NULL) { + errorstream<<"generateImagePart(): baseimg == NULL " + <<"for part_of_name=\""<<part_of_name + <<"\", cancelling."<<std::endl; + return false; + } + + // Crack image number and overlay option + // Format: crack[o][:<tiles>]:<frame_count>:<frame> + bool use_overlay = (part_of_name[6] == 'o'); + Strfnd sf(part_of_name); + sf.next(":"); + s32 frame_count = stoi(sf.next(":")); + s32 progression = stoi(sf.next(":")); + s32 tiles = 1; + // Check whether there is the <tiles> argument, that is, + // whether there are 3 arguments. If so, shift values + // as the first and not the last argument is optional. + auto s = sf.next(":"); + if (!s.empty()) { + tiles = frame_count; + frame_count = progression; + progression = stoi(s); + } + + if (progression >= 0) { + /* + Load crack image. + + It is an image with a number of cracking stages + horizontally tiled. + */ + video::IImage *img_crack = m_sourcecache.getOrLoad( + "crack_anylength.png"); + + if (img_crack) { + draw_crack(img_crack, baseimg, + use_overlay, frame_count, + progression, driver, tiles); + img_crack->drop(); + } + } + } + /* + [combine:WxH:X,Y=filename:X,Y=filename2 + Creates a bigger texture from any amount of smaller ones + */ + else if (str_starts_with(part_of_name, "[combine")) + { + Strfnd sf(part_of_name); + sf.next(":"); + u32 w0 = stoi(sf.next("x")); + u32 h0 = stoi(sf.next(":")); + core::dimension2d<u32> dim(w0,h0); + if (baseimg == NULL) { + baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); + baseimg->fill(video::SColor(0,0,0,0)); + } + while (!sf.at_end()) { + u32 x = stoi(sf.next(",")); + u32 y = stoi(sf.next("=")); + std::string filename = unescape_string(sf.next_esc(":", escape), escape); + infostream<<"Adding \""<<filename + <<"\" to combined ("<<x<<","<<y<<")" + <<std::endl; + video::IImage *img = generateImage(filename); + if (img) { + core::dimension2d<u32> dim = img->getDimension(); + core::position2d<s32> pos_base(x, y); + video::IImage *img2 = + driver->createImage(video::ECF_A8R8G8B8, dim); + img->copyTo(img2); + img->drop(); + /*img2->copyToWithAlpha(baseimg, pos_base, + core::rect<s32>(v2s32(0,0), dim), + video::SColor(255,255,255,255), + NULL);*/ + blit_with_alpha(img2, baseimg, v2s32(0,0), pos_base, dim); + img2->drop(); + } else { + errorstream << "generateImagePart(): Failed to load image \"" + << filename << "\" for [combine" << std::endl; + } + } + } + /* + [brighten + */ + else if (str_starts_with(part_of_name, "[brighten")) + { + if (baseimg == NULL) { + errorstream<<"generateImagePart(): baseimg==NULL " + <<"for part_of_name=\""<<part_of_name + <<"\", cancelling."<<std::endl; + return false; + } + + brighten(baseimg); + } + /* + [noalpha + Make image completely opaque. + Used for the leaves texture when in old leaves mode, so + that the transparent parts don't look completely black + when simple alpha channel is used for rendering. + */ + else if (str_starts_with(part_of_name, "[noalpha")) + { + if (baseimg == NULL){ + errorstream<<"generateImagePart(): baseimg==NULL " + <<"for part_of_name=\""<<part_of_name + <<"\", cancelling."<<std::endl; + return false; + } + + core::dimension2d<u32> dim = baseimg->getDimension(); + + // Set alpha to full + for (u32 y=0; y<dim.Height; y++) + for (u32 x=0; x<dim.Width; x++) + { + video::SColor c = baseimg->getPixel(x,y); + c.setAlpha(255); + baseimg->setPixel(x,y,c); + } + } + /* + [makealpha:R,G,B + Convert one color to transparent. + */ + else if (str_starts_with(part_of_name, "[makealpha:")) + { + if (baseimg == NULL) { + errorstream<<"generateImagePart(): baseimg == NULL " + <<"for part_of_name=\""<<part_of_name + <<"\", cancelling."<<std::endl; + return false; + } + + Strfnd sf(part_of_name.substr(11)); + u32 r1 = stoi(sf.next(",")); + u32 g1 = stoi(sf.next(",")); + u32 b1 = stoi(sf.next("")); + + core::dimension2d<u32> dim = baseimg->getDimension(); + + /*video::IImage *oldbaseimg = baseimg; + baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); + oldbaseimg->copyTo(baseimg); + oldbaseimg->drop();*/ + + // Set alpha to full + for (u32 y=0; y<dim.Height; y++) + for (u32 x=0; x<dim.Width; x++) + { + video::SColor c = baseimg->getPixel(x,y); + u32 r = c.getRed(); + u32 g = c.getGreen(); + u32 b = c.getBlue(); + if (!(r == r1 && g == g1 && b == b1)) + continue; + c.setAlpha(0); + baseimg->setPixel(x,y,c); + } + } + /* + [transformN + Rotates and/or flips the image. + + N can be a number (between 0 and 7) or a transform name. + Rotations are counter-clockwise. + 0 I identity + 1 R90 rotate by 90 degrees + 2 R180 rotate by 180 degrees + 3 R270 rotate by 270 degrees + 4 FX flip X + 5 FXR90 flip X then rotate by 90 degrees + 6 FY flip Y + 7 FYR90 flip Y then rotate by 90 degrees + + Note: Transform names can be concatenated to produce + their product (applies the first then the second). + The resulting transform will be equivalent to one of the + eight existing ones, though (see: dihedral group). + */ + else if (str_starts_with(part_of_name, "[transform")) + { + if (baseimg == NULL) { + errorstream<<"generateImagePart(): baseimg == NULL " + <<"for part_of_name=\""<<part_of_name + <<"\", cancelling."<<std::endl; + return false; + } + + u32 transform = parseImageTransform(part_of_name.substr(10)); + core::dimension2d<u32> dim = imageTransformDimension( + transform, baseimg->getDimension()); + video::IImage *image = driver->createImage( + baseimg->getColorFormat(), dim); + sanity_check(image != NULL); + imageTransform(transform, baseimg, image); + baseimg->drop(); + baseimg = image; + } + /* + [inventorycube{topimage{leftimage{rightimage + In every subimage, replace ^ with &. + Create an "inventory cube". + NOTE: This should be used only on its own. + Example (a grass block (not actually used in game): + "[inventorycube{grass.png{mud.png&grass_side.png{mud.png&grass_side.png" + */ + else if (str_starts_with(part_of_name, "[inventorycube")) + { + if (baseimg != NULL){ + errorstream<<"generateImagePart(): baseimg != NULL " + <<"for part_of_name=\""<<part_of_name + <<"\", cancelling."<<std::endl; + return false; + } + + str_replace(part_of_name, '&', '^'); + Strfnd sf(part_of_name); + sf.next("{"); + std::string imagename_top = sf.next("{"); + std::string imagename_left = sf.next("{"); + std::string imagename_right = sf.next("{"); + + // Generate images for the faces of the cube + video::IImage *img_top = generateImage(imagename_top); + video::IImage *img_left = generateImage(imagename_left); + video::IImage *img_right = generateImage(imagename_right); + + if (img_top == NULL || img_left == NULL || img_right == NULL) { + errorstream << "generateImagePart(): Failed to create textures" + << " for inventorycube \"" << part_of_name << "\"" + << std::endl; + baseimg = generateImage(imagename_top); + return true; + } + + baseimg = createInventoryCubeImage(img_top, img_left, img_right); + + // Face images are not needed anymore + img_top->drop(); + img_left->drop(); + img_right->drop(); + + return true; + } + /* + [lowpart:percent:filename + Adds the lower part of a texture + */ + else if (str_starts_with(part_of_name, "[lowpart:")) + { + Strfnd sf(part_of_name); + sf.next(":"); + u32 percent = stoi(sf.next(":")); + std::string filename = unescape_string(sf.next_esc(":", escape), escape); + + if (baseimg == NULL) + baseimg = driver->createImage(video::ECF_A8R8G8B8, v2u32(16,16)); + video::IImage *img = generateImage(filename); + if (img) + { + core::dimension2d<u32> dim = img->getDimension(); + core::position2d<s32> pos_base(0, 0); + video::IImage *img2 = + driver->createImage(video::ECF_A8R8G8B8, dim); + img->copyTo(img2); + img->drop(); + core::position2d<s32> clippos(0, 0); + clippos.Y = dim.Height * (100-percent) / 100; + core::dimension2d<u32> clipdim = dim; + clipdim.Height = clipdim.Height * percent / 100 + 1; + core::rect<s32> cliprect(clippos, clipdim); + img2->copyToWithAlpha(baseimg, pos_base, + core::rect<s32>(v2s32(0,0), dim), + video::SColor(255,255,255,255), + &cliprect); + img2->drop(); + } + } + /* + [verticalframe:N:I + Crops a frame of a vertical animation. + N = frame count, I = frame index + */ + else if (str_starts_with(part_of_name, "[verticalframe:")) + { + Strfnd sf(part_of_name); + sf.next(":"); + u32 frame_count = stoi(sf.next(":")); + u32 frame_index = stoi(sf.next(":")); + + if (baseimg == NULL){ + errorstream<<"generateImagePart(): baseimg != NULL " + <<"for part_of_name=\""<<part_of_name + <<"\", cancelling."<<std::endl; + return false; + } + + v2u32 frame_size = baseimg->getDimension(); + frame_size.Y /= frame_count; + + video::IImage *img = driver->createImage(video::ECF_A8R8G8B8, + frame_size); + if (!img){ + errorstream<<"generateImagePart(): Could not create image " + <<"for part_of_name=\""<<part_of_name + <<"\", cancelling."<<std::endl; + return false; + } + + // Fill target image with transparency + img->fill(video::SColor(0,0,0,0)); + + core::dimension2d<u32> dim = frame_size; + core::position2d<s32> pos_dst(0, 0); + core::position2d<s32> pos_src(0, frame_index * frame_size.Y); + baseimg->copyToWithAlpha(img, pos_dst, + core::rect<s32>(pos_src, dim), + video::SColor(255,255,255,255), + NULL); + // Replace baseimg + baseimg->drop(); + baseimg = img; + } + /* + [mask:filename + Applies a mask to an image + */ + else if (str_starts_with(part_of_name, "[mask:")) + { + if (baseimg == NULL) { + errorstream << "generateImage(): baseimg == NULL " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + Strfnd sf(part_of_name); + sf.next(":"); + std::string filename = unescape_string(sf.next_esc(":", escape), escape); + + video::IImage *img = generateImage(filename); + if (img) { + apply_mask(img, baseimg, v2s32(0, 0), v2s32(0, 0), + img->getDimension()); + img->drop(); + } else { + errorstream << "generateImage(): Failed to load \"" + << filename << "\"."; + } + } + /* + [multiply:color + multiplys a given color to any pixel of an image + color = color as ColorString + */ + else if (str_starts_with(part_of_name, "[multiply:")) { + Strfnd sf(part_of_name); + sf.next(":"); + std::string color_str = sf.next(":"); + + if (baseimg == NULL) { + errorstream << "generateImagePart(): baseimg != NULL " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + + video::SColor color; + + if (!parseColorString(color_str, color, false)) + return false; + + apply_multiplication(baseimg, v2u32(0, 0), baseimg->getDimension(), color); + } + /* + [colorize:color + Overlays image with given color + color = color as ColorString + */ + else if (str_starts_with(part_of_name, "[colorize:")) + { + Strfnd sf(part_of_name); + sf.next(":"); + std::string color_str = sf.next(":"); + std::string ratio_str = sf.next(":"); + + if (baseimg == NULL) { + errorstream << "generateImagePart(): baseimg != NULL " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + + video::SColor color; + int ratio = -1; + bool keep_alpha = false; + + if (!parseColorString(color_str, color, false)) + return false; + + if (is_number(ratio_str)) + ratio = mystoi(ratio_str, 0, 255); + else if (ratio_str == "alpha") + keep_alpha = true; + + apply_colorize(baseimg, v2u32(0, 0), baseimg->getDimension(), color, ratio, keep_alpha); + } + /* + [applyfiltersformesh + Internal modifier + */ + else if (str_starts_with(part_of_name, "[applyfiltersformesh")) + { + /* IMPORTANT: When changing this, getTextureForMesh() needs to be + * updated too. */ + + if (!baseimg) { + errorstream << "generateImagePart(): baseimg == NULL " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + + // Apply the "clean transparent" filter, if needed + if (m_setting_mipmap || g_settings->getBool("texture_clean_transparent")) + imageCleanTransparent(baseimg, 127); + + /* Upscale textures to user's requested minimum size. This is a trick to make + * filters look as good on low-res textures as on high-res ones, by making + * low-res textures BECOME high-res ones. This is helpful for worlds that + * mix high- and low-res textures, or for mods with least-common-denominator + * textures that don't have the resources to offer high-res alternatives. + */ + const bool filter = m_setting_trilinear_filter || m_setting_bilinear_filter; + const s32 scaleto = filter ? g_settings->getU16("texture_min_size") : 1; + if (scaleto > 1) { + const core::dimension2d<u32> dim = baseimg->getDimension(); + + /* Calculate scaling needed to make the shortest texture dimension + * equal to the target minimum. If e.g. this is a vertical frames + * animation, the short dimension will be the real size. + */ + if ((dim.Width == 0) || (dim.Height == 0)) { + errorstream << "generateImagePart(): Illegal 0 dimension " + << "for part_of_name=\""<< part_of_name + << "\", cancelling." << std::endl; + return false; + } + u32 xscale = scaleto / dim.Width; + u32 yscale = scaleto / dim.Height; + u32 scale = (xscale > yscale) ? xscale : yscale; + + // Never downscale; only scale up by 2x or more. + if (scale > 1) { + u32 w = scale * dim.Width; + u32 h = scale * dim.Height; + const core::dimension2d<u32> newdim = core::dimension2d<u32>(w, h); + video::IImage *newimg = driver->createImage( + baseimg->getColorFormat(), newdim); + baseimg->copyToScaling(newimg); + baseimg->drop(); + baseimg = newimg; + } + } + } + /* + [resize:WxH + Resizes the base image to the given dimensions + */ + else if (str_starts_with(part_of_name, "[resize")) + { + if (baseimg == NULL) { + errorstream << "generateImagePart(): baseimg == NULL " + << "for part_of_name=\""<< part_of_name + << "\", cancelling." << std::endl; + return false; + } + + Strfnd sf(part_of_name); + sf.next(":"); + u32 width = stoi(sf.next("x")); + u32 height = stoi(sf.next("")); + core::dimension2d<u32> dim(width, height); + + video::IImage *image = RenderingEngine::get_video_driver()-> + createImage(video::ECF_A8R8G8B8, dim); + baseimg->copyToScaling(image); + baseimg->drop(); + baseimg = image; + } + /* + [opacity:R + Makes the base image transparent according to the given ratio. + R must be between 0 and 255. + 0 means totally transparent. + 255 means totally opaque. + */ + else if (str_starts_with(part_of_name, "[opacity:")) { + if (baseimg == NULL) { + errorstream << "generateImagePart(): baseimg == NULL " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + + Strfnd sf(part_of_name); + sf.next(":"); + + u32 ratio = mystoi(sf.next(""), 0, 255); + + core::dimension2d<u32> dim = baseimg->getDimension(); + + for (u32 y = 0; y < dim.Height; y++) + for (u32 x = 0; x < dim.Width; x++) + { + video::SColor c = baseimg->getPixel(x, y); + c.setAlpha(floor((c.getAlpha() * ratio) / 255 + 0.5)); + baseimg->setPixel(x, y, c); + } + } + /* + [invert:mode + Inverts the given channels of the base image. + Mode may contain the characters "r", "g", "b", "a". + Only the channels that are mentioned in the mode string + will be inverted. + */ + else if (str_starts_with(part_of_name, "[invert:")) { + if (baseimg == NULL) { + errorstream << "generateImagePart(): baseimg == NULL " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + + Strfnd sf(part_of_name); + sf.next(":"); + + std::string mode = sf.next(""); + u32 mask = 0; + if (mode.find('a') != std::string::npos) + mask |= 0xff000000UL; + if (mode.find('r') != std::string::npos) + mask |= 0x00ff0000UL; + if (mode.find('g') != std::string::npos) + mask |= 0x0000ff00UL; + if (mode.find('b') != std::string::npos) + mask |= 0x000000ffUL; + + core::dimension2d<u32> dim = baseimg->getDimension(); + + for (u32 y = 0; y < dim.Height; y++) + for (u32 x = 0; x < dim.Width; x++) + { + video::SColor c = baseimg->getPixel(x, y); + c.color ^= mask; + baseimg->setPixel(x, y, c); + } + } + /* + [sheet:WxH:X,Y + Retrieves a tile at position X,Y (in tiles) + from the base image it assumes to be a + tilesheet with dimensions W,H (in tiles). + */ + else if (part_of_name.substr(0,7) == "[sheet:") { + if (baseimg == NULL) { + errorstream << "generateImagePart(): baseimg != NULL " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + + Strfnd sf(part_of_name); + sf.next(":"); + u32 w0 = stoi(sf.next("x")); + u32 h0 = stoi(sf.next(":")); + u32 x0 = stoi(sf.next(",")); + u32 y0 = stoi(sf.next(":")); + + core::dimension2d<u32> img_dim = baseimg->getDimension(); + core::dimension2d<u32> tile_dim(v2u32(img_dim) / v2u32(w0, h0)); + + video::IImage *img = driver->createImage( + video::ECF_A8R8G8B8, tile_dim); + if (!img) { + errorstream << "generateImagePart(): Could not create image " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + + img->fill(video::SColor(0,0,0,0)); + v2u32 vdim(tile_dim); + core::rect<s32> rect(v2s32(x0 * vdim.X, y0 * vdim.Y), tile_dim); + baseimg->copyToWithAlpha(img, v2s32(0), rect, + video::SColor(255,255,255,255), NULL); + + // Replace baseimg + baseimg->drop(); + baseimg = img; + } + /* + [png:base64 + Decodes a PNG image in base64 form. + Use minetest.encode_png and minetest.encode_base64 + to produce a valid string. + */ + else if (str_starts_with(part_of_name, "[png:")) { + Strfnd sf(part_of_name); + sf.next(":"); + std::string png; + { + std::string blob = sf.next(""); + if (!base64_is_valid(blob)) { + errorstream << "generateImagePart(): " + << "malformed base64 in '[png'" + << std::endl; + return false; + } + png = base64_decode(blob); + } + + auto *device = RenderingEngine::get_raw_device(); + auto *fs = device->getFileSystem(); + auto *vd = device->getVideoDriver(); + auto *memfile = fs->createMemoryReadFile(png.data(), png.size(), "__temp_png"); + video::IImage* pngimg = vd->createImageFromFile(memfile); + memfile->drop(); + + if (baseimg) { + blitBaseImage(pngimg, baseimg); + } else { + core::dimension2d<u32> dim = pngimg->getDimension(); + baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); + pngimg->copyTo(baseimg); + } + pngimg->drop(); + } + else + { + errorstream << "generateImagePart(): Invalid " + " modification: \"" << part_of_name << "\"" << std::endl; + } + } + + return true; +} + +/* + Calculate the color of a single pixel drawn on top of another pixel. + + This is a little more complicated than just video::SColor::getInterpolated + because getInterpolated does not handle alpha correctly. For example, a + pixel with alpha=64 drawn atop a pixel with alpha=128 should yield a + pixel with alpha=160, while getInterpolated would yield alpha=96. +*/ +static inline video::SColor blitPixel(const video::SColor &src_c, const video::SColor &dst_c, u32 ratio) +{ + if (dst_c.getAlpha() == 0) + return src_c; + video::SColor out_c = src_c.getInterpolated(dst_c, (float)ratio / 255.0f); + out_c.setAlpha(dst_c.getAlpha() + (255 - dst_c.getAlpha()) * + src_c.getAlpha() * ratio / (255 * 255)); + return out_c; +} + +/* + Draw an image on top of an another one, using the alpha channel of the + source image + + This exists because IImage::copyToWithAlpha() doesn't seem to always + work. +*/ +static void blit_with_alpha(video::IImage *src, video::IImage *dst, + v2s32 src_pos, v2s32 dst_pos, v2u32 size) +{ + for (u32 y0=0; y0<size.Y; y0++) + for (u32 x0=0; x0<size.X; x0++) + { + s32 src_x = src_pos.X + x0; + s32 src_y = src_pos.Y + y0; + s32 dst_x = dst_pos.X + x0; + s32 dst_y = dst_pos.Y + y0; + video::SColor src_c = src->getPixel(src_x, src_y); + video::SColor dst_c = dst->getPixel(dst_x, dst_y); + dst_c = blitPixel(src_c, dst_c, src_c.getAlpha()); + dst->setPixel(dst_x, dst_y, dst_c); + } +} + +/* + Draw an image on top of an another one, using the alpha channel of the + source image; only modify fully opaque pixels in destinaion +*/ +static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst, + v2s32 src_pos, v2s32 dst_pos, v2u32 size) +{ + for (u32 y0=0; y0<size.Y; y0++) + for (u32 x0=0; x0<size.X; x0++) + { + s32 src_x = src_pos.X + x0; + s32 src_y = src_pos.Y + y0; + s32 dst_x = dst_pos.X + x0; + s32 dst_y = dst_pos.Y + y0; + video::SColor src_c = src->getPixel(src_x, src_y); + video::SColor dst_c = dst->getPixel(dst_x, dst_y); + if (dst_c.getAlpha() == 255 && src_c.getAlpha() != 0) + { + dst_c = blitPixel(src_c, dst_c, src_c.getAlpha()); + dst->setPixel(dst_x, dst_y, dst_c); + } + } +} + +// This function has been disabled because it is currently unused. +// Feel free to re-enable if you find it handy. +#if 0 +/* + Draw an image on top of an another one, using the specified ratio + modify all partially-opaque pixels in the destination. +*/ +static void blit_with_interpolate_overlay(video::IImage *src, video::IImage *dst, + v2s32 src_pos, v2s32 dst_pos, v2u32 size, int ratio) +{ + for (u32 y0 = 0; y0 < size.Y; y0++) + for (u32 x0 = 0; x0 < size.X; x0++) + { + s32 src_x = src_pos.X + x0; + s32 src_y = src_pos.Y + y0; + s32 dst_x = dst_pos.X + x0; + s32 dst_y = dst_pos.Y + y0; + video::SColor src_c = src->getPixel(src_x, src_y); + video::SColor dst_c = dst->getPixel(dst_x, dst_y); + if (dst_c.getAlpha() > 0 && src_c.getAlpha() != 0) + { + if (ratio == -1) + dst_c = src_c.getInterpolated(dst_c, (float)src_c.getAlpha()/255.0f); + else + dst_c = src_c.getInterpolated(dst_c, (float)ratio/255.0f); + dst->setPixel(dst_x, dst_y, dst_c); + } + } +} +#endif + +/* + Apply color to destination +*/ +static void apply_colorize(video::IImage *dst, v2u32 dst_pos, v2u32 size, + const video::SColor &color, int ratio, bool keep_alpha) +{ + u32 alpha = color.getAlpha(); + video::SColor dst_c; + if ((ratio == -1 && alpha == 255) || ratio == 255) { // full replacement of color + if (keep_alpha) { // replace the color with alpha = dest alpha * color alpha + dst_c = color; + for (u32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++) + for (u32 x = dst_pos.X; x < dst_pos.X + size.X; x++) { + u32 dst_alpha = dst->getPixel(x, y).getAlpha(); + if (dst_alpha > 0) { + dst_c.setAlpha(dst_alpha * alpha / 255); + dst->setPixel(x, y, dst_c); + } + } + } else { // replace the color including the alpha + for (u32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++) + for (u32 x = dst_pos.X; x < dst_pos.X + size.X; x++) + if (dst->getPixel(x, y).getAlpha() > 0) + dst->setPixel(x, y, color); + } + } else { // interpolate between the color and destination + float interp = (ratio == -1 ? color.getAlpha() / 255.0f : ratio / 255.0f); + for (u32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++) + for (u32 x = dst_pos.X; x < dst_pos.X + size.X; x++) { + dst_c = dst->getPixel(x, y); + if (dst_c.getAlpha() > 0) { + dst_c = color.getInterpolated(dst_c, interp); + dst->setPixel(x, y, dst_c); + } + } + } +} + +/* + Apply color to destination +*/ +static void apply_multiplication(video::IImage *dst, v2u32 dst_pos, v2u32 size, + const video::SColor &color) +{ + video::SColor dst_c; + + for (u32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++) + for (u32 x = dst_pos.X; x < dst_pos.X + size.X; x++) { + dst_c = dst->getPixel(x, y); + dst_c.set( + dst_c.getAlpha(), + (dst_c.getRed() * color.getRed()) / 255, + (dst_c.getGreen() * color.getGreen()) / 255, + (dst_c.getBlue() * color.getBlue()) / 255 + ); + dst->setPixel(x, y, dst_c); + } +} + +/* + Apply mask to destination +*/ +static void apply_mask(video::IImage *mask, video::IImage *dst, + v2s32 mask_pos, v2s32 dst_pos, v2u32 size) +{ + for (u32 y0 = 0; y0 < size.Y; y0++) { + for (u32 x0 = 0; x0 < size.X; x0++) { + s32 mask_x = x0 + mask_pos.X; + s32 mask_y = y0 + mask_pos.Y; + s32 dst_x = x0 + dst_pos.X; + s32 dst_y = y0 + dst_pos.Y; + video::SColor mask_c = mask->getPixel(mask_x, mask_y); + video::SColor dst_c = dst->getPixel(dst_x, dst_y); + dst_c.color &= mask_c.color; + dst->setPixel(dst_x, dst_y, dst_c); + } + } +} + +video::IImage *create_crack_image(video::IImage *crack, s32 frame_index, + core::dimension2d<u32> size, u8 tiles, video::IVideoDriver *driver) +{ + core::dimension2d<u32> strip_size = crack->getDimension(); + core::dimension2d<u32> frame_size(strip_size.Width, strip_size.Width); + core::dimension2d<u32> tile_size(size / tiles); + s32 frame_count = strip_size.Height / strip_size.Width; + if (frame_index >= frame_count) + frame_index = frame_count - 1; + core::rect<s32> frame(v2s32(0, frame_index * frame_size.Height), frame_size); + video::IImage *result = nullptr; + +// extract crack frame + video::IImage *crack_tile = driver->createImage(video::ECF_A8R8G8B8, tile_size); + if (!crack_tile) + return nullptr; + if (tile_size == frame_size) { + crack->copyTo(crack_tile, v2s32(0, 0), frame); + } else { + video::IImage *crack_frame = driver->createImage(video::ECF_A8R8G8B8, frame_size); + if (!crack_frame) + goto exit__has_tile; + crack->copyTo(crack_frame, v2s32(0, 0), frame); + crack_frame->copyToScaling(crack_tile); + crack_frame->drop(); + } + if (tiles == 1) + return crack_tile; + +// tile it + result = driver->createImage(video::ECF_A8R8G8B8, size); + if (!result) + goto exit__has_tile; + result->fill({}); + for (u8 i = 0; i < tiles; i++) + for (u8 j = 0; j < tiles; j++) + crack_tile->copyTo(result, v2s32(i * tile_size.Width, j * tile_size.Height)); + +exit__has_tile: + crack_tile->drop(); + return result; +} + +static void draw_crack(video::IImage *crack, video::IImage *dst, + bool use_overlay, s32 frame_count, s32 progression, + video::IVideoDriver *driver, u8 tiles) +{ + // Dimension of destination image + core::dimension2d<u32> dim_dst = dst->getDimension(); + // Limit frame_count + if (frame_count > (s32) dim_dst.Height) + frame_count = dim_dst.Height; + if (frame_count < 1) + frame_count = 1; + // Dimension of the scaled crack stage, + // which is the same as the dimension of a single destination frame + core::dimension2d<u32> frame_size( + dim_dst.Width, + dim_dst.Height / frame_count + ); + video::IImage *crack_scaled = create_crack_image(crack, progression, + frame_size, tiles, driver); + if (!crack_scaled) + return; + + auto blit = use_overlay ? blit_with_alpha_overlay : blit_with_alpha; + for (s32 i = 0; i < frame_count; ++i) { + v2s32 dst_pos(0, frame_size.Height * i); + blit(crack_scaled, dst, v2s32(0,0), dst_pos, frame_size); + } + + crack_scaled->drop(); +} + +void brighten(video::IImage *image) +{ + if (image == NULL) + return; + + core::dimension2d<u32> dim = image->getDimension(); + + for (u32 y=0; y<dim.Height; y++) + for (u32 x=0; x<dim.Width; x++) + { + video::SColor c = image->getPixel(x,y); + c.setRed(0.5 * 255 + 0.5 * (float)c.getRed()); + c.setGreen(0.5 * 255 + 0.5 * (float)c.getGreen()); + c.setBlue(0.5 * 255 + 0.5 * (float)c.getBlue()); + image->setPixel(x,y,c); + } +} + +u32 parseImageTransform(const std::string& s) +{ + int total_transform = 0; + + std::string transform_names[8]; + transform_names[0] = "i"; + transform_names[1] = "r90"; + transform_names[2] = "r180"; + transform_names[3] = "r270"; + transform_names[4] = "fx"; + transform_names[6] = "fy"; + + std::size_t pos = 0; + while(pos < s.size()) + { + int transform = -1; + for (int i = 0; i <= 7; ++i) + { + const std::string &name_i = transform_names[i]; + + if (s[pos] == ('0' + i)) + { + transform = i; + pos++; + break; + } + + if (!(name_i.empty()) && lowercase(s.substr(pos, name_i.size())) == name_i) { + transform = i; + pos += name_i.size(); + break; + } + } + if (transform < 0) + break; + + // Multiply total_transform and transform in the group D4 + int new_total = 0; + if (transform < 4) + new_total = (transform + total_transform) % 4; + else + new_total = (transform - total_transform + 8) % 4; + if ((transform >= 4) ^ (total_transform >= 4)) + new_total += 4; + + total_transform = new_total; + } + return total_transform; +} + +core::dimension2d<u32> imageTransformDimension(u32 transform, core::dimension2d<u32> dim) +{ + if (transform % 2 == 0) + return dim; + + return core::dimension2d<u32>(dim.Height, dim.Width); +} + +void imageTransform(u32 transform, video::IImage *src, video::IImage *dst) +{ + if (src == NULL || dst == NULL) + return; + + core::dimension2d<u32> dstdim = dst->getDimension(); + + // Pre-conditions + assert(dstdim == imageTransformDimension(transform, src->getDimension())); + assert(transform <= 7); + + /* + Compute the transformation from source coordinates (sx,sy) + to destination coordinates (dx,dy). + */ + int sxn = 0; + int syn = 2; + if (transform == 0) // identity + sxn = 0, syn = 2; // sx = dx, sy = dy + else if (transform == 1) // rotate by 90 degrees ccw + sxn = 3, syn = 0; // sx = (H-1) - dy, sy = dx + else if (transform == 2) // rotate by 180 degrees + sxn = 1, syn = 3; // sx = (W-1) - dx, sy = (H-1) - dy + else if (transform == 3) // rotate by 270 degrees ccw + sxn = 2, syn = 1; // sx = dy, sy = (W-1) - dx + else if (transform == 4) // flip x + sxn = 1, syn = 2; // sx = (W-1) - dx, sy = dy + else if (transform == 5) // flip x then rotate by 90 degrees ccw + sxn = 2, syn = 0; // sx = dy, sy = dx + else if (transform == 6) // flip y + sxn = 0, syn = 3; // sx = dx, sy = (H-1) - dy + else if (transform == 7) // flip y then rotate by 90 degrees ccw + sxn = 3, syn = 1; // sx = (H-1) - dy, sy = (W-1) - dx + + for (u32 dy=0; dy<dstdim.Height; dy++) + for (u32 dx=0; dx<dstdim.Width; dx++) + { + u32 entries[4] = {dx, dstdim.Width-1-dx, dy, dstdim.Height-1-dy}; + u32 sx = entries[sxn]; + u32 sy = entries[syn]; + video::SColor c = src->getPixel(sx,sy); + dst->setPixel(dx,dy,c); + } +} + +video::ITexture* TextureSource::getNormalTexture(const std::string &name) +{ + if (isKnownSourceImage("override_normal.png")) + return getTexture("override_normal.png"); + std::string fname_base = name; + static const char *normal_ext = "_normal.png"; + static const u32 normal_ext_size = strlen(normal_ext); + size_t pos = fname_base.find('.'); + std::string fname_normal = fname_base.substr(0, pos) + normal_ext; + if (isKnownSourceImage(fname_normal)) { + // look for image extension and replace it + size_t i = 0; + while ((i = fname_base.find('.', i)) != std::string::npos) { + fname_base.replace(i, 4, normal_ext); + i += normal_ext_size; + } + return getTexture(fname_base); + } + return NULL; +} + +namespace { + // For more colourspace transformations, see for example + // https://github.com/tobspr/GLSL-Color-Spaces/blob/master/ColorSpaces.inc.glsl + + inline float linear_to_srgb_component(float v) + { + if (v > 0.0031308f) + return 1.055f * powf(v, 1.0f / 2.4f) - 0.055f; + return 12.92f * v; + } + inline float srgb_to_linear_component(float v) + { + if (v > 0.04045f) + return powf((v + 0.055f) / 1.055f, 2.4f); + return v / 12.92f; + } + + v3f srgb_to_linear(const video::SColor &col_srgb) + { + v3f col(col_srgb.getRed(), col_srgb.getGreen(), col_srgb.getBlue()); + col /= 255.0f; + col.X = srgb_to_linear_component(col.X); + col.Y = srgb_to_linear_component(col.Y); + col.Z = srgb_to_linear_component(col.Z); + return col; + } + + video::SColor linear_to_srgb(const v3f &col_linear) + { + v3f col; + col.X = linear_to_srgb_component(col_linear.X); + col.Y = linear_to_srgb_component(col_linear.Y); + col.Z = linear_to_srgb_component(col_linear.Z); + col *= 255.0f; + col.X = core::clamp<float>(col.X, 0.0f, 255.0f); + col.Y = core::clamp<float>(col.Y, 0.0f, 255.0f); + col.Z = core::clamp<float>(col.Z, 0.0f, 255.0f); + return video::SColor(0xff, myround(col.X), myround(col.Y), + myround(col.Z)); + } +} + +video::SColor TextureSource::getTextureAverageColor(const std::string &name) +{ + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + video::SColor c(0, 0, 0, 0); + video::ITexture *texture = getTexture(name); + if (!texture) + return c; + video::IImage *image = driver->createImage(texture, + core::position2d<s32>(0, 0), + texture->getOriginalSize()); + if (!image) + return c; + + u32 total = 0; + v3f col_acc(0, 0, 0); + core::dimension2d<u32> dim = image->getDimension(); + u16 step = 1; + if (dim.Width > 16) + step = dim.Width / 16; + for (u16 x = 0; x < dim.Width; x += step) { + for (u16 y = 0; y < dim.Width; y += step) { + c = image->getPixel(x,y); + if (c.getAlpha() > 0) { + total++; + col_acc += srgb_to_linear(c); + } + } + } + image->drop(); + if (total > 0) { + col_acc /= total; + c = linear_to_srgb(col_acc); + } + c.setAlpha(255); + return c; +} + + +video::ITexture *TextureSource::getShaderFlagsTexture(bool normalmap_present) +{ + std::string tname = "__shaderFlagsTexture"; + tname += normalmap_present ? "1" : "0"; + + if (isKnownSourceImage(tname)) { + return getTexture(tname); + } + + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + video::IImage *flags_image = driver->createImage( + video::ECF_A8R8G8B8, core::dimension2d<u32>(1, 1)); + sanity_check(flags_image != NULL); + video::SColor c(255, normalmap_present ? 255 : 0, 0, 0); + flags_image->setPixel(0, 0, c); + insertSourceImage(tname, flags_image); + flags_image->drop(); + return getTexture(tname); + +} + +std::vector<std::string> getTextureDirs() +{ + return fs::GetRecursiveDirs(g_settings->get("texture_path")); +} diff --git a/src/client/tile.h b/src/client/tile.h new file mode 100644 index 0000000..e55a26e --- /dev/null +++ b/src/client/tile.h @@ -0,0 +1,341 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "irr_v3d.h" +#include <ITexture.h> +#include <string> +#include <vector> +#include <SMaterial.h> +#include "util/numeric.h" +#include "config.h" + +#if ENABLE_GLES +#include <IVideoDriver.h> +#endif + +class IGameDef; +struct TileSpec; +struct TileDef; + +typedef std::vector<video::SColor> Palette; + +/* + tile.{h,cpp}: Texture handling stuff. +*/ + +/* + Find out the full path of an image by trying different filename + extensions. + + If failed, return "". + + TODO: Should probably be moved out from here, because things needing + this function do not need anything else from this header +*/ +std::string getImagePath(std::string path); + +/* + Gets the path to a texture by first checking if the texture exists + in texture_path and if not, using the data path. + + Checks all supported extensions by replacing the original extension. + + If not found, returns "". + + Utilizes a thread-safe cache. +*/ +std::string getTexturePath(const std::string &filename, bool *is_base_pack = nullptr); + +void clearTextureNameCache(); + +/* + TextureSource creates and caches textures. +*/ + +class ISimpleTextureSource +{ +public: + ISimpleTextureSource() = default; + + virtual ~ISimpleTextureSource() = default; + + virtual video::ITexture* getTexture( + const std::string &name, u32 *id = nullptr) = 0; +}; + +class ITextureSource : public ISimpleTextureSource +{ +public: + ITextureSource() = default; + + virtual ~ITextureSource() = default; + + virtual u32 getTextureId(const std::string &name)=0; + virtual std::string getTextureName(u32 id)=0; + virtual video::ITexture* getTexture(u32 id)=0; + virtual video::ITexture* getTexture( + const std::string &name, u32 *id = nullptr)=0; + virtual video::ITexture* getTextureForMesh( + const std::string &name, u32 *id = nullptr) = 0; + /*! + * Returns a palette from the given texture name. + * The pointer is valid until the texture source is + * destructed. + * Should be called from the main thread. + */ + virtual Palette* getPalette(const std::string &name) = 0; + virtual bool isKnownSourceImage(const std::string &name)=0; + virtual video::ITexture* getNormalTexture(const std::string &name)=0; + virtual video::SColor getTextureAverageColor(const std::string &name)=0; + virtual video::ITexture *getShaderFlagsTexture(bool normalmap_present)=0; +}; + +class IWritableTextureSource : public ITextureSource +{ +public: + IWritableTextureSource() = default; + + virtual ~IWritableTextureSource() = default; + + virtual u32 getTextureId(const std::string &name)=0; + virtual std::string getTextureName(u32 id)=0; + virtual video::ITexture* getTexture(u32 id)=0; + virtual video::ITexture* getTexture( + const std::string &name, u32 *id = nullptr)=0; + virtual bool isKnownSourceImage(const std::string &name)=0; + + virtual void processQueue()=0; + virtual void insertSourceImage(const std::string &name, video::IImage *img)=0; + virtual void rebuildImagesAndTextures()=0; + virtual video::ITexture* getNormalTexture(const std::string &name)=0; + virtual video::SColor getTextureAverageColor(const std::string &name)=0; + virtual video::ITexture *getShaderFlagsTexture(bool normalmap_present)=0; +}; + +IWritableTextureSource *createTextureSource(); + +#if ENABLE_GLES +video::IImage *Align2Npot2(video::IImage *image, video::IVideoDriver *driver); +#endif + +enum MaterialType{ + TILE_MATERIAL_BASIC, + TILE_MATERIAL_ALPHA, + TILE_MATERIAL_LIQUID_TRANSPARENT, + TILE_MATERIAL_LIQUID_OPAQUE, + TILE_MATERIAL_WAVING_LEAVES, + TILE_MATERIAL_WAVING_PLANTS, + TILE_MATERIAL_OPAQUE, + TILE_MATERIAL_WAVING_LIQUID_BASIC, + TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT, + TILE_MATERIAL_WAVING_LIQUID_OPAQUE, + TILE_MATERIAL_PLAIN, + TILE_MATERIAL_PLAIN_ALPHA +}; + +// Material flags +// Should backface culling be enabled? +#define MATERIAL_FLAG_BACKFACE_CULLING 0x01 +// Should a crack be drawn? +#define MATERIAL_FLAG_CRACK 0x02 +// Should the crack be drawn on transparent pixels (unset) or not (set)? +// Ignored if MATERIAL_FLAG_CRACK is not set. +#define MATERIAL_FLAG_CRACK_OVERLAY 0x04 +#define MATERIAL_FLAG_ANIMATION 0x08 +//#define MATERIAL_FLAG_HIGHLIGHTED 0x10 +#define MATERIAL_FLAG_TILEABLE_HORIZONTAL 0x20 +#define MATERIAL_FLAG_TILEABLE_VERTICAL 0x40 + +/* + This fully defines the looks of a tile. + The SMaterial of a tile is constructed according to this. +*/ +struct FrameSpec +{ + FrameSpec() = default; + + u32 texture_id = 0; + video::ITexture *texture = nullptr; + video::ITexture *normal_texture = nullptr; + video::ITexture *flags_texture = nullptr; +}; + +#define MAX_TILE_LAYERS 2 + +//! Defines a layer of a tile. +struct TileLayer +{ + TileLayer() = default; + + /*! + * Two layers are equal if they can be merged. + */ + bool operator==(const TileLayer &other) const + { + return + texture_id == other.texture_id && + material_type == other.material_type && + material_flags == other.material_flags && + has_color == other.has_color && + color == other.color && + scale == other.scale; + } + + /*! + * Two tiles are not equal if they must have different vertices. + */ + bool operator!=(const TileLayer &other) const + { + return !(*this == other); + } + + // Sets everything else except the texture in the material + void applyMaterialOptions(video::SMaterial &material) const + { + switch (material_type) { + case TILE_MATERIAL_OPAQUE: + case TILE_MATERIAL_LIQUID_OPAQUE: + case TILE_MATERIAL_WAVING_LIQUID_OPAQUE: + material.MaterialType = video::EMT_SOLID; + break; + case TILE_MATERIAL_BASIC: + case TILE_MATERIAL_WAVING_LEAVES: + case TILE_MATERIAL_WAVING_PLANTS: + case TILE_MATERIAL_WAVING_LIQUID_BASIC: + material.MaterialTypeParam = 0.5; + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + break; + case TILE_MATERIAL_ALPHA: + case TILE_MATERIAL_LIQUID_TRANSPARENT: + case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT: + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + break; + default: + break; + } + material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) != 0; + if (!(material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL)) { + material.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; + } + if (!(material_flags & MATERIAL_FLAG_TILEABLE_VERTICAL)) { + material.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + } + } + + void applyMaterialOptionsWithShaders(video::SMaterial &material) const + { + material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) != 0; + if (!(material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL)) { + material.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; + material.TextureLayer[1].TextureWrapU = video::ETC_CLAMP_TO_EDGE; + } + if (!(material_flags & MATERIAL_FLAG_TILEABLE_VERTICAL)) { + material.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + material.TextureLayer[1].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + } + } + + bool isTileable() const + { + return (material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL) + && (material_flags & MATERIAL_FLAG_TILEABLE_VERTICAL); + } + + bool isTransparent() const + { + switch (material_type) { + case TILE_MATERIAL_ALPHA: + case TILE_MATERIAL_LIQUID_TRANSPARENT: + case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT: + return true; + } + return false; + } + + // Ordered for size, please do not reorder + + video::ITexture *texture = nullptr; + video::ITexture *normal_texture = nullptr; + video::ITexture *flags_texture = nullptr; + + u32 shader_id = 0; + + u32 texture_id = 0; + + u16 animation_frame_length_ms = 0; + u16 animation_frame_count = 1; + + u8 material_type = TILE_MATERIAL_BASIC; + u8 material_flags = + //0 // <- DEBUG, Use the one below + MATERIAL_FLAG_BACKFACE_CULLING | + MATERIAL_FLAG_TILEABLE_HORIZONTAL| + MATERIAL_FLAG_TILEABLE_VERTICAL; + + //! If true, the tile has its own color. + bool has_color = false; + + std::vector<FrameSpec> *frames = nullptr; + + /*! + * The color of the tile, or if the tile does not own + * a color then the color of the node owning this tile. + */ + video::SColor color = video::SColor(0, 0, 0, 0); + + u8 scale = 1; +}; + +/*! + * Defines a face of a node. May have up to two layers. + */ +struct TileSpec +{ + TileSpec() = default; + + /*! + * Returns true if this tile can be merged with the other tile. + */ + bool isTileable(const TileSpec &other) const { + for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) { + if (layers[layer] != other.layers[layer]) + return false; + // Only non-transparent tiles can be merged into fast faces + if (layers[layer].isTransparent() || !layers[layer].isTileable()) + return false; + } + return rotation == 0 + && rotation == other.rotation + && emissive_light == other.emissive_light; + } + + //! If true, the tile rotation is ignored. + bool world_aligned = false; + //! Tile rotation. + u8 rotation = 0; + //! This much light does the tile emit. + u8 emissive_light = 0; + //! The first is base texture, the second is overlay. + TileLayer layers[MAX_TILE_LAYERS]; +}; + +std::vector<std::string> getTextureDirs(); diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp new file mode 100644 index 0000000..0a89e2a --- /dev/null +++ b/src/client/wieldmesh.cpp @@ -0,0 +1,765 @@ +/* +Minetest +Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "wieldmesh.h" +#include "settings.h" +#include "shader.h" +#include "inventory.h" +#include "client.h" +#include "itemdef.h" +#include "nodedef.h" +#include "mesh.h" +#include "content_mapblock.h" +#include "mapblock_mesh.h" +#include "client/meshgen/collector.h" +#include "client/tile.h" +#include "log.h" +#include "util/numeric.h" +#include <map> +#include <IMeshManipulator.h> +#include "client/renderingengine.h" + +#define WIELD_SCALE_FACTOR 30.0 +#define WIELD_SCALE_FACTOR_EXTRUDED 40.0 + +#define MIN_EXTRUSION_MESH_RESOLUTION 16 +#define MAX_EXTRUSION_MESH_RESOLUTION 512 + +static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y) +{ + const f32 r = 0.5; + + scene::IMeshBuffer *buf = new scene::SMeshBuffer(); + video::SColor c(255,255,255,255); + v3f scale(1.0, 1.0, 0.1); + + // Front and back + { + video::S3DVertex vertices[8] = { + // z- + video::S3DVertex(-r,+r,-r, 0,0,-1, c, 0,0), + video::S3DVertex(+r,+r,-r, 0,0,-1, c, 1,0), + video::S3DVertex(+r,-r,-r, 0,0,-1, c, 1,1), + video::S3DVertex(-r,-r,-r, 0,0,-1, c, 0,1), + // z+ + video::S3DVertex(-r,+r,+r, 0,0,+1, c, 0,0), + video::S3DVertex(-r,-r,+r, 0,0,+1, c, 0,1), + video::S3DVertex(+r,-r,+r, 0,0,+1, c, 1,1), + video::S3DVertex(+r,+r,+r, 0,0,+1, c, 1,0), + }; + u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4}; + buf->append(vertices, 8, indices, 12); + } + + f32 pixelsize_x = 1 / (f32) resolution_x; + f32 pixelsize_y = 1 / (f32) resolution_y; + + for (int i = 0; i < resolution_x; ++i) { + f32 pixelpos_x = i * pixelsize_x - 0.5; + f32 x0 = pixelpos_x; + f32 x1 = pixelpos_x + pixelsize_x; + f32 tex0 = (i + 0.1) * pixelsize_x; + f32 tex1 = (i + 0.9) * pixelsize_x; + video::S3DVertex vertices[8] = { + // x- + video::S3DVertex(x0,-r,-r, -1,0,0, c, tex0,1), + video::S3DVertex(x0,-r,+r, -1,0,0, c, tex1,1), + video::S3DVertex(x0,+r,+r, -1,0,0, c, tex1,0), + video::S3DVertex(x0,+r,-r, -1,0,0, c, tex0,0), + // x+ + video::S3DVertex(x1,-r,-r, +1,0,0, c, tex0,1), + video::S3DVertex(x1,+r,-r, +1,0,0, c, tex0,0), + video::S3DVertex(x1,+r,+r, +1,0,0, c, tex1,0), + video::S3DVertex(x1,-r,+r, +1,0,0, c, tex1,1), + }; + u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4}; + buf->append(vertices, 8, indices, 12); + } + for (int i = 0; i < resolution_y; ++i) { + f32 pixelpos_y = i * pixelsize_y - 0.5; + f32 y0 = -pixelpos_y - pixelsize_y; + f32 y1 = -pixelpos_y; + f32 tex0 = (i + 0.1) * pixelsize_y; + f32 tex1 = (i + 0.9) * pixelsize_y; + video::S3DVertex vertices[8] = { + // y- + video::S3DVertex(-r,y0,-r, 0,-1,0, c, 0,tex0), + video::S3DVertex(+r,y0,-r, 0,-1,0, c, 1,tex0), + video::S3DVertex(+r,y0,+r, 0,-1,0, c, 1,tex1), + video::S3DVertex(-r,y0,+r, 0,-1,0, c, 0,tex1), + // y+ + video::S3DVertex(-r,y1,-r, 0,+1,0, c, 0,tex0), + video::S3DVertex(-r,y1,+r, 0,+1,0, c, 0,tex1), + video::S3DVertex(+r,y1,+r, 0,+1,0, c, 1,tex1), + video::S3DVertex(+r,y1,-r, 0,+1,0, c, 1,tex0), + }; + u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4}; + buf->append(vertices, 8, indices, 12); + } + + // Create mesh object + scene::SMesh *mesh = new scene::SMesh(); + mesh->addMeshBuffer(buf); + buf->drop(); + scaleMesh(mesh, scale); // also recalculates bounding box + return mesh; +} + +/* + Caches extrusion meshes so that only one of them per resolution + is needed. Also caches one cube (for convenience). + + E.g. there is a single extrusion mesh that is used for all + 16x16 px images, another for all 256x256 px images, and so on. + + WARNING: Not thread safe. This should not be a problem since + rendering related classes (such as WieldMeshSceneNode) will be + used from the rendering thread only. +*/ +class ExtrusionMeshCache: public IReferenceCounted +{ +public: + // Constructor + ExtrusionMeshCache() + { + for (int resolution = MIN_EXTRUSION_MESH_RESOLUTION; + resolution <= MAX_EXTRUSION_MESH_RESOLUTION; + resolution *= 2) { + m_extrusion_meshes[resolution] = + createExtrusionMesh(resolution, resolution); + } + m_cube = createCubeMesh(v3f(1.0, 1.0, 1.0)); + } + // Destructor + virtual ~ExtrusionMeshCache() + { + for (auto &extrusion_meshe : m_extrusion_meshes) { + extrusion_meshe.second->drop(); + } + m_cube->drop(); + } + // Get closest extrusion mesh for given image dimensions + // Caller must drop the returned pointer + scene::IMesh* create(core::dimension2d<u32> dim) + { + // handle non-power of two textures inefficiently without cache + if (!is_power_of_two(dim.Width) || !is_power_of_two(dim.Height)) { + return createExtrusionMesh(dim.Width, dim.Height); + } + + int maxdim = MYMAX(dim.Width, dim.Height); + + std::map<int, scene::IMesh*>::iterator + it = m_extrusion_meshes.lower_bound(maxdim); + + if (it == m_extrusion_meshes.end()) { + // no viable resolution found; use largest one + it = m_extrusion_meshes.find(MAX_EXTRUSION_MESH_RESOLUTION); + sanity_check(it != m_extrusion_meshes.end()); + } + + scene::IMesh *mesh = it->second; + mesh->grab(); + return mesh; + } + // Returns a 1x1x1 cube mesh with one meshbuffer (material) per face + // Caller must drop the returned pointer + scene::IMesh* createCube() + { + m_cube->grab(); + return m_cube; + } + +private: + std::map<int, scene::IMesh*> m_extrusion_meshes; + scene::IMesh *m_cube; +}; + +ExtrusionMeshCache *g_extrusion_mesh_cache = NULL; + + +WieldMeshSceneNode::WieldMeshSceneNode(scene::ISceneManager *mgr, s32 id, bool lighting): + scene::ISceneNode(mgr->getRootSceneNode(), mgr, id), + m_material_type(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF), + m_lighting(lighting) +{ + m_enable_shaders = g_settings->getBool("enable_shaders"); + m_anisotropic_filter = g_settings->getBool("anisotropic_filter"); + m_bilinear_filter = g_settings->getBool("bilinear_filter"); + m_trilinear_filter = g_settings->getBool("trilinear_filter"); + + // If this is the first wield mesh scene node, create a cache + // for extrusion meshes (and a cube mesh), otherwise reuse it + if (!g_extrusion_mesh_cache) + g_extrusion_mesh_cache = new ExtrusionMeshCache(); + else + g_extrusion_mesh_cache->grab(); + + // Disable bounding box culling for this scene node + // since we won't calculate the bounding box. + setAutomaticCulling(scene::EAC_OFF); + + // Create the child scene node + scene::IMesh *dummymesh = g_extrusion_mesh_cache->createCube(); + m_meshnode = SceneManager->addMeshSceneNode(dummymesh, this, -1); + m_meshnode->setReadOnlyMaterials(false); + m_meshnode->setVisible(false); + dummymesh->drop(); // m_meshnode grabbed it + + m_shadow = RenderingEngine::get_shadow_renderer(); +} + +WieldMeshSceneNode::~WieldMeshSceneNode() +{ + sanity_check(g_extrusion_mesh_cache); + + // Remove node from shadow casters. m_shadow might be an invalid pointer! + if (auto shadow = RenderingEngine::get_shadow_renderer()) + shadow->removeNodeFromShadowList(m_meshnode); + + if (g_extrusion_mesh_cache->drop()) + g_extrusion_mesh_cache = nullptr; +} + +void WieldMeshSceneNode::setCube(const ContentFeatures &f, + v3f wield_scale) +{ + scene::IMesh *cubemesh = g_extrusion_mesh_cache->createCube(); + scene::SMesh *copy = cloneMesh(cubemesh); + cubemesh->drop(); + postProcessNodeMesh(copy, f, false, true, &m_material_type, &m_colors, true); + changeToMesh(copy); + copy->drop(); + m_meshnode->setScale(wield_scale * WIELD_SCALE_FACTOR); +} + +void WieldMeshSceneNode::setExtruded(const std::string &imagename, + const std::string &overlay_name, v3f wield_scale, ITextureSource *tsrc, + u8 num_frames) +{ + video::ITexture *texture = tsrc->getTexture(imagename); + if (!texture) { + changeToMesh(nullptr); + return; + } + video::ITexture *overlay_texture = + overlay_name.empty() ? NULL : tsrc->getTexture(overlay_name); + + core::dimension2d<u32> dim = texture->getSize(); + // Detect animation texture and pull off top frame instead of using entire thing + if (num_frames > 1) { + u32 frame_height = dim.Height / num_frames; + dim = core::dimension2d<u32>(dim.Width, frame_height); + } + scene::IMesh *original = g_extrusion_mesh_cache->create(dim); + scene::SMesh *mesh = cloneMesh(original); + original->drop(); + //set texture + mesh->getMeshBuffer(0)->getMaterial().setTexture(0, + tsrc->getTexture(imagename)); + if (overlay_texture) { + scene::IMeshBuffer *copy = cloneMeshBuffer(mesh->getMeshBuffer(0)); + copy->getMaterial().setTexture(0, overlay_texture); + mesh->addMeshBuffer(copy); + copy->drop(); + } + changeToMesh(mesh); + mesh->drop(); + + m_meshnode->setScale(wield_scale * WIELD_SCALE_FACTOR_EXTRUDED); + + // Customize materials + for (u32 layer = 0; layer < m_meshnode->getMaterialCount(); layer++) { + video::SMaterial &material = m_meshnode->getMaterial(layer); + material.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; + material.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + material.MaterialType = m_material_type; + material.MaterialTypeParam = 0.5f; + material.setFlag(video::EMF_BACK_FACE_CULLING, true); + // Enable bi/trilinear filtering only for high resolution textures + if (dim.Width > 32) { + material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter); + material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); + } else { + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setFlag(video::EMF_TRILINEAR_FILTER, false); + } + material.setFlag(video::EMF_ANISOTROPIC_FILTER, m_anisotropic_filter); + // mipmaps cause "thin black line" artifacts + material.setFlag(video::EMF_USE_MIP_MAPS, false); + if (m_enable_shaders) { + material.setTexture(2, tsrc->getShaderFlagsTexture(false)); + } + } +} + +static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n, + std::vector<ItemPartColor> *colors, const ContentFeatures &f) +{ + MeshMakeData mesh_make_data(client, false); + MeshCollector collector; + mesh_make_data.setSmoothLighting(false); + MapblockMeshGenerator gen(&mesh_make_data, &collector, + client->getSceneManager()->getMeshManipulator()); + + if (n.getParam2()) { + // keep it + } else if (f.param_type_2 == CPT2_WALLMOUNTED || + f.param_type_2 == CPT2_COLORED_WALLMOUNTED) { + if (f.drawtype == NDT_TORCHLIKE || + f.drawtype == NDT_SIGNLIKE || + f.drawtype == NDT_NODEBOX || + f.drawtype == NDT_MESH) { + n.setParam2(4); + } + } else if (f.drawtype == NDT_SIGNLIKE || f.drawtype == NDT_TORCHLIKE) { + n.setParam2(1); + } + gen.renderSingle(n.getContent(), n.getParam2()); + + colors->clear(); + scene::SMesh *mesh = new scene::SMesh(); + for (auto &prebuffers : collector.prebuffers) + for (PreMeshBuffer &p : prebuffers) { + if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) { + const FrameSpec &frame = (*p.layer.frames)[0]; + p.layer.texture = frame.texture; + p.layer.normal_texture = frame.normal_texture; + } + for (video::S3DVertex &v : p.vertices) { + v.Color.setAlpha(255); + } + scene::SMeshBuffer *buf = new scene::SMeshBuffer(); + buf->Material.setTexture(0, p.layer.texture); + p.layer.applyMaterialOptions(buf->Material); + mesh->addMeshBuffer(buf); + buf->append(&p.vertices[0], p.vertices.size(), + &p.indices[0], p.indices.size()); + buf->drop(); + colors->push_back( + ItemPartColor(p.layer.has_color, p.layer.color)); + } + return mesh; +} + +void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool check_wield_image) +{ + ITextureSource *tsrc = client->getTextureSource(); + IItemDefManager *idef = client->getItemDefManager(); + IShaderSource *shdrsrc = client->getShaderSource(); + const NodeDefManager *ndef = client->getNodeDefManager(); + const ItemDefinition &def = item.getDefinition(idef); + const ContentFeatures &f = ndef->get(def.name); + content_t id = ndef->getId(def.name); + + scene::SMesh *mesh = nullptr; + + if (m_enable_shaders) { + u32 shader_id = shdrsrc->getShader("object_shader", TILE_MATERIAL_BASIC, NDT_NORMAL); + m_material_type = shdrsrc->getShaderInfo(shader_id).material; + } + + // Color-related + m_colors.clear(); + m_base_color = idef->getItemstackColor(item, client); + + // If wield_image needs to be checked and is defined, it overrides everything else + if (!def.wield_image.empty() && check_wield_image) { + setExtruded(def.wield_image, def.wield_overlay, def.wield_scale, tsrc, + 1); + m_colors.emplace_back(); + // overlay is white, if present + m_colors.emplace_back(true, video::SColor(0xFFFFFFFF)); + // initialize the color + if (!m_lighting) + setColor(video::SColor(0xFFFFFFFF)); + return; + } + + // Handle nodes + // See also CItemDefManager::createClientCached() + if (def.type == ITEM_NODE) { + bool cull_backface = f.needsBackfaceCulling(); + + // Select rendering method + switch (f.drawtype) { + case NDT_AIRLIKE: + setExtruded("no_texture_airlike.png", "", + v3f(1.0, 1.0, 1.0), tsrc, 1); + break; + case NDT_SIGNLIKE: + case NDT_TORCHLIKE: + case NDT_RAILLIKE: + case NDT_PLANTLIKE: + case NDT_FLOWINGLIQUID: { + v3f wscale = def.wield_scale; + if (f.drawtype == NDT_FLOWINGLIQUID) + wscale.Z *= 0.1f; + setExtruded(tsrc->getTextureName(f.tiles[0].layers[0].texture_id), + tsrc->getTextureName(f.tiles[0].layers[1].texture_id), + wscale, tsrc, + f.tiles[0].layers[0].animation_frame_count); + // Add color + const TileLayer &l0 = f.tiles[0].layers[0]; + m_colors.emplace_back(l0.has_color, l0.color); + const TileLayer &l1 = f.tiles[0].layers[1]; + m_colors.emplace_back(l1.has_color, l1.color); + break; + } + case NDT_PLANTLIKE_ROOTED: { + setExtruded(tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id), + "", def.wield_scale, tsrc, + f.special_tiles[0].layers[0].animation_frame_count); + // Add color + const TileLayer &l0 = f.special_tiles[0].layers[0]; + m_colors.emplace_back(l0.has_color, l0.color); + break; + } + case NDT_NORMAL: + case NDT_ALLFACES: + case NDT_LIQUID: + setCube(f, def.wield_scale); + break; + default: { + // Render non-trivial drawtypes like the actual node + MapNode n(id); + n.setParam2(def.place_param2); + + mesh = createSpecialNodeMesh(client, n, &m_colors, f); + changeToMesh(mesh); + mesh->drop(); + m_meshnode->setScale( + def.wield_scale * WIELD_SCALE_FACTOR + / (BS * f.visual_scale)); + break; + } + } + + u32 material_count = m_meshnode->getMaterialCount(); + for (u32 i = 0; i < material_count; ++i) { + video::SMaterial &material = m_meshnode->getMaterial(i); + material.MaterialType = m_material_type; + material.MaterialTypeParam = 0.5f; + material.setFlag(video::EMF_BACK_FACE_CULLING, cull_backface); + material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter); + material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); + } + + // initialize the color + if (!m_lighting) + setColor(video::SColor(0xFFFFFFFF)); + return; + } else { + if (!def.inventory_image.empty()) { + setExtruded(def.inventory_image, def.inventory_overlay, def.wield_scale, + tsrc, 1); + } else { + setExtruded("no_texture.png", "", def.wield_scale, tsrc, 1); + } + + m_colors.emplace_back(); + // overlay is white, if present + m_colors.emplace_back(true, video::SColor(0xFFFFFFFF)); + + // initialize the color + if (!m_lighting) + setColor(video::SColor(0xFFFFFFFF)); + return; + } + + // no wield mesh found + changeToMesh(nullptr); +} + +void WieldMeshSceneNode::setColor(video::SColor c) +{ + assert(!m_lighting); + scene::IMesh *mesh = m_meshnode->getMesh(); + if (!mesh) + return; + + u8 red = c.getRed(); + u8 green = c.getGreen(); + u8 blue = c.getBlue(); + u32 mc = mesh->getMeshBufferCount(); + for (u32 j = 0; j < mc; j++) { + video::SColor bc(m_base_color); + if ((m_colors.size() > j) && (m_colors[j].override_base)) + bc = m_colors[j].color; + video::SColor buffercolor(255, + bc.getRed() * red / 255, + bc.getGreen() * green / 255, + bc.getBlue() * blue / 255); + scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); + + if (m_enable_shaders) + setMeshBufferColor(buf, buffercolor); + else + colorizeMeshBuffer(buf, &buffercolor); + } +} + +void WieldMeshSceneNode::setNodeLightColor(video::SColor color) +{ + if (!m_meshnode) + return; + + if (m_enable_shaders) { + for (u32 i = 0; i < m_meshnode->getMaterialCount(); ++i) { + video::SMaterial &material = m_meshnode->getMaterial(i); + material.EmissiveColor = color; + } + } + else { + setColor(color); + } +} + +void WieldMeshSceneNode::render() +{ + // note: if this method is changed to actually do something, + // you probably should implement OnRegisterSceneNode as well +} + +void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh) +{ + if (!mesh) { + scene::IMesh *dummymesh = g_extrusion_mesh_cache->createCube(); + m_meshnode->setVisible(false); + m_meshnode->setMesh(dummymesh); + dummymesh->drop(); // m_meshnode grabbed it + } else { + m_meshnode->setMesh(mesh); + } + + m_meshnode->setMaterialFlag(video::EMF_LIGHTING, m_lighting); + // need to normalize normals when lighting is enabled (because of setScale()) + m_meshnode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, m_lighting); + m_meshnode->setVisible(true); + + if (m_shadow) { + // Add mesh to shadow caster + m_shadow->addNodeToShadowList(m_meshnode); + } +} + +void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) +{ + ITextureSource *tsrc = client->getTextureSource(); + IItemDefManager *idef = client->getItemDefManager(); + const NodeDefManager *ndef = client->getNodeDefManager(); + const ItemDefinition &def = item.getDefinition(idef); + const ContentFeatures &f = ndef->get(def.name); + content_t id = ndef->getId(def.name); + + FATAL_ERROR_IF(!g_extrusion_mesh_cache, "Extrusion mesh cache is not yet initialized"); + + scene::SMesh *mesh = nullptr; + + // Shading is on by default + result->needs_shading = true; + + bool cull_backface = f.needsBackfaceCulling(); + + // If inventory_image is defined, it overrides everything else + if (!def.inventory_image.empty()) { + mesh = getExtrudedMesh(tsrc, def.inventory_image, + def.inventory_overlay); + result->buffer_colors.emplace_back(); + // overlay is white, if present + result->buffer_colors.emplace_back(true, video::SColor(0xFFFFFFFF)); + // Items with inventory images do not need shading + result->needs_shading = false; + } else if (def.type == ITEM_NODE && f.drawtype == NDT_AIRLIKE) { + // Fallback image for airlike node + mesh = getExtrudedMesh(tsrc, "no_texture_airlike.png", + def.inventory_overlay); + result->needs_shading = false; + } else if (def.type == ITEM_NODE) { + switch (f.drawtype) { + case NDT_NORMAL: + case NDT_ALLFACES: + case NDT_LIQUID: + case NDT_FLOWINGLIQUID: { + scene::IMesh *cube = g_extrusion_mesh_cache->createCube(); + mesh = cloneMesh(cube); + cube->drop(); + if (f.drawtype == NDT_FLOWINGLIQUID) { + scaleMesh(mesh, v3f(1.2, 0.03, 1.2)); + translateMesh(mesh, v3f(0, -0.57, 0)); + } else + scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); + // add overlays + postProcessNodeMesh(mesh, f, false, false, nullptr, + &result->buffer_colors, true); + if (f.drawtype == NDT_ALLFACES) + scaleMesh(mesh, v3f(f.visual_scale)); + break; + } + case NDT_PLANTLIKE: { + mesh = getExtrudedMesh(tsrc, + tsrc->getTextureName(f.tiles[0].layers[0].texture_id), + tsrc->getTextureName(f.tiles[0].layers[1].texture_id)); + // Add color + const TileLayer &l0 = f.tiles[0].layers[0]; + result->buffer_colors.emplace_back(l0.has_color, l0.color); + const TileLayer &l1 = f.tiles[0].layers[1]; + result->buffer_colors.emplace_back(l1.has_color, l1.color); + break; + } + case NDT_PLANTLIKE_ROOTED: { + mesh = getExtrudedMesh(tsrc, + tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id), ""); + // Add color + const TileLayer &l0 = f.special_tiles[0].layers[0]; + result->buffer_colors.emplace_back(l0.has_color, l0.color); + break; + } + default: { + // Render non-trivial drawtypes like the actual node + MapNode n(id); + n.setParam2(def.place_param2); + + mesh = createSpecialNodeMesh(client, n, &result->buffer_colors, f); + scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); + break; + } + } + + u32 mc = mesh->getMeshBufferCount(); + for (u32 i = 0; i < mc; ++i) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); + video::SMaterial &material = buf->getMaterial(); + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + material.MaterialTypeParam = 0.5f; + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setFlag(video::EMF_TRILINEAR_FILTER, false); + material.setFlag(video::EMF_BACK_FACE_CULLING, cull_backface); + material.setFlag(video::EMF_LIGHTING, false); + } + + rotateMeshXZby(mesh, -45); + rotateMeshYZby(mesh, -30); + } + result->mesh = mesh; +} + + + +scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, + const std::string &imagename, const std::string &overlay_name) +{ + // check textures + video::ITexture *texture = tsrc->getTextureForMesh(imagename); + if (!texture) { + return NULL; + } + video::ITexture *overlay_texture = + (overlay_name.empty()) ? NULL : tsrc->getTexture(overlay_name); + + // get mesh + core::dimension2d<u32> dim = texture->getSize(); + scene::IMesh *original = g_extrusion_mesh_cache->create(dim); + scene::SMesh *mesh = cloneMesh(original); + original->drop(); + + //set texture + mesh->getMeshBuffer(0)->getMaterial().setTexture(0, + tsrc->getTexture(imagename)); + if (overlay_texture) { + scene::IMeshBuffer *copy = cloneMeshBuffer(mesh->getMeshBuffer(0)); + copy->getMaterial().setTexture(0, overlay_texture); + mesh->addMeshBuffer(copy); + copy->drop(); + } + // Customize materials + for (u32 layer = 0; layer < mesh->getMeshBufferCount(); layer++) { + video::SMaterial &material = mesh->getMeshBuffer(layer)->getMaterial(); + material.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; + material.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setFlag(video::EMF_TRILINEAR_FILTER, false); + material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_LIGHTING, false); + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + material.MaterialTypeParam = 0.5f; + } + scaleMesh(mesh, v3f(2.0, 2.0, 2.0)); + + return mesh; +} + +void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, + bool use_shaders, bool set_material, const video::E_MATERIAL_TYPE *mattype, + std::vector<ItemPartColor> *colors, bool apply_scale) +{ + u32 mc = mesh->getMeshBufferCount(); + // Allocate colors for existing buffers + colors->clear(); + for (u32 i = 0; i < mc; ++i) + colors->push_back(ItemPartColor()); + + for (u32 i = 0; i < mc; ++i) { + const TileSpec *tile = &(f.tiles[i]); + scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); + for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) { + const TileLayer *layer = &tile->layers[layernum]; + if (layer->texture_id == 0) + continue; + if (layernum != 0) { + scene::IMeshBuffer *copy = cloneMeshBuffer(buf); + copy->getMaterial() = buf->getMaterial(); + mesh->addMeshBuffer(copy); + copy->drop(); + buf = copy; + colors->push_back( + ItemPartColor(layer->has_color, layer->color)); + } else { + (*colors)[i] = ItemPartColor(layer->has_color, layer->color); + } + video::SMaterial &material = buf->getMaterial(); + if (set_material) + layer->applyMaterialOptions(material); + if (mattype) { + material.MaterialType = *mattype; + } + if (layer->animation_frame_count > 1) { + const FrameSpec &animation_frame = (*layer->frames)[0]; + material.setTexture(0, animation_frame.texture); + } else { + material.setTexture(0, layer->texture); + } + if (use_shaders) { + if (layer->normal_texture) { + if (layer->animation_frame_count > 1) { + const FrameSpec &animation_frame = (*layer->frames)[0]; + material.setTexture(1, animation_frame.normal_texture); + } else + material.setTexture(1, layer->normal_texture); + } + material.setTexture(2, layer->flags_texture); + } + if (apply_scale && tile->world_aligned) { + u32 n = buf->getVertexCount(); + for (u32 k = 0; k != n; ++k) + buf->getTCoords(k) /= layer->scale; + } + } + } +} diff --git a/src/client/wieldmesh.h b/src/client/wieldmesh.h new file mode 100644 index 0000000..d1eeb64 --- /dev/null +++ b/src/client/wieldmesh.h @@ -0,0 +1,146 @@ +/* +Minetest +Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <vector> +#include "irrlichttypes_extrabloated.h" + +struct ItemStack; +class Client; +class ITextureSource; +struct ContentFeatures; +class ShadowRenderer; + +/*! + * Holds color information of an item mesh's buffer. + */ +struct ItemPartColor +{ + /*! + * If this is false, the global base color of the item + * will be used instead of the specific color of the + * buffer. + */ + bool override_base = false; + /*! + * The color of the buffer. + */ + video::SColor color = 0; + + ItemPartColor() = default; + + ItemPartColor(bool override, video::SColor color) : + override_base(override), color(color) + { + } +}; + +struct ItemMesh +{ + scene::IMesh *mesh = nullptr; + /*! + * Stores the color of each mesh buffer. + */ + std::vector<ItemPartColor> buffer_colors; + /*! + * If false, all faces of the item should have the same brightness. + * Disables shading based on normal vectors. + */ + bool needs_shading = true; + + ItemMesh() = default; +}; + +/* + Wield item scene node, renders the wield mesh of some item +*/ +class WieldMeshSceneNode : public scene::ISceneNode +{ +public: + WieldMeshSceneNode(scene::ISceneManager *mgr, s32 id = -1, bool lighting = false); + virtual ~WieldMeshSceneNode(); + + void setCube(const ContentFeatures &f, v3f wield_scale); + void setExtruded(const std::string &imagename, const std::string &overlay_image, + v3f wield_scale, ITextureSource *tsrc, u8 num_frames); + void setItem(const ItemStack &item, Client *client, + bool check_wield_image = true); + + // Sets the vertex color of the wield mesh. + // Must only be used if the constructor was called with lighting = false + void setColor(video::SColor color); + + void setNodeLightColor(video::SColor color); + + scene::IMesh *getMesh() { return m_meshnode->getMesh(); } + + virtual void render(); + + virtual const aabb3f &getBoundingBox() const { return m_bounding_box; } + +private: + void changeToMesh(scene::IMesh *mesh); + + // Child scene node with the current wield mesh + scene::IMeshSceneNode *m_meshnode = nullptr; + video::E_MATERIAL_TYPE m_material_type; + + // True if EMF_LIGHTING should be enabled. + bool m_lighting; + + bool m_enable_shaders; + bool m_anisotropic_filter; + bool m_bilinear_filter; + bool m_trilinear_filter; + /*! + * Stores the colors of the mesh's mesh buffers. + * This does not include lighting. + */ + std::vector<ItemPartColor> m_colors; + /*! + * The base color of this mesh. This is the default + * for all mesh buffers. + */ + video::SColor m_base_color; + + // Bounding box culling is disabled for this type of scene node, + // so this variable is just required so we can implement + // getBoundingBox() and is set to an empty box. + aabb3f m_bounding_box; + + ShadowRenderer *m_shadow; +}; + +void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result); + +scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, const std::string &imagename, + const std::string &overlay_name); + +/*! + * Applies overlays, textures and optionally materials to the given mesh and + * extracts tile colors for colorization. + * \param mattype overrides the buffer's material type, but can also + * be NULL to leave the original material. + * \param colors returns the colors of the mesh buffers in the mesh. + */ +void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, bool use_shaders, + bool set_material, const video::E_MATERIAL_TYPE *mattype, + std::vector<ItemPartColor> *colors, bool apply_scale = false); diff --git a/src/clientiface.cpp b/src/clientiface.cpp new file mode 100644 index 0000000..5733b05 --- /dev/null +++ b/src/clientiface.cpp @@ -0,0 +1,863 @@ +/* +Minetest +Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <sstream> +#include "clientiface.h" +#include "network/connection.h" +#include "network/serveropcodes.h" +#include "remoteplayer.h" +#include "settings.h" +#include "mapblock.h" +#include "serverenvironment.h" +#include "map.h" +#include "emerge.h" +#include "server/luaentity_sao.h" +#include "server/player_sao.h" +#include "log.h" +#include "util/srp.h" +#include "face_position_cache.h" + +const char *ClientInterface::statenames[] = { + "Invalid", + "Disconnecting", + "Denied", + "Created", + "AwaitingInit2", + "HelloSent", + "InitDone", + "DefinitionsSent", + "Active", + "SudoMode", +}; + + + +std::string ClientInterface::state2Name(ClientState state) +{ + return statenames[state]; +} + +RemoteClient::RemoteClient() : + m_max_simul_sends(g_settings->getU16("max_simultaneous_block_sends_per_client")), + m_min_time_from_building( + g_settings->getFloat("full_block_send_enable_min_time_from_building")), + m_max_send_distance(g_settings->getS16("max_block_send_distance")), + m_block_optimize_distance(g_settings->getS16("block_send_optimize_distance")), + m_max_gen_distance(g_settings->getS16("max_block_generate_distance")), + m_occ_cull(g_settings->getBool("server_side_occlusion_culling")) +{ +} + +void RemoteClient::ResendBlockIfOnWire(v3s16 p) +{ + // if this block is on wire, mark it for sending again as soon as possible + if (m_blocks_sending.find(p) != m_blocks_sending.end()) { + SetBlockNotSent(p); + } +} + +LuaEntitySAO *getAttachedObject(PlayerSAO *sao, ServerEnvironment *env) +{ + if (!sao->isAttached()) + return nullptr; + + int id; + std::string bone; + v3f dummy; + bool force_visible; + sao->getAttachment(&id, &bone, &dummy, &dummy, &force_visible); + ServerActiveObject *ao = env->getActiveObject(id); + while (id && ao) { + ao->getAttachment(&id, &bone, &dummy, &dummy, &force_visible); + if (id) + ao = env->getActiveObject(id); + } + return dynamic_cast<LuaEntitySAO *>(ao); +} + +void RemoteClient::GetNextBlocks ( + ServerEnvironment *env, + EmergeManager * emerge, + float dtime, + std::vector<PrioritySortedBlockTransfer> &dest) +{ + // Increment timers + m_nothing_to_send_pause_timer -= dtime; + + if (m_nothing_to_send_pause_timer >= 0) + return; + + RemotePlayer *player = env->getPlayer(peer_id); + // This can happen sometimes; clients and players are not in perfect sync. + if (!player) + return; + + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + return; + + // Won't send anything if already sending + if (m_blocks_sending.size() >= m_max_simul_sends) { + //infostream<<"Not sending any blocks, Queue full."<<std::endl; + return; + } + + v3f playerpos = sao->getBasePosition(); + // if the player is attached, get the velocity from the attached object + LuaEntitySAO *lsao = getAttachedObject(sao, env); + const v3f &playerspeed = lsao? lsao->getVelocity() : player->getSpeed(); + v3f playerspeeddir(0,0,0); + if (playerspeed.getLength() > 1.0f * BS) + playerspeeddir = playerspeed / playerspeed.getLength(); + // Predict to next block + v3f playerpos_predicted = playerpos + playerspeeddir * (MAP_BLOCKSIZE * BS); + + v3s16 center_nodepos = floatToInt(playerpos_predicted, BS); + + v3s16 center = getNodeBlockPos(center_nodepos); + + // Camera position and direction + v3f camera_pos = sao->getEyePosition(); + v3f camera_dir = v3f(0,0,1); + camera_dir.rotateYZBy(sao->getLookPitch()); + camera_dir.rotateXZBy(sao->getRotation().Y); + + u16 max_simul_sends_usually = m_max_simul_sends; + + /* + Check the time from last addNode/removeNode. + + Decrease send rate if player is building stuff. + */ + m_time_from_building += dtime; + if (m_time_from_building < m_min_time_from_building) { + max_simul_sends_usually + = LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS; + } + + /* + Number of blocks sending + number of blocks selected for sending + */ + u32 num_blocks_selected = m_blocks_sending.size(); + + /* + next time d will be continued from the d from which the nearest + unsent block was found this time. + + This is because not necessarily any of the blocks found this + time are actually sent. + */ + s32 new_nearest_unsent_d = -1; + + // Get view range and camera fov (radians) from the client + s16 wanted_range = sao->getWantedRange() + 1; + float camera_fov = sao->getFov(); + + /* + Get the starting value of the block finder radius. + */ + if (m_last_center != center) { + m_nearest_unsent_d = 0; + m_last_center = center; + } + // reset the unsent distance if the view angle has changed more that 10% of the fov + // (this matches isBlockInSight which allows for an extra 10%) + if (camera_dir.dotProduct(m_last_camera_dir) < std::cos(camera_fov * 0.1f)) { + m_nearest_unsent_d = 0; + m_last_camera_dir = camera_dir; + } + if (m_nearest_unsent_d > 0) { + // make sure any blocks modified since the last time we sent blocks are resent + for (const v3s16 &p : m_blocks_modified) { + m_nearest_unsent_d = std::min(m_nearest_unsent_d, center.getDistanceFrom(p)); + } + } + m_blocks_modified.clear(); + + s16 d_start = m_nearest_unsent_d; + + // Distrust client-sent FOV and get server-set player object property + // zoom FOV (degrees) as a check to avoid hacked clients using FOV to load + // distant world. + // (zoom is disabled by value 0) + float prop_zoom_fov = sao->getZoomFOV() < 0.001f ? + 0.0f : + std::max(camera_fov, sao->getZoomFOV() * core::DEGTORAD); + + const s16 full_d_max = std::min(adjustDist(m_max_send_distance, prop_zoom_fov), + wanted_range); + const s16 d_opt = std::min(adjustDist(m_block_optimize_distance, prop_zoom_fov), + wanted_range); + const s16 d_blocks_in_sight = full_d_max * BS * MAP_BLOCKSIZE; + + s16 d_max_gen = std::min(adjustDist(m_max_gen_distance, prop_zoom_fov), + wanted_range); + + s16 d_max = full_d_max; + + // Don't loop very much at a time + s16 max_d_increment_at_time = 2; + if (d_max > d_start + max_d_increment_at_time) + d_max = d_start + max_d_increment_at_time; + + // cos(angle between velocity and camera) * |velocity| + // Limit to 0.0f in case player moves backwards. + f32 dot = rangelim(camera_dir.dotProduct(playerspeed), 0.0f, 300.0f); + + // Reduce the field of view when a player moves and looks forward. + // limit max fov effect to 50%, 60% at 20n/s fly speed + camera_fov = camera_fov / (1 + dot / 300.0f); + + s32 nearest_emerged_d = -1; + s32 nearest_emergefull_d = -1; + s32 nearest_sent_d = -1; + //bool queue_is_full = false; + + const v3s16 cam_pos_nodes = floatToInt(camera_pos, BS); + + s16 d; + for (d = d_start; d <= d_max; d++) { + /* + Get the border/face dot coordinates of a "d-radiused" + box + */ + std::vector<v3s16> list = FacePositionCache::getFacePositions(d); + + std::vector<v3s16>::iterator li; + for (li = list.begin(); li != list.end(); ++li) { + v3s16 p = *li + center; + + /* + Send throttling + - Don't allow too many simultaneous transfers + - EXCEPT when the blocks are very close + + Also, don't send blocks that are already flying. + */ + + // Start with the usual maximum + u16 max_simul_dynamic = max_simul_sends_usually; + + // If block is very close, allow full maximum + if (d <= BLOCK_SEND_DISABLE_LIMITS_MAX_D) + max_simul_dynamic = m_max_simul_sends; + + // Don't select too many blocks for sending + if (num_blocks_selected >= max_simul_dynamic) { + //queue_is_full = true; + goto queue_full_break; + } + + // Don't send blocks that are currently being transferred + if (m_blocks_sending.find(p) != m_blocks_sending.end()) + continue; + + /* + Do not go over max mapgen limit + */ + if (blockpos_over_max_limit(p)) + continue; + + // If this is true, inexistent block will be made from scratch + bool generate = d <= d_max_gen; + + /* + Don't generate or send if not in sight + FIXME This only works if the client uses a small enough + FOV setting. The default of 72 degrees is fine. + Also retrieve a smaller view cone in the direction of the player's + movement. + (0.1 is about 4 degrees) + */ + f32 dist; + if (!(isBlockInSight(p, camera_pos, camera_dir, camera_fov, + d_blocks_in_sight, &dist) || + (playerspeed.getLength() > 1.0f * BS && + isBlockInSight(p, camera_pos, playerspeeddir, 0.1f, + d_blocks_in_sight)))) { + continue; + } + + /* + Don't send already sent blocks + */ + if (m_blocks_sent.find(p) != m_blocks_sent.end()) + continue; + + /* + Check if map has this block + */ + MapBlock *block = env->getMap().getBlockNoCreateNoEx(p); + + bool block_not_found = false; + if (block) { + // Reset usage timer, this block will be of use in the future. + block->resetUsageTimer(); + + // Check whether the block exists (with data) + if (block->isDummy() || !block->isGenerated()) + block_not_found = true; + + /* + If block is not close, don't send it unless it is near + ground level. + + Block is near ground level if night-time mesh + differs from day-time mesh. + */ + if (d >= d_opt) { + if (!block->getIsUnderground() && !block->getDayNightDiff()) + continue; + } + + if (m_occ_cull && !block_not_found && + env->getMap().isBlockOccluded(block, cam_pos_nodes)) { + continue; + } + } + + /* + If block has been marked to not exist on disk (dummy) or is + not generated and generating new ones is not wanted, skip block. + */ + if (!generate && block_not_found) { + // get next one. + continue; + } + + /* + Add inexistent block to emerge queue. + */ + if (block == NULL || block_not_found) { + if (emerge->enqueueBlockEmerge(peer_id, p, generate)) { + if (nearest_emerged_d == -1) + nearest_emerged_d = d; + } else { + if (nearest_emergefull_d == -1) + nearest_emergefull_d = d; + goto queue_full_break; + } + + // get next one. + continue; + } + + if (nearest_sent_d == -1) + nearest_sent_d = d; + + /* + Add block to send queue + */ + PrioritySortedBlockTransfer q((float)dist, p, peer_id); + + dest.push_back(q); + + num_blocks_selected += 1; + } + } +queue_full_break: + + // If nothing was found for sending and nothing was queued for + // emerging, continue next time browsing from here + if (nearest_emerged_d != -1) { + new_nearest_unsent_d = nearest_emerged_d; + } else if (nearest_emergefull_d != -1) { + new_nearest_unsent_d = nearest_emergefull_d; + } else { + if (d > full_d_max) { + new_nearest_unsent_d = 0; + m_nothing_to_send_pause_timer = 2.0f; + } else { + if (nearest_sent_d != -1) + new_nearest_unsent_d = nearest_sent_d; + else + new_nearest_unsent_d = d; + } + } + + if (new_nearest_unsent_d != -1) + m_nearest_unsent_d = new_nearest_unsent_d; +} + +void RemoteClient::GotBlock(v3s16 p) +{ + if (m_blocks_sending.find(p) != m_blocks_sending.end()) { + m_blocks_sending.erase(p); + // only add to sent blocks if it actually was sending + // (it might have been modified since) + m_blocks_sent.insert(p); + } else { + m_excess_gotblocks++; + } +} + +void RemoteClient::SentBlock(v3s16 p) +{ + if (m_blocks_sending.find(p) == m_blocks_sending.end()) + m_blocks_sending[p] = 0.0f; + else + infostream<<"RemoteClient::SentBlock(): Sent block" + " already in m_blocks_sending"<<std::endl; +} + +void RemoteClient::SetBlockNotSent(v3s16 p) +{ + m_nothing_to_send_pause_timer = 0; + + // remove the block from sending and sent sets, + // and mark as modified if found + if (m_blocks_sending.erase(p) + m_blocks_sent.erase(p) > 0) + m_blocks_modified.insert(p); +} + +void RemoteClient::SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks) +{ + m_nothing_to_send_pause_timer = 0; + + for (auto &block : blocks) { + v3s16 p = block.first; + // remove the block from sending and sent sets, + // and mark as modified if found + if (m_blocks_sending.erase(p) + m_blocks_sent.erase(p) > 0) + m_blocks_modified.insert(p); + } +} + +void RemoteClient::notifyEvent(ClientStateEvent event) +{ + std::ostringstream myerror; + switch (m_state) + { + case CS_Invalid: + //intentionally do nothing + break; + case CS_Created: + switch (event) { + case CSE_Hello: + m_state = CS_HelloSent; + break; + case CSE_Disconnect: + m_state = CS_Disconnecting; + break; + case CSE_SetDenied: + m_state = CS_Denied; + break; + /* GotInit2 SetDefinitionsSent SetMediaSent */ + default: + myerror << "Created: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); + } + break; + case CS_Denied: + /* don't do anything if in denied state */ + break; + case CS_HelloSent: + switch(event) + { + case CSE_AuthAccept: + m_state = CS_AwaitingInit2; + resetChosenMech(); + break; + case CSE_Disconnect: + m_state = CS_Disconnecting; + break; + case CSE_SetDenied: + m_state = CS_Denied; + resetChosenMech(); + break; + default: + myerror << "HelloSent: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); + } + break; + case CS_AwaitingInit2: + switch(event) + { + case CSE_GotInit2: + confirmSerializationVersion(); + m_state = CS_InitDone; + break; + case CSE_Disconnect: + m_state = CS_Disconnecting; + break; + case CSE_SetDenied: + m_state = CS_Denied; + break; + + /* Init SetDefinitionsSent SetMediaSent */ + default: + myerror << "InitSent: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); + } + break; + + case CS_InitDone: + switch(event) + { + case CSE_SetDefinitionsSent: + m_state = CS_DefinitionsSent; + break; + case CSE_Disconnect: + m_state = CS_Disconnecting; + break; + case CSE_SetDenied: + m_state = CS_Denied; + break; + + /* Init GotInit2 SetMediaSent */ + default: + myerror << "InitDone: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); + } + break; + case CS_DefinitionsSent: + switch(event) + { + case CSE_SetClientReady: + m_state = CS_Active; + break; + case CSE_Disconnect: + m_state = CS_Disconnecting; + break; + case CSE_SetDenied: + m_state = CS_Denied; + break; + /* Init GotInit2 SetDefinitionsSent */ + default: + myerror << "DefinitionsSent: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); + } + break; + case CS_Active: + switch(event) + { + case CSE_SetDenied: + m_state = CS_Denied; + break; + case CSE_Disconnect: + m_state = CS_Disconnecting; + break; + case CSE_SudoSuccess: + m_state = CS_SudoMode; + resetChosenMech(); + break; + /* Init GotInit2 SetDefinitionsSent SetMediaSent SetDenied */ + default: + myerror << "Active: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); + break; + } + break; + case CS_SudoMode: + switch(event) + { + case CSE_SetDenied: + m_state = CS_Denied; + break; + case CSE_Disconnect: + m_state = CS_Disconnecting; + break; + case CSE_SudoLeave: + m_state = CS_Active; + break; + default: + myerror << "Active: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); + break; + } + break; + case CS_Disconnecting: + /* we are already disconnecting */ + break; + } +} + +void RemoteClient::resetChosenMech() +{ + if (auth_data) { + srp_verifier_delete((SRPVerifier *) auth_data); + auth_data = nullptr; + } + chosen_mech = AUTH_MECHANISM_NONE; +} + +u64 RemoteClient::uptime() const +{ + return porting::getTimeS() - m_connection_time; +} + +ClientInterface::ClientInterface(const std::shared_ptr<con::Connection> & con) +: + m_con(con), + m_env(NULL), + m_print_info_timer(0.0f) +{ + +} +ClientInterface::~ClientInterface() +{ + /* + Delete clients + */ + { + RecursiveMutexAutoLock clientslock(m_clients_mutex); + + for (auto &client_it : m_clients) { + // Delete client + delete client_it.second; + } + } +} + +std::vector<session_t> ClientInterface::getClientIDs(ClientState min_state) +{ + std::vector<session_t> reply; + RecursiveMutexAutoLock clientslock(m_clients_mutex); + + for (const auto &m_client : m_clients) { + if (m_client.second->getState() >= min_state) + reply.push_back(m_client.second->peer_id); + } + + return reply; +} + +void ClientInterface::markBlockposAsNotSent(const v3s16 &pos) +{ + RecursiveMutexAutoLock clientslock(m_clients_mutex); + for (const auto &client : m_clients) { + if (client.second->getState() >= CS_Active) + client.second->SetBlockNotSent(pos); + } +} + +/** + * Verify if user limit was reached. + * User limit count all clients from HelloSent state (MT protocol user) to Active state + * @return true if user limit was reached + */ +bool ClientInterface::isUserLimitReached() +{ + return getClientIDs(CS_HelloSent).size() >= g_settings->getU16("max_users"); +} + +void ClientInterface::step(float dtime) +{ + m_print_info_timer += dtime; + if (m_print_info_timer >= 30.0f) { + m_print_info_timer = 0.0f; + UpdatePlayerList(); + } +} + +void ClientInterface::UpdatePlayerList() +{ + if (m_env) { + std::vector<session_t> clients = getClientIDs(); + m_clients_names.clear(); + + if (!clients.empty()) + infostream<<"Players:"<<std::endl; + + for (session_t i : clients) { + RemotePlayer *player = m_env->getPlayer(i); + + if (player == NULL) + continue; + + infostream << "* " << player->getName() << "\t"; + + { + RecursiveMutexAutoLock clientslock(m_clients_mutex); + RemoteClient* client = lockedGetClientNoEx(i); + if (client) + client->PrintInfo(infostream); + } + + m_clients_names.emplace_back(player->getName()); + } + } +} + +void ClientInterface::send(session_t peer_id, u8 channelnum, + NetworkPacket *pkt, bool reliable) +{ + m_con->Send(peer_id, channelnum, pkt, reliable); +} + +void ClientInterface::sendToAll(NetworkPacket *pkt) +{ + RecursiveMutexAutoLock clientslock(m_clients_mutex); + for (auto &client_it : m_clients) { + RemoteClient *client = client_it.second; + + if (client->net_proto_version != 0) { + m_con->Send(client->peer_id, + clientCommandFactoryTable[pkt->getCommand()].channel, pkt, + clientCommandFactoryTable[pkt->getCommand()].reliable); + } + } +} + +RemoteClient* ClientInterface::getClientNoEx(session_t peer_id, ClientState state_min) +{ + RecursiveMutexAutoLock clientslock(m_clients_mutex); + RemoteClientMap::const_iterator n = m_clients.find(peer_id); + // The client may not exist; clients are immediately removed if their + // access is denied, and this event occurs later then. + if (n == m_clients.end()) + return NULL; + + if (n->second->getState() >= state_min) + return n->second; + + return NULL; +} + +RemoteClient* ClientInterface::lockedGetClientNoEx(session_t peer_id, ClientState state_min) +{ + RemoteClientMap::const_iterator n = m_clients.find(peer_id); + // The client may not exist; clients are immediately removed if their + // access is denied, and this event occurs later then. + if (n == m_clients.end()) + return NULL; + + if (n->second->getState() >= state_min) + return n->second; + + return NULL; +} + +ClientState ClientInterface::getClientState(session_t peer_id) +{ + RecursiveMutexAutoLock clientslock(m_clients_mutex); + RemoteClientMap::const_iterator n = m_clients.find(peer_id); + // The client may not exist; clients are immediately removed if their + // access is denied, and this event occurs later then. + if (n == m_clients.end()) + return CS_Invalid; + + return n->second->getState(); +} + +void ClientInterface::setPlayerName(session_t peer_id, const std::string &name) +{ + RecursiveMutexAutoLock clientslock(m_clients_mutex); + RemoteClientMap::iterator n = m_clients.find(peer_id); + // The client may not exist; clients are immediately removed if their + // access is denied, and this event occurs later then. + if (n != m_clients.end()) + n->second->setName(name); +} + +void ClientInterface::DeleteClient(session_t peer_id) +{ + RecursiveMutexAutoLock conlock(m_clients_mutex); + + // Error check + RemoteClientMap::iterator n = m_clients.find(peer_id); + // The client may not exist; clients are immediately removed if their + // access is denied, and this event occurs later then. + if (n == m_clients.end()) + return; + + /* + Mark objects to be not known by the client + */ + //TODO this should be done by client destructor!!! + RemoteClient *client = n->second; + // Handle objects + for (u16 id : client->m_known_objects) { + // Get object + ServerActiveObject* obj = m_env->getActiveObject(id); + + if(obj && obj->m_known_by_count > 0) + obj->m_known_by_count--; + } + + // Delete client + delete m_clients[peer_id]; + m_clients.erase(peer_id); +} + +void ClientInterface::CreateClient(session_t peer_id) +{ + RecursiveMutexAutoLock conlock(m_clients_mutex); + + // Error check + RemoteClientMap::iterator n = m_clients.find(peer_id); + // The client shouldn't already exist + if (n != m_clients.end()) return; + + // Create client + RemoteClient *client = new RemoteClient(); + client->peer_id = peer_id; + m_clients[client->peer_id] = client; +} + +void ClientInterface::event(session_t peer_id, ClientStateEvent event) +{ + { + RecursiveMutexAutoLock clientlock(m_clients_mutex); + + // Error check + RemoteClientMap::iterator n = m_clients.find(peer_id); + + // No client to deliver event + if (n == m_clients.end()) + return; + n->second->notifyEvent(event); + } + + if ((event == CSE_SetClientReady) || + (event == CSE_Disconnect) || + (event == CSE_SetDenied)) + { + UpdatePlayerList(); + } +} + +u16 ClientInterface::getProtocolVersion(session_t peer_id) +{ + RecursiveMutexAutoLock conlock(m_clients_mutex); + + // Error check + RemoteClientMap::iterator n = m_clients.find(peer_id); + + // No client to get version + if (n == m_clients.end()) + return 0; + + return n->second->net_proto_version; +} + +void ClientInterface::setClientVersion(session_t peer_id, u8 major, u8 minor, u8 patch, + const std::string &full) +{ + RecursiveMutexAutoLock conlock(m_clients_mutex); + + // Error check + RemoteClientMap::iterator n = m_clients.find(peer_id); + + // No client to set versions + if (n == m_clients.end()) + return; + + n->second->setVersionInfo(major, minor, patch, full); +} diff --git a/src/clientiface.h b/src/clientiface.h new file mode 100644 index 0000000..3e7ba47 --- /dev/null +++ b/src/clientiface.h @@ -0,0 +1,536 @@ +/* +Minetest +Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_v3d.h" // for irrlicht datatypes + +#include "constants.h" +#include "serialization.h" // for SER_FMT_VER_INVALID +#include "network/networkpacket.h" +#include "network/networkprotocol.h" +#include "network/address.h" +#include "porting.h" +#include "threading/mutex_auto_lock.h" + +#include <list> +#include <vector> +#include <set> +#include <memory> +#include <mutex> + +class MapBlock; +class ServerEnvironment; +class EmergeManager; + +/* + * State Transitions + + Start + (peer connect) + | + v + /-----------------\ + | | + | Created | + | | + \-----------------/ + | depending of the incoming packet + ---------------------------------------- + v + +-----------------------------+ + |IN: | + | TOSERVER_INIT | + +-----------------------------+ + | invalid playername + | or denied by mod + v + +-----------------------------+ + |OUT: | + | TOCLIENT_HELLO | + +-----------------------------+ + | + | + v + /-----------------\ /-----------------\ + | | | | + | AwaitingInit2 |<--------- | HelloSent | + | | | | | + \-----------------/ | \-----------------/ + | | | ++-----------------------------+ | *-----------------------------* Auth fails +|IN: | | |Authentication, depending on |------------------ +| TOSERVER_INIT2 | | | packet sent by client | | ++-----------------------------+ | *-----------------------------* | + | | | | + | | | Authentication | + v | | successful | + /-----------------\ | v | + | | | +-----------------------------+ | + | InitDone | | |OUT: | | + | | | | TOCLIENT_AUTH_ACCEPT | | + \-----------------/ | +-----------------------------+ | + | | | | ++-----------------------------+ --------------------- | +|OUT: | | +| TOCLIENT_MOVEMENT | | +| TOCLIENT_ITEMDEF | | +| TOCLIENT_NODEDEF | | +| TOCLIENT_ANNOUNCE_MEDIA | | +| TOCLIENT_DETACHED_INVENTORY | | +| TOCLIENT_TIME_OF_DAY | | ++-----------------------------+ | + | | + | | + | ----------------------------- | + v | | | + /-----------------\ v | + | | +-----------------------------+ | + | DefinitionsSent | |IN: | | + | | | TOSERVER_REQUEST_MEDIA | | + \-----------------/ | | | + | +-----------------------------+ | + | ^ | | + | ----------------------------- | + v v ++-----------------------------+ --------------------------------+ +|IN: | | ^ +| TOSERVER_CLIENT_READY | v | ++-----------------------------+ +------------------------+ | + | |OUT: | | + v | TOCLIENT_ACCESS_DENIED | | ++-----------------------------+ +------------------------+ | +|OUT: | | | +| TOCLIENT_MOVE_PLAYER | v | +| TOCLIENT_PRIVILEGES | /-----------------\ | +| TOCLIENT_INVENTORY_FORMSPEC | | | | +| UpdateCrafting | | Denied | | +| TOCLIENT_INVENTORY | | | | +| TOCLIENT_HP (opt) | \-----------------/ | +| TOCLIENT_BREATH | | +| TOCLIENT_DEATHSCREEN | | ++-----------------------------+ | + | | + v | + /-----------------\ async mod action (ban, kick) | + | |--------------------------------------------------------------- + ---->| Active | + | | |---------------------------------------------- + | \-----------------/ timeout v + | | | +-----------------------------+ + | | | |OUT: | + | | | | TOCLIENT_DISCONNECT | + | | | +-----------------------------+ + | | | | + | | v v + | | +-----------------------------+ /-----------------\ + | | |IN: | | | + | | | TOSERVER_DISCONNECT |------------------->| Disconnecting | + | | +-----------------------------+ | | + | | \-----------------/ + | | any auth packet which was + | | allowed in TOCLIENT_AUTH_ACCEPT + | v + | *-----------------------------* Auth +-------------------------------+ + | |Authentication, depending on | succeeds |OUT: | + | | packet sent by client |---------->| TOCLIENT_ACCEPT_SUDO_MODE | + | *-----------------------------* +-------------------------------+ + | | | + | | Auth fails /-----------------\ + | v | | + | +-------------------------------+ | SudoMode | + | |OUT: | | | + | | TOCLIENT_DENY_SUDO_MODE | \-----------------/ + | +-------------------------------+ | + | | v + | | +-----------------------------+ + | | sets password accordingly |IN: | + -------------------+-------------------------------| TOSERVER_FIRST_SRP | + +-----------------------------+ + +*/ +namespace con { + class Connection; +} + + +// Also make sure to update the ClientInterface::statenames +// array when modifying these enums + +enum ClientState +{ + CS_Invalid, + CS_Disconnecting, + CS_Denied, + CS_Created, + CS_AwaitingInit2, + CS_HelloSent, + CS_InitDone, + CS_DefinitionsSent, + CS_Active, + CS_SudoMode +}; + +enum ClientStateEvent +{ + CSE_Hello, + CSE_AuthAccept, + CSE_GotInit2, + CSE_SetDenied, + CSE_SetDefinitionsSent, + CSE_SetClientReady, + CSE_SudoSuccess, + CSE_SudoLeave, + CSE_Disconnect +}; + +/* + Used for queueing and sorting block transfers in containers + + Lower priority number means higher priority. +*/ +struct PrioritySortedBlockTransfer +{ + PrioritySortedBlockTransfer(float a_priority, const v3s16 &a_pos, session_t a_peer_id) + { + priority = a_priority; + pos = a_pos; + peer_id = a_peer_id; + } + bool operator < (const PrioritySortedBlockTransfer &other) const + { + return priority < other.priority; + } + float priority; + v3s16 pos; + session_t peer_id; +}; + +class RemoteClient +{ +public: + // peer_id=0 means this client has no associated peer + // NOTE: If client is made allowed to exist while peer doesn't, + // this has to be set to 0 when there is no peer. + // Also, the client must be moved to some other container. + session_t peer_id = PEER_ID_INEXISTENT; + // The serialization version to use with the client + u8 serialization_version = SER_FMT_VER_INVALID; + // + u16 net_proto_version = 0; + + /* Authentication information */ + std::string enc_pwd = ""; + bool create_player_on_auth_success = false; + AuthMechanism chosen_mech = AUTH_MECHANISM_NONE; + void *auth_data = nullptr; + u32 allowed_auth_mechs = 0; + u32 allowed_sudo_mechs = 0; + + void resetChosenMech(); + + bool isSudoMechAllowed(AuthMechanism mech) + { return allowed_sudo_mechs & mech; } + bool isMechAllowed(AuthMechanism mech) + { return allowed_auth_mechs & mech; } + + RemoteClient(); + ~RemoteClient() = default; + + /* + Finds block that should be sent next to the client. + Environment should be locked when this is called. + dtime is used for resetting send radius at slow interval + */ + void GetNextBlocks(ServerEnvironment *env, EmergeManager* emerge, + float dtime, std::vector<PrioritySortedBlockTransfer> &dest); + + void GotBlock(v3s16 p); + + void SentBlock(v3s16 p); + + void SetBlockNotSent(v3s16 p); + void SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks); + + /** + * tell client about this block being modified right now. + * this information is required to requeue the block in case it's "on wire" + * while modification is processed by server + * @param p position of modified block + */ + void ResendBlockIfOnWire(v3s16 p); + + u32 getSendingCount() const { return m_blocks_sending.size(); } + + bool isBlockSent(v3s16 p) const + { + return m_blocks_sent.find(p) != m_blocks_sent.end(); + } + + // Increments timeouts and removes timed-out blocks from list + // NOTE: This doesn't fix the server-not-sending-block bug + // because it is related to emerging, not sending. + //void RunSendingTimeouts(float dtime, float timeout); + + void PrintInfo(std::ostream &o) + { + o<<"RemoteClient "<<peer_id<<": " + <<"m_blocks_sent.size()="<<m_blocks_sent.size() + <<", m_blocks_sending.size()="<<m_blocks_sending.size() + <<", m_nearest_unsent_d="<<m_nearest_unsent_d + <<", m_excess_gotblocks="<<m_excess_gotblocks + <<std::endl; + m_excess_gotblocks = 0; + } + + // Time from last placing or removing blocks + float m_time_from_building = 9999; + + /* + List of active objects that the client knows of. + */ + std::set<u16> m_known_objects; + + ClientState getState() const { return m_state; } + + std::string getName() const { return m_name; } + + void setName(const std::string &name) { m_name = name; } + + /* update internal client state */ + void notifyEvent(ClientStateEvent event); + + /* set expected serialization version */ + void setPendingSerializationVersion(u8 version) + { m_pending_serialization_version = version; } + + void setDeployedCompressionMode(u16 byteFlag) + { m_deployed_compression = byteFlag; } + + void confirmSerializationVersion() + { serialization_version = m_pending_serialization_version; } + + /* get uptime */ + u64 uptime() const; + + /* set version information */ + void setVersionInfo(u8 major, u8 minor, u8 patch, const std::string &full) + { + m_version_major = major; + m_version_minor = minor; + m_version_patch = patch; + m_full_version = full; + } + + /* read version information */ + u8 getMajor() const { return m_version_major; } + u8 getMinor() const { return m_version_minor; } + u8 getPatch() const { return m_version_patch; } + const std::string &getFullVer() const { return m_full_version; } + + void setLangCode(const std::string &code) { m_lang_code = code; } + const std::string &getLangCode() const { return m_lang_code; } + + void setCachedAddress(const Address &addr) { m_addr = addr; } + const Address &getAddress() const { return m_addr; } + +private: + // Version is stored in here after INIT before INIT2 + u8 m_pending_serialization_version = SER_FMT_VER_INVALID; + + /* current state of client */ + ClientState m_state = CS_Created; + + // Cached here so retrieval doesn't have to go to connection API + Address m_addr; + + // Client sent language code + std::string m_lang_code; + + /* + Blocks that have been sent to client. + - These don't have to be sent again. + - A block is cleared from here when client says it has + deleted it from it's memory + + List of block positions. + No MapBlock* is stored here because the blocks can get deleted. + */ + std::set<v3s16> m_blocks_sent; + s16 m_nearest_unsent_d = 0; + v3s16 m_last_center; + v3f m_last_camera_dir; + + const u16 m_max_simul_sends; + const float m_min_time_from_building; + const s16 m_max_send_distance; + const s16 m_block_optimize_distance; + const s16 m_max_gen_distance; + const bool m_occ_cull; + + /* + Blocks that are currently on the line. + This is used for throttling the sending of blocks. + - The size of this list is limited to some value + Block is added when it is sent with BLOCKDATA. + Block is removed when GOTBLOCKS is received. + Value is time from sending. (not used at the moment) + */ + std::map<v3s16, float> m_blocks_sending; + + /* + Blocks that have been modified since blocks were + sent to the client last (getNextBlocks()). + This is used to reset the unsent distance, so that + modified blocks are resent to the client. + + List of block positions. + */ + std::set<v3s16> m_blocks_modified; + + /* + Count of excess GotBlocks(). + There is an excess amount because the client sometimes + gets a block so late that the server sends it again, + and the client then sends two GOTBLOCKs. + This is resetted by PrintInfo() + */ + u32 m_excess_gotblocks = 0; + + // CPU usage optimization + float m_nothing_to_send_pause_timer = 0.0f; + + /* + name of player using this client + */ + std::string m_name = ""; + + /* + client information + */ + u8 m_version_major = 0; + u8 m_version_minor = 0; + u8 m_version_patch = 0; + + std::string m_full_version = "unknown"; + + u16 m_deployed_compression = 0; + + /* + time this client was created + */ + const u64 m_connection_time = porting::getTimeS(); +}; + +typedef std::unordered_map<u16, RemoteClient*> RemoteClientMap; + +class ClientInterface { +public: + + friend class Server; + + ClientInterface(const std::shared_ptr<con::Connection> &con); + ~ClientInterface(); + + /* run sync step */ + void step(float dtime); + + /* get list of active client id's */ + std::vector<session_t> getClientIDs(ClientState min_state=CS_Active); + + /* mark block as not sent to active client sessions */ + void markBlockposAsNotSent(const v3s16 &pos); + + /* verify is server user limit was reached */ + bool isUserLimitReached(); + + /* get list of client player names */ + const std::vector<std::string> &getPlayerNames() const { return m_clients_names; } + + /* send message to client */ + void send(session_t peer_id, u8 channelnum, NetworkPacket *pkt, bool reliable); + + /* send to all clients */ + void sendToAll(NetworkPacket *pkt); + + /* delete a client */ + void DeleteClient(session_t peer_id); + + /* create client */ + void CreateClient(session_t peer_id); + + /* get a client by peer_id */ + RemoteClient *getClientNoEx(session_t peer_id, ClientState state_min = CS_Active); + + /* get client by peer_id (make sure you have list lock before!*/ + RemoteClient *lockedGetClientNoEx(session_t peer_id, ClientState state_min = CS_Active); + + /* get state of client by id*/ + ClientState getClientState(session_t peer_id); + + /* set client playername */ + void setPlayerName(session_t peer_id, const std::string &name); + + /* get protocol version of client */ + u16 getProtocolVersion(session_t peer_id); + + /* set client version */ + void setClientVersion(session_t peer_id, u8 major, u8 minor, u8 patch, + const std::string &full); + + /* event to update client state */ + void event(session_t peer_id, ClientStateEvent event); + + /* Set environment. Do not call this function if environment is already set */ + void setEnv(ServerEnvironment *env) + { + assert(m_env == NULL); // pre-condition + m_env = env; + } + + static std::string state2Name(ClientState state); +protected: + class AutoLock { + public: + AutoLock(ClientInterface &iface): m_lock(iface.m_clients_mutex) {} + + private: + RecursiveMutexAutoLock m_lock; + }; + + RemoteClientMap& getClientList() { return m_clients; } + +private: + /* update internal player list */ + void UpdatePlayerList(); + + // Connection + std::shared_ptr<con::Connection> m_con; + std::recursive_mutex m_clients_mutex; + // Connected clients (behind the con mutex) + RemoteClientMap m_clients; + std::vector<std::string> m_clients_names; //for announcing masterserver + + // Environment + ServerEnvironment *m_env; + + float m_print_info_timer; + + static const char *statenames[]; +}; diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in new file mode 100644 index 0000000..17b70e2 --- /dev/null +++ b/src/cmake_config.h.in @@ -0,0 +1,40 @@ +// Filled in by the build system + +#pragma once + +#define PROJECT_NAME "@PROJECT_NAME@" +#define PROJECT_NAME_C "@PROJECT_NAME_CAPITALIZED@" +#define VERSION_MAJOR @VERSION_MAJOR@ +#define VERSION_MINOR @VERSION_MINOR@ +#define VERSION_PATCH @VERSION_PATCH@ +#define VERSION_EXTRA "@VERSION_EXTRA@" +#define VERSION_STRING "@VERSION_STRING@" +#define PRODUCT_VERSION_STRING "@VERSION_MAJOR@.@VERSION_MINOR@" +#define STATIC_SHAREDIR "@SHAREDIR@" +#define STATIC_LOCALEDIR "@LOCALEDIR@" +#define BUILD_TYPE "@CMAKE_BUILD_TYPE@" +#define ICON_DIR "@ICONDIR@" +#cmakedefine01 RUN_IN_PLACE +#cmakedefine01 DEVELOPMENT_BUILD +#cmakedefine01 ENABLE_UPDATE_CHECKER +#cmakedefine01 USE_GETTEXT +#cmakedefine01 USE_CURL +#cmakedefine01 USE_SOUND +#cmakedefine01 USE_CURSES +#cmakedefine01 USE_LEVELDB +#cmakedefine01 USE_LUAJIT +#cmakedefine01 USE_POSTGRESQL +#cmakedefine01 USE_PROMETHEUS +#cmakedefine01 USE_SPATIAL +#cmakedefine01 USE_SYSTEM_GMP +#cmakedefine01 USE_REDIS +#cmakedefine01 ENABLE_GLES +#cmakedefine01 HAVE_ENDIAN_H +#cmakedefine01 CURSES_HAVE_CURSES_H +#cmakedefine01 CURSES_HAVE_NCURSES_H +#cmakedefine01 CURSES_HAVE_NCURSES_NCURSES_H +#cmakedefine01 CURSES_HAVE_NCURSES_CURSES_H +#cmakedefine01 CURSES_HAVE_NCURSESW_NCURSES_H +#cmakedefine01 CURSES_HAVE_NCURSESW_CURSES_H +#cmakedefine01 BUILD_UNITTESTS +#cmakedefine01 BUILD_BENCHMARKS diff --git a/src/cmake_config_githash.h.in b/src/cmake_config_githash.h.in new file mode 100644 index 0000000..66870b0 --- /dev/null +++ b/src/cmake_config_githash.h.in @@ -0,0 +1,6 @@ +// Filled in by the build system +// Separated from cmake_config.h to avoid excessive rebuilds on every commit + +#pragma once + +#define VERSION_GITHASH "@VERSION_GITHASH@" diff --git a/src/collision.cpp b/src/collision.cpp new file mode 100644 index 0000000..be135a2 --- /dev/null +++ b/src/collision.cpp @@ -0,0 +1,613 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "collision.h" +#include <cmath> +#include "mapblock.h" +#include "map.h" +#include "nodedef.h" +#include "gamedef.h" +#ifndef SERVER +#include "client/clientenvironment.h" +#include "client/localplayer.h" +#endif +#include "serverenvironment.h" +#include "server/serveractiveobject.h" +#include "util/timetaker.h" +#include "profiler.h" + +#ifdef __FAST_MATH__ +#warning "-ffast-math is known to cause bugs in collision code, do not use!" +#endif + +struct NearbyCollisionInfo { + // node + NearbyCollisionInfo(bool is_ul, int bouncy, const v3s16 &pos, + const aabb3f &box) : + is_unloaded(is_ul), + obj(nullptr), + bouncy(bouncy), + position(pos), + box(box) + {} + + // object + NearbyCollisionInfo(ActiveObject *obj, int bouncy, + const aabb3f &box) : + is_unloaded(false), + obj(obj), + bouncy(bouncy), + box(box) + {} + + inline bool isObject() const { return obj != nullptr; } + + bool is_unloaded; + bool is_step_up = false; + ActiveObject *obj; + int bouncy; + v3s16 position; + aabb3f box; +}; + +// Helper functions: +// Truncate floating point numbers to specified number of decimal places +// in order to move all the floating point error to one side of the correct value +static inline f32 truncate(const f32 val, const f32 factor) +{ + return truncf(val * factor) / factor; +} + +static inline v3f truncate(const v3f& vec, const f32 factor) +{ + return v3f( + truncate(vec.X, factor), + truncate(vec.Y, factor), + truncate(vec.Z, factor) + ); +} + +// Helper function: +// Checks for collision of a moving aabbox with a static aabbox +// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision +// The time after which the collision occurs is stored in dtime. +CollisionAxis axisAlignedCollision( + const aabb3f &staticbox, const aabb3f &movingbox, + const v3f &speed, f32 *dtime) +{ + //TimeTaker tt("axisAlignedCollision"); + + aabb3f relbox( + (movingbox.MaxEdge.X - movingbox.MinEdge.X) + (staticbox.MaxEdge.X - staticbox.MinEdge.X), // sum of the widths + (movingbox.MaxEdge.Y - movingbox.MinEdge.Y) + (staticbox.MaxEdge.Y - staticbox.MinEdge.Y), + (movingbox.MaxEdge.Z - movingbox.MinEdge.Z) + (staticbox.MaxEdge.Z - staticbox.MinEdge.Z), + std::max(movingbox.MaxEdge.X, staticbox.MaxEdge.X) - std::min(movingbox.MinEdge.X, staticbox.MinEdge.X), //outer bounding 'box' dimensions + std::max(movingbox.MaxEdge.Y, staticbox.MaxEdge.Y) - std::min(movingbox.MinEdge.Y, staticbox.MinEdge.Y), + std::max(movingbox.MaxEdge.Z, staticbox.MaxEdge.Z) - std::min(movingbox.MinEdge.Z, staticbox.MinEdge.Z) + ); + + const f32 dtime_max = *dtime; + f32 inner_margin; // the distance of clipping recovery + f32 distance; + f32 time; + + + if (speed.Y) { + distance = relbox.MaxEdge.Y - relbox.MinEdge.Y; + *dtime = distance / std::abs(speed.Y); + time = std::max(*dtime, 0.0f); + + if (*dtime <= dtime_max) { + inner_margin = std::max(-0.5f * (staticbox.MaxEdge.Y - staticbox.MinEdge.Y), -2.0f); + + if ((speed.Y > 0 && staticbox.MinEdge.Y - movingbox.MaxEdge.Y > inner_margin) || + (speed.Y < 0 && movingbox.MinEdge.Y - staticbox.MaxEdge.Y > inner_margin)) { + if ( + (std::max(movingbox.MaxEdge.X + speed.X * time, staticbox.MaxEdge.X) + - std::min(movingbox.MinEdge.X + speed.X * time, staticbox.MinEdge.X) + - relbox.MinEdge.X < 0) && + (std::max(movingbox.MaxEdge.Z + speed.Z * time, staticbox.MaxEdge.Z) + - std::min(movingbox.MinEdge.Z + speed.Z * time, staticbox.MinEdge.Z) + - relbox.MinEdge.Z < 0) + ) + return COLLISION_AXIS_Y; + } + } + else { + return COLLISION_AXIS_NONE; + } + } + + // NO else if here + + if (speed.X) { + distance = relbox.MaxEdge.X - relbox.MinEdge.X; + *dtime = distance / std::abs(speed.X); + time = std::max(*dtime, 0.0f); + + if (*dtime <= dtime_max) { + inner_margin = std::max(-0.5f * (staticbox.MaxEdge.X - staticbox.MinEdge.X), -2.0f); + + if ((speed.X > 0 && staticbox.MinEdge.X - movingbox.MaxEdge.X > inner_margin) || + (speed.X < 0 && movingbox.MinEdge.X - staticbox.MaxEdge.X > inner_margin)) { + if ( + (std::max(movingbox.MaxEdge.Y + speed.Y * time, staticbox.MaxEdge.Y) + - std::min(movingbox.MinEdge.Y + speed.Y * time, staticbox.MinEdge.Y) + - relbox.MinEdge.Y < 0) && + (std::max(movingbox.MaxEdge.Z + speed.Z * time, staticbox.MaxEdge.Z) + - std::min(movingbox.MinEdge.Z + speed.Z * time, staticbox.MinEdge.Z) + - relbox.MinEdge.Z < 0) + ) + return COLLISION_AXIS_X; + } + } else { + return COLLISION_AXIS_NONE; + } + } + + // NO else if here + + if (speed.Z) { + distance = relbox.MaxEdge.Z - relbox.MinEdge.Z; + *dtime = distance / std::abs(speed.Z); + time = std::max(*dtime, 0.0f); + + if (*dtime <= dtime_max) { + inner_margin = std::max(-0.5f * (staticbox.MaxEdge.Z - staticbox.MinEdge.Z), -2.0f); + + if ((speed.Z > 0 && staticbox.MinEdge.Z - movingbox.MaxEdge.Z > inner_margin) || + (speed.Z < 0 && movingbox.MinEdge.Z - staticbox.MaxEdge.Z > inner_margin)) { + if ( + (std::max(movingbox.MaxEdge.X + speed.X * time, staticbox.MaxEdge.X) + - std::min(movingbox.MinEdge.X + speed.X * time, staticbox.MinEdge.X) + - relbox.MinEdge.X < 0) && + (std::max(movingbox.MaxEdge.Y + speed.Y * time, staticbox.MaxEdge.Y) + - std::min(movingbox.MinEdge.Y + speed.Y * time, staticbox.MinEdge.Y) + - relbox.MinEdge.Y < 0) + ) + return COLLISION_AXIS_Z; + } + } + } + + return COLLISION_AXIS_NONE; +} + +// Helper function: +// Checks if moving the movingbox up by the given distance would hit a ceiling. +bool wouldCollideWithCeiling( + const std::vector<NearbyCollisionInfo> &cinfo, + const aabb3f &movingbox, + f32 y_increase, f32 d) +{ + //TimeTaker tt("wouldCollideWithCeiling"); + + assert(y_increase >= 0); // pre-condition + + for (const auto &it : cinfo) { + const aabb3f &staticbox = it.box; + if ((movingbox.MaxEdge.Y - d <= staticbox.MinEdge.Y) && + (movingbox.MaxEdge.Y + y_increase > staticbox.MinEdge.Y) && + (movingbox.MinEdge.X < staticbox.MaxEdge.X) && + (movingbox.MaxEdge.X > staticbox.MinEdge.X) && + (movingbox.MinEdge.Z < staticbox.MaxEdge.Z) && + (movingbox.MaxEdge.Z > staticbox.MinEdge.Z)) + return true; + } + + return false; +} + +static inline void getNeighborConnectingFace(const v3s16 &p, + const NodeDefManager *nodedef, Map *map, MapNode n, int v, int *neighbors) +{ + MapNode n2 = map->getNode(p); + if (nodedef->nodeboxConnects(n, n2, v)) + *neighbors |= v; +} + +collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, + f32 pos_max_d, const aabb3f &box_0, + f32 stepheight, f32 dtime, + v3f *pos_f, v3f *speed_f, + v3f accel_f, ActiveObject *self, + bool collideWithObjects) +{ + static bool time_notification_done = false; + Map *map = &env->getMap(); + + ScopeProfiler sp(g_profiler, "collisionMoveSimple()", SPT_AVG); + + collisionMoveResult result; + + /* + Calculate new velocity + */ + if (dtime > 0.5f) { + if (!time_notification_done) { + time_notification_done = true; + infostream << "collisionMoveSimple: maximum step interval exceeded," + " lost movement details!"<<std::endl; + } + dtime = 0.5f; + } else { + time_notification_done = false; + } + *speed_f += accel_f * dtime; + + // If there is no speed, there are no collisions + if (speed_f->getLength() == 0) + return result; + + // Limit speed for avoiding hangs + speed_f->Y = rangelim(speed_f->Y, -5000, 5000); + speed_f->X = rangelim(speed_f->X, -5000, 5000); + speed_f->Z = rangelim(speed_f->Z, -5000, 5000); + + *speed_f = truncate(*speed_f, 10000.0f); + + /* + Collect node boxes in movement range + */ + std::vector<NearbyCollisionInfo> cinfo; + { + //TimeTaker tt2("collisionMoveSimple collect boxes"); + ScopeProfiler sp2(g_profiler, "collisionMoveSimple(): collect boxes", SPT_AVG); + + v3f newpos_f = *pos_f + *speed_f * dtime; + v3f minpos_f( + MYMIN(pos_f->X, newpos_f.X), + MYMIN(pos_f->Y, newpos_f.Y) + 0.01f * BS, // bias rounding, player often at +/-n.5 + MYMIN(pos_f->Z, newpos_f.Z) + ); + v3f maxpos_f( + MYMAX(pos_f->X, newpos_f.X), + MYMAX(pos_f->Y, newpos_f.Y), + MYMAX(pos_f->Z, newpos_f.Z) + ); + v3s16 min = floatToInt(minpos_f + box_0.MinEdge, BS) - v3s16(1, 1, 1); + v3s16 max = floatToInt(maxpos_f + box_0.MaxEdge, BS) + v3s16(1, 1, 1); + + bool any_position_valid = false; + + v3s16 p; + for (p.X = min.X; p.X <= max.X; p.X++) + for (p.Y = min.Y; p.Y <= max.Y; p.Y++) + for (p.Z = min.Z; p.Z <= max.Z; p.Z++) { + bool is_position_valid; + MapNode n = map->getNode(p, &is_position_valid); + + if (is_position_valid && n.getContent() != CONTENT_IGNORE) { + // Object collides into walkable nodes + + any_position_valid = true; + const NodeDefManager *nodedef = gamedef->getNodeDefManager(); + const ContentFeatures &f = nodedef->get(n); + + if (!f.walkable) + continue; + + // Negative bouncy may have a meaning, but we need +value here. + int n_bouncy_value = abs(itemgroup_get(f.groups, "bouncy")); + + int neighbors = 0; + if (f.drawtype == NDT_NODEBOX && + f.node_box.type == NODEBOX_CONNECTED) { + v3s16 p2 = p; + + p2.Y++; + getNeighborConnectingFace(p2, nodedef, map, n, 1, &neighbors); + + p2 = p; + p2.Y--; + getNeighborConnectingFace(p2, nodedef, map, n, 2, &neighbors); + + p2 = p; + p2.Z--; + getNeighborConnectingFace(p2, nodedef, map, n, 4, &neighbors); + + p2 = p; + p2.X--; + getNeighborConnectingFace(p2, nodedef, map, n, 8, &neighbors); + + p2 = p; + p2.Z++; + getNeighborConnectingFace(p2, nodedef, map, n, 16, &neighbors); + + p2 = p; + p2.X++; + getNeighborConnectingFace(p2, nodedef, map, n, 32, &neighbors); + } + std::vector<aabb3f> nodeboxes; + n.getCollisionBoxes(gamedef->ndef(), &nodeboxes, neighbors); + + // Calculate float position only once + v3f posf = intToFloat(p, BS); + for (auto box : nodeboxes) { + box.MinEdge += posf; + box.MaxEdge += posf; + cinfo.emplace_back(false, n_bouncy_value, p, box); + } + } else { + // Collide with unloaded nodes (position invalid) and loaded + // CONTENT_IGNORE nodes (position valid) + aabb3f box = getNodeBox(p, BS); + cinfo.emplace_back(true, 0, p, box); + } + } + + // Do not move if world has not loaded yet, since custom node boxes + // are not available for collision detection. + // This also intentionally occurs in the case of the object being positioned + // solely on loaded CONTENT_IGNORE nodes, no matter where they come from. + if (!any_position_valid) { + *speed_f = v3f(0, 0, 0); + return result; + } + + } // tt2 + + if(collideWithObjects) + { + /* add object boxes to cinfo */ + + std::vector<ActiveObject*> objects; +#ifndef SERVER + ClientEnvironment *c_env = dynamic_cast<ClientEnvironment*>(env); + if (c_env != 0) { + // Calculate distance by speed, add own extent and 1.5m of tolerance + f32 distance = speed_f->getLength() * dtime + + box_0.getExtent().getLength() + 1.5f * BS; + std::vector<DistanceSortedActiveObject> clientobjects; + c_env->getActiveObjects(*pos_f, distance, clientobjects); + + for (auto &clientobject : clientobjects) { + // Do collide with everything but itself and the parent CAO + if (!self || (self != clientobject.obj && + self != clientobject.obj->getParent())) { + objects.push_back((ActiveObject*) clientobject.obj); + } + } + } + else +#endif + { + ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env); + if (s_env != NULL) { + // Calculate distance by speed, add own extent and 1.5m of tolerance + f32 distance = speed_f->getLength() * dtime + + box_0.getExtent().getLength() + 1.5f * BS; + + // search for objects which are not us, or we are not its parent + // we directly use the callback to populate the result to prevent + // a useless result loop here + auto include_obj_cb = [self, &objects] (ServerActiveObject *obj) { + if (!obj->isGone() && + (!self || (self != obj && self != obj->getParent()))) { + objects.push_back((ActiveObject *)obj); + } + return false; + }; + + std::vector<ServerActiveObject *> s_objects; + s_env->getObjectsInsideRadius(s_objects, *pos_f, distance, include_obj_cb); + } + } + + for (std::vector<ActiveObject*>::const_iterator iter = objects.begin(); + iter != objects.end(); ++iter) { + ActiveObject *object = *iter; + + if (object && object->collideWithObjects()) { + aabb3f object_collisionbox; + if (object->getCollisionBox(&object_collisionbox)) + cinfo.emplace_back(object, 0, object_collisionbox); + } + } +#ifndef SERVER + if (self && c_env) { + LocalPlayer *lplayer = c_env->getLocalPlayer(); + if (lplayer->getParent() == nullptr) { + aabb3f lplayer_collisionbox = lplayer->getCollisionbox(); + v3f lplayer_pos = lplayer->getPosition(); + lplayer_collisionbox.MinEdge += lplayer_pos; + lplayer_collisionbox.MaxEdge += lplayer_pos; + ActiveObject *obj = (ActiveObject*) lplayer->getCAO(); + cinfo.emplace_back(obj, 0, lplayer_collisionbox); + } + } +#endif + } //tt3 + + /* + Collision detection + */ + + f32 d = 0.0f; + + int loopcount = 0; + + while(dtime > BS * 1e-10f) { + // Avoid infinite loop + loopcount++; + if (loopcount >= 100) { + warningstream << "collisionMoveSimple: Loop count exceeded, aborting to avoid infiniite loop" << std::endl; + break; + } + + aabb3f movingbox = box_0; + movingbox.MinEdge += *pos_f; + movingbox.MaxEdge += *pos_f; + + CollisionAxis nearest_collided = COLLISION_AXIS_NONE; + f32 nearest_dtime = dtime; + int nearest_boxindex = -1; + + /* + Go through every nodebox, find nearest collision + */ + for (u32 boxindex = 0; boxindex < cinfo.size(); boxindex++) { + const NearbyCollisionInfo &box_info = cinfo[boxindex]; + // Ignore if already stepped up this nodebox. + if (box_info.is_step_up) + continue; + + // Find nearest collision of the two boxes (raytracing-like) + f32 dtime_tmp = nearest_dtime; + CollisionAxis collided = axisAlignedCollision(box_info.box, + movingbox, *speed_f, &dtime_tmp); + + if (collided == -1 || dtime_tmp >= nearest_dtime) + continue; + + nearest_dtime = dtime_tmp; + nearest_collided = collided; + nearest_boxindex = boxindex; + } + + if (nearest_collided == COLLISION_AXIS_NONE) { + // No collision with any collision box. + *pos_f += truncate(*speed_f * dtime, 100.0f); + dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers + } else { + // Otherwise, a collision occurred. + NearbyCollisionInfo &nearest_info = cinfo[nearest_boxindex]; + const aabb3f& cbox = nearest_info.box; + + //movingbox except moved to the horizontal position it would be after step up + aabb3f stepbox = movingbox; + stepbox.MinEdge.X += speed_f->X * dtime; + stepbox.MinEdge.Z += speed_f->Z * dtime; + stepbox.MaxEdge.X += speed_f->X * dtime; + stepbox.MaxEdge.Z += speed_f->Z * dtime; + // Check for stairs. + bool step_up = (nearest_collided != COLLISION_AXIS_Y) && // must not be Y direction + (movingbox.MinEdge.Y < cbox.MaxEdge.Y) && + (movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) && + (!wouldCollideWithCeiling(cinfo, stepbox, + cbox.MaxEdge.Y - movingbox.MinEdge.Y, + d)); + + // Get bounce multiplier + float bounce = -(float)nearest_info.bouncy / 100.0f; + + // Move to the point of collision and reduce dtime by nearest_dtime + if (nearest_dtime < 0) { + // Handle negative nearest_dtime + if (!step_up) { + if (nearest_collided == COLLISION_AXIS_X) + pos_f->X += speed_f->X * nearest_dtime; + if (nearest_collided == COLLISION_AXIS_Y) + pos_f->Y += speed_f->Y * nearest_dtime; + if (nearest_collided == COLLISION_AXIS_Z) + pos_f->Z += speed_f->Z * nearest_dtime; + } + } else { + *pos_f += truncate(*speed_f * nearest_dtime, 100.0f); + dtime -= nearest_dtime; + } + + bool is_collision = true; + if (nearest_info.is_unloaded) + is_collision = false; + + CollisionInfo info; + if (nearest_info.isObject()) + info.type = COLLISION_OBJECT; + else + info.type = COLLISION_NODE; + + info.node_p = nearest_info.position; + info.object = nearest_info.obj; + info.old_speed = *speed_f; + info.plane = nearest_collided; + + // Set the speed component that caused the collision to zero + if (step_up) { + // Special case: Handle stairs + nearest_info.is_step_up = true; + is_collision = false; + } else if (nearest_collided == COLLISION_AXIS_X) { + if (fabs(speed_f->X) > BS * 3) + speed_f->X *= bounce; + else + speed_f->X = 0; + result.collides = true; + } else if (nearest_collided == COLLISION_AXIS_Y) { + if(fabs(speed_f->Y) > BS * 3) + speed_f->Y *= bounce; + else + speed_f->Y = 0; + result.collides = true; + } else if (nearest_collided == COLLISION_AXIS_Z) { + if (fabs(speed_f->Z) > BS * 3) + speed_f->Z *= bounce; + else + speed_f->Z = 0; + result.collides = true; + } + + info.new_speed = *speed_f; + if (info.new_speed.getDistanceFrom(info.old_speed) < 0.1f * BS) + is_collision = false; + + if (is_collision) { + info.axis = nearest_collided; + result.collisions.push_back(info); + } + } + } + + /* + Final touches: Check if standing on ground, step up stairs. + */ + aabb3f box = box_0; + box.MinEdge += *pos_f; + box.MaxEdge += *pos_f; + for (const auto &box_info : cinfo) { + const aabb3f &cbox = box_info.box; + + /* + See if the object is touching ground. + + Object touches ground if object's minimum Y is near node's + maximum Y and object's X-Z-area overlaps with the node's + X-Z-area. + */ + + if (cbox.MaxEdge.X - d > box.MinEdge.X && cbox.MinEdge.X + d < box.MaxEdge.X && + cbox.MaxEdge.Z - d > box.MinEdge.Z && + cbox.MinEdge.Z + d < box.MaxEdge.Z) { + if (box_info.is_step_up) { + pos_f->Y += cbox.MaxEdge.Y - box.MinEdge.Y; + box = box_0; + box.MinEdge += *pos_f; + box.MaxEdge += *pos_f; + } + if (std::fabs(cbox.MaxEdge.Y - box.MinEdge.Y) < 0.05f) { + result.touching_ground = true; + + if (box_info.isObject()) + result.standing_on_object = true; + } + } + } + + return result; +} diff --git a/src/collision.h b/src/collision.h new file mode 100644 index 0000000..87a5028 --- /dev/null +++ b/src/collision.h @@ -0,0 +1,88 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +#include <vector> + +class Map; +class IGameDef; +class Environment; +class ActiveObject; + +enum CollisionType +{ + COLLISION_NODE, + COLLISION_OBJECT, +}; + +enum CollisionAxis +{ + COLLISION_AXIS_NONE = -1, + COLLISION_AXIS_X, + COLLISION_AXIS_Y, + COLLISION_AXIS_Z, +}; + +struct CollisionInfo +{ + CollisionInfo() = default; + + CollisionType type = COLLISION_NODE; + CollisionAxis axis = COLLISION_AXIS_NONE; + v3s16 node_p = v3s16(-32768,-32768,-32768); // COLLISION_NODE + ActiveObject *object = nullptr; // COLLISION_OBJECT + v3f old_speed; + v3f new_speed; + int plane = -1; +}; + +struct collisionMoveResult +{ + collisionMoveResult() = default; + + bool touching_ground = false; + bool collides = false; + bool standing_on_object = false; + std::vector<CollisionInfo> collisions; +}; + +// Moves using a single iteration; speed should not exceed pos_max_d/dtime +collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef, + f32 pos_max_d, const aabb3f &box_0, + f32 stepheight, f32 dtime, + v3f *pos_f, v3f *speed_f, + v3f accel_f, ActiveObject *self=NULL, + bool collideWithObjects=true); + +// Helper function: +// Checks for collision of a moving aabbox with a static aabbox +// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision +// dtime receives time until first collision, invalid if -1 is returned +CollisionAxis axisAlignedCollision( + const aabb3f &staticbox, const aabb3f &movingbox, + const v3f &speed, f32 *dtime); + +// Helper function: +// Checks if moving the movingbox up by the given distance would hit a ceiling. +bool wouldCollideWithCeiling( + const std::vector<aabb3f> &staticboxes, + const aabb3f &movingbox, + f32 y_increase, f32 d); diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..a4c6c9f --- /dev/null +++ b/src/config.h @@ -0,0 +1,27 @@ +/* + If CMake is used, includes the cmake-generated cmake_config.h. + Otherwise use default values +*/ + +#pragma once + +#define STRINGIFY(x) #x +#define STR(x) STRINGIFY(x) + + +#if defined USE_CMAKE_CONFIG_H + #include "cmake_config.h" +#else + #if defined (__ANDROID__) + #define PROJECT_NAME "minetest" + #define PROJECT_NAME_C "Minetest" + #define STATIC_SHAREDIR "" + #define ENABLE_UPDATE_CHECKER 0 + #define VERSION_STRING STR(VERSION_MAJOR) "." STR(VERSION_MINOR) "." STR(VERSION_PATCH) STR(VERSION_EXTRA) + #endif + #ifdef NDEBUG + #define BUILD_TYPE "Release" + #else + #define BUILD_TYPE "Debug" + #endif +#endif diff --git a/src/constants.h b/src/constants.h new file mode 100644 index 0000000..b9d4f8d --- /dev/null +++ b/src/constants.h @@ -0,0 +1,113 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +/* + All kinds of constants. + + Cross-platform compatibility stuff should go in porting.h. + + Some things here are legacy. +*/ + +/* + Connection +*/ + +#define PEER_ID_INEXISTENT 0 +#define PEER_ID_SERVER 1 + +// Define for simulating the quirks of sending through internet. +// Causes the socket class to deliberately drop random packets. +// This disables unit testing of socket and connection. +#define INTERNET_SIMULATOR 0 +#define INTERNET_SIMULATOR_PACKET_LOSS 10 // 10 = easy, 4 = hard + +#define CONNECTION_TIMEOUT 30 + +#define RESEND_TIMEOUT_MIN 0.1 +#define RESEND_TIMEOUT_MAX 3.0 +// resend_timeout = avg_rtt * this +#define RESEND_TIMEOUT_FACTOR 4 + +/* + Server +*/ + +// This many blocks are sent when player is building +#define LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS 0 +// Override for the previous one when distance of block is very low +#define BLOCK_SEND_DISABLE_LIMITS_MAX_D 1 + +/* + Map-related things +*/ + +// The absolute working limit is (2^15 - viewing_range). +// I really don't want to make every algorithm to check if it's going near +// the limit or not, so this is lower. +// This is the maximum value the setting map_generation_limit can be +#define MAX_MAP_GENERATION_LIMIT (31007) + +// Size of node in floating-point units +// The original idea behind this is to disallow plain casts between +// floating-point and integer positions, which potentially give wrong +// results. (negative coordinates, values between nodes, ...) +// Use floatToInt(p, BS) and intToFloat(p, BS). +#define BS 10.0f + +// Dimension of a MapBlock +#define MAP_BLOCKSIZE 16 +// This makes mesh updates too slow, as many meshes are updated during +// the main loop (related to TempMods and day/night) +//#define MAP_BLOCKSIZE 32 + +// Player step height in nodes +#define PLAYER_DEFAULT_STEPHEIGHT 0.6f + +/* + Old stuff that shouldn't be hardcoded +*/ + +// Size of player's main inventory +#define PLAYER_INVENTORY_SIZE (8 * 4) + +// Default maximum health points of a player +#define PLAYER_MAX_HP_DEFAULT 20 + +// Default maximal breath of a player +#define PLAYER_MAX_BREATH_DEFAULT 10 + +// Number of different files to try to save a player to if the first fails +// (because of a case-insensitive filesystem) +// TODO: Use case-insensitive player names instead of this hack. +#define PLAYER_FILE_ALTERNATE_TRIES 1000 + +// For screenshots a serial number is appended to the filename + datetimestamp +// if filename + datetimestamp is not unique. +// This is the maximum number of attempts to try and add a serial to the end of +// the file attempting to ensure a unique filename +#define SCREENSHOT_MAX_SERIAL_TRIES 1000 + +/* + GUI related things +*/ + +#define TTF_DEFAULT_FONT_SIZE (16) diff --git a/src/content/CMakeLists.txt b/src/content/CMakeLists.txt new file mode 100644 index 0000000..2aefd40 --- /dev/null +++ b/src/content/CMakeLists.txt @@ -0,0 +1,7 @@ +set(content_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/content.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mod_configuration.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mods.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/subgames.cpp + PARENT_SCOPE +) diff --git a/src/content/content.cpp b/src/content/content.cpp new file mode 100644 index 0000000..e576943 --- /dev/null +++ b/src/content/content.cpp @@ -0,0 +1,122 @@ +/* +Minetest +Copyright (C) 2018 rubenwardy <rw@rubenwardy.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <fstream> +#include "content/content.h" +#include "content/subgames.h" +#include "content/mods.h" +#include "filesys.h" +#include "settings.h" + +enum ContentType +{ + ECT_UNKNOWN, + ECT_MOD, + ECT_MODPACK, + ECT_GAME, + ECT_TXP +}; + +ContentType getContentType(const ContentSpec &spec) +{ + std::ifstream modpack_is((spec.path + DIR_DELIM + "modpack.txt").c_str()); + if (modpack_is.good()) { + modpack_is.close(); + return ECT_MODPACK; + } + + std::ifstream modpack2_is((spec.path + DIR_DELIM + "modpack.conf").c_str()); + if (modpack2_is.good()) { + modpack2_is.close(); + return ECT_MODPACK; + } + + std::ifstream init_is((spec.path + DIR_DELIM + "init.lua").c_str()); + if (init_is.good()) { + init_is.close(); + return ECT_MOD; + } + + std::ifstream game_is((spec.path + DIR_DELIM + "game.conf").c_str()); + if (game_is.good()) { + game_is.close(); + return ECT_GAME; + } + + std::ifstream txp_is((spec.path + DIR_DELIM + "texture_pack.conf").c_str()); + if (txp_is.good()) { + txp_is.close(); + return ECT_TXP; + } + + return ECT_UNKNOWN; +} + +void parseContentInfo(ContentSpec &spec) +{ + std::string conf_path; + + switch (getContentType(spec)) { + case ECT_MOD: + spec.type = "mod"; + conf_path = spec.path + DIR_DELIM + "mod.conf"; + break; + case ECT_MODPACK: + spec.type = "modpack"; + conf_path = spec.path + DIR_DELIM + "modpack.conf"; + break; + case ECT_GAME: + spec.type = "game"; + conf_path = spec.path + DIR_DELIM + "game.conf"; + break; + case ECT_TXP: + spec.type = "txp"; + conf_path = spec.path + DIR_DELIM + "texture_pack.conf"; + break; + default: + spec.type = "unknown"; + break; + } + + Settings conf; + if (!conf_path.empty() && conf.readConfigFile(conf_path.c_str())) { + if (conf.exists("title")) + spec.title = conf.get("title"); + else if (spec.type == "game" && conf.exists("name")) + spec.title = conf.get("name"); + + if (spec.type != "game" && conf.exists("name")) + spec.name = conf.get("name"); + + if (conf.exists("description")) + spec.desc = conf.get("description"); + + if (conf.exists("author")) + spec.author = conf.get("author"); + + if (conf.exists("release")) + spec.release = conf.getS32("release"); + } + + if (spec.desc.empty()) { + std::ifstream is((spec.path + DIR_DELIM + "description.txt").c_str()); + spec.desc = std::string((std::istreambuf_iterator<char>(is)), + std::istreambuf_iterator<char>()); + } +} diff --git a/src/content/content.h b/src/content/content.h new file mode 100644 index 0000000..ce09a2e --- /dev/null +++ b/src/content/content.h @@ -0,0 +1,42 @@ +/* +Minetest +Copyright (C) 2018 rubenwardy <rw@rubenwardy.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "config.h" +#include "convert_json.h" +#include "irrlichttypes.h" + +struct ContentSpec +{ + std::string type; + std::string author; + u32 release = 0; + + /// Technical name / Id + std::string name; + + /// Human-readable title + std::string title; + + /// Short description + std::string desc; + std::string path; +}; + +void parseContentInfo(ContentSpec &spec); diff --git a/src/content/mod_configuration.cpp b/src/content/mod_configuration.cpp new file mode 100644 index 0000000..504cdaf --- /dev/null +++ b/src/content/mod_configuration.cpp @@ -0,0 +1,255 @@ +/* +Minetest +Copyright (C) 2013-22 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mod_configuration.h" +#include "log.h" +#include "settings.h" +#include "filesys.h" + +void ModConfiguration::printUnsatisfiedModsError() const +{ + for (const ModSpec &mod : m_unsatisfied_mods) { + errorstream << "mod \"" << mod.name + << "\" has unsatisfied dependencies: "; + for (const std::string &unsatisfied_depend : mod.unsatisfied_depends) + errorstream << " \"" << unsatisfied_depend << "\""; + errorstream << std::endl; + } +} + +void ModConfiguration::addModsInPath(const std::string &path, const std::string &virtual_path) +{ + addMods(flattenMods(getModsInPath(path, virtual_path))); +} + +void ModConfiguration::addMods(const std::vector<ModSpec> &new_mods) +{ + // Maintain a map of all existing m_unsatisfied_mods. + // Keys are mod names and values are indices into m_unsatisfied_mods. + std::map<std::string, u32> existing_mods; + for (u32 i = 0; i < m_unsatisfied_mods.size(); ++i) { + existing_mods[m_unsatisfied_mods[i].name] = i; + } + + // Add new mods + for (int want_from_modpack = 1; want_from_modpack >= 0; --want_from_modpack) { + // First iteration: + // Add all the mods that come from modpacks + // Second iteration: + // Add all the mods that didn't come from modpacks + + std::set<std::string> seen_this_iteration; + + for (const ModSpec &mod : new_mods) { + if (mod.part_of_modpack != (bool)want_from_modpack) + continue; + + if (existing_mods.count(mod.name) == 0) { + // GOOD CASE: completely new mod. + m_unsatisfied_mods.push_back(mod); + existing_mods[mod.name] = m_unsatisfied_mods.size() - 1; + } else if (seen_this_iteration.count(mod.name) == 0) { + // BAD CASE: name conflict in different levels. + u32 oldindex = existing_mods[mod.name]; + const ModSpec &oldmod = m_unsatisfied_mods[oldindex]; + warningstream << "Mod name conflict detected: \"" + << mod.name << "\"" << std::endl + << "Will not load: " << oldmod.path + << std::endl + << "Overridden by: " << mod.path + << std::endl; + m_unsatisfied_mods[oldindex] = mod; + + // If there was a "VERY BAD CASE" name conflict + // in an earlier level, ignore it. + m_name_conflicts.erase(mod.name); + } else { + // VERY BAD CASE: name conflict in the same level. + u32 oldindex = existing_mods[mod.name]; + const ModSpec &oldmod = m_unsatisfied_mods[oldindex]; + warningstream << "Mod name conflict detected: \"" + << mod.name << "\"" << std::endl + << "Will not load: " << oldmod.path + << std::endl + << "Will not load: " << mod.path + << std::endl; + m_unsatisfied_mods[oldindex] = mod; + m_name_conflicts.insert(mod.name); + } + + seen_this_iteration.insert(mod.name); + } + } +} + +void ModConfiguration::addGameMods(const SubgameSpec &gamespec) +{ + std::string game_virtual_path; + game_virtual_path.append("games/").append(gamespec.id).append("/mods"); + addModsInPath(gamespec.gamemods_path, game_virtual_path); +} + +void ModConfiguration::addModsFromConfig( + const std::string &settings_path, + const std::unordered_map<std::string, std::string> &modPaths) +{ + Settings conf; + std::unordered_map<std::string, std::string> load_mod_names; + + conf.readConfigFile(settings_path.c_str()); + std::vector<std::string> names = conf.getNames(); + for (const std::string &name : names) { + const auto &value = conf.get(name); + if (name.compare(0, 9, "load_mod_") == 0 && value != "false" && + value != "nil") + load_mod_names[name.substr(9)] = value; + } + + // List of enabled non-game non-world mods + std::vector<ModSpec> addon_mods; + + // Map of modname to a list candidate mod paths. Used to list + // alternatives if a particular mod cannot be found. + std::unordered_map<std::string, std::vector<std::string>> candidates; + + /* + * Iterate through all installed mods except game mods and world mods + * + * If the mod is enabled, add it to `addon_mods`. * + * + * Alternative candidates for a modname are stored in `candidates`, + * and used in an error message later. + * + * If not enabled, add `load_mod_modname = false` to world.mt + */ + for (const auto &modPath : modPaths) { + std::vector<ModSpec> addon_mods_in_path = flattenMods(getModsInPath(modPath.second, modPath.first)); + for (const auto &mod : addon_mods_in_path) { + const auto &pair = load_mod_names.find(mod.name); + if (pair != load_mod_names.end()) { + if (is_yes(pair->second) || pair->second == mod.virtual_path) { + addon_mods.push_back(mod); + } else { + candidates[pair->first].emplace_back(mod.virtual_path); + } + } else { + conf.setBool("load_mod_" + mod.name, false); + } + } + } + conf.updateConfigFile(settings_path.c_str()); + + addMods(addon_mods); + + // Remove all loaded mods from `load_mod_names` + // NB: as deps have not yet been resolved, `m_unsatisfied_mods` will contain all mods. + for (const ModSpec &mod : m_unsatisfied_mods) + load_mod_names.erase(mod.name); + + // Complain about mods declared to be loaded, but not found + if (!load_mod_names.empty()) { + errorstream << "The following mods could not be found:"; + for (const auto &pair : load_mod_names) + errorstream << " \"" << pair.first << "\""; + errorstream << std::endl; + + for (const auto &pair : load_mod_names) { + const auto &candidate = candidates.find(pair.first); + if (candidate != candidates.end()) { + errorstream << "Unable to load " << pair.first << " as the specified path " + << pair.second << " could not be found. " + << "However, it is available in the following locations:" + << std::endl; + for (const auto &path : candidate->second) { + errorstream << " - " << path << std::endl; + } + } + } + } +} + +void ModConfiguration::checkConflictsAndDeps() +{ + // report on name conflicts + if (!m_name_conflicts.empty()) { + std::string s = "Unresolved name conflicts for mods "; + + bool add_comma = false; + for (const auto& it : m_name_conflicts) { + if (add_comma) + s.append(", "); + s.append("\"").append(it).append("\""); + add_comma = true; + } + s.append("."); + + throw ModError(s); + } + + // get the mods in order + resolveDependencies(); +} + +void ModConfiguration::resolveDependencies() +{ + // Step 1: Compile a list of the mod names we're working with + std::set<std::string> modnames; + for (const ModSpec &mod : m_unsatisfied_mods) { + modnames.insert(mod.name); + } + + // Step 2: get dependencies (including optional dependencies) + // of each mod, split mods into satisfied and unsatisfied + std::list<ModSpec> satisfied; + std::list<ModSpec> unsatisfied; + for (ModSpec mod : m_unsatisfied_mods) { + mod.unsatisfied_depends = mod.depends; + // check which optional dependencies actually exist + for (const std::string &optdep : mod.optdepends) { + if (modnames.count(optdep) != 0) + mod.unsatisfied_depends.insert(optdep); + } + // if a mod has no depends it is initially satisfied + if (mod.unsatisfied_depends.empty()) + satisfied.push_back(mod); + else + unsatisfied.push_back(mod); + } + + // Step 3: mods without unmet dependencies can be appended to + // the sorted list. + while (!satisfied.empty()) { + ModSpec mod = satisfied.back(); + m_sorted_mods.push_back(mod); + satisfied.pop_back(); + for (auto it = unsatisfied.begin(); it != unsatisfied.end();) { + ModSpec &mod2 = *it; + mod2.unsatisfied_depends.erase(mod.name); + if (mod2.unsatisfied_depends.empty()) { + satisfied.push_back(mod2); + it = unsatisfied.erase(it); + } else { + ++it; + } + } + } + + // Step 4: write back list of unsatisfied mods + m_unsatisfied_mods.assign(unsatisfied.begin(), unsatisfied.end()); +} diff --git a/src/content/mod_configuration.h b/src/content/mod_configuration.h new file mode 100644 index 0000000..1595d1c --- /dev/null +++ b/src/content/mod_configuration.h @@ -0,0 +1,111 @@ +/* +Minetest +Copyright (C) 2013-22 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "mods.h" + + +/** + * ModConfiguration is a subset of installed mods. This class + * is used to resolve dependencies and return a sorted list of mods. + * + * This class should not be extended from, but instead used as a + * component in other classes. + */ +class ModConfiguration +{ +public: + /** + * @returns true if all dependencies are fullfilled. + */ + inline bool isConsistent() const { return m_unsatisfied_mods.empty(); } + + inline const std::vector<ModSpec> &getUnsatisfiedMods() const + { + return m_unsatisfied_mods; + } + + /** + * List of mods sorted such that they can be loaded in the + * given order with all dependencies being fulfilled. + * + * I.e: every mod in this list has only dependencies on mods which + * appear earlier in the vector. + */ + const std::vector<ModSpec> &getMods() const { return m_sorted_mods; } + + void printUnsatisfiedModsError() const; + + /** + * Adds all mods in the given path. used for games, modpacks + * and world-specific mods (worldmods-folders) + * + * @param path To search, should be absolute + * @param virtual_path Virtual path for this directory, see comment in ModSpec + */ + void addModsInPath(const std::string &path, const std::string &virtual_path); + + /** + * Adds all mods in `new_mods` + */ + void addMods(const std::vector<ModSpec> &new_mods); + + /** + * Adds game mods + */ + void addGameMods(const SubgameSpec &gamespec); + + /** + * Adds mods specifed by a world.mt config + * + * @param settings_path Path to world.mt + * @param modPaths Map from virtual name to mod path + */ + void addModsFromConfig(const std::string &settings_path, + const std::unordered_map<std::string, std::string> &modPaths); + + /** + * Call this function once all mods have been added + */ + void checkConflictsAndDeps(); + +private: + std::vector<ModSpec> m_sorted_mods; + + /** + * move mods from m_unsatisfied_mods to m_sorted_mods + * in an order that satisfies dependencies + */ + void resolveDependencies(); + + // mods with unmet dependencies. Before dependencies are resolved, + // this is where all mods are stored. Afterwards this contains + // only the ones with really unsatisfied dependencies. + std::vector<ModSpec> m_unsatisfied_mods; + + // set of mod names for which an unresolved name conflict + // exists. A name conflict happens when two or more mods + // at the same level have the same name but different paths. + // Levels (mods in higher levels override mods in lower levels): + // 1. game mod in modpack; 2. game mod; + // 3. world mod in modpack; 4. world mod; + // 5. addon mod in modpack; 6. addon mod. + std::unordered_set<std::string> m_name_conflicts; +}; diff --git a/src/content/mods.cpp b/src/content/mods.cpp new file mode 100644 index 0000000..cec6fc2 --- /dev/null +++ b/src/content/mods.cpp @@ -0,0 +1,245 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <cctype> +#include <fstream> +#include <json/json.h> +#include <algorithm> +#include "content/mods.h" +#include "database/database.h" +#include "filesys.h" +#include "log.h" +#include "content/subgames.h" +#include "settings.h" +#include "porting.h" +#include "convert_json.h" +#include "script/common/c_internal.h" + +void ModSpec::checkAndLog() const +{ + if (!string_allowed(name, MODNAME_ALLOWED_CHARS)) { + throw ModError("Error loading mod \"" + name + + "\": Mod name does not follow naming conventions: " + "Only characters [a-z0-9_] are allowed."); + } + + // Log deprecation messages + auto handling_mode = get_deprecated_handling_mode(); + if (!deprecation_msgs.empty() && handling_mode != DeprecatedHandlingMode::Ignore) { + std::ostringstream os; + os << "Mod " << name << " at " << path << ":" << std::endl; + for (auto msg : deprecation_msgs) + os << "\t" << msg << std::endl; + + if (handling_mode == DeprecatedHandlingMode::Error) + throw ModError(os.str()); + else + warningstream << os.str(); + } +} + +bool parseDependsString(std::string &dep, std::unordered_set<char> &symbols) +{ + dep = trim(dep); + symbols.clear(); + size_t pos = dep.size(); + while (pos > 0 && + !string_allowed(dep.substr(pos - 1, 1), MODNAME_ALLOWED_CHARS)) { + // last character is a symbol, not part of the modname + symbols.insert(dep[pos - 1]); + --pos; + } + dep = trim(dep.substr(0, pos)); + return !dep.empty(); +} + +bool parseModContents(ModSpec &spec) +{ + // NOTE: this function works in mutual recursion with getModsInPath + + spec.depends.clear(); + spec.optdepends.clear(); + spec.is_modpack = false; + spec.modpack_content.clear(); + + // Handle modpacks (defined by containing modpack.txt) + if (fs::IsFile(spec.path + DIR_DELIM + "modpack.txt") || + fs::IsFile(spec.path + DIR_DELIM + "modpack.conf")) { + spec.is_modpack = true; + spec.modpack_content = getModsInPath(spec.path, spec.virtual_path, true); + return true; + } else if (!fs::IsFile(spec.path + DIR_DELIM + "init.lua")) { + return false; + } + + + Settings info; + info.readConfigFile((spec.path + DIR_DELIM + "mod.conf").c_str()); + + if (info.exists("name")) + spec.name = info.get("name"); + else + spec.deprecation_msgs.push_back("Mods not having a mod.conf file with the name is deprecated."); + + if (info.exists("author")) + spec.author = info.get("author"); + + if (info.exists("release")) + spec.release = info.getS32("release"); + + // Attempt to load dependencies from mod.conf + bool mod_conf_has_depends = false; + if (info.exists("depends")) { + mod_conf_has_depends = true; + std::string dep = info.get("depends"); + // clang-format off + dep.erase(std::remove_if(dep.begin(), dep.end(), + static_cast<int (*)(int)>(&std::isspace)), dep.end()); + // clang-format on + for (const auto &dependency : str_split(dep, ',')) { + spec.depends.insert(dependency); + } + } + + if (info.exists("optional_depends")) { + mod_conf_has_depends = true; + std::string dep = info.get("optional_depends"); + // clang-format off + dep.erase(std::remove_if(dep.begin(), dep.end(), + static_cast<int (*)(int)>(&std::isspace)), dep.end()); + // clang-format on + for (const auto &dependency : str_split(dep, ',')) { + spec.optdepends.insert(dependency); + } + } + + // Fallback to depends.txt + if (!mod_conf_has_depends) { + std::vector<std::string> dependencies; + + std::ifstream is((spec.path + DIR_DELIM + "depends.txt").c_str()); + + if (is.good()) + spec.deprecation_msgs.push_back("depends.txt is deprecated, please use mod.conf instead."); + + while (is.good()) { + std::string dep; + std::getline(is, dep); + dependencies.push_back(dep); + } + + for (auto &dependency : dependencies) { + std::unordered_set<char> symbols; + if (parseDependsString(dependency, symbols)) { + if (symbols.count('?') != 0) { + spec.optdepends.insert(dependency); + } else { + spec.depends.insert(dependency); + } + } + } + } + + if (info.exists("description")) + spec.desc = info.get("description"); + else if (fs::ReadFile(spec.path + DIR_DELIM + "description.txt", spec.desc)) + spec.deprecation_msgs.push_back("description.txt is deprecated, please use mod.conf instead."); + + return true; +} + +std::map<std::string, ModSpec> getModsInPath( + const std::string &path, const std::string &virtual_path, bool part_of_modpack) +{ + // NOTE: this function works in mutual recursion with parseModContents + + std::map<std::string, ModSpec> result; + std::vector<fs::DirListNode> dirlist = fs::GetDirListing(path); + std::string mod_path; + std::string mod_virtual_path; + + for (const fs::DirListNode &dln : dirlist) { + if (!dln.dir) + continue; + + const std::string &modname = dln.name; + // Ignore all directories beginning with a ".", especially + // VCS directories like ".git" or ".svn" + if (modname[0] == '.') + continue; + + mod_path.clear(); + mod_path.append(path).append(DIR_DELIM).append(modname); + + mod_virtual_path.clear(); + // Intentionally uses / to keep paths same on different platforms + mod_virtual_path.append(virtual_path).append("/").append(modname); + + ModSpec spec(modname, mod_path, part_of_modpack, mod_virtual_path); + parseModContents(spec); + result.insert(std::make_pair(modname, spec)); + } + return result; +} + +std::vector<ModSpec> flattenMods(const std::map<std::string, ModSpec> &mods) +{ + std::vector<ModSpec> result; + for (const auto &it : mods) { + const ModSpec &mod = it.second; + if (mod.is_modpack) { + std::vector<ModSpec> content = flattenMods(mod.modpack_content); + result.reserve(result.size() + content.size()); + result.insert(result.end(), content.begin(), content.end()); + + } else // not a modpack + { + result.push_back(mod); + } + } + return result; +} + + +ModMetadata::ModMetadata(const std::string &mod_name, ModMetadataDatabase *database): + m_mod_name(mod_name), m_database(database) +{ + m_database->getModEntries(m_mod_name, &m_stringvars); +} + +void ModMetadata::clear() +{ + for (const auto &pair : m_stringvars) { + m_database->removeModEntry(m_mod_name, pair.first); + } + Metadata::clear(); +} + +bool ModMetadata::setString(const std::string &name, const std::string &var) +{ + if (Metadata::setString(name, var)) { + if (var.empty()) { + m_database->removeModEntry(m_mod_name, name); + } else { + m_database->setModEntry(m_mod_name, name, var); + } + return true; + } + return false; +} diff --git a/src/content/mods.h b/src/content/mods.h new file mode 100644 index 0000000..5ed5b81 --- /dev/null +++ b/src/content/mods.h @@ -0,0 +1,129 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include <list> +#include <set> +#include <vector> +#include <string> +#include <map> +#include <json/json.h> +#include <unordered_set> +#include "util/basic_macros.h" +#include "config.h" +#include "metadata.h" +#include "subgames.h" + +class ModMetadataDatabase; + +#define MODNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_" + +struct ModSpec +{ + std::string name; + std::string author; + std::string path; + std::string desc; + int release = 0; + + // if normal mod: + std::unordered_set<std::string> depends; + std::unordered_set<std::string> optdepends; + std::unordered_set<std::string> unsatisfied_depends; + + bool part_of_modpack = false; + bool is_modpack = false; + + /** + * A constructed canonical path to represent this mod's location. + * This intended to be used as an identifier for a modpath that tolerates file movement, + * and cannot be used to read the mod files. + * + * Note that `mymod` is the directory name, not the mod name specified in mod.conf. + * + * Ex: + * + * - mods/mymod + * - mods/mymod (1) + * (^ this would have name=mymod in mod.conf) + * - mods/modpack1/mymod + * - games/mygame/mods/mymod + * - worldmods/mymod + */ + std::string virtual_path; + + // For logging purposes + std::vector<const char *> deprecation_msgs; + + // if modpack: + std::map<std::string, ModSpec> modpack_content; + + ModSpec() + { + } + + ModSpec(const std::string &name, const std::string &path, bool part_of_modpack, const std::string &virtual_path) : + name(name), path(path), part_of_modpack(part_of_modpack), virtual_path(virtual_path) + { + } + + void checkAndLog() const; +}; + +/** + * Retrieves depends, optdepends, is_modpack and modpack_content + * + * @returns false if not a mod + */ +bool parseModContents(ModSpec &mod); + +/** + * Gets a list of all mods and modpacks in path + * + * @param Path to search, should be absolute + * @param part_of_modpack Is this searching within a modpack? + * @param virtual_path Virtual path for this directory, see comment in ModSpec + * @returns map of mods + */ +std::map<std::string, ModSpec> getModsInPath(const std::string &path, + const std::string &virtual_path, bool part_of_modpack = false); + +// replaces modpack Modspecs with their content +std::vector<ModSpec> flattenMods(const std::map<std::string, ModSpec> &mods); + + +class ModMetadata : public Metadata +{ +public: + ModMetadata() = delete; + ModMetadata(const std::string &mod_name, ModMetadataDatabase *database); + ~ModMetadata() = default; + + virtual void clear(); + + const std::string &getModName() const { return m_mod_name; } + + virtual bool setString(const std::string &name, const std::string &var); + +private: + std::string m_mod_name; + ModMetadataDatabase *m_database; +}; diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp new file mode 100644 index 0000000..d0de926 --- /dev/null +++ b/src/content/subgames.cpp @@ -0,0 +1,423 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <common/c_internal.h> +#include "content/subgames.h" +#include "porting.h" +#include "filesys.h" +#include "settings.h" +#include "log.h" +#include "util/strfnd.h" +#include "defaultsettings.h" // for set_default_settings +#include "map_settings_manager.h" +#include "util/string.h" + +#ifndef SERVER +#include "client/tile.h" // getImagePath +#endif + +// The maximum number of identical world names allowed +#define MAX_WORLD_NAMES 100 + +namespace +{ + +bool getGameMinetestConfig(const std::string &game_path, Settings &conf) +{ + std::string conf_path = game_path + DIR_DELIM + "minetest.conf"; + return conf.readConfigFile(conf_path.c_str()); +} + +} + + +void SubgameSpec::checkAndLog() const +{ + // Log deprecation messages + auto handling_mode = get_deprecated_handling_mode(); + if (!deprecation_msgs.empty() && handling_mode != DeprecatedHandlingMode::Ignore) { + std::ostringstream os; + os << "Game " << title << " at " << path << ":" << std::endl; + for (auto msg : deprecation_msgs) + os << "\t" << msg << std::endl; + + if (handling_mode == DeprecatedHandlingMode::Error) + throw ModError(os.str()); + else + warningstream << os.str(); + } +} + + +struct GameFindPath +{ + std::string path; + bool user_specific; + GameFindPath(const std::string &path, bool user_specific) : + path(path), user_specific(user_specific) + { + } +}; + +std::string getSubgamePathEnv() +{ + char *subgame_path = getenv("MINETEST_SUBGAME_PATH"); + return subgame_path ? std::string(subgame_path) : ""; +} + +SubgameSpec findSubgame(const std::string &id) +{ + if (id.empty()) + return SubgameSpec(); + std::string share = porting::path_share; + std::string user = porting::path_user; + + // Get games install locations + Strfnd search_paths(getSubgamePathEnv()); + + // Get all possible paths fo game + std::vector<GameFindPath> find_paths; + while (!search_paths.at_end()) { + std::string path = search_paths.next(PATH_DELIM); + path.append(DIR_DELIM).append(id); + find_paths.emplace_back(path, false); + path.append("_game"); + find_paths.emplace_back(path, false); + } + + std::string game_base = DIR_DELIM; + game_base = game_base.append("games").append(DIR_DELIM).append(id); + std::string game_suffixed = game_base + "_game"; + find_paths.emplace_back(user + game_suffixed, true); + find_paths.emplace_back(user + game_base, true); + find_paths.emplace_back(share + game_suffixed, false); + find_paths.emplace_back(share + game_base, false); + + // Find game directory + std::string game_path; + bool user_game = true; // Game is in user's directory + for (const GameFindPath &find_path : find_paths) { + const std::string &try_path = find_path.path; + if (fs::PathExists(try_path)) { + game_path = try_path; + user_game = find_path.user_specific; + break; + } + } + + if (game_path.empty()) + return SubgameSpec(); + + std::string gamemod_path = game_path + DIR_DELIM + "mods"; + + // Find mod directories + std::unordered_map<std::string, std::string> mods_paths; + mods_paths["mods"] = user + DIR_DELIM + "mods"; + if (!user_game && user != share) + mods_paths["share"] = share + DIR_DELIM + "mods"; + + for (const std::string &mod_path : getEnvModPaths()) { + mods_paths[fs::AbsolutePath(mod_path)] = mod_path; + } + + // Get meta + std::string conf_path = game_path + DIR_DELIM + "game.conf"; + Settings conf; + conf.readConfigFile(conf_path.c_str()); + + std::string game_title; + if (conf.exists("title")) + game_title = conf.get("title"); + else if (conf.exists("name")) + game_title = conf.get("name"); + else + game_title = id; + + std::string game_author; + if (conf.exists("author")) + game_author = conf.get("author"); + + int game_release = 0; + if (conf.exists("release")) + game_release = conf.getS32("release"); + + std::string menuicon_path; +#ifndef SERVER + menuicon_path = getImagePath( + game_path + DIR_DELIM + "menu" + DIR_DELIM + "icon.png"); +#endif + + SubgameSpec spec(id, game_path, gamemod_path, mods_paths, game_title, + menuicon_path, game_author, game_release); + + if (conf.exists("name") && !conf.exists("title")) + spec.deprecation_msgs.push_back("\"name\" setting in game.conf is deprecated, please use \"title\" instead"); + + return spec; +} + +SubgameSpec findWorldSubgame(const std::string &world_path) +{ + std::string world_gameid = getWorldGameId(world_path, true); + // See if world contains an embedded game; if so, use it. + std::string world_gamepath = world_path + DIR_DELIM + "game"; + if (fs::PathExists(world_gamepath)) { + SubgameSpec gamespec; + gamespec.id = world_gameid; + gamespec.path = world_gamepath; + gamespec.gamemods_path = world_gamepath + DIR_DELIM + "mods"; + + Settings conf; + std::string conf_path = world_gamepath + DIR_DELIM + "game.conf"; + conf.readConfigFile(conf_path.c_str()); + + if (conf.exists("title")) + gamespec.title = conf.get("title"); + else if (conf.exists("name")) + gamespec.title = conf.get("name"); + else + gamespec.title = world_gameid; + + return gamespec; + } + return findSubgame(world_gameid); +} + +std::set<std::string> getAvailableGameIds() +{ + std::set<std::string> gameids; + std::set<std::string> gamespaths; + gamespaths.insert(porting::path_share + DIR_DELIM + "games"); + gamespaths.insert(porting::path_user + DIR_DELIM + "games"); + + Strfnd search_paths(getSubgamePathEnv()); + + while (!search_paths.at_end()) + gamespaths.insert(search_paths.next(PATH_DELIM)); + + for (const std::string &gamespath : gamespaths) { + std::vector<fs::DirListNode> dirlist = fs::GetDirListing(gamespath); + for (const fs::DirListNode &dln : dirlist) { + if (!dln.dir) + continue; + + // If configuration file is not found or broken, ignore game + Settings conf; + std::string conf_path = gamespath + DIR_DELIM + dln.name + + DIR_DELIM + "game.conf"; + if (!conf.readConfigFile(conf_path.c_str())) + continue; + + // Add it to result + const char *ends[] = {"_game", NULL}; + std::string shorter = removeStringEnd(dln.name, ends); + if (!shorter.empty()) + gameids.insert(shorter); + else + gameids.insert(dln.name); + } + } + return gameids; +} + +std::vector<SubgameSpec> getAvailableGames() +{ + std::vector<SubgameSpec> specs; + std::set<std::string> gameids = getAvailableGameIds(); + specs.reserve(gameids.size()); + for (const auto &gameid : gameids) + specs.push_back(findSubgame(gameid)); + return specs; +} + +#define LEGACY_GAMEID "minetest" + +bool getWorldExists(const std::string &world_path) +{ + return (fs::PathExists(world_path + DIR_DELIM + "map_meta.txt") || + fs::PathExists(world_path + DIR_DELIM + "world.mt")); +} + +//! Try to get the displayed name of a world +std::string getWorldName(const std::string &world_path, const std::string &default_name) +{ + std::string conf_path = world_path + DIR_DELIM + "world.mt"; + Settings conf; + bool succeeded = conf.readConfigFile(conf_path.c_str()); + if (!succeeded) { + return default_name; + } + + if (!conf.exists("world_name")) + return default_name; + return conf.get("world_name"); +} + +std::string getWorldGameId(const std::string &world_path, bool can_be_legacy) +{ + std::string conf_path = world_path + DIR_DELIM + "world.mt"; + Settings conf; + bool succeeded = conf.readConfigFile(conf_path.c_str()); + if (!succeeded) { + if (can_be_legacy) { + // If map_meta.txt exists, it is probably an old minetest world + if (fs::PathExists(world_path + DIR_DELIM + "map_meta.txt")) + return LEGACY_GAMEID; + } + return ""; + } + if (!conf.exists("gameid")) + return ""; + // The "mesetint" gameid has been discarded + if (conf.get("gameid") == "mesetint") + return "minetest"; + return conf.get("gameid"); +} + +std::string getWorldPathEnv() +{ + char *world_path = getenv("MINETEST_WORLD_PATH"); + return world_path ? std::string(world_path) : ""; +} + +std::vector<WorldSpec> getAvailableWorlds() +{ + std::vector<WorldSpec> worlds; + std::set<std::string> worldspaths; + + Strfnd search_paths(getWorldPathEnv()); + + while (!search_paths.at_end()) + worldspaths.insert(search_paths.next(PATH_DELIM)); + + worldspaths.insert(porting::path_user + DIR_DELIM + "worlds"); + infostream << "Searching worlds..." << std::endl; + for (const std::string &worldspath : worldspaths) { + infostream << " In " << worldspath << ": "; + std::vector<fs::DirListNode> dirvector = fs::GetDirListing(worldspath); + for (const fs::DirListNode &dln : dirvector) { + if (!dln.dir) + continue; + std::string fullpath = worldspath + DIR_DELIM + dln.name; + std::string name = getWorldName(fullpath, dln.name); + // Just allow filling in the gameid always for now + bool can_be_legacy = true; + std::string gameid = getWorldGameId(fullpath, can_be_legacy); + WorldSpec spec(fullpath, name, gameid); + if (!spec.isValid()) { + infostream << "(invalid: " << name << ") "; + } else { + infostream << name << " "; + worlds.push_back(spec); + } + } + infostream << std::endl; + } + // Check old world location + do { + std::string fullpath = porting::path_user + DIR_DELIM + "world"; + if (!fs::PathExists(fullpath)) + break; + std::string name = "Old World"; + std::string gameid = getWorldGameId(fullpath, true); + WorldSpec spec(fullpath, name, gameid); + infostream << "Old world found." << std::endl; + worlds.push_back(spec); + } while (false); + infostream << worlds.size() << " found." << std::endl; + return worlds; +} + +void loadGameConfAndInitWorld(const std::string &path, const std::string &name, + const SubgameSpec &gamespec, bool create_world) +{ + std::string final_path = path; + + // If we're creating a new world, ensure that the path isn't already taken + if (create_world) { + int counter = 1; + while (fs::PathExists(final_path) && counter < MAX_WORLD_NAMES) { + final_path = path + "_" + std::to_string(counter); + counter++; + } + + if (fs::PathExists(final_path)) { + throw BaseException("Too many similar filenames"); + } + } + + Settings *game_settings = Settings::getLayer(SL_GAME); + const bool new_game_settings = (game_settings == nullptr); + if (new_game_settings) { + // Called by main-menu without a Server instance running + // -> create and free manually + game_settings = Settings::createLayer(SL_GAME); + } + + getGameMinetestConfig(gamespec.path, *game_settings); + game_settings->removeSecureSettings(); + + infostream << "Initializing world at " << final_path << std::endl; + + fs::CreateAllDirs(final_path); + + // Create world.mt if does not already exist + std::string worldmt_path = final_path + DIR_DELIM "world.mt"; + if (!fs::PathExists(worldmt_path)) { + Settings conf; + + conf.set("world_name", name); + conf.set("gameid", gamespec.id); + conf.set("backend", "sqlite3"); + conf.set("player_backend", "sqlite3"); + conf.set("auth_backend", "sqlite3"); + conf.set("mod_storage_backend", "sqlite3"); + conf.setBool("creative_mode", g_settings->getBool("creative_mode")); + conf.setBool("enable_damage", g_settings->getBool("enable_damage")); + + if (!conf.updateConfigFile(worldmt_path.c_str())) { + throw BaseException("Failed to update the config file"); + } + } + + // Create map_meta.txt if does not already exist + std::string map_meta_path = final_path + DIR_DELIM + "map_meta.txt"; + if (!fs::PathExists(map_meta_path)) { + MapSettingsManager mgr(map_meta_path); + + mgr.setMapSetting("seed", g_settings->get("fixed_map_seed")); + + mgr.makeMapgenParams(); + mgr.saveMapMeta(); + } + + // The Settings object is no longer needed for created worlds + if (new_game_settings) + delete game_settings; +} + +std::vector<std::string> getEnvModPaths() +{ + const char *c_mod_path = getenv("MINETEST_MOD_PATH"); + std::vector<std::string> paths; + Strfnd search_paths(c_mod_path ? c_mod_path : ""); + while (!search_paths.at_end()) + paths.push_back(search_paths.next(PATH_DELIM)); + return paths; +} diff --git a/src/content/subgames.h b/src/content/subgames.h new file mode 100644 index 0000000..d5d1682 --- /dev/null +++ b/src/content/subgames.h @@ -0,0 +1,101 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <set> +#include <unordered_map> +#include <vector> + +class Settings; + +struct SubgameSpec +{ + std::string id; + std::string title; + std::string author; + int release; + std::string path; + std::string gamemods_path; + + /** + * Map from virtual path to mods path + */ + std::unordered_map<std::string, std::string> addon_mods_paths; + std::string menuicon_path; + + // For logging purposes + std::vector<const char *> deprecation_msgs; + + SubgameSpec(const std::string &id = "", const std::string &path = "", + const std::string &gamemods_path = "", + const std::unordered_map<std::string, std::string> &addon_mods_paths = {}, + const std::string &title = "", + const std::string &menuicon_path = "", + const std::string &author = "", int release = 0) : + id(id), + title(title), author(author), release(release), path(path), + gamemods_path(gamemods_path), addon_mods_paths(addon_mods_paths), + menuicon_path(menuicon_path) + { + } + + bool isValid() const { return (!id.empty() && !path.empty()); } + void checkAndLog() const; +}; + +SubgameSpec findSubgame(const std::string &id); +SubgameSpec findWorldSubgame(const std::string &world_path); + +std::set<std::string> getAvailableGameIds(); +std::vector<SubgameSpec> getAvailableGames(); +// Get the list of paths to mods in the environment variable $MINETEST_MOD_PATH +std::vector<std::string> getEnvModPaths(); + +bool getWorldExists(const std::string &world_path); +//! Try to get the displayed name of a world +std::string getWorldName(const std::string &world_path, const std::string &default_name); +std::string getWorldGameId(const std::string &world_path, bool can_be_legacy = false); + +struct WorldSpec +{ + std::string path; + std::string name; + std::string gameid; + + WorldSpec(const std::string &path = "", const std::string &name = "", + const std::string &gameid = "") : + path(path), + name(name), gameid(gameid) + { + } + + bool isValid() const + { + return (!name.empty() && !path.empty() && !gameid.empty()); + } +}; + +std::vector<WorldSpec> getAvailableWorlds(); + +// loads the subgame's config and creates world directory +// and world.mt if they don't exist +void loadGameConfAndInitWorld(const std::string &path, const std::string &name, + const SubgameSpec &gamespec, bool create_world); diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp new file mode 100644 index 0000000..6da5f45 --- /dev/null +++ b/src/content_mapnode.cpp @@ -0,0 +1,167 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "content_mapnode.h" + +#include "irrlichttypes_bloated.h" +#include "mapnode.h" +#include "nodedef.h" +#include "nameidmapping.h" +#include "util/string.h" + +/* + Legacy node content type IDs + Ranges: + 0x000...0x07f (0...127): param2 is fully usable + 126 and 127 are reserved (CONTENT_AIR and CONTENT_IGNORE). + 0x800...0xfff (2048...4095): higher 4 bits of param2 are not usable +*/ +#define CONTENT_STONE 0 +#define CONTENT_WATER 2 +#define CONTENT_TORCH 3 +#define CONTENT_WATERSOURCE 9 +#define CONTENT_SIGN_WALL 14 +#define CONTENT_CHEST 15 +#define CONTENT_FURNACE 16 +#define CONTENT_LOCKABLE_CHEST 17 +#define CONTENT_FENCE 21 +#define CONTENT_RAIL 30 +#define CONTENT_LADDER 31 +#define CONTENT_LAVA 32 +#define CONTENT_LAVASOURCE 33 +#define CONTENT_GRASS 0x800 //1 +#define CONTENT_TREE 0x801 //4 +#define CONTENT_LEAVES 0x802 //5 +#define CONTENT_GRASS_FOOTSTEPS 0x803 //6 +#define CONTENT_MESE 0x804 //7 +#define CONTENT_MUD 0x805 //8 +#define CONTENT_CLOUD 0x806 //10 +#define CONTENT_COALSTONE 0x807 //11 +#define CONTENT_WOOD 0x808 //12 +#define CONTENT_SAND 0x809 //13 +#define CONTENT_COBBLE 0x80a //18 +#define CONTENT_STEEL 0x80b //19 +#define CONTENT_GLASS 0x80c //20 +#define CONTENT_MOSSYCOBBLE 0x80d //22 +#define CONTENT_GRAVEL 0x80e //23 +#define CONTENT_SANDSTONE 0x80f //24 +#define CONTENT_CACTUS 0x810 //25 +#define CONTENT_BRICK 0x811 //26 +#define CONTENT_CLAY 0x812 //27 +#define CONTENT_PAPYRUS 0x813 //28 +#define CONTENT_BOOKSHELF 0x814 //29 +#define CONTENT_JUNGLETREE 0x815 +#define CONTENT_JUNGLEGRASS 0x816 +#define CONTENT_NC 0x817 +#define CONTENT_NC_RB 0x818 +#define CONTENT_APPLE 0x819 +#define CONTENT_SAPLING 0x820 + +/* + A conversion table for backwards compatibility. + Maps <=v19 content types to current ones. + Should never be touched. +*/ +content_t trans_table_19[21][2] = { + {CONTENT_GRASS, 1}, + {CONTENT_TREE, 4}, + {CONTENT_LEAVES, 5}, + {CONTENT_GRASS_FOOTSTEPS, 6}, + {CONTENT_MESE, 7}, + {CONTENT_MUD, 8}, + {CONTENT_CLOUD, 10}, + {CONTENT_COALSTONE, 11}, + {CONTENT_WOOD, 12}, + {CONTENT_SAND, 13}, + {CONTENT_COBBLE, 18}, + {CONTENT_STEEL, 19}, + {CONTENT_GLASS, 20}, + {CONTENT_MOSSYCOBBLE, 22}, + {CONTENT_GRAVEL, 23}, + {CONTENT_SANDSTONE, 24}, + {CONTENT_CACTUS, 25}, + {CONTENT_BRICK, 26}, + {CONTENT_CLAY, 27}, + {CONTENT_PAPYRUS, 28}, + {CONTENT_BOOKSHELF, 29}, +}; + +MapNode mapnode_translate_to_internal(MapNode n_from, u8 version) +{ + MapNode result = n_from; + if(version <= 19) + { + content_t c_from = n_from.getContent(); + for (const auto &tt_i : trans_table_19) { + if (tt_i[1] == c_from) { + result.setContent(tt_i[0]); + break; + } + } + } + return result; +} + +void content_mapnode_get_name_id_mapping(NameIdMapping *nimap) +{ + nimap->set(0, "default:stone"); + nimap->set(2, "default:water_flowing"); + nimap->set(3, "default:torch"); + nimap->set(9, "default:water_source"); + nimap->set(14, "default:sign_wall"); + nimap->set(15, "default:chest"); + nimap->set(16, "default:furnace"); + nimap->set(17, "default:chest_locked"); + nimap->set(21, "default:fence_wood"); + nimap->set(30, "default:rail"); + nimap->set(31, "default:ladder"); + nimap->set(32, "default:lava_flowing"); + nimap->set(33, "default:lava_source"); + nimap->set(0x800, "default:dirt_with_grass"); + nimap->set(0x801, "default:tree"); + nimap->set(0x802, "default:leaves"); + nimap->set(0x803, "default:dirt_with_grass_footsteps"); + nimap->set(0x804, "default:mese"); + nimap->set(0x805, "default:dirt"); + nimap->set(0x806, "default:cloud"); + nimap->set(0x807, "default:coalstone"); + nimap->set(0x808, "default:wood"); + nimap->set(0x809, "default:sand"); + nimap->set(0x80a, "default:cobble"); + nimap->set(0x80b, "default:steelblock"); + nimap->set(0x80c, "default:glass"); + nimap->set(0x80d, "default:mossycobble"); + nimap->set(0x80e, "default:gravel"); + nimap->set(0x80f, "default:sandstone"); + nimap->set(0x810, "default:cactus"); + nimap->set(0x811, "default:brick"); + nimap->set(0x812, "default:clay"); + nimap->set(0x813, "default:papyrus"); + nimap->set(0x814, "default:bookshelf"); + nimap->set(0x815, "default:jungletree"); + nimap->set(0x816, "default:junglegrass"); + nimap->set(0x817, "default:nyancat"); + nimap->set(0x818, "default:nyancat_rainbow"); + nimap->set(0x819, "default:apple"); + nimap->set(0x820, "default:sapling"); + // Static types + nimap->set(CONTENT_IGNORE, "ignore"); + nimap->set(CONTENT_AIR, "air"); +} + diff --git a/src/content_mapnode.h b/src/content_mapnode.h new file mode 100644 index 0000000..76c3f6c --- /dev/null +++ b/src/content_mapnode.h @@ -0,0 +1,34 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "mapnode.h" + +/* + Legacy node definitions +*/ + +// Backwards compatibility for non-extended content types in v19 +extern content_t trans_table_19[21][2]; +MapNode mapnode_translate_to_internal(MapNode n_from, u8 version); + +// Get legacy node name mapping for loading old blocks +class NameIdMapping; +void content_mapnode_get_name_id_mapping(NameIdMapping *nimap); diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp new file mode 100644 index 0000000..39743c1 --- /dev/null +++ b/src/content_nodemeta.cpp @@ -0,0 +1,191 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "content_nodemeta.h" +#include "nodemetadata.h" +#include "nodetimer.h" +#include "inventory.h" +#include "log.h" +#include "serialization.h" +#include "util/serialize.h" +#include "util/string.h" +#include "constants.h" // MAP_BLOCKSIZE +#include <sstream> + +#define NODEMETA_GENERIC 1 +#define NODEMETA_SIGN 14 +#define NODEMETA_CHEST 15 +#define NODEMETA_FURNACE 16 +#define NODEMETA_LOCKABLE_CHEST 17 + +// Returns true if node timer must be set +static bool content_nodemeta_deserialize_legacy_body( + std::istream &is, s16 id, NodeMetadata *meta) +{ + meta->clear(); + + if(id == NODEMETA_GENERIC) // GenericNodeMetadata (0.4-dev) + { + meta->getInventory()->deSerialize(is); + deSerializeString32(is); // m_text + deSerializeString16(is); // m_owner + + meta->setString("infotext",deSerializeString16(is)); + meta->setString("formspec",deSerializeString16(is)); + readU8(is); // m_allow_text_input + readU8(is); // m_allow_removal + readU8(is); // m_enforce_owner + + int num_vars = readU32(is); + for(int i=0; i<num_vars; i++){ + std::string name = deSerializeString16(is); + std::string var = deSerializeString32(is); + meta->setString(name, var); + } + return false; + } + else if(id == NODEMETA_SIGN) // SignNodeMetadata + { + meta->setString("text", deSerializeString16(is)); + //meta->setString("infotext","\"${text}\""); + meta->setString("infotext", + std::string("\"") + meta->getString("text") + "\""); + meta->setString("formspec","field[text;;${text}]"); + return false; + } + else if(id == NODEMETA_CHEST) // ChestNodeMetadata + { + meta->getInventory()->deSerialize(is); + + // Rename inventory list "0" to "main" + Inventory *inv = meta->getInventory(); + if(!inv->getList("main") && inv->getList("0")){ + inv->getList("0")->setName("main"); + } + assert(inv->getList("main") && !inv->getList("0")); + + meta->setString("formspec","size[8,9]" + "list[current_name;main;0,0;8,4;]" + "list[current_player;main;0,5;8,4;]"); + return false; + } + else if(id == NODEMETA_LOCKABLE_CHEST) // LockingChestNodeMetadata + { + meta->setString("owner", deSerializeString16(is)); + meta->getInventory()->deSerialize(is); + + // Rename inventory list "0" to "main" + Inventory *inv = meta->getInventory(); + if(!inv->getList("main") && inv->getList("0")){ + inv->getList("0")->setName("main"); + } + assert(inv->getList("main") && !inv->getList("0")); + + meta->setString("formspec","size[8,9]" + "list[current_name;main;0,0;8,4;]" + "list[current_player;main;0,5;8,4;]"); + return false; + } + else if(id == NODEMETA_FURNACE) // FurnaceNodeMetadata + { + meta->getInventory()->deSerialize(is); + int temp = 0; + is>>temp; + meta->setString("fuel_totaltime", ftos((float)temp/10)); + temp = 0; + is>>temp; + meta->setString("fuel_time", ftos((float)temp/10)); + temp = 0; + is>>temp; + //meta->setString("src_totaltime", ftos((float)temp/10)); + temp = 0; + is>>temp; + meta->setString("src_time", ftos((float)temp/10)); + + meta->setString("formspec","size[8,9]" + "list[current_name;fuel;2,3;1,1;]" + "list[current_name;src;2,1;1,1;]" + "list[current_name;dst;5,1;2,2;]" + "list[current_player;main;0,5;8,4;]"); + return true; + } + else + { + throw SerializationError("Unknown legacy node metadata"); + } +} + +static bool content_nodemeta_deserialize_legacy_meta( + std::istream &is, NodeMetadata *meta) +{ + // Read id + s16 id = readS16(is); + + // Read data + std::string data = deSerializeString16(is); + std::istringstream tmp_is(data, std::ios::binary); + return content_nodemeta_deserialize_legacy_body(tmp_is, id, meta); +} + +void content_nodemeta_deserialize_legacy(std::istream &is, + NodeMetadataList *meta, NodeTimerList *timers, + IItemDefManager *item_def_mgr) +{ + meta->clear(); + timers->clear(); + + u16 version = readU16(is); + + if(version > 1) + { + infostream<<FUNCTION_NAME<<": version "<<version<<" not supported" + <<std::endl; + throw SerializationError(FUNCTION_NAME); + } + + u16 count = readU16(is); + + for(u16 i=0; i<count; i++) + { + u16 p16 = readU16(is); + + v3s16 p(0,0,0); + p.Z += p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE; + p16 -= p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE; + p.Y += p16 / MAP_BLOCKSIZE; + p16 -= p.Y * MAP_BLOCKSIZE; + p.X += p16; + + if(meta->get(p) != NULL) + { + warningstream<<FUNCTION_NAME<<": " + <<"already set data at position" + <<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring." + <<std::endl; + continue; + } + + NodeMetadata *data = new NodeMetadata(item_def_mgr); + bool need_timer = content_nodemeta_deserialize_legacy_meta(is, data); + meta->set(p, data); + + if(need_timer) + timers->set(NodeTimer(1., 0., p)); + } +} diff --git a/src/content_nodemeta.h b/src/content_nodemeta.h new file mode 100644 index 0000000..b853274 --- /dev/null +++ b/src/content_nodemeta.h @@ -0,0 +1,34 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <iostream> + +class NodeMetadataList; +class NodeTimerList; +class IItemDefManager; + +/* + Legacy nodemeta definitions +*/ + +void content_nodemeta_deserialize_legacy(std::istream &is, + NodeMetadataList *meta, NodeTimerList *timers, + IItemDefManager *item_def_mgr); diff --git a/src/convert_json.cpp b/src/convert_json.cpp new file mode 100644 index 0000000..686113f --- /dev/null +++ b/src/convert_json.cpp @@ -0,0 +1,39 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <iostream> +#include <sstream> +#include <memory> + +#include "convert_json.h" + +void fastWriteJson(const Json::Value &value, std::ostream &to) +{ + Json::StreamWriterBuilder builder; + builder["indentation"] = ""; + std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter()); + writer->write(value, &to); +} + +std::string fastWriteJson(const Json::Value &value) +{ + std::ostringstream oss; + fastWriteJson(value, oss); + return oss.str(); +} diff --git a/src/convert_json.h b/src/convert_json.h new file mode 100644 index 0000000..d1d487e --- /dev/null +++ b/src/convert_json.h @@ -0,0 +1,27 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <json/json.h> +#include <ostream> + +void fastWriteJson(const Json::Value &value, std::ostream &to); + +std::string fastWriteJson(const Json::Value &value); diff --git a/src/craftdef.cpp b/src/craftdef.cpp new file mode 100644 index 0000000..053e73b --- /dev/null +++ b/src/craftdef.cpp @@ -0,0 +1,1124 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "craftdef.h" + +#include "irrlichttypes.h" +#include "log.h" +#include <sstream> +#include <unordered_set> +#include <algorithm> +#include "gamedef.h" +#include "inventory.h" +#include "util/serialize.h" +#include "util/string.h" +#include "util/numeric.h" +#include "util/strfnd.h" +#include "exceptions.h" + +inline bool isGroupRecipeStr(const std::string &rec_name) +{ + return str_starts_with(rec_name, std::string("group:")); +} + +static bool hasGroupItem(const std::vector<std::string> &recipe) +{ + for (const auto &item : recipe) { + if (isGroupRecipeStr(item)) + return true; + } + return false; +} + +inline u64 getHashForString(const std::string &recipe_str) +{ + /*errorstream << "Hashing craft string \"" << recipe_str << '"';*/ + return murmur_hash_64_ua(recipe_str.data(), recipe_str.length(), 0xdeadbeef); +} + +static u64 getHashForGrid(CraftHashType type, const std::vector<std::string> &grid_names) +{ + switch (type) { + case CRAFT_HASH_TYPE_ITEM_NAMES: { + std::ostringstream os; + bool is_first = true; + for (const std::string &grid_name : grid_names) { + if (!grid_name.empty()) { + os << (is_first ? "" : "\n") << grid_name; + is_first = false; + } + } + return getHashForString(os.str()); + } case CRAFT_HASH_TYPE_COUNT: { + u64 cnt = 0; + for (const std::string &grid_name : grid_names) + if (!grid_name.empty()) + cnt++; + return cnt; + } case CRAFT_HASH_TYPE_UNHASHED: + return 0; + } + // invalid CraftHashType + assert(false); + return 0; +} + +// Check if input matches recipe +// Takes recipe groups into account +static bool inputItemMatchesRecipe(const std::string &inp_name, + const std::string &rec_name, IItemDefManager *idef) +{ + // Exact name + if (inp_name == rec_name) + return true; + + // Group + if (isGroupRecipeStr(rec_name) && idef->isKnown(inp_name)) { + const struct ItemDefinition &def = idef->get(inp_name); + Strfnd f(rec_name.substr(6)); + bool all_groups_match = true; + do { + std::string check_group = f.next(","); + if (itemgroup_get(def.groups, check_group) == 0) { + all_groups_match = false; + break; + } + } while (!f.at_end()); + if (all_groups_match) + return true; + } + + // Didn't match + return false; +} + +// Deserialize an itemstring then return the name of the item +static std::string craftGetItemName(const std::string &itemstring, IGameDef *gamedef) +{ + ItemStack item; + item.deSerialize(itemstring, gamedef->idef()); + return item.name; +} + +// (mapcar craftGetItemName itemstrings) +static std::vector<std::string> craftGetItemNames( + const std::vector<std::string> &itemstrings, IGameDef *gamedef) +{ + std::vector<std::string> result; + result.reserve(itemstrings.size()); + for (const auto &itemstring : itemstrings) { + result.push_back(craftGetItemName(itemstring, gamedef)); + } + return result; +} + +// Get name of each item, and return them as a new list. +static std::vector<std::string> craftGetItemNames( + const std::vector<ItemStack> &items, IGameDef *gamedef) +{ + std::vector<std::string> result; + result.reserve(items.size()); + for (const auto &item : items) { + result.push_back(item.name); + } + return result; +} + +// convert a list of item names, to ItemStacks. +static std::vector<ItemStack> craftGetItems( + const std::vector<std::string> &items, IGameDef *gamedef) +{ + std::vector<ItemStack> result; + result.reserve(items.size()); + for (const auto &item : items) { + result.emplace_back(std::string(item), (u16)1, + (u16)0, gamedef->getItemDefManager()); + } + return result; +} + +// Compute bounding rectangle given a matrix of items +// Returns false if every item is "" +static bool craftGetBounds(const std::vector<std::string> &items, unsigned int width, + unsigned int &min_x, unsigned int &max_x, + unsigned int &min_y, unsigned int &max_y) +{ + bool success = false; + unsigned int x = 0; + unsigned int y = 0; + for (const std::string &item : items) { + // Is this an actual item? + if (!item.empty()) { + if (!success) { + // This is the first nonempty item + min_x = max_x = x; + min_y = max_y = y; + success = true; + } else { + if (x < min_x) min_x = x; + if (x > max_x) max_x = x; + if (y < min_y) min_y = y; + if (y > max_y) max_y = y; + } + } + + // Step coordinate + x++; + if (x == width) { + x = 0; + y++; + } + } + return success; +} + +// Removes 1 from each item stack +static void craftDecrementInput(CraftInput &input, IGameDef *gamedef) +{ + for (auto &item : input.items) { + if (item.count != 0) + item.remove(1); + } +} + +// Removes 1 from each item stack with replacement support +// Example: if replacements contains the pair ("bucket:bucket_water", "bucket:bucket_empty"), +// a water bucket will not be removed but replaced by an empty bucket. +static void craftDecrementOrReplaceInput(CraftInput &input, + std::vector<ItemStack> &output_replacements, + const CraftReplacements &replacements, + IGameDef *gamedef) +{ + if (replacements.pairs.empty()) { + craftDecrementInput(input, gamedef); + return; + } + + // Make a copy of the replacements pair list + std::vector<std::pair<std::string, std::string> > pairs = replacements.pairs; + + for (auto &item : input.items) { + // Find an appropriate replacement + bool found_replacement = false; + for (auto j = pairs.begin(); j != pairs.end(); ++j) { + if (inputItemMatchesRecipe(item.name, j->first, gamedef->idef())) { + if (item.count == 1) { + item.deSerialize(j->second, gamedef->idef()); + found_replacement = true; + pairs.erase(j); + break; + } + + ItemStack rep; + rep.deSerialize(j->second, gamedef->idef()); + item.remove(1); + found_replacement = true; + output_replacements.push_back(rep); + break; + + } + } + // No replacement was found, simply decrement count by one + if (!found_replacement && item.count > 0) + item.remove(1); + } +} + +// Dump an itemstring matrix +static std::string craftDumpMatrix(const std::vector<std::string> &items, + unsigned int width) +{ + std::ostringstream os(std::ios::binary); + os << "{ "; + unsigned int x = 0; + for(std::vector<std::string>::size_type i = 0; + i < items.size(); i++, x++) { + if (x == width) { + os << "; "; + x = 0; + } else if (x != 0) { + os << ","; + } + os << '"' << items[i] << '"'; + } + os << " }"; + return os.str(); +} + +// Dump an item matrix +std::string craftDumpMatrix(const std::vector<ItemStack> &items, + unsigned int width) +{ + std::ostringstream os(std::ios::binary); + os << "{ "; + unsigned int x = 0; + for (std::vector<ItemStack>::size_type i = 0; + i < items.size(); i++, x++) { + if (x == width) { + os << "; "; + x = 0; + } else if (x != 0) { + os << ","; + } + os << '"' << (items[i].getItemString()) << '"'; + } + os << " }"; + return os.str(); +} + + +/* + CraftInput +*/ + +bool CraftInput::empty() const +{ + for (const auto &item : items) { + if (!item.empty()) + return false; + } + return true; +} + +std::string CraftInput::dump() const +{ + std::ostringstream os(std::ios::binary); + os << "(method=" << ((int)method) << ", items=" + << craftDumpMatrix(items, width) << ")"; + return os.str(); +} + +/* + CraftOutput +*/ + +std::string CraftOutput::dump() const +{ + std::ostringstream os(std::ios::binary); + os << "(item=\"" << item << "\", time=" << time << ")"; + return os.str(); +} + +/* + CraftReplacements +*/ + +std::string CraftReplacements::dump() const +{ + std::ostringstream os(std::ios::binary); + os<<"{"; + const char *sep = ""; + for (const auto &repl_p : pairs) { + os << sep + << '"' << (repl_p.first) + << "\"=>\"" << (repl_p.second) << '"'; + sep = ","; + } + os << "}"; + return os.str(); +} + +/* + CraftDefinitionShaped +*/ + +CraftDefinitionShaped::CraftDefinitionShaped( + const std::string &output_, + unsigned int width_, + const std::vector<std::string> &recipe_, + const CraftReplacements &replacements_): + output(output_), width(width_), recipe(recipe_), replacements(replacements_) +{ + if (hasGroupItem(recipe)) + priority = PRIORITY_SHAPED_AND_GROUPS; + else + priority = PRIORITY_SHAPED; +} + +std::string CraftDefinitionShaped::getName() const +{ + return "shaped"; +} + +bool CraftDefinitionShaped::check(const CraftInput &input, IGameDef *gamedef) const +{ + if (input.method != CRAFT_METHOD_NORMAL) + return false; + + // Get input item matrix + std::vector<std::string> inp_names = craftGetItemNames(input.items, gamedef); + unsigned int inp_width = input.width; + if (inp_width == 0) + return false; + while (inp_names.size() % inp_width != 0) + inp_names.emplace_back(""); + + // Get input bounds + unsigned int inp_min_x = 0, inp_max_x = 0, inp_min_y = 0, inp_max_y = 0; + if (!craftGetBounds(inp_names, inp_width, inp_min_x, inp_max_x, + inp_min_y, inp_max_y)) + return false; // it was empty + + std::vector<std::string> rec_names; + if (hash_inited) + rec_names = recipe_names; + else + rec_names = craftGetItemNames(recipe, gamedef); + + // Get recipe item matrix + unsigned int rec_width = width; + if (rec_width == 0) + return false; + while (rec_names.size() % rec_width != 0) + rec_names.emplace_back(""); + + // Get recipe bounds + unsigned int rec_min_x=0, rec_max_x=0, rec_min_y=0, rec_max_y=0; + if (!craftGetBounds(rec_names, rec_width, rec_min_x, rec_max_x, + rec_min_y, rec_max_y)) + return false; // it was empty + + // Different sizes? + if (inp_max_x - inp_min_x != rec_max_x - rec_min_x || + inp_max_y - inp_min_y != rec_max_y - rec_min_y) + return false; + + // Verify that all item names in the bounding box are equal + unsigned int w = inp_max_x - inp_min_x + 1; + unsigned int h = inp_max_y - inp_min_y + 1; + + for (unsigned int y=0; y < h; y++) { + unsigned int inp_y = (inp_min_y + y) * inp_width; + unsigned int rec_y = (rec_min_y + y) * rec_width; + + for (unsigned int x=0; x < w; x++) { + unsigned int inp_x = inp_min_x + x; + unsigned int rec_x = rec_min_x + x; + + if (!inputItemMatchesRecipe( + inp_names[inp_y + inp_x], + rec_names[rec_y + rec_x], gamedef->idef())) { + return false; + } + } + } + + return true; +} + +CraftOutput CraftDefinitionShaped::getOutput(const CraftInput &input, IGameDef *gamedef) const +{ + return CraftOutput(output, 0); +} + +CraftInput CraftDefinitionShaped::getInput(const CraftOutput &output, IGameDef *gamedef) const +{ + return CraftInput(CRAFT_METHOD_NORMAL,width,craftGetItems(recipe,gamedef)); +} + +void CraftDefinitionShaped::decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements, + IGameDef *gamedef) const +{ + craftDecrementOrReplaceInput(input, output_replacements, replacements, gamedef); +} + +u64 CraftDefinitionShaped::getHash(CraftHashType type) const +{ + assert(hash_inited); // Pre-condition + assert((type == CRAFT_HASH_TYPE_ITEM_NAMES) + || (type == CRAFT_HASH_TYPE_COUNT)); // Pre-condition + + std::vector<std::string> rec_names = recipe_names; + std::sort(rec_names.begin(), rec_names.end()); + return getHashForGrid(type, rec_names); +} + +void CraftDefinitionShaped::initHash(IGameDef *gamedef) +{ + if (hash_inited) + return; + hash_inited = true; + recipe_names = craftGetItemNames(recipe, gamedef); + + if (hasGroupItem(recipe_names)) + hash_type = CRAFT_HASH_TYPE_COUNT; + else + hash_type = CRAFT_HASH_TYPE_ITEM_NAMES; +} + +std::string CraftDefinitionShaped::dump() const +{ + std::ostringstream os(std::ios::binary); + os << "(shaped, output=\"" << output + << "\", recipe=" << craftDumpMatrix(recipe, width) + << ", replacements=" << replacements.dump() << ")"; + return os.str(); +} + +/* + CraftDefinitionShapeless +*/ + +CraftDefinitionShapeless::CraftDefinitionShapeless( + const std::string &output_, + const std::vector<std::string> &recipe_, + const CraftReplacements &replacements_): + output(output_), recipe(recipe_), replacements(replacements_) +{ + if (hasGroupItem(recipe)) + priority = PRIORITY_SHAPELESS_AND_GROUPS; + else + priority = PRIORITY_SHAPELESS; +} + +std::string CraftDefinitionShapeless::getName() const +{ + return "shapeless"; +} + +bool CraftDefinitionShapeless::check(const CraftInput &input, IGameDef *gamedef) const +{ + if (input.method != CRAFT_METHOD_NORMAL) + return false; + + // Filter empty items out of input + std::vector<std::string> input_filtered; + for (const auto &item : input.items) { + if (!item.name.empty()) + input_filtered.push_back(item.name); + } + + // If there is a wrong number of items in input, no match + if (input_filtered.size() != recipe.size()) { + /*dstream<<"Number of input items ("<<input_filtered.size() + <<") does not match recipe size ("<<recipe.size()<<") " + <<"of recipe with output="<<output<<std::endl;*/ + return false; + } + + std::vector<std::string> recipe_copy; + if (hash_inited) + recipe_copy = recipe_names; + else { + recipe_copy = craftGetItemNames(recipe, gamedef); + std::sort(recipe_copy.begin(), recipe_copy.end()); + } + + // Try with all permutations of the recipe, + // start from the lexicographically first permutation (=sorted), + // recipe_names is pre-sorted + do { + // If all items match, the recipe matches + bool all_match = true; + //dstream<<"Testing recipe (output="<<output<<"):"; + for (size_t i=0; i<recipe.size(); i++) { + //dstream<<" ("<<input_filtered[i]<<" == "<<recipe_copy[i]<<")"; + if (!inputItemMatchesRecipe(input_filtered[i], recipe_copy[i], + gamedef->idef())) { + all_match = false; + break; + } + } + //dstream<<" -> match="<<all_match<<std::endl; + if (all_match) + return true; + } while (std::next_permutation(recipe_copy.begin(), recipe_copy.end())); + + return false; +} + +CraftOutput CraftDefinitionShapeless::getOutput(const CraftInput &input, IGameDef *gamedef) const +{ + return CraftOutput(output, 0); +} + +CraftInput CraftDefinitionShapeless::getInput(const CraftOutput &output, IGameDef *gamedef) const +{ + return CraftInput(CRAFT_METHOD_NORMAL, 0, craftGetItems(recipe, gamedef)); +} + +void CraftDefinitionShapeless::decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements, + IGameDef *gamedef) const +{ + craftDecrementOrReplaceInput(input, output_replacements, replacements, gamedef); +} + +u64 CraftDefinitionShapeless::getHash(CraftHashType type) const +{ + assert(hash_inited); // Pre-condition + assert(type == CRAFT_HASH_TYPE_ITEM_NAMES + || type == CRAFT_HASH_TYPE_COUNT); // Pre-condition + return getHashForGrid(type, recipe_names); +} + +void CraftDefinitionShapeless::initHash(IGameDef *gamedef) +{ + if (hash_inited) + return; + hash_inited = true; + recipe_names = craftGetItemNames(recipe, gamedef); + std::sort(recipe_names.begin(), recipe_names.end()); + + if (hasGroupItem(recipe_names)) + hash_type = CRAFT_HASH_TYPE_COUNT; + else + hash_type = CRAFT_HASH_TYPE_ITEM_NAMES; +} + +std::string CraftDefinitionShapeless::dump() const +{ + std::ostringstream os(std::ios::binary); + os << "(shapeless, output=\"" << output + << "\", recipe=" << craftDumpMatrix(recipe, recipe.size()) + << ", replacements=" << replacements.dump() << ")"; + return os.str(); +} + +/* + CraftDefinitionToolRepair +*/ + +CraftDefinitionToolRepair::CraftDefinitionToolRepair(float additional_wear_): + additional_wear(additional_wear_) +{ + priority = PRIORITY_TOOLREPAIR; +} + +static ItemStack craftToolRepair( + const ItemStack &item1, + const ItemStack &item2, + float additional_wear, + IGameDef *gamedef) +{ + IItemDefManager *idef = gamedef->idef(); + if (item1.count != 1 || item2.count != 1 || item1.name != item2.name + || idef->get(item1.name).type != ITEM_TOOL + || itemgroup_get(idef->get(item1.name).groups, "disable_repair") == 1) { + // Failure + return ItemStack(); + } + + s32 item1_uses = 65536 - (u32) item1.wear; + s32 item2_uses = 65536 - (u32) item2.wear; + s32 new_uses = item1_uses + item2_uses; + s32 new_wear = 65536 - new_uses + floor(additional_wear * 65536 + 0.5); + if (new_wear >= 65536) + return ItemStack(); + if (new_wear < 0) + new_wear = 0; + + ItemStack repaired = item1; + repaired.wear = new_wear; + return repaired; +} + +std::string CraftDefinitionToolRepair::getName() const +{ + return "toolrepair"; +} + +bool CraftDefinitionToolRepair::check(const CraftInput &input, IGameDef *gamedef) const +{ + if (input.method != CRAFT_METHOD_NORMAL) + return false; + + ItemStack item1; + ItemStack item2; + for (const auto &item : input.items) { + if (!item.empty()) { + if (item1.empty()) + item1 = item; + else if (item2.empty()) + item2 = item; + else + return false; + } + } + ItemStack repaired = craftToolRepair(item1, item2, additional_wear, gamedef); + return !repaired.empty(); +} + +CraftOutput CraftDefinitionToolRepair::getOutput(const CraftInput &input, IGameDef *gamedef) const +{ + ItemStack item1; + ItemStack item2; + for (const auto &item : input.items) { + if (!item.empty()) { + if (item1.empty()) + item1 = item; + else if (item2.empty()) + item2 = item; + } + } + ItemStack repaired = craftToolRepair(item1, item2, additional_wear, gamedef); + return CraftOutput(repaired.getItemString(), 0); +} + +CraftInput CraftDefinitionToolRepair::getInput(const CraftOutput &output, IGameDef *gamedef) const +{ + std::vector<ItemStack> stack; + stack.emplace_back(); + return CraftInput(CRAFT_METHOD_COOKING, additional_wear, stack); +} + +void CraftDefinitionToolRepair::decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements, + IGameDef *gamedef) const +{ + craftDecrementInput(input, gamedef); +} + +std::string CraftDefinitionToolRepair::dump() const +{ + std::ostringstream os(std::ios::binary); + os << "(toolrepair, additional_wear=" << additional_wear << ")"; + return os.str(); +} + +/* + CraftDefinitionCooking +*/ + +CraftDefinitionCooking::CraftDefinitionCooking( + const std::string &output_, + const std::string &recipe_, + float cooktime_, + const CraftReplacements &replacements_): + output(output_), recipe(recipe_), cooktime(cooktime_), replacements(replacements_) +{ + if (isGroupRecipeStr(recipe)) + priority = PRIORITY_SHAPELESS_AND_GROUPS; + else + priority = PRIORITY_SHAPELESS; +} + +std::string CraftDefinitionCooking::getName() const +{ + return "cooking"; +} + +bool CraftDefinitionCooking::check(const CraftInput &input, IGameDef *gamedef) const +{ + if (input.method != CRAFT_METHOD_COOKING) + return false; + + // Filter empty items out of input + std::vector<std::string> input_filtered; + for (const auto &item : input.items) { + const std::string &name = item.name; + if (!name.empty()) + input_filtered.push_back(name); + } + + // If there is a wrong number of items in input, no match + if (input_filtered.size() != 1) { + /*dstream<<"Number of input items ("<<input_filtered.size() + <<") does not match recipe size (1) " + <<"of cooking recipe with output="<<output<<std::endl;*/ + return false; + } + + // Check the single input item + std::string rec_name = craftGetItemName(recipe, gamedef); + return inputItemMatchesRecipe(input_filtered[0], rec_name, gamedef->idef()); +} + +CraftOutput CraftDefinitionCooking::getOutput(const CraftInput &input, IGameDef *gamedef) const +{ + return CraftOutput(output, cooktime); +} + +CraftInput CraftDefinitionCooking::getInput(const CraftOutput &output, IGameDef *gamedef) const +{ + std::vector<std::string> rec; + rec.push_back(recipe); + return CraftInput(CRAFT_METHOD_COOKING,cooktime,craftGetItems(rec,gamedef)); +} + +void CraftDefinitionCooking::decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements, + IGameDef *gamedef) const +{ + craftDecrementOrReplaceInput(input, output_replacements, replacements, gamedef); +} + +u64 CraftDefinitionCooking::getHash(CraftHashType type) const +{ + if (type == CRAFT_HASH_TYPE_ITEM_NAMES) { + return getHashForString(recipe_name); + } + + if (type == CRAFT_HASH_TYPE_COUNT) { + return 1; + } + + // illegal hash type for this CraftDefinition (pre-condition) + assert(false); + return 0; +} + +void CraftDefinitionCooking::initHash(IGameDef *gamedef) +{ + if (hash_inited) + return; + hash_inited = true; + recipe_name = craftGetItemName(recipe, gamedef); + + if (isGroupRecipeStr(recipe_name)) + hash_type = CRAFT_HASH_TYPE_COUNT; + else + hash_type = CRAFT_HASH_TYPE_ITEM_NAMES; +} + +std::string CraftDefinitionCooking::dump() const +{ + std::ostringstream os(std::ios::binary); + os << "(cooking, output=\"" << output + << "\", recipe=\"" << recipe + << "\", cooktime=" << cooktime << ")" + << ", replacements=" << replacements.dump() << ")"; + return os.str(); +} + +/* + CraftDefinitionFuel +*/ + +CraftDefinitionFuel::CraftDefinitionFuel( + const std::string &recipe_, + float burntime_, + const CraftReplacements &replacements_): + recipe(recipe_), burntime(burntime_), replacements(replacements_) +{ + if (isGroupRecipeStr(recipe_name)) + priority = PRIORITY_SHAPELESS_AND_GROUPS; + else + priority = PRIORITY_SHAPELESS; +} + +std::string CraftDefinitionFuel::getName() const +{ + return "fuel"; +} + +bool CraftDefinitionFuel::check(const CraftInput &input, IGameDef *gamedef) const +{ + if (input.method != CRAFT_METHOD_FUEL) + return false; + + // Filter empty items out of input + std::vector<std::string> input_filtered; + for (const auto &item : input.items) { + const std::string &name = item.name; + if (!name.empty()) + input_filtered.push_back(name); + } + + // If there is a wrong number of items in input, no match + if (input_filtered.size() != 1) { + /*dstream<<"Number of input items ("<<input_filtered.size() + <<") does not match recipe size (1) " + <<"of fuel recipe with burntime="<<burntime<<std::endl;*/ + return false; + } + + // Check the single input item + std::string rec_name = craftGetItemName(recipe, gamedef); + return inputItemMatchesRecipe(input_filtered[0], rec_name, gamedef->idef()); +} + +CraftOutput CraftDefinitionFuel::getOutput(const CraftInput &input, IGameDef *gamedef) const +{ + return CraftOutput("", burntime); +} + +CraftInput CraftDefinitionFuel::getInput(const CraftOutput &output, IGameDef *gamedef) const +{ + std::vector<std::string> rec; + rec.push_back(recipe); + return CraftInput(CRAFT_METHOD_COOKING,(int)burntime,craftGetItems(rec,gamedef)); +} + +void CraftDefinitionFuel::decrementInput(CraftInput &input, std::vector<ItemStack> &output_replacements, + IGameDef *gamedef) const +{ + craftDecrementOrReplaceInput(input, output_replacements, replacements, gamedef); +} + +u64 CraftDefinitionFuel::getHash(CraftHashType type) const +{ + if (type == CRAFT_HASH_TYPE_ITEM_NAMES) { + return getHashForString(recipe_name); + } + + if (type == CRAFT_HASH_TYPE_COUNT) { + return 1; + } + + // illegal hash type for this CraftDefinition (pre-condition) + assert(false); + return 0; +} + +void CraftDefinitionFuel::initHash(IGameDef *gamedef) +{ + if (hash_inited) + return; + hash_inited = true; + recipe_name = craftGetItemName(recipe, gamedef); + + if (isGroupRecipeStr(recipe_name)) + hash_type = CRAFT_HASH_TYPE_COUNT; + else + hash_type = CRAFT_HASH_TYPE_ITEM_NAMES; +} + +std::string CraftDefinitionFuel::dump() const +{ + std::ostringstream os(std::ios::binary); + os << "(fuel, recipe=\"" << recipe + << "\", burntime=" << burntime << ")" + << ", replacements=" << replacements.dump() << ")"; + return os.str(); +} + +/* + Craft definition manager +*/ + +class CCraftDefManager: public IWritableCraftDefManager +{ +public: + CCraftDefManager() + { + m_craft_defs.resize(craft_hash_type_max + 1); + } + + virtual ~CCraftDefManager() + { + clear(); + } + + virtual bool getCraftResult(CraftInput &input, CraftOutput &output, + std::vector<ItemStack> &output_replacement, bool decrementInput, + IGameDef *gamedef) const + { + if (input.empty()) + return false; + + std::vector<std::string> input_names; + input_names = craftGetItemNames(input.items, gamedef); + std::sort(input_names.begin(), input_names.end()); + + // Try hash types with increasing collision rate + // while remembering the latest, highest priority recipe. + CraftDefinition::RecipePriority priority_best = + CraftDefinition::PRIORITY_NO_RECIPE; + CraftDefinition *def_best = nullptr; + for (int type = 0; type <= craft_hash_type_max; type++) { + u64 hash = getHashForGrid((CraftHashType) type, input_names); + + /*errorstream << "Checking type " << type << " with hash " << hash << std::endl;*/ + + // We'd like to do "const [...] hash_collisions = m_craft_defs[type][hash];" + // but that doesn't compile for some reason. This does. + auto col_iter = (m_craft_defs[type]).find(hash); + + if (col_iter == (m_craft_defs[type]).end()) + continue; + + const std::vector<CraftDefinition*> &hash_collisions = col_iter->second; + // Walk crafting definitions from back to front, so that later + // definitions can override earlier ones. + for (std::vector<CraftDefinition*>::size_type + i = hash_collisions.size(); i > 0; i--) { + CraftDefinition *def = hash_collisions[i - 1]; + + /*errorstream << "Checking " << input.dump() << std::endl + << " against " << def->dump() << std::endl;*/ + + CraftDefinition::RecipePriority priority = def->getPriority(); + if (priority > priority_best + && def->check(input, gamedef)) { + // Check if the crafted node/item exists + CraftOutput out = def->getOutput(input, gamedef); + ItemStack is; + is.deSerialize(out.item, gamedef->idef()); + if (!is.isKnown(gamedef->idef())) { + infostream << "trying to craft non-existent " + << out.item << ", ignoring recipe" << std::endl; + continue; + } + + output = out; + priority_best = priority; + def_best = def; + } + } + } + if (priority_best == CraftDefinition::PRIORITY_NO_RECIPE) + return false; + if (decrementInput) + def_best->decrementInput(input, output_replacement, gamedef); + return true; + } + + virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output, + IGameDef *gamedef, unsigned limit=0) const + { + std::vector<CraftDefinition*> recipes; + + auto vec_iter = m_output_craft_definitions.find(output.item); + + if (vec_iter == m_output_craft_definitions.end()) + return recipes; + + const std::vector<CraftDefinition*> &vec = vec_iter->second; + + recipes.reserve(limit ? MYMIN(limit, vec.size()) : vec.size()); + + for (std::vector<CraftDefinition*>::size_type i = vec.size(); + i > 0; i--) { + CraftDefinition *def = vec[i - 1]; + if (limit && recipes.size() >= limit) + break; + recipes.push_back(def); + } + + return recipes; + } + + virtual bool clearCraftsByOutput(const CraftOutput &output, IGameDef *gamedef) + { + auto to_clear = m_output_craft_definitions.find(output.item); + + if (to_clear == m_output_craft_definitions.end()) + return false; + + for (auto def : to_clear->second) { + // Recipes are not yet hashed at this point + std::vector<CraftDefinition *> &defs = m_craft_defs[(int)CRAFT_HASH_TYPE_UNHASHED][0]; + defs.erase(std::remove(defs.begin(), defs.end(), def), defs.end()); + delete def; + } + m_output_craft_definitions.erase(to_clear); + return true; + } + + virtual bool clearCraftsByInput(const CraftInput &input, IGameDef *gamedef) + { + if (input.empty()) + return false; + + // Recipes are not yet hashed at this point + std::vector<CraftDefinition *> &defs = m_craft_defs[(int)CRAFT_HASH_TYPE_UNHASHED][0]; + std::unordered_set<const CraftDefinition *> defs_to_remove; + std::vector<CraftDefinition *> new_defs; + + for (auto def : defs) { + if (def->check(input, gamedef)) + defs_to_remove.insert(def); + else + new_defs.push_back(def); + } + + if (!defs_to_remove.empty()) { + for (auto def : defs_to_remove) + delete def; + + defs.swap(new_defs); + + for (auto &output : m_output_craft_definitions) { + std::vector<CraftDefinition *> &outdefs = output.second; + outdefs.erase(std::remove_if(outdefs.begin(), outdefs.end(), [&](const CraftDefinition* def) { + return defs_to_remove.find(def) != defs_to_remove.end(); + }), outdefs.end()); + } + } + + return !defs_to_remove.empty(); + } + + virtual std::string dump() const + { + std::ostringstream os(std::ios::binary); + os << "Crafting definitions:\n"; + for (int type = 0; type <= craft_hash_type_max; ++type) { + for (auto it = m_craft_defs[type].begin(); + it != m_craft_defs[type].end(); ++it) { + for (std::vector<CraftDefinition*>::size_type i = 0; + i < it->second.size(); i++) { + os << "type " << type + << " hash " << it->first + << " def " << it->second[i]->dump() + << "\n"; + } + } + } + return os.str(); + } + virtual void registerCraft(CraftDefinition *def, IGameDef *gamedef) + { + TRACESTREAM(<< "registerCraft: registering craft definition: " + << def->dump() << std::endl); + m_craft_defs[(int) CRAFT_HASH_TYPE_UNHASHED][0].push_back(def); + + CraftInput input; + std::string output_name = craftGetItemName( + def->getOutput(input, gamedef).item, gamedef); + m_output_craft_definitions[output_name].push_back(def); + } + virtual void clear() + { + for (int type = 0; type <= craft_hash_type_max; ++type) { + for (auto &it : m_craft_defs[type]) { + for (auto &iit : it.second) { + delete iit; + } + it.second.clear(); + } + m_craft_defs[type].clear(); + } + m_output_craft_definitions.clear(); + } + virtual void initHashes(IGameDef *gamedef) + { + // Move the CraftDefs from the unhashed layer into layers higher up. + std::vector<CraftDefinition *> &unhashed = + m_craft_defs[(int) CRAFT_HASH_TYPE_UNHASHED][0]; + for (auto def : unhashed) { + // Initialize and get the definition's hash + def->initHash(gamedef); + CraftHashType type = def->getHashType(); + u64 hash = def->getHash(type); + + // Enter the definition + m_craft_defs[type][hash].push_back(def); + } + unhashed.clear(); + } +private: + std::vector<std::unordered_map<u64, std::vector<CraftDefinition*> > > + m_craft_defs; + std::unordered_map<std::string, std::vector<CraftDefinition*> > + m_output_craft_definitions; +}; + +IWritableCraftDefManager* createCraftDefManager() +{ + return new CCraftDefManager(); +} diff --git a/src/craftdef.h b/src/craftdef.h new file mode 100644 index 0000000..7c14e70 --- /dev/null +++ b/src/craftdef.h @@ -0,0 +1,463 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <iostream> +#include <vector> +#include <utility> +#include "gamedef.h" +#include "inventory.h" + +/* + Crafting methods. + + The crafting method depends on the inventory list + that the crafting input comes from. +*/ +enum CraftMethod +{ + // Crafting grid + CRAFT_METHOD_NORMAL, + // Cooking something in a furnace + CRAFT_METHOD_COOKING, + // Using something as fuel for a furnace + CRAFT_METHOD_FUEL, +}; + +/* + The type a hash can be. The earlier a type is mentioned in this enum, + the earlier it is tried at crafting, and the less likely is a collision. + Changing order causes changes in behaviour, so know what you do. + */ +enum CraftHashType +{ + // Hashes the normalized names of the recipe's elements. + // Only recipes without group usage can be found here, + // because groups can't be guessed efficiently. + CRAFT_HASH_TYPE_ITEM_NAMES, + + // Counts the non-empty slots. + CRAFT_HASH_TYPE_COUNT, + + // This layer both spares an extra variable, and helps to retain (albeit rarely used) functionality. Maps to 0. + // Before hashes are "initialized", all hashes reside here, after initialisation, none are. + CRAFT_HASH_TYPE_UNHASHED + +}; +const int craft_hash_type_max = (int) CRAFT_HASH_TYPE_UNHASHED; + +/* + Input: The contents of the crafting slots, arranged in matrix form +*/ +struct CraftInput +{ + CraftMethod method = CRAFT_METHOD_NORMAL; + unsigned int width = 0; + std::vector<ItemStack> items; + + CraftInput() = default; + + CraftInput(CraftMethod method_, unsigned int width_, + const std::vector<ItemStack> &items_): + method(method_), width(width_), items(items_) + {} + + // Returns true if all items are empty. + bool empty() const; + + std::string dump() const; +}; + +/* + Output: Result of crafting operation +*/ +struct CraftOutput +{ + // Used for normal crafting and cooking, itemstring + std::string item = ""; + // Used for cooking (cook time) and fuel (burn time), seconds + float time = 0.0f; + + CraftOutput() = default; + + CraftOutput(const std::string &item_, float time_): + item(item_), time(time_) + {} + std::string dump() const; +}; + +/* + A list of replacements. A replacement indicates that a specific + input item should not be deleted (when crafting) but replaced with + a different item. Each replacements is a pair (itemstring to remove, + itemstring to replace with) + + Example: If ("bucket:bucket_water", "bucket:bucket_empty") is a + replacement pair, the crafting input slot that contained a water + bucket will contain an empty bucket after crafting. +*/ +struct CraftReplacements +{ + // List of replacements + std::vector<std::pair<std::string, std::string> > pairs; + + CraftReplacements() = default; + CraftReplacements(const std::vector<std::pair<std::string, std::string> > &pairs_): + pairs(pairs_) + {} + std::string dump() const; +}; + +/* + Crafting definition base class +*/ +class CraftDefinition +{ +public: + /* + Craft recipe priorities, from low to high + + Recipes are searched from latest to first. + If a recipe with higher priority than a previous found one is + encountered, it is selected instead. + */ + enum RecipePriority + { + PRIORITY_NO_RECIPE, + PRIORITY_TOOLREPAIR, + PRIORITY_SHAPELESS_AND_GROUPS, + PRIORITY_SHAPELESS, + PRIORITY_SHAPED_AND_GROUPS, + PRIORITY_SHAPED, + }; + + CraftDefinition() = default; + virtual ~CraftDefinition() = default; + + // Returns type of crafting definition + virtual std::string getName() const=0; + + // Checks whether the recipe is applicable + virtual bool check(const CraftInput &input, IGameDef *gamedef) const=0; + RecipePriority getPriority() const + { + return priority; + } + // Returns the output structure, meaning depends on crafting method + // The implementation can assume that check(input) returns true + virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const=0; + // the inverse of the above + virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const=0; + // Decreases count of every input item + virtual void decrementInput(CraftInput &input, + std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const=0; + + CraftHashType getHashType() const + { + return hash_type; + } + virtual u64 getHash(CraftHashType type) const = 0; + + // to be called after all mods are loaded, so that we catch all aliases + virtual void initHash(IGameDef *gamedef) = 0; + + virtual std::string dump() const=0; + +protected: + CraftHashType hash_type; + RecipePriority priority; +}; + +/* + A plain-jane (shaped) crafting definition + + Supported crafting method: CRAFT_METHOD_NORMAL. + Requires the input items to be arranged exactly like in the recipe. +*/ +class CraftDefinitionShaped: public CraftDefinition +{ +public: + CraftDefinitionShaped() = delete; + CraftDefinitionShaped( + const std::string &output_, + unsigned int width_, + const std::vector<std::string> &recipe_, + const CraftReplacements &replacements_); + + virtual ~CraftDefinitionShaped() = default; + + virtual std::string getName() const; + virtual bool check(const CraftInput &input, IGameDef *gamedef) const; + virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const; + virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const; + virtual void decrementInput(CraftInput &input, + std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const; + + virtual u64 getHash(CraftHashType type) const; + + virtual void initHash(IGameDef *gamedef); + + virtual std::string dump() const; + +private: + // Output itemstring + std::string output = ""; + // Width of recipe + unsigned int width = 1; + // Recipe matrix (itemstrings) + std::vector<std::string> recipe; + // Recipe matrix (item names) + std::vector<std::string> recipe_names; + // bool indicating if initHash has been called already + bool hash_inited = false; + // Replacement items for decrementInput() + CraftReplacements replacements; +}; + +/* + A shapeless crafting definition + Supported crafting method: CRAFT_METHOD_NORMAL. + Input items can arranged in any way. +*/ +class CraftDefinitionShapeless: public CraftDefinition +{ +public: + CraftDefinitionShapeless() = delete; + CraftDefinitionShapeless( + const std::string &output_, + const std::vector<std::string> &recipe_, + const CraftReplacements &replacements_); + + virtual ~CraftDefinitionShapeless() = default; + + virtual std::string getName() const; + virtual bool check(const CraftInput &input, IGameDef *gamedef) const; + virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const; + virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const; + virtual void decrementInput(CraftInput &input, + std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const; + + virtual u64 getHash(CraftHashType type) const; + + virtual void initHash(IGameDef *gamedef); + + virtual std::string dump() const; + +private: + // Output itemstring + std::string output; + // Recipe list (itemstrings) + std::vector<std::string> recipe; + // Recipe list (item names) + std::vector<std::string> recipe_names; + // bool indicating if initHash has been called already + bool hash_inited = false; + // Replacement items for decrementInput() + CraftReplacements replacements; +}; + +/* + Tool repair crafting definition + Supported crafting method: CRAFT_METHOD_NORMAL. + Put two damaged tools into the crafting grid, get one tool back. + There should only be one crafting definition of this type. +*/ +class CraftDefinitionToolRepair: public CraftDefinition +{ +public: + CraftDefinitionToolRepair() = delete; + CraftDefinitionToolRepair(float additional_wear_); + + virtual ~CraftDefinitionToolRepair() = default; + + virtual std::string getName() const; + virtual bool check(const CraftInput &input, IGameDef *gamedef) const; + virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const; + virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const; + virtual void decrementInput(CraftInput &input, + std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const; + + virtual u64 getHash(CraftHashType type) const { return 2; } + + virtual void initHash(IGameDef *gamedef) + { + hash_type = CRAFT_HASH_TYPE_COUNT; + } + + virtual std::string dump() const; + +private: + // This is a constant that is added to the wear of the result. + // May be positive or negative, allowed range [-1,1]. + // 1 = new tool is completely broken + // 0 = simply add remaining uses of both input tools + // -1 = new tool is completely pristine + float additional_wear = 0.0f; +}; + +/* + A cooking (in furnace) definition + Supported crafting method: CRAFT_METHOD_COOKING. +*/ +class CraftDefinitionCooking: public CraftDefinition +{ +public: + CraftDefinitionCooking() = delete; + CraftDefinitionCooking( + const std::string &output_, + const std::string &recipe_, + float cooktime_, + const CraftReplacements &replacements_); + + virtual ~CraftDefinitionCooking() = default; + + virtual std::string getName() const; + virtual bool check(const CraftInput &input, IGameDef *gamedef) const; + virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const; + virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const; + virtual void decrementInput(CraftInput &input, + std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const; + + virtual u64 getHash(CraftHashType type) const; + + virtual void initHash(IGameDef *gamedef); + + virtual std::string dump() const; + +private: + // Output itemstring + std::string output; + // Recipe itemstring + std::string recipe; + // Recipe item name + std::string recipe_name; + // bool indicating if initHash has been called already + bool hash_inited = false; + // Time in seconds + float cooktime; + // Replacement items for decrementInput() + CraftReplacements replacements; +}; + +/* + A fuel (for furnace) definition + Supported crafting method: CRAFT_METHOD_FUEL. +*/ +class CraftDefinitionFuel: public CraftDefinition +{ +public: + CraftDefinitionFuel() = delete; + CraftDefinitionFuel( + const std::string &recipe_, + float burntime_, + const CraftReplacements &replacements_); + + virtual ~CraftDefinitionFuel() = default; + + virtual std::string getName() const; + virtual bool check(const CraftInput &input, IGameDef *gamedef) const; + virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const; + virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const; + virtual void decrementInput(CraftInput &input, + std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const; + + virtual u64 getHash(CraftHashType type) const; + + virtual void initHash(IGameDef *gamedef); + + virtual std::string dump() const; + +private: + // Recipe itemstring + std::string recipe; + // Recipe item name + std::string recipe_name; + // bool indicating if initHash has been called already + bool hash_inited = false; + // Time in seconds + float burntime; + // Replacement items for decrementInput() + CraftReplacements replacements; +}; + +/* + Crafting definition manager +*/ +class ICraftDefManager +{ +public: + ICraftDefManager() = default; + virtual ~ICraftDefManager() = default; + + /** + * The main crafting function. + * + * @param input The input grid. + * @param output CraftOutput where the result is placed. + * @param output_replacements A vector of ItemStacks where replacements are + * placed if they cannot be placed in the input. Replacements can be placed + * in the input if the stack of the replaced item has a count of 1. + * @param decrementInput If true, consume or replace input items. + * @param gamedef + * @return true if a result was found, otherwise false. + */ + virtual bool getCraftResult(CraftInput &input, CraftOutput &output, + std::vector<ItemStack> &output_replacements, + bool decrementInput, IGameDef *gamedef) const=0; + + virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output, + IGameDef *gamedef, unsigned limit=0) const=0; + + // Print crafting recipes for debugging + virtual std::string dump() const=0; +}; + +class IWritableCraftDefManager : public ICraftDefManager +{ +public: + IWritableCraftDefManager() = default; + virtual ~IWritableCraftDefManager() = default; + + // The main crafting function + virtual bool getCraftResult(CraftInput &input, CraftOutput &output, + std::vector<ItemStack> &output_replacements, + bool decrementInput, IGameDef *gamedef) const=0; + virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output, + IGameDef *gamedef, unsigned limit=0) const=0; + + virtual bool clearCraftsByOutput(const CraftOutput &output, IGameDef *gamedef) = 0; + virtual bool clearCraftsByInput(const CraftInput &input, IGameDef *gamedef) = 0; + + // Print crafting recipes for debugging + virtual std::string dump() const=0; + + // Add a crafting definition. + // After calling this, the pointer belongs to the manager. + virtual void registerCraft(CraftDefinition *def, IGameDef *gamedef) = 0; + + // Delete all crafting definitions + virtual void clear()=0; + + // To be called after all mods are loaded, so that we catch all aliases + virtual void initHashes(IGameDef *gamedef) = 0; +}; + +IWritableCraftDefManager* createCraftDefManager(); diff --git a/src/database/CMakeLists.txt b/src/database/CMakeLists.txt new file mode 100644 index 0000000..e9d157c --- /dev/null +++ b/src/database/CMakeLists.txt @@ -0,0 +1,10 @@ +set(database_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/database.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/database-dummy.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/database-files.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/database-leveldb.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/database-postgresql.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/database-redis.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/database-sqlite3.cpp + PARENT_SCOPE +) diff --git a/src/database/database-dummy.cpp b/src/database/database-dummy.cpp new file mode 100644 index 0000000..629b2fb --- /dev/null +++ b/src/database/database-dummy.cpp @@ -0,0 +1,120 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/* +Dummy database class +*/ + +#include "database-dummy.h" +#include "remoteplayer.h" + + +bool Database_Dummy::saveBlock(const v3s16 &pos, const std::string &data) +{ + m_database[getBlockAsInteger(pos)] = data; + return true; +} + +void Database_Dummy::loadBlock(const v3s16 &pos, std::string *block) +{ + s64 i = getBlockAsInteger(pos); + auto it = m_database.find(i); + if (it == m_database.end()) { + *block = ""; + return; + } + + *block = it->second; +} + +bool Database_Dummy::deleteBlock(const v3s16 &pos) +{ + m_database.erase(getBlockAsInteger(pos)); + return true; +} + +void Database_Dummy::listAllLoadableBlocks(std::vector<v3s16> &dst) +{ + dst.reserve(m_database.size()); + for (std::map<s64, std::string>::const_iterator x = m_database.begin(); + x != m_database.end(); ++x) { + dst.push_back(getIntegerAsBlock(x->first)); + } +} + +void Database_Dummy::savePlayer(RemotePlayer *player) +{ + m_player_database.insert(player->getName()); +} + +bool Database_Dummy::loadPlayer(RemotePlayer *player, PlayerSAO *sao) +{ + return m_player_database.find(player->getName()) != m_player_database.end(); +} + +bool Database_Dummy::removePlayer(const std::string &name) +{ + m_player_database.erase(name); + return true; +} + +void Database_Dummy::listPlayers(std::vector<std::string> &res) +{ + for (const auto &player : m_player_database) { + res.emplace_back(player); + } +} + +bool Database_Dummy::getModEntries(const std::string &modname, StringMap *storage) +{ + const auto mod_pair = m_mod_meta_database.find(modname); + if (mod_pair != m_mod_meta_database.cend()) { + for (const auto &pair : mod_pair->second) { + (*storage)[pair.first] = pair.second; + } + } + return true; +} + +bool Database_Dummy::setModEntry(const std::string &modname, + const std::string &key, const std::string &value) +{ + auto mod_pair = m_mod_meta_database.find(modname); + if (mod_pair == m_mod_meta_database.end()) { + m_mod_meta_database[modname] = StringMap({{key, value}}); + } else { + mod_pair->second[key] = value; + } + return true; +} + +bool Database_Dummy::removeModEntry(const std::string &modname, const std::string &key) +{ + auto mod_pair = m_mod_meta_database.find(modname); + if (mod_pair != m_mod_meta_database.end()) + return mod_pair->second.erase(key) > 0; + return false; +} + +void Database_Dummy::listMods(std::vector<std::string> *res) +{ + for (const auto &pair : m_mod_meta_database) { + res->push_back(pair.first); + } +} diff --git a/src/database/database-dummy.h b/src/database/database-dummy.h new file mode 100644 index 0000000..44b9e8d --- /dev/null +++ b/src/database/database-dummy.h @@ -0,0 +1,53 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <map> +#include <string> +#include "database.h" +#include "irrlichttypes.h" + +class Database_Dummy : public MapDatabase, public PlayerDatabase, public ModMetadataDatabase +{ +public: + bool saveBlock(const v3s16 &pos, const std::string &data); + void loadBlock(const v3s16 &pos, std::string *block); + bool deleteBlock(const v3s16 &pos); + void listAllLoadableBlocks(std::vector<v3s16> &dst); + + void savePlayer(RemotePlayer *player); + bool loadPlayer(RemotePlayer *player, PlayerSAO *sao); + bool removePlayer(const std::string &name); + void listPlayers(std::vector<std::string> &res); + + bool getModEntries(const std::string &modname, StringMap *storage); + bool setModEntry(const std::string &modname, + const std::string &key, const std::string &value); + bool removeModEntry(const std::string &modname, const std::string &key); + void listMods(std::vector<std::string> *res); + + void beginSave() {} + void endSave() {} + +private: + std::map<s64, std::string> m_database; + std::set<std::string> m_player_database; + std::unordered_map<std::string, StringMap> m_mod_meta_database; +}; diff --git a/src/database/database-files.cpp b/src/database/database-files.cpp new file mode 100644 index 0000000..7c0dbac --- /dev/null +++ b/src/database/database-files.cpp @@ -0,0 +1,501 @@ +/* +Minetest +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <cassert> +#include "convert_json.h" +#include "database-files.h" +#include "remoteplayer.h" +#include "settings.h" +#include "porting.h" +#include "filesys.h" +#include "server/player_sao.h" +#include "util/string.h" + +// !!! WARNING !!! +// This backend is intended to be used on Minetest 0.4.16 only for the transition backend +// for player files + +PlayerDatabaseFiles::PlayerDatabaseFiles(const std::string &savedir) : m_savedir(savedir) +{ + fs::CreateDir(m_savedir); +} + +void PlayerDatabaseFiles::deSerialize(RemotePlayer *p, std::istream &is, + const std::string &playername, PlayerSAO *sao) +{ + Settings args("PlayerArgsEnd"); + + if (!args.parseConfigLines(is)) { + throw SerializationError("PlayerArgsEnd of player " + playername + " not found!"); + } + + p->m_dirty = true; + //args.getS32("version"); // Version field value not used + const std::string &name = args.get("name"); + strlcpy(p->m_name, name.c_str(), PLAYERNAME_SIZE); + + if (sao) { + try { + sao->setHPRaw(args.getU16("hp")); + } catch(SettingNotFoundException &e) { + sao->setHPRaw(PLAYER_MAX_HP_DEFAULT); + } + + try { + sao->setBasePosition(args.getV3F("position")); + } catch (SettingNotFoundException &e) {} + + try { + sao->setLookPitch(args.getFloat("pitch")); + } catch (SettingNotFoundException &e) {} + try { + sao->setPlayerYaw(args.getFloat("yaw")); + } catch (SettingNotFoundException &e) {} + + try { + sao->setBreath(args.getU16("breath"), false); + } catch (SettingNotFoundException &e) {} + + try { + const std::string &extended_attributes = args.get("extended_attributes"); + std::istringstream iss(extended_attributes); + Json::CharReaderBuilder builder; + builder.settings_["collectComments"] = false; + std::string errs; + + Json::Value attr_root; + Json::parseFromStream(builder, iss, &attr_root, &errs); + + const Json::Value::Members attr_list = attr_root.getMemberNames(); + for (const auto &it : attr_list) { + Json::Value attr_value = attr_root[it]; + sao->getMeta().setString(it, attr_value.asString()); + } + sao->getMeta().setModified(false); + } catch (SettingNotFoundException &e) {} + } + + try { + p->inventory.deSerialize(is); + } catch (SerializationError &e) { + errorstream << "Failed to deserialize player inventory. player_name=" + << name << " " << e.what() << std::endl; + } + + if (!p->inventory.getList("craftpreview") && p->inventory.getList("craftresult")) { + // Convert players without craftpreview + p->inventory.addList("craftpreview", 1); + + bool craftresult_is_preview = true; + if(args.exists("craftresult_is_preview")) + craftresult_is_preview = args.getBool("craftresult_is_preview"); + if(craftresult_is_preview) + { + // Clear craftresult + p->inventory.getList("craftresult")->changeItem(0, ItemStack()); + } + } +} + +void PlayerDatabaseFiles::serialize(RemotePlayer *p, std::ostream &os) +{ + // Utilize a Settings object for storing values + Settings args("PlayerArgsEnd"); + args.setS32("version", 1); + args.set("name", p->m_name); + + PlayerSAO *sao = p->getPlayerSAO(); + // This should not happen + sanity_check(sao); + args.setU16("hp", sao->getHP()); + args.setV3F("position", sao->getBasePosition()); + args.setFloat("pitch", sao->getLookPitch()); + args.setFloat("yaw", sao->getRotation().Y); + args.setU16("breath", sao->getBreath()); + + std::string extended_attrs; + { + // serializeExtraAttributes + Json::Value json_root; + + const StringMap &attrs = sao->getMeta().getStrings(); + for (const auto &attr : attrs) { + json_root[attr.first] = attr.second; + } + + extended_attrs = fastWriteJson(json_root); + } + args.set("extended_attributes", extended_attrs); + + args.writeLines(os); + + p->inventory.serialize(os); +} + +void PlayerDatabaseFiles::savePlayer(RemotePlayer *player) +{ + fs::CreateDir(m_savedir); + + std::string savedir = m_savedir + DIR_DELIM; + std::string path = savedir + player->getName(); + bool path_found = false; + RemotePlayer testplayer("", NULL); + + for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES && !path_found; i++) { + if (!fs::PathExists(path)) { + path_found = true; + continue; + } + + // Open and deserialize file to check player name + std::ifstream is(path.c_str(), std::ios_base::binary); + if (!is.good()) { + errorstream << "Failed to open " << path << std::endl; + return; + } + + deSerialize(&testplayer, is, path, NULL); + is.close(); + if (strcmp(testplayer.getName(), player->getName()) == 0) { + path_found = true; + continue; + } + + path = savedir + player->getName() + itos(i); + } + + if (!path_found) { + errorstream << "Didn't find free file for player " << player->getName() + << std::endl; + return; + } + + // Open and serialize file + std::ostringstream ss(std::ios_base::binary); + serialize(player, ss); + if (!fs::safeWriteToFile(path, ss.str())) { + infostream << "Failed to write " << path << std::endl; + } + + player->onSuccessfulSave(); +} + +bool PlayerDatabaseFiles::removePlayer(const std::string &name) +{ + std::string players_path = m_savedir + DIR_DELIM; + std::string path = players_path + name; + + RemotePlayer temp_player("", NULL); + for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES; i++) { + // Open file and deserialize + std::ifstream is(path.c_str(), std::ios_base::binary); + if (!is.good()) + continue; + + deSerialize(&temp_player, is, path, NULL); + is.close(); + + if (temp_player.getName() == name) { + fs::DeleteSingleFileOrEmptyDirectory(path); + return true; + } + + path = players_path + name + itos(i); + } + + return false; +} + +bool PlayerDatabaseFiles::loadPlayer(RemotePlayer *player, PlayerSAO *sao) +{ + std::string players_path = m_savedir + DIR_DELIM; + std::string path = players_path + player->getName(); + + const std::string player_to_load = player->getName(); + for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES; i++) { + // Open file and deserialize + std::ifstream is(path.c_str(), std::ios_base::binary); + if (!is.good()) + continue; + + deSerialize(player, is, path, sao); + is.close(); + + if (player->getName() == player_to_load) + return true; + + path = players_path + player_to_load + itos(i); + } + + infostream << "Player file for player " << player_to_load << " not found" << std::endl; + return false; +} + +void PlayerDatabaseFiles::listPlayers(std::vector<std::string> &res) +{ + std::vector<fs::DirListNode> files = fs::GetDirListing(m_savedir); + // list files into players directory + for (std::vector<fs::DirListNode>::const_iterator it = files.begin(); it != + files.end(); ++it) { + // Ignore directories + if (it->dir) + continue; + + const std::string &filename = it->name; + std::string full_path = m_savedir + DIR_DELIM + filename; + std::ifstream is(full_path.c_str(), std::ios_base::binary); + if (!is.good()) + continue; + + RemotePlayer player(filename.c_str(), NULL); + // Null env & dummy peer_id + PlayerSAO playerSAO(NULL, &player, 15789, false); + + deSerialize(&player, is, "", &playerSAO); + is.close(); + + res.emplace_back(player.getName()); + } +} + +AuthDatabaseFiles::AuthDatabaseFiles(const std::string &savedir) : m_savedir(savedir) +{ + readAuthFile(); +} + +bool AuthDatabaseFiles::getAuth(const std::string &name, AuthEntry &res) +{ + const auto res_i = m_auth_list.find(name); + if (res_i == m_auth_list.end()) { + return false; + } + res = res_i->second; + return true; +} + +bool AuthDatabaseFiles::saveAuth(const AuthEntry &authEntry) +{ + m_auth_list[authEntry.name] = authEntry; + + // save entire file + return writeAuthFile(); +} + +bool AuthDatabaseFiles::createAuth(AuthEntry &authEntry) +{ + m_auth_list[authEntry.name] = authEntry; + + // save entire file + return writeAuthFile(); +} + +bool AuthDatabaseFiles::deleteAuth(const std::string &name) +{ + if (!m_auth_list.erase(name)) { + // did not delete anything -> hadn't existed + return false; + } + return writeAuthFile(); +} + +void AuthDatabaseFiles::listNames(std::vector<std::string> &res) +{ + res.clear(); + res.reserve(m_auth_list.size()); + for (const auto &res_pair : m_auth_list) { + res.push_back(res_pair.first); + } +} + +void AuthDatabaseFiles::reload() +{ + readAuthFile(); +} + +bool AuthDatabaseFiles::readAuthFile() +{ + std::string path = m_savedir + DIR_DELIM + "auth.txt"; + std::ifstream file(path, std::ios::binary); + if (!file.good()) { + return false; + } + m_auth_list.clear(); + while (file.good()) { + std::string line; + std::getline(file, line); + std::vector<std::string> parts = str_split(line, ':'); + if (parts.size() < 3) // also: empty line at end + continue; + const std::string &name = parts[0]; + const std::string &password = parts[1]; + std::vector<std::string> privileges = str_split(parts[2], ','); + s64 last_login = parts.size() > 3 ? atol(parts[3].c_str()) : 0; + + m_auth_list[name] = { + 1, + name, + password, + privileges, + last_login, + }; + } + return true; +} + +bool AuthDatabaseFiles::writeAuthFile() +{ + std::string path = m_savedir + DIR_DELIM + "auth.txt"; + std::ostringstream output(std::ios_base::binary); + for (const auto &auth_i : m_auth_list) { + const AuthEntry &authEntry = auth_i.second; + output << authEntry.name << ":" << authEntry.password << ":"; + output << str_join(authEntry.privileges, ","); + output << ":" << authEntry.last_login; + output << std::endl; + } + if (!fs::safeWriteToFile(path, output.str())) { + infostream << "Failed to write " << path << std::endl; + return false; + } + return true; +} + +ModMetadataDatabaseFiles::ModMetadataDatabaseFiles(const std::string &savedir): + m_storage_dir(savedir + DIR_DELIM + "mod_storage") +{ +} + +bool ModMetadataDatabaseFiles::getModEntries(const std::string &modname, StringMap *storage) +{ + Json::Value *meta = getOrCreateJson(modname); + if (!meta) + return false; + + const Json::Value::Members attr_list = meta->getMemberNames(); + for (const auto &it : attr_list) { + Json::Value attr_value = (*meta)[it]; + (*storage)[it] = attr_value.asString(); + } + + return true; +} + +bool ModMetadataDatabaseFiles::setModEntry(const std::string &modname, + const std::string &key, const std::string &value) +{ + Json::Value *meta = getOrCreateJson(modname); + if (!meta) + return false; + + (*meta)[key] = Json::Value(value); + m_modified.insert(modname); + + return true; +} + +bool ModMetadataDatabaseFiles::removeModEntry(const std::string &modname, + const std::string &key) +{ + Json::Value *meta = getOrCreateJson(modname); + if (!meta) + return false; + + Json::Value removed; + if (meta->removeMember(key, &removed)) { + m_modified.insert(modname); + return true; + } + return false; +} + +void ModMetadataDatabaseFiles::beginSave() +{ +} + +void ModMetadataDatabaseFiles::endSave() +{ + if (m_modified.empty()) + return; + + if (!fs::CreateAllDirs(m_storage_dir)) { + errorstream << "ModMetadataDatabaseFiles: Unable to save. '" + << m_storage_dir << "' cannot be created." << std::endl; + return; + } + if (!fs::IsDir(m_storage_dir)) { + errorstream << "ModMetadataDatabaseFiles: Unable to save. '" + << m_storage_dir << "' is not a directory." << std::endl; + return; + } + + for (auto it = m_modified.begin(); it != m_modified.end();) { + const std::string &modname = *it; + + const Json::Value &json = m_mod_meta[modname]; + + if (!fs::safeWriteToFile(m_storage_dir + DIR_DELIM + modname, fastWriteJson(json))) { + errorstream << "ModMetadataDatabaseFiles[" << modname + << "]: failed to write file." << std::endl; + ++it; + continue; + } + + it = m_modified.erase(it); + } +} + +void ModMetadataDatabaseFiles::listMods(std::vector<std::string> *res) +{ + // List in-memory metadata first. + for (const auto &pair : m_mod_meta) { + res->push_back(pair.first); + } + + // List other metadata present in the filesystem. + for (const auto &entry : fs::GetDirListing(m_storage_dir)) { + if (!entry.dir && m_mod_meta.count(entry.name) == 0) + res->push_back(entry.name); + } +} + +Json::Value *ModMetadataDatabaseFiles::getOrCreateJson(const std::string &modname) +{ + auto found = m_mod_meta.find(modname); + if (found != m_mod_meta.end()) + return &found->second; + + Json::Value meta(Json::objectValue); + + std::string path = m_storage_dir + DIR_DELIM + modname; + if (fs::PathExists(path)) { + std::ifstream is(path.c_str(), std::ios_base::binary); + + Json::CharReaderBuilder builder; + builder.settings_["collectComments"] = false; + std::string errs; + + if (!Json::parseFromStream(builder, is, &meta, &errs)) { + errorstream << "ModMetadataDatabaseFiles[" << modname + << "]: failed to decode data: " << errs << std::endl; + return nullptr; + } + } + + return &(m_mod_meta[modname] = meta); +} diff --git a/src/database/database-files.h b/src/database/database-files.h new file mode 100644 index 0000000..962e4d7 --- /dev/null +++ b/src/database/database-files.h @@ -0,0 +1,97 @@ +/* +Minetest +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +// !!! WARNING !!! +// This backend is intended to be used on Minetest 0.4.16 only for the transition backend +// for player files + +#include "database.h" +#include <unordered_map> +#include <unordered_set> +#include <json/json.h> + +class PlayerDatabaseFiles : public PlayerDatabase +{ +public: + PlayerDatabaseFiles(const std::string &savedir); + virtual ~PlayerDatabaseFiles() = default; + + void savePlayer(RemotePlayer *player); + bool loadPlayer(RemotePlayer *player, PlayerSAO *sao); + bool removePlayer(const std::string &name); + void listPlayers(std::vector<std::string> &res); + +private: + void deSerialize(RemotePlayer *p, std::istream &is, const std::string &playername, + PlayerSAO *sao); + /* + serialize() writes a bunch of text that can contain + any characters except a '\0', and such an ending that + deSerialize stops reading exactly at the right point. + */ + void serialize(RemotePlayer *p, std::ostream &os); + + std::string m_savedir; +}; + +class AuthDatabaseFiles : public AuthDatabase +{ +public: + AuthDatabaseFiles(const std::string &savedir); + virtual ~AuthDatabaseFiles() = default; + + virtual bool getAuth(const std::string &name, AuthEntry &res); + virtual bool saveAuth(const AuthEntry &authEntry); + virtual bool createAuth(AuthEntry &authEntry); + virtual bool deleteAuth(const std::string &name); + virtual void listNames(std::vector<std::string> &res); + virtual void reload(); + +private: + std::unordered_map<std::string, AuthEntry> m_auth_list; + std::string m_savedir; + bool readAuthFile(); + bool writeAuthFile(); +}; + +class ModMetadataDatabaseFiles : public ModMetadataDatabase +{ +public: + ModMetadataDatabaseFiles(const std::string &savedir); + virtual ~ModMetadataDatabaseFiles() = default; + + virtual bool getModEntries(const std::string &modname, StringMap *storage); + virtual bool setModEntry(const std::string &modname, + const std::string &key, const std::string &value); + virtual bool removeModEntry(const std::string &modname, const std::string &key); + virtual void listMods(std::vector<std::string> *res); + + virtual void beginSave(); + virtual void endSave(); + +private: + Json::Value *getOrCreateJson(const std::string &modname); + bool writeJson(const std::string &modname, const Json::Value &json); + + std::string m_storage_dir; + std::unordered_map<std::string, Json::Value> m_mod_meta; + std::unordered_set<std::string> m_modified; +}; diff --git a/src/database/database-leveldb.cpp b/src/database/database-leveldb.cpp new file mode 100644 index 0000000..6e59daa --- /dev/null +++ b/src/database/database-leveldb.cpp @@ -0,0 +1,309 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "config.h" + +#if USE_LEVELDB + +#include "database-leveldb.h" + +#include "log.h" +#include "filesys.h" +#include "exceptions.h" +#include "remoteplayer.h" +#include "server/player_sao.h" +#include "util/serialize.h" +#include "util/string.h" + +#include "leveldb/db.h" + + +#define ENSURE_STATUS_OK(s) \ + if (!(s).ok()) { \ + throw DatabaseException(std::string("LevelDB error: ") + \ + (s).ToString()); \ + } + + +Database_LevelDB::Database_LevelDB(const std::string &savedir) +{ + leveldb::Options options; + options.create_if_missing = true; + leveldb::Status status = leveldb::DB::Open(options, + savedir + DIR_DELIM + "map.db", &m_database); + ENSURE_STATUS_OK(status); +} + +Database_LevelDB::~Database_LevelDB() +{ + delete m_database; +} + +bool Database_LevelDB::saveBlock(const v3s16 &pos, const std::string &data) +{ + leveldb::Status status = m_database->Put(leveldb::WriteOptions(), + i64tos(getBlockAsInteger(pos)), data); + if (!status.ok()) { + warningstream << "saveBlock: LevelDB error saving block " + << PP(pos) << ": " << status.ToString() << std::endl; + return false; + } + + return true; +} + +void Database_LevelDB::loadBlock(const v3s16 &pos, std::string *block) +{ + leveldb::Status status = m_database->Get(leveldb::ReadOptions(), + i64tos(getBlockAsInteger(pos)), block); + + if (!status.ok()) + block->clear(); +} + +bool Database_LevelDB::deleteBlock(const v3s16 &pos) +{ + leveldb::Status status = m_database->Delete(leveldb::WriteOptions(), + i64tos(getBlockAsInteger(pos))); + if (!status.ok()) { + warningstream << "deleteBlock: LevelDB error deleting block " + << PP(pos) << ": " << status.ToString() << std::endl; + return false; + } + + return true; +} + +void Database_LevelDB::listAllLoadableBlocks(std::vector<v3s16> &dst) +{ + leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions()); + for (it->SeekToFirst(); it->Valid(); it->Next()) { + dst.push_back(getIntegerAsBlock(stoi64(it->key().ToString()))); + } + ENSURE_STATUS_OK(it->status()); // Check for any errors found during the scan + delete it; +} + +PlayerDatabaseLevelDB::PlayerDatabaseLevelDB(const std::string &savedir) +{ + leveldb::Options options; + options.create_if_missing = true; + leveldb::Status status = leveldb::DB::Open(options, + savedir + DIR_DELIM + "players.db", &m_database); + ENSURE_STATUS_OK(status); +} + +PlayerDatabaseLevelDB::~PlayerDatabaseLevelDB() +{ + delete m_database; +} + +void PlayerDatabaseLevelDB::savePlayer(RemotePlayer *player) +{ + /* + u8 version = 1 + u16 hp + v3f position + f32 pitch + f32 yaw + u16 breath + u32 attribute_count + for each attribute { + std::string name + std::string (long) value + } + std::string (long) serialized_inventory + */ + + std::ostringstream os(std::ios_base::binary); + writeU8(os, 1); + + PlayerSAO *sao = player->getPlayerSAO(); + sanity_check(sao); + writeU16(os, sao->getHP()); + writeV3F32(os, sao->getBasePosition()); + writeF32(os, sao->getLookPitch()); + writeF32(os, sao->getRotation().Y); + writeU16(os, sao->getBreath()); + + const auto &stringvars = sao->getMeta().getStrings(); + writeU32(os, stringvars.size()); + for (const auto &it : stringvars) { + os << serializeString16(it.first); + os << serializeString32(it.second); + } + + player->inventory.serialize(os); + + leveldb::Status status = m_database->Put(leveldb::WriteOptions(), + player->getName(), os.str()); + ENSURE_STATUS_OK(status); + player->onSuccessfulSave(); +} + +bool PlayerDatabaseLevelDB::removePlayer(const std::string &name) +{ + leveldb::Status s = m_database->Delete(leveldb::WriteOptions(), name); + return s.ok(); +} + +bool PlayerDatabaseLevelDB::loadPlayer(RemotePlayer *player, PlayerSAO *sao) +{ + std::string raw; + leveldb::Status s = m_database->Get(leveldb::ReadOptions(), + player->getName(), &raw); + if (!s.ok()) + return false; + std::istringstream is(raw, std::ios_base::binary); + + if (readU8(is) > 1) + return false; + + sao->setHPRaw(readU16(is)); + sao->setBasePosition(readV3F32(is)); + sao->setLookPitch(readF32(is)); + sao->setPlayerYaw(readF32(is)); + sao->setBreath(readU16(is), false); + + u32 attribute_count = readU32(is); + for (u32 i = 0; i < attribute_count; i++) { + std::string name = deSerializeString16(is); + std::string value = deSerializeString32(is); + sao->getMeta().setString(name, value); + } + sao->getMeta().setModified(false); + + // This should always be last. + try { + player->inventory.deSerialize(is); + } catch (SerializationError &e) { + errorstream << "Failed to deserialize player inventory. player_name=" + << player->getName() << " " << e.what() << std::endl; + } + + return true; +} + +void PlayerDatabaseLevelDB::listPlayers(std::vector<std::string> &res) +{ + leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions()); + res.clear(); + for (it->SeekToFirst(); it->Valid(); it->Next()) { + res.push_back(it->key().ToString()); + } + delete it; +} + +AuthDatabaseLevelDB::AuthDatabaseLevelDB(const std::string &savedir) +{ + leveldb::Options options; + options.create_if_missing = true; + leveldb::Status status = leveldb::DB::Open(options, + savedir + DIR_DELIM + "auth.db", &m_database); + ENSURE_STATUS_OK(status); +} + +AuthDatabaseLevelDB::~AuthDatabaseLevelDB() +{ + delete m_database; +} + +bool AuthDatabaseLevelDB::getAuth(const std::string &name, AuthEntry &res) +{ + std::string raw; + leveldb::Status s = m_database->Get(leveldb::ReadOptions(), name, &raw); + if (!s.ok()) + return false; + std::istringstream is(raw, std::ios_base::binary); + + /* + u8 version = 1 + std::string password + u16 number of privileges + for each privilege { + std::string privilege + } + s64 last_login + */ + + if (readU8(is) > 1) + return false; + + res.id = 1; + res.name = name; + res.password = deSerializeString16(is); + + u16 privilege_count = readU16(is); + res.privileges.clear(); + res.privileges.reserve(privilege_count); + for (u16 i = 0; i < privilege_count; i++) { + res.privileges.push_back(deSerializeString16(is)); + } + + res.last_login = readS64(is); + return true; +} + +bool AuthDatabaseLevelDB::saveAuth(const AuthEntry &authEntry) +{ + std::ostringstream os(std::ios_base::binary); + writeU8(os, 1); + os << serializeString16(authEntry.password); + + size_t privilege_count = authEntry.privileges.size(); + FATAL_ERROR_IF(privilege_count > U16_MAX, + "Unsupported number of privileges"); + writeU16(os, privilege_count); + for (const std::string &privilege : authEntry.privileges) { + os << serializeString16(privilege); + } + + writeS64(os, authEntry.last_login); + leveldb::Status s = m_database->Put(leveldb::WriteOptions(), + authEntry.name, os.str()); + return s.ok(); +} + +bool AuthDatabaseLevelDB::createAuth(AuthEntry &authEntry) +{ + return saveAuth(authEntry); +} + +bool AuthDatabaseLevelDB::deleteAuth(const std::string &name) +{ + leveldb::Status s = m_database->Delete(leveldb::WriteOptions(), name); + return s.ok(); +} + +void AuthDatabaseLevelDB::listNames(std::vector<std::string> &res) +{ + leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions()); + res.clear(); + for (it->SeekToFirst(); it->Valid(); it->Next()) { + res.emplace_back(it->key().ToString()); + } + delete it; +} + +void AuthDatabaseLevelDB::reload() +{ + // No-op for LevelDB. +} + +#endif // USE_LEVELDB diff --git a/src/database/database-leveldb.h b/src/database/database-leveldb.h new file mode 100644 index 0000000..61def12 --- /dev/null +++ b/src/database/database-leveldb.h @@ -0,0 +1,80 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "config.h" + +#if USE_LEVELDB + +#include <string> +#include "database.h" +#include "leveldb/db.h" + +class Database_LevelDB : public MapDatabase +{ +public: + Database_LevelDB(const std::string &savedir); + ~Database_LevelDB(); + + bool saveBlock(const v3s16 &pos, const std::string &data); + void loadBlock(const v3s16 &pos, std::string *block); + bool deleteBlock(const v3s16 &pos); + void listAllLoadableBlocks(std::vector<v3s16> &dst); + + void beginSave() {} + void endSave() {} + +private: + leveldb::DB *m_database; +}; + +class PlayerDatabaseLevelDB : public PlayerDatabase +{ +public: + PlayerDatabaseLevelDB(const std::string &savedir); + ~PlayerDatabaseLevelDB(); + + void savePlayer(RemotePlayer *player); + bool loadPlayer(RemotePlayer *player, PlayerSAO *sao); + bool removePlayer(const std::string &name); + void listPlayers(std::vector<std::string> &res); + +private: + leveldb::DB *m_database; +}; + +class AuthDatabaseLevelDB : public AuthDatabase +{ +public: + AuthDatabaseLevelDB(const std::string &savedir); + virtual ~AuthDatabaseLevelDB(); + + virtual bool getAuth(const std::string &name, AuthEntry &res); + virtual bool saveAuth(const AuthEntry &authEntry); + virtual bool createAuth(AuthEntry &authEntry); + virtual bool deleteAuth(const std::string &name); + virtual void listNames(std::vector<std::string> &res); + virtual void reload(); + +private: + leveldb::DB *m_database; +}; + +#endif // USE_LEVELDB diff --git a/src/database/database-postgresql.cpp b/src/database/database-postgresql.cpp new file mode 100644 index 0000000..9d6501e --- /dev/null +++ b/src/database/database-postgresql.cpp @@ -0,0 +1,816 @@ +/* +Copyright (C) 2016 Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "config.h" + +#if USE_POSTGRESQL + +#include "database-postgresql.h" + +#ifdef _WIN32 + // Without this some of the network functions are not found on mingw + #ifndef _WIN32_WINNT + #define _WIN32_WINNT 0x0501 + #endif + #include <windows.h> + #include <winsock2.h> +#else +#include <netinet/in.h> +#endif + +#include "debug.h" +#include "exceptions.h" +#include "settings.h" +#include "remoteplayer.h" +#include "server/player_sao.h" + +Database_PostgreSQL::Database_PostgreSQL(const std::string &connect_string, + const char *type) : + m_connect_string(connect_string) +{ + if (m_connect_string.empty()) { + // Use given type to reference the exact setting in the error message + std::string s = type; + std::string msg = + "Set pgsql" + s + "_connection string in world.mt to " + "use the postgresql backend\n" + "Notes:\n" + "pgsql" + s + "_connection has the following form: \n" + "\tpgsql" + s + "_connection = host=127.0.0.1 port=5432 " + "user=mt_user password=mt_password dbname=minetest" + s + "\n" + "mt_user should have CREATE TABLE, INSERT, SELECT, UPDATE and " + "DELETE rights on the database. " + "Don't create mt_user as a SUPERUSER!"; + throw SettingNotFoundException(msg); + } +} + +Database_PostgreSQL::~Database_PostgreSQL() +{ + PQfinish(m_conn); +} + +void Database_PostgreSQL::connectToDatabase() +{ + m_conn = PQconnectdb(m_connect_string.c_str()); + + if (PQstatus(m_conn) != CONNECTION_OK) { + throw DatabaseException(std::string( + "PostgreSQL database error: ") + + PQerrorMessage(m_conn)); + } + + m_pgversion = PQserverVersion(m_conn); + + /* + * We are using UPSERT feature from PostgreSQL 9.5 + * to have the better performance where possible. + */ + if (m_pgversion < 90500) { + warningstream << "Your PostgreSQL server lacks UPSERT " + << "support. Use version 9.5 or better if possible." + << std::endl; + } + + infostream << "PostgreSQL Database: Version " << m_pgversion + << " Connection made." << std::endl; + + createDatabase(); + initStatements(); +} + +void Database_PostgreSQL::verifyDatabase() +{ + if (PQstatus(m_conn) == CONNECTION_OK) + return; + + PQreset(m_conn); + ping(); +} + +void Database_PostgreSQL::ping() +{ + if (PQping(m_connect_string.c_str()) != PQPING_OK) { + throw DatabaseException(std::string( + "PostgreSQL database error: ") + + PQerrorMessage(m_conn)); + } +} + +bool Database_PostgreSQL::initialized() const +{ + return (PQstatus(m_conn) == CONNECTION_OK); +} + +PGresult *Database_PostgreSQL::checkResults(PGresult *result, bool clear) +{ + ExecStatusType statusType = PQresultStatus(result); + + switch (statusType) { + case PGRES_COMMAND_OK: + case PGRES_TUPLES_OK: + break; + case PGRES_FATAL_ERROR: + default: + throw DatabaseException( + std::string("PostgreSQL database error: ") + + PQresultErrorMessage(result)); + } + + if (clear) + PQclear(result); + + return result; +} + +void Database_PostgreSQL::createTableIfNotExists(const std::string &table_name, + const std::string &definition) +{ + std::string sql_check_table = "SELECT relname FROM pg_class WHERE relname='" + + table_name + "';"; + PGresult *result = checkResults(PQexec(m_conn, sql_check_table.c_str()), false); + + // If table doesn't exist, create it + if (!PQntuples(result)) { + checkResults(PQexec(m_conn, definition.c_str())); + } + + PQclear(result); +} + +void Database_PostgreSQL::beginSave() +{ + verifyDatabase(); + checkResults(PQexec(m_conn, "BEGIN;")); +} + +void Database_PostgreSQL::endSave() +{ + checkResults(PQexec(m_conn, "COMMIT;")); +} + +void Database_PostgreSQL::rollback() +{ + checkResults(PQexec(m_conn, "ROLLBACK;")); +} + +MapDatabasePostgreSQL::MapDatabasePostgreSQL(const std::string &connect_string): + Database_PostgreSQL(connect_string, ""), + MapDatabase() +{ + connectToDatabase(); +} + + +void MapDatabasePostgreSQL::createDatabase() +{ + createTableIfNotExists("blocks", + "CREATE TABLE blocks (" + "posX INT NOT NULL," + "posY INT NOT NULL," + "posZ INT NOT NULL," + "data BYTEA," + "PRIMARY KEY (posX,posY,posZ)" + ");" + ); + + infostream << "PostgreSQL: Map Database was initialized." << std::endl; +} + +void MapDatabasePostgreSQL::initStatements() +{ + prepareStatement("read_block", + "SELECT data FROM blocks " + "WHERE posX = $1::int4 AND posY = $2::int4 AND " + "posZ = $3::int4"); + + if (getPGVersion() < 90500) { + prepareStatement("write_block_insert", + "INSERT INTO blocks (posX, posY, posZ, data) SELECT " + "$1::int4, $2::int4, $3::int4, $4::bytea " + "WHERE NOT EXISTS (SELECT true FROM blocks " + "WHERE posX = $1::int4 AND posY = $2::int4 AND " + "posZ = $3::int4)"); + + prepareStatement("write_block_update", + "UPDATE blocks SET data = $4::bytea " + "WHERE posX = $1::int4 AND posY = $2::int4 AND " + "posZ = $3::int4"); + } else { + prepareStatement("write_block", + "INSERT INTO blocks (posX, posY, posZ, data) VALUES " + "($1::int4, $2::int4, $3::int4, $4::bytea) " + "ON CONFLICT ON CONSTRAINT blocks_pkey DO " + "UPDATE SET data = $4::bytea"); + } + + prepareStatement("delete_block", "DELETE FROM blocks WHERE " + "posX = $1::int4 AND posY = $2::int4 AND posZ = $3::int4"); + + prepareStatement("list_all_loadable_blocks", + "SELECT posX, posY, posZ FROM blocks"); +} + +bool MapDatabasePostgreSQL::saveBlock(const v3s16 &pos, const std::string &data) +{ + // Verify if we don't overflow the platform integer with the mapblock size + if (data.size() > INT_MAX) { + errorstream << "Database_PostgreSQL::saveBlock: Data truncation! " + << "data.size() over 0xFFFFFFFF (== " << data.size() + << ")" << std::endl; + return false; + } + + verifyDatabase(); + + s32 x, y, z; + x = htonl(pos.X); + y = htonl(pos.Y); + z = htonl(pos.Z); + + const void *args[] = { &x, &y, &z, data.c_str() }; + const int argLen[] = { + sizeof(x), sizeof(y), sizeof(z), (int)data.size() + }; + const int argFmt[] = { 1, 1, 1, 1 }; + + if (getPGVersion() < 90500) { + execPrepared("write_block_update", ARRLEN(args), args, argLen, argFmt); + execPrepared("write_block_insert", ARRLEN(args), args, argLen, argFmt); + } else { + execPrepared("write_block", ARRLEN(args), args, argLen, argFmt); + } + return true; +} + +void MapDatabasePostgreSQL::loadBlock(const v3s16 &pos, std::string *block) +{ + verifyDatabase(); + + s32 x, y, z; + x = htonl(pos.X); + y = htonl(pos.Y); + z = htonl(pos.Z); + + const void *args[] = { &x, &y, &z }; + const int argLen[] = { sizeof(x), sizeof(y), sizeof(z) }; + const int argFmt[] = { 1, 1, 1 }; + + PGresult *results = execPrepared("read_block", ARRLEN(args), args, + argLen, argFmt, false); + + if (PQntuples(results)) + block->assign(PQgetvalue(results, 0, 0), PQgetlength(results, 0, 0)); + else + block->clear(); + + PQclear(results); +} + +bool MapDatabasePostgreSQL::deleteBlock(const v3s16 &pos) +{ + verifyDatabase(); + + s32 x, y, z; + x = htonl(pos.X); + y = htonl(pos.Y); + z = htonl(pos.Z); + + const void *args[] = { &x, &y, &z }; + const int argLen[] = { sizeof(x), sizeof(y), sizeof(z) }; + const int argFmt[] = { 1, 1, 1 }; + + execPrepared("delete_block", ARRLEN(args), args, argLen, argFmt); + + return true; +} + +void MapDatabasePostgreSQL::listAllLoadableBlocks(std::vector<v3s16> &dst) +{ + verifyDatabase(); + + PGresult *results = execPrepared("list_all_loadable_blocks", 0, + NULL, NULL, NULL, false, false); + + int numrows = PQntuples(results); + + for (int row = 0; row < numrows; ++row) + dst.push_back(pg_to_v3s16(results, row, 0)); + + PQclear(results); +} + +/* + * Player Database + */ +PlayerDatabasePostgreSQL::PlayerDatabasePostgreSQL(const std::string &connect_string): + Database_PostgreSQL(connect_string, "_player"), + PlayerDatabase() +{ + connectToDatabase(); +} + + +void PlayerDatabasePostgreSQL::createDatabase() +{ + createTableIfNotExists("player", + "CREATE TABLE player (" + "name VARCHAR(60) NOT NULL," + "pitch NUMERIC(15, 7) NOT NULL," + "yaw NUMERIC(15, 7) NOT NULL," + "posX NUMERIC(15, 7) NOT NULL," + "posY NUMERIC(15, 7) NOT NULL," + "posZ NUMERIC(15, 7) NOT NULL," + "hp INT NOT NULL," + "breath INT NOT NULL," + "creation_date TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW()," + "modification_date TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW()," + "PRIMARY KEY (name)" + ");" + ); + + createTableIfNotExists("player_inventories", + "CREATE TABLE player_inventories (" + "player VARCHAR(60) NOT NULL," + "inv_id INT NOT NULL," + "inv_width INT NOT NULL," + "inv_name TEXT NOT NULL DEFAULT ''," + "inv_size INT NOT NULL," + "PRIMARY KEY(player, inv_id)," + "CONSTRAINT player_inventories_fkey FOREIGN KEY (player) REFERENCES " + "player (name) ON DELETE CASCADE" + ");" + ); + + createTableIfNotExists("player_inventory_items", + "CREATE TABLE player_inventory_items (" + "player VARCHAR(60) NOT NULL," + "inv_id INT NOT NULL," + "slot_id INT NOT NULL," + "item TEXT NOT NULL DEFAULT ''," + "PRIMARY KEY(player, inv_id, slot_id)," + "CONSTRAINT player_inventory_items_fkey FOREIGN KEY (player) REFERENCES " + "player (name) ON DELETE CASCADE" + ");" + ); + + createTableIfNotExists("player_metadata", + "CREATE TABLE player_metadata (" + "player VARCHAR(60) NOT NULL," + "attr VARCHAR(256) NOT NULL," + "value TEXT," + "PRIMARY KEY(player, attr)," + "CONSTRAINT player_metadata_fkey FOREIGN KEY (player) REFERENCES " + "player (name) ON DELETE CASCADE" + ");" + ); + + infostream << "PostgreSQL: Player Database was inited." << std::endl; +} + +void PlayerDatabasePostgreSQL::initStatements() +{ + if (getPGVersion() < 90500) { + prepareStatement("create_player", + "INSERT INTO player(name, pitch, yaw, posX, posY, posZ, hp, breath) VALUES " + "($1, $2, $3, $4, $5, $6, $7::int, $8::int)"); + + prepareStatement("update_player", + "UPDATE SET pitch = $2, yaw = $3, posX = $4, posY = $5, posZ = $6, hp = $7::int, " + "breath = $8::int, modification_date = NOW() WHERE name = $1"); + } else { + prepareStatement("save_player", + "INSERT INTO player(name, pitch, yaw, posX, posY, posZ, hp, breath) VALUES " + "($1, $2, $3, $4, $5, $6, $7::int, $8::int)" + "ON CONFLICT ON CONSTRAINT player_pkey DO UPDATE SET pitch = $2, yaw = $3, " + "posX = $4, posY = $5, posZ = $6, hp = $7::int, breath = $8::int, " + "modification_date = NOW()"); + } + + prepareStatement("remove_player", "DELETE FROM player WHERE name = $1"); + + prepareStatement("load_player_list", "SELECT name FROM player"); + + prepareStatement("remove_player_inventories", + "DELETE FROM player_inventories WHERE player = $1"); + + prepareStatement("remove_player_inventory_items", + "DELETE FROM player_inventory_items WHERE player = $1"); + + prepareStatement("add_player_inventory", + "INSERT INTO player_inventories (player, inv_id, inv_width, inv_name, inv_size) VALUES " + "($1, $2::int, $3::int, $4, $5::int)"); + + prepareStatement("add_player_inventory_item", + "INSERT INTO player_inventory_items (player, inv_id, slot_id, item) VALUES " + "($1, $2::int, $3::int, $4)"); + + prepareStatement("load_player_inventories", + "SELECT inv_id, inv_width, inv_name, inv_size FROM player_inventories " + "WHERE player = $1 ORDER BY inv_id"); + + prepareStatement("load_player_inventory_items", + "SELECT slot_id, item FROM player_inventory_items WHERE " + "player = $1 AND inv_id = $2::int"); + + prepareStatement("load_player", + "SELECT pitch, yaw, posX, posY, posZ, hp, breath FROM player WHERE name = $1"); + + prepareStatement("remove_player_metadata", + "DELETE FROM player_metadata WHERE player = $1"); + + prepareStatement("save_player_metadata", + "INSERT INTO player_metadata (player, attr, value) VALUES ($1, $2, $3)"); + + prepareStatement("load_player_metadata", + "SELECT attr, value FROM player_metadata WHERE player = $1"); + +} + +bool PlayerDatabasePostgreSQL::playerDataExists(const std::string &playername) +{ + verifyDatabase(); + + const char *values[] = { playername.c_str() }; + PGresult *results = execPrepared("load_player", 1, values, false); + + bool res = (PQntuples(results) > 0); + PQclear(results); + return res; +} + +void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player) +{ + PlayerSAO* sao = player->getPlayerSAO(); + if (!sao) + return; + + verifyDatabase(); + + v3f pos = sao->getBasePosition(); + std::string pitch = ftos(sao->getLookPitch()); + std::string yaw = ftos(sao->getRotation().Y); + std::string posx = ftos(pos.X); + std::string posy = ftos(pos.Y); + std::string posz = ftos(pos.Z); + std::string hp = itos(sao->getHP()); + std::string breath = itos(sao->getBreath()); + const char *values[] = { + player->getName(), + pitch.c_str(), + yaw.c_str(), + posx.c_str(), posy.c_str(), posz.c_str(), + hp.c_str(), + breath.c_str() + }; + + const char* rmvalues[] = { player->getName() }; + beginSave(); + + if (getPGVersion() < 90500) { + if (!playerDataExists(player->getName())) + execPrepared("create_player", 8, values, true, false); + else + execPrepared("update_player", 8, values, true, false); + } + else + execPrepared("save_player", 8, values, true, false); + + // Write player inventories + execPrepared("remove_player_inventories", 1, rmvalues); + execPrepared("remove_player_inventory_items", 1, rmvalues); + + const auto &inventory_lists = sao->getInventory()->getLists(); + std::ostringstream oss; + for (u16 i = 0; i < inventory_lists.size(); i++) { + const InventoryList* list = inventory_lists[i]; + const std::string &name = list->getName(); + std::string width = itos(list->getWidth()), + inv_id = itos(i), lsize = itos(list->getSize()); + + const char* inv_values[] = { + player->getName(), + inv_id.c_str(), + width.c_str(), + name.c_str(), + lsize.c_str() + }; + execPrepared("add_player_inventory", 5, inv_values); + + for (u32 j = 0; j < list->getSize(); j++) { + oss.str(""); + oss.clear(); + list->getItem(j).serialize(oss); + std::string itemStr = oss.str(), slotId = itos(j); + + const char* invitem_values[] = { + player->getName(), + inv_id.c_str(), + slotId.c_str(), + itemStr.c_str() + }; + execPrepared("add_player_inventory_item", 4, invitem_values); + } + } + + execPrepared("remove_player_metadata", 1, rmvalues); + const StringMap &attrs = sao->getMeta().getStrings(); + for (const auto &attr : attrs) { + const char *meta_values[] = { + player->getName(), + attr.first.c_str(), + attr.second.c_str() + }; + execPrepared("save_player_metadata", 3, meta_values); + } + endSave(); + + player->onSuccessfulSave(); +} + +bool PlayerDatabasePostgreSQL::loadPlayer(RemotePlayer *player, PlayerSAO *sao) +{ + sanity_check(sao); + verifyDatabase(); + + const char *values[] = { player->getName() }; + PGresult *results = execPrepared("load_player", 1, values, false, false); + + // Player not found, return not found + if (!PQntuples(results)) { + PQclear(results); + return false; + } + + sao->setLookPitch(pg_to_float(results, 0, 0)); + sao->setRotation(v3f(0, pg_to_float(results, 0, 1), 0)); + sao->setBasePosition(v3f( + pg_to_float(results, 0, 2), + pg_to_float(results, 0, 3), + pg_to_float(results, 0, 4)) + ); + sao->setHPRaw((u16) pg_to_int(results, 0, 5)); + sao->setBreath((u16) pg_to_int(results, 0, 6), false); + + PQclear(results); + + // Load inventory + results = execPrepared("load_player_inventories", 1, values, false, false); + + int resultCount = PQntuples(results); + + for (int row = 0; row < resultCount; ++row) { + InventoryList* invList = player->inventory. + addList(PQgetvalue(results, row, 2), pg_to_uint(results, row, 3)); + invList->setWidth(pg_to_uint(results, row, 1)); + + u32 invId = pg_to_uint(results, row, 0); + std::string invIdStr = itos(invId); + + const char* values2[] = { + player->getName(), + invIdStr.c_str() + }; + PGresult *results2 = execPrepared("load_player_inventory_items", 2, + values2, false, false); + + int resultCount2 = PQntuples(results2); + for (int row2 = 0; row2 < resultCount2; row2++) { + const std::string itemStr = PQgetvalue(results2, row2, 1); + if (itemStr.length() > 0) { + ItemStack stack; + stack.deSerialize(itemStr); + invList->changeItem(pg_to_uint(results2, row2, 0), stack); + } + } + PQclear(results2); + } + + PQclear(results); + + results = execPrepared("load_player_metadata", 1, values, false); + + int numrows = PQntuples(results); + for (int row = 0; row < numrows; row++) { + sao->getMeta().setString(PQgetvalue(results, row, 0), PQgetvalue(results, row, 1)); + } + sao->getMeta().setModified(false); + + PQclear(results); + + return true; +} + +bool PlayerDatabasePostgreSQL::removePlayer(const std::string &name) +{ + if (!playerDataExists(name)) + return false; + + verifyDatabase(); + + const char *values[] = { name.c_str() }; + execPrepared("remove_player", 1, values); + + return true; +} + +void PlayerDatabasePostgreSQL::listPlayers(std::vector<std::string> &res) +{ + verifyDatabase(); + + PGresult *results = execPrepared("load_player_list", 0, NULL, false); + + int numrows = PQntuples(results); + for (int row = 0; row < numrows; row++) + res.emplace_back(PQgetvalue(results, row, 0)); + + PQclear(results); +} + +AuthDatabasePostgreSQL::AuthDatabasePostgreSQL(const std::string &connect_string) : + Database_PostgreSQL(connect_string, "_auth"), + AuthDatabase() +{ + connectToDatabase(); +} + +void AuthDatabasePostgreSQL::createDatabase() +{ + createTableIfNotExists("auth", + "CREATE TABLE auth (" + "id SERIAL," + "name TEXT UNIQUE," + "password TEXT," + "last_login INT NOT NULL DEFAULT 0," + "PRIMARY KEY (id)" + ");"); + + createTableIfNotExists("user_privileges", + "CREATE TABLE user_privileges (" + "id INT," + "privilege TEXT," + "PRIMARY KEY (id, privilege)," + "CONSTRAINT fk_id FOREIGN KEY (id) REFERENCES auth (id) ON DELETE CASCADE" + ");"); +} + +void AuthDatabasePostgreSQL::initStatements() +{ + prepareStatement("auth_read", "SELECT id, name, password, last_login FROM auth WHERE name = $1"); + prepareStatement("auth_write", "UPDATE auth SET name = $1, password = $2, last_login = $3 WHERE id = $4"); + prepareStatement("auth_create", "INSERT INTO auth (name, password, last_login) VALUES ($1, $2, $3) RETURNING id"); + prepareStatement("auth_delete", "DELETE FROM auth WHERE name = $1"); + + prepareStatement("auth_list_names", "SELECT name FROM auth ORDER BY name DESC"); + + prepareStatement("auth_read_privs", "SELECT privilege FROM user_privileges WHERE id = $1"); + prepareStatement("auth_write_privs", "INSERT INTO user_privileges (id, privilege) VALUES ($1, $2)"); + prepareStatement("auth_delete_privs", "DELETE FROM user_privileges WHERE id = $1"); +} + +bool AuthDatabasePostgreSQL::getAuth(const std::string &name, AuthEntry &res) +{ + verifyDatabase(); + + const char *values[] = { name.c_str() }; + PGresult *result = execPrepared("auth_read", 1, values, false, false); + int numrows = PQntuples(result); + if (numrows == 0) { + PQclear(result); + return false; + } + + res.id = pg_to_uint(result, 0, 0); + res.name = std::string(PQgetvalue(result, 0, 1), PQgetlength(result, 0, 1)); + res.password = std::string(PQgetvalue(result, 0, 2), PQgetlength(result, 0, 2)); + res.last_login = pg_to_int(result, 0, 3); + + PQclear(result); + + std::string playerIdStr = itos(res.id); + const char *privsValues[] = { playerIdStr.c_str() }; + PGresult *results = execPrepared("auth_read_privs", 1, privsValues, false); + + numrows = PQntuples(results); + for (int row = 0; row < numrows; row++) + res.privileges.emplace_back(PQgetvalue(results, row, 0)); + + PQclear(results); + + return true; +} + +bool AuthDatabasePostgreSQL::saveAuth(const AuthEntry &authEntry) +{ + verifyDatabase(); + + beginSave(); + + std::string lastLoginStr = itos(authEntry.last_login); + std::string idStr = itos(authEntry.id); + const char *values[] = { + authEntry.name.c_str() , + authEntry.password.c_str(), + lastLoginStr.c_str(), + idStr.c_str(), + }; + execPrepared("auth_write", 4, values); + + writePrivileges(authEntry); + + endSave(); + return true; +} + +bool AuthDatabasePostgreSQL::createAuth(AuthEntry &authEntry) +{ + verifyDatabase(); + + std::string lastLoginStr = itos(authEntry.last_login); + const char *values[] = { + authEntry.name.c_str() , + authEntry.password.c_str(), + lastLoginStr.c_str() + }; + + beginSave(); + + PGresult *result = execPrepared("auth_create", 3, values, false, false); + + int numrows = PQntuples(result); + if (numrows == 0) { + errorstream << "Strange behaviour on auth creation, no ID returned." << std::endl; + PQclear(result); + rollback(); + return false; + } + + authEntry.id = pg_to_uint(result, 0, 0); + PQclear(result); + + writePrivileges(authEntry); + + endSave(); + return true; +} + +bool AuthDatabasePostgreSQL::deleteAuth(const std::string &name) +{ + verifyDatabase(); + + const char *values[] = { name.c_str() }; + execPrepared("auth_delete", 1, values); + + // privileges deleted by foreign key on delete cascade + return true; +} + +void AuthDatabasePostgreSQL::listNames(std::vector<std::string> &res) +{ + verifyDatabase(); + + PGresult *results = execPrepared("auth_list_names", 0, + NULL, NULL, NULL, false, false); + + int numrows = PQntuples(results); + + for (int row = 0; row < numrows; ++row) + res.emplace_back(PQgetvalue(results, row, 0)); + + PQclear(results); +} + +void AuthDatabasePostgreSQL::reload() +{ + // noop for PgSQL +} + +void AuthDatabasePostgreSQL::writePrivileges(const AuthEntry &authEntry) +{ + std::string authIdStr = itos(authEntry.id); + const char *values[] = { authIdStr.c_str() }; + execPrepared("auth_delete_privs", 1, values); + + for (const std::string &privilege : authEntry.privileges) { + const char *values[] = { authIdStr.c_str(), privilege.c_str() }; + execPrepared("auth_write_privs", 2, values); + } +} + + +#endif // USE_POSTGRESQL diff --git a/src/database/database-postgresql.h b/src/database/database-postgresql.h new file mode 100644 index 0000000..0a9ead0 --- /dev/null +++ b/src/database/database-postgresql.h @@ -0,0 +1,171 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <libpq-fe.h> +#include "database.h" +#include "util/basic_macros.h" + +class Settings; + +class Database_PostgreSQL: public Database +{ +public: + Database_PostgreSQL(const std::string &connect_string, const char *type); + ~Database_PostgreSQL(); + + void beginSave(); + void endSave(); + void rollback(); + + bool initialized() const; + + +protected: + // Conversion helpers + inline int pg_to_int(PGresult *res, int row, int col) + { + return atoi(PQgetvalue(res, row, col)); + } + + inline u32 pg_to_uint(PGresult *res, int row, int col) + { + return (u32) atoi(PQgetvalue(res, row, col)); + } + + inline float pg_to_float(PGresult *res, int row, int col) + { + return (float) atof(PQgetvalue(res, row, col)); + } + + inline v3s16 pg_to_v3s16(PGresult *res, int row, int col) + { + return v3s16( + pg_to_int(res, row, col), + pg_to_int(res, row, col + 1), + pg_to_int(res, row, col + 2) + ); + } + + inline PGresult *execPrepared(const char *stmtName, const int paramsNumber, + const void **params, + const int *paramsLengths = NULL, const int *paramsFormats = NULL, + bool clear = true, bool nobinary = true) + { + return checkResults(PQexecPrepared(m_conn, stmtName, paramsNumber, + (const char* const*) params, paramsLengths, paramsFormats, + nobinary ? 1 : 0), clear); + } + + inline PGresult *execPrepared(const char *stmtName, const int paramsNumber, + const char **params, bool clear = true, bool nobinary = true) + { + return execPrepared(stmtName, paramsNumber, + (const void **)params, NULL, NULL, clear, nobinary); + } + + void createTableIfNotExists(const std::string &table_name, const std::string &definition); + void verifyDatabase(); + + // Database initialization + void connectToDatabase(); + virtual void createDatabase() = 0; + virtual void initStatements() = 0; + inline void prepareStatement(const std::string &name, const std::string &sql) + { + checkResults(PQprepare(m_conn, name.c_str(), sql.c_str(), 0, NULL)); + } + + int getPGVersion() const { return m_pgversion; } + +private: + // Database connectivity checks + void ping(); + + // Database usage + PGresult *checkResults(PGresult *res, bool clear = true); + + // Attributes + std::string m_connect_string; + PGconn *m_conn = nullptr; + int m_pgversion = 0; +}; + +class MapDatabasePostgreSQL : private Database_PostgreSQL, public MapDatabase +{ +public: + MapDatabasePostgreSQL(const std::string &connect_string); + virtual ~MapDatabasePostgreSQL() = default; + + bool saveBlock(const v3s16 &pos, const std::string &data); + void loadBlock(const v3s16 &pos, std::string *block); + bool deleteBlock(const v3s16 &pos); + void listAllLoadableBlocks(std::vector<v3s16> &dst); + + void beginSave() { Database_PostgreSQL::beginSave(); } + void endSave() { Database_PostgreSQL::endSave(); } + +protected: + virtual void createDatabase(); + virtual void initStatements(); +}; + +class PlayerDatabasePostgreSQL : private Database_PostgreSQL, public PlayerDatabase +{ +public: + PlayerDatabasePostgreSQL(const std::string &connect_string); + virtual ~PlayerDatabasePostgreSQL() = default; + + void savePlayer(RemotePlayer *player); + bool loadPlayer(RemotePlayer *player, PlayerSAO *sao); + bool removePlayer(const std::string &name); + void listPlayers(std::vector<std::string> &res); + +protected: + virtual void createDatabase(); + virtual void initStatements(); + +private: + bool playerDataExists(const std::string &playername); +}; + +class AuthDatabasePostgreSQL : private Database_PostgreSQL, public AuthDatabase +{ +public: + AuthDatabasePostgreSQL(const std::string &connect_string); + virtual ~AuthDatabasePostgreSQL() = default; + + virtual void verifyDatabase() { Database_PostgreSQL::verifyDatabase(); } + + virtual bool getAuth(const std::string &name, AuthEntry &res); + virtual bool saveAuth(const AuthEntry &authEntry); + virtual bool createAuth(AuthEntry &authEntry); + virtual bool deleteAuth(const std::string &name); + virtual void listNames(std::vector<std::string> &res); + virtual void reload(); + +protected: + virtual void createDatabase(); + virtual void initStatements(); + +private: + virtual void writePrivileges(const AuthEntry &authEntry); +}; diff --git a/src/database/database-redis.cpp b/src/database/database-redis.cpp new file mode 100644 index 0000000..5ffff67 --- /dev/null +++ b/src/database/database-redis.cpp @@ -0,0 +1,201 @@ +/* +Minetest +Copyright (C) 2014 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "config.h" + +#if USE_REDIS + +#include "database-redis.h" + +#include "settings.h" +#include "log.h" +#include "exceptions.h" +#include "util/string.h" + +#include <hiredis.h> +#include <cassert> + + +Database_Redis::Database_Redis(Settings &conf) +{ + std::string tmp; + try { + tmp = conf.get("redis_address"); + hash = conf.get("redis_hash"); + } catch (SettingNotFoundException &) { + throw SettingNotFoundException("Set redis_address and " + "redis_hash in world.mt to use the redis backend"); + } + const char *addr = tmp.c_str(); + int port = conf.exists("redis_port") ? conf.getU16("redis_port") : 6379; + // if redis_address contains '/' assume unix socket, else hostname/ip + ctx = tmp.find('/') != std::string::npos ? redisConnectUnix(addr) : redisConnect(addr, port); + if (!ctx) { + throw DatabaseException("Cannot allocate redis context"); + } else if (ctx->err) { + std::string err = std::string("Connection error: ") + ctx->errstr; + redisFree(ctx); + throw DatabaseException(err); + } + if (conf.exists("redis_password")) { + tmp = conf.get("redis_password"); + redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "AUTH %s", tmp.c_str())); + if (!reply) + throw DatabaseException("Redis authentication failed"); + if (reply->type == REDIS_REPLY_ERROR) { + std::string err = "Redis authentication failed: " + std::string(reply->str, reply->len); + freeReplyObject(reply); + throw DatabaseException(err); + } + freeReplyObject(reply); + } +} + +Database_Redis::~Database_Redis() +{ + redisFree(ctx); +} + +void Database_Redis::beginSave() { + redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "MULTI")); + if (!reply) { + throw DatabaseException(std::string( + "Redis command 'MULTI' failed: ") + ctx->errstr); + } + freeReplyObject(reply); +} + +void Database_Redis::endSave() { + redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "EXEC")); + if (!reply) { + throw DatabaseException(std::string( + "Redis command 'EXEC' failed: ") + ctx->errstr); + } + freeReplyObject(reply); +} + +bool Database_Redis::saveBlock(const v3s16 &pos, const std::string &data) +{ + std::string tmp = i64tos(getBlockAsInteger(pos)); + + redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "HSET %s %s %b", + hash.c_str(), tmp.c_str(), data.c_str(), data.size())); + if (!reply) { + warningstream << "saveBlock: redis command 'HSET' failed on " + "block " << PP(pos) << ": " << ctx->errstr << std::endl; + freeReplyObject(reply); + return false; + } + + if (reply->type == REDIS_REPLY_ERROR) { + warningstream << "saveBlock: saving block " << PP(pos) + << " failed: " << std::string(reply->str, reply->len) << std::endl; + freeReplyObject(reply); + return false; + } + + freeReplyObject(reply); + return true; +} + +void Database_Redis::loadBlock(const v3s16 &pos, std::string *block) +{ + std::string tmp = i64tos(getBlockAsInteger(pos)); + redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, + "HGET %s %s", hash.c_str(), tmp.c_str())); + + if (!reply) { + throw DatabaseException(std::string( + "Redis command 'HGET %s %s' failed: ") + ctx->errstr); + } + + switch (reply->type) { + case REDIS_REPLY_STRING: { + block->assign(reply->str, reply->len); + freeReplyObject(reply); + return; + } + case REDIS_REPLY_ERROR: { + std::string errstr(reply->str, reply->len); + freeReplyObject(reply); + errorstream << "loadBlock: loading block " << PP(pos) + << " failed: " << errstr << std::endl; + throw DatabaseException(std::string( + "Redis command 'HGET %s %s' errored: ") + errstr); + } + case REDIS_REPLY_NIL: { + block->clear(); + freeReplyObject(reply); + return; + } + } + + errorstream << "loadBlock: loading block " << PP(pos) + << " returned invalid reply type " << reply->type + << ": " << std::string(reply->str, reply->len) << std::endl; + freeReplyObject(reply); + throw DatabaseException(std::string( + "Redis command 'HGET %s %s' gave invalid reply.")); +} + +bool Database_Redis::deleteBlock(const v3s16 &pos) +{ + std::string tmp = i64tos(getBlockAsInteger(pos)); + + redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, + "HDEL %s %s", hash.c_str(), tmp.c_str())); + if (!reply) { + throw DatabaseException(std::string( + "Redis command 'HDEL %s %s' failed: ") + ctx->errstr); + } else if (reply->type == REDIS_REPLY_ERROR) { + warningstream << "deleteBlock: deleting block " << PP(pos) + << " failed: " << std::string(reply->str, reply->len) << std::endl; + freeReplyObject(reply); + return false; + } + + freeReplyObject(reply); + return true; +} + +void Database_Redis::listAllLoadableBlocks(std::vector<v3s16> &dst) +{ + redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "HKEYS %s", hash.c_str())); + if (!reply) { + throw DatabaseException(std::string( + "Redis command 'HKEYS %s' failed: ") + ctx->errstr); + } + switch (reply->type) { + case REDIS_REPLY_ARRAY: + dst.reserve(reply->elements); + for (size_t i = 0; i < reply->elements; i++) { + assert(reply->element[i]->type == REDIS_REPLY_STRING); + dst.push_back(getIntegerAsBlock(stoi64(reply->element[i]->str))); + } + break; + case REDIS_REPLY_ERROR: + throw DatabaseException(std::string( + "Failed to get keys from database: ") + + std::string(reply->str, reply->len)); + } + freeReplyObject(reply); +} + +#endif // USE_REDIS + diff --git a/src/database/database-redis.h b/src/database/database-redis.h new file mode 100644 index 0000000..6bea563 --- /dev/null +++ b/src/database/database-redis.h @@ -0,0 +1,51 @@ +/* +Minetest +Copyright (C) 2014 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "config.h" + +#if USE_REDIS + +#include <hiredis.h> +#include <string> +#include "database.h" + +class Settings; + +class Database_Redis : public MapDatabase +{ +public: + Database_Redis(Settings &conf); + ~Database_Redis(); + + void beginSave(); + void endSave(); + + bool saveBlock(const v3s16 &pos, const std::string &data); + void loadBlock(const v3s16 &pos, std::string *block); + bool deleteBlock(const v3s16 &pos); + void listAllLoadableBlocks(std::vector<v3s16> &dst); + +private: + redisContext *ctx = nullptr; + std::string hash = ""; +}; + +#endif // USE_REDIS diff --git a/src/database/database-sqlite3.cpp b/src/database/database-sqlite3.cpp new file mode 100644 index 0000000..9521085 --- /dev/null +++ b/src/database/database-sqlite3.cpp @@ -0,0 +1,869 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/* +SQLite format specification: + blocks: + (PK) INT id + BLOB data +*/ + + +#include "database-sqlite3.h" + +#include "log.h" +#include "filesys.h" +#include "exceptions.h" +#include "settings.h" +#include "porting.h" +#include "util/string.h" +#include "remoteplayer.h" +#include "server/player_sao.h" + +#include <cassert> + +// When to print messages when the database is being held locked by another process +// Note: I've seen occasional delays of over 250ms while running minetestmapper. +#define BUSY_INFO_TRESHOLD 100 // Print first informational message after 100ms. +#define BUSY_WARNING_TRESHOLD 250 // Print warning message after 250ms. Lag is increased. +#define BUSY_ERROR_TRESHOLD 1000 // Print error message after 1000ms. Significant lag. +#define BUSY_FATAL_TRESHOLD 3000 // Allow SQLITE_BUSY to be returned, which will cause a minetest crash. +#define BUSY_ERROR_INTERVAL 10000 // Safety net: report again every 10 seconds + + +#define SQLRES(s, r, m) \ + if ((s) != (r)) { \ + throw DatabaseException(std::string(m) + ": " +\ + sqlite3_errmsg(m_database)); \ + } +#define SQLOK(s, m) SQLRES(s, SQLITE_OK, m) + +#define PREPARE_STATEMENT(name, query) \ + SQLOK(sqlite3_prepare_v2(m_database, query, -1, &m_stmt_##name, NULL),\ + "Failed to prepare query '" query "'") + +#define SQLOK_ERRSTREAM(s, m) \ + if ((s) != SQLITE_OK) { \ + errorstream << (m) << ": " \ + << sqlite3_errmsg(m_database) << std::endl; \ + } + +#define FINALIZE_STATEMENT(statement) SQLOK_ERRSTREAM(sqlite3_finalize(statement), \ + "Failed to finalize " #statement) + +int Database_SQLite3::busyHandler(void *data, int count) +{ + s64 &first_time = reinterpret_cast<s64 *>(data)[0]; + s64 &prev_time = reinterpret_cast<s64 *>(data)[1]; + s64 cur_time = porting::getTimeMs(); + + if (count == 0) { + first_time = cur_time; + prev_time = first_time; + } else { + while (cur_time < prev_time) + cur_time += s64(1)<<32; + } + + if (cur_time - first_time < BUSY_INFO_TRESHOLD) { + ; // do nothing + } else if (cur_time - first_time >= BUSY_INFO_TRESHOLD && + prev_time - first_time < BUSY_INFO_TRESHOLD) { + infostream << "SQLite3 database has been locked for " + << cur_time - first_time << " ms." << std::endl; + } else if (cur_time - first_time >= BUSY_WARNING_TRESHOLD && + prev_time - first_time < BUSY_WARNING_TRESHOLD) { + warningstream << "SQLite3 database has been locked for " + << cur_time - first_time << " ms." << std::endl; + } else if (cur_time - first_time >= BUSY_ERROR_TRESHOLD && + prev_time - first_time < BUSY_ERROR_TRESHOLD) { + errorstream << "SQLite3 database has been locked for " + << cur_time - first_time << " ms; this causes lag." << std::endl; + } else if (cur_time - first_time >= BUSY_FATAL_TRESHOLD && + prev_time - first_time < BUSY_FATAL_TRESHOLD) { + errorstream << "SQLite3 database has been locked for " + << cur_time - first_time << " ms - giving up!" << std::endl; + } else if ((cur_time - first_time) / BUSY_ERROR_INTERVAL != + (prev_time - first_time) / BUSY_ERROR_INTERVAL) { + // Safety net: keep reporting every BUSY_ERROR_INTERVAL + errorstream << "SQLite3 database has been locked for " + << (cur_time - first_time) / 1000 << " seconds!" << std::endl; + } + + prev_time = cur_time; + + // Make sqlite transaction fail if delay exceeds BUSY_FATAL_TRESHOLD + return cur_time - first_time < BUSY_FATAL_TRESHOLD; +} + + +Database_SQLite3::Database_SQLite3(const std::string &savedir, const std::string &dbname) : + m_savedir(savedir), + m_dbname(dbname) +{ +} + +void Database_SQLite3::beginSave() +{ + verifyDatabase(); + SQLRES(sqlite3_step(m_stmt_begin), SQLITE_DONE, + "Failed to start SQLite3 transaction"); + sqlite3_reset(m_stmt_begin); +} + +void Database_SQLite3::endSave() +{ + verifyDatabase(); + SQLRES(sqlite3_step(m_stmt_end), SQLITE_DONE, + "Failed to commit SQLite3 transaction"); + sqlite3_reset(m_stmt_end); +} + +void Database_SQLite3::openDatabase() +{ + if (m_database) return; + + std::string dbp = m_savedir + DIR_DELIM + m_dbname + ".sqlite"; + + // Open the database connection + + if (!fs::CreateAllDirs(m_savedir)) { + infostream << "Database_SQLite3: Failed to create directory \"" + << m_savedir << "\"" << std::endl; + throw FileNotGoodException("Failed to create database " + "save directory"); + } + + bool needs_create = !fs::PathExists(dbp); + + SQLOK(sqlite3_open_v2(dbp.c_str(), &m_database, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL), + std::string("Failed to open SQLite3 database file ") + dbp); + + SQLOK(sqlite3_busy_handler(m_database, Database_SQLite3::busyHandler, + m_busy_handler_data), "Failed to set SQLite3 busy handler"); + + if (needs_create) { + createDatabase(); + } + + std::string query_str = std::string("PRAGMA synchronous = ") + + itos(g_settings->getU16("sqlite_synchronous")); + SQLOK(sqlite3_exec(m_database, query_str.c_str(), NULL, NULL, NULL), + "Failed to modify sqlite3 synchronous mode"); + SQLOK(sqlite3_exec(m_database, "PRAGMA foreign_keys = ON", NULL, NULL, NULL), + "Failed to enable sqlite3 foreign key support"); +} + +void Database_SQLite3::verifyDatabase() +{ + if (m_initialized) return; + + openDatabase(); + + PREPARE_STATEMENT(begin, "BEGIN;"); + PREPARE_STATEMENT(end, "COMMIT;"); + + initStatements(); + + m_initialized = true; +} + +Database_SQLite3::~Database_SQLite3() +{ + FINALIZE_STATEMENT(m_stmt_begin) + FINALIZE_STATEMENT(m_stmt_end) + + SQLOK_ERRSTREAM(sqlite3_close(m_database), "Failed to close database"); +} + +/* + * Map database + */ + +MapDatabaseSQLite3::MapDatabaseSQLite3(const std::string &savedir): + Database_SQLite3(savedir, "map"), + MapDatabase() +{ +} + +MapDatabaseSQLite3::~MapDatabaseSQLite3() +{ + FINALIZE_STATEMENT(m_stmt_read) + FINALIZE_STATEMENT(m_stmt_write) + FINALIZE_STATEMENT(m_stmt_list) + FINALIZE_STATEMENT(m_stmt_delete) +} + + +void MapDatabaseSQLite3::createDatabase() +{ + assert(m_database); // Pre-condition + + SQLOK(sqlite3_exec(m_database, + "CREATE TABLE IF NOT EXISTS `blocks` (\n" + " `pos` INT PRIMARY KEY,\n" + " `data` BLOB\n" + ");\n", + NULL, NULL, NULL), + "Failed to create database table"); +} + +void MapDatabaseSQLite3::initStatements() +{ + PREPARE_STATEMENT(read, "SELECT `data` FROM `blocks` WHERE `pos` = ? LIMIT 1"); + PREPARE_STATEMENT(write, "REPLACE INTO `blocks` (`pos`, `data`) VALUES (?, ?)"); + PREPARE_STATEMENT(delete, "DELETE FROM `blocks` WHERE `pos` = ?"); + PREPARE_STATEMENT(list, "SELECT `pos` FROM `blocks`"); + + verbosestream << "ServerMap: SQLite3 database opened." << std::endl; +} + +inline void MapDatabaseSQLite3::bindPos(sqlite3_stmt *stmt, const v3s16 &pos, int index) +{ + SQLOK(sqlite3_bind_int64(stmt, index, getBlockAsInteger(pos)), + "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); +} + +bool MapDatabaseSQLite3::deleteBlock(const v3s16 &pos) +{ + verifyDatabase(); + + bindPos(m_stmt_delete, pos); + + bool good = sqlite3_step(m_stmt_delete) == SQLITE_DONE; + sqlite3_reset(m_stmt_delete); + + if (!good) { + warningstream << "deleteBlock: Block failed to delete " + << PP(pos) << ": " << sqlite3_errmsg(m_database) << std::endl; + } + return good; +} + +bool MapDatabaseSQLite3::saveBlock(const v3s16 &pos, const std::string &data) +{ + verifyDatabase(); + + bindPos(m_stmt_write, pos); + SQLOK(sqlite3_bind_blob(m_stmt_write, 2, data.data(), data.size(), NULL), + "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); + + SQLRES(sqlite3_step(m_stmt_write), SQLITE_DONE, "Failed to save block") + sqlite3_reset(m_stmt_write); + + return true; +} + +void MapDatabaseSQLite3::loadBlock(const v3s16 &pos, std::string *block) +{ + verifyDatabase(); + + bindPos(m_stmt_read, pos); + + if (sqlite3_step(m_stmt_read) != SQLITE_ROW) { + sqlite3_reset(m_stmt_read); + return; + } + + const char *data = (const char *) sqlite3_column_blob(m_stmt_read, 0); + size_t len = sqlite3_column_bytes(m_stmt_read, 0); + + if (data) + block->assign(data, len); + else + block->clear(); + + sqlite3_step(m_stmt_read); + // We should never get more than 1 row, so ok to reset + sqlite3_reset(m_stmt_read); +} + +void MapDatabaseSQLite3::listAllLoadableBlocks(std::vector<v3s16> &dst) +{ + verifyDatabase(); + + while (sqlite3_step(m_stmt_list) == SQLITE_ROW) + dst.push_back(getIntegerAsBlock(sqlite3_column_int64(m_stmt_list, 0))); + + sqlite3_reset(m_stmt_list); +} + +/* + * Player Database + */ + +PlayerDatabaseSQLite3::PlayerDatabaseSQLite3(const std::string &savedir): + Database_SQLite3(savedir, "players"), + PlayerDatabase() +{ +} + +PlayerDatabaseSQLite3::~PlayerDatabaseSQLite3() +{ + FINALIZE_STATEMENT(m_stmt_player_load) + FINALIZE_STATEMENT(m_stmt_player_add) + FINALIZE_STATEMENT(m_stmt_player_update) + FINALIZE_STATEMENT(m_stmt_player_remove) + FINALIZE_STATEMENT(m_stmt_player_list) + FINALIZE_STATEMENT(m_stmt_player_add_inventory) + FINALIZE_STATEMENT(m_stmt_player_add_inventory_items) + FINALIZE_STATEMENT(m_stmt_player_remove_inventory) + FINALIZE_STATEMENT(m_stmt_player_remove_inventory_items) + FINALIZE_STATEMENT(m_stmt_player_load_inventory) + FINALIZE_STATEMENT(m_stmt_player_load_inventory_items) + FINALIZE_STATEMENT(m_stmt_player_metadata_load) + FINALIZE_STATEMENT(m_stmt_player_metadata_add) + FINALIZE_STATEMENT(m_stmt_player_metadata_remove) +}; + + +void PlayerDatabaseSQLite3::createDatabase() +{ + assert(m_database); // Pre-condition + + SQLOK(sqlite3_exec(m_database, + "CREATE TABLE IF NOT EXISTS `player` (" + "`name` VARCHAR(50) NOT NULL," + "`pitch` NUMERIC(11, 4) NOT NULL," + "`yaw` NUMERIC(11, 4) NOT NULL," + "`posX` NUMERIC(11, 4) NOT NULL," + "`posY` NUMERIC(11, 4) NOT NULL," + "`posZ` NUMERIC(11, 4) NOT NULL," + "`hp` INT NOT NULL," + "`breath` INT NOT NULL," + "`creation_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP," + "`modification_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP," + "PRIMARY KEY (`name`));", + NULL, NULL, NULL), + "Failed to create player table"); + + SQLOK(sqlite3_exec(m_database, + "CREATE TABLE IF NOT EXISTS `player_metadata` (" + " `player` VARCHAR(50) NOT NULL," + " `metadata` VARCHAR(256) NOT NULL," + " `value` TEXT," + " PRIMARY KEY(`player`, `metadata`)," + " FOREIGN KEY (`player`) REFERENCES player (`name`) ON DELETE CASCADE );", + NULL, NULL, NULL), + "Failed to create player metadata table"); + + SQLOK(sqlite3_exec(m_database, + "CREATE TABLE IF NOT EXISTS `player_inventories` (" + " `player` VARCHAR(50) NOT NULL," + " `inv_id` INT NOT NULL," + " `inv_width` INT NOT NULL," + " `inv_name` TEXT NOT NULL DEFAULT ''," + " `inv_size` INT NOT NULL," + " PRIMARY KEY(player, inv_id)," + " FOREIGN KEY (`player`) REFERENCES player (`name`) ON DELETE CASCADE );", + NULL, NULL, NULL), + "Failed to create player inventory table"); + + SQLOK(sqlite3_exec(m_database, + "CREATE TABLE `player_inventory_items` (" + " `player` VARCHAR(50) NOT NULL," + " `inv_id` INT NOT NULL," + " `slot_id` INT NOT NULL," + " `item` TEXT NOT NULL DEFAULT ''," + " PRIMARY KEY(player, inv_id, slot_id)," + " FOREIGN KEY (`player`) REFERENCES player (`name`) ON DELETE CASCADE );", + NULL, NULL, NULL), + "Failed to create player inventory items table"); +} + +void PlayerDatabaseSQLite3::initStatements() +{ + PREPARE_STATEMENT(player_load, "SELECT `pitch`, `yaw`, `posX`, `posY`, `posZ`, `hp`, " + "`breath`" + "FROM `player` WHERE `name` = ?") + PREPARE_STATEMENT(player_add, "INSERT INTO `player` (`name`, `pitch`, `yaw`, `posX`, " + "`posY`, `posZ`, `hp`, `breath`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)") + PREPARE_STATEMENT(player_update, "UPDATE `player` SET `pitch` = ?, `yaw` = ?, " + "`posX` = ?, `posY` = ?, `posZ` = ?, `hp` = ?, `breath` = ?, " + "`modification_date` = CURRENT_TIMESTAMP WHERE `name` = ?") + PREPARE_STATEMENT(player_remove, "DELETE FROM `player` WHERE `name` = ?") + PREPARE_STATEMENT(player_list, "SELECT `name` FROM `player`") + + PREPARE_STATEMENT(player_add_inventory, "INSERT INTO `player_inventories` " + "(`player`, `inv_id`, `inv_width`, `inv_name`, `inv_size`) VALUES (?, ?, ?, ?, ?)") + PREPARE_STATEMENT(player_add_inventory_items, "INSERT INTO `player_inventory_items` " + "(`player`, `inv_id`, `slot_id`, `item`) VALUES (?, ?, ?, ?)") + PREPARE_STATEMENT(player_remove_inventory, "DELETE FROM `player_inventories` " + "WHERE `player` = ?") + PREPARE_STATEMENT(player_remove_inventory_items, "DELETE FROM `player_inventory_items` " + "WHERE `player` = ?") + PREPARE_STATEMENT(player_load_inventory, "SELECT `inv_id`, `inv_width`, `inv_name`, " + "`inv_size` FROM `player_inventories` WHERE `player` = ? ORDER BY inv_id") + PREPARE_STATEMENT(player_load_inventory_items, "SELECT `slot_id`, `item` " + "FROM `player_inventory_items` WHERE `player` = ? AND `inv_id` = ?") + + PREPARE_STATEMENT(player_metadata_load, "SELECT `metadata`, `value` FROM " + "`player_metadata` WHERE `player` = ?") + PREPARE_STATEMENT(player_metadata_add, "INSERT INTO `player_metadata` " + "(`player`, `metadata`, `value`) VALUES (?, ?, ?)") + PREPARE_STATEMENT(player_metadata_remove, "DELETE FROM `player_metadata` " + "WHERE `player` = ?") + verbosestream << "ServerEnvironment: SQLite3 database opened (players)." << std::endl; +} + +bool PlayerDatabaseSQLite3::playerDataExists(const std::string &name) +{ + verifyDatabase(); + str_to_sqlite(m_stmt_player_load, 1, name); + bool res = (sqlite3_step(m_stmt_player_load) == SQLITE_ROW); + sqlite3_reset(m_stmt_player_load); + return res; +} + +void PlayerDatabaseSQLite3::savePlayer(RemotePlayer *player) +{ + PlayerSAO* sao = player->getPlayerSAO(); + sanity_check(sao); + + const v3f &pos = sao->getBasePosition(); + // Begin save in brace is mandatory + if (!playerDataExists(player->getName())) { + beginSave(); + str_to_sqlite(m_stmt_player_add, 1, player->getName()); + double_to_sqlite(m_stmt_player_add, 2, sao->getLookPitch()); + double_to_sqlite(m_stmt_player_add, 3, sao->getRotation().Y); + double_to_sqlite(m_stmt_player_add, 4, pos.X); + double_to_sqlite(m_stmt_player_add, 5, pos.Y); + double_to_sqlite(m_stmt_player_add, 6, pos.Z); + int64_to_sqlite(m_stmt_player_add, 7, sao->getHP()); + int64_to_sqlite(m_stmt_player_add, 8, sao->getBreath()); + + sqlite3_vrfy(sqlite3_step(m_stmt_player_add), SQLITE_DONE); + sqlite3_reset(m_stmt_player_add); + } else { + beginSave(); + double_to_sqlite(m_stmt_player_update, 1, sao->getLookPitch()); + double_to_sqlite(m_stmt_player_update, 2, sao->getRotation().Y); + double_to_sqlite(m_stmt_player_update, 3, pos.X); + double_to_sqlite(m_stmt_player_update, 4, pos.Y); + double_to_sqlite(m_stmt_player_update, 5, pos.Z); + int64_to_sqlite(m_stmt_player_update, 6, sao->getHP()); + int64_to_sqlite(m_stmt_player_update, 7, sao->getBreath()); + str_to_sqlite(m_stmt_player_update, 8, player->getName()); + + sqlite3_vrfy(sqlite3_step(m_stmt_player_update), SQLITE_DONE); + sqlite3_reset(m_stmt_player_update); + } + + // Write player inventories + str_to_sqlite(m_stmt_player_remove_inventory, 1, player->getName()); + sqlite3_vrfy(sqlite3_step(m_stmt_player_remove_inventory), SQLITE_DONE); + sqlite3_reset(m_stmt_player_remove_inventory); + + str_to_sqlite(m_stmt_player_remove_inventory_items, 1, player->getName()); + sqlite3_vrfy(sqlite3_step(m_stmt_player_remove_inventory_items), SQLITE_DONE); + sqlite3_reset(m_stmt_player_remove_inventory_items); + + const auto &inventory_lists = sao->getInventory()->getLists(); + std::ostringstream oss; + for (u16 i = 0; i < inventory_lists.size(); i++) { + const InventoryList *list = inventory_lists[i]; + + str_to_sqlite(m_stmt_player_add_inventory, 1, player->getName()); + int_to_sqlite(m_stmt_player_add_inventory, 2, i); + int_to_sqlite(m_stmt_player_add_inventory, 3, list->getWidth()); + str_to_sqlite(m_stmt_player_add_inventory, 4, list->getName()); + int_to_sqlite(m_stmt_player_add_inventory, 5, list->getSize()); + sqlite3_vrfy(sqlite3_step(m_stmt_player_add_inventory), SQLITE_DONE); + sqlite3_reset(m_stmt_player_add_inventory); + + for (u32 j = 0; j < list->getSize(); j++) { + oss.str(""); + oss.clear(); + list->getItem(j).serialize(oss); + std::string itemStr = oss.str(); + + str_to_sqlite(m_stmt_player_add_inventory_items, 1, player->getName()); + int_to_sqlite(m_stmt_player_add_inventory_items, 2, i); + int_to_sqlite(m_stmt_player_add_inventory_items, 3, j); + str_to_sqlite(m_stmt_player_add_inventory_items, 4, itemStr); + sqlite3_vrfy(sqlite3_step(m_stmt_player_add_inventory_items), SQLITE_DONE); + sqlite3_reset(m_stmt_player_add_inventory_items); + } + } + + str_to_sqlite(m_stmt_player_metadata_remove, 1, player->getName()); + sqlite3_vrfy(sqlite3_step(m_stmt_player_metadata_remove), SQLITE_DONE); + sqlite3_reset(m_stmt_player_metadata_remove); + + const StringMap &attrs = sao->getMeta().getStrings(); + for (const auto &attr : attrs) { + str_to_sqlite(m_stmt_player_metadata_add, 1, player->getName()); + str_to_sqlite(m_stmt_player_metadata_add, 2, attr.first); + str_to_sqlite(m_stmt_player_metadata_add, 3, attr.second); + sqlite3_vrfy(sqlite3_step(m_stmt_player_metadata_add), SQLITE_DONE); + sqlite3_reset(m_stmt_player_metadata_add); + } + + endSave(); + + player->onSuccessfulSave(); +} + +bool PlayerDatabaseSQLite3::loadPlayer(RemotePlayer *player, PlayerSAO *sao) +{ + verifyDatabase(); + + str_to_sqlite(m_stmt_player_load, 1, player->getName()); + if (sqlite3_step(m_stmt_player_load) != SQLITE_ROW) { + sqlite3_reset(m_stmt_player_load); + return false; + } + sao->setLookPitch(sqlite_to_float(m_stmt_player_load, 0)); + sao->setPlayerYaw(sqlite_to_float(m_stmt_player_load, 1)); + sao->setBasePosition(sqlite_to_v3f(m_stmt_player_load, 2)); + sao->setHPRaw((u16) MYMIN(sqlite_to_int(m_stmt_player_load, 5), U16_MAX)); + sao->setBreath((u16) MYMIN(sqlite_to_int(m_stmt_player_load, 6), U16_MAX), false); + sqlite3_reset(m_stmt_player_load); + + // Load inventory + str_to_sqlite(m_stmt_player_load_inventory, 1, player->getName()); + while (sqlite3_step(m_stmt_player_load_inventory) == SQLITE_ROW) { + InventoryList *invList = player->inventory.addList( + sqlite_to_string(m_stmt_player_load_inventory, 2), + sqlite_to_uint(m_stmt_player_load_inventory, 3)); + invList->setWidth(sqlite_to_uint(m_stmt_player_load_inventory, 1)); + + u32 invId = sqlite_to_uint(m_stmt_player_load_inventory, 0); + + str_to_sqlite(m_stmt_player_load_inventory_items, 1, player->getName()); + int_to_sqlite(m_stmt_player_load_inventory_items, 2, invId); + while (sqlite3_step(m_stmt_player_load_inventory_items) == SQLITE_ROW) { + const std::string itemStr = sqlite_to_string(m_stmt_player_load_inventory_items, 1); + if (itemStr.length() > 0) { + ItemStack stack; + stack.deSerialize(itemStr); + invList->changeItem(sqlite_to_uint(m_stmt_player_load_inventory_items, 0), stack); + } + } + sqlite3_reset(m_stmt_player_load_inventory_items); + } + + sqlite3_reset(m_stmt_player_load_inventory); + + str_to_sqlite(m_stmt_player_metadata_load, 1, sao->getPlayer()->getName()); + while (sqlite3_step(m_stmt_player_metadata_load) == SQLITE_ROW) { + std::string attr = sqlite_to_string(m_stmt_player_metadata_load, 0); + std::string value = sqlite_to_string(m_stmt_player_metadata_load, 1); + + sao->getMeta().setString(attr, value); + } + sao->getMeta().setModified(false); + sqlite3_reset(m_stmt_player_metadata_load); + return true; +} + +bool PlayerDatabaseSQLite3::removePlayer(const std::string &name) +{ + if (!playerDataExists(name)) + return false; + + str_to_sqlite(m_stmt_player_remove, 1, name); + sqlite3_vrfy(sqlite3_step(m_stmt_player_remove), SQLITE_DONE); + sqlite3_reset(m_stmt_player_remove); + return true; +} + +void PlayerDatabaseSQLite3::listPlayers(std::vector<std::string> &res) +{ + verifyDatabase(); + + while (sqlite3_step(m_stmt_player_list) == SQLITE_ROW) + res.push_back(sqlite_to_string(m_stmt_player_list, 0)); + + sqlite3_reset(m_stmt_player_list); +} + +/* + * Auth database + */ + +AuthDatabaseSQLite3::AuthDatabaseSQLite3(const std::string &savedir) : + Database_SQLite3(savedir, "auth"), AuthDatabase() +{ +} + +AuthDatabaseSQLite3::~AuthDatabaseSQLite3() +{ + FINALIZE_STATEMENT(m_stmt_read) + FINALIZE_STATEMENT(m_stmt_write) + FINALIZE_STATEMENT(m_stmt_create) + FINALIZE_STATEMENT(m_stmt_delete) + FINALIZE_STATEMENT(m_stmt_list_names) + FINALIZE_STATEMENT(m_stmt_read_privs) + FINALIZE_STATEMENT(m_stmt_write_privs) + FINALIZE_STATEMENT(m_stmt_delete_privs) + FINALIZE_STATEMENT(m_stmt_last_insert_rowid) +} + +void AuthDatabaseSQLite3::createDatabase() +{ + assert(m_database); // Pre-condition + + SQLOK(sqlite3_exec(m_database, + "CREATE TABLE IF NOT EXISTS `auth` (" + "`id` INTEGER PRIMARY KEY AUTOINCREMENT," + "`name` VARCHAR(32) UNIQUE," + "`password` VARCHAR(512)," + "`last_login` INTEGER" + ");", + NULL, NULL, NULL), + "Failed to create auth table"); + + SQLOK(sqlite3_exec(m_database, + "CREATE TABLE IF NOT EXISTS `user_privileges` (" + "`id` INTEGER," + "`privilege` VARCHAR(32)," + "PRIMARY KEY (id, privilege)" + "CONSTRAINT fk_id FOREIGN KEY (id) REFERENCES auth (id) ON DELETE CASCADE" + ");", + NULL, NULL, NULL), + "Failed to create auth privileges table"); +} + +void AuthDatabaseSQLite3::initStatements() +{ + PREPARE_STATEMENT(read, "SELECT id, name, password, last_login FROM auth WHERE name = ?"); + PREPARE_STATEMENT(write, "UPDATE auth set name = ?, password = ?, last_login = ? WHERE id = ?"); + PREPARE_STATEMENT(create, "INSERT INTO auth (name, password, last_login) VALUES (?, ?, ?)"); + PREPARE_STATEMENT(delete, "DELETE FROM auth WHERE name = ?"); + + PREPARE_STATEMENT(list_names, "SELECT name FROM auth ORDER BY name DESC"); + + PREPARE_STATEMENT(read_privs, "SELECT privilege FROM user_privileges WHERE id = ?"); + PREPARE_STATEMENT(write_privs, "INSERT OR IGNORE INTO user_privileges (id, privilege) VALUES (?, ?)"); + PREPARE_STATEMENT(delete_privs, "DELETE FROM user_privileges WHERE id = ?"); + + PREPARE_STATEMENT(last_insert_rowid, "SELECT last_insert_rowid()"); +} + +bool AuthDatabaseSQLite3::getAuth(const std::string &name, AuthEntry &res) +{ + verifyDatabase(); + str_to_sqlite(m_stmt_read, 1, name); + if (sqlite3_step(m_stmt_read) != SQLITE_ROW) { + sqlite3_reset(m_stmt_read); + return false; + } + res.id = sqlite_to_uint(m_stmt_read, 0); + res.name = sqlite_to_string(m_stmt_read, 1); + res.password = sqlite_to_string(m_stmt_read, 2); + res.last_login = sqlite_to_int64(m_stmt_read, 3); + sqlite3_reset(m_stmt_read); + + int64_to_sqlite(m_stmt_read_privs, 1, res.id); + while (sqlite3_step(m_stmt_read_privs) == SQLITE_ROW) { + res.privileges.emplace_back(sqlite_to_string(m_stmt_read_privs, 0)); + } + sqlite3_reset(m_stmt_read_privs); + + return true; +} + +bool AuthDatabaseSQLite3::saveAuth(const AuthEntry &authEntry) +{ + beginSave(); + + str_to_sqlite(m_stmt_write, 1, authEntry.name); + str_to_sqlite(m_stmt_write, 2, authEntry.password); + int64_to_sqlite(m_stmt_write, 3, authEntry.last_login); + int64_to_sqlite(m_stmt_write, 4, authEntry.id); + sqlite3_vrfy(sqlite3_step(m_stmt_write), SQLITE_DONE); + sqlite3_reset(m_stmt_write); + + writePrivileges(authEntry); + + endSave(); + return true; +} + +bool AuthDatabaseSQLite3::createAuth(AuthEntry &authEntry) +{ + beginSave(); + + // id autoincrements + str_to_sqlite(m_stmt_create, 1, authEntry.name); + str_to_sqlite(m_stmt_create, 2, authEntry.password); + int64_to_sqlite(m_stmt_create, 3, authEntry.last_login); + sqlite3_vrfy(sqlite3_step(m_stmt_create), SQLITE_DONE); + sqlite3_reset(m_stmt_create); + + // obtain id and write back to original authEntry + sqlite3_step(m_stmt_last_insert_rowid); + authEntry.id = sqlite_to_uint(m_stmt_last_insert_rowid, 0); + sqlite3_reset(m_stmt_last_insert_rowid); + + writePrivileges(authEntry); + + endSave(); + return true; +} + +bool AuthDatabaseSQLite3::deleteAuth(const std::string &name) +{ + verifyDatabase(); + + str_to_sqlite(m_stmt_delete, 1, name); + sqlite3_vrfy(sqlite3_step(m_stmt_delete), SQLITE_DONE); + int changes = sqlite3_changes(m_database); + sqlite3_reset(m_stmt_delete); + + // privileges deleted by foreign key on delete cascade + + return changes > 0; +} + +void AuthDatabaseSQLite3::listNames(std::vector<std::string> &res) +{ + verifyDatabase(); + + while (sqlite3_step(m_stmt_list_names) == SQLITE_ROW) { + res.push_back(sqlite_to_string(m_stmt_list_names, 0)); + } + sqlite3_reset(m_stmt_list_names); +} + +void AuthDatabaseSQLite3::reload() +{ + // noop for SQLite +} + +void AuthDatabaseSQLite3::writePrivileges(const AuthEntry &authEntry) +{ + int64_to_sqlite(m_stmt_delete_privs, 1, authEntry.id); + sqlite3_vrfy(sqlite3_step(m_stmt_delete_privs), SQLITE_DONE); + sqlite3_reset(m_stmt_delete_privs); + for (const std::string &privilege : authEntry.privileges) { + int64_to_sqlite(m_stmt_write_privs, 1, authEntry.id); + str_to_sqlite(m_stmt_write_privs, 2, privilege); + sqlite3_vrfy(sqlite3_step(m_stmt_write_privs), SQLITE_DONE); + sqlite3_reset(m_stmt_write_privs); + } +} + +ModMetadataDatabaseSQLite3::ModMetadataDatabaseSQLite3(const std::string &savedir): + Database_SQLite3(savedir, "mod_storage"), ModMetadataDatabase() +{ +} + +ModMetadataDatabaseSQLite3::~ModMetadataDatabaseSQLite3() +{ + FINALIZE_STATEMENT(m_stmt_remove) + FINALIZE_STATEMENT(m_stmt_set) + FINALIZE_STATEMENT(m_stmt_get) +} + +void ModMetadataDatabaseSQLite3::createDatabase() +{ + assert(m_database); // Pre-condition + + SQLOK(sqlite3_exec(m_database, + "CREATE TABLE IF NOT EXISTS `entries` (\n" + " `modname` TEXT NOT NULL,\n" + " `key` BLOB NOT NULL,\n" + " `value` BLOB NOT NULL,\n" + " PRIMARY KEY (`modname`, `key`)\n" + ");\n", + NULL, NULL, NULL), + "Failed to create database table"); +} + +void ModMetadataDatabaseSQLite3::initStatements() +{ + PREPARE_STATEMENT(get, "SELECT `key`, `value` FROM `entries` WHERE `modname` = ?"); + PREPARE_STATEMENT(set, + "REPLACE INTO `entries` (`modname`, `key`, `value`) VALUES (?, ?, ?)"); + PREPARE_STATEMENT(remove, "DELETE FROM `entries` WHERE `modname` = ? AND `key` = ?"); +} + +bool ModMetadataDatabaseSQLite3::getModEntries(const std::string &modname, StringMap *storage) +{ + verifyDatabase(); + + str_to_sqlite(m_stmt_get, 1, modname); + while (sqlite3_step(m_stmt_get) == SQLITE_ROW) { + const char *key_data = (const char *) sqlite3_column_blob(m_stmt_get, 0); + size_t key_len = sqlite3_column_bytes(m_stmt_get, 0); + const char *value_data = (const char *) sqlite3_column_blob(m_stmt_get, 1); + size_t value_len = sqlite3_column_bytes(m_stmt_get, 1); + (*storage)[std::string(key_data, key_len)] = std::string(value_data, value_len); + } + sqlite3_vrfy(sqlite3_errcode(m_database), SQLITE_DONE); + + sqlite3_reset(m_stmt_get); + + return true; +} + +bool ModMetadataDatabaseSQLite3::setModEntry(const std::string &modname, + const std::string &key, const std::string &value) +{ + verifyDatabase(); + + str_to_sqlite(m_stmt_set, 1, modname); + SQLOK(sqlite3_bind_blob(m_stmt_set, 2, key.data(), key.size(), NULL), + "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); + SQLOK(sqlite3_bind_blob(m_stmt_set, 3, value.data(), value.size(), NULL), + "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); + SQLRES(sqlite3_step(m_stmt_set), SQLITE_DONE, "Failed to set mod entry") + + sqlite3_reset(m_stmt_set); + + return true; +} + +bool ModMetadataDatabaseSQLite3::removeModEntry(const std::string &modname, + const std::string &key) +{ + verifyDatabase(); + + str_to_sqlite(m_stmt_remove, 1, modname); + SQLOK(sqlite3_bind_blob(m_stmt_remove, 2, key.data(), key.size(), NULL), + "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); + sqlite3_vrfy(sqlite3_step(m_stmt_remove), SQLITE_DONE); + int changes = sqlite3_changes(m_database); + + sqlite3_reset(m_stmt_remove); + + return changes > 0; +} + +void ModMetadataDatabaseSQLite3::listMods(std::vector<std::string> *res) +{ + verifyDatabase(); + + char *errmsg; + int status = sqlite3_exec(m_database, + "SELECT `modname` FROM `entries` GROUP BY `modname`;", + [](void *res_vp, int n_col, char **cols, char **col_names) -> int { + ((decltype(res)) res_vp)->emplace_back(cols[0]); + return 0; + }, (void *) res, &errmsg); + if (status != SQLITE_OK) { + DatabaseException e(std::string("Error trying to list mods with metadata: ") + errmsg); + sqlite3_free(errmsg); + throw e; + } +} diff --git a/src/database/database-sqlite3.h b/src/database/database-sqlite3.h new file mode 100644 index 0000000..5e3d7c9 --- /dev/null +++ b/src/database/database-sqlite3.h @@ -0,0 +1,259 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <cstring> +#include <string> +#include "database.h" +#include "exceptions.h" + +extern "C" { +#include "sqlite3.h" +} + +class Database_SQLite3 : public Database +{ +public: + virtual ~Database_SQLite3(); + + void beginSave(); + void endSave(); + + bool initialized() const { return m_initialized; } +protected: + Database_SQLite3(const std::string &savedir, const std::string &dbname); + + // Open and initialize the database if needed + void verifyDatabase(); + + // Convertors + inline void str_to_sqlite(sqlite3_stmt *s, int iCol, const std::string &str) const + { + sqlite3_vrfy(sqlite3_bind_text(s, iCol, str.c_str(), str.size(), NULL)); + } + + inline void str_to_sqlite(sqlite3_stmt *s, int iCol, const char *str) const + { + sqlite3_vrfy(sqlite3_bind_text(s, iCol, str, strlen(str), NULL)); + } + + inline void int_to_sqlite(sqlite3_stmt *s, int iCol, int val) const + { + sqlite3_vrfy(sqlite3_bind_int(s, iCol, val)); + } + + inline void int64_to_sqlite(sqlite3_stmt *s, int iCol, s64 val) const + { + sqlite3_vrfy(sqlite3_bind_int64(s, iCol, (sqlite3_int64) val)); + } + + inline void double_to_sqlite(sqlite3_stmt *s, int iCol, double val) const + { + sqlite3_vrfy(sqlite3_bind_double(s, iCol, val)); + } + + inline std::string sqlite_to_string(sqlite3_stmt *s, int iCol) + { + const char* text = reinterpret_cast<const char*>(sqlite3_column_text(s, iCol)); + return std::string(text ? text : ""); + } + + inline s32 sqlite_to_int(sqlite3_stmt *s, int iCol) + { + return sqlite3_column_int(s, iCol); + } + + inline u32 sqlite_to_uint(sqlite3_stmt *s, int iCol) + { + return (u32) sqlite3_column_int(s, iCol); + } + + inline s64 sqlite_to_int64(sqlite3_stmt *s, int iCol) + { + return (s64) sqlite3_column_int64(s, iCol); + } + + inline u64 sqlite_to_uint64(sqlite3_stmt *s, int iCol) + { + return (u64) sqlite3_column_int64(s, iCol); + } + + inline float sqlite_to_float(sqlite3_stmt *s, int iCol) + { + return (float) sqlite3_column_double(s, iCol); + } + + inline const v3f sqlite_to_v3f(sqlite3_stmt *s, int iCol) + { + return v3f(sqlite_to_float(s, iCol), sqlite_to_float(s, iCol + 1), + sqlite_to_float(s, iCol + 2)); + } + + // Query verifiers helpers + inline void sqlite3_vrfy(int s, const std::string &m = "", int r = SQLITE_OK) const + { + if (s != r) + throw DatabaseException(m + ": " + sqlite3_errmsg(m_database)); + } + + inline void sqlite3_vrfy(const int s, const int r, const std::string &m = "") const + { + sqlite3_vrfy(s, m, r); + } + + // Create the database structure + virtual void createDatabase() = 0; + virtual void initStatements() = 0; + + sqlite3 *m_database = nullptr; +private: + // Open the database + void openDatabase(); + + bool m_initialized = false; + + std::string m_savedir = ""; + std::string m_dbname = ""; + + sqlite3_stmt *m_stmt_begin = nullptr; + sqlite3_stmt *m_stmt_end = nullptr; + + s64 m_busy_handler_data[2]; + + static int busyHandler(void *data, int count); +}; + +class MapDatabaseSQLite3 : private Database_SQLite3, public MapDatabase +{ +public: + MapDatabaseSQLite3(const std::string &savedir); + virtual ~MapDatabaseSQLite3(); + + bool saveBlock(const v3s16 &pos, const std::string &data); + void loadBlock(const v3s16 &pos, std::string *block); + bool deleteBlock(const v3s16 &pos); + void listAllLoadableBlocks(std::vector<v3s16> &dst); + + void beginSave() { Database_SQLite3::beginSave(); } + void endSave() { Database_SQLite3::endSave(); } +protected: + virtual void createDatabase(); + virtual void initStatements(); + +private: + void bindPos(sqlite3_stmt *stmt, const v3s16 &pos, int index = 1); + + // Map + sqlite3_stmt *m_stmt_read = nullptr; + sqlite3_stmt *m_stmt_write = nullptr; + sqlite3_stmt *m_stmt_list = nullptr; + sqlite3_stmt *m_stmt_delete = nullptr; +}; + +class PlayerDatabaseSQLite3 : private Database_SQLite3, public PlayerDatabase +{ +public: + PlayerDatabaseSQLite3(const std::string &savedir); + virtual ~PlayerDatabaseSQLite3(); + + void savePlayer(RemotePlayer *player); + bool loadPlayer(RemotePlayer *player, PlayerSAO *sao); + bool removePlayer(const std::string &name); + void listPlayers(std::vector<std::string> &res); + +protected: + virtual void createDatabase(); + virtual void initStatements(); + +private: + bool playerDataExists(const std::string &name); + + // Players + sqlite3_stmt *m_stmt_player_load = nullptr; + sqlite3_stmt *m_stmt_player_add = nullptr; + sqlite3_stmt *m_stmt_player_update = nullptr; + sqlite3_stmt *m_stmt_player_remove = nullptr; + sqlite3_stmt *m_stmt_player_list = nullptr; + sqlite3_stmt *m_stmt_player_load_inventory = nullptr; + sqlite3_stmt *m_stmt_player_load_inventory_items = nullptr; + sqlite3_stmt *m_stmt_player_add_inventory = nullptr; + sqlite3_stmt *m_stmt_player_add_inventory_items = nullptr; + sqlite3_stmt *m_stmt_player_remove_inventory = nullptr; + sqlite3_stmt *m_stmt_player_remove_inventory_items = nullptr; + sqlite3_stmt *m_stmt_player_metadata_load = nullptr; + sqlite3_stmt *m_stmt_player_metadata_remove = nullptr; + sqlite3_stmt *m_stmt_player_metadata_add = nullptr; +}; + +class AuthDatabaseSQLite3 : private Database_SQLite3, public AuthDatabase +{ +public: + AuthDatabaseSQLite3(const std::string &savedir); + virtual ~AuthDatabaseSQLite3(); + + virtual bool getAuth(const std::string &name, AuthEntry &res); + virtual bool saveAuth(const AuthEntry &authEntry); + virtual bool createAuth(AuthEntry &authEntry); + virtual bool deleteAuth(const std::string &name); + virtual void listNames(std::vector<std::string> &res); + virtual void reload(); + +protected: + virtual void createDatabase(); + virtual void initStatements(); + +private: + virtual void writePrivileges(const AuthEntry &authEntry); + + sqlite3_stmt *m_stmt_read = nullptr; + sqlite3_stmt *m_stmt_write = nullptr; + sqlite3_stmt *m_stmt_create = nullptr; + sqlite3_stmt *m_stmt_delete = nullptr; + sqlite3_stmt *m_stmt_list_names = nullptr; + sqlite3_stmt *m_stmt_read_privs = nullptr; + sqlite3_stmt *m_stmt_write_privs = nullptr; + sqlite3_stmt *m_stmt_delete_privs = nullptr; + sqlite3_stmt *m_stmt_last_insert_rowid = nullptr; +}; + +class ModMetadataDatabaseSQLite3 : private Database_SQLite3, public ModMetadataDatabase +{ +public: + ModMetadataDatabaseSQLite3(const std::string &savedir); + virtual ~ModMetadataDatabaseSQLite3(); + + virtual bool getModEntries(const std::string &modname, StringMap *storage); + virtual bool setModEntry(const std::string &modname, + const std::string &key, const std::string &value); + virtual bool removeModEntry(const std::string &modname, const std::string &key); + virtual void listMods(std::vector<std::string> *res); + + virtual void beginSave() { Database_SQLite3::beginSave(); } + virtual void endSave() { Database_SQLite3::endSave(); } + +protected: + virtual void createDatabase(); + virtual void initStatements(); + +private: + sqlite3_stmt *m_stmt_get = nullptr; + sqlite3_stmt *m_stmt_set = nullptr; + sqlite3_stmt *m_stmt_remove = nullptr; +}; diff --git a/src/database/database.cpp b/src/database/database.cpp new file mode 100644 index 0000000..12e0e1a --- /dev/null +++ b/src/database/database.cpp @@ -0,0 +1,69 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "database.h" +#include "irrlichttypes.h" + + +/**************** + * Black magic! * + **************** + * The position hashing is very messed up. + * It's a lot more complicated than it looks. + */ + +static inline s16 unsigned_to_signed(u16 i, u16 max_positive) +{ + if (i < max_positive) { + return i; + } + + return i - (max_positive * 2); +} + + +// Modulo of a negative number does not work consistently in C +static inline s64 pythonmodulo(s64 i, s16 mod) +{ + if (i >= 0) { + return i % mod; + } + return mod - ((-i) % mod); +} + + +s64 MapDatabase::getBlockAsInteger(const v3s16 &pos) +{ + return (u64) pos.Z * 0x1000000 + + (u64) pos.Y * 0x1000 + + (u64) pos.X; +} + + +v3s16 MapDatabase::getIntegerAsBlock(s64 i) +{ + v3s16 pos; + pos.X = unsigned_to_signed(pythonmodulo(i, 4096), 2048); + i = (i - pos.X) / 4096; + pos.Y = unsigned_to_signed(pythonmodulo(i, 4096), 2048); + i = (i - pos.Y) / 4096; + pos.Z = unsigned_to_signed(pythonmodulo(i, 4096), 2048); + return pos; +} + diff --git a/src/database/database.h b/src/database/database.h new file mode 100644 index 0000000..fbb5bef --- /dev/null +++ b/src/database/database.h @@ -0,0 +1,99 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <set> +#include <string> +#include <vector> +#include "irr_v3d.h" +#include "irrlichttypes.h" +#include "util/basic_macros.h" +#include "util/string.h" + +class Database +{ +public: + virtual void beginSave() = 0; + virtual void endSave() = 0; + virtual bool initialized() const { return true; } +}; + +class MapDatabase : public Database +{ +public: + virtual ~MapDatabase() = default; + + virtual bool saveBlock(const v3s16 &pos, const std::string &data) = 0; + virtual void loadBlock(const v3s16 &pos, std::string *block) = 0; + virtual bool deleteBlock(const v3s16 &pos) = 0; + + static s64 getBlockAsInteger(const v3s16 &pos); + static v3s16 getIntegerAsBlock(s64 i); + + virtual void listAllLoadableBlocks(std::vector<v3s16> &dst) = 0; +}; + +class PlayerSAO; +class RemotePlayer; + +class PlayerDatabase +{ +public: + virtual ~PlayerDatabase() = default; + + virtual void savePlayer(RemotePlayer *player) = 0; + virtual bool loadPlayer(RemotePlayer *player, PlayerSAO *sao) = 0; + virtual bool removePlayer(const std::string &name) = 0; + virtual void listPlayers(std::vector<std::string> &res) = 0; +}; + +struct AuthEntry +{ + u64 id; + std::string name; + std::string password; + std::vector<std::string> privileges; + s64 last_login; +}; + +class AuthDatabase +{ +public: + virtual ~AuthDatabase() = default; + + virtual bool getAuth(const std::string &name, AuthEntry &res) = 0; + virtual bool saveAuth(const AuthEntry &authEntry) = 0; + virtual bool createAuth(AuthEntry &authEntry) = 0; + virtual bool deleteAuth(const std::string &name) = 0; + virtual void listNames(std::vector<std::string> &res) = 0; + virtual void reload() = 0; +}; + +class ModMetadataDatabase : public Database +{ +public: + virtual ~ModMetadataDatabase() = default; + + virtual bool getModEntries(const std::string &modname, StringMap *storage) = 0; + virtual bool setModEntry(const std::string &modname, + const std::string &key, const std::string &value) = 0; + virtual bool removeModEntry(const std::string &modname, const std::string &key) = 0; + virtual void listMods(std::vector<std::string> *res) = 0; +}; diff --git a/src/daynightratio.h b/src/daynightratio.h new file mode 100644 index 0000000..538767c --- /dev/null +++ b/src/daynightratio.h @@ -0,0 +1,72 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +inline u32 time_to_daynight_ratio(float time_of_day, bool smooth) +{ + float t = time_of_day; + if (t < 0.0f) + t += ((int)(-t) / 24000) * 24000.0f; + if (t >= 24000.0f) + t -= ((int)(t) / 24000) * 24000.0f; + if (t > 12000.0f) + t = 24000.0f - t; + + const float values[9][2] = { + {4250.0f + 125.0f, 175.0f}, + {4500.0f + 125.0f, 175.0f}, + {4750.0f + 125.0f, 250.0f}, + {5000.0f + 125.0f, 350.0f}, + {5250.0f + 125.0f, 500.0f}, + {5500.0f + 125.0f, 675.0f}, + {5750.0f + 125.0f, 875.0f}, + {6000.0f + 125.0f, 1000.0f}, + {6250.0f + 125.0f, 1000.0f}, + }; + + if (!smooth) { + float lastt = values[0][0]; + for (u32 i = 1; i < 9; i++) { + float t0 = values[i][0]; + float switch_t = (t0 + lastt) / 2.0f; + lastt = t0; + if (switch_t <= t) + continue; + + return values[i][1]; + } + return 1000; + } + + if (t <= 4625.0f) // 4500 + 125 + return values[0][1]; + else if (t >= 6125.0f) // 6000 + 125 + return 1000; + + for (u32 i = 0; i < 9; i++) { + if (values[i][0] <= t) + continue; + + float td0 = values[i][0] - values[i - 1][0]; + float f = (t - values[i - 1][0]) / td0; + return f * values[i][1] + (1.0f - f) * values[i - 1][1]; + } + return 1000; +} diff --git a/src/debug.cpp b/src/debug.cpp new file mode 100644 index 0000000..3c82ed9 --- /dev/null +++ b/src/debug.cpp @@ -0,0 +1,197 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "porting.h" +#include "debug.h" +#include "exceptions.h" +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <map> +#include <sstream> +#include <thread> +#include "threading/mutex_auto_lock.h" +#include "config.h" + +#ifdef _MSC_VER + #include <dbghelp.h> + #include "version.h" + #include "filesys.h" +#endif + +#if USE_CURSES + #include "terminal_chat_console.h" +#endif + +/* + Assert +*/ + +void sanity_check_fn(const char *assertion, const char *file, + unsigned int line, const char *function) +{ +#if USE_CURSES + g_term_console.stopAndWaitforThread(); +#endif + + errorstream << std::endl << "In thread " << std::hex + << std::this_thread::get_id() << ":" << std::endl; + errorstream << file << ":" << line << ": " << function + << ": An engine assumption '" << assertion << "' failed." << std::endl; + + abort(); +} + +void fatal_error_fn(const char *msg, const char *file, + unsigned int line, const char *function) +{ +#if USE_CURSES + g_term_console.stopAndWaitforThread(); +#endif + + errorstream << std::endl << "In thread " << std::hex + << std::this_thread::get_id() << ":" << std::endl; + errorstream << file << ":" << line << ": " << function + << ": A fatal error occurred: " << msg << std::endl; + + abort(); +} + +#ifdef _MSC_VER + +const char *Win32ExceptionCodeToString(DWORD exception_code) +{ + switch (exception_code) { + case EXCEPTION_ACCESS_VIOLATION: + return "Access violation"; + case EXCEPTION_DATATYPE_MISALIGNMENT: + return "Misaligned data access"; + case EXCEPTION_BREAKPOINT: + return "Breakpoint reached"; + case EXCEPTION_SINGLE_STEP: + return "Single debug step"; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + return "Array access out of bounds"; + case EXCEPTION_FLT_DENORMAL_OPERAND: + return "Denormal floating point operand"; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + return "Floating point division by zero"; + case EXCEPTION_FLT_INEXACT_RESULT: + return "Inaccurate floating point result"; + case EXCEPTION_FLT_INVALID_OPERATION: + return "Invalid floating point operation"; + case EXCEPTION_FLT_OVERFLOW: + return "Floating point exponent overflow"; + case EXCEPTION_FLT_STACK_CHECK: + return "Floating point stack overflow or underflow"; + case EXCEPTION_FLT_UNDERFLOW: + return "Floating point exponent underflow"; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + return "Integer division by zero"; + case EXCEPTION_INT_OVERFLOW: + return "Integer overflow"; + case EXCEPTION_PRIV_INSTRUCTION: + return "Privileged instruction executed"; + case EXCEPTION_IN_PAGE_ERROR: + return "Could not access or load page"; + case EXCEPTION_ILLEGAL_INSTRUCTION: + return "Illegal instruction encountered"; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + return "Attempted to continue after fatal exception"; + case EXCEPTION_STACK_OVERFLOW: + return "Stack overflow"; + case EXCEPTION_INVALID_DISPOSITION: + return "Invalid disposition returned to the exception dispatcher"; + case EXCEPTION_GUARD_PAGE: + return "Attempted guard page access"; + case EXCEPTION_INVALID_HANDLE: + return "Invalid handle"; + } + + return "Unknown exception"; +} + +long WINAPI Win32ExceptionHandler(struct _EXCEPTION_POINTERS *pExceptInfo) +{ + char buf[512]; + MINIDUMP_EXCEPTION_INFORMATION mdei; + MINIDUMP_USER_STREAM_INFORMATION mdusi; + MINIDUMP_USER_STREAM mdus; + bool minidump_created = false; + + std::string dumpfile = porting::path_user + DIR_DELIM PROJECT_NAME ".dmp"; + + std::string version_str(PROJECT_NAME " "); + version_str += g_version_hash; + + HANDLE hFile = CreateFileA(dumpfile.c_str(), GENERIC_WRITE, + FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + goto minidump_failed; + + if (SetEndOfFile(hFile) == FALSE) + goto minidump_failed; + + mdei.ClientPointers = NULL; + mdei.ExceptionPointers = pExceptInfo; + mdei.ThreadId = GetCurrentThreadId(); + + mdus.Type = CommentStreamA; + mdus.BufferSize = version_str.size(); + mdus.Buffer = (PVOID)version_str.c_str(); + + mdusi.UserStreamArray = &mdus; + mdusi.UserStreamCount = 1; + + if (MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, + MiniDumpNormal, &mdei, &mdusi, NULL) == FALSE) + goto minidump_failed; + + minidump_created = true; + +minidump_failed: + + CloseHandle(hFile); + + DWORD excode = pExceptInfo->ExceptionRecord->ExceptionCode; + _snprintf(buf, sizeof(buf), + " >> === FATAL ERROR ===\n" + " >> %s (Exception 0x%08X) at 0x%p\n", + Win32ExceptionCodeToString(excode), excode, + pExceptInfo->ExceptionRecord->ExceptionAddress); + dstream << buf; + + if (minidump_created) + dstream << " >> Saved dump to " << dumpfile << std::endl; + else + dstream << " >> Failed to save dump" << std::endl; + + return EXCEPTION_EXECUTE_HANDLER; +} + +#endif + +void debug_set_exception_handler() +{ +#ifdef _MSC_VER + SetUnhandledExceptionFilter(Win32ExceptionHandler); +#endif +} + diff --git a/src/debug.h b/src/debug.h new file mode 100644 index 0000000..1faeece --- /dev/null +++ b/src/debug.h @@ -0,0 +1,102 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <iostream> +#include <exception> +#include <cassert> +#include "gettime.h" +#include "log.h" + +#ifdef _WIN32 + #ifndef _WIN32_WINNT + #define _WIN32_WINNT 0x0501 + #endif + #include <windows.h> + #ifdef _MSC_VER + #include <eh.h> + #endif + #define NORETURN __declspec(noreturn) + #define FUNCTION_NAME __FUNCTION__ +#else + #define NORETURN __attribute__ ((__noreturn__)) + #define FUNCTION_NAME __PRETTY_FUNCTION__ +#endif + +// Whether to catch all std::exceptions. +// When "catching", the program will abort with an error message. +// In debug mode, leave these for the debugger and don't catch them. +#ifdef NDEBUG + #define CATCH_UNHANDLED_EXCEPTIONS 1 +#else + #define CATCH_UNHANDLED_EXCEPTIONS 0 +#endif + +/* Abort program execution immediately + */ +NORETURN extern void fatal_error_fn( + const char *msg, const char *file, + unsigned int line, const char *function); + +#define FATAL_ERROR(msg) \ + fatal_error_fn((msg), __FILE__, __LINE__, FUNCTION_NAME) + +#define FATAL_ERROR_IF(expr, msg) \ + ((expr) \ + ? fatal_error_fn((msg), __FILE__, __LINE__, FUNCTION_NAME) \ + : (void)(0)) + +/* + sanity_check() + Equivalent to assert() but persists in Release builds (i.e. when NDEBUG is + defined) +*/ + +NORETURN extern void sanity_check_fn( + const char *assertion, const char *file, + unsigned int line, const char *function); + +#define SANITY_CHECK(expr) \ + ((expr) \ + ? (void)(0) \ + : sanity_check_fn(#expr, __FILE__, __LINE__, FUNCTION_NAME)) + +#define sanity_check(expr) SANITY_CHECK(expr) + + +void debug_set_exception_handler(); + +/* + These should be put into every thread +*/ + +#if CATCH_UNHANDLED_EXCEPTIONS == 1 + #define BEGIN_DEBUG_EXCEPTION_HANDLER try { + #define END_DEBUG_EXCEPTION_HANDLER \ + } catch (std::exception &e) { \ + errorstream << "An unhandled exception occurred: " \ + << e.what() << std::endl; \ + FATAL_ERROR(e.what()); \ + } +#else + // Dummy ones + #define BEGIN_DEBUG_EXCEPTION_HANDLER + #define END_DEBUG_EXCEPTION_HANDLER +#endif diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp new file mode 100644 index 0000000..c5d92e6 --- /dev/null +++ b/src/defaultsettings.cpp @@ -0,0 +1,518 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <IrrCompileConfig.h> +#include "settings.h" +#include "porting.h" +#include "filesys.h" +#include "config.h" +#include "constants.h" +#include "porting.h" +#include "mapgen/mapgen.h" // Mapgen::setDefaultSettings +#include "util/string.h" + +void set_default_settings() +{ + Settings *settings = Settings::createLayer(SL_DEFAULTS); + + // Client and server + settings->setDefault("language", ""); + settings->setDefault("name", ""); + settings->setDefault("bind_address", ""); + settings->setDefault("serverlist_url", "servers.minetest.net"); + + // Client + settings->setDefault("address", ""); + settings->setDefault("enable_sound", "true"); + settings->setDefault("sound_volume", "0.8"); + settings->setDefault("mute_sound", "false"); + settings->setDefault("enable_mesh_cache", "false"); + settings->setDefault("mesh_generation_interval", "0"); + settings->setDefault("meshgen_block_cache_size", "20"); + settings->setDefault("enable_vbo", "true"); + settings->setDefault("free_move", "false"); + settings->setDefault("pitch_move", "false"); + settings->setDefault("fast_move", "false"); + settings->setDefault("noclip", "false"); + settings->setDefault("screenshot_path", "screenshots"); + settings->setDefault("screenshot_format", "png"); + settings->setDefault("screenshot_quality", "0"); + settings->setDefault("client_unload_unused_data_timeout", "600"); + settings->setDefault("client_mapblock_limit", "7500"); + settings->setDefault("enable_build_where_you_stand", "false"); + settings->setDefault("curl_timeout", "20000"); + settings->setDefault("curl_parallel_limit", "8"); + settings->setDefault("curl_file_download_timeout", "300000"); + settings->setDefault("curl_verify_cert", "true"); + settings->setDefault("enable_remote_media_server", "true"); + settings->setDefault("enable_client_modding", "false"); + settings->setDefault("max_out_chat_queue_size", "20"); + settings->setDefault("pause_on_lost_focus", "false"); + settings->setDefault("enable_split_login_register", "true"); + settings->setDefault("chat_weblink_color", "#8888FF"); + + // Keymap + settings->setDefault("remote_port", "30000"); + settings->setDefault("keymap_forward", "KEY_KEY_W"); + settings->setDefault("keymap_autoforward", ""); + settings->setDefault("keymap_backward", "KEY_KEY_S"); + settings->setDefault("keymap_left", "KEY_KEY_A"); + settings->setDefault("keymap_right", "KEY_KEY_D"); + settings->setDefault("keymap_jump", "KEY_SPACE"); + settings->setDefault("keymap_sneak", "KEY_LSHIFT"); + settings->setDefault("keymap_dig", "KEY_LBUTTON"); + settings->setDefault("keymap_place", "KEY_RBUTTON"); + settings->setDefault("keymap_drop", "KEY_KEY_Q"); + settings->setDefault("keymap_zoom", "KEY_KEY_Z"); + settings->setDefault("keymap_inventory", "KEY_KEY_I"); + settings->setDefault("keymap_aux1", "KEY_KEY_E"); + settings->setDefault("keymap_chat", "KEY_KEY_T"); + settings->setDefault("keymap_cmd", "/"); + settings->setDefault("keymap_cmd_local", "."); + settings->setDefault("keymap_minimap", "KEY_KEY_V"); + settings->setDefault("keymap_console", "KEY_F10"); + settings->setDefault("keymap_rangeselect", "KEY_KEY_R"); + settings->setDefault("keymap_freemove", "KEY_KEY_K"); + settings->setDefault("keymap_pitchmove", "KEY_KEY_P"); + settings->setDefault("keymap_fastmove", "KEY_KEY_J"); + settings->setDefault("keymap_noclip", "KEY_KEY_H"); + settings->setDefault("keymap_hotbar_next", "KEY_KEY_N"); + settings->setDefault("keymap_hotbar_previous", "KEY_KEY_B"); + settings->setDefault("keymap_mute", "KEY_KEY_M"); + settings->setDefault("keymap_increase_volume", ""); + settings->setDefault("keymap_decrease_volume", ""); + settings->setDefault("keymap_cinematic", ""); + settings->setDefault("keymap_toggle_block_bounds", ""); + settings->setDefault("keymap_toggle_hud", "KEY_F1"); + settings->setDefault("keymap_toggle_chat", "KEY_F2"); + settings->setDefault("keymap_toggle_fog", "KEY_F3"); +#if DEBUG + settings->setDefault("keymap_toggle_update_camera", "KEY_F4"); +#else + settings->setDefault("keymap_toggle_update_camera", ""); +#endif + settings->setDefault("keymap_toggle_debug", "KEY_F5"); + settings->setDefault("keymap_toggle_profiler", "KEY_F6"); + settings->setDefault("keymap_camera_mode", "KEY_KEY_C"); + settings->setDefault("keymap_screenshot", "KEY_F12"); + settings->setDefault("keymap_increase_viewing_range_min", "+"); + settings->setDefault("keymap_decrease_viewing_range_min", "-"); + settings->setDefault("keymap_slot1", "KEY_KEY_1"); + settings->setDefault("keymap_slot2", "KEY_KEY_2"); + settings->setDefault("keymap_slot3", "KEY_KEY_3"); + settings->setDefault("keymap_slot4", "KEY_KEY_4"); + settings->setDefault("keymap_slot5", "KEY_KEY_5"); + settings->setDefault("keymap_slot6", "KEY_KEY_6"); + settings->setDefault("keymap_slot7", "KEY_KEY_7"); + settings->setDefault("keymap_slot8", "KEY_KEY_8"); + settings->setDefault("keymap_slot9", "KEY_KEY_9"); + settings->setDefault("keymap_slot10", "KEY_KEY_0"); + settings->setDefault("keymap_slot11", ""); + settings->setDefault("keymap_slot12", ""); + settings->setDefault("keymap_slot13", ""); + settings->setDefault("keymap_slot14", ""); + settings->setDefault("keymap_slot15", ""); + settings->setDefault("keymap_slot16", ""); + settings->setDefault("keymap_slot17", ""); + settings->setDefault("keymap_slot18", ""); + settings->setDefault("keymap_slot19", ""); + settings->setDefault("keymap_slot20", ""); + settings->setDefault("keymap_slot21", ""); + settings->setDefault("keymap_slot22", ""); + settings->setDefault("keymap_slot23", ""); + settings->setDefault("keymap_slot24", ""); + settings->setDefault("keymap_slot25", ""); + settings->setDefault("keymap_slot26", ""); + settings->setDefault("keymap_slot27", ""); + settings->setDefault("keymap_slot28", ""); + settings->setDefault("keymap_slot29", ""); + settings->setDefault("keymap_slot30", ""); + settings->setDefault("keymap_slot31", ""); + settings->setDefault("keymap_slot32", ""); + + // Some (temporary) keys for debugging + settings->setDefault("keymap_quicktune_prev", "KEY_HOME"); + settings->setDefault("keymap_quicktune_next", "KEY_END"); + settings->setDefault("keymap_quicktune_dec", "KEY_NEXT"); + settings->setDefault("keymap_quicktune_inc", "KEY_PRIOR"); + + // Visuals +#ifdef NDEBUG + settings->setDefault("show_debug", "false"); +#else + settings->setDefault("show_debug", "true"); +#endif + settings->setDefault("fsaa", "0"); + settings->setDefault("undersampling", "0"); + settings->setDefault("world_aligned_mode", "enable"); + settings->setDefault("autoscale_mode", "disable"); + settings->setDefault("enable_fog", "true"); + settings->setDefault("fog_start", "0.4"); + settings->setDefault("3d_mode", "none"); + settings->setDefault("3d_paralax_strength", "0.025"); + settings->setDefault("tooltip_show_delay", "400"); + settings->setDefault("tooltip_append_itemname", "false"); + settings->setDefault("fps_max", "60"); + settings->setDefault("fps_max_unfocused", "20"); + settings->setDefault("viewing_range", "190"); +#if ENABLE_GLES + settings->setDefault("near_plane", "0.1"); +#endif + settings->setDefault("screen_w", "1024"); + settings->setDefault("screen_h", "600"); + settings->setDefault("autosave_screensize", "true"); + settings->setDefault("fullscreen", "false"); + settings->setDefault("vsync", "false"); + settings->setDefault("fov", "72"); + settings->setDefault("leaves_style", "fancy"); + settings->setDefault("connected_glass", "false"); + settings->setDefault("smooth_lighting", "true"); + settings->setDefault("performance_tradeoffs", "false"); + settings->setDefault("lighting_alpha", "0.0"); + settings->setDefault("lighting_beta", "1.5"); + settings->setDefault("display_gamma", "1.0"); + settings->setDefault("lighting_boost", "0.2"); + settings->setDefault("lighting_boost_center", "0.5"); + settings->setDefault("lighting_boost_spread", "0.2"); + settings->setDefault("texture_path", ""); + settings->setDefault("shader_path", ""); +#if ENABLE_GLES +#ifdef _IRR_COMPILE_WITH_OGLES1_ + settings->setDefault("video_driver", "ogles1"); +#else + settings->setDefault("video_driver", "ogles2"); +#endif +#else + settings->setDefault("video_driver", "opengl"); +#endif + settings->setDefault("cinematic", "false"); + settings->setDefault("camera_smoothing", "0"); + settings->setDefault("cinematic_camera_smoothing", "0.7"); + settings->setDefault("enable_clouds", "true"); + settings->setDefault("view_bobbing_amount", "1.0"); + settings->setDefault("fall_bobbing_amount", "0.03"); + settings->setDefault("enable_3d_clouds", "true"); + settings->setDefault("cloud_radius", "12"); + settings->setDefault("menu_clouds", "true"); + settings->setDefault("opaque_water", "false"); + settings->setDefault("console_height", "0.6"); + settings->setDefault("console_color", "(0,0,0)"); + settings->setDefault("console_alpha", "200"); + settings->setDefault("formspec_fullscreen_bg_color", "(0,0,0)"); + settings->setDefault("formspec_fullscreen_bg_opacity", "140"); + settings->setDefault("formspec_default_bg_color", "(0,0,0)"); + settings->setDefault("formspec_default_bg_opacity", "140"); + settings->setDefault("selectionbox_color", "(0,0,0)"); + settings->setDefault("selectionbox_width", "2"); + settings->setDefault("node_highlighting", "box"); + settings->setDefault("crosshair_color", "(255,255,255)"); + settings->setDefault("crosshair_alpha", "255"); + settings->setDefault("recent_chat_messages", "6"); + settings->setDefault("hud_scaling", "1.0"); + settings->setDefault("gui_scaling", "1.0"); + settings->setDefault("gui_scaling_filter", "false"); + settings->setDefault("gui_scaling_filter_txr2img", "true"); + settings->setDefault("desynchronize_mapblock_texture_animation", "true"); + settings->setDefault("hud_hotbar_max_width", "1.0"); + settings->setDefault("enable_local_map_saving", "false"); + settings->setDefault("show_entity_selectionbox", "false"); + settings->setDefault("texture_clean_transparent", "false"); + settings->setDefault("texture_min_size", "64"); + settings->setDefault("ambient_occlusion_gamma", "1.8"); +#if ENABLE_GLES + settings->setDefault("enable_shaders", "false"); +#else + settings->setDefault("enable_shaders", "true"); +#endif + settings->setDefault("enable_particles", "true"); + settings->setDefault("arm_inertia", "true"); + settings->setDefault("show_nametag_backgrounds", "true"); + settings->setDefault("transparency_sorting_distance", "16"); + + settings->setDefault("enable_minimap", "true"); + settings->setDefault("minimap_shape_round", "true"); + settings->setDefault("minimap_double_scan_height", "true"); + + // Effects + settings->setDefault("directional_colored_fog", "true"); + settings->setDefault("inventory_items_animations", "false"); + settings->setDefault("mip_map", "false"); + settings->setDefault("anisotropic_filter", "false"); + settings->setDefault("bilinear_filter", "false"); + settings->setDefault("trilinear_filter", "false"); + settings->setDefault("tone_mapping", "false"); + settings->setDefault("enable_waving_water", "false"); + settings->setDefault("water_wave_height", "1.0"); + settings->setDefault("water_wave_length", "20.0"); + settings->setDefault("water_wave_speed", "5.0"); + settings->setDefault("enable_waving_leaves", "false"); + settings->setDefault("enable_waving_plants", "false"); + + // Effects Shadows + settings->setDefault("enable_dynamic_shadows", "false"); + settings->setDefault("shadow_strength_gamma", "1.0"); + settings->setDefault("shadow_map_max_distance", "200.0"); + settings->setDefault("shadow_map_texture_size", "2048"); + settings->setDefault("shadow_map_texture_32bit", "true"); + settings->setDefault("shadow_map_color", "false"); + settings->setDefault("shadow_filters", "1"); + settings->setDefault("shadow_poisson_filter", "true"); + settings->setDefault("shadow_update_frames", "8"); + settings->setDefault("shadow_soft_radius", "5.0"); + settings->setDefault("shadow_sky_body_orbit_tilt", "0.0"); + + // Input + settings->setDefault("invert_mouse", "false"); + settings->setDefault("mouse_sensitivity", "0.2"); + settings->setDefault("repeat_place_time", "0.25"); + settings->setDefault("safe_dig_and_place", "false"); + settings->setDefault("random_input", "false"); + settings->setDefault("aux1_descends", "false"); + settings->setDefault("doubletap_jump", "false"); + settings->setDefault("always_fly_fast", "true"); +#ifdef HAVE_TOUCHSCREENGUI + settings->setDefault("autojump", "true"); +#else + settings->setDefault("autojump", "false"); +#endif + settings->setDefault("continuous_forward", "false"); + settings->setDefault("enable_joysticks", "false"); + settings->setDefault("joystick_id", "0"); + settings->setDefault("joystick_type", ""); + settings->setDefault("repeat_joystick_button_time", "0.17"); + settings->setDefault("joystick_frustum_sensitivity", "170"); + settings->setDefault("joystick_deadzone", "2048"); + + // Main menu + settings->setDefault("main_menu_path", ""); + settings->setDefault("serverlist_file", "favoriteservers.json"); + + // General font settings + settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "Arimo-Regular.ttf")); + settings->setDefault("font_path_italic", porting::getDataPath("fonts" DIR_DELIM "Arimo-Italic.ttf")); + settings->setDefault("font_path_bold", porting::getDataPath("fonts" DIR_DELIM "Arimo-Bold.ttf")); + settings->setDefault("font_path_bold_italic", porting::getDataPath("fonts" DIR_DELIM "Arimo-BoldItalic.ttf")); + settings->setDefault("font_bold", "false"); + settings->setDefault("font_italic", "false"); + settings->setDefault("font_shadow", "1"); + settings->setDefault("font_shadow_alpha", "127"); + settings->setDefault("font_size_divisible_by", "1"); + settings->setDefault("mono_font_path", porting::getDataPath("fonts" DIR_DELIM "Cousine-Regular.ttf")); + settings->setDefault("mono_font_path_italic", porting::getDataPath("fonts" DIR_DELIM "Cousine-Italic.ttf")); + settings->setDefault("mono_font_path_bold", porting::getDataPath("fonts" DIR_DELIM "Cousine-Bold.ttf")); + settings->setDefault("mono_font_path_bold_italic", porting::getDataPath("fonts" DIR_DELIM "Cousine-BoldItalic.ttf")); + settings->setDefault("mono_font_size_divisible_by", "1"); + settings->setDefault("fallback_font_path", porting::getDataPath("fonts" DIR_DELIM "DroidSansFallbackFull.ttf")); + + std::string font_size_str = std::to_string(TTF_DEFAULT_FONT_SIZE); + settings->setDefault("font_size", font_size_str); + settings->setDefault("mono_font_size", font_size_str); + settings->setDefault("chat_font_size", "0"); // Default "font_size" + + // ContentDB + settings->setDefault("contentdb_url", "https://content.minetest.net"); + settings->setDefault("contentdb_max_concurrent_downloads", "3"); + +#ifdef __ANDROID__ + settings->setDefault("contentdb_flag_blacklist", "nonfree, android_default"); +#else + settings->setDefault("contentdb_flag_blacklist", "nonfree, desktop_default"); +#endif + + settings->setDefault("update_information_url", "https://www.minetest.net/release_info.json"); +#if ENABLE_UPDATE_CHECKER + settings->setDefault("update_last_checked", ""); +#else + settings->setDefault("update_last_checked", "disabled"); +#endif + + // Server + settings->setDefault("disable_escape_sequences", "false"); + settings->setDefault("strip_color_codes", "false"); +#if USE_PROMETHEUS + settings->setDefault("prometheus_listener_address", "127.0.0.1:30000"); +#endif + + // Network + settings->setDefault("enable_ipv6", "true"); + settings->setDefault("ipv6_server", "false"); + settings->setDefault("max_packets_per_iteration","1024"); + settings->setDefault("port", "30000"); + settings->setDefault("strict_protocol_version_checking", "false"); + settings->setDefault("player_transfer_distance", "0"); + settings->setDefault("max_simultaneous_block_sends_per_client", "40"); + settings->setDefault("time_send_interval", "5"); + + settings->setDefault("default_game", "minetest"); + settings->setDefault("motd", ""); + settings->setDefault("max_users", "15"); + settings->setDefault("creative_mode", "false"); + settings->setDefault("enable_damage", "true"); + settings->setDefault("default_password", ""); + settings->setDefault("default_privs", "interact, shout"); + settings->setDefault("enable_pvp", "true"); + settings->setDefault("enable_mod_channels", "false"); + settings->setDefault("disallow_empty_password", "false"); + settings->setDefault("disable_anticheat", "false"); + settings->setDefault("enable_rollback_recording", "false"); + settings->setDefault("deprecated_lua_api_handling", "log"); + + settings->setDefault("kick_msg_shutdown", "Server shutting down."); + settings->setDefault("kick_msg_crash", "This server has experienced an internal error. You will now be disconnected."); + settings->setDefault("ask_reconnect_on_crash", "false"); + + settings->setDefault("chat_message_format", "<@name> @message"); + settings->setDefault("profiler_print_interval", "0"); + settings->setDefault("active_object_send_range_blocks", "8"); + settings->setDefault("active_block_range", "4"); + //settings->setDefault("max_simultaneous_block_sends_per_client", "1"); + // This causes frametime jitter on client side, or does it? + settings->setDefault("max_block_send_distance", "12"); + settings->setDefault("block_send_optimize_distance", "4"); + settings->setDefault("server_side_occlusion_culling", "true"); + settings->setDefault("csm_restriction_flags", "62"); + settings->setDefault("csm_restriction_noderange", "0"); + settings->setDefault("max_clearobjects_extra_loaded_blocks", "4096"); + settings->setDefault("time_speed", "72"); + settings->setDefault("world_start_time", "6125"); + settings->setDefault("server_unload_unused_data_timeout", "29"); + settings->setDefault("max_objects_per_block", "256"); + settings->setDefault("server_map_save_interval", "5.3"); + settings->setDefault("chat_message_max_size", "500"); + settings->setDefault("chat_message_limit_per_10sec", "8.0"); + settings->setDefault("chat_message_limit_trigger_kick", "50"); + settings->setDefault("sqlite_synchronous", "2"); + settings->setDefault("map_compression_level_disk", "-1"); + settings->setDefault("map_compression_level_net", "-1"); + settings->setDefault("full_block_send_enable_min_time_from_building", "2.0"); + settings->setDefault("dedicated_server_step", "0.09"); + settings->setDefault("active_block_mgmt_interval", "2.0"); + settings->setDefault("abm_interval", "1.0"); + settings->setDefault("abm_time_budget", "0.2"); + settings->setDefault("nodetimer_interval", "0.2"); + settings->setDefault("ignore_world_load_errors", "false"); + settings->setDefault("remote_media", ""); + settings->setDefault("debug_log_level", "action"); + settings->setDefault("debug_log_size_max", "50"); + settings->setDefault("chat_log_level", "error"); + settings->setDefault("emergequeue_limit_total", "1024"); + settings->setDefault("emergequeue_limit_diskonly", "128"); + settings->setDefault("emergequeue_limit_generate", "128"); + settings->setDefault("num_emerge_threads", "1"); + settings->setDefault("secure.enable_security", "true"); + settings->setDefault("secure.trusted_mods", ""); + settings->setDefault("secure.http_mods", ""); + + // Physics + settings->setDefault("movement_acceleration_default", "3"); + settings->setDefault("movement_acceleration_air", "2"); + settings->setDefault("movement_acceleration_fast", "10"); + settings->setDefault("movement_speed_walk", "4"); + settings->setDefault("movement_speed_crouch", "1.35"); + settings->setDefault("movement_speed_fast", "20"); + settings->setDefault("movement_speed_climb", "3"); + settings->setDefault("movement_speed_jump", "6.5"); + settings->setDefault("movement_liquid_fluidity", "1"); + settings->setDefault("movement_liquid_fluidity_smooth", "0.5"); + settings->setDefault("movement_liquid_sink", "10"); + settings->setDefault("movement_gravity", "9.81"); + + // Liquids + settings->setDefault("liquid_loop_max", "100000"); + settings->setDefault("liquid_queue_purge_time", "0"); + settings->setDefault("liquid_update", "1.0"); + + // Mapgen + settings->setDefault("mg_name", "v7"); + settings->setDefault("water_level", "1"); + settings->setDefault("mapgen_limit", "31007"); + settings->setDefault("chunksize", "5"); + settings->setDefault("fixed_map_seed", ""); + settings->setDefault("max_block_generate_distance", "10"); + settings->setDefault("enable_mapgen_debug_info", "false"); + Mapgen::setDefaultSettings(settings); + + // Server list announcing + settings->setDefault("server_announce", "false"); + settings->setDefault("server_url", ""); + settings->setDefault("server_address", ""); + settings->setDefault("server_name", ""); + settings->setDefault("server_description", ""); + + settings->setDefault("enable_console", "false"); + settings->setDefault("screen_dpi", "72"); + settings->setDefault("display_density_factor", "1"); + + // Altered settings for macOS +#if defined(__MACH__) && defined(__APPLE__) + settings->setDefault("keymap_sneak", "KEY_SHIFT"); +#endif + +#ifdef HAVE_TOUCHSCREENGUI + settings->setDefault("touchtarget", "true"); + settings->setDefault("touchscreen_threshold","20"); + settings->setDefault("fixed_virtual_joystick", "false"); + settings->setDefault("virtual_joystick_triggers_aux1", "false"); + settings->setDefault("clickable_chat_weblinks", "false"); +#else + settings->setDefault("clickable_chat_weblinks", "true"); +#endif + // Altered settings for Android +#ifdef __ANDROID__ + settings->setDefault("screen_w", "0"); + settings->setDefault("screen_h", "0"); + settings->setDefault("fullscreen", "true"); + settings->setDefault("smooth_lighting", "false"); + settings->setDefault("performance_tradeoffs", "true"); + settings->setDefault("max_simultaneous_block_sends_per_client", "10"); + settings->setDefault("emergequeue_limit_diskonly", "16"); + settings->setDefault("emergequeue_limit_generate", "16"); + settings->setDefault("max_block_generate_distance", "5"); + settings->setDefault("enable_3d_clouds", "false"); + settings->setDefault("fps_max_unfocused", "10"); + settings->setDefault("sqlite_synchronous", "1"); + settings->setDefault("map_compression_level_disk", "-1"); + settings->setDefault("map_compression_level_net", "-1"); + settings->setDefault("server_map_save_interval", "15"); + settings->setDefault("client_mapblock_limit", "1000"); + settings->setDefault("active_block_range", "2"); + settings->setDefault("viewing_range", "50"); + settings->setDefault("leaves_style", "simple"); + settings->setDefault("curl_verify_cert","false"); + + // Apply settings according to screen size + float x_inches = (float) porting::getDisplaySize().X / + (160.f * porting::getDisplayDensity()); + + if (x_inches < 3.7f) { + settings->setDefault("hud_scaling", "0.6"); + settings->setDefault("font_size", "14"); + settings->setDefault("mono_font_size", "14"); + } else if (x_inches < 4.5f) { + settings->setDefault("hud_scaling", "0.7"); + settings->setDefault("font_size", "14"); + settings->setDefault("mono_font_size", "14"); + } else if (x_inches < 6.0f) { + settings->setDefault("hud_scaling", "0.85"); + settings->setDefault("font_size", "14"); + settings->setDefault("mono_font_size", "14"); + } + // Tablets >= 6.0 use non-Android defaults for these settings +#endif +} diff --git a/src/defaultsettings.h b/src/defaultsettings.h new file mode 100644 index 0000000..c239b3c --- /dev/null +++ b/src/defaultsettings.h @@ -0,0 +1,28 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +class Settings; + +/** + * initialize basic default settings + * @param settings pointer to settings + */ +void set_default_settings(); diff --git a/src/emerge.cpp b/src/emerge.cpp new file mode 100644 index 0000000..3e42742 --- /dev/null +++ b/src/emerge.cpp @@ -0,0 +1,753 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "emerge.h" + +#include <iostream> +#include <queue> + +#include "util/container.h" +#include "util/thread.h" +#include "threading/event.h" + +#include "config.h" +#include "constants.h" +#include "environment.h" +#include "log.h" +#include "map.h" +#include "mapblock.h" +#include "mapgen/mg_biome.h" +#include "mapgen/mg_ore.h" +#include "mapgen/mg_decoration.h" +#include "mapgen/mg_schematic.h" +#include "nodedef.h" +#include "profiler.h" +#include "scripting_server.h" +#include "server.h" +#include "settings.h" +#include "voxel.h" + +class EmergeThread : public Thread { +public: + bool enable_mapgen_debug_info; + int id; + + EmergeThread(Server *server, int ethreadid); + ~EmergeThread() = default; + + void *run(); + void signal(); + + // Requires queue mutex held + bool pushBlock(const v3s16 &pos); + + void cancelPendingItems(); + +protected: + + void runCompletionCallbacks( + const v3s16 &pos, EmergeAction action, + const EmergeCallbackList &callbacks); + +private: + Server *m_server; + ServerMap *m_map; + EmergeManager *m_emerge; + Mapgen *m_mapgen; + + Event m_queue_event; + std::queue<v3s16> m_block_queue; + + bool popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata); + + EmergeAction getBlockOrStartGen( + const v3s16 &pos, bool allow_gen, MapBlock **block, BlockMakeData *data); + MapBlock *finishGen(v3s16 pos, BlockMakeData *bmdata, + std::map<v3s16, MapBlock *> *modified_blocks); + + friend class EmergeManager; +}; + +class MapEditEventAreaIgnorer +{ +public: + MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a): + m_ignorevariable(ignorevariable) + { + if(m_ignorevariable->getVolume() == 0) + *m_ignorevariable = a; + else + m_ignorevariable = NULL; + } + + ~MapEditEventAreaIgnorer() + { + if(m_ignorevariable) + { + assert(m_ignorevariable->getVolume() != 0); + *m_ignorevariable = VoxelArea(); + } + } + +private: + VoxelArea *m_ignorevariable; +}; + +EmergeParams::~EmergeParams() +{ + infostream << "EmergeParams: destroying " << this << std::endl; + // Delete everything that was cloned on creation of EmergeParams + delete biomegen; + delete biomemgr; + delete oremgr; + delete decomgr; + delete schemmgr; +} + +EmergeParams::EmergeParams(EmergeManager *parent, const BiomeGen *biomegen, + const BiomeManager *biomemgr, + const OreManager *oremgr, const DecorationManager *decomgr, + const SchematicManager *schemmgr) : + ndef(parent->ndef), + enable_mapgen_debug_info(parent->enable_mapgen_debug_info), + gen_notify_on(parent->gen_notify_on), + gen_notify_on_deco_ids(&parent->gen_notify_on_deco_ids), + biomemgr(biomemgr->clone()), oremgr(oremgr->clone()), + decomgr(decomgr->clone()), schemmgr(schemmgr->clone()) +{ + this->biomegen = biomegen->clone(this->biomemgr); +} + +//// +//// EmergeManager +//// + +EmergeManager::EmergeManager(Server *server, MetricsBackend *mb) +{ + this->ndef = server->getNodeDefManager(); + this->biomemgr = new BiomeManager(server); + this->oremgr = new OreManager(server); + this->decomgr = new DecorationManager(server); + this->schemmgr = new SchematicManager(server); + + // initialized later + this->mgparams = nullptr; + this->biomegen = nullptr; + + // Note that accesses to this variable are not synchronized. + // This is because the *only* thread ever starting or stopping + // EmergeThreads should be the ServerThread. + + enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); + + STATIC_ASSERT(ARRLEN(emergeActionStrs) == ARRLEN(m_completed_emerge_counter), + enum_size_mismatches); + for (u32 i = 0; i < ARRLEN(m_completed_emerge_counter); i++) { + std::string help_str("Number of completed emerges with status "); + help_str.append(emergeActionStrs[i]); + m_completed_emerge_counter[i] = mb->addCounter( + "minetest_emerge_completed", help_str, + {{"status", emergeActionStrs[i]}} + ); + } + + s16 nthreads = 1; + g_settings->getS16NoEx("num_emerge_threads", nthreads); + // If automatic, leave a proc for the main thread and one for + // some other misc thread + if (nthreads <= 0) + nthreads = Thread::getNumberOfProcessors() - 2; + if (nthreads < 1) + nthreads = 1; + + m_qlimit_total = g_settings->getU32("emergequeue_limit_total"); + // FIXME: these fallback values are probably not good + if (!g_settings->getU32NoEx("emergequeue_limit_diskonly", m_qlimit_diskonly)) + m_qlimit_diskonly = nthreads * 5 + 1; + if (!g_settings->getU32NoEx("emergequeue_limit_generate", m_qlimit_generate)) + m_qlimit_generate = nthreads + 1; + + // don't trust user input for something very important like this + m_qlimit_total = rangelim(m_qlimit_total, 1, 1000000); + m_qlimit_diskonly = rangelim(m_qlimit_diskonly, 1, 1000000); + m_qlimit_generate = rangelim(m_qlimit_generate, 1, 1000000); + + for (s16 i = 0; i < nthreads; i++) + m_threads.push_back(new EmergeThread(server, i)); + + infostream << "EmergeManager: using " << nthreads << " threads" << std::endl; +} + + +EmergeManager::~EmergeManager() +{ + for (u32 i = 0; i != m_threads.size(); i++) { + EmergeThread *thread = m_threads[i]; + + if (m_threads_active) { + thread->stop(); + thread->signal(); + thread->wait(); + } + + delete thread; + + // Mapgen init might not be finished if there is an error during startup. + if (m_mapgens.size() > i) + delete m_mapgens[i]; + } + + delete biomegen; + delete biomemgr; + delete oremgr; + delete decomgr; + delete schemmgr; +} + + +BiomeManager *EmergeManager::getWritableBiomeManager() +{ + FATAL_ERROR_IF(!m_mapgens.empty(), + "Writable managers can only be returned before mapgen init"); + return biomemgr; +} + +OreManager *EmergeManager::getWritableOreManager() +{ + FATAL_ERROR_IF(!m_mapgens.empty(), + "Writable managers can only be returned before mapgen init"); + return oremgr; +} + +DecorationManager *EmergeManager::getWritableDecorationManager() +{ + FATAL_ERROR_IF(!m_mapgens.empty(), + "Writable managers can only be returned before mapgen init"); + return decomgr; +} + +SchematicManager *EmergeManager::getWritableSchematicManager() +{ + FATAL_ERROR_IF(!m_mapgens.empty(), + "Writable managers can only be returned before mapgen init"); + return schemmgr; +} + + +void EmergeManager::initMapgens(MapgenParams *params) +{ + FATAL_ERROR_IF(!m_mapgens.empty(), "Mapgen already initialised."); + + mgparams = params; + + v3s16 csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE); + biomegen = biomemgr->createBiomeGen(BIOMEGEN_ORIGINAL, params->bparams, csize); + + for (u32 i = 0; i != m_threads.size(); i++) { + EmergeParams *p = new EmergeParams(this, biomegen, + biomemgr, oremgr, decomgr, schemmgr); + infostream << "EmergeManager: Created params " << p + << " for thread " << i << std::endl; + m_mapgens.push_back(Mapgen::createMapgen(params->mgtype, params, p)); + } +} + + +Mapgen *EmergeManager::getCurrentMapgen() +{ + if (!m_threads_active) + return nullptr; + + for (u32 i = 0; i != m_threads.size(); i++) { + EmergeThread *t = m_threads[i]; + if (t->isRunning() && t->isCurrentThread()) + return t->m_mapgen; + } + + return nullptr; +} + + +void EmergeManager::startThreads() +{ + if (m_threads_active) + return; + + for (u32 i = 0; i != m_threads.size(); i++) + m_threads[i]->start(); + + m_threads_active = true; +} + + +void EmergeManager::stopThreads() +{ + if (!m_threads_active) + return; + + // Request thread stop in parallel + for (u32 i = 0; i != m_threads.size(); i++) { + m_threads[i]->stop(); + m_threads[i]->signal(); + } + + // Then do the waiting for each + for (u32 i = 0; i != m_threads.size(); i++) + m_threads[i]->wait(); + + m_threads_active = false; +} + + +bool EmergeManager::isRunning() +{ + return m_threads_active; +} + + +bool EmergeManager::enqueueBlockEmerge( + session_t peer_id, + v3s16 blockpos, + bool allow_generate, + bool ignore_queue_limits) +{ + u16 flags = 0; + if (allow_generate) + flags |= BLOCK_EMERGE_ALLOW_GEN; + if (ignore_queue_limits) + flags |= BLOCK_EMERGE_FORCE_QUEUE; + + return enqueueBlockEmergeEx(blockpos, peer_id, flags, NULL, NULL); +} + + +bool EmergeManager::enqueueBlockEmergeEx( + v3s16 blockpos, + session_t peer_id, + u16 flags, + EmergeCompletionCallback callback, + void *callback_param) +{ + EmergeThread *thread = NULL; + bool entry_already_exists = false; + + { + MutexAutoLock queuelock(m_queue_mutex); + + if (!pushBlockEmergeData(blockpos, peer_id, flags, + callback, callback_param, &entry_already_exists)) + return false; + + if (entry_already_exists) + return true; + + thread = getOptimalThread(); + thread->pushBlock(blockpos); + } + + thread->signal(); + + return true; +} + + +bool EmergeManager::isBlockInQueue(v3s16 pos) +{ + MutexAutoLock queuelock(m_queue_mutex); + return m_blocks_enqueued.find(pos) != m_blocks_enqueued.end(); +} + + +// +// Mapgen-related helper functions +// + + +// TODO(hmmmm): Move this to ServerMap +v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, s16 chunksize) +{ + s16 coff = -chunksize / 2; + v3s16 chunk_offset(coff, coff, coff); + + return getContainerPos(blockpos - chunk_offset, chunksize) + * chunksize + chunk_offset; +} + + +int EmergeManager::getSpawnLevelAtPoint(v2s16 p) +{ + if (m_mapgens.empty() || !m_mapgens[0]) { + errorstream << "EmergeManager: getSpawnLevelAtPoint() called" + " before mapgen init" << std::endl; + return 0; + } + + return m_mapgens[0]->getSpawnLevelAtPoint(p); +} + + +// TODO(hmmmm): Move this to ServerMap +bool EmergeManager::isBlockUnderground(v3s16 blockpos) +{ + // Use a simple heuristic + return blockpos.Y * (MAP_BLOCKSIZE + 1) <= mgparams->water_level; +} + +bool EmergeManager::pushBlockEmergeData( + v3s16 pos, + u16 peer_requested, + u16 flags, + EmergeCompletionCallback callback, + void *callback_param, + bool *entry_already_exists) +{ + u32 &count_peer = m_peer_queue_count[peer_requested]; + + if ((flags & BLOCK_EMERGE_FORCE_QUEUE) == 0) { + if (m_blocks_enqueued.size() >= m_qlimit_total) + return false; + + if (peer_requested != PEER_ID_INEXISTENT) { + u32 qlimit_peer = (flags & BLOCK_EMERGE_ALLOW_GEN) ? + m_qlimit_generate : m_qlimit_diskonly; + if (count_peer >= qlimit_peer) + return false; + } else { + // limit block enqueue requests for active blocks to 1/2 of total + if (count_peer * 2 >= m_qlimit_total) + return false; + } + } + + std::pair<std::map<v3s16, BlockEmergeData>::iterator, bool> findres; + findres = m_blocks_enqueued.insert(std::make_pair(pos, BlockEmergeData())); + + BlockEmergeData &bedata = findres.first->second; + *entry_already_exists = !findres.second; + + if (callback) + bedata.callbacks.emplace_back(callback, callback_param); + + if (*entry_already_exists) { + bedata.flags |= flags; + } else { + bedata.flags = flags; + bedata.peer_requested = peer_requested; + + count_peer++; + } + + return true; +} + + +bool EmergeManager::popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata) +{ + auto it = m_blocks_enqueued.find(pos); + if (it == m_blocks_enqueued.end()) + return false; + + *bedata = it->second; + + auto it2 = m_peer_queue_count.find(bedata->peer_requested); + if (it2 == m_peer_queue_count.end()) + return false; + + u32 &count_peer = it2->second; + + assert(count_peer != 0); + count_peer--; + + m_blocks_enqueued.erase(it); + + return true; +} + + +EmergeThread *EmergeManager::getOptimalThread() +{ + size_t nthreads = m_threads.size(); + + FATAL_ERROR_IF(nthreads == 0, "No emerge threads!"); + + size_t index = 0; + size_t nitems_lowest = m_threads[0]->m_block_queue.size(); + + for (size_t i = 1; i < nthreads; i++) { + size_t nitems = m_threads[i]->m_block_queue.size(); + if (nitems < nitems_lowest) { + index = i; + nitems_lowest = nitems; + } + } + + return m_threads[index]; +} + +void EmergeManager::reportCompletedEmerge(EmergeAction action) +{ + assert((size_t)action < ARRLEN(m_completed_emerge_counter)); + m_completed_emerge_counter[(int)action]->increment(); +} + + +//// +//// EmergeThread +//// + +EmergeThread::EmergeThread(Server *server, int ethreadid) : + enable_mapgen_debug_info(false), + id(ethreadid), + m_server(server), + m_map(NULL), + m_emerge(NULL), + m_mapgen(NULL) +{ + m_name = "Emerge-" + itos(ethreadid); +} + + +void EmergeThread::signal() +{ + m_queue_event.signal(); +} + + +bool EmergeThread::pushBlock(const v3s16 &pos) +{ + m_block_queue.push(pos); + return true; +} + + +void EmergeThread::cancelPendingItems() +{ + MutexAutoLock queuelock(m_emerge->m_queue_mutex); + + while (!m_block_queue.empty()) { + BlockEmergeData bedata; + v3s16 pos; + + pos = m_block_queue.front(); + m_block_queue.pop(); + + m_emerge->popBlockEmergeData(pos, &bedata); + + runCompletionCallbacks(pos, EMERGE_CANCELLED, bedata.callbacks); + } +} + + +void EmergeThread::runCompletionCallbacks(const v3s16 &pos, EmergeAction action, + const EmergeCallbackList &callbacks) +{ + m_emerge->reportCompletedEmerge(action); + + for (size_t i = 0; i != callbacks.size(); i++) { + EmergeCompletionCallback callback; + void *param; + + callback = callbacks[i].first; + param = callbacks[i].second; + + callback(pos, action, param); + } +} + + +bool EmergeThread::popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata) +{ + MutexAutoLock queuelock(m_emerge->m_queue_mutex); + + if (m_block_queue.empty()) + return false; + + *pos = m_block_queue.front(); + m_block_queue.pop(); + + m_emerge->popBlockEmergeData(*pos, bedata); + + return true; +} + + +EmergeAction EmergeThread::getBlockOrStartGen( + const v3s16 &pos, bool allow_gen, MapBlock **block, BlockMakeData *bmdata) +{ + MutexAutoLock envlock(m_server->m_env_mutex); + + // 1). Attempt to fetch block from memory + *block = m_map->getBlockNoCreateNoEx(pos); + if (*block && !(*block)->isDummy()) { + if ((*block)->isGenerated()) + return EMERGE_FROM_MEMORY; + } else { + // 2). Attempt to load block from disk if it was not in the memory + *block = m_map->loadBlock(pos); + if (*block && (*block)->isGenerated()) + return EMERGE_FROM_DISK; + } + + // 3). Attempt to start generation + if (allow_gen && m_map->initBlockMake(pos, bmdata)) + return EMERGE_GENERATED; + + // All attempts failed; cancel this block emerge + return EMERGE_CANCELLED; +} + + +MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata, + std::map<v3s16, MapBlock *> *modified_blocks) +{ + MutexAutoLock envlock(m_server->m_env_mutex); + ScopeProfiler sp(g_profiler, + "EmergeThread: after Mapgen::makeChunk", SPT_AVG); + + /* + Perform post-processing on blocks (invalidate lighting, queue liquid + transforms, etc.) to finish block make + */ + m_map->finishBlockMake(bmdata, modified_blocks); + + MapBlock *block = m_map->getBlockNoCreateNoEx(pos); + if (!block) { + errorstream << "EmergeThread::finishGen: Couldn't grab block we " + "just generated: " << PP(pos) << std::endl; + return NULL; + } + + v3s16 minp = bmdata->blockpos_min * MAP_BLOCKSIZE; + v3s16 maxp = bmdata->blockpos_max * MAP_BLOCKSIZE + + v3s16(1,1,1) * (MAP_BLOCKSIZE - 1); + + // Ignore map edit events, they will not need to be sent + // to anybody because the block hasn't been sent to anybody + MapEditEventAreaIgnorer ign( + &m_server->m_ignore_map_edit_events_area, + VoxelArea(minp, maxp)); + + /* + Run Lua on_generated callbacks + */ + try { + m_server->getScriptIface()->environment_OnGenerated( + minp, maxp, m_mapgen->blockseed); + } catch (LuaError &e) { + m_server->setAsyncFatalError(e); + } + + EMERGE_DBG_OUT("ended up with: " << analyze_block(block)); + + /* + Clear mapgen state + */ + assert(!m_mapgen->generating); + m_mapgen->gennotify.clearEvents(); + m_mapgen->vm = nullptr; + + /* + Activate the block + */ + m_server->m_env->activateBlock(block, 0); + + return block; +} + + +void *EmergeThread::run() +{ + BEGIN_DEBUG_EXCEPTION_HANDLER + + v3s16 pos; + std::map<v3s16, MapBlock *> modified_blocks; + + m_map = &m_server->m_env->getServerMap(); + m_emerge = m_server->m_emerge; + m_mapgen = m_emerge->m_mapgens[id]; + enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info; + + try { + while (!stopRequested()) { + BlockEmergeData bedata; + BlockMakeData bmdata; + EmergeAction action; + MapBlock *block = nullptr; + + if (!popBlockEmerge(&pos, &bedata)) { + m_queue_event.wait(); + continue; + } + + if (blockpos_over_max_limit(pos)) + continue; + + bool allow_gen = bedata.flags & BLOCK_EMERGE_ALLOW_GEN; + EMERGE_DBG_OUT("pos=" PP(pos) " allow_gen=" << allow_gen); + + action = getBlockOrStartGen(pos, allow_gen, &block, &bmdata); + if (action == EMERGE_GENERATED) { + { + ScopeProfiler sp(g_profiler, + "EmergeThread: Mapgen::makeChunk", SPT_AVG); + + m_mapgen->makeChunk(&bmdata); + } + + block = finishGen(pos, &bmdata, &modified_blocks); + if (!block) + action = EMERGE_ERRORED; + } + + runCompletionCallbacks(pos, action, bedata.callbacks); + + if (block) + modified_blocks[pos] = block; + + if (!modified_blocks.empty()) + m_server->SetBlocksNotSent(modified_blocks); + modified_blocks.clear(); + } + } catch (VersionMismatchException &e) { + std::ostringstream err; + err << "World data version mismatch in MapBlock " << PP(pos) << std::endl + << "----" << std::endl + << "\"" << e.what() << "\"" << std::endl + << "See debug.txt." << std::endl + << "World probably saved by a newer version of " PROJECT_NAME_C "." + << std::endl; + m_server->setAsyncFatalError(err.str()); + } catch (SerializationError &e) { + std::ostringstream err; + err << "Invalid data in MapBlock " << PP(pos) << std::endl + << "----" << std::endl + << "\"" << e.what() << "\"" << std::endl + << "See debug.txt." << std::endl + << "You can ignore this using [ignore_world_load_errors = true]." + << std::endl; + m_server->setAsyncFatalError(err.str()); + } + + cancelPendingItems(); + + END_DEBUG_EXCEPTION_HANDLER + return NULL; +} diff --git a/src/emerge.h b/src/emerge.h new file mode 100644 index 0000000..1bac4b7 --- /dev/null +++ b/src/emerge.h @@ -0,0 +1,236 @@ +/* +Minetest +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <map> +#include <mutex> +#include "network/networkprotocol.h" +#include "irr_v3d.h" +#include "util/container.h" +#include "util/metricsbackend.h" +#include "mapgen/mapgen.h" // for MapgenParams +#include "map.h" + +#define BLOCK_EMERGE_ALLOW_GEN (1 << 0) +#define BLOCK_EMERGE_FORCE_QUEUE (1 << 1) + +#define EMERGE_DBG_OUT(x) { \ + if (enable_mapgen_debug_info) \ + infostream << "EmergeThread: " x << std::endl; \ +} + +class EmergeThread; +class NodeDefManager; +class Settings; + +class BiomeManager; +class OreManager; +class DecorationManager; +class SchematicManager; +class Server; +class ModApiMapgen; + +// Structure containing inputs/outputs for chunk generation +struct BlockMakeData { + MMVManip *vmanip = nullptr; + u64 seed = 0; + v3s16 blockpos_min; + v3s16 blockpos_max; + UniqueQueue<v3s16> transforming_liquid; + const NodeDefManager *nodedef = nullptr; + + BlockMakeData() = default; + + ~BlockMakeData() { delete vmanip; } +}; + +// Result from processing an item on the emerge queue +enum EmergeAction { + EMERGE_CANCELLED, + EMERGE_ERRORED, + EMERGE_FROM_MEMORY, + EMERGE_FROM_DISK, + EMERGE_GENERATED, +}; + +const static std::string emergeActionStrs[] = { + "cancelled", + "errored", + "from_memory", + "from_disk", + "generated", +}; + +// Callback +typedef void (*EmergeCompletionCallback)( + v3s16 blockpos, EmergeAction action, void *param); + +typedef std::vector< + std::pair< + EmergeCompletionCallback, + void * + > +> EmergeCallbackList; + +struct BlockEmergeData { + u16 peer_requested; + u16 flags; + EmergeCallbackList callbacks; +}; + +class EmergeParams { + friend class EmergeManager; +public: + EmergeParams() = delete; + ~EmergeParams(); + DISABLE_CLASS_COPY(EmergeParams); + + const NodeDefManager *ndef; // shared + bool enable_mapgen_debug_info; + + u32 gen_notify_on; + const std::set<u32> *gen_notify_on_deco_ids; // shared + + BiomeGen *biomegen; + BiomeManager *biomemgr; + OreManager *oremgr; + DecorationManager *decomgr; + SchematicManager *schemmgr; + +private: + EmergeParams(EmergeManager *parent, const BiomeGen *biomegen, + const BiomeManager *biomemgr, + const OreManager *oremgr, const DecorationManager *decomgr, + const SchematicManager *schemmgr); +}; + +class EmergeManager { + /* The mod API needs unchecked access to allow: + * - using decomgr or oremgr to place decos/ores + * - using schemmgr to load and place schematics + */ + friend class ModApiMapgen; +public: + const NodeDefManager *ndef; + bool enable_mapgen_debug_info; + + // Generation Notify + u32 gen_notify_on = 0; + std::set<u32> gen_notify_on_deco_ids; + + // Parameters passed to mapgens owned by ServerMap + // TODO(hmmmm): Remove this after mapgen helper methods using them + // are moved to ServerMap + MapgenParams *mgparams; + + // Hackish workaround: + // For now, EmergeManager must hold onto a ptr to the Map's setting manager + // since the Map can only be accessed through the Environment, and the + // Environment is not created until after script initialization. + MapSettingsManager *map_settings_mgr; + + // Methods + EmergeManager(Server *server, MetricsBackend *mb); + ~EmergeManager(); + DISABLE_CLASS_COPY(EmergeManager); + + const BiomeGen *getBiomeGen() const { return biomegen; } + + // no usage restrictions + const BiomeManager *getBiomeManager() const { return biomemgr; } + const OreManager *getOreManager() const { return oremgr; } + const DecorationManager *getDecorationManager() const { return decomgr; } + const SchematicManager *getSchematicManager() const { return schemmgr; } + // only usable before mapgen init + BiomeManager *getWritableBiomeManager(); + OreManager *getWritableOreManager(); + DecorationManager *getWritableDecorationManager(); + SchematicManager *getWritableSchematicManager(); + + void initMapgens(MapgenParams *mgparams); + + void startThreads(); + void stopThreads(); + bool isRunning(); + + bool enqueueBlockEmerge( + session_t peer_id, + v3s16 blockpos, + bool allow_generate, + bool ignore_queue_limits=false); + + bool enqueueBlockEmergeEx( + v3s16 blockpos, + session_t peer_id, + u16 flags, + EmergeCompletionCallback callback, + void *callback_param); + + bool isBlockInQueue(v3s16 pos); + + Mapgen *getCurrentMapgen(); + + // Mapgen helpers methods + int getSpawnLevelAtPoint(v2s16 p); + bool isBlockUnderground(v3s16 blockpos); + + static v3s16 getContainingChunk(v3s16 blockpos, s16 chunksize); + +private: + std::vector<Mapgen *> m_mapgens; + std::vector<EmergeThread *> m_threads; + bool m_threads_active = false; + + std::mutex m_queue_mutex; + std::map<v3s16, BlockEmergeData> m_blocks_enqueued; + std::unordered_map<u16, u32> m_peer_queue_count; + + u32 m_qlimit_total; + u32 m_qlimit_diskonly; + u32 m_qlimit_generate; + + // Emerge metrics + MetricCounterPtr m_completed_emerge_counter[5]; + + // Managers of various map generation-related components + // Note that each Mapgen gets a copy(!) of these to work with + BiomeGen *biomegen; + BiomeManager *biomemgr; + OreManager *oremgr; + DecorationManager *decomgr; + SchematicManager *schemmgr; + + // Requires m_queue_mutex held + EmergeThread *getOptimalThread(); + + bool pushBlockEmergeData( + v3s16 pos, + u16 peer_requested, + u16 flags, + EmergeCompletionCallback callback, + void *callback_param, + bool *entry_already_exists); + + bool popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata); + + void reportCompletedEmerge(EmergeAction action); + + friend class EmergeThread; +}; diff --git a/src/environment.cpp b/src/environment.cpp new file mode 100644 index 0000000..b04f775 --- /dev/null +++ b/src/environment.cpp @@ -0,0 +1,324 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <fstream> +#include "environment.h" +#include "collision.h" +#include "raycast.h" +#include "scripting_server.h" +#include "server.h" +#include "daynightratio.h" +#include "emerge.h" + + +Environment::Environment(IGameDef *gamedef): + m_time_of_day_speed(0.0f), + m_day_count(0), + m_gamedef(gamedef) +{ + m_cache_enable_shaders = g_settings->getBool("enable_shaders"); + m_cache_active_block_mgmt_interval = g_settings->getFloat("active_block_mgmt_interval"); + m_cache_abm_interval = g_settings->getFloat("abm_interval"); + m_cache_nodetimer_interval = g_settings->getFloat("nodetimer_interval"); + m_cache_abm_time_budget = g_settings->getFloat("abm_time_budget"); + + m_time_of_day = g_settings->getU32("world_start_time"); + m_time_of_day_f = (float)m_time_of_day / 24000.0f; +} + +u32 Environment::getDayNightRatio() +{ + MutexAutoLock lock(this->m_time_lock); + if (m_enable_day_night_ratio_override) + return m_day_night_ratio_override; + return time_to_daynight_ratio(m_time_of_day_f * 24000, m_cache_enable_shaders); +} + +void Environment::setTimeOfDaySpeed(float speed) +{ + m_time_of_day_speed = speed; +} + +void Environment::setDayNightRatioOverride(bool enable, u32 value) +{ + MutexAutoLock lock(this->m_time_lock); + m_enable_day_night_ratio_override = enable; + m_day_night_ratio_override = value; +} + +void Environment::setTimeOfDay(u32 time) +{ + MutexAutoLock lock(this->m_time_lock); + if (m_time_of_day > time) + ++m_day_count; + m_time_of_day = time; + m_time_of_day_f = (float)time / 24000.0; +} + +u32 Environment::getTimeOfDay() +{ + MutexAutoLock lock(this->m_time_lock); + return m_time_of_day; +} + +float Environment::getTimeOfDayF() +{ + MutexAutoLock lock(this->m_time_lock); + return m_time_of_day_f; +} + +bool Environment::line_of_sight(v3f pos1, v3f pos2, v3s16 *p) +{ + // Iterate trough nodes on the line + voxalgo::VoxelLineIterator iterator(pos1 / BS, (pos2 - pos1) / BS); + do { + MapNode n = getMap().getNode(iterator.m_current_node_pos); + + // Return non-air + if (n.param0 != CONTENT_AIR) { + if (p) + *p = iterator.m_current_node_pos; + return false; + } + iterator.next(); + } while (iterator.m_current_index <= iterator.m_last_index); + return true; +} + +/* + Check if a node is pointable +*/ +inline static bool isPointableNode(const MapNode &n, + const NodeDefManager *nodedef , bool liquids_pointable) +{ + const ContentFeatures &features = nodedef->get(n); + return features.pointable || + (liquids_pointable && features.isLiquid()); +} + +void Environment::continueRaycast(RaycastState *state, PointedThing *result) +{ + const NodeDefManager *nodedef = getMap().getNodeDefManager(); + if (state->m_initialization_needed) { + // Add objects + if (state->m_objects_pointable) { + std::vector<PointedThing> found; + getSelectedActiveObjects(state->m_shootline, found); + for (const PointedThing &pointed : found) { + state->m_found.push(pointed); + } + } + // Set search range + core::aabbox3d<s16> maximal_exceed = nodedef->getSelectionBoxIntUnion(); + state->m_search_range.MinEdge = -maximal_exceed.MaxEdge; + state->m_search_range.MaxEdge = -maximal_exceed.MinEdge; + // Setting is done + state->m_initialization_needed = false; + } + + // The index of the first pointed thing that was not returned + // before. The last index which needs to be tested. + s16 lastIndex = state->m_iterator.m_last_index; + if (!state->m_found.empty()) { + lastIndex = state->m_iterator.getIndex( + floatToInt(state->m_found.top().intersection_point, BS)); + } + + Map &map = getMap(); + // If a node is found, this is the center of the + // first nodebox the shootline meets. + v3f found_boxcenter(0, 0, 0); + // The untested nodes are in this range. + core::aabbox3d<s16> new_nodes; + while (state->m_iterator.m_current_index <= lastIndex) { + // Test the nodes around the current node in search_range. + new_nodes = state->m_search_range; + new_nodes.MinEdge += state->m_iterator.m_current_node_pos; + new_nodes.MaxEdge += state->m_iterator.m_current_node_pos; + + // Only check new nodes + v3s16 delta = state->m_iterator.m_current_node_pos + - state->m_previous_node; + if (delta.X > 0) { + new_nodes.MinEdge.X = new_nodes.MaxEdge.X; + } else if (delta.X < 0) { + new_nodes.MaxEdge.X = new_nodes.MinEdge.X; + } else if (delta.Y > 0) { + new_nodes.MinEdge.Y = new_nodes.MaxEdge.Y; + } else if (delta.Y < 0) { + new_nodes.MaxEdge.Y = new_nodes.MinEdge.Y; + } else if (delta.Z > 0) { + new_nodes.MinEdge.Z = new_nodes.MaxEdge.Z; + } else if (delta.Z < 0) { + new_nodes.MaxEdge.Z = new_nodes.MinEdge.Z; + } + + if (new_nodes.MaxEdge.X == S16_MAX || + new_nodes.MaxEdge.Y == S16_MAX || + new_nodes.MaxEdge.Z == S16_MAX) { + break; // About to go out of bounds + } + + // For each untested node + for (s16 x = new_nodes.MinEdge.X; x <= new_nodes.MaxEdge.X; x++) + for (s16 y = new_nodes.MinEdge.Y; y <= new_nodes.MaxEdge.Y; y++) + for (s16 z = new_nodes.MinEdge.Z; z <= new_nodes.MaxEdge.Z; z++) { + MapNode n; + v3s16 np(x, y, z); + bool is_valid_position; + + n = map.getNode(np, &is_valid_position); + if (!(is_valid_position && isPointableNode(n, nodedef, + state->m_liquids_pointable))) { + continue; + } + + PointedThing result; + + std::vector<aabb3f> boxes; + n.getSelectionBoxes(nodedef, &boxes, + n.getNeighbors(np, &map)); + + // Is there a collision with a selection box? + bool is_colliding = false; + // Minimal distance of all collisions + float min_distance_sq = 10000000; + // ID of the current box (loop counter) + u16 id = 0; + + v3f npf = intToFloat(np, BS); + // This loop translates the boxes to their in-world place. + for (aabb3f &box : boxes) { + box.MinEdge += npf; + box.MaxEdge += npf; + + v3f intersection_point; + v3s16 intersection_normal; + if (!boxLineCollision(box, state->m_shootline.start, + state->m_shootline.getVector(), &intersection_point, + &intersection_normal)) { + ++id; + continue; + } + + f32 distanceSq = (intersection_point + - state->m_shootline.start).getLengthSQ(); + // If this is the nearest collision, save it + if (min_distance_sq > distanceSq) { + min_distance_sq = distanceSq; + result.intersection_point = intersection_point; + result.intersection_normal = intersection_normal; + result.box_id = id; + found_boxcenter = box.getCenter(); + is_colliding = true; + } + ++id; + } + // If there wasn't a collision, stop + if (!is_colliding) { + continue; + } + result.type = POINTEDTHING_NODE; + result.node_undersurface = np; + result.distanceSq = min_distance_sq; + // Set undersurface and abovesurface nodes + f32 d = 0.002 * BS; + v3f fake_intersection = result.intersection_point; + // Move intersection towards its source block. + if (fake_intersection.X < found_boxcenter.X) { + fake_intersection.X += d; + } else { + fake_intersection.X -= d; + } + if (fake_intersection.Y < found_boxcenter.Y) { + fake_intersection.Y += d; + } else { + fake_intersection.Y -= d; + } + if (fake_intersection.Z < found_boxcenter.Z) { + fake_intersection.Z += d; + } else { + fake_intersection.Z -= d; + } + result.node_real_undersurface = floatToInt( + fake_intersection, BS); + result.node_abovesurface = result.node_real_undersurface + + result.intersection_normal; + // Push found PointedThing + state->m_found.push(result); + // If this is nearer than the old nearest object, + // the search can be shorter + s16 newIndex = state->m_iterator.getIndex( + result.node_real_undersurface); + if (newIndex < lastIndex) { + lastIndex = newIndex; + } + } + // Next node + state->m_previous_node = state->m_iterator.m_current_node_pos; + state->m_iterator.next(); + } + // Return empty PointedThing if nothing left on the ray + if (state->m_found.empty()) { + result->type = POINTEDTHING_NOTHING; + } else { + *result = state->m_found.top(); + state->m_found.pop(); + } +} + +void Environment::stepTimeOfDay(float dtime) +{ + MutexAutoLock lock(this->m_time_lock); + + // Cached in order to prevent the two reads we do to give + // different results (can be written by code not under the lock) + f32 cached_time_of_day_speed = m_time_of_day_speed; + + f32 speed = cached_time_of_day_speed * 24000. / (24. * 3600); + m_time_conversion_skew += dtime; + u32 units = (u32)(m_time_conversion_skew * speed); + bool sync_f = false; + if (units > 0) { + // Sync at overflow + if (m_time_of_day + units >= 24000) { + sync_f = true; + ++m_day_count; + } + m_time_of_day = (m_time_of_day + units) % 24000; + if (sync_f) + m_time_of_day_f = (float)m_time_of_day / 24000.0; + } + if (speed > 0) { + m_time_conversion_skew -= (f32)units / speed; + } + if (!sync_f) { + m_time_of_day_f += cached_time_of_day_speed / 24 / 3600 * dtime; + if (m_time_of_day_f > 1.0) + m_time_of_day_f -= 1.0; + if (m_time_of_day_f < 0.0) + m_time_of_day_f += 1.0; + } +} + +u32 Environment::getDayCount() +{ + // Atomic<u32> counter + return m_day_count; +} diff --git a/src/environment.h b/src/environment.h new file mode 100644 index 0000000..b4884fd --- /dev/null +++ b/src/environment.h @@ -0,0 +1,156 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +/* + This class is the game's environment. + It contains: + - The map + - Players + - Other objects + - The current time in the game + - etc. +*/ + +#include <list> +#include <queue> +#include <map> +#include <atomic> +#include <mutex> +#include "irr_v3d.h" +#include "network/networkprotocol.h" // for AccessDeniedCode +#include "util/basic_macros.h" + +class IGameDef; +class Map; +struct PointedThing; +class RaycastState; + +class Environment +{ +public: + // Environment will delete the map passed to the constructor + Environment(IGameDef *gamedef); + virtual ~Environment() = default; + DISABLE_CLASS_COPY(Environment); + + /* + Step everything in environment. + - Move players + - Step mobs + - Run timers of map + */ + virtual void step(f32 dtime) = 0; + + virtual Map &getMap() = 0; + + u32 getDayNightRatio(); + + // 0-23999 + virtual void setTimeOfDay(u32 time); + u32 getTimeOfDay(); + float getTimeOfDayF(); + + void stepTimeOfDay(float dtime); + + void setTimeOfDaySpeed(float speed); + + void setDayNightRatioOverride(bool enable, u32 value); + + u32 getDayCount(); + + /*! + * Returns false if the given line intersects with a + * non-air node, true otherwise. + * \param pos1 start of the line + * \param pos2 end of the line + * \param p output, position of the first non-air node + * the line intersects + */ + bool line_of_sight(v3f pos1, v3f pos2, v3s16 *p = nullptr); + + /*! + * Gets the objects pointed by the shootline as + * pointed things. + * If this is a client environment, the local player + * won't be returned. + * @param[in] shootline_on_map the shootline for + * the test in world coordinates + * + * @param[out] objects found objects + */ + virtual void getSelectedActiveObjects(const core::line3d<f32> &shootline_on_map, + std::vector<PointedThing> &objects) = 0; + + /*! + * Returns the next node or object the shootline meets. + * @param state current state of the raycast + * @result output, will contain the next pointed thing + */ + void continueRaycast(RaycastState *state, PointedThing *result); + + // counter used internally when triggering ABMs + u32 m_added_objects; + + IGameDef *getGameDef() { return m_gamedef; } + +protected: + std::atomic<float> m_time_of_day_speed; + + /* + * Below: values managed by m_time_lock + */ + // Time of day in milli-hours (0-23999), determines day and night + u32 m_time_of_day; + // Time of day in 0...1 + float m_time_of_day_f; + // Stores the skew created by the float -> u32 conversion + // to be applied at next conversion, so that there is no real skew. + float m_time_conversion_skew = 0.0f; + // Overriding the day-night ratio is useful for custom sky visuals + bool m_enable_day_night_ratio_override = false; + u32 m_day_night_ratio_override = 0.0f; + // Days from the server start, accounts for time shift + // in game (e.g. /time or bed usage) + std::atomic<u32> m_day_count; + /* + * Above: values managed by m_time_lock + */ + + /* TODO: Add a callback function so these can be updated when a setting + * changes. At this point in time it doesn't matter (e.g. /set + * is documented to change server settings only) + * + * TODO: Local caching of settings is not optimal and should at some stage + * be updated to use a global settings object for getting thse values + * (as opposed to the this local caching). This can be addressed in + * a later release. + */ + bool m_cache_enable_shaders; + float m_cache_active_block_mgmt_interval; + float m_cache_abm_interval; + float m_cache_nodetimer_interval; + float m_cache_abm_time_budget; + + IGameDef *m_gamedef; + +private: + std::mutex m_time_lock; +}; diff --git a/src/exceptions.h b/src/exceptions.h new file mode 100644 index 0000000..a558adc --- /dev/null +++ b/src/exceptions.h @@ -0,0 +1,126 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <exception> +#include <string> + + +class BaseException : public std::exception +{ +public: + BaseException(const std::string &s) throw(): m_s(s) {} + ~BaseException() throw() = default; + + virtual const char * what() const throw() + { + return m_s.c_str(); + } +protected: + std::string m_s; +}; + +class AlreadyExistsException : public BaseException { +public: + AlreadyExistsException(const std::string &s): BaseException(s) {} +}; + +class VersionMismatchException : public BaseException { +public: + VersionMismatchException(const std::string &s): BaseException(s) {} +}; + +class FileNotGoodException : public BaseException { +public: + FileNotGoodException(const std::string &s): BaseException(s) {} +}; + +class DatabaseException : public BaseException { +public: + DatabaseException(const std::string &s): BaseException(s) {} +}; + +class SerializationError : public BaseException { +public: + SerializationError(const std::string &s): BaseException(s) {} +}; + +class PacketError : public BaseException { +public: + PacketError(const std::string &s): BaseException(s) {} +}; + +class SettingNotFoundException : public BaseException { +public: + SettingNotFoundException(const std::string &s): BaseException(s) {} +}; + +class ItemNotFoundException : public BaseException { +public: + ItemNotFoundException(const std::string &s): BaseException(s) {} +}; + +class ServerError : public BaseException { +public: + ServerError(const std::string &s): BaseException(s) {} +}; + +class ClientStateError : public BaseException { +public: + ClientStateError(const std::string &s): BaseException(s) {} +}; + +class PrngException : public BaseException { +public: + PrngException(const std::string &s): BaseException(s) {} +}; + +class ModError : public BaseException { +public: + ModError(const std::string &s): BaseException(s) {} +}; + + +/* + Some "old-style" interrupts: +*/ + +class InvalidNoiseParamsException : public BaseException { +public: + InvalidNoiseParamsException(): + BaseException("One or more noise parameters were invalid or require " + "too much memory") + {} + + InvalidNoiseParamsException(const std::string &s): + BaseException(s) + {} +}; + +class InvalidPositionException : public BaseException +{ +public: + InvalidPositionException(): + BaseException("Somebody tried to get/set something in a nonexistent position.") + {} + InvalidPositionException(const std::string &s): + BaseException(s) + {} +}; diff --git a/src/face_position_cache.cpp b/src/face_position_cache.cpp new file mode 100644 index 0000000..7a8f235 --- /dev/null +++ b/src/face_position_cache.cpp @@ -0,0 +1,110 @@ +/* +Minetest +Copyright (C) 2015 Nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "face_position_cache.h" +#include "threading/mutex_auto_lock.h" + + +std::unordered_map<u16, std::vector<v3s16>> FacePositionCache::cache; +std::mutex FacePositionCache::cache_mutex; + +// Calculate the borders of a "d-radius" cube +const std::vector<v3s16> &FacePositionCache::getFacePositions(u16 d) +{ + MutexAutoLock lock(cache_mutex); + std::unordered_map<u16, std::vector<v3s16>>::const_iterator it = cache.find(d); + if (it != cache.end()) + return it->second; + + return generateFacePosition(d); +} + +const std::vector<v3s16> &FacePositionCache::generateFacePosition(u16 d) +{ + cache[d] = std::vector<v3s16>(); + std::vector<v3s16> &c = cache[d]; + if (d == 0) { + c.emplace_back(0,0,0); + return c; + } + if (d == 1) { + // This is an optimized sequence of coordinates. + c.emplace_back(0, 1, 0); // Top + c.emplace_back(0, 0, 1); // Back + c.emplace_back(-1, 0, 0); // Left + c.emplace_back(1, 0, 0); // Right + c.emplace_back(0, 0,-1); // Front + c.emplace_back(0,-1, 0); // Bottom + // 6 + c.emplace_back(-1, 0, 1); // Back left + c.emplace_back(1, 0, 1); // Back right + c.emplace_back(-1, 0,-1); // Front left + c.emplace_back(1, 0,-1); // Front right + c.emplace_back(-1,-1, 0); // Bottom left + c.emplace_back(1,-1, 0); // Bottom right + c.emplace_back(0,-1, 1); // Bottom back + c.emplace_back(0,-1,-1); // Bottom front + c.emplace_back(-1, 1, 0); // Top left + c.emplace_back(1, 1, 0); // Top right + c.emplace_back(0, 1, 1); // Top back + c.emplace_back(0, 1,-1); // Top front + // 18 + c.emplace_back(-1, 1, 1); // Top back-left + c.emplace_back(1, 1, 1); // Top back-right + c.emplace_back(-1, 1,-1); // Top front-left + c.emplace_back(1, 1,-1); // Top front-right + c.emplace_back(-1,-1, 1); // Bottom back-left + c.emplace_back(1,-1, 1); // Bottom back-right + c.emplace_back(-1,-1,-1); // Bottom front-left + c.emplace_back(1,-1,-1); // Bottom front-right + // 26 + return c; + } + + // Take blocks in all sides, starting from y=0 and going +-y + for (s16 y = 0; y <= d - 1; y++) { + // Left and right side, including borders + for (s16 z =- d; z <= d; z++) { + c.emplace_back(d, y, z); + c.emplace_back(-d, y, z); + if (y != 0) { + c.emplace_back(d, -y, z); + c.emplace_back(-d, -y, z); + } + } + // Back and front side, excluding borders + for (s16 x = -d + 1; x <= d - 1; x++) { + c.emplace_back(x, y, d); + c.emplace_back(x, y, -d); + if (y != 0) { + c.emplace_back(x, -y, d); + c.emplace_back(x, -y, -d); + } + } + } + + // Take the bottom and top face with borders + // -d < x < d, y = +-d, -d < z < d + for (s16 x = -d; x <= d; x++) + for (s16 z = -d; z <= d; z++) { + c.emplace_back(x, -d, z); + c.emplace_back(x, d, z); + } + return c; +} diff --git a/src/face_position_cache.h b/src/face_position_cache.h new file mode 100644 index 0000000..36cb064 --- /dev/null +++ b/src/face_position_cache.h @@ -0,0 +1,41 @@ +/* +Minetest +Copyright (C) 2015 Nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_v3d.h" + +#include <map> +#include <vector> +#include <unordered_map> +#include <mutex> + +/* + * This class permits caching getFacePosition call results. + * This reduces CPU usage and vector calls. + */ +class FacePositionCache { +public: + static const std::vector<v3s16> &getFacePositions(u16 d); + +private: + static const std::vector<v3s16> &generateFacePosition(u16 d); + static std::unordered_map<u16, std::vector<v3s16>> cache; + static std::mutex cache_mutex; +}; diff --git a/src/filesys.cpp b/src/filesys.cpp new file mode 100644 index 0000000..28df320 --- /dev/null +++ b/src/filesys.cpp @@ -0,0 +1,879 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "filesys.h" +#include "util/string.h" +#include <iostream> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <cerrno> +#include <fstream> +#include "log.h" +#include "config.h" +#include "porting.h" +#ifndef SERVER +#include "irr_ptr.h" +#endif + +namespace fs +{ + +#ifdef _WIN32 + +/*********** + * Windows * + ***********/ + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif +#include <windows.h> +#include <shlwapi.h> +#include <io.h> +#include <direct.h> + +std::vector<DirListNode> GetDirListing(const std::string &pathstring) +{ + std::vector<DirListNode> listing; + + WIN32_FIND_DATA FindFileData; + HANDLE hFind = INVALID_HANDLE_VALUE; + DWORD dwError; + + std::string dirSpec = pathstring + "\\*"; + + // Find the first file in the directory. + hFind = FindFirstFile(dirSpec.c_str(), &FindFileData); + + if (hFind == INVALID_HANDLE_VALUE) { + dwError = GetLastError(); + if (dwError != ERROR_FILE_NOT_FOUND && dwError != ERROR_PATH_NOT_FOUND) { + errorstream << "GetDirListing: FindFirstFile error." + << " Error is " << dwError << std::endl; + } + } else { + // NOTE: + // Be very sure to not include '..' in the results, it will + // result in an epic failure when deleting stuff. + + DirListNode node; + node.name = FindFileData.cFileName; + node.dir = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + if (node.name != "." && node.name != "..") + listing.push_back(node); + + // List all the other files in the directory. + while (FindNextFile(hFind, &FindFileData) != 0) { + DirListNode node; + node.name = FindFileData.cFileName; + node.dir = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + if(node.name != "." && node.name != "..") + listing.push_back(node); + } + + dwError = GetLastError(); + FindClose(hFind); + if (dwError != ERROR_NO_MORE_FILES) { + errorstream << "GetDirListing: FindNextFile error." + << " Error is " << dwError << std::endl; + listing.clear(); + return listing; + } + } + return listing; +} + +bool CreateDir(const std::string &path) +{ + bool r = CreateDirectory(path.c_str(), NULL); + if(r == true) + return true; + if(GetLastError() == ERROR_ALREADY_EXISTS) + return true; + return false; +} + +bool PathExists(const std::string &path) +{ + return (GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES); +} + +bool IsPathAbsolute(const std::string &path) +{ + return !PathIsRelative(path.c_str()); +} + +bool IsDir(const std::string &path) +{ + DWORD attr = GetFileAttributes(path.c_str()); + return (attr != INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_DIRECTORY)); +} + +bool IsDirDelimiter(char c) +{ + return c == '/' || c == '\\'; +} + +bool RecursiveDelete(const std::string &path) +{ + infostream << "Recursively deleting \"" << path << "\"" << std::endl; + if (!IsDir(path)) { + infostream << "RecursiveDelete: Deleting file " << path << std::endl; + if (!DeleteFile(path.c_str())) { + errorstream << "RecursiveDelete: Failed to delete file " + << path << std::endl; + return false; + } + return true; + } + infostream << "RecursiveDelete: Deleting content of directory " + << path << std::endl; + std::vector<DirListNode> content = GetDirListing(path); + for (const DirListNode &n: content) { + std::string fullpath = path + DIR_DELIM + n.name; + if (!RecursiveDelete(fullpath)) { + errorstream << "RecursiveDelete: Failed to recurse to " + << fullpath << std::endl; + return false; + } + } + infostream << "RecursiveDelete: Deleting directory " << path << std::endl; + if (!RemoveDirectory(path.c_str())) { + errorstream << "Failed to recursively delete directory " + << path << std::endl; + return false; + } + return true; +} + +bool DeleteSingleFileOrEmptyDirectory(const std::string &path) +{ + DWORD attr = GetFileAttributes(path.c_str()); + bool is_directory = (attr != INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_DIRECTORY)); + if(!is_directory) + { + bool did = DeleteFile(path.c_str()); + return did; + } + else + { + bool did = RemoveDirectory(path.c_str()); + return did; + } +} + +std::string TempPath() +{ + DWORD bufsize = GetTempPath(0, NULL); + if(bufsize == 0){ + errorstream<<"GetTempPath failed, error = "<<GetLastError()<<std::endl; + return ""; + } + std::string buf; + buf.resize(bufsize); + DWORD len = GetTempPath(bufsize, &buf[0]); + if(len == 0 || len > bufsize){ + errorstream<<"GetTempPath failed, error = "<<GetLastError()<<std::endl; + return ""; + } + buf.resize(len); + return buf; +} + +std::string CreateTempFile() +{ + std::string path = TempPath() + DIR_DELIM "MT_XXXXXX"; + _mktemp_s(&path[0], path.size() + 1); // modifies path + HANDLE file = CreateFile(path.c_str(), GENERIC_WRITE, 0, nullptr, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (file == INVALID_HANDLE_VALUE) + return ""; + CloseHandle(file); + return path; +} + +#else + +/********* + * POSIX * + *********/ + +#include <sys/types.h> +#include <dirent.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <unistd.h> + +std::vector<DirListNode> GetDirListing(const std::string &pathstring) +{ + std::vector<DirListNode> listing; + + DIR *dp; + struct dirent *dirp; + if((dp = opendir(pathstring.c_str())) == NULL) { + //infostream<<"Error("<<errno<<") opening "<<pathstring<<std::endl; + return listing; + } + + while ((dirp = readdir(dp)) != NULL) { + // NOTE: + // Be very sure to not include '..' in the results, it will + // result in an epic failure when deleting stuff. + if(strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0) + continue; + + DirListNode node; + node.name = dirp->d_name; + + int isdir = -1; // -1 means unknown + + /* + POSIX doesn't define d_type member of struct dirent and + certain filesystems on glibc/Linux will only return + DT_UNKNOWN for the d_type member. + + Also we don't know whether symlinks are directories or not. + */ +#ifdef _DIRENT_HAVE_D_TYPE + if(dirp->d_type != DT_UNKNOWN && dirp->d_type != DT_LNK) + isdir = (dirp->d_type == DT_DIR); +#endif /* _DIRENT_HAVE_D_TYPE */ + + /* + Was d_type DT_UNKNOWN, DT_LNK or nonexistent? + If so, try stat(). + */ + if(isdir == -1) { + struct stat statbuf{}; + if (stat((pathstring + "/" + node.name).c_str(), &statbuf)) + continue; + isdir = ((statbuf.st_mode & S_IFDIR) == S_IFDIR); + } + node.dir = isdir; + listing.push_back(node); + } + closedir(dp); + + return listing; +} + +bool CreateDir(const std::string &path) +{ + int r = mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + if (r == 0) { + return true; + } + + // If already exists, return true + if (errno == EEXIST) + return true; + return false; + +} + +bool PathExists(const std::string &path) +{ + struct stat st{}; + return (stat(path.c_str(),&st) == 0); +} + +bool IsPathAbsolute(const std::string &path) +{ + return path[0] == '/'; +} + +bool IsDir(const std::string &path) +{ + struct stat statbuf{}; + if(stat(path.c_str(), &statbuf)) + return false; // Actually error; but certainly not a directory + return ((statbuf.st_mode & S_IFDIR) == S_IFDIR); +} + +bool IsDirDelimiter(char c) +{ + return c == '/'; +} + +bool RecursiveDelete(const std::string &path) +{ + /* + Execute the 'rm' command directly, by fork() and execve() + */ + + infostream<<"Removing \""<<path<<"\""<<std::endl; + + pid_t child_pid = fork(); + + if(child_pid == 0) + { + // Child + const char *argv[4] = { +#ifdef __ANDROID__ + "/system/bin/rm", +#else + "/bin/rm", +#endif + "-rf", + path.c_str(), + NULL + }; + + verbosestream<<"Executing '"<<argv[0]<<"' '"<<argv[1]<<"' '" + <<argv[2]<<"'"<<std::endl; + + execv(argv[0], const_cast<char**>(argv)); + + // Execv shouldn't return. Failed. + _exit(1); + } + else + { + // Parent + int child_status; + pid_t tpid; + do{ + tpid = wait(&child_status); + }while(tpid != child_pid); + return (child_status == 0); + } +} + +bool DeleteSingleFileOrEmptyDirectory(const std::string &path) +{ + if (IsDir(path)) { + bool did = (rmdir(path.c_str()) == 0); + if (!did) + errorstream << "rmdir errno: " << errno << ": " << strerror(errno) + << std::endl; + return did; + } + + bool did = (unlink(path.c_str()) == 0); + if (!did) + errorstream << "unlink errno: " << errno << ": " << strerror(errno) + << std::endl; + return did; +} + +std::string TempPath() +{ + /* + Should the environment variables TMPDIR, TMP and TEMP + and the macro P_tmpdir (if defined by stdio.h) be checked + before falling back on /tmp? + + Probably not, because this function is intended to be + compatible with lua's os.tmpname which under the default + configuration hardcodes mkstemp("/tmp/lua_XXXXXX"). + */ + +#ifdef __ANDROID__ + return porting::path_cache; +#else + return DIR_DELIM "tmp"; +#endif +} + +std::string CreateTempFile() +{ + std::string path = TempPath() + DIR_DELIM "MT_XXXXXX"; + int fd = mkstemp(&path[0]); // modifies path + if (fd == -1) + return ""; + close(fd); + return path; +} + +#endif + +/**************************** + * portable implementations * + ****************************/ + +void GetRecursiveDirs(std::vector<std::string> &dirs, const std::string &dir) +{ + static const std::set<char> chars_to_ignore = { '_', '.' }; + if (dir.empty() || !IsDir(dir)) + return; + dirs.push_back(dir); + fs::GetRecursiveSubPaths(dir, dirs, false, chars_to_ignore); +} + +std::vector<std::string> GetRecursiveDirs(const std::string &dir) +{ + std::vector<std::string> result; + GetRecursiveDirs(result, dir); + return result; +} + +void GetRecursiveSubPaths(const std::string &path, + std::vector<std::string> &dst, + bool list_files, + const std::set<char> &ignore) +{ + std::vector<DirListNode> content = GetDirListing(path); + for (const auto &n : content) { + std::string fullpath = path + DIR_DELIM + n.name; + if (ignore.count(n.name[0])) + continue; + if (list_files || n.dir) + dst.push_back(fullpath); + if (n.dir) + GetRecursiveSubPaths(fullpath, dst, list_files, ignore); + } +} + +bool RecursiveDeleteContent(const std::string &path) +{ + infostream<<"Removing content of \""<<path<<"\""<<std::endl; + std::vector<DirListNode> list = GetDirListing(path); + for (const DirListNode &dln : list) { + if(trim(dln.name) == "." || trim(dln.name) == "..") + continue; + std::string childpath = path + DIR_DELIM + dln.name; + bool r = RecursiveDelete(childpath); + if(!r) { + errorstream << "Removing \"" << childpath << "\" failed" << std::endl; + return false; + } + } + return true; +} + +bool CreateAllDirs(const std::string &path) +{ + + std::vector<std::string> tocreate; + std::string basepath = path; + while(!PathExists(basepath)) + { + tocreate.push_back(basepath); + basepath = RemoveLastPathComponent(basepath); + if(basepath.empty()) + break; + } + for(int i=tocreate.size()-1;i>=0;i--) + if(!CreateDir(tocreate[i])) + return false; + return true; +} + +bool CopyFileContents(const std::string &source, const std::string &target) +{ + FILE *sourcefile = fopen(source.c_str(), "rb"); + if(sourcefile == NULL){ + errorstream<<source<<": can't open for reading: " + <<strerror(errno)<<std::endl; + return false; + } + + FILE *targetfile = fopen(target.c_str(), "wb"); + if(targetfile == NULL){ + errorstream<<target<<": can't open for writing: " + <<strerror(errno)<<std::endl; + fclose(sourcefile); + return false; + } + + size_t total = 0; + bool retval = true; + bool done = false; + char readbuffer[BUFSIZ]; + while(!done){ + size_t readbytes = fread(readbuffer, 1, + sizeof(readbuffer), sourcefile); + total += readbytes; + if(ferror(sourcefile)){ + errorstream<<source<<": IO error: " + <<strerror(errno)<<std::endl; + retval = false; + done = true; + } + if(readbytes > 0){ + fwrite(readbuffer, 1, readbytes, targetfile); + } + if(feof(sourcefile) || ferror(sourcefile)){ + // flush destination file to catch write errors + // (e.g. disk full) + fflush(targetfile); + done = true; + } + if(ferror(targetfile)){ + errorstream<<target<<": IO error: " + <<strerror(errno)<<std::endl; + retval = false; + done = true; + } + } + infostream<<"copied "<<total<<" bytes from " + <<source<<" to "<<target<<std::endl; + fclose(sourcefile); + fclose(targetfile); + return retval; +} + +bool CopyDir(const std::string &source, const std::string &target) +{ + if(PathExists(source)){ + if(!PathExists(target)){ + fs::CreateAllDirs(target); + } + bool retval = true; + std::vector<DirListNode> content = fs::GetDirListing(source); + + for (const auto &dln : content) { + std::string sourcechild = source + DIR_DELIM + dln.name; + std::string targetchild = target + DIR_DELIM + dln.name; + if(dln.dir){ + if(!fs::CopyDir(sourcechild, targetchild)){ + retval = false; + } + } + else { + if(!fs::CopyFileContents(sourcechild, targetchild)){ + retval = false; + } + } + } + return retval; + } + + return false; +} + +bool MoveDir(const std::string &source, const std::string &target) +{ + infostream << "Moving \"" << source << "\" to \"" << target << "\"" << std::endl; + + // If target exists as empty folder delete, otherwise error + if (fs::PathExists(target)) { + if (rmdir(target.c_str()) != 0) { + errorstream << "MoveDir: target \"" << target + << "\" exists as file or non-empty folder" << std::endl; + return false; + } + } + + // Try renaming first which is instant + if (fs::Rename(source, target)) + return true; + + infostream << "MoveDir: rename not possible, will copy instead" << std::endl; + bool retval = fs::CopyDir(source, target); + if (retval) + retval &= fs::RecursiveDelete(source); + return retval; +} + +bool PathStartsWith(const std::string &path, const std::string &prefix) +{ + size_t pathsize = path.size(); + size_t pathpos = 0; + size_t prefixsize = prefix.size(); + size_t prefixpos = 0; + for(;;){ + bool delim1 = pathpos == pathsize + || IsDirDelimiter(path[pathpos]); + bool delim2 = prefixpos == prefixsize + || IsDirDelimiter(prefix[prefixpos]); + + if(delim1 != delim2) + return false; + + if(delim1){ + while(pathpos < pathsize && + IsDirDelimiter(path[pathpos])) + ++pathpos; + while(prefixpos < prefixsize && + IsDirDelimiter(prefix[prefixpos])) + ++prefixpos; + if(prefixpos == prefixsize) + return true; + if(pathpos == pathsize) + return false; + } + else{ + size_t len = 0; + do{ + char pathchar = path[pathpos+len]; + char prefixchar = prefix[prefixpos+len]; + if(FILESYS_CASE_INSENSITIVE){ + pathchar = tolower(pathchar); + prefixchar = tolower(prefixchar); + } + if(pathchar != prefixchar) + return false; + ++len; + } while(pathpos+len < pathsize + && !IsDirDelimiter(path[pathpos+len]) + && prefixpos+len < prefixsize + && !IsDirDelimiter( + prefix[prefixpos+len])); + pathpos += len; + prefixpos += len; + } + } +} + +std::string RemoveLastPathComponent(const std::string &path, + std::string *removed, int count) +{ + if(removed) + *removed = ""; + + size_t remaining = path.size(); + + for(int i = 0; i < count; ++i){ + // strip a dir delimiter + while(remaining != 0 && IsDirDelimiter(path[remaining-1])) + remaining--; + // strip a path component + size_t component_end = remaining; + while(remaining != 0 && !IsDirDelimiter(path[remaining-1])) + remaining--; + size_t component_start = remaining; + // strip a dir delimiter + while(remaining != 0 && IsDirDelimiter(path[remaining-1])) + remaining--; + if(removed){ + std::string component = path.substr(component_start, + component_end - component_start); + if(i) + *removed = component + DIR_DELIM + *removed; + else + *removed = component; + } + } + return path.substr(0, remaining); +} + +std::string RemoveRelativePathComponents(std::string path) +{ + size_t pos = path.size(); + size_t dotdot_count = 0; + while (pos != 0) { + size_t component_with_delim_end = pos; + // skip a dir delimiter + while (pos != 0 && IsDirDelimiter(path[pos-1])) + pos--; + // strip a path component + size_t component_end = pos; + while (pos != 0 && !IsDirDelimiter(path[pos-1])) + pos--; + size_t component_start = pos; + + std::string component = path.substr(component_start, + component_end - component_start); + bool remove_this_component = false; + if (component == ".") { + remove_this_component = true; + } else if (component == "..") { + remove_this_component = true; + dotdot_count += 1; + } else if (dotdot_count != 0) { + remove_this_component = true; + dotdot_count -= 1; + } + + if (remove_this_component) { + while (pos != 0 && IsDirDelimiter(path[pos-1])) + pos--; + if (component_start == 0) { + // We need to remove the delemiter too + path = path.substr(component_with_delim_end, std::string::npos); + } else { + path = path.substr(0, pos) + DIR_DELIM + + path.substr(component_with_delim_end, std::string::npos); + } + if (pos > 0) + pos++; + } + } + + if (dotdot_count > 0) + return ""; + + // remove trailing dir delimiters + pos = path.size(); + while (pos != 0 && IsDirDelimiter(path[pos-1])) + pos--; + return path.substr(0, pos); +} + +std::string AbsolutePath(const std::string &path) +{ +#ifdef _WIN32 + char *abs_path = _fullpath(NULL, path.c_str(), MAX_PATH); +#else + char *abs_path = realpath(path.c_str(), NULL); +#endif + if (!abs_path) return ""; + std::string abs_path_str(abs_path); + free(abs_path); + return abs_path_str; +} + +const char *GetFilenameFromPath(const char *path) +{ + const char *filename = strrchr(path, DIR_DELIM_CHAR); + // Consistent with IsDirDelimiter this function handles '/' too + if (DIR_DELIM_CHAR != '/') { + const char *tmp = strrchr(path, '/'); + if (tmp && tmp > filename) + filename = tmp; + } + return filename ? filename + 1 : path; +} + +bool safeWriteToFile(const std::string &path, const std::string &content) +{ + std::string tmp_file = path + ".~mt"; + + // Write to a tmp file + std::ofstream os(tmp_file.c_str(), std::ios::binary); + if (!os.good()) + return false; + os << content; + os.flush(); + os.close(); + if (os.fail()) { + // Remove the temporary file because writing it failed and it's useless. + remove(tmp_file.c_str()); + return false; + } + + bool rename_success = false; + + // Move the finished temporary file over the real file +#ifdef _WIN32 + // When creating the file, it can cause Windows Search indexer, virus scanners and other apps + // to query the file. This can make the move file call below fail. + // We retry up to 5 times, with a 1ms sleep between, before we consider the whole operation failed + int number_attempts = 0; + while (number_attempts < 5) { + rename_success = MoveFileEx(tmp_file.c_str(), path.c_str(), + MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH); + if (rename_success) + break; + sleep_ms(1); + ++number_attempts; + } +#else + // On POSIX compliant systems rename() is specified to be able to swap the + // file in place of the destination file, making this a truly error-proof + // transaction. + rename_success = rename(tmp_file.c_str(), path.c_str()) == 0; +#endif + if (!rename_success) { + warningstream << "Failed to write to file: " << path.c_str() << std::endl; + // Remove the temporary file because moving it over the target file + // failed. + remove(tmp_file.c_str()); + return false; + } + + return true; +} + +#ifndef SERVER +bool extractZipFile(io::IFileSystem *fs, const char *filename, const std::string &destination) +{ + // Be careful here not to touch the global file hierarchy in Irrlicht + // since this function needs to be thread-safe! + + io::IArchiveLoader *zip_loader = nullptr; + for (u32 i = 0; i < fs->getArchiveLoaderCount(); i++) { + if (fs->getArchiveLoader(i)->isALoadableFileFormat(io::EFAT_ZIP)) { + zip_loader = fs->getArchiveLoader(i); + break; + } + } + if (!zip_loader) { + warningstream << "fs::extractZipFile(): Irrlicht said it doesn't support ZIPs." << std::endl; + return false; + } + + irr_ptr<io::IFileArchive> opened_zip(zip_loader->createArchive(filename, false, false)); + const io::IFileList* files_in_zip = opened_zip->getFileList(); + + for (u32 i = 0; i < files_in_zip->getFileCount(); i++) { + std::string fullpath = destination + DIR_DELIM; + fullpath += files_in_zip->getFullFileName(i).c_str(); + std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath); + + if (files_in_zip->isDirectory(i)) + continue; // ignore, we create dirs as necessary + + if (!fs::PathExists(fullpath_dir) && !fs::CreateAllDirs(fullpath_dir)) + return false; + + irr_ptr<io::IReadFile> toread(opened_zip->createAndOpenFile(i)); + + std::ofstream os(fullpath.c_str(), std::ios::binary); + if (!os.good()) + return false; + + char buffer[4096]; + long total_read = 0; + + while (total_read < toread->getSize()) { + long bytes_read = toread->read(buffer, sizeof(buffer)); + bool error = true; + if (bytes_read != 0) { + os.write(buffer, bytes_read); + error = os.fail(); + } + if (error) { + os.close(); + remove(fullpath.c_str()); + return false; + } + total_read += bytes_read; + } + } + + return true; +} +#endif + +bool ReadFile(const std::string &path, std::string &out) +{ + std::ifstream is(path, std::ios::binary | std::ios::ate); + if (!is.good()) { + return false; + } + + auto size = is.tellg(); + out.resize(size); + is.seekg(0); + is.read(&out[0], size); + + return !is.fail(); +} + +bool Rename(const std::string &from, const std::string &to) +{ + return rename(from.c_str(), to.c_str()) == 0; +} + +} // namespace fs diff --git a/src/filesys.h b/src/filesys.h new file mode 100644 index 0000000..a26fe28 --- /dev/null +++ b/src/filesys.h @@ -0,0 +1,153 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <set> +#include <string> +#include <vector> +#include "exceptions.h" + +#ifdef _WIN32 +#define DIR_DELIM "\\" +#define DIR_DELIM_CHAR '\\' +#define FILESYS_CASE_INSENSITIVE true +#define PATH_DELIM ";" +#else +#define DIR_DELIM "/" +#define DIR_DELIM_CHAR '/' +#define FILESYS_CASE_INSENSITIVE false +#define PATH_DELIM ":" +#endif + +namespace irr { namespace io { +class IFileSystem; +}} + +namespace fs +{ + +struct DirListNode +{ + std::string name; + bool dir; +}; + +std::vector<DirListNode> GetDirListing(const std::string &path); + +// Returns true if already exists +bool CreateDir(const std::string &path); + +bool PathExists(const std::string &path); + +bool IsPathAbsolute(const std::string &path); + +bool IsDir(const std::string &path); + +inline bool IsFile(const std::string &path) +{ + return PathExists(path) && !IsDir(path); +} + +bool IsDirDelimiter(char c); + +// Only pass full paths to this one. True on success. +// NOTE: The WIN32 version returns always true. +bool RecursiveDelete(const std::string &path); + +bool DeleteSingleFileOrEmptyDirectory(const std::string &path); + +// Returns path to temp directory, can return "" on error +std::string TempPath(); + +// Returns path to securely-created temporary file (will already exist when this function returns) +// can return "" on error +std::string CreateTempFile(); + +/* Returns a list of subdirectories, including the path itself, but excluding + hidden directories (whose names start with . or _) +*/ +void GetRecursiveDirs(std::vector<std::string> &dirs, const std::string &dir); +std::vector<std::string> GetRecursiveDirs(const std::string &dir); + +/* Multiplatform */ + +/* The path itself not included, returns a list of all subpaths. + dst - vector that contains all the subpaths. + list files - include files in the list of subpaths. + ignore - paths that start with these charcters will not be listed. +*/ +void GetRecursiveSubPaths(const std::string &path, + std::vector<std::string> &dst, + bool list_files, + const std::set<char> &ignore = {}); + +// Only pass full paths to this one. True on success. +bool RecursiveDeleteContent(const std::string &path); + +// Create all directories on the given path that don't already exist. +bool CreateAllDirs(const std::string &path); + +// Copy a regular file +bool CopyFileContents(const std::string &source, const std::string &target); + +// Copy directory and all subdirectories +// Omits files and subdirectories that start with a period +bool CopyDir(const std::string &source, const std::string &target); + +// Move directory and all subdirectories +// Behavior with files/subdirs that start with a period is undefined +bool MoveDir(const std::string &source, const std::string &target); + +// Check if one path is prefix of another +// For example, "/tmp" is a prefix of "/tmp" and "/tmp/file" but not "/tmp2" +// Ignores case differences and '/' vs. '\\' on Windows +bool PathStartsWith(const std::string &path, const std::string &prefix); + +// Remove last path component and the dir delimiter before and/or after it, +// returns "" if there is only one path component. +// removed: If non-NULL, receives the removed component(s). +// count: Number of components to remove +std::string RemoveLastPathComponent(const std::string &path, + std::string *removed = NULL, int count = 1); + +// Remove "." and ".." path components and for every ".." removed, remove +// the last normal path component before it. Unlike AbsolutePath, +// this does not resolve symlinks and check for existence of directories. +std::string RemoveRelativePathComponents(std::string path); + +// Returns the absolute path for the passed path, with "." and ".." path +// components and symlinks removed. Returns "" on error. +std::string AbsolutePath(const std::string &path); + +// Returns the filename from a path or the entire path if no directory +// delimiter is found. +const char *GetFilenameFromPath(const char *path); + +bool safeWriteToFile(const std::string &path, const std::string &content); + +#ifndef SERVER +bool extractZipFile(irr::io::IFileSystem *fs, const char *filename, const std::string &destination); +#endif + +bool ReadFile(const std::string &path, std::string &out); + +bool Rename(const std::string &from, const std::string &to); + +} // namespace fs diff --git a/src/gamedef.h b/src/gamedef.h new file mode 100644 index 0000000..45b9c47 --- /dev/null +++ b/src/gamedef.h @@ -0,0 +1,85 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <vector> +#include "irrlichttypes.h" + +class IItemDefManager; +class NodeDefManager; +class ICraftDefManager; +class ITextureSource; +class IShaderSource; +class IRollbackManager; +class EmergeManager; +class Camera; +class ModChannel; +class ModMetadata; +class ModMetadataDatabase; + +namespace irr { namespace scene { + class IAnimatedMesh; + class ISceneManager; +}} + +struct ModSpec; +/* + An interface for fetching game-global definitions like tool and + mapnode properties +*/ + +class IGameDef +{ +public: + // These are thread-safe IF they are not edited while running threads. + // Thus, first they are set up and then they are only read. + virtual IItemDefManager* getItemDefManager()=0; + virtual const NodeDefManager* getNodeDefManager()=0; + virtual ICraftDefManager* getCraftDefManager()=0; + + // Used for keeping track of names/ids of unknown nodes + virtual u16 allocateUnknownNodeId(const std::string &name)=0; + + // Only usable on the server, and NOT thread-safe. It is usable from the + // environment thread. + virtual IRollbackManager* getRollbackManager() { return NULL; } + + // Shorthands + // TODO: these should be made const-safe so that a const IGameDef* is + // actually usable + IItemDefManager *idef() { return getItemDefManager(); } + const NodeDefManager *ndef() { return getNodeDefManager(); } + ICraftDefManager *cdef() { return getCraftDefManager(); } + IRollbackManager *rollback() { return getRollbackManager(); } + + virtual const std::vector<ModSpec> &getMods() const = 0; + virtual const ModSpec* getModSpec(const std::string &modname) const = 0; + virtual std::string getWorldPath() const { return ""; } + virtual bool registerModStorage(ModMetadata *storage) = 0; + virtual void unregisterModStorage(const std::string &name) = 0; + virtual ModMetadataDatabase *getModStorageDatabase() = 0; + + virtual bool joinModChannel(const std::string &channel) = 0; + virtual bool leaveModChannel(const std::string &channel) = 0; + virtual bool sendModChannelMessage(const std::string &channel, + const std::string &message) = 0; + virtual ModChannel *getModChannel(const std::string &channel) = 0; +}; diff --git a/src/gameparams.h b/src/gameparams.h new file mode 100644 index 0000000..b138f87 --- /dev/null +++ b/src/gameparams.h @@ -0,0 +1,58 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "content/subgames.h" + +// Information provided from "main" +struct GameParams +{ + GameParams() = default; + + u16 socket_port; + std::string world_path; + SubgameSpec game_spec; + bool is_dedicated_server; +}; + +enum class ELoginRegister { + Any = 0, + Login, + Register +}; + +// Information processed by main menu +struct GameStartData : GameParams +{ + GameStartData() = default; + + bool isSinglePlayer() const { return address.empty() && !local_server; } + + std::string name; + std::string password; + std::string address; + bool local_server; + + ELoginRegister allow_login_or_register = ELoginRegister::Any; + + // "world_path" must be kept in sync! + WorldSpec world_spec; +}; diff --git a/src/gettext.cpp b/src/gettext.cpp new file mode 100644 index 0000000..de042cf --- /dev/null +++ b/src/gettext.cpp @@ -0,0 +1,255 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <string> +#include <cstring> +#include <iostream> +#include <cstdlib> +#include "gettext.h" +#include "util/string.h" +#include "log.h" + +#if USE_GETTEXT && defined(_MSC_VER) +#include <windows.h> +#include <map> +#include <direct.h> +#include "filesys.h" + +#define setlocale(category, localename) \ + setlocale(category, MSVC_LocaleLookup(localename)) + +static std::map<std::wstring, std::wstring> glb_supported_locales; + +/******************************************************************************/ +BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr) +{ + char* endptr = 0; + int LOCALEID = strtol(pStr, &endptr,16); + + wchar_t buffer[LOCALE_NAME_MAX_LENGTH]; + memset(buffer, 0, sizeof(buffer)); + if (GetLocaleInfoW( + LOCALEID, + LOCALE_SISO639LANGNAME, + buffer, + LOCALE_NAME_MAX_LENGTH)) { + + std::wstring name = buffer; + + memset(buffer, 0, sizeof(buffer)); + GetLocaleInfoW( + LOCALEID, + LOCALE_SISO3166CTRYNAME, + buffer, + LOCALE_NAME_MAX_LENGTH); + + std::wstring country = buffer; + + memset(buffer, 0, sizeof(buffer)); + GetLocaleInfoW( + LOCALEID, + LOCALE_SENGLISHLANGUAGENAME, + buffer, + LOCALE_NAME_MAX_LENGTH); + + std::wstring languagename = buffer; + + /* set both short and long variant */ + glb_supported_locales[name] = languagename; + glb_supported_locales[name + L"_" + country] = languagename; + } + return true; +} + +/******************************************************************************/ +const char* MSVC_LocaleLookup(const char* raw_shortname) { + + /* NULL is used to read locale only so we need to return it too */ + if (raw_shortname == NULL) return NULL; + + std::string shortname(raw_shortname); + if (shortname == "C") return "C"; + if (shortname == "") return ""; + + static std::string last_raw_value = ""; + static std::string last_full_name = ""; + static bool first_use = true; + + if (last_raw_value == shortname) { + return last_full_name.c_str(); + } + + if (first_use) { + EnumSystemLocalesA(UpdateLocaleCallback, LCID_SUPPORTED | LCID_ALTERNATE_SORTS); + first_use = false; + } + + last_raw_value = shortname; + + if (glb_supported_locales.find(utf8_to_wide(shortname)) != glb_supported_locales.end()) { + last_full_name = wide_to_utf8( + glb_supported_locales[utf8_to_wide(shortname)]); + return last_full_name.c_str(); + } + + /* empty string is system default */ + errorstream << "MSVC_LocaleLookup: unsupported locale: \"" << shortname + << "\" switching to system default!" << std::endl; + return ""; +} + +#endif + +/******************************************************************************/ +void init_gettext(const char *path, const std::string &configured_language, + int argc, char *argv[]) +{ +#if USE_GETTEXT + // First, try to set user override environment + if (!configured_language.empty()) { +#ifndef _WIN32 + // Add user specified locale to environment + setenv("LANGUAGE", configured_language.c_str(), 1); + +#ifdef __ANDROID__ + setenv("LANG", configured_language.c_str(), 1); +#endif + + // Reload locale with changed environment + setlocale(LC_ALL, ""); +#elif defined(_MSC_VER) + std::string current_language; + const char *env_lang = getenv("LANGUAGE"); + if (env_lang) + current_language = env_lang; + + _putenv(("LANGUAGE=" + configured_language).c_str()); + SetEnvironmentVariableA("LANGUAGE", configured_language.c_str()); + +#ifndef SERVER + // Hack to force gettext to see the right environment + if (current_language != configured_language) { + errorstream << "MSVC localization workaround active. " + "Restarting " PROJECT_NAME_C " in a new environment!" << std::endl; + + std::string parameters; + + for (unsigned int i = 1; i < argc; i++) { + if (!parameters.empty()) + parameters += ' '; + + parameters += argv[i]; + } + + const char *ptr_parameters = NULL; + + if (!parameters.empty()) + ptr_parameters = parameters.c_str(); + + // Allow calling without an extension + std::string app_name = argv[0]; + if (app_name.compare(app_name.size() - 4, 4, ".exe") != 0) + app_name += ".exe"; + + STARTUPINFO startup_info = {0}; + PROCESS_INFORMATION process_info = {0}; + + bool success = CreateProcess(app_name.c_str(), (char *)ptr_parameters, + NULL, NULL, false, DETACHED_PROCESS | CREATE_UNICODE_ENVIRONMENT, + NULL, NULL, &startup_info, &process_info); + + if (success) { + exit(0); + // NOTREACHED + } else { + char buffer[1024]; + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), buffer, + sizeof(buffer) - 1, NULL); + + errorstream << "*******************************************************" << std::endl; + errorstream << "CMD: " << app_name << std::endl; + errorstream << "Failed to restart with current locale: " << std::endl; + errorstream << buffer; + errorstream << "Expect language to be broken!" << std::endl; + errorstream << "*******************************************************" << std::endl; + } + } +#else + errorstream << "*******************************************************" << std::endl; + errorstream << "Can't apply locale workaround for server!" << std::endl; + errorstream << "Expect language to be broken!" << std::endl; + errorstream << "*******************************************************" << std::endl; +#endif + + setlocale(LC_ALL, configured_language.c_str()); +#else // Mingw + _putenv(("LANGUAGE=" + configured_language).c_str()); + setlocale(LC_ALL, ""); +#endif // ifndef _WIN32 + } + else { + /* set current system default locale */ + setlocale(LC_ALL, ""); + } + +#if defined(_WIN32) + if (getenv("LANGUAGE") != 0) { + setlocale(LC_ALL, getenv("LANGUAGE")); + } +#ifdef _MSC_VER + else if (getenv("LANG") != 0) { + setlocale(LC_ALL, getenv("LANG")); + } +#endif +#endif + + std::string name = lowercase(PROJECT_NAME); + infostream << "Gettext: domainname=\"" << name + << "\" path=\"" << path << "\"" << std::endl; + + bindtextdomain(name.c_str(), path); + textdomain(name.c_str()); + +#if defined(_WIN32) + // Set character encoding for Win32 + char *tdomain = textdomain( (char *) NULL ); + if( tdomain == NULL ) + { + errorstream << "Warning: domainname parameter is the null pointer" << + ", default domain is not set" << std::endl; + tdomain = (char *) "messages"; + } + /* char *codeset = */bind_textdomain_codeset( tdomain, "UTF-8" ); + //errorstream << "Gettext debug: domainname = " << tdomain << "; codeset = "<< codeset << std::endl; +#endif // defined(_WIN32) + +#else + /* set current system default locale */ + setlocale(LC_ALL, ""); +#endif // if USE_GETTEXT + + /* no matter what locale is used we need number format to be "C" */ + /* to ensure formspec parameters are evaluated correct! */ + + setlocale(LC_NUMERIC, "C"); + infostream << "Message locale is now set to: " + << setlocale(LC_ALL, 0) << std::endl; +} diff --git a/src/gettext.h b/src/gettext.h new file mode 100644 index 0000000..6225fef --- /dev/null +++ b/src/gettext.h @@ -0,0 +1,107 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "config.h" // for USE_GETTEXT +#include <string> +#include "porting.h" + +#if USE_GETTEXT + #include <libintl.h> +#else + // In certain environments, some standard headers like <iomanip> + // and <locale> include libintl.h. If libintl.h is included after + // we define our gettext macro below, this causes a syntax error + // at the declaration of the gettext function in libintl.h. + // Fix this by including such a header before defining the macro. + // See issue #4446. + // Note that we can't include libintl.h directly since we're in + // the USE_GETTEXT=0 case and can't assume that gettext is installed. + #include <locale> + + #define gettext(String) String +#endif + +#define _(String) gettext(String) +#define gettext_noop(String) (String) +#define N_(String) gettext_noop((String)) + +void init_gettext(const char *path, const std::string &configured_language, + int argc, char *argv[]); + +extern wchar_t *utf8_to_wide_c(const char *str); + +// The returned string must be freed using delete[] +inline const wchar_t *wgettext(const char *str) +{ + // We must check here that is not an empty string to avoid trying to translate it + return str[0] ? utf8_to_wide_c(gettext(str)) : utf8_to_wide_c(""); +} + +inline std::string strgettext(const std::string &text) +{ + return text.empty() ? "" : gettext(text.c_str()); +} + +/** + * Returns translated string with format args applied + * + * @tparam Args Template parameter for format args + * @param src Translation source string + * @param args Variable format args + * @return translated string + */ +template <typename ...Args> +inline std::wstring fwgettext(const char *src, Args&&... args) +{ + wchar_t buf[255]; + const wchar_t* str = wgettext(src); + swprintf(buf, sizeof(buf) / sizeof(wchar_t), str, std::forward<Args>(args)...); + delete[] str; + return std::wstring(buf); +} + +/** + * Returns translated string with format args applied + * + * @tparam Args Template parameter for format args + * @param format Translation source string + * @param args Variable format args + * @return translated string. + */ +template <typename ...Args> +inline std::string fmtgettext(const char *format, Args&&... args) +{ + std::string buf; + std::size_t buf_size = 256; + buf.resize(buf_size); + + format = gettext(format); + + int len = porting::mt_snprintf(&buf[0], buf_size, format, std::forward<Args>(args)...); + if (len <= 0) throw std::runtime_error("gettext format error: " + std::string(format)); + if ((size_t)len >= buf.size()) { + buf.resize(len+1); // extra null byte + porting::mt_snprintf(&buf[0], buf.size(), format, std::forward<Args>(args)...); + } + buf.resize(len); // remove null bytes + + return buf; +} diff --git a/src/gettime.h b/src/gettime.h new file mode 100644 index 0000000..772ff9b --- /dev/null +++ b/src/gettime.h @@ -0,0 +1,64 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <ctime> +#include <string> +#include <mutex> + +enum TimePrecision +{ + PRECISION_SECONDS, + PRECISION_MILLI, + PRECISION_MICRO, + PRECISION_NANO +}; + +inline struct tm mt_localtime() +{ + // initialize the time zone on first invocation + static std::once_flag tz_init; + std::call_once(tz_init, [] { +#ifdef _WIN32 + _tzset(); +#else + tzset(); +#endif + }); + + struct tm ret; + time_t t = time(NULL); + // TODO we should check if the function returns NULL, which would mean error +#ifdef _WIN32 + localtime_s(&ret, &t); +#else + localtime_r(&t, &ret); +#endif + return ret; +} + + +inline std::string getTimestamp() +{ + const struct tm tm = mt_localtime(); + char cs[20]; // YYYY-MM-DD HH:MM:SS + '\0' + strftime(cs, 20, "%Y-%m-%d %H:%M:%S", &tm); + return cs; +} diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt new file mode 100644 index 0000000..4434b14 --- /dev/null +++ b/src/gui/CMakeLists.txt @@ -0,0 +1,34 @@ +set(extra_gui_SRCS "") +if(ENABLE_TOUCH) + set(extra_gui_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/touchscreengui.cpp) +endif() + +set(gui_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/guiAnimatedImage.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiBackgroundImage.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiBox.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiButton.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiButtonImage.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiButtonItemImage.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiChatConsole.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiEditBox.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiEditBoxWithScrollbar.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiEngine.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiFormSpecMenu.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiInventoryList.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiItemImage.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiKeyChangeMenu.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiPasswordChange.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiPathSelectMenu.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiScene.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiScrollBar.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiScrollContainer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiSkin.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiTable.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiHyperText.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiVolumeChange.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/modalMenu.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/profilergraph.cpp + ${extra_gui_SRCS} + PARENT_SCOPE +) diff --git a/src/gui/StyleSpec.h b/src/gui/StyleSpec.h new file mode 100644 index 0000000..7a45e07 --- /dev/null +++ b/src/gui/StyleSpec.h @@ -0,0 +1,479 @@ +/* +Minetest +Copyright (C) 2019 rubenwardy + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "client/tile.h" // ITextureSource +#include "client/fontengine.h" +#include "debug.h" +#include "irrlichttypes_extrabloated.h" +#include "util/string.h" +#include <algorithm> +#include <array> +#include <vector> + +#pragma once + +class StyleSpec +{ +public: + enum Property + { + TEXTCOLOR, + BGCOLOR, + BGCOLOR_HOVERED, // Note: Deprecated property + BGCOLOR_PRESSED, // Note: Deprecated property + NOCLIP, + BORDER, + BGIMG, + BGIMG_HOVERED, // Note: Deprecated property + BGIMG_MIDDLE, + BGIMG_PRESSED, // Note: Deprecated property + FGIMG, + FGIMG_HOVERED, // Note: Deprecated property + FGIMG_MIDDLE, + FGIMG_PRESSED, // Note: Deprecated property + ALPHA, + CONTENT_OFFSET, + PADDING, + FONT, + FONT_SIZE, + COLORS, + BORDERCOLORS, + BORDERWIDTHS, + SOUND, + SPACING, + SIZE, + NUM_PROPERTIES, + NONE + }; + enum State + { + STATE_DEFAULT = 0, + STATE_HOVERED = 1 << 0, + STATE_PRESSED = 1 << 1, + NUM_STATES = 1 << 2, + STATE_INVALID = 1 << 3, + }; + +private: + std::array<bool, NUM_PROPERTIES> property_set{}; + std::array<std::string, NUM_PROPERTIES> properties; + State state_map = STATE_DEFAULT; + +public: + static Property GetPropertyByName(const std::string &name) + { + if (name == "textcolor") { + return TEXTCOLOR; + } else if (name == "bgcolor") { + return BGCOLOR; + } else if (name == "bgcolor_hovered") { + return BGCOLOR_HOVERED; + } else if (name == "bgcolor_pressed") { + return BGCOLOR_PRESSED; + } else if (name == "noclip") { + return NOCLIP; + } else if (name == "border") { + return BORDER; + } else if (name == "bgimg") { + return BGIMG; + } else if (name == "bgimg_hovered") { + return BGIMG_HOVERED; + } else if (name == "bgimg_middle") { + return BGIMG_MIDDLE; + } else if (name == "bgimg_pressed") { + return BGIMG_PRESSED; + } else if (name == "fgimg") { + return FGIMG; + } else if (name == "fgimg_hovered") { + return FGIMG_HOVERED; + } else if (name == "fgimg_middle") { + return FGIMG_MIDDLE; + } else if (name == "fgimg_pressed") { + return FGIMG_PRESSED; + } else if (name == "alpha") { + return ALPHA; + } else if (name == "content_offset") { + return CONTENT_OFFSET; + } else if (name == "padding") { + return PADDING; + } else if (name == "font") { + return FONT; + } else if (name == "font_size") { + return FONT_SIZE; + } else if (name == "colors") { + return COLORS; + } else if (name == "bordercolors") { + return BORDERCOLORS; + } else if (name == "borderwidths") { + return BORDERWIDTHS; + } else if (name == "sound") { + return SOUND; + } else if (name == "spacing") { + return SPACING; + } else if (name == "size") { + return SIZE; + } else { + return NONE; + } + } + + std::string get(Property prop, std::string def) const + { + const auto &val = properties[prop]; + return val.empty() ? def : val; + } + + void set(Property prop, const std::string &value) + { + properties[prop] = value; + property_set[prop] = true; + } + + //! Parses a name and returns the corresponding state enum + static State getStateByName(const std::string &name) + { + if (name == "default") { + return STATE_DEFAULT; + } else if (name == "hovered") { + return STATE_HOVERED; + } else if (name == "pressed") { + return STATE_PRESSED; + } else { + return STATE_INVALID; + } + } + + //! Gets the state that this style is intended for + State getState() const + { + return state_map; + } + + //! Set the given state on this style + void addState(State state) + { + FATAL_ERROR_IF(state >= NUM_STATES, "Out-of-bounds state received"); + + state_map = static_cast<State>(state_map | state); + } + + //! Using a list of styles mapped to state values, calculate the final + // combined style for a state by propagating values in its component states + static StyleSpec getStyleFromStatePropagation(const std::array<StyleSpec, NUM_STATES> &styles, State state) + { + StyleSpec temp = styles[StyleSpec::STATE_DEFAULT]; + temp.state_map = state; + for (int i = StyleSpec::STATE_DEFAULT + 1; i <= state; i++) { + if ((state & i) != 0) { + temp = temp | styles[i]; + } + } + + return temp; + } + + video::SColor getColor(Property prop, video::SColor def) const + { + const auto &val = properties[prop]; + if (val.empty()) { + return def; + } + + parseColorString(val, def, false, 0xFF); + return def; + } + + video::SColor getColor(Property prop) const + { + const auto &val = properties[prop]; + FATAL_ERROR_IF(val.empty(), "Unexpected missing property"); + + video::SColor color; + parseColorString(val, color, false, 0xFF); + return color; + } + + std::array<video::SColor, 4> getColorArray(Property prop, + std::array<video::SColor, 4> def) const + { + const auto &val = properties[prop]; + if (val.empty()) + return def; + + std::vector<std::string> strs; + if (!parseArray(val, strs)) + return def; + + for (size_t i = 0; i <= 3; i++) { + video::SColor color; + if (parseColorString(strs[i], color, false, 0xff)) + def[i] = color; + } + + return def; + } + + std::array<s32, 4> getIntArray(Property prop, std::array<s32, 4> def) const + { + const auto &val = properties[prop]; + if (val.empty()) + return def; + + std::vector<std::string> strs; + if (!parseArray(val, strs)) + return def; + + for (size_t i = 0; i <= 3; i++) + def[i] = stoi(strs[i]); + + return def; + } + + irr::core::rect<s32> getRect(Property prop, irr::core::rect<s32> def) const + { + const auto &val = properties[prop]; + if (val.empty()) + return def; + + irr::core::rect<s32> rect; + if (!parseRect(val, &rect)) + return def; + + return rect; + } + + irr::core::rect<s32> getRect(Property prop) const + { + const auto &val = properties[prop]; + FATAL_ERROR_IF(val.empty(), "Unexpected missing property"); + + irr::core::rect<s32> rect; + parseRect(val, &rect); + return rect; + } + + v2f32 getVector2f(Property prop, v2f32 def) const + { + const auto &val = properties[prop]; + if (val.empty()) + return def; + + v2f32 vec; + if (!parseVector2f(val, &vec)) + return def; + + return vec; + } + + v2s32 getVector2i(Property prop, v2s32 def) const + { + const auto &val = properties[prop]; + if (val.empty()) + return def; + + v2f32 vec; + if (!parseVector2f(val, &vec)) + return def; + + return v2s32(vec.X, vec.Y); + } + + v2s32 getVector2i(Property prop) const + { + const auto &val = properties[prop]; + FATAL_ERROR_IF(val.empty(), "Unexpected missing property"); + + v2f32 vec; + parseVector2f(val, &vec); + return v2s32(vec.X, vec.Y); + } + + gui::IGUIFont *getFont() const + { + FontSpec spec(FONT_SIZE_UNSPECIFIED, FM_Standard, false, false); + + const std::string &font = properties[FONT]; + const std::string &size = properties[FONT_SIZE]; + + if (font.empty() && size.empty()) + return nullptr; + + std::vector<std::string> modes = split(font, ','); + + for (size_t i = 0; i < modes.size(); i++) { + if (modes[i] == "normal") + spec.mode = FM_Standard; + else if (modes[i] == "mono") + spec.mode = FM_Mono; + else if (modes[i] == "bold") + spec.bold = true; + else if (modes[i] == "italic") + spec.italic = true; + } + + if (!size.empty()) { + int calc_size = 1; + + if (size[0] == '*') { + std::string new_size = size.substr(1); // Remove '*' (invalid for stof) + calc_size = stof(new_size) * g_fontengine->getFontSize(spec.mode); + } else if (size[0] == '+' || size[0] == '-') { + calc_size = stoi(size) + g_fontengine->getFontSize(spec.mode); + } else { + calc_size = stoi(size); + } + + spec.size = (unsigned)std::min(std::max(calc_size, 1), 999); + } + + return g_fontengine->getFont(spec); + } + + video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc, + video::ITexture *def) const + { + const auto &val = properties[prop]; + if (val.empty()) { + return def; + } + + video::ITexture *texture = tsrc->getTexture(val); + + return texture; + } + + video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc) const + { + const auto &val = properties[prop]; + FATAL_ERROR_IF(val.empty(), "Unexpected missing property"); + + video::ITexture *texture = tsrc->getTexture(val); + + return texture; + } + + bool getBool(Property prop, bool def) const + { + const auto &val = properties[prop]; + if (val.empty()) { + return def; + } + + return is_yes(val); + } + + inline bool isNotDefault(Property prop) const + { + return !properties[prop].empty(); + } + + inline bool hasProperty(Property prop) const { return property_set[prop]; } + + StyleSpec &operator|=(const StyleSpec &other) + { + for (size_t i = 0; i < NUM_PROPERTIES; i++) { + auto prop = (Property)i; + if (other.hasProperty(prop)) { + set(prop, other.get(prop, "")); + } + } + + return *this; + } + + StyleSpec operator|(const StyleSpec &other) const + { + StyleSpec newspec = *this; + newspec |= other; + return newspec; + } + +private: + bool parseArray(const std::string &value, std::vector<std::string> &arr) const + { + std::vector<std::string> strs = split(value, ','); + + if (strs.size() == 1) { + arr = {strs[0], strs[0], strs[0], strs[0]}; + } else if (strs.size() == 2) { + arr = {strs[0], strs[1], strs[0], strs[1]}; + } else if (strs.size() == 4) { + arr = strs; + } else { + warningstream << "Invalid array size (" << strs.size() + << " arguments): \"" << value << "\"" << std::endl; + return false; + } + return true; + } + + bool parseRect(const std::string &value, irr::core::rect<s32> *parsed_rect) const + { + irr::core::rect<s32> rect; + std::vector<std::string> v_rect = split(value, ','); + + if (v_rect.size() == 1) { + s32 x = stoi(v_rect[0]); + rect.UpperLeftCorner = irr::core::vector2di(x, x); + rect.LowerRightCorner = irr::core::vector2di(-x, -x); + } else if (v_rect.size() == 2) { + s32 x = stoi(v_rect[0]); + s32 y = stoi(v_rect[1]); + rect.UpperLeftCorner = irr::core::vector2di(x, y); + rect.LowerRightCorner = irr::core::vector2di(-x, -y); + // `-x` is interpreted as `w - x` + } else if (v_rect.size() == 4) { + rect.UpperLeftCorner = irr::core::vector2di( + stoi(v_rect[0]), stoi(v_rect[1])); + rect.LowerRightCorner = irr::core::vector2di( + stoi(v_rect[2]), stoi(v_rect[3])); + } else { + warningstream << "Invalid rectangle string format: \"" << value + << "\"" << std::endl; + return false; + } + + *parsed_rect = rect; + + return true; + } + + bool parseVector2f(const std::string &value, v2f32 *parsed_vec) const + { + v2f32 vec; + std::vector<std::string> v_vector = split(value, ','); + + if (v_vector.size() == 1) { + f32 x = stof(v_vector[0]); + vec.X = x; + vec.Y = x; + } else if (v_vector.size() == 2) { + vec.X = stof(v_vector[0]); + vec.Y = stof(v_vector[1]); + } else { + warningstream << "Invalid 2d vector string format: \"" << value + << "\"" << std::endl; + return false; + } + + *parsed_vec = vec; + + return true; + } +}; diff --git a/src/gui/guiAnimatedImage.cpp b/src/gui/guiAnimatedImage.cpp new file mode 100644 index 0000000..890763e --- /dev/null +++ b/src/gui/guiAnimatedImage.cpp @@ -0,0 +1,62 @@ +#include "guiAnimatedImage.h" + +#include "client/guiscalingfilter.h" +#include "client/tile.h" // ITextureSource +#include "log.h" +#include "porting.h" +#include "util/string.h" +#include <string> +#include <vector> + +GUIAnimatedImage::GUIAnimatedImage(gui::IGUIEnvironment *env, gui::IGUIElement *parent, + s32 id, const core::rect<s32> &rectangle) : + gui::IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rectangle) +{ +} + +void GUIAnimatedImage::draw() +{ + if (m_texture == nullptr) + return; + + video::IVideoDriver *driver = Environment->getVideoDriver(); + + core::dimension2d<u32> size = m_texture->getOriginalSize(); + + if ((u32)m_frame_count > size.Height) + m_frame_count = size.Height; + if (m_frame_idx >= m_frame_count) + m_frame_idx = m_frame_count - 1; + + size.Height /= m_frame_count; + + core::rect<s32> rect(core::position2d<s32>(0, size.Height * m_frame_idx), size); + core::rect<s32> *cliprect = NoClip ? nullptr : &AbsoluteClippingRect; + + if (m_middle.getArea() == 0) { + const video::SColor color(255, 255, 255, 255); + const video::SColor colors[] = {color, color, color, color}; + draw2DImageFilterScaled(driver, m_texture, AbsoluteRect, rect, cliprect, + colors, true); + } else { + draw2DImage9Slice(driver, m_texture, AbsoluteRect, rect, m_middle, cliprect); + } + + // Step the animation + if (m_frame_count > 1 && m_frame_duration > 0) { + // Determine the delta time to step + u64 new_global_time = porting::getTimeMs(); + if (m_global_time > 0) + m_frame_time += new_global_time - m_global_time; + + m_global_time = new_global_time; + + // Advance by the number of elapsed frames, looping if necessary + m_frame_idx += (u32)(m_frame_time / m_frame_duration); + m_frame_idx %= m_frame_count; + + // If 1 or more frames have elapsed, reset the frame time counter with + // the remainder + m_frame_time %= m_frame_duration; + } +} diff --git a/src/gui/guiAnimatedImage.h b/src/gui/guiAnimatedImage.h new file mode 100644 index 0000000..885aede --- /dev/null +++ b/src/gui/guiAnimatedImage.h @@ -0,0 +1,41 @@ +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include <algorithm> +#include <string> + +class ISimpleTextureSource; + +class GUIAnimatedImage : public gui::IGUIElement { +public: + GUIAnimatedImage(gui::IGUIEnvironment *env, gui::IGUIElement *parent, + s32 id, const core::rect<s32> &rectangle); + + virtual void draw() override; + + void setTexture(video::ITexture *texture) { m_texture = texture; }; + video::ITexture *getTexture() const { return m_texture; }; + + void setMiddleRect(const core::rect<s32> &middle) { m_middle = middle; }; + core::rect<s32> getMiddleRect() const { return m_middle; }; + + void setFrameDuration(u64 duration) { m_frame_duration = duration; }; + u64 getFrameDuration() const { return m_frame_duration; }; + + void setFrameCount(s32 count) { m_frame_count = std::max(count, 1); }; + s32 getFrameCount() const { return m_frame_count; }; + + void setFrameIndex(s32 frame) { m_frame_idx = std::max(frame, 0); }; + s32 getFrameIndex() const { return m_frame_idx; }; + +private: + video::ITexture *m_texture = nullptr; + + u64 m_global_time = 0; + s32 m_frame_idx = 0; + s32 m_frame_count = 1; + u64 m_frame_duration = 0; + u64 m_frame_time = 0; + + core::rect<s32> m_middle; +}; diff --git a/src/gui/guiBackgroundImage.cpp b/src/gui/guiBackgroundImage.cpp new file mode 100644 index 0000000..8d0d1c0 --- /dev/null +++ b/src/gui/guiBackgroundImage.cpp @@ -0,0 +1,63 @@ +/* +Part of Minetest +Copyright (C) 2013 RealBadAngel, Maciej Kasatkin <mk@realbadangel.pl> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "guiBackgroundImage.h" +#include "client/guiscalingfilter.h" +#include "log.h" + +GUIBackgroundImage::GUIBackgroundImage(gui::IGUIEnvironment *env, + gui::IGUIElement *parent, s32 id, const core::rect<s32> &rectangle, + const std::string &name, const core::rect<s32> &middle, + ISimpleTextureSource *tsrc, bool autoclip) : + gui::IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rectangle), + m_name(name), m_middle(middle), m_tsrc(tsrc), m_autoclip(autoclip) +{ +} + +void GUIBackgroundImage::draw() +{ + if (!IsVisible) + return; + + video::ITexture *texture = m_tsrc->getTexture(m_name); + + if (!texture) { + errorstream << "GUIBackgroundImage::draw() Unable to load texture:" + << std::endl; + errorstream << "\t" << m_name << std::endl; + return; + } + + core::rect<s32> rect = AbsoluteRect; + if (m_autoclip) + rect.LowerRightCorner += Parent->getAbsoluteClippingRect().getSize(); + + video::IVideoDriver *driver = Environment->getVideoDriver(); + + core::rect<s32> srcrect(core::position2d<s32>(0, 0), + core::dimension2di(texture->getOriginalSize())); + + if (m_middle.getArea() == 0) { + const video::SColor color(255, 255, 255, 255); + const video::SColor colors[] = {color, color, color, color}; + draw2DImageFilterScaled(driver, texture, rect, srcrect, nullptr, colors, true); + } else { + draw2DImage9Slice(driver, texture, rect, srcrect, m_middle); + } + + IGUIElement::draw(); +} diff --git a/src/gui/guiBackgroundImage.h b/src/gui/guiBackgroundImage.h new file mode 100644 index 0000000..31fbfd0 --- /dev/null +++ b/src/gui/guiBackgroundImage.h @@ -0,0 +1,38 @@ +/* +Part of Minetest +Copyright (C) 2013 RealBadAngel, Maciej Kasatkin <mk@realbadangel.pl> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "util/string.h" +#include "client/tile.h" // ITextureSource + +class GUIBackgroundImage : public gui::IGUIElement +{ +public: + GUIBackgroundImage(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id, + const core::rect<s32> &rectangle, const std::string &name, + const core::rect<s32> &middle, ISimpleTextureSource *tsrc, bool autoclip); + + virtual void draw() override; + +private: + std::string m_name; + core::rect<s32> m_middle; + ISimpleTextureSource *m_tsrc; + bool m_autoclip; +}; diff --git a/src/gui/guiBox.cpp b/src/gui/guiBox.cpp new file mode 100644 index 0000000..443f106 --- /dev/null +++ b/src/gui/guiBox.cpp @@ -0,0 +1,117 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiBox.h" + +GUIBox::GUIBox(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id, + const core::rect<s32> &rectangle, + const std::array<video::SColor, 4> &colors, + const std::array<video::SColor, 4> &bordercolors, + const std::array<s32, 4> &borderwidths) : + gui::IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rectangle), + m_colors(colors), + m_bordercolors(bordercolors), + m_borderwidths(borderwidths) +{ +} + +void GUIBox::draw() +{ + if (!IsVisible) + return; + + std::array<s32, 4> negative_borders = {0, 0, 0, 0}; + std::array<s32, 4> positive_borders = {0, 0, 0, 0}; + + for (size_t i = 0; i <= 3; i++) { + if (m_borderwidths[i] > 0) + positive_borders[i] = m_borderwidths[i]; + else + negative_borders[i] = m_borderwidths[i]; + } + + v2s32 upperleft = AbsoluteRect.UpperLeftCorner; + v2s32 lowerright = AbsoluteRect.LowerRightCorner; + + v2s32 topleft_border = { + upperleft.X - positive_borders[3], + upperleft.Y - positive_borders[0] + }; + v2s32 topleft_rect = { + upperleft.X - negative_borders[3], + upperleft.Y - negative_borders[0] + }; + + v2s32 lowerright_border = { + lowerright.X + positive_borders[1], + lowerright.Y + positive_borders[2] + }; + v2s32 lowerright_rect = { + lowerright.X + negative_borders[1], + lowerright.Y + negative_borders[2] + }; + + core::rect<s32> main_rect( + topleft_rect.X, + topleft_rect.Y, + lowerright_rect.X, + lowerright_rect.Y + ); + + std::array<core::rect<s32>, 4> border_rects; + + border_rects[0] = core::rect<s32>( + topleft_border.X, + topleft_border.Y, + lowerright_border.X, + topleft_rect.Y + ); + + border_rects[1] = core::rect<s32>( + lowerright_rect.X, + topleft_rect.Y, + lowerright_border.X, + lowerright_rect.Y + ); + + border_rects[2] = core::rect<s32>( + topleft_border.X, + lowerright_rect.Y, + lowerright_border.X, + lowerright_border.Y + ); + + border_rects[3] = core::rect<s32>( + topleft_border.X, + topleft_rect.Y, + topleft_rect.X, + lowerright_rect.Y + ); + + video::IVideoDriver *driver = Environment->getVideoDriver(); + + driver->draw2DRectangle(main_rect, m_colors[0], m_colors[1], m_colors[3], + m_colors[2], &AbsoluteClippingRect); + + for (size_t i = 0; i <= 3; i++) + driver->draw2DRectangle(m_bordercolors[i], border_rects[i], + &AbsoluteClippingRect); + + IGUIElement::draw(); +} diff --git a/src/gui/guiBox.h b/src/gui/guiBox.h new file mode 100644 index 0000000..ca8f837 --- /dev/null +++ b/src/gui/guiBox.h @@ -0,0 +1,41 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <vector> +#include <array> +#include "irrlichttypes_extrabloated.h" + +class GUIBox : public gui::IGUIElement +{ +public: + GUIBox(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id, + const core::rect<s32> &rectangle, + const std::array<video::SColor, 4> &colors, + const std::array<video::SColor, 4> &bordercolors, + const std::array<s32, 4> &borderwidths); + + virtual void draw() override; + +private: + std::array<video::SColor, 4> m_colors; + std::array<video::SColor, 4> m_bordercolors; + std::array<s32, 4> m_borderwidths; +}; diff --git a/src/gui/guiButton.cpp b/src/gui/guiButton.cpp new file mode 100644 index 0000000..2e7f7ee --- /dev/null +++ b/src/gui/guiButton.cpp @@ -0,0 +1,766 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "guiButton.h" + + +#include "client/guiscalingfilter.h" +#include "client/tile.h" +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "irrlicht_changes/static_text.h" +#include "porting.h" +#include "StyleSpec.h" +#include "util/numeric.h" + +using namespace irr; +using namespace gui; + +// Multiply with a color to get the default corresponding hovered color +#define COLOR_HOVERED_MOD 1.25f + +// Multiply with a color to get the default corresponding pressed color +#define COLOR_PRESSED_MOD 0.85f + +//! constructor +GUIButton::GUIButton(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect<s32> rectangle, ISimpleTextureSource *tsrc, + bool noclip) +: IGUIButton(environment, parent, id, rectangle), + SpriteBank(0), OverrideFont(0), + OverrideColorEnabled(false), OverrideColor(video::SColor(101,255,255,255)), + ClickTime(0), HoverTime(0), FocusTime(0), + ClickShiftState(false), ClickControlState(false), + IsPushButton(false), Pressed(false), + UseAlphaChannel(false), DrawBorder(true), ScaleImage(false), TSrc(tsrc) +{ + setNotClipped(noclip); + + // This element can be tabbed. + setTabStop(true); + setTabOrder(-1); + + // PATCH + for (size_t i = 0; i < 4; i++) { + Colors[i] = Environment->getSkin()->getColor((EGUI_DEFAULT_COLOR)i); + } + StaticText = gui::StaticText::add(Environment, Text.c_str(), core::rect<s32>(0,0,rectangle.getWidth(),rectangle.getHeight()), false, false, this, id); + StaticText->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); + // END PATCH +} + +//! destructor +GUIButton::~GUIButton() +{ + if (OverrideFont) + OverrideFont->drop(); + + if (SpriteBank) + SpriteBank->drop(); +} + + +//! Sets if the images should be scaled to fit the button +void GUIButton::setScaleImage(bool scaleImage) +{ + ScaleImage = scaleImage; +} + + +//! Returns whether the button scale the used images +bool GUIButton::isScalingImage() const +{ + return ScaleImage; +} + + +//! Sets if the button should use the skin to draw its border +void GUIButton::setDrawBorder(bool border) +{ + DrawBorder = border; +} + + +void GUIButton::setSpriteBank(IGUISpriteBank* sprites) +{ + if (sprites) + sprites->grab(); + + if (SpriteBank) + SpriteBank->drop(); + + SpriteBank = sprites; +} + +void GUIButton::setSprite(EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop, bool scale) +{ + ButtonSprites[(u32)state].Index = index; + ButtonSprites[(u32)state].Color = color; + ButtonSprites[(u32)state].Loop = loop; + ButtonSprites[(u32)state].Scale = scale; +} + +//! Get the sprite-index for the given state or -1 when no sprite is set +s32 GUIButton::getSpriteIndex(EGUI_BUTTON_STATE state) const +{ + return ButtonSprites[(u32)state].Index; +} + +//! Get the sprite color for the given state. Color is only used when a sprite is set. +video::SColor GUIButton::getSpriteColor(EGUI_BUTTON_STATE state) const +{ + return ButtonSprites[(u32)state].Color; +} + +//! Returns if the sprite in the given state does loop +bool GUIButton::getSpriteLoop(EGUI_BUTTON_STATE state) const +{ + return ButtonSprites[(u32)state].Loop; +} + +//! Returns if the sprite in the given state is scaled +bool GUIButton::getSpriteScale(EGUI_BUTTON_STATE state) const +{ + return ButtonSprites[(u32)state].Scale; +} + +//! called if an event happened. +bool GUIButton::OnEvent(const SEvent& event) +{ + if (!isEnabled()) + return IGUIElement::OnEvent(event); + + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown && + (event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE)) + { + if (!IsPushButton) + setPressed(true); + else + setPressed(!Pressed); + + return true; + } + if (Pressed && !IsPushButton && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE) + { + setPressed(false); + return true; + } + else + if (!event.KeyInput.PressedDown && Pressed && + (event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE)) + { + + if (!IsPushButton) + setPressed(false); + + if (Parent) + { + ClickShiftState = event.KeyInput.Shift; + ClickControlState = event.KeyInput.Control; + + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_BUTTON_CLICKED; + Parent->OnEvent(newEvent); + } + return true; + } + break; + case EET_GUI_EVENT: + if (event.GUIEvent.Caller == this) + { + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + { + if (!IsPushButton) + setPressed(false); + FocusTime = (u32)porting::getTimeMs(); + } + else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED) + { + FocusTime = (u32)porting::getTimeMs(); + } + else if (event.GUIEvent.EventType == EGET_ELEMENT_HOVERED || event.GUIEvent.EventType == EGET_ELEMENT_LEFT) + { + HoverTime = (u32)porting::getTimeMs(); + } + } + break; + case EET_MOUSE_INPUT_EVENT: + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + { + // Sometimes formspec elements can receive mouse events when the + // mouse is outside of the formspec. Thus, we test the position here. + if ( !IsPushButton && AbsoluteClippingRect.isPointInside( + core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y ))) { + setPressed(true); + } + + return true; + } + else + if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) + { + bool wasPressed = Pressed; + + if ( !AbsoluteClippingRect.isPointInside( core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y ) ) ) + { + if (!IsPushButton) + setPressed(false); + return true; + } + + if (!IsPushButton) + setPressed(false); + else + { + setPressed(!Pressed); + } + + if ((!IsPushButton && wasPressed && Parent) || + (IsPushButton && wasPressed != Pressed)) + { + ClickShiftState = event.MouseInput.Shift; + ClickControlState = event.MouseInput.Control; + + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_BUTTON_CLICKED; + Parent->OnEvent(newEvent); + } + + return true; + } + break; + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + +//! draws the element and its children +void GUIButton::draw() +{ + if (!IsVisible) + return; + + // PATCH + // Track hovered state, if it has changed then we need to update the style. + bool hovered = isHovered(); + if (hovered != WasHovered) { + WasHovered = hovered; + setFromState(); + } + + GUISkin* skin = dynamic_cast<GUISkin*>(Environment->getSkin()); + video::IVideoDriver* driver = Environment->getVideoDriver(); + // END PATCH + + if (DrawBorder) + { + if (!Pressed) + { + // PATCH + skin->drawColored3DButtonPaneStandard(this, AbsoluteRect, + &AbsoluteClippingRect, Colors); + // END PATCH + } + else + { + // PATCH + skin->drawColored3DButtonPanePressed(this, AbsoluteRect, + &AbsoluteClippingRect, Colors); + // END PATCH + } + } + + const core::position2di buttonCenter(AbsoluteRect.getCenter()); + // PATCH + // The image changes based on the state, so we use the default every time. + EGUI_BUTTON_IMAGE_STATE imageState = EGBIS_IMAGE_UP; + // END PATCH + if ( ButtonImages[(u32)imageState].Texture ) + { + core::position2d<s32> pos(buttonCenter); + core::rect<s32> sourceRect(ButtonImages[(u32)imageState].SourceRect); + if ( sourceRect.getWidth() == 0 && sourceRect.getHeight() == 0 ) + sourceRect = core::rect<s32>(core::position2di(0,0), ButtonImages[(u32)imageState].Texture->getOriginalSize()); + + pos.X -= sourceRect.getWidth() / 2; + pos.Y -= sourceRect.getHeight() / 2; + + if ( Pressed ) + { + // Create a pressed-down effect by moving the image when it looks identical to the unpressed state image + EGUI_BUTTON_IMAGE_STATE unpressedState = getImageState(false); + if ( unpressedState == imageState || ButtonImages[(u32)imageState] == ButtonImages[(u32)unpressedState] ) + { + pos.X += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X); + pos.Y += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y); + } + } + + // PATCH + video::ITexture* texture = ButtonImages[(u32)imageState].Texture; + video::SColor image_colors[] = { BgColor, BgColor, BgColor, BgColor }; + if (BgMiddle.getArea() == 0) { + driver->draw2DImage(texture, + ScaleImage? AbsoluteRect : core::rect<s32>(pos, sourceRect.getSize()), + sourceRect, &AbsoluteClippingRect, + image_colors, UseAlphaChannel); + } else { + draw2DImage9Slice(driver, texture, + ScaleImage ? AbsoluteRect : core::rect<s32>(pos, sourceRect.getSize()), + sourceRect, BgMiddle, &AbsoluteClippingRect, image_colors); + } + // END PATCH + } + + if (SpriteBank) + { + core::position2di pos(buttonCenter); + + if (isEnabled()) + { + // pressed / unpressed animation + EGUI_BUTTON_STATE state = Pressed ? EGBS_BUTTON_DOWN : EGBS_BUTTON_UP; + drawSprite(state, ClickTime, pos); + + // focused / unfocused animation + state = Environment->hasFocus(this) ? EGBS_BUTTON_FOCUSED : EGBS_BUTTON_NOT_FOCUSED; + drawSprite(state, FocusTime, pos); + + // mouse over / off animation + state = isHovered() ? EGBS_BUTTON_MOUSE_OVER : EGBS_BUTTON_MOUSE_OFF; + drawSprite(state, HoverTime, pos); + } + else + { + // draw disabled +// drawSprite(EGBS_BUTTON_DISABLED, 0, pos); + } + } + + IGUIElement::draw(); +} + +void GUIButton::drawSprite(EGUI_BUTTON_STATE state, u32 startTime, const core::position2di& center) +{ + u32 stateIdx = (u32)state; + + if (ButtonSprites[stateIdx].Index != -1) + { + if ( ButtonSprites[stateIdx].Scale ) + { + const video::SColor colors[] = {ButtonSprites[stateIdx].Color,ButtonSprites[stateIdx].Color,ButtonSprites[stateIdx].Color,ButtonSprites[stateIdx].Color}; + SpriteBank->draw2DSprite(ButtonSprites[stateIdx].Index, AbsoluteRect.UpperLeftCorner, + &AbsoluteClippingRect, colors[0], // FIXME: remove [0] + porting::getTimeMs()-startTime, ButtonSprites[stateIdx].Loop); + } + else + { + SpriteBank->draw2DSprite(ButtonSprites[stateIdx].Index, center, + &AbsoluteClippingRect, ButtonSprites[stateIdx].Color, startTime, porting::getTimeMs(), + ButtonSprites[stateIdx].Loop, true); + } + } +} + +EGUI_BUTTON_IMAGE_STATE GUIButton::getImageState(bool pressed) const +{ + // PATCH + return getImageState(pressed, ButtonImages); + // END PATCH +} + +EGUI_BUTTON_IMAGE_STATE GUIButton::getImageState(bool pressed, const ButtonImage* images) const +{ + // figure state we should have + EGUI_BUTTON_IMAGE_STATE state = EGBIS_IMAGE_DISABLED; + bool focused = Environment->hasFocus((IGUIElement*)this); + bool mouseOver = isHovered(); + if (isEnabled()) + { + if ( pressed ) + { + if ( focused && mouseOver ) + state = EGBIS_IMAGE_DOWN_FOCUSED_MOUSEOVER; + else if ( focused ) + state = EGBIS_IMAGE_DOWN_FOCUSED; + else if ( mouseOver ) + state = EGBIS_IMAGE_DOWN_MOUSEOVER; + else + state = EGBIS_IMAGE_DOWN; + } + else // !pressed + { + if ( focused && mouseOver ) + state = EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER; + else if ( focused ) + state = EGBIS_IMAGE_UP_FOCUSED; + else if ( mouseOver ) + state = EGBIS_IMAGE_UP_MOUSEOVER; + else + state = EGBIS_IMAGE_UP; + } + } + + // find a compatible state that has images + while ( state != EGBIS_IMAGE_UP && !images[(u32)state].Texture ) + { + // PATCH + switch ( state ) + { + case EGBIS_IMAGE_UP_FOCUSED: + state = EGBIS_IMAGE_UP; + break; + case EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER: + state = EGBIS_IMAGE_UP_FOCUSED; + break; + case EGBIS_IMAGE_DOWN_MOUSEOVER: + state = EGBIS_IMAGE_DOWN; + break; + case EGBIS_IMAGE_DOWN_FOCUSED: + state = EGBIS_IMAGE_DOWN; + break; + case EGBIS_IMAGE_DOWN_FOCUSED_MOUSEOVER: + state = EGBIS_IMAGE_DOWN_FOCUSED; + break; + case EGBIS_IMAGE_DISABLED: + if ( pressed ) + state = EGBIS_IMAGE_DOWN; + else + state = EGBIS_IMAGE_UP; + break; + default: + state = EGBIS_IMAGE_UP; + } + // END PATCH + } + + return state; +} + +//! sets another skin independent font. if this is set to zero, the button uses the font of the skin. +void GUIButton::setOverrideFont(IGUIFont* font) +{ + if (OverrideFont == font) + return; + + if (OverrideFont) + OverrideFont->drop(); + + OverrideFont = font; + + if (OverrideFont) + OverrideFont->grab(); + + StaticText->setOverrideFont(font); +} + +//! Gets the override font (if any) +IGUIFont * GUIButton::getOverrideFont() const +{ + return OverrideFont; +} + +//! Get the font which is used right now for drawing +IGUIFont* GUIButton::getActiveFont() const +{ + if ( OverrideFont ) + return OverrideFont; + IGUISkin* skin = Environment->getSkin(); + if (skin) + return skin->getFont(EGDF_BUTTON); + return 0; +} + +//! Sets another color for the text. +void GUIButton::setOverrideColor(video::SColor color) +{ + OverrideColor = color; + OverrideColorEnabled = true; + + StaticText->setOverrideColor(color); +} + +video::SColor GUIButton::getOverrideColor() const +{ + return OverrideColor; +} + +#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8 +video::SColor GUIButton::getActiveColor() const +{ + return video::SColor(0,0,0,0); // unused? +} +#endif + +void GUIButton::enableOverrideColor(bool enable) +{ + OverrideColorEnabled = enable; +} + +bool GUIButton::isOverrideColorEnabled() const +{ + return OverrideColorEnabled; +} + +void GUIButton::setImage(EGUI_BUTTON_IMAGE_STATE state, video::ITexture* image, const core::rect<s32>& sourceRect) +{ + if ( state >= EGBIS_COUNT ) + return; + + if ( image ) + image->grab(); + + u32 stateIdx = (u32)state; + if ( ButtonImages[stateIdx].Texture ) + ButtonImages[stateIdx].Texture->drop(); + + ButtonImages[stateIdx].Texture = image; + ButtonImages[stateIdx].SourceRect = sourceRect; +} + +// PATCH +void GUIButton::setImage(video::ITexture* image) +{ + setImage(gui::EGBIS_IMAGE_UP, image); +} + +void GUIButton::setImage(video::ITexture* image, const core::rect<s32>& pos) +{ + setImage(gui::EGBIS_IMAGE_UP, image, pos); +} + +void GUIButton::setPressedImage(video::ITexture* image) +{ + setImage(gui::EGBIS_IMAGE_DOWN, image); +} + +void GUIButton::setPressedImage(video::ITexture* image, const core::rect<s32>& pos) +{ + setImage(gui::EGBIS_IMAGE_DOWN, image, pos); +} + +//! Sets the text displayed by the button +void GUIButton::setText(const wchar_t* text) +{ + StaticText->setText(text); + + IGUIButton::setText(text); +} +// END PATCH + +//! Sets if the button should behave like a push button. Which means it +//! can be in two states: Normal or Pressed. With a click on the button, +//! the user can change the state of the button. +void GUIButton::setIsPushButton(bool isPushButton) +{ + IsPushButton = isPushButton; +} + + +//! Returns if the button is currently pressed +bool GUIButton::isPressed() const +{ + return Pressed; +} + +// PATCH +//! Returns if this element (or one of its direct children) is hovered +bool GUIButton::isHovered() const +{ + IGUIElement *hovered = Environment->getHovered(); + return hovered == this || (hovered != nullptr && hovered->getParent() == this); +} +// END PATCH + +//! Sets the pressed state of the button if this is a pushbutton +void GUIButton::setPressed(bool pressed) +{ + if (Pressed != pressed) + { + ClickTime = porting::getTimeMs(); + Pressed = pressed; + setFromState(); + } +} + + +//! Returns whether the button is a push button +bool GUIButton::isPushButton() const +{ + return IsPushButton; +} + + +//! Sets if the alpha channel should be used for drawing images on the button (default is false) +void GUIButton::setUseAlphaChannel(bool useAlphaChannel) +{ + UseAlphaChannel = useAlphaChannel; +} + + +//! Returns if the alpha channel should be used for drawing images on the button +bool GUIButton::isAlphaChannelUsed() const +{ + return UseAlphaChannel; +} + + +bool GUIButton::isDrawingBorder() const +{ + return DrawBorder; +} + + +// PATCH +GUIButton* GUIButton::addButton(IGUIEnvironment *environment, + const core::rect<s32>& rectangle, ISimpleTextureSource *tsrc, + IGUIElement* parent, s32 id, const wchar_t* text, + const wchar_t *tooltiptext) +{ + GUIButton* button = new GUIButton(environment, parent ? parent : environment->getRootGUIElement(), id, rectangle, tsrc); + if (text) + button->setText(text); + + if ( tooltiptext ) + button->setToolTipText ( tooltiptext ); + + button->drop(); + return button; +} + +void GUIButton::setColor(video::SColor color) +{ + BgColor = color; + + float d = 0.65f; + for (size_t i = 0; i < 4; i++) { + video::SColor base = Environment->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i); + Colors[i] = base.getInterpolated(color, d); + } +} + +//! Set element properties from a StyleSpec corresponding to the button state +void GUIButton::setFromState() +{ + StyleSpec::State state = StyleSpec::STATE_DEFAULT; + + if (isPressed()) + state = static_cast<StyleSpec::State>(state | StyleSpec::STATE_PRESSED); + + if (isHovered()) + state = static_cast<StyleSpec::State>(state | StyleSpec::STATE_HOVERED); + + setFromStyle(StyleSpec::getStyleFromStatePropagation(Styles, state)); +} + +//! Set element properties from a StyleSpec +void GUIButton::setFromStyle(const StyleSpec& style) +{ + bool hovered = (style.getState() & StyleSpec::STATE_HOVERED) != 0; + bool pressed = (style.getState() & StyleSpec::STATE_PRESSED) != 0; + + if (style.isNotDefault(StyleSpec::BGCOLOR)) { + setColor(style.getColor(StyleSpec::BGCOLOR)); + + // If we have a propagated hover/press color, we need to automatically + // lighten/darken it + if (!Styles[style.getState()].isNotDefault(StyleSpec::BGCOLOR)) { + if (pressed) { + BgColor = multiplyColorValue(BgColor, COLOR_PRESSED_MOD); + + for (size_t i = 0; i < 4; i++) + Colors[i] = multiplyColorValue(Colors[i], COLOR_PRESSED_MOD); + } else if (hovered) { + BgColor = multiplyColorValue(BgColor, COLOR_HOVERED_MOD); + + for (size_t i = 0; i < 4; i++) + Colors[i] = multiplyColorValue(Colors[i], COLOR_HOVERED_MOD); + } + } + + } else { + BgColor = video::SColor(255, 255, 255, 255); + for (size_t i = 0; i < 4; i++) { + video::SColor base = + Environment->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i); + if (pressed) { + Colors[i] = multiplyColorValue(base, COLOR_PRESSED_MOD); + } else if (hovered) { + Colors[i] = multiplyColorValue(base, COLOR_HOVERED_MOD); + } else { + Colors[i] = base; + } + } + } + + if (style.isNotDefault(StyleSpec::TEXTCOLOR)) { + setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR)); + } else { + setOverrideColor(video::SColor(255,255,255,255)); + OverrideColorEnabled = false; + } + setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + setDrawBorder(style.getBool(StyleSpec::BORDER, true)); + setUseAlphaChannel(style.getBool(StyleSpec::ALPHA, true)); + setOverrideFont(style.getFont()); + + if (style.isNotDefault(StyleSpec::BGIMG)) { + video::ITexture *texture = style.getTexture(StyleSpec::BGIMG, + getTextureSource()); + setImage(guiScalingImageButton( + Environment->getVideoDriver(), texture, + AbsoluteRect.getWidth(), AbsoluteRect.getHeight())); + setScaleImage(true); + } else { + setImage(nullptr); + } + + BgMiddle = style.getRect(StyleSpec::BGIMG_MIDDLE, BgMiddle); + + // Child padding and offset + Padding = style.getRect(StyleSpec::PADDING, core::rect<s32>()); + Padding = core::rect<s32>( + Padding.UpperLeftCorner + BgMiddle.UpperLeftCorner, + Padding.LowerRightCorner + BgMiddle.LowerRightCorner); + + GUISkin* skin = dynamic_cast<GUISkin*>(Environment->getSkin()); + core::vector2d<s32> defaultPressOffset( + skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X), + skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y)); + ContentOffset = style.getVector2i(StyleSpec::CONTENT_OFFSET, isPressed() + ? defaultPressOffset + : core::vector2d<s32>(0)); + + core::rect<s32> childBounds( + Padding.UpperLeftCorner.X + ContentOffset.X, + Padding.UpperLeftCorner.Y + ContentOffset.Y, + AbsoluteRect.getWidth() + Padding.LowerRightCorner.X + ContentOffset.X, + AbsoluteRect.getHeight() + Padding.LowerRightCorner.Y + ContentOffset.Y); + + for (IGUIElement *child : getChildren()) { + child->setRelativePosition(childBounds); + } +} + +//! Set the styles used for each state +void GUIButton::setStyles(const std::array<StyleSpec, StyleSpec::NUM_STATES>& styles) +{ + Styles = styles; + setFromState(); +} +// END PATCH diff --git a/src/gui/guiButton.h b/src/gui/guiButton.h new file mode 100644 index 0000000..d67ba1a --- /dev/null +++ b/src/gui/guiButton.h @@ -0,0 +1,346 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#pragma once + +#include "IrrCompileConfig.h" + +#include <IGUIStaticText.h> +#include "irrlicht_changes/static_text.h" +#include "IGUIButton.h" +#include "IGUISpriteBank.h" +#include "ITexture.h" +#include "SColor.h" +#include "guiSkin.h" +#include "StyleSpec.h" + +using namespace irr; + +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 8) + namespace irr { namespace gui { + + //! State of buttons used for drawing texture images. + //! Note that only a single state is active at a time + //! Also when no image is defined for a state it will use images from another state + //! and if that state is not set from the replacement for that,etc. + //! So in many cases setting EGBIS_IMAGE_UP and EGBIS_IMAGE_DOWN is sufficient. + enum EGUI_BUTTON_IMAGE_STATE { + //! When no other states have images they will all use this one. + EGBIS_IMAGE_UP, + //! When not set EGBIS_IMAGE_UP is used. + EGBIS_IMAGE_UP_MOUSEOVER, + //! When not set EGBIS_IMAGE_UP_MOUSEOVER is used. + EGBIS_IMAGE_UP_FOCUSED, + //! When not set EGBIS_IMAGE_UP_FOCUSED is used. + EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER, + //! When not set EGBIS_IMAGE_UP is used. + EGBIS_IMAGE_DOWN, + //! When not set EGBIS_IMAGE_DOWN is used. + EGBIS_IMAGE_DOWN_MOUSEOVER, + //! When not set EGBIS_IMAGE_DOWN_MOUSEOVER is used. + EGBIS_IMAGE_DOWN_FOCUSED, + //! When not set EGBIS_IMAGE_DOWN_FOCUSED is used. + EGBIS_IMAGE_DOWN_FOCUSED_MOUSEOVER, + //! When not set EGBIS_IMAGE_UP or EGBIS_IMAGE_DOWN are used (depending on button state). + EGBIS_IMAGE_DISABLED, + //! not used, counts the number of enumerated items + EGBIS_COUNT + }; + + //! Names for gui button image states + const c8 *const GUIButtonImageStateNames[EGBIS_COUNT + 1] = + { + "Image", // not "ImageUp" as it otherwise breaks serialization of old files + "ImageUpOver", + "ImageUpFocused", + "ImageUpFocusedOver", + "PressedImage", // not "ImageDown" as it otherwise breaks serialization of old files + "ImageDownOver", + "ImageDownFocused", + "ImageDownFocusedOver", + "ImageDisabled", + 0 // count + }; + + }} + +#endif + +class ISimpleTextureSource; + +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 8) +#define OVERRIDE_19 +#else +#define OVERRIDE_19 override +#endif + +class GUIButton : public gui::IGUIButton +{ +public: + + //! constructor + GUIButton(gui::IGUIEnvironment* environment, gui::IGUIElement* parent, + s32 id, core::rect<s32> rectangle, ISimpleTextureSource *tsrc, + bool noclip=false); + + //! destructor + virtual ~GUIButton(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event) override; + + //! draws the element and its children + virtual void draw() override; + + //! sets another skin independent font. if this is set to zero, the button uses the font of the skin. + virtual void setOverrideFont(gui::IGUIFont* font=0) override; + + //! Gets the override font (if any) + virtual gui::IGUIFont* getOverrideFont() const override; + + //! Get the font which is used right now for drawing + virtual gui::IGUIFont* getActiveFont() const override; + + //! Sets another color for the button text. + virtual void setOverrideColor(video::SColor color) OVERRIDE_19; + + //! Gets the override color + virtual video::SColor getOverrideColor(void) const OVERRIDE_19; + + #if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8 + //! Gets the currently used text color + virtual video::SColor getActiveColor() const override; + #endif + + //! Sets if the button text should use the override color or the color in the gui skin. + virtual void enableOverrideColor(bool enable) OVERRIDE_19; + + //! Checks if an override color is enabled + virtual bool isOverrideColorEnabled(void) const OVERRIDE_19; + + // PATCH + //! Sets an image which should be displayed on the button when it is in the given state. + virtual void setImage(gui::EGUI_BUTTON_IMAGE_STATE state, + video::ITexture* image=nullptr, + const core::rect<s32>& sourceRect=core::rect<s32>(0,0,0,0)) OVERRIDE_19; + + //! Sets an image which should be displayed on the button when it is in normal state. + virtual void setImage(video::ITexture* image=nullptr) override; + + //! Sets an image which should be displayed on the button when it is in normal state. + virtual void setImage(video::ITexture* image, const core::rect<s32>& pos) override; + + //! Sets an image which should be displayed on the button when it is in pressed state. + virtual void setPressedImage(video::ITexture* image=nullptr) override; + + //! Sets an image which should be displayed on the button when it is in pressed state. + virtual void setPressedImage(video::ITexture* image, const core::rect<s32>& pos) override; + + //! Sets the text displayed by the button + virtual void setText(const wchar_t* text) override; + // END PATCH + + //! Sets the sprite bank used by the button + virtual void setSpriteBank(gui::IGUISpriteBank* bank=0) override; + + //! Sets the animated sprite for a specific button state + /** \param index: Number of the sprite within the sprite bank, use -1 for no sprite + \param state: State of the button to set the sprite for + \param index: The sprite number from the current sprite bank + \param color: The color of the sprite + */ + virtual void setSprite(gui::EGUI_BUTTON_STATE state, s32 index, + video::SColor color=video::SColor(255,255,255,255), + bool loop=false, bool scale=false) OVERRIDE_19; + +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 8) + void setSprite(gui::EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop) override { + setSprite(state, index, color, loop, false); + } +#endif + + //! Get the sprite-index for the given state or -1 when no sprite is set + virtual s32 getSpriteIndex(gui::EGUI_BUTTON_STATE state) const OVERRIDE_19; + + //! Get the sprite color for the given state. Color is only used when a sprite is set. + virtual video::SColor getSpriteColor(gui::EGUI_BUTTON_STATE state) const OVERRIDE_19; + + //! Returns if the sprite in the given state does loop + virtual bool getSpriteLoop(gui::EGUI_BUTTON_STATE state) const OVERRIDE_19; + + //! Returns if the sprite in the given state is scaled + virtual bool getSpriteScale(gui::EGUI_BUTTON_STATE state) const OVERRIDE_19; + + //! Sets if the button should behave like a push button. Which means it + //! can be in two states: Normal or Pressed. With a click on the button, + //! the user can change the state of the button. + virtual void setIsPushButton(bool isPushButton=true) override; + + //! Checks whether the button is a push button + virtual bool isPushButton() const override; + + //! Sets the pressed state of the button if this is a pushbutton + virtual void setPressed(bool pressed=true) override; + + //! Returns if the button is currently pressed + virtual bool isPressed() const override; + + // PATCH + //! Returns if this element (or one of its direct children) is hovered + bool isHovered() const; + // END PATCH + + //! Sets if the button should use the skin to draw its border + virtual void setDrawBorder(bool border=true) override; + + //! Checks if the button face and border are being drawn + virtual bool isDrawingBorder() const override; + + //! Sets if the alpha channel should be used for drawing images on the button (default is false) + virtual void setUseAlphaChannel(bool useAlphaChannel=true) override; + + //! Checks if the alpha channel should be used for drawing images on the button + virtual bool isAlphaChannelUsed() const override; + + //! Sets if the button should scale the button images to fit + virtual void setScaleImage(bool scaleImage=true) override; + + //! Checks whether the button scales the used images + virtual bool isScalingImage() const override; + + //! Get if the shift key was pressed in last EGET_BUTTON_CLICKED event + virtual bool getClickShiftState() const OVERRIDE_19 + { + return ClickShiftState; + } + + //! Get if the control key was pressed in last EGET_BUTTON_CLICKED event + virtual bool getClickControlState() const OVERRIDE_19 + { + return ClickControlState; + } + + void setColor(video::SColor color); + // PATCH + //! Set element properties from a StyleSpec corresponding to the button state + void setFromState(); + + //! Set element properties from a StyleSpec + virtual void setFromStyle(const StyleSpec& style); + + //! Set the styles used for each state + void setStyles(const std::array<StyleSpec, StyleSpec::NUM_STATES>& styles); + // END PATCH + + + //! Do not drop returned handle + static GUIButton* addButton(gui::IGUIEnvironment *environment, + const core::rect<s32>& rectangle, ISimpleTextureSource *tsrc, + IGUIElement* parent, s32 id, const wchar_t* text, + const wchar_t *tooltiptext=L""); + +protected: + void drawSprite(gui::EGUI_BUTTON_STATE state, u32 startTime, const core::position2di& center); + gui::EGUI_BUTTON_IMAGE_STATE getImageState(bool pressed) const; + + ISimpleTextureSource *getTextureSource() { return TSrc; } + + struct ButtonImage + { + ButtonImage() : Texture(0), SourceRect(core::rect<s32>(0,0,0,0)) + { + } + + ButtonImage(const ButtonImage& other) : Texture(0), SourceRect(core::rect<s32>(0,0,0,0)) + { + *this = other; + } + + ~ButtonImage() + { + if ( Texture ) + Texture->drop(); + } + + ButtonImage& operator=(const ButtonImage& other) + { + if ( this == &other ) + return *this; + + if (other.Texture) + other.Texture->grab(); + if ( Texture ) + Texture->drop(); + Texture = other.Texture; + SourceRect = other.SourceRect; + return *this; + } + + bool operator==(const ButtonImage& other) const + { + return Texture == other.Texture && SourceRect == other.SourceRect; + } + + + video::ITexture* Texture; + core::rect<s32> SourceRect; + }; + + gui::EGUI_BUTTON_IMAGE_STATE getImageState(bool pressed, const ButtonImage* images) const; + +private: + + struct ButtonSprite + { + ButtonSprite() : Index(-1), Loop(false), Scale(false) + { + } + + bool operator==(const ButtonSprite& other) const + { + return Index == other.Index && Color == other.Color && Loop == other.Loop && Scale == other.Scale; + } + + s32 Index; + video::SColor Color; + bool Loop; + bool Scale; + }; + + ButtonSprite ButtonSprites[gui::EGBS_COUNT]; + gui::IGUISpriteBank* SpriteBank; + + ButtonImage ButtonImages[gui::EGBIS_COUNT]; + + std::array<StyleSpec, StyleSpec::NUM_STATES> Styles; + + gui::IGUIFont* OverrideFont; + + bool OverrideColorEnabled; + video::SColor OverrideColor; + + u32 ClickTime, HoverTime, FocusTime; + + bool ClickShiftState; + bool ClickControlState; + + bool IsPushButton; + bool Pressed; + bool UseAlphaChannel; + bool DrawBorder; + bool ScaleImage; + + video::SColor Colors[4]; + // PATCH + bool WasHovered = false; + ISimpleTextureSource *TSrc; + + gui::IGUIStaticText *StaticText; + + core::rect<s32> BgMiddle; + core::rect<s32> Padding; + core::vector2d<s32> ContentOffset; + video::SColor BgColor; + // END PATCH +}; diff --git a/src/gui/guiButtonImage.cpp b/src/gui/guiButtonImage.cpp new file mode 100644 index 0000000..4ab770a --- /dev/null +++ b/src/gui/guiButtonImage.cpp @@ -0,0 +1,94 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiButtonImage.h" + +#include "client/guiscalingfilter.h" +#include "debug.h" +#include "IGUIEnvironment.h" +#include "IGUIImage.h" +#include "IVideoDriver.h" +#include "StyleSpec.h" + +using namespace irr; +using namespace gui; + +GUIButtonImage::GUIButtonImage(gui::IGUIEnvironment *environment, + gui::IGUIElement *parent, s32 id, core::rect<s32> rectangle, + ISimpleTextureSource *tsrc, bool noclip) + : GUIButton(environment, parent, id, rectangle, tsrc, noclip) +{ + GUIButton::setScaleImage(true); + m_image = new GUIAnimatedImage(environment, this, id, rectangle); + sendToBack(m_image); +} + +void GUIButtonImage::setForegroundImage(video::ITexture *image, + const core::rect<s32> &middle) +{ + if (image == m_foreground_image) + return; + + if (image != nullptr) + image->grab(); + + if (m_foreground_image != nullptr) + m_foreground_image->drop(); + + m_foreground_image = image; + m_image->setTexture(image); + m_image->setMiddleRect(middle); +} + +//! Set element properties from a StyleSpec +void GUIButtonImage::setFromStyle(const StyleSpec &style) +{ + GUIButton::setFromStyle(style); + + video::IVideoDriver *driver = Environment->getVideoDriver(); + + if (style.isNotDefault(StyleSpec::FGIMG)) { + video::ITexture *texture = style.getTexture(StyleSpec::FGIMG, + getTextureSource()); + + setForegroundImage(guiScalingImageButton(driver, texture, + AbsoluteRect.getWidth(), AbsoluteRect.getHeight()), + style.getRect(StyleSpec::FGIMG_MIDDLE, m_image->getMiddleRect())); + } else { + setForegroundImage(); + } +} + +GUIButtonImage *GUIButtonImage::addButton(IGUIEnvironment *environment, + const core::rect<s32> &rectangle, ISimpleTextureSource *tsrc, + IGUIElement *parent, s32 id, const wchar_t *text, + const wchar_t *tooltiptext) +{ + GUIButtonImage *button = new GUIButtonImage(environment, + parent ? parent : environment->getRootGUIElement(), id, rectangle, tsrc); + + if (text) + button->setText(text); + + if (tooltiptext) + button->setToolTipText(tooltiptext); + + button->drop(); + return button; +} diff --git a/src/gui/guiButtonImage.h b/src/gui/guiButtonImage.h new file mode 100644 index 0000000..5549345 --- /dev/null +++ b/src/gui/guiButtonImage.h @@ -0,0 +1,51 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "guiButton.h" +#include "IGUIButton.h" +#include "guiAnimatedImage.h" + +using namespace irr; + +class GUIButtonImage : public GUIButton +{ +public: + //! constructor + GUIButtonImage(gui::IGUIEnvironment *environment, gui::IGUIElement *parent, + s32 id, core::rect<s32> rectangle, ISimpleTextureSource *tsrc, + bool noclip = false); + + void setForegroundImage(video::ITexture *image = nullptr, + const core::rect<s32> &middle = core::rect<s32>()); + + //! Set element properties from a StyleSpec + virtual void setFromStyle(const StyleSpec &style) override; + + //! Do not drop returned handle + static GUIButtonImage *addButton(gui::IGUIEnvironment *environment, + const core::rect<s32> &rectangle, ISimpleTextureSource *tsrc, + IGUIElement *parent, s32 id, const wchar_t *text, + const wchar_t *tooltiptext = L""); + +private: + video::ITexture *m_foreground_image = nullptr; + GUIAnimatedImage *m_image; +}; diff --git a/src/gui/guiButtonItemImage.cpp b/src/gui/guiButtonItemImage.cpp new file mode 100644 index 0000000..d9ab4b9 --- /dev/null +++ b/src/gui/guiButtonItemImage.cpp @@ -0,0 +1,59 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiButtonItemImage.h" + +#include "client/client.h" +#include "client/hud.h" // drawItemStack +#include "guiItemImage.h" +#include "IGUIEnvironment.h" +#include "itemdef.h" + +using namespace irr; +using namespace gui; + +GUIButtonItemImage::GUIButtonItemImage(gui::IGUIEnvironment *environment, + gui::IGUIElement *parent, s32 id, core::rect<s32> rectangle, + ISimpleTextureSource *tsrc, const std::string &item, Client *client, + bool noclip) + : GUIButton (environment, parent, id, rectangle, tsrc, noclip) +{ + m_image = new GUIItemImage(environment, this, id, + core::rect<s32>(0,0,rectangle.getWidth(),rectangle.getHeight()), + item, getActiveFont(), client); + sendToBack(m_image); + + m_client = client; +} + +GUIButtonItemImage *GUIButtonItemImage::addButton(IGUIEnvironment *environment, + const core::rect<s32> &rectangle, ISimpleTextureSource *tsrc, + IGUIElement *parent, s32 id, const wchar_t *text, const std::string &item, + Client *client) +{ + GUIButtonItemImage *button = new GUIButtonItemImage(environment, + parent ? parent : environment->getRootGUIElement(), + id, rectangle, tsrc, item, client); + + if (text) + button->setText(text); + + button->drop(); + return button; +} diff --git a/src/gui/guiButtonItemImage.h b/src/gui/guiButtonItemImage.h new file mode 100644 index 0000000..205e957 --- /dev/null +++ b/src/gui/guiButtonItemImage.h @@ -0,0 +1,47 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "guiButton.h" +#include "IGUIButton.h" + +using namespace irr; + +class Client; +class GUIItemImage; + +class GUIButtonItemImage : public GUIButton +{ +public: + //! constructor + GUIButtonItemImage(gui::IGUIEnvironment *environment, gui::IGUIElement *parent, + s32 id, core::rect<s32> rectangle, ISimpleTextureSource *tsrc, + const std::string &item, Client *client, bool noclip = false); + + //! Do not drop returned handle + static GUIButtonItemImage *addButton(gui::IGUIEnvironment *environment, + const core::rect<s32> &rectangle, ISimpleTextureSource *tsrc, + IGUIElement *parent, s32 id, const wchar_t *text, + const std::string &item, Client *client); + +private: + Client *m_client; + GUIItemImage *m_image; +}; diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp new file mode 100644 index 0000000..280f7e4 --- /dev/null +++ b/src/gui/guiChatConsole.cpp @@ -0,0 +1,728 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "IrrCompileConfig.h" +#include "guiChatConsole.h" +#include "chat.h" +#include "client/client.h" +#include "debug.h" +#include "gettime.h" +#include "client/keycode.h" +#include "settings.h" +#include "porting.h" +#include "client/tile.h" +#include "client/fontengine.h" +#include "log.h" +#include "gettext.h" +#include "irrlicht_changes/CGUITTFont.h" +#include <string> + +inline u32 clamp_u8(s32 value) +{ + return (u32) MYMIN(MYMAX(value, 0), 255); +} + +inline bool isInCtrlKeys(const irr::EKEY_CODE& kc) +{ + return kc == KEY_LCONTROL || kc == KEY_RCONTROL || kc == KEY_CONTROL; +} + +GUIChatConsole::GUIChatConsole( + gui::IGUIEnvironment* env, + gui::IGUIElement* parent, + s32 id, + ChatBackend* backend, + Client* client, + IMenuManager* menumgr +): + IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, + core::rect<s32>(0,0,100,100)), + m_chat_backend(backend), + m_client(client), + m_menumgr(menumgr), + m_animate_time_old(porting::getTimeMs()) +{ + // load background settings + s32 console_alpha = g_settings->getS32("console_alpha"); + m_background_color.setAlpha(clamp_u8(console_alpha)); + + // load the background texture depending on settings + ITextureSource *tsrc = client->getTextureSource(); + if (tsrc->isKnownSourceImage("background_chat.jpg")) { + m_background = tsrc->getTexture("background_chat.jpg"); + m_background_color.setRed(255); + m_background_color.setGreen(255); + m_background_color.setBlue(255); + } else { + v3f console_color = g_settings->getV3F("console_color"); + m_background_color.setRed(clamp_u8(myround(console_color.X))); + m_background_color.setGreen(clamp_u8(myround(console_color.Y))); + m_background_color.setBlue(clamp_u8(myround(console_color.Z))); + } + + const u16 chat_font_size = g_settings->getU16("chat_font_size"); + m_font = g_fontengine->getFont(chat_font_size != 0 ? + rangelim(chat_font_size, 5, 72) : FONT_SIZE_UNSPECIFIED, FM_Mono); + + if (!m_font) { + errorstream << "GUIChatConsole: Unable to load mono font" << std::endl; + } else { + core::dimension2d<u32> dim = m_font->getDimension(L"M"); + m_fontsize = v2u32(dim.Width, dim.Height); + m_font->grab(); + } + m_fontsize.X = MYMAX(m_fontsize.X, 1); + m_fontsize.Y = MYMAX(m_fontsize.Y, 1); + + // set default cursor options + setCursor(true, true, 2.0, 0.1); + + // track ctrl keys for mouse event + m_is_ctrl_down = false; + m_cache_clickable_chat_weblinks = g_settings->getBool("clickable_chat_weblinks"); +} + +GUIChatConsole::~GUIChatConsole() +{ + if (m_font) + m_font->drop(); +} + +void GUIChatConsole::openConsole(f32 scale) +{ + assert(scale > 0.0f && scale <= 1.0f); + + m_open = true; + m_desired_height_fraction = scale; + m_desired_height = scale * m_screensize.Y; + reformatConsole(); + m_animate_time_old = porting::getTimeMs(); + IGUIElement::setVisible(true); + Environment->setFocus(this); + m_menumgr->createdMenu(this); +} + +bool GUIChatConsole::isOpen() const +{ + return m_open; +} + +bool GUIChatConsole::isOpenInhibited() const +{ + return m_open_inhibited > 0; +} + +void GUIChatConsole::closeConsole() +{ + m_open = false; + Environment->removeFocus(this); + m_menumgr->deletingMenu(this); +} + +void GUIChatConsole::closeConsoleAtOnce() +{ + closeConsole(); + m_height = 0; + recalculateConsolePosition(); +} + +void GUIChatConsole::replaceAndAddToHistory(const std::wstring &line) +{ + ChatPrompt& prompt = m_chat_backend->getPrompt(); + prompt.addToHistory(prompt.getLine()); + prompt.replace(line); +} + + +void GUIChatConsole::setCursor( + bool visible, bool blinking, f32 blink_speed, f32 relative_height) +{ + if (visible) + { + if (blinking) + { + // leave m_cursor_blink unchanged + m_cursor_blink_speed = blink_speed; + } + else + { + m_cursor_blink = 0x8000; // on + m_cursor_blink_speed = 0.0; + } + } + else + { + m_cursor_blink = 0; // off + m_cursor_blink_speed = 0.0; + } + m_cursor_height = relative_height; +} + +void GUIChatConsole::draw() +{ + if(!IsVisible) + return; + + video::IVideoDriver* driver = Environment->getVideoDriver(); + + // Check screen size + v2u32 screensize = driver->getScreenSize(); + if (screensize != m_screensize) + { + // screen size has changed + // scale current console height to new window size + if (m_screensize.Y != 0) + m_height = m_height * screensize.Y / m_screensize.Y; + m_screensize = screensize; + m_desired_height = m_desired_height_fraction * m_screensize.Y; + reformatConsole(); + } + + // Animation + u64 now = porting::getTimeMs(); + animate(now - m_animate_time_old); + m_animate_time_old = now; + + // Draw console elements if visible + if (m_height > 0) + { + drawBackground(); + drawText(); + drawPrompt(); + } + + gui::IGUIElement::draw(); +} + +void GUIChatConsole::reformatConsole() +{ + s32 cols = m_screensize.X / m_fontsize.X - 2; // make room for a margin (looks better) + s32 rows = m_desired_height / m_fontsize.Y - 1; // make room for the input prompt + if (cols <= 0 || rows <= 0) + cols = rows = 0; + recalculateConsolePosition(); + m_chat_backend->reformat(cols, rows); +} + +void GUIChatConsole::recalculateConsolePosition() +{ + core::rect<s32> rect(0, 0, m_screensize.X, m_height); + DesiredRect = rect; + recalculateAbsolutePosition(false); +} + +void GUIChatConsole::animate(u32 msec) +{ + // animate the console height + s32 goal = m_open ? m_desired_height : 0; + + // Set invisible if close animation finished (reset by openConsole) + // This function (animate()) is never called once its visibility becomes false so do not + // actually set visible to false before the inhibited period is over + if (!m_open && m_height == 0 && m_open_inhibited == 0) + IGUIElement::setVisible(false); + + if (m_height != goal) + { + s32 max_change = msec * m_screensize.Y * (m_height_speed / 1000.0); + if (max_change == 0) + max_change = 1; + + if (m_height < goal) + { + // increase height + if (m_height + max_change < goal) + m_height += max_change; + else + m_height = goal; + } + else + { + // decrease height + if (m_height > goal + max_change) + m_height -= max_change; + else + m_height = goal; + } + + recalculateConsolePosition(); + } + + // blink the cursor + if (m_cursor_blink_speed != 0.0) + { + u32 blink_increase = 0x10000 * msec * (m_cursor_blink_speed / 1000.0); + if (blink_increase == 0) + blink_increase = 1; + m_cursor_blink = ((m_cursor_blink + blink_increase) & 0xffff); + } + + // decrease open inhibit counter + if (m_open_inhibited > msec) + m_open_inhibited -= msec; + else + m_open_inhibited = 0; +} + +void GUIChatConsole::drawBackground() +{ + video::IVideoDriver* driver = Environment->getVideoDriver(); + if (m_background != NULL) + { + core::rect<s32> sourcerect(0, -m_height, m_screensize.X, 0); + driver->draw2DImage( + m_background, + v2s32(0, 0), + sourcerect, + &AbsoluteClippingRect, + m_background_color, + false); + } + else + { + driver->draw2DRectangle( + m_background_color, + core::rect<s32>(0, 0, m_screensize.X, m_height), + &AbsoluteClippingRect); + } +} + +void GUIChatConsole::drawText() +{ + if (m_font == NULL) + return; + + ChatBuffer& buf = m_chat_backend->getConsoleBuffer(); + for (u32 row = 0; row < buf.getRows(); ++row) + { + const ChatFormattedLine& line = buf.getFormattedLine(row); + if (line.fragments.empty()) + continue; + + s32 line_height = m_fontsize.Y; + s32 y = row * line_height + m_height - m_desired_height; + if (y + line_height < 0) + continue; + + for (const ChatFormattedFragment &fragment : line.fragments) { + s32 x = (fragment.column + 1) * m_fontsize.X; + core::rect<s32> destrect( + x, y, x + m_fontsize.X * fragment.text.size(), y + m_fontsize.Y); + + if (m_font->getType() == irr::gui::EGFT_CUSTOM) { + // Draw colored text if possible + gui::CGUITTFont *tmp = static_cast<gui::CGUITTFont*>(m_font); + tmp->draw( + fragment.text, + destrect, + false, + false, + &AbsoluteClippingRect); + } else { + // Otherwise use standard text + m_font->draw( + fragment.text.c_str(), + destrect, + video::SColor(255, 255, 255, 255), + false, + false, + &AbsoluteClippingRect); + } + } + } +} + +void GUIChatConsole::drawPrompt() +{ + if (!m_font) + return; + + u32 row = m_chat_backend->getConsoleBuffer().getRows(); + s32 line_height = m_fontsize.Y; + s32 y = row * line_height + m_height - m_desired_height; + + ChatPrompt& prompt = m_chat_backend->getPrompt(); + std::wstring prompt_text = prompt.getVisiblePortion(); + + // FIXME Draw string at once, not character by character + // That will only work with the cursor once we have a monospace font + for (u32 i = 0; i < prompt_text.size(); ++i) + { + wchar_t ws[2] = {prompt_text[i], 0}; + s32 x = (1 + i) * m_fontsize.X; + core::rect<s32> destrect( + x, y, x + m_fontsize.X, y + m_fontsize.Y); + m_font->draw( + ws, + destrect, + video::SColor(255, 255, 255, 255), + false, + false, + &AbsoluteClippingRect); + } + + // Draw the cursor during on periods + if ((m_cursor_blink & 0x8000) != 0) + { + s32 cursor_pos = prompt.getVisibleCursorPosition(); + if (cursor_pos >= 0) + { + s32 cursor_len = prompt.getCursorLength(); + video::IVideoDriver* driver = Environment->getVideoDriver(); + s32 x = (1 + cursor_pos) * m_fontsize.X; + core::rect<s32> destrect( + x, + y + m_fontsize.Y * (1.0 - m_cursor_height), + x + m_fontsize.X * MYMAX(cursor_len, 1), + y + m_fontsize.Y * (cursor_len ? m_cursor_height+1 : 1) + ); + video::SColor cursor_color(255,255,255,255); + driver->draw2DRectangle( + cursor_color, + destrect, + &AbsoluteClippingRect); + } + } + +} + +bool GUIChatConsole::OnEvent(const SEvent& event) +{ + + ChatPrompt &prompt = m_chat_backend->getPrompt(); + + if (event.EventType == EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown) + { + // CTRL up + if (isInCtrlKeys(event.KeyInput.Key)) + { + m_is_ctrl_down = false; + } + } + else if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown) + { + // CTRL down + if (isInCtrlKeys(event.KeyInput.Key)) { + m_is_ctrl_down = true; + } + + // Key input + if (KeyPress(event.KeyInput) == getKeySetting("keymap_console")) { + closeConsole(); + + // inhibit open so the_game doesn't reopen immediately + m_open_inhibited = 50; + m_close_on_enter = false; + return true; + } + + if (event.KeyInput.Key == KEY_ESCAPE) { + closeConsoleAtOnce(); + m_close_on_enter = false; + // inhibit open so the_game doesn't reopen immediately + m_open_inhibited = 1; // so the ESCAPE button doesn't open the "pause menu" + return true; + } + else if(event.KeyInput.Key == KEY_PRIOR) + { + m_chat_backend->scrollPageUp(); + return true; + } + else if(event.KeyInput.Key == KEY_NEXT) + { + m_chat_backend->scrollPageDown(); + return true; + } + else if(event.KeyInput.Key == KEY_RETURN) + { + prompt.addToHistory(prompt.getLine()); + std::wstring text = prompt.replace(L""); + m_client->typeChatMessage(text); + if (m_close_on_enter) { + closeConsoleAtOnce(); + m_close_on_enter = false; + } + return true; + } + else if(event.KeyInput.Key == KEY_UP) + { + // Up pressed + // Move back in history + prompt.historyPrev(); + return true; + } + else if(event.KeyInput.Key == KEY_DOWN) + { + // Down pressed + // Move forward in history + prompt.historyNext(); + return true; + } + else if(event.KeyInput.Key == KEY_LEFT || event.KeyInput.Key == KEY_RIGHT) + { + // Left/right pressed + // Move/select character/word to the left depending on control and shift keys + ChatPrompt::CursorOp op = event.KeyInput.Shift ? + ChatPrompt::CURSOROP_SELECT : + ChatPrompt::CURSOROP_MOVE; + ChatPrompt::CursorOpDir dir = event.KeyInput.Key == KEY_LEFT ? + ChatPrompt::CURSOROP_DIR_LEFT : + ChatPrompt::CURSOROP_DIR_RIGHT; + ChatPrompt::CursorOpScope scope = event.KeyInput.Control ? + ChatPrompt::CURSOROP_SCOPE_WORD : + ChatPrompt::CURSOROP_SCOPE_CHARACTER; + prompt.cursorOperation(op, dir, scope); + return true; + } + else if(event.KeyInput.Key == KEY_HOME) + { + // Home pressed + // move to beginning of line + prompt.cursorOperation( + ChatPrompt::CURSOROP_MOVE, + ChatPrompt::CURSOROP_DIR_LEFT, + ChatPrompt::CURSOROP_SCOPE_LINE); + return true; + } + else if(event.KeyInput.Key == KEY_END) + { + // End pressed + // move to end of line + prompt.cursorOperation( + ChatPrompt::CURSOROP_MOVE, + ChatPrompt::CURSOROP_DIR_RIGHT, + ChatPrompt::CURSOROP_SCOPE_LINE); + return true; + } + else if(event.KeyInput.Key == KEY_BACK) + { + // Backspace or Ctrl-Backspace pressed + // delete character / word to the left + ChatPrompt::CursorOpScope scope = + event.KeyInput.Control ? + ChatPrompt::CURSOROP_SCOPE_WORD : + ChatPrompt::CURSOROP_SCOPE_CHARACTER; + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_LEFT, + scope); + return true; + } + else if(event.KeyInput.Key == KEY_DELETE) + { + // Delete or Ctrl-Delete pressed + // delete character / word to the right + ChatPrompt::CursorOpScope scope = + event.KeyInput.Control ? + ChatPrompt::CURSOROP_SCOPE_WORD : + ChatPrompt::CURSOROP_SCOPE_CHARACTER; + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_RIGHT, + scope); + return true; + } + else if(event.KeyInput.Key == KEY_KEY_A && event.KeyInput.Control) + { + // Ctrl-A pressed + // Select all text + prompt.cursorOperation( + ChatPrompt::CURSOROP_SELECT, + ChatPrompt::CURSOROP_DIR_LEFT, // Ignored + ChatPrompt::CURSOROP_SCOPE_LINE); + return true; + } + else if(event.KeyInput.Key == KEY_KEY_C && event.KeyInput.Control) + { + // Ctrl-C pressed + // Copy text to clipboard + if (prompt.getCursorLength() <= 0) + return true; + std::wstring wselected = prompt.getSelection(); + std::string selected = wide_to_utf8(wselected); + Environment->getOSOperator()->copyToClipboard(selected.c_str()); + return true; + } + else if(event.KeyInput.Key == KEY_KEY_V && event.KeyInput.Control) + { + // Ctrl-V pressed + // paste text from clipboard + if (prompt.getCursorLength() > 0) { + // Delete selected section of text + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_LEFT, // Ignored + ChatPrompt::CURSOROP_SCOPE_SELECTION); + } + IOSOperator *os_operator = Environment->getOSOperator(); + const c8 *text = os_operator->getTextFromClipboard(); + if (!text) + return true; + prompt.input(utf8_to_wide(text)); + return true; + } + else if(event.KeyInput.Key == KEY_KEY_X && event.KeyInput.Control) + { + // Ctrl-X pressed + // Cut text to clipboard + if (prompt.getCursorLength() <= 0) + return true; + std::wstring wselected = prompt.getSelection(); + std::string selected = wide_to_utf8(wselected); + Environment->getOSOperator()->copyToClipboard(selected.c_str()); + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_LEFT, // Ignored + ChatPrompt::CURSOROP_SCOPE_SELECTION); + return true; + } + else if(event.KeyInput.Key == KEY_KEY_U && event.KeyInput.Control) + { + // Ctrl-U pressed + // kill line to left end + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_LEFT, + ChatPrompt::CURSOROP_SCOPE_LINE); + return true; + } + else if(event.KeyInput.Key == KEY_KEY_K && event.KeyInput.Control) + { + // Ctrl-K pressed + // kill line to right end + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_RIGHT, + ChatPrompt::CURSOROP_SCOPE_LINE); + return true; + } + else if(event.KeyInput.Key == KEY_TAB) + { + // Tab or Shift-Tab pressed + // Nick completion + std::list<std::string> names = m_client->getConnectedPlayerNames(); + bool backwards = event.KeyInput.Shift; + prompt.nickCompletion(names, backwards); + return true; + } else if (!iswcntrl(event.KeyInput.Char) && !event.KeyInput.Control) { + prompt.input(event.KeyInput.Char); + return true; + } + } + else if(event.EventType == EET_MOUSE_INPUT_EVENT) + { + if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) + { + s32 rows = myround(-3.0 * event.MouseInput.Wheel); + m_chat_backend->scroll(rows); + } + // Middle click or ctrl-click opens weblink, if enabled in config + else if(m_cache_clickable_chat_weblinks && ( + event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN || + (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN && m_is_ctrl_down) + )) + { + // If clicked within console output region + if (event.MouseInput.Y / m_fontsize.Y < (m_height / m_fontsize.Y) - 1 ) + { + // Translate pixel position to font position + middleClick(event.MouseInput.X / m_fontsize.X, event.MouseInput.Y / m_fontsize.Y); + } + } + } +#if (IRRLICHT_VERSION_MT_REVISION >= 2) + else if(event.EventType == EET_STRING_INPUT_EVENT) + { + prompt.input(std::wstring(event.StringInput.Str->c_str())); + return true; + } +#endif + + return Parent ? Parent->OnEvent(event) : false; +} + +void GUIChatConsole::setVisible(bool visible) +{ + m_open = visible; + IGUIElement::setVisible(visible); + if (!visible) { + m_height = 0; + recalculateConsolePosition(); + } +} + +void GUIChatConsole::middleClick(s32 col, s32 row) +{ + // Prevent accidental rapid clicking + static u64 s_oldtime = 0; + u64 newtime = porting::getTimeMs(); + + // 0.6 seconds should suffice + if (newtime - s_oldtime < 600) + return; + s_oldtime = newtime; + + const std::vector<ChatFormattedFragment> & + frags = m_chat_backend->getConsoleBuffer().getFormattedLine(row).fragments; + std::string weblink = ""; // from frag meta + + // Identify targetted fragment, if exists + int indx = frags.size() - 1; + if (indx < 0) { + // Invalid row, frags is empty + return; + } + // Scan from right to left, offset by 1 font space because left margin + while (indx > -1 && (u32)col < frags[indx].column + 1) { + --indx; + } + if (indx > -1) { + weblink = frags[indx].weblink; + // Note if(indx < 0) then a frag somehow had a corrupt column field + } + + /* + // Debug help. Please keep this in case adjustments are made later. + std::string ws; + ws = "Middleclick: (" + std::to_string(col) + ',' + std::to_string(row) + ')' + " frags:"; + // show all frags <position>(<length>) for the clicked row + for (u32 i=0;i<frags.size();++i) { + if (indx == int(i)) + // tag the actual clicked frag + ws += '*'; + ws += std::to_string(frags.at(i).column) + '(' + + std::to_string(frags.at(i).text.size()) + "),"; + } + actionstream << ws << std::endl; + */ + + // User notification + if (weblink.size() != 0) { + std::ostringstream msg; + msg << " * "; + if (porting::open_url(weblink)) { + msg << gettext("Opening webpage"); + } + else { + msg << gettext("Failed to open webpage"); + } + msg << " '" << weblink << "'"; + m_chat_backend->addUnparsedMessage(utf8_to_wide(msg.str())); + } +} diff --git a/src/gui/guiChatConsole.h b/src/gui/guiChatConsole.h new file mode 100644 index 0000000..32628f0 --- /dev/null +++ b/src/gui/guiChatConsole.h @@ -0,0 +1,137 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "modalMenu.h" +#include "chat.h" +#include "config.h" + +class Client; + +class GUIChatConsole : public gui::IGUIElement +{ +public: + GUIChatConsole(gui::IGUIEnvironment* env, + gui::IGUIElement* parent, + s32 id, + ChatBackend* backend, + Client* client, + IMenuManager* menumgr); + virtual ~GUIChatConsole(); + + // Open the console (height = desired fraction of screen size) + // This doesn't open immediately but initiates an animation. + // You should call isOpenInhibited() before this. + void openConsole(f32 scale); + + bool isOpen() const; + + // Check if the console should not be opened at the moment + // This is to avoid reopening the console immediately after closing + bool isOpenInhibited() const; + // Close the console, equivalent to openConsole(0). + // This doesn't close immediately but initiates an animation. + void closeConsole(); + // Close the console immediately, without animation. + void closeConsoleAtOnce(); + // Set whether to close the console after the user presses enter. + void setCloseOnEnter(bool close) { m_close_on_enter = close; } + + // Replace actual line when adding the actual to the history (if there is any) + void replaceAndAddToHistory(const std::wstring &line); + + // Change how the cursor looks + void setCursor( + bool visible, + bool blinking = false, + f32 blink_speed = 1.0, + f32 relative_height = 1.0); + + // Irrlicht draw method + virtual void draw(); + + virtual bool OnEvent(const SEvent& event); + + virtual void setVisible(bool visible); + + virtual bool acceptsIME() { return true; } + +private: + void reformatConsole(); + void recalculateConsolePosition(); + + // These methods are called by draw + void animate(u32 msec); + void drawBackground(); + void drawText(); + void drawPrompt(); + + // If clicked fragment has a web url, send it to the system default web browser + void middleClick(s32 col, s32 row); + +private: + ChatBackend* m_chat_backend; + Client* m_client; + IMenuManager* m_menumgr; + + // current screen size + v2u32 m_screensize; + + // used to compute how much time passed since last animate() + u64 m_animate_time_old; + + // should the console be opened or closed? + bool m_open = false; + // should it close after you press enter? + bool m_close_on_enter = false; + // current console height [pixels] + s32 m_height = 0; + // desired height [pixels] + f32 m_desired_height = 0.0f; + // desired height [screen height fraction] + f32 m_desired_height_fraction = 0.0f; + // console open/close animation speed [screen height fraction / second] + f32 m_height_speed = 5.0f; + // if nonzero, opening the console is inhibited [milliseconds] + u32 m_open_inhibited = 0; + + // cursor blink frame (16-bit value) + // cursor is off during [0,32767] and on during [32768,65535] + u32 m_cursor_blink = 0; + // cursor blink speed [on/off toggles / second] + f32 m_cursor_blink_speed = 0.0f; + // cursor height [line height] + f32 m_cursor_height = 0.0f; + + // background texture + video::ITexture *m_background = nullptr; + // background color (including alpha) + video::SColor m_background_color = video::SColor(255, 0, 0, 0); + + // font + gui::IGUIFont *m_font = nullptr; + v2u32 m_fontsize; + + // Enable clickable chat weblinks + bool m_cache_clickable_chat_weblinks; + // Track if a ctrl key is currently held down + bool m_is_ctrl_down; +}; diff --git a/src/gui/guiEditBox.cpp b/src/gui/guiEditBox.cpp new file mode 100644 index 0000000..4a0f501 --- /dev/null +++ b/src/gui/guiEditBox.cpp @@ -0,0 +1,848 @@ +/* +Minetest +Copyright (C) 2021 Minetest + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiEditBox.h" + +#include "IrrCompileConfig.h" +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIFont.h" + +#include "porting.h" +#include "util/string.h" + +GUIEditBox::~GUIEditBox() +{ + if (m_override_font) + m_override_font->drop(); + + if (m_operator) + m_operator->drop(); + + if (m_vscrollbar) + m_vscrollbar->drop(); +} + +void GUIEditBox::setOverrideFont(IGUIFont *font) +{ + if (m_override_font == font) + return; + + if (m_override_font) + m_override_font->drop(); + + m_override_font = font; + + if (m_override_font) + m_override_font->grab(); + + breakText(); +} + +//! Get the font which is used right now for drawing +IGUIFont *GUIEditBox::getActiveFont() const +{ + if (m_override_font) + return m_override_font; + IGUISkin *skin = Environment->getSkin(); + if (skin) + return skin->getFont(); + return 0; +} + +//! Sets another color for the text. +void GUIEditBox::setOverrideColor(video::SColor color) +{ + m_override_color = color; + m_override_color_enabled = true; +} + +video::SColor GUIEditBox::getOverrideColor() const +{ + return m_override_color; +} + +//! Sets if the text should use the overide color or the color in the gui skin. +void GUIEditBox::enableOverrideColor(bool enable) +{ + m_override_color_enabled = enable; +} + +//! Enables or disables word wrap +void GUIEditBox::setWordWrap(bool enable) +{ + m_word_wrap = enable; + breakText(); +} + +//! Enables or disables newlines. +void GUIEditBox::setMultiLine(bool enable) +{ + m_multiline = enable; +} + +//! Enables or disables automatic scrolling with cursor position +//! \param enable: If set to true, the text will move around with the cursor position +void GUIEditBox::setAutoScroll(bool enable) +{ + m_autoscroll = enable; +} + +void GUIEditBox::setPasswordBox(bool password_box, wchar_t password_char) +{ + m_passwordbox = password_box; + if (m_passwordbox) { + m_passwordchar = password_char; + setMultiLine(false); + setWordWrap(false); + m_broken_text.clear(); + } +} + +//! Sets text justification +void GUIEditBox::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) +{ + m_halign = horizontal; + m_valign = vertical; +} + +//! Sets the new caption of this element. +void GUIEditBox::setText(const wchar_t *text) +{ + Text = text; + if (u32(m_cursor_pos) > Text.size()) + m_cursor_pos = Text.size(); + m_hscroll_pos = 0; + breakText(); +} + +//! Sets the maximum amount of characters which may be entered in the box. +//! \param max: Maximum amount of characters. If 0, the character amount is +//! infinity. +void GUIEditBox::setMax(u32 max) +{ + m_max = max; + + if (Text.size() > m_max && m_max != 0) + Text = Text.subString(0, m_max); +} + +//! Gets the area of the text in the edit box +//! \return Returns the size in pixels of the text +core::dimension2du GUIEditBox::getTextDimension() +{ + core::rect<s32> ret; + + setTextRect(0); + ret = m_current_text_rect; + + for (u32 i = 1; i < m_broken_text.size(); ++i) { + setTextRect(i); + ret.addInternalPoint(m_current_text_rect.UpperLeftCorner); + ret.addInternalPoint(m_current_text_rect.LowerRightCorner); + } + + return core::dimension2du(ret.getSize()); +} + +//! Turns the border on or off +void GUIEditBox::setDrawBorder(bool border) +{ + m_border = border; +} + +void GUIEditBox::setWritable(bool can_write_text) +{ + m_writable = can_write_text; +} + +//! set text markers +void GUIEditBox::setTextMarkers(s32 begin, s32 end) +{ + if (begin != m_mark_begin || end != m_mark_end) { + m_mark_begin = begin; + m_mark_end = end; + sendGuiEvent(EGET_EDITBOX_MARKING_CHANGED); + } +} + +//! send some gui event to parent +void GUIEditBox::sendGuiEvent(EGUI_EVENT_TYPE type) +{ + if (Parent) { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = type; + + Parent->OnEvent(e); + } +} + +//! called if an event happened. +bool GUIEditBox::OnEvent(const SEvent &event) +{ + if (isEnabled()) { + + switch (event.EventType) { + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) { + if (event.GUIEvent.Caller == this) { + m_mouse_marking = false; + setTextMarkers(0, 0); + } + } + break; + case EET_KEY_INPUT_EVENT: + if (processKey(event)) + return true; + break; + case EET_MOUSE_INPUT_EVENT: + if (processMouse(event)) + return true; + break; +#if (IRRLICHT_VERSION_MT_REVISION >= 2) + case EET_STRING_INPUT_EVENT: + inputString(*event.StringInput.Str); + return true; +#endif + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + +bool GUIEditBox::processKey(const SEvent &event) +{ + if (!event.KeyInput.PressedDown) + return false; + + bool text_changed = false; + s32 new_mark_begin = m_mark_begin; + s32 new_mark_end = m_mark_end; + + // control shortcut handling + if (event.KeyInput.Control) { + + // german backlash '\' entered with control + '?' + if (event.KeyInput.Char == '\\') { + inputChar(event.KeyInput.Char); + return true; + } + + switch (event.KeyInput.Key) { + case KEY_KEY_A: + // select all + new_mark_begin = 0; + new_mark_end = Text.size(); + break; + case KEY_KEY_C: + onKeyControlC(event); + break; + case KEY_KEY_X: + text_changed = onKeyControlX(event, new_mark_begin, new_mark_end); + break; + case KEY_KEY_V: + text_changed = onKeyControlV(event, new_mark_begin, new_mark_end); + break; + case KEY_HOME: + // move/highlight to start of text + if (event.KeyInput.Shift) { + new_mark_end = m_cursor_pos; + new_mark_begin = 0; + m_cursor_pos = 0; + } else { + m_cursor_pos = 0; + new_mark_begin = 0; + new_mark_end = 0; + } + break; + case KEY_END: + // move/highlight to end of text + if (event.KeyInput.Shift) { + new_mark_begin = m_cursor_pos; + new_mark_end = Text.size(); + m_cursor_pos = 0; + } else { + m_cursor_pos = Text.size(); + new_mark_begin = 0; + new_mark_end = 0; + } + break; + default: + return false; + } + } else { + switch (event.KeyInput.Key) { + case KEY_END: { + s32 p = Text.size(); + if (m_word_wrap || m_multiline) { + p = getLineFromPos(m_cursor_pos); + p = m_broken_text_positions[p] + + (s32)m_broken_text[p].size(); + if (p > 0 && (Text[p - 1] == L'\r' || + Text[p - 1] == L'\n')) + p -= 1; + } + + if (event.KeyInput.Shift) { + if (m_mark_begin == m_mark_end) + new_mark_begin = m_cursor_pos; + + new_mark_end = p; + } else { + new_mark_begin = 0; + new_mark_end = 0; + } + m_cursor_pos = p; + m_blink_start_time = porting::getTimeMs(); + } break; + case KEY_HOME: { + + s32 p = 0; + if (m_word_wrap || m_multiline) { + p = getLineFromPos(m_cursor_pos); + p = m_broken_text_positions[p]; + } + + if (event.KeyInput.Shift) { + if (m_mark_begin == m_mark_end) + new_mark_begin = m_cursor_pos; + new_mark_end = p; + } else { + new_mark_begin = 0; + new_mark_end = 0; + } + m_cursor_pos = p; + m_blink_start_time = porting::getTimeMs(); + } break; + case KEY_RETURN: + if (m_multiline) { + inputChar(L'\n'); + } else { + calculateScrollPos(); + sendGuiEvent(EGET_EDITBOX_ENTER); + } + return true; + case KEY_LEFT: + if (event.KeyInput.Shift) { + if (m_cursor_pos > 0) { + if (m_mark_begin == m_mark_end) + new_mark_begin = m_cursor_pos; + + new_mark_end = m_cursor_pos - 1; + } + } else { + new_mark_begin = 0; + new_mark_end = 0; + } + + if (m_cursor_pos > 0) + m_cursor_pos--; + m_blink_start_time = porting::getTimeMs(); + break; + case KEY_RIGHT: + if (event.KeyInput.Shift) { + if (Text.size() > (u32)m_cursor_pos) { + if (m_mark_begin == m_mark_end) + new_mark_begin = m_cursor_pos; + + new_mark_end = m_cursor_pos + 1; + } + } else { + new_mark_begin = 0; + new_mark_end = 0; + } + + if (Text.size() > (u32)m_cursor_pos) + m_cursor_pos++; + m_blink_start_time = porting::getTimeMs(); + break; + case KEY_UP: + if (!onKeyUp(event, new_mark_begin, new_mark_end)) { + return false; + } + break; + case KEY_DOWN: + if (!onKeyDown(event, new_mark_begin, new_mark_end)) { + return false; + } + break; + case KEY_BACK: + text_changed = onKeyBack(event, new_mark_begin, new_mark_end); + break; + + case KEY_DELETE: + text_changed = onKeyDelete(event, new_mark_begin, new_mark_end); + break; + + case KEY_ESCAPE: + case KEY_TAB: + case KEY_SHIFT: + case KEY_F1: + case KEY_F2: + case KEY_F3: + case KEY_F4: + case KEY_F5: + case KEY_F6: + case KEY_F7: + case KEY_F8: + case KEY_F9: + case KEY_F10: + case KEY_F11: + case KEY_F12: + case KEY_F13: + case KEY_F14: + case KEY_F15: + case KEY_F16: + case KEY_F17: + case KEY_F18: + case KEY_F19: + case KEY_F20: + case KEY_F21: + case KEY_F22: + case KEY_F23: + case KEY_F24: + // ignore these keys + return false; + + default: + inputChar(event.KeyInput.Char); + return true; + } + } + + // Set new text markers + setTextMarkers(new_mark_begin, new_mark_end); + + // break the text if it has changed + if (text_changed) { + breakText(); + sendGuiEvent(EGET_EDITBOX_CHANGED); + } + + calculateScrollPos(); + + return true; +} + +bool GUIEditBox::onKeyUp(const SEvent &event, s32 &mark_begin, s32 &mark_end) +{ + // clang-format off + if (m_multiline || (m_word_wrap && m_broken_text.size() > 1)) { + s32 lineNo = getLineFromPos(m_cursor_pos); + s32 mb = (m_mark_begin == m_mark_end) ? m_cursor_pos : + (m_mark_begin > m_mark_end ? m_mark_begin : m_mark_end); + if (lineNo > 0) { + s32 cp = m_cursor_pos - m_broken_text_positions[lineNo]; + if ((s32)m_broken_text[lineNo - 1].size() < cp) { + m_cursor_pos = m_broken_text_positions[lineNo - 1] + + core::max_((u32)1, m_broken_text[lineNo - 1].size()) - 1; + } + else + m_cursor_pos = m_broken_text_positions[lineNo - 1] + cp; + } + + if (event.KeyInput.Shift) { + mark_begin = mb; + mark_end = m_cursor_pos; + } else { + mark_begin = 0; + mark_end = 0; + } + + return true; + } + + // clang-format on + return false; +} + +bool GUIEditBox::onKeyDown(const SEvent &event, s32 &mark_begin, s32 &mark_end) +{ + // clang-format off + if (m_multiline || (m_word_wrap && m_broken_text.size() > 1)) { + s32 lineNo = getLineFromPos(m_cursor_pos); + s32 mb = (m_mark_begin == m_mark_end) ? m_cursor_pos : + (m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end); + if (lineNo < (s32)m_broken_text.size() - 1) { + s32 cp = m_cursor_pos - m_broken_text_positions[lineNo]; + if ((s32)m_broken_text[lineNo + 1].size() < cp) { + m_cursor_pos = m_broken_text_positions[lineNo + 1] + + core::max_((u32)1, m_broken_text[lineNo + 1].size()) - 1; + } + else + m_cursor_pos = m_broken_text_positions[lineNo + 1] + cp; + } + + if (event.KeyInput.Shift) { + mark_begin = mb; + mark_end = m_cursor_pos; + } else { + mark_begin = 0; + mark_end = 0; + } + + return true; + } + + // clang-format on + return false; +} + +void GUIEditBox::onKeyControlC(const SEvent &event) +{ + // copy to clipboard + if (m_passwordbox || !m_operator || m_mark_begin == m_mark_end) + return; + + const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end; + const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin; + + std::string s = stringw_to_utf8(Text.subString(realmbgn, realmend - realmbgn)); + m_operator->copyToClipboard(s.c_str()); +} + +bool GUIEditBox::onKeyControlX(const SEvent &event, s32 &mark_begin, s32 &mark_end) +{ + // First copy to clipboard + onKeyControlC(event); + + if (!m_writable) + return false; + + if (m_passwordbox || !m_operator || m_mark_begin == m_mark_end) + return false; + + const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end; + const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin; + + // Now remove from box if enabled + if (isEnabled()) { + // delete + core::stringw s; + s = Text.subString(0, realmbgn); + s.append(Text.subString(realmend, Text.size() - realmend)); + Text = s; + + m_cursor_pos = realmbgn; + mark_begin = 0; + mark_end = 0; + return true; + } + + return false; +} + +bool GUIEditBox::onKeyControlV(const SEvent &event, s32 &mark_begin, s32 &mark_end) +{ + if (!isEnabled() || !m_writable) + return false; + + // paste from the clipboard + if (!m_operator) + return false; + + const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end; + const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin; + + // add new character + if (const c8 *p = m_operator->getTextFromClipboard()) { + core::stringw inserted_text = utf8_to_stringw(p); + if (m_mark_begin == m_mark_end) { + // insert text + core::stringw s = Text.subString(0, m_cursor_pos); + s.append(inserted_text); + s.append(Text.subString( + m_cursor_pos, Text.size() - m_cursor_pos)); + + if (!m_max || s.size() <= m_max) { + Text = s; + m_cursor_pos += inserted_text.size(); + } + } else { + // replace text + + core::stringw s = Text.subString(0, realmbgn); + s.append(inserted_text); + s.append(Text.subString(realmend, Text.size() - realmend)); + + if (!m_max || s.size() <= m_max) { + Text = s; + m_cursor_pos = realmbgn + inserted_text.size(); + } + } + } + + mark_begin = 0; + mark_end = 0; + return true; +} + +bool GUIEditBox::onKeyBack(const SEvent &event, s32 &mark_begin, s32 &mark_end) +{ + if (!isEnabled() || Text.empty() || !m_writable) + return false; + + core::stringw s; + + if (m_mark_begin != m_mark_end) { + // delete marked text + const s32 realmbgn = + m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end; + const s32 realmend = + m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin; + + s = Text.subString(0, realmbgn); + s.append(Text.subString(realmend, Text.size() - realmend)); + Text = s; + + m_cursor_pos = realmbgn; + } else { + // delete text behind cursor + if (m_cursor_pos > 0) + s = Text.subString(0, m_cursor_pos - 1); + else + s = L""; + s.append(Text.subString(m_cursor_pos, Text.size() - m_cursor_pos)); + Text = s; + --m_cursor_pos; + } + + if (m_cursor_pos < 0) + m_cursor_pos = 0; + m_blink_start_time = porting::getTimeMs(); // os::Timer::getTime(); + mark_begin = 0; + mark_end = 0; + return true; +} + +bool GUIEditBox::onKeyDelete(const SEvent &event, s32 &mark_begin, s32 &mark_end) +{ + if (!isEnabled() || Text.empty() || !m_writable) + return false; + + core::stringw s; + + if (m_mark_begin != m_mark_end) { + // delete marked text + const s32 realmbgn = + m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end; + const s32 realmend = + m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin; + + s = Text.subString(0, realmbgn); + s.append(Text.subString(realmend, Text.size() - realmend)); + Text = s; + + m_cursor_pos = realmbgn; + } else { + // delete text before cursor + s = Text.subString(0, m_cursor_pos); + s.append(Text.subString( + m_cursor_pos + 1, Text.size() - m_cursor_pos - 1)); + Text = s; + } + + if (m_cursor_pos > (s32)Text.size()) + m_cursor_pos = (s32)Text.size(); + + m_blink_start_time = porting::getTimeMs(); // os::Timer::getTime(); + mark_begin = 0; + mark_end = 0; + return true; +} + +void GUIEditBox::inputChar(wchar_t c) +{ + if (c == 0) + return; + core::stringw s(&c, 1); + inputString(s); +} + +void GUIEditBox::inputString(const core::stringw &str) +{ + if (!isEnabled() || !m_writable) + return; + + u32 len = str.size(); + if (Text.size()+len <= m_max || m_max == 0) { + core::stringw s; + if (m_mark_begin != m_mark_end) { + // replace marked text + s32 real_begin = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end; + s32 real_end = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin; + + s = Text.subString(0, real_begin); + s.append(str); + s.append(Text.subString(real_end, Text.size() - real_end)); + Text = s; + m_cursor_pos = real_begin + len; + } else { + // append string + s = Text.subString(0, m_cursor_pos); + s.append(str); + s.append(Text.subString(m_cursor_pos, + Text.size() - m_cursor_pos)); + Text = s; + m_cursor_pos += len; + } + + m_blink_start_time = porting::getTimeMs(); + setTextMarkers(0, 0); + } + + breakText(); + sendGuiEvent(EGET_EDITBOX_CHANGED); + calculateScrollPos(); +} + +bool GUIEditBox::processMouse(const SEvent &event) +{ + switch (event.MouseInput.Event) { + case irr::EMIE_LMOUSE_LEFT_UP: + if (Environment->hasFocus(this)) { + m_cursor_pos = getCursorPos( + event.MouseInput.X, event.MouseInput.Y); + if (m_mouse_marking) { + setTextMarkers(m_mark_begin, m_cursor_pos); + } + m_mouse_marking = false; + calculateScrollPos(); + return true; + } + break; + case irr::EMIE_MOUSE_MOVED: { + if (m_mouse_marking) { + m_cursor_pos = getCursorPos( + event.MouseInput.X, event.MouseInput.Y); + setTextMarkers(m_mark_begin, m_cursor_pos); + calculateScrollPos(); + return true; + } + } break; + case EMIE_LMOUSE_PRESSED_DOWN: + + if (!Environment->hasFocus(this)) { + m_blink_start_time = porting::getTimeMs(); + m_mouse_marking = true; + m_cursor_pos = getCursorPos( + event.MouseInput.X, event.MouseInput.Y); + setTextMarkers(m_cursor_pos, m_cursor_pos); + calculateScrollPos(); + return true; + } else { + if (!AbsoluteClippingRect.isPointInside(core::position2d<s32>( + event.MouseInput.X, event.MouseInput.Y))) { + return false; + } else { + // move cursor + m_cursor_pos = getCursorPos( + event.MouseInput.X, event.MouseInput.Y); + + s32 newMarkBegin = m_mark_begin; + if (!m_mouse_marking) + newMarkBegin = m_cursor_pos; + + m_mouse_marking = true; + setTextMarkers(newMarkBegin, m_cursor_pos); + calculateScrollPos(); + return true; + } + } + case EMIE_MOUSE_WHEEL: + if (m_vscrollbar && m_vscrollbar->isVisible()) { + s32 pos = m_vscrollbar->getPos(); + s32 step = m_vscrollbar->getSmallStep(); + m_vscrollbar->setPos(pos - event.MouseInput.Wheel * step); + return true; + } + break; + default: + break; + } + + return false; +} + +s32 GUIEditBox::getLineFromPos(s32 pos) +{ + if (!m_word_wrap && !m_multiline) + return 0; + + s32 i = 0; + while (i < (s32)m_broken_text_positions.size()) { + if (m_broken_text_positions[i] > pos) + return i - 1; + ++i; + } + return (s32)m_broken_text_positions.size() - 1; +} + +void GUIEditBox::updateVScrollBar() +{ + if (!m_vscrollbar) { + return; + } + + // OnScrollBarChanged(...) + if (m_vscrollbar->getPos() != m_vscroll_pos) { + s32 deltaScrollY = m_vscrollbar->getPos() - m_vscroll_pos; + m_current_text_rect.UpperLeftCorner.Y -= deltaScrollY; + m_current_text_rect.LowerRightCorner.Y -= deltaScrollY; + + s32 scrollymax = getTextDimension().Height - m_frame_rect.getHeight(); + if (scrollymax != m_vscrollbar->getMax()) { + // manage a newline or a deleted line + m_vscrollbar->setMax(scrollymax); + m_vscrollbar->setPageSize(s32(getTextDimension().Height)); + calculateScrollPos(); + } else { + // manage a newline or a deleted line + m_vscroll_pos = m_vscrollbar->getPos(); + } + } + + // check if a vertical scrollbar is needed ? + if (getTextDimension().Height > (u32)m_frame_rect.getHeight()) { + m_frame_rect.LowerRightCorner.X -= m_scrollbar_width; + + s32 scrollymax = getTextDimension().Height - m_frame_rect.getHeight(); + if (scrollymax != m_vscrollbar->getMax()) { + m_vscrollbar->setMax(scrollymax); + m_vscrollbar->setPageSize(s32(getTextDimension().Height)); + } + + if (!m_vscrollbar->isVisible()) { + m_vscrollbar->setVisible(true); + } + } else { + if (m_vscrollbar->isVisible()) { + m_vscrollbar->setVisible(false); + m_vscroll_pos = 0; + m_vscrollbar->setPos(0); + m_vscrollbar->setMax(1); + m_vscrollbar->setPageSize(s32(getTextDimension().Height)); + } + } +} diff --git a/src/gui/guiEditBox.h b/src/gui/guiEditBox.h new file mode 100644 index 0000000..4c7413f --- /dev/null +++ b/src/gui/guiEditBox.h @@ -0,0 +1,215 @@ +/* +Minetest +Copyright (C) 2021 Minetest + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "IGUIEditBox.h" +#include "IOSOperator.h" +#include "guiScrollBar.h" +#include <vector> + +using namespace irr; +using namespace irr::gui; + +class GUIEditBox : public IGUIEditBox +{ +public: + GUIEditBox(IGUIEnvironment *environment, IGUIElement *parent, s32 id, + core::rect<s32> rectangle, bool border, bool writable) : + IGUIEditBox(environment, parent, id, rectangle), + m_border(border), m_writable(writable), m_frame_rect(rectangle) + { + } + + virtual ~GUIEditBox(); + + //! Sets another skin independent font. + virtual void setOverrideFont(IGUIFont *font = 0); + + virtual IGUIFont *getOverrideFont() const { return m_override_font; } + + //! Get the font which is used right now for drawing + /** Currently this is the override font when one is set and the + font of the active skin otherwise */ + virtual IGUIFont *getActiveFont() const; + + //! Sets another color for the text. + virtual void setOverrideColor(video::SColor color); + + //! Gets the override color + virtual video::SColor getOverrideColor() const; + + //! Sets if the text should use the overide color or the + //! color in the gui skin. + virtual void enableOverrideColor(bool enable); + + //! Checks if an override color is enabled + /** \return true if the override color is enabled, false otherwise */ + virtual bool isOverrideColorEnabled(void) const + { + return m_override_color_enabled; + } + + //! Enables or disables word wrap for using the edit box as multiline text editor. + virtual void setWordWrap(bool enable); + + //! Checks if word wrap is enabled + //! \return true if word wrap is enabled, false otherwise + virtual bool isWordWrapEnabled() const { return m_word_wrap; } + + //! Turns the border on or off + virtual void setDrawBorder(bool border); + + virtual bool isDrawBorderEnabled() const { return m_border; } + + //! Enables or disables newlines. + /** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired, + instead a newline character will be inserted. */ + virtual void setMultiLine(bool enable); + + //! Checks if multi line editing is enabled + //! \return true if mult-line is enabled, false otherwise + virtual bool isMultiLineEnabled() const { return m_multiline; } + + //! Enables or disables automatic scrolling with cursor position + //! \param enable: If set to true, the text will move around with the cursor + //! position + virtual void setAutoScroll(bool enable); + + //! Checks to see if automatic scrolling is enabled + //! \return true if automatic scrolling is enabled, false if not + virtual bool isAutoScrollEnabled() const { return m_autoscroll; } + + //! Sets whether the edit box is a password box. Setting this to true will + /** disable MultiLine, WordWrap and the ability to copy with ctrl+c or ctrl+x + \param passwordBox: true to enable password, false to disable + \param passwordChar: the character that is displayed instead of letters */ + virtual void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*'); + + //! Returns true if the edit box is currently a password box. + virtual bool isPasswordBox() const { return m_passwordbox; } + + //! Sets text justification + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical); + + //! Sets the new caption of this element. + virtual void setText(const wchar_t *text); + + //! Sets the maximum amount of characters which may be entered in the box. + //! \param max: Maximum amount of characters. If 0, the character amount is + //! infinity. + virtual void setMax(u32 max); + + //! Returns maximum amount of characters, previously set by setMax(); + virtual u32 getMax() const { return m_max; } + + //! Gets the size area of the text in the edit box + //! \return Returns the size in pixels of the text + virtual core::dimension2du getTextDimension(); + + //! set true if this EditBox is writable + virtual void setWritable(bool can_write_text); + + //! called if an event happened. + virtual bool OnEvent(const SEvent &event); + + virtual bool acceptsIME() { return isEnabled() && m_writable; }; + +protected: + virtual void breakText() = 0; + + //! sets the area of the given line + virtual void setTextRect(s32 line) = 0; + + //! set text markers + void setTextMarkers(s32 begin, s32 end); + + //! send some gui event to parent + void sendGuiEvent(EGUI_EVENT_TYPE type); + + //! calculates the current scroll position + virtual void calculateScrollPos() = 0; + + virtual s32 getCursorPos(s32 x, s32 y) = 0; + + bool processKey(const SEvent &event); + virtual void inputString(const core::stringw &str); + virtual void inputChar(wchar_t c); + + //! returns the line number that the cursor is on + s32 getLineFromPos(s32 pos); + + //! update the vertical scrollBar (visibilty & position) + void updateVScrollBar(); + + gui::IGUIFont *m_override_font = nullptr; + + bool m_override_color_enabled = false; + bool m_word_wrap = false; + bool m_multiline = false; + bool m_autoscroll = true; + + bool m_border; + + bool m_passwordbox = false; + wchar_t m_passwordchar = L'*'; + + std::vector<core::stringw> m_broken_text; + std::vector<s32> m_broken_text_positions; + + EGUI_ALIGNMENT m_halign = EGUIA_UPPERLEFT; + EGUI_ALIGNMENT m_valign = EGUIA_CENTER; + + u32 m_blink_start_time = 0; + s32 m_cursor_pos = 0; + s32 m_hscroll_pos = 0; + s32 m_vscroll_pos = 0; // scroll position in characters + u32 m_max = 0; + + video::SColor m_override_color = video::SColor(101, 255, 255, 255); + + core::rect<s32> m_current_text_rect = core::rect<s32>(0, 0, 1, 1); + + bool m_writable; + + bool m_mouse_marking = false; + + s32 m_mark_begin = 0; + s32 m_mark_end = 0; + + gui::IGUIFont *m_last_break_font = nullptr; + IOSOperator *m_operator = nullptr; + + core::rect<s32> m_frame_rect; // temporary values + + u32 m_scrollbar_width = 0; + GUIScrollBar *m_vscrollbar = nullptr; + +private: + bool processMouse(const SEvent &event); + + bool onKeyUp(const SEvent &event, s32 &mark_begin, s32 &mark_end); + bool onKeyDown(const SEvent &event, s32 &mark_begin, s32 &mark_end); + void onKeyControlC(const SEvent &event); + bool onKeyControlX(const SEvent &event, s32 &mark_begin, s32 &mark_end); + bool onKeyControlV(const SEvent &event, s32 &mark_begin, s32 &mark_end); + bool onKeyBack(const SEvent &event, s32 &mark_begin, s32 &mark_end); + bool onKeyDelete(const SEvent &event, s32 &mark_begin, s32 &mark_end); +}; diff --git a/src/gui/guiEditBoxWithScrollbar.cpp b/src/gui/guiEditBoxWithScrollbar.cpp new file mode 100644 index 0000000..1b7f783 --- /dev/null +++ b/src/gui/guiEditBoxWithScrollbar.cpp @@ -0,0 +1,660 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// Modified by Mustapha T. +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "guiEditBoxWithScrollbar.h" + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIFont.h" +#include "IVideoDriver.h" +#include "rect.h" +#include "porting.h" +#include "Keycodes.h" + +/* +todo: +optional scrollbars [done] +ctrl+left/right to select word +double click/ctrl click: word select + drag to select whole words, triple click to select line +optional? dragging selected text +numerical +*/ + +//! constructor +GUIEditBoxWithScrollBar::GUIEditBoxWithScrollBar(const wchar_t* text, bool border, + IGUIEnvironment* environment, IGUIElement* parent, s32 id, + const core::rect<s32>& rectangle, bool writable, bool has_vscrollbar) + : GUIEditBox(environment, parent, id, rectangle, border, writable), + m_background(true), m_bg_color_used(false) +{ +#ifdef _DEBUG + setDebugName("GUIEditBoxWithScrollBar"); +#endif + + + Text = text; + + if (Environment) + m_operator = Environment->getOSOperator(); + + if (m_operator) + m_operator->grab(); + + // this element can be tabbed to + setTabStop(true); + setTabOrder(-1); + + if (has_vscrollbar) { + createVScrollBar(); + } + + calculateFrameRect(); + breakText(); + + calculateScrollPos(); + setWritable(writable); +} + +//! Sets whether to draw the background +void GUIEditBoxWithScrollBar::setDrawBackground(bool draw) +{ + m_background = draw; +} + + +void GUIEditBoxWithScrollBar::updateAbsolutePosition() +{ + core::rect<s32> old_absolute_rect(AbsoluteRect); + IGUIElement::updateAbsolutePosition(); + if (old_absolute_rect != AbsoluteRect) { + calculateFrameRect(); + breakText(); + calculateScrollPos(); + } +} + + +//! draws the element and its children +void GUIEditBoxWithScrollBar::draw() +{ + if (!IsVisible) + return; + + const bool focus = Environment->hasFocus(this); + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + video::SColor default_bg_color; + video::SColor bg_color; + + default_bg_color = m_writable ? skin->getColor(EGDC_WINDOW) : video::SColor(0); + bg_color = m_bg_color_used ? m_bg_color : default_bg_color; + + if (!m_border && m_background) { + skin->draw2DRectangle(this, bg_color, AbsoluteRect, &AbsoluteClippingRect); + } + + // draw the border + + if (m_border) { + + if (m_writable) { + skin->draw3DSunkenPane(this, bg_color, false, m_background, + AbsoluteRect, &AbsoluteClippingRect); + } + + calculateFrameRect(); + } + + core::rect<s32> local_clip_rect = m_frame_rect; + local_clip_rect.clipAgainst(AbsoluteClippingRect); + + // draw the text + + IGUIFont* font = getActiveFont(); + + s32 cursor_line = 0; + s32 charcursorpos = 0; + + if (font) { + if (m_last_break_font != font) { + breakText(); + } + + // calculate cursor pos + + core::stringw *txt_line = &Text; + s32 start_pos = 0; + + core::stringw s, s2; + + // get mark position + const bool ml = (!m_passwordbox && (m_word_wrap || m_multiline)); + const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end; + const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin; + const s32 hline_start = ml ? getLineFromPos(realmbgn) : 0; + const s32 hline_count = ml ? getLineFromPos(realmend) - hline_start + 1 : 1; + const s32 line_count = ml ? m_broken_text.size() : 1; + + // Save the override color information. + // Then, alter it if the edit box is disabled. + const bool prevOver = m_override_color_enabled; + const video::SColor prevColor = m_override_color; + + if (Text.size()) { + if (!isEnabled() && !m_override_color_enabled) { + m_override_color_enabled = true; + m_override_color = skin->getColor(EGDC_GRAY_TEXT); + } + + for (s32 i = 0; i < line_count; ++i) { + setTextRect(i); + + // clipping test - don't draw anything outside the visible area + core::rect<s32> c = local_clip_rect; + c.clipAgainst(m_current_text_rect); + if (!c.isValid()) + continue; + + // get current line + if (m_passwordbox) { + if (m_broken_text.size() != 1) { + m_broken_text.clear(); + m_broken_text.emplace_back(); + } + if (m_broken_text[0].size() != Text.size()){ + m_broken_text[0] = Text; + for (u32 q = 0; q < Text.size(); ++q) + { + m_broken_text[0][q] = m_passwordchar; + } + } + txt_line = &m_broken_text[0]; + start_pos = 0; + } else { + txt_line = ml ? &m_broken_text[i] : &Text; + start_pos = ml ? m_broken_text_positions[i] : 0; + } + + + // draw normal text + font->draw(txt_line->c_str(), m_current_text_rect, + m_override_color_enabled ? m_override_color : skin->getColor(EGDC_BUTTON_TEXT), + false, true, &local_clip_rect); + + // draw mark and marked text + if (focus && m_mark_begin != m_mark_end && i >= hline_start && i < hline_start + hline_count) { + + s32 mbegin = 0, mend = 0; + s32 lineStartPos = 0, lineEndPos = txt_line->size(); + + if (i == hline_start) { + // highlight start is on this line + s = txt_line->subString(0, realmbgn - start_pos); + mbegin = font->getDimension(s.c_str()).Width; + + // deal with kerning + mbegin += font->getKerningWidth( + &((*txt_line)[realmbgn - start_pos]), + realmbgn - start_pos > 0 ? &((*txt_line)[realmbgn - start_pos - 1]) : 0); + + lineStartPos = realmbgn - start_pos; + } + if (i == hline_start + hline_count - 1) { + // highlight end is on this line + s2 = txt_line->subString(0, realmend - start_pos); + mend = font->getDimension(s2.c_str()).Width; + lineEndPos = (s32)s2.size(); + } else { + mend = font->getDimension(txt_line->c_str()).Width; + } + + + m_current_text_rect.UpperLeftCorner.X += mbegin; + m_current_text_rect.LowerRightCorner.X = m_current_text_rect.UpperLeftCorner.X + mend - mbegin; + + + // draw mark + skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), m_current_text_rect, &local_clip_rect); + + // draw marked text + s = txt_line->subString(lineStartPos, lineEndPos - lineStartPos); + + if (s.size()) + font->draw(s.c_str(), m_current_text_rect, + m_override_color_enabled ? m_override_color : skin->getColor(EGDC_HIGH_LIGHT_TEXT), + false, true, &local_clip_rect); + + } + } + + // Return the override color information to its previous settings. + m_override_color_enabled = prevOver; + m_override_color = prevColor; + } + + // draw cursor + if (IsEnabled && m_writable) { + if (m_word_wrap || m_multiline) { + cursor_line = getLineFromPos(m_cursor_pos); + txt_line = &m_broken_text[cursor_line]; + start_pos = m_broken_text_positions[cursor_line]; + } + s = txt_line->subString(0, m_cursor_pos - start_pos); + charcursorpos = font->getDimension(s.c_str()).Width + + font->getKerningWidth(L"_", m_cursor_pos - start_pos > 0 ? &((*txt_line)[m_cursor_pos - start_pos - 1]) : 0); + + if (focus && (porting::getTimeMs() - m_blink_start_time) % 700 < 350) { + setTextRect(cursor_line); + m_current_text_rect.UpperLeftCorner.X += charcursorpos; + + font->draw(L"_", m_current_text_rect, + m_override_color_enabled ? m_override_color : skin->getColor(EGDC_BUTTON_TEXT), + false, true, &local_clip_rect); + } + } + } + + // draw children + IGUIElement::draw(); +} + + +s32 GUIEditBoxWithScrollBar::getCursorPos(s32 x, s32 y) +{ + IGUIFont* font = getActiveFont(); + + const u32 line_count = (m_word_wrap || m_multiline) ? m_broken_text.size() : 1; + + core::stringw *txt_line = 0; + s32 start_pos = 0; + x += 3; + + for (u32 i = 0; i < line_count; ++i) { + setTextRect(i); + if (i == 0 && y < m_current_text_rect.UpperLeftCorner.Y) + y = m_current_text_rect.UpperLeftCorner.Y; + if (i == line_count - 1 && y > m_current_text_rect.LowerRightCorner.Y) + y = m_current_text_rect.LowerRightCorner.Y; + + // is it inside this region? + if (y >= m_current_text_rect.UpperLeftCorner.Y && y <= m_current_text_rect.LowerRightCorner.Y) { + // we've found the clicked line + txt_line = (m_word_wrap || m_multiline) ? &m_broken_text[i] : &Text; + start_pos = (m_word_wrap || m_multiline) ? m_broken_text_positions[i] : 0; + break; + } + } + + if (x < m_current_text_rect.UpperLeftCorner.X) + x = m_current_text_rect.UpperLeftCorner.X; + + if (!txt_line) + return 0; + + s32 idx = font->getCharacterFromPos(txt_line->c_str(), x - m_current_text_rect.UpperLeftCorner.X); + + // click was on or left of the line + if (idx != -1) + return idx + start_pos; + + // click was off the right edge of the line, go to end. + return txt_line->size() + start_pos; +} + + +//! Breaks the single text line. +void GUIEditBoxWithScrollBar::breakText() +{ + if ((!m_word_wrap && !m_multiline)) + return; + + m_broken_text.clear(); // need to reallocate :/ + m_broken_text_positions.clear(); + + IGUIFont* font = getActiveFont(); + if (!font) + return; + + m_last_break_font = font; + + core::stringw line; + core::stringw word; + core::stringw whitespace; + s32 last_line_start = 0; + s32 size = Text.size(); + s32 length = 0; + s32 el_width = RelativeRect.getWidth() - m_scrollbar_width - 10; + wchar_t c; + + for (s32 i = 0; i < size; ++i) { + c = Text[i]; + bool line_break = false; + + if (c == L'\r') { // Mac or Windows breaks + + line_break = true; + c = 0; + if (Text[i + 1] == L'\n') { // Windows breaks + // TODO: I (Michael) think that we shouldn't change the text given by the user for whatever reason. + // Instead rework the cursor positioning to be able to handle this (but not in stable release + // branch as users might already expect this behavior). + Text.erase(i + 1); + --size; + if (m_cursor_pos > i) + --m_cursor_pos; + } + } else if (c == L'\n') { // Unix breaks + line_break = true; + c = 0; + } + + // don't break if we're not a multi-line edit box + if (!m_multiline) + line_break = false; + + if (c == L' ' || c == 0 || i == (size - 1)) { + // here comes the next whitespace, look if + // we can break the last word to the next line + // We also break whitespace, otherwise cursor would vanish beside the right border. + s32 whitelgth = font->getDimension(whitespace.c_str()).Width; + s32 worldlgth = font->getDimension(word.c_str()).Width; + + if (m_word_wrap && length + worldlgth + whitelgth > el_width && line.size() > 0) { + // break to next line + length = worldlgth; + m_broken_text.push_back(line); + m_broken_text_positions.push_back(last_line_start); + last_line_start = i - (s32)word.size(); + line = word; + } else { + // add word to line + line += whitespace; + line += word; + length += whitelgth + worldlgth; + } + + word = L""; + whitespace = L""; + + + if (c) + whitespace += c; + + // compute line break + if (line_break) { + line += whitespace; + line += word; + m_broken_text.push_back(line); + m_broken_text_positions.push_back(last_line_start); + last_line_start = i + 1; + line = L""; + word = L""; + whitespace = L""; + length = 0; + } + } else { + // yippee this is a word.. + word += c; + } + } + + line += whitespace; + line += word; + m_broken_text.push_back(line); + m_broken_text_positions.push_back(last_line_start); +} + +// TODO: that function does interpret VAlign according to line-index (indexed +// line is placed on top-center-bottom) but HAlign according to line-width +// (pixels) and not by row. +// Intuitively I suppose HAlign handling is better as VScrollPos should handle +// the line-scrolling. +// But please no one change this without also rewriting (and this time +// testing!!!) autoscrolling (I noticed this when fixing the old autoscrolling). +void GUIEditBoxWithScrollBar::setTextRect(s32 line) +{ + if (line < 0) + return; + + IGUIFont* font = getActiveFont(); + if (!font) + return; + + core::dimension2du d; + + // get text dimension + const u32 line_count = (m_word_wrap || m_multiline) ? m_broken_text.size() : 1; + if (m_word_wrap || m_multiline) { + d = font->getDimension(m_broken_text[line].c_str()); + } else { + d = font->getDimension(Text.c_str()); + d.Height = AbsoluteRect.getHeight(); + } + d.Height += font->getKerningHeight(); + + // justification + switch (m_halign) { + case EGUIA_CENTER: + // align to h centre + m_current_text_rect.UpperLeftCorner.X = (m_frame_rect.getWidth() / 2) - (d.Width / 2); + m_current_text_rect.LowerRightCorner.X = (m_frame_rect.getWidth() / 2) + (d.Width / 2); + break; + case EGUIA_LOWERRIGHT: + // align to right edge + m_current_text_rect.UpperLeftCorner.X = m_frame_rect.getWidth() - d.Width; + m_current_text_rect.LowerRightCorner.X = m_frame_rect.getWidth(); + break; + default: + // align to left edge + m_current_text_rect.UpperLeftCorner.X = 0; + m_current_text_rect.LowerRightCorner.X = d.Width; + + } + + switch (m_valign) { + case EGUIA_CENTER: + // align to v centre + m_current_text_rect.UpperLeftCorner.Y = + (m_frame_rect.getHeight() / 2) - (line_count*d.Height) / 2 + d.Height*line; + break; + case EGUIA_LOWERRIGHT: + // align to bottom edge + m_current_text_rect.UpperLeftCorner.Y = + m_frame_rect.getHeight() - line_count*d.Height + d.Height*line; + break; + default: + // align to top edge + m_current_text_rect.UpperLeftCorner.Y = d.Height*line; + break; + } + + m_current_text_rect.UpperLeftCorner.X -= m_hscroll_pos; + m_current_text_rect.LowerRightCorner.X -= m_hscroll_pos; + m_current_text_rect.UpperLeftCorner.Y -= m_vscroll_pos; + m_current_text_rect.LowerRightCorner.Y = m_current_text_rect.UpperLeftCorner.Y + d.Height; + + m_current_text_rect += m_frame_rect.UpperLeftCorner; +} + +// calculate autoscroll +void GUIEditBoxWithScrollBar::calculateScrollPos() +{ + if (!m_autoscroll) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + IGUIFont* font = m_override_font ? m_override_font : skin->getFont(); + if (!font) + return; + + s32 curs_line = getLineFromPos(m_cursor_pos); + if (curs_line < 0) + return; + setTextRect(curs_line); + const bool has_broken_text = m_multiline || m_word_wrap; + + // Check horizonal scrolling + // NOTE: Calculations different to vertical scrolling because setTextRect interprets VAlign relative to line but HAlign not relative to row + { + // get cursor position + IGUIFont* font = getActiveFont(); + if (!font) + return; + + // get cursor area + irr::u32 cursor_width = font->getDimension(L"_").Width; + core::stringw *txt_line = has_broken_text ? &m_broken_text[curs_line] : &Text; + s32 cpos = has_broken_text ? m_cursor_pos - m_broken_text_positions[curs_line] : m_cursor_pos; // column + s32 cstart = font->getDimension(txt_line->subString(0, cpos).c_str()).Width; // pixels from text-start + s32 cend = cstart + cursor_width; + s32 txt_width = font->getDimension(txt_line->c_str()).Width; + + if (txt_width < m_frame_rect.getWidth()) { + // TODO: Needs a clean left and right gap removal depending on HAlign, similar to vertical scrolling tests for top/bottom. + // This check just fixes the case where it was most noticable (text smaller than clipping area). + + m_hscroll_pos = 0; + setTextRect(curs_line); + } + + if (m_current_text_rect.UpperLeftCorner.X + cstart < m_frame_rect.UpperLeftCorner.X) { + // cursor to the left of the clipping area + m_hscroll_pos -= m_frame_rect.UpperLeftCorner.X - (m_current_text_rect.UpperLeftCorner.X + cstart); + setTextRect(curs_line); + + // TODO: should show more characters to the left when we're scrolling left + // and the cursor reaches the border. + } else if (m_current_text_rect.UpperLeftCorner.X + cend > m_frame_rect.LowerRightCorner.X) { + // cursor to the right of the clipping area + m_hscroll_pos += (m_current_text_rect.UpperLeftCorner.X + cend) - m_frame_rect.LowerRightCorner.X; + setTextRect(curs_line); + } + } + + // calculate vertical scrolling + if (has_broken_text) { + irr::u32 line_height = font->getDimension(L"A").Height + font->getKerningHeight(); + // only up to 1 line fits? + if (line_height >= (irr::u32)m_frame_rect.getHeight()) { + m_vscroll_pos = 0; + setTextRect(curs_line); + s32 unscrolledPos = m_current_text_rect.UpperLeftCorner.Y; + s32 pivot = m_frame_rect.UpperLeftCorner.Y; + switch (m_valign) { + case EGUIA_CENTER: + pivot += m_frame_rect.getHeight() / 2; + unscrolledPos += line_height / 2; + break; + case EGUIA_LOWERRIGHT: + pivot += m_frame_rect.getHeight(); + unscrolledPos += line_height; + break; + default: + break; + } + m_vscroll_pos = unscrolledPos - pivot; + setTextRect(curs_line); + } else { + // First 2 checks are necessary when people delete lines + setTextRect(0); + if (m_current_text_rect.UpperLeftCorner.Y > m_frame_rect.UpperLeftCorner.Y && m_valign != EGUIA_LOWERRIGHT) { + // first line is leaving a gap on top + m_vscroll_pos = 0; + } else if (m_valign != EGUIA_UPPERLEFT) { + u32 lastLine = m_broken_text_positions.empty() ? 0 : m_broken_text_positions.size() - 1; + setTextRect(lastLine); + if (m_current_text_rect.LowerRightCorner.Y < m_frame_rect.LowerRightCorner.Y) + { + // last line is leaving a gap on bottom + m_vscroll_pos -= m_frame_rect.LowerRightCorner.Y - m_current_text_rect.LowerRightCorner.Y; + } + } + + setTextRect(curs_line); + if (m_current_text_rect.UpperLeftCorner.Y < m_frame_rect.UpperLeftCorner.Y) { + // text above valid area + m_vscroll_pos -= m_frame_rect.UpperLeftCorner.Y - m_current_text_rect.UpperLeftCorner.Y; + setTextRect(curs_line); + } else if (m_current_text_rect.LowerRightCorner.Y > m_frame_rect.LowerRightCorner.Y){ + // text below valid area + m_vscroll_pos += m_current_text_rect.LowerRightCorner.Y - m_frame_rect.LowerRightCorner.Y; + setTextRect(curs_line); + } + } + } + + if (m_vscrollbar) { + m_vscrollbar->setPos(m_vscroll_pos); + } +} + +void GUIEditBoxWithScrollBar::calculateFrameRect() +{ + m_frame_rect = AbsoluteRect; + + + IGUISkin *skin = 0; + if (Environment) + skin = Environment->getSkin(); + if (m_border && skin) { + m_frame_rect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X) + 1; + m_frame_rect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y) + 1; + m_frame_rect.LowerRightCorner.X -= skin->getSize(EGDS_TEXT_DISTANCE_X) + 1; + m_frame_rect.LowerRightCorner.Y -= skin->getSize(EGDS_TEXT_DISTANCE_Y) + 1; + } + + updateVScrollBar(); +} + +//! create a vertical scroll bar +void GUIEditBoxWithScrollBar::createVScrollBar() +{ + IGUISkin *skin = 0; + if (Environment) + skin = Environment->getSkin(); + + s32 fontHeight = 1; + + if (m_override_font) { + fontHeight = m_override_font->getDimension(L"Ay").Height; + } else { + IGUIFont *font; + if (skin && (font = skin->getFont())) { + fontHeight = font->getDimension(L"Ay").Height; + } + } + + m_scrollbar_width = skin ? skin->getSize(gui::EGDS_SCROLLBAR_SIZE) : 16; + + irr::core::rect<s32> scrollbarrect = m_frame_rect; + scrollbarrect.UpperLeftCorner.X += m_frame_rect.getWidth() - m_scrollbar_width; + m_vscrollbar = new GUIScrollBar(Environment, getParent(), -1, + scrollbarrect, false, true); + + m_vscrollbar->setVisible(false); + m_vscrollbar->setSmallStep(3 * fontHeight); + m_vscrollbar->setLargeStep(10 * fontHeight); +} + + + +//! Change the background color +void GUIEditBoxWithScrollBar::setBackgroundColor(const video::SColor &bg_color) +{ + m_bg_color = bg_color; + m_bg_color_used = true; +} + +bool GUIEditBoxWithScrollBar::isDrawBackgroundEnabled() const { return false; } +bool GUIEditBoxWithScrollBar::isDrawBorderEnabled() const { return false; } +void GUIEditBoxWithScrollBar::setCursorChar(const wchar_t cursorChar) { } +wchar_t GUIEditBoxWithScrollBar::getCursorChar() const { return '|'; } +void GUIEditBoxWithScrollBar::setCursorBlinkTime(irr::u32 timeMs) { } +irr::u32 GUIEditBoxWithScrollBar::getCursorBlinkTime() const { return 500; } diff --git a/src/gui/guiEditBoxWithScrollbar.h b/src/gui/guiEditBoxWithScrollbar.h new file mode 100644 index 0000000..cea482f --- /dev/null +++ b/src/gui/guiEditBoxWithScrollbar.h @@ -0,0 +1,63 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt, Modified by Mustapha Tachouct +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef GUIEDITBOXWITHSCROLLBAR_HEADER +#define GUIEDITBOXWITHSCROLLBAR_HEADER + +#include "guiEditBox.h" + +class GUIEditBoxWithScrollBar : public GUIEditBox +{ +public: + + //! constructor + GUIEditBoxWithScrollBar(const wchar_t* text, bool border, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, const core::rect<s32>& rectangle, + bool writable = true, bool has_vscrollbar = true); + + //! destructor + virtual ~GUIEditBoxWithScrollBar() {} + + //! Sets whether to draw the background + virtual void setDrawBackground(bool draw); + + //! draws the element and its children + virtual void draw(); + + //! Updates the absolute position, splits text if required + virtual void updateAbsolutePosition(); + + //! Change the background color + virtual void setBackgroundColor(const video::SColor &bg_color); + + virtual bool isDrawBackgroundEnabled() const; + virtual bool isDrawBorderEnabled() const; + virtual void setCursorChar(const wchar_t cursorChar); + virtual wchar_t getCursorChar() const; + virtual void setCursorBlinkTime(irr::u32 timeMs); + virtual irr::u32 getCursorBlinkTime() const; + +protected: + //! Breaks the single text line. + virtual void breakText(); + //! sets the area of the given line + virtual void setTextRect(s32 line); + //! calculates the current scroll position + void calculateScrollPos(); + //! calculated the FrameRect + void calculateFrameRect(); + //! create a Vertical ScrollBar + void createVScrollBar(); + + s32 getCursorPos(s32 x, s32 y); + + bool m_background; + + bool m_bg_color_used; + video::SColor m_bg_color; +}; + + +#endif // GUIEDITBOXWITHSCROLLBAR_HEADER + diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp new file mode 100644 index 0000000..01f3f8f --- /dev/null +++ b/src/gui/guiEngine.cpp @@ -0,0 +1,635 @@ +/* +Minetest +Copyright (C) 2013 sapier + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiEngine.h" + +#include <IGUIStaticText.h> +#include <ICameraSceneNode.h> +#include "client/renderingengine.h" +#include "scripting_mainmenu.h" +#include "util/numeric.h" +#include "config.h" +#include "version.h" +#include "porting.h" +#include "filesys.h" +#include "settings.h" +#include "guiMainMenu.h" +#include "sound.h" +#include "client/sound_openal.h" +#include "client/clouds.h" +#include "httpfetch.h" +#include "log.h" +#include "client/fontengine.h" +#include "client/guiscalingfilter.h" +#include "irrlicht_changes/static_text.h" + +#if ENABLE_GLES +#include "client/tile.h" +#endif + + +/******************************************************************************/ +void TextDestGuiEngine::gotText(const StringMap &fields) +{ + m_engine->getScriptIface()->handleMainMenuButtons(fields); +} + +/******************************************************************************/ +void TextDestGuiEngine::gotText(const std::wstring &text) +{ + m_engine->getScriptIface()->handleMainMenuEvent(wide_to_utf8(text)); +} + +/******************************************************************************/ +MenuTextureSource::~MenuTextureSource() +{ + for (const std::string &texture_to_delete : m_to_delete) { + const char *tname = texture_to_delete.c_str(); + video::ITexture *texture = m_driver->getTexture(tname); + m_driver->removeTexture(texture); + } +} + +/******************************************************************************/ +video::ITexture *MenuTextureSource::getTexture(const std::string &name, u32 *id) +{ + if (id) + *id = 0; + + if (name.empty()) + return NULL; + +#if ENABLE_GLES + video::ITexture *retval = m_driver->findTexture(name.c_str()); + if (retval) + return retval; + + video::IImage *image = m_driver->createImageFromFile(name.c_str()); + if (!image) + return NULL; + + image = Align2Npot2(image, m_driver); + retval = m_driver->addTexture(name.c_str(), image); + m_to_delete.insert(name); + image->drop(); + return retval; +#else + return m_driver->getTexture(name.c_str()); +#endif +} + +/******************************************************************************/ +/** MenuMusicFetcher */ +/******************************************************************************/ +void MenuMusicFetcher::fetchSounds(const std::string &name, + std::set<std::string> &dst_paths, + std::set<std::string> &dst_datas) +{ + if(m_fetched.count(name)) + return; + m_fetched.insert(name); + std::vector<fs::DirListNode> list; + // Reusable local function + auto add_paths = [&dst_paths](const std::string name, const std::string base = "") { + dst_paths.insert(base + name + ".ogg"); + for (int i = 0; i < 10; i++) + dst_paths.insert(base + name + "." + itos(i) + ".ogg"); + }; + // Allow full paths + if (name.find(DIR_DELIM_CHAR) != std::string::npos) { + add_paths(name); + } else { + std::string share_prefix = porting::path_share + DIR_DELIM; + add_paths(name, share_prefix + "sounds" + DIR_DELIM); + std::string user_prefix = porting::path_user + DIR_DELIM; + add_paths(name, user_prefix + "sounds" + DIR_DELIM); + } +} + +/******************************************************************************/ +/** GUIEngine */ +/******************************************************************************/ +GUIEngine::GUIEngine(JoystickController *joystick, + gui::IGUIElement *parent, + RenderingEngine *rendering_engine, + IMenuManager *menumgr, + MainMenuData *data, + bool &kill) : + m_rendering_engine(rendering_engine), + m_parent(parent), + m_menumanager(menumgr), + m_smgr(rendering_engine->get_scene_manager()), + m_data(data), + m_kill(kill) +{ + //initialize texture pointers + for (image_definition &texture : m_textures) { + texture.texture = NULL; + } + // is deleted by guiformspec! + m_buttonhandler = new TextDestGuiEngine(this); + + //create texture source + m_texture_source = new MenuTextureSource(rendering_engine->get_video_driver()); + + //create soundmanager + MenuMusicFetcher soundfetcher; +#if USE_SOUND + if (g_settings->getBool("enable_sound") && g_sound_manager_singleton.get()) + m_sound_manager = createOpenALSoundManager(g_sound_manager_singleton.get(), &soundfetcher); +#endif + if (!m_sound_manager) + m_sound_manager = &dummySoundManager; + + //create topleft header + m_toplefttext = L""; + + core::rect<s32> rect(0, 0, g_fontengine->getTextWidth(m_toplefttext.c_str()), + g_fontengine->getTextHeight()); + rect += v2s32(4, 0); + + m_irr_toplefttext = gui::StaticText::add(rendering_engine->get_gui_env(), + m_toplefttext, rect, false, true, 0, -1); + + //create formspecsource + m_formspecgui = new FormspecFormSource(""); + + /* Create menu */ + m_menu = new GUIFormSpecMenu(joystick, + m_parent, + -1, + m_menumanager, + NULL /* &client */, + m_rendering_engine->get_gui_env(), + m_texture_source, + m_sound_manager, + m_formspecgui, + m_buttonhandler, + "", + false); + + m_menu->allowClose(false); + m_menu->lockSize(true,v2u32(800,600)); + + // Initialize scripting + + infostream << "GUIEngine: Initializing Lua" << std::endl; + + m_script = new MainMenuScripting(this); + + try { + m_script->setMainMenuData(&m_data->script_data); + m_data->script_data.errormessage = ""; + + if (!loadMainMenuScript()) { + errorstream << "No future without main menu!" << std::endl; + abort(); + } + + run(); + } catch (LuaError &e) { + errorstream << "Main menu error: " << e.what() << std::endl; + m_data->script_data.errormessage = e.what(); + } + + m_menu->quitMenu(); + m_menu->drop(); + m_menu = NULL; +} + +/******************************************************************************/ +bool GUIEngine::loadMainMenuScript() +{ + // Set main menu path (for core.get_mainmenu_path()) + m_scriptdir = g_settings->get("main_menu_path"); + if (m_scriptdir.empty()) { + m_scriptdir = porting::path_share + DIR_DELIM + "builtin" + DIR_DELIM + "mainmenu"; + } + + // Load builtin (which will load the main menu script) + std::string script = porting::path_share + DIR_DELIM "builtin" + DIR_DELIM "init.lua"; + try { + m_script->loadScript(script); + // Menu script loaded + return true; + } catch (const ModError &e) { + errorstream << "GUIEngine: execution of menu script failed: " + << e.what() << std::endl; + } + + return false; +} + +/******************************************************************************/ +void GUIEngine::run() +{ + // Always create clouds because they may or may not be + // needed based on the game selected + video::IVideoDriver *driver = m_rendering_engine->get_video_driver(); + + cloudInit(); + + unsigned int text_height = g_fontengine->getTextHeight(); + + irr::core::dimension2d<u32> previous_screen_size(g_settings->getU16("screen_w"), + g_settings->getU16("screen_h")); + + static const video::SColor sky_color(255, 140, 186, 250); + + // Reset fog color + { + video::SColor fog_color; + video::E_FOG_TYPE fog_type = video::EFT_FOG_LINEAR; + f32 fog_start = 0; + f32 fog_end = 0; + f32 fog_density = 0; + bool fog_pixelfog = false; + bool fog_rangefog = false; + driver->getFog(fog_color, fog_type, fog_start, fog_end, fog_density, + fog_pixelfog, fog_rangefog); + + driver->setFog(sky_color, fog_type, fog_start, fog_end, fog_density, + fog_pixelfog, fog_rangefog); + } + + while (m_rendering_engine->run() && (!m_startgame) && (!m_kill)) { + + const irr::core::dimension2d<u32> ¤t_screen_size = + m_rendering_engine->get_video_driver()->getScreenSize(); + // Verify if window size has changed and save it if it's the case + // Ensure evaluating settings->getBool after verifying screensize + // First condition is cheaper + if (previous_screen_size != current_screen_size && + current_screen_size != irr::core::dimension2d<u32>(0,0) && + g_settings->getBool("autosave_screensize")) { + g_settings->setU16("screen_w", current_screen_size.Width); + g_settings->setU16("screen_h", current_screen_size.Height); + previous_screen_size = current_screen_size; + } + + //check if we need to update the "upper left corner"-text + if (text_height != g_fontengine->getTextHeight()) { + updateTopLeftTextSize(); + text_height = g_fontengine->getTextHeight(); + } + + driver->beginScene(true, true, sky_color); + + if (m_clouds_enabled) + { + cloudPreProcess(); + drawOverlay(driver); + } + else + drawBackground(driver); + + drawHeader(driver); + drawFooter(driver); + + m_rendering_engine->get_gui_env()->drawAll(); + + driver->endScene(); + + IrrlichtDevice *device = m_rendering_engine->get_raw_device(); + u32 frametime_min = 1000 / (device->isWindowFocused() + ? g_settings->getFloat("fps_max") + : g_settings->getFloat("fps_max_unfocused")); + if (m_clouds_enabled) + cloudPostProcess(frametime_min, device); + else + sleep_ms(frametime_min); + + m_script->step(); + +#ifdef __ANDROID__ + m_menu->getAndroidUIInput(); +#endif + } +} + +/******************************************************************************/ +GUIEngine::~GUIEngine() +{ + if (m_sound_manager != &dummySoundManager){ + delete m_sound_manager; + m_sound_manager = NULL; + } + + infostream<<"GUIEngine: Deinitializing scripting"<<std::endl; + delete m_script; + + m_irr_toplefttext->setText(L""); + + //clean up texture pointers + for (image_definition &texture : m_textures) { + if (texture.texture) + m_rendering_engine->get_video_driver()->removeTexture(texture.texture); + } + + delete m_texture_source; + + if (m_cloud.clouds) + m_cloud.clouds->drop(); +} + +/******************************************************************************/ +void GUIEngine::cloudInit() +{ + m_cloud.clouds = new Clouds(m_smgr, -1, rand()); + m_cloud.clouds->setHeight(100.0f); + m_cloud.clouds->update(v3f(0, 0, 0), video::SColor(255,240,240,255)); + + m_cloud.camera = m_smgr->addCameraSceneNode(0, + v3f(0,0,0), v3f(0, 60, 100)); + m_cloud.camera->setFarValue(10000); + + m_cloud.lasttime = m_rendering_engine->get_timer_time(); +} + +/******************************************************************************/ +void GUIEngine::cloudPreProcess() +{ + u32 time = m_rendering_engine->get_timer_time(); + + if(time > m_cloud.lasttime) + m_cloud.dtime = (time - m_cloud.lasttime) / 1000.0; + else + m_cloud.dtime = 0; + + m_cloud.lasttime = time; + + m_cloud.clouds->step(m_cloud.dtime*3); + m_cloud.clouds->render(); + m_smgr->drawAll(); +} + +/******************************************************************************/ +void GUIEngine::cloudPostProcess(u32 frametime_min, IrrlichtDevice *device) +{ + // Time of frame without fps limit + u32 busytime_u32; + + // not using getRealTime is necessary for wine + u32 time = m_rendering_engine->get_timer_time(); + if(time > m_cloud.lasttime) + busytime_u32 = time - m_cloud.lasttime; + else + busytime_u32 = 0; + + // FPS limit + if (busytime_u32 < frametime_min) { + u32 sleeptime = frametime_min - busytime_u32; + device->sleep(sleeptime); + } +} + +/******************************************************************************/ +void GUIEngine::setFormspecPrepend(const std::string &fs) +{ + if (m_menu) { + m_menu->setFormspecPrepend(fs); + } +} + + +/******************************************************************************/ +void GUIEngine::drawBackground(video::IVideoDriver *driver) +{ + v2u32 screensize = driver->getScreenSize(); + + video::ITexture* texture = m_textures[TEX_LAYER_BACKGROUND].texture; + + /* If no texture, draw background of solid color */ + if(!texture){ + video::SColor color(255,80,58,37); + core::rect<s32> rect(0, 0, screensize.X, screensize.Y); + driver->draw2DRectangle(color, rect, NULL); + return; + } + + v2u32 sourcesize = texture->getOriginalSize(); + + if (m_textures[TEX_LAYER_BACKGROUND].tile) + { + v2u32 tilesize( + MYMAX(sourcesize.X,m_textures[TEX_LAYER_BACKGROUND].minsize), + MYMAX(sourcesize.Y,m_textures[TEX_LAYER_BACKGROUND].minsize)); + for (unsigned int x = 0; x < screensize.X; x += tilesize.X ) + { + for (unsigned int y = 0; y < screensize.Y; y += tilesize.Y ) + { + draw2DImageFilterScaled(driver, texture, + core::rect<s32>(x, y, x+tilesize.X, y+tilesize.Y), + core::rect<s32>(0, 0, sourcesize.X, sourcesize.Y), + NULL, NULL, true); + } + } + return; + } + + // Chop background image to the smaller screen dimension + v2u32 bg_size = screensize; + v2f32 scale( + (f32) bg_size.X / sourcesize.X, + (f32) bg_size.Y / sourcesize.Y); + if (scale.X < scale.Y) + bg_size.X = (int) (scale.Y * sourcesize.X); + else + bg_size.Y = (int) (scale.X * sourcesize.Y); + v2s32 offset = v2s32( + (s32) screensize.X - (s32) bg_size.X, + (s32) screensize.Y - (s32) bg_size.Y + ) / 2; + /* Draw background texture */ + draw2DImageFilterScaled(driver, texture, + core::rect<s32>(offset.X, offset.Y, bg_size.X + offset.X, bg_size.Y + offset.Y), + core::rect<s32>(0, 0, sourcesize.X, sourcesize.Y), + NULL, NULL, true); +} + +/******************************************************************************/ +void GUIEngine::drawOverlay(video::IVideoDriver *driver) +{ + v2u32 screensize = driver->getScreenSize(); + + video::ITexture* texture = m_textures[TEX_LAYER_OVERLAY].texture; + + /* If no texture, draw nothing */ + if(!texture) + return; + + /* Draw background texture */ + v2u32 sourcesize = texture->getOriginalSize(); + draw2DImageFilterScaled(driver, texture, + core::rect<s32>(0, 0, screensize.X, screensize.Y), + core::rect<s32>(0, 0, sourcesize.X, sourcesize.Y), + NULL, NULL, true); +} + +/******************************************************************************/ +void GUIEngine::drawHeader(video::IVideoDriver *driver) +{ + core::dimension2d<u32> screensize = driver->getScreenSize(); + + video::ITexture* texture = m_textures[TEX_LAYER_HEADER].texture; + + /* If no texture, draw nothing */ + if(!texture) + return; + + f32 mult = (((f32)screensize.Width / 2.0)) / + ((f32)texture->getOriginalSize().Width); + + v2s32 splashsize(((f32)texture->getOriginalSize().Width) * mult, + ((f32)texture->getOriginalSize().Height) * mult); + + // Don't draw the header if there isn't enough room + s32 free_space = (((s32)screensize.Height)-320)/2; + + if (free_space > splashsize.Y) { + core::rect<s32> splashrect(0, 0, splashsize.X, splashsize.Y); + splashrect += v2s32((screensize.Width/2)-(splashsize.X/2), + ((free_space/2)-splashsize.Y/2)+10); + + draw2DImageFilterScaled(driver, texture, splashrect, + core::rect<s32>(core::position2d<s32>(0,0), + core::dimension2di(texture->getOriginalSize())), + NULL, NULL, true); + } +} + +/******************************************************************************/ +void GUIEngine::drawFooter(video::IVideoDriver *driver) +{ + core::dimension2d<u32> screensize = driver->getScreenSize(); + + video::ITexture* texture = m_textures[TEX_LAYER_FOOTER].texture; + + /* If no texture, draw nothing */ + if(!texture) + return; + + f32 mult = (((f32)screensize.Width)) / + ((f32)texture->getOriginalSize().Width); + + v2s32 footersize(((f32)texture->getOriginalSize().Width) * mult, + ((f32)texture->getOriginalSize().Height) * mult); + + // Don't draw the footer if there isn't enough room + s32 free_space = (((s32)screensize.Height)-320)/2; + + if (free_space > footersize.Y) { + core::rect<s32> rect(0,0,footersize.X,footersize.Y); + rect += v2s32(screensize.Width/2,screensize.Height-footersize.Y); + rect -= v2s32(footersize.X/2, 0); + + draw2DImageFilterScaled(driver, texture, rect, + core::rect<s32>(core::position2d<s32>(0,0), + core::dimension2di(texture->getOriginalSize())), + NULL, NULL, true); + } +} + +/******************************************************************************/ +bool GUIEngine::setTexture(texture_layer layer, const std::string &texturepath, + bool tile_image, unsigned int minsize) +{ + video::IVideoDriver *driver = m_rendering_engine->get_video_driver(); + + if (m_textures[layer].texture) { + driver->removeTexture(m_textures[layer].texture); + m_textures[layer].texture = NULL; + } + + if (texturepath.empty() || !fs::PathExists(texturepath)) { + return false; + } + + m_textures[layer].texture = driver->getTexture(texturepath.c_str()); + m_textures[layer].tile = tile_image; + m_textures[layer].minsize = minsize; + + if (!m_textures[layer].texture) { + return false; + } + + return true; +} + +/******************************************************************************/ +bool GUIEngine::downloadFile(const std::string &url, const std::string &target) +{ +#if USE_CURL + std::ofstream target_file(target.c_str(), std::ios::out | std::ios::binary); + if (!target_file.good()) { + return false; + } + + HTTPFetchRequest fetch_request; + HTTPFetchResult fetch_result; + fetch_request.url = url; + fetch_request.caller = HTTPFETCH_SYNC; + fetch_request.timeout = g_settings->getS32("curl_file_download_timeout"); + httpfetch_sync(fetch_request, fetch_result); + + if (!fetch_result.succeeded) { + target_file.close(); + fs::DeleteSingleFileOrEmptyDirectory(target); + return false; + } + target_file << fetch_result.data; + + return true; +#else + return false; +#endif +} + +/******************************************************************************/ +void GUIEngine::setTopleftText(const std::string &text) +{ + m_toplefttext = translate_string(utf8_to_wide(text)); + + updateTopLeftTextSize(); +} + +/******************************************************************************/ +void GUIEngine::updateTopLeftTextSize() +{ + core::rect<s32> rect(0, 0, g_fontengine->getTextWidth(m_toplefttext.c_str()), + g_fontengine->getTextHeight()); + rect += v2s32(4, 0); + + m_irr_toplefttext->remove(); + m_irr_toplefttext = gui::StaticText::add(m_rendering_engine->get_gui_env(), + m_toplefttext, rect, false, true, 0, -1); +} + +/******************************************************************************/ +s32 GUIEngine::playSound(const SimpleSoundSpec &spec) +{ + s32 handle = m_sound_manager->playSound(spec); + return handle; +} + +/******************************************************************************/ +void GUIEngine::stopSound(s32 handle) +{ + m_sound_manager->stopSound(handle); +} diff --git a/src/gui/guiEngine.h b/src/gui/guiEngine.h new file mode 100644 index 0000000..2f182ca --- /dev/null +++ b/src/gui/guiEngine.h @@ -0,0 +1,304 @@ +/* +Minetest +Copyright (C) 2013 sapier + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +/******************************************************************************/ +/* Includes */ +/******************************************************************************/ +#include "irrlichttypes.h" +#include "guiFormSpecMenu.h" +#include "client/sound.h" +#include "client/tile.h" +#include "util/enriched_string.h" + +/******************************************************************************/ +/* Structs and macros */ +/******************************************************************************/ +/** texture layer ids */ +enum texture_layer { + TEX_LAYER_BACKGROUND = 0, + TEX_LAYER_OVERLAY, + TEX_LAYER_HEADER, + TEX_LAYER_FOOTER, + TEX_LAYER_MAX +}; + +struct image_definition { + video::ITexture *texture = nullptr; + bool tile; + unsigned int minsize; +}; + +/******************************************************************************/ +/* forward declarations */ +/******************************************************************************/ +class GUIEngine; +class RenderingEngine; +class MainMenuScripting; +class Clouds; +struct MainMenuData; + +/******************************************************************************/ +/* declarations */ +/******************************************************************************/ + +/** GUIEngine specific implementation of TextDest used within guiFormSpecMenu */ +class TextDestGuiEngine : public TextDest +{ +public: + /** + * default constructor + * @param engine the engine data is transmitted for further processing + */ + TextDestGuiEngine(GUIEngine* engine) : m_engine(engine) {}; + + /** + * receive fields transmitted by guiFormSpecMenu + * @param fields map containing formspec field elements currently active + */ + void gotText(const StringMap &fields); + + /** + * receive text/events transmitted by guiFormSpecMenu + * @param text textual representation of event + */ + void gotText(const std::wstring &text); + +private: + /** target to transmit data to */ + GUIEngine *m_engine = nullptr; +}; + +/** GUIEngine specific implementation of ISimpleTextureSource */ +class MenuTextureSource : public ISimpleTextureSource +{ +public: + /** + * default constructor + * @param driver the video driver to load textures from + */ + MenuTextureSource(video::IVideoDriver *driver) : m_driver(driver) {}; + + /** + * destructor, removes all loaded textures + */ + virtual ~MenuTextureSource(); + + /** + * get a texture, loading it if required + * @param name path to the texture + * @param id receives the texture ID, always 0 in this implementation + */ + video::ITexture *getTexture(const std::string &name, u32 *id = NULL); + +private: + /** driver to get textures from */ + video::IVideoDriver *m_driver = nullptr; + /** set of texture names to delete */ + std::set<std::string> m_to_delete; +}; + +/** GUIEngine specific implementation of OnDemandSoundFetcher */ +class MenuMusicFetcher: public OnDemandSoundFetcher +{ +public: + /** + * get sound file paths according to sound name + * @param name sound name + * @param dst_paths receives possible paths to sound files + * @param dst_datas receives binary sound data (not used here) + */ + void fetchSounds(const std::string &name, + std::set<std::string> &dst_paths, + std::set<std::string> &dst_datas); + +private: + /** set of fetched sound names */ + std::set<std::string> m_fetched; +}; + +/** implementation of main menu based uppon formspecs */ +class GUIEngine { + /** grant ModApiMainMenu access to private members */ + friend class ModApiMainMenu; + friend class ModApiSound; + +public: + /** + * default constructor + * @param dev device to draw at + * @param parent parent gui element + * @param menumgr manager to add menus to + * @param smgr scene manager to add scene elements to + * @param data struct to transfer data to main game handling + */ + GUIEngine(JoystickController *joystick, + gui::IGUIElement *parent, + RenderingEngine *rendering_engine, + IMenuManager *menumgr, + MainMenuData *data, + bool &kill); + + /** default destructor */ + virtual ~GUIEngine(); + + /** + * return MainMenuScripting interface + */ + MainMenuScripting *getScriptIface() + { + return m_script; + } + + /** + * return dir of current menuscript + */ + std::string getScriptDir() + { + return m_scriptdir; + } + +private: + + /** find and run the main menu script */ + bool loadMainMenuScript(); + + /** run main menu loop */ + void run(); + + /** update size of topleftext element */ + void updateTopLeftTextSize(); + + RenderingEngine *m_rendering_engine = nullptr; + /** parent gui element */ + gui::IGUIElement *m_parent = nullptr; + /** manager to add menus to */ + IMenuManager *m_menumanager = nullptr; + /** scene manager to add scene elements to */ + scene::ISceneManager *m_smgr = nullptr; + /** pointer to data beeing transfered back to main game handling */ + MainMenuData *m_data = nullptr; + /** pointer to texture source */ + ISimpleTextureSource *m_texture_source = nullptr; + /** pointer to soundmanager*/ + ISoundManager *m_sound_manager = nullptr; + + /** representation of form source to be used in mainmenu formspec */ + FormspecFormSource *m_formspecgui = nullptr; + /** formspec input receiver */ + TextDestGuiEngine *m_buttonhandler = nullptr; + /** the formspec menu */ + GUIFormSpecMenu *m_menu = nullptr; + + /** reference to kill variable managed by SIGINT handler */ + bool &m_kill; + + /** variable used to abort menu and return back to main game handling */ + bool m_startgame = false; + + /** scripting interface */ + MainMenuScripting *m_script = nullptr; + + /** script basefolder */ + std::string m_scriptdir = ""; + + void setFormspecPrepend(const std::string &fs); + + /** + * draw background layer + * @param driver to use for drawing + */ + void drawBackground(video::IVideoDriver *driver); + /** + * draw overlay layer + * @param driver to use for drawing + */ + void drawOverlay(video::IVideoDriver *driver); + /** + * draw header layer + * @param driver to use for drawing + */ + void drawHeader(video::IVideoDriver *driver); + /** + * draw footer layer + * @param driver to use for drawing + */ + void drawFooter(video::IVideoDriver *driver); + + /** + * load a texture for a specified layer + * @param layer draw layer to specify texture + * @param texturepath full path of texture to load + */ + bool setTexture(texture_layer layer, const std::string &texturepath, + bool tile_image, unsigned int minsize); + + /** + * download a file using curl + * @param url url to download + * @param target file to store to + */ + static bool downloadFile(const std::string &url, const std::string &target); + + /** array containing pointers to current specified texture layers */ + image_definition m_textures[TEX_LAYER_MAX]; + + /** + * specify text to appear as top left string + * @param text to set + */ + void setTopleftText(const std::string &text); + + /** pointer to gui element shown at topleft corner */ + irr::gui::IGUIStaticText *m_irr_toplefttext = nullptr; + /** and text that is in it */ + EnrichedString m_toplefttext; + + /** initialize cloud subsystem */ + void cloudInit(); + /** do preprocessing for cloud subsystem */ + void cloudPreProcess(); + /** do postprocessing for cloud subsystem */ + void cloudPostProcess(u32 frametime_min, IrrlichtDevice *device); + + /** internam data required for drawing clouds */ + struct clouddata { + /** delta time since last cloud processing */ + f32 dtime; + /** absolute time of last cloud processing */ + u32 lasttime; + /** pointer to cloud class */ + Clouds *clouds = nullptr; + /** camera required for drawing clouds */ + scene::ICameraSceneNode *camera = nullptr; + }; + + /** is drawing of clouds enabled atm */ + bool m_clouds_enabled = true; + /** data used to draw clouds */ + clouddata m_cloud; + + /** start playing a sound and return handle */ + s32 playSound(const SimpleSoundSpec &spec); + /** stop playing a sound started with playSound() */ + void stopSound(s32 handle); + + +}; diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp new file mode 100644 index 0000000..6293674 --- /dev/null +++ b/src/gui/guiFormSpecMenu.cpp @@ -0,0 +1,4759 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include <cstdlib> +#include <cmath> +#include <algorithm> +#include <iterator> +#include <limits> +#include <sstream> +#include "guiFormSpecMenu.h" +#include "constants.h" +#include "gamedef.h" +#include "client/keycode.h" +#include "util/strfnd.h" +#include <IGUIButton.h> +#include <IGUICheckBox.h> +#include <IGUIComboBox.h> +#include <IGUIEditBox.h> +#include <IGUIStaticText.h> +#include <IGUIFont.h> +#include <IGUITabControl.h> +#include "client/renderingengine.h" +#include "log.h" +#include "client/tile.h" // ITextureSource +#include "client/hud.h" // drawItemStack +#include "filesys.h" +#include "gettime.h" +#include "gettext.h" +#include "scripting_server.h" +#include "mainmenumanager.h" +#include "porting.h" +#include "settings.h" +#include "client/client.h" +#include "client/fontengine.h" +#include "client/sound.h" +#include "util/hex.h" +#include "util/numeric.h" +#include "util/string.h" // for parseColorString() +#include "irrlicht_changes/static_text.h" +#include "client/guiscalingfilter.h" +#include "guiAnimatedImage.h" +#include "guiBackgroundImage.h" +#include "guiBox.h" +#include "guiButton.h" +#include "guiButtonImage.h" +#include "guiButtonItemImage.h" +#include "guiEditBoxWithScrollbar.h" +#include "guiInventoryList.h" +#include "guiItemImage.h" +#include "guiScrollContainer.h" +#include "guiHyperText.h" +#include "guiScene.h" + +#define MY_CHECKPOS(a,b) \ + if (v_pos.size() != 2) { \ + errorstream<< "Invalid pos for element " << a << " specified: \"" \ + << parts[b] << "\"" << std::endl; \ + return; \ + } + +#define MY_CHECKGEOM(a,b) \ + if (v_geom.size() != 2) { \ + errorstream<< "Invalid geometry for element " << a << \ + " specified: \"" << parts[b] << "\"" << std::endl; \ + return; \ + } + +#define MY_CHECKCLIENT(a) \ + if (!m_client) { \ + errorstream << "Attempted to use element " << a << " with m_client == nullptr." << std::endl; \ + return; \ + } + +/* + GUIFormSpecMenu +*/ +static unsigned int font_line_height(gui::IGUIFont *font) +{ + return font->getDimension(L"Ay").Height + font->getKerningHeight(); +} + +inline u32 clamp_u8(s32 value) +{ + return (u32) MYMIN(MYMAX(value, 0), 255); +} + +GUIFormSpecMenu::GUIFormSpecMenu(JoystickController *joystick, + gui::IGUIElement *parent, s32 id, IMenuManager *menumgr, + Client *client, gui::IGUIEnvironment *guienv, ISimpleTextureSource *tsrc, + ISoundManager *sound_manager, IFormSource *fsrc, TextDest *tdst, + const std::string &formspecPrepend, bool remap_dbl_click): + GUIModalMenu(guienv, parent, id, menumgr, remap_dbl_click), + m_invmgr(client), + m_tsrc(tsrc), + m_sound_manager(sound_manager), + m_client(client), + m_formspec_prepend(formspecPrepend), + m_form_src(fsrc), + m_text_dst(tdst), + m_joystick(joystick) +{ + current_keys_pending.key_down = false; + current_keys_pending.key_up = false; + current_keys_pending.key_enter = false; + current_keys_pending.key_escape = false; + + m_tooltip_show_delay = (u32)g_settings->getS32("tooltip_show_delay"); + m_tooltip_append_itemname = g_settings->getBool("tooltip_append_itemname"); +} + +GUIFormSpecMenu::~GUIFormSpecMenu() +{ + removeAllChildren(); + removeTooltip(); + + for (auto &table_it : m_tables) + table_it.second->drop(); + for (auto &inventorylist_it : m_inventorylists) + inventorylist_it->drop(); + for (auto &checkbox_it : m_checkboxes) + checkbox_it.second->drop(); + for (auto &scrollbar_it : m_scrollbars) + scrollbar_it.second->drop(); + for (auto &tooltip_rect_it : m_tooltip_rects) + tooltip_rect_it.first->drop(); + for (auto &clickthrough_it : m_clickthrough_elements) + clickthrough_it->drop(); + for (auto &scroll_container_it : m_scroll_containers) + scroll_container_it.second->drop(); + + delete m_selected_item; + delete m_form_src; + delete m_text_dst; +} + +void GUIFormSpecMenu::create(GUIFormSpecMenu *&cur_formspec, Client *client, + gui::IGUIEnvironment *guienv, JoystickController *joystick, IFormSource *fs_src, + TextDest *txt_dest, const std::string &formspecPrepend, ISoundManager *sound_manager) +{ + if (cur_formspec == nullptr) { + cur_formspec = new GUIFormSpecMenu(joystick, guiroot, -1, &g_menumgr, + client, guienv, client->getTextureSource(), sound_manager, fs_src, + txt_dest, formspecPrepend); + cur_formspec->doPause = false; + + /* + Caution: do not call (*cur_formspec)->drop() here -- + the reference might outlive the menu, so we will + periodically check if *cur_formspec is the only + remaining reference (i.e. the menu was removed) + and delete it in that case. + */ + + } else { + cur_formspec->setFormspecPrepend(formspecPrepend); + cur_formspec->setFormSource(fs_src); + cur_formspec->setTextDest(txt_dest); + } +} + +void GUIFormSpecMenu::removeTooltip() +{ + if (m_tooltip_element) { + m_tooltip_element->remove(); + m_tooltip_element->drop(); + m_tooltip_element = nullptr; + } +} + +void GUIFormSpecMenu::setInitialFocus() +{ + // Set initial focus according to following order of precedence: + // 1. first empty editbox + // 2. first editbox + // 3. first table + // 4. last button + // 5. first focusable (not statictext, not tabheader) + // 6. first child element + + const auto& children = getChildren(); + + // 1. first empty editbox + for (gui::IGUIElement *it : children) { + if (it->getType() == gui::EGUIET_EDIT_BOX + && it->getText()[0] == 0) { + Environment->setFocus(it); + return; + } + } + + // 2. first editbox + for (gui::IGUIElement *it : children) { + if (it->getType() == gui::EGUIET_EDIT_BOX) { + Environment->setFocus(it); + return; + } + } + + // 3. first table + for (gui::IGUIElement *it : children) { + if (it->getTypeName() == std::string("GUITable")) { + Environment->setFocus(it); + return; + } + } + + // 4. last button + for (auto it = children.rbegin(); it != children.rend(); ++it) { + if ((*it)->getType() == gui::EGUIET_BUTTON) { + Environment->setFocus(*it); + return; + } + } + + // 5. first focusable (not statictext, not tabheader) + for (gui::IGUIElement *it : children) { + if (it->getType() != gui::EGUIET_STATIC_TEXT && + it->getType() != gui::EGUIET_TAB_CONTROL) { + Environment->setFocus(it); + return; + } + } + + // 6. first child element + if (children.empty()) + Environment->setFocus(this); + else + Environment->setFocus(children.front()); +} + +GUITable* GUIFormSpecMenu::getTable(const std::string &tablename) +{ + for (auto &table : m_tables) { + if (tablename == table.first.fname) + return table.second; + } + return 0; +} + +std::vector<std::string>* GUIFormSpecMenu::getDropDownValues(const std::string &name) +{ + for (auto &dropdown : m_dropdowns) { + if (name == dropdown.first.fname) + return &dropdown.second; + } + return NULL; +} + +v2s32 GUIFormSpecMenu::getElementBasePos(const std::vector<std::string> *v_pos) +{ + v2f32 pos_f = v2f32(padding.X, padding.Y) + pos_offset * spacing; + if (v_pos) { + pos_f.X += stof((*v_pos)[0]) * spacing.X; + pos_f.Y += stof((*v_pos)[1]) * spacing.Y; + } + return v2s32(pos_f.X, pos_f.Y); +} + +v2s32 GUIFormSpecMenu::getRealCoordinateBasePos(const std::vector<std::string> &v_pos) +{ + return v2s32((stof(v_pos[0]) + pos_offset.X) * imgsize.X, + (stof(v_pos[1]) + pos_offset.Y) * imgsize.Y); +} + +v2s32 GUIFormSpecMenu::getRealCoordinateGeometry(const std::vector<std::string> &v_geom) +{ + return v2s32(stof(v_geom[0]) * imgsize.X, stof(v_geom[1]) * imgsize.Y); +} + +bool GUIFormSpecMenu::precheckElement(const std::string &name, const std::string &element, + size_t args_min, size_t args_max, std::vector<std::string> &parts) +{ + parts = split(element, ';'); + if (parts.size() >= args_min && (parts.size() <= args_max || m_formspec_version > FORMSPEC_API_VERSION)) + return true; + + errorstream << "Invalid " << name << " element(" << parts.size() << "): '" << element << "'" << std::endl; + return false; +} + +void GUIFormSpecMenu::parseSize(parserData* data, const std::string &element) +{ + // Note: do not use precheckElement due to "," separator. + std::vector<std::string> parts = split(element,','); + + if (((parts.size() == 2) || parts.size() == 3) || + ((parts.size() > 3) && (m_formspec_version > FORMSPEC_API_VERSION))) + { + if (parts[1].find(';') != std::string::npos) + parts[1] = parts[1].substr(0,parts[1].find(';')); + + data->invsize.X = MYMAX(0, stof(parts[0])); + data->invsize.Y = MYMAX(0, stof(parts[1])); + + lockSize(false); +#ifndef HAVE_TOUCHSCREENGUI + if (parts.size() == 3) { + if (parts[2] == "true") { + lockSize(true,v2u32(800,600)); + } + } +#endif + data->explicit_size = true; + return; + } + errorstream<< "Invalid size element (" << parts.size() << "): '" << element << "'" << std::endl; +} + +void GUIFormSpecMenu::parseContainer(parserData* data, const std::string &element) +{ + std::vector<std::string> parts = split(element, ','); + + if (parts.size() >= 2) { + if (parts[1].find(';') != std::string::npos) + parts[1] = parts[1].substr(0, parts[1].find(';')); + + container_stack.push(pos_offset); + pos_offset.X += stof(parts[0]); + pos_offset.Y += stof(parts[1]); + return; + } + errorstream<< "Invalid container start element (" << parts.size() << "): '" << element << "'" << std::endl; +} + +void GUIFormSpecMenu::parseContainerEnd(parserData* data) +{ + if (container_stack.empty()) { + errorstream<< "Invalid container end element, no matching container start element" << std::endl; + } else { + pos_offset = container_stack.top(); + container_stack.pop(); + } +} + +void GUIFormSpecMenu::parseScrollContainer(parserData *data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("scroll_container start", element, 4, 5, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0], ','); + std::vector<std::string> v_geom = split(parts[1], ','); + std::string scrollbar_name = parts[2]; + std::string orientation = parts[3]; + f32 scroll_factor = 0.1f; + if (parts.size() >= 5 && !parts[4].empty()) + scroll_factor = stof(parts[4]); + + MY_CHECKPOS("scroll_container", 0); + MY_CHECKGEOM("scroll_container", 1); + + v2s32 pos = getRealCoordinateBasePos(v_pos); + v2s32 geom = getRealCoordinateGeometry(v_geom); + + if (orientation == "vertical") + scroll_factor *= -imgsize.Y; + else if (orientation == "horizontal") + scroll_factor *= -imgsize.X; + else + warningstream << "GUIFormSpecMenu::parseScrollContainer(): " + << "Invalid scroll_container orientation: " << orientation + << std::endl; + + // old parent (at first: this) + // ^ is parent of clipper + // ^ is parent of mover + // ^ is parent of other elements + + // make clipper + core::rect<s32> rect_clipper = core::rect<s32>(pos, pos + geom); + + gui::IGUIElement *clipper = new gui::IGUIElement(EGUIET_ELEMENT, Environment, + data->current_parent, 0, rect_clipper); + + // make mover + FieldSpec spec_mover( + "", + L"", + L"", + 258 + m_fields.size() + ); + + core::rect<s32> rect_mover = core::rect<s32>(0, 0, geom.X, geom.Y); + + GUIScrollContainer *mover = new GUIScrollContainer(Environment, + clipper, spec_mover.fid, rect_mover, orientation, scroll_factor); + + data->current_parent = mover; + + m_scroll_containers.emplace_back(scrollbar_name, mover); + + m_fields.push_back(spec_mover); + + clipper->drop(); + + // remove interferring offset of normal containers + container_stack.push(pos_offset); + pos_offset.X = 0.0f; + pos_offset.Y = 0.0f; +} + +void GUIFormSpecMenu::parseScrollContainerEnd(parserData *data) +{ + if (data->current_parent == this || data->current_parent->getParent() == this || + container_stack.empty()) { + errorstream << "Invalid scroll_container end element, " + << "no matching scroll_container start element" << std::endl; + return; + } + + if (pos_offset.getLengthSQ() != 0.0f) { + // pos_offset is only set by containers and scroll_containers. + // scroll_containers always set it to 0,0 which means that if it is + // not 0,0, it is a normal container that was opened last, not a + // scroll_container + errorstream << "Invalid scroll_container end element, " + << "an inner container was left open" << std::endl; + return; + } + + data->current_parent = data->current_parent->getParent()->getParent(); + pos_offset = container_stack.top(); + container_stack.pop(); +} + +void GUIFormSpecMenu::parseList(parserData *data, const std::string &element) +{ + MY_CHECKCLIENT("list"); + + std::vector<std::string> parts; + if (!precheckElement("list", element, 4, 5, parts)) + return; + + std::string location = parts[0]; + std::string listname = parts[1]; + std::vector<std::string> v_pos = split(parts[2],','); + std::vector<std::string> v_geom = split(parts[3],','); + std::string startindex; + if (parts.size() == 5) + startindex = parts[4]; + + MY_CHECKPOS("list",2); + MY_CHECKGEOM("list",3); + + InventoryLocation loc; + + if (location == "context" || location == "current_name") + loc = m_current_inventory_location; + else + loc.deSerialize(location); + + v2s32 geom; + geom.X = stoi(v_geom[0]); + geom.Y = stoi(v_geom[1]); + + s32 start_i = 0; + if (!startindex.empty()) + start_i = stoi(startindex); + + if (geom.X < 0 || geom.Y < 0 || start_i < 0) { + errorstream << "Invalid list element: '" << element << "'" << std::endl; + return; + } + + if (!data->explicit_size) + warningstream << "invalid use of list without a size[] element" << std::endl; + + FieldSpec spec( + "", + L"", + L"", + 258 + m_fields.size(), + 3 + ); + + auto style = getDefaultStyleForElement("list", spec.fname); + + v2f32 slot_scale = style.getVector2f(StyleSpec::SIZE, v2f32(0, 0)); + v2f32 slot_size( + slot_scale.X <= 0 ? imgsize.X : std::max<f32>(slot_scale.X * imgsize.X, 1), + slot_scale.Y <= 0 ? imgsize.Y : std::max<f32>(slot_scale.Y * imgsize.Y, 1) + ); + + v2f32 slot_spacing = style.getVector2f(StyleSpec::SPACING, v2f32(-1, -1)); + v2f32 default_spacing = data->real_coordinates ? + v2f32(imgsize.X * 0.25f, imgsize.Y * 0.25f) : + v2f32(spacing.X - imgsize.X, spacing.Y - imgsize.Y); + + slot_spacing.X = slot_spacing.X < 0 ? default_spacing.X : + imgsize.X * slot_spacing.X; + slot_spacing.Y = slot_spacing.Y < 0 ? default_spacing.Y : + imgsize.Y * slot_spacing.Y; + + slot_spacing += slot_size; + + v2s32 pos = data->real_coordinates ? getRealCoordinateBasePos(v_pos) : + getElementBasePos(&v_pos); + + core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, + pos.X + (geom.X - 1) * slot_spacing.X + slot_size.X, + pos.Y + (geom.Y - 1) * slot_spacing.Y + slot_size.Y); + + GUIInventoryList *e = new GUIInventoryList(Environment, data->current_parent, + spec.fid, rect, m_invmgr, loc, listname, geom, start_i, + v2s32(slot_size.X, slot_size.Y), slot_spacing, this, + data->inventorylist_options, m_font); + + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + + m_inventorylists.push_back(e); + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseListRing(parserData *data, const std::string &element) +{ + MY_CHECKCLIENT("listring"); + + std::vector<std::string> parts = split(element, ';'); + + if (parts.size() == 2) { + std::string location = parts[0]; + std::string listname = parts[1]; + + InventoryLocation loc; + + if (location == "context" || location == "current_name") + loc = m_current_inventory_location; + else + loc.deSerialize(location); + + m_inventory_rings.emplace_back(loc, listname); + return; + } + + if (element.empty() && m_inventorylists.size() > 1) { + size_t siz = m_inventorylists.size(); + // insert the last two inv list elements into the list ring + const GUIInventoryList *spa = m_inventorylists[siz - 2]; + const GUIInventoryList *spb = m_inventorylists[siz - 1]; + m_inventory_rings.emplace_back(spa->getInventoryloc(), spa->getListname()); + m_inventory_rings.emplace_back(spb->getInventoryloc(), spb->getListname()); + return; + } + + errorstream<< "Invalid list ring element(" << parts.size() << ", " + << m_inventorylists.size() << "): '" << element << "'" << std::endl; +} + +void GUIFormSpecMenu::parseCheckbox(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("checkbox", element, 3, 4, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0],','); + std::string name = parts[1]; + std::string label = parts[2]; + std::string selected; + + if (parts.size() >= 4) + selected = parts[3]; + + MY_CHECKPOS("checkbox",0); + + bool fselected = false; + + if (selected == "true") + fselected = true; + + std::wstring wlabel = translate_string(utf8_to_wide(unescape_string(label))); + const core::dimension2d<u32> label_size = m_font->getDimension(wlabel.c_str()); + s32 cb_size = Environment->getSkin()->getSize(gui::EGDS_CHECK_BOX_WIDTH); + s32 y_center = (std::max(label_size.Height, (u32)cb_size) + 1) / 2; + + v2s32 pos; + core::rect<s32> rect; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + + rect = core::rect<s32>( + pos.X, + pos.Y - y_center, + pos.X + label_size.Width + cb_size + 7, + pos.Y + y_center + ); + } else { + pos = getElementBasePos(&v_pos); + rect = core::rect<s32>( + pos.X, + pos.Y + imgsize.Y / 2 - y_center, + pos.X + label_size.Width + cb_size + 7, + pos.Y + imgsize.Y / 2 + y_center + ); + } + + FieldSpec spec( + name, + wlabel, //Needed for displaying text on MSVC + wlabel, + 258+m_fields.size() + ); + + spec.ftype = f_CheckBox; + + gui::IGUICheckBox *e = Environment->addCheckBox(fselected, rect, + data->current_parent, spec.fid, spec.flabel.c_str()); + + auto style = getDefaultStyleForElement("checkbox", name); + + spec.sound = style.get(StyleSpec::Property::SOUND, ""); + + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + + if (spec.fname == m_focused_element) { + Environment->setFocus(e); + } + + e->grab(); + m_checkboxes.emplace_back(spec, e); + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseScrollBar(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("scrollbar", element, 5, 5, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0],','); + std::vector<std::string> v_geom = split(parts[1],','); + std::string name = parts[3]; + std::string value = parts[4]; + + MY_CHECKPOS("scrollbar",0); + MY_CHECKGEOM("scrollbar",1); + + v2s32 pos; + v2s32 dim; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + dim = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + dim.X = stof(v_geom[0]) * spacing.X; + dim.Y = stof(v_geom[1]) * spacing.Y; + } + + core::rect<s32> rect = + core::rect<s32>(pos.X, pos.Y, pos.X + dim.X, pos.Y + dim.Y); + + FieldSpec spec( + name, + L"", + L"", + 258+m_fields.size() + ); + + bool is_horizontal = true; + + if (parts[2] == "vertical") + is_horizontal = false; + + spec.ftype = f_ScrollBar; + spec.send = true; + GUIScrollBar *e = new GUIScrollBar(Environment, data->current_parent, + spec.fid, rect, is_horizontal, true); + + auto style = getDefaultStyleForElement("scrollbar", name); + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + e->setArrowsVisible(data->scrollbar_options.arrow_visiblity); + + s32 max = data->scrollbar_options.max; + s32 min = data->scrollbar_options.min; + + e->setMax(max); + e->setMin(min); + + e->setPos(stoi(parts[4])); + + e->setSmallStep(data->scrollbar_options.small_step); + e->setLargeStep(data->scrollbar_options.large_step); + + s32 scrollbar_size = is_horizontal ? dim.X : dim.Y; + + e->setPageSize(scrollbar_size * (max - min + 1) / data->scrollbar_options.thumb_size); + + if (spec.fname == m_focused_element) { + Environment->setFocus(e); + } + + m_scrollbars.emplace_back(spec,e); + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseScrollBarOptions(parserData* data, const std::string &element) +{ + std::vector<std::string> parts = split(element, ';'); + + if (parts.size() == 0) { + warningstream << "Invalid scrollbaroptions element(" << parts.size() << "): '" << + element << "'" << std::endl; + return; + } + + for (const std::string &i : parts) { + std::vector<std::string> options = split(i, '='); + + if (options.size() != 2) { + warningstream << "Invalid scrollbaroptions option syntax: '" << + element << "'" << std::endl; + continue; // Go to next option + } + + if (options[0] == "max") { + data->scrollbar_options.max = stoi(options[1]); + continue; + } else if (options[0] == "min") { + data->scrollbar_options.min = stoi(options[1]); + continue; + } else if (options[0] == "smallstep") { + int value = stoi(options[1]); + data->scrollbar_options.small_step = value < 0 ? 10 : value; + continue; + } else if (options[0] == "largestep") { + int value = stoi(options[1]); + data->scrollbar_options.large_step = value < 0 ? 100 : value; + continue; + } else if (options[0] == "thumbsize") { + int value = stoi(options[1]); + data->scrollbar_options.thumb_size = value <= 0 ? 1 : value; + continue; + } else if (options[0] == "arrows") { + std::string value = trim(options[1]); + if (value == "hide") + data->scrollbar_options.arrow_visiblity = GUIScrollBar::HIDE; + else if (value == "show") + data->scrollbar_options.arrow_visiblity = GUIScrollBar::SHOW; + else // Auto hide/show + data->scrollbar_options.arrow_visiblity = GUIScrollBar::DEFAULT; + continue; + } + + warningstream << "Invalid scrollbaroptions option(" << options[0] << + "): '" << element << "'" << std::endl; + } +} + +void GUIFormSpecMenu::parseImage(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("image", element, 2, 4, parts)) + return; + + size_t offset = parts.size() >= 3; + + std::vector<std::string> v_pos = split(parts[0],','); + MY_CHECKPOS("image", 0); + + std::vector<std::string> v_geom; + if (parts.size() >= 3) { + v_geom = split(parts[1],','); + MY_CHECKGEOM("image", 1); + } + + std::string name = unescape_string(parts[1 + offset]); + video::ITexture *texture = m_tsrc->getTexture(name); + + v2s32 pos; + v2s32 geom; + + if (parts.size() < 3) { + if (texture != nullptr) { + core::dimension2du dim = texture->getOriginalSize(); + geom.X = dim.Width; + geom.Y = dim.Height; + } else { + geom = v2s32(0); + } + } + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + if (parts.size() >= 3) + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + if (parts.size() >= 3) { + geom.X = stof(v_geom[0]) * (float)imgsize.X; + geom.Y = stof(v_geom[1]) * (float)imgsize.Y; + } + } + + if (!data->explicit_size) + warningstream << "Invalid use of image without a size[] element" << std::endl; + + FieldSpec spec( + name, + L"", + L"", + 258 + m_fields.size(), + 1 + ); + + core::rect<s32> rect = core::rect<s32>(pos, pos + geom); + + core::rect<s32> middle; + if (parts.size() >= 4) + parseMiddleRect(parts[3], &middle); + + // Temporary fix for issue #12581 in 5.6.0. + // Use legacy image when not rendering 9-slice image because GUIAnimatedImage + // uses NNAA filter which causes visual artifacts when image uses alpha blending. + + gui::IGUIElement *e; + if (middle.getArea() > 0) { + GUIAnimatedImage *image = new GUIAnimatedImage(Environment, data->current_parent, + spec.fid, rect); + + image->setTexture(texture); + image->setMiddleRect(middle); + e = image; + } + else { + gui::IGUIImage *image = Environment->addImage(rect, data->current_parent, spec.fid, nullptr, true); + image->setImage(texture); + image->setScaleImage(true); + image->grab(); // compensate for drop in addImage + e = image; + } + + auto style = getDefaultStyleForElement("image", spec.fname); + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, m_formspec_version < 3)); + + // Animated images should let events through + m_clickthrough_elements.push_back(e); + + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseAnimatedImage(parserData *data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("animated_image", element, 6, 8, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0], ','); + std::vector<std::string> v_geom = split(parts[1], ','); + std::string name = parts[2]; + std::string texture_name = unescape_string(parts[3]); + s32 frame_count = stoi(parts[4]); + s32 frame_duration = stoi(parts[5]); + + MY_CHECKPOS("animated_image", 0); + MY_CHECKGEOM("animated_image", 1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + geom.X = stof(v_geom[0]) * (float)imgsize.X; + geom.Y = stof(v_geom[1]) * (float)imgsize.Y; + } + + if (!data->explicit_size) + warningstream << "Invalid use of animated_image without a size[] element" + << std::endl; + + FieldSpec spec( + name, + L"", + L"", + 258 + m_fields.size() + ); + spec.ftype = f_AnimatedImage; + spec.send = true; + + core::rect<s32> rect = core::rect<s32>(pos, pos + geom); + + core::rect<s32> middle; + if (parts.size() >= 8) + parseMiddleRect(parts[7], &middle); + + GUIAnimatedImage *e = new GUIAnimatedImage(Environment, data->current_parent, + spec.fid, rect); + + e->setTexture(m_tsrc->getTexture(texture_name)); + e->setMiddleRect(middle); + e->setFrameDuration(frame_duration); + e->setFrameCount(frame_count); + if (parts.size() >= 7) + e->setFrameIndex(stoi(parts[6]) - 1); + + auto style = getDefaultStyleForElement("animated_image", spec.fname, "image"); + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + + // Animated images should let events through + m_clickthrough_elements.push_back(e); + + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseItemImage(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("item_image", element, 3, 3, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0],','); + std::vector<std::string> v_geom = split(parts[1],','); + std::string name = parts[2]; + + MY_CHECKPOS("item_image",0); + MY_CHECKGEOM("item_image",1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + geom.X = stof(v_geom[0]) * (float)imgsize.X; + geom.Y = stof(v_geom[1]) * (float)imgsize.Y; + } + + if(!data->explicit_size) + warningstream<<"invalid use of item_image without a size[] element"<<std::endl; + + FieldSpec spec( + "", + L"", + L"", + 258 + m_fields.size(), + 2 + ); + spec.ftype = f_ItemImage; + + GUIItemImage *e = new GUIItemImage(Environment, data->current_parent, spec.fid, + core::rect<s32>(pos, pos + geom), name, m_font, m_client); + auto style = getDefaultStyleForElement("item_image", spec.fname); + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + + // item images should let events through + m_clickthrough_elements.push_back(e); + + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseButton(parserData* data, const std::string &element, + const std::string &type) +{ + std::vector<std::string> parts; + if (!precheckElement("button", element, 4, 4, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0],','); + std::vector<std::string> v_geom = split(parts[1],','); + std::string name = parts[2]; + std::string label = parts[3]; + + MY_CHECKPOS("button",0); + MY_CHECKGEOM("button",1); + + v2s32 pos; + v2s32 geom; + core::rect<s32> rect; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, + pos.Y+geom.Y); + } else { + pos = getElementBasePos(&v_pos); + geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X); + pos.Y += (stof(v_geom[1]) * (float)imgsize.Y)/2; + + rect = core::rect<s32>(pos.X, pos.Y - m_btn_height, + pos.X + geom.X, pos.Y + m_btn_height); + } + + if(!data->explicit_size) + warningstream<<"invalid use of button without a size[] element"<<std::endl; + + std::wstring wlabel = translate_string(utf8_to_wide(unescape_string(label))); + + FieldSpec spec( + name, + wlabel, + L"", + 258 + m_fields.size() + ); + spec.ftype = f_Button; + if(type == "button_exit") + spec.is_exit = true; + + GUIButton *e = GUIButton::addButton(Environment, rect, m_tsrc, + data->current_parent, spec.fid, spec.flabel.c_str()); + + auto style = getStyleForElement(type, name, (type != "button") ? "button" : ""); + + spec.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, ""); + + e->setStyles(style); + + if (spec.fname == m_focused_element) { + Environment->setFocus(e); + } + + m_fields.push_back(spec); +} + +bool GUIFormSpecMenu::parseMiddleRect(const std::string &value, core::rect<s32> *parsed_rect) +{ + core::rect<s32> rect; + std::vector<std::string> v_rect = split(value, ','); + + if (v_rect.size() == 1) { + s32 x = stoi(v_rect[0]); + rect.UpperLeftCorner = core::vector2di(x, x); + rect.LowerRightCorner = core::vector2di(-x, -x); + } else if (v_rect.size() == 2) { + s32 x = stoi(v_rect[0]); + s32 y = stoi(v_rect[1]); + rect.UpperLeftCorner = core::vector2di(x, y); + rect.LowerRightCorner = core::vector2di(-x, -y); + // `-x` is interpreted as `w - x` + } else if (v_rect.size() == 4) { + rect.UpperLeftCorner = core::vector2di(stoi(v_rect[0]), stoi(v_rect[1])); + rect.LowerRightCorner = core::vector2di(stoi(v_rect[2]), stoi(v_rect[3])); + } else { + warningstream << "Invalid rectangle string format: \"" << value + << "\"" << std::endl; + return false; + } + + *parsed_rect = rect; + + return true; +} + +void GUIFormSpecMenu::parseBackground(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("background", element, 3, 5, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0],','); + std::vector<std::string> v_geom = split(parts[1],','); + std::string name = unescape_string(parts[2]); + + MY_CHECKPOS("background",0); + MY_CHECKGEOM("background",1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + pos.X -= (spacing.X - (float)imgsize.X) / 2; + pos.Y -= (spacing.Y - (float)imgsize.Y) / 2; + + geom.X = stof(v_geom[0]) * spacing.X; + geom.Y = stof(v_geom[1]) * spacing.Y; + } + + bool clip = false; + if (parts.size() >= 4 && is_yes(parts[3])) { + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos) * -1; + geom = v2s32(0, 0); + } else { + pos.X = stoi(v_pos[0]); //acts as offset + pos.Y = stoi(v_pos[1]); + } + clip = true; + } + + core::rect<s32> middle; + if (parts.size() >= 5) + parseMiddleRect(parts[4], &middle); + + if (!data->explicit_size && !clip) + warningstream << "invalid use of unclipped background without a size[] element" << std::endl; + + FieldSpec spec( + name, + L"", + L"", + 258 + m_fields.size() + ); + + core::rect<s32> rect; + if (!clip) { + // no auto_clip => position like normal image + rect = core::rect<s32>(pos, pos + geom); + } else { + // it will be auto-clipped when drawing + rect = core::rect<s32>(-pos, pos); + } + + GUIBackgroundImage *e = new GUIBackgroundImage(Environment, data->background_parent.get(), + spec.fid, rect, name, middle, m_tsrc, clip); + + FATAL_ERROR_IF(!e, "Failed to create background formspec element"); + + e->setNotClipped(true); + + m_fields.push_back(spec); + e->drop(); +} + +void GUIFormSpecMenu::parseTableOptions(parserData* data, const std::string &element) +{ + std::vector<std::string> parts = split(element,';'); + + data->table_options.clear(); + for (const std::string &part : parts) { + // Parse table option + std::string opt = unescape_string(part); + data->table_options.push_back(GUITable::splitOption(opt)); + } +} + +void GUIFormSpecMenu::parseTableColumns(parserData* data, const std::string &element) +{ + std::vector<std::string> parts = split(element,';'); + + data->table_columns.clear(); + for (const std::string &part : parts) { + std::vector<std::string> col_parts = split(part,','); + GUITable::TableColumn column; + // Parse column type + if (!col_parts.empty()) + column.type = col_parts[0]; + // Parse column options + for (size_t j = 1; j < col_parts.size(); ++j) { + std::string opt = unescape_string(col_parts[j]); + column.options.push_back(GUITable::splitOption(opt)); + } + data->table_columns.push_back(column); + } +} + +void GUIFormSpecMenu::parseTable(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("table", element, 4, 5, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0],','); + std::vector<std::string> v_geom = split(parts[1],','); + std::string name = parts[2]; + std::vector<std::string> items = split(parts[3],','); + std::string str_initial_selection; + std::string str_transparent = "false"; + + if (parts.size() >= 5) + str_initial_selection = parts[4]; + + MY_CHECKPOS("table",0); + MY_CHECKGEOM("table",1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + geom.X = stof(v_geom[0]) * spacing.X; + geom.Y = stof(v_geom[1]) * spacing.Y; + } + + core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); + + FieldSpec spec( + name, + L"", + L"", + 258 + m_fields.size() + ); + + spec.ftype = f_Table; + + for (std::string &item : items) { + item = wide_to_utf8(unescape_translate(utf8_to_wide(unescape_string(item)))); + } + + //now really show table + GUITable *e = new GUITable(Environment, data->current_parent, spec.fid, + rect, m_tsrc); + + if (spec.fname == m_focused_element) { + Environment->setFocus(e); + } + + e->setTable(data->table_options, data->table_columns, items); + + if (data->table_dyndata.find(name) != data->table_dyndata.end()) { + e->setDynamicData(data->table_dyndata[name]); + } + + if (!str_initial_selection.empty() && str_initial_selection != "0") + e->setSelected(stoi(str_initial_selection)); + + auto style = getDefaultStyleForElement("table", name); + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + e->setOverrideFont(style.getFont()); + + m_tables.emplace_back(spec, e); + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseTextList(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("textlist", element, 4, 6, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0],','); + std::vector<std::string> v_geom = split(parts[1],','); + std::string name = parts[2]; + std::vector<std::string> items = split(parts[3],','); + std::string str_initial_selection; + std::string str_transparent = "false"; + + if (parts.size() >= 5) + str_initial_selection = parts[4]; + + if (parts.size() >= 6) + str_transparent = parts[5]; + + MY_CHECKPOS("textlist",0); + MY_CHECKGEOM("textlist",1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + geom.X = stof(v_geom[0]) * spacing.X; + geom.Y = stof(v_geom[1]) * spacing.Y; + } + + core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); + + FieldSpec spec( + name, + L"", + L"", + 258 + m_fields.size() + ); + + spec.ftype = f_Table; + + for (std::string &item : items) { + item = wide_to_utf8(unescape_translate(utf8_to_wide(unescape_string(item)))); + } + + //now really show list + GUITable *e = new GUITable(Environment, data->current_parent, spec.fid, + rect, m_tsrc); + + if (spec.fname == m_focused_element) { + Environment->setFocus(e); + } + + e->setTextList(items, is_yes(str_transparent)); + + if (data->table_dyndata.find(name) != data->table_dyndata.end()) { + e->setDynamicData(data->table_dyndata[name]); + } + + if (!str_initial_selection.empty() && str_initial_selection != "0") + e->setSelected(stoi(str_initial_selection)); + + auto style = getDefaultStyleForElement("textlist", name); + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + e->setOverrideFont(style.getFont()); + + m_tables.emplace_back(spec, e); + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseDropDown(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("dropdown", element, 5, 6, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0], ','); + std::string name = parts[2]; + std::vector<std::string> items = split(parts[3], ','); + std::string str_initial_selection = parts[4]; + + if (parts.size() >= 6 && is_yes(parts[5])) + m_dropdown_index_event[name] = true; + + MY_CHECKPOS("dropdown",0); + + v2s32 pos; + v2s32 geom; + core::rect<s32> rect; + + if (data->real_coordinates) { + std::vector<std::string> v_geom = split(parts[1],','); + + if (v_geom.size() == 1) + v_geom.emplace_back("1"); + + MY_CHECKGEOM("dropdown",1); + + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); + } else { + pos = getElementBasePos(&v_pos); + + s32 width = stof(parts[1]) * spacing.Y; + + rect = core::rect<s32>(pos.X, pos.Y, + pos.X + width, pos.Y + (m_btn_height * 2)); + } + + FieldSpec spec( + name, + L"", + L"", + 258 + m_fields.size() + ); + + spec.ftype = f_DropDown; + spec.send = true; + + //now really show list + gui::IGUIComboBox *e = Environment->addComboBox(rect, data->current_parent, + spec.fid); + + if (spec.fname == m_focused_element) { + Environment->setFocus(e); + } + + for (const std::string &item : items) { + e->addItem(unescape_translate(unescape_string( + utf8_to_wide(item))).c_str()); + } + + if (!str_initial_selection.empty()) + e->setSelected(stoi(str_initial_selection)-1); + + auto style = getDefaultStyleForElement("dropdown", name); + + spec.sound = style.get(StyleSpec::Property::SOUND, ""); + + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + + m_fields.push_back(spec); + + m_dropdowns.emplace_back(spec, std::vector<std::string>()); + std::vector<std::string> &values = m_dropdowns.back().second; + for (const std::string &item : items) { + values.push_back(unescape_string(item)); + } +} + +void GUIFormSpecMenu::parseFieldCloseOnEnter(parserData *data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("field_close_on_enter", element, 2, 2, parts)) + return; + + field_close_on_enter[parts[0]] = is_yes(parts[1]); +} + +void GUIFormSpecMenu::parsePwdField(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("pwdfield", element, 4, 4, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0],','); + std::vector<std::string> v_geom = split(parts[1],','); + std::string name = parts[2]; + std::string label = parts[3]; + + MY_CHECKPOS("pwdfield",0); + MY_CHECKGEOM("pwdfield",1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + pos -= padding; + + geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X); + + pos.Y += (stof(v_geom[1]) * (float)imgsize.Y)/2; + pos.Y -= m_btn_height; + geom.Y = m_btn_height*2; + } + + core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); + + std::wstring wlabel = translate_string(utf8_to_wide(unescape_string(label))); + + FieldSpec spec( + name, + wlabel, + L"", + 258 + m_fields.size(), + 0, + ECI_IBEAM + ); + + spec.send = true; + gui::IGUIEditBox *e = Environment->addEditBox(0, rect, true, + data->current_parent, spec.fid); + + if (spec.fname == m_focused_element) { + Environment->setFocus(e); + } + + if (label.length() >= 1) { + int font_height = g_fontengine->getTextHeight(); + rect.UpperLeftCorner.Y -= font_height; + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height; + gui::StaticText::add(Environment, spec.flabel.c_str(), rect, false, true, + data->current_parent, 0); + } + + e->setPasswordBox(true,L'*'); + + auto style = getDefaultStyleForElement("pwdfield", name, "field"); + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + e->setDrawBorder(style.getBool(StyleSpec::BORDER, true)); + e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF))); + e->setOverrideFont(style.getFont()); + + irr::SEvent evt; + evt.EventType = EET_KEY_INPUT_EVENT; + evt.KeyInput.Key = KEY_END; + evt.KeyInput.Char = 0; + evt.KeyInput.Control = false; + evt.KeyInput.Shift = false; + evt.KeyInput.PressedDown = true; + e->OnEvent(evt); + + // Note: Before 5.2.0 "parts.size() >= 5" resulted in a + // warning referring to field_close_on_enter[]! + + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::createTextField(parserData *data, FieldSpec &spec, + core::rect<s32> &rect, bool is_multiline) +{ + bool is_editable = !spec.fname.empty(); + if (!is_editable && !is_multiline) { + // spec field id to 0, this stops submit searching for a value that isn't there + gui::StaticText::add(Environment, spec.flabel.c_str(), rect, false, true, + data->current_parent, 0); + return; + } + + if (is_editable) { + spec.send = true; + } else if (is_multiline && + spec.fdefault.empty() && !spec.flabel.empty()) { + // Multiline textareas: swap default and label for backwards compat + spec.flabel.swap(spec.fdefault); + } + + gui::IGUIEditBox *e = nullptr; + if (is_multiline) { + e = new GUIEditBoxWithScrollBar(spec.fdefault.c_str(), true, Environment, + data->current_parent, spec.fid, rect, is_editable, true); + } else if (is_editable) { + e = Environment->addEditBox(spec.fdefault.c_str(), rect, true, + data->current_parent, spec.fid); + e->grab(); + } + + auto style = getDefaultStyleForElement(is_multiline ? "textarea" : "field", spec.fname); + + if (e) { + if (is_editable && spec.fname == m_focused_element) + Environment->setFocus(e); + + if (is_multiline) { + e->setMultiLine(true); + e->setWordWrap(true); + e->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_UPPERLEFT); + } else { + irr::SEvent evt; + evt.EventType = EET_KEY_INPUT_EVENT; + evt.KeyInput.Key = KEY_END; + evt.KeyInput.Char = 0; + evt.KeyInput.Control = 0; + evt.KeyInput.Shift = 0; + evt.KeyInput.PressedDown = true; + e->OnEvent(evt); + } + + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF))); + bool border = style.getBool(StyleSpec::BORDER, true); + e->setDrawBorder(border); + e->setDrawBackground(border); + e->setOverrideFont(style.getFont()); + + e->drop(); + } + + if (!spec.flabel.empty()) { + int font_height = g_fontengine->getTextHeight(); + rect.UpperLeftCorner.Y -= font_height; + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height; + IGUIElement *t = gui::StaticText::add(Environment, spec.flabel.c_str(), + rect, false, true, data->current_parent, 0); + + if (t) + t->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + } +} + +void GUIFormSpecMenu::parseSimpleField(parserData *data, + std::vector<std::string> &parts) +{ + std::string name = parts[0]; + std::string label = parts[1]; + std::string default_val = parts[2]; + + core::rect<s32> rect; + + if (data->explicit_size) + warningstream << "invalid use of unpositioned \"field\" in inventory" << std::endl; + + v2s32 pos = getElementBasePos(nullptr); + pos.Y = (data->simple_field_count + 2) * 60; + v2s32 size = DesiredRect.getSize(); + + rect = core::rect<s32>( + size.X / 2 - 150, pos.Y, + size.X / 2 - 150 + 300, pos.Y + m_btn_height * 2 + ); + + + if (m_form_src) + default_val = m_form_src->resolveText(default_val); + + + std::wstring wlabel = translate_string(utf8_to_wide(unescape_string(label))); + + FieldSpec spec( + name, + wlabel, + utf8_to_wide(unescape_string(default_val)), + 258 + m_fields.size(), + 0, + ECI_IBEAM + ); + + createTextField(data, spec, rect, false); + + m_fields.push_back(spec); + + data->simple_field_count++; +} + +void GUIFormSpecMenu::parseTextArea(parserData* data, std::vector<std::string>& parts, + const std::string &type) +{ + std::vector<std::string> v_pos = split(parts[0],','); + std::vector<std::string> v_geom = split(parts[1],','); + std::string name = parts[2]; + std::string label = parts[3]; + std::string default_val = parts[4]; + + MY_CHECKPOS(type,0); + MY_CHECKGEOM(type,1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + pos -= padding; + + geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X); + + if (type == "textarea") + { + geom.Y = (stof(v_geom[1]) * (float)imgsize.Y) - (spacing.Y-imgsize.Y); + pos.Y += m_btn_height; + } + else + { + pos.Y += (stof(v_geom[1]) * (float)imgsize.Y)/2; + pos.Y -= m_btn_height; + geom.Y = m_btn_height*2; + } + } + + core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); + + if(!data->explicit_size) + warningstream<<"invalid use of positioned "<<type<<" without a size[] element"<<std::endl; + + if(m_form_src) + default_val = m_form_src->resolveText(default_val); + + + std::wstring wlabel = translate_string(utf8_to_wide(unescape_string(label))); + + FieldSpec spec( + name, + wlabel, + utf8_to_wide(unescape_string(default_val)), + 258 + m_fields.size(), + 0, + ECI_IBEAM + ); + + createTextField(data, spec, rect, type == "textarea"); + + // Note: Before 5.2.0 "parts.size() >= 6" resulted in a + // warning referring to field_close_on_enter[]! + + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseField(parserData* data, const std::string &element, + const std::string &type) +{ + std::vector<std::string> parts; + if (!precheckElement(type, element, 3, 5, parts)) + return; + + if (parts.size() == 3 || parts.size() == 4) { + parseSimpleField(data, parts); + return; + } + + // Else: >= 5 arguments in "parts" + parseTextArea(data, parts, type); +} + +void GUIFormSpecMenu::parseHyperText(parserData *data, const std::string &element) +{ + MY_CHECKCLIENT("hypertext"); + + std::vector<std::string> parts; + if (!precheckElement("hypertext", element, 4, 4, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0], ','); + std::vector<std::string> v_geom = split(parts[1], ','); + std::string name = parts[2]; + std::string text = parts[3]; + + MY_CHECKPOS("hypertext", 0); + MY_CHECKGEOM("hypertext", 1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + pos -= padding; + + geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X); + geom.Y = (stof(v_geom[1]) * (float)imgsize.Y) - (spacing.Y - imgsize.Y); + pos.Y += m_btn_height; + } + + core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X + geom.X, pos.Y + geom.Y); + + if(m_form_src) + text = m_form_src->resolveText(text); + + FieldSpec spec( + name, + translate_string(utf8_to_wide(unescape_string(text))), + L"", + 258 + m_fields.size() + ); + + spec.ftype = f_HyperText; + + auto style = getDefaultStyleForElement("hypertext", spec.fname); + spec.sound = style.get(StyleSpec::Property::SOUND, ""); + + GUIHyperText *e = new GUIHyperText(spec.flabel.c_str(), Environment, + data->current_parent, spec.fid, rect, m_client, m_tsrc); + e->drop(); + + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("label", element, 2, 2, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0],','); + + MY_CHECKPOS("label",0); + + if(!data->explicit_size) + warningstream<<"invalid use of label without a size[] element"<<std::endl; + + auto style = getDefaultStyleForElement("label", ""); + gui::IGUIFont *font = style.getFont(); + if (!font) + font = m_font; + + EnrichedString str(unescape_string(utf8_to_wide(parts[1]))); + size_t str_pos = 0; + + for (size_t i = 0; str_pos < str.size(); ++i) { + // Split per line + size_t str_nl = str.getString().find(L'\n', str_pos); + if (str_nl == std::wstring::npos) + str_nl = str.getString().size(); + EnrichedString line = str.substr(str_pos, str_nl - str_pos); + str_pos += line.size() + 1; + + core::rect<s32> rect; + + if (data->real_coordinates) { + // Lines are spaced at the distance of 1/2 imgsize. + // This alows lines that line up with the new elements + // easily without sacrificing good line distance. If + // it was one whole imgsize, it would have too much + // spacing. + v2s32 pos = getRealCoordinateBasePos(v_pos); + + // Labels are positioned by their center, not their top. + pos.Y += (((float) imgsize.Y) / -2) + (((float) imgsize.Y) * i / 2); + + rect = core::rect<s32>( + pos.X, pos.Y, + pos.X + font->getDimension(line.c_str()).Width, + pos.Y + imgsize.Y); + + } else { + // Lines are spaced at the nominal distance of + // 2/5 inventory slot, even if the font doesn't + // quite match that. This provides consistent + // form layout, at the expense of sometimes + // having sub-optimal spacing for the font. + // We multiply by 2 and then divide by 5, rather + // than multiply by 0.4, to get exact results + // in the integer cases: 0.4 is not exactly + // representable in binary floating point. + + v2s32 pos = getElementBasePos(nullptr); + pos.X += stof(v_pos[0]) * spacing.X; + pos.Y += (stof(v_pos[1]) + 7.0f / 30.0f) * spacing.Y; + + pos.Y += ((float) i) * spacing.Y * 2.0 / 5.0; + + rect = core::rect<s32>( + pos.X, pos.Y - m_btn_height, + pos.X + font->getDimension(line.c_str()).Width, + pos.Y + m_btn_height); + } + + FieldSpec spec( + "", + L"", + L"", + 258 + m_fields.size(), + 4 + ); + gui::IGUIStaticText *e = gui::StaticText::add(Environment, + line, rect, false, false, data->current_parent, + spec.fid); + e->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_CENTER); + + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF))); + e->setOverrideFont(font); + + m_fields.push_back(spec); + + // labels should let events through + e->grab(); + m_clickthrough_elements.push_back(e); + } +} + +void GUIFormSpecMenu::parseVertLabel(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("vertlabel", element, 2, 2, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0],','); + std::wstring text = unescape_translate( + unescape_string(utf8_to_wide(parts[1]))); + + MY_CHECKPOS("vertlabel",1); + + auto style = getDefaultStyleForElement("vertlabel", "", "label"); + gui::IGUIFont *font = style.getFont(); + if (!font) + font = m_font; + + v2s32 pos; + core::rect<s32> rect; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + + // Vertlabels are positioned by center, not left. + pos.X -= imgsize.X / 2; + + // We use text.length + 1 because without it, the rect + // isn't quite tall enough and cuts off the text. + rect = core::rect<s32>(pos.X, pos.Y, + pos.X + imgsize.X, + pos.Y + font_line_height(font) * + (text.length() + 1)); + + } else { + pos = getElementBasePos(&v_pos); + + // As above, the length must be one longer. The width of + // the rect (15 pixels) seems rather arbitrary, but + // changing it might break something. + rect = core::rect<s32>( + pos.X, pos.Y+((imgsize.Y/2) - m_btn_height), + pos.X+15, pos.Y + + font_line_height(font) * + (text.length() + 1) + + ((imgsize.Y/2) - m_btn_height)); + } + + if(!data->explicit_size) + warningstream<<"invalid use of label without a size[] element"<<std::endl; + + std::wstring label; + + for (wchar_t i : text) { + label += i; + label += L"\n"; + } + + FieldSpec spec( + "", + label, + L"", + 258 + m_fields.size() + ); + gui::IGUIStaticText *e = gui::StaticText::add(Environment, spec.flabel.c_str(), + rect, false, false, data->current_parent, spec.fid); + e->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER); + + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF))); + e->setOverrideFont(font); + + m_fields.push_back(spec); + + // vertlabels should let events through + e->grab(); + m_clickthrough_elements.push_back(e); +} + +void GUIFormSpecMenu::parseImageButton(parserData* data, const std::string &element, + const std::string &type) +{ + std::vector<std::string> parts; + if (!precheckElement("image_button", element, 5, 8, parts)) + return; + + if (parts.size() == 6) { + // Invalid argument count. + errorstream << "Invalid image_button element(" << parts.size() << "): '" << element << "'" << std::endl; + return; + } + + std::vector<std::string> v_pos = split(parts[0],','); + std::vector<std::string> v_geom = split(parts[1],','); + std::string image_name = parts[2]; + std::string name = parts[3]; + std::string label = parts[4]; + + MY_CHECKPOS("image_button",0); + MY_CHECKGEOM("image_button",1); + + std::string pressed_image_name; + + if (parts.size() >= 8) { + pressed_image_name = parts[7]; + } + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X); + geom.Y = (stof(v_geom[1]) * spacing.Y) - (spacing.Y - imgsize.Y); + } + + core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, + pos.Y+geom.Y); + + if (!data->explicit_size) + warningstream<<"invalid use of image_button without a size[] element"<<std::endl; + + image_name = unescape_string(image_name); + pressed_image_name = unescape_string(pressed_image_name); + + std::wstring wlabel = utf8_to_wide(unescape_string(label)); + + FieldSpec spec( + name, + wlabel, + utf8_to_wide(image_name), + 258 + m_fields.size() + ); + spec.ftype = f_Button; + if (type == "image_button_exit") + spec.is_exit = true; + + GUIButtonImage *e = GUIButtonImage::addButton(Environment, rect, m_tsrc, + data->current_parent, spec.fid, spec.flabel.c_str()); + + if (spec.fname == m_focused_element) { + Environment->setFocus(e); + } + + auto style = getStyleForElement("image_button", spec.fname); + + spec.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, ""); + + // Override style properties with values specified directly in the element + if (!image_name.empty()) + style[StyleSpec::STATE_DEFAULT].set(StyleSpec::FGIMG, image_name); + + if (!pressed_image_name.empty()) + style[StyleSpec::STATE_PRESSED].set(StyleSpec::FGIMG, pressed_image_name); + + if (parts.size() >= 7) { + style[StyleSpec::STATE_DEFAULT].set(StyleSpec::NOCLIP, parts[5]); + style[StyleSpec::STATE_DEFAULT].set(StyleSpec::BORDER, parts[6]); + } + + e->setStyles(style); + e->setScaleImage(true); + + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseTabHeader(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("tabheader", element, 4, 7, parts)) + return; + + // Length 7: Additional "height" parameter after "pos". Only valid with real_coordinates. + // Note: New arguments for the "height" syntax cannot be added without breaking older clients. + if (parts.size() == 5 || (parts.size() == 7 && !data->real_coordinates)) { + errorstream << "Invalid tabheader element(" << parts.size() << "): '" + << element << "'" << std::endl; + return; + } + + std::vector<std::string> v_pos = split(parts[0],','); + + // If we're using real coordinates, add an extra field for height. + // Width is not here because tabs are the width of the text, and + // there's no reason to change that. + unsigned int i = 0; + std::vector<std::string> v_geom = {"1", "1"}; // Dummy width and height + bool auto_width = true; + if (parts.size() == 7) { + i++; + + v_geom = split(parts[1], ','); + if (v_geom.size() == 1) + v_geom.insert(v_geom.begin(), "1"); // Dummy value + else + auto_width = false; + } + + std::string name = parts[i+1]; + std::vector<std::string> buttons = split(parts[i+2], ','); + std::string str_index = parts[i+3]; + bool show_background = true; + bool show_border = true; + int tab_index = stoi(str_index) - 1; + + MY_CHECKPOS("tabheader", 0); + + if (parts.size() == 6 + i) { + if (parts[4+i] == "true") + show_background = false; + if (parts[5+i] == "false") + show_border = false; + } + + FieldSpec spec( + name, + L"", + L"", + 258 + m_fields.size() + ); + + spec.ftype = f_TabHeader; + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + + geom = getRealCoordinateGeometry(v_geom); + // Set default height + if (parts.size() <= 6) + geom.Y = m_btn_height * 2; + pos.Y -= geom.Y; // TabHeader base pos is the bottom, not the top. + if (auto_width) + geom.X = DesiredRect.getWidth(); // Set automatic width + + MY_CHECKGEOM("tabheader", 1); + } else { + v2f32 pos_f = pos_offset * spacing; + pos_f.X += stof(v_pos[0]) * spacing.X; + pos_f.Y += stof(v_pos[1]) * spacing.Y - m_btn_height * 2; + pos = v2s32(pos_f.X, pos_f.Y); + + geom.Y = m_btn_height * 2; + geom.X = DesiredRect.getWidth(); + } + + core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, + pos.Y+geom.Y); + + gui::IGUITabControl *e = Environment->addTabControl(rect, + data->current_parent, show_background, show_border, spec.fid); + e->setAlignment(irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT, + irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_LOWERRIGHT); + e->setTabHeight(geom.Y); + + auto style = getDefaultStyleForElement("tabheader", name); + + spec.sound = style.get(StyleSpec::Property::SOUND, ""); + + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, true)); + + for (const std::string &button : buttons) { + auto tab = e->addTab(unescape_translate(unescape_string( + utf8_to_wide(button))).c_str(), -1); + if (style.isNotDefault(StyleSpec::BGCOLOR)) + tab->setBackgroundColor(style.getColor(StyleSpec::BGCOLOR)); + + tab->setTextColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF))); + } + + if ((tab_index >= 0) && + (buttons.size() < INT_MAX) && + (tab_index < (int) buttons.size())) + e->setActiveTab(tab_index); + + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseItemImageButton(parserData* data, const std::string &element) +{ + MY_CHECKCLIENT("item_image_button"); + + std::vector<std::string> parts; + if (!precheckElement("item_image_button", element, 5, 5, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0],','); + std::vector<std::string> v_geom = split(parts[1],','); + std::string item_name = parts[2]; + std::string name = parts[3]; + std::string label = parts[4]; + + label = unescape_string(label); + item_name = unescape_string(item_name); + + MY_CHECKPOS("item_image_button",0); + MY_CHECKGEOM("item_image_button",1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X); + geom.Y = (stof(v_geom[1]) * spacing.Y) - (spacing.Y - imgsize.Y); + } + + core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); + + if(!data->explicit_size) + warningstream<<"invalid use of item_image_button without a size[] element"<<std::endl; + + IItemDefManager *idef = m_client->idef(); + ItemStack item; + item.deSerialize(item_name, idef); + + m_tooltips[name] = + TooltipSpec(utf8_to_wide(item.getDefinition(idef).description), + m_default_tooltip_bgcolor, + m_default_tooltip_color); + + // the spec for the button + FieldSpec spec_btn( + name, + utf8_to_wide(label), + utf8_to_wide(item_name), + 258 + m_fields.size(), + 2 + ); + + GUIButtonItemImage *e_btn = GUIButtonItemImage::addButton(Environment, + rect, m_tsrc, data->current_parent, spec_btn.fid, spec_btn.flabel.c_str(), + item_name, m_client); + + auto style = getStyleForElement("item_image_button", spec_btn.fname, "image_button"); + + spec_btn.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, ""); + + e_btn->setStyles(style); + + if (spec_btn.fname == m_focused_element) { + Environment->setFocus(e_btn); + } + + spec_btn.ftype = f_Button; + rect += data->basepos-padding; + spec_btn.rect = rect; + m_fields.push_back(spec_btn); +} + +void GUIFormSpecMenu::parseBox(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("box", element, 3, 3, parts)) + return; + + std::vector<std::string> v_pos = split(parts[0], ','); + std::vector<std::string> v_geom = split(parts[1], ','); + + MY_CHECKPOS("box", 0); + MY_CHECKGEOM("box", 1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + geom.X = stof(v_geom[0]) * spacing.X; + geom.Y = stof(v_geom[1]) * spacing.Y; + } + + FieldSpec spec( + "", + L"", + L"", + 258 + m_fields.size(), + -2 + ); + spec.ftype = f_Box; + + auto style = getDefaultStyleForElement("box", spec.fname); + + video::SColor tmp_color; + std::array<video::SColor, 4> colors; + std::array<video::SColor, 4> bordercolors = {0x0, 0x0, 0x0, 0x0}; + std::array<s32, 4> borderwidths = {0, 0, 0, 0}; + + if (parseColorString(parts[2], tmp_color, true, 0x8C)) { + colors = {tmp_color, tmp_color, tmp_color, tmp_color}; + } else { + colors = style.getColorArray(StyleSpec::COLORS, {0x0, 0x0, 0x0, 0x0}); + bordercolors = style.getColorArray(StyleSpec::BORDERCOLORS, + {0x0, 0x0, 0x0, 0x0}); + borderwidths = style.getIntArray(StyleSpec::BORDERWIDTHS, {0, 0, 0, 0}); + } + + core::rect<s32> rect(pos, pos + geom); + + GUIBox *e = new GUIBox(Environment, data->current_parent, spec.fid, rect, + colors, bordercolors, borderwidths); + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, m_formspec_version < 3)); + e->drop(); + + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseBackgroundColor(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("bgcolor", element, 1, 3, parts)) + return; + + const u32 parameter_count = parts.size(); + + if (parameter_count > 2 && m_formspec_version < 3) { + errorstream << "Invalid bgcolor element(" << parameter_count << "): '" + << element << "'" << std::endl; + return; + } + + // bgcolor + if (parameter_count >= 1 && parts[0] != "") + parseColorString(parts[0], m_bgcolor, false); + + // fullscreen + if (parameter_count >= 2) { + if (parts[1] == "both") { + m_bgnonfullscreen = true; + m_bgfullscreen = true; + } else if (parts[1] == "neither") { + m_bgnonfullscreen = false; + m_bgfullscreen = false; + } else if (parts[1] != "" || m_formspec_version < 3) { + m_bgfullscreen = is_yes(parts[1]); + m_bgnonfullscreen = !m_bgfullscreen; + } + } + + // fbgcolor + if (parameter_count >= 3 && parts[2] != "") + parseColorString(parts[2], m_fullscreen_bgcolor, false); +} + +void GUIFormSpecMenu::parseListColors(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + // Legacy Note: If clients older than 5.5.0-dev are supplied with additional arguments, + // the tooltip colors will be ignored. + if (!precheckElement("listcolors", element, 2, 5, parts)) + return; + + if (parts.size() == 4) { + // Invalid argument combination + errorstream << "Invalid listcolors element(" << parts.size() << "): '" + << element << "'" << std::endl; + return; + } + + parseColorString(parts[0], data->inventorylist_options.slotbg_n, false); + parseColorString(parts[1], data->inventorylist_options.slotbg_h, false); + + if (parts.size() >= 3) { + if (parseColorString(parts[2], data->inventorylist_options.slotbordercolor, + false)) { + data->inventorylist_options.slotborder = true; + } + } + if (parts.size() >= 5) { + video::SColor tmp_color; + + if (parseColorString(parts[3], tmp_color, false)) + m_default_tooltip_bgcolor = tmp_color; + if (parseColorString(parts[4], tmp_color, false)) + m_default_tooltip_color = tmp_color; + } + + // update all already parsed inventorylists + for (GUIInventoryList *e : m_inventorylists) { + e->setSlotBGColors(data->inventorylist_options.slotbg_n, + data->inventorylist_options.slotbg_h); + e->setSlotBorders(data->inventorylist_options.slotborder, + data->inventorylist_options.slotbordercolor); + } +} + +void GUIFormSpecMenu::parseTooltip(parserData* data, const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("tooltip", element, 2, 5, parts)) + return; + + // Get mode and check size + bool rect_mode = parts[0].find(',') != std::string::npos; + size_t base_size = rect_mode ? 3 : 2; + if (parts.size() != base_size && parts.size() != base_size + 2) { + errorstream << "Invalid tooltip element(" << parts.size() << "): '" + << element << "'" << std::endl; + return; + } + + // Read colors + video::SColor bgcolor = m_default_tooltip_bgcolor; + video::SColor color = m_default_tooltip_color; + if (parts.size() == base_size + 2 && + (!parseColorString(parts[base_size], bgcolor, false) || + !parseColorString(parts[base_size + 1], color, false))) { + errorstream << "Invalid color in tooltip element(" << parts.size() + << "): '" << element << "'" << std::endl; + return; + } + + // Make tooltip spec + std::string text = unescape_string(parts[rect_mode ? 2 : 1]); + TooltipSpec spec(utf8_to_wide(text), bgcolor, color); + + // Add tooltip + if (rect_mode) { + std::vector<std::string> v_pos = split(parts[0], ','); + std::vector<std::string> v_geom = split(parts[1], ','); + + MY_CHECKPOS("tooltip", 0); + MY_CHECKGEOM("tooltip", 1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + geom.X = stof(v_geom[0]) * spacing.X; + geom.Y = stof(v_geom[1]) * spacing.Y; + } + + FieldSpec fieldspec( + "", + L"", + L"", + 258 + m_fields.size() + ); + + core::rect<s32> rect(pos, pos + geom); + + gui::IGUIElement *e = new gui::IGUIElement(EGUIET_ELEMENT, Environment, + data->current_parent, fieldspec.fid, rect); + + // the element the rect tooltip is bound to should not block mouse-clicks + e->setVisible(false); + + m_fields.push_back(fieldspec); + m_tooltip_rects.emplace_back(e, spec); + + } else { + m_tooltips[parts[0]] = spec; + } +} + +bool GUIFormSpecMenu::parseVersionDirect(const std::string &data) +{ + //some prechecks + if (data.empty()) + return false; + + std::vector<std::string> parts = split(data,'['); + + if (parts.size() < 2) { + return false; + } + + if (trim(parts[0]) != "formspec_version") { + return false; + } + + if (is_number(parts[1])) { + m_formspec_version = mystoi(parts[1]); + return true; + } + + return false; +} + +bool GUIFormSpecMenu::parseSizeDirect(parserData* data, const std::string &element) +{ + if (element.empty()) + return false; + + std::vector<std::string> parts = split(element,'['); + + if (parts.size() < 2) + return false; + + std::string type = trim(parts[0]); + std::string description = trim(parts[1]); + + if (type != "size" && type != "invsize") + return false; + + if (type == "invsize") + warningstream << "Deprecated formspec element \"invsize\" is used" << std::endl; + + parseSize(data, description); + + return true; +} + +bool GUIFormSpecMenu::parsePositionDirect(parserData *data, const std::string &element) +{ + if (element.empty()) + return false; + + std::vector<std::string> parts = split(element, '['); + + if (parts.size() != 2) + return false; + + std::string type = trim(parts[0]); + std::string description = trim(parts[1]); + + if (type != "position") + return false; + + parsePosition(data, description); + + return true; +} + +void GUIFormSpecMenu::parsePosition(parserData *data, const std::string &element) +{ + std::vector<std::string> parts = split(element, ';'); + + if (parts.size() == 1 || + (parts.size() > 1 && m_formspec_version > FORMSPEC_API_VERSION)) { + std::vector<std::string> v_geom = split(parts[0], ','); + + MY_CHECKGEOM("position", 0); + + data->offset.X = stof(v_geom[0]); + data->offset.Y = stof(v_geom[1]); + return; + } + + errorstream << "Invalid position element (" << parts.size() << "): '" << element << "'" << std::endl; +} + +bool GUIFormSpecMenu::parseAnchorDirect(parserData *data, const std::string &element) +{ + if (element.empty()) + return false; + + std::vector<std::string> parts = split(element, '['); + + if (parts.size() != 2) + return false; + + std::string type = trim(parts[0]); + std::string description = trim(parts[1]); + + if (type != "anchor") + return false; + + parseAnchor(data, description); + + return true; +} + +void GUIFormSpecMenu::parseAnchor(parserData *data, const std::string &element) +{ + std::vector<std::string> parts = split(element, ';'); + + if (parts.size() == 1 || + (parts.size() > 1 && m_formspec_version > FORMSPEC_API_VERSION)) { + std::vector<std::string> v_geom = split(parts[0], ','); + + MY_CHECKGEOM("anchor", 0); + + data->anchor.X = stof(v_geom[0]); + data->anchor.Y = stof(v_geom[1]); + return; + } + + errorstream << "Invalid anchor element (" << parts.size() << "): '" << element + << "'" << std::endl; +} + +bool GUIFormSpecMenu::parsePaddingDirect(parserData *data, const std::string &element) +{ + if (element.empty()) + return false; + + std::vector<std::string> parts = split(element, '['); + + if (parts.size() != 2) + return false; + + std::string type = trim(parts[0]); + std::string description = trim(parts[1]); + + if (type != "padding") + return false; + + parsePadding(data, description); + + return true; +} + +void GUIFormSpecMenu::parsePadding(parserData *data, const std::string &element) +{ + std::vector<std::string> parts = split(element, ';'); + + if (parts.size() == 1 || + (parts.size() > 1 && m_formspec_version > FORMSPEC_API_VERSION)) { + std::vector<std::string> v_geom = split(parts[0], ','); + + MY_CHECKGEOM("padding", 0); + + data->padding.X = stof(v_geom[0]); + data->padding.Y = stof(v_geom[1]); + return; + } + + errorstream << "Invalid padding element (" << parts.size() << "): '" << element + << "'" << std::endl; +} + +bool GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element, bool style_type) +{ + std::vector<std::string> parts = split(element, ';'); + + if (parts.size() < 2) { + errorstream << "Invalid style element (" << parts.size() << "): '" << element + << "'" << std::endl; + return false; + } + + StyleSpec spec; + + // Parse properties + for (size_t i = 1; i < parts.size(); i++) { + size_t equal_pos = parts[i].find('='); + if (equal_pos == std::string::npos) { + errorstream << "Invalid style element (Property missing value): '" << element + << "'" << std::endl; + return false; + } + + std::string propname = trim(parts[i].substr(0, equal_pos)); + std::string value = trim(unescape_string(parts[i].substr(equal_pos + 1))); + + std::transform(propname.begin(), propname.end(), propname.begin(), ::tolower); + + StyleSpec::Property prop = StyleSpec::GetPropertyByName(propname); + if (prop == StyleSpec::NONE) { + if (property_warned.find(propname) != property_warned.end()) { + warningstream << "Invalid style element (Unknown property " << propname << "): '" + << element + << "'" << std::endl; + property_warned.insert(propname); + } + continue; + } + + spec.set(prop, value); + } + + std::vector<std::string> selectors = split(parts[0], ','); + for (size_t sel = 0; sel < selectors.size(); sel++) { + std::string selector = trim(selectors[sel]); + + // Copy the style properties to a new StyleSpec + // This allows a separate state mask per-selector + StyleSpec selector_spec = spec; + + // Parse state information, if it exists + bool state_valid = true; + size_t state_pos = selector.find(':'); + if (state_pos != std::string::npos) { + std::string state_str = selector.substr(state_pos + 1); + selector = selector.substr(0, state_pos); + + if (state_str.empty()) { + errorstream << "Invalid style element (Invalid state): '" << element + << "'" << std::endl; + state_valid = false; + } else { + std::vector<std::string> states = split(state_str, '+'); + for (std::string &state : states) { + StyleSpec::State converted = StyleSpec::getStateByName(state); + if (converted == StyleSpec::STATE_INVALID) { + infostream << "Unknown style state " << state << + " in element '" << element << "'" << std::endl; + state_valid = false; + break; + } + + selector_spec.addState(converted); + } + } + } + + if (!state_valid) { + // Skip this selector + continue; + } + + if (style_type) { + theme_by_type[selector].push_back(selector_spec); + } else { + theme_by_name[selector].push_back(selector_spec); + } + + // Backwards-compatibility for existing _hovered/_pressed properties + if (selector_spec.hasProperty(StyleSpec::BGCOLOR_HOVERED) + || selector_spec.hasProperty(StyleSpec::BGIMG_HOVERED) + || selector_spec.hasProperty(StyleSpec::FGIMG_HOVERED)) { + StyleSpec hover_spec; + hover_spec.addState(StyleSpec::STATE_HOVERED); + + if (selector_spec.hasProperty(StyleSpec::BGCOLOR_HOVERED)) { + hover_spec.set(StyleSpec::BGCOLOR, selector_spec.get(StyleSpec::BGCOLOR_HOVERED, "")); + } + if (selector_spec.hasProperty(StyleSpec::BGIMG_HOVERED)) { + hover_spec.set(StyleSpec::BGIMG, selector_spec.get(StyleSpec::BGIMG_HOVERED, "")); + } + if (selector_spec.hasProperty(StyleSpec::FGIMG_HOVERED)) { + hover_spec.set(StyleSpec::FGIMG, selector_spec.get(StyleSpec::FGIMG_HOVERED, "")); + } + + if (style_type) { + theme_by_type[selector].push_back(hover_spec); + } else { + theme_by_name[selector].push_back(hover_spec); + } + } + if (selector_spec.hasProperty(StyleSpec::BGCOLOR_PRESSED) + || selector_spec.hasProperty(StyleSpec::BGIMG_PRESSED) + || selector_spec.hasProperty(StyleSpec::FGIMG_PRESSED)) { + StyleSpec press_spec; + press_spec.addState(StyleSpec::STATE_PRESSED); + + if (selector_spec.hasProperty(StyleSpec::BGCOLOR_PRESSED)) { + press_spec.set(StyleSpec::BGCOLOR, selector_spec.get(StyleSpec::BGCOLOR_PRESSED, "")); + } + if (selector_spec.hasProperty(StyleSpec::BGIMG_PRESSED)) { + press_spec.set(StyleSpec::BGIMG, selector_spec.get(StyleSpec::BGIMG_PRESSED, "")); + } + if (selector_spec.hasProperty(StyleSpec::FGIMG_PRESSED)) { + press_spec.set(StyleSpec::FGIMG, selector_spec.get(StyleSpec::FGIMG_PRESSED, "")); + } + + if (style_type) { + theme_by_type[selector].push_back(press_spec); + } else { + theme_by_name[selector].push_back(press_spec); + } + } + } + + return true; +} + +void GUIFormSpecMenu::parseSetFocus(const std::string &element) +{ + std::vector<std::string> parts; + if (!precheckElement("set_focus", element, 1, 2, parts)) + return; + + if (m_is_form_regenerated) + return; // Never focus on resizing + + bool force_focus = parts.size() >= 2 && is_yes(parts[1]); + if (force_focus || m_text_dst->m_formname != m_last_formname) + setFocus(parts[0]); +} + +void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element) +{ + MY_CHECKCLIENT("model"); + + std::vector<std::string> parts; + if (!precheckElement("model", element, 5, 10, parts)) + return; + + // Avoid length checks by resizing + if (parts.size() < 10) + parts.resize(10); + + std::vector<std::string> v_pos = split(parts[0], ','); + std::vector<std::string> v_geom = split(parts[1], ','); + std::string name = unescape_string(parts[2]); + std::string meshstr = unescape_string(parts[3]); + std::vector<std::string> textures = split(parts[4], ','); + std::vector<std::string> vec_rot = split(parts[5], ','); + bool inf_rotation = is_yes(parts[6]); + bool mousectrl = is_yes(parts[7]) || parts[7].empty(); // default true + std::vector<std::string> frame_loop = split(parts[8], ','); + std::string speed = unescape_string(parts[9]); + + MY_CHECKPOS("model", 0); + MY_CHECKGEOM("model", 1); + + v2s32 pos; + v2s32 geom; + + if (data->real_coordinates) { + pos = getRealCoordinateBasePos(v_pos); + geom = getRealCoordinateGeometry(v_geom); + } else { + pos = getElementBasePos(&v_pos); + geom.X = stof(v_geom[0]) * (float)imgsize.X; + geom.Y = stof(v_geom[1]) * (float)imgsize.Y; + } + + if (!data->explicit_size) + warningstream << "invalid use of model without a size[] element" << std::endl; + + scene::IAnimatedMesh *mesh = m_client->getMesh(meshstr); + + if (!mesh) { + errorstream << "Invalid model element: Unable to load mesh:" + << std::endl << "\t" << meshstr << std::endl; + return; + } + + FieldSpec spec( + name, + L"", + L"", + 258 + m_fields.size() + ); + + core::rect<s32> rect(pos, pos + geom); + + GUIScene *e = new GUIScene(Environment, m_client->getSceneManager(), + data->current_parent, rect, spec.fid); + + auto meshnode = e->setMesh(mesh); + + for (u32 i = 0; i < textures.size() && i < meshnode->getMaterialCount(); ++i) + e->setTexture(i, m_tsrc->getTexture(unescape_string(textures[i]))); + + if (vec_rot.size() >= 2) + e->setRotation(v2f(stof(vec_rot[0]), stof(vec_rot[1]))); + + e->enableContinuousRotation(inf_rotation); + e->enableMouseControl(mousectrl); + + s32 frame_loop_begin = 0; + s32 frame_loop_end = 0x7FFFFFFF; + + if (frame_loop.size() == 2) { + frame_loop_begin = stoi(frame_loop[0]); + frame_loop_end = stoi(frame_loop[1]); + } + + e->setFrameLoop(frame_loop_begin, frame_loop_end); + e->setAnimationSpeed(stof(speed)); + + auto style = getStyleForElement("model", spec.fname); + e->setStyles(style); + e->drop(); + + m_fields.push_back(spec); +} + +void GUIFormSpecMenu::parseElement(parserData* data, const std::string &element) +{ + //some prechecks + if (element.empty()) + return; + + if (parseVersionDirect(element)) + return; + + size_t pos = element.find('['); + if (pos == std::string::npos) + return; + + std::string type = trim(element.substr(0, pos)); + std::string description = element.substr(pos+1); + + if (type == "container") { + parseContainer(data, description); + return; + } + + if (type == "container_end") { + parseContainerEnd(data); + return; + } + + if (type == "list") { + parseList(data, description); + return; + } + + if (type == "listring") { + parseListRing(data, description); + return; + } + + if (type == "checkbox") { + parseCheckbox(data, description); + return; + } + + if (type == "image") { + parseImage(data, description); + return; + } + + if (type == "animated_image") { + parseAnimatedImage(data, description); + return; + } + + if (type == "item_image") { + parseItemImage(data, description); + return; + } + + if (type == "button" || type == "button_exit") { + parseButton(data, description, type); + return; + } + + if (type == "background" || type == "background9") { + parseBackground(data, description); + return; + } + + if (type == "tableoptions"){ + parseTableOptions(data,description); + return; + } + + if (type == "tablecolumns"){ + parseTableColumns(data,description); + return; + } + + if (type == "table"){ + parseTable(data,description); + return; + } + + if (type == "textlist"){ + parseTextList(data,description); + return; + } + + if (type == "dropdown"){ + parseDropDown(data,description); + return; + } + + if (type == "field_close_on_enter") { + parseFieldCloseOnEnter(data, description); + return; + } + + if (type == "pwdfield") { + parsePwdField(data,description); + return; + } + + if ((type == "field") || (type == "textarea")){ + parseField(data,description,type); + return; + } + + if (type == "hypertext") { + parseHyperText(data,description); + return; + } + + if (type == "label") { + parseLabel(data,description); + return; + } + + if (type == "vertlabel") { + parseVertLabel(data,description); + return; + } + + if (type == "item_image_button") { + parseItemImageButton(data,description); + return; + } + + if ((type == "image_button") || (type == "image_button_exit")) { + parseImageButton(data,description,type); + return; + } + + if (type == "tabheader") { + parseTabHeader(data,description); + return; + } + + if (type == "box") { + parseBox(data,description); + return; + } + + if (type == "bgcolor") { + parseBackgroundColor(data,description); + return; + } + + if (type == "listcolors") { + parseListColors(data,description); + return; + } + + if (type == "tooltip") { + parseTooltip(data,description); + return; + } + + if (type == "scrollbar") { + parseScrollBar(data, description); + return; + } + + if (type == "real_coordinates") { + data->real_coordinates = is_yes(description); + return; + } + + if (type == "style") { + parseStyle(data, description, false); + return; + } + + if (type == "style_type") { + parseStyle(data, description, true); + return; + } + + if (type == "scrollbaroptions") { + parseScrollBarOptions(data, description); + return; + } + + if (type == "scroll_container") { + parseScrollContainer(data, description); + return; + } + + if (type == "scroll_container_end") { + parseScrollContainerEnd(data); + return; + } + + if (type == "set_focus") { + parseSetFocus(description); + return; + } + + if (type == "model") { + parseModel(data, description); + return; + } + + // Ignore others + infostream << "Unknown DrawSpec: type=" << type << ", data=\"" << description << "\"" + << std::endl; +} + +void GUIFormSpecMenu::regenerateGui(v2u32 screensize) +{ + // Useless to regenerate without a screensize + if ((screensize.X <= 0) || (screensize.Y <= 0)) { + return; + } + + parserData mydata; + + // Preserve stuff only on same form, not on a new form. + if (m_text_dst->m_formname == m_last_formname) { + // Preserve tables/textlists + for (auto &m_table : m_tables) { + std::string tablename = m_table.first.fname; + GUITable *table = m_table.second; + mydata.table_dyndata[tablename] = table->getDynamicData(); + } + + // Preserve focus + gui::IGUIElement *focused_element = Environment->getFocus(); + if (focused_element && focused_element->getParent() == this) { + s32 focused_id = focused_element->getID(); + if (focused_id > 257) { + for (const GUIFormSpecMenu::FieldSpec &field : m_fields) { + if (field.fid == focused_id) { + m_focused_element = field.fname; + break; + } + } + } + } + } else { + // Don't keep old focus value + m_focused_element = ""; + } + + // Remove children + removeAllChildren(); + removeTooltip(); + + for (auto &table_it : m_tables) + table_it.second->drop(); + for (auto &inventorylist_it : m_inventorylists) + inventorylist_it->drop(); + for (auto &checkbox_it : m_checkboxes) + checkbox_it.second->drop(); + for (auto &scrollbar_it : m_scrollbars) + scrollbar_it.second->drop(); + for (auto &tooltip_rect_it : m_tooltip_rects) + tooltip_rect_it.first->drop(); + for (auto &clickthrough_it : m_clickthrough_elements) + clickthrough_it->drop(); + for (auto &scroll_container_it : m_scroll_containers) + scroll_container_it.second->drop(); + + mydata.size = v2s32(100, 100); + mydata.screensize = screensize; + mydata.offset = v2f32(0.5f, 0.5f); + mydata.anchor = v2f32(0.5f, 0.5f); + mydata.padding = v2f32(0.05f, 0.05f); + mydata.simple_field_count = 0; + + // Base position of contents of form + mydata.basepos = getBasePos(); + + // the parent for the parsed elements + mydata.current_parent = this; + + m_inventorylists.clear(); + m_tables.clear(); + m_checkboxes.clear(); + m_scrollbars.clear(); + m_fields.clear(); + m_tooltips.clear(); + m_tooltip_rects.clear(); + m_inventory_rings.clear(); + m_dropdowns.clear(); + m_scroll_containers.clear(); + theme_by_name.clear(); + theme_by_type.clear(); + m_clickthrough_elements.clear(); + field_close_on_enter.clear(); + m_dropdown_index_event.clear(); + + m_bgnonfullscreen = true; + m_bgfullscreen = false; + + m_formspec_version = 1; + + { + v3f formspec_bgcolor = g_settings->getV3F("formspec_default_bg_color"); + m_bgcolor = video::SColor( + (u8) clamp_u8(g_settings->getS32("formspec_default_bg_opacity")), + clamp_u8(myround(formspec_bgcolor.X)), + clamp_u8(myround(formspec_bgcolor.Y)), + clamp_u8(myround(formspec_bgcolor.Z)) + ); + } + + { + v3f formspec_bgcolor = g_settings->getV3F("formspec_fullscreen_bg_color"); + m_fullscreen_bgcolor = video::SColor( + (u8) clamp_u8(g_settings->getS32("formspec_fullscreen_bg_opacity")), + clamp_u8(myround(formspec_bgcolor.X)), + clamp_u8(myround(formspec_bgcolor.Y)), + clamp_u8(myround(formspec_bgcolor.Z)) + ); + } + + m_default_tooltip_bgcolor = video::SColor(255,110,130,60); + m_default_tooltip_color = video::SColor(255,255,255,255); + + // Add tooltip + { + assert(!m_tooltip_element); + // Note: parent != this so that the tooltip isn't clipped by the menu rectangle + m_tooltip_element = gui::StaticText::add(Environment, L"", + core::rect<s32>(0, 0, 110, 18)); + m_tooltip_element->enableOverrideColor(true); + m_tooltip_element->setBackgroundColor(m_default_tooltip_bgcolor); + m_tooltip_element->setDrawBackground(true); + m_tooltip_element->setDrawBorder(true); + m_tooltip_element->setOverrideColor(m_default_tooltip_color); + m_tooltip_element->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER); + m_tooltip_element->setWordWrap(false); + //we're not parent so no autograb for this one! + m_tooltip_element->grab(); + } + + std::vector<std::string> elements = split(m_formspec_string,']'); + unsigned int i = 0; + + /* try to read version from first element only */ + if (!elements.empty()) { + if (parseVersionDirect(elements[0])) { + i++; + } + } + + /* we need size first in order to calculate image scale */ + mydata.explicit_size = false; + for (; i< elements.size(); i++) { + if (!parseSizeDirect(&mydata, elements[i])) { + break; + } + } + + /* "position" element is always after "size" element if it used */ + for (; i< elements.size(); i++) { + if (!parsePositionDirect(&mydata, elements[i])) { + break; + } + } + + /* "anchor" element is always after "position" (or "size" element) if it used */ + for (; i< elements.size(); i++) { + if (!parseAnchorDirect(&mydata, elements[i])) { + break; + } + } + + /* "padding" element is always after "anchor" and previous if it is used */ + for (; i < elements.size(); i++) { + if (!parsePaddingDirect(&mydata, elements[i])) { + break; + } + } + + /* "no_prepend" element is always after "padding" and previous if it used */ + bool enable_prepends = true; + for (; i < elements.size(); i++) { + if (elements[i].empty()) + break; + + std::vector<std::string> parts = split(elements[i], '['); + if (trim(parts[0]) == "no_prepend") + enable_prepends = false; + else + break; + } + + /* Copy of the "real_coordinates" element for after the form size. */ + mydata.real_coordinates = m_formspec_version >= 2; + for (; i < elements.size(); i++) { + std::vector<std::string> parts = split(elements[i], '['); + std::string name = trim(parts[0]); + if (name != "real_coordinates" || parts.size() != 2) + break; // Invalid format + + mydata.real_coordinates = is_yes(trim(parts[1])); + } + + if (mydata.explicit_size) { + // compute scaling for specified form size + if (m_lock) { + v2u32 current_screensize = RenderingEngine::get_video_driver()->getScreenSize(); + v2u32 delta = current_screensize - m_lockscreensize; + + if (current_screensize.Y > m_lockscreensize.Y) + delta.Y /= 2; + else + delta.Y = 0; + + if (current_screensize.X > m_lockscreensize.X) + delta.X /= 2; + else + delta.X = 0; + + offset = v2s32(delta.X,delta.Y); + + mydata.screensize = m_lockscreensize; + } else { + offset = v2s32(0,0); + } + + const double gui_scaling = g_settings->getFloat("gui_scaling", 0.5f, 42.0f); + const double screen_dpi = RenderingEngine::getDisplayDensity() * 96; + + double use_imgsize; + if (m_lock) { + // In fixed-size mode, inventory image size + // is 0.53 inch multiplied by the gui_scaling + // config parameter. This magic size is chosen + // to make the main menu (15.5 inventory images + // wide, including border) just fit into the + // default window (800 pixels wide) at 96 DPI + // and default scaling (1.00). + use_imgsize = 0.5555 * screen_dpi * gui_scaling; + } else { + // Variables for the maximum imgsize that can fit in the screen. + double fitx_imgsize; + double fity_imgsize; + + v2f padded_screensize( + mydata.screensize.X * (1.0f - mydata.padding.X * 2.0f), + mydata.screensize.Y * (1.0f - mydata.padding.Y * 2.0f) + ); + + if (mydata.real_coordinates) { + fitx_imgsize = padded_screensize.X / mydata.invsize.X; + fity_imgsize = padded_screensize.Y / mydata.invsize.Y; + } else { + // The maximum imgsize in the old coordinate system also needs to + // factor in padding and spacing along with 0.1 inventory slot spare + // and help text space, hence the magic numbers. + fitx_imgsize = padded_screensize.X / + ((5.0 / 4.0) * (0.5 + mydata.invsize.X)); + fity_imgsize = padded_screensize.Y / + ((15.0 / 13.0) * (0.85 + mydata.invsize.Y)); + } + + s32 min_screen_dim = std::min(padded_screensize.X, padded_screensize.Y); + +#ifdef HAVE_TOUCHSCREENGUI + // In Android, the preferred imgsize should be larger to accommodate the + // smaller screensize. + double prefer_imgsize = min_screen_dim / 10 * gui_scaling; +#else + // Desktop computers have more space, so try to fit 15 coordinates. + double prefer_imgsize = min_screen_dim / 15 * gui_scaling; +#endif + // Try to use the preferred imgsize, but if that's bigger than the maximum + // size, use the maximum size. + use_imgsize = std::min(prefer_imgsize, + std::min(fitx_imgsize, fity_imgsize)); + } + + // Everything else is scaled in proportion to the + // inventory image size. The inventory slot spacing + // is 5/4 image size horizontally and 15/13 image size + // vertically. The padding around the form (incorporating + // the border of the outer inventory slots) is 3/8 + // image size. Font height (baseline to baseline) + // is 2/5 vertical inventory slot spacing, and button + // half-height is 7/8 of font height. + imgsize = v2s32(use_imgsize, use_imgsize); + spacing = v2f32(use_imgsize*5.0/4, use_imgsize*15.0/13); + padding = v2s32(use_imgsize*3.0/8, use_imgsize*3.0/8); + m_btn_height = use_imgsize*15.0/13 * 0.35; + + m_font = g_fontengine->getFont(); + + if (mydata.real_coordinates) { + mydata.size = v2s32( + mydata.invsize.X*imgsize.X, + mydata.invsize.Y*imgsize.Y + ); + } else { + mydata.size = v2s32( + padding.X*2+spacing.X*(mydata.invsize.X-1.0)+imgsize.X, + padding.Y*2+spacing.Y*(mydata.invsize.Y-1.0)+imgsize.Y + m_btn_height*2.0/3.0 + ); + } + + DesiredRect = mydata.rect = core::rect<s32>( + (s32)((f32)mydata.screensize.X * mydata.offset.X) - (s32)(mydata.anchor.X * (f32)mydata.size.X) + offset.X, + (s32)((f32)mydata.screensize.Y * mydata.offset.Y) - (s32)(mydata.anchor.Y * (f32)mydata.size.Y) + offset.Y, + (s32)((f32)mydata.screensize.X * mydata.offset.X) + (s32)((1.0 - mydata.anchor.X) * (f32)mydata.size.X) + offset.X, + (s32)((f32)mydata.screensize.Y * mydata.offset.Y) + (s32)((1.0 - mydata.anchor.Y) * (f32)mydata.size.Y) + offset.Y + ); + } else { + // Non-size[] form must consist only of text fields and + // implicit "Proceed" button. Use default font, and + // temporary form size which will be recalculated below. + m_font = g_fontengine->getFont(); + m_btn_height = font_line_height(m_font) * 0.875; + DesiredRect = core::rect<s32>( + (s32)((f32)mydata.screensize.X * mydata.offset.X) - (s32)(mydata.anchor.X * 580.0), + (s32)((f32)mydata.screensize.Y * mydata.offset.Y) - (s32)(mydata.anchor.Y * 300.0), + (s32)((f32)mydata.screensize.X * mydata.offset.X) + (s32)((1.0 - mydata.anchor.X) * 580.0), + (s32)((f32)mydata.screensize.Y * mydata.offset.Y) + (s32)((1.0 - mydata.anchor.Y) * 300.0) + ); + } + recalculateAbsolutePosition(false); + mydata.basepos = getBasePos(); + m_tooltip_element->setOverrideFont(m_font); + + gui::IGUISkin *skin = Environment->getSkin(); + sanity_check(skin); + gui::IGUIFont *old_font = skin->getFont(); + skin->setFont(m_font); + + // Add a new element that will hold all the background elements as its children. + // Because it is the first added element, all backgrounds will be behind all + // the other elements. + // (We use an arbitrarily big rect. The actual size is determined later by + // clipping to `this`.) + core::rect<s32> background_parent_rect(0, 0, 100000, 100000); + mydata.background_parent.reset(new gui::IGUIElement(EGUIET_ELEMENT, Environment, + this, -1, background_parent_rect)); + + pos_offset = v2f32(); + + // used for formspec versions < 3 + std::list<IGUIElement *>::iterator legacy_sort_start = std::prev(Children.end()); // last element + + if (enable_prepends) { + // Backup the coordinates so that prepends can use the coordinates of choice. + bool rc_backup = mydata.real_coordinates; + u16 version_backup = m_formspec_version; + mydata.real_coordinates = false; // Old coordinates by default. + + std::vector<std::string> prepend_elements = split(m_formspec_prepend, ']'); + for (const auto &element : prepend_elements) + parseElement(&mydata, element); + + // legacy sorting for formspec versions < 3 + if (m_formspec_version >= 3) + // prepends do not need to be reordered + legacy_sort_start = std::prev(Children.end()); // last element + else if (version_backup >= 3) + // only prepends elements have to be reordered + legacySortElements(legacy_sort_start); + + m_formspec_version = version_backup; + mydata.real_coordinates = rc_backup; // Restore coordinates + } + + for (; i< elements.size(); i++) { + parseElement(&mydata, elements[i]); + } + + if (mydata.current_parent != this) { + errorstream << "Invalid formspec string: scroll_container was never closed!" + << std::endl; + } else if (!container_stack.empty()) { + errorstream << "Invalid formspec string: container was never closed!" + << std::endl; + } + + // get the scrollbar elements for scroll_containers + for (const std::pair<std::string, GUIScrollContainer *> &c : m_scroll_containers) { + for (const std::pair<FieldSpec, GUIScrollBar *> &b : m_scrollbars) { + if (c.first == b.first.fname) { + c.second->setScrollBar(b.second); + break; + } + } + } + + // If there are fields without explicit size[], add a "Proceed" + // button and adjust size to fit all the fields. + if (mydata.simple_field_count > 0 && !mydata.explicit_size) { + mydata.rect = core::rect<s32>( + mydata.screensize.X / 2 - 580 / 2, + mydata.screensize.Y / 2 - 300 / 2, + mydata.screensize.X / 2 + 580 / 2, + mydata.screensize.Y / 2 + 240 / 2 + mydata.simple_field_count * 60 + ); + + DesiredRect = mydata.rect; + recalculateAbsolutePosition(false); + mydata.basepos = getBasePos(); + + { + v2s32 pos = mydata.basepos; + pos.Y = (mydata.simple_field_count + 2) * 60; + + v2s32 size = DesiredRect.getSize(); + mydata.rect = core::rect<s32>( + size.X / 2 - 70, pos.Y, + size.X / 2 - 70 + 140, pos.Y + m_btn_height * 2 + ); + const wchar_t *text = wgettext("Proceed"); + GUIButton::addButton(Environment, mydata.rect, m_tsrc, this, 257, text); + delete[] text; + } + } + + // Set initial focus if parser didn't set it + gui::IGUIElement *focused_element = Environment->getFocus(); + if (!focused_element + || !isMyChild(focused_element) + || focused_element->getType() == gui::EGUIET_TAB_CONTROL) + setInitialFocus(); + + skin->setFont(old_font); + + // legacy sorting + if (m_formspec_version < 3) + legacySortElements(legacy_sort_start); + + // Formname and regeneration setting + if (!m_is_form_regenerated) { + // Only set previous form name if we purposefully showed a new formspec + m_last_formname = m_text_dst->m_formname; + m_is_form_regenerated = true; + } +} + +void GUIFormSpecMenu::legacySortElements(std::list<IGUIElement *>::iterator from) +{ + /* + Draw order for formspec_version <= 2: + -3 bgcolor + -2 background + -1 box + 0 All other elements + 1 image + 2 item_image, item_image_button + 3 list + 4 label + */ + + if (from == Children.end()) + from = Children.begin(); + else + ++from; + + std::list<IGUIElement *>::iterator to = Children.end(); + // 1: Copy into a sortable container + std::vector<IGUIElement *> elements(from, to); + + // 2: Sort the container + std::stable_sort(elements.begin(), elements.end(), + [this] (const IGUIElement *a, const IGUIElement *b) -> bool { + // TODO: getSpecByID is a linear search. It should made O(1), or cached here. + const FieldSpec *spec_a = getSpecByID(a->getID()); + const FieldSpec *spec_b = getSpecByID(b->getID()); + return spec_a && spec_b && + spec_a->priority < spec_b->priority; + }); + + // 3: Re-assign the pointers + reorderChildren(from, to, elements); +} + +#ifdef __ANDROID__ +bool GUIFormSpecMenu::getAndroidUIInput() +{ + if (!hasAndroidUIInput()) + return false; + + // still waiting + if (porting::getInputDialogState() == -1) + return true; + + std::string fieldname = m_jni_field_name; + m_jni_field_name.clear(); + + for (const FieldSpec &field : m_fields) { + if (field.fname != fieldname) + continue; + + IGUIElement *element = getElementFromId(field.fid, true); + + if (!element || element->getType() != irr::gui::EGUIET_EDIT_BOX) + return false; + + std::string text = porting::getInputDialogValue(); + ((gui::IGUIEditBox *)element)->setText(utf8_to_wide(text).c_str()); + } + return false; +} +#endif + +GUIInventoryList::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const +{ + for (const GUIInventoryList *e : m_inventorylists) { + s32 item_index = e->getItemIndexAtPos(p); + if (item_index != -1) + return GUIInventoryList::ItemSpec(e->getInventoryloc(), e->getListname(), + item_index); + } + + return GUIInventoryList::ItemSpec(InventoryLocation(), "", -1); +} + +void GUIFormSpecMenu::drawSelectedItem() +{ + video::IVideoDriver* driver = Environment->getVideoDriver(); + + if (!m_selected_item) { + // reset rotation time + drawItemStack(driver, m_font, ItemStack(), + core::rect<s32>(v2s32(0, 0), v2s32(0, 0)), NULL, + m_client, IT_ROT_DRAGGED); + return; + } + + Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc); + sanity_check(inv); + InventoryList *list = inv->getList(m_selected_item->listname); + sanity_check(list); + ItemStack stack = list->getItem(m_selected_item->i); + stack.count = m_selected_amount; + + core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y); + core::rect<s32> rect = imgrect + (m_pointer - imgrect.getCenter()); + rect.constrainTo(driver->getViewPort()); + drawItemStack(driver, m_font, stack, rect, NULL, m_client, IT_ROT_DRAGGED); +} + +void GUIFormSpecMenu::drawMenu() +{ + if (m_form_src) { + const std::string &newform = m_form_src->getForm(); + if (newform != m_formspec_string) { + m_formspec_string = newform; + m_is_form_regenerated = false; + regenerateGui(m_screensize_old); + } + } + + gui::IGUISkin* skin = Environment->getSkin(); + sanity_check(skin != NULL); + gui::IGUIFont *old_font = skin->getFont(); + skin->setFont(m_font); + + m_hovered_item_tooltips.clear(); + + updateSelectedItem(); + + video::IVideoDriver* driver = Environment->getVideoDriver(); + + /* + Draw background color + */ + v2u32 screenSize = driver->getScreenSize(); + core::rect<s32> allbg(0, 0, screenSize.X, screenSize.Y); + + if (m_bgfullscreen) + driver->draw2DRectangle(m_fullscreen_bgcolor, allbg, &allbg); + if (m_bgnonfullscreen) + driver->draw2DRectangle(m_bgcolor, AbsoluteRect, &AbsoluteClippingRect); + + /* + Draw rect_mode tooltip + */ + m_tooltip_element->setVisible(false); + + for (const auto &pair : m_tooltip_rects) { + const core::rect<s32> &rect = pair.first->getAbsoluteClippingRect(); + if (rect.getArea() > 0 && rect.isPointInside(m_pointer)) { + const std::wstring &text = pair.second.tooltip; + if (!text.empty()) { + showTooltip(text, pair.second.color, pair.second.bgcolor); + break; + } + } + } + + // Some elements are only visible while being drawn + for (gui::IGUIElement *e : m_clickthrough_elements) + e->setVisible(true); + + /* + This is where all the drawing happens. + */ + for (auto child : Children) + if (child->isNotClipped() || + AbsoluteClippingRect.isRectCollided( + child->getAbsolutePosition())) + child->draw(); + + for (gui::IGUIElement *e : m_clickthrough_elements) + e->setVisible(false); + + // Draw hovered item tooltips + for (const std::string &tooltip : m_hovered_item_tooltips) { + showTooltip(utf8_to_wide(tooltip), m_default_tooltip_color, + m_default_tooltip_bgcolor); + } + + if (m_hovered_item_tooltips.empty()) { + // reset rotation time + drawItemStack(driver, m_font, ItemStack(), + core::rect<s32>(v2s32(0, 0), v2s32(0, 0)), + NULL, m_client, IT_ROT_HOVERED); + } + +/* TODO find way to show tooltips on touchscreen */ +#ifndef HAVE_TOUCHSCREENGUI + m_pointer = RenderingEngine::get_raw_device()->getCursorControl()->getPosition(); +#endif + + /* + Draw fields/buttons tooltips and update the mouse cursor + */ + gui::IGUIElement *hovered = + Environment->getRootGUIElement()->getElementFromPoint(m_pointer); + +#ifndef HAVE_TOUCHSCREENGUI + gui::ICursorControl *cursor_control = RenderingEngine::get_raw_device()-> + getCursorControl(); + gui::ECURSOR_ICON current_cursor_icon = cursor_control->getActiveIcon(); +#endif + bool hovered_element_found = false; + + if (hovered) { + if (m_show_debug) { + core::rect<s32> rect = hovered->getAbsoluteClippingRect(); + driver->draw2DRectangle(0x22FFFF00, rect, &rect); + } + + // find the formspec-element of the hovered IGUIElement (a parent) + s32 id; + for (gui::IGUIElement *hovered_fselem = hovered; hovered_fselem; + hovered_fselem = hovered_fselem->getParent()) { + id = hovered_fselem->getID(); + if (id != -1) + break; + } + + u64 delta = 0; + if (id == -1) { + m_old_tooltip_id = id; + } else { + if (id == m_old_tooltip_id) { + delta = porting::getDeltaMs(m_hovered_time, porting::getTimeMs()); + } else { + m_hovered_time = porting::getTimeMs(); + m_old_tooltip_id = id; + } + } + + // Find and update the current tooltip and cursor icon + if (id != -1) { + for (const FieldSpec &field : m_fields) { + + if (field.fid != id) + continue; + + if (delta >= m_tooltip_show_delay) { + const std::wstring &text = m_tooltips[field.fname].tooltip; + if (!text.empty()) + showTooltip(text, m_tooltips[field.fname].color, + m_tooltips[field.fname].bgcolor); + } + +#ifndef HAVE_TOUCHSCREENGUI + if (field.ftype != f_HyperText && // Handled directly in guiHyperText + current_cursor_icon != field.fcursor_icon) + cursor_control->setActiveIcon(field.fcursor_icon); +#endif + + hovered_element_found = true; + + break; + } + } + } + + if (!hovered_element_found) { + // no element is hovered +#ifndef HAVE_TOUCHSCREENGUI + if (current_cursor_icon != ECI_NORMAL) + cursor_control->setActiveIcon(ECI_NORMAL); +#endif + } + + m_tooltip_element->draw(); + + /* + Draw dragged item stack + */ + drawSelectedItem(); + + skin->setFont(old_font); +} + + +void GUIFormSpecMenu::showTooltip(const std::wstring &text, + const irr::video::SColor &color, const irr::video::SColor &bgcolor) +{ + EnrichedString ntext(text); + ntext.setDefaultColor(color); + if (!ntext.hasBackground()) + ntext.setBackground(bgcolor); + + setStaticText(m_tooltip_element, ntext); + + // Tooltip size and offset + s32 tooltip_width = m_tooltip_element->getTextWidth() + m_btn_height; + s32 tooltip_height = m_tooltip_element->getTextHeight() + 5; + + v2u32 screenSize = Environment->getVideoDriver()->getScreenSize(); + int tooltip_offset_x = m_btn_height; + int tooltip_offset_y = m_btn_height; +#ifdef HAVE_TOUCHSCREENGUI + tooltip_offset_x *= 3; + tooltip_offset_y = 0; + if (m_pointer.X > (s32)screenSize.X / 2) + tooltip_offset_x = -(tooltip_offset_x + tooltip_width); + + // Hide tooltip after ETIE_LEFT_UP + if (m_pointer.X == 0) + return; +#endif + + // Calculate and set the tooltip position + s32 tooltip_x = m_pointer.X + tooltip_offset_x; + s32 tooltip_y = m_pointer.Y + tooltip_offset_y; + if (tooltip_x + tooltip_width > (s32)screenSize.X) + tooltip_x = (s32)screenSize.X - tooltip_width - m_btn_height; + if (tooltip_y + tooltip_height > (s32)screenSize.Y) + tooltip_y = (s32)screenSize.Y - tooltip_height - m_btn_height; + + m_tooltip_element->setRelativePosition( + core::rect<s32>( + core::position2d<s32>(tooltip_x, tooltip_y), + core::dimension2d<s32>(tooltip_width, tooltip_height) + ) + ); + + // Display the tooltip + m_tooltip_element->setVisible(true); + bringToFront(m_tooltip_element); +} + +void GUIFormSpecMenu::updateSelectedItem() +{ + verifySelectedItem(); + + // If craftresult is nonempty and nothing else is selected, select it now. + if (!m_selected_item) { + for (const GUIInventoryList *e : m_inventorylists) { + if (e->getListname() != "craftpreview") + continue; + + Inventory *inv = m_invmgr->getInventory(e->getInventoryloc()); + if (!inv) + continue; + + InventoryList *list = inv->getList("craftresult"); + + if (!list || list->getSize() == 0) + continue; + + const ItemStack &item = list->getItem(0); + if (item.empty()) + continue; + + // Grab selected item from the crafting result list + m_selected_item = new GUIInventoryList::ItemSpec; + m_selected_item->inventoryloc = e->getInventoryloc(); + m_selected_item->listname = "craftresult"; + m_selected_item->i = 0; + m_selected_amount = item.count; + m_selected_dragging = false; + break; + } + } + + // If craftresult is selected, keep the whole stack selected + if (m_selected_item && m_selected_item->listname == "craftresult") + m_selected_amount = verifySelectedItem().count; +} + +ItemStack GUIFormSpecMenu::verifySelectedItem() +{ + // If the selected stack has become empty for some reason, deselect it. + // If the selected stack has become inaccessible, deselect it. + // If the selected stack has become smaller, adjust m_selected_amount. + // Return the selected stack. + + if (m_selected_item) { + if (m_selected_item->isValid()) { + Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc); + if (inv) { + InventoryList *list = inv->getList(m_selected_item->listname); + if (list && (u32) m_selected_item->i < list->getSize()) { + ItemStack stack = list->getItem(m_selected_item->i); + if (!m_selected_swap.empty()) { + if (m_selected_swap.name == stack.name && + m_selected_swap.count == stack.count) + m_selected_swap.clear(); + } else { + m_selected_amount = std::min(m_selected_amount, stack.count); + } + + if (!stack.empty()) + return stack; + } + } + } + + // selection was not valid + delete m_selected_item; + m_selected_item = nullptr; + m_selected_amount = 0; + m_selected_dragging = false; + } + return ItemStack(); +} + +void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode) +{ + if(m_text_dst) + { + StringMap fields; + + if (quitmode == quit_mode_accept) { + fields["quit"] = "true"; + } + + if (quitmode == quit_mode_cancel) { + fields["quit"] = "true"; + m_text_dst->gotText(fields); + return; + } + + if (current_keys_pending.key_down) { + fields["key_down"] = "true"; + current_keys_pending.key_down = false; + } + + if (current_keys_pending.key_up) { + fields["key_up"] = "true"; + current_keys_pending.key_up = false; + } + + if (current_keys_pending.key_enter) { + fields["key_enter"] = "true"; + current_keys_pending.key_enter = false; + } + + if (!current_field_enter_pending.empty()) { + fields["key_enter_field"] = current_field_enter_pending; + current_field_enter_pending = ""; + } + + if (current_keys_pending.key_escape) { + fields["key_escape"] = "true"; + current_keys_pending.key_escape = false; + } + + for (const GUIFormSpecMenu::FieldSpec &s : m_fields) { + if (s.send) { + std::string name = s.fname; + if (s.ftype == f_Button) { + fields[name] = wide_to_utf8(s.flabel); + } else if (s.ftype == f_Table) { + GUITable *table = getTable(s.fname); + if (table) { + fields[name] = table->checkEvent(); + } + } else if (s.ftype == f_DropDown) { + // No dynamic cast possible due to some distributions shipped + // without rtti support in Irrlicht + IGUIElement *element = getElementFromId(s.fid, true); + gui::IGUIComboBox *e = NULL; + if ((element) && (element->getType() == gui::EGUIET_COMBO_BOX)) { + e = static_cast<gui::IGUIComboBox *>(element); + } else { + warningstream << "GUIFormSpecMenu::acceptInput: dropdown " + << "field without dropdown element" << std::endl; + continue; + } + s32 selected = e->getSelected(); + if (selected >= 0) { + if (m_dropdown_index_event.find(s.fname) != + m_dropdown_index_event.end()) { + fields[name] = std::to_string(selected + 1); + } else { + std::vector<std::string> *dropdown_values = + getDropDownValues(s.fname); + if (dropdown_values && selected < (s32)dropdown_values->size()) + fields[name] = (*dropdown_values)[selected]; + } + } + } else if (s.ftype == f_TabHeader) { + // No dynamic cast possible due to some distributions shipped + // without rtti support in Irrlicht + IGUIElement *element = getElementFromId(s.fid, true); + gui::IGUITabControl *e = nullptr; + if ((element) && (element->getType() == gui::EGUIET_TAB_CONTROL)) { + e = static_cast<gui::IGUITabControl *>(element); + } + + if (e != 0) { + fields[name] = itos(e->getActiveTab() + 1); + } + } else if (s.ftype == f_CheckBox) { + // No dynamic cast possible due to some distributions shipped + // without rtti support in Irrlicht + IGUIElement *element = getElementFromId(s.fid, true); + gui::IGUICheckBox *e = nullptr; + if ((element) && (element->getType() == gui::EGUIET_CHECK_BOX)) { + e = static_cast<gui::IGUICheckBox*>(element); + } + + if (e != 0) { + if (e->isChecked()) + fields[name] = "true"; + else + fields[name] = "false"; + } + } else if (s.ftype == f_ScrollBar) { + // No dynamic cast possible due to some distributions shipped + // without rtti support in Irrlicht + IGUIElement *element = getElementFromId(s.fid, true); + GUIScrollBar *e = nullptr; + if (element && element->getType() == gui::EGUIET_ELEMENT) + e = static_cast<GUIScrollBar *>(element); + + if (e) { + if (s.fdefault == L"Changed") + fields[name] = "CHG:" + itos(e->getPos()); + else + fields[name] = "VAL:" + itos(e->getPos()); + } + } else if (s.ftype == f_AnimatedImage) { + // No dynamic cast possible due to some distributions shipped + // without rtti support in Irrlicht + IGUIElement *element = getElementFromId(s.fid, true); + GUIAnimatedImage *e = nullptr; + if (element && element->getType() == gui::EGUIET_ELEMENT) + e = static_cast<GUIAnimatedImage *>(element); + + if (e) + fields[name] = std::to_string(e->getFrameIndex() + 1); + } else { + IGUIElement *e = getElementFromId(s.fid, true); + if (e) + fields[name] = wide_to_utf8(e->getText()); + } + } + } + + m_text_dst->gotText(fields); + } +} + +bool GUIFormSpecMenu::preprocessEvent(const SEvent& event) +{ + // The IGUITabControl renders visually using the skin's selected + // font, which we override for the duration of form drawing, + // but computes tab hotspots based on how it would have rendered + // using the font that is selected at the time of button release. + // To make these two consistent, temporarily override the skin's + // font while the IGUITabControl is processing the event. + if (event.EventType == EET_MOUSE_INPUT_EVENT && + event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) { + s32 x = event.MouseInput.X; + s32 y = event.MouseInput.Y; + gui::IGUIElement *hovered = + Environment->getRootGUIElement()->getElementFromPoint( + core::position2d<s32>(x, y)); + if (hovered && isMyChild(hovered) && + hovered->getType() == gui::EGUIET_TAB_CONTROL) { + gui::IGUISkin* skin = Environment->getSkin(); + sanity_check(skin != NULL); + gui::IGUIFont *old_font = skin->getFont(); + skin->setFont(m_font); + bool retval = hovered->OnEvent(event); + skin->setFont(old_font); + return retval; + } + } + + // Fix Esc/Return key being eaten by checkboxen and tables + if (event.EventType == EET_KEY_INPUT_EVENT) { + KeyPress kp(event.KeyInput); + if (kp == EscapeKey || kp == CancelKey + || kp == getKeySetting("keymap_inventory") + || event.KeyInput.Key==KEY_RETURN) { + gui::IGUIElement *focused = Environment->getFocus(); + if (focused && isMyChild(focused) && + (focused->getType() == gui::EGUIET_LIST_BOX || + focused->getType() == gui::EGUIET_CHECK_BOX) && + (focused->getParent()->getType() != gui::EGUIET_COMBO_BOX || + event.KeyInput.Key != KEY_RETURN)) { + OnEvent(event); + return true; + } + } + } + // Mouse wheel and move events: send to hovered element instead of focused + if (event.EventType == EET_MOUSE_INPUT_EVENT && + (event.MouseInput.Event == EMIE_MOUSE_WHEEL || + (event.MouseInput.Event == EMIE_MOUSE_MOVED && + event.MouseInput.ButtonStates == 0))) { + s32 x = event.MouseInput.X; + s32 y = event.MouseInput.Y; + gui::IGUIElement *hovered = + Environment->getRootGUIElement()->getElementFromPoint( + core::position2d<s32>(x, y)); + if (hovered && isMyChild(hovered)) { + hovered->OnEvent(event); + return event.MouseInput.Event == EMIE_MOUSE_WHEEL; + } + } + + if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT) { + /* TODO add a check like: + if (event.JoystickEvent != joystick_we_listen_for) + return false; + */ + bool handled = m_joystick->handleEvent(event.JoystickEvent); + if (handled) { + if (m_joystick->wasKeyDown(KeyType::ESC)) { + tryClose(); + } else if (m_joystick->wasKeyDown(KeyType::JUMP)) { + if (m_allowclose) { + acceptInput(quit_mode_accept); + quitMenu(); + } + } + } + return handled; + } + + return GUIModalMenu::preprocessEvent(event); +} + +void GUIFormSpecMenu::tryClose() +{ + if (m_allowclose) { + doPause = false; + acceptInput(quit_mode_cancel); + quitMenu(); + } else { + m_text_dst->gotText(L"MenuQuit"); + } +} + +enum ButtonEventType : u8 +{ + BET_LEFT, + BET_RIGHT, + BET_MIDDLE, + BET_WHEEL_UP, + BET_WHEEL_DOWN, + BET_UP, + BET_DOWN, + BET_MOVE, + BET_OTHER +}; + +bool GUIFormSpecMenu::OnEvent(const SEvent& event) +{ + if (event.EventType==EET_KEY_INPUT_EVENT) { + KeyPress kp(event.KeyInput); + if (event.KeyInput.PressedDown && ( + (kp == EscapeKey) || (kp == CancelKey) || + ((m_client != NULL) && (kp == getKeySetting("keymap_inventory"))))) { + tryClose(); + return true; + } + + if (m_client != NULL && event.KeyInput.PressedDown && + (kp == getKeySetting("keymap_screenshot"))) { + m_client->makeScreenshot(); + } + + if (event.KeyInput.PressedDown && kp == getKeySetting("keymap_toggle_debug")) + m_show_debug = !m_show_debug; + + if (event.KeyInput.PressedDown && + (event.KeyInput.Key==KEY_RETURN || + event.KeyInput.Key==KEY_UP || + event.KeyInput.Key==KEY_DOWN) + ) { + switch (event.KeyInput.Key) { + case KEY_RETURN: + current_keys_pending.key_enter = true; + break; + case KEY_UP: + current_keys_pending.key_up = true; + break; + case KEY_DOWN: + current_keys_pending.key_down = true; + break; + break; + default: + //can't happen at all! + FATAL_ERROR("Reached a source line that can't ever been reached"); + break; + } + if (current_keys_pending.key_enter && m_allowclose) { + acceptInput(quit_mode_accept); + quitMenu(); + } else { + acceptInput(); + } + return true; + } + + } + + /* Mouse event other than movement, or crossing the border of inventory + field while holding right mouse button + */ + if (event.EventType == EET_MOUSE_INPUT_EVENT && + (event.MouseInput.Event != EMIE_MOUSE_MOVED || + (event.MouseInput.Event == EMIE_MOUSE_MOVED && + event.MouseInput.isRightPressed() && + getItemAtPos(m_pointer).i != getItemAtPos(m_old_pointer).i))) { + + // Get selected item and hovered/clicked item (s) + + m_old_tooltip_id = -1; + updateSelectedItem(); + GUIInventoryList::ItemSpec s = getItemAtPos(m_pointer); + + Inventory *inv_selected = NULL; + Inventory *inv_s = NULL; + InventoryList *list_s = NULL; + + if (m_selected_item) { + inv_selected = m_invmgr->getInventory(m_selected_item->inventoryloc); + sanity_check(inv_selected); + sanity_check(inv_selected->getList(m_selected_item->listname) != NULL); + } + + u32 s_count = 0; + + if (s.isValid()) + do { // breakable + inv_s = m_invmgr->getInventory(s.inventoryloc); + + if (!inv_s) { + errorstream << "InventoryMenu: The selected inventory location " + << "\"" << s.inventoryloc.dump() << "\" doesn't exist" + << std::endl; + s.i = -1; // make it invalid again + break; + } + + list_s = inv_s->getList(s.listname); + if (list_s == NULL) { + verbosestream << "InventoryMenu: The selected inventory list \"" + << s.listname << "\" does not exist" << std::endl; + s.i = -1; // make it invalid again + break; + } + + if ((u32)s.i >= list_s->getSize()) { + infostream << "InventoryMenu: The selected inventory list \"" + << s.listname << "\" is too small (i=" << s.i << ", size=" + << list_s->getSize() << ")" << std::endl; + s.i = -1; // make it invalid again + break; + } + + s_count = list_s->getItem(s.i).count; + } while(0); + + bool identical = m_selected_item && s.isValid() && + (inv_selected == inv_s) && + (m_selected_item->listname == s.listname) && + (m_selected_item->i == s.i); + + ButtonEventType button = BET_LEFT; + ButtonEventType updown = BET_OTHER; + switch (event.MouseInput.Event) { + case EMIE_LMOUSE_PRESSED_DOWN: + button = BET_LEFT; updown = BET_DOWN; + break; + case EMIE_RMOUSE_PRESSED_DOWN: + button = BET_RIGHT; updown = BET_DOWN; + break; + case EMIE_MMOUSE_PRESSED_DOWN: + button = BET_MIDDLE; updown = BET_DOWN; + break; + case EMIE_MOUSE_WHEEL: + button = (event.MouseInput.Wheel > 0) ? + BET_WHEEL_UP : BET_WHEEL_DOWN; + updown = BET_DOWN; + break; + case EMIE_LMOUSE_LEFT_UP: + button = BET_LEFT; updown = BET_UP; + break; + case EMIE_RMOUSE_LEFT_UP: + button = BET_RIGHT; updown = BET_UP; + break; + case EMIE_MMOUSE_LEFT_UP: + button = BET_MIDDLE; updown = BET_UP; + break; + case EMIE_MOUSE_MOVED: + updown = BET_MOVE; + break; + default: + break; + } + + // Set this number to a positive value to generate a move action + // from m_selected_item to s. + u32 move_amount = 0; + + // Set this number to a positive value to generate a move action + // from s to the next inventory ring. + u32 shift_move_amount = 0; + + // Set this number to a positive value to generate a drop action + // from m_selected_item. + u32 drop_amount = 0; + + // Set this number to a positive value to generate a craft action at s. + u32 craft_amount = 0; + + switch (updown) { + case BET_DOWN: + // Some mouse button has been pressed + + //infostream << "Mouse button " << button << " pressed at p=(" + // << event.MouseInput.X << "," << event.MouseInput.Y << ")" + // << std::endl; + + m_selected_dragging = false; + + if (s.isValid() && s.listname == "craftpreview") { + // Craft preview has been clicked: craft + craft_amount = (button == BET_MIDDLE ? 10 : 1); + } else if (!m_selected_item) { + if (s_count && button != BET_WHEEL_UP) { + // Non-empty stack has been clicked: select or shift-move it + m_selected_item = new GUIInventoryList::ItemSpec(s); + + u32 count; + if (button == BET_RIGHT) + count = (s_count + 1) / 2; + else if (button == BET_MIDDLE) + count = MYMIN(s_count, 10); + else if (button == BET_WHEEL_DOWN) + count = 1; + else // left + count = s_count; + + if (!event.MouseInput.Shift) { + // no shift: select item + m_selected_amount = count; + m_selected_dragging = button != BET_WHEEL_DOWN; + m_auto_place = false; + } else { + // shift pressed: move item, right click moves 1 + shift_move_amount = button == BET_RIGHT ? 1 : count; + } + } + } else { // m_selected_item != NULL + assert(m_selected_amount >= 1); + + if (s.isValid()) { + // Clicked a slot: move + if (button == BET_RIGHT || button == BET_WHEEL_UP) + move_amount = 1; + else if (button == BET_MIDDLE) + move_amount = MYMIN(m_selected_amount, 10); + else if (button == BET_LEFT) + move_amount = m_selected_amount; + // else wheeldown + + if (identical) { + if (button == BET_WHEEL_DOWN) { + if (m_selected_amount < s_count) + ++m_selected_amount; + } else { + if (move_amount >= m_selected_amount) + m_selected_amount = 0; + else + m_selected_amount -= move_amount; + move_amount = 0; + } + } + } else if (!getAbsoluteClippingRect().isPointInside(m_pointer) + && button != BET_WHEEL_DOWN) { + // Clicked outside of the window: drop + if (button == BET_RIGHT || button == BET_WHEEL_UP) + drop_amount = 1; + else if (button == BET_MIDDLE) + drop_amount = MYMIN(m_selected_amount, 10); + else // left + drop_amount = m_selected_amount; + } + } + break; + case BET_UP: + // Some mouse button has been released + + //infostream<<"Mouse button "<<button<<" released at p=(" + // <<p.X<<","<<p.Y<<")"<<std::endl; + + if (m_selected_dragging && m_selected_item) { + if (s.isValid()) { + if (!identical) { + // Dragged to different slot: move all selected + move_amount = m_selected_amount; + } + } else if (!getAbsoluteClippingRect().isPointInside(m_pointer)) { + // Dragged outside of window: drop all selected + drop_amount = m_selected_amount; + } + } + + m_selected_dragging = false; + // Keep track of whether the mouse button be released + // One click is drag without dropping. Click + release + // + click changes to drop item when moved mode + if (m_selected_item) + m_auto_place = true; + break; + case BET_MOVE: + // Mouse has been moved and rmb is down and mouse pointer just + // entered a new inventory field (checked in the entry-if, this + // is the only action here that is generated by mouse movement) + if (m_selected_item && s.isValid() && s.listname != "craftpreview") { + // Move 1 item + // TODO: middle mouse to move 10 items might be handy + if (m_auto_place) { + // Only move an item if the destination slot is empty + // or contains the same item type as what is going to be + // moved + InventoryList *list_from = inv_selected->getList(m_selected_item->listname); + InventoryList *list_to = list_s; + assert(list_from && list_to); + ItemStack stack_from = list_from->getItem(m_selected_item->i); + ItemStack stack_to = list_to->getItem(s.i); + if (stack_to.empty() || stack_to.name == stack_from.name) + move_amount = 1; + } + } + break; + default: + break; + } + + // Possibly send inventory action to server + if (move_amount > 0) { + // Send IAction::Move + + assert(m_selected_item && m_selected_item->isValid()); + assert(s.isValid()); + + assert(inv_selected && inv_s); + InventoryList *list_from = inv_selected->getList(m_selected_item->listname); + InventoryList *list_to = list_s; + assert(list_from && list_to); + ItemStack stack_from = list_from->getItem(m_selected_item->i); + ItemStack stack_to = list_to->getItem(s.i); + + // Check how many items can be moved + move_amount = stack_from.count = MYMIN(move_amount, stack_from.count); + ItemStack leftover = stack_to.addItem(stack_from, m_client->idef()); + bool move = true; + // If source stack cannot be added to destination stack at all, + // they are swapped + if (leftover.count == stack_from.count && + leftover.name == stack_from.name) { + + if (m_selected_swap.empty()) { + m_selected_amount = stack_to.count; + m_selected_dragging = false; + + // WARNING: BLACK MAGIC, BUT IN A REDUCED SET + // Skip next validation checks due async inventory calls + m_selected_swap = stack_to; + } else { + move = false; + } + } + // Source stack goes fully into destination stack + else if (leftover.empty()) { + m_selected_amount -= move_amount; + } + // Source stack goes partly into destination stack + else { + move_amount -= leftover.count; + m_selected_amount -= move_amount; + } + + if (move) { + infostream << "Handing IAction::Move to manager" << std::endl; + IMoveAction *a = new IMoveAction(); + a->count = move_amount; + a->from_inv = m_selected_item->inventoryloc; + a->from_list = m_selected_item->listname; + a->from_i = m_selected_item->i; + a->to_inv = s.inventoryloc; + a->to_list = s.listname; + a->to_i = s.i; + m_invmgr->inventoryAction(a); + } + } else if (shift_move_amount > 0) { + u32 mis = m_inventory_rings.size(); + u32 i = 0; + for (; i < mis; i++) { + const ListRingSpec &sp = m_inventory_rings[i]; + if (sp.inventoryloc == s.inventoryloc + && sp.listname == s.listname) + break; + } + do { + if (i >= mis) // if not found + break; + u32 to_inv_ind = (i + 1) % mis; + const ListRingSpec &to_inv_sp = m_inventory_rings[to_inv_ind]; + InventoryList *list_from = list_s; + if (!s.isValid()) + break; + Inventory *inv_to = m_invmgr->getInventory(to_inv_sp.inventoryloc); + if (!inv_to) + break; + InventoryList *list_to = inv_to->getList(to_inv_sp.listname); + if (!list_to) + break; + ItemStack stack_from = list_from->getItem(s.i); + assert(shift_move_amount <= stack_from.count); + + infostream << "Handing IAction::Move to manager" << std::endl; + IMoveAction *a = new IMoveAction(); + a->count = shift_move_amount; + a->from_inv = s.inventoryloc; + a->from_list = s.listname; + a->from_i = s.i; + a->to_inv = to_inv_sp.inventoryloc; + a->to_list = to_inv_sp.listname; + a->move_somewhere = true; + m_invmgr->inventoryAction(a); + } while (0); + } else if (drop_amount > 0) { + // Send IAction::Drop + + assert(m_selected_item && m_selected_item->isValid()); + assert(inv_selected); + InventoryList *list_from = inv_selected->getList(m_selected_item->listname); + assert(list_from); + ItemStack stack_from = list_from->getItem(m_selected_item->i); + + // Check how many items can be dropped + drop_amount = stack_from.count = MYMIN(drop_amount, stack_from.count); + assert(drop_amount > 0 && drop_amount <= m_selected_amount); + m_selected_amount -= drop_amount; + + infostream << "Handing IAction::Drop to manager" << std::endl; + IDropAction *a = new IDropAction(); + a->count = drop_amount; + a->from_inv = m_selected_item->inventoryloc; + a->from_list = m_selected_item->listname; + a->from_i = m_selected_item->i; + m_invmgr->inventoryAction(a); + } else if (craft_amount > 0) { + assert(s.isValid()); + + // if there are no items selected or the selected item + // belongs to craftresult list, proceed with crafting + if (!m_selected_item || + !m_selected_item->isValid() || m_selected_item->listname == "craftresult") { + + assert(inv_s); + + // Send IACTION_CRAFT + infostream << "Handing IACTION_CRAFT to manager" << std::endl; + ICraftAction *a = new ICraftAction(); + a->count = craft_amount; + a->craft_inv = s.inventoryloc; + m_invmgr->inventoryAction(a); + } + } + + // If m_selected_amount has been decreased to zero, deselect + if (m_selected_amount == 0) { + m_selected_swap.clear(); + delete m_selected_item; + m_selected_item = nullptr; + m_selected_amount = 0; + m_selected_dragging = false; + } + m_old_pointer = m_pointer; + } + + if (event.EventType == EET_GUI_EVENT) { + if (event.GUIEvent.EventType == gui::EGET_TAB_CHANGED + && isVisible()) { + // find the element that was clicked + for (GUIFormSpecMenu::FieldSpec &s : m_fields) { + if ((s.ftype == f_TabHeader) && + (s.fid == event.GUIEvent.Caller->getID())) { + if (!s.sound.empty() && m_sound_manager) + m_sound_manager->playSound(SimpleSoundSpec(s.sound, 1.0f)); + s.send = true; + acceptInput(); + s.send = false; + return true; + } + } + } + if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST + && isVisible()) { + if (!canTakeFocus(event.GUIEvent.Element)) { + infostream<<"GUIFormSpecMenu: Not allowing focus change." + <<std::endl; + // Returning true disables focus change + return true; + } + } + if ((event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) || + (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED) || + (event.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED) || + (event.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED)) { + s32 caller_id = event.GUIEvent.Caller->getID(); + + if (caller_id == 257) { + if (m_allowclose) { + acceptInput(quit_mode_accept); + quitMenu(); + } else { + acceptInput(); + m_text_dst->gotText(L"ExitButton"); + } + // quitMenu deallocates menu + return true; + } + + // find the element that was clicked + for (GUIFormSpecMenu::FieldSpec &s : m_fields) { + // if its a button, set the send field so + // lua knows which button was pressed + + if (caller_id != s.fid) + continue; + + if (s.ftype == f_Button || s.ftype == f_CheckBox) { + if (!s.sound.empty() && m_sound_manager) + m_sound_manager->playSound(SimpleSoundSpec(s.sound, 1.0f)); + + s.send = true; + if (s.is_exit) { + if (m_allowclose) { + acceptInput(quit_mode_accept); + quitMenu(); + } else { + m_text_dst->gotText(L"ExitButton"); + } + return true; + } + + acceptInput(quit_mode_no); + s.send = false; + return true; + + } else if (s.ftype == f_DropDown) { + // only send the changed dropdown + for (GUIFormSpecMenu::FieldSpec &s2 : m_fields) { + if (s2.ftype == f_DropDown) { + s2.send = false; + } + } + if (!s.sound.empty() && m_sound_manager) + m_sound_manager->playSound(SimpleSoundSpec(s.sound, 1.0f)); + s.send = true; + acceptInput(quit_mode_no); + + // revert configuration to make sure dropdowns are sent on + // regular button click + for (GUIFormSpecMenu::FieldSpec &s2 : m_fields) { + if (s2.ftype == f_DropDown) { + s2.send = true; + } + } + return true; + } else if (s.ftype == f_ScrollBar) { + s.fdefault = L"Changed"; + acceptInput(quit_mode_no); + s.fdefault = L""; + } else if (s.ftype == f_Unknown || s.ftype == f_HyperText) { + if (!s.sound.empty() && m_sound_manager) + m_sound_manager->playSound(SimpleSoundSpec(s.sound, 1.0f)); + s.send = true; + acceptInput(); + s.send = false; + } + } + } + + if (event.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED) { + // move scroll_containers + for (const std::pair<std::string, GUIScrollContainer *> &c : m_scroll_containers) + c.second->onScrollEvent(event.GUIEvent.Caller); + } + + if (event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) { + if (event.GUIEvent.Caller->getID() > 257) { + bool close_on_enter = true; + for (GUIFormSpecMenu::FieldSpec &s : m_fields) { + if (s.ftype == f_Unknown && + s.fid == event.GUIEvent.Caller->getID()) { + current_field_enter_pending = s.fname; + std::unordered_map<std::string, bool>::const_iterator it = + field_close_on_enter.find(s.fname); + if (it != field_close_on_enter.end()) + close_on_enter = (*it).second; + + break; + } + } + + if (m_allowclose && close_on_enter) { + current_keys_pending.key_enter = true; + acceptInput(quit_mode_accept); + quitMenu(); + } else { + current_keys_pending.key_enter = true; + acceptInput(); + } + // quitMenu deallocates menu + return true; + } + } + + if (event.GUIEvent.EventType == gui::EGET_TABLE_CHANGED) { + int current_id = event.GUIEvent.Caller->getID(); + if (current_id > 257) { + // find the element that was clicked + for (GUIFormSpecMenu::FieldSpec &s : m_fields) { + // if it's a table, set the send field + // so lua knows which table was changed + if ((s.ftype == f_Table) && (s.fid == current_id)) { + s.send = true; + acceptInput(); + s.send=false; + } + } + return true; + } + } + } + + return Parent ? Parent->OnEvent(event) : false; +} + +/** + * get name of element by element id + * @param id of element + * @return name string or empty string + */ +std::string GUIFormSpecMenu::getNameByID(s32 id) +{ + for (FieldSpec &spec : m_fields) { + if (spec.fid == id) + return spec.fname; + } + return ""; +} + + +const GUIFormSpecMenu::FieldSpec *GUIFormSpecMenu::getSpecByID(s32 id) +{ + for (FieldSpec &spec : m_fields) { + if (spec.fid == id) + return &spec; + } + return nullptr; +} + +/** + * get label of element by id + * @param id of element + * @return label string or empty string + */ +std::wstring GUIFormSpecMenu::getLabelByID(s32 id) +{ + for (FieldSpec &spec : m_fields) { + if (spec.fid == id) + return spec.flabel; + } + return L""; +} + +StyleSpec GUIFormSpecMenu::getDefaultStyleForElement(const std::string &type, + const std::string &name, const std::string &parent_type) { + return getStyleForElement(type, name, parent_type)[StyleSpec::STATE_DEFAULT]; +} + +std::array<StyleSpec, StyleSpec::NUM_STATES> GUIFormSpecMenu::getStyleForElement( + const std::string &type, const std::string &name, const std::string &parent_type) +{ + std::array<StyleSpec, StyleSpec::NUM_STATES> ret; + + auto it = theme_by_type.find("*"); + if (it != theme_by_type.end()) { + for (const StyleSpec &spec : it->second) + ret[(u32)spec.getState()] |= spec; + } + + it = theme_by_name.find("*"); + if (it != theme_by_name.end()) { + for (const StyleSpec &spec : it->second) + ret[(u32)spec.getState()] |= spec; + } + + if (!parent_type.empty()) { + it = theme_by_type.find(parent_type); + if (it != theme_by_type.end()) { + for (const StyleSpec &spec : it->second) + ret[(u32)spec.getState()] |= spec; + } + } + + it = theme_by_type.find(type); + if (it != theme_by_type.end()) { + for (const StyleSpec &spec : it->second) + ret[(u32)spec.getState()] |= spec; + } + + it = theme_by_name.find(name); + if (it != theme_by_name.end()) { + for (const StyleSpec &spec : it->second) + ret[(u32)spec.getState()] |= spec; + } + + return ret; +} diff --git a/src/gui/guiFormSpecMenu.h b/src/gui/guiFormSpecMenu.h new file mode 100644 index 0000000..c01ff81 --- /dev/null +++ b/src/gui/guiFormSpecMenu.h @@ -0,0 +1,499 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <utility> +#include <stack> +#include <unordered_set> + +#include "irrlichttypes_extrabloated.h" +#include "irr_ptr.h" +#include "inventorymanager.h" +#include "modalMenu.h" +#include "guiInventoryList.h" +#include "guiScrollBar.h" +#include "guiTable.h" +#include "network/networkprotocol.h" +#include "client/joystick_controller.h" +#include "util/string.h" +#include "util/enriched_string.h" +#include "StyleSpec.h" + +class InventoryManager; +class ISimpleTextureSource; +class Client; +class GUIScrollContainer; +class ISoundManager; + +enum FormspecFieldType { + f_Button, + f_Table, + f_TabHeader, + f_CheckBox, + f_DropDown, + f_ScrollBar, + f_Box, + f_ItemImage, + f_HyperText, + f_AnimatedImage, + f_Unknown +}; + +enum FormspecQuitMode { + quit_mode_no, + quit_mode_accept, + quit_mode_cancel +}; + +struct TextDest +{ + virtual ~TextDest() = default; + + // This is deprecated I guess? -celeron55 + virtual void gotText(const std::wstring &text) {} + virtual void gotText(const StringMap &fields) = 0; + + std::string m_formname; +}; + +class IFormSource +{ +public: + virtual ~IFormSource() = default; + virtual const std::string &getForm() const = 0; + // Fill in variables in field text + virtual std::string resolveText(const std::string &str) { return str; } +}; + +class GUIFormSpecMenu : public GUIModalMenu +{ + struct ListRingSpec + { + ListRingSpec() = default; + + ListRingSpec(const InventoryLocation &a_inventoryloc, + const std::string &a_listname): + inventoryloc(a_inventoryloc), + listname(a_listname) + { + } + + InventoryLocation inventoryloc; + std::string listname; + }; + + struct FieldSpec + { + FieldSpec() = default; + + FieldSpec(const std::string &name, const std::wstring &label, + const std::wstring &default_text, s32 id, int priority = 0, + gui::ECURSOR_ICON cursor_icon = ECI_NORMAL) : + fname(name), + flabel(label), + fdefault(unescape_enriched(translate_string(default_text))), + fid(id), + send(false), + ftype(f_Unknown), + is_exit(false), + priority(priority), + fcursor_icon(cursor_icon) + { + } + + std::string fname; + std::wstring flabel; + std::wstring fdefault; + s32 fid; + bool send; + FormspecFieldType ftype; + bool is_exit; + // Draw priority for formspec version < 3 + int priority; + core::rect<s32> rect; + gui::ECURSOR_ICON fcursor_icon; + std::string sound; + }; + + struct TooltipSpec + { + TooltipSpec() = default; + TooltipSpec(const std::wstring &a_tooltip, irr::video::SColor a_bgcolor, + irr::video::SColor a_color): + tooltip(translate_string(a_tooltip)), + bgcolor(a_bgcolor), + color(a_color) + { + } + + std::wstring tooltip; + irr::video::SColor bgcolor; + irr::video::SColor color; + }; + +public: + GUIFormSpecMenu(JoystickController *joystick, + gui::IGUIElement* parent, s32 id, + IMenuManager *menumgr, + Client *client, + gui::IGUIEnvironment *guienv, + ISimpleTextureSource *tsrc, + ISoundManager *sound_manager, + IFormSource* fs_src, + TextDest* txt_dst, + const std::string &formspecPrepend, + bool remap_dbl_click = true); + + ~GUIFormSpecMenu(); + + static void create(GUIFormSpecMenu *&cur_formspec, Client *client, + gui::IGUIEnvironment *guienv, JoystickController *joystick, IFormSource *fs_src, + TextDest *txt_dest, const std::string &formspecPrepend, + ISoundManager *sound_manager); + + void setFormSpec(const std::string &formspec_string, + const InventoryLocation ¤t_inventory_location) + { + m_formspec_string = formspec_string; + m_current_inventory_location = current_inventory_location; + m_is_form_regenerated = false; + regenerateGui(m_screensize_old); + } + + const InventoryLocation &getFormspecLocation() + { + return m_current_inventory_location; + } + + void setFormspecPrepend(const std::string &formspecPrepend) + { + m_formspec_prepend = formspecPrepend; + } + + // form_src is deleted by this GUIFormSpecMenu + void setFormSource(IFormSource *form_src) + { + delete m_form_src; + m_form_src = form_src; + } + + // text_dst is deleted by this GUIFormSpecMenu + void setTextDest(TextDest *text_dst) + { + delete m_text_dst; + m_text_dst = text_dst; + } + + void allowClose(bool value) + { + m_allowclose = value; + } + + void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0)) + { + m_lock = lock; + m_lockscreensize = basescreensize; + } + + void removeTooltip(); + void setInitialFocus(); + + void setFocus(const std::string &elementname) + { + m_focused_element = elementname; + } + + Client *getClient() const + { + return m_client; + } + + const GUIInventoryList::ItemSpec *getSelectedItem() const + { + return m_selected_item; + } + + u16 getSelectedAmount() const + { + return m_selected_amount; + } + + bool doTooltipAppendItemname() const + { + return m_tooltip_append_itemname; + } + + void addHoveredItemTooltip(const std::string &name) + { + m_hovered_item_tooltips.emplace_back(name); + } + + /* + Remove and re-add (or reposition) stuff + */ + void regenerateGui(v2u32 screensize); + + GUIInventoryList::ItemSpec getItemAtPos(v2s32 p) const; + void drawSelectedItem(); + void drawMenu(); + void updateSelectedItem(); + ItemStack verifySelectedItem(); + + void acceptInput(FormspecQuitMode quitmode=quit_mode_no); + bool preprocessEvent(const SEvent& event); + bool OnEvent(const SEvent& event); + bool doPause; + bool pausesGame() { return doPause; } + + GUITable* getTable(const std::string &tablename); + std::vector<std::string>* getDropDownValues(const std::string &name); + +#ifdef __ANDROID__ + bool getAndroidUIInput(); +#endif + +protected: + v2s32 getBasePos() const + { + return padding + offset + AbsoluteRect.UpperLeftCorner; + } + std::wstring getLabelByID(s32 id); + std::string getNameByID(s32 id); + const FieldSpec *getSpecByID(s32 id); + v2s32 getElementBasePos(const std::vector<std::string> *v_pos); + v2s32 getRealCoordinateBasePos(const std::vector<std::string> &v_pos); + v2s32 getRealCoordinateGeometry(const std::vector<std::string> &v_geom); + bool precheckElement(const std::string &name, const std::string &element, + size_t args_min, size_t args_max, std::vector<std::string> &parts); + + std::unordered_map<std::string, std::vector<StyleSpec>> theme_by_type; + std::unordered_map<std::string, std::vector<StyleSpec>> theme_by_name; + std::unordered_set<std::string> property_warned; + + StyleSpec getDefaultStyleForElement(const std::string &type, + const std::string &name="", const std::string &parent_type=""); + std::array<StyleSpec, StyleSpec::NUM_STATES> getStyleForElement(const std::string &type, + const std::string &name="", const std::string &parent_type=""); + + v2s32 padding; + v2f32 spacing; + v2s32 imgsize; + v2s32 offset; + v2f32 pos_offset; + std::stack<v2f32> container_stack; + + InventoryManager *m_invmgr; + ISimpleTextureSource *m_tsrc; + ISoundManager *m_sound_manager; + Client *m_client; + + std::string m_formspec_string; + std::string m_formspec_prepend; + InventoryLocation m_current_inventory_location; + + // Default true because we can't control regeneration on resizing, but + // we can control cases when the formspec is shown intentionally. + bool m_is_form_regenerated = true; + + std::vector<GUIInventoryList *> m_inventorylists; + std::vector<ListRingSpec> m_inventory_rings; + std::unordered_map<std::string, bool> field_close_on_enter; + std::unordered_map<std::string, bool> m_dropdown_index_event; + std::vector<FieldSpec> m_fields; + std::vector<std::pair<FieldSpec, GUITable *>> m_tables; + std::vector<std::pair<FieldSpec, gui::IGUICheckBox *>> m_checkboxes; + std::map<std::string, TooltipSpec> m_tooltips; + std::vector<std::pair<gui::IGUIElement *, TooltipSpec>> m_tooltip_rects; + std::vector<std::pair<FieldSpec, GUIScrollBar *>> m_scrollbars; + std::vector<std::pair<FieldSpec, std::vector<std::string>>> m_dropdowns; + std::vector<gui::IGUIElement *> m_clickthrough_elements; + std::vector<std::pair<std::string, GUIScrollContainer *>> m_scroll_containers; + + GUIInventoryList::ItemSpec *m_selected_item = nullptr; + u16 m_selected_amount = 0; + bool m_selected_dragging = false; + ItemStack m_selected_swap; + + gui::IGUIStaticText *m_tooltip_element = nullptr; + + u64 m_tooltip_show_delay; + bool m_tooltip_append_itemname; + u64 m_hovered_time = 0; + s32 m_old_tooltip_id = -1; + + bool m_auto_place = false; + + bool m_allowclose = true; + bool m_lock = false; + v2u32 m_lockscreensize; + + bool m_bgnonfullscreen; + bool m_bgfullscreen; + video::SColor m_bgcolor; + video::SColor m_fullscreen_bgcolor; + video::SColor m_default_tooltip_bgcolor; + video::SColor m_default_tooltip_color; + +private: + IFormSource *m_form_src; + TextDest *m_text_dst; + std::string m_last_formname; + u16 m_formspec_version = 1; + std::string m_focused_element = ""; + JoystickController *m_joystick; + bool m_show_debug = false; + + struct parserData { + bool explicit_size; + bool real_coordinates; + u8 simple_field_count; + v2f invsize; + v2s32 size; + v2f32 offset; + v2f32 anchor; + v2f32 padding; + core::rect<s32> rect; + v2s32 basepos; + v2u32 screensize; + GUITable::TableOptions table_options; + GUITable::TableColumns table_columns; + gui::IGUIElement *current_parent = nullptr; + irr_ptr<gui::IGUIElement> background_parent; + + GUIInventoryList::Options inventorylist_options; + + struct { + s32 max = 1000; + s32 min = 0; + s32 small_step = 10; + s32 large_step = 100; + s32 thumb_size = 1; + GUIScrollBar::ArrowVisibility arrow_visiblity = GUIScrollBar::DEFAULT; + } scrollbar_options; + + // used to restore table selection/scroll/treeview state + std::unordered_map<std::string, GUITable::DynamicData> table_dyndata; + }; + + struct fs_key_pending { + bool key_up; + bool key_down; + bool key_enter; + bool key_escape; + }; + + fs_key_pending current_keys_pending; + std::string current_field_enter_pending = ""; + std::vector<std::string> m_hovered_item_tooltips; + + void parseElement(parserData* data, const std::string &element); + + void parseSize(parserData* data, const std::string &element); + void parseContainer(parserData* data, const std::string &element); + void parseContainerEnd(parserData* data); + void parseScrollContainer(parserData *data, const std::string &element); + void parseScrollContainerEnd(parserData *data); + void parseList(parserData* data, const std::string &element); + void parseListRing(parserData* data, const std::string &element); + void parseCheckbox(parserData* data, const std::string &element); + void parseImage(parserData* data, const std::string &element); + void parseAnimatedImage(parserData *data, const std::string &element); + void parseItemImage(parserData* data, const std::string &element); + void parseButton(parserData* data, const std::string &element, + const std::string &typ); + void parseBackground(parserData* data, const std::string &element); + void parseTableOptions(parserData* data, const std::string &element); + void parseTableColumns(parserData* data, const std::string &element); + void parseTable(parserData* data, const std::string &element); + void parseTextList(parserData* data, const std::string &element); + void parseDropDown(parserData* data, const std::string &element); + void parseFieldCloseOnEnter(parserData *data, const std::string &element); + void parsePwdField(parserData* data, const std::string &element); + void parseField(parserData* data, const std::string &element, const std::string &type); + void createTextField(parserData *data, FieldSpec &spec, + core::rect<s32> &rect, bool is_multiline); + void parseSimpleField(parserData* data,std::vector<std::string> &parts); + void parseTextArea(parserData* data,std::vector<std::string>& parts, + const std::string &type); + void parseHyperText(parserData *data, const std::string &element); + void parseLabel(parserData* data, const std::string &element); + void parseVertLabel(parserData* data, const std::string &element); + void parseImageButton(parserData* data, const std::string &element, + const std::string &type); + void parseItemImageButton(parserData* data, const std::string &element); + void parseTabHeader(parserData* data, const std::string &element); + void parseBox(parserData* data, const std::string &element); + void parseBackgroundColor(parserData* data, const std::string &element); + void parseListColors(parserData* data, const std::string &element); + void parseTooltip(parserData* data, const std::string &element); + bool parseVersionDirect(const std::string &data); + bool parseSizeDirect(parserData* data, const std::string &element); + void parseScrollBar(parserData* data, const std::string &element); + void parseScrollBarOptions(parserData *data, const std::string &element); + bool parsePositionDirect(parserData *data, const std::string &element); + void parsePosition(parserData *data, const std::string &element); + bool parseAnchorDirect(parserData *data, const std::string &element); + void parseAnchor(parserData *data, const std::string &element); + bool parsePaddingDirect(parserData *data, const std::string &element); + void parsePadding(parserData *data, const std::string &element); + bool parseStyle(parserData *data, const std::string &element, bool style_type); + void parseSetFocus(const std::string &element); + void parseModel(parserData *data, const std::string &element); + + bool parseMiddleRect(const std::string &value, core::rect<s32> *parsed_rect); + + void tryClose(); + + void showTooltip(const std::wstring &text, const irr::video::SColor &color, + const irr::video::SColor &bgcolor); + + /** + * In formspec version < 2 the elements were not ordered properly. Some element + * types were drawn before others. + * This function sorts the elements in the old order for backwards compatibility. + */ + void legacySortElements(std::list<IGUIElement *>::iterator from); + + int m_btn_height; + gui::IGUIFont *m_font = nullptr; +}; + +class FormspecFormSource: public IFormSource +{ +public: + FormspecFormSource(const std::string &formspec): + m_formspec(formspec) + { + } + + ~FormspecFormSource() = default; + + void setForm(const std::string &formspec) + { + m_formspec = formspec; + } + + const std::string &getForm() const + { + return m_formspec; + } + + std::string m_formspec; +}; diff --git a/src/gui/guiHyperText.cpp b/src/gui/guiHyperText.cpp new file mode 100644 index 0000000..40450ce --- /dev/null +++ b/src/gui/guiHyperText.cpp @@ -0,0 +1,1153 @@ +/* +Minetest +Copyright (C) 2019 EvicenceBKidscode / Pierre-Yves Rollo <dev@pyrollo.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiHyperText.h" +#include "guiScrollBar.h" +#include "client/fontengine.h" +#include "client/tile.h" +#include "IVideoDriver.h" +#include "client/client.h" +#include "client/renderingengine.h" +#include "hud.h" +#include "util/string.h" +#include "irrlicht_changes/CGUITTFont.h" + +using namespace irr::gui; + +static bool check_color(const std::string &str) +{ + irr::video::SColor color; + return parseColorString(str, color, false); +} + +static bool check_integer(const std::string &str) +{ + if (str.empty()) + return false; + + char *endptr = nullptr; + strtol(str.c_str(), &endptr, 10); + + return *endptr == '\0'; +} + +// ----------------------------------------------------------------------------- +// ParsedText - A text parser + +void ParsedText::Element::setStyle(StyleList &style) +{ + this->underline = is_yes(style["underline"]); + + video::SColor color; + + if (parseColorString(style["color"], color, false)) + this->color = color; + if (parseColorString(style["hovercolor"], color, false)) + this->hovercolor = color; + + unsigned int font_size = std::atoi(style["fontsize"].c_str()); + FontMode font_mode = FM_Standard; + if (style["fontstyle"] == "mono") + font_mode = FM_Mono; + + FontSpec spec(font_size, font_mode, + is_yes(style["bold"]), is_yes(style["italic"])); + + // TODO: find a way to check font validity + // Build a new fontengine ? + this->font = g_fontengine->getFont(spec); + + if (!this->font) + printf("No font found ! Size=%d, mode=%d, bold=%s, italic=%s\n", + font_size, font_mode, style["bold"].c_str(), + style["italic"].c_str()); +} + +void ParsedText::Paragraph::setStyle(StyleList &style) +{ + if (style["halign"] == "center") + this->halign = HALIGN_CENTER; + else if (style["halign"] == "right") + this->halign = HALIGN_RIGHT; + else if (style["halign"] == "justify") + this->halign = HALIGN_JUSTIFY; + else + this->halign = HALIGN_LEFT; +} + +ParsedText::ParsedText(const wchar_t *text) +{ + // Default style + m_root_tag.name = "root"; + m_root_tag.style["fontsize"] = "16"; + m_root_tag.style["fontstyle"] = "normal"; + m_root_tag.style["bold"] = "false"; + m_root_tag.style["italic"] = "false"; + m_root_tag.style["underline"] = "false"; + m_root_tag.style["halign"] = "left"; + m_root_tag.style["color"] = "#EEEEEE"; + m_root_tag.style["hovercolor"] = "#FF0000"; + + m_active_tags.push_front(&m_root_tag); + m_style = m_root_tag.style; + + // Default simple tags definitions + StyleList style; + + style["color"] = "#0000FF"; + style["underline"] = "true"; + m_elementtags["action"] = style; + style.clear(); + + style["bold"] = "true"; + m_elementtags["b"] = style; + style.clear(); + + style["italic"] = "true"; + m_elementtags["i"] = style; + style.clear(); + + style["underline"] = "true"; + m_elementtags["u"] = style; + style.clear(); + + style["fontstyle"] = "mono"; + m_elementtags["mono"] = style; + style.clear(); + + style["fontsize"] = m_root_tag.style["fontsize"]; + m_elementtags["normal"] = style; + style.clear(); + + style["fontsize"] = "24"; + m_elementtags["big"] = style; + style.clear(); + + style["fontsize"] = "36"; + m_elementtags["bigger"] = style; + style.clear(); + + style["halign"] = "center"; + m_paragraphtags["center"] = style; + style.clear(); + + style["halign"] = "justify"; + m_paragraphtags["justify"] = style; + style.clear(); + + style["halign"] = "left"; + m_paragraphtags["left"] = style; + style.clear(); + + style["halign"] = "right"; + m_paragraphtags["right"] = style; + style.clear(); + + m_element = NULL; + m_paragraph = NULL; + m_end_paragraph_reason = ER_NONE; + + parse(text); +} + +ParsedText::~ParsedText() +{ + for (auto &tag : m_not_root_tags) + delete tag; +} + +void ParsedText::parse(const wchar_t *text) +{ + wchar_t c; + u32 cursor = 0; + bool escape = false; + + while ((c = text[cursor]) != L'\0') { + cursor++; + + if (c == L'\r') { // Mac or Windows breaks + if (text[cursor] == L'\n') + cursor++; + // If text has begun, don't skip empty line + if (m_paragraph) { + endParagraph(ER_NEWLINE); + enterElement(ELEMENT_SEPARATOR); + } + escape = false; + continue; + } + + if (c == L'\n') { // Unix breaks + // If text has begun, don't skip empty line + if (m_paragraph) { + endParagraph(ER_NEWLINE); + enterElement(ELEMENT_SEPARATOR); + } + escape = false; + continue; + } + + if (escape) { + escape = false; + pushChar(c); + continue; + } + + if (c == L'\\') { + escape = true; + continue; + } + + // Tag check + if (c == L'<') { + u32 newcursor = parseTag(text, cursor); + if (newcursor > 0) { + cursor = newcursor; + continue; + } + } + + // Default behavior + pushChar(c); + } + + endParagraph(ER_NONE); +} + +void ParsedText::endElement() +{ + m_element = NULL; +} + +void ParsedText::endParagraph(EndReason reason) +{ + if (!m_paragraph) + return; + + EndReason previous = m_end_paragraph_reason; + m_end_paragraph_reason = reason; + if (m_empty_paragraph && (reason == ER_TAG || + (reason == ER_NEWLINE && previous == ER_TAG))) { + // Ignore last empty paragraph + m_paragraph = nullptr; + m_paragraphs.pop_back(); + return; + } + endElement(); + m_paragraph = NULL; +} + +void ParsedText::enterParagraph() +{ + if (!m_paragraph) { + m_paragraphs.emplace_back(); + m_paragraph = &m_paragraphs.back(); + m_paragraph->setStyle(m_style); + m_empty_paragraph = true; + } +} + +void ParsedText::enterElement(ElementType type) +{ + enterParagraph(); + + if (!m_element || m_element->type != type) { + m_paragraph->elements.emplace_back(); + m_element = &m_paragraph->elements.back(); + m_element->type = type; + m_element->tags = m_active_tags; + m_element->setStyle(m_style); + } +} + +void ParsedText::pushChar(wchar_t c) +{ + // New word if needed + if (c == L' ' || c == L'\t') { + if (!m_empty_paragraph) + enterElement(ELEMENT_SEPARATOR); + else + return; + } else { + m_empty_paragraph = false; + enterElement(ELEMENT_TEXT); + } + m_element->text += c; +} + +ParsedText::Tag *ParsedText::newTag(const std::string &name, const AttrsList &attrs) +{ + endElement(); + Tag *newtag = new Tag(); + newtag->name = name; + newtag->attrs = attrs; + m_not_root_tags.push_back(newtag); + return newtag; +} + +ParsedText::Tag *ParsedText::openTag(const std::string &name, const AttrsList &attrs) +{ + Tag *newtag = newTag(name, attrs); + m_active_tags.push_front(newtag); + return newtag; +} + +bool ParsedText::closeTag(const std::string &name) +{ + bool found = false; + for (auto id = m_active_tags.begin(); id != m_active_tags.end(); ++id) + if ((*id)->name == name) { + m_active_tags.erase(id); + found = true; + break; + } + return found; +} + +void ParsedText::parseGenericStyleAttr( + const std::string &name, const std::string &value, StyleList &style) +{ + // Color styles + if (name == "color" || name == "hovercolor") { + if (check_color(value)) + style[name] = value; + + // Boolean styles + } else if (name == "bold" || name == "italic" || name == "underline") { + style[name] = is_yes(value); + + } else if (name == "size") { + if (check_integer(value)) + style["fontsize"] = value; + + } else if (name == "font") { + if (value == "mono" || value == "normal") + style["fontstyle"] = value; + } +} + +void ParsedText::parseStyles(const AttrsList &attrs, StyleList &style) +{ + for (auto const &attr : attrs) + parseGenericStyleAttr(attr.first, attr.second, style); +} + +void ParsedText::globalTag(const AttrsList &attrs) +{ + for (const auto &attr : attrs) { + // Only page level style + if (attr.first == "margin") { + if (check_integer(attr.second)) + margin = stoi(attr.second.c_str()); + + } else if (attr.first == "valign") { + if (attr.second == "top") + valign = ParsedText::VALIGN_TOP; + else if (attr.second == "bottom") + valign = ParsedText::VALIGN_BOTTOM; + else if (attr.second == "middle") + valign = ParsedText::VALIGN_MIDDLE; + } else if (attr.first == "background") { + irr::video::SColor color; + if (attr.second == "none") { + background_type = BACKGROUND_NONE; + } else if (parseColorString(attr.second, color, false)) { + background_type = BACKGROUND_COLOR; + background_color = color; + } + + // Inheriting styles + + } else if (attr.first == "halign") { + if (attr.second == "left" || attr.second == "center" || + attr.second == "right" || + attr.second == "justify") + m_root_tag.style["halign"] = attr.second; + + // Generic default styles + + } else { + parseGenericStyleAttr(attr.first, attr.second, m_root_tag.style); + } + } +} + +u32 ParsedText::parseTag(const wchar_t *text, u32 cursor) +{ + // Tag name + bool end = false; + std::string name = ""; + wchar_t c = text[cursor]; + + if (c == L'/') { + end = true; + c = text[++cursor]; + if (c == L'\0') + return 0; + } + + while (c != ' ' && c != '>') { + name += c; + c = text[++cursor]; + if (c == L'\0') + return 0; + } + + // Tag attributes + AttrsList attrs; + while (c != L'>') { + std::string attr_name = ""; + core::stringw attr_val = L""; + + while (c == ' ') { + c = text[++cursor]; + if (c == L'\0' || c == L'=') + return 0; + } + + while (c != L' ' && c != L'=') { + attr_name += (char)c; + c = text[++cursor]; + if (c == L'\0' || c == L'>') + return 0; + } + + while (c == L' ') { + c = text[++cursor]; + if (c == L'\0' || c == L'>') + return 0; + } + + if (c != L'=') + return 0; + + c = text[++cursor]; + + if (c == L'\0') + return 0; + + while (c != L'>' && c != L' ') { + attr_val += c; + c = text[++cursor]; + if (c == L'\0') + return 0; + } + + attrs[attr_name] = stringw_to_utf8(attr_val); + } + + ++cursor; // Last ">" + + // Tag specific processing + StyleList style; + + if (name == "global") { + if (end) + return 0; + globalTag(attrs); + + } else if (name == "style") { + if (end) { + closeTag(name); + } else { + parseStyles(attrs, style); + openTag(name, attrs)->style = style; + } + endElement(); + } else if (name == "img" || name == "item") { + if (end) + return 0; + + // Name is a required attribute + if (!attrs.count("name")) + return 0; + + // Rotate attribute is only for <item> + if (attrs.count("rotate") && name != "item") + return 0; + + // Angle attribute is only for <item> + if (attrs.count("angle") && name != "item") + return 0; + + // Ok, element can be created + newTag(name, attrs); + + if (name == "img") + enterElement(ELEMENT_IMAGE); + else + enterElement(ELEMENT_ITEM); + + m_element->text = utf8_to_stringw(attrs["name"]); + + if (attrs.count("float")) { + if (attrs["float"] == "left") + m_element->floating = FLOAT_LEFT; + if (attrs["float"] == "right") + m_element->floating = FLOAT_RIGHT; + } + + if (attrs.count("width")) { + int width = stoi(attrs["width"]); + if (width > 0) + m_element->dim.Width = width; + } + + if (attrs.count("height")) { + int height = stoi(attrs["height"]); + if (height > 0) + m_element->dim.Height = height; + } + + if (attrs.count("angle")) { + std::string str = attrs["angle"]; + std::vector<std::string> parts = split(str, ','); + if (parts.size() == 3) { + m_element->angle = v3s16( + rangelim(stoi(parts[0]), -180, 180), + rangelim(stoi(parts[1]), -180, 180), + rangelim(stoi(parts[2]), -180, 180)); + m_element->rotation = v3s16(0, 0, 0); + } + } + + if (attrs.count("rotate")) { + if (attrs["rotate"] == "yes") { + m_element->rotation = v3s16(0, 100, 0); + } else { + std::string str = attrs["rotate"]; + std::vector<std::string> parts = split(str, ','); + if (parts.size() == 3) { + m_element->rotation = v3s16 ( + rangelim(stoi(parts[0]), -1000, 1000), + rangelim(stoi(parts[1]), -1000, 1000), + rangelim(stoi(parts[2]), -1000, 1000)); + } + } + } + + endElement(); + + } else if (name == "tag") { + // Required attributes + if (!attrs.count("name")) + return 0; + + StyleList tagstyle; + parseStyles(attrs, tagstyle); + + if (is_yes(attrs["paragraph"])) + m_paragraphtags[attrs["name"]] = tagstyle; + else + m_elementtags[attrs["name"]] = tagstyle; + + } else if (name == "action") { + if (end) { + closeTag(name); + } else { + if (!attrs.count("name")) + return 0; + openTag(name, attrs)->style = m_elementtags["action"]; + } + + } else if (m_elementtags.count(name)) { + if (end) { + closeTag(name); + } else { + openTag(name, attrs)->style = m_elementtags[name]; + } + endElement(); + + } else if (m_paragraphtags.count(name)) { + if (end) { + closeTag(name); + } else { + openTag(name, attrs)->style = m_paragraphtags[name]; + } + endParagraph(ER_TAG); + + } else + return 0; // Unknown tag + + // Update styles accordingly + m_style.clear(); + for (auto tag = m_active_tags.crbegin(); tag != m_active_tags.crend(); ++tag) + for (const auto &prop : (*tag)->style) + m_style[prop.first] = prop.second; + + return cursor; +} + +// ----------------------------------------------------------------------------- +// Text Drawer + +TextDrawer::TextDrawer(const wchar_t *text, Client *client, + gui::IGUIEnvironment *environment, ISimpleTextureSource *tsrc) : + m_text(text), + m_client(client), m_environment(environment) +{ + // Size all elements + for (auto &p : m_text.m_paragraphs) { + for (auto &e : p.elements) { + switch (e.type) { + case ParsedText::ELEMENT_SEPARATOR: + case ParsedText::ELEMENT_TEXT: + if (e.font) { + e.dim.Width = e.font->getDimension(e.text.c_str()).Width; + e.dim.Height = e.font->getDimension(L"Yy").Height; + if (e.font->getType() == irr::gui::EGFT_CUSTOM) { + CGUITTFont *tmp = static_cast<CGUITTFont*>(e.font); + e.baseline = e.dim.Height - 1 - tmp->getAscender() / 64; + } + } else { + e.dim = {0, 0}; + } + break; + + case ParsedText::ELEMENT_IMAGE: + case ParsedText::ELEMENT_ITEM: + // Resize only non sized items + if (e.dim.Height != 0 && e.dim.Width != 0) + break; + + // Default image and item size + core::dimension2d<u32> dim(80, 80); + + if (e.type == ParsedText::ELEMENT_IMAGE) { + video::ITexture *texture = + m_client->getTextureSource()-> + getTexture(stringw_to_utf8(e.text)); + if (texture) + dim = texture->getOriginalSize(); + } + + if (e.dim.Height == 0) + if (e.dim.Width == 0) + e.dim = dim; + else + e.dim.Height = dim.Height * e.dim.Width / + dim.Width; + else + e.dim.Width = dim.Width * e.dim.Height / + dim.Height; + break; + } + } + } +} + +// Get element at given coordinates. Coordinates are inner coordinates (starting +// at 0,0). +ParsedText::Element *TextDrawer::getElementAt(core::position2d<s32> pos) +{ + pos.Y -= m_voffset; + for (auto &p : m_text.m_paragraphs) { + for (auto &el : p.elements) { + core::rect<s32> rect(el.pos, el.dim); + if (rect.isPointInside(pos)) + return ⪙ + } + } + return 0; +} + +/* + This function places all elements according to given width. Elements have + been previously sized by constructor and will be later drawed by draw. + It may be called each time width changes and resulting height can be + retrieved using getHeight. See GUIHyperText constructor, it uses it once to + test if text fits in window and eventually another time if width is reduced + m_floating because of scrollbar added. +*/ +void TextDrawer::place(const core::rect<s32> &dest_rect) +{ + m_floating.clear(); + s32 y = 0; + s32 ymargin = m_text.margin; + + // Iterator used : + // p - Current paragraph, walked only once + // el - Current element, walked only once + // e and f - local element and floating operators + + for (auto &p : m_text.m_paragraphs) { + // Find and place floating stuff in paragraph + for (auto e = p.elements.begin(); e != p.elements.end(); ++e) { + if (e->floating != ParsedText::FLOAT_NONE) { + if (y) + e->pos.Y = y + std::max(ymargin, e->margin); + else + e->pos.Y = ymargin; + + if (e->floating == ParsedText::FLOAT_LEFT) + e->pos.X = m_text.margin; + if (e->floating == ParsedText::FLOAT_RIGHT) + e->pos.X = dest_rect.getWidth() - e->dim.Width - + m_text.margin; + + RectWithMargin floating; + floating.rect = core::rect<s32>(e->pos, e->dim); + floating.margin = e->margin; + + m_floating.push_back(floating); + } + } + + if (y) + y = y + std::max(ymargin, p.margin); + + ymargin = p.margin; + + // Place non floating stuff + std::vector<ParsedText::Element>::iterator el = p.elements.begin(); + + while (el != p.elements.end()) { + // Determine line width and y pos + s32 left, right; + s32 nexty = y; + do { + y = nexty; + nexty = 0; + + // Inner left & right + left = m_text.margin; + right = dest_rect.getWidth() - m_text.margin; + + for (const auto &f : m_floating) { + // Does floating rect intersect paragraph y line? + if (f.rect.UpperLeftCorner.Y - f.margin <= y && + f.rect.LowerRightCorner.Y + f.margin >= y) { + + // Next Y to try if no room left + if (!nexty || f.rect.LowerRightCorner.Y + + std::max(f.margin, p.margin) < nexty) { + nexty = f.rect.LowerRightCorner.Y + + std::max(f.margin, p.margin) + 1; + } + + if (f.rect.UpperLeftCorner.X - f.margin <= left && + f.rect.LowerRightCorner.X + f.margin < right) { + // float on left + if (f.rect.LowerRightCorner.X + + std::max(f.margin, p.margin) > left) { + left = f.rect.LowerRightCorner.X + + std::max(f.margin, p.margin); + } + } else if (f.rect.LowerRightCorner.X + f.margin >= right && + f.rect.UpperLeftCorner.X - f.margin > left) { + // float on right + if (f.rect.UpperLeftCorner.X - + std::max(f.margin, p.margin) < right) + right = f.rect.UpperLeftCorner.X - + std::max(f.margin, p.margin); + + } else if (f.rect.UpperLeftCorner.X - f.margin <= left && + f.rect.LowerRightCorner.X + f.margin >= right) { + // float taking all space + left = right; + } + else + { // float in the middle -- should not occure yet, see that later + } + } + } + } while (nexty && right <= left); + + u32 linewidth = right - left; + float x = left; + + u32 charsheight = 0; + u32 charswidth = 0; + u32 wordcount = 0; + + // Skip begining of line separators but include them in height + // computation. + while (el != p.elements.end() && + el->type == ParsedText::ELEMENT_SEPARATOR) { + if (el->floating == ParsedText::FLOAT_NONE) { + el->drawwidth = 0; + if (charsheight < el->dim.Height) + charsheight = el->dim.Height; + } + el++; + } + + std::vector<ParsedText::Element>::iterator linestart = el; + std::vector<ParsedText::Element>::iterator lineend = p.elements.end(); + + // First pass, find elements fitting into line + // (or at least one element) + while (el != p.elements.end() && (charswidth == 0 || + charswidth + el->dim.Width <= linewidth)) { + if (el->floating == ParsedText::FLOAT_NONE) { + if (el->type != ParsedText::ELEMENT_SEPARATOR) { + lineend = el; + wordcount++; + } + charswidth += el->dim.Width; + if (charsheight < el->dim.Height) + charsheight = el->dim.Height; + } + el++; + } + + // Empty line, nothing to place only go down line height + if (lineend == p.elements.end()) { + y += charsheight; + continue; + } + + // Point to the first position outside line (may be end()) + lineend++; + + // Second pass, compute printable line width and adjustments + charswidth = 0; + s32 top = 0; + s32 bottom = 0; + for (auto e = linestart; e != lineend; ++e) { + if (e->floating == ParsedText::FLOAT_NONE) { + charswidth += e->dim.Width; + if (top < (s32)e->dim.Height - e->baseline) + top = e->dim.Height - e->baseline; + if (bottom < e->baseline) + bottom = e->baseline; + } + } + + float extraspace = 0.f; + + switch (p.halign) { + case ParsedText::HALIGN_CENTER: + x += (linewidth - charswidth) / 2.f; + break; + case ParsedText::HALIGN_JUSTIFY: + if (wordcount > 1 && // Justification only if at least two words + !(lineend == p.elements.end())) // Don't justify last line + extraspace = ((float)(linewidth - charswidth)) / (wordcount - 1); + break; + case ParsedText::HALIGN_RIGHT: + x += linewidth - charswidth; + break; + case ParsedText::HALIGN_LEFT: + break; + } + + // Third pass, actually place everything + for (auto e = linestart; e != lineend; ++e) { + if (e->floating != ParsedText::FLOAT_NONE) + continue; + + e->pos.X = x; + e->pos.Y = y; + + switch (e->type) { + case ParsedText::ELEMENT_TEXT: + case ParsedText::ELEMENT_SEPARATOR: + e->pos.X = x; + + // Align char baselines + e->pos.Y = y + top + e->baseline - e->dim.Height; + + x += e->dim.Width; + if (e->type == ParsedText::ELEMENT_SEPARATOR) + x += extraspace; + break; + + case ParsedText::ELEMENT_IMAGE: + case ParsedText::ELEMENT_ITEM: + x += e->dim.Width; + break; + } + + // Draw width for separator can be different than element + // width. This will be important for char effects like + // underline. + e->drawwidth = x - e->pos.X; + } + y += charsheight; + } // Elements (actually lines) + } // Paragraph + + // Check if float goes under paragraph + for (const auto &f : m_floating) { + if (f.rect.LowerRightCorner.Y >= y) + y = f.rect.LowerRightCorner.Y; + } + + m_height = y + m_text.margin; + // Compute vertical offset according to vertical alignment + if (m_height < dest_rect.getHeight()) + switch (m_text.valign) { + case ParsedText::VALIGN_BOTTOM: + m_voffset = dest_rect.getHeight() - m_height; + break; + case ParsedText::VALIGN_MIDDLE: + m_voffset = (dest_rect.getHeight() - m_height) / 2; + break; + case ParsedText::VALIGN_TOP: + default: + m_voffset = 0; + } + else + m_voffset = 0; +} + +// Draw text in a rectangle with a given offset. Items are actually placed in +// relative (to upper left corner) coordinates. +void TextDrawer::draw(const core::rect<s32> &clip_rect, + const core::position2d<s32> &dest_offset) +{ + irr::video::IVideoDriver *driver = m_environment->getVideoDriver(); + core::position2d<s32> offset = dest_offset; + offset.Y += m_voffset; + + if (m_text.background_type == ParsedText::BACKGROUND_COLOR) + driver->draw2DRectangle(m_text.background_color, clip_rect); + + for (auto &p : m_text.m_paragraphs) { + for (auto &el : p.elements) { + core::rect<s32> rect(el.pos + offset, el.dim); + if (!rect.isRectCollided(clip_rect)) + continue; + + switch (el.type) { + case ParsedText::ELEMENT_SEPARATOR: + case ParsedText::ELEMENT_TEXT: { + irr::video::SColor color = el.color; + + for (auto tag : el.tags) + if (&(*tag) == m_hovertag) + color = el.hovercolor; + + if (!el.font) + break; + + if (el.type == ParsedText::ELEMENT_TEXT) + el.font->draw(el.text, rect, color, false, true, + &clip_rect); + + if (el.underline && el.drawwidth) { + s32 linepos = el.pos.Y + offset.Y + + el.dim.Height - (el.baseline >> 1); + + core::rect<s32> linerect(el.pos.X + offset.X, + linepos - (el.baseline >> 3) - 1, + el.pos.X + offset.X + el.drawwidth, + linepos + (el.baseline >> 3)); + + driver->draw2DRectangle(color, linerect, &clip_rect); + } + } break; + + case ParsedText::ELEMENT_IMAGE: { + video::ITexture *texture = + m_client->getTextureSource()->getTexture( + stringw_to_utf8(el.text)); + if (texture != 0) + m_environment->getVideoDriver()->draw2DImage( + texture, rect, + irr::core::rect<s32>( + core::position2d<s32>(0, 0), + texture->getOriginalSize()), + &clip_rect, 0, true); + } break; + + case ParsedText::ELEMENT_ITEM: { + IItemDefManager *idef = m_client->idef(); + ItemStack item; + item.deSerialize(stringw_to_utf8(el.text), idef); + + drawItemStack( + m_environment->getVideoDriver(), + g_fontengine->getFont(), item, rect, &clip_rect, + m_client, IT_ROT_OTHER, el.angle, el.rotation + ); + } break; + } + } + } +} + +// ----------------------------------------------------------------------------- +// GUIHyperText - The formated text area formspec item + +//! constructor +GUIHyperText::GUIHyperText(const wchar_t *text, IGUIEnvironment *environment, + IGUIElement *parent, s32 id, const core::rect<s32> &rectangle, + Client *client, ISimpleTextureSource *tsrc) : + IGUIElement(EGUIET_ELEMENT, environment, parent, id, rectangle), + m_client(client), m_vscrollbar(nullptr), + m_drawer(text, client, environment, tsrc), m_text_scrollpos(0, 0) +{ + +#ifdef _DEBUG + setDebugName("GUIHyperText"); +#endif + + IGUISkin *skin = 0; + if (Environment) + skin = Environment->getSkin(); + + m_scrollbar_width = skin ? skin->getSize(gui::EGDS_SCROLLBAR_SIZE) : 16; + + core::rect<s32> rect = irr::core::rect<s32>( + RelativeRect.getWidth() - m_scrollbar_width, 0, + RelativeRect.getWidth(), RelativeRect.getHeight()); + + m_vscrollbar = new GUIScrollBar(Environment, this, -1, rect, false, true); + m_vscrollbar->setVisible(false); +} + +//! destructor +GUIHyperText::~GUIHyperText() +{ + m_vscrollbar->remove(); + m_vscrollbar->drop(); +} + +ParsedText::Element *GUIHyperText::getElementAt(s32 X, s32 Y) +{ + core::position2d<s32> pos{X, Y}; + pos -= m_display_text_rect.UpperLeftCorner; + pos -= m_text_scrollpos; + return m_drawer.getElementAt(pos); +} + +void GUIHyperText::checkHover(s32 X, s32 Y) +{ + m_drawer.m_hovertag = nullptr; + + if (AbsoluteRect.isPointInside(core::position2d<s32>(X, Y))) { + ParsedText::Element *element = getElementAt(X, Y); + + if (element) { + for (auto &tag : element->tags) { + if (tag->name == "action") { + m_drawer.m_hovertag = tag; + break; + } + } + } + } + +#ifndef HAVE_TOUCHSCREENGUI + if (m_drawer.m_hovertag) + RenderingEngine::get_raw_device()->getCursorControl()->setActiveIcon( + gui::ECI_HAND); + else + RenderingEngine::get_raw_device()->getCursorControl()->setActiveIcon( + gui::ECI_NORMAL); +#endif +} + +bool GUIHyperText::OnEvent(const SEvent &event) +{ + // Scroll bar + if (event.EventType == EET_GUI_EVENT && + event.GUIEvent.EventType == EGET_SCROLL_BAR_CHANGED && + event.GUIEvent.Caller == m_vscrollbar) { + m_text_scrollpos.Y = -m_vscrollbar->getPos(); + } + + // Reset hover if element left + if (event.EventType == EET_GUI_EVENT && + event.GUIEvent.EventType == EGET_ELEMENT_LEFT) { + m_drawer.m_hovertag = nullptr; +#ifndef HAVE_TOUCHSCREENGUI + gui::ICursorControl *cursor_control = + RenderingEngine::get_raw_device()->getCursorControl(); + if (cursor_control->isVisible()) + cursor_control->setActiveIcon(gui::ECI_NORMAL); +#endif + } + + if (event.EventType == EET_MOUSE_INPUT_EVENT) { + if (event.MouseInput.Event == EMIE_MOUSE_MOVED) + checkHover(event.MouseInput.X, event.MouseInput.Y); + + if (event.MouseInput.Event == EMIE_MOUSE_WHEEL && m_vscrollbar->isVisible()) { + m_vscrollbar->setPos(m_vscrollbar->getPos() - + event.MouseInput.Wheel * m_vscrollbar->getSmallStep()); + m_text_scrollpos.Y = -m_vscrollbar->getPos(); + m_drawer.draw(m_display_text_rect, m_text_scrollpos); + checkHover(event.MouseInput.X, event.MouseInput.Y); + return true; + + } else if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { + ParsedText::Element *element = getElementAt( + event.MouseInput.X, event.MouseInput.Y); + + if (element) { + for (auto &tag : element->tags) { + if (tag->name == "action") { + Text = core::stringw(L"action:") + + utf8_to_stringw(tag->attrs["name"]); + if (Parent) { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_BUTTON_CLICKED; + Parent->OnEvent(newEvent); + } + break; + } + } + } + } + } + + return IGUIElement::OnEvent(event); +} + +//! draws the element and its children +void GUIHyperText::draw() +{ + if (!IsVisible) + return; + + // Text + m_display_text_rect = AbsoluteRect; + m_drawer.place(m_display_text_rect); + + // Show scrollbar if text overflow + if (m_drawer.getHeight() > m_display_text_rect.getHeight()) { + m_vscrollbar->setSmallStep(m_display_text_rect.getHeight() * 0.1f); + m_vscrollbar->setLargeStep(m_display_text_rect.getHeight() * 0.5f); + m_vscrollbar->setMax(m_drawer.getHeight() - m_display_text_rect.getHeight()); + + m_vscrollbar->setVisible(true); + + m_vscrollbar->setPageSize(s32(m_drawer.getHeight())); + + core::rect<s32> smaller_rect = m_display_text_rect; + + smaller_rect.LowerRightCorner.X -= m_scrollbar_width; + m_drawer.place(smaller_rect); + } else { + m_vscrollbar->setMax(0); + m_vscrollbar->setPos(0); + m_vscrollbar->setVisible(false); + } + m_drawer.draw(AbsoluteClippingRect, + m_display_text_rect.UpperLeftCorner + m_text_scrollpos); + + // draw children + IGUIElement::draw(); +} diff --git a/src/gui/guiHyperText.h b/src/gui/guiHyperText.h new file mode 100644 index 0000000..04c664d --- /dev/null +++ b/src/gui/guiHyperText.h @@ -0,0 +1,230 @@ +/* +Minetest +Copyright (C) 2019 EvicenceBKidscode / Pierre-Yves Rollo <dev@pyrollo.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <vector> +#include <list> +#include <unordered_map> +#include <string> +#include "irrlichttypes_extrabloated.h" + +using namespace irr; + +class ISimpleTextureSource; +class Client; +class GUIScrollBar; + +class ParsedText +{ +public: + ParsedText(const wchar_t *text); + ~ParsedText(); + + enum ElementType + { + ELEMENT_TEXT, + ELEMENT_SEPARATOR, + ELEMENT_IMAGE, + ELEMENT_ITEM + }; + + enum BackgroundType + { + BACKGROUND_NONE, + BACKGROUND_COLOR + }; + + enum FloatType + { + FLOAT_NONE, + FLOAT_RIGHT, + FLOAT_LEFT + }; + + enum HalignType + { + HALIGN_CENTER, + HALIGN_LEFT, + HALIGN_RIGHT, + HALIGN_JUSTIFY + }; + + enum ValignType + { + VALIGN_MIDDLE, + VALIGN_TOP, + VALIGN_BOTTOM + }; + + typedef std::unordered_map<std::string, std::string> StyleList; + typedef std::unordered_map<std::string, std::string> AttrsList; + + struct Tag + { + std::string name; + AttrsList attrs; + StyleList style; + }; + + struct Element + { + std::list<Tag *> tags; + ElementType type; + core::stringw text = ""; + + core::dimension2d<u32> dim; + core::position2d<s32> pos; + s32 drawwidth; + + FloatType floating = FLOAT_NONE; + + ValignType valign; + + gui::IGUIFont *font; + + irr::video::SColor color; + irr::video::SColor hovercolor; + bool underline; + + s32 baseline = 0; + + // img & item specific attributes + std::string name; + v3s16 angle{0, 0, 0}; + v3s16 rotation{0, 0, 0}; + + s32 margin = 10; + + void setStyle(StyleList &style); + }; + + struct Paragraph + { + std::vector<Element> elements; + HalignType halign; + s32 margin = 10; + + void setStyle(StyleList &style); + }; + + std::vector<Paragraph> m_paragraphs; + + // Element style + s32 margin = 3; + ValignType valign = VALIGN_TOP; + BackgroundType background_type = BACKGROUND_NONE; + irr::video::SColor background_color; + + Tag m_root_tag; + +protected: + typedef enum { ER_NONE, ER_TAG, ER_NEWLINE } EndReason; + + // Parser functions + void enterElement(ElementType type); + void endElement(); + void enterParagraph(); + void endParagraph(EndReason reason); + void pushChar(wchar_t c); + ParsedText::Tag *newTag(const std::string &name, const AttrsList &attrs); + ParsedText::Tag *openTag(const std::string &name, const AttrsList &attrs); + bool closeTag(const std::string &name); + void parseGenericStyleAttr(const std::string &name, const std::string &value, + StyleList &style); + void parseStyles(const AttrsList &attrs, StyleList &style); + void globalTag(const ParsedText::AttrsList &attrs); + u32 parseTag(const wchar_t *text, u32 cursor); + void parse(const wchar_t *text); + + std::unordered_map<std::string, StyleList> m_elementtags; + std::unordered_map<std::string, StyleList> m_paragraphtags; + + std::vector<Tag *> m_not_root_tags; + std::list<Tag *> m_active_tags; + + // Current values + StyleList m_style; + Element *m_element; + Paragraph *m_paragraph; + bool m_empty_paragraph; + EndReason m_end_paragraph_reason; +}; + +class TextDrawer +{ +public: + TextDrawer(const wchar_t *text, Client *client, gui::IGUIEnvironment *environment, + ISimpleTextureSource *tsrc); + + void place(const core::rect<s32> &dest_rect); + inline s32 getHeight() { return m_height; }; + void draw(const core::rect<s32> &clip_rect, + const core::position2d<s32> &dest_offset); + ParsedText::Element *getElementAt(core::position2d<s32> pos); + ParsedText::Tag *m_hovertag; + +protected: + struct RectWithMargin + { + core::rect<s32> rect; + s32 margin; + }; + + ParsedText m_text; + Client *m_client; + gui::IGUIEnvironment *m_environment; + s32 m_height; + s32 m_voffset; + std::vector<RectWithMargin> m_floating; +}; + +class GUIHyperText : public gui::IGUIElement +{ +public: + //! constructor + GUIHyperText(const wchar_t *text, gui::IGUIEnvironment *environment, + gui::IGUIElement *parent, s32 id, + const core::rect<s32> &rectangle, Client *client, + ISimpleTextureSource *tsrc); + + //! destructor + virtual ~GUIHyperText(); + + //! draws the element and its children + virtual void draw(); + + core::dimension2du getTextDimension(); + + bool OnEvent(const SEvent &event); + +protected: + // GUI members + Client *m_client; + GUIScrollBar *m_vscrollbar; + TextDrawer m_drawer; + + // Positioning + u32 m_scrollbar_width; + core::rect<s32> m_display_text_rect; + core::position2d<s32> m_text_scrollpos; + + ParsedText::Element *getElementAt(s32 X, s32 Y); + void checkHover(s32 X, s32 Y); +}; diff --git a/src/gui/guiInventoryList.cpp b/src/gui/guiInventoryList.cpp new file mode 100644 index 0000000..183d721 --- /dev/null +++ b/src/gui/guiInventoryList.cpp @@ -0,0 +1,235 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiInventoryList.h" +#include "guiFormSpecMenu.h" +#include "client/hud.h" +#include "client/client.h" + +GUIInventoryList::GUIInventoryList(gui::IGUIEnvironment *env, + gui::IGUIElement *parent, + s32 id, + const core::rect<s32> &rectangle, + InventoryManager *invmgr, + const InventoryLocation &inventoryloc, + const std::string &listname, + const v2s32 &geom, + const s32 start_item_i, + const v2s32 &slot_size, + const v2f32 &slot_spacing, + GUIFormSpecMenu *fs_menu, + const Options &options, + gui::IGUIFont *font) : + gui::IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rectangle), + m_invmgr(invmgr), + m_inventoryloc(inventoryloc), + m_listname(listname), + m_geom(geom), + m_start_item_i(start_item_i), + m_slot_size(slot_size), + m_slot_spacing(slot_spacing), + m_fs_menu(fs_menu), + m_options(options), + m_font(font), + m_hovered_i(-1), + m_already_warned(false) +{ +} + +void GUIInventoryList::draw() +{ + if (!IsVisible) + return; + + Inventory *inv = m_invmgr->getInventory(m_inventoryloc); + if (!inv) { + if (!m_already_warned) { + warningstream << "GUIInventoryList::draw(): " + << "The inventory location " + << "\"" << m_inventoryloc.dump() << "\" doesn't exist" + << std::endl; + m_already_warned = true; + } + return; + } + InventoryList *ilist = inv->getList(m_listname); + if (!ilist) { + if (!m_already_warned) { + warningstream << "GUIInventoryList::draw(): " + << "The inventory list \"" << m_listname << "\" @ \"" + << m_inventoryloc.dump() << "\" doesn't exist" + << std::endl; + m_already_warned = true; + } + return; + } + m_already_warned = false; + + video::IVideoDriver *driver = Environment->getVideoDriver(); + Client *client = m_fs_menu->getClient(); + const ItemSpec *selected_item = m_fs_menu->getSelectedItem(); + + core::rect<s32> imgrect(0, 0, m_slot_size.X, m_slot_size.Y); + v2s32 base_pos = AbsoluteRect.UpperLeftCorner; + + const s32 list_size = (s32)ilist->getSize(); + + for (s32 i = 0; i < m_geom.X * m_geom.Y; i++) { + s32 item_i = i + m_start_item_i; + if (item_i >= list_size) + break; + + v2s32 p((i % m_geom.X) * m_slot_spacing.X, + (i / m_geom.X) * m_slot_spacing.Y); + core::rect<s32> rect = imgrect + base_pos + p; + ItemStack item = ilist->getItem(item_i); + + bool selected = selected_item + && m_invmgr->getInventory(selected_item->inventoryloc) == inv + && selected_item->listname == m_listname + && selected_item->i == item_i; + bool hovering = m_hovered_i == item_i; + ItemRotationKind rotation_kind = selected ? IT_ROT_SELECTED : + (hovering ? IT_ROT_HOVERED : IT_ROT_NONE); + + // layer 0 + if (hovering) { + driver->draw2DRectangle(m_options.slotbg_h, rect, &AbsoluteClippingRect); + } else { + driver->draw2DRectangle(m_options.slotbg_n, rect, &AbsoluteClippingRect); + } + + // Draw inv slot borders + if (m_options.slotborder) { + s32 x1 = rect.UpperLeftCorner.X; + s32 y1 = rect.UpperLeftCorner.Y; + s32 x2 = rect.LowerRightCorner.X; + s32 y2 = rect.LowerRightCorner.Y; + s32 border = 1; + core::rect<s32> clipping_rect = Parent ? Parent->getAbsoluteClippingRect() + : core::rect<s32>(); + core::rect<s32> *clipping_rect_ptr = Parent ? &clipping_rect : nullptr; + driver->draw2DRectangle(m_options.slotbordercolor, + core::rect<s32>(v2s32(x1 - border, y1 - border), + v2s32(x2 + border, y1)), clipping_rect_ptr); + driver->draw2DRectangle(m_options.slotbordercolor, + core::rect<s32>(v2s32(x1 - border, y2), + v2s32(x2 + border, y2 + border)), clipping_rect_ptr); + driver->draw2DRectangle(m_options.slotbordercolor, + core::rect<s32>(v2s32(x1 - border, y1), + v2s32(x1, y2)), clipping_rect_ptr); + driver->draw2DRectangle(m_options.slotbordercolor, + core::rect<s32>(v2s32(x2, y1), + v2s32(x2 + border, y2)), clipping_rect_ptr); + } + + // layer 1 + if (selected) + item.takeItem(m_fs_menu->getSelectedAmount()); + + if (!item.empty()) { + // Draw item stack + drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect, + client, rotation_kind); + // Add hovering tooltip + if (hovering && !selected_item) { + std::string tooltip = item.getDescription(client->idef()); + if (m_fs_menu->doTooltipAppendItemname()) + tooltip += "\n[" + item.name + "]"; + m_fs_menu->addHoveredItemTooltip(tooltip); + } + } + } + + IGUIElement::draw(); +} + +bool GUIInventoryList::OnEvent(const SEvent &event) +{ + if (event.EventType != EET_MOUSE_INPUT_EVENT) { + if (event.EventType == EET_GUI_EVENT && + event.GUIEvent.EventType == EGET_ELEMENT_LEFT) { + // element is no longer hovered + m_hovered_i = -1; + } + return IGUIElement::OnEvent(event); + } + + m_hovered_i = getItemIndexAtPos(v2s32(event.MouseInput.X, event.MouseInput.Y)); + + if (m_hovered_i != -1) + return IGUIElement::OnEvent(event); + + // no item slot at pos of mouse event => allow clicking through + // find the element that would be hovered if this inventorylist was invisible + bool was_visible = IsVisible; + IsVisible = false; + IGUIElement *hovered = + Environment->getRootGUIElement()->getElementFromPoint( + core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y)); + + // if the player clicks outside of the formspec window, hovered is not + // m_fs_menu, but some other weird element (with ID -1). we do however need + // hovered to be m_fs_menu as item dropping when clicking outside of the + // formspec window is handled in its OnEvent callback + if (!hovered || hovered->getID() == -1) + hovered = m_fs_menu; + + bool ret = hovered->OnEvent(event); + + IsVisible = was_visible; + + return ret; +} + +s32 GUIInventoryList::getItemIndexAtPos(v2s32 p) const +{ + // no item if no gui element at pointer + if (!IsVisible || AbsoluteClippingRect.getArea() <= 0 || + !AbsoluteClippingRect.isPointInside(p)) + return -1; + + // there can not be an item if the inventory or the inventorylist does not exist + Inventory *inv = m_invmgr->getInventory(m_inventoryloc); + if (!inv) + return -1; + InventoryList *ilist = inv->getList(m_listname); + if (!ilist) + return -1; + + core::rect<s32> imgrect(0, 0, m_slot_size.X, m_slot_size.Y); + v2s32 base_pos = AbsoluteRect.UpperLeftCorner; + + // instead of looping through each slot, we look where p would be in the grid + s32 i = (p.X - base_pos.X) / (s32)m_slot_spacing.X + + m_geom.X * ((p.Y - base_pos.Y) / (s32)m_slot_spacing.Y); + + v2s32 p0((i % m_geom.X) * m_slot_spacing.X, + (i / m_geom.X) * m_slot_spacing.Y); + + core::rect<s32> rect = imgrect + base_pos + p0; + + rect.clipAgainst(AbsoluteClippingRect); + + if (rect.getArea() > 0 && rect.isPointInside(p) && + i + m_start_item_i < (s32)ilist->getSize()) + return i + m_start_item_i; + + return -1; +} diff --git a/src/gui/guiInventoryList.h b/src/gui/guiInventoryList.h new file mode 100644 index 0000000..28e95fb --- /dev/null +++ b/src/gui/guiInventoryList.h @@ -0,0 +1,133 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "inventorymanager.h" +#include "irrlichttypes_extrabloated.h" +#include "util/string.h" + +class GUIFormSpecMenu; + +class GUIInventoryList : public gui::IGUIElement +{ +public: + struct ItemSpec + { + ItemSpec() = default; + + ItemSpec(const InventoryLocation &a_inventoryloc, + const std::string &a_listname, + s32 a_i) : + inventoryloc(a_inventoryloc), + listname(a_listname), + i(a_i) + { + } + + bool isValid() const { return i != -1; } + + InventoryLocation inventoryloc; + std::string listname; + s32 i = -1; + }; + + // options for inventorylists that are setable with the lua api + struct Options { + // whether a one-pixel border for the slots should be drawn and its color + bool slotborder = false; + video::SColor slotbordercolor = video::SColor(200, 0, 0, 0); + // colors for normal and highlighted slot background + video::SColor slotbg_n = video::SColor(255, 128, 128, 128); + video::SColor slotbg_h = video::SColor(255, 192, 192, 192); + }; + + GUIInventoryList(gui::IGUIEnvironment *env, + gui::IGUIElement *parent, + s32 id, + const core::rect<s32> &rectangle, + InventoryManager *invmgr, + const InventoryLocation &inventoryloc, + const std::string &listname, + const v2s32 &geom, + const s32 start_item_i, + const v2s32 &slot_size, + const v2f32 &slot_spacing, + GUIFormSpecMenu *fs_menu, + const Options &options, + gui::IGUIFont *font); + + virtual void draw() override; + + virtual bool OnEvent(const SEvent &event) override; + + const InventoryLocation &getInventoryloc() const + { + return m_inventoryloc; + } + + const std::string &getListname() const + { + return m_listname; + } + + void setSlotBGColors(const video::SColor &slotbg_n, const video::SColor &slotbg_h) + { + m_options.slotbg_n = slotbg_n; + m_options.slotbg_h = slotbg_h; + } + + void setSlotBorders(bool slotborder, const video::SColor &slotbordercolor) + { + m_options.slotborder = slotborder; + m_options.slotbordercolor = slotbordercolor; + } + + // returns -1 if not item is at pos p + s32 getItemIndexAtPos(v2s32 p) const; + +private: + InventoryManager *m_invmgr; + const InventoryLocation m_inventoryloc; + const std::string m_listname; + + // the specified width and height of the shown inventorylist in itemslots + const v2s32 m_geom; + // the first item's index in inventory + const s32 m_start_item_i; + + // specifies how large the slot rects are + const v2s32 m_slot_size; + // specifies how large the space between slots is (space between is spacing-size) + const v2f32 m_slot_spacing; + + // the GUIFormSpecMenu can have an item selected and co. + GUIFormSpecMenu *m_fs_menu; + + Options m_options; + + // the font + gui::IGUIFont *m_font; + + // the index of the hovered item; -1 if no item is hovered + s32 m_hovered_i; + + // we do not want to write a warning on every draw + bool m_already_warned; +}; diff --git a/src/gui/guiItemImage.cpp b/src/gui/guiItemImage.cpp new file mode 100644 index 0000000..f93d547 --- /dev/null +++ b/src/gui/guiItemImage.cpp @@ -0,0 +1,52 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiItemImage.h" +#include "client/client.h" + +GUIItemImage::GUIItemImage(gui::IGUIEnvironment *env, gui::IGUIElement *parent, + s32 id, const core::rect<s32> &rectangle, const std::string &item_name, + gui::IGUIFont *font, Client *client) : + gui::IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rectangle), + m_item_name(item_name), m_font(font), m_client(client), m_label(core::stringw()) +{ +} + +void GUIItemImage::draw() +{ + if (!IsVisible) + return; + + if (!m_client) { + IGUIElement::draw(); + return; + } + + IItemDefManager *idef = m_client->idef(); + ItemStack item; + item.deSerialize(m_item_name, idef); + // Viewport rectangle on screen + core::rect<s32> rect = core::rect<s32>(AbsoluteRect); + drawItemStack(Environment->getVideoDriver(), m_font, item, rect, + &AbsoluteClippingRect, m_client, IT_ROT_NONE); + video::SColor color(255, 255, 255, 255); + m_font->draw(m_label, rect, color, true, true, &AbsoluteClippingRect); + + IGUIElement::draw(); +} diff --git a/src/gui/guiItemImage.h b/src/gui/guiItemImage.h new file mode 100644 index 0000000..6fede65 --- /dev/null +++ b/src/gui/guiItemImage.h @@ -0,0 +1,46 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "util/string.h" + +class Client; + +class GUIItemImage : public gui::IGUIElement +{ +public: + GUIItemImage(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id, + const core::rect<s32> &rectangle, const std::string &item_name, + gui::IGUIFont *font, Client *client); + + virtual void draw() override; + + virtual void setText(const wchar_t *text) override + { + m_label = text; + } + +private: + std::string m_item_name; + gui::IGUIFont *m_font; + Client *m_client; + core::stringw m_label; +}; diff --git a/src/gui/guiKeyChangeMenu.cpp b/src/gui/guiKeyChangeMenu.cpp new file mode 100644 index 0000000..021f5f0 --- /dev/null +++ b/src/gui/guiKeyChangeMenu.cpp @@ -0,0 +1,438 @@ +/* + Minetest + Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> + Copyright (C) 2013 Ciaran Gultnieks <ciaran@ciarang.com> + Copyright (C) 2013 teddydestodes <derkomtur@schattengang.net> + + 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.1 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "guiKeyChangeMenu.h" +#include "debug.h" +#include "guiButton.h" +#include "serialization.h" +#include <string> +#include <IGUICheckBox.h> +#include <IGUIEditBox.h> +#include <IGUIButton.h> +#include <IGUIStaticText.h> +#include <IGUIFont.h> +#include "settings.h" +#include <algorithm> + +#include "mainmenumanager.h" // for g_gamecallback + +#define KMaxButtonPerColumns 12 + +extern MainGameCallback *g_gamecallback; + +enum +{ + GUI_ID_BACK_BUTTON = 101, GUI_ID_ABORT_BUTTON, GUI_ID_SCROLL_BAR, + // buttons + GUI_ID_KEY_FORWARD_BUTTON, + GUI_ID_KEY_BACKWARD_BUTTON, + GUI_ID_KEY_LEFT_BUTTON, + GUI_ID_KEY_RIGHT_BUTTON, + GUI_ID_KEY_AUX1_BUTTON, + GUI_ID_KEY_FLY_BUTTON, + GUI_ID_KEY_FAST_BUTTON, + GUI_ID_KEY_JUMP_BUTTON, + GUI_ID_KEY_NOCLIP_BUTTON, + GUI_ID_KEY_PITCH_MOVE, + GUI_ID_KEY_CHAT_BUTTON, + GUI_ID_KEY_CMD_BUTTON, + GUI_ID_KEY_CMD_LOCAL_BUTTON, + GUI_ID_KEY_CONSOLE_BUTTON, + GUI_ID_KEY_SNEAK_BUTTON, + GUI_ID_KEY_DROP_BUTTON, + GUI_ID_KEY_INVENTORY_BUTTON, + GUI_ID_KEY_HOTBAR_PREV_BUTTON, + GUI_ID_KEY_HOTBAR_NEXT_BUTTON, + GUI_ID_KEY_MUTE_BUTTON, + GUI_ID_KEY_DEC_VOLUME_BUTTON, + GUI_ID_KEY_INC_VOLUME_BUTTON, + GUI_ID_KEY_RANGE_BUTTON, + GUI_ID_KEY_ZOOM_BUTTON, + GUI_ID_KEY_CAMERA_BUTTON, + GUI_ID_KEY_MINIMAP_BUTTON, + GUI_ID_KEY_SCREENSHOT_BUTTON, + GUI_ID_KEY_CHATLOG_BUTTON, + GUI_ID_KEY_BLOCK_BOUNDS_BUTTON, + GUI_ID_KEY_HUD_BUTTON, + GUI_ID_KEY_FOG_BUTTON, + GUI_ID_KEY_DEC_RANGE_BUTTON, + GUI_ID_KEY_INC_RANGE_BUTTON, + GUI_ID_KEY_AUTOFWD_BUTTON, + // other + GUI_ID_CB_AUX1_DESCENDS, + GUI_ID_CB_DOUBLETAP_JUMP, + GUI_ID_CB_AUTOJUMP, +}; + +GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env, + gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, + ISimpleTextureSource *tsrc) : + GUIModalMenu(env, parent, id, menumgr), + m_tsrc(tsrc) +{ + init_keys(); +} + +GUIKeyChangeMenu::~GUIKeyChangeMenu() +{ + removeAllChildren(); + key_used_text = nullptr; + + for (key_setting *ks : key_settings) { + delete[] ks->button_name; + delete ks; + } + key_settings.clear(); +} + +void GUIKeyChangeMenu::regenerateGui(v2u32 screensize) +{ + removeAllChildren(); + key_used_text = nullptr; + + const float s = m_gui_scale; + DesiredRect = core::rect<s32>( + screensize.X / 2 - 835 * s / 2, + screensize.Y / 2 - 430 * s / 2, + screensize.X / 2 + 835 * s / 2, + screensize.Y / 2 + 430 * s / 2 + ); + recalculateAbsolutePosition(false); + + v2s32 size = DesiredRect.getSize(); + v2s32 topleft(0, 0); + + { + core::rect<s32> rect(0, 0, 600 * s, 40 * s); + rect += topleft + v2s32(25 * s, 3 * s); + //gui::IGUIStaticText *t = + const wchar_t *text = wgettext("Keybindings."); + Environment->addStaticText(text, + rect, false, true, this, -1); + delete[] text; + //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT); + } + + // Build buttons + + v2s32 offset(25 * s, 60 * s); + + for(size_t i = 0; i < key_settings.size(); i++) + { + key_setting *k = key_settings.at(i); + { + core::rect<s32> rect(0, 0, 150 * s, 20 * s); + rect += topleft + v2s32(offset.X, offset.Y); + Environment->addStaticText(k->button_name, rect, false, true, this, -1); + } + + { + core::rect<s32> rect(0, 0, 100 * s, 30 * s); + rect += topleft + v2s32(offset.X + 150 * s, offset.Y - 5 * s); + const wchar_t *text = wgettext(k->key.name()); + k->button = GUIButton::addButton(Environment, rect, m_tsrc, this, k->id, text); + delete[] text; + } + if ((i + 1) % KMaxButtonPerColumns == 0) { + offset.X += 260 * s; + offset.Y = 60 * s; + } else { + offset += v2s32(0, 25 * s); + } + } + + { + s32 option_x = offset.X; + s32 option_y = offset.Y + 5 * s; + u32 option_w = 180 * s; + { + core::rect<s32> rect(0, 0, option_w, 30 * s); + rect += topleft + v2s32(option_x, option_y); + const wchar_t *text = wgettext("\"Aux1\" = climb down"); + Environment->addCheckBox(g_settings->getBool("aux1_descends"), rect, this, + GUI_ID_CB_AUX1_DESCENDS, text); + delete[] text; + } + offset += v2s32(0, 25 * s); + } + + { + s32 option_x = offset.X; + s32 option_y = offset.Y + 5 * s; + u32 option_w = 280 * s; + { + core::rect<s32> rect(0, 0, option_w, 30 * s); + rect += topleft + v2s32(option_x, option_y); + const wchar_t *text = wgettext("Double tap \"jump\" to toggle fly"); + Environment->addCheckBox(g_settings->getBool("doubletap_jump"), rect, this, + GUI_ID_CB_DOUBLETAP_JUMP, text); + delete[] text; + } + offset += v2s32(0, 25 * s); + } + + { + s32 option_x = offset.X; + s32 option_y = offset.Y + 5 * s; + u32 option_w = 280; + { + core::rect<s32> rect(0, 0, option_w, 30 * s); + rect += topleft + v2s32(option_x, option_y); + const wchar_t *text = wgettext("Automatic jumping"); + Environment->addCheckBox(g_settings->getBool("autojump"), rect, this, + GUI_ID_CB_AUTOJUMP, text); + delete[] text; + } + offset += v2s32(0, 25); + } + + { + core::rect<s32> rect(0, 0, 100 * s, 30 * s); + rect += topleft + v2s32(size.X / 2 - 105 * s, size.Y - 40 * s); + const wchar_t *text = wgettext("Save"); + GUIButton::addButton(Environment, rect, m_tsrc, this, GUI_ID_BACK_BUTTON, text); + delete[] text; + } + { + core::rect<s32> rect(0, 0, 100 * s, 30 * s); + rect += topleft + v2s32(size.X / 2 + 5 * s, size.Y - 40 * s); + const wchar_t *text = wgettext("Cancel"); + GUIButton::addButton(Environment, rect, m_tsrc, this, GUI_ID_ABORT_BUTTON, text); + delete[] text; + } +} + +void GUIKeyChangeMenu::drawMenu() +{ + gui::IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + video::IVideoDriver* driver = Environment->getVideoDriver(); + + video::SColor bgcolor(140, 0, 0, 0); + driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect); + + gui::IGUIElement::draw(); +} + +bool GUIKeyChangeMenu::acceptInput() +{ + for (key_setting *k : key_settings) { + std::string default_key; + Settings::getLayer(SL_DEFAULTS)->getNoEx(k->setting_name, default_key); + + if (k->key.sym() != default_key) + g_settings->set(k->setting_name, k->key.sym()); + else + g_settings->remove(k->setting_name); + } + + { + gui::IGUIElement *e = getElementFromId(GUI_ID_CB_AUX1_DESCENDS); + if(e && e->getType() == gui::EGUIET_CHECK_BOX) + g_settings->setBool("aux1_descends", ((gui::IGUICheckBox*)e)->isChecked()); + } + { + gui::IGUIElement *e = getElementFromId(GUI_ID_CB_DOUBLETAP_JUMP); + if(e && e->getType() == gui::EGUIET_CHECK_BOX) + g_settings->setBool("doubletap_jump", ((gui::IGUICheckBox*)e)->isChecked()); + } + { + gui::IGUIElement *e = getElementFromId(GUI_ID_CB_AUTOJUMP); + if(e && e->getType() == gui::EGUIET_CHECK_BOX) + g_settings->setBool("autojump", ((gui::IGUICheckBox*)e)->isChecked()); + } + + clearKeyCache(); + + g_gamecallback->signalKeyConfigChange(); + + return true; +} + +bool GUIKeyChangeMenu::resetMenu() +{ + if (active_key) { + const wchar_t *text = wgettext(active_key->key.name()); + active_key->button->setText(text); + delete[] text; + active_key = nullptr; + return false; + } + return true; +} +bool GUIKeyChangeMenu::OnEvent(const SEvent& event) +{ + if (event.EventType == EET_KEY_INPUT_EVENT && active_key + && event.KeyInput.PressedDown) { + + bool prefer_character = shift_down; + KeyPress kp(event.KeyInput, prefer_character); + + if (event.KeyInput.Key == irr::KEY_DELETE) + kp = KeyPress(""); // To erase key settings + else if (event.KeyInput.Key == irr::KEY_ESCAPE) + kp = active_key->key; // Cancel + + bool shift_went_down = false; + if(!shift_down && + (event.KeyInput.Key == irr::KEY_SHIFT || + event.KeyInput.Key == irr::KEY_LSHIFT || + event.KeyInput.Key == irr::KEY_RSHIFT)) + shift_went_down = true; + + // Display Key already in use message + bool key_in_use = false; + if (strcmp(kp.sym(), "") != 0) { + for (key_setting *ks : key_settings) { + if (ks != active_key && ks->key == kp) { + key_in_use = true; + break; + } + } + } + + if (key_in_use && !this->key_used_text) { + core::rect<s32> rect(0, 0, 600, 40); + rect += v2s32(0, 0) + v2s32(25, 30); + const wchar_t *text = wgettext("Key already in use"); + this->key_used_text = Environment->addStaticText(text, + rect, false, true, this, -1); + delete[] text; + } else if (!key_in_use && this->key_used_text) { + this->key_used_text->remove(); + this->key_used_text = nullptr; + } + + // But go on + { + active_key->key = kp; + const wchar_t *text = wgettext(kp.name()); + active_key->button->setText(text); + delete[] text; + + // Allow characters made with shift + if (shift_went_down){ + shift_down = true; + return false; + } + + active_key = nullptr; + return true; + } + } else if (event.EventType == EET_KEY_INPUT_EVENT && !active_key + && event.KeyInput.PressedDown + && event.KeyInput.Key == irr::KEY_ESCAPE) { + quitMenu(); + return true; + } else if (event.EventType == EET_GUI_EVENT) { + if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST + && isVisible()) + { + if (!canTakeFocus(event.GUIEvent.Element)) + { + infostream << "GUIKeyChangeMenu: Not allowing focus change." + << std::endl; + // Returning true disables focus change + return true; + } + } + if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) + { + switch (event.GUIEvent.Caller->getID()) + { + case GUI_ID_BACK_BUTTON: //back + acceptInput(); + quitMenu(); + return true; + case GUI_ID_ABORT_BUTTON: //abort + quitMenu(); + return true; + default: + resetMenu(); + for (key_setting *ks : key_settings) { + if (ks->id == event.GUIEvent.Caller->getID()) { + active_key = ks; + break; + } + } + FATAL_ERROR_IF(!active_key, "Key setting not found"); + + shift_down = false; + const wchar_t *text = wgettext("press key"); + active_key->button->setText(text); + delete[] text; + break; + } + Environment->setFocus(this); + } + } + return Parent ? Parent->OnEvent(event) : false; +} + +void GUIKeyChangeMenu::add_key(int id, const wchar_t *button_name, const std::string &setting_name) +{ + key_setting *k = new key_setting; + k->id = id; + + k->button_name = button_name; + k->setting_name = setting_name; + k->key = getKeySetting(k->setting_name.c_str()); + key_settings.push_back(k); +} + +void GUIKeyChangeMenu::init_keys() +{ + this->add_key(GUI_ID_KEY_FORWARD_BUTTON, wgettext("Forward"), "keymap_forward"); + this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, wgettext("Backward"), "keymap_backward"); + this->add_key(GUI_ID_KEY_LEFT_BUTTON, wgettext("Left"), "keymap_left"); + this->add_key(GUI_ID_KEY_RIGHT_BUTTON, wgettext("Right"), "keymap_right"); + this->add_key(GUI_ID_KEY_AUX1_BUTTON, wgettext("Aux1"), "keymap_aux1"); + this->add_key(GUI_ID_KEY_JUMP_BUTTON, wgettext("Jump"), "keymap_jump"); + this->add_key(GUI_ID_KEY_SNEAK_BUTTON, wgettext("Sneak"), "keymap_sneak"); + this->add_key(GUI_ID_KEY_DROP_BUTTON, wgettext("Drop"), "keymap_drop"); + this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, wgettext("Inventory"), "keymap_inventory"); + this->add_key(GUI_ID_KEY_HOTBAR_PREV_BUTTON, wgettext("Prev. item"), "keymap_hotbar_previous"); + this->add_key(GUI_ID_KEY_HOTBAR_NEXT_BUTTON, wgettext("Next item"), "keymap_hotbar_next"); + this->add_key(GUI_ID_KEY_ZOOM_BUTTON, wgettext("Zoom"), "keymap_zoom"); + this->add_key(GUI_ID_KEY_CAMERA_BUTTON, wgettext("Change camera"), "keymap_camera_mode"); + this->add_key(GUI_ID_KEY_MINIMAP_BUTTON, wgettext("Toggle minimap"), "keymap_minimap"); + this->add_key(GUI_ID_KEY_FLY_BUTTON, wgettext("Toggle fly"), "keymap_freemove"); + this->add_key(GUI_ID_KEY_PITCH_MOVE, wgettext("Toggle pitchmove"), "keymap_pitchmove"); + this->add_key(GUI_ID_KEY_FAST_BUTTON, wgettext("Toggle fast"), "keymap_fastmove"); + this->add_key(GUI_ID_KEY_NOCLIP_BUTTON, wgettext("Toggle noclip"), "keymap_noclip"); + this->add_key(GUI_ID_KEY_MUTE_BUTTON, wgettext("Mute"), "keymap_mute"); + this->add_key(GUI_ID_KEY_DEC_VOLUME_BUTTON, wgettext("Dec. volume"), "keymap_decrease_volume"); + this->add_key(GUI_ID_KEY_INC_VOLUME_BUTTON, wgettext("Inc. volume"), "keymap_increase_volume"); + this->add_key(GUI_ID_KEY_AUTOFWD_BUTTON, wgettext("Autoforward"), "keymap_autoforward"); + this->add_key(GUI_ID_KEY_CHAT_BUTTON, wgettext("Chat"), "keymap_chat"); + this->add_key(GUI_ID_KEY_SCREENSHOT_BUTTON, wgettext("Screenshot"), "keymap_screenshot"); + this->add_key(GUI_ID_KEY_RANGE_BUTTON, wgettext("Range select"), "keymap_rangeselect"); + this->add_key(GUI_ID_KEY_DEC_RANGE_BUTTON, wgettext("Dec. range"), "keymap_decrease_viewing_range_min"); + this->add_key(GUI_ID_KEY_INC_RANGE_BUTTON, wgettext("Inc. range"), "keymap_increase_viewing_range_min"); + this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, wgettext("Console"), "keymap_console"); + this->add_key(GUI_ID_KEY_CMD_BUTTON, wgettext("Command"), "keymap_cmd"); + this->add_key(GUI_ID_KEY_CMD_LOCAL_BUTTON, wgettext("Local command"), "keymap_cmd_local"); + this->add_key(GUI_ID_KEY_BLOCK_BOUNDS_BUTTON, wgettext("Block bounds"), "keymap_toggle_block_bounds"); + this->add_key(GUI_ID_KEY_HUD_BUTTON, wgettext("Toggle HUD"), "keymap_toggle_hud"); + this->add_key(GUI_ID_KEY_CHATLOG_BUTTON, wgettext("Toggle chat log"), "keymap_toggle_chat"); + this->add_key(GUI_ID_KEY_FOG_BUTTON, wgettext("Toggle fog"), "keymap_toggle_fog"); +} diff --git a/src/gui/guiKeyChangeMenu.h b/src/gui/guiKeyChangeMenu.h new file mode 100644 index 0000000..84a8987 --- /dev/null +++ b/src/gui/guiKeyChangeMenu.h @@ -0,0 +1,79 @@ +/* + Minetest + Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> + Copyright (C) 2013 Ciaran Gultnieks <ciaran@ciarang.com> + Copyright (C) 2013 teddydestodes <derkomtur@schattengang.net> + + 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.1 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "modalMenu.h" +#include "gettext.h" +#include "client/keycode.h" +#include <string> +#include <vector> + +class ISimpleTextureSource; + +struct key_setting +{ + int id; + const wchar_t *button_name; + KeyPress key; + std::string setting_name; + gui::IGUIButton *button; +}; + +class GUIKeyChangeMenu : public GUIModalMenu +{ +public: + GUIKeyChangeMenu(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id, + IMenuManager *menumgr, ISimpleTextureSource *tsrc); + ~GUIKeyChangeMenu(); + + /* + Remove and re-add (or reposition) stuff + */ + void regenerateGui(v2u32 screensize); + + void drawMenu(); + + bool acceptInput(); + + bool OnEvent(const SEvent &event); + + bool pausesGame() { return true; } + +protected: + std::wstring getLabelByID(s32 id) { return L""; } + std::string getNameByID(s32 id) { return ""; } + +private: + void init_keys(); + + bool resetMenu(); + + void add_key(int id, const wchar_t *button_name, const std::string &setting_name); + + bool shift_down = false; + + key_setting *active_key = nullptr; + gui::IGUIStaticText *key_used_text = nullptr; + std::vector<key_setting *> key_settings; + ISimpleTextureSource *m_tsrc; +}; diff --git a/src/gui/guiMainMenu.h b/src/gui/guiMainMenu.h new file mode 100644 index 0000000..9b8ff38 --- /dev/null +++ b/src/gui/guiMainMenu.h @@ -0,0 +1,57 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "gameparams.h" +#include <string> +#include <list> + +struct MainMenuDataForScript { + + MainMenuDataForScript() = default; + + // Whether the server has requested a reconnect + bool reconnect_requested = false; + std::string errormessage = ""; +}; + +struct MainMenuData { + // Client options + std::string servername; + std::string serverdescription; + std::string address; + std::string port; + std::string name; + std::string password; + // Whether to reconnect + bool do_reconnect = false; + + // Server options + int selected_world = 0; + bool simple_singleplayer_mode = false; + + // Data to be passed to the script + MainMenuDataForScript script_data; + + ELoginRegister allow_login_or_register = ELoginRegister::Any; + + MainMenuData() = default; +}; diff --git a/src/gui/guiPasswordChange.cpp b/src/gui/guiPasswordChange.cpp new file mode 100644 index 0000000..c39df17 --- /dev/null +++ b/src/gui/guiPasswordChange.cpp @@ -0,0 +1,303 @@ +/* +Part of Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013 Ciaran Gultnieks <ciaran@ciarang.com> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "guiPasswordChange.h" +#include "client/client.h" +#include "guiButton.h" +#include <IGUICheckBox.h> +#include <IGUIEditBox.h> +#include <IGUIButton.h> +#include <IGUIStaticText.h> +#include <IGUIFont.h> + +#ifdef HAVE_TOUCHSCREENGUI + #include "client/renderingengine.h" +#endif + +#include "porting.h" +#include "gettext.h" + +const int ID_oldPassword = 256; +const int ID_newPassword1 = 257; +const int ID_newPassword2 = 258; +const int ID_change = 259; +const int ID_message = 260; +const int ID_cancel = 261; + +GUIPasswordChange::GUIPasswordChange(gui::IGUIEnvironment* env, + gui::IGUIElement* parent, s32 id, + IMenuManager *menumgr, + Client* client, + ISimpleTextureSource *tsrc +): + GUIModalMenu(env, parent, id, menumgr), + m_client(client), + m_tsrc(tsrc) +{ +} + +void GUIPasswordChange::regenerateGui(v2u32 screensize) +{ + /* + save current input + */ + acceptInput(); + + /* + Remove stuff + */ + removeAllChildren(); + + /* + Calculate new sizes and positions + */ +#ifdef HAVE_TOUCHSCREENGUI + const float s = m_gui_scale * RenderingEngine::getDisplayDensity() / 2; +#else + const float s = m_gui_scale; +#endif + DesiredRect = core::rect<s32>( + screensize.X / 2 - 580 * s / 2, + screensize.Y / 2 - 300 * s / 2, + screensize.X / 2 + 580 * s / 2, + screensize.Y / 2 + 300 * s / 2 + ); + recalculateAbsolutePosition(false); + + v2s32 size = DesiredRect.getSize(); + v2s32 topleft_client(40 * s, 0); + + const wchar_t *text; + + /* + Add stuff + */ + s32 ypos = 50 * s; + { + core::rect<s32> rect(0, 0, 150 * s, 20 * s); + rect += topleft_client + v2s32(25 * s, ypos + 6 * s); + text = wgettext("Old Password"); + Environment->addStaticText(text, rect, false, true, this, -1); + delete[] text; + } + { + core::rect<s32> rect(0, 0, 230 * s, 30 * s); + rect += topleft_client + v2s32(160 * s, ypos); + gui::IGUIEditBox *e = Environment->addEditBox( + m_oldpass.c_str(), rect, true, this, ID_oldPassword); + Environment->setFocus(e); + e->setPasswordBox(true); + } + ypos += 50 * s; + { + core::rect<s32> rect(0, 0, 150 * s, 20 * s); + rect += topleft_client + v2s32(25 * s, ypos + 6 * s); + text = wgettext("New Password"); + Environment->addStaticText(text, rect, false, true, this, -1); + delete[] text; + } + { + core::rect<s32> rect(0, 0, 230 * s, 30 * s); + rect += topleft_client + v2s32(160 * s, ypos); + gui::IGUIEditBox *e = Environment->addEditBox( + m_newpass.c_str(), rect, true, this, ID_newPassword1); + e->setPasswordBox(true); + } + ypos += 50 * s; + { + core::rect<s32> rect(0, 0, 150 * s, 20 * s); + rect += topleft_client + v2s32(25 * s, ypos + 6 * s); + text = wgettext("Confirm Password"); + Environment->addStaticText(text, rect, false, true, this, -1); + delete[] text; + } + { + core::rect<s32> rect(0, 0, 230 * s, 30 * s); + rect += topleft_client + v2s32(160 * s, ypos); + gui::IGUIEditBox *e = Environment->addEditBox( + m_newpass_confirm.c_str(), rect, true, this, ID_newPassword2); + e->setPasswordBox(true); + } + + ypos += 50 * s; + { + core::rect<s32> rect(0, 0, 100 * s, 30 * s); + rect = rect + v2s32(size.X / 4 + 56 * s, ypos); + text = wgettext("Change"); + GUIButton::addButton(Environment, rect, m_tsrc, this, ID_change, text); + delete[] text; + } + { + core::rect<s32> rect(0, 0, 100 * s, 30 * s); + rect = rect + v2s32(size.X / 4 + 185 * s, ypos); + text = wgettext("Cancel"); + GUIButton::addButton(Environment, rect, m_tsrc, this, ID_cancel, text); + delete[] text; + } + + ypos += 50 * s; + { + core::rect<s32> rect(0, 0, 300 * s, 20 * s); + rect += topleft_client + v2s32(35 * s, ypos); + text = wgettext("Passwords do not match!"); + IGUIElement *e = + Environment->addStaticText( + text, rect, false, true, this, ID_message); + e->setVisible(false); + delete[] text; + } +} + +void GUIPasswordChange::drawMenu() +{ + gui::IGUISkin *skin = Environment->getSkin(); + if (!skin) + return; + video::IVideoDriver *driver = Environment->getVideoDriver(); + + video::SColor bgcolor(140, 0, 0, 0); + driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect); + + gui::IGUIElement::draw(); +#ifdef __ANDROID__ + getAndroidUIInput(); +#endif +} + +void GUIPasswordChange::acceptInput() +{ + gui::IGUIElement *e; + e = getElementFromId(ID_oldPassword); + if (e != NULL) + m_oldpass = e->getText(); + e = getElementFromId(ID_newPassword1); + if (e != NULL) + m_newpass = e->getText(); + e = getElementFromId(ID_newPassword2); + if (e != NULL) + m_newpass_confirm = e->getText(); +} + +bool GUIPasswordChange::processInput() +{ + if (m_newpass != m_newpass_confirm) { + gui::IGUIElement *e = getElementFromId(ID_message); + if (e != NULL) + e->setVisible(true); + return false; + } + m_client->sendChangePassword(wide_to_utf8(m_oldpass), wide_to_utf8(m_newpass)); + return true; +} + +bool GUIPasswordChange::OnEvent(const SEvent &event) +{ + if (event.EventType == EET_KEY_INPUT_EVENT) { + // clang-format off + if ((event.KeyInput.Key == KEY_ESCAPE || + event.KeyInput.Key == KEY_CANCEL) && + event.KeyInput.PressedDown) { + quitMenu(); + return true; + } + // clang-format on + if (event.KeyInput.Key == KEY_RETURN && event.KeyInput.PressedDown) { + acceptInput(); + if (processInput()) + quitMenu(); + return true; + } + } + if (event.EventType == EET_GUI_EVENT) { + if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST && + isVisible()) { + if (!canTakeFocus(event.GUIEvent.Element)) { + infostream << "GUIPasswordChange: Not allowing focus change." + << std::endl; + // Returning true disables focus change + return true; + } + } + if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) { + switch (event.GUIEvent.Caller->getID()) { + case ID_change: + acceptInput(); + if (processInput()) + quitMenu(); + return true; + case ID_cancel: + quitMenu(); + return true; + } + } + if (event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) { + switch (event.GUIEvent.Caller->getID()) { + case ID_oldPassword: + case ID_newPassword1: + case ID_newPassword2: + acceptInput(); + if (processInput()) + quitMenu(); + return true; + } + } + } + + return Parent ? Parent->OnEvent(event) : false; +} + +std::string GUIPasswordChange::getNameByID(s32 id) +{ + switch (id) { + case ID_oldPassword: + return "old_password"; + case ID_newPassword1: + return "new_password_1"; + case ID_newPassword2: + return "new_password_2"; + } + return ""; +} + +#ifdef __ANDROID__ +bool GUIPasswordChange::getAndroidUIInput() +{ + if (!hasAndroidUIInput()) + return false; + + // still waiting + if (porting::getInputDialogState() == -1) + return true; + + gui::IGUIElement *e = nullptr; + if (m_jni_field_name == "old_password") + e = getElementFromId(ID_oldPassword); + else if (m_jni_field_name == "new_password_1") + e = getElementFromId(ID_newPassword1); + else if (m_jni_field_name == "new_password_2") + e = getElementFromId(ID_newPassword2); + m_jni_field_name.clear(); + + if (!e || e->getType() != irr::gui::EGUIET_EDIT_BOX) + return false; + + std::string text = porting::getInputDialogValue(); + e->setText(utf8_to_wide(text).c_str()); + return false; +} +#endif diff --git a/src/gui/guiPasswordChange.h b/src/gui/guiPasswordChange.h new file mode 100644 index 0000000..452702a --- /dev/null +++ b/src/gui/guiPasswordChange.h @@ -0,0 +1,61 @@ +/* +Part of Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013 Ciaran Gultnieks <ciaran@ciarang.com> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "modalMenu.h" +#include <string> + +class Client; +class ISimpleTextureSource; + +class GUIPasswordChange : public GUIModalMenu +{ +public: + GUIPasswordChange(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id, + IMenuManager *menumgr, Client *client, + ISimpleTextureSource *tsrc); + + /* + Remove and re-add (or reposition) stuff + */ + void regenerateGui(v2u32 screensize); + + void drawMenu(); + + void acceptInput(); + + bool processInput(); + + bool OnEvent(const SEvent &event); +#ifdef __ANDROID__ + bool getAndroidUIInput(); +#endif + +protected: + std::wstring getLabelByID(s32 id) { return L""; } + std::string getNameByID(s32 id); + +private: + Client *m_client; + std::wstring m_oldpass = L""; + std::wstring m_newpass = L""; + std::wstring m_newpass_confirm = L""; + ISimpleTextureSource *m_tsrc; +}; diff --git a/src/gui/guiPathSelectMenu.cpp b/src/gui/guiPathSelectMenu.cpp new file mode 100644 index 0000000..9c63e06 --- /dev/null +++ b/src/gui/guiPathSelectMenu.cpp @@ -0,0 +1,112 @@ +/* + Minetest + Copyright (C) 2013 sapier + + 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.1 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "guiPathSelectMenu.h" + +GUIFileSelectMenu::GUIFileSelectMenu(gui::IGUIEnvironment* env, + gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, + const std::string &title, const std::string &formname, + bool is_file_select) : + GUIModalMenu(env, parent, id, menumgr), + m_title(utf8_to_wide(title)), + m_formname(formname), + m_file_select_dialog(is_file_select) +{ +} + +GUIFileSelectMenu::~GUIFileSelectMenu() +{ + setlocale(LC_NUMERIC, "C"); +} + +void GUIFileSelectMenu::regenerateGui(v2u32 screensize) +{ + removeAllChildren(); + m_fileOpenDialog = 0; + + core::dimension2du size(600 * m_gui_scale, 400 * m_gui_scale); + core::rect<s32> rect(0, 0, screensize.X, screensize.Y); + + DesiredRect = rect; + recalculateAbsolutePosition(false); + + m_fileOpenDialog = + Environment->addFileOpenDialog(m_title.c_str(), false, this, -1); + + core::position2di pos = core::position2di(screensize.X / 2 - size.Width / 2, + screensize.Y / 2 - size.Height / 2); + m_fileOpenDialog->setRelativePosition(pos); + m_fileOpenDialog->setMinSize(size); +} + +void GUIFileSelectMenu::drawMenu() +{ + gui::IGUISkin *skin = Environment->getSkin(); + if (!skin) + return; + + gui::IGUIElement::draw(); +} + +void GUIFileSelectMenu::acceptInput() +{ + if (m_text_dst && !m_formname.empty()) { + StringMap fields; + if (m_accepted) { + std::string path; + if (!m_file_select_dialog) { + core::string<fschar_t> string = + m_fileOpenDialog->getDirectoryName(); + path = std::string(string.c_str()); + } else { + path = wide_to_utf8(m_fileOpenDialog->getFileName()); + } + fields[m_formname + "_accepted"] = path; + } else { + fields[m_formname + "_canceled"] = m_formname; + } + m_text_dst->gotText(fields); + } + quitMenu(); +} + +bool GUIFileSelectMenu::OnEvent(const SEvent &event) +{ + if (event.EventType == irr::EET_GUI_EVENT) { + switch (event.GUIEvent.EventType) { + case gui::EGET_ELEMENT_CLOSED: + case gui::EGET_FILE_CHOOSE_DIALOG_CANCELLED: + m_accepted = false; + acceptInput(); + return true; + case gui::EGET_DIRECTORY_SELECTED: + m_accepted = !m_file_select_dialog; + acceptInput(); + return true; + case gui::EGET_FILE_SELECTED: + m_accepted = m_file_select_dialog; + acceptInput(); + return true; + default: + // ignore this event + break; + } + } + return Parent ? Parent->OnEvent(event) : false; +} diff --git a/src/gui/guiPathSelectMenu.h b/src/gui/guiPathSelectMenu.h new file mode 100644 index 0000000..11307d6 --- /dev/null +++ b/src/gui/guiPathSelectMenu.h @@ -0,0 +1,63 @@ +/* + Minetest + Copyright (C) 2013 sapier + + 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.1 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include <string> + +#include "modalMenu.h" +#include "IGUIFileOpenDialog.h" +#include "guiFormSpecMenu.h" //required because of TextDest only !!! + +class GUIFileSelectMenu : public GUIModalMenu +{ +public: + GUIFileSelectMenu(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id, + IMenuManager *menumgr, const std::string &title, + const std::string &formid, bool is_file_select); + ~GUIFileSelectMenu(); + + /* + Remove and re-add (or reposition) stuff + */ + void regenerateGui(v2u32 screensize); + + void drawMenu(); + + bool OnEvent(const SEvent &event); + + void setTextDest(TextDest *dest) { m_text_dst = dest; } + +protected: + std::wstring getLabelByID(s32 id) { return L""; } + std::string getNameByID(s32 id) { return ""; } + +private: + void acceptInput(); + + std::wstring m_title; + bool m_accepted = false; + + gui::IGUIFileOpenDialog *m_fileOpenDialog = nullptr; + + TextDest *m_text_dst = nullptr; + + std::string m_formname; + bool m_file_select_dialog; +}; diff --git a/src/gui/guiScene.cpp b/src/gui/guiScene.cpp new file mode 100644 index 0000000..ee2556b --- /dev/null +++ b/src/gui/guiScene.cpp @@ -0,0 +1,274 @@ +/* +Minetest +Copyright (C) 2020 Jean-Patrick Guerrero <jeanpatrick.guerrero@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiScene.h" + +#include <SViewFrustum.h> +#include <IAnimatedMeshSceneNode.h> +#include "porting.h" + +GUIScene::GUIScene(gui::IGUIEnvironment *env, scene::ISceneManager *smgr, + gui::IGUIElement *parent, core::recti rect, s32 id) + : IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rect) +{ + m_driver = env->getVideoDriver(); + m_smgr = smgr->createNewSceneManager(false); + + m_cam = m_smgr->addCameraSceneNode(0, v3f(0.f, 0.f, -100.f), v3f(0.f)); + m_cam->setFOV(30.f * core::DEGTORAD); + + m_smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); +} + +GUIScene::~GUIScene() +{ + setMesh(nullptr); + + m_smgr->drop(); +} + +scene::IAnimatedMeshSceneNode *GUIScene::setMesh(scene::IAnimatedMesh *mesh) +{ + if (m_mesh) { + m_mesh->remove(); + m_mesh = nullptr; + } + + if (!mesh) + return nullptr; + + m_mesh = m_smgr->addAnimatedMeshSceneNode(mesh); + m_mesh->setPosition(-m_mesh->getBoundingBox().getCenter()); + m_mesh->animateJoints(); + + return m_mesh; +} + +void GUIScene::setTexture(u32 idx, video::ITexture *texture) +{ + video::SMaterial &material = m_mesh->getMaterial(idx); + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + material.MaterialTypeParam = 0.5f; + material.TextureLayer[0].Texture = texture; + material.setFlag(video::EMF_LIGHTING, false); + material.setFlag(video::EMF_FOG_ENABLE, true); + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setFlag(video::EMF_BACK_FACE_CULLING, false); + material.setFlag(video::EMF_ZWRITE_ENABLE, true); +} + +void GUIScene::draw() +{ + m_driver->clearBuffers(video::ECBF_DEPTH); + + // Control rotation speed based on time + u64 new_time = porting::getTimeMs(); + u64 dtime_ms = 0; + if (m_last_time != 0) + dtime_ms = porting::getDeltaMs(m_last_time, new_time); + m_last_time = new_time; + + core::rect<s32> oldViewPort = m_driver->getViewPort(); + m_driver->setViewPort(getAbsoluteClippingRect()); + core::recti borderRect = Environment->getRootGUIElement()->getAbsoluteClippingRect(); + + if (m_bgcolor != 0) { + Environment->getSkin()->draw3DSunkenPane( + this, m_bgcolor, false, true, borderRect, 0); + } + + core::dimension2d<s32> size = getAbsoluteClippingRect().getSize(); + m_smgr->getActiveCamera()->setAspectRatio((f32)size.Width / (f32)size.Height); + + if (!m_target) { + updateCamera(m_smgr->addEmptySceneNode()); + rotateCamera(v3f(0.f)); + m_cam->bindTargetAndRotation(true); + } + + cameraLoop(); + + // Continuous rotation + if (m_inf_rot) + rotateCamera(v3f(0.f, -0.03f * (float)dtime_ms, 0.f)); + + m_smgr->drawAll(); + + if (m_initial_rotation && m_mesh) { + rotateCamera(v3f(m_custom_rot.X, m_custom_rot.Y, 0.f)); + calcOptimalDistance(); + + m_initial_rotation = false; + } + + m_driver->setViewPort(oldViewPort); +} + +bool GUIScene::OnEvent(const SEvent &event) +{ + if (m_mouse_ctrl && event.EventType == EET_MOUSE_INPUT_EVENT) { + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { + m_last_pos = v2f((f32)event.MouseInput.X, (f32)event.MouseInput.Y); + return true; + } else if (event.MouseInput.Event == EMIE_MOUSE_MOVED) { + if (event.MouseInput.isLeftPressed()) { + m_curr_pos = v2f((f32)event.MouseInput.X, (f32)event.MouseInput.Y); + + rotateCamera(v3f( + m_last_pos.Y - m_curr_pos.Y, + m_curr_pos.X - m_last_pos.X, 0.f)); + + m_last_pos = m_curr_pos; + return true; + } + } + } + + return gui::IGUIElement::OnEvent(event); +} + +void GUIScene::setStyles(const std::array<StyleSpec, StyleSpec::NUM_STATES> &styles) +{ + StyleSpec::State state = StyleSpec::STATE_DEFAULT; + StyleSpec style = StyleSpec::getStyleFromStatePropagation(styles, state); + + setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); + setBackgroundColor(style.getColor(StyleSpec::BGCOLOR, m_bgcolor)); +} + +/** + * Sets the frame loop range for the mesh + */ +void GUIScene::setFrameLoop(s32 begin, s32 end) +{ + if (m_mesh->getStartFrame() != begin || m_mesh->getEndFrame() != end) + m_mesh->setFrameLoop(begin, end); +} + +/** + * Sets the animation speed (FPS) for the mesh + */ +void GUIScene::setAnimationSpeed(f32 speed) +{ + m_mesh->setAnimationSpeed(speed); +} + +/* Camera control functions */ + +inline void GUIScene::calcOptimalDistance() +{ + core::aabbox3df box = m_mesh->getBoundingBox(); + f32 width = box.MaxEdge.X - box.MinEdge.X; + f32 height = box.MaxEdge.Y - box.MinEdge.Y; + f32 depth = box.MaxEdge.Z - box.MinEdge.Z; + f32 max_width = width > depth ? width : depth; + + const scene::SViewFrustum *f = m_cam->getViewFrustum(); + f32 cam_far = m_cam->getFarValue(); + f32 far_width = core::line3df(f->getFarLeftUp(), f->getFarRightUp()).getLength(); + f32 far_height = core::line3df(f->getFarLeftUp(), f->getFarLeftDown()).getLength(); + + core::recti rect = getAbsolutePosition(); + f32 zoomX = rect.getWidth() / max_width; + f32 zoomY = rect.getHeight() / height; + f32 dist; + + if (zoomX < zoomY) + dist = (max_width / (far_width / cam_far)) + (0.5f * max_width); + else + dist = (height / (far_height / cam_far)) + (0.5f * max_width); + + m_cam_distance = dist; + m_update_cam = true; +} + +void GUIScene::updateCamera(scene::ISceneNode *target) +{ + m_target = target; + updateTargetPos(); + + m_last_target_pos = m_target_pos; + updateCameraPos(); + + m_update_cam = true; +} + +void GUIScene::updateTargetPos() +{ + m_last_target_pos = m_target_pos; + m_target->updateAbsolutePosition(); + m_target_pos = m_target->getAbsolutePosition(); +} + +void GUIScene::setCameraRotation(v3f rot) +{ + correctBounds(rot); + + core::matrix4 mat; + mat.setRotationDegrees(rot); + + m_cam_pos = v3f(0.f, 0.f, m_cam_distance); + mat.rotateVect(m_cam_pos); + + m_cam_pos += m_target_pos; + m_cam->setPosition(m_cam_pos); + m_update_cam = false; +} + +bool GUIScene::correctBounds(v3f &rot) +{ + const float ROTATION_MAX_1 = 60.0f; + const float ROTATION_MAX_2 = 300.0f; + + // Limit and correct the rotation when needed + if (rot.X < 90.f) { + if (rot.X > ROTATION_MAX_1) { + rot.X = ROTATION_MAX_1; + return true; + } + } else if (rot.X < ROTATION_MAX_2) { + rot.X = ROTATION_MAX_2; + return true; + } + + // Not modified + return false; +} + +void GUIScene::cameraLoop() +{ + updateCameraPos(); + updateTargetPos(); + + if (m_target_pos != m_last_target_pos) + m_update_cam = true; + + if (m_update_cam) { + m_cam_pos = m_target_pos + (m_cam_pos - m_target_pos).normalize() * m_cam_distance; + + v3f rot = getCameraRotation(); + if (correctBounds(rot)) + setCameraRotation(rot); + + m_cam->setPosition(m_cam_pos); + m_cam->setTarget(m_target_pos); + + m_update_cam = false; + } +} diff --git a/src/gui/guiScene.h b/src/gui/guiScene.h new file mode 100644 index 0000000..0f5f3a8 --- /dev/null +++ b/src/gui/guiScene.h @@ -0,0 +1,87 @@ +/* +Minetest +Copyright (C) 2020 Jean-Patrick Guerrero <jeanpatrick.guerrero@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "ICameraSceneNode.h" +#include "StyleSpec.h" + +using namespace irr; + +class GUIScene : public gui::IGUIElement +{ +public: + GUIScene(gui::IGUIEnvironment *env, scene::ISceneManager *smgr, + gui::IGUIElement *parent, core::recti rect, s32 id = -1); + + ~GUIScene(); + + scene::IAnimatedMeshSceneNode *setMesh(scene::IAnimatedMesh *mesh = nullptr); + void setTexture(u32 idx, video::ITexture *texture); + void setBackgroundColor(const video::SColor &color) noexcept { m_bgcolor = color; }; + void setFrameLoop(s32 begin, s32 end); + void setAnimationSpeed(f32 speed); + void enableMouseControl(bool enable) noexcept { m_mouse_ctrl = enable; }; + void setRotation(v2f rot) noexcept { m_custom_rot = rot; }; + void enableContinuousRotation(bool enable) noexcept { m_inf_rot = enable; }; + void setStyles(const std::array<StyleSpec, StyleSpec::NUM_STATES> &styles); + + virtual void draw(); + virtual bool OnEvent(const SEvent &event); + +private: + void calcOptimalDistance(); + void updateTargetPos(); + void updateCamera(scene::ISceneNode *target); + void setCameraRotation(v3f rot); + /// @return true indicates that the rotation was corrected + bool correctBounds(v3f &rot); + void cameraLoop(); + + void updateCameraPos() { m_cam_pos = m_cam->getPosition(); }; + v3f getCameraRotation() const { return (m_cam_pos - m_target_pos).getHorizontalAngle(); }; + void rotateCamera(const v3f &delta) { setCameraRotation(getCameraRotation() + delta); }; + + scene::ISceneManager *m_smgr; + video::IVideoDriver *m_driver; + scene::ICameraSceneNode *m_cam; + scene::ISceneNode *m_target = nullptr; + scene::IAnimatedMeshSceneNode *m_mesh = nullptr; + + f32 m_cam_distance = 50.f; + + u64 m_last_time = 0; + + v3f m_cam_pos; + v3f m_target_pos; + v3f m_last_target_pos; + // Cursor positions + v2f m_curr_pos; + v2f m_last_pos; + // Initial rotation + v2f m_custom_rot; + + bool m_mouse_ctrl = true; + bool m_update_cam = false; + bool m_inf_rot = false; + bool m_initial_rotation = true; + + video::SColor m_bgcolor = 0; +}; diff --git a/src/gui/guiScrollBar.cpp b/src/gui/guiScrollBar.cpp new file mode 100644 index 0000000..c6a03f3 --- /dev/null +++ b/src/gui/guiScrollBar.cpp @@ -0,0 +1,446 @@ +/* +Copyright (C) 2002-2013 Nikolaus Gebhardt +This file is part of the "Irrlicht Engine". +For conditions of distribution and use, see copyright notice in irrlicht.h + +Modified 2019.05.01 by stujones11, Stuart Jones <stujones111@gmail.com> + +This is a heavily modified copy of the Irrlicht CGUIScrollBar class +which includes automatic scaling of the thumb slider and hiding of +the arrow buttons where there is insufficient space. +*/ + +#include "guiScrollBar.h" +#include <IGUIButton.h> +#include <IGUISkin.h> + +GUIScrollBar::GUIScrollBar(IGUIEnvironment *environment, IGUIElement *parent, s32 id, + core::rect<s32> rectangle, bool horizontal, bool auto_scale) : + IGUIElement(EGUIET_ELEMENT, environment, parent, id, rectangle), + up_button(nullptr), down_button(nullptr), is_dragging(false), + is_horizontal(horizontal), is_auto_scaling(auto_scale), + dragged_by_slider(false), tray_clicked(false), scroll_pos(0), + draw_center(0), thumb_size(0), min_pos(0), max_pos(100), small_step(10), + large_step(50), drag_offset(0), page_size(100), border_size(0) +{ + refreshControls(); + setNotClipped(false); + setTabStop(true); + setTabOrder(-1); + setPos(0); +} + +bool GUIScrollBar::OnEvent(const SEvent &event) +{ + if (isEnabled()) { + switch (event.EventType) { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown) { + const s32 old_pos = scroll_pos; + bool absorb = true; + switch (event.KeyInput.Key) { + case KEY_LEFT: + case KEY_UP: + setPos(scroll_pos - small_step); + break; + case KEY_RIGHT: + case KEY_DOWN: + setPos(scroll_pos + small_step); + break; + case KEY_HOME: + setPos(min_pos); + break; + case KEY_PRIOR: + setPos(scroll_pos - large_step); + break; + case KEY_END: + setPos(max_pos); + break; + case KEY_NEXT: + setPos(scroll_pos + large_step); + break; + default: + absorb = false; + } + if (scroll_pos != old_pos) { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = nullptr; + e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(e); + } + if (absorb) + return true; + } + break; + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED) { + if (event.GUIEvent.Caller == up_button) + setPos(scroll_pos - small_step); + else if (event.GUIEvent.Caller == down_button) + setPos(scroll_pos + small_step); + + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = nullptr; + e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(e); + return true; + } else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + if (event.GUIEvent.Caller == this) + is_dragging = false; + break; + case EET_MOUSE_INPUT_EVENT: { + const core::position2di p(event.MouseInput.X, event.MouseInput.Y); + bool is_inside = isPointInside(p); + switch (event.MouseInput.Event) { + case EMIE_MOUSE_WHEEL: + if (Environment->hasFocus(this)) { + s8 d = event.MouseInput.Wheel < 0 ? -1 : 1; + s8 h = is_horizontal ? 1 : -1; + setPos(getPos() + (d * small_step * h)); + + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = nullptr; + e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(e); + return true; + } + break; + case EMIE_LMOUSE_PRESSED_DOWN: { + if (is_inside) { + is_dragging = true; + dragged_by_slider = slider_rect.isPointInside(p); + core::vector2di corner = slider_rect.UpperLeftCorner; + drag_offset = is_horizontal ? p.X - corner.X : p.Y - corner.Y; + tray_clicked = !dragged_by_slider; + if (tray_clicked) { + const s32 new_pos = getPosFromMousePos(p); + const s32 old_pos = scroll_pos; + setPos(new_pos); + // drag in the middle + drag_offset = thumb_size / 2; + // report the scroll event + if (scroll_pos != old_pos && Parent) { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = nullptr; + e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(e); + } + } + Environment->setFocus(this); + return true; + } + break; + } + case EMIE_LMOUSE_LEFT_UP: + case EMIE_MOUSE_MOVED: { + if (!event.MouseInput.isLeftPressed()) + is_dragging = false; + + if (!is_dragging) { + if (event.MouseInput.Event == EMIE_MOUSE_MOVED) + break; + return is_inside; + } + + if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) + is_dragging = false; + + // clang-format off + if (!dragged_by_slider) { + if (is_inside) { + dragged_by_slider = slider_rect.isPointInside(p); + tray_clicked = !dragged_by_slider; + } + if (!dragged_by_slider) { + tray_clicked = false; + if (event.MouseInput.Event == EMIE_MOUSE_MOVED) + return is_inside; + } + } + // clang-format on + + const s32 new_pos = getPosFromMousePos(p); + const s32 old_pos = scroll_pos; + + setPos(new_pos); + + if (scroll_pos != old_pos && Parent) { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = nullptr; + e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(e); + } + return is_inside; + } + default: + break; + } + } break; + default: + break; + } + } + return IGUIElement::OnEvent(event); +} + +void GUIScrollBar::draw() +{ + if (!IsVisible) + return; + + IGUISkin *skin = Environment->getSkin(); + if (!skin) + return; + + video::SColor icon_color = skin->getColor( + isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL); + if (icon_color != current_icon_color) + refreshControls(); + + slider_rect = AbsoluteRect; + skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR), slider_rect, + &AbsoluteClippingRect); + + if (core::isnotzero(range())) { + if (is_horizontal) { + slider_rect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + + draw_center - thumb_size / 2; + slider_rect.LowerRightCorner.X = + slider_rect.UpperLeftCorner.X + thumb_size; + } else { + slider_rect.UpperLeftCorner.Y = AbsoluteRect.UpperLeftCorner.Y + + draw_center - thumb_size / 2; + slider_rect.LowerRightCorner.Y = + slider_rect.UpperLeftCorner.Y + thumb_size; + } + skin->draw3DButtonPaneStandard(this, slider_rect, &AbsoluteClippingRect); + } + IGUIElement::draw(); +} + +void GUIScrollBar::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + refreshControls(); + setPos(scroll_pos); +} + +s32 GUIScrollBar::getPosFromMousePos(const core::position2di &pos) const +{ + s32 w, p; + s32 offset = dragged_by_slider ? drag_offset : thumb_size / 2; + + if (is_horizontal) { + w = RelativeRect.getWidth() - border_size * 2 - thumb_size; + p = pos.X - AbsoluteRect.UpperLeftCorner.X - border_size - offset; + } else { + w = RelativeRect.getHeight() - border_size * 2 - thumb_size; + p = pos.Y - AbsoluteRect.UpperLeftCorner.Y - border_size - offset; + } + return core::isnotzero(range()) ? s32(f32(p) / f32(w) * range() + 0.5f) + min_pos : 0; +} + +void GUIScrollBar::setPos(const s32 &pos) +{ + s32 thumb_area = 0; + s32 thumb_min = 0; + + if (is_horizontal) { + thumb_min = RelativeRect.getHeight(); + thumb_area = RelativeRect.getWidth() - border_size * 2; + } else { + thumb_min = RelativeRect.getWidth(); + thumb_area = RelativeRect.getHeight() - border_size * 2; + } + + if (is_auto_scaling) + thumb_size = s32(thumb_area / + (f32(page_size) / f32(thumb_area + border_size * 2))); + + thumb_size = core::s32_clamp(thumb_size, thumb_min, thumb_area); + scroll_pos = core::s32_clamp(pos, min_pos, max_pos); + + f32 f = core::isnotzero(range()) ? (f32(thumb_area) - f32(thumb_size)) / range() + : 1.0f; + draw_center = s32((f32(scroll_pos - min_pos) * f) + (f32(thumb_size) * 0.5f)) + + border_size; +} + +void GUIScrollBar::setSmallStep(const s32 &step) +{ + small_step = step > 0 ? step : 10; +} + +void GUIScrollBar::setLargeStep(const s32 &step) +{ + large_step = step > 0 ? step : 50; +} + +void GUIScrollBar::setMax(const s32 &max) +{ + max_pos = max; + if (min_pos > max_pos) + min_pos = max_pos; + + bool enable = core::isnotzero(range()); + up_button->setEnabled(enable); + down_button->setEnabled(enable); + setPos(scroll_pos); +} + +void GUIScrollBar::setMin(const s32 &min) +{ + min_pos = min; + if (max_pos < min_pos) + max_pos = min_pos; + + bool enable = core::isnotzero(range()); + up_button->setEnabled(enable); + down_button->setEnabled(enable); + setPos(scroll_pos); +} + +void GUIScrollBar::setPageSize(const s32 &size) +{ + page_size = size; + setPos(scroll_pos); +} + +void GUIScrollBar::setArrowsVisible(ArrowVisibility visible) +{ + arrow_visibility = visible; + refreshControls(); +} + +s32 GUIScrollBar::getPos() const +{ + return scroll_pos; +} + +void GUIScrollBar::refreshControls() +{ + IGUISkin *skin = Environment->getSkin(); + IGUISpriteBank *sprites = nullptr; + current_icon_color = video::SColor(255, 255, 255, 255); + + if (skin) { + sprites = skin->getSpriteBank(); + current_icon_color = + skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL + : EGDC_GRAY_WINDOW_SYMBOL); + } + if (is_horizontal) { + s32 h = RelativeRect.getHeight(); + border_size = RelativeRect.getWidth() < h * 4 ? 0 : h; + if (!up_button) { + up_button = Environment->addButton( + core::rect<s32>(0, 0, h, h), this); + up_button->setSubElement(true); + up_button->setTabStop(false); + } + if (sprites) { + up_button->setSpriteBank(sprites); + up_button->setSprite(EGBS_BUTTON_UP, + s32(skin->getIcon(EGDI_CURSOR_LEFT)), + current_icon_color); + up_button->setSprite(EGBS_BUTTON_DOWN, + s32(skin->getIcon(EGDI_CURSOR_LEFT)), + current_icon_color); + } + up_button->setRelativePosition(core::rect<s32>(0, 0, h, h)); + up_button->setAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, + EGUIA_LOWERRIGHT); + if (!down_button) { + down_button = Environment->addButton( + core::rect<s32>(RelativeRect.getWidth() - h, 0, + RelativeRect.getWidth(), h), + this); + down_button->setSubElement(true); + down_button->setTabStop(false); + } + if (sprites) { + down_button->setSpriteBank(sprites); + down_button->setSprite(EGBS_BUTTON_UP, + s32(skin->getIcon(EGDI_CURSOR_RIGHT)), + current_icon_color); + down_button->setSprite(EGBS_BUTTON_DOWN, + s32(skin->getIcon(EGDI_CURSOR_RIGHT)), + current_icon_color); + } + down_button->setRelativePosition( + core::rect<s32>(RelativeRect.getWidth() - h, 0, + RelativeRect.getWidth(), h)); + down_button->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, + EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + } else { + s32 w = RelativeRect.getWidth(); + border_size = RelativeRect.getHeight() < w * 4 ? 0 : w; + if (!up_button) { + up_button = Environment->addButton( + core::rect<s32>(0, 0, w, w), this); + up_button->setSubElement(true); + up_button->setTabStop(false); + } + if (sprites) { + up_button->setSpriteBank(sprites); + up_button->setSprite(EGBS_BUTTON_UP, + s32(skin->getIcon(EGDI_CURSOR_UP)), + current_icon_color); + up_button->setSprite(EGBS_BUTTON_DOWN, + s32(skin->getIcon(EGDI_CURSOR_UP)), + current_icon_color); + } + up_button->setRelativePosition(core::rect<s32>(0, 0, w, w)); + up_button->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, + EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + if (!down_button) { + down_button = Environment->addButton( + core::rect<s32>(0, RelativeRect.getHeight() - w, + w, RelativeRect.getHeight()), + this); + down_button->setSubElement(true); + down_button->setTabStop(false); + } + if (sprites) { + down_button->setSpriteBank(sprites); + down_button->setSprite(EGBS_BUTTON_UP, + s32(skin->getIcon(EGDI_CURSOR_DOWN)), + current_icon_color); + down_button->setSprite(EGBS_BUTTON_DOWN, + s32(skin->getIcon(EGDI_CURSOR_DOWN)), + current_icon_color); + } + down_button->setRelativePosition( + core::rect<s32>(0, RelativeRect.getHeight() - w, w, + RelativeRect.getHeight())); + down_button->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, + EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT); + } + + bool visible; + if (arrow_visibility == DEFAULT) + visible = (border_size != 0); + else if (arrow_visibility == HIDE) { + visible = false; + border_size = 0; + } else { + visible = true; + if (is_horizontal) + border_size = RelativeRect.getHeight(); + else + border_size = RelativeRect.getWidth(); + } + + up_button->setVisible(visible); + down_button->setVisible(visible); +} diff --git a/src/gui/guiScrollBar.h b/src/gui/guiScrollBar.h new file mode 100644 index 0000000..d18f8e8 --- /dev/null +++ b/src/gui/guiScrollBar.h @@ -0,0 +1,77 @@ +/* +Copyright (C) 2002-2013 Nikolaus Gebhardt +This file is part of the "Irrlicht Engine". +For conditions of distribution and use, see copyright notice in irrlicht.h + +Modified 2019.05.01 by stujones11, Stuart Jones <stujones111@gmail.com> + +This is a heavily modified copy of the Irrlicht CGUIScrollBar class +which includes automatic scaling of the thumb slider and hiding of +the arrow buttons where there is insufficient space. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" + +using namespace irr; +using namespace gui; + +class GUIScrollBar : public IGUIElement +{ +public: + GUIScrollBar(IGUIEnvironment *environment, IGUIElement *parent, s32 id, + core::rect<s32> rectangle, bool horizontal, bool auto_scale); + + enum ArrowVisibility + { + HIDE, + SHOW, + DEFAULT + }; + + virtual void draw(); + virtual void updateAbsolutePosition(); + virtual bool OnEvent(const SEvent &event); + + s32 getMax() const { return max_pos; } + s32 getMin() const { return min_pos; } + s32 getLargeStep() const { return large_step; } + s32 getSmallStep() const { return small_step; } + s32 getPos() const; + + void setMax(const s32 &max); + void setMin(const s32 &min); + void setSmallStep(const s32 &step); + void setLargeStep(const s32 &step); + void setPos(const s32 &pos); + void setPageSize(const s32 &size); + void setArrowsVisible(ArrowVisibility visible); + +private: + void refreshControls(); + s32 getPosFromMousePos(const core::position2di &p) const; + f32 range() const { return f32(max_pos - min_pos); } + + IGUIButton *up_button; + IGUIButton *down_button; + ArrowVisibility arrow_visibility = DEFAULT; + bool is_dragging; + bool is_horizontal; + bool is_auto_scaling; + bool dragged_by_slider; + bool tray_clicked; + s32 scroll_pos; + s32 draw_center; + s32 thumb_size; + s32 min_pos; + s32 max_pos; + s32 small_step; + s32 large_step; + s32 drag_offset; + s32 page_size; + s32 border_size; + + core::rect<s32> slider_rect; + video::SColor current_icon_color; +}; diff --git a/src/gui/guiScrollContainer.cpp b/src/gui/guiScrollContainer.cpp new file mode 100644 index 0000000..2d71f34 --- /dev/null +++ b/src/gui/guiScrollContainer.cpp @@ -0,0 +1,81 @@ +/* +Minetest +Copyright (C) 2020 DS + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiScrollContainer.h" + +GUIScrollContainer::GUIScrollContainer(gui::IGUIEnvironment *env, + gui::IGUIElement *parent, s32 id, const core::rect<s32> &rectangle, + const std::string &orientation, f32 scrollfactor) : + gui::IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rectangle), + m_scrollbar(nullptr), m_scrollfactor(scrollfactor) +{ + if (orientation == "vertical") + m_orientation = VERTICAL; + else if (orientation == "horizontal") + m_orientation = HORIZONTAL; + else + m_orientation = UNDEFINED; +} + +bool GUIScrollContainer::OnEvent(const SEvent &event) +{ + if (event.EventType == EET_MOUSE_INPUT_EVENT && + event.MouseInput.Event == EMIE_MOUSE_WHEEL && + !event.MouseInput.isLeftPressed() && m_scrollbar) { + Environment->setFocus(m_scrollbar); + bool retval = m_scrollbar->OnEvent(event); + + // a hacky fix for updating the hovering and co. + IGUIElement *hovered_elem = getElementFromPoint(core::position2d<s32>( + event.MouseInput.X, event.MouseInput.Y)); + SEvent mov_event = event; + mov_event.MouseInput.Event = EMIE_MOUSE_MOVED; + Environment->postEventFromUser(mov_event); + if (hovered_elem) + hovered_elem->OnEvent(mov_event); + + return retval; + } + + return IGUIElement::OnEvent(event); +} + +void GUIScrollContainer::draw() +{ + if (isVisible()) { + for (auto child : Children) + if (child->isNotClipped() || + AbsoluteClippingRect.isRectCollided( + child->getAbsolutePosition())) + child->draw(); + } +} + +void GUIScrollContainer::updateScrolling() +{ + s32 pos = m_scrollbar->getPos(); + core::rect<s32> rect = getRelativePosition(); + + if (m_orientation == VERTICAL) + rect.UpperLeftCorner.Y = pos * m_scrollfactor; + else if (m_orientation == HORIZONTAL) + rect.UpperLeftCorner.X = pos * m_scrollfactor; + + setRelativePosition(rect); +} diff --git a/src/gui/guiScrollContainer.h b/src/gui/guiScrollContainer.h new file mode 100644 index 0000000..9e3ec6e --- /dev/null +++ b/src/gui/guiScrollContainer.h @@ -0,0 +1,62 @@ +/* +Minetest +Copyright (C) 2020 DS + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "util/string.h" +#include "guiScrollBar.h" + +class GUIScrollContainer : public gui::IGUIElement +{ +public: + GUIScrollContainer(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id, + const core::rect<s32> &rectangle, const std::string &orientation, + f32 scrollfactor); + + virtual bool OnEvent(const SEvent &event) override; + + virtual void draw() override; + + inline void onScrollEvent(gui::IGUIElement *caller) + { + if (caller == m_scrollbar) + updateScrolling(); + } + + inline void setScrollBar(GUIScrollBar *scrollbar) + { + m_scrollbar = scrollbar; + updateScrolling(); + } + +private: + enum OrientationEnum + { + VERTICAL, + HORIZONTAL, + UNDEFINED + }; + + GUIScrollBar *m_scrollbar; + OrientationEnum m_orientation; + f32 m_scrollfactor; + + void updateScrolling(); +}; diff --git a/src/gui/guiSkin.cpp b/src/gui/guiSkin.cpp new file mode 100644 index 0000000..6440379 --- /dev/null +++ b/src/gui/guiSkin.cpp @@ -0,0 +1,1042 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// Copyright (C) 2019 Irrlick +// +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "guiSkin.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIFont.h" +#include "IGUISpriteBank.h" +#include "IGUIElement.h" +#include "IVideoDriver.h" +#include "IAttributes.h" + +namespace irr +{ +namespace gui +{ + +GUISkin::GUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver) +: SpriteBank(0), Driver(driver), Type(type) +{ + #ifdef _DEBUG + setDebugName("GUISkin"); + #endif + + if ((Type == EGST_WINDOWS_CLASSIC) || (Type == EGST_WINDOWS_METALLIC)) + { + Colors[EGDC_3D_DARK_SHADOW] = video::SColor(101,50,50,50); + Colors[EGDC_3D_SHADOW] = video::SColor(101,130,130,130); + Colors[EGDC_3D_FACE] = video::SColor(220,100,100,100); + Colors[EGDC_3D_HIGH_LIGHT] = video::SColor(101,255,255,255); + Colors[EGDC_3D_LIGHT] = video::SColor(101,210,210,210); + Colors[EGDC_ACTIVE_BORDER] = video::SColor(101,16,14,115); + Colors[EGDC_ACTIVE_CAPTION] = video::SColor(255,255,255,255); + Colors[EGDC_APP_WORKSPACE] = video::SColor(101,100,100,100); + Colors[EGDC_BUTTON_TEXT] = video::SColor(240,10,10,10); + Colors[EGDC_GRAY_TEXT] = video::SColor(240,130,130,130); + Colors[EGDC_HIGH_LIGHT] = video::SColor(101,8,36,107); + Colors[EGDC_HIGH_LIGHT_TEXT] = video::SColor(240,255,255,255); + Colors[EGDC_INACTIVE_BORDER] = video::SColor(101,165,165,165); + Colors[EGDC_INACTIVE_CAPTION] = video::SColor(255,30,30,30); + Colors[EGDC_TOOLTIP] = video::SColor(200,0,0,0); + Colors[EGDC_TOOLTIP_BACKGROUND] = video::SColor(200,255,255,225); + Colors[EGDC_SCROLLBAR] = video::SColor(101,230,230,230); + Colors[EGDC_WINDOW] = video::SColor(101,255,255,255); + Colors[EGDC_WINDOW_SYMBOL] = video::SColor(200,10,10,10); + Colors[EGDC_ICON] = video::SColor(200,255,255,255); + Colors[EGDC_ICON_HIGH_LIGHT] = video::SColor(200,8,36,107); + Colors[EGDC_GRAY_WINDOW_SYMBOL] = video::SColor(240,100,100,100); + Colors[EGDC_EDITABLE] = video::SColor(255,255,255,255); + Colors[EGDC_GRAY_EDITABLE] = video::SColor(255,120,120,120); + Colors[EGDC_FOCUSED_EDITABLE] = video::SColor(255,240,240,255); + + + Sizes[EGDS_SCROLLBAR_SIZE] = 14; + Sizes[EGDS_MENU_HEIGHT] = 30; + Sizes[EGDS_WINDOW_BUTTON_WIDTH] = 15; + Sizes[EGDS_CHECK_BOX_WIDTH] = 18; + Sizes[EGDS_MESSAGE_BOX_WIDTH] = 500; + Sizes[EGDS_MESSAGE_BOX_HEIGHT] = 200; + Sizes[EGDS_BUTTON_WIDTH] = 80; + Sizes[EGDS_BUTTON_HEIGHT] = 30; + + Sizes[EGDS_TEXT_DISTANCE_X] = 2; + Sizes[EGDS_TEXT_DISTANCE_Y] = 0; + + Sizes[EGDS_TITLEBARTEXT_DISTANCE_X] = 2; + Sizes[EGDS_TITLEBARTEXT_DISTANCE_Y] = 0; + } + else + { + //0x80a6a8af + Colors[EGDC_3D_DARK_SHADOW] = 0x60767982; + //Colors[EGDC_3D_FACE] = 0xc0c9ccd4; // tab background + Colors[EGDC_3D_FACE] = 0xc0cbd2d9; // tab background + Colors[EGDC_3D_SHADOW] = 0x50e4e8f1; // tab background, and left-top highlight + Colors[EGDC_3D_HIGH_LIGHT] = 0x40c7ccdc; + Colors[EGDC_3D_LIGHT] = 0x802e313a; + Colors[EGDC_ACTIVE_BORDER] = 0x80404040; // window title + Colors[EGDC_ACTIVE_CAPTION] = 0xffd0d0d0; + Colors[EGDC_APP_WORKSPACE] = 0xc0646464; // unused + Colors[EGDC_BUTTON_TEXT] = 0xd0161616; + Colors[EGDC_GRAY_TEXT] = 0x3c141414; + Colors[EGDC_HIGH_LIGHT] = 0x6c606060; + Colors[EGDC_HIGH_LIGHT_TEXT] = 0xd0e0e0e0; + Colors[EGDC_INACTIVE_BORDER] = 0xf0a5a5a5; + Colors[EGDC_INACTIVE_CAPTION] = 0xffd2d2d2; + Colors[EGDC_TOOLTIP] = 0xf00f2033; + Colors[EGDC_TOOLTIP_BACKGROUND] = 0xc0cbd2d9; + Colors[EGDC_SCROLLBAR] = 0xf0e0e0e0; + Colors[EGDC_WINDOW] = 0xf0f0f0f0; + Colors[EGDC_WINDOW_SYMBOL] = 0xd0161616; + Colors[EGDC_ICON] = 0xd0161616; + Colors[EGDC_ICON_HIGH_LIGHT] = 0xd0606060; + Colors[EGDC_GRAY_WINDOW_SYMBOL] = 0x3c101010; + Colors[EGDC_EDITABLE] = 0xf0ffffff; + Colors[EGDC_GRAY_EDITABLE] = 0xf0cccccc; + Colors[EGDC_FOCUSED_EDITABLE] = 0xf0fffff0; + + Sizes[EGDS_SCROLLBAR_SIZE] = 14; + Sizes[EGDS_MENU_HEIGHT] = 48; + Sizes[EGDS_WINDOW_BUTTON_WIDTH] = 15; + Sizes[EGDS_CHECK_BOX_WIDTH] = 18; + Sizes[EGDS_MESSAGE_BOX_WIDTH] = 500; + Sizes[EGDS_MESSAGE_BOX_HEIGHT] = 200; + Sizes[EGDS_BUTTON_WIDTH] = 80; + Sizes[EGDS_BUTTON_HEIGHT] = 30; + + Sizes[EGDS_TEXT_DISTANCE_X] = 3; + Sizes[EGDS_TEXT_DISTANCE_Y] = 2; + + Sizes[EGDS_TITLEBARTEXT_DISTANCE_X] = 3; + Sizes[EGDS_TITLEBARTEXT_DISTANCE_Y] = 2; + } + + Sizes[EGDS_MESSAGE_BOX_GAP_SPACE] = 15; + Sizes[EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH] = 0; + Sizes[EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH] = 500; + Sizes[EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT] = 0; + Sizes[EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT] = 99999; + + Sizes[EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X] = 1; + Sizes[EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y] = 1; + Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_X] = 0; + Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y] = 2; + + Texts[EGDT_MSG_BOX_OK] = L"OK"; + Texts[EGDT_MSG_BOX_CANCEL] = L"Cancel"; + Texts[EGDT_MSG_BOX_YES] = L"Yes"; + Texts[EGDT_MSG_BOX_NO] = L"No"; + Texts[EGDT_WINDOW_CLOSE] = L"Close"; + Texts[EGDT_WINDOW_RESTORE] = L"Restore"; + Texts[EGDT_WINDOW_MINIMIZE] = L"Minimize"; + Texts[EGDT_WINDOW_MAXIMIZE] = L"Maximize"; + + Icons[EGDI_WINDOW_MAXIMIZE] = 225; + Icons[EGDI_WINDOW_RESTORE] = 226; + Icons[EGDI_WINDOW_CLOSE] = 227; + Icons[EGDI_WINDOW_MINIMIZE] = 228; + Icons[EGDI_CURSOR_UP] = 229; + Icons[EGDI_CURSOR_DOWN] = 230; + Icons[EGDI_CURSOR_LEFT] = 231; + Icons[EGDI_CURSOR_RIGHT] = 232; + Icons[EGDI_MENU_MORE] = 232; + Icons[EGDI_CHECK_BOX_CHECKED] = 233; + Icons[EGDI_DROP_DOWN] = 234; + Icons[EGDI_SMALL_CURSOR_UP] = 235; + Icons[EGDI_SMALL_CURSOR_DOWN] = 236; + Icons[EGDI_RADIO_BUTTON_CHECKED] = 237; + Icons[EGDI_MORE_LEFT] = 238; + Icons[EGDI_MORE_RIGHT] = 239; + Icons[EGDI_MORE_UP] = 240; + Icons[EGDI_MORE_DOWN] = 241; + Icons[EGDI_WINDOW_RESIZE] = 242; + Icons[EGDI_EXPAND] = 243; + Icons[EGDI_COLLAPSE] = 244; + + Icons[EGDI_FILE] = 245; + Icons[EGDI_DIRECTORY] = 246; + + for (u32 i=0; i<EGDF_COUNT; ++i) + Fonts[i] = 0; + + UseGradient = (Type == EGST_WINDOWS_METALLIC) || (Type == EGST_BURNING_SKIN) ; +} + + +//! destructor +GUISkin::~GUISkin() +{ + for (u32 i=0; i<EGDF_COUNT; ++i) + { + if (Fonts[i]) + Fonts[i]->drop(); + } + + if (SpriteBank) + SpriteBank->drop(); +} + + +//! returns default color +video::SColor GUISkin::getColor(EGUI_DEFAULT_COLOR color) const +{ + if ((u32)color < EGDC_COUNT) + return Colors[color]; + else + return video::SColor(); +} + + +//! sets a default color +void GUISkin::setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor) +{ + if ((u32)which < EGDC_COUNT) + Colors[which] = newColor; +} + + +//! returns size for the given size type +s32 GUISkin::getSize(EGUI_DEFAULT_SIZE size) const +{ + if ((u32)size < EGDS_COUNT) + return Sizes[size]; + else + return 0; +} + + +//! sets a default size +void GUISkin::setSize(EGUI_DEFAULT_SIZE which, s32 size) +{ + if ((u32)which < EGDS_COUNT) + Sizes[which] = size; +} + + +//! returns the default font +IGUIFont* GUISkin::getFont(EGUI_DEFAULT_FONT which) const +{ + if (((u32)which < EGDF_COUNT) && Fonts[which]) + return Fonts[which]; + else + return Fonts[EGDF_DEFAULT]; +} + + +//! sets a default font +void GUISkin::setFont(IGUIFont* font, EGUI_DEFAULT_FONT which) +{ + if ((u32)which >= EGDF_COUNT) + return; + + if (font) + { + font->grab(); + if (Fonts[which]) + Fonts[which]->drop(); + + Fonts[which] = font; + } +} + + +//! gets the sprite bank stored +IGUISpriteBank* GUISkin::getSpriteBank() const +{ + return SpriteBank; +} + + +//! set a new sprite bank or remove one by passing 0 +void GUISkin::setSpriteBank(IGUISpriteBank* bank) +{ + if (bank) + bank->grab(); + + if (SpriteBank) + SpriteBank->drop(); + + SpriteBank = bank; +} + + +//! Returns a default icon +u32 GUISkin::getIcon(EGUI_DEFAULT_ICON icon) const +{ + if ((u32)icon < EGDI_COUNT) + return Icons[icon]; + else + return 0; +} + + +//! Sets a default icon +void GUISkin::setIcon(EGUI_DEFAULT_ICON icon, u32 index) +{ + if ((u32)icon < EGDI_COUNT) + Icons[icon] = index; +} + + +//! Returns a default text. For example for Message box button captions: +//! "OK", "Cancel", "Yes", "No" and so on. +const wchar_t* GUISkin::getDefaultText(EGUI_DEFAULT_TEXT text) const +{ + if ((u32)text < EGDT_COUNT) + return Texts[text].c_str(); + else + return Texts[0].c_str(); +} + + +//! Sets a default text. For example for Message box button captions: +//! "OK", "Cancel", "Yes", "No" and so on. +void GUISkin::setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText) +{ + if ((u32)which < EGDT_COUNT) + Texts[which] = newText; +} + + +//! draws a standard 3d button pane +/** Used for drawing for example buttons in normal state. +It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and +EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. +\param rect: Defining area where to draw. +\param clip: Clip area. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. */ +// PATCH +void GUISkin::drawColored3DButtonPaneStandard(IGUIElement* element, + const core::rect<s32>& r, + const core::rect<s32>* clip, + const video::SColor* colors) +{ + if (!Driver) + return; + + if (!colors) + colors = Colors; + + core::rect<s32> rect = r; + + if ( Type == EGST_BURNING_SKIN ) + { + rect.UpperLeftCorner.X -= 1; + rect.UpperLeftCorner.Y -= 1; + rect.LowerRightCorner.X += 1; + rect.LowerRightCorner.Y += 1; + draw3DSunkenPane(element, + colors[ EGDC_WINDOW ].getInterpolated( 0xFFFFFFFF, 0.9f ) + ,false, true, rect, clip); + return; + } + + Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip); + + rect.LowerRightCorner.X -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); + + rect.LowerRightCorner.X -= 1; + rect.LowerRightCorner.Y -= 1; + + if (!UseGradient) + { + Driver->draw2DRectangle(colors[EGDC_3D_FACE], rect, clip); + } + else + { + const video::SColor c1 = colors[EGDC_3D_FACE]; + const video::SColor c2 = c1.getInterpolated(colors[EGDC_3D_DARK_SHADOW], 0.4f); + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} +// END PATCH + + +//! draws a pressed 3d button pane +/** Used for drawing for example buttons in pressed state. +It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and +EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. +\param rect: Defining area where to draw. +\param clip: Clip area. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. */ +// PATCH +void GUISkin::drawColored3DButtonPanePressed(IGUIElement* element, + const core::rect<s32>& r, + const core::rect<s32>* clip, + const video::SColor* colors) +{ + if (!Driver) + return; + + if (!colors) + colors = Colors; + + core::rect<s32> rect = r; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); + + rect.LowerRightCorner.X -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.UpperLeftCorner.Y += 1; + + if (!UseGradient) + { + Driver->draw2DRectangle(colors[EGDC_3D_FACE], rect, clip); + } + else + { + const video::SColor c1 = colors[EGDC_3D_FACE]; + const video::SColor c2 = c1.getInterpolated(colors[EGDC_3D_DARK_SHADOW], 0.4f); + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} +// END PATCH + + +//! draws a sunken 3d pane +/** Used for drawing the background of edit, combo or check boxes. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param bgcolor: Background color. +\param flat: Specifies if the sunken pane should be flat or displayed as sunken +deep into the ground. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +// PATCH +void GUISkin::drawColored3DSunkenPane(IGUIElement* element, video::SColor bgcolor, + bool flat, bool fillBackGround, + const core::rect<s32>& r, + const core::rect<s32>* clip, + const video::SColor* colors) +{ + if (!Driver) + return; + + if (!colors) + colors = Colors; + + core::rect<s32> rect = r; + + if (fillBackGround) + Driver->draw2DRectangle(bgcolor, rect, clip); + + if (flat) + { + // draw flat sunken pane + + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); // top + + ++rect.UpperLeftCorner.Y; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); // left + + rect = r; + ++rect.UpperLeftCorner.Y; + rect.UpperLeftCorner.X = rect.LowerRightCorner.X - 1; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); // right + + rect = r; + ++rect.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + --rect.LowerRightCorner.X; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); // bottom + } + else + { + // draw deep sunken pane + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); // top + ++rect.UpperLeftCorner.X; + ++rect.UpperLeftCorner.Y; + --rect.LowerRightCorner.X; + ++rect.LowerRightCorner.Y; + Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip); + + rect.UpperLeftCorner.X = r.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y+1; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); // left + ++rect.UpperLeftCorner.X; + ++rect.UpperLeftCorner.Y; + ++rect.LowerRightCorner.X; + --rect.LowerRightCorner.Y; + Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip); + + rect = r; + rect.UpperLeftCorner.X = rect.LowerRightCorner.X - 1; + ++rect.UpperLeftCorner.Y; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); // right + --rect.UpperLeftCorner.X; + ++rect.UpperLeftCorner.Y; + --rect.LowerRightCorner.X; + --rect.LowerRightCorner.Y; + Driver->draw2DRectangle(colors[EGDC_3D_LIGHT], rect, clip); + + rect = r; + ++rect.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + --rect.LowerRightCorner.X; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); // bottom + ++rect.UpperLeftCorner.X; + --rect.UpperLeftCorner.Y; + --rect.LowerRightCorner.X; + --rect.LowerRightCorner.Y; + Driver->draw2DRectangle(colors[EGDC_3D_LIGHT], rect, clip); + } +} +// END PATCH + +//! draws a window background +// return where to draw title bar text. +// PATCH +core::rect<s32> GUISkin::drawColored3DWindowBackground(IGUIElement* element, + bool drawTitleBar, video::SColor titleBarColor, + const core::rect<s32>& r, + const core::rect<s32>* clip, + core::rect<s32>* checkClientArea, + const video::SColor* colors) +{ + if (!Driver) + { + if ( checkClientArea ) + { + *checkClientArea = r; + } + return r; + } + + if (!colors) + colors = Colors; + + core::rect<s32> rect = r; + + // top border + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); + } + + // left border + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); + } + + // right border dark outer line + rect.UpperLeftCorner.X = r.LowerRightCorner.X - 1; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip); + } + + // right border bright innner line + rect.UpperLeftCorner.X -= 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y += 1; + rect.LowerRightCorner.Y -= 1; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); + } + + // bottom border dark outer line + rect.UpperLeftCorner.X = r.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip); + } + + // bottom border bright inner line + rect.UpperLeftCorner.X += 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y -= 1; + rect.LowerRightCorner.Y -= 1; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); + } + + // client area for background + rect = r; + rect.UpperLeftCorner.X +=1; + rect.UpperLeftCorner.Y +=1; + rect.LowerRightCorner.X -= 2; + rect.LowerRightCorner.Y -= 2; + if (checkClientArea) + { + *checkClientArea = rect; + } + + if ( !checkClientArea ) + { + if (!UseGradient) + { + Driver->draw2DRectangle(colors[EGDC_3D_FACE], rect, clip); + } + else if ( Type == EGST_BURNING_SKIN ) + { + const video::SColor c1 = colors[EGDC_WINDOW].getInterpolated ( 0xFFFFFFFF, 0.9f ); + const video::SColor c2 = colors[EGDC_WINDOW].getInterpolated ( 0xFFFFFFFF, 0.8f ); + + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } + else + { + const video::SColor c2 = colors[EGDC_3D_SHADOW]; + const video::SColor c1 = colors[EGDC_3D_FACE]; + Driver->draw2DRectangle(rect, c1, c1, c1, c2, clip); + } + } + + // title bar + rect = r; + rect.UpperLeftCorner.X += 2; + rect.UpperLeftCorner.Y += 2; + rect.LowerRightCorner.X -= 2; + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + getSize(EGDS_WINDOW_BUTTON_WIDTH) + 2; + + if (drawTitleBar ) + { + if (checkClientArea) + { + (*checkClientArea).UpperLeftCorner.Y = rect.LowerRightCorner.Y; + } + else + { + // draw title bar + //if (!UseGradient) + // Driver->draw2DRectangle(titleBarColor, rect, clip); + //else + if ( Type == EGST_BURNING_SKIN ) + { + const video::SColor c = titleBarColor.getInterpolated( video::SColor(titleBarColor.getAlpha(),255,255,255), 0.8f); + Driver->draw2DRectangle(rect, titleBarColor, titleBarColor, c, c, clip); + } + else + { + const video::SColor c = titleBarColor.getInterpolated(video::SColor(titleBarColor.getAlpha(),0,0,0), 0.2f); + Driver->draw2DRectangle(rect, titleBarColor, c, titleBarColor, c, clip); + } + } + } + + return rect; +} +// END PATCH + + +//! draws a standard 3d menu pane +/** Used for drawing for menus and context menus. +It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and +EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +// PATCH +void GUISkin::drawColored3DMenuPane(IGUIElement* element, + const core::rect<s32>& r, const core::rect<s32>* clip, + const video::SColor* colors) +{ + if (!Driver) + return; + + if (!colors) + colors = Colors; + + core::rect<s32> rect = r; + + if ( Type == EGST_BURNING_SKIN ) + { + rect.UpperLeftCorner.Y -= 3; + draw3DButtonPaneStandard(element, rect, clip); + return; + } + + // in this skin, this is exactly what non pressed buttons look like, + // so we could simply call + // draw3DButtonPaneStandard(element, rect, clip); + // here. + // but if the skin is transparent, this doesn't look that nice. So + // We draw it a little bit better, with some more draw2DRectangle calls, + // but there aren't that much menus visible anyway. + + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); + + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); + + rect.UpperLeftCorner.X = r.LowerRightCorner.X - 1; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip); + + rect.UpperLeftCorner.X -= 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y += 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); + + rect.UpperLeftCorner.X = r.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); + + rect = r; + rect.UpperLeftCorner.X +=1; + rect.UpperLeftCorner.Y +=1; + rect.LowerRightCorner.X -= 2; + rect.LowerRightCorner.Y -= 2; + + if (!UseGradient) + Driver->draw2DRectangle(colors[EGDC_3D_FACE], rect, clip); + else + { + const video::SColor c1 = colors[EGDC_3D_FACE]; + const video::SColor c2 = colors[EGDC_3D_SHADOW]; + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} +// END PATCH + + +//! draws a standard 3d tool bar +/** Used for drawing for toolbars and menus. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +// PATCH +void GUISkin::drawColored3DToolBar(IGUIElement* element, + const core::rect<s32>& r, + const core::rect<s32>* clip, + const video::SColor* colors) +{ + if (!Driver) + return; + + if (!colors) + colors = Colors; + + core::rect<s32> rect = r; + + rect.UpperLeftCorner.X = r.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); + + rect = r; + rect.LowerRightCorner.Y -= 1; + + if (!UseGradient) + { + Driver->draw2DRectangle(colors[EGDC_3D_FACE], rect, clip); + } + else + if ( Type == EGST_BURNING_SKIN ) + { + const video::SColor c1 = 0xF0000000 | colors[EGDC_3D_FACE].color; + const video::SColor c2 = 0xF0000000 | colors[EGDC_3D_SHADOW].color; + + rect.LowerRightCorner.Y += 1; + Driver->draw2DRectangle(rect, c1, c2, c1, c2, clip); + } + else + { + const video::SColor c1 = colors[EGDC_3D_FACE]; + const video::SColor c2 = colors[EGDC_3D_SHADOW]; + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} +// END PATCH + +//! draws a tab button +/** Used for drawing for tab buttons on top of tabs. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param active: Specifies if the tab is currently active. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +// PATCH +void GUISkin::drawColored3DTabButton(IGUIElement* element, bool active, + const core::rect<s32>& frameRect, const core::rect<s32>* clip, EGUI_ALIGNMENT alignment, + const video::SColor* colors) +{ + if (!Driver) + return; + + if (!colors) + colors = Colors; + + core::rect<s32> tr = frameRect; + + if ( alignment == EGUIA_UPPERLEFT ) + { + tr.LowerRightCorner.X -= 2; + tr.LowerRightCorner.Y = tr.UpperLeftCorner.Y + 1; + tr.UpperLeftCorner.X += 1; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip); + + // draw left highlight + tr = frameRect; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + tr.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip); + + // draw grey background + tr = frameRect; + tr.UpperLeftCorner.X += 1; + tr.UpperLeftCorner.Y += 1; + tr.LowerRightCorner.X -= 2; + Driver->draw2DRectangle(colors[EGDC_3D_FACE], tr, clip); + + // draw right middle gray shadow + tr.LowerRightCorner.X += 1; + tr.UpperLeftCorner.X = tr.LowerRightCorner.X - 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], tr, clip); + + tr.LowerRightCorner.X += 1; + tr.UpperLeftCorner.X += 1; + tr.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], tr, clip); + } + else + { + tr.LowerRightCorner.X -= 2; + tr.UpperLeftCorner.Y = tr.LowerRightCorner.Y - 1; + tr.UpperLeftCorner.X += 1; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip); + + // draw left highlight + tr = frameRect; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + tr.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip); + + // draw grey background + tr = frameRect; + tr.UpperLeftCorner.X += 1; + tr.UpperLeftCorner.Y -= 1; + tr.LowerRightCorner.X -= 2; + tr.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(colors[EGDC_3D_FACE], tr, clip); + + // draw right middle gray shadow + tr.LowerRightCorner.X += 1; + tr.UpperLeftCorner.X = tr.LowerRightCorner.X - 1; + //tr.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], tr, clip); + + tr.LowerRightCorner.X += 1; + tr.UpperLeftCorner.X += 1; + tr.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], tr, clip); + } +} +// END PATCH + + +//! draws a tab control body +/** \param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param border: Specifies if the border should be drawn. +\param background: Specifies if the background should be drawn. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +// PATCH +void GUISkin::drawColored3DTabBody(IGUIElement* element, bool border, bool background, + const core::rect<s32>& rect, const core::rect<s32>* clip, s32 tabHeight, EGUI_ALIGNMENT alignment, + const video::SColor* colors) +{ + if (!Driver) + return; + + if (!colors) + colors = Colors; + + core::rect<s32> tr = rect; + + if ( tabHeight == -1 ) + tabHeight = getSize(gui::EGDS_BUTTON_HEIGHT); + + // draw border. + if (border) + { + if ( alignment == EGUIA_UPPERLEFT ) + { + // draw left hightlight + tr.UpperLeftCorner.Y += tabHeight + 2; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip); + + // draw right shadow + tr.UpperLeftCorner.X = rect.LowerRightCorner.X - 1; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], tr, clip); + + // draw lower shadow + tr = rect; + tr.UpperLeftCorner.Y = tr.LowerRightCorner.Y - 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], tr, clip); + } + else + { + // draw left hightlight + tr.LowerRightCorner.Y -= tabHeight + 2; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip); + + // draw right shadow + tr.UpperLeftCorner.X = rect.LowerRightCorner.X - 1; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], tr, clip); + + // draw lower shadow + tr = rect; + tr.LowerRightCorner.Y = tr.UpperLeftCorner.Y + 1; + Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip); + } + } + + if (background) + { + if ( alignment == EGUIA_UPPERLEFT ) + { + tr = rect; + tr.UpperLeftCorner.Y += tabHeight + 2; + tr.LowerRightCorner.X -= 1; + tr.UpperLeftCorner.X += 1; + tr.LowerRightCorner.Y -= 1; + } + else + { + tr = rect; + tr.UpperLeftCorner.X += 1; + tr.UpperLeftCorner.Y -= 1; + tr.LowerRightCorner.X -= 1; + tr.LowerRightCorner.Y -= tabHeight + 2; + //tr.UpperLeftCorner.X += 1; + } + + if (!UseGradient) + Driver->draw2DRectangle(colors[EGDC_3D_FACE], tr, clip); + else + { + video::SColor c1 = colors[EGDC_3D_FACE]; + video::SColor c2 = colors[EGDC_3D_SHADOW]; + Driver->draw2DRectangle(tr, c1, c1, c2, c2, clip); + } + } +} +// END PATCH + + +//! draws an icon, usually from the skin's sprite bank +/** \param parent: Pointer to the element which wishes to draw this icon. +This parameter is usually not used by IGUISkin, but can be used for example +by more complex implementations to find out how to draw the part exactly. +\param icon: Specifies the icon to be drawn. +\param position: The position to draw the icon +\param starttime: The time at the start of the animation +\param currenttime: The present time, used to calculate the frame number +\param loop: Whether the animation should loop or not +\param clip: Clip area. */ +// PATCH +void GUISkin::drawColoredIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon, + const core::position2di position, + u32 starttime, u32 currenttime, + bool loop, const core::rect<s32>* clip, + const video::SColor* colors) +{ + if (!SpriteBank) + return; + + if (!colors) + colors = Colors; + + bool gray = element && !element->isEnabled(); + SpriteBank->draw2DSprite(Icons[icon], position, clip, + colors[gray? EGDC_GRAY_WINDOW_SYMBOL : EGDC_WINDOW_SYMBOL], starttime, currenttime, loop, true); +} +// END PATCH + + +EGUI_SKIN_TYPE GUISkin::getType() const +{ + return Type; +} + + +//! draws a 2d rectangle. +void GUISkin::draw2DRectangle(IGUIElement* element, + const video::SColor &color, const core::rect<s32>& pos, + const core::rect<s32>* clip) +{ + Driver->draw2DRectangle(color, pos, clip); +} + + +//! gets the colors +// PATCH +void GUISkin::getColors(video::SColor* colors) +{ + u32 i; + for (i=0; i<EGDC_COUNT; ++i) + colors[i] = Colors[i]; +} +// END PATCH + +} // end namespace gui +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/gui/guiSkin.h b/src/gui/guiSkin.h new file mode 100644 index 0000000..b75eb30 --- /dev/null +++ b/src/gui/guiSkin.h @@ -0,0 +1,366 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __GUI_SKIN_H_INCLUDED__ +#define __GUI_SKIN_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "irrString.h" +#include <string> +#include "ITexture.h" + +namespace irr +{ +namespace video +{ + class IVideoDriver; +} +namespace gui +{ + class GUISkin : public IGUISkin + { + public: + + GUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver); + + //! destructor + virtual ~GUISkin(); + + //! returns default color + virtual video::SColor getColor(EGUI_DEFAULT_COLOR color) const; + + //! sets a default color + virtual void setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor); + + //! returns size for the given size type + virtual s32 getSize(EGUI_DEFAULT_SIZE size) const; + + //! sets a default size + virtual void setSize(EGUI_DEFAULT_SIZE which, s32 size); + + //! returns the default font + virtual IGUIFont* getFont(EGUI_DEFAULT_FONT which=EGDF_DEFAULT) const; + + //! sets a default font + virtual void setFont(IGUIFont* font, EGUI_DEFAULT_FONT which=EGDF_DEFAULT); + + //! sets the sprite bank used for drawing icons + virtual void setSpriteBank(IGUISpriteBank* bank); + + //! gets the sprite bank used for drawing icons + virtual IGUISpriteBank* getSpriteBank() const; + + //! Returns a default icon + /** Returns the sprite index within the sprite bank */ + virtual u32 getIcon(EGUI_DEFAULT_ICON icon) const; + + //! Sets a default icon + /** Sets the sprite index used for drawing icons like arrows, + close buttons and ticks in checkboxes + \param icon: Enum specifying which icon to change + \param index: The sprite index used to draw this icon */ + virtual void setIcon(EGUI_DEFAULT_ICON icon, u32 index); + + //! Returns a default text. + /** For example for Message box button captions: + "OK", "Cancel", "Yes", "No" and so on. */ + virtual const wchar_t* getDefaultText(EGUI_DEFAULT_TEXT text) const; + + //! Sets a default text. + /** For example for Message box button captions: + "OK", "Cancel", "Yes", "No" and so on. */ + virtual void setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText); + + //! draws a standard 3d button pane + /** Used for drawing for example buttons in normal state. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param rect: Defining area where to draw. + \param clip: Clip area. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. */ + virtual void draw3DButtonPaneStandard(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0) + { + drawColored3DButtonPaneStandard(element, rect,clip); + } + + virtual void drawColored3DButtonPaneStandard(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0, + const video::SColor* colors=0); + + //! draws a pressed 3d button pane + /** Used for drawing for example buttons in pressed state. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param rect: Defining area where to draw. + \param clip: Clip area. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. */ + virtual void draw3DButtonPanePressed(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0) + { + drawColored3DButtonPanePressed(element, rect, clip); + } + + virtual void drawColored3DButtonPanePressed(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0, + const video::SColor* colors=0); + + //! draws a sunken 3d pane + /** Used for drawing the background of edit, combo or check boxes. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param bgcolor: Background color. + \param flat: Specifies if the sunken pane should be flat or displayed as sunken + deep into the ground. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DSunkenPane(IGUIElement* element, + video::SColor bgcolor, bool flat, + bool fillBackGround, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0) + { + drawColored3DSunkenPane(element, bgcolor, flat, fillBackGround, rect, clip); + } + + virtual void drawColored3DSunkenPane(IGUIElement* element, + video::SColor bgcolor, bool flat, + bool fillBackGround, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0, + const video::SColor* colors=0); + + //! draws a window background + /** Used for drawing the background of dialogs and windows. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param titleBarColor: Title color. + \param drawTitleBar: True to enable title drawing. + \param rect: Defining area where to draw. + \param clip: Clip area. + \param checkClientArea: When set to non-null the function will not draw anything, + but will instead return the clientArea which can be used for drawing by the calling window. + That is the area without borders and without titlebar. + \return Returns rect where it would be good to draw title bar text. This will + work even when checkClientArea is set to a non-null value.*/ + virtual core::rect<s32> draw3DWindowBackground(IGUIElement* element, + bool drawTitleBar, video::SColor titleBarColor, + const core::rect<s32>& rect, + const core::rect<s32>* clip, + core::rect<s32>* checkClientArea) + { + return drawColored3DWindowBackground(element, drawTitleBar, titleBarColor, + rect, clip, checkClientArea); + } + + virtual core::rect<s32> drawColored3DWindowBackground(IGUIElement* element, + bool drawTitleBar, video::SColor titleBarColor, + const core::rect<s32>& rect, + const core::rect<s32>* clip, + core::rect<s32>* checkClientArea, + const video::SColor* colors=0); + + //! draws a standard 3d menu pane + /** Used for drawing for menus and context menus. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DMenuPane(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0) + { + drawColored3DMenuPane(element, rect, clip); + } + + virtual void drawColored3DMenuPane(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0, + const video::SColor* colors=0); + + //! draws a standard 3d tool bar + /** Used for drawing for toolbars and menus. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DToolBar(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0) + { + drawColored3DToolBar(element, rect, clip); + } + + virtual void drawColored3DToolBar(IGUIElement* element, + const core::rect<s32>& rect, + const core::rect<s32>* clip=0, + const video::SColor* colors=0); + + //! draws a tab button + /** Used for drawing for tab buttons on top of tabs. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param active: Specifies if the tab is currently active. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DTabButton(IGUIElement* element, bool active, + const core::rect<s32>& rect, const core::rect<s32>* clip=0, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT) + { + drawColored3DTabButton(element, active, rect, clip, alignment); + } + + virtual void drawColored3DTabButton(IGUIElement* element, bool active, + const core::rect<s32>& rect, const core::rect<s32>* clip=0, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT, + const video::SColor* colors=0); + + //! draws a tab control body + /** \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param border: Specifies if the border should be drawn. + \param background: Specifies if the background should be drawn. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DTabBody(IGUIElement* element, bool border, bool background, + const core::rect<s32>& rect, const core::rect<s32>* clip=0, s32 tabHeight=-1, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT) + { + drawColored3DTabBody(element, border, background, rect, clip, tabHeight, alignment); + } + + virtual void drawColored3DTabBody(IGUIElement* element, bool border, bool background, + const core::rect<s32>& rect, const core::rect<s32>* clip=0, s32 tabHeight=-1, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT, + const video::SColor* colors=0); + + //! draws an icon, usually from the skin's sprite bank + /** \param element: Pointer to the element which wishes to draw this icon. + This parameter is usually not used by IGUISkin, but can be used for example + by more complex implementations to find out how to draw the part exactly. + \param icon: Specifies the icon to be drawn. + \param position: The position to draw the icon + \param starttime: The time at the start of the animation + \param currenttime: The present time, used to calculate the frame number + \param loop: Whether the animation should loop or not + \param clip: Clip area. */ + virtual void drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon, + const core::position2di position, + u32 starttime=0, u32 currenttime=0, + bool loop=false, const core::rect<s32>* clip=0) + { + drawColoredIcon(element, icon, position, starttime, currenttime, loop, clip); + } + + virtual void drawColoredIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon, + const core::position2di position, + u32 starttime=0, u32 currenttime=0, + bool loop=false, const core::rect<s32>* clip=0, + const video::SColor* colors=0); + + //! draws a 2d rectangle. + /** \param element: Pointer to the element which wishes to draw this icon. + This parameter is usually not used by IGUISkin, but can be used for example + by more complex implementations to find out how to draw the part exactly. + \param color: Color of the rectangle to draw. The alpha component specifies how + transparent the rectangle will be. + \param pos: Position of the rectangle. + \param clip: Pointer to rectangle against which the rectangle will be clipped. + If the pointer is null, no clipping will be performed. */ + virtual void draw2DRectangle(IGUIElement* element, const video::SColor &color, + const core::rect<s32>& pos, const core::rect<s32>* clip = 0); + + + //! get the type of this skin + virtual EGUI_SKIN_TYPE getType() const; + + //! gets the colors + virtual void getColors(video::SColor* colors); // ::PATCH: + + private: + + video::SColor Colors[EGDC_COUNT]; + s32 Sizes[EGDS_COUNT]; + u32 Icons[EGDI_COUNT]; + IGUIFont* Fonts[EGDF_COUNT]; + IGUISpriteBank* SpriteBank; + core::stringw Texts[EGDT_COUNT]; + video::IVideoDriver* Driver; + bool UseGradient; + + EGUI_SKIN_TYPE Type; + }; + + #define set3DSkinColors(skin, button_color) \ + { \ + skin->setColor(EGDC_3D_FACE, button_color); \ + skin->setColor(EGDC_3D_DARK_SHADOW, button_color, 0.25f); \ + skin->setColor(EGDC_3D_SHADOW, button_color, 0.5f); \ + skin->setColor(EGDC_3D_LIGHT, button_color); \ + skin->setColor(EGDC_3D_HIGH_LIGHT, button_color, 1.5f); \ + } + + #define getElementSkinColor(color) \ + { \ + if (!Colors) \ + { \ + IGUISkin* skin = Environment->getSkin(); \ + if (skin) \ + return skin->getColor(color); \ + } \ + return Colors[color]; \ + } + + #define setElementSkinColor(which, newColor, shading) \ + { \ + if (!Colors) \ + { \ + Colors = new video::SColor[EGDC_COUNT]; \ + GUISkin* skin = (GUISkin *)Environment->getSkin(); \ + if (skin) \ + skin->getColors(Colors); \ + } \ + Colors[which] = newColor; \ + setShading(Colors[which],shading); \ + } +} // end namespace gui +//! Sets the shading +inline void setShading(video::SColor &color,f32 s) // :PATCH: +{ + if (s < 1.0f) + { + color.setRed(color.getRed() * s); + color.setGreen(color.getGreen() * s); + color.setBlue(color.getBlue() * s); + } + else if (s > 1.0f) + { + s -= 1.0f; + + color.setRed(color.getRed() + (255 - color.getRed()) * s); + color.setGreen(color.getGreen() + (255 - color.getGreen()) * s); + color.setBlue(color.getBlue() + (255 - color.getBlue()) * s); + } +} +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif diff --git a/src/gui/guiTable.cpp b/src/gui/guiTable.cpp new file mode 100644 index 0000000..3929d67 --- /dev/null +++ b/src/gui/guiTable.cpp @@ -0,0 +1,1289 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "guiTable.h" +#include <queue> +#include <sstream> +#include <utility> +#include <cstring> +#include <IGUISkin.h> +#include <IGUIFont.h> +#include "client/renderingengine.h" +#include "debug.h" +#include "log.h" +#include "client/tile.h" +#include "gettime.h" +#include "util/string.h" +#include "util/numeric.h" +#include "util/string.h" // for parseColorString() +#include "settings.h" // for settings +#include "porting.h" // for dpi +#include "client/guiscalingfilter.h" + +/* + GUITable +*/ + +GUITable::GUITable(gui::IGUIEnvironment *env, + gui::IGUIElement* parent, s32 id, + core::rect<s32> rectangle, + ISimpleTextureSource *tsrc +): + gui::IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rectangle), + m_tsrc(tsrc) +{ + assert(tsrc != NULL); + + gui::IGUISkin* skin = Environment->getSkin(); + + m_font = skin->getFont(); + if (m_font) { + m_font->grab(); + m_rowheight = m_font->getDimension(L"Ay").Height + 4; + m_rowheight = MYMAX(m_rowheight, 1); + } + + const s32 s = skin->getSize(gui::EGDS_SCROLLBAR_SIZE); + m_scrollbar = new GUIScrollBar(Environment, this, -1, + core::rect<s32>(RelativeRect.getWidth() - s, + 0, + RelativeRect.getWidth(), + RelativeRect.getHeight()), + false, true); + m_scrollbar->setSubElement(true); + m_scrollbar->setTabStop(false); + m_scrollbar->setAlignment(gui::EGUIA_LOWERRIGHT, gui::EGUIA_LOWERRIGHT, + gui::EGUIA_UPPERLEFT, gui::EGUIA_LOWERRIGHT); + m_scrollbar->setVisible(false); + m_scrollbar->setPos(0); + + setTabStop(true); + setTabOrder(-1); + updateAbsolutePosition(); +#ifdef HAVE_TOUCHSCREENGUI + float density = 1; // dp scaling is applied by the skin +#else + float density = RenderingEngine::getDisplayDensity(); +#endif + core::rect<s32> relative_rect = m_scrollbar->getRelativePosition(); + s32 width = (relative_rect.getWidth() / (2.0 / 3.0)) * density * + g_settings->getFloat("gui_scaling", 0.5f, 20.0f); + m_scrollbar->setRelativePosition(core::rect<s32>( + relative_rect.LowerRightCorner.X-width,relative_rect.UpperLeftCorner.Y, + relative_rect.LowerRightCorner.X,relative_rect.LowerRightCorner.Y + )); +} + +GUITable::~GUITable() +{ + for (GUITable::Row &row : m_rows) + delete[] row.cells; + + if (m_font) + m_font->drop(); + + if (m_scrollbar) + m_scrollbar->drop(); +} + +GUITable::Option GUITable::splitOption(const std::string &str) +{ + size_t equal_pos = str.find('='); + if (equal_pos == std::string::npos) + return GUITable::Option(str, ""); + + return GUITable::Option(str.substr(0, equal_pos), + str.substr(equal_pos + 1)); +} + +void GUITable::setTextList(const std::vector<std::string> &content, + bool transparent) +{ + clear(); + + if (transparent) { + m_background.setAlpha(0); + m_border = false; + } + + m_is_textlist = true; + + s32 empty_string_index = allocString(""); + + m_rows.resize(content.size()); + for (s32 i = 0; i < (s32) content.size(); ++i) { + Row *row = &m_rows[i]; + row->cells = new Cell[1]; + row->cellcount = 1; + row->indent = 0; + row->visible_index = i; + m_visible_rows.push_back(i); + + Cell *cell = row->cells; + cell->xmin = 0; + cell->xmax = 0x7fff; // something large enough + cell->xpos = 6; + cell->content_type = COLUMN_TYPE_TEXT; + cell->content_index = empty_string_index; + cell->tooltip_index = empty_string_index; + cell->color.set(255, 255, 255, 255); + cell->color_defined = false; + cell->reported_column = 1; + + // parse row content (color) + const std::string &s = content[i]; + if (s[0] == '#' && s[1] == '#') { + // double # to escape + cell->content_index = allocString(s.substr(2)); + } + else if (s[0] == '#' && s.size() >= 7 && + parseColorString( + s.substr(0,7), cell->color, false)) { + // single # for color + cell->color_defined = true; + cell->content_index = allocString(s.substr(7)); + } + else { + // no #, just text + cell->content_index = allocString(s); + } + + } + + allocationComplete(); + + // Clamp scroll bar position + updateScrollBar(); +} + +void GUITable::setTable(const TableOptions &options, + const TableColumns &columns, + std::vector<std::string> &content) +{ + clear(); + + // Naming conventions: + // i is always a row index, 0-based + // j is always a column index, 0-based + // k is another index, for example an option index + + // Handle a stupid error case... (issue #1187) + if (columns.empty()) { + TableColumn text_column; + text_column.type = "text"; + TableColumns new_columns; + new_columns.push_back(text_column); + setTable(options, new_columns, content); + return; + } + + // Handle table options + video::SColor default_color(255, 255, 255, 255); + s32 opendepth = 0; + for (const Option &option : options) { + const std::string &name = option.name; + const std::string &value = option.value; + if (name == "color") + parseColorString(value, m_color, false); + else if (name == "background") + parseColorString(value, m_background, false); + else if (name == "border") + m_border = is_yes(value); + else if (name == "highlight") + parseColorString(value, m_highlight, false); + else if (name == "highlight_text") + parseColorString(value, m_highlight_text, false); + else if (name == "opendepth") + opendepth = stoi(value); + else + errorstream<<"Invalid table option: \""<<name<<"\"" + <<" (value=\""<<value<<"\")"<<std::endl; + } + + // Get number of columns and rows + // note: error case columns.size() == 0 was handled above + s32 colcount = columns.size(); + assert(colcount >= 1); + // rowcount = ceil(cellcount / colcount) but use integer arithmetic + s32 rowcount = (content.size() + colcount - 1) / colcount; + assert(rowcount >= 0); + // Append empty strings to content if there is an incomplete row + s32 cellcount = rowcount * colcount; + while (content.size() < (u32) cellcount) + content.emplace_back(""); + + // Create temporary rows (for processing columns) + struct TempRow { + // Current horizontal position (may different between rows due + // to indent/tree columns, or text/image columns with width<0) + s32 x; + // Tree indentation level + s32 indent; + // Next cell: Index into m_strings or m_images + s32 content_index; + // Next cell: Width in pixels + s32 content_width; + // Vector of completed cells in this row + std::vector<Cell> cells; + // Stores colors and how long they last (maximum column index) + std::vector<std::pair<video::SColor, s32> > colors; + + TempRow(): x(0), indent(0), content_index(0), content_width(0) {} + }; + TempRow *rows = new TempRow[rowcount]; + + // Get em width. Pedantically speaking, the width of "M" is not + // necessarily the same as the em width, but whatever, close enough. + s32 em = 6; + if (m_font) + em = m_font->getDimension(L"M").Width; + + s32 default_tooltip_index = allocString(""); + + std::map<s32, s32> active_image_indices; + + // Process content in column-major order + for (s32 j = 0; j < colcount; ++j) { + // Check column type + ColumnType columntype = COLUMN_TYPE_TEXT; + if (columns[j].type == "text") + columntype = COLUMN_TYPE_TEXT; + else if (columns[j].type == "image") + columntype = COLUMN_TYPE_IMAGE; + else if (columns[j].type == "color") + columntype = COLUMN_TYPE_COLOR; + else if (columns[j].type == "indent") + columntype = COLUMN_TYPE_INDENT; + else if (columns[j].type == "tree") + columntype = COLUMN_TYPE_TREE; + else + errorstream<<"Invalid table column type: \"" + <<columns[j].type<<"\""<<std::endl; + + // Process column options + s32 padding = myround(0.5 * em); + s32 tooltip_index = default_tooltip_index; + s32 align = 0; + s32 width = 0; + s32 span = colcount; + + if (columntype == COLUMN_TYPE_INDENT) { + padding = 0; // default indent padding + } + if (columntype == COLUMN_TYPE_INDENT || + columntype == COLUMN_TYPE_TREE) { + width = myround(em * 1.5); // default indent width + } + + for (const Option &option : columns[j].options) { + const std::string &name = option.name; + const std::string &value = option.value; + if (name == "padding") + padding = myround(stof(value) * em); + else if (name == "tooltip") + tooltip_index = allocString(value); + else if (name == "align" && value == "left") + align = 0; + else if (name == "align" && value == "center") + align = 1; + else if (name == "align" && value == "right") + align = 2; + else if (name == "align" && value == "inline") + align = 3; + else if (name == "width") + width = myround(stof(value) * em); + else if (name == "span" && columntype == COLUMN_TYPE_COLOR) + span = stoi(value); + else if (columntype == COLUMN_TYPE_IMAGE && + !name.empty() && + string_allowed(name, "0123456789")) { + s32 content_index = allocImage(value); + active_image_indices.insert(std::make_pair( + stoi(name), + content_index)); + } + else { + errorstream<<"Invalid table column option: \""<<name<<"\"" + <<" (value=\""<<value<<"\")"<<std::endl; + } + } + + // If current column type can use information from "color" columns, + // find out which of those is currently active + if (columntype == COLUMN_TYPE_TEXT) { + for (s32 i = 0; i < rowcount; ++i) { + TempRow *row = &rows[i]; + while (!row->colors.empty() && row->colors.back().second < j) + row->colors.pop_back(); + } + } + + // Make template for new cells + Cell newcell; + newcell.content_type = columntype; + newcell.tooltip_index = tooltip_index; + newcell.reported_column = j+1; + + if (columntype == COLUMN_TYPE_TEXT) { + // Find right edge of column + s32 xmax = 0; + for (s32 i = 0; i < rowcount; ++i) { + TempRow *row = &rows[i]; + row->content_index = allocString(content[i * colcount + j]); + const core::stringw &text = m_strings[row->content_index]; + row->content_width = m_font ? + m_font->getDimension(text.c_str()).Width : 0; + row->content_width = MYMAX(row->content_width, width); + s32 row_xmax = row->x + padding + row->content_width; + xmax = MYMAX(xmax, row_xmax); + } + // Add a new cell (of text type) to each row + for (s32 i = 0; i < rowcount; ++i) { + newcell.xmin = rows[i].x + padding; + alignContent(&newcell, xmax, rows[i].content_width, align); + newcell.content_index = rows[i].content_index; + newcell.color_defined = !rows[i].colors.empty(); + if (newcell.color_defined) + newcell.color = rows[i].colors.back().first; + rows[i].cells.push_back(newcell); + rows[i].x = newcell.xmax; + } + } + else if (columntype == COLUMN_TYPE_IMAGE) { + // Find right edge of column + s32 xmax = 0; + for (s32 i = 0; i < rowcount; ++i) { + TempRow *row = &rows[i]; + row->content_index = -1; + + // Find content_index. Image indices are defined in + // column options so check active_image_indices. + s32 image_index = stoi(content[i * colcount + j]); + std::map<s32, s32>::iterator image_iter = + active_image_indices.find(image_index); + if (image_iter != active_image_indices.end()) + row->content_index = image_iter->second; + + // Get texture object (might be NULL) + video::ITexture *image = NULL; + if (row->content_index >= 0) + image = m_images[row->content_index]; + + // Get content width and update xmax + row->content_width = image ? image->getOriginalSize().Width : 0; + row->content_width = MYMAX(row->content_width, width); + s32 row_xmax = row->x + padding + row->content_width; + xmax = MYMAX(xmax, row_xmax); + } + // Add a new cell (of image type) to each row + for (s32 i = 0; i < rowcount; ++i) { + newcell.xmin = rows[i].x + padding; + alignContent(&newcell, xmax, rows[i].content_width, align); + newcell.content_index = rows[i].content_index; + rows[i].cells.push_back(newcell); + rows[i].x = newcell.xmax; + } + active_image_indices.clear(); + } + else if (columntype == COLUMN_TYPE_COLOR) { + for (s32 i = 0; i < rowcount; ++i) { + video::SColor cellcolor(255, 255, 255, 255); + if (parseColorString(content[i * colcount + j], cellcolor, true)) + rows[i].colors.emplace_back(cellcolor, j+span); + } + } + else if (columntype == COLUMN_TYPE_INDENT || + columntype == COLUMN_TYPE_TREE) { + // For column type "tree", reserve additional space for +/- + // Also enable special processing for treeview-type tables + s32 content_width = 0; + if (columntype == COLUMN_TYPE_TREE) { + content_width = m_font ? m_font->getDimension(L"+").Width : 0; + m_has_tree_column = true; + } + // Add a new cell (of indent or tree type) to each row + for (s32 i = 0; i < rowcount; ++i) { + TempRow *row = &rows[i]; + + s32 indentlevel = stoi(content[i * colcount + j]); + indentlevel = MYMAX(indentlevel, 0); + if (columntype == COLUMN_TYPE_TREE) + row->indent = indentlevel; + + newcell.xmin = row->x + padding; + newcell.xpos = newcell.xmin + indentlevel * width; + newcell.xmax = newcell.xpos + content_width; + newcell.content_index = 0; + newcell.color_defined = !rows[i].colors.empty(); + if (newcell.color_defined) + newcell.color = rows[i].colors.back().first; + row->cells.push_back(newcell); + row->x = newcell.xmax; + } + } + } + + // Copy temporary rows to not so temporary rows + if (rowcount >= 1) { + m_rows.resize(rowcount); + for (s32 i = 0; i < rowcount; ++i) { + Row *row = &m_rows[i]; + row->cellcount = rows[i].cells.size(); + row->cells = new Cell[row->cellcount]; + memcpy((void*) row->cells, (void*) &rows[i].cells[0], + row->cellcount * sizeof(Cell)); + row->indent = rows[i].indent; + row->visible_index = i; + m_visible_rows.push_back(i); + } + } + + if (m_has_tree_column) { + // Treeview: convert tree to indent cells on leaf rows + for (s32 i = 0; i < rowcount; ++i) { + if (i == rowcount-1 || m_rows[i].indent >= m_rows[i+1].indent) + for (s32 j = 0; j < m_rows[i].cellcount; ++j) + if (m_rows[i].cells[j].content_type == COLUMN_TYPE_TREE) + m_rows[i].cells[j].content_type = COLUMN_TYPE_INDENT; + } + + // Treeview: close rows according to opendepth option + std::set<s32> opened_trees; + for (s32 i = 0; i < rowcount; ++i) + if (m_rows[i].indent < opendepth) + opened_trees.insert(i); + setOpenedTrees(opened_trees); + } + + // Delete temporary information used only during setTable() + delete[] rows; + allocationComplete(); + + // Clamp scroll bar position + updateScrollBar(); +} + +void GUITable::clear() +{ + // Clean up cells and rows + for (GUITable::Row &row : m_rows) + delete[] row.cells; + m_rows.clear(); + m_visible_rows.clear(); + + // Get colors from skin + gui::IGUISkin *skin = Environment->getSkin(); + m_color = skin->getColor(gui::EGDC_BUTTON_TEXT); + m_background = skin->getColor(gui::EGDC_3D_HIGH_LIGHT); + m_highlight = skin->getColor(gui::EGDC_HIGH_LIGHT); + m_highlight_text = skin->getColor(gui::EGDC_HIGH_LIGHT_TEXT); + + // Reset members + m_is_textlist = false; + m_has_tree_column = false; + m_selected = -1; + m_sel_column = 0; + m_sel_doubleclick = false; + m_keynav_time = 0; + m_keynav_buffer = L""; + m_border = true; + m_strings.clear(); + m_images.clear(); + m_alloc_strings.clear(); + m_alloc_images.clear(); +} + +std::string GUITable::checkEvent() +{ + s32 sel = getSelected(); + assert(sel >= 0); + + if (sel == 0) { + return "INV"; + } + + std::ostringstream os(std::ios::binary); + if (m_sel_doubleclick) { + os<<"DCL:"; + m_sel_doubleclick = false; + } + else { + os<<"CHG:"; + } + os<<sel; + if (!m_is_textlist) { + os<<":"<<m_sel_column; + } + return os.str(); +} + +s32 GUITable::getSelected() const +{ + if (m_selected < 0) + return 0; + + assert(m_selected >= 0 && m_selected < (s32) m_visible_rows.size()); + return m_visible_rows[m_selected] + 1; +} + +void GUITable::setSelected(s32 index) +{ + s32 old_selected = m_selected; + + m_selected = -1; + m_sel_column = 0; + m_sel_doubleclick = false; + + --index; // Switch from 1-based indexing to 0-based indexing + + s32 rowcount = m_rows.size(); + if (rowcount == 0 || index < 0) { + return; + } + + if (index >= rowcount) { + index = rowcount - 1; + } + + // If the selected row is not visible, open its ancestors to make it visible + bool selection_invisible = m_rows[index].visible_index < 0; + if (selection_invisible) { + std::set<s32> opened_trees; + getOpenedTrees(opened_trees); + s32 indent = m_rows[index].indent; + for (s32 j = index - 1; j >= 0; --j) { + if (m_rows[j].indent < indent) { + opened_trees.insert(j); + indent = m_rows[j].indent; + } + } + setOpenedTrees(opened_trees); + } + + if (index >= 0) { + m_selected = m_rows[index].visible_index; + assert(m_selected >= 0 && m_selected < (s32) m_visible_rows.size()); + } + + if (m_selected != old_selected || selection_invisible) { + autoScroll(); + } +} + +void GUITable::setOverrideFont(IGUIFont *font) +{ + if (m_font == font) + return; + + if (font == nullptr) + font = Environment->getSkin()->getFont(); + + if (m_font) + m_font->drop(); + + m_font = font; + m_font->grab(); + + m_rowheight = m_font->getDimension(L"Ay").Height + 4; + m_rowheight = MYMAX(m_rowheight, 1); + + updateScrollBar(); +} + +IGUIFont *GUITable::getOverrideFont() const +{ + return m_font; +} + +GUITable::DynamicData GUITable::getDynamicData() const +{ + DynamicData dyndata; + dyndata.selected = getSelected(); + dyndata.scrollpos = m_scrollbar->getPos(); + dyndata.keynav_time = m_keynav_time; + dyndata.keynav_buffer = m_keynav_buffer; + if (m_has_tree_column) + getOpenedTrees(dyndata.opened_trees); + return dyndata; +} + +void GUITable::setDynamicData(const DynamicData &dyndata) +{ + if (m_has_tree_column) + setOpenedTrees(dyndata.opened_trees); + + m_keynav_time = dyndata.keynav_time; + m_keynav_buffer = dyndata.keynav_buffer; + + setSelected(dyndata.selected); + m_sel_column = 0; + m_sel_doubleclick = false; + + m_scrollbar->setPos(dyndata.scrollpos); +} + +const c8* GUITable::getTypeName() const +{ + return "GUITable"; +} + +void GUITable::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + updateScrollBar(); +} + +void GUITable::draw() +{ + if (!IsVisible) + return; + + gui::IGUISkin *skin = Environment->getSkin(); + + // draw background + + bool draw_background = m_background.getAlpha() > 0; + if (m_border) + skin->draw3DSunkenPane(this, m_background, + true, draw_background, + AbsoluteRect, &AbsoluteClippingRect); + else if (draw_background) + skin->draw2DRectangle(this, m_background, + AbsoluteRect, &AbsoluteClippingRect); + + // get clipping rect + + core::rect<s32> client_clip(AbsoluteRect); + client_clip.UpperLeftCorner.Y += 1; + client_clip.UpperLeftCorner.X += 1; + client_clip.LowerRightCorner.Y -= 1; + client_clip.LowerRightCorner.X -= 1; + if (m_scrollbar->isVisible()) { + client_clip.LowerRightCorner.X = + m_scrollbar->getAbsolutePosition().UpperLeftCorner.X; + } + client_clip.clipAgainst(AbsoluteClippingRect); + + // draw visible rows + + s32 scrollpos = m_scrollbar->getPos(); + s32 row_min = scrollpos / m_rowheight; + s32 row_max = (scrollpos + AbsoluteRect.getHeight() - 1) + / m_rowheight + 1; + row_max = MYMIN(row_max, (s32) m_visible_rows.size()); + + core::rect<s32> row_rect(AbsoluteRect); + if (m_scrollbar->isVisible()) + row_rect.LowerRightCorner.X -= + skin->getSize(gui::EGDS_SCROLLBAR_SIZE); + row_rect.UpperLeftCorner.Y += row_min * m_rowheight - scrollpos; + row_rect.LowerRightCorner.Y = row_rect.UpperLeftCorner.Y + m_rowheight; + + for (s32 i = row_min; i < row_max; ++i) { + Row *row = &m_rows[m_visible_rows[i]]; + bool is_sel = i == m_selected; + video::SColor color = m_color; + + if (is_sel) { + skin->draw2DRectangle(this, m_highlight, row_rect, &client_clip); + color = m_highlight_text; + } + + for (s32 j = 0; j < row->cellcount; ++j) + drawCell(&row->cells[j], color, row_rect, client_clip); + + row_rect.UpperLeftCorner.Y += m_rowheight; + row_rect.LowerRightCorner.Y += m_rowheight; + } + + // Draw children + IGUIElement::draw(); +} + +void GUITable::drawCell(const Cell *cell, video::SColor color, + const core::rect<s32> &row_rect, + const core::rect<s32> &client_clip) +{ + if ((cell->content_type == COLUMN_TYPE_TEXT) + || (cell->content_type == COLUMN_TYPE_TREE)) { + + core::rect<s32> text_rect = row_rect; + text_rect.UpperLeftCorner.X = row_rect.UpperLeftCorner.X + + cell->xpos; + text_rect.LowerRightCorner.X = row_rect.UpperLeftCorner.X + + cell->xmax; + + if (cell->color_defined) + color = cell->color; + + if (m_font) { + if (cell->content_type == COLUMN_TYPE_TEXT) + m_font->draw(m_strings[cell->content_index], + text_rect, color, + false, true, &client_clip); + else // tree + m_font->draw(cell->content_index ? L"+" : L"-", + text_rect, color, + false, true, &client_clip); + } + } + else if (cell->content_type == COLUMN_TYPE_IMAGE) { + + if (cell->content_index < 0) + return; + + video::IVideoDriver *driver = Environment->getVideoDriver(); + video::ITexture *image = m_images[cell->content_index]; + + if (image) { + core::position2d<s32> dest_pos = + row_rect.UpperLeftCorner; + dest_pos.X += cell->xpos; + core::rect<s32> source_rect( + core::position2d<s32>(0, 0), + image->getOriginalSize()); + s32 imgh = source_rect.LowerRightCorner.Y; + s32 rowh = row_rect.getHeight(); + if (imgh < rowh) + dest_pos.Y += (rowh - imgh) / 2; + else + source_rect.LowerRightCorner.Y = rowh; + + video::SColor color(255, 255, 255, 255); + + driver->draw2DImage(image, dest_pos, source_rect, + &client_clip, color, true); + } + } +} + +bool GUITable::OnEvent(const SEvent &event) +{ + if (!isEnabled()) + return IGUIElement::OnEvent(event); + + if (event.EventType == EET_KEY_INPUT_EVENT) { + if (event.KeyInput.PressedDown && ( + event.KeyInput.Key == KEY_DOWN || + event.KeyInput.Key == KEY_UP || + event.KeyInput.Key == KEY_HOME || + event.KeyInput.Key == KEY_END || + event.KeyInput.Key == KEY_NEXT || + event.KeyInput.Key == KEY_PRIOR)) { + s32 offset = 0; + switch (event.KeyInput.Key) { + case KEY_DOWN: + offset = 1; + break; + case KEY_UP: + offset = -1; + break; + case KEY_HOME: + offset = - (s32) m_visible_rows.size(); + break; + case KEY_END: + offset = m_visible_rows.size(); + break; + case KEY_NEXT: + offset = AbsoluteRect.getHeight() / m_rowheight; + break; + case KEY_PRIOR: + offset = - (s32) (AbsoluteRect.getHeight() / m_rowheight); + break; + default: + break; + } + s32 old_selected = m_selected; + s32 rowcount = m_visible_rows.size(); + if (rowcount != 0) { + m_selected = rangelim(m_selected + offset, 0, rowcount-1); + autoScroll(); + } + + if (m_selected != old_selected) + sendTableEvent(0, false); + + return true; + } + + if (event.KeyInput.PressedDown && ( + event.KeyInput.Key == KEY_LEFT || + event.KeyInput.Key == KEY_RIGHT)) { + // Open/close subtree via keyboard + if (m_selected >= 0) { + int dir = event.KeyInput.Key == KEY_LEFT ? -1 : 1; + toggleVisibleTree(m_selected, dir, true); + } + return true; + } + else if (!event.KeyInput.PressedDown && ( + event.KeyInput.Key == KEY_RETURN || + event.KeyInput.Key == KEY_SPACE)) { + sendTableEvent(0, true); + return true; + } + else if (event.KeyInput.Key == KEY_ESCAPE || + event.KeyInput.Key == KEY_SPACE) { + // pass to parent + } + else if (event.KeyInput.PressedDown && event.KeyInput.Char) { + // change selection based on text as it is typed + u64 now = porting::getTimeMs(); + if (now - m_keynav_time >= 500) + m_keynav_buffer = L""; + m_keynav_time = now; + + // add to key buffer if not a key repeat + if (!(m_keynav_buffer.size() == 1 && + m_keynav_buffer[0] == event.KeyInput.Char)) { + m_keynav_buffer.append(event.KeyInput.Char); + } + + // find the selected item, starting at the current selection + // don't change selection if the key buffer matches the current item + s32 old_selected = m_selected; + s32 start = MYMAX(m_selected, 0); + s32 rowcount = m_visible_rows.size(); + for (s32 k = 1; k < rowcount; ++k) { + s32 current = start + k; + if (current >= rowcount) + current -= rowcount; + if (doesRowStartWith(getRow(current), m_keynav_buffer)) { + m_selected = current; + break; + } + } + autoScroll(); + if (m_selected != old_selected) + sendTableEvent(0, false); + + return true; + } + } + if (event.EventType == EET_MOUSE_INPUT_EVENT) { + core::position2d<s32> p(event.MouseInput.X, event.MouseInput.Y); + + if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) { + m_scrollbar->setPos(m_scrollbar->getPos() + + (event.MouseInput.Wheel < 0 ? -3 : 3) * + - (s32) m_rowheight / 2); + return true; + } + + // Find hovered row and cell + bool really_hovering = false; + s32 row_i = getRowAt(p.Y, really_hovering); + const Cell *cell = NULL; + if (really_hovering) { + s32 cell_j = getCellAt(p.X, row_i); + if (cell_j >= 0) + cell = &(getRow(row_i)->cells[cell_j]); + } + + // Update tooltip + setToolTipText(cell ? m_strings[cell->tooltip_index].c_str() : L""); + + // Fix for #1567/#1806: + // IGUIScrollBar passes double click events to its parent, + // which we don't want. Detect this case and discard the event + if (event.MouseInput.Event != EMIE_MOUSE_MOVED && + m_scrollbar->isVisible() && + m_scrollbar->isPointInside(p)) + return true; + + if (event.MouseInput.isLeftPressed() && + (isPointInside(p) || + event.MouseInput.Event == EMIE_MOUSE_MOVED)) { + s32 sel_column = 0; + bool sel_doubleclick = (event.MouseInput.Event + == EMIE_LMOUSE_DOUBLE_CLICK); + bool plusminus_clicked = false; + + // For certain events (left click), report column + // Also open/close subtrees when the +/- is clicked + if (cell && ( + event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN || + event.MouseInput.Event == EMIE_LMOUSE_DOUBLE_CLICK || + event.MouseInput.Event == EMIE_LMOUSE_TRIPLE_CLICK)) { + sel_column = cell->reported_column; + if (cell->content_type == COLUMN_TYPE_TREE) + plusminus_clicked = true; + } + + if (plusminus_clicked) { + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { + toggleVisibleTree(row_i, 0, false); + } + } + else { + // Normal selection + s32 old_selected = m_selected; + m_selected = row_i; + autoScroll(); + + if (m_selected != old_selected || + sel_column >= 1 || + sel_doubleclick) { + sendTableEvent(sel_column, sel_doubleclick); + } + + // Treeview: double click opens/closes trees + if (m_has_tree_column && sel_doubleclick) { + toggleVisibleTree(m_selected, 0, false); + } + } + } + return true; + } + if (event.EventType == EET_GUI_EVENT && + event.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED && + event.GUIEvent.Caller == m_scrollbar) { + // Don't pass events from our scrollbar to the parent + return true; + } + + return IGUIElement::OnEvent(event); +} + +/******************************************************************************/ +/* GUITable helper functions */ +/******************************************************************************/ + +s32 GUITable::allocString(const std::string &text) +{ + std::map<std::string, s32>::iterator it = m_alloc_strings.find(text); + if (it == m_alloc_strings.end()) { + s32 id = m_strings.size(); + std::wstring wtext = utf8_to_wide(text); + m_strings.emplace_back(wtext.c_str()); + m_alloc_strings.insert(std::make_pair(text, id)); + return id; + } + + return it->second; +} + +s32 GUITable::allocImage(const std::string &imagename) +{ + std::map<std::string, s32>::iterator it = m_alloc_images.find(imagename); + if (it == m_alloc_images.end()) { + s32 id = m_images.size(); + m_images.push_back(m_tsrc->getTexture(imagename)); + m_alloc_images.insert(std::make_pair(imagename, id)); + return id; + } + + return it->second; +} + +void GUITable::allocationComplete() +{ + // Called when done with creating rows and cells from table data, + // i.e. when allocString and allocImage won't be called anymore + m_alloc_strings.clear(); + m_alloc_images.clear(); +} + +const GUITable::Row* GUITable::getRow(s32 i) const +{ + if (i >= 0 && i < (s32) m_visible_rows.size()) + return &m_rows[m_visible_rows[i]]; + + return NULL; +} + +bool GUITable::doesRowStartWith(const Row *row, const core::stringw &str) const +{ + if (row == NULL) + return false; + + for (s32 j = 0; j < row->cellcount; ++j) { + Cell *cell = &row->cells[j]; + if (cell->content_type == COLUMN_TYPE_TEXT) { + const core::stringw &cellstr = m_strings[cell->content_index]; + if (cellstr.size() >= str.size() && + str.equals_ignore_case(cellstr.subString(0, str.size()))) + return true; + } + } + return false; +} + +s32 GUITable::getRowAt(s32 y, bool &really_hovering) const +{ + really_hovering = false; + + s32 rowcount = m_visible_rows.size(); + if (rowcount == 0) + return -1; + + // Use arithmetic to find row + s32 rel_y = y - AbsoluteRect.UpperLeftCorner.Y - 1; + s32 i = (rel_y + m_scrollbar->getPos()) / m_rowheight; + + if (i >= 0 && i < rowcount) { + really_hovering = true; + return i; + } + if (i < 0) + return 0; + + return rowcount - 1; +} + +s32 GUITable::getCellAt(s32 x, s32 row_i) const +{ + const Row *row = getRow(row_i); + if (row == NULL) + return -1; + + // Use binary search to find cell in row + s32 rel_x = x - AbsoluteRect.UpperLeftCorner.X - 1; + s32 jmin = 0; + s32 jmax = row->cellcount - 1; + while (jmin < jmax) { + s32 pivot = jmin + (jmax - jmin) / 2; + assert(pivot >= 0 && pivot < row->cellcount); + const Cell *cell = &row->cells[pivot]; + + if (rel_x >= cell->xmin && rel_x <= cell->xmax) + return pivot; + + if (rel_x < cell->xmin) + jmax = pivot - 1; + else + jmin = pivot + 1; + } + + if (jmin >= 0 && jmin < row->cellcount && + rel_x >= row->cells[jmin].xmin && + rel_x <= row->cells[jmin].xmax) + return jmin; + + return -1; +} + +void GUITable::autoScroll() +{ + if (m_selected >= 0) { + s32 pos = m_scrollbar->getPos(); + s32 maxpos = m_selected * m_rowheight; + s32 minpos = maxpos - (AbsoluteRect.getHeight() - m_rowheight); + if (pos > maxpos) + m_scrollbar->setPos(maxpos); + else if (pos < minpos) + m_scrollbar->setPos(minpos); + } +} + +void GUITable::updateScrollBar() +{ + s32 totalheight = m_rowheight * m_visible_rows.size(); + s32 scrollmax = MYMAX(0, totalheight - AbsoluteRect.getHeight()); + m_scrollbar->setVisible(scrollmax > 0); + m_scrollbar->setMax(scrollmax); + m_scrollbar->setSmallStep(m_rowheight); + m_scrollbar->setLargeStep(2 * m_rowheight); + m_scrollbar->setPageSize(totalheight); +} + +void GUITable::sendTableEvent(s32 column, bool doubleclick) +{ + m_sel_column = column; + m_sel_doubleclick = doubleclick; + if (Parent) { + SEvent e; + memset(&e, 0, sizeof e); + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = gui::EGET_TABLE_CHANGED; + Parent->OnEvent(e); + } +} + +void GUITable::getOpenedTrees(std::set<s32> &opened_trees) const +{ + opened_trees.clear(); + s32 rowcount = m_rows.size(); + for (s32 i = 0; i < rowcount - 1; ++i) { + if (m_rows[i].indent < m_rows[i+1].indent && + m_rows[i+1].visible_index != -2) + opened_trees.insert(i); + } +} + +void GUITable::setOpenedTrees(const std::set<s32> &opened_trees) +{ + s32 old_selected = -1; + if (m_selected >= 0) + old_selected = m_visible_rows[m_selected]; + + std::vector<s32> parents; + std::vector<s32> closed_parents; + + m_visible_rows.clear(); + + for (size_t i = 0; i < m_rows.size(); ++i) { + Row *row = &m_rows[i]; + + // Update list of ancestors + while (!parents.empty() && m_rows[parents.back()].indent >= row->indent) + parents.pop_back(); + while (!closed_parents.empty() && + m_rows[closed_parents.back()].indent >= row->indent) + closed_parents.pop_back(); + + assert(closed_parents.size() <= parents.size()); + + if (closed_parents.empty()) { + // Visible row + row->visible_index = m_visible_rows.size(); + m_visible_rows.push_back(i); + } + else if (parents.back() == closed_parents.back()) { + // Invisible row, direct parent is closed + row->visible_index = -2; + } + else { + // Invisible row, direct parent is open, some ancestor is closed + row->visible_index = -1; + } + + // If not a leaf, add to parents list + if (i < m_rows.size()-1 && row->indent < m_rows[i+1].indent) { + parents.push_back(i); + + s32 content_index = 0; // "-", open + if (opened_trees.count(i) == 0) { + closed_parents.push_back(i); + content_index = 1; // "+", closed + } + + // Update all cells of type "tree" + for (s32 j = 0; j < row->cellcount; ++j) + if (row->cells[j].content_type == COLUMN_TYPE_TREE) + row->cells[j].content_index = content_index; + } + } + + updateScrollBar(); + + // m_selected must be updated since it is a visible row index + if (old_selected >= 0) + m_selected = m_rows[old_selected].visible_index; +} + +void GUITable::openTree(s32 to_open) +{ + std::set<s32> opened_trees; + getOpenedTrees(opened_trees); + opened_trees.insert(to_open); + setOpenedTrees(opened_trees); +} + +void GUITable::closeTree(s32 to_close) +{ + std::set<s32> opened_trees; + getOpenedTrees(opened_trees); + opened_trees.erase(to_close); + setOpenedTrees(opened_trees); +} + +// The following function takes a visible row index (hidden rows skipped) +// dir: -1 = left (close), 0 = auto (toggle), 1 = right (open) +void GUITable::toggleVisibleTree(s32 row_i, int dir, bool move_selection) +{ + // Check if the chosen tree is currently open + const Row *row = getRow(row_i); + if (row == NULL) + return; + + bool was_open = false; + for (s32 j = 0; j < row->cellcount; ++j) { + if (row->cells[j].content_type == COLUMN_TYPE_TREE) { + was_open = row->cells[j].content_index == 0; + break; + } + } + + // Check if the chosen tree should be opened + bool do_open = !was_open; + if (dir < 0) + do_open = false; + else if (dir > 0) + do_open = true; + + // Close or open the tree; the heavy lifting is done by setOpenedTrees + if (was_open && !do_open) + closeTree(m_visible_rows[row_i]); + else if (!was_open && do_open) + openTree(m_visible_rows[row_i]); + + // Change selected row if requested by caller, + // this is useful for keyboard navigation + if (move_selection) { + s32 sel = row_i; + if (was_open && do_open) { + // Move selection to first child + const Row *maybe_child = getRow(sel + 1); + if (maybe_child && maybe_child->indent > row->indent) + sel++; + } + else if (!was_open && !do_open) { + // Move selection to parent + assert(getRow(sel) != NULL); + while (sel > 0 && getRow(sel - 1)->indent >= row->indent) + sel--; + sel--; + if (sel < 0) // was root already selected? + sel = row_i; + } + if (sel != m_selected) { + m_selected = sel; + autoScroll(); + sendTableEvent(0, false); + } + } +} + +void GUITable::alignContent(Cell *cell, s32 xmax, s32 content_width, s32 align) +{ + // requires that cell.xmin, cell.xmax are properly set + // align = 0: left aligned, 1: centered, 2: right aligned, 3: inline + if (align == 0) { + cell->xpos = cell->xmin; + cell->xmax = xmax; + } + else if (align == 1) { + cell->xpos = (cell->xmin + xmax - content_width) / 2; + cell->xmax = xmax; + } + else if (align == 2) { + cell->xpos = xmax - content_width; + cell->xmax = xmax; + } + else { + // inline alignment: the cells of the column don't have an aligned + // right border, the right border of each cell depends on the content + cell->xpos = cell->xmin; + cell->xmax = cell->xmin + content_width; + } +} diff --git a/src/gui/guiTable.h b/src/gui/guiTable.h new file mode 100644 index 0000000..76a0e94 --- /dev/null +++ b/src/gui/guiTable.h @@ -0,0 +1,263 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <map> +#include <set> +#include <string> +#include <vector> +#include <iostream> + +#include "irrlichttypes_extrabloated.h" +#include "guiScrollBar.h" + +class ISimpleTextureSource; + +/* + A table GUI element for GUIFormSpecMenu. + + Sends a EGET_TABLE_CHANGED event to the parent when + an item is selected or double-clicked. + Call checkEvent() to get info. + + Credits: The interface and implementation of this class are (very) + loosely based on the Irrlicht classes CGUITable and CGUIListBox. + CGUITable and CGUIListBox are licensed under the Irrlicht license; + they are Copyright (C) 2002-2012 Nikolaus Gebhardt +*/ +class GUITable : public gui::IGUIElement +{ +public: + /* + Stores dynamic data that should be preserved + when updating a formspec + */ + struct DynamicData + { + s32 selected = 0; + s32 scrollpos = 0; + s32 keynav_time = 0; + core::stringw keynav_buffer; + std::set<s32> opened_trees; + }; + + /* + An option of the form <name>=<value> + */ + struct Option + { + std::string name; + std::string value; + + Option(const std::string &name_, const std::string &value_) : + name(name_), + value(value_) + {} + }; + + /* + A list of options that concern the entire table + */ + typedef std::vector<Option> TableOptions; + + /* + A column with options + */ + struct TableColumn + { + std::string type; + std::vector<Option> options; + }; + typedef std::vector<TableColumn> TableColumns; + + + GUITable(gui::IGUIEnvironment *env, + gui::IGUIElement *parent, s32 id, + core::rect<s32> rectangle, + ISimpleTextureSource *tsrc); + + virtual ~GUITable(); + + /* Split a string of the form "name=value" into name and value */ + static Option splitOption(const std::string &str); + + /* Set textlist-like options, columns and data */ + void setTextList(const std::vector<std::string> &content, + bool transparent); + + /* Set generic table options, columns and content */ + // Adds empty strings to end of content if there is an incomplete row + void setTable(const TableOptions &options, + const TableColumns &columns, + std::vector<std::string> &content); + + /* Clear the table */ + void clear(); + + /* Get info about last event (string such as "CHG:1:2") */ + // Call this after EGET_TABLE_CHANGED + std::string checkEvent(); + + /* Get index of currently selected row (first=1; 0 if none selected) */ + s32 getSelected() const; + + /* Set currently selected row (first=1; 0 if none selected) */ + // If given index is not visible at the moment, select its parent + // Autoscroll to make the selected row fully visible + void setSelected(s32 index); + + //! Sets another skin independent font. If this is set to zero, the button uses the font of the skin. + virtual void setOverrideFont(gui::IGUIFont *font = nullptr); + + //! Gets the override font (if any) + virtual gui::IGUIFont *getOverrideFont() const; + + /* Get selection, scroll position and opened (sub)trees */ + DynamicData getDynamicData() const; + + /* Set selection, scroll position and opened (sub)trees */ + void setDynamicData(const DynamicData &dyndata); + + /* Returns "GUITable" */ + virtual const c8* getTypeName() const; + + /* Must be called when position or size changes */ + virtual void updateAbsolutePosition(); + + /* Irrlicht draw method */ + virtual void draw(); + + /* Irrlicht event handler */ + virtual bool OnEvent(const SEvent &event); + +protected: + enum ColumnType { + COLUMN_TYPE_TEXT, + COLUMN_TYPE_IMAGE, + COLUMN_TYPE_COLOR, + COLUMN_TYPE_INDENT, + COLUMN_TYPE_TREE, + }; + + struct Cell { + s32 xmin; + s32 xmax; + s32 xpos; + ColumnType content_type; + s32 content_index; + s32 tooltip_index; + video::SColor color; + bool color_defined; + s32 reported_column; + }; + + struct Row { + Cell *cells; + s32 cellcount; + s32 indent; + // visible_index >= 0: is index of row in m_visible_rows + // visible_index == -1: parent open but other ancestor closed + // visible_index == -2: parent closed + s32 visible_index; + }; + + // Texture source + ISimpleTextureSource *m_tsrc; + + // Table content (including hidden rows) + std::vector<Row> m_rows; + // Table content (only visible; indices into m_rows) + std::vector<s32> m_visible_rows; + bool m_is_textlist = false; + bool m_has_tree_column = false; + + // Selection status + s32 m_selected = -1; // index of row (1...n), or 0 if none selected + s32 m_sel_column = 0; + bool m_sel_doubleclick = false; + + // Keyboard navigation stuff + u64 m_keynav_time = 0; + core::stringw m_keynav_buffer = L""; + + // Drawing and geometry information + bool m_border = true; + video::SColor m_color = video::SColor(255, 255, 255, 255); + video::SColor m_background = video::SColor(255, 0, 0, 0); + video::SColor m_highlight = video::SColor(255, 70, 100, 50); + video::SColor m_highlight_text = video::SColor(255, 255, 255, 255); + s32 m_rowheight = 1; + gui::IGUIFont *m_font = nullptr; + GUIScrollBar *m_scrollbar = nullptr; + + // Allocated strings and images + std::vector<core::stringw> m_strings; + std::vector<video::ITexture*> m_images; + std::map<std::string, s32> m_alloc_strings; + std::map<std::string, s32> m_alloc_images; + + s32 allocString(const std::string &text); + s32 allocImage(const std::string &imagename); + void allocationComplete(); + + // Helper for draw() that draws a single cell + void drawCell(const Cell *cell, video::SColor color, + const core::rect<s32> &rowrect, + const core::rect<s32> &client_clip); + + // Returns the i-th visible row (NULL if i is invalid) + const Row *getRow(s32 i) const; + + // Key navigation helper + bool doesRowStartWith(const Row *row, const core::stringw &str) const; + + // Returns the row at a given screen Y coordinate + // Returns index i such that m_rows[i] is valid (or -1 on error) + s32 getRowAt(s32 y, bool &really_hovering) const; + + // Returns the cell at a given screen X coordinate within m_rows[row_i] + // Returns index j such that m_rows[row_i].cells[j] is valid + // (or -1 on error) + s32 getCellAt(s32 x, s32 row_i) const; + + // Make the selected row fully visible + void autoScroll(); + + // Should be called when m_rowcount or m_rowheight changes + void updateScrollBar(); + + // Sends EET_GUI_EVENT / EGET_TABLE_CHANGED to parent + void sendTableEvent(s32 column, bool doubleclick); + + // Functions that help deal with hidden rows + // The following functions take raw row indices (hidden rows not skipped) + void getOpenedTrees(std::set<s32> &opened_trees) const; + void setOpenedTrees(const std::set<s32> &opened_trees); + void openTree(s32 to_open); + void closeTree(s32 to_close); + // The following function takes a visible row index (hidden rows skipped) + // dir: -1 = left (close), 0 = auto (toggle), 1 = right (open) + void toggleVisibleTree(s32 row_i, int dir, bool move_selection); + + // Aligns cell content in column according to alignment specification + // align = 0: left aligned, 1: centered, 2: right aligned, 3: inline + static void alignContent(Cell *cell, s32 xmax, s32 content_width, + s32 align); +}; diff --git a/src/gui/guiVolumeChange.cpp b/src/gui/guiVolumeChange.cpp new file mode 100644 index 0000000..0f6f43f --- /dev/null +++ b/src/gui/guiVolumeChange.cpp @@ -0,0 +1,182 @@ +/* +Part of Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013 Ciaran Gultnieks <ciaran@ciarang.com> +Copyright (C) 2013 RealBadAngel, Maciej Kasatkin <mk@realbadangel.pl> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "guiVolumeChange.h" +#include "debug.h" +#include "guiButton.h" +#include "serialization.h" +#include <string> +#include <IGUICheckBox.h> +#include <IGUIButton.h> +#include <IGUIScrollBar.h> +#include <IGUIStaticText.h> +#include <IGUIFont.h> +#include "settings.h" + +#include "gettext.h" + +const int ID_soundText = 263; +const int ID_soundExitButton = 264; +const int ID_soundSlider = 265; +const int ID_soundMuteButton = 266; + +GUIVolumeChange::GUIVolumeChange(gui::IGUIEnvironment* env, + gui::IGUIElement* parent, s32 id, + IMenuManager *menumgr, ISimpleTextureSource *tsrc +): + GUIModalMenu(env, parent, id, menumgr), + m_tsrc(tsrc) +{ +} + +void GUIVolumeChange::regenerateGui(v2u32 screensize) +{ + /* + Remove stuff + */ + removeAllChildren(); + /* + Calculate new sizes and positions + */ + const float s = m_gui_scale; + DesiredRect = core::rect<s32>( + screensize.X / 2 - 380 * s / 2, + screensize.Y / 2 - 200 * s / 2, + screensize.X / 2 + 380 * s / 2, + screensize.Y / 2 + 200 * s / 2 + ); + recalculateAbsolutePosition(false); + + v2s32 size = DesiredRect.getSize(); + int volume = (int)(g_settings->getFloat("sound_volume") * 100); + + /* + Add stuff + */ + { + core::rect<s32> rect(0, 0, 160 * s, 20 * s); + rect = rect + v2s32(size.X / 2 - 80 * s, size.Y / 2 - 70 * s); + + wchar_t text[100]; + const wchar_t *str = wgettext("Sound Volume: %d%%"); + swprintf(text, sizeof(text) / sizeof(wchar_t), str, volume); + delete[] str; + core::stringw volume_text = text; + + Environment->addStaticText(volume_text.c_str(), rect, false, + true, this, ID_soundText); + } + { + core::rect<s32> rect(0, 0, 80 * s, 30 * s); + rect = rect + v2s32(size.X / 2 - 80 * s / 2, size.Y / 2 + 55 * s); + const wchar_t *text = wgettext("Exit"); + GUIButton::addButton(Environment, rect, m_tsrc, this, ID_soundExitButton, text); + delete[] text; + } + { + core::rect<s32> rect(0, 0, 300 * s, 20 * s); + rect = rect + v2s32(size.X / 2 - 150 * s, size.Y / 2); + gui::IGUIScrollBar *e = Environment->addScrollBar(true, + rect, this, ID_soundSlider); + e->setMax(100); + e->setPos(volume); + } + { + core::rect<s32> rect(0, 0, 160 * s, 20 * s); + rect = rect + v2s32(size.X / 2 - 80 * s, size.Y / 2 - 35 * s); + const wchar_t *text = wgettext("Muted"); + Environment->addCheckBox(g_settings->getBool("mute_sound"), rect, this, + ID_soundMuteButton, text); + delete[] text; + } +} + +void GUIVolumeChange::drawMenu() +{ + gui::IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + video::IVideoDriver* driver = Environment->getVideoDriver(); + video::SColor bgcolor(140, 0, 0, 0); + driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect); + gui::IGUIElement::draw(); +} + +bool GUIVolumeChange::OnEvent(const SEvent& event) +{ + if (event.EventType == EET_KEY_INPUT_EVENT) { + if (event.KeyInput.Key == KEY_ESCAPE && event.KeyInput.PressedDown) { + quitMenu(); + return true; + } + + if (event.KeyInput.Key == KEY_RETURN && event.KeyInput.PressedDown) { + quitMenu(); + return true; + } + } else if (event.EventType == EET_GUI_EVENT) { + if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED) { + gui::IGUIElement *e = getElementFromId(ID_soundMuteButton); + if (e != NULL && e->getType() == gui::EGUIET_CHECK_BOX) { + g_settings->setBool("mute_sound", ((gui::IGUICheckBox*)e)->isChecked()); + } + + Environment->setFocus(this); + return true; + } + + if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) { + if (event.GUIEvent.Caller->getID() == ID_soundExitButton) { + quitMenu(); + return true; + } + Environment->setFocus(this); + } + + if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST + && isVisible()) { + if (!canTakeFocus(event.GUIEvent.Element)) { + infostream << "GUIVolumeChange: Not allowing focus change." + << std::endl; + // Returning true disables focus change + return true; + } + } + if (event.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED) { + if (event.GUIEvent.Caller->getID() == ID_soundSlider) { + s32 pos = ((gui::IGUIScrollBar*)event.GUIEvent.Caller)->getPos(); + g_settings->setFloat("sound_volume", (float) pos / 100); + + gui::IGUIElement *e = getElementFromId(ID_soundText); + wchar_t text[100]; + const wchar_t *str = wgettext("Sound Volume: %d%%"); + swprintf(text, sizeof(text) / sizeof(wchar_t), str, pos); + delete[] str; + + core::stringw volume_text = text; + + e->setText(volume_text.c_str()); + return true; + } + } + + } + + return Parent ? Parent->OnEvent(event) : false; +} diff --git a/src/gui/guiVolumeChange.h b/src/gui/guiVolumeChange.h new file mode 100644 index 0000000..ccdaca0 --- /dev/null +++ b/src/gui/guiVolumeChange.h @@ -0,0 +1,51 @@ +/* +Part of Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013 Ciaran Gultnieks <ciaran@ciarang.com> +Copyright (C) 2013 RealBadAngel, Maciej Kasatkin <mk@realbadangel.pl> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "modalMenu.h" +#include <string> + +class ISimpleTextureSource; + +class GUIVolumeChange : public GUIModalMenu +{ +public: + GUIVolumeChange(gui::IGUIEnvironment* env, + gui::IGUIElement* parent, s32 id, + IMenuManager *menumgr, ISimpleTextureSource *tsrc); + /* + Remove and re-add (or reposition) stuff + */ + void regenerateGui(v2u32 screensize); + + void drawMenu(); + + bool OnEvent(const SEvent& event); + + bool pausesGame() { return true; } + +protected: + std::wstring getLabelByID(s32 id) { return L""; } + std::string getNameByID(s32 id) { return ""; } + +private: + ISimpleTextureSource *m_tsrc; +}; diff --git a/src/gui/mainmenumanager.h b/src/gui/mainmenumanager.h new file mode 100644 index 0000000..76d3573 --- /dev/null +++ b/src/gui/mainmenumanager.h @@ -0,0 +1,148 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +/* + All kinds of stuff that needs to be exposed from main.cpp +*/ +#include "modalMenu.h" +#include <cassert> +#include <list> + +class IGameCallback +{ +public: + virtual void exitToOS() = 0; + virtual void keyConfig() = 0; + virtual void disconnect() = 0; + virtual void changePassword() = 0; + virtual void changeVolume() = 0; + + virtual void signalKeyConfigChange() = 0; +}; + +extern gui::IGUIEnvironment *guienv; +extern gui::IGUIStaticText *guiroot; + +// Handler for the modal menus + +class MainMenuManager : public IMenuManager +{ +public: + virtual void createdMenu(gui::IGUIElement *menu) + { +#ifndef NDEBUG + for (gui::IGUIElement *i : m_stack) { + assert(i != menu); + } +#endif + + if(!m_stack.empty()) + m_stack.back()->setVisible(false); + m_stack.push_back(menu); + } + + virtual void deletingMenu(gui::IGUIElement *menu) + { + // Remove all entries if there are duplicates + m_stack.remove(menu); + + if(!m_stack.empty()) + m_stack.back()->setVisible(true); + } + + // Returns true to prevent further processing + virtual bool preprocessEvent(const SEvent& event) + { + if (m_stack.empty()) + return false; + GUIModalMenu *mm = dynamic_cast<GUIModalMenu*>(m_stack.back()); + return mm && mm->preprocessEvent(event); + } + + u32 menuCount() + { + return m_stack.size(); + } + + bool pausesGame() + { + for (gui::IGUIElement *i : m_stack) { + GUIModalMenu *mm = dynamic_cast<GUIModalMenu*>(i); + if (mm && mm->pausesGame()) + return true; + } + return false; + } + + std::list<gui::IGUIElement*> m_stack; +}; + +extern MainMenuManager g_menumgr; + +extern bool isMenuActive(); + +class MainGameCallback : public IGameCallback +{ +public: + MainGameCallback() = default; + virtual ~MainGameCallback() = default; + + virtual void exitToOS() + { + shutdown_requested = true; + } + + virtual void disconnect() + { + disconnect_requested = true; + } + + virtual void changePassword() + { + changepassword_requested = true; + } + + virtual void changeVolume() + { + changevolume_requested = true; + } + + virtual void keyConfig() + { + keyconfig_requested = true; + } + + virtual void signalKeyConfigChange() + { + keyconfig_changed = true; + } + + + bool disconnect_requested = false; + bool changepassword_requested = false; + bool changevolume_requested = false; + bool keyconfig_requested = false; + bool shutdown_requested = false; + + bool keyconfig_changed = false; +}; + +extern MainGameCallback *g_gamecallback; diff --git a/src/gui/modalMenu.cpp b/src/gui/modalMenu.cpp new file mode 100644 index 0000000..9f5258c --- /dev/null +++ b/src/gui/modalMenu.cpp @@ -0,0 +1,361 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2018 stujones11, Stuart Jones <stujones111@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <cstdlib> +#include "client/renderingengine.h" +#include "modalMenu.h" +#include "gettext.h" +#include "porting.h" +#include "settings.h" + +#ifdef HAVE_TOUCHSCREENGUI +#include "touchscreengui.h" +#endif + +// clang-format off +GUIModalMenu::GUIModalMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, + s32 id, IMenuManager *menumgr, bool remap_dbl_click) : + IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, + core::rect<s32>(0, 0, 100, 100)), +#ifdef __ANDROID__ + m_jni_field_name(""), +#endif + m_menumgr(menumgr), + m_remap_dbl_click(remap_dbl_click) +{ + m_gui_scale = std::max(g_settings->getFloat("gui_scaling"), 0.5f); + const float screen_dpi_scale = RenderingEngine::getDisplayDensity(); +#ifdef HAVE_TOUCHSCREENGUI + m_gui_scale *= 1.1f - 0.3f * screen_dpi_scale + 0.2f * screen_dpi_scale * screen_dpi_scale; +#else + m_gui_scale *= screen_dpi_scale; +#endif + + setVisible(true); + Environment->setFocus(this); + m_menumgr->createdMenu(this); + + m_doubleclickdetect[0].time = 0; + m_doubleclickdetect[1].time = 0; + + m_doubleclickdetect[0].pos = v2s32(0, 0); + m_doubleclickdetect[1].pos = v2s32(0, 0); +} +// clang-format on + +GUIModalMenu::~GUIModalMenu() +{ + m_menumgr->deletingMenu(this); +} + +void GUIModalMenu::allowFocusRemoval(bool allow) +{ + m_allow_focus_removal = allow; +} + +bool GUIModalMenu::canTakeFocus(gui::IGUIElement *e) +{ + return (e && (e == this || isMyChild(e))) || m_allow_focus_removal; +} + +void GUIModalMenu::draw() +{ + if (!IsVisible) + return; + + video::IVideoDriver *driver = Environment->getVideoDriver(); + v2u32 screensize = driver->getScreenSize(); + if (screensize != m_screensize_old) { + m_screensize_old = screensize; + regenerateGui(screensize); + } + + drawMenu(); +} + +/* + This should be called when the menu wants to quit. + + WARNING: THIS DEALLOCATES THE MENU FROM MEMORY. Return + immediately if you call this from the menu itself. + + (More precisely, this decrements the reference count.) +*/ +void GUIModalMenu::quitMenu() +{ + allowFocusRemoval(true); + // This removes Environment's grab on us + Environment->removeFocus(this); + m_menumgr->deletingMenu(this); + this->remove(); +#ifdef HAVE_TOUCHSCREENGUI + if (g_touchscreengui && m_touchscreen_visible) + g_touchscreengui->show(); +#endif +} + +// clang-format off +bool GUIModalMenu::DoubleClickDetection(const SEvent &event) +{ + /* The following code is for capturing double-clicks of the mouse button + * and translating the double-click into an EET_KEY_INPUT_EVENT event + * -- which closes the form -- under some circumstances. + * + * There have been many github issues reporting this as a bug even though it + * was an intended feature. For this reason, remapping the double-click as + * an ESC must be explicitly set when creating this class via the + * /p remap_dbl_click parameter of the constructor. + */ + + if (!m_remap_dbl_click) + return false; + + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { + m_doubleclickdetect[0].pos = m_doubleclickdetect[1].pos; + m_doubleclickdetect[0].time = m_doubleclickdetect[1].time; + + m_doubleclickdetect[1].pos = m_pointer; + m_doubleclickdetect[1].time = porting::getTimeMs(); + } else if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) { + u64 delta = porting::getDeltaMs( + m_doubleclickdetect[0].time, porting::getTimeMs()); + if (delta > 400) + return false; + + double squaredistance = m_doubleclickdetect[0].pos. + getDistanceFromSQ(m_doubleclickdetect[1].pos); + + if (squaredistance > (30 * 30)) { + return false; + } + + SEvent translated{}; + // translate doubleclick to escape + translated.EventType = EET_KEY_INPUT_EVENT; + translated.KeyInput.Key = KEY_ESCAPE; + translated.KeyInput.Control = false; + translated.KeyInput.Shift = false; + translated.KeyInput.PressedDown = true; + translated.KeyInput.Char = 0; + OnEvent(translated); + + return true; + } + + return false; +} +// clang-format on + +static bool isChild(gui::IGUIElement *tocheck, gui::IGUIElement *parent) +{ + while (tocheck) { + if (tocheck == parent) { + return true; + } + tocheck = tocheck->getParent(); + } + return false; +} + +#ifdef HAVE_TOUCHSCREENGUI + +bool GUIModalMenu::simulateMouseEvent( + gui::IGUIElement *target, ETOUCH_INPUT_EVENT touch_event) +{ + SEvent mouse_event{}; // value-initialized, not unitialized + mouse_event.EventType = EET_MOUSE_INPUT_EVENT; + mouse_event.MouseInput.X = m_pointer.X; + mouse_event.MouseInput.Y = m_pointer.Y; + switch (touch_event) { + case ETIE_PRESSED_DOWN: + mouse_event.MouseInput.Event = EMIE_LMOUSE_PRESSED_DOWN; + mouse_event.MouseInput.ButtonStates = EMBSM_LEFT; + break; + case ETIE_MOVED: + mouse_event.MouseInput.Event = EMIE_MOUSE_MOVED; + mouse_event.MouseInput.ButtonStates = EMBSM_LEFT; + break; + case ETIE_LEFT_UP: + mouse_event.MouseInput.Event = EMIE_LMOUSE_LEFT_UP; + mouse_event.MouseInput.ButtonStates = 0; + break; + default: + return false; + } + if (preprocessEvent(mouse_event)) + return true; + if (!target) + return false; + return target->OnEvent(mouse_event); +} + +void GUIModalMenu::enter(gui::IGUIElement *hovered) +{ + if (!hovered) + return; + sanity_check(!m_hovered); + m_hovered.grab(hovered); + SEvent gui_event{}; + gui_event.EventType = EET_GUI_EVENT; + gui_event.GUIEvent.Caller = m_hovered.get(); + gui_event.GUIEvent.EventType = EGET_ELEMENT_HOVERED; + gui_event.GUIEvent.Element = gui_event.GUIEvent.Caller; + m_hovered->OnEvent(gui_event); +} + +void GUIModalMenu::leave() +{ + if (!m_hovered) + return; + SEvent gui_event{}; + gui_event.EventType = EET_GUI_EVENT; + gui_event.GUIEvent.Caller = m_hovered.get(); + gui_event.GUIEvent.EventType = EGET_ELEMENT_LEFT; + m_hovered->OnEvent(gui_event); + m_hovered.reset(); +} + +#endif + +bool GUIModalMenu::preprocessEvent(const SEvent &event) +{ +#ifdef __ANDROID__ + // clang-format off + // display software keyboard when clicking edit boxes + if (event.EventType == EET_MOUSE_INPUT_EVENT && + event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { + gui::IGUIElement *hovered = + Environment->getRootGUIElement()->getElementFromPoint( + core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y)); + if ((hovered) && (hovered->getType() == irr::gui::EGUIET_EDIT_BOX)) { + bool retval = hovered->OnEvent(event); + if (retval) + Environment->setFocus(hovered); + + std::string field_name = getNameByID(hovered->getID()); + // read-only field + if (field_name.empty()) + return retval; + + m_jni_field_name = field_name; + + // single line text input + int type = 2; + + // multi line text input + if (((gui::IGUIEditBox *)hovered)->isMultiLineEnabled()) + type = 1; + + // passwords are always single line + if (((gui::IGUIEditBox *)hovered)->isPasswordBox()) + type = 3; + + porting::showInputDialog(gettext("OK"), "", + wide_to_utf8(((gui::IGUIEditBox *)hovered)->getText()), type); + return retval; + } + } +#endif + +#ifdef HAVE_TOUCHSCREENGUI + if (event.EventType == EET_TOUCH_INPUT_EVENT) { + irr_ptr<GUIModalMenu> holder; + holder.grab(this); // keep this alive until return (it might be dropped downstream [?]) + + switch ((int)event.TouchInput.touchedCount) { + case 1: { + if (event.TouchInput.Event == ETIE_PRESSED_DOWN || event.TouchInput.Event == ETIE_MOVED) + m_pointer = v2s32(event.TouchInput.X, event.TouchInput.Y); + if (event.TouchInput.Event == ETIE_PRESSED_DOWN) + m_down_pos = m_pointer; + gui::IGUIElement *hovered = Environment->getRootGUIElement()->getElementFromPoint(core::position2d<s32>(m_pointer)); + if (event.TouchInput.Event == ETIE_PRESSED_DOWN) + Environment->setFocus(hovered); + if (m_hovered != hovered) { + leave(); + enter(hovered); + } + gui::IGUIElement *focused = Environment->getFocus(); + bool ret = simulateMouseEvent(focused, event.TouchInput.Event); + if (!ret && m_hovered != focused) + ret = simulateMouseEvent(m_hovered.get(), event.TouchInput.Event); + if (event.TouchInput.Event == ETIE_LEFT_UP) + leave(); + return ret; + } + case 2: { + if (event.TouchInput.Event != ETIE_PRESSED_DOWN) + return true; // ignore + auto focused = Environment->getFocus(); + if (!focused) + return true; + SEvent rclick_event{}; + rclick_event.EventType = EET_MOUSE_INPUT_EVENT; + rclick_event.MouseInput.Event = EMIE_RMOUSE_PRESSED_DOWN; + rclick_event.MouseInput.ButtonStates = EMBSM_LEFT | EMBSM_RIGHT; + rclick_event.MouseInput.X = m_pointer.X; + rclick_event.MouseInput.Y = m_pointer.Y; + focused->OnEvent(rclick_event); + rclick_event.MouseInput.Event = EMIE_RMOUSE_LEFT_UP; + rclick_event.MouseInput.ButtonStates = EMBSM_LEFT; + focused->OnEvent(rclick_event); + return true; + } + default: // ignored + return true; + } + } +#endif + + if (event.EventType == EET_MOUSE_INPUT_EVENT) { + s32 x = event.MouseInput.X; + s32 y = event.MouseInput.Y; + gui::IGUIElement *hovered = + Environment->getRootGUIElement()->getElementFromPoint( + core::position2d<s32>(x, y)); + if (!isChild(hovered, this)) { + if (DoubleClickDetection(event)) { + return true; + } + } + } + return false; +} + +#ifdef __ANDROID__ +bool GUIModalMenu::hasAndroidUIInput() +{ + // no dialog shown + if (m_jni_field_name.empty()) + return false; + + // still waiting + if (porting::getInputDialogState() == -1) + return true; + + // no value abort dialog processing + if (porting::getInputDialogState() != 0) { + m_jni_field_name.clear(); + return false; + } + + return true; +} +#endif diff --git a/src/gui/modalMenu.h b/src/gui/modalMenu.h new file mode 100644 index 0000000..e37c415 --- /dev/null +++ b/src/gui/modalMenu.h @@ -0,0 +1,111 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include "irr_ptr.h" +#include "util/string.h" + +class GUIModalMenu; + +class IMenuManager +{ +public: + // A GUIModalMenu calls these when this class is passed as a parameter + virtual void createdMenu(gui::IGUIElement *menu) = 0; + virtual void deletingMenu(gui::IGUIElement *menu) = 0; +}; + +// Remember to drop() the menu after creating, so that it can +// remove itself when it wants to. + +class GUIModalMenu : public gui::IGUIElement +{ +public: + GUIModalMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, s32 id, + IMenuManager *menumgr, bool remap_dbl_click = true); + virtual ~GUIModalMenu(); + + void allowFocusRemoval(bool allow); + bool canTakeFocus(gui::IGUIElement *e); + void draw(); + void quitMenu(); + + virtual void regenerateGui(v2u32 screensize) = 0; + virtual void drawMenu() = 0; + virtual bool preprocessEvent(const SEvent &event); + virtual bool OnEvent(const SEvent &event) { return false; }; + virtual bool pausesGame() { return false; } // Used for pause menu +#ifdef __ANDROID__ + virtual bool getAndroidUIInput() { return false; } + bool hasAndroidUIInput(); +#endif + +protected: + virtual std::wstring getLabelByID(s32 id) = 0; + virtual std::string getNameByID(s32 id) = 0; + + /** + * check if event is part of a double click + * @param event event to evaluate + * @return true/false if a doubleclick was detected + */ + bool DoubleClickDetection(const SEvent &event); + + v2s32 m_pointer; + v2s32 m_old_pointer; // Mouse position after previous mouse event + v2u32 m_screensize_old; + float m_gui_scale; +#ifdef __ANDROID__ + std::string m_jni_field_name; +#endif +#ifdef HAVE_TOUCHSCREENGUI + v2s32 m_down_pos; + bool m_touchscreen_visible = true; +#endif + +private: + struct clickpos + { + v2s32 pos; + s64 time; + }; + clickpos m_doubleclickdetect[2]; + + IMenuManager *m_menumgr; + /* If true, remap a double-click (or double-tap) action to ESC. This is so + * that, for example, Android users can double-tap to close a formspec. + * + * This value can (currently) only be set by the class constructor + * and the default value for the setting is true. + */ + bool m_remap_dbl_click; + // This might be necessary to expose to the implementation if it + // wants to launch other menus + bool m_allow_focus_removal = false; + +#ifdef HAVE_TOUCHSCREENGUI + irr_ptr<gui::IGUIElement> m_hovered; + + bool simulateMouseEvent(gui::IGUIElement *target, ETOUCH_INPUT_EVENT touch_event); + void enter(gui::IGUIElement *element); + void leave(); +#endif +}; diff --git a/src/gui/profilergraph.cpp b/src/gui/profilergraph.cpp new file mode 100644 index 0000000..f71ef37 --- /dev/null +++ b/src/gui/profilergraph.cpp @@ -0,0 +1,176 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "porting.h" +#include "profilergraph.h" +#include "util/string.h" + +void ProfilerGraph::put(const Profiler::GraphValues &values) +{ + m_log.emplace_back(values); + + while (m_log.size() > m_log_max_size) + m_log.erase(m_log.begin()); +} + +void ProfilerGraph::draw(s32 x_left, s32 y_bottom, video::IVideoDriver *driver, + gui::IGUIFont *font) const +{ + // Do *not* use UNORDERED_MAP here as the order needs + // to be the same for each call to prevent flickering + std::map<std::string, Meta> m_meta; + + for (const Piece &piece : m_log) { + for (const auto &i : piece.values) { + const std::string &id = i.first; + const float &value = i.second; + std::map<std::string, Meta>::iterator j = m_meta.find(id); + + if (j == m_meta.end()) { + m_meta[id] = Meta(value); + continue; + } + + if (value < j->second.min) + j->second.min = value; + + if (value > j->second.max) + j->second.max = value; + } + } + + // Assign colors + static const video::SColor usable_colors[] = {video::SColor(255, 255, 100, 100), + video::SColor(255, 90, 225, 90), + video::SColor(255, 100, 100, 255), + video::SColor(255, 255, 150, 50), + video::SColor(255, 220, 220, 100)}; + static const u32 usable_colors_count = + sizeof(usable_colors) / sizeof(*usable_colors); + u32 next_color_i = 0; + + for (auto &i : m_meta) { + Meta &meta = i.second; + video::SColor color(255, 200, 200, 200); + + if (next_color_i < usable_colors_count) + color = usable_colors[next_color_i++]; + + meta.color = color; + } + + s32 graphh = 50; + s32 textx = x_left + m_log_max_size + 15; + s32 textx2 = textx + 200 - 15; + s32 meta_i = 0; + + for (const auto &p : m_meta) { + const std::string &id = p.first; + const Meta &meta = p.second; + s32 x = x_left; + s32 y = y_bottom - meta_i * 50; + float show_min = meta.min; + float show_max = meta.max; + + if (show_min >= -0.0001 && show_max >= -0.0001) { + if (show_min <= show_max * 0.5) + show_min = 0; + } + + const s32 texth = 15; + char buf[10]; + if (floorf(show_max) == show_max) + porting::mt_snprintf(buf, sizeof(buf), "%.5g", show_max); + else + porting::mt_snprintf(buf, sizeof(buf), "%.3g", show_max); + font->draw(utf8_to_wide(buf).c_str(), + core::rect<s32>(textx, y - graphh, textx2, + y - graphh + texth), + meta.color); + + if (floorf(show_min) == show_min) + porting::mt_snprintf(buf, sizeof(buf), "%.5g", show_min); + else + porting::mt_snprintf(buf, sizeof(buf), "%.3g", show_min); + font->draw(utf8_to_wide(buf).c_str(), + core::rect<s32>(textx, y - texth, textx2, y), meta.color); + + font->draw(utf8_to_wide(id).c_str(), + core::rect<s32>(textx, y - graphh / 2 - texth / 2, textx2, + y - graphh / 2 + texth / 2), + meta.color); + + s32 graph1y = y; + s32 graph1h = graphh; + bool relativegraph = (show_min != 0 && show_min != show_max); + float lastscaledvalue = 0.0; + bool lastscaledvalue_exists = false; + + for (const Piece &piece : m_log) { + float value = 0; + bool value_exists = false; + Profiler::GraphValues::const_iterator k = piece.values.find(id); + + if (k != piece.values.end()) { + value = k->second; + value_exists = true; + } + + if (!value_exists) { + x++; + lastscaledvalue_exists = false; + continue; + } + + float scaledvalue = 1.0; + + if (show_max != show_min) + scaledvalue = (value - show_min) / (show_max - show_min); + + if (scaledvalue == 1.0 && value == 0) { + x++; + lastscaledvalue_exists = false; + continue; + } + + if (relativegraph) { + if (lastscaledvalue_exists) { + s32 ivalue1 = lastscaledvalue * graph1h; + s32 ivalue2 = scaledvalue * graph1h; + driver->draw2DLine( + v2s32(x - 1, graph1y - ivalue1), + v2s32(x, graph1y - ivalue2), + meta.color); + } + + lastscaledvalue = scaledvalue; + lastscaledvalue_exists = true; + } else { + s32 ivalue = scaledvalue * graph1h; + driver->draw2DLine(v2s32(x, graph1y), + v2s32(x, graph1y - ivalue), meta.color); + } + + x++; + } + + meta_i++; + } +} diff --git a/src/gui/profilergraph.h b/src/gui/profilergraph.h new file mode 100644 index 0000000..6354ac9 --- /dev/null +++ b/src/gui/profilergraph.h @@ -0,0 +1,61 @@ +/* +Minetest +Copyright (C) 2010-2018 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <SColor.h> +#include <deque> +#include <utility> +#include <IGUIFont.h> +#include <IVideoDriver.h> +#include "profiler.h" + +/* Profiler display */ +class ProfilerGraph +{ +private: + struct Piece + { + Piece(Profiler::GraphValues v) : values(std::move(v)) {} + Profiler::GraphValues values; + }; + struct Meta + { + float min; + float max; + video::SColor color; + Meta(float initial = 0, + video::SColor color = video::SColor(255, 255, 255, 255)) : + min(initial), + max(initial), color(color) + { + } + }; + std::deque<Piece> m_log; + +public: + u32 m_log_max_size = 200; + + ProfilerGraph() = default; + + void put(const Profiler::GraphValues &values); + + void draw(s32 x_left, s32 y_bottom, video::IVideoDriver *driver, + gui::IGUIFont *font) const; +}; diff --git a/src/gui/touchscreengui.cpp b/src/gui/touchscreengui.cpp new file mode 100644 index 0000000..d483c13 --- /dev/null +++ b/src/gui/touchscreengui.cpp @@ -0,0 +1,1200 @@ +/* +Copyright (C) 2014 sapier +Copyright (C) 2018 srifqi, Muhammad Rifqi Priyo Susanto + <muhammadrifqipriyosusanto@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "touchscreengui.h" +#include "irrlichttypes.h" +#include "irr_v2d.h" +#include "log.h" +#include "client/keycode.h" +#include "settings.h" +#include "gettime.h" +#include "util/numeric.h" +#include "porting.h" +#include "client/guiscalingfilter.h" +#include "client/renderingengine.h" + +#include <iostream> +#include <algorithm> + +using namespace irr::core; + +const char **button_imagenames = (const char *[]) { + "jump_btn.png", + "down.png", + "zoom.png", + "aux1_btn.png" +}; + +const char **joystick_imagenames = (const char *[]) { + "joystick_off.png", + "joystick_bg.png", + "joystick_center.png" +}; + +static irr::EKEY_CODE id2keycode(touch_gui_button_id id) +{ + std::string key = ""; + switch (id) { + case forward_id: + key = "forward"; + break; + case left_id: + key = "left"; + break; + case right_id: + key = "right"; + break; + case backward_id: + key = "backward"; + break; + case inventory_id: + key = "inventory"; + break; + case drop_id: + key = "drop"; + break; + case jump_id: + key = "jump"; + break; + case crunch_id: + key = "sneak"; + break; + case zoom_id: + key = "zoom"; + break; + case aux1_id: + key = "aux1"; + break; + case fly_id: + key = "freemove"; + break; + case noclip_id: + key = "noclip"; + break; + case fast_id: + key = "fastmove"; + break; + case debug_id: + key = "toggle_debug"; + break; + case toggle_chat_id: + key = "toggle_chat"; + break; + case minimap_id: + key = "minimap"; + break; + case chat_id: + key = "chat"; + break; + case camera_id: + key = "camera_mode"; + break; + case range_id: + key = "rangeselect"; + break; + default: + break; + } + assert(!key.empty()); + return keyname_to_keycode(g_settings->get("keymap_" + key).c_str()); +} + +TouchScreenGUI *g_touchscreengui; + +static void load_button_texture(button_info *btn, const char *path, + const rect<s32> &button_rect, ISimpleTextureSource *tsrc, video::IVideoDriver *driver) +{ + unsigned int tid; + video::ITexture *texture = guiScalingImageButton(driver, + tsrc->getTexture(path, &tid), button_rect.getWidth(), + button_rect.getHeight()); + if (texture) { + btn->guibutton->setUseAlphaChannel(true); + if (g_settings->getBool("gui_scaling_filter")) { + rect<s32> txr_rect = rect<s32>(0, 0, button_rect.getWidth(), button_rect.getHeight()); + btn->guibutton->setImage(texture, txr_rect); + btn->guibutton->setPressedImage(texture, txr_rect); + btn->guibutton->setScaleImage(false); + } else { + btn->guibutton->setImage(texture); + btn->guibutton->setPressedImage(texture); + btn->guibutton->setScaleImage(true); + } + btn->guibutton->setDrawBorder(false); + btn->guibutton->setText(L""); + } +} + +AutoHideButtonBar::AutoHideButtonBar(IrrlichtDevice *device, + IEventReceiver *receiver) : + m_driver(device->getVideoDriver()), + m_guienv(device->getGUIEnvironment()), + m_receiver(receiver) +{ +} + +void AutoHideButtonBar::init(ISimpleTextureSource *tsrc, + const char *starter_img, int button_id, const v2s32 &UpperLeft, + const v2s32 &LowerRight, autohide_button_bar_dir dir, float timeout) +{ + m_texturesource = tsrc; + + m_upper_left = UpperLeft; + m_lower_right = LowerRight; + + // init settings bar + + irr::core::rect<int> current_button = rect<s32>(UpperLeft.X, UpperLeft.Y, + LowerRight.X, LowerRight.Y); + + m_starter.guibutton = m_guienv->addButton(current_button, nullptr, button_id, L"", nullptr); + m_starter.guibutton->grab(); + m_starter.repeatcounter = -1; + m_starter.keycode = KEY_OEM_8; // use invalid keycode as it's not relevant + m_starter.immediate_release = true; + m_starter.ids.clear(); + + load_button_texture(&m_starter, starter_img, current_button, + m_texturesource, m_driver); + + m_dir = dir; + m_timeout_value = timeout; + + m_initialized = true; +} + +AutoHideButtonBar::~AutoHideButtonBar() +{ + if (m_starter.guibutton) { + m_starter.guibutton->setVisible(false); + m_starter.guibutton->drop(); + } +} + +void AutoHideButtonBar::addButton(touch_gui_button_id button_id, + const wchar_t *caption, const char *btn_image) +{ + + if (!m_initialized) { + errorstream << "AutoHideButtonBar::addButton not yet initialized!" + << std::endl; + return; + } + int button_size = 0; + + if ((m_dir == AHBB_Dir_Top_Bottom) || (m_dir == AHBB_Dir_Bottom_Top)) + button_size = m_lower_right.X - m_upper_left.X; + else + button_size = m_lower_right.Y - m_upper_left.Y; + + irr::core::rect<int> current_button; + + if ((m_dir == AHBB_Dir_Right_Left) || (m_dir == AHBB_Dir_Left_Right)) { + int x_start = 0; + int x_end = 0; + + if (m_dir == AHBB_Dir_Left_Right) { + x_start = m_lower_right.X + (button_size * 1.25 * m_buttons.size()) + + (button_size * 0.25); + x_end = x_start + button_size; + } else { + x_end = m_upper_left.X - (button_size * 1.25 * m_buttons.size()) + - (button_size * 0.25); + x_start = x_end - button_size; + } + + current_button = rect<s32>(x_start, m_upper_left.Y, x_end, + m_lower_right.Y); + } else { + double y_start = 0; + double y_end = 0; + + if (m_dir == AHBB_Dir_Top_Bottom) { + y_start = m_lower_right.X + (button_size * 1.25 * m_buttons.size()) + + (button_size * 0.25); + y_end = y_start + button_size; + } else { + y_end = m_upper_left.X - (button_size * 1.25 * m_buttons.size()) + - (button_size * 0.25); + y_start = y_end - button_size; + } + + current_button = rect<s32>(m_upper_left.X, y_start, + m_lower_right.Y, y_end); + } + + auto *btn = new button_info(); + btn->guibutton = m_guienv->addButton(current_button, + nullptr, button_id, caption, nullptr); + btn->guibutton->grab(); + btn->guibutton->setVisible(false); + btn->guibutton->setEnabled(false); + btn->repeatcounter = -1; + btn->keycode = id2keycode(button_id); + btn->immediate_release = true; + btn->ids.clear(); + + load_button_texture(btn, btn_image, current_button, m_texturesource, + m_driver); + + m_buttons.push_back(btn); +} + +void AutoHideButtonBar::addToggleButton(touch_gui_button_id button_id, + const wchar_t *caption, const char *btn_image_1, + const char *btn_image_2) +{ + addButton(button_id, caption, btn_image_1); + button_info *btn = m_buttons.back(); + btn->togglable = 1; + btn->textures.push_back(btn_image_1); + btn->textures.push_back(btn_image_2); +} + +bool AutoHideButtonBar::isButton(const SEvent &event) +{ + IGUIElement *rootguielement = m_guienv->getRootGUIElement(); + + if (rootguielement == nullptr) + return false; + + gui::IGUIElement *element = rootguielement->getElementFromPoint( + core::position2d<s32>(event.TouchInput.X, event.TouchInput.Y)); + + if (element == nullptr) + return false; + + if (m_active) { + // check for all buttons in vector + auto iter = m_buttons.begin(); + + while (iter != m_buttons.end()) { + if ((*iter)->guibutton == element) { + + auto *translated = new SEvent(); + memset(translated, 0, sizeof(SEvent)); + translated->EventType = irr::EET_KEY_INPUT_EVENT; + translated->KeyInput.Key = (*iter)->keycode; + translated->KeyInput.Control = false; + translated->KeyInput.Shift = false; + translated->KeyInput.Char = 0; + + // add this event + translated->KeyInput.PressedDown = true; + m_receiver->OnEvent(*translated); + + // remove this event + translated->KeyInput.PressedDown = false; + m_receiver->OnEvent(*translated); + + delete translated; + + (*iter)->ids.push_back(event.TouchInput.ID); + + m_timeout = 0; + + if ((*iter)->togglable == 1) { + (*iter)->togglable = 2; + load_button_texture(*iter, (*iter)->textures[1], + (*iter)->guibutton->getRelativePosition(), + m_texturesource, m_driver); + } else if ((*iter)->togglable == 2) { + (*iter)->togglable = 1; + load_button_texture(*iter, (*iter)->textures[0], + (*iter)->guibutton->getRelativePosition(), + m_texturesource, m_driver); + } + + return true; + } + ++iter; + } + } else { + // check for starter button only + if (element == m_starter.guibutton) { + m_starter.ids.push_back(event.TouchInput.ID); + m_starter.guibutton->setVisible(false); + m_starter.guibutton->setEnabled(false); + m_active = true; + m_timeout = 0; + + auto iter = m_buttons.begin(); + + while (iter != m_buttons.end()) { + (*iter)->guibutton->setVisible(true); + (*iter)->guibutton->setEnabled(true); + ++iter; + } + + return true; + } + } + return false; +} + +void AutoHideButtonBar::step(float dtime) +{ + if (m_active) { + m_timeout += dtime; + + if (m_timeout > m_timeout_value) + deactivate(); + } +} + +void AutoHideButtonBar::deactivate() +{ + if (m_visible) { + m_starter.guibutton->setVisible(true); + m_starter.guibutton->setEnabled(true); + } + m_active = false; + + auto iter = m_buttons.begin(); + + while (iter != m_buttons.end()) { + (*iter)->guibutton->setVisible(false); + (*iter)->guibutton->setEnabled(false); + ++iter; + } +} + +void AutoHideButtonBar::hide() +{ + m_visible = false; + m_starter.guibutton->setVisible(false); + m_starter.guibutton->setEnabled(false); + + auto iter = m_buttons.begin(); + + while (iter != m_buttons.end()) { + (*iter)->guibutton->setVisible(false); + (*iter)->guibutton->setEnabled(false); + ++iter; + } +} + +void AutoHideButtonBar::show() +{ + m_visible = true; + + if (m_active) { + auto iter = m_buttons.begin(); + + while (iter != m_buttons.end()) { + (*iter)->guibutton->setVisible(true); + (*iter)->guibutton->setEnabled(true); + ++iter; + } + } else { + m_starter.guibutton->setVisible(true); + m_starter.guibutton->setEnabled(true); + } +} + +TouchScreenGUI::TouchScreenGUI(IrrlichtDevice *device, IEventReceiver *receiver): + m_device(device), + m_guienv(device->getGUIEnvironment()), + m_receiver(receiver), + m_settingsbar(device, receiver), + m_rarecontrolsbar(device, receiver) +{ + for (auto &button : m_buttons) { + button.guibutton = nullptr; + button.repeatcounter = -1; + button.repeatdelay = BUTTON_REPEAT_DELAY; + } + + m_touchscreen_threshold = g_settings->getU16("touchscreen_threshold"); + m_fixed_joystick = g_settings->getBool("fixed_virtual_joystick"); + m_joystick_triggers_aux1 = g_settings->getBool("virtual_joystick_triggers_aux1"); + m_screensize = m_device->getVideoDriver()->getScreenSize(); + button_size = MYMIN(m_screensize.Y / 4.5f, + RenderingEngine::getDisplayDensity() * + g_settings->getFloat("hud_scaling") * 65.0f); +} + +void TouchScreenGUI::initButton(touch_gui_button_id id, const rect<s32> &button_rect, + const std::wstring &caption, bool immediate_release, float repeat_delay) +{ + button_info *btn = &m_buttons[id]; + btn->guibutton = m_guienv->addButton(button_rect, nullptr, id, caption.c_str()); + btn->guibutton->grab(); + btn->repeatcounter = -1; + btn->repeatdelay = repeat_delay; + btn->keycode = id2keycode(id); + btn->immediate_release = immediate_release; + btn->ids.clear(); + + load_button_texture(btn, button_imagenames[id], button_rect, + m_texturesource, m_device->getVideoDriver()); +} + +button_info *TouchScreenGUI::initJoystickButton(touch_gui_button_id id, + const rect<s32> &button_rect, int texture_id, bool visible) +{ + auto *btn = new button_info(); + btn->guibutton = m_guienv->addButton(button_rect, nullptr, id, L"O"); + btn->guibutton->setVisible(visible); + btn->guibutton->grab(); + btn->ids.clear(); + + load_button_texture(btn, joystick_imagenames[texture_id], + button_rect, m_texturesource, m_device->getVideoDriver()); + + return btn; +} + +void TouchScreenGUI::init(ISimpleTextureSource *tsrc) +{ + assert(tsrc); + + m_visible = true; + m_texturesource = tsrc; + + /* Init joystick display "button" + * Joystick is placed on bottom left of screen. + */ + if (m_fixed_joystick) { + m_joystick_btn_off = initJoystickButton(joystick_off_id, + rect<s32>(button_size, + m_screensize.Y - button_size * 4, + button_size * 4, + m_screensize.Y - button_size), 0); + } else { + m_joystick_btn_off = initJoystickButton(joystick_off_id, + rect<s32>(button_size, + m_screensize.Y - button_size * 3, + button_size * 3, + m_screensize.Y - button_size), 0); + } + + m_joystick_btn_bg = initJoystickButton(joystick_bg_id, + rect<s32>(button_size, + m_screensize.Y - button_size * 4, + button_size * 4, + m_screensize.Y - button_size), + 1, false); + + m_joystick_btn_center = initJoystickButton(joystick_center_id, + rect<s32>(0, 0, button_size, button_size), 2, false); + + // init jump button + initButton(jump_id, + rect<s32>(m_screensize.X - (1.75 * button_size), + m_screensize.Y - button_size, + m_screensize.X - (0.25 * button_size), + m_screensize.Y), + L"x", false); + + // init crunch button + initButton(crunch_id, + rect<s32>(m_screensize.X - (3.25 * button_size), + m_screensize.Y - button_size, + m_screensize.X - (1.75 * button_size), + m_screensize.Y), + L"H", false); + + // init zoom button + initButton(zoom_id, + rect<s32>(m_screensize.X - (1.25 * button_size), + m_screensize.Y - (4 * button_size), + m_screensize.X - (0.25 * button_size), + m_screensize.Y - (3 * button_size)), + L"z", false); + + // init aux1 button + if (!m_joystick_triggers_aux1) + initButton(aux1_id, + rect<s32>(m_screensize.X - (1.25 * button_size), + m_screensize.Y - (2.5 * button_size), + m_screensize.X - (0.25 * button_size), + m_screensize.Y - (1.5 * button_size)), + L"spc1", false); + + m_settingsbar.init(m_texturesource, "gear_icon.png", settings_starter_id, + v2s32(m_screensize.X - (1.25 * button_size), + m_screensize.Y - ((SETTINGS_BAR_Y_OFFSET + 1.0) * button_size) + + (0.5 * button_size)), + v2s32(m_screensize.X - (0.25 * button_size), + m_screensize.Y - (SETTINGS_BAR_Y_OFFSET * button_size) + + (0.5 * button_size)), + AHBB_Dir_Right_Left, 3.0); + + m_settingsbar.addButton(fly_id, L"fly", "fly_btn.png"); + m_settingsbar.addButton(noclip_id, L"noclip", "noclip_btn.png"); + m_settingsbar.addButton(fast_id, L"fast", "fast_btn.png"); + m_settingsbar.addButton(debug_id, L"debug", "debug_btn.png"); + m_settingsbar.addButton(camera_id, L"camera", "camera_btn.png"); + m_settingsbar.addButton(range_id, L"rangeview", "rangeview_btn.png"); + m_settingsbar.addButton(minimap_id, L"minimap", "minimap_btn.png"); + + // Chat is shown by default, so chat_hide_btn.png is shown first. + m_settingsbar.addToggleButton(toggle_chat_id, L"togglechat", + "chat_hide_btn.png", "chat_show_btn.png"); + + m_rarecontrolsbar.init(m_texturesource, "rare_controls.png", + rare_controls_starter_id, + v2s32(0.25 * button_size, + m_screensize.Y - ((RARE_CONTROLS_BAR_Y_OFFSET + 1.0) * button_size) + + (0.5 * button_size)), + v2s32(0.75 * button_size, + m_screensize.Y - (RARE_CONTROLS_BAR_Y_OFFSET * button_size) + + (0.5 * button_size)), + AHBB_Dir_Left_Right, 2.0); + + m_rarecontrolsbar.addButton(chat_id, L"Chat", "chat_btn.png"); + m_rarecontrolsbar.addButton(inventory_id, L"inv", "inventory_btn.png"); + m_rarecontrolsbar.addButton(drop_id, L"drop", "drop_btn.png"); +} + +touch_gui_button_id TouchScreenGUI::getButtonID(s32 x, s32 y) +{ + IGUIElement *rootguielement = m_guienv->getRootGUIElement(); + + if (rootguielement != nullptr) { + gui::IGUIElement *element = + rootguielement->getElementFromPoint(core::position2d<s32>(x, y)); + + if (element) + for (unsigned int i = 0; i < after_last_element_id; i++) + if (element == m_buttons[i].guibutton) + return (touch_gui_button_id) i; + } + + return after_last_element_id; +} + +touch_gui_button_id TouchScreenGUI::getButtonID(size_t eventID) +{ + for (unsigned int i = 0; i < after_last_element_id; i++) { + button_info *btn = &m_buttons[i]; + + auto id = std::find(btn->ids.begin(), btn->ids.end(), eventID); + + if (id != btn->ids.end()) + return (touch_gui_button_id) i; + } + + return after_last_element_id; +} + +bool TouchScreenGUI::isHUDButton(const SEvent &event) +{ + // check if hud item is pressed + for (auto &hud_rect : m_hud_rects) { + if (hud_rect.second.isPointInside(v2s32(event.TouchInput.X, + event.TouchInput.Y))) { + auto *translated = new SEvent(); + memset(translated, 0, sizeof(SEvent)); + translated->EventType = irr::EET_KEY_INPUT_EVENT; + translated->KeyInput.Key = (irr::EKEY_CODE) (KEY_KEY_1 + hud_rect.first); + translated->KeyInput.Control = false; + translated->KeyInput.Shift = false; + translated->KeyInput.PressedDown = true; + m_receiver->OnEvent(*translated); + m_hud_ids[event.TouchInput.ID] = translated->KeyInput.Key; + delete translated; + return true; + } + } + return false; +} + +void TouchScreenGUI::handleButtonEvent(touch_gui_button_id button, + size_t eventID, bool action) +{ + button_info *btn = &m_buttons[button]; + auto *translated = new SEvent(); + memset(translated, 0, sizeof(SEvent)); + translated->EventType = irr::EET_KEY_INPUT_EVENT; + translated->KeyInput.Key = btn->keycode; + translated->KeyInput.Control = false; + translated->KeyInput.Shift = false; + translated->KeyInput.Char = 0; + + // add this event + if (action) { + assert(std::find(btn->ids.begin(), btn->ids.end(), eventID) == btn->ids.end()); + + btn->ids.push_back(eventID); + + if (btn->ids.size() > 1) return; + + btn->repeatcounter = 0; + translated->KeyInput.PressedDown = true; + translated->KeyInput.Key = btn->keycode; + m_receiver->OnEvent(*translated); + } + + // remove event + if ((!action) || (btn->immediate_release)) { + auto pos = std::find(btn->ids.begin(), btn->ids.end(), eventID); + // has to be in touch list + assert(pos != btn->ids.end()); + btn->ids.erase(pos); + + if (!btn->ids.empty()) + return; + + translated->KeyInput.PressedDown = false; + btn->repeatcounter = -1; + m_receiver->OnEvent(*translated); + } + delete translated; +} + +void TouchScreenGUI::handleReleaseEvent(size_t evt_id) +{ + touch_gui_button_id button = getButtonID(evt_id); + + + if (button != after_last_element_id) { + // handle button events + handleButtonEvent(button, evt_id, false); + } else if (m_has_move_id && evt_id == m_move_id) { + // handle the point used for moving view + m_has_move_id = false; + + // if this pointer issued a mouse event issue symmetric release here + if (m_move_sent_as_mouse_event) { + auto *translated = new SEvent; + memset(translated, 0, sizeof(SEvent)); + translated->EventType = EET_MOUSE_INPUT_EVENT; + translated->MouseInput.X = m_move_downlocation.X; + translated->MouseInput.Y = m_move_downlocation.Y; + translated->MouseInput.Shift = false; + translated->MouseInput.Control = false; + translated->MouseInput.ButtonStates = 0; + translated->MouseInput.Event = EMIE_LMOUSE_LEFT_UP; + m_receiver->OnEvent(*translated); + delete translated; + } else { + // do double tap detection + doubleTapDetection(); + } + } + + // handle joystick + else if (m_has_joystick_id && evt_id == m_joystick_id) { + m_has_joystick_id = false; + + // reset joystick + for (unsigned int i = 0; i < 4; i++) + m_joystick_status[i] = false; + applyJoystickStatus(); + + m_joystick_btn_off->guibutton->setVisible(true); + m_joystick_btn_bg->guibutton->setVisible(false); + m_joystick_btn_center->guibutton->setVisible(false); + } else { + infostream + << "TouchScreenGUI::translateEvent released unknown button: " + << evt_id << std::endl; + } + + for (auto iter = m_known_ids.begin(); + iter != m_known_ids.end(); ++iter) { + if (iter->id == evt_id) { + m_known_ids.erase(iter); + break; + } + } +} + +void TouchScreenGUI::translateEvent(const SEvent &event) +{ + if (!m_visible) { + infostream + << "TouchScreenGUI::translateEvent got event but not visible!" + << std::endl; + return; + } + + if (event.EventType != EET_TOUCH_INPUT_EVENT) + return; + + if (event.TouchInput.Event == ETIE_PRESSED_DOWN) { + /* + * Add to own copy of event list... + * android would provide this information but Irrlicht guys don't + * wanna design a efficient interface + */ + id_status toadd{}; + toadd.id = event.TouchInput.ID; + toadd.X = event.TouchInput.X; + toadd.Y = event.TouchInput.Y; + m_known_ids.push_back(toadd); + + size_t eventID = event.TouchInput.ID; + + touch_gui_button_id button = + getButtonID(event.TouchInput.X, event.TouchInput.Y); + + // handle button events + if (button != after_last_element_id) { + handleButtonEvent(button, eventID, true); + m_settingsbar.deactivate(); + m_rarecontrolsbar.deactivate(); + } else if (isHUDButton(event)) { + m_settingsbar.deactivate(); + m_rarecontrolsbar.deactivate(); + // already handled in isHUDButton() + } else if (m_settingsbar.isButton(event)) { + m_rarecontrolsbar.deactivate(); + // already handled in isSettingsBarButton() + } else if (m_rarecontrolsbar.isButton(event)) { + m_settingsbar.deactivate(); + // already handled in isSettingsBarButton() + } else { + // handle non button events + m_settingsbar.deactivate(); + m_rarecontrolsbar.deactivate(); + + s32 dxj = event.TouchInput.X - button_size * 5.0f / 2.0f; + s32 dyj = event.TouchInput.Y - m_screensize.Y + button_size * 5.0f / 2.0f; + + /* Select joystick when left 1/3 of screen dragged or + * when joystick tapped (fixed joystick position) + */ + if ((m_fixed_joystick && dxj * dxj + dyj * dyj <= button_size * button_size * 1.5 * 1.5) || + (!m_fixed_joystick && event.TouchInput.X < m_screensize.X / 3.0f)) { + // If we don't already have a starting point for joystick make this the one. + if (!m_has_joystick_id) { + m_has_joystick_id = true; + m_joystick_id = event.TouchInput.ID; + m_joystick_has_really_moved = false; + + m_joystick_btn_off->guibutton->setVisible(false); + m_joystick_btn_bg->guibutton->setVisible(true); + m_joystick_btn_center->guibutton->setVisible(true); + + // If it's a fixed joystick, don't move the joystick "button". + if (!m_fixed_joystick) + m_joystick_btn_bg->guibutton->setRelativePosition(v2s32( + event.TouchInput.X - button_size * 3.0f / 2.0f, + event.TouchInput.Y - button_size * 3.0f / 2.0f)); + + m_joystick_btn_center->guibutton->setRelativePosition(v2s32( + event.TouchInput.X - button_size / 2.0f, + event.TouchInput.Y - button_size / 2.0f)); + } + } else { + // If we don't already have a moving point make this the moving one. + if (!m_has_move_id) { + m_has_move_id = true; + m_move_id = event.TouchInput.ID; + m_move_has_really_moved = false; + m_move_downtime = porting::getTimeMs(); + m_move_downlocation = v2s32(event.TouchInput.X, event.TouchInput.Y); + m_move_sent_as_mouse_event = false; + } + } + } + + m_pointerpos[event.TouchInput.ID] = v2s32(event.TouchInput.X, event.TouchInput.Y); + } + else if (event.TouchInput.Event == ETIE_LEFT_UP) { + verbosestream + << "Up event for pointerid: " << event.TouchInput.ID << std::endl; + handleReleaseEvent(event.TouchInput.ID); + } else { + assert(event.TouchInput.Event == ETIE_MOVED); + + if (m_pointerpos[event.TouchInput.ID] == + v2s32(event.TouchInput.X, event.TouchInput.Y)) + return; + + if (m_has_move_id) { + if ((event.TouchInput.ID == m_move_id) && + (!m_move_sent_as_mouse_event)) { + + double distance = sqrt( + (m_pointerpos[event.TouchInput.ID].X - event.TouchInput.X) * + (m_pointerpos[event.TouchInput.ID].X - event.TouchInput.X) + + (m_pointerpos[event.TouchInput.ID].Y - event.TouchInput.Y) * + (m_pointerpos[event.TouchInput.ID].Y - event.TouchInput.Y)); + + if ((distance > m_touchscreen_threshold) || + (m_move_has_really_moved)) { + m_move_has_really_moved = true; + s32 X = event.TouchInput.X; + s32 Y = event.TouchInput.Y; + + // update camera_yaw and camera_pitch + s32 dx = X - m_pointerpos[event.TouchInput.ID].X; + s32 dy = Y - m_pointerpos[event.TouchInput.ID].Y; + + // adapt to similar behaviour as pc screen + const double d = g_settings->getFloat("mouse_sensitivity", 0.001f, 10.0f) * 3.0f; + + m_camera_yaw_change -= dx * d; + m_camera_pitch = MYMIN(MYMAX(m_camera_pitch + (dy * d), -180), 180); + + // update shootline + m_shootline = m_device + ->getSceneManager() + ->getSceneCollisionManager() + ->getRayFromScreenCoordinates(v2s32(X, Y)); + m_pointerpos[event.TouchInput.ID] = v2s32(X, Y); + } + } else if ((event.TouchInput.ID == m_move_id) && + (m_move_sent_as_mouse_event)) { + m_shootline = m_device + ->getSceneManager() + ->getSceneCollisionManager() + ->getRayFromScreenCoordinates( + v2s32(event.TouchInput.X, event.TouchInput.Y)); + } + } + + if (m_has_joystick_id && event.TouchInput.ID == m_joystick_id) { + s32 X = event.TouchInput.X; + s32 Y = event.TouchInput.Y; + + s32 dx = X - m_pointerpos[event.TouchInput.ID].X; + s32 dy = Y - m_pointerpos[event.TouchInput.ID].Y; + if (m_fixed_joystick) { + dx = X - button_size * 5 / 2; + dy = Y - m_screensize.Y + button_size * 5 / 2; + } + + double distance_sq = dx * dx + dy * dy; + + s32 dxj = event.TouchInput.X - button_size * 5.0f / 2.0f; + s32 dyj = event.TouchInput.Y - m_screensize.Y + button_size * 5.0f / 2.0f; + bool inside_joystick = (dxj * dxj + dyj * dyj <= button_size * button_size * 1.5 * 1.5); + + if (m_joystick_has_really_moved || inside_joystick || + (!m_fixed_joystick && + distance_sq > m_touchscreen_threshold * m_touchscreen_threshold)) { + m_joystick_has_really_moved = true; + double distance = sqrt(distance_sq); + + // angle in degrees + double angle = acos(dx / distance) * 180 / M_PI; + if (dy < 0) + angle *= -1; + // rotate to make comparing easier + angle = fmod(angle + 180 + 22.5, 360); + + // reset state before applying + for (bool & joystick_status : m_joystick_status) + joystick_status = false; + + if (distance <= m_touchscreen_threshold) { + // do nothing + } else if (angle < 45) + m_joystick_status[j_left] = true; + else if (angle < 90) { + m_joystick_status[j_forward] = true; + m_joystick_status[j_left] = true; + } else if (angle < 135) + m_joystick_status[j_forward] = true; + else if (angle < 180) { + m_joystick_status[j_forward] = true; + m_joystick_status[j_right] = true; + } else if (angle < 225) + m_joystick_status[j_right] = true; + else if (angle < 270) { + m_joystick_status[j_backward] = true; + m_joystick_status[j_right] = true; + } else if (angle < 315) + m_joystick_status[j_backward] = true; + else if (angle <= 360) { + m_joystick_status[j_backward] = true; + m_joystick_status[j_left] = true; + } + + if (distance > button_size) { + m_joystick_status[j_aux1] = true; + // move joystick "button" + s32 ndx = button_size * dx / distance - button_size / 2.0f; + s32 ndy = button_size * dy / distance - button_size / 2.0f; + if (m_fixed_joystick) { + m_joystick_btn_center->guibutton->setRelativePosition(v2s32( + button_size * 5 / 2 + ndx, + m_screensize.Y - button_size * 5 / 2 + ndy)); + } else { + m_joystick_btn_center->guibutton->setRelativePosition(v2s32( + m_pointerpos[event.TouchInput.ID].X + ndx, + m_pointerpos[event.TouchInput.ID].Y + ndy)); + } + } else { + m_joystick_btn_center->guibutton->setRelativePosition( + v2s32(X - button_size / 2, Y - button_size / 2)); + } + } + } + + if (!m_has_move_id && !m_has_joystick_id) + handleChangedButton(event); + } +} + +void TouchScreenGUI::handleChangedButton(const SEvent &event) +{ + for (unsigned int i = 0; i < after_last_element_id; i++) { + if (m_buttons[i].ids.empty()) + continue; + + for (auto iter = m_buttons[i].ids.begin(); + iter != m_buttons[i].ids.end(); ++iter) { + if (event.TouchInput.ID == *iter) { + int current_button_id = + getButtonID(event.TouchInput.X, event.TouchInput.Y); + + if (current_button_id == i) + continue; + + // remove old button + handleButtonEvent((touch_gui_button_id) i, *iter, false); + + if (current_button_id == after_last_element_id) + return; + + handleButtonEvent((touch_gui_button_id) current_button_id, *iter, true); + return; + } + } + } + + int current_button_id = getButtonID(event.TouchInput.X, event.TouchInput.Y); + + if (current_button_id == after_last_element_id) + return; + + button_info *btn = &m_buttons[current_button_id]; + if (std::find(btn->ids.begin(), btn->ids.end(), event.TouchInput.ID) + == btn->ids.end()) + handleButtonEvent((touch_gui_button_id) current_button_id, + event.TouchInput.ID, true); +} + +bool TouchScreenGUI::doubleTapDetection() +{ + m_key_events[0].down_time = m_key_events[1].down_time; + m_key_events[0].x = m_key_events[1].x; + m_key_events[0].y = m_key_events[1].y; + m_key_events[1].down_time = m_move_downtime; + m_key_events[1].x = m_move_downlocation.X; + m_key_events[1].y = m_move_downlocation.Y; + + u64 delta = porting::getDeltaMs(m_key_events[0].down_time, porting::getTimeMs()); + if (delta > 400) + return false; + + double distance = sqrt( + (m_key_events[0].x - m_key_events[1].x) * + (m_key_events[0].x - m_key_events[1].x) + + (m_key_events[0].y - m_key_events[1].y) * + (m_key_events[0].y - m_key_events[1].y)); + + if (distance > (20 + m_touchscreen_threshold)) + return false; + + auto *translated = new SEvent(); + memset(translated, 0, sizeof(SEvent)); + translated->EventType = EET_MOUSE_INPUT_EVENT; + translated->MouseInput.X = m_key_events[0].x; + translated->MouseInput.Y = m_key_events[0].y; + translated->MouseInput.Shift = false; + translated->MouseInput.Control = false; + translated->MouseInput.ButtonStates = EMBSM_RIGHT; + + // update shootline + m_shootline = m_device + ->getSceneManager() + ->getSceneCollisionManager() + ->getRayFromScreenCoordinates(v2s32(m_key_events[0].x, m_key_events[0].y)); + + translated->MouseInput.Event = EMIE_RMOUSE_PRESSED_DOWN; + verbosestream << "TouchScreenGUI::translateEvent right click press" << std::endl; + m_receiver->OnEvent(*translated); + + translated->MouseInput.ButtonStates = 0; + translated->MouseInput.Event = EMIE_RMOUSE_LEFT_UP; + verbosestream << "TouchScreenGUI::translateEvent right click release" << std::endl; + m_receiver->OnEvent(*translated); + delete translated; + return true; +} + +void TouchScreenGUI::applyJoystickStatus() +{ + for (unsigned int i = 0; i < 5; i++) { + if (i == 4 && !m_joystick_triggers_aux1) + continue; + + SEvent translated{}; + translated.EventType = irr::EET_KEY_INPUT_EVENT; + translated.KeyInput.Key = id2keycode(m_joystick_names[i]); + translated.KeyInput.PressedDown = false; + m_receiver->OnEvent(translated); + + if (m_joystick_status[i]) { + translated.KeyInput.PressedDown = true; + m_receiver->OnEvent(translated); + } + } +} + +TouchScreenGUI::~TouchScreenGUI() +{ + for (auto &button : m_buttons) { + if (button.guibutton) { + button.guibutton->drop(); + button.guibutton = nullptr; + } + } + + if (m_joystick_btn_off->guibutton) { + m_joystick_btn_off->guibutton->drop(); + m_joystick_btn_off->guibutton = nullptr; + } + + if (m_joystick_btn_bg->guibutton) { + m_joystick_btn_bg->guibutton->drop(); + m_joystick_btn_bg->guibutton = nullptr; + } + + if (m_joystick_btn_center->guibutton) { + m_joystick_btn_center->guibutton->drop(); + m_joystick_btn_center->guibutton = nullptr; + } +} + +void TouchScreenGUI::step(float dtime) +{ + // simulate keyboard repeats + for (auto &button : m_buttons) { + if (!button.ids.empty()) { + button.repeatcounter += dtime; + + // in case we're moving around digging does not happen + if (m_has_move_id) + m_move_has_really_moved = true; + + if (button.repeatcounter < button.repeatdelay) + continue; + + button.repeatcounter = 0; + SEvent translated; + memset(&translated, 0, sizeof(SEvent)); + translated.EventType = irr::EET_KEY_INPUT_EVENT; + translated.KeyInput.Key = button.keycode; + translated.KeyInput.PressedDown = false; + m_receiver->OnEvent(translated); + + translated.KeyInput.PressedDown = true; + m_receiver->OnEvent(translated); + } + } + + // joystick + for (unsigned int i = 0; i < 4; i++) { + if (m_joystick_status[i]) { + applyJoystickStatus(); + break; + } + } + + // if a new placed pointer isn't moved for some time start digging + if (m_has_move_id && + (!m_move_has_really_moved) && + (!m_move_sent_as_mouse_event)) { + + u64 delta = porting::getDeltaMs(m_move_downtime, porting::getTimeMs()); + + if (delta > MIN_DIG_TIME_MS) { + m_shootline = m_device + ->getSceneManager() + ->getSceneCollisionManager() + ->getRayFromScreenCoordinates( + v2s32(m_move_downlocation.X,m_move_downlocation.Y)); + + SEvent translated; + memset(&translated, 0, sizeof(SEvent)); + translated.EventType = EET_MOUSE_INPUT_EVENT; + translated.MouseInput.X = m_move_downlocation.X; + translated.MouseInput.Y = m_move_downlocation.Y; + translated.MouseInput.Shift = false; + translated.MouseInput.Control = false; + translated.MouseInput.ButtonStates = EMBSM_LEFT; + translated.MouseInput.Event = EMIE_LMOUSE_PRESSED_DOWN; + verbosestream << "TouchScreenGUI::step left click press" << std::endl; + m_receiver->OnEvent(translated); + m_move_sent_as_mouse_event = true; + } + } + + m_settingsbar.step(dtime); + m_rarecontrolsbar.step(dtime); +} + +void TouchScreenGUI::resetHud() +{ + m_hud_rects.clear(); +} + +void TouchScreenGUI::registerHudItem(int index, const rect<s32> &rect) +{ + m_hud_rects[index] = rect; +} + +void TouchScreenGUI::Toggle(bool visible) +{ + m_visible = visible; + for (auto &button : m_buttons) { + if (button.guibutton) + button.guibutton->setVisible(visible); + } + + if (m_joystick_btn_off->guibutton) + m_joystick_btn_off->guibutton->setVisible(visible); + + // clear all active buttons + if (!visible) { + while (!m_known_ids.empty()) + handleReleaseEvent(m_known_ids.begin()->id); + + m_settingsbar.hide(); + m_rarecontrolsbar.hide(); + } else { + m_settingsbar.show(); + m_rarecontrolsbar.show(); + } +} + +void TouchScreenGUI::hide() +{ + if (!m_visible) + return; + + Toggle(false); +} + +void TouchScreenGUI::show() +{ + if (m_visible) + return; + + Toggle(true); +} diff --git a/src/gui/touchscreengui.h b/src/gui/touchscreengui.h new file mode 100644 index 0000000..6b36c0d --- /dev/null +++ b/src/gui/touchscreengui.h @@ -0,0 +1,314 @@ +/* +Copyright (C) 2014 sapier + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include <IEventReceiver.h> +#include <IGUIButton.h> +#include <IGUIEnvironment.h> +#include <IrrlichtDevice.h> + +#include <map> +#include <vector> + +#include "client/tile.h" +#include "client/game.h" + +using namespace irr; +using namespace irr::core; +using namespace irr::gui; + +typedef enum +{ + jump_id = 0, + crunch_id, + zoom_id, + aux1_id, + after_last_element_id, + settings_starter_id, + rare_controls_starter_id, + fly_id, + noclip_id, + fast_id, + debug_id, + camera_id, + range_id, + minimap_id, + toggle_chat_id, + chat_id, + inventory_id, + drop_id, + forward_id, + backward_id, + left_id, + right_id, + joystick_off_id, + joystick_bg_id, + joystick_center_id +} touch_gui_button_id; + +typedef enum +{ + j_forward = 0, + j_backward, + j_left, + j_right, + j_aux1 +} touch_gui_joystick_move_id; + +typedef enum +{ + AHBB_Dir_Top_Bottom, + AHBB_Dir_Bottom_Top, + AHBB_Dir_Left_Right, + AHBB_Dir_Right_Left +} autohide_button_bar_dir; + +#define MIN_DIG_TIME_MS 500 +#define BUTTON_REPEAT_DELAY 0.2f +#define SETTINGS_BAR_Y_OFFSET 5 +#define RARE_CONTROLS_BAR_Y_OFFSET 5 + +// Very slow button repeat frequency +#define SLOW_BUTTON_REPEAT 1.0f + +extern const char **button_imagenames; +extern const char **joystick_imagenames; + +struct button_info +{ + float repeatcounter; + float repeatdelay; + irr::EKEY_CODE keycode; + std::vector<size_t> ids; + IGUIButton *guibutton = nullptr; + bool immediate_release; + + // 0: false, 1: (true) first texture, 2: (true) second texture + int togglable = 0; + std::vector<const char *> textures; +}; + +class AutoHideButtonBar +{ +public: + AutoHideButtonBar(IrrlichtDevice *device, IEventReceiver *receiver); + + void init(ISimpleTextureSource *tsrc, const char *starter_img, int button_id, + const v2s32 &UpperLeft, const v2s32 &LowerRight, + autohide_button_bar_dir dir, float timeout); + + ~AutoHideButtonBar(); + + // add button to be shown + void addButton(touch_gui_button_id id, const wchar_t *caption, + const char *btn_image); + + // add toggle button to be shown + void addToggleButton(touch_gui_button_id id, const wchar_t *caption, + const char *btn_image_1, const char *btn_image_2); + + // detect settings bar button events + bool isButton(const SEvent &event); + + // step handler + void step(float dtime); + + // deactivate button bar + void deactivate(); + + // hide the whole buttonbar + void hide(); + + // unhide the buttonbar + void show(); + +private: + ISimpleTextureSource *m_texturesource = nullptr; + irr::video::IVideoDriver *m_driver; + IGUIEnvironment *m_guienv; + IEventReceiver *m_receiver; + button_info m_starter; + std::vector<button_info *> m_buttons; + + v2s32 m_upper_left; + v2s32 m_lower_right; + + // show settings bar + bool m_active = false; + + bool m_visible = true; + + // settings bar timeout + float m_timeout = 0.0f; + float m_timeout_value = 3.0f; + bool m_initialized = false; + autohide_button_bar_dir m_dir = AHBB_Dir_Right_Left; +}; + +class TouchScreenGUI +{ +public: + TouchScreenGUI(IrrlichtDevice *device, IEventReceiver *receiver); + ~TouchScreenGUI(); + + void translateEvent(const SEvent &event); + + void init(ISimpleTextureSource *tsrc); + + double getYawChange() + { + double res = m_camera_yaw_change; + m_camera_yaw_change = 0; + return res; + } + + double getPitch() { return m_camera_pitch; } + + /* + * Returns a line which describes what the player is pointing at. + * The starting point and looking direction are significant, + * the line should be scaled to match its length to the actual distance + * the player can reach. + * The line starts at the camera and ends on the camera's far plane. + * The coordinates do not contain the camera offset. + */ + line3d<f32> getShootline() { return m_shootline; } + + void step(float dtime); + void resetHud(); + void registerHudItem(int index, const rect<s32> &rect); + void Toggle(bool visible); + + void hide(); + void show(); + +private: + IrrlichtDevice *m_device; + IGUIEnvironment *m_guienv; + IEventReceiver *m_receiver; + ISimpleTextureSource *m_texturesource; + v2u32 m_screensize; + s32 button_size; + double m_touchscreen_threshold; + std::map<int, rect<s32>> m_hud_rects; + std::map<size_t, irr::EKEY_CODE> m_hud_ids; + bool m_visible; // is the gui visible + + // value in degree + double m_camera_yaw_change = 0.0; + double m_camera_pitch = 0.0; + + // forward, backward, left, right + touch_gui_button_id m_joystick_names[5] = { + forward_id, backward_id, left_id, right_id, aux1_id}; + bool m_joystick_status[5] = {false, false, false, false, false}; + + /* + * A line starting at the camera and pointing towards the + * selected object. + * The line ends on the camera's far plane. + * The coordinates do not contain the camera offset. + */ + line3d<f32> m_shootline; + + bool m_has_move_id = false; + size_t m_move_id; + bool m_move_has_really_moved = false; + u64 m_move_downtime = 0; + bool m_move_sent_as_mouse_event = false; + v2s32 m_move_downlocation = v2s32(-10000, -10000); + + bool m_has_joystick_id = false; + size_t m_joystick_id; + bool m_joystick_has_really_moved = false; + bool m_fixed_joystick = false; + bool m_joystick_triggers_aux1 = false; + button_info *m_joystick_btn_off = nullptr; + button_info *m_joystick_btn_bg = nullptr; + button_info *m_joystick_btn_center = nullptr; + + button_info m_buttons[after_last_element_id]; + + // gui button detection + touch_gui_button_id getButtonID(s32 x, s32 y); + + // gui button by eventID + touch_gui_button_id getButtonID(size_t eventID); + + // check if a button has changed + void handleChangedButton(const SEvent &event); + + // initialize a button + void initButton(touch_gui_button_id id, const rect<s32> &button_rect, + const std::wstring &caption, bool immediate_release, + float repeat_delay = BUTTON_REPEAT_DELAY); + + // initialize a joystick button + button_info *initJoystickButton(touch_gui_button_id id, + const rect<s32> &button_rect, int texture_id, + bool visible = true); + + struct id_status + { + size_t id; + int X; + int Y; + }; + + // vector to store known ids and their initial touch positions + std::vector<id_status> m_known_ids; + + // handle a button event + void handleButtonEvent(touch_gui_button_id bID, size_t eventID, bool action); + + // handle pressed hud buttons + bool isHUDButton(const SEvent &event); + + // handle double taps + bool doubleTapDetection(); + + // handle release event + void handleReleaseEvent(size_t evt_id); + + // apply joystick status + void applyJoystickStatus(); + + // double-click detection variables + struct key_event + { + u64 down_time; + s32 x; + s32 y; + }; + + // array for saving last known position of a pointer + std::map<size_t, v2s32> m_pointerpos; + + // array for double tap detection + key_event m_key_events[2]; + + // settings bar + AutoHideButtonBar m_settingsbar; + + // rare controls bar + AutoHideButtonBar m_rarecontrolsbar; +}; + +extern TouchScreenGUI *g_touchscreengui; diff --git a/src/httpfetch.cpp b/src/httpfetch.cpp new file mode 100644 index 0000000..16f0791 --- /dev/null +++ b/src/httpfetch.cpp @@ -0,0 +1,848 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "httpfetch.h" +#include "porting.h" // for sleep_ms(), get_sysinfo(), secure_rand_fill_buf() +#include <iostream> +#include <sstream> +#include <list> +#include <unordered_map> +#include <cerrno> +#include <mutex> +#include "network/socket.h" // for select() +#include "threading/event.h" +#include "config.h" +#include "exceptions.h" +#include "debug.h" +#include "log.h" +#include "util/container.h" +#include "util/thread.h" +#include "version.h" +#include "settings.h" +#include "noise.h" + +static std::mutex g_httpfetch_mutex; +static std::unordered_map<u64, std::queue<HTTPFetchResult>> + g_httpfetch_results; +static PcgRandom g_callerid_randomness; + +HTTPFetchRequest::HTTPFetchRequest() : + timeout(g_settings->getS32("curl_timeout")), + connect_timeout(10 * 1000), + useragent(std::string(PROJECT_NAME_C "/") + g_version_hash + " (" + porting::get_sysinfo() + ")") +{ +} + + +static void httpfetch_deliver_result(const HTTPFetchResult &fetch_result) +{ + u64 caller = fetch_result.caller; + if (caller != HTTPFETCH_DISCARD) { + MutexAutoLock lock(g_httpfetch_mutex); + g_httpfetch_results[caller].emplace(fetch_result); + } +} + +static void httpfetch_request_clear(u64 caller); + +u64 httpfetch_caller_alloc() +{ + MutexAutoLock lock(g_httpfetch_mutex); + + // Check each caller ID except reserved ones + for (u64 caller = HTTPFETCH_CID_START; caller != 0; ++caller) { + auto it = g_httpfetch_results.find(caller); + if (it == g_httpfetch_results.end()) { + verbosestream << "httpfetch_caller_alloc: allocating " + << caller << std::endl; + // Access element to create it + g_httpfetch_results[caller]; + return caller; + } + } + + FATAL_ERROR("httpfetch_caller_alloc: ran out of caller IDs"); +} + +u64 httpfetch_caller_alloc_secure() +{ + MutexAutoLock lock(g_httpfetch_mutex); + + // Generate random caller IDs and make sure they're not + // already used or reserved. + // Give up after 100 tries to prevent infinite loop + size_t tries = 100; + u64 caller; + + do { + caller = (((u64) g_callerid_randomness.next()) << 32) | + g_callerid_randomness.next(); + + if (--tries < 1) { + FATAL_ERROR("httpfetch_caller_alloc_secure: ran out of caller IDs"); + return HTTPFETCH_DISCARD; + } + } while (caller >= HTTPFETCH_CID_START && + g_httpfetch_results.find(caller) != g_httpfetch_results.end()); + + verbosestream << "httpfetch_caller_alloc_secure: allocating " + << caller << std::endl; + + // Access element to create it + g_httpfetch_results[caller]; + return caller; +} + +void httpfetch_caller_free(u64 caller) +{ + verbosestream<<"httpfetch_caller_free: freeing " + <<caller<<std::endl; + + httpfetch_request_clear(caller); + if (caller != HTTPFETCH_DISCARD) { + MutexAutoLock lock(g_httpfetch_mutex); + g_httpfetch_results.erase(caller); + } +} + +bool httpfetch_async_get(u64 caller, HTTPFetchResult &fetch_result) +{ + MutexAutoLock lock(g_httpfetch_mutex); + + // Check that caller exists + auto it = g_httpfetch_results.find(caller); + if (it == g_httpfetch_results.end()) + return false; + + // Check that result queue is nonempty + std::queue<HTTPFetchResult> &caller_results = it->second; + if (caller_results.empty()) + return false; + + // Pop first result + fetch_result = std::move(caller_results.front()); + caller_results.pop(); + return true; +} + +#if USE_CURL +#include <curl/curl.h> + +/* + USE_CURL is on: use cURL based httpfetch implementation +*/ + +static size_t httpfetch_writefunction( + char *ptr, size_t size, size_t nmemb, void *userdata) +{ + std::ostringstream *stream = (std::ostringstream*)userdata; + size_t count = size * nmemb; + stream->write(ptr, count); + return count; +} + +static size_t httpfetch_discardfunction( + char *ptr, size_t size, size_t nmemb, void *userdata) +{ + return size * nmemb; +} + +class CurlHandlePool +{ + std::list<CURL*> handles; + +public: + CurlHandlePool() = default; + + ~CurlHandlePool() + { + for (std::list<CURL*>::iterator it = handles.begin(); + it != handles.end(); ++it) { + curl_easy_cleanup(*it); + } + } + CURL * alloc() + { + CURL *curl; + if (handles.empty()) { + curl = curl_easy_init(); + if (curl == NULL) { + errorstream<<"curl_easy_init returned NULL"<<std::endl; + } + } + else { + curl = handles.front(); + handles.pop_front(); + } + return curl; + } + void free(CURL *handle) + { + if (handle) + handles.push_back(handle); + } +}; + +class HTTPFetchOngoing +{ +public: + HTTPFetchOngoing(const HTTPFetchRequest &request, CurlHandlePool *pool); + ~HTTPFetchOngoing(); + + CURLcode start(CURLM *multi); + const HTTPFetchResult * complete(CURLcode res); + + const HTTPFetchRequest &getRequest() const { return request; }; + const CURL *getEasyHandle() const { return curl; }; + +private: + CurlHandlePool *pool; + CURL *curl; + CURLM *multi; + HTTPFetchRequest request; + HTTPFetchResult result; + std::ostringstream oss; + struct curl_slist *http_header; + curl_httppost *post; +}; + + +HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_, + CurlHandlePool *pool_): + pool(pool_), + curl(NULL), + multi(NULL), + request(request_), + result(request_), + oss(std::ios::binary), + http_header(NULL), + post(NULL) +{ + curl = pool->alloc(); + if (curl == NULL) { + return; + } + + // Set static cURL options + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 3); + curl_easy_setopt(curl, CURLOPT_ENCODING, "gzip"); + + std::string bind_address = g_settings->get("bind_address"); + if (!bind_address.empty()) { + curl_easy_setopt(curl, CURLOPT_INTERFACE, bind_address.c_str()); + } + + if (!g_settings->getBool("enable_ipv6")) { + curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + } + +#if LIBCURL_VERSION_NUM >= 0x071304 + // Restrict protocols so that curl vulnerabilities in + // other protocols don't affect us. + // These settings were introduced in curl 7.19.4. + long protocols = + CURLPROTO_HTTP | + CURLPROTO_HTTPS | + CURLPROTO_FTP | + CURLPROTO_FTPS; + curl_easy_setopt(curl, CURLOPT_PROTOCOLS, protocols); + curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, protocols); +#endif + + // Set cURL options based on HTTPFetchRequest + curl_easy_setopt(curl, CURLOPT_URL, + request.url.c_str()); + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, + request.timeout); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, + request.connect_timeout); + + if (!request.useragent.empty()) + curl_easy_setopt(curl, CURLOPT_USERAGENT, request.useragent.c_str()); + + // Set up a write callback that writes to the + // ostringstream ongoing->oss, unless the data + // is to be discarded + if (request.caller == HTTPFETCH_DISCARD) { + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, + httpfetch_discardfunction); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL); + } else { + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, + httpfetch_writefunction); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &oss); + } + + // Set data from fields or raw_data + if (request.multipart) { + curl_httppost *last = NULL; + for (StringMap::iterator it = request.fields.begin(); + it != request.fields.end(); ++it) { + curl_formadd(&post, &last, + CURLFORM_NAMELENGTH, it->first.size(), + CURLFORM_PTRNAME, it->first.c_str(), + CURLFORM_CONTENTSLENGTH, it->second.size(), + CURLFORM_PTRCONTENTS, it->second.c_str(), + CURLFORM_END); + } + curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); + // request.post_fields must now *never* be + // modified until CURLOPT_HTTPPOST is cleared + } else { + switch (request.method) { + case HTTP_GET: + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); + break; + case HTTP_POST: + curl_easy_setopt(curl, CURLOPT_POST, 1); + break; + case HTTP_PUT: + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); + break; + case HTTP_DELETE: + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); + break; + } + if (request.method != HTTP_GET) { + if (!request.raw_data.empty()) { + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, + request.raw_data.size()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, + request.raw_data.c_str()); + } else if (!request.fields.empty()) { + std::string str; + for (auto &field : request.fields) { + if (!str.empty()) + str += "&"; + str += urlencode(field.first); + str += "="; + str += urlencode(field.second); + } + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, + str.size()); + curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, + str.c_str()); + } + } + } + // Set additional HTTP headers + for (const std::string &extra_header : request.extra_headers) { + http_header = curl_slist_append(http_header, extra_header.c_str()); + } + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_header); + + if (!g_settings->getBool("curl_verify_cert")) { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); + } +} + +CURLcode HTTPFetchOngoing::start(CURLM *multi_) +{ + if (!curl) + return CURLE_FAILED_INIT; + + if (!multi_) { + // Easy interface (sync) + return curl_easy_perform(curl); + } + + // Multi interface (async) + CURLMcode mres = curl_multi_add_handle(multi_, curl); + if (mres != CURLM_OK) { + errorstream << "curl_multi_add_handle" + << " returned error code " << mres + << std::endl; + return CURLE_FAILED_INIT; + } + multi = multi_; // store for curl_multi_remove_handle + return CURLE_OK; +} + +const HTTPFetchResult * HTTPFetchOngoing::complete(CURLcode res) +{ + result.succeeded = (res == CURLE_OK); + result.timeout = (res == CURLE_OPERATION_TIMEDOUT); + result.data = oss.str(); + + // Get HTTP/FTP response code + result.response_code = 0; + if (curl && (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, + &result.response_code) != CURLE_OK)) { + // We failed to get a return code, make sure it is still 0 + result.response_code = 0; + } + + if (res != CURLE_OK) { + errorstream << "HTTPFetch for " << request.url << " failed (" + << curl_easy_strerror(res) << ")" << std::endl; + } else if (result.response_code >= 400) { + errorstream << "HTTPFetch for " << request.url + << " returned response code " << result.response_code + << std::endl; + if (result.caller == HTTPFETCH_PRINT_ERR && !result.data.empty()) { + errorstream << "Response body:" << std::endl; + safe_print_string(errorstream, result.data); + errorstream << std::endl; + } + } + + return &result; +} + +HTTPFetchOngoing::~HTTPFetchOngoing() +{ + if (multi) { + CURLMcode mres = curl_multi_remove_handle(multi, curl); + if (mres != CURLM_OK) { + errorstream << "curl_multi_remove_handle" + << " returned error code " << mres + << std::endl; + } + } + + // Set safe options for the reusable cURL handle + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, + httpfetch_discardfunction); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, NULL); + if (http_header) { + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL); + curl_slist_free_all(http_header); + } + if (post) { + curl_easy_setopt(curl, CURLOPT_HTTPPOST, NULL); + curl_formfree(post); + } + + // Store the cURL handle for reuse + pool->free(curl); +} + + +class CurlFetchThread : public Thread +{ +protected: + enum RequestType { + RT_FETCH, + RT_CLEAR, + RT_WAKEUP, + }; + + struct Request { + RequestType type; + HTTPFetchRequest fetch_request; + Event *event; + }; + + CURLM *m_multi; + MutexedQueue<Request> m_requests; + size_t m_parallel_limit; + + // Variables exclusively used within thread + std::vector<HTTPFetchOngoing*> m_all_ongoing; + std::list<HTTPFetchRequest> m_queued_fetches; + +public: + CurlFetchThread(int parallel_limit) : + Thread("CurlFetch") + { + if (parallel_limit >= 1) + m_parallel_limit = parallel_limit; + else + m_parallel_limit = 1; + } + + void requestFetch(const HTTPFetchRequest &fetch_request) + { + Request req; + req.type = RT_FETCH; + req.fetch_request = fetch_request; + req.event = NULL; + m_requests.push_back(req); + } + + void requestClear(u64 caller, Event *event) + { + Request req; + req.type = RT_CLEAR; + req.fetch_request.caller = caller; + req.event = event; + m_requests.push_back(req); + } + + void requestWakeUp() + { + Request req; + req.type = RT_WAKEUP; + req.event = NULL; + m_requests.push_back(req); + } + +protected: + // Handle a request from some other thread + // E.g. new fetch; clear fetches for one caller; wake up + void processRequest(const Request &req) + { + if (req.type == RT_FETCH) { + // New fetch, queue until there are less + // than m_parallel_limit ongoing fetches + m_queued_fetches.push_back(req.fetch_request); + + // see processQueued() for what happens next + + } + else if (req.type == RT_CLEAR) { + u64 caller = req.fetch_request.caller; + + // Abort all ongoing fetches for the caller + for (std::vector<HTTPFetchOngoing*>::iterator + it = m_all_ongoing.begin(); + it != m_all_ongoing.end();) { + if ((*it)->getRequest().caller == caller) { + delete (*it); + it = m_all_ongoing.erase(it); + } else { + ++it; + } + } + + // Also abort all queued fetches for the caller + for (std::list<HTTPFetchRequest>::iterator + it = m_queued_fetches.begin(); + it != m_queued_fetches.end();) { + if ((*it).caller == caller) + it = m_queued_fetches.erase(it); + else + ++it; + } + } + else if (req.type == RT_WAKEUP) { + // Wakeup: Nothing to do, thread is awake at this point + } + + if (req.event != NULL) + req.event->signal(); + } + + // Start new ongoing fetches if m_parallel_limit allows + void processQueued(CurlHandlePool *pool) + { + while (m_all_ongoing.size() < m_parallel_limit && + !m_queued_fetches.empty()) { + HTTPFetchRequest request = m_queued_fetches.front(); + m_queued_fetches.pop_front(); + + // Create ongoing fetch data and make a cURL handle + // Set cURL options based on HTTPFetchRequest + HTTPFetchOngoing *ongoing = + new HTTPFetchOngoing(request, pool); + + // Initiate the connection (curl_multi_add_handle) + CURLcode res = ongoing->start(m_multi); + if (res == CURLE_OK) { + m_all_ongoing.push_back(ongoing); + } + else { + httpfetch_deliver_result(*ongoing->complete(res)); + delete ongoing; + } + } + } + + // Process CURLMsg (indicates completion of a fetch) + void processCurlMessage(CURLMsg *msg) + { + // Determine which ongoing fetch the message pertains to + size_t i = 0; + bool found = false; + for (i = 0; i < m_all_ongoing.size(); ++i) { + if (m_all_ongoing[i]->getEasyHandle() == msg->easy_handle) { + found = true; + break; + } + } + if (msg->msg == CURLMSG_DONE && found) { + // m_all_ongoing[i] succeeded or failed. + HTTPFetchOngoing *ongoing = m_all_ongoing[i]; + httpfetch_deliver_result(*ongoing->complete(msg->data.result)); + delete ongoing; + m_all_ongoing.erase(m_all_ongoing.begin() + i); + } + } + + // Wait for a request from another thread, or timeout elapses + void waitForRequest(long timeout) + { + if (m_queued_fetches.empty()) { + try { + Request req = m_requests.pop_front(timeout); + processRequest(req); + } + catch (ItemNotFoundException &e) {} + } + } + + // Wait until some IO happens, or timeout elapses + void waitForIO(long timeout) + { + fd_set read_fd_set; + fd_set write_fd_set; + fd_set exc_fd_set; + int max_fd; + long select_timeout = -1; + struct timeval select_tv; + CURLMcode mres; + + FD_ZERO(&read_fd_set); + FD_ZERO(&write_fd_set); + FD_ZERO(&exc_fd_set); + + mres = curl_multi_fdset(m_multi, &read_fd_set, + &write_fd_set, &exc_fd_set, &max_fd); + if (mres != CURLM_OK) { + errorstream<<"curl_multi_fdset" + <<" returned error code "<<mres + <<std::endl; + select_timeout = 0; + } + + mres = curl_multi_timeout(m_multi, &select_timeout); + if (mres != CURLM_OK) { + errorstream<<"curl_multi_timeout" + <<" returned error code "<<mres + <<std::endl; + select_timeout = 0; + } + + // Limit timeout so new requests get through + if (select_timeout < 0 || select_timeout > timeout) + select_timeout = timeout; + + if (select_timeout > 0) { + // in Winsock it is forbidden to pass three empty + // fd_sets to select(), so in that case use sleep_ms + if (max_fd != -1) { + select_tv.tv_sec = select_timeout / 1000; + select_tv.tv_usec = (select_timeout % 1000) * 1000; + int retval = select(max_fd + 1, &read_fd_set, + &write_fd_set, &exc_fd_set, + &select_tv); + if (retval == -1) { + #ifdef _WIN32 + errorstream<<"select returned error code " + <<WSAGetLastError()<<std::endl; + #else + errorstream<<"select returned error code " + <<errno<<std::endl; + #endif + } + } + else { + sleep_ms(select_timeout); + } + } + } + + void *run() + { + CurlHandlePool pool; + + m_multi = curl_multi_init(); + if (m_multi == NULL) { + errorstream<<"curl_multi_init returned NULL\n"; + return NULL; + } + + FATAL_ERROR_IF(!m_all_ongoing.empty(), "Expected empty"); + + while (!stopRequested()) { + BEGIN_DEBUG_EXCEPTION_HANDLER + + /* + Handle new async requests + */ + + while (!m_requests.empty()) { + Request req = m_requests.pop_frontNoEx(); + processRequest(req); + } + processQueued(&pool); + + /* + Handle ongoing async requests + */ + + int still_ongoing = 0; + while (curl_multi_perform(m_multi, &still_ongoing) == + CURLM_CALL_MULTI_PERFORM) + /* noop */; + + /* + Handle completed async requests + */ + if (still_ongoing < (int) m_all_ongoing.size()) { + CURLMsg *msg; + int msgs_in_queue; + msg = curl_multi_info_read(m_multi, &msgs_in_queue); + while (msg != NULL) { + processCurlMessage(msg); + msg = curl_multi_info_read(m_multi, &msgs_in_queue); + } + } + + /* + If there are ongoing requests, wait for data + (with a timeout of 100ms so that new requests + can be processed). + + If no ongoing requests, wait for a new request. + (Possibly an empty request that signals + that the thread should be stopped.) + */ + if (m_all_ongoing.empty()) + waitForRequest(100000000); + else + waitForIO(100); + + END_DEBUG_EXCEPTION_HANDLER + } + + // Call curl_multi_remove_handle and cleanup easy handles + for (HTTPFetchOngoing *i : m_all_ongoing) { + delete i; + } + m_all_ongoing.clear(); + + m_queued_fetches.clear(); + + CURLMcode mres = curl_multi_cleanup(m_multi); + if (mres != CURLM_OK) { + errorstream<<"curl_multi_cleanup" + <<" returned error code "<<mres + <<std::endl; + } + + return NULL; + } +}; + +CurlFetchThread *g_httpfetch_thread = NULL; + +void httpfetch_init(int parallel_limit) +{ + verbosestream<<"httpfetch_init: parallel_limit="<<parallel_limit + <<std::endl; + + CURLcode res = curl_global_init(CURL_GLOBAL_DEFAULT); + FATAL_ERROR_IF(res != CURLE_OK, "CURL init failed"); + + g_httpfetch_thread = new CurlFetchThread(parallel_limit); + + // Initialize g_callerid_randomness for httpfetch_caller_alloc_secure + u64 randbuf[2]; + porting::secure_rand_fill_buf(randbuf, sizeof(u64) * 2); + g_callerid_randomness = PcgRandom(randbuf[0], randbuf[1]); +} + +void httpfetch_cleanup() +{ + verbosestream<<"httpfetch_cleanup: cleaning up"<<std::endl; + + if (g_httpfetch_thread) { + g_httpfetch_thread->stop(); + g_httpfetch_thread->requestWakeUp(); + g_httpfetch_thread->wait(); + delete g_httpfetch_thread; + } + + curl_global_cleanup(); +} + +void httpfetch_async(const HTTPFetchRequest &fetch_request) +{ + g_httpfetch_thread->requestFetch(fetch_request); + if (!g_httpfetch_thread->isRunning()) + g_httpfetch_thread->start(); +} + +static void httpfetch_request_clear(u64 caller) +{ + if (g_httpfetch_thread->isRunning()) { + Event event; + g_httpfetch_thread->requestClear(caller, &event); + event.wait(); + } else { + g_httpfetch_thread->requestClear(caller, NULL); + } +} + +void httpfetch_sync(const HTTPFetchRequest &fetch_request, + HTTPFetchResult &fetch_result) +{ + // Create ongoing fetch data and make a cURL handle + // Set cURL options based on HTTPFetchRequest + CurlHandlePool pool; + HTTPFetchOngoing ongoing(fetch_request, &pool); + // Do the fetch (curl_easy_perform) + CURLcode res = ongoing.start(NULL); + // Update fetch result + fetch_result = *ongoing.complete(res); +} + +#else // USE_CURL + +/* + USE_CURL is off: + + Dummy httpfetch implementation that always returns an error. +*/ + +void httpfetch_init(int parallel_limit) +{ +} + +void httpfetch_cleanup() +{ +} + +void httpfetch_async(const HTTPFetchRequest &fetch_request) +{ + errorstream << "httpfetch_async: unable to fetch " << fetch_request.url + << " because USE_CURL=0" << std::endl; + + HTTPFetchResult fetch_result(fetch_request); // sets succeeded = false etc. + httpfetch_deliver_result(fetch_result); +} + +static void httpfetch_request_clear(u64 caller) +{ +} + +void httpfetch_sync(const HTTPFetchRequest &fetch_request, + HTTPFetchResult &fetch_result) +{ + errorstream << "httpfetch_sync: unable to fetch " << fetch_request.url + << " because USE_CURL=0" << std::endl; + + fetch_result = HTTPFetchResult(fetch_request); // sets succeeded = false etc. +} + +#endif // USE_CURL diff --git a/src/httpfetch.h b/src/httpfetch.h new file mode 100644 index 0000000..a4901e6 --- /dev/null +++ b/src/httpfetch.h @@ -0,0 +1,133 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <vector> +#include "util/string.h" +#include "config.h" + +// These can be used in place of "caller" in to specify special handling. +// Discard result (used as default value of "caller"). +#define HTTPFETCH_DISCARD 0 +// Indicates that the result should not be discarded when performing a +// synchronous request (since a real caller ID is not needed for synchronous +// requests because the result does not have to be retrieved later). +#define HTTPFETCH_SYNC 1 +// Print response body to console if the server returns an error code. +#define HTTPFETCH_PRINT_ERR 2 +// Start of regular allocated caller IDs. +#define HTTPFETCH_CID_START 3 + +// Methods +enum HttpMethod : u8 +{ + HTTP_GET, + HTTP_POST, + HTTP_PUT, + HTTP_DELETE, +}; + +struct HTTPFetchRequest +{ + std::string url = ""; + + // Identifies the caller (for asynchronous requests) + // Ignored by httpfetch_sync + u64 caller = HTTPFETCH_DISCARD; + + // Some number that identifies the request + // (when the same caller issues multiple httpfetch_async calls) + u64 request_id = 0; + + // Timeout for the whole transfer, in milliseconds + long timeout; + + // Timeout for the connection phase, in milliseconds + long connect_timeout; + + // Indicates if this is multipart/form-data or + // application/x-www-form-urlencoded. POST-only. + bool multipart = false; + + // The Method to use default = GET + // Avaible methods GET, POST, PUT, DELETE + HttpMethod method = HTTP_GET; + + // Fields of the request + StringMap fields; + + // Raw data of the request overrides fields + std::string raw_data; + + // If not empty, should contain entries such as "Accept: text/html" + std::vector<std::string> extra_headers; + + // useragent to use + std::string useragent; + + HTTPFetchRequest(); +}; + +struct HTTPFetchResult +{ + bool succeeded = false; + bool timeout = false; + long response_code = 0; + std::string data = ""; + // The caller and request_id from the corresponding HTTPFetchRequest. + u64 caller = HTTPFETCH_DISCARD; + u64 request_id = 0; + + HTTPFetchResult() = default; + + HTTPFetchResult(const HTTPFetchRequest &fetch_request) : + caller(fetch_request.caller), request_id(fetch_request.request_id) + { + } +}; + +// Initializes the httpfetch module +void httpfetch_init(int parallel_limit); + +// Stops the httpfetch thread and cleans up resources +void httpfetch_cleanup(); + +// Starts an asynchronous HTTP fetch request +void httpfetch_async(const HTTPFetchRequest &fetch_request); + +// If any fetch for the given caller ID is complete, removes it from the +// result queue, sets the fetch result and returns true. Otherwise returns false. +bool httpfetch_async_get(u64 caller, HTTPFetchResult &fetch_result); + +// Allocates a caller ID for httpfetch_async +// Not required if you want to set caller = HTTPFETCH_DISCARD +u64 httpfetch_caller_alloc(); + +// Allocates a non-predictable caller ID for httpfetch_async +u64 httpfetch_caller_alloc_secure(); + +// Frees a caller ID allocated with httpfetch_caller_alloc +// Note: This can be expensive, because the httpfetch thread is told +// to stop any ongoing fetches for the given caller. +void httpfetch_caller_free(u64 caller); + +// Performs a synchronous HTTP request. This blocks and therefore should +// only be used from background threads. +void httpfetch_sync(const HTTPFetchRequest &fetch_request, HTTPFetchResult &fetch_result); diff --git a/src/hud.cpp b/src/hud.cpp new file mode 100644 index 0000000..841c907 --- /dev/null +++ b/src/hud.cpp @@ -0,0 +1,68 @@ +/* +Minetest +Copyright (C) 2010-2018 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "hud.h" +#include <cmath> + +const struct EnumString es_HudElementType[] = +{ + {HUD_ELEM_IMAGE, "image"}, + {HUD_ELEM_TEXT, "text"}, + {HUD_ELEM_STATBAR, "statbar"}, + {HUD_ELEM_INVENTORY, "inventory"}, + {HUD_ELEM_WAYPOINT, "waypoint"}, + {HUD_ELEM_IMAGE_WAYPOINT, "image_waypoint"}, + {HUD_ELEM_COMPASS, "compass"}, + {HUD_ELEM_MINIMAP, "minimap"}, + {0, NULL}, +}; + +const struct EnumString es_HudElementStat[] = +{ + {HUD_STAT_POS, "position"}, + {HUD_STAT_POS, "pos"}, /* Deprecated, only for compatibility's sake */ + {HUD_STAT_NAME, "name"}, + {HUD_STAT_SCALE, "scale"}, + {HUD_STAT_TEXT, "text"}, + {HUD_STAT_NUMBER, "number"}, + {HUD_STAT_ITEM, "item"}, + {HUD_STAT_ITEM, "precision"}, + {HUD_STAT_DIR, "direction"}, + {HUD_STAT_ALIGN, "alignment"}, + {HUD_STAT_OFFSET, "offset"}, + {HUD_STAT_WORLD_POS, "world_pos"}, + {HUD_STAT_SIZE, "size"}, + {HUD_STAT_Z_INDEX, "z_index"}, + {HUD_STAT_TEXT2, "text2"}, + {HUD_STAT_STYLE, "style"}, + {0, NULL}, +}; + +const struct EnumString es_HudBuiltinElement[] = +{ + {HUD_FLAG_HOTBAR_VISIBLE, "hotbar"}, + {HUD_FLAG_HEALTHBAR_VISIBLE, "healthbar"}, + {HUD_FLAG_CROSSHAIR_VISIBLE, "crosshair"}, + {HUD_FLAG_WIELDITEM_VISIBLE, "wielditem"}, + {HUD_FLAG_BREATHBAR_VISIBLE, "breathbar"}, + {HUD_FLAG_MINIMAP_VISIBLE, "minimap"}, + {HUD_FLAG_MINIMAP_RADAR_VISIBLE, "minimap_radar"}, + {HUD_FLAG_BASIC_DEBUG, "basic_debug"}, + {0, NULL}, +}; diff --git a/src/hud.h b/src/hud.h new file mode 100644 index 0000000..173633f --- /dev/null +++ b/src/hud.h @@ -0,0 +1,126 @@ +/* +Minetest +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2017 red-001 <red-001@outlook.ie> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include <string> +#include "common/c_types.h" + +#define HUD_DIR_LEFT_RIGHT 0 +#define HUD_DIR_RIGHT_LEFT 1 +#define HUD_DIR_TOP_BOTTOM 2 +#define HUD_DIR_BOTTOM_TOP 3 + +#define HUD_CORNER_UPPER 0 +#define HUD_CORNER_LOWER 1 +#define HUD_CORNER_CENTER 2 + +#define HUD_STYLE_BOLD 1 +#define HUD_STYLE_ITALIC 2 +#define HUD_STYLE_MONO 4 + +// Note that these visibility flags do not determine if the hud items are +// actually drawn, but rather, whether to draw the item should the rest +// of the game state permit it. +#define HUD_FLAG_HOTBAR_VISIBLE (1 << 0) +#define HUD_FLAG_HEALTHBAR_VISIBLE (1 << 1) +#define HUD_FLAG_CROSSHAIR_VISIBLE (1 << 2) +#define HUD_FLAG_WIELDITEM_VISIBLE (1 << 3) +#define HUD_FLAG_BREATHBAR_VISIBLE (1 << 4) +#define HUD_FLAG_MINIMAP_VISIBLE (1 << 5) +#define HUD_FLAG_MINIMAP_RADAR_VISIBLE (1 << 6) +#define HUD_FLAG_BASIC_DEBUG (1 << 7) + +#define HUD_PARAM_HOTBAR_ITEMCOUNT 1 +#define HUD_PARAM_HOTBAR_IMAGE 2 +#define HUD_PARAM_HOTBAR_SELECTED_IMAGE 3 + +#define HUD_HOTBAR_ITEMCOUNT_DEFAULT 8 +#define HUD_HOTBAR_ITEMCOUNT_MAX 32 + +#define HOTBAR_IMAGE_SIZE 48 + +enum HudElementType { + HUD_ELEM_IMAGE = 0, + HUD_ELEM_TEXT = 1, + HUD_ELEM_STATBAR = 2, + HUD_ELEM_INVENTORY = 3, + HUD_ELEM_WAYPOINT = 4, + HUD_ELEM_IMAGE_WAYPOINT = 5, + HUD_ELEM_COMPASS = 6, + HUD_ELEM_MINIMAP = 7 +}; + +enum HudElementStat { + HUD_STAT_POS = 0, + HUD_STAT_NAME, + HUD_STAT_SCALE, + HUD_STAT_TEXT, + HUD_STAT_NUMBER, + HUD_STAT_ITEM, + HUD_STAT_DIR, + HUD_STAT_ALIGN, + HUD_STAT_OFFSET, + HUD_STAT_WORLD_POS, + HUD_STAT_SIZE, + HUD_STAT_Z_INDEX, + HUD_STAT_TEXT2, + HUD_STAT_STYLE, +}; + +enum HudCompassDir { + HUD_COMPASS_ROTATE = 0, + HUD_COMPASS_ROTATE_REVERSE, + HUD_COMPASS_TRANSLATE, + HUD_COMPASS_TRANSLATE_REVERSE, +}; + +struct HudElement { + HudElementType type; + v2f pos; + std::string name; + v2f scale; + std::string text; + u32 number; + u32 item; + u32 dir; + v2f align; + v2f offset; + v3f world_pos; + v2s32 size; + s16 z_index = 0; + std::string text2; + u32 style; +}; + +extern const EnumString es_HudElementType[]; +extern const EnumString es_HudElementStat[]; +extern const EnumString es_HudBuiltinElement[]; + +// Minimap stuff + +enum MinimapType { + MINIMAP_TYPE_OFF, + MINIMAP_TYPE_SURFACE, + MINIMAP_TYPE_RADAR, + MINIMAP_TYPE_TEXTURE, +}; + diff --git a/src/inventory.cpp b/src/inventory.cpp new file mode 100644 index 0000000..6d2b7fb --- /dev/null +++ b/src/inventory.cpp @@ -0,0 +1,961 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "inventory.h" +#include "serialization.h" +#include "debug.h" +#include <algorithm> +#include <sstream> +#include "log.h" +#include "itemdef.h" +#include "util/strfnd.h" +#include "content_mapnode.h" // For loading legacy MaterialItems +#include "nameidmapping.h" // For loading legacy MaterialItems +#include "util/serialize.h" +#include "util/string.h" + +/* + ItemStack +*/ + +static content_t content_translate_from_19_to_internal(content_t c_from) +{ + for (const auto &tt : trans_table_19) { + if(tt[1] == c_from) { + return tt[0]; + } + } + return c_from; +} + +ItemStack::ItemStack(const std::string &name_, u16 count_, + u16 wear_, IItemDefManager *itemdef) : + name(itemdef->getAlias(name_)), + count(count_), + wear(wear_) +{ + if (name.empty() || count == 0) + clear(); + else if (itemdef->get(name).type == ITEM_TOOL) + count = 1; +} + +void ItemStack::serialize(std::ostream &os, bool serialize_meta) const +{ + if (empty()) + return; + + // Check how many parts of the itemstring are needed + int parts = 1; + if (!metadata.empty()) + parts = 4; + else if (wear != 0) + parts = 3; + else if (count != 1) + parts = 2; + + os << serializeJsonStringIfNeeded(name); + if (parts >= 2) + os << " " << count; + if (parts >= 3) + os << " " << wear; + if (parts >= 4) { + os << " "; + if (serialize_meta) + metadata.serialize(os); + else + os << "<metadata size=" << metadata.size() << ">"; + } +} + +void ItemStack::deSerialize(std::istream &is, IItemDefManager *itemdef) +{ + clear(); + + // Read name + name = deSerializeJsonStringIfNeeded(is); + + // Skip space + std::string tmp; + std::getline(is, tmp, ' '); + if(!tmp.empty()) + throw SerializationError("Unexpected text after item name"); + + if(name == "MaterialItem") + { + // Obsoleted on 2011-07-30 + + u16 material; + is>>material; + u16 materialcount; + is>>materialcount; + // Convert old materials + if(material <= 0xff) + material = content_translate_from_19_to_internal(material); + if(material > 0xfff) + throw SerializationError("Too large material number"); + // Convert old id to name + NameIdMapping legacy_nimap; + content_mapnode_get_name_id_mapping(&legacy_nimap); + legacy_nimap.getName(material, name); + if(name.empty()) + name = "unknown_block"; + if (itemdef) + name = itemdef->getAlias(name); + count = materialcount; + } + else if(name == "MaterialItem2") + { + // Obsoleted on 2011-11-16 + + u16 material; + is>>material; + u16 materialcount; + is>>materialcount; + if(material > 0xfff) + throw SerializationError("Too large material number"); + // Convert old id to name + NameIdMapping legacy_nimap; + content_mapnode_get_name_id_mapping(&legacy_nimap); + legacy_nimap.getName(material, name); + if(name.empty()) + name = "unknown_block"; + if (itemdef) + name = itemdef->getAlias(name); + count = materialcount; + } + else if(name == "node" || name == "NodeItem" || name == "MaterialItem3" + || name == "craft" || name == "CraftItem") + { + // Obsoleted on 2012-01-07 + + std::string all; + std::getline(is, all, '\n'); + // First attempt to read inside "" + Strfnd fnd(all); + fnd.next("\""); + // If didn't skip to end, we have ""s + if(!fnd.at_end()){ + name = fnd.next("\""); + } else { // No luck, just read a word then + fnd.start(all); + name = fnd.next(" "); + } + fnd.skip_over(" "); + if (itemdef) + name = itemdef->getAlias(name); + count = stoi(trim(fnd.next(""))); + if(count == 0) + count = 1; + } + else if(name == "MBOItem") + { + // Obsoleted on 2011-10-14 + throw SerializationError("MBOItem not supported anymore"); + } + else if(name == "tool" || name == "ToolItem") + { + // Obsoleted on 2012-01-07 + + std::string all; + std::getline(is, all, '\n'); + // First attempt to read inside "" + Strfnd fnd(all); + fnd.next("\""); + // If didn't skip to end, we have ""s + if(!fnd.at_end()){ + name = fnd.next("\""); + } else { // No luck, just read a word then + fnd.start(all); + name = fnd.next(" "); + } + count = 1; + // Then read wear + fnd.skip_over(" "); + if (itemdef) + name = itemdef->getAlias(name); + wear = stoi(trim(fnd.next(""))); + } + else + { + do // This loop is just to allow "break;" + { + // The real thing + + // Apply item aliases + if (itemdef) + name = itemdef->getAlias(name); + + // Read the count + std::string count_str; + std::getline(is, count_str, ' '); + if (count_str.empty()) { + count = 1; + break; + } + + count = stoi(count_str); + + // Read the wear + std::string wear_str; + std::getline(is, wear_str, ' '); + if(wear_str.empty()) + break; + + wear = stoi(wear_str); + + // Read metadata + metadata.deSerialize(is); + + // In case fields are added after metadata, skip space here: + //std::getline(is, tmp, ' '); + //if(!tmp.empty()) + // throw SerializationError("Unexpected text after metadata"); + + } while(false); + } + + if (name.empty() || count == 0) + clear(); + else if (itemdef && itemdef->get(name).type == ITEM_TOOL) + count = 1; +} + +void ItemStack::deSerialize(const std::string &str, IItemDefManager *itemdef) +{ + std::istringstream is(str, std::ios::binary); + deSerialize(is, itemdef); +} + +std::string ItemStack::getItemString(bool include_meta) const +{ + std::ostringstream os(std::ios::binary); + serialize(os, include_meta); + return os.str(); +} + +std::string ItemStack::getDescription(IItemDefManager *itemdef) const +{ + std::string desc = metadata.getString("description"); + if (desc.empty()) + desc = getDefinition(itemdef).description; + return desc.empty() ? name : desc; +} + +std::string ItemStack::getShortDescription(IItemDefManager *itemdef) const +{ + std::string desc = metadata.getString("short_description"); + if (desc.empty()) + desc = getDefinition(itemdef).short_description; + if (!desc.empty()) + return desc; + // no short_description because of old server version or modified builtin + // return first line of description + std::stringstream sstr(getDescription(itemdef)); + std::getline(sstr, desc, '\n'); + return desc; +} + + +ItemStack ItemStack::addItem(ItemStack newitem, IItemDefManager *itemdef) +{ + // If the item is empty or the position invalid, bail out + if(newitem.empty()) + { + // nothing can be added trivially + } + // If this is an empty item, it's an easy job. + else if(empty()) + { + *this = newitem; + newitem.clear(); + } + // If item name or metadata differs, bail out + else if (name != newitem.name + || metadata != newitem.metadata) + { + // cannot be added + } + // If the item fits fully, add counter and delete it + else if(newitem.count <= freeSpace(itemdef)) + { + add(newitem.count); + newitem.clear(); + } + // Else the item does not fit fully. Add all that fits and return + // the rest. + else + { + u16 freespace = freeSpace(itemdef); + add(freespace); + newitem.remove(freespace); + } + + return newitem; +} + +bool ItemStack::itemFits(ItemStack newitem, + ItemStack *restitem, + IItemDefManager *itemdef) const +{ + + // If the item is empty or the position invalid, bail out + if(newitem.empty()) + { + // nothing can be added trivially + } + // If this is an empty item, it's an easy job. + else if(empty()) + { + newitem.clear(); + } + // If item name or metadata differs, bail out + else if (name != newitem.name + || metadata != newitem.metadata) + { + // cannot be added + } + // If the item fits fully, delete it + else if(newitem.count <= freeSpace(itemdef)) + { + newitem.clear(); + } + // Else the item does not fit fully. Return the rest. + else + { + u16 freespace = freeSpace(itemdef); + newitem.remove(freespace); + } + + if(restitem) + *restitem = newitem; + + return newitem.empty(); +} + +ItemStack ItemStack::takeItem(u32 takecount) +{ + if(takecount == 0 || count == 0) + return ItemStack(); + + ItemStack result = *this; + if(takecount >= count) + { + // Take all + clear(); + } + else + { + // Take part + remove(takecount); + result.count = takecount; + } + return result; +} + +ItemStack ItemStack::peekItem(u32 peekcount) const +{ + if(peekcount == 0 || count == 0) + return ItemStack(); + + ItemStack result = *this; + if(peekcount < count) + result.count = peekcount; + return result; +} + +/* + Inventory +*/ + +InventoryList::InventoryList(const std::string &name, u32 size, IItemDefManager *itemdef): + m_name(name), + m_size(size), + m_itemdef(itemdef) +{ + clearItems(); +} + +void InventoryList::clearItems() +{ + m_items.clear(); + + for (u32 i=0; i < m_size; i++) { + m_items.emplace_back(); + } + + setModified(); +} + +void InventoryList::setSize(u32 newsize) +{ + if (newsize == m_items.size()) + return; + + m_items.resize(newsize); + m_size = newsize; + setModified(); +} + +void InventoryList::setWidth(u32 newwidth) +{ + m_width = newwidth; + setModified(); +} + +void InventoryList::setName(const std::string &name) +{ + m_name = name; + setModified(); +} + +void InventoryList::serialize(std::ostream &os, bool incremental) const +{ + //os.imbue(std::locale("C")); + + os<<"Width "<<m_width<<"\n"; + + for (const auto &item : m_items) { + if (item.empty()) { + os<<"Empty"; + } else { + os<<"Item "; + item.serialize(os); + } + // TODO: Implement this: + // if (!incremental || item.checkModified()) + // os << "Keep"; + os<<"\n"; + } + + os<<"EndInventoryList\n"; +} + +void InventoryList::deSerialize(std::istream &is) +{ + //is.imbue(std::locale("C")); + setModified(); + + u32 item_i = 0; + m_width = 0; + + while (is.good()) { + std::string line; + std::getline(is, line, '\n'); + + std::istringstream iss(line); + + std::string name; + std::getline(iss, name, ' '); + + if (name == "EndInventoryList" || name == "end") { + // If partial incremental: Clear leftover items (should not happen!) + for (size_t i = item_i; i < m_items.size(); ++i) + m_items[i].clear(); + return; + } + + if (name == "Width") { + iss >> m_width; + if (iss.fail()) + throw SerializationError("incorrect width property"); + } + else if(name == "Item") + { + if(item_i > getSize() - 1) + throw SerializationError("too many items"); + ItemStack item; + item.deSerialize(iss, m_itemdef); + m_items[item_i++] = item; + } + else if(name == "Empty") + { + if(item_i > getSize() - 1) + throw SerializationError("too many items"); + m_items[item_i++].clear(); + } else if (name == "Keep") { + ++item_i; // Unmodified item + } + } + + // Contents given to deSerialize() were not terminated properly: throw error. + + std::ostringstream ss; + ss << "Malformatted inventory list. list=" + << m_name << ", read " << item_i << " of " << getSize() + << " ItemStacks." << std::endl; + throw SerializationError(ss.str()); +} + +InventoryList & InventoryList::operator = (const InventoryList &other) +{ + m_items = other.m_items; + m_size = other.m_size; + m_width = other.m_width; + m_name = other.m_name; + m_itemdef = other.m_itemdef; + //setDirty(true); + + return *this; +} + +bool InventoryList::operator == (const InventoryList &other) const +{ + if(m_size != other.m_size) + return false; + if(m_width != other.m_width) + return false; + if(m_name != other.m_name) + return false; + for (u32 i = 0; i < m_items.size(); i++) + if (m_items[i] != other.m_items[i]) + return false; + + return true; +} + +u32 InventoryList::getUsedSlots() const +{ + u32 num = 0; + for (const auto &m_item : m_items) { + if (!m_item.empty()) + num++; + } + return num; +} + +ItemStack InventoryList::changeItem(u32 i, const ItemStack &newitem) +{ + if(i >= m_items.size()) + return newitem; + + ItemStack olditem = m_items[i]; + m_items[i] = newitem; + setModified(); + return olditem; +} + +void InventoryList::deleteItem(u32 i) +{ + assert(i < m_items.size()); // Pre-condition + m_items[i].clear(); + setModified(); +} + +ItemStack InventoryList::addItem(const ItemStack &newitem_) +{ + ItemStack newitem = newitem_; + + if(newitem.empty()) + return newitem; + + /* + First try to find if it could be added to some existing items + */ + for(u32 i=0; i<m_items.size(); i++) + { + // Ignore empty slots + if(m_items[i].empty()) + continue; + // Try adding + newitem = addItem(i, newitem); + if(newitem.empty()) + return newitem; // All was eaten + } + + /* + Then try to add it to empty slots + */ + for(u32 i=0; i<m_items.size(); i++) + { + // Ignore unempty slots + if(!m_items[i].empty()) + continue; + // Try adding + newitem = addItem(i, newitem); + if(newitem.empty()) + return newitem; // All was eaten + } + + // Return leftover + return newitem; +} + +ItemStack InventoryList::addItem(u32 i, const ItemStack &newitem) +{ + if(i >= m_items.size()) + return newitem; + + ItemStack leftover = m_items[i].addItem(newitem, m_itemdef); + if (leftover != newitem) + setModified(); + return leftover; +} + +bool InventoryList::itemFits(const u32 i, const ItemStack &newitem, + ItemStack *restitem) const +{ + if(i >= m_items.size()) + { + if(restitem) + *restitem = newitem; + return false; + } + + return m_items[i].itemFits(newitem, restitem, m_itemdef); +} + +bool InventoryList::roomForItem(const ItemStack &item_) const +{ + ItemStack item = item_; + ItemStack leftover; + for(u32 i=0; i<m_items.size(); i++) + { + if(itemFits(i, item, &leftover)) + return true; + item = leftover; + } + return false; +} + +bool InventoryList::containsItem(const ItemStack &item, bool match_meta) const +{ + u32 count = item.count; + if (count == 0) + return true; + + for (auto i = m_items.rbegin(); i != m_items.rend(); ++i) { + if (count == 0) + break; + if (i->name == item.name && (!match_meta || (i->metadata == item.metadata))) { + if (i->count >= count) + return true; + + count -= i->count; + } + } + return false; +} + +ItemStack InventoryList::removeItem(const ItemStack &item) +{ + ItemStack removed; + for (auto i = m_items.rbegin(); i != m_items.rend(); ++i) { + if (i->name == item.name) { + u32 still_to_remove = item.count - removed.count; + ItemStack leftover = removed.addItem(i->takeItem(still_to_remove), + m_itemdef); + // Allow oversized stacks + removed.count += leftover.count; + + if (removed.count == item.count) + break; + } + } + if (!removed.empty()) + setModified(); + return removed; +} + +ItemStack InventoryList::takeItem(u32 i, u32 takecount) +{ + if(i >= m_items.size()) + return ItemStack(); + + ItemStack taken = m_items[i].takeItem(takecount); + if (!taken.empty()) + setModified(); + return taken; +} + +void InventoryList::moveItemSomewhere(u32 i, InventoryList *dest, u32 count) +{ + // Take item from source list + ItemStack item1; + if (count == 0) + item1 = changeItem(i, ItemStack()); + else + item1 = takeItem(i, count); + + if (item1.empty()) + return; + + ItemStack leftover; + leftover = dest->addItem(item1); + + if (!leftover.empty()) { + // Add the remaining part back to the source item + addItem(i, leftover); + } +} + +u32 InventoryList::moveItem(u32 i, InventoryList *dest, u32 dest_i, + u32 count, bool swap_if_needed, bool *did_swap) +{ + if (this == dest && i == dest_i) + return count; + + // Take item from source list + ItemStack item1; + if (count == 0) + item1 = changeItem(i, ItemStack()); + else + item1 = takeItem(i, count); + + if (item1.empty()) + return 0; + + // Try to add the item to destination list + u32 oldcount = item1.count; + item1 = dest->addItem(dest_i, item1); + + // If something is returned, the item was not fully added + if (!item1.empty()) { + // If olditem is returned, nothing was added. + bool nothing_added = (item1.count == oldcount); + + // If something else is returned, part of the item was left unadded. + // Add the other part back to the source item + addItem(i, item1); + + // If olditem is returned, nothing was added. + // Swap the items + if (nothing_added && swap_if_needed) { + // Tell that we swapped + if (did_swap != NULL) { + *did_swap = true; + } + // Take item from source list + item1 = changeItem(i, ItemStack()); + // Adding was not possible, swap the items. + ItemStack item2 = dest->changeItem(dest_i, item1); + // Put item from destination list to the source list + changeItem(i, item2); + } + } + return (oldcount - item1.count); +} + +/* + Inventory +*/ + +Inventory::~Inventory() +{ + clear(); +} + +void Inventory::clear() +{ + for (auto &m_list : m_lists) { + delete m_list; + } + m_lists.clear(); + setModified(); +} + +Inventory::Inventory(IItemDefManager *itemdef) +{ + m_itemdef = itemdef; + setModified(); +} + +Inventory::Inventory(const Inventory &other) +{ + *this = other; +} + +Inventory & Inventory::operator = (const Inventory &other) +{ + // Gracefully handle self assignment + if(this != &other) + { + clear(); + m_itemdef = other.m_itemdef; + for (InventoryList *list : other.m_lists) { + m_lists.push_back(new InventoryList(*list)); + } + setModified(); + } + return *this; +} + +bool Inventory::operator == (const Inventory &other) const +{ + if(m_lists.size() != other.m_lists.size()) + return false; + + for(u32 i=0; i<m_lists.size(); i++) + { + if(*m_lists[i] != *other.m_lists[i]) + return false; + } + return true; +} + +void Inventory::serialize(std::ostream &os, bool incremental) const +{ + //std::cout << "Serialize " << (int)incremental << ", n=" << m_lists.size() << std::endl; + for (const InventoryList *list : m_lists) { + if (!incremental || list->checkModified()) { + os << "List " << list->getName() << " " << list->getSize() << "\n"; + list->serialize(os, incremental); + } else { + os << "KeepList " << list->getName() << "\n"; + } + } + + os<<"EndInventory\n"; +} + +void Inventory::deSerialize(std::istream &is) +{ + std::vector<InventoryList *> new_lists; + new_lists.reserve(m_lists.size()); + + while (is.good()) { + std::string line; + std::getline(is, line, '\n'); + + std::istringstream iss(line); + + std::string name; + std::getline(iss, name, ' '); + + if (name == "EndInventory" || name == "end") { + // Remove all lists that were not sent + for (auto &list : m_lists) { + if (std::find(new_lists.begin(), new_lists.end(), list) != new_lists.end()) + continue; + + delete list; + list = nullptr; + setModified(); + } + m_lists.erase(std::remove(m_lists.begin(), m_lists.end(), + nullptr), m_lists.end()); + return; + } + + if (name == "List") { + std::string listname; + u32 listsize; + + std::getline(iss, listname, ' '); + iss>>listsize; + + InventoryList *list = getList(listname); + bool create_new = !list; + if (create_new) + list = new InventoryList(listname, listsize, m_itemdef); + else + list->setSize(listsize); + list->deSerialize(is); + + new_lists.push_back(list); + if (create_new) + m_lists.push_back(list); + + } else if (name == "KeepList") { + // Incrementally sent list + std::string listname; + std::getline(iss, listname, ' '); + + InventoryList *list = getList(listname); + if (list) { + new_lists.push_back(list); + } else { + errorstream << "Inventory::deSerialize(): Tried to keep list '" << + listname << "' which is non-existent." << std::endl; + } + } + // Any additional fields will throw errors when received by a client + // older than PROTOCOL_VERSION 38 + } + + // Contents given to deSerialize() were not terminated properly: throw error. + + std::ostringstream ss; + ss << "Malformatted inventory (damaged?). " + << m_lists.size() << " lists read." << std::endl; + throw SerializationError(ss.str()); +} + +InventoryList * Inventory::addList(const std::string &name, u32 size) +{ + setModified(); + + // Remove existing lists + s32 i = getListIndex(name); + if (i != -1) { + delete m_lists[i]; + m_lists[i] = new InventoryList(name, size, m_itemdef); + m_lists[i]->setModified(); + return m_lists[i]; + } + + //don't create list with invalid name + if (name.find(' ') != std::string::npos) + return nullptr; + + InventoryList *list = new InventoryList(name, size, m_itemdef); + list->setModified(); + m_lists.push_back(list); + return list; +} + +InventoryList * Inventory::getList(const std::string &name) +{ + s32 i = getListIndex(name); + if(i == -1) + return nullptr; + return m_lists[i]; +} + +bool Inventory::deleteList(const std::string &name) +{ + s32 i = getListIndex(name); + if(i == -1) + return false; + + setModified(); + delete m_lists[i]; + m_lists.erase(m_lists.begin() + i); + return true; +} + +const InventoryList *Inventory::getList(const std::string &name) const +{ + s32 i = getListIndex(name); + if(i == -1) + return nullptr; + return m_lists[i]; +} + +s32 Inventory::getListIndex(const std::string &name) const +{ + for(u32 i=0; i<m_lists.size(); i++) + { + if(m_lists[i]->getName() == name) + return i; + } + return -1; +} + +//END diff --git a/src/inventory.h b/src/inventory.h new file mode 100644 index 0000000..8b31de3 --- /dev/null +++ b/src/inventory.h @@ -0,0 +1,353 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "itemdef.h" +#include "irrlichttypes.h" +#include "itemstackmetadata.h" +#include <istream> +#include <ostream> +#include <string> +#include <vector> +#include <cassert> + +struct ToolCapabilities; + +struct ItemStack +{ + ItemStack() = default; + + ItemStack(const std::string &name_, u16 count_, + u16 wear, IItemDefManager *itemdef); + + ~ItemStack() = default; + + // Serialization + void serialize(std::ostream &os, bool serialize_meta = true) const; + // Deserialization. Pass itemdef unless you don't want aliases resolved. + void deSerialize(std::istream &is, IItemDefManager *itemdef = NULL); + void deSerialize(const std::string &s, IItemDefManager *itemdef = NULL); + + // Returns the string used for inventory + std::string getItemString(bool include_meta = true) const; + // Returns the tooltip + std::string getDescription(IItemDefManager *itemdef) const; + std::string getShortDescription(IItemDefManager *itemdef) const; + + /* + Quantity methods + */ + + bool empty() const + { + return count == 0; + } + + void clear() + { + name = ""; + count = 0; + wear = 0; + metadata.clear(); + } + + void add(u16 n) + { + count += n; + } + + void remove(u16 n) + { + assert(count >= n); // Pre-condition + count -= n; + if(count == 0) + clear(); // reset name, wear and metadata too + } + + // Maximum size of a stack + u16 getStackMax(IItemDefManager *itemdef) const + { + return itemdef->get(name).stack_max; + } + + // Number of items that can be added to this stack + u16 freeSpace(IItemDefManager *itemdef) const + { + u16 max = getStackMax(itemdef); + if (count >= max) + return 0; + return max - count; + } + + // Returns false if item is not known and cannot be used + bool isKnown(IItemDefManager *itemdef) const + { + return itemdef->isKnown(name); + } + + // Returns a pointer to the item definition struct, + // or a fallback one (name="unknown") if the item is unknown. + const ItemDefinition& getDefinition( + IItemDefManager *itemdef) const + { + return itemdef->get(name); + } + + // Get tool digging properties, or those of the hand if not a tool + const ToolCapabilities& getToolCapabilities( + IItemDefManager *itemdef) const + { + const ToolCapabilities *item_cap = + itemdef->get(name).tool_capabilities; + + if (item_cap == NULL) + // Fall back to the hand's tool capabilities + item_cap = itemdef->get("").tool_capabilities; + + assert(item_cap != NULL); + return metadata.getToolCapabilities(*item_cap); // Check for override + } + + // Wear out (only tools) + // Returns true if the item is (was) a tool + bool addWear(s32 amount, IItemDefManager *itemdef) + { + if(getDefinition(itemdef).type == ITEM_TOOL) + { + if(amount > 65535 - wear) + clear(); + else if(amount < -wear) + wear = 0; + else + wear += amount; + return true; + } + + return false; + } + + // If possible, adds newitem to this item. + // If cannot be added at all, returns the item back. + // If can be added partly, decremented item is returned back. + // If can be added fully, empty item is returned. + ItemStack addItem(ItemStack newitem, IItemDefManager *itemdef); + + // Checks whether newitem could be added. + // If restitem is non-NULL, it receives the part of newitem that + // would be left over after adding. + bool itemFits(ItemStack newitem, + ItemStack *restitem, // may be NULL + IItemDefManager *itemdef) const; + + // Takes some items. + // If there are not enough, takes as many as it can. + // Returns empty item if couldn't take any. + ItemStack takeItem(u32 takecount); + + // Similar to takeItem, but keeps this ItemStack intact. + ItemStack peekItem(u32 peekcount) const; + + bool operator ==(const ItemStack &s) const + { + return (this->name == s.name && + this->count == s.count && + this->wear == s.wear && + this->metadata == s.metadata); + } + + bool operator !=(const ItemStack &s) const + { + return !(*this == s); + } + + /* + Properties + */ + std::string name = ""; + u16 count = 0; + u16 wear = 0; + ItemStackMetadata metadata; +}; + +class InventoryList +{ +public: + InventoryList(const std::string &name, u32 size, IItemDefManager *itemdef); + ~InventoryList() = default; + void clearItems(); + void setSize(u32 newsize); + void setWidth(u32 newWidth); + void setName(const std::string &name); + void serialize(std::ostream &os, bool incremental) const; + void deSerialize(std::istream &is); + + InventoryList(const InventoryList &other) { *this = other; } + InventoryList & operator = (const InventoryList &other); + bool operator == (const InventoryList &other) const; + bool operator != (const InventoryList &other) const + { + return !(*this == other); + } + + const std::string &getName() const { return m_name; } + u32 getSize() const { return static_cast<u32>(m_items.size()); } + u32 getWidth() const { return m_width; } + // Count used slots + u32 getUsedSlots() const; + + // Get reference to item + const ItemStack &getItem(u32 i) const + { + assert(i < m_size); // Pre-condition + return m_items[i]; + } + ItemStack &getItem(u32 i) + { + assert(i < m_size); // Pre-condition + return m_items[i]; + } + // Get reference to all items + const std::vector<ItemStack> &getItems() const { return m_items; } + // Returns old item. Parameter can be an empty item. + ItemStack changeItem(u32 i, const ItemStack &newitem); + // Delete item + void deleteItem(u32 i); + + // Adds an item to a suitable place. Returns leftover item (possibly empty). + ItemStack addItem(const ItemStack &newitem); + + // If possible, adds item to given slot. + // If cannot be added at all, returns the item back. + // If can be added partly, decremented item is returned back. + // If can be added fully, empty item is returned. + ItemStack addItem(u32 i, const ItemStack &newitem); + + // Checks whether the item could be added to the given slot + // If restitem is non-NULL, it receives the part of newitem that + // would be left over after adding. + bool itemFits(const u32 i, const ItemStack &newitem, + ItemStack *restitem = NULL) const; + + // Checks whether there is room for a given item + bool roomForItem(const ItemStack &item) const; + + // Checks whether the given count of the given item + // exists in this inventory list. + // If match_meta is false, only the items' names are compared. + bool containsItem(const ItemStack &item, bool match_meta) const; + + // Removes the given count of the given item name from + // this inventory list. Walks the list in reverse order. + // If not as many items exist as requested, removes as + // many as possible. + // Returns the items that were actually removed. + ItemStack removeItem(const ItemStack &item); + + // Takes some items from a slot. + // If there are not enough, takes as many as it can. + // Returns empty item if couldn't take any. + ItemStack takeItem(u32 i, u32 takecount); + + // Move an item to a different list (or a different stack in the same list) + // count is the maximum number of items to move (0 for everything) + // returns number of moved items + u32 moveItem(u32 i, InventoryList *dest, u32 dest_i, + u32 count = 0, bool swap_if_needed = true, bool *did_swap = NULL); + + // like moveItem, but without a fixed destination index + // also with optional rollback recording + void moveItemSomewhere(u32 i, InventoryList *dest, u32 count); + + inline bool checkModified() const { return m_dirty; } + inline void setModified(bool dirty = true) { m_dirty = dirty; } + +private: + std::vector<ItemStack> m_items; + std::string m_name; + u32 m_size; // always the same as m_items.size() + u32 m_width = 0; + IItemDefManager *m_itemdef; + bool m_dirty = true; +}; + +class Inventory +{ +public: + ~Inventory(); + + void clear(); + + Inventory(IItemDefManager *itemdef); + Inventory(const Inventory &other); + Inventory & operator = (const Inventory &other); + bool operator == (const Inventory &other) const; + bool operator != (const Inventory &other) const + { + return !(*this == other); + } + + // Never ever serialize to disk using "incremental"! + void serialize(std::ostream &os, bool incremental = false) const; + void deSerialize(std::istream &is); + + // Creates a new list if none exists or truncates existing lists + InventoryList * addList(const std::string &name, u32 size); + InventoryList * getList(const std::string &name); + const InventoryList * getList(const std::string &name) const; + const std::vector<InventoryList *> &getLists() const { return m_lists; } + bool deleteList(const std::string &name); + // A shorthand for adding items. Returns leftover item (possibly empty). + ItemStack addItem(const std::string &listname, const ItemStack &newitem) + { + InventoryList *list = getList(listname); + if(list == NULL) + return newitem; + return list->addItem(newitem); + } + + inline bool checkModified() const + { + if (m_dirty) + return true; + + for (const auto &list : m_lists) + if (list->checkModified()) + return true; + + return false; + } + + inline void setModified(bool dirty = true) + { + m_dirty = dirty; + // Set all as handled + if (!dirty) { + for (const auto &list : m_lists) + list->setModified(dirty); + } + } +private: + // -1 if not found + s32 getListIndex(const std::string &name) const; + + std::vector<InventoryList*> m_lists; + IItemDefManager *m_itemdef; + bool m_dirty = true; +}; diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp new file mode 100644 index 0000000..ecdb56a --- /dev/null +++ b/src/inventorymanager.cpp @@ -0,0 +1,999 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "inventorymanager.h" +#include "debug.h" +#include "log.h" +#include "serverenvironment.h" +#include "scripting_server.h" +#include "server/serveractiveobject.h" +#include "settings.h" +#include "craftdef.h" +#include "rollback_interface.h" +#include "util/strfnd.h" +#include "util/basic_macros.h" + +#define PLAYER_TO_SA(p) p->getEnv()->getScriptIface() + +/* + InventoryLocation +*/ + +std::string InventoryLocation::dump() const +{ + std::ostringstream os(std::ios::binary); + serialize(os); + return os.str(); +} + +void InventoryLocation::serialize(std::ostream &os) const +{ + switch (type) { + case InventoryLocation::UNDEFINED: + os<<"undefined"; + break; + case InventoryLocation::CURRENT_PLAYER: + os<<"current_player"; + break; + case InventoryLocation::PLAYER: + os<<"player:"<<name; + break; + case InventoryLocation::NODEMETA: + os<<"nodemeta:"<<p.X<<","<<p.Y<<","<<p.Z; + break; + case InventoryLocation::DETACHED: + os<<"detached:"<<name; + break; + default: + FATAL_ERROR("Unhandled inventory location type"); + } +} + +void InventoryLocation::deSerialize(std::istream &is) +{ + std::string tname; + std::getline(is, tname, ':'); + if (tname == "undefined") { + type = InventoryLocation::UNDEFINED; + } else if (tname == "current_player") { + type = InventoryLocation::CURRENT_PLAYER; + } else if (tname == "player") { + type = InventoryLocation::PLAYER; + std::getline(is, name, '\n'); + } else if (tname == "nodemeta") { + type = InventoryLocation::NODEMETA; + std::string pos; + std::getline(is, pos, '\n'); + Strfnd fn(pos); + p.X = stoi(fn.next(",")); + p.Y = stoi(fn.next(",")); + p.Z = stoi(fn.next(",")); + } else if (tname == "detached") { + type = InventoryLocation::DETACHED; + std::getline(is, name, '\n'); + } else { + infostream<<"Unknown InventoryLocation type=\""<<tname<<"\""<<std::endl; + throw SerializationError("Unknown InventoryLocation type"); + } +} + +void InventoryLocation::deSerialize(const std::string &s) +{ + std::istringstream is(s, std::ios::binary); + deSerialize(is); +} + +/* + InventoryAction +*/ + +InventoryAction *InventoryAction::deSerialize(std::istream &is) +{ + std::string type; + std::getline(is, type, ' '); + + InventoryAction *a = nullptr; + + if (type == "Move") { + a = new IMoveAction(is, false); + } else if (type == "MoveSomewhere") { + a = new IMoveAction(is, true); + } else if (type == "Drop") { + a = new IDropAction(is); + } else if (type == "Craft") { + a = new ICraftAction(is); + } + + return a; +} + +/* + IMoveAction +*/ + +IMoveAction::IMoveAction(std::istream &is, bool somewhere) : + move_somewhere(somewhere) +{ + std::string ts; + + std::getline(is, ts, ' '); + count = stoi(ts); + + std::getline(is, ts, ' '); + from_inv.deSerialize(ts); + + std::getline(is, from_list, ' '); + + std::getline(is, ts, ' '); + from_i = stoi(ts); + + std::getline(is, ts, ' '); + to_inv.deSerialize(ts); + + std::getline(is, to_list, ' '); + + if (!somewhere) { + std::getline(is, ts, ' '); + to_i = stoi(ts); + } +} + +void IMoveAction::swapDirections() +{ + std::swap(from_inv, to_inv); + std::swap(from_list, to_list); + std::swap(from_i, to_i); +} + +void IMoveAction::onPutAndOnTake(const ItemStack &src_item, ServerActiveObject *player) const +{ + ServerScripting *sa = PLAYER_TO_SA(player); + if (to_inv.type == InventoryLocation::DETACHED) + sa->detached_inventory_OnPut(*this, src_item, player); + else if (to_inv.type == InventoryLocation::NODEMETA) + sa->nodemeta_inventory_OnPut(*this, src_item, player); + else if (to_inv.type == InventoryLocation::PLAYER) + sa->player_inventory_OnPut(*this, src_item, player); + else + assert(false); + + if (from_inv.type == InventoryLocation::DETACHED) + sa->detached_inventory_OnTake(*this, src_item, player); + else if (from_inv.type == InventoryLocation::NODEMETA) + sa->nodemeta_inventory_OnTake(*this, src_item, player); + else if (from_inv.type == InventoryLocation::PLAYER) + sa->player_inventory_OnTake(*this, src_item, player); + else + assert(false); +} + +void IMoveAction::onMove(int count, ServerActiveObject *player) const +{ + ServerScripting *sa = PLAYER_TO_SA(player); + if (from_inv.type == InventoryLocation::DETACHED) + sa->detached_inventory_OnMove(*this, count, player); + else if (from_inv.type == InventoryLocation::NODEMETA) + sa->nodemeta_inventory_OnMove(*this, count, player); + else if (from_inv.type == InventoryLocation::PLAYER) + sa->player_inventory_OnMove(*this, count, player); + else + assert(false); +} + +int IMoveAction::allowPut(const ItemStack &dst_item, ServerActiveObject *player) const +{ + ServerScripting *sa = PLAYER_TO_SA(player); + int dst_can_put_count = 0xffff; + if (to_inv.type == InventoryLocation::DETACHED) + dst_can_put_count = sa->detached_inventory_AllowPut(*this, dst_item, player); + else if (to_inv.type == InventoryLocation::NODEMETA) + dst_can_put_count = sa->nodemeta_inventory_AllowPut(*this, dst_item, player); + else if (to_inv.type == InventoryLocation::PLAYER) + dst_can_put_count = sa->player_inventory_AllowPut(*this, dst_item, player); + else + assert(false); + return dst_can_put_count; +} + +int IMoveAction::allowTake(const ItemStack &src_item, ServerActiveObject *player) const +{ + ServerScripting *sa = PLAYER_TO_SA(player); + int src_can_take_count = 0xffff; + if (from_inv.type == InventoryLocation::DETACHED) + src_can_take_count = sa->detached_inventory_AllowTake(*this, src_item, player); + else if (from_inv.type == InventoryLocation::NODEMETA) + src_can_take_count = sa->nodemeta_inventory_AllowTake(*this, src_item, player); + else if (from_inv.type == InventoryLocation::PLAYER) + src_can_take_count = sa->player_inventory_AllowTake(*this, src_item, player); + else + assert(false); + return src_can_take_count; +} + +int IMoveAction::allowMove(int try_take_count, ServerActiveObject *player) const +{ + ServerScripting *sa = PLAYER_TO_SA(player); + int src_can_take_count = 0xffff; + if (from_inv.type == InventoryLocation::DETACHED) + src_can_take_count = sa->detached_inventory_AllowMove(*this, try_take_count, player); + else if (from_inv.type == InventoryLocation::NODEMETA) + src_can_take_count = sa->nodemeta_inventory_AllowMove(*this, try_take_count, player); + else if (from_inv.type == InventoryLocation::PLAYER) + src_can_take_count = sa->player_inventory_AllowMove(*this, try_take_count, player); + else + assert(false); + return src_can_take_count; +} + +void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef) +{ + Inventory *inv_from = mgr->getInventory(from_inv); + Inventory *inv_to = mgr->getInventory(to_inv); + + if (!inv_from) { + infostream << "IMoveAction::apply(): FAIL: source inventory not found: " + << "from_inv=\""<<from_inv.dump() << "\"" + << ", to_inv=\"" << to_inv.dump() << "\"" << std::endl; + return; + } + if (!inv_to) { + infostream << "IMoveAction::apply(): FAIL: destination inventory not found: " + << "from_inv=\"" << from_inv.dump() << "\"" + << ", to_inv=\"" << to_inv.dump() << "\"" << std::endl; + return; + } + + InventoryList *list_from = inv_from->getList(from_list); + InventoryList *list_to = inv_to->getList(to_list); + + /* + If a list doesn't exist or the source item doesn't exist + */ + if (!list_from) { + infostream << "IMoveAction::apply(): FAIL: source list not found: " + << "from_inv=\"" << from_inv.dump() << "\"" + << ", from_list=\"" << from_list << "\"" << std::endl; + return; + } + if (!list_to) { + infostream << "IMoveAction::apply(): FAIL: destination list not found: " + << "to_inv=\"" << to_inv.dump() << "\"" + << ", to_list=\"" << to_list << "\"" << std::endl; + return; + } + + if (move_somewhere) { + s16 old_to_i = to_i; + u16 old_count = count; + caused_by_move_somewhere = true; + move_somewhere = false; + + infostream << "IMoveAction::apply(): moving item somewhere" + << " msom=" << move_somewhere + << " count=" << count + << " from inv=\"" << from_inv.dump() << "\"" + << " list=\"" << from_list << "\"" + << " i=" << from_i + << " to inv=\"" << to_inv.dump() << "\"" + << " list=\"" << to_list << "\"" + << std::endl; + + // Try to add the item to destination list + s16 dest_size = list_to->getSize(); + // First try all the non-empty slots + for (s16 dest_i = 0; dest_i < dest_size && count > 0; dest_i++) { + if (!list_to->getItem(dest_i).empty()) { + to_i = dest_i; + apply(mgr, player, gamedef); + assert(move_count <= count); + count -= move_count; + } + } + + // Then try all the empty ones + for (s16 dest_i = 0; dest_i < dest_size && count > 0; dest_i++) { + if (list_to->getItem(dest_i).empty()) { + to_i = dest_i; + apply(mgr, player, gamedef); + count -= move_count; + } + } + + to_i = old_to_i; + count = old_count; + caused_by_move_somewhere = false; + move_somewhere = true; + return; + } + + if (from_i < 0 || list_from->getSize() <= (u32) from_i) { + infostream << "IMoveAction::apply(): FAIL: source index out of bounds: " + << "size of from_list=\"" << list_from->getSize() << "\"" + << ", from_index=\"" << from_i << "\"" << std::endl; + return; + } + + if (to_i < 0 || list_to->getSize() <= (u32) to_i) { + infostream << "IMoveAction::apply(): FAIL: destination index out of bounds: " + << "size of to_list=\"" << list_to->getSize() << "\"" + << ", to_index=\"" << to_i << "\"" << std::endl; + return; + } + + /* + Do not handle rollback if both inventories are that of the same player + */ + bool ignore_rollback = ( + from_inv.type == InventoryLocation::PLAYER && + from_inv == to_inv); + + /* + Collect information of endpoints + */ + + ItemStack src_item = list_from->getItem(from_i); + if (count > 0 && count < src_item.count) + src_item.count = count; + if (src_item.empty()) + return; + + int src_can_take_count = 0xffff; + int dst_can_put_count = 0xffff; + + // this is needed for swapping items inside one inventory to work + ItemStack restitem; + bool allow_swap = !list_to->itemFits(to_i, src_item, &restitem) + && restitem.count == src_item.count + && !caused_by_move_somewhere; + move_count = src_item.count - restitem.count; + + // Shift-click: Cannot fill this stack, proceed with next slot + if (caused_by_move_somewhere && move_count == 0) { + return; + } + + if (allow_swap) { + // Swap will affect the entire stack if it can performed. + src_item = list_from->getItem(from_i); + count = src_item.count; + } + + if (from_inv == to_inv) { + // Move action within the same inventory + src_can_take_count = allowMove(src_item.count, player); + + bool swap_expected = allow_swap; + allow_swap = allow_swap + && (src_can_take_count == -1 || src_can_take_count >= src_item.count); + if (allow_swap) { + int try_put_count = list_to->getItem(to_i).count; + swapDirections(); + dst_can_put_count = allowMove(try_put_count, player); + allow_swap = allow_swap + && (dst_can_put_count == -1 || dst_can_put_count >= try_put_count); + swapDirections(); + } else { + dst_can_put_count = src_can_take_count; + } + if (swap_expected != allow_swap) + src_can_take_count = dst_can_put_count = 0; + } else { + // Take from one inventory, put into another + int src_item_count = src_item.count; + if (caused_by_move_somewhere) + // When moving somewhere: temporarily use the actual movable stack + // size to ensure correct callback execution. + src_item.count = move_count; + dst_can_put_count = allowPut(src_item, player); + src_can_take_count = allowTake(src_item, player); + if (caused_by_move_somewhere) + // Reset source item count + src_item.count = src_item_count; + bool swap_expected = allow_swap; + allow_swap = allow_swap + && (src_can_take_count == -1 || src_can_take_count >= src_item.count) + && (dst_can_put_count == -1 || dst_can_put_count >= src_item.count); + // A swap is expected, which means that we have to + // run the "allow" callbacks a second time with swapped inventories + if (allow_swap) { + ItemStack dst_item = list_to->getItem(to_i); + swapDirections(); + + int src_can_take = allowPut(dst_item, player); + int dst_can_put = allowTake(dst_item, player); + allow_swap = allow_swap + && (src_can_take == -1 || src_can_take >= dst_item.count) + && (dst_can_put == -1 || dst_can_put >= dst_item.count); + swapDirections(); + } + if (swap_expected != allow_swap) + src_can_take_count = dst_can_put_count = 0; + } + + int old_count = count; + + /* Modify count according to collected data */ + count = src_item.count; + if (src_can_take_count != -1 && count > src_can_take_count) + count = src_can_take_count; + if (dst_can_put_count != -1 && count > dst_can_put_count) + count = dst_can_put_count; + + /* Limit according to source item count */ + if (count > list_from->getItem(from_i).count) + count = list_from->getItem(from_i).count; + + /* If no items will be moved, don't go further */ + if (count == 0) { + if (caused_by_move_somewhere) + // Set move count to zero, as no items have been moved + move_count = 0; + + // Undo client prediction. See 'clientApply' + if (from_inv.type == InventoryLocation::PLAYER) + list_from->setModified(); + + if (to_inv.type == InventoryLocation::PLAYER) + list_to->setModified(); + + infostream<<"IMoveAction::apply(): move was completely disallowed:" + <<" count="<<old_count + <<" from inv=\""<<from_inv.dump()<<"\"" + <<" list=\""<<from_list<<"\"" + <<" i="<<from_i + <<" to inv=\""<<to_inv.dump()<<"\"" + <<" list=\""<<to_list<<"\"" + <<" i="<<to_i + <<std::endl; + + return; + } + + src_item = list_from->getItem(from_i); + src_item.count = count; + ItemStack from_stack_was = list_from->getItem(from_i); + ItemStack to_stack_was = list_to->getItem(to_i); + + /* + Perform actual move + + If something is wrong (source item is empty, destination is the + same as source), nothing happens + */ + bool did_swap = false; + move_count = list_from->moveItem(from_i, + list_to, to_i, count, allow_swap, &did_swap); + if (caused_by_move_somewhere) + count = old_count; + assert(allow_swap == did_swap); + + // If source is infinite, reset it's stack + if (src_can_take_count == -1) { + // For the caused_by_move_somewhere == true case we didn't force-put the item, + // which guarantees there is no leftover, and code below would duplicate the + // (not replaced) to_stack_was item. + if (!caused_by_move_somewhere) { + // If destination stack is of different type and there are leftover + // items, attempt to put the leftover items to a different place in the + // destination inventory. + // The client-side GUI will try to guess if this happens. + if (from_stack_was.name != to_stack_was.name) { + for (u32 i = 0; i < list_to->getSize(); i++) { + if (list_to->getItem(i).empty()) { + list_to->changeItem(i, to_stack_was); + break; + } + } + } + } + if (move_count > 0 || did_swap) { + list_from->deleteItem(from_i); + list_from->addItem(from_i, from_stack_was); + } + } + // If destination is infinite, reset it's stack and take count from source + if (dst_can_put_count == -1) { + list_to->deleteItem(to_i); + list_to->addItem(to_i, to_stack_was); + list_from->deleteItem(from_i); + list_from->addItem(from_i, from_stack_was); + list_from->takeItem(from_i, count); + } + + infostream << "IMoveAction::apply(): moved" + << " msom=" << move_somewhere + << " caused=" << caused_by_move_somewhere + << " count=" << count + << " from inv=\"" << from_inv.dump() << "\"" + << " list=\"" << from_list << "\"" + << " i=" << from_i + << " to inv=\"" << to_inv.dump() << "\"" + << " list=\"" << to_list << "\"" + << " i=" << to_i + << std::endl; + + // If we are inside the move somewhere loop, we don't need to report + // anything if nothing happened + if (caused_by_move_somewhere && move_count == 0) + return; + + /* + Record rollback information + */ + if (!ignore_rollback && gamedef->rollback()) { + IRollbackManager *rollback = gamedef->rollback(); + + // If source is not infinite, record item take + if (src_can_take_count != -1) { + RollbackAction action; + std::string loc; + { + std::ostringstream os(std::ios::binary); + from_inv.serialize(os); + loc = os.str(); + } + action.setModifyInventoryStack(loc, from_list, from_i, false, + src_item); + rollback->reportAction(action); + } + // If destination is not infinite, record item put + if (dst_can_put_count != -1) { + RollbackAction action; + std::string loc; + { + std::ostringstream os(std::ios::binary); + to_inv.serialize(os); + loc = os.str(); + } + action.setModifyInventoryStack(loc, to_list, to_i, true, + src_item); + rollback->reportAction(action); + } + } + + /* + Report move to endpoints + */ + + // Source = destination => move + if (from_inv == to_inv) { + onMove(count, player); + if (did_swap) { + // Item is now placed in source list + src_item = list_from->getItem(from_i); + swapDirections(); + onMove(src_item.count, player); + swapDirections(); + } + mgr->setInventoryModified(from_inv); + } else { + int src_item_count = src_item.count; + if (caused_by_move_somewhere) + // When moving somewhere: temporarily use the actual movable stack + // size to ensure correct callback execution. + src_item.count = move_count; + onPutAndOnTake(src_item, player); + if (caused_by_move_somewhere) + // Reset source item count + src_item.count = src_item_count; + if (did_swap) { + // Item is now placed in source list + src_item = list_from->getItem(from_i); + swapDirections(); + onPutAndOnTake(src_item, player); + swapDirections(); + } + mgr->setInventoryModified(to_inv); + mgr->setInventoryModified(from_inv); + } +} + +void IMoveAction::clientApply(InventoryManager *mgr, IGameDef *gamedef) +{ + // Optional InventoryAction operation that is run on the client + // to make lag less apparent. + + Inventory *inv_from = mgr->getInventory(from_inv); + Inventory *inv_to = mgr->getInventory(to_inv); + if (!inv_from || !inv_to) + return; + + InventoryLocation current_player; + current_player.setCurrentPlayer(); + Inventory *inv_player = mgr->getInventory(current_player); + if (inv_from != inv_player || inv_to != inv_player) + return; + + InventoryList *list_from = inv_from->getList(from_list); + InventoryList *list_to = inv_to->getList(to_list); + if (!list_from || !list_to) + return; + + if (!move_somewhere) + list_from->moveItem(from_i, list_to, to_i, count); + else + list_from->moveItemSomewhere(from_i, list_to, count); + + mgr->setInventoryModified(from_inv); + if (inv_from != inv_to) + mgr->setInventoryModified(to_inv); +} + +/* + IDropAction +*/ + +IDropAction::IDropAction(std::istream &is) +{ + std::string ts; + + std::getline(is, ts, ' '); + count = stoi(ts); + + std::getline(is, ts, ' '); + from_inv.deSerialize(ts); + + std::getline(is, from_list, ' '); + + std::getline(is, ts, ' '); + from_i = stoi(ts); +} + +void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef) +{ + Inventory *inv_from = mgr->getInventory(from_inv); + + if (!inv_from) { + infostream<<"IDropAction::apply(): FAIL: source inventory not found: " + <<"from_inv=\""<<from_inv.dump()<<"\""<<std::endl; + return; + } + + InventoryList *list_from = inv_from->getList(from_list); + + /* + If a list doesn't exist or the source item doesn't exist + */ + if (!list_from) { + infostream<<"IDropAction::apply(): FAIL: source list not found: " + <<"from_inv=\""<<from_inv.dump()<<"\""<<std::endl; + return; + } + if (list_from->getItem(from_i).empty()) { + infostream<<"IDropAction::apply(): FAIL: source item not found: " + <<"from_inv=\""<<from_inv.dump()<<"\"" + <<", from_list=\""<<from_list<<"\"" + <<" from_i="<<from_i<<std::endl; + return; + } + + /* + Do not handle rollback if inventory is player's + */ + bool ignore_src_rollback = (from_inv.type == InventoryLocation::PLAYER); + + /* + Collect information of endpoints + */ + + int take_count = list_from->getItem(from_i).count; + if (count != 0 && count < take_count) + take_count = count; + int src_can_take_count = take_count; + + ItemStack src_item = list_from->getItem(from_i); + src_item.count = take_count; + + // Run callbacks depending on source inventory + switch (from_inv.type) { + case InventoryLocation::DETACHED: + src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowTake( + *this, src_item, player); + break; + case InventoryLocation::NODEMETA: + src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowTake( + *this, src_item, player); + break; + case InventoryLocation::PLAYER: + src_can_take_count = PLAYER_TO_SA(player)->player_inventory_AllowTake( + *this, src_item, player); + break; + default: + break; + } + + if (src_can_take_count != -1 && src_can_take_count < take_count) + take_count = src_can_take_count; + + // Update item due executed callbacks + src_item = list_from->getItem(from_i); + + // Drop the item + ItemStack item1 = list_from->getItem(from_i); + item1.count = take_count; + if(PLAYER_TO_SA(player)->item_OnDrop(item1, player, + player->getBasePosition())) { + int actually_dropped_count = take_count - item1.count; + + if (actually_dropped_count == 0) { + infostream<<"Actually dropped no items"<<std::endl; + + // Revert client prediction. See 'clientApply' + if (from_inv.type == InventoryLocation::PLAYER) + list_from->setModified(); + return; + } + + // If source isn't infinite + if (src_can_take_count != -1) { + // Take item from source list + ItemStack item2 = list_from->takeItem(from_i, actually_dropped_count); + + if (item2.count != actually_dropped_count) + errorstream<<"Could not take dropped count of items"<<std::endl; + } + + src_item.count = actually_dropped_count; + mgr->setInventoryModified(from_inv); + } + + infostream<<"IDropAction::apply(): dropped " + <<" from inv=\""<<from_inv.dump()<<"\"" + <<" list=\""<<from_list<<"\"" + <<" i="<<from_i + <<std::endl; + + + /* + Report drop to endpoints + */ + + switch (from_inv.type) { + case InventoryLocation::DETACHED: + PLAYER_TO_SA(player)->detached_inventory_OnTake( + *this, src_item, player); + break; + case InventoryLocation::NODEMETA: + PLAYER_TO_SA(player)->nodemeta_inventory_OnTake( + *this, src_item, player); + break; + case InventoryLocation::PLAYER: + PLAYER_TO_SA(player)->player_inventory_OnTake( + *this, src_item, player); + break; + default: + break; + } + + /* + Record rollback information + */ + if (!ignore_src_rollback && gamedef->rollback()) { + IRollbackManager *rollback = gamedef->rollback(); + + // If source is not infinite, record item take + if (src_can_take_count != -1) { + RollbackAction action; + std::string loc; + { + std::ostringstream os(std::ios::binary); + from_inv.serialize(os); + loc = os.str(); + } + action.setModifyInventoryStack(loc, from_list, from_i, + false, src_item); + rollback->reportAction(action); + } + } +} + +void IDropAction::clientApply(InventoryManager *mgr, IGameDef *gamedef) +{ + // Optional InventoryAction operation that is run on the client + // to make lag less apparent. + + Inventory *inv_from = mgr->getInventory(from_inv); + if (!inv_from) + return; + + InventoryLocation current_player; + current_player.setCurrentPlayer(); + Inventory *inv_player = mgr->getInventory(current_player); + if (inv_from != inv_player) + return; + + InventoryList *list_from = inv_from->getList(from_list); + if (!list_from) + return; + + if (count == 0) + list_from->changeItem(from_i, ItemStack()); + else + list_from->takeItem(from_i, count); + + mgr->setInventoryModified(from_inv); +} + +/* + ICraftAction +*/ + +ICraftAction::ICraftAction(std::istream &is) +{ + std::string ts; + + std::getline(is, ts, ' '); + count = stoi(ts); + + std::getline(is, ts, ' '); + craft_inv.deSerialize(ts); +} + +void ICraftAction::apply(InventoryManager *mgr, + ServerActiveObject *player, IGameDef *gamedef) +{ + Inventory *inv_craft = mgr->getInventory(craft_inv); + + if (!inv_craft) { + infostream << "ICraftAction::apply(): FAIL: inventory not found: " + << "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl; + return; + } + + InventoryList *list_craft = inv_craft->getList("craft"); + InventoryList *list_craftresult = inv_craft->getList("craftresult"); + InventoryList *list_main = inv_craft->getList("main"); + + /* + If a list doesn't exist or the source item doesn't exist + */ + if (!list_craft) { + infostream << "ICraftAction::apply(): FAIL: craft list not found: " + << "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl; + return; + } + if (!list_craftresult) { + infostream << "ICraftAction::apply(): FAIL: craftresult list not found: " + << "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl; + return; + } + if (list_craftresult->getSize() < 1) { + infostream << "ICraftAction::apply(): FAIL: craftresult list too short: " + << "craft_inv=\"" << craft_inv.dump() << "\"" << std::endl; + return; + } + + ItemStack crafted; + ItemStack craftresultitem; + int count_remaining = count; + std::vector<ItemStack> output_replacements; + getCraftingResult(inv_craft, crafted, output_replacements, false, gamedef); + PLAYER_TO_SA(player)->item_CraftPredict(crafted, player, list_craft, craft_inv); + bool found = !crafted.empty(); + + while (found && list_craftresult->itemFits(0, crafted)) { + InventoryList saved_craft_list = *list_craft; + + std::vector<ItemStack> temp; + // Decrement input and add crafting output + getCraftingResult(inv_craft, crafted, temp, true, gamedef); + PLAYER_TO_SA(player)->item_OnCraft(crafted, player, &saved_craft_list, craft_inv); + list_craftresult->addItem(0, crafted); + mgr->setInventoryModified(craft_inv); + + // Add the new replacements to the list + IItemDefManager *itemdef = gamedef->getItemDefManager(); + for (auto &itemstack : temp) { + for (auto &output_replacement : output_replacements) { + if (itemstack.name == output_replacement.name) { + itemstack = output_replacement.addItem(itemstack, itemdef); + if (itemstack.empty()) + continue; + } + } + output_replacements.push_back(itemstack); + } + + actionstream << player->getDescription() + << " crafts " + << crafted.getItemString() + << std::endl; + + // Decrement counter + if (count_remaining == 1) + break; + + if (count_remaining > 1) + count_remaining--; + + // Get next crafting result + getCraftingResult(inv_craft, crafted, temp, false, gamedef); + PLAYER_TO_SA(player)->item_CraftPredict(crafted, player, list_craft, craft_inv); + found = !crafted.empty(); + } + + // Put the replacements in the inventory or drop them on the floor, if + // the inventory is full + for (auto &output_replacement : output_replacements) { + if (list_main) + output_replacement = list_main->addItem(output_replacement); + if (output_replacement.empty()) + continue; + u16 count = output_replacement.count; + do { + PLAYER_TO_SA(player)->item_OnDrop(output_replacement, player, + player->getBasePosition()); + if (count >= output_replacement.count) { + errorstream << "Couldn't drop replacement stack " << + output_replacement.getItemString() << " because drop loop didn't " + "decrease count." << std::endl; + + break; + } + } while (!output_replacement.empty()); + } + + infostream<<"ICraftAction::apply(): crafted " + <<" craft_inv=\""<<craft_inv.dump()<<"\"" + <<std::endl; +} + +void ICraftAction::clientApply(InventoryManager *mgr, IGameDef *gamedef) +{ + // Optional InventoryAction operation that is run on the client + // to make lag less apparent. +} + + +// Crafting helper +bool getCraftingResult(Inventory *inv, ItemStack &result, + std::vector<ItemStack> &output_replacements, + bool decrementInput, IGameDef *gamedef) +{ + result.clear(); + + // Get the InventoryList in which we will operate + InventoryList *clist = inv->getList("craft"); + if (!clist) + return false; + + // Mangle crafting grid to an another format + CraftInput ci; + ci.method = CRAFT_METHOD_NORMAL; + ci.width = clist->getWidth() ? clist->getWidth() : 3; + for (u16 i=0; i < clist->getSize(); i++) + ci.items.push_back(clist->getItem(i)); + + // Find out what is crafted and add it to result item slot + CraftOutput co; + bool found = gamedef->getCraftDefManager()->getCraftResult( + ci, co, output_replacements, decrementInput, gamedef); + if (found) + result.deSerialize(co.item, gamedef->getItemDefManager()); + + if (found && decrementInput) { + // CraftInput has been changed, apply changes in clist + for (u16 i=0; i < clist->getSize(); i++) { + clist->changeItem(i, ci.items[i]); + } + } + + return found; +} + diff --git a/src/inventorymanager.h b/src/inventorymanager.h new file mode 100644 index 0000000..4ad5d3f --- /dev/null +++ b/src/inventorymanager.h @@ -0,0 +1,258 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "inventory.h" +#include <iostream> +#include <string> +class ServerActiveObject; + +struct InventoryLocation +{ + enum Type{ + UNDEFINED, + CURRENT_PLAYER, + PLAYER, + NODEMETA, + DETACHED, + } type; + + std::string name; // PLAYER, DETACHED + v3s16 p; // NODEMETA + + InventoryLocation() + { + setUndefined(); + } + void setUndefined() + { + type = UNDEFINED; + } + void setCurrentPlayer() + { + type = CURRENT_PLAYER; + } + void setPlayer(const std::string &name_) + { + type = PLAYER; + name = name_; + } + void setNodeMeta(const v3s16 &p_) + { + type = NODEMETA; + p = p_; + } + void setDetached(const std::string &name_) + { + type = DETACHED; + name = name_; + } + + bool operator==(const InventoryLocation &other) const + { + if(type != other.type) + return false; + switch(type){ + case UNDEFINED: + return false; + case CURRENT_PLAYER: + return true; + case PLAYER: + return (name == other.name); + case NODEMETA: + return (p == other.p); + case DETACHED: + return (name == other.name); + } + return false; + } + bool operator!=(const InventoryLocation &other) const + { + return !(*this == other); + } + + void applyCurrentPlayer(const std::string &name_) + { + if(type == CURRENT_PLAYER) + setPlayer(name_); + } + + std::string dump() const; + void serialize(std::ostream &os) const; + void deSerialize(std::istream &is); + void deSerialize(const std::string &s); +}; + +struct InventoryAction; + +class InventoryManager +{ +public: + InventoryManager() = default; + virtual ~InventoryManager() = default; + + // Get an inventory (server and client) + virtual Inventory* getInventory(const InventoryLocation &loc){return NULL;} + // Set modified (will be saved and sent over network; only on server) + virtual void setInventoryModified(const InventoryLocation &loc) {} + // Send inventory action to server (only on client) + virtual void inventoryAction(InventoryAction *a){} +}; + +enum class IAction : u16 { + Move, + Drop, + Craft +}; + +struct InventoryAction +{ + static InventoryAction *deSerialize(std::istream &is); + + virtual IAction getType() const = 0; + virtual void serialize(std::ostream &os) const = 0; + virtual void apply(InventoryManager *mgr, ServerActiveObject *player, + IGameDef *gamedef) = 0; + virtual void clientApply(InventoryManager *mgr, IGameDef *gamedef) = 0; + virtual ~InventoryAction() = default;; +}; + +struct MoveAction +{ + InventoryLocation from_inv; + std::string from_list; + s16 from_i = -1; + InventoryLocation to_inv; + std::string to_list; + s16 to_i = -1; +}; + +struct IMoveAction : public InventoryAction, public MoveAction +{ + // count=0 means "everything" + u16 count = 0; + bool move_somewhere = false; + + // treat these as private + // related to movement to somewhere + bool caused_by_move_somewhere = false; + u32 move_count = 0; + + IMoveAction() = default; + + IMoveAction(std::istream &is, bool somewhere); + + IAction getType() const + { + return IAction::Move; + } + + void serialize(std::ostream &os) const + { + if (!move_somewhere) + os << "Move "; + else + os << "MoveSomewhere "; + os << count << " "; + os << from_inv.dump() << " "; + os << from_list << " "; + os << from_i << " "; + os << to_inv.dump() << " "; + os << to_list; + if (!move_somewhere) + os << " " << to_i; + } + + void apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef); + + void clientApply(InventoryManager *mgr, IGameDef *gamedef); + + void swapDirections(); + + void onPutAndOnTake(const ItemStack &src_item, ServerActiveObject *player) const; + + void onMove(int count, ServerActiveObject *player) const; + + int allowPut(const ItemStack &dst_item, ServerActiveObject *player) const; + + int allowTake(const ItemStack &src_item, ServerActiveObject *player) const; + + int allowMove(int try_take_count, ServerActiveObject *player) const; +}; + +struct IDropAction : public InventoryAction, public MoveAction +{ + // count=0 means "everything" + u16 count = 0; + + IDropAction() = default; + + IDropAction(std::istream &is); + + IAction getType() const + { + return IAction::Drop; + } + + void serialize(std::ostream &os) const + { + os<<"Drop "; + os<<count<<" "; + os<<from_inv.dump()<<" "; + os<<from_list<<" "; + os<<from_i; + } + + void apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef); + + void clientApply(InventoryManager *mgr, IGameDef *gamedef); +}; + +struct ICraftAction : public InventoryAction +{ + // count=0 means "everything" + u16 count = 0; + InventoryLocation craft_inv; + + ICraftAction() = default; + + ICraftAction(std::istream &is); + + IAction getType() const + { + return IAction::Craft; + } + + void serialize(std::ostream &os) const + { + os<<"Craft "; + os<<count<<" "; + os<<craft_inv.dump()<<" "; + } + + void apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef); + + void clientApply(InventoryManager *mgr, IGameDef *gamedef); +}; + +// Crafting helper +bool getCraftingResult(Inventory *inv, ItemStack &result, + std::vector<ItemStack> &output_replacements, + bool decrementInput, IGameDef *gamedef); diff --git a/src/irr_aabb3d.h b/src/irr_aabb3d.h new file mode 100644 index 0000000..73bb2db --- /dev/null +++ b/src/irr_aabb3d.h @@ -0,0 +1,26 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" + +#include <aabbox3d.h> + +typedef core::aabbox3d<f32> aabb3f; diff --git a/src/irr_ptr.h b/src/irr_ptr.h new file mode 100644 index 0000000..42b4096 --- /dev/null +++ b/src/irr_ptr.h @@ -0,0 +1,200 @@ +/* +Minetest +Copyright (C) 2018 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include <type_traits> +#include "irrlichttypes.h" +#include "IReferenceCounted.h" + +/** Shared pointer for IrrLicht objects. + * + * It should only be used for user-managed objects, i.e. those created with + * the @c new operator or @c create* functions, like: + * `irr_ptr<scene::IMeshBuffer> buf{new scene::SMeshBuffer()};` + * The reference counting is *not* balanced as new objects have reference + * count set to one, and the @c irr_ptr constructor (and @c reset) assumes + * ownership of that reference. + * + * It shouldn’t be used for engine-managed objects, including those created + * with @c addTexture and similar methods. Constructing @c irr_ptr directly + * from such object is a bug and may lead to a crash. Indirect construction + * is possible though; see the @c grab free function for details and use cases. + */ +template <class ReferenceCounted, + class = typename std::enable_if<std::is_base_of<IReferenceCounted, + ReferenceCounted>::value>::type> +class irr_ptr +{ + ReferenceCounted *value = nullptr; + +public: + irr_ptr() {} + + irr_ptr(std::nullptr_t) noexcept {} + + irr_ptr(const irr_ptr &b) noexcept { grab(b.get()); } + + irr_ptr(irr_ptr &&b) noexcept { reset(b.release()); } + + template <typename B, class = typename std::enable_if<std::is_convertible<B *, + ReferenceCounted *>::value>::type> + irr_ptr(const irr_ptr<B> &b) noexcept + { + grab(b.get()); + } + + template <typename B, class = typename std::enable_if<std::is_convertible<B *, + ReferenceCounted *>::value>::type> + irr_ptr(irr_ptr<B> &&b) noexcept + { + reset(b.release()); + } + + /** Constructs a shared pointer out of a plain one to control object lifetime. + * @param object The object, usually returned by some @c create* function. + * @note Move semantics: reference counter is *not* increased. + * @warning Never wrap any @c add* function with this! + */ + explicit irr_ptr(ReferenceCounted *object) noexcept { reset(object); } + + ~irr_ptr() { reset(); } + + irr_ptr &operator=(const irr_ptr &b) noexcept + { + grab(b.get()); + return *this; + } + + irr_ptr &operator=(irr_ptr &&b) noexcept + { + reset(b.release()); + return *this; + } + + template <typename B, class = typename std::enable_if<std::is_convertible<B *, + ReferenceCounted *>::value>::type> + irr_ptr &operator=(const irr_ptr<B> &b) noexcept + { + grab(b.get()); + return *this; + } + + template <typename B, class = typename std::enable_if<std::is_convertible<B *, + ReferenceCounted *>::value>::type> + irr_ptr &operator=(irr_ptr<B> &&b) noexcept + { + reset(b.release()); + return *this; + } + + ReferenceCounted &operator*() const noexcept { return *value; } + ReferenceCounted *operator->() const noexcept { return value; } + explicit operator ReferenceCounted *() const noexcept { return value; } + explicit operator bool() const noexcept { return !!value; } + + /** Returns the stored pointer. + */ + ReferenceCounted *get() const noexcept { return value; } + + /** Returns the stored pointer, erasing it from this class. + * @note Move semantics: reference counter is not changed. + */ + ReferenceCounted *release() noexcept + { + ReferenceCounted *object = value; + value = nullptr; + return object; + } + + /** Drops stored pointer replacing it with the given one. + * @note Move semantics: reference counter is *not* increased. + */ + void reset(ReferenceCounted *object = nullptr) noexcept + { + if (value) + value->drop(); + value = object; + } + + /** Drops stored pointer replacing it with the given one. + * @note Copy semantics: reference counter *is* increased. + */ + void grab(ReferenceCounted *object) noexcept + { + if (object) + object->grab(); + reset(object); + } +}; + +// clang-format off +// ^ dislikes long lines + +/** Constructs a shared pointer as a *secondary* reference to an object + * + * This function is intended to make a temporary reference to an object which + * is owned elsewhere so that it is not destroyed too early. To acheive that + * it does balanced reference counting, i.e. reference count is increased + * in this function and decreased when the returned pointer is destroyed. + */ +template <class ReferenceCounted> +irr_ptr<ReferenceCounted> grab(ReferenceCounted *object) noexcept +{ + irr_ptr<ReferenceCounted> ptr; + ptr.grab(object); + return ptr; +} + +template <typename ReferenceCounted> +bool operator==(const irr_ptr<ReferenceCounted> &a, const irr_ptr<ReferenceCounted> &b) noexcept +{ + return a.get() == b.get(); +} + +template <typename ReferenceCounted> +bool operator==(const irr_ptr<ReferenceCounted> &a, const ReferenceCounted *b) noexcept +{ + return a.get() == b; +} + +template <typename ReferenceCounted> +bool operator==(const ReferenceCounted *a, const irr_ptr<ReferenceCounted> &b) noexcept +{ + return a == b.get(); +} + +template <typename ReferenceCounted> +bool operator!=(const irr_ptr<ReferenceCounted> &a, const irr_ptr<ReferenceCounted> &b) noexcept +{ + return a.get() != b.get(); +} + +template <typename ReferenceCounted> +bool operator!=(const irr_ptr<ReferenceCounted> &a, const ReferenceCounted *b) noexcept +{ + return a.get() != b; +} + +template <typename ReferenceCounted> +bool operator!=(const ReferenceCounted *a, const irr_ptr<ReferenceCounted> &b) noexcept +{ + return a != b.get(); +} + +// clang-format on diff --git a/src/irr_v2d.h b/src/irr_v2d.h new file mode 100644 index 0000000..a906576 --- /dev/null +++ b/src/irr_v2d.h @@ -0,0 +1,30 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" + +#include <vector2d.h> + +typedef core::vector2d<f32> v2f; +typedef core::vector2d<s16> v2s16; +typedef core::vector2d<s32> v2s32; +typedef core::vector2d<u32> v2u32; +typedef core::vector2d<f32> v2f32; diff --git a/src/irr_v3d.h b/src/irr_v3d.h new file mode 100644 index 0000000..3e95c79 --- /dev/null +++ b/src/irr_v3d.h @@ -0,0 +1,30 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" + +#include <vector3d.h> + +typedef core::vector3df v3f; +typedef core::vector3d<double> v3d; +typedef core::vector3d<s16> v3s16; +typedef core::vector3d<u16> v3u16; +typedef core::vector3d<s32> v3s32; diff --git a/src/irrlicht_changes/CGUITTFont.cpp b/src/irrlicht_changes/CGUITTFont.cpp new file mode 100644 index 0000000..53be273 --- /dev/null +++ b/src/irrlicht_changes/CGUITTFont.cpp @@ -0,0 +1,1244 @@ +/* + CGUITTFont FreeType class for Irrlicht + Copyright (c) 2009-2010 John Norman + Copyright (c) 2016 Nathanaëlle Courant + + 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. + + The original version of this class can be located at: + http://irrlicht.suckerfreegames.com/ + + John Norman + john@suckerfreegames.com +*/ + +#include <irrlicht.h> +#include <iostream> +#include "CGUITTFont.h" + +namespace irr +{ +namespace gui +{ + +// Manages the FT_Face cache. +struct SGUITTFace : public virtual irr::IReferenceCounted +{ + SGUITTFace() : face_buffer(0), face_buffer_size(0) + { + memset((void*)&face, 0, sizeof(FT_Face)); + } + + ~SGUITTFace() + { + FT_Done_Face(face); + delete[] face_buffer; + } + + FT_Face face; + FT_Byte* face_buffer; + FT_Long face_buffer_size; +}; + +// Static variables. +FT_Library CGUITTFont::c_library; +std::map<io::path, SGUITTFace*> CGUITTFont::c_faces; +bool CGUITTFont::c_libraryLoaded = false; +scene::IMesh* CGUITTFont::shared_plane_ptr_ = 0; +scene::SMesh CGUITTFont::shared_plane_; + +// + +/** Checks that no dimension of the FT_BitMap object is negative. If either is + * negative, abort execution. + */ +inline void checkFontBitmapSize(const FT_Bitmap &bits) +{ + if ((s32)bits.rows < 0 || (s32)bits.width < 0) { + std::cout << "Insane font glyph size. File: " + << __FILE__ << " Line " << __LINE__ + << std::endl; + abort(); + } +} + +video::IImage* SGUITTGlyph::createGlyphImage(const FT_Bitmap& bits, video::IVideoDriver* driver) const +{ + // Make sure our casts to s32 in the loops below will not cause problems + checkFontBitmapSize(bits); + + // Determine what our texture size should be. + // Add 1 because textures are inclusive-exclusive. + core::dimension2du d(bits.width + 1, bits.rows + 1); + core::dimension2du texture_size; + //core::dimension2du texture_size(bits.width + 1, bits.rows + 1); + + // Create and load our image now. + video::IImage* image = 0; + switch (bits.pixel_mode) + { + case FT_PIXEL_MODE_MONO: + { + // Create a blank image and fill it with transparent pixels. + texture_size = d.getOptimalSize(true, true); + image = driver->createImage(video::ECF_A1R5G5B5, texture_size); + image->fill(video::SColor(0, 255, 255, 255)); + + // Load the monochrome data in. + const u32 image_pitch = image->getPitch() / sizeof(u16); + u16* image_data = (u16*)image->getData(); + u8* glyph_data = bits.buffer; + + for (s32 y = 0; y < (s32)bits.rows; ++y) + { + u16* row = image_data; + for (s32 x = 0; x < (s32)bits.width; ++x) + { + // Monochrome bitmaps store 8 pixels per byte. The left-most pixel is the bit 0x80. + // So, we go through the data each bit at a time. + if ((glyph_data[y * bits.pitch + (x / 8)] & (0x80 >> (x % 8))) != 0) + *row = 0xFFFF; + ++row; + } + image_data += image_pitch; + } + break; + } + + case FT_PIXEL_MODE_GRAY: + { + // Create our blank image. + texture_size = d.getOptimalSize(!driver->queryFeature(video::EVDF_TEXTURE_NPOT), !driver->queryFeature(video::EVDF_TEXTURE_NSQUARE), true, 0); + image = driver->createImage(video::ECF_A8R8G8B8, texture_size); + image->fill(video::SColor(0, 255, 255, 255)); + + // Load the grayscale data in. + const float gray_count = static_cast<float>(bits.num_grays); + const u32 image_pitch = image->getPitch() / sizeof(u32); + u32* image_data = (u32*)image->getData(); + u8* glyph_data = bits.buffer; + for (s32 y = 0; y < (s32)bits.rows; ++y) + { + u8* row = glyph_data; + for (s32 x = 0; x < (s32)bits.width; ++x) + { + image_data[y * image_pitch + x] |= static_cast<u32>(255.0f * (static_cast<float>(*row++) / gray_count)) << 24; + //data[y * image_pitch + x] |= ((u32)(*bitsdata++) << 24); + } + glyph_data += bits.pitch; + } + break; + } + default: + // TODO: error message? + return 0; + } + return image; +} + +void SGUITTGlyph::preload(u32 char_index, FT_Face face, video::IVideoDriver* driver, u32 font_size, const FT_Int32 loadFlags) +{ + if (isLoaded) return; + + // Set the size of the glyph. + FT_Set_Pixel_Sizes(face, 0, font_size); + + // Attempt to load the glyph. + if (FT_Load_Glyph(face, char_index, loadFlags) != FT_Err_Ok) + // TODO: error message? + return; + + FT_GlyphSlot glyph = face->glyph; + FT_Bitmap bits = glyph->bitmap; + + // Setup the glyph information here: + advance = glyph->advance; + offset = core::vector2di(glyph->bitmap_left, glyph->bitmap_top); + + // Try to get the last page with available slots. + CGUITTGlyphPage* page = parent->getLastGlyphPage(); + + // If we need to make a new page, do that now. + if (!page) + { + page = parent->createGlyphPage(bits.pixel_mode); + if (!page) + // TODO: add error message? + return; + } + + glyph_page = parent->getLastGlyphPageIndex(); + u32 texture_side_length = page->texture->getOriginalSize().Width; + core::vector2di page_position( + (page->used_slots % (texture_side_length / font_size)) * font_size, + (page->used_slots / (texture_side_length / font_size)) * font_size + ); + source_rect.UpperLeftCorner = page_position; + source_rect.LowerRightCorner = core::vector2di(page_position.X + bits.width, page_position.Y + bits.rows); + + page->dirty = true; + ++page->used_slots; + --page->available_slots; + + // We grab the glyph bitmap here so the data won't be removed when the next glyph is loaded. + surface = createGlyphImage(bits, driver); + + // Set our glyph as loaded. + isLoaded = true; +} + +void SGUITTGlyph::unload() +{ + if (surface) + { + surface->drop(); + surface = 0; + } + isLoaded = false; +} + +////////////////////// + +CGUITTFont* CGUITTFont::createTTFont(IGUIEnvironment *env, const io::path& filename, const u32 size, const bool antialias, const bool transparency, const u32 shadow, const u32 shadow_alpha) +{ + if (!c_libraryLoaded) + { + if (FT_Init_FreeType(&c_library)) + return 0; + c_libraryLoaded = true; + } + + CGUITTFont* font = new CGUITTFont(env); + bool ret = font->load(filename, size, antialias, transparency); + if (!ret) + { + font->drop(); + return 0; + } + + font->shadow_offset = shadow; + font->shadow_alpha = shadow_alpha; + + return font; +} + +CGUITTFont* CGUITTFont::createTTFont(IrrlichtDevice *device, const io::path& filename, const u32 size, const bool antialias, const bool transparency) +{ + if (!c_libraryLoaded) + { + if (FT_Init_FreeType(&c_library)) + return 0; + c_libraryLoaded = true; + } + + CGUITTFont* font = new CGUITTFont(device->getGUIEnvironment()); + font->Device = device; + bool ret = font->load(filename, size, antialias, transparency); + if (!ret) + { + font->drop(); + return 0; + } + + return font; +} + +CGUITTFont* CGUITTFont::create(IGUIEnvironment *env, const io::path& filename, const u32 size, const bool antialias, const bool transparency) +{ + return CGUITTFont::createTTFont(env, filename, size, antialias, transparency); +} + +CGUITTFont* CGUITTFont::create(IrrlichtDevice *device, const io::path& filename, const u32 size, const bool antialias, const bool transparency) +{ + return CGUITTFont::createTTFont(device, filename, size, antialias, transparency); +} + +////////////////////// + +//! Constructor. +CGUITTFont::CGUITTFont(IGUIEnvironment *env) +: use_monochrome(false), use_transparency(true), use_hinting(true), use_auto_hinting(true), +batch_load_size(1), Device(0), Environment(env), Driver(0), GlobalKerningWidth(0), GlobalKerningHeight(0), +shadow_offset(0), shadow_alpha(0), fallback(0) +{ + #ifdef _DEBUG + setDebugName("CGUITTFont"); + #endif + + if (Environment) + { + // don't grab environment, to avoid circular references + Driver = Environment->getVideoDriver(); + } + + if (Driver) + Driver->grab(); + + setInvisibleCharacters(L" "); +} + +bool CGUITTFont::load(const io::path& filename, const u32 size, const bool antialias, const bool transparency) +{ + // Some sanity checks. + if (Environment == 0 || Driver == 0) return false; + if (size == 0) return false; + if (filename.size() == 0) return false; + + io::IFileSystem* filesystem = Environment->getFileSystem(); + irr::ILogger* logger = (Device != 0 ? Device->getLogger() : 0); + this->size = size; + this->filename = filename; + + // Update the font loading flags when the font is first loaded. + this->use_monochrome = !antialias; + this->use_transparency = transparency; + update_load_flags(); + + // Log. + if (logger) + logger->log(L"CGUITTFont", core::stringw(core::stringw(L"Creating new font: ") + core::ustring(filename).toWCHAR_s() + L" " + core::stringc(size) + L"pt " + (antialias ? L"+antialias " : L"-antialias ") + (transparency ? L"+transparency" : L"-transparency")).c_str(), irr::ELL_INFORMATION); + + // Grab the face. + SGUITTFace* face = 0; + auto node = c_faces.find(filename); + if (node == c_faces.end()) + { + face = new SGUITTFace(); + c_faces.emplace(filename, face); + + if (filesystem) + { + // Read in the file data. + io::IReadFile* file = filesystem->createAndOpenFile(filename); + if (file == 0) + { + if (logger) logger->log(L"CGUITTFont", L"Failed to open the file.", irr::ELL_INFORMATION); + + c_faces.erase(filename); + delete face; + face = 0; + return false; + } + face->face_buffer = new FT_Byte[file->getSize()]; + file->read(face->face_buffer, file->getSize()); + face->face_buffer_size = file->getSize(); + file->drop(); + + // Create the face. + if (FT_New_Memory_Face(c_library, face->face_buffer, face->face_buffer_size, 0, &face->face)) + { + if (logger) logger->log(L"CGUITTFont", L"FT_New_Memory_Face failed.", irr::ELL_INFORMATION); + + c_faces.erase(filename); + delete face; + face = 0; + return false; + } + } + else + { + core::ustring converter(filename); + if (FT_New_Face(c_library, reinterpret_cast<const char*>(converter.toUTF8_s().c_str()), 0, &face->face)) + { + if (logger) logger->log(L"CGUITTFont", L"FT_New_Face failed.", irr::ELL_INFORMATION); + + c_faces.erase(filename); + delete face; + face = 0; + return false; + } + } + } + else + { + // Using another instance of this face. + face = node->second; + face->grab(); + } + + // Store our face. + tt_face = face->face; + + // Store font metrics. + FT_Set_Pixel_Sizes(tt_face, size, 0); + font_metrics = tt_face->size->metrics; + + // Allocate our glyphs. + Glyphs.clear(); + Glyphs.reallocate(tt_face->num_glyphs); + Glyphs.set_used(tt_face->num_glyphs); + for (FT_Long i = 0; i < tt_face->num_glyphs; ++i) + { + Glyphs[i].isLoaded = false; + Glyphs[i].glyph_page = 0; + Glyphs[i].source_rect = core::recti(); + Glyphs[i].offset = core::vector2di(); + Glyphs[i].advance = FT_Vector(); + Glyphs[i].surface = 0; + Glyphs[i].parent = this; + } + + // Cache the first 127 ascii characters. + u32 old_size = batch_load_size; + batch_load_size = 127; + getGlyphIndexByChar((uchar32_t)0); + batch_load_size = old_size; + + return true; +} + +CGUITTFont::~CGUITTFont() +{ + // Delete the glyphs and glyph pages. + reset_images(); + Glyphs.clear(); + + // We aren't using this face anymore. + auto n = c_faces.find(filename); + if (n != c_faces.end()) + { + SGUITTFace* f = n->second; + + // Drop our face. If this was the last face, the destructor will clean up. + if (f->drop()) + c_faces.erase(filename); + + // If there are no more faces referenced by FreeType, clean up. + if (c_faces.empty()) + { + FT_Done_FreeType(c_library); + c_libraryLoaded = false; + } + } + + // Drop our driver now. + if (Driver) + Driver->drop(); +} + +void CGUITTFont::reset_images() +{ + // Delete the glyphs. + for (u32 i = 0; i != Glyphs.size(); ++i) + Glyphs[i].unload(); + + // Unload the glyph pages from video memory. + for (u32 i = 0; i != Glyph_Pages.size(); ++i) + delete Glyph_Pages[i]; + Glyph_Pages.clear(); + + // Always update the internal FreeType loading flags after resetting. + update_load_flags(); +} + +void CGUITTFont::update_glyph_pages() const +{ + for (u32 i = 0; i != Glyph_Pages.size(); ++i) + { + if (Glyph_Pages[i]->dirty) + Glyph_Pages[i]->updateTexture(); + } +} + +CGUITTGlyphPage* CGUITTFont::getLastGlyphPage() const +{ + CGUITTGlyphPage* page = 0; + if (Glyph_Pages.empty()) + return 0; + else + { + page = Glyph_Pages[getLastGlyphPageIndex()]; + if (page->available_slots == 0) + page = 0; + } + return page; +} + +CGUITTGlyphPage* CGUITTFont::createGlyphPage(const u8& pixel_mode) +{ + CGUITTGlyphPage* page = 0; + + // Name of our page. + io::path name("TTFontGlyphPage_"); + name += tt_face->family_name; + name += "."; + name += tt_face->style_name; + name += "."; + name += size; + name += "_"; + name += Glyph_Pages.size(); // The newly created page will be at the end of the collection. + + // Create the new page. + page = new CGUITTGlyphPage(Driver, name); + + // Determine our maximum texture size. + // If we keep getting 0, set it to 1024x1024, as that number is pretty safe. + core::dimension2du max_texture_size = max_page_texture_size; + if (max_texture_size.Width == 0 || max_texture_size.Height == 0) + max_texture_size = Driver->getMaxTextureSize(); + if (max_texture_size.Width == 0 || max_texture_size.Height == 0) + max_texture_size = core::dimension2du(1024, 1024); + + // We want to try to put at least 144 glyphs on a single texture. + core::dimension2du page_texture_size; + if (size <= 21) page_texture_size = core::dimension2du(256, 256); + else if (size <= 42) page_texture_size = core::dimension2du(512, 512); + else if (size <= 84) page_texture_size = core::dimension2du(1024, 1024); + else if (size <= 168) page_texture_size = core::dimension2du(2048, 2048); + else page_texture_size = core::dimension2du(4096, 4096); + + if (page_texture_size.Width > max_texture_size.Width || page_texture_size.Height > max_texture_size.Height) + page_texture_size = max_texture_size; + + if (!page->createPageTexture(pixel_mode, page_texture_size)) { + // TODO: add error message? + delete page; + return 0; + } + + if (page) + { + // Determine the number of glyph slots on the page and add it to the list of pages. + page->available_slots = (page_texture_size.Width / size) * (page_texture_size.Height / size); + Glyph_Pages.push_back(page); + } + return page; +} + +void CGUITTFont::setTransparency(const bool flag) +{ + use_transparency = flag; + reset_images(); +} + +void CGUITTFont::setMonochrome(const bool flag) +{ + use_monochrome = flag; + reset_images(); +} + +void CGUITTFont::setFontHinting(const bool enable, const bool enable_auto_hinting) +{ + use_hinting = enable; + use_auto_hinting = enable_auto_hinting; + reset_images(); +} + +void CGUITTFont::draw(const core::stringw& text, const core::rect<s32>& position, video::SColor color, bool hcenter, bool vcenter, const core::rect<s32>* clip) +{ + draw(EnrichedString(std::wstring(text.c_str()), color), position, hcenter, vcenter, clip); +} + +void CGUITTFont::draw(const EnrichedString &text, const core::rect<s32>& position, bool hcenter, bool vcenter, const core::rect<s32>* clip) +{ + const std::vector<video::SColor> &colors = text.getColors(); + + if (!Driver) + return; + + // Clear the glyph pages of their render information. + for (u32 i = 0; i < Glyph_Pages.size(); ++i) + { + Glyph_Pages[i]->render_positions.clear(); + Glyph_Pages[i]->render_source_rects.clear(); + Glyph_Pages[i]->render_colors.clear(); + } + + // Set up some variables. + core::dimension2d<s32> textDimension; + core::position2d<s32> offset = position.UpperLeftCorner; + + // Determine offset positions. + if (hcenter || vcenter) + { + textDimension = getDimension(text.c_str()); + + if (hcenter) + offset.X = ((position.getWidth() - textDimension.Width) >> 1) + offset.X; + + if (vcenter) + offset.Y = ((position.getHeight() - textDimension.Height) >> 1) + offset.Y; + } + + // Convert to a unicode string. + core::ustring utext = text.getString(); + + // Set up our render map. + std::map<u32, CGUITTGlyphPage*> Render_Map; + + // Start parsing characters. + u32 n; + uchar32_t previousChar = 0; + core::ustring::const_iterator iter(utext); + while (!iter.atEnd()) + { + uchar32_t currentChar = *iter; + n = getGlyphIndexByChar(currentChar); + bool visible = (Invisible.findFirst(currentChar) == -1); + bool lineBreak=false; + if (currentChar == L'\r') // Mac or Windows breaks + { + lineBreak = true; + if (*(iter + 1) == (uchar32_t)'\n') // Windows line breaks. + currentChar = *(++iter); + } + else if (currentChar == (uchar32_t)'\n') // Unix breaks + { + lineBreak = true; + } + + if (lineBreak) + { + previousChar = 0; + offset.Y += font_metrics.height / 64; + offset.X = position.UpperLeftCorner.X; + + if (hcenter) + offset.X += (position.getWidth() - textDimension.Width) >> 1; + ++iter; + continue; + } + + if (n > 0 && visible) + { + // Calculate the glyph offset. + s32 offx = Glyphs[n-1].offset.X; + s32 offy = (font_metrics.ascender / 64) - Glyphs[n-1].offset.Y; + + // Apply kerning. + core::vector2di k = getKerning(currentChar, previousChar); + offset.X += k.X; + offset.Y += k.Y; + + // Determine rendering information. + SGUITTGlyph& glyph = Glyphs[n-1]; + CGUITTGlyphPage* const page = Glyph_Pages[glyph.glyph_page]; + page->render_positions.push_back(core::position2di(offset.X + offx, offset.Y + offy)); + page->render_source_rects.push_back(glyph.source_rect); + if (iter.getPos() < colors.size()) + page->render_colors.push_back(colors[iter.getPos()]); + else + page->render_colors.push_back(video::SColor(255,255,255,255)); + Render_Map[glyph.glyph_page] = page; + } + if (n > 0) + { + offset.X += getWidthFromCharacter(currentChar); + } + else if (fallback != 0) + { + // Let the fallback font draw it, this isn't super efficient but hopefully that doesn't matter + wchar_t l1[] = { (wchar_t) currentChar, 0 }, l2 = (wchar_t) previousChar; + + if (visible) + { + // Apply kerning. + offset.X += fallback->getKerningWidth(l1, &l2); + offset.Y += fallback->getKerningHeight(); + + u32 current_color = iter.getPos(); + fallback->draw(core::stringw(l1), + core::rect<s32>({offset.X-1, offset.Y-1}, position.LowerRightCorner), // ??? + current_color < colors.size() ? colors[current_color] : video::SColor(255, 255, 255, 255), + false, false, clip); + } + + offset.X += fallback->getDimension(l1).Width; + } + + previousChar = currentChar; + ++iter; + } + + // Draw now. + update_glyph_pages(); + auto it = Render_Map.begin(); + auto ie = Render_Map.end(); + core::array<core::vector2di> tmp_positions; + core::array<core::recti> tmp_source_rects; + while (it != ie) + { + CGUITTGlyphPage* page = it->second; + ++it; + + if (shadow_offset) { + for (size_t i = 0; i < page->render_positions.size(); ++i) + page->render_positions[i] += core::vector2di(shadow_offset, shadow_offset); + Driver->draw2DImageBatch(page->texture, page->render_positions, page->render_source_rects, clip, video::SColor(shadow_alpha,0,0,0), true); + for (size_t i = 0; i < page->render_positions.size(); ++i) + page->render_positions[i] -= core::vector2di(shadow_offset, shadow_offset); + } + // render runs of matching color in batch + size_t ibegin; + video::SColor colprev; + for (size_t i = 0; i < page->render_positions.size(); ++i) { + ibegin = i; + colprev = page->render_colors[i]; + do + ++i; + while (i < page->render_positions.size() && page->render_colors[i] == colprev); + tmp_positions.set_data(&page->render_positions[ibegin], i - ibegin); + tmp_source_rects.set_data(&page->render_source_rects[ibegin], i - ibegin); + --i; + + if (!use_transparency) + colprev.color |= 0xff000000; + Driver->draw2DImageBatch(page->texture, tmp_positions, tmp_source_rects, clip, colprev, true); + } + } +} + +core::dimension2d<u32> CGUITTFont::getCharDimension(const wchar_t ch) const +{ + return core::dimension2d<u32>(getWidthFromCharacter(ch), getHeightFromCharacter(ch)); +} + +core::dimension2d<u32> CGUITTFont::getDimension(const wchar_t* text) const +{ + return getDimension(core::ustring(text)); +} + +core::dimension2d<u32> CGUITTFont::getDimension(const core::ustring& text) const +{ + // Get the maximum font height. Unfortunately, we have to do this hack as + // Irrlicht will draw things wrong. In FreeType, the font size is the + // maximum size for a single glyph, but that glyph may hang "under" the + // draw line, increasing the total font height to beyond the set size. + // Irrlicht does not understand this concept when drawing fonts. Also, I + // add +1 to give it a 1 pixel blank border. This makes things like + // tooltips look nicer. + s32 test1 = getHeightFromCharacter((uchar32_t)'g') + 1; + s32 test2 = getHeightFromCharacter((uchar32_t)'j') + 1; + s32 test3 = getHeightFromCharacter((uchar32_t)'_') + 1; + s32 max_font_height = core::max_(test1, core::max_(test2, test3)); + + core::dimension2d<u32> text_dimension(0, max_font_height); + core::dimension2d<u32> line(0, max_font_height); + + uchar32_t previousChar = 0; + core::ustring::const_iterator iter = text.begin(); + for (; !iter.atEnd(); ++iter) + { + uchar32_t p = *iter; + bool lineBreak = false; + if (p == '\r') // Mac or Windows line breaks. + { + lineBreak = true; + if (*(iter + 1) == '\n') + { + ++iter; + p = *iter; + } + } + else if (p == '\n') // Unix line breaks. + { + lineBreak = true; + } + + // Kerning. + core::vector2di k = getKerning(p, previousChar); + line.Width += k.X; + previousChar = p; + + // Check for linebreak. + if (lineBreak) + { + previousChar = 0; + text_dimension.Height += line.Height; + if (text_dimension.Width < line.Width) + text_dimension.Width = line.Width; + line.Width = 0; + line.Height = max_font_height; + continue; + } + line.Width += getWidthFromCharacter(p); + } + if (text_dimension.Width < line.Width) + text_dimension.Width = line.Width; + + return text_dimension; +} + +inline u32 CGUITTFont::getWidthFromCharacter(wchar_t c) const +{ + return getWidthFromCharacter((uchar32_t)c); +} + +inline u32 CGUITTFont::getWidthFromCharacter(uchar32_t c) const +{ + // Set the size of the face. + // This is because we cache faces and the face may have been set to a different size. + //FT_Set_Pixel_Sizes(tt_face, 0, size); + + u32 n = getGlyphIndexByChar(c); + if (n > 0) + { + int w = Glyphs[n-1].advance.x / 64; + return w; + } + if (fallback != 0) + { + wchar_t s[] = { (wchar_t) c, 0 }; + return fallback->getDimension(s).Width; + } + + if (c >= 0x2000) + return (font_metrics.ascender / 64); + else return (font_metrics.ascender / 64) / 2; +} + +inline u32 CGUITTFont::getHeightFromCharacter(wchar_t c) const +{ + return getHeightFromCharacter((uchar32_t)c); +} + +inline u32 CGUITTFont::getHeightFromCharacter(uchar32_t c) const +{ + // Set the size of the face. + // This is because we cache faces and the face may have been set to a different size. + //FT_Set_Pixel_Sizes(tt_face, 0, size); + + u32 n = getGlyphIndexByChar(c); + if (n > 0) + { + // Grab the true height of the character, taking into account underhanging glyphs. + s32 height = (font_metrics.ascender / 64) - Glyphs[n-1].offset.Y + Glyphs[n-1].source_rect.getHeight(); + return height; + } + if (fallback != 0) + { + wchar_t s[] = { (wchar_t) c, 0 }; + return fallback->getDimension(s).Height; + } + + if (c >= 0x2000) + return (font_metrics.ascender / 64); + else return (font_metrics.ascender / 64) / 2; +} + +u32 CGUITTFont::getGlyphIndexByChar(wchar_t c) const +{ + return getGlyphIndexByChar((uchar32_t)c); +} + +u32 CGUITTFont::getGlyphIndexByChar(uchar32_t c) const +{ + // Get the glyph. + u32 glyph = FT_Get_Char_Index(tt_face, c); + + // Check for a valid glyph. + if (glyph == 0) + return 0; + + // If our glyph is already loaded, don't bother doing any batch loading code. + if (glyph != 0 && Glyphs[glyph - 1].isLoaded) + return glyph; + + // Determine our batch loading positions. + u32 half_size = (batch_load_size / 2); + u32 start_pos = 0; + if (c > half_size) start_pos = c - half_size; + u32 end_pos = start_pos + batch_load_size; + + // Load all our characters. + do + { + // Get the character we are going to load. + u32 char_index = FT_Get_Char_Index(tt_face, start_pos); + + // If the glyph hasn't been loaded yet, do it now. + if (char_index) + { + SGUITTGlyph& glyph = Glyphs[char_index - 1]; + if (!glyph.isLoaded) + { + glyph.preload(char_index, tt_face, Driver, size, load_flags); + Glyph_Pages[glyph.glyph_page]->pushGlyphToBePaged(&glyph); + } + } + } + while (++start_pos < end_pos); + + // Return our original character. + return glyph; +} + +s32 CGUITTFont::getCharacterFromPos(const wchar_t* text, s32 pixel_x) const +{ + return getCharacterFromPos(core::ustring(text), pixel_x); +} + +s32 CGUITTFont::getCharacterFromPos(const core::ustring& text, s32 pixel_x) const +{ + s32 x = 0; + //s32 idx = 0; + + u32 character = 0; + uchar32_t previousChar = 0; + core::ustring::const_iterator iter = text.begin(); + while (!iter.atEnd()) + { + uchar32_t c = *iter; + x += getWidthFromCharacter(c); + + // Kerning. + core::vector2di k = getKerning(c, previousChar); + x += k.X; + + if (x >= pixel_x) + return character; + + previousChar = c; + ++iter; + ++character; + } + + return -1; +} + +void CGUITTFont::setKerningWidth(s32 kerning) +{ + GlobalKerningWidth = kerning; +} + +void CGUITTFont::setKerningHeight(s32 kerning) +{ + GlobalKerningHeight = kerning; +} + +s32 CGUITTFont::getKerningWidth(const wchar_t* thisLetter, const wchar_t* previousLetter) const +{ + if (tt_face == 0) + return GlobalKerningWidth; + if (thisLetter == 0 || previousLetter == 0) + return 0; + + return getKerningWidth((uchar32_t)*thisLetter, (uchar32_t)*previousLetter); +} + +s32 CGUITTFont::getKerningWidth(const uchar32_t thisLetter, const uchar32_t previousLetter) const +{ + // Return only the kerning width. + return getKerning(thisLetter, previousLetter).X; +} + +s32 CGUITTFont::getKerningHeight() const +{ + // FreeType 2 currently doesn't return any height kerning information. + return GlobalKerningHeight; +} + +core::vector2di CGUITTFont::getKerning(const wchar_t thisLetter, const wchar_t previousLetter) const +{ + return getKerning((uchar32_t)thisLetter, (uchar32_t)previousLetter); +} + +core::vector2di CGUITTFont::getKerning(const uchar32_t thisLetter, const uchar32_t previousLetter) const +{ + if (tt_face == 0 || thisLetter == 0 || previousLetter == 0) + return core::vector2di(); + + // Set the size of the face. + // This is because we cache faces and the face may have been set to a different size. + FT_Set_Pixel_Sizes(tt_face, 0, size); + + core::vector2di ret(GlobalKerningWidth, GlobalKerningHeight); + + u32 n = getGlyphIndexByChar(thisLetter); + + // If we don't have this glyph, ask fallback font + if (n == 0) + { + if (fallback != 0) { + wchar_t l1 = (wchar_t) thisLetter, l2 = (wchar_t) previousLetter; + ret.X = fallback->getKerningWidth(&l1, &l2); + ret.Y = fallback->getKerningHeight(); + } + return ret; + } + + // If we don't have kerning, no point in continuing. + if (!FT_HAS_KERNING(tt_face)) + return ret; + + // Get the kerning information. + FT_Vector v; + FT_Get_Kerning(tt_face, getGlyphIndexByChar(previousLetter), n, FT_KERNING_DEFAULT, &v); + + // If we have a scalable font, the return value will be in font points. + if (FT_IS_SCALABLE(tt_face)) + { + // Font points, so divide by 64. + ret.X += (v.x / 64); + ret.Y += (v.y / 64); + } + else + { + // Pixel units. + ret.X += v.x; + ret.Y += v.y; + } + return ret; +} + +void CGUITTFont::setInvisibleCharacters(const wchar_t *s) +{ + core::ustring us(s); + Invisible = us; +} + +void CGUITTFont::setInvisibleCharacters(const core::ustring& s) +{ + Invisible = s; +} + +video::IImage* CGUITTFont::createTextureFromChar(const uchar32_t& ch) +{ + u32 n = getGlyphIndexByChar(ch); + if (n == 0) + n = getGlyphIndexByChar((uchar32_t) core::unicode::UTF_REPLACEMENT_CHARACTER); + + const SGUITTGlyph& glyph = Glyphs[n-1]; + CGUITTGlyphPage* page = Glyph_Pages[glyph.glyph_page]; + + if (page->dirty) + page->updateTexture(); + + video::ITexture* tex = page->texture; + + // Acquire a read-only lock of the corresponding page texture. + void* ptr = tex->lock(video::ETLM_READ_ONLY); + + video::ECOLOR_FORMAT format = tex->getColorFormat(); + core::dimension2du tex_size = tex->getOriginalSize(); + video::IImage* pageholder = Driver->createImageFromData(format, tex_size, ptr, true, false); + + // Copy the image data out of the page texture. + core::dimension2du glyph_size(glyph.source_rect.getSize()); + video::IImage* image = Driver->createImage(format, glyph_size); + pageholder->copyTo(image, core::position2di(0, 0), glyph.source_rect); + + tex->unlock(); + return image; +} + +video::ITexture* CGUITTFont::getPageTextureByIndex(const u32& page_index) const +{ + if (page_index < Glyph_Pages.size()) + return Glyph_Pages[page_index]->texture; + else + return 0; +} + +void CGUITTFont::createSharedPlane() +{ + /* + 2___3 + | /| + | / | <-- plane mesh is like this, point 2 is (0,0), point 0 is (0, -1) + |/ | <-- the texture coords of point 2 is (0,0, point 0 is (0, 1) + 0---1 + */ + + using namespace core; + using namespace video; + using namespace scene; + S3DVertex vertices[4]; + u16 indices[6] = {0,2,3,3,1,0}; + vertices[0] = S3DVertex(vector3df(0,-1,0), vector3df(0,0,-1), SColor(255,255,255,255), vector2df(0,1)); + vertices[1] = S3DVertex(vector3df(1,-1,0), vector3df(0,0,-1), SColor(255,255,255,255), vector2df(1,1)); + vertices[2] = S3DVertex(vector3df(0, 0,0), vector3df(0,0,-1), SColor(255,255,255,255), vector2df(0,0)); + vertices[3] = S3DVertex(vector3df(1, 0,0), vector3df(0,0,-1), SColor(255,255,255,255), vector2df(1,0)); + + SMeshBuffer* buf = new SMeshBuffer(); + buf->append(vertices, 4, indices, 6); + + shared_plane_.addMeshBuffer( buf ); + + shared_plane_ptr_ = &shared_plane_; + buf->drop(); //the addMeshBuffer method will grab it, so we can drop this ptr. +} + +core::dimension2d<u32> CGUITTFont::getDimensionUntilEndOfLine(const wchar_t* p) const +{ + core::stringw s; + for (const wchar_t* temp = p; temp && *temp != '\0' && *temp != L'\r' && *temp != L'\n'; ++temp ) + s.append(*temp); + + return getDimension(s.c_str()); +} + +core::array<scene::ISceneNode*> CGUITTFont::addTextSceneNode(const wchar_t* text, scene::ISceneManager* smgr, scene::ISceneNode* parent, const video::SColor& color, bool center) +{ + using namespace core; + using namespace video; + using namespace scene; + + array<scene::ISceneNode*> container; + + if (!Driver || !smgr) return container; + if (!parent) + parent = smgr->addEmptySceneNode(smgr->getRootSceneNode(), -1); + // if you don't specify parent, then we add a empty node attached to the root node + // this is generally undesirable. + + if (!shared_plane_ptr_) //this points to a static mesh that contains the plane + createSharedPlane(); //if it's not initialized, we create one. + + dimension2d<s32> text_size(getDimension(text)); //convert from unsigned to signed. + vector3df start_point(0, 0, 0), offset; + + /** NOTICE: + Because we are considering adding texts into 3D world, all Y axis vectors are inverted. + **/ + + // There's currently no "vertical center" concept when you apply text scene node to the 3D world. + if (center) + { + offset.X = start_point.X = -text_size.Width / 2.f; + offset.Y = start_point.Y = +text_size.Height/ 2.f; + offset.X += (text_size.Width - getDimensionUntilEndOfLine(text).Width) >> 1; + } + + // the default font material + SMaterial mat; + mat.setFlag(video::EMF_LIGHTING, true); + mat.setFlag(video::EMF_ZWRITE_ENABLE, false); + mat.setFlag(video::EMF_NORMALIZE_NORMALS, true); + mat.ColorMaterial = video::ECM_NONE; + mat.MaterialType = use_transparency ? video::EMT_TRANSPARENT_ALPHA_CHANNEL : video::EMT_SOLID; + mat.MaterialTypeParam = 0.01f; + mat.DiffuseColor = color; + + wchar_t current_char = 0, previous_char = 0; + u32 n = 0; + + array<u32> glyph_indices; + + while (*text) + { + current_char = *text; + bool line_break=false; + if (current_char == L'\r') // Mac or Windows breaks + { + line_break = true; + if (*(text + 1) == L'\n') // Windows line breaks. + current_char = *(++text); + } + else if (current_char == L'\n') // Unix breaks + { + line_break = true; + } + + if (line_break) + { + previous_char = 0; + offset.Y -= tt_face->size->metrics.ascender / 64; + offset.X = start_point.X; + if (center) + offset.X += (text_size.Width - getDimensionUntilEndOfLine(text+1).Width) >> 1; + ++text; + } + else + { + n = getGlyphIndexByChar(current_char); + if (n > 0) + { + glyph_indices.push_back( n ); + + // Store glyph size and offset informations. + SGUITTGlyph const& glyph = Glyphs[n-1]; + u32 texw = glyph.source_rect.getWidth(); + u32 texh = glyph.source_rect.getHeight(); + s32 offx = glyph.offset.X; + s32 offy = (font_metrics.ascender / 64) - glyph.offset.Y; + + // Apply kerning. + vector2di k = getKerning(current_char, previous_char); + offset.X += k.X; + offset.Y += k.Y; + + vector3df current_pos(offset.X + offx, offset.Y - offy, 0); + dimension2d<u32> letter_size = dimension2d<u32>(texw, texh); + + // Now we copy planes corresponding to the letter size. + IMeshManipulator* mani = smgr->getMeshManipulator(); + IMesh* meshcopy = mani->createMeshCopy(shared_plane_ptr_); + mani->scale(meshcopy, vector3df((f32)letter_size.Width, (f32)letter_size.Height, 1)); + + ISceneNode* current_node = smgr->addMeshSceneNode(meshcopy, parent, -1, current_pos); + meshcopy->drop(); + + current_node->getMaterial(0) = mat; + current_node->setAutomaticCulling(EAC_OFF); + current_node->setIsDebugObject(true); //so the picking won't have any effect on individual letter + //current_node->setDebugDataVisible(EDS_BBOX); //de-comment this when debugging + + container.push_back(current_node); + } + offset.X += getWidthFromCharacter(current_char); + // Note that fallback font handling is missing here (Minetest never uses this) + + previous_char = current_char; + ++text; + } + } + + update_glyph_pages(); + //only after we update the textures can we use the glyph page textures. + + for (u32 i = 0; i < glyph_indices.size(); ++i) + { + u32 n = glyph_indices[i]; + SGUITTGlyph const& glyph = Glyphs[n-1]; + ITexture* current_tex = Glyph_Pages[glyph.glyph_page]->texture; + f32 page_texture_size = (f32)current_tex->getSize().Width; + //Now we calculate the UV position according to the texture size and the source rect. + // + // 2___3 + // | /| + // | / | <-- plane mesh is like this, point 2 is (0,0), point 0 is (0, -1) + // |/ | <-- the texture coords of point 2 is (0,0, point 0 is (0, 1) + // 0---1 + // + f32 u1 = glyph.source_rect.UpperLeftCorner.X / page_texture_size; + f32 u2 = u1 + (glyph.source_rect.getWidth() / page_texture_size); + f32 v1 = glyph.source_rect.UpperLeftCorner.Y / page_texture_size; + f32 v2 = v1 + (glyph.source_rect.getHeight() / page_texture_size); + + //we can be quite sure that this is IMeshSceneNode, because we just added them in the above loop. + IMeshSceneNode* node = static_cast<IMeshSceneNode*>(container[i]); + + S3DVertex* pv = static_cast<S3DVertex*>(node->getMesh()->getMeshBuffer(0)->getVertices()); + //pv[0].TCoords.Y = pv[1].TCoords.Y = (letter_size.Height - 1) / static_cast<f32>(letter_size.Height); + //pv[1].TCoords.X = pv[3].TCoords.X = (letter_size.Width - 1) / static_cast<f32>(letter_size.Width); + pv[0].TCoords = vector2df(u1, v2); + pv[1].TCoords = vector2df(u2, v2); + pv[2].TCoords = vector2df(u1, v1); + pv[3].TCoords = vector2df(u2, v1); + + container[i]->getMaterial(0).setTexture(0, current_tex); + } + + return container; +} + +} // end namespace gui +} // end namespace irr diff --git a/src/irrlicht_changes/CGUITTFont.h b/src/irrlicht_changes/CGUITTFont.h new file mode 100644 index 0000000..2721364 --- /dev/null +++ b/src/irrlicht_changes/CGUITTFont.h @@ -0,0 +1,412 @@ +/* + CGUITTFont FreeType class for Irrlicht + Copyright (c) 2009-2010 John Norman + Copyright (c) 2016 Nathanaëlle Courant + + 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. + + The original version of this class can be located at: + http://irrlicht.suckerfreegames.com/ + + John Norman + john@suckerfreegames.com +*/ + +#pragma once + +#include <irrlicht.h> +#include <ft2build.h> +#include <vector> +#include <map> +#include <irrUString.h> +#include "util/enriched_string.h" +#include "util/basic_macros.h" +#include FT_FREETYPE_H + +namespace irr +{ +namespace gui +{ + struct SGUITTFace; + class CGUITTFont; + + //! Structure representing a single TrueType glyph. + struct SGUITTGlyph + { + //! Constructor. + SGUITTGlyph() : + isLoaded(false), + glyph_page(0), + source_rect(), + offset(), + advance(), + surface(0), + parent(0) + {} + + DISABLE_CLASS_COPY(SGUITTGlyph); + + //! This class would be trivially copyable except for the reference count on `surface`. + SGUITTGlyph(SGUITTGlyph &&other) : + isLoaded(other.isLoaded), + glyph_page(other.glyph_page), + source_rect(other.source_rect), + offset(other.offset), + advance(other.advance), + surface(other.surface), + parent(other.parent) + { + other.surface = 0; + } + + //! Destructor. + ~SGUITTGlyph() { unload(); } + + //! Preload the glyph. + //! The preload process occurs when the program tries to cache the glyph from FT_Library. + //! However, it simply defines the SGUITTGlyph's properties and will only create the page + //! textures if necessary. The actual creation of the textures should only occur right + //! before the batch draw call. + void preload(u32 char_index, FT_Face face, video::IVideoDriver* driver, u32 font_size, const FT_Int32 loadFlags); + + //! Unloads the glyph. + void unload(); + + //! Creates the IImage object from the FT_Bitmap. + video::IImage* createGlyphImage(const FT_Bitmap& bits, video::IVideoDriver* driver) const; + + //! If true, the glyph has been loaded. + bool isLoaded; + + //! The page the glyph is on. + u32 glyph_page; + + //! The source rectangle for the glyph. + core::recti source_rect; + + //! The offset of glyph when drawn. + core::vector2di offset; + + //! Glyph advance information. + FT_Vector advance; + + //! This is just the temporary image holder. After this glyph is paged, + //! it will be dropped. + mutable video::IImage* surface; + + //! The pointer pointing to the parent (CGUITTFont) + CGUITTFont* parent; + }; + + //! Holds a sheet of glyphs. + class CGUITTGlyphPage + { + public: + CGUITTGlyphPage(video::IVideoDriver* Driver, const io::path& texture_name) :texture(0), available_slots(0), used_slots(0), dirty(false), driver(Driver), name(texture_name) {} + ~CGUITTGlyphPage() + { + if (texture) + { + if (driver) + driver->removeTexture(texture); + else texture->drop(); + } + } + + //! Create the actual page texture, + bool createPageTexture(const u8& pixel_mode, const core::dimension2du& texture_size) + { + if( texture ) + return false; + + bool flgmip = driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); +#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8 + bool flgcpy = driver->getTextureCreationFlag(video::ETCF_ALLOW_MEMORY_COPY); + driver->setTextureCreationFlag(video::ETCF_ALLOW_MEMORY_COPY, true); +#endif + + // Set the texture color format. + switch (pixel_mode) + { + case FT_PIXEL_MODE_MONO: + texture = driver->addTexture(texture_size, name, video::ECF_A1R5G5B5); + break; + case FT_PIXEL_MODE_GRAY: + default: + texture = driver->addTexture(texture_size, name, video::ECF_A8R8G8B8); + break; + } + + // Restore our texture creation flags. + driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, flgmip); +#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8 + driver->setTextureCreationFlag(video::ETCF_ALLOW_MEMORY_COPY, flgcpy); +#endif + return texture ? true : false; + } + + //! Add the glyph to a list of glyphs to be paged. + //! This collection will be cleared after updateTexture is called. + void pushGlyphToBePaged(const SGUITTGlyph* glyph) + { + glyph_to_be_paged.push_back(glyph); + } + + //! Updates the texture atlas with new glyphs. + void updateTexture() + { + if (!dirty) return; + + void* ptr = texture->lock(); + video::ECOLOR_FORMAT format = texture->getColorFormat(); + core::dimension2du size = texture->getOriginalSize(); + video::IImage* pageholder = driver->createImageFromData(format, size, ptr, true, false); + + for (u32 i = 0; i < glyph_to_be_paged.size(); ++i) + { + const SGUITTGlyph* glyph = glyph_to_be_paged[i]; + if (glyph && glyph->isLoaded) + { + if (glyph->surface) + { + glyph->surface->copyTo(pageholder, glyph->source_rect.UpperLeftCorner); + glyph->surface->drop(); + glyph->surface = 0; + } + else + { + ; // TODO: add error message? + //currently, if we failed to create the image, just ignore this operation. + } + } + } + + pageholder->drop(); + texture->unlock(); + glyph_to_be_paged.clear(); + dirty = false; + } + + video::ITexture* texture; + u32 available_slots; + u32 used_slots; + bool dirty; + + core::array<core::vector2di> render_positions; + core::array<core::recti> render_source_rects; + core::array<video::SColor> render_colors; + + private: + core::array<const SGUITTGlyph*> glyph_to_be_paged; + video::IVideoDriver* driver; + io::path name; + }; + + //! Class representing a TrueType font. + class CGUITTFont : public IGUIFont + { + public: + //! Creates a new TrueType font and returns a pointer to it. The pointer must be drop()'ed when finished. + //! \param env The IGUIEnvironment the font loads out of. + //! \param filename The filename of the font. + //! \param size The size of the font glyphs in pixels. Since this is the size of the individual glyphs, the true height of the font may change depending on the characters used. + //! \param antialias set the use_monochrome (opposite to antialias) flag + //! \param transparency set the use_transparency flag + //! \return Returns a pointer to a CGUITTFont. Will return 0 if the font failed to load. + static CGUITTFont* createTTFont(IGUIEnvironment *env, const io::path& filename, const u32 size, const bool antialias = true, const bool transparency = true, const u32 shadow = 0, const u32 shadow_alpha = 255); + static CGUITTFont* createTTFont(IrrlichtDevice *device, const io::path& filename, const u32 size, const bool antialias = true, const bool transparency = true); + static CGUITTFont* create(IGUIEnvironment *env, const io::path& filename, const u32 size, const bool antialias = true, const bool transparency = true); + static CGUITTFont* create(IrrlichtDevice *device, const io::path& filename, const u32 size, const bool antialias = true, const bool transparency = true); + + //! Destructor + virtual ~CGUITTFont(); + + //! Sets the amount of glyphs to batch load. + virtual void setBatchLoadSize(u32 batch_size) { batch_load_size = batch_size; } + + //! Sets the maximum texture size for a page of glyphs. + virtual void setMaxPageTextureSize(const core::dimension2du& texture_size) { max_page_texture_size = texture_size; } + + //! Get the font size. + virtual u32 getFontSize() const { return size; } + + //! Check the font's transparency. + virtual bool isTransparent() const { return use_transparency; } + + //! Check if the font auto-hinting is enabled. + //! Auto-hinting is FreeType's built-in font hinting engine. + virtual bool useAutoHinting() const { return use_auto_hinting; } + + //! Check if the font hinting is enabled. + virtual bool useHinting() const { return use_hinting; } + + //! Check if the font is being loaded as a monochrome font. + //! The font can either be a 256 color grayscale font, or a 2 color monochrome font. + virtual bool useMonochrome() const { return use_monochrome; } + + //! Tells the font to allow transparency when rendering. + //! Default: true. + //! \param flag If true, the font draws using transparency. + virtual void setTransparency(const bool flag); + + //! Tells the font to use monochrome rendering. + //! Default: false. + //! \param flag If true, the font draws using a monochrome image. If false, the font uses a grayscale image. + virtual void setMonochrome(const bool flag); + + //! Enables or disables font hinting. + //! Default: Hinting and auto-hinting true. + //! \param enable If false, font hinting is turned off. If true, font hinting is turned on. + //! \param enable_auto_hinting If true, FreeType uses its own auto-hinting algorithm. If false, it tries to use the algorithm specified by the font. + virtual void setFontHinting(const bool enable, const bool enable_auto_hinting = true); + + //! Draws some text and clips it to the specified rectangle if wanted. + virtual void draw(const core::stringw& text, const core::rect<s32>& position, + video::SColor color, bool hcenter=false, bool vcenter=false, + const core::rect<s32>* clip=0); + + void draw(const EnrichedString& text, const core::rect<s32>& position, + bool hcenter=false, bool vcenter=false, + const core::rect<s32>* clip=0); + + //! Returns the dimension of a character produced by this font. + virtual core::dimension2d<u32> getCharDimension(const wchar_t ch) const; + + //! Returns the dimension of a text string. + virtual core::dimension2d<u32> getDimension(const wchar_t* text) const; + virtual core::dimension2d<u32> getDimension(const core::ustring& text) const; + + //! Calculates the index of the character in the text which is on a specific position. + virtual s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const; + virtual s32 getCharacterFromPos(const core::ustring& text, s32 pixel_x) const; + + //! Sets global kerning width for the font. + virtual void setKerningWidth(s32 kerning); + + //! Sets global kerning height for the font. + virtual void setKerningHeight(s32 kerning); + + //! Gets kerning values (distance between letters) for the font. If no parameters are provided, + virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const; + virtual s32 getKerningWidth(const uchar32_t thisLetter=0, const uchar32_t previousLetter=0) const; + + //! Returns the distance between letters + virtual s32 getKerningHeight() const; + + //! Define which characters should not be drawn by the font. + virtual void setInvisibleCharacters(const wchar_t *s); + virtual void setInvisibleCharacters(const core::ustring& s); + + //! Get the last glyph page if there's still available slots. + //! If not, it will return zero. + CGUITTGlyphPage* getLastGlyphPage() const; + + //! Create a new glyph page texture. + //! \param pixel_mode the pixel mode defined by FT_Pixel_Mode + //should be better typed. fix later. + CGUITTGlyphPage* createGlyphPage(const u8& pixel_mode); + + //! Get the last glyph page's index. + u32 getLastGlyphPageIndex() const { return Glyph_Pages.size() - 1; } + + //! Set font that should be used for glyphs not present in ours + void setFallback(gui::IGUIFont* font) { fallback = font; } + + //! Create corresponding character's software image copy from the font, + //! so you can use this data just like any ordinary video::IImage. + //! \param ch The character you need + virtual video::IImage* createTextureFromChar(const uchar32_t& ch); + + //! This function is for debugging mostly. If the page doesn't exist it returns zero. + //! \param page_index Simply return the texture handle of a given page index. + virtual video::ITexture* getPageTextureByIndex(const u32& page_index) const; + + //! Add a list of scene nodes generated by putting font textures on the 3D planes. + virtual core::array<scene::ISceneNode*> addTextSceneNode + (const wchar_t* text, scene::ISceneManager* smgr, scene::ISceneNode* parent = 0, + const video::SColor& color = video::SColor(255, 0, 0, 0), bool center = false ); + + inline s32 getAscender() const { return font_metrics.ascender; } + + protected: + bool use_monochrome; + bool use_transparency; + bool use_hinting; + bool use_auto_hinting; + u32 size; + u32 batch_load_size; + core::dimension2du max_page_texture_size; + + private: + // Manages the FreeType library. + static FT_Library c_library; + static std::map<io::path, SGUITTFace*> c_faces; + static bool c_libraryLoaded; + static scene::IMesh* shared_plane_ptr_; + static scene::SMesh shared_plane_; + + CGUITTFont(IGUIEnvironment *env); + bool load(const io::path& filename, const u32 size, const bool antialias, const bool transparency); + void reset_images(); + void update_glyph_pages() const; + void update_load_flags() + { + // Set up our loading flags. + load_flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER; + if (!useHinting()) load_flags |= FT_LOAD_NO_HINTING; + if (!useAutoHinting()) load_flags |= FT_LOAD_NO_AUTOHINT; + if (useMonochrome()) load_flags |= FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO; + else load_flags |= FT_LOAD_TARGET_NORMAL; + } + u32 getWidthFromCharacter(wchar_t c) const; + u32 getWidthFromCharacter(uchar32_t c) const; + u32 getHeightFromCharacter(wchar_t c) const; + u32 getHeightFromCharacter(uchar32_t c) const; + u32 getGlyphIndexByChar(wchar_t c) const; + u32 getGlyphIndexByChar(uchar32_t c) const; + core::vector2di getKerning(const wchar_t thisLetter, const wchar_t previousLetter) const; + core::vector2di getKerning(const uchar32_t thisLetter, const uchar32_t previousLetter) const; + core::dimension2d<u32> getDimensionUntilEndOfLine(const wchar_t* p) const; + + void createSharedPlane(); + + irr::IrrlichtDevice* Device; + gui::IGUIEnvironment* Environment; + video::IVideoDriver* Driver; + io::path filename; + FT_Face tt_face; + FT_Size_Metrics font_metrics; + FT_Int32 load_flags; + + mutable core::array<CGUITTGlyphPage*> Glyph_Pages; + mutable core::array<SGUITTGlyph> Glyphs; + + s32 GlobalKerningWidth; + s32 GlobalKerningHeight; + core::ustring Invisible; + u32 shadow_offset; + u32 shadow_alpha; + + gui::IGUIFont* fallback; + }; + +} // end namespace gui +} // end namespace irr diff --git a/src/irrlicht_changes/CMakeLists.txt b/src/irrlicht_changes/CMakeLists.txt new file mode 100644 index 0000000..19f431a --- /dev/null +++ b/src/irrlicht_changes/CMakeLists.txt @@ -0,0 +1,11 @@ +if (BUILD_CLIENT) + set(client_irrlicht_changes_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/static_text.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/CGUITTFont.cpp + ) + + # CMake require us to set a local scope and then parent scope + # Else the last set win in parent scope + set(client_irrlicht_changes_SRCS ${client_irrlicht_changes_SRCS} PARENT_SCOPE) +endif() + diff --git a/src/irrlicht_changes/static_text.cpp b/src/irrlicht_changes/static_text.cpp new file mode 100644 index 0000000..a4749ba --- /dev/null +++ b/src/irrlicht_changes/static_text.cpp @@ -0,0 +1,589 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// Copyright (C) 2016 Nathanaëlle Courant: +// Modified the functions to use EnrichedText instead of string. +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "static_text.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include <IGUIFont.h> +#include <IVideoDriver.h> +#include <rect.h> +#include <SColor.h> + +#include "CGUITTFont.h" +#include "util/string.h" + +namespace irr +{ + +namespace gui +{ +//! constructor +StaticText::StaticText(const EnrichedString &text, bool border, + IGUIEnvironment* environment, IGUIElement* parent, + s32 id, const core::rect<s32>& rectangle, + bool background) +: IGUIStaticText(environment, parent, id, rectangle), + HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_UPPERLEFT), + Border(border), WordWrap(false), Background(background), + RestrainTextInside(true), RightToLeft(false), + OverrideFont(0), LastBreakFont(0) +{ + #ifdef _DEBUG + setDebugName("StaticText"); + #endif + + setText(text); +} + + +//! destructor +StaticText::~StaticText() +{ + if (OverrideFont) + OverrideFont->drop(); +} + +//! draws the element and its children +void StaticText::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + video::IVideoDriver* driver = Environment->getVideoDriver(); + + core::rect<s32> frameRect(AbsoluteRect); + + // draw background + + if (Background) + driver->draw2DRectangle(getBackgroundColor(), frameRect, &AbsoluteClippingRect); + + // draw the border + + if (Border) + { + skin->draw3DSunkenPane(this, 0, true, false, frameRect, &AbsoluteClippingRect); + frameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X); + } + + // draw the text + IGUIFont *font = getActiveFont(); + if (font && BrokenText.size()) { + if (font != LastBreakFont) + updateText(); + + core::rect<s32> r = frameRect; + s32 height_line = font->getDimension(L"A").Height + font->getKerningHeight(); + s32 height_total = height_line * BrokenText.size(); + if (VAlign == EGUIA_CENTER && WordWrap) + { + r.UpperLeftCorner.Y = r.getCenter().Y - (height_total / 2); + } + else if (VAlign == EGUIA_LOWERRIGHT) + { + r.UpperLeftCorner.Y = r.LowerRightCorner.Y - height_total; + } + if (HAlign == EGUIA_LOWERRIGHT) + { + r.UpperLeftCorner.X = r.LowerRightCorner.X - + getTextWidth(); + } + + irr::video::SColor previous_color(255, 255, 255, 255); + for (const EnrichedString &str : BrokenText) { + if (HAlign == EGUIA_LOWERRIGHT) + { + r.UpperLeftCorner.X = frameRect.LowerRightCorner.X - + font->getDimension(str.c_str()).Width; + } + + if (font->getType() == irr::gui::EGFT_CUSTOM) { + CGUITTFont *tmp = static_cast<CGUITTFont*>(font); + tmp->draw(str, + r, HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER, + (RestrainTextInside ? &AbsoluteClippingRect : NULL)); + } else + { + // Draw non-colored text + font->draw(str.c_str(), + r, str.getDefaultColor(), // TODO: Implement colorization + HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER, + (RestrainTextInside ? &AbsoluteClippingRect : NULL)); + } + + + r.LowerRightCorner.Y += height_line; + r.UpperLeftCorner.Y += height_line; + } + } + + IGUIElement::draw(); +} + + +//! Sets another skin independent font. +void StaticText::setOverrideFont(IGUIFont* font) +{ + if (OverrideFont == font) + return; + + if (OverrideFont) + OverrideFont->drop(); + + OverrideFont = font; + + if (OverrideFont) + OverrideFont->grab(); + + updateText(); +} + +//! Gets the override font (if any) +IGUIFont * StaticText::getOverrideFont() const +{ + return OverrideFont; +} + +//! Get the font which is used right now for drawing +IGUIFont* StaticText::getActiveFont() const +{ + if ( OverrideFont ) + return OverrideFont; + IGUISkin* skin = Environment->getSkin(); + if (skin) + return skin->getFont(); + return 0; +} + +//! Sets another color for the text. +void StaticText::setOverrideColor(video::SColor color) +{ + ColoredText.setDefaultColor(color); + updateText(); +} + + +//! Sets another color for the text. +void StaticText::setBackgroundColor(video::SColor color) +{ + ColoredText.setBackground(color); + Background = true; +} + + +//! Sets whether to draw the background +void StaticText::setDrawBackground(bool draw) +{ + Background = draw; +} + + +//! Gets the background color +video::SColor StaticText::getBackgroundColor() const +{ + IGUISkin *skin = Environment->getSkin(); + + return (ColoredText.hasBackground() || !skin) ? + ColoredText.getBackground() : skin->getColor(gui::EGDC_3D_FACE); +} + + +//! Checks if background drawing is enabled +bool StaticText::isDrawBackgroundEnabled() const +{ + return Background; +} + + +//! Sets whether to draw the border +void StaticText::setDrawBorder(bool draw) +{ + Border = draw; +} + + +//! Checks if border drawing is enabled +bool StaticText::isDrawBorderEnabled() const +{ + return Border; +} + + +void StaticText::setTextRestrainedInside(bool restrainTextInside) +{ + RestrainTextInside = restrainTextInside; +} + + +bool StaticText::isTextRestrainedInside() const +{ + return RestrainTextInside; +} + + +void StaticText::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) +{ + HAlign = horizontal; + VAlign = vertical; +} + + +video::SColor StaticText::getOverrideColor() const +{ + return ColoredText.getDefaultColor(); +} + +#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8 +video::SColor StaticText::getActiveColor() const +{ + return getOverrideColor(); +} +#endif + +//! Sets if the static text should use the overide color or the +//! color in the gui skin. +void StaticText::enableOverrideColor(bool enable) +{ + // TODO +} + + +bool StaticText::isOverrideColorEnabled() const +{ + return true; +} + + +//! Enables or disables word wrap for using the static text as +//! multiline text control. +void StaticText::setWordWrap(bool enable) +{ + WordWrap = enable; + updateText(); +} + + +bool StaticText::isWordWrapEnabled() const +{ + return WordWrap; +} + + +void StaticText::setRightToLeft(bool rtl) +{ + if (RightToLeft != rtl) + { + RightToLeft = rtl; + updateText(); + } +} + + +bool StaticText::isRightToLeft() const +{ + return RightToLeft; +} + + +//! Breaks the single text line. +// Updates the font colors +void StaticText::updateText() +{ + const EnrichedString &cText = ColoredText; + BrokenText.clear(); + + if (cText.hasBackground()) + setBackgroundColor(cText.getBackground()); + else + setDrawBackground(false); + + if (!WordWrap) { + BrokenText.push_back(cText); + return; + } + + // Update word wrap + + IGUISkin* skin = Environment->getSkin(); + IGUIFont* font = getActiveFont(); + if (!font) + return; + + LastBreakFont = font; + + EnrichedString line; + EnrichedString word; + EnrichedString whitespace; + s32 size = cText.size(); + s32 length = 0; + s32 elWidth = RelativeRect.getWidth(); + if (Border) + elWidth -= 2*skin->getSize(EGDS_TEXT_DISTANCE_X); + wchar_t c; + + //std::vector<irr::video::SColor> colors; + + // We have to deal with right-to-left and left-to-right differently + // However, most parts of the following code is the same, it's just + // some order and boundaries which change. + if (!RightToLeft) + { + // regular (left-to-right) + for (s32 i=0; i<size; ++i) + { + c = cText.getString()[i]; + bool lineBreak = false; + + if (c == L'\r') // Mac or Windows breaks + { + lineBreak = true; + //if (Text[i+1] == L'\n') // Windows breaks + //{ + // Text.erase(i+1); + // --size; + //} + c = '\0'; + } + else if (c == L'\n') // Unix breaks + { + lineBreak = true; + c = '\0'; + } + + bool isWhitespace = (c == L' ' || c == 0); + if ( !isWhitespace ) + { + // part of a word + //word += c; + word.addChar(cText, i); + } + + if ( isWhitespace || i == (size-1)) + { + if (word.size()) + { + // here comes the next whitespace, look if + // we must break the last word to the next line. + const s32 whitelgth = font->getDimension(whitespace.c_str()).Width; + //const std::wstring sanitized = removeEscapes(word.c_str()); + const s32 wordlgth = font->getDimension(word.c_str()).Width; + + if (wordlgth > elWidth) + { + // This word is too long to fit in the available space, look for + // the Unicode Soft HYphen (SHY / 00AD) character for a place to + // break the word at + int where = core::stringw(word.c_str()).findFirst( wchar_t(0x00AD) ); + if (where != -1) + { + EnrichedString first = word.substr(0, where); + EnrichedString second = word.substr(where, word.size() - where); + first.addCharNoColor(L'-'); + BrokenText.push_back(line + first); + const s32 secondLength = font->getDimension(second.c_str()).Width; + + length = secondLength; + line = second; + } + else + { + // No soft hyphen found, so there's nothing more we can do + // break to next line + if (length) + BrokenText.push_back(line); + length = wordlgth; + line = word; + } + } + else if (length && (length + wordlgth + whitelgth > elWidth)) + { + // break to next line + BrokenText.push_back(line); + length = wordlgth; + line = word; + } + else + { + // add word to line + line += whitespace; + line += word; + length += whitelgth + wordlgth; + } + + word.clear(); + whitespace.clear(); + } + + if ( isWhitespace && c != 0) + { + whitespace.addChar(cText, i); + } + + // compute line break + if (lineBreak) + { + line += whitespace; + line += word; + BrokenText.push_back(line); + line.clear(); + word.clear(); + whitespace.clear(); + length = 0; + } + } + } + + line += whitespace; + line += word; + BrokenText.push_back(line); + } + else + { + // right-to-left + for (s32 i=size; i>=0; --i) + { + c = cText.getString()[i]; + bool lineBreak = false; + + if (c == L'\r') // Mac or Windows breaks + { + lineBreak = true; + //if ((i>0) && Text[i-1] == L'\n') // Windows breaks + //{ + // Text.erase(i-1); + // --size; + //} + c = '\0'; + } + else if (c == L'\n') // Unix breaks + { + lineBreak = true; + c = '\0'; + } + + if (c==L' ' || c==0 || i==0) + { + if (word.size()) + { + // here comes the next whitespace, look if + // we must break the last word to the next line. + const s32 whitelgth = font->getDimension(whitespace.c_str()).Width; + const s32 wordlgth = font->getDimension(word.c_str()).Width; + + if (length && (length + wordlgth + whitelgth > elWidth)) + { + // break to next line + BrokenText.push_back(line); + length = wordlgth; + line = word; + } + else + { + // add word to line + line = whitespace + line; + line = word + line; + length += whitelgth + wordlgth; + } + + word.clear(); + whitespace.clear(); + } + + if (c != 0) + // whitespace = core::stringw(&c, 1) + whitespace; + whitespace = cText.substr(i, 1) + whitespace; + + // compute line break + if (lineBreak) + { + line = whitespace + line; + line = word + line; + BrokenText.push_back(line); + line.clear(); + word.clear(); + whitespace.clear(); + length = 0; + } + } + else + { + // yippee this is a word.. + //word = core::stringw(&c, 1) + word; + word = cText.substr(i, 1) + word; + } + } + + line = whitespace + line; + line = word + line; + BrokenText.push_back(line); + } +} + + +//! Sets the new caption of this element. +void StaticText::setText(const wchar_t* text) +{ + setText(EnrichedString(text, getOverrideColor())); +} + +void StaticText::setText(const EnrichedString &text) +{ + ColoredText = text; + IGUIElement::setText(ColoredText.c_str()); + updateText(); +} + +void StaticText::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + updateText(); +} + + +//! Returns the height of the text in pixels when it is drawn. +s32 StaticText::getTextHeight() const +{ + IGUIFont* font = getActiveFont(); + if (!font) + return 0; + + if (WordWrap) { + s32 height = font->getDimension(L"A").Height + font->getKerningHeight(); + return height * BrokenText.size(); + } + // There may be intentional new lines without WordWrap + return font->getDimension(BrokenText[0].c_str()).Height; +} + + +s32 StaticText::getTextWidth() const +{ + IGUIFont *font = getActiveFont(); + if (!font) + return 0; + + s32 widest = 0; + + for (const EnrichedString &line : BrokenText) { + s32 width = font->getDimension(line.c_str()).Width; + + if (width > widest) + widest = width; + } + + return widest; +} + + +} // end namespace gui + +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/irrlicht_changes/static_text.h b/src/irrlicht_changes/static_text.h new file mode 100644 index 0000000..fc58e3e --- /dev/null +++ b/src/irrlicht_changes/static_text.h @@ -0,0 +1,237 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// Copyright (C) 2016 Nathanaëlle Courant +// Modified this class to work with EnrichedStrings too +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#pragma once + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIStaticText.h" +#include "irrArray.h" + +#include "log.h" + +#include <vector> + +#include "util/enriched_string.h" +#include "config.h" +#include <IGUIEnvironment.h> + + +namespace irr +{ + +namespace gui +{ + + const EGUI_ELEMENT_TYPE EGUIET_ENRICHED_STATIC_TEXT = (EGUI_ELEMENT_TYPE)(0x1000); + + class StaticText : public IGUIStaticText + { + public: + + // StaticText is translated by EnrichedString. + // No need to use translate_string() + StaticText(const EnrichedString &text, bool border, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, const core::rect<s32>& rectangle, + bool background = false); + + //! destructor + virtual ~StaticText(); + + static irr::gui::IGUIStaticText *add( + irr::gui::IGUIEnvironment *guienv, + const EnrichedString &text, + const core::rect< s32 > &rectangle, + bool border = false, + bool wordWrap = true, + irr::gui::IGUIElement *parent = NULL, + s32 id = -1, + bool fillBackground = false) + { + if (parent == NULL) { + // parent is NULL, so we must find one, or we need not to drop + // result, but then there will be a memory leak. + // + // What Irrlicht does is to use guienv as a parent, but the problem + // is that guienv is here only an IGUIEnvironment, while it is a + // CGUIEnvironment in Irrlicht, which inherits from both IGUIElement + // and IGUIEnvironment. + // + // A solution would be to dynamic_cast guienv to a + // IGUIElement*, but Irrlicht is shipped without rtti support + // in some distributions, causing the dymanic_cast to segfault. + // + // Thus, to find the parent, we create a dummy StaticText and ask + // for its parent, and then remove it. + irr::gui::IGUIStaticText *dummy_text = + guienv->addStaticText(L"", rectangle, border, wordWrap, + parent, id, fillBackground); + parent = dummy_text->getParent(); + dummy_text->remove(); + } + irr::gui::IGUIStaticText *result = new irr::gui::StaticText( + text, border, guienv, parent, + id, rectangle, fillBackground); + + result->setWordWrap(wordWrap); + result->drop(); + return result; + } + + static irr::gui::IGUIStaticText *add( + irr::gui::IGUIEnvironment *guienv, + const wchar_t *text, + const core::rect< s32 > &rectangle, + bool border = false, + bool wordWrap = true, + irr::gui::IGUIElement *parent = NULL, + s32 id = -1, + bool fillBackground = false) + { + return add(guienv, EnrichedString(text), rectangle, border, wordWrap, parent, + id, fillBackground); + } + + //! draws the element and its children + virtual void draw(); + + //! Sets another skin independent font. + virtual void setOverrideFont(IGUIFont* font=0); + + //! Gets the override font (if any) + virtual IGUIFont* getOverrideFont() const; + + //! Get the font which is used right now for drawing + virtual IGUIFont* getActiveFont() const; + + //! Sets another color for the text. + virtual void setOverrideColor(video::SColor color); + + //! Sets another color for the background. + virtual void setBackgroundColor(video::SColor color); + + //! Sets whether to draw the background + virtual void setDrawBackground(bool draw); + + //! Gets the background color + virtual video::SColor getBackgroundColor() const; + + //! Checks if background drawing is enabled + virtual bool isDrawBackgroundEnabled() const; + + //! Sets whether to draw the border + virtual void setDrawBorder(bool draw); + + //! Checks if border drawing is enabled + virtual bool isDrawBorderEnabled() const; + + //! Sets alignment mode for text + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical); + + //! Gets the override color + virtual video::SColor getOverrideColor() const; + + #if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8 + //! Gets the currently used text color + virtual video::SColor getActiveColor() const; + #endif + + //! Sets if the static text should use the overide color or the + //! color in the gui skin. + virtual void enableOverrideColor(bool enable); + + //! Checks if an override color is enabled + virtual bool isOverrideColorEnabled() const; + + //! Set whether the text in this label should be clipped if it goes outside bounds + virtual void setTextRestrainedInside(bool restrainedInside); + + //! Checks if the text in this label should be clipped if it goes outside bounds + virtual bool isTextRestrainedInside() const; + + //! Enables or disables word wrap for using the static text as + //! multiline text control. + virtual void setWordWrap(bool enable); + + //! Checks if word wrap is enabled + virtual bool isWordWrapEnabled() const; + + //! Sets the new caption of this element. + virtual void setText(const wchar_t* text); + + //! Returns the height of the text in pixels when it is drawn. + virtual s32 getTextHeight() const; + + //! Returns the width of the current text, in the current font + virtual s32 getTextWidth() const; + + //! Updates the absolute position, splits text if word wrap is enabled + virtual void updateAbsolutePosition(); + + //! Set whether the string should be interpreted as right-to-left (RTL) text + /** \note This component does not implement the Unicode bidi standard, the + text of the component should be already RTL if you call this. The + main difference when RTL is enabled is that the linebreaks for multiline + elements are performed starting from the end. + */ + virtual void setRightToLeft(bool rtl); + + //! Checks if the text should be interpreted as right-to-left text + virtual bool isRightToLeft() const; + + virtual bool hasType(EGUI_ELEMENT_TYPE t) const { + return (t == EGUIET_ENRICHED_STATIC_TEXT) || (t == EGUIET_STATIC_TEXT); + }; + + virtual bool hasType(EGUI_ELEMENT_TYPE t) { + return (t == EGUIET_ENRICHED_STATIC_TEXT) || (t == EGUIET_STATIC_TEXT); + }; + + void setText(const EnrichedString &text); + + private: + + //! Breaks the single text line. + void updateText(); + + EGUI_ALIGNMENT HAlign, VAlign; + bool Border; + bool WordWrap; + bool Background; + bool RestrainTextInside; + bool RightToLeft; + + gui::IGUIFont* OverrideFont; + gui::IGUIFont* LastBreakFont; // stored because: if skin changes, line break must be recalculated. + + EnrichedString ColoredText; + std::vector<EnrichedString> BrokenText; + }; + + +} // end namespace gui + +} // end namespace irr + +inline void setStaticText(irr::gui::IGUIStaticText *static_text, const EnrichedString &text) +{ + // dynamic_cast not possible due to some distributions shipped + // without rtti support in irrlicht + if (static_text->hasType(irr::gui::EGUIET_ENRICHED_STATIC_TEXT)) { + irr::gui::StaticText* stext = static_cast<irr::gui::StaticText*>(static_text); + stext->setText(text); + } else { + static_text->setText(text.c_str()); + } +} + +inline void setStaticText(irr::gui::IGUIStaticText *static_text, const wchar_t *text) +{ + setStaticText(static_text, EnrichedString(text, static_text->getOverrideColor())); +} + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/irrlichttypes.h b/src/irrlichttypes.h new file mode 100644 index 0000000..93c2d10 --- /dev/null +++ b/src/irrlichttypes.h @@ -0,0 +1,62 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +/* + * IrrlichtMt already includes stdint.h in irrTypes.h. This works everywhere + * we need it to (including recent MSVC), so should be fine here too. + */ +#include <cstdint> + +#include <irrTypes.h> + +using namespace irr; + +namespace irr { + +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR >= 9) +namespace core { + template <typename T> + inline T roundingError(); + + template <> + inline s16 roundingError() + { + return 0; + } +} +#endif + +} + +#define S8_MIN (-0x7F - 1) +#define S16_MIN (-0x7FFF - 1) +#define S32_MIN (-0x7FFFFFFF - 1) +#define S64_MIN (-0x7FFFFFFFFFFFFFFF - 1) + +#define S8_MAX 0x7F +#define S16_MAX 0x7FFF +#define S32_MAX 0x7FFFFFFF +#define S64_MAX 0x7FFFFFFFFFFFFFFF + +#define U8_MAX 0xFF +#define U16_MAX 0xFFFF +#define U32_MAX 0xFFFFFFFF +#define U64_MAX 0xFFFFFFFFFFFFFFFF diff --git a/src/irrlichttypes_bloated.h b/src/irrlichttypes_bloated.h new file mode 100644 index 0000000..a772a5c --- /dev/null +++ b/src/irrlichttypes_bloated.h @@ -0,0 +1,28 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" + +#include "irr_v2d.h" +#include "irr_v3d.h" +#include "irr_aabb3d.h" + +#include <SColor.h> diff --git a/src/irrlichttypes_extrabloated.h b/src/irrlichttypes_extrabloated.h new file mode 100644 index 0000000..b03ba79 --- /dev/null +++ b/src/irrlichttypes_extrabloated.h @@ -0,0 +1,36 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" + +#ifndef SERVER +#include <IMesh.h> +#include <IImage.h> +#include <IrrlichtDevice.h> +#include <IMeshSceneNode.h> +#include <IDummyTransformationSceneNode.h> +#include <SMesh.h> +#include <ISceneManager.h> +#include <IMeshBuffer.h> +#include <SMeshBuffer.h> +#include <IGUIElement.h> +#include <IGUIEnvironment.h> +#endif diff --git a/src/itemdef.cpp b/src/itemdef.cpp new file mode 100644 index 0000000..a34805b --- /dev/null +++ b/src/itemdef.cpp @@ -0,0 +1,600 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013 Kahrl <kahrl@gmx.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "itemdef.h" + +#include "nodedef.h" +#include "tool.h" +#include "inventory.h" +#ifndef SERVER +#include "client/mapblock_mesh.h" +#include "client/mesh.h" +#include "client/wieldmesh.h" +#include "client/tile.h" +#include "client/client.h" +#endif +#include "log.h" +#include "settings.h" +#include "util/serialize.h" +#include "util/container.h" +#include "util/thread.h" +#include <map> +#include <set> + +/* + ItemDefinition +*/ +ItemDefinition::ItemDefinition() +{ + resetInitial(); +} + +ItemDefinition::ItemDefinition(const ItemDefinition &def) +{ + resetInitial(); + *this = def; +} + +ItemDefinition& ItemDefinition::operator=(const ItemDefinition &def) +{ + if(this == &def) + return *this; + + reset(); + + type = def.type; + name = def.name; + description = def.description; + short_description = def.short_description; + inventory_image = def.inventory_image; + inventory_overlay = def.inventory_overlay; + wield_image = def.wield_image; + wield_overlay = def.wield_overlay; + wield_scale = def.wield_scale; + stack_max = def.stack_max; + usable = def.usable; + liquids_pointable = def.liquids_pointable; + if (def.tool_capabilities) + tool_capabilities = new ToolCapabilities(*def.tool_capabilities); + groups = def.groups; + node_placement_prediction = def.node_placement_prediction; + place_param2 = def.place_param2; + sound_place = def.sound_place; + sound_place_failed = def.sound_place_failed; + range = def.range; + palette_image = def.palette_image; + color = def.color; + return *this; +} + +ItemDefinition::~ItemDefinition() +{ + reset(); +} + +void ItemDefinition::resetInitial() +{ + // Initialize pointers to NULL so reset() does not delete undefined pointers + tool_capabilities = NULL; + reset(); +} + +void ItemDefinition::reset() +{ + type = ITEM_NONE; + name = ""; + description = ""; + short_description = ""; + inventory_image = ""; + inventory_overlay = ""; + wield_image = ""; + wield_overlay = ""; + palette_image = ""; + color = video::SColor(0xFFFFFFFF); + wield_scale = v3f(1.0, 1.0, 1.0); + stack_max = 99; + usable = false; + liquids_pointable = false; + delete tool_capabilities; + tool_capabilities = NULL; + groups.clear(); + sound_place = SimpleSoundSpec(); + sound_place_failed = SimpleSoundSpec(); + range = -1; + node_placement_prediction = ""; + place_param2 = 0; +} + +void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const +{ + // protocol_version >= 37 + u8 version = 6; + writeU8(os, version); + writeU8(os, type); + os << serializeString16(name); + os << serializeString16(description); + os << serializeString16(inventory_image); + os << serializeString16(wield_image); + writeV3F32(os, wield_scale); + writeS16(os, stack_max); + writeU8(os, usable); + writeU8(os, liquids_pointable); + + std::string tool_capabilities_s; + if (tool_capabilities) { + std::ostringstream tmp_os(std::ios::binary); + tool_capabilities->serialize(tmp_os, protocol_version); + tool_capabilities_s = tmp_os.str(); + } + os << serializeString16(tool_capabilities_s); + + writeU16(os, groups.size()); + for (const auto &group : groups) { + os << serializeString16(group.first); + writeS16(os, group.second); + } + + os << serializeString16(node_placement_prediction); + + // Version from ContentFeatures::serialize to keep in sync + sound_place.serialize(os, protocol_version); + sound_place_failed.serialize(os, protocol_version); + + writeF32(os, range); + os << serializeString16(palette_image); + writeARGB8(os, color); + os << serializeString16(inventory_overlay); + os << serializeString16(wield_overlay); + + os << serializeString16(short_description); + + os << place_param2; +} + +void ItemDefinition::deSerialize(std::istream &is, u16 protocol_version) +{ + // Reset everything + reset(); + + // Deserialize + int version = readU8(is); + if (version < 6) + throw SerializationError("unsupported ItemDefinition version"); + + type = (enum ItemType)readU8(is); + name = deSerializeString16(is); + description = deSerializeString16(is); + inventory_image = deSerializeString16(is); + wield_image = deSerializeString16(is); + wield_scale = readV3F32(is); + stack_max = readS16(is); + usable = readU8(is); + liquids_pointable = readU8(is); + + std::string tool_capabilities_s = deSerializeString16(is); + if (!tool_capabilities_s.empty()) { + std::istringstream tmp_is(tool_capabilities_s, std::ios::binary); + tool_capabilities = new ToolCapabilities; + tool_capabilities->deSerialize(tmp_is); + } + + groups.clear(); + u32 groups_size = readU16(is); + for(u32 i=0; i<groups_size; i++){ + std::string name = deSerializeString16(is); + int value = readS16(is); + groups[name] = value; + } + + node_placement_prediction = deSerializeString16(is); + + sound_place.deSerialize(is, protocol_version); + sound_place_failed.deSerialize(is, protocol_version); + + range = readF32(is); + palette_image = deSerializeString16(is); + color = readARGB8(is); + inventory_overlay = deSerializeString16(is); + wield_overlay = deSerializeString16(is); + + // If you add anything here, insert it primarily inside the try-catch + // block to not need to increase the version. + try { + short_description = deSerializeString16(is); + + place_param2 = readU8(is); // 0 if missing + } catch(SerializationError &e) {}; +} + + +/* + CItemDefManager +*/ + +// SUGG: Support chains of aliases? + +class CItemDefManager: public IWritableItemDefManager +{ +#ifndef SERVER + struct ClientCached + { + video::ITexture *inventory_texture; + ItemMesh wield_mesh; + Palette *palette; + + ClientCached(): + inventory_texture(NULL), + palette(NULL) + {} + }; +#endif + +public: + CItemDefManager() + { + +#ifndef SERVER + m_main_thread = std::this_thread::get_id(); +#endif + clear(); + } + virtual ~CItemDefManager() + { +#ifndef SERVER + const std::vector<ClientCached*> &values = m_clientcached.getValues(); + for (ClientCached *cc : values) { + if (cc->wield_mesh.mesh) + cc->wield_mesh.mesh->drop(); + delete cc; + } + +#endif + for (auto &item_definition : m_item_definitions) { + delete item_definition.second; + } + m_item_definitions.clear(); + } + virtual const ItemDefinition& get(const std::string &name_) const + { + // Convert name according to possible alias + std::string name = getAlias(name_); + // Get the definition + auto i = m_item_definitions.find(name); + if (i == m_item_definitions.cend()) + i = m_item_definitions.find("unknown"); + assert(i != m_item_definitions.cend()); + return *(i->second); + } + virtual const std::string &getAlias(const std::string &name) const + { + auto it = m_aliases.find(name); + if (it != m_aliases.cend()) + return it->second; + return name; + } + virtual void getAll(std::set<std::string> &result) const + { + result.clear(); + for (const auto &item_definition : m_item_definitions) { + result.insert(item_definition.first); + } + + for (const auto &alias : m_aliases) { + result.insert(alias.first); + } + } + virtual bool isKnown(const std::string &name_) const + { + // Convert name according to possible alias + std::string name = getAlias(name_); + // Get the definition + return m_item_definitions.find(name) != m_item_definitions.cend(); + } +#ifndef SERVER +public: + ClientCached* createClientCachedDirect(const std::string &name, + Client *client) const + { + infostream<<"Lazily creating item texture and mesh for \"" + <<name<<"\""<<std::endl; + + // This is not thread-safe + sanity_check(std::this_thread::get_id() == m_main_thread); + + // Skip if already in cache + ClientCached *cc = NULL; + m_clientcached.get(name, &cc); + if(cc) + return cc; + + ITextureSource *tsrc = client->getTextureSource(); + const ItemDefinition &def = get(name); + + // Create new ClientCached + cc = new ClientCached(); + + // Create an inventory texture + cc->inventory_texture = NULL; + if (!def.inventory_image.empty()) + cc->inventory_texture = tsrc->getTexture(def.inventory_image); + + ItemStack item = ItemStack(); + item.name = def.name; + + getItemMesh(client, item, &(cc->wield_mesh)); + + cc->palette = tsrc->getPalette(def.palette_image); + + // Put in cache + m_clientcached.set(name, cc); + + return cc; + } + ClientCached* getClientCached(const std::string &name, + Client *client) const + { + ClientCached *cc = NULL; + m_clientcached.get(name, &cc); + if (cc) + return cc; + + if (std::this_thread::get_id() == m_main_thread) { + return createClientCachedDirect(name, client); + } + + // We're gonna ask the result to be put into here + static ResultQueue<std::string, ClientCached*, u8, u8> result_queue; + + // Throw a request in + m_get_clientcached_queue.add(name, 0, 0, &result_queue); + try { + while(true) { + // Wait result for a second + GetResult<std::string, ClientCached*, u8, u8> + result = result_queue.pop_front(1000); + + if (result.key == name) { + return result.item; + } + } + } catch(ItemNotFoundException &e) { + errorstream << "Waiting for clientcached " << name + << " timed out." << std::endl; + return &m_dummy_clientcached; + } + } + // Get item inventory texture + virtual video::ITexture* getInventoryTexture(const std::string &name, + Client *client) const + { + ClientCached *cc = getClientCached(name, client); + if(!cc) + return NULL; + return cc->inventory_texture; + } + // Get item wield mesh + virtual ItemMesh* getWieldMesh(const std::string &name, + Client *client) const + { + ClientCached *cc = getClientCached(name, client); + if(!cc) + return NULL; + return &(cc->wield_mesh); + } + + // Get item palette + virtual Palette* getPalette(const std::string &name, + Client *client) const + { + ClientCached *cc = getClientCached(name, client); + if(!cc) + return NULL; + return cc->palette; + } + + virtual video::SColor getItemstackColor(const ItemStack &stack, + Client *client) const + { + // Look for direct color definition + const std::string &colorstring = stack.metadata.getString("color", 0); + video::SColor directcolor; + if (!colorstring.empty() && parseColorString(colorstring, directcolor, true)) + return directcolor; + // See if there is a palette + Palette *palette = getPalette(stack.name, client); + const std::string &index = stack.metadata.getString("palette_index", 0); + if (palette && !index.empty()) + return (*palette)[mystoi(index, 0, 255)]; + // Fallback color + return get(stack.name).color; + } +#endif + void applyTextureOverrides(const std::vector<TextureOverride> &overrides) + { + infostream << "ItemDefManager::applyTextureOverrides(): Applying " + "overrides to textures" << std::endl; + + for (const TextureOverride& texture_override : overrides) { + if (m_item_definitions.find(texture_override.id) == m_item_definitions.end()) { + continue; // Ignore unknown item + } + + ItemDefinition* itemdef = m_item_definitions[texture_override.id]; + + if (texture_override.hasTarget(OverrideTarget::INVENTORY)) + itemdef->inventory_image = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::WIELD)) + itemdef->wield_image = texture_override.texture; + } + } + void clear() + { + for (auto &i : m_item_definitions) + { + delete i.second; + } + m_item_definitions.clear(); + m_aliases.clear(); + + // Add the four builtin items: + // "" is the hand + // "unknown" is returned whenever an undefined item + // is accessed (is also the unknown node) + // "air" is the air node + // "ignore" is the ignore node + + ItemDefinition* hand_def = new ItemDefinition; + hand_def->name = ""; + hand_def->wield_image = "wieldhand.png"; + hand_def->tool_capabilities = new ToolCapabilities; + m_item_definitions.insert(std::make_pair("", hand_def)); + + ItemDefinition* unknown_def = new ItemDefinition; + unknown_def->type = ITEM_NODE; + unknown_def->name = "unknown"; + m_item_definitions.insert(std::make_pair("unknown", unknown_def)); + + ItemDefinition* air_def = new ItemDefinition; + air_def->type = ITEM_NODE; + air_def->name = "air"; + m_item_definitions.insert(std::make_pair("air", air_def)); + + ItemDefinition* ignore_def = new ItemDefinition; + ignore_def->type = ITEM_NODE; + ignore_def->name = "ignore"; + m_item_definitions.insert(std::make_pair("ignore", ignore_def)); + } + virtual void registerItem(const ItemDefinition &def) + { + TRACESTREAM(<< "ItemDefManager: registering " << def.name << std::endl); + // Ensure that the "" item (the hand) always has ToolCapabilities + if (def.name.empty()) + FATAL_ERROR_IF(!def.tool_capabilities, "Hand does not have ToolCapabilities"); + + if(m_item_definitions.count(def.name) == 0) + m_item_definitions[def.name] = new ItemDefinition(def); + else + *(m_item_definitions[def.name]) = def; + + // Remove conflicting alias if it exists + bool alias_removed = (m_aliases.erase(def.name) != 0); + if(alias_removed) + infostream<<"ItemDefManager: erased alias "<<def.name + <<" because item was defined"<<std::endl; + } + virtual void unregisterItem(const std::string &name) + { + verbosestream<<"ItemDefManager: unregistering \""<<name<<"\""<<std::endl; + + delete m_item_definitions[name]; + m_item_definitions.erase(name); + } + virtual void registerAlias(const std::string &name, + const std::string &convert_to) + { + if (m_item_definitions.find(name) == m_item_definitions.end()) { + TRACESTREAM(<< "ItemDefManager: setting alias " << name + << " -> " << convert_to << std::endl); + m_aliases[name] = convert_to; + } + } + void serialize(std::ostream &os, u16 protocol_version) + { + writeU8(os, 0); // version + u16 count = m_item_definitions.size(); + writeU16(os, count); + + for (const auto &it : m_item_definitions) { + ItemDefinition *def = it.second; + // Serialize ItemDefinition and write wrapped in a string + std::ostringstream tmp_os(std::ios::binary); + def->serialize(tmp_os, protocol_version); + os << serializeString16(tmp_os.str()); + } + + writeU16(os, m_aliases.size()); + + for (const auto &it : m_aliases) { + os << serializeString16(it.first); + os << serializeString16(it.second); + } + } + void deSerialize(std::istream &is, u16 protocol_version) + { + // Clear everything + clear(); + + if(readU8(is) != 0) + throw SerializationError("unsupported ItemDefManager version"); + + u16 count = readU16(is); + for(u16 i=0; i<count; i++) + { + // Deserialize a string and grab an ItemDefinition from it + std::istringstream tmp_is(deSerializeString16(is), std::ios::binary); + ItemDefinition def; + def.deSerialize(tmp_is, protocol_version); + // Register + registerItem(def); + } + u16 num_aliases = readU16(is); + for(u16 i=0; i<num_aliases; i++) + { + std::string name = deSerializeString16(is); + std::string convert_to = deSerializeString16(is); + registerAlias(name, convert_to); + } + } + void processQueue(IGameDef *gamedef) + { +#ifndef SERVER + //NOTE this is only thread safe for ONE consumer thread! + while(!m_get_clientcached_queue.empty()) + { + GetRequest<std::string, ClientCached*, u8, u8> + request = m_get_clientcached_queue.pop(); + + m_get_clientcached_queue.pushResult(request, + createClientCachedDirect(request.key, (Client *)gamedef)); + } +#endif + } +private: + // Key is name + std::map<std::string, ItemDefinition*> m_item_definitions; + // Aliases + StringMap m_aliases; +#ifndef SERVER + // The id of the thread that is allowed to use irrlicht directly + std::thread::id m_main_thread; + // A reference to this can be returned when nothing is found, to avoid NULLs + mutable ClientCached m_dummy_clientcached; + // Cached textures and meshes + mutable MutexedMap<std::string, ClientCached*> m_clientcached; + // Queued clientcached fetches (to be processed by the main thread) + mutable RequestQueue<std::string, ClientCached*, u8, u8> m_get_clientcached_queue; +#endif +}; + +IWritableItemDefManager* createItemDefManager() +{ + return new CItemDefManager(); +} diff --git a/src/itemdef.h b/src/itemdef.h new file mode 100644 index 0000000..0357173 --- /dev/null +++ b/src/itemdef.h @@ -0,0 +1,186 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013 Kahrl <kahrl@gmx.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_extrabloated.h" +#include <string> +#include <iostream> +#include <set> +#include "itemgroup.h" +#include "sound.h" +#include "texture_override.h" // TextureOverride +class IGameDef; +class Client; +struct ToolCapabilities; +#ifndef SERVER +#include "client/tile.h" +struct ItemMesh; +struct ItemStack; +#endif + +/* + Base item definition +*/ + +enum ItemType +{ + ITEM_NONE, + ITEM_NODE, + ITEM_CRAFT, + ITEM_TOOL, +}; + +struct ItemDefinition +{ + /* + Basic item properties + */ + ItemType type; + std::string name; // "" = hand + std::string description; // Shown in tooltip. + std::string short_description; + + /* + Visual properties + */ + std::string inventory_image; // Optional for nodes, mandatory for tools/craftitems + std::string inventory_overlay; // Overlay of inventory_image. + std::string wield_image; // If empty, inventory_image or mesh (only nodes) is used + std::string wield_overlay; // Overlay of wield_image. + std::string palette_image; // If specified, the item will be colorized based on this + video::SColor color; // The fallback color of the node. + v3f wield_scale; + + /* + Item stack and interaction properties + */ + u16 stack_max; + bool usable; + bool liquids_pointable; + // May be NULL. If non-NULL, deleted by destructor + ToolCapabilities *tool_capabilities; + ItemGroupList groups; + SimpleSoundSpec sound_place; + SimpleSoundSpec sound_place_failed; + f32 range; + + // Client shall immediately place this node when player places the item. + // Server will update the precise end result a moment later. + // "" = no prediction + std::string node_placement_prediction; + u8 place_param2; + + /* + Some helpful methods + */ + ItemDefinition(); + ItemDefinition(const ItemDefinition &def); + ItemDefinition& operator=(const ItemDefinition &def); + ~ItemDefinition(); + void reset(); + void serialize(std::ostream &os, u16 protocol_version) const; + void deSerialize(std::istream &is, u16 protocol_version); +private: + void resetInitial(); +}; + +class IItemDefManager +{ +public: + IItemDefManager() = default; + + virtual ~IItemDefManager() = default; + + // Get item definition + virtual const ItemDefinition& get(const std::string &name) const=0; + // Get alias definition + virtual const std::string &getAlias(const std::string &name) const=0; + // Get set of all defined item names and aliases + virtual void getAll(std::set<std::string> &result) const=0; + // Check if item is known + virtual bool isKnown(const std::string &name) const=0; +#ifndef SERVER + // Get item inventory texture + virtual video::ITexture* getInventoryTexture(const std::string &name, + Client *client) const=0; + // Get item wield mesh + virtual ItemMesh* getWieldMesh(const std::string &name, + Client *client) const=0; + // Get item palette + virtual Palette* getPalette(const std::string &name, + Client *client) const = 0; + // Returns the base color of an item stack: the color of all + // tiles that do not define their own color. + virtual video::SColor getItemstackColor(const ItemStack &stack, + Client *client) const = 0; +#endif + + virtual void serialize(std::ostream &os, u16 protocol_version)=0; +}; + +class IWritableItemDefManager : public IItemDefManager +{ +public: + IWritableItemDefManager() = default; + + virtual ~IWritableItemDefManager() = default; + + // Get item definition + virtual const ItemDefinition& get(const std::string &name) const=0; + // Get alias definition + virtual const std::string &getAlias(const std::string &name) const=0; + // Get set of all defined item names and aliases + virtual void getAll(std::set<std::string> &result) const=0; + // Check if item is known + virtual bool isKnown(const std::string &name) const=0; +#ifndef SERVER + // Get item inventory texture + virtual video::ITexture* getInventoryTexture(const std::string &name, + Client *client) const=0; + // Get item wield mesh + virtual ItemMesh* getWieldMesh(const std::string &name, + Client *client) const=0; +#endif + + // Replace the textures of registered nodes with the ones specified in + // the texture pack's override.txt files + virtual void applyTextureOverrides(const std::vector<TextureOverride> &overrides)=0; + + // Remove all registered item and node definitions and aliases + // Then re-add the builtin item definitions + virtual void clear()=0; + // Register item definition + virtual void registerItem(const ItemDefinition &def)=0; + virtual void unregisterItem(const std::string &name)=0; + // Set an alias so that items named <name> will load as <convert_to>. + // Alias is not set if <name> has already been defined. + // Alias will be removed if <name> is defined at a later point of time. + virtual void registerAlias(const std::string &name, + const std::string &convert_to)=0; + + virtual void serialize(std::ostream &os, u16 protocol_version)=0; + virtual void deSerialize(std::istream &is, u16 protocol_version)=0; + + // Do stuff asked by threads that can only be done in the main thread + virtual void processQueue(IGameDef *gamedef)=0; +}; + +IWritableItemDefManager* createItemDefManager(); diff --git a/src/itemgroup.h b/src/itemgroup.h new file mode 100644 index 0000000..fcf7206 --- /dev/null +++ b/src/itemgroup.h @@ -0,0 +1,33 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <unordered_map> + +typedef std::unordered_map<std::string, int> ItemGroupList; + +static inline int itemgroup_get(const ItemGroupList &groups, const std::string &name) +{ + ItemGroupList::const_iterator i = groups.find(name); + if (i == groups.end()) + return 0; + return i->second; +} diff --git a/src/itemstackmetadata.cpp b/src/itemstackmetadata.cpp new file mode 100644 index 0000000..529e014 --- /dev/null +++ b/src/itemstackmetadata.cpp @@ -0,0 +1,118 @@ +/* +Minetest +Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "itemstackmetadata.h" +#include "util/serialize.h" +#include "util/strfnd.h" +#include <algorithm> + +#define DESERIALIZE_START '\x01' +#define DESERIALIZE_KV_DELIM '\x02' +#define DESERIALIZE_PAIR_DELIM '\x03' +#define DESERIALIZE_START_STR "\x01" +#define DESERIALIZE_KV_DELIM_STR "\x02" +#define DESERIALIZE_PAIR_DELIM_STR "\x03" + +#define TOOLCAP_KEY "tool_capabilities" + +void ItemStackMetadata::clear() +{ + Metadata::clear(); + updateToolCapabilities(); +} + +static void sanitize_string(std::string &str) +{ + str.erase(std::remove(str.begin(), str.end(), DESERIALIZE_START), str.end()); + str.erase(std::remove(str.begin(), str.end(), DESERIALIZE_KV_DELIM), str.end()); + str.erase(std::remove(str.begin(), str.end(), DESERIALIZE_PAIR_DELIM), str.end()); +} + +bool ItemStackMetadata::setString(const std::string &name, const std::string &var) +{ + std::string clean_name = name; + std::string clean_var = var; + sanitize_string(clean_name); + sanitize_string(clean_var); + + bool result = Metadata::setString(clean_name, clean_var); + if (clean_name == TOOLCAP_KEY) + updateToolCapabilities(); + return result; +} + +void ItemStackMetadata::serialize(std::ostream &os) const +{ + std::ostringstream os2(std::ios_base::binary); + os2 << DESERIALIZE_START; + for (const auto &stringvar : m_stringvars) { + if (!stringvar.first.empty() || !stringvar.second.empty()) + os2 << stringvar.first << DESERIALIZE_KV_DELIM + << stringvar.second << DESERIALIZE_PAIR_DELIM; + } + os << serializeJsonStringIfNeeded(os2.str()); +} + +void ItemStackMetadata::deSerialize(std::istream &is) +{ + std::string in = deSerializeJsonStringIfNeeded(is); + + m_stringvars.clear(); + + if (!in.empty()) { + if (in[0] == DESERIALIZE_START) { + Strfnd fnd(in); + fnd.to(1); + while (!fnd.at_end()) { + std::string name = fnd.next(DESERIALIZE_KV_DELIM_STR); + std::string var = fnd.next(DESERIALIZE_PAIR_DELIM_STR); + m_stringvars[name] = var; + } + } else { + // BACKWARDS COMPATIBILITY + m_stringvars[""] = in; + } + } + updateToolCapabilities(); +} + +void ItemStackMetadata::updateToolCapabilities() +{ + if (contains(TOOLCAP_KEY)) { + toolcaps_overridden = true; + toolcaps_override = ToolCapabilities(); + std::istringstream is(getString(TOOLCAP_KEY)); + toolcaps_override.deserializeJson(is); + } else { + toolcaps_overridden = false; + } +} + +void ItemStackMetadata::setToolCapabilities(const ToolCapabilities &caps) +{ + std::ostringstream os; + caps.serializeJson(os); + setString(TOOLCAP_KEY, os.str()); +} + +void ItemStackMetadata::clearToolCapabilities() +{ + setString(TOOLCAP_KEY, ""); +} diff --git a/src/itemstackmetadata.h b/src/itemstackmetadata.h new file mode 100644 index 0000000..a7f1349 --- /dev/null +++ b/src/itemstackmetadata.h @@ -0,0 +1,54 @@ +/* +Minetest +Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "metadata.h" +#include "tool.h" + +class Inventory; +class IItemDefManager; + +class ItemStackMetadata : public Metadata +{ +public: + ItemStackMetadata() : toolcaps_overridden(false) {} + + // Overrides + void clear() override; + bool setString(const std::string &name, const std::string &var) override; + + void serialize(std::ostream &os) const; + void deSerialize(std::istream &is); + + const ToolCapabilities &getToolCapabilities( + const ToolCapabilities &default_caps) const + { + return toolcaps_overridden ? toolcaps_override : default_caps; + } + + void setToolCapabilities(const ToolCapabilities &caps); + void clearToolCapabilities(); + +private: + void updateToolCapabilities(); + + bool toolcaps_overridden; + ToolCapabilities toolcaps_override; +}; diff --git a/src/light.cpp b/src/light.cpp new file mode 100644 index 0000000..d5389b4 --- /dev/null +++ b/src/light.cpp @@ -0,0 +1,93 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "light.h" +#include <algorithm> +#include <cmath> +#include "util/numeric.h" +#include "settings.h" + +#ifndef SERVER + +static u8 light_LUT[LIGHT_SUN + 1]; + +// The const ref to light_LUT is what is actually used in the code +const u8 *light_decode_table = light_LUT; + + +struct LightingParams { + float a, b, c; // Lighting curve polynomial coefficients + float boost, center, sigma; // Lighting curve parametric boost + float gamma; // Lighting curve gamma correction +}; + +static LightingParams params; + + +float decode_light_f(float x) +{ + if (x >= 1.0f) // x is often 1.0f + return 1.0f; + x = std::fmax(x, 0.0f); + float brightness = ((params.a * x + params.b) * x + params.c) * x; + brightness += params.boost * + std::exp(-0.5f * sqr((x - params.center) / params.sigma)); + if (brightness <= 0.0f) // May happen if parameters are extreme + return 0.0f; + if (brightness >= 1.0f) + return 1.0f; + return powf(brightness, 1.0f / params.gamma); +} + + +// Initialize or update the light value tables using the specified gamma +void set_light_table(float gamma) +{ +// Lighting curve bounding gradients + const float alpha = rangelim(g_settings->getFloat("lighting_alpha"), 0.0f, 3.0f); + const float beta = rangelim(g_settings->getFloat("lighting_beta"), 0.0f, 3.0f); +// Lighting curve polynomial coefficients + params.a = alpha + beta - 2.0f; + params.b = 3.0f - 2.0f * alpha - beta; + params.c = alpha; +// Lighting curve parametric boost + params.boost = rangelim(g_settings->getFloat("lighting_boost"), 0.0f, 0.4f); + params.center = rangelim(g_settings->getFloat("lighting_boost_center"), 0.0f, 1.0f); + params.sigma = rangelim(g_settings->getFloat("lighting_boost_spread"), 0.0f, 0.4f); +// Lighting curve gamma correction + params.gamma = rangelim(gamma, 0.33f, 3.0f); + +// Boundary values should be fixed + light_LUT[0] = 0; + light_LUT[LIGHT_SUN] = 255; + + for (size_t i = 1; i < LIGHT_SUN; i++) { + float brightness = decode_light_f((float)i / LIGHT_SUN); + // Strictly speaking, rangelim is not necessary here—if the implementation + // is conforming. But we don’t want problems in any case. + light_LUT[i] = rangelim((s32)(255.0f * brightness), 0, 255); + + // Ensure light brightens with each level + if (i > 0 && light_LUT[i] <= light_LUT[i - 1]) { + light_LUT[i] = std::min((u8)254, light_LUT[i - 1]) + 1; + } + } +} + +#endif diff --git a/src/light.h b/src/light.h new file mode 100644 index 0000000..44082a1 --- /dev/null +++ b/src/light.h @@ -0,0 +1,82 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include <cassert> +#include "irrlichttypes.h" + +/* + Lower level lighting stuff +*/ + +// This directly sets the range of light. +// Actually this is not the real maximum, and this is not the brightest, the +// brightest is LIGHT_SUN. +// If changed, this constant as defined in builtin/game/constants.lua must +// also be changed. +#define LIGHT_MAX 14 +// Light is stored as 4 bits, thus 15 is the maximum. +// This brightness is reserved for sunlight +#define LIGHT_SUN 15 + +#ifndef SERVER + +/** + * \internal + * + * \warning DO NOT USE this directly; it is here simply so that decode_light() + * can be inlined. + * + * Array size is #LIGHTMAX+1 + * + * The array is a lookup table to convert the internal representation of light + * (brightness) to the display brightness. + * + */ +extern const u8 *light_decode_table; + +// 0 <= light <= LIGHT_SUN +// 0 <= return value <= 255 +inline u8 decode_light(u8 light) +{ + // assert(light <= LIGHT_SUN); + if (light > LIGHT_SUN) + light = LIGHT_SUN; + return light_decode_table[light]; +} + +// 0.0 <= light <= 1.0 +// 0.0 <= return value <= 1.0 +float decode_light_f(float light_f); + +void set_light_table(float gamma); + +#endif // ifndef SERVER + +// 0 <= daylight_factor <= 1000 +// 0 <= lightday, lightnight <= LIGHT_SUN +// 0 <= return value <= LIGHT_SUN +inline u8 blend_light(u32 daylight_factor, u8 lightday, u8 lightnight) +{ + u32 c = 1000; + u32 l = ((daylight_factor * lightday + (c - daylight_factor) * lightnight)) / c; + if (l > LIGHT_SUN) + l = LIGHT_SUN; + return l; +} diff --git a/src/lighting.h b/src/lighting.h new file mode 100644 index 0000000..e0d9cee --- /dev/null +++ b/src/lighting.h @@ -0,0 +1,27 @@ +/* +Minetest +Copyright (C) 2021 x2048, Dmitry Kostenko <codeforsmile@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +/** Describes ambient light settings for a player + */ +struct Lighting +{ + float shadow_intensity {0.0f}; +}; diff --git a/src/log.cpp b/src/log.cpp new file mode 100644 index 0000000..ef998f1 --- /dev/null +++ b/src/log.cpp @@ -0,0 +1,395 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "log.h" + +#include "threading/mutex_auto_lock.h" +#include "debug.h" +#include "gettime.h" +#include "porting.h" +#include "settings.h" +#include "config.h" +#include "exceptions.h" +#include "util/numeric.h" +#include "log.h" + +#include <sstream> +#include <iostream> +#include <algorithm> +#include <cerrno> +#include <cstring> + +class LevelTarget : public LogTarget { +public: + LevelTarget(Logger &logger, LogLevel level, bool raw = false) : + m_logger(logger), + m_level(level), + m_raw(raw) + {} + + virtual bool hasOutput() override { + return m_logger.hasOutput(m_level); + } + + virtual void log(const std::string &buf) override { + if (!m_raw) { + m_logger.log(m_level, buf); + } else { + m_logger.logRaw(m_level, buf); + } + } + +private: + Logger &m_logger; + LogLevel m_level; + bool m_raw; +}; + +//// +//// Globals +//// + +Logger g_logger; + +#ifdef __ANDROID__ +AndroidLogOutput stdout_output; +AndroidLogOutput stderr_output; +#else +StreamLogOutput stdout_output(std::cout); +StreamLogOutput stderr_output(std::cerr); +#endif + +LevelTarget none_target_raw(g_logger, LL_NONE, true); +LevelTarget none_target(g_logger, LL_NONE); +LevelTarget error_target(g_logger, LL_ERROR); +LevelTarget warning_target(g_logger, LL_WARNING); +LevelTarget action_target(g_logger, LL_ACTION); +LevelTarget info_target(g_logger, LL_INFO); +LevelTarget verbose_target(g_logger, LL_VERBOSE); +LevelTarget trace_target(g_logger, LL_TRACE); + +thread_local LogStream dstream(none_target); +thread_local LogStream rawstream(none_target_raw); +thread_local LogStream errorstream(error_target); +thread_local LogStream warningstream(warning_target); +thread_local LogStream actionstream(action_target); +thread_local LogStream infostream(info_target); +thread_local LogStream verbosestream(verbose_target); +thread_local LogStream tracestream(trace_target); +thread_local LogStream derr_con(verbose_target); +thread_local LogStream dout_con(trace_target); + +// Android +#ifdef __ANDROID__ + +static unsigned int g_level_to_android[] = { + ANDROID_LOG_INFO, // LL_NONE + //ANDROID_LOG_FATAL, + ANDROID_LOG_ERROR, // LL_ERROR + ANDROID_LOG_WARN, // LL_WARNING + ANDROID_LOG_WARN, // LL_ACTION + //ANDROID_LOG_INFO, + ANDROID_LOG_DEBUG, // LL_INFO + ANDROID_LOG_VERBOSE, // LL_VERBOSE + ANDROID_LOG_VERBOSE, // LL_TRACE +}; + +void AndroidLogOutput::logRaw(LogLevel lev, const std::string &line) { + STATIC_ASSERT(ARRLEN(g_level_to_android) == LL_MAX, + mismatch_between_android_and_internal_loglevels); + __android_log_print(g_level_to_android[lev], + PROJECT_NAME_C, "%s", line.c_str()); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// + + +//// +//// Logger +//// + +LogLevel Logger::stringToLevel(const std::string &name) +{ + if (name == "none") + return LL_NONE; + else if (name == "error") + return LL_ERROR; + else if (name == "warning") + return LL_WARNING; + else if (name == "action") + return LL_ACTION; + else if (name == "info") + return LL_INFO; + else if (name == "verbose") + return LL_VERBOSE; + else if (name == "trace") + return LL_TRACE; + else + return LL_MAX; +} + +void Logger::addOutput(ILogOutput *out) +{ + addOutputMaxLevel(out, (LogLevel)(LL_MAX - 1)); +} + +void Logger::addOutput(ILogOutput *out, LogLevel lev) +{ + MutexAutoLock lock(m_mutex); + m_outputs[lev].push_back(out); + m_has_outputs[lev] = true; +} + +void Logger::addOutputMasked(ILogOutput *out, LogLevelMask mask) +{ + MutexAutoLock lock(m_mutex); + for (size_t i = 0; i < LL_MAX; i++) { + if (mask & LOGLEVEL_TO_MASKLEVEL(i)) { + m_outputs[i].push_back(out); + m_has_outputs[i] = true; + } + } +} + +void Logger::addOutputMaxLevel(ILogOutput *out, LogLevel lev) +{ + MutexAutoLock lock(m_mutex); + assert(lev < LL_MAX); + for (size_t i = 0; i <= lev; i++) { + m_outputs[i].push_back(out); + m_has_outputs[i] = true; + } +} + +LogLevelMask Logger::removeOutput(ILogOutput *out) +{ + MutexAutoLock lock(m_mutex); + LogLevelMask ret_mask = 0; + for (size_t i = 0; i < LL_MAX; i++) { + std::vector<ILogOutput *>::iterator it; + + it = std::find(m_outputs[i].begin(), m_outputs[i].end(), out); + if (it != m_outputs[i].end()) { + ret_mask |= LOGLEVEL_TO_MASKLEVEL(i); + m_outputs[i].erase(it); + m_has_outputs[i] = !m_outputs[i].empty(); + } + } + return ret_mask; +} + +void Logger::setLevelSilenced(LogLevel lev, bool silenced) +{ + m_silenced_levels[lev] = silenced; +} + +void Logger::registerThread(const std::string &name) +{ + std::thread::id id = std::this_thread::get_id(); + MutexAutoLock lock(m_mutex); + m_thread_names[id] = name; +} + +void Logger::deregisterThread() +{ + std::thread::id id = std::this_thread::get_id(); + MutexAutoLock lock(m_mutex); + m_thread_names.erase(id); +} + +const std::string Logger::getLevelLabel(LogLevel lev) +{ + static const std::string names[] = { + "", + "ERROR", + "WARNING", + "ACTION", + "INFO", + "VERBOSE", + "TRACE", + }; + assert(lev < LL_MAX && lev >= 0); + STATIC_ASSERT(ARRLEN(names) == LL_MAX, + mismatch_between_loglevel_names_and_enum); + return names[lev]; +} + +LogColor Logger::color_mode = LOG_COLOR_AUTO; + +const std::string Logger::getThreadName() +{ + std::map<std::thread::id, std::string>::const_iterator it; + + std::thread::id id = std::this_thread::get_id(); + it = m_thread_names.find(id); + if (it != m_thread_names.end()) + return it->second; + + std::ostringstream os; + os << "#0x" << std::hex << id; + return os.str(); +} + +void Logger::log(LogLevel lev, const std::string &text) +{ + if (m_silenced_levels[lev]) + return; + + const std::string thread_name = getThreadName(); + const std::string label = getLevelLabel(lev); + const std::string timestamp = getTimestamp(); + std::ostringstream os(std::ios_base::binary); + os << timestamp << ": " << label << "[" << thread_name << "]: " << text; + + logToOutputs(lev, os.str(), timestamp, thread_name, text); +} + +void Logger::logRaw(LogLevel lev, const std::string &text) +{ + if (m_silenced_levels[lev]) + return; + + logToOutputsRaw(lev, text); +} + +void Logger::logToOutputsRaw(LogLevel lev, const std::string &line) +{ + MutexAutoLock lock(m_mutex); + for (size_t i = 0; i != m_outputs[lev].size(); i++) + m_outputs[lev][i]->logRaw(lev, line); +} + +void Logger::logToOutputs(LogLevel lev, const std::string &combined, + const std::string &time, const std::string &thread_name, + const std::string &payload_text) +{ + MutexAutoLock lock(m_mutex); + for (size_t i = 0; i != m_outputs[lev].size(); i++) + m_outputs[lev][i]->log(lev, combined, time, thread_name, payload_text); +} + +//// +//// *LogOutput methods +//// + +void FileLogOutput::setFile(const std::string &filename, s64 file_size_max) +{ + // Only move debug.txt if there is a valid maximum file size + bool is_too_large = false; + if (file_size_max > 0) { + std::ifstream ifile(filename, std::ios::binary | std::ios::ate); + is_too_large = ifile.tellg() > file_size_max; + ifile.close(); + } + + if (is_too_large) { + std::string filename_secondary = filename + ".1"; + actionstream << "The log file grew too big; it is moved to " << + filename_secondary << std::endl; + remove(filename_secondary.c_str()); + rename(filename.c_str(), filename_secondary.c_str()); + } + m_stream.open(filename, std::ios::app | std::ios::ate); + + if (!m_stream.good()) + throw FileNotGoodException("Failed to open log file " + + filename + ": " + strerror(errno)); + m_stream << "\n\n" + "-------------" << std::endl << + " Separator" << std::endl << + "-------------\n" << std::endl; +} + +void StreamLogOutput::logRaw(LogLevel lev, const std::string &line) +{ + bool colored_message = (Logger::color_mode == LOG_COLOR_ALWAYS) || + (Logger::color_mode == LOG_COLOR_AUTO && is_tty); + if (colored_message) { + switch (lev) { + case LL_ERROR: + // error is red + m_stream << "\033[91m"; + break; + case LL_WARNING: + // warning is yellow + m_stream << "\033[93m"; + break; + case LL_INFO: + // info is a bit dark + m_stream << "\033[37m"; + break; + case LL_VERBOSE: + case LL_TRACE: + // verbose is darker than info + m_stream << "\033[2m"; + break; + default: + // action is white + colored_message = false; + } + } + + m_stream << line << std::endl; + + if (colored_message) { + // reset to white color + m_stream << "\033[0m"; + } +} + +void LogOutputBuffer::updateLogLevel() +{ + const std::string &conf_loglev = g_settings->get("chat_log_level"); + LogLevel log_level = Logger::stringToLevel(conf_loglev); + if (log_level == LL_MAX) { + warningstream << "Supplied unrecognized chat_log_level; " + "showing none." << std::endl; + log_level = LL_NONE; + } + + m_logger.removeOutput(this); + m_logger.addOutputMaxLevel(this, log_level); +} + +void LogOutputBuffer::logRaw(LogLevel lev, const std::string &line) +{ + std::string color; + + if (!g_settings->getBool("disable_escape_sequences")) { + switch (lev) { + case LL_ERROR: // red + color = "\x1b(c@#F00)"; + break; + case LL_WARNING: // yellow + color = "\x1b(c@#EE0)"; + break; + case LL_INFO: // grey + color = "\x1b(c@#BBB)"; + break; + case LL_VERBOSE: // dark grey + case LL_TRACE: + color = "\x1b(c@#888)"; + break; + default: break; + } + } + MutexAutoLock lock(m_buffer_mutex); + m_buffer.emplace(color.append(line)); +} diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000..0a84332 --- /dev/null +++ b/src/log.h @@ -0,0 +1,375 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <atomic> +#include <map> +#include <queue> +#include <string> +#include <fstream> +#include <thread> +#include <mutex> +#if !defined(_WIN32) // POSIX + #include <unistd.h> +#endif +#include "threading/mutex_auto_lock.h" +#include "util/basic_macros.h" +#include "util/stream.h" +#include "irrlichttypes.h" + +class ILogOutput; + +enum LogLevel { + LL_NONE, // Special level that is always printed + LL_ERROR, + LL_WARNING, + LL_ACTION, // In-game actions + LL_INFO, + LL_VERBOSE, + LL_TRACE, + LL_MAX, +}; + +enum LogColor { + LOG_COLOR_NEVER, + LOG_COLOR_ALWAYS, + LOG_COLOR_AUTO, +}; + +typedef u8 LogLevelMask; +#define LOGLEVEL_TO_MASKLEVEL(x) (1 << x) + +class Logger { +public: + void addOutput(ILogOutput *out); + void addOutput(ILogOutput *out, LogLevel lev); + void addOutputMasked(ILogOutput *out, LogLevelMask mask); + void addOutputMaxLevel(ILogOutput *out, LogLevel lev); + LogLevelMask removeOutput(ILogOutput *out); + void setLevelSilenced(LogLevel lev, bool silenced); + + void registerThread(const std::string &name); + void deregisterThread(); + + void log(LogLevel lev, const std::string &text); + // Logs without a prefix + void logRaw(LogLevel lev, const std::string &text); + + static LogLevel stringToLevel(const std::string &name); + static const std::string getLevelLabel(LogLevel lev); + + bool hasOutput(LogLevel level) { + return m_has_outputs[level].load(std::memory_order_relaxed); + } + + static LogColor color_mode; + +private: + void logToOutputsRaw(LogLevel, const std::string &line); + void logToOutputs(LogLevel, const std::string &combined, + const std::string &time, const std::string &thread_name, + const std::string &payload_text); + + const std::string getThreadName(); + + std::vector<ILogOutput *> m_outputs[LL_MAX]; + std::atomic<bool> m_has_outputs[LL_MAX]; + + // Should implement atomic loads and stores (even though it's only + // written to when one thread has access currently). + // Works on all known architectures (x86, ARM, MIPS). + volatile bool m_silenced_levels[LL_MAX]; + std::map<std::thread::id, std::string> m_thread_names; + mutable std::mutex m_mutex; +}; + +class ILogOutput { +public: + virtual void logRaw(LogLevel, const std::string &line) = 0; + virtual void log(LogLevel, const std::string &combined, + const std::string &time, const std::string &thread_name, + const std::string &payload_text) = 0; +}; + +class ICombinedLogOutput : public ILogOutput { +public: + void log(LogLevel lev, const std::string &combined, + const std::string &time, const std::string &thread_name, + const std::string &payload_text) + { + logRaw(lev, combined); + } +}; + +class StreamLogOutput : public ICombinedLogOutput { +public: + StreamLogOutput(std::ostream &stream) : + m_stream(stream) + { +#if !defined(_WIN32) + is_tty = isatty(fileno(stdout)); +#else + is_tty = false; +#endif + } + + void logRaw(LogLevel lev, const std::string &line); + +private: + std::ostream &m_stream; + bool is_tty; +}; + +class FileLogOutput : public ICombinedLogOutput { +public: + void setFile(const std::string &filename, s64 file_size_max); + + void logRaw(LogLevel lev, const std::string &line) + { + m_stream << line << std::endl; + } + +private: + std::ofstream m_stream; +}; + +class LogOutputBuffer : public ICombinedLogOutput { +public: + LogOutputBuffer(Logger &logger) : + m_logger(logger) + { + updateLogLevel(); + }; + + virtual ~LogOutputBuffer() + { + m_logger.removeOutput(this); + } + + void updateLogLevel(); + + void logRaw(LogLevel lev, const std::string &line); + + void clear() + { + MutexAutoLock lock(m_buffer_mutex); + m_buffer = std::queue<std::string>(); + } + + bool empty() const + { + MutexAutoLock lock(m_buffer_mutex); + return m_buffer.empty(); + } + + std::string get() + { + MutexAutoLock lock(m_buffer_mutex); + if (m_buffer.empty()) + return ""; + std::string s = std::move(m_buffer.front()); + m_buffer.pop(); + return s; + } + +private: + // g_logger serializes calls to logRaw() with a mutex, but that + // doesn't prevent get() / clear() from being called on top of it. + // This mutex prevents that. + mutable std::mutex m_buffer_mutex; + std::queue<std::string> m_buffer; + Logger &m_logger; +}; + +#ifdef __ANDROID__ +class AndroidLogOutput : public ICombinedLogOutput { +public: + void logRaw(LogLevel lev, const std::string &line); +}; +#endif + +/* + * LogTarget + * + * This is the interface that sits between the LogStreams and the global logger. + * Primarily used to route streams to log levels, but could also enable other + * custom behavior. + * + */ +class LogTarget { +public: + // Must be thread-safe. These can be called from any thread. + virtual bool hasOutput() = 0; + virtual void log(const std::string &buf) = 0; +}; + + +/* + * StreamProxy + * + * An ostream-like object that can proxy to a real ostream or do nothing, + * depending on how it is configured. See LogStream below. + * + */ +class StreamProxy { +public: + StreamProxy(std::ostream *os) : m_os(os) { } + + template<typename T> + StreamProxy& operator<<(T&& arg) { + if (m_os) { + *m_os << std::forward<T>(arg); + } + return *this; + } + + StreamProxy& operator<<(std::ostream& (*manip)(std::ostream&)) { + if (m_os) { + *m_os << manip; + } + return *this; + } + +private: + std::ostream *m_os; +}; + + +/* + * LogStream + * + * The public interface for log streams (infostream, verbosestream, etc). + * + * LogStream minimizes the work done when a given stream is off. (meaning + * it has no output targets, so it goes to /dev/null) + * + * For example, consider: + * + * verbosestream << "hello world" << 123 << std::endl; + * + * The compiler evaluates this as: + * + * (((verbosestream << "hello world") << 123) << std::endl) + * ^ ^ + * + * If `verbosestream` is on, the innermost expression (marked by ^) will return + * a StreamProxy that forwards to a real ostream, that feeds into the logger. + * However, if `verbosestream` is off, it will return a StreamProxy that does + * nothing on all later operations. Specifically, CPU time won't be wasted + * writing "hello world" and 123 into a buffer, or formatting the log entry. + * + * It is also possible to directly check if the stream is on/off: + * + * if (verbosestream) { + * auto data = ComputeExpensiveDataForTheLog(); + * verbosestream << data << endl; + * } + * +*/ + +class LogStream { +public: + LogStream() = delete; + DISABLE_CLASS_COPY(LogStream); + + LogStream(LogTarget &target) : + m_target(target), + m_buffer(std::bind(&LogStream::internalFlush, this, std::placeholders::_1)), + m_dummy_buffer(), + m_stream(&m_buffer), + m_dummy_stream(&m_dummy_buffer), + m_proxy(&m_stream), + m_dummy_proxy(nullptr) { } + + template<typename T> + StreamProxy& operator<<(T&& arg) { + StreamProxy& sp = m_target.hasOutput() ? m_proxy : m_dummy_proxy; + sp << std::forward<T>(arg); + return sp; + } + + StreamProxy& operator<<(std::ostream& (*manip)(std::ostream&)) { + StreamProxy& sp = m_target.hasOutput() ? m_proxy : m_dummy_proxy; + sp << manip; + return sp; + } + + operator bool() { + return m_target.hasOutput(); + } + + void internalFlush(const std::string &buf) { + m_target.log(buf); + } + + operator std::ostream&() { + return m_target.hasOutput() ? m_stream : m_dummy_stream; + } + +private: + // 10 streams per thread x (256 + overhead) ~ 3K per thread + static const int BUFFER_LENGTH = 256; + LogTarget &m_target; + StringStreamBuffer<BUFFER_LENGTH> m_buffer; + DummyStreamBuffer m_dummy_buffer; + std::ostream m_stream; + std::ostream m_dummy_stream; + StreamProxy m_proxy; + StreamProxy m_dummy_proxy; + +}; + +#ifdef __ANDROID__ +extern AndroidLogOutput stdout_output; +extern AndroidLogOutput stderr_output; +#else +extern StreamLogOutput stdout_output; +extern StreamLogOutput stderr_output; +#endif + +extern Logger g_logger; + +/* + * By making the streams thread_local, each thread has its own + * private buffer. Two or more threads can write to the same stream + * simultaneously (lock-free), and there won't be any interference. + * + * The finished lines are sent to a LogTarget which is a global (not thread-local) + * object, and from there relayed to g_logger. The final writes are serialized + * by the mutex in g_logger. +*/ + +extern thread_local LogStream dstream; +extern thread_local LogStream rawstream; // Writes directly to all LL_NONE log outputs with no prefix. +extern thread_local LogStream errorstream; +extern thread_local LogStream warningstream; +extern thread_local LogStream actionstream; +extern thread_local LogStream infostream; +extern thread_local LogStream verbosestream; +extern thread_local LogStream tracestream; +// TODO: Search/replace these with verbose/tracestream +extern thread_local LogStream derr_con; +extern thread_local LogStream dout_con; + +#define TRACESTREAM(x) do { \ + if (tracestream) { \ + tracestream x; \ + } \ +} while (0) diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..ebd1f74 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,1130 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "irrlichttypes.h" // must be included before anything irrlicht, see comment in the file +#include "irrlicht.h" // createDevice +#include "irrlichttypes_extrabloated.h" +#include "benchmark/benchmark.h" +#include "chat_interface.h" +#include "debug.h" +#include "unittest/test.h" +#include "server.h" +#include "filesys.h" +#include "version.h" +#include "client/game.h" +#include "defaultsettings.h" +#include "gettext.h" +#include "log.h" +#include "util/quicktune.h" +#include "httpfetch.h" +#include "gameparams.h" +#include "database/database.h" +#include "config.h" +#include "player.h" +#include "porting.h" +#include "network/socket.h" +#include "mapblock.h" +#if USE_CURSES + #include "terminal_chat_console.h" +#endif +#ifndef SERVER +#include "gui/guiMainMenu.h" +#include "client/clientlauncher.h" +#include "gui/guiEngine.h" +#include "gui/mainmenumanager.h" +#endif +#ifdef HAVE_TOUCHSCREENGUI + #include "gui/touchscreengui.h" +#endif + +// for version information only +extern "C" { +#if USE_LUAJIT + #include <luajit.h> +#else + #include <lua.h> +#endif +} + +#if !defined(__cpp_rtti) || !defined(__cpp_exceptions) +#error Minetest cannot be built without exceptions or RTTI +#endif + +#if defined(__MINGW32__) && !defined(__MINGW64__) && !defined(__clang__) && \ + (__GNUC__ < 11 || (__GNUC__ == 11 && __GNUC_MINOR__ < 1)) +// see e.g. https://github.com/minetest/minetest/issues/10137 +#warning ================================== +#warning 32-bit MinGW gcc before 11.1 has known issues with crashes on thread exit, you should upgrade. +#warning ================================== +#endif + +#define DEBUGFILE "debug.txt" +#define DEFAULT_SERVER_PORT 30000 + +typedef std::map<std::string, ValueSpec> OptionList; + +/********************************************************************** + * Private functions + **********************************************************************/ + +static bool get_cmdline_opts(int argc, char *argv[], Settings *cmd_args); +static void set_allowed_options(OptionList *allowed_options); + +static void print_help(const OptionList &allowed_options); +static void print_allowed_options(const OptionList &allowed_options); +static void print_version(); +static void print_worldspecs(const std::vector<WorldSpec> &worldspecs, + std::ostream &os, bool print_name = true, bool print_path = true); +static void print_modified_quicktune_values(); + +static void list_game_ids(); +static void list_worlds(bool print_name, bool print_path); +static bool setup_log_params(const Settings &cmd_args); +static bool create_userdata_path(); +static bool init_common(const Settings &cmd_args, int argc, char *argv[]); +static void uninit_common(); +static void startup_message(); +static bool read_config_file(const Settings &cmd_args); +static void init_log_streams(const Settings &cmd_args); + +static bool game_configure(GameParams *game_params, const Settings &cmd_args); +static void game_configure_port(GameParams *game_params, const Settings &cmd_args); + +static bool game_configure_world(GameParams *game_params, const Settings &cmd_args); +static bool get_world_from_cmdline(GameParams *game_params, const Settings &cmd_args); +static bool get_world_from_config(GameParams *game_params, const Settings &cmd_args); +static bool auto_select_world(GameParams *game_params); +static std::string get_clean_world_path(const std::string &path); + +static bool game_configure_subgame(GameParams *game_params, const Settings &cmd_args); +static bool get_game_from_cmdline(GameParams *game_params, const Settings &cmd_args); +static bool determine_subgame(GameParams *game_params); + +static bool run_dedicated_server(const GameParams &game_params, const Settings &cmd_args); +static bool migrate_map_database(const GameParams &game_params, const Settings &cmd_args); +static bool recompress_map_database(const GameParams &game_params, const Settings &cmd_args, const Address &addr); + +/**********************************************************************/ + + +FileLogOutput file_log_output; + +static OptionList allowed_options; + +int main(int argc, char *argv[]) +{ + int retval; + debug_set_exception_handler(); + + g_logger.registerThread("Main"); + g_logger.addOutputMaxLevel(&stderr_output, LL_ACTION); + + Settings cmd_args; + bool cmd_args_ok = get_cmdline_opts(argc, argv, &cmd_args); + if (!cmd_args_ok + || cmd_args.getFlag("help") + || cmd_args.exists("nonopt1")) { + porting::attachOrCreateConsole(); + print_help(allowed_options); + return cmd_args_ok ? 0 : 1; + } + if (cmd_args.getFlag("console")) + porting::attachOrCreateConsole(); + + if (cmd_args.getFlag("version")) { + porting::attachOrCreateConsole(); + print_version(); + return 0; + } + + if (!setup_log_params(cmd_args)) + return 1; + + porting::signal_handler_init(); + +#ifdef __ANDROID__ + porting::initAndroid(); + porting::initializePathsAndroid(); +#else + porting::initializePaths(); +#endif + + if (!create_userdata_path()) { + errorstream << "Cannot create user data directory" << std::endl; + return 1; + } + + // Debug handler + BEGIN_DEBUG_EXCEPTION_HANDLER + + // List gameids if requested + if (cmd_args.exists("gameid") && cmd_args.get("gameid") == "list") { + list_game_ids(); + return 0; + } + + // List worlds, world names, and world paths if requested + if (cmd_args.exists("worldlist")) { + if (cmd_args.get("worldlist") == "name") { + list_worlds(true, false); + } else if (cmd_args.get("worldlist") == "path") { + list_worlds(false, true); + } else if (cmd_args.get("worldlist") == "both") { + list_worlds(true, true); + } else { + errorstream << "Invalid --worldlist value: " + << cmd_args.get("worldlist") << std::endl; + return 1; + } + return 0; + } + + if (!init_common(cmd_args, argc, argv)) + return 1; + + if (g_settings->getBool("enable_console")) + porting::attachOrCreateConsole(); + +#ifndef __ANDROID__ + // Run unit tests + if (cmd_args.getFlag("run-unittests")) { +#if BUILD_UNITTESTS + return run_tests(); +#else + errorstream << "Unittest support is not enabled in this binary. " + << "If you want to enable it, compile project with BUILD_UNITTESTS=1 flag." + << std::endl; + return 1; +#endif + } + + // Run benchmarks + if (cmd_args.getFlag("run-benchmarks")) { +#if BUILD_BENCHMARKS + return run_benchmarks(); +#else + errorstream << "Benchmark support is not enabled in this binary. " + << "If you want to enable it, compile project with BUILD_BENCHMARKS=1 flag." + << std::endl; + return 1; +#endif + } +#endif // __ANDROID__ + + GameStartData game_params; +#ifdef SERVER + porting::attachOrCreateConsole(); + game_params.is_dedicated_server = true; +#else + const bool isServer = cmd_args.getFlag("server"); + if (isServer) + porting::attachOrCreateConsole(); + game_params.is_dedicated_server = isServer; +#endif + + if (!game_configure(&game_params, cmd_args)) + return 1; + + sanity_check(!game_params.world_path.empty()); + + if (game_params.is_dedicated_server) + return run_dedicated_server(game_params, cmd_args) ? 0 : 1; + +#ifndef SERVER + retval = ClientLauncher().run(game_params, cmd_args) ? 0 : 1; +#else + retval = 0; +#endif + + // Update configuration file + if (!g_settings_path.empty()) + g_settings->updateConfigFile(g_settings_path.c_str()); + + print_modified_quicktune_values(); + + END_DEBUG_EXCEPTION_HANDLER + + return retval; +} + + +/***************************************************************************** + * Startup / Init + *****************************************************************************/ + + +static bool get_cmdline_opts(int argc, char *argv[], Settings *cmd_args) +{ + set_allowed_options(&allowed_options); + + return cmd_args->parseCommandLine(argc, argv, allowed_options); +} + +static void set_allowed_options(OptionList *allowed_options) +{ + allowed_options->clear(); + + allowed_options->insert(std::make_pair("help", ValueSpec(VALUETYPE_FLAG, + _("Show allowed options")))); + allowed_options->insert(std::make_pair("version", ValueSpec(VALUETYPE_FLAG, + _("Show version information")))); + allowed_options->insert(std::make_pair("config", ValueSpec(VALUETYPE_STRING, + _("Load configuration from specified file")))); + allowed_options->insert(std::make_pair("port", ValueSpec(VALUETYPE_STRING, + _("Set network port (UDP)")))); + allowed_options->insert(std::make_pair("run-unittests", ValueSpec(VALUETYPE_FLAG, + _("Run the unit tests and exit")))); + allowed_options->insert(std::make_pair("run-benchmarks", ValueSpec(VALUETYPE_FLAG, + _("Run the benchmarks and exit")))); + allowed_options->insert(std::make_pair("map-dir", ValueSpec(VALUETYPE_STRING, + _("Same as --world (deprecated)")))); + allowed_options->insert(std::make_pair("world", ValueSpec(VALUETYPE_STRING, + _("Set world path (implies local game if used with option --go)")))); + allowed_options->insert(std::make_pair("worldname", ValueSpec(VALUETYPE_STRING, + _("Set world by name (implies local game if used with option --go)")))); + allowed_options->insert(std::make_pair("worldlist", ValueSpec(VALUETYPE_STRING, + _("Get list of worlds ('path' lists paths, " + "'name' lists names, 'both' lists both)")))); + allowed_options->insert(std::make_pair("quiet", ValueSpec(VALUETYPE_FLAG, + _("Print to console errors only")))); + allowed_options->insert(std::make_pair("color", ValueSpec(VALUETYPE_STRING, + _("Coloured logs ('always', 'never' or 'auto'), defaults to 'auto'" + )))); + allowed_options->insert(std::make_pair("info", ValueSpec(VALUETYPE_FLAG, + _("Print more information to console")))); + allowed_options->insert(std::make_pair("verbose", ValueSpec(VALUETYPE_FLAG, + _("Print even more information to console")))); + allowed_options->insert(std::make_pair("trace", ValueSpec(VALUETYPE_FLAG, + _("Print enormous amounts of information to log and console")))); + allowed_options->insert(std::make_pair("logfile", ValueSpec(VALUETYPE_STRING, + _("Set logfile path ('' = no logging)")))); + allowed_options->insert(std::make_pair("gameid", ValueSpec(VALUETYPE_STRING, + _("Set gameid (\"--gameid list\" prints available ones)")))); + allowed_options->insert(std::make_pair("migrate", ValueSpec(VALUETYPE_STRING, + _("Migrate from current map backend to another (Only works when using minetestserver or with --server)")))); + allowed_options->insert(std::make_pair("migrate-players", ValueSpec(VALUETYPE_STRING, + _("Migrate from current players backend to another (Only works when using minetestserver or with --server)")))); + allowed_options->insert(std::make_pair("migrate-auth", ValueSpec(VALUETYPE_STRING, + _("Migrate from current auth backend to another (Only works when using minetestserver or with --server)")))); + allowed_options->insert(std::make_pair("migrate-mod-storage", ValueSpec(VALUETYPE_STRING, + _("Migrate from current mod storage backend to another (Only works when using minetestserver or with --server)")))); + allowed_options->insert(std::make_pair("terminal", ValueSpec(VALUETYPE_FLAG, + _("Feature an interactive terminal (Only works when using minetestserver or with --server)")))); + allowed_options->insert(std::make_pair("recompress", ValueSpec(VALUETYPE_FLAG, + _("Recompress the blocks of the given map database.")))); +#ifndef SERVER + allowed_options->insert(std::make_pair("speedtests", ValueSpec(VALUETYPE_FLAG, + _("Run speed tests")))); + allowed_options->insert(std::make_pair("address", ValueSpec(VALUETYPE_STRING, + _("Address to connect to. ('' = local game)")))); + allowed_options->insert(std::make_pair("random-input", ValueSpec(VALUETYPE_FLAG, + _("Enable random user input, for testing")))); + allowed_options->insert(std::make_pair("server", ValueSpec(VALUETYPE_FLAG, + _("Run dedicated server")))); + allowed_options->insert(std::make_pair("name", ValueSpec(VALUETYPE_STRING, + _("Set player name")))); + allowed_options->insert(std::make_pair("password", ValueSpec(VALUETYPE_STRING, + _("Set password")))); + allowed_options->insert(std::make_pair("password-file", ValueSpec(VALUETYPE_STRING, + _("Set password from contents of file")))); + allowed_options->insert(std::make_pair("go", ValueSpec(VALUETYPE_FLAG, + _("Disable main menu")))); + allowed_options->insert(std::make_pair("console", ValueSpec(VALUETYPE_FLAG, + _("Starts with the console (Windows only)")))); +#endif + +} + +static void print_help(const OptionList &allowed_options) +{ + std::cout << _("Allowed options:") << std::endl; + print_allowed_options(allowed_options); +} + +static void print_allowed_options(const OptionList &allowed_options) +{ + for (const auto &allowed_option : allowed_options) { + std::ostringstream os1(std::ios::binary); + os1 << " --" << allowed_option.first; + if (allowed_option.second.type != VALUETYPE_FLAG) + os1 << _(" <value>"); + + std::cout << padStringRight(os1.str(), 30); + + if (allowed_option.second.help) + std::cout << allowed_option.second.help; + + std::cout << std::endl; + } +} + +static void print_version() +{ + std::cout << PROJECT_NAME_C " " << g_version_hash + << " (" << porting::getPlatformName() << ")" << std::endl; +#ifndef SERVER + std::cout << "Using Irrlicht " IRRLICHT_SDK_VERSION << std::endl; +#endif +#if USE_LUAJIT + std::cout << "Using " << LUAJIT_VERSION << std::endl; +#else + std::cout << "Using " << LUA_RELEASE << std::endl; +#endif + std::cout << g_build_info << std::endl; +} + +static void list_game_ids() +{ + std::set<std::string> gameids = getAvailableGameIds(); + for (const std::string &gameid : gameids) + std::cout << gameid <<std::endl; +} + +static void list_worlds(bool print_name, bool print_path) +{ + std::cout << _("Available worlds:") << std::endl; + std::vector<WorldSpec> worldspecs = getAvailableWorlds(); + print_worldspecs(worldspecs, std::cout, print_name, print_path); +} + +static void print_worldspecs(const std::vector<WorldSpec> &worldspecs, + std::ostream &os, bool print_name, bool print_path) +{ + for (const WorldSpec &worldspec : worldspecs) { + std::string name = worldspec.name; + std::string path = worldspec.path; + if (print_name && print_path) { + os << "\t" << name << "\t\t" << path << std::endl; + } else if (print_name) { + os << "\t" << name << std::endl; + } else if (print_path) { + os << "\t" << path << std::endl; + } + } +} + +static void print_modified_quicktune_values() +{ + bool header_printed = false; + std::vector<std::string> names = getQuicktuneNames(); + + for (const std::string &name : names) { + QuicktuneValue val = getQuicktuneValue(name); + if (!val.modified) + continue; + if (!header_printed) { + dstream << "Modified quicktune values:" << std::endl; + header_printed = true; + } + dstream << name << " = " << val.getString() << std::endl; + } +} + +static bool setup_log_params(const Settings &cmd_args) +{ + // Quiet mode, print errors only + if (cmd_args.getFlag("quiet")) { + g_logger.removeOutput(&stderr_output); + g_logger.addOutputMaxLevel(&stderr_output, LL_ERROR); + } + + // Coloured log messages (see log.h) + std::string color_mode; + if (cmd_args.exists("color")) { + color_mode = cmd_args.get("color"); +#if !defined(_WIN32) + } else { + char *color_mode_env = getenv("MT_LOGCOLOR"); + if (color_mode_env) + color_mode = color_mode_env; +#endif + } + if (color_mode != "") { + if (color_mode == "auto") { + Logger::color_mode = LOG_COLOR_AUTO; + } else if (color_mode == "always") { + Logger::color_mode = LOG_COLOR_ALWAYS; + } else if (color_mode == "never") { + Logger::color_mode = LOG_COLOR_NEVER; + } else { + errorstream << "Invalid color mode: " << color_mode << std::endl; + return false; + } + } + + // In certain cases, output info level on stderr + if (cmd_args.getFlag("info") || cmd_args.getFlag("verbose") || + cmd_args.getFlag("trace") || cmd_args.getFlag("speedtests")) + g_logger.addOutput(&stderr_output, LL_INFO); + + // In certain cases, output verbose level on stderr + if (cmd_args.getFlag("verbose") || cmd_args.getFlag("trace")) + g_logger.addOutput(&stderr_output, LL_VERBOSE); + + if (cmd_args.getFlag("trace")) { + dstream << _("Enabling trace level debug output") << std::endl; + g_logger.addOutput(&stderr_output, LL_TRACE); + socket_enable_debug_output = true; + } + + return true; +} + +static bool create_userdata_path() +{ + bool success; + +#ifdef __ANDROID__ + if (!fs::PathExists(porting::path_user)) { + success = fs::CreateDir(porting::path_user); + } else { + success = true; + } +#else + // Create user data directory + success = fs::CreateDir(porting::path_user); +#endif + + return success; +} + +static bool init_common(const Settings &cmd_args, int argc, char *argv[]) +{ + startup_message(); + set_default_settings(); + + sockets_init(); + + // Initialize g_settings + Settings::createLayer(SL_GLOBAL); + + // Set cleanup callback(s) to run at process exit + atexit(uninit_common); + + if (!read_config_file(cmd_args)) + return false; + + init_log_streams(cmd_args); + + // Initialize random seed + srand(time(0)); + mysrand(time(0)); + + // Initialize HTTP fetcher + httpfetch_init(g_settings->getS32("curl_parallel_limit")); + + init_gettext(porting::path_locale.c_str(), + g_settings->get("language"), argc, argv); + + return true; +} + +static void uninit_common() +{ + httpfetch_cleanup(); + + sockets_cleanup(); + + // It'd actually be okay to leak these but we want to please valgrind... + for (int i = 0; i < (int)SL_TOTAL_COUNT; i++) + delete Settings::getLayer((SettingsLayer)i); +} + +static void startup_message() +{ + infostream << PROJECT_NAME << " " << _("with") + << " SER_FMT_VER_HIGHEST_READ=" + << (int)SER_FMT_VER_HIGHEST_READ << ", " + << g_build_info << std::endl; +} + +static bool read_config_file(const Settings &cmd_args) +{ + // Path of configuration file in use + sanity_check(g_settings_path == ""); // Sanity check + + if (cmd_args.exists("config")) { + bool r = g_settings->readConfigFile(cmd_args.get("config").c_str()); + if (!r) { + errorstream << "Could not read configuration from \"" + << cmd_args.get("config") << "\"" << std::endl; + return false; + } + g_settings_path = cmd_args.get("config"); + } else { + std::vector<std::string> filenames; + filenames.push_back(porting::path_user + DIR_DELIM + "minetest.conf"); + // Legacy configuration file location + filenames.push_back(porting::path_user + + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf"); + +#if RUN_IN_PLACE + // Try also from a lower level (to aid having the same configuration + // for many RUN_IN_PLACE installs) + filenames.push_back(porting::path_user + + DIR_DELIM + ".." + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf"); +#endif + + for (const std::string &filename : filenames) { + bool r = g_settings->readConfigFile(filename.c_str()); + if (r) { + g_settings_path = filename; + break; + } + } + + // If no path found, use the first one (menu creates the file) + if (g_settings_path.empty()) + g_settings_path = filenames[0]; + } + + return true; +} + +static void init_log_streams(const Settings &cmd_args) +{ + std::string log_filename = porting::path_user + DIR_DELIM + DEBUGFILE; + + if (cmd_args.exists("logfile")) + log_filename = cmd_args.get("logfile"); + + g_logger.removeOutput(&file_log_output); + std::string conf_loglev = g_settings->get("debug_log_level"); + + // Old integer format + if (std::isdigit(conf_loglev[0])) { + warningstream << "Deprecated use of debug_log_level with an " + "integer value; please update your configuration." << std::endl; + static const char *lev_name[] = + {"", "error", "action", "info", "verbose", "trace"}; + int lev_i = atoi(conf_loglev.c_str()); + if (lev_i < 0 || lev_i >= (int)ARRLEN(lev_name)) { + warningstream << "Supplied invalid debug_log_level!" + " Assuming action level." << std::endl; + lev_i = 2; + } + conf_loglev = lev_name[lev_i]; + } + + if (log_filename.empty() || conf_loglev.empty()) // No logging + return; + + LogLevel log_level = Logger::stringToLevel(conf_loglev); + if (log_level == LL_MAX) { + warningstream << "Supplied unrecognized debug_log_level; " + "using maximum." << std::endl; + } + + file_log_output.setFile(log_filename, + g_settings->getU64("debug_log_size_max") * 1000000); + g_logger.addOutputMaxLevel(&file_log_output, log_level); +} + +static bool game_configure(GameParams *game_params, const Settings &cmd_args) +{ + game_configure_port(game_params, cmd_args); + + if (!game_configure_world(game_params, cmd_args)) { + errorstream << "No world path specified or found." << std::endl; + return false; + } + + game_configure_subgame(game_params, cmd_args); + + return true; +} + +static void game_configure_port(GameParams *game_params, const Settings &cmd_args) +{ + if (cmd_args.exists("port")) { + game_params->socket_port = cmd_args.getU16("port"); + } else { + if (game_params->is_dedicated_server) + game_params->socket_port = g_settings->getU16("port"); + else + game_params->socket_port = g_settings->getU16("remote_port"); + } + + if (game_params->socket_port == 0) + game_params->socket_port = DEFAULT_SERVER_PORT; +} + +static bool game_configure_world(GameParams *game_params, const Settings &cmd_args) +{ + if (get_world_from_cmdline(game_params, cmd_args)) + return true; + + if (get_world_from_config(game_params, cmd_args)) + return true; + + return auto_select_world(game_params); +} + +static bool get_world_from_cmdline(GameParams *game_params, const Settings &cmd_args) +{ + std::string commanded_world; + + // World name + std::string commanded_worldname; + if (cmd_args.exists("worldname")) + commanded_worldname = cmd_args.get("worldname"); + + // If a world name was specified, convert it to a path + if (!commanded_worldname.empty()) { + // Get information about available worlds + std::vector<WorldSpec> worldspecs = getAvailableWorlds(); + bool found = false; + for (const WorldSpec &worldspec : worldspecs) { + std::string name = worldspec.name; + if (name == commanded_worldname) { + dstream << _("Using world specified by --worldname on the " + "command line") << std::endl; + commanded_world = worldspec.path; + found = true; + break; + } + } + if (!found) { + dstream << _("World") << " '" << commanded_worldname + << _("' not available. Available worlds:") << std::endl; + print_worldspecs(worldspecs, dstream); + return false; + } + + game_params->world_path = get_clean_world_path(commanded_world); + return !commanded_world.empty(); + } + + if (cmd_args.exists("world")) + commanded_world = cmd_args.get("world"); + else if (cmd_args.exists("map-dir")) + commanded_world = cmd_args.get("map-dir"); + else if (cmd_args.exists("nonopt0")) // First nameless argument + commanded_world = cmd_args.get("nonopt0"); + + game_params->world_path = get_clean_world_path(commanded_world); + return !commanded_world.empty(); +} + +static bool get_world_from_config(GameParams *game_params, const Settings &cmd_args) +{ + // World directory + std::string commanded_world; + + if (g_settings->exists("map-dir")) + commanded_world = g_settings->get("map-dir"); + + game_params->world_path = get_clean_world_path(commanded_world); + + return !commanded_world.empty(); +} + +static bool auto_select_world(GameParams *game_params) +{ + // No world was specified; try to select it automatically + // Get information about available worlds + + std::vector<WorldSpec> worldspecs = getAvailableWorlds(); + std::string world_path; + + // If there is only a single world, use it + if (worldspecs.size() == 1) { + world_path = worldspecs[0].path; + dstream <<_("Automatically selecting world at") << " [" + << world_path << "]" << std::endl; + // If there are multiple worlds, list them + } else if (worldspecs.size() > 1 && game_params->is_dedicated_server) { + std::cerr << _("Multiple worlds are available.") << std::endl; + std::cerr << _("Please select one using --worldname <name>" + " or --world <path>") << std::endl; + print_worldspecs(worldspecs, std::cerr); + return false; + // If there are no worlds, automatically create a new one + } else { + // This is the ultimate default world path + world_path = porting::path_user + DIR_DELIM + "worlds" + + DIR_DELIM + "world"; + infostream << "Using default world at [" + << world_path << "]" << std::endl; + } + + assert(world_path != ""); // Post-condition + game_params->world_path = world_path; + return true; +} + +static std::string get_clean_world_path(const std::string &path) +{ + const std::string worldmt = "world.mt"; + std::string clean_path; + + if (path.size() > worldmt.size() + && path.substr(path.size() - worldmt.size()) == worldmt) { + dstream << _("Supplied world.mt file - stripping it off.") << std::endl; + clean_path = path.substr(0, path.size() - worldmt.size()); + } else { + clean_path = path; + } + return path; +} + + +static bool game_configure_subgame(GameParams *game_params, const Settings &cmd_args) +{ + bool success; + + success = get_game_from_cmdline(game_params, cmd_args); + if (!success) + success = determine_subgame(game_params); + + return success; +} + +static bool get_game_from_cmdline(GameParams *game_params, const Settings &cmd_args) +{ + SubgameSpec commanded_gamespec; + + if (cmd_args.exists("gameid")) { + std::string gameid = cmd_args.get("gameid"); + commanded_gamespec = findSubgame(gameid); + if (!commanded_gamespec.isValid()) { + errorstream << "Game \"" << gameid << "\" not found" << std::endl; + return false; + } + dstream << _("Using game specified by --gameid on the command line") + << std::endl; + game_params->game_spec = commanded_gamespec; + return true; + } + + return false; +} + +static bool determine_subgame(GameParams *game_params) +{ + SubgameSpec gamespec; + + assert(game_params->world_path != ""); // Pre-condition + + // If world doesn't exist + if (!game_params->world_path.empty() + && !getWorldExists(game_params->world_path)) { + // Try to take gamespec from command line + if (game_params->game_spec.isValid()) { + gamespec = game_params->game_spec; + infostream << "Using commanded gameid [" << gamespec.id << "]" << std::endl; + } else { // Otherwise we will be using "minetest" + gamespec = findSubgame(g_settings->get("default_game")); + infostream << "Using default gameid [" << gamespec.id << "]" << std::endl; + if (!gamespec.isValid()) { + errorstream << "Game specified in default_game [" + << g_settings->get("default_game") + << "] is invalid." << std::endl; + return false; + } + } + } else { // World exists + std::string world_gameid = getWorldGameId(game_params->world_path, false); + // If commanded to use a gameid, do so + if (game_params->game_spec.isValid()) { + gamespec = game_params->game_spec; + if (game_params->game_spec.id != world_gameid) { + warningstream << "Using commanded gameid [" + << gamespec.id << "]" << " instead of world gameid [" + << world_gameid << "]" << std::endl; + } + } else { + // If world contains an embedded game, use it; + // Otherwise find world from local system. + gamespec = findWorldSubgame(game_params->world_path); + infostream << "Using world gameid [" << gamespec.id << "]" << std::endl; + } + } + + if (!gamespec.isValid()) { + errorstream << "Game [" << gamespec.id << "] could not be found." + << std::endl; + return false; + } + + game_params->game_spec = gamespec; + return true; +} + + +/***************************************************************************** + * Dedicated server + *****************************************************************************/ +static bool run_dedicated_server(const GameParams &game_params, const Settings &cmd_args) +{ + verbosestream << _("Using world path") << " [" + << game_params.world_path << "]" << std::endl; + verbosestream << _("Using gameid") << " [" + << game_params.game_spec.id << "]" << std::endl; + + // Bind address + std::string bind_str = g_settings->get("bind_address"); + Address bind_addr(0, 0, 0, 0, game_params.socket_port); + + if (g_settings->getBool("ipv6_server")) { + bind_addr.setAddress((IPv6AddressBytes*) NULL); + } + try { + bind_addr.Resolve(bind_str.c_str()); + } catch (ResolveError &e) { + infostream << "Resolving bind address \"" << bind_str + << "\" failed: " << e.what() + << " -- Listening on all addresses." << std::endl; + } + if (bind_addr.isIPv6() && !g_settings->getBool("enable_ipv6")) { + errorstream << "Unable to listen on " + << bind_addr.serializeString() + << L" because IPv6 is disabled" << std::endl; + return false; + } + + // Database migration/compression + if (cmd_args.exists("migrate")) + return migrate_map_database(game_params, cmd_args); + + if (cmd_args.exists("migrate-players")) + return ServerEnvironment::migratePlayersDatabase(game_params, cmd_args); + + if (cmd_args.exists("migrate-auth")) + return ServerEnvironment::migrateAuthDatabase(game_params, cmd_args); + + if (cmd_args.exists("migrate-mod-storage")) + return Server::migrateModStorageDatabase(game_params, cmd_args); + + if (cmd_args.getFlag("recompress")) + return recompress_map_database(game_params, cmd_args, bind_addr); + + if (cmd_args.exists("terminal")) { +#if USE_CURSES + bool name_ok = true; + std::string admin_nick = g_settings->get("name"); + + name_ok = name_ok && !admin_nick.empty(); + name_ok = name_ok && string_allowed(admin_nick, PLAYERNAME_ALLOWED_CHARS); + + if (!name_ok) { + if (admin_nick.empty()) { + errorstream << "No name given for admin. " + << "Please check your minetest.conf that it " + << "contains a 'name = ' to your main admin account." + << std::endl; + } else { + errorstream << "Name for admin '" + << admin_nick << "' is not valid. " + << "Please check that it only contains allowed characters. " + << "Valid characters are: " << PLAYERNAME_ALLOWED_CHARS_USER_EXPL + << std::endl; + } + return false; + } + ChatInterface iface; + bool &kill = *porting::signal_handler_killstatus(); + + try { + // Create server + Server server(game_params.world_path, game_params.game_spec, + false, bind_addr, true, &iface); + + g_term_console.setup(&iface, &kill, admin_nick); + + g_term_console.start(); + + server.start(); + // Run server + dedicated_server_loop(server, kill); + } catch (const ModError &e) { + g_term_console.stopAndWaitforThread(); + errorstream << "ModError: " << e.what() << std::endl; + return false; + } catch (const ServerError &e) { + g_term_console.stopAndWaitforThread(); + errorstream << "ServerError: " << e.what() << std::endl; + return false; + } + + // Tell the console to stop, and wait for it to finish, + // only then leave context and free iface + g_term_console.stop(); + g_term_console.wait(); + + g_term_console.clearKillStatus(); + } else { +#else + errorstream << "Cmd arg --terminal passed, but " + << "compiled without ncurses. Ignoring." << std::endl; + } { +#endif + try { + // Create server + Server server(game_params.world_path, game_params.game_spec, false, + bind_addr, true); + server.start(); + + // Run server + bool &kill = *porting::signal_handler_killstatus(); + dedicated_server_loop(server, kill); + + } catch (const ModError &e) { + errorstream << "ModError: " << e.what() << std::endl; + return false; + } catch (const ServerError &e) { + errorstream << "ServerError: " << e.what() << std::endl; + return false; + } + } + + return true; +} + +static bool migrate_map_database(const GameParams &game_params, const Settings &cmd_args) +{ + std::string migrate_to = cmd_args.get("migrate"); + Settings world_mt; + std::string world_mt_path = game_params.world_path + DIR_DELIM + "world.mt"; + if (!world_mt.readConfigFile(world_mt_path.c_str())) { + errorstream << "Cannot read world.mt!" << std::endl; + return false; + } + + if (!world_mt.exists("backend")) { + errorstream << "Please specify your current backend in world.mt:" + << std::endl + << " backend = {sqlite3|leveldb|redis|dummy|postgresql}" + << std::endl; + return false; + } + + std::string backend = world_mt.get("backend"); + if (backend == migrate_to) { + errorstream << "Cannot migrate: new backend is same" + << " as the old one" << std::endl; + return false; + } + + MapDatabase *old_db = ServerMap::createDatabase(backend, game_params.world_path, world_mt), + *new_db = ServerMap::createDatabase(migrate_to, game_params.world_path, world_mt); + + u32 count = 0; + time_t last_update_time = 0; + bool &kill = *porting::signal_handler_killstatus(); + + std::vector<v3s16> blocks; + old_db->listAllLoadableBlocks(blocks); + new_db->beginSave(); + for (std::vector<v3s16>::const_iterator it = blocks.begin(); it != blocks.end(); ++it) { + if (kill) return false; + + std::string data; + old_db->loadBlock(*it, &data); + if (!data.empty()) { + new_db->saveBlock(*it, data); + } else { + errorstream << "Failed to load block " << PP(*it) << ", skipping it." << std::endl; + } + if (++count % 0xFF == 0 && time(NULL) - last_update_time >= 1) { + std::cerr << " Migrated " << count << " blocks, " + << (100.0 * count / blocks.size()) << "% completed.\r"; + new_db->endSave(); + new_db->beginSave(); + last_update_time = time(NULL); + } + } + std::cerr << std::endl; + new_db->endSave(); + delete old_db; + delete new_db; + + actionstream << "Successfully migrated " << count << " blocks" << std::endl; + world_mt.set("backend", migrate_to); + if (!world_mt.updateConfigFile(world_mt_path.c_str())) + errorstream << "Failed to update world.mt!" << std::endl; + else + actionstream << "world.mt updated" << std::endl; + + return true; +} + +static bool recompress_map_database(const GameParams &game_params, const Settings &cmd_args, const Address &addr) +{ + Settings world_mt; + const std::string world_mt_path = game_params.world_path + DIR_DELIM + "world.mt"; + + if (!world_mt.readConfigFile(world_mt_path.c_str())) { + errorstream << "Cannot read world.mt at " << world_mt_path << std::endl; + return false; + } + const std::string &backend = world_mt.get("backend"); + Server server(game_params.world_path, game_params.game_spec, false, addr, false); + MapDatabase *db = ServerMap::createDatabase(backend, game_params.world_path, world_mt); + + u32 count = 0; + u64 last_update_time = 0; + bool &kill = *porting::signal_handler_killstatus(); + const u8 serialize_as_ver = SER_FMT_VER_HIGHEST_WRITE; + + // This is ok because the server doesn't actually run + std::vector<v3s16> blocks; + db->listAllLoadableBlocks(blocks); + db->beginSave(); + std::istringstream iss(std::ios_base::binary); + std::ostringstream oss(std::ios_base::binary); + for (auto it = blocks.begin(); it != blocks.end(); ++it) { + if (kill) return false; + + std::string data; + db->loadBlock(*it, &data); + if (data.empty()) { + errorstream << "Failed to load block " << PP(*it) << std::endl; + return false; + } + + iss.str(data); + iss.clear(); + + MapBlock mb(nullptr, v3s16(0,0,0), &server); + u8 ver = readU8(iss); + mb.deSerialize(iss, ver, true); + + oss.str(""); + oss.clear(); + writeU8(oss, serialize_as_ver); + mb.serialize(oss, serialize_as_ver, true, -1); + + db->saveBlock(*it, oss.str()); + + count++; + if (count % 0xFF == 0 && porting::getTimeS() - last_update_time >= 1) { + std::cerr << " Recompressed " << count << " blocks, " + << (100.0f * count / blocks.size()) << "% completed.\r"; + db->endSave(); + db->beginSave(); + last_update_time = porting::getTimeS(); + } + } + std::cerr << std::endl; + db->endSave(); + + actionstream << "Done, " << count << " blocks were recompressed." << std::endl; + return true; +} diff --git a/src/map.cpp b/src/map.cpp new file mode 100644 index 0000000..a536800 --- /dev/null +++ b/src/map.cpp @@ -0,0 +1,2062 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "map.h" +#include "mapsector.h" +#include "mapblock.h" +#include "filesys.h" +#include "voxel.h" +#include "voxelalgorithms.h" +#include "porting.h" +#include "serialization.h" +#include "nodemetadata.h" +#include "settings.h" +#include "log.h" +#include "profiler.h" +#include "nodedef.h" +#include "gamedef.h" +#include "util/directiontables.h" +#include "util/basic_macros.h" +#include "rollback_interface.h" +#include "environment.h" +#include "reflowscan.h" +#include "emerge.h" +#include "mapgen/mapgen_v6.h" +#include "mapgen/mg_biome.h" +#include "config.h" +#include "server.h" +#include "database/database.h" +#include "database/database-dummy.h" +#include "database/database-sqlite3.h" +#include "script/scripting_server.h" +#include <deque> +#include <queue> +#if USE_LEVELDB +#include "database/database-leveldb.h" +#endif +#if USE_REDIS +#include "database/database-redis.h" +#endif +#if USE_POSTGRESQL +#include "database/database-postgresql.h" +#endif + + +/* + Map +*/ + +Map::Map(IGameDef *gamedef): + m_gamedef(gamedef), + m_nodedef(gamedef->ndef()) +{ +} + +Map::~Map() +{ + /* + Free all MapSectors + */ + for (auto §or : m_sectors) { + delete sector.second; + } +} + +void Map::addEventReceiver(MapEventReceiver *event_receiver) +{ + m_event_receivers.insert(event_receiver); +} + +void Map::removeEventReceiver(MapEventReceiver *event_receiver) +{ + m_event_receivers.erase(event_receiver); +} + +void Map::dispatchEvent(const MapEditEvent &event) +{ + for (MapEventReceiver *event_receiver : m_event_receivers) { + event_receiver->onMapEditEvent(event); + } +} + +MapSector * Map::getSectorNoGenerateNoLock(v2s16 p) +{ + if(m_sector_cache != NULL && p == m_sector_cache_p){ + MapSector * sector = m_sector_cache; + return sector; + } + + auto n = m_sectors.find(p); + + if (n == m_sectors.end()) + return NULL; + + MapSector *sector = n->second; + + // Cache the last result + m_sector_cache_p = p; + m_sector_cache = sector; + + return sector; +} + +MapSector * Map::getSectorNoGenerate(v2s16 p) +{ + return getSectorNoGenerateNoLock(p); +} + +MapBlock * Map::getBlockNoCreateNoEx(v3s16 p3d) +{ + v2s16 p2d(p3d.X, p3d.Z); + MapSector * sector = getSectorNoGenerate(p2d); + if(sector == NULL) + return NULL; + MapBlock *block = sector->getBlockNoCreateNoEx(p3d.Y); + return block; +} + +MapBlock * Map::getBlockNoCreate(v3s16 p3d) +{ + MapBlock *block = getBlockNoCreateNoEx(p3d); + if(block == NULL) + throw InvalidPositionException(); + return block; +} + +bool Map::isValidPosition(v3s16 p) +{ + v3s16 blockpos = getNodeBlockPos(p); + MapBlock *block = getBlockNoCreateNoEx(blockpos); + return (block != NULL); +} + +// Returns a CONTENT_IGNORE node if not found +MapNode Map::getNode(v3s16 p, bool *is_valid_position) +{ + v3s16 blockpos = getNodeBlockPos(p); + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if (block == NULL) { + if (is_valid_position != NULL) + *is_valid_position = false; + return {CONTENT_IGNORE}; + } + + v3s16 relpos = p - blockpos*MAP_BLOCKSIZE; + bool is_valid_p; + MapNode node = block->getNodeNoCheck(relpos, &is_valid_p); + if (is_valid_position != NULL) + *is_valid_position = is_valid_p; + return node; +} + +static void set_node_in_block(MapBlock *block, v3s16 relpos, MapNode n) +{ + // Never allow placing CONTENT_IGNORE, it causes problems + if(n.getContent() == CONTENT_IGNORE){ + const NodeDefManager *nodedef = block->getParent()->getNodeDefManager(); + v3s16 blockpos = block->getPos(); + v3s16 p = blockpos * MAP_BLOCKSIZE + relpos; + bool temp_bool; + errorstream<<"Not allowing to place CONTENT_IGNORE" + <<" while trying to replace \"" + <<nodedef->get(block->getNodeNoCheck(relpos, &temp_bool)).name + <<"\" at "<<PP(p)<<" (block "<<PP(blockpos)<<")"<<std::endl; + return; + } + block->setNodeNoCheck(relpos, n); +} + +// throws InvalidPositionException if not found +void Map::setNode(v3s16 p, MapNode & n) +{ + v3s16 blockpos = getNodeBlockPos(p); + MapBlock *block = getBlockNoCreate(blockpos); + v3s16 relpos = p - blockpos*MAP_BLOCKSIZE; + set_node_in_block(block, relpos, n); +} + +void Map::addNodeAndUpdate(v3s16 p, MapNode n, + std::map<v3s16, MapBlock*> &modified_blocks, + bool remove_metadata) +{ + // Collect old node for rollback + RollbackNode rollback_oldnode(this, p, m_gamedef); + + v3s16 blockpos = getNodeBlockPos(p); + MapBlock *block = getBlockNoCreate(blockpos); + if (block->isDummy()) + throw InvalidPositionException(); + v3s16 relpos = p - blockpos * MAP_BLOCKSIZE; + + // This is needed for updating the lighting + MapNode oldnode = block->getNodeUnsafe(relpos); + + // Remove node metadata + if (remove_metadata) { + removeNodeMetadata(p); + } + + // Set the node on the map + const ContentFeatures &cf = m_nodedef->get(n); + const ContentFeatures &oldcf = m_nodedef->get(oldnode); + if (cf.lightingEquivalent(oldcf)) { + // No light update needed, just copy over the old light. + n.setLight(LIGHTBANK_DAY, oldnode.getLightRaw(LIGHTBANK_DAY, oldcf), cf); + n.setLight(LIGHTBANK_NIGHT, oldnode.getLightRaw(LIGHTBANK_NIGHT, oldcf), cf); + set_node_in_block(block, relpos, n); + + modified_blocks[blockpos] = block; + } else { + // Ignore light (because calling voxalgo::update_lighting_nodes) + n.setLight(LIGHTBANK_DAY, 0, cf); + n.setLight(LIGHTBANK_NIGHT, 0, cf); + set_node_in_block(block, relpos, n); + + // Update lighting + std::vector<std::pair<v3s16, MapNode> > oldnodes; + oldnodes.emplace_back(p, oldnode); + voxalgo::update_lighting_nodes(this, oldnodes, modified_blocks); + + for (auto &modified_block : modified_blocks) { + modified_block.second->expireDayNightDiff(); + } + } + + // Report for rollback + if(m_gamedef->rollback()) + { + RollbackNode rollback_newnode(this, p, m_gamedef); + RollbackAction action; + action.setSetNode(p, rollback_oldnode, rollback_newnode); + m_gamedef->rollback()->reportAction(action); + } +} + +void Map::removeNodeAndUpdate(v3s16 p, + std::map<v3s16, MapBlock*> &modified_blocks) +{ + addNodeAndUpdate(p, MapNode(CONTENT_AIR), modified_blocks, true); +} + +bool Map::addNodeWithEvent(v3s16 p, MapNode n, bool remove_metadata) +{ + MapEditEvent event; + event.type = remove_metadata ? MEET_ADDNODE : MEET_SWAPNODE; + event.p = p; + event.n = n; + + bool succeeded = true; + try{ + std::map<v3s16, MapBlock*> modified_blocks; + addNodeAndUpdate(p, n, modified_blocks, remove_metadata); + + // Copy modified_blocks to event + for (auto &modified_block : modified_blocks) { + event.modified_blocks.insert(modified_block.first); + } + } + catch(InvalidPositionException &e){ + succeeded = false; + } + + dispatchEvent(event); + + return succeeded; +} + +bool Map::removeNodeWithEvent(v3s16 p) +{ + MapEditEvent event; + event.type = MEET_REMOVENODE; + event.p = p; + + bool succeeded = true; + try{ + std::map<v3s16, MapBlock*> modified_blocks; + removeNodeAndUpdate(p, modified_blocks); + + // Copy modified_blocks to event + for (auto &modified_block : modified_blocks) { + event.modified_blocks.insert(modified_block.first); + } + } + catch(InvalidPositionException &e){ + succeeded = false; + } + + dispatchEvent(event); + + return succeeded; +} + +struct TimeOrderedMapBlock { + MapSector *sect; + MapBlock *block; + + TimeOrderedMapBlock(MapSector *sect, MapBlock *block) : + sect(sect), + block(block) + {} + + bool operator<(const TimeOrderedMapBlock &b) const + { + return block->getUsageTimer() < b.block->getUsageTimer(); + }; +}; + +/* + Updates usage timers +*/ +void Map::timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks, + std::vector<v3s16> *unloaded_blocks) +{ + bool save_before_unloading = maySaveBlocks(); + + // Profile modified reasons + Profiler modprofiler; + + std::vector<v2s16> sector_deletion_queue; + u32 deleted_blocks_count = 0; + u32 saved_blocks_count = 0; + u32 block_count_all = 0; + + const auto start_time = porting::getTimeUs(); + beginSave(); + + // If there is no practical limit, we spare creation of mapblock_queue + if (max_loaded_blocks < 0) { + for (auto §or_it : m_sectors) { + MapSector *sector = sector_it.second; + + bool all_blocks_deleted = true; + + MapBlockVect blocks; + sector->getBlocks(blocks); + + for (MapBlock *block : blocks) { + block->incrementUsageTimer(dtime); + + if (block->refGet() == 0 + && block->getUsageTimer() > unload_timeout) { + v3s16 p = block->getPos(); + + // Save if modified + if (block->getModified() != MOD_STATE_CLEAN + && save_before_unloading) { + modprofiler.add(block->getModifiedReasonString(), 1); + if (!saveBlock(block)) + continue; + saved_blocks_count++; + } + + // Delete from memory + sector->deleteBlock(block); + + if (unloaded_blocks) + unloaded_blocks->push_back(p); + + deleted_blocks_count++; + } else { + all_blocks_deleted = false; + block_count_all++; + } + } + + // Delete sector if we emptied it + if (all_blocks_deleted) { + sector_deletion_queue.push_back(sector_it.first); + } + } + } else { + std::priority_queue<TimeOrderedMapBlock> mapblock_queue; + for (auto §or_it : m_sectors) { + MapSector *sector = sector_it.second; + + MapBlockVect blocks; + sector->getBlocks(blocks); + + for (MapBlock *block : blocks) { + block->incrementUsageTimer(dtime); + mapblock_queue.push(TimeOrderedMapBlock(sector, block)); + } + } + block_count_all = mapblock_queue.size(); + + // Delete old blocks, and blocks over the limit from the memory + while (!mapblock_queue.empty() && ((s32)mapblock_queue.size() > max_loaded_blocks + || mapblock_queue.top().block->getUsageTimer() > unload_timeout)) { + TimeOrderedMapBlock b = mapblock_queue.top(); + mapblock_queue.pop(); + + MapBlock *block = b.block; + + if (block->refGet() != 0) + continue; + + v3s16 p = block->getPos(); + + // Save if modified + if (block->getModified() != MOD_STATE_CLEAN && save_before_unloading) { + modprofiler.add(block->getModifiedReasonString(), 1); + if (!saveBlock(block)) + continue; + saved_blocks_count++; + } + + // Delete from memory + b.sect->deleteBlock(block); + + if (unloaded_blocks) + unloaded_blocks->push_back(p); + + deleted_blocks_count++; + block_count_all--; + } + + // Delete empty sectors + for (auto §or_it : m_sectors) { + if (sector_it.second->empty()) { + sector_deletion_queue.push_back(sector_it.first); + } + } + } + + endSave(); + const auto end_time = porting::getTimeUs(); + + reportMetrics(end_time - start_time, saved_blocks_count, block_count_all); + + // Finally delete the empty sectors + deleteSectors(sector_deletion_queue); + + if(deleted_blocks_count != 0) + { + PrintInfo(infostream); // ServerMap/ClientMap: + infostream<<"Unloaded "<<deleted_blocks_count + <<" blocks from memory"; + if(save_before_unloading) + infostream<<", of which "<<saved_blocks_count<<" were written"; + infostream<<", "<<block_count_all<<" blocks in memory"; + infostream<<"."<<std::endl; + if(saved_blocks_count != 0){ + PrintInfo(infostream); // ServerMap/ClientMap: + infostream<<"Blocks modified by: "<<std::endl; + modprofiler.print(infostream); + } + } +} + +void Map::unloadUnreferencedBlocks(std::vector<v3s16> *unloaded_blocks) +{ + timerUpdate(0.0, -1.0, 0, unloaded_blocks); +} + +void Map::deleteSectors(std::vector<v2s16> §orList) +{ + for (v2s16 j : sectorList) { + MapSector *sector = m_sectors[j]; + // If sector is in sector cache, remove it from there + if(m_sector_cache == sector) + m_sector_cache = NULL; + // Remove from map and delete + m_sectors.erase(j); + delete sector; + } +} + +void Map::PrintInfo(std::ostream &out) +{ + out<<"Map: "; +} + +#define WATER_DROP_BOOST 4 + +const static v3s16 liquid_6dirs[6] = { + // order: upper before same level before lower + v3s16( 0, 1, 0), + v3s16( 0, 0, 1), + v3s16( 1, 0, 0), + v3s16( 0, 0,-1), + v3s16(-1, 0, 0), + v3s16( 0,-1, 0) +}; + +enum NeighborType : u8 { + NEIGHBOR_UPPER, + NEIGHBOR_SAME_LEVEL, + NEIGHBOR_LOWER +}; + +struct NodeNeighbor { + MapNode n; + NeighborType t; + v3s16 p; + + NodeNeighbor() + : n(CONTENT_AIR), t(NEIGHBOR_SAME_LEVEL) + { } + + NodeNeighbor(const MapNode &node, NeighborType n_type, const v3s16 &pos) + : n(node), + t(n_type), + p(pos) + { } +}; + +void ServerMap::transforming_liquid_add(v3s16 p) { + m_transforming_liquid.push_back(p); +} + +void ServerMap::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks, + ServerEnvironment *env) +{ + u32 loopcount = 0; + u32 initial_size = m_transforming_liquid.size(); + + /*if(initial_size != 0) + infostream<<"transformLiquids(): initial_size="<<initial_size<<std::endl;*/ + + // list of nodes that due to viscosity have not reached their max level height + std::deque<v3s16> must_reflow; + + std::vector<std::pair<v3s16, MapNode> > changed_nodes; + + u32 liquid_loop_max = g_settings->getS32("liquid_loop_max"); + u32 loop_max = liquid_loop_max; + + while (m_transforming_liquid.size() != 0) + { + // This should be done here so that it is done when continue is used + if (loopcount >= initial_size || loopcount >= loop_max) + break; + loopcount++; + + /* + Get a queued transforming liquid node + */ + v3s16 p0 = m_transforming_liquid.front(); + m_transforming_liquid.pop_front(); + + MapNode n0 = getNode(p0); + + /* + Collect information about current node + */ + s8 liquid_level = -1; + // The liquid node which will be placed there if + // the liquid flows into this node. + content_t liquid_kind = CONTENT_IGNORE; + // The node which will be placed there if liquid + // can't flow into this node. + content_t floodable_node = CONTENT_AIR; + const ContentFeatures &cf = m_nodedef->get(n0); + LiquidType liquid_type = cf.liquid_type; + switch (liquid_type) { + case LIQUID_SOURCE: + liquid_level = LIQUID_LEVEL_SOURCE; + liquid_kind = cf.liquid_alternative_flowing_id; + break; + case LIQUID_FLOWING: + liquid_level = (n0.param2 & LIQUID_LEVEL_MASK); + liquid_kind = n0.getContent(); + break; + case LIQUID_NONE: + // if this node is 'floodable', it *could* be transformed + // into a liquid, otherwise, continue with the next node. + if (!cf.floodable) + continue; + floodable_node = n0.getContent(); + liquid_kind = CONTENT_AIR; + break; + } + + /* + Collect information about the environment + */ + NodeNeighbor sources[6]; // surrounding sources + int num_sources = 0; + NodeNeighbor flows[6]; // surrounding flowing liquid nodes + int num_flows = 0; + NodeNeighbor airs[6]; // surrounding air + int num_airs = 0; + NodeNeighbor neutrals[6]; // nodes that are solid or another kind of liquid + int num_neutrals = 0; + bool flowing_down = false; + bool ignored_sources = false; + for (u16 i = 0; i < 6; i++) { + NeighborType nt = NEIGHBOR_SAME_LEVEL; + switch (i) { + case 0: + nt = NEIGHBOR_UPPER; + break; + case 5: + nt = NEIGHBOR_LOWER; + break; + default: + break; + } + v3s16 npos = p0 + liquid_6dirs[i]; + NodeNeighbor nb(getNode(npos), nt, npos); + const ContentFeatures &cfnb = m_nodedef->get(nb.n); + switch (m_nodedef->get(nb.n.getContent()).liquid_type) { + case LIQUID_NONE: + if (cfnb.floodable) { + airs[num_airs++] = nb; + // if the current node is a water source the neighbor + // should be enqueded for transformation regardless of whether the + // current node changes or not. + if (nb.t != NEIGHBOR_UPPER && liquid_type != LIQUID_NONE) + m_transforming_liquid.push_back(npos); + // if the current node happens to be a flowing node, it will start to flow down here. + if (nb.t == NEIGHBOR_LOWER) + flowing_down = true; + } else { + neutrals[num_neutrals++] = nb; + if (nb.n.getContent() == CONTENT_IGNORE) { + // If node below is ignore prevent water from + // spreading outwards and otherwise prevent from + // flowing away as ignore node might be the source + if (nb.t == NEIGHBOR_LOWER) + flowing_down = true; + else + ignored_sources = true; + } + } + break; + case LIQUID_SOURCE: + // if this node is not (yet) of a liquid type, choose the first liquid type we encounter + if (liquid_kind == CONTENT_AIR) + liquid_kind = cfnb.liquid_alternative_flowing_id; + if (cfnb.liquid_alternative_flowing_id != liquid_kind) { + neutrals[num_neutrals++] = nb; + } else { + // Do not count bottom source, it will screw things up + if(nt != NEIGHBOR_LOWER) + sources[num_sources++] = nb; + } + break; + case LIQUID_FLOWING: + if (nb.t != NEIGHBOR_SAME_LEVEL || + (nb.n.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK) { + // if this node is not (yet) of a liquid type, choose the first liquid type we encounter + // but exclude falling liquids on the same level, they cannot flow here anyway + if (liquid_kind == CONTENT_AIR) + liquid_kind = cfnb.liquid_alternative_flowing_id; + } + if (cfnb.liquid_alternative_flowing_id != liquid_kind) { + neutrals[num_neutrals++] = nb; + } else { + flows[num_flows++] = nb; + if (nb.t == NEIGHBOR_LOWER) + flowing_down = true; + } + break; + } + } + + /* + decide on the type (and possibly level) of the current node + */ + content_t new_node_content; + s8 new_node_level = -1; + s8 max_node_level = -1; + + u8 range = m_nodedef->get(liquid_kind).liquid_range; + if (range > LIQUID_LEVEL_MAX + 1) + range = LIQUID_LEVEL_MAX + 1; + + if ((num_sources >= 2 && m_nodedef->get(liquid_kind).liquid_renewable) || liquid_type == LIQUID_SOURCE) { + // liquid_kind will be set to either the flowing alternative of the node (if it's a liquid) + // or the flowing alternative of the first of the surrounding sources (if it's air), so + // it's perfectly safe to use liquid_kind here to determine the new node content. + new_node_content = m_nodedef->get(liquid_kind).liquid_alternative_source_id; + } else if (num_sources >= 1 && sources[0].t != NEIGHBOR_LOWER) { + // liquid_kind is set properly, see above + max_node_level = new_node_level = LIQUID_LEVEL_MAX; + if (new_node_level >= (LIQUID_LEVEL_MAX + 1 - range)) + new_node_content = liquid_kind; + else + new_node_content = floodable_node; + } else if (ignored_sources && liquid_level >= 0) { + // Maybe there are neighbouring sources that aren't loaded yet + // so prevent flowing away. + new_node_level = liquid_level; + new_node_content = liquid_kind; + } else { + // no surrounding sources, so get the maximum level that can flow into this node + for (u16 i = 0; i < num_flows; i++) { + u8 nb_liquid_level = (flows[i].n.param2 & LIQUID_LEVEL_MASK); + switch (flows[i].t) { + case NEIGHBOR_UPPER: + if (nb_liquid_level + WATER_DROP_BOOST > max_node_level) { + max_node_level = LIQUID_LEVEL_MAX; + if (nb_liquid_level + WATER_DROP_BOOST < LIQUID_LEVEL_MAX) + max_node_level = nb_liquid_level + WATER_DROP_BOOST; + } else if (nb_liquid_level > max_node_level) { + max_node_level = nb_liquid_level; + } + break; + case NEIGHBOR_LOWER: + break; + case NEIGHBOR_SAME_LEVEL: + if ((flows[i].n.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK && + nb_liquid_level > 0 && nb_liquid_level - 1 > max_node_level) + max_node_level = nb_liquid_level - 1; + break; + } + } + + u8 viscosity = m_nodedef->get(liquid_kind).liquid_viscosity; + if (viscosity > 1 && max_node_level != liquid_level) { + // amount to gain, limited by viscosity + // must be at least 1 in absolute value + s8 level_inc = max_node_level - liquid_level; + if (level_inc < -viscosity || level_inc > viscosity) + new_node_level = liquid_level + level_inc/viscosity; + else if (level_inc < 0) + new_node_level = liquid_level - 1; + else if (level_inc > 0) + new_node_level = liquid_level + 1; + if (new_node_level != max_node_level) + must_reflow.push_back(p0); + } else { + new_node_level = max_node_level; + } + + if (max_node_level >= (LIQUID_LEVEL_MAX + 1 - range)) + new_node_content = liquid_kind; + else + new_node_content = floodable_node; + + } + + /* + check if anything has changed. if not, just continue with the next node. + */ + if (new_node_content == n0.getContent() && + (m_nodedef->get(n0.getContent()).liquid_type != LIQUID_FLOWING || + ((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level && + ((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK) + == flowing_down))) + continue; + + + /* + update the current node + */ + MapNode n00 = n0; + //bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK)); + if (m_nodedef->get(new_node_content).liquid_type == LIQUID_FLOWING) { + // set level to last 3 bits, flowing down bit to 4th bit + n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK); + } else { + // set the liquid level and flow bits to 0 + n0.param2 &= ~(LIQUID_LEVEL_MASK | LIQUID_FLOW_DOWN_MASK); + } + + // change the node. + n0.setContent(new_node_content); + + // on_flood() the node + if (floodable_node != CONTENT_AIR) { + if (env->getScriptIface()->node_on_flood(p0, n00, n0)) + continue; + } + + // Ignore light (because calling voxalgo::update_lighting_nodes) + n0.setLight(LIGHTBANK_DAY, 0, m_nodedef); + n0.setLight(LIGHTBANK_NIGHT, 0, m_nodedef); + + // Find out whether there is a suspect for this action + std::string suspect; + if (m_gamedef->rollback()) + suspect = m_gamedef->rollback()->getSuspect(p0, 83, 1); + + if (m_gamedef->rollback() && !suspect.empty()) { + // Blame suspect + RollbackScopeActor rollback_scope(m_gamedef->rollback(), suspect, true); + // Get old node for rollback + RollbackNode rollback_oldnode(this, p0, m_gamedef); + // Set node + setNode(p0, n0); + // Report + RollbackNode rollback_newnode(this, p0, m_gamedef); + RollbackAction action; + action.setSetNode(p0, rollback_oldnode, rollback_newnode); + m_gamedef->rollback()->reportAction(action); + } else { + // Set node + setNode(p0, n0); + } + + v3s16 blockpos = getNodeBlockPos(p0); + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if (block != NULL) { + modified_blocks[blockpos] = block; + changed_nodes.emplace_back(p0, n00); + } + + /* + enqueue neighbors for update if neccessary + */ + switch (m_nodedef->get(n0.getContent()).liquid_type) { + case LIQUID_SOURCE: + case LIQUID_FLOWING: + // make sure source flows into all neighboring nodes + for (u16 i = 0; i < num_flows; i++) + if (flows[i].t != NEIGHBOR_UPPER) + m_transforming_liquid.push_back(flows[i].p); + for (u16 i = 0; i < num_airs; i++) + if (airs[i].t != NEIGHBOR_UPPER) + m_transforming_liquid.push_back(airs[i].p); + break; + case LIQUID_NONE: + // this flow has turned to air; neighboring flows might need to do the same + for (u16 i = 0; i < num_flows; i++) + m_transforming_liquid.push_back(flows[i].p); + break; + } + } + //infostream<<"Map::transformLiquids(): loopcount="<<loopcount<<std::endl; + + for (auto &iter : must_reflow) + m_transforming_liquid.push_back(iter); + + voxalgo::update_lighting_nodes(this, changed_nodes, modified_blocks); + env->getScriptIface()->on_liquid_transformed(changed_nodes); + + /* ---------------------------------------------------------------------- + * Manage the queue so that it does not grow indefinately + */ + u16 time_until_purge = g_settings->getU16("liquid_queue_purge_time"); + + if (time_until_purge == 0) + return; // Feature disabled + + time_until_purge *= 1000; // seconds -> milliseconds + + u64 curr_time = porting::getTimeMs(); + u32 prev_unprocessed = m_unprocessed_count; + m_unprocessed_count = m_transforming_liquid.size(); + + // if unprocessed block count is decreasing or stable + if (m_unprocessed_count <= prev_unprocessed) { + m_queue_size_timer_started = false; + } else { + if (!m_queue_size_timer_started) + m_inc_trending_up_start_time = curr_time; + m_queue_size_timer_started = true; + } + + // Account for curr_time overflowing + if (m_queue_size_timer_started && m_inc_trending_up_start_time > curr_time) + m_queue_size_timer_started = false; + + /* If the queue has been growing for more than liquid_queue_purge_time seconds + * and the number of unprocessed blocks is still > liquid_loop_max then we + * cannot keep up; dump the oldest blocks from the queue so that the queue + * has liquid_loop_max items in it + */ + if (m_queue_size_timer_started + && curr_time - m_inc_trending_up_start_time > time_until_purge + && m_unprocessed_count > liquid_loop_max) { + + size_t dump_qty = m_unprocessed_count - liquid_loop_max; + + infostream << "transformLiquids(): DUMPING " << dump_qty + << " blocks from the queue" << std::endl; + + while (dump_qty--) + m_transforming_liquid.pop_front(); + + m_queue_size_timer_started = false; // optimistically assume we can keep up now + m_unprocessed_count = m_transforming_liquid.size(); + } +} + +std::vector<v3s16> Map::findNodesWithMetadata(v3s16 p1, v3s16 p2) +{ + std::vector<v3s16> positions_with_meta; + + sortBoxVerticies(p1, p2); + v3s16 bpmin = getNodeBlockPos(p1); + v3s16 bpmax = getNodeBlockPos(p2); + + VoxelArea area(p1, p2); + + for (s16 z = bpmin.Z; z <= bpmax.Z; z++) + for (s16 y = bpmin.Y; y <= bpmax.Y; y++) + for (s16 x = bpmin.X; x <= bpmax.X; x++) { + v3s16 blockpos(x, y, z); + + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if (!block) { + verbosestream << "Map::getNodeMetadata(): Need to emerge " + << PP(blockpos) << std::endl; + block = emergeBlock(blockpos, false); + } + if (!block) { + infostream << "WARNING: Map::getNodeMetadata(): Block not found" + << std::endl; + continue; + } + + v3s16 p_base = blockpos * MAP_BLOCKSIZE; + std::vector<v3s16> keys = block->m_node_metadata.getAllKeys(); + for (size_t i = 0; i != keys.size(); i++) { + v3s16 p(keys[i] + p_base); + if (!area.contains(p)) + continue; + + positions_with_meta.push_back(p); + } + } + + return positions_with_meta; +} + +NodeMetadata *Map::getNodeMetadata(v3s16 p) +{ + v3s16 blockpos = getNodeBlockPos(p); + v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE; + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if(!block){ + infostream<<"Map::getNodeMetadata(): Need to emerge " + <<PP(blockpos)<<std::endl; + block = emergeBlock(blockpos, false); + } + if(!block){ + warningstream<<"Map::getNodeMetadata(): Block not found" + <<std::endl; + return NULL; + } + NodeMetadata *meta = block->m_node_metadata.get(p_rel); + return meta; +} + +bool Map::setNodeMetadata(v3s16 p, NodeMetadata *meta) +{ + v3s16 blockpos = getNodeBlockPos(p); + v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE; + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if(!block){ + infostream<<"Map::setNodeMetadata(): Need to emerge " + <<PP(blockpos)<<std::endl; + block = emergeBlock(blockpos, false); + } + if(!block){ + warningstream<<"Map::setNodeMetadata(): Block not found" + <<std::endl; + return false; + } + block->m_node_metadata.set(p_rel, meta); + return true; +} + +void Map::removeNodeMetadata(v3s16 p) +{ + v3s16 blockpos = getNodeBlockPos(p); + v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE; + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if(block == NULL) + { + warningstream<<"Map::removeNodeMetadata(): Block not found" + <<std::endl; + return; + } + block->m_node_metadata.remove(p_rel); +} + +NodeTimer Map::getNodeTimer(v3s16 p) +{ + v3s16 blockpos = getNodeBlockPos(p); + v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE; + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if(!block){ + infostream<<"Map::getNodeTimer(): Need to emerge " + <<PP(blockpos)<<std::endl; + block = emergeBlock(blockpos, false); + } + if(!block){ + warningstream<<"Map::getNodeTimer(): Block not found" + <<std::endl; + return NodeTimer(); + } + NodeTimer t = block->m_node_timers.get(p_rel); + NodeTimer nt(t.timeout, t.elapsed, p); + return nt; +} + +void Map::setNodeTimer(const NodeTimer &t) +{ + v3s16 p = t.position; + v3s16 blockpos = getNodeBlockPos(p); + v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE; + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if(!block){ + infostream<<"Map::setNodeTimer(): Need to emerge " + <<PP(blockpos)<<std::endl; + block = emergeBlock(blockpos, false); + } + if(!block){ + warningstream<<"Map::setNodeTimer(): Block not found" + <<std::endl; + return; + } + NodeTimer nt(t.timeout, t.elapsed, p_rel); + block->m_node_timers.set(nt); +} + +void Map::removeNodeTimer(v3s16 p) +{ + v3s16 blockpos = getNodeBlockPos(p); + v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE; + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if(block == NULL) + { + warningstream<<"Map::removeNodeTimer(): Block not found" + <<std::endl; + return; + } + block->m_node_timers.remove(p_rel); +} + +bool Map::determineAdditionalOcclusionCheck(const v3s16 &pos_camera, + const core::aabbox3d<s16> &block_bounds, v3s16 &check) +{ + /* + This functions determines the node inside the target block that is + closest to the camera position. This increases the occlusion culling + accuracy in straight and diagonal corridors. + The returned position will be occlusion checked first in addition to the + others (8 corners + center). + No position is returned if + - the closest node is a corner, corners are checked anyway. + - the camera is inside the target block, it will never be occluded. + */ +#define CLOSEST_EDGE(pos, bounds, axis) \ + ((pos).axis <= (bounds).MinEdge.axis) ? (bounds).MinEdge.axis : \ + (bounds).MaxEdge.axis + + bool x_inside = (block_bounds.MinEdge.X <= pos_camera.X) && + (pos_camera.X <= block_bounds.MaxEdge.X); + bool y_inside = (block_bounds.MinEdge.Y <= pos_camera.Y) && + (pos_camera.Y <= block_bounds.MaxEdge.Y); + bool z_inside = (block_bounds.MinEdge.Z <= pos_camera.Z) && + (pos_camera.Z <= block_bounds.MaxEdge.Z); + + if (x_inside && y_inside && z_inside) + return false; // Camera inside target mapblock + + // straight + if (x_inside && y_inside) { + check = v3s16(pos_camera.X, pos_camera.Y, 0); + check.Z = CLOSEST_EDGE(pos_camera, block_bounds, Z); + return true; + } else if (y_inside && z_inside) { + check = v3s16(0, pos_camera.Y, pos_camera.Z); + check.X = CLOSEST_EDGE(pos_camera, block_bounds, X); + return true; + } else if (x_inside && z_inside) { + check = v3s16(pos_camera.X, 0, pos_camera.Z); + check.Y = CLOSEST_EDGE(pos_camera, block_bounds, Y); + return true; + } + + // diagonal + if (x_inside) { + check = v3s16(pos_camera.X, 0, 0); + check.Y = CLOSEST_EDGE(pos_camera, block_bounds, Y); + check.Z = CLOSEST_EDGE(pos_camera, block_bounds, Z); + return true; + } else if (y_inside) { + check = v3s16(0, pos_camera.Y, 0); + check.X = CLOSEST_EDGE(pos_camera, block_bounds, X); + check.Z = CLOSEST_EDGE(pos_camera, block_bounds, Z); + return true; + } else if (z_inside) { + check = v3s16(0, 0, pos_camera.Z); + check.X = CLOSEST_EDGE(pos_camera, block_bounds, X); + check.Y = CLOSEST_EDGE(pos_camera, block_bounds, Y); + return true; + } + + // Closest node would be a corner, none returned + return false; +} + +bool Map::isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target, + float step, float stepfac, float offset, float end_offset, u32 needed_count) +{ + v3f direction = intToFloat(pos_target - pos_camera, BS); + float distance = direction.getLength(); + + // Normalize direction vector + if (distance > 0.0f) + direction /= distance; + + v3f pos_origin_f = intToFloat(pos_camera, BS); + u32 count = 0; + bool is_valid_position; + + for (; offset < distance + end_offset; offset += step) { + v3f pos_node_f = pos_origin_f + direction * offset; + v3s16 pos_node = floatToInt(pos_node_f, BS); + + MapNode node = getNode(pos_node, &is_valid_position); + + if (is_valid_position && + !m_nodedef->get(node).light_propagates) { + // Cannot see through light-blocking nodes --> occluded + count++; + if (count >= needed_count) + return true; + } + step *= stepfac; + } + return false; +} + +bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes) +{ + // Check occlusion for center and all 8 corners of the mapblock + // Overshoot a little for less flickering + static const s16 bs2 = MAP_BLOCKSIZE / 2 + 1; + static const v3s16 dir9[9] = { + v3s16( 0, 0, 0), + v3s16( 1, 1, 1) * bs2, + v3s16( 1, 1, -1) * bs2, + v3s16( 1, -1, 1) * bs2, + v3s16( 1, -1, -1) * bs2, + v3s16(-1, 1, 1) * bs2, + v3s16(-1, 1, -1) * bs2, + v3s16(-1, -1, 1) * bs2, + v3s16(-1, -1, -1) * bs2, + }; + + v3s16 pos_blockcenter = block->getPosRelative() + (MAP_BLOCKSIZE / 2); + + // Starting step size, value between 1m and sqrt(3)m + float step = BS * 1.2f; + // Multiply step by each iteraction by 'stepfac' to reduce checks in distance + float stepfac = 1.05f; + + float start_offset = BS * 1.0f; + + // The occlusion search of 'isOccluded()' must stop short of the target + // point by distance 'end_offset' to not enter the target mapblock. + // For the 8 mapblock corners 'end_offset' must therefore be the maximum + // diagonal of a mapblock, because we must consider all view angles. + // sqrt(1^2 + 1^2 + 1^2) = 1.732 + float end_offset = -BS * MAP_BLOCKSIZE * 1.732f; + + // to reduce the likelihood of falsely occluded blocks + // require at least two solid blocks + // this is a HACK, we should think of a more precise algorithm + u32 needed_count = 2; + + // Additional occlusion check, see comments in that function + v3s16 check; + if (determineAdditionalOcclusionCheck(cam_pos_nodes, block->getBox(), check)) { + // node is always on a side facing the camera, end_offset can be lower + if (!isOccluded(cam_pos_nodes, check, step, stepfac, start_offset, + -1.0f, needed_count)) + return false; + } + + for (const v3s16 &dir : dir9) { + if (!isOccluded(cam_pos_nodes, pos_blockcenter + dir, step, stepfac, + start_offset, end_offset, needed_count)) + return false; + } + return true; +} + +/* + ServerMap +*/ +ServerMap::ServerMap(const std::string &savedir, IGameDef *gamedef, + EmergeManager *emerge, MetricsBackend *mb): + Map(gamedef), + settings_mgr(savedir + DIR_DELIM + "map_meta.txt"), + m_emerge(emerge) +{ + verbosestream<<FUNCTION_NAME<<std::endl; + + // Tell the EmergeManager about our MapSettingsManager + emerge->map_settings_mgr = &settings_mgr; + + /* + Try to load map; if not found, create a new one. + */ + + // Determine which database backend to use + std::string conf_path = savedir + DIR_DELIM + "world.mt"; + Settings conf; + bool succeeded = conf.readConfigFile(conf_path.c_str()); + if (!succeeded || !conf.exists("backend")) { + // fall back to sqlite3 + conf.set("backend", "sqlite3"); + } + std::string backend = conf.get("backend"); + dbase = createDatabase(backend, savedir, conf); + if (conf.exists("readonly_backend")) { + std::string readonly_dir = savedir + DIR_DELIM + "readonly"; + dbase_ro = createDatabase(conf.get("readonly_backend"), readonly_dir, conf); + } + if (!conf.updateConfigFile(conf_path.c_str())) + errorstream << "ServerMap::ServerMap(): Failed to update world.mt!" << std::endl; + + m_savedir = savedir; + m_map_saving_enabled = false; + + m_save_time_counter = mb->addCounter( + "minetest_map_save_time", "Time spent saving blocks (in microseconds)"); + m_save_count_counter = mb->addCounter( + "minetest_map_saved_blocks", "Number of blocks saved"); + m_loaded_blocks_gauge = mb->addGauge( + "minetest_map_loaded_blocks", "Number of loaded blocks"); + + m_map_compression_level = rangelim(g_settings->getS16("map_compression_level_disk"), -1, 9); + + try { + // If directory exists, check contents and load if possible + if (fs::PathExists(m_savedir)) { + // If directory is empty, it is safe to save into it. + if (fs::GetDirListing(m_savedir).empty()) { + infostream<<"ServerMap: Empty save directory is valid." + <<std::endl; + m_map_saving_enabled = true; + } + else + { + + if (settings_mgr.loadMapMeta()) { + infostream << "ServerMap: Metadata loaded from " + << savedir << std::endl; + } else { + infostream << "ServerMap: Metadata could not be loaded " + "from " << savedir << ", assuming valid save " + "directory." << std::endl; + } + + m_map_saving_enabled = true; + // Map loaded, not creating new one + return; + } + } + // If directory doesn't exist, it is safe to save to it + else{ + m_map_saving_enabled = true; + } + } + catch(std::exception &e) + { + warningstream<<"ServerMap: Failed to load map from "<<savedir + <<", exception: "<<e.what()<<std::endl; + infostream<<"Please remove the map or fix it."<<std::endl; + warningstream<<"Map saving will be disabled."<<std::endl; + } +} + +ServerMap::~ServerMap() +{ + verbosestream<<FUNCTION_NAME<<std::endl; + + try + { + if (m_map_saving_enabled) { + // Save only changed parts + save(MOD_STATE_WRITE_AT_UNLOAD); + infostream << "ServerMap: Saved map to " << m_savedir << std::endl; + } else { + infostream << "ServerMap: Map not saved" << std::endl; + } + } + catch(std::exception &e) + { + infostream<<"ServerMap: Failed to save map to "<<m_savedir + <<", exception: "<<e.what()<<std::endl; + } + + /* + Close database if it was opened + */ + delete dbase; + delete dbase_ro; +} + +MapgenParams *ServerMap::getMapgenParams() +{ + // getMapgenParams() should only ever be called after Server is initialized + assert(settings_mgr.mapgen_params != NULL); + return settings_mgr.mapgen_params; +} + +u64 ServerMap::getSeed() +{ + return getMapgenParams()->seed; +} + +bool ServerMap::blockpos_over_mapgen_limit(v3s16 p) +{ + const s16 mapgen_limit_bp = rangelim( + getMapgenParams()->mapgen_limit, 0, MAX_MAP_GENERATION_LIMIT) / + MAP_BLOCKSIZE; + return p.X < -mapgen_limit_bp || + p.X > mapgen_limit_bp || + p.Y < -mapgen_limit_bp || + p.Y > mapgen_limit_bp || + p.Z < -mapgen_limit_bp || + p.Z > mapgen_limit_bp; +} + +bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data) +{ + s16 csize = getMapgenParams()->chunksize; + v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize); + v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1); + + if (!m_chunks_in_progress.insert(bpmin).second) + return false; + + bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info; + EMERGE_DBG_OUT("initBlockMake(): " PP(bpmin) " - " PP(bpmax)); + + v3s16 extra_borders(1, 1, 1); + v3s16 full_bpmin = bpmin - extra_borders; + v3s16 full_bpmax = bpmax + extra_borders; + + // Do nothing if not inside mapgen limits (+-1 because of neighbors) + if (blockpos_over_mapgen_limit(full_bpmin) || + blockpos_over_mapgen_limit(full_bpmax)) + return false; + + data->seed = getSeed(); + data->blockpos_min = bpmin; + data->blockpos_max = bpmax; + data->nodedef = m_nodedef; + + /* + Create the whole area of this and the neighboring blocks + */ + for (s16 x = full_bpmin.X; x <= full_bpmax.X; x++) + for (s16 z = full_bpmin.Z; z <= full_bpmax.Z; z++) { + v2s16 sectorpos(x, z); + // Sector metadata is loaded from disk if not already loaded. + MapSector *sector = createSector(sectorpos); + FATAL_ERROR_IF(sector == NULL, "createSector() failed"); + + for (s16 y = full_bpmin.Y; y <= full_bpmax.Y; y++) { + v3s16 p(x, y, z); + + MapBlock *block = emergeBlock(p, false); + if (block == NULL) { + block = createBlock(p); + + // Block gets sunlight if this is true. + // Refer to the map generator heuristics. + bool ug = m_emerge->isBlockUnderground(p); + block->setIsUnderground(ug); + } + } + } + + /* + Now we have a big empty area. + + Make a ManualMapVoxelManipulator that contains this and the + neighboring blocks + */ + + data->vmanip = new MMVManip(this); + data->vmanip->initialEmerge(full_bpmin, full_bpmax); + + // Data is ready now. + return true; +} + +void ServerMap::finishBlockMake(BlockMakeData *data, + std::map<v3s16, MapBlock*> *changed_blocks) +{ + v3s16 bpmin = data->blockpos_min; + v3s16 bpmax = data->blockpos_max; + + bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info; + EMERGE_DBG_OUT("finishBlockMake(): " PP(bpmin) " - " PP(bpmax)); + + /* + Blit generated stuff to map + NOTE: blitBackAll adds nearly everything to changed_blocks + */ + data->vmanip->blitBackAll(changed_blocks); + + EMERGE_DBG_OUT("finishBlockMake: changed_blocks.size()=" + << changed_blocks->size()); + + /* + Copy transforming liquid information + */ + while (data->transforming_liquid.size()) { + m_transforming_liquid.push_back(data->transforming_liquid.front()); + data->transforming_liquid.pop_front(); + } + + for (auto &changed_block : *changed_blocks) { + MapBlock *block = changed_block.second; + if (!block) + continue; + /* + Update day/night difference cache of the MapBlocks + */ + block->expireDayNightDiff(); + /* + Set block as modified + */ + block->raiseModified(MOD_STATE_WRITE_NEEDED, + MOD_REASON_EXPIRE_DAYNIGHTDIFF); + } + + /* + Set central blocks as generated + */ + for (s16 x = bpmin.X; x <= bpmax.X; x++) + for (s16 z = bpmin.Z; z <= bpmax.Z; z++) + for (s16 y = bpmin.Y; y <= bpmax.Y; y++) { + MapBlock *block = getBlockNoCreateNoEx(v3s16(x, y, z)); + if (!block) + continue; + + block->setGenerated(true); + } + + /* + Save changed parts of map + NOTE: Will be saved later. + */ + //save(MOD_STATE_WRITE_AT_UNLOAD); + m_chunks_in_progress.erase(bpmin); +} + +MapSector *ServerMap::createSector(v2s16 p2d) +{ + /* + Check if it exists already in memory + */ + MapSector *sector = getSectorNoGenerate(p2d); + if (sector) + return sector; + + /* + Do not create over max mapgen limit + */ + if (blockpos_over_max_limit(v3s16(p2d.X, 0, p2d.Y))) + throw InvalidPositionException("createSector(): pos. over max mapgen limit"); + + /* + Generate blank sector + */ + + sector = new MapSector(this, p2d, m_gamedef); + + /* + Insert to container + */ + m_sectors[p2d] = sector; + + return sector; +} + +MapBlock * ServerMap::createBlock(v3s16 p) +{ + /* + Do not create over max mapgen limit + */ + if (blockpos_over_max_limit(p)) + throw InvalidPositionException("createBlock(): pos. over max mapgen limit"); + + v2s16 p2d(p.X, p.Z); + s16 block_y = p.Y; + /* + This will create or load a sector if not found in memory. + If block exists on disk, it will be loaded. + + NOTE: On old save formats, this will be slow, as it generates + lighting on blocks for them. + */ + MapSector *sector; + try { + sector = createSector(p2d); + } catch (InvalidPositionException &e) { + infostream<<"createBlock: createSector() failed"<<std::endl; + throw e; + } + + /* + Try to get a block from the sector + */ + + MapBlock *block = sector->getBlockNoCreateNoEx(block_y); + if (block) { + if(block->isDummy()) + block->unDummify(); + return block; + } + // Create blank + block = sector->createBlankBlock(block_y); + + return block; +} + +MapBlock * ServerMap::emergeBlock(v3s16 p, bool create_blank) +{ + { + MapBlock *block = getBlockNoCreateNoEx(p); + if (block && !block->isDummy()) + return block; + } + + { + MapBlock *block = loadBlock(p); + if(block) + return block; + } + + if (create_blank) { + MapSector *sector = createSector(v2s16(p.X, p.Z)); + MapBlock *block = sector->createBlankBlock(p.Y); + + return block; + } + + return NULL; +} + +MapBlock *ServerMap::getBlockOrEmerge(v3s16 p3d) +{ + MapBlock *block = getBlockNoCreateNoEx(p3d); + if (block == NULL) + m_emerge->enqueueBlockEmerge(PEER_ID_INEXISTENT, p3d, false); + + return block; +} + +bool ServerMap::isBlockInQueue(v3s16 pos) +{ + return m_emerge && m_emerge->isBlockInQueue(pos); +} + +void ServerMap::addNodeAndUpdate(v3s16 p, MapNode n, + std::map<v3s16, MapBlock*> &modified_blocks, + bool remove_metadata) +{ + Map::addNodeAndUpdate(p, n, modified_blocks, remove_metadata); + + /* + Add neighboring liquid nodes and this node to transform queue. + (it's vital for the node itself to get updated last, if it was removed.) + */ + + for (const v3s16 &dir : g_7dirs) { + v3s16 p2 = p + dir; + + bool is_valid_position; + MapNode n2 = getNode(p2, &is_valid_position); + if(is_valid_position && + (m_nodedef->get(n2).isLiquid() || + n2.getContent() == CONTENT_AIR)) + m_transforming_liquid.push_back(p2); + } +} + +// N.B. This requires no synchronization, since data will not be modified unless +// the VoxelManipulator being updated belongs to the same thread. +void ServerMap::updateVManip(v3s16 pos) +{ + Mapgen *mg = m_emerge->getCurrentMapgen(); + if (!mg) + return; + + MMVManip *vm = mg->vm; + if (!vm) + return; + + if (!vm->m_area.contains(pos)) + return; + + s32 idx = vm->m_area.index(pos); + vm->m_data[idx] = getNode(pos); + vm->m_flags[idx] &= ~VOXELFLAG_NO_DATA; + + vm->m_is_dirty = true; +} + +void ServerMap::reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks) +{ + m_loaded_blocks_gauge->set(all_blocks); + m_save_time_counter->increment(save_time_us); + m_save_count_counter->increment(saved_blocks); +} + +void ServerMap::save(ModifiedState save_level) +{ + if (!m_map_saving_enabled) { + warningstream<<"Not saving map, saving disabled."<<std::endl; + return; + } + + const auto start_time = porting::getTimeUs(); + + if(save_level == MOD_STATE_CLEAN) + infostream<<"ServerMap: Saving whole map, this can take time." + <<std::endl; + + if (m_map_metadata_changed || save_level == MOD_STATE_CLEAN) { + if (settings_mgr.saveMapMeta()) + m_map_metadata_changed = false; + } + + // Profile modified reasons + Profiler modprofiler; + + u32 block_count = 0; + u32 block_count_all = 0; // Number of blocks in memory + + // Don't do anything with sqlite unless something is really saved + bool save_started = false; + + for (auto §or_it : m_sectors) { + MapSector *sector = sector_it.second; + + MapBlockVect blocks; + sector->getBlocks(blocks); + + for (MapBlock *block : blocks) { + block_count_all++; + + if(block->getModified() >= (u32)save_level) { + // Lazy beginSave() + if(!save_started) { + beginSave(); + save_started = true; + } + + modprofiler.add(block->getModifiedReasonString(), 1); + + saveBlock(block); + block_count++; + } + } + } + + if(save_started) + endSave(); + + /* + Only print if something happened or saved whole map + */ + if(save_level == MOD_STATE_CLEAN + || block_count != 0) { + infostream << "ServerMap: Written: " + << block_count << " blocks" + << ", " << block_count_all << " blocks in memory." + << std::endl; + PrintInfo(infostream); // ServerMap/ClientMap: + infostream<<"Blocks modified by: "<<std::endl; + modprofiler.print(infostream); + } + + const auto end_time = porting::getTimeUs(); + reportMetrics(end_time - start_time, block_count, block_count_all); +} + +void ServerMap::listAllLoadableBlocks(std::vector<v3s16> &dst) +{ + dbase->listAllLoadableBlocks(dst); + if (dbase_ro) + dbase_ro->listAllLoadableBlocks(dst); +} + +void ServerMap::listAllLoadedBlocks(std::vector<v3s16> &dst) +{ + for (auto §or_it : m_sectors) { + MapSector *sector = sector_it.second; + + MapBlockVect blocks; + sector->getBlocks(blocks); + + for (MapBlock *block : blocks) { + v3s16 p = block->getPos(); + dst.push_back(p); + } + } +} + +MapDatabase *ServerMap::createDatabase( + const std::string &name, + const std::string &savedir, + Settings &conf) +{ + if (name == "sqlite3") + return new MapDatabaseSQLite3(savedir); + if (name == "dummy") + return new Database_Dummy(); + #if USE_LEVELDB + if (name == "leveldb") + return new Database_LevelDB(savedir); + #endif + #if USE_REDIS + if (name == "redis") + return new Database_Redis(conf); + #endif + #if USE_POSTGRESQL + if (name == "postgresql") { + std::string connect_string; + conf.getNoEx("pgsql_connection", connect_string); + return new MapDatabasePostgreSQL(connect_string); + } + #endif + + throw BaseException(std::string("Database backend ") + name + " not supported."); +} + +void ServerMap::beginSave() +{ + dbase->beginSave(); +} + +void ServerMap::endSave() +{ + dbase->endSave(); +} + +bool ServerMap::saveBlock(MapBlock *block) +{ + return saveBlock(block, dbase, m_map_compression_level); +} + +bool ServerMap::saveBlock(MapBlock *block, MapDatabase *db, int compression_level) +{ + v3s16 p3d = block->getPos(); + + // Dummy blocks are not written + if (block->isDummy()) { + warningstream << "saveBlock: Not writing dummy block " + << PP(p3d) << std::endl; + return true; + } + + // Format used for writing + u8 version = SER_FMT_VER_HIGHEST_WRITE; + + /* + [0] u8 serialization version + [1] data + */ + std::ostringstream o(std::ios_base::binary); + o.write((char*) &version, 1); + block->serialize(o, version, true, compression_level); + + bool ret = db->saveBlock(p3d, o.str()); + if (ret) { + // We just wrote it to the disk so clear modified flag + block->resetModified(); + } + return ret; +} + +void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load) +{ + try { + std::istringstream is(*blob, std::ios_base::binary); + + u8 version = SER_FMT_VER_INVALID; + is.read((char*)&version, 1); + + if(is.fail()) + throw SerializationError("ServerMap::loadBlock(): Failed" + " to read MapBlock version"); + + MapBlock *block = NULL; + bool created_new = false; + block = sector->getBlockNoCreateNoEx(p3d.Y); + if(block == NULL) + { + block = sector->createBlankBlockNoInsert(p3d.Y); + created_new = true; + } + + // Read basic data + block->deSerialize(is, version, true); + + // If it's a new block, insert it to the map + if (created_new) { + sector->insertBlock(block); + ReflowScan scanner(this, m_emerge->ndef); + scanner.scan(block, &m_transforming_liquid); + } + + /* + Save blocks loaded in old format in new format + */ + + //if(version < SER_FMT_VER_HIGHEST_READ || save_after_load) + // Only save if asked to; no need to update version + if(save_after_load) + saveBlock(block); + + // We just loaded it from, so it's up-to-date. + block->resetModified(); + } + catch(SerializationError &e) + { + errorstream<<"Invalid block data in database" + <<" ("<<p3d.X<<","<<p3d.Y<<","<<p3d.Z<<")" + <<" (SerializationError): "<<e.what()<<std::endl; + + // TODO: Block should be marked as invalid in memory so that it is + // not touched but the game can run + + if(g_settings->getBool("ignore_world_load_errors")){ + errorstream<<"Ignoring block load error. Duck and cover! " + <<"(ignore_world_load_errors)"<<std::endl; + } else { + throw SerializationError("Invalid block data in database"); + } + } +} + +MapBlock* ServerMap::loadBlock(v3s16 blockpos) +{ + bool created_new = (getBlockNoCreateNoEx(blockpos) == NULL); + + v2s16 p2d(blockpos.X, blockpos.Z); + + std::string ret; + dbase->loadBlock(blockpos, &ret); + if (!ret.empty()) { + loadBlock(&ret, blockpos, createSector(p2d), false); + } else if (dbase_ro) { + dbase_ro->loadBlock(blockpos, &ret); + if (!ret.empty()) { + loadBlock(&ret, blockpos, createSector(p2d), false); + } + } else { + return NULL; + } + + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if (created_new && (block != NULL)) { + std::map<v3s16, MapBlock*> modified_blocks; + // Fix lighting if necessary + voxalgo::update_block_border_lighting(this, block, modified_blocks); + if (!modified_blocks.empty()) { + //Modified lighting, send event + MapEditEvent event; + event.type = MEET_OTHER; + std::map<v3s16, MapBlock *>::iterator it; + for (it = modified_blocks.begin(); + it != modified_blocks.end(); ++it) + event.modified_blocks.insert(it->first); + dispatchEvent(event); + } + } + return block; +} + +bool ServerMap::deleteBlock(v3s16 blockpos) +{ + if (!dbase->deleteBlock(blockpos)) + return false; + + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if (block) { + v2s16 p2d(blockpos.X, blockpos.Z); + MapSector *sector = getSectorNoGenerate(p2d); + if (!sector) + return false; + sector->deleteBlock(block); + } + + return true; +} + +void ServerMap::PrintInfo(std::ostream &out) +{ + out<<"ServerMap: "; +} + +bool ServerMap::repairBlockLight(v3s16 blockpos, + std::map<v3s16, MapBlock *> *modified_blocks) +{ + MapBlock *block = emergeBlock(blockpos, false); + if (!block || !block->isGenerated()) + return false; + voxalgo::repair_block_light(this, block, modified_blocks); + return true; +} + +MMVManip::MMVManip(Map *map): + VoxelManipulator(), + m_map(map) +{ + assert(map); +} + +void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max, + bool load_if_inexistent) +{ + TimeTaker timer1("initialEmerge", &emerge_time); + + assert(m_map); + + // Units of these are MapBlocks + v3s16 p_min = blockpos_min; + v3s16 p_max = blockpos_max; + + VoxelArea block_area_nodes + (p_min*MAP_BLOCKSIZE, (p_max+1)*MAP_BLOCKSIZE-v3s16(1,1,1)); + + u32 size_MB = block_area_nodes.getVolume()*4/1000000; + if(size_MB >= 1) + { + infostream<<"initialEmerge: area: "; + block_area_nodes.print(infostream); + infostream<<" ("<<size_MB<<"MB)"; + infostream<<std::endl; + } + + addArea(block_area_nodes); + + for(s32 z=p_min.Z; z<=p_max.Z; z++) + for(s32 y=p_min.Y; y<=p_max.Y; y++) + for(s32 x=p_min.X; x<=p_max.X; x++) + { + u8 flags = 0; + MapBlock *block; + v3s16 p(x,y,z); + std::map<v3s16, u8>::iterator n; + n = m_loaded_blocks.find(p); + if(n != m_loaded_blocks.end()) + continue; + + bool block_data_inexistent = false; + { + TimeTaker timer2("emerge load", &emerge_load_time); + + block = m_map->getBlockNoCreateNoEx(p); + if (!block || block->isDummy()) + block_data_inexistent = true; + else + block->copyTo(*this); + } + + if(block_data_inexistent) + { + + if (load_if_inexistent && !blockpos_over_max_limit(p)) { + ServerMap *svrmap = (ServerMap *)m_map; + block = svrmap->emergeBlock(p, false); + if (block == NULL) + block = svrmap->createBlock(p); + block->copyTo(*this); + } else { + flags |= VMANIP_BLOCK_DATA_INEXIST; + + /* + Mark area inexistent + */ + VoxelArea a(p*MAP_BLOCKSIZE, (p+1)*MAP_BLOCKSIZE-v3s16(1,1,1)); + // Fill with VOXELFLAG_NO_DATA + for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++) + for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++) + { + s32 i = m_area.index(a.MinEdge.X,y,z); + memset(&m_flags[i], VOXELFLAG_NO_DATA, MAP_BLOCKSIZE); + } + } + } + /*else if (block->getNode(0, 0, 0).getContent() == CONTENT_IGNORE) + { + // Mark that block was loaded as blank + flags |= VMANIP_BLOCK_CONTAINS_CIGNORE; + }*/ + + m_loaded_blocks[p] = flags; + } + + m_is_dirty = false; +} + +void MMVManip::blitBackAll(std::map<v3s16, MapBlock*> *modified_blocks, + bool overwrite_generated) +{ + if(m_area.getExtent() == v3s16(0,0,0)) + return; + assert(m_map); + + /* + Copy data of all blocks + */ + for (auto &loaded_block : m_loaded_blocks) { + v3s16 p = loaded_block.first; + MapBlock *block = m_map->getBlockNoCreateNoEx(p); + bool existed = !(loaded_block.second & VMANIP_BLOCK_DATA_INEXIST); + if (!existed || (block == NULL) || + (!overwrite_generated && block->isGenerated())) + continue; + + block->copyFrom(*this); + block->raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_VMANIP); + + if(modified_blocks) + (*modified_blocks)[p] = block; + } +} + +MMVManip *MMVManip::clone() const +{ + MMVManip *ret = new MMVManip(); + + const s32 size = m_area.getVolume(); + ret->m_area = m_area; + if (m_data) { + ret->m_data = new MapNode[size]; + memcpy(ret->m_data, m_data, size * sizeof(MapNode)); + } + if (m_flags) { + ret->m_flags = new u8[size]; + memcpy(ret->m_flags, m_flags, size * sizeof(u8)); + } + + ret->m_is_dirty = m_is_dirty; + // Even if the copy is disconnected from a map object keep the information + // needed to write it back to one + ret->m_loaded_blocks = m_loaded_blocks; + + return ret; +} + +void MMVManip::reparent(Map *map) +{ + assert(map && !m_map); + m_map = map; +} + +//END diff --git a/src/map.h b/src/map.h new file mode 100644 index 0000000..6bc2aaa --- /dev/null +++ b/src/map.h @@ -0,0 +1,483 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <iostream> +#include <sstream> +#include <set> +#include <map> +#include <list> + +#include "irrlichttypes_bloated.h" +#include "mapnode.h" +#include "constants.h" +#include "voxel.h" +#include "modifiedstate.h" +#include "util/container.h" +#include "util/metricsbackend.h" +#include "nodetimer.h" +#include "map_settings_manager.h" +#include "debug.h" + +class Settings; +class MapDatabase; +class ClientMap; +class MapSector; +class ServerMapSector; +class MapBlock; +class NodeMetadata; +class IGameDef; +class IRollbackManager; +class EmergeManager; +class MetricsBackend; +class ServerEnvironment; +struct BlockMakeData; + +/* + MapEditEvent +*/ + +enum MapEditEventType{ + // Node added (changed from air or something else to something) + MEET_ADDNODE, + // Node removed (changed to air) + MEET_REMOVENODE, + // Node swapped (changed without metadata change) + MEET_SWAPNODE, + // Node metadata changed + MEET_BLOCK_NODE_METADATA_CHANGED, + // Anything else (modified_blocks are set unsent) + MEET_OTHER +}; + +struct MapEditEvent +{ + MapEditEventType type = MEET_OTHER; + v3s16 p; + MapNode n = CONTENT_AIR; + std::set<v3s16> modified_blocks; + bool is_private_change = false; + + MapEditEvent() = default; + + VoxelArea getArea() const + { + switch(type){ + case MEET_ADDNODE: + return VoxelArea(p); + case MEET_REMOVENODE: + return VoxelArea(p); + case MEET_SWAPNODE: + return VoxelArea(p); + case MEET_BLOCK_NODE_METADATA_CHANGED: + { + v3s16 np1 = p*MAP_BLOCKSIZE; + v3s16 np2 = np1 + v3s16(1,1,1)*MAP_BLOCKSIZE - v3s16(1,1,1); + return VoxelArea(np1, np2); + } + case MEET_OTHER: + { + VoxelArea a; + for (v3s16 p : modified_blocks) { + v3s16 np1 = p*MAP_BLOCKSIZE; + v3s16 np2 = np1 + v3s16(1,1,1)*MAP_BLOCKSIZE - v3s16(1,1,1); + a.addPoint(np1); + a.addPoint(np2); + } + return a; + } + } + return VoxelArea(); + } +}; + +class MapEventReceiver +{ +public: + // event shall be deleted by caller after the call. + virtual void onMapEditEvent(const MapEditEvent &event) = 0; +}; + +class Map /*: public NodeContainer*/ +{ +public: + + Map(IGameDef *gamedef); + virtual ~Map(); + DISABLE_CLASS_COPY(Map); + + /* + Drop (client) or delete (server) the map. + */ + virtual void drop() + { + delete this; + } + + void addEventReceiver(MapEventReceiver *event_receiver); + void removeEventReceiver(MapEventReceiver *event_receiver); + // event shall be deleted by caller after the call. + void dispatchEvent(const MapEditEvent &event); + + // On failure returns NULL + MapSector * getSectorNoGenerateNoLock(v2s16 p2d); + // Same as the above (there exists no lock anymore) + MapSector * getSectorNoGenerate(v2s16 p2d); + + /* + This is overloaded by ClientMap and ServerMap to allow + their differing fetch methods. + */ + virtual MapSector * emergeSector(v2s16 p){ return NULL; } + + // Returns InvalidPositionException if not found + MapBlock * getBlockNoCreate(v3s16 p); + // Returns NULL if not found + MapBlock * getBlockNoCreateNoEx(v3s16 p); + + /* Server overrides */ + virtual MapBlock * emergeBlock(v3s16 p, bool create_blank=true) + { return getBlockNoCreateNoEx(p); } + + inline const NodeDefManager * getNodeDefManager() { return m_nodedef; } + + bool isValidPosition(v3s16 p); + + // throws InvalidPositionException if not found + void setNode(v3s16 p, MapNode & n); + + // Returns a CONTENT_IGNORE node if not found + // If is_valid_position is not NULL then this will be set to true if the + // position is valid, otherwise false + MapNode getNode(v3s16 p, bool *is_valid_position = NULL); + + /* + These handle lighting but not faces. + */ + virtual void addNodeAndUpdate(v3s16 p, MapNode n, + std::map<v3s16, MapBlock*> &modified_blocks, + bool remove_metadata = true); + void removeNodeAndUpdate(v3s16 p, + std::map<v3s16, MapBlock*> &modified_blocks); + + /* + Wrappers for the latter ones. + These emit events. + Return true if succeeded, false if not. + */ + bool addNodeWithEvent(v3s16 p, MapNode n, bool remove_metadata = true); + bool removeNodeWithEvent(v3s16 p); + + // Call these before and after saving of many blocks + virtual void beginSave() {} + virtual void endSave() {} + + virtual void save(ModifiedState save_level) { FATAL_ERROR("FIXME"); } + + /* + Return true unless the map definitely cannot save blocks. + */ + virtual bool maySaveBlocks() { return true; } + + // Server implements these. + // Client leaves them as no-op. + virtual bool saveBlock(MapBlock *block) { return false; } + virtual bool deleteBlock(v3s16 blockpos) { return false; } + + /* + Updates usage timers and unloads unused blocks and sectors. + Saves modified blocks before unloading if possible. + */ + void timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks, + std::vector<v3s16> *unloaded_blocks=NULL); + + /* + Unloads all blocks with a zero refCount(). + Saves modified blocks before unloading if possible. + */ + void unloadUnreferencedBlocks(std::vector<v3s16> *unloaded_blocks=NULL); + + // Deletes sectors and their blocks from memory + // Takes cache into account + // If deleted sector is in sector cache, clears cache + void deleteSectors(std::vector<v2s16> &list); + + // For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: " + virtual void PrintInfo(std::ostream &out); + + /* + Node metadata + These are basically coordinate wrappers to MapBlock + */ + + std::vector<v3s16> findNodesWithMetadata(v3s16 p1, v3s16 p2); + NodeMetadata *getNodeMetadata(v3s16 p); + + /** + * Sets metadata for a node. + * This method sets the metadata for a given node. + * On success, it returns @c true and the object pointed to + * by @p meta is then managed by the system and should + * not be deleted by the caller. + * + * In case of failure, the method returns @c false and the + * caller is still responsible for deleting the object! + * + * @param p node coordinates + * @param meta pointer to @c NodeMetadata object + * @return @c true on success, false on failure + */ + bool setNodeMetadata(v3s16 p, NodeMetadata *meta); + void removeNodeMetadata(v3s16 p); + + /* + Node Timers + These are basically coordinate wrappers to MapBlock + */ + + NodeTimer getNodeTimer(v3s16 p); + void setNodeTimer(const NodeTimer &t); + void removeNodeTimer(v3s16 p); + + /* + Variables + */ + + bool isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes); +protected: + IGameDef *m_gamedef; + + std::set<MapEventReceiver*> m_event_receivers; + + std::unordered_map<v2s16, MapSector*> m_sectors; + + // Be sure to set this to NULL when the cached sector is deleted + MapSector *m_sector_cache = nullptr; + v2s16 m_sector_cache_p; + + // This stores the properties of the nodes on the map. + const NodeDefManager *m_nodedef; + + // Can be implemented by child class + virtual void reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks) {} + + bool determineAdditionalOcclusionCheck(const v3s16 &pos_camera, + const core::aabbox3d<s16> &block_bounds, v3s16 &check); + bool isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target, + float step, float stepfac, float start_offset, float end_offset, + u32 needed_count); +}; + +/* + ServerMap + + This is the only map class that is able to generate map. +*/ + +class ServerMap : public Map +{ +public: + /* + savedir: directory to which map data should be saved + */ + ServerMap(const std::string &savedir, IGameDef *gamedef, EmergeManager *emerge, MetricsBackend *mb); + ~ServerMap(); + + /* + Get a sector from somewhere. + - Check memory + - Check disk (doesn't load blocks) + - Create blank one + */ + MapSector *createSector(v2s16 p); + + /* + Blocks are generated by using these and makeBlock(). + */ + bool blockpos_over_mapgen_limit(v3s16 p); + bool initBlockMake(v3s16 blockpos, BlockMakeData *data); + void finishBlockMake(BlockMakeData *data, + std::map<v3s16, MapBlock*> *changed_blocks); + + /* + Get a block from somewhere. + - Memory + - Create blank + */ + MapBlock *createBlock(v3s16 p); + + /* + Forcefully get a block from somewhere. + - Memory + - Load from disk + - Create blank filled with CONTENT_IGNORE + + */ + MapBlock *emergeBlock(v3s16 p, bool create_blank=true) override; + + /* + Try to get a block. + If it does not exist in memory, add it to the emerge queue. + - Memory + - Emerge Queue (deferred disk or generate) + */ + MapBlock *getBlockOrEmerge(v3s16 p3d); + + bool isBlockInQueue(v3s16 pos); + + void addNodeAndUpdate(v3s16 p, MapNode n, + std::map<v3s16, MapBlock*> &modified_blocks, + bool remove_metadata) override; + + /* + Database functions + */ + static MapDatabase *createDatabase(const std::string &name, const std::string &savedir, Settings &conf); + + // Call these before and after saving of blocks + void beginSave() override; + void endSave() override; + + void save(ModifiedState save_level) override; + void listAllLoadableBlocks(std::vector<v3s16> &dst); + void listAllLoadedBlocks(std::vector<v3s16> &dst); + + MapgenParams *getMapgenParams(); + + bool saveBlock(MapBlock *block) override; + static bool saveBlock(MapBlock *block, MapDatabase *db, int compression_level = -1); + MapBlock* loadBlock(v3s16 p); + // Database version + void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false); + + bool deleteBlock(v3s16 blockpos) override; + + void updateVManip(v3s16 pos); + + // For debug printing + void PrintInfo(std::ostream &out) override; + + bool isSavingEnabled(){ return m_map_saving_enabled; } + + u64 getSeed(); + + /*! + * Fixes lighting in one map block. + * May modify other blocks as well, as light can spread + * out of the specified block. + * Returns false if the block is not generated (so nothing + * changed), true otherwise. + */ + bool repairBlockLight(v3s16 blockpos, + std::map<v3s16, MapBlock *> *modified_blocks); + + void transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks, + ServerEnvironment *env); + + void transforming_liquid_add(v3s16 p); + + MapSettingsManager settings_mgr; + +protected: + + void reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks) override; + +private: + friend class LuaVoxelManip; + + // Emerge manager + EmergeManager *m_emerge; + + std::string m_savedir; + bool m_map_saving_enabled; + + int m_map_compression_level; + + std::set<v3s16> m_chunks_in_progress; + + // Queued transforming water nodes + UniqueQueue<v3s16> m_transforming_liquid; + f32 m_transforming_liquid_loop_count_multiplier = 1.0f; + u32 m_unprocessed_count = 0; + u64 m_inc_trending_up_start_time = 0; // milliseconds + bool m_queue_size_timer_started = false; + + /* + Metadata is re-written on disk only if this is true. + This is reset to false when written on disk. + */ + bool m_map_metadata_changed = true; + MapDatabase *dbase = nullptr; + MapDatabase *dbase_ro = nullptr; + + // Map metrics + MetricGaugePtr m_loaded_blocks_gauge; + MetricCounterPtr m_save_time_counter; + MetricCounterPtr m_save_count_counter; +}; + + +#define VMANIP_BLOCK_DATA_INEXIST 1 +#define VMANIP_BLOCK_CONTAINS_CIGNORE 2 + +class MMVManip : public VoxelManipulator +{ +public: + MMVManip(Map *map); + virtual ~MMVManip() = default; + + virtual void clear() + { + VoxelManipulator::clear(); + m_loaded_blocks.clear(); + } + + void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max, + bool load_if_inexistent = true); + + // This is much faster with big chunks of generated data + void blitBackAll(std::map<v3s16, MapBlock*> * modified_blocks, + bool overwrite_generated = true); + + /* + Creates a copy of this VManip including contents, the copy will not be + associated with a Map. + */ + MMVManip *clone() const; + + // Reassociates a copied VManip to a map + void reparent(Map *map); + + // Is it impossible to call initialEmerge / blitBackAll? + inline bool isOrphan() const { return !m_map; } + + bool m_is_dirty = false; + +protected: + MMVManip() {}; + + // may be null + Map *m_map = nullptr; + /* + key = blockpos + value = flags describing the block + */ + std::map<v3s16, u8> m_loaded_blocks; +}; diff --git a/src/map_settings_manager.cpp b/src/map_settings_manager.cpp new file mode 100644 index 0000000..c75483e --- /dev/null +++ b/src/map_settings_manager.cpp @@ -0,0 +1,180 @@ +/* +Minetest +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "debug.h" +#include "filesys.h" +#include "log.h" +#include "mapgen/mapgen.h" +#include "settings.h" + +#include "map_settings_manager.h" + +MapSettingsManager::MapSettingsManager(const std::string &map_meta_path): + m_map_meta_path(map_meta_path), + m_hierarchy(g_settings) +{ + /* + * We build our own hierarchy which falls back to the global one. + * It looks as follows: (lowest prio first) + * 0: whatever is picked up from g_settings (incl. engine defaults) + * 1: defaults set by scripts (override_meta = false) + * 2: settings present in map_meta.txt or overriden by scripts + */ + m_defaults = new Settings("", &m_hierarchy, 1); + m_map_settings = new Settings("[end_of_params]", &m_hierarchy, 2); +} + + +MapSettingsManager::~MapSettingsManager() +{ + delete m_defaults; + delete m_map_settings; + delete mapgen_params; +} + + +bool MapSettingsManager::getMapSetting( + const std::string &name, std::string *value_out) +{ + return m_map_settings->getNoEx(name, *value_out); +} + + +bool MapSettingsManager::getMapSettingNoiseParams( + const std::string &name, NoiseParams *value_out) +{ + // TODO: Rename to "getNoiseParams" + return m_map_settings->getNoiseParams(name, *value_out); +} + + +bool MapSettingsManager::setMapSetting( + const std::string &name, const std::string &value, bool override_meta) +{ + if (mapgen_params) + return false; + + if (override_meta) + m_map_settings->set(name, value); + else + m_defaults->set(name, value); + + return true; +} + + +bool MapSettingsManager::setMapSettingNoiseParams( + const std::string &name, const NoiseParams *value, bool override_meta) +{ + if (mapgen_params) + return false; + + if (override_meta) + m_map_settings->setNoiseParams(name, *value); + else + m_defaults->setNoiseParams(name, *value); + + return true; +} + + +bool MapSettingsManager::loadMapMeta() +{ + std::ifstream is(m_map_meta_path.c_str(), std::ios_base::binary); + + if (!is.good()) { + errorstream << "loadMapMeta: could not open " + << m_map_meta_path << std::endl; + return false; + } + + if (!m_map_settings->parseConfigLines(is)) { + errorstream << "loadMapMeta: Format error. '[end_of_params]' missing?" << std::endl; + return false; + } + + return true; +} + + +bool MapSettingsManager::saveMapMeta() +{ + // If mapgen params haven't been created yet; abort + if (!mapgen_params) { + infostream << "saveMapMeta: mapgen_params not present! " + << "Server startup was probably interrupted." << std::endl; + return false; + } + + // Paths set up by subgames.cpp, but not in unittests + if (!fs::CreateAllDirs(fs::RemoveLastPathComponent(m_map_meta_path))) { + errorstream << "saveMapMeta: could not create dirs to " + << m_map_meta_path; + return false; + } + + mapgen_params->MapgenParams::writeParams(m_map_settings); + mapgen_params->writeParams(m_map_settings); + + if (!m_map_settings->updateConfigFile(m_map_meta_path.c_str())) { + errorstream << "saveMapMeta: could not write " + << m_map_meta_path << std::endl; + return false; + } + + return true; +} + + +MapgenParams *MapSettingsManager::makeMapgenParams() +{ + if (mapgen_params) + return mapgen_params; + + assert(m_map_settings); + assert(m_defaults); + + // Now, get the mapgen type so we can create the appropriate MapgenParams + std::string mg_name; + MapgenType mgtype = getMapSetting("mg_name", &mg_name) ? + Mapgen::getMapgenType(mg_name) : MAPGEN_DEFAULT; + + if (mgtype == MAPGEN_INVALID) { + errorstream << "EmergeManager: mapgen '" << mg_name << + "' not valid; falling back to " << + Mapgen::getMapgenName(MAPGEN_DEFAULT) << std::endl; + mgtype = MAPGEN_DEFAULT; + } + + // Create our MapgenParams + MapgenParams *params = Mapgen::createMapgenParams(mgtype); + if (!params) + return nullptr; + + params->mgtype = mgtype; + + // Load the rest of the mapgen params from our active settings + params->MapgenParams::readParams(m_map_settings); + params->readParams(m_map_settings); + + // Hold onto our params + mapgen_params = params; + + return params; +} diff --git a/src/map_settings_manager.h b/src/map_settings_manager.h new file mode 100644 index 0000000..fa27126 --- /dev/null +++ b/src/map_settings_manager.h @@ -0,0 +1,77 @@ +/* +Minetest +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include "settings.h" + +struct NoiseParams; +struct MapgenParams; + +/* + MapSettingsManager is a centralized object for management (creating, + loading, storing, saving, etc.) of config settings related to the Map. + + It has two phases: the initial r/w "gather and modify settings" state, and + the final r/o "read and save settings" state. + + The typical use case is, in order, as follows: + - Create a MapSettingsManager object + - Try to load map metadata into it from the metadata file + - Manually view and modify the current configuration as desired through a + Settings-like interface + - When all modifications are finished, create a 'Parameters' object + containing the finalized, active parameters. This could be passed along + to whichever Map-related objects that may require it. + - Save these active settings to the metadata file when requested +*/ +class MapSettingsManager { +public: + MapSettingsManager(const std::string &map_meta_path); + ~MapSettingsManager(); + + // Finalized map generation parameters + MapgenParams *mapgen_params = nullptr; + + bool getMapSetting(const std::string &name, std::string *value_out); + + bool getMapSettingNoiseParams( + const std::string &name, NoiseParams *value_out); + + // Note: Map config becomes read-only after makeMapgenParams() gets called + // (i.e. mapgen_params is non-NULL). Attempts to set map config after + // params have been finalized will result in failure. + bool setMapSetting(const std::string &name, + const std::string &value, bool override_meta = false); + + bool setMapSettingNoiseParams(const std::string &name, + const NoiseParams *value, bool override_meta = false); + + bool loadMapMeta(); + bool saveMapMeta(); + MapgenParams *makeMapgenParams(); + +private: + std::string m_map_meta_path; + + SettingsHierarchy m_hierarchy; + Settings *m_defaults; + Settings *m_map_settings; +}; diff --git a/src/mapblock.cpp b/src/mapblock.cpp new file mode 100644 index 0000000..2bbc0eb --- /dev/null +++ b/src/mapblock.cpp @@ -0,0 +1,915 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mapblock.h" + +#include <sstream> +#include "map.h" +#include "light.h" +#include "nodedef.h" +#include "nodemetadata.h" +#include "gamedef.h" +#include "log.h" +#include "nameidmapping.h" +#include "content_mapnode.h" // For legacy name-id mapping +#include "content_nodemeta.h" // For legacy deserialization +#include "serialization.h" +#ifndef SERVER +#include "client/mapblock_mesh.h" +#endif +#include "porting.h" +#include "util/string.h" +#include "util/serialize.h" +#include "util/basic_macros.h" + +static const char *modified_reason_strings[] = { + "initial", + "reallocate", + "setIsUnderground", + "setLightingExpired", + "setGenerated", + "setNode", + "setNodeNoCheck", + "setTimestamp", + "NodeMetaRef::reportMetadataChange", + "clearAllObjects", + "Timestamp expired (step)", + "addActiveObjectRaw", + "removeRemovedObjects/remove", + "removeRemovedObjects/deactivate", + "Stored list cleared in activateObjects due to overflow", + "deactivateFarObjects: Static data moved in", + "deactivateFarObjects: Static data moved out", + "deactivateFarObjects: Static data changed considerably", + "finishBlockMake: expireDayNightDiff", + "unknown", +}; + + +/* + MapBlock +*/ + +MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy): + m_parent(parent), + m_pos(pos), + m_pos_relative(pos * MAP_BLOCKSIZE), + m_gamedef(gamedef) +{ + if (!dummy) + reallocate(); +} + +MapBlock::~MapBlock() +{ +#ifndef SERVER + { + delete mesh; + mesh = nullptr; + } +#endif + + delete[] data; +} + +bool MapBlock::isValidPositionParent(v3s16 p) +{ + if (isValidPosition(p)) { + return true; + } + + return m_parent->isValidPosition(getPosRelative() + p); +} + +MapNode MapBlock::getNodeParent(v3s16 p, bool *is_valid_position) +{ + if (!isValidPosition(p)) + return m_parent->getNode(getPosRelative() + p, is_valid_position); + + if (!data) { + if (is_valid_position) + *is_valid_position = false; + return {CONTENT_IGNORE}; + } + if (is_valid_position) + *is_valid_position = true; + return data[p.Z * zstride + p.Y * ystride + p.X]; +} + +std::string MapBlock::getModifiedReasonString() +{ + std::string reason; + + const u32 ubound = MYMIN(sizeof(m_modified_reason) * CHAR_BIT, + ARRLEN(modified_reason_strings)); + + for (u32 i = 0; i != ubound; i++) { + if ((m_modified_reason & (1 << i)) == 0) + continue; + + reason += modified_reason_strings[i]; + reason += ", "; + } + + if (reason.length() > 2) + reason.resize(reason.length() - 2); + + return reason; +} + + +void MapBlock::copyTo(VoxelManipulator &dst) +{ + v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE); + VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1)); + + // Copy from data to VoxelManipulator + dst.copyFrom(data, data_area, v3s16(0,0,0), + getPosRelative(), data_size); +} + +void MapBlock::copyFrom(VoxelManipulator &dst) +{ + v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE); + VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1)); + + // Copy from VoxelManipulator to data + dst.copyTo(data, data_area, v3s16(0,0,0), + getPosRelative(), data_size); +} + +void MapBlock::actuallyUpdateDayNightDiff() +{ + const NodeDefManager *nodemgr = m_gamedef->ndef(); + + // Running this function un-expires m_day_night_differs + m_day_night_differs_expired = false; + + if (!data) { + m_day_night_differs = false; + return; + } + + bool differs = false; + + /* + Check if any lighting value differs + */ + + MapNode previous_n(CONTENT_IGNORE); + for (u32 i = 0; i < nodecount; i++) { + MapNode n = data[i]; + + // If node is identical to previous node, don't verify if it differs + if (n == previous_n) + continue; + + differs = !n.isLightDayNightEq(nodemgr); + if (differs) + break; + previous_n = n; + } + + /* + If some lighting values differ, check if the whole thing is + just air. If it is just air, differs = false + */ + if (differs) { + bool only_air = true; + for (u32 i = 0; i < nodecount; i++) { + MapNode &n = data[i]; + if (n.getContent() != CONTENT_AIR) { + only_air = false; + break; + } + } + if (only_air) + differs = false; + } + + // Set member variable + m_day_night_differs = differs; +} + +void MapBlock::expireDayNightDiff() +{ + if (!data) { + m_day_night_differs = false; + m_day_night_differs_expired = false; + return; + } + + m_day_night_differs_expired = true; +} + +/* + Serialization +*/ + +// List relevant id-name pairs for ids in the block using nodedef +// Renumbers the content IDs (starting at 0 and incrementing) +static void getBlockNodeIdMapping(NameIdMapping *nimap, MapNode *nodes, + const NodeDefManager *nodedef) +{ + // The static memory requires about 65535 * sizeof(int) RAM in order to be + // sure we can handle all content ids. But it's absolutely worth it as it's + // a speedup of 4 for one of the major time consuming functions on storing + // mapblocks. + thread_local std::unique_ptr<content_t[]> mapping; + static_assert(sizeof(content_t) == 2, "content_t must be 16-bit"); + if (!mapping) + mapping = std::make_unique<content_t[]>(USHRT_MAX + 1); + + memset(mapping.get(), 0xFF, (USHRT_MAX + 1) * sizeof(content_t)); + + std::unordered_set<content_t> unknown_contents; + content_t id_counter = 0; + for (u32 i = 0; i < MapBlock::nodecount; i++) { + content_t global_id = nodes[i].getContent(); + content_t id = CONTENT_IGNORE; + + // Try to find an existing mapping + if (mapping[global_id] != 0xFFFF) { + id = mapping[global_id]; + } else { + // We have to assign a new mapping + id = id_counter++; + mapping[global_id] = id; + + const ContentFeatures &f = nodedef->get(global_id); + const std::string &name = f.name; + if (name.empty()) + unknown_contents.insert(global_id); + else + nimap->set(id, name); + } + + // Update the MapNode + nodes[i].setContent(id); + } + for (u16 unknown_content : unknown_contents) { + errorstream << "getBlockNodeIdMapping(): IGNORING ERROR: " + << "Name for node id " << unknown_content << " not known" << std::endl; + } +} + +// Correct ids in the block to match nodedef based on names. +// Unknown ones are added to nodedef. +// Will not update itself to match id-name pairs in nodedef. +static void correctBlockNodeIds(const NameIdMapping *nimap, MapNode *nodes, + IGameDef *gamedef) +{ + const NodeDefManager *nodedef = gamedef->ndef(); + // This means the block contains incorrect ids, and we contain + // the information to convert those to names. + // nodedef contains information to convert our names to globally + // correct ids. + std::unordered_set<content_t> unnamed_contents; + std::unordered_set<std::string> unallocatable_contents; + + bool previous_exists = false; + content_t previous_local_id = CONTENT_IGNORE; + content_t previous_global_id = CONTENT_IGNORE; + + for (u32 i = 0; i < MapBlock::nodecount; i++) { + content_t local_id = nodes[i].getContent(); + // If previous node local_id was found and same than before, don't lookup maps + // apply directly previous resolved id + // This permits to massively improve loading performance when nodes are similar + // example: default:air, default:stone are massively present + if (previous_exists && local_id == previous_local_id) { + nodes[i].setContent(previous_global_id); + continue; + } + + std::string name; + if (!nimap->getName(local_id, name)) { + unnamed_contents.insert(local_id); + previous_exists = false; + continue; + } + + content_t global_id; + if (!nodedef->getId(name, global_id)) { + global_id = gamedef->allocateUnknownNodeId(name); + if (global_id == CONTENT_IGNORE) { + unallocatable_contents.insert(name); + previous_exists = false; + continue; + } + } + nodes[i].setContent(global_id); + + // Save previous node local_id & global_id result + previous_local_id = local_id; + previous_global_id = global_id; + previous_exists = true; + } + + for (const content_t c: unnamed_contents) { + errorstream << "correctBlockNodeIds(): IGNORING ERROR: " + << "Block contains id " << c + << " with no name mapping" << std::endl; + } + for (const std::string &node_name: unallocatable_contents) { + errorstream << "correctBlockNodeIds(): IGNORING ERROR: " + << "Could not allocate global id for node name \"" + << node_name << "\"" << std::endl; + } +} + +void MapBlock::serialize(std::ostream &os_compressed, u8 version, bool disk, int compression_level) +{ + if(!ser_ver_supported(version)) + throw VersionMismatchException("ERROR: MapBlock format not supported"); + + if (!data) + throw SerializationError("ERROR: Not writing dummy block."); + + FATAL_ERROR_IF(version < SER_FMT_VER_LOWEST_WRITE, "Serialisation version error"); + + std::ostringstream os_raw(std::ios_base::binary); + std::ostream &os = version >= 29 ? os_raw : os_compressed; + + // First byte + u8 flags = 0; + if(is_underground) + flags |= 0x01; + if(getDayNightDiff()) + flags |= 0x02; + if (!m_generated) + flags |= 0x08; + writeU8(os, flags); + if (version >= 27) { + writeU16(os, m_lighting_complete); + } + + /* + Bulk node data + */ + NameIdMapping nimap; + SharedBuffer<u8> buf; + const u8 content_width = 2; + const u8 params_width = 2; + if(disk) + { + MapNode *tmp_nodes = new MapNode[nodecount]; + memcpy(tmp_nodes, data, nodecount * sizeof(MapNode)); + getBlockNodeIdMapping(&nimap, tmp_nodes, m_gamedef->ndef()); + + buf = MapNode::serializeBulk(version, tmp_nodes, nodecount, + content_width, params_width); + delete[] tmp_nodes; + + // write timestamp and node/id mapping first + if (version >= 29) { + writeU32(os, getTimestamp()); + + nimap.serialize(os); + } + } + else + { + buf = MapNode::serializeBulk(version, data, nodecount, + content_width, params_width); + } + + writeU8(os, content_width); + writeU8(os, params_width); + if (version >= 29) { + os.write(reinterpret_cast<char*>(*buf), buf.getSize()); + } else { + // prior to 29 node data was compressed individually + compress(buf, os, version, compression_level); + } + + /* + Node metadata + */ + if (version >= 29) { + m_node_metadata.serialize(os, version, disk); + } else { + // use os_raw from above to avoid allocating another stream object + m_node_metadata.serialize(os_raw, version, disk); + // prior to 29 node data was compressed individually + compress(os_raw.str(), os, version, compression_level); + } + + /* + Data that goes to disk, but not the network + */ + if(disk) + { + if(version <= 24){ + // Node timers + m_node_timers.serialize(os, version); + } + + // Static objects + m_static_objects.serialize(os); + + if(version < 29){ + // Timestamp + writeU32(os, getTimestamp()); + + // Write block-specific node definition id mapping + nimap.serialize(os); + } + + if(version >= 25){ + // Node timers + m_node_timers.serialize(os, version); + } + } + + if (version >= 29) { + // now compress the whole thing + compress(os_raw.str(), os_compressed, version, compression_level); + } +} + +void MapBlock::serializeNetworkSpecific(std::ostream &os) +{ + if (!data) { + throw SerializationError("ERROR: Not writing dummy block."); + } + + writeU8(os, 2); // version +} + +void MapBlock::deSerialize(std::istream &in_compressed, u8 version, bool disk) +{ + if(!ser_ver_supported(version)) + throw VersionMismatchException("ERROR: MapBlock format not supported"); + + TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())<<std::endl); + + m_day_night_differs_expired = false; + + if(version <= 21) + { + deSerialize_pre22(in_compressed, version, disk); + return; + } + + // Decompress the whole block (version >= 29) + std::stringstream in_raw(std::ios_base::binary | std::ios_base::in | std::ios_base::out); + if (version >= 29) + decompress(in_compressed, in_raw, version); + std::istream &is = version >= 29 ? in_raw : in_compressed; + + u8 flags = readU8(is); + is_underground = (flags & 0x01) != 0; + m_day_night_differs = (flags & 0x02) != 0; + if (version < 27) + m_lighting_complete = 0xFFFF; + else + m_lighting_complete = readU16(is); + m_generated = (flags & 0x08) == 0; + + NameIdMapping nimap; + if (disk && version >= 29) { + // Timestamp + TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos()) + <<": Timestamp"<<std::endl); + setTimestampNoChangedFlag(readU32(is)); + m_disk_timestamp = m_timestamp; + + // Node/id mapping + TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos()) + <<": NameIdMapping"<<std::endl); + nimap.deSerialize(is); + } + + TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos()) + <<": Bulk node data"<<std::endl); + u8 content_width = readU8(is); + u8 params_width = readU8(is); + if(content_width != 1 && content_width != 2) + throw SerializationError("MapBlock::deSerialize(): invalid content_width"); + if(params_width != 2) + throw SerializationError("MapBlock::deSerialize(): invalid params_width"); + + /* + Bulk node data + */ + if (version >= 29) { + MapNode::deSerializeBulk(is, version, data, nodecount, + content_width, params_width); + } else { + // use in_raw from above to avoid allocating another stream object + decompress(is, in_raw, version); + MapNode::deSerializeBulk(in_raw, version, data, nodecount, + content_width, params_width); + } + + /* + NodeMetadata + */ + TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos()) + <<": Node metadata"<<std::endl); + if (version >= 29) { + m_node_metadata.deSerialize(is, m_gamedef->idef()); + } else { + try { + // reuse in_raw + in_raw.str(""); + in_raw.clear(); + decompress(is, in_raw, version); + if (version >= 23) + m_node_metadata.deSerialize(in_raw, m_gamedef->idef()); + else + content_nodemeta_deserialize_legacy(in_raw, + &m_node_metadata, &m_node_timers, + m_gamedef->idef()); + } catch(SerializationError &e) { + warningstream<<"MapBlock::deSerialize(): Ignoring an error" + <<" while deserializing node metadata at (" + <<PP(getPos())<<": "<<e.what()<<std::endl; + } + } + + /* + Data that is only on disk + */ + if(disk) + { + // Node timers + if(version == 23){ + // Read unused zero + readU8(is); + } + if(version == 24){ + TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos()) + <<": Node timers (ver==24)"<<std::endl); + m_node_timers.deSerialize(is, version); + } + + // Static objects + TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos()) + <<": Static objects"<<std::endl); + m_static_objects.deSerialize(is); + + if(version < 29) { + // Timestamp + TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos()) + <<": Timestamp"<<std::endl); + setTimestampNoChangedFlag(readU32(is)); + m_disk_timestamp = m_timestamp; + + // Node/id mapping + TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos()) + <<": NameIdMapping"<<std::endl); + nimap.deSerialize(is); + } + + // Dynamically re-set ids based on node names + correctBlockNodeIds(&nimap, data, m_gamedef); + + if(version >= 25){ + TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos()) + <<": Node timers (ver>=25)"<<std::endl); + m_node_timers.deSerialize(is, version); + } + } + + TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos()) + <<": Done."<<std::endl); +} + +void MapBlock::deSerializeNetworkSpecific(std::istream &is) +{ + try { + readU8(is); + //const u8 version = readU8(is); + //if (version != 1) + //throw SerializationError("unsupported MapBlock version"); + + } catch(SerializationError &e) { + warningstream<<"MapBlock::deSerializeNetworkSpecific(): Ignoring an error" + <<": "<<e.what()<<std::endl; + } +} + +/* + Legacy serialization +*/ + +void MapBlock::deSerialize_pre22(std::istream &is, u8 version, bool disk) +{ + // Initialize default flags + is_underground = false; + m_day_night_differs = false; + m_lighting_complete = 0xFFFF; + m_generated = true; + + // Make a temporary buffer + u32 ser_length = MapNode::serializedLength(version); + SharedBuffer<u8> databuf_nodelist(nodecount * ser_length); + + // These have no compression + if (version <= 3 || version == 5 || version == 6) { + char tmp; + is.read(&tmp, 1); + if (is.gcount() != 1) + throw SerializationError(std::string(FUNCTION_NAME) + + ": not enough input data"); + is_underground = tmp; + is.read((char *)*databuf_nodelist, nodecount * ser_length); + if ((u32)is.gcount() != nodecount * ser_length) + throw SerializationError(std::string(FUNCTION_NAME) + + ": not enough input data"); + } else if (version <= 10) { + u8 t8; + is.read((char *)&t8, 1); + is_underground = t8; + + { + // Uncompress and set material data + std::ostringstream os(std::ios_base::binary); + decompress(is, os, version); + std::string s = os.str(); + if (s.size() != nodecount) + throw SerializationError(std::string(FUNCTION_NAME) + + ": not enough input data"); + for (u32 i = 0; i < s.size(); i++) { + databuf_nodelist[i*ser_length] = s[i]; + } + } + { + // Uncompress and set param data + std::ostringstream os(std::ios_base::binary); + decompress(is, os, version); + std::string s = os.str(); + if (s.size() != nodecount) + throw SerializationError(std::string(FUNCTION_NAME) + + ": not enough input data"); + for (u32 i = 0; i < s.size(); i++) { + databuf_nodelist[i*ser_length + 1] = s[i]; + } + } + + if (version >= 10) { + // Uncompress and set param2 data + std::ostringstream os(std::ios_base::binary); + decompress(is, os, version); + std::string s = os.str(); + if (s.size() != nodecount) + throw SerializationError(std::string(FUNCTION_NAME) + + ": not enough input data"); + for (u32 i = 0; i < s.size(); i++) { + databuf_nodelist[i*ser_length + 2] = s[i]; + } + } + } else { // All other versions (10 to 21) + u8 flags; + is.read((char*)&flags, 1); + is_underground = (flags & 0x01) != 0; + m_day_night_differs = (flags & 0x02) != 0; + if(version >= 18) + m_generated = (flags & 0x08) == 0; + + // Uncompress data + std::ostringstream os(std::ios_base::binary); + decompress(is, os, version); + std::string s = os.str(); + if (s.size() != nodecount * 3) + throw SerializationError(std::string(FUNCTION_NAME) + + ": decompress resulted in size other than nodecount*3"); + + // deserialize nodes from buffer + for (u32 i = 0; i < nodecount; i++) { + databuf_nodelist[i*ser_length] = s[i]; + databuf_nodelist[i*ser_length + 1] = s[i+nodecount]; + databuf_nodelist[i*ser_length + 2] = s[i+nodecount*2]; + } + + /* + NodeMetadata + */ + if (version >= 14) { + // Ignore errors + try { + if (version <= 15) { + std::string data = deSerializeString16(is); + std::istringstream iss(data, std::ios_base::binary); + content_nodemeta_deserialize_legacy(iss, + &m_node_metadata, &m_node_timers, + m_gamedef->idef()); + } else { + //std::string data = deSerializeString32(is); + std::ostringstream oss(std::ios_base::binary); + decompressZlib(is, oss); + std::istringstream iss(oss.str(), std::ios_base::binary); + content_nodemeta_deserialize_legacy(iss, + &m_node_metadata, &m_node_timers, + m_gamedef->idef()); + } + } catch(SerializationError &e) { + warningstream<<"MapBlock::deSerialize(): Ignoring an error" + <<" while deserializing node metadata"<<std::endl; + } + } + } + + // Deserialize node data + for (u32 i = 0; i < nodecount; i++) { + data[i].deSerialize(&databuf_nodelist[i * ser_length], version); + } + + if (disk) { + /* + Versions up from 9 have block objects. (DEPRECATED) + */ + if (version >= 9) { + u16 count = readU16(is); + // Not supported and length not known if count is not 0 + if(count != 0){ + warningstream<<"MapBlock::deSerialize_pre22(): " + <<"Ignoring stuff coming at and after MBOs"<<std::endl; + return; + } + } + + /* + Versions up from 15 have static objects. + */ + if (version >= 15) + m_static_objects.deSerialize(is); + + // Timestamp + if (version >= 17) { + setTimestampNoChangedFlag(readU32(is)); + m_disk_timestamp = m_timestamp; + } else { + setTimestampNoChangedFlag(BLOCK_TIMESTAMP_UNDEFINED); + } + + // Dynamically re-set ids based on node names + NameIdMapping nimap; + // If supported, read node definition id mapping + if (version >= 21) { + nimap.deSerialize(is); + // Else set the legacy mapping + } else { + content_mapnode_get_name_id_mapping(&nimap); + } + correctBlockNodeIds(&nimap, data, m_gamedef); + } + + + // Legacy data changes + // This code has to convert from pre-22 to post-22 format. + const NodeDefManager *nodedef = m_gamedef->ndef(); + for(u32 i=0; i<nodecount; i++) + { + const ContentFeatures &f = nodedef->get(data[i].getContent()); + // Mineral + if(nodedef->getId("default:stone") == data[i].getContent() + && data[i].getParam1() == 1) + { + data[i].setContent(nodedef->getId("default:stone_with_coal")); + data[i].setParam1(0); + } + else if(nodedef->getId("default:stone") == data[i].getContent() + && data[i].getParam1() == 2) + { + data[i].setContent(nodedef->getId("default:stone_with_iron")); + data[i].setParam1(0); + } + // facedir_simple + if(f.legacy_facedir_simple) + { + data[i].setParam2(data[i].getParam1()); + data[i].setParam1(0); + } + // wall_mounted + if(f.legacy_wallmounted) + { + u8 wallmounted_new_to_old[8] = {0x04, 0x08, 0x01, 0x02, 0x10, 0x20, 0, 0}; + u8 dir_old_format = data[i].getParam2(); + u8 dir_new_format = 0; + for(u8 j=0; j<8; j++) + { + if((dir_old_format & wallmounted_new_to_old[j]) != 0) + { + dir_new_format = j; + break; + } + } + data[i].setParam2(dir_new_format); + } + } + +} + +/* + Get a quick string to describe what a block actually contains +*/ +std::string analyze_block(MapBlock *block) +{ + if(block == NULL) + return "NULL"; + + std::ostringstream desc; + + v3s16 p = block->getPos(); + char spos[25]; + porting::mt_snprintf(spos, sizeof(spos), "(%2d,%2d,%2d), ", p.X, p.Y, p.Z); + desc<<spos; + + switch(block->getModified()) + { + case MOD_STATE_CLEAN: + desc<<"CLEAN, "; + break; + case MOD_STATE_WRITE_AT_UNLOAD: + desc<<"WRITE_AT_UNLOAD, "; + break; + case MOD_STATE_WRITE_NEEDED: + desc<<"WRITE_NEEDED, "; + break; + default: + desc<<"unknown getModified()="+itos(block->getModified())+", "; + } + + if(block->isGenerated()) + desc<<"is_gen [X], "; + else + desc<<"is_gen [ ], "; + + if(block->getIsUnderground()) + desc<<"is_ug [X], "; + else + desc<<"is_ug [ ], "; + + desc<<"lighting_complete: "<<block->getLightingComplete()<<", "; + + if(block->isDummy()) + { + desc<<"Dummy, "; + } + else + { + bool full_ignore = true; + bool some_ignore = false; + bool full_air = true; + bool some_air = false; + for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++) + for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++) + for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++) + { + v3s16 p(x0,y0,z0); + MapNode n = block->getNodeNoEx(p); + content_t c = n.getContent(); + if(c == CONTENT_IGNORE) + some_ignore = true; + else + full_ignore = false; + if(c == CONTENT_AIR) + some_air = true; + else + full_air = false; + } + + desc<<"content {"; + + std::ostringstream ss; + + if(full_ignore) + ss<<"IGNORE (full), "; + else if(some_ignore) + ss<<"IGNORE, "; + + if(full_air) + ss<<"AIR (full), "; + else if(some_air) + ss<<"AIR, "; + + if(ss.str().size()>=2) + desc<<ss.str().substr(0, ss.str().size()-2); + + desc<<"}, "; + } + + return desc.str().substr(0, desc.str().size()-2); +} + + +//END diff --git a/src/mapblock.h b/src/mapblock.h new file mode 100644 index 0000000..a86db7b --- /dev/null +++ b/src/mapblock.h @@ -0,0 +1,640 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <set> +#include "irr_v3d.h" +#include "mapnode.h" +#include "exceptions.h" +#include "constants.h" +#include "staticobject.h" +#include "nodemetadata.h" +#include "nodetimer.h" +#include "modifiedstate.h" +#include "util/numeric.h" // getContainerPos +#include "settings.h" +#include "mapgen/mapgen.h" + +class Map; +class NodeMetadataList; +class IGameDef; +class MapBlockMesh; +class VoxelManipulator; + +#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff + +//// +//// MapBlock modified reason flags +//// + +#define MOD_REASON_INITIAL (1 << 0) +#define MOD_REASON_REALLOCATE (1 << 1) +#define MOD_REASON_SET_IS_UNDERGROUND (1 << 2) +#define MOD_REASON_SET_LIGHTING_COMPLETE (1 << 3) +#define MOD_REASON_SET_GENERATED (1 << 4) +#define MOD_REASON_SET_NODE (1 << 5) +#define MOD_REASON_SET_NODE_NO_CHECK (1 << 6) +#define MOD_REASON_SET_TIMESTAMP (1 << 7) +#define MOD_REASON_REPORT_META_CHANGE (1 << 8) +#define MOD_REASON_CLEAR_ALL_OBJECTS (1 << 9) +#define MOD_REASON_BLOCK_EXPIRED (1 << 10) +#define MOD_REASON_ADD_ACTIVE_OBJECT_RAW (1 << 11) +#define MOD_REASON_REMOVE_OBJECTS_REMOVE (1 << 12) +#define MOD_REASON_REMOVE_OBJECTS_DEACTIVATE (1 << 13) +#define MOD_REASON_TOO_MANY_OBJECTS (1 << 14) +#define MOD_REASON_STATIC_DATA_ADDED (1 << 15) +#define MOD_REASON_STATIC_DATA_REMOVED (1 << 16) +#define MOD_REASON_STATIC_DATA_CHANGED (1 << 17) +#define MOD_REASON_EXPIRE_DAYNIGHTDIFF (1 << 18) +#define MOD_REASON_VMANIP (1 << 19) +#define MOD_REASON_UNKNOWN (1 << 20) + +//// +//// MapBlock itself +//// + +class MapBlock +{ +public: + MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy=false); + ~MapBlock(); + + /*virtual u16 nodeContainerId() const + { + return NODECONTAINER_ID_MAPBLOCK; + }*/ + + Map * getParent() + { + return m_parent; + } + + void reallocate() + { + delete[] data; + data = new MapNode[nodecount]; + for (u32 i = 0; i < nodecount; i++) + data[i] = MapNode(CONTENT_IGNORE); + + raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_REALLOCATE); + } + + MapNode* getData() + { + return data; + } + + //// + //// Modification tracking methods + //// + void raiseModified(u32 mod, u32 reason=MOD_REASON_UNKNOWN) + { + if (mod > m_modified) { + m_modified = mod; + m_modified_reason = reason; + if (m_modified >= MOD_STATE_WRITE_AT_UNLOAD) + m_disk_timestamp = m_timestamp; + } else if (mod == m_modified) { + m_modified_reason |= reason; + } + if (mod == MOD_STATE_WRITE_NEEDED) + contents_cached = false; + } + + inline u32 getModified() + { + return m_modified; + } + + inline u32 getModifiedReason() + { + return m_modified_reason; + } + + std::string getModifiedReasonString(); + + inline void resetModified() + { + m_modified = MOD_STATE_CLEAN; + m_modified_reason = 0; + } + + //// + //// Flags + //// + + inline bool isDummy() const + { + return !data; + } + + inline void unDummify() + { + assert(isDummy()); // Pre-condition + reallocate(); + } + + // is_underground getter/setter + inline bool getIsUnderground() + { + return is_underground; + } + + inline void setIsUnderground(bool a_is_underground) + { + is_underground = a_is_underground; + raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_IS_UNDERGROUND); + } + + inline void setLightingComplete(u16 newflags) + { + if (newflags != m_lighting_complete) { + m_lighting_complete = newflags; + raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_LIGHTING_COMPLETE); + } + } + + inline u16 getLightingComplete() + { + return m_lighting_complete; + } + + inline void setLightingComplete(LightBank bank, u8 direction, + bool is_complete) + { + assert(direction >= 0 && direction <= 5); + if (bank == LIGHTBANK_NIGHT) { + direction += 6; + } + u16 newflags = m_lighting_complete; + if (is_complete) { + newflags |= 1 << direction; + } else { + newflags &= ~(1 << direction); + } + setLightingComplete(newflags); + } + + inline bool isLightingComplete(LightBank bank, u8 direction) + { + assert(direction >= 0 && direction <= 5); + if (bank == LIGHTBANK_NIGHT) { + direction += 6; + } + return (m_lighting_complete & (1 << direction)) != 0; + } + + inline bool isGenerated() + { + return m_generated; + } + + inline void setGenerated(bool b) + { + if (b != m_generated) { + raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_GENERATED); + m_generated = b; + } + } + + //// + //// Position stuff + //// + + inline v3s16 getPos() + { + return m_pos; + } + + inline v3s16 getPosRelative() + { + return m_pos_relative; + } + + inline core::aabbox3d<s16> getBox() + { + return core::aabbox3d<s16>(getPosRelative(), + getPosRelative() + + v3s16(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE) + - v3s16(1,1,1)); + } + + //// + //// Regular MapNode get-setters + //// + + inline bool isValidPosition(s16 x, s16 y, s16 z) + { + return data + && x >= 0 && x < MAP_BLOCKSIZE + && y >= 0 && y < MAP_BLOCKSIZE + && z >= 0 && z < MAP_BLOCKSIZE; + } + + inline bool isValidPosition(v3s16 p) + { + return isValidPosition(p.X, p.Y, p.Z); + } + + inline MapNode getNode(s16 x, s16 y, s16 z, bool *valid_position) + { + *valid_position = isValidPosition(x, y, z); + + if (!*valid_position) + return {CONTENT_IGNORE}; + + return data[z * zstride + y * ystride + x]; + } + + inline MapNode getNode(v3s16 p, bool *valid_position) + { + return getNode(p.X, p.Y, p.Z, valid_position); + } + + inline MapNode getNodeNoEx(v3s16 p) + { + bool is_valid; + return getNode(p.X, p.Y, p.Z, &is_valid); + } + + inline void setNode(s16 x, s16 y, s16 z, MapNode & n) + { + if (!isValidPosition(x, y, z)) + throw InvalidPositionException(); + + data[z * zstride + y * ystride + x] = n; + raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_NODE); + } + + inline void setNode(v3s16 p, MapNode & n) + { + setNode(p.X, p.Y, p.Z, n); + } + + //// + //// Non-checking variants of the above + //// + + inline MapNode getNodeNoCheck(s16 x, s16 y, s16 z, bool *valid_position) + { + *valid_position = data != nullptr; + if (!*valid_position) + return {CONTENT_IGNORE}; + + return data[z * zstride + y * ystride + x]; + } + + inline MapNode getNodeNoCheck(v3s16 p, bool *valid_position) + { + return getNodeNoCheck(p.X, p.Y, p.Z, valid_position); + } + + //// + //// Non-checking, unsafe variants of the above + //// MapBlock must be loaded by another function in the same scope/function + //// Caller must ensure that this is not a dummy block (by calling isDummy()) + //// + + inline const MapNode &getNodeUnsafe(s16 x, s16 y, s16 z) + { + return data[z * zstride + y * ystride + x]; + } + + inline const MapNode &getNodeUnsafe(v3s16 &p) + { + return getNodeUnsafe(p.X, p.Y, p.Z); + } + + inline void setNodeNoCheck(s16 x, s16 y, s16 z, MapNode & n) + { + if (!data) + throw InvalidPositionException(); + + data[z * zstride + y * ystride + x] = n; + raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_NODE_NO_CHECK); + } + + inline void setNodeNoCheck(v3s16 p, MapNode & n) + { + setNodeNoCheck(p.X, p.Y, p.Z, n); + } + + // These functions consult the parent container if the position + // is not valid on this MapBlock. + bool isValidPositionParent(v3s16 p); + MapNode getNodeParent(v3s16 p, bool *is_valid_position = NULL); + + // Copies data to VoxelManipulator to getPosRelative() + void copyTo(VoxelManipulator &dst); + + // Copies data from VoxelManipulator getPosRelative() + void copyFrom(VoxelManipulator &dst); + + // Update day-night lighting difference flag. + // Sets m_day_night_differs to appropriate value. + // These methods don't care about neighboring blocks. + void actuallyUpdateDayNightDiff(); + + // Call this to schedule what the previous function does to be done + // when the value is actually needed. + void expireDayNightDiff(); + + inline bool getDayNightDiff() + { + if (m_day_night_differs_expired) + actuallyUpdateDayNightDiff(); + return m_day_night_differs; + } + + //// + //// Timestamp (see m_timestamp) + //// + + // NOTE: BLOCK_TIMESTAMP_UNDEFINED=0xffffffff means there is no timestamp. + + inline void setTimestamp(u32 time) + { + m_timestamp = time; + raiseModified(MOD_STATE_WRITE_AT_UNLOAD, MOD_REASON_SET_TIMESTAMP); + } + + inline void setTimestampNoChangedFlag(u32 time) + { + m_timestamp = time; + } + + inline u32 getTimestamp() + { + return m_timestamp; + } + + inline u32 getDiskTimestamp() + { + return m_disk_timestamp; + } + + //// + //// Usage timer (see m_usage_timer) + //// + + inline void resetUsageTimer() + { + m_usage_timer = 0; + } + + inline void incrementUsageTimer(float dtime) + { + m_usage_timer += dtime; + } + + inline float getUsageTimer() + { + return m_usage_timer; + } + + //// + //// Reference counting (see m_refcount) + //// + + inline void refGrab() + { + m_refcount++; + } + + inline void refDrop() + { + m_refcount--; + } + + inline int refGet() + { + return m_refcount; + } + + //// + //// Node Timers + //// + + inline NodeTimer getNodeTimer(const v3s16 &p) + { + return m_node_timers.get(p); + } + + inline void removeNodeTimer(const v3s16 &p) + { + m_node_timers.remove(p); + } + + inline void setNodeTimer(const NodeTimer &t) + { + m_node_timers.set(t); + } + + inline void clearNodeTimers() + { + m_node_timers.clear(); + } + + //// + //// Serialization + /// + + // These don't write or read version by itself + // Set disk to true for on-disk format, false for over-the-network format + // Precondition: version >= SER_FMT_VER_LOWEST_WRITE + void serialize(std::ostream &result, u8 version, bool disk, int compression_level); + // If disk == true: In addition to doing other things, will add + // unknown blocks from id-name mapping to wndef + void deSerialize(std::istream &is, u8 version, bool disk); + + void serializeNetworkSpecific(std::ostream &os); + void deSerializeNetworkSpecific(std::istream &is); +private: + /* + Private methods + */ + + void deSerialize_pre22(std::istream &is, u8 version, bool disk); + + /* + Used only internally, because changes can't be tracked + */ + + inline MapNode &getNodeRef(s16 x, s16 y, s16 z) + { + if (!isValidPosition(x, y, z)) + throw InvalidPositionException(); + + return data[z * zstride + y * ystride + x]; + } + + inline MapNode &getNodeRef(v3s16 &p) + { + return getNodeRef(p.X, p.Y, p.Z); + } + +public: + /* + Public member variables + */ + +#ifndef SERVER // Only on client + MapBlockMesh *mesh = nullptr; +#endif + + NodeMetadataList m_node_metadata; + NodeTimerList m_node_timers; + StaticObjectList m_static_objects; + + static const u32 ystride = MAP_BLOCKSIZE; + static const u32 zstride = MAP_BLOCKSIZE * MAP_BLOCKSIZE; + + static const u32 nodecount = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE; + + //// ABM optimizations //// + // Cache of content types + std::unordered_set<content_t> contents; + // True if content types are cached + bool contents_cached = false; + // True if we never want to cache content types for this block + bool do_not_cache_contents = false; + +private: + /* + Private member variables + */ + + // NOTE: Lots of things rely on this being the Map + Map *m_parent; + // Position in blocks on parent + v3s16 m_pos; + + /* This is the precalculated m_pos_relative value + * This caches the value, improving performance by removing 3 s16 multiplications + * at runtime on each getPosRelative call + * For a 5 minutes runtime with valgrind this removes 3 * 19M s16 multiplications + * The gain can be estimated in Release Build to 3 * 100M multiply operations for 5 mins + */ + v3s16 m_pos_relative; + + IGameDef *m_gamedef; + + /* + If NULL, block is a dummy block. + Dummy blocks are used for caching not-found-on-disk blocks. + */ + MapNode *data = nullptr; + + /* + - On the server, this is used for telling whether the + block has been modified from the one on disk. + - On the client, this is used for nothing. + */ + u32 m_modified = MOD_STATE_WRITE_NEEDED; + u32 m_modified_reason = MOD_REASON_INITIAL; + + /* + When propagating sunlight and the above block doesn't exist, + sunlight is assumed if this is false. + + In practice this is set to true if the block is completely + undeground with nothing visible above the ground except + caves. + */ + bool is_underground = false; + + /*! + * Each bit indicates if light spreading was finished + * in a direction. (Because the neighbor could also be unloaded.) + * Bits (most significant first): + * nothing, nothing, nothing, nothing, + * night X-, night Y-, night Z-, night Z+, night Y+, night X+, + * day X-, day Y-, day Z-, day Z+, day Y+, day X+. + */ + u16 m_lighting_complete = 0xFFFF; + + // Whether day and night lighting differs + bool m_day_night_differs = false; + bool m_day_night_differs_expired = true; + + bool m_generated = false; + + /* + When block is removed from active blocks, this is set to gametime. + Value BLOCK_TIMESTAMP_UNDEFINED=0xffffffff means there is no timestamp. + */ + u32 m_timestamp = BLOCK_TIMESTAMP_UNDEFINED; + // The on-disk (or to-be on-disk) timestamp value + u32 m_disk_timestamp = BLOCK_TIMESTAMP_UNDEFINED; + + /* + When the block is accessed, this is set to 0. + Map will unload the block when this reaches a timeout. + */ + float m_usage_timer = 0; + + /* + Reference count; currently used for determining if this block is in + the list of blocks to be drawn. + */ + int m_refcount = 0; +}; + +typedef std::vector<MapBlock*> MapBlockVect; + +inline bool objectpos_over_limit(v3f p) +{ + const float max_limit_bs = (MAX_MAP_GENERATION_LIMIT + 0.5f) * BS; + return p.X < -max_limit_bs || + p.X > max_limit_bs || + p.Y < -max_limit_bs || + p.Y > max_limit_bs || + p.Z < -max_limit_bs || + p.Z > max_limit_bs; +} + +inline bool blockpos_over_max_limit(v3s16 p) +{ + const s16 max_limit_bp = MAX_MAP_GENERATION_LIMIT / MAP_BLOCKSIZE; + return p.X < -max_limit_bp || + p.X > max_limit_bp || + p.Y < -max_limit_bp || + p.Y > max_limit_bp || + p.Z < -max_limit_bp || + p.Z > max_limit_bp; +} + +/* + Returns the position of the block where the node is located +*/ +inline v3s16 getNodeBlockPos(const v3s16 &p) +{ + return getContainerPos(p, MAP_BLOCKSIZE); +} + +inline void getNodeBlockPosWithOffset(const v3s16 &p, v3s16 &block, v3s16 &offset) +{ + getContainerPosWithOffset(p, MAP_BLOCKSIZE, block, offset); +} + +/* + Get a quick string to describe what a block actually contains +*/ +std::string analyze_block(MapBlock *block); diff --git a/src/mapgen/CMakeLists.txt b/src/mapgen/CMakeLists.txt new file mode 100644 index 0000000..e74bd85 --- /dev/null +++ b/src/mapgen/CMakeLists.txt @@ -0,0 +1,19 @@ +set(mapgen_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/cavegen.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/dungeongen.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mapgen_carpathian.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mapgen.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mapgen_flat.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mapgen_fractal.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mapgen_singlenode.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mapgen_v5.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mapgen_v6.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mapgen_v7.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mapgen_valleys.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mg_biome.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mg_decoration.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mg_ore.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mg_schematic.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/treegen.cpp + PARENT_SCOPE +) diff --git a/src/mapgen/cavegen.cpp b/src/mapgen/cavegen.cpp new file mode 100644 index 0000000..3400798 --- /dev/null +++ b/src/mapgen/cavegen.cpp @@ -0,0 +1,915 @@ +/* +Minetest +Copyright (C) 2010-2020 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2015-2020 paramat +Copyright (C) 2010-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "util/numeric.h" +#include <cmath> +#include "map.h" +#include "mapgen.h" +#include "mapgen_v5.h" +#include "mapgen_v6.h" +#include "mapgen_v7.h" +#include "mg_biome.h" +#include "cavegen.h" + +// TODO Remove this. Cave liquids are now defined and located using biome definitions +static NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0); + + +//// +//// CavesNoiseIntersection +//// + +CavesNoiseIntersection::CavesNoiseIntersection( + const NodeDefManager *nodedef, BiomeManager *biomemgr, v3s16 chunksize, + NoiseParams *np_cave1, NoiseParams *np_cave2, s32 seed, float cave_width) +{ + assert(nodedef); + assert(biomemgr); + + m_ndef = nodedef; + m_bmgr = biomemgr; + + m_csize = chunksize; + m_cave_width = cave_width; + + m_ystride = m_csize.X; + m_zstride_1d = m_csize.X * (m_csize.Y + 1); + + // Noises are created using 1-down overgeneration + // A Nx-by-1-by-Nz-sized plane is at the bottom of the desired for + // re-carving the solid overtop placed for blocking sunlight + noise_cave1 = new Noise(np_cave1, seed, m_csize.X, m_csize.Y + 1, m_csize.Z); + noise_cave2 = new Noise(np_cave2, seed, m_csize.X, m_csize.Y + 1, m_csize.Z); +} + + +CavesNoiseIntersection::~CavesNoiseIntersection() +{ + delete noise_cave1; + delete noise_cave2; +} + + +void CavesNoiseIntersection::generateCaves(MMVManip *vm, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) +{ + assert(vm); + assert(biomemap); + + noise_cave1->perlinMap3D(nmin.X, nmin.Y - 1, nmin.Z); + noise_cave2->perlinMap3D(nmin.X, nmin.Y - 1, nmin.Z); + + const v3s16 &em = vm->m_area.getExtent(); + u32 index2d = 0; // Biomemap index + + for (s16 z = nmin.Z; z <= nmax.Z; z++) + for (s16 x = nmin.X; x <= nmax.X; x++, index2d++) { + bool column_is_open = false; // Is column open to overground + bool is_under_river = false; // Is column under river water + bool is_under_tunnel = false; // Is tunnel or is under tunnel + bool is_top_filler_above = false; // Is top or filler above node + // Indexes at column top + u32 vi = vm->m_area.index(x, nmax.Y, z); + u32 index3d = (z - nmin.Z) * m_zstride_1d + m_csize.Y * m_ystride + + (x - nmin.X); // 3D noise index + // Biome of column + Biome *biome = (Biome *)m_bmgr->getRaw(biomemap[index2d]); + u16 depth_top = biome->depth_top; + u16 base_filler = depth_top + biome->depth_filler; + u16 depth_riverbed = biome->depth_riverbed; + u16 nplaced = 0; + // Don't excavate the overgenerated stone at nmax.Y + 1, + // this creates a 'roof' over the tunnel, preventing light in + // tunnels at mapchunk borders when generating mapchunks upwards. + // This 'roof' is removed when the mapchunk above is generated. + for (s16 y = nmax.Y; y >= nmin.Y - 1; y--, + index3d -= m_ystride, + VoxelArea::add_y(em, vi, -1)) { + content_t c = vm->m_data[vi].getContent(); + + if (c == CONTENT_AIR || c == biome->c_water_top || + c == biome->c_water) { + column_is_open = true; + is_top_filler_above = false; + continue; + } + + if (c == biome->c_river_water) { + column_is_open = true; + is_under_river = true; + is_top_filler_above = false; + continue; + } + + // Ground + float d1 = contour(noise_cave1->result[index3d]); + float d2 = contour(noise_cave2->result[index3d]); + + if (d1 * d2 > m_cave_width && m_ndef->get(c).is_ground_content) { + // In tunnel and ground content, excavate + vm->m_data[vi] = MapNode(CONTENT_AIR); + is_under_tunnel = true; + // If tunnel roof is top or filler, replace with stone + if (is_top_filler_above) + vm->m_data[vi + em.X] = MapNode(biome->c_stone); + is_top_filler_above = false; + } else if (column_is_open && is_under_tunnel && + (c == biome->c_stone || c == biome->c_filler)) { + // Tunnel entrance floor, place biome surface nodes + if (is_under_river) { + if (nplaced < depth_riverbed) { + vm->m_data[vi] = MapNode(biome->c_riverbed); + is_top_filler_above = true; + nplaced++; + } else { + // Disable top/filler placement + column_is_open = false; + is_under_river = false; + is_under_tunnel = false; + } + } else if (nplaced < depth_top) { + vm->m_data[vi] = MapNode(biome->c_top); + is_top_filler_above = true; + nplaced++; + } else if (nplaced < base_filler) { + vm->m_data[vi] = MapNode(biome->c_filler); + is_top_filler_above = true; + nplaced++; + } else { + // Disable top/filler placement + column_is_open = false; + is_under_tunnel = false; + } + } else { + // Not tunnel or tunnel entrance floor + // Check node for possible replacing with stone for tunnel roof + if (c == biome->c_top || c == biome->c_filler) + is_top_filler_above = true; + + column_is_open = false; + } + } + } +} + + +//// +//// CavernsNoise +//// + +CavernsNoise::CavernsNoise( + const NodeDefManager *nodedef, v3s16 chunksize, NoiseParams *np_cavern, + s32 seed, float cavern_limit, float cavern_taper, float cavern_threshold) +{ + assert(nodedef); + + m_ndef = nodedef; + + m_csize = chunksize; + m_cavern_limit = cavern_limit; + m_cavern_taper = cavern_taper; + m_cavern_threshold = cavern_threshold; + + m_ystride = m_csize.X; + m_zstride_1d = m_csize.X * (m_csize.Y + 1); + + // Noise is created using 1-down overgeneration + // A Nx-by-1-by-Nz-sized plane is at the bottom of the desired for + // re-carving the solid overtop placed for blocking sunlight + noise_cavern = new Noise(np_cavern, seed, m_csize.X, m_csize.Y + 1, m_csize.Z); + + c_water_source = m_ndef->getId("mapgen_water_source"); + if (c_water_source == CONTENT_IGNORE) + c_water_source = CONTENT_AIR; + + c_lava_source = m_ndef->getId("mapgen_lava_source"); + if (c_lava_source == CONTENT_IGNORE) + c_lava_source = CONTENT_AIR; +} + + +CavernsNoise::~CavernsNoise() +{ + delete noise_cavern; +} + + +bool CavernsNoise::generateCaverns(MMVManip *vm, v3s16 nmin, v3s16 nmax) +{ + assert(vm); + + // Calculate noise + noise_cavern->perlinMap3D(nmin.X, nmin.Y - 1, nmin.Z); + + // Cache cavern_amp values + float *cavern_amp = new float[m_csize.Y + 1]; + u8 cavern_amp_index = 0; // Index zero at column top + for (s16 y = nmax.Y; y >= nmin.Y - 1; y--, cavern_amp_index++) { + cavern_amp[cavern_amp_index] = + MYMIN((m_cavern_limit - y) / (float)m_cavern_taper, 1.0f); + } + + //// Place nodes + bool near_cavern = false; + const v3s16 &em = vm->m_area.getExtent(); + u32 index2d = 0; + + for (s16 z = nmin.Z; z <= nmax.Z; z++) + for (s16 x = nmin.X; x <= nmax.X; x++, index2d++) { + // Reset cave_amp index to column top + cavern_amp_index = 0; + // Initial voxelmanip index at column top + u32 vi = vm->m_area.index(x, nmax.Y, z); + // Initial 3D noise index at column top + u32 index3d = (z - nmin.Z) * m_zstride_1d + m_csize.Y * m_ystride + + (x - nmin.X); + // Don't excavate the overgenerated stone at node_max.Y + 1, + // this creates a 'roof' over the cavern, preventing light in + // caverns at mapchunk borders when generating mapchunks upwards. + // This 'roof' is excavated when the mapchunk above is generated. + for (s16 y = nmax.Y; y >= nmin.Y - 1; y--, + index3d -= m_ystride, + VoxelArea::add_y(em, vi, -1), + cavern_amp_index++) { + content_t c = vm->m_data[vi].getContent(); + float n_absamp_cavern = std::fabs(noise_cavern->result[index3d]) * + cavern_amp[cavern_amp_index]; + // Disable CavesRandomWalk at a safe distance from caverns + // to avoid excessively spreading liquids in caverns. + if (n_absamp_cavern > m_cavern_threshold - 0.1f) { + near_cavern = true; + if (n_absamp_cavern > m_cavern_threshold && + m_ndef->get(c).is_ground_content) + vm->m_data[vi] = MapNode(CONTENT_AIR); + } + } + } + + delete[] cavern_amp; + + return near_cavern; +} + + +//// +//// CavesRandomWalk +//// + +CavesRandomWalk::CavesRandomWalk( + const NodeDefManager *ndef, + GenerateNotifier *gennotify, + s32 seed, + int water_level, + content_t water_source, + content_t lava_source, + float large_cave_flooded, + BiomeGen *biomegen) +{ + assert(ndef); + + this->ndef = ndef; + this->gennotify = gennotify; + this->seed = seed; + this->water_level = water_level; + this->np_caveliquids = &nparams_caveliquids; + this->large_cave_flooded = large_cave_flooded; + this->bmgn = biomegen; + + c_water_source = water_source; + if (c_water_source == CONTENT_IGNORE) + c_water_source = ndef->getId("mapgen_water_source"); + if (c_water_source == CONTENT_IGNORE) + c_water_source = CONTENT_AIR; + + c_lava_source = lava_source; + if (c_lava_source == CONTENT_IGNORE) + c_lava_source = ndef->getId("mapgen_lava_source"); + if (c_lava_source == CONTENT_IGNORE) + c_lava_source = CONTENT_AIR; +} + + +void CavesRandomWalk::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, + PseudoRandom *ps, bool is_large_cave, int max_stone_height, s16 *heightmap) +{ + assert(vm); + assert(ps); + + this->vm = vm; + this->ps = ps; + this->node_min = nmin; + this->node_max = nmax; + this->heightmap = heightmap; + this->large_cave = is_large_cave; + + this->ystride = nmax.X - nmin.X + 1; + + flooded = ps->range(1, 1000) <= large_cave_flooded * 1000.0f; + + // If flooded: + // Get biome at mapchunk midpoint. If cave liquid defined for biome, use it. + // If defined liquid is "air", disable 'flooded' to avoid placing "air". + use_biome_liquid = false; + if (flooded && bmgn) { + v3s16 midp = node_min + (node_max - node_min) / v3s16(2, 2, 2); + Biome *biome = (Biome *)bmgn->getBiomeAtPoint(midp); + if (biome->c_cave_liquid[0] != CONTENT_IGNORE) { + use_biome_liquid = true; + c_biome_liquid = + biome->c_cave_liquid[ps->range(0, biome->c_cave_liquid.size() - 1)]; + if (c_biome_liquid == CONTENT_AIR) + flooded = false; + } + } + + // Set initial parameters from randomness + int dswitchint = ps->range(1, 14); + + if (large_cave) { + part_max_length_rs = ps->range(2, 4); + tunnel_routepoints = ps->range(5, ps->range(15, 30)); + min_tunnel_diameter = 5; + max_tunnel_diameter = ps->range(7, ps->range(8, 24)); + } else { + part_max_length_rs = ps->range(2, 9); + tunnel_routepoints = ps->range(10, ps->range(15, 30)); + min_tunnel_diameter = 2; + max_tunnel_diameter = ps->range(2, 6); + } + + large_cave_is_flat = (ps->range(0, 1) == 0); + + main_direction = v3f(0, 0, 0); + + // Allowed route area size in nodes + ar = node_max - node_min + v3s16(1, 1, 1); + // Area starting point in nodes + of = node_min; + + // Allow caves to extend up to 16 nodes beyond the mapchunk edge, to allow + // connecting with caves of neighbor mapchunks. + // 'insure' is needed to avoid many 'out of voxelmanip' cave nodes. + const s16 insure = 2; + s16 more = MYMAX(MAP_BLOCKSIZE - max_tunnel_diameter / 2 - insure, 1); + ar += v3s16(1, 1, 1) * more * 2; + of -= v3s16(1, 1, 1) * more; + + route_y_min = 0; + // Allow half a diameter + 7 over stone surface + route_y_max = -of.Y + max_stone_height + max_tunnel_diameter / 2 + 7; + + // Limit maximum to area + route_y_max = rangelim(route_y_max, 0, ar.Y - 1); + + if (large_cave) { + s16 minpos = 0; + if (node_min.Y < water_level && node_max.Y > water_level) { + minpos = water_level - max_tunnel_diameter / 3 - of.Y; + route_y_max = water_level + max_tunnel_diameter / 3 - of.Y; + } + route_y_min = ps->range(minpos, minpos + max_tunnel_diameter); + route_y_min = rangelim(route_y_min, 0, route_y_max); + } + + s16 route_start_y_min = route_y_min; + s16 route_start_y_max = route_y_max; + + route_start_y_min = rangelim(route_start_y_min, 0, ar.Y - 1); + route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y - 1); + + // Randomize starting position + orp.Z = (float)(ps->next() % ar.Z) + 0.5f; + orp.Y = (float)(ps->range(route_start_y_min, route_start_y_max)) + 0.5f; + orp.X = (float)(ps->next() % ar.X) + 0.5f; + + // Add generation notify begin event + if (gennotify) { + v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); + GenNotifyType notifytype = large_cave ? + GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN; + gennotify->addEvent(notifytype, abs_pos); + } + + // Generate some tunnel starting from orp + for (u16 j = 0; j < tunnel_routepoints; j++) + makeTunnel(j % dswitchint == 0); + + // Add generation notify end event + if (gennotify) { + v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); + GenNotifyType notifytype = large_cave ? + GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END; + gennotify->addEvent(notifytype, abs_pos); + } +} + + +void CavesRandomWalk::makeTunnel(bool dirswitch) +{ + if (dirswitch && !large_cave) { + main_direction.Z = ((float)(ps->next() % 20) - (float)10) / 10; + main_direction.Y = ((float)(ps->next() % 20) - (float)10) / 30; + main_direction.X = ((float)(ps->next() % 20) - (float)10) / 10; + + main_direction *= (float)ps->range(0, 10) / 10; + } + + // Randomize size + s16 min_d = min_tunnel_diameter; + s16 max_d = max_tunnel_diameter; + rs = ps->range(min_d, max_d); + s16 rs_part_max_length_rs = rs * part_max_length_rs; + + v3s16 maxlen; + if (large_cave) { + maxlen = v3s16( + rs_part_max_length_rs, + rs_part_max_length_rs / 2, + rs_part_max_length_rs + ); + } else { + maxlen = v3s16( + rs_part_max_length_rs, + ps->range(1, rs_part_max_length_rs), + rs_part_max_length_rs + ); + } + + v3f vec; + // Jump downward sometimes + if (!large_cave && ps->range(0, 12) == 0) { + vec.Z = (float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2; + vec.Y = (float)(ps->next() % (maxlen.Y * 2)) - (float)maxlen.Y; + vec.X = (float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2; + } else { + vec.Z = (float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2; + vec.Y = (float)(ps->next() % (maxlen.Y * 1)) - (float)maxlen.Y / 2; + vec.X = (float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2; + } + + // Do not make caves that are above ground. + // It is only necessary to check the startpoint and endpoint. + v3s16 p1 = v3s16(orp.X, orp.Y, orp.Z) + of + rs / 2; + v3s16 p2 = v3s16(vec.X, vec.Y, vec.Z) + p1; + if (isPosAboveSurface(p1) || isPosAboveSurface(p2)) + return; + + vec += main_direction; + + v3f rp = orp + vec; + if (rp.X < 0) + rp.X = 0; + else if (rp.X >= ar.X) + rp.X = ar.X - 1; + + if (rp.Y < route_y_min) + rp.Y = route_y_min; + else if (rp.Y >= route_y_max) + rp.Y = route_y_max - 1; + + if (rp.Z < 0) + rp.Z = 0; + else if (rp.Z >= ar.Z) + rp.Z = ar.Z - 1; + + vec = rp - orp; + + float veclen = vec.getLength(); + if (veclen < 0.05f) + veclen = 1.0f; + + // Every second section is rough + bool randomize_xz = (ps->range(1, 2) == 1); + + // Carve routes + for (float f = 0.f; f < 1.0f; f += 1.0f / veclen) + carveRoute(vec, f, randomize_xz); + + orp = rp; +} + + +void CavesRandomWalk::carveRoute(v3f vec, float f, bool randomize_xz) +{ + MapNode airnode(CONTENT_AIR); + MapNode waternode(c_water_source); + MapNode lavanode(c_lava_source); + + v3s16 startp(orp.X, orp.Y, orp.Z); + startp += of; + + v3f fp = orp + vec * f; + fp.X += 0.1f * ps->range(-10, 10); + fp.Z += 0.1f * ps->range(-10, 10); + v3s16 cp(fp.X, fp.Y, fp.Z); + + // Choose cave liquid + MapNode liquidnode = CONTENT_IGNORE; + + if (flooded) { + if (use_biome_liquid) { + liquidnode = c_biome_liquid; + } else { + // If cave liquid not defined by biome, fallback to old hardcoded behaviour. + // TODO 'np_caveliquids' is deprecated and should eventually be removed. + // Cave liquids are now defined and located using biome definitions. + float nval = NoisePerlin3D(np_caveliquids, startp.X, + startp.Y, startp.Z, seed); + liquidnode = (nval < 0.40f && node_max.Y < water_level - 256) ? + lavanode : waternode; + } + } + + s16 d0 = -rs / 2; + s16 d1 = d0 + rs; + if (randomize_xz) { + d0 += ps->range(-1, 1); + d1 += ps->range(-1, 1); + } + + bool flat_cave_floor = !large_cave && ps->range(0, 2) == 2; + + for (s16 z0 = d0; z0 <= d1; z0++) { + s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1); + for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) { + s16 maxabsxz = MYMAX(abs(x0), abs(z0)); + + s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1); + + for (s16 y0 = -si2; y0 <= si2; y0++) { + // Make better floors in small caves + if (flat_cave_floor && y0 <= -rs / 2 && rs <= 7) + continue; + + if (large_cave_is_flat) { + // Make large caves not so tall + if (rs > 7 && abs(y0) >= rs / 3) + continue; + } + + v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0); + p += of; + + if (!vm->m_area.contains(p)) + continue; + + u32 i = vm->m_area.index(p); + content_t c = vm->m_data[i].getContent(); + if (!ndef->get(c).is_ground_content) + continue; + + if (large_cave) { + int full_ymin = node_min.Y - MAP_BLOCKSIZE; + int full_ymax = node_max.Y + MAP_BLOCKSIZE; + + if (flooded && full_ymin < water_level && full_ymax > water_level) + vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode; + else if (flooded && full_ymax < water_level) + vm->m_data[i] = (p.Y < startp.Y - 4) ? liquidnode : airnode; + else + vm->m_data[i] = airnode; + } else { + vm->m_data[i] = airnode; + vm->m_flags[i] |= VMANIP_FLAG_CAVE; + } + } + } + } +} + + +inline bool CavesRandomWalk::isPosAboveSurface(v3s16 p) +{ + if (heightmap != NULL && + p.Z >= node_min.Z && p.Z <= node_max.Z && + p.X >= node_min.X && p.X <= node_max.X) { + u32 index = (p.Z - node_min.Z) * ystride + (p.X - node_min.X); + if (heightmap[index] < p.Y) + return true; + } else if (p.Y > water_level) { + return true; + } + + return false; +} + + +//// +//// CavesV6 +//// + +CavesV6::CavesV6(const NodeDefManager *ndef, GenerateNotifier *gennotify, + int water_level, content_t water_source, content_t lava_source) +{ + assert(ndef); + + this->ndef = ndef; + this->gennotify = gennotify; + this->water_level = water_level; + + c_water_source = water_source; + if (c_water_source == CONTENT_IGNORE) + c_water_source = ndef->getId("mapgen_water_source"); + if (c_water_source == CONTENT_IGNORE) + c_water_source = CONTENT_AIR; + + c_lava_source = lava_source; + if (c_lava_source == CONTENT_IGNORE) + c_lava_source = ndef->getId("mapgen_lava_source"); + if (c_lava_source == CONTENT_IGNORE) + c_lava_source = CONTENT_AIR; +} + + +void CavesV6::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, + PseudoRandom *ps, PseudoRandom *ps2, + bool is_large_cave, int max_stone_height, s16 *heightmap) +{ + assert(vm); + assert(ps); + assert(ps2); + + this->vm = vm; + this->ps = ps; + this->ps2 = ps2; + this->node_min = nmin; + this->node_max = nmax; + this->heightmap = heightmap; + this->large_cave = is_large_cave; + + this->ystride = nmax.X - nmin.X + 1; + + // Set initial parameters from randomness + min_tunnel_diameter = 2; + max_tunnel_diameter = ps->range(2, 6); + int dswitchint = ps->range(1, 14); + if (large_cave) { + part_max_length_rs = ps->range(2, 4); + tunnel_routepoints = ps->range(5, ps->range(15, 30)); + min_tunnel_diameter = 5; + max_tunnel_diameter = ps->range(7, ps->range(8, 24)); + } else { + part_max_length_rs = ps->range(2, 9); + tunnel_routepoints = ps->range(10, ps->range(15, 30)); + } + large_cave_is_flat = (ps->range(0, 1) == 0); + + main_direction = v3f(0, 0, 0); + + // Allowed route area size in nodes + ar = node_max - node_min + v3s16(1, 1, 1); + // Area starting point in nodes + of = node_min; + + // Allow a bit more + //(this should be more than the maximum radius of the tunnel) + const s16 max_spread_amount = MAP_BLOCKSIZE; + const s16 insure = 10; + s16 more = MYMAX(max_spread_amount - max_tunnel_diameter / 2 - insure, 1); + ar += v3s16(1, 0, 1) * more * 2; + of -= v3s16(1, 0, 1) * more; + + route_y_min = 0; + // Allow half a diameter + 7 over stone surface + route_y_max = -of.Y + max_stone_height + max_tunnel_diameter / 2 + 7; + + // Limit maximum to area + route_y_max = rangelim(route_y_max, 0, ar.Y - 1); + + if (large_cave) { + s16 minpos = 0; + if (node_min.Y < water_level && node_max.Y > water_level) { + minpos = water_level - max_tunnel_diameter / 3 - of.Y; + route_y_max = water_level + max_tunnel_diameter / 3 - of.Y; + } + route_y_min = ps->range(minpos, minpos + max_tunnel_diameter); + route_y_min = rangelim(route_y_min, 0, route_y_max); + } + + s16 route_start_y_min = route_y_min; + s16 route_start_y_max = route_y_max; + + route_start_y_min = rangelim(route_start_y_min, 0, ar.Y - 1); + route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y - 1); + + // Randomize starting position + orp.Z = (float)(ps->next() % ar.Z) + 0.5f; + orp.Y = (float)(ps->range(route_start_y_min, route_start_y_max)) + 0.5f; + orp.X = (float)(ps->next() % ar.X) + 0.5f; + + // Add generation notify begin event + if (gennotify != NULL) { + v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); + GenNotifyType notifytype = large_cave ? + GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN; + gennotify->addEvent(notifytype, abs_pos); + } + + // Generate some tunnel starting from orp + for (u16 j = 0; j < tunnel_routepoints; j++) + makeTunnel(j % dswitchint == 0); + + // Add generation notify end event + if (gennotify != NULL) { + v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); + GenNotifyType notifytype = large_cave ? + GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END; + gennotify->addEvent(notifytype, abs_pos); + } +} + + +void CavesV6::makeTunnel(bool dirswitch) +{ + if (dirswitch && !large_cave) { + main_direction.Z = ((float)(ps->next() % 20) - (float)10) / 10; + main_direction.Y = ((float)(ps->next() % 20) - (float)10) / 30; + main_direction.X = ((float)(ps->next() % 20) - (float)10) / 10; + + main_direction *= (float)ps->range(0, 10) / 10; + } + + // Randomize size + s16 min_d = min_tunnel_diameter; + s16 max_d = max_tunnel_diameter; + rs = ps->range(min_d, max_d); + s16 rs_part_max_length_rs = rs * part_max_length_rs; + + v3s16 maxlen; + if (large_cave) { + maxlen = v3s16( + rs_part_max_length_rs, + rs_part_max_length_rs / 2, + rs_part_max_length_rs + ); + } else { + maxlen = v3s16( + rs_part_max_length_rs, + ps->range(1, rs_part_max_length_rs), + rs_part_max_length_rs + ); + } + + v3f vec; + vec.Z = (float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2; + vec.Y = (float)(ps->next() % maxlen.Y) - (float)maxlen.Y / 2; + vec.X = (float)(ps->next() % maxlen.X) - (float)maxlen.X / 2; + + // Jump downward sometimes + if (!large_cave && ps->range(0, 12) == 0) { + vec.Z = (float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2; + vec.Y = (float)(ps->next() % (maxlen.Y * 2)) - (float)maxlen.Y; + vec.X = (float)(ps->next() % maxlen.X) - (float)maxlen.X / 2; + } + + // Do not make caves that are entirely above ground, to fix shadow bugs + // caused by overgenerated large caves. + // It is only necessary to check the startpoint and endpoint. + v3s16 p1 = v3s16(orp.X, orp.Y, orp.Z) + of + rs / 2; + v3s16 p2 = v3s16(vec.X, vec.Y, vec.Z) + p1; + + // If startpoint and endpoint are above ground, disable placement of nodes + // in carveRoute while still running all PseudoRandom calls to ensure caves + // are consistent with existing worlds. + bool tunnel_above_ground = + p1.Y > getSurfaceFromHeightmap(p1) && + p2.Y > getSurfaceFromHeightmap(p2); + + vec += main_direction; + + v3f rp = orp + vec; + if (rp.X < 0) + rp.X = 0; + else if (rp.X >= ar.X) + rp.X = ar.X - 1; + + if (rp.Y < route_y_min) + rp.Y = route_y_min; + else if (rp.Y >= route_y_max) + rp.Y = route_y_max - 1; + + if (rp.Z < 0) + rp.Z = 0; + else if (rp.Z >= ar.Z) + rp.Z = ar.Z - 1; + + vec = rp - orp; + + float veclen = vec.getLength(); + // As odd as it sounds, veclen is *exactly* 0.0 sometimes, causing a FPE + if (veclen < 0.05f) + veclen = 1.0f; + + // Every second section is rough + bool randomize_xz = (ps2->range(1, 2) == 1); + + // Carve routes + for (float f = 0.f; f < 1.0f; f += 1.0f / veclen) + carveRoute(vec, f, randomize_xz, tunnel_above_ground); + + orp = rp; +} + + +void CavesV6::carveRoute(v3f vec, float f, bool randomize_xz, + bool tunnel_above_ground) +{ + MapNode airnode(CONTENT_AIR); + MapNode waternode(c_water_source); + MapNode lavanode(c_lava_source); + + v3s16 startp(orp.X, orp.Y, orp.Z); + startp += of; + + v3f fp = orp + vec * f; + fp.X += 0.1f * ps->range(-10, 10); + fp.Z += 0.1f * ps->range(-10, 10); + v3s16 cp(fp.X, fp.Y, fp.Z); + + s16 d0 = -rs / 2; + s16 d1 = d0 + rs; + if (randomize_xz) { + d0 += ps->range(-1, 1); + d1 += ps->range(-1, 1); + } + + for (s16 z0 = d0; z0 <= d1; z0++) { + s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1); + for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) { + if (tunnel_above_ground) + continue; + + s16 maxabsxz = MYMAX(abs(x0), abs(z0)); + s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1); + for (s16 y0 = -si2; y0 <= si2; y0++) { + if (large_cave_is_flat) { + // Make large caves not so tall + if (rs > 7 && abs(y0) >= rs / 3) + continue; + } + + v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0); + p += of; + + if (!vm->m_area.contains(p)) + continue; + + u32 i = vm->m_area.index(p); + content_t c = vm->m_data[i].getContent(); + if (!ndef->get(c).is_ground_content) + continue; + + if (large_cave) { + int full_ymin = node_min.Y - MAP_BLOCKSIZE; + int full_ymax = node_max.Y + MAP_BLOCKSIZE; + + if (full_ymin < water_level && full_ymax > water_level) { + vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode; + } else if (full_ymax < water_level) { + vm->m_data[i] = (p.Y < startp.Y - 2) ? lavanode : airnode; + } else { + vm->m_data[i] = airnode; + } + } else { + if (c == CONTENT_AIR) + continue; + + vm->m_data[i] = airnode; + vm->m_flags[i] |= VMANIP_FLAG_CAVE; + } + } + } + } +} + + +inline s16 CavesV6::getSurfaceFromHeightmap(v3s16 p) +{ + if (heightmap != NULL && + p.Z >= node_min.Z && p.Z <= node_max.Z && + p.X >= node_min.X && p.X <= node_max.X) { + u32 index = (p.Z - node_min.Z) * ystride + (p.X - node_min.X); + return heightmap[index]; + } + + return water_level; + +} diff --git a/src/mapgen/cavegen.h b/src/mapgen/cavegen.h new file mode 100644 index 0000000..d678d36 --- /dev/null +++ b/src/mapgen/cavegen.h @@ -0,0 +1,248 @@ +/* +Minetest +Copyright (C) 2015-2020 paramat +Copyright (C) 2010-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1 + +typedef u16 biome_t; // copy from mg_biome.h to avoid an unnecessary include + +class GenerateNotifier; + +/* + CavesNoiseIntersection is a cave digging algorithm that carves smooth, + web-like, continuous tunnels at points where the density of the intersection + between two separate 3d noises is above a certain value. This value, + cave_width, can be modified to set the effective width of these tunnels. + + This algorithm is relatively heavyweight, taking ~80ms to generate an + 80x80x80 chunk of map on a modern processor. Use sparingly! + + TODO(hmmmm): Remove dependency on biomes + TODO(hmmmm): Find alternative to overgeneration as solution for sunlight issue +*/ +class CavesNoiseIntersection +{ +public: + CavesNoiseIntersection(const NodeDefManager *nodedef, + BiomeManager *biomemgr, v3s16 chunksize, NoiseParams *np_cave1, + NoiseParams *np_cave2, s32 seed, float cave_width); + ~CavesNoiseIntersection(); + + void generateCaves(MMVManip *vm, v3s16 nmin, v3s16 nmax, biome_t *biomemap); + +private: + const NodeDefManager *m_ndef; + BiomeManager *m_bmgr; + + // configurable parameters + v3s16 m_csize; + float m_cave_width; + + // intermediate state variables + u16 m_ystride; + u16 m_zstride_1d; + + Noise *noise_cave1; + Noise *noise_cave2; +}; + +/* + CavernsNoise is a cave digging algorithm +*/ +class CavernsNoise +{ +public: + CavernsNoise(const NodeDefManager *nodedef, v3s16 chunksize, + NoiseParams *np_cavern, s32 seed, float cavern_limit, + float cavern_taper, float cavern_threshold); + ~CavernsNoise(); + + bool generateCaverns(MMVManip *vm, v3s16 nmin, v3s16 nmax); + +private: + const NodeDefManager *m_ndef; + + // configurable parameters + v3s16 m_csize; + float m_cavern_limit; + float m_cavern_taper; + float m_cavern_threshold; + + // intermediate state variables + u16 m_ystride; + u16 m_zstride_1d; + + Noise *noise_cavern; + + content_t c_water_source; + content_t c_lava_source; +}; + +/* + CavesRandomWalk is an implementation of a cave-digging algorithm that + operates on the principle of a "random walk" to approximate the stochiastic + activity of cavern development. + + In summary, this algorithm works by carving a randomly sized tunnel in a + random direction a random amount of times, randomly varying in width. + All randomness here is uniformly distributed; alternative distributions have + not yet been implemented. + + This algorithm is very fast, executing in less than 1ms on average for an + 80x80x80 chunk of map on a modern processor. +*/ +class CavesRandomWalk +{ +public: + MMVManip *vm; + const NodeDefManager *ndef; + GenerateNotifier *gennotify; + s16 *heightmap; + BiomeGen *bmgn; + + s32 seed; + int water_level; + float large_cave_flooded; + // TODO 'np_caveliquids' is deprecated and should eventually be removed. + // Cave liquids are now defined and located using biome definitions. + NoiseParams *np_caveliquids; + + u16 ystride; + + s16 min_tunnel_diameter; + s16 max_tunnel_diameter; + u16 tunnel_routepoints; + int part_max_length_rs; + + bool large_cave; + bool large_cave_is_flat; + bool flooded; + bool use_biome_liquid; + + v3s16 node_min; + v3s16 node_max; + + v3f orp; // starting point, relative to caved space + v3s16 of; // absolute coordinates of caved space + v3s16 ar; // allowed route area + s16 rs; // tunnel radius size + v3f main_direction; + + s16 route_y_min; + s16 route_y_max; + + PseudoRandom *ps; + + content_t c_water_source; + content_t c_lava_source; + content_t c_biome_liquid; + + // ndef is a mandatory parameter. + // If gennotify is NULL, generation events are not logged. + // If biomegen is NULL, cave liquids have classic behaviour. + CavesRandomWalk(const NodeDefManager *ndef, GenerateNotifier *gennotify = + NULL, s32 seed = 0, int water_level = 1, content_t water_source = + CONTENT_IGNORE, content_t lava_source = CONTENT_IGNORE, + float large_cave_flooded = 0.5f, BiomeGen *biomegen = NULL); + + // vm and ps are mandatory parameters. + // If heightmap is NULL, the surface level at all points is assumed to + // be water_level. + void makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, PseudoRandom *ps, + bool is_large_cave, int max_stone_height, s16 *heightmap); + +private: + void makeTunnel(bool dirswitch); + void carveRoute(v3f vec, float f, bool randomize_xz); + + inline bool isPosAboveSurface(v3s16 p); +}; + +/* + CavesV6 is the original version of caves used with Mapgen V6. + + Though it uses the same fundamental algorithm as CavesRandomWalk, it is made + separate to preserve the exact sequence of PseudoRandom calls - any change + to this ordering results in the output being radically different. + Because caves in Mapgen V6 are responsible for a large portion of the basic + terrain shape, modifying this will break our contract of reverse + compatibility for a 'stable' mapgen such as V6. + + tl;dr, + *** DO NOT TOUCH THIS CLASS UNLESS YOU KNOW WHAT YOU ARE DOING *** +*/ +class CavesV6 +{ +public: + MMVManip *vm; + const NodeDefManager *ndef; + GenerateNotifier *gennotify; + PseudoRandom *ps; + PseudoRandom *ps2; + + // configurable parameters + s16 *heightmap; + content_t c_water_source; + content_t c_lava_source; + int water_level; + + // intermediate state variables + u16 ystride; + + s16 min_tunnel_diameter; + s16 max_tunnel_diameter; + u16 tunnel_routepoints; + int part_max_length_rs; + + bool large_cave; + bool large_cave_is_flat; + + v3s16 node_min; + v3s16 node_max; + + v3f orp; // starting point, relative to caved space + v3s16 of; // absolute coordinates of caved space + v3s16 ar; // allowed route area + s16 rs; // tunnel radius size + v3f main_direction; + + s16 route_y_min; + s16 route_y_max; + + // ndef is a mandatory parameter. + // If gennotify is NULL, generation events are not logged. + CavesV6(const NodeDefManager *ndef, GenerateNotifier *gennotify = NULL, + int water_level = 1, content_t water_source = CONTENT_IGNORE, + content_t lava_source = CONTENT_IGNORE); + + // vm, ps, and ps2 are mandatory parameters. + // If heightmap is NULL, the surface level at all points is assumed to + // be water_level. + void makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, PseudoRandom *ps, + PseudoRandom *ps2, bool is_large_cave, int max_stone_height, + s16 *heightmap = NULL); + +private: + void makeTunnel(bool dirswitch); + void carveRoute(v3f vec, float f, bool randomize_xz, bool tunnel_above_ground); + + inline s16 getSurfaceFromHeightmap(v3s16 p); +}; diff --git a/src/mapgen/dungeongen.cpp b/src/mapgen/dungeongen.cpp new file mode 100644 index 0000000..1d439ab --- /dev/null +++ b/src/mapgen/dungeongen.cpp @@ -0,0 +1,674 @@ +/* +Minetest +Copyright (C) 2010-2018 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2015-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "dungeongen.h" +#include <cmath> +#include "mapgen.h" +#include "voxel.h" +#include "noise.h" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +#include "nodedef.h" +#include "settings.h" + +//#define DGEN_USE_TORCHES + + +/////////////////////////////////////////////////////////////////////////////// + + +DungeonGen::DungeonGen(const NodeDefManager *ndef, + GenerateNotifier *gennotify, DungeonParams *dparams) +{ + assert(ndef); + + this->ndef = ndef; + this->gennotify = gennotify; + +#ifdef DGEN_USE_TORCHES + c_torch = ndef->getId("default:torch"); +#endif + + if (dparams) { + dp = *dparams; + } else { + // Default dungeon parameters + dp.seed = 0; + + dp.c_wall = ndef->getId("mapgen_cobble"); + dp.c_alt_wall = ndef->getId("mapgen_mossycobble"); + dp.c_stair = ndef->getId("mapgen_stair_cobble"); + + dp.diagonal_dirs = false; + dp.only_in_ground = true; + dp.holesize = v3s16(1, 2, 1); + dp.corridor_len_min = 1; + dp.corridor_len_max = 13; + dp.room_size_min = v3s16(4, 4, 4); + dp.room_size_max = v3s16(8, 6, 8); + dp.room_size_large_min = v3s16(8, 8, 8); + dp.room_size_large_max = v3s16(16, 16, 16); + dp.large_room_chance = 1; + dp.num_rooms = 8; + dp.num_dungeons = 1; + dp.notifytype = GENNOTIFY_DUNGEON; + + dp.np_alt_wall = + NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0); + } +} + + +void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax) +{ + if (dp.num_dungeons == 0) + return; + + assert(vm); + + //TimeTaker t("gen dungeons"); + + this->vm = vm; + this->blockseed = bseed; + random.seed(bseed + 2); + + // Dungeon generator doesn't modify places which have this set + vm->clearFlag(VMANIP_FLAG_DUNGEON_INSIDE | VMANIP_FLAG_DUNGEON_PRESERVE); + + if (dp.only_in_ground) { + // Set all air and liquid drawtypes to be untouchable to make dungeons generate + // in ground only. + // Set 'ignore' to be untouchable to prevent generation in ungenerated neighbor + // mapchunks, to avoid dungeon rooms generating outside ground. + // Like randomwalk caves, preserve nodes that have 'is_ground_content = false', + // to avoid dungeons that generate out beyond the edge of a mapchunk destroying + // nodes added by mods in 'register_on_generated()'. + for (s16 z = nmin.Z; z <= nmax.Z; z++) { + for (s16 y = nmin.Y; y <= nmax.Y; y++) { + u32 i = vm->m_area.index(nmin.X, y, z); + for (s16 x = nmin.X; x <= nmax.X; x++) { + content_t c = vm->m_data[i].getContent(); + NodeDrawType dtype = ndef->get(c).drawtype; + if (dtype == NDT_AIRLIKE || dtype == NDT_LIQUID || + c == CONTENT_IGNORE || !ndef->get(c).is_ground_content) + vm->m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE; + i++; + } + } + } + } + + // Add them + for (u32 i = 0; i < dp.num_dungeons; i++) + makeDungeon(v3s16(1, 1, 1) * MAP_BLOCKSIZE); + + // Optionally convert some structure to alternative structure + if (dp.c_alt_wall == CONTENT_IGNORE) + return; + + for (s16 z = nmin.Z; z <= nmax.Z; z++) + for (s16 y = nmin.Y; y <= nmax.Y; y++) { + u32 i = vm->m_area.index(nmin.X, y, z); + for (s16 x = nmin.X; x <= nmax.X; x++) { + if (vm->m_data[i].getContent() == dp.c_wall) { + if (NoisePerlin3D(&dp.np_alt_wall, x, y, z, blockseed) > 0.0f) + vm->m_data[i].setContent(dp.c_alt_wall); + } + i++; + } + } + + //printf("== gen dungeons: %dms\n", t.stop()); +} + + +void DungeonGen::makeDungeon(v3s16 start_padding) +{ + const v3s16 &areasize = vm->m_area.getExtent(); + v3s16 roomsize; + v3s16 roomplace; + + /* + Find place for first room. + */ + bool fits = false; + for (u32 i = 0; i < 100 && !fits; i++) { + if (dp.large_room_chance >= 1) { + roomsize.Z = random.range(dp.room_size_large_min.Z, dp.room_size_large_max.Z); + roomsize.Y = random.range(dp.room_size_large_min.Y, dp.room_size_large_max.Y); + roomsize.X = random.range(dp.room_size_large_min.X, dp.room_size_large_max.X); + } else { + roomsize.Z = random.range(dp.room_size_min.Z, dp.room_size_max.Z); + roomsize.Y = random.range(dp.room_size_min.Y, dp.room_size_max.Y); + roomsize.X = random.range(dp.room_size_min.X, dp.room_size_max.X); + } + + // start_padding is used to disallow starting the generation of + // a dungeon in a neighboring generation chunk + roomplace = vm->m_area.MinEdge + start_padding; + roomplace.Z += random.range(0, areasize.Z - roomsize.Z - start_padding.Z); + roomplace.Y += random.range(0, areasize.Y - roomsize.Y - start_padding.Y); + roomplace.X += random.range(0, areasize.X - roomsize.X - start_padding.X); + + /* + Check that we're not putting the room to an unknown place, + otherwise it might end up floating in the air + */ + fits = true; + for (s16 z = 0; z < roomsize.Z; z++) + for (s16 y = 0; y < roomsize.Y; y++) + for (s16 x = 0; x < roomsize.X; x++) { + v3s16 p = roomplace + v3s16(x, y, z); + u32 vi = vm->m_area.index(p); + if ((vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) || + vm->m_data[vi].getContent() == CONTENT_IGNORE) { + fits = false; + break; + } + } + } + // No place found + if (!fits) + return; + + /* + Stores the center position of the last room made, so that + a new corridor can be started from the last room instead of + the new room, if chosen so. + */ + v3s16 last_room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2); + + for (u32 i = 0; i < dp.num_rooms; i++) { + // Make a room to the determined place + makeRoom(roomsize, roomplace); + + v3s16 room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2); + if (gennotify) + gennotify->addEvent(dp.notifytype, room_center); + +#ifdef DGEN_USE_TORCHES + // Place torch at room center (for testing) + vm->m_data[vm->m_area.index(room_center)] = MapNode(c_torch); +#endif + + // Quit if last room + if (i + 1 == dp.num_rooms) + break; + + // Determine walker start position + + bool start_in_last_room = (random.range(0, 2) != 0); + + v3s16 walker_start_place; + + if (start_in_last_room) { + walker_start_place = last_room_center; + } else { + walker_start_place = room_center; + // Store center of current room as the last one + last_room_center = room_center; + } + + // Create walker and find a place for a door + v3s16 doorplace; + v3s16 doordir; + + m_pos = walker_start_place; + if (!findPlaceForDoor(doorplace, doordir)) + return; + + if (random.range(0, 1) == 0) + // Make the door + makeDoor(doorplace, doordir); + else + // Don't actually make a door + doorplace -= doordir; + + // Make a random corridor starting from the door + v3s16 corridor_end; + v3s16 corridor_end_dir; + makeCorridor(doorplace, doordir, corridor_end, corridor_end_dir); + + // Find a place for a random sized room + if (dp.large_room_chance > 1 && random.range(1, dp.large_room_chance) == 1) { + // Large room + roomsize.Z = random.range(dp.room_size_large_min.Z, dp.room_size_large_max.Z); + roomsize.Y = random.range(dp.room_size_large_min.Y, dp.room_size_large_max.Y); + roomsize.X = random.range(dp.room_size_large_min.X, dp.room_size_large_max.X); + } else { + roomsize.Z = random.range(dp.room_size_min.Z, dp.room_size_max.Z); + roomsize.Y = random.range(dp.room_size_min.Y, dp.room_size_max.Y); + roomsize.X = random.range(dp.room_size_min.X, dp.room_size_max.X); + } + + m_pos = corridor_end; + m_dir = corridor_end_dir; + if (!findPlaceForRoomDoor(roomsize, doorplace, doordir, roomplace)) + return; + + if (random.range(0, 1) == 0) + // Make the door + makeDoor(doorplace, doordir); + else + // Don't actually make a door + roomplace -= doordir; + } +} + + +void DungeonGen::makeRoom(v3s16 roomsize, v3s16 roomplace) +{ + MapNode n_wall(dp.c_wall); + MapNode n_air(CONTENT_AIR); + + // Make +-X walls + for (s16 z = 0; z < roomsize.Z; z++) + for (s16 y = 0; y < roomsize.Y; y++) { + { + v3s16 p = roomplace + v3s16(0, y, z); + if (!vm->m_area.contains(p)) + continue; + u32 vi = vm->m_area.index(p); + if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) + continue; + vm->m_data[vi] = n_wall; + } + { + v3s16 p = roomplace + v3s16(roomsize.X - 1, y, z); + if (!vm->m_area.contains(p)) + continue; + u32 vi = vm->m_area.index(p); + if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) + continue; + vm->m_data[vi] = n_wall; + } + } + + // Make +-Z walls + for (s16 x = 0; x < roomsize.X; x++) + for (s16 y = 0; y < roomsize.Y; y++) { + { + v3s16 p = roomplace + v3s16(x, y, 0); + if (!vm->m_area.contains(p)) + continue; + u32 vi = vm->m_area.index(p); + if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) + continue; + vm->m_data[vi] = n_wall; + } + { + v3s16 p = roomplace + v3s16(x, y, roomsize.Z - 1); + if (!vm->m_area.contains(p)) + continue; + u32 vi = vm->m_area.index(p); + if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) + continue; + vm->m_data[vi] = n_wall; + } + } + + // Make +-Y walls (floor and ceiling) + for (s16 z = 0; z < roomsize.Z; z++) + for (s16 x = 0; x < roomsize.X; x++) { + { + v3s16 p = roomplace + v3s16(x, 0, z); + if (!vm->m_area.contains(p)) + continue; + u32 vi = vm->m_area.index(p); + if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) + continue; + vm->m_data[vi] = n_wall; + } + { + v3s16 p = roomplace + v3s16(x,roomsize. Y - 1, z); + if (!vm->m_area.contains(p)) + continue; + u32 vi = vm->m_area.index(p); + if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) + continue; + vm->m_data[vi] = n_wall; + } + } + + // Fill with air + for (s16 z = 1; z < roomsize.Z - 1; z++) + for (s16 y = 1; y < roomsize.Y - 1; y++) + for (s16 x = 1; x < roomsize.X - 1; x++) { + v3s16 p = roomplace + v3s16(x, y, z); + if (!vm->m_area.contains(p)) + continue; + u32 vi = vm->m_area.index(p); + vm->m_flags[vi] |= VMANIP_FLAG_DUNGEON_UNTOUCHABLE; + vm->m_data[vi] = n_air; + } +} + + +void DungeonGen::makeFill(v3s16 place, v3s16 size, + u8 avoid_flags, MapNode n, u8 or_flags) +{ + for (s16 z = 0; z < size.Z; z++) + for (s16 y = 0; y < size.Y; y++) + for (s16 x = 0; x < size.X; x++) { + v3s16 p = place + v3s16(x, y, z); + if (!vm->m_area.contains(p)) + continue; + u32 vi = vm->m_area.index(p); + if (vm->m_flags[vi] & avoid_flags) + continue; + vm->m_flags[vi] |= or_flags; + vm->m_data[vi] = n; + } +} + + +void DungeonGen::makeHole(v3s16 place) +{ + makeFill(place, dp.holesize, 0, MapNode(CONTENT_AIR), + VMANIP_FLAG_DUNGEON_INSIDE); +} + + +void DungeonGen::makeDoor(v3s16 doorplace, v3s16 doordir) +{ + makeHole(doorplace); + +#ifdef DGEN_USE_TORCHES + // Place torch (for testing) + vm->m_data[vm->m_area.index(doorplace)] = MapNode(c_torch); +#endif +} + + +void DungeonGen::makeCorridor(v3s16 doorplace, v3s16 doordir, + v3s16 &result_place, v3s16 &result_dir) +{ + makeHole(doorplace); + v3s16 p0 = doorplace; + v3s16 dir = doordir; + u32 length = random.range(dp.corridor_len_min, dp.corridor_len_max); + u32 partlength = random.range(dp.corridor_len_min, dp.corridor_len_max); + u32 partcount = 0; + s16 make_stairs = 0; + + if (random.next() % 2 == 0 && partlength >= 3) + make_stairs = random.next() % 2 ? 1 : -1; + + for (u32 i = 0; i < length; i++) { + v3s16 p = p0 + dir; + if (partcount != 0) + p.Y += make_stairs; + + // Check segment of minimum size corridor is in voxelmanip + if (vm->m_area.contains(p) && vm->m_area.contains(p + v3s16(0, 1, 0))) { + if (make_stairs) { + makeFill(p + v3s16(-1, -1, -1), + dp.holesize + v3s16(2, 3, 2), + VMANIP_FLAG_DUNGEON_UNTOUCHABLE, + MapNode(dp.c_wall), + 0); + makeFill(p, dp.holesize, VMANIP_FLAG_DUNGEON_UNTOUCHABLE, + MapNode(CONTENT_AIR), VMANIP_FLAG_DUNGEON_INSIDE); + makeFill(p - dir, dp.holesize, VMANIP_FLAG_DUNGEON_UNTOUCHABLE, + MapNode(CONTENT_AIR), VMANIP_FLAG_DUNGEON_INSIDE); + + // TODO: fix stairs code so it works 100% + // (quite difficult) + + // exclude stairs from the bottom step + // exclude stairs from diagonal steps + if (((dir.X ^ dir.Z) & 1) && + (((make_stairs == 1) && i != 0) || + ((make_stairs == -1) && i != length - 1))) { + // rotate face 180 deg if + // making stairs backwards + int facedir = dir_to_facedir(dir * make_stairs); + v3s16 ps = p; + u16 stair_width = (dir.Z != 0) ? dp.holesize.X : dp.holesize.Z; + // Stair width direction vector + v3s16 swv = (dir.Z != 0) ? v3s16(1, 0, 0) : v3s16(0, 0, 1); + + for (u16 st = 0; st < stair_width; st++) { + if (make_stairs == -1) { + u32 vi = vm->m_area.index(ps.X - dir.X, ps.Y - 1, ps.Z - dir.Z); + if (vm->m_area.contains(ps + v3s16(-dir.X, -1, -dir.Z)) && + vm->m_data[vi].getContent() == dp.c_wall) { + vm->m_flags[vi] |= VMANIP_FLAG_DUNGEON_UNTOUCHABLE; + vm->m_data[vi] = MapNode(dp.c_stair, 0, facedir); + } + } else if (make_stairs == 1) { + u32 vi = vm->m_area.index(ps.X, ps.Y - 1, ps.Z); + if (vm->m_area.contains(ps + v3s16(0, -1, 0)) && + vm->m_data[vi].getContent() == dp.c_wall) { + vm->m_flags[vi] |= VMANIP_FLAG_DUNGEON_UNTOUCHABLE; + vm->m_data[vi] = MapNode(dp.c_stair, 0, facedir); + } + } + ps += swv; + } + } + } else { + makeFill(p + v3s16(-1, -1, -1), + dp.holesize + v3s16(2, 2, 2), + VMANIP_FLAG_DUNGEON_UNTOUCHABLE, + MapNode(dp.c_wall), + 0); + makeHole(p); + } + + p0 = p; + } else { + // Can't go here, turn away + dir = turn_xz(dir, random.range(0, 1)); + make_stairs = -make_stairs; + partcount = 0; + partlength = random.range(1, length); + continue; + } + + partcount++; + if (partcount >= partlength) { + partcount = 0; + + random_turn(random, dir); + + partlength = random.range(1, length); + + make_stairs = 0; + if (random.next() % 2 == 0 && partlength >= 3) + make_stairs = random.next() % 2 ? 1 : -1; + } + } + result_place = p0; + result_dir = dir; +} + + +bool DungeonGen::findPlaceForDoor(v3s16 &result_place, v3s16 &result_dir) +{ + for (u32 i = 0; i < 100; i++) { + v3s16 p = m_pos + m_dir; + v3s16 p1 = p + v3s16(0, 1, 0); + if (!vm->m_area.contains(p) || !vm->m_area.contains(p1) || i % 4 == 0) { + randomizeDir(); + continue; + } + if (vm->getNodeNoExNoEmerge(p).getContent() == dp.c_wall && + vm->getNodeNoExNoEmerge(p1).getContent() == dp.c_wall) { + // Found wall, this is a good place! + result_place = p; + result_dir = m_dir; + // Randomize next direction + randomizeDir(); + return true; + } + /* + Determine where to move next + */ + // Jump one up if the actual space is there + if (vm->getNodeNoExNoEmerge(p + + v3s16(0, 0, 0)).getContent() == dp.c_wall && + vm->getNodeNoExNoEmerge(p + + v3s16(0, 1, 0)).getContent() == CONTENT_AIR && + vm->getNodeNoExNoEmerge(p + + v3s16(0, 2, 0)).getContent() == CONTENT_AIR) + p += v3s16(0,1,0); + // Jump one down if the actual space is there + if (vm->getNodeNoExNoEmerge(p + + v3s16(0, 1, 0)).getContent() == dp.c_wall && + vm->getNodeNoExNoEmerge(p + + v3s16(0, 0, 0)).getContent() == CONTENT_AIR && + vm->getNodeNoExNoEmerge(p + + v3s16(0, -1, 0)).getContent() == CONTENT_AIR) + p += v3s16(0, -1, 0); + // Check if walking is now possible + if (vm->getNodeNoExNoEmerge(p).getContent() != CONTENT_AIR || + vm->getNodeNoExNoEmerge(p + + v3s16(0, 1, 0)).getContent() != CONTENT_AIR) { + // Cannot continue walking here + randomizeDir(); + continue; + } + // Move there + m_pos = p; + } + return false; +} + + +bool DungeonGen::findPlaceForRoomDoor(v3s16 roomsize, v3s16 &result_doorplace, + v3s16 &result_doordir, v3s16 &result_roomplace) +{ + for (s16 trycount = 0; trycount < 30; trycount++) { + v3s16 doorplace; + v3s16 doordir; + bool r = findPlaceForDoor(doorplace, doordir); + if (!r) + continue; + v3s16 roomplace; + // X east, Z north, Y up + if (doordir == v3s16(1, 0, 0)) // X+ + roomplace = doorplace + + v3s16(0, -1, random.range(-roomsize.Z + 2, -2)); + if (doordir == v3s16(-1, 0, 0)) // X- + roomplace = doorplace + + v3s16(-roomsize.X + 1, -1, random.range(-roomsize.Z + 2, -2)); + if (doordir == v3s16(0, 0, 1)) // Z+ + roomplace = doorplace + + v3s16(random.range(-roomsize.X + 2, -2), -1, 0); + if (doordir == v3s16(0, 0, -1)) // Z- + roomplace = doorplace + + v3s16(random.range(-roomsize.X + 2, -2), -1, -roomsize.Z + 1); + + // Check fit + bool fits = true; + for (s16 z = 1; z < roomsize.Z - 1; z++) + for (s16 y = 1; y < roomsize.Y - 1; y++) + for (s16 x = 1; x < roomsize.X - 1; x++) { + v3s16 p = roomplace + v3s16(x, y, z); + if (!vm->m_area.contains(p)) { + fits = false; + break; + } + if (vm->m_flags[vm->m_area.index(p)] & VMANIP_FLAG_DUNGEON_INSIDE) { + fits = false; + break; + } + } + if (!fits) { + // Find new place + continue; + } + result_doorplace = doorplace; + result_doordir = doordir; + result_roomplace = roomplace; + return true; + } + return false; +} + + +v3s16 rand_ortho_dir(PseudoRandom &random, bool diagonal_dirs) +{ + // Make diagonal directions somewhat rare + if (diagonal_dirs && (random.next() % 4 == 0)) { + v3s16 dir; + int trycount = 0; + + do { + trycount++; + + dir.Z = random.next() % 3 - 1; + dir.Y = 0; + dir.X = random.next() % 3 - 1; + } while ((dir.X == 0 || dir.Z == 0) && trycount < 10); + + return dir; + } + + if (random.next() % 2 == 0) + return random.next() % 2 ? v3s16(-1, 0, 0) : v3s16(1, 0, 0); + + return random.next() % 2 ? v3s16(0, 0, -1) : v3s16(0, 0, 1); +} + + +v3s16 turn_xz(v3s16 olddir, int t) +{ + v3s16 dir; + if (t == 0) { + // Turn right + dir.X = olddir.Z; + dir.Z = -olddir.X; + dir.Y = olddir.Y; + } else { + // Turn left + dir.X = -olddir.Z; + dir.Z = olddir.X; + dir.Y = olddir.Y; + } + return dir; +} + + +void random_turn(PseudoRandom &random, v3s16 &dir) +{ + int turn = random.range(0, 2); + if (turn == 0) { + // Go straight: nothing to do + return; + } else if (turn == 1) { + // Turn right + dir = turn_xz(dir, 0); + } else { + // Turn left + dir = turn_xz(dir, 1); + } +} + + +int dir_to_facedir(v3s16 d) +{ + if (abs(d.X) > abs(d.Z)) + return d.X < 0 ? 3 : 1; + + return d.Z < 0 ? 2 : 0; +} diff --git a/src/mapgen/dungeongen.h b/src/mapgen/dungeongen.h new file mode 100644 index 0000000..35e6bee --- /dev/null +++ b/src/mapgen/dungeongen.h @@ -0,0 +1,126 @@ +/* +Minetest +Copyright (C) 2010-2018 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2015-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "voxel.h" +#include "noise.h" +#include "mapgen.h" + +#define VMANIP_FLAG_DUNGEON_INSIDE VOXELFLAG_CHECKED1 +#define VMANIP_FLAG_DUNGEON_PRESERVE VOXELFLAG_CHECKED2 +#define VMANIP_FLAG_DUNGEON_UNTOUCHABLE (\ + VMANIP_FLAG_DUNGEON_INSIDE|VMANIP_FLAG_DUNGEON_PRESERVE) + +class MMVManip; +class NodeDefManager; + +v3s16 rand_ortho_dir(PseudoRandom &random, bool diagonal_dirs); +v3s16 turn_xz(v3s16 olddir, int t); +void random_turn(PseudoRandom &random, v3s16 &dir); +int dir_to_facedir(v3s16 d); + + +struct DungeonParams { + s32 seed; + + content_t c_wall; + // Randomly scattered alternative wall nodes + content_t c_alt_wall; + content_t c_stair; + + // 3D noise that determines which c_wall nodes are converted to c_alt_wall + NoiseParams np_alt_wall; + + // Number of dungeons generated in mapchunk. All will use the same set of + // dungeonparams. + u16 num_dungeons; + // Dungeons only generate in ground + bool only_in_ground; + // Number of rooms + u16 num_rooms; + // Room size random range. Includes walls / floor / ceilng + v3s16 room_size_min; + v3s16 room_size_max; + // Large room size random range. Includes walls / floor / ceilng + v3s16 room_size_large_min; + v3s16 room_size_large_max; + // Value 0 disables large rooms. + // Value 1 results in 1 large room, the first generated room. + // Value > 1 makes the first generated room large, all other rooms have a + // '1 in value' chance of being large. + u16 large_room_chance; + // Dimensions of 3D 'brush' that creates corridors. + // Dimensions are of the empty space, not including walls / floor / ceilng. + // Diagonal corridors must have hole width >=2 to be passable. + // Currently, hole width >= 3 causes stair corridor bugs. + v3s16 holesize; + // Corridor length random range + u16 corridor_len_min; + u16 corridor_len_max; + // Diagonal corridors are possible, 1 in 4 corridors will be diagonal + bool diagonal_dirs; + // Usually 'GENNOTIFY_DUNGEON', but mapgen v6 uses 'GENNOTIFY_TEMPLE' for + // desert dungeons. + GenNotifyType notifytype; +}; + +class DungeonGen { +public: + MMVManip *vm = nullptr; + const NodeDefManager *ndef; + GenerateNotifier *gennotify; + + u32 blockseed; + PseudoRandom random; + v3s16 csize; + + content_t c_torch; + DungeonParams dp; + + // RoomWalker + v3s16 m_pos; + v3s16 m_dir; + + DungeonGen(const NodeDefManager *ndef, + GenerateNotifier *gennotify, DungeonParams *dparams); + + void generate(MMVManip *vm, u32 bseed, v3s16 full_node_min, v3s16 full_node_max); + + void makeDungeon(v3s16 start_padding); + void makeRoom(v3s16 roomsize, v3s16 roomplace); + void makeCorridor(v3s16 doorplace, v3s16 doordir, + v3s16 &result_place, v3s16 &result_dir); + void makeDoor(v3s16 doorplace, v3s16 doordir); + void makeFill(v3s16 place, v3s16 size, u8 avoid_flags, MapNode n, u8 or_flags); + void makeHole(v3s16 place); + + bool findPlaceForDoor(v3s16 &result_place, v3s16 &result_dir); + bool findPlaceForRoomDoor(v3s16 roomsize, v3s16 &result_doorplace, + v3s16 &result_doordir, v3s16 &result_roomplace); + + inline void randomizeDir() + { + m_dir = rand_ortho_dir(random, dp.diagonal_dirs); + } +}; + +extern NoiseParams nparams_dungeon_density; +extern NoiseParams nparams_dungeon_alt_wall; diff --git a/src/mapgen/mapgen.cpp b/src/mapgen/mapgen.cpp new file mode 100644 index 0000000..99db504 --- /dev/null +++ b/src/mapgen/mapgen.cpp @@ -0,0 +1,1105 @@ +/* +Minetest +Copyright (C) 2010-2018 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2015-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <cmath> +#include "mapgen.h" +#include "voxel.h" +#include "noise.h" +#include "gamedef.h" +#include "mg_biome.h" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +#include "nodedef.h" +#include "emerge.h" +#include "voxelalgorithms.h" +#include "porting.h" +#include "profiler.h" +#include "settings.h" +#include "treegen.h" +#include "serialization.h" +#include "util/serialize.h" +#include "util/numeric.h" +#include "util/directiontables.h" +#include "filesys.h" +#include "log.h" +#include "mapgen_carpathian.h" +#include "mapgen_flat.h" +#include "mapgen_fractal.h" +#include "mapgen_v5.h" +#include "mapgen_v6.h" +#include "mapgen_v7.h" +#include "mapgen_valleys.h" +#include "mapgen_singlenode.h" +#include "cavegen.h" +#include "dungeongen.h" + +FlagDesc flagdesc_mapgen[] = { + {"caves", MG_CAVES}, + {"dungeons", MG_DUNGEONS}, + {"light", MG_LIGHT}, + {"decorations", MG_DECORATIONS}, + {"biomes", MG_BIOMES}, + {"ores", MG_ORES}, + {NULL, 0} +}; + +FlagDesc flagdesc_gennotify[] = { + {"dungeon", 1 << GENNOTIFY_DUNGEON}, + {"temple", 1 << GENNOTIFY_TEMPLE}, + {"cave_begin", 1 << GENNOTIFY_CAVE_BEGIN}, + {"cave_end", 1 << GENNOTIFY_CAVE_END}, + {"large_cave_begin", 1 << GENNOTIFY_LARGECAVE_BEGIN}, + {"large_cave_end", 1 << GENNOTIFY_LARGECAVE_END}, + {"decoration", 1 << GENNOTIFY_DECORATION}, + {NULL, 0} +}; + +struct MapgenDesc { + const char *name; + bool is_user_visible; +}; + +//// +//// Built-in mapgens +//// + +// Order used here defines the order of appearence in mainmenu. +// v6 always last to discourage selection. +// Special mapgens flat, fractal, singlenode, next to last. Of these, singlenode +// last to discourage selection. +// Of the remaining, v5 last due to age, v7 first due to being the default. +// The order of 'enum MapgenType' in mapgen.h must match this order. +static MapgenDesc g_reg_mapgens[] = { + {"v7", true}, + {"valleys", true}, + {"carpathian", true}, + {"v5", true}, + {"flat", true}, + {"fractal", true}, + {"singlenode", true}, + {"v6", true}, +}; + +STATIC_ASSERT( + ARRLEN(g_reg_mapgens) == MAPGEN_INVALID, + registered_mapgens_is_wrong_size); + +//// +//// Mapgen +//// + +Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeParams *emerge) : + gennotify(emerge->gen_notify_on, emerge->gen_notify_on_deco_ids) +{ + id = mapgenid; + water_level = params->water_level; + mapgen_limit = params->mapgen_limit; + flags = params->flags; + csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE); + + /* + We are losing half our entropy by doing this, but it is necessary to + preserve reverse compatibility. If the top half of our current 64 bit + seeds ever starts getting used, existing worlds will break due to a + different hash outcome and no way to differentiate between versions. + + A solution could be to add a new bit to designate that the top half of + the seed value should be used, essentially a 1-bit version code, but + this would require increasing the total size of a seed to 9 bytes (yuck) + + It's probably okay if this never gets fixed. 4.2 billion possibilities + ought to be enough for anyone. + */ + seed = (s32)params->seed; + + ndef = emerge->ndef; +} + + +MapgenType Mapgen::getMapgenType(const std::string &mgname) +{ + for (size_t i = 0; i != ARRLEN(g_reg_mapgens); i++) { + if (mgname == g_reg_mapgens[i].name) + return (MapgenType)i; + } + + return MAPGEN_INVALID; +} + + +const char *Mapgen::getMapgenName(MapgenType mgtype) +{ + size_t index = (size_t)mgtype; + if (index == MAPGEN_INVALID || index >= ARRLEN(g_reg_mapgens)) + return "invalid"; + + return g_reg_mapgens[index].name; +} + + +Mapgen *Mapgen::createMapgen(MapgenType mgtype, MapgenParams *params, + EmergeParams *emerge) +{ + switch (mgtype) { + case MAPGEN_CARPATHIAN: + return new MapgenCarpathian((MapgenCarpathianParams *)params, emerge); + case MAPGEN_FLAT: + return new MapgenFlat((MapgenFlatParams *)params, emerge); + case MAPGEN_FRACTAL: + return new MapgenFractal((MapgenFractalParams *)params, emerge); + case MAPGEN_SINGLENODE: + return new MapgenSinglenode((MapgenSinglenodeParams *)params, emerge); + case MAPGEN_V5: + return new MapgenV5((MapgenV5Params *)params, emerge); + case MAPGEN_V6: + return new MapgenV6((MapgenV6Params *)params, emerge); + case MAPGEN_V7: + return new MapgenV7((MapgenV7Params *)params, emerge); + case MAPGEN_VALLEYS: + return new MapgenValleys((MapgenValleysParams *)params, emerge); + default: + return nullptr; + } +} + + +MapgenParams *Mapgen::createMapgenParams(MapgenType mgtype) +{ + switch (mgtype) { + case MAPGEN_CARPATHIAN: + return new MapgenCarpathianParams; + case MAPGEN_FLAT: + return new MapgenFlatParams; + case MAPGEN_FRACTAL: + return new MapgenFractalParams; + case MAPGEN_SINGLENODE: + return new MapgenSinglenodeParams; + case MAPGEN_V5: + return new MapgenV5Params; + case MAPGEN_V6: + return new MapgenV6Params; + case MAPGEN_V7: + return new MapgenV7Params; + case MAPGEN_VALLEYS: + return new MapgenValleysParams; + default: + return nullptr; + } +} + + +void Mapgen::getMapgenNames(std::vector<const char *> *mgnames, bool include_hidden) +{ + for (u32 i = 0; i != ARRLEN(g_reg_mapgens); i++) { + if (include_hidden || g_reg_mapgens[i].is_user_visible) + mgnames->push_back(g_reg_mapgens[i].name); + } +} + +void Mapgen::setDefaultSettings(Settings *settings) +{ + settings->setDefault("mg_flags", flagdesc_mapgen, + MG_CAVES | MG_DUNGEONS | MG_LIGHT | MG_DECORATIONS | MG_BIOMES | MG_ORES); + + for (int i = 0; i < (int)MAPGEN_INVALID; ++i) { + MapgenParams *params = createMapgenParams((MapgenType)i); + params->setDefaultSettings(settings); + delete params; + } +} + +u32 Mapgen::getBlockSeed(v3s16 p, s32 seed) +{ + return (u32)seed + + p.Z * 38134234 + + p.Y * 42123 + + p.X * 23; +} + + +u32 Mapgen::getBlockSeed2(v3s16 p, s32 seed) +{ + // Multiply by unsigned number to avoid signed overflow (UB) + u32 n = 1619U * p.X + 31337U * p.Y + 52591U * p.Z + 1013U * seed; + n = (n >> 13) ^ n; + return (n * (n * n * 60493 + 19990303) + 1376312589); +} + + +// Returns -MAX_MAP_GENERATION_LIMIT if not found +s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax) +{ + const v3s16 &em = vm->m_area.getExtent(); + u32 i = vm->m_area.index(p2d.X, ymax, p2d.Y); + s16 y; + + for (y = ymax; y >= ymin; y--) { + MapNode &n = vm->m_data[i]; + if (ndef->get(n).walkable) + break; + + VoxelArea::add_y(em, i, -1); + } + return (y >= ymin) ? y : -MAX_MAP_GENERATION_LIMIT; +} + + +// Returns -MAX_MAP_GENERATION_LIMIT if not found or if ground is found first +s16 Mapgen::findLiquidSurface(v2s16 p2d, s16 ymin, s16 ymax) +{ + const v3s16 &em = vm->m_area.getExtent(); + u32 i = vm->m_area.index(p2d.X, ymax, p2d.Y); + s16 y; + + for (y = ymax; y >= ymin; y--) { + MapNode &n = vm->m_data[i]; + if (ndef->get(n).walkable) + return -MAX_MAP_GENERATION_LIMIT; + + if (ndef->get(n).isLiquid()) + break; + + VoxelArea::add_y(em, i, -1); + } + return (y >= ymin) ? y : -MAX_MAP_GENERATION_LIMIT; +} + + +void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) +{ + if (!heightmap) + return; + + //TimeTaker t("Mapgen::updateHeightmap", NULL, PRECISION_MICRO); + int index = 0; + for (s16 z = nmin.Z; z <= nmax.Z; z++) { + for (s16 x = nmin.X; x <= nmax.X; x++, index++) { + s16 y = findGroundLevel(v2s16(x, z), nmin.Y, nmax.Y); + + heightmap[index] = y; + } + } +} + + +void Mapgen::getSurfaces(v2s16 p2d, s16 ymin, s16 ymax, + std::vector<s16> &floors, std::vector<s16> &ceilings) +{ + const v3s16 &em = vm->m_area.getExtent(); + + bool is_walkable = false; + u32 vi = vm->m_area.index(p2d.X, ymax, p2d.Y); + MapNode mn_max = vm->m_data[vi]; + bool walkable_above = ndef->get(mn_max).walkable; + VoxelArea::add_y(em, vi, -1); + + for (s16 y = ymax - 1; y >= ymin; y--) { + MapNode mn = vm->m_data[vi]; + is_walkable = ndef->get(mn).walkable; + + if (is_walkable && !walkable_above) { + floors.push_back(y); + } else if (!is_walkable && walkable_above) { + ceilings.push_back(y + 1); + } + + VoxelArea::add_y(em, vi, -1); + walkable_above = is_walkable; + } +} + + +inline bool Mapgen::isLiquidHorizontallyFlowable(u32 vi, v3s16 em) +{ + u32 vi_neg_x = vi; + VoxelArea::add_x(em, vi_neg_x, -1); + if (vm->m_data[vi_neg_x].getContent() != CONTENT_IGNORE) { + const ContentFeatures &c_nx = ndef->get(vm->m_data[vi_neg_x]); + if (c_nx.floodable && !c_nx.isLiquid()) + return true; + } + u32 vi_pos_x = vi; + VoxelArea::add_x(em, vi_pos_x, +1); + if (vm->m_data[vi_pos_x].getContent() != CONTENT_IGNORE) { + const ContentFeatures &c_px = ndef->get(vm->m_data[vi_pos_x]); + if (c_px.floodable && !c_px.isLiquid()) + return true; + } + u32 vi_neg_z = vi; + VoxelArea::add_z(em, vi_neg_z, -1); + if (vm->m_data[vi_neg_z].getContent() != CONTENT_IGNORE) { + const ContentFeatures &c_nz = ndef->get(vm->m_data[vi_neg_z]); + if (c_nz.floodable && !c_nz.isLiquid()) + return true; + } + u32 vi_pos_z = vi; + VoxelArea::add_z(em, vi_pos_z, +1); + if (vm->m_data[vi_pos_z].getContent() != CONTENT_IGNORE) { + const ContentFeatures &c_pz = ndef->get(vm->m_data[vi_pos_z]); + if (c_pz.floodable && !c_pz.isLiquid()) + return true; + } + return false; +} + +void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax) +{ + bool isignored, isliquid, wasignored, wasliquid, waschecked, waspushed; + const v3s16 &em = vm->m_area.getExtent(); + + for (s16 z = nmin.Z + 1; z <= nmax.Z - 1; z++) + for (s16 x = nmin.X + 1; x <= nmax.X - 1; x++) { + wasignored = true; + wasliquid = false; + waschecked = false; + waspushed = false; + + u32 vi = vm->m_area.index(x, nmax.Y, z); + for (s16 y = nmax.Y; y >= nmin.Y; y--) { + isignored = vm->m_data[vi].getContent() == CONTENT_IGNORE; + isliquid = ndef->get(vm->m_data[vi]).isLiquid(); + + if (isignored || wasignored || isliquid == wasliquid) { + // Neither topmost node of liquid column nor topmost node below column + waschecked = false; + waspushed = false; + } else if (isliquid) { + // This is the topmost node in the column + bool ispushed = false; + if (isLiquidHorizontallyFlowable(vi, em)) { + trans_liquid->push_back(v3s16(x, y, z)); + ispushed = true; + } + // Remember waschecked and waspushed to avoid repeated + // checks/pushes in case the column consists of only this node + waschecked = true; + waspushed = ispushed; + } else { + // This is the topmost node below a liquid column + u32 vi_above = vi; + VoxelArea::add_y(em, vi_above, 1); + if (!waspushed && (ndef->get(vm->m_data[vi]).floodable || + (!waschecked && isLiquidHorizontallyFlowable(vi_above, em)))) { + // Push back the lowest node in the column which is one + // node above this one + trans_liquid->push_back(v3s16(x, y + 1, z)); + } + } + + wasliquid = isliquid; + wasignored = isignored; + VoxelArea::add_y(em, vi, -1); + } + } +} + + +void Mapgen::setLighting(u8 light, v3s16 nmin, v3s16 nmax) +{ + ScopeProfiler sp(g_profiler, "EmergeThread: update lighting", SPT_AVG); + VoxelArea a(nmin, nmax); + + for (int z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) { + for (int y = a.MinEdge.Y; y <= a.MaxEdge.Y; y++) { + u32 i = vm->m_area.index(a.MinEdge.X, y, z); + for (int x = a.MinEdge.X; x <= a.MaxEdge.X; x++, i++) + vm->m_data[i].param1 = light; + } + } +} + + +void Mapgen::lightSpread(VoxelArea &a, std::queue<std::pair<v3s16, u8>> &queue, + const v3s16 &p, u8 light) +{ + if (light <= 1 || !a.contains(p)) + return; + + u32 vi = vm->m_area.index(p); + MapNode &n = vm->m_data[vi]; + + // Decay light in each of the banks separately + u8 light_day = light & 0x0F; + if (light_day > 0) + light_day -= 0x01; + + u8 light_night = light & 0xF0; + if (light_night > 0) + light_night -= 0x10; + + // Bail out only if we have no more light from either bank to propogate, or + // we hit a solid block that light cannot pass through. + if ((light_day <= (n.param1 & 0x0F) && + light_night <= (n.param1 & 0xF0)) || + !ndef->get(n).light_propagates) + return; + + // MYMAX still needed here because we only exit early if both banks have + // nothing to propagate anymore. + light = MYMAX(light_day, n.param1 & 0x0F) | + MYMAX(light_night, n.param1 & 0xF0); + + n.param1 = light; + + // add to queue + queue.emplace(p, light); +} + + +void Mapgen::calcLighting(v3s16 nmin, v3s16 nmax, v3s16 full_nmin, v3s16 full_nmax, + bool propagate_shadow) +{ + ScopeProfiler sp(g_profiler, "EmergeThread: update lighting", SPT_AVG); + + propagateSunlight(nmin, nmax, propagate_shadow); + spreadLight(full_nmin, full_nmax); +} + + +void Mapgen::propagateSunlight(v3s16 nmin, v3s16 nmax, bool propagate_shadow) +{ + //TimeTaker t("propagateSunlight"); + VoxelArea a(nmin, nmax); + bool block_is_underground = (water_level >= nmax.Y); + const v3s16 &em = vm->m_area.getExtent(); + + // NOTE: Direct access to the low 4 bits of param1 is okay here because, + // by definition, sunlight will never be in the night lightbank. + + for (int z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) { + for (int x = a.MinEdge.X; x <= a.MaxEdge.X; x++) { + // see if we can get a light value from the overtop + u32 i = vm->m_area.index(x, a.MaxEdge.Y + 1, z); + if (vm->m_data[i].getContent() == CONTENT_IGNORE) { + if (block_is_underground) + continue; + } else if ((vm->m_data[i].param1 & 0x0F) != LIGHT_SUN && + propagate_shadow) { + continue; + } + VoxelArea::add_y(em, i, -1); + + for (int y = a.MaxEdge.Y; y >= a.MinEdge.Y; y--) { + MapNode &n = vm->m_data[i]; + if (!ndef->get(n).sunlight_propagates) + break; + n.param1 = LIGHT_SUN; + VoxelArea::add_y(em, i, -1); + } + } + } + //printf("propagateSunlight: %dms\n", t.stop()); +} + + +void Mapgen::spreadLight(const v3s16 &nmin, const v3s16 &nmax) +{ + //TimeTaker t("spreadLight"); + std::queue<std::pair<v3s16, u8>> queue; + VoxelArea a(nmin, nmax); + + for (int z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) { + for (int y = a.MinEdge.Y; y <= a.MaxEdge.Y; y++) { + u32 i = vm->m_area.index(a.MinEdge.X, y, z); + for (int x = a.MinEdge.X; x <= a.MaxEdge.X; x++, i++) { + MapNode &n = vm->m_data[i]; + if (n.getContent() == CONTENT_IGNORE) + continue; + + const ContentFeatures &cf = ndef->get(n); + if (!cf.light_propagates) + continue; + + // TODO(hmmmmm): Abstract away direct param1 accesses with a + // wrapper, but something lighter than MapNode::get/setLight + + u8 light_produced = cf.light_source; + if (light_produced) + n.param1 = light_produced | (light_produced << 4); + + u8 light = n.param1; + if (light) { + const v3s16 p(x, y, z); + // spread to all 6 neighbor nodes + for (const auto &dir : g_6dirs) + lightSpread(a, queue, p + dir, light); + } + } + } + } + + while (!queue.empty()) { + const auto &i = queue.front(); + // spread to all 6 neighbor nodes + for (const auto &dir : g_6dirs) + lightSpread(a, queue, i.first + dir, i.second); + queue.pop(); + } + + //printf("spreadLight: %lums\n", t.stop()); +} + + +//// +//// MapgenBasic +//// + +MapgenBasic::MapgenBasic(int mapgenid, MapgenParams *params, EmergeParams *emerge) + : Mapgen(mapgenid, params, emerge) +{ + this->m_emerge = emerge; + this->m_bmgr = emerge->biomemgr; + + //// Here, 'stride' refers to the number of elements needed to skip to index + //// an adjacent element for that coordinate in noise/height/biome maps + //// (*not* vmanip content map!) + + // Note there is no X stride explicitly defined. Items adjacent in the X + // coordinate are assumed to be adjacent in memory as well (i.e. stride of 1). + + // Number of elements to skip to get to the next Y coordinate + this->ystride = csize.X; + + // Number of elements to skip to get to the next Z coordinate + this->zstride = csize.X * csize.Y; + + // Z-stride value for maps oversized for 1-down overgeneration + this->zstride_1d = csize.X * (csize.Y + 1); + + // Z-stride value for maps oversized for 1-up 1-down overgeneration + this->zstride_1u1d = csize.X * (csize.Y + 2); + + //// Allocate heightmap + this->heightmap = new s16[csize.X * csize.Z]; + + //// Initialize biome generator + biomegen = emerge->biomegen; + biomegen->assertChunkSize(csize); + biomemap = biomegen->biomemap; + + //// Look up some commonly used content + c_stone = ndef->getId("mapgen_stone"); + c_water_source = ndef->getId("mapgen_water_source"); + c_river_water_source = ndef->getId("mapgen_river_water_source"); + c_lava_source = ndef->getId("mapgen_lava_source"); + c_cobble = ndef->getId("mapgen_cobble"); + + // Fall back to more basic content if not defined. + // Lava falls back to water as both are suitable as cave liquids. + if (c_lava_source == CONTENT_IGNORE) + c_lava_source = c_water_source; + + if (c_stone == CONTENT_IGNORE) + errorstream << "Mapgen: Mapgen alias 'mapgen_stone' is invalid!" << std::endl; + if (c_water_source == CONTENT_IGNORE) + errorstream << "Mapgen: Mapgen alias 'mapgen_water_source' is invalid!" << std::endl; + if (c_river_water_source == CONTENT_IGNORE) + warningstream << "Mapgen: Mapgen alias 'mapgen_river_water_source' is invalid!" << std::endl; +} + + +MapgenBasic::~MapgenBasic() +{ + delete []heightmap; + + delete m_emerge; // destroying EmergeParams is our responsibility +} + + +void MapgenBasic::generateBiomes() +{ + // can't generate biomes without a biome generator! + assert(biomegen); + assert(biomemap); + + const v3s16 &em = vm->m_area.getExtent(); + u32 index = 0; + + noise_filler_depth->perlinMap2D(node_min.X, node_min.Z); + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index++) { + Biome *biome = NULL; + biome_t water_biome_index = 0; + u16 depth_top = 0; + u16 base_filler = 0; + u16 depth_water_top = 0; + u16 depth_riverbed = 0; + s16 biome_y_min = -MAX_MAP_GENERATION_LIMIT; + u32 vi = vm->m_area.index(x, node_max.Y, z); + + // Check node at base of mapchunk above, either a node of a previously + // generated mapchunk or if not, a node of overgenerated base terrain. + content_t c_above = vm->m_data[vi + em.X].getContent(); + bool air_above = c_above == CONTENT_AIR; + bool river_water_above = c_above == c_river_water_source; + bool water_above = c_above == c_water_source || river_water_above; + + biomemap[index] = BIOME_NONE; + + // If there is air or water above enable top/filler placement, otherwise force + // nplaced to stone level by setting a number exceeding any possible filler depth. + u16 nplaced = (air_above || water_above) ? 0 : U16_MAX; + + for (s16 y = node_max.Y; y >= node_min.Y; y--) { + content_t c = vm->m_data[vi].getContent(); + // Biome is (re)calculated: + // 1. At the surface of stone below air or water. + // 2. At the surface of water below air. + // 3. When stone or water is detected but biome has not yet been calculated. + // 4. When stone or water is detected just below a biome's lower limit. + bool is_stone_surface = (c == c_stone) && + (air_above || water_above || !biome || y < biome_y_min); // 1, 3, 4 + + bool is_water_surface = + (c == c_water_source || c == c_river_water_source) && + (air_above || !biome || y < biome_y_min); // 2, 3, 4 + + if (is_stone_surface || is_water_surface) { + // (Re)calculate biome + biome = biomegen->getBiomeAtIndex(index, v3s16(x, y, z)); + + // Add biome to biomemap at first stone surface detected + if (biomemap[index] == BIOME_NONE && is_stone_surface) + biomemap[index] = biome->index; + + // Store biome of first water surface detected, as a fallback + // entry for the biomemap. + if (water_biome_index == 0 && is_water_surface) + water_biome_index = biome->index; + + depth_top = biome->depth_top; + base_filler = MYMAX(depth_top + + biome->depth_filler + + noise_filler_depth->result[index], 0.0f); + depth_water_top = biome->depth_water_top; + depth_riverbed = biome->depth_riverbed; + biome_y_min = biome->min_pos.Y; + } + + if (c == c_stone) { + content_t c_below = vm->m_data[vi - em.X].getContent(); + + // If the node below isn't solid, make this node stone, so that + // any top/filler nodes above are structurally supported. + // This is done by aborting the cycle of top/filler placement + // immediately by forcing nplaced to stone level. + if (c_below == CONTENT_AIR + || c_below == c_water_source + || c_below == c_river_water_source) + nplaced = U16_MAX; + + if (river_water_above) { + if (nplaced < depth_riverbed) { + vm->m_data[vi] = MapNode(biome->c_riverbed); + nplaced++; + } else { + nplaced = U16_MAX; // Disable top/filler placement + river_water_above = false; + } + } else if (nplaced < depth_top) { + vm->m_data[vi] = MapNode(biome->c_top); + nplaced++; + } else if (nplaced < base_filler) { + vm->m_data[vi] = MapNode(biome->c_filler); + nplaced++; + } else { + vm->m_data[vi] = MapNode(biome->c_stone); + nplaced = U16_MAX; // Disable top/filler placement + } + + air_above = false; + water_above = false; + } else if (c == c_water_source) { + vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top)) + ? biome->c_water_top : biome->c_water); + nplaced = 0; // Enable top/filler placement for next surface + air_above = false; + water_above = true; + } else if (c == c_river_water_source) { + vm->m_data[vi] = MapNode(biome->c_river_water); + nplaced = 0; // Enable riverbed placement for next surface + air_above = false; + water_above = true; + river_water_above = true; + } else if (c == CONTENT_AIR) { + nplaced = 0; // Enable top/filler placement for next surface + air_above = true; + water_above = false; + } else { // Possible various nodes overgenerated from neighbouring mapchunks + nplaced = U16_MAX; // Disable top/filler placement + air_above = false; + water_above = false; + } + + VoxelArea::add_y(em, vi, -1); + } + // If no stone surface detected in mapchunk column and a water surface + // biome fallback exists, add it to the biomemap. This avoids water + // surface decorations failing in deep water. + if (biomemap[index] == BIOME_NONE && water_biome_index != 0) + biomemap[index] = water_biome_index; + } +} + + +void MapgenBasic::dustTopNodes() +{ + if (node_max.Y < water_level) + return; + + const v3s16 &em = vm->m_area.getExtent(); + u32 index = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index++) { + Biome *biome = (Biome *)m_bmgr->getRaw(biomemap[index]); + + if (biome->c_dust == CONTENT_IGNORE) + continue; + + // Check if mapchunk above has generated, if so, drop dust from 16 nodes + // above current mapchunk top, above decorations that will extend above + // the current mapchunk. If the mapchunk above has not generated, it + // will provide this required dust when it does. + u32 vi = vm->m_area.index(x, full_node_max.Y, z); + content_t c_full_max = vm->m_data[vi].getContent(); + s16 y_start; + + if (c_full_max == CONTENT_AIR) { + y_start = full_node_max.Y - 1; + } else if (c_full_max == CONTENT_IGNORE) { + vi = vm->m_area.index(x, node_max.Y + 1, z); + content_t c_max = vm->m_data[vi].getContent(); + + if (c_max == CONTENT_AIR) + y_start = node_max.Y; + else + continue; + } else { + continue; + } + + vi = vm->m_area.index(x, y_start, z); + for (s16 y = y_start; y >= node_min.Y - 1; y--) { + if (vm->m_data[vi].getContent() != CONTENT_AIR) + break; + + VoxelArea::add_y(em, vi, -1); + } + + content_t c = vm->m_data[vi].getContent(); + NodeDrawType dtype = ndef->get(c).drawtype; + // Only place on cubic, walkable, non-dust nodes. + // Dust check needed due to avoid double layer of dust caused by + // dropping dust from 16 nodes above mapchunk top. + if ((dtype == NDT_NORMAL || + dtype == NDT_ALLFACES || + dtype == NDT_ALLFACES_OPTIONAL || + dtype == NDT_GLASSLIKE || + dtype == NDT_GLASSLIKE_FRAMED || + dtype == NDT_GLASSLIKE_FRAMED_OPTIONAL) && + ndef->get(c).walkable && c != biome->c_dust) { + VoxelArea::add_y(em, vi, 1); + vm->m_data[vi] = MapNode(biome->c_dust); + } + } +} + + +void MapgenBasic::generateCavesNoiseIntersection(s16 max_stone_y) +{ + // cave_width >= 10 is used to disable generation and avoid the intensive + // 3D noise calculations. Tunnels already have zero width when cave_width > 1. + if (node_min.Y > max_stone_y || cave_width >= 10.0f) + return; + + CavesNoiseIntersection caves_noise(ndef, m_bmgr, csize, + &np_cave1, &np_cave2, seed, cave_width); + + caves_noise.generateCaves(vm, node_min, node_max, biomemap); +} + + +void MapgenBasic::generateCavesRandomWalk(s16 max_stone_y, s16 large_cave_ymax) +{ + if (node_min.Y > max_stone_y) + return; + + PseudoRandom ps(blockseed + 21343); + // Small randomwalk caves + u32 num_small_caves = ps.range(small_cave_num_min, small_cave_num_max); + + for (u32 i = 0; i < num_small_caves; i++) { + CavesRandomWalk cave(ndef, &gennotify, seed, water_level, + c_water_source, c_lava_source, large_cave_flooded, biomegen); + cave.makeCave(vm, node_min, node_max, &ps, false, max_stone_y, heightmap); + } + + if (node_max.Y > large_cave_ymax) + return; + + // Large randomwalk caves below 'large_cave_ymax'. + // 'large_cave_ymax' can differ from the 'large_cave_depth' mapgen parameter, + // it is set to world base to disable large caves in or near caverns. + u32 num_large_caves = ps.range(large_cave_num_min, large_cave_num_max); + + for (u32 i = 0; i < num_large_caves; i++) { + CavesRandomWalk cave(ndef, &gennotify, seed, water_level, + c_water_source, c_lava_source, large_cave_flooded, biomegen); + cave.makeCave(vm, node_min, node_max, &ps, true, max_stone_y, heightmap); + } +} + + +bool MapgenBasic::generateCavernsNoise(s16 max_stone_y) +{ + if (node_min.Y > max_stone_y || node_min.Y > cavern_limit) + return false; + + CavernsNoise caverns_noise(ndef, csize, &np_cavern, + seed, cavern_limit, cavern_taper, cavern_threshold); + + return caverns_noise.generateCaverns(vm, node_min, node_max); +} + + +void MapgenBasic::generateDungeons(s16 max_stone_y) +{ + if (node_min.Y > max_stone_y || node_min.Y > dungeon_ymax || + node_max.Y < dungeon_ymin) + return; + + u16 num_dungeons = std::fmax(std::floor( + NoisePerlin3D(&np_dungeons, node_min.X, node_min.Y, node_min.Z, seed)), 0.0f); + if (num_dungeons == 0) + return; + + PseudoRandom ps(blockseed + 70033); + + DungeonParams dp; + + dp.np_alt_wall = + NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0); + + dp.seed = seed; + dp.only_in_ground = true; + dp.num_dungeons = num_dungeons; + dp.notifytype = GENNOTIFY_DUNGEON; + dp.num_rooms = ps.range(2, 16); + dp.room_size_min = v3s16(5, 5, 5); + dp.room_size_max = v3s16(12, 6, 12); + dp.room_size_large_min = v3s16(12, 6, 12); + dp.room_size_large_max = v3s16(16, 16, 16); + dp.large_room_chance = (ps.range(1, 4) == 1) ? 8 : 0; + dp.diagonal_dirs = ps.range(1, 8) == 1; + // Diagonal corridors must have 'hole' width >=2 to be passable + u8 holewidth = (dp.diagonal_dirs) ? 2 : ps.range(1, 2); + dp.holesize = v3s16(holewidth, 3, holewidth); + dp.corridor_len_min = 1; + dp.corridor_len_max = 13; + + // Get biome at mapchunk midpoint + v3s16 chunk_mid = node_min + (node_max - node_min) / v3s16(2, 2, 2); + Biome *biome = (Biome *)biomegen->getBiomeAtPoint(chunk_mid); + + // Use biome-defined dungeon nodes if defined + if (biome->c_dungeon != CONTENT_IGNORE) { + dp.c_wall = biome->c_dungeon; + // If 'node_dungeon_alt' is not defined by biome, it and dp.c_alt_wall + // become CONTENT_IGNORE which skips the alt wall node placement loop in + // dungeongen.cpp. + dp.c_alt_wall = biome->c_dungeon_alt; + // Stairs fall back to 'c_dungeon' if not defined by biome + dp.c_stair = (biome->c_dungeon_stair != CONTENT_IGNORE) ? + biome->c_dungeon_stair : biome->c_dungeon; + // Fallback to using cobble mapgen alias if defined + } else if (c_cobble != CONTENT_IGNORE) { + dp.c_wall = c_cobble; + dp.c_alt_wall = CONTENT_IGNORE; + dp.c_stair = c_cobble; + // Fallback to using biome-defined stone + } else { + dp.c_wall = biome->c_stone; + dp.c_alt_wall = CONTENT_IGNORE; + dp.c_stair = biome->c_stone; + } + + DungeonGen dgen(ndef, &gennotify, &dp); + dgen.generate(vm, blockseed, full_node_min, full_node_max); +} + + +//// +//// GenerateNotifier +//// + +GenerateNotifier::GenerateNotifier(u32 notify_on, + const std::set<u32> *notify_on_deco_ids) +{ + m_notify_on = notify_on; + m_notify_on_deco_ids = notify_on_deco_ids; +} + + +bool GenerateNotifier::addEvent(GenNotifyType type, v3s16 pos, u32 id) +{ + if (!(m_notify_on & (1 << type))) + return false; + + if (type == GENNOTIFY_DECORATION && + m_notify_on_deco_ids->find(id) == m_notify_on_deco_ids->cend()) + return false; + + GenNotifyEvent gne; + gne.type = type; + gne.pos = pos; + gne.id = id; + m_notify_events.push_back(gne); + + return true; +} + + +void GenerateNotifier::getEvents( + std::map<std::string, std::vector<v3s16> > &event_map) +{ + std::list<GenNotifyEvent>::iterator it; + + for (it = m_notify_events.begin(); it != m_notify_events.end(); ++it) { + GenNotifyEvent &gn = *it; + std::string name = (gn.type == GENNOTIFY_DECORATION) ? + "decoration#"+ itos(gn.id) : + flagdesc_gennotify[gn.type].name; + + event_map[name].push_back(gn.pos); + } +} + + +void GenerateNotifier::clearEvents() +{ + m_notify_events.clear(); +} + + +//// +//// MapgenParams +//// + + +MapgenParams::~MapgenParams() +{ + delete bparams; +} + + +void MapgenParams::readParams(const Settings *settings) +{ + // should always be used via MapSettingsManager + assert(settings != g_settings); + + std::string seed_str; + if (settings->getNoEx("seed", seed_str)) { + if (!seed_str.empty()) + seed = read_seed(seed_str.c_str()); + else + myrand_bytes(&seed, sizeof(seed)); + } + + std::string mg_name; + if (settings->getNoEx("mg_name", mg_name)) { + mgtype = Mapgen::getMapgenType(mg_name); + if (mgtype == MAPGEN_INVALID) + mgtype = MAPGEN_DEFAULT; + } + + settings->getS16NoEx("water_level", water_level); + settings->getS16NoEx("mapgen_limit", mapgen_limit); + settings->getS16NoEx("chunksize", chunksize); + settings->getFlagStrNoEx("mg_flags", flags, flagdesc_mapgen); + + chunksize = rangelim(chunksize, 1, 10); + + delete bparams; + bparams = BiomeManager::createBiomeParams(BIOMEGEN_ORIGINAL); + if (bparams) { + bparams->readParams(settings); + bparams->seed = seed; + } +} + + +void MapgenParams::writeParams(Settings *settings) const +{ + settings->set("mg_name", Mapgen::getMapgenName(mgtype)); + settings->setU64("seed", seed); + settings->setS16("water_level", water_level); + settings->setS16("mapgen_limit", mapgen_limit); + settings->setS16("chunksize", chunksize); + settings->setFlagStr("mg_flags", flags, flagdesc_mapgen); + + if (bparams) + bparams->writeParams(settings); +} + + +// Calculate exact edges of the outermost mapchunks that are within the +// set 'mapgen_limit'. +void MapgenParams::calcMapgenEdges() +{ + // Central chunk offset, in blocks + s16 ccoff_b = -chunksize / 2; + // Chunksize, in nodes + s32 csize_n = chunksize * MAP_BLOCKSIZE; + // Minp/maxp of central chunk, in nodes + s16 ccmin = ccoff_b * MAP_BLOCKSIZE; + s16 ccmax = ccmin + csize_n - 1; + // Fullminp/fullmaxp of central chunk, in nodes + s16 ccfmin = ccmin - MAP_BLOCKSIZE; + s16 ccfmax = ccmax + MAP_BLOCKSIZE; + // Effective mapgen limit, in blocks + // Uses same calculation as ServerMap::blockpos_over_mapgen_limit(v3s16 p) + s16 mapgen_limit_b = rangelim(mapgen_limit, + 0, MAX_MAP_GENERATION_LIMIT) / MAP_BLOCKSIZE; + // Effective mapgen limits, in nodes + s16 mapgen_limit_min = -mapgen_limit_b * MAP_BLOCKSIZE; + s16 mapgen_limit_max = (mapgen_limit_b + 1) * MAP_BLOCKSIZE - 1; + // Number of complete chunks from central chunk fullminp/fullmaxp + // to effective mapgen limits. + s16 numcmin = MYMAX((ccfmin - mapgen_limit_min) / csize_n, 0); + s16 numcmax = MYMAX((mapgen_limit_max - ccfmax) / csize_n, 0); + // Mapgen edges, in nodes + mapgen_edge_min = ccmin - numcmin * csize_n; + mapgen_edge_max = ccmax + numcmax * csize_n; + + m_mapgen_edges_calculated = true; +} + + +s32 MapgenParams::getSpawnRangeMax() +{ + if (!m_mapgen_edges_calculated) + calcMapgenEdges(); + + return MYMIN(-mapgen_edge_min, mapgen_edge_max); +} diff --git a/src/mapgen/mapgen.h b/src/mapgen/mapgen.h new file mode 100644 index 0000000..ef5de60 --- /dev/null +++ b/src/mapgen/mapgen.h @@ -0,0 +1,331 @@ +/* +Minetest +Copyright (C) 2010-2020 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2015-2020 paramat +Copyright (C) 2013-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "noise.h" +#include "nodedef.h" +#include "util/string.h" +#include "util/container.h" + +#define MAPGEN_DEFAULT MAPGEN_V7 +#define MAPGEN_DEFAULT_NAME "v7" + +/////////////////// Mapgen flags +#define MG_CAVES 0x02 +#define MG_DUNGEONS 0x04 +#define MG_LIGHT 0x10 +#define MG_DECORATIONS 0x20 +#define MG_BIOMES 0x40 +#define MG_ORES 0x80 + +typedef u16 biome_t; // copy from mg_biome.h to avoid an unnecessary include + +class Settings; +class MMVManip; +class NodeDefManager; + +extern FlagDesc flagdesc_mapgen[]; +extern FlagDesc flagdesc_gennotify[]; + +class Biome; +class BiomeGen; +struct BiomeParams; +class BiomeManager; +class EmergeParams; +class EmergeManager; +class MapBlock; +class VoxelManipulator; +struct BlockMakeData; +class VoxelArea; +class Map; + +enum MapgenObject { + MGOBJ_VMANIP, + MGOBJ_HEIGHTMAP, + MGOBJ_BIOMEMAP, + MGOBJ_HEATMAP, + MGOBJ_HUMIDMAP, + MGOBJ_GENNOTIFY +}; + +enum GenNotifyType { + GENNOTIFY_DUNGEON, + GENNOTIFY_TEMPLE, + GENNOTIFY_CAVE_BEGIN, + GENNOTIFY_CAVE_END, + GENNOTIFY_LARGECAVE_BEGIN, + GENNOTIFY_LARGECAVE_END, + GENNOTIFY_DECORATION, + NUM_GENNOTIFY_TYPES +}; + +struct GenNotifyEvent { + GenNotifyType type; + v3s16 pos; + u32 id; +}; + +class GenerateNotifier { +public: + // Use only for temporary Mapgen objects with no map generation! + GenerateNotifier() = default; + GenerateNotifier(u32 notify_on, const std::set<u32> *notify_on_deco_ids); + + bool addEvent(GenNotifyType type, v3s16 pos, u32 id=0); + void getEvents(std::map<std::string, std::vector<v3s16> > &event_map); + void clearEvents(); + +private: + u32 m_notify_on = 0; + const std::set<u32> *m_notify_on_deco_ids = nullptr; + std::list<GenNotifyEvent> m_notify_events; +}; + +// Order must match the order of 'static MapgenDesc g_reg_mapgens[]' in mapgen.cpp +enum MapgenType { + MAPGEN_V7, + MAPGEN_VALLEYS, + MAPGEN_CARPATHIAN, + MAPGEN_V5, + MAPGEN_FLAT, + MAPGEN_FRACTAL, + MAPGEN_SINGLENODE, + MAPGEN_V6, + MAPGEN_INVALID, +}; + +struct MapgenParams { + MapgenParams() = default; + virtual ~MapgenParams(); + + MapgenType mgtype = MAPGEN_DEFAULT; + s16 chunksize = 5; + u64 seed = 0; + s16 water_level = 1; + s16 mapgen_limit = MAX_MAP_GENERATION_LIMIT; + // Flags set in readParams + u32 flags = 0; + u32 spflags = 0; + + BiomeParams *bparams = nullptr; + + s16 mapgen_edge_min = -MAX_MAP_GENERATION_LIMIT; + s16 mapgen_edge_max = MAX_MAP_GENERATION_LIMIT; + + virtual void readParams(const Settings *settings); + virtual void writeParams(Settings *settings) const; + // Default settings for g_settings such as flags + virtual void setDefaultSettings(Settings *settings) {}; + + s32 getSpawnRangeMax(); + +private: + void calcMapgenEdges(); + bool m_mapgen_edges_calculated = false; +}; + + +/* + Generic interface for map generators. All mapgens must inherit this class. + If a feature exposed by a public member pointer is not supported by a + certain mapgen, it must be set to NULL. + + Apart from makeChunk, getGroundLevelAtPoint, and getSpawnLevelAtPoint, all + methods can be used by constructing a Mapgen base class and setting the + appropriate public members (e.g. vm, ndef, and so on). +*/ +class Mapgen { +public: + s32 seed = 0; + int water_level = 0; + int mapgen_limit = 0; + u32 flags = 0; + bool generating = false; + int id = -1; + + MMVManip *vm = nullptr; + const NodeDefManager *ndef = nullptr; + + u32 blockseed; + s16 *heightmap = nullptr; + biome_t *biomemap = nullptr; + v3s16 csize; + + BiomeGen *biomegen = nullptr; + GenerateNotifier gennotify; + + Mapgen() = default; + Mapgen(int mapgenid, MapgenParams *params, EmergeParams *emerge); + virtual ~Mapgen() = default; + DISABLE_CLASS_COPY(Mapgen); + + virtual MapgenType getType() const { return MAPGEN_INVALID; } + + static u32 getBlockSeed(v3s16 p, s32 seed); + static u32 getBlockSeed2(v3s16 p, s32 seed); + s16 findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax); + s16 findLiquidSurface(v2s16 p2d, s16 ymin, s16 ymax); + void updateHeightmap(v3s16 nmin, v3s16 nmax); + void getSurfaces(v2s16 p2d, s16 ymin, s16 ymax, + std::vector<s16> &floors, std::vector<s16> &ceilings); + + void updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax); + + /** + * Set light in entire area to fixed value. + * @param light Light value (contains both banks) + * @param nmin Area to operate on + * @param nmax ^ + */ + void setLighting(u8 light, v3s16 nmin, v3s16 nmax); + /** + * Run all lighting calculations. + * @param nmin Area to spread sunlight in + * @param nmax ^ + * @param full_nmin Area to recalculate light in + * @param full_nmax ^ + * @param propagate_shadow see propagateSunlight() + */ + void calcLighting(v3s16 nmin, v3s16 nmax, v3s16 full_nmin, v3s16 full_nmax, + bool propagate_shadow = true); + /** + * Spread sunlight from the area above downwards. + * Note that affected nodes have their night bank cleared so you want to + * run a light spread afterwards. + * @param nmin Area to operate on + * @param nmax ^ + * @param propagate_shadow Ignore obstructions above and spread sun anyway + */ + void propagateSunlight(v3s16 nmin, v3s16 nmax, bool propagate_shadow); + /** + * Spread light in the given area. + * Artificial light is taken from nodedef, sunlight must already be set. + * @param nmin Area to operate on + * @param nmax ^ + */ + void spreadLight(const v3s16 &nmin, const v3s16 &nmax); + + virtual void makeChunk(BlockMakeData *data) {} + virtual int getGroundLevelAtPoint(v2s16 p) { return 0; } + + // getSpawnLevelAtPoint() is a function within each mapgen that returns a + // suitable y co-ordinate for player spawn ('suitable' usually meaning + // within 16 nodes of water_level). If a suitable spawn level cannot be + // found at the specified (X, Z) 'MAX_MAP_GENERATION_LIMIT' is returned to + // signify this and to cause Server::findSpawnPos() to try another (X, Z). + virtual int getSpawnLevelAtPoint(v2s16 p) { return 0; } + + // Mapgen management functions + static MapgenType getMapgenType(const std::string &mgname); + static const char *getMapgenName(MapgenType mgtype); + static Mapgen *createMapgen(MapgenType mgtype, MapgenParams *params, + EmergeParams *emerge); + static MapgenParams *createMapgenParams(MapgenType mgtype); + static void getMapgenNames(std::vector<const char *> *mgnames, bool include_hidden); + static void setDefaultSettings(Settings *settings); + +private: + /** + * Spread light to the node at the given position, add to queue if changed. + * The given light value is diminished once. + * @param a VoxelArea being operated on + * @param queue Queue for later lightSpread() calls + * @param p Node position + * @param light Light value (contains both banks) + * + */ + void lightSpread(VoxelArea &a, std::queue<std::pair<v3s16, u8>> &queue, + const v3s16 &p, u8 light); + + // isLiquidHorizontallyFlowable() is a helper function for updateLiquid() + // that checks whether there are floodable nodes without liquid beneath + // the node at index vi. + inline bool isLiquidHorizontallyFlowable(u32 vi, v3s16 em); +}; + +/* + MapgenBasic is a Mapgen implementation that handles basic functionality + the majority of conventional mapgens will probably want to use, but isn't + generic enough to be included as part of the base Mapgen class (such as + generating biome terrain over terrain node skeletons, generating caves, + dungeons, etc.) + + Inherit MapgenBasic instead of Mapgen to add this basic functionality to + your mapgen without having to reimplement it. Feel free to override any of + these methods if you desire different or more advanced behavior. + + Note that you must still create your own generateTerrain implementation when + inheriting MapgenBasic. +*/ +class MapgenBasic : public Mapgen { +public: + MapgenBasic(int mapgenid, MapgenParams *params, EmergeParams *emerge); + virtual ~MapgenBasic(); + + virtual void generateBiomes(); + virtual void dustTopNodes(); + virtual void generateCavesNoiseIntersection(s16 max_stone_y); + virtual void generateCavesRandomWalk(s16 max_stone_y, s16 large_cave_ymax); + virtual bool generateCavernsNoise(s16 max_stone_y); + virtual void generateDungeons(s16 max_stone_y); + +protected: + EmergeParams *m_emerge; + BiomeManager *m_bmgr; + + Noise *noise_filler_depth; + + v3s16 node_min; + v3s16 node_max; + v3s16 full_node_min; + v3s16 full_node_max; + + content_t c_stone; + content_t c_water_source; + content_t c_river_water_source; + content_t c_lava_source; + content_t c_cobble; + + int ystride; + int zstride; + int zstride_1d; + int zstride_1u1d; + + u32 spflags; + + NoiseParams np_cave1; + NoiseParams np_cave2; + NoiseParams np_cavern; + NoiseParams np_dungeons; + float cave_width; + float cavern_limit; + float cavern_taper; + float cavern_threshold; + int small_cave_num_min; + int small_cave_num_max; + int large_cave_num_min; + int large_cave_num_max; + float large_cave_flooded; + s16 large_cave_depth; + s16 dungeon_ymin; + s16 dungeon_ymax; +}; diff --git a/src/mapgen/mapgen_carpathian.cpp b/src/mapgen/mapgen_carpathian.cpp new file mode 100644 index 0000000..b3a0bd2 --- /dev/null +++ b/src/mapgen/mapgen_carpathian.cpp @@ -0,0 +1,572 @@ +/* +Minetest +Copyright (C) 2017-2019 vlapsley, Vaughan Lapsley <vlapsley@gmail.com> +Copyright (C) 2017-2019 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include <cmath> +#include "mapgen.h" +#include "voxel.h" +#include "noise.h" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +#include "nodedef.h" +#include "voxelalgorithms.h" +//#include "profiler.h" // For TimeTaker +#include "settings.h" // For g_settings +#include "emerge.h" +#include "dungeongen.h" +#include "cavegen.h" +#include "mg_biome.h" +#include "mg_ore.h" +#include "mg_decoration.h" +#include "mapgen_carpathian.h" + + +FlagDesc flagdesc_mapgen_carpathian[] = { + {"caverns", MGCARPATHIAN_CAVERNS}, + {"rivers", MGCARPATHIAN_RIVERS}, + {NULL, 0} +}; + + +/////////////////////////////////////////////////////////////////////////////// + + +MapgenCarpathian::MapgenCarpathian(MapgenCarpathianParams *params, EmergeParams *emerge) + : MapgenBasic(MAPGEN_CARPATHIAN, params, emerge) +{ + base_level = params->base_level; + river_width = params->river_width; + river_depth = params->river_depth; + valley_width = params->valley_width; + + spflags = params->spflags; + cave_width = params->cave_width; + large_cave_depth = params->large_cave_depth; + small_cave_num_min = params->small_cave_num_min; + small_cave_num_max = params->small_cave_num_max; + large_cave_num_min = params->large_cave_num_min; + large_cave_num_max = params->large_cave_num_max; + large_cave_flooded = params->large_cave_flooded; + cavern_limit = params->cavern_limit; + cavern_taper = params->cavern_taper; + cavern_threshold = params->cavern_threshold; + dungeon_ymin = params->dungeon_ymin; + dungeon_ymax = params->dungeon_ymax; + + grad_wl = 1 - water_level; + + //// 2D Terrain noise + noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); + noise_height1 = new Noise(¶ms->np_height1, seed, csize.X, csize.Z); + noise_height2 = new Noise(¶ms->np_height2, seed, csize.X, csize.Z); + noise_height3 = new Noise(¶ms->np_height3, seed, csize.X, csize.Z); + noise_height4 = new Noise(¶ms->np_height4, seed, csize.X, csize.Z); + noise_hills_terrain = new Noise(¶ms->np_hills_terrain, seed, csize.X, csize.Z); + noise_ridge_terrain = new Noise(¶ms->np_ridge_terrain, seed, csize.X, csize.Z); + noise_step_terrain = new Noise(¶ms->np_step_terrain, seed, csize.X, csize.Z); + noise_hills = new Noise(¶ms->np_hills, seed, csize.X, csize.Z); + noise_ridge_mnt = new Noise(¶ms->np_ridge_mnt, seed, csize.X, csize.Z); + noise_step_mnt = new Noise(¶ms->np_step_mnt, seed, csize.X, csize.Z); + if (spflags & MGCARPATHIAN_RIVERS) + noise_rivers = new Noise(¶ms->np_rivers, seed, csize.X, csize.Z); + + //// 3D terrain noise + // 1 up 1 down overgeneration + noise_mnt_var = new Noise(¶ms->np_mnt_var, seed, csize.X, csize.Y + 2, csize.Z); + + //// Cave noise + MapgenBasic::np_cave1 = params->np_cave1; + MapgenBasic::np_cave2 = params->np_cave2; + MapgenBasic::np_cavern = params->np_cavern; + MapgenBasic::np_dungeons = params->np_dungeons; +} + + +MapgenCarpathian::~MapgenCarpathian() +{ + delete noise_filler_depth; + delete noise_height1; + delete noise_height2; + delete noise_height3; + delete noise_height4; + delete noise_hills_terrain; + delete noise_ridge_terrain; + delete noise_step_terrain; + delete noise_hills; + delete noise_ridge_mnt; + delete noise_step_mnt; + if (spflags & MGCARPATHIAN_RIVERS) + delete noise_rivers; + + delete noise_mnt_var; +} + + +MapgenCarpathianParams::MapgenCarpathianParams(): + np_filler_depth (0, 1, v3f(128, 128, 128), 261, 3, 0.7, 2.0), + np_height1 (0, 5, v3f(251, 251, 251), 9613, 5, 0.5, 2.0), + np_height2 (0, 5, v3f(383, 383, 383), 1949, 5, 0.5, 2.0), + np_height3 (0, 5, v3f(509, 509, 509), 3211, 5, 0.5, 2.0), + np_height4 (0, 5, v3f(631, 631, 631), 1583, 5, 0.5, 2.0), + np_hills_terrain (1, 1, v3f(1301, 1301, 1301), 1692, 5, 0.5, 2.0), + np_ridge_terrain (1, 1, v3f(1889, 1889, 1889), 3568, 5, 0.5, 2.0), + np_step_terrain (1, 1, v3f(1889, 1889, 1889), 4157, 5, 0.5, 2.0), + np_hills (0, 3, v3f(257, 257, 257), 6604, 6, 0.5, 2.0), + np_ridge_mnt (0, 12, v3f(743, 743, 743), 5520, 6, 0.7, 2.0), + np_step_mnt (0, 8, v3f(509, 509, 509), 2590, 6, 0.6, 2.0), + np_rivers (0, 1, v3f(1000, 1000, 1000), 85039, 5, 0.6, 2.0), + np_mnt_var (0, 1, v3f(499, 499, 499), 2490, 5, 0.55, 2.0), + np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0), + np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0), + np_cavern (0, 1, v3f(384, 128, 384), 723, 5, 0.63, 2.0), + np_dungeons (0.9, 0.5, v3f(500, 500, 500), 0, 2, 0.8, 2.0) +{ +} + + +void MapgenCarpathianParams::readParams(const Settings *settings) +{ + settings->getFlagStrNoEx("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian); + + settings->getFloatNoEx("mgcarpathian_base_level", base_level); + settings->getFloatNoEx("mgcarpathian_river_width", river_width); + settings->getFloatNoEx("mgcarpathian_river_depth", river_depth); + settings->getFloatNoEx("mgcarpathian_valley_width", valley_width); + + settings->getFloatNoEx("mgcarpathian_cave_width", cave_width); + settings->getS16NoEx("mgcarpathian_large_cave_depth", large_cave_depth); + settings->getU16NoEx("mgcarpathian_small_cave_num_min", small_cave_num_min); + settings->getU16NoEx("mgcarpathian_small_cave_num_max", small_cave_num_max); + settings->getU16NoEx("mgcarpathian_large_cave_num_min", large_cave_num_min); + settings->getU16NoEx("mgcarpathian_large_cave_num_max", large_cave_num_max); + settings->getFloatNoEx("mgcarpathian_large_cave_flooded", large_cave_flooded); + settings->getS16NoEx("mgcarpathian_cavern_limit", cavern_limit); + settings->getS16NoEx("mgcarpathian_cavern_taper", cavern_taper); + settings->getFloatNoEx("mgcarpathian_cavern_threshold", cavern_threshold); + settings->getS16NoEx("mgcarpathian_dungeon_ymin", dungeon_ymin); + settings->getS16NoEx("mgcarpathian_dungeon_ymax", dungeon_ymax); + + settings->getNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth); + settings->getNoiseParams("mgcarpathian_np_height1", np_height1); + settings->getNoiseParams("mgcarpathian_np_height2", np_height2); + settings->getNoiseParams("mgcarpathian_np_height3", np_height3); + settings->getNoiseParams("mgcarpathian_np_height4", np_height4); + settings->getNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain); + settings->getNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain); + settings->getNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain); + settings->getNoiseParams("mgcarpathian_np_hills", np_hills); + settings->getNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt); + settings->getNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt); + settings->getNoiseParams("mgcarpathian_np_rivers", np_rivers); + settings->getNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var); + settings->getNoiseParams("mgcarpathian_np_cave1", np_cave1); + settings->getNoiseParams("mgcarpathian_np_cave2", np_cave2); + settings->getNoiseParams("mgcarpathian_np_cavern", np_cavern); + settings->getNoiseParams("mgcarpathian_np_dungeons", np_dungeons); +} + + +void MapgenCarpathianParams::writeParams(Settings *settings) const +{ + settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian); + + settings->setFloat("mgcarpathian_base_level", base_level); + settings->setFloat("mgcarpathian_river_width", river_width); + settings->setFloat("mgcarpathian_river_depth", river_depth); + settings->setFloat("mgcarpathian_valley_width", valley_width); + + settings->setFloat("mgcarpathian_cave_width", cave_width); + settings->setS16("mgcarpathian_large_cave_depth", large_cave_depth); + settings->setU16("mgcarpathian_small_cave_num_min", small_cave_num_min); + settings->setU16("mgcarpathian_small_cave_num_max", small_cave_num_max); + settings->setU16("mgcarpathian_large_cave_num_min", large_cave_num_min); + settings->setU16("mgcarpathian_large_cave_num_max", large_cave_num_max); + settings->setFloat("mgcarpathian_large_cave_flooded", large_cave_flooded); + settings->setS16("mgcarpathian_cavern_limit", cavern_limit); + settings->setS16("mgcarpathian_cavern_taper", cavern_taper); + settings->setFloat("mgcarpathian_cavern_threshold", cavern_threshold); + settings->setS16("mgcarpathian_dungeon_ymin", dungeon_ymin); + settings->setS16("mgcarpathian_dungeon_ymax", dungeon_ymax); + + settings->setNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth); + settings->setNoiseParams("mgcarpathian_np_height1", np_height1); + settings->setNoiseParams("mgcarpathian_np_height2", np_height2); + settings->setNoiseParams("mgcarpathian_np_height3", np_height3); + settings->setNoiseParams("mgcarpathian_np_height4", np_height4); + settings->setNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain); + settings->setNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain); + settings->setNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain); + settings->setNoiseParams("mgcarpathian_np_hills", np_hills); + settings->setNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt); + settings->setNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt); + settings->setNoiseParams("mgcarpathian_np_rivers", np_rivers); + settings->setNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var); + settings->setNoiseParams("mgcarpathian_np_cave1", np_cave1); + settings->setNoiseParams("mgcarpathian_np_cave2", np_cave2); + settings->setNoiseParams("mgcarpathian_np_cavern", np_cavern); + settings->setNoiseParams("mgcarpathian_np_dungeons", np_dungeons); +} + + +void MapgenCarpathianParams::setDefaultSettings(Settings *settings) +{ + settings->setDefault("mgcarpathian_spflags", flagdesc_mapgen_carpathian, + MGCARPATHIAN_CAVERNS); +} + +//////////////////////////////////////////////////////////////////////////////// + + +// Lerp function +inline float MapgenCarpathian::getLerp(float noise1, float noise2, float mod) +{ + return noise1 + mod * (noise2 - noise1); +} + +// Steps function +float MapgenCarpathian::getSteps(float noise) +{ + float w = 0.5f; + float k = std::floor(noise / w); + float f = (noise - k * w) / w; + float s = std::fmin(2.f * f, 1.f); + return (k + s) * w; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MapgenCarpathian::makeChunk(BlockMakeData *data) +{ + // Pre-conditions + assert(data->vmanip); + assert(data->nodedef); + + this->generating = true; + this->vm = data->vmanip; + this->ndef = data->nodedef; + + v3s16 blockpos_min = data->blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + node_min = blockpos_min * MAP_BLOCKSIZE; + node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE; + full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + + // Create a block-specific seed + blockseed = getBlockSeed2(full_node_min, seed); + + // Generate terrain + s16 stone_surface_max_y = generateTerrain(); + + // Create heightmap + updateHeightmap(node_min, node_max); + + // Init biome generator, place biome-specific nodes, and build biomemap + if (flags & MG_BIOMES) { + biomegen->calcBiomeNoise(node_min); + generateBiomes(); + } + + // Generate tunnels, caverns and large randomwalk caves + if (flags & MG_CAVES) { + // Generate tunnels first as caverns confuse them + generateCavesNoiseIntersection(stone_surface_max_y); + + // Generate caverns + bool near_cavern = false; + if (spflags & MGCARPATHIAN_CAVERNS) + near_cavern = generateCavernsNoise(stone_surface_max_y); + + // Generate large randomwalk caves + if (near_cavern) + // Disable large randomwalk caves in this mapchunk by setting + // 'large cave depth' to world base. Avoids excessive liquid in + // large caverns and floating blobs of overgenerated liquid. + generateCavesRandomWalk(stone_surface_max_y, + -MAX_MAP_GENERATION_LIMIT); + else + generateCavesRandomWalk(stone_surface_max_y, large_cave_depth); + } + + // Generate the registered ores + if (flags & MG_ORES) + m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max); + + // Generate dungeons + if (flags & MG_DUNGEONS) + generateDungeons(stone_surface_max_y); + + // Generate the registered decorations + if (flags & MG_DECORATIONS) + m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max); + + // Sprinkle some dust on top after everything else was generated + if (flags & MG_BIOMES) + dustTopNodes(); + + // Update liquids + updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); + + // Calculate lighting + if (flags & MG_LIGHT) { + calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0), + full_node_min, full_node_max); + } + + this->generating = false; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p) +{ + // If rivers are enabled, first check if in a river channel + if (spflags & MGCARPATHIAN_RIVERS) { + float river = std::fabs(NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed)) - + river_width; + if (river < 0.0f) + return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point + } + + float height1 = NoisePerlin2D(&noise_height1->np, p.X, p.Y, seed); + float height2 = NoisePerlin2D(&noise_height2->np, p.X, p.Y, seed); + float height3 = NoisePerlin2D(&noise_height3->np, p.X, p.Y, seed); + float height4 = NoisePerlin2D(&noise_height4->np, p.X, p.Y, seed); + + float hterabs = std::fabs(NoisePerlin2D(&noise_hills_terrain->np, p.X, p.Y, seed)); + float n_hills = NoisePerlin2D(&noise_hills->np, p.X, p.Y, seed); + float hill_mnt = hterabs * hterabs * hterabs * n_hills * n_hills; + + float rterabs = std::fabs(NoisePerlin2D(&noise_ridge_terrain->np, p.X, p.Y, seed)); + float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, p.X, p.Y, seed); + float ridge_mnt = rterabs * rterabs * rterabs * (1.0f - std::fabs(n_ridge_mnt)); + + float sterabs = std::fabs(NoisePerlin2D(&noise_step_terrain->np, p.X, p.Y, seed)); + float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, p.X, p.Y, seed); + float step_mnt = sterabs * sterabs * sterabs * getSteps(n_step_mnt); + + float valley = 1.0f; + float river = 0.0f; + + if ((spflags & MGCARPATHIAN_RIVERS) && node_max.Y >= water_level - 16) { + river = std::fabs(NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed)) - river_width; + if (river <= valley_width) { + // Within river valley + if (river < 0.0f) { + // River channel + valley = river; + } else { + // Valley slopes. + // 0 at river edge, 1 at valley edge. + float riversc = river / valley_width; + // Smoothstep + valley = riversc * riversc * (3.0f - 2.0f * riversc); + } + } + } + + bool solid_below = false; + u8 cons_non_solid = 0; // consecutive non-solid nodes + + for (s16 y = water_level; y <= water_level + 32; y++) { + float mnt_var = NoisePerlin3D(&noise_mnt_var->np, p.X, y, p.Y, seed); + float hill1 = getLerp(height1, height2, mnt_var); + float hill2 = getLerp(height3, height4, mnt_var); + float hill3 = getLerp(height3, height2, mnt_var); + float hill4 = getLerp(height1, height4, mnt_var); + + float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4)); + float hills = hill_mnt * hilliness; + float ridged_mountains = ridge_mnt * hilliness; + float step_mountains = step_mnt * hilliness; + + s32 grad = 1 - y; + + float mountains = hills + ridged_mountains + step_mountains; + float surface_level = base_level + mountains + grad; + + if ((spflags & MGCARPATHIAN_RIVERS) && river <= valley_width) { + if (valley < 0.0f) { + // River channel + surface_level = std::fmin(surface_level, + water_level - std::sqrt(-valley) * river_depth); + } else if (surface_level > water_level) { + // Valley slopes + surface_level = water_level + (surface_level - water_level) * valley; + } + } + + if (y < surface_level) { //TODO '<=' fix from generateTerrain() + // solid node + solid_below = true; + cons_non_solid = 0; + } else { + // non-solid node + cons_non_solid++; + if (cons_non_solid == 3 && solid_below) + return y - 1; + } + } + + return MAX_MAP_GENERATION_LIMIT; // No suitable spawn point found +} + + +//////////////////////////////////////////////////////////////////////////////// + + +int MapgenCarpathian::generateTerrain() +{ + MapNode mn_air(CONTENT_AIR); + MapNode mn_stone(c_stone); + MapNode mn_water(c_water_source); + + // Calculate noise for terrain generation + noise_height1->perlinMap2D(node_min.X, node_min.Z); + noise_height2->perlinMap2D(node_min.X, node_min.Z); + noise_height3->perlinMap2D(node_min.X, node_min.Z); + noise_height4->perlinMap2D(node_min.X, node_min.Z); + noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z); + noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z); + noise_step_terrain->perlinMap2D(node_min.X, node_min.Z); + noise_hills->perlinMap2D(node_min.X, node_min.Z); + noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z); + noise_step_mnt->perlinMap2D(node_min.X, node_min.Z); + noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + + if (spflags & MGCARPATHIAN_RIVERS) + noise_rivers->perlinMap2D(node_min.X, node_min.Z); + + //// Place nodes + const v3s16 &em = vm->m_area.getExtent(); + s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; + u32 index2d = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { + // Hill/Mountain height (hilliness) + float height1 = noise_height1->result[index2d]; + float height2 = noise_height2->result[index2d]; + float height3 = noise_height3->result[index2d]; + float height4 = noise_height4->result[index2d]; + + // Rolling hills + float hterabs = std::fabs(noise_hills_terrain->result[index2d]); + float n_hills = noise_hills->result[index2d]; + float hill_mnt = hterabs * hterabs * hterabs * n_hills * n_hills; + + // Ridged mountains + float rterabs = std::fabs(noise_ridge_terrain->result[index2d]); + float n_ridge_mnt = noise_ridge_mnt->result[index2d]; + float ridge_mnt = rterabs * rterabs * rterabs * + (1.0f - std::fabs(n_ridge_mnt)); + + // Step (terraced) mountains + float sterabs = std::fabs(noise_step_terrain->result[index2d]); + float n_step_mnt = noise_step_mnt->result[index2d]; + float step_mnt = sterabs * sterabs * sterabs * getSteps(n_step_mnt); + + // Rivers + float valley = 1.0f; + float river = 0.0f; + + if ((spflags & MGCARPATHIAN_RIVERS) && node_max.Y >= water_level - 16) { + river = std::fabs(noise_rivers->result[index2d]) - river_width; + if (river <= valley_width) { + // Within river valley + if (river < 0.0f) { + // River channel + valley = river; + } else { + // Valley slopes. + // 0 at river edge, 1 at valley edge. + float riversc = river / valley_width; + // Smoothstep + valley = riversc * riversc * (3.0f - 2.0f * riversc); + } + } + } + + // Initialise 3D noise index and voxelmanip index to column base + u32 index3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X); + u32 vi = vm->m_area.index(x, node_min.Y - 1, z); + + for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; + y++, + index3d += ystride, + VoxelArea::add_y(em, vi, 1)) { + if (vm->m_data[vi].getContent() != CONTENT_IGNORE) + continue; + + // Combine height noises and apply 3D variation + float mnt_var = noise_mnt_var->result[index3d]; + float hill1 = getLerp(height1, height2, mnt_var); + float hill2 = getLerp(height3, height4, mnt_var); + float hill3 = getLerp(height3, height2, mnt_var); + float hill4 = getLerp(height1, height4, mnt_var); + + // 'hilliness' determines whether hills/mountains are + // small or large + float hilliness = + std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4)); + float hills = hill_mnt * hilliness; + float ridged_mountains = ridge_mnt * hilliness; + float step_mountains = step_mnt * hilliness; + + // Gradient & shallow seabed + s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : + 1 - y; + + // Final terrain level + float mountains = hills + ridged_mountains + step_mountains; + float surface_level = base_level + mountains + grad; + + // Rivers + if ((spflags & MGCARPATHIAN_RIVERS) && node_max.Y >= water_level - 16 && + river <= valley_width) { + if (valley < 0.0f) { + // River channel + surface_level = std::fmin(surface_level, + water_level - std::sqrt(-valley) * river_depth); + } else if (surface_level > water_level) { + // Valley slopes + surface_level = water_level + (surface_level - water_level) * valley; + } + } + + if (y < surface_level) { //TODO '<=' + vm->m_data[vi] = mn_stone; // Stone + if (y > stone_surface_max_y) + stone_surface_max_y = y; + } else if (y <= water_level) { + vm->m_data[vi] = mn_water; // Sea water + } else { + vm->m_data[vi] = mn_air; // Air + } + } + } + + return stone_surface_max_y; +} diff --git a/src/mapgen/mapgen_carpathian.h b/src/mapgen/mapgen_carpathian.h new file mode 100644 index 0000000..31b2b91 --- /dev/null +++ b/src/mapgen/mapgen_carpathian.h @@ -0,0 +1,114 @@ +/* +Minetest +Copyright (C) 2017-2019 vlapsley, Vaughan Lapsley <vlapsley@gmail.com> +Copyright (C) 2017-2019 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "mapgen.h" + +#define MGCARPATHIAN_CAVERNS 0x01 +#define MGCARPATHIAN_RIVERS 0x02 + +class BiomeManager; + +extern FlagDesc flagdesc_mapgen_carpathian[]; + + +struct MapgenCarpathianParams : public MapgenParams +{ + float base_level = 12.0f; + float river_width = 0.05f; + float river_depth = 24.0f; + float valley_width = 0.25f; + + float cave_width = 0.09f; + s16 large_cave_depth = -33; + u16 small_cave_num_min = 0; + u16 small_cave_num_max = 0; + u16 large_cave_num_min = 0; + u16 large_cave_num_max = 2; + float large_cave_flooded = 0.5f; + s16 cavern_limit = -256; + s16 cavern_taper = 256; + float cavern_threshold = 0.7f; + s16 dungeon_ymin = -31000; + s16 dungeon_ymax = 31000; + + NoiseParams np_filler_depth; + NoiseParams np_height1; + NoiseParams np_height2; + NoiseParams np_height3; + NoiseParams np_height4; + NoiseParams np_hills_terrain; + NoiseParams np_ridge_terrain; + NoiseParams np_step_terrain; + NoiseParams np_hills; + NoiseParams np_ridge_mnt; + NoiseParams np_step_mnt; + NoiseParams np_rivers; + NoiseParams np_mnt_var; + NoiseParams np_cave1; + NoiseParams np_cave2; + NoiseParams np_cavern; + NoiseParams np_dungeons; + + MapgenCarpathianParams(); + ~MapgenCarpathianParams() = default; + + void readParams(const Settings *settings); + void writeParams(Settings *settings) const; + void setDefaultSettings(Settings *settings); +}; + +class MapgenCarpathian : public MapgenBasic +{ +public: + MapgenCarpathian(MapgenCarpathianParams *params, EmergeParams *emerge); + ~MapgenCarpathian(); + + virtual MapgenType getType() const { return MAPGEN_CARPATHIAN; } + + virtual void makeChunk(BlockMakeData *data); + int getSpawnLevelAtPoint(v2s16 p); + +private: + float base_level; + float river_width; + float river_depth; + float valley_width; + + Noise *noise_height1; + Noise *noise_height2; + Noise *noise_height3; + Noise *noise_height4; + Noise *noise_hills_terrain; + Noise *noise_ridge_terrain; + Noise *noise_step_terrain; + Noise *noise_hills; + Noise *noise_ridge_mnt; + Noise *noise_step_mnt; + Noise *noise_rivers = nullptr; + Noise *noise_mnt_var; + + s32 grad_wl; + + float getSteps(float noise); + inline float getLerp(float noise1, float noise2, float mod); + int generateTerrain(); +}; diff --git a/src/mapgen/mapgen_flat.cpp b/src/mapgen/mapgen_flat.cpp new file mode 100644 index 0000000..6b249ea --- /dev/null +++ b/src/mapgen/mapgen_flat.cpp @@ -0,0 +1,335 @@ +/* +Minetest +Copyright (C) 2015-2020 paramat +Copyright (C) 2015-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "mapgen.h" +#include "voxel.h" +#include "noise.h" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +#include "nodedef.h" +#include "voxelalgorithms.h" +//#include "profiler.h" // For TimeTaker +#include "settings.h" // For g_settings +#include "emerge.h" +#include "dungeongen.h" +#include "cavegen.h" +#include "mg_biome.h" +#include "mg_ore.h" +#include "mg_decoration.h" +#include "mapgen_flat.h" + + +FlagDesc flagdesc_mapgen_flat[] = { + {"lakes", MGFLAT_LAKES}, + {"hills", MGFLAT_HILLS}, + {"caverns", MGFLAT_CAVERNS}, + {NULL, 0} +}; + +/////////////////////////////////////////////////////////////////////////////////////// + + +MapgenFlat::MapgenFlat(MapgenFlatParams *params, EmergeParams *emerge) + : MapgenBasic(MAPGEN_FLAT, params, emerge) +{ + spflags = params->spflags; + ground_level = params->ground_level; + lake_threshold = params->lake_threshold; + lake_steepness = params->lake_steepness; + hill_threshold = params->hill_threshold; + hill_steepness = params->hill_steepness; + + cave_width = params->cave_width; + small_cave_num_min = params->small_cave_num_min; + small_cave_num_max = params->small_cave_num_max; + large_cave_num_min = params->large_cave_num_min; + large_cave_num_max = params->large_cave_num_max; + large_cave_depth = params->large_cave_depth; + large_cave_flooded = params->large_cave_flooded; + cavern_limit = params->cavern_limit; + cavern_taper = params->cavern_taper; + cavern_threshold = params->cavern_threshold; + dungeon_ymin = params->dungeon_ymin; + dungeon_ymax = params->dungeon_ymax; + + // 2D noise + noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); + + if ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS)) + noise_terrain = new Noise(¶ms->np_terrain, seed, csize.X, csize.Z); + + // 3D noise + MapgenBasic::np_cave1 = params->np_cave1; + MapgenBasic::np_cave2 = params->np_cave2; + MapgenBasic::np_cavern = params->np_cavern; + MapgenBasic::np_dungeons = params->np_dungeons; +} + + +MapgenFlat::~MapgenFlat() +{ + delete noise_filler_depth; + + if ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS)) + delete noise_terrain; +} + + +MapgenFlatParams::MapgenFlatParams(): + np_terrain (0, 1, v3f(600, 600, 600), 7244, 5, 0.6, 2.0), + np_filler_depth (0, 1.2, v3f(150, 150, 150), 261, 3, 0.7, 2.0), + np_cavern (0.0, 1.0, v3f(384, 128, 384), 723, 5, 0.63, 2.0), + np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0), + np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0), + np_dungeons (0.9, 0.5, v3f(500, 500, 500), 0, 2, 0.8, 2.0) +{ +} + + +void MapgenFlatParams::readParams(const Settings *settings) +{ + settings->getFlagStrNoEx("mgflat_spflags", spflags, flagdesc_mapgen_flat); + settings->getS16NoEx("mgflat_ground_level", ground_level); + settings->getS16NoEx("mgflat_large_cave_depth", large_cave_depth); + settings->getU16NoEx("mgflat_small_cave_num_min", small_cave_num_min); + settings->getU16NoEx("mgflat_small_cave_num_max", small_cave_num_max); + settings->getU16NoEx("mgflat_large_cave_num_min", large_cave_num_min); + settings->getU16NoEx("mgflat_large_cave_num_max", large_cave_num_max); + settings->getFloatNoEx("mgflat_large_cave_flooded", large_cave_flooded); + settings->getFloatNoEx("mgflat_cave_width", cave_width); + settings->getFloatNoEx("mgflat_lake_threshold", lake_threshold); + settings->getFloatNoEx("mgflat_lake_steepness", lake_steepness); + settings->getFloatNoEx("mgflat_hill_threshold", hill_threshold); + settings->getFloatNoEx("mgflat_hill_steepness", hill_steepness); + settings->getS16NoEx("mgflat_cavern_limit", cavern_limit); + settings->getS16NoEx("mgflat_cavern_taper", cavern_taper); + settings->getFloatNoEx("mgflat_cavern_threshold", cavern_threshold); + settings->getS16NoEx("mgflat_dungeon_ymin", dungeon_ymin); + settings->getS16NoEx("mgflat_dungeon_ymax", dungeon_ymax); + + settings->getNoiseParams("mgflat_np_terrain", np_terrain); + settings->getNoiseParams("mgflat_np_filler_depth", np_filler_depth); + settings->getNoiseParams("mgflat_np_cavern", np_cavern); + settings->getNoiseParams("mgflat_np_cave1", np_cave1); + settings->getNoiseParams("mgflat_np_cave2", np_cave2); + settings->getNoiseParams("mgflat_np_dungeons", np_dungeons); +} + + +void MapgenFlatParams::writeParams(Settings *settings) const +{ + settings->setFlagStr("mgflat_spflags", spflags, flagdesc_mapgen_flat); + settings->setS16("mgflat_ground_level", ground_level); + settings->setS16("mgflat_large_cave_depth", large_cave_depth); + settings->setU16("mgflat_small_cave_num_min", small_cave_num_min); + settings->setU16("mgflat_small_cave_num_max", small_cave_num_max); + settings->setU16("mgflat_large_cave_num_min", large_cave_num_min); + settings->setU16("mgflat_large_cave_num_max", large_cave_num_max); + settings->setFloat("mgflat_large_cave_flooded", large_cave_flooded); + settings->setFloat("mgflat_cave_width", cave_width); + settings->setFloat("mgflat_lake_threshold", lake_threshold); + settings->setFloat("mgflat_lake_steepness", lake_steepness); + settings->setFloat("mgflat_hill_threshold", hill_threshold); + settings->setFloat("mgflat_hill_steepness", hill_steepness); + settings->setS16("mgflat_cavern_limit", cavern_limit); + settings->setS16("mgflat_cavern_taper", cavern_taper); + settings->setFloat("mgflat_cavern_threshold", cavern_threshold); + settings->setS16("mgflat_dungeon_ymin", dungeon_ymin); + settings->setS16("mgflat_dungeon_ymax", dungeon_ymax); + + settings->setNoiseParams("mgflat_np_terrain", np_terrain); + settings->setNoiseParams("mgflat_np_filler_depth", np_filler_depth); + settings->setNoiseParams("mgflat_np_cavern", np_cavern); + settings->setNoiseParams("mgflat_np_cave1", np_cave1); + settings->setNoiseParams("mgflat_np_cave2", np_cave2); + settings->setNoiseParams("mgflat_np_dungeons", np_dungeons); +} + + +void MapgenFlatParams::setDefaultSettings(Settings *settings) +{ + settings->setDefault("mgflat_spflags", flagdesc_mapgen_flat, 0); +} + + +///////////////////////////////////////////////////////////////// + + +int MapgenFlat::getSpawnLevelAtPoint(v2s16 p) +{ + s16 stone_level = ground_level; + float n_terrain = + ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS)) ? + NoisePerlin2D(&noise_terrain->np, p.X, p.Y, seed) : + 0.0f; + + if ((spflags & MGFLAT_LAKES) && n_terrain < lake_threshold) { + s16 depress = (lake_threshold - n_terrain) * lake_steepness; + stone_level = ground_level - depress; + } else if ((spflags & MGFLAT_HILLS) && n_terrain > hill_threshold) { + s16 rise = (n_terrain - hill_threshold) * hill_steepness; + stone_level = ground_level + rise; + } + + if (ground_level < water_level) + // Ocean world, may not have islands so allow spawn in water + return MYMAX(stone_level + 2, water_level); + + if (stone_level >= water_level) + // Spawn on land + // + 2 not + 1, to spawn above biome 'dust' nodes + return stone_level + 2; + + // Unsuitable spawn point + return MAX_MAP_GENERATION_LIMIT; +} + + +void MapgenFlat::makeChunk(BlockMakeData *data) +{ + // Pre-conditions + assert(data->vmanip); + assert(data->nodedef); + + this->generating = true; + this->vm = data->vmanip; + this->ndef = data->nodedef; + //TimeTaker t("makeChunk"); + + v3s16 blockpos_min = data->blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + node_min = blockpos_min * MAP_BLOCKSIZE; + node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE; + full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + + blockseed = getBlockSeed2(full_node_min, seed); + + // Generate base terrain, mountains, and ridges with initial heightmaps + s16 stone_surface_max_y = generateTerrain(); + + // Create heightmap + updateHeightmap(node_min, node_max); + + // Init biome generator, place biome-specific nodes, and build biomemap + if (flags & MG_BIOMES) { + biomegen->calcBiomeNoise(node_min); + generateBiomes(); + } + + // Generate tunnels, caverns and large randomwalk caves + if (flags & MG_CAVES) { + // Generate tunnels first as caverns confuse them + generateCavesNoiseIntersection(stone_surface_max_y); + + // Generate caverns + bool near_cavern = false; + if (spflags & MGFLAT_CAVERNS) + near_cavern = generateCavernsNoise(stone_surface_max_y); + + // Generate large randomwalk caves + if (near_cavern) + // Disable large randomwalk caves in this mapchunk by setting + // 'large cave depth' to world base. Avoids excessive liquid in + // large caverns and floating blobs of overgenerated liquid. + generateCavesRandomWalk(stone_surface_max_y, + -MAX_MAP_GENERATION_LIMIT); + else + generateCavesRandomWalk(stone_surface_max_y, large_cave_depth); + } + + // Generate the registered ores + if (flags & MG_ORES) + m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max); + + if (flags & MG_DUNGEONS) + generateDungeons(stone_surface_max_y); + + // Generate the registered decorations + if (flags & MG_DECORATIONS) + m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max); + + // Sprinkle some dust on top after everything else was generated + if (flags & MG_BIOMES) + dustTopNodes(); + + //printf("makeChunk: %dms\n", t.stop()); + + updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); + + if (flags & MG_LIGHT) + calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0), + full_node_min, full_node_max); + + //setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE, + // node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF); + + this->generating = false; +} + + +s16 MapgenFlat::generateTerrain() +{ + MapNode n_air(CONTENT_AIR); + MapNode n_stone(c_stone); + MapNode n_water(c_water_source); + + const v3s16 &em = vm->m_area.getExtent(); + s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; + u32 ni2d = 0; + + bool use_noise = (spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS); + if (use_noise) + noise_terrain->perlinMap2D(node_min.X, node_min.Z); + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, ni2d++) { + s16 stone_level = ground_level; + float n_terrain = use_noise ? noise_terrain->result[ni2d] : 0.0f; + + if ((spflags & MGFLAT_LAKES) && n_terrain < lake_threshold) { + s16 depress = (lake_threshold - n_terrain) * lake_steepness; + stone_level = ground_level - depress; + } else if ((spflags & MGFLAT_HILLS) && n_terrain > hill_threshold) { + s16 rise = (n_terrain - hill_threshold) * hill_steepness; + stone_level = ground_level + rise; + } + + u32 vi = vm->m_area.index(x, node_min.Y - 1, z); + for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { + if (vm->m_data[vi].getContent() == CONTENT_IGNORE) { + if (y <= stone_level) { + vm->m_data[vi] = n_stone; + if (y > stone_surface_max_y) + stone_surface_max_y = y; + } else if (y <= water_level) { + vm->m_data[vi] = n_water; + } else { + vm->m_data[vi] = n_air; + } + } + VoxelArea::add_y(em, vi, 1); + } + } + + return stone_surface_max_y; +} diff --git a/src/mapgen/mapgen_flat.h b/src/mapgen/mapgen_flat.h new file mode 100644 index 0000000..4b46aff --- /dev/null +++ b/src/mapgen/mapgen_flat.h @@ -0,0 +1,90 @@ +/* +Minetest +Copyright (C) 2015-2020 paramat +Copyright (C) 2015-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "mapgen.h" + +/////// Mapgen Flat flags +#define MGFLAT_LAKES 0x01 +#define MGFLAT_HILLS 0x02 +#define MGFLAT_CAVERNS 0x04 + +class BiomeManager; + +extern FlagDesc flagdesc_mapgen_flat[]; + +struct MapgenFlatParams : public MapgenParams +{ + s16 ground_level = 8; + float lake_threshold = -0.45f; + float lake_steepness = 48.0f; + float hill_threshold = 0.45f; + float hill_steepness = 64.0f; + + float cave_width = 0.09f; + u16 small_cave_num_min = 0; + u16 small_cave_num_max = 0; + u16 large_cave_num_min = 0; + u16 large_cave_num_max = 2; + s16 large_cave_depth = -33; + float large_cave_flooded = 0.5f; + s16 cavern_limit = -256; + s16 cavern_taper = 256; + float cavern_threshold = 0.7f; + s16 dungeon_ymin = -31000; + s16 dungeon_ymax = 31000; + + NoiseParams np_terrain; + NoiseParams np_filler_depth; + NoiseParams np_cavern; + NoiseParams np_cave1; + NoiseParams np_cave2; + NoiseParams np_dungeons; + + MapgenFlatParams(); + ~MapgenFlatParams() = default; + + void readParams(const Settings *settings); + void writeParams(Settings *settings) const; + void setDefaultSettings(Settings *settings); +}; + +class MapgenFlat : public MapgenBasic +{ +public: + MapgenFlat(MapgenFlatParams *params, EmergeParams *emerge); + ~MapgenFlat(); + + virtual MapgenType getType() const { return MAPGEN_FLAT; } + + virtual void makeChunk(BlockMakeData *data); + int getSpawnLevelAtPoint(v2s16 p); + s16 generateTerrain(); + +private: + s16 ground_level; + float lake_threshold; + float lake_steepness; + float hill_threshold; + float hill_steepness; + + Noise *noise_terrain; +}; diff --git a/src/mapgen/mapgen_fractal.cpp b/src/mapgen/mapgen_fractal.cpp new file mode 100644 index 0000000..c9071ce --- /dev/null +++ b/src/mapgen/mapgen_fractal.cpp @@ -0,0 +1,448 @@ +/* +Minetest +Copyright (C) 2015-2019 paramat +Copyright (C) 2015-2016 kwolekr, Ryan Kwolek + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "mapgen.h" +#include <cmath> +#include "voxel.h" +#include "noise.h" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +#include "nodedef.h" +#include "voxelalgorithms.h" +//#include "profiler.h" // For TimeTaker +#include "settings.h" // For g_settings +#include "emerge.h" +#include "dungeongen.h" +#include "cavegen.h" +#include "mg_biome.h" +#include "mg_ore.h" +#include "mg_decoration.h" +#include "mapgen_fractal.h" + + +FlagDesc flagdesc_mapgen_fractal[] = { + {"terrain", MGFRACTAL_TERRAIN}, + {NULL, 0} +}; + +/////////////////////////////////////////////////////////////////////////////////////// + + +MapgenFractal::MapgenFractal(MapgenFractalParams *params, EmergeParams *emerge) + : MapgenBasic(MAPGEN_FRACTAL, params, emerge) +{ + spflags = params->spflags; + cave_width = params->cave_width; + large_cave_depth = params->large_cave_depth; + small_cave_num_min = params->small_cave_num_min; + small_cave_num_max = params->small_cave_num_max; + large_cave_num_min = params->large_cave_num_min; + large_cave_num_max = params->large_cave_num_max; + large_cave_flooded = params->large_cave_flooded; + dungeon_ymin = params->dungeon_ymin; + dungeon_ymax = params->dungeon_ymax; + fractal = params->fractal; + iterations = params->iterations; + scale = params->scale; + offset = params->offset; + slice_w = params->slice_w; + julia_x = params->julia_x; + julia_y = params->julia_y; + julia_z = params->julia_z; + julia_w = params->julia_w; + + //// 2D noise + if (spflags & MGFRACTAL_TERRAIN) + noise_seabed = new Noise(¶ms->np_seabed, seed, csize.X, csize.Z); + + noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); + + //// 3D noise + MapgenBasic::np_dungeons = params->np_dungeons; + // Overgeneration to node_min.Y - 1 + MapgenBasic::np_cave1 = params->np_cave1; + MapgenBasic::np_cave2 = params->np_cave2; + + formula = fractal / 2 + fractal % 2; + julia = fractal % 2 == 0; +} + + +MapgenFractal::~MapgenFractal() +{ + delete noise_seabed; + delete noise_filler_depth; +} + + +MapgenFractalParams::MapgenFractalParams(): + np_seabed (-14, 9, v3f(600, 600, 600), 41900, 5, 0.6, 2.0), + np_filler_depth (0, 1.2, v3f(150, 150, 150), 261, 3, 0.7, 2.0), + np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0), + np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0), + np_dungeons (0.9, 0.5, v3f(500, 500, 500), 0, 2, 0.8, 2.0) +{ +} + + +void MapgenFractalParams::readParams(const Settings *settings) +{ + settings->getFlagStrNoEx("mgfractal_spflags", spflags, flagdesc_mapgen_fractal); + settings->getFloatNoEx("mgfractal_cave_width", cave_width); + settings->getS16NoEx("mgfractal_large_cave_depth", large_cave_depth); + settings->getU16NoEx("mgfractal_small_cave_num_min", small_cave_num_min); + settings->getU16NoEx("mgfractal_small_cave_num_max", small_cave_num_max); + settings->getU16NoEx("mgfractal_large_cave_num_min", large_cave_num_min); + settings->getU16NoEx("mgfractal_large_cave_num_max", large_cave_num_max); + settings->getFloatNoEx("mgfractal_large_cave_flooded", large_cave_flooded); + settings->getS16NoEx("mgfractal_dungeon_ymin", dungeon_ymin); + settings->getS16NoEx("mgfractal_dungeon_ymax", dungeon_ymax); + settings->getU16NoEx("mgfractal_fractal", fractal); + settings->getU16NoEx("mgfractal_iterations", iterations); + settings->getV3FNoEx("mgfractal_scale", scale); + settings->getV3FNoEx("mgfractal_offset", offset); + settings->getFloatNoEx("mgfractal_slice_w", slice_w); + settings->getFloatNoEx("mgfractal_julia_x", julia_x); + settings->getFloatNoEx("mgfractal_julia_y", julia_y); + settings->getFloatNoEx("mgfractal_julia_z", julia_z); + settings->getFloatNoEx("mgfractal_julia_w", julia_w); + + settings->getNoiseParams("mgfractal_np_seabed", np_seabed); + settings->getNoiseParams("mgfractal_np_filler_depth", np_filler_depth); + settings->getNoiseParams("mgfractal_np_cave1", np_cave1); + settings->getNoiseParams("mgfractal_np_cave2", np_cave2); + settings->getNoiseParams("mgfractal_np_dungeons", np_dungeons); + iterations = std::max<u16>(iterations, 1); +} + + +void MapgenFractalParams::writeParams(Settings *settings) const +{ + settings->setFlagStr("mgfractal_spflags", spflags, flagdesc_mapgen_fractal); + settings->setFloat("mgfractal_cave_width", cave_width); + settings->setS16("mgfractal_large_cave_depth", large_cave_depth); + settings->setU16("mgfractal_small_cave_num_min", small_cave_num_min); + settings->setU16("mgfractal_small_cave_num_max", small_cave_num_max); + settings->setU16("mgfractal_large_cave_num_min", large_cave_num_min); + settings->setU16("mgfractal_large_cave_num_max", large_cave_num_max); + settings->setFloat("mgfractal_large_cave_flooded", large_cave_flooded); + settings->setS16("mgfractal_dungeon_ymin", dungeon_ymin); + settings->setS16("mgfractal_dungeon_ymax", dungeon_ymax); + settings->setU16("mgfractal_fractal", fractal); + settings->setU16("mgfractal_iterations", iterations); + settings->setV3F("mgfractal_scale", scale); + settings->setV3F("mgfractal_offset", offset); + settings->setFloat("mgfractal_slice_w", slice_w); + settings->setFloat("mgfractal_julia_x", julia_x); + settings->setFloat("mgfractal_julia_y", julia_y); + settings->setFloat("mgfractal_julia_z", julia_z); + settings->setFloat("mgfractal_julia_w", julia_w); + + settings->setNoiseParams("mgfractal_np_seabed", np_seabed); + settings->setNoiseParams("mgfractal_np_filler_depth", np_filler_depth); + settings->setNoiseParams("mgfractal_np_cave1", np_cave1); + settings->setNoiseParams("mgfractal_np_cave2", np_cave2); + settings->setNoiseParams("mgfractal_np_dungeons", np_dungeons); +} + + +void MapgenFractalParams::setDefaultSettings(Settings *settings) +{ + settings->setDefault("mgfractal_spflags", flagdesc_mapgen_fractal, + MGFRACTAL_TERRAIN); +} + + +///////////////////////////////////////////////////////////////// + + +int MapgenFractal::getSpawnLevelAtPoint(v2s16 p) +{ + bool solid_below = false; // Fractal node is present below to spawn on + u8 air_count = 0; // Consecutive air nodes above a fractal node + s16 search_start = 0; // No terrain search start + + // If terrain present, don't start search below terrain or water level + if (noise_seabed) { + s16 seabed_level = NoisePerlin2D(&noise_seabed->np, p.X, p.Y, seed); + search_start = MYMAX(search_start, MYMAX(seabed_level, water_level)); + } + + for (s16 y = search_start; y <= search_start + 4096; y++) { + if (getFractalAtPoint(p.X, y, p.Y)) { + // Fractal node + solid_below = true; + air_count = 0; + } else if (solid_below) { + // Air above fractal node + air_count++; + // 3 and -2 to account for biome dust nodes + if (air_count == 3) + return y - 2; + } + } + + return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point +} + + +void MapgenFractal::makeChunk(BlockMakeData *data) +{ + // Pre-conditions + assert(data->vmanip); + assert(data->nodedef); + + //TimeTaker t("makeChunk"); + + this->generating = true; + this->vm = data->vmanip; + this->ndef = data->nodedef; + + v3s16 blockpos_min = data->blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + node_min = blockpos_min * MAP_BLOCKSIZE; + node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE; + full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + + blockseed = getBlockSeed2(full_node_min, seed); + + // Generate fractal and optional terrain + s16 stone_surface_max_y = generateTerrain(); + + // Create heightmap + updateHeightmap(node_min, node_max); + + // Init biome generator, place biome-specific nodes, and build biomemap + if (flags & MG_BIOMES) { + biomegen->calcBiomeNoise(node_min); + generateBiomes(); + } + + // Generate tunnels and randomwalk caves + if (flags & MG_CAVES) { + generateCavesNoiseIntersection(stone_surface_max_y); + generateCavesRandomWalk(stone_surface_max_y, large_cave_depth); + } + + // Generate the registered ores + if (flags & MG_ORES) + m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max); + + // Generate dungeons + if (flags & MG_DUNGEONS) + generateDungeons(stone_surface_max_y); + + // Generate the registered decorations + if (flags & MG_DECORATIONS) + m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max); + + // Sprinkle some dust on top after everything else was generated + if (flags & MG_BIOMES) + dustTopNodes(); + + // Update liquids + if (spflags & MGFRACTAL_TERRAIN) + updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); + + // Calculate lighting + if (flags & MG_LIGHT) + calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0), + full_node_min, full_node_max); + + this->generating = false; + + //printf("makeChunk: %lums\n", t.stop()); +} + + +bool MapgenFractal::getFractalAtPoint(s16 x, s16 y, s16 z) +{ + float cx, cy, cz, cw, ox, oy, oz, ow; + + if (julia) { // Julia set + cx = julia_x; + cy = julia_y; + cz = julia_z; + cw = julia_w; + ox = (float)x / scale.X - offset.X; + oy = (float)y / scale.Y - offset.Y; + oz = (float)z / scale.Z - offset.Z; + ow = slice_w; + } else { // Mandelbrot set + cx = (float)x / scale.X - offset.X; + cy = (float)y / scale.Y - offset.Y; + cz = (float)z / scale.Z - offset.Z; + cw = slice_w; + ox = 0.0f; + oy = 0.0f; + oz = 0.0f; + ow = 0.0f; + } + + float nx = 0.0f; + float ny = 0.0f; + float nz = 0.0f; + float nw = 0.0f; + + for (u16 iter = 0; iter < iterations; iter++) { + switch (formula) { + default: + case 1: // 4D "Roundy" + nx = ox * ox - oy * oy - oz * oz - ow * ow + cx; + ny = 2.0f * (ox * oy + oz * ow) + cy; + nz = 2.0f * (ox * oz + oy * ow) + cz; + nw = 2.0f * (ox * ow + oy * oz) + cw; + break; + case 2: // 4D "Squarry" + nx = ox * ox - oy * oy - oz * oz - ow * ow + cx; + ny = 2.0f * (ox * oy + oz * ow) + cy; + nz = 2.0f * (ox * oz + oy * ow) + cz; + nw = 2.0f * (ox * ow - oy * oz) + cw; + break; + case 3: // 4D "Mandy Cousin" + nx = ox * ox - oy * oy - oz * oz + ow * ow + cx; + ny = 2.0f * (ox * oy + oz * ow) + cy; + nz = 2.0f * (ox * oz + oy * ow) + cz; + nw = 2.0f * (ox * ow + oy * oz) + cw; + break; + case 4: // 4D "Variation" + nx = ox * ox - oy * oy - oz * oz - ow * ow + cx; + ny = 2.0f * (ox * oy + oz * ow) + cy; + nz = 2.0f * (ox * oz - oy * ow) + cz; + nw = 2.0f * (ox * ow + oy * oz) + cw; + break; + case 5: // 3D "Mandelbrot/Mandelbar" + nx = ox * ox - oy * oy - oz * oz + cx; + ny = 2.0f * ox * oy + cy; + nz = -2.0f * ox * oz + cz; + break; + case 6: // 3D "Christmas Tree" + // Altering the formula here is necessary to avoid division by zero + if (std::fabs(oz) < 0.000000001f) { + nx = ox * ox - oy * oy - oz * oz + cx; + ny = 2.0f * oy * ox + cy; + nz = 4.0f * oz * ox + cz; + } else { + float a = (2.0f * ox) / (std::sqrt(oy * oy + oz * oz)); + nx = ox * ox - oy * oy - oz * oz + cx; + ny = a * (oy * oy - oz * oz) + cy; + nz = a * 2.0f * oy * oz + cz; + } + break; + case 7: // 3D "Mandelbulb" + if (std::fabs(oy) < 0.000000001f) { + nx = ox * ox - oz * oz + cx; + ny = cy; + nz = -2.0f * oz * std::sqrt(ox * ox) + cz; + } else { + float a = 1.0f - (oz * oz) / (ox * ox + oy * oy); + nx = (ox * ox - oy * oy) * a + cx; + ny = 2.0f * ox * oy * a + cy; + nz = -2.0f * oz * std::sqrt(ox * ox + oy * oy) + cz; + } + break; + case 8: // 3D "Cosine Mandelbulb" + if (std::fabs(oy) < 0.000000001f) { + nx = 2.0f * ox * oz + cx; + ny = 4.0f * oy * oz + cy; + nz = oz * oz - ox * ox - oy * oy + cz; + } else { + float a = (2.0f * oz) / std::sqrt(ox * ox + oy * oy); + nx = (ox * ox - oy * oy) * a + cx; + ny = 2.0f * ox * oy * a + cy; + nz = oz * oz - ox * ox - oy * oy + cz; + } + break; + case 9: // 4D "Mandelbulb" + float rxy = std::sqrt(ox * ox + oy * oy); + float rxyz = std::sqrt(ox * ox + oy * oy + oz * oz); + if (std::fabs(ow) < 0.000000001f && std::fabs(oz) < 0.000000001f) { + nx = (ox * ox - oy * oy) + cx; + ny = 2.0f * ox * oy + cy; + nz = -2.0f * rxy * oz + cz; + nw = 2.0f * rxyz * ow + cw; + } else { + float a = 1.0f - (ow * ow) / (rxyz * rxyz); + float b = a * (1.0f - (oz * oz) / (rxy * rxy)); + nx = (ox * ox - oy * oy) * b + cx; + ny = 2.0f * ox * oy * b + cy; + nz = -2.0f * rxy * oz * a + cz; + nw = 2.0f * rxyz * ow + cw; + } + break; + } + + if (nx * nx + ny * ny + nz * nz + nw * nw > 4.0f) + return false; + + ox = nx; + oy = ny; + oz = nz; + ow = nw; + } + + return true; +} + + +s16 MapgenFractal::generateTerrain() +{ + MapNode n_air(CONTENT_AIR); + MapNode n_stone(c_stone); + MapNode n_water(c_water_source); + + s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; + u32 index2d = 0; + + if (noise_seabed) + noise_seabed->perlinMap2D(node_min.X, node_min.Z); + + for (s16 z = node_min.Z; z <= node_max.Z; z++) { + for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { + u32 vi = vm->m_area.index(node_min.X, y, z); + for (s16 x = node_min.X; x <= node_max.X; x++, vi++, index2d++) { + if (vm->m_data[vi].getContent() != CONTENT_IGNORE) + continue; + + s16 seabed_height = -MAX_MAP_GENERATION_LIMIT; + if (noise_seabed) + seabed_height = noise_seabed->result[index2d]; + + if (((spflags & MGFRACTAL_TERRAIN) && y <= seabed_height) || + getFractalAtPoint(x, y, z)) { + vm->m_data[vi] = n_stone; + if (y > stone_surface_max_y) + stone_surface_max_y = y; + } else if ((spflags & MGFRACTAL_TERRAIN) && y <= water_level) { + vm->m_data[vi] = n_water; + } else { + vm->m_data[vi] = n_air; + } + } + index2d -= ystride; + } + index2d += ystride; + } + + return stone_surface_max_y; +} diff --git a/src/mapgen/mapgen_fractal.h b/src/mapgen/mapgen_fractal.h new file mode 100644 index 0000000..23af925 --- /dev/null +++ b/src/mapgen/mapgen_fractal.h @@ -0,0 +1,98 @@ +/* +Minetest +Copyright (C) 2015-2019 paramat +Copyright (C) 2015-2016 kwolekr, Ryan Kwolek + +Fractal formulas from http://www.bugman123.com/Hypercomplex/index.html +by Paul Nylander, and from http://www.fractalforums.com, thank you. + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "mapgen.h" + +///////////// Mapgen Fractal flags +#define MGFRACTAL_TERRAIN 0x01 + +class BiomeManager; + +extern FlagDesc flagdesc_mapgen_fractal[]; + + +struct MapgenFractalParams : public MapgenParams +{ + float cave_width = 0.09f; + s16 large_cave_depth = -33; + u16 small_cave_num_min = 0; + u16 small_cave_num_max = 0; + u16 large_cave_num_min = 0; + u16 large_cave_num_max = 2; + float large_cave_flooded = 0.5f; + s16 dungeon_ymin = -31000; + s16 dungeon_ymax = 31000; + u16 fractal = 1; + u16 iterations = 11; + v3f scale = v3f(4096.0, 1024.0, 4096.0); + v3f offset = v3f(1.52, 0.0, 0.0); + float slice_w = 0.0f; + float julia_x = 0.267f; + float julia_y = 0.2f; + float julia_z = 0.133f; + float julia_w = 0.067f; + + NoiseParams np_seabed; + NoiseParams np_filler_depth; + NoiseParams np_cave1; + NoiseParams np_cave2; + NoiseParams np_dungeons; + + MapgenFractalParams(); + ~MapgenFractalParams() = default; + + void readParams(const Settings *settings); + void writeParams(Settings *settings) const; + void setDefaultSettings(Settings *settings); +}; + + +class MapgenFractal : public MapgenBasic +{ +public: + MapgenFractal(MapgenFractalParams *params, EmergeParams *emerge); + ~MapgenFractal(); + + virtual MapgenType getType() const { return MAPGEN_FRACTAL; } + + virtual void makeChunk(BlockMakeData *data); + int getSpawnLevelAtPoint(v2s16 p); + bool getFractalAtPoint(s16 x, s16 y, s16 z); + s16 generateTerrain(); + +private: + u16 formula; + bool julia; + u16 fractal; + u16 iterations; + v3f scale; + v3f offset; + float slice_w; + float julia_x; + float julia_y; + float julia_z; + float julia_w; + Noise *noise_seabed = nullptr; +}; diff --git a/src/mapgen/mapgen_singlenode.cpp b/src/mapgen/mapgen_singlenode.cpp new file mode 100644 index 0000000..5382423 --- /dev/null +++ b/src/mapgen/mapgen_singlenode.cpp @@ -0,0 +1,93 @@ +/* +Minetest +Copyright (C) 2013-2018 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2015-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mapgen_singlenode.h" +#include "voxel.h" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +#include "nodedef.h" +#include "voxelalgorithms.h" +#include "emerge.h" + + +MapgenSinglenode::MapgenSinglenode(MapgenParams *params, EmergeParams *emerge) + : Mapgen(MAPGEN_SINGLENODE, params, emerge) +{ + const NodeDefManager *ndef = emerge->ndef; + + c_node = ndef->getId("mapgen_singlenode"); + if (c_node == CONTENT_IGNORE) + c_node = CONTENT_AIR; + + MapNode n_node(c_node); + set_light = (ndef->get(n_node).sunlight_propagates) ? LIGHT_SUN : 0x00; +} + + +//////////////////////// Map generator + +void MapgenSinglenode::makeChunk(BlockMakeData *data) +{ + // Pre-conditions + assert(data->vmanip); + assert(data->nodedef); + + this->generating = true; + this->vm = data->vmanip; + this->ndef = data->nodedef; + + v3s16 blockpos_min = data->blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + + // Area of central chunk + v3s16 node_min = blockpos_min * MAP_BLOCKSIZE; + v3s16 node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + + blockseed = getBlockSeed2(node_min, data->seed); + + MapNode n_node(c_node); + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 y = node_min.Y; y <= node_max.Y; y++) { + u32 i = vm->m_area.index(node_min.X, y, z); + for (s16 x = node_min.X; x <= node_max.X; x++) { + if (vm->m_data[i].getContent() == CONTENT_IGNORE) + vm->m_data[i] = n_node; + i++; + } + } + + // Add top and bottom side of water to transforming_liquid queue + updateLiquid(&data->transforming_liquid, node_min, node_max); + + // Set lighting + if ((flags & MG_LIGHT) && set_light == LIGHT_SUN) + setLighting(LIGHT_SUN, node_min, node_max); + + this->generating = false; +} + + +int MapgenSinglenode::getSpawnLevelAtPoint(v2s16 p) +{ + return 0; +} diff --git a/src/mapgen/mapgen_singlenode.h b/src/mapgen/mapgen_singlenode.h new file mode 100644 index 0000000..e056d9a --- /dev/null +++ b/src/mapgen/mapgen_singlenode.h @@ -0,0 +1,48 @@ +/* +Minetest +Copyright (C) 2013-2018 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2015-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "mapgen.h" + +struct MapgenSinglenodeParams : public MapgenParams +{ + MapgenSinglenodeParams() = default; + ~MapgenSinglenodeParams() = default; + + void readParams(const Settings *settings) {} + void writeParams(Settings *settings) const {} +}; + +class MapgenSinglenode : public Mapgen +{ +public: + content_t c_node; + u8 set_light; + + MapgenSinglenode(MapgenParams *params, EmergeParams *emerge); + ~MapgenSinglenode() = default; + + virtual MapgenType getType() const { return MAPGEN_SINGLENODE; } + + void makeChunk(BlockMakeData *data); + int getSpawnLevelAtPoint(v2s16 p); +}; diff --git a/src/mapgen/mapgen_v5.cpp b/src/mapgen/mapgen_v5.cpp new file mode 100644 index 0000000..87e5475 --- /dev/null +++ b/src/mapgen/mapgen_v5.cpp @@ -0,0 +1,325 @@ +/* +Minetest +Copyright (C) 2014-2018 paramat +Copyright (C) 2014-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "mapgen.h" +#include "voxel.h" +#include "noise.h" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +#include "nodedef.h" +#include "voxelalgorithms.h" +//#include "profiler.h" // For TimeTaker +#include "settings.h" // For g_settings +#include "emerge.h" +#include "dungeongen.h" +#include "cavegen.h" +#include "mg_biome.h" +#include "mg_ore.h" +#include "mg_decoration.h" +#include "mapgen_v5.h" + + +FlagDesc flagdesc_mapgen_v5[] = { + {"caverns", MGV5_CAVERNS}, + {NULL, 0} +}; + + +MapgenV5::MapgenV5(MapgenV5Params *params, EmergeParams *emerge) + : MapgenBasic(MAPGEN_V5, params, emerge) +{ + spflags = params->spflags; + cave_width = params->cave_width; + large_cave_depth = params->large_cave_depth; + small_cave_num_min = params->small_cave_num_min; + small_cave_num_max = params->small_cave_num_max; + large_cave_num_min = params->large_cave_num_min; + large_cave_num_max = params->large_cave_num_max; + large_cave_flooded = params->large_cave_flooded; + cavern_limit = params->cavern_limit; + cavern_taper = params->cavern_taper; + cavern_threshold = params->cavern_threshold; + dungeon_ymin = params->dungeon_ymin; + dungeon_ymax = params->dungeon_ymax; + + // Terrain noise + noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); + noise_factor = new Noise(¶ms->np_factor, seed, csize.X, csize.Z); + noise_height = new Noise(¶ms->np_height, seed, csize.X, csize.Z); + + // 3D terrain noise + // 1-up 1-down overgeneration + noise_ground = new Noise(¶ms->np_ground, seed, csize.X, csize.Y + 2, csize.Z); + // 1 down overgeneration + MapgenBasic::np_cave1 = params->np_cave1; + MapgenBasic::np_cave2 = params->np_cave2; + MapgenBasic::np_cavern = params->np_cavern; + MapgenBasic::np_dungeons = params->np_dungeons; +} + + +MapgenV5::~MapgenV5() +{ + delete noise_filler_depth; + delete noise_factor; + delete noise_height; + delete noise_ground; +} + + +MapgenV5Params::MapgenV5Params(): + np_filler_depth (0, 1, v3f(150, 150, 150), 261, 4, 0.7, 2.0), + np_factor (0, 1, v3f(250, 250, 250), 920381, 3, 0.45, 2.0), + np_height (0, 10, v3f(250, 250, 250), 84174, 4, 0.5, 2.0), + np_ground (0, 40, v3f(80, 80, 80), 983240, 4, 0.55, 2.0, NOISE_FLAG_EASED), + np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0), + np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0), + np_cavern (0, 1, v3f(384, 128, 384), 723, 5, 0.63, 2.0), + np_dungeons (0.9, 0.5, v3f(500, 500, 500), 0, 2, 0.8, 2.0) +{ +} + + +void MapgenV5Params::readParams(const Settings *settings) +{ + settings->getFlagStrNoEx("mgv5_spflags", spflags, flagdesc_mapgen_v5); + settings->getFloatNoEx("mgv5_cave_width", cave_width); + settings->getS16NoEx("mgv5_large_cave_depth", large_cave_depth); + settings->getU16NoEx("mgv5_small_cave_num_min", small_cave_num_min); + settings->getU16NoEx("mgv5_small_cave_num_max", small_cave_num_max); + settings->getU16NoEx("mgv5_large_cave_num_min", large_cave_num_min); + settings->getU16NoEx("mgv5_large_cave_num_max", large_cave_num_max); + settings->getFloatNoEx("mgv5_large_cave_flooded", large_cave_flooded); + settings->getS16NoEx("mgv5_cavern_limit", cavern_limit); + settings->getS16NoEx("mgv5_cavern_taper", cavern_taper); + settings->getFloatNoEx("mgv5_cavern_threshold", cavern_threshold); + settings->getS16NoEx("mgv5_dungeon_ymin", dungeon_ymin); + settings->getS16NoEx("mgv5_dungeon_ymax", dungeon_ymax); + + settings->getNoiseParams("mgv5_np_filler_depth", np_filler_depth); + settings->getNoiseParams("mgv5_np_factor", np_factor); + settings->getNoiseParams("mgv5_np_height", np_height); + settings->getNoiseParams("mgv5_np_ground", np_ground); + settings->getNoiseParams("mgv5_np_cave1", np_cave1); + settings->getNoiseParams("mgv5_np_cave2", np_cave2); + settings->getNoiseParams("mgv5_np_cavern", np_cavern); + settings->getNoiseParams("mgv5_np_dungeons", np_dungeons); +} + + +void MapgenV5Params::writeParams(Settings *settings) const +{ + settings->setFlagStr("mgv5_spflags", spflags, flagdesc_mapgen_v5); + settings->setFloat("mgv5_cave_width", cave_width); + settings->setS16("mgv5_large_cave_depth", large_cave_depth); + settings->setU16("mgv5_small_cave_num_min", small_cave_num_min); + settings->setU16("mgv5_small_cave_num_max", small_cave_num_max); + settings->setU16("mgv5_large_cave_num_min", large_cave_num_min); + settings->setU16("mgv5_large_cave_num_max", large_cave_num_max); + settings->setFloat("mgv5_large_cave_flooded", large_cave_flooded); + settings->setS16("mgv5_cavern_limit", cavern_limit); + settings->setS16("mgv5_cavern_taper", cavern_taper); + settings->setFloat("mgv5_cavern_threshold", cavern_threshold); + settings->setS16("mgv5_dungeon_ymin", dungeon_ymin); + settings->setS16("mgv5_dungeon_ymax", dungeon_ymax); + + settings->setNoiseParams("mgv5_np_filler_depth", np_filler_depth); + settings->setNoiseParams("mgv5_np_factor", np_factor); + settings->setNoiseParams("mgv5_np_height", np_height); + settings->setNoiseParams("mgv5_np_ground", np_ground); + settings->setNoiseParams("mgv5_np_cave1", np_cave1); + settings->setNoiseParams("mgv5_np_cave2", np_cave2); + settings->setNoiseParams("mgv5_np_cavern", np_cavern); + settings->setNoiseParams("mgv5_np_dungeons", np_dungeons); +} + + +void MapgenV5Params::setDefaultSettings(Settings *settings) +{ + settings->setDefault("mgv5_spflags", flagdesc_mapgen_v5, MGV5_CAVERNS); +} + + +///////////////////////////////////////////////////////////////// + + +int MapgenV5::getSpawnLevelAtPoint(v2s16 p) +{ + + float f = 0.55 + NoisePerlin2D(&noise_factor->np, p.X, p.Y, seed); + if (f < 0.01) + f = 0.01; + else if (f >= 1.0) + f *= 1.6; + float h = NoisePerlin2D(&noise_height->np, p.X, p.Y, seed); + + // noise_height 'offset' is the average level of terrain. At least 50% of + // terrain will be below this. + // Raising the maximum spawn level above 'water_level + 16' is necessary + // for when noise_height 'offset' is set much higher than water_level. + s16 max_spawn_y = MYMAX(noise_height->np.offset, water_level + 16); + + // Starting spawn search at max_spawn_y + 128 ensures 128 nodes of open + // space above spawn position. Avoids spawning in possibly sealed voids. + for (s16 y = max_spawn_y + 128; y >= water_level; y--) { + float n_ground = NoisePerlin3D(&noise_ground->np, p.X, y, p.Y, seed); + + if (n_ground * f > y - h) { // If solid + if (y < water_level || y > max_spawn_y) + return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point + + // y + 2 because y is surface and due to biome 'dust' nodes. + return y + 2; + } + } + // Unsuitable spawn position, no ground found + return MAX_MAP_GENERATION_LIMIT; +} + + +void MapgenV5::makeChunk(BlockMakeData *data) +{ + // Pre-conditions + assert(data->vmanip); + assert(data->nodedef); + + this->generating = true; + this->vm = data->vmanip; + this->ndef = data->nodedef; + //TimeTaker t("makeChunk"); + + v3s16 blockpos_min = data->blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + node_min = blockpos_min * MAP_BLOCKSIZE; + node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE; + full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + + // Create a block-specific seed + blockseed = getBlockSeed2(full_node_min, seed); + + // Generate base terrain + s16 stone_surface_max_y = generateBaseTerrain(); + + // Create heightmap + updateHeightmap(node_min, node_max); + + // Init biome generator, place biome-specific nodes, and build biomemap + if (flags & MG_BIOMES) { + biomegen->calcBiomeNoise(node_min); + generateBiomes(); + } + + // Generate tunnels, caverns and large randomwalk caves + if (flags & MG_CAVES) { + // Generate tunnels first as caverns confuse them + generateCavesNoiseIntersection(stone_surface_max_y); + + // Generate caverns + bool near_cavern = false; + if (spflags & MGV5_CAVERNS) + near_cavern = generateCavernsNoise(stone_surface_max_y); + + // Generate large randomwalk caves + if (near_cavern) + // Disable large randomwalk caves in this mapchunk by setting + // 'large cave depth' to world base. Avoids excessive liquid in + // large caverns and floating blobs of overgenerated liquid. + generateCavesRandomWalk(stone_surface_max_y, + -MAX_MAP_GENERATION_LIMIT); + else + generateCavesRandomWalk(stone_surface_max_y, large_cave_depth); + } + + // Generate the registered ores + if (flags & MG_ORES) + m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max); + + // Generate dungeons and desert temples + if (flags & MG_DUNGEONS) + generateDungeons(stone_surface_max_y); + + // Generate the registered decorations + if (flags & MG_DECORATIONS) + m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max); + + // Sprinkle some dust on top after everything else was generated + if (flags & MG_BIOMES) + dustTopNodes(); + + //printf("makeChunk: %dms\n", t.stop()); + + // Add top and bottom side of water to transforming_liquid queue + updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); + + // Calculate lighting + if (flags & MG_LIGHT) { + calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0), + full_node_min, full_node_max); + } + + this->generating = false; +} + + +int MapgenV5::generateBaseTerrain() +{ + u32 index = 0; + u32 index2d = 0; + int stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; + + noise_factor->perlinMap2D(node_min.X, node_min.Z); + noise_height->perlinMap2D(node_min.X, node_min.Z); + noise_ground->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + + for (s16 z=node_min.Z; z<=node_max.Z; z++) { + for (s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) { + u32 vi = vm->m_area.index(node_min.X, y, z); + for (s16 x=node_min.X; x<=node_max.X; x++, vi++, index++, index2d++) { + if (vm->m_data[vi].getContent() != CONTENT_IGNORE) + continue; + + float f = 0.55 + noise_factor->result[index2d]; + if (f < 0.01) + f = 0.01; + else if (f >= 1.0) + f *= 1.6; + float h = noise_height->result[index2d]; + + if (noise_ground->result[index] * f < y - h) { + if (y <= water_level) + vm->m_data[vi] = MapNode(c_water_source); + else + vm->m_data[vi] = MapNode(CONTENT_AIR); + } else { + vm->m_data[vi] = MapNode(c_stone); + if (y > stone_surface_max_y) + stone_surface_max_y = y; + } + } + index2d -= ystride; + } + index2d += ystride; + } + + return stone_surface_max_y; +} diff --git a/src/mapgen/mapgen_v5.h b/src/mapgen/mapgen_v5.h new file mode 100644 index 0000000..cf4ee48 --- /dev/null +++ b/src/mapgen/mapgen_v5.h @@ -0,0 +1,80 @@ +/* +Minetest +Copyright (C) 2014-2018 paramat +Copyright (C) 2014-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "mapgen.h" + +///////// Mapgen V5 flags +#define MGV5_CAVERNS 0x01 + +class BiomeManager; + +extern FlagDesc flagdesc_mapgen_v5[]; + +struct MapgenV5Params : public MapgenParams +{ + float cave_width = 0.09f; + s16 large_cave_depth = -256; + u16 small_cave_num_min = 0; + u16 small_cave_num_max = 0; + u16 large_cave_num_min = 0; + u16 large_cave_num_max = 2; + float large_cave_flooded = 0.5f; + s16 cavern_limit = -256; + s16 cavern_taper = 256; + float cavern_threshold = 0.7f; + s16 dungeon_ymin = -31000; + s16 dungeon_ymax = 31000; + + NoiseParams np_filler_depth; + NoiseParams np_factor; + NoiseParams np_height; + NoiseParams np_ground; + NoiseParams np_cave1; + NoiseParams np_cave2; + NoiseParams np_cavern; + NoiseParams np_dungeons; + + MapgenV5Params(); + ~MapgenV5Params() = default; + + void readParams(const Settings *settings); + void writeParams(Settings *settings) const; + void setDefaultSettings(Settings *settings); +}; + +class MapgenV5 : public MapgenBasic +{ +public: + MapgenV5(MapgenV5Params *params, EmergeParams *emerge); + ~MapgenV5(); + + virtual MapgenType getType() const { return MAPGEN_V5; } + + virtual void makeChunk(BlockMakeData *data); + int getSpawnLevelAtPoint(v2s16 p); + int generateBaseTerrain(); + +private: + Noise *noise_factor; + Noise *noise_height; + Noise *noise_ground; +}; diff --git a/src/mapgen/mapgen_v6.cpp b/src/mapgen/mapgen_v6.cpp new file mode 100644 index 0000000..a418aca --- /dev/null +++ b/src/mapgen/mapgen_v6.cpp @@ -0,0 +1,1117 @@ +/* +Minetest +Copyright (C) 2010-2018 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2014-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include <cmath> +#include "mapgen.h" +#include "voxel.h" +#include "noise.h" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +#include "nodedef.h" +#include "voxelalgorithms.h" +//#include "profiler.h" // For TimeTaker +#include "settings.h" // For g_settings +#include "emerge.h" +#include "dungeongen.h" +#include "cavegen.h" +#include "treegen.h" +#include "mg_ore.h" +#include "mg_decoration.h" +#include "mapgen_v6.h" + + +FlagDesc flagdesc_mapgen_v6[] = { + {"jungles", MGV6_JUNGLES}, + {"biomeblend", MGV6_BIOMEBLEND}, + {"mudflow", MGV6_MUDFLOW}, + {"snowbiomes", MGV6_SNOWBIOMES}, + {"flat", MGV6_FLAT}, + {"trees", MGV6_TREES}, + {NULL, 0} +}; + + +///////////////////////////////////////////////////////////////////////////// + + +MapgenV6::MapgenV6(MapgenV6Params *params, EmergeParams *emerge) + : Mapgen(MAPGEN_V6, params, emerge) +{ + m_emerge = emerge; + ystride = csize.X; + + heightmap = new s16[csize.X * csize.Z]; + + spflags = params->spflags; + freq_desert = params->freq_desert; + freq_beach = params->freq_beach; + dungeon_ymin = params->dungeon_ymin; + dungeon_ymax = params->dungeon_ymax; + + np_cave = ¶ms->np_cave; + np_humidity = ¶ms->np_humidity; + np_trees = ¶ms->np_trees; + np_apple_trees = ¶ms->np_apple_trees; + + np_dungeons = NoiseParams(0.9, 0.5, v3f(500.0, 500.0, 500.0), 0, 2, 0.8, 2.0); + + //// Create noise objects + noise_terrain_base = new Noise(¶ms->np_terrain_base, seed, csize.X, csize.Y); + noise_terrain_higher = new Noise(¶ms->np_terrain_higher, seed, csize.X, csize.Y); + noise_steepness = new Noise(¶ms->np_steepness, seed, csize.X, csize.Y); + noise_height_select = new Noise(¶ms->np_height_select, seed, csize.X, csize.Y); + noise_mud = new Noise(¶ms->np_mud, seed, csize.X, csize.Y); + noise_beach = new Noise(¶ms->np_beach, seed, csize.X, csize.Y); + noise_biome = new Noise(¶ms->np_biome, seed, + csize.X + 2 * MAP_BLOCKSIZE, csize.Y + 2 * MAP_BLOCKSIZE); + noise_humidity = new Noise(¶ms->np_humidity, seed, + csize.X + 2 * MAP_BLOCKSIZE, csize.Y + 2 * MAP_BLOCKSIZE); + + //// Resolve nodes to be used + const NodeDefManager *ndef = emerge->ndef; + + c_stone = ndef->getId("mapgen_stone"); + c_dirt = ndef->getId("mapgen_dirt"); + c_dirt_with_grass = ndef->getId("mapgen_dirt_with_grass"); + c_sand = ndef->getId("mapgen_sand"); + c_water_source = ndef->getId("mapgen_water_source"); + c_lava_source = ndef->getId("mapgen_lava_source"); + c_gravel = ndef->getId("mapgen_gravel"); + c_desert_stone = ndef->getId("mapgen_desert_stone"); + c_desert_sand = ndef->getId("mapgen_desert_sand"); + c_dirt_with_snow = ndef->getId("mapgen_dirt_with_snow"); + c_snow = ndef->getId("mapgen_snow"); + c_snowblock = ndef->getId("mapgen_snowblock"); + c_ice = ndef->getId("mapgen_ice"); + + if (c_gravel == CONTENT_IGNORE) + c_gravel = c_stone; + if (c_desert_stone == CONTENT_IGNORE) + c_desert_stone = c_stone; + if (c_desert_sand == CONTENT_IGNORE) + c_desert_sand = c_sand; + if (c_dirt_with_snow == CONTENT_IGNORE) + c_dirt_with_snow = c_dirt_with_grass; + if (c_snow == CONTENT_IGNORE) + c_snow = CONTENT_AIR; + if (c_snowblock == CONTENT_IGNORE) + c_snowblock = c_dirt_with_grass; + if (c_ice == CONTENT_IGNORE) + c_ice = c_water_source; + + c_cobble = ndef->getId("mapgen_cobble"); + c_mossycobble = ndef->getId("mapgen_mossycobble"); + c_stair_cobble = ndef->getId("mapgen_stair_cobble"); + c_stair_desert_stone = ndef->getId("mapgen_stair_desert_stone"); + + if (c_mossycobble == CONTENT_IGNORE) + c_mossycobble = c_cobble; + if (c_stair_cobble == CONTENT_IGNORE) + c_stair_cobble = c_cobble; + if (c_stair_desert_stone == CONTENT_IGNORE) + c_stair_desert_stone = c_desert_stone; + + if (c_stone == CONTENT_IGNORE) + errorstream << "Mapgen v6: Mapgen alias 'mapgen_stone' is invalid!" << std::endl; + if (c_dirt == CONTENT_IGNORE) + errorstream << "Mapgen v6: Mapgen alias 'mapgen_dirt' is invalid!" << std::endl; + if (c_dirt_with_grass == CONTENT_IGNORE) + errorstream << "Mapgen v6: Mapgen alias 'mapgen_dirt_with_grass' is invalid!" << std::endl; + if (c_sand == CONTENT_IGNORE) + errorstream << "Mapgen v6: Mapgen alias 'mapgen_sand' is invalid!" << std::endl; + if (c_water_source == CONTENT_IGNORE) + errorstream << "Mapgen v6: Mapgen alias 'mapgen_water_source' is invalid!" << std::endl; + if (c_lava_source == CONTENT_IGNORE) + errorstream << "Mapgen v6: Mapgen alias 'mapgen_lava_source' is invalid!" << std::endl; + if (c_cobble == CONTENT_IGNORE) + errorstream << "Mapgen v6: Mapgen alias 'mapgen_cobble' is invalid!" << std::endl; +} + + +MapgenV6::~MapgenV6() +{ + delete noise_terrain_base; + delete noise_terrain_higher; + delete noise_steepness; + delete noise_height_select; + delete noise_mud; + delete noise_beach; + delete noise_biome; + delete noise_humidity; + + delete[] heightmap; + + delete m_emerge; // our responsibility +} + + +MapgenV6Params::MapgenV6Params(): + np_terrain_base (-4, 20.0, v3f(250.0, 250.0, 250.0), 82341, 5, 0.6, 2.0), + np_terrain_higher (20, 16.0, v3f(500.0, 500.0, 500.0), 85039, 5, 0.6, 2.0), + np_steepness (0.85, 0.5, v3f(125.0, 125.0, 125.0), -932, 5, 0.7, 2.0), + np_height_select (0, 1.0, v3f(250.0, 250.0, 250.0), 4213, 5, 0.69, 2.0), + np_mud (4, 2.0, v3f(200.0, 200.0, 200.0), 91013, 3, 0.55, 2.0), + np_beach (0, 1.0, v3f(250.0, 250.0, 250.0), 59420, 3, 0.50, 2.0), + np_biome (0, 1.0, v3f(500.0, 500.0, 500.0), 9130, 3, 0.50, 2.0), + np_cave (6, 6.0, v3f(250.0, 250.0, 250.0), 34329, 3, 0.50, 2.0), + np_humidity (0.5, 0.5, v3f(500.0, 500.0, 500.0), 72384, 3, 0.50, 2.0), + np_trees (0, 1.0, v3f(125.0, 125.0, 125.0), 2, 4, 0.66, 2.0), + np_apple_trees (0, 1.0, v3f(100.0, 100.0, 100.0), 342902, 3, 0.45, 2.0) +{ +} + + +void MapgenV6Params::readParams(const Settings *settings) +{ + settings->getFlagStrNoEx("mgv6_spflags", spflags, flagdesc_mapgen_v6); + settings->getFloatNoEx("mgv6_freq_desert", freq_desert); + settings->getFloatNoEx("mgv6_freq_beach", freq_beach); + settings->getS16NoEx("mgv6_dungeon_ymin", dungeon_ymin); + settings->getS16NoEx("mgv6_dungeon_ymax", dungeon_ymax); + + settings->getNoiseParams("mgv6_np_terrain_base", np_terrain_base); + settings->getNoiseParams("mgv6_np_terrain_higher", np_terrain_higher); + settings->getNoiseParams("mgv6_np_steepness", np_steepness); + settings->getNoiseParams("mgv6_np_height_select", np_height_select); + settings->getNoiseParams("mgv6_np_mud", np_mud); + settings->getNoiseParams("mgv6_np_beach", np_beach); + settings->getNoiseParams("mgv6_np_biome", np_biome); + settings->getNoiseParams("mgv6_np_cave", np_cave); + settings->getNoiseParams("mgv6_np_humidity", np_humidity); + settings->getNoiseParams("mgv6_np_trees", np_trees); + settings->getNoiseParams("mgv6_np_apple_trees", np_apple_trees); +} + + +void MapgenV6Params::writeParams(Settings *settings) const +{ + settings->setFlagStr("mgv6_spflags", spflags, flagdesc_mapgen_v6); + settings->setFloat("mgv6_freq_desert", freq_desert); + settings->setFloat("mgv6_freq_beach", freq_beach); + settings->setS16("mgv6_dungeon_ymin", dungeon_ymin); + settings->setS16("mgv6_dungeon_ymax", dungeon_ymax); + + settings->setNoiseParams("mgv6_np_terrain_base", np_terrain_base); + settings->setNoiseParams("mgv6_np_terrain_higher", np_terrain_higher); + settings->setNoiseParams("mgv6_np_steepness", np_steepness); + settings->setNoiseParams("mgv6_np_height_select", np_height_select); + settings->setNoiseParams("mgv6_np_mud", np_mud); + settings->setNoiseParams("mgv6_np_beach", np_beach); + settings->setNoiseParams("mgv6_np_biome", np_biome); + settings->setNoiseParams("mgv6_np_cave", np_cave); + settings->setNoiseParams("mgv6_np_humidity", np_humidity); + settings->setNoiseParams("mgv6_np_trees", np_trees); + settings->setNoiseParams("mgv6_np_apple_trees", np_apple_trees); +} + + +void MapgenV6Params::setDefaultSettings(Settings *settings) +{ + settings->setDefault("mgv6_spflags", flagdesc_mapgen_v6, MGV6_JUNGLES | + MGV6_SNOWBIOMES | MGV6_TREES | MGV6_BIOMEBLEND | MGV6_MUDFLOW); +} + + +//////////////////////// Some helper functions for the map generator + + +// Returns Y one under area minimum if not found +s16 MapgenV6::find_stone_level(v2s16 p2d) +{ + const v3s16 &em = vm->m_area.getExtent(); + s16 y_nodes_max = vm->m_area.MaxEdge.Y; + s16 y_nodes_min = vm->m_area.MinEdge.Y; + u32 i = vm->m_area.index(p2d.X, y_nodes_max, p2d.Y); + s16 y; + + for (y = y_nodes_max; y >= y_nodes_min; y--) { + content_t c = vm->m_data[i].getContent(); + if (c != CONTENT_IGNORE && (c == c_stone || c == c_desert_stone)) + break; + + VoxelArea::add_y(em, i, -1); + } + return (y >= y_nodes_min) ? y : y_nodes_min - 1; +} + + +// Required by mapgen.h +bool MapgenV6::block_is_underground(u64 seed, v3s16 blockpos) +{ + /*s16 minimum_groundlevel = (s16)get_sector_minimum_ground_level( + seed, v2s16(blockpos.X, blockpos.Z));*/ + // Nah, this is just a heuristic, just return something + s16 minimum_groundlevel = water_level; + + if(blockpos.Y * MAP_BLOCKSIZE + MAP_BLOCKSIZE <= minimum_groundlevel) + return true; + + return false; +} + + +//////////////////////// Base terrain height functions + +float MapgenV6::baseTerrainLevel(float terrain_base, float terrain_higher, + float steepness, float height_select) +{ + float base = 1 + terrain_base; + float higher = 1 + terrain_higher; + + // Limit higher ground level to at least base + if(higher < base) + higher = base; + + // Steepness factor of cliffs + float b = steepness; + b = rangelim(b, 0.0, 1000.0); + b = 5 * b * b * b * b * b * b * b; + b = rangelim(b, 0.5, 1000.0); + + // Values 1.5...100 give quite horrible looking slopes + if (b > 1.5 && b < 100.0) + b = (b < 10.0) ? 1.5 : 100.0; + + float a_off = -0.20; // Offset to more low + float a = 0.5 + b * (a_off + height_select); + a = rangelim(a, 0.0, 1.0); // Limit + + return base * (1.0 - a) + higher * a; +} + + +float MapgenV6::baseTerrainLevelFromNoise(v2s16 p) +{ + if (spflags & MGV6_FLAT) + return water_level; + + float terrain_base = NoisePerlin2D_PO(&noise_terrain_base->np, + p.X, 0.5, p.Y, 0.5, seed); + float terrain_higher = NoisePerlin2D_PO(&noise_terrain_higher->np, + p.X, 0.5, p.Y, 0.5, seed); + float steepness = NoisePerlin2D_PO(&noise_steepness->np, + p.X, 0.5, p.Y, 0.5, seed); + float height_select = NoisePerlin2D_PO(&noise_height_select->np, + p.X, 0.5, p.Y, 0.5, seed); + + return baseTerrainLevel(terrain_base, terrain_higher, + steepness, height_select); +} + + +float MapgenV6::baseTerrainLevelFromMap(v2s16 p) +{ + int index = (p.Y - node_min.Z) * ystride + (p.X - node_min.X); + return baseTerrainLevelFromMap(index); +} + + +float MapgenV6::baseTerrainLevelFromMap(int index) +{ + if (spflags & MGV6_FLAT) + return water_level; + + float terrain_base = noise_terrain_base->result[index]; + float terrain_higher = noise_terrain_higher->result[index]; + float steepness = noise_steepness->result[index]; + float height_select = noise_height_select->result[index]; + + return baseTerrainLevel(terrain_base, terrain_higher, + steepness, height_select); +} + + +int MapgenV6::getGroundLevelAtPoint(v2s16 p) +{ + return baseTerrainLevelFromNoise(p) + MGV6_AVERAGE_MUD_AMOUNT; +} + + +int MapgenV6::getSpawnLevelAtPoint(v2s16 p) +{ + s16 level_at_point = baseTerrainLevelFromNoise(p) + MGV6_AVERAGE_MUD_AMOUNT; + if (level_at_point <= water_level || + level_at_point > water_level + 16) + return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point + + return level_at_point; +} + + +//////////////////////// Noise functions + + +BiomeV6Type MapgenV6::getBiome(v2s16 p) +{ + int index = (p.Y - full_node_min.Z) * (ystride + 2 * MAP_BLOCKSIZE) + + (p.X - full_node_min.X); + return getBiome(index, p); +} + + +float MapgenV6::getHumidity(v2s16 p) +{ + /*double noise = noise2d_perlin( + 0.5+(float)p.X/500, 0.5+(float)p.Y/500, + seed+72384, 4, 0.66); + noise = (noise + 1.0)/2.0;*/ + + int index = (p.Y - full_node_min.Z) * (ystride + 2 * MAP_BLOCKSIZE) + + (p.X - full_node_min.X); + float noise = noise_humidity->result[index]; + + if (noise < 0.0) + noise = 0.0; + if (noise > 1.0) + noise = 1.0; + return noise; +} + + +float MapgenV6::getTreeAmount(v2s16 p) +{ + /*double noise = noise2d_perlin( + 0.5+(float)p.X/125, 0.5+(float)p.Y/125, + seed+2, 4, 0.66);*/ + + float noise = NoisePerlin2D(np_trees, p.X, p.Y, seed); + float zeroval = -0.39; + if (noise < zeroval) + return 0; + + return 0.04 * (noise - zeroval) / (1.0 - zeroval); +} + + +bool MapgenV6::getHaveAppleTree(v2s16 p) +{ + /*is_apple_tree = noise2d_perlin( + 0.5+(float)p.X/100, 0.5+(float)p.Z/100, + data->seed+342902, 3, 0.45) > 0.2;*/ + + float noise = NoisePerlin2D(np_apple_trees, p.X, p.Y, seed); + + return noise > 0.2; +} + + +float MapgenV6::getMudAmount(int index) +{ + if (spflags & MGV6_FLAT) + return MGV6_AVERAGE_MUD_AMOUNT; + + /*return ((float)AVERAGE_MUD_AMOUNT + 2.0 * noise2d_perlin( + 0.5+(float)p.X/200, 0.5+(float)p.Y/200, + seed+91013, 3, 0.55));*/ + + return noise_mud->result[index]; +} + + +bool MapgenV6::getHaveBeach(int index) +{ + // Determine whether to have sand here + /*double sandnoise = noise2d_perlin( + 0.2+(float)p2d.X/250, 0.7+(float)p2d.Y/250, + seed+59420, 3, 0.50);*/ + + float sandnoise = noise_beach->result[index]; + return (sandnoise > freq_beach); +} + + +BiomeV6Type MapgenV6::getBiome(int index, v2s16 p) +{ + // Just do something very simple as for now + /*double d = noise2d_perlin( + 0.6+(float)p2d.X/250, 0.2+(float)p2d.Y/250, + seed+9130, 3, 0.50);*/ + + float d = noise_biome->result[index]; + float h = noise_humidity->result[index]; + + if (spflags & MGV6_SNOWBIOMES) { + float blend = (spflags & MGV6_BIOMEBLEND) ? noise2d(p.X, p.Y, seed) / 40 : 0; + + if (d > MGV6_FREQ_HOT + blend) { + if (h > MGV6_FREQ_JUNGLE + blend) + return BT_JUNGLE; + + return BT_DESERT; + } + + if (d < MGV6_FREQ_SNOW + blend) { + if (h > MGV6_FREQ_TAIGA + blend) + return BT_TAIGA; + + return BT_TUNDRA; + } + + return BT_NORMAL; + } + + if (d > freq_desert) + return BT_DESERT; + + if ((spflags & MGV6_BIOMEBLEND) && (d > freq_desert - 0.10) && + ((noise2d(p.X, p.Y, seed) + 1.0) > (freq_desert - d) * 20.0)) + return BT_DESERT; + + if ((spflags & MGV6_JUNGLES) && h > 0.75) + return BT_JUNGLE; + + return BT_NORMAL; + +} + + +u32 MapgenV6::get_blockseed(u64 seed, v3s16 p) +{ + s32 x = p.X, y = p.Y, z = p.Z; + return (u32)(seed % 0x100000000ULL) + z * 38134234 + y * 42123 + x * 23; +} + + +//////////////////////// Map generator + +void MapgenV6::makeChunk(BlockMakeData *data) +{ + // Pre-conditions + assert(data->vmanip); + assert(data->nodedef); + + this->generating = true; + this->vm = data->vmanip; + this->ndef = data->nodedef; + + // Hack: use minimum block coords for old code that assumes a single block + v3s16 blockpos_min = data->blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + + // Area of central chunk + node_min = blockpos_min * MAP_BLOCKSIZE; + node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + + // Full allocated area + full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE; + full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + + central_area_size = node_max - node_min + v3s16(1, 1, 1); + assert(central_area_size.X == central_area_size.Z); + + // Create a block-specific seed + blockseed = get_blockseed(data->seed, full_node_min); + + // Make some noise + calculateNoise(); + + // Maximum height of the stone surface and obstacles. + // This is used to guide the cave generation + s16 stone_surface_max_y; + + // Generate general ground level to full area + stone_surface_max_y = generateGround(); + + // Create initial heightmap to limit caves + updateHeightmap(node_min, node_max); + + const s16 max_spread_amount = MAP_BLOCKSIZE; + // Limit dirt flow area by 1 because mud is flowed into neighbors + s16 mudflow_minpos = -max_spread_amount + 1; + s16 mudflow_maxpos = central_area_size.X + max_spread_amount - 2; + + // Loop this part, it will make stuff look older and newer nicely + const u32 age_loops = 2; + for (u32 i_age = 0; i_age < age_loops; i_age++) { // Aging loop + // Make caves (this code is relatively horrible) + if (flags & MG_CAVES) + generateCaves(stone_surface_max_y); + + // Add mud to the central chunk + addMud(); + + // Flow mud away from steep edges + if (spflags & MGV6_MUDFLOW) + flowMud(mudflow_minpos, mudflow_maxpos); + + } + + // Update heightmap after mudflow + updateHeightmap(node_min, node_max); + + // Add dungeons + if ((flags & MG_DUNGEONS) && stone_surface_max_y >= node_min.Y && + full_node_min.Y >= dungeon_ymin && full_node_max.Y <= dungeon_ymax) { + u16 num_dungeons = std::fmax(std::floor( + NoisePerlin3D(&np_dungeons, node_min.X, node_min.Y, node_min.Z, seed)), 0.0f); + + if (num_dungeons >= 1) { + PseudoRandom ps(blockseed + 4713); + + DungeonParams dp; + + dp.seed = seed; + dp.num_dungeons = num_dungeons; + dp.only_in_ground = true; + dp.corridor_len_min = 1; + dp.corridor_len_max = 13; + dp.num_rooms = ps.range(2, 16); + dp.large_room_chance = (ps.range(1, 4) == 1) ? 1 : 0; + + dp.np_alt_wall + = NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0); + + if (getBiome(0, v2s16(node_min.X, node_min.Z)) == BT_DESERT) { + dp.c_wall = c_desert_stone; + dp.c_alt_wall = CONTENT_IGNORE; + dp.c_stair = c_stair_desert_stone; + + dp.diagonal_dirs = true; + dp.holesize = v3s16(2, 3, 2); + dp.room_size_min = v3s16(6, 9, 6); + dp.room_size_max = v3s16(10, 11, 10); + dp.room_size_large_min = v3s16(10, 13, 10); + dp.room_size_large_max = v3s16(18, 21, 18); + dp.notifytype = GENNOTIFY_TEMPLE; + } else { + dp.c_wall = c_cobble; + dp.c_alt_wall = c_mossycobble; + dp.c_stair = c_stair_cobble; + + dp.diagonal_dirs = false; + dp.holesize = v3s16(1, 2, 1); + dp.room_size_min = v3s16(4, 4, 4); + dp.room_size_max = v3s16(8, 6, 8); + dp.room_size_large_min = v3s16(8, 8, 8); + dp.room_size_large_max = v3s16(16, 16, 16); + dp.notifytype = GENNOTIFY_DUNGEON; + } + + DungeonGen dgen(ndef, &gennotify, &dp); + dgen.generate(vm, blockseed, full_node_min, full_node_max); + } + } + + // Add top and bottom side of water to transforming_liquid queue + updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); + + // Add surface nodes + growGrass(); + + // Generate some trees, and add grass, if a jungle + if (spflags & MGV6_TREES) + placeTreesAndJungleGrass(); + + // Generate the registered decorations + if (flags & MG_DECORATIONS) + m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max); + + // Generate the registered ores + if (flags & MG_ORES) + m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max); + + // Calculate lighting + if (flags & MG_LIGHT) + calcLighting(node_min - v3s16(1, 1, 1) * MAP_BLOCKSIZE, + node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, + full_node_min, full_node_max); + + this->generating = false; +} + + +void MapgenV6::calculateNoise() +{ + int x = node_min.X; + int z = node_min.Z; + int fx = full_node_min.X; + int fz = full_node_min.Z; + + if (!(spflags & MGV6_FLAT)) { + noise_terrain_base->perlinMap2D_PO(x, 0.5, z, 0.5); + noise_terrain_higher->perlinMap2D_PO(x, 0.5, z, 0.5); + noise_steepness->perlinMap2D_PO(x, 0.5, z, 0.5); + noise_height_select->perlinMap2D_PO(x, 0.5, z, 0.5); + noise_mud->perlinMap2D_PO(x, 0.5, z, 0.5); + } + + noise_beach->perlinMap2D_PO(x, 0.2, z, 0.7); + + noise_biome->perlinMap2D_PO(fx, 0.6, fz, 0.2); + noise_humidity->perlinMap2D_PO(fx, 0.0, fz, 0.0); + // Humidity map does not need range limiting 0 to 1, + // only humidity at point does +} + + +int MapgenV6::generateGround() +{ + //TimeTaker timer1("Generating ground level"); + MapNode n_air(CONTENT_AIR), n_water_source(c_water_source); + MapNode n_stone(c_stone), n_desert_stone(c_desert_stone); + MapNode n_ice(c_ice); + int stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; + + u32 index = 0; + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index++) { + // Surface height + s16 surface_y = (s16)baseTerrainLevelFromMap(index); + + // Log it + if (surface_y > stone_surface_max_y) + stone_surface_max_y = surface_y; + + BiomeV6Type bt = getBiome(v2s16(x, z)); + + // Fill ground with stone + const v3s16 &em = vm->m_area.getExtent(); + u32 i = vm->m_area.index(x, node_min.Y, z); + for (s16 y = node_min.Y; y <= node_max.Y; y++) { + if (vm->m_data[i].getContent() == CONTENT_IGNORE) { + if (y <= surface_y) { + vm->m_data[i] = (y >= MGV6_DESERT_STONE_BASE + && bt == BT_DESERT) ? + n_desert_stone : n_stone; + } else if (y <= water_level) { + vm->m_data[i] = (y >= MGV6_ICE_BASE + && bt == BT_TUNDRA) ? + n_ice : n_water_source; + } else { + vm->m_data[i] = n_air; + } + } + VoxelArea::add_y(em, i, 1); + } + } + + return stone_surface_max_y; +} + + +void MapgenV6::addMud() +{ + // 15ms @cs=8 + //TimeTaker timer1("add mud"); + MapNode n_dirt(c_dirt), n_gravel(c_gravel); + MapNode n_sand(c_sand), n_desert_sand(c_desert_sand); + MapNode addnode; + + u32 index = 0; + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index++) { + // Randomize mud amount + s16 mud_add_amount = getMudAmount(index) / 2.0 + 0.5; + + // Find ground level + s16 surface_y = find_stone_level(v2s16(x, z)); /////////////////optimize this! + + // Handle area not found + if (surface_y == vm->m_area.MinEdge.Y - 1) + continue; + + BiomeV6Type bt = getBiome(v2s16(x, z)); + addnode = (bt == BT_DESERT) ? n_desert_sand : n_dirt; + + if (bt == BT_DESERT && surface_y + mud_add_amount <= water_level + 1) { + addnode = n_sand; + } else if (mud_add_amount <= 0) { + mud_add_amount = 1 - mud_add_amount; + addnode = n_gravel; + } else if (bt != BT_DESERT && getHaveBeach(index) && + surface_y + mud_add_amount <= water_level + 2) { + addnode = n_sand; + } + + if ((bt == BT_DESERT || bt == BT_TUNDRA) && surface_y > 20) + mud_add_amount = MYMAX(0, mud_add_amount - (surface_y - 20) / 5); + + /* If topmost node is grass, change it to mud. It might be if it was + // flown to there from a neighboring chunk and then converted. + u32 i = vm->m_area.index(x, surface_y, z); + if (vm->m_data[i].getContent() == c_dirt_with_grass) + vm->m_data[i] = n_dirt;*/ + + // Add mud on ground + s16 mudcount = 0; + const v3s16 &em = vm->m_area.getExtent(); + s16 y_start = surface_y + 1; + u32 i = vm->m_area.index(x, y_start, z); + for (s16 y = y_start; y <= node_max.Y; y++) { + if (mudcount >= mud_add_amount) + break; + + vm->m_data[i] = addnode; + mudcount++; + + VoxelArea::add_y(em, i, 1); + } + } +} + + +void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos) +{ + const v3s16 &em = vm->m_area.getExtent(); + static const v3s16 dirs4[4] = { + v3s16(0, 0, 1), // Back + v3s16(1, 0, 0), // Right + v3s16(0, 0, -1), // Front + v3s16(-1, 0, 0), // Left + }; + + // Iterate twice + for (s16 k = 0; k < 2; k++) { + for (s16 z = mudflow_minpos; z <= mudflow_maxpos; z++) + for (s16 x = mudflow_minpos; x <= mudflow_maxpos; x++) { + // Node column position + v2s16 p2d; + // Invert coordinates on second iteration to process columns in + // opposite order, to avoid a directional bias. + if (k == 1) + p2d = v2s16(node_max.X, node_max.Z) - v2s16(x, z); + else + p2d = v2s16(node_min.X, node_min.Z) + v2s16(x, z); + + s16 y = node_max.Y; + + while (y >= node_min.Y) { + for (;; y--) { + u32 i = vm->m_area.index(p2d.X, y, p2d.Y); + MapNode *n = nullptr; + + // Find next mud node in mapchunk column + for (; y >= node_min.Y; y--) { + n = &vm->m_data[i]; + if (n->getContent() == c_dirt || + n->getContent() == c_dirt_with_grass || + n->getContent() == c_gravel) + break; + + VoxelArea::add_y(em, i, -1); + } + if (y < node_min.Y) + // No mud found in mapchunk column, process the next column + break; + + if (n->getContent() == c_dirt || n->getContent() == c_dirt_with_grass) { + // Convert dirt_with_grass to dirt + n->setContent(c_dirt); + // Don't flow mud if the stuff under it is not mud, + // to leave at least 1 node of mud. + u32 i2 = i; + VoxelArea::add_y(em, i2, -1); + MapNode *n2 = &vm->m_data[i2]; + if (n2->getContent() != c_dirt && + n2->getContent() != c_dirt_with_grass) + // Find next mud node in column + continue; + } + + // Check if node above is walkable. If so, cancel + // flowing as if node above keeps it in place. + u32 i3 = i; + VoxelArea::add_y(em, i3, 1); + MapNode *n3 = &vm->m_data[i3]; + if (ndef->get(*n3).walkable) + // Find next mud node in column + continue; + + // Drop mud on one side + for (const v3s16 &dirp : dirs4) { + u32 i2 = i; + // Move to side + VoxelArea::add_p(em, i2, dirp); + // Check that side is air + MapNode *n2 = &vm->m_data[i2]; + if (ndef->get(*n2).walkable) + continue; + + // Check that under side is air + VoxelArea::add_y(em, i2, -1); + n2 = &vm->m_data[i2]; + if (ndef->get(*n2).walkable) + continue; + + // Loop further down until not air + s16 y2 = y - 1; // y of i2 + bool dropped_to_unknown = false; + do { + y2--; + VoxelArea::add_y(em, i2, -1); + n2 = &vm->m_data[i2]; + // If out of area or in ungenerated world + if (y2 < full_node_min.Y || n2->getContent() == CONTENT_IGNORE) { + dropped_to_unknown = true; + break; + } + } while (!ndef->get(*n2).walkable); + + if (!dropped_to_unknown) { + // Move up one so that we're in air + VoxelArea::add_y(em, i2, 1); + // Move mud to new place, and if outside mapchunk remove + // any decorations above removed or placed mud. + moveMud(i, i2, i3, p2d, em); + } + // Done, find next mud node in column + break; + } + } + } + } + } +} + + +void MapgenV6::moveMud(u32 remove_index, u32 place_index, + u32 above_remove_index, v2s16 pos, v3s16 em) +{ + MapNode n_air(CONTENT_AIR); + // Copy mud from old place to new place + vm->m_data[place_index] = vm->m_data[remove_index]; + // Set old place to be air + vm->m_data[remove_index] = n_air; + // Outside the mapchunk decorations may need to be removed if above removed + // mud or if half-buried in placed mud. Placed mud is to the side of pos so + // use 'pos.X >= node_max.X' etc. + if (pos.X >= node_max.X || pos.X <= node_min.X || + pos.Y >= node_max.Z || pos.Y <= node_min.Z) { + // 'above remove' node is above removed mud. If it is not air, water or + // 'ignore' it is a decoration that needs removing. Also search upwards + // to remove a possible stacked decoration. + // Check for 'ignore' because stacked decorations can penetrate into + // 'ignore' nodes above the mapchunk. + while (vm->m_area.contains(above_remove_index) && + vm->m_data[above_remove_index].getContent() != CONTENT_AIR && + vm->m_data[above_remove_index].getContent() != c_water_source && + vm->m_data[above_remove_index].getContent() != CONTENT_IGNORE) { + vm->m_data[above_remove_index] = n_air; + VoxelArea::add_y(em, above_remove_index, 1); + } + // Mud placed may have partially-buried a stacked decoration, search + // above and remove. + VoxelArea::add_y(em, place_index, 1); + while (vm->m_area.contains(place_index) && + vm->m_data[place_index].getContent() != CONTENT_AIR && + vm->m_data[place_index].getContent() != c_water_source && + vm->m_data[place_index].getContent() != CONTENT_IGNORE) { + vm->m_data[place_index] = n_air; + VoxelArea::add_y(em, place_index, 1); + } + } +} + + +void MapgenV6::placeTreesAndJungleGrass() +{ + //TimeTaker t("placeTrees"); + if (node_max.Y < water_level) + return; + + PseudoRandom grassrandom(blockseed + 53); + content_t c_junglegrass = ndef->getId("mapgen_junglegrass"); + // if we don't have junglegrass, don't place cignore... that's bad + if (c_junglegrass == CONTENT_IGNORE) + c_junglegrass = CONTENT_AIR; + MapNode n_junglegrass(c_junglegrass); + const v3s16 &em = vm->m_area.getExtent(); + + // Divide area into parts + s16 div = 8; + s16 sidelen = central_area_size.X / div; + double area = sidelen * sidelen; + + // N.B. We must add jungle grass first, since tree leaves will + // obstruct the ground, giving us a false ground level + for (s16 z0 = 0; z0 < div; z0++) + for (s16 x0 = 0; x0 < div; x0++) { + // Center position of part of division + v2s16 p2d_center( + node_min.X + sidelen / 2 + sidelen * x0, + node_min.Z + sidelen / 2 + sidelen * z0 + ); + // Minimum edge of part of division + v2s16 p2d_min( + node_min.X + sidelen * x0, + node_min.Z + sidelen * z0 + ); + // Maximum edge of part of division + v2s16 p2d_max( + node_min.X + sidelen + sidelen * x0 - 1, + node_min.Z + sidelen + sidelen * z0 - 1 + ); + + // Get biome at center position of part of division + BiomeV6Type bt = getBiome(p2d_center); + + // Amount of trees + u32 tree_count; + if (bt == BT_JUNGLE || bt == BT_TAIGA || bt == BT_NORMAL) { + tree_count = area * getTreeAmount(p2d_center); + if (bt == BT_JUNGLE) + tree_count *= 4; + } else { + tree_count = 0; + } + + // Add jungle grass + if (bt == BT_JUNGLE) { + float humidity = getHumidity(p2d_center); + u32 grass_count = 5 * humidity * tree_count; + for (u32 i = 0; i < grass_count; i++) { + s16 x = grassrandom.range(p2d_min.X, p2d_max.X); + s16 z = grassrandom.range(p2d_min.Y, p2d_max.Y); + int mapindex = central_area_size.X * (z - node_min.Z) + + (x - node_min.X); + s16 y = heightmap[mapindex]; + if (y < water_level) + continue; + + u32 vi = vm->m_area.index(x, y, z); + // place on dirt_with_grass, since we know it is exposed to sunlight + if (vm->m_data[vi].getContent() == c_dirt_with_grass) { + VoxelArea::add_y(em, vi, 1); + vm->m_data[vi] = n_junglegrass; + } + } + } + + // Put trees in random places on part of division + for (u32 i = 0; i < tree_count; i++) { + s16 x = myrand_range(p2d_min.X, p2d_max.X); + s16 z = myrand_range(p2d_min.Y, p2d_max.Y); + int mapindex = central_area_size.X * (z - node_min.Z) + + (x - node_min.X); + s16 y = heightmap[mapindex]; + // Don't make a tree under water level + // Don't make a tree so high that it doesn't fit + if (y < water_level || y > node_max.Y - 6) + continue; + + v3s16 p(x, y, z); + // Trees grow only on mud and grass + { + u32 i = vm->m_area.index(p); + content_t c = vm->m_data[i].getContent(); + if (c != c_dirt && + c != c_dirt_with_grass && + c != c_dirt_with_snow) + continue; + } + p.Y++; + + // Make a tree + if (bt == BT_JUNGLE) { + treegen::make_jungletree(*vm, p, ndef, myrand()); + } else if (bt == BT_TAIGA) { + treegen::make_pine_tree(*vm, p - v3s16(0, 1, 0), ndef, myrand()); + } else if (bt == BT_NORMAL) { + bool is_apple_tree = (myrand_range(0, 3) == 0) && + getHaveAppleTree(v2s16(x, z)); + treegen::make_tree(*vm, p, is_apple_tree, ndef, myrand()); + } + } + } + //printf("placeTreesAndJungleGrass: %dms\n", t.stop()); +} + + +void MapgenV6::growGrass() // Add surface nodes +{ + MapNode n_dirt_with_grass(c_dirt_with_grass); + MapNode n_dirt_with_snow(c_dirt_with_snow); + MapNode n_snowblock(c_snowblock); + const v3s16 &em = vm->m_area.getExtent(); + + u32 index = 0; + for (s16 z = full_node_min.Z; z <= full_node_max.Z; z++) + for (s16 x = full_node_min.X; x <= full_node_max.X; x++, index++) { + // Find the lowest surface to which enough light ends up to make + // grass grow. Basically just wait until not air and not leaves. + s16 surface_y = 0; + { + u32 i = vm->m_area.index(x, node_max.Y, z); + s16 y; + // Go to ground level + for (y = node_max.Y; y >= full_node_min.Y; y--) { + MapNode &n = vm->m_data[i]; + if (ndef->get(n).param_type != CPT_LIGHT || + ndef->get(n).liquid_type != LIQUID_NONE || + n.getContent() == c_ice) + break; + VoxelArea::add_y(em, i, -1); + } + surface_y = (y >= full_node_min.Y) ? y : full_node_min.Y; + } + + BiomeV6Type bt = getBiome(index, v2s16(x, z)); + u32 i = vm->m_area.index(x, surface_y, z); + content_t c = vm->m_data[i].getContent(); + if (surface_y >= water_level - 20) { + if (bt == BT_TAIGA && c == c_dirt) { + vm->m_data[i] = n_dirt_with_snow; + } else if (bt == BT_TUNDRA) { + if (c == c_dirt) { + vm->m_data[i] = n_snowblock; + VoxelArea::add_y(em, i, -1); + vm->m_data[i] = n_dirt_with_snow; + } else if (c == c_stone && surface_y < node_max.Y) { + VoxelArea::add_y(em, i, 1); + vm->m_data[i] = n_snowblock; + } + } else if (c == c_dirt) { + vm->m_data[i] = n_dirt_with_grass; + } + } + } +} + + +void MapgenV6::generateCaves(int max_stone_y) +{ + float cave_amount = NoisePerlin2D(np_cave, node_min.X, node_min.Y, seed); + int volume_nodes = (node_max.X - node_min.X + 1) * + (node_max.Y - node_min.Y + 1) * MAP_BLOCKSIZE; + cave_amount = MYMAX(0.0, cave_amount); + u32 caves_count = cave_amount * volume_nodes / 50000; + u32 bruises_count = 1; + PseudoRandom ps(blockseed + 21343); + PseudoRandom ps2(blockseed + 1032); + + if (ps.range(1, 6) == 1) + bruises_count = ps.range(0, ps.range(0, 2)); + + if (getBiome(v2s16(node_min.X, node_min.Z)) == BT_DESERT) { + caves_count /= 3; + bruises_count /= 3; + } + + for (u32 i = 0; i < caves_count + bruises_count; i++) { + CavesV6 cave(ndef, &gennotify, water_level, c_water_source, c_lava_source); + + bool large_cave = (i >= caves_count); + cave.makeCave(vm, node_min, node_max, &ps, &ps2, + large_cave, max_stone_y, heightmap); + } +} diff --git a/src/mapgen/mapgen_v6.h b/src/mapgen/mapgen_v6.h new file mode 100644 index 0000000..b0eb678 --- /dev/null +++ b/src/mapgen/mapgen_v6.h @@ -0,0 +1,173 @@ +/* +Minetest +Copyright (C) 2010-2018 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2014-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "mapgen.h" +#include "noise.h" + +#define MGV6_AVERAGE_MUD_AMOUNT 4 +#define MGV6_DESERT_STONE_BASE -32 +#define MGV6_ICE_BASE 0 +#define MGV6_FREQ_HOT 0.4 +#define MGV6_FREQ_SNOW -0.4 +#define MGV6_FREQ_TAIGA 0.5 +#define MGV6_FREQ_JUNGLE 0.5 + +//////////// Mapgen V6 flags +#define MGV6_JUNGLES 0x01 +#define MGV6_BIOMEBLEND 0x02 +#define MGV6_MUDFLOW 0x04 +#define MGV6_SNOWBIOMES 0x08 +#define MGV6_FLAT 0x10 +#define MGV6_TREES 0x20 + + +extern FlagDesc flagdesc_mapgen_v6[]; + + +enum BiomeV6Type +{ + BT_NORMAL, + BT_DESERT, + BT_JUNGLE, + BT_TUNDRA, + BT_TAIGA, +}; + + +struct MapgenV6Params : public MapgenParams { + float freq_desert = 0.45f; + float freq_beach = 0.15f; + s16 dungeon_ymin = -31000; + s16 dungeon_ymax = 31000; + + NoiseParams np_terrain_base; + NoiseParams np_terrain_higher; + NoiseParams np_steepness; + NoiseParams np_height_select; + NoiseParams np_mud; + NoiseParams np_beach; + NoiseParams np_biome; + NoiseParams np_cave; + NoiseParams np_humidity; + NoiseParams np_trees; + NoiseParams np_apple_trees; + + MapgenV6Params(); + ~MapgenV6Params() = default; + + void readParams(const Settings *settings); + void writeParams(Settings *settings) const; + void setDefaultSettings(Settings *settings); +}; + + +class MapgenV6 : public Mapgen { +public: + EmergeParams *m_emerge; + + int ystride; + u32 spflags; + + v3s16 node_min; + v3s16 node_max; + v3s16 full_node_min; + v3s16 full_node_max; + v3s16 central_area_size; + + Noise *noise_terrain_base; + Noise *noise_terrain_higher; + Noise *noise_steepness; + Noise *noise_height_select; + Noise *noise_mud; + Noise *noise_beach; + Noise *noise_biome; + Noise *noise_humidity; + NoiseParams *np_cave; + NoiseParams *np_humidity; + NoiseParams *np_trees; + NoiseParams *np_apple_trees; + + NoiseParams np_dungeons; + + float freq_desert; + float freq_beach; + s16 dungeon_ymin; + s16 dungeon_ymax; + + content_t c_stone; + content_t c_dirt; + content_t c_dirt_with_grass; + content_t c_sand; + content_t c_water_source; + content_t c_lava_source; + content_t c_gravel; + content_t c_desert_stone; + content_t c_desert_sand; + content_t c_dirt_with_snow; + content_t c_snow; + content_t c_snowblock; + content_t c_ice; + + content_t c_cobble; + content_t c_mossycobble; + content_t c_stair_cobble; + content_t c_stair_desert_stone; + + MapgenV6(MapgenV6Params *params, EmergeParams *emerge); + ~MapgenV6(); + + virtual MapgenType getType() const { return MAPGEN_V6; } + + void makeChunk(BlockMakeData *data); + int getGroundLevelAtPoint(v2s16 p); + int getSpawnLevelAtPoint(v2s16 p); + + float baseTerrainLevel(float terrain_base, float terrain_higher, + float steepness, float height_select); + virtual float baseTerrainLevelFromNoise(v2s16 p); + virtual float baseTerrainLevelFromMap(v2s16 p); + virtual float baseTerrainLevelFromMap(int index); + + s16 find_stone_level(v2s16 p2d); + bool block_is_underground(u64 seed, v3s16 blockpos); + + float getHumidity(v2s16 p); + float getTreeAmount(v2s16 p); + bool getHaveAppleTree(v2s16 p); + float getMudAmount(int index); + bool getHaveBeach(int index); + BiomeV6Type getBiome(v2s16 p); + BiomeV6Type getBiome(int index, v2s16 p); + + u32 get_blockseed(u64 seed, v3s16 p); + + virtual void calculateNoise(); + int generateGround(); + void addMud(); + void flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos); + void moveMud(u32 remove_index, u32 place_index, + u32 above_remove_index, v2s16 pos, v3s16 em); + void growGrass(); + void placeTreesAndJungleGrass(); + virtual void generateCaves(int max_stone_y); +}; diff --git a/src/mapgen/mapgen_v7.cpp b/src/mapgen/mapgen_v7.cpp new file mode 100644 index 0000000..91f0045 --- /dev/null +++ b/src/mapgen/mapgen_v7.cpp @@ -0,0 +1,590 @@ +/* +Minetest +Copyright (C) 2014-2020 paramat +Copyright (C) 2013-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "mapgen.h" +#include <cmath> +#include "voxel.h" +#include "noise.h" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +#include "nodedef.h" +#include "voxelalgorithms.h" +//#include "profiler.h" // For TimeTaker +#include "settings.h" // For g_settings +#include "emerge.h" +#include "dungeongen.h" +#include "cavegen.h" +#include "mg_biome.h" +#include "mg_ore.h" +#include "mg_decoration.h" +#include "mapgen_v7.h" + + +FlagDesc flagdesc_mapgen_v7[] = { + {"mountains", MGV7_MOUNTAINS}, + {"ridges", MGV7_RIDGES}, + {"floatlands", MGV7_FLOATLANDS}, + {"caverns", MGV7_CAVERNS}, + {NULL, 0} +}; + + +//////////////////////////////////////////////////////////////////////////////// + + +MapgenV7::MapgenV7(MapgenV7Params *params, EmergeParams *emerge) + : MapgenBasic(MAPGEN_V7, params, emerge) +{ + spflags = params->spflags; + mount_zero_level = params->mount_zero_level; + floatland_ymin = params->floatland_ymin; + floatland_ymax = params->floatland_ymax; + floatland_taper = params->floatland_taper; + float_taper_exp = params->float_taper_exp; + floatland_density = params->floatland_density; + floatland_ywater = params->floatland_ywater; + + cave_width = params->cave_width; + large_cave_depth = params->large_cave_depth; + small_cave_num_min = params->small_cave_num_min; + small_cave_num_max = params->small_cave_num_max; + large_cave_num_min = params->large_cave_num_min; + large_cave_num_max = params->large_cave_num_max; + large_cave_flooded = params->large_cave_flooded; + cavern_limit = params->cavern_limit; + cavern_taper = params->cavern_taper; + cavern_threshold = params->cavern_threshold; + dungeon_ymin = params->dungeon_ymin; + dungeon_ymax = params->dungeon_ymax; + + // Allocate floatland noise offset cache + this->float_offset_cache = new float[csize.Y + 2]; + + // 2D noise + noise_terrain_base = + new Noise(¶ms->np_terrain_base, seed, csize.X, csize.Z); + noise_terrain_alt = + new Noise(¶ms->np_terrain_alt, seed, csize.X, csize.Z); + noise_terrain_persist = + new Noise(¶ms->np_terrain_persist, seed, csize.X, csize.Z); + noise_height_select = + new Noise(¶ms->np_height_select, seed, csize.X, csize.Z); + noise_filler_depth = + new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); + + if (spflags & MGV7_MOUNTAINS) { + // 2D noise + noise_mount_height = + new Noise(¶ms->np_mount_height, seed, csize.X, csize.Z); + // 3D noise, 1 up, 1 down overgeneration + noise_mountain = + new Noise(¶ms->np_mountain, seed, csize.X, csize.Y + 2, csize.Z); + } + + if (spflags & MGV7_RIDGES) { + // 2D noise + noise_ridge_uwater = + new Noise(¶ms->np_ridge_uwater, seed, csize.X, csize.Z); + // 3D noise, 1 up, 1 down overgeneration + noise_ridge = + new Noise(¶ms->np_ridge, seed, csize.X, csize.Y + 2, csize.Z); + } + + if (spflags & MGV7_FLOATLANDS) { + // 3D noise, 1 up, 1 down overgeneration + noise_floatland = + new Noise(¶ms->np_floatland, seed, csize.X, csize.Y + 2, csize.Z); + } + + // 3D noise, 1 down overgeneration + MapgenBasic::np_cave1 = params->np_cave1; + MapgenBasic::np_cave2 = params->np_cave2; + MapgenBasic::np_cavern = params->np_cavern; + // 3D noise + MapgenBasic::np_dungeons = params->np_dungeons; +} + + +MapgenV7::~MapgenV7() +{ + delete noise_terrain_base; + delete noise_terrain_alt; + delete noise_terrain_persist; + delete noise_height_select; + delete noise_filler_depth; + + if (spflags & MGV7_MOUNTAINS) { + delete noise_mount_height; + delete noise_mountain; + } + + if (spflags & MGV7_RIDGES) { + delete noise_ridge_uwater; + delete noise_ridge; + } + + if (spflags & MGV7_FLOATLANDS) { + delete noise_floatland; + } + + delete []float_offset_cache; +} + + +MapgenV7Params::MapgenV7Params(): + np_terrain_base (4.0, 70.0, v3f(600, 600, 600), 82341, 5, 0.6, 2.0), + np_terrain_alt (4.0, 25.0, v3f(600, 600, 600), 5934, 5, 0.6, 2.0), + np_terrain_persist (0.6, 0.1, v3f(2000, 2000, 2000), 539, 3, 0.6, 2.0), + np_height_select (-8.0, 16.0, v3f(500, 500, 500), 4213, 6, 0.7, 2.0), + np_filler_depth (0.0, 1.2, v3f(150, 150, 150), 261, 3, 0.7, 2.0), + np_mount_height (256.0, 112.0, v3f(1000, 1000, 1000), 72449, 3, 0.6, 2.0), + np_ridge_uwater (0.0, 1.0, v3f(1000, 1000, 1000), 85039, 5, 0.6, 2.0), + np_mountain (-0.6, 1.0, v3f(250, 350, 250), 5333, 5, 0.63, 2.0), + np_ridge (0.0, 1.0, v3f(100, 100, 100), 6467, 4, 0.75, 2.0), + np_floatland (0.0, 0.7, v3f(384, 96, 384), 1009, 4, 0.75, 1.618), + np_cavern (0.0, 1.0, v3f(384, 128, 384), 723, 5, 0.63, 2.0), + np_cave1 (0.0, 12.0, v3f(61, 61, 61), 52534, 3, 0.5, 2.0), + np_cave2 (0.0, 12.0, v3f(67, 67, 67), 10325, 3, 0.5, 2.0), + np_dungeons (0.9, 0.5, v3f(500, 500, 500), 0, 2, 0.8, 2.0) +{ +} + + +void MapgenV7Params::readParams(const Settings *settings) +{ + settings->getFlagStrNoEx("mgv7_spflags", spflags, flagdesc_mapgen_v7); + settings->getS16NoEx("mgv7_mount_zero_level", mount_zero_level); + settings->getS16NoEx("mgv7_floatland_ymin", floatland_ymin); + settings->getS16NoEx("mgv7_floatland_ymax", floatland_ymax); + settings->getS16NoEx("mgv7_floatland_taper", floatland_taper); + settings->getFloatNoEx("mgv7_float_taper_exp", float_taper_exp); + settings->getFloatNoEx("mgv7_floatland_density", floatland_density); + settings->getS16NoEx("mgv7_floatland_ywater", floatland_ywater); + + settings->getFloatNoEx("mgv7_cave_width", cave_width); + settings->getS16NoEx("mgv7_large_cave_depth", large_cave_depth); + settings->getU16NoEx("mgv7_small_cave_num_min", small_cave_num_min); + settings->getU16NoEx("mgv7_small_cave_num_max", small_cave_num_max); + settings->getU16NoEx("mgv7_large_cave_num_min", large_cave_num_min); + settings->getU16NoEx("mgv7_large_cave_num_max", large_cave_num_max); + settings->getFloatNoEx("mgv7_large_cave_flooded", large_cave_flooded); + settings->getS16NoEx("mgv7_cavern_limit", cavern_limit); + settings->getS16NoEx("mgv7_cavern_taper", cavern_taper); + settings->getFloatNoEx("mgv7_cavern_threshold", cavern_threshold); + settings->getS16NoEx("mgv7_dungeon_ymin", dungeon_ymin); + settings->getS16NoEx("mgv7_dungeon_ymax", dungeon_ymax); + + settings->getNoiseParams("mgv7_np_terrain_base", np_terrain_base); + settings->getNoiseParams("mgv7_np_terrain_alt", np_terrain_alt); + settings->getNoiseParams("mgv7_np_terrain_persist", np_terrain_persist); + settings->getNoiseParams("mgv7_np_height_select", np_height_select); + settings->getNoiseParams("mgv7_np_filler_depth", np_filler_depth); + settings->getNoiseParams("mgv7_np_mount_height", np_mount_height); + settings->getNoiseParams("mgv7_np_ridge_uwater", np_ridge_uwater); + settings->getNoiseParams("mgv7_np_mountain", np_mountain); + settings->getNoiseParams("mgv7_np_ridge", np_ridge); + settings->getNoiseParams("mgv7_np_floatland", np_floatland); + settings->getNoiseParams("mgv7_np_cavern", np_cavern); + settings->getNoiseParams("mgv7_np_cave1", np_cave1); + settings->getNoiseParams("mgv7_np_cave2", np_cave2); + settings->getNoiseParams("mgv7_np_dungeons", np_dungeons); +} + + +void MapgenV7Params::writeParams(Settings *settings) const +{ + settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7); + settings->setS16("mgv7_mount_zero_level", mount_zero_level); + settings->setS16("mgv7_floatland_ymin", floatland_ymin); + settings->setS16("mgv7_floatland_ymax", floatland_ymax); + settings->setS16("mgv7_floatland_taper", floatland_taper); + settings->setFloat("mgv7_float_taper_exp", float_taper_exp); + settings->setFloat("mgv7_floatland_density", floatland_density); + settings->setS16("mgv7_floatland_ywater", floatland_ywater); + + settings->setFloat("mgv7_cave_width", cave_width); + settings->setS16("mgv7_large_cave_depth", large_cave_depth); + settings->setU16("mgv7_small_cave_num_min", small_cave_num_min); + settings->setU16("mgv7_small_cave_num_max", small_cave_num_max); + settings->setU16("mgv7_large_cave_num_min", large_cave_num_min); + settings->setU16("mgv7_large_cave_num_max", large_cave_num_max); + settings->setFloat("mgv7_large_cave_flooded", large_cave_flooded); + settings->setS16("mgv7_cavern_limit", cavern_limit); + settings->setS16("mgv7_cavern_taper", cavern_taper); + settings->setFloat("mgv7_cavern_threshold", cavern_threshold); + settings->setS16("mgv7_dungeon_ymin", dungeon_ymin); + settings->setS16("mgv7_dungeon_ymax", dungeon_ymax); + + settings->setNoiseParams("mgv7_np_terrain_base", np_terrain_base); + settings->setNoiseParams("mgv7_np_terrain_alt", np_terrain_alt); + settings->setNoiseParams("mgv7_np_terrain_persist", np_terrain_persist); + settings->setNoiseParams("mgv7_np_height_select", np_height_select); + settings->setNoiseParams("mgv7_np_filler_depth", np_filler_depth); + settings->setNoiseParams("mgv7_np_mount_height", np_mount_height); + settings->setNoiseParams("mgv7_np_ridge_uwater", np_ridge_uwater); + settings->setNoiseParams("mgv7_np_mountain", np_mountain); + settings->setNoiseParams("mgv7_np_ridge", np_ridge); + settings->setNoiseParams("mgv7_np_floatland", np_floatland); + settings->setNoiseParams("mgv7_np_cavern", np_cavern); + settings->setNoiseParams("mgv7_np_cave1", np_cave1); + settings->setNoiseParams("mgv7_np_cave2", np_cave2); + settings->setNoiseParams("mgv7_np_dungeons", np_dungeons); +} + + +void MapgenV7Params::setDefaultSettings(Settings *settings) +{ + settings->setDefault("mgv7_spflags", flagdesc_mapgen_v7, + MGV7_MOUNTAINS | MGV7_RIDGES | MGV7_CAVERNS); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +int MapgenV7::getSpawnLevelAtPoint(v2s16 p) +{ + // If rivers are enabled, first check if in a river + if (spflags & MGV7_RIDGES) { + float width = 0.2f; + float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * + 2.0f; + if (std::fabs(uwatern) <= width) + return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point + } + + // Terrain noise 'offset' is the average level of that terrain. + // At least 50% of terrain will be below the higher of base and alt terrain + // 'offset's. + // Raising the maximum spawn level above 'water_level + 16' is necessary + // for when terrain 'offset's are set much higher than water_level. + s16 max_spawn_y = std::fmax(std::fmax(noise_terrain_alt->np.offset, + noise_terrain_base->np.offset), + water_level + 16); + // Base terrain calculation + s16 y = baseTerrainLevelAtPoint(p.X, p.Y); + + // If mountains are disabled, terrain level is base terrain level. + // Avoids mid-air spawn where mountain terrain would have been. + if (!(spflags & MGV7_MOUNTAINS)) { + if (y < water_level || y > max_spawn_y) + return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point + + // y + 2 because y is surface level and due to biome 'dust' + return y + 2; + } + + // Search upwards for first node without mountain terrain + int iters = 256; + while (iters > 0 && y <= max_spawn_y) { + if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) { + if (y <= water_level) + return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point + + // y + 1 due to biome 'dust' + return y + 1; + } + y++; + iters--; + } + + // Unsuitable spawn point + return MAX_MAP_GENERATION_LIMIT; +} + + +void MapgenV7::makeChunk(BlockMakeData *data) +{ + // Pre-conditions + assert(data->vmanip); + assert(data->nodedef); + + //TimeTaker t("makeChunk"); + + this->generating = true; + this->vm = data->vmanip; + this->ndef = data->nodedef; + + v3s16 blockpos_min = data->blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + node_min = blockpos_min * MAP_BLOCKSIZE; + node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE; + full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + + blockseed = getBlockSeed2(full_node_min, seed); + + // Generate base and mountain terrain + s16 stone_surface_max_y = generateTerrain(); + + // Create heightmap + updateHeightmap(node_min, node_max); + + // Init biome generator, place biome-specific nodes, and build biomemap + if (flags & MG_BIOMES) { + biomegen->calcBiomeNoise(node_min); + generateBiomes(); + } + + // Generate tunnels, caverns and large randomwalk caves + if (flags & MG_CAVES) { + // Generate tunnels first as caverns confuse them + generateCavesNoiseIntersection(stone_surface_max_y); + + // Generate caverns + bool near_cavern = false; + if (spflags & MGV7_CAVERNS) + near_cavern = generateCavernsNoise(stone_surface_max_y); + + // Generate large randomwalk caves + if (near_cavern) + // Disable large randomwalk caves in this mapchunk by setting + // 'large cave depth' to world base. Avoids excessive liquid in + // large caverns and floating blobs of overgenerated liquid. + generateCavesRandomWalk(stone_surface_max_y, + -MAX_MAP_GENERATION_LIMIT); + else + generateCavesRandomWalk(stone_surface_max_y, large_cave_depth); + } + + // Generate the registered ores + if (flags & MG_ORES) + m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max); + + // Generate dungeons + if (flags & MG_DUNGEONS) + generateDungeons(stone_surface_max_y); + + // Generate the registered decorations + if (flags & MG_DECORATIONS) + m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max); + + // Sprinkle some dust on top after everything else was generated + if (flags & MG_BIOMES) + dustTopNodes(); + + // Update liquids + updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); + + // Calculate lighting + // Limit floatland shadows + bool propagate_shadow = !((spflags & MGV7_FLOATLANDS) && + node_max.Y >= floatland_ymin - csize.Y * 2 && node_min.Y <= floatland_ymax); + + if (flags & MG_LIGHT) + calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0), + full_node_min, full_node_max, propagate_shadow); + + this->generating = false; + + //printf("makeChunk: %lums\n", t.stop()); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +float MapgenV7::baseTerrainLevelAtPoint(s16 x, s16 z) +{ + float hselect = NoisePerlin2D(&noise_height_select->np, x, z, seed); + hselect = rangelim(hselect, 0.0f, 1.0f); + + float persist = NoisePerlin2D(&noise_terrain_persist->np, x, z, seed); + + noise_terrain_base->np.persist = persist; + float height_base = NoisePerlin2D(&noise_terrain_base->np, x, z, seed); + + noise_terrain_alt->np.persist = persist; + float height_alt = NoisePerlin2D(&noise_terrain_alt->np, x, z, seed); + + if (height_alt > height_base) + return height_alt; + + return (height_base * hselect) + (height_alt * (1.0f - hselect)); +} + + +float MapgenV7::baseTerrainLevelFromMap(int index) +{ + float hselect = rangelim(noise_height_select->result[index], 0.0f, 1.0f); + float height_base = noise_terrain_base->result[index]; + float height_alt = noise_terrain_alt->result[index]; + + if (height_alt > height_base) + return height_alt; + + return (height_base * hselect) + (height_alt * (1.0f - hselect)); +} + + +bool MapgenV7::getMountainTerrainAtPoint(s16 x, s16 y, s16 z) +{ + float mnt_h_n = + std::fmax(NoisePerlin2D(&noise_mount_height->np, x, z, seed), 1.0f); + float density_gradient = -((float)(y - mount_zero_level) / mnt_h_n); + float mnt_n = NoisePerlin3D(&noise_mountain->np, x, y, z, seed); + + return mnt_n + density_gradient >= 0.0f; +} + + +bool MapgenV7::getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y) +{ + float mounthn = std::fmax(noise_mount_height->result[idx_xz], 1.0f); + float density_gradient = -((float)(y - mount_zero_level) / mounthn); + float mountn = noise_mountain->result[idx_xyz]; + + return mountn + density_gradient >= 0.0f; +} + + +bool MapgenV7::getRiverChannelFromMap(int idx_xyz, int idx_xz, s16 y) +{ + // Maximum width of river channel. Creates the vertical canyon walls + float width = 0.2f; + float absuwatern = std::fabs(noise_ridge_uwater->result[idx_xz]) * 2.0f; + if (absuwatern > width) + return false; + + float altitude = y - water_level; + float height_mod = (altitude + 17.0f) / 2.5f; + float width_mod = width - absuwatern; + float nridge = noise_ridge->result[idx_xyz] * std::fmax(altitude, 0.0f) / 7.0f; + + return nridge + width_mod * height_mod >= 0.6f; +} + + +bool MapgenV7::getFloatlandTerrainFromMap(int idx_xyz, float float_offset) +{ + return noise_floatland->result[idx_xyz] + floatland_density - float_offset >= 0.0f; +} + + +int MapgenV7::generateTerrain() +{ + MapNode n_air(CONTENT_AIR); + MapNode n_stone(c_stone); + MapNode n_water(c_water_source); + + //// Calculate noise for terrain generation + noise_terrain_persist->perlinMap2D(node_min.X, node_min.Z); + float *persistmap = noise_terrain_persist->result; + + noise_terrain_base->perlinMap2D(node_min.X, node_min.Z, persistmap); + noise_terrain_alt->perlinMap2D(node_min.X, node_min.Z, persistmap); + noise_height_select->perlinMap2D(node_min.X, node_min.Z); + + if (spflags & MGV7_MOUNTAINS) { + noise_mount_height->perlinMap2D(node_min.X, node_min.Z); + noise_mountain->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + } + + //// Floatlands + // 'Generate floatlands in this mapchunk' bool for + // simplification of condition checks in y-loop. + bool gen_floatlands = false; + u8 cache_index = 0; + // Y values where floatland tapering starts + s16 float_taper_ymax = floatland_ymax - floatland_taper; + s16 float_taper_ymin = floatland_ymin + floatland_taper; + + if ((spflags & MGV7_FLOATLANDS) && + node_max.Y >= floatland_ymin && node_min.Y <= floatland_ymax) { + gen_floatlands = true; + // Calculate noise for floatland generation + noise_floatland->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + + // Cache floatland noise offset values, for floatland tapering + for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++, cache_index++) { + float float_offset = 0.0f; + if (y > float_taper_ymax) { + float_offset = std::pow((y - float_taper_ymax) / (float)floatland_taper, + float_taper_exp) * 4.0f; + } else if (y < float_taper_ymin) { + float_offset = std::pow((float_taper_ymin - y) / (float)floatland_taper, + float_taper_exp) * 4.0f; + } + float_offset_cache[cache_index] = float_offset; + } + } + + // 'Generate rivers in this mapchunk' bool for + // simplification of condition checks in y-loop. + bool gen_rivers = (spflags & MGV7_RIDGES) && node_max.Y >= water_level - 16 && + !gen_floatlands; + if (gen_rivers) { + noise_ridge->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + noise_ridge_uwater->perlinMap2D(node_min.X, node_min.Z); + } + + //// Place nodes + const v3s16 &em = vm->m_area.getExtent(); + s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; + u32 index2d = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { + s16 surface_y = baseTerrainLevelFromMap(index2d); + if (surface_y > stone_surface_max_y) + stone_surface_max_y = surface_y; + + cache_index = 0; + u32 vi = vm->m_area.index(x, node_min.Y - 1, z); + u32 index3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X); + + for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; + y++, + index3d += ystride, + VoxelArea::add_y(em, vi, 1), + cache_index++) { + if (vm->m_data[vi].getContent() != CONTENT_IGNORE) + continue; + + bool is_river_channel = gen_rivers && + getRiverChannelFromMap(index3d, index2d, y); + if (y <= surface_y && !is_river_channel) { + vm->m_data[vi] = n_stone; // Base terrain + } else if ((spflags & MGV7_MOUNTAINS) && + getMountainTerrainFromMap(index3d, index2d, y) && + !is_river_channel) { + vm->m_data[vi] = n_stone; // Mountain terrain + if (y > stone_surface_max_y) + stone_surface_max_y = y; + } else if (gen_floatlands && + getFloatlandTerrainFromMap(index3d, + float_offset_cache[cache_index])) { + vm->m_data[vi] = n_stone; // Floatland terrain + if (y > stone_surface_max_y) + stone_surface_max_y = y; + } else if (y <= water_level) { // Surface water + vm->m_data[vi] = n_water; + } else if (gen_floatlands && y >= float_taper_ymax && y <= floatland_ywater) { + vm->m_data[vi] = n_water; // Water for solid floatland layer only + } else { + vm->m_data[vi] = n_air; // Air + } + } + } + + return stone_surface_max_y; +} diff --git a/src/mapgen/mapgen_v7.h b/src/mapgen/mapgen_v7.h new file mode 100644 index 0000000..5db10a3 --- /dev/null +++ b/src/mapgen/mapgen_v7.h @@ -0,0 +1,122 @@ +/* +Minetest +Copyright (C) 2014-2020 paramat +Copyright (C) 2013-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "mapgen.h" + +///////////// Mapgen V7 flags +#define MGV7_MOUNTAINS 0x01 +#define MGV7_RIDGES 0x02 +#define MGV7_FLOATLANDS 0x04 +#define MGV7_CAVERNS 0x08 +#define MGV7_BIOMEREPEAT 0x10 // Now unused + +class BiomeManager; + +extern FlagDesc flagdesc_mapgen_v7[]; + + +struct MapgenV7Params : public MapgenParams { + s16 mount_zero_level = 0; + s16 floatland_ymin = 1024; + s16 floatland_ymax = 4096; + s16 floatland_taper = 256; + float float_taper_exp = 2.0f; + float floatland_density = -0.6f; + s16 floatland_ywater = -31000; + + float cave_width = 0.09f; + s16 large_cave_depth = -33; + u16 small_cave_num_min = 0; + u16 small_cave_num_max = 0; + u16 large_cave_num_min = 0; + u16 large_cave_num_max = 2; + float large_cave_flooded = 0.5f; + s16 cavern_limit = -256; + s16 cavern_taper = 256; + float cavern_threshold = 0.7f; + s16 dungeon_ymin = -31000; + s16 dungeon_ymax = 31000; + + NoiseParams np_terrain_base; + NoiseParams np_terrain_alt; + NoiseParams np_terrain_persist; + NoiseParams np_height_select; + NoiseParams np_filler_depth; + NoiseParams np_mount_height; + NoiseParams np_ridge_uwater; + NoiseParams np_mountain; + NoiseParams np_ridge; + NoiseParams np_floatland; + NoiseParams np_cavern; + NoiseParams np_cave1; + NoiseParams np_cave2; + NoiseParams np_dungeons; + + MapgenV7Params(); + ~MapgenV7Params() = default; + + void readParams(const Settings *settings); + void writeParams(Settings *settings) const; + void setDefaultSettings(Settings *settings); +}; + + +class MapgenV7 : public MapgenBasic { +public: + MapgenV7(MapgenV7Params *params, EmergeParams *emerge); + ~MapgenV7(); + + virtual MapgenType getType() const { return MAPGEN_V7; } + + virtual void makeChunk(BlockMakeData *data); + int getSpawnLevelAtPoint(v2s16 p); + + float baseTerrainLevelAtPoint(s16 x, s16 z); + float baseTerrainLevelFromMap(int index); + bool getMountainTerrainAtPoint(s16 x, s16 y, s16 z); + bool getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y); + bool getRiverChannelFromMap(int idx_xyz, int idx_xz, s16 y); + bool getFloatlandTerrainFromMap(int idx_xyz, float float_offset); + + int generateTerrain(); + +private: + s16 mount_zero_level; + s16 floatland_ymin; + s16 floatland_ymax; + s16 floatland_taper; + float float_taper_exp; + float floatland_density; + s16 floatland_ywater; + + float *float_offset_cache = nullptr; + + Noise *noise_terrain_base; + Noise *noise_terrain_alt; + Noise *noise_terrain_persist; + Noise *noise_height_select; + Noise *noise_mount_height; + Noise *noise_ridge_uwater; + Noise *noise_mountain; + Noise *noise_ridge; + Noise *noise_floatland; +}; diff --git a/src/mapgen/mapgen_valleys.cpp b/src/mapgen/mapgen_valleys.cpp new file mode 100644 index 0000000..80a99b1 --- /dev/null +++ b/src/mapgen/mapgen_valleys.cpp @@ -0,0 +1,483 @@ +/* +Minetest +Copyright (C) 2016-2019 Duane Robertson <duane@duanerobertson.com> +Copyright (C) 2016-2019 paramat + +Based on Valleys Mapgen by Gael de Sailly +(https://forum.minetest.net/viewtopic.php?f=9&t=11430) +and mapgen_v7, mapgen_flat by kwolekr and paramat. + +Licensing changed by permission of Gael de Sailly. + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "mapgen.h" +#include "voxel.h" +#include "noise.h" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +#include "nodedef.h" +#include "voxelalgorithms.h" +//#include "profiler.h" // For TimeTaker +#include "settings.h" // For g_settings +#include "emerge.h" +#include "dungeongen.h" +#include "mg_biome.h" +#include "mg_ore.h" +#include "mg_decoration.h" +#include "mapgen_valleys.h" +#include "cavegen.h" +#include <cmath> + + +FlagDesc flagdesc_mapgen_valleys[] = { + {"altitude_chill", MGVALLEYS_ALT_CHILL}, + {"humid_rivers", MGVALLEYS_HUMID_RIVERS}, + {"vary_river_depth", MGVALLEYS_VARY_RIVER_DEPTH}, + {"altitude_dry", MGVALLEYS_ALT_DRY}, + {NULL, 0} +}; + + +MapgenValleys::MapgenValleys(MapgenValleysParams *params, EmergeParams *emerge) + : MapgenBasic(MAPGEN_VALLEYS, params, emerge) +{ + FATAL_ERROR_IF(biomegen->getType() != BIOMEGEN_ORIGINAL, + "MapgenValleys has a hard dependency on BiomeGenOriginal"); + m_bgen = (BiomeGenOriginal *)biomegen; + + spflags = params->spflags; + altitude_chill = params->altitude_chill; + river_depth_bed = params->river_depth + 1.0f; + river_size_factor = params->river_size / 100.0f; + + cave_width = params->cave_width; + large_cave_depth = params->large_cave_depth; + small_cave_num_min = params->small_cave_num_min; + small_cave_num_max = params->small_cave_num_max; + large_cave_num_min = params->large_cave_num_min; + large_cave_num_max = params->large_cave_num_max; + large_cave_flooded = params->large_cave_flooded; + cavern_limit = params->cavern_limit; + cavern_taper = params->cavern_taper; + cavern_threshold = params->cavern_threshold; + dungeon_ymin = params->dungeon_ymin; + dungeon_ymax = params->dungeon_ymax; + + //// 2D Terrain noise + noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); + noise_inter_valley_slope = new Noise(¶ms->np_inter_valley_slope, seed, csize.X, csize.Z); + noise_rivers = new Noise(¶ms->np_rivers, seed, csize.X, csize.Z); + noise_terrain_height = new Noise(¶ms->np_terrain_height, seed, csize.X, csize.Z); + noise_valley_depth = new Noise(¶ms->np_valley_depth, seed, csize.X, csize.Z); + noise_valley_profile = new Noise(¶ms->np_valley_profile, seed, csize.X, csize.Z); + + //// 3D Terrain noise + // 1-up 1-down overgeneration + noise_inter_valley_fill = new Noise(¶ms->np_inter_valley_fill, + seed, csize.X, csize.Y + 2, csize.Z); + // 1-down overgeneraion + MapgenBasic::np_cave1 = params->np_cave1; + MapgenBasic::np_cave2 = params->np_cave2; + MapgenBasic::np_cavern = params->np_cavern; + MapgenBasic::np_dungeons = params->np_dungeons; +} + + +MapgenValleys::~MapgenValleys() +{ + delete noise_filler_depth; + delete noise_inter_valley_fill; + delete noise_inter_valley_slope; + delete noise_rivers; + delete noise_terrain_height; + delete noise_valley_depth; + delete noise_valley_profile; +} + + +MapgenValleysParams::MapgenValleysParams(): + np_filler_depth (0.0, 1.2, v3f(256, 256, 256), 1605, 3, 0.5, 2.0), + np_inter_valley_fill (0.0, 1.0, v3f(256, 512, 256), 1993, 6, 0.8, 2.0), + np_inter_valley_slope (0.5, 0.5, v3f(128, 128, 128), 746, 1, 1.0, 2.0), + np_rivers (0.0, 1.0, v3f(256, 256, 256), -6050, 5, 0.6, 2.0), + np_terrain_height (-10.0, 50.0, v3f(1024, 1024, 1024), 5202, 6, 0.4, 2.0), + np_valley_depth (5.0, 4.0, v3f(512, 512, 512), -1914, 1, 1.0, 2.0), + np_valley_profile (0.6, 0.50, v3f(512, 512, 512), 777, 1, 1.0, 2.0), + np_cave1 (0.0, 12.0, v3f(61, 61, 61), 52534, 3, 0.5, 2.0), + np_cave2 (0.0, 12.0, v3f(67, 67, 67), 10325, 3, 0.5, 2.0), + np_cavern (0.0, 1.0, v3f(768, 256, 768), 59033, 6, 0.63, 2.0), + np_dungeons (0.9, 0.5, v3f(500, 500, 500), 0, 2, 0.8, 2.0) +{ +} + + +void MapgenValleysParams::readParams(const Settings *settings) +{ + settings->getFlagStrNoEx("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys); + settings->getU16NoEx("mgvalleys_altitude_chill", altitude_chill); + settings->getS16NoEx("mgvalleys_large_cave_depth", large_cave_depth); + settings->getU16NoEx("mgvalleys_small_cave_num_min", small_cave_num_min); + settings->getU16NoEx("mgvalleys_small_cave_num_max", small_cave_num_max); + settings->getU16NoEx("mgvalleys_large_cave_num_min", large_cave_num_min); + settings->getU16NoEx("mgvalleys_large_cave_num_max", large_cave_num_max); + settings->getFloatNoEx("mgvalleys_large_cave_flooded", large_cave_flooded); + settings->getU16NoEx("mgvalleys_river_depth", river_depth); + settings->getU16NoEx("mgvalleys_river_size", river_size); + settings->getFloatNoEx("mgvalleys_cave_width", cave_width); + settings->getS16NoEx("mgvalleys_cavern_limit", cavern_limit); + settings->getS16NoEx("mgvalleys_cavern_taper", cavern_taper); + settings->getFloatNoEx("mgvalleys_cavern_threshold", cavern_threshold); + settings->getS16NoEx("mgvalleys_dungeon_ymin", dungeon_ymin); + settings->getS16NoEx("mgvalleys_dungeon_ymax", dungeon_ymax); + + settings->getNoiseParams("mgvalleys_np_filler_depth", np_filler_depth); + settings->getNoiseParams("mgvalleys_np_inter_valley_fill", np_inter_valley_fill); + settings->getNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope); + settings->getNoiseParams("mgvalleys_np_rivers", np_rivers); + settings->getNoiseParams("mgvalleys_np_terrain_height", np_terrain_height); + settings->getNoiseParams("mgvalleys_np_valley_depth", np_valley_depth); + settings->getNoiseParams("mgvalleys_np_valley_profile", np_valley_profile); + + settings->getNoiseParams("mgvalleys_np_cave1", np_cave1); + settings->getNoiseParams("mgvalleys_np_cave2", np_cave2); + settings->getNoiseParams("mgvalleys_np_cavern", np_cavern); + settings->getNoiseParams("mgvalleys_np_dungeons", np_dungeons); +} + + +void MapgenValleysParams::writeParams(Settings *settings) const +{ + settings->setFlagStr("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys); + settings->setU16("mgvalleys_altitude_chill", altitude_chill); + settings->setS16("mgvalleys_large_cave_depth", large_cave_depth); + settings->setU16("mgvalleys_small_cave_num_min", small_cave_num_min); + settings->setU16("mgvalleys_small_cave_num_max", small_cave_num_max); + settings->setU16("mgvalleys_large_cave_num_min", large_cave_num_min); + settings->setU16("mgvalleys_large_cave_num_max", large_cave_num_max); + settings->setFloat("mgvalleys_large_cave_flooded", large_cave_flooded); + settings->setU16("mgvalleys_river_depth", river_depth); + settings->setU16("mgvalleys_river_size", river_size); + settings->setFloat("mgvalleys_cave_width", cave_width); + settings->setS16("mgvalleys_cavern_limit", cavern_limit); + settings->setS16("mgvalleys_cavern_taper", cavern_taper); + settings->setFloat("mgvalleys_cavern_threshold", cavern_threshold); + settings->setS16("mgvalleys_dungeon_ymin", dungeon_ymin); + settings->setS16("mgvalleys_dungeon_ymax", dungeon_ymax); + + settings->setNoiseParams("mgvalleys_np_filler_depth", np_filler_depth); + settings->setNoiseParams("mgvalleys_np_inter_valley_fill", np_inter_valley_fill); + settings->setNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope); + settings->setNoiseParams("mgvalleys_np_rivers", np_rivers); + settings->setNoiseParams("mgvalleys_np_terrain_height", np_terrain_height); + settings->setNoiseParams("mgvalleys_np_valley_depth", np_valley_depth); + settings->setNoiseParams("mgvalleys_np_valley_profile", np_valley_profile); + + settings->setNoiseParams("mgvalleys_np_cave1", np_cave1); + settings->setNoiseParams("mgvalleys_np_cave2", np_cave2); + settings->setNoiseParams("mgvalleys_np_cavern", np_cavern); + settings->setNoiseParams("mgvalleys_np_dungeons", np_dungeons); +} + + +void MapgenValleysParams::setDefaultSettings(Settings *settings) +{ + settings->setDefault("mgvalleys_spflags", flagdesc_mapgen_valleys, + MGVALLEYS_ALT_CHILL | MGVALLEYS_HUMID_RIVERS | + MGVALLEYS_VARY_RIVER_DEPTH | MGVALLEYS_ALT_DRY); +} + + +///////////////////////////////////////////////////////////////// + + +void MapgenValleys::makeChunk(BlockMakeData *data) +{ + // Pre-conditions + assert(data->vmanip); + assert(data->nodedef); + + //TimeTaker t("makeChunk"); + + this->generating = true; + this->vm = data->vmanip; + this->ndef = data->nodedef; + + v3s16 blockpos_min = data->blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + node_min = blockpos_min * MAP_BLOCKSIZE; + node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE; + full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + + blockseed = getBlockSeed2(full_node_min, seed); + + // Generate biome noises. Note this must be executed strictly before + // generateTerrain, because generateTerrain depends on intermediate + // biome-related noises. + m_bgen->calcBiomeNoise(node_min); + + // Generate terrain + s16 stone_surface_max_y = generateTerrain(); + + // Create heightmap + updateHeightmap(node_min, node_max); + + // Place biome-specific nodes and build biomemap + if (flags & MG_BIOMES) { + generateBiomes(); + } + + // Generate tunnels, caverns and large randomwalk caves + if (flags & MG_CAVES) { + // Generate tunnels first as caverns confuse them + generateCavesNoiseIntersection(stone_surface_max_y); + + // Generate caverns + bool near_cavern = generateCavernsNoise(stone_surface_max_y); + + // Generate large randomwalk caves + if (near_cavern) + // Disable large randomwalk caves in this mapchunk by setting + // 'large cave depth' to world base. Avoids excessive liquid in + // large caverns and floating blobs of overgenerated liquid. + generateCavesRandomWalk(stone_surface_max_y, + -MAX_MAP_GENERATION_LIMIT); + else + generateCavesRandomWalk(stone_surface_max_y, large_cave_depth); + } + + // Generate the registered ores + if (flags & MG_ORES) + m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max); + + // Dungeon creation + if (flags & MG_DUNGEONS) + generateDungeons(stone_surface_max_y); + + // Generate the registered decorations + if (flags & MG_DECORATIONS) + m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max); + + // Sprinkle some dust on top after everything else was generated + if (flags & MG_BIOMES) + dustTopNodes(); + + updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); + + if (flags & MG_LIGHT) + calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0), + full_node_min, full_node_max); + + this->generating = false; + + //printf("makeChunk: %lums\n", t.stop()); +} + + +int MapgenValleys::getSpawnLevelAtPoint(v2s16 p) +{ + // Check if in a river channel + float n_rivers = NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed); + if (std::fabs(n_rivers) <= river_size_factor) + // Unsuitable spawn point + return MAX_MAP_GENERATION_LIMIT; + + float n_slope = NoisePerlin2D(&noise_inter_valley_slope->np, p.X, p.Y, seed); + float n_terrain_height = NoisePerlin2D(&noise_terrain_height->np, p.X, p.Y, seed); + float n_valley = NoisePerlin2D(&noise_valley_depth->np, p.X, p.Y, seed); + float n_valley_profile = NoisePerlin2D(&noise_valley_profile->np, p.X, p.Y, seed); + + float valley_d = n_valley * n_valley; + float base = n_terrain_height + valley_d; + float river = std::fabs(n_rivers) - river_size_factor; + float tv = std::fmax(river / n_valley_profile, 0.0f); + float valley_h = valley_d * (1.0f - std::exp(-tv * tv)); + float surface_y = base + valley_h; + float slope = n_slope * valley_h; + float river_y = base - 1.0f; + + // Raising the maximum spawn level above 'water_level + 16' is necessary for custom + // parameters that set average terrain level much higher than water_level. + s16 max_spawn_y = std::fmax( + noise_terrain_height->np.offset + + noise_valley_depth->np.offset * noise_valley_depth->np.offset, + water_level + 16); + + // Starting spawn search at max_spawn_y + 128 ensures 128 nodes of open + // space above spawn position. Avoids spawning in possibly sealed voids. + for (s16 y = max_spawn_y + 128; y >= water_level; y--) { + float n_fill = NoisePerlin3D(&noise_inter_valley_fill->np, p.X, y, p.Y, seed); + float surface_delta = (float)y - surface_y; + float density = slope * n_fill - surface_delta; + + if (density > 0.0f) { // If solid + // Sometimes surface level is below river water level in places that are not + // river channels. + if (y < water_level || y > max_spawn_y || y < (s16)river_y) + // Unsuitable spawn point + return MAX_MAP_GENERATION_LIMIT; + + // y + 2 because y is surface and due to biome 'dust' nodes. + return y + 2; + } + } + // Unsuitable spawn position, no ground found + return MAX_MAP_GENERATION_LIMIT; +} + + +int MapgenValleys::generateTerrain() +{ + MapNode n_air(CONTENT_AIR); + MapNode n_river_water(c_river_water_source); + MapNode n_stone(c_stone); + MapNode n_water(c_water_source); + + noise_inter_valley_slope->perlinMap2D(node_min.X, node_min.Z); + noise_rivers->perlinMap2D(node_min.X, node_min.Z); + noise_terrain_height->perlinMap2D(node_min.X, node_min.Z); + noise_valley_depth->perlinMap2D(node_min.X, node_min.Z); + noise_valley_profile->perlinMap2D(node_min.X, node_min.Z); + + noise_inter_valley_fill->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + + const v3s16 &em = vm->m_area.getExtent(); + s16 surface_max_y = -MAX_MAP_GENERATION_LIMIT; + u32 index_2d = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) { + float n_slope = noise_inter_valley_slope->result[index_2d]; + float n_rivers = noise_rivers->result[index_2d]; + float n_terrain_height = noise_terrain_height->result[index_2d]; + float n_valley = noise_valley_depth->result[index_2d]; + float n_valley_profile = noise_valley_profile->result[index_2d]; + + float valley_d = n_valley * n_valley; + // 'base' represents the level of the river banks + float base = n_terrain_height + valley_d; + // 'river' represents the distance from the river edge + float river = std::fabs(n_rivers) - river_size_factor; + // Use the curve of the function 1-exp(-(x/a)^2) to model valleys. + // 'valley_h' represents the height of the terrain, from the rivers. + float tv = std::fmax(river / n_valley_profile, 0.0f); + float valley_h = valley_d * (1.0f - std::exp(-tv * tv)); + // Approximate height of the terrain + float surface_y = base + valley_h; + float slope = n_slope * valley_h; + // River water surface is 1 node below river banks + float river_y = base - 1.0f; + + // Rivers are placed where 'river' is negative + if (river < 0.0f) { + // Use the function -sqrt(1-x^2) which models a circle + float tr = river / river_size_factor + 1.0f; + float depth = (river_depth_bed * + std::sqrt(std::fmax(0.0f, 1.0f - tr * tr))); + // There is no logical equivalent to this using rangelim + surface_y = std::fmin( + std::fmax(base - depth, (float)(water_level - 3)), + surface_y); + slope = 0.0f; + } + + // Optionally vary river depth according to heat and humidity + if (spflags & MGVALLEYS_VARY_RIVER_DEPTH) { + float t_heat = m_bgen->heatmap[index_2d]; + float heat = (spflags & MGVALLEYS_ALT_CHILL) ? + // Match heat value calculated below in + // 'Optionally decrease heat with altitude'. + // In rivers, 'ground height ignoring riverbeds' is 'base'. + // As this only affects river water we can assume y > water_level. + t_heat + 5.0f - (base - water_level) * 20.0f / altitude_chill : + t_heat; + float delta = m_bgen->humidmap[index_2d] - 50.0f; + if (delta < 0.0f) { + float t_evap = (heat - 32.0f) / 300.0f; + river_y += delta * std::fmax(t_evap, 0.08f); + } + } + + // Highest solid node in column + s16 column_max_y = surface_y; + u32 index_3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X); + u32 index_data = vm->m_area.index(x, node_min.Y - 1, z); + + for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { + if (vm->m_data[index_data].getContent() == CONTENT_IGNORE) { + float n_fill = noise_inter_valley_fill->result[index_3d]; + float surface_delta = (float)y - surface_y; + // Density = density noise + density gradient + float density = slope * n_fill - surface_delta; + + if (density > 0.0f) { + vm->m_data[index_data] = n_stone; // Stone + if (y > surface_max_y) + surface_max_y = y; + if (y > column_max_y) + column_max_y = y; + } else if (y <= water_level) { + vm->m_data[index_data] = n_water; // Water + } else if (y <= (s16)river_y) { + vm->m_data[index_data] = n_river_water; // River water + } else { + vm->m_data[index_data] = n_air; // Air + } + } + + VoxelArea::add_y(em, index_data, 1); + index_3d += ystride; + } + + // Optionally increase humidity around rivers + if (spflags & MGVALLEYS_HUMID_RIVERS) { + // Compensate to avoid increasing average humidity + m_bgen->humidmap[index_2d] *= 0.8f; + // Ground height ignoring riverbeds + float t_alt = std::fmax(base, (float)column_max_y); + float water_depth = (t_alt - base) / 4.0f; + m_bgen->humidmap[index_2d] *= + 1.0f + std::pow(0.5f, std::fmax(water_depth, 1.0f)); + } + + // Optionally decrease humidity with altitude + if (spflags & MGVALLEYS_ALT_DRY) { + // Ground height ignoring riverbeds + float t_alt = std::fmax(base, (float)column_max_y); + // Only decrease above water_level + if (t_alt > water_level) + m_bgen->humidmap[index_2d] -= + (t_alt - water_level) * 10.0f / altitude_chill; + } + + // Optionally decrease heat with altitude + if (spflags & MGVALLEYS_ALT_CHILL) { + // Compensate to avoid reducing the average heat + m_bgen->heatmap[index_2d] += 5.0f; + // Ground height ignoring riverbeds + float t_alt = std::fmax(base, (float)column_max_y); + // Only decrease above water_level + if (t_alt > water_level) + m_bgen->heatmap[index_2d] -= + (t_alt - water_level) * 20.0f / altitude_chill; + } + } + + return surface_max_y; +} diff --git a/src/mapgen/mapgen_valleys.h b/src/mapgen/mapgen_valleys.h new file mode 100644 index 0000000..34a923d --- /dev/null +++ b/src/mapgen/mapgen_valleys.h @@ -0,0 +1,110 @@ +/* +Minetest +Copyright (C) 2016-2019 Duane Robertson <duane@duanerobertson.com> +Copyright (C) 2016-2019 paramat + +Based on Valleys Mapgen by Gael de Sailly +(https://forum.minetest.net/viewtopic.php?f=9&t=11430) +and mapgen_v7, mapgen_flat by kwolekr and paramat. + +Licensing changed by permission of Gael de Sailly. + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#pragma once + +#include "mapgen.h" + +#define MGVALLEYS_ALT_CHILL 0x01 +#define MGVALLEYS_HUMID_RIVERS 0x02 +#define MGVALLEYS_VARY_RIVER_DEPTH 0x04 +#define MGVALLEYS_ALT_DRY 0x08 + +class BiomeManager; +class BiomeGenOriginal; + +extern FlagDesc flagdesc_mapgen_valleys[]; + + +struct MapgenValleysParams : public MapgenParams { + u16 altitude_chill = 90; + u16 river_depth = 4; + u16 river_size = 5; + + float cave_width = 0.09f; + s16 large_cave_depth = -33; + u16 small_cave_num_min = 0; + u16 small_cave_num_max = 0; + u16 large_cave_num_min = 0; + u16 large_cave_num_max = 2; + float large_cave_flooded = 0.5f; + s16 cavern_limit = -256; + s16 cavern_taper = 192; + float cavern_threshold = 0.6f; + s16 dungeon_ymin = -31000; + s16 dungeon_ymax = 63; + + NoiseParams np_filler_depth; + NoiseParams np_inter_valley_fill; + NoiseParams np_inter_valley_slope; + NoiseParams np_rivers; + NoiseParams np_terrain_height; + NoiseParams np_valley_depth; + NoiseParams np_valley_profile; + + NoiseParams np_cave1; + NoiseParams np_cave2; + NoiseParams np_cavern; + NoiseParams np_dungeons; + + MapgenValleysParams(); + ~MapgenValleysParams() = default; + + void readParams(const Settings *settings); + void writeParams(Settings *settings) const; + void setDefaultSettings(Settings *settings); +}; + + +class MapgenValleys : public MapgenBasic { +public: + + MapgenValleys(MapgenValleysParams *params, + EmergeParams *emerge); + ~MapgenValleys(); + + virtual MapgenType getType() const { return MAPGEN_VALLEYS; } + + virtual void makeChunk(BlockMakeData *data); + int getSpawnLevelAtPoint(v2s16 p); + +private: + BiomeGenOriginal *m_bgen; + + float altitude_chill; + float river_depth_bed; + float river_size_factor; + + Noise *noise_inter_valley_fill; + Noise *noise_inter_valley_slope; + Noise *noise_rivers; + Noise *noise_terrain_height; + Noise *noise_valley_depth; + Noise *noise_valley_profile; + + virtual int generateTerrain(); +}; diff --git a/src/mapgen/mg_biome.cpp b/src/mapgen/mg_biome.cpp new file mode 100644 index 0000000..8b4c96c --- /dev/null +++ b/src/mapgen/mg_biome.cpp @@ -0,0 +1,331 @@ +/* +Minetest +Copyright (C) 2014-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2014-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mg_biome.h" +#include "mg_decoration.h" +#include "emerge.h" +#include "server.h" +#include "nodedef.h" +#include "map.h" //for MMVManip +#include "util/numeric.h" +#include "porting.h" +#include "settings.h" + + +/////////////////////////////////////////////////////////////////////////////// + + +BiomeManager::BiomeManager(Server *server) : + ObjDefManager(server, OBJDEF_BIOME) +{ + m_server = server; + + // Create default biome to be used in case none exist + Biome *b = new Biome; + + b->name = "default"; + b->flags = 0; + b->depth_top = 0; + b->depth_filler = -MAX_MAP_GENERATION_LIMIT; + b->depth_water_top = 0; + b->depth_riverbed = 0; + b->min_pos = v3s16(-MAX_MAP_GENERATION_LIMIT, + -MAX_MAP_GENERATION_LIMIT, -MAX_MAP_GENERATION_LIMIT); + b->max_pos = v3s16(MAX_MAP_GENERATION_LIMIT, + MAX_MAP_GENERATION_LIMIT, MAX_MAP_GENERATION_LIMIT); + b->heat_point = 0.0; + b->humidity_point = 0.0; + b->vertical_blend = 0; + + b->m_nodenames.emplace_back("mapgen_stone"); + b->m_nodenames.emplace_back("mapgen_stone"); + b->m_nodenames.emplace_back("mapgen_stone"); + b->m_nodenames.emplace_back("mapgen_water_source"); + b->m_nodenames.emplace_back("mapgen_water_source"); + b->m_nodenames.emplace_back("mapgen_river_water_source"); + b->m_nodenames.emplace_back("mapgen_stone"); + b->m_nodenames.emplace_back("ignore"); + b->m_nodenames.emplace_back("ignore"); + b->m_nnlistsizes.push_back(1); + b->m_nodenames.emplace_back("ignore"); + b->m_nodenames.emplace_back("ignore"); + b->m_nodenames.emplace_back("ignore"); + m_ndef->pendNodeResolve(b); + + add(b); +} + + +void BiomeManager::clear() +{ + EmergeManager *emerge = m_server->getEmergeManager(); + + // Remove all dangling references in Decorations + DecorationManager *decomgr = emerge->getWritableDecorationManager(); + for (size_t i = 0; i != decomgr->getNumObjects(); i++) { + Decoration *deco = (Decoration *)decomgr->getRaw(i); + deco->biomes.clear(); + } + + // Don't delete the first biome + for (size_t i = 1; i < m_objects.size(); i++) + delete (Biome *)m_objects[i]; + + m_objects.resize(1); +} + + +BiomeManager *BiomeManager::clone() const +{ + auto mgr = new BiomeManager(); + assert(mgr); + ObjDefManager::cloneTo(mgr); + mgr->m_server = m_server; + return mgr; +} + +//////////////////////////////////////////////////////////////////////////////// + +void BiomeParamsOriginal::readParams(const Settings *settings) +{ + settings->getNoiseParams("mg_biome_np_heat", np_heat); + settings->getNoiseParams("mg_biome_np_heat_blend", np_heat_blend); + settings->getNoiseParams("mg_biome_np_humidity", np_humidity); + settings->getNoiseParams("mg_biome_np_humidity_blend", np_humidity_blend); +} + + +void BiomeParamsOriginal::writeParams(Settings *settings) const +{ + settings->setNoiseParams("mg_biome_np_heat", np_heat); + settings->setNoiseParams("mg_biome_np_heat_blend", np_heat_blend); + settings->setNoiseParams("mg_biome_np_humidity", np_humidity); + settings->setNoiseParams("mg_biome_np_humidity_blend", np_humidity_blend); +} + + +//////////////////////////////////////////////////////////////////////////////// + +BiomeGenOriginal::BiomeGenOriginal(BiomeManager *biomemgr, + const BiomeParamsOriginal *params, v3s16 chunksize) +{ + m_bmgr = biomemgr; + m_params = params; + m_csize = chunksize; + + noise_heat = new Noise(¶ms->np_heat, + params->seed, m_csize.X, m_csize.Z); + noise_humidity = new Noise(¶ms->np_humidity, + params->seed, m_csize.X, m_csize.Z); + noise_heat_blend = new Noise(¶ms->np_heat_blend, + params->seed, m_csize.X, m_csize.Z); + noise_humidity_blend = new Noise(¶ms->np_humidity_blend, + params->seed, m_csize.X, m_csize.Z); + + heatmap = noise_heat->result; + humidmap = noise_humidity->result; + + biomemap = new biome_t[m_csize.X * m_csize.Z]; + // Initialise with the ID of 'BIOME_NONE' so that cavegen can get the + // fallback biome when biome generation (which calculates the biomemap IDs) + // is disabled. + memset(biomemap, 0, sizeof(biome_t) * m_csize.X * m_csize.Z); +} + +BiomeGenOriginal::~BiomeGenOriginal() +{ + delete []biomemap; + + delete noise_heat; + delete noise_humidity; + delete noise_heat_blend; + delete noise_humidity_blend; +} + +BiomeGen *BiomeGenOriginal::clone(BiomeManager *biomemgr) const +{ + return new BiomeGenOriginal(biomemgr, m_params, m_csize); +} + +float BiomeGenOriginal::calcHeatAtPoint(v3s16 pos) const +{ + return NoisePerlin2D(&m_params->np_heat, pos.X, pos.Z, m_params->seed) + + NoisePerlin2D(&m_params->np_heat_blend, pos.X, pos.Z, m_params->seed); +} + +float BiomeGenOriginal::calcHumidityAtPoint(v3s16 pos) const +{ + return NoisePerlin2D(&m_params->np_humidity, pos.X, pos.Z, m_params->seed) + + NoisePerlin2D(&m_params->np_humidity_blend, pos.X, pos.Z, m_params->seed); +} + +Biome *BiomeGenOriginal::calcBiomeAtPoint(v3s16 pos) const +{ + return calcBiomeFromNoise(calcHeatAtPoint(pos), calcHumidityAtPoint(pos), pos); +} + + +void BiomeGenOriginal::calcBiomeNoise(v3s16 pmin) +{ + m_pmin = pmin; + + noise_heat->perlinMap2D(pmin.X, pmin.Z); + noise_humidity->perlinMap2D(pmin.X, pmin.Z); + noise_heat_blend->perlinMap2D(pmin.X, pmin.Z); + noise_humidity_blend->perlinMap2D(pmin.X, pmin.Z); + + for (s32 i = 0; i < m_csize.X * m_csize.Z; i++) { + noise_heat->result[i] += noise_heat_blend->result[i]; + noise_humidity->result[i] += noise_humidity_blend->result[i]; + } +} + + +biome_t *BiomeGenOriginal::getBiomes(s16 *heightmap, v3s16 pmin) +{ + for (s16 zr = 0; zr < m_csize.Z; zr++) + for (s16 xr = 0; xr < m_csize.X; xr++) { + s32 i = zr * m_csize.X + xr; + Biome *biome = calcBiomeFromNoise( + noise_heat->result[i], + noise_humidity->result[i], + v3s16(pmin.X + xr, heightmap[i], pmin.Z + zr)); + + biomemap[i] = biome->index; + } + + return biomemap; +} + + +Biome *BiomeGenOriginal::getBiomeAtPoint(v3s16 pos) const +{ + return getBiomeAtIndex( + (pos.Z - m_pmin.Z) * m_csize.X + (pos.X - m_pmin.X), + pos); +} + + +Biome *BiomeGenOriginal::getBiomeAtIndex(size_t index, v3s16 pos) const +{ + return calcBiomeFromNoise( + noise_heat->result[index], + noise_humidity->result[index], + pos); +} + + +Biome *BiomeGenOriginal::calcBiomeFromNoise(float heat, float humidity, v3s16 pos) const +{ + Biome *biome_closest = nullptr; + Biome *biome_closest_blend = nullptr; + float dist_min = FLT_MAX; + float dist_min_blend = FLT_MAX; + + for (size_t i = 1; i < m_bmgr->getNumObjects(); i++) { + Biome *b = (Biome *)m_bmgr->getRaw(i); + if (!b || + pos.Y < b->min_pos.Y || pos.Y > b->max_pos.Y + b->vertical_blend || + pos.X < b->min_pos.X || pos.X > b->max_pos.X || + pos.Z < b->min_pos.Z || pos.Z > b->max_pos.Z) + continue; + + float d_heat = heat - b->heat_point; + float d_humidity = humidity - b->humidity_point; + float dist = (d_heat * d_heat) + (d_humidity * d_humidity); + + if (pos.Y <= b->max_pos.Y) { // Within y limits of biome b + if (dist < dist_min) { + dist_min = dist; + biome_closest = b; + } + } else if (dist < dist_min_blend) { // Blend area above biome b + dist_min_blend = dist; + biome_closest_blend = b; + } + } + + // Carefully tune pseudorandom seed variation to avoid single node dither + // and create larger scale blending patterns similar to horizontal biome + // blend. + const u64 seed = pos.Y + (heat + humidity) * 0.9f; + PcgRandom rng(seed); + + if (biome_closest_blend && dist_min_blend <= dist_min && + rng.range(0, biome_closest_blend->vertical_blend) >= + pos.Y - biome_closest_blend->max_pos.Y) + return biome_closest_blend; + + return (biome_closest) ? biome_closest : (Biome *)m_bmgr->getRaw(BIOME_NONE); +} + + +//////////////////////////////////////////////////////////////////////////////// + +ObjDef *Biome::clone() const +{ + auto obj = new Biome(); + ObjDef::cloneTo(obj); + NodeResolver::cloneTo(obj); + + obj->flags = flags; + + obj->c_top = c_top; + obj->c_filler = c_filler; + obj->c_stone = c_stone; + obj->c_water_top = c_water_top; + obj->c_water = c_water; + obj->c_river_water = c_river_water; + obj->c_riverbed = c_riverbed; + obj->c_dust = c_dust; + obj->c_cave_liquid = c_cave_liquid; + obj->c_dungeon = c_dungeon; + obj->c_dungeon_alt = c_dungeon_alt; + obj->c_dungeon_stair = c_dungeon_stair; + + obj->depth_top = depth_top; + obj->depth_filler = depth_filler; + obj->depth_water_top = depth_water_top; + obj->depth_riverbed = depth_riverbed; + + obj->min_pos = min_pos; + obj->max_pos = max_pos; + obj->heat_point = heat_point; + obj->humidity_point = humidity_point; + obj->vertical_blend = vertical_blend; + + return obj; +} + +void Biome::resolveNodeNames() +{ + getIdFromNrBacklog(&c_top, "mapgen_stone", CONTENT_AIR, false); + getIdFromNrBacklog(&c_filler, "mapgen_stone", CONTENT_AIR, false); + getIdFromNrBacklog(&c_stone, "mapgen_stone", CONTENT_AIR, false); + getIdFromNrBacklog(&c_water_top, "mapgen_water_source", CONTENT_AIR, false); + getIdFromNrBacklog(&c_water, "mapgen_water_source", CONTENT_AIR, false); + getIdFromNrBacklog(&c_river_water, "mapgen_river_water_source", CONTENT_AIR, false); + getIdFromNrBacklog(&c_riverbed, "mapgen_stone", CONTENT_AIR, false); + getIdFromNrBacklog(&c_dust, "ignore", CONTENT_IGNORE, false); + getIdsFromNrBacklog(&c_cave_liquid); + getIdFromNrBacklog(&c_dungeon, "ignore", CONTENT_IGNORE, false); + getIdFromNrBacklog(&c_dungeon_alt, "ignore", CONTENT_IGNORE, false); + getIdFromNrBacklog(&c_dungeon_stair, "ignore", CONTENT_IGNORE, false); +} diff --git a/src/mapgen/mg_biome.h b/src/mapgen/mg_biome.h new file mode 100644 index 0000000..c85afc3 --- /dev/null +++ b/src/mapgen/mg_biome.h @@ -0,0 +1,252 @@ +/* +Minetest +Copyright (C) 2014-2020 paramat +Copyright (C) 2014-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "objdef.h" +#include "nodedef.h" +#include "noise.h" + +class Server; +class Settings; +class BiomeManager; + +//// +//// Biome +//// + +typedef u16 biome_t; + +#define BIOME_NONE ((biome_t)0) + +enum BiomeType { + BIOMETYPE_NORMAL, +}; + +class Biome : public ObjDef, public NodeResolver { +public: + ObjDef *clone() const; + + u32 flags; + + content_t c_top; + content_t c_filler; + content_t c_stone; + content_t c_water_top; + content_t c_water; + content_t c_river_water; + content_t c_riverbed; + content_t c_dust; + std::vector<content_t> c_cave_liquid; + content_t c_dungeon; + content_t c_dungeon_alt; + content_t c_dungeon_stair; + + s16 depth_top; + s16 depth_filler; + s16 depth_water_top; + s16 depth_riverbed; + + v3s16 min_pos; + v3s16 max_pos; + float heat_point; + float humidity_point; + s16 vertical_blend; + + virtual void resolveNodeNames(); +}; + + +//// +//// BiomeGen +//// + +enum BiomeGenType { + BIOMEGEN_ORIGINAL, +}; + +struct BiomeParams { + virtual void readParams(const Settings *settings) = 0; + virtual void writeParams(Settings *settings) const = 0; + virtual ~BiomeParams() = default; + + s32 seed; +}; + +// WARNING: this class is not thread-safe +class BiomeGen { +public: + virtual ~BiomeGen() = default; + + virtual BiomeGenType getType() const = 0; + + // Clone this BiomeGen and set a the new BiomeManager to be used by the copy + virtual BiomeGen *clone(BiomeManager *biomemgr) const = 0; + + // Check that the internal chunk size is what the mapgen expects, just to be sure. + inline void assertChunkSize(v3s16 expect) const + { + FATAL_ERROR_IF(m_csize != expect, "Chunk size mismatches"); + } + + // Calculates the biome at the exact position provided. This function can + // be called at any time, but may be less efficient than the latter methods, + // depending on implementation. + virtual Biome *calcBiomeAtPoint(v3s16 pos) const = 0; + + // Computes any intermediate results needed for biome generation. Must be + // called before using any of: getBiomes, getBiomeAtPoint, or getBiomeAtIndex. + // Calling this invalidates the previous results stored in biomemap. + virtual void calcBiomeNoise(v3s16 pmin) = 0; + + // Gets all biomes in current chunk using each corresponding element of + // heightmap as the y position, then stores the results by biome index in + // biomemap (also returned) + virtual biome_t *getBiomes(s16 *heightmap, v3s16 pmin) = 0; + + // Gets a single biome at the specified position, which must be contained + // in the region formed by m_pmin and (m_pmin + m_csize - 1). + virtual Biome *getBiomeAtPoint(v3s16 pos) const = 0; + + // Same as above, but uses a raw numeric index correlating to the (x,z) position. + virtual Biome *getBiomeAtIndex(size_t index, v3s16 pos) const = 0; + + // Result of calcBiomes bulk computation. + biome_t *biomemap = nullptr; + +protected: + BiomeManager *m_bmgr = nullptr; + v3s16 m_pmin; + v3s16 m_csize; +}; + + +//// +//// BiomeGen implementations +//// + +// +// Original biome algorithm (Whittaker's classification + surface height) +// + +struct BiomeParamsOriginal : public BiomeParams { + BiomeParamsOriginal() : + np_heat(50, 50, v3f(1000.0, 1000.0, 1000.0), 5349, 3, 0.5, 2.0), + np_humidity(50, 50, v3f(1000.0, 1000.0, 1000.0), 842, 3, 0.5, 2.0), + np_heat_blend(0, 1.5, v3f(8.0, 8.0, 8.0), 13, 2, 1.0, 2.0), + np_humidity_blend(0, 1.5, v3f(8.0, 8.0, 8.0), 90003, 2, 1.0, 2.0) + { + } + + virtual void readParams(const Settings *settings); + virtual void writeParams(Settings *settings) const; + + NoiseParams np_heat; + NoiseParams np_humidity; + NoiseParams np_heat_blend; + NoiseParams np_humidity_blend; +}; + +class BiomeGenOriginal : public BiomeGen { +public: + BiomeGenOriginal(BiomeManager *biomemgr, + const BiomeParamsOriginal *params, v3s16 chunksize); + virtual ~BiomeGenOriginal(); + + BiomeGenType getType() const { return BIOMEGEN_ORIGINAL; } + + BiomeGen *clone(BiomeManager *biomemgr) const; + + // Slower, meant for Script API use + float calcHeatAtPoint(v3s16 pos) const; + float calcHumidityAtPoint(v3s16 pos) const; + Biome *calcBiomeAtPoint(v3s16 pos) const; + + void calcBiomeNoise(v3s16 pmin); + + biome_t *getBiomes(s16 *heightmap, v3s16 pmin); + Biome *getBiomeAtPoint(v3s16 pos) const; + Biome *getBiomeAtIndex(size_t index, v3s16 pos) const; + + Biome *calcBiomeFromNoise(float heat, float humidity, v3s16 pos) const; + + float *heatmap; + float *humidmap; + +private: + const BiomeParamsOriginal *m_params; + + Noise *noise_heat; + Noise *noise_humidity; + Noise *noise_heat_blend; + Noise *noise_humidity_blend; +}; + + +//// +//// BiomeManager +//// + +class BiomeManager : public ObjDefManager { +public: + BiomeManager(Server *server); + virtual ~BiomeManager() = default; + + BiomeManager *clone() const; + + const char *getObjectTitle() const + { + return "biome"; + } + + static Biome *create(BiomeType type) + { + return new Biome; + } + + BiomeGen *createBiomeGen(BiomeGenType type, BiomeParams *params, v3s16 chunksize) + { + switch (type) { + case BIOMEGEN_ORIGINAL: + return new BiomeGenOriginal(this, + (BiomeParamsOriginal *)params, chunksize); + default: + return NULL; + } + } + + static BiomeParams *createBiomeParams(BiomeGenType type) + { + switch (type) { + case BIOMEGEN_ORIGINAL: + return new BiomeParamsOriginal; + default: + return NULL; + } + } + + virtual void clear(); + +private: + BiomeManager() {}; + + Server *m_server; + +}; diff --git a/src/mapgen/mg_decoration.cpp b/src/mapgen/mg_decoration.cpp new file mode 100644 index 0000000..a4cada3 --- /dev/null +++ b/src/mapgen/mg_decoration.cpp @@ -0,0 +1,467 @@ +/* +Minetest +Copyright (C) 2014-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2015-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mg_decoration.h" +#include "mg_schematic.h" +#include "mapgen.h" +#include "noise.h" +#include "map.h" +#include "log.h" +#include "util/numeric.h" +#include <algorithm> +#include <vector> + + +FlagDesc flagdesc_deco[] = { + {"place_center_x", DECO_PLACE_CENTER_X}, + {"place_center_y", DECO_PLACE_CENTER_Y}, + {"place_center_z", DECO_PLACE_CENTER_Z}, + {"force_placement", DECO_FORCE_PLACEMENT}, + {"liquid_surface", DECO_LIQUID_SURFACE}, + {"all_floors", DECO_ALL_FLOORS}, + {"all_ceilings", DECO_ALL_CEILINGS}, + {NULL, 0} +}; + + +/////////////////////////////////////////////////////////////////////////////// + + +DecorationManager::DecorationManager(IGameDef *gamedef) : + ObjDefManager(gamedef, OBJDEF_DECORATION) +{ +} + + +size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed, + v3s16 nmin, v3s16 nmax) +{ + size_t nplaced = 0; + + for (size_t i = 0; i != m_objects.size(); i++) { + Decoration *deco = (Decoration *)m_objects[i]; + if (!deco) + continue; + + nplaced += deco->placeDeco(mg, blockseed, nmin, nmax); + blockseed++; + } + + return nplaced; +} + +DecorationManager *DecorationManager::clone() const +{ + auto mgr = new DecorationManager(); + ObjDefManager::cloneTo(mgr); + return mgr; +} + + +/////////////////////////////////////////////////////////////////////////////// + + +void Decoration::resolveNodeNames() +{ + getIdsFromNrBacklog(&c_place_on); + getIdsFromNrBacklog(&c_spawnby); +} + + +bool Decoration::canPlaceDecoration(MMVManip *vm, v3s16 p) +{ + // Check if the decoration can be placed on this node + u32 vi = vm->m_area.index(p); + if (!CONTAINS(c_place_on, vm->m_data[vi].getContent())) + return false; + + // Don't continue if there are no spawnby constraints + if (nspawnby == -1) + return true; + + int nneighs = 0; + static const v3s16 dirs[16] = { + v3s16( 0, 0, 1), + v3s16( 0, 0, -1), + v3s16( 1, 0, 0), + v3s16(-1, 0, 0), + v3s16( 1, 0, 1), + v3s16(-1, 0, 1), + v3s16(-1, 0, -1), + v3s16( 1, 0, -1), + + v3s16( 0, 1, 1), + v3s16( 0, 1, -1), + v3s16( 1, 1, 0), + v3s16(-1, 1, 0), + v3s16( 1, 1, 1), + v3s16(-1, 1, 1), + v3s16(-1, 1, -1), + v3s16( 1, 1, -1) + }; + + // Check these 16 neighbouring nodes for enough spawnby nodes + for (size_t i = 0; i != ARRLEN(dirs); i++) { + u32 index = vm->m_area.index(p + dirs[i]); + if (!vm->m_area.contains(index)) + continue; + + if (CONTAINS(c_spawnby, vm->m_data[index].getContent())) + nneighs++; + } + + if (nneighs < nspawnby) + return false; + + return true; +} + + +size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) +{ + PcgRandom ps(blockseed + 53); + int carea_size = nmax.X - nmin.X + 1; + + // Divide area into parts + // If chunksize is changed it may no longer be divisable by sidelen + if (carea_size % sidelen) + sidelen = carea_size; + + s16 divlen = carea_size / sidelen; + int area = sidelen * sidelen; + + for (s16 z0 = 0; z0 < divlen; z0++) + for (s16 x0 = 0; x0 < divlen; x0++) { + v2s16 p2d_center( // Center position of part of division + nmin.X + sidelen / 2 + sidelen * x0, + nmin.Z + sidelen / 2 + sidelen * z0 + ); + v2s16 p2d_min( // Minimum edge of part of division + nmin.X + sidelen * x0, + nmin.Z + sidelen * z0 + ); + v2s16 p2d_max( // Maximum edge of part of division + nmin.X + sidelen + sidelen * x0 - 1, + nmin.Z + sidelen + sidelen * z0 - 1 + ); + + bool cover = false; + // Amount of decorations + float nval = (flags & DECO_USE_NOISE) ? + NoisePerlin2D(&np, p2d_center.X, p2d_center.Y, mapseed) : + fill_ratio; + u32 deco_count = 0; + + if (nval >= 10.0f) { + // Complete coverage. Disable random placement to avoid + // redundant multiple placements at one position. + cover = true; + deco_count = area; + } else { + float deco_count_f = (float)area * nval; + if (deco_count_f >= 1.0f) { + deco_count = deco_count_f; + } else if (deco_count_f > 0.0f) { + // For very low density calculate a chance for 1 decoration + if (ps.range(1000) <= deco_count_f * 1000.0f) + deco_count = 1; + } + } + + s16 x = p2d_min.X - 1; + s16 z = p2d_min.Y; + + for (u32 i = 0; i < deco_count; i++) { + if (!cover) { + x = ps.range(p2d_min.X, p2d_max.X); + z = ps.range(p2d_min.Y, p2d_max.Y); + } else { + x++; + if (x == p2d_max.X + 1) { + z++; + x = p2d_min.X; + } + } + int mapindex = carea_size * (z - nmin.Z) + (x - nmin.X); + + if ((flags & DECO_ALL_FLOORS) || + (flags & DECO_ALL_CEILINGS)) { + // All-surfaces decorations + // Check biome of column + if (mg->biomemap && !biomes.empty()) { + auto iter = biomes.find(mg->biomemap[mapindex]); + if (iter == biomes.end()) + continue; + } + + // Get all floors and ceilings in node column + u16 size = (nmax.Y - nmin.Y + 1) / 2; + std::vector<s16> floors; + std::vector<s16> ceilings; + floors.reserve(size); + ceilings.reserve(size); + + mg->getSurfaces(v2s16(x, z), nmin.Y, nmax.Y, floors, ceilings); + + if (flags & DECO_ALL_FLOORS) { + // Floor decorations + for (const s16 y : floors) { + if (y < y_min || y > y_max) + continue; + + v3s16 pos(x, y, z); + if (generate(mg->vm, &ps, pos, false)) + mg->gennotify.addEvent( + GENNOTIFY_DECORATION, pos, index); + } + } + + if (flags & DECO_ALL_CEILINGS) { + // Ceiling decorations + for (const s16 y : ceilings) { + if (y < y_min || y > y_max) + continue; + + v3s16 pos(x, y, z); + if (generate(mg->vm, &ps, pos, true)) + mg->gennotify.addEvent( + GENNOTIFY_DECORATION, pos, index); + } + } + } else { // Heightmap decorations + s16 y = -MAX_MAP_GENERATION_LIMIT; + if (flags & DECO_LIQUID_SURFACE) + y = mg->findLiquidSurface(v2s16(x, z), nmin.Y, nmax.Y); + else if (mg->heightmap) + y = mg->heightmap[mapindex]; + else + y = mg->findGroundLevel(v2s16(x, z), nmin.Y, nmax.Y); + + if (y < y_min || y > y_max || y < nmin.Y || y > nmax.Y) + continue; + + if (mg->biomemap && !biomes.empty()) { + auto iter = biomes.find(mg->biomemap[mapindex]); + if (iter == biomes.end()) + continue; + } + + v3s16 pos(x, y, z); + if (generate(mg->vm, &ps, pos, false)) + mg->gennotify.addEvent(GENNOTIFY_DECORATION, pos, index); + } + } + } + + return 0; +} + + +void Decoration::cloneTo(Decoration *def) const +{ + ObjDef::cloneTo(def); + def->flags = flags; + def->mapseed = mapseed; + def->c_place_on = c_place_on; + def->sidelen = sidelen; + def->y_min = y_min; + def->y_max = y_max; + def->fill_ratio = fill_ratio; + def->np = np; + def->c_spawnby = c_spawnby; + def->nspawnby = nspawnby; + def->place_offset_y = place_offset_y; + def->biomes = biomes; +} + + +/////////////////////////////////////////////////////////////////////////////// + + +ObjDef *DecoSimple::clone() const +{ + auto def = new DecoSimple(); + Decoration::cloneTo(def); + + def->c_decos = c_decos; + def->deco_height = deco_height; + def->deco_height_max = deco_height_max; + def->deco_param2 = deco_param2; + def->deco_param2_max = deco_param2_max; + + return def; +} + + +void DecoSimple::resolveNodeNames() +{ + Decoration::resolveNodeNames(); + getIdsFromNrBacklog(&c_decos); +} + + +size_t DecoSimple::generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling) +{ + // Don't bother if there aren't any decorations to place + if (c_decos.empty()) + return 0; + + if (!canPlaceDecoration(vm, p)) + return 0; + + // Check for placement outside the voxelmanip volume + if (ceiling) { + // Ceiling decorations + // 'place offset y' is inverted + if (p.Y - place_offset_y - std::max(deco_height, deco_height_max) < + vm->m_area.MinEdge.Y) + return 0; + + if (p.Y - 1 - place_offset_y > vm->m_area.MaxEdge.Y) + return 0; + + } else { // Heightmap and floor decorations + if (p.Y + place_offset_y + std::max(deco_height, deco_height_max) > + vm->m_area.MaxEdge.Y) + return 0; + + if (p.Y + 1 + place_offset_y < vm->m_area.MinEdge.Y) + return 0; + } + + content_t c_place = c_decos[pr->range(0, c_decos.size() - 1)]; + s16 height = (deco_height_max > 0) ? + pr->range(deco_height, deco_height_max) : deco_height; + u8 param2 = (deco_param2_max > 0) ? + pr->range(deco_param2, deco_param2_max) : deco_param2; + bool force_placement = (flags & DECO_FORCE_PLACEMENT); + + const v3s16 &em = vm->m_area.getExtent(); + u32 vi = vm->m_area.index(p); + + if (ceiling) { + // Ceiling decorations + // 'place offset y' is inverted + VoxelArea::add_y(em, vi, -place_offset_y); + + for (int i = 0; i < height; i++) { + VoxelArea::add_y(em, vi, -1); + content_t c = vm->m_data[vi].getContent(); + if (c != CONTENT_AIR && c != CONTENT_IGNORE && !force_placement) + break; + + vm->m_data[vi] = MapNode(c_place, 0, param2); + } + } else { // Heightmap and floor decorations + VoxelArea::add_y(em, vi, place_offset_y); + + for (int i = 0; i < height; i++) { + VoxelArea::add_y(em, vi, 1); + content_t c = vm->m_data[vi].getContent(); + if (c != CONTENT_AIR && c != CONTENT_IGNORE && !force_placement) + break; + + vm->m_data[vi] = MapNode(c_place, 0, param2); + } + } + + return 1; +} + + +/////////////////////////////////////////////////////////////////////////////// + + +DecoSchematic::~DecoSchematic() +{ + if (was_cloned) + delete schematic; +} + + +ObjDef *DecoSchematic::clone() const +{ + auto def = new DecoSchematic(); + Decoration::cloneTo(def); + NodeResolver::cloneTo(def); + + def->rotation = rotation; + /* FIXME: We do not own this schematic, yet we only have a pointer to it + * and not a handle. We are left with no option but to clone it ourselves. + * This is a waste of memory and should be replaced with an alternative + * approach sometime. */ + def->schematic = dynamic_cast<Schematic*>(schematic->clone()); + def->was_cloned = true; + + return def; +} + + +size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling) +{ + // Schematic could have been unloaded but not the decoration + // In this case generate() does nothing (but doesn't *fail*) + if (schematic == NULL) + return 0; + + if (!canPlaceDecoration(vm, p)) + return 0; + + if (flags & DECO_PLACE_CENTER_Y) { + p.Y -= (schematic->size.Y - 1) / 2; + } else { + // Only apply 'place offset y' if not 'deco place center y' + if (ceiling) + // Shift down so that schematic top layer is level with ceiling + // 'place offset y' is inverted + p.Y -= (place_offset_y + schematic->size.Y - 1); + else + p.Y += place_offset_y; + } + + // Check schematic top and base are in voxelmanip + if (p.Y + schematic->size.Y - 1 > vm->m_area.MaxEdge.Y) + return 0; + + if (p.Y < vm->m_area.MinEdge.Y) + return 0; + + Rotation rot = (rotation == ROTATE_RAND) ? + (Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation; + + if (flags & DECO_PLACE_CENTER_X) { + if (rot == ROTATE_0 || rot == ROTATE_180) + p.X -= (schematic->size.X - 1) / 2; + else + p.Z -= (schematic->size.X - 1) / 2; + } + if (flags & DECO_PLACE_CENTER_Z) { + if (rot == ROTATE_0 || rot == ROTATE_180) + p.Z -= (schematic->size.Z - 1) / 2; + else + p.X -= (schematic->size.Z - 1) / 2; + } + + bool force_placement = (flags & DECO_FORCE_PLACEMENT); + + schematic->blitToVManip(vm, p, rot, force_placement); + + return 1; +} diff --git a/src/mapgen/mg_decoration.h b/src/mapgen/mg_decoration.h new file mode 100644 index 0000000..1ea02a5 --- /dev/null +++ b/src/mapgen/mg_decoration.h @@ -0,0 +1,152 @@ +/* +Minetest +Copyright (C) 2014-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2015-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <unordered_set> +#include "objdef.h" +#include "noise.h" +#include "nodedef.h" + +typedef u16 biome_t; // copy from mg_biome.h to avoid an unnecessary include + +class Mapgen; +class MMVManip; +class PcgRandom; +class Schematic; + +enum DecorationType { + DECO_SIMPLE, + DECO_SCHEMATIC, + DECO_LSYSTEM +}; + +#define DECO_PLACE_CENTER_X 0x01 +#define DECO_PLACE_CENTER_Y 0x02 +#define DECO_PLACE_CENTER_Z 0x04 +#define DECO_USE_NOISE 0x08 +#define DECO_FORCE_PLACEMENT 0x10 +#define DECO_LIQUID_SURFACE 0x20 +#define DECO_ALL_FLOORS 0x40 +#define DECO_ALL_CEILINGS 0x80 + +extern FlagDesc flagdesc_deco[]; + + +class Decoration : public ObjDef, public NodeResolver { +public: + Decoration() = default; + virtual ~Decoration() = default; + + virtual void resolveNodeNames(); + + bool canPlaceDecoration(MMVManip *vm, v3s16 p); + size_t placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax); + + virtual size_t generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling) = 0; + + u32 flags = 0; + int mapseed = 0; + std::vector<content_t> c_place_on; + s16 sidelen = 1; + s16 y_min; + s16 y_max; + float fill_ratio = 0.0f; + NoiseParams np; + std::vector<content_t> c_spawnby; + s16 nspawnby; + s16 place_offset_y = 0; + + std::unordered_set<biome_t> biomes; + +protected: + void cloneTo(Decoration *def) const; +}; + + +class DecoSimple : public Decoration { +public: + ObjDef *clone() const; + + virtual void resolveNodeNames(); + virtual size_t generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling); + + std::vector<content_t> c_decos; + s16 deco_height; + s16 deco_height_max; + u8 deco_param2; + u8 deco_param2_max; +}; + + +class DecoSchematic : public Decoration { +public: + ObjDef *clone() const; + + DecoSchematic() = default; + virtual ~DecoSchematic(); + + virtual size_t generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling); + + Rotation rotation; + Schematic *schematic = nullptr; + bool was_cloned = false; // see FIXME inside DecoSchemtic::clone() +}; + + +/* +class DecoLSystem : public Decoration { +public: + virtual void generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax); +}; +*/ + + +class DecorationManager : public ObjDefManager { +public: + DecorationManager(IGameDef *gamedef); + virtual ~DecorationManager() = default; + + DecorationManager *clone() const; + + const char *getObjectTitle() const + { + return "decoration"; + } + + static Decoration *create(DecorationType type) + { + switch (type) { + case DECO_SIMPLE: + return new DecoSimple; + case DECO_SCHEMATIC: + return new DecoSchematic; + //case DECO_LSYSTEM: + // return new DecoLSystem; + default: + return NULL; + } + } + + size_t placeAllDecos(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax); + +private: + DecorationManager() {}; +}; diff --git a/src/mapgen/mg_ore.cpp b/src/mapgen/mg_ore.cpp new file mode 100644 index 0000000..4f0c355 --- /dev/null +++ b/src/mapgen/mg_ore.cpp @@ -0,0 +1,600 @@ +/* +Minetest +Copyright (C) 2015-2020 paramat +Copyright (C) 2014-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mg_ore.h" +#include "mapgen.h" +#include "noise.h" +#include "map.h" +#include "log.h" +#include "util/numeric.h" +#include <cmath> +#include <algorithm> + + +FlagDesc flagdesc_ore[] = { + {"absheight", OREFLAG_ABSHEIGHT}, // Non-functional + {"puff_cliffs", OREFLAG_PUFF_CLIFFS}, + {"puff_additive_composition", OREFLAG_PUFF_ADDITIVE}, + {NULL, 0} +}; + + +/////////////////////////////////////////////////////////////////////////////// + + +OreManager::OreManager(IGameDef *gamedef) : + ObjDefManager(gamedef, OBJDEF_ORE) +{ +} + + +size_t OreManager::placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) +{ + size_t nplaced = 0; + + for (size_t i = 0; i != m_objects.size(); i++) { + Ore *ore = (Ore *)m_objects[i]; + if (!ore) + continue; + + nplaced += ore->placeOre(mg, blockseed, nmin, nmax); + blockseed++; + } + + return nplaced; +} + + +void OreManager::clear() +{ + for (ObjDef *object : m_objects) { + Ore *ore = (Ore *) object; + delete ore; + } + m_objects.clear(); +} + + +OreManager *OreManager::clone() const +{ + auto mgr = new OreManager(); + ObjDefManager::cloneTo(mgr); + return mgr; +} + + +/////////////////////////////////////////////////////////////////////////////// + + +Ore::~Ore() +{ + delete noise; +} + + +void Ore::resolveNodeNames() +{ + getIdFromNrBacklog(&c_ore, "", CONTENT_AIR); + getIdsFromNrBacklog(&c_wherein); +} + + +size_t Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) +{ + if (nmin.Y > y_max || nmax.Y < y_min) + return 0; + + int actual_ymin = MYMAX(nmin.Y, y_min); + int actual_ymax = MYMIN(nmax.Y, y_max); + if (clust_size >= actual_ymax - actual_ymin + 1) + return 0; + + nmin.Y = actual_ymin; + nmax.Y = actual_ymax; + generate(mg->vm, mg->seed, blockseed, nmin, nmax, mg->biomemap); + + return 1; +} + + +void Ore::cloneTo(Ore *def) const +{ + ObjDef::cloneTo(def); + NodeResolver::cloneTo(def); + def->c_ore = c_ore; + def->c_wherein = c_wherein; + def->clust_scarcity = clust_scarcity; + def->clust_num_ores = clust_num_ores; + def->clust_size = clust_size; + def->y_min = y_min; + def->y_max = y_max; + def->ore_param2 = ore_param2; + def->flags = flags; + def->nthresh = nthresh; + def->np = np; + def->noise = nullptr; // cannot be shared! so created on demand + def->biomes = biomes; +} + + +/////////////////////////////////////////////////////////////////////////////// + + +ObjDef *OreScatter::clone() const +{ + auto def = new OreScatter(); + Ore::cloneTo(def); + return def; +} + + +void OreScatter::generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) +{ + PcgRandom pr(blockseed); + MapNode n_ore(c_ore, 0, ore_param2); + + u32 sizex = (nmax.X - nmin.X + 1); + u32 volume = (nmax.X - nmin.X + 1) * + (nmax.Y - nmin.Y + 1) * + (nmax.Z - nmin.Z + 1); + u32 csize = clust_size; + u32 cvolume = csize * csize * csize; + u32 nclusters = volume / clust_scarcity; + + for (u32 i = 0; i != nclusters; i++) { + int x0 = pr.range(nmin.X, nmax.X - csize + 1); + int y0 = pr.range(nmin.Y, nmax.Y - csize + 1); + int z0 = pr.range(nmin.Z, nmax.Z - csize + 1); + + if ((flags & OREFLAG_USE_NOISE) && + (NoisePerlin3D(&np, x0, y0, z0, mapseed) < nthresh)) + continue; + + if (biomemap && !biomes.empty()) { + u32 index = sizex * (z0 - nmin.Z) + (x0 - nmin.X); + auto it = biomes.find(biomemap[index]); + if (it == biomes.end()) + continue; + } + + for (u32 z1 = 0; z1 != csize; z1++) + for (u32 y1 = 0; y1 != csize; y1++) + for (u32 x1 = 0; x1 != csize; x1++) { + if (pr.range(1, cvolume) > clust_num_ores) + continue; + + u32 i = vm->m_area.index(x0 + x1, y0 + y1, z0 + z1); + if (!CONTAINS(c_wherein, vm->m_data[i].getContent())) + continue; + + vm->m_data[i] = n_ore; + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// + + +ObjDef *OreSheet::clone() const +{ + auto def = new OreSheet(); + Ore::cloneTo(def); + + def->column_height_max = column_height_max; + def->column_height_min = column_height_min; + def->column_midpoint_factor = column_midpoint_factor; + + return def; +} + + +void OreSheet::generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) +{ + PcgRandom pr(blockseed + 4234); + MapNode n_ore(c_ore, 0, ore_param2); + + u16 max_height = column_height_max; + int y_start_min = nmin.Y + max_height; + int y_start_max = nmax.Y - max_height; + + int y_start = y_start_min < y_start_max ? + pr.range(y_start_min, y_start_max) : + (y_start_min + y_start_max) / 2; + + if (!noise) { + int sx = nmax.X - nmin.X + 1; + int sz = nmax.Z - nmin.Z + 1; + noise = new Noise(&np, 0, sx, sz); + } + noise->seed = mapseed + y_start; + noise->perlinMap2D(nmin.X, nmin.Z); + + size_t index = 0; + for (int z = nmin.Z; z <= nmax.Z; z++) + for (int x = nmin.X; x <= nmax.X; x++, index++) { + float noiseval = noise->result[index]; + if (noiseval < nthresh) + continue; + + if (biomemap && !biomes.empty()) { + auto it = biomes.find(biomemap[index]); + if (it == biomes.end()) + continue; + } + + u16 height = pr.range(column_height_min, column_height_max); + int ymidpoint = y_start + noiseval; + int y0 = MYMAX(nmin.Y, ymidpoint - height * (1 - column_midpoint_factor)); + int y1 = MYMIN(nmax.Y, y0 + height - 1); + + for (int y = y0; y <= y1; y++) { + u32 i = vm->m_area.index(x, y, z); + if (!vm->m_area.contains(i)) + continue; + if (!CONTAINS(c_wherein, vm->m_data[i].getContent())) + continue; + + vm->m_data[i] = n_ore; + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// + + +OrePuff::~OrePuff() +{ + delete noise_puff_top; + delete noise_puff_bottom; +} + + +ObjDef *OrePuff::clone() const +{ + auto def = new OrePuff(); + Ore::cloneTo(def); + + def->np_puff_top = np_puff_top; + def->np_puff_bottom = np_puff_bottom; + def->noise_puff_top = nullptr; // cannot be shared, on-demand + def->noise_puff_bottom = nullptr; + + return def; +} + + +void OrePuff::generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) +{ + PcgRandom pr(blockseed + 4234); + MapNode n_ore(c_ore, 0, ore_param2); + + int y_start = pr.range(nmin.Y, nmax.Y); + + if (!noise) { + int sx = nmax.X - nmin.X + 1; + int sz = nmax.Z - nmin.Z + 1; + noise = new Noise(&np, 0, sx, sz); + noise_puff_top = new Noise(&np_puff_top, 0, sx, sz); + noise_puff_bottom = new Noise(&np_puff_bottom, 0, sx, sz); + } + + noise->seed = mapseed + y_start; + noise->perlinMap2D(nmin.X, nmin.Z); + bool noise_generated = false; + + size_t index = 0; + for (int z = nmin.Z; z <= nmax.Z; z++) + for (int x = nmin.X; x <= nmax.X; x++, index++) { + float noiseval = noise->result[index]; + if (noiseval < nthresh) + continue; + + if (biomemap && !biomes.empty()) { + auto it = biomes.find(biomemap[index]); + if (it == biomes.end()) + continue; + } + + if (!noise_generated) { + noise_generated = true; + noise_puff_top->perlinMap2D(nmin.X, nmin.Z); + noise_puff_bottom->perlinMap2D(nmin.X, nmin.Z); + } + + float ntop = noise_puff_top->result[index]; + float nbottom = noise_puff_bottom->result[index]; + + if (!(flags & OREFLAG_PUFF_CLIFFS)) { + float ndiff = noiseval - nthresh; + if (ndiff < 1.0f) { + ntop *= ndiff; + nbottom *= ndiff; + } + } + + int ymid = y_start; + int y0 = ymid - nbottom; + int y1 = ymid + ntop; + + if ((flags & OREFLAG_PUFF_ADDITIVE) && (y0 > y1)) + SWAP(int, y0, y1); + + for (int y = y0; y <= y1; y++) { + u32 i = vm->m_area.index(x, y, z); + if (!vm->m_area.contains(i)) + continue; + if (!CONTAINS(c_wherein, vm->m_data[i].getContent())) + continue; + + vm->m_data[i] = n_ore; + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// + + +ObjDef *OreBlob::clone() const +{ + auto def = new OreBlob(); + Ore::cloneTo(def); + return def; +} + + +void OreBlob::generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) +{ + PcgRandom pr(blockseed + 2404); + MapNode n_ore(c_ore, 0, ore_param2); + + u32 sizex = (nmax.X - nmin.X + 1); + u32 volume = (nmax.X - nmin.X + 1) * + (nmax.Y - nmin.Y + 1) * + (nmax.Z - nmin.Z + 1); + u32 csize = clust_size; + u32 nblobs = volume / clust_scarcity; + + if (!noise) + noise = new Noise(&np, mapseed, csize, csize, csize); + + for (u32 i = 0; i != nblobs; i++) { + int x0 = pr.range(nmin.X, nmax.X - csize + 1); + int y0 = pr.range(nmin.Y, nmax.Y - csize + 1); + int z0 = pr.range(nmin.Z, nmax.Z - csize + 1); + + if (biomemap && !biomes.empty()) { + u32 bmapidx = sizex * (z0 - nmin.Z) + (x0 - nmin.X); + auto it = biomes.find(biomemap[bmapidx]); + if (it == biomes.end()) + continue; + } + + bool noise_generated = false; + noise->seed = blockseed + i; + + size_t index = 0; + for (u32 z1 = 0; z1 != csize; z1++) + for (u32 y1 = 0; y1 != csize; y1++) + for (u32 x1 = 0; x1 != csize; x1++, index++) { + u32 i = vm->m_area.index(x0 + x1, y0 + y1, z0 + z1); + if (!CONTAINS(c_wherein, vm->m_data[i].getContent())) + continue; + + // Lazily generate noise only if there's a chance of ore being placed + // This simple optimization makes calls 6x faster on average + if (!noise_generated) { + noise_generated = true; + noise->perlinMap3D(x0, y0, z0); + } + + float noiseval = noise->result[index]; + + float xdist = (s32)x1 - (s32)csize / 2; + float ydist = (s32)y1 - (s32)csize / 2; + float zdist = (s32)z1 - (s32)csize / 2; + + noiseval -= std::sqrt(xdist * xdist + ydist * ydist + zdist * zdist) / csize; + + if (noiseval < nthresh) + continue; + + vm->m_data[i] = n_ore; + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// + + +OreVein::~OreVein() +{ + delete noise2; +} + + +ObjDef *OreVein::clone() const +{ + auto def = new OreVein(); + Ore::cloneTo(def); + + def->random_factor = random_factor; + def->noise2 = nullptr; // cannot be shared, on-demand + def->sizey_prev = sizey_prev; + + return def; +} + + +void OreVein::generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) +{ + PcgRandom pr(blockseed + 520); + MapNode n_ore(c_ore, 0, ore_param2); + + int sizex = nmax.X - nmin.X + 1; + int sizey = nmax.Y - nmin.Y + 1; + // Because this ore uses 3D noise the perlinmap Y size can be different in + // different mapchunks due to ore Y limits. So recreate the noise objects + // if Y size has changed. + // Because these noise objects are created multiple times for this ore type + // it is necessary to 'delete' them here. + if (!noise || sizey != sizey_prev) { + delete noise; + delete noise2; + int sizez = nmax.Z - nmin.Z + 1; + noise = new Noise(&np, mapseed, sizex, sizey, sizez); + noise2 = new Noise(&np, mapseed + 436, sizex, sizey, sizez); + sizey_prev = sizey; + } + + bool noise_generated = false; + size_t index = 0; + for (int z = nmin.Z; z <= nmax.Z; z++) + for (int y = nmin.Y; y <= nmax.Y; y++) + for (int x = nmin.X; x <= nmax.X; x++, index++) { + u32 i = vm->m_area.index(x, y, z); + if (!vm->m_area.contains(i)) + continue; + if (!CONTAINS(c_wherein, vm->m_data[i].getContent())) + continue; + + if (biomemap && !biomes.empty()) { + u32 bmapidx = sizex * (z - nmin.Z) + (x - nmin.X); + auto it = biomes.find(biomemap[bmapidx]); + if (it == biomes.end()) + continue; + } + + // Same lazy generation optimization as in OreBlob + if (!noise_generated) { + noise_generated = true; + noise->perlinMap3D(nmin.X, nmin.Y, nmin.Z); + noise2->perlinMap3D(nmin.X, nmin.Y, nmin.Z); + } + + // randval ranges from -1..1 + /* + Note: can generate values slightly larger than 1 + but this can't be changed as mapgen must be deterministic accross versions. + */ + float randval = (float)pr.next() / float(pr.RANDOM_RANGE / 2) - 1.f; + float noiseval = contour(noise->result[index]); + float noiseval2 = contour(noise2->result[index]); + if (noiseval * noiseval2 + randval * random_factor < nthresh) + continue; + + vm->m_data[i] = n_ore; + } +} + + +/////////////////////////////////////////////////////////////////////////////// + + +OreStratum::~OreStratum() +{ + delete noise_stratum_thickness; +} + + +ObjDef *OreStratum::clone() const +{ + auto def = new OreStratum(); + Ore::cloneTo(def); + + def->np_stratum_thickness = np_stratum_thickness; + def->noise_stratum_thickness = nullptr; // cannot be shared, on-demand + def->stratum_thickness = stratum_thickness; + + return def; +} + + +void OreStratum::generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) +{ + PcgRandom pr(blockseed + 4234); + MapNode n_ore(c_ore, 0, ore_param2); + + if (flags & OREFLAG_USE_NOISE) { + if (!noise) { + int sx = nmax.X - nmin.X + 1; + int sz = nmax.Z - nmin.Z + 1; + noise = new Noise(&np, 0, sx, sz); + } + noise->perlinMap2D(nmin.X, nmin.Z); + } + + if (flags & OREFLAG_USE_NOISE2) { + if (!noise_stratum_thickness) { + int sx = nmax.X - nmin.X + 1; + int sz = nmax.Z - nmin.Z + 1; + noise_stratum_thickness = new Noise(&np_stratum_thickness, 0, sx, sz); + } + noise_stratum_thickness->perlinMap2D(nmin.X, nmin.Z); + } + + size_t index = 0; + + for (int z = nmin.Z; z <= nmax.Z; z++) + for (int x = nmin.X; x <= nmax.X; x++, index++) { + if (biomemap && !biomes.empty()) { + auto it = biomes.find(biomemap[index]); + if (it == biomes.end()) + continue; + } + + int y0; + int y1; + + if (flags & OREFLAG_USE_NOISE) { + float nhalfthick = ((flags & OREFLAG_USE_NOISE2) ? + noise_stratum_thickness->result[index] : (float)stratum_thickness) / + 2.0f; + float nmid = noise->result[index]; + y0 = MYMAX(nmin.Y, std::ceil(nmid - nhalfthick)); + y1 = MYMIN(nmax.Y, nmid + nhalfthick); + } else { // Simple horizontal stratum + y0 = nmin.Y; + y1 = nmax.Y; + } + + for (int y = y0; y <= y1; y++) { + if (pr.range(1, clust_scarcity) != 1) + continue; + + u32 i = vm->m_area.index(x, y, z); + if (!vm->m_area.contains(i)) + continue; + if (!CONTAINS(c_wherein, vm->m_data[i].getContent())) + continue; + + vm->m_data[i] = n_ore; + } + } +} diff --git a/src/mapgen/mg_ore.h b/src/mapgen/mg_ore.h new file mode 100644 index 0000000..a757fa6 --- /dev/null +++ b/src/mapgen/mg_ore.h @@ -0,0 +1,201 @@ +/* +Minetest +Copyright (C) 2015-2020 paramat +Copyright (C) 2014-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <unordered_set> +#include "objdef.h" +#include "noise.h" +#include "nodedef.h" + +typedef u16 biome_t; // copy from mg_biome.h to avoid an unnecessary include + +class Noise; +class Mapgen; +class MMVManip; + +/////////////////// Ore generation flags + +#define OREFLAG_ABSHEIGHT 0x01 // Non-functional but kept to not break flags +#define OREFLAG_PUFF_CLIFFS 0x02 +#define OREFLAG_PUFF_ADDITIVE 0x04 +#define OREFLAG_USE_NOISE 0x08 +#define OREFLAG_USE_NOISE2 0x10 + +enum OreType { + ORE_SCATTER, + ORE_SHEET, + ORE_PUFF, + ORE_BLOB, + ORE_VEIN, + ORE_STRATUM, +}; + +extern FlagDesc flagdesc_ore[]; + +class Ore : public ObjDef, public NodeResolver { +public: + const bool needs_noise; + + content_t c_ore; // the node to place + std::vector<content_t> c_wherein; // the nodes to be placed in + u32 clust_scarcity; // ore cluster has a 1-in-clust_scarcity chance of appearing at a node + s16 clust_num_ores; // how many ore nodes are in a chunk + s16 clust_size; // how large (in nodes) a chunk of ore is + s16 y_min; + s16 y_max; + u8 ore_param2; // to set node-specific attributes + u32 flags = 0; // attributes for this ore + float nthresh; // threshold for noise at which an ore is placed + NoiseParams np; // noise for distribution of clusters (NULL for uniform scattering) + Noise *noise = nullptr; + std::unordered_set<biome_t> biomes; + + explicit Ore(bool needs_noise): needs_noise(needs_noise) {} + virtual ~Ore(); + + virtual void resolveNodeNames(); + + size_t placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax); + virtual void generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) = 0; + +protected: + void cloneTo(Ore *def) const; +}; + +class OreScatter : public Ore { +public: + OreScatter() : Ore(false) {} + + ObjDef *clone() const override; + + void generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) override; +}; + +class OreSheet : public Ore { +public: + OreSheet() : Ore(true) {} + + ObjDef *clone() const override; + + u16 column_height_min; + u16 column_height_max; + float column_midpoint_factor; + + void generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) override; +}; + +class OrePuff : public Ore { +public: + ObjDef *clone() const override; + + NoiseParams np_puff_top; + NoiseParams np_puff_bottom; + Noise *noise_puff_top = nullptr; + Noise *noise_puff_bottom = nullptr; + + OrePuff() : Ore(true) {} + virtual ~OrePuff(); + + void generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) override; +}; + +class OreBlob : public Ore { +public: + ObjDef *clone() const override; + + OreBlob() : Ore(true) {} + void generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) override; +}; + +class OreVein : public Ore { +public: + ObjDef *clone() const override; + + float random_factor; + Noise *noise2 = nullptr; + int sizey_prev = 0; + + OreVein() : Ore(true) {} + virtual ~OreVein(); + + void generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) override; +}; + +class OreStratum : public Ore { +public: + ObjDef *clone() const override; + + NoiseParams np_stratum_thickness; + Noise *noise_stratum_thickness = nullptr; + u16 stratum_thickness; + + OreStratum() : Ore(false) {} + virtual ~OreStratum(); + + void generate(MMVManip *vm, int mapseed, u32 blockseed, + v3s16 nmin, v3s16 nmax, biome_t *biomemap) override; +}; + +class OreManager : public ObjDefManager { +public: + OreManager(IGameDef *gamedef); + virtual ~OreManager() = default; + + OreManager *clone() const; + + const char *getObjectTitle() const + { + return "ore"; + } + + static Ore *create(OreType type) + { + switch (type) { + case ORE_SCATTER: + return new OreScatter; + case ORE_SHEET: + return new OreSheet; + case ORE_PUFF: + return new OrePuff; + case ORE_BLOB: + return new OreBlob; + case ORE_VEIN: + return new OreVein; + case ORE_STRATUM: + return new OreStratum; + default: + return nullptr; + } + } + + void clear(); + + size_t placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax); + +private: + OreManager() {}; +}; diff --git a/src/mapgen/mg_schematic.cpp b/src/mapgen/mg_schematic.cpp new file mode 100644 index 0000000..b9ba703 --- /dev/null +++ b/src/mapgen/mg_schematic.cpp @@ -0,0 +1,636 @@ +/* +Minetest +Copyright (C) 2014-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2015-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <fstream> +#include <typeinfo> +#include "mg_schematic.h" +#include "server.h" +#include "mapgen.h" +#include "emerge.h" +#include "map.h" +#include "mapblock.h" +#include "log.h" +#include "util/numeric.h" +#include "util/serialize.h" +#include "serialization.h" +#include "filesys.h" +#include "voxelalgorithms.h" + +/////////////////////////////////////////////////////////////////////////////// + + +SchematicManager::SchematicManager(Server *server) : + ObjDefManager(server, OBJDEF_SCHEMATIC), + m_server(server) +{ +} + + +SchematicManager *SchematicManager::clone() const +{ + auto mgr = new SchematicManager(); + assert(mgr); + ObjDefManager::cloneTo(mgr); + return mgr; +} + + +void SchematicManager::clear() +{ + EmergeManager *emerge = m_server->getEmergeManager(); + + // Remove all dangling references in Decorations + DecorationManager *decomgr = emerge->getWritableDecorationManager(); + for (size_t i = 0; i != decomgr->getNumObjects(); i++) { + Decoration *deco = (Decoration *)decomgr->getRaw(i); + + try { + DecoSchematic *dschem = dynamic_cast<DecoSchematic *>(deco); + if (dschem) + dschem->schematic = NULL; + } catch (const std::bad_cast &) { + } + } + + ObjDefManager::clear(); +} + + +/////////////////////////////////////////////////////////////////////////////// + + +Schematic::~Schematic() +{ + delete []schemdata; + delete []slice_probs; +} + +ObjDef *Schematic::clone() const +{ + auto def = new Schematic(); + ObjDef::cloneTo(def); + NodeResolver::cloneTo(def); + + def->c_nodes = c_nodes; + def->flags = flags; + def->size = size; + FATAL_ERROR_IF(!schemdata, "Schematic can only be cloned after loading"); + u32 nodecount = size.X * size.Y * size.Z; + def->schemdata = new MapNode[nodecount]; + memcpy(def->schemdata, schemdata, sizeof(MapNode) * nodecount); + def->slice_probs = new u8[size.Y]; + memcpy(def->slice_probs, slice_probs, sizeof(u8) * size.Y); + + return def; +} + + +void Schematic::resolveNodeNames() +{ + c_nodes.clear(); + getIdsFromNrBacklog(&c_nodes, true, CONTENT_AIR); + + size_t bufsize = size.X * size.Y * size.Z; + for (size_t i = 0; i != bufsize; i++) { + content_t c_original = schemdata[i].getContent(); + if (c_original >= c_nodes.size()) { + errorstream << "Corrupt schematic. name=\"" << name + << "\" at index " << i << std::endl; + c_original = 0; + } + // Unfold condensed ID layout to content_t + schemdata[i].setContent(c_nodes[c_original]); + } +} + + +void Schematic::blitToVManip(MMVManip *vm, v3s16 p, Rotation rot, bool force_place) +{ + assert(schemdata && slice_probs); + sanity_check(m_ndef != NULL); + + int xstride = 1; + int ystride = size.X; + int zstride = size.X * size.Y; + + s16 sx = size.X; + s16 sy = size.Y; + s16 sz = size.Z; + + int i_start, i_step_x, i_step_z; + switch (rot) { + case ROTATE_90: + i_start = sx - 1; + i_step_x = zstride; + i_step_z = -xstride; + SWAP(s16, sx, sz); + break; + case ROTATE_180: + i_start = zstride * (sz - 1) + sx - 1; + i_step_x = -xstride; + i_step_z = -zstride; + break; + case ROTATE_270: + i_start = zstride * (sz - 1); + i_step_x = -zstride; + i_step_z = xstride; + SWAP(s16, sx, sz); + break; + default: + i_start = 0; + i_step_x = xstride; + i_step_z = zstride; + } + + s16 y_map = p.Y; + for (s16 y = 0; y != sy; y++) { + if ((slice_probs[y] != MTSCHEM_PROB_ALWAYS) && + (slice_probs[y] <= myrand_range(1, MTSCHEM_PROB_ALWAYS))) + continue; + + for (s16 z = 0; z != sz; z++) { + u32 i = z * i_step_z + y * ystride + i_start; + for (s16 x = 0; x != sx; x++, i += i_step_x) { + v3s16 pos(p.X + x, y_map, p.Z + z); + if (!vm->m_area.contains(pos)) + continue; + + if (schemdata[i].getContent() == CONTENT_IGNORE) + continue; + + u8 placement_prob = schemdata[i].param1 & MTSCHEM_PROB_MASK; + bool force_place_node = schemdata[i].param1 & MTSCHEM_FORCE_PLACE; + + if (placement_prob == MTSCHEM_PROB_NEVER) + continue; + + u32 vi = vm->m_area.index(pos); + if (!force_place && !force_place_node) { + content_t c = vm->m_data[vi].getContent(); + if (c != CONTENT_AIR && c != CONTENT_IGNORE) + continue; + } + + if ((placement_prob != MTSCHEM_PROB_ALWAYS) && + (placement_prob <= myrand_range(1, MTSCHEM_PROB_ALWAYS))) + continue; + + vm->m_data[vi] = schemdata[i]; + vm->m_data[vi].param1 = 0; + + if (rot) + vm->m_data[vi].rotateAlongYAxis(m_ndef, rot); + } + } + y_map++; + } +} + + +bool Schematic::placeOnVManip(MMVManip *vm, v3s16 p, u32 flags, + Rotation rot, bool force_place) +{ + assert(vm != NULL); + assert(schemdata && slice_probs); + sanity_check(m_ndef != NULL); + + //// Determine effective rotation and effective schematic dimensions + if (rot == ROTATE_RAND) + rot = (Rotation)myrand_range(ROTATE_0, ROTATE_270); + + v3s16 s = (rot == ROTATE_90 || rot == ROTATE_270) ? + v3s16(size.Z, size.Y, size.X) : size; + + //// Adjust placement position if necessary + if (flags & DECO_PLACE_CENTER_X) + p.X -= (s.X - 1) / 2; + if (flags & DECO_PLACE_CENTER_Y) + p.Y -= (s.Y - 1) / 2; + if (flags & DECO_PLACE_CENTER_Z) + p.Z -= (s.Z - 1) / 2; + + blitToVManip(vm, p, rot, force_place); + + return vm->m_area.contains(VoxelArea(p, p + s - v3s16(1, 1, 1))); +} + +void Schematic::placeOnMap(ServerMap *map, v3s16 p, u32 flags, + Rotation rot, bool force_place) +{ + std::map<v3s16, MapBlock *> lighting_modified_blocks; + std::map<v3s16, MapBlock *> modified_blocks; + std::map<v3s16, MapBlock *>::iterator it; + + assert(map != NULL); + assert(schemdata != NULL); + sanity_check(m_ndef != NULL); + + //// Determine effective rotation and effective schematic dimensions + if (rot == ROTATE_RAND) + rot = (Rotation)myrand_range(ROTATE_0, ROTATE_270); + + v3s16 s = (rot == ROTATE_90 || rot == ROTATE_270) ? + v3s16(size.Z, size.Y, size.X) : size; + + //// Adjust placement position if necessary + if (flags & DECO_PLACE_CENTER_X) + p.X -= (s.X - 1) / 2; + if (flags & DECO_PLACE_CENTER_Y) + p.Y -= (s.Y - 1) / 2; + if (flags & DECO_PLACE_CENTER_Z) + p.Z -= (s.Z - 1) / 2; + + //// Create VManip for effected area, emerge our area, modify area + //// inside VManip, then blit back. + v3s16 bp1 = getNodeBlockPos(p); + v3s16 bp2 = getNodeBlockPos(p + s - v3s16(1, 1, 1)); + + MMVManip vm(map); + vm.initialEmerge(bp1, bp2); + + blitToVManip(&vm, p, rot, force_place); + + voxalgo::blit_back_with_light(map, &vm, &modified_blocks); + + //// Carry out post-map-modification actions + + //// Create & dispatch map modification events to observers + MapEditEvent event; + event.type = MEET_OTHER; + for (it = modified_blocks.begin(); it != modified_blocks.end(); ++it) + event.modified_blocks.insert(it->first); + + map->dispatchEvent(event); +} + + +bool Schematic::deserializeFromMts(std::istream *is) +{ + std::istream &ss = *is; + content_t cignore = CONTENT_IGNORE; + bool have_cignore = false; + + //// Read signature + u32 signature = readU32(ss); + if (signature != MTSCHEM_FILE_SIGNATURE) { + errorstream << __FUNCTION__ << ": invalid schematic " + "file" << std::endl; + return false; + } + + //// Read version + u16 version = readU16(ss); + if (version > MTSCHEM_FILE_VER_HIGHEST_READ) { + errorstream << __FUNCTION__ << ": unsupported schematic " + "file version" << std::endl; + return false; + } + + //// Read size + size = readV3S16(ss); + + //// Read Y-slice probability values + delete []slice_probs; + slice_probs = new u8[size.Y]; + for (int y = 0; y != size.Y; y++) + slice_probs[y] = (version >= 3) ? readU8(ss) : MTSCHEM_PROB_ALWAYS_OLD; + + //// Read node names + NodeResolver::reset(); + + u16 nidmapcount = readU16(ss); + for (int i = 0; i != nidmapcount; i++) { + std::string name = deSerializeString16(ss); + + // Instances of "ignore" from v1 are converted to air (and instances + // are fixed to have MTSCHEM_PROB_NEVER later on). + if (name == "ignore") { + name = "air"; + cignore = i; + have_cignore = true; + } + + m_nodenames.push_back(name); + } + + // Prepare for node resolver + m_nnlistsizes.push_back(m_nodenames.size()); + + //// Read node data + size_t nodecount = size.X * size.Y * size.Z; + + delete []schemdata; + schemdata = new MapNode[nodecount]; + + std::stringstream d_ss(std::ios_base::binary | std::ios_base::in | std::ios_base::out); + decompress(ss, d_ss, MTSCHEM_MAPNODE_SER_FMT_VER); + MapNode::deSerializeBulk(d_ss, MTSCHEM_MAPNODE_SER_FMT_VER, schemdata, + nodecount, 2, 2); + + // Fix probability values for nodes that were ignore; removed in v2 + if (version < 2) { + for (size_t i = 0; i != nodecount; i++) { + if (schemdata[i].param1 == 0) + schemdata[i].param1 = MTSCHEM_PROB_ALWAYS_OLD; + if (have_cignore && schemdata[i].getContent() == cignore) + schemdata[i].param1 = MTSCHEM_PROB_NEVER; + } + } + + // Fix probability values for probability range truncation introduced in v4 + if (version < 4) { + for (s16 y = 0; y != size.Y; y++) + slice_probs[y] >>= 1; + for (size_t i = 0; i != nodecount; i++) + schemdata[i].param1 >>= 1; + } + + return true; +} + + +bool Schematic::serializeToMts(std::ostream *os) const +{ + // Nodes must not be resolved (-> condensed) + // checking here is not possible because "schemdata" might be temporary. + + std::ostream &ss = *os; + + writeU32(ss, MTSCHEM_FILE_SIGNATURE); // signature + writeU16(ss, MTSCHEM_FILE_VER_HIGHEST_WRITE); // version + writeV3S16(ss, size); // schematic size + + for (int y = 0; y != size.Y; y++) // Y slice probabilities + writeU8(ss, slice_probs[y]); + + writeU16(ss, m_nodenames.size()); // name count + for (size_t i = 0; i != m_nodenames.size(); i++) { + ss << serializeString16(m_nodenames[i]); // node names + } + + // compressed bulk node data + SharedBuffer<u8> buf = MapNode::serializeBulk(MTSCHEM_MAPNODE_SER_FMT_VER, + schemdata, size.X * size.Y * size.Z, 2, 2); + compress(buf, ss, MTSCHEM_MAPNODE_SER_FMT_VER); + + return true; +} + + +bool Schematic::serializeToLua(std::ostream *os, bool use_comments, + u32 indent_spaces) const +{ + std::ostream &ss = *os; + + std::string indent("\t"); + if (indent_spaces > 0) + indent.assign(indent_spaces, ' '); + + bool resolve_done = isResolveDone(); + FATAL_ERROR_IF(resolve_done && !m_ndef, "serializeToLua: NodeDefManager is required"); + + //// Write header + { + ss << "schematic = {" << std::endl; + ss << indent << "size = " + << "{x=" << size.X + << ", y=" << size.Y + << ", z=" << size.Z + << "}," << std::endl; + } + + //// Write y-slice probabilities + { + ss << indent << "yslice_prob = {" << std::endl; + + for (u16 y = 0; y != size.Y; y++) { + u8 probability = slice_probs[y] & MTSCHEM_PROB_MASK; + + ss << indent << indent << "{" + << "ypos=" << y + << ", prob=" << (u16)probability * 2 + << "}," << std::endl; + } + + ss << indent << "}," << std::endl; + } + + //// Write node data + { + ss << indent << "data = {" << std::endl; + + u32 i = 0; + for (u16 z = 0; z != size.Z; z++) + for (u16 y = 0; y != size.Y; y++) { + if (use_comments) { + ss << std::endl + << indent << indent + << "-- z=" << z + << ", y=" << y << std::endl; + } + + for (u16 x = 0; x != size.X; x++, i++) { + u8 probability = schemdata[i].param1 & MTSCHEM_PROB_MASK; + bool force_place = schemdata[i].param1 & MTSCHEM_FORCE_PLACE; + + // After node resolving: real content_t, lookup using NodeDefManager + // Prior node resolving: condensed ID, lookup using m_nodenames + content_t c = schemdata[i].getContent(); + + ss << indent << indent << "{" << "name=\""; + + if (!resolve_done) { + // Prior node resolving (eg. direct schematic load) + FATAL_ERROR_IF(c >= m_nodenames.size(), "Invalid node list"); + ss << m_nodenames[c]; + } else { + // After node resolving (eg. biome decoration) + ss << m_ndef->get(c).name; + } + + ss << "\", prob=" << (u16)probability * 2 + << ", param2=" << (u16)schemdata[i].param2; + + if (force_place) + ss << ", force_place=true"; + + ss << "}," << std::endl; + } + } + + ss << indent << "}," << std::endl; + } + + ss << "}" << std::endl; + + return true; +} + + +bool Schematic::loadSchematicFromFile(const std::string &filename, + const NodeDefManager *ndef, StringMap *replace_names) +{ + std::ifstream is(filename.c_str(), std::ios_base::binary); + if (!is.good()) { + errorstream << __FUNCTION__ << ": unable to open file '" + << filename << "'" << std::endl; + return false; + } + + if (!m_ndef) + m_ndef = ndef; + + if (!deserializeFromMts(&is)) + return false; + + name = filename; + + if (replace_names) { + for (std::string &node_name : m_nodenames) { + StringMap::iterator it = replace_names->find(node_name); + if (it != replace_names->end()) + node_name = it->second; + } + } + + if (m_ndef) + m_ndef->pendNodeResolve(this); + + return true; +} + + +bool Schematic::saveSchematicToFile(const std::string &filename, + const NodeDefManager *ndef) +{ + Schematic *schem = this; + + bool needs_condense = isResolveDone(); + + if (!m_ndef) + m_ndef = ndef; + + if (needs_condense) { + if (!m_ndef) + return false; + + schem = (Schematic *)this->clone(); + schem->condenseContentIds(); + } + + std::ostringstream os(std::ios_base::binary); + bool status = schem->serializeToMts(&os); + + if (needs_condense) + delete schem; + + if (!status) + return false; + + return fs::safeWriteToFile(filename, os.str()); +} + + +bool Schematic::getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2) +{ + MMVManip *vm = new MMVManip(map); + + v3s16 bp1 = getNodeBlockPos(p1); + v3s16 bp2 = getNodeBlockPos(p2); + vm->initialEmerge(bp1, bp2); + + size = p2 - p1 + 1; + + slice_probs = new u8[size.Y]; + for (s16 y = 0; y != size.Y; y++) + slice_probs[y] = MTSCHEM_PROB_ALWAYS; + + schemdata = new MapNode[size.X * size.Y * size.Z]; + + u32 i = 0; + for (s16 z = p1.Z; z <= p2.Z; z++) + for (s16 y = p1.Y; y <= p2.Y; y++) { + u32 vi = vm->m_area.index(p1.X, y, z); + for (s16 x = p1.X; x <= p2.X; x++, i++, vi++) { + schemdata[i] = vm->m_data[vi]; + schemdata[i].param1 = MTSCHEM_PROB_ALWAYS; + } + } + + delete vm; + + // Reset and mark as complete + NodeResolver::reset(true); + + return true; +} + + +void Schematic::applyProbabilities(v3s16 p0, + std::vector<std::pair<v3s16, u8> > *plist, + std::vector<std::pair<s16, u8> > *splist) +{ + for (size_t i = 0; i != plist->size(); i++) { + v3s16 p = (*plist)[i].first - p0; + int index = p.Z * (size.Y * size.X) + p.Y * size.X + p.X; + if (index < size.Z * size.Y * size.X) { + u8 prob = (*plist)[i].second; + schemdata[index].param1 = prob; + + // trim unnecessary node names from schematic + if (prob == MTSCHEM_PROB_NEVER) + schemdata[index].setContent(CONTENT_AIR); + } + } + + for (size_t i = 0; i != splist->size(); i++) { + s16 slice = (*splist)[i].first; + if (slice < size.Y) + slice_probs[slice] = (*splist)[i].second; + } +} + + +void Schematic::condenseContentIds() +{ + std::unordered_map<content_t, content_t> nodeidmap; + content_t numids = 0; + + // Reset node resolve fields + NodeResolver::reset(); + + size_t nodecount = size.X * size.Y * size.Z; + for (size_t i = 0; i != nodecount; i++) { + content_t id; + content_t c = schemdata[i].getContent(); + + auto it = nodeidmap.find(c); + if (it == nodeidmap.end()) { + id = numids; + numids++; + + m_nodenames.push_back(m_ndef->get(c).name); + nodeidmap.emplace(std::make_pair(c, id)); + } else { + id = it->second; + } + schemdata[i].setContent(id); + } +} diff --git a/src/mapgen/mg_schematic.h b/src/mapgen/mg_schematic.h new file mode 100644 index 0000000..9189bb3 --- /dev/null +++ b/src/mapgen/mg_schematic.h @@ -0,0 +1,156 @@ +/* +Minetest +Copyright (C) 2014-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net> +Copyright (C) 2015-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <map> +#include "mg_decoration.h" +#include "util/string.h" + +class Map; +class ServerMap; +class Mapgen; +class MMVManip; +class PseudoRandom; +class NodeResolver; +class Server; + +/* + Minetest Schematic File Format + + All values are stored in big-endian byte order. + [u32] signature: 'MTSM' + [u16] version: 4 + [u16] size X + [u16] size Y + [u16] size Z + For each Y: + [u8] slice probability value + [Name-ID table] Name ID Mapping Table + [u16] name-id count + For each name-id mapping: + [u16] name length + [u8[]] name + ZLib deflated { + For each node in schematic: (for z, y, x) + [u16] content + For each node in schematic: + [u8] param1 + bit 0-6: probability + bit 7: specific node force placement + For each node in schematic: + [u8] param2 + } + + Version changes: + 1 - Initial version + 2 - Fixed messy never/always place; 0 probability is now never, 0xFF is always + 3 - Added y-slice probabilities; this allows for variable height structures + 4 - Compressed range of node occurence prob., added per-node force placement bit +*/ + +//// Schematic constants +#define MTSCHEM_FILE_SIGNATURE 0x4d54534d // 'MTSM' +#define MTSCHEM_FILE_VER_HIGHEST_READ 4 +#define MTSCHEM_FILE_VER_HIGHEST_WRITE 4 +#define MTSCHEM_MAPNODE_SER_FMT_VER 28 // Fixed serialization version for schematics since these still need to use Zlib + +#define MTSCHEM_PROB_MASK 0x7F + +#define MTSCHEM_PROB_NEVER 0x00 +#define MTSCHEM_PROB_ALWAYS 0x7F +#define MTSCHEM_PROB_ALWAYS_OLD 0xFF + +#define MTSCHEM_FORCE_PLACE 0x80 + +enum SchematicType +{ + SCHEMATIC_NORMAL, +}; + +enum SchematicFormatType { + SCHEM_FMT_HANDLE, + SCHEM_FMT_MTS, + SCHEM_FMT_LUA, +}; + +class Schematic : public ObjDef, public NodeResolver { +public: + Schematic() = default; + virtual ~Schematic(); + + ObjDef *clone() const; + + virtual void resolveNodeNames(); + + bool loadSchematicFromFile(const std::string &filename, + const NodeDefManager *ndef, StringMap *replace_names = NULL); + bool saveSchematicToFile(const std::string &filename, + const NodeDefManager *ndef); + bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2); + + bool deserializeFromMts(std::istream *is); + bool serializeToMts(std::ostream *os) const; + bool serializeToLua(std::ostream *os, bool use_comments, u32 indent_spaces) const; + + void blitToVManip(MMVManip *vm, v3s16 p, Rotation rot, bool force_place); + bool placeOnVManip(MMVManip *vm, v3s16 p, u32 flags, Rotation rot, bool force_place); + void placeOnMap(ServerMap *map, v3s16 p, u32 flags, Rotation rot, bool force_place); + + void applyProbabilities(v3s16 p0, + std::vector<std::pair<v3s16, u8> > *plist, + std::vector<std::pair<s16, u8> > *splist); + + std::vector<content_t> c_nodes; + u32 flags = 0; + v3s16 size; + MapNode *schemdata = nullptr; + u8 *slice_probs = nullptr; + +private: + // Counterpart to the node resolver: Condense content_t to a sequential "m_nodenames" list + void condenseContentIds(); +}; + +class SchematicManager : public ObjDefManager { +public: + SchematicManager(Server *server); + virtual ~SchematicManager() = default; + + SchematicManager *clone() const; + + virtual void clear(); + + const char *getObjectTitle() const + { + return "schematic"; + } + + static Schematic *create(SchematicType type) + { + return new Schematic; + } + +private: + SchematicManager() {}; + + Server *m_server; +}; + diff --git a/src/mapgen/treegen.cpp b/src/mapgen/treegen.cpp new file mode 100644 index 0000000..ec77714 --- /dev/null +++ b/src/mapgen/treegen.cpp @@ -0,0 +1,875 @@ +/* +Minetest +Copyright (C) 2010-2018 celeron55, Perttu Ahola <celeron55@gmail.com>, +Copyright (C) 2012-2018 RealBadAngel, Maciej Kasatkin +Copyright (C) 2015-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "irr_v3d.h" +#include <stack> +#include "util/pointer.h" +#include "util/numeric.h" +#include "map.h" +#include "mapblock.h" +#include "nodedef.h" +#include "treegen.h" +#include "voxelalgorithms.h" + +namespace treegen +{ + +void make_tree(MMVManip &vmanip, v3s16 p0, bool is_apple_tree, + const NodeDefManager *ndef, s32 seed) +{ + /* + NOTE: Tree-placing code is currently duplicated in the engine + and in games that have saplings; both are deprecated but not + replaced yet + */ + MapNode treenode(ndef->getId("mapgen_tree")); + MapNode leavesnode(ndef->getId("mapgen_leaves")); + MapNode applenode(ndef->getId("mapgen_apple")); + if (treenode == CONTENT_IGNORE) + errorstream << "Treegen: Mapgen alias 'mapgen_tree' is invalid!" << std::endl; + if (leavesnode == CONTENT_IGNORE) + errorstream << "Treegen: Mapgen alias 'mapgen_leaves' is invalid!" << std::endl; + if (applenode == CONTENT_IGNORE) + errorstream << "Treegen: Mapgen alias 'mapgen_apple' is invalid!" << std::endl; + + PseudoRandom pr(seed); + s16 trunk_h = pr.range(4, 5); + v3s16 p1 = p0; + for (s16 ii = 0; ii < trunk_h; ii++) { + if (vmanip.m_area.contains(p1)) { + u32 vi = vmanip.m_area.index(p1); + vmanip.m_data[vi] = treenode; + } + p1.Y++; + } + + // p1 is now the last piece of the trunk + p1.Y -= 1; + + VoxelArea leaves_a(v3s16(-2, -1, -2), v3s16(2, 2, 2)); + Buffer<u8> leaves_d(leaves_a.getVolume()); + for (s32 i = 0; i < leaves_a.getVolume(); i++) + leaves_d[i] = 0; + + // Force leaves at near the end of the trunk + s16 d = 1; + for (s16 z = -d; z <= d; z++) + for (s16 y = -d; y <= d; y++) + for (s16 x = -d; x <= d; x++) { + leaves_d[leaves_a.index(v3s16(x, y, z))] = 1; + } + + // Add leaves randomly + for (u32 iii = 0; iii < 7; iii++) { + v3s16 p( + pr.range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X - d), + pr.range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y - d), + pr.range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z - d) + ); + + for (s16 z = 0; z <= d; z++) + for (s16 y = 0; y <= d; y++) + for (s16 x = 0; x <= d; x++) { + leaves_d[leaves_a.index(p + v3s16(x, y, z))] = 1; + } + } + + // Blit leaves to vmanip + for (s16 z = leaves_a.MinEdge.Z; z <= leaves_a.MaxEdge.Z; z++) + for (s16 y = leaves_a.MinEdge.Y; y <= leaves_a.MaxEdge.Y; y++) { + v3s16 pmin(leaves_a.MinEdge.X, y, z); + u32 i = leaves_a.index(pmin); + u32 vi = vmanip.m_area.index(pmin + p1); + for (s16 x = leaves_a.MinEdge.X; x <= leaves_a.MaxEdge.X; x++) { + v3s16 p(x, y, z); + if (vmanip.m_area.contains(p + p1) && + (vmanip.m_data[vi].getContent() == CONTENT_AIR || + vmanip.m_data[vi].getContent() == CONTENT_IGNORE)) { + if (leaves_d[i] == 1) { + bool is_apple = pr.range(0, 99) < 10; + if (is_apple_tree && is_apple) + vmanip.m_data[vi] = applenode; + else + vmanip.m_data[vi] = leavesnode; + } + } + vi++; + i++; + } + } +} + + +// L-System tree LUA spawner +treegen::error spawn_ltree(ServerMap *map, v3s16 p0, + const NodeDefManager *ndef, const TreeDef &tree_definition) +{ + std::map<v3s16, MapBlock*> modified_blocks; + MMVManip vmanip(map); + v3s16 tree_blockp = getNodeBlockPos(p0); + treegen::error e; + + vmanip.initialEmerge(tree_blockp - v3s16(1, 1, 1), tree_blockp + v3s16(1, 3, 1)); + e = make_ltree(vmanip, p0, ndef, tree_definition); + if (e != SUCCESS) + return e; + + voxalgo::blit_back_with_light(map, &vmanip, &modified_blocks); + + // Send a MEET_OTHER event + MapEditEvent event; + event.type = MEET_OTHER; + for (auto &modified_block : modified_blocks) + event.modified_blocks.insert(modified_block.first); + map->dispatchEvent(event); + return SUCCESS; +} + + +//L-System tree generator +treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, + const NodeDefManager *ndef, TreeDef tree_definition) +{ + s32 seed; + if (tree_definition.explicit_seed) + seed = tree_definition.seed + 14002; + else + seed = p0.X * 2 + p0.Y * 4 + p0.Z; // use the tree position to seed PRNG + PseudoRandom ps(seed); + + // chance of inserting abcd rules + double prop_a = 9; + double prop_b = 8; + double prop_c = 7; + double prop_d = 6; + + //randomize tree growth level, minimum=2 + s16 iterations = tree_definition.iterations; + if (tree_definition.iterations_random_level > 0) + iterations -= ps.range(0, tree_definition.iterations_random_level); + if (iterations < 2) + iterations = 2; + + s16 MAX_ANGLE_OFFSET = 5; + double angle_in_radians = (double)tree_definition.angle * M_PI / 180; + double angleOffset_in_radians = (s16)(ps.range(0, 1) % MAX_ANGLE_OFFSET) * M_PI / 180; + + //initialize rotation matrix, position and stacks for branches + core::matrix4 rotation; + rotation = setRotationAxisRadians(rotation, M_PI / 2, v3f(0, 0, 1)); + v3f position; + position.X = p0.X; + position.Y = p0.Y; + position.Z = p0.Z; + std::stack <core::matrix4> stack_orientation; + std::stack <v3f> stack_position; + + //generate axiom + std::string axiom = tree_definition.initial_axiom; + for (s16 i = 0; i < iterations; i++) { + std::string temp; + for (s16 j = 0; j < (s16)axiom.size(); j++) { + char axiom_char = axiom.at(j); + switch (axiom_char) { + case 'A': + temp += tree_definition.rules_a; + break; + case 'B': + temp += tree_definition.rules_b; + break; + case 'C': + temp += tree_definition.rules_c; + break; + case 'D': + temp += tree_definition.rules_d; + break; + case 'a': + if (prop_a >= ps.range(1, 10)) + temp += tree_definition.rules_a; + break; + case 'b': + if (prop_b >= ps.range(1, 10)) + temp += tree_definition.rules_b; + break; + case 'c': + if (prop_c >= ps.range(1, 10)) + temp += tree_definition.rules_c; + break; + case 'd': + if (prop_d >= ps.range(1, 10)) + temp += tree_definition.rules_d; + break; + default: + temp += axiom_char; + break; + } + } + axiom = temp; + } + + // Add trunk nodes below a wide trunk to avoid gaps when tree is on sloping ground + if (tree_definition.trunk_type == "double") { + tree_trunk_placement( + vmanip, + v3f(position.X + 1, position.Y - 1, position.Z), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X, position.Y - 1, position.Z + 1), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X + 1, position.Y - 1, position.Z + 1), + tree_definition + ); + } else if (tree_definition.trunk_type == "crossed") { + tree_trunk_placement( + vmanip, + v3f(position.X + 1, position.Y - 1, position.Z), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X - 1, position.Y - 1, position.Z), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X, position.Y - 1, position.Z + 1), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X, position.Y - 1, position.Z - 1), + tree_definition + ); + } + + /* build tree out of generated axiom + + Key for Special L-System Symbols used in Axioms + + G - move forward one unit with the pen up + F - move forward one unit with the pen down drawing trunks and branches + f - move forward one unit with the pen down drawing leaves (100% chance) + T - move forward one unit with the pen down drawing trunks only + R - move forward one unit with the pen down placing fruit + A - replace with rules set A + B - replace with rules set B + C - replace with rules set C + D - replace with rules set D + a - replace with rules set A, chance 90% + b - replace with rules set B, chance 80% + c - replace with rules set C, chance 70% + d - replace with rules set D, chance 60% + + - yaw the turtle right by angle degrees + - - yaw the turtle left by angle degrees + & - pitch the turtle down by angle degrees + ^ - pitch the turtle up by angle degrees + / - roll the turtle to the right by angle degrees + * - roll the turtle to the left by angle degrees + [ - save in stack current state info + ] - recover from stack state info + + */ + + s16 x,y,z; + for (s16 i = 0; i < (s16)axiom.size(); i++) { + char axiom_char = axiom.at(i); + core::matrix4 temp_rotation; + temp_rotation.makeIdentity(); + v3f dir; + switch (axiom_char) { + case 'G': + dir = v3f(1, 0, 0); + dir = transposeMatrix(rotation, dir); + position += dir; + break; + case 'T': + tree_trunk_placement( + vmanip, + v3f(position.X, position.Y, position.Z), + tree_definition + ); + if (tree_definition.trunk_type == "double" && + !tree_definition.thin_branches) { + tree_trunk_placement( + vmanip, + v3f(position.X + 1, position.Y, position.Z), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X, position.Y, position.Z + 1), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X + 1, position.Y, position.Z + 1), + tree_definition + ); + } else if (tree_definition.trunk_type == "crossed" && + !tree_definition.thin_branches) { + tree_trunk_placement( + vmanip, + v3f(position.X + 1, position.Y, position.Z), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X - 1, position.Y, position.Z), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X, position.Y, position.Z + 1), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X, position.Y, position.Z - 1), + tree_definition + ); + } + dir = v3f(1, 0, 0); + dir = transposeMatrix(rotation, dir); + position += dir; + break; + case 'F': + tree_trunk_placement( + vmanip, + v3f(position.X, position.Y, position.Z), + tree_definition + ); + if ((stack_orientation.empty() && + tree_definition.trunk_type == "double") || + (!stack_orientation.empty() && + tree_definition.trunk_type == "double" && + !tree_definition.thin_branches)) { + tree_trunk_placement( + vmanip, + v3f(position.X + 1, position.Y, position.Z), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X, position.Y, position.Z + 1), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X + 1, position.Y, position.Z + 1), + tree_definition + ); + } else if ((stack_orientation.empty() && + tree_definition.trunk_type == "crossed") || + (!stack_orientation.empty() && + tree_definition.trunk_type == "crossed" && + !tree_definition.thin_branches)) { + tree_trunk_placement( + vmanip, + v3f(position.X + 1, position.Y, position.Z), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X - 1, position.Y, position.Z), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X, position.Y, position.Z + 1), + tree_definition + ); + tree_trunk_placement( + vmanip, + v3f(position.X, position.Y, position.Z - 1), + tree_definition + ); + } + if (!stack_orientation.empty()) { + s16 size = 1; + for (x = -size; x <= size; x++) + for (y = -size; y <= size; y++) + for (z = -size; z <= size; z++) { + if (abs(x) == size && + abs(y) == size && + abs(z) == size) { + tree_leaves_placement( + vmanip, + v3f(position.X + x + 1, position.Y + y, + position.Z + z), + ps.next(), + tree_definition + ); + tree_leaves_placement( + vmanip, + v3f(position.X + x - 1, position.Y + y, + position.Z + z), + ps.next(), + tree_definition + ); + tree_leaves_placement( + vmanip,v3f(position.X + x, position.Y + y, + position.Z + z + 1), + ps.next(), + tree_definition + ); + tree_leaves_placement( + vmanip,v3f(position.X + x, position.Y + y, + position.Z + z - 1), + ps.next(), + tree_definition + ); + } + } + } + dir = v3f(1, 0, 0); + dir = transposeMatrix(rotation, dir); + position += dir; + break; + case 'f': + tree_single_leaves_placement( + vmanip, + v3f(position.X, position.Y, position.Z), + ps.next(), + tree_definition + ); + dir = v3f(1, 0, 0); + dir = transposeMatrix(rotation, dir); + position += dir; + break; + case 'R': + tree_fruit_placement( + vmanip, + v3f(position.X, position.Y, position.Z), + tree_definition + ); + dir = v3f(1, 0, 0); + dir = transposeMatrix(rotation, dir); + position += dir; + break; + + // turtle orientation commands + case '[': + stack_orientation.push(rotation); + stack_position.push(position); + break; + case ']': + if (stack_orientation.empty()) + return UNBALANCED_BRACKETS; + rotation = stack_orientation.top(); + stack_orientation.pop(); + position = stack_position.top(); + stack_position.pop(); + break; + case '+': + temp_rotation.makeIdentity(); + temp_rotation = setRotationAxisRadians(temp_rotation, + angle_in_radians + angleOffset_in_radians, v3f(0, 0, 1)); + rotation *= temp_rotation; + break; + case '-': + temp_rotation.makeIdentity(); + temp_rotation = setRotationAxisRadians(temp_rotation, + angle_in_radians + angleOffset_in_radians, v3f(0, 0, -1)); + rotation *= temp_rotation; + break; + case '&': + temp_rotation.makeIdentity(); + temp_rotation = setRotationAxisRadians(temp_rotation, + angle_in_radians + angleOffset_in_radians, v3f(0, 1, 0)); + rotation *= temp_rotation; + break; + case '^': + temp_rotation.makeIdentity(); + temp_rotation = setRotationAxisRadians(temp_rotation, + angle_in_radians + angleOffset_in_radians, v3f(0, -1, 0)); + rotation *= temp_rotation; + break; + case '*': + temp_rotation.makeIdentity(); + temp_rotation = setRotationAxisRadians(temp_rotation, + angle_in_radians, v3f(1, 0, 0)); + rotation *= temp_rotation; + break; + case '/': + temp_rotation.makeIdentity(); + temp_rotation = setRotationAxisRadians(temp_rotation, + angle_in_radians, v3f(-1, 0, 0)); + rotation *= temp_rotation; + break; + default: + break; + } + } + + return SUCCESS; +} + + +void tree_trunk_placement(MMVManip &vmanip, v3f p0, TreeDef &tree_definition) +{ + v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z)); + if (!vmanip.m_area.contains(p1)) + return; + u32 vi = vmanip.m_area.index(p1); + content_t current_node = vmanip.m_data[vi].getContent(); + if (current_node != CONTENT_AIR && current_node != CONTENT_IGNORE + && current_node != tree_definition.leavesnode.getContent() + && current_node != tree_definition.leaves2node.getContent() + && current_node != tree_definition.fruitnode.getContent()) + return; + vmanip.m_data[vi] = tree_definition.trunknode; +} + + +void tree_leaves_placement(MMVManip &vmanip, v3f p0, + PseudoRandom ps, TreeDef &tree_definition) +{ + MapNode leavesnode = tree_definition.leavesnode; + if (ps.range(1, 100) > 100 - tree_definition.leaves2_chance) + leavesnode = tree_definition.leaves2node; + v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z)); + if (!vmanip.m_area.contains(p1)) + return; + u32 vi = vmanip.m_area.index(p1); + if (vmanip.m_data[vi].getContent() != CONTENT_AIR + && vmanip.m_data[vi].getContent() != CONTENT_IGNORE) + return; + if (tree_definition.fruit_chance > 0) { + if (ps.range(1, 100) > 100 - tree_definition.fruit_chance) + vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.fruitnode; + else + vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode; + } else if (ps.range(1, 100) > 20) { + vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode; + } +} + + +void tree_single_leaves_placement(MMVManip &vmanip, v3f p0, + PseudoRandom ps, TreeDef &tree_definition) +{ + MapNode leavesnode = tree_definition.leavesnode; + if (ps.range(1, 100) > 100 - tree_definition.leaves2_chance) + leavesnode = tree_definition.leaves2node; + v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z)); + if (!vmanip.m_area.contains(p1)) + return; + u32 vi = vmanip.m_area.index(p1); + if (vmanip.m_data[vi].getContent() != CONTENT_AIR + && vmanip.m_data[vi].getContent() != CONTENT_IGNORE) + return; + vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode; +} + + +void tree_fruit_placement(MMVManip &vmanip, v3f p0, TreeDef &tree_definition) +{ + v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z)); + if (!vmanip.m_area.contains(p1)) + return; + u32 vi = vmanip.m_area.index(p1); + if (vmanip.m_data[vi].getContent() != CONTENT_AIR + && vmanip.m_data[vi].getContent() != CONTENT_IGNORE) + return; + vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.fruitnode; +} + + +irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle, v3f axis) +{ + double c = cos(angle); + double s = sin(angle); + double t = 1.0 - c; + + double tx = t * axis.X; + double ty = t * axis.Y; + double tz = t * axis.Z; + double sx = s * axis.X; + double sy = s * axis.Y; + double sz = s * axis.Z; + + M[0] = tx * axis.X + c; + M[1] = tx * axis.Y + sz; + M[2] = tx * axis.Z - sy; + + M[4] = ty * axis.X - sz; + M[5] = ty * axis.Y + c; + M[6] = ty * axis.Z + sx; + + M[8] = tz * axis.X + sy; + M[9] = tz * axis.Y - sx; + M[10] = tz * axis.Z + c; + return M; +} + + +v3f transposeMatrix(irr::core::matrix4 M, v3f v) +{ + v3f translated; + double x = M[0] * v.X + M[4] * v.Y + M[8] * v.Z +M[12]; + double y = M[1] * v.X + M[5] * v.Y + M[9] * v.Z +M[13]; + double z = M[2] * v.X + M[6] * v.Y + M[10] * v.Z +M[14]; + translated.X = x; + translated.Y = y; + translated.Z = z; + return translated; +} + + +void make_jungletree(MMVManip &vmanip, v3s16 p0, const NodeDefManager *ndef, + s32 seed) +{ + /* + NOTE: Tree-placing code is currently duplicated in the engine + and in games that have saplings; both are deprecated but not + replaced yet + */ + content_t c_tree = ndef->getId("mapgen_jungletree"); + content_t c_leaves = ndef->getId("mapgen_jungleleaves"); + if (c_tree == CONTENT_IGNORE) + c_tree = ndef->getId("mapgen_tree"); + if (c_leaves == CONTENT_IGNORE) + c_leaves = ndef->getId("mapgen_leaves"); + if (c_tree == CONTENT_IGNORE) + errorstream << "Treegen: Mapgen alias 'mapgen_jungletree' is invalid!" << std::endl; + if (c_leaves == CONTENT_IGNORE) + errorstream << "Treegen: Mapgen alias 'mapgen_jungleleaves' is invalid!" << std::endl; + + MapNode treenode(c_tree); + MapNode leavesnode(c_leaves); + + PseudoRandom pr(seed); + for (s16 x= -1; x <= 1; x++) + for (s16 z= -1; z <= 1; z++) { + if (pr.range(0, 2) == 0) + continue; + v3s16 p1 = p0 + v3s16(x, 0, z); + v3s16 p2 = p0 + v3s16(x, -1, z); + u32 vi1 = vmanip.m_area.index(p1); + u32 vi2 = vmanip.m_area.index(p2); + + if (vmanip.m_area.contains(p2) && + vmanip.m_data[vi2].getContent() == CONTENT_AIR) + vmanip.m_data[vi2] = treenode; + else if (vmanip.m_area.contains(p1) && + vmanip.m_data[vi1].getContent() == CONTENT_AIR) + vmanip.m_data[vi1] = treenode; + } + vmanip.m_data[vmanip.m_area.index(p0)] = treenode; + + s16 trunk_h = pr.range(8, 12); + v3s16 p1 = p0; + for (s16 ii = 0; ii < trunk_h; ii++) { + if (vmanip.m_area.contains(p1)) { + u32 vi = vmanip.m_area.index(p1); + vmanip.m_data[vi] = treenode; + } + p1.Y++; + } + + // p1 is now the last piece of the trunk + p1.Y -= 1; + + VoxelArea leaves_a(v3s16(-3, -2, -3), v3s16(3, 2, 3)); + //SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]); + Buffer<u8> leaves_d(leaves_a.getVolume()); + for (s32 i = 0; i < leaves_a.getVolume(); i++) + leaves_d[i] = 0; + + // Force leaves at near the end of the trunk + s16 d = 1; + for (s16 z = -d; z <= d; z++) + for (s16 y = -d; y <= d; y++) + for (s16 x = -d; x <= d; x++) { + leaves_d[leaves_a.index(v3s16(x,y,z))] = 1; + } + + // Add leaves randomly + for (u32 iii = 0; iii < 30; iii++) { + v3s16 p( + pr.range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X - d), + pr.range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y - d), + pr.range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z - d) + ); + + for (s16 z = 0; z <= d; z++) + for (s16 y = 0; y <= d; y++) + for (s16 x = 0; x <= d; x++) { + leaves_d[leaves_a.index(p + v3s16(x, y, z))] = 1; + } + } + + // Blit leaves to vmanip + for (s16 z = leaves_a.MinEdge.Z; z <= leaves_a.MaxEdge.Z; z++) + for (s16 y = leaves_a.MinEdge.Y; y <= leaves_a.MaxEdge.Y; y++) { + v3s16 pmin(leaves_a.MinEdge.X, y, z); + u32 i = leaves_a.index(pmin); + u32 vi = vmanip.m_area.index(pmin + p1); + for (s16 x = leaves_a.MinEdge.X; x <= leaves_a.MaxEdge.X; x++) { + v3s16 p(x, y, z); + if (vmanip.m_area.contains(p + p1) && + (vmanip.m_data[vi].getContent() == CONTENT_AIR || + vmanip.m_data[vi].getContent() == CONTENT_IGNORE)) { + if (leaves_d[i] == 1) + vmanip.m_data[vi] = leavesnode; + } + vi++; + i++; + } + } +} + + +void make_pine_tree(MMVManip &vmanip, v3s16 p0, const NodeDefManager *ndef, + s32 seed) +{ + /* + NOTE: Tree-placing code is currently duplicated in the engine + and in games that have saplings; both are deprecated but not + replaced yet + */ + content_t c_tree = ndef->getId("mapgen_pine_tree"); + content_t c_leaves = ndef->getId("mapgen_pine_needles"); + content_t c_snow = ndef->getId("mapgen_snow"); + if (c_tree == CONTENT_IGNORE) + c_tree = ndef->getId("mapgen_tree"); + if (c_leaves == CONTENT_IGNORE) + c_leaves = ndef->getId("mapgen_leaves"); + if (c_snow == CONTENT_IGNORE) + c_snow = CONTENT_AIR; + if (c_tree == CONTENT_IGNORE) + errorstream << "Treegen: Mapgen alias 'mapgen_pine_tree' is invalid!" << std::endl; + if (c_leaves == CONTENT_IGNORE) + errorstream << "Treegen: Mapgen alias 'mapgen_pine_needles' is invalid!" << std::endl; + + MapNode treenode(c_tree); + MapNode leavesnode(c_leaves); + MapNode snownode(c_snow); + + PseudoRandom pr(seed); + u16 trunk_h = pr.range(9, 13); + v3s16 p1 = p0; + for (u16 ii = 0; ii < trunk_h; ii++) { + if (vmanip.m_area.contains(p1)) { + u32 vi = vmanip.m_area.index(p1); + vmanip.m_data[vi] = treenode; + } + p1.Y++; + } + + // Make p1 the top node of the trunk + p1.Y -= 1; + + VoxelArea leaves_a(v3s16(-3, -6, -3), v3s16(3, 3, 3)); + Buffer<u8> leaves_d(leaves_a.getVolume()); + for (s32 i = 0; i < leaves_a.getVolume(); i++) + leaves_d[i] = 0; + + // Upper branches + u16 dev = 3; + for (s16 yy = -1; yy <= 1; yy++) { + for (s16 zz = -dev; zz <= dev; zz++) { + u32 i = leaves_a.index(v3s16(-dev, yy, zz)); + u32 ia = leaves_a.index(v3s16(-dev, yy+1, zz)); + for (s16 xx = -dev; xx <= dev; xx++) { + if (pr.range(0, 20) <= 19 - dev) { + leaves_d[i] = 1; + leaves_d[ia] = 2; + } + i++; + ia++; + } + } + dev--; + } + + // Centre top nodes + leaves_d[leaves_a.index(v3s16(0, 1, 0))] = 1; + leaves_d[leaves_a.index(v3s16(0, 2, 0))] = 1; + leaves_d[leaves_a.index(v3s16(0, 3, 0))] = 2; + + // Lower branches + s16 my = -6; + for (u32 iii = 0; iii < 20; iii++) { + s16 xi = pr.range(-3, 2); + s16 yy = pr.range(-6, -5); + s16 zi = pr.range(-3, 2); + if (yy > my) + my = yy; + for (s16 zz = zi; zz <= zi + 1; zz++) { + u32 i = leaves_a.index(v3s16(xi, yy, zz)); + u32 ia = leaves_a.index(v3s16(xi, yy + 1, zz)); + for (s32 xx = xi; xx <= xi + 1; xx++) { + leaves_d[i] = 1; + if (leaves_d[ia] == 0) + leaves_d[ia] = 2; + i++; + ia++; + } + } + } + + dev = 2; + for (s16 yy = my + 1; yy <= my + 2; yy++) { + for (s16 zz = -dev; zz <= dev; zz++) { + u32 i = leaves_a.index(v3s16(-dev, yy, zz)); + u32 ia = leaves_a.index(v3s16(-dev, yy + 1, zz)); + for (s16 xx = -dev; xx <= dev; xx++) { + if (pr.range(0, 20) <= 19 - dev) { + leaves_d[i] = 1; + leaves_d[ia] = 2; + } + i++; + ia++; + } + } + dev--; + } + + // Blit leaves to vmanip + for (s16 z = leaves_a.MinEdge.Z; z <= leaves_a.MaxEdge.Z; z++) + for (s16 y = leaves_a.MinEdge.Y; y <= leaves_a.MaxEdge.Y; y++) { + v3s16 pmin(leaves_a.MinEdge.X, y, z); + u32 i = leaves_a.index(pmin); + u32 vi = vmanip.m_area.index(pmin + p1); + for (s16 x = leaves_a.MinEdge.X; x <= leaves_a.MaxEdge.X; x++) { + v3s16 p(x, y, z); + if (vmanip.m_area.contains(p + p1) && + (vmanip.m_data[vi].getContent() == CONTENT_AIR || + vmanip.m_data[vi].getContent() == CONTENT_IGNORE || + vmanip.m_data[vi] == snownode)) { + if (leaves_d[i] == 1) + vmanip.m_data[vi] = leavesnode; + else if (leaves_d[i] == 2) + vmanip.m_data[vi] = snownode; + } + vi++; + i++; + } + } +} + +}; // namespace treegen diff --git a/src/mapgen/treegen.h b/src/mapgen/treegen.h new file mode 100644 index 0000000..59a4188 --- /dev/null +++ b/src/mapgen/treegen.h @@ -0,0 +1,91 @@ +/* +Minetest +Copyright (C) 2010-2018 celeron55, Perttu Ahola <celeron55@gmail.com>, +Copyright (C) 2012-2018 RealBadAngel, Maciej Kasatkin +Copyright (C) 2015-2018 paramat + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <matrix4.h> +#include "noise.h" + +class MMVManip; +class NodeDefManager; +class ServerMap; + +namespace treegen { + + enum error { + SUCCESS, + UNBALANCED_BRACKETS + }; + + struct TreeDef { + std::string initial_axiom; + std::string rules_a; + std::string rules_b; + std::string rules_c; + std::string rules_d; + + MapNode trunknode; + MapNode leavesnode; + MapNode leaves2node; + + int leaves2_chance; + int angle; + int iterations; + int iterations_random_level; + std::string trunk_type; + bool thin_branches; + MapNode fruitnode; + int fruit_chance; + s32 seed; + bool explicit_seed; + }; + + // Add default tree + void make_tree(MMVManip &vmanip, v3s16 p0, + bool is_apple_tree, const NodeDefManager *ndef, s32 seed); + // Add jungle tree + void make_jungletree(MMVManip &vmanip, v3s16 p0, + const NodeDefManager *ndef, s32 seed); + // Add pine tree + void make_pine_tree(MMVManip &vmanip, v3s16 p0, + const NodeDefManager *ndef, s32 seed); + + // Add L-Systems tree (used by engine) + treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, + const NodeDefManager *ndef, TreeDef tree_definition); + // Spawn L-systems tree from LUA + treegen::error spawn_ltree (ServerMap *map, v3s16 p0, + const NodeDefManager *ndef, const TreeDef &tree_definition); + + // L-System tree gen helper functions + void tree_trunk_placement(MMVManip &vmanip, v3f p0, + TreeDef &tree_definition); + void tree_leaves_placement(MMVManip &vmanip, v3f p0, + PseudoRandom ps, TreeDef &tree_definition); + void tree_single_leaves_placement(MMVManip &vmanip, v3f p0, + PseudoRandom ps, TreeDef &tree_definition); + void tree_fruit_placement(MMVManip &vmanip, v3f p0, + TreeDef &tree_definition); + irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle, v3f axis); + + v3f transposeMatrix(irr::core::matrix4 M ,v3f v); + +}; // namespace treegen diff --git a/src/mapnode.cpp b/src/mapnode.cpp new file mode 100644 index 0000000..42f020e --- /dev/null +++ b/src/mapnode.cpp @@ -0,0 +1,863 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "irrlichttypes_extrabloated.h" +#include "mapnode.h" +#include "porting.h" +#include "nodedef.h" +#include "map.h" +#include "content_mapnode.h" // For mapnode_translate_*_internal +#include "serialization.h" // For ser_ver_supported +#include "util/serialize.h" +#include "log.h" +#include "util/directiontables.h" +#include "util/numeric.h" +#include <string> +#include <sstream> + +static const Rotation wallmounted_to_rot[] = { + ROTATE_0, ROTATE_180, ROTATE_90, ROTATE_270 +}; + +static const u8 rot_to_wallmounted[] = { + 2, 4, 3, 5 +}; + + +/* + MapNode +*/ + +void MapNode::getColor(const ContentFeatures &f, video::SColor *color) const +{ + if (f.palette) { + *color = (*f.palette)[param2]; + return; + } + *color = f.color; +} + +void MapNode::setLight(LightBank bank, u8 a_light, const ContentFeatures &f) noexcept +{ + // If node doesn't contain light data, ignore this + if(f.param_type != CPT_LIGHT) + return; + if(bank == LIGHTBANK_DAY) + { + param1 &= 0xf0; + param1 |= a_light & 0x0f; + } + else if(bank == LIGHTBANK_NIGHT) + { + param1 &= 0x0f; + param1 |= (a_light & 0x0f)<<4; + } + else + assert("Invalid light bank" == NULL); +} + +void MapNode::setLight(LightBank bank, u8 a_light, const NodeDefManager *nodemgr) +{ + setLight(bank, a_light, nodemgr->get(*this)); +} + +bool MapNode::isLightDayNightEq(const NodeDefManager *nodemgr) const +{ + const ContentFeatures &f = nodemgr->get(*this); + bool isEqual; + + if (f.param_type == CPT_LIGHT) { + u8 day = MYMAX(f.light_source, param1 & 0x0f); + u8 night = MYMAX(f.light_source, (param1 >> 4) & 0x0f); + isEqual = day == night; + } else { + isEqual = true; + } + + return isEqual; +} + +u8 MapNode::getLight(LightBank bank, const NodeDefManager *nodemgr) const +{ + // Select the brightest of [light source, propagated light] + const ContentFeatures &f = nodemgr->get(*this); + + u8 light; + if(f.param_type == CPT_LIGHT) + light = bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f; + else + light = 0; + + return MYMAX(f.light_source, light); +} + +u8 MapNode::getLightRaw(LightBank bank, const ContentFeatures &f) const noexcept +{ + if(f.param_type == CPT_LIGHT) + return bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f; + return 0; +} + +u8 MapNode::getLightNoChecks(LightBank bank, const ContentFeatures *f) const noexcept +{ + return MYMAX(f->light_source, + bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f); +} + +bool MapNode::getLightBanks(u8 &lightday, u8 &lightnight, + const NodeDefManager *nodemgr) const +{ + // Select the brightest of [light source, propagated light] + const ContentFeatures &f = nodemgr->get(*this); + if(f.param_type == CPT_LIGHT) + { + lightday = param1 & 0x0f; + lightnight = (param1>>4)&0x0f; + } + else + { + lightday = 0; + lightnight = 0; + } + if(f.light_source > lightday) + lightday = f.light_source; + if(f.light_source > lightnight) + lightnight = f.light_source; + return f.param_type == CPT_LIGHT || f.light_source != 0; +} + +u8 MapNode::getFaceDir(const NodeDefManager *nodemgr, + bool allow_wallmounted) const +{ + const ContentFeatures &f = nodemgr->get(*this); + if (f.param_type_2 == CPT2_FACEDIR || + f.param_type_2 == CPT2_COLORED_FACEDIR) + return (getParam2() & 0x1F) % 24; + if (allow_wallmounted && (f.param_type_2 == CPT2_WALLMOUNTED || + f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) + return wallmounted_to_facedir[getParam2() & 0x07]; + return 0; +} + +u8 MapNode::getWallMounted(const NodeDefManager *nodemgr) const +{ + const ContentFeatures &f = nodemgr->get(*this); + if (f.param_type_2 == CPT2_WALLMOUNTED || + f.param_type_2 == CPT2_COLORED_WALLMOUNTED) { + return getParam2() & 0x07; + } else if (f.drawtype == NDT_SIGNLIKE || f.drawtype == NDT_TORCHLIKE || + f.drawtype == NDT_PLANTLIKE || + f.drawtype == NDT_PLANTLIKE_ROOTED) { + return 1; + } + return 0; +} + +v3s16 MapNode::getWallMountedDir(const NodeDefManager *nodemgr) const +{ + switch(getWallMounted(nodemgr)) + { + case 0: default: return v3s16(0,1,0); + case 1: return v3s16(0,-1,0); + case 2: return v3s16(1,0,0); + case 3: return v3s16(-1,0,0); + case 4: return v3s16(0,0,1); + case 5: return v3s16(0,0,-1); + } +} + +u8 MapNode::getDegRotate(const NodeDefManager *nodemgr) const +{ + const ContentFeatures &f = nodemgr->get(*this); + if (f.param_type_2 == CPT2_DEGROTATE) + return getParam2() % 240; + if (f.param_type_2 == CPT2_COLORED_DEGROTATE) + return 10 * ((getParam2() & 0x1F) % 24); + return 0; +} + +void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot) +{ + ContentParamType2 cpt2 = nodemgr->get(*this).param_type_2; + + if (cpt2 == CPT2_FACEDIR || cpt2 == CPT2_COLORED_FACEDIR) { + static const u8 rotate_facedir[24 * 4] = { + // Table value = rotated facedir + // Columns: 0, 90, 180, 270 degrees rotation around vertical axis + // Rotation is anticlockwise as seen from above (+Y) + + 0, 1, 2, 3, // Initial facedir 0 to 3 + 1, 2, 3, 0, + 2, 3, 0, 1, + 3, 0, 1, 2, + + 4, 13, 10, 19, // 4 to 7 + 5, 14, 11, 16, + 6, 15, 8, 17, + 7, 12, 9, 18, + + 8, 17, 6, 15, // 8 to 11 + 9, 18, 7, 12, + 10, 19, 4, 13, + 11, 16, 5, 14, + + 12, 9, 18, 7, // 12 to 15 + 13, 10, 19, 4, + 14, 11, 16, 5, + 15, 8, 17, 6, + + 16, 5, 14, 11, // 16 to 19 + 17, 6, 15, 8, + 18, 7, 12, 9, + 19, 4, 13, 10, + + 20, 23, 22, 21, // 20 to 23 + 21, 20, 23, 22, + 22, 21, 20, 23, + 23, 22, 21, 20 + }; + u8 facedir = (param2 & 31) % 24; + u8 index = facedir * 4 + rot; + param2 &= ~31; + param2 |= rotate_facedir[index]; + } else if (cpt2 == CPT2_WALLMOUNTED || + cpt2 == CPT2_COLORED_WALLMOUNTED) { + u8 wmountface = (param2 & 7); + if (wmountface <= 1) + return; + + Rotation oldrot = wallmounted_to_rot[wmountface - 2]; + param2 &= ~7; + param2 |= rot_to_wallmounted[(oldrot - rot) & 3]; + } else if (cpt2 == CPT2_DEGROTATE) { + int angle = param2; // in 1.5° + angle += 60 * rot; // don’t do that on u8 + angle %= 240; + param2 = angle; + } else if (cpt2 == CPT2_COLORED_DEGROTATE) { + int angle = param2 & 0x1F; // in 15° + int color = param2 & 0xE0; + angle += 6 * rot; + angle %= 24; + param2 = color | angle; + } +} + +void transformNodeBox(const MapNode &n, const NodeBox &nodebox, + const NodeDefManager *nodemgr, std::vector<aabb3f> *p_boxes, + u8 neighbors = 0) +{ + std::vector<aabb3f> &boxes = *p_boxes; + + if (nodebox.type == NODEBOX_FIXED || nodebox.type == NODEBOX_LEVELED) { + const auto &fixed = nodebox.fixed; + int facedir = n.getFaceDir(nodemgr, true); + u8 axisdir = facedir>>2; + facedir&=0x03; + + boxes.reserve(boxes.size() + fixed.size()); + for (aabb3f box : fixed) { + if (nodebox.type == NODEBOX_LEVELED) + box.MaxEdge.Y = (-0.5f + n.getLevel(nodemgr) / 64.0f) * BS; + + switch (axisdir) { + case 0: + if(facedir == 1) + { + box.MinEdge.rotateXZBy(-90); + box.MaxEdge.rotateXZBy(-90); + } + else if(facedir == 2) + { + box.MinEdge.rotateXZBy(180); + box.MaxEdge.rotateXZBy(180); + } + else if(facedir == 3) + { + box.MinEdge.rotateXZBy(90); + box.MaxEdge.rotateXZBy(90); + } + break; + case 1: // z+ + box.MinEdge.rotateYZBy(90); + box.MaxEdge.rotateYZBy(90); + if(facedir == 1) + { + box.MinEdge.rotateXYBy(90); + box.MaxEdge.rotateXYBy(90); + } + else if(facedir == 2) + { + box.MinEdge.rotateXYBy(180); + box.MaxEdge.rotateXYBy(180); + } + else if(facedir == 3) + { + box.MinEdge.rotateXYBy(-90); + box.MaxEdge.rotateXYBy(-90); + } + break; + case 2: //z- + box.MinEdge.rotateYZBy(-90); + box.MaxEdge.rotateYZBy(-90); + if(facedir == 1) + { + box.MinEdge.rotateXYBy(-90); + box.MaxEdge.rotateXYBy(-90); + } + else if(facedir == 2) + { + box.MinEdge.rotateXYBy(180); + box.MaxEdge.rotateXYBy(180); + } + else if(facedir == 3) + { + box.MinEdge.rotateXYBy(90); + box.MaxEdge.rotateXYBy(90); + } + break; + case 3: //x+ + box.MinEdge.rotateXYBy(-90); + box.MaxEdge.rotateXYBy(-90); + if(facedir == 1) + { + box.MinEdge.rotateYZBy(90); + box.MaxEdge.rotateYZBy(90); + } + else if(facedir == 2) + { + box.MinEdge.rotateYZBy(180); + box.MaxEdge.rotateYZBy(180); + } + else if(facedir == 3) + { + box.MinEdge.rotateYZBy(-90); + box.MaxEdge.rotateYZBy(-90); + } + break; + case 4: //x- + box.MinEdge.rotateXYBy(90); + box.MaxEdge.rotateXYBy(90); + if(facedir == 1) + { + box.MinEdge.rotateYZBy(-90); + box.MaxEdge.rotateYZBy(-90); + } + else if(facedir == 2) + { + box.MinEdge.rotateYZBy(180); + box.MaxEdge.rotateYZBy(180); + } + else if(facedir == 3) + { + box.MinEdge.rotateYZBy(90); + box.MaxEdge.rotateYZBy(90); + } + break; + case 5: + box.MinEdge.rotateXYBy(-180); + box.MaxEdge.rotateXYBy(-180); + if(facedir == 1) + { + box.MinEdge.rotateXZBy(90); + box.MaxEdge.rotateXZBy(90); + } + else if(facedir == 2) + { + box.MinEdge.rotateXZBy(180); + box.MaxEdge.rotateXZBy(180); + } + else if(facedir == 3) + { + box.MinEdge.rotateXZBy(-90); + box.MaxEdge.rotateXZBy(-90); + } + break; + default: + break; + } + box.repair(); + boxes.push_back(box); + } + } + else if(nodebox.type == NODEBOX_WALLMOUNTED) + { + v3s16 dir = n.getWallMountedDir(nodemgr); + + // top + if(dir == v3s16(0,1,0)) + { + boxes.push_back(nodebox.wall_top); + } + // bottom + else if(dir == v3s16(0,-1,0)) + { + boxes.push_back(nodebox.wall_bottom); + } + // side + else + { + v3f vertices[2] = + { + nodebox.wall_side.MinEdge, + nodebox.wall_side.MaxEdge + }; + + for (v3f &vertex : vertices) { + if(dir == v3s16(-1,0,0)) + vertex.rotateXZBy(0); + if(dir == v3s16(1,0,0)) + vertex.rotateXZBy(180); + if(dir == v3s16(0,0,-1)) + vertex.rotateXZBy(90); + if(dir == v3s16(0,0,1)) + vertex.rotateXZBy(-90); + } + + aabb3f box = aabb3f(vertices[0]); + box.addInternalPoint(vertices[1]); + boxes.push_back(box); + } + } + else if (nodebox.type == NODEBOX_CONNECTED) + { + size_t boxes_size = boxes.size(); + boxes_size += nodebox.fixed.size(); + const auto &c = nodebox.getConnected(); + + if (neighbors & 1) + boxes_size += c.connect_top.size(); + else + boxes_size += c.disconnected_top.size(); + + if (neighbors & 2) + boxes_size += c.connect_bottom.size(); + else + boxes_size += c.disconnected_bottom.size(); + + if (neighbors & 4) + boxes_size += c.connect_front.size(); + else + boxes_size += c.disconnected_front.size(); + + if (neighbors & 8) + boxes_size += c.connect_left.size(); + else + boxes_size += c.disconnected_left.size(); + + if (neighbors & 16) + boxes_size += c.connect_back.size(); + else + boxes_size += c.disconnected_back.size(); + + if (neighbors & 32) + boxes_size += c.connect_right.size(); + else + boxes_size += c.disconnected_right.size(); + + if (neighbors == 0) + boxes_size += c.disconnected.size(); + + if (neighbors < 4) + boxes_size += c.disconnected_sides.size(); + + boxes.reserve(boxes_size); + +#define BOXESPUSHBACK(c) \ + for (std::vector<aabb3f>::const_iterator \ + it = (c).begin(); \ + it != (c).end(); ++it) \ + (boxes).push_back(*it); + + BOXESPUSHBACK(nodebox.fixed); + + if (neighbors & 1) { + BOXESPUSHBACK(c.connect_top); + } else { + BOXESPUSHBACK(c.disconnected_top); + } + + if (neighbors & 2) { + BOXESPUSHBACK(c.connect_bottom); + } else { + BOXESPUSHBACK(c.disconnected_bottom); + } + + if (neighbors & 4) { + BOXESPUSHBACK(c.connect_front); + } else { + BOXESPUSHBACK(c.disconnected_front); + } + + if (neighbors & 8) { + BOXESPUSHBACK(c.connect_left); + } else { + BOXESPUSHBACK(c.disconnected_left); + } + + if (neighbors & 16) { + BOXESPUSHBACK(c.connect_back); + } else { + BOXESPUSHBACK(c.disconnected_back); + } + + if (neighbors & 32) { + BOXESPUSHBACK(c.connect_right); + } else { + BOXESPUSHBACK(c.disconnected_right); + } + + if (neighbors == 0) { + BOXESPUSHBACK(c.disconnected); + } + + if (neighbors < 4) { + BOXESPUSHBACK(c.disconnected_sides); + } + + } + else // NODEBOX_REGULAR + { + boxes.emplace_back(-BS/2,-BS/2,-BS/2,BS/2,BS/2,BS/2); + } +} + +static inline void getNeighborConnectingFace( + const v3s16 &p, const NodeDefManager *nodedef, + Map *map, MapNode n, u8 bitmask, u8 *neighbors) +{ + MapNode n2 = map->getNode(p); + if (nodedef->nodeboxConnects(n, n2, bitmask)) + *neighbors |= bitmask; +} + +u8 MapNode::getNeighbors(v3s16 p, Map *map) const +{ + const NodeDefManager *nodedef = map->getNodeDefManager(); + u8 neighbors = 0; + const ContentFeatures &f = nodedef->get(*this); + // locate possible neighboring nodes to connect to + if (f.drawtype == NDT_NODEBOX && f.node_box.type == NODEBOX_CONNECTED) { + v3s16 p2 = p; + + p2.Y++; + getNeighborConnectingFace(p2, nodedef, map, *this, 1, &neighbors); + + p2 = p; + p2.Y--; + getNeighborConnectingFace(p2, nodedef, map, *this, 2, &neighbors); + + p2 = p; + p2.Z--; + getNeighborConnectingFace(p2, nodedef, map, *this, 4, &neighbors); + + p2 = p; + p2.X--; + getNeighborConnectingFace(p2, nodedef, map, *this, 8, &neighbors); + + p2 = p; + p2.Z++; + getNeighborConnectingFace(p2, nodedef, map, *this, 16, &neighbors); + + p2 = p; + p2.X++; + getNeighborConnectingFace(p2, nodedef, map, *this, 32, &neighbors); + } + + return neighbors; +} + +void MapNode::getNodeBoxes(const NodeDefManager *nodemgr, + std::vector<aabb3f> *boxes, u8 neighbors) const +{ + const ContentFeatures &f = nodemgr->get(*this); + transformNodeBox(*this, f.node_box, nodemgr, boxes, neighbors); +} + +void MapNode::getCollisionBoxes(const NodeDefManager *nodemgr, + std::vector<aabb3f> *boxes, u8 neighbors) const +{ + const ContentFeatures &f = nodemgr->get(*this); + if (f.collision_box.fixed.empty()) + transformNodeBox(*this, f.node_box, nodemgr, boxes, neighbors); + else + transformNodeBox(*this, f.collision_box, nodemgr, boxes, neighbors); +} + +void MapNode::getSelectionBoxes(const NodeDefManager *nodemgr, + std::vector<aabb3f> *boxes, u8 neighbors) const +{ + const ContentFeatures &f = nodemgr->get(*this); + transformNodeBox(*this, f.selection_box, nodemgr, boxes, neighbors); +} + +u8 MapNode::getMaxLevel(const NodeDefManager *nodemgr) const +{ + const ContentFeatures &f = nodemgr->get(*this); + // todo: after update in all games leave only if (f.param_type_2 == + if( f.liquid_type == LIQUID_FLOWING || f.param_type_2 == CPT2_FLOWINGLIQUID) + return LIQUID_LEVEL_MAX; + if(f.leveled || f.param_type_2 == CPT2_LEVELED) + return f.leveled_max; + return 0; +} + +u8 MapNode::getLevel(const NodeDefManager *nodemgr) const +{ + const ContentFeatures &f = nodemgr->get(*this); + // todo: after update in all games leave only if (f.param_type_2 == + if(f.liquid_type == LIQUID_SOURCE) + return LIQUID_LEVEL_SOURCE; + if (f.param_type_2 == CPT2_FLOWINGLIQUID) + return getParam2() & LIQUID_LEVEL_MASK; + if(f.liquid_type == LIQUID_FLOWING) // can remove if all param_type_2 setted + return getParam2() & LIQUID_LEVEL_MASK; + if (f.param_type_2 == CPT2_LEVELED) { + u8 level = getParam2() & LEVELED_MASK; + if (level) + return level; + } + // Return static value from nodedef if param2 isn't used for level + if (f.leveled > f.leveled_max) + return f.leveled_max; + return f.leveled; +} + +s8 MapNode::setLevel(const NodeDefManager *nodemgr, s16 level) +{ + s8 rest = 0; + const ContentFeatures &f = nodemgr->get(*this); + if (f.param_type_2 == CPT2_FLOWINGLIQUID + || f.liquid_type == LIQUID_FLOWING + || f.liquid_type == LIQUID_SOURCE) { + if (level <= 0) { // liquid can’t exist with zero level + setContent(CONTENT_AIR); + return 0; + } + if (level >= LIQUID_LEVEL_SOURCE) { + rest = level - LIQUID_LEVEL_SOURCE; + setContent(f.liquid_alternative_source_id); + setParam2(0); + } else { + setContent(f.liquid_alternative_flowing_id); + setParam2((level & LIQUID_LEVEL_MASK) | (getParam2() & ~LIQUID_LEVEL_MASK)); + } + } else if (f.param_type_2 == CPT2_LEVELED) { + if (level < 0) { // zero means default for a leveled nodebox + rest = level; + level = 0; + } else if (level > f.leveled_max) { + rest = level - f.leveled_max; + level = f.leveled_max; + } + setParam2((level & LEVELED_MASK) | (getParam2() & ~LEVELED_MASK)); + } + return rest; +} + +s8 MapNode::addLevel(const NodeDefManager *nodemgr, s16 add) +{ + s16 level = getLevel(nodemgr); + level += add; + return setLevel(nodemgr, level); +} + +u32 MapNode::serializedLength(u8 version) +{ + if(!ser_ver_supported(version)) + throw VersionMismatchException("ERROR: MapNode format not supported"); + + if (version == 0) + return 1; + + if (version <= 9) + return 2; + + if (version <= 23) + return 3; + + return 4; +} +void MapNode::serialize(u8 *dest, u8 version) const +{ + if(!ser_ver_supported(version)) + throw VersionMismatchException("ERROR: MapNode format not supported"); + + // Can't do this anymore; we have 16-bit dynamically allocated node IDs + // in memory; conversion just won't work in this direction. + if(version < 24) + throw SerializationError("MapNode::serialize: serialization to " + "version < 24 not possible"); + + writeU16(dest+0, param0); + writeU8(dest+2, param1); + writeU8(dest+3, param2); +} +void MapNode::deSerialize(u8 *source, u8 version) +{ + if(!ser_ver_supported(version)) + throw VersionMismatchException("ERROR: MapNode format not supported"); + + if(version <= 21) + { + deSerialize_pre22(source, version); + return; + } + + if(version >= 24){ + param0 = readU16(source+0); + param1 = readU8(source+2); + param2 = readU8(source+3); + }else{ + param0 = readU8(source+0); + param1 = readU8(source+1); + param2 = readU8(source+2); + if(param0 > 0x7F){ + param0 |= ((param2&0xF0)<<4); + param2 &= 0x0F; + } + } +} + +SharedBuffer<u8> MapNode::serializeBulk(int version, + const MapNode *nodes, u32 nodecount, + u8 content_width, u8 params_width) +{ + if (!ser_ver_supported(version)) + throw VersionMismatchException("ERROR: MapNode format not supported"); + + sanity_check(content_width == 2); + sanity_check(params_width == 2); + + // Can't do this anymore; we have 16-bit dynamically allocated node IDs + // in memory; conversion just won't work in this direction. + if (version < 24) + throw SerializationError("MapNode::serializeBulk: serialization to " + "version < 24 not possible"); + + SharedBuffer<u8> databuf(nodecount * (content_width + params_width)); + + u32 start1 = content_width * nodecount; + u32 start2 = (content_width + 1) * nodecount; + + // Serialize content + for (u32 i = 0; i < nodecount; i++) { + writeU16(&databuf[i * 2], nodes[i].param0); + writeU8(&databuf[start1 + i], nodes[i].param1); + writeU8(&databuf[start2 + i], nodes[i].param2); + } + return databuf; +} + +// Deserialize bulk node data +void MapNode::deSerializeBulk(std::istream &is, int version, + MapNode *nodes, u32 nodecount, + u8 content_width, u8 params_width) +{ + if(!ser_ver_supported(version)) + throw VersionMismatchException("ERROR: MapNode format not supported"); + + if (version < 22 + || (content_width != 1 && content_width != 2) + || params_width != 2) + FATAL_ERROR("Deserialize bulk node data error"); + + // read data + const u32 len = nodecount * (content_width + params_width); + Buffer<u8> databuf(len); + is.read(reinterpret_cast<char*>(*databuf), len); + + // Deserialize content + if(content_width == 1) + { + for(u32 i=0; i<nodecount; i++) + nodes[i].param0 = readU8(&databuf[i]); + } + else if(content_width == 2) + { + for(u32 i=0; i<nodecount; i++) + nodes[i].param0 = readU16(&databuf[i*2]); + } + + // Deserialize param1 + u32 start1 = content_width * nodecount; + for(u32 i=0; i<nodecount; i++) + nodes[i].param1 = readU8(&databuf[start1 + i]); + + // Deserialize param2 + u32 start2 = (content_width + 1) * nodecount; + if(content_width == 1) + { + for(u32 i=0; i<nodecount; i++) { + nodes[i].param2 = readU8(&databuf[start2 + i]); + if(nodes[i].param0 > 0x7F){ + nodes[i].param0 <<= 4; + nodes[i].param0 |= (nodes[i].param2&0xF0)>>4; + nodes[i].param2 &= 0x0F; + } + } + } + else if(content_width == 2) + { + for(u32 i=0; i<nodecount; i++) + nodes[i].param2 = readU8(&databuf[start2 + i]); + } +} + +/* + Legacy serialization +*/ +void MapNode::deSerialize_pre22(const u8 *source, u8 version) +{ + if(version <= 1) + { + param0 = source[0]; + } + else if(version <= 9) + { + param0 = source[0]; + param1 = source[1]; + } + else + { + param0 = source[0]; + param1 = source[1]; + param2 = source[2]; + if(param0 > 0x7f){ + param0 <<= 4; + param0 |= (param2&0xf0)>>4; + param2 &= 0x0f; + } + } + + // Convert special values from old version to new + if(version <= 19) + { + // In these versions, CONTENT_IGNORE and CONTENT_AIR + // are 255 and 254 + // Version 19 is messed up with sometimes the old values and sometimes not + if(param0 == 255) + param0 = CONTENT_IGNORE; + else if(param0 == 254) + param0 = CONTENT_AIR; + } + + // Translate to our known version + *this = mapnode_translate_to_internal(*this, version); +} diff --git a/src/mapnode.h b/src/mapnode.h new file mode 100644 index 0000000..afd3a96 --- /dev/null +++ b/src/mapnode.h @@ -0,0 +1,307 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +#include "light.h" +#include "util/pointer.h" +#include <string> +#include <vector> + +class NodeDefManager; +class Map; + +/* + Naming scheme: + - Material = irrlicht's Material class + - Content = (content_t) content of a node + - Tile = TileSpec at some side of a node of some content type +*/ +typedef u16 content_t; + +/* + The maximum node ID that can be registered by mods. This must + be significantly lower than the maximum content_t value, so that + there is enough room for dummy node IDs, which are created when + a MapBlock containing unknown node names is loaded from disk. +*/ +#define MAX_REGISTERED_CONTENT 0x7fffU + +/* + A solid walkable node with the texture unknown_node.png. + + For example, used on the client to display unregistered node IDs + (instead of expanding the vector of node definitions each time + such a node is received). +*/ +#define CONTENT_UNKNOWN 125 + +/* + The common material through which the player can walk and which + is transparent to light +*/ +#define CONTENT_AIR 126 + +/* + Ignored node. + + Unloaded chunks are considered to consist of this. Several other + methods return this when an error occurs. Also, during + map generation this means the node has not been set yet. + + Doesn't create faces with anything and is considered being + out-of-map in the game map. +*/ +#define CONTENT_IGNORE 127 + +enum LightBank +{ + LIGHTBANK_DAY, + LIGHTBANK_NIGHT +}; + +/* + Simple rotation enum. +*/ +enum Rotation { + ROTATE_0, + ROTATE_90, + ROTATE_180, + ROTATE_270, + ROTATE_RAND, +}; + +/* + Masks for MapNode.param2 of flowing liquids + */ +#define LIQUID_LEVEL_MASK 0x07 +#define LIQUID_FLOW_DOWN_MASK 0x08 + +//#define LIQUID_LEVEL_MASK 0x3f // better finite water +//#define LIQUID_FLOW_DOWN_MASK 0x40 // not used when finite water + +/* maximum amount of liquid in a block */ +#define LIQUID_LEVEL_MAX LIQUID_LEVEL_MASK +#define LIQUID_LEVEL_SOURCE (LIQUID_LEVEL_MAX+1) + +#define LIQUID_INFINITY_MASK 0x80 //0b10000000 + +// mask for leveled nodebox param2 +#define LEVELED_MASK 0x7F +#define LEVELED_MAX LEVELED_MASK + + +struct ContentFeatures; + +/* + This is the stuff what the whole world consists of. +*/ + + +struct MapNode +{ + /* + Main content + */ + u16 param0; + + /* + Misc parameter. Initialized to 0. + - For light_propagates() blocks, this is light intensity, + stored logarithmically from 0 to LIGHT_MAX. + Sunlight is LIGHT_SUN, which is LIGHT_MAX+1. + - Contains 2 values, day- and night lighting. Each takes 4 bits. + - Uhh... well, most blocks have light or nothing in here. + */ + u8 param1; + + /* + The second parameter. Initialized to 0. + E.g. direction for torches and flowing water. + */ + u8 param2; + + MapNode() = default; + + MapNode(content_t content, u8 a_param1=0, u8 a_param2=0) noexcept + : param0(content), + param1(a_param1), + param2(a_param2) + { } + + bool operator==(const MapNode &other) const noexcept + { + return (param0 == other.param0 + && param1 == other.param1 + && param2 == other.param2); + } + + // To be used everywhere + content_t getContent() const noexcept + { + return param0; + } + void setContent(content_t c) noexcept + { + param0 = c; + } + u8 getParam1() const noexcept + { + return param1; + } + void setParam1(u8 p) noexcept + { + param1 = p; + } + u8 getParam2() const noexcept + { + return param2; + } + void setParam2(u8 p) noexcept + { + param2 = p; + } + + /*! + * Returns the color of the node. + * + * \param f content features of this node + * \param color output, contains the node's color. + */ + void getColor(const ContentFeatures &f, video::SColor *color) const; + + void setLight(LightBank bank, u8 a_light, const ContentFeatures &f) noexcept; + + void setLight(LightBank bank, u8 a_light, const NodeDefManager *nodemgr); + + /** + * Check if the light value for night differs from the light value for day. + * + * @return If the light values are equal, returns true; otherwise false + */ + bool isLightDayNightEq(const NodeDefManager *nodemgr) const; + + u8 getLight(LightBank bank, const NodeDefManager *nodemgr) const; + + /*! + * Returns the node's light level from param1. + * If the node emits light, it is ignored. + * \param f the ContentFeatures of this node. + */ + u8 getLightRaw(LightBank bank, const ContentFeatures &f) const noexcept; + + /** + * This function differs from getLight(LightBank bank, NodeDefManager *nodemgr) + * in that the ContentFeatures of the node in question are not retrieved by + * the function itself. Thus, if you have already called nodemgr->get() to + * get the ContentFeatures you pass it to this function instead of the + * function getting ContentFeatures itself. Since NodeDefManager::get() + * is relatively expensive this can lead to significant performance + * improvements in some situations. Call this function if (and only if) + * you have already retrieved the ContentFeatures by calling + * NodeDefManager::get() for the node you're working with and the + * pre-conditions listed are true. + * + * @pre f != NULL + * @pre f->param_type == CPT_LIGHT + */ + u8 getLightNoChecks(LightBank bank, const ContentFeatures *f) const noexcept; + + bool getLightBanks(u8 &lightday, u8 &lightnight, + const NodeDefManager *nodemgr) const; + + // 0 <= daylight_factor <= 1000 + // 0 <= return value <= LIGHT_SUN + u8 getLightBlend(u32 daylight_factor, const NodeDefManager *nodemgr) const + { + u8 lightday = 0; + u8 lightnight = 0; + getLightBanks(lightday, lightnight, nodemgr); + return blend_light(daylight_factor, lightday, lightnight); + } + + u8 getFaceDir(const NodeDefManager *nodemgr, bool allow_wallmounted = false) const; + u8 getWallMounted(const NodeDefManager *nodemgr) const; + v3s16 getWallMountedDir(const NodeDefManager *nodemgr) const; + + /// @returns Rotation in range 0–239 (in 1.5° steps) + u8 getDegRotate(const NodeDefManager *nodemgr) const; + + void rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot); + + /*! + * Checks which neighbors does this node connect to. + * + * \param p coordinates of the node + */ + u8 getNeighbors(v3s16 p, Map *map) const; + + /* + Gets list of node boxes (used for rendering (NDT_NODEBOX)) + */ + void getNodeBoxes(const NodeDefManager *nodemgr, std::vector<aabb3f> *boxes, + u8 neighbors = 0) const; + + /* + Gets list of selection boxes + */ + void getSelectionBoxes(const NodeDefManager *nodemg, + std::vector<aabb3f> *boxes, u8 neighbors = 0) const; + + /* + Gets list of collision boxes + */ + void getCollisionBoxes(const NodeDefManager *nodemgr, + std::vector<aabb3f> *boxes, u8 neighbors = 0) const; + + /* + Liquid/leveled helpers + */ + u8 getMaxLevel(const NodeDefManager *nodemgr) const; + u8 getLevel(const NodeDefManager *nodemgr) const; + s8 setLevel(const NodeDefManager *nodemgr, s16 level = 1); + s8 addLevel(const NodeDefManager *nodemgr, s16 add = 1); + + /* + Serialization functions + */ + + static u32 serializedLength(u8 version); + void serialize(u8 *dest, u8 version) const; + void deSerialize(u8 *source, u8 version); + + // Serializes or deserializes a list of nodes in bulk format (first the + // content of all nodes, then the param1 of all nodes, then the param2 + // of all nodes). + // version = serialization version. Must be >= 22 + // content_width = the number of bytes of content per node + // params_width = the number of bytes of params per node + // compressed = true to zlib-compress output + static SharedBuffer<u8> serializeBulk(int version, + const MapNode *nodes, u32 nodecount, + u8 content_width, u8 params_width); + static void deSerializeBulk(std::istream &is, int version, + MapNode *nodes, u32 nodecount, + u8 content_width, u8 params_width); + +private: + // Deprecated serialization methods + void deSerialize_pre22(const u8 *source, u8 version); +}; diff --git a/src/mapsector.cpp b/src/mapsector.cpp new file mode 100644 index 0000000..3eefa54 --- /dev/null +++ b/src/mapsector.cpp @@ -0,0 +1,130 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mapsector.h" +#include "exceptions.h" +#include "mapblock.h" +#include "serialization.h" + +MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef): + m_parent(parent), + m_pos(pos), + m_gamedef(gamedef) +{ +} + +MapSector::~MapSector() +{ + deleteBlocks(); +} + +void MapSector::deleteBlocks() +{ + // Clear cache + m_block_cache = nullptr; + + // Delete all + for (auto &block : m_blocks) { + delete block.second; + } + + // Clear container + m_blocks.clear(); +} + +MapBlock * MapSector::getBlockBuffered(s16 y) +{ + MapBlock *block; + + if (m_block_cache && y == m_block_cache_y) { + return m_block_cache; + } + + // If block doesn't exist, return NULL + std::unordered_map<s16, MapBlock*>::const_iterator n = m_blocks.find(y); + block = (n != m_blocks.end() ? n->second : nullptr); + + // Cache the last result + m_block_cache_y = y; + m_block_cache = block; + + return block; +} + +MapBlock * MapSector::getBlockNoCreateNoEx(s16 y) +{ + return getBlockBuffered(y); +} + +MapBlock * MapSector::createBlankBlockNoInsert(s16 y) +{ + assert(getBlockBuffered(y) == NULL); // Pre-condition + + v3s16 blockpos_map(m_pos.X, y, m_pos.Y); + + MapBlock *block = new MapBlock(m_parent, blockpos_map, m_gamedef); + + return block; +} + +MapBlock * MapSector::createBlankBlock(s16 y) +{ + MapBlock *block = createBlankBlockNoInsert(y); + + m_blocks[y] = block; + + return block; +} + +void MapSector::insertBlock(MapBlock *block) +{ + s16 block_y = block->getPos().Y; + + MapBlock *block2 = getBlockBuffered(block_y); + if (block2) { + throw AlreadyExistsException("Block already exists"); + } + + v2s16 p2d(block->getPos().X, block->getPos().Z); + assert(p2d == m_pos); + + // Insert into container + m_blocks[block_y] = block; +} + +void MapSector::deleteBlock(MapBlock *block) +{ + s16 block_y = block->getPos().Y; + + // Clear from cache + m_block_cache = nullptr; + + // Remove from container + m_blocks.erase(block_y); + + // Delete + delete block; +} + +void MapSector::getBlocks(MapBlockVect &dest) +{ + for (auto &block : m_blocks) { + dest.push_back(block.second); + } +} diff --git a/src/mapsector.h b/src/mapsector.h new file mode 100644 index 0000000..ffd4cdd --- /dev/null +++ b/src/mapsector.h @@ -0,0 +1,87 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "irr_v2d.h" +#include "mapblock.h" +#include <ostream> +#include <map> +#include <vector> + +class Map; +class IGameDef; + +/* + This is an Y-wise stack of MapBlocks. +*/ + +#define MAPSECTOR_SERVER 0 +#define MAPSECTOR_CLIENT 1 + +class MapSector +{ +public: + + MapSector(Map *parent, v2s16 pos, IGameDef *gamedef); + virtual ~MapSector(); + + void deleteBlocks(); + + v2s16 getPos() + { + return m_pos; + } + + MapBlock * getBlockNoCreateNoEx(s16 y); + MapBlock * createBlankBlockNoInsert(s16 y); + MapBlock * createBlankBlock(s16 y); + + void insertBlock(MapBlock *block); + + void deleteBlock(MapBlock *block); + + void getBlocks(MapBlockVect &dest); + + bool empty() const { return m_blocks.empty(); } + + int size() const { return m_blocks.size(); } +protected: + + // The pile of MapBlocks + std::unordered_map<s16, MapBlock*> m_blocks; + + Map *m_parent; + // Position on parent (in MapBlock widths) + v2s16 m_pos; + + IGameDef *m_gamedef; + + // Last-used block is cached here for quicker access. + // Be sure to set this to nullptr when the cached block is deleted + MapBlock *m_block_cache = nullptr; + s16 m_block_cache_y; + + /* + Private methods + */ + MapBlock *getBlockBuffered(s16 y); + +}; diff --git a/src/metadata.cpp b/src/metadata.cpp new file mode 100644 index 0000000..453ac1c --- /dev/null +++ b/src/metadata.cpp @@ -0,0 +1,115 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "metadata.h" +#include "log.h" + +/* + Metadata +*/ + +void Metadata::clear() +{ + m_stringvars.clear(); + m_modified = true; +} + +bool Metadata::empty() const +{ + return m_stringvars.empty(); +} + +size_t Metadata::size() const +{ + return m_stringvars.size(); +} + +bool Metadata::contains(const std::string &name) const +{ + return m_stringvars.find(name) != m_stringvars.end(); +} + +bool Metadata::operator==(const Metadata &other) const +{ + if (size() != other.size()) + return false; + + for (const auto &sv : m_stringvars) { + if (!other.contains(sv.first) || other.getString(sv.first) != sv.second) + return false; + } + + return true; +} + +const std::string &Metadata::getString(const std::string &name, u16 recursion) const +{ + StringMap::const_iterator it = m_stringvars.find(name); + if (it == m_stringvars.end()) { + static const std::string empty_string = std::string(""); + return empty_string; + } + + return resolveString(it->second, recursion); +} + +bool Metadata::getStringToRef( + const std::string &name, std::string &str, u16 recursion) const +{ + StringMap::const_iterator it = m_stringvars.find(name); + if (it == m_stringvars.end()) { + return false; + } + + str = resolveString(it->second, recursion); + return true; +} + +/** + * Sets var to name key in the metadata storage + * + * @param name + * @param var + * @return true if key-value pair is created or changed + */ +bool Metadata::setString(const std::string &name, const std::string &var) +{ + if (var.empty()) { + m_stringvars.erase(name); + return true; + } + + StringMap::iterator it = m_stringvars.find(name); + if (it != m_stringvars.end() && it->second == var) { + return false; + } + + m_stringvars[name] = var; + m_modified = true; + return true; +} + +const std::string &Metadata::resolveString(const std::string &str, u16 recursion) const +{ + if (recursion <= 1 && str.substr(0, 2) == "${" && str[str.length() - 1] == '}') { + return getString(str.substr(2, str.length() - 3), recursion + 1); + } + + return str; +} diff --git a/src/metadata.h b/src/metadata.h new file mode 100644 index 0000000..5333f8a --- /dev/null +++ b/src/metadata.h @@ -0,0 +1,63 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_v3d.h" +#include <iostream> +#include <vector> +#include "util/string.h" + +class Metadata +{ + bool m_modified = false; +public: + virtual ~Metadata() = default; + + virtual void clear(); + virtual bool empty() const; + + bool operator==(const Metadata &other) const; + inline bool operator!=(const Metadata &other) const + { + return !(*this == other); + } + + // + // Key-value related + // + + size_t size() const; + bool contains(const std::string &name) const; + const std::string &getString(const std::string &name, u16 recursion = 0) const; + bool getStringToRef(const std::string &name, std::string &str, u16 recursion = 0) const; + virtual bool setString(const std::string &name, const std::string &var); + inline bool removeString(const std::string &name) { return setString(name, ""); } + const StringMap &getStrings() const + { + return m_stringvars; + } + // Add support for variable names in values + const std::string &resolveString(const std::string &str, u16 recursion = 0) const; + + inline bool isModified() const { return m_modified; } + inline void setModified(bool v) { m_modified = v; } +protected: + StringMap m_stringvars; +}; diff --git a/src/modchannels.cpp b/src/modchannels.cpp new file mode 100644 index 0000000..9626e8e --- /dev/null +++ b/src/modchannels.cpp @@ -0,0 +1,151 @@ +/* +Minetest +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "modchannels.h" +#include <algorithm> +#include <cassert> +#include "util/basic_macros.h" + +bool ModChannel::registerConsumer(session_t peer_id) +{ + + // ignore if peer_id already joined + if (CONTAINS(m_client_consumers, peer_id)) + return false; + + m_client_consumers.push_back(peer_id); + return true; +} + +bool ModChannel::removeConsumer(session_t peer_id) +{ + bool found = false; + auto peer_removal_fct = [peer_id, &found](u16 p) { + if (p == peer_id) + found = true; + + return p == peer_id; + }; + + m_client_consumers.erase( + std::remove_if(m_client_consumers.begin(), + m_client_consumers.end(), peer_removal_fct), + m_client_consumers.end()); + + return found; +} + +bool ModChannel::canWrite() const +{ + return m_state == MODCHANNEL_STATE_READ_WRITE; +} + +void ModChannel::setState(ModChannelState state) +{ + assert(state != MODCHANNEL_STATE_INIT); + + m_state = state; +} + +bool ModChannelMgr::channelRegistered(const std::string &channel) const +{ + return m_registered_channels.find(channel) != m_registered_channels.end(); +} + +ModChannel *ModChannelMgr::getModChannel(const std::string &channel) +{ + if (!channelRegistered(channel)) + return nullptr; + + return m_registered_channels[channel].get(); +} + +bool ModChannelMgr::canWriteOnChannel(const std::string &channel) const +{ + const auto channel_it = m_registered_channels.find(channel); + if (channel_it == m_registered_channels.end()) { + return false; + } + + return channel_it->second->canWrite(); +} + +void ModChannelMgr::registerChannel(const std::string &channel) +{ + m_registered_channels[channel] = std::make_unique<ModChannel>(channel); +} + +bool ModChannelMgr::setChannelState(const std::string &channel, ModChannelState state) +{ + if (!channelRegistered(channel)) + return false; + + auto channel_it = m_registered_channels.find(channel); + channel_it->second->setState(state); + + return true; +} + +bool ModChannelMgr::removeChannel(const std::string &channel) +{ + if (!channelRegistered(channel)) + return false; + + m_registered_channels.erase(channel); + return true; +} + +bool ModChannelMgr::joinChannel(const std::string &channel, session_t peer_id) +{ + if (!channelRegistered(channel)) + registerChannel(channel); + + return m_registered_channels[channel]->registerConsumer(peer_id); +} + +bool ModChannelMgr::leaveChannel(const std::string &channel, session_t peer_id) +{ + if (!channelRegistered(channel)) + return false; + + // Remove consumer from channel + bool consumerRemoved = m_registered_channels[channel]->removeConsumer(peer_id); + + // If channel is empty, remove it + if (m_registered_channels[channel]->getChannelPeers().empty()) { + removeChannel(channel); + } + return consumerRemoved; +} + +void ModChannelMgr::leaveAllChannels(session_t peer_id) +{ + for (auto &channel_it : m_registered_channels) + channel_it.second->removeConsumer(peer_id); +} + +static std::vector<u16> empty_channel_list; +const std::vector<u16> &ModChannelMgr::getChannelPeers(const std::string &channel) const +{ + const auto &channel_it = m_registered_channels.find(channel); + if (channel_it == m_registered_channels.end()) + return empty_channel_list; + + return channel_it->second->getChannelPeers(); +} diff --git a/src/modchannels.h b/src/modchannels.h new file mode 100644 index 0000000..735609b --- /dev/null +++ b/src/modchannels.h @@ -0,0 +1,93 @@ +/* +Minetest +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <unordered_map> +#include <string> +#include <vector> +#include <memory> +#include "network/networkprotocol.h" +#include "irrlichttypes.h" + +enum ModChannelState : u8 +{ + MODCHANNEL_STATE_INIT, + MODCHANNEL_STATE_READ_WRITE, + MODCHANNEL_STATE_READ_ONLY, + MODCHANNEL_STATE_MAX, +}; + +class ModChannel +{ +public: + ModChannel(const std::string &name) : m_name(name) {} + ~ModChannel() = default; + + const std::string &getName() const { return m_name; } + bool registerConsumer(session_t peer_id); + bool removeConsumer(session_t peer_id); + const std::vector<u16> &getChannelPeers() const { return m_client_consumers; } + bool canWrite() const; + void setState(ModChannelState state); + +private: + std::string m_name; + ModChannelState m_state = MODCHANNEL_STATE_INIT; + std::vector<u16> m_client_consumers; +}; + +enum ModChannelSignal : u8 +{ + MODCHANNEL_SIGNAL_JOIN_OK, + MODCHANNEL_SIGNAL_JOIN_FAILURE, + MODCHANNEL_SIGNAL_LEAVE_OK, + MODCHANNEL_SIGNAL_LEAVE_FAILURE, + MODCHANNEL_SIGNAL_CHANNEL_NOT_REGISTERED, + MODCHANNEL_SIGNAL_SET_STATE, +}; + +class ModChannelMgr +{ +public: + ModChannelMgr() = default; + ~ModChannelMgr() = default; + + void registerChannel(const std::string &channel); + bool setChannelState(const std::string &channel, ModChannelState state); + bool joinChannel(const std::string &channel, session_t peer_id); + bool leaveChannel(const std::string &channel, session_t peer_id); + bool channelRegistered(const std::string &channel) const; + ModChannel *getModChannel(const std::string &channel); + /** + * This function check if a local mod can write on the channel + * + * @param channel + * @return true if write is allowed + */ + bool canWriteOnChannel(const std::string &channel) const; + void leaveAllChannels(session_t peer_id); + const std::vector<u16> &getChannelPeers(const std::string &channel) const; + +private: + bool removeChannel(const std::string &channel); + + std::unordered_map<std::string, std::unique_ptr<ModChannel>> + m_registered_channels; +}; diff --git a/src/modifiedstate.h b/src/modifiedstate.h new file mode 100644 index 0000000..3eeb55d --- /dev/null +++ b/src/modifiedstate.h @@ -0,0 +1,33 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +enum ModifiedState +{ + // Has not been modified. + MOD_STATE_CLEAN = 0, + MOD_RESERVED1 = 1, + // Has been modified, and will be saved when being unloaded. + MOD_STATE_WRITE_AT_UNLOAD = 2, + MOD_RESERVED3 = 3, + // Has been modified, and will be saved as soon as possible. + MOD_STATE_WRITE_NEEDED = 4, + MOD_RESERVED5 = 5, +}; diff --git a/src/mtevent.h b/src/mtevent.h new file mode 100644 index 0000000..149f7ee --- /dev/null +++ b/src/mtevent.h @@ -0,0 +1,71 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" + +class MtEvent +{ +public: + enum Type : u8 + { + VIEW_BOBBING_STEP = 0, + CAMERA_PUNCH_LEFT, + CAMERA_PUNCH_RIGHT, + PLAYER_FALLING_DAMAGE, + PLAYER_DAMAGE, + NODE_DUG, + PLAYER_JUMP, + PLAYER_REGAIN_GROUND, + TYPE_MAX, + }; + + virtual ~MtEvent() = default; + virtual Type getType() const = 0; +}; + +// An event with no parameters and customizable name +class SimpleTriggerEvent : public MtEvent +{ + Type type; + +public: + SimpleTriggerEvent(Type type) : type(type) {} + Type getType() const override { return type; } +}; + +class MtEventReceiver +{ +public: + virtual ~MtEventReceiver() = default; + virtual void onEvent(MtEvent *e) = 0; +}; + +typedef void (*event_receive_func)(MtEvent *e, void *data); + +class MtEventManager +{ +public: + virtual ~MtEventManager() = default; + virtual void put(MtEvent *e) = 0; + virtual void reg(MtEvent::Type type, event_receive_func f, void *data) = 0; + // If data==NULL, every occurence of f is deregistered. + virtual void dereg(MtEvent::Type type, event_receive_func f, void *data) = 0; +}; diff --git a/src/nameidmapping.cpp b/src/nameidmapping.cpp new file mode 100644 index 0000000..05cfae0 --- /dev/null +++ b/src/nameidmapping.cpp @@ -0,0 +1,48 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "nameidmapping.h" +#include "exceptions.h" +#include "util/serialize.h" + +void NameIdMapping::serialize(std::ostream &os) const +{ + writeU8(os, 0); // version + writeU16(os, m_id_to_name.size()); + for (const auto &i : m_id_to_name) { + writeU16(os, i.first); + os << serializeString16(i.second); + } +} + +void NameIdMapping::deSerialize(std::istream &is) +{ + int version = readU8(is); + if (version != 0) + throw SerializationError("unsupported NameIdMapping version"); + u32 count = readU16(is); + m_id_to_name.clear(); + m_name_to_id.clear(); + for (u32 i = 0; i < count; i++) { + u16 id = readU16(is); + std::string name = deSerializeString16(is); + m_id_to_name[id] = name; + m_name_to_id[name] = id; + } +} diff --git a/src/nameidmapping.h b/src/nameidmapping.h new file mode 100644 index 0000000..3acb43e --- /dev/null +++ b/src/nameidmapping.h @@ -0,0 +1,91 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <iostream> +#include <set> +#include <unordered_map> +#include "irrlichttypes_bloated.h" + +typedef std::unordered_map<u16, std::string> IdToNameMap; +typedef std::unordered_map<std::string, u16> NameToIdMap; + +class NameIdMapping +{ +public: + void serialize(std::ostream &os) const; + void deSerialize(std::istream &is); + + void clear() + { + m_id_to_name.clear(); + m_name_to_id.clear(); + } + + void set(u16 id, const std::string &name) + { + m_id_to_name[id] = name; + m_name_to_id[name] = id; + } + + void removeId(u16 id) + { + std::string name; + bool found = getName(id, name); + if (!found) + return; + m_id_to_name.erase(id); + m_name_to_id.erase(name); + } + + void eraseName(const std::string &name) + { + u16 id; + bool found = getId(name, id); + if (!found) + return; + m_id_to_name.erase(id); + m_name_to_id.erase(name); + } + bool getName(u16 id, std::string &result) const + { + IdToNameMap::const_iterator i; + i = m_id_to_name.find(id); + if (i == m_id_to_name.end()) + return false; + result = i->second; + return true; + } + bool getId(const std::string &name, u16 &result) const + { + NameToIdMap::const_iterator i; + i = m_name_to_id.find(name); + if (i == m_name_to_id.end()) + return false; + result = i->second; + return true; + } + u16 size() const { return m_id_to_name.size(); } + +private: + IdToNameMap m_id_to_name; + NameToIdMap m_name_to_id; +}; diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt new file mode 100644 index 0000000..d2e2f52 --- /dev/null +++ b/src/network/CMakeLists.txt @@ -0,0 +1,18 @@ +set(common_network_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/address.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/connection.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/connectionthreads.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/networkpacket.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/serverpackethandler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/serveropcodes.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/socket.cpp + PARENT_SCOPE +) + +if (BUILD_CLIENT) + set(client_network_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/clientopcodes.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/clientpackethandler.cpp + PARENT_SCOPE + ) +endif() diff --git a/src/network/address.cpp b/src/network/address.cpp new file mode 100644 index 0000000..cf2e620 --- /dev/null +++ b/src/network/address.cpp @@ -0,0 +1,259 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "address.h" + +#include <cstdio> +#include <iostream> +#include <cstdlib> +#include <cstring> +#include <cerrno> +#include <sstream> +#include <iomanip> +#include "network/networkexceptions.h" +#include "util/string.h" +#include "util/numeric.h" +#include "constants.h" +#include "debug.h" +#include "settings.h" +#include "log.h" + +#ifdef _WIN32 +// Without this some of the network functions are not found on mingw +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif +#include <windows.h> +#include <winsock2.h> +#include <ws2tcpip.h> +#define LAST_SOCKET_ERR() WSAGetLastError() +typedef SOCKET socket_t; +typedef int socklen_t; +#else +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <fcntl.h> +#include <netdb.h> +#include <unistd.h> +#include <arpa/inet.h> +#define LAST_SOCKET_ERR() (errno) +typedef int socket_t; +#endif + +/* + Address +*/ + +Address::Address() +{ + memset(&m_address, 0, sizeof(m_address)); +} + +Address::Address(u32 address, u16 port) +{ + memset(&m_address, 0, sizeof(m_address)); + setAddress(address); + setPort(port); +} + +Address::Address(u8 a, u8 b, u8 c, u8 d, u16 port) +{ + memset(&m_address, 0, sizeof(m_address)); + setAddress(a, b, c, d); + setPort(port); +} + +Address::Address(const IPv6AddressBytes *ipv6_bytes, u16 port) +{ + memset(&m_address, 0, sizeof(m_address)); + setAddress(ipv6_bytes); + setPort(port); +} + +// Equality (address family, IP and port must be equal) +bool Address::operator==(const Address &other) +{ + if (other.m_addr_family != m_addr_family || other.m_port != m_port) + return false; + + if (m_addr_family == AF_INET) { + return m_address.ipv4.s_addr == other.m_address.ipv4.s_addr; + } + + if (m_addr_family == AF_INET6) { + return memcmp(m_address.ipv6.s6_addr, + other.m_address.ipv6.s6_addr, 16) == 0; + } + + return false; +} + +void Address::Resolve(const char *name) +{ + if (!name || name[0] == 0) { + if (m_addr_family == AF_INET) + setAddress(static_cast<u32>(0)); + else if (m_addr_family == AF_INET6) + setAddress(static_cast<IPv6AddressBytes*>(nullptr)); + return; + } + + struct addrinfo *resolved, hints; + memset(&hints, 0, sizeof(hints)); + + // Setup hints + if (g_settings->getBool("enable_ipv6")) { + // AF_UNSPEC allows both IPv6 and IPv4 addresses to be returned + hints.ai_family = AF_UNSPEC; + } else { + hints.ai_family = AF_INET; + } + + // Do getaddrinfo() + int e = getaddrinfo(name, NULL, &hints, &resolved); + if (e != 0) + throw ResolveError(gai_strerror(e)); + + // Copy data + if (resolved->ai_family == AF_INET) { + struct sockaddr_in *t = (struct sockaddr_in *)resolved->ai_addr; + m_addr_family = AF_INET; + m_address.ipv4 = t->sin_addr; + } else if (resolved->ai_family == AF_INET6) { + struct sockaddr_in6 *t = (struct sockaddr_in6 *)resolved->ai_addr; + m_addr_family = AF_INET6; + m_address.ipv6 = t->sin6_addr; + } else { + m_addr_family = 0; + } + freeaddrinfo(resolved); +} + +// IP address -> textual representation +std::string Address::serializeString() const +{ +// windows XP doesnt have inet_ntop, maybe use better func +#ifdef _WIN32 + if (m_addr_family == AF_INET) { + return inet_ntoa(m_address.ipv4); + } else if (m_addr_family == AF_INET6) { + std::ostringstream os; + os << std::hex; + for (int i = 0; i < 16; i += 2) { + u16 section = (m_address.ipv6.s6_addr[i] << 8) | + (m_address.ipv6.s6_addr[i + 1]); + os << section; + if (i < 14) + os << ":"; + } + return os.str(); + } else { + return ""; + } +#else + char str[INET6_ADDRSTRLEN]; + if (inet_ntop(m_addr_family, (void*) &m_address, str, sizeof(str)) == nullptr) + return ""; + return str; +#endif +} + +struct in_addr Address::getAddress() const +{ + return m_address.ipv4; +} + +struct in6_addr Address::getAddress6() const +{ + return m_address.ipv6; +} + +u16 Address::getPort() const +{ + return m_port; +} + +bool Address::isZero() const +{ + if (m_addr_family == AF_INET) { + return m_address.ipv4.s_addr == 0; + } + + if (m_addr_family == AF_INET6) { + static const char zero[16] = {0}; + return memcmp(m_address.ipv6.s6_addr, zero, 16) == 0; + } + + return false; +} + +void Address::setAddress(u32 address) +{ + m_addr_family = AF_INET; + m_address.ipv4.s_addr = htonl(address); +} + +void Address::setAddress(u8 a, u8 b, u8 c, u8 d) +{ + u32 addr = (a << 24) | (b << 16) | (c << 8) | d; + setAddress(addr); +} + +void Address::setAddress(const IPv6AddressBytes *ipv6_bytes) +{ + m_addr_family = AF_INET6; + if (ipv6_bytes) + memcpy(m_address.ipv6.s6_addr, ipv6_bytes->bytes, 16); + else + memset(m_address.ipv6.s6_addr, 0, 16); +} + +void Address::setPort(u16 port) +{ + m_port = port; +} + +void Address::print(std::ostream& s) const +{ + if (m_addr_family == AF_INET6) + s << "[" << serializeString() << "]:" << m_port; + else if (m_addr_family == AF_INET) + s << serializeString() << ":" << m_port; + else + s << "(undefined)"; +} + +bool Address::isLocalhost() const +{ + if (isIPv6()) { + static const u8 localhost_bytes[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + static const u8 mapped_ipv4_localhost[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x7f, 0, 0, 0}; + + auto addr = m_address.ipv6.s6_addr; + + return memcmp(addr, localhost_bytes, 16) == 0 || + memcmp(addr, mapped_ipv4_localhost, 13) == 0; + } + + auto addr = ntohl(m_address.ipv4.s_addr); + return (addr >> 24) == 0x7f; +} diff --git a/src/network/address.h b/src/network/address.h new file mode 100644 index 0000000..692bf82 --- /dev/null +++ b/src/network/address.h @@ -0,0 +1,82 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#ifdef _WIN32 +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif +#include <windows.h> +#include <winsock2.h> +#include <ws2tcpip.h> +#else +#include <netinet/in.h> +#include <sys/socket.h> +#endif + +#include <ostream> +#include <cstring> +#include "irrlichttypes.h" +#include "networkexceptions.h" + +struct IPv6AddressBytes +{ + u8 bytes[16]; + IPv6AddressBytes() { memset(bytes, 0, 16); } +}; + +class Address +{ +public: + Address(); + Address(u32 address, u16 port); + Address(u8 a, u8 b, u8 c, u8 d, u16 port); + Address(const IPv6AddressBytes *ipv6_bytes, u16 port); + + bool operator==(const Address &address); + bool operator!=(const Address &address) { return !(*this == address); } + + struct in_addr getAddress() const; + struct in6_addr getAddress6() const; + u16 getPort() const; + int getFamily() const { return m_addr_family; } + bool isIPv6() const { return m_addr_family == AF_INET6; } + bool isZero() const; + void print(std::ostream &s) const; + std::string serializeString() const; + bool isLocalhost() const; + + // Resolve() may throw ResolveError (address is unchanged in this case) + void Resolve(const char *name); + + void setAddress(u32 address); + void setAddress(u8 a, u8 b, u8 c, u8 d); + void setAddress(const IPv6AddressBytes *ipv6_bytes); + void setPort(u16 port); + +private: + unsigned short m_addr_family = 0; + union + { + struct in_addr ipv4; + struct in6_addr ipv6; + } m_address; + u16 m_port = 0; // Port is separate from sockaddr structures +}; diff --git a/src/network/clientopcodes.cpp b/src/network/clientopcodes.cpp new file mode 100644 index 0000000..6a78b46 --- /dev/null +++ b/src/network/clientopcodes.cpp @@ -0,0 +1,226 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2015 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "clientopcodes.h" + +const static ToClientCommandHandler null_command_handler = {"TOCLIENT_NULL", TOCLIENT_STATE_ALL, &Client::handleCommand_Null}; + +const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] = +{ + null_command_handler, // 0x00 (never use this) + null_command_handler, // 0x01 + { "TOCLIENT_HELLO", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_Hello }, // 0x02 + { "TOCLIENT_AUTH_ACCEPT", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_AuthAccept }, // 0x03 + { "TOCLIENT_ACCEPT_SUDO_MODE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_AcceptSudoMode}, // 0x04 + { "TOCLIENT_DENY_SUDO_MODE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DenySudoMode}, // 0x05 + null_command_handler, // 0x06 + null_command_handler, // 0x07 + null_command_handler, // 0x08 + null_command_handler, // 0x09 + { "TOCLIENT_ACCESS_DENIED", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_AccessDenied }, // 0x0A + null_command_handler, // 0x0B + null_command_handler, // 0x0C + null_command_handler, // 0x0D + null_command_handler, // 0x0E + null_command_handler, // 0x0F + null_command_handler, // 0x10 + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + { "TOCLIENT_BLOCKDATA", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_BlockData }, // 0x20 + { "TOCLIENT_ADDNODE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_AddNode }, // 0x21 + { "TOCLIENT_REMOVENODE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_RemoveNode }, // 0x22 + null_command_handler, + null_command_handler, + null_command_handler, + null_command_handler, + { "TOCLIENT_INVENTORY", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Inventory }, // 0x27 + null_command_handler, + { "TOCLIENT_TIME_OF_DAY", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_TimeOfDay }, // 0x29 + { "TOCLIENT_CSM_RESTRICTION_FLAGS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_CSMRestrictionFlags }, // 0x2A + { "TOCLIENT_PLAYER_SPEED", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_PlayerSpeed }, // 0x2B + { "TOCLIENT_MEDIA_PUSH", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_MediaPush }, // 0x2C + null_command_handler, + null_command_handler, + { "TOCLIENT_CHAT_MESSAGE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ChatMessage }, // 0x2F + null_command_handler, // 0x30 + { "TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ActiveObjectRemoveAdd }, // 0x31 + { "TOCLIENT_ACTIVE_OBJECT_MESSAGES", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ActiveObjectMessages }, // 0x32 + { "TOCLIENT_HP", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HP }, // 0x33 + { "TOCLIENT_MOVE_PLAYER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_MovePlayer }, // 0x34 + { "TOCLIENT_ACCESS_DENIED_LEGACY", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_AccessDenied }, // 0x35 + { "TOCLIENT_FOV", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Fov }, // 0x36 + { "TOCLIENT_DEATHSCREEN", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DeathScreen }, // 0x37 + { "TOCLIENT_MEDIA", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Media }, // 0x38 + null_command_handler, + { "TOCLIENT_NODEDEF", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_NodeDef }, // 0x3a + null_command_handler, + { "TOCLIENT_ANNOUNCE_MEDIA", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_AnnounceMedia }, // 0x3c + { "TOCLIENT_ITEMDEF", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ItemDef }, // 0x3d + null_command_handler, + { "TOCLIENT_PLAY_SOUND", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_PlaySound }, // 0x3f + { "TOCLIENT_STOP_SOUND", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_StopSound }, // 0x40 + { "TOCLIENT_PRIVILEGES", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Privileges }, // 0x41 + { "TOCLIENT_INVENTORY_FORMSPEC", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_InventoryFormSpec }, // 0x42 + { "TOCLIENT_DETACHED_INVENTORY", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DetachedInventory }, // 0x43 + { "TOCLIENT_SHOW_FORMSPEC", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ShowFormSpec }, // 0x44 + { "TOCLIENT_MOVEMENT", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Movement }, // 0x45 + { "TOCLIENT_SPAWN_PARTICLE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_SpawnParticle }, // 0x46 + { "TOCLIENT_ADD_PARTICLESPAWNER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_AddParticleSpawner }, // 0x47 + null_command_handler, + { "TOCLIENT_HUDADD", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudAdd }, // 0x49 + { "TOCLIENT_HUDRM", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudRemove }, // 0x4a + { "TOCLIENT_HUDCHANGE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudChange }, // 0x4b + { "TOCLIENT_HUD_SET_FLAGS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudSetFlags }, // 0x4c + { "TOCLIENT_HUD_SET_PARAM", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudSetParam }, // 0x4d + { "TOCLIENT_BREATH", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Breath }, // 0x4e + { "TOCLIENT_SET_SKY", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudSetSky }, // 0x4f + { "TOCLIENT_OVERRIDE_DAY_NIGHT_RATIO", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_OverrideDayNightRatio }, // 0x50 + { "TOCLIENT_LOCAL_PLAYER_ANIMATIONS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_LocalPlayerAnimations }, // 0x51 + { "TOCLIENT_EYE_OFFSET", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_EyeOffset }, // 0x52 + { "TOCLIENT_DELETE_PARTICLESPAWNER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DeleteParticleSpawner }, // 0x53 + { "TOCLIENT_CLOUD_PARAMS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_CloudParams }, // 0x54 + { "TOCLIENT_FADE_SOUND", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_FadeSound }, // 0x55 + { "TOCLIENT_UPDATE_PLAYER_LIST", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_UpdatePlayerList }, // 0x56 + { "TOCLIENT_MODCHANNEL_MSG", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ModChannelMsg }, // 0x57 + { "TOCLIENT_MODCHANNEL_SIGNAL", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ModChannelSignal }, // 0x58 + { "TOCLIENT_NODEMETA_CHANGED", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_NodemetaChanged }, // 0x59 + { "TOCLIENT_SET_SUN", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudSetSun }, // 0x5a + { "TOCLIENT_SET_MOON", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudSetMoon }, // 0x5b + { "TOCLIENT_SET_STARS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudSetStars }, // 0x5c + null_command_handler, + null_command_handler, + null_command_handler, + { "TOCLIENT_SRP_BYTES_S_B", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_SrpBytesSandB }, // 0x60 + { "TOCLIENT_FORMSPEC_PREPEND", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_FormspecPrepend }, // 0x61, + { "TOCLIENT_MINIMAP_MODES", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_MinimapModes }, // 0x62, + { "TOCLIENT_SET_LIGHTING", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_SetLighting }, // 0x63, +}; + +const static ServerCommandFactory null_command_factory = { "TOSERVER_NULL", 0, false }; + +/* + Channels used for Client -> Server communication + 2: Notifications back to the server (e.g. GOTBLOCKS) + 1: Init and Authentication + 0: everything else + + Packet order is only guaranteed inside a channel, so packets that operate on + the same objects are *required* to be in the same channel. +*/ + +const ServerCommandFactory serverCommandFactoryTable[TOSERVER_NUM_MSG_TYPES] = +{ + null_command_factory, // 0x00 + null_command_factory, // 0x01 + { "TOSERVER_INIT", 1, false }, // 0x02 + null_command_factory, // 0x03 + null_command_factory, // 0x04 + null_command_factory, // 0x05 + null_command_factory, // 0x06 + null_command_factory, // 0x07 + null_command_factory, // 0x08 + null_command_factory, // 0x09 + null_command_factory, // 0x0a + null_command_factory, // 0x0b + null_command_factory, // 0x0c + null_command_factory, // 0x0d + null_command_factory, // 0x0e + null_command_factory, // 0x0f + null_command_factory, // 0x10 + { "TOSERVER_INIT2", 1, true }, // 0x11 + null_command_factory, // 0x12 + null_command_factory, // 0x13 + null_command_factory, // 0x14 + null_command_factory, // 0x15 + null_command_factory, // 0x16 + { "TOSERVER_MODCHANNEL_JOIN", 0, true }, // 0x17 + { "TOSERVER_MODCHANNEL_LEAVE", 0, true }, // 0x18 + { "TOSERVER_MODCHANNEL_MSG", 0, true }, // 0x19 + null_command_factory, // 0x1a + null_command_factory, // 0x1b + null_command_factory, // 0x1c + null_command_factory, // 0x1d + null_command_factory, // 0x1e + null_command_factory, // 0x1f + null_command_factory, // 0x20 + null_command_factory, // 0x21 + null_command_factory, // 0x22 + { "TOSERVER_PLAYERPOS", 0, false }, // 0x23 + { "TOSERVER_GOTBLOCKS", 2, true }, // 0x24 + { "TOSERVER_DELETEDBLOCKS", 2, true }, // 0x25 + null_command_factory, // 0x26 + null_command_factory, // 0x27 + null_command_factory, // 0x28 + null_command_factory, // 0x29 + null_command_factory, // 0x2a + null_command_factory, // 0x2b + null_command_factory, // 0x2c + null_command_factory, // 0x2d + null_command_factory, // 0x2e + null_command_factory, // 0x2f + null_command_factory, // 0x30 + { "TOSERVER_INVENTORY_ACTION", 0, true }, // 0x31 + { "TOSERVER_CHAT_MESSAGE", 0, true }, // 0x32 + null_command_factory, // 0x33 + null_command_factory, // 0x34 + { "TOSERVER_DAMAGE", 0, true }, // 0x35 + null_command_factory, // 0x36 + { "TOSERVER_PLAYERITEM", 0, true }, // 0x37 + { "TOSERVER_RESPAWN", 0, true }, // 0x38 + { "TOSERVER_INTERACT", 0, true }, // 0x39 + { "TOSERVER_REMOVED_SOUNDS", 2, true }, // 0x3a + { "TOSERVER_NODEMETA_FIELDS", 0, true }, // 0x3b + { "TOSERVER_INVENTORY_FIELDS", 0, true }, // 0x3c + null_command_factory, // 0x3d + null_command_factory, // 0x3e + null_command_factory, // 0x3f + { "TOSERVER_REQUEST_MEDIA", 1, true }, // 0x40 + { "TOSERVER_HAVE_MEDIA", 2, true }, // 0x41 + null_command_factory, // 0x42 + { "TOSERVER_CLIENT_READY", 1, true }, // 0x43 + null_command_factory, // 0x44 + null_command_factory, // 0x45 + null_command_factory, // 0x46 + null_command_factory, // 0x47 + null_command_factory, // 0x48 + null_command_factory, // 0x49 + null_command_factory, // 0x4a + null_command_factory, // 0x4b + null_command_factory, // 0x4c + null_command_factory, // 0x4d + null_command_factory, // 0x4e + null_command_factory, // 0x4f + { "TOSERVER_FIRST_SRP", 1, true }, // 0x50 + { "TOSERVER_SRP_BYTES_A", 1, true }, // 0x51 + { "TOSERVER_SRP_BYTES_M", 1, true }, // 0x52 +}; diff --git a/src/network/clientopcodes.h b/src/network/clientopcodes.h new file mode 100644 index 0000000..d03dc45 --- /dev/null +++ b/src/network/clientopcodes.h @@ -0,0 +1,50 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2015 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "client/client.h" +#include "networkprotocol.h" + +class NetworkPacket; + +enum ToClientConnectionState { + TOCLIENT_STATE_NOT_CONNECTED, + TOCLIENT_STATE_CONNECTED, + TOCLIENT_STATE_ALL, +}; + +struct ToClientCommandHandler +{ + const char* name; + ToClientConnectionState state; + void (Client::*handler)(NetworkPacket* pkt); +}; + +struct ServerCommandFactory +{ + const char* name; + u8 channel; + bool reliable; +}; + +extern const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES]; + +extern const ServerCommandFactory serverCommandFactoryTable[TOSERVER_NUM_MSG_TYPES]; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp new file mode 100644 index 0000000..25c1d26 --- /dev/null +++ b/src/network/clientpackethandler.cpp @@ -0,0 +1,1767 @@ +/* +Minetest +Copyright (C) 2015 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "client/client.h" + +#include "util/base64.h" +#include "client/camera.h" +#include "chatmessage.h" +#include "client/clientmedia.h" +#include "log.h" +#include "map.h" +#include "mapsector.h" +#include "client/minimap.h" +#include "modchannels.h" +#include "nodedef.h" +#include "serialization.h" +#include "server.h" +#include "util/strfnd.h" +#include "client/clientevent.h" +#include "client/sound.h" +#include "network/clientopcodes.h" +#include "network/connection.h" +#include "script/scripting_client.h" +#include "util/serialize.h" +#include "util/srp.h" +#include "util/sha1.h" +#include "tileanimation.h" +#include "gettext.h" +#include "skyparams.h" +#include <memory> + +void Client::handleCommand_Deprecated(NetworkPacket* pkt) +{ + infostream << "Got deprecated command " + << toClientCommandTable[pkt->getCommand()].name << " from peer " + << pkt->getPeerId() << "!" << std::endl; +} + +void Client::handleCommand_Hello(NetworkPacket* pkt) +{ + if (pkt->getSize() < 1) + return; + + u8 serialization_ver; + u16 proto_ver; + u16 compression_mode; + u32 auth_mechs; + std::string username_legacy; // for case insensitivity + *pkt >> serialization_ver >> compression_mode >> proto_ver + >> auth_mechs >> username_legacy; + + // Chose an auth method we support + AuthMechanism chosen_auth_mechanism = choseAuthMech(auth_mechs); + + infostream << "Client: TOCLIENT_HELLO received with " + << "serialization_ver=" << (u32)serialization_ver + << ", auth_mechs=" << auth_mechs + << ", proto_ver=" << proto_ver + << ", compression_mode=" << compression_mode + << ". Doing auth with mech " << chosen_auth_mechanism << std::endl; + + if (!ser_ver_supported(serialization_ver)) { + infostream << "Client: TOCLIENT_HELLO: Server sent " + << "unsupported ser_fmt_ver"<< std::endl; + return; + } + + m_server_ser_ver = serialization_ver; + m_proto_ver = proto_ver; + + //TODO verify that username_legacy matches sent username, only + // differs in casing (make both uppercase and compare) + // This is only neccessary though when we actually want to add casing support + + if (m_chosen_auth_mech != AUTH_MECHANISM_NONE) { + // we received a TOCLIENT_HELLO while auth was already going on + errorstream << "Client: TOCLIENT_HELLO while auth was already going on" + << "(chosen_mech=" << m_chosen_auth_mech << ")." << std::endl; + if (m_chosen_auth_mech == AUTH_MECHANISM_SRP || + m_chosen_auth_mech == AUTH_MECHANISM_LEGACY_PASSWORD) { + srp_user_delete((SRPUser *) m_auth_data); + m_auth_data = 0; + } + } + + // Authenticate using that method, or abort if there wasn't any method found + if (chosen_auth_mechanism != AUTH_MECHANISM_NONE) { + bool is_register = chosen_auth_mechanism == AUTH_MECHANISM_FIRST_SRP; + ELoginRegister mode = is_register ? ELoginRegister::Register : ELoginRegister::Login; + if (m_allow_login_or_register != ELoginRegister::Any && + m_allow_login_or_register != mode) { + m_chosen_auth_mech = AUTH_MECHANISM_NONE; + m_access_denied = true; + if (m_allow_login_or_register == ELoginRegister::Login) { + m_access_denied_reason = + gettext("Name is not registered. To create an account on this server, click 'Register'"); + } else { + m_access_denied_reason = + gettext("Name is taken. Please choose another name"); + } + m_con->Disconnect(); + } else { + startAuth(chosen_auth_mechanism); + } + } else { + m_chosen_auth_mech = AUTH_MECHANISM_NONE; + m_access_denied = true; + m_access_denied_reason = "Unknown"; + m_con->Disconnect(); + } + +} + +void Client::handleCommand_AuthAccept(NetworkPacket* pkt) +{ + deleteAuthData(); + + v3f playerpos; + *pkt >> playerpos >> m_map_seed >> m_recommended_send_interval + >> m_sudo_auth_methods; + + playerpos -= v3f(0, BS / 2, 0); + + // Set player position + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + player->setPosition(playerpos); + + infostream << "Client: received map seed: " << m_map_seed << std::endl; + infostream << "Client: received recommended send interval " + << m_recommended_send_interval<<std::endl; + + // Reply to server + /*~ DO NOT TRANSLATE THIS LITERALLY! + This is a special string which needs to contain the translation's + language code (e.g. "de" for German). */ + std::string lang = gettext("LANG_CODE"); + if (lang == "LANG_CODE") + lang = ""; + + NetworkPacket resp_pkt(TOSERVER_INIT2, sizeof(u16) + lang.size()); + resp_pkt << lang; + Send(&resp_pkt); + + m_state = LC_Init; +} +void Client::handleCommand_AcceptSudoMode(NetworkPacket* pkt) +{ + deleteAuthData(); + + m_password = m_new_password; + + verbosestream << "Client: Received TOCLIENT_ACCEPT_SUDO_MODE." << std::endl; + + // send packet to actually set the password + startAuth(AUTH_MECHANISM_FIRST_SRP); + + // reset again + m_chosen_auth_mech = AUTH_MECHANISM_NONE; +} +void Client::handleCommand_DenySudoMode(NetworkPacket* pkt) +{ + ChatMessage *chatMessage = new ChatMessage(CHATMESSAGE_TYPE_SYSTEM, + L"Password change denied. Password NOT changed."); + pushToChatQueue(chatMessage); + // reset everything and be sad + deleteAuthData(); +} + +void Client::handleCommand_AccessDenied(NetworkPacket* pkt) +{ + // The server didn't like our password. Note, this needs + // to be processed even if the serialisation format has + // not been agreed yet, the same as TOCLIENT_INIT. + m_access_denied = true; + m_access_denied_reason = "Unknown"; + + if (pkt->getCommand() != TOCLIENT_ACCESS_DENIED) { + // Legacy code from 0.4.12 and older but is still used + // in some places of the server code + if (pkt->getSize() >= 2) { + std::wstring wide_reason; + *pkt >> wide_reason; + m_access_denied_reason = wide_to_utf8(wide_reason); + } + return; + } + + if (pkt->getSize() < 1) + return; + + u8 denyCode; + *pkt >> denyCode; + + if (denyCode == SERVER_ACCESSDENIED_SHUTDOWN || + denyCode == SERVER_ACCESSDENIED_CRASH) { + *pkt >> m_access_denied_reason; + if (m_access_denied_reason.empty()) + m_access_denied_reason = accessDeniedStrings[denyCode]; + u8 reconnect; + *pkt >> reconnect; + m_access_denied_reconnect = reconnect & 1; + } else if (denyCode == SERVER_ACCESSDENIED_CUSTOM_STRING) { + *pkt >> m_access_denied_reason; + } else if (denyCode == SERVER_ACCESSDENIED_TOO_MANY_USERS) { + m_access_denied_reason = accessDeniedStrings[denyCode]; + m_access_denied_reconnect = true; + } else if (denyCode < SERVER_ACCESSDENIED_MAX) { + m_access_denied_reason = accessDeniedStrings[denyCode]; + } else { + // Allow us to add new error messages to the + // protocol without raising the protocol version, if we want to. + // Until then (which may be never), this is outside + // of the defined protocol. + *pkt >> m_access_denied_reason; + if (m_access_denied_reason.empty()) + m_access_denied_reason = "Unknown"; + } +} + +void Client::handleCommand_RemoveNode(NetworkPacket* pkt) +{ + if (pkt->getSize() < 6) + return; + + v3s16 p; + *pkt >> p; + removeNode(p); +} + +void Client::handleCommand_AddNode(NetworkPacket* pkt) +{ + if (pkt->getSize() < 6 + MapNode::serializedLength(m_server_ser_ver)) + return; + + v3s16 p; + *pkt >> p; + + MapNode n; + n.deSerialize(pkt->getU8Ptr(6), m_server_ser_ver); + + bool remove_metadata = true; + u32 index = 6 + MapNode::serializedLength(m_server_ser_ver); + if ((pkt->getSize() >= index + 1) && pkt->getU8(index)) { + remove_metadata = false; + } + + addNode(p, n, remove_metadata); +} + +void Client::handleCommand_NodemetaChanged(NetworkPacket *pkt) +{ + if (pkt->getSize() < 1) + return; + + std::istringstream is(pkt->readLongString(), std::ios::binary); + std::stringstream sstr(std::ios::binary | std::ios::in | std::ios::out); + decompressZlib(is, sstr); + + NodeMetadataList meta_updates_list(false); + meta_updates_list.deSerialize(sstr, m_itemdef, true); + + Map &map = m_env.getMap(); + for (NodeMetadataMap::const_iterator i = meta_updates_list.begin(); + i != meta_updates_list.end(); ++i) { + v3s16 pos = i->first; + + if (map.isValidPosition(pos) && + map.setNodeMetadata(pos, i->second)) + continue; // Prevent from deleting metadata + + // Meta couldn't be set, unused metadata + delete i->second; + } +} + +void Client::handleCommand_BlockData(NetworkPacket* pkt) +{ + // Ignore too small packet + if (pkt->getSize() < 6) + return; + + v3s16 p; + *pkt >> p; + + std::string datastring(pkt->getString(6), pkt->getSize() - 6); + std::istringstream istr(datastring, std::ios_base::binary); + + MapSector *sector; + MapBlock *block; + + v2s16 p2d(p.X, p.Z); + sector = m_env.getMap().emergeSector(p2d); + + assert(sector->getPos() == p2d); + + block = sector->getBlockNoCreateNoEx(p.Y); + if (block) { + /* + Update an existing block + */ + block->deSerialize(istr, m_server_ser_ver, false); + block->deSerializeNetworkSpecific(istr); + } + else { + /* + Create a new block + */ + block = new MapBlock(&m_env.getMap(), p, this); + block->deSerialize(istr, m_server_ser_ver, false); + block->deSerializeNetworkSpecific(istr); + sector->insertBlock(block); + } + + if (m_localdb) { + ServerMap::saveBlock(block, m_localdb); + } + + /* + Add it to mesh update queue and set it to be acknowledged after update. + */ + addUpdateMeshTaskWithEdge(p, true); +} + +void Client::handleCommand_Inventory(NetworkPacket* pkt) +{ + if (pkt->getSize() < 1) + return; + + std::string datastring(pkt->getString(0), pkt->getSize()); + std::istringstream is(datastring, std::ios_base::binary); + + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + player->inventory.deSerialize(is); + + m_update_wielded_item = true; + + delete m_inventory_from_server; + m_inventory_from_server = new Inventory(player->inventory); + m_inventory_from_server_age = 0.0; +} + +void Client::handleCommand_TimeOfDay(NetworkPacket* pkt) +{ + if (pkt->getSize() < 2) + return; + + u16 time_of_day; + + *pkt >> time_of_day; + + time_of_day = time_of_day % 24000; + float time_speed = 0; + + if (pkt->getSize() >= 2 + 4) { + *pkt >> time_speed; + } + else { + // Old message; try to approximate speed of time by ourselves + float time_of_day_f = (float)time_of_day / 24000.0f; + float tod_diff_f = 0; + + if (time_of_day_f < 0.2 && m_last_time_of_day_f > 0.8) + tod_diff_f = time_of_day_f - m_last_time_of_day_f + 1.0f; + else + tod_diff_f = time_of_day_f - m_last_time_of_day_f; + + m_last_time_of_day_f = time_of_day_f; + float time_diff = m_time_of_day_update_timer; + m_time_of_day_update_timer = 0; + + if (m_time_of_day_set) { + time_speed = (3600.0f * 24.0f) * tod_diff_f / time_diff; + infostream << "Client: Measured time_of_day speed (old format): " + << time_speed << " tod_diff_f=" << tod_diff_f + << " time_diff=" << time_diff << std::endl; + } + } + + // Update environment + m_env.setTimeOfDay(time_of_day); + m_env.setTimeOfDaySpeed(time_speed); + m_time_of_day_set = true; + + //u32 dr = m_env.getDayNightRatio(); + //infostream << "Client: time_of_day=" << time_of_day + // << " time_speed=" << time_speed + // << " dr=" << dr << std::endl; +} + +void Client::handleCommand_ChatMessage(NetworkPacket *pkt) +{ + /* + u8 version + u8 message_type + u16 sendername length + wstring sendername + u16 length + wstring message + */ + + ChatMessage *chatMessage = new ChatMessage(); + u8 version, message_type; + *pkt >> version >> message_type; + + if (version != 1 || message_type >= CHATMESSAGE_TYPE_MAX) { + delete chatMessage; + return; + } + + u64 timestamp; + *pkt >> chatMessage->sender >> chatMessage->message >> timestamp; + chatMessage->timestamp = static_cast<std::time_t>(timestamp); + + chatMessage->type = (ChatMessageType) message_type; + + // @TODO send this to CSM using ChatMessage object + if (modsLoaded() && m_script->on_receiving_message( + wide_to_utf8(chatMessage->message))) { + // Message was consumed by CSM and should not be handled by client + delete chatMessage; + } else { + pushToChatQueue(chatMessage); + } +} + +void Client::handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt) +{ + /* + u16 count of removed objects + for all removed objects { + u16 id + } + u16 count of added objects + for all added objects { + u16 id + u8 type + u32 initialization data length + string initialization data + } + */ + + try { + u8 type; + u16 removed_count, added_count, id; + + // Read removed objects + *pkt >> removed_count; + + for (u16 i = 0; i < removed_count; i++) { + *pkt >> id; + m_env.removeActiveObject(id); + } + + // Read added objects + *pkt >> added_count; + + for (u16 i = 0; i < added_count; i++) { + *pkt >> id >> type; + m_env.addActiveObject(id, type, pkt->readLongString()); + } + } catch (PacketError &e) { + infostream << "handleCommand_ActiveObjectRemoveAdd: " << e.what() + << ". The packet is unreliable, ignoring" << std::endl; + } + + // m_activeobjects_received is false before the first + // TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD packet is received + m_activeobjects_received = true; +} + +void Client::handleCommand_ActiveObjectMessages(NetworkPacket* pkt) +{ + /* + for all objects + { + u16 id + u16 message length + string message + } + */ + std::string datastring(pkt->getString(0), pkt->getSize()); + std::istringstream is(datastring, std::ios_base::binary); + + try { + while (is.good()) { + u16 id = readU16(is); + if (!is.good()) + break; + + std::string message = deSerializeString16(is); + + // Pass on to the environment + m_env.processActiveObjectMessage(id, message); + } + } catch (SerializationError &e) { + errorstream << "Client::handleCommand_ActiveObjectMessages: " + << "caught SerializationError: " << e.what() << std::endl; + } +} + +void Client::handleCommand_Movement(NetworkPacket* pkt) +{ + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + float mad, maa, maf, msw, mscr, msf, mscl, msj, lf, lfs, ls, g; + + *pkt >> mad >> maa >> maf >> msw >> mscr >> msf >> mscl >> msj + >> lf >> lfs >> ls >> g; + + player->movement_acceleration_default = mad * BS; + player->movement_acceleration_air = maa * BS; + player->movement_acceleration_fast = maf * BS; + player->movement_speed_walk = msw * BS; + player->movement_speed_crouch = mscr * BS; + player->movement_speed_fast = msf * BS; + player->movement_speed_climb = mscl * BS; + player->movement_speed_jump = msj * BS; + player->movement_liquid_fluidity = lf * BS; + player->movement_liquid_fluidity_smooth = lfs * BS; + player->movement_liquid_sink = ls * BS; + player->movement_gravity = g * BS; +} + +void Client::handleCommand_Fov(NetworkPacket *pkt) +{ + f32 fov; + bool is_multiplier = false; + f32 transition_time = 0.0f; + + *pkt >> fov >> is_multiplier; + + // Wrap transition_time extraction within a + // try-catch to preserve backwards compat + try { + *pkt >> transition_time; + } catch (PacketError &e) {}; + + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player); + player->setFov({ fov, is_multiplier, transition_time }); + m_camera->notifyFovChange(); +} + +void Client::handleCommand_HP(NetworkPacket *pkt) +{ + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + u16 oldhp = player->hp; + + u16 hp; + *pkt >> hp; + bool damage_effect = true; + try { + *pkt >> damage_effect; + } catch (PacketError &e) {}; + + player->hp = hp; + + if (modsLoaded()) + m_script->on_hp_modification(hp); + + if (hp < oldhp) { + // Add to ClientEvent queue + ClientEvent *event = new ClientEvent(); + event->type = CE_PLAYER_DAMAGE; + event->player_damage.amount = oldhp - hp; + event->player_damage.effect = damage_effect; + m_client_event_queue.push(event); + } +} + +void Client::handleCommand_Breath(NetworkPacket* pkt) +{ + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + u16 breath; + + *pkt >> breath; + + player->setBreath(breath); +} + +void Client::handleCommand_MovePlayer(NetworkPacket* pkt) +{ + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + v3f pos; + f32 pitch, yaw; + + *pkt >> pos >> pitch >> yaw; + + player->setPosition(pos); + + infostream << "Client got TOCLIENT_MOVE_PLAYER" + << " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")" + << " pitch=" << pitch + << " yaw=" << yaw + << std::endl; + + /* + Add to ClientEvent queue. + This has to be sent to the main program because otherwise + it would just force the pitch and yaw values to whatever + the camera points to. + */ + ClientEvent *event = new ClientEvent(); + event->type = CE_PLAYER_FORCE_MOVE; + event->player_force_move.pitch = pitch; + event->player_force_move.yaw = yaw; + m_client_event_queue.push(event); +} + +void Client::handleCommand_DeathScreen(NetworkPacket* pkt) +{ + bool set_camera_point_target; + v3f camera_point_target; + + *pkt >> set_camera_point_target; + *pkt >> camera_point_target; + + ClientEvent *event = new ClientEvent(); + event->type = CE_DEATHSCREEN; + event->deathscreen.set_camera_point_target = set_camera_point_target; + event->deathscreen.camera_point_target_x = camera_point_target.X; + event->deathscreen.camera_point_target_y = camera_point_target.Y; + event->deathscreen.camera_point_target_z = camera_point_target.Z; + m_client_event_queue.push(event); +} + +void Client::handleCommand_AnnounceMedia(NetworkPacket* pkt) +{ + u16 num_files; + + *pkt >> num_files; + + infostream << "Client: Received media announcement: packet size: " + << pkt->getSize() << std::endl; + + if (m_media_downloader == NULL || + m_media_downloader->isStarted()) { + const char *problem = m_media_downloader ? + "we already saw another announcement" : + "all media has been received already"; + errorstream << "Client: Received media announcement but " + << problem << "! " + << " files=" << num_files + << " size=" << pkt->getSize() << std::endl; + return; + } + + // Mesh update thread must be stopped while + // updating content definitions + sanity_check(!m_mesh_update_thread.isRunning()); + + for (u16 i = 0; i < num_files; i++) { + std::string name, sha1_base64; + + *pkt >> name >> sha1_base64; + + std::string sha1_raw = base64_decode(sha1_base64); + m_media_downloader->addFile(name, sha1_raw); + } + + { + std::string str; + *pkt >> str; + + Strfnd sf(str); + while (!sf.at_end()) { + std::string baseurl = trim(sf.next(",")); + if (!baseurl.empty()) { + m_remote_media_servers.emplace_back(baseurl); + m_media_downloader->addRemoteServer(baseurl); + } + } + } + + m_media_downloader->step(this); +} + +void Client::handleCommand_Media(NetworkPacket* pkt) +{ + /* + u16 command + u16 total number of file bunches + u16 index of this bunch + u32 number of files in this bunch + for each file { + u16 length of name + string name + u32 length of data + data + } + */ + u16 num_bunches; + u16 bunch_i; + u32 num_files; + + *pkt >> num_bunches >> bunch_i >> num_files; + + infostream << "Client: Received files: bunch " << bunch_i << "/" + << num_bunches << " files=" << num_files + << " size=" << pkt->getSize() << std::endl; + + if (num_files == 0) + return; + + bool init_phase = m_media_downloader && m_media_downloader->isStarted(); + + if (init_phase) { + // Mesh update thread must be stopped while + // updating content definitions + sanity_check(!m_mesh_update_thread.isRunning()); + } + + for (u32 i = 0; i < num_files; i++) { + std::string name, data; + + *pkt >> name; + data = pkt->readLongString(); + + bool ok = false; + if (init_phase) { + ok = m_media_downloader->conventionalTransferDone(name, data, this); + } else { + // Check pending dynamic transfers, one of them must be it + for (const auto &it : m_pending_media_downloads) { + if (it.second->conventionalTransferDone(name, data, this)) { + ok = true; + break; + } + } + } + if (!ok) { + errorstream << "Client: Received media \"" << name + << "\" but no downloads pending. " << num_bunches << " bunches, " + << num_files << " in this one. (init_phase=" << init_phase + << ")" << std::endl; + } + } +} + +void Client::handleCommand_NodeDef(NetworkPacket* pkt) +{ + infostream << "Client: Received node definitions: packet size: " + << pkt->getSize() << std::endl; + + // Mesh update thread must be stopped while + // updating content definitions + sanity_check(!m_mesh_update_thread.isRunning()); + + // Decompress node definitions + std::istringstream tmp_is(pkt->readLongString(), std::ios::binary); + std::stringstream tmp_os(std::ios::binary | std::ios::in | std::ios::out); + decompressZlib(tmp_is, tmp_os); + + // Deserialize node definitions + m_nodedef->deSerialize(tmp_os, m_proto_ver); + m_nodedef_received = true; +} + +void Client::handleCommand_ItemDef(NetworkPacket* pkt) +{ + infostream << "Client: Received item definitions: packet size: " + << pkt->getSize() << std::endl; + + // Mesh update thread must be stopped while + // updating content definitions + sanity_check(!m_mesh_update_thread.isRunning()); + + // Decompress item definitions + std::istringstream tmp_is(pkt->readLongString(), std::ios::binary); + std::stringstream tmp_os(std::ios::binary | std::ios::in | std::ios::out); + decompressZlib(tmp_is, tmp_os); + + // Deserialize node definitions + m_itemdef->deSerialize(tmp_os, m_proto_ver); + m_itemdef_received = true; +} + +void Client::handleCommand_PlaySound(NetworkPacket* pkt) +{ + /* + [0] u32 server_id + [4] u16 name length + [6] char name[len] + [ 6 + len] f32 gain + [10 + len] u8 type + [11 + len] (f32 * 3) pos + [23 + len] u16 object_id + [25 + len] bool loop + [26 + len] f32 fade + [30 + len] f32 pitch + [34 + len] bool ephemeral + */ + + s32 server_id; + + SimpleSoundSpec spec; + SoundLocation type; // 0=local, 1=positional, 2=object + v3f pos; + u16 object_id; + bool ephemeral = false; + + *pkt >> server_id >> spec.name >> spec.gain >> (u8 &)type >> pos >> object_id >> spec.loop; + + try { + *pkt >> spec.fade; + *pkt >> spec.pitch; + *pkt >> ephemeral; + } catch (PacketError &e) {}; + + // Start playing + int client_id = -1; + switch(type) { + case SoundLocation::Local: + client_id = m_sound->playSound(spec); + break; + case SoundLocation::Position: + client_id = m_sound->playSoundAt(spec, pos); + break; + case SoundLocation::Object: + { + ClientActiveObject *cao = m_env.getActiveObject(object_id); + if (cao) + pos = cao->getPosition(); + client_id = m_sound->playSoundAt(spec, pos); + break; + } + } + + if (client_id != -1) { + // for ephemeral sounds, server_id is not meaningful + if (!ephemeral) { + m_sounds_server_to_client[server_id] = client_id; + m_sounds_client_to_server[client_id] = server_id; + } + if (object_id != 0) + m_sounds_to_objects[client_id] = object_id; + } +} + +void Client::handleCommand_StopSound(NetworkPacket* pkt) +{ + s32 server_id; + + *pkt >> server_id; + + std::unordered_map<s32, int>::iterator i = m_sounds_server_to_client.find(server_id); + if (i != m_sounds_server_to_client.end()) { + int client_id = i->second; + m_sound->stopSound(client_id); + } +} + +void Client::handleCommand_FadeSound(NetworkPacket *pkt) +{ + s32 sound_id; + float step; + float gain; + + *pkt >> sound_id >> step >> gain; + + std::unordered_map<s32, int>::const_iterator i = + m_sounds_server_to_client.find(sound_id); + + if (i != m_sounds_server_to_client.end()) + m_sound->fadeSound(i->second, step, gain); +} + +void Client::handleCommand_Privileges(NetworkPacket* pkt) +{ + m_privileges.clear(); + infostream << "Client: Privileges updated: "; + u16 num_privileges; + + *pkt >> num_privileges; + + for (u16 i = 0; i < num_privileges; i++) { + std::string priv; + + *pkt >> priv; + + m_privileges.insert(priv); + infostream << priv << " "; + } + infostream << std::endl; +} + +void Client::handleCommand_InventoryFormSpec(NetworkPacket* pkt) +{ + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + // Store formspec in LocalPlayer + player->inventory_formspec = pkt->readLongString(); +} + +void Client::handleCommand_DetachedInventory(NetworkPacket* pkt) +{ + std::string name; + bool keep_inv = true; + *pkt >> name >> keep_inv; + + infostream << "Client: Detached inventory update: \"" << name + << "\", mode=" << (keep_inv ? "update" : "remove") << std::endl; + + const auto &inv_it = m_detached_inventories.find(name); + if (!keep_inv) { + if (inv_it != m_detached_inventories.end()) { + delete inv_it->second; + m_detached_inventories.erase(inv_it); + } + return; + } + Inventory *inv = nullptr; + if (inv_it == m_detached_inventories.end()) { + inv = new Inventory(m_itemdef); + m_detached_inventories[name] = inv; + } else { + inv = inv_it->second; + } + + u16 ignore; + *pkt >> ignore; // this used to be the length of the following string, ignore it + + std::string contents(pkt->getRemainingString(), pkt->getRemainingBytes()); + std::istringstream is(contents, std::ios::binary); + inv->deSerialize(is); +} + +void Client::handleCommand_ShowFormSpec(NetworkPacket* pkt) +{ + std::string formspec = pkt->readLongString(); + std::string formname; + + *pkt >> formname; + + ClientEvent *event = new ClientEvent(); + event->type = CE_SHOW_FORMSPEC; + // pointer is required as event is a struct only! + // adding a std:string to a struct isn't possible + event->show_formspec.formspec = new std::string(formspec); + event->show_formspec.formname = new std::string(formname); + m_client_event_queue.push(event); +} + +void Client::handleCommand_SpawnParticle(NetworkPacket* pkt) +{ + std::string datastring(pkt->getString(0), pkt->getSize()); + std::istringstream is(datastring, std::ios_base::binary); + + ParticleParameters p; + p.deSerialize(is, m_proto_ver); + + ClientEvent *event = new ClientEvent(); + event->type = CE_SPAWN_PARTICLE; + event->spawn_particle = new ParticleParameters(p); + + m_client_event_queue.push(event); +} + +void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) +{ + std::string datastring(pkt->getString(0), pkt->getSize()); + std::istringstream is(datastring, std::ios_base::binary); + + ParticleSpawnerParameters p; + u32 server_id; + u16 attached_id = 0; + + p.amount = readU16(is); + p.time = readF32(is); + + // older protocols do not support tweening, and send only + // static ranges, so we can't just use the normal serialization + // functions for the older values. + p.pos.start.legacyDeSerialize(is); + p.vel.start.legacyDeSerialize(is); + p.acc.start.legacyDeSerialize(is); + p.exptime.start.legacyDeSerialize(is); + p.size.start.legacyDeSerialize(is); + + p.collisiondetection = readU8(is); + p.texture.string = deSerializeString32(is); + + server_id = readU32(is); + + p.vertical = readU8(is); + p.collision_removal = readU8(is); + + attached_id = readU16(is); + + p.animation.deSerialize(is, m_proto_ver); + p.glow = readU8(is); + p.object_collision = readU8(is); + + bool legacy_format = true; + + // This is kinda awful + do { + u16 tmp_param0 = readU16(is); + if (is.eof()) + break; + p.node.param0 = tmp_param0; + p.node.param2 = readU8(is); + p.node_tile = readU8(is); + + // v >= 5.6.0 + f32 tmp_sbias = readF32(is); + if (is.eof()) + break; + + // initial bias must be stored separately in the stream to preserve + // backwards compatibility with older clients, which do not support + // a bias field in their range "format" + p.pos.start.bias = tmp_sbias; + p.vel.start.bias = readF32(is); + p.acc.start.bias = readF32(is); + p.exptime.start.bias = readF32(is); + p.size.start.bias = readF32(is); + + p.pos.end.deSerialize(is); + p.vel.end.deSerialize(is); + p.acc.end.deSerialize(is); + p.exptime.end.deSerialize(is); + p.size.end.deSerialize(is); + + // properties for legacy texture field + p.texture.deSerialize(is, m_proto_ver, true); + + p.drag.deSerialize(is); + p.jitter.deSerialize(is); + p.bounce.deSerialize(is); + ParticleParamTypes::deSerializeParameterValue(is, p.attractor_kind); + using ParticleParamTypes::AttractorKind; + if (p.attractor_kind != AttractorKind::none) { + p.attract.deSerialize(is); + p.attractor_origin.deSerialize(is); + p.attractor_attachment = readU16(is); + /* we only check the first bit, in order to allow this value + * to be turned into a bit flag field later if needed */ + p.attractor_kill = !!(readU8(is) & 1); + if (p.attractor_kind != AttractorKind::point) { + p.attractor_direction.deSerialize(is); + p.attractor_direction_attachment = readU16(is); + } + } + p.radius.deSerialize(is); + + u16 texpoolsz = readU16(is); + p.texpool.reserve(texpoolsz); + for (u16 i = 0; i < texpoolsz; ++i) { + ServerParticleTexture newtex; + newtex.deSerialize(is, m_proto_ver); + p.texpool.push_back(newtex); + } + + legacy_format = false; + } while(0); + + if (legacy_format) { + // there's no tweening data to be had, so we need to set the + // legacy params to constant values, otherwise everything old + // will tween to zero + p.pos.end = p.pos.start; + p.vel.end = p.vel.start; + p.acc.end = p.acc.start; + p.exptime.end = p.exptime.start; + p.size.end = p.size.start; + } + + auto event = new ClientEvent(); + event->type = CE_ADD_PARTICLESPAWNER; + event->add_particlespawner.p = new ParticleSpawnerParameters(p); + event->add_particlespawner.attached_id = attached_id; + event->add_particlespawner.id = server_id; + + m_client_event_queue.push(event); +} + + +void Client::handleCommand_DeleteParticleSpawner(NetworkPacket* pkt) +{ + u32 server_id; + *pkt >> server_id; + + ClientEvent *event = new ClientEvent(); + event->type = CE_DELETE_PARTICLESPAWNER; + event->delete_particlespawner.id = server_id; + + m_client_event_queue.push(event); +} + +void Client::handleCommand_HudAdd(NetworkPacket* pkt) +{ + u32 server_id; + u8 type; + v2f pos; + std::string name; + v2f scale; + std::string text; + u32 number; + u32 item; + u32 dir; + v2f align; + v2f offset; + v3f world_pos; + v2s32 size; + s16 z_index = 0; + std::string text2; + u32 style = 0; + + *pkt >> server_id >> type >> pos >> name >> scale >> text >> number >> item + >> dir >> align >> offset; + try { + *pkt >> world_pos; + *pkt >> size; + *pkt >> z_index; + *pkt >> text2; + *pkt >> style; + } catch(PacketError &e) {}; + + ClientEvent *event = new ClientEvent(); + event->type = CE_HUDADD; + event->hudadd = new ClientEventHudAdd(); + event->hudadd->server_id = server_id; + event->hudadd->type = type; + event->hudadd->pos = pos; + event->hudadd->name = name; + event->hudadd->scale = scale; + event->hudadd->text = text; + event->hudadd->number = number; + event->hudadd->item = item; + event->hudadd->dir = dir; + event->hudadd->align = align; + event->hudadd->offset = offset; + event->hudadd->world_pos = world_pos; + event->hudadd->size = size; + event->hudadd->z_index = z_index; + event->hudadd->text2 = text2; + event->hudadd->style = style; + m_client_event_queue.push(event); +} + +void Client::handleCommand_HudRemove(NetworkPacket* pkt) +{ + u32 server_id; + + *pkt >> server_id; + + ClientEvent *event = new ClientEvent(); + event->type = CE_HUDRM; + event->hudrm.id = server_id; + m_client_event_queue.push(event); +} + +void Client::handleCommand_HudChange(NetworkPacket* pkt) +{ + std::string sdata; + v2f v2fdata; + v3f v3fdata; + u32 intdata = 0; + v2s32 v2s32data; + u32 server_id; + u8 stat; + + *pkt >> server_id >> stat; + + // Keep in sync with:server.cpp -> SendHUDChange + switch ((HudElementStat)stat) { + case HUD_STAT_POS: + case HUD_STAT_SCALE: + case HUD_STAT_ALIGN: + case HUD_STAT_OFFSET: + *pkt >> v2fdata; + break; + case HUD_STAT_NAME: + case HUD_STAT_TEXT: + case HUD_STAT_TEXT2: + *pkt >> sdata; + break; + case HUD_STAT_WORLD_POS: + *pkt >> v3fdata; + break; + case HUD_STAT_SIZE: + *pkt >> v2s32data; + break; + default: + *pkt >> intdata; + break; + } + + ClientEvent *event = new ClientEvent(); + event->type = CE_HUDCHANGE; + event->hudchange = new ClientEventHudChange(); + event->hudchange->id = server_id; + event->hudchange->stat = static_cast<HudElementStat>(stat); + event->hudchange->v2fdata = v2fdata; + event->hudchange->v3fdata = v3fdata; + event->hudchange->sdata = sdata; + event->hudchange->data = intdata; + event->hudchange->v2s32data = v2s32data; + m_client_event_queue.push(event); +} + +void Client::handleCommand_HudSetFlags(NetworkPacket* pkt) +{ + u32 flags, mask; + + *pkt >> flags >> mask; + + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + bool was_minimap_visible = player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE; + bool was_minimap_radar_visible = player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE; + + player->hud_flags &= ~mask; + player->hud_flags |= flags; + + m_minimap_disabled_by_server = !(player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE); + bool m_minimap_radar_disabled_by_server = !(player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE); + + // Not so satisying code to keep compatibility with old fixed mode system + // --> + + // Hide minimap if it has been disabled by the server + if (m_minimap && m_minimap_disabled_by_server && was_minimap_visible) + // defers a minimap update, therefore only call it if really + // needed, by checking that minimap was visible before + m_minimap->setModeIndex(0); + + // If radar has been disabled, try to find a non radar mode or fall back to 0 + if (m_minimap && m_minimap_radar_disabled_by_server + && was_minimap_radar_visible) { + while (m_minimap->getModeIndex() > 0 && + m_minimap->getModeDef().type == MINIMAP_TYPE_RADAR) + m_minimap->nextMode(); + } + // <-- + // End of 'not so satifying code' +} + +void Client::handleCommand_HudSetParam(NetworkPacket* pkt) +{ + u16 param; std::string value; + + *pkt >> param >> value; + + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + if (param == HUD_PARAM_HOTBAR_ITEMCOUNT && value.size() == 4) { + s32 hotbar_itemcount = readS32((u8*) value.c_str()); + if (hotbar_itemcount > 0 && hotbar_itemcount <= HUD_HOTBAR_ITEMCOUNT_MAX) + player->hud_hotbar_itemcount = hotbar_itemcount; + } + else if (param == HUD_PARAM_HOTBAR_IMAGE) { + player->hotbar_image = value; + } + else if (param == HUD_PARAM_HOTBAR_SELECTED_IMAGE) { + player->hotbar_selected_image = value; + } +} + +void Client::handleCommand_HudSetSky(NetworkPacket* pkt) +{ + if (m_proto_ver < 39) { + // Handle Protocol 38 and below servers with old set_sky, + // ensuring the classic look is kept. + std::string datastring(pkt->getString(0), pkt->getSize()); + std::istringstream is(datastring, std::ios_base::binary); + + SkyboxParams skybox; + skybox.bgcolor = video::SColor(readARGB8(is)); + skybox.type = std::string(deSerializeString16(is)); + u16 count = readU16(is); + + for (size_t i = 0; i < count; i++) + skybox.textures.emplace_back(deSerializeString16(is)); + + skybox.clouds = true; + try { + skybox.clouds = readU8(is); + } catch (...) {} + + // Use default skybox settings: + SunParams sun = SkyboxDefaults::getSunDefaults(); + MoonParams moon = SkyboxDefaults::getMoonDefaults(); + StarParams stars = SkyboxDefaults::getStarDefaults(); + + // Fix for "regular" skies, as color isn't kept: + if (skybox.type == "regular") { + skybox.sky_color = SkyboxDefaults::getSkyColorDefaults(); + skybox.fog_tint_type = "default"; + skybox.fog_moon_tint = video::SColor(255, 255, 255, 255); + skybox.fog_sun_tint = video::SColor(255, 255, 255, 255); + } else { + sun.visible = false; + sun.sunrise_visible = false; + moon.visible = false; + stars.visible = false; + } + + // Skybox, sun, moon and stars ClientEvents: + ClientEvent *sky_event = new ClientEvent(); + sky_event->type = CE_SET_SKY; + sky_event->set_sky = new SkyboxParams(skybox); + m_client_event_queue.push(sky_event); + + ClientEvent *sun_event = new ClientEvent(); + sun_event->type = CE_SET_SUN; + sun_event->sun_params = new SunParams(sun); + m_client_event_queue.push(sun_event); + + ClientEvent *moon_event = new ClientEvent(); + moon_event->type = CE_SET_MOON; + moon_event->moon_params = new MoonParams(moon); + m_client_event_queue.push(moon_event); + + ClientEvent *star_event = new ClientEvent(); + star_event->type = CE_SET_STARS; + star_event->star_params = new StarParams(stars); + m_client_event_queue.push(star_event); + } else { + SkyboxParams skybox; + u16 texture_count; + std::string texture; + + *pkt >> skybox.bgcolor >> skybox.type >> skybox.clouds >> + skybox.fog_sun_tint >> skybox.fog_moon_tint >> skybox.fog_tint_type; + + if (skybox.type == "skybox") { + *pkt >> texture_count; + for (int i = 0; i < texture_count; i++) { + *pkt >> texture; + skybox.textures.emplace_back(texture); + } + } + else if (skybox.type == "regular") { + *pkt >> skybox.sky_color.day_sky >> skybox.sky_color.day_horizon + >> skybox.sky_color.dawn_sky >> skybox.sky_color.dawn_horizon + >> skybox.sky_color.night_sky >> skybox.sky_color.night_horizon + >> skybox.sky_color.indoors; + } + + ClientEvent *event = new ClientEvent(); + event->type = CE_SET_SKY; + event->set_sky = new SkyboxParams(skybox); + m_client_event_queue.push(event); + } +} + +void Client::handleCommand_HudSetSun(NetworkPacket *pkt) +{ + SunParams sun; + + *pkt >> sun.visible >> sun.texture>> sun.tonemap + >> sun.sunrise >> sun.sunrise_visible >> sun.scale; + + ClientEvent *event = new ClientEvent(); + event->type = CE_SET_SUN; + event->sun_params = new SunParams(sun); + m_client_event_queue.push(event); +} + +void Client::handleCommand_HudSetMoon(NetworkPacket *pkt) +{ + MoonParams moon; + + *pkt >> moon.visible >> moon.texture + >> moon.tonemap >> moon.scale; + + ClientEvent *event = new ClientEvent(); + event->type = CE_SET_MOON; + event->moon_params = new MoonParams(moon); + m_client_event_queue.push(event); +} + +void Client::handleCommand_HudSetStars(NetworkPacket *pkt) +{ + StarParams stars = SkyboxDefaults::getStarDefaults(); + + *pkt >> stars.visible >> stars.count + >> stars.starcolor >> stars.scale; + try { + *pkt >> stars.day_opacity; + } catch (PacketError &e) {}; + + ClientEvent *event = new ClientEvent(); + event->type = CE_SET_STARS; + event->star_params = new StarParams(stars); + + m_client_event_queue.push(event); +} + +void Client::handleCommand_CloudParams(NetworkPacket* pkt) +{ + f32 density; + video::SColor color_bright; + video::SColor color_ambient; + f32 height; + f32 thickness; + v2f speed; + + *pkt >> density >> color_bright >> color_ambient + >> height >> thickness >> speed; + + ClientEvent *event = new ClientEvent(); + event->type = CE_CLOUD_PARAMS; + event->cloud_params.density = density; + // use the underlying u32 representation, because we can't + // use struct members with constructors here, and this way + // we avoid using new() and delete() for no good reason + event->cloud_params.color_bright = color_bright.color; + event->cloud_params.color_ambient = color_ambient.color; + event->cloud_params.height = height; + event->cloud_params.thickness = thickness; + // same here: deconstruct to skip constructor + event->cloud_params.speed_x = speed.X; + event->cloud_params.speed_y = speed.Y; + m_client_event_queue.push(event); +} + +void Client::handleCommand_OverrideDayNightRatio(NetworkPacket* pkt) +{ + bool do_override; + u16 day_night_ratio_u; + + *pkt >> do_override >> day_night_ratio_u; + + float day_night_ratio_f = (float)day_night_ratio_u / 65536; + + ClientEvent *event = new ClientEvent(); + event->type = CE_OVERRIDE_DAY_NIGHT_RATIO; + event->override_day_night_ratio.do_override = do_override; + event->override_day_night_ratio.ratio_f = day_night_ratio_f; + m_client_event_queue.push(event); +} + +void Client::handleCommand_LocalPlayerAnimations(NetworkPacket* pkt) +{ + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + *pkt >> player->local_animations[0]; + *pkt >> player->local_animations[1]; + *pkt >> player->local_animations[2]; + *pkt >> player->local_animations[3]; + *pkt >> player->local_animation_speed; + + player->last_animation = -1; +} + +void Client::handleCommand_EyeOffset(NetworkPacket* pkt) +{ + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + *pkt >> player->eye_offset_first >> player->eye_offset_third; +} + +void Client::handleCommand_UpdatePlayerList(NetworkPacket* pkt) +{ + u8 type; + u16 num_players; + *pkt >> type >> num_players; + PlayerListModifer notice_type = (PlayerListModifer) type; + + for (u16 i = 0; i < num_players; i++) { + std::string name; + *pkt >> name; + switch (notice_type) { + case PLAYER_LIST_INIT: + case PLAYER_LIST_ADD: + m_env.addPlayerName(name); + continue; + case PLAYER_LIST_REMOVE: + m_env.removePlayerName(name); + continue; + } + } +} + +void Client::handleCommand_SrpBytesSandB(NetworkPacket* pkt) +{ + if (m_chosen_auth_mech != AUTH_MECHANISM_SRP && + m_chosen_auth_mech != AUTH_MECHANISM_LEGACY_PASSWORD) { + errorstream << "Client: Received SRP S_B login message," + << " but wasn't supposed to (chosen_mech=" + << m_chosen_auth_mech << ")." << std::endl; + return; + } + + char *bytes_M = 0; + size_t len_M = 0; + SRPUser *usr = (SRPUser *) m_auth_data; + std::string s; + std::string B; + *pkt >> s >> B; + + infostream << "Client: Received TOCLIENT_SRP_BYTES_S_B." << std::endl; + + srp_user_process_challenge(usr, (const unsigned char *) s.c_str(), s.size(), + (const unsigned char *) B.c_str(), B.size(), + (unsigned char **) &bytes_M, &len_M); + + if ( !bytes_M ) { + errorstream << "Client: SRP-6a S_B safety check violation!" << std::endl; + return; + } + + NetworkPacket resp_pkt(TOSERVER_SRP_BYTES_M, 0); + resp_pkt << std::string(bytes_M, len_M); + Send(&resp_pkt); +} + +void Client::handleCommand_FormspecPrepend(NetworkPacket *pkt) +{ + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + // Store formspec in LocalPlayer + *pkt >> player->formspec_prepend; +} + +void Client::handleCommand_CSMRestrictionFlags(NetworkPacket *pkt) +{ + *pkt >> m_csm_restriction_flags >> m_csm_restriction_noderange; + + // Restrictions were received -> load mods if it's enabled + // Note: this should be moved after mods receptions from server instead + loadMods(); +} + +void Client::handleCommand_PlayerSpeed(NetworkPacket *pkt) +{ + v3f added_vel; + + *pkt >> added_vel; + + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + player->addVelocity(added_vel); +} + +void Client::handleCommand_MediaPush(NetworkPacket *pkt) +{ + std::string raw_hash, filename, filedata; + u32 token; + bool cached; + + *pkt >> raw_hash >> filename >> cached; + if (m_proto_ver >= 40) + *pkt >> token; + else + filedata = pkt->readLongString(); + + if (raw_hash.size() != 20 || filename.empty() || + (m_proto_ver < 40 && filedata.empty()) || + !string_allowed(filename, TEXTURENAME_ALLOWED_CHARS)) { + throw PacketError("Illegal filename, data or hash"); + } + + verbosestream << "Server pushes media file \"" << filename << "\" "; + if (filedata.empty()) + verbosestream << "to be fetched "; + else + verbosestream << "with " << filedata.size() << " bytes "; + verbosestream << "(cached=" << cached << ")" << std::endl; + + if (m_media_pushed_files.count(filename) != 0) { + // Ignore (but acknowledge). Previously this was for sync purposes, + // but even in new versions media cannot be replaced at runtime. + if (m_proto_ver >= 40) + sendHaveMedia({ token }); + return; + } + + if (!filedata.empty()) { + // LEGACY CODEPATH + // Compute and check checksum of data + std::string computed_hash; + { + SHA1 ctx; + ctx.addBytes(filedata.c_str(), filedata.size()); + unsigned char *buf = ctx.getDigest(); + computed_hash.assign((char*) buf, 20); + free(buf); + } + if (raw_hash != computed_hash) { + verbosestream << "Hash of file data mismatches, ignoring." << std::endl; + return; + } + + // Actually load media + loadMedia(filedata, filename, true); + m_media_pushed_files.insert(filename); + + // Cache file for the next time when this client joins the same server + if (cached) + clientMediaUpdateCache(raw_hash, filedata); + return; + } + + m_media_pushed_files.insert(filename); + + // create a downloader for this file + auto downloader(std::make_shared<SingleMediaDownloader>(cached)); + m_pending_media_downloads.emplace_back(token, downloader); + downloader->addFile(filename, raw_hash); + for (const auto &baseurl : m_remote_media_servers) + downloader->addRemoteServer(baseurl); + + downloader->step(this); +} + +/* + * Mod channels + */ + +void Client::handleCommand_ModChannelMsg(NetworkPacket *pkt) +{ + std::string channel_name, sender, channel_msg; + *pkt >> channel_name >> sender >> channel_msg; + + verbosestream << "Mod channel message received from server " << pkt->getPeerId() + << " on channel " << channel_name << ". sender: `" << sender << "`, message: " + << channel_msg << std::endl; + + if (!m_modchannel_mgr->channelRegistered(channel_name)) { + verbosestream << "Server sent us messages on unregistered channel " + << channel_name << ", ignoring." << std::endl; + return; + } + + m_script->on_modchannel_message(channel_name, sender, channel_msg); +} + +void Client::handleCommand_ModChannelSignal(NetworkPacket *pkt) +{ + u8 signal_tmp; + ModChannelSignal signal; + std::string channel; + + *pkt >> signal_tmp >> channel; + + signal = (ModChannelSignal)signal_tmp; + + bool valid_signal = true; + // @TODO: send Signal to Lua API + switch (signal) { + case MODCHANNEL_SIGNAL_JOIN_OK: + m_modchannel_mgr->setChannelState(channel, MODCHANNEL_STATE_READ_WRITE); + infostream << "Server ack our mod channel join on channel `" << channel + << "`, joining." << std::endl; + break; + case MODCHANNEL_SIGNAL_JOIN_FAILURE: + // Unable to join, remove channel + m_modchannel_mgr->leaveChannel(channel, 0); + infostream << "Server refused our mod channel join on channel `" << channel + << "`" << std::endl; + break; + case MODCHANNEL_SIGNAL_LEAVE_OK: +#ifndef NDEBUG + infostream << "Server ack our mod channel leave on channel " << channel + << "`, leaving." << std::endl; +#endif + break; + case MODCHANNEL_SIGNAL_LEAVE_FAILURE: + infostream << "Server refused our mod channel leave on channel `" << channel + << "`" << std::endl; + break; + case MODCHANNEL_SIGNAL_CHANNEL_NOT_REGISTERED: +#ifndef NDEBUG + // Generally unused, but ensure we don't do an implementation error + infostream << "Server tells us we sent a message on channel `" << channel + << "` but we are not registered. Message was dropped." << std::endl; +#endif + break; + case MODCHANNEL_SIGNAL_SET_STATE: { + u8 state; + *pkt >> state; + + if (state == MODCHANNEL_STATE_INIT || state >= MODCHANNEL_STATE_MAX) { + infostream << "Received wrong channel state " << state + << ", ignoring." << std::endl; + return; + } + + m_modchannel_mgr->setChannelState(channel, (ModChannelState) state); + infostream << "Server sets mod channel `" << channel + << "` in read-only mode." << std::endl; + break; + } + default: +#ifndef NDEBUG + warningstream << "Received unhandled mod channel signal ID " + << signal << ", ignoring." << std::endl; +#endif + valid_signal = false; + break; + } + + // If signal is valid, forward it to client side mods + if (valid_signal) + m_script->on_modchannel_signal(channel, signal); +} + +void Client::handleCommand_MinimapModes(NetworkPacket *pkt) +{ + u16 count; // modes + u16 mode; // wanted current mode index after change + + *pkt >> count >> mode; + + if (m_minimap) + m_minimap->clearModes(); + + for (size_t index = 0; index < count; index++) { + u16 type; + std::string label; + u16 size; + std::string texture; + u16 scale; + + *pkt >> type >> label >> size >> texture >> scale; + + if (m_minimap) + m_minimap->addMode(MinimapType(type), size, label, texture, scale); + } + + if (m_minimap) + m_minimap->setModeIndex(mode); +} + +void Client::handleCommand_SetLighting(NetworkPacket *pkt) +{ + Lighting& lighting = m_env.getLocalPlayer()->getLighting(); + + if (pkt->getRemainingBytes() >= 4) + *pkt >> lighting.shadow_intensity; +} diff --git a/src/network/connection.cpp b/src/network/connection.cpp new file mode 100644 index 0000000..6fb676f --- /dev/null +++ b/src/network/connection.cpp @@ -0,0 +1,1647 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <iomanip> +#include <cerrno> +#include <algorithm> +#include <cmath> +#include "connection.h" +#include "serialization.h" +#include "log.h" +#include "porting.h" +#include "network/connectionthreads.h" +#include "network/networkpacket.h" +#include "network/peerhandler.h" +#include "util/serialize.h" +#include "util/numeric.h" +#include "util/string.h" +#include "settings.h" +#include "profiler.h" + +namespace con +{ + +/******************************************************************************/ +/* defines used for debugging and profiling */ +/******************************************************************************/ +#ifdef NDEBUG + #define PROFILE(a) +#else + #define PROFILE(a) a +#endif + +// TODO: Clean this up. +#define LOG(a) a + +#define PING_TIMEOUT 5.0 + +u16 BufferedPacket::getSeqnum() const +{ + if (size() < BASE_HEADER_SIZE + 3) + return 0; // should never happen + + return readU16(&data[BASE_HEADER_SIZE + 1]); +} + +BufferedPacketPtr makePacket(Address &address, const SharedBuffer<u8> &data, + u32 protocol_id, session_t sender_peer_id, u8 channel) +{ + u32 packet_size = data.getSize() + BASE_HEADER_SIZE; + + BufferedPacketPtr p(new BufferedPacket(packet_size)); + p->address = address; + + writeU32(&p->data[0], protocol_id); + writeU16(&p->data[4], sender_peer_id); + writeU8(&p->data[6], channel); + + memcpy(&p->data[BASE_HEADER_SIZE], *data, data.getSize()); + + return p; +} + +SharedBuffer<u8> makeOriginalPacket(const SharedBuffer<u8> &data) +{ + u32 header_size = 1; + u32 packet_size = data.getSize() + header_size; + SharedBuffer<u8> b(packet_size); + + writeU8(&(b[0]), PACKET_TYPE_ORIGINAL); + if (data.getSize() > 0) { + memcpy(&(b[header_size]), *data, data.getSize()); + } + return b; +} + +// Split data in chunks and add TYPE_SPLIT headers to them +void makeSplitPacket(const SharedBuffer<u8> &data, u32 chunksize_max, u16 seqnum, + std::list<SharedBuffer<u8>> *chunks) +{ + // Chunk packets, containing the TYPE_SPLIT header + u32 chunk_header_size = 7; + u32 maximum_data_size = chunksize_max - chunk_header_size; + u32 start = 0; + u32 end = 0; + u32 chunk_num = 0; + u16 chunk_count = 0; + do { + end = start + maximum_data_size - 1; + if (end > data.getSize() - 1) + end = data.getSize() - 1; + + u32 payload_size = end - start + 1; + u32 packet_size = chunk_header_size + payload_size; + + SharedBuffer<u8> chunk(packet_size); + + writeU8(&chunk[0], PACKET_TYPE_SPLIT); + writeU16(&chunk[1], seqnum); + // [3] u16 chunk_count is written at next stage + writeU16(&chunk[5], chunk_num); + memcpy(&chunk[chunk_header_size], &data[start], payload_size); + + chunks->push_back(chunk); + chunk_count++; + + start = end + 1; + chunk_num++; + } + while (end != data.getSize() - 1); + + for (SharedBuffer<u8> &chunk : *chunks) { + // Write chunk_count + writeU16(&(chunk[3]), chunk_count); + } +} + +void makeAutoSplitPacket(const SharedBuffer<u8> &data, u32 chunksize_max, + u16 &split_seqnum, std::list<SharedBuffer<u8>> *list) +{ + u32 original_header_size = 1; + + if (data.getSize() + original_header_size > chunksize_max) { + makeSplitPacket(data, chunksize_max, split_seqnum, list); + split_seqnum++; + return; + } + + list->push_back(makeOriginalPacket(data)); +} + +SharedBuffer<u8> makeReliablePacket(const SharedBuffer<u8> &data, u16 seqnum) +{ + u32 header_size = 3; + u32 packet_size = data.getSize() + header_size; + SharedBuffer<u8> b(packet_size); + + writeU8(&b[0], PACKET_TYPE_RELIABLE); + writeU16(&b[1], seqnum); + + memcpy(&b[header_size], *data, data.getSize()); + + return b; +} + +/* + ReliablePacketBuffer +*/ + +void ReliablePacketBuffer::print() +{ + MutexAutoLock listlock(m_list_mutex); + LOG(dout_con<<"Dump of ReliablePacketBuffer:" << std::endl); + unsigned int index = 0; + for (BufferedPacketPtr &packet : m_list) { + LOG(dout_con<<index<< ":" << packet->getSeqnum() << std::endl); + index++; + } +} + +bool ReliablePacketBuffer::empty() +{ + MutexAutoLock listlock(m_list_mutex); + return m_list.empty(); +} + +u32 ReliablePacketBuffer::size() +{ + MutexAutoLock listlock(m_list_mutex); + return m_list.size(); +} + +RPBSearchResult ReliablePacketBuffer::findPacketNoLock(u16 seqnum) +{ + for (auto it = m_list.begin(); it != m_list.end(); ++it) { + if ((*it)->getSeqnum() == seqnum) + return it; + } + return m_list.end(); +} + +bool ReliablePacketBuffer::getFirstSeqnum(u16& result) +{ + MutexAutoLock listlock(m_list_mutex); + if (m_list.empty()) + return false; + result = m_list.front()->getSeqnum(); + return true; +} + +BufferedPacketPtr ReliablePacketBuffer::popFirst() +{ + MutexAutoLock listlock(m_list_mutex); + if (m_list.empty()) + throw NotFoundException("Buffer is empty"); + + BufferedPacketPtr p(m_list.front()); + m_list.pop_front(); + + if (m_list.empty()) { + m_oldest_non_answered_ack = 0; + } else { + m_oldest_non_answered_ack = m_list.front()->getSeqnum(); + } + return p; +} + +BufferedPacketPtr ReliablePacketBuffer::popSeqnum(u16 seqnum) +{ + MutexAutoLock listlock(m_list_mutex); + RPBSearchResult r = findPacketNoLock(seqnum); + if (r == m_list.end()) { + LOG(dout_con<<"Sequence number: " << seqnum + << " not found in reliable buffer"<<std::endl); + throw NotFoundException("seqnum not found in buffer"); + } + + BufferedPacketPtr p(*r); + m_list.erase(r); + + if (m_list.empty()) { + m_oldest_non_answered_ack = 0; + } else { + m_oldest_non_answered_ack = m_list.front()->getSeqnum(); + } + return p; +} + +void ReliablePacketBuffer::insert(BufferedPacketPtr &p_ptr, u16 next_expected) +{ + MutexAutoLock listlock(m_list_mutex); + const BufferedPacket &p = *p_ptr; + + if (p.size() < BASE_HEADER_SIZE + 3) { + errorstream << "ReliablePacketBuffer::insert(): Invalid data size for " + "reliable packet" << std::endl; + return; + } + u8 type = readU8(&p.data[BASE_HEADER_SIZE + 0]); + if (type != PACKET_TYPE_RELIABLE) { + errorstream << "ReliablePacketBuffer::insert(): type is not reliable" + << std::endl; + return; + } + const u16 seqnum = p.getSeqnum(); + + if (!seqnum_in_window(seqnum, next_expected, MAX_RELIABLE_WINDOW_SIZE)) { + errorstream << "ReliablePacketBuffer::insert(): seqnum is outside of " + "expected window " << std::endl; + return; + } + if (seqnum == next_expected) { + errorstream << "ReliablePacketBuffer::insert(): seqnum is next expected" + << std::endl; + return; + } + + sanity_check(m_list.size() <= SEQNUM_MAX); // FIXME: Handle the error? + + // Find the right place for the packet and insert it there + // If list is empty, just add it + if (m_list.empty()) { + m_list.push_back(p_ptr); + m_oldest_non_answered_ack = seqnum; + // Done. + return; + } + + // Otherwise find the right place + auto it = m_list.begin(); + // Find the first packet in the list which has a higher seqnum + u16 s = (*it)->getSeqnum(); + + /* case seqnum is smaller then next_expected seqnum */ + /* this is true e.g. on wrap around */ + if (seqnum < next_expected) { + while(((s < seqnum) || (s >= next_expected)) && (it != m_list.end())) { + ++it; + if (it != m_list.end()) + s = (*it)->getSeqnum(); + } + } + /* non wrap around case (at least for incoming and next_expected */ + else + { + while(((s < seqnum) && (s >= next_expected)) && (it != m_list.end())) { + ++it; + if (it != m_list.end()) + s = (*it)->getSeqnum(); + } + } + + if (s == seqnum) { + /* nothing to do this seems to be a resent packet */ + /* for paranoia reason data should be compared */ + auto &i = *it; + if ( + (i->getSeqnum() != seqnum) || + (i->size() != p.size()) || + (i->address != p.address) + ) + { + /* if this happens your maximum transfer window may be to big */ + fprintf(stderr, + "Duplicated seqnum %d non matching packet detected:\n", + seqnum); + fprintf(stderr, "Old: seqnum: %05d size: %04zu, address: %s\n", + i->getSeqnum(), i->size(), + i->address.serializeString().c_str()); + fprintf(stderr, "New: seqnum: %05d size: %04zu, address: %s\n", + p.getSeqnum(), p.size(), + p.address.serializeString().c_str()); + throw IncomingDataCorruption("duplicated packet isn't same as original one"); + } + } + /* insert or push back */ + else if (it != m_list.end()) { + m_list.insert(it, p_ptr); + } else { + m_list.push_back(p_ptr); + } + + /* update last packet number */ + m_oldest_non_answered_ack = m_list.front()->getSeqnum(); +} + +void ReliablePacketBuffer::incrementTimeouts(float dtime) +{ + MutexAutoLock listlock(m_list_mutex); + for (auto &packet : m_list) { + packet->time += dtime; + packet->totaltime += dtime; + } +} + +std::list<ConstSharedPtr<BufferedPacket>> + ReliablePacketBuffer::getTimedOuts(float timeout, u32 max_packets) +{ + MutexAutoLock listlock(m_list_mutex); + std::list<ConstSharedPtr<BufferedPacket>> timed_outs; + for (auto &packet : m_list) { + if (packet->time < timeout) + continue; + + // caller will resend packet so reset time and increase counter + packet->time = 0.0f; + packet->resend_count++; + + timed_outs.emplace_back(packet); + + if (timed_outs.size() >= max_packets) + break; + } + return timed_outs; +} + +/* + IncomingSplitPacket +*/ + +bool IncomingSplitPacket::insert(u32 chunk_num, SharedBuffer<u8> &chunkdata) +{ + sanity_check(chunk_num < chunk_count); + + // If chunk already exists, ignore it. + // Sometimes two identical packets may arrive when there is network + // lag and the server re-sends stuff. + if (chunks.find(chunk_num) != chunks.end()) + return false; + + // Set chunk data in buffer + chunks[chunk_num] = chunkdata; + + return true; +} + +SharedBuffer<u8> IncomingSplitPacket::reassemble() +{ + sanity_check(allReceived()); + + // Calculate total size + u32 totalsize = 0; + for (const auto &chunk : chunks) + totalsize += chunk.second.getSize(); + + SharedBuffer<u8> fulldata(totalsize); + + // Copy chunks to data buffer + u32 start = 0; + for (u32 chunk_i = 0; chunk_i < chunk_count; chunk_i++) { + const SharedBuffer<u8> &buf = chunks[chunk_i]; + memcpy(&fulldata[start], *buf, buf.getSize()); + start += buf.getSize(); + } + + return fulldata; +} + +/* + IncomingSplitBuffer +*/ + +IncomingSplitBuffer::~IncomingSplitBuffer() +{ + MutexAutoLock listlock(m_map_mutex); + for (auto &i : m_buf) { + delete i.second; + } +} + +SharedBuffer<u8> IncomingSplitBuffer::insert(BufferedPacketPtr &p_ptr, bool reliable) +{ + MutexAutoLock listlock(m_map_mutex); + const BufferedPacket &p = *p_ptr; + + u32 headersize = BASE_HEADER_SIZE + 7; + if (p.size() < headersize) { + errorstream << "Invalid data size for split packet" << std::endl; + return SharedBuffer<u8>(); + } + u8 type = readU8(&p.data[BASE_HEADER_SIZE+0]); + u16 seqnum = readU16(&p.data[BASE_HEADER_SIZE+1]); + u16 chunk_count = readU16(&p.data[BASE_HEADER_SIZE+3]); + u16 chunk_num = readU16(&p.data[BASE_HEADER_SIZE+5]); + + if (type != PACKET_TYPE_SPLIT) { + errorstream << "IncomingSplitBuffer::insert(): type is not split" + << std::endl; + return SharedBuffer<u8>(); + } + if (chunk_num >= chunk_count) { + errorstream << "IncomingSplitBuffer::insert(): chunk_num=" << chunk_num + << " >= chunk_count=" << chunk_count << std::endl; + return SharedBuffer<u8>(); + } + + // Add if doesn't exist + IncomingSplitPacket *sp; + if (m_buf.find(seqnum) == m_buf.end()) { + sp = new IncomingSplitPacket(chunk_count, reliable); + m_buf[seqnum] = sp; + } else { + sp = m_buf[seqnum]; + } + + if (chunk_count != sp->chunk_count) { + errorstream << "IncomingSplitBuffer::insert(): chunk_count=" + << chunk_count << " != sp->chunk_count=" << sp->chunk_count + << std::endl; + return SharedBuffer<u8>(); + } + if (reliable != sp->reliable) + LOG(derr_con<<"Connection: WARNING: reliable="<<reliable + <<" != sp->reliable="<<sp->reliable + <<std::endl); + + // Cut chunk data out of packet + u32 chunkdatasize = p.size() - headersize; + SharedBuffer<u8> chunkdata(chunkdatasize); + memcpy(*chunkdata, &(p.data[headersize]), chunkdatasize); + + if (!sp->insert(chunk_num, chunkdata)) + return SharedBuffer<u8>(); + + // If not all chunks are received, return empty buffer + if (!sp->allReceived()) + return SharedBuffer<u8>(); + + SharedBuffer<u8> fulldata = sp->reassemble(); + + // Remove sp from buffer + m_buf.erase(seqnum); + delete sp; + + return fulldata; +} + +void IncomingSplitBuffer::removeUnreliableTimedOuts(float dtime, float timeout) +{ + std::deque<u16> remove_queue; + { + MutexAutoLock listlock(m_map_mutex); + for (auto &i : m_buf) { + IncomingSplitPacket *p = i.second; + // Reliable ones are not removed by timeout + if (p->reliable) + continue; + p->time += dtime; + if (p->time >= timeout) + remove_queue.push_back(i.first); + } + } + for (u16 j : remove_queue) { + MutexAutoLock listlock(m_map_mutex); + LOG(dout_con<<"NOTE: Removing timed out unreliable split packet"<<std::endl); + delete m_buf[j]; + m_buf.erase(j); + } +} + +/* + ConnectionCommand + */ + +ConnectionCommandPtr ConnectionCommand::create(ConnectionCommandType type) +{ + return ConnectionCommandPtr(new ConnectionCommand(type)); +} + +ConnectionCommandPtr ConnectionCommand::serve(Address address) +{ + auto c = create(CONNCMD_SERVE); + c->address = address; + return c; +} + +ConnectionCommandPtr ConnectionCommand::connect(Address address) +{ + auto c = create(CONNCMD_CONNECT); + c->address = address; + return c; +} + +ConnectionCommandPtr ConnectionCommand::disconnect() +{ + return create(CONNCMD_DISCONNECT); +} + +ConnectionCommandPtr ConnectionCommand::disconnect_peer(session_t peer_id) +{ + auto c = create(CONNCMD_DISCONNECT_PEER); + c->peer_id = peer_id; + return c; +} + +ConnectionCommandPtr ConnectionCommand::send(session_t peer_id, u8 channelnum, + NetworkPacket *pkt, bool reliable) +{ + auto c = create(CONNCMD_SEND); + c->peer_id = peer_id; + c->channelnum = channelnum; + c->reliable = reliable; + c->data = pkt->oldForgePacket(); + return c; +} + +ConnectionCommandPtr ConnectionCommand::ack(session_t peer_id, u8 channelnum, const Buffer<u8> &data) +{ + auto c = create(CONCMD_ACK); + c->peer_id = peer_id; + c->channelnum = channelnum; + c->reliable = false; + data.copyTo(c->data); + return c; +} + +ConnectionCommandPtr ConnectionCommand::createPeer(session_t peer_id, const Buffer<u8> &data) +{ + auto c = create(CONCMD_CREATE_PEER); + c->peer_id = peer_id; + c->channelnum = 0; + c->reliable = true; + c->raw = true; + data.copyTo(c->data); + return c; +} + +/* + Channel +*/ + +u16 Channel::readNextIncomingSeqNum() +{ + MutexAutoLock internal(m_internal_mutex); + return next_incoming_seqnum; +} + +u16 Channel::incNextIncomingSeqNum() +{ + MutexAutoLock internal(m_internal_mutex); + u16 retval = next_incoming_seqnum; + next_incoming_seqnum++; + return retval; +} + +u16 Channel::readNextSplitSeqNum() +{ + MutexAutoLock internal(m_internal_mutex); + return next_outgoing_split_seqnum; +} +void Channel::setNextSplitSeqNum(u16 seqnum) +{ + MutexAutoLock internal(m_internal_mutex); + next_outgoing_split_seqnum = seqnum; +} + +u16 Channel::getOutgoingSequenceNumber(bool& successful) +{ + MutexAutoLock internal(m_internal_mutex); + + u16 retval = next_outgoing_seqnum; + successful = false; + + /* shortcut if there ain't any packet in outgoing list */ + if (outgoing_reliables_sent.empty()) { + successful = true; + next_outgoing_seqnum++; + return retval; + } + + u16 lowest_unacked_seqnumber; + if (outgoing_reliables_sent.getFirstSeqnum(lowest_unacked_seqnumber)) { + if (lowest_unacked_seqnumber < next_outgoing_seqnum) { + // ugly cast but this one is required in order to tell compiler we + // know about difference of two unsigned may be negative in general + // but we already made sure it won't happen in this case + if (((u16)(next_outgoing_seqnum - lowest_unacked_seqnumber)) > m_window_size) { + return 0; + } + } else { + // ugly cast but this one is required in order to tell compiler we + // know about difference of two unsigned may be negative in general + // but we already made sure it won't happen in this case + if ((next_outgoing_seqnum + (u16)(SEQNUM_MAX - lowest_unacked_seqnumber)) > + m_window_size) { + return 0; + } + } + } + + successful = true; + next_outgoing_seqnum++; + return retval; +} + +u16 Channel::readOutgoingSequenceNumber() +{ + MutexAutoLock internal(m_internal_mutex); + return next_outgoing_seqnum; +} + +bool Channel::putBackSequenceNumber(u16 seqnum) +{ + if (((seqnum + 1) % (SEQNUM_MAX+1)) == next_outgoing_seqnum) { + + next_outgoing_seqnum = seqnum; + return true; + } + return false; +} + +void Channel::UpdateBytesSent(unsigned int bytes, unsigned int packets) +{ + MutexAutoLock internal(m_internal_mutex); + current_bytes_transfered += bytes; + current_packet_successful += packets; +} + +void Channel::UpdateBytesReceived(unsigned int bytes) { + MutexAutoLock internal(m_internal_mutex); + current_bytes_received += bytes; +} + +void Channel::UpdateBytesLost(unsigned int bytes) +{ + MutexAutoLock internal(m_internal_mutex); + current_bytes_lost += bytes; +} + + +void Channel::UpdatePacketLossCounter(unsigned int count) +{ + MutexAutoLock internal(m_internal_mutex); + current_packet_loss += count; +} + +void Channel::UpdatePacketTooLateCounter() +{ + MutexAutoLock internal(m_internal_mutex); + current_packet_too_late++; +} + +void Channel::UpdateTimers(float dtime) +{ + bpm_counter += dtime; + packet_loss_counter += dtime; + + if (packet_loss_counter > 1.0f) { + packet_loss_counter -= 1.0f; + + unsigned int packet_loss = 11; /* use a neutral value for initialization */ + unsigned int packets_successful = 0; + //unsigned int packet_too_late = 0; + + bool reasonable_amount_of_data_transmitted = false; + + { + MutexAutoLock internal(m_internal_mutex); + packet_loss = current_packet_loss; + //packet_too_late = current_packet_too_late; + packets_successful = current_packet_successful; + + if (current_bytes_transfered > (unsigned int) (m_window_size*512/2)) { + reasonable_amount_of_data_transmitted = true; + } + current_packet_loss = 0; + current_packet_too_late = 0; + current_packet_successful = 0; + } + + /* dynamic window size */ + float successful_to_lost_ratio = 0.0f; + bool done = false; + + if (packets_successful > 0) { + successful_to_lost_ratio = packet_loss/packets_successful; + } else if (packet_loss > 0) { + setWindowSize(m_window_size - 10); + done = true; + } + + if (!done) { + if (successful_to_lost_ratio < 0.01f) { + /* don't even think about increasing if we didn't even + * use major parts of our window */ + if (reasonable_amount_of_data_transmitted) + setWindowSize(m_window_size + 100); + } else if (successful_to_lost_ratio < 0.05f) { + /* don't even think about increasing if we didn't even + * use major parts of our window */ + if (reasonable_amount_of_data_transmitted) + setWindowSize(m_window_size + 50); + } else if (successful_to_lost_ratio > 0.15f) { + setWindowSize(m_window_size - 100); + } else if (successful_to_lost_ratio > 0.1f) { + setWindowSize(m_window_size - 50); + } + } + } + + if (bpm_counter > 10.0f) { + { + MutexAutoLock internal(m_internal_mutex); + cur_kbps = + (((float) current_bytes_transfered)/bpm_counter)/1024.0f; + current_bytes_transfered = 0; + cur_kbps_lost = + (((float) current_bytes_lost)/bpm_counter)/1024.0f; + current_bytes_lost = 0; + cur_incoming_kbps = + (((float) current_bytes_received)/bpm_counter)/1024.0f; + current_bytes_received = 0; + bpm_counter = 0.0f; + } + + if (cur_kbps > max_kbps) { + max_kbps = cur_kbps; + } + + if (cur_kbps_lost > max_kbps_lost) { + max_kbps_lost = cur_kbps_lost; + } + + if (cur_incoming_kbps > max_incoming_kbps) { + max_incoming_kbps = cur_incoming_kbps; + } + + rate_samples = MYMIN(rate_samples+1,10); + float old_fraction = ((float) (rate_samples-1) )/( (float) rate_samples); + avg_kbps = avg_kbps * old_fraction + + cur_kbps * (1.0 - old_fraction); + avg_kbps_lost = avg_kbps_lost * old_fraction + + cur_kbps_lost * (1.0 - old_fraction); + avg_incoming_kbps = avg_incoming_kbps * old_fraction + + cur_incoming_kbps * (1.0 - old_fraction); + } +} + + +/* + Peer +*/ + +PeerHelper::PeerHelper(Peer* peer) : + m_peer(peer) +{ + if (peer && !peer->IncUseCount()) + m_peer = nullptr; +} + +PeerHelper::~PeerHelper() +{ + if (m_peer) + m_peer->DecUseCount(); + + m_peer = nullptr; +} + +PeerHelper& PeerHelper::operator=(Peer* peer) +{ + m_peer = peer; + if (peer && !peer->IncUseCount()) + m_peer = nullptr; + return *this; +} + +Peer* PeerHelper::operator->() const +{ + return m_peer; +} + +Peer* PeerHelper::operator&() const +{ + return m_peer; +} + +bool PeerHelper::operator!() +{ + return ! m_peer; +} + +bool PeerHelper::operator!=(void* ptr) +{ + return ((void*) m_peer != ptr); +} + +bool Peer::IncUseCount() +{ + MutexAutoLock lock(m_exclusive_access_mutex); + + if (!m_pending_deletion) { + this->m_usage++; + return true; + } + + return false; +} + +void Peer::DecUseCount() +{ + { + MutexAutoLock lock(m_exclusive_access_mutex); + sanity_check(m_usage > 0); + m_usage--; + + if (!((m_pending_deletion) && (m_usage == 0))) + return; + } + delete this; +} + +void Peer::RTTStatistics(float rtt, const std::string &profiler_id, + unsigned int num_samples) { + + if (m_last_rtt > 0) { + /* set min max values */ + if (rtt < m_rtt.min_rtt) + m_rtt.min_rtt = rtt; + if (rtt >= m_rtt.max_rtt) + m_rtt.max_rtt = rtt; + + /* do average calculation */ + if (m_rtt.avg_rtt < 0.0) + m_rtt.avg_rtt = rtt; + else + m_rtt.avg_rtt = m_rtt.avg_rtt * (num_samples/(num_samples-1)) + + rtt * (1/num_samples); + + /* do jitter calculation */ + + //just use some neutral value at beginning + float jitter = m_rtt.jitter_min; + + if (rtt > m_last_rtt) + jitter = rtt-m_last_rtt; + + if (rtt <= m_last_rtt) + jitter = m_last_rtt - rtt; + + if (jitter < m_rtt.jitter_min) + m_rtt.jitter_min = jitter; + if (jitter >= m_rtt.jitter_max) + m_rtt.jitter_max = jitter; + + if (m_rtt.jitter_avg < 0.0) + m_rtt.jitter_avg = jitter; + else + m_rtt.jitter_avg = m_rtt.jitter_avg * (num_samples/(num_samples-1)) + + jitter * (1/num_samples); + + if (!profiler_id.empty()) { + g_profiler->graphAdd(profiler_id + " RTT [ms]", rtt * 1000.f); + g_profiler->graphAdd(profiler_id + " jitter [ms]", jitter * 1000.f); + } + } + /* save values required for next loop */ + m_last_rtt = rtt; +} + +bool Peer::isTimedOut(float timeout) +{ + MutexAutoLock lock(m_exclusive_access_mutex); + u64 current_time = porting::getTimeMs(); + + float dtime = CALC_DTIME(m_last_timeout_check,current_time); + m_last_timeout_check = current_time; + + m_timeout_counter += dtime; + + return m_timeout_counter > timeout; +} + +void Peer::Drop() +{ + { + MutexAutoLock usage_lock(m_exclusive_access_mutex); + m_pending_deletion = true; + if (m_usage != 0) + return; + } + + PROFILE(std::stringstream peerIdentifier1); + PROFILE(peerIdentifier1 << "runTimeouts[" << m_connection->getDesc() + << ";" << id << ";RELIABLE]"); + PROFILE(g_profiler->remove(peerIdentifier1.str())); + PROFILE(std::stringstream peerIdentifier2); + PROFILE(peerIdentifier2 << "sendPackets[" << m_connection->getDesc() + << ";" << id << ";RELIABLE]"); + PROFILE(ScopeProfiler peerprofiler(g_profiler, peerIdentifier2.str(), SPT_AVG)); + + delete this; +} + +UDPPeer::UDPPeer(u16 a_id, Address a_address, Connection* connection) : + Peer(a_address,a_id,connection) +{ + for (Channel &channel : channels) + channel.setWindowSize(START_RELIABLE_WINDOW_SIZE); +} + +bool UDPPeer::getAddress(MTProtocols type,Address& toset) +{ + if ((type == MTP_UDP) || (type == MTP_MINETEST_RELIABLE_UDP) || (type == MTP_PRIMARY)) + { + toset = address; + return true; + } + + return false; +} + +void UDPPeer::reportRTT(float rtt) +{ + if (rtt < 0.0) { + return; + } + RTTStatistics(rtt,"rudp",MAX_RELIABLE_WINDOW_SIZE*10); + + float timeout = getStat(AVG_RTT) * RESEND_TIMEOUT_FACTOR; + if (timeout < RESEND_TIMEOUT_MIN) + timeout = RESEND_TIMEOUT_MIN; + if (timeout > RESEND_TIMEOUT_MAX) + timeout = RESEND_TIMEOUT_MAX; + + MutexAutoLock usage_lock(m_exclusive_access_mutex); + resend_timeout = timeout; +} + +bool UDPPeer::Ping(float dtime,SharedBuffer<u8>& data) +{ + m_ping_timer += dtime; + if (m_ping_timer >= PING_TIMEOUT) + { + // Create and send PING packet + writeU8(&data[0], PACKET_TYPE_CONTROL); + writeU8(&data[1], CONTROLTYPE_PING); + m_ping_timer = 0.0; + return true; + } + return false; +} + +void UDPPeer::PutReliableSendCommand(ConnectionCommandPtr &c, + unsigned int max_packet_size) +{ + if (m_pending_disconnect) + return; + + Channel &chan = channels[c->channelnum]; + + if (chan.queued_commands.empty() && + /* don't queue more packets then window size */ + (chan.queued_reliables.size() + 1 < chan.getWindowSize() / 2)) { + LOG(dout_con<<m_connection->getDesc() + <<" processing reliable command for peer id: " << c->peer_id + <<" data size: " << c->data.getSize() << std::endl); + if (processReliableSendCommand(c, max_packet_size)) + return; + } else { + LOG(dout_con<<m_connection->getDesc() + <<" Queueing reliable command for peer id: " << c->peer_id + <<" data size: " << c->data.getSize() <<std::endl); + + if (chan.queued_commands.size() + 1 >= chan.getWindowSize() / 2) { + LOG(derr_con << m_connection->getDesc() + << "Possible packet stall to peer id: " << c->peer_id + << " queued_commands=" << chan.queued_commands.size() + << std::endl); + } + } + chan.queued_commands.push_back(c); +} + +bool UDPPeer::processReliableSendCommand( + ConnectionCommandPtr &c_ptr, + unsigned int max_packet_size) +{ + if (m_pending_disconnect) + return true; + + const auto &c = *c_ptr; + Channel &chan = channels[c.channelnum]; + + u32 chunksize_max = max_packet_size + - BASE_HEADER_SIZE + - RELIABLE_HEADER_SIZE; + + sanity_check(c.data.getSize() < MAX_RELIABLE_WINDOW_SIZE*512); + + std::list<SharedBuffer<u8>> originals; + u16 split_sequence_number = chan.readNextSplitSeqNum(); + + if (c.raw) { + originals.emplace_back(c.data); + } else { + makeAutoSplitPacket(c.data, chunksize_max,split_sequence_number, &originals); + chan.setNextSplitSeqNum(split_sequence_number); + } + + bool have_sequence_number = false; + bool have_initial_sequence_number = false; + std::queue<BufferedPacketPtr> toadd; + volatile u16 initial_sequence_number = 0; + + for (SharedBuffer<u8> &original : originals) { + u16 seqnum = chan.getOutgoingSequenceNumber(have_sequence_number); + + /* oops, we don't have enough sequence numbers to send this packet */ + if (!have_sequence_number) + break; + + if (!have_initial_sequence_number) + { + initial_sequence_number = seqnum; + have_initial_sequence_number = true; + } + + SharedBuffer<u8> reliable = makeReliablePacket(original, seqnum); + + // Add base headers and make a packet + BufferedPacketPtr p = con::makePacket(address, reliable, + m_connection->GetProtocolID(), m_connection->GetPeerID(), + c.channelnum); + + toadd.push(p); + } + + if (have_sequence_number) { + while (!toadd.empty()) { + BufferedPacketPtr p = toadd.front(); + toadd.pop(); +// LOG(dout_con<<connection->getDesc() +// << " queuing reliable packet for peer_id: " << c.peer_id +// << " channel: " << (c.channelnum&0xFF) +// << " seqnum: " << readU16(&p.data[BASE_HEADER_SIZE+1]) +// << std::endl) + chan.queued_reliables.push(p); + } + sanity_check(chan.queued_reliables.size() < 0xFFFF); + return true; + } + + volatile u16 packets_available = toadd.size(); + /* we didn't get a single sequence number no need to fill queue */ + if (!have_initial_sequence_number) { + LOG(derr_con << m_connection->getDesc() << "Ran out of sequence numbers!" << std::endl); + return false; + } + + while (!toadd.empty()) { + /* remove packet */ + toadd.pop(); + + bool successfully_put_back_sequence_number + = chan.putBackSequenceNumber( + (initial_sequence_number+toadd.size() % (SEQNUM_MAX+1))); + + FATAL_ERROR_IF(!successfully_put_back_sequence_number, "error"); + } + + // DO NOT REMOVE n_queued! It avoids a deadlock of async locked + // 'log_message_mutex' and 'm_list_mutex'. + u32 n_queued = chan.outgoing_reliables_sent.size(); + + LOG(dout_con<<m_connection->getDesc() + << " Windowsize exceeded on reliable sending " + << c.data.getSize() << " bytes" + << std::endl << "\t\tinitial_sequence_number: " + << initial_sequence_number + << std::endl << "\t\tgot at most : " + << packets_available << " packets" + << std::endl << "\t\tpackets queued : " + << n_queued + << std::endl); + + return false; +} + +void UDPPeer::RunCommandQueues( + unsigned int max_packet_size, + unsigned int maxcommands, + unsigned int maxtransfer) +{ + + for (Channel &channel : channels) { + unsigned int commands_processed = 0; + + if ((!channel.queued_commands.empty()) && + (channel.queued_reliables.size() < maxtransfer) && + (commands_processed < maxcommands)) { + try { + ConnectionCommandPtr c = channel.queued_commands.front(); + + LOG(dout_con << m_connection->getDesc() + << " processing queued reliable command " << std::endl); + + // Packet is processed, remove it from queue + if (processReliableSendCommand(c, max_packet_size)) { + channel.queued_commands.pop_front(); + } else { + LOG(dout_con << m_connection->getDesc() + << " Failed to queue packets for peer_id: " << c->peer_id + << ", delaying sending of " << c->data.getSize() + << " bytes" << std::endl); + } + } + catch (ItemNotFoundException &e) { + // intentionally empty + } + } + } +} + +u16 UDPPeer::getNextSplitSequenceNumber(u8 channel) +{ + assert(channel < CHANNEL_COUNT); // Pre-condition + return channels[channel].readNextSplitSeqNum(); +} + +void UDPPeer::setNextSplitSequenceNumber(u8 channel, u16 seqnum) +{ + assert(channel < CHANNEL_COUNT); // Pre-condition + channels[channel].setNextSplitSeqNum(seqnum); +} + +SharedBuffer<u8> UDPPeer::addSplitPacket(u8 channel, BufferedPacketPtr &toadd, + bool reliable) +{ + assert(channel < CHANNEL_COUNT); // Pre-condition + return channels[channel].incoming_splits.insert(toadd, reliable); +} + +/* + ConnectionEvent +*/ + +const char *ConnectionEvent::describe() const +{ + switch(type) { + case CONNEVENT_NONE: + return "CONNEVENT_NONE"; + case CONNEVENT_DATA_RECEIVED: + return "CONNEVENT_DATA_RECEIVED"; + case CONNEVENT_PEER_ADDED: + return "CONNEVENT_PEER_ADDED"; + case CONNEVENT_PEER_REMOVED: + return "CONNEVENT_PEER_REMOVED"; + case CONNEVENT_BIND_FAILED: + return "CONNEVENT_BIND_FAILED"; + } + return "Invalid ConnectionEvent"; +} + + +ConnectionEventPtr ConnectionEvent::create(ConnectionEventType type) +{ + return std::shared_ptr<ConnectionEvent>(new ConnectionEvent(type)); +} + +ConnectionEventPtr ConnectionEvent::dataReceived(session_t peer_id, const Buffer<u8> &data) +{ + auto e = create(CONNEVENT_DATA_RECEIVED); + e->peer_id = peer_id; + data.copyTo(e->data); + return e; +} + +ConnectionEventPtr ConnectionEvent::peerAdded(session_t peer_id, Address address) +{ + auto e = create(CONNEVENT_PEER_ADDED); + e->peer_id = peer_id; + e->address = address; + return e; +} + +ConnectionEventPtr ConnectionEvent::peerRemoved(session_t peer_id, bool is_timeout, Address address) +{ + auto e = create(CONNEVENT_PEER_REMOVED); + e->peer_id = peer_id; + e->timeout = is_timeout; + e->address = address; + return e; +} + +ConnectionEventPtr ConnectionEvent::bindFailed() +{ + return create(CONNEVENT_BIND_FAILED); +} + +/* + Connection +*/ + +Connection::Connection(u32 protocol_id, u32 max_packet_size, float timeout, + bool ipv6, PeerHandler *peerhandler) : + m_udpSocket(ipv6), + m_protocol_id(protocol_id), + m_sendThread(new ConnectionSendThread(max_packet_size, timeout)), + m_receiveThread(new ConnectionReceiveThread(max_packet_size)), + m_bc_peerhandler(peerhandler) + +{ + /* Amount of time Receive() will wait for data, this is entirely different + * from the connection timeout */ + m_udpSocket.setTimeoutMs(500); + + m_sendThread->setParent(this); + m_receiveThread->setParent(this); + + m_sendThread->start(); + m_receiveThread->start(); +} + + +Connection::~Connection() +{ + m_shutting_down = true; + // request threads to stop + m_sendThread->stop(); + m_receiveThread->stop(); + + //TODO for some unkonwn reason send/receive threads do not exit as they're + // supposed to be but wait on peer timeout. To speed up shutdown we reduce + // timeout to half a second. + m_sendThread->setPeerTimeout(0.5); + + // wait for threads to finish + m_sendThread->wait(); + m_receiveThread->wait(); + + // Delete peers + for (auto &peer : m_peers) { + delete peer.second; + } +} + +/* Internal stuff */ + +void Connection::putEvent(ConnectionEventPtr e) +{ + assert(e->type != CONNEVENT_NONE); // Pre-condition + m_event_queue.push_back(e); +} + +void Connection::TriggerSend() +{ + m_sendThread->Trigger(); +} + +PeerHelper Connection::getPeerNoEx(session_t peer_id) +{ + MutexAutoLock peerlock(m_peers_mutex); + std::map<session_t, Peer *>::iterator node = m_peers.find(peer_id); + + if (node == m_peers.end()) { + return PeerHelper(NULL); + } + + // Error checking + FATAL_ERROR_IF(node->second->id != peer_id, "Invalid peer id"); + + return PeerHelper(node->second); +} + +/* find peer_id for address */ +u16 Connection::lookupPeer(Address& sender) +{ + MutexAutoLock peerlock(m_peers_mutex); + std::map<u16, Peer*>::iterator j; + j = m_peers.begin(); + for(; j != m_peers.end(); ++j) + { + Peer *peer = j->second; + if (peer->isPendingDeletion()) + continue; + + Address tocheck; + + if ((peer->getAddress(MTP_MINETEST_RELIABLE_UDP, tocheck)) && (tocheck == sender)) + return peer->id; + + if ((peer->getAddress(MTP_UDP, tocheck)) && (tocheck == sender)) + return peer->id; + } + + return PEER_ID_INEXISTENT; +} + +bool Connection::deletePeer(session_t peer_id, bool timeout) +{ + Peer *peer = 0; + + /* lock list as short as possible */ + { + MutexAutoLock peerlock(m_peers_mutex); + if (m_peers.find(peer_id) == m_peers.end()) + return false; + peer = m_peers[peer_id]; + m_peers.erase(peer_id); + auto it = std::find(m_peer_ids.begin(), m_peer_ids.end(), peer_id); + m_peer_ids.erase(it); + } + + Address peer_address; + //any peer has a primary address this never fails! + peer->getAddress(MTP_PRIMARY, peer_address); + + // Create event + putEvent(ConnectionEvent::peerRemoved(peer_id, timeout, peer_address)); + + peer->Drop(); + return true; +} + +/* Interface */ + +ConnectionEventPtr Connection::waitEvent(u32 timeout_ms) +{ + try { + return m_event_queue.pop_front(timeout_ms); + } catch(ItemNotFoundException &ex) { + return ConnectionEvent::create(CONNEVENT_NONE); + } +} + +void Connection::putCommand(ConnectionCommandPtr c) +{ + if (!m_shutting_down) { + m_command_queue.push_back(c); + m_sendThread->Trigger(); + } +} + +void Connection::Serve(Address bind_addr) +{ + putCommand(ConnectionCommand::serve(bind_addr)); +} + +void Connection::Connect(Address address) +{ + putCommand(ConnectionCommand::connect(address)); +} + +bool Connection::Connected() +{ + MutexAutoLock peerlock(m_peers_mutex); + + if (m_peers.size() != 1) + return false; + + std::map<session_t, Peer *>::iterator node = m_peers.find(PEER_ID_SERVER); + if (node == m_peers.end()) + return false; + + if (m_peer_id == PEER_ID_INEXISTENT) + return false; + + return true; +} + +void Connection::Disconnect() +{ + putCommand(ConnectionCommand::disconnect()); +} + +bool Connection::Receive(NetworkPacket *pkt, u32 timeout) +{ + /* + Note that this function can potentially wait infinitely if non-data + events keep happening before the timeout expires. + This is not considered to be a problem (is it?) + */ + for(;;) { + ConnectionEventPtr e_ptr = waitEvent(timeout); + const ConnectionEvent &e = *e_ptr; + + if (e.type != CONNEVENT_NONE) { + LOG(dout_con << getDesc() << ": Receive: got event: " + << e.describe() << std::endl); + } + + switch (e.type) { + case CONNEVENT_NONE: + return false; + case CONNEVENT_DATA_RECEIVED: + // Data size is lesser than command size, ignoring packet + if (e.data.getSize() < 2) { + continue; + } + + pkt->putRawPacket(*e.data, e.data.getSize(), e.peer_id); + return true; + case CONNEVENT_PEER_ADDED: { + UDPPeer tmp(e.peer_id, e.address, this); + if (m_bc_peerhandler) + m_bc_peerhandler->peerAdded(&tmp); + continue; + } + case CONNEVENT_PEER_REMOVED: { + UDPPeer tmp(e.peer_id, e.address, this); + if (m_bc_peerhandler) + m_bc_peerhandler->deletingPeer(&tmp, e.timeout); + continue; + } + case CONNEVENT_BIND_FAILED: + throw ConnectionBindFailed("Failed to bind socket " + "(port already in use?)"); + } + } + return false; +} + +void Connection::Receive(NetworkPacket *pkt) +{ + bool any = Receive(pkt, m_bc_receive_timeout); + if (!any) + throw NoIncomingDataException("No incoming data"); +} + +bool Connection::TryReceive(NetworkPacket *pkt) +{ + return Receive(pkt, 0); +} + +void Connection::Send(session_t peer_id, u8 channelnum, + NetworkPacket *pkt, bool reliable) +{ + assert(channelnum < CHANNEL_COUNT); // Pre-condition + + putCommand(ConnectionCommand::send(peer_id, channelnum, pkt, reliable)); +} + +Address Connection::GetPeerAddress(session_t peer_id) +{ + PeerHelper peer = getPeerNoEx(peer_id); + + if (!peer) + throw PeerNotFoundException("No address for peer found!"); + Address peer_address; + peer->getAddress(MTP_PRIMARY, peer_address); + return peer_address; +} + +float Connection::getPeerStat(session_t peer_id, rtt_stat_type type) +{ + PeerHelper peer = getPeerNoEx(peer_id); + if (!peer) return -1; + return peer->getStat(type); +} + +float Connection::getLocalStat(rate_stat_type type) +{ + PeerHelper peer = getPeerNoEx(PEER_ID_SERVER); + + FATAL_ERROR_IF(!peer, "Connection::getLocalStat we couldn't get our own peer? are you serious???"); + + float retval = 0.0; + + for (Channel &channel : dynamic_cast<UDPPeer *>(&peer)->channels) { + switch(type) { + case CUR_DL_RATE: + retval += channel.getCurrentDownloadRateKB(); + break; + case AVG_DL_RATE: + retval += channel.getAvgDownloadRateKB(); + break; + case CUR_INC_RATE: + retval += channel.getCurrentIncomingRateKB(); + break; + case AVG_INC_RATE: + retval += channel.getAvgIncomingRateKB(); + break; + case AVG_LOSS_RATE: + retval += channel.getAvgLossRateKB(); + break; + case CUR_LOSS_RATE: + retval += channel.getCurrentLossRateKB(); + break; + default: + FATAL_ERROR("Connection::getLocalStat Invalid stat type"); + } + } + return retval; +} + +u16 Connection::createPeer(Address& sender, MTProtocols protocol, int fd) +{ + // Somebody wants to make a new connection + + // Get a unique peer id (2 or higher) + session_t peer_id_new = m_next_remote_peer_id; + u16 overflow = MAX_UDP_PEERS; + + /* + Find an unused peer id + */ + MutexAutoLock lock(m_peers_mutex); + bool out_of_ids = false; + for(;;) { + // Check if exists + if (m_peers.find(peer_id_new) == m_peers.end()) + + break; + // Check for overflow + if (peer_id_new == overflow) { + out_of_ids = true; + break; + } + peer_id_new++; + } + + if (out_of_ids) { + errorstream << getDesc() << " ran out of peer ids" << std::endl; + return PEER_ID_INEXISTENT; + } + + // Create a peer + Peer *peer = 0; + peer = new UDPPeer(peer_id_new, sender, this); + + m_peers[peer->id] = peer; + m_peer_ids.push_back(peer->id); + + m_next_remote_peer_id = (peer_id_new +1 ) % MAX_UDP_PEERS; + + LOG(dout_con << getDesc() + << "createPeer(): giving peer_id=" << peer_id_new << std::endl); + + { + Buffer<u8> reply(4); + writeU8(&reply[0], PACKET_TYPE_CONTROL); + writeU8(&reply[1], CONTROLTYPE_SET_PEER_ID); + writeU16(&reply[2], peer_id_new); + putCommand(ConnectionCommand::createPeer(peer_id_new, reply)); + } + + // Create peer addition event + putEvent(ConnectionEvent::peerAdded(peer_id_new, sender)); + + // We're now talking to a valid peer_id + return peer_id_new; +} + +const std::string Connection::getDesc() +{ + MutexAutoLock _(m_info_mutex); + return std::string("con(")+ + itos(m_udpSocket.GetHandle())+"/"+itos(m_peer_id)+")"; +} + +void Connection::DisconnectPeer(session_t peer_id) +{ + putCommand(ConnectionCommand::disconnect_peer(peer_id)); +} + +void Connection::sendAck(session_t peer_id, u8 channelnum, u16 seqnum) +{ + assert(channelnum < CHANNEL_COUNT); // Pre-condition + + LOG(dout_con<<getDesc() + <<" Queuing ACK command to peer_id: " << peer_id << + " channel: " << (channelnum & 0xFF) << + " seqnum: " << seqnum << std::endl); + + SharedBuffer<u8> ack(4); + writeU8(&ack[0], PACKET_TYPE_CONTROL); + writeU8(&ack[1], CONTROLTYPE_ACK); + writeU16(&ack[2], seqnum); + + putCommand(ConnectionCommand::ack(peer_id, channelnum, ack)); + m_sendThread->Trigger(); +} + +UDPPeer* Connection::createServerPeer(Address& address) +{ + if (ConnectedToServer()) + { + throw ConnectionException("Already connected to a server"); + } + + UDPPeer *peer = new UDPPeer(PEER_ID_SERVER, address, this); + + { + MutexAutoLock lock(m_peers_mutex); + m_peers[peer->id] = peer; + m_peer_ids.push_back(peer->id); + } + + return peer; +} + +} // namespace diff --git a/src/network/connection.h b/src/network/connection.h new file mode 100644 index 0000000..b5ae248 --- /dev/null +++ b/src/network/connection.h @@ -0,0 +1,785 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "peerhandler.h" +#include "socket.h" +#include "constants.h" +#include "util/pointer.h" +#include "util/container.h" +#include "util/thread.h" +#include "util/numeric.h" +#include "networkprotocol.h" +#include <iostream> +#include <vector> +#include <map> + +#define MAX_UDP_PEERS 65535 + +/* +=== NOTES === + +A packet is sent through a channel to a peer with a basic header: + Header (7 bytes): + [0] u32 protocol_id + [4] session_t sender_peer_id + [6] u8 channel +sender_peer_id: + Unique to each peer. + value 0 (PEER_ID_INEXISTENT) is reserved for making new connections + value 1 (PEER_ID_SERVER) is reserved for server + these constants are defined in constants.h +channel: + Channel numbers have no intrinsic meaning. Currently only 0, 1, 2 exist. +*/ +#define BASE_HEADER_SIZE 7 +#define CHANNEL_COUNT 3 + +/* +Packet types: + +CONTROL: This is a packet used by the protocol. +- When this is processed, nothing is handed to the user. + Header (2 byte): + [0] u8 type + [1] u8 controltype +controltype and data description: + CONTROLTYPE_ACK + [2] u16 seqnum + CONTROLTYPE_SET_PEER_ID + [2] session_t peer_id_new + CONTROLTYPE_PING + - There is no actual reply, but this can be sent in a reliable + packet to get a reply + CONTROLTYPE_DISCO +*/ +enum ControlType : u8 { + CONTROLTYPE_ACK = 0, + CONTROLTYPE_SET_PEER_ID = 1, + CONTROLTYPE_PING = 2, + CONTROLTYPE_DISCO = 3, +}; + +/* +ORIGINAL: This is a plain packet with no control and no error +checking at all. +- When this is processed, it is directly handed to the user. + Header (1 byte): + [0] u8 type +*/ +//#define TYPE_ORIGINAL 1 +#define ORIGINAL_HEADER_SIZE 1 + +/* +SPLIT: These are sequences of packets forming one bigger piece of +data. +- When processed and all the packet_nums 0...packet_count-1 are + present (this should be buffered), the resulting data shall be + directly handed to the user. +- If the data fails to come up in a reasonable time, the buffer shall + be silently discarded. +- These can be sent as-is or atop of a RELIABLE packet stream. + Header (7 bytes): + [0] u8 type + [1] u16 seqnum + [3] u16 chunk_count + [5] u16 chunk_num +*/ +//#define TYPE_SPLIT 2 + +/* +RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs, +and they shall be delivered in the same order as sent. This is done +with a buffer in the receiving and transmitting end. +- When this is processed, the contents of each packet is recursively + processed as packets. + Header (3 bytes): + [0] u8 type + [1] u16 seqnum + +*/ +//#define TYPE_RELIABLE 3 +#define RELIABLE_HEADER_SIZE 3 +#define SEQNUM_INITIAL 65500 +#define SEQNUM_MAX 65535 + +class NetworkPacket; + +namespace con +{ + +class ConnectionReceiveThread; +class ConnectionSendThread; + +typedef enum MTProtocols { + MTP_PRIMARY, + MTP_UDP, + MTP_MINETEST_RELIABLE_UDP +} MTProtocols; + +enum PacketType : u8 { + PACKET_TYPE_CONTROL = 0, + PACKET_TYPE_ORIGINAL = 1, + PACKET_TYPE_SPLIT = 2, + PACKET_TYPE_RELIABLE = 3, + PACKET_TYPE_MAX +}; + +inline bool seqnum_higher(u16 totest, u16 base) +{ + if (totest > base) + { + if ((totest - base) > (SEQNUM_MAX/2)) + return false; + + return true; + } + + if ((base - totest) > (SEQNUM_MAX/2)) + return true; + + return false; +} + +inline bool seqnum_in_window(u16 seqnum, u16 next,u16 window_size) +{ + u16 window_start = next; + u16 window_end = ( next + window_size ) % (SEQNUM_MAX+1); + + if (window_start < window_end) { + return ((seqnum >= window_start) && (seqnum < window_end)); + } + + + return ((seqnum < window_end) || (seqnum >= window_start)); +} + +static inline float CALC_DTIME(u64 lasttime, u64 curtime) +{ + float value = ( curtime - lasttime) / 1000.0; + return MYMAX(MYMIN(value,0.1),0.0); +} + +/* + Struct for all kinds of packets. Includes following data: + BASE_HEADER + u8[] packet data (usually copied from SharedBuffer<u8>) +*/ +struct BufferedPacket { + BufferedPacket(u32 a_size) + { + m_data.resize(a_size); + data = &m_data[0]; + } + + DISABLE_CLASS_COPY(BufferedPacket) + + u16 getSeqnum() const; + + inline size_t size() const { return m_data.size(); } + + u8 *data; // Direct memory access + float time = 0.0f; // Seconds from buffering the packet or re-sending + float totaltime = 0.0f; // Seconds from buffering the packet + u64 absolute_send_time = -1; + Address address; // Sender or destination + unsigned int resend_count = 0; + +private: + std::vector<u8> m_data; // Data of the packet, including headers +}; + +typedef std::shared_ptr<BufferedPacket> BufferedPacketPtr; + + +// This adds the base headers to the data and makes a packet out of it +BufferedPacketPtr makePacket(Address &address, const SharedBuffer<u8> &data, + u32 protocol_id, session_t sender_peer_id, u8 channel); + +// Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet +// Increments split_seqnum if a split packet is made +void makeAutoSplitPacket(const SharedBuffer<u8> &data, u32 chunksize_max, + u16 &split_seqnum, std::list<SharedBuffer<u8>> *list); + +// Add the TYPE_RELIABLE header to the data +SharedBuffer<u8> makeReliablePacket(const SharedBuffer<u8> &data, u16 seqnum); + +struct IncomingSplitPacket +{ + IncomingSplitPacket(u32 cc, bool r): + chunk_count(cc), reliable(r) {} + + IncomingSplitPacket() = delete; + + float time = 0.0f; // Seconds from adding + u32 chunk_count; + bool reliable; // If true, isn't deleted on timeout + + bool allReceived() const + { + return (chunks.size() == chunk_count); + } + bool insert(u32 chunk_num, SharedBuffer<u8> &chunkdata); + SharedBuffer<u8> reassemble(); + +private: + // Key is chunk number, value is data without headers + std::map<u16, SharedBuffer<u8>> chunks; +}; + +/* + A buffer which stores reliable packets and sorts them internally + for fast access to the smallest one. +*/ + +typedef std::list<BufferedPacketPtr>::iterator RPBSearchResult; + +class ReliablePacketBuffer +{ +public: + ReliablePacketBuffer() = default; + + bool getFirstSeqnum(u16& result); + + BufferedPacketPtr popFirst(); + BufferedPacketPtr popSeqnum(u16 seqnum); + void insert(BufferedPacketPtr &p_ptr, u16 next_expected); + + void incrementTimeouts(float dtime); + std::list<ConstSharedPtr<BufferedPacket>> getTimedOuts(float timeout, u32 max_packets); + + void print(); + bool empty(); + u32 size(); + + +private: + RPBSearchResult findPacketNoLock(u16 seqnum); + + std::list<BufferedPacketPtr> m_list; + + u16 m_oldest_non_answered_ack; + + std::mutex m_list_mutex; +}; + +/* + A buffer for reconstructing split packets +*/ + +class IncomingSplitBuffer +{ +public: + ~IncomingSplitBuffer(); + /* + Returns a reference counted buffer of length != 0 when a full split + packet is constructed. If not, returns one of length 0. + */ + SharedBuffer<u8> insert(BufferedPacketPtr &p_ptr, bool reliable); + + void removeUnreliableTimedOuts(float dtime, float timeout); + +private: + // Key is seqnum + std::map<u16, IncomingSplitPacket*> m_buf; + + std::mutex m_map_mutex; +}; + +enum ConnectionCommandType{ + CONNCMD_NONE, + CONNCMD_SERVE, + CONNCMD_CONNECT, + CONNCMD_DISCONNECT, + CONNCMD_DISCONNECT_PEER, + CONNCMD_SEND, + CONNCMD_SEND_TO_ALL, + CONCMD_ACK, + CONCMD_CREATE_PEER +}; + +struct ConnectionCommand; +typedef std::shared_ptr<ConnectionCommand> ConnectionCommandPtr; + +// This is very similar to ConnectionEvent +struct ConnectionCommand +{ + const ConnectionCommandType type; + Address address; + session_t peer_id = PEER_ID_INEXISTENT; + u8 channelnum = 0; + Buffer<u8> data; + bool reliable = false; + bool raw = false; + + DISABLE_CLASS_COPY(ConnectionCommand); + + static ConnectionCommandPtr serve(Address address); + static ConnectionCommandPtr connect(Address address); + static ConnectionCommandPtr disconnect(); + static ConnectionCommandPtr disconnect_peer(session_t peer_id); + static ConnectionCommandPtr send(session_t peer_id, u8 channelnum, NetworkPacket *pkt, bool reliable); + static ConnectionCommandPtr ack(session_t peer_id, u8 channelnum, const Buffer<u8> &data); + static ConnectionCommandPtr createPeer(session_t peer_id, const Buffer<u8> &data); + +private: + ConnectionCommand(ConnectionCommandType type_) : + type(type_) {} + + static ConnectionCommandPtr create(ConnectionCommandType type); +}; + +/* maximum window size to use, 0xFFFF is theoretical maximum. don't think about + * touching it, the less you're away from it the more likely data corruption + * will occur + */ +#define MAX_RELIABLE_WINDOW_SIZE 0x8000 +/* starting value for window size */ +#define START_RELIABLE_WINDOW_SIZE 0x400 +/* minimum value for window size */ +#define MIN_RELIABLE_WINDOW_SIZE 0x40 + +class Channel +{ + +public: + u16 readNextIncomingSeqNum(); + u16 incNextIncomingSeqNum(); + + u16 getOutgoingSequenceNumber(bool& successfull); + u16 readOutgoingSequenceNumber(); + bool putBackSequenceNumber(u16); + + u16 readNextSplitSeqNum(); + void setNextSplitSeqNum(u16 seqnum); + + // This is for buffering the incoming packets that are coming in + // the wrong order + ReliablePacketBuffer incoming_reliables; + // This is for buffering the sent packets so that the sender can + // re-send them if no ACK is received + ReliablePacketBuffer outgoing_reliables_sent; + + //queued reliable packets + std::queue<BufferedPacketPtr> queued_reliables; + + //queue commands prior splitting to packets + std::deque<ConnectionCommandPtr> queued_commands; + + IncomingSplitBuffer incoming_splits; + + Channel() = default; + ~Channel() = default; + + void UpdatePacketLossCounter(unsigned int count); + void UpdatePacketTooLateCounter(); + void UpdateBytesSent(unsigned int bytes,unsigned int packages=1); + void UpdateBytesLost(unsigned int bytes); + void UpdateBytesReceived(unsigned int bytes); + + void UpdateTimers(float dtime); + + float getCurrentDownloadRateKB() + { MutexAutoLock lock(m_internal_mutex); return cur_kbps; }; + float getMaxDownloadRateKB() + { MutexAutoLock lock(m_internal_mutex); return max_kbps; }; + + float getCurrentLossRateKB() + { MutexAutoLock lock(m_internal_mutex); return cur_kbps_lost; }; + float getMaxLossRateKB() + { MutexAutoLock lock(m_internal_mutex); return max_kbps_lost; }; + + float getCurrentIncomingRateKB() + { MutexAutoLock lock(m_internal_mutex); return cur_incoming_kbps; }; + float getMaxIncomingRateKB() + { MutexAutoLock lock(m_internal_mutex); return max_incoming_kbps; }; + + float getAvgDownloadRateKB() + { MutexAutoLock lock(m_internal_mutex); return avg_kbps; }; + float getAvgLossRateKB() + { MutexAutoLock lock(m_internal_mutex); return avg_kbps_lost; }; + float getAvgIncomingRateKB() + { MutexAutoLock lock(m_internal_mutex); return avg_incoming_kbps; }; + + u16 getWindowSize() const { return m_window_size; }; + + void setWindowSize(long size) + { + m_window_size = (u16)rangelim(size, MIN_RELIABLE_WINDOW_SIZE, MAX_RELIABLE_WINDOW_SIZE); + } + +private: + std::mutex m_internal_mutex; + u16 m_window_size = MIN_RELIABLE_WINDOW_SIZE; + + u16 next_incoming_seqnum = SEQNUM_INITIAL; + + u16 next_outgoing_seqnum = SEQNUM_INITIAL; + u16 next_outgoing_split_seqnum = SEQNUM_INITIAL; + + unsigned int current_packet_loss = 0; + unsigned int current_packet_too_late = 0; + unsigned int current_packet_successful = 0; + float packet_loss_counter = 0.0f; + + unsigned int current_bytes_transfered = 0; + unsigned int current_bytes_received = 0; + unsigned int current_bytes_lost = 0; + float max_kbps = 0.0f; + float cur_kbps = 0.0f; + float avg_kbps = 0.0f; + float max_incoming_kbps = 0.0f; + float cur_incoming_kbps = 0.0f; + float avg_incoming_kbps = 0.0f; + float max_kbps_lost = 0.0f; + float cur_kbps_lost = 0.0f; + float avg_kbps_lost = 0.0f; + float bpm_counter = 0.0f; + + unsigned int rate_samples = 0; +}; + +class Peer; + +class PeerHelper +{ +public: + PeerHelper() = default; + PeerHelper(Peer* peer); + ~PeerHelper(); + + PeerHelper& operator=(Peer* peer); + Peer* operator->() const; + bool operator!(); + Peer* operator&() const; + bool operator!=(void* ptr); + +private: + Peer *m_peer = nullptr; +}; + +class Connection; + +typedef enum { + CUR_DL_RATE, + AVG_DL_RATE, + CUR_INC_RATE, + AVG_INC_RATE, + CUR_LOSS_RATE, + AVG_LOSS_RATE, +} rate_stat_type; + +class Peer { + public: + friend class PeerHelper; + + Peer(Address address_,session_t id_,Connection* connection) : + id(id_), + m_connection(connection), + address(address_), + m_last_timeout_check(porting::getTimeMs()) + { + }; + + virtual ~Peer() { + MutexAutoLock usage_lock(m_exclusive_access_mutex); + FATAL_ERROR_IF(m_usage != 0, "Reference counting failure"); + }; + + // Unique id of the peer + const session_t id; + + void Drop(); + + virtual void PutReliableSendCommand(ConnectionCommandPtr &c, + unsigned int max_packet_size) {}; + + virtual bool getAddress(MTProtocols type, Address& toset) = 0; + + bool isPendingDeletion() + { MutexAutoLock lock(m_exclusive_access_mutex); return m_pending_deletion; }; + + void ResetTimeout() + {MutexAutoLock lock(m_exclusive_access_mutex); m_timeout_counter = 0.0; }; + + bool isTimedOut(float timeout); + + unsigned int m_increment_packets_remaining = 0; + + virtual u16 getNextSplitSequenceNumber(u8 channel) { return 0; }; + virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum) {}; + virtual SharedBuffer<u8> addSplitPacket(u8 channel, BufferedPacketPtr &toadd, + bool reliable) + { + errorstream << "Peer::addSplitPacket called," + << " this is supposed to be never called!" << std::endl; + return SharedBuffer<u8>(0); + }; + + virtual bool Ping(float dtime, SharedBuffer<u8>& data) { return false; }; + + virtual float getStat(rtt_stat_type type) const { + switch (type) { + case MIN_RTT: + return m_rtt.min_rtt; + case MAX_RTT: + return m_rtt.max_rtt; + case AVG_RTT: + return m_rtt.avg_rtt; + case MIN_JITTER: + return m_rtt.jitter_min; + case MAX_JITTER: + return m_rtt.jitter_max; + case AVG_JITTER: + return m_rtt.jitter_avg; + } + return -1; + } + protected: + virtual void reportRTT(float rtt) {}; + + void RTTStatistics(float rtt, + const std::string &profiler_id = "", + unsigned int num_samples = 1000); + + bool IncUseCount(); + void DecUseCount(); + + mutable std::mutex m_exclusive_access_mutex; + + bool m_pending_deletion = false; + + Connection* m_connection; + + // Address of the peer + Address address; + + // Ping timer + float m_ping_timer = 0.0f; + private: + + struct rttstats { + float jitter_min = FLT_MAX; + float jitter_max = 0.0f; + float jitter_avg = -1.0f; + float min_rtt = FLT_MAX; + float max_rtt = 0.0f; + float avg_rtt = -1.0f; + + rttstats() = default; + }; + + rttstats m_rtt; + float m_last_rtt = -1.0f; + + // current usage count + unsigned int m_usage = 0; + + // Seconds from last receive + float m_timeout_counter = 0.0f; + + u64 m_last_timeout_check; +}; + +class UDPPeer : public Peer +{ +public: + + friend class PeerHelper; + friend class ConnectionReceiveThread; + friend class ConnectionSendThread; + friend class Connection; + + UDPPeer(u16 a_id, Address a_address, Connection* connection); + virtual ~UDPPeer() = default; + + void PutReliableSendCommand(ConnectionCommandPtr &c, + unsigned int max_packet_size); + + bool getAddress(MTProtocols type, Address& toset); + + u16 getNextSplitSequenceNumber(u8 channel); + void setNextSplitSequenceNumber(u8 channel, u16 seqnum); + + SharedBuffer<u8> addSplitPacket(u8 channel, BufferedPacketPtr &toadd, + bool reliable); + +protected: + /* + Calculates avg_rtt and resend_timeout. + rtt=-1 only recalculates resend_timeout + */ + void reportRTT(float rtt); + + void RunCommandQueues( + unsigned int max_packet_size, + unsigned int maxcommands, + unsigned int maxtransfer); + + float getResendTimeout() + { MutexAutoLock lock(m_exclusive_access_mutex); return resend_timeout; } + + void setResendTimeout(float timeout) + { MutexAutoLock lock(m_exclusive_access_mutex); resend_timeout = timeout; } + bool Ping(float dtime,SharedBuffer<u8>& data); + + Channel channels[CHANNEL_COUNT]; + bool m_pending_disconnect = false; +private: + // This is changed dynamically + float resend_timeout = 0.5; + + bool processReliableSendCommand( + ConnectionCommandPtr &c_ptr, + unsigned int max_packet_size); +}; + +/* + Connection +*/ + +enum ConnectionEventType { + CONNEVENT_NONE, + CONNEVENT_DATA_RECEIVED, + CONNEVENT_PEER_ADDED, + CONNEVENT_PEER_REMOVED, + CONNEVENT_BIND_FAILED, +}; + +struct ConnectionEvent; +typedef std::shared_ptr<ConnectionEvent> ConnectionEventPtr; + +// This is very similar to ConnectionCommand +struct ConnectionEvent +{ + const ConnectionEventType type; + session_t peer_id = 0; + Buffer<u8> data; + bool timeout = false; + Address address; + + // We don't want to copy "data" + DISABLE_CLASS_COPY(ConnectionEvent); + + static ConnectionEventPtr create(ConnectionEventType type); + static ConnectionEventPtr dataReceived(session_t peer_id, const Buffer<u8> &data); + static ConnectionEventPtr peerAdded(session_t peer_id, Address address); + static ConnectionEventPtr peerRemoved(session_t peer_id, bool is_timeout, Address address); + static ConnectionEventPtr bindFailed(); + + const char *describe() const; + +private: + ConnectionEvent(ConnectionEventType type_) : + type(type_) {} +}; + +class PeerHandler; + +class Connection +{ +public: + friend class ConnectionSendThread; + friend class ConnectionReceiveThread; + + Connection(u32 protocol_id, u32 max_packet_size, float timeout, bool ipv6, + PeerHandler *peerhandler); + ~Connection(); + + /* Interface */ + ConnectionEventPtr waitEvent(u32 timeout_ms); + + void putCommand(ConnectionCommandPtr c); + + void SetTimeoutMs(u32 timeout) { m_bc_receive_timeout = timeout; } + void Serve(Address bind_addr); + void Connect(Address address); + bool Connected(); + void Disconnect(); + void Receive(NetworkPacket* pkt); + bool TryReceive(NetworkPacket *pkt); + void Send(session_t peer_id, u8 channelnum, NetworkPacket *pkt, bool reliable); + session_t GetPeerID() const { return m_peer_id; } + Address GetPeerAddress(session_t peer_id); + float getPeerStat(session_t peer_id, rtt_stat_type type); + float getLocalStat(rate_stat_type type); + u32 GetProtocolID() const { return m_protocol_id; }; + const std::string getDesc(); + void DisconnectPeer(session_t peer_id); + +protected: + PeerHelper getPeerNoEx(session_t peer_id); + u16 lookupPeer(Address& sender); + + u16 createPeer(Address& sender, MTProtocols protocol, int fd); + UDPPeer* createServerPeer(Address& sender); + bool deletePeer(session_t peer_id, bool timeout); + + void SetPeerID(session_t id) { m_peer_id = id; } + + void sendAck(session_t peer_id, u8 channelnum, u16 seqnum); + + std::vector<session_t> getPeerIDs() + { + MutexAutoLock peerlock(m_peers_mutex); + return m_peer_ids; + } + + UDPSocket m_udpSocket; + // Command queue: user -> SendThread + MutexedQueue<ConnectionCommandPtr> m_command_queue; + + bool Receive(NetworkPacket *pkt, u32 timeout); + + void putEvent(ConnectionEventPtr e); + + void TriggerSend(); + + bool ConnectedToServer() + { + return getPeerNoEx(PEER_ID_SERVER) != nullptr; + } +private: + // Event queue: ReceiveThread -> user + MutexedQueue<ConnectionEventPtr> m_event_queue; + + session_t m_peer_id = 0; + u32 m_protocol_id; + + std::map<session_t, Peer *> m_peers; + std::vector<session_t> m_peer_ids; + std::mutex m_peers_mutex; + + std::unique_ptr<ConnectionSendThread> m_sendThread; + std::unique_ptr<ConnectionReceiveThread> m_receiveThread; + + mutable std::mutex m_info_mutex; + + // Backwards compatibility + PeerHandler *m_bc_peerhandler; + u32 m_bc_receive_timeout = 0; + + bool m_shutting_down = false; + + session_t m_next_remote_peer_id = 2; +}; + +} // namespace diff --git a/src/network/connectionthreads.cpp b/src/network/connectionthreads.cpp new file mode 100644 index 0000000..90936b4 --- /dev/null +++ b/src/network/connectionthreads.cpp @@ -0,0 +1,1358 @@ +/* +Minetest +Copyright (C) 2013-2017 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 celeron55, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "connectionthreads.h" +#include "log.h" +#include "profiler.h" +#include "settings.h" +#include "network/networkpacket.h" +#include "util/serialize.h" + +namespace con +{ + +/******************************************************************************/ +/* defines used for debugging and profiling */ +/******************************************************************************/ +#ifdef NDEBUG +#define PROFILE(a) +#undef DEBUG_CONNECTION_KBPS +#else +/* this mutex is used to achieve log message consistency */ +#define PROFILE(a) a +//#define DEBUG_CONNECTION_KBPS +#undef DEBUG_CONNECTION_KBPS +#endif + +// TODO: Clean this up. +#define LOG(a) a + +#define WINDOW_SIZE 5 + +static session_t readPeerId(const u8 *packetdata) +{ + return readU16(&packetdata[4]); +} +static u8 readChannel(const u8 *packetdata) +{ + return readU8(&packetdata[6]); +} + +/******************************************************************************/ +/* Connection Threads */ +/******************************************************************************/ + +ConnectionSendThread::ConnectionSendThread(unsigned int max_packet_size, + float timeout) : + Thread("ConnectionSend"), + m_max_packet_size(max_packet_size), + m_timeout(timeout), + m_max_data_packets_per_iteration(g_settings->getU16("max_packets_per_iteration")) +{ + SANITY_CHECK(m_max_data_packets_per_iteration > 1); +} + +void *ConnectionSendThread::run() +{ + assert(m_connection); + + LOG(dout_con << m_connection->getDesc() + << "ConnectionSend thread started" << std::endl); + + u64 curtime = porting::getTimeMs(); + u64 lasttime = curtime; + + PROFILE(std::stringstream ThreadIdentifier); + PROFILE(ThreadIdentifier << "ConnectionSend: [" << m_connection->getDesc() << "]"); + + /* if stop is requested don't stop immediately but try to send all */ + /* packets first */ + while (!stopRequested() || packetsQueued()) { + BEGIN_DEBUG_EXCEPTION_HANDLER + PROFILE(ScopeProfiler sp(g_profiler, ThreadIdentifier.str(), SPT_AVG)); + + m_iteration_packets_avaialble = m_max_data_packets_per_iteration; + + /* wait for trigger or timeout */ + m_send_sleep_semaphore.wait(50); + + /* remove all triggers */ + while (m_send_sleep_semaphore.wait(0)) { + } + + lasttime = curtime; + curtime = porting::getTimeMs(); + float dtime = CALC_DTIME(lasttime, curtime); + + /* first resend timed-out packets */ + runTimeouts(dtime); + if (m_iteration_packets_avaialble == 0) { + LOG(warningstream << m_connection->getDesc() + << " Packet quota used up after re-sending packets, " + << "max=" << m_max_data_packets_per_iteration << std::endl); + } + + /* translate commands to packets */ + auto c = m_connection->m_command_queue.pop_frontNoEx(0); + while (c && c->type != CONNCMD_NONE) { + if (c->reliable) + processReliableCommand(c); + else + processNonReliableCommand(c); + + c = m_connection->m_command_queue.pop_frontNoEx(0); + } + + /* send queued packets */ + sendPackets(dtime); + + END_DEBUG_EXCEPTION_HANDLER + } + + PROFILE(g_profiler->remove(ThreadIdentifier.str())); + return NULL; +} + +void ConnectionSendThread::Trigger() +{ + m_send_sleep_semaphore.post(); +} + +bool ConnectionSendThread::packetsQueued() +{ + std::vector<session_t> peerIds = m_connection->getPeerIDs(); + + if (!m_outgoing_queue.empty() && !peerIds.empty()) + return true; + + for (session_t peerId : peerIds) { + PeerHelper peer = m_connection->getPeerNoEx(peerId); + + if (!peer) + continue; + + if (dynamic_cast<UDPPeer *>(&peer) == 0) + continue; + + for (Channel &channel : (dynamic_cast<UDPPeer *>(&peer))->channels) { + if (!channel.queued_commands.empty()) { + return true; + } + } + } + + + return false; +} + +void ConnectionSendThread::runTimeouts(float dtime) +{ + std::vector<session_t> timeouted_peers; + std::vector<session_t> peerIds = m_connection->getPeerIDs(); + + const u32 numpeers = m_connection->m_peers.size(); + + if (numpeers == 0) + return; + + for (session_t &peerId : peerIds) { + PeerHelper peer = m_connection->getPeerNoEx(peerId); + + if (!peer) + continue; + + UDPPeer *udpPeer = dynamic_cast<UDPPeer *>(&peer); + if (!udpPeer) + continue; + + PROFILE(std::stringstream peerIdentifier); + PROFILE(peerIdentifier << "runTimeouts[" << m_connection->getDesc() + << ";" << peerId << ";RELIABLE]"); + PROFILE(ScopeProfiler + peerprofiler(g_profiler, peerIdentifier.str(), SPT_AVG)); + + SharedBuffer<u8> data(2); // data for sending ping, required here because of goto + + /* + Check peer timeout + */ + if (peer->isTimedOut(m_timeout)) { + infostream << m_connection->getDesc() + << "RunTimeouts(): Peer " << peer->id + << " has timed out." + << std::endl; + // Add peer to the list + timeouted_peers.push_back(peer->id); + // Don't bother going through the buffers of this one + continue; + } + + float resend_timeout = udpPeer->getResendTimeout(); + for (Channel &channel : udpPeer->channels) { + + // Remove timed out incomplete unreliable split packets + channel.incoming_splits.removeUnreliableTimedOuts(dtime, m_timeout); + + // Increment reliable packet times + channel.outgoing_reliables_sent.incrementTimeouts(dtime); + + // Re-send timed out outgoing reliables + auto timed_outs = channel.outgoing_reliables_sent.getTimedOuts(resend_timeout, + (m_max_data_packets_per_iteration / numpeers)); + + channel.UpdatePacketLossCounter(timed_outs.size()); + g_profiler->graphAdd("packets_lost", timed_outs.size()); + + m_iteration_packets_avaialble -= timed_outs.size(); + + for (const auto &k : timed_outs) { + u8 channelnum = readChannel(k->data); + u16 seqnum = k->getSeqnum(); + + channel.UpdateBytesLost(k->size()); + + LOG(derr_con << m_connection->getDesc() + << "RE-SENDING timed-out RELIABLE to " + << k->address.serializeString() + << "(t/o=" << resend_timeout << "): " + << "count=" << k->resend_count + << ", channel=" << ((int) channelnum & 0xff) + << ", seqnum=" << seqnum + << std::endl); + + rawSend(k.get()); + + // do not handle rtt here as we can't decide if this packet was + // lost or really takes more time to transmit + } + + channel.UpdateTimers(dtime); + } + + /* send ping if necessary */ + if (udpPeer->Ping(dtime, data)) { + LOG(dout_con << m_connection->getDesc() + << "Sending ping for peer_id: " << udpPeer->id << std::endl); + /* this may fail if there ain't a sequence number left */ + if (!rawSendAsPacket(udpPeer->id, 0, data, true)) { + //retrigger with reduced ping interval + udpPeer->Ping(4.0, data); + } + } + + udpPeer->RunCommandQueues(m_max_packet_size, + m_max_commands_per_iteration, + m_max_packets_requeued); + } + + // Remove timed out peers + for (u16 timeouted_peer : timeouted_peers) { + LOG(dout_con << m_connection->getDesc() + << "RunTimeouts(): Removing peer " << timeouted_peer << std::endl); + m_connection->deletePeer(timeouted_peer, true); + } +} + +void ConnectionSendThread::rawSend(const BufferedPacket *p) +{ + try { + m_connection->m_udpSocket.Send(p->address, p->data, p->size()); + LOG(dout_con << m_connection->getDesc() + << " rawSend: " << p->size() + << " bytes sent" << std::endl); + } catch (SendFailedException &e) { + LOG(derr_con << m_connection->getDesc() + << "Connection::rawSend(): SendFailedException: " + << p->address.serializeString() << std::endl); + } +} + +void ConnectionSendThread::sendAsPacketReliable(BufferedPacketPtr &p, Channel *channel) +{ + try { + p->absolute_send_time = porting::getTimeMs(); + // Buffer the packet + channel->outgoing_reliables_sent.insert(p, + (channel->readOutgoingSequenceNumber() - MAX_RELIABLE_WINDOW_SIZE) + % (MAX_RELIABLE_WINDOW_SIZE + 1)); + } + catch (AlreadyExistsException &e) { + LOG(derr_con << m_connection->getDesc() + << "WARNING: Going to send a reliable packet" + << " in outgoing buffer" << std::endl); + } + + // Send the packet + rawSend(p.get()); +} + +bool ConnectionSendThread::rawSendAsPacket(session_t peer_id, u8 channelnum, + const SharedBuffer<u8> &data, bool reliable) +{ + PeerHelper peer = m_connection->getPeerNoEx(peer_id); + if (!peer) { + LOG(errorstream << m_connection->getDesc() + << " dropped " << (reliable ? "reliable " : "") + << "packet for non existent peer_id: " << peer_id << std::endl); + return false; + } + Channel *channel = &(dynamic_cast<UDPPeer *>(&peer)->channels[channelnum]); + + if (reliable) { + bool have_seqnum = false; + const u16 seqnum = channel->getOutgoingSequenceNumber(have_seqnum); + + if (!have_seqnum) + return false; + + SharedBuffer<u8> reliable = makeReliablePacket(data, seqnum); + Address peer_address; + peer->getAddress(MTP_MINETEST_RELIABLE_UDP, peer_address); + + // Add base headers and make a packet + BufferedPacketPtr p = con::makePacket(peer_address, reliable, + m_connection->GetProtocolID(), m_connection->GetPeerID(), + channelnum); + + // first check if our send window is already maxed out + if (channel->outgoing_reliables_sent.size() < channel->getWindowSize()) { + LOG(dout_con << m_connection->getDesc() + << " INFO: sending a reliable packet to peer_id " << peer_id + << " channel: " << (u32)channelnum + << " seqnum: " << seqnum << std::endl); + sendAsPacketReliable(p, channel); + return true; + } + + LOG(dout_con << m_connection->getDesc() + << " INFO: queueing reliable packet for peer_id: " << peer_id + << " channel: " << (u32)channelnum + << " seqnum: " << seqnum << std::endl); + channel->queued_reliables.push(p); + return false; + } + + Address peer_address; + if (peer->getAddress(MTP_UDP, peer_address)) { + // Add base headers and make a packet + BufferedPacketPtr p = con::makePacket(peer_address, data, + m_connection->GetProtocolID(), m_connection->GetPeerID(), + channelnum); + + // Send the packet + rawSend(p.get()); + return true; + } + + LOG(dout_con << m_connection->getDesc() + << " INFO: dropped unreliable packet for peer_id: " << peer_id + << " because of (yet) missing udp address" << std::endl); + return false; +} + +void ConnectionSendThread::processReliableCommand(ConnectionCommandPtr &c) +{ + assert(c->reliable); // Pre-condition + + switch (c->type) { + case CONNCMD_NONE: + LOG(dout_con << m_connection->getDesc() + << "UDP processing reliable CONNCMD_NONE" << std::endl); + return; + + case CONNCMD_SEND: + LOG(dout_con << m_connection->getDesc() + << "UDP processing reliable CONNCMD_SEND" << std::endl); + sendReliable(c); + return; + + case CONNCMD_SEND_TO_ALL: + LOG(dout_con << m_connection->getDesc() + << "UDP processing CONNCMD_SEND_TO_ALL" << std::endl); + sendToAllReliable(c); + return; + + case CONCMD_CREATE_PEER: + LOG(dout_con << m_connection->getDesc() + << "UDP processing reliable CONCMD_CREATE_PEER" << std::endl); + if (!rawSendAsPacket(c->peer_id, c->channelnum, c->data, c->reliable)) { + /* put to queue if we couldn't send it immediately */ + sendReliable(c); + } + return; + + case CONNCMD_SERVE: + case CONNCMD_CONNECT: + case CONNCMD_DISCONNECT: + case CONCMD_ACK: + FATAL_ERROR("Got command that shouldn't be reliable as reliable command"); + default: + LOG(dout_con << m_connection->getDesc() + << " Invalid reliable command type: " << c->type << std::endl); + } +} + + +void ConnectionSendThread::processNonReliableCommand(ConnectionCommandPtr &c_ptr) +{ + const ConnectionCommand &c = *c_ptr; + assert(!c.reliable); // Pre-condition + + switch (c.type) { + case CONNCMD_NONE: + LOG(dout_con << m_connection->getDesc() + << " UDP processing CONNCMD_NONE" << std::endl); + return; + case CONNCMD_SERVE: + LOG(dout_con << m_connection->getDesc() + << " UDP processing CONNCMD_SERVE port=" + << c.address.serializeString() << std::endl); + serve(c.address); + return; + case CONNCMD_CONNECT: + LOG(dout_con << m_connection->getDesc() + << " UDP processing CONNCMD_CONNECT" << std::endl); + connect(c.address); + return; + case CONNCMD_DISCONNECT: + LOG(dout_con << m_connection->getDesc() + << " UDP processing CONNCMD_DISCONNECT" << std::endl); + disconnect(); + return; + case CONNCMD_DISCONNECT_PEER: + LOG(dout_con << m_connection->getDesc() + << " UDP processing CONNCMD_DISCONNECT_PEER" << std::endl); + disconnect_peer(c.peer_id); + return; + case CONNCMD_SEND: + LOG(dout_con << m_connection->getDesc() + << " UDP processing CONNCMD_SEND" << std::endl); + send(c.peer_id, c.channelnum, c.data); + return; + case CONNCMD_SEND_TO_ALL: + LOG(dout_con << m_connection->getDesc() + << " UDP processing CONNCMD_SEND_TO_ALL" << std::endl); + sendToAll(c.channelnum, c.data); + return; + case CONCMD_ACK: + LOG(dout_con << m_connection->getDesc() + << " UDP processing CONCMD_ACK" << std::endl); + sendAsPacket(c.peer_id, c.channelnum, c.data, true); + return; + case CONCMD_CREATE_PEER: + FATAL_ERROR("Got command that should be reliable as unreliable command"); + default: + LOG(dout_con << m_connection->getDesc() + << " Invalid command type: " << c.type << std::endl); + } +} + +void ConnectionSendThread::serve(Address bind_address) +{ + LOG(dout_con << m_connection->getDesc() + << "UDP serving at port " << bind_address.serializeString() << std::endl); + try { + m_connection->m_udpSocket.Bind(bind_address); + m_connection->SetPeerID(PEER_ID_SERVER); + } + catch (SocketException &e) { + // Create event + m_connection->putEvent(ConnectionEvent::bindFailed()); + } +} + +void ConnectionSendThread::connect(Address address) +{ + LOG(dout_con << m_connection->getDesc() << " connecting to " + << address.serializeString() + << ":" << address.getPort() << std::endl); + + UDPPeer *peer = m_connection->createServerPeer(address); + + // Create event + m_connection->putEvent(ConnectionEvent::peerAdded(peer->id, peer->address)); + + Address bind_addr; + + if (address.isIPv6()) + bind_addr.setAddress((IPv6AddressBytes *) NULL); + else + bind_addr.setAddress(0, 0, 0, 0); + + m_connection->m_udpSocket.Bind(bind_addr); + + // Send a dummy packet to server with peer_id = PEER_ID_INEXISTENT + m_connection->SetPeerID(PEER_ID_INEXISTENT); + NetworkPacket pkt(0, 0); + m_connection->Send(PEER_ID_SERVER, 0, &pkt, true); +} + +void ConnectionSendThread::disconnect() +{ + LOG(dout_con << m_connection->getDesc() << " disconnecting" << std::endl); + + // Create and send DISCO packet + SharedBuffer<u8> data(2); + writeU8(&data[0], PACKET_TYPE_CONTROL); + writeU8(&data[1], CONTROLTYPE_DISCO); + + + // Send to all + std::vector<session_t> peerids = m_connection->getPeerIDs(); + + for (session_t peerid : peerids) { + sendAsPacket(peerid, 0, data, false); + } +} + +void ConnectionSendThread::disconnect_peer(session_t peer_id) +{ + LOG(dout_con << m_connection->getDesc() << " disconnecting peer" << std::endl); + + // Create and send DISCO packet + SharedBuffer<u8> data(2); + writeU8(&data[0], PACKET_TYPE_CONTROL); + writeU8(&data[1], CONTROLTYPE_DISCO); + sendAsPacket(peer_id, 0, data, false); + + PeerHelper peer = m_connection->getPeerNoEx(peer_id); + + if (!peer) + return; + + if (dynamic_cast<UDPPeer *>(&peer) == 0) { + return; + } + + dynamic_cast<UDPPeer *>(&peer)->m_pending_disconnect = true; +} + +void ConnectionSendThread::send(session_t peer_id, u8 channelnum, + const SharedBuffer<u8> &data) +{ + assert(channelnum < CHANNEL_COUNT); // Pre-condition + + PeerHelper peer = m_connection->getPeerNoEx(peer_id); + if (!peer) { + LOG(dout_con << m_connection->getDesc() << " peer: peer_id=" << peer_id + << ">>>NOT<<< found on sending packet" + << ", channel " << (channelnum % 0xFF) + << ", size: " << data.getSize() << std::endl); + return; + } + + LOG(dout_con << m_connection->getDesc() << " sending to peer_id=" << peer_id + << ", channel " << (channelnum % 0xFF) + << ", size: " << data.getSize() << std::endl); + + u16 split_sequence_number = peer->getNextSplitSequenceNumber(channelnum); + + u32 chunksize_max = m_max_packet_size - BASE_HEADER_SIZE; + std::list<SharedBuffer<u8>> originals; + + makeAutoSplitPacket(data, chunksize_max, split_sequence_number, &originals); + + peer->setNextSplitSequenceNumber(channelnum, split_sequence_number); + + for (const SharedBuffer<u8> &original : originals) { + sendAsPacket(peer_id, channelnum, original); + } +} + +void ConnectionSendThread::sendReliable(ConnectionCommandPtr &c) +{ + PeerHelper peer = m_connection->getPeerNoEx(c->peer_id); + if (!peer) + return; + + peer->PutReliableSendCommand(c, m_max_packet_size); +} + +void ConnectionSendThread::sendToAll(u8 channelnum, const SharedBuffer<u8> &data) +{ + std::vector<session_t> peerids = m_connection->getPeerIDs(); + + for (session_t peerid : peerids) { + send(peerid, channelnum, data); + } +} + +void ConnectionSendThread::sendToAllReliable(ConnectionCommandPtr &c) +{ + std::vector<session_t> peerids = m_connection->getPeerIDs(); + + for (session_t peerid : peerids) { + PeerHelper peer = m_connection->getPeerNoEx(peerid); + + if (!peer) + continue; + + peer->PutReliableSendCommand(c, m_max_packet_size); + } +} + +void ConnectionSendThread::sendPackets(float dtime) +{ + std::vector<session_t> peerIds = m_connection->getPeerIDs(); + std::vector<session_t> pendingDisconnect; + std::map<session_t, bool> pending_unreliable; + + const unsigned int peer_packet_quota = m_iteration_packets_avaialble + / MYMAX(peerIds.size(), 1); + + for (session_t peerId : peerIds) { + PeerHelper peer = m_connection->getPeerNoEx(peerId); + //peer may have been removed + if (!peer) { + LOG(dout_con << m_connection->getDesc() << " Peer not found: peer_id=" + << peerId + << std::endl); + continue; + } + peer->m_increment_packets_remaining = peer_packet_quota; + + UDPPeer *udpPeer = dynamic_cast<UDPPeer *>(&peer); + + if (!udpPeer) { + continue; + } + + if (udpPeer->m_pending_disconnect) { + pendingDisconnect.push_back(peerId); + } + + PROFILE(std::stringstream + peerIdentifier); + PROFILE( + peerIdentifier << "sendPackets[" << m_connection->getDesc() << ";" << peerId + << ";RELIABLE]"); + PROFILE(ScopeProfiler + peerprofiler(g_profiler, peerIdentifier.str(), SPT_AVG)); + + LOG(dout_con << m_connection->getDesc() + << " Handle per peer queues: peer_id=" << peerId + << " packet quota: " << peer->m_increment_packets_remaining << std::endl); + + // first send queued reliable packets for all peers (if possible) + for (unsigned int i = 0; i < CHANNEL_COUNT; i++) { + Channel &channel = udpPeer->channels[i]; + + // Reduces logging verbosity + if (channel.queued_reliables.empty()) + continue; + + u16 next_to_ack = 0; + channel.outgoing_reliables_sent.getFirstSeqnum(next_to_ack); + u16 next_to_receive = 0; + channel.incoming_reliables.getFirstSeqnum(next_to_receive); + + LOG(dout_con << m_connection->getDesc() << "\t channel: " + << i << ", peer quota:" + << peer->m_increment_packets_remaining + << std::endl + << "\t\t\treliables on wire: " + << channel.outgoing_reliables_sent.size() + << ", waiting for ack for " << next_to_ack + << std::endl + << "\t\t\tincoming_reliables: " + << channel.incoming_reliables.size() + << ", next reliable packet: " + << channel.readNextIncomingSeqNum() + << ", next queued: " << next_to_receive + << std::endl + << "\t\t\treliables queued : " + << channel.queued_reliables.size() + << std::endl + << "\t\t\tqueued commands : " + << channel.queued_commands.size() + << std::endl); + + while (!channel.queued_reliables.empty() && + channel.outgoing_reliables_sent.size() + < channel.getWindowSize() && + peer->m_increment_packets_remaining > 0) { + BufferedPacketPtr p = channel.queued_reliables.front(); + channel.queued_reliables.pop(); + + LOG(dout_con << m_connection->getDesc() + << " INFO: sending a queued reliable packet " + << " channel: " << i + << ", seqnum: " << p->getSeqnum() + << std::endl); + + sendAsPacketReliable(p, &channel); + peer->m_increment_packets_remaining--; + } + } + } + + if (!m_outgoing_queue.empty()) { + LOG(dout_con << m_connection->getDesc() + << " Handle non reliable queue (" + << m_outgoing_queue.size() << " pkts)" << std::endl); + } + + unsigned int initial_queuesize = m_outgoing_queue.size(); + /* send non reliable packets*/ + for (unsigned int i = 0; i < initial_queuesize; i++) { + OutgoingPacket packet = m_outgoing_queue.front(); + m_outgoing_queue.pop(); + + if (packet.reliable) + continue; + + PeerHelper peer = m_connection->getPeerNoEx(packet.peer_id); + if (!peer) { + LOG(dout_con << m_connection->getDesc() + << " Outgoing queue: peer_id=" << packet.peer_id + << ">>>NOT<<< found on sending packet" + << ", channel " << (packet.channelnum % 0xFF) + << ", size: " << packet.data.getSize() << std::endl); + continue; + } + + /* send acks immediately */ + if (packet.ack || peer->m_increment_packets_remaining > 0 || stopRequested()) { + rawSendAsPacket(packet.peer_id, packet.channelnum, + packet.data, packet.reliable); + if (peer->m_increment_packets_remaining > 0) + peer->m_increment_packets_remaining--; + } else { + m_outgoing_queue.push(packet); + pending_unreliable[packet.peer_id] = true; + } + } + + if (peer_packet_quota > 0) { + for (session_t peerId : peerIds) { + PeerHelper peer = m_connection->getPeerNoEx(peerId); + if (!peer) + continue; + if (peer->m_increment_packets_remaining == 0) { + LOG(warningstream << m_connection->getDesc() + << " Packet quota used up for peer_id=" << peerId + << ", was " << peer_packet_quota << " pkts" << std::endl); + } + } + } + + for (session_t peerId : pendingDisconnect) { + if (!pending_unreliable[peerId]) { + m_connection->deletePeer(peerId, false); + } + } +} + +void ConnectionSendThread::sendAsPacket(session_t peer_id, u8 channelnum, + const SharedBuffer<u8> &data, bool ack) +{ + OutgoingPacket packet(peer_id, channelnum, data, false, ack); + m_outgoing_queue.push(packet); +} + +ConnectionReceiveThread::ConnectionReceiveThread(unsigned int max_packet_size) : + Thread("ConnectionReceive") +{ +} + +void *ConnectionReceiveThread::run() +{ + assert(m_connection); + + LOG(dout_con << m_connection->getDesc() + << "ConnectionReceive thread started" << std::endl); + + PROFILE(std::stringstream + ThreadIdentifier); + PROFILE(ThreadIdentifier << "ConnectionReceive: [" << m_connection->getDesc() << "]"); + + // use IPv6 minimum allowed MTU as receive buffer size as this is + // theoretical reliable upper boundary of a udp packet for all IPv6 enabled + // infrastructure + const unsigned int packet_maxsize = 1500; + SharedBuffer<u8> packetdata(packet_maxsize); + + bool packet_queued = true; + +#ifdef DEBUG_CONNECTION_KBPS + u64 curtime = porting::getTimeMs(); + u64 lasttime = curtime; + float debug_print_timer = 0.0; +#endif + + while (!stopRequested()) { + BEGIN_DEBUG_EXCEPTION_HANDLER + PROFILE(ScopeProfiler + sp(g_profiler, ThreadIdentifier.str(), SPT_AVG)); + +#ifdef DEBUG_CONNECTION_KBPS + lasttime = curtime; + curtime = porting::getTimeMs(); + float dtime = CALC_DTIME(lasttime,curtime); +#endif + + /* receive packets */ + receive(packetdata, packet_queued); + +#ifdef DEBUG_CONNECTION_KBPS + debug_print_timer += dtime; + if (debug_print_timer > 20.0) { + debug_print_timer -= 20.0; + + std::vector<session_t> peerids = m_connection->getPeerIDs(); + + for (auto id : peerids) + { + PeerHelper peer = m_connection->getPeerNoEx(id); + if (!peer) + continue; + + float peer_current = 0.0; + float peer_loss = 0.0; + float avg_rate = 0.0; + float avg_loss = 0.0; + + for(u16 j=0; j<CHANNEL_COUNT; j++) + { + peer_current +=peer->channels[j].getCurrentDownloadRateKB(); + peer_loss += peer->channels[j].getCurrentLossRateKB(); + avg_rate += peer->channels[j].getAvgDownloadRateKB(); + avg_loss += peer->channels[j].getAvgLossRateKB(); + } + + std::stringstream output; + output << std::fixed << std::setprecision(1); + output << "OUT to Peer " << *i << " RATES (good / loss) " << std::endl; + output << "\tcurrent (sum): " << peer_current << "kb/s "<< peer_loss << "kb/s" << std::endl; + output << "\taverage (sum): " << avg_rate << "kb/s "<< avg_loss << "kb/s" << std::endl; + output << std::setfill(' '); + for(u16 j=0; j<CHANNEL_COUNT; j++) + { + output << "\tcha " << j << ":" + << " CUR: " << std::setw(6) << peer->channels[j].getCurrentDownloadRateKB() <<"kb/s" + << " AVG: " << std::setw(6) << peer->channels[j].getAvgDownloadRateKB() <<"kb/s" + << " MAX: " << std::setw(6) << peer->channels[j].getMaxDownloadRateKB() <<"kb/s" + << " /" + << " CUR: " << std::setw(6) << peer->channels[j].getCurrentLossRateKB() <<"kb/s" + << " AVG: " << std::setw(6) << peer->channels[j].getAvgLossRateKB() <<"kb/s" + << " MAX: " << std::setw(6) << peer->channels[j].getMaxLossRateKB() <<"kb/s" + << " / WS: " << peer->channels[j].getWindowSize() + << std::endl; + } + + fprintf(stderr,"%s\n",output.str().c_str()); + } + } +#endif + END_DEBUG_EXCEPTION_HANDLER + } + + PROFILE(g_profiler->remove(ThreadIdentifier.str())); + return NULL; +} + +// Receive packets from the network and buffers and create ConnectionEvents +void ConnectionReceiveThread::receive(SharedBuffer<u8> &packetdata, + bool &packet_queued) +{ + try { + // First, see if there any buffered packets we can process now + if (packet_queued) { + session_t peer_id; + SharedBuffer<u8> resultdata; + while (true) { + try { + if (!getFromBuffers(peer_id, resultdata)) + break; + + m_connection->putEvent(ConnectionEvent::dataReceived(peer_id, resultdata)); + } + catch (ProcessedSilentlyException &e) { + /* try reading again */ + } + } + packet_queued = false; + } + + // Call Receive() to wait for incoming data + Address sender; + s32 received_size = m_connection->m_udpSocket.Receive(sender, + *packetdata, packetdata.getSize()); + if (received_size < 0) + return; + + if ((received_size < BASE_HEADER_SIZE) || + (readU32(&packetdata[0]) != m_connection->GetProtocolID())) { + LOG(derr_con << m_connection->getDesc() + << "Receive(): Invalid incoming packet, " + << "size: " << received_size + << ", protocol: " + << ((received_size >= 4) ? readU32(&packetdata[0]) : -1) + << std::endl); + return; + } + + session_t peer_id = readPeerId(*packetdata); + u8 channelnum = readChannel(*packetdata); + + if (channelnum > CHANNEL_COUNT - 1) { + LOG(derr_con << m_connection->getDesc() + << "Receive(): Invalid channel " << (u32)channelnum << std::endl); + return; + } + + /* Try to identify peer by sender address (may happen on join) */ + if (peer_id == PEER_ID_INEXISTENT) { + peer_id = m_connection->lookupPeer(sender); + // We do not have to remind the peer of its + // peer id as the CONTROLTYPE_SET_PEER_ID + // command was sent reliably. + } + + if (peer_id == PEER_ID_INEXISTENT) { + /* Ignore it if we are a client */ + if (m_connection->ConnectedToServer()) + return; + /* The peer was not found in our lists. Add it. */ + peer_id = m_connection->createPeer(sender, MTP_MINETEST_RELIABLE_UDP, 0); + } + + PeerHelper peer = m_connection->getPeerNoEx(peer_id); + if (!peer) { + LOG(dout_con << m_connection->getDesc() + << " got packet from unknown peer_id: " + << peer_id << " Ignoring." << std::endl); + return; + } + + // Validate peer address + + Address peer_address; + if (peer->getAddress(MTP_UDP, peer_address)) { + if (peer_address != sender) { + LOG(derr_con << m_connection->getDesc() + << " Peer " << peer_id << " sending from different address." + " Ignoring." << std::endl); + return; + } + } else { + LOG(derr_con << m_connection->getDesc() + << " Peer " << peer_id << " doesn't have an address?!" + " Ignoring." << std::endl); + return; + } + + peer->ResetTimeout(); + + Channel *channel = nullptr; + if (dynamic_cast<UDPPeer *>(&peer)) { + channel = &dynamic_cast<UDPPeer *>(&peer)->channels[channelnum]; + } else { + LOG(derr_con << m_connection->getDesc() + << "Receive(): peer_id=" << peer_id << " isn't an UDPPeer?!" + " Ignoring." << std::endl); + return; + } + + channel->UpdateBytesReceived(received_size); + + // Throw the received packet to channel->processPacket() + + // Make a new SharedBuffer from the data without the base headers + SharedBuffer<u8> strippeddata(received_size - BASE_HEADER_SIZE); + memcpy(*strippeddata, &packetdata[BASE_HEADER_SIZE], + strippeddata.getSize()); + + try { + // Process it (the result is some data with no headers made by us) + SharedBuffer<u8> resultdata = processPacket + (channel, strippeddata, peer_id, channelnum, false); + + LOG(dout_con << m_connection->getDesc() + << " ProcessPacket from peer_id: " << peer_id + << ", channel: " << (u32)channelnum << ", returned " + << resultdata.getSize() << " bytes" << std::endl); + + m_connection->putEvent(ConnectionEvent::dataReceived(peer_id, resultdata)); + } + catch (ProcessedSilentlyException &e) { + } + catch (ProcessedQueued &e) { + // we set it to true anyway (see below) + } + + /* Every time we receive a packet it can happen that a previously + * buffered packet is now ready to process. */ + packet_queued = true; + } + catch (InvalidIncomingDataException &e) { + } +} + +bool ConnectionReceiveThread::getFromBuffers(session_t &peer_id, SharedBuffer<u8> &dst) +{ + std::vector<session_t> peerids = m_connection->getPeerIDs(); + + for (session_t peerid : peerids) { + PeerHelper peer = m_connection->getPeerNoEx(peerid); + if (!peer) + continue; + + UDPPeer *p = dynamic_cast<UDPPeer *>(&peer); + if (!p) + continue; + + for (Channel &channel : p->channels) { + if (checkIncomingBuffers(&channel, peer_id, dst)) { + return true; + } + } + } + return false; +} + +bool ConnectionReceiveThread::checkIncomingBuffers(Channel *channel, + session_t &peer_id, SharedBuffer<u8> &dst) +{ + u16 firstseqnum = 0; + if (!channel->incoming_reliables.getFirstSeqnum(firstseqnum)) + return false; + + if (firstseqnum != channel->readNextIncomingSeqNum()) + return false; + + BufferedPacketPtr p = channel->incoming_reliables.popFirst(); + + peer_id = readPeerId(p->data); // Carried over to caller function + u8 channelnum = readChannel(p->data); + u16 seqnum = p->getSeqnum(); + + LOG(dout_con << m_connection->getDesc() + << "UNBUFFERING TYPE_RELIABLE" + << " seqnum=" << seqnum + << " peer_id=" << peer_id + << " channel=" << ((int) channelnum & 0xff) + << std::endl); + + channel->incNextIncomingSeqNum(); + + u32 headers_size = BASE_HEADER_SIZE + RELIABLE_HEADER_SIZE; + // Get out the inside packet and re-process it + SharedBuffer<u8> payload(p->size() - headers_size); + memcpy(*payload, &p->data[headers_size], payload.getSize()); + + dst = processPacket(channel, payload, peer_id, channelnum, true); + return true; +} + +SharedBuffer<u8> ConnectionReceiveThread::processPacket(Channel *channel, + const SharedBuffer<u8> &packetdata, session_t peer_id, u8 channelnum, bool reliable) +{ + PeerHelper peer = m_connection->getPeerNoEx(peer_id); + + if (!peer) { + errorstream << "Peer not found (possible timeout)" << std::endl; + throw ProcessedSilentlyException("Peer not found (possible timeout)"); + } + + if (packetdata.getSize() < 1) + throw InvalidIncomingDataException("packetdata.getSize() < 1"); + + u8 type = readU8(&(packetdata[0])); + + if (MAX_UDP_PEERS <= 65535 && peer_id >= MAX_UDP_PEERS) { + std::string errmsg = "Invalid peer_id=" + itos(peer_id); + errorstream << errmsg << std::endl; + throw InvalidIncomingDataException(errmsg.c_str()); + } + + if (type >= PACKET_TYPE_MAX) { + derr_con << m_connection->getDesc() << "Got invalid type=" << ((int) type & 0xff) + << std::endl; + throw InvalidIncomingDataException("Invalid packet type"); + } + + const PacketTypeHandler &pHandle = packetTypeRouter[type]; + return (this->*pHandle.handler)(channel, packetdata, &peer, channelnum, reliable); +} + +const ConnectionReceiveThread::PacketTypeHandler + ConnectionReceiveThread::packetTypeRouter[PACKET_TYPE_MAX] = { + {&ConnectionReceiveThread::handlePacketType_Control}, + {&ConnectionReceiveThread::handlePacketType_Original}, + {&ConnectionReceiveThread::handlePacketType_Split}, + {&ConnectionReceiveThread::handlePacketType_Reliable}, +}; + +SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Control(Channel *channel, + const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum, bool reliable) +{ + if (packetdata.getSize() < 2) + throw InvalidIncomingDataException("packetdata.getSize() < 2"); + + ControlType controltype = (ControlType)readU8(&(packetdata[1])); + + if (controltype == CONTROLTYPE_ACK) { + assert(channel != NULL); + + if (packetdata.getSize() < 4) { + throw InvalidIncomingDataException( + "packetdata.getSize() < 4 (ACK header size)"); + } + + u16 seqnum = readU16(&packetdata[2]); + LOG(dout_con << m_connection->getDesc() << " [ CONTROLTYPE_ACK: channelnum=" + << ((int) channelnum & 0xff) << ", peer_id=" << peer->id << ", seqnum=" + << seqnum << " ]" << std::endl); + + try { + BufferedPacketPtr p = channel->outgoing_reliables_sent.popSeqnum(seqnum); + + // the rtt calculation will be a bit off for re-sent packets but that's okay + { + // Get round trip time + u64 current_time = porting::getTimeMs(); + + // a overflow is quite unlikely but as it'd result in major + // rtt miscalculation we handle it here + if (current_time > p->absolute_send_time) { + float rtt = (current_time - p->absolute_send_time) / 1000.0; + + // Let peer calculate stuff according to it + // (avg_rtt and resend_timeout) + dynamic_cast<UDPPeer *>(peer)->reportRTT(rtt); + } else if (p->totaltime > 0) { + float rtt = p->totaltime; + + // Let peer calculate stuff according to it + // (avg_rtt and resend_timeout) + dynamic_cast<UDPPeer *>(peer)->reportRTT(rtt); + } + } + + // put bytes for max bandwidth calculation + channel->UpdateBytesSent(p->size(), 1); + if (channel->outgoing_reliables_sent.size() == 0) + m_connection->TriggerSend(); + } catch (NotFoundException &e) { + LOG(derr_con << m_connection->getDesc() + << "WARNING: ACKed packet not in outgoing queue" + << " seqnum=" << seqnum << std::endl); + channel->UpdatePacketTooLateCounter(); + } + + throw ProcessedSilentlyException("Got an ACK"); + } else if (controltype == CONTROLTYPE_SET_PEER_ID) { + // Got a packet to set our peer id + if (packetdata.getSize() < 4) + throw InvalidIncomingDataException + ("packetdata.getSize() < 4 (SET_PEER_ID header size)"); + session_t peer_id_new = readU16(&packetdata[2]); + LOG(dout_con << m_connection->getDesc() << "Got new peer id: " << peer_id_new + << "... " << std::endl); + + if (m_connection->GetPeerID() != PEER_ID_INEXISTENT) { + LOG(derr_con << m_connection->getDesc() + << "WARNING: Not changing existing peer id." << std::endl); + } else { + LOG(dout_con << m_connection->getDesc() << "changing own peer id" + << std::endl); + m_connection->SetPeerID(peer_id_new); + } + + throw ProcessedSilentlyException("Got a SET_PEER_ID"); + } else if (controltype == CONTROLTYPE_PING) { + // Just ignore it, the incoming data already reset + // the timeout counter + LOG(dout_con << m_connection->getDesc() << "PING" << std::endl); + throw ProcessedSilentlyException("Got a PING"); + } else if (controltype == CONTROLTYPE_DISCO) { + // Just ignore it, the incoming data already reset + // the timeout counter + LOG(dout_con << m_connection->getDesc() << "DISCO: Removing peer " + << peer->id << std::endl); + + if (!m_connection->deletePeer(peer->id, false)) { + derr_con << m_connection->getDesc() << "DISCO: Peer not found" << std::endl; + } + + throw ProcessedSilentlyException("Got a DISCO"); + } else { + LOG(derr_con << m_connection->getDesc() + << "INVALID controltype=" + << ((int) controltype & 0xff) << std::endl); + throw InvalidIncomingDataException("Invalid control type"); + } +} + +SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Original(Channel *channel, + const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum, bool reliable) +{ + if (packetdata.getSize() <= ORIGINAL_HEADER_SIZE) + throw InvalidIncomingDataException + ("packetdata.getSize() <= ORIGINAL_HEADER_SIZE"); + LOG(dout_con << m_connection->getDesc() << "RETURNING TYPE_ORIGINAL to user" + << std::endl); + // Get the inside packet out and return it + SharedBuffer<u8> payload(packetdata.getSize() - ORIGINAL_HEADER_SIZE); + memcpy(*payload, &(packetdata[ORIGINAL_HEADER_SIZE]), payload.getSize()); + return payload; +} + +SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Split(Channel *channel, + const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum, bool reliable) +{ + Address peer_address; + + if (peer->getAddress(MTP_UDP, peer_address)) { + // We have to create a packet again for buffering + // This isn't actually too bad an idea. + BufferedPacketPtr packet = con::makePacket(peer_address, + packetdata, + m_connection->GetProtocolID(), + peer->id, + channelnum); + + // Buffer the packet + SharedBuffer<u8> data = peer->addSplitPacket(channelnum, packet, reliable); + + if (data.getSize() != 0) { + LOG(dout_con << m_connection->getDesc() + << "RETURNING TYPE_SPLIT: Constructed full data, " + << "size=" << data.getSize() << std::endl); + return data; + } + LOG(dout_con << m_connection->getDesc() << "BUFFERED TYPE_SPLIT" << std::endl); + throw ProcessedSilentlyException("Buffered a split packet chunk"); + } + + // We should never get here. + FATAL_ERROR("Invalid execution point"); +} + +SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Reliable(Channel *channel, + const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum, bool reliable) +{ + assert(channel != NULL); + + // Recursive reliable packets not allowed + if (reliable) + throw InvalidIncomingDataException("Found nested reliable packets"); + + if (packetdata.getSize() < RELIABLE_HEADER_SIZE) + throw InvalidIncomingDataException("packetdata.getSize() < RELIABLE_HEADER_SIZE"); + + const u16 seqnum = readU16(&packetdata[1]); + bool is_future_packet = false; + bool is_old_packet = false; + + /* packet is within our receive window send ack */ + if (seqnum_in_window(seqnum, + channel->readNextIncomingSeqNum(), MAX_RELIABLE_WINDOW_SIZE)) { + m_connection->sendAck(peer->id, channelnum, seqnum); + } else { + is_future_packet = seqnum_higher(seqnum, channel->readNextIncomingSeqNum()); + is_old_packet = seqnum_higher(channel->readNextIncomingSeqNum(), seqnum); + + /* packet is not within receive window, don't send ack. * + * if this was a valid packet it's gonna be retransmitted */ + if (is_future_packet) + throw ProcessedSilentlyException( + "Received packet newer then expected, not sending ack"); + + /* seems like our ack was lost, send another one for a old packet */ + if (is_old_packet) { + LOG(dout_con << m_connection->getDesc() + << "RE-SENDING ACK: peer_id: " << peer->id + << ", channel: " << (channelnum & 0xFF) + << ", seqnum: " << seqnum << std::endl;) + m_connection->sendAck(peer->id, channelnum, seqnum); + + // we already have this packet so this one was on wire at least + // the current timeout + // we don't know how long this packet was on wire don't do silly guessing + // dynamic_cast<UDPPeer*>(&peer)-> + // reportRTT(dynamic_cast<UDPPeer*>(&peer)->getResendTimeout()); + + throw ProcessedSilentlyException("Retransmitting ack for old packet"); + } + } + + if (seqnum != channel->readNextIncomingSeqNum()) { + Address peer_address; + + // this is a reliable packet so we have a udp address for sure + peer->getAddress(MTP_MINETEST_RELIABLE_UDP, peer_address); + // This one comes later, buffer it. + // Actually we have to make a packet to buffer one. + // Well, we have all the ingredients, so just do it. + BufferedPacketPtr packet = con::makePacket( + peer_address, + packetdata, + m_connection->GetProtocolID(), + peer->id, + channelnum); + try { + channel->incoming_reliables.insert(packet, channel->readNextIncomingSeqNum()); + + LOG(dout_con << m_connection->getDesc() + << "BUFFERING, TYPE_RELIABLE peer_id: " << peer->id + << ", channel: " << (channelnum & 0xFF) + << ", seqnum: " << seqnum << std::endl;) + + throw ProcessedQueued("Buffered future reliable packet"); + } catch (AlreadyExistsException &e) { + } catch (IncomingDataCorruption &e) { + m_connection->putCommand(ConnectionCommand::disconnect_peer(peer->id)); + + LOG(derr_con << m_connection->getDesc() + << "INVALID, TYPE_RELIABLE peer_id: " << peer->id + << ", channel: " << (channelnum & 0xFF) + << ", seqnum: " << seqnum + << "DROPPING CLIENT!" << std::endl;) + } + } + + /* we got a packet to process right now */ + LOG(dout_con << m_connection->getDesc() + << "RECURSIVE, TYPE_RELIABLE peer_id: " << peer->id + << ", channel: " << (channelnum & 0xFF) + << ", seqnum: " << seqnum << std::endl;) + + + /* check for resend case */ + u16 queued_seqnum = 0; + if (channel->incoming_reliables.getFirstSeqnum(queued_seqnum)) { + if (queued_seqnum == seqnum) { + BufferedPacketPtr queued_packet = channel->incoming_reliables.popFirst(); + /** TODO find a way to verify the new against the old packet */ + } + } + + channel->incNextIncomingSeqNum(); + + // Get out the inside packet and re-process it + SharedBuffer<u8> payload(packetdata.getSize() - RELIABLE_HEADER_SIZE); + memcpy(*payload, &packetdata[RELIABLE_HEADER_SIZE], payload.getSize()); + + return processPacket(channel, payload, peer->id, channelnum, true); +} + +} diff --git a/src/network/connectionthreads.h b/src/network/connectionthreads.h new file mode 100644 index 0000000..c2e2dae --- /dev/null +++ b/src/network/connectionthreads.h @@ -0,0 +1,169 @@ +/* +Minetest +Copyright (C) 2013-2017 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 celeron55, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <cassert> +#include "threading/thread.h" +#include "connection.h" + +namespace con +{ + +class Connection; + +struct OutgoingPacket +{ + session_t peer_id; + u8 channelnum; + SharedBuffer<u8> data; + bool reliable; + bool ack; + + OutgoingPacket(session_t peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_, + bool reliable_,bool ack_=false): + peer_id(peer_id_), + channelnum(channelnum_), + data(data_), + reliable(reliable_), + ack(ack_) + { + } +}; + +class ConnectionSendThread : public Thread +{ + +public: + friend class UDPPeer; + + ConnectionSendThread(unsigned int max_packet_size, float timeout); + + void *run(); + + void Trigger(); + + void setParent(Connection *parent) + { + assert(parent != NULL); // Pre-condition + m_connection = parent; + } + + void setPeerTimeout(float peer_timeout) { m_timeout = peer_timeout; } + +private: + void runTimeouts(float dtime); + void rawSend(const BufferedPacket *p); + bool rawSendAsPacket(session_t peer_id, u8 channelnum, + const SharedBuffer<u8> &data, bool reliable); + + void processReliableCommand(ConnectionCommandPtr &c); + void processNonReliableCommand(ConnectionCommandPtr &c); + void serve(Address bind_address); + void connect(Address address); + void disconnect(); + void disconnect_peer(session_t peer_id); + void send(session_t peer_id, u8 channelnum, const SharedBuffer<u8> &data); + void sendReliable(ConnectionCommandPtr &c); + void sendToAll(u8 channelnum, const SharedBuffer<u8> &data); + void sendToAllReliable(ConnectionCommandPtr &c); + + void sendPackets(float dtime); + + void sendAsPacket(session_t peer_id, u8 channelnum, const SharedBuffer<u8> &data, + bool ack = false); + + void sendAsPacketReliable(BufferedPacketPtr &p, Channel *channel); + + bool packetsQueued(); + + Connection *m_connection = nullptr; + unsigned int m_max_packet_size; + float m_timeout; + std::queue<OutgoingPacket> m_outgoing_queue; + Semaphore m_send_sleep_semaphore; + + unsigned int m_iteration_packets_avaialble; + unsigned int m_max_commands_per_iteration = 1; + unsigned int m_max_data_packets_per_iteration; + unsigned int m_max_packets_requeued = 256; +}; + +class ConnectionReceiveThread : public Thread +{ +public: + ConnectionReceiveThread(unsigned int max_packet_size); + + void *run(); + + void setParent(Connection *parent) + { + assert(parent); // Pre-condition + m_connection = parent; + } + +private: + void receive(SharedBuffer<u8> &packetdata, bool &packet_queued); + + // Returns next data from a buffer if possible + // If found, returns true; if not, false. + // If found, sets peer_id and dst + bool getFromBuffers(session_t &peer_id, SharedBuffer<u8> &dst); + + bool checkIncomingBuffers( + Channel *channel, session_t &peer_id, SharedBuffer<u8> &dst); + + /* + Processes a packet with the basic header stripped out. + Parameters: + packetdata: Data in packet (with no base headers) + peer_id: peer id of the sender of the packet in question + channelnum: channel on which the packet was sent + reliable: true if recursing into a reliable packet + */ + SharedBuffer<u8> processPacket(Channel *channel, + const SharedBuffer<u8> &packetdata, session_t peer_id, + u8 channelnum, bool reliable); + + SharedBuffer<u8> handlePacketType_Control(Channel *channel, + const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum, + bool reliable); + SharedBuffer<u8> handlePacketType_Original(Channel *channel, + const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum, + bool reliable); + SharedBuffer<u8> handlePacketType_Split(Channel *channel, + const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum, + bool reliable); + SharedBuffer<u8> handlePacketType_Reliable(Channel *channel, + const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum, + bool reliable); + + struct PacketTypeHandler + { + SharedBuffer<u8> (ConnectionReceiveThread::*handler)(Channel *channel, + const SharedBuffer<u8> &packet, Peer *peer, u8 channelnum, + bool reliable); + }; + + static const PacketTypeHandler packetTypeRouter[PACKET_TYPE_MAX]; + + Connection *m_connection = nullptr; +}; +} diff --git a/src/network/networkexceptions.h b/src/network/networkexceptions.h new file mode 100644 index 0000000..58a3bb4 --- /dev/null +++ b/src/network/networkexceptions.h @@ -0,0 +1,100 @@ +/* +Minetest +Copyright (C) 2013-2017 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "exceptions.h" + +namespace con +{ +/* + Exceptions +*/ +class NotFoundException : public BaseException +{ +public: + NotFoundException(const char *s) : BaseException(s) {} +}; + +class PeerNotFoundException : public BaseException +{ +public: + PeerNotFoundException(const char *s) : BaseException(s) {} +}; + +class ConnectionException : public BaseException +{ +public: + ConnectionException(const char *s) : BaseException(s) {} +}; + +class ConnectionBindFailed : public BaseException +{ +public: + ConnectionBindFailed(const char *s) : BaseException(s) {} +}; + +class InvalidIncomingDataException : public BaseException +{ +public: + InvalidIncomingDataException(const char *s) : BaseException(s) {} +}; + +class NoIncomingDataException : public BaseException +{ +public: + NoIncomingDataException(const char *s) : BaseException(s) {} +}; + +class ProcessedSilentlyException : public BaseException +{ +public: + ProcessedSilentlyException(const char *s) : BaseException(s) {} +}; + +class ProcessedQueued : public BaseException +{ +public: + ProcessedQueued(const char *s) : BaseException(s) {} +}; + +class IncomingDataCorruption : public BaseException +{ +public: + IncomingDataCorruption(const char *s) : BaseException(s) {} +}; +} + +class SocketException : public BaseException +{ +public: + SocketException(const std::string &s) : BaseException(s) {} +}; + +class ResolveError : public BaseException +{ +public: + ResolveError(const std::string &s) : BaseException(s) {} +}; + +class SendFailedException : public BaseException +{ +public: + SendFailedException(const std::string &s) : BaseException(s) {} +}; diff --git a/src/network/networkpacket.cpp b/src/network/networkpacket.cpp new file mode 100644 index 0000000..6b8b0f7 --- /dev/null +++ b/src/network/networkpacket.cpp @@ -0,0 +1,559 @@ +/* +Minetest +Copyright (C) 2015 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "networkpacket.h" +#include <sstream> +#include "networkexceptions.h" +#include "util/serialize.h" +#include "networkprotocol.h" + +NetworkPacket::NetworkPacket(u16 command, u32 datasize, session_t peer_id): +m_datasize(datasize), m_command(command), m_peer_id(peer_id) +{ + m_data.resize(m_datasize); +} + +NetworkPacket::NetworkPacket(u16 command, u32 datasize): +m_datasize(datasize), m_command(command) +{ + m_data.resize(m_datasize); +} + +NetworkPacket::~NetworkPacket() +{ + m_data.clear(); +} + +void NetworkPacket::checkReadOffset(u32 from_offset, u32 field_size) +{ + if (from_offset + field_size > m_datasize) { + std::stringstream ss; + ss << "Reading outside packet (offset: " << + from_offset << ", packet size: " << getSize() << ")"; + throw PacketError(ss.str()); + } +} + +void NetworkPacket::putRawPacket(const u8 *data, u32 datasize, session_t peer_id) +{ + // If a m_command is already set, we are rewriting on same packet + // This is not permitted + assert(m_command == 0); + + m_datasize = datasize - 2; + m_peer_id = peer_id; + + m_data.resize(m_datasize); + + // split command and datas + m_command = readU16(&data[0]); + memcpy(m_data.data(), &data[2], m_datasize); +} + +void NetworkPacket::clear() +{ + m_data.clear(); + m_datasize = 0; + m_read_offset = 0; + m_command = 0; + m_peer_id = 0; +} + +const char* NetworkPacket::getString(u32 from_offset) +{ + checkReadOffset(from_offset, 0); + + return (char*)&m_data[from_offset]; +} + +void NetworkPacket::putRawString(const char* src, u32 len) +{ + if (m_read_offset + len > m_datasize) { + m_datasize = m_read_offset + len; + m_data.resize(m_datasize); + } + + if (len == 0) + return; + + memcpy(&m_data[m_read_offset], src, len); + m_read_offset += len; +} + +NetworkPacket& NetworkPacket::operator>>(std::string& dst) +{ + checkReadOffset(m_read_offset, 2); + u16 strLen = readU16(&m_data[m_read_offset]); + m_read_offset += 2; + + dst.clear(); + + if (strLen == 0) { + return *this; + } + + checkReadOffset(m_read_offset, strLen); + + dst.reserve(strLen); + dst.append((char*)&m_data[m_read_offset], strLen); + + m_read_offset += strLen; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(const std::string &src) +{ + if (src.size() > STRING_MAX_LEN) { + throw PacketError("String too long"); + } + + u16 msgsize = src.size(); + + *this << msgsize; + + putRawString(src.c_str(), (u32)msgsize); + + return *this; +} + +void NetworkPacket::putLongString(const std::string &src) +{ + if (src.size() > LONG_STRING_MAX_LEN) { + throw PacketError("String too long"); + } + + u32 msgsize = src.size(); + + *this << msgsize; + + putRawString(src.c_str(), msgsize); +} + +static constexpr bool NEED_SURROGATE_CODING = sizeof(wchar_t) > 2; + +NetworkPacket& NetworkPacket::operator>>(std::wstring& dst) +{ + checkReadOffset(m_read_offset, 2); + u16 strLen = readU16(&m_data[m_read_offset]); + m_read_offset += 2; + + dst.clear(); + + if (strLen == 0) { + return *this; + } + + checkReadOffset(m_read_offset, strLen * 2); + + dst.reserve(strLen); + for (u16 i = 0; i < strLen; i++) { + wchar_t c = readU16(&m_data[m_read_offset]); + if (NEED_SURROGATE_CODING && c >= 0xD800 && c < 0xDC00 && i+1 < strLen) { + i++; + m_read_offset += sizeof(u16); + + wchar_t c2 = readU16(&m_data[m_read_offset]); + c = 0x10000 + ( ((c & 0x3ff) << 10) | (c2 & 0x3ff) ); + } + dst.push_back(c); + m_read_offset += sizeof(u16); + } + + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(const std::wstring &src) +{ + if (src.size() > WIDE_STRING_MAX_LEN) { + throw PacketError("String too long"); + } + + if (!NEED_SURROGATE_CODING || src.size() == 0) { + *this << static_cast<u16>(src.size()); + for (u16 i = 0; i < src.size(); i++) + *this << static_cast<u16>(src[i]); + + return *this; + } + + // write dummy value, to be overwritten later + const u32 len_offset = m_read_offset; + u32 written = 0; + *this << static_cast<u16>(0xfff0); + + for (u16 i = 0; i < src.size(); i++) { + wchar_t c = src[i]; + if (c > 0xffff) { + // Encode high code-points as surrogate pairs + u32 n = c - 0x10000; + *this << static_cast<u16>(0xD800 | (n >> 10)) + << static_cast<u16>(0xDC00 | (n & 0x3ff)); + written += 2; + } else { + *this << static_cast<u16>(c); + written++; + } + } + + if (written > WIDE_STRING_MAX_LEN) + throw PacketError("String too long"); + writeU16(&m_data[len_offset], written); + + return *this; +} + +std::string NetworkPacket::readLongString() +{ + checkReadOffset(m_read_offset, 4); + u32 strLen = readU32(&m_data[m_read_offset]); + m_read_offset += 4; + + if (strLen == 0) { + return ""; + } + + if (strLen > LONG_STRING_MAX_LEN) { + throw PacketError("String too long"); + } + + checkReadOffset(m_read_offset, strLen); + + std::string dst; + + dst.reserve(strLen); + dst.append((char*)&m_data[m_read_offset], strLen); + + m_read_offset += strLen; + + return dst; +} + +NetworkPacket& NetworkPacket::operator>>(char& dst) +{ + checkReadOffset(m_read_offset, 1); + + dst = readU8(&m_data[m_read_offset]); + + m_read_offset += 1; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(char src) +{ + checkDataSize(1); + + writeU8(&m_data[m_read_offset], src); + + m_read_offset += 1; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(u8 src) +{ + checkDataSize(1); + + writeU8(&m_data[m_read_offset], src); + + m_read_offset += 1; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(bool src) +{ + checkDataSize(1); + + writeU8(&m_data[m_read_offset], src); + + m_read_offset += 1; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(u16 src) +{ + checkDataSize(2); + + writeU16(&m_data[m_read_offset], src); + + m_read_offset += 2; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(u32 src) +{ + checkDataSize(4); + + writeU32(&m_data[m_read_offset], src); + + m_read_offset += 4; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(u64 src) +{ + checkDataSize(8); + + writeU64(&m_data[m_read_offset], src); + + m_read_offset += 8; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(float src) +{ + checkDataSize(4); + + writeF32(&m_data[m_read_offset], src); + + m_read_offset += 4; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(bool& dst) +{ + checkReadOffset(m_read_offset, 1); + + dst = readU8(&m_data[m_read_offset]); + + m_read_offset += 1; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(u8& dst) +{ + checkReadOffset(m_read_offset, 1); + + dst = readU8(&m_data[m_read_offset]); + + m_read_offset += 1; + return *this; +} + +u8 NetworkPacket::getU8(u32 offset) +{ + checkReadOffset(offset, 1); + + return readU8(&m_data[offset]); +} + +u8* NetworkPacket::getU8Ptr(u32 from_offset) +{ + if (m_datasize == 0) { + return NULL; + } + + checkReadOffset(from_offset, 1); + + return (u8*)&m_data[from_offset]; +} + +NetworkPacket& NetworkPacket::operator>>(u16& dst) +{ + checkReadOffset(m_read_offset, 2); + + dst = readU16(&m_data[m_read_offset]); + + m_read_offset += 2; + return *this; +} + +u16 NetworkPacket::getU16(u32 from_offset) +{ + checkReadOffset(from_offset, 2); + + return readU16(&m_data[from_offset]); +} + +NetworkPacket& NetworkPacket::operator>>(u32& dst) +{ + checkReadOffset(m_read_offset, 4); + + dst = readU32(&m_data[m_read_offset]); + + m_read_offset += 4; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(u64& dst) +{ + checkReadOffset(m_read_offset, 8); + + dst = readU64(&m_data[m_read_offset]); + + m_read_offset += 8; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(float& dst) +{ + checkReadOffset(m_read_offset, 4); + + dst = readF32(&m_data[m_read_offset]); + + m_read_offset += 4; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(v2f& dst) +{ + checkReadOffset(m_read_offset, 8); + + dst = readV2F32(&m_data[m_read_offset]); + + m_read_offset += 8; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(v3f& dst) +{ + checkReadOffset(m_read_offset, 12); + + dst = readV3F32(&m_data[m_read_offset]); + + m_read_offset += 12; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(s16& dst) +{ + checkReadOffset(m_read_offset, 2); + + dst = readS16(&m_data[m_read_offset]); + + m_read_offset += 2; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(s16 src) +{ + *this << (u16) src; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(s32& dst) +{ + checkReadOffset(m_read_offset, 4); + + dst = readS32(&m_data[m_read_offset]); + + m_read_offset += 4; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(s32 src) +{ + *this << (u32) src; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(v3s16& dst) +{ + checkReadOffset(m_read_offset, 6); + + dst = readV3S16(&m_data[m_read_offset]); + + m_read_offset += 6; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(v2s32& dst) +{ + checkReadOffset(m_read_offset, 8); + + dst = readV2S32(&m_data[m_read_offset]); + + m_read_offset += 8; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(v3s32& dst) +{ + checkReadOffset(m_read_offset, 12); + + dst = readV3S32(&m_data[m_read_offset]); + + m_read_offset += 12; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(v2f src) +{ + *this << (float) src.X; + *this << (float) src.Y; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(v3f src) +{ + *this << (float) src.X; + *this << (float) src.Y; + *this << (float) src.Z; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(v3s16 src) +{ + *this << (s16) src.X; + *this << (s16) src.Y; + *this << (s16) src.Z; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(v2s32 src) +{ + *this << (s32) src.X; + *this << (s32) src.Y; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(v3s32 src) +{ + *this << (s32) src.X; + *this << (s32) src.Y; + *this << (s32) src.Z; + return *this; +} + +NetworkPacket& NetworkPacket::operator>>(video::SColor& dst) +{ + checkReadOffset(m_read_offset, 4); + + dst = readARGB8(&m_data[m_read_offset]); + + m_read_offset += 4; + return *this; +} + +NetworkPacket& NetworkPacket::operator<<(video::SColor src) +{ + checkDataSize(4); + + writeU32(&m_data[m_read_offset], src.color); + + m_read_offset += 4; + return *this; +} + +Buffer<u8> NetworkPacket::oldForgePacket() +{ + Buffer<u8> sb(m_datasize + 2); + writeU16(&sb[0], m_command); + memcpy(&sb[2], m_data.data(), m_datasize); + + return sb; +} diff --git a/src/network/networkpacket.h b/src/network/networkpacket.h new file mode 100644 index 0000000..b9c39f3 --- /dev/null +++ b/src/network/networkpacket.h @@ -0,0 +1,137 @@ +/* +Minetest +Copyright (C) 2015 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "util/pointer.h" +#include "util/numeric.h" +#include "networkprotocol.h" +#include <SColor.h> + +class NetworkPacket +{ + +public: + NetworkPacket(u16 command, u32 datasize, session_t peer_id); + NetworkPacket(u16 command, u32 datasize); + NetworkPacket() = default; + + ~NetworkPacket(); + + void putRawPacket(const u8 *data, u32 datasize, session_t peer_id); + void clear(); + + // Getters + u32 getSize() const { return m_datasize; } + session_t getPeerId() const { return m_peer_id; } + u16 getCommand() { return m_command; } + u32 getRemainingBytes() const { return m_datasize - m_read_offset; } + const char *getRemainingString() { return getString(m_read_offset); } + + // Returns a c-string without copying. + // A better name for this would be getRawString() + const char *getString(u32 from_offset); + // major difference to putCString(): doesn't write len into the buffer + void putRawString(const char *src, u32 len); + void putRawString(const std::string &src) + { + putRawString(src.c_str(), src.size()); + } + + NetworkPacket &operator>>(std::string &dst); + NetworkPacket &operator<<(const std::string &src); + + void putLongString(const std::string &src); + + NetworkPacket &operator>>(std::wstring &dst); + NetworkPacket &operator<<(const std::wstring &src); + + std::string readLongString(); + + NetworkPacket &operator>>(char &dst); + NetworkPacket &operator<<(char src); + + NetworkPacket &operator>>(bool &dst); + NetworkPacket &operator<<(bool src); + + u8 getU8(u32 offset); + + NetworkPacket &operator>>(u8 &dst); + NetworkPacket &operator<<(u8 src); + + u8 *getU8Ptr(u32 offset); + + u16 getU16(u32 from_offset); + NetworkPacket &operator>>(u16 &dst); + NetworkPacket &operator<<(u16 src); + + NetworkPacket &operator>>(u32 &dst); + NetworkPacket &operator<<(u32 src); + + NetworkPacket &operator>>(u64 &dst); + NetworkPacket &operator<<(u64 src); + + NetworkPacket &operator>>(float &dst); + NetworkPacket &operator<<(float src); + + NetworkPacket &operator>>(v2f &dst); + NetworkPacket &operator<<(v2f src); + + NetworkPacket &operator>>(v3f &dst); + NetworkPacket &operator<<(v3f src); + + NetworkPacket &operator>>(s16 &dst); + NetworkPacket &operator<<(s16 src); + + NetworkPacket &operator>>(s32 &dst); + NetworkPacket &operator<<(s32 src); + + NetworkPacket &operator>>(v2s32 &dst); + NetworkPacket &operator<<(v2s32 src); + + NetworkPacket &operator>>(v3s16 &dst); + NetworkPacket &operator<<(v3s16 src); + + NetworkPacket &operator>>(v3s32 &dst); + NetworkPacket &operator<<(v3s32 src); + + NetworkPacket &operator>>(video::SColor &dst); + NetworkPacket &operator<<(video::SColor src); + + // Temp, we remove SharedBuffer when migration finished + // ^ this comment has been here for 4 years + Buffer<u8> oldForgePacket(); + +private: + void checkReadOffset(u32 from_offset, u32 field_size); + + inline void checkDataSize(u32 field_size) + { + if (m_read_offset + field_size > m_datasize) { + m_datasize = m_read_offset + field_size; + m_data.resize(m_datasize); + } + } + + std::vector<u8> m_data; + u32 m_datasize = 0; + u32 m_read_offset = 0; + u16 m_command = 0; + session_t m_peer_id = 0; +}; diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h new file mode 100644 index 0000000..3ab839f --- /dev/null +++ b/src/network/networkprotocol.h @@ -0,0 +1,1141 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "util/string.h" + +/* + changes by PROTOCOL_VERSION: + + PROTOCOL_VERSION 3: + Base for writing changes here + PROTOCOL_VERSION 4: + Add TOCLIENT_MEDIA + Add TOCLIENT_TOOLDEF + Add TOCLIENT_NODEDEF + Add TOCLIENT_CRAFTITEMDEF + Add TOSERVER_INTERACT + Obsolete TOSERVER_CLICK_ACTIVEOBJECT + Obsolete TOSERVER_GROUND_ACTION + PROTOCOL_VERSION 5: + Make players to be handled mostly as ActiveObjects + PROTOCOL_VERSION 6: + Only non-cached textures are sent + PROTOCOL_VERSION 7: + Add TOCLIENT_ITEMDEF + Obsolete TOCLIENT_TOOLDEF + Obsolete TOCLIENT_CRAFTITEMDEF + Compress the contents of TOCLIENT_ITEMDEF and TOCLIENT_NODEDEF + PROTOCOL_VERSION 8: + Digging based on item groups + Many things + PROTOCOL_VERSION 9: + ContentFeatures and NodeDefManager use a different serialization + format; better for future version cross-compatibility + Many things + Obsolete TOCLIENT_PLAYERITEM + PROTOCOL_VERSION 10: + TOCLIENT_PRIVILEGES + Version raised to force 'fly' and 'fast' privileges into effect. + Node metadata change (came in later; somewhat incompatible) + PROTOCOL_VERSION 11: + TileDef in ContentFeatures + Nodebox drawtype + (some dev snapshot) + TOCLIENT_INVENTORY_FORMSPEC + (0.4.0, 0.4.1) + PROTOCOL_VERSION 12: + TOSERVER_INVENTORY_FIELDS + 16-bit node ids + TOCLIENT_DETACHED_INVENTORY + PROTOCOL_VERSION 13: + InventoryList field "Width" (deserialization fails with old versions) + PROTOCOL_VERSION 14: + Added transfer of player pressed keys to the server + Added new messages for mesh and bone animation, as well as attachments + AO_CMD_SET_ANIMATION + AO_CMD_SET_BONE_POSITION + GENERIC_CMD_SET_ATTACHMENT + PROTOCOL_VERSION 15: + Serialization format changes + PROTOCOL_VERSION 16: + TOCLIENT_SHOW_FORMSPEC + PROTOCOL_VERSION 17: + Serialization format change: include backface_culling flag in TileDef + Added rightclickable field in nodedef + TOCLIENT_SPAWN_PARTICLE + TOCLIENT_ADD_PARTICLESPAWNER + TOCLIENT_DELETE_PARTICLESPAWNER + PROTOCOL_VERSION 18: + damageGroups added to ToolCapabilities + sound_place added to ItemDefinition + PROTOCOL_VERSION 19: + AO_CMD_SET_PHYSICS_OVERRIDE + PROTOCOL_VERSION 20: + TOCLIENT_HUDADD + TOCLIENT_HUDRM + TOCLIENT_HUDCHANGE + TOCLIENT_HUD_SET_FLAGS + PROTOCOL_VERSION 21: + TOCLIENT_BREATH + TOSERVER_BREATH + range added to ItemDefinition + drowning, leveled and liquid_range added to ContentFeatures + stepheight and collideWithObjects added to object properties + version, heat and humidity transfer in MapBock + automatic_face_movement_dir and automatic_face_movement_dir_offset + added to object properties + PROTOCOL_VERSION 22: + add swap_node + PROTOCOL_VERSION 23: + Obsolete TOSERVER_RECEIVED_MEDIA + Server: Stop using TOSERVER_CLIENT_READY + PROTOCOL_VERSION 24: + ContentFeatures version 7 + ContentFeatures: change number of special tiles to 6 (CF_SPECIAL_COUNT) + PROTOCOL_VERSION 25: + Rename TOCLIENT_ACCESS_DENIED to TOCLIENT_ACCESS_DENIED_LEGAGY + Rename TOCLIENT_DELETE_PARTICLESPAWNER to + TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY + Rename TOSERVER_PASSWORD to TOSERVER_PASSWORD_LEGACY + Rename TOSERVER_INIT to TOSERVER_INIT_LEGACY + Rename TOCLIENT_INIT to TOCLIENT_INIT_LEGACY + Add TOCLIENT_ACCESS_DENIED new opcode (0x0A), using error codes + for standard error, keeping customisation possible. This + permit translation + Add TOCLIENT_DELETE_PARTICLESPAWNER (0x53), fixing the u16 read and + reading u32 + Add new opcode TOSERVER_INIT for client presentation to server + Add new opcodes TOSERVER_FIRST_SRP, TOSERVER_SRP_BYTES_A, + TOSERVER_SRP_BYTES_M, TOCLIENT_SRP_BYTES_S_B + for the three supported auth mechanisms around srp + Add new opcodes TOCLIENT_ACCEPT_SUDO_MODE and TOCLIENT_DENY_SUDO_MODE + for sudo mode handling (auth mech generic way of changing password). + Add TOCLIENT_HELLO for presenting server to client after client + presentation + Add TOCLIENT_AUTH_ACCEPT to accept connection from client + Rename GENERIC_CMD_SET_ATTACHMENT to AO_CMD_ATTACH_TO + PROTOCOL_VERSION 26: + Add TileDef tileable_horizontal, tileable_vertical flags + PROTOCOL_VERSION 27: + backface_culling: backwards compatibility for playing with + newer client on pre-27 servers. + Add nodedef v3 - connected nodeboxes + PROTOCOL_VERSION 28: + CPT2_MESHOPTIONS + PROTOCOL_VERSION 29: + Server doesn't accept TOSERVER_BREATH anymore + serialization of TileAnimation params changed + TAT_SHEET_2D + Removed client-sided chat perdiction + PROTOCOL VERSION 30: + New ContentFeatures serialization version + Add node and tile color and palette + Fix plantlike visual_scale being applied squared and add compatibility + with pre-30 clients by sending sqrt(visual_scale) + PROTOCOL VERSION 31: + Add tile overlay + Stop sending TOSERVER_CLIENT_READY + PROTOCOL VERSION 32: + Add fading sounds + PROTOCOL VERSION 33: + Add TOCLIENT_UPDATE_PLAYER_LIST and send the player list to the client, + instead of guessing based on the active object list. + PROTOCOL VERSION 34: + Add sound pitch + PROTOCOL VERSION 35: + Rename TOCLIENT_CHAT_MESSAGE to TOCLIENT_CHAT_MESSAGE_OLD (0x30) + Add TOCLIENT_CHAT_MESSAGE (0x2F) + This chat message is a signalisation message containing various + informations: + * timestamp + * sender + * type (RAW, NORMAL, ANNOUNCE, SYSTEM) + * content + Add TOCLIENT_CSM_RESTRICTION_FLAGS to define which CSM features should be + limited + Add settable player collisionbox. Breaks compatibility with older + clients as a 1-node vertical offset has been removed from player's + position + Add settable player stepheight using existing object property. + Breaks compatibility with older clients. + PROTOCOL VERSION 36: + Backwards compatibility drop + Add 'can_zoom' to player object properties + Add glow to object properties + Change TileDef serialization format. + Add world-aligned tiles. + Mod channels + Raise ObjectProperties version to 3 for removing 'can_zoom' and adding + 'zoom_fov'. + Nodebox version 5 + Add disconnected nodeboxes + Add TOCLIENT_FORMSPEC_PREPEND + PROTOCOL VERSION 37: + Redo detached inventory sending + Add TOCLIENT_NODEMETA_CHANGED + New network float format + ContentFeatures version 13 + Add full Euler rotations instead of just yaw + Add TOCLIENT_PLAYER_SPEED + PROTOCOL VERSION 38: + Incremental inventory sending mode + Unknown inventory serialization fields no longer throw an error + Mod-specific formspec version + Player FOV override API + "ephemeral" added to TOCLIENT_PLAY_SOUND + PROTOCOL VERSION 39: + Updated set_sky packet + Adds new sun, moon and stars packets + Minimap modes + PROTOCOL VERSION 40: + TOCLIENT_MEDIA_PUSH changed, TOSERVER_HAVE_MEDIA added + Added new particlespawner parameters + [scheduled bump for 5.6.0] +*/ + +#define LATEST_PROTOCOL_VERSION 41 +#define LATEST_PROTOCOL_VERSION_STRING TOSTRING(LATEST_PROTOCOL_VERSION) + +// Server's supported network protocol range +#define SERVER_PROTOCOL_VERSION_MIN 37 +#define SERVER_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION + +// Client's supported network protocol range +// The minimal version depends on whether +// send_pre_v25_init is enabled or not +#define CLIENT_PROTOCOL_VERSION_MIN 37 +#define CLIENT_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION + +// Constant that differentiates the protocol from random data and other protocols +#define PROTOCOL_ID 0x4f457403 + +#define PASSWORD_SIZE 28 // Maximum password length. Allows for + // base64-encoded SHA-1 (27+\0). + +// See also formspec [Version History] in doc/lua_api.txt +#define FORMSPEC_API_VERSION 6 + +#define TEXTURENAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-" + +typedef u16 session_t; + +enum ToClientCommand +{ + TOCLIENT_HELLO = 0x02, + /* + Sent after TOSERVER_INIT. + + u8 deployed serialisation version + u16 deployed network compression mode + u16 deployed protocol version + u32 supported auth methods + std::string username that should be used for legacy hash (for proper casing) + */ + TOCLIENT_AUTH_ACCEPT = 0x03, + /* + Message from server to accept auth. + + v3s16 player's position + v3f(0,BS/2,0) floatToInt'd + u64 map seed + f1000 recommended send interval + u32 : supported auth methods for sudo mode + (where the user can change their password) + */ + TOCLIENT_ACCEPT_SUDO_MODE = 0x04, + /* + Sent to client to show it is in sudo mode now. + */ + TOCLIENT_DENY_SUDO_MODE = 0x05, + /* + Signals client that sudo mode auth failed. + */ + TOCLIENT_ACCESS_DENIED = 0x0A, + /* + u8 reason + std::string custom reason (if needed, otherwise "") + u8 (bool) reconnect + */ + + TOCLIENT_INIT_LEGACY = 0x10, // Obsolete + + TOCLIENT_BLOCKDATA = 0x20, //TODO: Multiple blocks + TOCLIENT_ADDNODE = 0x21, + /* + v3s16 position + serialized mapnode + u8 keep_metadata // Added in protocol version 22 + */ + TOCLIENT_REMOVENODE = 0x22, + + TOCLIENT_PLAYERPOS = 0x23, // Obsolete + TOCLIENT_PLAYERINFO = 0x24, // Obsolete + TOCLIENT_OPT_BLOCK_NOT_FOUND = 0x25, // Obsolete + TOCLIENT_SECTORMETA = 0x26, // Obsolete + + TOCLIENT_INVENTORY = 0x27, + /* + [0] u16 command + [2] serialized inventory + */ + + TOCLIENT_OBJECTDATA = 0x28, // Obsolete + + TOCLIENT_TIME_OF_DAY = 0x29, + /* + u16 time (0-23999) + Added in a later version: + f1000 time_speed + */ + + TOCLIENT_CSM_RESTRICTION_FLAGS = 0x2A, + /* + u32 CSMRestrictionFlags byteflag + */ + + TOCLIENT_PLAYER_SPEED = 0x2B, + /* + v3f added_vel + */ + + TOCLIENT_MEDIA_PUSH = 0x2C, + /* + std::string raw_hash + std::string filename + u32 callback_token + bool should_be_cached + */ + + // (oops, there is some gap here) + + TOCLIENT_CHAT_MESSAGE = 0x2F, + /* + u8 version + u8 message_type + u16 sendername length + wstring sendername + u16 length + wstring message + */ + + TOCLIENT_CHAT_MESSAGE_OLD = 0x30, // Obsolete + + TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD = 0x31, + /* + u16 count of removed objects + for all removed objects { + u16 id + } + u16 count of added objects + for all added objects { + u16 id + u8 type + u32 initialization data length + string initialization data + } + */ + + TOCLIENT_ACTIVE_OBJECT_MESSAGES = 0x32, + /* + for all objects + { + u16 id + u16 message length + string message + } + */ + + TOCLIENT_HP = 0x33, + /* + u8 hp + */ + + TOCLIENT_MOVE_PLAYER = 0x34, + /* + v3f1000 player position + f1000 player pitch + f1000 player yaw + */ + + TOCLIENT_ACCESS_DENIED_LEGACY = 0x35, + /* + u16 reason_length + wstring reason + */ + + TOCLIENT_FOV = 0x36, + /* + Sends an FOV override/multiplier to client. + + f32 fov + bool is_multiplier + f32 transition_time + */ + + TOCLIENT_DEATHSCREEN = 0x37, + /* + u8 bool set camera point target + v3f1000 camera point target (to point the death cause or whatever) + */ + + TOCLIENT_MEDIA = 0x38, + /* + u16 total number of texture bunches + u16 index of this bunch + u32 number of files in this bunch + for each file { + u16 length of name + string name + u32 length of data + data + } + u16 length of remote media server url (if applicable) + string url + */ + + TOCLIENT_TOOLDEF = 0x39, + /* + u32 length of the next item + serialized ToolDefManager + */ + + TOCLIENT_NODEDEF = 0x3a, + /* + u32 length of the next item + serialized NodeDefManager + */ + + TOCLIENT_CRAFTITEMDEF = 0x3b, + /* + u32 length of the next item + serialized CraftiItemDefManager + */ + + TOCLIENT_ANNOUNCE_MEDIA = 0x3c, + + /* + u32 number of files + for each texture { + u16 length of name + string name + u16 length of sha1_digest + string sha1_digest + } + */ + + TOCLIENT_ITEMDEF = 0x3d, + /* + u32 length of next item + serialized ItemDefManager + */ + + TOCLIENT_PLAY_SOUND = 0x3f, + /* + s32 sound_id + u16 len + u8[len] sound name + s32 gain*1000 + u8 type (0=local, 1=positional, 2=object) + s32[3] pos_nodes*10000 + u16 object_id + u8 loop (bool) + u8 ephemeral (bool) + */ + + TOCLIENT_STOP_SOUND = 0x40, + /* + s32 sound_id + */ + + TOCLIENT_PRIVILEGES = 0x41, + /* + u16 number of privileges + for each privilege + u16 len + u8[len] privilege + */ + + TOCLIENT_INVENTORY_FORMSPEC = 0x42, + /* + u32 len + u8[len] formspec + */ + + TOCLIENT_DETACHED_INVENTORY = 0x43, + /* + [0] u16 command + u16 len + u8[len] name + [2] serialized inventory + */ + + TOCLIENT_SHOW_FORMSPEC = 0x44, + /* + [0] u16 command + u32 len + u8[len] formspec + u16 len + u8[len] formname + */ + + TOCLIENT_MOVEMENT = 0x45, + /* + f1000 movement_acceleration_default + f1000 movement_acceleration_air + f1000 movement_acceleration_fast + f1000 movement_speed_walk + f1000 movement_speed_crouch + f1000 movement_speed_fast + f1000 movement_speed_climb + f1000 movement_speed_jump + f1000 movement_liquid_fluidity + f1000 movement_liquid_fluidity_smooth + f1000 movement_liquid_sink + f1000 movement_gravity + */ + + TOCLIENT_SPAWN_PARTICLE = 0x46, + /* + -- struct range<T> { T min, T max, f32 bias }; + v3f pos + v3f velocity + v3f acceleration + f32 expirationtime + f32 size + u8 bool collisiondetection + u32 len + u8[len] texture + u8 bool vertical + u8 collision_removal + TileAnimation animation + u8 glow + u8 object_collision + v3f drag + range<v3f> bounce + */ + + TOCLIENT_ADD_PARTICLESPAWNER = 0x47, + /* + -- struct range<T> { T min, T max, f32 bias }; + -- struct tween<T> { T start, T end }; + u16 amount + f32 spawntime + v3f minpos + v3f maxpos + v3f minvel + v3f maxvel + v3f minacc + v3f maxacc + f32 minexptime + f32 maxexptime + f32 minsize + f32 maxsize + u8 bool collisiondetection + u32 len + u8[len] texture + u8 bool vertical + u8 collision_removal + u32 id + TileAnimation animation + u8 glow + u8 object_collision + + f32 pos_start_bias + f32 vel_start_bias + f32 acc_start_bias + f32 exptime_start_bias + f32 size_start_bias + + range<v3f> pos_end + -- i.e v3f pos_end_min + -- v3f pos_end_max + -- f32 pos_end_bias + range<v3f> vel_end + range<v3f> acc_end + + tween<range<v3f>> drag + -- i.e. v3f drag_start_min + -- v3f drag_start_max + -- f32 drag_start_bias + -- v3f drag_end_min + -- v3f drag_end_max + -- f32 drag_end_bias + tween<range<v3f>> jitter + tween<range<f32>> bounce + + u8 attraction_kind + none = 0 + point = 1 + line = 2 + plane = 3 + + if attraction_kind > none { + tween<range<f32>> attract_strength + tween<v3f> attractor_origin + u16 attractor_origin_attachment_object_id + u8 spawner_flags + bit 1: attractor_kill (particles dies on contact) + if attraction_mode > point { + tween<v3f> attractor_angle + u16 attractor_origin_attachment_object_id + } + } + + tween<range<v3f>> radius + tween<range<v3f>> drag + + u16 texpool_sz + texpool_sz.times { + u8 flags + -- bit 0: animated + -- other bits free & ignored as of proto v40 + tween<f32> alpha + tween<v2f> scale + if flags.animated { + TileAnimation animation + } + } + + */ + + TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY = 0x48, // Obsolete + + TOCLIENT_HUDADD = 0x49, + /* + u32 id + u8 type + v2f1000 pos + u16 len + u8[len] name + v2f1000 scale + u16 len2 + u8[len2] text + u32 number + u32 item + u32 dir + v2f1000 align + v2f1000 offset + v3f1000 world_pos + v2s32 size + s16 z_index + u16 len3 + u8[len3] text2 + */ + + TOCLIENT_HUDRM = 0x4a, + /* + u32 id + */ + + TOCLIENT_HUDCHANGE = 0x4b, + /* + u32 id + u8 stat + [v2f1000 data | + u32 len + u8[len] data | + u32 data] + */ + + TOCLIENT_HUD_SET_FLAGS = 0x4c, + /* + u32 flags + u32 mask + */ + + TOCLIENT_HUD_SET_PARAM = 0x4d, + /* + u16 param + u16 len + u8[len] value + */ + + TOCLIENT_BREATH = 0x4e, + /* + u16 breath + */ + + TOCLIENT_SET_SKY = 0x4f, + /* + Protocol 38: + u8[4] base_color (ARGB) + u8 len + u8[len] type + u16 count + foreach count: + u8 len + u8[len] param + u8 clouds (boolean) + + Protocol 39: + u8[4] bgcolor (ARGB) + std::string type + int texture_count + std::string[6] param + bool clouds + bool bgcolor_fog + u8[4] day_sky (ARGB) + u8[4] day_horizon (ARGB) + u8[4] dawn_sky (ARGB) + u8[4] dawn_horizon (ARGB) + u8[4] night_sky (ARGB) + u8[4] night_horizon (ARGB) + u8[4] indoors (ARGB) + u8[4] fog_sun_tint (ARGB) + u8[4] fog_moon_tint (ARGB) + std::string fog_tint_type + */ + + TOCLIENT_OVERRIDE_DAY_NIGHT_RATIO = 0x50, + /* + u8 do_override (boolean) + u16 day-night ratio 0...65535 + */ + + TOCLIENT_LOCAL_PLAYER_ANIMATIONS = 0x51, + /* + v2s32 stand/idle + v2s32 walk + v2s32 dig + v2s32 walk+dig + f1000 frame_speed + */ + + TOCLIENT_EYE_OFFSET = 0x52, + /* + v3f1000 first + v3f1000 third + */ + + TOCLIENT_DELETE_PARTICLESPAWNER = 0x53, + /* + u32 id + */ + + TOCLIENT_CLOUD_PARAMS = 0x54, + /* + f1000 density + u8[4] color_diffuse (ARGB) + u8[4] color_ambient (ARGB) + f1000 height + f1000 thickness + v2f1000 speed + */ + + TOCLIENT_FADE_SOUND = 0x55, + /* + s32 sound_id + float step + float gain + */ + TOCLIENT_UPDATE_PLAYER_LIST = 0x56, + /* + u8 type + u16 number of players + for each player + u16 len + u8[len] player name + */ + + TOCLIENT_MODCHANNEL_MSG = 0x57, + /* + u16 channel name length + std::string channel name + u16 channel name sender + std::string channel name + u16 message length + std::string message + */ + + TOCLIENT_MODCHANNEL_SIGNAL = 0x58, + /* + u8 signal id + u16 channel name length + std::string channel name + */ + + TOCLIENT_NODEMETA_CHANGED = 0x59, + /* + serialized and compressed node metadata + */ + + TOCLIENT_SET_SUN = 0x5a, + /* + bool visible + std::string texture + std::string tonemap + std::string sunrise + f32 scale + */ + + TOCLIENT_SET_MOON = 0x5b, + /* + bool visible + std::string texture + std::string tonemap + f32 scale + */ + + TOCLIENT_SET_STARS = 0x5c, + /* + bool visible + u32 count + u8[4] starcolor (ARGB) + f32 scale + f32 day_opacity + */ + + TOCLIENT_SRP_BYTES_S_B = 0x60, + /* + Belonging to AUTH_MECHANISM_SRP. + + std::string bytes_s + std::string bytes_B + */ + + TOCLIENT_FORMSPEC_PREPEND = 0x61, + /* + u16 len + u8[len] formspec + */ + + TOCLIENT_MINIMAP_MODES = 0x62, + /* + u16 count // modes + u16 mode // wanted current mode index after change + for each mode + u16 type + std::string label + u16 size + std::string extra + */ + + TOCLIENT_SET_LIGHTING = 0x63, + /* + f32 shadow_intensity + */ + + TOCLIENT_NUM_MSG_TYPES = 0x64, +}; + +enum ToServerCommand +{ + TOSERVER_INIT = 0x02, + /* + Sent first after connected. + + u8 serialisation version (=SER_FMT_VER_HIGHEST_READ) + u16 supported network compression modes + u16 minimum supported network protocol version + u16 maximum supported network protocol version + std::string player name + */ + + TOSERVER_INIT_LEGACY = 0x10, // Obsolete + + TOSERVER_INIT2 = 0x11, + /* + Sent as an ACK for TOCLIENT_INIT. + After this, the server can send data. + + [0] u16 TOSERVER_INIT2 + */ + + TOSERVER_MODCHANNEL_JOIN = 0x17, + /* + u16 channel name length + std::string channel name + */ + + TOSERVER_MODCHANNEL_LEAVE = 0x18, + /* + u16 channel name length + std::string channel name + */ + + TOSERVER_MODCHANNEL_MSG = 0x19, + /* + u16 channel name length + std::string channel name + u16 message length + std::string message + */ + + TOSERVER_GETBLOCK = 0x20, // Obsolete + TOSERVER_ADDNODE = 0x21, // Obsolete + TOSERVER_REMOVENODE = 0x22, // Obsolete + + TOSERVER_PLAYERPOS = 0x23, + /* + [0] u16 command + [2] v3s32 position*100 + [2+12] v3s32 speed*100 + [2+12+12] s32 pitch*100 + [2+12+12+4] s32 yaw*100 + [2+12+12+4+4] u32 keyPressed + [2+12+12+4+4+1] u8 fov*80 + [2+12+12+4+4+4+1] u8 ceil(wanted_range / MAP_BLOCKSIZE) + */ + + TOSERVER_GOTBLOCKS = 0x24, + /* + [0] u16 command + [2] u8 count + [3] v3s16 pos_0 + [3+6] v3s16 pos_1 + ... + */ + + TOSERVER_DELETEDBLOCKS = 0x25, + /* + [0] u16 command + [2] u8 count + [3] v3s16 pos_0 + [3+6] v3s16 pos_1 + ... + */ + + TOSERVER_ADDNODE_FROM_INVENTORY = 0x26, // Obsolete + TOSERVER_CLICK_OBJECT = 0x27, // Obsolete + TOSERVER_GROUND_ACTION = 0x28, // Obsolete + TOSERVER_RELEASE = 0x29, // Obsolete + TOSERVER_SIGNTEXT = 0x30, // Obsolete + + TOSERVER_INVENTORY_ACTION = 0x31, + /* + See InventoryAction in inventorymanager.h + */ + + TOSERVER_CHAT_MESSAGE = 0x32, + /* + u16 length + wstring message + */ + + TOSERVER_SIGNNODETEXT = 0x33, // Obsolete + TOSERVER_CLICK_ACTIVEOBJECT = 0x34, // Obsolete + + TOSERVER_DAMAGE = 0x35, + /* + u8 amount + */ + + TOSERVER_PASSWORD_LEGACY = 0x36, // Obsolete + + TOSERVER_PLAYERITEM = 0x37, + /* + Sent to change selected item. + + [0] u16 TOSERVER_PLAYERITEM + [2] u16 item + */ + + TOSERVER_RESPAWN = 0x38, + /* + u16 TOSERVER_RESPAWN + */ + + TOSERVER_INTERACT = 0x39, + /* + [0] u16 command + [2] u8 action + [3] u16 item + [5] u32 length of the next item + [9] serialized PointedThing + actions: + 0: start digging (from undersurface) or use + 1: stop digging (all parameters ignored) + 2: digging completed + 3: place block or item (to abovesurface) + 4: use item + */ + + TOSERVER_REMOVED_SOUNDS = 0x3a, + /* + u16 len + s32[len] sound_id + */ + + TOSERVER_NODEMETA_FIELDS = 0x3b, + /* + v3s16 p + u16 len + u8[len] form name (reserved for future use) + u16 number of fields + for each field: + u16 len + u8[len] field name + u32 len + u8[len] field value + */ + + TOSERVER_INVENTORY_FIELDS = 0x3c, + /* + u16 len + u8[len] form name (reserved for future use) + u16 number of fields + for each field: + u16 len + u8[len] field name + u32 len + u8[len] field value + */ + + TOSERVER_REQUEST_MEDIA = 0x40, + /* + u16 number of files requested + for each file { + u16 length of name + string name + } + */ + + TOSERVER_HAVE_MEDIA = 0x41, + /* + u8 number of callback tokens + for each: + u32 token + */ + + TOSERVER_BREATH = 0x42, // Obsolete + + TOSERVER_CLIENT_READY = 0x43, + /* + u8 major + u8 minor + u8 patch + u8 reserved + u16 len + u8[len] full_version_string + */ + + TOSERVER_FIRST_SRP = 0x50, + /* + Belonging to AUTH_MECHANISM_FIRST_SRP. + + std::string srp salt + std::string srp verification key + u8 is_empty (=1 if password is empty, 0 otherwise) + */ + + TOSERVER_SRP_BYTES_A = 0x51, + /* + Belonging to AUTH_MECHANISM_SRP, + depending on current_login_based_on. + + std::string bytes_A + u8 current_login_based_on : on which version of the password's + hash this login is based on (0 legacy hash, + or 1 directly the password) + */ + + TOSERVER_SRP_BYTES_M = 0x52, + /* + Belonging to AUTH_MECHANISM_SRP. + + std::string bytes_M + */ + + TOSERVER_NUM_MSG_TYPES = 0x53, +}; + +enum AuthMechanism +{ + // reserved + AUTH_MECHANISM_NONE = 0, + + // SRP based on the legacy hash + AUTH_MECHANISM_LEGACY_PASSWORD = 1 << 0, + + // SRP based on the srp verification key + AUTH_MECHANISM_SRP = 1 << 1, + + // Establishes a srp verification key, for first login and password changing + AUTH_MECHANISM_FIRST_SRP = 1 << 2, +}; + +enum AccessDeniedCode : u8 { + SERVER_ACCESSDENIED_WRONG_PASSWORD, + SERVER_ACCESSDENIED_UNEXPECTED_DATA, + SERVER_ACCESSDENIED_SINGLEPLAYER, + SERVER_ACCESSDENIED_WRONG_VERSION, + SERVER_ACCESSDENIED_WRONG_CHARS_IN_NAME, + SERVER_ACCESSDENIED_WRONG_NAME, + SERVER_ACCESSDENIED_TOO_MANY_USERS, + SERVER_ACCESSDENIED_EMPTY_PASSWORD, + SERVER_ACCESSDENIED_ALREADY_CONNECTED, + SERVER_ACCESSDENIED_SERVER_FAIL, + SERVER_ACCESSDENIED_CUSTOM_STRING, + SERVER_ACCESSDENIED_SHUTDOWN, + SERVER_ACCESSDENIED_CRASH, + SERVER_ACCESSDENIED_MAX, +}; + +enum NetProtoCompressionMode { + NETPROTO_COMPRESSION_NONE = 0, +}; + +const static std::string accessDeniedStrings[SERVER_ACCESSDENIED_MAX] = { + "Invalid password", + "Your client sent something the server didn't expect. Try reconnecting or updating your client.", + "The server is running in simple singleplayer mode. You cannot connect.", + "Your client's version is not supported.\nPlease contact the server administrator.", + "Player name contains disallowed characters", + "Player name not allowed", + "Too many users", + "Empty passwords are disallowed. Set a password and try again.", + "Another client is connected with this name. If your client closed unexpectedly, try again in a minute.", + "Internal server error", + "", + "Server shutting down", + "The server has experienced an internal error. You will now be disconnected." +}; + +enum PlayerListModifer : u8 +{ + PLAYER_LIST_INIT, + PLAYER_LIST_ADD, + PLAYER_LIST_REMOVE, +}; + +enum CSMRestrictionFlags : u64 { + CSM_RF_NONE = 0x00000000, + // Until server-sent CSM and verifying of builtin are complete, + // 'CSM_RF_LOAD_CLIENT_MODS' also disables loading 'builtin'. + // When those are complete, this should return to only being a restriction on the + // loading of client mods. + CSM_RF_LOAD_CLIENT_MODS = 0x00000001, // Don't load client-provided mods or 'builtin' + CSM_RF_CHAT_MESSAGES = 0x00000002, // Disable chat message sending from CSM + CSM_RF_READ_ITEMDEFS = 0x00000004, // Disable itemdef lookups + CSM_RF_READ_NODEDEFS = 0x00000008, // Disable nodedef lookups + CSM_RF_LOOKUP_NODES = 0x00000010, // Limit node lookups + CSM_RF_READ_PLAYERINFO = 0x00000020, // Disable player info lookups + CSM_RF_ALL = 0xFFFFFFFF, +}; + +enum InteractAction : u8 +{ + INTERACT_START_DIGGING, // 0: start digging (from undersurface) or use + INTERACT_STOP_DIGGING, // 1: stop digging (all parameters ignored) + INTERACT_DIGGING_COMPLETED, // 2: digging completed + INTERACT_PLACE, // 3: place block or item (to abovesurface) + INTERACT_USE, // 4: use item + INTERACT_ACTIVATE // 5: rightclick air ("activate") +}; diff --git a/src/network/peerhandler.h b/src/network/peerhandler.h new file mode 100644 index 0000000..da65483 --- /dev/null +++ b/src/network/peerhandler.h @@ -0,0 +1,77 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "networkprotocol.h" + +namespace con +{ + +typedef enum +{ + MIN_RTT, + MAX_RTT, + AVG_RTT, + MIN_JITTER, + MAX_JITTER, + AVG_JITTER +} rtt_stat_type; + +class Peer; + +class PeerHandler +{ +public: + PeerHandler() = default; + + virtual ~PeerHandler() = default; + + /* + This is called after the Peer has been inserted into the + Connection's peer container. + */ + virtual void peerAdded(Peer *peer) = 0; + + /* + This is called before the Peer has been removed from the + Connection's peer container. + */ + virtual void deletingPeer(Peer *peer, bool timeout) = 0; +}; + +enum PeerChangeType : u8 +{ + PEER_ADDED, + PEER_REMOVED +}; + +struct PeerChange +{ + PeerChange(PeerChangeType t, session_t _peer_id, bool _timeout) : + type(t), peer_id(_peer_id), timeout(_timeout) + { + } + PeerChange() = delete; + + PeerChangeType type; + session_t peer_id; + bool timeout; +}; +} diff --git a/src/network/serveropcodes.cpp b/src/network/serveropcodes.cpp new file mode 100644 index 0000000..12665e7 --- /dev/null +++ b/src/network/serveropcodes.cpp @@ -0,0 +1,225 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2015 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "serveropcodes.h" + +const static ToServerCommandHandler null_command_handler = { "TOSERVER_NULL", TOSERVER_STATE_ALL, &Server::handleCommand_Null }; + +const ToServerCommandHandler toServerCommandTable[TOSERVER_NUM_MSG_TYPES] = +{ + null_command_handler, // 0x00 (never use this) + null_command_handler, // 0x01 + { "TOSERVER_INIT", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_Init }, // 0x02 + null_command_handler, // 0x03 + null_command_handler, // 0x04 + null_command_handler, // 0x05 + null_command_handler, // 0x06 + null_command_handler, // 0x07 + null_command_handler, // 0x08 + null_command_handler, // 0x09 + null_command_handler, // 0x0a + null_command_handler, // 0x0b + null_command_handler, // 0x0c + null_command_handler, // 0x0d + null_command_handler, // 0x0e + null_command_handler, // 0x0f + null_command_handler, // 0x10 + { "TOSERVER_INIT2", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_Init2 }, // 0x11 + null_command_handler, // 0x12 + null_command_handler, // 0x13 + null_command_handler, // 0x14 + null_command_handler, // 0x15 + null_command_handler, // 0x16 + { "TOSERVER_MODCHANNEL_JOIN", TOSERVER_STATE_INGAME, &Server::handleCommand_ModChannelJoin }, // 0x17 + { "TOSERVER_MODCHANNEL_LEAVE", TOSERVER_STATE_INGAME, &Server::handleCommand_ModChannelLeave }, // 0x18 + { "TOSERVER_MODCHANNEL_MSG", TOSERVER_STATE_INGAME, &Server::handleCommand_ModChannelMsg }, // 0x19 + null_command_handler, // 0x1a + null_command_handler, // 0x1b + null_command_handler, // 0x1c + null_command_handler, // 0x1d + null_command_handler, // 0x1e + null_command_handler, // 0x1f + null_command_handler, // 0x20 + null_command_handler, // 0x21 + null_command_handler, // 0x22 + { "TOSERVER_PLAYERPOS", TOSERVER_STATE_INGAME, &Server::handleCommand_PlayerPos }, // 0x23 + { "TOSERVER_GOTBLOCKS", TOSERVER_STATE_STARTUP, &Server::handleCommand_GotBlocks }, // 0x24 + { "TOSERVER_DELETEDBLOCKS", TOSERVER_STATE_INGAME, &Server::handleCommand_DeletedBlocks }, // 0x25 + null_command_handler, // 0x26 + null_command_handler, // 0x27 + null_command_handler, // 0x28 + null_command_handler, // 0x29 + null_command_handler, // 0x2a + null_command_handler, // 0x2b + null_command_handler, // 0x2c + null_command_handler, // 0x2d + null_command_handler, // 0x2e + null_command_handler, // 0x2f + null_command_handler, // 0x30 + { "TOSERVER_INVENTORY_ACTION", TOSERVER_STATE_INGAME, &Server::handleCommand_InventoryAction }, // 0x31 + { "TOSERVER_CHAT_MESSAGE", TOSERVER_STATE_INGAME, &Server::handleCommand_ChatMessage }, // 0x32 + null_command_handler, // 0x33 + null_command_handler, // 0x34 + { "TOSERVER_DAMAGE", TOSERVER_STATE_INGAME, &Server::handleCommand_Damage }, // 0x35 + null_command_handler, // 0x36 + { "TOSERVER_PLAYERITEM", TOSERVER_STATE_INGAME, &Server::handleCommand_PlayerItem }, // 0x37 + { "TOSERVER_RESPAWN", TOSERVER_STATE_INGAME, &Server::handleCommand_Respawn }, // 0x38 + { "TOSERVER_INTERACT", TOSERVER_STATE_INGAME, &Server::handleCommand_Interact }, // 0x39 + { "TOSERVER_REMOVED_SOUNDS", TOSERVER_STATE_INGAME, &Server::handleCommand_RemovedSounds }, // 0x3a + { "TOSERVER_NODEMETA_FIELDS", TOSERVER_STATE_INGAME, &Server::handleCommand_NodeMetaFields }, // 0x3b + { "TOSERVER_INVENTORY_FIELDS", TOSERVER_STATE_INGAME, &Server::handleCommand_InventoryFields }, // 0x3c + null_command_handler, // 0x3d + null_command_handler, // 0x3e + null_command_handler, // 0x3f + { "TOSERVER_REQUEST_MEDIA", TOSERVER_STATE_STARTUP, &Server::handleCommand_RequestMedia }, // 0x40 + { "TOSERVER_HAVE_MEDIA", TOSERVER_STATE_INGAME, &Server::handleCommand_HaveMedia }, // 0x41 + null_command_handler, // 0x42 + { "TOSERVER_CLIENT_READY", TOSERVER_STATE_STARTUP, &Server::handleCommand_ClientReady }, // 0x43 + null_command_handler, // 0x44 + null_command_handler, // 0x45 + null_command_handler, // 0x46 + null_command_handler, // 0x47 + null_command_handler, // 0x48 + null_command_handler, // 0x49 + null_command_handler, // 0x4a + null_command_handler, // 0x4b + null_command_handler, // 0x4c + null_command_handler, // 0x4d + null_command_handler, // 0x4e + null_command_handler, // 0x4f + { "TOSERVER_FIRST_SRP", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_FirstSrp }, // 0x50 + { "TOSERVER_SRP_BYTES_A", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_SrpBytesA }, // 0x51 + { "TOSERVER_SRP_BYTES_M", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_SrpBytesM }, // 0x52 +}; + +const static ClientCommandFactory null_command_factory = { "TOCLIENT_NULL", 0, false }; + +/* + Channels used for Server -> Client communication + 2: Bulk data (mapblocks, media, ...) + 1: HUD packets + 0: everything else + + Packet order is only guaranteed inside a channel, so packets that operate on + the same objects are *required* to be in the same channel. +*/ + +const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] = +{ + null_command_factory, // 0x00 + null_command_factory, // 0x01 + { "TOCLIENT_HELLO", 0, true }, // 0x02 + { "TOCLIENT_AUTH_ACCEPT", 0, true }, // 0x03 + { "TOCLIENT_ACCEPT_SUDO_MODE", 0, true }, // 0x04 + { "TOCLIENT_DENY_SUDO_MODE", 0, true }, // 0x05 + null_command_factory, // 0x06 + null_command_factory, // 0x07 + null_command_factory, // 0x08 + null_command_factory, // 0x09 + { "TOCLIENT_ACCESS_DENIED", 0, true }, // 0x0A + null_command_factory, // 0x0B + null_command_factory, // 0x0C + null_command_factory, // 0x0D + null_command_factory, // 0x0E + null_command_factory, // 0x0F + { "TOCLIENT_INIT", 0, true }, // 0x10 + null_command_factory, // 0x11 + null_command_factory, // 0x12 + null_command_factory, // 0x13 + null_command_factory, // 0x14 + null_command_factory, // 0x15 + null_command_factory, // 0x16 + null_command_factory, // 0x17 + null_command_factory, // 0x18 + null_command_factory, // 0x19 + null_command_factory, // 0x1A + null_command_factory, // 0x1B + null_command_factory, // 0x1C + null_command_factory, // 0x1D + null_command_factory, // 0x1E + null_command_factory, // 0x1F + { "TOCLIENT_BLOCKDATA", 2, true }, // 0x20 + { "TOCLIENT_ADDNODE", 0, true }, // 0x21 + { "TOCLIENT_REMOVENODE", 0, true }, // 0x22 + null_command_factory, // 0x23 + null_command_factory, // 0x24 + null_command_factory, // 0x25 + null_command_factory, // 0x26 + { "TOCLIENT_INVENTORY", 0, true }, // 0x27 + null_command_factory, // 0x28 + { "TOCLIENT_TIME_OF_DAY", 0, true }, // 0x29 + { "TOCLIENT_CSM_RESTRICTION_FLAGS", 0, true }, // 0x2A + { "TOCLIENT_PLAYER_SPEED", 0, true }, // 0x2B + { "TOCLIENT_MEDIA_PUSH", 0, true }, // 0x2C (sent over channel 1 too if legacy) + null_command_factory, // 0x2D + null_command_factory, // 0x2E + { "TOCLIENT_CHAT_MESSAGE", 0, true }, // 0x2F + null_command_factory, // 0x30 + { "TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD", 0, true }, // 0x31 + { "TOCLIENT_ACTIVE_OBJECT_MESSAGES", 0, true }, // 0x32 (may be sent as unrel over channel 1 too) + { "TOCLIENT_HP", 0, true }, // 0x33 + { "TOCLIENT_MOVE_PLAYER", 0, true }, // 0x34 + null_command_factory, // 0x35 + { "TOCLIENT_FOV", 0, true }, // 0x36 + { "TOCLIENT_DEATHSCREEN", 0, true }, // 0x37 + { "TOCLIENT_MEDIA", 2, true }, // 0x38 + null_command_factory, // 0x39 + { "TOCLIENT_NODEDEF", 0, true }, // 0x3A + null_command_factory, // 0x3B + { "TOCLIENT_ANNOUNCE_MEDIA", 0, true }, // 0x3C + { "TOCLIENT_ITEMDEF", 0, true }, // 0x3D + null_command_factory, // 0x3E + { "TOCLIENT_PLAY_SOUND", 0, true }, // 0x3f (may be sent as unrel too) + { "TOCLIENT_STOP_SOUND", 0, true }, // 0x40 + { "TOCLIENT_PRIVILEGES", 0, true }, // 0x41 + { "TOCLIENT_INVENTORY_FORMSPEC", 0, true }, // 0x42 + { "TOCLIENT_DETACHED_INVENTORY", 0, true }, // 0x43 + { "TOCLIENT_SHOW_FORMSPEC", 0, true }, // 0x44 + { "TOCLIENT_MOVEMENT", 0, true }, // 0x45 + { "TOCLIENT_SPAWN_PARTICLE", 0, true }, // 0x46 + { "TOCLIENT_ADD_PARTICLESPAWNER", 0, true }, // 0x47 + null_command_factory, // 0x48 + { "TOCLIENT_HUDADD", 1, true }, // 0x49 + { "TOCLIENT_HUDRM", 1, true }, // 0x4a + { "TOCLIENT_HUDCHANGE", 1, true }, // 0x4b + { "TOCLIENT_HUD_SET_FLAGS", 1, true }, // 0x4c + { "TOCLIENT_HUD_SET_PARAM", 1, true }, // 0x4d + { "TOCLIENT_BREATH", 0, true }, // 0x4e + { "TOCLIENT_SET_SKY", 0, true }, // 0x4f + { "TOCLIENT_OVERRIDE_DAY_NIGHT_RATIO", 0, true }, // 0x50 + { "TOCLIENT_LOCAL_PLAYER_ANIMATIONS", 0, true }, // 0x51 + { "TOCLIENT_EYE_OFFSET", 0, true }, // 0x52 + { "TOCLIENT_DELETE_PARTICLESPAWNER", 0, true }, // 0x53 + { "TOCLIENT_CLOUD_PARAMS", 0, true }, // 0x54 + { "TOCLIENT_FADE_SOUND", 0, true }, // 0x55 + { "TOCLIENT_UPDATE_PLAYER_LIST", 0, true }, // 0x56 + { "TOCLIENT_MODCHANNEL_MSG", 0, true }, // 0x57 + { "TOCLIENT_MODCHANNEL_SIGNAL", 0, true }, // 0x58 + { "TOCLIENT_NODEMETA_CHANGED", 0, true }, // 0x59 + { "TOCLIENT_SET_SUN", 0, true }, // 0x5a + { "TOCLIENT_SET_MOON", 0, true }, // 0x5b + { "TOCLIENT_SET_STARS", 0, true }, // 0x5c + null_command_factory, // 0x5d + null_command_factory, // 0x5e + null_command_factory, // 0x5f + { "TOSERVER_SRP_BYTES_S_B", 0, true }, // 0x60 + { "TOCLIENT_FORMSPEC_PREPEND", 0, true }, // 0x61 + { "TOCLIENT_MINIMAP_MODES", 0, true }, // 0x62 +}; diff --git a/src/network/serveropcodes.h b/src/network/serveropcodes.h new file mode 100644 index 0000000..6df09d5 --- /dev/null +++ b/src/network/serveropcodes.h @@ -0,0 +1,50 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2015 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "server.h" +#include "networkprotocol.h" + +class NetworkPacket; + +enum ToServerConnectionState { + TOSERVER_STATE_NOT_CONNECTED, + TOSERVER_STATE_STARTUP, + TOSERVER_STATE_INGAME, + TOSERVER_STATE_ALL, +}; +struct ToServerCommandHandler +{ + const std::string name; + ToServerConnectionState state; + void (Server::*handler)(NetworkPacket* pkt); +}; + +struct ClientCommandFactory +{ + const char* name; + u8 channel; + bool reliable; +}; + +extern const ToServerCommandHandler toServerCommandTable[TOSERVER_NUM_MSG_TYPES]; + +extern const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES]; diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp new file mode 100644 index 0000000..a5ee81a --- /dev/null +++ b/src/network/serverpackethandler.cpp @@ -0,0 +1,1843 @@ +/* +Minetest +Copyright (C) 2015 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "chatmessage.h" +#include "server.h" +#include "log.h" +#include "emerge.h" +#include "mapblock.h" +#include "modchannels.h" +#include "nodedef.h" +#include "remoteplayer.h" +#include "rollback_interface.h" +#include "scripting_server.h" +#include "settings.h" +#include "tool.h" +#include "version.h" +#include "network/connection.h" +#include "network/networkprotocol.h" +#include "network/serveropcodes.h" +#include "server/player_sao.h" +#include "server/serverinventorymgr.h" +#include "util/auth.h" +#include "util/base64.h" +#include "util/pointedthing.h" +#include "util/serialize.h" +#include "util/srp.h" + +void Server::handleCommand_Deprecated(NetworkPacket* pkt) +{ + infostream << "Server: " << toServerCommandTable[pkt->getCommand()].name + << " not supported anymore" << std::endl; +} + +void Server::handleCommand_Init(NetworkPacket* pkt) +{ + + if(pkt->getSize() < 1) + return; + + session_t peer_id = pkt->getPeerId(); + RemoteClient *client = getClient(peer_id, CS_Created); + + Address addr; + std::string addr_s; + try { + addr = m_con->GetPeerAddress(peer_id); + addr_s = addr.serializeString(); + } catch (con::PeerNotFoundException &e) { + /* + * no peer for this packet found + * most common reason is peer timeout, e.g. peer didn't + * respond for some time, your server was overloaded or + * things like that. + */ + infostream << "Server::ProcessData(): Canceling: peer " << peer_id << + " not found" << std::endl; + return; + } + + if (client->getState() > CS_Created) { + verbosestream << "Server: Ignoring multiple TOSERVER_INITs from " << + addr_s << " (peer_id=" << peer_id << ")" << std::endl; + return; + } + + client->setCachedAddress(addr); + + verbosestream << "Server: Got TOSERVER_INIT from " << addr_s << + " (peer_id=" << peer_id << ")" << std::endl; + + // Do not allow multiple players in simple singleplayer mode. + // This isn't a perfect way to do it, but will suffice for now + if (m_simple_singleplayer_mode && !m_clients.getClientIDs().empty()) { + infostream << "Server: Not allowing another client (" << addr_s << + ") to connect in simple singleplayer mode" << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_SINGLEPLAYER); + return; + } + + // First byte after command is maximum supported + // serialization version + u8 client_max; + u16 supp_compr_modes; + u16 min_net_proto_version = 0; + u16 max_net_proto_version; + std::string playerName; + + *pkt >> client_max >> supp_compr_modes >> min_net_proto_version + >> max_net_proto_version >> playerName; + + u8 our_max = SER_FMT_VER_HIGHEST_READ; + // Use the highest version supported by both + u8 depl_serial_v = std::min(client_max, our_max); + // If it's lower than the lowest supported, give up. +#if SER_FMT_VER_LOWEST_READ > 0 + if (depl_serial_v < SER_FMT_VER_LOWEST_READ) + depl_serial_v = SER_FMT_VER_INVALID; +#endif + + if (depl_serial_v == SER_FMT_VER_INVALID) { + actionstream << "Server: A mismatched client tried to connect from " << + addr_s << " ser_fmt_max=" << (int)client_max << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_WRONG_VERSION); + return; + } + + client->setPendingSerializationVersion(depl_serial_v); + + /* + Read and check network protocol version + */ + + u16 net_proto_version = 0; + + // Figure out a working version if it is possible at all + if (max_net_proto_version >= SERVER_PROTOCOL_VERSION_MIN || + min_net_proto_version <= SERVER_PROTOCOL_VERSION_MAX) { + // If maximum is larger than our maximum, go with our maximum + if (max_net_proto_version > SERVER_PROTOCOL_VERSION_MAX) + net_proto_version = SERVER_PROTOCOL_VERSION_MAX; + // Else go with client's maximum + else + net_proto_version = max_net_proto_version; + } + + verbosestream << "Server: " << addr_s << ": Protocol version: min: " + << min_net_proto_version << ", max: " << max_net_proto_version + << ", chosen: " << net_proto_version << std::endl; + + client->net_proto_version = net_proto_version; + + if ((g_settings->getBool("strict_protocol_version_checking") && + net_proto_version != LATEST_PROTOCOL_VERSION) || + net_proto_version < SERVER_PROTOCOL_VERSION_MIN || + net_proto_version > SERVER_PROTOCOL_VERSION_MAX) { + actionstream << "Server: A mismatched client tried to connect from " << + addr_s << " proto_max=" << (int)max_net_proto_version << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_WRONG_VERSION); + return; + } + + /* + Validate player name + */ + const char* playername = playerName.c_str(); + + size_t pns = playerName.size(); + if (pns == 0 || pns > PLAYERNAME_SIZE) { + actionstream << "Server: Player with " << + ((pns > PLAYERNAME_SIZE) ? "a too long" : "an empty") << + " name tried to connect from " << addr_s << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_WRONG_NAME); + return; + } + + if (!string_allowed(playerName, PLAYERNAME_ALLOWED_CHARS)) { + actionstream << "Server: Player with an invalid name tried to connect " + "from " << addr_s << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_WRONG_CHARS_IN_NAME); + return; + } + + RemotePlayer *player = m_env->getPlayer(playername); + + // If player is already connected, cancel + if (player && player->getPeerId() != PEER_ID_INEXISTENT) { + actionstream << "Server: Player with name \"" << playername << + "\" tried to connect, but player with same name is already connected" << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_ALREADY_CONNECTED); + return; + } + + m_clients.setPlayerName(peer_id, playername); + //TODO (later) case insensitivity + + std::string legacyPlayerNameCasing = playerName; + + if (!isSingleplayer() && strcasecmp(playername, "singleplayer") == 0) { + actionstream << "Server: Player with the name \"singleplayer\" tried " + "to connect from " << addr_s << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_WRONG_NAME); + return; + } + + { + std::string reason; + if (m_script->on_prejoinplayer(playername, addr_s, &reason)) { + actionstream << "Server: Player with the name \"" << playerName << + "\" tried to connect from " << addr_s << + " but it was disallowed for the following reason: " << reason << + std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_CUSTOM_STRING, reason); + return; + } + } + + infostream << "Server: New connection: \"" << playerName << "\" from " << + addr_s << " (peer_id=" << peer_id << ")" << std::endl; + + // Enforce user limit. + // Don't enforce for users that have some admin right or mod permits it. + if (m_clients.isUserLimitReached() && + playername != g_settings->get("name") && + !m_script->can_bypass_userlimit(playername, addr_s)) { + actionstream << "Server: " << playername << " tried to join from " << + addr_s << ", but there are already max_users=" << + g_settings->getU16("max_users") << " players." << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_TOO_MANY_USERS); + return; + } + + /* + Compose auth methods for answer + */ + std::string encpwd; // encrypted Password field for the user + bool has_auth = m_script->getAuth(playername, &encpwd, nullptr); + u32 auth_mechs = 0; + + client->chosen_mech = AUTH_MECHANISM_NONE; + + if (has_auth) { + std::vector<std::string> pwd_components = str_split(encpwd, '#'); + if (pwd_components.size() == 4) { + if (pwd_components[1] == "1") { // 1 means srp + auth_mechs |= AUTH_MECHANISM_SRP; + client->enc_pwd = encpwd; + } else { + actionstream << "User " << playername << " tried to log in, " + "but password field was invalid (unknown mechcode)." << + std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_SERVER_FAIL); + return; + } + } else if (base64_is_valid(encpwd)) { + auth_mechs |= AUTH_MECHANISM_LEGACY_PASSWORD; + client->enc_pwd = encpwd; + } else { + actionstream << "User " << playername << " tried to log in, but " + "password field was invalid (invalid base64)." << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_SERVER_FAIL); + return; + } + } else { + std::string default_password = g_settings->get("default_password"); + if (default_password.length() == 0) { + auth_mechs |= AUTH_MECHANISM_FIRST_SRP; + } else { + // Take care of default passwords. + client->enc_pwd = get_encoded_srp_verifier(playerName, default_password); + auth_mechs |= AUTH_MECHANISM_SRP; + // Allocate player in db, but only on successful login. + client->create_player_on_auth_success = true; + } + } + + /* + Answer with a TOCLIENT_HELLO + */ + + verbosestream << "Sending TOCLIENT_HELLO with auth method field: " + << auth_mechs << std::endl; + + NetworkPacket resp_pkt(TOCLIENT_HELLO, + 1 + 4 + legacyPlayerNameCasing.size(), peer_id); + + u16 depl_compress_mode = NETPROTO_COMPRESSION_NONE; + resp_pkt << depl_serial_v << depl_compress_mode << net_proto_version + << auth_mechs << legacyPlayerNameCasing; + + Send(&resp_pkt); + + client->allowed_auth_mechs = auth_mechs; + client->setDeployedCompressionMode(depl_compress_mode); + + m_clients.event(peer_id, CSE_Hello); +} + +void Server::handleCommand_Init2(NetworkPacket* pkt) +{ + session_t peer_id = pkt->getPeerId(); + verbosestream << "Server: Got TOSERVER_INIT2 from " << peer_id << std::endl; + + m_clients.event(peer_id, CSE_GotInit2); + u16 protocol_version = m_clients.getProtocolVersion(peer_id); + + std::string lang; + if (pkt->getSize() > 0) + *pkt >> lang; + + /* + Send some initialization data + */ + + infostream << "Server: Sending content to " << getPlayerName(peer_id) << + std::endl; + + // Send item definitions + SendItemDef(peer_id, m_itemdef, protocol_version); + + // Send node definitions + SendNodeDef(peer_id, m_nodedef, protocol_version); + + m_clients.event(peer_id, CSE_SetDefinitionsSent); + + // Send media announcement + sendMediaAnnouncement(peer_id, lang); + + RemoteClient *client = getClient(peer_id, CS_InitDone); + + // Keep client language for server translations + client->setLangCode(lang); + + // Send active objects + { + PlayerSAO *sao = getPlayerSAO(peer_id); + if (sao) + SendActiveObjectRemoveAdd(client, sao); + } + + // Send detached inventories + sendDetachedInventories(peer_id, false); + + // Send player movement settings + SendMovement(peer_id); + + // Send time of day + u16 time = m_env->getTimeOfDay(); + float time_speed = g_settings->getFloat("time_speed"); + SendTimeOfDay(peer_id, time, time_speed); + + SendCSMRestrictionFlags(peer_id); + + // Warnings about protocol version can be issued here + if (client->net_proto_version < LATEST_PROTOCOL_VERSION) { + SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_SYSTEM, + L"# Server: WARNING: YOUR CLIENT'S VERSION MAY NOT BE FULLY COMPATIBLE " + L"WITH THIS SERVER!")); + } +} + +void Server::handleCommand_RequestMedia(NetworkPacket* pkt) +{ + std::vector<std::string> tosend; + u16 numfiles; + + *pkt >> numfiles; + + session_t peer_id = pkt->getPeerId(); + infostream << "Sending " << numfiles << " files to " << + getPlayerName(peer_id) << std::endl; + verbosestream << "TOSERVER_REQUEST_MEDIA: requested file(s)" << std::endl; + + for (u16 i = 0; i < numfiles; i++) { + std::string name; + + *pkt >> name; + + tosend.emplace_back(name); + verbosestream << " " << name << std::endl; + } + + sendRequestedMedia(peer_id, tosend); +} + +void Server::handleCommand_ClientReady(NetworkPacket* pkt) +{ + session_t peer_id = pkt->getPeerId(); + + // decode all information first + u8 major_ver, minor_ver, patch_ver, reserved; + u16 formspec_ver = 1; // v1 for clients older than 5.1.0-dev + std::string full_ver; + + *pkt >> major_ver >> minor_ver >> patch_ver >> reserved >> full_ver; + if (pkt->getRemainingBytes() >= 2) + *pkt >> formspec_ver; + + m_clients.setClientVersion(peer_id, major_ver, minor_ver, patch_ver, + full_ver); + + // Emerge player + PlayerSAO* playersao = StageTwoClientInit(peer_id); + if (!playersao) { + errorstream << "Server: stage 2 client init failed " + "peer_id=" << peer_id << std::endl; + DisconnectPeer(peer_id); + return; + } + + playersao->getPlayer()->formspec_version = formspec_ver; + m_clients.event(peer_id, CSE_SetClientReady); + + // Send player list to this client + { + const std::vector<std::string> &players = m_clients.getPlayerNames(); + NetworkPacket list_pkt(TOCLIENT_UPDATE_PLAYER_LIST, 0, peer_id); + list_pkt << (u8) PLAYER_LIST_INIT << (u16) players.size(); + for (const auto &player : players) + list_pkt << player; + Send(peer_id, &list_pkt); + } + + s64 last_login; + m_script->getAuth(playersao->getPlayer()->getName(), nullptr, nullptr, &last_login); + m_script->on_joinplayer(playersao, last_login); + + // Send shutdown timer if shutdown has been scheduled + if (m_shutdown_state.isTimerRunning()) + SendChatMessage(peer_id, m_shutdown_state.getShutdownTimerMessage()); +} + +void Server::handleCommand_GotBlocks(NetworkPacket* pkt) +{ + if (pkt->getSize() < 1) + return; + + /* + [0] u16 command + [2] u8 count + [3] v3s16 pos_0 + [3+6] v3s16 pos_1 + ... + */ + + u8 count; + *pkt >> count; + + if ((s16)pkt->getSize() < 1 + (int)count * 6) { + throw con::InvalidIncomingDataException + ("GOTBLOCKS length is too short"); + } + + ClientInterface::AutoLock lock(m_clients); + RemoteClient *client = m_clients.lockedGetClientNoEx(pkt->getPeerId()); + + for (u16 i = 0; i < count; i++) { + v3s16 p; + *pkt >> p; + client->GotBlock(p); + } +} + +void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, + NetworkPacket *pkt) +{ + if (pkt->getRemainingBytes() < 12 + 12 + 4 + 4 + 4 + 1 + 1) + return; + + v3s32 ps, ss; + s32 f32pitch, f32yaw; + u8 f32fov; + + *pkt >> ps; + *pkt >> ss; + *pkt >> f32pitch; + *pkt >> f32yaw; + + f32 pitch = (f32)f32pitch / 100.0f; + f32 yaw = (f32)f32yaw / 100.0f; + u32 keyPressed = 0; + + f32 fov = 0; + u8 wanted_range = 0; + + *pkt >> keyPressed; + *pkt >> f32fov; + fov = (f32)f32fov / 80.0f; + *pkt >> wanted_range; + + v3f position((f32)ps.X / 100.0f, (f32)ps.Y / 100.0f, (f32)ps.Z / 100.0f); + v3f speed((f32)ss.X / 100.0f, (f32)ss.Y / 100.0f, (f32)ss.Z / 100.0f); + + pitch = modulo360f(pitch); + yaw = wrapDegrees_0_360(yaw); + + if (!playersao->isAttached()) { + // Only update player positions when moving freely + // to not interfere with attachment handling + playersao->setBasePosition(position); + player->setSpeed(speed); + } + playersao->setLookPitch(pitch); + playersao->setPlayerYaw(yaw); + playersao->setFov(fov); + playersao->setWantedRange(wanted_range); + + player->control.unpackKeysPressed(keyPressed); + + if (playersao->checkMovementCheat()) { + // Call callbacks + m_script->on_cheat(playersao, "moved_too_fast"); + SendMovePlayer(pkt->getPeerId()); + } +} + +void Server::handleCommand_PlayerPos(NetworkPacket* pkt) +{ + session_t peer_id = pkt->getPeerId(); + RemotePlayer *player = m_env->getPlayer(peer_id); + if (player == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + PlayerSAO *playersao = player->getPlayerSAO(); + if (playersao == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player object for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + // If player is dead we don't care of this packet + if (playersao->isDead()) { + verbosestream << "TOSERVER_PLAYERPOS: " << player->getName() + << " is dead. Ignoring packet"; + return; + } + + process_PlayerPos(player, playersao, pkt); +} + +void Server::handleCommand_DeletedBlocks(NetworkPacket* pkt) +{ + if (pkt->getSize() < 1) + return; + + /* + [0] u16 command + [2] u8 count + [3] v3s16 pos_0 + [3+6] v3s16 pos_1 + ... + */ + + u8 count; + *pkt >> count; + + RemoteClient *client = getClient(pkt->getPeerId()); + + if ((s16)pkt->getSize() < 1 + (int)count * 6) { + throw con::InvalidIncomingDataException + ("DELETEDBLOCKS length is too short"); + } + + for (u16 i = 0; i < count; i++) { + v3s16 p; + *pkt >> p; + client->SetBlockNotSent(p); + } +} + +void Server::handleCommand_InventoryAction(NetworkPacket* pkt) +{ + session_t peer_id = pkt->getPeerId(); + RemotePlayer *player = m_env->getPlayer(peer_id); + + if (player == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + PlayerSAO *playersao = player->getPlayerSAO(); + if (playersao == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player object for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + // Strip command and create a stream + std::string datastring(pkt->getString(0), pkt->getSize()); + verbosestream << "TOSERVER_INVENTORY_ACTION: data=" << datastring + << std::endl; + std::istringstream is(datastring, std::ios_base::binary); + // Create an action + std::unique_ptr<InventoryAction> a(InventoryAction::deSerialize(is)); + if (!a) { + infostream << "TOSERVER_INVENTORY_ACTION: " + << "InventoryAction::deSerialize() returned NULL" + << std::endl; + return; + } + + // If something goes wrong, this player is to blame + RollbackScopeActor rollback_scope(m_rollback, + std::string("player:")+player->getName()); + + /* + Note: Always set inventory not sent, to repair cases + where the client made a bad prediction. + */ + + const bool player_has_interact = checkPriv(player->getName(), "interact"); + + auto check_inv_access = [player, player_has_interact, this] ( + const InventoryLocation &loc) -> bool { + + // Players without interact may modify their own inventory + if (!player_has_interact && loc.type != InventoryLocation::PLAYER) { + infostream << "Cannot modify foreign inventory: " + << "No interact privilege" << std::endl; + return false; + } + + switch (loc.type) { + case InventoryLocation::CURRENT_PLAYER: + // Only used internally on the client, never sent + return false; + case InventoryLocation::PLAYER: + // Allow access to own inventory in all cases + return loc.name == player->getName(); + case InventoryLocation::NODEMETA: + { + // Check for out-of-range interaction + v3f node_pos = intToFloat(loc.p, BS); + v3f player_pos = player->getPlayerSAO()->getEyePosition(); + f32 d = player_pos.getDistanceFrom(node_pos); + return checkInteractDistance(player, d, "inventory"); + } + case InventoryLocation::DETACHED: + return getInventoryMgr()->checkDetachedInventoryAccess(loc, player->getName()); + default: + return false; + } + }; + + /* + Handle restrictions and special cases of the move action + */ + if (a->getType() == IAction::Move) { + IMoveAction *ma = (IMoveAction*)a.get(); + + ma->from_inv.applyCurrentPlayer(player->getName()); + ma->to_inv.applyCurrentPlayer(player->getName()); + + m_inventory_mgr->setInventoryModified(ma->from_inv); + if (ma->from_inv != ma->to_inv) + m_inventory_mgr->setInventoryModified(ma->to_inv); + + if (!check_inv_access(ma->from_inv) || + !check_inv_access(ma->to_inv)) + return; + + /* + Disable moving items out of craftpreview + */ + if (ma->from_list == "craftpreview") { + infostream << "Ignoring IMoveAction from " + << (ma->from_inv.dump()) << ":" << ma->from_list + << " to " << (ma->to_inv.dump()) << ":" << ma->to_list + << " because src is " << ma->from_list << std::endl; + return; + } + + /* + Disable moving items into craftresult and craftpreview + */ + if (ma->to_list == "craftpreview" || ma->to_list == "craftresult") { + infostream << "Ignoring IMoveAction from " + << (ma->from_inv.dump()) << ":" << ma->from_list + << " to " << (ma->to_inv.dump()) << ":" << ma->to_list + << " because dst is " << ma->to_list << std::endl; + return; + } + } + /* + Handle restrictions and special cases of the drop action + */ + else if (a->getType() == IAction::Drop) { + IDropAction *da = (IDropAction*)a.get(); + + da->from_inv.applyCurrentPlayer(player->getName()); + + m_inventory_mgr->setInventoryModified(da->from_inv); + + /* + Disable dropping items out of craftpreview + */ + if (da->from_list == "craftpreview") { + infostream << "Ignoring IDropAction from " + << (da->from_inv.dump()) << ":" << da->from_list + << " because src is " << da->from_list << std::endl; + return; + } + + // Disallow dropping items if not allowed to interact + if (!player_has_interact || !check_inv_access(da->from_inv)) + return; + + // Disallow dropping items if dead + if (playersao->isDead()) { + infostream << "Ignoring IDropAction from " + << (da->from_inv.dump()) << ":" << da->from_list + << " because player is dead." << std::endl; + return; + } + } + /* + Handle restrictions and special cases of the craft action + */ + else if (a->getType() == IAction::Craft) { + ICraftAction *ca = (ICraftAction*)a.get(); + + ca->craft_inv.applyCurrentPlayer(player->getName()); + + m_inventory_mgr->setInventoryModified(ca->craft_inv); + + // Disallow crafting if not allowed to interact + if (!player_has_interact) { + infostream << "Cannot craft: " + << "No interact privilege" << std::endl; + return; + } + + if (!check_inv_access(ca->craft_inv)) + return; + } else { + // Unknown action. Ignored. + return; + } + + // Do the action + a->apply(m_inventory_mgr.get(), playersao, this); +} + +void Server::handleCommand_ChatMessage(NetworkPacket* pkt) +{ + std::wstring message; + *pkt >> message; + + session_t peer_id = pkt->getPeerId(); + RemotePlayer *player = m_env->getPlayer(peer_id); + if (player == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + std::string name = player->getName(); + + std::wstring answer_to_sender = handleChat(name, message, true, player); + if (!answer_to_sender.empty()) { + // Send the answer to sender + SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_SYSTEM, + answer_to_sender)); + } +} + +void Server::handleCommand_Damage(NetworkPacket* pkt) +{ + u16 damage; + + *pkt >> damage; + + session_t peer_id = pkt->getPeerId(); + RemotePlayer *player = m_env->getPlayer(peer_id); + + if (player == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + PlayerSAO *playersao = player->getPlayerSAO(); + if (playersao == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player object for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + if (!playersao->isImmortal()) { + if (playersao->isDead()) { + verbosestream << "Server::ProcessData(): Info: " + "Ignoring damage as player " << player->getName() + << " is already dead." << std::endl; + return; + } + + actionstream << player->getName() << " damaged by " + << (int)damage << " hp at " << PP(playersao->getBasePosition() / BS) + << std::endl; + + PlayerHPChangeReason reason(PlayerHPChangeReason::FALL); + playersao->setHP((s32)playersao->getHP() - (s32)damage, reason, true); + } +} + +void Server::handleCommand_PlayerItem(NetworkPacket* pkt) +{ + if (pkt->getSize() < 2) + return; + + session_t peer_id = pkt->getPeerId(); + RemotePlayer *player = m_env->getPlayer(peer_id); + + if (player == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + PlayerSAO *playersao = player->getPlayerSAO(); + if (playersao == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player object for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + u16 item; + + *pkt >> item; + + if (item >= player->getHotbarItemcount()) { + actionstream << "Player: " << player->getName() + << " tried to access item=" << item + << " out of hotbar_itemcount=" + << player->getHotbarItemcount() + << "; ignoring." << std::endl; + return; + } + + playersao->getPlayer()->setWieldIndex(item); +} + +void Server::handleCommand_Respawn(NetworkPacket* pkt) +{ + session_t peer_id = pkt->getPeerId(); + RemotePlayer *player = m_env->getPlayer(peer_id); + if (player == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + PlayerSAO *playersao = player->getPlayerSAO(); + assert(playersao); + + if (!playersao->isDead()) + return; + + RespawnPlayer(peer_id); + + actionstream << player->getName() << " respawns at " + << PP(playersao->getBasePosition() / BS) << std::endl; + + // ActiveObject is added to environment in AsyncRunStep after + // the previous addition has been successfully removed +} + +bool Server::checkInteractDistance(RemotePlayer *player, const f32 d, const std::string &what) +{ + ItemStack selected_item, hand_item; + player->getWieldedItem(&selected_item, &hand_item); + f32 max_d = BS * getToolRange(selected_item.getDefinition(m_itemdef), + hand_item.getDefinition(m_itemdef)); + + // Cube diagonal * 1.5 for maximal supported node extents: + // sqrt(3) * 1.5 ≅ 2.6 + if (d > max_d + 2.6f * BS) { + actionstream << "Player " << player->getName() + << " tried to access " << what + << " from too far: " + << "d=" << d << ", max_d=" << max_d + << "; ignoring." << std::endl; + // Call callbacks + m_script->on_cheat(player->getPlayerSAO(), "interacted_too_far"); + return false; + } + return true; +} + +// Tiny helper to retrieve the selected item into an Optional +static inline void getWieldedItem(const PlayerSAO *playersao, Optional<ItemStack> &ret) +{ + ret = ItemStack(); + playersao->getWieldedItem(&(*ret)); +} + +void Server::handleCommand_Interact(NetworkPacket *pkt) +{ + /* + [0] u16 command + [2] u8 action + [3] u16 item + [5] u32 length of the next item (plen) + [9] serialized PointedThing + [9 + plen] player position information + */ + + InteractAction action; + u16 item_i; + + *pkt >> (u8 &)action; + *pkt >> item_i; + + std::istringstream tmp_is(pkt->readLongString(), std::ios::binary); + PointedThing pointed; + pointed.deSerialize(tmp_is); + + verbosestream << "TOSERVER_INTERACT: action=" << (int)action << ", item=" + << item_i << ", pointed=" << pointed.dump() << std::endl; + + session_t peer_id = pkt->getPeerId(); + RemotePlayer *player = m_env->getPlayer(peer_id); + + if (player == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + PlayerSAO *playersao = player->getPlayerSAO(); + if (playersao == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player object for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + if (playersao->isDead()) { + actionstream << "Server: " << player->getName() + << " tried to interact while dead; ignoring." << std::endl; + if (pointed.type == POINTEDTHING_NODE) { + // Re-send block to revert change on client-side + RemoteClient *client = getClient(peer_id); + v3s16 blockpos = getNodeBlockPos(pointed.node_undersurface); + client->SetBlockNotSent(blockpos); + } + // Call callbacks + m_script->on_cheat(playersao, "interacted_while_dead"); + return; + } + + process_PlayerPos(player, playersao, pkt); + + v3f player_pos = playersao->getLastGoodPosition(); + + // Update wielded item + + if (item_i >= player->getHotbarItemcount()) { + actionstream << "Player: " << player->getName() + << " tried to access item=" << item_i + << " out of hotbar_itemcount=" + << player->getHotbarItemcount() + << "; ignoring." << std::endl; + return; + } + + playersao->getPlayer()->setWieldIndex(item_i); + + // Get pointed to object (NULL if not POINTEDTYPE_OBJECT) + ServerActiveObject *pointed_object = NULL; + if (pointed.type == POINTEDTHING_OBJECT) { + pointed_object = m_env->getActiveObject(pointed.object_id); + if (pointed_object == NULL) { + verbosestream << "TOSERVER_INTERACT: " + "pointed object is NULL" << std::endl; + return; + } + + } + + /* + Make sure the player is allowed to do it + */ + if (!checkPriv(player->getName(), "interact")) { + actionstream << player->getName() << " attempted to interact with " << + pointed.dump() << " without 'interact' privilege" << std::endl; + + if (pointed.type != POINTEDTHING_NODE) + return; + + // Re-send block to revert change on client-side + RemoteClient *client = getClient(peer_id); + // Digging completed -> under + if (action == INTERACT_DIGGING_COMPLETED) { + v3s16 blockpos = getNodeBlockPos(pointed.node_undersurface); + client->SetBlockNotSent(blockpos); + } + // Placement -> above + else if (action == INTERACT_PLACE) { + v3s16 blockpos = getNodeBlockPos(pointed.node_abovesurface); + client->SetBlockNotSent(blockpos); + } + return; + } + + /* + Check that target is reasonably close + */ + static thread_local const bool enable_anticheat = + !g_settings->getBool("disable_anticheat"); + + if ((action == INTERACT_START_DIGGING || action == INTERACT_DIGGING_COMPLETED || + action == INTERACT_PLACE || action == INTERACT_USE) && + enable_anticheat && !isSingleplayer()) { + v3f target_pos = player_pos; + if (pointed.type == POINTEDTHING_NODE) { + target_pos = intToFloat(pointed.node_undersurface, BS); + } else if (pointed.type == POINTEDTHING_OBJECT) { + if (playersao->getId() == pointed_object->getId()) { + actionstream << "Server: " << player->getName() + << " attempted to interact with themselves" << std::endl; + m_script->on_cheat(playersao, "interacted_with_self"); + return; + } + target_pos = pointed_object->getBasePosition(); + } + float d = playersao->getEyePosition().getDistanceFrom(target_pos); + + if (!checkInteractDistance(player, d, pointed.dump())) { + if (pointed.type == POINTEDTHING_NODE) { + // Re-send block to revert change on client-side + RemoteClient *client = getClient(peer_id); + v3s16 blockpos = getNodeBlockPos(pointed.node_undersurface); + client->SetBlockNotSent(blockpos); + } + return; + } + } + + /* + If something goes wrong, this player is to blame + */ + RollbackScopeActor rollback_scope(m_rollback, + std::string("player:")+player->getName()); + + switch (action) { + // Start digging or punch object + case INTERACT_START_DIGGING: { + if (pointed.type == POINTEDTHING_NODE) { + MapNode n(CONTENT_IGNORE); + bool pos_ok; + + v3s16 p_under = pointed.node_undersurface; + n = m_env->getMap().getNode(p_under, &pos_ok); + if (!pos_ok) { + infostream << "Server: Not punching: Node not found. " + "Adding block to emerge queue." << std::endl; + m_emerge->enqueueBlockEmerge(peer_id, + getNodeBlockPos(pointed.node_abovesurface), false); + } + + if (n.getContent() != CONTENT_IGNORE) + m_script->node_on_punch(p_under, n, playersao, pointed); + + // Cheat prevention + playersao->noCheatDigStart(p_under); + + return; + } + + // Skip if the object can't be interacted with anymore + if (pointed.type != POINTEDTHING_OBJECT || pointed_object->isGone()) + return; + + ItemStack selected_item, hand_item; + ItemStack tool_item = playersao->getWieldedItem(&selected_item, &hand_item); + ToolCapabilities toolcap = + tool_item.getToolCapabilities(m_itemdef); + v3f dir = (pointed_object->getBasePosition() - + (playersao->getBasePosition() + playersao->getEyeOffset()) + ).normalize(); + float time_from_last_punch = + playersao->resetTimeFromLastPunch(); + + u32 wear = pointed_object->punch(dir, &toolcap, playersao, + time_from_last_punch, tool_item.wear); + + // Callback may have changed item, so get it again + playersao->getWieldedItem(&selected_item); + bool changed = selected_item.addWear(wear, m_itemdef); + if (changed) + playersao->setWieldedItem(selected_item); + + return; + } // action == INTERACT_START_DIGGING + + case INTERACT_STOP_DIGGING: + // Nothing to do + return; + + case INTERACT_DIGGING_COMPLETED: { + // Only digging of nodes + if (pointed.type != POINTEDTHING_NODE) + return; + bool pos_ok; + v3s16 p_under = pointed.node_undersurface; + MapNode n = m_env->getMap().getNode(p_under, &pos_ok); + if (!pos_ok) { + infostream << "Server: Not finishing digging: Node not found. " + "Adding block to emerge queue." << std::endl; + m_emerge->enqueueBlockEmerge(peer_id, + getNodeBlockPos(pointed.node_abovesurface), false); + } + + /* Cheat prevention */ + bool is_valid_dig = true; + if (enable_anticheat && !isSingleplayer()) { + v3s16 nocheat_p = playersao->getNoCheatDigPos(); + float nocheat_t = playersao->getNoCheatDigTime(); + playersao->noCheatDigEnd(); + // If player didn't start digging this, ignore dig + if (nocheat_p != p_under) { + infostream << "Server: " << player->getName() + << " started digging " + << PP(nocheat_p) << " and completed digging " + << PP(p_under) << "; not digging." << std::endl; + is_valid_dig = false; + // Call callbacks + m_script->on_cheat(playersao, "finished_unknown_dig"); + } + + // Get player's wielded item + // See also: Game::handleDigging + ItemStack selected_item, hand_item; + playersao->getPlayer()->getWieldedItem(&selected_item, &hand_item); + + // Get diggability and expected digging time + DigParams params = getDigParams(m_nodedef->get(n).groups, + &selected_item.getToolCapabilities(m_itemdef), + selected_item.wear); + // If can't dig, try hand + if (!params.diggable) { + params = getDigParams(m_nodedef->get(n).groups, + &hand_item.getToolCapabilities(m_itemdef)); + } + // If can't dig, ignore dig + if (!params.diggable) { + infostream << "Server: " << player->getName() + << " completed digging " << PP(p_under) + << ", which is not diggable with tool; not digging." + << std::endl; + is_valid_dig = false; + // Call callbacks + m_script->on_cheat(playersao, "dug_unbreakable"); + } + // Check digging time + // If already invalidated, we don't have to + if (!is_valid_dig) { + // Well not our problem then + } + // Clean and long dig + else if (params.time > 2.0 && nocheat_t * 1.2 > params.time) { + // All is good, but grab time from pool; don't care if + // it's actually available + playersao->getDigPool().grab(params.time); + } + // Short or laggy dig + // Try getting the time from pool + else if (playersao->getDigPool().grab(params.time)) { + // All is good + } + // Dig not possible + else { + infostream << "Server: " << player->getName() + << " completed digging " << PP(p_under) + << "too fast; not digging." << std::endl; + is_valid_dig = false; + // Call callbacks + m_script->on_cheat(playersao, "dug_too_fast"); + } + } + + /* Actually dig node */ + + if (is_valid_dig && n.getContent() != CONTENT_IGNORE) + m_script->node_on_dig(p_under, n, playersao); + + v3s16 blockpos = getNodeBlockPos(p_under); + RemoteClient *client = getClient(peer_id); + // Send unusual result (that is, node not being removed) + if (m_env->getMap().getNode(p_under).getContent() != CONTENT_AIR) + // Re-send block to revert change on client-side + client->SetBlockNotSent(blockpos); + else + client->ResendBlockIfOnWire(blockpos); + + return; + } // action == INTERACT_DIGGING_COMPLETED + + // Place block or right-click object + case INTERACT_PLACE: { + Optional<ItemStack> selected_item; + getWieldedItem(playersao, selected_item); + + // Reset build time counter + if (pointed.type == POINTEDTHING_NODE && + selected_item->getDefinition(m_itemdef).type == ITEM_NODE) + getClient(peer_id)->m_time_from_building = 0.0; + + const bool had_prediction = !selected_item->getDefinition(m_itemdef). + node_placement_prediction.empty(); + + if (pointed.type == POINTEDTHING_OBJECT) { + // Right click object + + // Skip if object can't be interacted with anymore + if (pointed_object->isGone()) + return; + + actionstream << player->getName() << " right-clicks object " + << pointed.object_id << ": " + << pointed_object->getDescription() << std::endl; + + // Do stuff + if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) { + if (selected_item.has_value() && playersao->setWieldedItem(*selected_item)) + SendInventory(playersao, true); + } + + pointed_object->rightClick(playersao); + } else if (m_script->item_OnPlace(selected_item, playersao, pointed)) { + // Placement was handled in lua + + // Apply returned ItemStack + if (selected_item.has_value() && playersao->setWieldedItem(*selected_item)) + SendInventory(playersao, true); + } + + if (pointed.type != POINTEDTHING_NODE) + return; + + // If item has node placement prediction, always send the + // blocks to make sure the client knows what exactly happened + RemoteClient *client = getClient(peer_id); + v3s16 blockpos = getNodeBlockPos(pointed.node_abovesurface); + v3s16 blockpos2 = getNodeBlockPos(pointed.node_undersurface); + if (had_prediction) { + client->SetBlockNotSent(blockpos); + if (blockpos2 != blockpos) + client->SetBlockNotSent(blockpos2); + } else { + client->ResendBlockIfOnWire(blockpos); + if (blockpos2 != blockpos) + client->ResendBlockIfOnWire(blockpos2); + } + + return; + } // action == INTERACT_PLACE + + case INTERACT_USE: { + Optional<ItemStack> selected_item; + getWieldedItem(playersao, selected_item); + + actionstream << player->getName() << " uses " << selected_item->name + << ", pointing at " << pointed.dump() << std::endl; + + if (m_script->item_OnUse(selected_item, playersao, pointed)) { + // Apply returned ItemStack + if (selected_item.has_value() && playersao->setWieldedItem(*selected_item)) + SendInventory(playersao, true); + } + + return; + } + + // Rightclick air + case INTERACT_ACTIVATE: { + Optional<ItemStack> selected_item; + getWieldedItem(playersao, selected_item); + + actionstream << player->getName() << " activates " + << selected_item->name << std::endl; + + pointed.type = POINTEDTHING_NOTHING; // can only ever be NOTHING + + if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) { + // Apply returned ItemStack + if (selected_item.has_value() && playersao->setWieldedItem(*selected_item)) + SendInventory(playersao, true); + } + + return; + } + + default: + warningstream << "Server: Invalid action " << action << std::endl; + + } +} + +void Server::handleCommand_RemovedSounds(NetworkPacket* pkt) +{ + u16 num; + *pkt >> num; + for (u16 k = 0; k < num; k++) { + s32 id; + + *pkt >> id; + + std::unordered_map<s32, ServerPlayingSound>::iterator i = + m_playing_sounds.find(id); + if (i == m_playing_sounds.end()) + continue; + + ServerPlayingSound &psound = i->second; + psound.clients.erase(pkt->getPeerId()); + if (psound.clients.empty()) + m_playing_sounds.erase(i++); + } +} + +void Server::handleCommand_NodeMetaFields(NetworkPacket* pkt) +{ + v3s16 p; + std::string formname; + u16 num; + + *pkt >> p >> formname >> num; + + StringMap fields; + for (u16 k = 0; k < num; k++) { + std::string fieldname; + *pkt >> fieldname; + fields[fieldname] = pkt->readLongString(); + } + + session_t peer_id = pkt->getPeerId(); + RemotePlayer *player = m_env->getPlayer(peer_id); + + if (player == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + PlayerSAO *playersao = player->getPlayerSAO(); + if (playersao == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player object for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + // If something goes wrong, this player is to blame + RollbackScopeActor rollback_scope(m_rollback, + std::string("player:")+player->getName()); + + // Check the target node for rollback data; leave others unnoticed + RollbackNode rn_old(&m_env->getMap(), p, this); + + m_script->node_on_receive_fields(p, formname, fields, playersao); + + // Report rollback data + RollbackNode rn_new(&m_env->getMap(), p, this); + if (rollback() && rn_new != rn_old) { + RollbackAction action; + action.setSetNode(p, rn_old, rn_new); + rollback()->reportAction(action); + } +} + +void Server::handleCommand_InventoryFields(NetworkPacket* pkt) +{ + std::string client_formspec_name; + u16 num; + + *pkt >> client_formspec_name >> num; + + StringMap fields; + for (u16 k = 0; k < num; k++) { + std::string fieldname; + *pkt >> fieldname; + fields[fieldname] = pkt->readLongString(); + } + + session_t peer_id = pkt->getPeerId(); + RemotePlayer *player = m_env->getPlayer(peer_id); + + if (player == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + PlayerSAO *playersao = player->getPlayerSAO(); + if (playersao == NULL) { + errorstream << + "Server::ProcessData(): Canceling: No player object for peer_id=" << + peer_id << " disconnecting peer!" << std::endl; + DisconnectPeer(peer_id); + return; + } + + if (client_formspec_name.empty()) { // pass through inventory submits + m_script->on_playerReceiveFields(playersao, client_formspec_name, fields); + return; + } + + // verify that we displayed the formspec to the user + const auto peer_state_iterator = m_formspec_state_data.find(peer_id); + if (peer_state_iterator != m_formspec_state_data.end()) { + const std::string &server_formspec_name = peer_state_iterator->second; + if (client_formspec_name == server_formspec_name) { + auto it = fields.find("quit"); + if (it != fields.end() && it->second == "true") + m_formspec_state_data.erase(peer_state_iterator); + + m_script->on_playerReceiveFields(playersao, client_formspec_name, fields); + return; + } + actionstream << "'" << player->getName() + << "' submitted formspec ('" << client_formspec_name + << "') but the name of the formspec doesn't match the" + " expected name ('" << server_formspec_name << "')"; + + } else { + actionstream << "'" << player->getName() + << "' submitted formspec ('" << client_formspec_name + << "') but server hasn't sent formspec to client"; + } + actionstream << ", possible exploitation attempt" << std::endl; +} + +void Server::handleCommand_FirstSrp(NetworkPacket* pkt) +{ + session_t peer_id = pkt->getPeerId(); + RemoteClient *client = getClient(peer_id, CS_Invalid); + ClientState cstate = client->getState(); + const std::string playername = client->getName(); + + std::string salt, verification_key; + + std::string addr_s = getPeerAddress(peer_id).serializeString(); + u8 is_empty; + + *pkt >> salt >> verification_key >> is_empty; + + verbosestream << "Server: Got TOSERVER_FIRST_SRP from " << addr_s + << ", with is_empty=" << (is_empty == 1) << std::endl; + + const bool empty_disallowed = !isSingleplayer() && is_empty == 1 && + g_settings->getBool("disallow_empty_password"); + + // Either this packet is sent because the user is new or to change the password + if (cstate == CS_HelloSent) { + if (!client->isMechAllowed(AUTH_MECHANISM_FIRST_SRP)) { + actionstream << "Server: Client from " << addr_s + << " tried to set password without being " + << "authenticated, or the username being new." << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_UNEXPECTED_DATA); + return; + } + + if (empty_disallowed) { + actionstream << "Server: " << playername + << " supplied empty password from " << addr_s << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_EMPTY_PASSWORD); + return; + } + + std::string initial_ver_key; + initial_ver_key = encode_srp_verifier(verification_key, salt); + + // It is possible for multiple connections to get this far with the same + // player name. In the end only one player with a given name will be emerged + // (see Server::StateTwoClientInit) but we still have to be careful here. + if (m_script->getAuth(playername, nullptr, nullptr)) { + // Another client beat us to it + actionstream << "Server: Client from " << addr_s + << " tried to register " << playername << " a second time." + << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_ALREADY_CONNECTED); + return; + } + m_script->createAuth(playername, initial_ver_key); + m_script->on_authplayer(playername, addr_s, true); + + acceptAuth(peer_id, false); + } else { + if (cstate < CS_SudoMode) { + infostream << "Server::ProcessData(): Ignoring TOSERVER_FIRST_SRP from " + << addr_s << ": " << "Client has wrong state " << cstate << "." + << std::endl; + return; + } + m_clients.event(peer_id, CSE_SudoLeave); + + if (empty_disallowed) { + actionstream << "Server: " << playername + << " supplied empty password" << std::endl; + SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_SYSTEM, + L"Changing to an empty password is not allowed.")); + return; + } + + std::string pw_db_field = encode_srp_verifier(verification_key, salt); + bool success = m_script->setPassword(playername, pw_db_field); + if (success) { + actionstream << playername << " changes password" << std::endl; + SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_SYSTEM, + L"Password change successful.")); + } else { + actionstream << playername << + " tries to change password but it fails" << std::endl; + SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_SYSTEM, + L"Password change failed or unavailable.")); + } + } +} + +void Server::handleCommand_SrpBytesA(NetworkPacket* pkt) +{ + session_t peer_id = pkt->getPeerId(); + RemoteClient *client = getClient(peer_id, CS_Invalid); + ClientState cstate = client->getState(); + + if (!((cstate == CS_HelloSent) || (cstate == CS_Active))) { + actionstream << "Server: got SRP _A packet in wrong state " << cstate << + " from " << getPeerAddress(peer_id).serializeString() << + ". Ignoring." << std::endl; + return; + } + + const bool wantSudo = (cstate == CS_Active); + + if (client->chosen_mech != AUTH_MECHANISM_NONE) { + actionstream << "Server: got SRP _A packet, while auth is already " + "going on with mech " << client->chosen_mech << " from " << + getPeerAddress(peer_id).serializeString() << + " (wantSudo=" << wantSudo << "). Ignoring." << std::endl; + if (wantSudo) { + DenySudoAccess(peer_id); + return; + } + + DenyAccess(peer_id, SERVER_ACCESSDENIED_UNEXPECTED_DATA); + return; + } + + std::string bytes_A; + u8 based_on; + *pkt >> bytes_A >> based_on; + + infostream << "Server: TOSERVER_SRP_BYTES_A received with " + << "based_on=" << int(based_on) << " and len_A=" + << bytes_A.length() << "." << std::endl; + + AuthMechanism chosen = (based_on == 0) ? + AUTH_MECHANISM_LEGACY_PASSWORD : AUTH_MECHANISM_SRP; + + if (wantSudo) { + if (!client->isSudoMechAllowed(chosen)) { + actionstream << "Server: Player \"" << client->getName() << + "\" at " << getPeerAddress(peer_id).serializeString() << + " tried to change password using unallowed mech " << chosen << + "." << std::endl; + DenySudoAccess(peer_id); + return; + } + } else { + if (!client->isMechAllowed(chosen)) { + actionstream << "Server: Client tried to authenticate from " << + getPeerAddress(peer_id).serializeString() << + " using unallowed mech " << chosen << "." << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_UNEXPECTED_DATA); + return; + } + } + + client->chosen_mech = chosen; + + std::string salt, verifier; + + if (based_on == 0) { + + generate_srp_verifier_and_salt(client->getName(), client->enc_pwd, + &verifier, &salt); + } else if (!decode_srp_verifier_and_salt(client->enc_pwd, &verifier, &salt)) { + // Non-base64 errors should have been catched in the init handler + actionstream << "Server: User " << client->getName() << + " tried to log in, but srp verifier field was invalid (most likely " + "invalid base64)." << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_SERVER_FAIL); + return; + } + + char *bytes_B = 0; + size_t len_B = 0; + + client->auth_data = srp_verifier_new(SRP_SHA256, SRP_NG_2048, + client->getName().c_str(), + (const unsigned char *) salt.c_str(), salt.size(), + (const unsigned char *) verifier.c_str(), verifier.size(), + (const unsigned char *) bytes_A.c_str(), bytes_A.size(), + NULL, 0, + (unsigned char **) &bytes_B, &len_B, NULL, NULL); + + if (!bytes_B) { + actionstream << "Server: User " << client->getName() + << " tried to log in, SRP-6a safety check violated in _A handler." + << std::endl; + if (wantSudo) { + DenySudoAccess(peer_id); + client->resetChosenMech(); + return; + } + + DenyAccess(peer_id, SERVER_ACCESSDENIED_UNEXPECTED_DATA); + return; + } + + NetworkPacket resp_pkt(TOCLIENT_SRP_BYTES_S_B, 0, peer_id); + resp_pkt << salt << std::string(bytes_B, len_B); + Send(&resp_pkt); +} + +void Server::handleCommand_SrpBytesM(NetworkPacket* pkt) +{ + session_t peer_id = pkt->getPeerId(); + RemoteClient *client = getClient(peer_id, CS_Invalid); + ClientState cstate = client->getState(); + const std::string addr_s = client->getAddress().serializeString(); + const std::string playername = client->getName(); + + const bool wantSudo = (cstate == CS_Active); + + verbosestream << "Server: Received TOSERVER_SRP_BYTES_M." << std::endl; + + if (!((cstate == CS_HelloSent) || (cstate == CS_Active))) { + warningstream << "Server: got SRP_M packet in wrong state " + << cstate << " from " << addr_s << ". Ignoring." << std::endl; + return; + } + + if (client->chosen_mech != AUTH_MECHANISM_SRP && + client->chosen_mech != AUTH_MECHANISM_LEGACY_PASSWORD) { + warningstream << "Server: got SRP_M packet, while auth " + "is going on with mech " << client->chosen_mech << " from " + << addr_s << " (wantSudo=" << wantSudo << "). Denying." << std::endl; + if (wantSudo) { + DenySudoAccess(peer_id); + return; + } + + DenyAccess(peer_id, SERVER_ACCESSDENIED_UNEXPECTED_DATA); + return; + } + + std::string bytes_M; + *pkt >> bytes_M; + + if (srp_verifier_get_session_key_length((SRPVerifier *) client->auth_data) + != bytes_M.size()) { + actionstream << "Server: User " << playername << " at " << addr_s + << " sent bytes_M with invalid length " << bytes_M.size() << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_UNEXPECTED_DATA); + return; + } + + unsigned char *bytes_HAMK = 0; + + srp_verifier_verify_session((SRPVerifier *) client->auth_data, + (unsigned char *)bytes_M.c_str(), &bytes_HAMK); + + if (!bytes_HAMK) { + if (wantSudo) { + actionstream << "Server: User " << playername << " at " << addr_s + << " tried to change their password, but supplied wrong" + << " (SRP) password for authentication." << std::endl; + DenySudoAccess(peer_id); + client->resetChosenMech(); + return; + } + + actionstream << "Server: User " << playername << " at " << addr_s + << " supplied wrong password (auth mechanism: SRP)." << std::endl; + m_script->on_authplayer(playername, addr_s, false); + DenyAccess(peer_id, SERVER_ACCESSDENIED_WRONG_PASSWORD); + return; + } + + if (client->create_player_on_auth_success) { + m_script->createAuth(playername, client->enc_pwd); + + if (!m_script->getAuth(playername, nullptr, nullptr)) { + errorstream << "Server: " << playername << + " cannot be authenticated (auth handler does not work?)" << + std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_SERVER_FAIL); + return; + } + client->create_player_on_auth_success = false; + } + + m_script->on_authplayer(playername, addr_s, true); + acceptAuth(peer_id, wantSudo); +} + +/* + * Mod channels + */ + +void Server::handleCommand_ModChannelJoin(NetworkPacket *pkt) +{ + std::string channel_name; + *pkt >> channel_name; + + session_t peer_id = pkt->getPeerId(); + NetworkPacket resp_pkt(TOCLIENT_MODCHANNEL_SIGNAL, + 1 + 2 + channel_name.size(), peer_id); + + // Send signal to client to notify join succeed or not + if (g_settings->getBool("enable_mod_channels") && + m_modchannel_mgr->joinChannel(channel_name, peer_id)) { + resp_pkt << (u8) MODCHANNEL_SIGNAL_JOIN_OK; + infostream << "Peer " << peer_id << " joined channel " << + channel_name << std::endl; + } + else { + resp_pkt << (u8)MODCHANNEL_SIGNAL_JOIN_FAILURE; + infostream << "Peer " << peer_id << " tried to join channel " << + channel_name << ", but was already registered." << std::endl; + } + resp_pkt << channel_name; + Send(&resp_pkt); +} + +void Server::handleCommand_ModChannelLeave(NetworkPacket *pkt) +{ + std::string channel_name; + *pkt >> channel_name; + + session_t peer_id = pkt->getPeerId(); + NetworkPacket resp_pkt(TOCLIENT_MODCHANNEL_SIGNAL, + 1 + 2 + channel_name.size(), peer_id); + + // Send signal to client to notify join succeed or not + if (g_settings->getBool("enable_mod_channels") && + m_modchannel_mgr->leaveChannel(channel_name, peer_id)) { + resp_pkt << (u8)MODCHANNEL_SIGNAL_LEAVE_OK; + infostream << "Peer " << peer_id << " left channel " << channel_name << + std::endl; + } else { + resp_pkt << (u8) MODCHANNEL_SIGNAL_LEAVE_FAILURE; + infostream << "Peer " << peer_id << " left channel " << channel_name << + ", but was not registered." << std::endl; + } + resp_pkt << channel_name; + Send(&resp_pkt); +} + +void Server::handleCommand_ModChannelMsg(NetworkPacket *pkt) +{ + std::string channel_name, channel_msg; + *pkt >> channel_name >> channel_msg; + + session_t peer_id = pkt->getPeerId(); + verbosestream << "Mod channel message received from peer " << peer_id << + " on channel " << channel_name << " message: " << channel_msg << + std::endl; + + // If mod channels are not enabled, discard message + if (!g_settings->getBool("enable_mod_channels")) { + return; + } + + // If channel not registered, signal it and ignore message + if (!m_modchannel_mgr->channelRegistered(channel_name)) { + NetworkPacket resp_pkt(TOCLIENT_MODCHANNEL_SIGNAL, + 1 + 2 + channel_name.size(), peer_id); + resp_pkt << (u8)MODCHANNEL_SIGNAL_CHANNEL_NOT_REGISTERED << channel_name; + Send(&resp_pkt); + return; + } + + // @TODO: filter, rate limit + + broadcastModChannelMessage(channel_name, channel_msg, peer_id); +} + +void Server::handleCommand_HaveMedia(NetworkPacket *pkt) +{ + std::vector<u32> tokens; + u8 numtokens; + + *pkt >> numtokens; + for (u16 i = 0; i < numtokens; i++) { + u32 n; + *pkt >> n; + tokens.emplace_back(n); + } + + const session_t peer_id = pkt->getPeerId(); + auto player = m_env->getPlayer(peer_id); + + for (const u32 token : tokens) { + auto it = m_pending_dyn_media.find(token); + if (it == m_pending_dyn_media.end()) + continue; + if (it->second.waiting_players.count(peer_id)) { + it->second.waiting_players.erase(peer_id); + if (player) + getScriptIface()->on_dynamic_media_added(token, player->getName()); + } + } +} diff --git a/src/network/socket.cpp b/src/network/socket.cpp new file mode 100644 index 0000000..df15c89 --- /dev/null +++ b/src/network/socket.cpp @@ -0,0 +1,372 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "socket.h" + +#include <cstdio> +#include <iostream> +#include <cstdlib> +#include <cstring> +#include <iomanip> +#include "util/string.h" +#include "util/numeric.h" +#include "constants.h" +#include "debug.h" +#include "log.h" + +#ifdef _WIN32 +// Without this some of the network functions are not found on mingw +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif +#include <windows.h> +#include <winsock2.h> +#include <ws2tcpip.h> +#define LAST_SOCKET_ERR() WSAGetLastError() +#define SOCKET_ERR_STR(e) itos(e) +typedef int socklen_t; +#else +#include <cerrno> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <fcntl.h> +#include <netdb.h> +#include <unistd.h> +#include <arpa/inet.h> +#define LAST_SOCKET_ERR() (errno) +#define SOCKET_ERR_STR(e) strerror(e) +#endif + +// Set to true to enable verbose debug output +bool socket_enable_debug_output = false; // yuck + +static bool g_sockets_initialized = false; + +// Initialize sockets +void sockets_init() +{ +#ifdef _WIN32 + // Windows needs sockets to be initialized before use + WSADATA WsaData; + if (WSAStartup(MAKEWORD(2, 2), &WsaData) != NO_ERROR) + throw SocketException("WSAStartup failed"); +#endif + g_sockets_initialized = true; +} + +void sockets_cleanup() +{ +#ifdef _WIN32 + // On Windows, cleanup sockets after use + WSACleanup(); +#endif +} + +/* + UDPSocket +*/ + +UDPSocket::UDPSocket(bool ipv6) +{ + init(ipv6, false); +} + +bool UDPSocket::init(bool ipv6, bool noExceptions) +{ + if (!g_sockets_initialized) { + dstream << "Sockets not initialized" << std::endl; + return false; + } + + // Use IPv6 if specified + m_addr_family = ipv6 ? AF_INET6 : AF_INET; + m_handle = socket(m_addr_family, SOCK_DGRAM, IPPROTO_UDP); + + if (socket_enable_debug_output) { + dstream << "UDPSocket(" << (int)m_handle + << ")::UDPSocket(): ipv6 = " << (ipv6 ? "true" : "false") + << std::endl; + } + + if (m_handle <= 0) { + if (noExceptions) { + return false; + } + + throw SocketException(std::string("Failed to create socket: error ") + + SOCKET_ERR_STR(LAST_SOCKET_ERR())); + } + + setTimeoutMs(0); + + if (m_addr_family == AF_INET6) { + // Allow our socket to accept both IPv4 and IPv6 connections + // required on Windows: + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb513665(v=vs.85).aspx + int value = 0; + setsockopt(m_handle, IPPROTO_IPV6, IPV6_V6ONLY, + reinterpret_cast<char *>(&value), sizeof(value)); + } + + return true; +} + +UDPSocket::~UDPSocket() +{ + if (socket_enable_debug_output) { + dstream << "UDPSocket( " << (int)m_handle << ")::~UDPSocket()" + << std::endl; + } + +#ifdef _WIN32 + closesocket(m_handle); +#else + close(m_handle); +#endif +} + +void UDPSocket::Bind(Address addr) +{ + if (socket_enable_debug_output) { + dstream << "UDPSocket(" << (int)m_handle + << ")::Bind(): " << addr.serializeString() << ":" + << addr.getPort() << std::endl; + } + + if (addr.getFamily() != m_addr_family) { + const char *errmsg = + "Socket and bind address families do not match"; + errorstream << "Bind failed: " << errmsg << std::endl; + throw SocketException(errmsg); + } + + int ret = 0; + + if (m_addr_family == AF_INET6) { + struct sockaddr_in6 address; + memset(&address, 0, sizeof(address)); + + address.sin6_family = AF_INET6; + address.sin6_addr = addr.getAddress6(); + address.sin6_port = htons(addr.getPort()); + + ret = bind(m_handle, (const struct sockaddr *) &address, + sizeof(struct sockaddr_in6)); + } else { + struct sockaddr_in address; + memset(&address, 0, sizeof(address)); + + address.sin_family = AF_INET; + address.sin_addr = addr.getAddress(); + address.sin_port = htons(addr.getPort()); + + ret = bind(m_handle, (const struct sockaddr *) &address, + sizeof(struct sockaddr_in)); + } + + if (ret < 0) { + dstream << (int)m_handle << ": Bind failed: " + << SOCKET_ERR_STR(LAST_SOCKET_ERR()) << std::endl; + throw SocketException("Failed to bind socket"); + } +} + +void UDPSocket::Send(const Address &destination, const void *data, int size) +{ + bool dumping_packet = false; // for INTERNET_SIMULATOR + + if (INTERNET_SIMULATOR) + dumping_packet = myrand() % INTERNET_SIMULATOR_PACKET_LOSS == 0; + + if (socket_enable_debug_output) { + // Print packet destination and size + dstream << (int)m_handle << " -> "; + destination.print(dstream); + dstream << ", size=" << size; + + // Print packet contents + dstream << ", data="; + for (int i = 0; i < size && i < 20; i++) { + if (i % 2 == 0) + dstream << " "; + unsigned int a = ((const unsigned char *)data)[i]; + dstream << std::hex << std::setw(2) << std::setfill('0') << a; + } + + if (size > 20) + dstream << "..."; + + if (dumping_packet) + dstream << " (DUMPED BY INTERNET_SIMULATOR)"; + + dstream << std::endl; + } + + if (dumping_packet) { + // Lol let's forget it + dstream << "UDPSocket::Send(): INTERNET_SIMULATOR: dumping packet." + << std::endl; + return; + } + + if (destination.getFamily() != m_addr_family) + throw SendFailedException("Address family mismatch"); + + int sent; + if (m_addr_family == AF_INET6) { + struct sockaddr_in6 address = {}; + address.sin6_family = AF_INET6; + address.sin6_addr = destination.getAddress6(); + address.sin6_port = htons(destination.getPort()); + + sent = sendto(m_handle, (const char *)data, size, 0, + (struct sockaddr *)&address, sizeof(struct sockaddr_in6)); + } else { + struct sockaddr_in address = {}; + address.sin_family = AF_INET; + address.sin_addr = destination.getAddress(); + address.sin_port = htons(destination.getPort()); + + sent = sendto(m_handle, (const char *)data, size, 0, + (struct sockaddr *)&address, sizeof(struct sockaddr_in)); + } + + if (sent != size) + throw SendFailedException("Failed to send packet"); +} + +int UDPSocket::Receive(Address &sender, void *data, int size) +{ + // Return on timeout + if (!WaitData(m_timeout_ms)) + return -1; + + int received; + if (m_addr_family == AF_INET6) { + struct sockaddr_in6 address; + memset(&address, 0, sizeof(address)); + socklen_t address_len = sizeof(address); + + received = recvfrom(m_handle, (char *)data, size, 0, + (struct sockaddr *)&address, &address_len); + + if (received < 0) + return -1; + + u16 address_port = ntohs(address.sin6_port); + const auto *bytes = reinterpret_cast<IPv6AddressBytes*> + (address.sin6_addr.s6_addr); + sender = Address(bytes, address_port); + } else { + struct sockaddr_in address; + memset(&address, 0, sizeof(address)); + + socklen_t address_len = sizeof(address); + + received = recvfrom(m_handle, (char *)data, size, 0, + (struct sockaddr *)&address, &address_len); + + if (received < 0) + return -1; + + u32 address_ip = ntohl(address.sin_addr.s_addr); + u16 address_port = ntohs(address.sin_port); + + sender = Address(address_ip, address_port); + } + + if (socket_enable_debug_output) { + // Print packet sender and size + dstream << (int)m_handle << " <- "; + sender.print(dstream); + dstream << ", size=" << received; + + // Print packet contents + dstream << ", data="; + for (int i = 0; i < received && i < 20; i++) { + if (i % 2 == 0) + dstream << " "; + unsigned int a = ((const unsigned char *)data)[i]; + dstream << std::hex << std::setw(2) << std::setfill('0') << a; + } + if (received > 20) + dstream << "..."; + + dstream << std::endl; + } + + return received; +} + +int UDPSocket::GetHandle() +{ + return m_handle; +} + +void UDPSocket::setTimeoutMs(int timeout_ms) +{ + m_timeout_ms = timeout_ms; +} + +bool UDPSocket::WaitData(int timeout_ms) +{ + fd_set readset; + int result; + + // Initialize the set + FD_ZERO(&readset); + FD_SET(m_handle, &readset); + + // Initialize time out struct + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = timeout_ms * 1000; + + // select() + result = select(m_handle + 1, &readset, NULL, NULL, &tv); + + if (result == 0) + return false; + + int e = LAST_SOCKET_ERR(); +#ifdef _WIN32 + if (result < 0 && (e == WSAEINTR || e == WSAEBADF)) { +#else + if (result < 0 && (e == EINTR || e == EBADF)) { +#endif + // N.B. select() fails when sockets are destroyed on Connection's dtor + // with EBADF. Instead of doing tricky synchronization, allow this + // thread to exit but don't throw an exception. + return false; + } + + if (result < 0) { + dstream << (int)m_handle << ": Select failed: " << SOCKET_ERR_STR(e) + << std::endl; + + throw SocketException("Select failed"); + } else if (!FD_ISSET(m_handle, &readset)) { + // No data + return false; + } + + // There is data + return true; +} diff --git a/src/network/socket.h b/src/network/socket.h new file mode 100644 index 0000000..d34186b --- /dev/null +++ b/src/network/socket.h @@ -0,0 +1,56 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <ostream> +#include <cstring> +#include "address.h" +#include "irrlichttypes.h" +#include "networkexceptions.h" + +extern bool socket_enable_debug_output; + +void sockets_init(); +void sockets_cleanup(); + +class UDPSocket +{ +public: + UDPSocket() = default; + + UDPSocket(bool ipv6); + ~UDPSocket(); + void Bind(Address addr); + + bool init(bool ipv6, bool noExceptions = false); + + void Send(const Address &destination, const void *data, int size); + // Returns -1 if there is no data + int Receive(Address &sender, void *data, int size); + int GetHandle(); // For debugging purposes only + void setTimeoutMs(int timeout_ms); + // Returns true if there is data, false if timeout occurred + bool WaitData(int timeout_ms); + +private: + int m_handle; + int m_timeout_ms; + int m_addr_family; +}; diff --git a/src/nodedef.cpp b/src/nodedef.cpp new file mode 100644 index 0000000..e9b322f --- /dev/null +++ b/src/nodedef.cpp @@ -0,0 +1,1844 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "nodedef.h" + +#include "itemdef.h" +#ifndef SERVER +#include "client/mesh.h" +#include "client/shader.h" +#include "client/client.h" +#include "client/renderingengine.h" +#include "client/tile.h" +#include <IMeshManipulator.h> +#endif +#include "log.h" +#include "settings.h" +#include "nameidmapping.h" +#include "util/numeric.h" +#include "util/serialize.h" +#include "util/string.h" +#include "exceptions.h" +#include "debug.h" +#include "gamedef.h" +#include "mapnode.h" +#include <fstream> // Used in applyTextureOverrides() +#include <algorithm> +#include <cmath> + +/* + NodeBox +*/ + +void NodeBox::reset() +{ + type = NODEBOX_REGULAR; + // default is empty + fixed.clear(); + // default is sign/ladder-like + wall_top = aabb3f(-BS/2, BS/2-BS/16., -BS/2, BS/2, BS/2, BS/2); + wall_bottom = aabb3f(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2); + wall_side = aabb3f(-BS/2, -BS/2, -BS/2, -BS/2+BS/16., BS/2, BS/2); + // no default for other parts + connected.reset(); +} + +void NodeBox::serialize(std::ostream &os, u16 protocol_version) const +{ + writeU8(os, 6); // version. Protocol >= 36 + + switch (type) { + case NODEBOX_LEVELED: + case NODEBOX_FIXED: + writeU8(os, type); + + writeU16(os, fixed.size()); + for (const aabb3f &nodebox : fixed) { + writeV3F32(os, nodebox.MinEdge); + writeV3F32(os, nodebox.MaxEdge); + } + break; + case NODEBOX_WALLMOUNTED: + writeU8(os, type); + + writeV3F32(os, wall_top.MinEdge); + writeV3F32(os, wall_top.MaxEdge); + writeV3F32(os, wall_bottom.MinEdge); + writeV3F32(os, wall_bottom.MaxEdge); + writeV3F32(os, wall_side.MinEdge); + writeV3F32(os, wall_side.MaxEdge); + break; + case NODEBOX_CONNECTED: { + writeU8(os, type); + +#define WRITEBOX(box) \ + writeU16(os, (box).size()); \ + for (const aabb3f &i: (box)) { \ + writeV3F32(os, i.MinEdge); \ + writeV3F32(os, i.MaxEdge); \ + }; + + const auto &c = getConnected(); + + WRITEBOX(fixed); + WRITEBOX(c.connect_top); + WRITEBOX(c.connect_bottom); + WRITEBOX(c.connect_front); + WRITEBOX(c.connect_left); + WRITEBOX(c.connect_back); + WRITEBOX(c.connect_right); + WRITEBOX(c.disconnected_top); + WRITEBOX(c.disconnected_bottom); + WRITEBOX(c.disconnected_front); + WRITEBOX(c.disconnected_left); + WRITEBOX(c.disconnected_back); + WRITEBOX(c.disconnected_right); + WRITEBOX(c.disconnected); + WRITEBOX(c.disconnected_sides); + break; + } + default: + writeU8(os, type); + break; + } +} + +void NodeBox::deSerialize(std::istream &is) +{ + if (readU8(is) < 6) + throw SerializationError("unsupported NodeBox version"); + + reset(); + + type = (enum NodeBoxType)readU8(is); + + if(type == NODEBOX_FIXED || type == NODEBOX_LEVELED) + { + u16 fixed_count = readU16(is); + while(fixed_count--) + { + aabb3f box; + box.MinEdge = readV3F32(is); + box.MaxEdge = readV3F32(is); + fixed.push_back(box); + } + } + else if(type == NODEBOX_WALLMOUNTED) + { + wall_top.MinEdge = readV3F32(is); + wall_top.MaxEdge = readV3F32(is); + wall_bottom.MinEdge = readV3F32(is); + wall_bottom.MaxEdge = readV3F32(is); + wall_side.MinEdge = readV3F32(is); + wall_side.MaxEdge = readV3F32(is); + } + else if (type == NODEBOX_CONNECTED) + { +#define READBOXES(box) { \ + count = readU16(is); \ + (box).reserve(count); \ + while (count--) { \ + v3f min = readV3F32(is); \ + v3f max = readV3F32(is); \ + (box).emplace_back(min, max); }; } + + u16 count; + + auto &c = getConnected(); + + READBOXES(fixed); + READBOXES(c.connect_top); + READBOXES(c.connect_bottom); + READBOXES(c.connect_front); + READBOXES(c.connect_left); + READBOXES(c.connect_back); + READBOXES(c.connect_right); + READBOXES(c.disconnected_top); + READBOXES(c.disconnected_bottom); + READBOXES(c.disconnected_front); + READBOXES(c.disconnected_left); + READBOXES(c.disconnected_back); + READBOXES(c.disconnected_right); + READBOXES(c.disconnected); + READBOXES(c.disconnected_sides); + } +} + +/* + TileDef +*/ + +#define TILE_FLAG_BACKFACE_CULLING (1 << 0) +#define TILE_FLAG_TILEABLE_HORIZONTAL (1 << 1) +#define TILE_FLAG_TILEABLE_VERTICAL (1 << 2) +#define TILE_FLAG_HAS_COLOR (1 << 3) +#define TILE_FLAG_HAS_SCALE (1 << 4) +#define TILE_FLAG_HAS_ALIGN_STYLE (1 << 5) + +void TileDef::serialize(std::ostream &os, u16 protocol_version) const +{ + // protocol_version >= 36 + u8 version = 6; + writeU8(os, version); + + if (protocol_version > 39) { + os << serializeString16(name); + } else { + // Before f018737, TextureSource::getTextureAverageColor did not handle + // missing textures. "[png" can be used as base texture, but is not known + // on older clients. Hence use "blank.png" to avoid this problem. + // To be forward-compatible with future base textures/modifiers, + // we apply the same prefix to any texture beginning with [, + // except for the ones that are supported on older clients. + bool pass_through = true; + + if (!name.empty() && name[0] == '[') { + pass_through = str_starts_with(name, "[combine:") || + str_starts_with(name, "[inventorycube{") || + str_starts_with(name, "[lowpart:"); + } + + if (pass_through) + os << serializeString16(name); + else + os << serializeString16("blank.png^" + name); + } + animation.serialize(os, version); + bool has_scale = scale > 0; + u16 flags = 0; + if (backface_culling) + flags |= TILE_FLAG_BACKFACE_CULLING; + if (tileable_horizontal) + flags |= TILE_FLAG_TILEABLE_HORIZONTAL; + if (tileable_vertical) + flags |= TILE_FLAG_TILEABLE_VERTICAL; + if (has_color) + flags |= TILE_FLAG_HAS_COLOR; + if (has_scale) + flags |= TILE_FLAG_HAS_SCALE; + if (align_style != ALIGN_STYLE_NODE) + flags |= TILE_FLAG_HAS_ALIGN_STYLE; + writeU16(os, flags); + if (has_color) { + writeU8(os, color.getRed()); + writeU8(os, color.getGreen()); + writeU8(os, color.getBlue()); + } + if (has_scale) + writeU8(os, scale); + if (align_style != ALIGN_STYLE_NODE) + writeU8(os, align_style); +} + +void TileDef::deSerialize(std::istream &is, NodeDrawType drawtype, u16 protocol_version) +{ + if (readU8(is) < 6) + throw SerializationError("unsupported TileDef version"); + + name = deSerializeString16(is); + animation.deSerialize(is, protocol_version); + u16 flags = readU16(is); + backface_culling = flags & TILE_FLAG_BACKFACE_CULLING; + tileable_horizontal = flags & TILE_FLAG_TILEABLE_HORIZONTAL; + tileable_vertical = flags & TILE_FLAG_TILEABLE_VERTICAL; + has_color = flags & TILE_FLAG_HAS_COLOR; + bool has_scale = flags & TILE_FLAG_HAS_SCALE; + bool has_align_style = flags & TILE_FLAG_HAS_ALIGN_STYLE; + if (has_color) { + color.setRed(readU8(is)); + color.setGreen(readU8(is)); + color.setBlue(readU8(is)); + } + scale = has_scale ? readU8(is) : 0; + if (has_align_style) + align_style = static_cast<AlignStyle>(readU8(is)); + else + align_style = ALIGN_STYLE_NODE; +} + +void TextureSettings::readSettings() +{ + connected_glass = g_settings->getBool("connected_glass"); + opaque_water = g_settings->getBool("opaque_water"); + bool smooth_lighting = g_settings->getBool("smooth_lighting"); + enable_mesh_cache = g_settings->getBool("enable_mesh_cache"); + enable_minimap = g_settings->getBool("enable_minimap"); + node_texture_size = std::max<u16>(g_settings->getU16("texture_min_size"), 1); + std::string leaves_style_str = g_settings->get("leaves_style"); + std::string world_aligned_mode_str = g_settings->get("world_aligned_mode"); + std::string autoscale_mode_str = g_settings->get("autoscale_mode"); + + // Mesh cache is not supported in combination with smooth lighting + if (smooth_lighting) + enable_mesh_cache = false; + + if (leaves_style_str == "fancy") { + leaves_style = LEAVES_FANCY; + } else if (leaves_style_str == "simple") { + leaves_style = LEAVES_SIMPLE; + } else { + leaves_style = LEAVES_OPAQUE; + } + + if (world_aligned_mode_str == "enable") + world_aligned_mode = WORLDALIGN_ENABLE; + else if (world_aligned_mode_str == "force_solid") + world_aligned_mode = WORLDALIGN_FORCE; + else if (world_aligned_mode_str == "force_nodebox") + world_aligned_mode = WORLDALIGN_FORCE_NODEBOX; + else + world_aligned_mode = WORLDALIGN_DISABLE; + + if (autoscale_mode_str == "enable") + autoscale_mode = AUTOSCALE_ENABLE; + else if (autoscale_mode_str == "force") + autoscale_mode = AUTOSCALE_FORCE; + else + autoscale_mode = AUTOSCALE_DISABLE; +} + +/* + ContentFeatures +*/ + +ContentFeatures::ContentFeatures() +{ + reset(); +} + +ContentFeatures::~ContentFeatures() +{ +#ifndef SERVER + for (u16 j = 0; j < 6; j++) { + delete tiles[j].layers[0].frames; + delete tiles[j].layers[1].frames; + } + for (u16 j = 0; j < CF_SPECIAL_COUNT; j++) + delete special_tiles[j].layers[0].frames; +#endif +} + +void ContentFeatures::reset() +{ + /* + Cached stuff + */ +#ifndef SERVER + solidness = 2; + visual_solidness = 0; + backface_culling = true; + +#endif + has_on_construct = false; + has_on_destruct = false; + has_after_destruct = false; + /* + Actual data + + NOTE: Most of this is always overridden by the default values given + in builtin.lua + */ + name = ""; + groups.clear(); + // Unknown nodes can be dug + groups["dig_immediate"] = 2; + drawtype = NDT_NORMAL; + mesh = ""; +#ifndef SERVER + for (auto &i : mesh_ptr) + i = NULL; + minimap_color = video::SColor(0, 0, 0, 0); +#endif + visual_scale = 1.0; + for (auto &i : tiledef) + i = TileDef(); + for (auto &j : tiledef_special) + j = TileDef(); + alpha = ALPHAMODE_OPAQUE; + post_effect_color = video::SColor(0, 0, 0, 0); + param_type = CPT_NONE; + param_type_2 = CPT2_NONE; + is_ground_content = false; + light_propagates = false; + sunlight_propagates = false; + walkable = true; + pointable = true; + diggable = true; + climbable = false; + buildable_to = false; + floodable = false; + rightclickable = true; + leveled = 0; + leveled_max = LEVELED_MAX; + liquid_type = LIQUID_NONE; + liquid_alternative_flowing = ""; + liquid_alternative_flowing_id = CONTENT_IGNORE; + liquid_alternative_source = ""; + liquid_alternative_source_id = CONTENT_IGNORE; + liquid_viscosity = 0; + liquid_renewable = true; + liquid_range = LIQUID_LEVEL_MAX+1; + drowning = 0; + light_source = 0; + damage_per_second = 0; + node_box.reset(); + selection_box.reset(); + collision_box.reset(); + waving = 0; + legacy_facedir_simple = false; + legacy_wallmounted = false; + sound_footstep = SimpleSoundSpec(); + sound_dig = SimpleSoundSpec("__group"); + sound_dug = SimpleSoundSpec(); + connects_to.clear(); + connects_to_ids.clear(); + connect_sides = 0; + color = video::SColor(0xFFFFFFFF); + palette_name = ""; + palette = NULL; + node_dig_prediction = "air"; + move_resistance = 0; + liquid_move_physics = false; +} + +void ContentFeatures::setAlphaFromLegacy(u8 legacy_alpha) +{ + // No special handling for nodebox/mesh here as it doesn't make sense to + // throw warnings when the server is too old to support the "correct" way + switch (drawtype) { + case NDT_NORMAL: + alpha = legacy_alpha == 255 ? ALPHAMODE_OPAQUE : ALPHAMODE_CLIP; + break; + case NDT_LIQUID: + case NDT_FLOWINGLIQUID: + alpha = legacy_alpha == 255 ? ALPHAMODE_OPAQUE : ALPHAMODE_BLEND; + break; + default: + alpha = legacy_alpha == 255 ? ALPHAMODE_CLIP : ALPHAMODE_BLEND; + break; + } +} + +u8 ContentFeatures::getAlphaForLegacy() const +{ + // This is so simple only because 255 and 0 mean wildly different things + // depending on drawtype... + return alpha == ALPHAMODE_OPAQUE ? 255 : 0; +} + +void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const +{ + writeU8(os, CONTENTFEATURES_VERSION); + + // general + os << serializeString16(name); + writeU16(os, groups.size()); + for (const auto &group : groups) { + os << serializeString16(group.first); + if (protocol_version < 41 && group.first.compare("bouncy") == 0) { + // Old clients may choke on negative bouncy value + writeS16(os, abs(group.second)); + } else { + writeS16(os, group.second); + } + } + writeU8(os, param_type); + writeU8(os, param_type_2); + + // visual + writeU8(os, drawtype); + os << serializeString16(mesh); + writeF32(os, visual_scale); + writeU8(os, 6); + for (const TileDef &td : tiledef) + td.serialize(os, protocol_version); + for (const TileDef &td : tiledef_overlay) + td.serialize(os, protocol_version); + writeU8(os, CF_SPECIAL_COUNT); + for (const TileDef &td : tiledef_special) { + td.serialize(os, protocol_version); + } + writeU8(os, getAlphaForLegacy()); + writeU8(os, color.getRed()); + writeU8(os, color.getGreen()); + writeU8(os, color.getBlue()); + os << serializeString16(palette_name); + writeU8(os, waving); + writeU8(os, connect_sides); + writeU16(os, connects_to_ids.size()); + for (u16 connects_to_id : connects_to_ids) + writeU16(os, connects_to_id); + writeARGB8(os, post_effect_color); + writeU8(os, leveled); + + // lighting + writeU8(os, light_propagates); + writeU8(os, sunlight_propagates); + writeU8(os, light_source); + + // map generation + writeU8(os, is_ground_content); + + // interaction + writeU8(os, walkable); + writeU8(os, pointable); + writeU8(os, diggable); + writeU8(os, climbable); + writeU8(os, buildable_to); + writeU8(os, rightclickable); + writeU32(os, damage_per_second); + + // liquid + LiquidType liquid_type_bc = liquid_type; + if (protocol_version <= 39) { + // Since commit 7f25823, liquid drawtypes can be used even with LIQUID_NONE + // solution: force liquid type accordingly to accepted values + if (drawtype == NDT_LIQUID) + liquid_type_bc = LIQUID_SOURCE; + else if (drawtype == NDT_FLOWINGLIQUID) + liquid_type_bc = LIQUID_FLOWING; + } + writeU8(os, liquid_type_bc); + os << serializeString16(liquid_alternative_flowing); + os << serializeString16(liquid_alternative_source); + writeU8(os, liquid_viscosity); + writeU8(os, liquid_renewable); + writeU8(os, liquid_range); + writeU8(os, drowning); + writeU8(os, floodable); + + // node boxes + node_box.serialize(os, protocol_version); + selection_box.serialize(os, protocol_version); + collision_box.serialize(os, protocol_version); + + // sound + sound_footstep.serialize(os, protocol_version); + sound_dig.serialize(os, protocol_version); + sound_dug.serialize(os, protocol_version); + + // legacy + writeU8(os, legacy_facedir_simple); + writeU8(os, legacy_wallmounted); + + // new attributes + os << serializeString16(node_dig_prediction); + writeU8(os, leveled_max); + writeU8(os, alpha); + writeU8(os, move_resistance); + writeU8(os, liquid_move_physics); +} + +void ContentFeatures::deSerialize(std::istream &is, u16 protocol_version) +{ + if (readU8(is) < CONTENTFEATURES_VERSION) + throw SerializationError("unsupported ContentFeatures version"); + + // general + name = deSerializeString16(is); + groups.clear(); + u32 groups_size = readU16(is); + for (u32 i = 0; i < groups_size; i++) { + std::string name = deSerializeString16(is); + int value = readS16(is); + groups[name] = value; + } + param_type = (enum ContentParamType) readU8(is); + param_type_2 = (enum ContentParamType2) readU8(is); + + // visual + drawtype = (enum NodeDrawType) readU8(is); + mesh = deSerializeString16(is); + visual_scale = readF32(is); + if (readU8(is) != 6) + throw SerializationError("unsupported tile count"); + for (TileDef &td : tiledef) + td.deSerialize(is, drawtype, protocol_version); + for (TileDef &td : tiledef_overlay) + td.deSerialize(is, drawtype, protocol_version); + if (readU8(is) != CF_SPECIAL_COUNT) + throw SerializationError("unsupported CF_SPECIAL_COUNT"); + for (TileDef &td : tiledef_special) + td.deSerialize(is, drawtype, protocol_version); + setAlphaFromLegacy(readU8(is)); + color.setRed(readU8(is)); + color.setGreen(readU8(is)); + color.setBlue(readU8(is)); + palette_name = deSerializeString16(is); + waving = readU8(is); + connect_sides = readU8(is); + u16 connects_to_size = readU16(is); + connects_to_ids.clear(); + for (u16 i = 0; i < connects_to_size; i++) + connects_to_ids.push_back(readU16(is)); + post_effect_color = readARGB8(is); + leveled = readU8(is); + + // lighting-related + light_propagates = readU8(is); + sunlight_propagates = readU8(is); + light_source = readU8(is); + light_source = MYMIN(light_source, LIGHT_MAX); + + // map generation + is_ground_content = readU8(is); + + // interaction + walkable = readU8(is); + pointable = readU8(is); + diggable = readU8(is); + climbable = readU8(is); + buildable_to = readU8(is); + rightclickable = readU8(is); + damage_per_second = readU32(is); + + // liquid + liquid_type = (enum LiquidType) readU8(is); + liquid_move_physics = liquid_type != LIQUID_NONE; + liquid_alternative_flowing = deSerializeString16(is); + liquid_alternative_source = deSerializeString16(is); + liquid_viscosity = readU8(is); + move_resistance = liquid_viscosity; // set default move_resistance + liquid_renewable = readU8(is); + liquid_range = readU8(is); + drowning = readU8(is); + floodable = readU8(is); + + // node boxes + node_box.deSerialize(is); + selection_box.deSerialize(is); + collision_box.deSerialize(is); + + // sounds + sound_footstep.deSerialize(is, protocol_version); + sound_dig.deSerialize(is, protocol_version); + sound_dug.deSerialize(is, protocol_version); + + // read legacy properties + legacy_facedir_simple = readU8(is); + legacy_wallmounted = readU8(is); + + try { + node_dig_prediction = deSerializeString16(is); + + u8 tmp = readU8(is); + if (is.eof()) /* readU8 doesn't throw exceptions so we have to do this */ + throw SerializationError(""); + leveled_max = tmp; + + tmp = readU8(is); + if (is.eof()) + throw SerializationError(""); + alpha = static_cast<enum AlphaMode>(tmp); + + tmp = readU8(is); + if (is.eof()) + throw SerializationError(""); + move_resistance = tmp; + + tmp = readU8(is); + if (is.eof()) + throw SerializationError(""); + liquid_move_physics = tmp; + } catch(SerializationError &e) {}; +} + +#ifndef SERVER +static void fillTileAttribs(ITextureSource *tsrc, TileLayer *layer, + const TileSpec &tile, const TileDef &tiledef, video::SColor color, + u8 material_type, u32 shader_id, bool backface_culling, + const TextureSettings &tsettings) +{ + layer->shader_id = shader_id; + layer->texture = tsrc->getTextureForMesh(tiledef.name, &layer->texture_id); + layer->material_type = material_type; + + bool has_scale = tiledef.scale > 0; + bool use_autoscale = tsettings.autoscale_mode == AUTOSCALE_FORCE || + (tsettings.autoscale_mode == AUTOSCALE_ENABLE && !has_scale); + if (use_autoscale && layer->texture) { + auto texture_size = layer->texture->getOriginalSize(); + float base_size = tsettings.node_texture_size; + float size = std::fmin(texture_size.Width, texture_size.Height); + layer->scale = std::fmax(base_size, size) / base_size; + } else if (has_scale) { + layer->scale = tiledef.scale; + } else { + layer->scale = 1; + } + if (!tile.world_aligned) + layer->scale = 1; + + layer->flags_texture = tsrc->getShaderFlagsTexture(layer->normal_texture ? true : false); + + // Material flags + layer->material_flags = 0; + if (backface_culling) + layer->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; + if (tiledef.animation.type != TAT_NONE) + layer->material_flags |= MATERIAL_FLAG_ANIMATION; + if (tiledef.tileable_horizontal) + layer->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL; + if (tiledef.tileable_vertical) + layer->material_flags |= MATERIAL_FLAG_TILEABLE_VERTICAL; + + // Color + layer->has_color = tiledef.has_color; + if (tiledef.has_color) + layer->color = tiledef.color; + else + layer->color = color; + + // Animation parameters + int frame_count = 1; + if (layer->material_flags & MATERIAL_FLAG_ANIMATION) { + assert(layer->texture); + int frame_length_ms; + tiledef.animation.determineParams(layer->texture->getOriginalSize(), + &frame_count, &frame_length_ms, NULL); + layer->animation_frame_count = frame_count; + layer->animation_frame_length_ms = frame_length_ms; + } + + if (frame_count == 1) { + layer->material_flags &= ~MATERIAL_FLAG_ANIMATION; + } else { + assert(layer->texture); + if (!layer->frames) + layer->frames = new std::vector<FrameSpec>(); + layer->frames->resize(frame_count); + + std::ostringstream os(std::ios::binary); + for (int i = 0; i < frame_count; i++) { + FrameSpec frame; + + os.str(""); + os << tiledef.name; + tiledef.animation.getTextureModifer(os, + layer->texture->getOriginalSize(), i); + + frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id); + if (layer->normal_texture) + frame.normal_texture = tsrc->getNormalTexture(os.str()); + frame.flags_texture = layer->flags_texture; + (*layer->frames)[i] = frame; + } + } +} + +bool ContentFeatures::textureAlphaCheck(ITextureSource *tsrc, const TileDef *tiles, int length) +{ + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + static thread_local bool long_warning_printed = false; + std::set<std::string> seen; + + for (int i = 0; i < length; i++) { + if (seen.find(tiles[i].name) != seen.end()) + continue; + seen.insert(tiles[i].name); + + // Load the texture and see if there's any transparent pixels + video::ITexture *texture = tsrc->getTexture(tiles[i].name); + video::IImage *image = driver->createImage(texture, + core::position2d<s32>(0, 0), texture->getOriginalSize()); + if (!image) + continue; + core::dimension2d<u32> dim = image->getDimension(); + bool ok = true; + for (u16 x = 0; x < dim.Width; x++) { + for (u16 y = 0; y < dim.Height; y++) { + if (image->getPixel(x, y).getAlpha() < 255) { + ok = false; + goto break_loop; + } + } + } + +break_loop: + image->drop(); + if (ok) + continue; + warningstream << "Texture \"" << tiles[i].name << "\" of " + << name << " has transparency, assuming " + "use_texture_alpha = \"clip\"." << std::endl; + if (!long_warning_printed) { + warningstream << " This warning can be a false-positive if " + "unused pixels in the texture are transparent. However if " + "it is meant to be transparent, you *MUST* update the " + "nodedef and set use_texture_alpha = \"clip\"! This " + "compatibility code will be removed in a few releases." + << std::endl; + long_warning_printed = true; + } + return true; + } + return false; +} + +bool isWorldAligned(AlignStyle style, WorldAlignMode mode, NodeDrawType drawtype) +{ + if (style == ALIGN_STYLE_WORLD) + return true; + if (mode == WORLDALIGN_DISABLE) + return false; + if (style == ALIGN_STYLE_USER_DEFINED) + return true; + if (drawtype == NDT_NORMAL) + return mode >= WORLDALIGN_FORCE; + if (drawtype == NDT_NODEBOX) + return mode >= WORLDALIGN_FORCE_NODEBOX; + return false; +} + +void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc, + scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings) +{ + // minimap pixel color - the average color of a texture + if (tsettings.enable_minimap && !tiledef[0].name.empty()) + minimap_color = tsrc->getTextureAverageColor(tiledef[0].name); + + // Figure out the actual tiles to use + TileDef tdef[6]; + for (u32 j = 0; j < 6; j++) { + tdef[j] = tiledef[j]; + if (tdef[j].name.empty()) { + tdef[j].name = "no_texture.png"; + tdef[j].backface_culling = false; + } + } + // also the overlay tiles + TileDef tdef_overlay[6]; + for (u32 j = 0; j < 6; j++) + tdef_overlay[j] = tiledef_overlay[j]; + // also the special tiles + TileDef tdef_spec[6]; + for (u32 j = 0; j < CF_SPECIAL_COUNT; j++) { + tdef_spec[j] = tiledef_special[j]; + } + + bool is_liquid = false; + + if (alpha == ALPHAMODE_LEGACY_COMPAT) { + // Before working with the alpha mode, resolve any legacy kludges + alpha = textureAlphaCheck(tsrc, tdef, 6) ? ALPHAMODE_CLIP : ALPHAMODE_OPAQUE; + } + + MaterialType material_type = alpha == ALPHAMODE_OPAQUE ? + TILE_MATERIAL_OPAQUE : (alpha == ALPHAMODE_CLIP ? TILE_MATERIAL_BASIC : + TILE_MATERIAL_ALPHA); + + switch (drawtype) { + default: + case NDT_NORMAL: + solidness = 2; + break; + case NDT_AIRLIKE: + solidness = 0; + break; + case NDT_LIQUID: + if (tsettings.opaque_water) + alpha = ALPHAMODE_OPAQUE; + solidness = 1; + is_liquid = true; + break; + case NDT_FLOWINGLIQUID: + solidness = 0; + if (tsettings.opaque_water) + alpha = ALPHAMODE_OPAQUE; + is_liquid = true; + break; + case NDT_GLASSLIKE: + solidness = 0; + visual_solidness = 1; + break; + case NDT_GLASSLIKE_FRAMED: + solidness = 0; + visual_solidness = 1; + break; + case NDT_GLASSLIKE_FRAMED_OPTIONAL: + solidness = 0; + visual_solidness = 1; + drawtype = tsettings.connected_glass ? NDT_GLASSLIKE_FRAMED : NDT_GLASSLIKE; + break; + case NDT_ALLFACES: + solidness = 0; + visual_solidness = 1; + break; + case NDT_ALLFACES_OPTIONAL: + if (tsettings.leaves_style == LEAVES_FANCY) { + drawtype = NDT_ALLFACES; + solidness = 0; + visual_solidness = 1; + } else if (tsettings.leaves_style == LEAVES_SIMPLE) { + for (u32 j = 0; j < 6; j++) { + if (!tdef_spec[j].name.empty()) + tdef[j].name = tdef_spec[j].name; + } + drawtype = NDT_GLASSLIKE; + solidness = 0; + visual_solidness = 1; + } else { + if (waving >= 1) { + // waving nodes must make faces so there are no gaps + drawtype = NDT_ALLFACES; + solidness = 0; + visual_solidness = 1; + } else { + drawtype = NDT_NORMAL; + solidness = 2; + } + for (TileDef &td : tdef) + td.name += std::string("^[noalpha"); + } + if (waving >= 1) + material_type = TILE_MATERIAL_WAVING_LEAVES; + break; + case NDT_PLANTLIKE: + solidness = 0; + if (waving >= 1) + material_type = TILE_MATERIAL_WAVING_PLANTS; + break; + case NDT_FIRELIKE: + solidness = 0; + break; + case NDT_MESH: + case NDT_NODEBOX: + solidness = 0; + if (waving == 1) { + material_type = TILE_MATERIAL_WAVING_PLANTS; + } else if (waving == 2) { + material_type = TILE_MATERIAL_WAVING_LEAVES; + } else if (waving == 3) { + material_type = alpha == ALPHAMODE_OPAQUE ? + TILE_MATERIAL_WAVING_LIQUID_OPAQUE : (alpha == ALPHAMODE_CLIP ? + TILE_MATERIAL_WAVING_LIQUID_BASIC : TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT); + } + break; + case NDT_TORCHLIKE: + case NDT_SIGNLIKE: + case NDT_FENCELIKE: + case NDT_RAILLIKE: + solidness = 0; + break; + case NDT_PLANTLIKE_ROOTED: + solidness = 2; + break; + } + + if (is_liquid) { + if (waving == 3) { + material_type = alpha == ALPHAMODE_OPAQUE ? + TILE_MATERIAL_WAVING_LIQUID_OPAQUE : (alpha == ALPHAMODE_CLIP ? + TILE_MATERIAL_WAVING_LIQUID_BASIC : TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT); + } else { + material_type = alpha == ALPHAMODE_OPAQUE ? TILE_MATERIAL_LIQUID_OPAQUE : + TILE_MATERIAL_LIQUID_TRANSPARENT; + } + } + + u32 tile_shader = shdsrc->getShader("nodes_shader", material_type, drawtype); + + MaterialType overlay_material = material_type; + if (overlay_material == TILE_MATERIAL_OPAQUE) + overlay_material = TILE_MATERIAL_BASIC; + else if (overlay_material == TILE_MATERIAL_LIQUID_OPAQUE) + overlay_material = TILE_MATERIAL_LIQUID_TRANSPARENT; + + u32 overlay_shader = shdsrc->getShader("nodes_shader", overlay_material, drawtype); + + // Tiles (fill in f->tiles[]) + for (u16 j = 0; j < 6; j++) { + tiles[j].world_aligned = isWorldAligned(tdef[j].align_style, + tsettings.world_aligned_mode, drawtype); + fillTileAttribs(tsrc, &tiles[j].layers[0], tiles[j], tdef[j], + color, material_type, tile_shader, + tdef[j].backface_culling, tsettings); + if (!tdef_overlay[j].name.empty()) + fillTileAttribs(tsrc, &tiles[j].layers[1], tiles[j], tdef_overlay[j], + color, overlay_material, overlay_shader, + tdef[j].backface_culling, tsettings); + } + + MaterialType special_material = material_type; + if (drawtype == NDT_PLANTLIKE_ROOTED) { + if (waving == 1) + special_material = TILE_MATERIAL_WAVING_PLANTS; + else if (waving == 2) + special_material = TILE_MATERIAL_WAVING_LEAVES; + } + u32 special_shader = shdsrc->getShader("nodes_shader", special_material, drawtype); + + // Special tiles (fill in f->special_tiles[]) + for (u16 j = 0; j < CF_SPECIAL_COUNT; j++) + fillTileAttribs(tsrc, &special_tiles[j].layers[0], special_tiles[j], tdef_spec[j], + color, special_material, special_shader, + tdef_spec[j].backface_culling, tsettings); + + if (param_type_2 == CPT2_COLOR || + param_type_2 == CPT2_COLORED_FACEDIR || + param_type_2 == CPT2_COLORED_WALLMOUNTED || + param_type_2 == CPT2_COLORED_DEGROTATE) + palette = tsrc->getPalette(palette_name); + + if (drawtype == NDT_MESH && !mesh.empty()) { + // Meshnode drawtype + // Read the mesh and apply scale + mesh_ptr[0] = client->getMesh(mesh); + if (mesh_ptr[0]){ + v3f scale = v3f(1.0, 1.0, 1.0) * BS * visual_scale; + scaleMesh(mesh_ptr[0], scale); + recalculateBoundingBox(mesh_ptr[0]); + meshmanip->recalculateNormals(mesh_ptr[0], true, false); + } + } + + //Cache 6dfacedir and wallmounted rotated clones of meshes + if (tsettings.enable_mesh_cache && mesh_ptr[0] && + (param_type_2 == CPT2_FACEDIR + || param_type_2 == CPT2_COLORED_FACEDIR)) { + for (u16 j = 1; j < 24; j++) { + mesh_ptr[j] = cloneMesh(mesh_ptr[0]); + rotateMeshBy6dFacedir(mesh_ptr[j], j); + recalculateBoundingBox(mesh_ptr[j]); + meshmanip->recalculateNormals(mesh_ptr[j], true, false); + } + } else if (tsettings.enable_mesh_cache && mesh_ptr[0] + && (param_type_2 == CPT2_WALLMOUNTED || + param_type_2 == CPT2_COLORED_WALLMOUNTED)) { + static const u8 wm_to_6d[6] = { 20, 0, 16 + 1, 12 + 3, 8, 4 + 2 }; + for (u16 j = 1; j < 6; j++) { + mesh_ptr[j] = cloneMesh(mesh_ptr[0]); + rotateMeshBy6dFacedir(mesh_ptr[j], wm_to_6d[j]); + recalculateBoundingBox(mesh_ptr[j]); + meshmanip->recalculateNormals(mesh_ptr[j], true, false); + } + rotateMeshBy6dFacedir(mesh_ptr[0], wm_to_6d[0]); + recalculateBoundingBox(mesh_ptr[0]); + meshmanip->recalculateNormals(mesh_ptr[0], true, false); + } +} +#endif + +/* + NodeDefManager +*/ + + + + +NodeDefManager::NodeDefManager() +{ + clear(); +} + + +NodeDefManager::~NodeDefManager() +{ +#ifndef SERVER + for (ContentFeatures &f : m_content_features) { + for (auto &j : f.mesh_ptr) { + if (j) + j->drop(); + } + } +#endif +} + + +void NodeDefManager::clear() +{ + m_content_features.clear(); + m_name_id_mapping.clear(); + m_name_id_mapping_with_aliases.clear(); + m_group_to_items.clear(); + m_next_id = 0; + m_selection_box_union.reset(0,0,0); + m_selection_box_int_union.reset(0,0,0); + + resetNodeResolveState(); + + u32 initial_length = 0; + initial_length = MYMAX(initial_length, CONTENT_UNKNOWN + 1); + initial_length = MYMAX(initial_length, CONTENT_AIR + 1); + initial_length = MYMAX(initial_length, CONTENT_IGNORE + 1); + m_content_features.resize(initial_length); + + // Set CONTENT_UNKNOWN + { + ContentFeatures f; + f.name = "unknown"; + for (int t = 0; t < 6; t++) + f.tiledef[t].name = "unknown_node.png"; + // Insert directly into containers + content_t c = CONTENT_UNKNOWN; + m_content_features[c] = f; + addNameIdMapping(c, f.name); + } + + // Set CONTENT_AIR + { + ContentFeatures f; + f.name = "air"; + f.drawtype = NDT_AIRLIKE; + f.param_type = CPT_LIGHT; + f.light_propagates = true; + f.sunlight_propagates = true; + f.walkable = false; + f.pointable = false; + f.diggable = false; + f.buildable_to = true; + f.floodable = true; + f.is_ground_content = true; + // Insert directly into containers + content_t c = CONTENT_AIR; + m_content_features[c] = f; + addNameIdMapping(c, f.name); + } + + // Set CONTENT_IGNORE + { + ContentFeatures f; + f.name = "ignore"; + f.drawtype = NDT_AIRLIKE; + f.param_type = CPT_NONE; + f.light_propagates = false; + f.sunlight_propagates = false; + f.walkable = false; + f.pointable = false; + f.diggable = false; + f.buildable_to = true; // A way to remove accidental CONTENT_IGNOREs + f.is_ground_content = true; + // Insert directly into containers + content_t c = CONTENT_IGNORE; + m_content_features[c] = f; + addNameIdMapping(c, f.name); + } +} + + +bool NodeDefManager::getId(const std::string &name, content_t &result) const +{ + std::unordered_map<std::string, content_t>::const_iterator + i = m_name_id_mapping_with_aliases.find(name); + if(i == m_name_id_mapping_with_aliases.end()) + return false; + result = i->second; + return true; +} + + +content_t NodeDefManager::getId(const std::string &name) const +{ + content_t id = CONTENT_IGNORE; + getId(name, id); + return id; +} + + +bool NodeDefManager::getIds(const std::string &name, + std::vector<content_t> &result) const +{ + //TimeTaker t("getIds", NULL, PRECISION_MICRO); + if (name.substr(0,6) != "group:") { + content_t id = CONTENT_IGNORE; + bool exists = getId(name, id); + if (exists) + result.push_back(id); + return exists; + } + std::string group = name.substr(6); + + std::unordered_map<std::string, std::vector<content_t>>::const_iterator + i = m_group_to_items.find(group); + if (i == m_group_to_items.end()) + return true; + + const std::vector<content_t> &items = i->second; + result.insert(result.end(), items.begin(), items.end()); + //printf("getIds: %dus\n", t.stop()); + return true; +} + + +const ContentFeatures& NodeDefManager::get(const std::string &name) const +{ + content_t id = CONTENT_UNKNOWN; + getId(name, id); + return get(id); +} + + +// returns CONTENT_IGNORE if no free ID found +content_t NodeDefManager::allocateId() +{ + for (content_t id = m_next_id; + id >= m_next_id; // overflow? + ++id) { + while (id >= m_content_features.size()) { + m_content_features.emplace_back(); + } + const ContentFeatures &f = m_content_features[id]; + if (f.name.empty()) { + m_next_id = id + 1; + return id; + } + } + // If we arrive here, an overflow occurred in id. + // That means no ID was found + return CONTENT_IGNORE; +} + + +/*! + * Returns the smallest box that contains all boxes + * in the vector. Box_union is expanded. + * @param[in] boxes the vector containing the boxes + * @param[in, out] box_union the union of the arguments + */ +void boxVectorUnion(const std::vector<aabb3f> &boxes, aabb3f *box_union) +{ + for (const aabb3f &box : boxes) { + box_union->addInternalBox(box); + } +} + + +/*! + * Returns a box that contains the nodebox in every case. + * The argument node_union is expanded. + * @param[in] nodebox the nodebox to be measured + * @param[in] features used to decide whether the nodebox + * can be rotated + * @param[in, out] box_union the union of the arguments + */ +void getNodeBoxUnion(const NodeBox &nodebox, const ContentFeatures &features, + aabb3f *box_union) +{ + switch(nodebox.type) { + case NODEBOX_FIXED: + case NODEBOX_LEVELED: { + // Raw union + aabb3f half_processed(0, 0, 0, 0, 0, 0); + boxVectorUnion(nodebox.fixed, &half_processed); + // Set leveled boxes to maximal + if (nodebox.type == NODEBOX_LEVELED) { + half_processed.MaxEdge.Y = +BS / 2; + } + if (features.param_type_2 == CPT2_FACEDIR || + features.param_type_2 == CPT2_COLORED_FACEDIR) { + // Get maximal coordinate + f32 coords[] = { + fabsf(half_processed.MinEdge.X), + fabsf(half_processed.MinEdge.Y), + fabsf(half_processed.MinEdge.Z), + fabsf(half_processed.MaxEdge.X), + fabsf(half_processed.MaxEdge.Y), + fabsf(half_processed.MaxEdge.Z) }; + f32 max = 0; + for (float coord : coords) { + if (max < coord) { + max = coord; + } + } + // Add the union of all possible rotated boxes + box_union->addInternalPoint(-max, -max, -max); + box_union->addInternalPoint(+max, +max, +max); + } else { + box_union->addInternalBox(half_processed); + } + break; + } + case NODEBOX_WALLMOUNTED: { + // Add fix boxes + box_union->addInternalBox(nodebox.wall_top); + box_union->addInternalBox(nodebox.wall_bottom); + // Find maximal coordinate in the X-Z plane + f32 coords[] = { + fabsf(nodebox.wall_side.MinEdge.X), + fabsf(nodebox.wall_side.MinEdge.Z), + fabsf(nodebox.wall_side.MaxEdge.X), + fabsf(nodebox.wall_side.MaxEdge.Z) }; + f32 max = 0; + for (float coord : coords) { + if (max < coord) { + max = coord; + } + } + // Add the union of all possible rotated boxes + box_union->addInternalPoint(-max, nodebox.wall_side.MinEdge.Y, -max); + box_union->addInternalPoint(max, nodebox.wall_side.MaxEdge.Y, max); + break; + } + case NODEBOX_CONNECTED: { + const auto &c = nodebox.getConnected(); + // Add all possible connected boxes + boxVectorUnion(nodebox.fixed, box_union); + boxVectorUnion(c.connect_top, box_union); + boxVectorUnion(c.connect_bottom, box_union); + boxVectorUnion(c.connect_front, box_union); + boxVectorUnion(c.connect_left, box_union); + boxVectorUnion(c.connect_back, box_union); + boxVectorUnion(c.connect_right, box_union); + boxVectorUnion(c.disconnected_top, box_union); + boxVectorUnion(c.disconnected_bottom, box_union); + boxVectorUnion(c.disconnected_front, box_union); + boxVectorUnion(c.disconnected_left, box_union); + boxVectorUnion(c.disconnected_back, box_union); + boxVectorUnion(c.disconnected_right, box_union); + boxVectorUnion(c.disconnected, box_union); + boxVectorUnion(c.disconnected_sides, box_union); + break; + } + default: { + // NODEBOX_REGULAR + box_union->addInternalPoint(-BS / 2, -BS / 2, -BS / 2); + box_union->addInternalPoint(+BS / 2, +BS / 2, +BS / 2); + } + } +} + + +inline void NodeDefManager::fixSelectionBoxIntUnion() +{ + m_selection_box_int_union.MinEdge.X = floorf( + m_selection_box_union.MinEdge.X / BS + 0.5f); + m_selection_box_int_union.MinEdge.Y = floorf( + m_selection_box_union.MinEdge.Y / BS + 0.5f); + m_selection_box_int_union.MinEdge.Z = floorf( + m_selection_box_union.MinEdge.Z / BS + 0.5f); + m_selection_box_int_union.MaxEdge.X = ceilf( + m_selection_box_union.MaxEdge.X / BS - 0.5f); + m_selection_box_int_union.MaxEdge.Y = ceilf( + m_selection_box_union.MaxEdge.Y / BS - 0.5f); + m_selection_box_int_union.MaxEdge.Z = ceilf( + m_selection_box_union.MaxEdge.Z / BS - 0.5f); +} + + +void NodeDefManager::eraseIdFromGroups(content_t id) +{ + // For all groups in m_group_to_items... + for (auto iter_groups = m_group_to_items.begin(); + iter_groups != m_group_to_items.end();) { + // Get the group items vector. + std::vector<content_t> &items = iter_groups->second; + + // Remove any occurence of the id in the group items vector. + items.erase(std::remove(items.begin(), items.end(), id), items.end()); + + // If group is empty, erase its vector from the map. + if (items.empty()) + iter_groups = m_group_to_items.erase(iter_groups); + else + ++iter_groups; + } +} + + +// IWritableNodeDefManager +content_t NodeDefManager::set(const std::string &name, const ContentFeatures &def) +{ + // Pre-conditions + assert(name != ""); + assert(name != "ignore"); + assert(name == def.name); + + content_t id = CONTENT_IGNORE; + if (!m_name_id_mapping.getId(name, id)) { // ignore aliases + // Get new id + id = allocateId(); + if (id == CONTENT_IGNORE) { + warningstream << "NodeDefManager: Absolute " + "limit reached" << std::endl; + return CONTENT_IGNORE; + } + assert(id != CONTENT_IGNORE); + addNameIdMapping(id, name); + } + + // If there is already ContentFeatures registered for this id, clear old groups + if (id < m_content_features.size()) + eraseIdFromGroups(id); + + m_content_features[id] = def; + verbosestream << "NodeDefManager: registering content id \"" << id + << "\": name=\"" << def.name << "\""<<std::endl; + + getNodeBoxUnion(def.selection_box, def, &m_selection_box_union); + fixSelectionBoxIntUnion(); + + // Add this content to the list of all groups it belongs to + for (const auto &group : def.groups) { + const std::string &group_name = group.first; + m_group_to_items[group_name].push_back(id); + } + + return id; +} + + +content_t NodeDefManager::allocateDummy(const std::string &name) +{ + assert(name != ""); // Pre-condition + ContentFeatures f; + f.name = name; + return set(name, f); +} + + +void NodeDefManager::removeNode(const std::string &name) +{ + // Pre-condition + assert(name != ""); + + // Erase name from name ID mapping + content_t id = CONTENT_IGNORE; + if (m_name_id_mapping.getId(name, id)) { + m_name_id_mapping.eraseName(name); + m_name_id_mapping_with_aliases.erase(name); + } + + eraseIdFromGroups(id); +} + + +void NodeDefManager::updateAliases(IItemDefManager *idef) +{ + std::set<std::string> all; + idef->getAll(all); + m_name_id_mapping_with_aliases.clear(); + for (const std::string &name : all) { + const std::string &convert_to = idef->getAlias(name); + content_t id; + if (m_name_id_mapping.getId(convert_to, id)) { + m_name_id_mapping_with_aliases.insert( + std::make_pair(name, id)); + } + } +} + +void NodeDefManager::applyTextureOverrides(const std::vector<TextureOverride> &overrides) +{ + infostream << "NodeDefManager::applyTextureOverrides(): Applying " + "overrides to textures" << std::endl; + + for (const TextureOverride& texture_override : overrides) { + content_t id; + if (!getId(texture_override.id, id)) + continue; // Ignore unknown node + + ContentFeatures &nodedef = m_content_features[id]; + + // Override tiles + if (texture_override.hasTarget(OverrideTarget::TOP)) + nodedef.tiledef[0].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::BOTTOM)) + nodedef.tiledef[1].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::RIGHT)) + nodedef.tiledef[2].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::LEFT)) + nodedef.tiledef[3].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::BACK)) + nodedef.tiledef[4].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::FRONT)) + nodedef.tiledef[5].name = texture_override.texture; + + + // Override special tiles, if applicable + if (texture_override.hasTarget(OverrideTarget::SPECIAL_1)) + nodedef.tiledef_special[0].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::SPECIAL_2)) + nodedef.tiledef_special[1].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::SPECIAL_3)) + nodedef.tiledef_special[2].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::SPECIAL_4)) + nodedef.tiledef_special[3].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::SPECIAL_5)) + nodedef.tiledef_special[4].name = texture_override.texture; + + if (texture_override.hasTarget(OverrideTarget::SPECIAL_6)) + nodedef.tiledef_special[5].name = texture_override.texture; + } +} + +void NodeDefManager::updateTextures(IGameDef *gamedef, void *progress_callback_args) +{ +#ifndef SERVER + infostream << "NodeDefManager::updateTextures(): Updating " + "textures in node definitions" << std::endl; + + Client *client = (Client *)gamedef; + ITextureSource *tsrc = client->tsrc(); + IShaderSource *shdsrc = client->getShaderSource(); + auto smgr = client->getSceneManager(); + scene::IMeshManipulator *meshmanip = smgr->getMeshManipulator(); + TextureSettings tsettings; + tsettings.readSettings(); + + u32 size = m_content_features.size(); + + for (u32 i = 0; i < size; i++) { + ContentFeatures *f = &(m_content_features[i]); + f->updateTextures(tsrc, shdsrc, meshmanip, client, tsettings); + client->showUpdateProgressTexture(progress_callback_args, i, size); + } +#endif +} + +void NodeDefManager::serialize(std::ostream &os, u16 protocol_version) const +{ + writeU8(os, 1); // version + u16 count = 0; + std::ostringstream os2(std::ios::binary); + for (u32 i = 0; i < m_content_features.size(); i++) { + if (i == CONTENT_IGNORE || i == CONTENT_AIR + || i == CONTENT_UNKNOWN) + continue; + const ContentFeatures *f = &m_content_features[i]; + if (f->name.empty()) + continue; + writeU16(os2, i); + // Wrap it in a string to allow different lengths without + // strict version incompatibilities + std::ostringstream wrapper_os(std::ios::binary); + f->serialize(wrapper_os, protocol_version); + os2<<serializeString16(wrapper_os.str()); + + // must not overflow + u16 next = count + 1; + FATAL_ERROR_IF(next < count, "Overflow"); + count++; + } + writeU16(os, count); + os << serializeString32(os2.str()); +} + + +void NodeDefManager::deSerialize(std::istream &is, u16 protocol_version) +{ + clear(); + + if (readU8(is) < 1) + throw SerializationError("unsupported NodeDefinitionManager version"); + + u16 count = readU16(is); + std::istringstream is2(deSerializeString32(is), std::ios::binary); + ContentFeatures f; + for (u16 n = 0; n < count; n++) { + u16 i = readU16(is2); + + // Read it from the string wrapper + std::string wrapper = deSerializeString16(is2); + std::istringstream wrapper_is(wrapper, std::ios::binary); + f.deSerialize(wrapper_is, protocol_version); + + // Check error conditions + if (i == CONTENT_IGNORE || i == CONTENT_AIR || i == CONTENT_UNKNOWN) { + warningstream << "NodeDefManager::deSerialize(): " + "not changing builtin node " << i << std::endl; + continue; + } + if (f.name.empty()) { + warningstream << "NodeDefManager::deSerialize(): " + "received empty name" << std::endl; + continue; + } + + // Ignore aliases + u16 existing_id; + if (m_name_id_mapping.getId(f.name, existing_id) && i != existing_id) { + warningstream << "NodeDefManager::deSerialize(): " + "already defined with different ID: " << f.name << std::endl; + continue; + } + + // All is ok, add node definition with the requested ID + if (i >= m_content_features.size()) + m_content_features.resize((u32)(i) + 1); + m_content_features[i] = f; + addNameIdMapping(i, f.name); + TRACESTREAM(<< "NodeDef: deserialized " << f.name << std::endl); + + getNodeBoxUnion(f.selection_box, f, &m_selection_box_union); + fixSelectionBoxIntUnion(); + } + + // Since liquid_alternative_flowing_id and liquid_alternative_source_id + // are not sent, resolve them client-side too. + resolveCrossrefs(); +} + + +void NodeDefManager::addNameIdMapping(content_t i, const std::string &name) +{ + m_name_id_mapping.set(i, name); + m_name_id_mapping_with_aliases.emplace(name, i); +} + + +NodeDefManager *createNodeDefManager() +{ + return new NodeDefManager(); +} + + +void NodeDefManager::pendNodeResolve(NodeResolver *nr) const +{ + nr->m_ndef = this; + if (m_node_registration_complete) + nr->nodeResolveInternal(); + else + m_pending_resolve_callbacks.push_back(nr); +} + + +bool NodeDefManager::cancelNodeResolveCallback(NodeResolver *nr) const +{ + size_t len = m_pending_resolve_callbacks.size(); + for (size_t i = 0; i != len; i++) { + if (nr != m_pending_resolve_callbacks[i]) + continue; + + len--; + m_pending_resolve_callbacks[i] = m_pending_resolve_callbacks[len]; + m_pending_resolve_callbacks.resize(len); + return true; + } + + return false; +} + + +void NodeDefManager::runNodeResolveCallbacks() +{ + for (size_t i = 0; i != m_pending_resolve_callbacks.size(); i++) { + NodeResolver *nr = m_pending_resolve_callbacks[i]; + nr->nodeResolveInternal(); + } + + m_pending_resolve_callbacks.clear(); +} + + +void NodeDefManager::resetNodeResolveState() +{ + m_node_registration_complete = false; + m_pending_resolve_callbacks.clear(); +} + +static void removeDupes(std::vector<content_t> &list) +{ + std::sort(list.begin(), list.end()); + auto new_end = std::unique(list.begin(), list.end()); + list.erase(new_end, list.end()); +} + +void NodeDefManager::resolveCrossrefs() +{ + for (ContentFeatures &f : m_content_features) { + if (f.liquid_type != LIQUID_NONE || f.drawtype == NDT_LIQUID || f.drawtype == NDT_FLOWINGLIQUID) { + f.liquid_alternative_flowing_id = getId(f.liquid_alternative_flowing); + f.liquid_alternative_source_id = getId(f.liquid_alternative_source); + continue; + } + if (f.drawtype != NDT_NODEBOX || f.node_box.type != NODEBOX_CONNECTED) + continue; + + for (const std::string &name : f.connects_to) { + getIds(name, f.connects_to_ids); + } + removeDupes(f.connects_to_ids); + } +} + +bool NodeDefManager::nodeboxConnects(MapNode from, MapNode to, + u8 connect_face) const +{ + const ContentFeatures &f1 = get(from); + + if ((f1.drawtype != NDT_NODEBOX) || (f1.node_box.type != NODEBOX_CONNECTED)) + return false; + + // lookup target in connected set + if (!CONTAINS(f1.connects_to_ids, to.param0)) + return false; + + const ContentFeatures &f2 = get(to); + + if ((f2.drawtype == NDT_NODEBOX) && (f2.node_box.type == NODEBOX_CONNECTED)) + // ignores actually looking if back connection exists + return CONTAINS(f2.connects_to_ids, from.param0); + + // does to node declare usable faces? + if (f2.connect_sides > 0) { + if ((f2.param_type_2 == CPT2_FACEDIR || + f2.param_type_2 == CPT2_COLORED_FACEDIR) + && (connect_face >= 4)) { + static const u8 rot[33 * 4] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 32, 16, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // 4 - back + 8, 4, 32, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // 8 - right + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 8, 4, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // 16 - front + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 32, 16, 8, 4 // 32 - left + }; + return (f2.connect_sides + & rot[(connect_face * 4) + (to.param2 & 0x1F)]); + } + return (f2.connect_sides & connect_face); + } + // the target is just a regular node, so connect no matter back connection + return true; +} + +//// +//// NodeResolver +//// + +NodeResolver::NodeResolver() +{ + reset(); +} + + +NodeResolver::~NodeResolver() +{ + if (!m_resolve_done && m_ndef) + m_ndef->cancelNodeResolveCallback(this); +} + + +void NodeResolver::cloneTo(NodeResolver *res) const +{ + FATAL_ERROR_IF(!m_resolve_done, "NodeResolver can only be cloned" + " after resolving has completed"); + /* We don't actually do anything significant. Since the node resolving has + * already completed, the class that called us will already have the + * resolved IDs in its data structures (which it copies on its own) */ + res->m_ndef = m_ndef; + res->m_resolve_done = true; +} + + +void NodeResolver::nodeResolveInternal() +{ + m_nodenames_idx = 0; + m_nnlistsizes_idx = 0; + + resolveNodeNames(); + m_resolve_done = true; + + m_nodenames.clear(); + m_nnlistsizes.clear(); +} + + +bool NodeResolver::getIdFromNrBacklog(content_t *result_out, + const std::string &node_alt, content_t c_fallback, bool error_on_fallback) +{ + if (m_nodenames_idx == m_nodenames.size()) { + *result_out = c_fallback; + errorstream << "NodeResolver: no more nodes in list" << std::endl; + return false; + } + + content_t c; + std::string name = m_nodenames[m_nodenames_idx++]; + + bool success = m_ndef->getId(name, c); + if (!success && !node_alt.empty()) { + name = node_alt; + success = m_ndef->getId(name, c); + } + + if (!success) { + if (error_on_fallback) + errorstream << "NodeResolver: failed to resolve node name '" << name + << "'." << std::endl; + c = c_fallback; + } + + *result_out = c; + return success; +} + + +bool NodeResolver::getIdsFromNrBacklog(std::vector<content_t> *result_out, + bool all_required, content_t c_fallback) +{ + bool success = true; + + if (m_nnlistsizes_idx == m_nnlistsizes.size()) { + errorstream << "NodeResolver: no more node lists" << std::endl; + return false; + } + + size_t length = m_nnlistsizes[m_nnlistsizes_idx++]; + + while (length--) { + if (m_nodenames_idx == m_nodenames.size()) { + errorstream << "NodeResolver: no more nodes in list" << std::endl; + return false; + } + + content_t c; + std::string &name = m_nodenames[m_nodenames_idx++]; + + if (name.substr(0,6) != "group:") { + if (m_ndef->getId(name, c)) { + result_out->push_back(c); + } else if (all_required) { + errorstream << "NodeResolver: failed to resolve node name '" + << name << "'." << std::endl; + result_out->push_back(c_fallback); + success = false; + } + } else { + m_ndef->getIds(name, *result_out); + } + } + + return success; +} + +void NodeResolver::reset(bool resolve_done) +{ + m_nodenames.clear(); + m_nodenames_idx = 0; + m_nnlistsizes.clear(); + m_nnlistsizes_idx = 0; + + m_resolve_done = resolve_done; + + m_nodenames.reserve(16); + m_nnlistsizes.reserve(4); +} diff --git a/src/nodedef.h b/src/nodedef.h new file mode 100644 index 0000000..f4367cb --- /dev/null +++ b/src/nodedef.h @@ -0,0 +1,867 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +#include <string> +#include <iostream> +#include <map> +#include "mapnode.h" +#include "nameidmapping.h" +#ifndef SERVER +#include "client/tile.h" +#include <IMeshManipulator.h> +class Client; +#endif +#include "itemgroup.h" +#include "sound.h" // SimpleSoundSpec +#include "constants.h" // BS +#include "texture_override.h" // TextureOverride +#include "tileanimation.h" + +class IItemDefManager; +class ITextureSource; +class IShaderSource; +class IGameDef; +class NodeResolver; +#if BUILD_UNITTESTS +class TestSchematic; +#endif + +enum ContentParamType +{ + CPT_NONE, + CPT_LIGHT, +}; + +enum ContentParamType2 +{ + CPT2_NONE, + // Need 8-bit param2 + CPT2_FULL, + // Flowing liquid properties + CPT2_FLOWINGLIQUID, + // Direction for chests and furnaces and such + CPT2_FACEDIR, + // Direction for signs, torches and such + CPT2_WALLMOUNTED, + // Block level like FLOWINGLIQUID + CPT2_LEVELED, + // 2D rotation + CPT2_DEGROTATE, + // Mesh options for plants + CPT2_MESHOPTIONS, + // Index for palette + CPT2_COLOR, + // 3 bits of palette index, then facedir + CPT2_COLORED_FACEDIR, + // 5 bits of palette index, then wallmounted + CPT2_COLORED_WALLMOUNTED, + // Glasslike framed drawtype internal liquid level, param2 values 0 to 63 + CPT2_GLASSLIKE_LIQUID_LEVEL, + // 3 bits of palette index, then degrotate + CPT2_COLORED_DEGROTATE, +}; + +enum LiquidType +{ + LIQUID_NONE, + LIQUID_FLOWING, + LIQUID_SOURCE, +}; + +enum NodeBoxType +{ + NODEBOX_REGULAR, // Regular block; allows buildable_to + NODEBOX_FIXED, // Static separately defined box(es) + NODEBOX_WALLMOUNTED, // Box for wall mounted nodes; (top, bottom, side) + NODEBOX_LEVELED, // Same as fixed, but with dynamic height from param2. for snow, ... + NODEBOX_CONNECTED, // optionally draws nodeboxes if a neighbor node attaches +}; + +struct NodeBoxConnected +{ + std::vector<aabb3f> connect_top; + std::vector<aabb3f> connect_bottom; + std::vector<aabb3f> connect_front; + std::vector<aabb3f> connect_left; + std::vector<aabb3f> connect_back; + std::vector<aabb3f> connect_right; + std::vector<aabb3f> disconnected_top; + std::vector<aabb3f> disconnected_bottom; + std::vector<aabb3f> disconnected_front; + std::vector<aabb3f> disconnected_left; + std::vector<aabb3f> disconnected_back; + std::vector<aabb3f> disconnected_right; + std::vector<aabb3f> disconnected; + std::vector<aabb3f> disconnected_sides; +}; + +struct NodeBox +{ + enum NodeBoxType type; + // NODEBOX_REGULAR (no parameters) + // NODEBOX_FIXED + std::vector<aabb3f> fixed; + // NODEBOX_WALLMOUNTED + aabb3f wall_top; + aabb3f wall_bottom; + aabb3f wall_side; // being at the -X side + // NODEBOX_CONNECTED + // (kept externally to not bloat the structure) + std::shared_ptr<NodeBoxConnected> connected; + + NodeBox() + { reset(); } + ~NodeBox() = default; + + inline NodeBoxConnected &getConnected() { + if (!connected) + connected = std::make_shared<NodeBoxConnected>(); + return *connected; + } + inline const NodeBoxConnected &getConnected() const { + assert(connected); + return *connected; + } + + void reset(); + void serialize(std::ostream &os, u16 protocol_version) const; + void deSerialize(std::istream &is); +}; + +struct MapNode; +class NodeMetadata; + +enum LeavesStyle { + LEAVES_FANCY, + LEAVES_SIMPLE, + LEAVES_OPAQUE, +}; + +enum AutoScale : u8 { + AUTOSCALE_DISABLE, + AUTOSCALE_ENABLE, + AUTOSCALE_FORCE, +}; + +enum WorldAlignMode : u8 { + WORLDALIGN_DISABLE, + WORLDALIGN_ENABLE, + WORLDALIGN_FORCE, + WORLDALIGN_FORCE_NODEBOX, +}; + +class TextureSettings { +public: + LeavesStyle leaves_style; + WorldAlignMode world_aligned_mode; + AutoScale autoscale_mode; + int node_texture_size; + bool opaque_water; + bool connected_glass; + bool enable_mesh_cache; + bool enable_minimap; + + TextureSettings() = default; + + void readSettings(); +}; + +enum NodeDrawType +{ + // A basic solid block + NDT_NORMAL, + // Nothing is drawn + NDT_AIRLIKE, + // Do not draw face towards same kind of flowing/source liquid + NDT_LIQUID, + // A very special kind of thing + NDT_FLOWINGLIQUID, + // Glass-like, don't draw faces towards other glass + NDT_GLASSLIKE, + // Leaves-like, draw all faces no matter what + NDT_ALLFACES, + // Enabled -> ndt_allfaces, disabled -> ndt_normal + NDT_ALLFACES_OPTIONAL, + // Single plane perpendicular to a surface + NDT_TORCHLIKE, + // Single plane parallel to a surface + NDT_SIGNLIKE, + // 2 vertical planes in a 'X' shape diagonal to XZ axes. + // paramtype2 = "meshoptions" allows various forms, sizes and + // vertical and horizontal random offsets. + NDT_PLANTLIKE, + // Fenceposts that connect to neighbouring fenceposts with horizontal bars + NDT_FENCELIKE, + // Selects appropriate junction texture to connect like rails to + // neighbouring raillikes. + NDT_RAILLIKE, + // Custom Lua-definable structure of multiple cuboids + NDT_NODEBOX, + // Glass-like, draw connected frames and all visible faces. + // param2 > 0 defines 64 levels of internal liquid + // Uses 3 textures, one for frames, second for faces, + // optional third is a 'special tile' for the liquid. + NDT_GLASSLIKE_FRAMED, + // Draw faces slightly rotated and only on neighbouring nodes + NDT_FIRELIKE, + // Enabled -> ndt_glasslike_framed, disabled -> ndt_glasslike + NDT_GLASSLIKE_FRAMED_OPTIONAL, + // Uses static meshes + NDT_MESH, + // Combined plantlike-on-solid + NDT_PLANTLIKE_ROOTED, +}; + +// Mesh options for NDT_PLANTLIKE with CPT2_MESHOPTIONS +static const u8 MO_MASK_STYLE = 0x07; +static const u8 MO_BIT_RANDOM_OFFSET = 0x08; +static const u8 MO_BIT_SCALE_SQRT2 = 0x10; +static const u8 MO_BIT_RANDOM_OFFSET_Y = 0x20; +enum PlantlikeStyle { + PLANT_STYLE_CROSS, + PLANT_STYLE_CROSS2, + PLANT_STYLE_STAR, + PLANT_STYLE_HASH, + PLANT_STYLE_HASH2, +}; + +enum AlignStyle : u8 { + ALIGN_STYLE_NODE, + ALIGN_STYLE_WORLD, + ALIGN_STYLE_USER_DEFINED, +}; + +enum AlphaMode : u8 { + ALPHAMODE_BLEND, + ALPHAMODE_CLIP, + ALPHAMODE_OPAQUE, + ALPHAMODE_LEGACY_COMPAT, /* means either opaque or clip */ +}; + + +/* + Stand-alone definition of a TileSpec (basically a server-side TileSpec) +*/ + +struct TileDef +{ + std::string name = ""; + bool backface_culling = true; // Takes effect only in special cases + bool tileable_horizontal = true; + bool tileable_vertical = true; + //! If true, the tile has its own color. + bool has_color = false; + //! The color of the tile. + video::SColor color = video::SColor(0xFFFFFFFF); + AlignStyle align_style = ALIGN_STYLE_NODE; + u8 scale = 0; + + struct TileAnimationParams animation; + + TileDef() + { + animation.type = TAT_NONE; + } + + void serialize(std::ostream &os, u16 protocol_version) const; + void deSerialize(std::istream &is, NodeDrawType drawtype, u16 protocol_version); +}; + +// Defines the number of special tiles per nodedef +// +// NOTE: When changing this value, the enum entries of OverrideTarget and +// parser in TextureOverrideSource must be updated so that all special +// tiles can be overridden. +#define CF_SPECIAL_COUNT 6 + +struct ContentFeatures +{ + // PROTOCOL_VERSION >= 37. This is legacy and should not be increased anymore, + // write checks that depend directly on the protocol version instead. + static const u8 CONTENTFEATURES_VERSION = 13; + + /* + Cached stuff + */ +#ifndef SERVER + // 0 1 2 3 4 5 + // up down right left back front + TileSpec tiles[6]; + // Special tiles + TileSpec special_tiles[CF_SPECIAL_COUNT]; + u8 solidness; // Used when choosing which face is drawn + u8 visual_solidness; // When solidness=0, this tells how it looks like + bool backface_culling; +#endif + + // Server-side cached callback existence for fast skipping + bool has_on_construct; + bool has_on_destruct; + bool has_after_destruct; + + /* + Actual data + */ + + // --- GENERAL PROPERTIES --- + + std::string name; // "" = undefined node + ItemGroupList groups; // Same as in itemdef + // Type of MapNode::param1 + ContentParamType param_type; + // Type of MapNode::param2 + ContentParamType2 param_type_2; + + // --- VISUAL PROPERTIES --- + + enum NodeDrawType drawtype; + std::string mesh; +#ifndef SERVER + scene::IMesh *mesh_ptr[24]; + video::SColor minimap_color; +#endif + float visual_scale; // Misc. scale parameter + TileDef tiledef[6]; + // These will be drawn over the base tiles. + TileDef tiledef_overlay[6]; + TileDef tiledef_special[CF_SPECIAL_COUNT]; // eg. flowing liquid + AlphaMode alpha; + // The color of the node. + video::SColor color; + std::string palette_name; + std::vector<video::SColor> *palette; + // Used for waving leaves/plants + u8 waving; + // for NDT_CONNECTED pairing + u8 connect_sides; + std::vector<std::string> connects_to; + std::vector<content_t> connects_to_ids; + // Post effect color, drawn when the camera is inside the node. + video::SColor post_effect_color; + // Flowing liquid or leveled nodebox, value = default level + u8 leveled; + // Maximum value for leveled nodes + u8 leveled_max; + + // --- LIGHTING-RELATED --- + + bool light_propagates; + bool sunlight_propagates; + // Amount of light the node emits + u8 light_source; + + // --- MAP GENERATION --- + + // True for all ground-like things like stone and mud, false for eg. trees + bool is_ground_content; + + // --- INTERACTION PROPERTIES --- + + // This is used for collision detection. + // Also for general solidness queries. + bool walkable; + // Player can point to these + bool pointable; + // Player can dig these + bool diggable; + // Player can climb these + bool climbable; + // Player can build on these + bool buildable_to; + // Player cannot build to these (placement prediction disabled) + bool rightclickable; + u32 damage_per_second; + // client dig prediction + std::string node_dig_prediction; + // how slow players move through + u8 move_resistance = 0; + + // --- LIQUID PROPERTIES --- + + // Whether the node is non-liquid, source liquid or flowing liquid + enum LiquidType liquid_type; + // If true, movement (e.g. of players) inside this node is liquid-like. + bool liquid_move_physics; + // If the content is liquid, this is the flowing version of the liquid. + std::string liquid_alternative_flowing; + content_t liquid_alternative_flowing_id; + // If the content is liquid, this is the source version of the liquid. + std::string liquid_alternative_source; + content_t liquid_alternative_source_id; + // Viscosity for fluid flow, ranging from 1 to 7, with + // 1 giving almost instantaneous propagation and 7 being + // the slowest possible + u8 liquid_viscosity; + // Is liquid renewable (new liquid source will be created between 2 existing) + bool liquid_renewable; + // Number of flowing liquids surrounding source + u8 liquid_range; + u8 drowning; + // Liquids flow into and replace node + bool floodable; + + // --- NODEBOXES --- + + NodeBox node_box; + NodeBox selection_box; + NodeBox collision_box; + + // --- SOUND PROPERTIES --- + + SimpleSoundSpec sound_footstep; + SimpleSoundSpec sound_dig; + SimpleSoundSpec sound_dug; + + // --- LEGACY --- + + // Compatibility with old maps + // Set to true if paramtype used to be 'facedir_simple' + bool legacy_facedir_simple; + // Set to true if wall_mounted used to be set to true + bool legacy_wallmounted; + + /* + Methods + */ + + ContentFeatures(); + ~ContentFeatures(); + void reset(); + void serialize(std::ostream &os, u16 protocol_version) const; + void deSerialize(std::istream &is, u16 protocol_version); + + /* + Some handy methods + */ + void setDefaultAlphaMode() + { + switch (drawtype) { + case NDT_NORMAL: + case NDT_LIQUID: + case NDT_FLOWINGLIQUID: + alpha = ALPHAMODE_OPAQUE; + break; + case NDT_NODEBOX: + case NDT_MESH: + alpha = ALPHAMODE_LEGACY_COMPAT; // this should eventually be OPAQUE + break; + default: + alpha = ALPHAMODE_CLIP; + break; + } + } + + bool needsBackfaceCulling() const + { + switch (drawtype) { + case NDT_TORCHLIKE: + case NDT_SIGNLIKE: + case NDT_FIRELIKE: + case NDT_RAILLIKE: + case NDT_PLANTLIKE: + case NDT_PLANTLIKE_ROOTED: + case NDT_MESH: + return false; + default: + return true; + } + } + + bool isLiquid() const{ + return (liquid_type != LIQUID_NONE); + } + bool sameLiquid(const ContentFeatures &f) const{ + if(!isLiquid() || !f.isLiquid()) return false; + return (liquid_alternative_flowing_id == f.liquid_alternative_flowing_id); + } + + bool lightingEquivalent(const ContentFeatures &other) const { + return light_propagates == other.light_propagates + && sunlight_propagates == other.sunlight_propagates + && light_source == other.light_source; + } + + int getGroup(const std::string &group) const + { + return itemgroup_get(groups, group); + } + +#ifndef SERVER + void updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc, + scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings); +#endif + +private: +#ifndef SERVER + /* + * Checks if any tile texture has any transparent pixels. + * Prints a warning and returns true if that is the case, false otherwise. + * This is supposed to be used for use_texture_alpha backwards compatibility. + */ + bool textureAlphaCheck(ITextureSource *tsrc, const TileDef *tiles, + int length); +#endif + + void setAlphaFromLegacy(u8 legacy_alpha); + + u8 getAlphaForLegacy() const; +}; + +/*! + * @brief This class is for getting the actual properties of nodes from their + * content ID. + * + * @details The nodes on the map are represented by three numbers (see MapNode). + * The first number (param0) is the type of a node. All node types have own + * properties (see ContentFeatures). This class is for storing and getting the + * properties of nodes. + * The manager is first filled with registered nodes, then as the game begins, + * functions only get `const` pointers to it, to prevent modification of + * registered nodes. + */ +class NodeDefManager { +public: + /*! + * Creates a NodeDefManager, and registers three ContentFeatures: + * \ref CONTENT_AIR, \ref CONTENT_UNKNOWN and \ref CONTENT_IGNORE. + */ + NodeDefManager(); + ~NodeDefManager(); + + /*! + * Returns the properties for the given content type. + * @param c content type of a node + * @return properties of the given content type, or \ref CONTENT_UNKNOWN + * if the given content type is not registered. + */ + inline const ContentFeatures& get(content_t c) const { + return + (c < m_content_features.size() && !m_content_features[c].name.empty()) ? + m_content_features[c] : m_content_features[CONTENT_UNKNOWN]; + } + + /*! + * Returns the properties of the given node. + * @param n a map node + * @return properties of the given node or @ref CONTENT_UNKNOWN if the + * given content type is not registered. + */ + inline const ContentFeatures& get(const MapNode &n) const { + return get(n.getContent()); + } + + /*! + * Returns the node properties for a node name. + * @param name name of a node + * @return properties of the given node or @ref CONTENT_UNKNOWN if + * not found + */ + const ContentFeatures& get(const std::string &name) const; + + /*! + * Returns the content ID for the given name. + * @param name a node name + * @param[out] result will contain the content ID if found, otherwise + * remains unchanged + * @return true if the ID was found, false otherwise + */ + bool getId(const std::string &name, content_t &result) const; + + /*! + * Returns the content ID for the given name. + * @param name a node name + * @return ID of the node or @ref CONTENT_IGNORE if not found + */ + content_t getId(const std::string &name) const; + + /*! + * Returns the content IDs of the given node name or node group name. + * Group names start with "group:". + * @param name a node name or node group name + * @param[out] result will be appended with matching IDs + * @return true if `name` is a valid node name or a (not necessarily + * valid) group name + */ + bool getIds(const std::string &name, std::vector<content_t> &result) const; + + /*! + * Returns the smallest box in integer node coordinates that + * contains all nodes' selection boxes. The returned box might be larger + * than the minimal size if the largest node is removed from the manager. + */ + inline core::aabbox3d<s16> getSelectionBoxIntUnion() const { + return m_selection_box_int_union; + } + + /*! + * Checks whether a node connects to an adjacent node. + * @param from the node to be checked + * @param to the adjacent node + * @param connect_face a bit field indicating which face of the node is + * adjacent to the other node. + * Bits: +y (least significant), -y, -z, -x, +z, +x (most significant). + * @return true if the node connects, false otherwise + */ + bool nodeboxConnects(MapNode from, MapNode to, + u8 connect_face) const; + + /*! + * Registers a NodeResolver to wait for the registration of + * ContentFeatures. Once the node registration finishes, all + * listeners are notified. + */ + void pendNodeResolve(NodeResolver *nr) const; + + /*! + * Stops listening to the NodeDefManager. + * @return true if the listener was registered before, false otherwise + */ + bool cancelNodeResolveCallback(NodeResolver *nr) const; + + /*! + * Registers a new node type with the given name and allocates a new + * content ID. + * Should not be called with an already existing name. + * @param name name of the node, must match with `def.name`. + * @param def definition of the registered node type. + * @return ID of the registered node or @ref CONTENT_IGNORE if + * the function could not allocate an ID. + */ + content_t set(const std::string &name, const ContentFeatures &def); + + /*! + * Allocates a blank node ID for the given name. + * @param name name of a node + * @return allocated ID or @ref CONTENT_IGNORE if could not allocate + * an ID. + */ + content_t allocateDummy(const std::string &name); + + /*! + * Removes the given node name from the manager. + * The node ID will remain in the manager, but won't be linked to any name. + * @param name name to be removed + */ + void removeNode(const std::string &name); + + /*! + * Regenerates the alias list (a map from names to node IDs). + * @param idef the item definition manager containing alias information + */ + void updateAliases(IItemDefManager *idef); + + /*! + * Replaces the textures of registered nodes with the ones specified in + * the texturepack's override.txt file + * + * @param overrides the texture overrides + */ + void applyTextureOverrides(const std::vector<TextureOverride> &overrides); + + /*! + * Only the client uses this. Loads textures and shaders required for + * rendering the nodes. + * @param gamedef must be a Client. + * @param progress_cbk called each time a node is loaded. Arguments: + * `progress_cbk_args`, number of loaded ContentFeatures, number of + * total ContentFeatures. + * @param progress_cbk_args passed to the callback function + */ + void updateTextures(IGameDef *gamedef, void *progress_cbk_args); + + /*! + * Writes the content of this manager to the given output stream. + * @param protocol_version Active network protocol version + */ + void serialize(std::ostream &os, u16 protocol_version) const; + + /*! + * Restores the manager from a serialized stream. + * This clears the previous state. + * @param is input stream containing a serialized NodeDefManager + * @param protocol_version Active network protocol version + */ + void deSerialize(std::istream &is, u16 protocol_version); + + /*! + * Used to indicate that node registration has finished. + * @param completed tells whether registration is complete + */ + inline void setNodeRegistrationStatus(bool completed) { + m_node_registration_complete = completed; + } + + /*! + * Notifies the registered NodeResolver instances that node registration + * has finished, then unregisters all listeners. + * Must be called after node registration has finished! + */ + void runNodeResolveCallbacks(); + + /*! + * Sets the registration completion flag to false and unregisters all + * NodeResolver instances listening to the manager. + */ + void resetNodeResolveState(); + + /*! + * Resolves (caches the IDs) cross-references between nodes, + * like liquid alternatives. + * Must be called after node registration has finished! + */ + void resolveCrossrefs(); + +private: + /*! + * Resets the manager to its initial state. + * See the documentation of the constructor. + */ + void clear(); + + /*! + * Allocates a new content ID, and returns it. + * @return the allocated ID or \ref CONTENT_IGNORE if could not allocate + */ + content_t allocateId(); + + /*! + * Binds the given content ID and node name. + * Registers them in \ref m_name_id_mapping and + * \ref m_name_id_mapping_with_aliases. + * @param i a content ID + * @param name a node name + */ + void addNameIdMapping(content_t i, const std::string &name); + + /*! + * Removes a content ID from all groups. + * Erases content IDs from vectors in \ref m_group_to_items and + * removes empty vectors. + * @param id Content ID + */ + void eraseIdFromGroups(content_t id); + + /*! + * Recalculates m_selection_box_int_union based on + * m_selection_box_union. + */ + void fixSelectionBoxIntUnion(); + + //! Features indexed by ID. + std::vector<ContentFeatures> m_content_features; + + //! A mapping for fast conversion between names and IDs + NameIdMapping m_name_id_mapping; + + /*! + * Like @ref m_name_id_mapping, but maps only from names to IDs, and + * includes aliases too. Updated by \ref updateAliases(). + * Note: Not serialized. + */ + std::unordered_map<std::string, content_t> m_name_id_mapping_with_aliases; + + /*! + * A mapping from group names to a vector of content types that belong + * to it. Necessary for a direct lookup in \ref getIds(). + * Note: Not serialized. + */ + std::unordered_map<std::string, std::vector<content_t>> m_group_to_items; + + /*! + * The next ID that might be free to allocate. + * It can be allocated already, because \ref CONTENT_AIR, + * \ref CONTENT_UNKNOWN and \ref CONTENT_IGNORE are registered when the + * manager is initialized, and new IDs are allocated from 0. + */ + content_t m_next_id; + + //! True if all nodes have been registered. + bool m_node_registration_complete; + + /*! + * The union of all nodes' selection boxes. + * Might be larger if big nodes are removed from the manager. + */ + aabb3f m_selection_box_union; + + /*! + * The smallest box in integer node coordinates that + * contains all nodes' selection boxes. + * Might be larger if big nodes are removed from the manager. + */ + core::aabbox3d<s16> m_selection_box_int_union; + + /*! + * NodeResolver instances to notify once node registration has finished. + * Even constant NodeDefManager instances can register listeners. + */ + mutable std::vector<NodeResolver *> m_pending_resolve_callbacks; +}; + +NodeDefManager *createNodeDefManager(); + +// NodeResolver: Queue for node names which are then translated +// to content_t after the NodeDefManager was initialized +class NodeResolver { +public: + NodeResolver(); + virtual ~NodeResolver(); + // Callback which is run as soon NodeDefManager is ready + virtual void resolveNodeNames() = 0; + + // required because this class is used as mixin for ObjDef + void cloneTo(NodeResolver *res) const; + + bool getIdFromNrBacklog(content_t *result_out, + const std::string &node_alt, content_t c_fallback, + bool error_on_fallback = true); + bool getIdsFromNrBacklog(std::vector<content_t> *result_out, + bool all_required = false, content_t c_fallback = CONTENT_IGNORE); + + inline bool isResolveDone() const { return m_resolve_done; } + void reset(bool resolve_done = false); + + // Vector containing all node names in the resolve "queue" + std::vector<std::string> m_nodenames; + // Specifies the "set size" of node names which are to be processed + // this is used for getIdsFromNrBacklog + // TODO: replace or remove + std::vector<size_t> m_nnlistsizes; + +protected: + friend class NodeDefManager; // m_ndef + + const NodeDefManager *m_ndef = nullptr; + // Index of the next "m_nodenames" entry to resolve + u32 m_nodenames_idx = 0; + +private: +#if BUILD_UNITTESTS + // Unittest requires access to m_resolve_done + friend class TestSchematic; +#endif + void nodeResolveInternal(); + + // Index of the next "m_nnlistsizes" entry to process + u32 m_nnlistsizes_idx = 0; + bool m_resolve_done = false; +}; diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp new file mode 100644 index 0000000..b5052c3 --- /dev/null +++ b/src/nodemetadata.cpp @@ -0,0 +1,258 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "nodemetadata.h" +#include "exceptions.h" +#include "gamedef.h" +#include "inventory.h" +#include "log.h" +#include "util/serialize.h" +#include "util/basic_macros.h" +#include "constants.h" // MAP_BLOCKSIZE +#include <sstream> + +/* + NodeMetadata +*/ + +NodeMetadata::NodeMetadata(IItemDefManager *item_def_mgr): + m_inventory(new Inventory(item_def_mgr)) +{} + +NodeMetadata::~NodeMetadata() +{ + delete m_inventory; +} + +void NodeMetadata::serialize(std::ostream &os, u8 version, bool disk) const +{ + int num_vars = disk ? m_stringvars.size() : countNonPrivate(); + writeU32(os, num_vars); + for (const auto &sv : m_stringvars) { + bool priv = isPrivate(sv.first); + if (!disk && priv) + continue; + + os << serializeString16(sv.first); + os << serializeString32(sv.second); + if (version >= 2) + writeU8(os, (priv) ? 1 : 0); + } + + m_inventory->serialize(os); +} + +void NodeMetadata::deSerialize(std::istream &is, u8 version) +{ + clear(); + int num_vars = readU32(is); + for(int i=0; i<num_vars; i++){ + std::string name = deSerializeString16(is); + std::string var = deSerializeString32(is); + m_stringvars[name] = var; + if (version >= 2) { + if (readU8(is) == 1) + markPrivate(name, true); + } + } + + m_inventory->deSerialize(is); +} + +void NodeMetadata::clear() +{ + Metadata::clear(); + m_privatevars.clear(); + m_inventory->clear(); +} + +bool NodeMetadata::empty() const +{ + return Metadata::empty() && m_inventory->getLists().empty(); +} + + +void NodeMetadata::markPrivate(const std::string &name, bool set) +{ + if (set) + m_privatevars.insert(name); + else + m_privatevars.erase(name); +} + +int NodeMetadata::countNonPrivate() const +{ + // m_privatevars can contain names not actually present + // DON'T: return m_stringvars.size() - m_privatevars.size(); + int n = 0; + for (const auto &sv : m_stringvars) { + if (!isPrivate(sv.first)) + n++; + } + return n; +} + +/* + NodeMetadataList +*/ + +void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk, + bool absolute_pos, bool include_empty) const +{ + /* + Version 0 is a placeholder for "nothing to see here; go away." + */ + + u16 count = include_empty ? m_data.size() : countNonEmpty(); + if (count == 0) { + writeU8(os, 0); // version + return; + } + + u8 version = (blockver > 27) ? 2 : 1; + writeU8(os, version); + writeU16(os, count); + + for (NodeMetadataMap::const_iterator + i = m_data.begin(); + i != m_data.end(); ++i) { + v3s16 p = i->first; + NodeMetadata *data = i->second; + if (!include_empty && data->empty()) + continue; + + if (absolute_pos) { + writeS16(os, p.X); + writeS16(os, p.Y); + writeS16(os, p.Z); + } else { + // Serialize positions within a mapblock + u16 p16 = (p.Z * MAP_BLOCKSIZE + p.Y) * MAP_BLOCKSIZE + p.X; + writeU16(os, p16); + } + data->serialize(os, version, disk); + } +} + +void NodeMetadataList::deSerialize(std::istream &is, + IItemDefManager *item_def_mgr, bool absolute_pos) +{ + clear(); + + u8 version = readU8(is); + + if (version == 0) { + // Nothing + return; + } + + if (version > 2) { + std::string err_str = std::string(FUNCTION_NAME) + + ": version " + itos(version) + " not supported"; + infostream << err_str << std::endl; + throw SerializationError(err_str); + } + + u16 count = readU16(is); + + for (u16 i = 0; i < count; i++) { + v3s16 p; + if (absolute_pos) { + p.X = readS16(is); + p.Y = readS16(is); + p.Z = readS16(is); + } else { + u16 p16 = readU16(is); + p.X = p16 & (MAP_BLOCKSIZE - 1); + p16 /= MAP_BLOCKSIZE; + p.Y = p16 & (MAP_BLOCKSIZE - 1); + p16 /= MAP_BLOCKSIZE; + p.Z = p16; + } + if (m_data.find(p) != m_data.end()) { + warningstream << "NodeMetadataList::deSerialize(): " + << "already set data at position " << PP(p) + << ": Ignoring." << std::endl; + continue; + } + + NodeMetadata *data = new NodeMetadata(item_def_mgr); + data->deSerialize(is, version); + m_data[p] = data; + } +} + +NodeMetadataList::~NodeMetadataList() +{ + clear(); +} + +std::vector<v3s16> NodeMetadataList::getAllKeys() +{ + std::vector<v3s16> keys; + keys.reserve(m_data.size()); + for (const auto &it : m_data) + keys.push_back(it.first); + + return keys; +} + +NodeMetadata *NodeMetadataList::get(v3s16 p) +{ + NodeMetadataMap::const_iterator n = m_data.find(p); + if (n == m_data.end()) + return nullptr; + return n->second; +} + +void NodeMetadataList::remove(v3s16 p) +{ + NodeMetadata *olddata = get(p); + if (olddata) { + if (m_is_metadata_owner) + delete olddata; + m_data.erase(p); + } +} + +void NodeMetadataList::set(v3s16 p, NodeMetadata *d) +{ + remove(p); + m_data.emplace(p, d); +} + +void NodeMetadataList::clear() +{ + if (m_is_metadata_owner) { + NodeMetadataMap::const_iterator it; + for (it = m_data.begin(); it != m_data.end(); ++it) + delete it->second; + } + m_data.clear(); +} + +int NodeMetadataList::countNonEmpty() const +{ + int n = 0; + for (const auto &it : m_data) { + if (!it.second->empty()) + n++; + } + return n; +} diff --git a/src/nodemetadata.h b/src/nodemetadata.h new file mode 100644 index 0000000..4b5b4d8 --- /dev/null +++ b/src/nodemetadata.h @@ -0,0 +1,117 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <unordered_set> +#include "metadata.h" + +/* + NodeMetadata stores arbitary amounts of data for special blocks. + Used for furnaces, chests and signs. + + There are two interaction methods: inventory menu and text input. + Only one can be used for a single metadata, thus only inventory OR + text input should exist in a metadata. +*/ + +class Inventory; +class IItemDefManager; + +class NodeMetadata : public Metadata +{ +public: + NodeMetadata(IItemDefManager *item_def_mgr); + ~NodeMetadata(); + + void serialize(std::ostream &os, u8 version, bool disk=true) const; + void deSerialize(std::istream &is, u8 version); + + void clear(); + bool empty() const; + + // The inventory + Inventory *getInventory() + { + return m_inventory; + } + + inline bool isPrivate(const std::string &name) const + { + return m_privatevars.count(name) != 0; + } + void markPrivate(const std::string &name, bool set); + +private: + int countNonPrivate() const; + + Inventory *m_inventory; + std::unordered_set<std::string> m_privatevars; +}; + + +/* + List of metadata of all the nodes of a block +*/ + +typedef std::map<v3s16, NodeMetadata *> NodeMetadataMap; + +class NodeMetadataList +{ +public: + NodeMetadataList(bool is_metadata_owner = true) : + m_is_metadata_owner(is_metadata_owner) + {} + + ~NodeMetadataList(); + + void serialize(std::ostream &os, u8 blockver, bool disk = true, + bool absolute_pos = false, bool include_empty = false) const; + void deSerialize(std::istream &is, IItemDefManager *item_def_mgr, + bool absolute_pos = false); + + // Add all keys in this list to the vector keys + std::vector<v3s16> getAllKeys(); + // Get pointer to data + NodeMetadata *get(v3s16 p); + // Deletes data + void remove(v3s16 p); + // Deletes old data and sets a new one + void set(v3s16 p, NodeMetadata *d); + // Deletes all + void clear(); + + size_t size() const { return m_data.size(); } + + NodeMetadataMap::const_iterator begin() + { + return m_data.begin(); + } + + NodeMetadataMap::const_iterator end() + { + return m_data.end(); + } + +private: + int countNonEmpty() const; + + bool m_is_metadata_owner; + NodeMetadataMap m_data; +}; diff --git a/src/nodetimer.cpp b/src/nodetimer.cpp new file mode 100644 index 0000000..ec8611a --- /dev/null +++ b/src/nodetimer.cpp @@ -0,0 +1,150 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "nodetimer.h" +#include "log.h" +#include "serialization.h" +#include "util/serialize.h" +#include "constants.h" // MAP_BLOCKSIZE + +/* + NodeTimer +*/ + +void NodeTimer::serialize(std::ostream &os) const +{ + writeF1000(os, timeout); + writeF1000(os, elapsed); +} + +void NodeTimer::deSerialize(std::istream &is) +{ + timeout = readF1000(is); + elapsed = readF1000(is); +} + +/* + NodeTimerList +*/ + +void NodeTimerList::serialize(std::ostream &os, u8 map_format_version) const +{ + if (map_format_version == 24) { + // Version 0 is a placeholder for "nothing to see here; go away." + if (m_timers.empty()) { + writeU8(os, 0); // version + return; + } + writeU8(os, 1); // version + writeU16(os, m_timers.size()); + } + + if (map_format_version >= 25) { + writeU8(os, 2 + 4 + 4); // length of the data for a single timer + writeU16(os, m_timers.size()); + } + + for (const auto &timer : m_timers) { + NodeTimer t = timer.second; + NodeTimer nt = NodeTimer(t.timeout, + t.timeout - (f32)(timer.first - m_time), t.position); + v3s16 p = t.position; + + u16 p16 = p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE + p.Y * MAP_BLOCKSIZE + p.X; + writeU16(os, p16); + nt.serialize(os); + } +} + +void NodeTimerList::deSerialize(std::istream &is, u8 map_format_version) +{ + clear(); + + if (map_format_version == 24) { + u8 timer_version = readU8(is); + if(timer_version == 0) + return; + if(timer_version != 1) + throw SerializationError("unsupported NodeTimerList version"); + } + + if (map_format_version >= 25) { + u8 timer_data_len = readU8(is); + if(timer_data_len != 2+4+4) + throw SerializationError("unsupported NodeTimer data length"); + } + + u16 count = readU16(is); + + for (u16 i = 0; i < count; i++) { + u16 p16 = readU16(is); + + v3s16 p; + p.Z = p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE; + p16 &= MAP_BLOCKSIZE * MAP_BLOCKSIZE - 1; + p.Y = p16 / MAP_BLOCKSIZE; + p16 &= MAP_BLOCKSIZE - 1; + p.X = p16; + + NodeTimer t(p); + t.deSerialize(is); + + if (t.timeout <= 0) { + warningstream<<"NodeTimerList::deSerialize(): " + <<"invalid data at position" + <<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring." + <<std::endl; + continue; + } + + if (m_iterators.find(p) != m_iterators.end()) { + warningstream<<"NodeTimerList::deSerialize(): " + <<"already set data at position" + <<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring." + <<std::endl; + continue; + } + + insert(t); + } +} + +std::vector<NodeTimer> NodeTimerList::step(float dtime) +{ + std::vector<NodeTimer> elapsed_timers; + m_time += dtime; + if (m_next_trigger_time == -1. || m_time < m_next_trigger_time) { + return elapsed_timers; + } + std::multimap<double, NodeTimer>::iterator i = m_timers.begin(); + // Process timers + for (; i != m_timers.end() && i->first <= m_time; ++i) { + NodeTimer t = i->second; + t.elapsed = t.timeout + (f32)(m_time - i->first); + elapsed_timers.push_back(t); + m_iterators.erase(t.position); + } + // Delete elapsed timers + m_timers.erase(m_timers.begin(), i); + if (m_timers.empty()) + m_next_trigger_time = -1.; + else + m_next_trigger_time = m_timers.begin()->first; + return elapsed_timers; +} diff --git a/src/nodetimer.h b/src/nodetimer.h new file mode 100644 index 0000000..40e54cc --- /dev/null +++ b/src/nodetimer.h @@ -0,0 +1,128 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_v3d.h" +#include <iostream> +#include <map> +#include <vector> + +/* + NodeTimer provides per-node timed callback functionality. + Can be used for: + - Furnaces, to keep the fire burnin' + - "activated" nodes that snap back to their original state + after a fixed amount of time (mesecons buttons, for example) +*/ + +class NodeTimer +{ +public: + NodeTimer() = default; + NodeTimer(const v3s16 &position_): + position(position_) {} + NodeTimer(f32 timeout_, f32 elapsed_, v3s16 position_): + timeout(timeout_), elapsed(elapsed_), position(position_) {} + ~NodeTimer() = default; + + void serialize(std::ostream &os) const; + void deSerialize(std::istream &is); + + f32 timeout = 0.0f; + f32 elapsed = 0.0f; + v3s16 position; +}; + +/* + List of timers of all the nodes of a block +*/ + +class NodeTimerList +{ +public: + NodeTimerList() = default; + ~NodeTimerList() = default; + + void serialize(std::ostream &os, u8 map_format_version) const; + void deSerialize(std::istream &is, u8 map_format_version); + + // Get timer + NodeTimer get(const v3s16 &p) { + std::map<v3s16, std::multimap<double, NodeTimer>::iterator>::iterator n = + m_iterators.find(p); + if (n == m_iterators.end()) + return NodeTimer(); + NodeTimer t = n->second->second; + t.elapsed = t.timeout - (n->second->first - m_time); + return t; + } + // Deletes timer + void remove(v3s16 p) { + std::map<v3s16, std::multimap<double, NodeTimer>::iterator>::iterator n = + m_iterators.find(p); + if(n != m_iterators.end()) { + double removed_time = n->second->first; + m_timers.erase(n->second); + m_iterators.erase(n); + // Yes, this is float equality, but it is not a problem + // since we only test equality of floats as an ordered type + // and thus we never lose precision + if (removed_time == m_next_trigger_time) { + if (m_timers.empty()) + m_next_trigger_time = -1.; + else + m_next_trigger_time = m_timers.begin()->first; + } + } + } + // Undefined behaviour if there already is a timer + void insert(NodeTimer timer) { + v3s16 p = timer.position; + double trigger_time = m_time + (double)(timer.timeout - timer.elapsed); + std::multimap<double, NodeTimer>::iterator it = + m_timers.insert(std::pair<double, NodeTimer>( + trigger_time, timer + )); + m_iterators.insert( + std::pair<v3s16, std::multimap<double, NodeTimer>::iterator>(p, it)); + if (m_next_trigger_time == -1. || trigger_time < m_next_trigger_time) + m_next_trigger_time = trigger_time; + } + // Deletes old timer and sets a new one + inline void set(const NodeTimer &timer) { + remove(timer.position); + insert(timer); + } + // Deletes all timers + void clear() { + m_timers.clear(); + m_iterators.clear(); + m_next_trigger_time = -1.; + } + + // Move forward in time, returns elapsed timers + std::vector<NodeTimer> step(float dtime); + +private: + std::multimap<double, NodeTimer> m_timers; + std::map<v3s16, std::multimap<double, NodeTimer>::iterator> m_iterators; + double m_next_trigger_time = -1.0; + double m_time = 0.0; +}; diff --git a/src/noise.cpp b/src/noise.cpp new file mode 100644 index 0000000..99624f8 --- /dev/null +++ b/src/noise.cpp @@ -0,0 +1,733 @@ +/* + * Minetest + * Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com> + * Copyright (C) 2010-2014 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <cmath> +#include "noise.h" +#include <iostream> +#include <cstring> // memset +#include "debug.h" +#include "util/numeric.h" +#include "util/string.h" +#include "exceptions.h" + +#define NOISE_MAGIC_X 1619 +#define NOISE_MAGIC_Y 31337 +#define NOISE_MAGIC_Z 52591 +// Unsigned magic seed prevents undefined behavior. +#define NOISE_MAGIC_SEED 1013U + +FlagDesc flagdesc_noiseparams[] = { + {"defaults", NOISE_FLAG_DEFAULTS}, + {"eased", NOISE_FLAG_EASED}, + {"absvalue", NOISE_FLAG_ABSVALUE}, + {"pointbuffer", NOISE_FLAG_POINTBUFFER}, + {"simplex", NOISE_FLAG_SIMPLEX}, + {NULL, 0} +}; + +/////////////////////////////////////////////////////////////////////////////// + +PcgRandom::PcgRandom(u64 state, u64 seq) +{ + seed(state, seq); +} + +void PcgRandom::seed(u64 state, u64 seq) +{ + m_state = 0U; + m_inc = (seq << 1u) | 1u; + next(); + m_state += state; + next(); +} + + +u32 PcgRandom::next() +{ + u64 oldstate = m_state; + m_state = oldstate * 6364136223846793005ULL + m_inc; + + u32 xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; + u32 rot = oldstate >> 59u; + return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); +} + + +u32 PcgRandom::range(u32 bound) +{ + // If the bound is 0, we cover the whole RNG's range + if (bound == 0) + return next(); + + /* + This is an optimization of the expression: + 0x100000000ull % bound + since 64-bit modulo operations typically much slower than 32. + */ + u32 threshold = -bound % bound; + u32 r; + + /* + If the bound is not a multiple of the RNG's range, it may cause bias, + e.g. a RNG has a range from 0 to 3 and we take want a number 0 to 2. + Using rand() % 3, the number 0 would be twice as likely to appear. + With a very large RNG range, the effect becomes less prevalent but + still present. + + This can be solved by modifying the range of the RNG to become a + multiple of bound by dropping values above the a threshold. + + In our example, threshold == 4 % 3 == 1, so reject values < 1 + (that is, 0), thus making the range == 3 with no bias. + + This loop may look dangerous, but will always terminate due to the + RNG's property of uniformity. + */ + while ((r = next()) < threshold) + ; + + return r % bound; +} + + +s32 PcgRandom::range(s32 min, s32 max) +{ + if (max < min) + throw PrngException("Invalid range (max < min)"); + + // We have to cast to s64 because otherwise this could overflow, + // and signed overflow is undefined behavior. + u32 bound = (s64)max - (s64)min + 1; + return range(bound) + min; +} + + +void PcgRandom::bytes(void *out, size_t len) +{ + u8 *outb = (u8 *)out; + int bytes_left = 0; + u32 r; + + while (len--) { + if (bytes_left == 0) { + bytes_left = sizeof(u32); + r = next(); + } + + *outb = r & 0xFF; + outb++; + bytes_left--; + r >>= CHAR_BIT; + } +} + + +s32 PcgRandom::randNormalDist(s32 min, s32 max, int num_trials) +{ + s32 accum = 0; + for (int i = 0; i != num_trials; i++) + accum += range(min, max); + return myround((float)accum / num_trials); +} + +/////////////////////////////////////////////////////////////////////////////// + +float noise2d(int x, int y, s32 seed) +{ + unsigned int n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y + + NOISE_MAGIC_SEED * seed) & 0x7fffffff; + n = (n >> 13) ^ n; + n = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; + return 1.f - (float)(int)n / 0x40000000; +} + + +float noise3d(int x, int y, int z, s32 seed) +{ + unsigned int n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y + NOISE_MAGIC_Z * z + + NOISE_MAGIC_SEED * seed) & 0x7fffffff; + n = (n >> 13) ^ n; + n = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; + return 1.f - (float)(int)n / 0x40000000; +} + + +inline float dotProduct(float vx, float vy, float wx, float wy) +{ + return vx * wx + vy * wy; +} + + +inline float linearInterpolation(float v0, float v1, float t) +{ + return v0 + (v1 - v0) * t; +} + + +inline float biLinearInterpolation( + float v00, float v10, + float v01, float v11, + float x, float y, + bool eased) +{ + // Inlining will optimize this branch out when possible + if (eased) { + x = easeCurve(x); + y = easeCurve(y); + } + float u = linearInterpolation(v00, v10, x); + float v = linearInterpolation(v01, v11, x); + return linearInterpolation(u, v, y); +} + + +inline float triLinearInterpolation( + float v000, float v100, float v010, float v110, + float v001, float v101, float v011, float v111, + float x, float y, float z, + bool eased) +{ + // Inlining will optimize this branch out when possible + if (eased) { + x = easeCurve(x); + y = easeCurve(y); + z = easeCurve(z); + } + float u = biLinearInterpolation(v000, v100, v010, v110, x, y, false); + float v = biLinearInterpolation(v001, v101, v011, v111, x, y, false); + return linearInterpolation(u, v, z); +} + +float noise2d_gradient(float x, float y, s32 seed, bool eased) +{ + // Calculate the integer coordinates + int x0 = myfloor(x); + int y0 = myfloor(y); + // Calculate the remaining part of the coordinates + float xl = x - (float)x0; + float yl = y - (float)y0; + // Get values for corners of square + float v00 = noise2d(x0, y0, seed); + float v10 = noise2d(x0+1, y0, seed); + float v01 = noise2d(x0, y0+1, seed); + float v11 = noise2d(x0+1, y0+1, seed); + // Interpolate + return biLinearInterpolation(v00, v10, v01, v11, xl, yl, eased); +} + + +float noise3d_gradient(float x, float y, float z, s32 seed, bool eased) +{ + // Calculate the integer coordinates + int x0 = myfloor(x); + int y0 = myfloor(y); + int z0 = myfloor(z); + // Calculate the remaining part of the coordinates + float xl = x - (float)x0; + float yl = y - (float)y0; + float zl = z - (float)z0; + // Get values for corners of cube + float v000 = noise3d(x0, y0, z0, seed); + float v100 = noise3d(x0 + 1, y0, z0, seed); + float v010 = noise3d(x0, y0 + 1, z0, seed); + float v110 = noise3d(x0 + 1, y0 + 1, z0, seed); + float v001 = noise3d(x0, y0, z0 + 1, seed); + float v101 = noise3d(x0 + 1, y0, z0 + 1, seed); + float v011 = noise3d(x0, y0 + 1, z0 + 1, seed); + float v111 = noise3d(x0 + 1, y0 + 1, z0 + 1, seed); + // Interpolate + return triLinearInterpolation( + v000, v100, v010, v110, + v001, v101, v011, v111, + xl, yl, zl, + eased); +} + + +float noise2d_perlin(float x, float y, s32 seed, + int octaves, float persistence, bool eased) +{ + float a = 0; + float f = 1.0; + float g = 1.0; + for (int i = 0; i < octaves; i++) + { + a += g * noise2d_gradient(x * f, y * f, seed + i, eased); + f *= 2.0; + g *= persistence; + } + return a; +} + + +float contour(float v) +{ + v = std::fabs(v); + if (v >= 1.0) + return 0.0; + return (1.0 - v); +} + + +///////////////////////// [ New noise ] //////////////////////////// + + +float NoisePerlin2D(const NoiseParams *np, float x, float y, s32 seed) +{ + float a = 0; + float f = 1.0; + float g = 1.0; + + x /= np->spread.X; + y /= np->spread.Y; + seed += np->seed; + + for (size_t i = 0; i < np->octaves; i++) { + float noiseval = noise2d_gradient(x * f, y * f, seed + i, + np->flags & (NOISE_FLAG_DEFAULTS | NOISE_FLAG_EASED)); + + if (np->flags & NOISE_FLAG_ABSVALUE) + noiseval = std::fabs(noiseval); + + a += g * noiseval; + f *= np->lacunarity; + g *= np->persist; + } + + return np->offset + a * np->scale; +} + + +float NoisePerlin3D(const NoiseParams *np, float x, float y, float z, s32 seed) +{ + float a = 0; + float f = 1.0; + float g = 1.0; + + x /= np->spread.X; + y /= np->spread.Y; + z /= np->spread.Z; + seed += np->seed; + + for (size_t i = 0; i < np->octaves; i++) { + float noiseval = noise3d_gradient(x * f, y * f, z * f, seed + i, + np->flags & NOISE_FLAG_EASED); + + if (np->flags & NOISE_FLAG_ABSVALUE) + noiseval = std::fabs(noiseval); + + a += g * noiseval; + f *= np->lacunarity; + g *= np->persist; + } + + return np->offset + a * np->scale; +} + + +Noise::Noise(const NoiseParams *np_, s32 seed, u32 sx, u32 sy, u32 sz) +{ + np = *np_; + this->seed = seed; + this->sx = sx; + this->sy = sy; + this->sz = sz; + + allocBuffers(); +} + + +Noise::~Noise() +{ + delete[] gradient_buf; + delete[] persist_buf; + delete[] noise_buf; + delete[] result; +} + + +void Noise::allocBuffers() +{ + if (sx < 1) + sx = 1; + if (sy < 1) + sy = 1; + if (sz < 1) + sz = 1; + + this->noise_buf = NULL; + resizeNoiseBuf(sz > 1); + + delete[] gradient_buf; + delete[] persist_buf; + delete[] result; + + try { + size_t bufsize = sx * sy * sz; + this->persist_buf = NULL; + this->gradient_buf = new float[bufsize]; + this->result = new float[bufsize]; + } catch (std::bad_alloc &e) { + throw InvalidNoiseParamsException(); + } +} + + +void Noise::setSize(u32 sx, u32 sy, u32 sz) +{ + this->sx = sx; + this->sy = sy; + this->sz = sz; + + allocBuffers(); +} + + +void Noise::setSpreadFactor(v3f spread) +{ + this->np.spread = spread; + + resizeNoiseBuf(sz > 1); +} + + +void Noise::setOctaves(int octaves) +{ + this->np.octaves = octaves; + + resizeNoiseBuf(sz > 1); +} + + +void Noise::resizeNoiseBuf(bool is3d) +{ + // Maximum possible spread value factor + float ofactor = (np.lacunarity > 1.0) ? + pow(np.lacunarity, np.octaves - 1) : + np.lacunarity; + + // Noise lattice point count + // (int)(sz * spread * ofactor) is # of lattice points crossed due to length + float num_noise_points_x = sx * ofactor / np.spread.X; + float num_noise_points_y = sy * ofactor / np.spread.Y; + float num_noise_points_z = sz * ofactor / np.spread.Z; + + // Protect against obviously invalid parameters + if (num_noise_points_x > 1000000000.f || + num_noise_points_y > 1000000000.f || + num_noise_points_z > 1000000000.f) + throw InvalidNoiseParamsException(); + + // Protect against an octave having a spread < 1, causing broken noise values + if (np.spread.X / ofactor < 1.0f || + np.spread.Y / ofactor < 1.0f || + np.spread.Z / ofactor < 1.0f) { + errorstream << "A noise parameter has too many octaves: " + << np.octaves << " octaves" << std::endl; + throw InvalidNoiseParamsException("A noise parameter has too many octaves"); + } + + // + 2 for the two initial endpoints + // + 1 for potentially crossing a boundary due to offset + size_t nlx = (size_t)std::ceil(num_noise_points_x) + 3; + size_t nly = (size_t)std::ceil(num_noise_points_y) + 3; + size_t nlz = is3d ? (size_t)std::ceil(num_noise_points_z) + 3 : 1; + + delete[] noise_buf; + try { + noise_buf = new float[nlx * nly * nlz]; + } catch (std::bad_alloc &e) { + throw InvalidNoiseParamsException(); + } +} + + +/* + * NB: This algorithm is not optimal in terms of space complexity. The entire + * integer lattice of noise points could be done as 2 lines instead, and for 3D, + * 2 lines + 2 planes. + * However, this would require the noise calls to be interposed with the + * interpolation loops, which may trash the icache, leading to lower overall + * performance. + * Another optimization that could save half as many noise calls is to carry over + * values from the previous noise lattice as midpoints in the new lattice for the + * next octave. + */ +#define idx(x, y) ((y) * nlx + (x)) +void Noise::gradientMap2D( + float x, float y, + float step_x, float step_y, + s32 seed) +{ + float v00, v01, v10, v11, u, v, orig_u; + u32 index, i, j, noisex, noisey; + u32 nlx, nly; + s32 x0, y0; + + bool eased = np.flags & (NOISE_FLAG_DEFAULTS | NOISE_FLAG_EASED); + x0 = std::floor(x); + y0 = std::floor(y); + u = x - (float)x0; + v = y - (float)y0; + orig_u = u; + + //calculate noise point lattice + nlx = (u32)(u + sx * step_x) + 2; + nly = (u32)(v + sy * step_y) + 2; + index = 0; + for (j = 0; j != nly; j++) + for (i = 0; i != nlx; i++) + noise_buf[index++] = noise2d(x0 + i, y0 + j, seed); + + //calculate interpolations + index = 0; + noisey = 0; + for (j = 0; j != sy; j++) { + v00 = noise_buf[idx(0, noisey)]; + v10 = noise_buf[idx(1, noisey)]; + v01 = noise_buf[idx(0, noisey + 1)]; + v11 = noise_buf[idx(1, noisey + 1)]; + + u = orig_u; + noisex = 0; + for (i = 0; i != sx; i++) { + gradient_buf[index++] = + biLinearInterpolation(v00, v10, v01, v11, u, v, eased); + + u += step_x; + if (u >= 1.0) { + u -= 1.0; + noisex++; + v00 = v10; + v01 = v11; + v10 = noise_buf[idx(noisex + 1, noisey)]; + v11 = noise_buf[idx(noisex + 1, noisey + 1)]; + } + } + + v += step_y; + if (v >= 1.0) { + v -= 1.0; + noisey++; + } + } +} +#undef idx + + +#define idx(x, y, z) ((z) * nly * nlx + (y) * nlx + (x)) +void Noise::gradientMap3D( + float x, float y, float z, + float step_x, float step_y, float step_z, + s32 seed) +{ + float v000, v010, v100, v110; + float v001, v011, v101, v111; + float u, v, w, orig_u, orig_v; + u32 index, i, j, k, noisex, noisey, noisez; + u32 nlx, nly, nlz; + s32 x0, y0, z0; + + bool eased = np.flags & NOISE_FLAG_EASED; + + x0 = std::floor(x); + y0 = std::floor(y); + z0 = std::floor(z); + u = x - (float)x0; + v = y - (float)y0; + w = z - (float)z0; + orig_u = u; + orig_v = v; + + //calculate noise point lattice + nlx = (u32)(u + sx * step_x) + 2; + nly = (u32)(v + sy * step_y) + 2; + nlz = (u32)(w + sz * step_z) + 2; + index = 0; + for (k = 0; k != nlz; k++) + for (j = 0; j != nly; j++) + for (i = 0; i != nlx; i++) + noise_buf[index++] = noise3d(x0 + i, y0 + j, z0 + k, seed); + + //calculate interpolations + index = 0; + noisey = 0; + noisez = 0; + for (k = 0; k != sz; k++) { + v = orig_v; + noisey = 0; + for (j = 0; j != sy; j++) { + v000 = noise_buf[idx(0, noisey, noisez)]; + v100 = noise_buf[idx(1, noisey, noisez)]; + v010 = noise_buf[idx(0, noisey + 1, noisez)]; + v110 = noise_buf[idx(1, noisey + 1, noisez)]; + v001 = noise_buf[idx(0, noisey, noisez + 1)]; + v101 = noise_buf[idx(1, noisey, noisez + 1)]; + v011 = noise_buf[idx(0, noisey + 1, noisez + 1)]; + v111 = noise_buf[idx(1, noisey + 1, noisez + 1)]; + + u = orig_u; + noisex = 0; + for (i = 0; i != sx; i++) { + gradient_buf[index++] = triLinearInterpolation( + v000, v100, v010, v110, + v001, v101, v011, v111, + u, v, w, + eased); + + u += step_x; + if (u >= 1.0) { + u -= 1.0; + noisex++; + v000 = v100; + v010 = v110; + v100 = noise_buf[idx(noisex + 1, noisey, noisez)]; + v110 = noise_buf[idx(noisex + 1, noisey + 1, noisez)]; + v001 = v101; + v011 = v111; + v101 = noise_buf[idx(noisex + 1, noisey, noisez + 1)]; + v111 = noise_buf[idx(noisex + 1, noisey + 1, noisez + 1)]; + } + } + + v += step_y; + if (v >= 1.0) { + v -= 1.0; + noisey++; + } + } + + w += step_z; + if (w >= 1.0) { + w -= 1.0; + noisez++; + } + } +} +#undef idx + + +float *Noise::perlinMap2D(float x, float y, float *persistence_map) +{ + float f = 1.0, g = 1.0; + size_t bufsize = sx * sy; + + x /= np.spread.X; + y /= np.spread.Y; + + memset(result, 0, sizeof(float) * bufsize); + + if (persistence_map) { + if (!persist_buf) + persist_buf = new float[bufsize]; + for (size_t i = 0; i != bufsize; i++) + persist_buf[i] = 1.0; + } + + for (size_t oct = 0; oct < np.octaves; oct++) { + gradientMap2D(x * f, y * f, + f / np.spread.X, f / np.spread.Y, + seed + np.seed + oct); + + updateResults(g, persist_buf, persistence_map, bufsize); + + f *= np.lacunarity; + g *= np.persist; + } + + if (std::fabs(np.offset - 0.f) > 0.00001 || std::fabs(np.scale - 1.f) > 0.00001) { + for (size_t i = 0; i != bufsize; i++) + result[i] = result[i] * np.scale + np.offset; + } + + return result; +} + + +float *Noise::perlinMap3D(float x, float y, float z, float *persistence_map) +{ + float f = 1.0, g = 1.0; + size_t bufsize = sx * sy * sz; + + x /= np.spread.X; + y /= np.spread.Y; + z /= np.spread.Z; + + memset(result, 0, sizeof(float) * bufsize); + + if (persistence_map) { + if (!persist_buf) + persist_buf = new float[bufsize]; + for (size_t i = 0; i != bufsize; i++) + persist_buf[i] = 1.0; + } + + for (size_t oct = 0; oct < np.octaves; oct++) { + gradientMap3D(x * f, y * f, z * f, + f / np.spread.X, f / np.spread.Y, f / np.spread.Z, + seed + np.seed + oct); + + updateResults(g, persist_buf, persistence_map, bufsize); + + f *= np.lacunarity; + g *= np.persist; + } + + if (std::fabs(np.offset - 0.f) > 0.00001 || std::fabs(np.scale - 1.f) > 0.00001) { + for (size_t i = 0; i != bufsize; i++) + result[i] = result[i] * np.scale + np.offset; + } + + return result; +} + + +void Noise::updateResults(float g, float *gmap, + const float *persistence_map, size_t bufsize) +{ + // This looks very ugly, but it is 50-70% faster than having + // conditional statements inside the loop + if (np.flags & NOISE_FLAG_ABSVALUE) { + if (persistence_map) { + for (size_t i = 0; i != bufsize; i++) { + result[i] += gmap[i] * std::fabs(gradient_buf[i]); + gmap[i] *= persistence_map[i]; + } + } else { + for (size_t i = 0; i != bufsize; i++) + result[i] += g * std::fabs(gradient_buf[i]); + } + } else { + if (persistence_map) { + for (size_t i = 0; i != bufsize; i++) { + result[i] += gmap[i] * gradient_buf[i]; + gmap[i] *= persistence_map[i]; + } + } else { + for (size_t i = 0; i != bufsize; i++) + result[i] += g * gradient_buf[i]; + } + } +} diff --git a/src/noise.h b/src/noise.h new file mode 100644 index 0000000..e4a9ed6 --- /dev/null +++ b/src/noise.h @@ -0,0 +1,232 @@ +/* + * Minetest + * Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com> + * Copyright (C) 2010-2014 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "irr_v3d.h" +#include "exceptions.h" +#include "util/string.h" + +#if defined(RANDOM_MIN) +#undef RANDOM_MIN +#endif +#if defined(RANDOM_MAX) +#undef RANDOM_MAX +#endif + +extern FlagDesc flagdesc_noiseparams[]; + +// Note: this class is not polymorphic so that its high level of +// optimizability may be preserved in the common use case +class PseudoRandom { +public: + const static u32 RANDOM_RANGE = 32767; + + inline PseudoRandom(int seed=0): + m_next(seed) + { + } + + inline void seed(int seed) + { + m_next = seed; + } + + inline int next() + { + m_next = m_next * 1103515245 + 12345; + return (unsigned)(m_next / 65536) % (RANDOM_RANGE + 1); + } + + inline int range(int min, int max) + { + if (max < min) + throw PrngException("Invalid range (max < min)"); + /* + Here, we ensure the range is not too large relative to RANDOM_MAX, + as otherwise the effects of bias would become noticable. Unlike + PcgRandom, we cannot modify this RNG's range as it would change the + output of this RNG for reverse compatibility. + */ + if ((u32)(max - min) > (RANDOM_RANGE + 1) / 10) + throw PrngException("Range too large"); + + return (next() % (max - min + 1)) + min; + } + +private: + int m_next; +}; + +class PcgRandom { +public: + const static s32 RANDOM_MIN = -0x7fffffff - 1; + const static s32 RANDOM_MAX = 0x7fffffff; + const static u32 RANDOM_RANGE = 0xffffffff; + + PcgRandom(u64 state=0x853c49e6748fea9bULL, u64 seq=0xda3e39cb94b95bdbULL); + void seed(u64 state, u64 seq=0xda3e39cb94b95bdbULL); + u32 next(); + u32 range(u32 bound); + s32 range(s32 min, s32 max); + void bytes(void *out, size_t len); + s32 randNormalDist(s32 min, s32 max, int num_trials=6); + +private: + u64 m_state; + u64 m_inc; +}; + +#define NOISE_FLAG_DEFAULTS 0x01 +#define NOISE_FLAG_EASED 0x02 +#define NOISE_FLAG_ABSVALUE 0x04 + +//// TODO(hmmmm): implement these! +#define NOISE_FLAG_POINTBUFFER 0x08 +#define NOISE_FLAG_SIMPLEX 0x10 + +struct NoiseParams { + float offset = 0.0f; + float scale = 1.0f; + v3f spread = v3f(250, 250, 250); + s32 seed = 12345; + u16 octaves = 3; + float persist = 0.6f; + float lacunarity = 2.0f; + u32 flags = NOISE_FLAG_DEFAULTS; + + NoiseParams() = default; + + NoiseParams(float offset_, float scale_, const v3f &spread_, s32 seed_, + u16 octaves_, float persist_, float lacunarity_, + u32 flags_=NOISE_FLAG_DEFAULTS) + { + offset = offset_; + scale = scale_; + spread = spread_; + seed = seed_; + octaves = octaves_; + persist = persist_; + lacunarity = lacunarity_; + flags = flags_; + } +}; + +class Noise { +public: + NoiseParams np; + s32 seed; + u32 sx; + u32 sy; + u32 sz; + float *noise_buf = nullptr; + float *gradient_buf = nullptr; + float *persist_buf = nullptr; + float *result = nullptr; + + Noise(const NoiseParams *np, s32 seed, u32 sx, u32 sy, u32 sz=1); + ~Noise(); + + void setSize(u32 sx, u32 sy, u32 sz=1); + void setSpreadFactor(v3f spread); + void setOctaves(int octaves); + + void gradientMap2D( + float x, float y, + float step_x, float step_y, + s32 seed); + void gradientMap3D( + float x, float y, float z, + float step_x, float step_y, float step_z, + s32 seed); + + float *perlinMap2D(float x, float y, float *persistence_map=NULL); + float *perlinMap3D(float x, float y, float z, float *persistence_map=NULL); + + inline float *perlinMap2D_PO(float x, float xoff, float y, float yoff, + float *persistence_map=NULL) + { + return perlinMap2D( + x + xoff * np.spread.X, + y + yoff * np.spread.Y, + persistence_map); + } + + inline float *perlinMap3D_PO(float x, float xoff, float y, float yoff, + float z, float zoff, float *persistence_map=NULL) + { + return perlinMap3D( + x + xoff * np.spread.X, + y + yoff * np.spread.Y, + z + zoff * np.spread.Z, + persistence_map); + } + +private: + void allocBuffers(); + void resizeNoiseBuf(bool is3d); + void updateResults(float g, float *gmap, const float *persistence_map, + size_t bufsize); + +}; + +float NoisePerlin2D(const NoiseParams *np, float x, float y, s32 seed); +float NoisePerlin3D(const NoiseParams *np, float x, float y, float z, s32 seed); + +inline float NoisePerlin2D_PO(NoiseParams *np, float x, float xoff, + float y, float yoff, s32 seed) +{ + return NoisePerlin2D(np, + x + xoff * np->spread.X, + y + yoff * np->spread.Y, + seed); +} + +inline float NoisePerlin3D_PO(NoiseParams *np, float x, float xoff, + float y, float yoff, float z, float zoff, s32 seed) +{ + return NoisePerlin3D(np, + x + xoff * np->spread.X, + y + yoff * np->spread.Y, + z + zoff * np->spread.Z, + seed); +} + +// Return value: -1 ... 1 +float noise2d(int x, int y, s32 seed); +float noise3d(int x, int y, int z, s32 seed); + +float noise2d_gradient(float x, float y, s32 seed, bool eased=true); +float noise3d_gradient(float x, float y, float z, s32 seed, bool eased=false); + +float noise2d_perlin(float x, float y, s32 seed, + int octaves, float persistence, bool eased=true); + +inline float easeCurve(float t) +{ + return t * t * t * (t * (6.f * t - 15.f) + 10.f); +} + +float contour(float v); diff --git a/src/objdef.cpp b/src/objdef.cpp new file mode 100644 index 0000000..482544d --- /dev/null +++ b/src/objdef.cpp @@ -0,0 +1,203 @@ +/* +Minetest +Copyright (C) 2010-2015 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "objdef.h" +#include "util/numeric.h" +#include "log.h" +#include "gamedef.h" + +ObjDefManager::ObjDefManager(IGameDef *gamedef, ObjDefType type) +{ + m_objtype = type; + m_ndef = gamedef ? gamedef->getNodeDefManager() : NULL; +} + + +ObjDefManager::~ObjDefManager() +{ + for (size_t i = 0; i != m_objects.size(); i++) + delete m_objects[i]; +} + + +ObjDefHandle ObjDefManager::add(ObjDef *obj) +{ + assert(obj); + + if (obj->name.length() && getByName(obj->name)) + return OBJDEF_INVALID_HANDLE; + + u32 index = addRaw(obj); + if (index == OBJDEF_INVALID_INDEX) + return OBJDEF_INVALID_HANDLE; + + obj->handle = createHandle(index, m_objtype, obj->uid); + return obj->handle; +} + + +ObjDef *ObjDefManager::get(ObjDefHandle handle) const +{ + u32 index = validateHandle(handle); + return (index != OBJDEF_INVALID_INDEX) ? getRaw(index) : NULL; +} + + +ObjDef *ObjDefManager::set(ObjDefHandle handle, ObjDef *obj) +{ + u32 index = validateHandle(handle); + if (index == OBJDEF_INVALID_INDEX) + return NULL; + + ObjDef *oldobj = setRaw(index, obj); + + obj->uid = oldobj->uid; + obj->index = oldobj->index; + obj->handle = oldobj->handle; + + return oldobj; +} + + +u32 ObjDefManager::addRaw(ObjDef *obj) +{ + size_t nobjects = m_objects.size(); + if (nobjects >= OBJDEF_MAX_ITEMS) + return -1; + + obj->index = nobjects; + + // Ensure UID is nonzero so that a valid handle == OBJDEF_INVALID_HANDLE + // is not possible. The slight randomness bias isn't very significant. + obj->uid = myrand() & OBJDEF_UID_MASK; + if (obj->uid == 0) + obj->uid = 1; + + m_objects.push_back(obj); + + infostream << "ObjDefManager: added " << getObjectTitle() + << ": name=\"" << obj->name + << "\" index=" << obj->index + << " uid=" << obj->uid + << std::endl; + + return nobjects; +} + + +ObjDef *ObjDefManager::getRaw(u32 index) const +{ + return m_objects[index]; +} + + +ObjDef *ObjDefManager::setRaw(u32 index, ObjDef *obj) +{ + ObjDef *old_obj = m_objects[index]; + m_objects[index] = obj; + return old_obj; +} + + +ObjDef *ObjDefManager::getByName(const std::string &name) const +{ + for (size_t i = 0; i != m_objects.size(); i++) { + ObjDef *obj = m_objects[i]; + if (obj && !strcasecmp(name.c_str(), obj->name.c_str())) + return obj; + } + + return NULL; +} + + +void ObjDefManager::clear() +{ + for (size_t i = 0; i != m_objects.size(); i++) + delete m_objects[i]; + + m_objects.clear(); +} + + +u32 ObjDefManager::validateHandle(ObjDefHandle handle) const +{ + ObjDefType type; + u32 index; + u32 uid; + + bool is_valid = + (handle != OBJDEF_INVALID_HANDLE) && + decodeHandle(handle, &index, &type, &uid) && + (type == m_objtype) && + (index < m_objects.size()) && + (m_objects[index]->uid == uid); + + return is_valid ? index : -1; +} + + +ObjDefHandle ObjDefManager::createHandle(u32 index, ObjDefType type, u32 uid) +{ + ObjDefHandle handle = 0; + set_bits(&handle, 0, 18, index); + set_bits(&handle, 18, 6, type); + set_bits(&handle, 24, 7, uid); + + u32 parity = calc_parity(handle); + set_bits(&handle, 31, 1, parity); + + return handle ^ OBJDEF_HANDLE_SALT; +} + + +bool ObjDefManager::decodeHandle(ObjDefHandle handle, u32 *index, + ObjDefType *type, u32 *uid) +{ + handle ^= OBJDEF_HANDLE_SALT; + + u32 parity = get_bits(handle, 31, 1); + set_bits(&handle, 31, 1, 0); + if (parity != calc_parity(handle)) + return false; + + *index = get_bits(handle, 0, 18); + *type = (ObjDefType)get_bits(handle, 18, 6); + *uid = get_bits(handle, 24, 7); + return true; +} + +// Cloning + +void ObjDef::cloneTo(ObjDef *def) const +{ + def->index = index; + def->uid = uid; + def->handle = handle; + def->name = name; +} + +void ObjDefManager::cloneTo(ObjDefManager *mgr) const +{ + mgr->m_ndef = m_ndef; + mgr->m_objects.reserve(m_objects.size()); + for (const auto &obj : m_objects) + mgr->m_objects.push_back(obj->clone()); + mgr->m_objtype = m_objtype; +} diff --git a/src/objdef.h b/src/objdef.h new file mode 100644 index 0000000..e40324a --- /dev/null +++ b/src/objdef.h @@ -0,0 +1,113 @@ +/* +Minetest +Copyright (C) 2010-2015 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "util/basic_macros.h" +#include "porting.h" + +class IGameDef; +class NodeDefManager; + +#define OBJDEF_INVALID_INDEX ((u32)(-1)) +#define OBJDEF_INVALID_HANDLE 0 +#define OBJDEF_HANDLE_SALT 0x00585e6fu +#define OBJDEF_MAX_ITEMS (1 << 18) +#define OBJDEF_UID_MASK ((1 << 7) - 1) + +typedef u32 ObjDefHandle; + +enum ObjDefType { + OBJDEF_GENERIC, + OBJDEF_BIOME, + OBJDEF_ORE, + OBJDEF_DECORATION, + OBJDEF_SCHEMATIC, +}; + +class ObjDef { +public: + virtual ~ObjDef() = default; + + // Only implemented by child classes (leafs in class hierarchy) + // Should create new object of its own type, call cloneTo() of parent class + // and copy its own instance variables over + virtual ObjDef *clone() const = 0; + + u32 index; + u32 uid; + ObjDefHandle handle; + std::string name; + +protected: + // Only implemented by classes that have children themselves + // by copying the defintion and changing that argument type (!!!) + // Should defer to parent class cloneTo() if applicable and then copy + // over its own properties + void cloneTo(ObjDef *def) const; +}; + +// WARNING: Ownership of ObjDefs is transferred to the ObjDefManager it is +// added/set to. Note that ObjDefs managed by ObjDefManager are NOT refcounted, +// so the same ObjDef instance must not be referenced multiple +// TODO: const correctness for getter methods +class ObjDefManager { +public: + ObjDefManager(IGameDef *gamedef, ObjDefType type); + virtual ~ObjDefManager(); + DISABLE_CLASS_COPY(ObjDefManager); + + // T *clone() const; // implemented in child class with correct type + + virtual const char *getObjectTitle() const { return "ObjDef"; } + + virtual void clear(); + virtual ObjDef *getByName(const std::string &name) const; + + //// Add new/get/set object definitions by handle + virtual ObjDefHandle add(ObjDef *obj); + virtual ObjDef *get(ObjDefHandle handle) const; + virtual ObjDef *set(ObjDefHandle handle, ObjDef *obj); + + //// Raw variants that work on indexes + virtual u32 addRaw(ObjDef *obj); + + // It is generally assumed that getRaw() will always return a valid object + // This won't be true if people do odd things such as call setRaw() with NULL + virtual ObjDef *getRaw(u32 index) const; + virtual ObjDef *setRaw(u32 index, ObjDef *obj); + + size_t getNumObjects() const { return m_objects.size(); } + ObjDefType getType() const { return m_objtype; } + const NodeDefManager *getNodeDef() const { return m_ndef; } + + u32 validateHandle(ObjDefHandle handle) const; + static ObjDefHandle createHandle(u32 index, ObjDefType type, u32 uid); + static bool decodeHandle(ObjDefHandle handle, u32 *index, + ObjDefType *type, u32 *uid); + +protected: + ObjDefManager() {}; + // Helper for child classes to implement clone() + void cloneTo(ObjDefManager *mgr) const; + + const NodeDefManager *m_ndef; + std::vector<ObjDef *> m_objects; + ObjDefType m_objtype; +}; diff --git a/src/object_properties.cpp b/src/object_properties.cpp new file mode 100644 index 0000000..c7f6bec --- /dev/null +++ b/src/object_properties.cpp @@ -0,0 +1,240 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "object_properties.h" +#include "irrlichttypes_bloated.h" +#include "exceptions.h" +#include "util/serialize.h" +#include "util/basic_macros.h" +#include <sstream> + +static const video::SColor NULL_BGCOLOR{0, 1, 1, 1}; + +ObjectProperties::ObjectProperties() +{ + textures.emplace_back("no_texture.png"); + colors.emplace_back(255,255,255,255); +} + +std::string ObjectProperties::dump() +{ + std::ostringstream os(std::ios::binary); + os << "hp_max=" << hp_max; + os << ", breath_max=" << breath_max; + os << ", physical=" << physical; + os << ", collideWithObjects=" << collideWithObjects; + os << ", collisionbox=" << PP(collisionbox.MinEdge) << "," << PP(collisionbox.MaxEdge); + os << ", visual=" << visual; + os << ", mesh=" << mesh; + os << ", visual_size=" << PP(visual_size); + os << ", textures=["; + for (const std::string &texture : textures) { + os << "\"" << texture << "\" "; + } + os << "]"; + os << ", colors=["; + for (const video::SColor &color : colors) { + os << "\"" << color.getAlpha() << "," << color.getRed() << "," + << color.getGreen() << "," << color.getBlue() << "\" "; + } + os << "]"; + os << ", spritediv=" << PP2(spritediv); + os << ", initial_sprite_basepos=" << PP2(initial_sprite_basepos); + os << ", is_visible=" << is_visible; + os << ", makes_footstep_sound=" << makes_footstep_sound; + os << ", automatic_rotate="<< automatic_rotate; + os << ", backface_culling="<< backface_culling; + os << ", glow=" << glow; + os << ", nametag=" << nametag; + os << ", nametag_color=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed() + << "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" "; + + if (nametag_bgcolor) + os << ", nametag_bgcolor=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed() + << "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" "; + else + os << ", nametag_bgcolor=null "; + + os << ", selectionbox=" << PP(selectionbox.MinEdge) << "," << PP(selectionbox.MaxEdge); + os << ", pointable=" << pointable; + os << ", static_save=" << static_save; + os << ", eye_height=" << eye_height; + os << ", zoom_fov=" << zoom_fov; + os << ", use_texture_alpha=" << use_texture_alpha; + os << ", damage_texture_modifier=" << damage_texture_modifier; + os << ", shaded=" << shaded; + os << ", show_on_minimap=" << show_on_minimap; + return os.str(); +} + +bool ObjectProperties::validate() +{ + const char *func = "ObjectProperties::validate(): "; + bool ret = true; + + // cf. where serializeString16 is used below + for (u32 i = 0; i < textures.size(); i++) { + if (textures[i].size() > U16_MAX) { + warningstream << func << "texture " << (i+1) << " has excessive length, " + "clearing it." << std::endl; + textures[i].clear(); + ret = false; + } + } + if (nametag.length() > U16_MAX) { + warningstream << func << "nametag has excessive length, clearing it." << std::endl; + nametag.clear(); + ret = false; + } + if (infotext.length() > U16_MAX) { + warningstream << func << "infotext has excessive length, clearing it." << std::endl; + infotext.clear(); + ret = false; + } + if (wield_item.length() > U16_MAX) { + warningstream << func << "wield_item has excessive length, clearing it." << std::endl; + wield_item.clear(); + ret = false; + } + + return ret; +} + +void ObjectProperties::serialize(std::ostream &os) const +{ + writeU8(os, 4); // PROTOCOL_VERSION >= 37 + writeU16(os, hp_max); + writeU8(os, physical); + writeF32(os, 0.f); // Removed property (weight) + writeV3F32(os, collisionbox.MinEdge); + writeV3F32(os, collisionbox.MaxEdge); + writeV3F32(os, selectionbox.MinEdge); + writeV3F32(os, selectionbox.MaxEdge); + writeU8(os, pointable); + os << serializeString16(visual); + writeV3F32(os, visual_size); + writeU16(os, textures.size()); + for (const std::string &texture : textures) { + os << serializeString16(texture); + } + writeV2S16(os, spritediv); + writeV2S16(os, initial_sprite_basepos); + writeU8(os, is_visible); + writeU8(os, makes_footstep_sound); + writeF32(os, automatic_rotate); + os << serializeString16(mesh); + writeU16(os, colors.size()); + for (video::SColor color : colors) { + writeARGB8(os, color); + } + writeU8(os, collideWithObjects); + writeF32(os, stepheight); + writeU8(os, automatic_face_movement_dir); + writeF32(os, automatic_face_movement_dir_offset); + writeU8(os, backface_culling); + os << serializeString16(nametag); + writeARGB8(os, nametag_color); + writeF32(os, automatic_face_movement_max_rotation_per_sec); + os << serializeString16(infotext); + os << serializeString16(wield_item); + writeS8(os, glow); + writeU16(os, breath_max); + writeF32(os, eye_height); + writeF32(os, zoom_fov); + writeU8(os, use_texture_alpha); + os << serializeString16(damage_texture_modifier); + writeU8(os, shaded); + writeU8(os, show_on_minimap); + + if (!nametag_bgcolor) + writeARGB8(os, NULL_BGCOLOR); + else if (nametag_bgcolor.value().getAlpha() == 0) + writeARGB8(os, video::SColor(0, 0, 0, 0)); + else + writeARGB8(os, nametag_bgcolor.value()); + + // Add stuff only at the bottom. + // Never remove anything, because we don't want new versions of this +} + +void ObjectProperties::deSerialize(std::istream &is) +{ + int version = readU8(is); + if (version != 4) + throw SerializationError("unsupported ObjectProperties version"); + + hp_max = readU16(is); + physical = readU8(is); + readU32(is); // removed property (weight) + collisionbox.MinEdge = readV3F32(is); + collisionbox.MaxEdge = readV3F32(is); + selectionbox.MinEdge = readV3F32(is); + selectionbox.MaxEdge = readV3F32(is); + pointable = readU8(is); + visual = deSerializeString16(is); + visual_size = readV3F32(is); + textures.clear(); + u32 texture_count = readU16(is); + for (u32 i = 0; i < texture_count; i++){ + textures.push_back(deSerializeString16(is)); + } + spritediv = readV2S16(is); + initial_sprite_basepos = readV2S16(is); + is_visible = readU8(is); + makes_footstep_sound = readU8(is); + automatic_rotate = readF32(is); + mesh = deSerializeString16(is); + colors.clear(); + u32 color_count = readU16(is); + for (u32 i = 0; i < color_count; i++){ + colors.push_back(readARGB8(is)); + } + collideWithObjects = readU8(is); + stepheight = readF32(is); + automatic_face_movement_dir = readU8(is); + automatic_face_movement_dir_offset = readF32(is); + backface_culling = readU8(is); + nametag = deSerializeString16(is); + nametag_color = readARGB8(is); + automatic_face_movement_max_rotation_per_sec = readF32(is); + infotext = deSerializeString16(is); + wield_item = deSerializeString16(is); + glow = readS8(is); + breath_max = readU16(is); + eye_height = readF32(is); + zoom_fov = readF32(is); + use_texture_alpha = readU8(is); + try { + damage_texture_modifier = deSerializeString16(is); + u8 tmp = readU8(is); + if (is.eof()) + return; + shaded = tmp; + tmp = readU8(is); + if (is.eof()) + return; + show_on_minimap = tmp; + + auto bgcolor = readARGB8(is); + if (bgcolor != NULL_BGCOLOR) + nametag_bgcolor = bgcolor; + else + nametag_bgcolor = nullopt; + } catch (SerializationError &e) {} +} diff --git a/src/object_properties.h b/src/object_properties.h new file mode 100644 index 0000000..79866a2 --- /dev/null +++ b/src/object_properties.h @@ -0,0 +1,75 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include "irrlichttypes_bloated.h" +#include <iostream> +#include <map> +#include <vector> +#include "util/Optional.h" + +struct ObjectProperties +{ + u16 hp_max = 1; + u16 breath_max = 0; + bool physical = false; + bool collideWithObjects = true; + // Values are BS=1 + aabb3f collisionbox = aabb3f(-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f); + aabb3f selectionbox = aabb3f(-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f); + bool pointable = true; + std::string visual = "sprite"; + std::string mesh = ""; + v3f visual_size = v3f(1, 1, 1); + std::vector<std::string> textures; + std::string damage_texture_modifier = "^[brighten"; + std::vector<video::SColor> colors; + v2s16 spritediv = v2s16(1, 1); + v2s16 initial_sprite_basepos; + bool is_visible = true; + bool makes_footstep_sound = false; + f32 stepheight = 0.0f; + float automatic_rotate = 0.0f; + bool automatic_face_movement_dir = false; + f32 automatic_face_movement_dir_offset = 0.0f; + bool backface_culling = true; + s8 glow = 0; + std::string nametag = ""; + video::SColor nametag_color = video::SColor(255, 255, 255, 255); + Optional<video::SColor> nametag_bgcolor = nullopt; + f32 automatic_face_movement_max_rotation_per_sec = -1.0f; + std::string infotext; + //! For dropped items, this contains item information. + std::string wield_item; + bool static_save = true; + float eye_height = 1.625f; + float zoom_fov = 0.0f; + bool use_texture_alpha = false; + bool shaded = true; + bool show_on_minimap = false; + + ObjectProperties(); + std::string dump(); + // check limits of some important properties (strings) that'd cause exceptions later on + bool validate(); + void serialize(std::ostream &os) const; + void deSerialize(std::istream &is); +}; diff --git a/src/particles.cpp b/src/particles.cpp new file mode 100644 index 0000000..e495ecd --- /dev/null +++ b/src/particles.cpp @@ -0,0 +1,176 @@ +/* +Minetest +Copyright (C) 2020 sfan5 <sfan5@live.de> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "particles.h" +#include <type_traits> +using namespace ParticleParamTypes; + +#define PARAM_PVFN(n) ParticleParamTypes::n##ParameterValue +v2f PARAM_PVFN(pick) (float* f, const v2f a, const v2f b) { + return v2f( + numericalBlend(f[0], a.X, b.X), + numericalBlend(f[1], a.Y, b.Y) + ); +} + +v3f PARAM_PVFN(pick) (float* f, const v3f a, const v3f b) { + return v3f( + numericalBlend(f[0], a.X, b.X), + numericalBlend(f[1], a.Y, b.Y), + numericalBlend(f[2], a.Z, b.Z) + ); +} + +v2f PARAM_PVFN(interpolate) (float fac, const v2f a, const v2f b) + { return b.getInterpolated(a, fac); } +v3f PARAM_PVFN(interpolate) (float fac, const v3f a, const v3f b) + { return b.getInterpolated(a, fac); } + +#define PARAM_DEF_SRZR(T, wr, rd) \ + void PARAM_PVFN(serialize) (std::ostream& os, T v) {wr(os,v); } \ + void PARAM_PVFN(deSerialize)(std::istream& is, T& v) {v = rd(is);} + + +#define PARAM_DEF_NUM(T, wr, rd) PARAM_DEF_SRZR(T, wr, rd) \ + T PARAM_PVFN(interpolate)(float fac, const T a, const T b) \ + { return numericalBlend<T>(fac,a,b); } \ + T PARAM_PVFN(pick) (float* f, const T a, const T b) \ + { return numericalBlend<T>(f[0],a,b); } + +PARAM_DEF_NUM(u8, writeU8, readU8); PARAM_DEF_NUM(s8, writeS8, readS8); +PARAM_DEF_NUM(u16, writeU16, readU16); PARAM_DEF_NUM(s16, writeS16, readS16); +PARAM_DEF_NUM(u32, writeU32, readU32); PARAM_DEF_NUM(s32, writeS32, readS32); +PARAM_DEF_NUM(f32, writeF32, readF32); +PARAM_DEF_SRZR(v2f, writeV2F32, readV2F32); +PARAM_DEF_SRZR(v3f, writeV3F32, readV3F32); + +enum class ParticleTextureFlags : u8 { + /* each value specifies a bit in a bitmask; if the maximum value + * goes above 1<<7 the type of the flags field must be changed + * from u8, which will necessitate a protocol change! */ + + // the first bit indicates whether the texture is animated + animated = 1, + + /* the next three bits indicate the blending mode of the texture + * blendmode is encoded by (flags |= (u8)blend << 1); retrieve with + * (flags & ParticleTextureFlags::blend) >> 1. note that the third + * bit is currently reserved for adding more blend modes in the future */ + blend = 0x7 << 1, +}; + +/* define some shorthand so we don't have to repeat ourselves or use + * decltype everywhere */ +using FlagT = std::underlying_type_t<ParticleTextureFlags>; + +void ServerParticleTexture::serialize(std::ostream &os, u16 protocol_ver, bool newPropertiesOnly) const +{ + /* newPropertiesOnly is used to de/serialize parameters of the legacy texture + * field, which are encoded separately from the texspec string */ + FlagT flags = 0; + if (animated) + flags |= FlagT(ParticleTextureFlags::animated); + if (blendmode != BlendMode::alpha) + flags |= FlagT(blendmode) << 1; + serializeParameterValue(os, flags); + + alpha.serialize(os); + scale.serialize(os); + if (!newPropertiesOnly) + os << serializeString32(string); + + if (animated) + animation.serialize(os, protocol_ver); +} + +void ServerParticleTexture::deSerialize(std::istream &is, u16 protocol_ver, bool newPropertiesOnly) +{ + FlagT flags = 0; + deSerializeParameterValue(is, flags); + + animated = !!(flags & FlagT(ParticleTextureFlags::animated)); + blendmode = BlendMode((flags & FlagT(ParticleTextureFlags::blend)) >> 1); + + alpha.deSerialize(is); + scale.deSerialize(is); + if (!newPropertiesOnly) + string = deSerializeString32(is); + + if (animated) + animation.deSerialize(is, protocol_ver); +} + +void ParticleParameters::serialize(std::ostream &os, u16 protocol_ver) const +{ + writeV3F32(os, pos); + writeV3F32(os, vel); + writeV3F32(os, acc); + writeF32(os, expirationtime); + writeF32(os, size); + writeU8(os, collisiondetection); + os << serializeString32(texture.string); + writeU8(os, vertical); + writeU8(os, collision_removal); + animation.serialize(os, protocol_ver); + writeU8(os, glow); + writeU8(os, object_collision); + writeU16(os, node.param0); + writeU8(os, node.param2); + writeU8(os, node_tile); + writeV3F32(os, drag); + jitter.serialize(os); + bounce.serialize(os); +} + +template <typename T, T (reader)(std::istream& is)> +inline bool streamEndsBeforeParam(T& val, std::istream& is) +{ + // This is kinda awful + T tmp = reader(is); + if (is.eof()) + return true; + val = tmp; + return false; +} + +void ParticleParameters::deSerialize(std::istream &is, u16 protocol_ver) +{ + pos = readV3F32(is); + vel = readV3F32(is); + acc = readV3F32(is); + expirationtime = readF32(is); + size = readF32(is); + collisiondetection = readU8(is); + texture.string = deSerializeString32(is); + vertical = readU8(is); + collision_removal = readU8(is); + animation.deSerialize(is, protocol_ver); + glow = readU8(is); + object_collision = readU8(is); + + if (streamEndsBeforeParam<u16, readU16>(node.param0, is)) + return; + node.param2 = readU8(is); + node_tile = readU8(is); + + if (streamEndsBeforeParam<v3f, readV3F32>(drag, is)) + return; + jitter.deSerialize(is); + bounce.deSerialize(is); +} diff --git a/src/particles.h b/src/particles.h new file mode 100644 index 0000000..3061deb --- /dev/null +++ b/src/particles.h @@ -0,0 +1,430 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <sstream> +#include <vector> +#include <ctgmath> +#include <type_traits> +#include "irrlichttypes_bloated.h" +#include "tileanimation.h" +#include "mapnode.h" +#include "util/serialize.h" +#include "util/numeric.h" + +// This file defines the particle-related structures that both the server and +// client need. The ParticleManager and rendering is in client/particles.h + +namespace ParticleParamTypes +{ + template <bool cond, typename T> + using enableIf = typename std::enable_if<cond, T>::type; + // std::enable_if_t does not appear to be present in GCC???? + // std::is_enum_v also missing. wtf. these are supposed to be + // present as of c++14 + + template<typename T> using BlendFunction = T(float,T,T); + #define DECL_PARAM_SRZRS(type) \ + void serializeParameterValue (std::ostream& os, type v); \ + void deSerializeParameterValue(std::istream& is, type& r); + #define DECL_PARAM_OVERLOADS(type) DECL_PARAM_SRZRS(type) \ + type interpolateParameterValue(float fac, const type a, const type b); \ + type pickParameterValue (float* facs, const type a, const type b); + + DECL_PARAM_OVERLOADS(u8); DECL_PARAM_OVERLOADS(s8); + DECL_PARAM_OVERLOADS(u16); DECL_PARAM_OVERLOADS(s16); + DECL_PARAM_OVERLOADS(u32); DECL_PARAM_OVERLOADS(s32); + DECL_PARAM_OVERLOADS(f32); + DECL_PARAM_OVERLOADS(v2f); + DECL_PARAM_OVERLOADS(v3f); + + /* C++ is a strongly typed language. this means that enums cannot be implicitly + * cast to integers, as they can be in C. while this may sound good in principle, + * it means that our normal serialization functions cannot be called on + * enumerations unless they are explicitly cast to a particular type first. this + * is problematic, because in C++ enums can have any integral type as an underlying + * type, and that type would need to be named everywhere an enumeration is + * de/serialized. + * + * this is obviously not cool, both in terms of writing legible, succinct code, + * and in terms of robustness: the underlying type might be changed at some point, + * e.g. if a bitmask gets too big for its britches. we could use an equivalent of + * `std::to_underlying(value)` everywhere we need to deal with enumerations, but + * that's hideous and unintuitive. instead, we supply the following functions to + * transparently map enumeration types to their underlying values. */ + + template <typename E, enableIf<std::is_enum<E>::value, bool> = true> + void serializeParameterValue(std::ostream& os, E k) { + serializeParameterValue(os, (std::underlying_type_t<E>)k); + } + + template <typename E, enableIf<std::is_enum<E>::value, bool> = true> + void deSerializeParameterValue(std::istream& is, E& k) { + std::underlying_type_t<E> v; + deSerializeParameterValue(is, v); + k = (E)v; + } + + /* this is your brain on C++. */ + + template <typename T, size_t PN> + struct Parameter + { + using ValType = T; + using pickFactors = float[PN]; + + T val = T(); + using This = Parameter<T, PN>; + + Parameter() = default; + + template <typename... Args> + Parameter(Args... args) : val(args...) {} + + virtual void serialize(std::ostream &os) const + { serializeParameterValue (os, this->val); } + virtual void deSerialize(std::istream &is) + { deSerializeParameterValue(is, this->val); } + + virtual T interpolate(float fac, const This& against) const + { + return interpolateParameterValue(fac, this->val, against.val); + } + + static T pick(float* f, const This& a, const This& b) + { + return pickParameterValue(f, a.val, b.val); + } + + operator T() const { return val; } + T operator=(T b) { return val = b; } + + }; + + template <typename T> T numericalBlend(float fac, T min, T max) + { return min + ((max - min) * fac); } + + template <typename T, size_t N> + struct VectorParameter : public Parameter<T,N> { + using This = VectorParameter<T,N>; + template <typename... Args> + VectorParameter(Args... args) : Parameter<T,N>(args...) {} + }; + + template <typename T, size_t PN> + inline std::string dump(const Parameter<T,PN>& p) + { + return std::to_string(p.val); + } + + template <typename T, size_t N> + inline std::string dump(const VectorParameter<T,N>& v) + { + std::ostringstream oss; + if (N == 3) + oss << PP(v.val); + else + oss << PP2(v.val); + return oss.str(); + } + + using u8Parameter = Parameter<u8, 1>; using s8Parameter = Parameter<s8, 1>; + using u16Parameter = Parameter<u16, 1>; using s16Parameter = Parameter<s16, 1>; + using u32Parameter = Parameter<u32, 1>; using s32Parameter = Parameter<s32, 1>; + + using f32Parameter = Parameter<f32, 1>; + + using v2fParameter = VectorParameter<v2f, 2>; + using v3fParameter = VectorParameter<v3f, 3>; + + template <typename T> + struct RangedParameter + { + using ValType = T; + using This = RangedParameter<T>; + + T min, max; + f32 bias = 0; + + RangedParameter() = default; + RangedParameter(T _min, T _max) : min(_min), max(_max) {} + template <typename M> RangedParameter(M b) : min(b), max(b) {} + + // these functions handle the old range serialization "format"; bias must + // be manually encoded in a separate part of the stream. NEVER ADD FIELDS + // TO THESE FUNCTIONS + void legacySerialize(std::ostream& os) const + { + min.serialize(os); + max.serialize(os); + } + void legacyDeSerialize(std::istream& is) + { + min.deSerialize(is); + max.deSerialize(is); + } + + // these functions handle the format used by new fields. new fields go here + void serialize(std::ostream &os) const + { + legacySerialize(os); + writeF32(os, bias); + } + void deSerialize(std::istream &is) + { + legacyDeSerialize(is); + bias = readF32(is); + } + + This interpolate(float fac, const This against) const + { + This r; + r.min = min.interpolate(fac, against.min); + r.max = max.interpolate(fac, against.max); + r.bias = bias; + return r; + } + + T pickWithin() const + { + typename T::pickFactors values; + auto p = numericAbsolute(bias) + 1; + for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) { + if (bias < 0) + values[i] = 1.0f - pow(myrand_float(), p); + else + values[i] = pow(myrand_float(), p); + } + return T::pick(values, min, max); + } + + }; + + template <typename T> + inline std::string dump(const RangedParameter<T>& r) + { + std::ostringstream s; + s << "range<" << dump(r.min) << " ~ " << dump(r.max); + if (r.bias != 0) + s << " :: " << r.bias; + s << ">"; + return s.str(); + } + + enum class TweenStyle : u8 { fwd, rev, pulse, flicker }; + + template <typename T> + struct TweenedParameter + { + using ValType = T; + using This = TweenedParameter<T>; + + TweenStyle style = TweenStyle::fwd; + u16 reps = 1; + f32 beginning = 0.0f; + + T start, end; + + TweenedParameter() = default; + TweenedParameter(T _start, T _end) : start(_start), end(_end) {} + template <typename M> TweenedParameter(M b) : start(b), end(b) {} + + T blend(float fac) const + { + // warp time coordinates in accordance w/ settings + if (fac > beginning) { + // remap for beginning offset + auto len = 1 - beginning; + fac -= beginning; + fac /= len; + + // remap for repetitions + fac *= reps; + if (fac > 1) // poor man's modulo + fac -= (decltype(reps))fac; + + // remap for style + switch (style) { + case TweenStyle::fwd: /* do nothing */ break; + case TweenStyle::rev: fac = 1.0f - fac; break; + case TweenStyle::pulse: + case TweenStyle::flicker: { + if (fac > 0.5f) { + fac = 1.f - (fac*2.f - 1.f); + } else { + fac = fac * 2; + } + if (style == TweenStyle::flicker) { + fac *= myrand_range(0.7f, 1.0f); + } + } + } + if (fac>1.f) + fac = 1.f; + else if (fac<0.f) + fac = 0.f; + } else { + fac = (style == TweenStyle::rev) ? 1.f : 0.f; + } + + return start.interpolate(fac, end); + } + + void serialize(std::ostream &os) const + { + writeU8(os, static_cast<u8>(style)); + writeU16(os, reps); + writeF32(os, beginning); + start.serialize(os); + end.serialize(os); + } + void deSerialize(std::istream &is) + { + style = static_cast<TweenStyle>(readU8(is)); + reps = readU16(is); + beginning = readF32(is); + start.deSerialize(is); + end.deSerialize(is); + } + }; + + template <typename T> + inline std::string dump(const TweenedParameter<T>& t) + { + std::ostringstream s; + const char* icon; + switch (t.style) { + case TweenStyle::fwd: icon = "→"; break; + case TweenStyle::rev: icon = "←"; break; + case TweenStyle::pulse: icon = "↔"; break; + case TweenStyle::flicker: icon = "↯"; break; + } + s << "tween<"; + if (t.reps != 1) + s << t.reps << "x "; + s << dump(t.start) << " "<<icon<<" " << dump(t.end) << ">"; + return s.str(); + } + + enum class AttractorKind : u8 { none, point, line, plane }; + enum class BlendMode : u8 { alpha, add, sub, screen }; + + // these are consistently-named convenience aliases to make code more readable without `using ParticleParamTypes` declarations + using v3fRange = RangedParameter<v3fParameter>; + using f32Range = RangedParameter<f32Parameter>; + + using v2fTween = TweenedParameter<v2fParameter>; + using v3fTween = TweenedParameter<v3fParameter>; + using f32Tween = TweenedParameter<f32Parameter>; + using v3fRangeTween = TweenedParameter<v3fRange>; + using f32RangeTween = TweenedParameter<f32Range>; + + #undef DECL_PARAM_SRZRS + #undef DECL_PARAM_OVERLOADS +} + +struct ParticleTexture +{ + bool animated = false; + ParticleParamTypes::BlendMode blendmode = ParticleParamTypes::BlendMode::alpha; + TileAnimationParams animation; + ParticleParamTypes::f32Tween alpha{1.0f}; + ParticleParamTypes::v2fTween scale{v2f(1.0f)}; +}; + +struct ServerParticleTexture : public ParticleTexture +{ + std::string string; + void serialize(std::ostream &os, u16 protocol_ver, bool newPropertiesOnly = false) const; + void deSerialize(std::istream &is, u16 protocol_ver, bool newPropertiesOnly = false); +}; + +struct CommonParticleParams +{ + bool collisiondetection = false; + bool collision_removal = false; + bool object_collision = false; + bool vertical = false; + ServerParticleTexture texture; + struct TileAnimationParams animation; + u8 glow = 0; + MapNode node; + u8 node_tile = 0; + + CommonParticleParams() { + animation.type = TAT_NONE; + node.setContent(CONTENT_IGNORE); + } + + /* This helper is useful for copying params from + * ParticleSpawnerParameters to ParticleParameters */ + inline void copyCommon(CommonParticleParams &to) const { + to.collisiondetection = collisiondetection; + to.collision_removal = collision_removal; + to.object_collision = object_collision; + to.vertical = vertical; + to.texture = texture; + to.animation = animation; + to.glow = glow; + to.node = node; + to.node_tile = node_tile; + } +}; + +struct ParticleParameters : CommonParticleParams +{ + v3f pos, vel, acc, drag; + f32 size = 1, expirationtime = 1; + ParticleParamTypes::f32Range bounce; + ParticleParamTypes::v3fRange jitter; + + void serialize(std::ostream &os, u16 protocol_ver) const; + void deSerialize(std::istream &is, u16 protocol_ver); +}; + +struct ParticleSpawnerParameters : CommonParticleParams +{ + u16 amount = 1; + f32 time = 1; + + std::vector<ServerParticleTexture> texpool; + + ParticleParamTypes::v3fRangeTween + pos, vel, acc, drag, radius, jitter; + + ParticleParamTypes::AttractorKind + attractor_kind; + ParticleParamTypes::v3fTween + attractor_origin, attractor_direction; + // object IDs + u16 attractor_attachment = 0, + attractor_direction_attachment = 0; + // do particles disappear when they cross the attractor threshold? + bool attractor_kill = true; + + ParticleParamTypes::f32RangeTween + exptime{1.0f}, + size {1.0f}, + attract{0.0f}, + bounce {0.0f}; + + // For historical reasons no (de-)serialization methods here +}; diff --git a/src/pathfinder.cpp b/src/pathfinder.cpp new file mode 100644 index 0000000..c45ce91 --- /dev/null +++ b/src/pathfinder.cpp @@ -0,0 +1,1441 @@ +/* +Minetest +Copyright (C) 2013 sapier, sapier at gmx dot net +Copyright (C) 2016 est31, <MTest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/******************************************************************************/ +/* Includes */ +/******************************************************************************/ + +#include "pathfinder.h" +#include "map.h" +#include "nodedef.h" + +//#define PATHFINDER_DEBUG +//#define PATHFINDER_CALC_TIME + +#ifdef PATHFINDER_DEBUG + #include <string> +#endif +#ifdef PATHFINDER_DEBUG + #include <iomanip> +#endif +#ifdef PATHFINDER_CALC_TIME + #include <sys/time.h> +#endif + +/******************************************************************************/ +/* Typedefs and macros */ +/******************************************************************************/ + +#define LVL "(" << level << ")" << + +#ifdef PATHFINDER_DEBUG +#define DEBUG_OUT(a) std::cout << a +#define INFO_TARGET std::cout +#define VERBOSE_TARGET std::cout +#define ERROR_TARGET std::cout +#else +#define DEBUG_OUT(a) while(0) +#define INFO_TARGET infostream << "Pathfinder: " +#define VERBOSE_TARGET verbosestream << "Pathfinder: " +#define ERROR_TARGET warningstream << "Pathfinder: " +#endif + +#define PATHFINDER_MAX_WAYPOINTS 700 + +/******************************************************************************/ +/* Class definitions */ +/******************************************************************************/ + + +/** representation of cost in specific direction */ +class PathCost { +public: + + /** default constructor */ + PathCost() = default; + + /** copy constructor */ + PathCost(const PathCost &b); + + /** assignment operator */ + PathCost &operator= (const PathCost &b); + + bool valid = false; /**< movement is possible */ + int value = 0; /**< cost of movement */ + int y_change = 0; /**< change of y position of movement */ + bool updated = false; /**< this cost has ben calculated */ + +}; + + +/** representation of a mapnode to be used for pathfinding */ +class PathGridnode { + +public: + /** default constructor */ + PathGridnode() = default; + + /** copy constructor */ + PathGridnode(const PathGridnode &b); + + /** + * assignment operator + * @param b node to copy + */ + PathGridnode &operator= (const PathGridnode &b); + + /** + * read cost in a specific direction + * @param dir direction of cost to fetch + */ + PathCost getCost(v3s16 dir); + + /** + * set cost value for movement + * @param dir direction to set cost for + * @cost cost to set + */ + void setCost(v3s16 dir, const PathCost &cost); + + bool valid = false; /**< node is on surface */ + bool target = false; /**< node is target position */ + bool source = false; /**< node is stating position */ + int totalcost = -1; /**< cost to move here from starting point */ + int estimated_cost = -1; /**< totalcost + heuristic cost to end */ + v3s16 sourcedir; /**< origin of movement for current cost */ + v3s16 pos; /**< real position of node */ + PathCost directions[4]; /**< cost in different directions */ + bool is_closed = false; /**< for A* search: if true, is in closed list */ + bool is_open = false; /**< for A* search: if true, is in open list */ + + /* debug values */ + bool is_element = false; /**< node is element of path detected */ + char type = 'u'; /**< Type of pathfinding node. + * u = unknown + * i = invalid + * s = surface (walkable node) + * - = non-walkable node (e.g. air) above surface + * g = other non-walkable node + */ +}; + +class Pathfinder; +class PathfinderCompareHeuristic; + +/** Abstract class to manage the map data */ +class GridNodeContainer { +public: + virtual PathGridnode &access(v3s16 p)=0; + virtual ~GridNodeContainer() = default; + +protected: + Pathfinder *m_pathf; + + void initNode(v3s16 ipos, PathGridnode *p_node); +}; + +class ArrayGridNodeContainer : public GridNodeContainer { +public: + virtual ~ArrayGridNodeContainer() = default; + + ArrayGridNodeContainer(Pathfinder *pathf, v3s16 dimensions); + virtual PathGridnode &access(v3s16 p); + +private: + int m_x_stride; + int m_y_stride; + std::vector<PathGridnode> m_nodes_array; +}; + +class MapGridNodeContainer : public GridNodeContainer { +public: + virtual ~MapGridNodeContainer() = default; + + MapGridNodeContainer(Pathfinder *pathf); + virtual PathGridnode &access(v3s16 p); +private: + std::map<v3s16, PathGridnode> m_nodes; +}; + +/** class doing pathfinding */ +class Pathfinder { + +public: + Pathfinder() = delete; + Pathfinder(Map *map, const NodeDefManager *ndef) : m_map(map), m_ndef(ndef) {} + + ~Pathfinder(); + + /** + * path evaluation function + * @param env environment to look for path + * @param source origin of path + * @param destination end position of path + * @param searchdistance maximum number of nodes to look in each direction + * @param max_jump maximum number of blocks a path may jump up + * @param max_drop maximum number of blocks a path may drop + * @param algo Algorithm to use for finding a path + */ + std::vector<v3s16> getPath(v3s16 source, + v3s16 destination, + unsigned int searchdistance, + unsigned int max_jump, + unsigned int max_drop, + PathAlgorithm algo); + +private: + /* helper functions */ + + /** + * transform index pos to mappos + * @param ipos a index position + * @return map position + */ + v3s16 getRealPos(v3s16 ipos); + + /** + * transform mappos to index pos + * @param pos a real pos + * @return index position + */ + v3s16 getIndexPos(v3s16 pos); + + /** + * get gridnode at a specific index position + * @param ipos index position + * @return gridnode for index + */ + PathGridnode &getIndexElement(v3s16 ipos); + + /** + * Get gridnode at a specific index position + * @return gridnode for index + */ + PathGridnode &getIdxElem(s16 x, s16 y, s16 z); + + /** + * invert a 3D position (change sign of coordinates) + * @param pos 3D position + * @return pos *-1 + */ + v3s16 invert(v3s16 pos); + + /** + * check if a index is within current search area + * @param index position to validate + * @return true/false + */ + bool isValidIndex(v3s16 index); + + + /* algorithm functions */ + + /** + * calculate 2D Manhattan distance to target + * @param pos position to calc distance + * @return integer distance + */ + int getXZManhattanDist(v3s16 pos); + + /** + * calculate cost of movement + * @param pos real world position to start movement + * @param dir direction to move to + * @return cost information + */ + PathCost calcCost(v3s16 pos, v3s16 dir); + + /** + * recursive update whole search areas total cost information + * @param ipos position to check next + * @param srcdir positionc checked last time + * @param total_cost cost of moving to ipos + * @param level current recursion depth + * @return true/false path to destination has been found + */ + bool updateAllCosts(v3s16 ipos, v3s16 srcdir, int current_cost, int level); + + /** + * try to find a path to destination using a heuristic function + * to estimate distance to target (A* search algorithm) + * @param isource start position (index pos) + * @param idestination end position (index pos) + * @return true/false path to destination has been found + */ + bool updateCostHeuristic(v3s16 isource, v3s16 idestination); + + /** + * build a vector containing all nodes from destination to source; + * to be called after the node costs have been processed + * @param path vector to add nodes to + * @param ipos initial pos to check (index pos) + * @return true/false path has been fully built + */ + bool buildPath(std::vector<v3s16> &path, v3s16 ipos); + + /** + * go downwards from a position until some barrier + * is hit. + * @param pos position from which to go downwards + * @param max_down maximum distance to go downwards + * @return new position after movement; if too far down, + * pos is returned + */ + v3s16 walkDownwards(v3s16 pos, unsigned int max_down); + + /* variables */ + int m_max_index_x = 0; /**< max index of search area in x direction */ + int m_max_index_y = 0; /**< max index of search area in y direction */ + int m_max_index_z = 0; /**< max index of search area in z direction */ + + int m_maxdrop = 0; /**< maximum number of blocks a path may drop */ + int m_maxjump = 0; /**< maximum number of blocks a path may jump */ + int m_min_target_distance = 0; /**< current smalest path to target */ + + bool m_prefetch = true; /**< prefetch cost data */ + + v3s16 m_start; /**< source position */ + v3s16 m_destination; /**< destination position */ + + core::aabbox3d<s16> m_limits; /**< position limits in real map coordinates */ + + /** contains all map data already collected and analyzed. + Access it via the getIndexElement/getIdxElem methods. */ + friend class GridNodeContainer; + GridNodeContainer *m_nodes_container = nullptr; + + Map *m_map = nullptr; + + const NodeDefManager *m_ndef = nullptr; + + friend class PathfinderCompareHeuristic; + +#ifdef PATHFINDER_DEBUG + + /** + * print collected cost information + */ + void printCost(); + + /** + * print collected cost information in a specific direction + * @param dir direction to print + */ + void printCost(PathDirections dir); + + /** + * print type of node as evaluated + */ + void printType(); + + /** + * print pathlenght for all nodes in search area + */ + void printPathLen(); + + /** + * print a path + * @param path path to show + */ + void printPath(std::vector<v3s16> path); + + /** + * print y direction for all movements + */ + void printYdir(); + + /** + * print y direction for moving in a specific direction + * @param dir direction to show data + */ + void printYdir(PathDirections dir); + + /** + * helper function to translate a direction to speaking text + * @param dir direction to translate + * @return textual name of direction + */ + std::string dirToName(PathDirections dir); +#endif +}; + +/** Helper class for the open list priority queue in the A* pathfinder + * to sort the pathfinder nodes by cost. + */ +class PathfinderCompareHeuristic +{ + private: + Pathfinder *myPathfinder; + public: + PathfinderCompareHeuristic(Pathfinder *pf) + { + myPathfinder = pf; + } + bool operator() (v3s16 pos1, v3s16 pos2) { + v3s16 ipos1 = myPathfinder->getIndexPos(pos1); + v3s16 ipos2 = myPathfinder->getIndexPos(pos2); + PathGridnode &g_pos1 = myPathfinder->getIndexElement(ipos1); + PathGridnode &g_pos2 = myPathfinder->getIndexElement(ipos2); + if (!g_pos1.valid) + return false; + if (!g_pos2.valid) + return false; + return g_pos1.estimated_cost > g_pos2.estimated_cost; + } +}; + +/******************************************************************************/ +/* implementation */ +/******************************************************************************/ + +std::vector<v3s16> get_path(Map* map, const NodeDefManager *ndef, + v3s16 source, + v3s16 destination, + unsigned int searchdistance, + unsigned int max_jump, + unsigned int max_drop, + PathAlgorithm algo) +{ + return Pathfinder(map, ndef).getPath(source, destination, + searchdistance, max_jump, max_drop, algo); +} + +/******************************************************************************/ +PathCost::PathCost(const PathCost &b) +{ + valid = b.valid; + y_change = b.y_change; + value = b.value; + updated = b.updated; +} + +/******************************************************************************/ +PathCost &PathCost::operator= (const PathCost &b) +{ + valid = b.valid; + y_change = b.y_change; + value = b.value; + updated = b.updated; + + return *this; +} + +/******************************************************************************/ +PathGridnode::PathGridnode(const PathGridnode &b) +: valid(b.valid), + target(b.target), + source(b.source), + totalcost(b.totalcost), + sourcedir(b.sourcedir), + pos(b.pos), + is_element(b.is_element), + type(b.type) +{ + + directions[DIR_XP] = b.directions[DIR_XP]; + directions[DIR_XM] = b.directions[DIR_XM]; + directions[DIR_ZP] = b.directions[DIR_ZP]; + directions[DIR_ZM] = b.directions[DIR_ZM]; +} + +/******************************************************************************/ +PathGridnode &PathGridnode::operator= (const PathGridnode &b) +{ + valid = b.valid; + target = b.target; + source = b.source; + is_element = b.is_element; + totalcost = b.totalcost; + sourcedir = b.sourcedir; + pos = b.pos; + type = b.type; + + directions[DIR_XP] = b.directions[DIR_XP]; + directions[DIR_XM] = b.directions[DIR_XM]; + directions[DIR_ZP] = b.directions[DIR_ZP]; + directions[DIR_ZM] = b.directions[DIR_ZM]; + + return *this; +} + +/******************************************************************************/ +PathCost PathGridnode::getCost(v3s16 dir) +{ + if (dir.X > 0) { + return directions[DIR_XP]; + } + if (dir.X < 0) { + return directions[DIR_XM]; + } + if (dir.Z > 0) { + return directions[DIR_ZP]; + } + if (dir.Z < 0) { + return directions[DIR_ZM]; + } + PathCost retval; + return retval; +} + +/******************************************************************************/ +void PathGridnode::setCost(v3s16 dir, const PathCost &cost) +{ + if (dir.X > 0) { + directions[DIR_XP] = cost; + } + if (dir.X < 0) { + directions[DIR_XM] = cost; + } + if (dir.Z > 0) { + directions[DIR_ZP] = cost; + } + if (dir.Z < 0) { + directions[DIR_ZM] = cost; + } +} + +void GridNodeContainer::initNode(v3s16 ipos, PathGridnode *p_node) +{ + const NodeDefManager *ndef = m_pathf->m_ndef; + PathGridnode &elem = *p_node; + + v3s16 realpos = m_pathf->getRealPos(ipos); + + MapNode current = m_pathf->m_map->getNode(realpos); + MapNode below = m_pathf->m_map->getNode(realpos + v3s16(0, -1, 0)); + + + if ((current.param0 == CONTENT_IGNORE) || + (below.param0 == CONTENT_IGNORE)) { + DEBUG_OUT("Pathfinder: " << PP(realpos) << + " current or below is invalid element" << std::endl); + if (current.param0 == CONTENT_IGNORE) { + elem.type = 'i'; + DEBUG_OUT(PP(ipos) << ": " << 'i' << std::endl); + } + return; + } + + //don't add anything if it isn't an air node + if (ndef->get(current).walkable || !ndef->get(below).walkable) { + DEBUG_OUT("Pathfinder: " << PP(realpos) + << " not on surface" << std::endl); + if (ndef->get(current).walkable) { + elem.type = 's'; + DEBUG_OUT(PP(ipos) << ": " << 's' << std::endl); + } else { + elem.type = '-'; + DEBUG_OUT(PP(ipos) << ": " << '-' << std::endl); + } + return; + } + + elem.valid = true; + elem.pos = realpos; + elem.type = 'g'; + DEBUG_OUT(PP(ipos) << ": " << 'a' << std::endl); + + if (m_pathf->m_prefetch) { + elem.directions[DIR_XP] = m_pathf->calcCost(realpos, v3s16( 1, 0, 0)); + elem.directions[DIR_XM] = m_pathf->calcCost(realpos, v3s16(-1, 0, 0)); + elem.directions[DIR_ZP] = m_pathf->calcCost(realpos, v3s16( 0, 0, 1)); + elem.directions[DIR_ZM] = m_pathf->calcCost(realpos, v3s16( 0, 0,-1)); + } +} + +ArrayGridNodeContainer::ArrayGridNodeContainer(Pathfinder *pathf, v3s16 dimensions) : + m_x_stride(dimensions.Y * dimensions.Z), + m_y_stride(dimensions.Z) +{ + m_pathf = pathf; + + m_nodes_array.resize(dimensions.X * dimensions.Y * dimensions.Z); + INFO_TARGET << "Pathfinder ArrayGridNodeContainer constructor." << std::endl; + for (int x = 0; x < dimensions.X; x++) { + for (int y = 0; y < dimensions.Y; y++) { + for (int z= 0; z < dimensions.Z; z++) { + v3s16 ipos(x, y, z); + initNode(ipos, &access(ipos)); + } + } + } +} + +PathGridnode &ArrayGridNodeContainer::access(v3s16 p) +{ + return m_nodes_array[p.X * m_x_stride + p.Y * m_y_stride + p.Z]; +} + +MapGridNodeContainer::MapGridNodeContainer(Pathfinder *pathf) +{ + m_pathf = pathf; +} + +PathGridnode &MapGridNodeContainer::access(v3s16 p) +{ + std::map<v3s16, PathGridnode>::iterator it = m_nodes.find(p); + if (it != m_nodes.end()) { + return it->second; + } + PathGridnode &n = m_nodes[p]; + initNode(p, &n); + return n; +} + + + +/******************************************************************************/ +std::vector<v3s16> Pathfinder::getPath(v3s16 source, + v3s16 destination, + unsigned int searchdistance, + unsigned int max_jump, + unsigned int max_drop, + PathAlgorithm algo) +{ +#ifdef PATHFINDER_CALC_TIME + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); +#endif + std::vector<v3s16> retval; + + //initialization + m_maxjump = max_jump; + m_maxdrop = max_drop; + m_start = source; + m_destination = destination; + m_min_target_distance = -1; + m_prefetch = true; + + if (algo == PA_PLAIN_NP) { + m_prefetch = false; + } + + //calculate boundaries within we're allowed to search + int min_x = MYMIN(source.X, destination.X); + int max_x = MYMAX(source.X, destination.X); + + int min_y = MYMIN(source.Y, destination.Y); + int max_y = MYMAX(source.Y, destination.Y); + + int min_z = MYMIN(source.Z, destination.Z); + int max_z = MYMAX(source.Z, destination.Z); + + m_limits.MinEdge.X = min_x - searchdistance; + m_limits.MinEdge.Y = min_y - searchdistance; + m_limits.MinEdge.Z = min_z - searchdistance; + + m_limits.MaxEdge.X = max_x + searchdistance; + m_limits.MaxEdge.Y = max_y + searchdistance; + m_limits.MaxEdge.Z = max_z + searchdistance; + + v3s16 diff = m_limits.MaxEdge - m_limits.MinEdge; + + m_max_index_x = diff.X; + m_max_index_y = diff.Y; + m_max_index_z = diff.Z; + + delete m_nodes_container; + if (diff.getLength() > 5) { + m_nodes_container = new MapGridNodeContainer(this); + } else { + m_nodes_container = new ArrayGridNodeContainer(this, diff); + } +#ifdef PATHFINDER_DEBUG + printType(); + printCost(); + printYdir(); +#endif + + //fail if source or destination is walkable + MapNode node_at_pos = m_map->getNode(destination); + if (m_ndef->get(node_at_pos).walkable) { + VERBOSE_TARGET << "Destination is walkable. " << + "Pos: " << PP(destination) << std::endl; + return retval; + } + node_at_pos = m_map->getNode(source); + if (m_ndef->get(node_at_pos).walkable) { + VERBOSE_TARGET << "Source is walkable. " << + "Pos: " << PP(source) << std::endl; + return retval; + } + + //If source pos is hovering above air, drop + //to the first walkable node (up to m_maxdrop). + //All algorithms expect the source pos to be *directly* above + //a walkable node. + v3s16 true_source = v3s16(source); + source = walkDownwards(source, m_maxdrop); + + //If destination pos is hovering above air, go downwards + //to the first walkable node (up to m_maxjump). + //This means a hovering destination pos could be reached + //by a final upwards jump. + v3s16 true_destination = v3s16(destination); + destination = walkDownwards(destination, m_maxjump); + + //validate and mark start and end pos + + v3s16 StartIndex = getIndexPos(source); + v3s16 EndIndex = getIndexPos(destination); + + PathGridnode &startpos = getIndexElement(StartIndex); + PathGridnode &endpos = getIndexElement(EndIndex); + + if (!startpos.valid) { + VERBOSE_TARGET << "Invalid startpos " << + "Index: " << PP(StartIndex) << + "Realpos: " << PP(getRealPos(StartIndex)) << std::endl; + return retval; + } + if (!endpos.valid) { + VERBOSE_TARGET << "Invalid stoppos " << + "Index: " << PP(EndIndex) << + "Realpos: " << PP(getRealPos(EndIndex)) << std::endl; + return retval; + } + + endpos.target = true; + startpos.source = true; + startpos.totalcost = 0; + + bool update_cost_retval = false; + + //calculate node costs + switch (algo) { + case PA_DIJKSTRA: + update_cost_retval = updateAllCosts(StartIndex, v3s16(0, 0, 0), 0, 0); + break; + case PA_PLAIN_NP: + case PA_PLAIN: + update_cost_retval = updateCostHeuristic(StartIndex, EndIndex); + break; + default: + ERROR_TARGET << "Missing PathAlgorithm" << std::endl; + break; + } + + if (update_cost_retval) { + +#ifdef PATHFINDER_DEBUG + std::cout << "Path to target found!" << std::endl; + printPathLen(); +#endif + + //find path + std::vector<v3s16> index_path; + buildPath(index_path, EndIndex); + //Now we have a path of index positions, + //and it's in reverse. + //The "true" start or end position might be missing + //since those have been given special treatment. + +#ifdef PATHFINDER_DEBUG + std::cout << "Index path:" << std::endl; + printPath(index_path); +#endif + //from here we'll make the final changes to the path + std::vector<v3s16> full_path; + + //calculate required size + int full_path_size = index_path.size(); + if (source != true_source) { + full_path_size++; + } + if (destination != true_destination) { + full_path_size++; + } + full_path.reserve(full_path_size); + + //manually add true_source to start of path, if needed + if (source != true_source) { + full_path.push_back(true_source); + } + //convert all index positions to "normal" positions and insert + //them into full_path in reverse + std::vector<v3s16>::reverse_iterator rit = index_path.rbegin(); + for (; rit != index_path.rend(); ++rit) { + full_path.push_back(getIndexElement(*rit).pos); + } + //manually add true_destination to end of path, if needed + if (destination != true_destination) { + full_path.push_back(true_destination); + } + + //Done! We now have a complete path of normal positions. + + +#ifdef PATHFINDER_DEBUG + std::cout << "Full path:" << std::endl; + printPath(full_path); +#endif +#ifdef PATHFINDER_CALC_TIME + timespec ts2; + clock_gettime(CLOCK_REALTIME, &ts2); + + int ms = (ts2.tv_nsec - ts.tv_nsec)/(1000*1000); + int us = ((ts2.tv_nsec - ts.tv_nsec) - (ms*1000*1000))/1000; + int ns = ((ts2.tv_nsec - ts.tv_nsec) - ( (ms*1000*1000) + (us*1000))); + + + std::cout << "Calculating path took: " << (ts2.tv_sec - ts.tv_sec) << + "s " << ms << "ms " << us << "us " << ns << "ns " << std::endl; +#endif + return full_path; + } + else { +#ifdef PATHFINDER_DEBUG + printPathLen(); +#endif + INFO_TARGET << "No path found" << std::endl; + } + + + //return + return retval; +} + +Pathfinder::~Pathfinder() +{ + delete m_nodes_container; +} +/******************************************************************************/ +v3s16 Pathfinder::getRealPos(v3s16 ipos) +{ + return m_limits.MinEdge + ipos; +} + +/******************************************************************************/ +PathCost Pathfinder::calcCost(v3s16 pos, v3s16 dir) +{ + PathCost retval; + + retval.updated = true; + + v3s16 pos2 = pos + dir; + + //check limits + if (!m_limits.isPointInside(pos2)) { + DEBUG_OUT("Pathfinder: " << PP(pos2) << + " no cost -> out of limits" << std::endl); + return retval; + } + + MapNode node_at_pos2 = m_map->getNode(pos2); + + //did we get information about node? + if (node_at_pos2.param0 == CONTENT_IGNORE ) { + VERBOSE_TARGET << "Pathfinder: (1) area at pos: " + << PP(pos2) << " not loaded"; + return retval; + } + + if (!m_ndef->get(node_at_pos2).walkable) { + MapNode node_below_pos2 = + m_map->getNode(pos2 + v3s16(0, -1, 0)); + + //did we get information about node? + if (node_below_pos2.param0 == CONTENT_IGNORE ) { + VERBOSE_TARGET << "Pathfinder: (2) area at pos: " + << PP((pos2 + v3s16(0, -1, 0))) << " not loaded"; + return retval; + } + + //test if the same-height neighbor is suitable + if (m_ndef->get(node_below_pos2).walkable) { + //SUCCESS! + retval.valid = true; + retval.value = 1; + retval.y_change = 0; + DEBUG_OUT("Pathfinder: "<< PP(pos) + << " cost same height found" << std::endl); + } + else { + //test if we can fall a couple of nodes (m_maxdrop) + v3s16 testpos = pos2 + v3s16(0, -1, 0); + MapNode node_at_pos = m_map->getNode(testpos); + + while ((node_at_pos.param0 != CONTENT_IGNORE) && + (!m_ndef->get(node_at_pos).walkable) && + (testpos.Y > m_limits.MinEdge.Y)) { + testpos += v3s16(0, -1, 0); + node_at_pos = m_map->getNode(testpos); + } + + //did we find surface? + if ((testpos.Y >= m_limits.MinEdge.Y) && + (node_at_pos.param0 != CONTENT_IGNORE) && + (m_ndef->get(node_at_pos).walkable)) { + if ((pos2.Y - testpos.Y - 1) <= m_maxdrop) { + //SUCCESS! + retval.valid = true; + retval.value = 2; + //difference of y-pos +1 (target node is ABOVE solid node) + retval.y_change = ((testpos.Y - pos2.Y) +1); + DEBUG_OUT("Pathfinder cost below height found" << std::endl); + } + else { + INFO_TARGET << "Pathfinder:" + " distance to surface below too big: " + << (testpos.Y - pos2.Y) << " max: " << m_maxdrop + << std::endl; + } + } + else { + DEBUG_OUT("Pathfinder: no surface below found" << std::endl); + } + } + } + else { + //test if we can jump upwards (m_maxjump) + + v3s16 targetpos = pos2; // position for jump target + v3s16 jumppos = pos; // position for checking if jumping space is free + MapNode node_target = m_map->getNode(targetpos); + MapNode node_jump = m_map->getNode(jumppos); + bool headbanger = false; // true if anything blocks jumppath + + while ((node_target.param0 != CONTENT_IGNORE) && + (m_ndef->get(node_target).walkable) && + (targetpos.Y < m_limits.MaxEdge.Y)) { + //if the jump would hit any solid node, discard + if ((node_jump.param0 == CONTENT_IGNORE) || + (m_ndef->get(node_jump).walkable)) { + headbanger = true; + break; + } + targetpos += v3s16(0, 1, 0); + jumppos += v3s16(0, 1, 0); + node_target = m_map->getNode(targetpos); + node_jump = m_map->getNode(jumppos); + + } + //check headbanger one last time + if ((node_jump.param0 == CONTENT_IGNORE) || + (m_ndef->get(node_jump).walkable)) { + headbanger = true; + } + + //did we find surface without banging our head? + if ((!headbanger) && (targetpos.Y <= m_limits.MaxEdge.Y) && + (!m_ndef->get(node_target).walkable)) { + + if (targetpos.Y - pos2.Y <= m_maxjump) { + //SUCCESS! + retval.valid = true; + retval.value = 2; + retval.y_change = (targetpos.Y - pos2.Y); + DEBUG_OUT("Pathfinder cost above found" << std::endl); + } + else { + DEBUG_OUT("Pathfinder: distance to surface above too big: " + << (targetpos.Y - pos2.Y) << " max: " << m_maxjump + << std::endl); + } + } + else { + DEBUG_OUT("Pathfinder: no surface above found" << std::endl); + } + } + return retval; +} + +/******************************************************************************/ +v3s16 Pathfinder::getIndexPos(v3s16 pos) +{ + return pos - m_limits.MinEdge; +} + +/******************************************************************************/ +PathGridnode &Pathfinder::getIndexElement(v3s16 ipos) +{ + return m_nodes_container->access(ipos); +} + +/******************************************************************************/ +inline PathGridnode &Pathfinder::getIdxElem(s16 x, s16 y, s16 z) +{ + return m_nodes_container->access(v3s16(x,y,z)); +} + +/******************************************************************************/ +bool Pathfinder::isValidIndex(v3s16 index) +{ + if ( (index.X < m_max_index_x) && + (index.Y < m_max_index_y) && + (index.Z < m_max_index_z) && + (index.X >= 0) && + (index.Y >= 0) && + (index.Z >= 0)) + return true; + + return false; +} + +/******************************************************************************/ +v3s16 Pathfinder::invert(v3s16 pos) +{ + v3s16 retval = pos; + + retval.X *=-1; + retval.Y *=-1; + retval.Z *=-1; + + return retval; +} + +/******************************************************************************/ +bool Pathfinder::updateAllCosts(v3s16 ipos, + v3s16 srcdir, + int current_cost, + int level) +{ + PathGridnode &g_pos = getIndexElement(ipos); + g_pos.totalcost = current_cost; + g_pos.sourcedir = srcdir; + + level ++; + + //check if target has been found + if (g_pos.target) { + m_min_target_distance = current_cost; + DEBUG_OUT(LVL " Pathfinder: target found!" << std::endl); + return true; + } + + bool retval = false; + + // the 4 cardinal directions + const static v3s16 directions[4] = { + v3s16(1,0, 0), + v3s16(-1,0, 0), + v3s16(0,0, 1), + v3s16(0,0,-1) + }; + + for (v3s16 direction : directions) { + if (direction != srcdir) { + PathCost cost = g_pos.getCost(direction); + + if (cost.valid) { + direction.Y = cost.y_change; + + v3s16 ipos2 = ipos + direction; + + if (!isValidIndex(ipos2)) { + DEBUG_OUT(LVL " Pathfinder: " << PP(ipos2) << + " out of range, max=" << PP(m_limits.MaxEdge) << std::endl); + continue; + } + + PathGridnode &g_pos2 = getIndexElement(ipos2); + + if (!g_pos2.valid) { + VERBOSE_TARGET << LVL "Pathfinder: no data for new position: " + << PP(ipos2) << std::endl; + continue; + } + + assert(cost.value > 0); + + int new_cost = current_cost + cost.value; + + // check if there already is a smaller path + if ((m_min_target_distance > 0) && + (m_min_target_distance < new_cost)) { + return false; + } + + if ((g_pos2.totalcost < 0) || + (g_pos2.totalcost > new_cost)) { + DEBUG_OUT(LVL "Pathfinder: updating path at: "<< + PP(ipos2) << " from: " << g_pos2.totalcost << " to "<< + new_cost << std::endl); + if (updateAllCosts(ipos2, invert(direction), + new_cost, level)) { + retval = true; + } + } + else { + DEBUG_OUT(LVL "Pathfinder:" + " already found shorter path to: " + << PP(ipos2) << std::endl); + } + } + else { + DEBUG_OUT(LVL "Pathfinder:" + " not moving to invalid direction: " + << PP(directions[i]) << std::endl); + } + } + } + return retval; +} + +/******************************************************************************/ +int Pathfinder::getXZManhattanDist(v3s16 pos) +{ + int min_x = MYMIN(pos.X, m_destination.X); + int max_x = MYMAX(pos.X, m_destination.X); + int min_z = MYMIN(pos.Z, m_destination.Z); + int max_z = MYMAX(pos.Z, m_destination.Z); + + return (max_x - min_x) + (max_z - min_z); +} + + + +/******************************************************************************/ +bool Pathfinder::updateCostHeuristic(v3s16 isource, v3s16 idestination) +{ + // A* search algorithm. + + // The open list contains the pathfinder nodes that still need to be + // checked. The priority queue sorts the pathfinder nodes by + // estimated cost, with lowest cost on the top. + std::priority_queue<v3s16, std::vector<v3s16>, PathfinderCompareHeuristic> + openList(PathfinderCompareHeuristic(this)); + + v3s16 source = getRealPos(isource); + v3s16 destination = getRealPos(idestination); + + // initial position + openList.push(source); + + // the 4 cardinal directions + const static v3s16 directions[4] = { + v3s16(1,0, 0), + v3s16(-1,0, 0), + v3s16(0,0, 1), + v3s16(0,0,-1) + }; + + v3s16 current_pos; + PathGridnode& s_pos = getIndexElement(isource); + s_pos.source = true; + s_pos.totalcost = 0; + + // estimated cost from start to finish + int cur_manhattan = getXZManhattanDist(destination); + s_pos.estimated_cost = cur_manhattan; + + while (!openList.empty()) { + // Pick node with lowest total cost estimate. + // The "cheapest" node is always on top. + current_pos = openList.top(); + openList.pop(); + v3s16 ipos = getIndexPos(current_pos); + + // check if node is inside searchdistance and valid + if (!isValidIndex(ipos)) { + DEBUG_OUT(LVL " Pathfinder: " << PP(current_pos) << + " out of search distance, max=" << PP(m_limits.MaxEdge) << std::endl); + continue; + } + + PathGridnode& g_pos = getIndexElement(ipos); + g_pos.is_closed = true; + g_pos.is_open = false; + if (!g_pos.valid) { + continue; + } + + if (current_pos == destination) { + // destination found, terminate + g_pos.target = true; + return true; + } + + // for this node, check the 4 cardinal directions + for (v3s16 direction_flat : directions) { + int current_totalcost = g_pos.totalcost; + + // get cost from current node to currently checked direction + PathCost cost = g_pos.getCost(direction_flat); + if (!cost.updated) { + cost = calcCost(current_pos, direction_flat); + g_pos.setCost(direction_flat, cost); + } + // update Y component of direction if neighbor requires jump or fall + v3s16 direction_3d = v3s16(direction_flat); + direction_3d.Y = cost.y_change; + + // get position of true neighbor + v3s16 neighbor = current_pos + direction_3d; + v3s16 ineighbor = getIndexPos(neighbor); + PathGridnode &n_pos = getIndexElement(ineighbor); + + if (cost.valid && !n_pos.is_closed && !n_pos.is_open) { + // heuristic function; estimate cost from neighbor to destination + cur_manhattan = getXZManhattanDist(neighbor); + + // add neighbor to open list + n_pos.sourcedir = invert(direction_3d); + n_pos.totalcost = current_totalcost + cost.value; + n_pos.estimated_cost = current_totalcost + cost.value + cur_manhattan; + n_pos.is_open = true; + openList.push(neighbor); + } + } + } + // no path found; all possible nodes within searchdistance have been exhausted + return false; +} + +/******************************************************************************/ +bool Pathfinder::buildPath(std::vector<v3s16> &path, v3s16 ipos) +{ + // The cost calculation should have set a source direction for all relevant nodes. + // To build the path, we go backwards from the destination until we reach the start. + for(u32 waypoints = 1; waypoints++; ) { + if (waypoints > PATHFINDER_MAX_WAYPOINTS) { + ERROR_TARGET << "Pathfinder: buildPath: path is too long (too many waypoints), aborting" << std::endl; + return false; + } + // Insert node into path + PathGridnode &g_pos = getIndexElement(ipos); + if (!g_pos.valid) { + ERROR_TARGET << "Pathfinder: buildPath: invalid next pos detected, aborting" << std::endl; + return false; + } + + g_pos.is_element = true; + path.push_back(ipos); + if (g_pos.source) + // start node found, terminate + return true; + + // go to the node from which the pathfinder came + ipos += g_pos.sourcedir; + } + + ERROR_TARGET << "Pathfinder: buildPath: no source node found" << std::endl; + return false; +} + +/******************************************************************************/ +v3s16 Pathfinder::walkDownwards(v3s16 pos, unsigned int max_down) { + if (max_down == 0) + return pos; + v3s16 testpos = v3s16(pos); + MapNode node_at_pos = m_map->getNode(testpos); + unsigned int down = 0; + while ((node_at_pos.param0 != CONTENT_IGNORE) && + (!m_ndef->get(node_at_pos).walkable) && + (testpos.Y > m_limits.MinEdge.Y) && + (down <= max_down)) { + testpos += v3s16(0, -1, 0); + down++; + node_at_pos = m_map->getNode(testpos); + } + //did we find surface? + if ((testpos.Y >= m_limits.MinEdge.Y) && + (node_at_pos.param0 != CONTENT_IGNORE) && + (m_ndef->get(node_at_pos).walkable)) { + if (down == 0) { + pos = testpos; + } else if ((down - 1) <= max_down) { + //difference of y-pos +1 (target node is ABOVE solid node) + testpos += v3s16(0, 1, 0); + pos = testpos; + } + else { + VERBOSE_TARGET << "Pos too far above ground: " << + "Index: " << PP(getIndexPos(pos)) << + "Realpos: " << PP(getRealPos(getIndexPos(pos))) << std::endl; + } + } else { + DEBUG_OUT("Pathfinder: no surface found below pos" << std::endl); + } + return pos; +} + +#ifdef PATHFINDER_DEBUG + +/******************************************************************************/ +void Pathfinder::printCost() +{ + printCost(DIR_XP); + printCost(DIR_XM); + printCost(DIR_ZP); + printCost(DIR_ZM); +} + +/******************************************************************************/ +void Pathfinder::printYdir() +{ + printYdir(DIR_XP); + printYdir(DIR_XM); + printYdir(DIR_ZP); + printYdir(DIR_ZM); +} + +/******************************************************************************/ +void Pathfinder::printCost(PathDirections dir) +{ + std::cout << "Cost in direction: " << dirToName(dir) << std::endl; + std::cout << std::setfill('-') << std::setw(80) << "-" << std::endl; + std::cout << std::setfill(' '); + for (int y = 0; y < m_max_index_y; y++) { + + std::cout << "Level: " << y << std::endl; + + std::cout << std::setw(4) << " " << " "; + for (int x = 0; x < m_max_index_x; x++) { + std::cout << std::setw(4) << x; + } + std::cout << std::endl; + + for (int z = 0; z < m_max_index_z; z++) { + std::cout << std::setw(4) << z <<": "; + for (int x = 0; x < m_max_index_x; x++) { + if (getIdxElem(x, y, z).directions[dir].valid) + std::cout << std::setw(4) + << getIdxElem(x, y, z).directions[dir].value; + else + std::cout << std::setw(4) << "-"; + } + std::cout << std::endl; + } + std::cout << std::endl; + } +} + +/******************************************************************************/ +void Pathfinder::printYdir(PathDirections dir) +{ + std::cout << "Height difference in direction: " << dirToName(dir) << std::endl; + std::cout << std::setfill('-') << std::setw(80) << "-" << std::endl; + std::cout << std::setfill(' '); + for (int y = 0; y < m_max_index_y; y++) { + + std::cout << "Level: " << y << std::endl; + + std::cout << std::setw(4) << " " << " "; + for (int x = 0; x < m_max_index_x; x++) { + std::cout << std::setw(4) << x; + } + std::cout << std::endl; + + for (int z = 0; z < m_max_index_z; z++) { + std::cout << std::setw(4) << z <<": "; + for (int x = 0; x < m_max_index_x; x++) { + if (getIdxElem(x, y, z).directions[dir].valid) + std::cout << std::setw(4) + << getIdxElem(x, y, z).directions[dir].y_change; + else + std::cout << std::setw(4) << "-"; + } + std::cout << std::endl; + } + std::cout << std::endl; + } +} + +/******************************************************************************/ +void Pathfinder::printType() +{ + std::cout << "Type of node:" << std::endl; + std::cout << std::setfill('-') << std::setw(80) << "-" << std::endl; + std::cout << std::setfill(' '); + for (int y = 0; y < m_max_index_y; y++) { + + std::cout << "Level: " << y << std::endl; + + std::cout << std::setw(3) << " " << " "; + for (int x = 0; x < m_max_index_x; x++) { + std::cout << std::setw(3) << x; + } + std::cout << std::endl; + + for (int z = 0; z < m_max_index_z; z++) { + std::cout << std::setw(3) << z <<": "; + for (int x = 0; x < m_max_index_x; x++) { + char toshow = getIdxElem(x, y, z).type; + std::cout << std::setw(3) << toshow; + } + std::cout << std::endl; + } + std::cout << std::endl; + } + std::cout << std::endl; +} + +/******************************************************************************/ +void Pathfinder::printPathLen() +{ + std::cout << "Pathlen:" << std::endl; + std::cout << std::setfill('-') << std::setw(80) << "-" << std::endl; + std::cout << std::setfill(' '); + for (int y = 0; y < m_max_index_y; y++) { + + std::cout << "Level: " << y << std::endl; + + std::cout << std::setw(3) << " " << " "; + for (int x = 0; x < m_max_index_x; x++) { + std::cout << std::setw(3) << x; + } + std::cout << std::endl; + + for (int z = 0; z < m_max_index_z; z++) { + std::cout << std::setw(3) << z <<": "; + for (int x = 0; x < m_max_index_x; x++) { + std::cout << std::setw(3) << getIdxElem(x, y, z).totalcost; + } + std::cout << std::endl; + } + std::cout << std::endl; + } + std::cout << std::endl; +} + +/******************************************************************************/ +std::string Pathfinder::dirToName(PathDirections dir) +{ + switch (dir) { + case DIR_XP: + return "XP"; + break; + case DIR_XM: + return "XM"; + break; + case DIR_ZP: + return "ZP"; + break; + case DIR_ZM: + return "ZM"; + break; + default: + return "UKN"; + } +} + +/******************************************************************************/ +void Pathfinder::printPath(const std::vector<v3s16> &path) +{ + unsigned int current = 0; + for (std::vector<v3s16>::iterator i = path.begin(); + i != path.end(); ++i) { + std::cout << std::setw(3) << current << ":" << PP((*i)) << std::endl; + current++; + } +} + +#endif diff --git a/src/pathfinder.h b/src/pathfinder.h new file mode 100644 index 0000000..526aa0e --- /dev/null +++ b/src/pathfinder.h @@ -0,0 +1,64 @@ +/* +Minetest +Copyright (C) 2013 sapier, sapier at gmx dot net + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +/******************************************************************************/ +/* Includes */ +/******************************************************************************/ +#include <vector> +#include "irr_v3d.h" + +/******************************************************************************/ +/* Forward declarations */ +/******************************************************************************/ + +class NodeDefManager; +class Map; + +/******************************************************************************/ +/* Typedefs and macros */ +/******************************************************************************/ + +typedef enum { + DIR_XP, + DIR_XM, + DIR_ZP, + DIR_ZM +} PathDirections; + +/** List of supported algorithms */ +typedef enum { + PA_DIJKSTRA, /**< Dijkstra shortest path algorithm */ + PA_PLAIN, /**< A* algorithm using heuristics to find a path */ + PA_PLAIN_NP /**< A* algorithm without prefetching of map data */ +} PathAlgorithm; + +/******************************************************************************/ +/* declarations */ +/******************************************************************************/ + +/** c wrapper function to use from scriptapi */ +std::vector<v3s16> get_path(Map *map, const NodeDefManager *ndef, + v3s16 source, + v3s16 destination, + unsigned int searchdistance, + unsigned int max_jump, + unsigned int max_drop, + PathAlgorithm algo); diff --git a/src/player.cpp b/src/player.cpp new file mode 100644 index 0000000..1e064c1 --- /dev/null +++ b/src/player.cpp @@ -0,0 +1,236 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "player.h" + +#include <cmath> +#include "threading/mutex_auto_lock.h" +#include "util/numeric.h" +#include "hud.h" +#include "constants.h" +#include "gamedef.h" +#include "settings.h" +#include "log.h" +#include "porting.h" // strlcpy + + +Player::Player(const char *name, IItemDefManager *idef): + inventory(idef) +{ + strlcpy(m_name, name, PLAYERNAME_SIZE); + + inventory.clear(); + inventory.addList("main", PLAYER_INVENTORY_SIZE); + InventoryList *craft = inventory.addList("craft", 9); + craft->setWidth(3); + inventory.addList("craftpreview", 1); + inventory.addList("craftresult", 1); + inventory.setModified(false); + + // Can be redefined via Lua + inventory_formspec = "size[8,7.5]" + //"image[1,0.6;1,2;player.png]" + "list[current_player;main;0,3.5;8,4;]" + "list[current_player;craft;3,0;3,3;]" + "listring[]" + "list[current_player;craftpreview;7,1;1,1;]"; + + // Initialize movement settings at default values, so movement can work + // if the server fails to send them + movement_acceleration_default = 3 * BS; + movement_acceleration_air = 2 * BS; + movement_acceleration_fast = 10 * BS; + movement_speed_walk = 4 * BS; + movement_speed_crouch = 1.35 * BS; + movement_speed_fast = 20 * BS; + movement_speed_climb = 2 * BS; + movement_speed_jump = 6.5 * BS; + movement_liquid_fluidity = 1 * BS; + movement_liquid_fluidity_smooth = 0.5 * BS; + movement_liquid_sink = 10 * BS; + movement_gravity = 9.81 * BS; + local_animation_speed = 0.0; + + hud_flags = + HUD_FLAG_HOTBAR_VISIBLE | HUD_FLAG_HEALTHBAR_VISIBLE | + HUD_FLAG_CROSSHAIR_VISIBLE | HUD_FLAG_WIELDITEM_VISIBLE | + HUD_FLAG_BREATHBAR_VISIBLE | HUD_FLAG_MINIMAP_VISIBLE | + HUD_FLAG_MINIMAP_RADAR_VISIBLE | HUD_FLAG_BASIC_DEBUG; + + hud_hotbar_itemcount = HUD_HOTBAR_ITEMCOUNT_DEFAULT; + + m_player_settings.readGlobalSettings(); + // Register player setting callbacks + for (const std::string &name : m_player_settings.setting_names) + g_settings->registerChangedCallback(name, + &Player::settingsChangedCallback, &m_player_settings); +} + +Player::~Player() +{ + // m_player_settings becomes invalid, remove callbacks + for (const std::string &name : m_player_settings.setting_names) + g_settings->deregisterChangedCallback(name, + &Player::settingsChangedCallback, &m_player_settings); + clearHud(); +} + +void Player::setWieldIndex(u16 index) +{ + const InventoryList *mlist = inventory.getList("main"); + m_wield_index = MYMIN(index, mlist ? mlist->getSize() : 0); +} + +ItemStack &Player::getWieldedItem(ItemStack *selected, ItemStack *hand) const +{ + assert(selected); + + const InventoryList *mlist = inventory.getList("main"); // TODO: Make this generic + const InventoryList *hlist = inventory.getList("hand"); + + if (mlist && m_wield_index < mlist->getSize()) + *selected = mlist->getItem(m_wield_index); + + if (hand && hlist) + *hand = hlist->getItem(0); + + // Return effective tool item + return (hand && selected->name.empty()) ? *hand : *selected; +} + +u32 Player::addHud(HudElement *toadd) +{ + MutexAutoLock lock(m_mutex); + + u32 id = getFreeHudID(); + + if (id < hud.size()) + hud[id] = toadd; + else + hud.push_back(toadd); + + return id; +} + +HudElement* Player::getHud(u32 id) +{ + MutexAutoLock lock(m_mutex); + + if (id < hud.size()) + return hud[id]; + + return NULL; +} + +HudElement* Player::removeHud(u32 id) +{ + MutexAutoLock lock(m_mutex); + + HudElement* retval = NULL; + if (id < hud.size()) { + retval = hud[id]; + hud[id] = NULL; + } + return retval; +} + +void Player::clearHud() +{ + MutexAutoLock lock(m_mutex); + + while(!hud.empty()) { + delete hud.back(); + hud.pop_back(); + } +} + +#ifndef SERVER + +u32 PlayerControl::getKeysPressed() const +{ + u32 keypress_bits = + ( (u32)(jump & 1) << 4) | + ( (u32)(aux1 & 1) << 5) | + ( (u32)(sneak & 1) << 6) | + ( (u32)(dig & 1) << 7) | + ( (u32)(place & 1) << 8) | + ( (u32)(zoom & 1) << 9) + ; + + // If any direction keys are pressed pass those through + if (direction_keys != 0) + { + keypress_bits |= direction_keys; + } + // Otherwise set direction keys based on joystick movement (for mod compatibility) + else if (isMoving()) + { + float abs_d; + + // (absolute value indicates forward / backward) + abs_d = abs(movement_direction); + if (abs_d < 3.0f / 8.0f * M_PI) + keypress_bits |= (u32)1; // Forward + if (abs_d > 5.0f / 8.0f * M_PI) + keypress_bits |= (u32)1 << 1; // Backward + + // rotate entire coordinate system by 90 degree + abs_d = movement_direction + M_PI_2; + if (abs_d >= M_PI) + abs_d -= 2 * M_PI; + abs_d = abs(abs_d); + // (value now indicates left / right) + if (abs_d < 3.0f / 8.0f * M_PI) + keypress_bits |= (u32)1 << 2; // Left + if (abs_d > 5.0f / 8.0f * M_PI) + keypress_bits |= (u32)1 << 3; // Right + } + + return keypress_bits; +} + +#endif + +void PlayerControl::unpackKeysPressed(u32 keypress_bits) +{ + direction_keys = keypress_bits & 0xf; + jump = keypress_bits & (1 << 4); + aux1 = keypress_bits & (1 << 5); + sneak = keypress_bits & (1 << 6); + dig = keypress_bits & (1 << 7); + place = keypress_bits & (1 << 8); + zoom = keypress_bits & (1 << 9); +} + +void PlayerSettings::readGlobalSettings() +{ + free_move = g_settings->getBool("free_move"); + pitch_move = g_settings->getBool("pitch_move"); + fast_move = g_settings->getBool("fast_move"); + continuous_forward = g_settings->getBool("continuous_forward"); + always_fly_fast = g_settings->getBool("always_fly_fast"); + aux1_descends = g_settings->getBool("aux1_descends"); + noclip = g_settings->getBool("noclip"); + autojump = g_settings->getBool("autojump"); +} + +void Player::settingsChangedCallback(const std::string &name, void *data) +{ + ((PlayerSettings *)data)->readGlobalSettings(); +} diff --git a/src/player.h b/src/player.h new file mode 100644 index 0000000..beca82f --- /dev/null +++ b/src/player.h @@ -0,0 +1,224 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +#include "inventory.h" +#include "constants.h" +#include "network/networkprotocol.h" +#include "util/basic_macros.h" +#include <list> +#include <mutex> + +#define PLAYERNAME_SIZE 20 + +#define PLAYERNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_" +#define PLAYERNAME_ALLOWED_CHARS_USER_EXPL "'a' to 'z', 'A' to 'Z', '0' to '9', '-', '_'" + +struct PlayerFovSpec +{ + f32 fov; + + // Whether to multiply the client's FOV or to override it + bool is_multiplier; + + // The time to be take to trasition to the new FOV value. + // Transition is instantaneous if omitted. Omitted by default. + f32 transition_time; +}; + +struct PlayerControl +{ + PlayerControl() = default; + + PlayerControl( + bool a_up, bool a_down, bool a_left, bool a_right, + bool a_jump, bool a_aux1, bool a_sneak, + bool a_zoom, + bool a_dig, bool a_place, + float a_pitch, float a_yaw, + float a_movement_speed, float a_movement_direction + ) + { + // Encode direction keys into a single value so nobody uses it accidentally + // as movement_{speed,direction} is supposed to be the source of truth. + direction_keys = (a_up&1) | ((a_down&1) << 1) | + ((a_left&1) << 2) | ((a_right&1) << 3); + jump = a_jump; + aux1 = a_aux1; + sneak = a_sneak; + zoom = a_zoom; + dig = a_dig; + place = a_place; + pitch = a_pitch; + yaw = a_yaw; + movement_speed = a_movement_speed; + movement_direction = a_movement_direction; + } + +#ifndef SERVER + // For client use + u32 getKeysPressed() const; + inline bool isMoving() const { return movement_speed > 0.001f; } +#endif + + // For server use + void unpackKeysPressed(u32 keypress_bits); + + u8 direction_keys = 0; + bool jump = false; + bool aux1 = false; + bool sneak = false; + bool zoom = false; + bool dig = false; + bool place = false; + // Note: These four are NOT available on the server + float pitch = 0.0f; + float yaw = 0.0f; + float movement_speed = 0.0f; + float movement_direction = 0.0f; +}; + +struct PlayerSettings +{ + bool free_move = false; + bool pitch_move = false; + bool fast_move = false; + bool continuous_forward = false; + bool always_fly_fast = false; + bool aux1_descends = false; + bool noclip = false; + bool autojump = false; + + const std::string setting_names[8] = { + "free_move", "pitch_move", "fast_move", "continuous_forward", "always_fly_fast", + "aux1_descends", "noclip", "autojump" + }; + void readGlobalSettings(); +}; + +class Map; +struct CollisionInfo; +struct HudElement; +class Environment; + +class Player +{ +public: + + Player(const char *name, IItemDefManager *idef); + virtual ~Player() = 0; + + DISABLE_CLASS_COPY(Player); + + virtual void move(f32 dtime, Environment *env, f32 pos_max_d) + {} + virtual void move(f32 dtime, Environment *env, f32 pos_max_d, + std::vector<CollisionInfo> *collision_info) + {} + + v3f getSpeed() const + { + return m_speed; + } + + void setSpeed(v3f speed) + { + m_speed = speed; + } + + const char *getName() const { return m_name; } + + u32 getFreeHudID() + { + size_t size = hud.size(); + for (size_t i = 0; i != size; i++) { + if (!hud[i]) + return i; + } + return size; + } + + v3f eye_offset_first; + v3f eye_offset_third; + + Inventory inventory; + + f32 movement_acceleration_default; + f32 movement_acceleration_air; + f32 movement_acceleration_fast; + f32 movement_speed_walk; + f32 movement_speed_crouch; + f32 movement_speed_fast; + f32 movement_speed_climb; + f32 movement_speed_jump; + f32 movement_liquid_fluidity; + f32 movement_liquid_fluidity_smooth; + f32 movement_liquid_sink; + f32 movement_gravity; + + v2s32 local_animations[4]; + float local_animation_speed; + + std::string inventory_formspec; + std::string formspec_prepend; + + PlayerControl control; + const PlayerControl& getPlayerControl() { return control; } + PlayerSettings &getPlayerSettings() { return m_player_settings; } + static void settingsChangedCallback(const std::string &name, void *data); + + // Returns non-empty `selected` ItemStack. `hand` is a fallback, if specified + ItemStack &getWieldedItem(ItemStack *selected, ItemStack *hand) const; + void setWieldIndex(u16 index); + u16 getWieldIndex() const { return m_wield_index; } + + void setFov(const PlayerFovSpec &spec) + { + m_fov_override_spec = spec; + } + + const PlayerFovSpec &getFov() const + { + return m_fov_override_spec; + } + + HudElement* getHud(u32 id); + u32 addHud(HudElement* hud); + HudElement* removeHud(u32 id); + void clearHud(); + + u32 hud_flags; + s32 hud_hotbar_itemcount; + +protected: + char m_name[PLAYERNAME_SIZE]; + v3f m_speed; + u16 m_wield_index = 0; + PlayerFovSpec m_fov_override_spec = { 0.0f, false, 0.0f }; + + std::vector<HudElement *> hud; +private: + // Protect some critical areas + // hud for example can be modified by EmergeThread + // and ServerThread + std::mutex m_mutex; + PlayerSettings m_player_settings; +}; diff --git a/src/porting.cpp b/src/porting.cpp new file mode 100644 index 0000000..0962743 --- /dev/null +++ b/src/porting.cpp @@ -0,0 +1,791 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/* + Random portability stuff + + See comments in porting.h +*/ + +#include "porting.h" + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) + #include <sys/types.h> + #include <sys/sysctl.h> + extern char **environ; +#elif defined(_WIN32) + #include <windows.h> + #include <wincrypt.h> + #include <algorithm> + #include <shlwapi.h> + #include <shellapi.h> + #include <mmsystem.h> +#endif +#if !defined(_WIN32) + #include <unistd.h> + #include <sys/utsname.h> + #if !defined(__ANDROID__) + #include <spawn.h> + #endif +#endif +#if defined(__hpux) + #define _PSTAT64 + #include <sys/pstat.h> +#endif +#if defined(__ANDROID__) + #include "porting_android.h" +#endif +#if defined(__APPLE__) + // For _NSGetEnviron() + // Related: https://gitlab.haskell.org/ghc/ghc/issues/2458 + #include <crt_externs.h> +#endif + +#if defined(__HAIKU__) + #include <FindDirectory.h> +#endif + +#include "config.h" +#include "debug.h" +#include "filesys.h" +#include "log.h" +#include "util/string.h" +#include <list> +#include <cstdarg> +#include <cstdio> + +#if !defined(SERVER) && defined(_WIN32) +// On Windows export some driver-specific variables to encourage Minetest to be +// executed on the discrete GPU in case of systems with two. Portability is fun. +extern "C" { + __declspec(dllexport) DWORD NvOptimusEnablement = 1; + __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 1; +} +#endif + +namespace porting +{ + +/* + Signal handler (grabs Ctrl-C on POSIX systems) +*/ + +bool g_killed = false; + +bool *signal_handler_killstatus() +{ + return &g_killed; +} + +#if !defined(_WIN32) // POSIX + #include <signal.h> + +void signal_handler(int sig) +{ + if (!g_killed) { + if (sig == SIGINT) { + dstream << "INFO: signal_handler(): " + << "Ctrl-C pressed, shutting down." << std::endl; + } else if (sig == SIGTERM) { + dstream << "INFO: signal_handler(): " + << "got SIGTERM, shutting down." << std::endl; + } + + // Comment out for less clutter when testing scripts + /*dstream << "INFO: sigint_handler(): " + << "Printing debug stacks" << std::endl; + debug_stacks_print();*/ + + g_killed = true; + } else { + (void)signal(sig, SIG_DFL); + } +} + +void signal_handler_init(void) +{ + (void)signal(SIGINT, signal_handler); + (void)signal(SIGTERM, signal_handler); +} + +#else // _WIN32 + #include <signal.h> + +BOOL WINAPI event_handler(DWORD sig) +{ + switch (sig) { + case CTRL_C_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + if (!g_killed) { + dstream << "INFO: event_handler(): " + << "Ctrl+C, Close Event, Logoff Event or Shutdown Event," + " shutting down." << std::endl; + g_killed = true; + } else { + (void)signal(SIGINT, SIG_DFL); + } + break; + case CTRL_BREAK_EVENT: + break; + } + + return TRUE; +} + +void signal_handler_init(void) +{ + SetConsoleCtrlHandler((PHANDLER_ROUTINE)event_handler, TRUE); +} + +#endif + + +/* + Path mangler +*/ + +// Default to RUN_IN_PLACE style relative paths +std::string path_share = ".."; +std::string path_user = ".."; +std::string path_locale = path_share + DIR_DELIM + "locale"; +std::string path_cache = path_user + DIR_DELIM + "cache"; + + +std::string getDataPath(const char *subpath) +{ + return path_share + DIR_DELIM + subpath; +} + +void pathRemoveFile(char *path, char delim) +{ + // Remove filename and path delimiter + int i; + for(i = strlen(path)-1; i>=0; i--) + { + if(path[i] == delim) + break; + } + path[i] = 0; +} + +bool detectMSVCBuildDir(const std::string &path) +{ + const char *ends[] = { + "bin\\Release", + "bin\\MinSizeRel", + "bin\\RelWithDebInfo", + "bin\\Debug", + "bin\\Build", + NULL + }; + return (!removeStringEnd(path, ends).empty()); +} + +std::string get_sysinfo() +{ +#ifdef _WIN32 + + std::ostringstream oss; + LPSTR filePath = new char[MAX_PATH]; + UINT blockSize; + VS_FIXEDFILEINFO *fixedFileInfo; + + GetSystemDirectoryA(filePath, MAX_PATH); + PathAppendA(filePath, "kernel32.dll"); + + DWORD dwVersionSize = GetFileVersionInfoSizeA(filePath, NULL); + LPBYTE lpVersionInfo = new BYTE[dwVersionSize]; + + GetFileVersionInfoA(filePath, 0, dwVersionSize, lpVersionInfo); + VerQueryValueA(lpVersionInfo, "\\", (LPVOID *)&fixedFileInfo, &blockSize); + + oss << "Windows/" + << HIWORD(fixedFileInfo->dwProductVersionMS) << '.' // Major + << LOWORD(fixedFileInfo->dwProductVersionMS) << '.' // Minor + << HIWORD(fixedFileInfo->dwProductVersionLS) << ' '; // Build + + #ifdef _WIN64 + oss << "x86_64"; + #else + BOOL is64 = FALSE; + if (IsWow64Process(GetCurrentProcess(), &is64) && is64) + oss << "x86_64"; // 32-bit app on 64-bit OS + else + oss << "x86"; + #endif + + delete[] lpVersionInfo; + delete[] filePath; + + return oss.str(); +#else + struct utsname osinfo; + uname(&osinfo); + return std::string(osinfo.sysname) + "/" + + osinfo.release + " " + osinfo.machine; +#endif +} + + +bool getCurrentWorkingDir(char *buf, size_t len) +{ +#ifdef _WIN32 + DWORD ret = GetCurrentDirectory(len, buf); + return (ret != 0) && (ret <= len); +#else + return getcwd(buf, len); +#endif +} + + +bool getExecPathFromProcfs(char *buf, size_t buflen) +{ +#ifndef _WIN32 + buflen--; + + ssize_t len; + if ((len = readlink("/proc/self/exe", buf, buflen)) == -1 && + (len = readlink("/proc/curproc/file", buf, buflen)) == -1 && + (len = readlink("/proc/curproc/exe", buf, buflen)) == -1) + return false; + + buf[len] = '\0'; + return true; +#else + return false; +#endif +} + +//// Windows +#if defined(_WIN32) + +bool getCurrentExecPath(char *buf, size_t len) +{ + DWORD written = GetModuleFileNameA(NULL, buf, len); + if (written == 0 || written == len) + return false; + + return true; +} + + +//// Linux +#elif defined(__linux__) + +bool getCurrentExecPath(char *buf, size_t len) +{ + if (!getExecPathFromProcfs(buf, len)) + return false; + + return true; +} + + +//// Mac OS X, Darwin +#elif defined(__APPLE__) + +bool getCurrentExecPath(char *buf, size_t len) +{ + uint32_t lenb = (uint32_t)len; + if (_NSGetExecutablePath(buf, &lenb) == -1) + return false; + + return true; +} + + +//// FreeBSD, NetBSD, DragonFlyBSD +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) + +bool getCurrentExecPath(char *buf, size_t len) +{ + // Try getting path from procfs first, since valgrind + // doesn't work with the latter + if (getExecPathFromProcfs(buf, len)) + return true; + + int mib[4]; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; + + if (sysctl(mib, 4, buf, &len, NULL, 0) == -1) + return false; + + return true; +} + +#elif defined(__HAIKU__) + +bool getCurrentExecPath(char *buf, size_t len) +{ + return find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, NULL, buf, len) == B_OK; +} + +//// Solaris +#elif defined(__sun) || defined(sun) + +bool getCurrentExecPath(char *buf, size_t len) +{ + const char *exec = getexecname(); + if (exec == NULL) + return false; + + if (strlcpy(buf, exec, len) >= len) + return false; + + return true; +} + + +// HP-UX +#elif defined(__hpux) + +bool getCurrentExecPath(char *buf, size_t len) +{ + struct pst_status psts; + + if (pstat_getproc(&psts, sizeof(psts), 0, getpid()) == -1) + return false; + + if (pstat_getpathname(buf, len, &psts.pst_fid_text) == -1) + return false; + + return true; +} + + +#else + +bool getCurrentExecPath(char *buf, size_t len) +{ + return false; +} + +#endif + + +//// Non-Windows +#if !defined(_WIN32) + +const char *getHomeOrFail() +{ + const char *home = getenv("HOME"); + // In rare cases the HOME environment variable may be unset + FATAL_ERROR_IF(!home, + "Required environment variable HOME is not set"); + return home; +} + +#endif + + +//// Windows +#if defined(_WIN32) + +bool setSystemPaths() +{ + char buf[BUFSIZ]; + + // Find path of executable and set path_share relative to it + FATAL_ERROR_IF(!getCurrentExecPath(buf, sizeof(buf)), + "Failed to get current executable path"); + pathRemoveFile(buf, '\\'); + + std::string exepath(buf); + + // Use ".\bin\.." + path_share = exepath + "\\.."; + if (detectMSVCBuildDir(exepath)) { + // The msvc build dir schould normaly not be present if properly installed, + // but its usefull for debugging. + path_share += DIR_DELIM ".."; + } + + // Use "C:\Users\<user>\AppData\Roaming\<PROJECT_NAME_C>" + DWORD len = GetEnvironmentVariable("APPDATA", buf, sizeof(buf)); + FATAL_ERROR_IF(len == 0 || len > sizeof(buf), "Failed to get APPDATA"); + + path_user = std::string(buf) + DIR_DELIM + PROJECT_NAME_C; + return true; +} + + +//// Linux +#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) + +bool setSystemPaths() +{ + char buf[BUFSIZ]; + + if (!getCurrentExecPath(buf, sizeof(buf))) { +#ifdef __ANDROID__ + errorstream << "Unable to read bindir "<< std::endl; +#else + FATAL_ERROR("Unable to read bindir"); +#endif + return false; + } + + pathRemoveFile(buf, '/'); + std::string bindir(buf); + + // Find share directory from these. + // It is identified by containing the subdirectory "builtin". + std::list<std::string> trylist; + std::string static_sharedir = STATIC_SHAREDIR; + if (!static_sharedir.empty() && static_sharedir != ".") + trylist.push_back(static_sharedir); + + trylist.push_back(bindir + DIR_DELIM ".." DIR_DELIM "share" + DIR_DELIM + PROJECT_NAME); + trylist.push_back(bindir + DIR_DELIM ".."); + +#ifdef __ANDROID__ + trylist.push_back(path_user); +#endif + + for (std::list<std::string>::const_iterator + i = trylist.begin(); i != trylist.end(); ++i) { + const std::string &trypath = *i; + if (!fs::PathExists(trypath) || + !fs::PathExists(trypath + DIR_DELIM + "builtin")) { + warningstream << "system-wide share not found at \"" + << trypath << "\""<< std::endl; + continue; + } + + // Warn if was not the first alternative + if (i != trylist.begin()) { + warningstream << "system-wide share found at \"" + << trypath << "\"" << std::endl; + } + + path_share = trypath; + break; + } + +#ifndef __ANDROID__ + path_user = std::string(getHomeOrFail()) + DIR_DELIM "." + + PROJECT_NAME; +#endif + + return true; +} + + +//// Mac OS X +#elif defined(__APPLE__) + +bool setSystemPaths() +{ + CFBundleRef main_bundle = CFBundleGetMainBundle(); + CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(main_bundle); + char path[PATH_MAX]; + if (CFURLGetFileSystemRepresentation(resources_url, + TRUE, (UInt8 *)path, PATH_MAX)) { + path_share = std::string(path); + } else { + warningstream << "Could not determine bundle resource path" << std::endl; + } + CFRelease(resources_url); + + path_user = std::string(getHomeOrFail()) + + "/Library/Application Support/" + + PROJECT_NAME; + return true; +} + + +#else + +bool setSystemPaths() +{ + path_share = STATIC_SHAREDIR; + path_user = std::string(getHomeOrFail()) + DIR_DELIM "." + + lowercase(PROJECT_NAME); + return true; +} + + +#endif + +void migrateCachePath() +{ + const std::string local_cache_path = path_user + DIR_DELIM + "cache"; + + // Delete tmp folder if it exists (it only ever contained + // a temporary ogg file, which is no longer used). + if (fs::PathExists(local_cache_path + DIR_DELIM + "tmp")) + fs::RecursiveDelete(local_cache_path + DIR_DELIM + "tmp"); + + // Bail if migration impossible + if (path_cache == local_cache_path || !fs::PathExists(local_cache_path) + || fs::PathExists(path_cache)) { + return; + } + if (!fs::Rename(local_cache_path, path_cache)) { + errorstream << "Failed to migrate local cache path " + "to system path!" << std::endl; + } +} + +void initializePaths() +{ +#if RUN_IN_PLACE + char buf[BUFSIZ]; + + infostream << "Using relative paths (RUN_IN_PLACE)" << std::endl; + + bool success = + getCurrentExecPath(buf, sizeof(buf)) || + getExecPathFromProcfs(buf, sizeof(buf)); + + if (success) { + pathRemoveFile(buf, DIR_DELIM_CHAR); + std::string execpath(buf); + + path_share = execpath + DIR_DELIM ".."; + path_user = execpath + DIR_DELIM ".."; + + if (detectMSVCBuildDir(execpath)) { + path_share += DIR_DELIM ".."; + path_user += DIR_DELIM ".."; + } + } else { + errorstream << "Failed to get paths by executable location, " + "trying cwd" << std::endl; + + if (!getCurrentWorkingDir(buf, sizeof(buf))) + FATAL_ERROR("Ran out of methods to get paths"); + + size_t cwdlen = strlen(buf); + if (cwdlen >= 1 && buf[cwdlen - 1] == DIR_DELIM_CHAR) { + cwdlen--; + buf[cwdlen] = '\0'; + } + + if (cwdlen >= 4 && !strcmp(buf + cwdlen - 4, DIR_DELIM "bin")) + pathRemoveFile(buf, DIR_DELIM_CHAR); + + std::string execpath(buf); + + path_share = execpath; + path_user = execpath; + } + path_cache = path_user + DIR_DELIM + "cache"; +#else + infostream << "Using system-wide paths (NOT RUN_IN_PLACE)" << std::endl; + + if (!setSystemPaths()) + errorstream << "Failed to get one or more system-wide path" << std::endl; + + +# ifdef _WIN32 + path_cache = path_user + DIR_DELIM + "cache"; +# else + // Initialize path_cache + // First try $XDG_CACHE_HOME/PROJECT_NAME + const char *cache_dir = getenv("XDG_CACHE_HOME"); + const char *home_dir = getenv("HOME"); + if (cache_dir && cache_dir[0] != '\0') { + path_cache = std::string(cache_dir) + DIR_DELIM + PROJECT_NAME; + } else if (home_dir) { + // Then try $HOME/.cache/PROJECT_NAME + path_cache = std::string(home_dir) + DIR_DELIM + ".cache" + + DIR_DELIM + PROJECT_NAME; + } else { + // If neither works, use $PATH_USER/cache + path_cache = path_user + DIR_DELIM + "cache"; + } + // Migrate cache folder to new location if possible + migrateCachePath(); +# endif // _WIN32 +#endif // RUN_IN_PLACE + + infostream << "Detected share path: " << path_share << std::endl; + infostream << "Detected user path: " << path_user << std::endl; + infostream << "Detected cache path: " << path_cache << std::endl; + +#if USE_GETTEXT + bool found_localedir = false; +# ifdef STATIC_LOCALEDIR + /* STATIC_LOCALEDIR may be a generalized path such as /usr/share/locale that + * doesn't necessarily contain our locale files, so check data path first. */ + path_locale = getDataPath("locale"); + if (fs::PathExists(path_locale)) { + found_localedir = true; + infostream << "Using in-place locale directory " << path_locale + << " even though a static one was provided." << std::endl; + } else if (STATIC_LOCALEDIR[0] && fs::PathExists(STATIC_LOCALEDIR)) { + found_localedir = true; + path_locale = STATIC_LOCALEDIR; + infostream << "Using static locale directory " << STATIC_LOCALEDIR + << std::endl; + } +# else + path_locale = getDataPath("locale"); + if (fs::PathExists(path_locale)) { + found_localedir = true; + } +# endif + if (!found_localedir) { + warningstream << "Couldn't find a locale directory!" << std::endl; + } +#endif // USE_GETTEXT +} + +//// +//// OS-specific Secure Random +//// + +#ifdef WIN32 + +bool secure_rand_fill_buf(void *buf, size_t len) +{ + HCRYPTPROV wctx; + + if (!CryptAcquireContext(&wctx, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + return false; + + CryptGenRandom(wctx, len, (BYTE *)buf); + CryptReleaseContext(wctx, 0); + return true; +} + +#else + +bool secure_rand_fill_buf(void *buf, size_t len) +{ + // N.B. This function checks *only* for /dev/urandom, because on most + // common OSes it is non-blocking, whereas /dev/random is blocking, and it + // is exceptionally uncommon for there to be a situation where /dev/random + // exists but /dev/urandom does not. This guesswork is necessary since + // random devices are not covered by any POSIX standard... + FILE *fp = fopen("/dev/urandom", "rb"); + if (!fp) + return false; + + bool success = fread(buf, len, 1, fp) == 1; + + fclose(fp); + return success; +} + +#endif + +void attachOrCreateConsole() +{ +#ifdef _WIN32 + static bool consoleAllocated = false; + const bool redirected = (_fileno(stdout) == -2 || _fileno(stdout) == -1); // If output is redirected to e.g a file + if (!consoleAllocated && redirected && (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole())) { + freopen("CONOUT$", "w", stdout); + freopen("CONOUT$", "w", stderr); + consoleAllocated = true; + } +#endif +} + +int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...) +{ + // https://msdn.microsoft.com/en-us/library/bt7tawza.aspx + // Many of the MSVC / Windows printf-style functions do not support positional + // arguments (eg. "%1$s"). We just forward the call to vsnprintf for sane + // platforms, but defer to _vsprintf_p on MSVC / Windows. + // https://github.com/FFmpeg/FFmpeg/blob/5ae9fa13f5ac640bec113120d540f70971aa635d/compat/msvcrt/snprintf.c#L46 + // _vsprintf_p has to be shimmed with _vscprintf_p on -1 (for an example see + // above FFmpeg link). + va_list args; + va_start(args, fmt); +#ifndef _MSC_VER + int c = vsnprintf(buf, buf_size, fmt, args); +#else // _MSC_VER + int c = _vsprintf_p(buf, buf_size, fmt, args); + if (c == -1) + c = _vscprintf_p(fmt, args); +#endif // _MSC_VER + va_end(args); + return c; +} + +static bool open_uri(const std::string &uri) +{ + if (uri.find_first_of("\r\n") != std::string::npos) { + errorstream << "Unable to open URI as it is invalid, contains new line: " << uri << std::endl; + return false; + } + +#if defined(_WIN32) + return (intptr_t)ShellExecuteA(NULL, NULL, uri.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32; +#elif defined(__ANDROID__) + openURIAndroid(uri); + return true; +#elif defined(__APPLE__) + const char *argv[] = {"open", uri.c_str(), NULL}; + return posix_spawnp(NULL, "open", NULL, NULL, (char**)argv, + (*_NSGetEnviron())) == 0; +#else + const char *argv[] = {"xdg-open", uri.c_str(), NULL}; + return posix_spawnp(NULL, "xdg-open", NULL, NULL, (char**)argv, environ) == 0; +#endif +} + +bool open_url(const std::string &url) +{ + if (url.substr(0, 7) != "http://" && url.substr(0, 8) != "https://") { + errorstream << "Unable to open browser as URL is missing schema: " << url << std::endl; + return false; + } + + return open_uri(url); +} + +bool open_directory(const std::string &path) +{ + if (!fs::IsDir(path)) { + errorstream << "Unable to open directory as it does not exist: " << path << std::endl; + return false; + } + + return open_uri(path); +} + +// Load performance counter frequency only once at startup +#ifdef _WIN32 + +inline double get_perf_freq() +{ + // Also use this opportunity to enable high-res timers + timeBeginPeriod(1); + + LARGE_INTEGER freq; + QueryPerformanceFrequency(&freq); + return freq.QuadPart; +} + +double perf_freq = get_perf_freq(); + +#endif + +} //namespace porting diff --git a/src/porting.h b/src/porting.h new file mode 100644 index 0000000..93932e1 --- /dev/null +++ b/src/porting.h @@ -0,0 +1,359 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/* + Random portability stuff +*/ + +#pragma once + +#ifdef _WIN32 + #ifdef _WIN32_WINNT + #undef _WIN32_WINNT + #endif + #define _WIN32_WINNT 0x0501 // We need to do this before any other headers + // because those might include sdkddkver.h which defines _WIN32_WINNT if not already set +#endif + +#include <string> +#include <vector> +#include "irrlicht.h" +#include "irrlichttypes.h" // u32 +#include "irrlichttypes_extrabloated.h" +#include "debug.h" +#include "constants.h" +#include "gettime.h" + +#ifdef _MSC_VER + #define SWPRINTF_CHARSTRING L"%S" +#else + #define SWPRINTF_CHARSTRING L"%s" +#endif + +//currently not needed +//template<typename T> struct alignment_trick { char c; T member; }; +//#define ALIGNOF(type) offsetof (alignment_trick<type>, member) + +#ifdef _WIN32 + #include <windows.h> + + #define sleep_ms(x) Sleep(x) +#else + #include <unistd.h> + #include <cstdint> //for uintptr_t + + // Use standard Posix macro for Linux + #if (defined(linux) || defined(__linux)) && !defined(__linux__) + #define __linux__ + #endif + #if (defined(__linux__) || defined(__GNU__)) && !defined(_GNU_SOURCE) + #define _GNU_SOURCE + #endif + + #define sleep_ms(x) usleep(x*1000) +#endif + +#ifdef _MSC_VER + #define ALIGNOF(x) __alignof(x) + #define strtok_r(x, y, z) strtok_s(x, y, z) + #define strtof(x, y) (float)strtod(x, y) + #define strtoll(x, y, z) _strtoi64(x, y, z) + #define strtoull(x, y, z) _strtoui64(x, y, z) + #define strcasecmp(x, y) stricmp(x, y) + #define strncasecmp(x, y, n) strnicmp(x, y, n) +#else + #define ALIGNOF(x) __alignof__(x) +#endif + +#ifdef __MINGW32__ + #define strtok_r(x, y, z) mystrtok_r(x, y, z) +#endif + +// strlcpy is missing from glibc. thanks a lot, drepper. +// strlcpy is also missing from AIX and HP-UX because they aim to be weird. +// We can't simply alias strlcpy to MSVC's strcpy_s, since strcpy_s by +// default raises an assertion error and aborts the program if the buffer is +// too small. +#if defined(__FreeBSD__) || defined(__NetBSD__) || \ + defined(__OpenBSD__) || defined(__DragonFly__) || \ + defined(__APPLE__) || \ + defined(__sun) || defined(sun) || \ + defined(__QNX__) || defined(__QNXNTO__) + #define HAVE_STRLCPY +#endif + +// So we need to define our own. +#ifndef HAVE_STRLCPY + #define strlcpy(d, s, n) mystrlcpy(d, s, n) +#endif + +#define PADDING(x, y) ((ALIGNOF(y) - ((uintptr_t)(x) & (ALIGNOF(y) - 1))) & (ALIGNOF(y) - 1)) + +#if defined(__APPLE__) + #include <mach-o/dyld.h> + #include <CoreFoundation/CoreFoundation.h> +#endif + +#ifndef _WIN32 // Posix + #include <sys/time.h> + #include <ctime> + +#if defined(__MACH__) && defined(__APPLE__) + #include <mach/clock.h> + #include <mach/mach.h> + #endif +#endif + +namespace porting +{ + +/* + Signal handler (grabs Ctrl-C on POSIX systems) +*/ + +void signal_handler_init(); +// Returns a pointer to a bool. +// When the bool is true, program should quit. +bool * signal_handler_killstatus(); + +/* + Path of static data directory. +*/ +extern std::string path_share; + +/* + Directory for storing user data. Examples: + Windows: "C:\Documents and Settings\user\Application Data\<PROJECT_NAME>" + Linux: "~/.<PROJECT_NAME>" + Mac: "~/Library/Application Support/<PROJECT_NAME>" +*/ +extern std::string path_user; + +/* + Path to gettext locale files +*/ +extern std::string path_locale; + +/* + Path to directory for storing caches. +*/ +extern std::string path_cache; + +/* + Get full path of stuff in data directory. + Example: "stone.png" -> "../data/stone.png" +*/ +std::string getDataPath(const char *subpath); + +/* + Move cache folder from path_user to the + system cache location if possible. +*/ +void migrateCachePath(); + +/* + Initialize path_*. +*/ +void initializePaths(); + +/* + Return system information + e.g. "Linux/3.12.7 x86_64" +*/ +std::string get_sysinfo(); + + +// Monotonic counter getters. + +#ifdef _WIN32 // Windows + +extern double perf_freq; + +inline u64 os_get_time(double mult) +{ + LARGE_INTEGER t; + QueryPerformanceCounter(&t); + return static_cast<double>(t.QuadPart) / (perf_freq / mult); +} + +// Resolution is <1us. +inline u64 getTimeS() { return os_get_time(1); } +inline u64 getTimeMs() { return os_get_time(1000); } +inline u64 getTimeUs() { return os_get_time(1000*1000); } +inline u64 getTimeNs() { return os_get_time(1000*1000*1000); } + +#else // Posix + +inline void os_get_clock(struct timespec *ts) +{ +#if defined(__MACH__) && defined(__APPLE__) +// From http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x +// OS X does not have clock_gettime, use clock_get_time + clock_serv_t cclock; + mach_timespec_t mts; + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + ts->tv_sec = mts.tv_sec; + ts->tv_nsec = mts.tv_nsec; +#elif defined(CLOCK_MONOTONIC_RAW) + clock_gettime(CLOCK_MONOTONIC_RAW, ts); +#elif defined(_POSIX_MONOTONIC_CLOCK) + clock_gettime(CLOCK_MONOTONIC, ts); +#else + struct timeval tv; + gettimeofday(&tv, NULL); + TIMEVAL_TO_TIMESPEC(&tv, ts); +#endif +} + +inline u64 getTimeS() +{ + struct timespec ts; + os_get_clock(&ts); + return ts.tv_sec; +} + +inline u64 getTimeMs() +{ + struct timespec ts; + os_get_clock(&ts); + return ((u64) ts.tv_sec) * 1000LL + ((u64) ts.tv_nsec) / 1000000LL; +} + +inline u64 getTimeUs() +{ + struct timespec ts; + os_get_clock(&ts); + return ((u64) ts.tv_sec) * 1000000LL + ((u64) ts.tv_nsec) / 1000LL; +} + +inline u64 getTimeNs() +{ + struct timespec ts; + os_get_clock(&ts); + return ((u64) ts.tv_sec) * 1000000000LL + ((u64) ts.tv_nsec); +} + +#endif + +inline u64 getTime(TimePrecision prec) +{ + switch (prec) { + case PRECISION_SECONDS: return getTimeS(); + case PRECISION_MILLI: return getTimeMs(); + case PRECISION_MICRO: return getTimeUs(); + case PRECISION_NANO: return getTimeNs(); + } + FATAL_ERROR("Called getTime with invalid time precision"); +} + +/** + * Delta calculation function arguments. + * @param old_time_ms old time for delta calculation + * @param new_time_ms new time for delta calculation + * @return positive delta value + */ +inline u64 getDeltaMs(u64 old_time_ms, u64 new_time_ms) +{ + if (new_time_ms >= old_time_ms) { + return (new_time_ms - old_time_ms); + } + + return (old_time_ms - new_time_ms); +} + +inline const char *getPlatformName() +{ + return +#if defined(ANDROID) + "Android" +#elif defined(__linux__) + "Linux" +#elif defined(_WIN32) || defined(_WIN64) + "Windows" +#elif defined(__DragonFly__) || defined(__FreeBSD__) || \ + defined(__NetBSD__) || defined(__OpenBSD__) + "BSD" +#elif defined(__APPLE__) && defined(__MACH__) + #if TARGET_OS_MAC + "OSX" + #elif TARGET_OS_IPHONE + "iOS" + #else + "Apple" + #endif +#elif defined(_AIX) + "AIX" +#elif defined(__hpux) + "HP-UX" +#elif defined(__sun) || defined(sun) + #if defined(__SVR4) + "Solaris" + #else + "SunOS" + #endif +#elif defined(__HAIKU__) + "Haiku" +#elif defined(__CYGWIN__) + "Cygwin" +#elif defined(__unix__) || defined(__unix) + #if defined(_POSIX_VERSION) + "Posix" + #else + "Unix" + #endif +#else + "?" +#endif + ; +} + +bool secure_rand_fill_buf(void *buf, size_t len); + +// This attaches to the parents process console, or creates a new one if it doesnt exist. +void attachOrCreateConsole(); + +int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...); + +/** + * Opens URL in default web browser + * + * Must begin with http:// or https://, and not contain any new lines + * + * @param url The URL + * @return true on success, false on failure + */ +bool open_url(const std::string &url); + +/** + * Opens a directory in the default file manager + * + * The directory must exist. + * + * @param path Path to directory + * @return true on success, false on failure + */ +bool open_directory(const std::string &path); + +} // namespace porting + +#ifdef __ANDROID__ +#include "porting_android.h" +#endif diff --git a/src/porting_android.cpp b/src/porting_android.cpp new file mode 100644 index 0000000..83b590b --- /dev/null +++ b/src/porting_android.cpp @@ -0,0 +1,305 @@ +/* +Minetest +Copyright (C) 2014 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __ANDROID__ +#error This file may only be compiled for android! +#endif + +#include "util/numeric.h" +#include "porting.h" +#include "porting_android.h" +#include "threading/thread.h" +#include "config.h" +#include "filesys.h" +#include "log.h" + +#include <sstream> +#include <exception> +#include <cstdlib> + +#ifdef GPROF +#include "prof.h" +#endif + +extern int main(int argc, char *argv[]); + +void android_main(android_app *app) +{ + int retval = 0; + porting::app_global = app; + + Thread::setName("Main"); + + try { + char *argv[] = {strdup(PROJECT_NAME), nullptr}; + main(ARRLEN(argv) - 1, argv); + free(argv[0]); + } catch (std::exception &e) { + errorstream << "Uncaught exception in main thread: " << e.what() << std::endl; + retval = -1; + } catch (...) { + errorstream << "Uncaught exception in main thread!" << std::endl; + retval = -1; + } + + porting::cleanupAndroid(); + infostream << "Shutting down." << std::endl; + exit(retval); +} + +/** + * Handler for finished message box input + * Intentionally NOT in namespace porting + * ToDo: this doesn't work as expected, there's a workaround for it right now + */ +extern "C" { + JNIEXPORT void JNICALL Java_net_minetest_minetest_GameActivity_putMessageBoxResult( + JNIEnv *env, jclass thiz, jstring text) + { + errorstream << + "Java_net_minetest_minetest_GameActivity_putMessageBoxResult got: " << + std::string((const char*) env->GetStringChars(text, nullptr)) << std::endl; + } +} + +namespace porting { +android_app *app_global; +JNIEnv *jnienv; +jclass nativeActivity; + +jclass findClass(const std::string &classname) +{ + if (jnienv == nullptr) + return nullptr; + + jclass nativeactivity = jnienv->FindClass("android/app/NativeActivity"); + jmethodID getClassLoader = jnienv->GetMethodID( + nativeactivity, "getClassLoader", "()Ljava/lang/ClassLoader;"); + jobject cls = jnienv->CallObjectMethod( + app_global->activity->clazz, getClassLoader); + jclass classLoader = jnienv->FindClass("java/lang/ClassLoader"); + jmethodID findClass = jnienv->GetMethodID(classLoader, "loadClass", + "(Ljava/lang/String;)Ljava/lang/Class;"); + jstring strClassName = jnienv->NewStringUTF(classname.c_str()); + return (jclass) jnienv->CallObjectMethod(cls, findClass, strClassName); +} + +void initAndroid() +{ + porting::jnienv = nullptr; + JavaVM *jvm = app_global->activity->vm; + JavaVMAttachArgs lJavaVMAttachArgs; + lJavaVMAttachArgs.version = JNI_VERSION_1_6; + lJavaVMAttachArgs.name = PROJECT_NAME_C "NativeThread"; + lJavaVMAttachArgs.group = nullptr; + + if (jvm->AttachCurrentThread(&porting::jnienv, &lJavaVMAttachArgs) == JNI_ERR) { + errorstream << "Failed to attach native thread to jvm" << std::endl; + exit(-1); + } + + nativeActivity = findClass("net/minetest/minetest/GameActivity"); + if (nativeActivity == nullptr) + errorstream << + "porting::initAndroid unable to find java native activity class" << + std::endl; + +#ifdef GPROF + // in the start-up code + __android_log_print(ANDROID_LOG_ERROR, PROJECT_NAME_C, + "Initializing GPROF profiler"); + monstartup("libMinetest.so"); +#endif +} + +void cleanupAndroid() +{ +#ifdef GPROF + errorstream << "Shutting down GPROF profiler" << std::endl; + setenv("CPUPROFILE", (path_user + DIR_DELIM + "gmon.out").c_str(), 1); + moncleanup(); +#endif + + JavaVM *jvm = app_global->activity->vm; + jvm->DetachCurrentThread(); +} + +static std::string javaStringToUTF8(jstring js) +{ + std::string str; + // Get string as a UTF-8 c-string + const char *c_str = jnienv->GetStringUTFChars(js, nullptr); + // Save it + str = c_str; + // And free the c-string + jnienv->ReleaseStringUTFChars(js, c_str); + return str; +} + +void initializePathsAndroid() +{ + // Set user and share paths + { + jmethodID getUserDataPath = jnienv->GetMethodID(nativeActivity, + "getUserDataPath", "()Ljava/lang/String;"); + FATAL_ERROR_IF(getUserDataPath==nullptr, + "porting::initializePathsAndroid unable to find Java getUserDataPath method"); + jobject result = jnienv->CallObjectMethod(app_global->activity->clazz, getUserDataPath); + const char *javachars = jnienv->GetStringUTFChars((jstring) result, nullptr); + path_user = javachars; + path_share = javachars; + path_locale = path_share + DIR_DELIM + "locale"; + jnienv->ReleaseStringUTFChars((jstring) result, javachars); + } + + // Set cache path + { + jmethodID getCachePath = jnienv->GetMethodID(nativeActivity, + "getCachePath", "()Ljava/lang/String;"); + FATAL_ERROR_IF(getCachePath==nullptr, + "porting::initializePathsAndroid unable to find Java getCachePath method"); + jobject result = jnienv->CallObjectMethod(app_global->activity->clazz, getCachePath); + const char *javachars = jnienv->GetStringUTFChars((jstring) result, nullptr); + path_cache = javachars; + jnienv->ReleaseStringUTFChars((jstring) result, javachars); + + migrateCachePath(); + } +} + +void showInputDialog(const std::string &acceptButton, const std::string &hint, + const std::string ¤t, int editType) +{ + jmethodID showdialog = jnienv->GetMethodID(nativeActivity, "showDialog", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V"); + + FATAL_ERROR_IF(showdialog == nullptr, + "porting::showInputDialog unable to find java show dialog method"); + + jstring jacceptButton = jnienv->NewStringUTF(acceptButton.c_str()); + jstring jhint = jnienv->NewStringUTF(hint.c_str()); + jstring jcurrent = jnienv->NewStringUTF(current.c_str()); + jint jeditType = editType; + + jnienv->CallVoidMethod(app_global->activity->clazz, showdialog, + jacceptButton, jhint, jcurrent, jeditType); +} + +void openURIAndroid(const std::string &url) +{ + jmethodID url_open = jnienv->GetMethodID(nativeActivity, "openURI", + "(Ljava/lang/String;)V"); + + FATAL_ERROR_IF(url_open == nullptr, + "porting::openURIAndroid unable to find java openURI method"); + + jstring jurl = jnienv->NewStringUTF(url.c_str()); + jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl); +} + +void shareFileAndroid(const std::string &path) +{ + jmethodID url_open = jnienv->GetMethodID(nativeActivity, "shareFile", + "(Ljava/lang/String;)V"); + + FATAL_ERROR_IF(url_open == nullptr, + "porting::shareFileAndroid unable to find java openURI method"); + + jstring jurl = jnienv->NewStringUTF(path.c_str()); + jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl); +} + +int getInputDialogState() +{ + jmethodID dialogstate = jnienv->GetMethodID(nativeActivity, + "getDialogState", "()I"); + + FATAL_ERROR_IF(dialogstate == nullptr, + "porting::getInputDialogState unable to find java dialog state method"); + + return jnienv->CallIntMethod(app_global->activity->clazz, dialogstate); +} + +std::string getInputDialogValue() +{ + jmethodID dialogvalue = jnienv->GetMethodID(nativeActivity, + "getDialogValue", "()Ljava/lang/String;"); + + FATAL_ERROR_IF(dialogvalue == nullptr, + "porting::getInputDialogValue unable to find java dialog value method"); + + jobject result = jnienv->CallObjectMethod(app_global->activity->clazz, + dialogvalue); + + const char *javachars = jnienv->GetStringUTFChars((jstring) result, nullptr); + std::string text(javachars); + jnienv->ReleaseStringUTFChars((jstring) result, javachars); + + return text; +} + +#ifndef SERVER +float getDisplayDensity() +{ + static bool firstrun = true; + static float value = 0; + + if (firstrun) { + jmethodID getDensity = jnienv->GetMethodID(nativeActivity, + "getDensity", "()F"); + + FATAL_ERROR_IF(getDensity == nullptr, + "porting::getDisplayDensity unable to find java getDensity method"); + + value = jnienv->CallFloatMethod(app_global->activity->clazz, getDensity); + firstrun = false; + } + return value; +} + +v2u32 getDisplaySize() +{ + static bool firstrun = true; + static v2u32 retval; + + if (firstrun) { + jmethodID getDisplayWidth = jnienv->GetMethodID(nativeActivity, + "getDisplayWidth", "()I"); + + FATAL_ERROR_IF(getDisplayWidth == nullptr, + "porting::getDisplayWidth unable to find java getDisplayWidth method"); + + retval.X = jnienv->CallIntMethod(app_global->activity->clazz, + getDisplayWidth); + + jmethodID getDisplayHeight = jnienv->GetMethodID(nativeActivity, + "getDisplayHeight", "()I"); + + FATAL_ERROR_IF(getDisplayHeight == nullptr, + "porting::getDisplayHeight unable to find java getDisplayHeight method"); + + retval.Y = jnienv->CallIntMethod(app_global->activity->clazz, + getDisplayHeight); + + firstrun = false; + } + return retval; +} +#endif // ndef SERVER +} diff --git a/src/porting_android.h b/src/porting_android.h new file mode 100644 index 0000000..265825f --- /dev/null +++ b/src/porting_android.h @@ -0,0 +1,86 @@ +/* +Minetest +Copyright (C) 2014 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#ifndef __ANDROID__ +#error this include has to be included on android port only! +#endif + +#include <jni.h> +#include <android_native_app_glue.h> +#include <android/log.h> + +#include <string> + +namespace porting { +// java app +extern android_app *app_global; + +// java <-> c++ interaction interface +extern JNIEnv *jnienv; + +// do initialization required on android only +void initAndroid(); + +void cleanupAndroid(); + +/** + * Initializes path_* variables for Android + * @param env Android JNI environment + */ +void initializePathsAndroid(); + +/** + * show text input dialog in java + * @param acceptButton text to display on accept button + * @param hint hint to show + * @param current initial value to display + * @param editType type of texfield + * (1==multiline text input; 2==single line text input; 3=password field) + */ +void showInputDialog(const std::string &acceptButton, + const std::string &hint, const std::string ¤t, int editType); + +void openURIAndroid(const std::string &url); + +/** + * Opens a share intent to the file at path + * + * @param path + */ +void shareFileAndroid(const std::string &path); + +/** + * WORKAROUND for not working callbacks from java -> c++ + * get current state of input dialog + */ +int getInputDialogState(); + +/** + * WORKAROUND for not working callbacks from java -> c++ + * get text in current input dialog + */ +std::string getInputDialogValue(); + +#ifndef SERVER +float getDisplayDensity(); +v2u32 getDisplaySize(); +#endif +} diff --git a/src/profiler.cpp b/src/profiler.cpp new file mode 100644 index 0000000..d05b7ab --- /dev/null +++ b/src/profiler.cpp @@ -0,0 +1,182 @@ +/* +Minetest +Copyright (C) 2015 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "profiler.h" +#include "porting.h" + +static Profiler main_profiler; +Profiler *g_profiler = &main_profiler; +ScopeProfiler::ScopeProfiler( + Profiler *profiler, const std::string &name, ScopeProfilerType type) : + m_profiler(profiler), + m_name(name), m_type(type) +{ + m_name.append(" [ms]"); + if (m_profiler) + m_timer = new TimeTaker(m_name, nullptr, PRECISION_MILLI); +} + +ScopeProfiler::~ScopeProfiler() +{ + if (!m_timer) + return; + + float duration_ms = m_timer->stop(true); + float duration = duration_ms; + if (m_profiler) { + switch (m_type) { + case SPT_ADD: + m_profiler->add(m_name, duration); + break; + case SPT_AVG: + m_profiler->avg(m_name, duration); + break; + case SPT_GRAPH_ADD: + m_profiler->graphAdd(m_name, duration); + break; + } + } + delete m_timer; +} + +Profiler::Profiler() +{ + m_start_time = porting::getTimeMs(); +} + +void Profiler::add(const std::string &name, float value) +{ + MutexAutoLock lock(m_mutex); + { + /* No average shall have been used; mark add used as -2 */ + std::map<std::string, int>::iterator n = m_avgcounts.find(name); + if (n == m_avgcounts.end()) { + m_avgcounts[name] = -2; + } else { + if (n->second == -1) + n->second = -2; + assert(n->second == -2); + } + } + { + std::map<std::string, float>::iterator n = m_data.find(name); + if (n == m_data.end()) + m_data[name] = value; + else + n->second += value; + } +} + +void Profiler::avg(const std::string &name, float value) +{ + MutexAutoLock lock(m_mutex); + int &count = m_avgcounts[name]; + + assert(count != -2); + count = MYMAX(count, 0) + 1; + m_data[name] += value; +} + +void Profiler::clear() +{ + MutexAutoLock lock(m_mutex); + for (auto &it : m_data) { + it.second = 0; + } + m_avgcounts.clear(); + m_start_time = porting::getTimeMs(); +} + +float Profiler::getValue(const std::string &name) const +{ + auto numerator = m_data.find(name); + if (numerator == m_data.end()) + return 0.f; + + auto denominator = m_avgcounts.find(name); + if (denominator != m_avgcounts.end()) { + if (denominator->second >= 1) + return numerator->second / denominator->second; + } + + return numerator->second; +} + +int Profiler::getAvgCount(const std::string &name) const +{ + auto n = m_avgcounts.find(name); + + if (n != m_avgcounts.end() && n->second >= 1) + return n->second; + + return 1; +} + +u64 Profiler::getElapsedMs() const +{ + return porting::getTimeMs() - m_start_time; +} + +int Profiler::print(std::ostream &o, u32 page, u32 pagecount) +{ + GraphValues values; + getPage(values, page, pagecount); + char num_buf[50]; + + for (const auto &i : values) { + o << " " << i.first << " "; + if (i.second == 0) { + o << std::endl; + continue; + } + + s32 space = 44 - i.first.size(); + for (s32 j = 0; j < space; j++) { + if ((j & 1) && j < space - 1) + o << "."; + else + o << " "; + } + porting::mt_snprintf(num_buf, sizeof(num_buf), "% 4ix % 3g", + getAvgCount(i.first), i.second); + o << num_buf << std::endl; + } + return values.size(); +} + +void Profiler::getPage(GraphValues &o, u32 page, u32 pagecount) +{ + MutexAutoLock lock(m_mutex); + + u32 minindex, maxindex; + paging(m_data.size(), page, pagecount, minindex, maxindex); + + for (const auto &i : m_data) { + if (maxindex == 0) + break; + maxindex--; + + if (minindex != 0) { + minindex--; + continue; + } + + o[i.first] = i.second / getAvgCount(i.first); + } +} diff --git a/src/profiler.h b/src/profiler.h new file mode 100644 index 0000000..b4a0657 --- /dev/null +++ b/src/profiler.h @@ -0,0 +1,109 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include <cassert> +#include <string> +#include <map> +#include <ostream> + +#include "threading/mutex_auto_lock.h" +#include "util/timetaker.h" +#include "util/numeric.h" // paging() + +// Global profiler +class Profiler; +extern Profiler *g_profiler; + +/* + Time profiler +*/ + +class Profiler +{ +public: + Profiler(); + + void add(const std::string &name, float value); + void avg(const std::string &name, float value); + void clear(); + + float getValue(const std::string &name) const; + int getAvgCount(const std::string &name) const; + u64 getElapsedMs() const; + + typedef std::map<std::string, float> GraphValues; + + // Returns the line count + int print(std::ostream &o, u32 page = 1, u32 pagecount = 1); + void getPage(GraphValues &o, u32 page, u32 pagecount); + + + void graphAdd(const std::string &id, float value) + { + MutexAutoLock lock(m_mutex); + std::map<std::string, float>::iterator i = + m_graphvalues.find(id); + if(i == m_graphvalues.end()) + m_graphvalues[id] = value; + else + i->second += value; + } + void graphGet(GraphValues &result) + { + MutexAutoLock lock(m_mutex); + result = m_graphvalues; + m_graphvalues.clear(); + } + + void remove(const std::string& name) + { + MutexAutoLock lock(m_mutex); + m_avgcounts.erase(name); + m_data.erase(name); + } + +private: + std::mutex m_mutex; + std::map<std::string, float> m_data; + std::map<std::string, int> m_avgcounts; + std::map<std::string, float> m_graphvalues; + u64 m_start_time; +}; + +enum ScopeProfilerType{ + SPT_ADD, + SPT_AVG, + SPT_GRAPH_ADD +}; + +class ScopeProfiler +{ +public: + ScopeProfiler(Profiler *profiler, const std::string &name, + ScopeProfilerType type = SPT_ADD); + ~ScopeProfiler(); +private: + Profiler *m_profiler = nullptr; + std::string m_name; + TimeTaker *m_timer = nullptr; + enum ScopeProfilerType m_type; +}; diff --git a/src/raycast.cpp b/src/raycast.cpp new file mode 100644 index 0000000..ebc4023 --- /dev/null +++ b/src/raycast.cpp @@ -0,0 +1,137 @@ +/* +Minetest +Copyright (C) 2016 juhdanad, Daniel Juhasz <juhdanad@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "raycast.h" +#include "irr_v3d.h" +#include "irr_aabb3d.h" +#include "constants.h" + +bool RaycastSort::operator() (const PointedThing &pt1, + const PointedThing &pt2) const +{ + // "nothing" can not be sorted + assert(pt1.type != POINTEDTHING_NOTHING); + assert(pt2.type != POINTEDTHING_NOTHING); + f32 pt1_distSq = pt1.distanceSq; + + // Add some bonus when one of them is an object + if (pt1.type != pt2.type) { + if (pt1.type == POINTEDTHING_OBJECT) + pt1_distSq -= BS * BS; + else if (pt2.type == POINTEDTHING_OBJECT) + pt1_distSq += BS * BS; + } + + // returns false if pt1 is nearer than pt2 + if (pt1_distSq < pt2.distanceSq) { + return false; + } + + if (pt1_distSq == pt2.distanceSq) { + // Sort them to allow only one order + if (pt1.type == POINTEDTHING_OBJECT) + return (pt2.type == POINTEDTHING_OBJECT + && pt1.object_id < pt2.object_id); + + return (pt2.type == POINTEDTHING_OBJECT + || pt1.node_undersurface < pt2.node_undersurface); + } + return true; +} + + +RaycastState::RaycastState(const core::line3d<f32> &shootline, + bool objects_pointable, bool liquids_pointable) : + m_shootline(shootline), + m_iterator(shootline.start / BS, shootline.getVector() / BS), + m_previous_node(m_iterator.m_current_node_pos), + m_objects_pointable(objects_pointable), + m_liquids_pointable(liquids_pointable) +{ +} + + +bool boxLineCollision(const aabb3f &box, const v3f &start, + const v3f &dir, v3f *collision_point, v3s16 *collision_normal) +{ + if (box.isPointInside(start)) { + *collision_point = start; + collision_normal->set(0, 0, 0); + return true; + } + float m = 0; + + // Test X collision + if (dir.X != 0) { + if (dir.X > 0) + m = (box.MinEdge.X - start.X) / dir.X; + else + m = (box.MaxEdge.X - start.X) / dir.X; + + if (m >= 0 && m <= 1) { + *collision_point = start + dir * m; + if ((collision_point->Y >= box.MinEdge.Y) + && (collision_point->Y <= box.MaxEdge.Y) + && (collision_point->Z >= box.MinEdge.Z) + && (collision_point->Z <= box.MaxEdge.Z)) { + collision_normal->set((dir.X > 0) ? -1 : 1, 0, 0); + return true; + } + } + } + + // Test Y collision + if (dir.Y != 0) { + if (dir.Y > 0) + m = (box.MinEdge.Y - start.Y) / dir.Y; + else + m = (box.MaxEdge.Y - start.Y) / dir.Y; + + if (m >= 0 && m <= 1) { + *collision_point = start + dir * m; + if ((collision_point->X >= box.MinEdge.X) + && (collision_point->X <= box.MaxEdge.X) + && (collision_point->Z >= box.MinEdge.Z) + && (collision_point->Z <= box.MaxEdge.Z)) { + collision_normal->set(0, (dir.Y > 0) ? -1 : 1, 0); + return true; + } + } + } + + // Test Z collision + if (dir.Z != 0) { + if (dir.Z > 0) + m = (box.MinEdge.Z - start.Z) / dir.Z; + else + m = (box.MaxEdge.Z - start.Z) / dir.Z; + + if (m >= 0 && m <= 1) { + *collision_point = start + dir * m; + if ((collision_point->X >= box.MinEdge.X) + && (collision_point->X <= box.MaxEdge.X) + && (collision_point->Y >= box.MinEdge.Y) + && (collision_point->Y <= box.MaxEdge.Y)) { + collision_normal->set(0, 0, (dir.Z > 0) ? -1 : 1); + return true; + } + } + } + return false; +} diff --git a/src/raycast.h b/src/raycast.h new file mode 100644 index 0000000..734efd6 --- /dev/null +++ b/src/raycast.h @@ -0,0 +1,77 @@ +/* +Minetest +Copyright (C) 2016 juhdanad, Daniel Juhasz <juhdanad@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "voxelalgorithms.h" +#include "util/pointedthing.h" + +//! Sorts PointedThings based on their distance. +struct RaycastSort +{ + bool operator() (const PointedThing &pt1, const PointedThing &pt2) const; +}; + +//! Describes the state of a raycast. +class RaycastState +{ +public: + /*! + * Creates a raycast. + * @param objects_pointable if false, only nodes will be found + * @param liquids pointable if false, liquid nodes won't be found + */ + RaycastState(const core::line3d<f32> &shootline, bool objects_pointable, + bool liquids_pointable); + + //! Shootline of the raycast. + core::line3d<f32> m_shootline; + //! Iterator to store the progress of the raycast. + voxalgo::VoxelLineIterator m_iterator; + //! Previous tested node during the raycast. + v3s16 m_previous_node; + + /*! + * This priority queue stores the found pointed things + * waiting to be returned. + */ + std::priority_queue<PointedThing, std::vector<PointedThing>, RaycastSort> m_found; + + bool m_objects_pointable; + bool m_liquids_pointable; + + //! The code needs to search these nodes around the center node. + core::aabbox3d<s16> m_search_range { 0, 0, 0, 0, 0, 0 }; + + //! If true, the Environment will initialize this state. + bool m_initialization_needed = true; +}; + +/*! + * Checks if a line and a box intersects. + * @param[in] box box to test collision + * @param[in] start starting point of the line + * @param[in] dir direction and length of the line + * @param[out] collision_point first point of the collision + * @param[out] collision_normal normal vector at the collision, points + * outwards of the surface. If start is in the box, zero vector. + * @returns true if a collision point was found + */ +bool boxLineCollision(const aabb3f &box, const v3f &start, const v3f &dir, + v3f *collision_point, v3s16 *collision_normal); diff --git a/src/reflowscan.cpp b/src/reflowscan.cpp new file mode 100644 index 0000000..9d5c965 --- /dev/null +++ b/src/reflowscan.cpp @@ -0,0 +1,205 @@ +/* +Minetest +Copyright (C) 2016 MillersMan <millersman@users.noreply.github.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "reflowscan.h" +#include "map.h" +#include "mapblock.h" +#include "nodedef.h" +#include "util/timetaker.h" + + +ReflowScan::ReflowScan(Map *map, const NodeDefManager *ndef) : + m_map(map), + m_ndef(ndef) +{ +} + +void ReflowScan::scan(MapBlock *block, UniqueQueue<v3s16> *liquid_queue) +{ + m_block_pos = block->getPos(); + m_rel_block_pos = block->getPosRelative(); + m_liquid_queue = liquid_queue; + + // Prepare the lookup which is a 3x3x3 array of the blocks surrounding the + // scanned block. Blocks are only added to the lookup if they are really + // needed. The lookup is indexed manually to use the same index in a + // bit-array (of uint32 type) which stores for unloaded blocks that they + // were already fetched from Map but were actually nullptr. + memset(m_lookup, 0, sizeof(m_lookup)); + int block_idx = 1 + (1 * 9) + (1 * 3); + m_lookup[block_idx] = block; + m_lookup_state_bitset = 1 << block_idx; + + // Scan the columns in the block + for (s16 z = 0; z < MAP_BLOCKSIZE; z++) + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { + scanColumn(x, z); + } + + // Scan neighbouring columns from the nearby blocks as they might contain + // liquid nodes that weren't allowed to flow to prevent gaps. + for (s16 i = 0; i < MAP_BLOCKSIZE; i++) { + scanColumn(i, -1); + scanColumn(i, MAP_BLOCKSIZE); + scanColumn(-1, i); + scanColumn(MAP_BLOCKSIZE, i); + } +} + +inline MapBlock *ReflowScan::lookupBlock(int x, int y, int z) +{ + // Gets the block that contains (x,y,z) relativ to the scanned block. + // This uses a lookup as there might be many lookups into the same + // neighbouring block which makes fetches from Map costly. + int bx = (MAP_BLOCKSIZE + x) / MAP_BLOCKSIZE; + int by = (MAP_BLOCKSIZE + y) / MAP_BLOCKSIZE; + int bz = (MAP_BLOCKSIZE + z) / MAP_BLOCKSIZE; + int idx = (bx + (by * 9) + (bz * 3)); + MapBlock *result = m_lookup[idx]; + if (!result && (m_lookup_state_bitset & (1 << idx)) == 0) { + // The block wasn't requested yet so fetch it from Map and store it + // in the lookup + v3s16 pos = m_block_pos + v3s16(bx - 1, by - 1, bz - 1); + m_lookup[idx] = result = m_map->getBlockNoCreateNoEx(pos); + m_lookup_state_bitset |= (1 << idx); + } + return result; +} + +inline bool ReflowScan::isLiquidFlowableTo(int x, int y, int z) +{ + // Tests whether (x,y,z) is a node to which liquid might flow. + bool valid_position; + MapBlock *block = lookupBlock(x, y, z); + if (block) { + int dx = (MAP_BLOCKSIZE + x) % MAP_BLOCKSIZE; + int dy = (MAP_BLOCKSIZE + y) % MAP_BLOCKSIZE; + int dz = (MAP_BLOCKSIZE + z) % MAP_BLOCKSIZE; + MapNode node = block->getNodeNoCheck(dx, dy, dz, &valid_position); + if (node.getContent() != CONTENT_IGNORE) { + const ContentFeatures &f = m_ndef->get(node); + // NOTE: No need to check for flowing nodes with lower liquid level + // as they should only occur on top of other columns where they + // will be added to the queue themselves. + return f.floodable; + } + } + return false; +} + +inline bool ReflowScan::isLiquidHorizontallyFlowable(int x, int y, int z) +{ + // Check if the (x,y,z) might spread to one of the horizontally + // neighbouring nodes + return isLiquidFlowableTo(x - 1, y, z) || + isLiquidFlowableTo(x + 1, y, z) || + isLiquidFlowableTo(x, y, z - 1) || + isLiquidFlowableTo(x, y, z + 1); +} + +void ReflowScan::scanColumn(int x, int z) +{ + bool valid_position; + + // Is the column inside a loaded block? + MapBlock *block = lookupBlock(x, 0, z); + if (!block) + return; + + MapBlock *above = lookupBlock(x, MAP_BLOCKSIZE, z); + int dx = (MAP_BLOCKSIZE + x) % MAP_BLOCKSIZE; + int dz = (MAP_BLOCKSIZE + z) % MAP_BLOCKSIZE; + + // Get the state from the node above the scanned block + bool was_ignore, was_liquid; + if (above) { + MapNode node = above->getNodeNoCheck(dx, 0, dz, &valid_position); + was_ignore = node.getContent() == CONTENT_IGNORE; + was_liquid = m_ndef->get(node).isLiquid(); + } else { + was_ignore = true; + was_liquid = false; + } + bool was_checked = false; + bool was_pushed = false; + + // Scan through the whole block + for (s16 y = MAP_BLOCKSIZE - 1; y >= 0; y--) { + MapNode node = block->getNodeNoCheck(dx, y, dz, &valid_position); + const ContentFeatures &f = m_ndef->get(node); + bool is_ignore = node.getContent() == CONTENT_IGNORE; + bool is_liquid = f.isLiquid(); + + if (is_ignore || was_ignore || is_liquid == was_liquid) { + // Neither topmost node of liquid column nor topmost node below column + was_checked = false; + was_pushed = false; + } else if (is_liquid) { + // This is the topmost node in the column + bool is_pushed = false; + if (f.liquid_type == LIQUID_FLOWING || + isLiquidHorizontallyFlowable(x, y, z)) { + m_liquid_queue->push_back(m_rel_block_pos + v3s16(x, y, z)); + is_pushed = true; + } + // Remember waschecked and waspushed to avoid repeated + // checks/pushes in case the column consists of only this node + was_checked = true; + was_pushed = is_pushed; + } else { + // This is the topmost node below a liquid column + if (!was_pushed && (f.floodable || + (!was_checked && isLiquidHorizontallyFlowable(x, y + 1, z)))) { + // Activate the lowest node in the column which is one + // node above this one + m_liquid_queue->push_back(m_rel_block_pos + v3s16(x, y + 1, z)); + } + } + + was_liquid = is_liquid; + was_ignore = is_ignore; + } + + // Check the node below the current block + MapBlock *below = lookupBlock(x, -1, z); + if (below) { + MapNode node = below->getNodeNoCheck(dx, MAP_BLOCKSIZE - 1, dz, &valid_position); + const ContentFeatures &f = m_ndef->get(node); + bool is_ignore = node.getContent() == CONTENT_IGNORE; + bool is_liquid = f.isLiquid(); + + if (is_ignore || was_ignore || is_liquid == was_liquid) { + // Neither topmost node of liquid column nor topmost node below column + } else if (is_liquid) { + // This is the topmost node in the column and might want to flow away + if (f.liquid_type == LIQUID_FLOWING || + isLiquidHorizontallyFlowable(x, -1, z)) { + m_liquid_queue->push_back(m_rel_block_pos + v3s16(x, -1, z)); + } + } else { + // This is the topmost node below a liquid column + if (!was_pushed && (f.floodable || + (!was_checked && isLiquidHorizontallyFlowable(x, 0, z)))) { + // Activate the lowest node in the column which is one + // node above this one + m_liquid_queue->push_back(m_rel_block_pos + v3s16(x, 0, z)); + } + } + } +} diff --git a/src/reflowscan.h b/src/reflowscan.h new file mode 100644 index 0000000..7961432 --- /dev/null +++ b/src/reflowscan.h @@ -0,0 +1,47 @@ +/* +Minetest +Copyright (C) 2016 MillersMan <millersman@users.noreply.github.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "util/container.h" +#include "irrlichttypes_bloated.h" + +class NodeDefManager; +class Map; +class MapBlock; + +class ReflowScan { +public: + ReflowScan(Map *map, const NodeDefManager *ndef); + void scan(MapBlock *block, UniqueQueue<v3s16> *liquid_queue); + +private: + MapBlock *lookupBlock(int x, int y, int z); + bool isLiquidFlowableTo(int x, int y, int z); + bool isLiquidHorizontallyFlowable(int x, int y, int z); + void scanColumn(int x, int z); + +private: + Map *m_map = nullptr; + const NodeDefManager *m_ndef = nullptr; + v3s16 m_block_pos, m_rel_block_pos; + UniqueQueue<v3s16> *m_liquid_queue = nullptr; + MapBlock *m_lookup[3 * 3 * 3]; + u32 m_lookup_state_bitset; +}; diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp new file mode 100644 index 0000000..20be7a8 --- /dev/null +++ b/src/remoteplayer.cpp @@ -0,0 +1,117 @@ +/* +Minetest +Copyright (C) 2010-2016 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2014-2016 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "remoteplayer.h" +#include <json/json.h> +#include "filesys.h" +#include "gamedef.h" +#include "porting.h" // strlcpy +#include "server.h" +#include "settings.h" +#include "convert_json.h" +#include "server/player_sao.h" + +/* + RemotePlayer +*/ + +// static config cache for remoteplayer +bool RemotePlayer::m_setting_cache_loaded = false; +float RemotePlayer::m_setting_chat_message_limit_per_10sec = 0.0f; +u16 RemotePlayer::m_setting_chat_message_limit_trigger_kick = 0; + +RemotePlayer::RemotePlayer(const char *name, IItemDefManager *idef): + Player(name, idef) +{ + if (!RemotePlayer::m_setting_cache_loaded) { + RemotePlayer::m_setting_chat_message_limit_per_10sec = + g_settings->getFloat("chat_message_limit_per_10sec"); + RemotePlayer::m_setting_chat_message_limit_trigger_kick = + g_settings->getU16("chat_message_limit_trigger_kick"); + RemotePlayer::m_setting_cache_loaded = true; + } + + movement_acceleration_default = g_settings->getFloat("movement_acceleration_default") * BS; + movement_acceleration_air = g_settings->getFloat("movement_acceleration_air") * BS; + movement_acceleration_fast = g_settings->getFloat("movement_acceleration_fast") * BS; + movement_speed_walk = g_settings->getFloat("movement_speed_walk") * BS; + movement_speed_crouch = g_settings->getFloat("movement_speed_crouch") * BS; + movement_speed_fast = g_settings->getFloat("movement_speed_fast") * BS; + movement_speed_climb = g_settings->getFloat("movement_speed_climb") * BS; + movement_speed_jump = g_settings->getFloat("movement_speed_jump") * BS; + movement_liquid_fluidity = g_settings->getFloat("movement_liquid_fluidity") * BS; + movement_liquid_fluidity_smooth = g_settings->getFloat("movement_liquid_fluidity_smooth") * BS; + movement_liquid_sink = g_settings->getFloat("movement_liquid_sink") * BS; + movement_gravity = g_settings->getFloat("movement_gravity") * BS; + + // Skybox defaults: + m_cloud_params = SkyboxDefaults::getCloudDefaults(); + m_skybox_params = SkyboxDefaults::getSkyDefaults(); + m_sun_params = SkyboxDefaults::getSunDefaults(); + m_moon_params = SkyboxDefaults::getMoonDefaults(); + m_star_params = SkyboxDefaults::getStarDefaults(); +} + + +RemotePlayerChatResult RemotePlayer::canSendChatMessage() +{ + // Rate limit messages + u32 now = time(NULL); + float time_passed = now - m_last_chat_message_sent; + m_last_chat_message_sent = now; + + // If this feature is disabled + if (m_setting_chat_message_limit_per_10sec <= 0.0) { + return RPLAYER_CHATRESULT_OK; + } + + m_chat_message_allowance += time_passed * (m_setting_chat_message_limit_per_10sec / 8.0f); + if (m_chat_message_allowance > m_setting_chat_message_limit_per_10sec) { + m_chat_message_allowance = m_setting_chat_message_limit_per_10sec; + } + + if (m_chat_message_allowance < 1.0f) { + infostream << "Player " << m_name + << " chat limited due to excessive message amount." << std::endl; + + // Kick player if flooding is too intensive + m_message_rate_overhead++; + if (m_message_rate_overhead > RemotePlayer::m_setting_chat_message_limit_trigger_kick) { + return RPLAYER_CHATRESULT_KICK; + } + + return RPLAYER_CHATRESULT_FLOODING; + } + + // Reinit message overhead + if (m_message_rate_overhead > 0) { + m_message_rate_overhead = 0; + } + + m_chat_message_allowance -= 1.0f; + return RPLAYER_CHATRESULT_OK; +} + +void RemotePlayer::onSuccessfulSave() +{ + setModified(false); + if (m_sao) + m_sao->getMeta().setModified(false); +} diff --git a/src/remoteplayer.h b/src/remoteplayer.h new file mode 100644 index 0000000..0ab33ad --- /dev/null +++ b/src/remoteplayer.h @@ -0,0 +1,171 @@ +/* +Minetest +Copyright (C) 2010-2016 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2014-2016 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "player.h" +#include "skyparams.h" +#include "lighting.h" + +class PlayerSAO; + +enum RemotePlayerChatResult +{ + RPLAYER_CHATRESULT_OK, + RPLAYER_CHATRESULT_FLOODING, + RPLAYER_CHATRESULT_KICK, +}; + +/* + Player on the server +*/ +class RemotePlayer : public Player +{ + friend class PlayerDatabaseFiles; + +public: + RemotePlayer(const char *name, IItemDefManager *idef); + virtual ~RemotePlayer() = default; + + PlayerSAO *getPlayerSAO() { return m_sao; } + void setPlayerSAO(PlayerSAO *sao) { m_sao = sao; } + + RemotePlayerChatResult canSendChatMessage(); + + void setHotbarItemcount(s32 hotbar_itemcount) + { + hud_hotbar_itemcount = hotbar_itemcount; + } + + s32 getHotbarItemcount() const { return hud_hotbar_itemcount; } + + void overrideDayNightRatio(bool do_override, float ratio) + { + m_day_night_ratio_do_override = do_override; + m_day_night_ratio = ratio; + } + + void getDayNightRatio(bool *do_override, float *ratio) + { + *do_override = m_day_night_ratio_do_override; + *ratio = m_day_night_ratio; + } + + void setHotbarImage(const std::string &name) { hud_hotbar_image = name; } + + const std::string &getHotbarImage() const { return hud_hotbar_image; } + + void setHotbarSelectedImage(const std::string &name) + { + hud_hotbar_selected_image = name; + } + + const std::string &getHotbarSelectedImage() const + { + return hud_hotbar_selected_image; + } + + void setSky(const SkyboxParams &skybox_params) + { + m_skybox_params = skybox_params; + } + + const SkyboxParams &getSkyParams() const { return m_skybox_params; } + + void setSun(const SunParams &sun_params) { m_sun_params = sun_params; } + + const SunParams &getSunParams() const { return m_sun_params; } + + void setMoon(const MoonParams &moon_params) { m_moon_params = moon_params; } + + const MoonParams &getMoonParams() const { return m_moon_params; } + + void setStars(const StarParams &star_params) { m_star_params = star_params; } + + const StarParams &getStarParams() const { return m_star_params; } + + void setCloudParams(const CloudParams &cloud_params) + { + m_cloud_params = cloud_params; + } + + const CloudParams &getCloudParams() const { return m_cloud_params; } + + bool checkModified() const { return m_dirty || inventory.checkModified(); } + + inline void setModified(const bool x) { m_dirty = x; } + + void setLocalAnimations(v2s32 frames[4], float frame_speed) + { + for (int i = 0; i < 4; i++) + local_animations[i] = frames[i]; + local_animation_speed = frame_speed; + } + + void getLocalAnimations(v2s32 *frames, float *frame_speed) + { + for (int i = 0; i < 4; i++) + frames[i] = local_animations[i]; + *frame_speed = local_animation_speed; + } + + void setLighting(const Lighting &lighting) { m_lighting = lighting; } + + const Lighting& getLighting() const { return m_lighting; } + + void setDirty(bool dirty) { m_dirty = true; } + + u16 protocol_version = 0; + u16 formspec_version = 0; + + session_t getPeerId() const { return m_peer_id; } + + void setPeerId(session_t peer_id) { m_peer_id = peer_id; } + + void onSuccessfulSave(); + +private: + PlayerSAO *m_sao = nullptr; + bool m_dirty = false; + + static bool m_setting_cache_loaded; + static float m_setting_chat_message_limit_per_10sec; + static u16 m_setting_chat_message_limit_trigger_kick; + + u32 m_last_chat_message_sent = std::time(0); + float m_chat_message_allowance = 5.0f; + u16 m_message_rate_overhead = 0; + + bool m_day_night_ratio_do_override = false; + float m_day_night_ratio; + std::string hud_hotbar_image = ""; + std::string hud_hotbar_selected_image = ""; + + CloudParams m_cloud_params; + + SkyboxParams m_skybox_params; + SunParams m_sun_params; + MoonParams m_moon_params; + StarParams m_star_params; + + Lighting m_lighting; + + session_t m_peer_id = PEER_ID_INEXISTENT; +}; diff --git a/src/rollback.cpp b/src/rollback.cpp new file mode 100644 index 0000000..b454e40 --- /dev/null +++ b/src/rollback.cpp @@ -0,0 +1,966 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "rollback.h" +#include <fstream> +#include <list> +#include <sstream> +#include "log.h" +#include "mapnode.h" +#include "gamedef.h" +#include "nodedef.h" +#include "util/serialize.h" +#include "util/string.h" +#include "util/numeric.h" +#include "inventorymanager.h" // deserializing InventoryLocations +#include "sqlite3.h" +#include "filesys.h" + +#define POINTS_PER_NODE (16.0) + +#define SQLRES(f, good) \ + if ((f) != (good)) {\ + throw FileNotGoodException(std::string("RollbackManager: " \ + "SQLite3 error (" __FILE__ ":" TOSTRING(__LINE__) \ + "): ") + sqlite3_errmsg(db)); \ + } +#define SQLOK(f) SQLRES(f, SQLITE_OK) + +#define SQLOK_ERRSTREAM(s, m) \ + if ((s) != SQLITE_OK) { \ + errorstream << "RollbackManager: " << (m) << ": " \ + << sqlite3_errmsg(db) << std::endl; \ + } + +#define FINALIZE_STATEMENT(statement) \ + SQLOK_ERRSTREAM(sqlite3_finalize(statement), "Failed to finalize " #statement) + +class ItemStackRow : public ItemStack { +public: + ItemStackRow & operator = (const ItemStack & other) + { + *static_cast<ItemStack *>(this) = other; + return *this; + } + + int id; +}; + +struct ActionRow { + int id; + int actor; + time_t timestamp; + int type; + std::string location, list; + int index, add; + ItemStackRow stack; + int nodeMeta; + int x, y, z; + int oldNode; + int oldParam1, oldParam2; + std::string oldMeta; + int newNode; + int newParam1, newParam2; + std::string newMeta; + int guessed; +}; + + +struct Entity { + int id; + std::string name; +}; + + + +RollbackManager::RollbackManager(const std::string & world_path, + IGameDef * gamedef_) : + gamedef(gamedef_) +{ + verbosestream << "RollbackManager::RollbackManager(" << world_path + << ")" << std::endl; + + std::string txt_filename = world_path + DIR_DELIM "rollback.txt"; + std::string migrating_flag = txt_filename + ".migrating"; + database_path = world_path + DIR_DELIM "rollback.sqlite"; + + bool created = initDatabase(); + + if (fs::PathExists(txt_filename) && (created || + fs::PathExists(migrating_flag))) { + std::ofstream of(migrating_flag.c_str()); + of.close(); + migrate(txt_filename); + fs::DeleteSingleFileOrEmptyDirectory(migrating_flag); + } +} + + +RollbackManager::~RollbackManager() +{ + flush(); + + FINALIZE_STATEMENT(stmt_insert); + FINALIZE_STATEMENT(stmt_replace); + FINALIZE_STATEMENT(stmt_select); + FINALIZE_STATEMENT(stmt_select_range); + FINALIZE_STATEMENT(stmt_select_withActor); + FINALIZE_STATEMENT(stmt_knownActor_select); + FINALIZE_STATEMENT(stmt_knownActor_insert); + FINALIZE_STATEMENT(stmt_knownNode_select); + FINALIZE_STATEMENT(stmt_knownNode_insert); + + SQLOK_ERRSTREAM(sqlite3_close(db), "Could not close db"); +} + + +void RollbackManager::registerNewActor(const int id, const std::string &name) +{ + Entity actor = {id, name}; + knownActors.push_back(actor); +} + + +void RollbackManager::registerNewNode(const int id, const std::string &name) +{ + Entity node = {id, name}; + knownNodes.push_back(node); +} + + +int RollbackManager::getActorId(const std::string &name) +{ + for (std::vector<Entity>::const_iterator iter = knownActors.begin(); + iter != knownActors.end(); ++iter) { + if (iter->name == name) { + return iter->id; + } + } + + SQLOK(sqlite3_bind_text(stmt_knownActor_insert, 1, name.c_str(), name.size(), NULL)); + SQLRES(sqlite3_step(stmt_knownActor_insert), SQLITE_DONE); + SQLOK(sqlite3_reset(stmt_knownActor_insert)); + + int id = sqlite3_last_insert_rowid(db); + registerNewActor(id, name); + + return id; +} + + +int RollbackManager::getNodeId(const std::string &name) +{ + for (std::vector<Entity>::const_iterator iter = knownNodes.begin(); + iter != knownNodes.end(); ++iter) { + if (iter->name == name) { + return iter->id; + } + } + + SQLOK(sqlite3_bind_text(stmt_knownNode_insert, 1, name.c_str(), name.size(), NULL)); + SQLRES(sqlite3_step(stmt_knownNode_insert), SQLITE_DONE); + SQLOK(sqlite3_reset(stmt_knownNode_insert)); + + int id = sqlite3_last_insert_rowid(db); + registerNewNode(id, name); + + return id; +} + + +const char * RollbackManager::getActorName(const int id) +{ + for (std::vector<Entity>::const_iterator iter = knownActors.begin(); + iter != knownActors.end(); ++iter) { + if (iter->id == id) { + return iter->name.c_str(); + } + } + + return ""; +} + + +const char * RollbackManager::getNodeName(const int id) +{ + for (std::vector<Entity>::const_iterator iter = knownNodes.begin(); + iter != knownNodes.end(); ++iter) { + if (iter->id == id) { + return iter->name.c_str(); + } + } + + return ""; +} + + +bool RollbackManager::createTables() +{ + SQLOK(sqlite3_exec(db, + "CREATE TABLE IF NOT EXISTS `actor` (\n" + " `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" + " `name` TEXT NOT NULL\n" + ");\n" + "CREATE TABLE IF NOT EXISTS `node` (\n" + " `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" + " `name` TEXT NOT NULL\n" + ");\n" + "CREATE TABLE IF NOT EXISTS `action` (\n" + " `id` INTEGER PRIMARY KEY AUTOINCREMENT,\n" + " `actor` INTEGER NOT NULL,\n" + " `timestamp` TIMESTAMP NOT NULL,\n" + " `type` INTEGER NOT NULL,\n" + " `list` TEXT,\n" + " `index` INTEGER,\n" + " `add` INTEGER,\n" + " `stackNode` INTEGER,\n" + " `stackQuantity` INTEGER,\n" + " `nodeMeta` INTEGER,\n" + " `x` INT,\n" + " `y` INT,\n" + " `z` INT,\n" + " `oldNode` INTEGER,\n" + " `oldParam1` INTEGER,\n" + " `oldParam2` INTEGER,\n" + " `oldMeta` TEXT,\n" + " `newNode` INTEGER,\n" + " `newParam1` INTEGER,\n" + " `newParam2` INTEGER,\n" + " `newMeta` TEXT,\n" + " `guessedActor` INTEGER,\n" + " FOREIGN KEY (`actor`) REFERENCES `actor`(`id`),\n" + " FOREIGN KEY (`stackNode`) REFERENCES `node`(`id`),\n" + " FOREIGN KEY (`oldNode`) REFERENCES `node`(`id`),\n" + " FOREIGN KEY (`newNode`) REFERENCES `node`(`id`)\n" + ");\n" + "CREATE INDEX IF NOT EXISTS `actionIndex` ON `action`(`x`,`y`,`z`,`timestamp`,`actor`);\n", + NULL, NULL, NULL)); + verbosestream << "SQL Rollback: SQLite3 database structure was created" << std::endl; + + return true; +} + + +bool RollbackManager::initDatabase() +{ + verbosestream << "RollbackManager: Database connection setup" << std::endl; + + bool needs_create = !fs::PathExists(database_path); + SQLOK(sqlite3_open_v2(database_path.c_str(), &db, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)); + + if (needs_create) { + createTables(); + } + + SQLOK(sqlite3_prepare_v2(db, + "INSERT INTO `action` (\n" + " `actor`, `timestamp`, `type`,\n" + " `list`, `index`, `add`, `stackNode`, `stackQuantity`, `nodeMeta`,\n" + " `x`, `y`, `z`,\n" + " `oldNode`, `oldParam1`, `oldParam2`, `oldMeta`,\n" + " `newNode`, `newParam1`, `newParam2`, `newMeta`,\n" + " `guessedActor`\n" + ") VALUES (\n" + " ?, ?, ?,\n" + " ?, ?, ?, ?, ?, ?,\n" + " ?, ?, ?,\n" + " ?, ?, ?, ?,\n" + " ?, ?, ?, ?,\n" + " ?" + ");", + -1, &stmt_insert, NULL)); + + SQLOK(sqlite3_prepare_v2(db, + "REPLACE INTO `action` (\n" + " `actor`, `timestamp`, `type`,\n" + " `list`, `index`, `add`, `stackNode`, `stackQuantity`, `nodeMeta`,\n" + " `x`, `y`, `z`,\n" + " `oldNode`, `oldParam1`, `oldParam2`, `oldMeta`,\n" + " `newNode`, `newParam1`, `newParam2`, `newMeta`,\n" + " `guessedActor`, `id`\n" + ") VALUES (\n" + " ?, ?, ?,\n" + " ?, ?, ?, ?, ?, ?,\n" + " ?, ?, ?,\n" + " ?, ?, ?, ?,\n" + " ?, ?, ?, ?,\n" + " ?, ?\n" + ");", + -1, &stmt_replace, NULL)); + + SQLOK(sqlite3_prepare_v2(db, + "SELECT\n" + " `actor`, `timestamp`, `type`,\n" + " `list`, `index`, `add`, `stackNode`, `stackQuantity`, `nodemeta`,\n" + " `x`, `y`, `z`,\n" + " `oldNode`, `oldParam1`, `oldParam2`, `oldMeta`,\n" + " `newNode`, `newParam1`, `newParam2`, `newMeta`,\n" + " `guessedActor`\n" + " FROM `action`\n" + " WHERE `timestamp` >= ?\n" + " ORDER BY `timestamp` DESC, `id` DESC", + -1, &stmt_select, NULL)); + + SQLOK(sqlite3_prepare_v2(db, + "SELECT\n" + " `actor`, `timestamp`, `type`,\n" + " `list`, `index`, `add`, `stackNode`, `stackQuantity`, `nodemeta`,\n" + " `x`, `y`, `z`,\n" + " `oldNode`, `oldParam1`, `oldParam2`, `oldMeta`,\n" + " `newNode`, `newParam1`, `newParam2`, `newMeta`,\n" + " `guessedActor`\n" + "FROM `action`\n" + "WHERE `timestamp` >= ?\n" + " AND `x` IS NOT NULL\n" + " AND `y` IS NOT NULL\n" + " AND `z` IS NOT NULL\n" + " AND `x` BETWEEN ? AND ?\n" + " AND `y` BETWEEN ? AND ?\n" + " AND `z` BETWEEN ? AND ?\n" + "ORDER BY `timestamp` DESC, `id` DESC\n" + "LIMIT 0,?", + -1, &stmt_select_range, NULL)); + + SQLOK(sqlite3_prepare_v2(db, + "SELECT\n" + " `actor`, `timestamp`, `type`,\n" + " `list`, `index`, `add`, `stackNode`, `stackQuantity`, `nodemeta`,\n" + " `x`, `y`, `z`,\n" + " `oldNode`, `oldParam1`, `oldParam2`, `oldMeta`,\n" + " `newNode`, `newParam1`, `newParam2`, `newMeta`,\n" + " `guessedActor`\n" + "FROM `action`\n" + "WHERE `timestamp` >= ?\n" + " AND `actor` = ?\n" + "ORDER BY `timestamp` DESC, `id` DESC\n", + -1, &stmt_select_withActor, NULL)); + + SQLOK(sqlite3_prepare_v2(db, "SELECT `id`, `name` FROM `actor`", + -1, &stmt_knownActor_select, NULL)); + + SQLOK(sqlite3_prepare_v2(db, "INSERT INTO `actor` (`name`) VALUES (?)", + -1, &stmt_knownActor_insert, NULL)); + + SQLOK(sqlite3_prepare_v2(db, "SELECT `id`, `name` FROM `node`", + -1, &stmt_knownNode_select, NULL)); + + SQLOK(sqlite3_prepare_v2(db, "INSERT INTO `node` (`name`) VALUES (?)", + -1, &stmt_knownNode_insert, NULL)); + + verbosestream << "SQL prepared statements setup correctly" << std::endl; + + while (sqlite3_step(stmt_knownActor_select) == SQLITE_ROW) { + registerNewActor( + sqlite3_column_int(stmt_knownActor_select, 0), + reinterpret_cast<const char *>(sqlite3_column_text(stmt_knownActor_select, 1)) + ); + } + SQLOK(sqlite3_reset(stmt_knownActor_select)); + + while (sqlite3_step(stmt_knownNode_select) == SQLITE_ROW) { + registerNewNode( + sqlite3_column_int(stmt_knownNode_select, 0), + reinterpret_cast<const char *>(sqlite3_column_text(stmt_knownNode_select, 1)) + ); + } + SQLOK(sqlite3_reset(stmt_knownNode_select)); + + return needs_create; +} + + +bool RollbackManager::registerRow(const ActionRow & row) +{ + sqlite3_stmt * stmt_do = (row.id) ? stmt_replace : stmt_insert; + + bool nodeMeta = false; + + SQLOK(sqlite3_bind_int (stmt_do, 1, row.actor)); + SQLOK(sqlite3_bind_int64(stmt_do, 2, row.timestamp)); + SQLOK(sqlite3_bind_int (stmt_do, 3, row.type)); + + if (row.type == RollbackAction::TYPE_MODIFY_INVENTORY_STACK) { + const std::string & loc = row.location; + nodeMeta = (loc.substr(0, 9) == "nodemeta:"); + + SQLOK(sqlite3_bind_text(stmt_do, 4, row.list.c_str(), row.list.size(), NULL)); + SQLOK(sqlite3_bind_int (stmt_do, 5, row.index)); + SQLOK(sqlite3_bind_int (stmt_do, 6, row.add)); + SQLOK(sqlite3_bind_int (stmt_do, 7, row.stack.id)); + SQLOK(sqlite3_bind_int (stmt_do, 8, row.stack.count)); + SQLOK(sqlite3_bind_int (stmt_do, 9, (int) nodeMeta)); + + if (nodeMeta) { + std::string::size_type p1, p2; + p1 = loc.find(':') + 1; + p2 = loc.find(','); + std::string x = loc.substr(p1, p2 - p1); + p1 = p2 + 1; + p2 = loc.find(',', p1); + std::string y = loc.substr(p1, p2 - p1); + std::string z = loc.substr(p2 + 1); + SQLOK(sqlite3_bind_int(stmt_do, 10, atoi(x.c_str()))); + SQLOK(sqlite3_bind_int(stmt_do, 11, atoi(y.c_str()))); + SQLOK(sqlite3_bind_int(stmt_do, 12, atoi(z.c_str()))); + } + } else { + SQLOK(sqlite3_bind_null(stmt_do, 4)); + SQLOK(sqlite3_bind_null(stmt_do, 5)); + SQLOK(sqlite3_bind_null(stmt_do, 6)); + SQLOK(sqlite3_bind_null(stmt_do, 7)); + SQLOK(sqlite3_bind_null(stmt_do, 8)); + SQLOK(sqlite3_bind_null(stmt_do, 9)); + } + + if (row.type == RollbackAction::TYPE_SET_NODE) { + SQLOK(sqlite3_bind_int (stmt_do, 10, row.x)); + SQLOK(sqlite3_bind_int (stmt_do, 11, row.y)); + SQLOK(sqlite3_bind_int (stmt_do, 12, row.z)); + SQLOK(sqlite3_bind_int (stmt_do, 13, row.oldNode)); + SQLOK(sqlite3_bind_int (stmt_do, 14, row.oldParam1)); + SQLOK(sqlite3_bind_int (stmt_do, 15, row.oldParam2)); + SQLOK(sqlite3_bind_text(stmt_do, 16, row.oldMeta.c_str(), row.oldMeta.size(), NULL)); + SQLOK(sqlite3_bind_int (stmt_do, 17, row.newNode)); + SQLOK(sqlite3_bind_int (stmt_do, 18, row.newParam1)); + SQLOK(sqlite3_bind_int (stmt_do, 19, row.newParam2)); + SQLOK(sqlite3_bind_text(stmt_do, 20, row.newMeta.c_str(), row.newMeta.size(), NULL)); + SQLOK(sqlite3_bind_int (stmt_do, 21, row.guessed ? 1 : 0)); + } else { + if (!nodeMeta) { + SQLOK(sqlite3_bind_null(stmt_do, 10)); + SQLOK(sqlite3_bind_null(stmt_do, 11)); + SQLOK(sqlite3_bind_null(stmt_do, 12)); + } + SQLOK(sqlite3_bind_null(stmt_do, 13)); + SQLOK(sqlite3_bind_null(stmt_do, 14)); + SQLOK(sqlite3_bind_null(stmt_do, 15)); + SQLOK(sqlite3_bind_null(stmt_do, 16)); + SQLOK(sqlite3_bind_null(stmt_do, 17)); + SQLOK(sqlite3_bind_null(stmt_do, 18)); + SQLOK(sqlite3_bind_null(stmt_do, 19)); + SQLOK(sqlite3_bind_null(stmt_do, 20)); + SQLOK(sqlite3_bind_null(stmt_do, 21)); + } + + if (row.id) { + SQLOK(sqlite3_bind_int(stmt_do, 22, row.id)); + } + + int written = sqlite3_step(stmt_do); + + SQLOK(sqlite3_reset(stmt_do)); + + return written == SQLITE_DONE; +} + + +const std::list<ActionRow> RollbackManager::actionRowsFromSelect(sqlite3_stmt* stmt) +{ + std::list<ActionRow> rows; + const unsigned char * text; + size_t size; + + while (sqlite3_step(stmt) == SQLITE_ROW) { + ActionRow row; + + row.actor = sqlite3_column_int (stmt, 0); + row.timestamp = sqlite3_column_int64(stmt, 1); + row.type = sqlite3_column_int (stmt, 2); + row.nodeMeta = 0; + + if (row.type == RollbackAction::TYPE_MODIFY_INVENTORY_STACK) { + text = sqlite3_column_text (stmt, 3); + size = sqlite3_column_bytes(stmt, 3); + row.list = std::string(reinterpret_cast<const char*>(text), size); + row.index = sqlite3_column_int(stmt, 4); + row.add = sqlite3_column_int(stmt, 5); + row.stack.id = sqlite3_column_int(stmt, 6); + row.stack.count = sqlite3_column_int(stmt, 7); + row.nodeMeta = sqlite3_column_int(stmt, 8); + } + + if (row.type == RollbackAction::TYPE_SET_NODE || row.nodeMeta) { + row.x = sqlite3_column_int(stmt, 9); + row.y = sqlite3_column_int(stmt, 10); + row.z = sqlite3_column_int(stmt, 11); + } + + if (row.type == RollbackAction::TYPE_SET_NODE) { + row.oldNode = sqlite3_column_int(stmt, 12); + row.oldParam1 = sqlite3_column_int(stmt, 13); + row.oldParam2 = sqlite3_column_int(stmt, 14); + text = sqlite3_column_text (stmt, 15); + size = sqlite3_column_bytes(stmt, 15); + row.oldMeta = std::string(reinterpret_cast<const char*>(text), size); + row.newNode = sqlite3_column_int(stmt, 16); + row.newParam1 = sqlite3_column_int(stmt, 17); + row.newParam2 = sqlite3_column_int(stmt, 18); + text = sqlite3_column_text(stmt, 19); + size = sqlite3_column_bytes(stmt, 19); + row.newMeta = std::string(reinterpret_cast<const char*>(text), size); + row.guessed = sqlite3_column_int(stmt, 20); + } + + if (row.nodeMeta) { + row.location = "nodemeta:"; + row.location += itos(row.x); + row.location += ','; + row.location += itos(row.y); + row.location += ','; + row.location += itos(row.z); + } else { + row.location = getActorName(row.actor); + } + + rows.push_back(row); + } + + SQLOK(sqlite3_reset(stmt)); + + return rows; +} + + +ActionRow RollbackManager::actionRowFromRollbackAction(const RollbackAction & action) +{ + ActionRow row; + + row.id = 0; + row.actor = getActorId(action.actor); + row.timestamp = action.unix_time; + row.type = action.type; + + if (row.type == RollbackAction::TYPE_MODIFY_INVENTORY_STACK) { + row.location = action.inventory_location; + row.list = action.inventory_list; + row.index = action.inventory_index; + row.add = action.inventory_add; + row.stack = action.inventory_stack; + row.stack.id = getNodeId(row.stack.name); + } else { + row.x = action.p.X; + row.y = action.p.Y; + row.z = action.p.Z; + row.oldNode = getNodeId(action.n_old.name); + row.oldParam1 = action.n_old.param1; + row.oldParam2 = action.n_old.param2; + row.oldMeta = action.n_old.meta; + row.newNode = getNodeId(action.n_new.name); + row.newParam1 = action.n_new.param1; + row.newParam2 = action.n_new.param2; + row.newMeta = action.n_new.meta; + row.guessed = action.actor_is_guess; + } + + return row; +} + + +const std::list<RollbackAction> RollbackManager::rollbackActionsFromActionRows( + const std::list<ActionRow> & rows) +{ + std::list<RollbackAction> actions; + + for (const ActionRow &row : rows) { + RollbackAction action; + action.actor = (row.actor) ? getActorName(row.actor) : ""; + action.unix_time = row.timestamp; + action.type = static_cast<RollbackAction::Type>(row.type); + + switch (action.type) { + case RollbackAction::TYPE_MODIFY_INVENTORY_STACK: + action.inventory_location = row.location; + action.inventory_list = row.list; + action.inventory_index = row.index; + action.inventory_add = row.add; + action.inventory_stack = row.stack; + if (action.inventory_stack.name.empty()) { + action.inventory_stack.name = getNodeName(row.stack.id); + } + break; + + case RollbackAction::TYPE_SET_NODE: + action.p = v3s16(row.x, row.y, row.z); + action.n_old.name = getNodeName(row.oldNode); + action.n_old.param1 = row.oldParam1; + action.n_old.param2 = row.oldParam2; + action.n_old.meta = row.oldMeta; + action.n_new.name = getNodeName(row.newNode); + action.n_new.param1 = row.newParam1; + action.n_new.param2 = row.newParam2; + action.n_new.meta = row.newMeta; + break; + + default: + throw ("W.T.F."); + break; + } + + actions.push_back(action); + } + + return actions; +} + + +const std::list<ActionRow> RollbackManager::getRowsSince(time_t firstTime, const std::string & actor) +{ + sqlite3_stmt *stmt_stmt = actor.empty() ? stmt_select : stmt_select_withActor; + sqlite3_bind_int64(stmt_stmt, 1, firstTime); + + if (!actor.empty()) { + sqlite3_bind_int(stmt_stmt, 2, getActorId(actor)); + } + + const std::list<ActionRow> & rows = actionRowsFromSelect(stmt_stmt); + sqlite3_reset(stmt_stmt); + + return rows; +} + + +const std::list<ActionRow> RollbackManager::getRowsSince_range( + time_t start_time, v3s16 p, int range, int limit) +{ + + sqlite3_bind_int64(stmt_select_range, 1, start_time); + sqlite3_bind_int (stmt_select_range, 2, static_cast<int>(p.X - range)); + sqlite3_bind_int (stmt_select_range, 3, static_cast<int>(p.X + range)); + sqlite3_bind_int (stmt_select_range, 4, static_cast<int>(p.Y - range)); + sqlite3_bind_int (stmt_select_range, 5, static_cast<int>(p.Y + range)); + sqlite3_bind_int (stmt_select_range, 6, static_cast<int>(p.Z - range)); + sqlite3_bind_int (stmt_select_range, 7, static_cast<int>(p.Z + range)); + sqlite3_bind_int (stmt_select_range, 8, limit); + + const std::list<ActionRow> & rows = actionRowsFromSelect(stmt_select_range); + sqlite3_reset(stmt_select_range); + + return rows; +} + + +const std::list<RollbackAction> RollbackManager::getActionsSince_range( + time_t start_time, v3s16 p, int range, int limit) +{ + return rollbackActionsFromActionRows(getRowsSince_range(start_time, p, range, limit)); +} + + +const std::list<RollbackAction> RollbackManager::getActionsSince( + time_t start_time, const std::string & actor) +{ + return rollbackActionsFromActionRows(getRowsSince(start_time, actor)); +} + + +void RollbackManager::migrate(const std::string & file_path) +{ + std::cout << "Migrating from rollback.txt to rollback.sqlite." << std::endl; + + std::ifstream fh(file_path.c_str(), std::ios::in | std::ios::ate); + if (!fh.good()) { + throw FileNotGoodException("Unable to open rollback.txt"); + } + + std::streampos file_size = fh.tellg(); + + if (file_size < 10) { + errorstream << "Empty rollback log." << std::endl; + return; + } + + fh.seekg(0); + + sqlite3_stmt *stmt_begin; + sqlite3_stmt *stmt_commit; + SQLOK(sqlite3_prepare_v2(db, "BEGIN", -1, &stmt_begin, NULL)); + SQLOK(sqlite3_prepare_v2(db, "COMMIT", -1, &stmt_commit, NULL)); + + std::string bit; + int i = 0; + time_t start = time(0); + time_t t = start; + SQLRES(sqlite3_step(stmt_begin), SQLITE_DONE); + sqlite3_reset(stmt_begin); + do { + ActionRow row; + row.id = 0; + + // Get the timestamp + std::getline(fh, bit, ' '); + bit = trim(bit); + if (!atoi(bit.c_str())) { + std::getline(fh, bit); + continue; + } + row.timestamp = atoi(bit.c_str()); + + // Get the actor + row.actor = getActorId(deSerializeJsonString(fh)); + + // Get the action type + std::getline(fh, bit, '['); + std::getline(fh, bit, ' '); + + if (bit == "modify_inventory_stack") { + row.type = RollbackAction::TYPE_MODIFY_INVENTORY_STACK; + row.location = trim(deSerializeJsonString(fh)); + std::getline(fh, bit, ' '); + row.list = trim(deSerializeJsonString(fh)); + std::getline(fh, bit, ' '); + std::getline(fh, bit, ' '); + row.index = atoi(trim(bit).c_str()); + std::getline(fh, bit, ' '); + row.add = (int)(trim(bit) == "add"); + row.stack.deSerialize(deSerializeJsonString(fh)); + row.stack.id = getNodeId(row.stack.name); + std::getline(fh, bit); + } else if (bit == "set_node") { + row.type = RollbackAction::TYPE_SET_NODE; + std::getline(fh, bit, '('); + std::getline(fh, bit, ','); + row.x = atoi(trim(bit).c_str()); + std::getline(fh, bit, ','); + row.y = atoi(trim(bit).c_str()); + std::getline(fh, bit, ')'); + row.z = atoi(trim(bit).c_str()); + std::getline(fh, bit, ' '); + row.oldNode = getNodeId(trim(deSerializeJsonString(fh))); + std::getline(fh, bit, ' '); + std::getline(fh, bit, ' '); + row.oldParam1 = atoi(trim(bit).c_str()); + std::getline(fh, bit, ' '); + row.oldParam2 = atoi(trim(bit).c_str()); + row.oldMeta = trim(deSerializeJsonString(fh)); + std::getline(fh, bit, ' '); + row.newNode = getNodeId(trim(deSerializeJsonString(fh))); + std::getline(fh, bit, ' '); + std::getline(fh, bit, ' '); + row.newParam1 = atoi(trim(bit).c_str()); + std::getline(fh, bit, ' '); + row.newParam2 = atoi(trim(bit).c_str()); + row.newMeta = trim(deSerializeJsonString(fh)); + std::getline(fh, bit, ' '); + std::getline(fh, bit, ' '); + std::getline(fh, bit); + row.guessed = (int)(trim(bit) == "actor_is_guess"); + } else { + errorstream << "Unrecognized rollback action type \"" + << bit << "\"!" << std::endl; + continue; + } + + registerRow(row); + ++i; + + if (time(0) - t >= 1) { + SQLRES(sqlite3_step(stmt_commit), SQLITE_DONE); + sqlite3_reset(stmt_commit); + t = time(0); + std::cout + << " Done: " << static_cast<int>((static_cast<float>(fh.tellg()) / static_cast<float>(file_size)) * 100) << "%" + << " Speed: " << i / (t - start) << "/second \r" << std::flush; + SQLRES(sqlite3_step(stmt_begin), SQLITE_DONE); + sqlite3_reset(stmt_begin); + } + } while (fh.good()); + SQLRES(sqlite3_step(stmt_commit), SQLITE_DONE); + sqlite3_reset(stmt_commit); + + SQLOK(sqlite3_finalize(stmt_begin)); + SQLOK(sqlite3_finalize(stmt_commit)); + + std::cout + << " Done: 100% " << std::endl + << "Now you can delete the old rollback.txt file." << std::endl; +} + + +// Get nearness factor for subject's action for this action +// Return value: 0 = impossible, >0 = factor +float RollbackManager::getSuspectNearness(bool is_guess, v3s16 suspect_p, + time_t suspect_t, v3s16 action_p, time_t action_t) +{ + // Suspect cannot cause things in the past + if (action_t < suspect_t) { + return 0; // 0 = cannot be + } + // Start from 100 + int f = 100; + // Distance (1 node = -x points) + f -= POINTS_PER_NODE * intToFloat(suspect_p, 1).getDistanceFrom(intToFloat(action_p, 1)); + // Time (1 second = -x points) + f -= 1 * (action_t - suspect_t); + // If is a guess, halve the points + if (is_guess) { + f *= 0.5; + } + // Limit to 0 + if (f < 0) { + f = 0; + } + return f; +} + + +void RollbackManager::reportAction(const RollbackAction &action_) +{ + // Ignore if not important + if (!action_.isImportant(gamedef)) { + return; + } + + RollbackAction action = action_; + action.unix_time = time(0); + + // Figure out actor + action.actor = current_actor; + action.actor_is_guess = current_actor_is_guess; + + if (action.actor.empty()) { // If actor is not known, find out suspect or cancel + v3s16 p; + if (!action.getPosition(&p)) { + return; + } + + action.actor = getSuspect(p, 83, 1); + if (action.actor.empty()) { + return; + } + + action.actor_is_guess = true; + } + + addAction(action); +} + +std::string RollbackManager::getActor() +{ + return current_actor; +} + +bool RollbackManager::isActorGuess() +{ + return current_actor_is_guess; +} + +void RollbackManager::setActor(const std::string & actor, bool is_guess) +{ + current_actor = actor; + current_actor_is_guess = is_guess; +} + +std::string RollbackManager::getSuspect(v3s16 p, float nearness_shortcut, + float min_nearness) +{ + if (!current_actor.empty()) { + return current_actor; + } + int cur_time = time(0); + time_t first_time = cur_time - (100 - min_nearness); + RollbackAction likely_suspect; + float likely_suspect_nearness = 0; + for (std::list<RollbackAction>::const_reverse_iterator + i = action_latest_buffer.rbegin(); + i != action_latest_buffer.rend(); ++i) { + if (i->unix_time < first_time) { + break; + } + if (i->actor.empty()) { + continue; + } + // Find position of suspect or continue + v3s16 suspect_p; + if (!i->getPosition(&suspect_p)) { + continue; + } + float f = getSuspectNearness(i->actor_is_guess, suspect_p, + i->unix_time, p, cur_time); + if (f >= min_nearness && f > likely_suspect_nearness) { + likely_suspect_nearness = f; + likely_suspect = *i; + if (likely_suspect_nearness >= nearness_shortcut) { + break; + } + } + } + // No likely suspect was found + if (likely_suspect_nearness == 0) { + return ""; + } + // Likely suspect was found + return likely_suspect.actor; +} + + +void RollbackManager::flush() +{ + sqlite3_exec(db, "BEGIN", NULL, NULL, NULL); + + std::list<RollbackAction>::const_iterator iter; + + for (iter = action_todisk_buffer.begin(); + iter != action_todisk_buffer.end(); + ++iter) { + if (iter->actor.empty()) { + continue; + } + + registerRow(actionRowFromRollbackAction(*iter)); + } + + sqlite3_exec(db, "COMMIT", NULL, NULL, NULL); + action_todisk_buffer.clear(); +} + + +void RollbackManager::addAction(const RollbackAction & action) +{ + action_todisk_buffer.push_back(action); + action_latest_buffer.push_back(action); + + // Flush to disk sometimes + if (action_todisk_buffer.size() >= 500) { + flush(); + } +} + +std::list<RollbackAction> RollbackManager::getNodeActors(v3s16 pos, int range, + time_t seconds, int limit) +{ + flush(); + time_t cur_time = time(0); + time_t first_time = cur_time - seconds; + + return getActionsSince_range(first_time, pos, range, limit); +} + +std::list<RollbackAction> RollbackManager::getRevertActions( + const std::string &actor_filter, + time_t seconds) +{ + time_t cur_time = time(0); + time_t first_time = cur_time - seconds; + + flush(); + + return getActionsSince(first_time, actor_filter); +} + diff --git a/src/rollback.h b/src/rollback.h new file mode 100644 index 0000000..ff96e51 --- /dev/null +++ b/src/rollback.h @@ -0,0 +1,103 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include "irr_v3d.h" +#include "rollback_interface.h" +#include <list> +#include <vector> +#include "sqlite3.h" + +class IGameDef; + +struct ActionRow; +struct Entity; + +class RollbackManager: public IRollbackManager +{ +public: + RollbackManager(const std::string & world_path, IGameDef * gamedef); + ~RollbackManager(); + + void reportAction(const RollbackAction & action_); + std::string getActor(); + bool isActorGuess(); + void setActor(const std::string & actor, bool is_guess); + std::string getSuspect(v3s16 p, float nearness_shortcut, + float min_nearness); + void flush(); + + void addAction(const RollbackAction & action); + std::list<RollbackAction> getNodeActors(v3s16 pos, int range, + time_t seconds, int limit); + std::list<RollbackAction> getRevertActions( + const std::string & actor_filter, time_t seconds); + +private: + void registerNewActor(const int id, const std::string & name); + void registerNewNode(const int id, const std::string & name); + int getActorId(const std::string & name); + int getNodeId(const std::string & name); + const char * getActorName(const int id); + const char * getNodeName(const int id); + bool createTables(); + bool initDatabase(); + bool registerRow(const ActionRow & row); + const std::list<ActionRow> actionRowsFromSelect(sqlite3_stmt * stmt); + ActionRow actionRowFromRollbackAction(const RollbackAction & action); + const std::list<RollbackAction> rollbackActionsFromActionRows( + const std::list<ActionRow> & rows); + const std::list<ActionRow> getRowsSince(time_t firstTime, + const std::string & actor); + const std::list<ActionRow> getRowsSince_range(time_t firstTime, v3s16 p, + int range, int limit); + const std::list<RollbackAction> getActionsSince_range(time_t firstTime, v3s16 p, + int range, int limit); + const std::list<RollbackAction> getActionsSince(time_t firstTime, + const std::string & actor = ""); + void migrate(const std::string & filepath); + static float getSuspectNearness(bool is_guess, v3s16 suspect_p, + time_t suspect_t, v3s16 action_p, time_t action_t); + + + IGameDef *gamedef = nullptr; + + std::string current_actor; + bool current_actor_is_guess = false; + + std::list<RollbackAction> action_todisk_buffer; + std::list<RollbackAction> action_latest_buffer; + + std::string database_path; + sqlite3 * db; + sqlite3_stmt * stmt_insert; + sqlite3_stmt * stmt_replace; + sqlite3_stmt * stmt_select; + sqlite3_stmt * stmt_select_range; + sqlite3_stmt * stmt_select_withActor; + sqlite3_stmt * stmt_knownActor_select; + sqlite3_stmt * stmt_knownActor_insert; + sqlite3_stmt * stmt_knownNode_select; + sqlite3_stmt * stmt_knownNode_insert; + + std::vector<Entity> knownActors; + std::vector<Entity> knownNodes; +}; diff --git a/src/rollback_interface.cpp b/src/rollback_interface.cpp new file mode 100644 index 0000000..c00206e --- /dev/null +++ b/src/rollback_interface.cpp @@ -0,0 +1,236 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "rollback_interface.h" +#include <sstream> +#include "util/serialize.h" +#include "util/string.h" +#include "util/numeric.h" +#include "util/basic_macros.h" +#include "map.h" +#include "gamedef.h" +#include "nodedef.h" +#include "nodemetadata.h" +#include "exceptions.h" +#include "log.h" +#include "inventorymanager.h" +#include "inventory.h" +#include "mapblock.h" + + +RollbackNode::RollbackNode(Map *map, v3s16 p, IGameDef *gamedef) +{ + const NodeDefManager *ndef = gamedef->ndef(); + MapNode n = map->getNode(p); + name = ndef->get(n).name; + param1 = n.param1; + param2 = n.param2; + NodeMetadata *metap = map->getNodeMetadata(p); + if (metap) { + std::ostringstream os(std::ios::binary); + metap->serialize(os, 1); // FIXME: version bump?? + meta = os.str(); + } +} + + +std::string RollbackAction::toString() const +{ + std::ostringstream os(std::ios::binary); + switch (type) { + case TYPE_SET_NODE: + os << "set_node " << PP(p); + os << ": (" << serializeJsonString(n_old.name); + os << ", " << itos(n_old.param1); + os << ", " << itos(n_old.param2); + os << ", " << serializeJsonString(n_old.meta); + os << ") -> (" << serializeJsonString(n_new.name); + os << ", " << itos(n_new.param1); + os << ", " << itos(n_new.param2); + os << ", " << serializeJsonString(n_new.meta); + os << ')'; + case TYPE_MODIFY_INVENTORY_STACK: + os << "modify_inventory_stack ("; + os << serializeJsonString(inventory_location); + os << ", " << serializeJsonString(inventory_list); + os << ", " << inventory_index; + os << ", " << (inventory_add ? "add" : "remove"); + os << ", " << serializeJsonString(inventory_stack.getItemString()); + os << ')'; + default: + return "<unknown action>"; + } + return os.str(); +} + + +bool RollbackAction::isImportant(IGameDef *gamedef) const +{ + if (type != TYPE_SET_NODE) + return true; + // If names differ, action is always important + if(n_old.name != n_new.name) + return true; + // If metadata differs, action is always important + if(n_old.meta != n_new.meta) + return true; + const NodeDefManager *ndef = gamedef->ndef(); + // Both are of the same name, so a single definition is needed + const ContentFeatures &def = ndef->get(n_old.name); + // If the type is flowing liquid, action is not important + if (def.liquid_type == LIQUID_FLOWING) + return false; + // Otherwise action is important + return true; +} + + +bool RollbackAction::getPosition(v3s16 *dst) const +{ + switch (type) { + case TYPE_SET_NODE: + if (dst) *dst = p; + return true; + case TYPE_MODIFY_INVENTORY_STACK: { + InventoryLocation loc; + loc.deSerialize(inventory_location); + if (loc.type != InventoryLocation::NODEMETA) { + return false; + } + if (dst) *dst = loc.p; + return true; } + default: + return false; + } +} + + +bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gamedef) const +{ + try { + switch (type) { + case TYPE_NOTHING: + return true; + case TYPE_SET_NODE: { + const NodeDefManager *ndef = gamedef->ndef(); + // Make sure position is loaded from disk + map->emergeBlock(getContainerPos(p, MAP_BLOCKSIZE), false); + // Check current node + MapNode current_node = map->getNode(p); + std::string current_name = ndef->get(current_node).name; + // If current node not the new node, it's bad + if (current_name != n_new.name) { + return false; + } + // Create rollback node + content_t id = CONTENT_IGNORE; + if (!ndef->getId(n_old.name, id)) { + // The old node is not registered + return false; + } + MapNode n(id, n_old.param1, n_old.param2); + // Set rollback node + try { + if (!map->addNodeWithEvent(p, n)) { + infostream << "RollbackAction::applyRevert(): " + << "AddNodeWithEvent failed at " + << PP(p) << " for " << n_old.name + << std::endl; + return false; + } + if (n_old.meta.empty()) { + map->removeNodeMetadata(p); + } else { + NodeMetadata *meta = map->getNodeMetadata(p); + if (!meta) { + meta = new NodeMetadata(gamedef->idef()); + if (!map->setNodeMetadata(p, meta)) { + delete meta; + infostream << "RollbackAction::applyRevert(): " + << "setNodeMetadata failed at " + << PP(p) << " for " << n_old.name + << std::endl; + return false; + } + } + std::istringstream is(n_old.meta, std::ios::binary); + meta->deSerialize(is, 1); // FIXME: version bump?? + } + // Inform other things that the meta data has changed + MapEditEvent event; + event.type = MEET_BLOCK_NODE_METADATA_CHANGED; + event.p = p; + map->dispatchEvent(event); + } catch (InvalidPositionException &e) { + infostream << "RollbackAction::applyRevert(): " + << "InvalidPositionException: " << e.what() + << std::endl; + return false; + } + // Success + return true; } + case TYPE_MODIFY_INVENTORY_STACK: { + InventoryLocation loc; + loc.deSerialize(inventory_location); + Inventory *inv = imgr->getInventory(loc); + if (!inv) { + infostream << "RollbackAction::applyRevert(): Could not get " + "inventory at " << inventory_location << std::endl; + return false; + } + InventoryList *list = inv->getList(inventory_list); + if (!list) { + infostream << "RollbackAction::applyRevert(): Could not get " + "inventory list \"" << inventory_list << "\" in " + << inventory_location << std::endl; + return false; + } + if (list->getSize() <= inventory_index) { + infostream << "RollbackAction::applyRevert(): List index " + << inventory_index << " too large in " + << "inventory list \"" << inventory_list << "\" in " + << inventory_location << std::endl; + return false; + } + + // If item was added, take away item, otherwise add removed item + if (inventory_add) { + // Silently ignore different current item + if (list->getItem(inventory_index).name != + gamedef->idef()->getAlias(inventory_stack.name)) + return false; + list->takeItem(inventory_index, inventory_stack.count); + } else { + list->addItem(inventory_index, inventory_stack); + } + // Inventory was modified; send to clients + imgr->setInventoryModified(loc); + return true; } + default: + errorstream << "RollbackAction::applyRevert(): type not handled" + << std::endl; + return false; + } + } catch(SerializationError &e) { + errorstream << "RollbackAction::applyRevert(): n_old.name=" << n_old.name + << ", SerializationError: " << e.what() << std::endl; + } + return false; +} + diff --git a/src/rollback_interface.h b/src/rollback_interface.h new file mode 100644 index 0000000..94b8005 --- /dev/null +++ b/src/rollback_interface.h @@ -0,0 +1,157 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_v3d.h" +#include <string> +#include <iostream> +#include <list> +#include "exceptions.h" +#include "inventory.h" + +class Map; +class IGameDef; +struct MapNode; +class InventoryManager; + +struct RollbackNode +{ + std::string name; + int param1 = 0; + int param2 = 0; + std::string meta; + + bool operator == (const RollbackNode &other) + { + return (name == other.name && param1 == other.param1 && + param2 == other.param2 && meta == other.meta); + } + bool operator != (const RollbackNode &other) { return !(*this == other); } + + RollbackNode() = default; + + RollbackNode(Map *map, v3s16 p, IGameDef *gamedef); +}; + + +struct RollbackAction +{ + enum Type{ + TYPE_NOTHING, + TYPE_SET_NODE, + TYPE_MODIFY_INVENTORY_STACK, + } type = TYPE_NOTHING; + + time_t unix_time = 0; + std::string actor; + bool actor_is_guess = false; + + v3s16 p; + RollbackNode n_old; + RollbackNode n_new; + + std::string inventory_location; + std::string inventory_list; + u32 inventory_index; + bool inventory_add; + ItemStack inventory_stack; + + RollbackAction() = default; + + void setSetNode(v3s16 p_, const RollbackNode &n_old_, + const RollbackNode &n_new_) + { + type = TYPE_SET_NODE; + p = p_; + n_old = n_old_; + n_new = n_new_; + } + + void setModifyInventoryStack(const std::string &inventory_location_, + const std::string &inventory_list_, u32 index_, + bool add_, const ItemStack &inventory_stack_) + { + type = TYPE_MODIFY_INVENTORY_STACK; + inventory_location = inventory_location_; + inventory_list = inventory_list_; + inventory_index = index_; + inventory_add = add_; + inventory_stack = inventory_stack_; + } + + // String should not contain newlines or nulls + std::string toString() const; + + // Eg. flowing water level changes are not important + bool isImportant(IGameDef *gamedef) const; + + bool getPosition(v3s16 *dst) const; + + bool applyRevert(Map *map, InventoryManager *imgr, IGameDef *gamedef) const; +}; + + +class IRollbackManager +{ +public: + virtual void reportAction(const RollbackAction &action) = 0; + virtual std::string getActor() = 0; + virtual bool isActorGuess() = 0; + virtual void setActor(const std::string &actor, bool is_guess) = 0; + virtual std::string getSuspect(v3s16 p, float nearness_shortcut, + float min_nearness) = 0; + + virtual ~IRollbackManager() = default;; + virtual void flush() = 0; + // Get all actors that did something to position p, but not further than + // <seconds> in history + virtual std::list<RollbackAction> getNodeActors(v3s16 pos, int range, + time_t seconds, int limit) = 0; + // Get actions to revert <seconds> of history made by <actor> + virtual std::list<RollbackAction> getRevertActions(const std::string &actor, + time_t seconds) = 0; +}; + + +class RollbackScopeActor +{ +public: + RollbackScopeActor(IRollbackManager * rollback_, + const std::string & actor, bool is_guess = false) : + rollback(rollback_) + { + if (rollback) { + old_actor = rollback->getActor(); + old_actor_guess = rollback->isActorGuess(); + rollback->setActor(actor, is_guess); + } + } + ~RollbackScopeActor() + { + if (rollback) { + rollback->setActor(old_actor, old_actor_guess); + } + } + +private: + IRollbackManager * rollback; + std::string old_actor; + bool old_actor_guess; +}; diff --git a/src/script/CMakeLists.txt b/src/script/CMakeLists.txt new file mode 100644 index 0000000..bebe2f0 --- /dev/null +++ b/src/script/CMakeLists.txt @@ -0,0 +1,21 @@ +add_subdirectory(common) +add_subdirectory(cpp_api) +add_subdirectory(lua_api) + +# Used by server and client +set(common_SCRIPT_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/scripting_server.cpp + ${common_SCRIPT_COMMON_SRCS} + ${common_SCRIPT_CPP_API_SRCS} + ${common_SCRIPT_LUA_API_SRCS} + PARENT_SCOPE) + +# Used by client only +set(client_SCRIPT_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/scripting_mainmenu.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/scripting_client.cpp + ${client_SCRIPT_COMMON_SRCS} + ${client_SCRIPT_CPP_API_SRCS} + ${client_SCRIPT_LUA_API_SRCS} + PARENT_SCOPE) + diff --git a/src/script/common/CMakeLists.txt b/src/script/common/CMakeLists.txt new file mode 100644 index 0000000..3e84b46 --- /dev/null +++ b/src/script/common/CMakeLists.txt @@ -0,0 +1,12 @@ +set(common_SCRIPT_COMMON_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/c_content.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/c_converter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/c_types.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/c_internal.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/c_packer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/helper.cpp + PARENT_SCOPE) + +set(client_SCRIPT_COMMON_SRCS + PARENT_SCOPE) + diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp new file mode 100644 index 0000000..fafb2ed --- /dev/null +++ b/src/script/common/c_content.cpp @@ -0,0 +1,2180 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "common/c_content.h" +#include "common/c_converter.h" +#include "common/c_types.h" +#include "nodedef.h" +#include "object_properties.h" +#include "collision.h" +#include "cpp_api/s_node.h" +#include "lua_api/l_object.h" +#include "lua_api/l_item.h" +#include "common/c_internal.h" +#include "server.h" +#include "log.h" +#include "tool.h" +#include "porting.h" +#include "mapgen/mg_schematic.h" +#include "noise.h" +#include "server/player_sao.h" +#include "util/pointedthing.h" +#include "debug.h" // For FATAL_ERROR +#include <json/json.h> + +struct EnumString es_TileAnimationType[] = +{ + {TAT_NONE, "none"}, + {TAT_VERTICAL_FRAMES, "vertical_frames"}, + {TAT_SHEET_2D, "sheet_2d"}, + {0, nullptr}, +}; + +/******************************************************************************/ +void read_item_definition(lua_State* L, int index, + const ItemDefinition &default_def, ItemDefinition &def) +{ + if (index < 0) + index = lua_gettop(L) + 1 + index; + + def.type = (ItemType)getenumfield(L, index, "type", + es_ItemType, ITEM_NONE); + getstringfield(L, index, "name", def.name); + getstringfield(L, index, "description", def.description); + getstringfield(L, index, "short_description", def.short_description); + getstringfield(L, index, "inventory_image", def.inventory_image); + getstringfield(L, index, "inventory_overlay", def.inventory_overlay); + getstringfield(L, index, "wield_image", def.wield_image); + getstringfield(L, index, "wield_overlay", def.wield_overlay); + getstringfield(L, index, "palette", def.palette_image); + + // Read item color. + lua_getfield(L, index, "color"); + read_color(L, -1, &def.color); + lua_pop(L, 1); + + lua_getfield(L, index, "wield_scale"); + if(lua_istable(L, -1)){ + def.wield_scale = check_v3f(L, -1); + } + lua_pop(L, 1); + + int stack_max = getintfield_default(L, index, "stack_max", def.stack_max); + def.stack_max = rangelim(stack_max, 1, U16_MAX); + + lua_getfield(L, index, "on_use"); + def.usable = lua_isfunction(L, -1); + lua_pop(L, 1); + + getboolfield(L, index, "liquids_pointable", def.liquids_pointable); + + lua_getfield(L, index, "tool_capabilities"); + if(lua_istable(L, -1)){ + def.tool_capabilities = new ToolCapabilities( + read_tool_capabilities(L, -1)); + } + + // If name is "" (hand), ensure there are ToolCapabilities + // because it will be looked up there whenever any other item has + // no ToolCapabilities + if (def.name.empty() && def.tool_capabilities == NULL){ + def.tool_capabilities = new ToolCapabilities(); + } + + lua_getfield(L, index, "groups"); + read_groups(L, -1, def.groups); + lua_pop(L, 1); + + lua_getfield(L, index, "sounds"); + if (!lua_isnil(L, -1)) { + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, "place"); + read_soundspec(L, -1, def.sound_place); + lua_pop(L, 1); + lua_getfield(L, -1, "place_failed"); + read_soundspec(L, -1, def.sound_place_failed); + lua_pop(L, 1); + } + lua_pop(L, 1); + + def.range = getfloatfield_default(L, index, "range", def.range); + + // Client shall immediately place this node when player places the item. + // Server will update the precise end result a moment later. + // "" = no prediction + getstringfield(L, index, "node_placement_prediction", + def.node_placement_prediction); + + getintfield(L, index, "place_param2", def.place_param2); +} + +/******************************************************************************/ +void push_item_definition(lua_State *L, const ItemDefinition &i) +{ + lua_newtable(L); + lua_pushstring(L, i.name.c_str()); + lua_setfield(L, -2, "name"); + lua_pushstring(L, i.description.c_str()); + lua_setfield(L, -2, "description"); +} + +void push_item_definition_full(lua_State *L, const ItemDefinition &i) +{ + std::string type(es_ItemType[(int)i.type].str); + + lua_newtable(L); + lua_pushstring(L, i.name.c_str()); + lua_setfield(L, -2, "name"); + lua_pushstring(L, i.description.c_str()); + lua_setfield(L, -2, "description"); + if (!i.short_description.empty()) { + lua_pushstring(L, i.short_description.c_str()); + lua_setfield(L, -2, "short_description"); + } + lua_pushstring(L, type.c_str()); + lua_setfield(L, -2, "type"); + lua_pushstring(L, i.inventory_image.c_str()); + lua_setfield(L, -2, "inventory_image"); + lua_pushstring(L, i.inventory_overlay.c_str()); + lua_setfield(L, -2, "inventory_overlay"); + lua_pushstring(L, i.wield_image.c_str()); + lua_setfield(L, -2, "wield_image"); + lua_pushstring(L, i.wield_overlay.c_str()); + lua_setfield(L, -2, "wield_overlay"); + lua_pushstring(L, i.palette_image.c_str()); + lua_setfield(L, -2, "palette_image"); + push_ARGB8(L, i.color); + lua_setfield(L, -2, "color"); + push_v3f(L, i.wield_scale); + lua_setfield(L, -2, "wield_scale"); + lua_pushinteger(L, i.stack_max); + lua_setfield(L, -2, "stack_max"); + lua_pushboolean(L, i.usable); + lua_setfield(L, -2, "usable"); + lua_pushboolean(L, i.liquids_pointable); + lua_setfield(L, -2, "liquids_pointable"); + if (i.tool_capabilities) { + push_tool_capabilities(L, *i.tool_capabilities); + lua_setfield(L, -2, "tool_capabilities"); + } + push_groups(L, i.groups); + lua_setfield(L, -2, "groups"); + push_soundspec(L, i.sound_place); + lua_setfield(L, -2, "sound_place"); + push_soundspec(L, i.sound_place_failed); + lua_setfield(L, -2, "sound_place_failed"); + lua_pushstring(L, i.node_placement_prediction.c_str()); + lua_setfield(L, -2, "node_placement_prediction"); +} + +/******************************************************************************/ +void read_object_properties(lua_State *L, int index, + ServerActiveObject *sao, ObjectProperties *prop, IItemDefManager *idef) +{ + if(index < 0) + index = lua_gettop(L) + 1 + index; + if (lua_isnil(L, index)) + return; + + luaL_checktype(L, -1, LUA_TTABLE); + + int hp_max = 0; + if (getintfield(L, -1, "hp_max", hp_max)) { + prop->hp_max = (u16)rangelim(hp_max, 0, U16_MAX); + // hp_max = 0 is sometimes used as a hack to keep players dead, only validate for entities + if (prop->hp_max == 0 && sao->getType() != ACTIVEOBJECT_TYPE_PLAYER) + throw LuaError("The hp_max property may not be 0 for entities!"); + + if (prop->hp_max < sao->getHP()) { + PlayerHPChangeReason reason(PlayerHPChangeReason::SET_HP_MAX); + sao->setHP(prop->hp_max, reason); + } + } + + if (getintfield(L, -1, "breath_max", prop->breath_max)) { + if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) { + PlayerSAO *player = (PlayerSAO *)sao; + if (prop->breath_max < player->getBreath()) + player->setBreath(prop->breath_max); + } + } + getboolfield(L, -1, "physical", prop->physical); + getboolfield(L, -1, "collide_with_objects", prop->collideWithObjects); + + lua_getfield(L, -1, "collisionbox"); + bool collisionbox_defined = lua_istable(L, -1); + if (collisionbox_defined) + prop->collisionbox = read_aabb3f(L, -1, 1.0); + lua_pop(L, 1); + + lua_getfield(L, -1, "selectionbox"); + if (lua_istable(L, -1)) + prop->selectionbox = read_aabb3f(L, -1, 1.0); + else if (collisionbox_defined) + prop->selectionbox = prop->collisionbox; + lua_pop(L, 1); + + getboolfield(L, -1, "pointable", prop->pointable); + getstringfield(L, -1, "visual", prop->visual); + + getstringfield(L, -1, "mesh", prop->mesh); + + lua_getfield(L, -1, "visual_size"); + if (lua_istable(L, -1)) { + // Backwards compatibility: Also accept { x = ?, y = ? } + v2f scale_xy = read_v2f(L, -1); + + f32 scale_z = scale_xy.X; + lua_getfield(L, -1, "z"); + if (lua_isnumber(L, -1)) + scale_z = lua_tonumber(L, -1); + lua_pop(L, 1); + + prop->visual_size = v3f(scale_xy.X, scale_xy.Y, scale_z); + } + lua_pop(L, 1); + + lua_getfield(L, -1, "textures"); + if(lua_istable(L, -1)){ + prop->textures.clear(); + int table = lua_gettop(L); + lua_pushnil(L); + while(lua_next(L, table) != 0){ + // key at index -2 and value at index -1 + if(lua_isstring(L, -1)) + prop->textures.emplace_back(lua_tostring(L, -1)); + else + prop->textures.emplace_back(""); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } + lua_pop(L, 1); + + lua_getfield(L, -1, "colors"); + if (lua_istable(L, -1)) { + int table = lua_gettop(L); + prop->colors.clear(); + for (lua_pushnil(L); lua_next(L, table); lua_pop(L, 1)) { + video::SColor color(255, 255, 255, 255); + read_color(L, -1, &color); + prop->colors.push_back(color); + } + } + lua_pop(L, 1); + + lua_getfield(L, -1, "spritediv"); + if(lua_istable(L, -1)) + prop->spritediv = read_v2s16(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "initial_sprite_basepos"); + if(lua_istable(L, -1)) + prop->initial_sprite_basepos = read_v2s16(L, -1); + lua_pop(L, 1); + + getboolfield(L, -1, "is_visible", prop->is_visible); + getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound); + if (getfloatfield(L, -1, "stepheight", prop->stepheight)) + prop->stepheight *= BS; + getfloatfield(L, -1, "eye_height", prop->eye_height); + + getfloatfield(L, -1, "automatic_rotate", prop->automatic_rotate); + lua_getfield(L, -1, "automatic_face_movement_dir"); + if (lua_isnumber(L, -1)) { + prop->automatic_face_movement_dir = true; + prop->automatic_face_movement_dir_offset = luaL_checknumber(L, -1); + } else if (lua_isboolean(L, -1)) { + prop->automatic_face_movement_dir = lua_toboolean(L, -1); + prop->automatic_face_movement_dir_offset = 0.0; + } + lua_pop(L, 1); + getboolfield(L, -1, "backface_culling", prop->backface_culling); + getintfield(L, -1, "glow", prop->glow); + + getstringfield(L, -1, "nametag", prop->nametag); + lua_getfield(L, -1, "nametag_color"); + if (!lua_isnil(L, -1)) { + video::SColor color = prop->nametag_color; + if (read_color(L, -1, &color)) + prop->nametag_color = color; + } + lua_pop(L, 1); + lua_getfield(L, -1, "nametag_bgcolor"); + if (!lua_isnil(L, -1)) { + if (lua_toboolean(L, -1)) { + video::SColor color; + if (read_color(L, -1, &color)) + prop->nametag_bgcolor = color; + } else { + prop->nametag_bgcolor = nullopt; + } + } + lua_pop(L, 1); + + lua_getfield(L, -1, "automatic_face_movement_max_rotation_per_sec"); + if (lua_isnumber(L, -1)) { + prop->automatic_face_movement_max_rotation_per_sec = luaL_checknumber(L, -1); + } + lua_pop(L, 1); + + getstringfield(L, -1, "infotext", prop->infotext); + getboolfield(L, -1, "static_save", prop->static_save); + + lua_getfield(L, -1, "wield_item"); + if (!lua_isnil(L, -1)) + prop->wield_item = read_item(L, -1, idef).getItemString(); + lua_pop(L, 1); + + getfloatfield(L, -1, "zoom_fov", prop->zoom_fov); + getboolfield(L, -1, "use_texture_alpha", prop->use_texture_alpha); + getboolfield(L, -1, "shaded", prop->shaded); + getboolfield(L, -1, "show_on_minimap", prop->show_on_minimap); + + getstringfield(L, -1, "damage_texture_modifier", prop->damage_texture_modifier); +} + +/******************************************************************************/ +void push_object_properties(lua_State *L, ObjectProperties *prop) +{ + lua_newtable(L); + lua_pushnumber(L, prop->hp_max); + lua_setfield(L, -2, "hp_max"); + lua_pushnumber(L, prop->breath_max); + lua_setfield(L, -2, "breath_max"); + lua_pushboolean(L, prop->physical); + lua_setfield(L, -2, "physical"); + lua_pushboolean(L, prop->collideWithObjects); + lua_setfield(L, -2, "collide_with_objects"); + push_aabb3f(L, prop->collisionbox); + lua_setfield(L, -2, "collisionbox"); + push_aabb3f(L, prop->selectionbox); + lua_setfield(L, -2, "selectionbox"); + lua_pushboolean(L, prop->pointable); + lua_setfield(L, -2, "pointable"); + lua_pushlstring(L, prop->visual.c_str(), prop->visual.size()); + lua_setfield(L, -2, "visual"); + lua_pushlstring(L, prop->mesh.c_str(), prop->mesh.size()); + lua_setfield(L, -2, "mesh"); + push_v3f(L, prop->visual_size); + lua_setfield(L, -2, "visual_size"); + + lua_createtable(L, prop->textures.size(), 0); + u16 i = 1; + for (const std::string &texture : prop->textures) { + lua_pushlstring(L, texture.c_str(), texture.size()); + lua_rawseti(L, -2, i++); + } + lua_setfield(L, -2, "textures"); + + lua_createtable(L, prop->colors.size(), 0); + i = 1; + for (const video::SColor &color : prop->colors) { + push_ARGB8(L, color); + lua_rawseti(L, -2, i++); + } + lua_setfield(L, -2, "colors"); + + push_v2s16(L, prop->spritediv); + lua_setfield(L, -2, "spritediv"); + push_v2s16(L, prop->initial_sprite_basepos); + lua_setfield(L, -2, "initial_sprite_basepos"); + lua_pushboolean(L, prop->is_visible); + lua_setfield(L, -2, "is_visible"); + lua_pushboolean(L, prop->makes_footstep_sound); + lua_setfield(L, -2, "makes_footstep_sound"); + lua_pushnumber(L, prop->stepheight / BS); + lua_setfield(L, -2, "stepheight"); + lua_pushnumber(L, prop->eye_height); + lua_setfield(L, -2, "eye_height"); + lua_pushnumber(L, prop->automatic_rotate); + lua_setfield(L, -2, "automatic_rotate"); + if (prop->automatic_face_movement_dir) + lua_pushnumber(L, prop->automatic_face_movement_dir_offset); + else + lua_pushboolean(L, false); + lua_setfield(L, -2, "automatic_face_movement_dir"); + lua_pushboolean(L, prop->backface_culling); + lua_setfield(L, -2, "backface_culling"); + lua_pushnumber(L, prop->glow); + lua_setfield(L, -2, "glow"); + lua_pushlstring(L, prop->nametag.c_str(), prop->nametag.size()); + lua_setfield(L, -2, "nametag"); + push_ARGB8(L, prop->nametag_color); + lua_setfield(L, -2, "nametag_color"); + if (prop->nametag_bgcolor) { + push_ARGB8(L, prop->nametag_bgcolor.value()); + lua_setfield(L, -2, "nametag_bgcolor"); + } else { + lua_pushboolean(L, false); + lua_setfield(L, -2, "nametag_bgcolor"); + } + lua_pushnumber(L, prop->automatic_face_movement_max_rotation_per_sec); + lua_setfield(L, -2, "automatic_face_movement_max_rotation_per_sec"); + lua_pushlstring(L, prop->infotext.c_str(), prop->infotext.size()); + lua_setfield(L, -2, "infotext"); + lua_pushboolean(L, prop->static_save); + lua_setfield(L, -2, "static_save"); + lua_pushlstring(L, prop->wield_item.c_str(), prop->wield_item.size()); + lua_setfield(L, -2, "wield_item"); + lua_pushnumber(L, prop->zoom_fov); + lua_setfield(L, -2, "zoom_fov"); + lua_pushboolean(L, prop->use_texture_alpha); + lua_setfield(L, -2, "use_texture_alpha"); + lua_pushboolean(L, prop->shaded); + lua_setfield(L, -2, "shaded"); + lua_pushlstring(L, prop->damage_texture_modifier.c_str(), prop->damage_texture_modifier.size()); + lua_setfield(L, -2, "damage_texture_modifier"); + lua_pushboolean(L, prop->show_on_minimap); + lua_setfield(L, -2, "show_on_minimap"); +} + +/******************************************************************************/ +TileDef read_tiledef(lua_State *L, int index, u8 drawtype) +{ + if(index < 0) + index = lua_gettop(L) + 1 + index; + + TileDef tiledef; + + bool default_tiling = true; + bool default_culling = true; + switch (drawtype) { + case NDT_PLANTLIKE: + case NDT_PLANTLIKE_ROOTED: + case NDT_FIRELIKE: + default_tiling = false; + // "break" is omitted here intentionaly, as PLANTLIKE + // FIRELIKE drawtype both should default to having + // backface_culling to false. + case NDT_MESH: + case NDT_LIQUID: + default_culling = false; + break; + default: + break; + } + + // key at index -2 and value at index + if(lua_isstring(L, index)){ + // "default_lava.png" + tiledef.name = lua_tostring(L, index); + tiledef.tileable_vertical = default_tiling; + tiledef.tileable_horizontal = default_tiling; + tiledef.backface_culling = default_culling; + } + else if(lua_istable(L, index)) + { + // name="default_lava.png" + tiledef.name = ""; + getstringfield(L, index, "name", tiledef.name); + getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat. + tiledef.backface_culling = getboolfield_default( + L, index, "backface_culling", default_culling); + tiledef.tileable_horizontal = getboolfield_default( + L, index, "tileable_horizontal", default_tiling); + tiledef.tileable_vertical = getboolfield_default( + L, index, "tileable_vertical", default_tiling); + std::string align_style; + if (getstringfield(L, index, "align_style", align_style)) { + if (align_style == "user") + tiledef.align_style = ALIGN_STYLE_USER_DEFINED; + else if (align_style == "world") + tiledef.align_style = ALIGN_STYLE_WORLD; + else + tiledef.align_style = ALIGN_STYLE_NODE; + } + tiledef.scale = getintfield_default(L, index, "scale", 0); + // color = ... + lua_getfield(L, index, "color"); + tiledef.has_color = read_color(L, -1, &tiledef.color); + lua_pop(L, 1); + // animation = {} + lua_getfield(L, index, "animation"); + tiledef.animation = read_animation_definition(L, -1); + lua_pop(L, 1); + } + + return tiledef; +} + +/******************************************************************************/ +void read_content_features(lua_State *L, ContentFeatures &f, int index) +{ + if(index < 0) + index = lua_gettop(L) + 1 + index; + + /* Cache existence of some callbacks */ + lua_getfield(L, index, "on_construct"); + if(!lua_isnil(L, -1)) f.has_on_construct = true; + lua_pop(L, 1); + lua_getfield(L, index, "on_destruct"); + if(!lua_isnil(L, -1)) f.has_on_destruct = true; + lua_pop(L, 1); + lua_getfield(L, index, "after_destruct"); + if(!lua_isnil(L, -1)) f.has_after_destruct = true; + lua_pop(L, 1); + + lua_getfield(L, index, "on_rightclick"); + f.rightclickable = lua_isfunction(L, -1); + lua_pop(L, 1); + + /* Name */ + getstringfield(L, index, "name", f.name); + + /* Groups */ + lua_getfield(L, index, "groups"); + read_groups(L, -1, f.groups); + lua_pop(L, 1); + + /* Visual definition */ + + f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", + ScriptApiNode::es_DrawType,NDT_NORMAL); + getfloatfield(L, index, "visual_scale", f.visual_scale); + + /* Meshnode model filename */ + getstringfield(L, index, "mesh", f.mesh); + + // tiles = {} + lua_getfield(L, index, "tiles"); + if(lua_istable(L, -1)){ + int table = lua_gettop(L); + lua_pushnil(L); + int i = 0; + while(lua_next(L, table) != 0){ + // Read tiledef from value + f.tiledef[i] = read_tiledef(L, -1, f.drawtype); + // removes value, keeps key for next iteration + lua_pop(L, 1); + i++; + if(i==6){ + lua_pop(L, 1); + break; + } + } + // Copy last value to all remaining textures + if(i >= 1){ + TileDef lasttile = f.tiledef[i-1]; + while(i < 6){ + f.tiledef[i] = lasttile; + i++; + } + } + } + lua_pop(L, 1); + + // overlay_tiles = {} + lua_getfield(L, index, "overlay_tiles"); + if (lua_istable(L, -1)) { + int table = lua_gettop(L); + lua_pushnil(L); + int i = 0; + while (lua_next(L, table) != 0) { + // Read tiledef from value + f.tiledef_overlay[i] = read_tiledef(L, -1, f.drawtype); + // removes value, keeps key for next iteration + lua_pop(L, 1); + i++; + if (i == 6) { + lua_pop(L, 1); + break; + } + } + // Copy last value to all remaining textures + if (i >= 1) { + TileDef lasttile = f.tiledef_overlay[i - 1]; + while (i < 6) { + f.tiledef_overlay[i] = lasttile; + i++; + } + } + } + lua_pop(L, 1); + + // special_tiles = {} + lua_getfield(L, index, "special_tiles"); + if(lua_istable(L, -1)){ + int table = lua_gettop(L); + lua_pushnil(L); + int i = 0; + while(lua_next(L, table) != 0){ + // Read tiledef from value + f.tiledef_special[i] = read_tiledef(L, -1, f.drawtype); + // removes value, keeps key for next iteration + lua_pop(L, 1); + i++; + if(i==CF_SPECIAL_COUNT){ + lua_pop(L, 1); + break; + } + } + } + lua_pop(L, 1); + + /* alpha & use_texture_alpha */ + // This is a bit complicated due to compatibility + + f.setDefaultAlphaMode(); + + warn_if_field_exists(L, index, "alpha", + "Obsolete, only limited compatibility provided; " + "replaced by \"use_texture_alpha\""); + if (getintfield_default(L, index, "alpha", 255) != 255) + f.alpha = ALPHAMODE_BLEND; + + lua_getfield(L, index, "use_texture_alpha"); + if (lua_isboolean(L, -1)) { + warn_if_field_exists(L, index, "use_texture_alpha", + "Boolean values are deprecated; use the new choices"); + if (lua_toboolean(L, -1)) + f.alpha = (f.drawtype == NDT_NORMAL) ? ALPHAMODE_CLIP : ALPHAMODE_BLEND; + } else if (check_field_or_nil(L, -1, LUA_TSTRING, "use_texture_alpha")) { + int result = f.alpha; + string_to_enum(ScriptApiNode::es_TextureAlphaMode, result, + std::string(lua_tostring(L, -1))); + f.alpha = static_cast<enum AlphaMode>(result); + } + lua_pop(L, 1); + + /* Other stuff */ + + lua_getfield(L, index, "color"); + read_color(L, -1, &f.color); + lua_pop(L, 1); + + getstringfield(L, index, "palette", f.palette_name); + + lua_getfield(L, index, "post_effect_color"); + read_color(L, -1, &f.post_effect_color); + lua_pop(L, 1); + + f.param_type = (ContentParamType)getenumfield(L, index, "paramtype", + ScriptApiNode::es_ContentParamType, CPT_NONE); + f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2", + ScriptApiNode::es_ContentParamType2, CPT2_NONE); + + if (!f.palette_name.empty() && + !(f.param_type_2 == CPT2_COLOR || + f.param_type_2 == CPT2_COLORED_FACEDIR || + f.param_type_2 == CPT2_COLORED_WALLMOUNTED || + f.param_type_2 == CPT2_COLORED_DEGROTATE)) + warningstream << "Node " << f.name.c_str() + << " has a palette, but not a suitable paramtype2." << std::endl; + + // True for all ground-like things like stone and mud, false for eg. trees + getboolfield(L, index, "is_ground_content", f.is_ground_content); + f.light_propagates = (f.param_type == CPT_LIGHT); + getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates); + // This is used for collision detection. + // Also for general solidness queries. + getboolfield(L, index, "walkable", f.walkable); + // Player can point to these + getboolfield(L, index, "pointable", f.pointable); + // Player can dig these + getboolfield(L, index, "diggable", f.diggable); + // Player can climb these + getboolfield(L, index, "climbable", f.climbable); + // Player can build on these + getboolfield(L, index, "buildable_to", f.buildable_to); + // Liquids flow into and replace node + getboolfield(L, index, "floodable", f.floodable); + // Whether the node is non-liquid, source liquid or flowing liquid + f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype", + ScriptApiNode::es_LiquidType, LIQUID_NONE); + // If the content is liquid, this is the flowing version of the liquid. + getstringfield(L, index, "liquid_alternative_flowing", + f.liquid_alternative_flowing); + // If the content is liquid, this is the source version of the liquid. + getstringfield(L, index, "liquid_alternative_source", + f.liquid_alternative_source); + // Viscosity for fluid flow, ranging from 1 to 7, with + // 1 giving almost instantaneous propagation and 7 being + // the slowest possible + f.liquid_viscosity = getintfield_default(L, index, + "liquid_viscosity", f.liquid_viscosity); + // If move_resistance is not set explicitly, + // move_resistance is equal to liquid_viscosity + f.move_resistance = f.liquid_viscosity; + f.liquid_range = getintfield_default(L, index, + "liquid_range", f.liquid_range); + f.leveled = getintfield_default(L, index, "leveled", f.leveled); + f.leveled_max = getintfield_default(L, index, + "leveled_max", f.leveled_max); + + getboolfield(L, index, "liquid_renewable", f.liquid_renewable); + f.drowning = getintfield_default(L, index, + "drowning", f.drowning); + // Amount of light the node emits + f.light_source = getintfield_default(L, index, + "light_source", f.light_source); + if (f.light_source > LIGHT_MAX) { + warningstream << "Node " << f.name.c_str() + << " had greater light_source than " << LIGHT_MAX + << ", it was reduced." << std::endl; + f.light_source = LIGHT_MAX; + } + f.damage_per_second = getintfield_default(L, index, + "damage_per_second", f.damage_per_second); + + lua_getfield(L, index, "node_box"); + if(lua_istable(L, -1)) + f.node_box = read_nodebox(L, -1); + lua_pop(L, 1); + + lua_getfield(L, index, "connects_to"); + if (lua_istable(L, -1)) { + int table = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, table) != 0) { + // Value at -1 + f.connects_to.emplace_back(lua_tostring(L, -1)); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + + lua_getfield(L, index, "connect_sides"); + if (lua_istable(L, -1)) { + int table = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, table) != 0) { + // Value at -1 + std::string side(lua_tostring(L, -1)); + // Note faces are flipped to make checking easier + if (side == "top") + f.connect_sides |= 2; + else if (side == "bottom") + f.connect_sides |= 1; + else if (side == "front") + f.connect_sides |= 16; + else if (side == "left") + f.connect_sides |= 32; + else if (side == "back") + f.connect_sides |= 4; + else if (side == "right") + f.connect_sides |= 8; + else + warningstream << "Unknown value for \"connect_sides\": " + << side << std::endl; + lua_pop(L, 1); + } + } + lua_pop(L, 1); + + lua_getfield(L, index, "selection_box"); + if(lua_istable(L, -1)) + f.selection_box = read_nodebox(L, -1); + lua_pop(L, 1); + + lua_getfield(L, index, "collision_box"); + if(lua_istable(L, -1)) + f.collision_box = read_nodebox(L, -1); + lua_pop(L, 1); + + f.waving = getintfield_default(L, index, + "waving", f.waving); + + // Set to true if paramtype used to be 'facedir_simple' + getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple); + // Set to true if wall_mounted used to be set to true + getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted); + + // Sound table + lua_getfield(L, index, "sounds"); + if(lua_istable(L, -1)){ + lua_getfield(L, -1, "footstep"); + read_soundspec(L, -1, f.sound_footstep); + lua_pop(L, 1); + lua_getfield(L, -1, "dig"); + read_soundspec(L, -1, f.sound_dig); + lua_pop(L, 1); + lua_getfield(L, -1, "dug"); + read_soundspec(L, -1, f.sound_dug); + lua_pop(L, 1); + } + lua_pop(L, 1); + + // Node immediately placed by client when node is dug + getstringfield(L, index, "node_dig_prediction", + f.node_dig_prediction); + + // How much the node slows down players, ranging from 1 to 7, + // the higher, the slower. + f.move_resistance = getintfield_default(L, index, + "move_resistance", f.move_resistance); + + // Whether e.g. players in this node will have liquid movement physics + lua_getfield(L, index, "liquid_move_physics"); + if(lua_isboolean(L, -1)) { + f.liquid_move_physics = lua_toboolean(L, -1); + } else if(lua_isnil(L, -1)) { + f.liquid_move_physics = f.liquid_type != LIQUID_NONE; + } else { + errorstream << "Field \"liquid_move_physics\": Invalid type!" << std::endl; + } + lua_pop(L, 1); +} + +void push_content_features(lua_State *L, const ContentFeatures &c) +{ + std::string paramtype(ScriptApiNode::es_ContentParamType[(int)c.param_type].str); + std::string paramtype2(ScriptApiNode::es_ContentParamType2[(int)c.param_type_2].str); + std::string drawtype(ScriptApiNode::es_DrawType[(int)c.drawtype].str); + std::string liquid_type(ScriptApiNode::es_LiquidType[(int)c.liquid_type].str); + + /* Missing "tiles" because I don't see a usecase (at least not yet). */ + + lua_newtable(L); + lua_pushboolean(L, c.has_on_construct); + lua_setfield(L, -2, "has_on_construct"); + lua_pushboolean(L, c.has_on_destruct); + lua_setfield(L, -2, "has_on_destruct"); + lua_pushboolean(L, c.has_after_destruct); + lua_setfield(L, -2, "has_after_destruct"); + lua_pushstring(L, c.name.c_str()); + lua_setfield(L, -2, "name"); + push_groups(L, c.groups); + lua_setfield(L, -2, "groups"); + lua_pushstring(L, paramtype.c_str()); + lua_setfield(L, -2, "paramtype"); + lua_pushstring(L, paramtype2.c_str()); + lua_setfield(L, -2, "paramtype2"); + lua_pushstring(L, drawtype.c_str()); + lua_setfield(L, -2, "drawtype"); + if (!c.mesh.empty()) { + lua_pushstring(L, c.mesh.c_str()); + lua_setfield(L, -2, "mesh"); + } +#ifndef SERVER + push_ARGB8(L, c.minimap_color); // I know this is not set-able w/ register_node, + lua_setfield(L, -2, "minimap_color"); // but the people need to know! +#endif + lua_pushnumber(L, c.visual_scale); + lua_setfield(L, -2, "visual_scale"); + lua_pushnumber(L, c.alpha); + lua_setfield(L, -2, "alpha"); + if (!c.palette_name.empty()) { + push_ARGB8(L, c.color); + lua_setfield(L, -2, "color"); + + lua_pushstring(L, c.palette_name.c_str()); + lua_setfield(L, -2, "palette_name"); + + push_palette(L, c.palette); + lua_setfield(L, -2, "palette"); + } + lua_pushnumber(L, c.waving); + lua_setfield(L, -2, "waving"); + lua_pushnumber(L, c.connect_sides); + lua_setfield(L, -2, "connect_sides"); + + lua_createtable(L, c.connects_to.size(), 0); + u16 i = 1; + for (const std::string &it : c.connects_to) { + lua_pushlstring(L, it.c_str(), it.size()); + lua_rawseti(L, -2, i++); + } + lua_setfield(L, -2, "connects_to"); + + push_ARGB8(L, c.post_effect_color); + lua_setfield(L, -2, "post_effect_color"); + lua_pushnumber(L, c.leveled); + lua_setfield(L, -2, "leveled"); + lua_pushnumber(L, c.leveled_max); + lua_setfield(L, -2, "leveled_max"); + lua_pushboolean(L, c.sunlight_propagates); + lua_setfield(L, -2, "sunlight_propagates"); + lua_pushnumber(L, c.light_source); + lua_setfield(L, -2, "light_source"); + lua_pushboolean(L, c.is_ground_content); + lua_setfield(L, -2, "is_ground_content"); + lua_pushboolean(L, c.walkable); + lua_setfield(L, -2, "walkable"); + lua_pushboolean(L, c.pointable); + lua_setfield(L, -2, "pointable"); + lua_pushboolean(L, c.diggable); + lua_setfield(L, -2, "diggable"); + lua_pushboolean(L, c.climbable); + lua_setfield(L, -2, "climbable"); + lua_pushboolean(L, c.buildable_to); + lua_setfield(L, -2, "buildable_to"); + lua_pushboolean(L, c.rightclickable); + lua_setfield(L, -2, "rightclickable"); + lua_pushnumber(L, c.damage_per_second); + lua_setfield(L, -2, "damage_per_second"); + if (c.isLiquid()) { + lua_pushstring(L, liquid_type.c_str()); + lua_setfield(L, -2, "liquid_type"); + lua_pushstring(L, c.liquid_alternative_flowing.c_str()); + lua_setfield(L, -2, "liquid_alternative_flowing"); + lua_pushstring(L, c.liquid_alternative_source.c_str()); + lua_setfield(L, -2, "liquid_alternative_source"); + lua_pushnumber(L, c.liquid_viscosity); + lua_setfield(L, -2, "liquid_viscosity"); + lua_pushboolean(L, c.liquid_renewable); + lua_setfield(L, -2, "liquid_renewable"); + lua_pushnumber(L, c.liquid_range); + lua_setfield(L, -2, "liquid_range"); + } + lua_pushnumber(L, c.drowning); + lua_setfield(L, -2, "drowning"); + lua_pushboolean(L, c.floodable); + lua_setfield(L, -2, "floodable"); + push_nodebox(L, c.node_box); + lua_setfield(L, -2, "node_box"); + push_nodebox(L, c.selection_box); + lua_setfield(L, -2, "selection_box"); + push_nodebox(L, c.collision_box); + lua_setfield(L, -2, "collision_box"); + lua_newtable(L); + push_soundspec(L, c.sound_footstep); + lua_setfield(L, -2, "sound_footstep"); + push_soundspec(L, c.sound_dig); + lua_setfield(L, -2, "sound_dig"); + push_soundspec(L, c.sound_dug); + lua_setfield(L, -2, "sound_dug"); + lua_setfield(L, -2, "sounds"); + lua_pushboolean(L, c.legacy_facedir_simple); + lua_setfield(L, -2, "legacy_facedir_simple"); + lua_pushboolean(L, c.legacy_wallmounted); + lua_setfield(L, -2, "legacy_wallmounted"); + lua_pushstring(L, c.node_dig_prediction.c_str()); + lua_setfield(L, -2, "node_dig_prediction"); + lua_pushnumber(L, c.move_resistance); + lua_setfield(L, -2, "move_resistance"); + lua_pushboolean(L, c.liquid_move_physics); + lua_setfield(L, -2, "liquid_move_physics"); +} + +/******************************************************************************/ +void push_nodebox(lua_State *L, const NodeBox &box) +{ + lua_newtable(L); + switch (box.type) + { + case NODEBOX_REGULAR: + lua_pushstring(L, "regular"); + lua_setfield(L, -2, "type"); + break; + case NODEBOX_LEVELED: + case NODEBOX_FIXED: + lua_pushstring(L, "fixed"); + lua_setfield(L, -2, "type"); + push_box(L, box.fixed); + lua_setfield(L, -2, "fixed"); + break; + case NODEBOX_WALLMOUNTED: + lua_pushstring(L, "wallmounted"); + lua_setfield(L, -2, "type"); + push_aabb3f(L, box.wall_top); + lua_setfield(L, -2, "wall_top"); + push_aabb3f(L, box.wall_bottom); + lua_setfield(L, -2, "wall_bottom"); + push_aabb3f(L, box.wall_side); + lua_setfield(L, -2, "wall_side"); + break; + case NODEBOX_CONNECTED: { + lua_pushstring(L, "connected"); + lua_setfield(L, -2, "type"); + const auto &c = box.getConnected(); + push_box(L, c.connect_top); + lua_setfield(L, -2, "connect_top"); + push_box(L, c.connect_bottom); + lua_setfield(L, -2, "connect_bottom"); + push_box(L, c.connect_front); + lua_setfield(L, -2, "connect_front"); + push_box(L, c.connect_back); + lua_setfield(L, -2, "connect_back"); + push_box(L, c.connect_left); + lua_setfield(L, -2, "connect_left"); + push_box(L, c.connect_right); + lua_setfield(L, -2, "connect_right"); + // half the boxes are missing here? + break; + } + default: + FATAL_ERROR("Invalid box.type"); + break; + } +} + +void push_box(lua_State *L, const std::vector<aabb3f> &box) +{ + lua_createtable(L, box.size(), 0); + u8 i = 1; + for (const aabb3f &it : box) { + push_aabb3f(L, it); + lua_rawseti(L, -2, i++); + } +} + +/******************************************************************************/ +void push_palette(lua_State *L, const std::vector<video::SColor> *palette) +{ + lua_createtable(L, palette->size(), 0); + int newTable = lua_gettop(L); + int index = 1; + std::vector<video::SColor>::const_iterator iter; + for (iter = palette->begin(); iter != palette->end(); ++iter) { + push_ARGB8(L, (*iter)); + lua_rawseti(L, newTable, index); + index++; + } +} + +/******************************************************************************/ +void read_server_sound_params(lua_State *L, int index, + ServerPlayingSound ¶ms) +{ + if(index < 0) + index = lua_gettop(L) + 1 + index; + + if(lua_istable(L, index)){ + // Functional overlap: this may modify SimpleSoundSpec contents + getfloatfield(L, index, "fade", params.spec.fade); + getfloatfield(L, index, "pitch", params.spec.pitch); + getboolfield(L, index, "loop", params.spec.loop); + + getfloatfield(L, index, "gain", params.gain); + + // Handle positional information + getstringfield(L, index, "to_player", params.to_player); + lua_getfield(L, index, "pos"); + if(!lua_isnil(L, -1)){ + v3f p = read_v3f(L, -1)*BS; + params.pos = p; + params.type = SoundLocation::Position; + } + lua_pop(L, 1); + lua_getfield(L, index, "object"); + if(!lua_isnil(L, -1)){ + ObjectRef *ref = ObjectRef::checkobject(L, -1); + ServerActiveObject *sao = ObjectRef::getobject(ref); + if(sao){ + params.object = sao->getId(); + params.type = SoundLocation::Object; + } + } + lua_pop(L, 1); + params.max_hear_distance = BS*getfloatfield_default(L, index, + "max_hear_distance", params.max_hear_distance/BS); + getstringfield(L, index, "exclude_player", params.exclude_player); + } +} + +/******************************************************************************/ +void read_soundspec(lua_State *L, int index, SimpleSoundSpec &spec) +{ + if(index < 0) + index = lua_gettop(L) + 1 + index; + if (lua_isnil(L, index)) + return; + + if (lua_istable(L, index)) { + getstringfield(L, index, "name", spec.name); + getfloatfield(L, index, "gain", spec.gain); + getfloatfield(L, index, "fade", spec.fade); + getfloatfield(L, index, "pitch", spec.pitch); + } else if (lua_isstring(L, index)) { + spec.name = lua_tostring(L, index); + } +} + +void push_soundspec(lua_State *L, const SimpleSoundSpec &spec) +{ + lua_createtable(L, 0, 3); + lua_pushstring(L, spec.name.c_str()); + lua_setfield(L, -2, "name"); + lua_pushnumber(L, spec.gain); + lua_setfield(L, -2, "gain"); + lua_pushnumber(L, spec.fade); + lua_setfield(L, -2, "fade"); + lua_pushnumber(L, spec.pitch); + lua_setfield(L, -2, "pitch"); +} + +/******************************************************************************/ +NodeBox read_nodebox(lua_State *L, int index) +{ + NodeBox nodebox; + if (lua_isnil(L, -1)) + return nodebox; + + luaL_checktype(L, -1, LUA_TTABLE); + + nodebox.type = (NodeBoxType)getenumfield(L, index, "type", + ScriptApiNode::es_NodeBoxType, NODEBOX_REGULAR); + +#define NODEBOXREAD(n, s){ \ + lua_getfield(L, index, (s)); \ + if (lua_istable(L, -1)) \ + (n) = read_aabb3f(L, -1, BS); \ + lua_pop(L, 1); \ + } + +#define NODEBOXREADVEC(n, s) \ + lua_getfield(L, index, (s)); \ + if (lua_istable(L, -1)) \ + (n) = read_aabb3f_vector(L, -1, BS); \ + lua_pop(L, 1); + + NODEBOXREADVEC(nodebox.fixed, "fixed"); + NODEBOXREAD(nodebox.wall_top, "wall_top"); + NODEBOXREAD(nodebox.wall_bottom, "wall_bottom"); + NODEBOXREAD(nodebox.wall_side, "wall_side"); + + if (nodebox.type == NODEBOX_CONNECTED) { + auto &c = nodebox.getConnected(); + NODEBOXREADVEC(c.connect_top, "connect_top"); + NODEBOXREADVEC(c.connect_bottom, "connect_bottom"); + NODEBOXREADVEC(c.connect_front, "connect_front"); + NODEBOXREADVEC(c.connect_left, "connect_left"); + NODEBOXREADVEC(c.connect_back, "connect_back"); + NODEBOXREADVEC(c.connect_right, "connect_right"); + NODEBOXREADVEC(c.disconnected_top, "disconnected_top"); + NODEBOXREADVEC(c.disconnected_bottom, "disconnected_bottom"); + NODEBOXREADVEC(c.disconnected_front, "disconnected_front"); + NODEBOXREADVEC(c.disconnected_left, "disconnected_left"); + NODEBOXREADVEC(c.disconnected_back, "disconnected_back"); + NODEBOXREADVEC(c.disconnected_right, "disconnected_right"); + NODEBOXREADVEC(c.disconnected, "disconnected"); + NODEBOXREADVEC(c.disconnected_sides, "disconnected_sides"); + } + + return nodebox; +} + +/******************************************************************************/ +MapNode readnode(lua_State *L, int index, const NodeDefManager *ndef) +{ + lua_getfield(L, index, "name"); + if (!lua_isstring(L, -1)) + throw LuaError("Node name is not set or is not a string!"); + std::string name = lua_tostring(L, -1); + lua_pop(L, 1); + + u8 param1 = 0; + lua_getfield(L, index, "param1"); + if (!lua_isnil(L, -1)) + param1 = lua_tonumber(L, -1); + lua_pop(L, 1); + + u8 param2 = 0; + lua_getfield(L, index, "param2"); + if (!lua_isnil(L, -1)) + param2 = lua_tonumber(L, -1); + lua_pop(L, 1); + + content_t id = CONTENT_IGNORE; + if (!ndef->getId(name, id)) + throw LuaError("\"" + name + "\" is not a registered node!"); + + return {id, param1, param2}; +} + +/******************************************************************************/ +void pushnode(lua_State *L, const MapNode &n, const NodeDefManager *ndef) +{ + lua_createtable(L, 0, 3); + lua_pushstring(L, ndef->get(n).name.c_str()); + lua_setfield(L, -2, "name"); + lua_pushinteger(L, n.getParam1()); + lua_setfield(L, -2, "param1"); + lua_pushinteger(L, n.getParam2()); + lua_setfield(L, -2, "param2"); +} + +/******************************************************************************/ +void warn_if_field_exists(lua_State *L, int table, + const char *name, const std::string &message) +{ + lua_getfield(L, table, name); + if (!lua_isnil(L, -1)) { + warningstream << "Field \"" << name << "\": " + << message << std::endl; + infostream << script_get_backtrace(L) << std::endl; + } + lua_pop(L, 1); +} + +/******************************************************************************/ +int getenumfield(lua_State *L, int table, + const char *fieldname, const EnumString *spec, int default_) +{ + int result = default_; + string_to_enum(spec, result, + getstringfield_default(L, table, fieldname, "")); + return result; +} + +/******************************************************************************/ +bool string_to_enum(const EnumString *spec, int &result, + const std::string &str) +{ + const EnumString *esp = spec; + while(esp->str){ + if (!strcmp(str.c_str(), esp->str)) { + result = esp->num; + return true; + } + esp++; + } + return false; +} + +/******************************************************************************/ +ItemStack read_item(lua_State* L, int index, IItemDefManager *idef) +{ + if(index < 0) + index = lua_gettop(L) + 1 + index; + + if (lua_isnil(L, index)) { + return ItemStack(); + } + + if (lua_isuserdata(L, index)) { + // Convert from LuaItemStack + LuaItemStack *o = LuaItemStack::checkobject(L, index); + return o->getItem(); + } + + if (lua_isstring(L, index)) { + // Convert from itemstring + std::string itemstring = lua_tostring(L, index); + try + { + ItemStack item; + item.deSerialize(itemstring, idef); + return item; + } + catch(SerializationError &e) + { + warningstream<<"unable to create item from itemstring" + <<": "<<itemstring<<std::endl; + return ItemStack(); + } + } + else if(lua_istable(L, index)) + { + // Convert from table + std::string name = getstringfield_default(L, index, "name", ""); + int count = getintfield_default(L, index, "count", 1); + int wear = getintfield_default(L, index, "wear", 0); + + ItemStack istack(name, count, wear, idef); + + // BACKWARDS COMPATIBLITY + std::string value = getstringfield_default(L, index, "metadata", ""); + istack.metadata.setString("", value); + + // Get meta + lua_getfield(L, index, "meta"); + int fieldstable = lua_gettop(L); + if (lua_istable(L, fieldstable)) { + lua_pushnil(L); + while (lua_next(L, fieldstable) != 0) { + // key at index -2 and value at index -1 + std::string key = lua_tostring(L, -2); + size_t value_len; + const char *value_cs = lua_tolstring(L, -1, &value_len); + std::string value(value_cs, value_len); + istack.metadata.setString(key, value); + lua_pop(L, 1); // removes value, keeps key for next iteration + } + } + + return istack; + } else { + throw LuaError("Expecting itemstack, itemstring, table or nil"); + } +} + +/******************************************************************************/ +void push_tool_capabilities(lua_State *L, + const ToolCapabilities &toolcap) +{ + lua_newtable(L); + setfloatfield(L, -1, "full_punch_interval", toolcap.full_punch_interval); + setintfield(L, -1, "max_drop_level", toolcap.max_drop_level); + setintfield(L, -1, "punch_attack_uses", toolcap.punch_attack_uses); + // Create groupcaps table + lua_newtable(L); + // For each groupcap + for (const auto &gc_it : toolcap.groupcaps) { + // Create groupcap table + lua_newtable(L); + const std::string &name = gc_it.first; + const ToolGroupCap &groupcap = gc_it.second; + // Create subtable "times" + lua_newtable(L); + for (auto time : groupcap.times) { + lua_pushinteger(L, time.first); + lua_pushnumber(L, time.second); + lua_settable(L, -3); + } + // Set subtable "times" + lua_setfield(L, -2, "times"); + // Set simple parameters + setintfield(L, -1, "maxlevel", groupcap.maxlevel); + setintfield(L, -1, "uses", groupcap.uses); + // Insert groupcap table into groupcaps table + lua_setfield(L, -2, name.c_str()); + } + // Set groupcaps table + lua_setfield(L, -2, "groupcaps"); + //Create damage_groups table + lua_newtable(L); + // For each damage group + for (const auto &damageGroup : toolcap.damageGroups) { + // Create damage group table + lua_pushinteger(L, damageGroup.second); + lua_setfield(L, -2, damageGroup.first.c_str()); + } + lua_setfield(L, -2, "damage_groups"); +} + +/******************************************************************************/ +void push_inventory_list(lua_State *L, const InventoryList &invlist) +{ + push_items(L, invlist.getItems()); +} + +/******************************************************************************/ +void push_inventory_lists(lua_State *L, const Inventory &inv) +{ + const auto &lists = inv.getLists(); + lua_createtable(L, 0, lists.size()); + for(const InventoryList *list : lists) { + const std::string &name = list->getName(); + lua_pushlstring(L, name.c_str(), name.size()); + push_inventory_list(L, *list); + lua_rawset(L, -3); + } +} + +/******************************************************************************/ +void read_inventory_list(lua_State *L, int tableindex, + Inventory *inv, const char *name, IGameDef *gdef, int forcesize) +{ + if(tableindex < 0) + tableindex = lua_gettop(L) + 1 + tableindex; + + // If nil, delete list + if(lua_isnil(L, tableindex)){ + inv->deleteList(name); + return; + } + + // Get Lua-specified items to insert into the list + std::vector<ItemStack> items = read_items(L, tableindex, gdef); + size_t listsize = (forcesize >= 0) ? forcesize : items.size(); + + // Create or resize/clear list + InventoryList *invlist = inv->addList(name, listsize); + if (!invlist) { + luaL_error(L, "inventory list: cannot create list named '%s'", name); + return; + } + + for (size_t i = 0; i < items.size(); ++i) { + if (i == listsize) + break; // Truncate provided list of items + invlist->changeItem(i, items[i]); + } +} + +/******************************************************************************/ +struct TileAnimationParams read_animation_definition(lua_State *L, int index) +{ + if(index < 0) + index = lua_gettop(L) + 1 + index; + + struct TileAnimationParams anim; + anim.type = TAT_NONE; + if (!lua_istable(L, index)) + return anim; + + anim.type = (TileAnimationType) + getenumfield(L, index, "type", es_TileAnimationType, + TAT_NONE); + if (anim.type == TAT_VERTICAL_FRAMES) { + // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + anim.vertical_frames.aspect_w = + getintfield_default(L, index, "aspect_w", 16); + anim.vertical_frames.aspect_h = + getintfield_default(L, index, "aspect_h", 16); + anim.vertical_frames.length = + getfloatfield_default(L, index, "length", 1.0); + } else if (anim.type == TAT_SHEET_2D) { + // {type="sheet_2d", frames_w=5, frames_h=3, frame_length=0.5} + getintfield(L, index, "frames_w", + anim.sheet_2d.frames_w); + getintfield(L, index, "frames_h", + anim.sheet_2d.frames_h); + getfloatfield(L, index, "frame_length", + anim.sheet_2d.frame_length); + } + + return anim; +} + +/******************************************************************************/ +ToolCapabilities read_tool_capabilities( + lua_State *L, int table) +{ + ToolCapabilities toolcap; + getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval); + getintfield(L, table, "max_drop_level", toolcap.max_drop_level); + getintfield(L, table, "punch_attack_uses", toolcap.punch_attack_uses); + lua_getfield(L, table, "groupcaps"); + if(lua_istable(L, -1)){ + int table_groupcaps = lua_gettop(L); + lua_pushnil(L); + while(lua_next(L, table_groupcaps) != 0){ + // key at index -2 and value at index -1 + std::string groupname = luaL_checkstring(L, -2); + if(lua_istable(L, -1)){ + int table_groupcap = lua_gettop(L); + // This will be created + ToolGroupCap groupcap; + // Read simple parameters + getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel); + getintfield(L, table_groupcap, "uses", groupcap.uses); + // DEPRECATED: maxwear + float maxwear = 0; + if (getfloatfield(L, table_groupcap, "maxwear", maxwear)){ + if (maxwear != 0) + groupcap.uses = 1.0/maxwear; + else + groupcap.uses = 0; + warningstream << "Field \"maxwear\" is deprecated; " + << "replace with uses=1/maxwear" << std::endl; + infostream << script_get_backtrace(L) << std::endl; + } + // Read "times" table + lua_getfield(L, table_groupcap, "times"); + if(lua_istable(L, -1)){ + int table_times = lua_gettop(L); + lua_pushnil(L); + while(lua_next(L, table_times) != 0){ + // key at index -2 and value at index -1 + int rating = luaL_checkinteger(L, -2); + float time = luaL_checknumber(L, -1); + groupcap.times[rating] = time; + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } + lua_pop(L, 1); + // Insert groupcap into toolcap + toolcap.groupcaps[groupname] = groupcap; + } + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } + lua_pop(L, 1); + + lua_getfield(L, table, "damage_groups"); + if(lua_istable(L, -1)){ + int table_damage_groups = lua_gettop(L); + lua_pushnil(L); + while(lua_next(L, table_damage_groups) != 0){ + // key at index -2 and value at index -1 + std::string groupname = luaL_checkstring(L, -2); + u16 value = luaL_checkinteger(L, -1); + toolcap.damageGroups[groupname] = value; + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } + lua_pop(L, 1); + return toolcap; +} + +/******************************************************************************/ +void push_dig_params(lua_State *L,const DigParams ¶ms) +{ + lua_createtable(L, 0, 3); + setboolfield(L, -1, "diggable", params.diggable); + setfloatfield(L, -1, "time", params.time); + setintfield(L, -1, "wear", params.wear); +} + +/******************************************************************************/ +void push_hit_params(lua_State *L,const HitParams ¶ms) +{ + lua_createtable(L, 0, 3); + setintfield(L, -1, "hp", params.hp); + setintfield(L, -1, "wear", params.wear); +} + +/******************************************************************************/ + +bool getflagsfield(lua_State *L, int table, const char *fieldname, + FlagDesc *flagdesc, u32 *flags, u32 *flagmask) +{ + lua_getfield(L, table, fieldname); + + bool success = read_flags(L, -1, flagdesc, flags, flagmask); + + lua_pop(L, 1); + + return success; +} + +bool read_flags(lua_State *L, int index, FlagDesc *flagdesc, + u32 *flags, u32 *flagmask) +{ + if (lua_isstring(L, index)) { + std::string flagstr = lua_tostring(L, index); + *flags = readFlagString(flagstr, flagdesc, flagmask); + } else if (lua_istable(L, index)) { + *flags = read_flags_table(L, index, flagdesc, flagmask); + } else { + return false; + } + + return true; +} + +u32 read_flags_table(lua_State *L, int table, FlagDesc *flagdesc, u32 *flagmask) +{ + u32 flags = 0, mask = 0; + char fnamebuf[64] = "no"; + + for (int i = 0; flagdesc[i].name; i++) { + bool result; + + if (getboolfield(L, table, flagdesc[i].name, result)) { + mask |= flagdesc[i].flag; + if (result) + flags |= flagdesc[i].flag; + } + + strlcpy(fnamebuf + 2, flagdesc[i].name, sizeof(fnamebuf) - 2); + if (getboolfield(L, table, fnamebuf, result)) + mask |= flagdesc[i].flag; + } + + if (flagmask) + *flagmask = mask; + + return flags; +} + +void push_flags_string(lua_State *L, FlagDesc *flagdesc, u32 flags, u32 flagmask) +{ + std::string flagstring = writeFlagString(flags, flagdesc, flagmask); + lua_pushlstring(L, flagstring.c_str(), flagstring.size()); +} + +/******************************************************************************/ +/* Lua Stored data! */ +/******************************************************************************/ + +/******************************************************************************/ +void read_groups(lua_State *L, int index, ItemGroupList &result) +{ + if (lua_isnil(L, index)) + return; + + luaL_checktype(L, index, LUA_TTABLE); + + result.clear(); + lua_pushnil(L); + if (index < 0) + index -= 1; + while (lua_next(L, index) != 0) { + // key at index -2 and value at index -1 + std::string name = luaL_checkstring(L, -2); + int rating = luaL_checkinteger(L, -1); + // zero rating indicates not in the group + if (rating != 0) + result[name] = rating; + // removes value, keeps key for next iteration + lua_pop(L, 1); + } +} + +/******************************************************************************/ +void push_groups(lua_State *L, const ItemGroupList &groups) +{ + lua_createtable(L, 0, groups.size()); + for (const auto &group : groups) { + lua_pushinteger(L, group.second); + lua_setfield(L, -2, group.first.c_str()); + } +} + +/******************************************************************************/ +void push_items(lua_State *L, const std::vector<ItemStack> &items) +{ + lua_createtable(L, items.size(), 0); + for (u32 i = 0; i != items.size(); i++) { + LuaItemStack::create(L, items[i]); + lua_rawseti(L, -2, i + 1); + } +} + +/******************************************************************************/ +std::vector<ItemStack> read_items(lua_State *L, int index, IGameDef *gdef) +{ + if(index < 0) + index = lua_gettop(L) + 1 + index; + + std::vector<ItemStack> items; + luaL_checktype(L, index, LUA_TTABLE); + lua_pushnil(L); + while (lua_next(L, index)) { + s32 key = luaL_checkinteger(L, -2); + if (key < 1) { + throw LuaError("Invalid inventory list index"); + } + if (items.size() < (u32) key) { + items.resize(key); + } + items[key - 1] = read_item(L, -1, gdef->idef()); + lua_pop(L, 1); + } + return items; +} + +/******************************************************************************/ +void luaentity_get(lua_State *L, u16 id) +{ + // Get luaentities[i] + lua_getglobal(L, "core"); + lua_getfield(L, -1, "luaentities"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_pushinteger(L, id); + lua_gettable(L, -2); + lua_remove(L, -2); // Remove luaentities + lua_remove(L, -2); // Remove core +} + +/******************************************************************************/ +bool read_noiseparams(lua_State *L, int index, NoiseParams *np) +{ + if (index < 0) + index = lua_gettop(L) + 1 + index; + + if (!lua_istable(L, index)) + return false; + + getfloatfield(L, index, "offset", np->offset); + getfloatfield(L, index, "scale", np->scale); + getfloatfield(L, index, "persist", np->persist); + getfloatfield(L, index, "persistence", np->persist); + getfloatfield(L, index, "lacunarity", np->lacunarity); + getintfield(L, index, "seed", np->seed); + getintfield(L, index, "octaves", np->octaves); + + u32 flags = 0; + u32 flagmask = 0; + np->flags = getflagsfield(L, index, "flags", flagdesc_noiseparams, + &flags, &flagmask) ? flags : NOISE_FLAG_DEFAULTS; + + lua_getfield(L, index, "spread"); + np->spread = read_v3f(L, -1); + lua_pop(L, 1); + + return true; +} + +void push_noiseparams(lua_State *L, NoiseParams *np) +{ + lua_newtable(L); + setfloatfield(L, -1, "offset", np->offset); + setfloatfield(L, -1, "scale", np->scale); + setfloatfield(L, -1, "persist", np->persist); + setfloatfield(L, -1, "persistence", np->persist); + setfloatfield(L, -1, "lacunarity", np->lacunarity); + setintfield( L, -1, "seed", np->seed); + setintfield( L, -1, "octaves", np->octaves); + + push_flags_string(L, flagdesc_noiseparams, np->flags, + np->flags); + lua_setfield(L, -2, "flags"); + + push_v3f(L, np->spread); + lua_setfield(L, -2, "spread"); +} + +/******************************************************************************/ +// Returns depth of json value tree +static int push_json_value_getdepth(const Json::Value &value) +{ + if (!value.isArray() && !value.isObject()) + return 1; + + int maxdepth = 0; + for (const auto &it : value) { + int elemdepth = push_json_value_getdepth(it); + if (elemdepth > maxdepth) + maxdepth = elemdepth; + } + return maxdepth + 1; +} +// Recursive function to convert JSON --> Lua table +static bool push_json_value_helper(lua_State *L, const Json::Value &value, + int nullindex) +{ + switch(value.type()) { + case Json::nullValue: + default: + lua_pushvalue(L, nullindex); + break; + case Json::intValue: + lua_pushinteger(L, value.asLargestInt()); + break; + case Json::uintValue: + lua_pushinteger(L, value.asLargestUInt()); + break; + case Json::realValue: + lua_pushnumber(L, value.asDouble()); + break; + case Json::stringValue: + { + const char *str = value.asCString(); + lua_pushstring(L, str ? str : ""); + } + break; + case Json::booleanValue: + lua_pushboolean(L, value.asInt()); + break; + case Json::arrayValue: + lua_createtable(L, value.size(), 0); + for (Json::Value::const_iterator it = value.begin(); + it != value.end(); ++it) { + push_json_value_helper(L, *it, nullindex); + lua_rawseti(L, -2, it.index() + 1); + } + break; + case Json::objectValue: + lua_createtable(L, 0, value.size()); + for (Json::Value::const_iterator it = value.begin(); + it != value.end(); ++it) { +#if !defined(JSONCPP_STRING) && (JSONCPP_VERSION_MAJOR < 1 || JSONCPP_VERSION_MINOR < 9) + const char *str = it.memberName(); + lua_pushstring(L, str ? str : ""); +#else + std::string str = it.name(); + lua_pushstring(L, str.c_str()); +#endif + push_json_value_helper(L, *it, nullindex); + lua_rawset(L, -3); + } + break; + } + return true; +} +// converts JSON --> Lua table; returns false if lua stack limit exceeded +// nullindex: Lua stack index of value to use in place of JSON null +bool push_json_value(lua_State *L, const Json::Value &value, int nullindex) +{ + if(nullindex < 0) + nullindex = lua_gettop(L) + 1 + nullindex; + + int depth = push_json_value_getdepth(value); + + // The maximum number of Lua stack slots used at each recursion level + // of push_json_value_helper is 2, so make sure there a depth * 2 slots + if (lua_checkstack(L, depth * 2)) + return push_json_value_helper(L, value, nullindex); + + return false; +} + +// Converts Lua table --> JSON +void read_json_value(lua_State *L, Json::Value &root, int index, u8 recursion) +{ + if (recursion > 16) { + throw SerializationError("Maximum recursion depth exceeded"); + } + int type = lua_type(L, index); + if (type == LUA_TBOOLEAN) { + root = (bool) lua_toboolean(L, index); + } else if (type == LUA_TNUMBER) { + root = lua_tonumber(L, index); + } else if (type == LUA_TSTRING) { + size_t len; + const char *str = lua_tolstring(L, index, &len); + root = std::string(str, len); + } else if (type == LUA_TTABLE) { + lua_pushnil(L); + while (lua_next(L, index)) { + // Key is at -2 and value is at -1 + Json::Value value; + read_json_value(L, value, lua_gettop(L), recursion + 1); + + Json::ValueType roottype = root.type(); + int keytype = lua_type(L, -1); + if (keytype == LUA_TNUMBER) { + lua_Number key = lua_tonumber(L, -1); + if (roottype != Json::nullValue && roottype != Json::arrayValue) { + throw SerializationError("Can't mix array and object values in JSON"); + } else if (key < 1) { + throw SerializationError("Can't use zero-based or negative indexes in JSON"); + } else if (floor(key) != key) { + throw SerializationError("Can't use indexes with a fractional part in JSON"); + } + root[(Json::ArrayIndex) key - 1] = value; + } else if (keytype == LUA_TSTRING) { + if (roottype != Json::nullValue && roottype != Json::objectValue) { + throw SerializationError("Can't mix array and object values in JSON"); + } + root[lua_tostring(L, -1)] = value; + } else { + throw SerializationError("Lua key to convert to JSON is not a string or number"); + } + } + } else if (type == LUA_TNIL) { + root = Json::nullValue; + } else { + throw SerializationError("Can only store booleans, numbers, strings, objects, arrays, and null in JSON"); + } + lua_pop(L, 1); // Pop value +} + +void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm, + bool hitpoint) +{ + lua_newtable(L); + if (pointed.type == POINTEDTHING_NODE) { + lua_pushstring(L, "node"); + lua_setfield(L, -2, "type"); + push_v3s16(L, pointed.node_undersurface); + lua_setfield(L, -2, "under"); + push_v3s16(L, pointed.node_abovesurface); + lua_setfield(L, -2, "above"); + } else if (pointed.type == POINTEDTHING_OBJECT) { + lua_pushstring(L, "object"); + lua_setfield(L, -2, "type"); + + if (csm) { + lua_pushinteger(L, pointed.object_id); + lua_setfield(L, -2, "id"); + } else { + push_objectRef(L, pointed.object_id); + lua_setfield(L, -2, "ref"); + } + } else { + lua_pushstring(L, "nothing"); + lua_setfield(L, -2, "type"); + } + if (hitpoint && (pointed.type != POINTEDTHING_NOTHING)) { + push_v3f(L, pointed.intersection_point / BS); // convert to node coords + lua_setfield(L, -2, "intersection_point"); + push_v3s16(L, pointed.intersection_normal); + lua_setfield(L, -2, "intersection_normal"); + lua_pushinteger(L, pointed.box_id + 1); // change to Lua array index + lua_setfield(L, -2, "box_id"); + } +} + +void push_objectRef(lua_State *L, const u16 id) +{ + // Get core.object_refs[i] + lua_getglobal(L, "core"); + lua_getfield(L, -1, "object_refs"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_pushinteger(L, id); + lua_gettable(L, -2); + lua_remove(L, -2); // object_refs + lua_remove(L, -2); // core +} + +void read_hud_element(lua_State *L, HudElement *elem) +{ + elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type", + es_HudElementType, HUD_ELEM_TEXT); + + lua_getfield(L, 2, "position"); + elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); + lua_pop(L, 1); + + lua_getfield(L, 2, "scale"); + elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); + lua_pop(L, 1); + + lua_getfield(L, 2, "size"); + elem->size = lua_istable(L, -1) ? read_v2s32(L, -1) : v2s32(); + lua_pop(L, 1); + + elem->name = getstringfield_default(L, 2, "name", ""); + elem->text = getstringfield_default(L, 2, "text", ""); + elem->number = getintfield_default(L, 2, "number", 0); + if (elem->type == HUD_ELEM_WAYPOINT) + // waypoints reuse the item field to store precision, item = precision + 1 + elem->item = getintfield_default(L, 2, "precision", -1) + 1; + else + elem->item = getintfield_default(L, 2, "item", 0); + elem->dir = getintfield_default(L, 2, "direction", 0); + elem->z_index = MYMAX(S16_MIN, MYMIN(S16_MAX, + getintfield_default(L, 2, "z_index", 0))); + elem->text2 = getstringfield_default(L, 2, "text2", ""); + + // Deprecated, only for compatibility's sake + if (elem->dir == 0) + elem->dir = getintfield_default(L, 2, "dir", 0); + + lua_getfield(L, 2, "alignment"); + elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); + lua_pop(L, 1); + + lua_getfield(L, 2, "offset"); + elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); + lua_pop(L, 1); + + lua_getfield(L, 2, "world_pos"); + elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f(); + lua_pop(L, 1); + + elem->style = getintfield_default(L, 2, "style", 0); + + /* check for known deprecated element usage */ + if ((elem->type == HUD_ELEM_STATBAR) && (elem->size == v2s32())) + log_deprecated(L,"Deprecated usage of statbar without size!"); +} + +void push_hud_element(lua_State *L, HudElement *elem) +{ + lua_newtable(L); + + lua_pushstring(L, es_HudElementType[(u8)elem->type].str); + lua_setfield(L, -2, "type"); + + push_v2f(L, elem->pos); + lua_setfield(L, -2, "position"); + + lua_pushstring(L, elem->name.c_str()); + lua_setfield(L, -2, "name"); + + push_v2f(L, elem->scale); + lua_setfield(L, -2, "scale"); + + lua_pushstring(L, elem->text.c_str()); + lua_setfield(L, -2, "text"); + + lua_pushnumber(L, elem->number); + lua_setfield(L, -2, "number"); + + if (elem->type == HUD_ELEM_WAYPOINT) { + // waypoints reuse the item field to store precision, precision = item - 1 + lua_pushnumber(L, elem->item - 1); + lua_setfield(L, -2, "precision"); + } + // push the item field for waypoints as well for backwards compatibility + lua_pushnumber(L, elem->item); + lua_setfield(L, -2, "item"); + + lua_pushnumber(L, elem->dir); + lua_setfield(L, -2, "direction"); + + push_v2f(L, elem->offset); + lua_setfield(L, -2, "offset"); + + push_v2f(L, elem->align); + lua_setfield(L, -2, "alignment"); + + push_v2s32(L, elem->size); + lua_setfield(L, -2, "size"); + + // Deprecated, only for compatibility's sake + lua_pushnumber(L, elem->dir); + lua_setfield(L, -2, "dir"); + + push_v3f(L, elem->world_pos); + lua_setfield(L, -2, "world_pos"); + + lua_pushnumber(L, elem->z_index); + lua_setfield(L, -2, "z_index"); + + lua_pushstring(L, elem->text2.c_str()); + lua_setfield(L, -2, "text2"); + + lua_pushinteger(L, elem->style); + lua_setfield(L, -2, "style"); +} + +bool read_hud_change(lua_State *L, HudElementStat &stat, HudElement *elem, void **value) +{ + std::string statstr = lua_tostring(L, 3); + { + int statint; + if (!string_to_enum(es_HudElementStat, statint, statstr)) { + script_log_unique(L, "Unknown HUD stat type: " + statstr, warningstream); + return false; + } + + stat = (HudElementStat)statint; + } + + switch (stat) { + case HUD_STAT_POS: + elem->pos = read_v2f(L, 4); + *value = &elem->pos; + break; + case HUD_STAT_NAME: + elem->name = luaL_checkstring(L, 4); + *value = &elem->name; + break; + case HUD_STAT_SCALE: + elem->scale = read_v2f(L, 4); + *value = &elem->scale; + break; + case HUD_STAT_TEXT: + elem->text = luaL_checkstring(L, 4); + *value = &elem->text; + break; + case HUD_STAT_NUMBER: + elem->number = luaL_checknumber(L, 4); + *value = &elem->number; + break; + case HUD_STAT_ITEM: + elem->item = luaL_checknumber(L, 4); + if (elem->type == HUD_ELEM_WAYPOINT && statstr == "precision") + elem->item++; + *value = &elem->item; + break; + case HUD_STAT_DIR: + elem->dir = luaL_checknumber(L, 4); + *value = &elem->dir; + break; + case HUD_STAT_ALIGN: + elem->align = read_v2f(L, 4); + *value = &elem->align; + break; + case HUD_STAT_OFFSET: + elem->offset = read_v2f(L, 4); + *value = &elem->offset; + break; + case HUD_STAT_WORLD_POS: + elem->world_pos = read_v3f(L, 4); + *value = &elem->world_pos; + break; + case HUD_STAT_SIZE: + elem->size = read_v2s32(L, 4); + *value = &elem->size; + break; + case HUD_STAT_Z_INDEX: + elem->z_index = MYMAX(S16_MIN, MYMIN(S16_MAX, luaL_checknumber(L, 4))); + *value = &elem->z_index; + break; + case HUD_STAT_TEXT2: + elem->text2 = luaL_checkstring(L, 4); + *value = &elem->text2; + break; + case HUD_STAT_STYLE: + elem->style = luaL_checknumber(L, 4); + *value = &elem->style; + break; + } + + return true; +} + +/******************************************************************************/ + +// Indices must match values in `enum CollisionType` exactly!! +static const char *collision_type_str[] = { + "node", + "object", +}; + +// Indices must match values in `enum CollisionAxis` exactly!! +static const char *collision_axis_str[] = { + "x", + "y", + "z", +}; + +void push_collision_move_result(lua_State *L, const collisionMoveResult &res) +{ + lua_createtable(L, 0, 4); + + setboolfield(L, -1, "touching_ground", res.touching_ground); + setboolfield(L, -1, "collides", res.collides); + setboolfield(L, -1, "standing_on_object", res.standing_on_object); + + /* collisions */ + lua_createtable(L, res.collisions.size(), 0); + int i = 1; + for (const auto &c : res.collisions) { + lua_createtable(L, 0, 5); + + lua_pushstring(L, collision_type_str[c.type]); + lua_setfield(L, -2, "type"); + + assert(c.axis != COLLISION_AXIS_NONE); + lua_pushstring(L, collision_axis_str[c.axis]); + lua_setfield(L, -2, "axis"); + + if (c.type == COLLISION_NODE) { + push_v3s16(L, c.node_p); + lua_setfield(L, -2, "node_pos"); + } else if (c.type == COLLISION_OBJECT) { + push_objectRef(L, c.object->getId()); + lua_setfield(L, -2, "object"); + } + + push_v3f(L, c.old_speed / BS); + lua_setfield(L, -2, "old_velocity"); + + push_v3f(L, c.new_speed / BS); + lua_setfield(L, -2, "new_velocity"); + + lua_rawseti(L, -2, i++); + } + lua_setfield(L, -2, "collisions"); + /**/ +} + + +void push_mod_spec(lua_State *L, const ModSpec &spec, bool include_unsatisfied) +{ + lua_newtable(L); + + lua_pushstring(L, spec.name.c_str()); + lua_setfield(L, -2, "name"); + + lua_pushstring(L, spec.author.c_str()); + lua_setfield(L, -2, "author"); + + lua_pushinteger(L, spec.release); + lua_setfield(L, -2, "release"); + + lua_pushstring(L, spec.desc.c_str()); + lua_setfield(L, -2, "description"); + + lua_pushstring(L, spec.path.c_str()); + lua_setfield(L, -2, "path"); + + lua_pushstring(L, spec.virtual_path.c_str()); + lua_setfield(L, -2, "virtual_path"); + + lua_newtable(L); + int i = 1; + for (const auto &dep : spec.unsatisfied_depends) { + lua_pushstring(L, dep.c_str()); + lua_rawseti(L, -2, i++); + } + lua_setfield(L, -2, "unsatisfied_depends"); +} diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h new file mode 100644 index 0000000..ade3e4c --- /dev/null +++ b/src/script/common/c_content.h @@ -0,0 +1,209 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +/******************************************************************************/ +/******************************************************************************/ +/* WARNING!!!! do NOT add this header in any include file or any code file */ +/* not being a script/modapi file!!!!!!!! */ +/******************************************************************************/ +/******************************************************************************/ + +#pragma once + +extern "C" { +#include <lua.h> +} + +#include <iostream> +#include <vector> + +#include "irrlichttypes_bloated.h" +#include "util/string.h" +#include "itemgroup.h" +#include "itemdef.h" +#include "c_types.h" +// We do a explicit path include because by default c_content.h include src/client/hud.h +// prior to the src/hud.h, which is not good on server only build +#include "../../hud.h" +#include "content/mods.h" + +namespace Json { class Value; } + +struct MapNode; +class NodeDefManager; +struct PointedThing; +struct ItemStack; +struct ItemDefinition; +struct ToolCapabilities; +struct ObjectProperties; +struct SimpleSoundSpec; +struct ServerPlayingSound; +class Inventory; +class InventoryList; +struct NodeBox; +struct ContentFeatures; +struct TileDef; +class IGameDef; +struct DigParams; +struct HitParams; +struct EnumString; +struct NoiseParams; +class Schematic; +class ServerActiveObject; +struct collisionMoveResult; + +extern struct EnumString es_TileAnimationType[]; + +void read_content_features (lua_State *L, ContentFeatures &f, + int index); +void push_content_features (lua_State *L, + const ContentFeatures &c); + +void push_nodebox (lua_State *L, + const NodeBox &box); +void push_box (lua_State *L, + const std::vector<aabb3f> &box); + +void push_palette (lua_State *L, + const std::vector<video::SColor> *palette); + +TileDef read_tiledef (lua_State *L, int index, + u8 drawtype); + +void read_soundspec (lua_State *L, int index, + SimpleSoundSpec &spec); +NodeBox read_nodebox (lua_State *L, int index); + +void read_server_sound_params (lua_State *L, int index, + ServerPlayingSound ¶ms); + +void push_dig_params (lua_State *L, + const DigParams ¶ms); +void push_hit_params (lua_State *L, + const HitParams ¶ms); + +ItemStack read_item (lua_State *L, int index, IItemDefManager *idef); + +struct TileAnimationParams read_animation_definition(lua_State *L, int index); + +ToolCapabilities read_tool_capabilities (lua_State *L, int table); +void push_tool_capabilities (lua_State *L, + const ToolCapabilities &prop); + +void read_item_definition (lua_State *L, int index, const ItemDefinition &default_def, + ItemDefinition &def); +void push_item_definition (lua_State *L, + const ItemDefinition &i); +void push_item_definition_full (lua_State *L, + const ItemDefinition &i); + +void read_object_properties (lua_State *L, int index, + ServerActiveObject *sao, + ObjectProperties *prop, + IItemDefManager *idef); +void push_object_properties (lua_State *L, + ObjectProperties *prop); + +void push_inventory_list (lua_State *L, + const InventoryList &invlist); +void push_inventory_lists (lua_State *L, + const Inventory &inv); +void read_inventory_list (lua_State *L, int tableindex, + Inventory *inv, const char *name, + IGameDef *gdef, int forcesize=-1); + +MapNode readnode (lua_State *L, int index, + const NodeDefManager *ndef); +void pushnode (lua_State *L, const MapNode &n, + const NodeDefManager *ndef); + + +void read_groups (lua_State *L, int index, + ItemGroupList &result); + +void push_groups (lua_State *L, + const ItemGroupList &groups); + +//TODO rename to "read_enum_field" +int getenumfield (lua_State *L, int table, + const char *fieldname, + const EnumString *spec, + int default_); + +bool getflagsfield (lua_State *L, int table, + const char *fieldname, + FlagDesc *flagdesc, + u32 *flags, u32 *flagmask); + +bool read_flags (lua_State *L, int index, + FlagDesc *flagdesc, + u32 *flags, u32 *flagmask); + +void push_flags_string (lua_State *L, FlagDesc *flagdesc, + u32 flags, u32 flagmask); + +u32 read_flags_table (lua_State *L, int table, + FlagDesc *flagdesc, u32 *flagmask); + +void push_items (lua_State *L, + const std::vector<ItemStack> &items); + +std::vector<ItemStack> read_items (lua_State *L, + int index, + IGameDef* gdef); + +void push_soundspec (lua_State *L, + const SimpleSoundSpec &spec); + +bool string_to_enum (const EnumString *spec, + int &result, + const std::string &str); + +bool read_noiseparams (lua_State *L, int index, + NoiseParams *np); +void push_noiseparams (lua_State *L, NoiseParams *np); + +void luaentity_get (lua_State *L,u16 id); + +bool push_json_value (lua_State *L, + const Json::Value &value, + int nullindex); +void read_json_value (lua_State *L, Json::Value &root, + int index, u8 recursion = 0); + +/*! + * Pushes a Lua `pointed_thing` to the given Lua stack. + * \param csm If true, a client side pointed thing is pushed + * \param hitpoint If true, the exact pointing location is also pushed + */ +void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm = + false, bool hitpoint = false); + +void push_objectRef (lua_State *L, const u16 id); + +void read_hud_element (lua_State *L, HudElement *elem); + +void push_hud_element (lua_State *L, HudElement *elem); + +bool read_hud_change (lua_State *L, HudElementStat &stat, HudElement *elem, void **value); + +void push_collision_move_result(lua_State *L, const collisionMoveResult &res); + +void push_mod_spec(lua_State *L, const ModSpec &spec, bool include_unsatisfied); diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp new file mode 100644 index 0000000..69da35b --- /dev/null +++ b/src/script/common/c_converter.cpp @@ -0,0 +1,674 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +} + +#include "util/numeric.h" +#include "util/serialize.h" +#include "util/string.h" +#include "common/c_converter.h" +#include "common/c_internal.h" +#include "constants.h" +#include <set> +#include <cmath> + + +#define CHECK_TYPE(index, name, type) do { \ + int t = lua_type(L, (index)); \ + if (t != (type)) { \ + throw LuaError(std::string("Invalid ") + (name) + \ + " (expected " + lua_typename(L, (type)) + \ + " got " + lua_typename(L, t) + ")."); \ + } \ + } while(0) + +#define CHECK_FLOAT(value, name) do {\ + if (std::isnan(value) || std::isinf(value)) { \ + throw LuaError("Invalid float value for '" name \ + "' (NaN or infinity)"); \ + } \ + } while (0) + +#define CHECK_POS_COORD(name) CHECK_TYPE(-1, "vector coordinate " name, LUA_TNUMBER) +#define CHECK_POS_TAB(index) CHECK_TYPE(index, "vector", LUA_TTABLE) + + +/** + * A helper which sets the vector metatable for the table on top of the stack + */ +static void set_vector_metatable(lua_State *L) +{ + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE); + lua_setmetatable(L, -2); +} + +// Retrieve an integer vector where all components are optional +template<class T> +static bool getv3intfield(lua_State *L, int index, + const char *fieldname, T &result) +{ + lua_getfield(L, index, fieldname); + bool got = false; + if (lua_istable(L, -1)) { + got |= getintfield(L, -1, "x", result.X); + got |= getintfield(L, -1, "y", result.Y); + got |= getintfield(L, -1, "z", result.Z); + } + lua_pop(L, 1); + return got; +} + +void push_v3f(lua_State *L, v3f p) +{ + lua_createtable(L, 0, 3); + lua_pushnumber(L, p.X); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, p.Y); + lua_setfield(L, -2, "y"); + lua_pushnumber(L, p.Z); + lua_setfield(L, -2, "z"); + set_vector_metatable(L); +} + +void push_v2f(lua_State *L, v2f p) +{ + lua_createtable(L, 0, 2); + lua_pushnumber(L, p.X); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, p.Y); + lua_setfield(L, -2, "y"); +} + +v2s16 read_v2s16(lua_State *L, int index) +{ + v2s16 p; + CHECK_POS_TAB(index); + lua_getfield(L, index, "x"); + p.X = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "y"); + p.Y = lua_tonumber(L, -1); + lua_pop(L, 1); + return p; +} + +void push_v2s16(lua_State *L, v2s16 p) +{ + lua_createtable(L, 0, 2); + lua_pushinteger(L, p.X); + lua_setfield(L, -2, "x"); + lua_pushinteger(L, p.Y); + lua_setfield(L, -2, "y"); +} + +void push_v2s32(lua_State *L, v2s32 p) +{ + lua_createtable(L, 0, 2); + lua_pushinteger(L, p.X); + lua_setfield(L, -2, "x"); + lua_pushinteger(L, p.Y); + lua_setfield(L, -2, "y"); +} + +v2s32 read_v2s32(lua_State *L, int index) +{ + v2s32 p; + CHECK_POS_TAB(index); + lua_getfield(L, index, "x"); + p.X = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "y"); + p.Y = lua_tonumber(L, -1); + lua_pop(L, 1); + return p; +} + +v2f read_v2f(lua_State *L, int index) +{ + v2f p; + CHECK_POS_TAB(index); + lua_getfield(L, index, "x"); + p.X = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "y"); + p.Y = lua_tonumber(L, -1); + lua_pop(L, 1); + return p; +} + +v2f check_v2f(lua_State *L, int index) +{ + v2f p; + CHECK_POS_TAB(index); + lua_getfield(L, index, "x"); + CHECK_POS_COORD("x"); + p.X = lua_tonumber(L, -1); + CHECK_FLOAT(p.X, "x"); + lua_pop(L, 1); + lua_getfield(L, index, "y"); + CHECK_POS_COORD("y"); + p.Y = lua_tonumber(L, -1); + CHECK_FLOAT(p.Y, "y"); + lua_pop(L, 1); + return p; +} + +v3f read_v3f(lua_State *L, int index) +{ + v3f pos; + CHECK_POS_TAB(index); + lua_getfield(L, index, "x"); + pos.X = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "y"); + pos.Y = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "z"); + pos.Z = lua_tonumber(L, -1); + lua_pop(L, 1); + return pos; +} + +v3f check_v3f(lua_State *L, int index) +{ + v3f pos; + CHECK_POS_TAB(index); + lua_getfield(L, index, "x"); + CHECK_POS_COORD("x"); + pos.X = lua_tonumber(L, -1); + CHECK_FLOAT(pos.X, "x"); + lua_pop(L, 1); + lua_getfield(L, index, "y"); + CHECK_POS_COORD("y"); + pos.Y = lua_tonumber(L, -1); + CHECK_FLOAT(pos.Y, "y"); + lua_pop(L, 1); + lua_getfield(L, index, "z"); + CHECK_POS_COORD("z"); + pos.Z = lua_tonumber(L, -1); + CHECK_FLOAT(pos.Z, "z"); + lua_pop(L, 1); + return pos; +} + +v3d read_v3d(lua_State *L, int index) +{ + v3d pos; + CHECK_POS_TAB(index); + lua_getfield(L, index, "x"); + pos.X = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "y"); + pos.Y = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "z"); + pos.Z = lua_tonumber(L, -1); + lua_pop(L, 1); + return pos; +} + +v3d check_v3d(lua_State *L, int index) +{ + v3d pos; + CHECK_POS_TAB(index); + lua_getfield(L, index, "x"); + CHECK_POS_COORD("x"); + pos.X = lua_tonumber(L, -1); + CHECK_FLOAT(pos.X, "x"); + lua_pop(L, 1); + lua_getfield(L, index, "y"); + CHECK_POS_COORD("y"); + pos.Y = lua_tonumber(L, -1); + CHECK_FLOAT(pos.Y, "y"); + lua_pop(L, 1); + lua_getfield(L, index, "z"); + CHECK_POS_COORD("z"); + pos.Z = lua_tonumber(L, -1); + CHECK_FLOAT(pos.Z, "z"); + lua_pop(L, 1); + return pos; +} + +void push_ARGB8(lua_State *L, video::SColor color) +{ + lua_createtable(L, 0, 4); + lua_pushinteger(L, color.getAlpha()); + lua_setfield(L, -2, "a"); + lua_pushinteger(L, color.getRed()); + lua_setfield(L, -2, "r"); + lua_pushinteger(L, color.getGreen()); + lua_setfield(L, -2, "g"); + lua_pushinteger(L, color.getBlue()); + lua_setfield(L, -2, "b"); +} + +void pushFloatPos(lua_State *L, v3f p) +{ + p /= BS; + push_v3f(L, p); +} + +v3f checkFloatPos(lua_State *L, int index) +{ + return check_v3f(L, index) * BS; +} + +void push_v3s16(lua_State *L, v3s16 p) +{ + lua_createtable(L, 0, 3); + lua_pushinteger(L, p.X); + lua_setfield(L, -2, "x"); + lua_pushinteger(L, p.Y); + lua_setfield(L, -2, "y"); + lua_pushinteger(L, p.Z); + lua_setfield(L, -2, "z"); + set_vector_metatable(L); +} + +v3s16 read_v3s16(lua_State *L, int index) +{ + // Correct rounding at <0 + v3d pf = read_v3d(L, index); + return doubleToInt(pf, 1.0); +} + +v3s16 check_v3s16(lua_State *L, int index) +{ + // Correct rounding at <0 + v3d pf = check_v3d(L, index); + return doubleToInt(pf, 1.0); +} + +bool read_color(lua_State *L, int index, video::SColor *color) +{ + if (lua_istable(L, index)) { + *color = read_ARGB8(L, index); + } else if (lua_isnumber(L, index)) { + color->set(lua_tonumber(L, index)); + } else if (lua_isstring(L, index)) { + video::SColor parsed_color; + if (!parseColorString(lua_tostring(L, index), parsed_color, true)) + return false; + + *color = parsed_color; + } else { + return false; + } + + return true; +} + +video::SColor read_ARGB8(lua_State *L, int index) +{ + video::SColor color(0); + CHECK_TYPE(index, "ARGB color", LUA_TTABLE); + lua_getfield(L, index, "a"); + color.setAlpha(lua_isnumber(L, -1) ? lua_tonumber(L, -1) : 0xFF); + lua_pop(L, 1); + lua_getfield(L, index, "r"); + color.setRed(lua_tonumber(L, -1)); + lua_pop(L, 1); + lua_getfield(L, index, "g"); + color.setGreen(lua_tonumber(L, -1)); + lua_pop(L, 1); + lua_getfield(L, index, "b"); + color.setBlue(lua_tonumber(L, -1)); + lua_pop(L, 1); + return color; +} + +bool is_color_table(lua_State *L, int index) +{ + // Check whole table in case of missing ColorSpec keys: + // This check does not remove the checked value from the stack. + // Only update the value if we know we have a valid ColorSpec key pair. + if (!lua_istable(L, index)) + return false; + + bool is_color_table = false; + lua_getfield(L, index, "r"); + if (!is_color_table) + is_color_table = lua_isnumber(L, -1); + lua_getfield(L, index, "g"); + if (!is_color_table) + is_color_table = lua_isnumber(L, -1); + lua_getfield(L, index, "b"); + if (!is_color_table) + is_color_table = lua_isnumber(L, -1); + lua_pop(L, 3); // b, g, r values + return is_color_table; +} + +aabb3f read_aabb3f(lua_State *L, int index, f32 scale) +{ + aabb3f box; + if(lua_istable(L, index)){ + lua_rawgeti(L, index, 1); + box.MinEdge.X = lua_tonumber(L, -1) * scale; + lua_pop(L, 1); + lua_rawgeti(L, index, 2); + box.MinEdge.Y = lua_tonumber(L, -1) * scale; + lua_pop(L, 1); + lua_rawgeti(L, index, 3); + box.MinEdge.Z = lua_tonumber(L, -1) * scale; + lua_pop(L, 1); + lua_rawgeti(L, index, 4); + box.MaxEdge.X = lua_tonumber(L, -1) * scale; + lua_pop(L, 1); + lua_rawgeti(L, index, 5); + box.MaxEdge.Y = lua_tonumber(L, -1) * scale; + lua_pop(L, 1); + lua_rawgeti(L, index, 6); + box.MaxEdge.Z = lua_tonumber(L, -1) * scale; + lua_pop(L, 1); + } + box.repair(); + return box; +} + +void push_aabb3f(lua_State *L, aabb3f box) +{ + lua_createtable(L, 6, 0); + lua_pushnumber(L, box.MinEdge.X); + lua_rawseti(L, -2, 1); + lua_pushnumber(L, box.MinEdge.Y); + lua_rawseti(L, -2, 2); + lua_pushnumber(L, box.MinEdge.Z); + lua_rawseti(L, -2, 3); + lua_pushnumber(L, box.MaxEdge.X); + lua_rawseti(L, -2, 4); + lua_pushnumber(L, box.MaxEdge.Y); + lua_rawseti(L, -2, 5); + lua_pushnumber(L, box.MaxEdge.Z); + lua_rawseti(L, -2, 6); +} + +std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale) +{ + std::vector<aabb3f> boxes; + if(lua_istable(L, index)){ + int n = lua_objlen(L, index); + // Check if it's a single box or a list of boxes + bool possibly_single_box = (n == 6); + for(int i = 1; i <= n && possibly_single_box; i++){ + lua_rawgeti(L, index, i); + if(!lua_isnumber(L, -1)) + possibly_single_box = false; + lua_pop(L, 1); + } + if(possibly_single_box){ + // Read a single box + boxes.push_back(read_aabb3f(L, index, scale)); + } else { + // Read a list of boxes + for(int i = 1; i <= n; i++){ + lua_rawgeti(L, index, i); + boxes.push_back(read_aabb3f(L, -1, scale)); + lua_pop(L, 1); + } + } + } + return boxes; +} + +size_t read_stringlist(lua_State *L, int index, std::vector<std::string> *result) +{ + if (index < 0) + index = lua_gettop(L) + 1 + index; + + size_t num_strings = 0; + + if (lua_istable(L, index)) { + lua_pushnil(L); + while (lua_next(L, index)) { + if (lua_isstring(L, -1)) { + result->push_back(lua_tostring(L, -1)); + num_strings++; + } + lua_pop(L, 1); + } + } else if (lua_isstring(L, index)) { + result->push_back(lua_tostring(L, index)); + num_strings++; + } + + return num_strings; +} + +/* + Table field getters +*/ + +bool check_field_or_nil(lua_State *L, int index, int type, const char *fieldname) +{ + thread_local std::set<u64> warned_msgs; + + int t = lua_type(L, index); + if (t == LUA_TNIL) + return false; + + if (t == type) + return true; + + // Check coercion types + if (type == LUA_TNUMBER) { + if (lua_isnumber(L, index)) + return true; + } else if (type == LUA_TSTRING) { + if (lua_isstring(L, index)) + return true; + } + + // Types mismatch. Log unique line. + std::string backtrace = std::string("Invalid field ") + fieldname + + " (expected " + lua_typename(L, type) + + " got " + lua_typename(L, t) + ").\n" + script_get_backtrace(L); + + u64 hash = murmur_hash_64_ua(backtrace.data(), backtrace.length(), 0xBADBABE); + if (warned_msgs.find(hash) == warned_msgs.end()) { + errorstream << backtrace << std::endl; + warned_msgs.insert(hash); + } + + return false; +} + +bool getstringfield(lua_State *L, int table, + const char *fieldname, std::string &result) +{ + lua_getfield(L, table, fieldname); + bool got = false; + + if (check_field_or_nil(L, -1, LUA_TSTRING, fieldname)) { + size_t len = 0; + const char *ptr = lua_tolstring(L, -1, &len); + if (ptr) { + result.assign(ptr, len); + got = true; + } + } + lua_pop(L, 1); + return got; +} + +bool getfloatfield(lua_State *L, int table, + const char *fieldname, float &result) +{ + lua_getfield(L, table, fieldname); + bool got = false; + + if (check_field_or_nil(L, -1, LUA_TNUMBER, fieldname)) { + result = lua_tonumber(L, -1); + got = true; + } + lua_pop(L, 1); + return got; +} + +bool getboolfield(lua_State *L, int table, + const char *fieldname, bool &result) +{ + lua_getfield(L, table, fieldname); + bool got = false; + + if (check_field_or_nil(L, -1, LUA_TBOOLEAN, fieldname)){ + result = lua_toboolean(L, -1); + got = true; + } + lua_pop(L, 1); + return got; +} + +size_t getstringlistfield(lua_State *L, int table, const char *fieldname, + std::vector<std::string> *result) +{ + lua_getfield(L, table, fieldname); + + size_t num_strings_read = read_stringlist(L, -1, result); + + lua_pop(L, 1); + return num_strings_read; +} + +std::string getstringfield_default(lua_State *L, int table, + const char *fieldname, const std::string &default_) +{ + std::string result = default_; + getstringfield(L, table, fieldname, result); + return result; +} + +int getintfield_default(lua_State *L, int table, + const char *fieldname, int default_) +{ + int result = default_; + getintfield(L, table, fieldname, result); + return result; +} + +float getfloatfield_default(lua_State *L, int table, + const char *fieldname, float default_) +{ + float result = default_; + getfloatfield(L, table, fieldname, result); + return result; +} + +bool getboolfield_default(lua_State *L, int table, + const char *fieldname, bool default_) +{ + bool result = default_; + getboolfield(L, table, fieldname, result); + return result; +} + +v3s16 getv3s16field_default(lua_State *L, int table, + const char *fieldname, v3s16 default_) +{ + getv3intfield(L, table, fieldname, default_); + return default_; +} + +void setstringfield(lua_State *L, int table, + const char *fieldname, const std::string &value) +{ + lua_pushlstring(L, value.c_str(), value.length()); + if(table < 0) + table -= 1; + lua_setfield(L, table, fieldname); +} + +void setintfield(lua_State *L, int table, + const char *fieldname, int value) +{ + lua_pushinteger(L, value); + if(table < 0) + table -= 1; + lua_setfield(L, table, fieldname); +} + +void setfloatfield(lua_State *L, int table, + const char *fieldname, float value) +{ + lua_pushnumber(L, value); + if(table < 0) + table -= 1; + lua_setfield(L, table, fieldname); +} + +void setboolfield(lua_State *L, int table, + const char *fieldname, bool value) +{ + lua_pushboolean(L, value); + if(table < 0) + table -= 1; + lua_setfield(L, table, fieldname); +} + + +//// +//// Array table slices +//// + +size_t write_array_slice_float( + lua_State *L, + int table_index, + float *data, + v3u16 data_size, + v3u16 slice_offset, + v3u16 slice_size) +{ + v3u16 pmin, pmax(data_size); + + if (slice_offset.X > 0) { + slice_offset.X--; + pmin.X = slice_offset.X; + pmax.X = MYMIN(slice_offset.X + slice_size.X, data_size.X); + } + + if (slice_offset.Y > 0) { + slice_offset.Y--; + pmin.Y = slice_offset.Y; + pmax.Y = MYMIN(slice_offset.Y + slice_size.Y, data_size.Y); + } + + if (slice_offset.Z > 0) { + slice_offset.Z--; + pmin.Z = slice_offset.Z; + pmax.Z = MYMIN(slice_offset.Z + slice_size.Z, data_size.Z); + } + + const u32 ystride = data_size.X; + const u32 zstride = data_size.X * data_size.Y; + + u32 elem_index = 1; + for (u32 z = pmin.Z; z != pmax.Z; z++) + for (u32 y = pmin.Y; y != pmax.Y; y++) + for (u32 x = pmin.X; x != pmax.X; x++) { + u32 i = z * zstride + y * ystride + x; + lua_pushnumber(L, data[i]); + lua_rawseti(L, table_index, elem_index); + elem_index++; + } + + return elem_index - 1; +} diff --git a/src/script/common/c_converter.h b/src/script/common/c_converter.h new file mode 100644 index 0000000..2af726d --- /dev/null +++ b/src/script/common/c_converter.h @@ -0,0 +1,123 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +/******************************************************************************/ +/******************************************************************************/ +/* WARNING!!!! do NOT add this header in any include file or any code file */ +/* not being a script/modapi file!!!!!!!! */ +/******************************************************************************/ +/******************************************************************************/ +#pragma once + +#include <vector> +#include <unordered_map> + +#include "irrlichttypes_bloated.h" +#include "common/c_types.h" + +extern "C" { +#include <lua.h> +} + +std::string getstringfield_default(lua_State *L, int table, + const char *fieldname, const std::string &default_); +bool getboolfield_default(lua_State *L, int table, + const char *fieldname, bool default_); +float getfloatfield_default(lua_State *L, int table, + const char *fieldname, float default_); +int getintfield_default(lua_State *L, int table, + const char *fieldname, int default_); + +bool check_field_or_nil(lua_State *L, int index, int type, const char *fieldname); + +template<typename T> +bool getintfield(lua_State *L, int table, + const char *fieldname, T &result) +{ + lua_getfield(L, table, fieldname); + bool got = false; + if (check_field_or_nil(L, -1, LUA_TNUMBER, fieldname)){ + result = lua_tointeger(L, -1); + got = true; + } + lua_pop(L, 1); + return got; +} + +// Retrieve an v3s16 where all components are optional (falls back to default) +v3s16 getv3s16field_default(lua_State *L, int table, + const char *fieldname, v3s16 default_); + +bool getstringfield(lua_State *L, int table, + const char *fieldname, std::string &result); +size_t getstringlistfield(lua_State *L, int table, + const char *fieldname, + std::vector<std::string> *result); +void read_groups(lua_State *L, int index, + std::unordered_map<std::string, int> &result); +bool getboolfield(lua_State *L, int table, + const char *fieldname, bool &result); +bool getfloatfield(lua_State *L, int table, + const char *fieldname, float &result); + +void setstringfield(lua_State *L, int table, + const char *fieldname, const std::string &value); +void setintfield(lua_State *L, int table, + const char *fieldname, int value); +void setfloatfield(lua_State *L, int table, + const char *fieldname, float value); +void setboolfield(lua_State *L, int table, + const char *fieldname, bool value); + +v3f checkFloatPos (lua_State *L, int index); +v2f check_v2f (lua_State *L, int index); +v3f check_v3f (lua_State *L, int index); +v3s16 check_v3s16 (lua_State *L, int index); + +v3f read_v3f (lua_State *L, int index); +v2f read_v2f (lua_State *L, int index); +v2s16 read_v2s16 (lua_State *L, int index); +v2s32 read_v2s32 (lua_State *L, int index); +video::SColor read_ARGB8 (lua_State *L, int index); +bool read_color (lua_State *L, int index, + video::SColor *color); +bool is_color_table (lua_State *L, int index); + +aabb3f read_aabb3f (lua_State *L, int index, f32 scale); +v3s16 read_v3s16 (lua_State *L, int index); +std::vector<aabb3f> read_aabb3f_vector (lua_State *L, int index, f32 scale); +size_t read_stringlist (lua_State *L, int index, + std::vector<std::string> *result); + +void push_v2s16 (lua_State *L, v2s16 p); +void push_v2s32 (lua_State *L, v2s32 p); +void push_v3s16 (lua_State *L, v3s16 p); +void push_aabb3f (lua_State *L, aabb3f box); +void push_ARGB8 (lua_State *L, video::SColor color); +void pushFloatPos (lua_State *L, v3f p); +void push_v3f (lua_State *L, v3f p); +void push_v2f (lua_State *L, v2f p); + +void warn_if_field_exists(lua_State *L, int table, + const char *fieldname, + const std::string &message); + +size_t write_array_slice_float(lua_State *L, int table_index, float *data, + v3u16 data_size, v3u16 slice_offset, v3u16 slice_size); diff --git a/src/script/common/c_internal.cpp b/src/script/common/c_internal.cpp new file mode 100644 index 0000000..ddd2d18 --- /dev/null +++ b/src/script/common/c_internal.cpp @@ -0,0 +1,182 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "common/c_internal.h" +#include "util/numeric.h" +#include "debug.h" +#include "log.h" +#include "porting.h" +#include "settings.h" +#include <algorithm> // std::find + +std::string script_get_backtrace(lua_State *L) +{ + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_BACKTRACE); + lua_call(L, 0, 1); + std::string result = luaL_checkstring(L, -1); + lua_pop(L, 1); + return result; +} + +int script_exception_wrapper(lua_State *L, lua_CFunction f) +{ + try { + return f(L); // Call wrapped function and return result. + } catch (const char *s) { // Catch and convert exceptions. + lua_pushstring(L, s); + } catch (std::exception &e) { + lua_pushstring(L, e.what()); + } + return lua_error(L); // Rethrow as a Lua error. +} + +/* + * Note that we can't get tracebacks for LUA_ERRMEM or LUA_ERRERR (without + * hacking Lua internals). For LUA_ERRMEM, this is because memory errors will + * not execute the error handler, and by the time lua_pcall returns the + * execution stack will have already been unwound. For LUA_ERRERR, there was + * another error while trying to generate a backtrace from a LUA_ERRRUN. It is + * presumed there is an error with the internal Lua state and thus not possible + * to gather a coherent backtrace. Realistically, the best we can do here is + * print which C function performed the failing pcall. + */ +void script_error(lua_State *L, int pcall_result, const char *mod, const char *fxn) +{ + if (pcall_result == 0) + return; + + const char *err_type; + switch (pcall_result) { + case LUA_ERRRUN: + err_type = "Runtime"; + break; + case LUA_ERRMEM: + err_type = "OOM"; + break; + case LUA_ERRERR: + err_type = "Double fault"; + break; + default: + err_type = "Unknown"; + } + + if (!mod) + mod = "??"; + + if (!fxn) + fxn = "??"; + + const char *err_descr = lua_tostring(L, -1); + if (!err_descr) + err_descr = "<no description>"; + + char buf[256]; + porting::mt_snprintf(buf, sizeof(buf), "%s error from mod '%s' in callback %s(): ", + err_type, mod, fxn); + + std::string err_msg(buf); + err_msg += err_descr; + + if (pcall_result == LUA_ERRMEM) { + err_msg += "\nCurrent Lua memory usage: " + + itos(lua_gc(L, LUA_GCCOUNT, 0) >> 10) + " MB"; + } + + throw LuaError(err_msg); +} + +static void script_log_add_source(lua_State *L, std::string &message, int stack_depth) +{ + lua_Debug ar; + + if (lua_getstack(L, stack_depth, &ar)) { + FATAL_ERROR_IF(!lua_getinfo(L, "Sl", &ar), "lua_getinfo() failed"); + message.append(" (at " + std::string(ar.short_src) + ":" + + std::to_string(ar.currentline) + ")"); + } else { + message.append(" (at ?:?)"); + } +} + +bool script_log_unique(lua_State *L, std::string message, std::ostream &log_to, + int stack_depth) +{ + thread_local std::vector<u64> logged_messages; + + script_log_add_source(L, message, stack_depth); + u64 hash = murmur_hash_64_ua(message.data(), message.length(), 0xBADBABE); + + if (std::find(logged_messages.begin(), logged_messages.end(), hash) + == logged_messages.end()) { + + logged_messages.emplace_back(hash); + log_to << message << std::endl; + return true; + } + return false; +} + +DeprecatedHandlingMode get_deprecated_handling_mode() +{ + static thread_local bool configured = false; + static thread_local DeprecatedHandlingMode ret = DeprecatedHandlingMode::Ignore; + + // Only read settings on first call + if (!configured) { + std::string value = g_settings->get("deprecated_lua_api_handling"); + if (value == "log") { + ret = DeprecatedHandlingMode::Log; + } else if (value == "error") { + ret = DeprecatedHandlingMode::Error; + } + configured = true; + } + + return ret; +} + +void log_deprecated(lua_State *L, std::string message, int stack_depth) +{ + DeprecatedHandlingMode mode = get_deprecated_handling_mode(); + if (mode == DeprecatedHandlingMode::Ignore) + return; + + script_log_add_source(L, message, stack_depth); + warningstream << message << std::endl; + + if (mode == DeprecatedHandlingMode::Error) + script_error(L, LUA_ERRRUN, NULL, NULL); + else + infostream << script_get_backtrace(L) << std::endl; +} + +void call_string_dump(lua_State *L, int idx) +{ + // Retrieve string.dump from insecure env to avoid it being tampered with + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP); + if (!lua_isnil(L, -1)) + lua_getfield(L, -1, "string"); + else + lua_getglobal(L, "string"); + lua_getfield(L, -1, "dump"); + lua_remove(L, -2); // remove _G + lua_remove(L, -2); // remove 'string' table + lua_pushvalue(L, idx); + lua_call(L, 1, 1); +} diff --git a/src/script/common/c_internal.h b/src/script/common/c_internal.h new file mode 100644 index 0000000..272a399 --- /dev/null +++ b/src/script/common/c_internal.h @@ -0,0 +1,146 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/******************************************************************************/ +/******************************************************************************/ +/* WARNING!!!! do NOT add this header in any include file or any code file */ +/* not being a modapi file!!!!!!!! */ +/******************************************************************************/ +/******************************************************************************/ + +#pragma once + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +} + +#include "config.h" +#include "common/c_types.h" + + +/* + Define our custom indices into the Lua registry table. + + Lua 5.2 and above define the LUA_RIDX_LAST macro. Only numbers above that + may be used for custom indices, anything else is reserved. + + Lua 5.1 / LuaJIT do not use any numeric indices (only string indices), + so we can use numeric indices freely. +*/ +#ifdef LUA_RIDX_LAST +#define CUSTOM_RIDX_BASE ((LUA_RIDX_LAST)+1) +#else +#define CUSTOM_RIDX_BASE 1 +#endif + +#define CUSTOM_RIDX_SCRIPTAPI (CUSTOM_RIDX_BASE) +#define CUSTOM_RIDX_GLOBALS_BACKUP (CUSTOM_RIDX_BASE + 1) +#define CUSTOM_RIDX_CURRENT_MOD_NAME (CUSTOM_RIDX_BASE + 2) +#define CUSTOM_RIDX_BACKTRACE (CUSTOM_RIDX_BASE + 3) +#define CUSTOM_RIDX_HTTP_API_LUA (CUSTOM_RIDX_BASE + 4) +#define CUSTOM_RIDX_VECTOR_METATABLE (CUSTOM_RIDX_BASE + 5) +#define CUSTOM_RIDX_METATABLE_MAP (CUSTOM_RIDX_BASE + 6) + + +// Determine if CUSTOM_RIDX_SCRIPTAPI will hold a light or full userdata +#if defined(__aarch64__) && USE_LUAJIT +/* LuaJIT has a 47-bit limit for lightuserdata on this platform and we cannot + * assume that the ScriptApi class was allocated at a fitting address. */ +#define INDIRECT_SCRIPTAPI_RIDX 1 +#else +#define INDIRECT_SCRIPTAPI_RIDX 0 +#endif + +// Pushes the error handler onto the stack and returns its index +#define PUSH_ERROR_HANDLER(L) \ + (lua_rawgeti((L), LUA_REGISTRYINDEX, CUSTOM_RIDX_BACKTRACE), lua_gettop((L))) + +#define PCALL_RESL(L, RES) { \ + int result_ = (RES); \ + if (result_ != 0) { \ + script_error((L), result_, NULL, __FUNCTION__); \ + } \ +} + +// What script_run_callbacks does with the return values of callbacks. +// Regardless of the mode, if only one callback is defined, +// its return value is the total return value. +// Modes only affect the case where 0 or >= 2 callbacks are defined. +enum RunCallbacksMode +{ + // Returns the return value of the first callback + // Returns nil if list of callbacks is empty + RUN_CALLBACKS_MODE_FIRST, + // Returns the return value of the last callback + // Returns nil if list of callbacks is empty + RUN_CALLBACKS_MODE_LAST, + // If any callback returns a false value, the first such is returned + // Otherwise, the first callback's return value (trueish) is returned + // Returns true if list of callbacks is empty + RUN_CALLBACKS_MODE_AND, + // Like above, but stops calling callbacks (short circuit) + // after seeing the first false value + RUN_CALLBACKS_MODE_AND_SC, + // If any callback returns a true value, the first such is returned + // Otherwise, the first callback's return value (falseish) is returned + // Returns false if list of callbacks is empty + RUN_CALLBACKS_MODE_OR, + // Like above, but stops calling callbacks (short circuit) + // after seeing the first true value + RUN_CALLBACKS_MODE_OR_SC, + // Note: "a true value" and "a false value" refer to values that + // are converted by readParam<bool> to true or false, respectively. +}; + +// Gets a backtrace of the current execution point +std::string script_get_backtrace(lua_State *L); +// Wrapper for CFunction calls that converts C++ exceptions to Lua errors +int script_exception_wrapper(lua_State *L, lua_CFunction f); +// Takes an error from lua_pcall and throws it as a LuaError +void script_error(lua_State *L, int pcall_result, const char *mod, const char *fxn); + +bool script_log_unique(lua_State *L, std::string message, std::ostream &log_to, + int stack_depth = 1); + +enum DeprecatedHandlingMode { + Ignore, + Log, + Error +}; + +/** + * Reads `deprecated_lua_api_handling` in settings, returns cached value. + * + * @return DeprecatedHandlingMode + */ +DeprecatedHandlingMode get_deprecated_handling_mode(); + +/** + * Handles a deprecation warning based on user settings + * + * @param L Lua State + * @param message The deprecation method + * @param stack_depth How far on the stack to the first user function (ie: not builtin or core) + */ +void log_deprecated(lua_State *L, std::string message, int stack_depth = 1); + +// Safely call string.dump on a function value +// (does not pop, leaves one value on stack) +void call_string_dump(lua_State *L, int idx); diff --git a/src/script/common/c_packer.cpp b/src/script/common/c_packer.cpp new file mode 100644 index 0000000..597f5e4 --- /dev/null +++ b/src/script/common/c_packer.cpp @@ -0,0 +1,596 @@ +/* +Minetest +Copyright (C) 2022 sfan5 <sfan5@live.de> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <cstdio> +#include <cstring> +#include <cmath> +#include <cassert> +#include <unordered_set> +#include <unordered_map> +#include "c_packer.h" +#include "c_internal.h" +#include "log.h" +#include "debug.h" +#include "threading/mutex_auto_lock.h" + +extern "C" { +#include <lauxlib.h> +} + +// +// Helpers +// + +// convert negative index to absolute position on Lua stack +static inline int absidx(lua_State *L, int idx) +{ + assert(idx < 0); + return lua_gettop(L) + idx + 1; +} + +// does the type put anything into PackedInstr::sdata? +static inline bool uses_sdata(int type) +{ + switch (type) { + case LUA_TSTRING: + case LUA_TFUNCTION: + case LUA_TUSERDATA: + return true; + default: + return false; + } +} + +// does the type put anything into PackedInstr::<union>? +static inline bool uses_union(int type) +{ + switch (type) { + case LUA_TNIL: + case LUA_TSTRING: + case LUA_TFUNCTION: + return false; + default: + return true; + } +} + +static inline bool can_set_into(int ktype, int vtype) +{ + switch (ktype) { + case LUA_TNUMBER: + return !uses_union(vtype); + case LUA_TSTRING: + return !uses_sdata(vtype); + default: + return false; + } +} + +// is the key suitable for use with set_into? +static inline bool suitable_key(lua_State *L, int idx) +{ + if (lua_type(L, idx) == LUA_TSTRING) { + // strings may not have a NULL byte (-> lua_setfield) + size_t len; + const char *str = lua_tolstring(L, idx, &len); + return strlen(str) == len; + } else { + assert(lua_type(L, idx) == LUA_TNUMBER); + // numbers must fit into an s32 and be integers (-> lua_rawseti) + lua_Number n = lua_tonumber(L, idx); + return std::floor(n) == n && n >= S32_MIN && n <= S32_MAX; + } +} + +namespace { + // checks if you left any values on the stack, for debugging + class StackChecker { + lua_State *L; + int top; + public: + StackChecker(lua_State *L) : L(L), top(lua_gettop(L)) {} + ~StackChecker() { + assert(lua_gettop(L) >= top); + if (lua_gettop(L) > top) { + rawstream << "Lua stack not cleaned up: " + << lua_gettop(L) << " != " << top + << " (false-positive if exception thrown)" << std::endl; + } + } + }; + + // Since an std::vector may reallocate, this is the only safe way to keep + // a reference to a particular element. + template <typename T> + class VectorRef { + std::vector<T> *vec; + size_t idx; + VectorRef(std::vector<T> *vec, size_t idx) : vec(vec), idx(idx) {} + public: + constexpr VectorRef() : vec(nullptr), idx(0) {} + static VectorRef<T> front(std::vector<T> &vec) { + return VectorRef(&vec, 0); + } + static VectorRef<T> back(std::vector<T> &vec) { + return VectorRef(&vec, vec.size() - 1); + } + T &operator*() { return (*vec)[idx]; } + T *operator->() { return &(*vec)[idx]; } + operator bool() const { return vec != nullptr; } + }; + + struct Packer { + PackInFunc fin; + PackOutFunc fout; + }; + + typedef std::pair<std::string, Packer> PackerTuple; +} + +static inline auto emplace(PackedValue &pv, s16 type) +{ + pv.i.emplace_back(); + auto ref = VectorRef<PackedInstr>::back(pv.i); + ref->type = type; + // Initialize fields that may be left untouched + if (type == LUA_TTABLE) { + ref->uidata1 = 0; + ref->uidata2 = 0; + } else if (type == LUA_TUSERDATA) { + ref->ptrdata = nullptr; + } else if (type == INSTR_POP) { + ref->sidata2 = 0; + } + return ref; +} + +// +// Management of registered packers +// + +static std::unordered_map<std::string, Packer> g_packers; +static std::mutex g_packers_lock; + +void script_register_packer(lua_State *L, const char *regname, + PackInFunc fin, PackOutFunc fout) +{ + // Store away callbacks + { + MutexAutoLock autolock(g_packers_lock); + auto it = g_packers.find(regname); + if (it == g_packers.end()) { + auto &ref = g_packers[regname]; + ref.fin = fin; + ref.fout = fout; + } else { + FATAL_ERROR_IF(it->second.fin != fin || it->second.fout != fout, + "Packer registered twice with mismatching callbacks"); + } + } + + // Save metatable so we can identify instances later + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_METATABLE_MAP); + if (lua_isnil(L, -1)) { + lua_newtable(L); + lua_pushvalue(L, -1); + lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_METATABLE_MAP); + } + + luaL_getmetatable(L, regname); + FATAL_ERROR_IF(lua_isnil(L, -1), "No metatable registered with that name"); + + // CUSTOM_RIDX_METATABLE_MAP contains { [metatable] = "regname", ... } + // check first + lua_pushstring(L, regname); + lua_rawget(L, -3); + if (!lua_isnil(L, -1)) { + FATAL_ERROR_IF(lua_topointer(L, -1) != lua_topointer(L, -2), + "Packer registered twice with inconsistent metatable"); + } + lua_pop(L, 1); + // then set + lua_pushstring(L, regname); + lua_rawset(L, -3); + + lua_pop(L, 1); +} + +static bool find_packer(const char *regname, PackerTuple &out) +{ + MutexAutoLock autolock(g_packers_lock); + auto it = g_packers.find(regname); + if (it == g_packers.end()) + return false; + // copy data for thread safety + out.first = it->first; + out.second = it->second; + return true; +} + +static bool find_packer(lua_State *L, int idx, PackerTuple &out) +{ +#ifndef NDEBUG + StackChecker checker(L); +#endif + + // retrieve metatable of the object + if (lua_getmetatable(L, idx) != 1) + return false; + + // use our global table to map it to the registry name + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_METATABLE_MAP); + assert(lua_istable(L, -1)); + lua_pushvalue(L, -2); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { + lua_pop(L, 3); + return false; + } + + // load the associated data + bool found = find_packer(lua_tostring(L, -1), out); + FATAL_ERROR_IF(!found, "Inconsistent internal state"); + lua_pop(L, 3); + return true; +} + +// +// Packing implementation +// + +static VectorRef<PackedInstr> record_object(lua_State *L, int idx, PackedValue &pv, + std::unordered_map<const void *, s32> &seen) +{ + const void *ptr = lua_topointer(L, idx); + assert(ptr); + auto found = seen.find(ptr); + if (found == seen.end()) { + seen[ptr] = pv.i.size(); + return VectorRef<PackedInstr>(); + } + s32 ref = found->second; + assert(ref < (s32)pv.i.size()); + // reuse the value from first time + auto r = emplace(pv, INSTR_PUSHREF); + r->ref = ref; + pv.i[ref].keep_ref = true; + return r; +} + +static VectorRef<PackedInstr> pack_inner(lua_State *L, int idx, int vidx, PackedValue &pv, + std::unordered_map<const void *, s32> &seen) +{ +#ifndef NDEBUG + StackChecker checker(L); + assert(idx > 0); + assert(vidx > 0); +#endif + + switch (lua_type(L, idx)) { + case LUA_TNONE: + case LUA_TNIL: + return emplace(pv, LUA_TNIL); + case LUA_TBOOLEAN: { + auto r = emplace(pv, LUA_TBOOLEAN); + r->bdata = lua_toboolean(L, idx); + return r; + } + case LUA_TNUMBER: { + auto r = emplace(pv, LUA_TNUMBER); + r->ndata = lua_tonumber(L, idx); + return r; + } + case LUA_TSTRING: { + auto r = emplace(pv, LUA_TSTRING); + size_t len; + const char *str = lua_tolstring(L, idx, &len); + assert(str); + r->sdata.assign(str, len); + return r; + } + case LUA_TTABLE: { + auto r = record_object(L, idx, pv, seen); + if (r) + return r; + break; // execution continues + } + case LUA_TFUNCTION: { + auto r = record_object(L, idx, pv, seen); + if (r) + return r; + r = emplace(pv, LUA_TFUNCTION); + call_string_dump(L, idx); + size_t len; + const char *str = lua_tolstring(L, -1, &len); + assert(str); + r->sdata.assign(str, len); + lua_pop(L, 1); + return r; + } + case LUA_TUSERDATA: { + auto r = record_object(L, idx, pv, seen); + if (r) + return r; + PackerTuple ser; + if (!find_packer(L, idx, ser)) + throw LuaError("Cannot serialize unsupported userdata"); + pv.contains_userdata = true; + r = emplace(pv, LUA_TUSERDATA); + r->sdata = ser.first; + r->ptrdata = ser.second.fin(L, idx); + return r; + } + default: { + std::string err = "Cannot serialize type "; + err += lua_typename(L, lua_type(L, idx)); + throw LuaError(err); + } + } + + // LUA_TTABLE + lua_checkstack(L, 5); + + auto rtable = emplace(pv, LUA_TTABLE); + const int vi_table = vidx++; + + lua_pushnil(L); + while (lua_next(L, idx) != 0) { + // key at -2, value at -1 + const int ktype = lua_type(L, -2), vtype = lua_type(L, -1); + if (ktype == LUA_TNUMBER) + rtable->uidata1++; // narr + else + rtable->uidata2++; // nrec + + // check if we can use a shortcut + if (can_set_into(ktype, vtype) && suitable_key(L, -2)) { + // push only the value + auto rval = pack_inner(L, absidx(L, -1), vidx, pv, seen); + rval->pop = rval->type != LUA_TTABLE; + // and where to put it: + rval->set_into = vi_table; + if (ktype == LUA_TSTRING) + rval->sdata = lua_tostring(L, -2); + else + rval->sidata1 = lua_tointeger(L, -2); + // pop tables after the fact + if (!rval->pop) { + auto ri1 = emplace(pv, INSTR_POP); + ri1->sidata1 = vidx; + } + } else { + // push the key and value + pack_inner(L, absidx(L, -2), vidx, pv, seen); + vidx++; + pack_inner(L, absidx(L, -1), vidx, pv, seen); + vidx++; + // push an instruction to set them + auto ri1 = emplace(pv, INSTR_SETTABLE); + ri1->set_into = vi_table; + ri1->sidata1 = vidx - 2; + ri1->sidata2 = vidx - 1; + ri1->pop = true; + vidx -= 2; + } + + lua_pop(L, 1); + } + + assert(vidx == vi_table + 1); + return rtable; +} + +PackedValue *script_pack(lua_State *L, int idx) +{ + if (idx < 0) + idx = absidx(L, idx); + + PackedValue pv; + std::unordered_map<const void *, s32> seen; + pack_inner(L, idx, 1, pv, seen); + + return new PackedValue(std::move(pv)); +} + +// +// Unpacking implementation +// + +void script_unpack(lua_State *L, PackedValue *pv) +{ + lua_newtable(L); // table at index top to track ref indices -> objects + const int top = lua_gettop(L); + int ctr = 0; + + for (size_t packed_idx = 0; packed_idx < pv->i.size(); packed_idx++) { + auto &i = pv->i[packed_idx]; + + // If leaving values on stack make sure there's space (every 5th iteration) + if (!i.pop && (ctr++) >= 5) { + lua_checkstack(L, 5); + ctr = 0; + } + + switch (i.type) { + /* Instructions */ + case INSTR_SETTABLE: + lua_pushvalue(L, top + i.sidata1); // key + lua_pushvalue(L, top + i.sidata2); // value + lua_rawset(L, top + i.set_into); + if (i.pop) { + if (i.sidata1 != i.sidata2) { + // removing moves indices so pop higher index first + lua_remove(L, top + std::max(i.sidata1, i.sidata2)); + lua_remove(L, top + std::min(i.sidata1, i.sidata2)); + } else { + lua_remove(L, top + i.sidata1); + } + } + continue; + case INSTR_POP: + lua_remove(L, top + i.sidata1); + if (i.sidata2 > 0) + lua_remove(L, top + i.sidata2); + continue; + case INSTR_PUSHREF: + lua_pushinteger(L, i.ref); + lua_rawget(L, top); + break; + + /* Lua types */ + case LUA_TNIL: + lua_pushnil(L); + break; + case LUA_TBOOLEAN: + lua_pushboolean(L, i.bdata); + break; + case LUA_TNUMBER: + lua_pushnumber(L, i.ndata); + break; + case LUA_TSTRING: + lua_pushlstring(L, i.sdata.data(), i.sdata.size()); + break; + case LUA_TTABLE: + lua_createtable(L, i.uidata1, i.uidata2); + break; + case LUA_TFUNCTION: + luaL_loadbuffer(L, i.sdata.data(), i.sdata.size(), nullptr); + break; + case LUA_TUSERDATA: { + PackerTuple ser; + sanity_check(find_packer(i.sdata.c_str(), ser)); + ser.second.fout(L, i.ptrdata); + i.ptrdata = nullptr; // ownership taken by callback + break; + } + + default: + assert(0); + break; + } + + if (i.keep_ref) { + lua_pushinteger(L, packed_idx); + lua_pushvalue(L, -2); + lua_rawset(L, top); + } + + if (i.set_into) { + if (!i.pop) + lua_pushvalue(L, -1); + if (uses_sdata(i.type)) + lua_rawseti(L, top + i.set_into, i.sidata1); + else + lua_setfield(L, top + i.set_into, i.sdata.c_str()); + } else { + if (i.pop) + lua_pop(L, 1); + } + } + + // as part of the unpacking process we take ownership of all userdata + pv->contains_userdata = false; + // leave exactly one value on the stack + lua_settop(L, top+1); + lua_remove(L, top); +} + +// +// PackedValue +// + +PackedValue::~PackedValue() +{ + if (!contains_userdata) + return; + for (auto &i : this->i) { + if (i.type == LUA_TUSERDATA && i.ptrdata) { + PackerTuple ser; + if (find_packer(i.sdata.c_str(), ser)) { + // tell it to deallocate object + ser.second.fout(nullptr, i.ptrdata); + } else { + assert(false); + } + } + } +} + +// +// script_dump_packed +// + +#ifndef NDEBUG +void script_dump_packed(const PackedValue *val) +{ + printf("instruction stream: [\n"); + for (const auto &i : val->i) { + printf("\t("); + switch (i.type) { + case INSTR_SETTABLE: + printf("SETTABLE(%d, %d)", i.sidata1, i.sidata2); + break; + case INSTR_POP: + printf(i.sidata2 ? "POP(%d, %d)" : "POP(%d)", i.sidata1, i.sidata2); + break; + case INSTR_PUSHREF: + printf("PUSHREF(%d)", i.ref); + break; + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(i.bdata ? "true" : "false"); + break; + case LUA_TNUMBER: + printf("%f", i.ndata); + break; + case LUA_TSTRING: + printf("\"%s\"", i.sdata.c_str()); + break; + case LUA_TTABLE: + printf("table(%d, %d)", i.uidata1, i.uidata2); + break; + case LUA_TFUNCTION: + printf("function(%lu byte)", i.sdata.size()); + break; + case LUA_TUSERDATA: + printf("userdata %s %p", i.sdata.c_str(), i.ptrdata); + break; + default: + printf("!!UNKNOWN!!"); + break; + } + if (i.set_into) { + if (i.type >= 0 && uses_sdata(i.type)) + printf(", k=%d, into=%d", i.sidata1, i.set_into); + else if (i.type >= 0) + printf(", k=\"%s\", into=%d", i.sdata.c_str(), i.set_into); + else + printf(", into=%d", i.set_into); + } + if (i.keep_ref) + printf(", keep_ref"); + if (i.pop) + printf(", pop"); + printf(")\n"); + } + printf("]\n"); +} +#endif diff --git a/src/script/common/c_packer.h b/src/script/common/c_packer.h new file mode 100644 index 0000000..fe072c1 --- /dev/null +++ b/src/script/common/c_packer.h @@ -0,0 +1,126 @@ +/* +Minetest +Copyright (C) 2022 sfan5 <sfan5@live.de> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <vector> +#include "irrlichttypes.h" +#include "util/basic_macros.h" + +extern "C" { +#include <lua.h> +} + +/* + This file defines an in-memory representation of Lua objects including + support for functions and userdata. It it used to move data between Lua + states and cannot be used for persistence or network transfer. +*/ + +#define INSTR_SETTABLE (-10) +#define INSTR_POP (-11) +#define INSTR_PUSHREF (-12) + +/** + * Represents a single instruction that pushes a new value or works with existing ones. + */ +struct PackedInstr +{ + s16 type; // LUA_T* or INSTR_* + u16 set_into; // set into table on stack + bool keep_ref; // is referenced later by INSTR_PUSHREF? + bool pop; // remove from stack? + union { + bool bdata; // boolean: value + lua_Number ndata; // number: value + struct { + u16 uidata1, uidata2; // table: narr, nrec + }; + struct { + /* + SETTABLE: key index, value index + POP: indices to remove + otherwise w/ set_into: numeric key, - + */ + s32 sidata1, sidata2; + }; + void *ptrdata; // userdata: implementation defined + s32 ref; // PUSHREF: index of referenced instr + }; + /* + - string: value + - function: buffer + - w/ set_into: string key (no null bytes!) + - userdata: name in registry + */ + std::string sdata; + + PackedInstr() : type(0), set_into(0), keep_ref(false), pop(false) {} +}; + +/** + * A packed value can be a primitive like a string or number but also a table + * including all of its contents. It is made up of a linear stream of + * 'instructions' that build the final value when executed. + */ +struct PackedValue +{ + std::vector<PackedInstr> i; + // Indicates whether there are any userdata pointers that need to be deallocated + bool contains_userdata = false; + + PackedValue() = default; + ~PackedValue(); + + DISABLE_CLASS_COPY(PackedValue) + + ALLOW_CLASS_MOVE(PackedValue) +}; + +/* + * Packing callback: Turns a Lua value at given index into a void* + */ +typedef void *(*PackInFunc)(lua_State *L, int idx); +/* + * Unpacking callback: Turns a void* back into the Lua value (left on top of stack) + * + * Note that this function must take ownership of the pointer, so make sure + * to free or keep the memory. + * `L` can be nullptr to indicate that data should just be discarded. + */ +typedef void (*PackOutFunc)(lua_State *L, void *ptr); +/* + * Register a packable type with the name of its metatable. + * + * Even though the callbacks are global this must be called for every Lua state + * that supports objects of this type. + * This function is thread-safe. + */ +void script_register_packer(lua_State *L, const char *regname, + PackInFunc fin, PackOutFunc fout); + +// Pack a Lua value +PackedValue *script_pack(lua_State *L, int idx); +// Unpack a Lua value (left on top of stack) +// Note that this may modify the PackedValue, reusability is not guaranteed! +void script_unpack(lua_State *L, PackedValue *val); + +// Dump contents of PackedValue to stdout for debugging +void script_dump_packed(const PackedValue *val); diff --git a/src/script/common/c_types.cpp b/src/script/common/c_types.cpp new file mode 100644 index 0000000..e832ff2 --- /dev/null +++ b/src/script/common/c_types.cpp @@ -0,0 +1,34 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <iostream> + +#include "common/c_types.h" +#include "common/c_internal.h" +#include "itemdef.h" + + +struct EnumString es_ItemType[] = + { + {ITEM_NONE, "none"}, + {ITEM_NODE, "node"}, + {ITEM_CRAFT, "craft"}, + {ITEM_TOOL, "tool"}, + {0, NULL}, + }; diff --git a/src/script/common/c_types.h b/src/script/common/c_types.h new file mode 100644 index 0000000..86bfb0b --- /dev/null +++ b/src/script/common/c_types.h @@ -0,0 +1,61 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +extern "C" { +#include "lua.h" +} + +#include <iostream> + +#include "exceptions.h" + +struct EnumString +{ + int num; + const char *str; +}; + +class StackUnroller +{ +private: + lua_State *m_lua; + int m_original_top; +public: + StackUnroller(lua_State *L): + m_lua(L), + m_original_top(-1) + { + m_original_top = lua_gettop(m_lua); // store stack height + } + ~StackUnroller() + { + lua_settop(m_lua, m_original_top); // restore stack height + } +}; + +class LuaError : public ModError +{ +public: + LuaError(const std::string &s) : ModError(s) {} +}; + + +extern EnumString es_ItemType[]; diff --git a/src/script/common/helper.cpp b/src/script/common/helper.cpp new file mode 100644 index 0000000..72de2b1 --- /dev/null +++ b/src/script/common/helper.cpp @@ -0,0 +1,88 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +extern "C" { +#include <lauxlib.h> +} + +#include "helper.h" +#include <cmath> +#include <irr_v2d.h> +#include <irr_v3d.h> +#include "c_converter.h" +#include "c_types.h" + +/* + * Read template functions + */ +template <> +bool LuaHelper::readParam(lua_State *L, int index) +{ + return lua_toboolean(L, index) != 0; +} + +template <> +s16 LuaHelper::readParam(lua_State *L, int index) +{ + return luaL_checkinteger(L, index); +} + +template <> +int LuaHelper::readParam(lua_State *L, int index) +{ + return luaL_checkinteger(L, index); +} + +template <> +float LuaHelper::readParam(lua_State *L, int index) +{ + lua_Number v = luaL_checknumber(L, index); + if (std::isnan(v) && std::isinf(v)) + throw LuaError("Invalid float value (NaN or infinity)"); + + return static_cast<float>(v); +} + +template <> +v2s16 LuaHelper::readParam(lua_State *L, int index) +{ + return read_v2s16(L, index); +} + +template <> +v2f LuaHelper::readParam(lua_State *L, int index) +{ + return check_v2f(L, index); +} + +template <> +v3f LuaHelper::readParam(lua_State *L, int index) +{ + return check_v3f(L, index); +} + +template <> +std::string LuaHelper::readParam(lua_State *L, int index) +{ + size_t length; + std::string result; + const char *str = luaL_checklstring(L, index, &length); + result.assign(str, length); + return result; +} diff --git a/src/script/common/helper.h b/src/script/common/helper.h new file mode 100644 index 0000000..fc462b6 --- /dev/null +++ b/src/script/common/helper.h @@ -0,0 +1,55 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +extern "C" { +#include <lua.h> +} + +class LuaHelper +{ +protected: + /** + * Read a value using a template type T from Lua State L and index + * + * + * @tparam T type to read from Lua + * @param L Lua state + * @param index Lua Index to read + * @return read value from Lua + */ + template <typename T> + static T readParam(lua_State *L, int index); + + /** + * Read a value using a template type T from Lua State L and index + * + * @tparam T type to read from Lua + * @param L Lua state + * @param index Lua Index to read + * @param default_value default value to apply if nil + * @return read value from Lua or default value if nil + */ + template <typename T> + static inline T readParam(lua_State *L, int index, const T &default_value) + { + return lua_isnoneornil(L, index) ? default_value : readParam<T>(L, index); + } +}; diff --git a/src/script/cpp_api/CMakeLists.txt b/src/script/cpp_api/CMakeLists.txt new file mode 100644 index 0000000..3cfd770 --- /dev/null +++ b/src/script/cpp_api/CMakeLists.txt @@ -0,0 +1,20 @@ +set(common_SCRIPT_CPP_API_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/s_async.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_base.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_entity.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_env.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_inventory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_item.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_modchannels.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_node.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_nodemeta.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_player.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_security.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_server.cpp + PARENT_SCOPE) + +set(client_SCRIPT_CPP_API_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/s_client.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/s_mainmenu.cpp + PARENT_SCOPE) + diff --git a/src/script/cpp_api/s_async.cpp b/src/script/cpp_api/s_async.cpp new file mode 100644 index 0000000..42a794c --- /dev/null +++ b/src/script/cpp_api/s_async.cpp @@ -0,0 +1,389 @@ +/* +Minetest +Copyright (C) 2013 sapier, <sapier AT gmx DOT net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <cstdio> +#include <cstdlib> + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} + +#include "server.h" +#include "s_async.h" +#include "log.h" +#include "filesys.h" +#include "porting.h" +#include "common/c_internal.h" +#include "common/c_packer.h" +#include "lua_api/l_base.h" + +/******************************************************************************/ +AsyncEngine::~AsyncEngine() +{ + // Request all threads to stop + for (AsyncWorkerThread *workerThread : workerThreads) { + workerThread->stop(); + } + + // Wake up all threads + for (auto it : workerThreads) { + (void)it; + jobQueueCounter.post(); + } + + // Wait for threads to finish + for (AsyncWorkerThread *workerThread : workerThreads) { + workerThread->wait(); + } + + // Force kill all threads + for (AsyncWorkerThread *workerThread : workerThreads) { + delete workerThread; + } + + jobQueueMutex.lock(); + jobQueue.clear(); + jobQueueMutex.unlock(); + workerThreads.clear(); +} + +/******************************************************************************/ +void AsyncEngine::registerStateInitializer(StateInitializer func) +{ + FATAL_ERROR_IF(initDone, "Initializer may not be registered after init"); + stateInitializers.push_back(func); +} + +/******************************************************************************/ +void AsyncEngine::initialize(unsigned int numEngines) +{ + initDone = true; + + if (numEngines == 0) { + // Leave one core for the main thread and one for whatever else + autoscaleMaxWorkers = Thread::getNumberOfProcessors(); + if (autoscaleMaxWorkers >= 2) + autoscaleMaxWorkers -= 2; + infostream << "AsyncEngine: using at most " << autoscaleMaxWorkers + << " threads with automatic scaling" << std::endl; + + addWorkerThread(); + } else { + for (unsigned int i = 0; i < numEngines; i++) + addWorkerThread(); + } +} + +void AsyncEngine::addWorkerThread() +{ + AsyncWorkerThread *toAdd = new AsyncWorkerThread(this, + std::string("AsyncWorker-") + itos(workerThreads.size())); + workerThreads.push_back(toAdd); + toAdd->start(); +} + +/******************************************************************************/ +u32 AsyncEngine::queueAsyncJob(std::string &&func, std::string &¶ms, + const std::string &mod_origin) +{ + MutexAutoLock autolock(jobQueueMutex); + u32 jobId = jobIdCounter++; + + jobQueue.emplace_back(); + auto &to_add = jobQueue.back(); + to_add.id = jobId; + to_add.function = std::move(func); + to_add.params = std::move(params); + to_add.mod_origin = mod_origin; + + jobQueueCounter.post(); + return jobId; +} + +u32 AsyncEngine::queueAsyncJob(std::string &&func, PackedValue *params, + const std::string &mod_origin) +{ + MutexAutoLock autolock(jobQueueMutex); + u32 jobId = jobIdCounter++; + + jobQueue.emplace_back(); + auto &to_add = jobQueue.back(); + to_add.id = jobId; + to_add.function = std::move(func); + to_add.params_ext.reset(params); + to_add.mod_origin = mod_origin; + + jobQueueCounter.post(); + return jobId; +} + +/******************************************************************************/ +bool AsyncEngine::getJob(LuaJobInfo *job) +{ + jobQueueCounter.wait(); + jobQueueMutex.lock(); + + bool retval = false; + + if (!jobQueue.empty()) { + *job = std::move(jobQueue.front()); + jobQueue.pop_front(); + retval = true; + } + jobQueueMutex.unlock(); + + return retval; +} + +/******************************************************************************/ +void AsyncEngine::putJobResult(LuaJobInfo &&result) +{ + resultQueueMutex.lock(); + resultQueue.emplace_back(std::move(result)); + resultQueueMutex.unlock(); +} + +/******************************************************************************/ +void AsyncEngine::step(lua_State *L) +{ + stepJobResults(L); + stepAutoscale(); +} + +void AsyncEngine::stepJobResults(lua_State *L) +{ + int error_handler = PUSH_ERROR_HANDLER(L); + lua_getglobal(L, "core"); + + ScriptApiBase *script = ModApiBase::getScriptApiBase(L); + + MutexAutoLock autolock(resultQueueMutex); + while (!resultQueue.empty()) { + LuaJobInfo j = std::move(resultQueue.front()); + resultQueue.pop_front(); + + lua_getfield(L, -1, "async_event_handler"); + if (lua_isnil(L, -1)) + FATAL_ERROR("Async event handler does not exist!"); + luaL_checktype(L, -1, LUA_TFUNCTION); + + lua_pushinteger(L, j.id); + if (j.result_ext) + script_unpack(L, j.result_ext.get()); + else + lua_pushlstring(L, j.result.data(), j.result.size()); + + // Call handler + const char *origin = j.mod_origin.empty() ? nullptr : j.mod_origin.c_str(); + script->setOriginDirect(origin); + int result = lua_pcall(L, 2, 0, error_handler); + if (result) + script_error(L, result, origin, "<async>"); + } + + lua_pop(L, 2); // Pop core and error handler +} + +void AsyncEngine::stepAutoscale() +{ + if (workerThreads.size() >= autoscaleMaxWorkers) + return; + + MutexAutoLock autolock(jobQueueMutex); + + // 2) If the timer elapsed, check again + if (autoscaleTimer && porting::getTimeMs() >= autoscaleTimer) { + autoscaleTimer = 0; + // Determine overlap with previous snapshot + unsigned int n = 0; + for (const auto &it : jobQueue) + n += autoscaleSeenJobs.count(it.id); + autoscaleSeenJobs.clear(); + infostream << "AsyncEngine: " << n << " jobs were still waiting after 1s" << std::endl; + // Start this many new threads + while (workerThreads.size() < autoscaleMaxWorkers && n > 0) { + addWorkerThread(); + n--; + } + return; + } + + // 1) Check if there's anything in the queue + if (!autoscaleTimer && !jobQueue.empty()) { + // Take a snapshot of all jobs we have seen + for (const auto &it : jobQueue) + autoscaleSeenJobs.emplace(it.id); + // and set a timer for 1 second + autoscaleTimer = porting::getTimeMs() + 1000; + } +} + +/******************************************************************************/ +bool AsyncEngine::prepareEnvironment(lua_State* L, int top) +{ + for (StateInitializer &stateInitializer : stateInitializers) { + stateInitializer(L, top); + } + + auto *script = ModApiBase::getScriptApiBase(L); + try { + script->loadMod(Server::getBuiltinLuaPath() + DIR_DELIM + "init.lua", + BUILTIN_MOD_NAME); + } catch (const ModError &e) { + errorstream << "Execution of async base environment failed: " + << e.what() << std::endl; + FATAL_ERROR("Execution of async base environment failed"); + } + + // Load per mod stuff + if (server) { + const auto &list = server->m_async_init_files; + try { + for (auto &it : list) + script->loadMod(it.second, it.first); + } catch (const ModError &e) { + errorstream << "Failed to load mod script inside async environment." << std::endl; + server->setAsyncFatalError(e.what()); + return false; + } + } + + return true; +} + +/******************************************************************************/ +AsyncWorkerThread::AsyncWorkerThread(AsyncEngine* jobDispatcher, + const std::string &name) : + ScriptApiBase(ScriptingType::Async), + Thread(name), + jobDispatcher(jobDispatcher) +{ + lua_State *L = getStack(); + + if (jobDispatcher->server) { + setGameDef(jobDispatcher->server); + + if (g_settings->getBool("secure.enable_security")) + initializeSecurity(); + } + + // Prepare job lua environment + lua_getglobal(L, "core"); + int top = lua_gettop(L); + + // Push builtin initialization type + lua_pushstring(L, jobDispatcher->server ? "async_game" : "async"); + lua_setglobal(L, "INIT"); + + if (!jobDispatcher->prepareEnvironment(L, top)) { + // can't throw from here so we're stuck with this + isErrored = true; + } +} + +/******************************************************************************/ +AsyncWorkerThread::~AsyncWorkerThread() +{ + sanity_check(!isRunning()); +} + +/******************************************************************************/ +void* AsyncWorkerThread::run() +{ + if (isErrored) + return nullptr; + + lua_State *L = getStack(); + + int error_handler = PUSH_ERROR_HANDLER(L); + + auto report_error = [this] (const ModError &e) { + if (jobDispatcher->server) + jobDispatcher->server->setAsyncFatalError(e.what()); + else + errorstream << e.what() << std::endl; + }; + + lua_getglobal(L, "core"); + if (lua_isnil(L, -1)) { + FATAL_ERROR("Unable to find core within async environment!"); + } + + // Main loop + LuaJobInfo j; + while (!stopRequested()) { + // Wait for job + if (!jobDispatcher->getJob(&j) || stopRequested()) + continue; + + const bool use_ext = !!j.params_ext; + + lua_getfield(L, -1, "job_processor"); + if (lua_isnil(L, -1)) + FATAL_ERROR("Unable to get async job processor!"); + luaL_checktype(L, -1, LUA_TFUNCTION); + + if (luaL_loadbuffer(L, j.function.data(), j.function.size(), "=(async)")) { + errorstream << "ASYNC WORKER: Unable to deserialize function" << std::endl; + lua_pushnil(L); + } + if (use_ext) + script_unpack(L, j.params_ext.get()); + else + lua_pushlstring(L, j.params.data(), j.params.size()); + + // Call it + setOriginDirect(j.mod_origin.empty() ? nullptr : j.mod_origin.c_str()); + int result = lua_pcall(L, 2, 1, error_handler); + if (result) { + try { + scriptError(result, "<async>"); + } catch (const ModError &e) { + report_error(e); + } + } else { + // Fetch result + if (use_ext) { + try { + j.result_ext.reset(script_pack(L, -1)); + } catch (const ModError &e) { + report_error(e); + result = LUA_ERRERR; + } + } else { + size_t length; + const char *retval = lua_tolstring(L, -1, &length); + j.result.assign(retval, length); + } + } + + lua_pop(L, 1); // Pop retval + + // Put job result + if (result == 0) + jobDispatcher->putJobResult(std::move(j)); + } + + lua_pop(L, 2); // Pop core and error handler + + return 0; +} + diff --git a/src/script/cpp_api/s_async.h b/src/script/cpp_api/s_async.h new file mode 100644 index 0000000..1e34e40 --- /dev/null +++ b/src/script/cpp_api/s_async.h @@ -0,0 +1,197 @@ +/* +Minetest +Copyright (C) 2013 sapier, <sapier AT gmx DOT net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <vector> +#include <deque> +#include <unordered_set> +#include <memory> + +#include <lua.h> +#include "threading/semaphore.h" +#include "threading/thread.h" +#include "common/c_packer.h" +#include "cpp_api/s_base.h" +#include "cpp_api/s_security.h" + +// Forward declarations +class AsyncEngine; + + +// Declarations + +// Data required to queue a job +struct LuaJobInfo +{ + LuaJobInfo() = default; + + // Function to be called in async environment (from string.dump) + std::string function; + // Parameter to be passed to function (serialized) + std::string params; + // Alternative parameters + std::unique_ptr<PackedValue> params_ext; + // Result of function call (serialized) + std::string result; + // Alternative result + std::unique_ptr<PackedValue> result_ext; + // Name of the mod who invoked this call + std::string mod_origin; + // JobID used to identify a job and match it to callback + u32 id; +}; + +// Asynchronous working environment +class AsyncWorkerThread : public Thread, + virtual public ScriptApiBase, public ScriptApiSecurity { + friend class AsyncEngine; +public: + virtual ~AsyncWorkerThread(); + + void *run(); + +protected: + AsyncWorkerThread(AsyncEngine* jobDispatcher, const std::string &name); + +private: + AsyncEngine *jobDispatcher = nullptr; + bool isErrored = false; +}; + +// Asynchornous thread and job management +class AsyncEngine { + friend class AsyncWorkerThread; + typedef void (*StateInitializer)(lua_State *L, int top); +public: + AsyncEngine() = default; + AsyncEngine(Server *server) : server(server) {}; + ~AsyncEngine(); + + /** + * Register function to be called on new states + * @param func C function to be called + */ + void registerStateInitializer(StateInitializer func); + + /** + * Create async engine tasks and lock function registration + * @param numEngines Number of worker threads, 0 for automatic scaling + */ + void initialize(unsigned int numEngines); + + /** + * Queue an async job + * @param func Serialized lua function + * @param params Serialized parameters + * @return jobid The job is queued + */ + u32 queueAsyncJob(std::string &&func, std::string &¶ms, + const std::string &mod_origin = ""); + + /** + * Queue an async job + * @param func Serialized lua function + * @param params Serialized parameters (takes ownership!) + * @return ID of queued job + */ + u32 queueAsyncJob(std::string &&func, PackedValue *params, + const std::string &mod_origin = ""); + + /** + * Engine step to process finished jobs + * @param L The Lua stack + */ + void step(lua_State *L); + +protected: + /** + * Get a Job from queue to be processed + * this function blocks until a job is ready + * @param job a job to be processed + * @return whether a job was available + */ + bool getJob(LuaJobInfo *job); + + /** + * Put a Job result back to result queue + * @param result result of completed job + */ + void putJobResult(LuaJobInfo &&result); + + /** + * Start an additional worker thread + */ + void addWorkerThread(); + + /** + * Process finished jobs callbacks + */ + void stepJobResults(lua_State *L); + + /** + * Handle automatic scaling of worker threads + */ + void stepAutoscale(); + + /** + * Initialize environment with current registred functions + * this function adds all functions registred by registerFunction to the + * passed lua stack + * @param L Lua stack to initialize + * @param top Stack position + * @return false if a mod error ocurred + */ + bool prepareEnvironment(lua_State* L, int top); + +private: + // Variable locking the engine against further modification + bool initDone = false; + + // Maximum number of worker threads for automatic scaling + // 0 if disabled + unsigned int autoscaleMaxWorkers = 0; + u64 autoscaleTimer = 0; + std::unordered_set<u32> autoscaleSeenJobs; + + // Only set for the server async environment (duh) + Server *server = nullptr; + + // Internal store for registred state initializers + std::vector<StateInitializer> stateInitializers; + + // Internal counter to create job IDs + u32 jobIdCounter = 0; + + // Mutex to protect job queue + std::mutex jobQueueMutex; + // Job queue + std::deque<LuaJobInfo> jobQueue; + + // Mutex to protect result queue + std::mutex resultQueueMutex; + // Result queue + std::deque<LuaJobInfo> resultQueue; + + // List of current worker threads + std::vector<AsyncWorkerThread*> workerThreads; + + // Counter semaphore for job dispatching + Semaphore jobQueueCounter; +}; diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp new file mode 100644 index 0000000..595c9e5 --- /dev/null +++ b/src/script/cpp_api/s_base.cpp @@ -0,0 +1,465 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_base.h" +#include "cpp_api/s_internal.h" +#include "cpp_api/s_security.h" +#include "lua_api/l_object.h" +#include "common/c_converter.h" +#include "server/player_sao.h" +#include "filesys.h" +#include "content/mods.h" +#include "porting.h" +#include "util/string.h" +#include "server.h" +#ifndef SERVER +#include "client/client.h" +#endif + + +extern "C" { +#include "lualib.h" +#if USE_LUAJIT + #include "luajit.h" +#else + #include "bit.h" +#endif +} + +#include <cstdio> +#include <cstdarg> +#include "script/common/c_content.h" +#include <sstream> + + +class ModNameStorer +{ +private: + lua_State *L; +public: + ModNameStorer(lua_State *L_, const std::string &mod_name): + L(L_) + { + // Store current mod name in registry + lua_pushstring(L, mod_name.c_str()); + lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); + } + ~ModNameStorer() + { + // Clear current mod name from registry + lua_pushnil(L); + lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); + } +}; + + +/* + ScriptApiBase +*/ + +ScriptApiBase::ScriptApiBase(ScriptingType type): + m_type(type) +{ +#ifdef SCRIPTAPI_LOCK_DEBUG + m_lock_recursion_count = 0; +#endif + + m_luastack = luaL_newstate(); + FATAL_ERROR_IF(!m_luastack, "luaL_newstate() failed"); + + lua_atpanic(m_luastack, &luaPanic); + + if (m_type == ScriptingType::Client) + clientOpenLibs(m_luastack); + else + luaL_openlibs(m_luastack); + + // Load bit library + lua_pushcfunction(m_luastack, luaopen_bit); + lua_pushstring(m_luastack, LUA_BITLIBNAME); + lua_call(m_luastack, 1, 0); + + // Make the ScriptApiBase* accessible to ModApiBase +#if INDIRECT_SCRIPTAPI_RIDX + *(void **)(lua_newuserdata(m_luastack, sizeof(void *))) = this; +#else + lua_pushlightuserdata(m_luastack, this); +#endif + lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI); + + // Add and save an error handler + lua_getglobal(m_luastack, "debug"); + lua_getfield(m_luastack, -1, "traceback"); + lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_BACKTRACE); + lua_pop(m_luastack, 1); // pop debug + + // If we are using LuaJIT add a C++ wrapper function to catch + // exceptions thrown in Lua -> C++ calls +#if USE_LUAJIT + lua_pushlightuserdata(m_luastack, (void*) script_exception_wrapper); + luaJIT_setmode(m_luastack, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON); + lua_pop(m_luastack, 1); +#endif + + // Add basic globals + lua_newtable(m_luastack); + lua_setglobal(m_luastack, "core"); + + // vector.metatable is stored in the registry for quick access from C++. + lua_newtable(m_luastack); + lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE); + lua_newtable(m_luastack); + lua_rawgeti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE); + lua_setfield(m_luastack, -2, "metatable"); + lua_setglobal(m_luastack, "vector"); + + if (m_type == ScriptingType::Client) + lua_pushstring(m_luastack, "/"); + else + lua_pushstring(m_luastack, DIR_DELIM); + lua_setglobal(m_luastack, "DIR_DELIM"); + + lua_pushstring(m_luastack, porting::getPlatformName()); + lua_setglobal(m_luastack, "PLATFORM"); + + // Make sure Lua uses the right locale + setlocale(LC_NUMERIC, "C"); +} + +ScriptApiBase::~ScriptApiBase() +{ + lua_close(m_luastack); +} + +int ScriptApiBase::luaPanic(lua_State *L) +{ + std::ostringstream oss; + oss << "LUA PANIC: unprotected error in call to Lua API (" + << readParam<std::string>(L, -1) << ")"; + FATAL_ERROR(oss.str().c_str()); + // NOTREACHED + return 0; +} + +void ScriptApiBase::clientOpenLibs(lua_State *L) +{ + static const std::vector<std::pair<std::string, lua_CFunction>> m_libs = { + { "", luaopen_base }, + { LUA_TABLIBNAME, luaopen_table }, + { LUA_OSLIBNAME, luaopen_os }, + { LUA_STRLIBNAME, luaopen_string }, + { LUA_MATHLIBNAME, luaopen_math }, + { LUA_DBLIBNAME, luaopen_debug }, +#if USE_LUAJIT + { LUA_JITLIBNAME, luaopen_jit }, +#endif + }; + + for (const std::pair<std::string, lua_CFunction> &lib : m_libs) { + lua_pushcfunction(L, lib.second); + lua_pushstring(L, lib.first.c_str()); + lua_call(L, 1, 0); + } +} + +void ScriptApiBase::loadMod(const std::string &script_path, + const std::string &mod_name) +{ + ModNameStorer mod_name_storer(getStack(), mod_name); + + loadScript(script_path); +} + +void ScriptApiBase::loadScript(const std::string &script_path) +{ + verbosestream << "Loading and running script from " << script_path << std::endl; + + lua_State *L = getStack(); + + int error_handler = PUSH_ERROR_HANDLER(L); + + bool ok; + if (m_secure) { + ok = ScriptApiSecurity::safeLoadFile(L, script_path.c_str()); + } else { + ok = !luaL_loadfile(L, script_path.c_str()); + } + ok = ok && !lua_pcall(L, 0, 0, error_handler); + if (!ok) { + const char *error_msg = lua_tostring(L, -1); + if (!error_msg) + error_msg = "(error object is not a string)"; + lua_pop(L, 2); // Pop error message and error handler + throw ModError("Failed to load and run script from " + + script_path + ":\n" + error_msg); + } + lua_pop(L, 1); // Pop error handler +} + +#ifndef SERVER +void ScriptApiBase::loadModFromMemory(const std::string &mod_name) +{ + ModNameStorer mod_name_storer(getStack(), mod_name); + + sanity_check(m_type == ScriptingType::Client); + + const std::string init_filename = mod_name + ":init.lua"; + const std::string chunk_name = "@" + init_filename; + + const std::string *contents = getClient()->getModFile(init_filename); + if (!contents) + throw ModError("Mod \"" + mod_name + "\" lacks init.lua"); + + verbosestream << "Loading and running script " << chunk_name << std::endl; + + lua_State *L = getStack(); + + int error_handler = PUSH_ERROR_HANDLER(L); + + bool ok = ScriptApiSecurity::safeLoadString(L, *contents, chunk_name.c_str()); + if (ok) + ok = !lua_pcall(L, 0, 0, error_handler); + if (!ok) { + const char *error_msg = lua_tostring(L, -1); + if (!error_msg) + error_msg = "(error object is not a string)"; + lua_pop(L, 2); // Pop error message and error handler + throw ModError("Failed to load and run mod \"" + + mod_name + "\":\n" + error_msg); + } + lua_pop(L, 1); // Pop error handler +} +#endif + +// Push the list of callbacks (a lua table). +// Then push nargs arguments. +// Then call this function, which +// - runs the callbacks +// - replaces the table and arguments with the return value, +// computed depending on mode +// This function must only be called with scriptlock held (i.e. inside of a +// code block with SCRIPTAPI_PRECHECKHEADER declared) +void ScriptApiBase::runCallbacksRaw(int nargs, + RunCallbacksMode mode, const char *fxn) +{ +#ifndef SERVER + // Hard fail for bad guarded callbacks + // Only run callbacks when the scripting enviroment is loaded + FATAL_ERROR_IF(m_type == ScriptingType::Client && + !getClient()->modsLoaded(), fxn); +#endif + +#ifdef SCRIPTAPI_LOCK_DEBUG + assert(m_lock_recursion_count > 0); +#endif + lua_State *L = getStack(); + FATAL_ERROR_IF(lua_gettop(L) < nargs + 1, "Not enough arguments"); + + // Insert error handler + PUSH_ERROR_HANDLER(L); + int error_handler = lua_gettop(L) - nargs - 1; + lua_insert(L, error_handler); + + // Insert run_callbacks between error handler and table + lua_getglobal(L, "core"); + lua_getfield(L, -1, "run_callbacks"); + lua_remove(L, -2); + lua_insert(L, error_handler + 1); + + // Insert mode after table + lua_pushnumber(L, (int)mode); + lua_insert(L, error_handler + 3); + + // Stack now looks like this: + // ... <error handler> <run_callbacks> <table> <mode> <arg#1> <arg#2> ... <arg#n> + + int result = lua_pcall(L, nargs + 2, 1, error_handler); + if (result != 0) + scriptError(result, fxn); + + lua_remove(L, error_handler); +} + +void ScriptApiBase::realityCheck() +{ + int top = lua_gettop(m_luastack); + if (top >= 30) { + dstream << "Stack is over 30:" << std::endl; + stackDump(dstream); + std::string traceback = script_get_backtrace(m_luastack); + throw LuaError("Stack is over 30 (reality check)\n" + traceback); + } +} + +void ScriptApiBase::scriptError(int result, const char *fxn) +{ + script_error(getStack(), result, m_last_run_mod.c_str(), fxn); +} + +void ScriptApiBase::stackDump(std::ostream &o) +{ + int top = lua_gettop(m_luastack); + for (int i = 1; i <= top; i++) { /* repeat for each level */ + int t = lua_type(m_luastack, i); + switch (t) { + case LUA_TSTRING: /* strings */ + o << "\"" << readParam<std::string>(m_luastack, i) << "\""; + break; + case LUA_TBOOLEAN: /* booleans */ + o << (readParam<bool>(m_luastack, i) ? "true" : "false"); + break; + case LUA_TNUMBER: /* numbers */ { + char buf[10]; + porting::mt_snprintf(buf, sizeof(buf), "%lf", lua_tonumber(m_luastack, i)); + o << buf; + break; + } + default: /* other values */ + o << lua_typename(m_luastack, t); + break; + } + o << " "; + } + o << std::endl; +} + +void ScriptApiBase::setOriginDirect(const char *origin) +{ + m_last_run_mod = origin ? origin : "??"; +} + +void ScriptApiBase::setOriginFromTableRaw(int index, const char *fxn) +{ + lua_State *L = getStack(); + m_last_run_mod = lua_istable(L, index) ? + getstringfield_default(L, index, "mod_origin", "") : ""; +} + +/* + * How ObjectRefs are handled in Lua: + * When an active object is created, an ObjectRef is created on the Lua side + * and stored in core.object_refs[id]. + * Methods that require an ObjectRef to a certain object retrieve it from that + * table instead of creating their own.(*) + * When an active object is removed, the existing ObjectRef is invalidated + * using ::set_null() and removed from the core.object_refs table. + * (*) An exception to this are NULL ObjectRefs and anonymous ObjectRefs + * for objects without ID. + * It's unclear what the latter are needed for and their use is problematic + * since we lose control over the ref and the contained pointer. + */ + +void ScriptApiBase::addObjectReference(ServerActiveObject *cobj) +{ + SCRIPTAPI_PRECHECKHEADER + //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl; + + // Create object on stack + ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack + int object = lua_gettop(L); + + // Get core.object_refs table + lua_getglobal(L, "core"); + lua_getfield(L, -1, "object_refs"); + luaL_checktype(L, -1, LUA_TTABLE); + int objectstable = lua_gettop(L); + + // object_refs[id] = object + lua_pushnumber(L, cobj->getId()); // Push id + lua_pushvalue(L, object); // Copy object to top of stack + lua_settable(L, objectstable); +} + +void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj) +{ + SCRIPTAPI_PRECHECKHEADER + //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl; + + // Get core.object_refs table + lua_getglobal(L, "core"); + lua_getfield(L, -1, "object_refs"); + luaL_checktype(L, -1, LUA_TTABLE); + int objectstable = lua_gettop(L); + + // Get object_refs[id] + lua_pushnumber(L, cobj->getId()); // Push id + lua_gettable(L, objectstable); + // Set object reference to NULL + ObjectRef::set_null(L); + lua_pop(L, 1); // pop object + + // Set object_refs[id] = nil + lua_pushnumber(L, cobj->getId()); // Push id + lua_pushnil(L); + lua_settable(L, objectstable); +} + +// Creates a new anonymous reference if cobj=NULL or id=0 +void ScriptApiBase::objectrefGetOrCreate(lua_State *L, + ServerActiveObject *cobj) +{ + if (cobj == NULL || cobj->getId() == 0) { + ObjectRef::create(L, cobj); + } else { + push_objectRef(L, cobj->getId()); + if (cobj->isGone()) + warningstream << "ScriptApiBase::objectrefGetOrCreate(): " + << "Pushing ObjectRef to removed/deactivated object" + << ", this is probably a bug." << std::endl; + } +} + +void ScriptApiBase::pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeReason &reason) +{ + if (reason.hasLuaReference()) + lua_rawgeti(L, LUA_REGISTRYINDEX, reason.lua_reference); + else + lua_newtable(L); + + lua_getfield(L, -1, "type"); + bool has_type = (bool)lua_isstring(L, -1); + lua_pop(L, 1); + if (!has_type) { + lua_pushstring(L, reason.getTypeAsString().c_str()); + lua_setfield(L, -2, "type"); + } + + lua_pushstring(L, reason.from_mod ? "mod" : "engine"); + lua_setfield(L, -2, "from"); + + if (reason.object) { + objectrefGetOrCreate(L, reason.object); + lua_setfield(L, -2, "object"); + } + if (!reason.node.empty()) { + lua_pushstring(L, reason.node.c_str()); + lua_setfield(L, -2, "node"); + } +} + +Server* ScriptApiBase::getServer() +{ + return dynamic_cast<Server *>(m_gamedef); +} +#ifndef SERVER +Client* ScriptApiBase::getClient() +{ + return dynamic_cast<Client *>(m_gamedef); +} +#endif diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h new file mode 100644 index 0000000..244d816 --- /dev/null +++ b/src/script/cpp_api/s_base.h @@ -0,0 +1,180 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <iostream> +#include <string> +#include <thread> +#include <mutex> +#include <unordered_map> +#include "common/helper.h" +#include "util/basic_macros.h" + +extern "C" { +#include <lua.h> +#include <lualib.h> +} + +#include "irrlichttypes.h" +#include "common/c_types.h" +#include "common/c_internal.h" +#include "debug.h" +#include "config.h" + +#define SCRIPTAPI_LOCK_DEBUG + +// MUST be an invalid mod name so that mods can't +// use that name to bypass security! +#define BUILTIN_MOD_NAME "*builtin*" + +#define PCALL_RES(RES) { \ + int result_ = (RES); \ + if (result_ != 0) { \ + scriptError(result_, __FUNCTION__); \ + } \ +} + +#define runCallbacks(nargs, mode) \ + runCallbacksRaw((nargs), (mode), __FUNCTION__) + +#define setOriginFromTable(index) \ + setOriginFromTableRaw(index, __FUNCTION__) + +enum class ScriptingType: u8 { + Async, + Client, + MainMenu, + Server +}; + +class Server; +#ifndef SERVER +class Client; +#endif +class IGameDef; +class Environment; +class GUIEngine; +class ServerActiveObject; +struct PlayerHPChangeReason; + +class ScriptApiBase : protected LuaHelper { +public: + ScriptApiBase(ScriptingType type); + // fake constructor to allow script API classes (e.g ScriptApiEnv) to virtually inherit from this one. + ScriptApiBase() + { + FATAL_ERROR("ScriptApiBase created without ScriptingType!"); + } + virtual ~ScriptApiBase(); + DISABLE_CLASS_COPY(ScriptApiBase); + + // These throw a ModError on failure + void loadMod(const std::string &script_path, const std::string &mod_name); + void loadScript(const std::string &script_path); + +#ifndef SERVER + void loadModFromMemory(const std::string &mod_name); +#endif + + void runCallbacksRaw(int nargs, + RunCallbacksMode mode, const char *fxn); + + /* object */ + void addObjectReference(ServerActiveObject *cobj); + void removeObjectReference(ServerActiveObject *cobj); + + IGameDef *getGameDef() { return m_gamedef; } + Server* getServer(); + ScriptingType getType() { return m_type; } +#ifndef SERVER + Client* getClient(); +#endif + + // IMPORTANT: these cannot be used for any security-related uses, they exist + // only to enrich error messages + const std::string &getOrigin() { return m_last_run_mod; } + void setOriginDirect(const char *origin); + void setOriginFromTableRaw(int index, const char *fxn); + + void clientOpenLibs(lua_State *L); + +protected: + friend class LuaABM; + friend class LuaLBM; + friend class InvRef; + friend class ObjectRef; + friend class NodeMetaRef; + friend class ModApiBase; + friend class ModApiEnvMod; + friend class LuaVoxelManip; + + /* + Subtle edge case with coroutines: If for whatever reason you have a + method in a subclass that's called from existing lua_CFunction + (any of the l_*.cpp files) then make it static and take the lua_State* + as an argument. This is REQUIRED because getStack() will not return the + correct state if called inside coroutines. + + Also note that src/script/common/ is the better place for such helpers. + */ + lua_State* getStack() + { return m_luastack; } + + // Checks that stack size is sane + void realityCheck(); + // Takes an error from lua_pcall and throws it as a LuaError + void scriptError(int result, const char *fxn); + // Dumps stack contents for debugging + void stackDump(std::ostream &o); + + void setGameDef(IGameDef* gamedef) { m_gamedef = gamedef; } + + Environment* getEnv() { return m_environment; } + void setEnv(Environment* env) { m_environment = env; } + +#ifndef SERVER + GUIEngine* getGuiEngine() { return m_guiengine; } + void setGuiEngine(GUIEngine* guiengine) { m_guiengine = guiengine; } +#endif + + void objectrefGetOrCreate(lua_State *L, ServerActiveObject *cobj); + + void pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeReason& reason); + + std::recursive_mutex m_luastackmutex; + std::string m_last_run_mod; + bool m_secure = false; +#ifdef SCRIPTAPI_LOCK_DEBUG + int m_lock_recursion_count{}; + std::thread::id m_owning_thread; +#endif + +private: + static int luaPanic(lua_State *L); + + lua_State *m_luastack = nullptr; + + IGameDef *m_gamedef = nullptr; + Environment *m_environment = nullptr; +#ifndef SERVER + GUIEngine *m_guiengine = nullptr; +#endif + ScriptingType m_type; +}; diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp new file mode 100644 index 0000000..b02a0c7 --- /dev/null +++ b/src/script/cpp_api/s_client.cpp @@ -0,0 +1,298 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "s_client.h" +#include "s_internal.h" +#include "client/client.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "s_item.h" + +void ScriptApiClient::on_mods_loaded() +{ + SCRIPTAPI_PRECHECKHEADER + + // Get registered shutdown hooks + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_mods_loaded"); + // Call callbacks + try { + runCallbacks(0, RUN_CALLBACKS_MODE_FIRST); + } catch (LuaError &e) { + getClient()->setFatalError(e); + } +} + +void ScriptApiClient::on_shutdown() +{ + SCRIPTAPI_PRECHECKHEADER + + // Get registered shutdown hooks + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_shutdown"); + // Call callbacks + try { + runCallbacks(0, RUN_CALLBACKS_MODE_FIRST); + } catch (LuaError &e) { + getClient()->setFatalError(e); + } +} + +bool ScriptApiClient::on_sending_message(const std::string &message) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_chat_messages + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_sending_chat_message"); + // Call callbacks + lua_pushstring(L, message.c_str()); + try { + runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC); + } catch (LuaError &e) { + getClient()->setFatalError(e); + return true; + } + return readParam<bool>(L, -1); +} + +bool ScriptApiClient::on_receiving_message(const std::string &message) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_chat_messages + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_receiving_chat_message"); + // Call callbacks + lua_pushstring(L, message.c_str()); + try { + runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC); + } catch (LuaError &e) { + getClient()->setFatalError(e); + return true; + } + return readParam<bool>(L, -1); +} + +void ScriptApiClient::on_damage_taken(int32_t damage_amount) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_chat_messages + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_damage_taken"); + // Call callbacks + lua_pushinteger(L, damage_amount); + try { + runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC); + } catch (LuaError &e) { + getClient()->setFatalError(e); + } +} + +void ScriptApiClient::on_hp_modification(int32_t newhp) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_chat_messages + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_hp_modification"); + // Call callbacks + lua_pushinteger(L, newhp); + try { + runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC); + } catch (LuaError &e) { + getClient()->setFatalError(e); + } +} + +void ScriptApiClient::on_death() +{ + SCRIPTAPI_PRECHECKHEADER + + // Get registered shutdown hooks + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_death"); + // Call callbacks + try { + runCallbacks(0, RUN_CALLBACKS_MODE_FIRST); + } catch (LuaError &e) { + getClient()->setFatalError(e); + } +} + +void ScriptApiClient::environment_step(float dtime) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_globalsteps + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_globalsteps"); + // Call callbacks + lua_pushnumber(L, dtime); + try { + runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); + } catch (LuaError &e) { + getClient()->setFatalError(e); + } +} + +void ScriptApiClient::on_formspec_input(const std::string &formname, + const StringMap &fields) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_chat_messages + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_formspec_input"); + // Call callbacks + // param 1 + lua_pushstring(L, formname.c_str()); + // param 2 + lua_newtable(L); + StringMap::const_iterator it; + for (it = fields.begin(); it != fields.end(); ++it) { + const std::string &name = it->first; + const std::string &value = it->second; + lua_pushstring(L, name.c_str()); + lua_pushlstring(L, value.c_str(), value.size()); + lua_settable(L, -3); + } + try { + runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC); + } catch (LuaError &e) { + getClient()->setFatalError(e); + } +} + +bool ScriptApiClient::on_dignode(v3s16 p, MapNode node) +{ + SCRIPTAPI_PRECHECKHEADER + + const NodeDefManager *ndef = getClient()->ndef(); + + // Get core.registered_on_dignode + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_dignode"); + + // Push data + push_v3s16(L, p); + pushnode(L, node, ndef); + + // Call functions + try { + runCallbacks(2, RUN_CALLBACKS_MODE_OR); + } catch (LuaError &e) { + getClient()->setFatalError(e); + return true; + } + return lua_toboolean(L, -1); +} + +bool ScriptApiClient::on_punchnode(v3s16 p, MapNode node) +{ + SCRIPTAPI_PRECHECKHEADER + + const NodeDefManager *ndef = getClient()->ndef(); + + // Get core.registered_on_punchgnode + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_punchnode"); + + // Push data + push_v3s16(L, p); + pushnode(L, node, ndef); + + // Call functions + try { + runCallbacks(2, RUN_CALLBACKS_MODE_OR); + } catch (LuaError &e) { + getClient()->setFatalError(e); + return true; + } + return readParam<bool>(L, -1); +} + +bool ScriptApiClient::on_placenode(const PointedThing &pointed, const ItemDefinition &item) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_placenode + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_placenode"); + + // Push data + push_pointed_thing(L, pointed, true); + push_item_definition(L, item); + + // Call functions + try { + runCallbacks(2, RUN_CALLBACKS_MODE_OR); + } catch (LuaError &e) { + getClient()->setFatalError(e); + return true; + } + return readParam<bool>(L, -1); +} + +bool ScriptApiClient::on_item_use(const ItemStack &item, const PointedThing &pointed) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_item_use + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_item_use"); + + // Push data + LuaItemStack::create(L, item); + push_pointed_thing(L, pointed, true); + + // Call functions + try { + runCallbacks(2, RUN_CALLBACKS_MODE_OR); + } catch (LuaError &e) { + getClient()->setFatalError(e); + return true; + } + return readParam<bool>(L, -1); +} + +bool ScriptApiClient::on_inventory_open(Inventory *inventory) +{ + SCRIPTAPI_PRECHECKHEADER + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_inventory_open"); + + push_inventory_lists(L, *inventory); + + try { + runCallbacks(1, RUN_CALLBACKS_MODE_OR); + } catch (LuaError &e) { + getClient()->setFatalError(e); + return true; + } + return readParam<bool>(L, -1); +} + +void ScriptApiClient::setEnv(ClientEnvironment *env) +{ + ScriptApiBase::setEnv(env); +} diff --git a/src/script/cpp_api/s_client.h b/src/script/cpp_api/s_client.h new file mode 100644 index 0000000..93fe967 --- /dev/null +++ b/src/script/cpp_api/s_client.h @@ -0,0 +1,64 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "util/pointedthing.h" +#include "cpp_api/s_base.h" +#include "mapnode.h" +#include "itemdef.h" +#include "util/string.h" +#include "util/pointedthing.h" +#include "lua_api/l_item.h" + +#ifdef _CRT_MSVCP_CURRENT +#include <cstdint> +#endif + +class ClientEnvironment; + +class ScriptApiClient : virtual public ScriptApiBase +{ +public: + // Calls when mods are loaded + void on_mods_loaded(); + + // Calls on_shutdown handlers + void on_shutdown(); + + // Chat message handlers + bool on_sending_message(const std::string &message); + bool on_receiving_message(const std::string &message); + + void on_damage_taken(int32_t damage_amount); + void on_hp_modification(int32_t newhp); + void on_death(); + void environment_step(float dtime); + void on_formspec_input(const std::string &formname, const StringMap &fields); + + bool on_dignode(v3s16 p, MapNode node); + bool on_punchnode(v3s16 p, MapNode node); + bool on_placenode(const PointedThing &pointed, const ItemDefinition &item); + bool on_item_use(const ItemStack &item, const PointedThing &pointed); + + bool on_inventory_open(Inventory *inventory); + + void setEnv(ClientEnvironment *env); +}; diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp new file mode 100644 index 0000000..852a27d --- /dev/null +++ b/src/script/cpp_api/s_entity.cpp @@ -0,0 +1,334 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_entity.h" +#include "cpp_api/s_internal.h" +#include "log.h" +#include "object_properties.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "server.h" + +bool ScriptApiEntity::luaentity_Add(u16 id, const char *name) +{ + SCRIPTAPI_PRECHECKHEADER + + verbosestream<<"scriptapi_luaentity_add: id="<<id<<" name=\"" + <<name<<"\""<<std::endl; + + // Get core.registered_entities[name] + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_entities"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_pushstring(L, name); + lua_gettable(L, -2); + // Should be a table, which we will use as a prototype + //luaL_checktype(L, -1, LUA_TTABLE); + if (lua_type(L, -1) != LUA_TTABLE){ + errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl; + return false; + } + int prototype_table = lua_gettop(L); + //dump2(L, "prototype_table"); + + // Create entity object + lua_newtable(L); + int object = lua_gettop(L); + + // Set object metatable + lua_pushvalue(L, prototype_table); + lua_setmetatable(L, -2); + + // Add object reference + // This should be userdata with metatable ObjectRef + push_objectRef(L, id); + luaL_checktype(L, -1, LUA_TUSERDATA); + if (!luaL_checkudata(L, -1, "ObjectRef")) + luaL_typerror(L, -1, "ObjectRef"); + lua_setfield(L, -2, "object"); + + // core.luaentities[id] = object + lua_getglobal(L, "core"); + lua_getfield(L, -1, "luaentities"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_pushnumber(L, id); // Push id + lua_pushvalue(L, object); // Copy object to top of stack + lua_settable(L, -3); + + return true; +} + +void ScriptApiEntity::luaentity_Activate(u16 id, + const std::string &staticdata, u32 dtime_s) +{ + SCRIPTAPI_PRECHECKHEADER + + verbosestream << "scriptapi_luaentity_activate: id=" << id << std::endl; + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get core.luaentities[id] + luaentity_get(L, id); + int object = lua_gettop(L); + + // Get on_activate function + lua_getfield(L, -1, "on_activate"); + if (!lua_isnil(L, -1)) { + luaL_checktype(L, -1, LUA_TFUNCTION); + lua_pushvalue(L, object); // self + lua_pushlstring(L, staticdata.c_str(), staticdata.size()); + lua_pushinteger(L, dtime_s); + + setOriginFromTable(object); + PCALL_RES(lua_pcall(L, 3, 0, error_handler)); + } else { + lua_pop(L, 1); + } + lua_pop(L, 2); // Pop object and error handler +} + +void ScriptApiEntity::luaentity_Deactivate(u16 id, bool removal) +{ + SCRIPTAPI_PRECHECKHEADER + + verbosestream << "scriptapi_luaentity_deactivate: id=" << id << std::endl; + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get the entity + luaentity_get(L, id); + int object = lua_gettop(L); + + // Get on_deactivate + lua_getfield(L, -1, "on_deactivate"); + if (!lua_isnil(L, -1)) { + luaL_checktype(L, -1, LUA_TFUNCTION); + lua_pushvalue(L, object); + lua_pushboolean(L, removal); + setOriginFromTable(object); + PCALL_RES(lua_pcall(L, 2, 0, error_handler)); + } else { + lua_pop(L, 1); + } + lua_pop(L, 2); // Pop object and error handler +} + +void ScriptApiEntity::luaentity_Remove(u16 id) +{ + SCRIPTAPI_PRECHECKHEADER + + verbosestream << "scriptapi_luaentity_rm: id=" << id << std::endl; + + // Get core.luaentities table + lua_getglobal(L, "core"); + lua_getfield(L, -1, "luaentities"); + luaL_checktype(L, -1, LUA_TTABLE); + int objectstable = lua_gettop(L); + + // Set luaentities[id] = nil + lua_pushnumber(L, id); // Push id + lua_pushnil(L); + lua_settable(L, objectstable); + + lua_pop(L, 2); // pop luaentities, core +} + +std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id) +{ + SCRIPTAPI_PRECHECKHEADER + + //infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl; + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get core.luaentities[id] + luaentity_get(L, id); + int object = lua_gettop(L); + + // Get get_staticdata function + lua_getfield(L, -1, "get_staticdata"); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); // Pop entity and get_staticdata + return ""; + } + luaL_checktype(L, -1, LUA_TFUNCTION); + lua_pushvalue(L, object); // self + + setOriginFromTable(object); + PCALL_RES(lua_pcall(L, 1, 1, error_handler)); + + lua_remove(L, object); + lua_remove(L, error_handler); + + size_t len = 0; + const char *s = lua_tolstring(L, -1, &len); + lua_pop(L, 1); // Pop static data + return std::string(s, len); +} + +void ScriptApiEntity::luaentity_GetProperties(u16 id, + ServerActiveObject *self, ObjectProperties *prop) +{ + SCRIPTAPI_PRECHECKHEADER + + //infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl; + + // Get core.luaentities[id] + luaentity_get(L, id); + + // Set default values that differ from ObjectProperties defaults + prop->hp_max = 10; + + // Deprecated: read object properties directly + read_object_properties(L, -1, self, prop, getServer()->idef()); + + // Read initial_properties + lua_getfield(L, -1, "initial_properties"); + read_object_properties(L, -1, self, prop, getServer()->idef()); + lua_pop(L, 1); +} + +void ScriptApiEntity::luaentity_Step(u16 id, float dtime, + const collisionMoveResult *moveresult) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get core.luaentities[id] + luaentity_get(L, id); + int object = lua_gettop(L); + // State: object is at top of stack + // Get step function + lua_getfield(L, -1, "on_step"); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); // Pop on_step and entity + return; + } + luaL_checktype(L, -1, LUA_TFUNCTION); + lua_pushvalue(L, object); // self + lua_pushnumber(L, dtime); // dtime + /* moveresult */ + if (moveresult) + push_collision_move_result(L, *moveresult); + else + lua_pushnil(L); + + setOriginFromTable(object); + PCALL_RES(lua_pcall(L, 3, 0, error_handler)); + + lua_pop(L, 2); // Pop object and error handler +} + +// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch, +// tool_capabilities, direction, damage) +bool ScriptApiEntity::luaentity_Punch(u16 id, + ServerActiveObject *puncher, float time_from_last_punch, + const ToolCapabilities *toolcap, v3f dir, s32 damage) +{ + SCRIPTAPI_PRECHECKHEADER + + assert(puncher); + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get core.luaentities[id] + luaentity_get(L,id); + int object = lua_gettop(L); + // State: object is at top of stack + // Get function + lua_getfield(L, -1, "on_punch"); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); // Pop on_punch and entity + return false; + } + luaL_checktype(L, -1, LUA_TFUNCTION); + lua_pushvalue(L, object); // self + objectrefGetOrCreate(L, puncher); // Clicker reference + lua_pushnumber(L, time_from_last_punch); + push_tool_capabilities(L, *toolcap); + push_v3f(L, dir); + lua_pushnumber(L, damage); + + setOriginFromTable(object); + PCALL_RES(lua_pcall(L, 6, 1, error_handler)); + + bool retval = readParam<bool>(L, -1); + lua_pop(L, 2); // Pop object and error handler + return retval; +} + +// Calls entity[field](ObjectRef self, ObjectRef sao) +bool ScriptApiEntity::luaentity_run_simple_callback(u16 id, + ServerActiveObject *sao, const char *field) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get core.luaentities[id] + luaentity_get(L, id); + int object = lua_gettop(L); + // State: object is at top of stack + // Get function + lua_getfield(L, -1, field); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); // Pop callback field and entity + return false; + } + luaL_checktype(L, -1, LUA_TFUNCTION); + lua_pushvalue(L, object); // self + if (sao) + objectrefGetOrCreate(L, sao); // sao reference + else + lua_pushnil(L); + + setOriginFromTable(object); + PCALL_RES(lua_pcall(L, 2, 1, error_handler)); + + bool retval = readParam<bool>(L, -1); + lua_pop(L, 2); // Pop object and error handler + return retval; +} + +bool ScriptApiEntity::luaentity_on_death(u16 id, ServerActiveObject *killer) +{ + return luaentity_run_simple_callback(id, killer, "on_death"); +} + +// Calls entity:on_rightclick(ObjectRef clicker) +void ScriptApiEntity::luaentity_Rightclick(u16 id, ServerActiveObject *clicker) +{ + luaentity_run_simple_callback(id, clicker, "on_rightclick"); +} + +void ScriptApiEntity::luaentity_on_attach_child(u16 id, ServerActiveObject *child) +{ + luaentity_run_simple_callback(id, child, "on_attach_child"); +} + +void ScriptApiEntity::luaentity_on_detach_child(u16 id, ServerActiveObject *child) +{ + luaentity_run_simple_callback(id, child, "on_detach_child"); +} + +void ScriptApiEntity::luaentity_on_detach(u16 id, ServerActiveObject *parent) +{ + luaentity_run_simple_callback(id, parent, "on_detach"); +} diff --git a/src/script/cpp_api/s_entity.h b/src/script/cpp_api/s_entity.h new file mode 100644 index 0000000..13f3e9a --- /dev/null +++ b/src/script/cpp_api/s_entity.h @@ -0,0 +1,54 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" +#include "irr_v3d.h" + +struct ObjectProperties; +struct ToolCapabilities; +struct collisionMoveResult; + +class ScriptApiEntity + : virtual public ScriptApiBase +{ +public: + bool luaentity_Add(u16 id, const char *name); + void luaentity_Activate(u16 id, + const std::string &staticdata, u32 dtime_s); + void luaentity_Deactivate(u16 id, bool removal); + void luaentity_Remove(u16 id); + std::string luaentity_GetStaticdata(u16 id); + void luaentity_GetProperties(u16 id, + ServerActiveObject *self, ObjectProperties *prop); + void luaentity_Step(u16 id, float dtime, + const collisionMoveResult *moveresult); + bool luaentity_Punch(u16 id, + ServerActiveObject *puncher, float time_from_last_punch, + const ToolCapabilities *toolcap, v3f dir, s32 damage); + bool luaentity_on_death(u16 id, ServerActiveObject *killer); + void luaentity_Rightclick(u16 id, ServerActiveObject *clicker); + void luaentity_on_attach_child(u16 id, ServerActiveObject *child); + void luaentity_on_detach_child(u16 id, ServerActiveObject *child); + void luaentity_on_detach(u16 id, ServerActiveObject *parent); +private: + bool luaentity_run_simple_callback(u16 id, ServerActiveObject *sao, + const char *field); +}; diff --git a/src/script/cpp_api/s_env.cpp b/src/script/cpp_api/s_env.cpp new file mode 100644 index 0000000..af68f68 --- /dev/null +++ b/src/script/cpp_api/s_env.cpp @@ -0,0 +1,290 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_env.h" +#include "cpp_api/s_internal.h" +#include "common/c_converter.h" +#include "log.h" +#include "environment.h" +#include "mapgen/mapgen.h" +#include "lua_api/l_env.h" +#include "server.h" +#include "script/common/c_content.h" + + +void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp, + u32 blockseed) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_generateds + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_generateds"); + // Call callbacks + push_v3s16(L, minp); + push_v3s16(L, maxp); + lua_pushnumber(L, blockseed); + runCallbacks(3, RUN_CALLBACKS_MODE_FIRST); +} + +void ScriptApiEnv::environment_Step(float dtime) +{ + SCRIPTAPI_PRECHECKHEADER + //infostream << "scriptapi_environment_step" << std::endl; + + // Get core.registered_globalsteps + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_globalsteps"); + // Call callbacks + lua_pushnumber(L, dtime); + runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); +} + +void ScriptApiEnv::player_event(ServerActiveObject *player, const std::string &type) +{ + SCRIPTAPI_PRECHECKHEADER + + if (player == NULL) + return; + + // Get minetest.registered_playerevents + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_playerevents"); + + // Call callbacks + objectrefGetOrCreate(L, player); // player + lua_pushstring(L,type.c_str()); // event type + runCallbacks(2, RUN_CALLBACKS_MODE_FIRST); +} + +void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env) +{ + SCRIPTAPI_PRECHECKHEADER + verbosestream << "ScriptApiEnv: Environment initialized" << std::endl; + setEnv(env); + + /* + Add {Loading,Active}BlockModifiers to environment + */ + + // Get core.registered_abms + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_abms"); + int registered_abms = lua_gettop(L); + + if (!lua_istable(L, registered_abms)) { + lua_pop(L, 1); + throw LuaError("core.registered_abms was not a lua table, as expected."); + } + lua_pushnil(L); + while (lua_next(L, registered_abms)) { + // key at index -2 and value at index -1 + int id = lua_tonumber(L, -2); + int current_abm = lua_gettop(L); + + std::vector<std::string> trigger_contents; + lua_getfield(L, current_abm, "nodenames"); + if (lua_istable(L, -1)) { + int table = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, table)) { + // key at index -2 and value at index -1 + luaL_checktype(L, -1, LUA_TSTRING); + trigger_contents.emplace_back(readParam<std::string>(L, -1)); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } else if (lua_isstring(L, -1)) { + trigger_contents.emplace_back(readParam<std::string>(L, -1)); + } + lua_pop(L, 1); + + std::vector<std::string> required_neighbors; + lua_getfield(L, current_abm, "neighbors"); + if (lua_istable(L, -1)) { + int table = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, table)) { + // key at index -2 and value at index -1 + luaL_checktype(L, -1, LUA_TSTRING); + required_neighbors.emplace_back(readParam<std::string>(L, -1)); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } else if (lua_isstring(L, -1)) { + required_neighbors.emplace_back(readParam<std::string>(L, -1)); + } + lua_pop(L, 1); + + float trigger_interval = 10.0; + getfloatfield(L, current_abm, "interval", trigger_interval); + + int trigger_chance = 50; + getintfield(L, current_abm, "chance", trigger_chance); + + bool simple_catch_up = true; + getboolfield(L, current_abm, "catch_up", simple_catch_up); + + s16 min_y = INT16_MIN; + getintfield(L, current_abm, "min_y", min_y); + + s16 max_y = INT16_MAX; + getintfield(L, current_abm, "max_y", max_y); + + lua_getfield(L, current_abm, "action"); + luaL_checktype(L, current_abm + 1, LUA_TFUNCTION); + lua_pop(L, 1); + + LuaABM *abm = new LuaABM(L, id, trigger_contents, required_neighbors, + trigger_interval, trigger_chance, simple_catch_up, min_y, max_y); + + env->addActiveBlockModifier(abm); + + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + lua_pop(L, 1); + + // Get core.registered_lbms + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_lbms"); + int registered_lbms = lua_gettop(L); + + if (!lua_istable(L, registered_lbms)) { + lua_pop(L, 1); + throw LuaError("core.registered_lbms was not a lua table, as expected."); + } + + lua_pushnil(L); + while (lua_next(L, registered_lbms)) { + // key at index -2 and value at index -1 + int id = lua_tonumber(L, -2); + int current_lbm = lua_gettop(L); + + std::set<std::string> trigger_contents; + lua_getfield(L, current_lbm, "nodenames"); + if (lua_istable(L, -1)) { + int table = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, table)) { + // key at index -2 and value at index -1 + luaL_checktype(L, -1, LUA_TSTRING); + trigger_contents.insert(readParam<std::string>(L, -1)); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } else if (lua_isstring(L, -1)) { + trigger_contents.insert(readParam<std::string>(L, -1)); + } + lua_pop(L, 1); + + std::string name; + getstringfield(L, current_lbm, "name", name); + + bool run_at_every_load = getboolfield_default(L, current_lbm, + "run_at_every_load", false); + + lua_getfield(L, current_lbm, "action"); + luaL_checktype(L, current_lbm + 1, LUA_TFUNCTION); + lua_pop(L, 1); + + LuaLBM *lbm = new LuaLBM(L, id, trigger_contents, name, + run_at_every_load); + + env->addLoadingBlockModifierDef(lbm); + + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + lua_pop(L, 1); +} + +void ScriptApiEnv::on_emerge_area_completion( + v3s16 blockpos, int action, ScriptCallbackState *state) +{ + Server *server = getServer(); + + // This function should be executed with envlock held. + // The caller (LuaEmergeAreaCallback in src/script/lua_api/l_env.cpp) + // should have obtained the lock. + // Note that the order of these locks is important! Envlock must *ALWAYS* + // be acquired before attempting to acquire scriptlock, or else ServerThread + // will try to acquire scriptlock after it already owns envlock, thus + // deadlocking EmergeThread and ServerThread + + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + lua_rawgeti(L, LUA_REGISTRYINDEX, state->callback_ref); + luaL_checktype(L, -1, LUA_TFUNCTION); + + push_v3s16(L, blockpos); + lua_pushinteger(L, action); + lua_pushinteger(L, state->refcount); + lua_rawgeti(L, LUA_REGISTRYINDEX, state->args_ref); + + setOriginDirect(state->origin.c_str()); + + try { + PCALL_RES(lua_pcall(L, 4, 0, error_handler)); + } catch (LuaError &e) { + // Note: don't throw here, we still need to run the cleanup code below + server->setAsyncFatalError(e); + } + + lua_pop(L, 1); // Pop error handler + + if (state->refcount == 0) { + luaL_unref(L, LUA_REGISTRYINDEX, state->callback_ref); + luaL_unref(L, LUA_REGISTRYINDEX, state->args_ref); + } +} + +void ScriptApiEnv::on_liquid_transformed( + const std::vector<std::pair<v3s16, MapNode>> &list) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_liquid_transformed + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_liquid_transformed"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_remove(L, -2); + + // Skip converting list and calling hook if there are + // no registered callbacks. + if(lua_objlen(L, -1) < 1) return; + + // Convert the list to a pos array and a node array for lua + int index = 1; + const NodeDefManager *ndef = getEnv()->getGameDef()->ndef(); + lua_createtable(L, list.size(), 0); + lua_createtable(L, list.size(), 0); + for(std::pair<v3s16, MapNode> p : list) { + lua_pushnumber(L, index); + push_v3s16(L, p.first); + lua_rawset(L, -4); + lua_pushnumber(L, index++); + pushnode(L, p.second, ndef); + lua_rawset(L, -3); + } + + runCallbacks(2, RUN_CALLBACKS_MODE_FIRST); +} diff --git a/src/script/cpp_api/s_env.h b/src/script/cpp_api/s_env.h new file mode 100644 index 0000000..090858f --- /dev/null +++ b/src/script/cpp_api/s_env.h @@ -0,0 +1,50 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" +#include "irr_v3d.h" +#include "mapnode.h" +#include <vector> + +class ServerEnvironment; +struct ScriptCallbackState; + +class ScriptApiEnv : virtual public ScriptApiBase +{ +public: + // Called on environment step + void environment_Step(float dtime); + + // Called after generating a piece of map + void environment_OnGenerated(v3s16 minp, v3s16 maxp, u32 blockseed); + + // Called on player event + void player_event(ServerActiveObject *player, const std::string &type); + + // Called after emerge of a block queued from core.emerge_area() + void on_emerge_area_completion(v3s16 blockpos, int action, + ScriptCallbackState *state); + + // Called after liquid transform changes + void on_liquid_transformed(const std::vector<std::pair<v3s16, MapNode>> &list); + + void initializeEnvironment(ServerEnvironment *env); +}; diff --git a/src/script/cpp_api/s_internal.h b/src/script/cpp_api/s_internal.h new file mode 100644 index 0000000..83b3b9d --- /dev/null +++ b/src/script/cpp_api/s_internal.h @@ -0,0 +1,85 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/******************************************************************************/ +/******************************************************************************/ +/* WARNING!!!! do NOT add this header in any include file or any code file */ +/* not being a modapi file!!!!!!!! */ +/******************************************************************************/ +/******************************************************************************/ + +#pragma once + +#include <thread> +#include "common/c_internal.h" +#include "cpp_api/s_base.h" +#include "threading/mutex_auto_lock.h" + +#ifdef SCRIPTAPI_LOCK_DEBUG +#include <cassert> + +class LockChecker { +public: + LockChecker(int *recursion_counter, std::thread::id *owning_thread) + { + m_lock_recursion_counter = recursion_counter; + m_owning_thread = owning_thread; + m_original_level = *recursion_counter; + + if (*m_lock_recursion_counter > 0) { + assert(*m_owning_thread == std::this_thread::get_id()); + } else { + *m_owning_thread = std::this_thread::get_id(); + } + + (*m_lock_recursion_counter)++; + } + + ~LockChecker() + { + assert(*m_owning_thread == std::this_thread::get_id()); + assert(*m_lock_recursion_counter > 0); + + (*m_lock_recursion_counter)--; + + assert(*m_lock_recursion_counter == m_original_level); + } + +private: + int *m_lock_recursion_counter; + int m_original_level; + std::thread::id *m_owning_thread; +}; + +#define SCRIPTAPI_LOCK_CHECK \ + LockChecker scriptlock_checker( \ + &this->m_lock_recursion_count, \ + &this->m_owning_thread) + +#else + #define SCRIPTAPI_LOCK_CHECK while(0) +#endif + +#define SCRIPTAPI_PRECHECKHEADER \ + RecursiveMutexAutoLock scriptlock(this->m_luastackmutex); \ + SCRIPTAPI_LOCK_CHECK; \ + realityCheck(); \ + lua_State *L = getStack(); \ + assert(lua_checkstack(L, 20)); \ + StackUnroller stack_unroller(L); diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp new file mode 100644 index 0000000..e9c09f7 --- /dev/null +++ b/src/script/cpp_api/s_inventory.cpp @@ -0,0 +1,225 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_inventory.h" +#include "cpp_api/s_internal.h" +#include "inventorymanager.h" +#include "lua_api/l_inventory.h" +#include "lua_api/l_item.h" +#include "log.h" + +// Return number of accepted items to be moved +int ScriptApiDetached::detached_inventory_AllowMove( + const MoveAction &ma, int count, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Push callback function on stack + if (!getDetachedInventoryCallback(ma.from_inv.name, "allow_move")) + return count; + + // function(inv, from_list, from_index, to_list, to_index, count, player) + // inv + InvRef::create(L, ma.from_inv); + lua_pushstring(L, ma.from_list.c_str()); // from_list + lua_pushinteger(L, ma.from_i + 1); // from_index + lua_pushstring(L, ma.to_list.c_str()); // to_list + lua_pushinteger(L, ma.to_i + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 7, 1, error_handler)); + if(!lua_isnumber(L, -1)) + throw LuaError("allow_move should return a number. name=" + ma.from_inv.name); + int ret = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return ret; +} + +// Return number of accepted items to be put +int ScriptApiDetached::detached_inventory_AllowPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Push callback function on stack + if (!getDetachedInventoryCallback(ma.to_inv.name, "allow_put")) + return stack.count; // All will be accepted + + // Call function(inv, listname, index, stack, player) + InvRef::create(L, ma.to_inv); // inv + lua_pushstring(L, ma.to_list.c_str()); // listname + lua_pushinteger(L, ma.to_i + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 5, 1, error_handler)); + if (!lua_isnumber(L, -1)) + throw LuaError("allow_put should return a number. name=" + ma.to_inv.name); + int ret = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return ret; +} + +// Return number of accepted items to be taken +int ScriptApiDetached::detached_inventory_AllowTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Push callback function on stack + if (!getDetachedInventoryCallback(ma.from_inv.name, "allow_take")) + return stack.count; // All will be accepted + + // Call function(inv, listname, index, stack, player) + InvRef::create(L, ma.from_inv); // inv + lua_pushstring(L, ma.from_list.c_str()); // listname + lua_pushinteger(L, ma.from_i + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 5, 1, error_handler)); + if (!lua_isnumber(L, -1)) + throw LuaError("allow_take should return a number. name=" + ma.from_inv.name); + int ret = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return ret; +} + +// Report moved items +void ScriptApiDetached::detached_inventory_OnMove( + const MoveAction &ma, int count, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Push callback function on stack + if (!getDetachedInventoryCallback(ma.from_inv.name, "on_move")) + return; + + // function(inv, from_list, from_index, to_list, to_index, count, player) + // inv + InvRef::create(L, ma.from_inv); + lua_pushstring(L, ma.from_list.c_str()); // from_list + lua_pushinteger(L, ma.from_i + 1); // from_index + lua_pushstring(L, ma.to_list.c_str()); // to_list + lua_pushinteger(L, ma.to_i + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 7, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} + +// Report put items +void ScriptApiDetached::detached_inventory_OnPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Push callback function on stack + if (!getDetachedInventoryCallback(ma.to_inv.name, "on_put")) + return; + + // Call function(inv, listname, index, stack, player) + // inv + InvRef::create(L, ma.to_inv); + lua_pushstring(L, ma.to_list.c_str()); // listname + lua_pushinteger(L, ma.to_i + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 5, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} + +// Report taken items +void ScriptApiDetached::detached_inventory_OnTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Push callback function on stack + if (!getDetachedInventoryCallback(ma.from_inv.name, "on_take")) + return; + + // Call function(inv, listname, index, stack, player) + // inv + InvRef::create(L, ma.from_inv); + lua_pushstring(L, ma.from_list.c_str()); // listname + lua_pushinteger(L, ma.from_i + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 5, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} + +// Retrieves core.detached_inventories[name][callbackname] +// If that is nil or on error, return false and stack is unchanged +// If that is a function, returns true and pushes the +// function onto the stack +bool ScriptApiDetached::getDetachedInventoryCallback( + const std::string &name, const char *callbackname) +{ + lua_State *L = getStack(); + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "detached_inventories"); + lua_remove(L, -2); + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, name.c_str()); + lua_remove(L, -2); + // Should be a table + if (lua_type(L, -1) != LUA_TTABLE) { + errorstream<<"Detached inventory \""<<name<<"\" not defined"<<std::endl; + lua_pop(L, 1); + return false; + } + + setOriginFromTable(-1); + + lua_getfield(L, -1, callbackname); + lua_remove(L, -2); + // Should be a function or nil + if (lua_type(L, -1) == LUA_TFUNCTION) { + return true; + } + + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + return false; + } + + errorstream << "Detached inventory \"" << name << "\" callback \"" + << callbackname << "\" is not a function" << std::endl; + lua_pop(L, 1); + return false; +} diff --git a/src/script/cpp_api/s_inventory.h b/src/script/cpp_api/s_inventory.h new file mode 100644 index 0000000..e79b3d1 --- /dev/null +++ b/src/script/cpp_api/s_inventory.h @@ -0,0 +1,59 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" + +struct MoveAction; +struct ItemStack; + +class ScriptApiDetached + : virtual public ScriptApiBase +{ +public: + /* Detached inventory callbacks */ + // Return number of accepted items to be moved + int detached_inventory_AllowMove( + const MoveAction &ma, int count, + ServerActiveObject *player); + // Return number of accepted items to be put + int detached_inventory_AllowPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); + // Return number of accepted items to be taken + int detached_inventory_AllowTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); + // Report moved items + void detached_inventory_OnMove( + const MoveAction &ma, int count, + ServerActiveObject *player); + // Report put items + void detached_inventory_OnPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); + // Report taken items + void detached_inventory_OnTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); +private: + bool getDetachedInventoryCallback( + const std::string &name, const char *callbackname); +}; diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp new file mode 100644 index 0000000..b191607 --- /dev/null +++ b/src/script/cpp_api/s_item.cpp @@ -0,0 +1,275 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_item.h" +#include "cpp_api/s_internal.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "lua_api/l_item.h" +#include "lua_api/l_inventory.h" +#include "server.h" +#include "log.h" +#include "util/pointedthing.h" +#include "inventory.h" +#include "inventorymanager.h" + +#define WRAP_LUAERROR(e, detail) \ + LuaError(std::string(__FUNCTION__) + ": " + (e).what() + ". " detail) + +bool ScriptApiItem::item_OnDrop(ItemStack &item, + ServerActiveObject *dropper, v3f pos) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Push callback function on stack + if (!getItemCallback(item.name.c_str(), "on_drop")) + return false; + + // Call function + LuaItemStack::create(L, item); + objectrefGetOrCreate(L, dropper); + pushFloatPos(L, pos); + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + if (!lua_isnil(L, -1)) { + try { + item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw WRAP_LUAERROR(e, "item=" + item.name); + } + } + lua_pop(L, 2); // Pop item and error handler + return true; +} + +bool ScriptApiItem::item_OnPlace(Optional<ItemStack> &ret_item, + ServerActiveObject *placer, const PointedThing &pointed) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const ItemStack &item = *ret_item; + // Push callback function on stack + if (!getItemCallback(item.name.c_str(), "on_place")) + return false; + + // Call function + LuaItemStack::create(L, item); + + if (!placer) + lua_pushnil(L); + else + objectrefGetOrCreate(L, placer); + + pushPointedThing(pointed); + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + if (!lua_isnil(L, -1)) { + try { + ret_item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw WRAP_LUAERROR(e, "item=" + item.name); + } + } else { + ret_item = nullopt; + } + lua_pop(L, 2); // Pop item and error handler + return true; +} + +bool ScriptApiItem::item_OnUse(Optional<ItemStack> &ret_item, + ServerActiveObject *user, const PointedThing &pointed) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const ItemStack &item = *ret_item; + // Push callback function on stack + if (!getItemCallback(item.name.c_str(), "on_use")) + return false; + + // Call function + LuaItemStack::create(L, item); + objectrefGetOrCreate(L, user); + pushPointedThing(pointed); + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + if(!lua_isnil(L, -1)) { + try { + ret_item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw WRAP_LUAERROR(e, "item=" + item.name); + } + } else { + ret_item = nullopt; + } + lua_pop(L, 2); // Pop item and error handler + return true; +} + +bool ScriptApiItem::item_OnSecondaryUse(Optional<ItemStack> &ret_item, + ServerActiveObject *user, const PointedThing &pointed) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const ItemStack &item = *ret_item; + if (!getItemCallback(item.name.c_str(), "on_secondary_use")) + return false; + + LuaItemStack::create(L, item); + objectrefGetOrCreate(L, user); + pushPointedThing(pointed); + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + if (!lua_isnil(L, -1)) { + try { + ret_item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw WRAP_LUAERROR(e, "item=" + item.name); + } + } else { + ret_item = nullopt; + } + lua_pop(L, 2); // Pop item and error handler + return true; +} + +bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user, + const InventoryList *old_craft_grid, const InventoryLocation &craft_inv) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "on_craft"); + LuaItemStack::create(L, item); + objectrefGetOrCreate(L, user); + + // Push inventory list + std::vector<ItemStack> items; + for (u32 i = 0; i < old_craft_grid->getSize(); i++) { + items.push_back(old_craft_grid->getItem(i)); + } + push_items(L, items); + + InvRef::create(L, craft_inv); + PCALL_RES(lua_pcall(L, 4, 1, error_handler)); + if (!lua_isnil(L, -1)) { + try { + item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw WRAP_LUAERROR(e, "item=" + item.name); + } + } + lua_pop(L, 2); // Pop item and error handler + return true; +} + +bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user, + const InventoryList *old_craft_grid, const InventoryLocation &craft_inv) +{ + SCRIPTAPI_PRECHECKHEADER + sanity_check(old_craft_grid); + int error_handler = PUSH_ERROR_HANDLER(L); + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "craft_predict"); + LuaItemStack::create(L, item); + objectrefGetOrCreate(L, user); + + //Push inventory list + std::vector<ItemStack> items; + for (u32 i = 0; i < old_craft_grid->getSize(); i++) { + items.push_back(old_craft_grid->getItem(i)); + } + push_items(L, items); + + InvRef::create(L, craft_inv); + PCALL_RES(lua_pcall(L, 4, 1, error_handler)); + if (!lua_isnil(L, -1)) { + try { + item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw WRAP_LUAERROR(e, "item=" + item.name); + } + } + lua_pop(L, 2); // Pop item and error handler + return true; +} + +// Retrieves core.registered_items[name][callbackname] +// If that is nil or on error, return false and stack is unchanged +// If that is a function, returns true and pushes the +// function onto the stack +// If core.registered_items[name] doesn't exist, core.nodedef_default +// is tried instead so unknown items can still be manipulated to some degree +bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname, + const v3s16 *p) +{ + lua_State* L = getStack(); + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_items"); + lua_remove(L, -2); // Remove core + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, name); + lua_remove(L, -2); // Remove registered_items + // Should be a table + if (lua_type(L, -1) != LUA_TTABLE) { + // Report error and clean up + errorstream << "Item \"" << name << "\" not defined"; + if (p) + errorstream << " at position " << PP(*p); + errorstream << std::endl; + lua_pop(L, 1); + + // Try core.nodedef_default instead + lua_getglobal(L, "core"); + lua_getfield(L, -1, "nodedef_default"); + lua_remove(L, -2); + luaL_checktype(L, -1, LUA_TTABLE); + } + + setOriginFromTable(-1); + + lua_getfield(L, -1, callbackname); + lua_remove(L, -2); // Remove item def + // Should be a function or nil + if (lua_type(L, -1) == LUA_TFUNCTION) { + return true; + } + + if (!lua_isnil(L, -1)) { + errorstream << "Item \"" << name << "\" callback \"" + << callbackname << "\" is not a function" << std::endl; + } + lua_pop(L, 1); + return false; +} + +void ScriptApiItem::pushPointedThing(const PointedThing &pointed, bool hitpoint) +{ + lua_State* L = getStack(); + + push_pointed_thing(L, pointed, false, hitpoint); +} + diff --git a/src/script/cpp_api/s_item.h b/src/script/cpp_api/s_item.h new file mode 100644 index 0000000..5015d8b --- /dev/null +++ b/src/script/cpp_api/s_item.h @@ -0,0 +1,70 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" +#include "irr_v3d.h" +#include "util/Optional.h" + +struct PointedThing; +struct ItemStack; +class ServerActiveObject; +struct ItemDefinition; +class LuaItemStack; +class ModApiItemMod; +class InventoryList; +struct InventoryLocation; + +class ScriptApiItem +: virtual public ScriptApiBase +{ +public: + /* + * Functions with Optional<ItemStack> are for callbacks where Lua may + * want to prevent the engine from modifying the inventory after it's done. + * This has a longer backstory where on_use may need to empty the player's + * inventory without the engine interfering (see issue #6546). + */ + + bool item_OnDrop(ItemStack &item, + ServerActiveObject *dropper, v3f pos); + bool item_OnPlace(Optional<ItemStack> &item, + ServerActiveObject *placer, const PointedThing &pointed); + bool item_OnUse(Optional<ItemStack> &item, + ServerActiveObject *user, const PointedThing &pointed); + bool item_OnSecondaryUse(Optional<ItemStack> &item, + ServerActiveObject *user, const PointedThing &pointed); + bool item_OnCraft(ItemStack &item, ServerActiveObject *user, + const InventoryList *old_craft_grid, const InventoryLocation &craft_inv); + bool item_CraftPredict(ItemStack &item, ServerActiveObject *user, + const InventoryList *old_craft_grid, const InventoryLocation &craft_inv); + +protected: + friend class LuaItemStack; + friend class ModApiItemMod; + + bool getItemCallback(const char *name, const char *callbackname, const v3s16 *p = nullptr); + /*! + * Pushes a `pointed_thing` tabe to the stack. + * \param hitpoint If true, the exact pointing location is also pushed + */ + void pushPointedThing(const PointedThing &pointed, bool hitpoint = false); + +}; diff --git a/src/script/cpp_api/s_mainmenu.cpp b/src/script/cpp_api/s_mainmenu.cpp new file mode 100644 index 0000000..1e9ba3a --- /dev/null +++ b/src/script/cpp_api/s_mainmenu.cpp @@ -0,0 +1,93 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_mainmenu.h" +#include "cpp_api/s_internal.h" +#include "common/c_converter.h" + +void ScriptApiMainMenu::setMainMenuData(MainMenuDataForScript *data) +{ + SCRIPTAPI_PRECHECKHEADER + + lua_getglobal(L, "gamedata"); + int gamedata_idx = lua_gettop(L); + lua_pushstring(L, "errormessage"); + if (!data->errormessage.empty()) { + lua_pushstring(L, data->errormessage.c_str()); + } else { + lua_pushnil(L); + } + lua_settable(L, gamedata_idx); + setboolfield(L, gamedata_idx, "reconnect_requested", data->reconnect_requested); + lua_pop(L, 1); +} + +void ScriptApiMainMenu::handleMainMenuEvent(std::string text) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get handler function + lua_getglobal(L, "core"); + lua_getfield(L, -1, "event_handler"); + lua_remove(L, -2); // Remove core + if (lua_isnil(L, -1)) { + lua_pop(L, 1); // Pop event_handler + return; + } + luaL_checktype(L, -1, LUA_TFUNCTION); + + // Call it + lua_pushstring(L, text.c_str()); + PCALL_RES(lua_pcall(L, 1, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} + +void ScriptApiMainMenu::handleMainMenuButtons(const StringMap &fields) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get handler function + lua_getglobal(L, "core"); + lua_getfield(L, -1, "button_handler"); + lua_remove(L, -2); // Remove core + if (lua_isnil(L, -1)) { + lua_pop(L, 1); // Pop button handler + return; + } + luaL_checktype(L, -1, LUA_TFUNCTION); + + // Convert fields to a Lua table + lua_newtable(L); + StringMap::const_iterator it; + for (it = fields.begin(); it != fields.end(); ++it) { + const std::string &name = it->first; + const std::string &value = it->second; + lua_pushstring(L, name.c_str()); + lua_pushlstring(L, value.c_str(), value.size()); + lua_settable(L, -3); + } + + // Call it + PCALL_RES(lua_pcall(L, 1, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} diff --git a/src/script/cpp_api/s_mainmenu.h b/src/script/cpp_api/s_mainmenu.h new file mode 100644 index 0000000..470577a --- /dev/null +++ b/src/script/cpp_api/s_mainmenu.h @@ -0,0 +1,45 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" +#include "util/string.h" +#include "gui/guiMainMenu.h" + +class ScriptApiMainMenu : virtual public ScriptApiBase { +public: + /** + * Hand over MainMenuDataForScript to lua to inform lua of the content + * @param data the data + */ + void setMainMenuData(MainMenuDataForScript *data); + + /** + * process events received from formspec + * @param text events in textual form + */ + void handleMainMenuEvent(std::string text); + + /** + * process field data received from formspec + * @param fields data in field format + */ + void handleMainMenuButtons(const StringMap &fields); +}; diff --git a/src/script/cpp_api/s_modchannels.cpp b/src/script/cpp_api/s_modchannels.cpp new file mode 100644 index 0000000..caff3f0 --- /dev/null +++ b/src/script/cpp_api/s_modchannels.cpp @@ -0,0 +1,50 @@ +/* +Minetest +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "s_modchannels.h" +#include "s_internal.h" + +void ScriptApiModChannels::on_modchannel_message(const std::string &channel, + const std::string &sender, const std::string &message) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_generateds + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_modchannel_message"); + // Call callbacks + lua_pushstring(L, channel.c_str()); + lua_pushstring(L, sender.c_str()); + lua_pushstring(L, message.c_str()); + runCallbacks(3, RUN_CALLBACKS_MODE_AND); +} + +void ScriptApiModChannels::on_modchannel_signal( + const std::string &channel, ModChannelSignal signal) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_generateds + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_modchannel_signal"); + // Call callbacks + lua_pushstring(L, channel.c_str()); + lua_pushinteger(L, (int)signal); + runCallbacks(2, RUN_CALLBACKS_MODE_AND); +} diff --git a/src/script/cpp_api/s_modchannels.h b/src/script/cpp_api/s_modchannels.h new file mode 100644 index 0000000..4de7a82 --- /dev/null +++ b/src/script/cpp_api/s_modchannels.h @@ -0,0 +1,31 @@ +/* +Minetest +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" +#include "modchannels.h" + +class ScriptApiModChannels : virtual public ScriptApiBase +{ +public: + void on_modchannel_message(const std::string &channel, const std::string &sender, + const std::string &message); + void on_modchannel_signal(const std::string &channel, ModChannelSignal signal); +}; diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp new file mode 100644 index 0000000..029cb63 --- /dev/null +++ b/src/script/cpp_api/s_node.cpp @@ -0,0 +1,286 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_node.h" +#include "cpp_api/s_internal.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "nodedef.h" +#include "server.h" +#include "environment.h" +#include "util/pointedthing.h" + + +// Should be ordered exactly like enum NodeDrawType in nodedef.h +struct EnumString ScriptApiNode::es_DrawType[] = + { + {NDT_NORMAL, "normal"}, + {NDT_AIRLIKE, "airlike"}, + {NDT_LIQUID, "liquid"}, + {NDT_FLOWINGLIQUID, "flowingliquid"}, + {NDT_GLASSLIKE, "glasslike"}, + {NDT_ALLFACES, "allfaces"}, + {NDT_ALLFACES_OPTIONAL, "allfaces_optional"}, + {NDT_TORCHLIKE, "torchlike"}, + {NDT_SIGNLIKE, "signlike"}, + {NDT_PLANTLIKE, "plantlike"}, + {NDT_FENCELIKE, "fencelike"}, + {NDT_RAILLIKE, "raillike"}, + {NDT_NODEBOX, "nodebox"}, + {NDT_GLASSLIKE_FRAMED, "glasslike_framed"}, + {NDT_FIRELIKE, "firelike"}, + {NDT_GLASSLIKE_FRAMED_OPTIONAL, "glasslike_framed_optional"}, + {NDT_MESH, "mesh"}, + {NDT_PLANTLIKE_ROOTED, "plantlike_rooted"}, + {0, NULL}, + }; + +struct EnumString ScriptApiNode::es_ContentParamType2[] = + { + {CPT2_NONE, "none"}, + {CPT2_FULL, "full"}, + {CPT2_FLOWINGLIQUID, "flowingliquid"}, + {CPT2_FACEDIR, "facedir"}, + {CPT2_WALLMOUNTED, "wallmounted"}, + {CPT2_LEVELED, "leveled"}, + {CPT2_DEGROTATE, "degrotate"}, + {CPT2_MESHOPTIONS, "meshoptions"}, + {CPT2_COLOR, "color"}, + {CPT2_COLORED_FACEDIR, "colorfacedir"}, + {CPT2_COLORED_WALLMOUNTED, "colorwallmounted"}, + {CPT2_GLASSLIKE_LIQUID_LEVEL, "glasslikeliquidlevel"}, + {CPT2_COLORED_DEGROTATE, "colordegrotate"}, + {0, NULL}, + }; + +struct EnumString ScriptApiNode::es_LiquidType[] = + { + {LIQUID_NONE, "none"}, + {LIQUID_FLOWING, "flowing"}, + {LIQUID_SOURCE, "source"}, + {0, NULL}, + }; + +struct EnumString ScriptApiNode::es_ContentParamType[] = + { + {CPT_NONE, "none"}, + {CPT_LIGHT, "light"}, + {0, NULL}, + }; + +struct EnumString ScriptApiNode::es_NodeBoxType[] = + { + {NODEBOX_REGULAR, "regular"}, + {NODEBOX_FIXED, "fixed"}, + {NODEBOX_WALLMOUNTED, "wallmounted"}, + {NODEBOX_LEVELED, "leveled"}, + {NODEBOX_CONNECTED, "connected"}, + {0, NULL}, + }; + +struct EnumString ScriptApiNode::es_TextureAlphaMode[] = + { + {ALPHAMODE_OPAQUE, "opaque"}, + {ALPHAMODE_CLIP, "clip"}, + {ALPHAMODE_BLEND, "blend"}, + {0, NULL}, + }; + +bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node, + ServerActiveObject *puncher, const PointedThing &pointed) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // Push callback function on stack + if (!getItemCallback(ndef->get(node).name.c_str(), "on_punch", &p)) + return false; + + // Call function + push_v3s16(L, p); + pushnode(L, node, ndef); + objectrefGetOrCreate(L, puncher); + pushPointedThing(pointed); + PCALL_RES(lua_pcall(L, 4, 0, error_handler)); + lua_pop(L, 1); // Pop error handler + return true; +} + +bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node, + ServerActiveObject *digger) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // Push callback function on stack + if (!getItemCallback(ndef->get(node).name.c_str(), "on_dig", &p)) + return false; + + // Call function + push_v3s16(L, p); + pushnode(L, node, ndef); + objectrefGetOrCreate(L, digger); + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + + // nil is treated as true for backwards compat + bool result = lua_isnil(L, -1) || lua_toboolean(L, -1); + + lua_pop(L, 2); // Pop error handler and result + + return result; +} + +void ScriptApiNode::node_on_construct(v3s16 p, MapNode node) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // Push callback function on stack + if (!getItemCallback(ndef->get(node).name.c_str(), "on_construct", &p)) + return; + + // Call function + push_v3s16(L, p); + PCALL_RES(lua_pcall(L, 1, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} + +void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // Push callback function on stack + if (!getItemCallback(ndef->get(node).name.c_str(), "on_destruct", &p)) + return; + + // Call function + push_v3s16(L, p); + PCALL_RES(lua_pcall(L, 1, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} + +bool ScriptApiNode::node_on_flood(v3s16 p, MapNode node, MapNode newnode) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // Push callback function on stack + if (!getItemCallback(ndef->get(node).name.c_str(), "on_flood", &p)) + return false; + + // Call function + push_v3s16(L, p); + pushnode(L, node, ndef); + pushnode(L, newnode, ndef); + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + lua_remove(L, error_handler); + return readParam<bool>(L, -1, false); +} + +void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // Push callback function on stack + if (!getItemCallback(ndef->get(node).name.c_str(), "after_destruct", &p)) + return; + + // Call function + push_v3s16(L, p); + pushnode(L, node, ndef); + PCALL_RES(lua_pcall(L, 2, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} + +bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // Push callback function on stack + if (!getItemCallback(ndef->get(node).name.c_str(), "on_timer", &p)) + return false; + + // Call function + push_v3s16(L, p); + lua_pushnumber(L,dtime); + PCALL_RES(lua_pcall(L, 2, 1, error_handler)); + lua_remove(L, error_handler); + return readParam<bool>(L, -1, false); +} + +void ScriptApiNode::node_on_receive_fields(v3s16 p, + const std::string &formname, + const StringMap &fields, + ServerActiveObject *sender) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // If node doesn't exist, we don't know what callback to call + MapNode node = getEnv()->getMap().getNode(p); + if (node.getContent() == CONTENT_IGNORE) + return; + + // Push callback function on stack + if (!getItemCallback(ndef->get(node).name.c_str(), "on_receive_fields", &p)) + return; + + // Call function + push_v3s16(L, p); // pos + lua_pushstring(L, formname.c_str()); // formname + lua_newtable(L); // fields + StringMap::const_iterator it; + for (it = fields.begin(); it != fields.end(); ++it) { + const std::string &name = it->first; + const std::string &value = it->second; + lua_pushstring(L, name.c_str()); + lua_pushlstring(L, value.c_str(), value.size()); + lua_settable(L, -3); + } + objectrefGetOrCreate(L, sender); // player + PCALL_RES(lua_pcall(L, 4, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} diff --git a/src/script/cpp_api/s_node.h b/src/script/cpp_api/s_node.h new file mode 100644 index 0000000..3c6a844 --- /dev/null +++ b/src/script/cpp_api/s_node.h @@ -0,0 +1,59 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_v3d.h" +#include "cpp_api/s_base.h" +#include "cpp_api/s_nodemeta.h" +#include "util/string.h" + +struct MapNode; +class ServerActiveObject; + +class ScriptApiNode + : virtual public ScriptApiBase, + public ScriptApiNodemeta +{ +public: + ScriptApiNode() = default; + virtual ~ScriptApiNode() = default; + + bool node_on_punch(v3s16 p, MapNode node, + ServerActiveObject *puncher, const PointedThing &pointed); + bool node_on_dig(v3s16 p, MapNode node, + ServerActiveObject *digger); + void node_on_construct(v3s16 p, MapNode node); + void node_on_destruct(v3s16 p, MapNode node); + bool node_on_flood(v3s16 p, MapNode node, MapNode newnode); + void node_after_destruct(v3s16 p, MapNode node); + bool node_on_timer(v3s16 p, MapNode node, f32 dtime); + void node_on_receive_fields(v3s16 p, + const std::string &formname, + const StringMap &fields, + ServerActiveObject *sender); +public: + static struct EnumString es_DrawType[]; + static struct EnumString es_ContentParamType[]; + static struct EnumString es_ContentParamType2[]; + static struct EnumString es_LiquidType[]; + static struct EnumString es_LiquidMoveType[]; + static struct EnumString es_NodeBoxType[]; + static struct EnumString es_TextureAlphaMode[]; +}; diff --git a/src/script/cpp_api/s_nodemeta.cpp b/src/script/cpp_api/s_nodemeta.cpp new file mode 100644 index 0000000..7ab3757 --- /dev/null +++ b/src/script/cpp_api/s_nodemeta.cpp @@ -0,0 +1,232 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_nodemeta.h" +#include "cpp_api/s_internal.h" +#include "common/c_converter.h" +#include "nodedef.h" +#include "mapnode.h" +#include "server.h" +#include "environment.h" +#include "lua_api/l_item.h" + +// Return number of accepted items to be moved +int ScriptApiNodemeta::nodemeta_inventory_AllowMove( + const MoveAction &ma, int count, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // If node doesn't exist, we don't know what callback to call + MapNode node = getEnv()->getMap().getNode(ma.to_inv.p); + if (node.getContent() == CONTENT_IGNORE) + return 0; + + // Push callback function on stack + const auto &nodename = ndef->get(node).name; + if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_move", &ma.to_inv.p)) + return count; + + // function(pos, from_list, from_index, to_list, to_index, count, player) + push_v3s16(L, ma.to_inv.p); // pos + lua_pushstring(L, ma.from_list.c_str()); // from_list + lua_pushinteger(L, ma.from_i + 1); // from_index + lua_pushstring(L, ma.to_list.c_str()); // to_list + lua_pushinteger(L, ma.to_i + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 7, 1, error_handler)); + if (!lua_isnumber(L, -1)) + throw LuaError("allow_metadata_inventory_move should" + " return a number. node=" + nodename); + int num = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return num; +} + +// Return number of accepted items to be put +int ScriptApiNodemeta::nodemeta_inventory_AllowPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // If node doesn't exist, we don't know what callback to call + MapNode node = getEnv()->getMap().getNode(ma.to_inv.p); + if (node.getContent() == CONTENT_IGNORE) + return 0; + + // Push callback function on stack + const auto &nodename = ndef->get(node).name; + if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_put", &ma.to_inv.p)) + return stack.count; + + // Call function(pos, listname, index, stack, player) + push_v3s16(L, ma.to_inv.p); // pos + lua_pushstring(L, ma.to_list.c_str()); // listname + lua_pushinteger(L, ma.to_i + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 5, 1, error_handler)); + if(!lua_isnumber(L, -1)) + throw LuaError("allow_metadata_inventory_put should" + " return a number. node=" + nodename); + int num = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return num; +} + +// Return number of accepted items to be taken +int ScriptApiNodemeta::nodemeta_inventory_AllowTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // If node doesn't exist, we don't know what callback to call + MapNode node = getEnv()->getMap().getNode(ma.from_inv.p); + if (node.getContent() == CONTENT_IGNORE) + return 0; + + // Push callback function on stack + const auto &nodename = ndef->get(node).name; + if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_take", &ma.from_inv.p)) + return stack.count; + + // Call function(pos, listname, index, count, player) + push_v3s16(L, ma.from_inv.p); // pos + lua_pushstring(L, ma.from_list.c_str()); // listname + lua_pushinteger(L, ma.from_i + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 5, 1, error_handler)); + if (!lua_isnumber(L, -1)) + throw LuaError("allow_metadata_inventory_take should" + " return a number. node=" + nodename); + int num = luaL_checkinteger(L, -1); + lua_pop(L, 2); // Pop integer and error handler + return num; +} + +// Report moved items +void ScriptApiNodemeta::nodemeta_inventory_OnMove( + const MoveAction &ma, int count, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // If node doesn't exist, we don't know what callback to call + MapNode node = getEnv()->getMap().getNode(ma.from_inv.p); + if (node.getContent() == CONTENT_IGNORE) + return; + + // Push callback function on stack + const auto &nodename = ndef->get(node).name; + if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_move", &ma.from_inv.p)) + return; + + // function(pos, from_list, from_index, to_list, to_index, count, player) + push_v3s16(L, ma.from_inv.p); // pos + lua_pushstring(L, ma.from_list.c_str()); // from_list + lua_pushinteger(L, ma.from_i + 1); // from_index + lua_pushstring(L, ma.to_list.c_str()); // to_list + lua_pushinteger(L, ma.to_i + 1); // to_index + lua_pushinteger(L, count); // count + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 7, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} + +// Report put items +void ScriptApiNodemeta::nodemeta_inventory_OnPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // If node doesn't exist, we don't know what callback to call + MapNode node = getEnv()->getMap().getNode(ma.to_inv.p); + if (node.getContent() == CONTENT_IGNORE) + return; + + // Push callback function on stack + const auto &nodename = ndef->get(node).name; + if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_put", &ma.to_inv.p)) + return; + + // Call function(pos, listname, index, stack, player) + push_v3s16(L, ma.to_inv.p); // pos + lua_pushstring(L, ma.to_list.c_str()); // listname + lua_pushinteger(L, ma.to_i + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 5, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} + +// Report taken items +void ScriptApiNodemeta::nodemeta_inventory_OnTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + const NodeDefManager *ndef = getServer()->ndef(); + + // If node doesn't exist, we don't know what callback to call + MapNode node = getEnv()->getMap().getNode(ma.from_inv.p); + if (node.getContent() == CONTENT_IGNORE) + return; + + // Push callback function on stack + const auto &nodename = ndef->get(node).name; + if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_take", &ma.from_inv.p)) + return; + + // Call function(pos, listname, index, stack, player) + push_v3s16(L, ma.from_inv.p); // pos + lua_pushstring(L, ma.from_list.c_str()); // listname + lua_pushinteger(L, ma.from_i + 1); // index + LuaItemStack::create(L, stack); // stack + objectrefGetOrCreate(L, player); // player + PCALL_RES(lua_pcall(L, 5, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} diff --git a/src/script/cpp_api/s_nodemeta.h b/src/script/cpp_api/s_nodemeta.h new file mode 100644 index 0000000..8c7cdd9 --- /dev/null +++ b/src/script/cpp_api/s_nodemeta.h @@ -0,0 +1,63 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" +#include "cpp_api/s_item.h" +#include "irr_v3d.h" + +struct MoveAction; +struct ItemStack; + +class ScriptApiNodemeta + : virtual public ScriptApiBase, + public ScriptApiItem +{ +public: + ScriptApiNodemeta() = default; + virtual ~ScriptApiNodemeta() = default; + + // Return number of accepted items to be moved + int nodemeta_inventory_AllowMove( + const MoveAction &ma, int count, + ServerActiveObject *player); + // Return number of accepted items to be put + int nodemeta_inventory_AllowPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); + // Return number of accepted items to be taken + int nodemeta_inventory_AllowTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); + // Report moved items + void nodemeta_inventory_OnMove( + const MoveAction &ma, int count, + ServerActiveObject *player); + // Report put items + void nodemeta_inventory_OnPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); + // Report taken items + void nodemeta_inventory_OnTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); +private: + +}; diff --git a/src/script/cpp_api/s_player.cpp b/src/script/cpp_api/s_player.cpp new file mode 100644 index 0000000..22b24f3 --- /dev/null +++ b/src/script/cpp_api/s_player.cpp @@ -0,0 +1,382 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_player.h" +#include "cpp_api/s_internal.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "debug.h" +#include "inventorymanager.h" +#include "lua_api/l_inventory.h" +#include "lua_api/l_item.h" +#include "util/string.h" + +void ScriptApiPlayer::on_newplayer(ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_newplayers + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_newplayers"); + // Call callbacks + objectrefGetOrCreate(L, player); + runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); +} + +void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player, const PlayerHPChangeReason &reason) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get callback table + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_dieplayers"); + + // Push arguments + objectrefGetOrCreate(L, player); + pushPlayerHPChangeReason(L, reason); + + // Run callbacks + runCallbacks(2, RUN_CALLBACKS_MODE_FIRST); +} + +bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player, + ServerActiveObject *hitter, + float time_from_last_punch, + const ToolCapabilities *toolcap, + v3f dir, + s32 damage) +{ + SCRIPTAPI_PRECHECKHEADER + // Get core.registered_on_punchplayers + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_punchplayers"); + // Call callbacks + objectrefGetOrCreate(L, player); + objectrefGetOrCreate(L, hitter); + lua_pushnumber(L, time_from_last_punch); + push_tool_capabilities(L, *toolcap); + push_v3f(L, dir); + lua_pushnumber(L, damage); + runCallbacks(6, RUN_CALLBACKS_MODE_OR); + return readParam<bool>(L, -1); +} + +void ScriptApiPlayer::on_rightclickplayer(ServerActiveObject *player, + ServerActiveObject *clicker) +{ + SCRIPTAPI_PRECHECKHEADER + // Get core.registered_on_rightclickplayers + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_rightclickplayers"); + // Call callbacks + objectrefGetOrCreate(L, player); + objectrefGetOrCreate(L, clicker); + runCallbacks(2, RUN_CALLBACKS_MODE_FIRST); +} + +s32 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player, + s32 hp_change, const PlayerHPChangeReason &reason) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get core.registered_on_player_hpchange + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_player_hpchange"); + lua_remove(L, -2); + + // Push arguments + objectrefGetOrCreate(L, player); + lua_pushnumber(L, hp_change); + pushPlayerHPChangeReason(L, reason); + + // Call callbacks + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + hp_change = lua_tointeger(L, -1); + lua_pop(L, 2); // Pop result and error handler + return hp_change; +} + +bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_respawnplayers + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_respawnplayers"); + // Call callbacks + objectrefGetOrCreate(L, player); + runCallbacks(1, RUN_CALLBACKS_MODE_OR); + return readParam<bool>(L, -1); +} + +bool ScriptApiPlayer::on_prejoinplayer( + const std::string &name, + const std::string &ip, + std::string *reason) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_prejoinplayers + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_prejoinplayers"); + lua_pushstring(L, name.c_str()); + lua_pushstring(L, ip.c_str()); + runCallbacks(2, RUN_CALLBACKS_MODE_OR); + if (lua_isstring(L, -1)) { + reason->assign(readParam<std::string>(L, -1)); + return true; + } + return false; +} + +bool ScriptApiPlayer::can_bypass_userlimit(const std::string &name, const std::string &ip) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_prejoinplayers + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_can_bypass_userlimit"); + lua_pushstring(L, name.c_str()); + lua_pushstring(L, ip.c_str()); + runCallbacks(2, RUN_CALLBACKS_MODE_OR); + return lua_toboolean(L, -1); +} + +void ScriptApiPlayer::on_joinplayer(ServerActiveObject *player, s64 last_login) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_joinplayers + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_joinplayers"); + // Call callbacks + objectrefGetOrCreate(L, player); + if (last_login != -1) + lua_pushinteger(L, last_login); + else + lua_pushnil(L); + runCallbacks(2, RUN_CALLBACKS_MODE_FIRST); +} + +void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player, + bool timeout) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_leaveplayers + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_leaveplayers"); + // Call callbacks + objectrefGetOrCreate(L, player); + lua_pushboolean(L, timeout); + runCallbacks(2, RUN_CALLBACKS_MODE_FIRST); +} + +void ScriptApiPlayer::on_cheat(ServerActiveObject *player, + const std::string &cheat_type) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_cheats + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_cheats"); + // Call callbacks + objectrefGetOrCreate(L, player); + lua_newtable(L); + lua_pushlstring(L, cheat_type.c_str(), cheat_type.size()); + lua_setfield(L, -2, "type"); + runCallbacks(2, RUN_CALLBACKS_MODE_FIRST); +} + +void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player, + const std::string &formname, + const StringMap &fields) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_player_receive_fields + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_player_receive_fields"); + // Call callbacks + // param 1 + objectrefGetOrCreate(L, player); + // param 2 + lua_pushstring(L, formname.c_str()); + // param 3 + lua_newtable(L); + StringMap::const_iterator it; + for (it = fields.begin(); it != fields.end(); ++it) { + const std::string &name = it->first; + const std::string &value = it->second; + lua_pushstring(L, name.c_str()); + lua_pushlstring(L, value.c_str(), value.size()); + lua_settable(L, -3); + } + runCallbacks(3, RUN_CALLBACKS_MODE_OR_SC); +} + +void ScriptApiPlayer::on_authplayer(const std::string &name, const std::string &ip, bool is_success) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_authplayers + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_authplayers"); + + // Call callbacks + lua_pushstring(L, name.c_str()); + lua_pushstring(L, ip.c_str()); + lua_pushboolean(L, is_success); + runCallbacks(3, RUN_CALLBACKS_MODE_FIRST); +} + +void ScriptApiPlayer::pushMoveArguments( + const MoveAction &ma, int count, + ServerActiveObject *player) +{ + lua_State *L = getStack(); + objectrefGetOrCreate(L, player); // player + lua_pushstring(L, "move"); // action + InvRef::create(L, ma.from_inv); // inventory + lua_newtable(L); + { + // Table containing the action information + lua_pushstring(L, ma.from_list.c_str()); + lua_setfield(L, -2, "from_list"); + lua_pushstring(L, ma.to_list.c_str()); + lua_setfield(L, -2, "to_list"); + + lua_pushinteger(L, ma.from_i + 1); + lua_setfield(L, -2, "from_index"); + lua_pushinteger(L, ma.to_i + 1); + lua_setfield(L, -2, "to_index"); + + lua_pushinteger(L, count); + lua_setfield(L, -2, "count"); + } +} + +void ScriptApiPlayer::pushPutTakeArguments( + const char *method, const InventoryLocation &loc, + const std::string &listname, int index, const ItemStack &stack, + ServerActiveObject *player) +{ + lua_State *L = getStack(); + objectrefGetOrCreate(L, player); // player + lua_pushstring(L, method); // action + InvRef::create(L, loc); // inventory + lua_newtable(L); + { + // Table containing the action information + lua_pushstring(L, listname.c_str()); + lua_setfield(L, -2, "listname"); + + lua_pushinteger(L, index + 1); + lua_setfield(L, -2, "index"); + + LuaItemStack::create(L, stack); + lua_setfield(L, -2, "stack"); + } +} + +// Return number of accepted items to be moved +int ScriptApiPlayer::player_inventory_AllowMove( + const MoveAction &ma, int count, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_allow_player_inventory_actions"); + pushMoveArguments(ma, count, player); + runCallbacks(4, RUN_CALLBACKS_MODE_OR_SC); + + return lua_type(L, -1) == LUA_TNUMBER ? lua_tonumber(L, -1) : count; +} + +// Return number of accepted items to be put +int ScriptApiPlayer::player_inventory_AllowPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_allow_player_inventory_actions"); + pushPutTakeArguments("put", ma.to_inv, ma.to_list, ma.to_i, stack, player); + runCallbacks(4, RUN_CALLBACKS_MODE_OR_SC); + + return lua_type(L, -1) == LUA_TNUMBER ? lua_tonumber(L, -1) : stack.count; +} + +// Return number of accepted items to be taken +int ScriptApiPlayer::player_inventory_AllowTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_allow_player_inventory_actions"); + pushPutTakeArguments("take", ma.from_inv, ma.from_list, ma.from_i, stack, player); + runCallbacks(4, RUN_CALLBACKS_MODE_OR_SC); + + return lua_type(L, -1) == LUA_TNUMBER ? lua_tonumber(L, -1) : stack.count; +} + +// Report moved items +void ScriptApiPlayer::player_inventory_OnMove( + const MoveAction &ma, int count, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_player_inventory_actions"); + pushMoveArguments(ma, count, player); + runCallbacks(4, RUN_CALLBACKS_MODE_FIRST); +} + +// Report put items +void ScriptApiPlayer::player_inventory_OnPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_player_inventory_actions"); + pushPutTakeArguments("put", ma.to_inv, ma.to_list, ma.to_i, stack, player); + runCallbacks(4, RUN_CALLBACKS_MODE_FIRST); +} + +// Report taken items +void ScriptApiPlayer::player_inventory_OnTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_player_inventory_actions"); + pushPutTakeArguments("take", ma.from_inv, ma.from_list, ma.from_i, stack, player); + runCallbacks(4, RUN_CALLBACKS_MODE_FIRST); +} diff --git a/src/script/cpp_api/s_player.h b/src/script/cpp_api/s_player.h new file mode 100644 index 0000000..e866aee --- /dev/null +++ b/src/script/cpp_api/s_player.h @@ -0,0 +1,89 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" +#include "irr_v3d.h" +#include "util/string.h" + +struct MoveAction; +struct InventoryLocation; +struct ItemStack; +struct ToolCapabilities; +struct PlayerHPChangeReason; +class ServerActiveObject; + +class ScriptApiPlayer : virtual public ScriptApiBase +{ +public: + virtual ~ScriptApiPlayer() = default; + + void on_newplayer(ServerActiveObject *player); + void on_dieplayer(ServerActiveObject *player, const PlayerHPChangeReason &reason); + bool on_respawnplayer(ServerActiveObject *player); + bool on_prejoinplayer(const std::string &name, const std::string &ip, + std::string *reason); + bool can_bypass_userlimit(const std::string &name, const std::string &ip); + void on_joinplayer(ServerActiveObject *player, s64 last_login); + void on_leaveplayer(ServerActiveObject *player, bool timeout); + void on_cheat(ServerActiveObject *player, const std::string &cheat_type); + bool on_punchplayer(ServerActiveObject *player, ServerActiveObject *hitter, + float time_from_last_punch, const ToolCapabilities *toolcap, + v3f dir, s32 damage); + void on_rightclickplayer(ServerActiveObject *player, ServerActiveObject *clicker); + s32 on_player_hpchange(ServerActiveObject *player, s32 hp_change, + const PlayerHPChangeReason &reason); + void on_playerReceiveFields(ServerActiveObject *player, + const std::string &formname, const StringMap &fields); + void on_authplayer(const std::string &name, const std::string &ip, bool is_success); + + // Player inventory callbacks + // Return number of accepted items to be moved + int player_inventory_AllowMove( + const MoveAction &ma, int count, + ServerActiveObject *player); + // Return number of accepted items to be put + int player_inventory_AllowPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); + // Return number of accepted items to be taken + int player_inventory_AllowTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); + // Report moved items + void player_inventory_OnMove( + const MoveAction &ma, int count, + ServerActiveObject *player); + // Report put items + void player_inventory_OnPut( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); + // Report taken items + void player_inventory_OnTake( + const MoveAction &ma, const ItemStack &stack, + ServerActiveObject *player); +private: + void pushPutTakeArguments( + const char *method, const InventoryLocation &loc, + const std::string &listname, int index, const ItemStack &stack, + ServerActiveObject *player); + void pushMoveArguments(const MoveAction &ma, + int count, ServerActiveObject *player); +}; diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp new file mode 100644 index 0000000..316b199 --- /dev/null +++ b/src/script/cpp_api/s_security.cpp @@ -0,0 +1,901 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_security.h" +#include "lua_api/l_base.h" +#include "filesys.h" +#include "porting.h" +#include "server.h" +#include "client/client.h" +#include "settings.h" + +#include <cerrno> +#include <string> +#include <algorithm> +#include <iostream> + + +#define SECURE_API(lib, name) \ + lua_pushcfunction(L, sl_##lib##_##name); \ + lua_setfield(L, -2, #name); + + +static inline void copy_safe(lua_State *L, const char *list[], unsigned len, int from=-2, int to=-1) +{ + if (from < 0) from = lua_gettop(L) + from + 1; + if (to < 0) to = lua_gettop(L) + to + 1; + for (unsigned i = 0; i < (len / sizeof(list[0])); i++) { + lua_getfield(L, from, list[i]); + lua_setfield(L, to, list[i]); + } +} + +static void shallow_copy_table(lua_State *L, int from=-2, int to=-1) +{ + if (from < 0) from = lua_gettop(L) + from + 1; + if (to < 0) to = lua_gettop(L) + to + 1; + lua_pushnil(L); + while (lua_next(L, from) != 0) { + assert(lua_type(L, -1) != LUA_TTABLE); + // duplicate key and value for lua_rawset + lua_pushvalue(L, -2); + lua_pushvalue(L, -2); + lua_rawset(L, to); + lua_pop(L, 1); + } +} + +// Pushes the original version of a library function on the stack, from the old version +static inline void push_original(lua_State *L, const char *lib, const char *func) +{ + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP); + lua_getfield(L, -1, lib); + lua_remove(L, -2); // Remove globals_backup + lua_getfield(L, -1, func); + lua_remove(L, -2); // Remove lib +} + + +void ScriptApiSecurity::initializeSecurity() +{ + static const char *whitelist[] = { + "assert", + "core", + "collectgarbage", + "DIR_DELIM", + "error", + "getfenv", + "getmetatable", + "ipairs", + "next", + "pairs", + "pcall", + "print", + "rawequal", + "rawget", + "rawset", + "select", + "setfenv", + "setmetatable", + "tonumber", + "tostring", + "type", + "unpack", + "_VERSION", + "vector", + "xpcall", + }; + static const char *whitelist_tables[] = { + // These libraries are completely safe BUT we need to duplicate their table + // to ensure the sandbox can't affect the insecure env + "coroutine", + "string", + "table", + "math", + "bit" + }; + static const char *io_whitelist[] = { + "close", + "flush", + "read", + "type", + "write", + }; + static const char *os_whitelist[] = { + "clock", + "date", + "difftime", + "getenv", + "time", + }; + static const char *debug_whitelist[] = { + "gethook", + "traceback", + "getinfo", + "upvalueid", + "sethook", + "debug", + }; + static const char *package_whitelist[] = { + "config", + "cpath", + "path", + "searchpath", + }; +#if USE_LUAJIT + static const char *jit_whitelist[] = { + "arch", + "flush", + "off", + "on", + "opt", + "os", + "status", + "version", + "version_num", + }; +#endif + m_secure = true; + + lua_State *L = getStack(); + + // Backup globals to the registry + lua_getglobal(L, "_G"); + lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP); + + // Replace the global environment with an empty one + int thread = getThread(L); + createEmptyEnv(L); + setLuaEnv(L, thread); + + // Get old globals + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP); + int old_globals = lua_gettop(L); + + + // Copy safe base functions + lua_getglobal(L, "_G"); + copy_safe(L, whitelist, sizeof(whitelist)); + + // And replace unsafe ones + SECURE_API(g, dofile); + SECURE_API(g, load); + SECURE_API(g, loadfile); + SECURE_API(g, loadstring); + SECURE_API(g, require); + lua_pop(L, 1); + + + // Copy safe libraries + for (const char *libname : whitelist_tables) { + lua_getfield(L, old_globals, libname); + lua_newtable(L); + shallow_copy_table(L); + + lua_setglobal(L, libname); + lua_pop(L, 1); + } + + + // Copy safe IO functions + lua_getfield(L, old_globals, "io"); + lua_newtable(L); + copy_safe(L, io_whitelist, sizeof(io_whitelist)); + + // And replace unsafe ones + SECURE_API(io, open); + SECURE_API(io, input); + SECURE_API(io, output); + SECURE_API(io, lines); + + lua_setglobal(L, "io"); + lua_pop(L, 1); // Pop old IO + + + // Copy safe OS functions + lua_getfield(L, old_globals, "os"); + lua_newtable(L); + copy_safe(L, os_whitelist, sizeof(os_whitelist)); + + // And replace unsafe ones + SECURE_API(os, remove); + SECURE_API(os, rename); + SECURE_API(os, setlocale); + + lua_setglobal(L, "os"); + lua_pop(L, 1); // Pop old OS + + + // Copy safe debug functions + lua_getfield(L, old_globals, "debug"); + lua_newtable(L); + copy_safe(L, debug_whitelist, sizeof(debug_whitelist)); + lua_setglobal(L, "debug"); + lua_pop(L, 1); // Pop old debug + + + // Copy safe package fields + lua_getfield(L, old_globals, "package"); + lua_newtable(L); + copy_safe(L, package_whitelist, sizeof(package_whitelist)); + lua_setglobal(L, "package"); + lua_pop(L, 1); // Pop old package + +#if USE_LUAJIT + // Copy safe jit functions, if they exist + lua_getfield(L, -1, "jit"); + if (!lua_isnil(L, -1)) { + lua_newtable(L); + copy_safe(L, jit_whitelist, sizeof(jit_whitelist)); + lua_setglobal(L, "jit"); + } + lua_pop(L, 1); // Pop old jit +#endif + + // Get rid of 'core' in the old globals, we don't want anyone thinking it's + // safe or even usable. + lua_pushnil(L); + lua_setfield(L, old_globals, "core"); + + // 'vector' as well. + lua_pushnil(L); + lua_setfield(L, old_globals, "vector"); + + lua_pop(L, 1); // Pop globals_backup + + + /* + * In addition to copying the tables in whitelist_tables, we also need to + * replace the string metatable. Otherwise old_globals.string would + * be accessible via getmetatable("").__index from inside the sandbox. + */ + lua_pushliteral(L, ""); + lua_newtable(L); + lua_getglobal(L, "string"); + lua_setfield(L, -2, "__index"); + lua_setmetatable(L, -2); + lua_pop(L, 1); // Pop empty string +} + +void ScriptApiSecurity::initializeSecurityClient() +{ + static const char *whitelist[] = { + "assert", + "core", + "collectgarbage", + "DIR_DELIM", + "error", + "getfenv", + "ipairs", + "next", + "pairs", + "pcall", + "print", + "rawequal", + "rawget", + "rawset", + "select", + "setfenv", + // getmetatable can be used to escape the sandbox <- ??? + "setmetatable", + "tonumber", + "tostring", + "type", + "unpack", + "_VERSION", + "vector", + "xpcall", + // Completely safe libraries + "coroutine", + "string", + "table", + "math", + "bit", + }; + static const char *os_whitelist[] = { + "clock", + "date", + "difftime", + "time" + }; + static const char *debug_whitelist[] = { + "getinfo", // used by builtin and unset before mods load + "traceback" + }; + +#if USE_LUAJIT + static const char *jit_whitelist[] = { + "arch", + "flush", + "off", + "on", + "opt", + "os", + "status", + "version", + "version_num", + }; +#endif + + m_secure = true; + + lua_State *L = getStack(); + int thread = getThread(L); + + // create an empty environment + createEmptyEnv(L); + + // Copy safe base functions + lua_getglobal(L, "_G"); + lua_getfield(L, -2, "_G"); + copy_safe(L, whitelist, sizeof(whitelist)); + + // And replace unsafe ones + SECURE_API(g, dofile); + SECURE_API(g, load); + SECURE_API(g, loadfile); + SECURE_API(g, loadstring); + SECURE_API(g, require); + lua_pop(L, 2); + + + + // Copy safe OS functions + lua_getglobal(L, "os"); + lua_newtable(L); + copy_safe(L, os_whitelist, sizeof(os_whitelist)); + lua_setfield(L, -3, "os"); + lua_pop(L, 1); // Pop old OS + + + // Copy safe debug functions + lua_getglobal(L, "debug"); + lua_newtable(L); + copy_safe(L, debug_whitelist, sizeof(debug_whitelist)); + lua_setfield(L, -3, "debug"); + lua_pop(L, 1); // Pop old debug + +#if USE_LUAJIT + // Copy safe jit functions, if they exist + lua_getglobal(L, "jit"); + lua_newtable(L); + copy_safe(L, jit_whitelist, sizeof(jit_whitelist)); + lua_setfield(L, -3, "jit"); + lua_pop(L, 1); // Pop old jit +#endif + + // Set the environment to the one we created earlier + setLuaEnv(L, thread); +} + +int ScriptApiSecurity::getThread(lua_State *L) +{ +#if LUA_VERSION_NUM <= 501 + int is_main = lua_pushthread(L); // Push the main thread + FATAL_ERROR_IF(!is_main, "Security: ScriptApi's Lua state " + "isn't the main Lua thread!"); + return lua_gettop(L); +#endif + return 0; +} + +void ScriptApiSecurity::createEmptyEnv(lua_State *L) +{ + lua_newtable(L); // Create new environment + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_G"); // Create the _G loop +} + +void ScriptApiSecurity::setLuaEnv(lua_State *L, int thread) +{ +#if LUA_VERSION_NUM >= 502 // Lua >= 5.2 + // Set the global environment + lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); +#else // Lua <= 5.1 + // Set the environment of the main thread + FATAL_ERROR_IF(!lua_setfenv(L, thread), "Security: Unable to set " + "environment of the main Lua thread!"); + lua_pop(L, 1); // Pop thread +#endif +} + +bool ScriptApiSecurity::isSecure(lua_State *L) +{ +#ifndef SERVER + auto script = ModApiBase::getScriptApiBase(L); + // CSM keeps no globals backup but is always secure + if (script->getType() == ScriptingType::Client) + return true; +#endif + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP); + bool secure = !lua_isnil(L, -1); + lua_pop(L, 1); + return secure; +} + +bool ScriptApiSecurity::safeLoadString(lua_State *L, const std::string &code, const char *chunk_name) +{ + if (code.size() > 0 && code[0] == LUA_SIGNATURE[0]) { + lua_pushliteral(L, "Bytecode prohibited when mod security is enabled."); + return false; + } + if (luaL_loadbuffer(L, code.data(), code.size(), chunk_name)) + return false; + return true; +} + +bool ScriptApiSecurity::safeLoadFile(lua_State *L, const char *path, const char *display_name) +{ + FILE *fp; + char *chunk_name; + if (!display_name) + display_name = path; + if (!path) { + fp = stdin; + chunk_name = const_cast<char *>("=stdin"); + } else { + fp = fopen(path, "rb"); + if (!fp) { + lua_pushfstring(L, "%s: %s", path, strerror(errno)); + return false; + } + size_t len = strlen(display_name) + 2; + chunk_name = new char[len]; + snprintf(chunk_name, len, "@%s", display_name); + } + + size_t start = 0; + int c = std::getc(fp); + if (c == '#') { + // Skip the first line + while ((c = std::getc(fp)) != EOF && c != '\n') {} + if (c == '\n') + std::getc(fp); + start = std::ftell(fp); + } + + // Read the file + int ret = std::fseek(fp, 0, SEEK_END); + if (ret) { + lua_pushfstring(L, "%s: %s", path, strerror(errno)); + if (path) { + std::fclose(fp); + delete [] chunk_name; + } + return false; + } + + size_t size = std::ftell(fp) - start; + std::string code(size, '\0'); + ret = std::fseek(fp, start, SEEK_SET); + if (ret) { + lua_pushfstring(L, "%s: %s", path, strerror(errno)); + if (path) { + std::fclose(fp); + delete [] chunk_name; + } + return false; + } + + size_t num_read = std::fread(&code[0], 1, size, fp); + if (path) + std::fclose(fp); + if (num_read != size) { + lua_pushliteral(L, "Error reading file to load."); + if (path) + delete [] chunk_name; + return false; + } + + bool result = safeLoadString(L, code, chunk_name); + if (path) + delete [] chunk_name; + return result; +} + + +bool ScriptApiSecurity::checkPath(lua_State *L, const char *path, + bool write_required, bool *write_allowed) +{ + if (write_allowed) + *write_allowed = false; + + std::string str; // Transient + + std::string abs_path = fs::AbsolutePath(path); + + if (!abs_path.empty()) { + // Don't allow accessing the settings file + str = fs::AbsolutePath(g_settings_path); + if (str == abs_path) return false; + } + + // If we couldn't find the absolute path (path doesn't exist) then + // try removing the last components until it works (to allow + // non-existent files/folders for mkdir). + std::string cur_path = path; + std::string removed; + while (abs_path.empty() && !cur_path.empty()) { + std::string component; + cur_path = fs::RemoveLastPathComponent(cur_path, &component); + if (component == "..") { + // Parent components can't be allowed or we could allow something like + // /home/user/minetest/worlds/foo/noexist/../../../../../../etc/passwd. + // If we have previous non-relative elements in the path we might be + // able to remove them so that things like worlds/foo/noexist/../auth.txt + // could be allowed, but those paths will be interpreted as nonexistent + // by the operating system anyways. + return false; + } + removed.append(component).append(removed.empty() ? "" : DIR_DELIM + removed); + abs_path = fs::AbsolutePath(cur_path); + } + if (abs_path.empty()) + return false; + // Add the removed parts back so that you can't, eg, create a + // directory in worldmods if worldmods doesn't exist. + if (!removed.empty()) + abs_path += DIR_DELIM + removed; + + // Get gamedef from registry + ScriptApiBase *script = ModApiBase::getScriptApiBase(L); + const IGameDef *gamedef = script->getGameDef(); + if (!gamedef) + return false; + + // Get mod name + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); + if (lua_isstring(L, -1)) { + std::string mod_name = readParam<std::string>(L, -1); + + // Builtin can access anything + if (mod_name == BUILTIN_MOD_NAME) { + if (write_allowed) *write_allowed = true; + return true; + } + + // Allow paths in mod path + // Don't bother if write access isn't important, since it will be handled later + if (write_required || write_allowed != NULL) { + const ModSpec *mod = gamedef->getModSpec(mod_name); + if (mod) { + str = fs::AbsolutePath(mod->path); + if (!str.empty() && fs::PathStartsWith(abs_path, str)) { + if (write_allowed) *write_allowed = true; + return true; + } + } + } + } + lua_pop(L, 1); // Pop mod name + + // Allow read-only access to all mod directories + if (!write_required) { + const std::vector<ModSpec> &mods = gamedef->getMods(); + for (const ModSpec &mod : mods) { + str = fs::AbsolutePath(mod.path); + if (!str.empty() && fs::PathStartsWith(abs_path, str)) { + return true; + } + } + } + + str = fs::AbsolutePath(gamedef->getWorldPath()); + if (!str.empty()) { + // Don't allow access to other paths in the world mod/game path. + // These have to be blocked so you can't override a trusted mod + // by creating a mod with the same name in a world mod directory. + // We add to the absolute path of the world instead of getting + // the absolute paths directly because that won't work if they + // don't exist. + if (fs::PathStartsWith(abs_path, str + DIR_DELIM + "worldmods") || + fs::PathStartsWith(abs_path, str + DIR_DELIM + "game")) { + return false; + } + // Allow all other paths in world path + if (fs::PathStartsWith(abs_path, str)) { + if (write_allowed) *write_allowed = true; + return true; + } + } + + // Default to disallowing + return false; +} + +bool ScriptApiSecurity::checkWhitelisted(lua_State *L, const std::string &setting) +{ + assert(str_starts_with(setting, "secure.")); + + // We have to make sure that this function is being called directly by + // a mod, otherwise a malicious mod could override this function and + // steal its return value. + lua_Debug info; + + // Make sure there's only one item below this function on the stack... + if (lua_getstack(L, 2, &info)) + return false; + FATAL_ERROR_IF(!lua_getstack(L, 1, &info), "lua_getstack() failed"); + FATAL_ERROR_IF(!lua_getinfo(L, "S", &info), "lua_getinfo() failed"); + + // ...and that that item is the main file scope. + if (strcmp(info.what, "main") != 0) + return false; + + // Mod must be listed in secure.http_mods or secure.trusted_mods + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); + if (!lua_isstring(L, -1)) + return false; + std::string mod_name = readParam<std::string>(L, -1); + + std::string value = g_settings->get(setting); + value.erase(std::remove(value.begin(), value.end(), ' '), value.end()); + auto mod_list = str_split(value, ','); + + return CONTAINS(mod_list, mod_name); +} + + +int ScriptApiSecurity::sl_g_dofile(lua_State *L) +{ + int nret = sl_g_loadfile(L); + if (nret != 1) { + lua_error(L); + // code after this function isn't executed + } + int top_precall = lua_gettop(L); + lua_call(L, 0, LUA_MULTRET); + // Return number of arguments returned by the function, + // adjusting for the function being poped. + return lua_gettop(L) - (top_precall - 1); +} + + +int ScriptApiSecurity::sl_g_load(lua_State *L) +{ + size_t len; + const char *buf; + std::string code; + const char *chunk_name = "=(load)"; + + luaL_checktype(L, 1, LUA_TFUNCTION); + if (!lua_isnone(L, 2)) { + luaL_checktype(L, 2, LUA_TSTRING); + chunk_name = lua_tostring(L, 2); + } + + while (true) { + lua_pushvalue(L, 1); + lua_call(L, 0, 1); + int t = lua_type(L, -1); + if (t == LUA_TNIL) { + break; + } + + if (t != LUA_TSTRING) { + lua_pushnil(L); + lua_pushliteral(L, "Loader didn't return a string"); + return 2; + } + buf = lua_tolstring(L, -1, &len); + code += std::string(buf, len); + lua_pop(L, 1); // Pop return value + } + if (!safeLoadString(L, code, chunk_name)) { + lua_pushnil(L); + lua_insert(L, -2); + return 2; + } + return 1; +} + + +int ScriptApiSecurity::sl_g_loadfile(lua_State *L) +{ +#ifndef SERVER + ScriptApiBase *script = ModApiBase::getScriptApiBase(L); + + // Client implementation + if (script->getType() == ScriptingType::Client) { + std::string path = readParam<std::string>(L, 1); + const std::string *contents = script->getClient()->getModFile(path); + if (!contents) { + std::string error_msg = "Coudln't find script called: " + path; + lua_pushnil(L); + lua_pushstring(L, error_msg.c_str()); + return 2; + } + + std::string chunk_name = "@" + path; + if (!safeLoadString(L, *contents, chunk_name.c_str())) { + lua_pushnil(L); + lua_insert(L, -2); + return 2; + } + return 1; + } +#endif + + // Server implementation + const char *path = NULL; + if (lua_isstring(L, 1)) { + path = lua_tostring(L, 1); + CHECK_SECURE_PATH_INTERNAL(L, path, false, NULL); + } + + if (!safeLoadFile(L, path)) { + lua_pushnil(L); + lua_insert(L, -2); + return 2; + } + + return 1; +} + + +int ScriptApiSecurity::sl_g_loadstring(lua_State *L) +{ + const char *chunk_name = "=(load)"; + + luaL_checktype(L, 1, LUA_TSTRING); + if (!lua_isnone(L, 2)) { + luaL_checktype(L, 2, LUA_TSTRING); + chunk_name = lua_tostring(L, 2); + } + + size_t size; + const char *code = lua_tolstring(L, 1, &size); + std::string code_s(code, size); + + if (!safeLoadString(L, code_s, chunk_name)) { + lua_pushnil(L); + lua_insert(L, -2); + return 2; + } + return 1; +} + + +int ScriptApiSecurity::sl_g_require(lua_State *L) +{ + lua_pushliteral(L, "require() is disabled when mod security is on."); + return lua_error(L); +} + + +int ScriptApiSecurity::sl_io_open(lua_State *L) +{ + bool with_mode = lua_gettop(L) > 1; + + luaL_checktype(L, 1, LUA_TSTRING); + const char *path = lua_tostring(L, 1); + + bool write_requested = false; + if (with_mode) { + luaL_checktype(L, 2, LUA_TSTRING); + const char *mode = lua_tostring(L, 2); + write_requested = strchr(mode, 'w') != NULL || + strchr(mode, '+') != NULL || + strchr(mode, 'a') != NULL; + } + CHECK_SECURE_PATH_INTERNAL(L, path, write_requested, NULL); + + push_original(L, "io", "open"); + lua_pushvalue(L, 1); + if (with_mode) { + lua_pushvalue(L, 2); + } + + lua_call(L, with_mode ? 2 : 1, 2); + return 2; +} + + +int ScriptApiSecurity::sl_io_input(lua_State *L) +{ + if (lua_isstring(L, 1)) { + const char *path = lua_tostring(L, 1); + CHECK_SECURE_PATH_INTERNAL(L, path, false, NULL); + } + + push_original(L, "io", "input"); + lua_pushvalue(L, 1); + lua_call(L, 1, 1); + return 1; +} + + +int ScriptApiSecurity::sl_io_output(lua_State *L) +{ + if (lua_isstring(L, 1)) { + const char *path = lua_tostring(L, 1); + CHECK_SECURE_PATH_INTERNAL(L, path, true, NULL); + } + + push_original(L, "io", "output"); + lua_pushvalue(L, 1); + lua_call(L, 1, 1); + return 1; +} + + +int ScriptApiSecurity::sl_io_lines(lua_State *L) +{ + if (lua_isstring(L, 1)) { + const char *path = lua_tostring(L, 1); + CHECK_SECURE_PATH_INTERNAL(L, path, false, NULL); + } + + int top_precall = lua_gettop(L); + push_original(L, "io", "lines"); + lua_pushvalue(L, 1); + lua_call(L, 1, LUA_MULTRET); + // Return number of arguments returned by the function, + // adjusting for the function being poped. + return lua_gettop(L) - top_precall; +} + + +int ScriptApiSecurity::sl_os_rename(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TSTRING); + const char *path1 = lua_tostring(L, 1); + CHECK_SECURE_PATH_INTERNAL(L, path1, true, NULL); + + luaL_checktype(L, 2, LUA_TSTRING); + const char *path2 = lua_tostring(L, 2); + CHECK_SECURE_PATH_INTERNAL(L, path2, true, NULL); + + push_original(L, "os", "rename"); + lua_pushvalue(L, 1); + lua_pushvalue(L, 2); + lua_call(L, 2, 2); + return 2; +} + + +int ScriptApiSecurity::sl_os_remove(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TSTRING); + const char *path = lua_tostring(L, 1); + CHECK_SECURE_PATH_INTERNAL(L, path, true, NULL); + + push_original(L, "os", "remove"); + lua_pushvalue(L, 1); + lua_call(L, 1, 2); + return 2; +} + + +int ScriptApiSecurity::sl_os_setlocale(lua_State *L) +{ + const bool cat = lua_gettop(L) > 1; + // Don't allow changes + if (!lua_isnoneornil(L, 1)) { + lua_pushnil(L); + return 1; + } + + push_original(L, "os", "setlocale"); + lua_pushnil(L); + if (cat) + lua_pushvalue(L, 2); + lua_call(L, cat ? 2 : 1, 1); + return 1; +} diff --git a/src/script/cpp_api/s_security.h b/src/script/cpp_api/s_security.h new file mode 100644 index 0000000..880ce16 --- /dev/null +++ b/src/script/cpp_api/s_security.h @@ -0,0 +1,83 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" + + +#define CHECK_SECURE_PATH_INTERNAL(L, path, write_required, ptr) \ + if (!ScriptApiSecurity::checkPath(L, path, write_required, ptr)) { \ + throw LuaError(std::string("Mod security: Blocked attempted ") + \ + (write_required ? "write to " : "read from ") + path); \ + } +#define CHECK_SECURE_PATH(L, path, write_required) \ + if (ScriptApiSecurity::isSecure(L)) { \ + CHECK_SECURE_PATH_INTERNAL(L, path, write_required, NULL); \ + } +#define CHECK_SECURE_PATH_POSSIBLE_WRITE(L, path, ptr) \ + if (ScriptApiSecurity::isSecure(L)) { \ + CHECK_SECURE_PATH_INTERNAL(L, path, false, ptr); \ + } + + +class ScriptApiSecurity : virtual public ScriptApiBase +{ +public: + // Sets up security on the ScriptApi's Lua state + void initializeSecurity(); + void initializeSecurityClient(); + // Checks if the Lua state has been secured + static bool isSecure(lua_State *L); + // Loads a string as Lua code safely (doesn't allow bytecode). + static bool safeLoadString(lua_State *L, const std::string &code, const char *chunk_name); + // Loads a file as Lua code safely (doesn't allow bytecode). + static bool safeLoadFile(lua_State *L, const char *path, const char *display_name = NULL); + // Checks if mods are allowed to read (and optionally write) to the path + static bool checkPath(lua_State *L, const char *path, bool write_required, + bool *write_allowed=NULL); + // Check if mod is whitelisted in the given setting + // This additionally checks that the mod's main file scope is executing. + static bool checkWhitelisted(lua_State *L, const std::string &setting); + +private: + int getThread(lua_State *L); + // sets the enviroment to the table thats on top of the stack + void setLuaEnv(lua_State *L, int thread); + // creates an empty Lua environment + void createEmptyEnv(lua_State *L); + + // Syntax: "sl_" <Library name or 'g' (global)> '_' <Function name> + // (sl stands for Secure Lua) + + static int sl_g_dofile(lua_State *L); + static int sl_g_load(lua_State *L); + static int sl_g_loadfile(lua_State *L); + static int sl_g_loadstring(lua_State *L); + static int sl_g_require(lua_State *L); + + static int sl_io_open(lua_State *L); + static int sl_io_input(lua_State *L); + static int sl_io_output(lua_State *L); + static int sl_io_lines(lua_State *L); + + static int sl_os_rename(lua_State *L); + static int sl_os_remove(lua_State *L); + static int sl_os_setlocale(lua_State *L); +}; diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp new file mode 100644 index 0000000..c255b0c --- /dev/null +++ b/src/script/cpp_api/s_server.cpp @@ -0,0 +1,262 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "cpp_api/s_server.h" +#include "cpp_api/s_internal.h" +#include "common/c_converter.h" +#include "util/numeric.h" // myrand + +bool ScriptApiServer::getAuth(const std::string &playername, + std::string *dst_password, + std::set<std::string> *dst_privs, + s64 *dst_last_login) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + getAuthHandler(); + lua_getfield(L, -1, "get_auth"); + if (lua_type(L, -1) != LUA_TFUNCTION) + throw LuaError("Authentication handler missing get_auth"); + lua_pushstring(L, playername.c_str()); + PCALL_RES(lua_pcall(L, 1, 1, error_handler)); + lua_remove(L, -2); // Remove auth handler + lua_remove(L, error_handler); + + // nil = login not allowed + if (lua_isnil(L, -1)) + return false; + luaL_checktype(L, -1, LUA_TTABLE); + + std::string password; + if (!getstringfield(L, -1, "password", password)) + throw LuaError("Authentication handler didn't return password"); + if (dst_password) + *dst_password = password; + + lua_getfield(L, -1, "privileges"); + if (!lua_istable(L, -1)) + throw LuaError("Authentication handler didn't return privilege table"); + if (dst_privs) + readPrivileges(-1, *dst_privs); + lua_pop(L, 1); // Remove key from privs table + + s64 last_login; + if(!getintfield(L, -1, "last_login", last_login)) + throw LuaError("Authentication handler didn't return last_login"); + if (dst_last_login) + *dst_last_login = (s64)last_login; + + return true; +} + +void ScriptApiServer::getAuthHandler() +{ + lua_State *L = getStack(); + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_auth_handler"); + if (lua_isnil(L, -1)){ + lua_pop(L, 1); + lua_getfield(L, -1, "builtin_auth_handler"); + } + + setOriginFromTable(-1); + + lua_remove(L, -2); // Remove core + if (lua_type(L, -1) != LUA_TTABLE) + throw LuaError("Authentication handler table not valid"); +} + +void ScriptApiServer::readPrivileges(int index, std::set<std::string> &result) +{ + lua_State *L = getStack(); + + result.clear(); + lua_pushnil(L); + if (index < 0) + index -= 1; + while (lua_next(L, index) != 0) { + // key at index -2 and value at index -1 + std::string key = luaL_checkstring(L, -2); + bool value = readParam<bool>(L, -1); + if (value) + result.insert(key); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } +} + +void ScriptApiServer::createAuth(const std::string &playername, + const std::string &password) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + getAuthHandler(); + lua_getfield(L, -1, "create_auth"); + lua_remove(L, -2); // Remove auth handler + if (lua_type(L, -1) != LUA_TFUNCTION) + throw LuaError("Authentication handler missing create_auth"); + lua_pushstring(L, playername.c_str()); + lua_pushstring(L, password.c_str()); + PCALL_RES(lua_pcall(L, 2, 0, error_handler)); + lua_pop(L, 1); // Pop error handler +} + +bool ScriptApiServer::setPassword(const std::string &playername, + const std::string &password) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + getAuthHandler(); + lua_getfield(L, -1, "set_password"); + lua_remove(L, -2); // Remove auth handler + if (lua_type(L, -1) != LUA_TFUNCTION) + throw LuaError("Authentication handler missing set_password"); + lua_pushstring(L, playername.c_str()); + lua_pushstring(L, password.c_str()); + PCALL_RES(lua_pcall(L, 2, 1, error_handler)); + lua_remove(L, error_handler); + return lua_toboolean(L, -1); +} + +bool ScriptApiServer::on_chat_message(const std::string &name, + const std::string &message) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_chat_messages + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_chat_messages"); + // Call callbacks + lua_pushstring(L, name.c_str()); + lua_pushstring(L, message.c_str()); + runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC); + return readParam<bool>(L, -1); +} + +void ScriptApiServer::on_mods_loaded() +{ + SCRIPTAPI_PRECHECKHEADER + + // Get registered shutdown hooks + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_mods_loaded"); + // Call callbacks + runCallbacks(0, RUN_CALLBACKS_MODE_FIRST); +} + +void ScriptApiServer::on_shutdown() +{ + SCRIPTAPI_PRECHECKHEADER + + // Get registered shutdown hooks + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_shutdown"); + // Call callbacks + runCallbacks(0, RUN_CALLBACKS_MODE_FIRST); +} + +std::string ScriptApiServer::formatChatMessage(const std::string &name, + const std::string &message) +{ + SCRIPTAPI_PRECHECKHEADER + + // Push function onto stack + lua_getglobal(L, "core"); + lua_getfield(L, -1, "format_chat_message"); + + // Push arguments onto stack + lua_pushstring(L, name.c_str()); + lua_pushstring(L, message.c_str()); + + // Actually call the function + lua_call(L, 2, 1); + + // Fetch return value + std::string ret = lua_tostring(L, -1); + lua_pop(L, 1); + + return ret; +} + +u32 ScriptApiServer::allocateDynamicMediaCallback(lua_State *L, int f_idx) +{ + if (f_idx < 0) + f_idx = lua_gettop(L) + f_idx + 1; + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "dynamic_media_callbacks"); + luaL_checktype(L, -1, LUA_TTABLE); + + // Find a randomly generated token that doesn't exist yet + int tries = 100; + u32 token; + while (1) { + token = myrand(); + lua_rawgeti(L, -2, token); + bool is_free = lua_isnil(L, -1); + lua_pop(L, 1); + if (is_free) + break; + if (--tries < 0) + FATAL_ERROR("Ran out of callbacks IDs?!"); + } + + // core.dynamic_media_callbacks[token] = callback_func + lua_pushvalue(L, f_idx); + lua_rawseti(L, -2, token); + + lua_pop(L, 2); + + verbosestream << "allocateDynamicMediaCallback() = " << token << std::endl; + return token; +} + +void ScriptApiServer::freeDynamicMediaCallback(u32 token) +{ + SCRIPTAPI_PRECHECKHEADER + + verbosestream << "freeDynamicMediaCallback(" << token << ")" << std::endl; + + // core.dynamic_media_callbacks[token] = nil + lua_getglobal(L, "core"); + lua_getfield(L, -1, "dynamic_media_callbacks"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_pushnil(L); + lua_rawseti(L, -2, token); + lua_pop(L, 2); +} + +void ScriptApiServer::on_dynamic_media_added(u32 token, const char *playername) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + lua_getglobal(L, "core"); + lua_getfield(L, -1, "dynamic_media_callbacks"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_rawgeti(L, -1, token); + luaL_checktype(L, -1, LUA_TFUNCTION); + + lua_pushstring(L, playername); + PCALL_RES(lua_pcall(L, 1, 0, error_handler)); +} diff --git a/src/script/cpp_api/s_server.h b/src/script/cpp_api/s_server.h new file mode 100644 index 0000000..58c8c0e --- /dev/null +++ b/src/script/cpp_api/s_server.h @@ -0,0 +1,61 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" +#include <set> + +class ScriptApiServer + : virtual public ScriptApiBase +{ +public: + // Calls on_chat_message handlers + // Returns true if script handled message + bool on_chat_message(const std::string &name, const std::string &message); + + // Calls when mods are loaded + void on_mods_loaded(); + + // Calls on_shutdown handlers + void on_shutdown(); + + // Calls core.format_chat_message + std::string formatChatMessage(const std::string &name, + const std::string &message); + + /* auth */ + bool getAuth(const std::string &playername, + std::string *dst_password, + std::set<std::string> *dst_privs, + s64 *dst_last_login = nullptr); + void createAuth(const std::string &playername, + const std::string &password); + bool setPassword(const std::string &playername, + const std::string &password); + + /* dynamic media handling */ + static u32 allocateDynamicMediaCallback(lua_State *L, int f_idx); + void freeDynamicMediaCallback(u32 token); + void on_dynamic_media_added(u32 token, const char *playername); + +private: + void getAuthHandler(); + void readPrivileges(int index, std::set<std::string> &result); +}; diff --git a/src/script/lua_api/CMakeLists.txt b/src/script/lua_api/CMakeLists.txt new file mode 100644 index 0000000..32f6a27 --- /dev/null +++ b/src/script/lua_api/CMakeLists.txt @@ -0,0 +1,37 @@ +set(common_SCRIPT_LUA_API_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/l_areastore.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_auth.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_base.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_craft.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_env.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_http.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_inventory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_itemstackmeta.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_metadata.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_modchannels.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_nodemeta.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_nodetimer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_object.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_particles.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_playermeta.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_rollback.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_server.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_settings.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_storage.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_util.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_vmanip.cpp + PARENT_SCOPE) + +set(client_SCRIPT_LUA_API_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/l_camera.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_client.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_localplayer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_minimap.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_particles_local.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_sound.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_storage.cpp + PARENT_SCOPE) diff --git a/src/script/lua_api/l_areastore.cpp b/src/script/lua_api/l_areastore.cpp new file mode 100644 index 0000000..ec2656c --- /dev/null +++ b/src/script/lua_api/l_areastore.cpp @@ -0,0 +1,397 @@ +/* +Minetest +Copyright (C) 2015 est31 <mtest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "lua_api/l_areastore.h" +#include "lua_api/l_internal.h" +#include "common/c_converter.h" +#include "cpp_api/s_security.h" +#include "irr_v3d.h" +#include "util/areastore.h" +#include "filesys.h" +#include <fstream> + +static inline void get_data_and_corner_flags(lua_State *L, u8 start_i, + bool *corners, bool *data) +{ + if (!lua_isboolean(L, start_i)) + return; + *corners = lua_toboolean(L, start_i); + if (!lua_isboolean(L, start_i + 1)) + return; + *data = lua_toboolean(L, start_i + 1); +} + +static void push_area(lua_State *L, const Area *a, + bool include_corners, bool include_data) +{ + if (!include_corners && !include_data) { + lua_pushboolean(L, true); + return; + } + lua_newtable(L); + if (include_corners) { + push_v3s16(L, a->minedge); + lua_setfield(L, -2, "min"); + push_v3s16(L, a->maxedge); + lua_setfield(L, -2, "max"); + } + if (include_data) { + lua_pushlstring(L, a->data.c_str(), a->data.size()); + lua_setfield(L, -2, "data"); + } +} + +static inline void push_areas(lua_State *L, const std::vector<Area *> &areas, + bool corners, bool data) +{ + lua_newtable(L); + size_t cnt = areas.size(); + for (size_t i = 0; i < cnt; i++) { + lua_pushnumber(L, areas[i]->id); + push_area(L, areas[i], corners, data); + lua_settable(L, -3); + } +} + +// Deserializes value and handles errors +static int deserialization_helper(lua_State *L, AreaStore *as, + std::istream &is) +{ + try { + as->deserialize(is); + } catch (const SerializationError &e) { + lua_pushboolean(L, false); + lua_pushstring(L, e.what()); + return 2; + } + + lua_pushboolean(L, true); + return 1; +} + +// garbage collector +int LuaAreaStore::gc_object(lua_State *L) +{ + LuaAreaStore *o = *(LuaAreaStore **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +// get_area(id, include_corners, include_data) +int LuaAreaStore::l_get_area(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = checkobject(L, 1); + AreaStore *ast = o->as; + + u32 id = luaL_checknumber(L, 2); + + bool include_corners = true; + bool include_data = false; + get_data_and_corner_flags(L, 3, &include_corners, &include_data); + + const Area *res; + + res = ast->getArea(id); + if (!res) + return 0; + + push_area(L, res, include_corners, include_data); + + return 1; +} + +// get_areas_for_pos(pos, include_corners, include_data) +int LuaAreaStore::l_get_areas_for_pos(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = checkobject(L, 1); + AreaStore *ast = o->as; + + v3s16 pos = check_v3s16(L, 2); + + bool include_corners = true; + bool include_data = false; + get_data_and_corner_flags(L, 3, &include_corners, &include_data); + + std::vector<Area *> res; + + ast->getAreasForPos(&res, pos); + push_areas(L, res, include_corners, include_data); + + return 1; +} + +// get_areas_in_area(corner1, corner2, accept_overlap, include_corners, include_data) +int LuaAreaStore::l_get_areas_in_area(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = checkobject(L, 1); + AreaStore *ast = o->as; + + v3s16 minp = check_v3s16(L, 2); + v3s16 maxp = check_v3s16(L, 3); + sortBoxVerticies(minp, maxp); + + bool include_corners = true; + bool include_data = false; + bool accept_overlap = false; + if (lua_isboolean(L, 4)) { + accept_overlap = readParam<bool>(L, 4); + get_data_and_corner_flags(L, 5, &include_corners, &include_data); + } + std::vector<Area *> res; + + ast->getAreasInArea(&res, minp, maxp, accept_overlap); + push_areas(L, res, include_corners, include_data); + + return 1; +} + +// insert_area(corner1, corner2, data, id) +int LuaAreaStore::l_insert_area(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = checkobject(L, 1); + AreaStore *ast = o->as; + + Area a(check_v3s16(L, 2), check_v3s16(L, 3)); + + size_t d_len; + const char *data = luaL_checklstring(L, 4, &d_len); + + a.data = std::string(data, d_len); + + if (lua_isnumber(L, 5)) + a.id = lua_tonumber(L, 5); + + // Insert & assign a new ID if necessary + if (!ast->insertArea(&a)) + return 0; + + lua_pushnumber(L, a.id); + return 1; +} + +// reserve(count) +int LuaAreaStore::l_reserve(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = checkobject(L, 1); + AreaStore *ast = o->as; + + size_t count = luaL_checknumber(L, 2); + ast->reserve(count); + return 0; +} + +// remove_area(id) +int LuaAreaStore::l_remove_area(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = checkobject(L, 1); + AreaStore *ast = o->as; + + u32 id = luaL_checknumber(L, 2); + bool success = ast->removeArea(id); + + lua_pushboolean(L, success); + return 1; +} + +// set_cache_params(params) +int LuaAreaStore::l_set_cache_params(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = checkobject(L, 1); + AreaStore *ast = o->as; + + luaL_checktype(L, 2, LUA_TTABLE); + + bool enabled = getboolfield_default(L, 2, "enabled", true); + u8 block_radius = getintfield_default(L, 2, "block_radius", 64); + size_t limit = getintfield_default(L, 2, "block_radius", 1000); + + ast->setCacheParams(enabled, block_radius, limit); + + return 0; +} + +// to_string() +int LuaAreaStore::l_to_string(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = checkobject(L, 1); + + std::ostringstream os(std::ios_base::binary); + o->as->serialize(os); + std::string str = os.str(); + + lua_pushlstring(L, str.c_str(), str.length()); + return 1; +} + +// to_file(filename) +int LuaAreaStore::l_to_file(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = checkobject(L, 1); + AreaStore *ast = o->as; + + const char *filename = luaL_checkstring(L, 2); + CHECK_SECURE_PATH(L, filename, true); + + std::ostringstream os(std::ios_base::binary); + ast->serialize(os); + + lua_pushboolean(L, fs::safeWriteToFile(filename, os.str())); + return 1; +} + +// from_string(str) +int LuaAreaStore::l_from_string(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = checkobject(L, 1); + + size_t len; + const char *str = luaL_checklstring(L, 2, &len); + + std::istringstream is(std::string(str, len), std::ios::binary); + return deserialization_helper(L, o->as, is); +} + +// from_file(filename) +int LuaAreaStore::l_from_file(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = checkobject(L, 1); + + const char *filename = luaL_checkstring(L, 2); + CHECK_SECURE_PATH(L, filename, false); + + std::ifstream is(filename, std::ios::binary); + return deserialization_helper(L, o->as, is); +} + +LuaAreaStore::LuaAreaStore() : as(AreaStore::getOptimalImplementation()) +{ +} + +LuaAreaStore::LuaAreaStore(const std::string &type) +{ +#if USE_SPATIAL + if (type == "LibSpatial") { + as = new SpatialAreaStore(); + } else +#endif + { + as = new VectorAreaStore(); + } +} + +LuaAreaStore::~LuaAreaStore() +{ + delete as; +} + +// LuaAreaStore() +// Creates an LuaAreaStore and leaves it on top of stack +int LuaAreaStore::create_object(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaAreaStore *o = (lua_isstring(L, 1)) ? + new LuaAreaStore(readParam<std::string>(L, 1)) : + new LuaAreaStore(); + + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + +LuaAreaStore *LuaAreaStore::checkobject(lua_State *L, int narg) +{ + NO_MAP_LOCK_REQUIRED; + + luaL_checktype(L, narg, LUA_TUSERDATA); + + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + + return *(LuaAreaStore **)ud; // unbox pointer +} + +void LuaAreaStore::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // drop methodtable + + // Can be created from Lua (AreaStore()) + lua_register(L, className, create_object); +} + +const char LuaAreaStore::className[] = "AreaStore"; +const luaL_Reg LuaAreaStore::methods[] = { + luamethod(LuaAreaStore, get_area), + luamethod(LuaAreaStore, get_areas_for_pos), + luamethod(LuaAreaStore, get_areas_in_area), + luamethod(LuaAreaStore, insert_area), + luamethod(LuaAreaStore, reserve), + luamethod(LuaAreaStore, remove_area), + luamethod(LuaAreaStore, set_cache_params), + luamethod(LuaAreaStore, to_string), + luamethod(LuaAreaStore, to_file), + luamethod(LuaAreaStore, from_string), + luamethod(LuaAreaStore, from_file), + {0,0} +}; diff --git a/src/script/lua_api/l_areastore.h b/src/script/lua_api/l_areastore.h new file mode 100644 index 0000000..56acd90 --- /dev/null +++ b/src/script/lua_api/l_areastore.h @@ -0,0 +1,64 @@ +/* +Minetest +Copyright (C) 2015 est31 <mtest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" + +class AreaStore; + +class LuaAreaStore : public ModApiBase +{ +private: + static const char className[]; + static const luaL_Reg methods[]; + + static int gc_object(lua_State *L); + + static int l_get_area(lua_State *L); + + static int l_get_areas_for_pos(lua_State *L); + static int l_get_areas_in_area(lua_State *L); + static int l_insert_area(lua_State *L); + static int l_reserve(lua_State *L); + static int l_remove_area(lua_State *L); + + static int l_set_cache_params(lua_State *L); + + static int l_to_string(lua_State *L); + static int l_to_file(lua_State *L); + + static int l_from_string(lua_State *L); + static int l_from_file(lua_State *L); + +public: + AreaStore *as = nullptr; + + LuaAreaStore(); + LuaAreaStore(const std::string &type); + ~LuaAreaStore(); + + // AreaStore() + // Creates a AreaStore and leaves it on top of stack + static int create_object(lua_State *L); + + static LuaAreaStore *checkobject(lua_State *L, int narg); + + static void Register(lua_State *L); +}; diff --git a/src/script/lua_api/l_auth.cpp b/src/script/lua_api/l_auth.cpp new file mode 100644 index 0000000..32d8a74 --- /dev/null +++ b/src/script/lua_api/l_auth.cpp @@ -0,0 +1,219 @@ +/* +Minetest +Copyright (C) 2018 bendeutsch, Ben Deutsch <ben@bendeutsch.de> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_auth.h" +#include "lua_api/l_internal.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "cpp_api/s_base.h" +#include "server.h" +#include "environment.h" +#include "database/database.h" +#include <algorithm> + +// common start: ensure auth db +AuthDatabase *ModApiAuth::getAuthDb(lua_State *L) +{ + ServerEnvironment *server_environment = + dynamic_cast<ServerEnvironment *>(getEnv(L)); + if (!server_environment) { + luaL_error(L, "Attempt to access an auth function but the auth" + " system is yet not initialized. This causes bugs."); + return nullptr; + } + return server_environment->getAuthDatabase(); +} + +void ModApiAuth::pushAuthEntry(lua_State *L, const AuthEntry &authEntry) +{ + lua_newtable(L); + int table = lua_gettop(L); + // id + lua_pushnumber(L, authEntry.id); + lua_setfield(L, table, "id"); + // name + lua_pushstring(L, authEntry.name.c_str()); + lua_setfield(L, table, "name"); + // password + lua_pushstring(L, authEntry.password.c_str()); + lua_setfield(L, table, "password"); + // privileges + lua_newtable(L); + int privtable = lua_gettop(L); + for (const std::string &privs : authEntry.privileges) { + lua_pushboolean(L, true); + lua_setfield(L, privtable, privs.c_str()); + } + lua_setfield(L, table, "privileges"); + // last_login + lua_pushnumber(L, authEntry.last_login); + lua_setfield(L, table, "last_login"); + + lua_pushvalue(L, table); +} + +// auth_read(name) +int ModApiAuth::l_auth_read(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + AuthDatabase *auth_db = getAuthDb(L); + if (!auth_db) + return 0; + AuthEntry authEntry; + const char *name = luaL_checkstring(L, 1); + bool success = auth_db->getAuth(std::string(name), authEntry); + if (!success) + return 0; + + pushAuthEntry(L, authEntry); + return 1; +} + +// auth_save(table) +int ModApiAuth::l_auth_save(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + AuthDatabase *auth_db = getAuthDb(L); + if (!auth_db) + return 0; + luaL_checktype(L, 1, LUA_TTABLE); + int table = 1; + AuthEntry authEntry; + bool success; + success = getintfield(L, table, "id", authEntry.id); + success = success && getstringfield(L, table, "name", authEntry.name); + success = success && getstringfield(L, table, "password", authEntry.password); + lua_getfield(L, table, "privileges"); + if (lua_istable(L, -1)) { + lua_pushnil(L); + while (lua_next(L, -2)) { + authEntry.privileges.emplace_back( + lua_tostring(L, -2)); // the key, not the value + lua_pop(L, 1); + } + } else { + success = false; + } + lua_pop(L, 1); // the table + success = success && getintfield(L, table, "last_login", authEntry.last_login); + + if (!success) { + lua_pushboolean(L, false); + return 1; + } + + lua_pushboolean(L, auth_db->saveAuth(authEntry)); + return 1; +} + +// auth_create(table) +int ModApiAuth::l_auth_create(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + AuthDatabase *auth_db = getAuthDb(L); + if (!auth_db) + return 0; + luaL_checktype(L, 1, LUA_TTABLE); + int table = 1; + AuthEntry authEntry; + bool success; + // no meaningful id field, we assume + success = getstringfield(L, table, "name", authEntry.name); + success = success && getstringfield(L, table, "password", authEntry.password); + lua_getfield(L, table, "privileges"); + if (lua_istable(L, -1)) { + lua_pushnil(L); + while (lua_next(L, -2)) { + authEntry.privileges.emplace_back( + lua_tostring(L, -2)); // the key, not the value + lua_pop(L, 1); + } + } else { + success = false; + } + lua_pop(L, 1); // the table + success = success && getintfield(L, table, "last_login", authEntry.last_login); + + if (!success) + return 0; + + if (auth_db->createAuth(authEntry)) { + pushAuthEntry(L, authEntry); + return 1; + } + + return 0; +} + +// auth_delete(name) +int ModApiAuth::l_auth_delete(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + AuthDatabase *auth_db = getAuthDb(L); + if (!auth_db) + return 0; + std::string name(luaL_checkstring(L, 1)); + lua_pushboolean(L, auth_db->deleteAuth(name)); + return 1; +} + +// auth_list_names() +int ModApiAuth::l_auth_list_names(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + AuthDatabase *auth_db = getAuthDb(L); + if (!auth_db) + return 0; + std::vector<std::string> names; + auth_db->listNames(names); + lua_createtable(L, names.size(), 0); + int table = lua_gettop(L); + int i = 1; + for (const std::string &name : names) { + lua_pushstring(L, name.c_str()); + lua_rawseti(L, table, i++); + } + return 1; +} + +// auth_reload() +int ModApiAuth::l_auth_reload(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + AuthDatabase *auth_db = getAuthDb(L); + if (auth_db) + auth_db->reload(); + return 0; +} + +void ModApiAuth::Initialize(lua_State *L, int top) +{ + + lua_newtable(L); + int auth_top = lua_gettop(L); + + registerFunction(L, "read", l_auth_read, auth_top); + registerFunction(L, "save", l_auth_save, auth_top); + registerFunction(L, "create", l_auth_create, auth_top); + registerFunction(L, "delete", l_auth_delete, auth_top); + registerFunction(L, "list_names", l_auth_list_names, auth_top); + registerFunction(L, "reload", l_auth_reload, auth_top); + + lua_setfield(L, top, "auth"); +} diff --git a/src/script/lua_api/l_auth.h b/src/script/lua_api/l_auth.h new file mode 100644 index 0000000..fb9a987 --- /dev/null +++ b/src/script/lua_api/l_auth.h @@ -0,0 +1,54 @@ +/* +Minetest +Copyright (C) 2018 bendeutsch, Ben Deutsch <ben@bendeutsch.de> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" + +class AuthDatabase; +struct AuthEntry; + +class ModApiAuth : public ModApiBase +{ +private: + // auth_read(name) + static int l_auth_read(lua_State *L); + + // auth_save(table) + static int l_auth_save(lua_State *L); + + // auth_create(table) + static int l_auth_create(lua_State *L); + + // auth_delete(name) + static int l_auth_delete(lua_State *L); + + // auth_list_names() + static int l_auth_list_names(lua_State *L); + + // auth_reload() + static int l_auth_reload(lua_State *L); + + // helper for auth* methods + static AuthDatabase *getAuthDb(lua_State *L); + static void pushAuthEntry(lua_State *L, const AuthEntry &authEntry); + +public: + static void Initialize(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_base.cpp b/src/script/lua_api/l_base.cpp new file mode 100644 index 0000000..f842671 --- /dev/null +++ b/src/script/lua_api/l_base.cpp @@ -0,0 +1,139 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_base.h" +#include "lua_api/l_internal.h" +#include "cpp_api/s_base.h" +#include "content/mods.h" +#include "profiler.h" +#include "server.h" +#include <algorithm> +#include <cmath> + +ScriptApiBase *ModApiBase::getScriptApiBase(lua_State *L) +{ + // Get server from registry + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI); + ScriptApiBase *sapi_ptr; +#if INDIRECT_SCRIPTAPI_RIDX + sapi_ptr = (ScriptApiBase*) *(void**)(lua_touserdata(L, -1)); +#else + sapi_ptr = (ScriptApiBase*) lua_touserdata(L, -1); +#endif + lua_pop(L, 1); + return sapi_ptr; +} + +Server *ModApiBase::getServer(lua_State *L) +{ + return getScriptApiBase(L)->getServer(); +} + +ServerInventoryManager *ModApiBase::getServerInventoryMgr(lua_State *L) +{ + return getScriptApiBase(L)->getServer()->getInventoryMgr(); +} + +#ifndef SERVER +Client *ModApiBase::getClient(lua_State *L) +{ + return getScriptApiBase(L)->getClient(); +} +#endif + +IGameDef *ModApiBase::getGameDef(lua_State *L) +{ + return getScriptApiBase(L)->getGameDef(); +} + +Environment *ModApiBase::getEnv(lua_State *L) +{ + return getScriptApiBase(L)->getEnv(); +} + +#ifndef SERVER +GUIEngine *ModApiBase::getGuiEngine(lua_State *L) +{ + return getScriptApiBase(L)->getGuiEngine(); +} +#endif + +std::string ModApiBase::getCurrentModPath(lua_State *L) +{ + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); + std::string current_mod_name = readParam<std::string>(L, -1, ""); + if (current_mod_name.empty()) + return "."; + + const ModSpec *mod = getServer(L)->getModSpec(current_mod_name); + if (!mod) + return "."; + + return mod->path; +} + + +bool ModApiBase::registerFunction(lua_State *L, const char *name, + lua_CFunction func, int top) +{ + // TODO: Check presence first! + + lua_pushcfunction(L, func); + lua_setfield(L, top, name); + + return true; +} + +int ModApiBase::l_deprecated_function(lua_State *L, const char *good, const char *bad, lua_CFunction func) +{ + thread_local std::vector<u64> deprecated_logged; + + DeprecatedHandlingMode dep_mode = get_deprecated_handling_mode(); + if (dep_mode == DeprecatedHandlingMode::Ignore) + return func(L); + + u64 start_time = porting::getTimeUs(); + lua_Debug ar; + + // Get caller name with line and script backtrace + FATAL_ERROR_IF(!lua_getstack(L, 1, &ar), "lua_getstack() failed"); + FATAL_ERROR_IF(!lua_getinfo(L, "Sl", &ar), "lua_getinfo() failed"); + + // Get backtrace and hash it to reduce the warning flood + std::string backtrace = ar.short_src; + backtrace.append(":").append(std::to_string(ar.currentline)); + u64 hash = murmur_hash_64_ua(backtrace.data(), backtrace.length(), 0xBADBABE); + + if (std::find(deprecated_logged.begin(), deprecated_logged.end(), hash) + == deprecated_logged.end()) { + + deprecated_logged.emplace_back(hash); + warningstream << "Call to deprecated function '" << bad << "', please use '" + << good << "' at " << backtrace << std::endl; + + if (dep_mode == DeprecatedHandlingMode::Error) + script_error(L, LUA_ERRRUN, NULL, NULL); + } + + u64 end_time = porting::getTimeUs(); + g_profiler->avg("l_deprecated_function", end_time - start_time); + + return func(L); +} + diff --git a/src/script/lua_api/l_base.h b/src/script/lua_api/l_base.h new file mode 100644 index 0000000..aa5905d --- /dev/null +++ b/src/script/lua_api/l_base.h @@ -0,0 +1,91 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "common/c_types.h" +#include "common/c_internal.h" +#include "common/helper.h" +#include "gamedef.h" +#include <unordered_map> + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +} + +#ifndef SERVER +class Client; +class GUIEngine; +#endif + +class ScriptApiBase; +class Server; +class Environment; +class ServerInventoryManager; + +class ModApiBase : protected LuaHelper { +public: + static ScriptApiBase* getScriptApiBase(lua_State *L); + static Server* getServer(lua_State *L); + static ServerInventoryManager *getServerInventoryMgr(lua_State *L); + #ifndef SERVER + static Client* getClient(lua_State *L); + static GUIEngine* getGuiEngine(lua_State *L); + #endif // !SERVER + + static IGameDef* getGameDef(lua_State *L); + + static Environment* getEnv(lua_State *L); + + // When we are not loading the mod, this function returns "." + static std::string getCurrentModPath(lua_State *L); + + // Get an arbitrary subclass of ScriptApiBase + // by using dynamic_cast<> on getScriptApiBase() + template<typename T> + static T* getScriptApi(lua_State *L) { + ScriptApiBase *scriptIface = getScriptApiBase(L); + T *scriptIfaceDowncast = dynamic_cast<T*>(scriptIface); + if (!scriptIfaceDowncast) { + throw LuaError("Requested unavailable ScriptApi - core engine bug!"); + } + return scriptIfaceDowncast; + } + + static bool registerFunction(lua_State *L, + const char* name, + lua_CFunction func, + int top); + + /** + * A wrapper for deprecated functions. + * + * When called, handles the deprecation according to user settings and then calls `func`. + * + * @throws Lua Error if required by the user settings. + * + * @param L Lua state + * @param good Name of good function/method + * @param bad Name of deprecated function/method + * @param func Actual implementation of function + * @return value from `func` + */ + static int l_deprecated_function(lua_State *L, const char *good, const char *bad, lua_CFunction func); +}; diff --git a/src/script/lua_api/l_camera.cpp b/src/script/lua_api/l_camera.cpp new file mode 100644 index 0000000..d85d162 --- /dev/null +++ b/src/script/lua_api/l_camera.cpp @@ -0,0 +1,241 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "l_camera.h" +#include <cmath> +#include "script/common/c_converter.h" +#include "l_internal.h" +#include "client/content_cao.h" +#include "client/camera.h" +#include "client/client.h" + +LuaCamera::LuaCamera(Camera *m) : m_camera(m) +{ +} + +void LuaCamera::create(lua_State *L, Camera *m) +{ + lua_getglobal(L, "core"); + luaL_checktype(L, -1, LUA_TTABLE); + int objectstable = lua_gettop(L); + lua_getfield(L, -1, "camera"); + + // Duplication check + if (lua_type(L, -1) == LUA_TUSERDATA) { + lua_pop(L, 1); + return; + } + + LuaCamera *o = new LuaCamera(m); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + + lua_pushvalue(L, lua_gettop(L)); + lua_setfield(L, objectstable, "camera"); +} + +// set_camera_mode(self, mode) +int LuaCamera::l_set_camera_mode(lua_State *L) +{ + Camera *camera = getobject(L, 1); + GenericCAO *playercao = getClient(L)->getEnv().getLocalPlayer()->getCAO(); + if (!camera) + return 0; + sanity_check(playercao); + if (!lua_isnumber(L, 2)) + return 0; + + camera->setCameraMode((CameraMode)((int)lua_tonumber(L, 2))); + // Make the player visible depending on camera mode. + playercao->updateMeshCulling(); + playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST); + return 0; +} + +// get_camera_mode(self) +int LuaCamera::l_get_camera_mode(lua_State *L) +{ + Camera *camera = getobject(L, 1); + if (!camera) + return 0; + + lua_pushinteger(L, (int)camera->getCameraMode()); + + return 1; +} + +// get_fov(self) +int LuaCamera::l_get_fov(lua_State *L) +{ + Camera *camera = getobject(L, 1); + if (!camera) + return 0; + + lua_newtable(L); + lua_pushnumber(L, camera->getFovX() * core::RADTODEG); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, camera->getFovY() * core::RADTODEG); + lua_setfield(L, -2, "y"); + lua_pushnumber(L, camera->getCameraNode()->getFOV() * core::RADTODEG); + lua_setfield(L, -2, "actual"); + lua_pushnumber(L, camera->getFovMax() * core::RADTODEG); + lua_setfield(L, -2, "max"); + return 1; +} + +// get_pos(self) +int LuaCamera::l_get_pos(lua_State *L) +{ + Camera *camera = getobject(L, 1); + if (!camera) + return 0; + + push_v3f(L, camera->getPosition() / BS); + return 1; +} + +// get_offset(self) +int LuaCamera::l_get_offset(lua_State *L) +{ + LocalPlayer *player = getClient(L)->getEnv().getLocalPlayer(); + sanity_check(player); + + push_v3f(L, player->getEyeOffset() / BS); + return 1; +} + +// get_look_dir(self) +int LuaCamera::l_get_look_dir(lua_State *L) +{ + Camera *camera = getobject(L, 1); + if (!camera) + return 0; + + push_v3f(L, camera->getDirection()); + return 1; +} + +// get_look_horizontal(self) +// FIXME: wouldn't localplayer be a better place for this? +int LuaCamera::l_get_look_horizontal(lua_State *L) +{ + LocalPlayer *player = getClient(L)->getEnv().getLocalPlayer(); + sanity_check(player); + + lua_pushnumber(L, (player->getYaw() + 90.f) * core::DEGTORAD); + return 1; +} + +// get_look_vertical(self) +// FIXME: wouldn't localplayer be a better place for this? +int LuaCamera::l_get_look_vertical(lua_State *L) +{ + LocalPlayer *player = getClient(L)->getEnv().getLocalPlayer(); + sanity_check(player); + + lua_pushnumber(L, -1.0f * player->getPitch() * core::DEGTORAD); + return 1; +} + +// get_aspect_ratio(self) +int LuaCamera::l_get_aspect_ratio(lua_State *L) +{ + Camera *camera = getobject(L, 1); + if (!camera) + return 0; + + lua_pushnumber(L, camera->getCameraNode()->getAspectRatio()); + return 1; +} + +LuaCamera *LuaCamera::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + + return *(LuaCamera **)ud; +} + +Camera *LuaCamera::getobject(LuaCamera *ref) +{ + return ref->m_camera; +} + +Camera *LuaCamera::getobject(lua_State *L, int narg) +{ + LuaCamera *ref = checkobject(L, narg); + assert(ref); + Camera *camera = getobject(ref); + if (!camera) + return NULL; + return camera; +} + +int LuaCamera::gc_object(lua_State *L) +{ + LuaCamera *o = *(LuaCamera **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +void LuaCamera::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); + + luaL_register(L, nullptr, methods); + lua_pop(L, 1); +} + +// clang-format off +const char LuaCamera::className[] = "Camera"; +const luaL_Reg LuaCamera::methods[] = { + luamethod(LuaCamera, set_camera_mode), + luamethod(LuaCamera, get_camera_mode), + luamethod(LuaCamera, get_fov), + luamethod(LuaCamera, get_pos), + luamethod(LuaCamera, get_offset), + luamethod(LuaCamera, get_look_dir), + luamethod(LuaCamera, get_look_vertical), + luamethod(LuaCamera, get_look_horizontal), + luamethod(LuaCamera, get_aspect_ratio), + + {0, 0} +}; +// clang-format on diff --git a/src/script/lua_api/l_camera.h b/src/script/lua_api/l_camera.h new file mode 100644 index 0000000..f3021bc --- /dev/null +++ b/src/script/lua_api/l_camera.h @@ -0,0 +1,60 @@ +/* +Minetest +Copyright (C) 2013-2017 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "l_base.h" + +class Camera; + +class LuaCamera : public ModApiBase +{ +private: + static const char className[]; + static const luaL_Reg methods[]; + + // garbage collector + static int gc_object(lua_State *L); + + static int l_set_camera_mode(lua_State *L); + static int l_get_camera_mode(lua_State *L); + + static int l_get_fov(lua_State *L); + + static int l_get_pos(lua_State *L); + static int l_get_offset(lua_State *L); + static int l_get_look_dir(lua_State *L); + static int l_get_look_vertical(lua_State *L); + static int l_get_look_horizontal(lua_State *L); + static int l_get_aspect_ratio(lua_State *L); + + Camera *m_camera = nullptr; + +public: + LuaCamera(Camera *m); + ~LuaCamera() = default; + + static void create(lua_State *L, Camera *m); + + static LuaCamera *checkobject(lua_State *L, int narg); + static Camera *getobject(LuaCamera *ref); + static Camera *getobject(lua_State *L, int narg); + + static void Register(lua_State *L); +}; diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp new file mode 100644 index 0000000..05ac53c --- /dev/null +++ b/src/script/lua_api/l_client.cpp @@ -0,0 +1,446 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "l_client.h" +#include "chatmessage.h" +#include "client/client.h" +#include "client/clientevent.h" +#include "client/sound.h" +#include "client/clientenvironment.h" +#include "common/c_content.h" +#include "common/c_converter.h" +#include "cpp_api/s_base.h" +#include "gettext.h" +#include "l_internal.h" +#include "lua_api/l_nodemeta.h" +#include "gui/mainmenumanager.h" +#include "map.h" +#include "util/string.h" +#include "nodedef.h" + +#define checkCSMRestrictionFlag(flag) \ + ( getClient(L)->checkCSMRestrictionFlag(CSMRestrictionFlags::flag) ) + +// Not the same as FlagDesc, which contains an `u32 flag` +struct CSMFlagDesc { + const char *name; + u64 flag; +}; + +/* + FIXME: This should eventually be moved somewhere else + It also needs to be kept in sync with the definition of CSMRestrictionFlags + in network/networkprotocol.h +*/ +const static CSMFlagDesc flagdesc_csm_restriction[] = { + {"load_client_mods", CSM_RF_LOAD_CLIENT_MODS}, + {"chat_messages", CSM_RF_CHAT_MESSAGES}, + {"read_itemdefs", CSM_RF_READ_ITEMDEFS}, + {"read_nodedefs", CSM_RF_READ_NODEDEFS}, + {"lookup_nodes", CSM_RF_LOOKUP_NODES}, + {"read_playerinfo", CSM_RF_READ_PLAYERINFO}, + {NULL, 0} +}; + +// get_current_modname() +int ModApiClient::l_get_current_modname(lua_State *L) +{ + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); + return 1; +} + +// get_modpath(modname) +int ModApiClient::l_get_modpath(lua_State *L) +{ + std::string modname = readParam<std::string>(L, 1); + // Client mods use a virtual filesystem, see Client::scanModSubfolder() + std::string path = modname + ":"; + lua_pushstring(L, path.c_str()); + return 1; +} + +// get_last_run_mod() +int ModApiClient::l_get_last_run_mod(lua_State *L) +{ + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); + std::string current_mod = readParam<std::string>(L, -1, ""); + if (current_mod.empty()) { + lua_pop(L, 1); + lua_pushstring(L, getScriptApiBase(L)->getOrigin().c_str()); + } + return 1; +} + +// set_last_run_mod(modname) +int ModApiClient::l_set_last_run_mod(lua_State *L) +{ + if (!lua_isstring(L, 1)) + return 0; + + const char *mod = lua_tostring(L, 1); + getScriptApiBase(L)->setOriginDirect(mod); + lua_pushboolean(L, true); + return 1; +} + +// print(text) +int ModApiClient::l_print(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string text = luaL_checkstring(L, 1); + rawstream << text << std::endl; + return 0; +} + +// display_chat_message(message) +int ModApiClient::l_display_chat_message(lua_State *L) +{ + if (!lua_isstring(L, 1)) + return 0; + + std::string message = luaL_checkstring(L, 1); + getClient(L)->pushToChatQueue(new ChatMessage(utf8_to_wide(message))); + lua_pushboolean(L, true); + return 1; +} + +// send_chat_message(message) +int ModApiClient::l_send_chat_message(lua_State *L) +{ + if (!lua_isstring(L, 1)) + return 0; + + // If server disabled this API, discard + + if (checkCSMRestrictionFlag(CSM_RF_CHAT_MESSAGES)) + return 0; + + std::string message = luaL_checkstring(L, 1); + getClient(L)->sendChatMessage(utf8_to_wide(message)); + return 0; +} + +// clear_out_chat_queue() +int ModApiClient::l_clear_out_chat_queue(lua_State *L) +{ + getClient(L)->clearOutChatQueue(); + return 0; +} + +// get_player_names() +int ModApiClient::l_get_player_names(lua_State *L) +{ + if (checkCSMRestrictionFlag(CSM_RF_READ_PLAYERINFO)) + return 0; + + const std::list<std::string> &plist = getClient(L)->getConnectedPlayerNames(); + lua_createtable(L, plist.size(), 0); + int newTable = lua_gettop(L); + int index = 1; + std::list<std::string>::const_iterator iter; + for (iter = plist.begin(); iter != plist.end(); ++iter) { + lua_pushstring(L, (*iter).c_str()); + lua_rawseti(L, newTable, index); + index++; + } + return 1; +} + +// show_formspec(formspec) +int ModApiClient::l_show_formspec(lua_State *L) +{ + if (!lua_isstring(L, 1) || !lua_isstring(L, 2)) + return 0; + + ClientEvent *event = new ClientEvent(); + event->type = CE_SHOW_LOCAL_FORMSPEC; + event->show_formspec.formname = new std::string(luaL_checkstring(L, 1)); + event->show_formspec.formspec = new std::string(luaL_checkstring(L, 2)); + getClient(L)->pushToEventQueue(event); + lua_pushboolean(L, true); + return 1; +} + +// send_respawn() +int ModApiClient::l_send_respawn(lua_State *L) +{ + getClient(L)->sendRespawn(); + return 0; +} + +// disconnect() +int ModApiClient::l_disconnect(lua_State *L) +{ + // Stops badly written Lua code form causing boot loops + if (getClient(L)->isShutdown()) { + lua_pushboolean(L, false); + return 1; + } + + g_gamecallback->disconnect(); + lua_pushboolean(L, true); + return 1; +} + +// gettext(text) +int ModApiClient::l_gettext(lua_State *L) +{ + std::string text = strgettext(std::string(luaL_checkstring(L, 1))); + lua_pushstring(L, text.c_str()); + + return 1; +} + +// get_node_or_nil(pos) +// pos = {x=num, y=num, z=num} +int ModApiClient::l_get_node_or_nil(lua_State *L) +{ + // pos + v3s16 pos = read_v3s16(L, 1); + + // Do it + bool pos_ok; + MapNode n = getClient(L)->CSMGetNode(pos, &pos_ok); + if (pos_ok) { + // Return node + pushnode(L, n, getClient(L)->ndef()); + } else { + lua_pushnil(L); + } + return 1; +} + +// get_langauge() +int ModApiClient::l_get_language(lua_State *L) +{ +#ifdef _WIN32 + char *locale = setlocale(LC_ALL, NULL); +#else + char *locale = setlocale(LC_MESSAGES, NULL); +#endif + std::string lang = gettext("LANG_CODE"); + if (lang == "LANG_CODE") + lang = ""; + + lua_pushstring(L, locale); + lua_pushstring(L, lang.c_str()); + return 2; +} + +// get_meta(pos) +int ModApiClient::l_get_meta(lua_State *L) +{ + v3s16 p = read_v3s16(L, 1); + + // check restrictions first + bool pos_ok; + getClient(L)->CSMGetNode(p, &pos_ok); + if (!pos_ok) + return 0; + + NodeMetadata *meta = getEnv(L)->getMap().getNodeMetadata(p); + NodeMetaRef::createClient(L, meta); + return 1; +} + +// sound_play(spec, parameters) +int ModApiClient::l_sound_play(lua_State *L) +{ + ISoundManager *sound = getClient(L)->getSoundManager(); + + SimpleSoundSpec spec; + read_soundspec(L, 1, spec); + + SoundLocation type = SoundLocation::Local; + float gain = 1.0f; + v3f position; + + if (lua_istable(L, 2)) { + getfloatfield(L, 2, "gain", gain); + getfloatfield(L, 2, "pitch", spec.pitch); + getboolfield(L, 2, "loop", spec.loop); + + lua_getfield(L, 2, "pos"); + if (!lua_isnil(L, -1)) { + position = read_v3f(L, -1) * BS; + type = SoundLocation::Position; + lua_pop(L, 1); + } + } + + spec.gain *= gain; + + s32 handle; + if (type == SoundLocation::Local) + handle = sound->playSound(spec); + else + handle = sound->playSoundAt(spec, position); + + lua_pushinteger(L, handle); + return 1; +} + +// sound_stop(handle) +int ModApiClient::l_sound_stop(lua_State *L) +{ + s32 handle = luaL_checkinteger(L, 1); + + getClient(L)->getSoundManager()->stopSound(handle); + + return 0; +} + +// sound_fade(handle, step, gain) +int ModApiClient::l_sound_fade(lua_State *L) +{ + s32 handle = luaL_checkinteger(L, 1); + float step = readParam<float>(L, 2); + float gain = readParam<float>(L, 3); + getClient(L)->getSoundManager()->fadeSound(handle, step, gain); + return 0; +} + +// get_server_info() +int ModApiClient::l_get_server_info(lua_State *L) +{ + Client *client = getClient(L); + Address serverAddress = client->getServerAddress(); + lua_newtable(L); + lua_pushstring(L, client->getAddressName().c_str()); + lua_setfield(L, -2, "address"); + lua_pushstring(L, serverAddress.serializeString().c_str()); + lua_setfield(L, -2, "ip"); + lua_pushinteger(L, serverAddress.getPort()); + lua_setfield(L, -2, "port"); + lua_pushinteger(L, client->getProtoVersion()); + lua_setfield(L, -2, "protocol_version"); + return 1; +} + +// get_item_def(itemstring) +int ModApiClient::l_get_item_def(lua_State *L) +{ + IGameDef *gdef = getGameDef(L); + assert(gdef); + + IItemDefManager *idef = gdef->idef(); + assert(idef); + + if (checkCSMRestrictionFlag(CSM_RF_READ_ITEMDEFS)) + return 0; + + if (!lua_isstring(L, 1)) + return 0; + + std::string name = readParam<std::string>(L, 1); + if (!idef->isKnown(name)) + return 0; + const ItemDefinition &def = idef->get(name); + + push_item_definition_full(L, def); + + return 1; +} + +// get_node_def(nodename) +int ModApiClient::l_get_node_def(lua_State *L) +{ + IGameDef *gdef = getGameDef(L); + assert(gdef); + + const NodeDefManager *ndef = gdef->ndef(); + assert(ndef); + + if (!lua_isstring(L, 1)) + return 0; + + if (checkCSMRestrictionFlag(CSM_RF_READ_NODEDEFS)) + return 0; + + std::string name = readParam<std::string>(L, 1); + const ContentFeatures &cf = ndef->get(ndef->getId(name)); + if (cf.name != name) // Unknown node. | name = <whatever>, cf.name = ignore + return 0; + + push_content_features(L, cf); + + return 1; +} + +// get_privilege_list() +int ModApiClient::l_get_privilege_list(lua_State *L) +{ + const Client *client = getClient(L); + lua_newtable(L); + for (const std::string &priv : client->getPrivilegeList()) { + lua_pushboolean(L, true); + lua_setfield(L, -2, priv.c_str()); + } + return 1; +} + +// get_builtin_path() +int ModApiClient::l_get_builtin_path(lua_State *L) +{ + lua_pushstring(L, BUILTIN_MOD_NAME ":"); + return 1; +} + +// get_csm_restrictions() +int ModApiClient::l_get_csm_restrictions(lua_State *L) +{ + u64 flags = getClient(L)->getCSMRestrictionFlags(); + const CSMFlagDesc *flagdesc = flagdesc_csm_restriction; + + lua_newtable(L); + for (int i = 0; flagdesc[i].name; i++) { + setboolfield(L, -1, flagdesc[i].name, !!(flags & flagdesc[i].flag)); + } + return 1; +} + +void ModApiClient::Initialize(lua_State *L, int top) +{ + API_FCT(get_current_modname); + API_FCT(get_modpath); + API_FCT(print); + API_FCT(display_chat_message); + API_FCT(send_chat_message); + API_FCT(clear_out_chat_queue); + API_FCT(get_player_names); + API_FCT(set_last_run_mod); + API_FCT(get_last_run_mod); + API_FCT(show_formspec); + API_FCT(send_respawn); + API_FCT(gettext); + API_FCT(get_node_or_nil); + API_FCT(disconnect); + API_FCT(get_meta); + API_FCT(sound_play); + API_FCT(sound_stop); + API_FCT(sound_fade); + API_FCT(get_server_info); + API_FCT(get_item_def); + API_FCT(get_node_def); + API_FCT(get_privilege_list); + API_FCT(get_builtin_path); + API_FCT(get_language); + API_FCT(get_csm_restrictions); +} diff --git a/src/script/lua_api/l_client.h b/src/script/lua_api/l_client.h new file mode 100644 index 0000000..5dc3efd --- /dev/null +++ b/src/script/lua_api/l_client.h @@ -0,0 +1,110 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" +#include "itemdef.h" +#include "tool.h" + +class ModApiClient : public ModApiBase +{ +private: + // get_current_modname() + static int l_get_current_modname(lua_State *L); + + // get_modpath(modname) + static int l_get_modpath(lua_State *L); + + // print(text) + static int l_print(lua_State *L); + + // display_chat_message(message) + static int l_display_chat_message(lua_State *L); + + // send_chat_message(message) + static int l_send_chat_message(lua_State *L); + + // clear_out_chat_queue() + static int l_clear_out_chat_queue(lua_State *L); + + // get_player_names() + static int l_get_player_names(lua_State *L); + + // show_formspec(name, formspec) + static int l_show_formspec(lua_State *L); + + // send_respawn() + static int l_send_respawn(lua_State *L); + + // disconnect() + static int l_disconnect(lua_State *L); + + // gettext(text) + static int l_gettext(lua_State *L); + + // get_last_run_mod(n) + static int l_get_last_run_mod(lua_State *L); + + // set_last_run_mod(modname) + static int l_set_last_run_mod(lua_State *L); + + // get_node(pos) + static int l_get_node_or_nil(lua_State *L); + + // get_language() + static int l_get_language(lua_State *L); + + // get_wielded_item() + static int l_get_wielded_item(lua_State *L); + + // get_meta(pos) + static int l_get_meta(lua_State *L); + + // sound_play(spec, parameters) + static int l_sound_play(lua_State *L); + + // sound_stop(handle) + static int l_sound_stop(lua_State *L); + + // sound_fade(handle, step, gain) + static int l_sound_fade(lua_State *L); + + // get_server_info() + static int l_get_server_info(lua_State *L); + + // get_item_def(itemstring) + static int l_get_item_def(lua_State *L); + + // get_node_def(nodename) + static int l_get_node_def(lua_State *L); + + // get_privilege_list() + static int l_get_privilege_list(lua_State *L); + + // get_builtin_path() + static int l_get_builtin_path(lua_State *L); + + // get_csm_restrictions() + static int l_get_csm_restrictions(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_craft.cpp b/src/script/lua_api/l_craft.cpp new file mode 100644 index 0000000..137b210 --- /dev/null +++ b/src/script/lua_api/l_craft.cpp @@ -0,0 +1,535 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "lua_api/l_craft.h" +#include "lua_api/l_internal.h" +#include "lua_api/l_item.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "server.h" +#include "craftdef.h" + +struct EnumString ModApiCraft::es_CraftMethod[] = +{ + {CRAFT_METHOD_NORMAL, "normal"}, + {CRAFT_METHOD_COOKING, "cooking"}, + {CRAFT_METHOD_FUEL, "fuel"}, + {0, NULL}, +}; + +// helper for register_craft +bool ModApiCraft::readCraftRecipeShaped(lua_State *L, int index, + int &width, std::vector<std::string> &recipe) +{ + if(index < 0) + index = lua_gettop(L) + 1 + index; + + if(!lua_istable(L, index)) + return false; + + lua_pushnil(L); + int rowcount = 0; + while(lua_next(L, index) != 0){ + int colcount = 0; + // key at index -2 and value at index -1 + if(!lua_istable(L, -1)) + return false; + int table2 = lua_gettop(L); + lua_pushnil(L); + while(lua_next(L, table2) != 0){ + // key at index -2 and value at index -1 + if(!lua_isstring(L, -1)) + return false; + recipe.emplace_back(readParam<std::string>(L, -1)); + // removes value, keeps key for next iteration + lua_pop(L, 1); + colcount++; + } + if(rowcount == 0){ + width = colcount; + } else { + if(colcount != width) + return false; + } + // removes value, keeps key for next iteration + lua_pop(L, 1); + rowcount++; + } + return width != 0; +} + +// helper for register_craft +bool ModApiCraft::readCraftRecipeShapeless(lua_State *L, int index, + std::vector<std::string> &recipe) +{ + if(index < 0) + index = lua_gettop(L) + 1 + index; + + if(!lua_istable(L, index)) + return false; + + lua_pushnil(L); + while(lua_next(L, index) != 0){ + // key at index -2 and value at index -1 + if(!lua_isstring(L, -1)) + return false; + recipe.emplace_back(readParam<std::string>(L, -1)); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + return true; +} + +// helper for register_craft +bool ModApiCraft::readCraftReplacements(lua_State *L, int index, + CraftReplacements &replacements) +{ + if(index < 0) + index = lua_gettop(L) + 1 + index; + + if(!lua_istable(L, index)) + return false; + + lua_pushnil(L); + while(lua_next(L, index) != 0){ + // key at index -2 and value at index -1 + if(!lua_istable(L, -1)) + return false; + lua_rawgeti(L, -1, 1); + if(!lua_isstring(L, -1)) + return false; + std::string replace_from = readParam<std::string>(L, -1); + lua_pop(L, 1); + lua_rawgeti(L, -1, 2); + if(!lua_isstring(L, -1)) + return false; + std::string replace_to = readParam<std::string>(L, -1); + lua_pop(L, 1); + replacements.pairs.emplace_back(replace_from, replace_to); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + return true; +} +// register_craft({output=item, recipe={{item00,item10},{item01,item11}}) +int ModApiCraft::l_register_craft(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + //infostream<<"register_craft"<<std::endl; + luaL_checktype(L, 1, LUA_TTABLE); + int table = 1; + + // Get the writable craft definition manager from the server + IWritableCraftDefManager *craftdef = + getServer(L)->getWritableCraftDefManager(); + + std::string type = getstringfield_default(L, table, "type", "shaped"); + + /* + CraftDefinitionShaped + */ + if(type == "shaped"){ + std::string output = getstringfield_default(L, table, "output", ""); + if (output.empty()) + throw LuaError("Crafting definition is missing an output"); + + int width = 0; + std::vector<std::string> recipe; + lua_getfield(L, table, "recipe"); + if(lua_isnil(L, -1)) + throw LuaError("Crafting definition is missing a recipe" + " (output=\"" + output + "\")"); + if(!readCraftRecipeShaped(L, -1, width, recipe)) + throw LuaError("Invalid crafting recipe" + " (output=\"" + output + "\")"); + + CraftReplacements replacements; + lua_getfield(L, table, "replacements"); + if(!lua_isnil(L, -1)) + { + if(!readCraftReplacements(L, -1, replacements)) + throw LuaError("Invalid replacements" + " (output=\"" + output + "\")"); + } + + CraftDefinition *def = new CraftDefinitionShaped( + output, width, recipe, replacements); + craftdef->registerCraft(def, getServer(L)); + } + /* + CraftDefinitionShapeless + */ + else if(type == "shapeless"){ + std::string output = getstringfield_default(L, table, "output", ""); + if (output.empty()) + throw LuaError("Crafting definition (shapeless)" + " is missing an output"); + + std::vector<std::string> recipe; + lua_getfield(L, table, "recipe"); + if(lua_isnil(L, -1)) + throw LuaError("Crafting definition (shapeless)" + " is missing a recipe" + " (output=\"" + output + "\")"); + if(!readCraftRecipeShapeless(L, -1, recipe)) + throw LuaError("Invalid crafting recipe" + " (output=\"" + output + "\")"); + + CraftReplacements replacements; + lua_getfield(L, table, "replacements"); + if(!lua_isnil(L, -1)) + { + if(!readCraftReplacements(L, -1, replacements)) + throw LuaError("Invalid replacements" + " (output=\"" + output + "\")"); + } + + CraftDefinition *def = new CraftDefinitionShapeless( + output, recipe, replacements); + craftdef->registerCraft(def, getServer(L)); + } + /* + CraftDefinitionToolRepair + */ + else if(type == "toolrepair"){ + float additional_wear = getfloatfield_default(L, table, + "additional_wear", 0.0); + + CraftDefinition *def = new CraftDefinitionToolRepair( + additional_wear); + craftdef->registerCraft(def, getServer(L)); + } + /* + CraftDefinitionCooking + */ + else if(type == "cooking"){ + std::string output = getstringfield_default(L, table, "output", ""); + if (output.empty()) + throw LuaError("Crafting definition (cooking)" + " is missing an output"); + + std::string recipe = getstringfield_default(L, table, "recipe", ""); + if (recipe.empty()) + throw LuaError("Crafting definition (cooking)" + " is missing a recipe" + " (output=\"" + output + "\")"); + + float cooktime = getfloatfield_default(L, table, "cooktime", 3.0); + + CraftReplacements replacements; + lua_getfield(L, table, "replacements"); + if(!lua_isnil(L, -1)) + { + if(!readCraftReplacements(L, -1, replacements)) + throw LuaError("Invalid replacements" + " (cooking output=\"" + output + "\")"); + } + + CraftDefinition *def = new CraftDefinitionCooking( + output, recipe, cooktime, replacements); + craftdef->registerCraft(def, getServer(L)); + } + /* + CraftDefinitionFuel + */ + else if(type == "fuel"){ + std::string recipe = getstringfield_default(L, table, "recipe", ""); + if (recipe.empty()) + throw LuaError("Crafting definition (fuel)" + " is missing a recipe"); + + float burntime = getfloatfield_default(L, table, "burntime", 1.0); + + CraftReplacements replacements; + lua_getfield(L, table, "replacements"); + if(!lua_isnil(L, -1)) + { + if(!readCraftReplacements(L, -1, replacements)) + throw LuaError("Invalid replacements" + " (fuel recipe=\"" + recipe + "\")"); + } + + CraftDefinition *def = new CraftDefinitionFuel( + recipe, burntime, replacements); + craftdef->registerCraft(def, getServer(L)); + } + else + { + throw LuaError("Unknown crafting definition type: \"" + type + "\""); + } + + lua_pop(L, 1); + return 0; /* number of results */ +} + +// clear_craft({[output=item], [recipe={{item00,item10},{item01,item11}}]) +int ModApiCraft::l_clear_craft(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + luaL_checktype(L, 1, LUA_TTABLE); + int table = 1; + + // Get the writable craft definition manager from the server + IWritableCraftDefManager *craftdef = + getServer(L)->getWritableCraftDefManager(); + + std::string output = getstringfield_default(L, table, "output", ""); + std::string type = getstringfield_default(L, table, "type", "shaped"); + CraftOutput c_output(output, 0); + if (!output.empty()) { + if (craftdef->clearCraftsByOutput(c_output, getServer(L))) { + lua_pushboolean(L, true); + return 1; + } + + warningstream << "No craft recipe known for output" << std::endl; + lua_pushboolean(L, false); + return 1; + } + std::vector<std::string> recipe; + int width = 0; + CraftMethod method = CRAFT_METHOD_NORMAL; + /* + CraftDefinitionShaped + */ + if (type == "shaped") { + lua_getfield(L, table, "recipe"); + if (lua_isnil(L, -1)) + throw LuaError("Either output or recipe has to be defined"); + if (!readCraftRecipeShaped(L, -1, width, recipe)) + throw LuaError("Invalid crafting recipe"); + } + /* + CraftDefinitionShapeless + */ + else if (type == "shapeless") { + lua_getfield(L, table, "recipe"); + if (lua_isnil(L, -1)) + throw LuaError("Either output or recipe has to be defined"); + if (!readCraftRecipeShapeless(L, -1, recipe)) + throw LuaError("Invalid crafting recipe"); + } + /* + CraftDefinitionCooking + */ + else if (type == "cooking") { + method = CRAFT_METHOD_COOKING; + std::string rec = getstringfield_default(L, table, "recipe", ""); + if (rec.empty()) + throw LuaError("Crafting definition (cooking)" + " is missing a recipe"); + recipe.push_back(rec); + } + /* + CraftDefinitionFuel + */ + else if (type == "fuel") { + method = CRAFT_METHOD_FUEL; + std::string rec = getstringfield_default(L, table, "recipe", ""); + if (rec.empty()) + throw LuaError("Crafting definition (fuel)" + " is missing a recipe"); + recipe.push_back(rec); + } else { + throw LuaError("Unknown crafting definition type: \"" + type + "\""); + } + + std::vector<ItemStack> items; + items.reserve(recipe.size()); + for (const auto &item : recipe) + items.emplace_back(item, 1, 0, getServer(L)->idef()); + CraftInput input(method, width, items); + + if (!craftdef->clearCraftsByInput(input, getServer(L))) { + warningstream << "No craft recipe matches input" << std::endl; + lua_pushboolean(L, false); + return 1; + } + + lua_pushboolean(L, true); + return 1; +} + +// get_craft_result(input) +int ModApiCraft::l_get_craft_result(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + IGameDef *gdef = getGameDef(L); + + const int input_i = 1; + std::string method_s = getstringfield_default(L, input_i, "method", "normal"); + enum CraftMethod method = (CraftMethod)getenumfield(L, input_i, "method", + es_CraftMethod, CRAFT_METHOD_NORMAL); + int width = 1; + lua_getfield(L, input_i, "width"); + if(lua_isnumber(L, -1)) + width = luaL_checkinteger(L, -1); + lua_pop(L, 1); + lua_getfield(L, input_i, "items"); + std::vector<ItemStack> items = read_items(L, -1, gdef); + lua_pop(L, 1); // items + + ICraftDefManager *cdef = gdef->cdef(); + CraftInput input(method, width, items); + CraftOutput output; + std::vector<ItemStack> output_replacements; + bool got = cdef->getCraftResult(input, output, output_replacements, true, gdef); + lua_newtable(L); // output table + if (got) { + ItemStack item; + item.deSerialize(output.item, gdef->idef()); + LuaItemStack::create(L, item); + lua_setfield(L, -2, "item"); + setintfield(L, -1, "time", output.time); + push_items(L, output_replacements); + lua_setfield(L, -2, "replacements"); + } else { + LuaItemStack::create(L, ItemStack()); + lua_setfield(L, -2, "item"); + setintfield(L, -1, "time", 0); + lua_newtable(L); + lua_setfield(L, -2, "replacements"); + } + lua_newtable(L); // decremented input table + lua_pushstring(L, method_s.c_str()); + lua_setfield(L, -2, "method"); + lua_pushinteger(L, width); + lua_setfield(L, -2, "width"); + push_items(L, input.items); + lua_setfield(L, -2, "items"); + return 2; +} + + +static void push_craft_recipe(lua_State *L, IGameDef *gdef, + const CraftDefinition *recipe, + const CraftOutput &tmpout) +{ + CraftInput input = recipe->getInput(tmpout, gdef); + CraftOutput output = recipe->getOutput(input, gdef); + + lua_newtable(L); // items + std::vector<ItemStack>::const_iterator iter = input.items.begin(); + for (u16 j = 1; iter != input.items.end(); ++iter, j++) { + if (iter->empty()) + continue; + lua_pushstring(L, iter->name.c_str()); + lua_rawseti(L, -2, j); + } + lua_setfield(L, -2, "items"); + setintfield(L, -1, "width", input.width); + + std::string method_s; + switch (input.method) { + case CRAFT_METHOD_NORMAL: + method_s = "normal"; + break; + case CRAFT_METHOD_COOKING: + method_s = "cooking"; + break; + case CRAFT_METHOD_FUEL: + method_s = "fuel"; + break; + default: + method_s = "unknown"; + } + lua_pushstring(L, method_s.c_str()); + lua_setfield(L, -2, "method"); + + // Deprecated, only for compatibility's sake + lua_pushstring(L, method_s.c_str()); + lua_setfield(L, -2, "type"); + + lua_pushstring(L, output.item.c_str()); + lua_setfield(L, -2, "output"); +} + +static void push_craft_recipes(lua_State *L, IGameDef *gdef, + const std::vector<CraftDefinition*> &recipes, + const CraftOutput &output) +{ + if (recipes.empty()) { + lua_pushnil(L); + return; + } + + lua_createtable(L, recipes.size(), 0); + + std::vector<CraftDefinition*>::const_iterator it = recipes.begin(); + for (unsigned i = 0; it != recipes.end(); ++it) { + lua_newtable(L); + push_craft_recipe(L, gdef, *it, output); + lua_rawseti(L, -2, ++i); + } +} + + +// get_craft_recipe(result item) +int ModApiCraft::l_get_craft_recipe(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + std::string item = luaL_checkstring(L, 1); + IGameDef *gdef = getGameDef(L); + CraftOutput output(item, 0); + auto recipes = gdef->cdef()->getCraftRecipes(output, gdef, 1); + + lua_createtable(L, 1, 0); + + if (recipes.empty()) { + lua_pushnil(L); + lua_setfield(L, -2, "items"); + setintfield(L, -1, "width", 0); + return 1; + } + push_craft_recipe(L, gdef, recipes[0], output); + return 1; +} + +// get_all_craft_recipes(result item) +int ModApiCraft::l_get_all_craft_recipes(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + std::string item = luaL_checkstring(L, 1); + IGameDef *gdef = getGameDef(L); + CraftOutput output(item, 0); + auto recipes = gdef->cdef()->getCraftRecipes(output, gdef); + + push_craft_recipes(L, gdef, recipes, output); + return 1; +} + +void ModApiCraft::Initialize(lua_State *L, int top) +{ + API_FCT(get_all_craft_recipes); + API_FCT(get_craft_recipe); + API_FCT(get_craft_result); + API_FCT(register_craft); + API_FCT(clear_craft); +} + +void ModApiCraft::InitializeAsync(lua_State *L, int top) +{ + // all read-only functions + API_FCT(get_all_craft_recipes); + API_FCT(get_craft_recipe); + API_FCT(get_craft_result); +} diff --git a/src/script/lua_api/l_craft.h b/src/script/lua_api/l_craft.h new file mode 100644 index 0000000..5234af5 --- /dev/null +++ b/src/script/lua_api/l_craft.h @@ -0,0 +1,49 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <vector> + +#include "lua_api/l_base.h" + +struct CraftReplacements; + +class ModApiCraft : public ModApiBase { +private: + static int l_register_craft(lua_State *L); + static int l_get_craft_recipe(lua_State *L); + static int l_get_all_craft_recipes(lua_State *L); + static int l_get_craft_result(lua_State *L); + static int l_clear_craft(lua_State *L); + + static bool readCraftReplacements(lua_State *L, int index, + CraftReplacements &replacements); + static bool readCraftRecipeShapeless(lua_State *L, int index, + std::vector<std::string> &recipe); + static bool readCraftRecipeShaped(lua_State *L, int index, + int &width, std::vector<std::string> &recipe); + + static struct EnumString es_CraftMethod[]; + +public: + static void Initialize(lua_State *L, int top); + static void InitializeAsync(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp new file mode 100644 index 0000000..b26c89e --- /dev/null +++ b/src/script/lua_api/l_env.cpp @@ -0,0 +1,1512 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <algorithm> +#include "lua_api/l_env.h" +#include "lua_api/l_internal.h" +#include "lua_api/l_nodemeta.h" +#include "lua_api/l_nodetimer.h" +#include "lua_api/l_noise.h" +#include "lua_api/l_vmanip.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "scripting_server.h" +#include "environment.h" +#include "mapblock.h" +#include "server.h" +#include "nodedef.h" +#include "daynightratio.h" +#include "util/pointedthing.h" +#include "mapgen/treegen.h" +#include "emerge.h" +#include "pathfinder.h" +#include "face_position_cache.h" +#include "remoteplayer.h" +#include "server/luaentity_sao.h" +#include "server/player_sao.h" +#include "util/string.h" +#include "translation.h" +#ifndef SERVER +#include "client/client.h" +#endif + +const EnumString ModApiEnvMod::es_ClearObjectsMode[] = +{ + {CLEAR_OBJECTS_MODE_FULL, "full"}, + {CLEAR_OBJECTS_MODE_QUICK, "quick"}, + {0, NULL}, +}; + +const EnumString ModApiEnvMod::es_BlockStatusType[] = +{ + {ServerEnvironment::BS_UNKNOWN, "unknown"}, + {ServerEnvironment::BS_EMERGING, "emerging"}, + {ServerEnvironment::BS_LOADED, "loaded"}, + {ServerEnvironment::BS_ACTIVE, "active"}, + {0, NULL}, +}; + +/////////////////////////////////////////////////////////////////////////////// + + +void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n, + u32 active_object_count, u32 active_object_count_wider) +{ + ServerScripting *scriptIface = env->getScriptIface(); + scriptIface->realityCheck(); + + lua_State *L = scriptIface->getStack(); + sanity_check(lua_checkstack(L, 20)); + StackUnroller stack_unroller(L); + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get registered_abms + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_abms"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_remove(L, -2); // Remove core + + // Get registered_abms[m_id] + lua_pushinteger(L, m_id); + lua_gettable(L, -2); + if(lua_isnil(L, -1)) + FATAL_ERROR(""); + lua_remove(L, -2); // Remove registered_abms + + scriptIface->setOriginFromTable(-1); + + // Call action + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, "action"); + luaL_checktype(L, -1, LUA_TFUNCTION); + lua_remove(L, -2); // Remove registered_abms[m_id] + push_v3s16(L, p); + pushnode(L, n, env->getGameDef()->ndef()); + lua_pushnumber(L, active_object_count); + lua_pushnumber(L, active_object_count_wider); + + int result = lua_pcall(L, 4, 0, error_handler); + if (result) + scriptIface->scriptError(result, "LuaABM::trigger"); + + lua_pop(L, 1); // Pop error handler +} + +void LuaLBM::trigger(ServerEnvironment *env, v3s16 p, MapNode n) +{ + ServerScripting *scriptIface = env->getScriptIface(); + scriptIface->realityCheck(); + + lua_State *L = scriptIface->getStack(); + sanity_check(lua_checkstack(L, 20)); + StackUnroller stack_unroller(L); + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get registered_lbms + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_lbms"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_remove(L, -2); // Remove core + + // Get registered_lbms[m_id] + lua_pushinteger(L, m_id); + lua_gettable(L, -2); + FATAL_ERROR_IF(lua_isnil(L, -1), "Entry with given id not found in registered_lbms table"); + lua_remove(L, -2); // Remove registered_lbms + + scriptIface->setOriginFromTable(-1); + + // Call action + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, "action"); + luaL_checktype(L, -1, LUA_TFUNCTION); + lua_remove(L, -2); // Remove registered_lbms[m_id] + push_v3s16(L, p); + pushnode(L, n, env->getGameDef()->ndef()); + + int result = lua_pcall(L, 2, 0, error_handler); + if (result) + scriptIface->scriptError(result, "LuaLBM::trigger"); + + lua_pop(L, 1); // Pop error handler +} + +int LuaRaycast::l_next(lua_State *L) +{ + GET_PLAIN_ENV_PTR; + + bool csm = false; +#ifndef SERVER + csm = getClient(L) != nullptr; +#endif + + LuaRaycast *o = checkobject(L, 1); + PointedThing pointed; + env->continueRaycast(&o->state, &pointed); + if (pointed.type == POINTEDTHING_NOTHING) + lua_pushnil(L); + else + push_pointed_thing(L, pointed, csm, true); + + return 1; +} + +int LuaRaycast::create_object(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + bool objects = true; + bool liquids = false; + + v3f pos1 = checkFloatPos(L, 1); + v3f pos2 = checkFloatPos(L, 2); + if (lua_isboolean(L, 3)) { + objects = readParam<bool>(L, 3); + } + if (lua_isboolean(L, 4)) { + liquids = readParam<bool>(L, 4); + } + + LuaRaycast *o = new LuaRaycast(core::line3d<f32>(pos1, pos2), + objects, liquids); + + *(void **) (lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + +LuaRaycast *LuaRaycast::checkobject(lua_State *L, int narg) +{ + NO_MAP_LOCK_REQUIRED; + + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + return *(LuaRaycast **) ud; +} + +int LuaRaycast::gc_object(lua_State *L) +{ + LuaRaycast *o = *(LuaRaycast **) (lua_touserdata(L, 1)); + delete o; + return 0; +} + +void LuaRaycast::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pushliteral(L, "__call"); + lua_pushcfunction(L, l_next); + lua_settable(L, metatable); + + lua_pop(L, 1); + + luaL_register(L, nullptr, methods); + lua_pop(L, 1); + + lua_register(L, className, create_object); +} + +const char LuaRaycast::className[] = "Raycast"; +const luaL_Reg LuaRaycast::methods[] = +{ + luamethod(LuaRaycast, next), + { 0, 0 } +}; + +void LuaEmergeAreaCallback(v3s16 blockpos, EmergeAction action, void *param) +{ + ScriptCallbackState *state = (ScriptCallbackState *)param; + assert(state != NULL); + assert(state->script != NULL); + assert(state->refcount > 0); + + // state must be protected by envlock + Server *server = state->script->getServer(); + MutexAutoLock envlock(server->m_env_mutex); + + state->refcount--; + + state->script->on_emerge_area_completion(blockpos, action, state); + + if (state->refcount == 0) + delete state; +} + +// Exported functions + +// set_node(pos, node) +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_set_node(lua_State *L) +{ + GET_ENV_PTR; + + const NodeDefManager *ndef = env->getGameDef()->ndef(); + // parameters + v3s16 pos = read_v3s16(L, 1); + MapNode n = readnode(L, 2, ndef); + // Do it + bool succeeded = env->setNode(pos, n); + lua_pushboolean(L, succeeded); + return 1; +} + +// bulk_set_node([pos1, pos2, ...], node) +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_bulk_set_node(lua_State *L) +{ + GET_ENV_PTR; + + const NodeDefManager *ndef = env->getGameDef()->ndef(); + // parameters + if (!lua_istable(L, 1)) { + return 0; + } + + s32 len = lua_objlen(L, 1); + if (len == 0) { + lua_pushboolean(L, true); + return 1; + } + + MapNode n = readnode(L, 2, ndef); + + // Do it + bool succeeded = true; + for (s32 i = 1; i <= len; i++) { + lua_rawgeti(L, 1, i); + if (!env->setNode(read_v3s16(L, -1), n)) + succeeded = false; + lua_pop(L, 1); + } + + lua_pushboolean(L, succeeded); + return 1; +} + +int ModApiEnvMod::l_add_node(lua_State *L) +{ + return l_set_node(L); +} + +// remove_node(pos) +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_remove_node(lua_State *L) +{ + GET_ENV_PTR; + + // parameters + v3s16 pos = read_v3s16(L, 1); + // Do it + bool succeeded = env->removeNode(pos); + lua_pushboolean(L, succeeded); + return 1; +} + +// swap_node(pos, node) +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_swap_node(lua_State *L) +{ + GET_ENV_PTR; + + const NodeDefManager *ndef = env->getGameDef()->ndef(); + // parameters + v3s16 pos = read_v3s16(L, 1); + MapNode n = readnode(L, 2, ndef); + // Do it + bool succeeded = env->swapNode(pos, n); + lua_pushboolean(L, succeeded); + return 1; +} + +// get_node(pos) +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_get_node(lua_State *L) +{ + GET_ENV_PTR; + + // pos + v3s16 pos = read_v3s16(L, 1); + // Do it + MapNode n = env->getMap().getNode(pos); + // Return node + pushnode(L, n, env->getGameDef()->ndef()); + return 1; +} + +// get_node_or_nil(pos) +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_get_node_or_nil(lua_State *L) +{ + GET_ENV_PTR; + + // pos + v3s16 pos = read_v3s16(L, 1); + // Do it + bool pos_ok; + MapNode n = env->getMap().getNode(pos, &pos_ok); + if (pos_ok) { + // Return node + pushnode(L, n, env->getGameDef()->ndef()); + } else { + lua_pushnil(L); + } + return 1; +} + +// get_node_light(pos, timeofday) +// pos = {x=num, y=num, z=num} +// timeofday: nil = current time, 0 = night, 0.5 = day +int ModApiEnvMod::l_get_node_light(lua_State *L) +{ + GET_PLAIN_ENV_PTR; + + // Do it + v3s16 pos = read_v3s16(L, 1); + u32 time_of_day = env->getTimeOfDay(); + if(lua_isnumber(L, 2)) + time_of_day = 24000.0 * lua_tonumber(L, 2); + time_of_day %= 24000; + u32 dnr = time_to_daynight_ratio(time_of_day, true); + + bool is_position_ok; + MapNode n = env->getMap().getNode(pos, &is_position_ok); + if (is_position_ok) { + const NodeDefManager *ndef = env->getGameDef()->ndef(); + lua_pushinteger(L, n.getLightBlend(dnr, ndef)); + } else { + lua_pushnil(L); + } + return 1; +} + + +// get_natural_light(pos, timeofday) +// pos = {x=num, y=num, z=num} +// timeofday: nil = current time, 0 = night, 0.5 = day +int ModApiEnvMod::l_get_natural_light(lua_State *L) +{ + GET_ENV_PTR; + + v3s16 pos = read_v3s16(L, 1); + + bool is_position_ok; + MapNode n = env->getMap().getNode(pos, &is_position_ok); + if (!is_position_ok) + return 0; + + // If the daylight is 0, nothing needs to be calculated + u8 daylight = n.param1 & 0x0f; + if (daylight == 0) { + lua_pushinteger(L, 0); + return 1; + } + + u32 time_of_day; + if (lua_isnumber(L, 2)) { + time_of_day = 24000.0 * lua_tonumber(L, 2); + time_of_day %= 24000; + } else { + time_of_day = env->getTimeOfDay(); + } + u32 dnr = time_to_daynight_ratio(time_of_day, true); + + // If it's the same as the artificial light, the sunlight needs to be + // searched for because the value may not emanate from the sun + if (daylight == n.param1 >> 4) + daylight = env->findSunlight(pos); + + lua_pushinteger(L, dnr * daylight / 1000); + return 1; +} + +// place_node(pos, node) +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_place_node(lua_State *L) +{ + GET_ENV_PTR; + + ScriptApiItem *scriptIfaceItem = getScriptApi<ScriptApiItem>(L); + Server *server = getServer(L); + const NodeDefManager *ndef = server->ndef(); + IItemDefManager *idef = server->idef(); + + v3s16 pos = read_v3s16(L, 1); + MapNode n = readnode(L, 2, ndef); + + // Don't attempt to load non-loaded area as of now + MapNode n_old = env->getMap().getNode(pos); + if(n_old.getContent() == CONTENT_IGNORE){ + lua_pushboolean(L, false); + return 1; + } + // Create item to place + Optional<ItemStack> item = ItemStack(ndef->get(n).name, 1, 0, idef); + // Make pointed position + PointedThing pointed; + pointed.type = POINTEDTHING_NODE; + pointed.node_abovesurface = pos; + pointed.node_undersurface = pos + v3s16(0,-1,0); + // Place it with a NULL placer (appears in Lua as nil) + bool success = scriptIfaceItem->item_OnPlace(item, nullptr, pointed); + lua_pushboolean(L, success); + return 1; +} + +// dig_node(pos) +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_dig_node(lua_State *L) +{ + GET_ENV_PTR; + + ScriptApiNode *scriptIfaceNode = getScriptApi<ScriptApiNode>(L); + + v3s16 pos = read_v3s16(L, 1); + + // Don't attempt to load non-loaded area as of now + MapNode n = env->getMap().getNode(pos); + if(n.getContent() == CONTENT_IGNORE){ + lua_pushboolean(L, false); + return 1; + } + // Dig it out with a NULL digger (appears in Lua as a + // non-functional ObjectRef) + bool success = scriptIfaceNode->node_on_dig(pos, n, NULL); + lua_pushboolean(L, success); + return 1; +} + +// punch_node(pos) +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_punch_node(lua_State *L) +{ + GET_ENV_PTR; + + ScriptApiNode *scriptIfaceNode = getScriptApi<ScriptApiNode>(L); + + v3s16 pos = read_v3s16(L, 1); + + // Don't attempt to load non-loaded area as of now + MapNode n = env->getMap().getNode(pos); + if(n.getContent() == CONTENT_IGNORE){ + lua_pushboolean(L, false); + return 1; + } + // Punch it with a NULL puncher (appears in Lua as a non-functional + // ObjectRef) + bool success = scriptIfaceNode->node_on_punch(pos, n, NULL, PointedThing()); + lua_pushboolean(L, success); + return 1; +} + +// get_node_max_level(pos) +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_get_node_max_level(lua_State *L) +{ + GET_PLAIN_ENV_PTR; + + v3s16 pos = read_v3s16(L, 1); + MapNode n = env->getMap().getNode(pos); + lua_pushnumber(L, n.getMaxLevel(env->getGameDef()->ndef())); + return 1; +} + +// get_node_level(pos) +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_get_node_level(lua_State *L) +{ + GET_PLAIN_ENV_PTR; + + v3s16 pos = read_v3s16(L, 1); + MapNode n = env->getMap().getNode(pos); + lua_pushnumber(L, n.getLevel(env->getGameDef()->ndef())); + return 1; +} + +// set_node_level(pos, level) +// pos = {x=num, y=num, z=num} +// level: 0..63 +int ModApiEnvMod::l_set_node_level(lua_State *L) +{ + GET_ENV_PTR; + + v3s16 pos = read_v3s16(L, 1); + u8 level = 1; + if(lua_isnumber(L, 2)) + level = lua_tonumber(L, 2); + MapNode n = env->getMap().getNode(pos); + lua_pushnumber(L, n.setLevel(env->getGameDef()->ndef(), level)); + env->setNode(pos, n); + return 1; +} + +// add_node_level(pos, level) +// pos = {x=num, y=num, z=num} +// level: -127..127 +int ModApiEnvMod::l_add_node_level(lua_State *L) +{ + GET_ENV_PTR; + + v3s16 pos = read_v3s16(L, 1); + s16 level = 1; + if(lua_isnumber(L, 2)) + level = lua_tonumber(L, 2); + MapNode n = env->getMap().getNode(pos); + lua_pushnumber(L, n.addLevel(env->getGameDef()->ndef(), level)); + env->setNode(pos, n); + return 1; +} + +// find_nodes_with_meta(pos1, pos2) +int ModApiEnvMod::l_find_nodes_with_meta(lua_State *L) +{ + GET_PLAIN_ENV_PTR; + + std::vector<v3s16> positions = env->getMap().findNodesWithMetadata( + check_v3s16(L, 1), check_v3s16(L, 2)); + + lua_createtable(L, positions.size(), 0); + for (size_t i = 0; i != positions.size(); i++) { + push_v3s16(L, positions[i]); + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +// get_meta(pos) +int ModApiEnvMod::l_get_meta(lua_State *L) +{ + GET_ENV_PTR; + + // Do it + v3s16 p = read_v3s16(L, 1); + NodeMetaRef::create(L, p, env); + return 1; +} + +// get_node_timer(pos) +int ModApiEnvMod::l_get_node_timer(lua_State *L) +{ + GET_ENV_PTR; + + // Do it + v3s16 p = read_v3s16(L, 1); + NodeTimerRef::create(L, p, &env->getServerMap()); + return 1; +} + +// add_entity(pos, entityname, [staticdata]) -> ObjectRef or nil +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_add_entity(lua_State *L) +{ + GET_ENV_PTR; + + v3f pos = checkFloatPos(L, 1); + const char *name = luaL_checkstring(L, 2); + std::string staticdata = readParam<std::string>(L, 3, ""); + + ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, staticdata); + int objectid = env->addActiveObject(obj); + // If failed to add, return nothing (reads as nil) + if(objectid == 0) + return 0; + + // If already deleted (can happen in on_activate), return nil + if (obj->isGone()) + return 0; + getScriptApiBase(L)->objectrefGetOrCreate(L, obj); + return 1; +} + +// add_item(pos, itemstack or itemstring or table) -> ObjectRef or nil +// pos = {x=num, y=num, z=num} +int ModApiEnvMod::l_add_item(lua_State *L) +{ + GET_ENV_PTR; + + // pos + //v3f pos = checkFloatPos(L, 1); + // item + ItemStack item = read_item(L, 2,getServer(L)->idef()); + if(item.empty() || !item.isKnown(getServer(L)->idef())) + return 0; + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Use spawn_item to spawn a __builtin:item + lua_getglobal(L, "core"); + lua_getfield(L, -1, "spawn_item"); + lua_remove(L, -2); // Remove core + if(lua_isnil(L, -1)) + return 0; + lua_pushvalue(L, 1); + lua_pushstring(L, item.getItemString().c_str()); + + PCALL_RESL(L, lua_pcall(L, 2, 1, error_handler)); + + lua_remove(L, error_handler); + return 1; +} + +// get_connected_players() +int ModApiEnvMod::l_get_connected_players(lua_State *L) +{ + ServerEnvironment *env = (ServerEnvironment *) getEnv(L); + if (!env) { + log_deprecated(L, "Calling get_connected_players() at mod load time" + " is deprecated"); + lua_createtable(L, 0, 0); + return 1; + } + + lua_createtable(L, env->getPlayerCount(), 0); + u32 i = 0; + for (RemotePlayer *player : env->getPlayers()) { + if (player->getPeerId() == PEER_ID_INEXISTENT) + continue; + PlayerSAO *sao = player->getPlayerSAO(); + if (sao && !sao->isGone()) { + getScriptApiBase(L)->objectrefGetOrCreate(L, sao); + lua_rawseti(L, -2, ++i); + } + } + return 1; +} + +// get_player_by_name(name) +int ModApiEnvMod::l_get_player_by_name(lua_State *L) +{ + GET_ENV_PTR; + + // Do it + const char *name = luaL_checkstring(L, 1); + RemotePlayer *player = env->getPlayer(name); + if (!player || player->getPeerId() == PEER_ID_INEXISTENT) + return 0; + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao || sao->isGone()) + return 0; + // Put player on stack + getScriptApiBase(L)->objectrefGetOrCreate(L, sao); + return 1; +} + +// get_objects_inside_radius(pos, radius) +int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L) +{ + GET_ENV_PTR; + ScriptApiBase *script = getScriptApiBase(L); + + // Do it + v3f pos = checkFloatPos(L, 1); + float radius = readParam<float>(L, 2) * BS; + std::vector<ServerActiveObject *> objs; + + auto include_obj_cb = [](ServerActiveObject *obj){ return !obj->isGone(); }; + env->getObjectsInsideRadius(objs, pos, radius, include_obj_cb); + + int i = 0; + lua_createtable(L, objs.size(), 0); + for (const auto obj : objs) { + // Insert object reference into table + script->objectrefGetOrCreate(L, obj); + lua_rawseti(L, -2, ++i); + } + return 1; +} + +// get_objects_in_area(pos, minp, maxp) +int ModApiEnvMod::l_get_objects_in_area(lua_State *L) +{ + GET_ENV_PTR; + ScriptApiBase *script = getScriptApiBase(L); + + v3f minp = read_v3f(L, 1) * BS; + v3f maxp = read_v3f(L, 2) * BS; + aabb3f box(minp, maxp); + box.repair(); + std::vector<ServerActiveObject *> objs; + + auto include_obj_cb = [](ServerActiveObject *obj){ return !obj->isGone(); }; + env->getObjectsInArea(objs, box, include_obj_cb); + + int i = 0; + lua_createtable(L, objs.size(), 0); + for (const auto obj : objs) { + // Insert object reference into table + script->objectrefGetOrCreate(L, obj); + lua_rawseti(L, -2, ++i); + } + return 1; +} + +// set_timeofday(val) +// val = 0...1 +int ModApiEnvMod::l_set_timeofday(lua_State *L) +{ + GET_ENV_PTR; + + // Do it + float timeofday_f = readParam<float>(L, 1); + luaL_argcheck(L, timeofday_f >= 0.0f && timeofday_f <= 1.0f, 1, + "value must be between 0 and 1"); + int timeofday_mh = (int)(timeofday_f * 24000.0f); + // This should be set directly in the environment but currently + // such changes aren't immediately sent to the clients, so call + // the server instead. + //env->setTimeOfDay(timeofday_mh); + getServer(L)->setTimeOfDay(timeofday_mh); + return 0; +} + +// get_timeofday() -> 0...1 +int ModApiEnvMod::l_get_timeofday(lua_State *L) +{ + GET_PLAIN_ENV_PTR; + + // Do it + int timeofday_mh = env->getTimeOfDay(); + float timeofday_f = (float)timeofday_mh / 24000.0f; + lua_pushnumber(L, timeofday_f); + return 1; +} + +// get_day_count() -> int +int ModApiEnvMod::l_get_day_count(lua_State *L) +{ + GET_PLAIN_ENV_PTR; + + lua_pushnumber(L, env->getDayCount()); + return 1; +} + +// get_gametime() +int ModApiEnvMod::l_get_gametime(lua_State *L) +{ + GET_ENV_PTR; + + int game_time = env->getGameTime(); + lua_pushnumber(L, game_time); + return 1; +} + +void ModApiEnvMod::collectNodeIds(lua_State *L, int idx, const NodeDefManager *ndef, + std::vector<content_t> &filter) +{ + if (lua_istable(L, idx)) { + lua_pushnil(L); + while (lua_next(L, idx) != 0) { + // key at index -2 and value at index -1 + luaL_checktype(L, -1, LUA_TSTRING); + ndef->getIds(readParam<std::string>(L, -1), filter); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } else if (lua_isstring(L, idx)) { + ndef->getIds(readParam<std::string>(L, 3), filter); + } +} + +// find_node_near(pos, radius, nodenames, [search_center]) -> pos or nil +// nodenames: eg. {"ignore", "group:tree"} or "default:dirt" +int ModApiEnvMod::l_find_node_near(lua_State *L) +{ + GET_PLAIN_ENV_PTR; + + const NodeDefManager *ndef = env->getGameDef()->ndef(); + Map &map = env->getMap(); + + v3s16 pos = read_v3s16(L, 1); + int radius = luaL_checkinteger(L, 2); + std::vector<content_t> filter; + collectNodeIds(L, 3, ndef, filter); + + int start_radius = (lua_isboolean(L, 4) && readParam<bool>(L, 4)) ? 0 : 1; + +#ifndef SERVER + // Client API limitations + if (Client *client = getClient(L)) + radius = client->CSMClampRadius(pos, radius); +#endif + + for (int d = start_radius; d <= radius; d++) { + const std::vector<v3s16> &list = FacePositionCache::getFacePositions(d); + for (const v3s16 &i : list) { + v3s16 p = pos + i; + content_t c = map.getNode(p).getContent(); + if (CONTAINS(filter, c)) { + push_v3s16(L, p); + return 1; + } + } + } + return 0; +} + +static void checkArea(v3s16 &minp, v3s16 &maxp) +{ + auto volume = VoxelArea(minp, maxp).getVolume(); + // Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000 + if (volume > 4096000) { + throw LuaError("Area volume exceeds allowed value of 4096000"); + } + + // Clamp to map range to avoid problems +#define CLAMP(arg) core::clamp(arg, (s16)-MAX_MAP_GENERATION_LIMIT, (s16)MAX_MAP_GENERATION_LIMIT) + minp = v3s16(CLAMP(minp.X), CLAMP(minp.Y), CLAMP(minp.Z)); + maxp = v3s16(CLAMP(maxp.X), CLAMP(maxp.Y), CLAMP(maxp.Z)); +#undef CLAMP +} + +// find_nodes_in_area(minp, maxp, nodenames, [grouped]) +int ModApiEnvMod::l_find_nodes_in_area(lua_State *L) +{ + GET_PLAIN_ENV_PTR; + + v3s16 minp = read_v3s16(L, 1); + v3s16 maxp = read_v3s16(L, 2); + sortBoxVerticies(minp, maxp); + + const NodeDefManager *ndef = env->getGameDef()->ndef(); + Map &map = env->getMap(); + +#ifndef SERVER + if (Client *client = getClient(L)) { + minp = client->CSMClampPos(minp); + maxp = client->CSMClampPos(maxp); + } +#endif + + checkArea(minp, maxp); + + std::vector<content_t> filter; + collectNodeIds(L, 3, ndef, filter); + + bool grouped = lua_isboolean(L, 4) && readParam<bool>(L, 4); + + if (grouped) { + // create the table we will be returning + lua_createtable(L, 0, filter.size()); + int base = lua_gettop(L); + + // create one table for each filter + std::vector<u32> idx; + idx.resize(filter.size()); + for (u32 i = 0; i < filter.size(); i++) + lua_newtable(L); + + v3s16 p; + for (p.X = minp.X; p.X <= maxp.X; p.X++) + for (p.Y = minp.Y; p.Y <= maxp.Y; p.Y++) + for (p.Z = minp.Z; p.Z <= maxp.Z; p.Z++) { + content_t c = map.getNode(p).getContent(); + + auto it = std::find(filter.begin(), filter.end(), c); + if (it != filter.end()) { + // Calculate index of the table and append the position + u32 filt_index = it - filter.begin(); + push_v3s16(L, p); + lua_rawseti(L, base + 1 + filt_index, ++idx[filt_index]); + } + } + + // last filter table is at top of stack + u32 i = filter.size() - 1; + do { + if (idx[i] == 0) { + // No such node found -> drop the empty table + lua_pop(L, 1); + } else { + // This node was found -> put table into the return table + lua_setfield(L, base, ndef->get(filter[i]).name.c_str()); + } + } while (i-- != 0); + + assert(lua_gettop(L) == base); + return 1; + } else { + std::vector<u32> individual_count; + individual_count.resize(filter.size()); + + lua_newtable(L); + u32 i = 0; + v3s16 p; + for (p.X = minp.X; p.X <= maxp.X; p.X++) + for (p.Y = minp.Y; p.Y <= maxp.Y; p.Y++) + for (p.Z = minp.Z; p.Z <= maxp.Z; p.Z++) { + content_t c = env->getMap().getNode(p).getContent(); + + auto it = std::find(filter.begin(), filter.end(), c); + if (it != filter.end()) { + push_v3s16(L, p); + lua_rawseti(L, -2, ++i); + + u32 filt_index = it - filter.begin(); + individual_count[filt_index]++; + } + } + + lua_createtable(L, 0, filter.size()); + for (u32 i = 0; i < filter.size(); i++) { + lua_pushinteger(L, individual_count[i]); + lua_setfield(L, -2, ndef->get(filter[i]).name.c_str()); + } + return 2; + } +} + +// find_nodes_in_area_under_air(minp, maxp, nodenames) -> list of positions +// nodenames: e.g. {"ignore", "group:tree"} or "default:dirt" +int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L) +{ + /* Note: A similar but generalized (and therefore slower) version of this + * function could be created -- e.g. find_nodes_in_area_under -- which + * would accept a node name (or ID?) or list of names that the "above node" + * should be. + * TODO + */ + + GET_PLAIN_ENV_PTR; + + v3s16 minp = read_v3s16(L, 1); + v3s16 maxp = read_v3s16(L, 2); + sortBoxVerticies(minp, maxp); + + const NodeDefManager *ndef = env->getGameDef()->ndef(); + Map &map = env->getMap(); + +#ifndef SERVER + if (Client *client = getClient(L)) { + minp = client->CSMClampPos(minp); + maxp = client->CSMClampPos(maxp); + } +#endif + + checkArea(minp, maxp); + + std::vector<content_t> filter; + collectNodeIds(L, 3, ndef, filter); + + lua_newtable(L); + u32 i = 0; + v3s16 p; + for (p.X = minp.X; p.X <= maxp.X; p.X++) + for (p.Z = minp.Z; p.Z <= maxp.Z; p.Z++) { + p.Y = minp.Y; + content_t c = map.getNode(p).getContent(); + for (; p.Y <= maxp.Y; p.Y++) { + v3s16 psurf(p.X, p.Y + 1, p.Z); + content_t csurf = map.getNode(psurf).getContent(); + if (c != CONTENT_AIR && csurf == CONTENT_AIR && + CONTAINS(filter, c)) { + push_v3s16(L, p); + lua_rawseti(L, -2, ++i); + } + c = csurf; + } + } + return 1; +} + +// get_perlin(seeddiff, octaves, persistence, scale) +// returns world-specific PerlinNoise +int ModApiEnvMod::l_get_perlin(lua_State *L) +{ + GET_ENV_PTR_NO_MAP_LOCK; + + NoiseParams params; + + if (lua_istable(L, 1)) { + read_noiseparams(L, 1, ¶ms); + } else { + params.seed = luaL_checkint(L, 1); + params.octaves = luaL_checkint(L, 2); + params.persist = readParam<float>(L, 3); + params.spread = v3f(1, 1, 1) * readParam<float>(L, 4); + } + + params.seed += (int)env->getServerMap().getSeed(); + + LuaPerlinNoise *n = new LuaPerlinNoise(¶ms); + *(void **)(lua_newuserdata(L, sizeof(void *))) = n; + luaL_getmetatable(L, "PerlinNoise"); + lua_setmetatable(L, -2); + return 1; +} + +// get_perlin_map(noiseparams, size) +// returns world-specific PerlinNoiseMap +int ModApiEnvMod::l_get_perlin_map(lua_State *L) +{ + GET_ENV_PTR_NO_MAP_LOCK; + + NoiseParams np; + if (!read_noiseparams(L, 1, &np)) + return 0; + v3s16 size = read_v3s16(L, 2); + + s32 seed = (s32)(env->getServerMap().getSeed()); + LuaPerlinNoiseMap *n = new LuaPerlinNoiseMap(&np, seed, size); + *(void **)(lua_newuserdata(L, sizeof(void *))) = n; + luaL_getmetatable(L, "PerlinNoiseMap"); + lua_setmetatable(L, -2); + return 1; +} + +// get_voxel_manip() +// returns voxel manipulator +int ModApiEnvMod::l_get_voxel_manip(lua_State *L) +{ + GET_ENV_PTR; + + Map *map = &(env->getMap()); + LuaVoxelManip *o = (lua_istable(L, 1) && lua_istable(L, 2)) ? + new LuaVoxelManip(map, read_v3s16(L, 1), read_v3s16(L, 2)) : + new LuaVoxelManip(map); + + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, "VoxelManip"); + lua_setmetatable(L, -2); + return 1; +} + +// clear_objects([options]) +// clear all objects in the environment +// where options = {mode = "full" or "quick"} +int ModApiEnvMod::l_clear_objects(lua_State *L) +{ + GET_ENV_PTR; + + ClearObjectsMode mode = CLEAR_OBJECTS_MODE_QUICK; + if (lua_istable(L, 1)) { + mode = (ClearObjectsMode)getenumfield(L, 1, "mode", + ModApiEnvMod::es_ClearObjectsMode, mode); + } + + env->clearObjects(mode); + return 0; +} + +// line_of_sight(pos1, pos2) -> true/false, pos +int ModApiEnvMod::l_line_of_sight(lua_State *L) +{ + GET_PLAIN_ENV_PTR; + + // read position 1 from lua + v3f pos1 = checkFloatPos(L, 1); + // read position 2 from lua + v3f pos2 = checkFloatPos(L, 2); + + v3s16 p; + + bool success = env->line_of_sight(pos1, pos2, &p); + lua_pushboolean(L, success); + if (!success) { + push_v3s16(L, p); + return 2; + } + return 1; +} + +// fix_light(p1, p2) +int ModApiEnvMod::l_fix_light(lua_State *L) +{ + GET_ENV_PTR; + + v3s16 blockpos1 = getContainerPos(read_v3s16(L, 1), MAP_BLOCKSIZE); + v3s16 blockpos2 = getContainerPos(read_v3s16(L, 2), MAP_BLOCKSIZE); + ServerMap &map = env->getServerMap(); + std::map<v3s16, MapBlock *> modified_blocks; + bool success = true; + v3s16 blockpos; + for (blockpos.X = blockpos1.X; blockpos.X <= blockpos2.X; blockpos.X++) + for (blockpos.Y = blockpos1.Y; blockpos.Y <= blockpos2.Y; blockpos.Y++) + for (blockpos.Z = blockpos1.Z; blockpos.Z <= blockpos2.Z; blockpos.Z++) { + success = success & map.repairBlockLight(blockpos, &modified_blocks); + } + if (!modified_blocks.empty()) { + MapEditEvent event; + event.type = MEET_OTHER; + for (auto &modified_block : modified_blocks) + event.modified_blocks.insert(modified_block.first); + + map.dispatchEvent(event); + } + lua_pushboolean(L, success); + + return 1; +} + +int ModApiEnvMod::l_raycast(lua_State *L) +{ + return LuaRaycast::create_object(L); +} + +// load_area(p1, [p2]) +// load mapblocks in area p1..p2, but do not generate map +int ModApiEnvMod::l_load_area(lua_State *L) +{ + GET_ENV_PTR; + MAP_LOCK_REQUIRED; + + Map *map = &(env->getMap()); + v3s16 bp1 = getNodeBlockPos(check_v3s16(L, 1)); + if (!lua_istable(L, 2)) { + map->emergeBlock(bp1); + } else { + v3s16 bp2 = getNodeBlockPos(check_v3s16(L, 2)); + sortBoxVerticies(bp1, bp2); + for (s16 z = bp1.Z; z <= bp2.Z; z++) + for (s16 y = bp1.Y; y <= bp2.Y; y++) + for (s16 x = bp1.X; x <= bp2.X; x++) { + map->emergeBlock(v3s16(x, y, z)); + } + } + + return 0; +} + +// emerge_area(p1, p2, [callback, context]) +// emerge mapblocks in area p1..p2, calls callback with context upon completion +int ModApiEnvMod::l_emerge_area(lua_State *L) +{ + GET_ENV_PTR; + + EmergeCompletionCallback callback = NULL; + ScriptCallbackState *state = NULL; + + EmergeManager *emerge = getServer(L)->getEmergeManager(); + + v3s16 bpmin = getNodeBlockPos(read_v3s16(L, 1)); + v3s16 bpmax = getNodeBlockPos(read_v3s16(L, 2)); + sortBoxVerticies(bpmin, bpmax); + + size_t num_blocks = VoxelArea(bpmin, bpmax).getVolume(); + if (num_blocks == 0) + return 0; + + if (lua_isfunction(L, 3)) { + callback = LuaEmergeAreaCallback; + + lua_pushvalue(L, 3); + int callback_ref = luaL_ref(L, LUA_REGISTRYINDEX); + + lua_pushvalue(L, 4); + int args_ref = luaL_ref(L, LUA_REGISTRYINDEX); + + state = new ScriptCallbackState; + state->script = getServer(L)->getScriptIface(); + state->callback_ref = callback_ref; + state->args_ref = args_ref; + state->refcount = num_blocks; + state->origin = getScriptApiBase(L)->getOrigin(); + } + + for (s16 z = bpmin.Z; z <= bpmax.Z; z++) + for (s16 y = bpmin.Y; y <= bpmax.Y; y++) + for (s16 x = bpmin.X; x <= bpmax.X; x++) { + emerge->enqueueBlockEmergeEx(v3s16(x, y, z), PEER_ID_INEXISTENT, + BLOCK_EMERGE_ALLOW_GEN | BLOCK_EMERGE_FORCE_QUEUE, callback, state); + } + + return 0; +} + +// delete_area(p1, p2) +// delete mapblocks in area p1..p2 +int ModApiEnvMod::l_delete_area(lua_State *L) +{ + GET_ENV_PTR; + + v3s16 bpmin = getNodeBlockPos(read_v3s16(L, 1)); + v3s16 bpmax = getNodeBlockPos(read_v3s16(L, 2)); + sortBoxVerticies(bpmin, bpmax); + + ServerMap &map = env->getServerMap(); + + MapEditEvent event; + event.type = MEET_OTHER; + + bool success = true; + for (s16 z = bpmin.Z; z <= bpmax.Z; z++) + for (s16 y = bpmin.Y; y <= bpmax.Y; y++) + for (s16 x = bpmin.X; x <= bpmax.X; x++) { + v3s16 bp(x, y, z); + if (map.deleteBlock(bp)) { + env->setStaticForActiveObjectsInBlock(bp, false); + event.modified_blocks.insert(bp); + } else { + success = false; + } + } + + map.dispatchEvent(event); + lua_pushboolean(L, success); + return 1; +} + +// find_path(pos1, pos2, searchdistance, +// max_jump, max_drop, algorithm) -> table containing path +int ModApiEnvMod::l_find_path(lua_State *L) +{ + GET_ENV_PTR; + + v3s16 pos1 = read_v3s16(L, 1); + v3s16 pos2 = read_v3s16(L, 2); + unsigned int searchdistance = luaL_checkint(L, 3); + unsigned int max_jump = luaL_checkint(L, 4); + unsigned int max_drop = luaL_checkint(L, 5); + PathAlgorithm algo = PA_PLAIN_NP; + if (!lua_isnoneornil(L, 6)) { + std::string algorithm = luaL_checkstring(L,6); + + if (algorithm == "A*") + algo = PA_PLAIN; + + if (algorithm == "Dijkstra") + algo = PA_DIJKSTRA; + } + + std::vector<v3s16> path = get_path(&env->getServerMap(), env->getGameDef()->ndef(), pos1, pos2, + searchdistance, max_jump, max_drop, algo); + + if (!path.empty()) { + lua_createtable(L, path.size(), 0); + int top = lua_gettop(L); + unsigned int index = 1; + for (const v3s16 &i : path) { + lua_pushnumber(L,index); + push_v3s16(L, i); + lua_settable(L, top); + index++; + } + return 1; + } + + return 0; +} + +// spawn_tree(pos, treedef) +int ModApiEnvMod::l_spawn_tree(lua_State *L) +{ + GET_ENV_PTR; + + v3s16 p0 = read_v3s16(L, 1); + + treegen::TreeDef tree_def; + std::string trunk,leaves,fruit; + const NodeDefManager *ndef = env->getGameDef()->ndef(); + + if(lua_istable(L, 2)) + { + getstringfield(L, 2, "axiom", tree_def.initial_axiom); + getstringfield(L, 2, "rules_a", tree_def.rules_a); + getstringfield(L, 2, "rules_b", tree_def.rules_b); + getstringfield(L, 2, "rules_c", tree_def.rules_c); + getstringfield(L, 2, "rules_d", tree_def.rules_d); + getstringfield(L, 2, "trunk", trunk); + tree_def.trunknode=ndef->getId(trunk); + getstringfield(L, 2, "leaves", leaves); + tree_def.leavesnode=ndef->getId(leaves); + tree_def.leaves2_chance=0; + getstringfield(L, 2, "leaves2", leaves); + if (!leaves.empty()) { + tree_def.leaves2node=ndef->getId(leaves); + getintfield(L, 2, "leaves2_chance", tree_def.leaves2_chance); + } + getintfield(L, 2, "angle", tree_def.angle); + getintfield(L, 2, "iterations", tree_def.iterations); + if (!getintfield(L, 2, "random_level", tree_def.iterations_random_level)) + tree_def.iterations_random_level = 0; + getstringfield(L, 2, "trunk_type", tree_def.trunk_type); + getboolfield(L, 2, "thin_branches", tree_def.thin_branches); + tree_def.fruit_chance=0; + getstringfield(L, 2, "fruit", fruit); + if (!fruit.empty()) { + tree_def.fruitnode=ndef->getId(fruit); + getintfield(L, 2, "fruit_chance",tree_def.fruit_chance); + } + tree_def.explicit_seed = getintfield(L, 2, "seed", tree_def.seed); + } + else + return 0; + + ServerMap *map = &env->getServerMap(); + treegen::error e; + if ((e = treegen::spawn_ltree (map, p0, ndef, tree_def)) != treegen::SUCCESS) { + if (e == treegen::UNBALANCED_BRACKETS) { + luaL_error(L, "spawn_tree(): closing ']' has no matching opening bracket"); + } else { + luaL_error(L, "spawn_tree(): unknown error"); + } + } + + return 1; +} + +// transforming_liquid_add(pos) +int ModApiEnvMod::l_transforming_liquid_add(lua_State *L) +{ + GET_ENV_PTR; + + v3s16 p0 = read_v3s16(L, 1); + env->getServerMap().transforming_liquid_add(p0); + return 1; +} + +// forceload_block(blockpos) +// blockpos = {x=num, y=num, z=num} +int ModApiEnvMod::l_forceload_block(lua_State *L) +{ + GET_ENV_PTR; + + v3s16 blockpos = read_v3s16(L, 1); + env->getForceloadedBlocks()->insert(blockpos); + return 0; +} + +// compare_block_status(nodepos) +int ModApiEnvMod::l_compare_block_status(lua_State *L) +{ + GET_ENV_PTR; + + v3s16 nodepos = check_v3s16(L, 1); + std::string condition_s = luaL_checkstring(L, 2); + auto status = env->getBlockStatus(getNodeBlockPos(nodepos)); + + int condition_i = -1; + if (!string_to_enum(es_BlockStatusType, condition_i, condition_s)) + return 0; // Unsupported + + lua_pushboolean(L, status >= condition_i); + return 1; +} + + +// forceload_free_block(blockpos) +// blockpos = {x=num, y=num, z=num} +int ModApiEnvMod::l_forceload_free_block(lua_State *L) +{ + GET_ENV_PTR; + + v3s16 blockpos = read_v3s16(L, 1); + env->getForceloadedBlocks()->erase(blockpos); + return 0; +} + +// get_translated_string(lang_code, string) +int ModApiEnvMod::l_get_translated_string(lua_State * L) +{ + GET_ENV_PTR; + std::string lang_code = luaL_checkstring(L, 1); + std::string string = luaL_checkstring(L, 2); + + auto *translations = getServer(L)->getTranslationLanguage(lang_code); + string = wide_to_utf8(translate_string(utf8_to_wide(string), translations)); + lua_pushstring(L, string.c_str()); + return 1; +} + +void ModApiEnvMod::Initialize(lua_State *L, int top) +{ + API_FCT(set_node); + API_FCT(bulk_set_node); + API_FCT(add_node); + API_FCT(swap_node); + API_FCT(add_item); + API_FCT(remove_node); + API_FCT(get_node); + API_FCT(get_node_or_nil); + API_FCT(get_node_light); + API_FCT(get_natural_light); + API_FCT(place_node); + API_FCT(dig_node); + API_FCT(punch_node); + API_FCT(get_node_max_level); + API_FCT(get_node_level); + API_FCT(set_node_level); + API_FCT(add_node_level); + API_FCT(add_entity); + API_FCT(find_nodes_with_meta); + API_FCT(get_meta); + API_FCT(get_node_timer); + API_FCT(get_connected_players); + API_FCT(get_player_by_name); + API_FCT(get_objects_in_area); + API_FCT(get_objects_inside_radius); + API_FCT(set_timeofday); + API_FCT(get_timeofday); + API_FCT(get_gametime); + API_FCT(get_day_count); + API_FCT(find_node_near); + API_FCT(find_nodes_in_area); + API_FCT(find_nodes_in_area_under_air); + API_FCT(fix_light); + API_FCT(load_area); + API_FCT(emerge_area); + API_FCT(delete_area); + API_FCT(get_perlin); + API_FCT(get_perlin_map); + API_FCT(get_voxel_manip); + API_FCT(clear_objects); + API_FCT(spawn_tree); + API_FCT(find_path); + API_FCT(line_of_sight); + API_FCT(raycast); + API_FCT(transforming_liquid_add); + API_FCT(forceload_block); + API_FCT(forceload_free_block); + API_FCT(compare_block_status); + API_FCT(get_translated_string); +} + +void ModApiEnvMod::InitializeClient(lua_State *L, int top) +{ + API_FCT(get_node_light); + API_FCT(get_timeofday); + API_FCT(get_node_max_level); + API_FCT(get_node_level); + API_FCT(find_nodes_with_meta); + API_FCT(find_node_near); + API_FCT(find_nodes_in_area); + API_FCT(find_nodes_in_area_under_air); + API_FCT(line_of_sight); + API_FCT(raycast); +} diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h new file mode 100644 index 0000000..a7d406d --- /dev/null +++ b/src/script/lua_api/l_env.h @@ -0,0 +1,340 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" +#include "serverenvironment.h" +#include "raycast.h" + +class ModApiEnvMod : public ModApiBase { +private: + // set_node(pos, node) + // pos = {x=num, y=num, z=num} + static int l_set_node(lua_State *L); + + // bulk_set_node([pos1, pos2, ...], node) + // pos = {x=num, y=num, z=num} + static int l_bulk_set_node(lua_State *L); + + static int l_add_node(lua_State *L); + + // remove_node(pos) + // pos = {x=num, y=num, z=num} + static int l_remove_node(lua_State *L); + + // swap_node(pos, node) + // pos = {x=num, y=num, z=num} + static int l_swap_node(lua_State *L); + + // get_node(pos) + // pos = {x=num, y=num, z=num} + static int l_get_node(lua_State *L); + + // get_node_or_nil(pos) + // pos = {x=num, y=num, z=num} + static int l_get_node_or_nil(lua_State *L); + + // get_node_light(pos, timeofday) + // pos = {x=num, y=num, z=num} + // timeofday: nil = current time, 0 = night, 0.5 = day + static int l_get_node_light(lua_State *L); + + // get_natural_light(pos, timeofday) + // pos = {x=num, y=num, z=num} + // timeofday: nil = current time, 0 = night, 0.5 = day + static int l_get_natural_light(lua_State *L); + + // place_node(pos, node) + // pos = {x=num, y=num, z=num} + static int l_place_node(lua_State *L); + + // dig_node(pos) + // pos = {x=num, y=num, z=num} + static int l_dig_node(lua_State *L); + + // punch_node(pos) + // pos = {x=num, y=num, z=num} + static int l_punch_node(lua_State *L); + + // get_node_max_level(pos) + // pos = {x=num, y=num, z=num} + static int l_get_node_max_level(lua_State *L); + + // get_node_level(pos) + // pos = {x=num, y=num, z=num} + static int l_get_node_level(lua_State *L); + + // set_node_level(pos) + // pos = {x=num, y=num, z=num} + static int l_set_node_level(lua_State *L); + + // add_node_level(pos) + // pos = {x=num, y=num, z=num} + static int l_add_node_level(lua_State *L); + + // find_nodes_with_meta(pos1, pos2) + static int l_find_nodes_with_meta(lua_State *L); + + // get_meta(pos) + static int l_get_meta(lua_State *L); + + // get_node_timer(pos) + static int l_get_node_timer(lua_State *L); + + // add_entity(pos, entityname) -> ObjectRef or nil + // pos = {x=num, y=num, z=num} + static int l_add_entity(lua_State *L); + + // add_item(pos, itemstack or itemstring or table) -> ObjectRef or nil + // pos = {x=num, y=num, z=num} + static int l_add_item(lua_State *L); + + // get_connected_players() + static int l_get_connected_players(lua_State *L); + + // get_player_by_name(name) + static int l_get_player_by_name(lua_State *L); + + // get_objects_inside_radius(pos, radius) + static int l_get_objects_inside_radius(lua_State *L); + + // get_objects_in_area(pos, minp, maxp) + static int l_get_objects_in_area(lua_State *L); + + // set_timeofday(val) + // val = 0...1 + static int l_set_timeofday(lua_State *L); + + // get_timeofday() -> 0...1 + static int l_get_timeofday(lua_State *L); + + // get_gametime() + static int l_get_gametime(lua_State *L); + + // get_day_count() -> int + static int l_get_day_count(lua_State *L); + + // find_node_near(pos, radius, nodenames, search_center) -> pos or nil + // nodenames: eg. {"ignore", "group:tree"} or "default:dirt" + static int l_find_node_near(lua_State *L); + + // find_nodes_in_area(minp, maxp, nodenames) -> list of positions + // nodenames: eg. {"ignore", "group:tree"} or "default:dirt" + static int l_find_nodes_in_area(lua_State *L); + + // find_surface_nodes_in_area(minp, maxp, nodenames) -> list of positions + // nodenames: eg. {"ignore", "group:tree"} or "default:dirt" + static int l_find_nodes_in_area_under_air(lua_State *L); + + // fix_light(p1, p2) -> true/false + static int l_fix_light(lua_State *L); + + // load_area(p1) + static int l_load_area(lua_State *L); + + // emerge_area(p1, p2) + static int l_emerge_area(lua_State *L); + + // delete_area(p1, p2) -> true/false + static int l_delete_area(lua_State *L); + + // get_perlin(seeddiff, octaves, persistence, scale) + // returns world-specific PerlinNoise + static int l_get_perlin(lua_State *L); + + // get_perlin_map(noiseparams, size) + // returns world-specific PerlinNoiseMap + static int l_get_perlin_map(lua_State *L); + + // get_voxel_manip() + // returns world-specific voxel manipulator + static int l_get_voxel_manip(lua_State *L); + + // clear_objects() + // clear all objects in the environment + static int l_clear_objects(lua_State *L); + + // spawn_tree(pos, treedef) + static int l_spawn_tree(lua_State *L); + + // line_of_sight(pos1, pos2) -> true/false + static int l_line_of_sight(lua_State *L); + + // raycast(pos1, pos2, objects, liquids) -> Raycast + static int l_raycast(lua_State *L); + + // find_path(pos1, pos2, searchdistance, + // max_jump, max_drop, algorithm) -> table containing path + static int l_find_path(lua_State *L); + + // transforming_liquid_add(pos) + static int l_transforming_liquid_add(lua_State *L); + + // forceload_block(blockpos) + // forceloads a block + static int l_forceload_block(lua_State *L); + + // forceload_free_block(blockpos) + // stops forceloading a position + static int l_forceload_free_block(lua_State *L); + + // compare_block_status(nodepos) + static int l_compare_block_status(lua_State *L); + + // Get a string translated server side + static int l_get_translated_string(lua_State * L); + + /* Helpers */ + + static void collectNodeIds(lua_State *L, int idx, + const NodeDefManager *ndef, std::vector<content_t> &filter); + +public: + static void Initialize(lua_State *L, int top); + static void InitializeClient(lua_State *L, int top); + + static const EnumString es_ClearObjectsMode[]; + static const EnumString es_BlockStatusType[]; +}; + +class LuaABM : public ActiveBlockModifier { +private: + int m_id; + + std::vector<std::string> m_trigger_contents; + std::vector<std::string> m_required_neighbors; + float m_trigger_interval; + u32 m_trigger_chance; + bool m_simple_catch_up; + s16 m_min_y; + s16 m_max_y; +public: + LuaABM(lua_State *L, int id, + const std::vector<std::string> &trigger_contents, + const std::vector<std::string> &required_neighbors, + float trigger_interval, u32 trigger_chance, bool simple_catch_up, s16 min_y, s16 max_y): + m_id(id), + m_trigger_contents(trigger_contents), + m_required_neighbors(required_neighbors), + m_trigger_interval(trigger_interval), + m_trigger_chance(trigger_chance), + m_simple_catch_up(simple_catch_up), + m_min_y(min_y), + m_max_y(max_y) + { + } + virtual const std::vector<std::string> &getTriggerContents() const + { + return m_trigger_contents; + } + virtual const std::vector<std::string> &getRequiredNeighbors() const + { + return m_required_neighbors; + } + virtual float getTriggerInterval() + { + return m_trigger_interval; + } + virtual u32 getTriggerChance() + { + return m_trigger_chance; + } + virtual bool getSimpleCatchUp() + { + return m_simple_catch_up; + } + virtual s16 getMinY() + { + return m_min_y; + } + virtual s16 getMaxY() + { + return m_max_y; + } + virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n, + u32 active_object_count, u32 active_object_count_wider); +}; + +class LuaLBM : public LoadingBlockModifierDef +{ +private: + int m_id; +public: + LuaLBM(lua_State *L, int id, + const std::set<std::string> &trigger_contents, + const std::string &name, + bool run_at_every_load): + m_id(id) + { + this->run_at_every_load = run_at_every_load; + this->trigger_contents = trigger_contents; + this->name = name; + } + virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n); +}; + +//! Lua wrapper for RaycastState objects +class LuaRaycast : public ModApiBase +{ +private: + static const char className[]; + static const luaL_Reg methods[]; + //! Inner state + RaycastState state; + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + /*! + * Raycast:next() -> pointed_thing + * Returns the next pointed thing on the ray. + */ + static int l_next(lua_State *L); +public: + //! Constructor with the same arguments as RaycastState. + LuaRaycast( + const core::line3d<f32> &shootline, + bool objects_pointable, + bool liquids_pointable) : + state(shootline, objects_pointable, liquids_pointable) + {} + + //! Creates a LuaRaycast and leaves it on top of the stack. + static int create_object(lua_State *L); + + /*! + * Returns the Raycast from the stack or throws an error. + * @param narg location of the RaycastState in the stack + */ + static LuaRaycast *checkobject(lua_State *L, int narg); + + //! Registers Raycast as a Lua userdata type. + static void Register(lua_State *L); +}; + +struct ScriptCallbackState { + ServerScripting *script; + int callback_ref; + int args_ref; + unsigned int refcount; + std::string origin; +}; diff --git a/src/script/lua_api/l_http.cpp b/src/script/lua_api/l_http.cpp new file mode 100644 index 0000000..5566a85 --- /dev/null +++ b/src/script/lua_api/l_http.cpp @@ -0,0 +1,249 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_internal.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "lua_api/l_http.h" +#include "cpp_api/s_security.h" +#include "httpfetch.h" +#include "settings.h" +#include "debug.h" +#include "log.h" + +#include <iomanip> + +#define HTTP_API(name) \ + lua_pushstring(L, #name); \ + lua_pushcfunction(L, l_http_##name); \ + lua_settable(L, -3); + +#if USE_CURL +void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req) +{ + luaL_checktype(L, 1, LUA_TTABLE); + + req.caller = httpfetch_caller_alloc_secure(); + getstringfield(L, 1, "url", req.url); + getstringfield(L, 1, "user_agent", req.useragent); + req.multipart = getboolfield_default(L, 1, "multipart", false); + if (getintfield(L, 1, "timeout", req.timeout)) + req.timeout *= 1000; + + lua_getfield(L, 1, "method"); + if (lua_isstring(L, -1)) { + std::string mth = getstringfield_default(L, 1, "method", ""); + if (mth == "GET") + req.method = HTTP_GET; + else if (mth == "POST") + req.method = HTTP_POST; + else if (mth == "PUT") + req.method = HTTP_PUT; + else if (mth == "DELETE") + req.method = HTTP_DELETE; + } + lua_pop(L, 1); + + // post_data: if table, post form data, otherwise raw data DEPRECATED use data and method instead + lua_getfield(L, 1, "post_data"); + if (lua_isnil(L, 2)) { + lua_pop(L, 1); + lua_getfield(L, 1, "data"); + } + else { + req.method = HTTP_POST; + } + + if (lua_istable(L, 2)) { + lua_pushnil(L); + while (lua_next(L, 2) != 0) { + req.fields[readParam<std::string>(L, -2)] = readParam<std::string>(L, -1); + lua_pop(L, 1); + } + } else if (lua_isstring(L, 2)) { + req.raw_data = readParam<std::string>(L, 2); + } + + lua_pop(L, 1); + + lua_getfield(L, 1, "extra_headers"); + if (lua_istable(L, 2)) { + lua_pushnil(L); + while (lua_next(L, 2) != 0) { + req.extra_headers.emplace_back(readParam<std::string>(L, -1)); + lua_pop(L, 1); + } + } + lua_pop(L, 1); +} + +void ModApiHttp::push_http_fetch_result(lua_State *L, HTTPFetchResult &res, bool completed) +{ + lua_newtable(L); + setboolfield(L, -1, "succeeded", res.succeeded); + setboolfield(L, -1, "timeout", res.timeout); + setboolfield(L, -1, "completed", completed); + setintfield(L, -1, "code", res.response_code); + setstringfield(L, -1, "data", res.data); +} + +// http_api.fetch_sync(HTTPRequest definition) +int ModApiHttp::l_http_fetch_sync(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + HTTPFetchRequest req; + read_http_fetch_request(L, req); + + infostream << "Mod performs HTTP request with URL " << req.url << std::endl; + + HTTPFetchResult res; + httpfetch_sync(req, res); + + push_http_fetch_result(L, res, true); + + return 1; +} + +// http_api.fetch_async(HTTPRequest definition) +int ModApiHttp::l_http_fetch_async(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + HTTPFetchRequest req; + read_http_fetch_request(L, req); + + infostream << "Mod performs HTTP request with URL " << req.url << std::endl; + httpfetch_async(req); + + // Convert handle to hex string since lua can't handle 64-bit integers + std::stringstream handle_conversion_stream; + handle_conversion_stream << std::hex << req.caller; + std::string caller_handle(handle_conversion_stream.str()); + + lua_pushstring(L, caller_handle.c_str()); + return 1; +} + +// http_api.fetch_async_get(handle) +int ModApiHttp::l_http_fetch_async_get(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + std::string handle_str = luaL_checkstring(L, 1); + + // Convert hex string back to 64-bit handle + u64 handle; + std::stringstream handle_conversion_stream; + handle_conversion_stream << std::hex << handle_str; + handle_conversion_stream >> handle; + + HTTPFetchResult res; + bool completed = httpfetch_async_get(handle, res); + + push_http_fetch_result(L, res, completed); + + return 1; +} + +int ModApiHttp::l_request_http_api(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + if (!ScriptApiSecurity::checkWhitelisted(L, "secure.http_mods") && + !ScriptApiSecurity::checkWhitelisted(L, "secure.trusted_mods")) { + lua_pushnil(L); + return 1; + } + + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_HTTP_API_LUA); + assert(lua_isfunction(L, -1)); + + lua_newtable(L); + HTTP_API(fetch_async); + HTTP_API(fetch_async_get); + + // Stack now looks like this: + // <function> <table with fetch_async, fetch_async_get> + // Now call it to append .fetch(request, callback) to table + lua_call(L, 1, 1); + + return 1; +} + +int ModApiHttp::l_get_http_api(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + lua_newtable(L); + HTTP_API(fetch_async); + HTTP_API(fetch_async_get); + HTTP_API(fetch_sync); + + return 1; +} + +#endif + +int ModApiHttp::l_set_http_api_lua(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + +#if USE_CURL + // This is called by builtin to give us a function that will later + // populate the http_api table with additional method(s). + // We need this because access to the HTTP api is security-relevant and + // any mod could just mess with a global variable. + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_HTTP_API_LUA); +#endif + + return 0; +} + +void ModApiHttp::Initialize(lua_State *L, int top) +{ +#if USE_CURL + + bool isMainmenu = false; +#ifndef SERVER + isMainmenu = ModApiBase::getGuiEngine(L) != nullptr; +#endif + + if (isMainmenu) { + API_FCT(get_http_api); + } else { + API_FCT(request_http_api); + API_FCT(set_http_api_lua); + } + +#else + + // Define this function anyway so builtin can call it without checking + API_FCT(set_http_api_lua); + +#endif +} + +void ModApiHttp::InitializeAsync(lua_State *L, int top) +{ +#if USE_CURL + API_FCT(get_http_api); +#endif +} diff --git a/src/script/lua_api/l_http.h b/src/script/lua_api/l_http.h new file mode 100644 index 0000000..8d084ec --- /dev/null +++ b/src/script/lua_api/l_http.h @@ -0,0 +1,58 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" +#include "config.h" + +struct HTTPFetchRequest; +struct HTTPFetchResult; + +class ModApiHttp : public ModApiBase { +private: +#if USE_CURL + // Helpers for HTTP fetch functions + static void read_http_fetch_request(lua_State *L, HTTPFetchRequest &req); + static void push_http_fetch_result(lua_State *L, HTTPFetchResult &res, bool completed = true); + + // http_fetch_sync({url=, timeout=, data=}) + static int l_http_fetch_sync(lua_State *L); + + // http_fetch_async({url=, timeout=, data=}) + static int l_http_fetch_async(lua_State *L); + + // http_fetch_async_get(handle) + static int l_http_fetch_async_get(lua_State *L); + + // request_http_api() + static int l_request_http_api(lua_State *L); + + // get_http_api() + static int l_get_http_api(lua_State *L); +#endif + + // set_http_api_lua() [internal] + static int l_set_http_api_lua(lua_State *L); + + +public: + static void Initialize(lua_State *L, int top); + static void InitializeAsync(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_internal.h b/src/script/lua_api/l_internal.h new file mode 100644 index 0000000..de73ff4 --- /dev/null +++ b/src/script/lua_api/l_internal.h @@ -0,0 +1,79 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/******************************************************************************/ +/******************************************************************************/ +/* WARNING!!!! do NOT add this header in any include file or any code file */ +/* not being a modapi file!!!!!!!! */ +/******************************************************************************/ +/******************************************************************************/ + +#pragma once + +#include "common/c_internal.h" + +#define luamethod(class, name) {#name, class::l_##name} + +#define luamethod_dep(class, good, bad) \ + {#bad, [](lua_State *L) -> int { \ + return l_deprecated_function(L, #good, #bad, &class::l_##good); \ + }} + +#define luamethod_aliased(class, good, bad) \ + luamethod(class, good), \ + luamethod_dep(class, good, bad) + +#define API_FCT(name) registerFunction(L, #name, l_##name, top) + +// For future use +#define MAP_LOCK_REQUIRED ((void)0) +#define NO_MAP_LOCK_REQUIRED ((void)0) + +/* In debug mode ensure no code tries to retrieve the server env when it isn't + * actually available (in CSM) */ +#if !defined(SERVER) && !defined(NDEBUG) +#define DEBUG_ASSERT_NO_CLIENTAPI \ + FATAL_ERROR_IF(getClient(L) != nullptr, "Tried " \ + "to retrieve ServerEnvironment on client") +#else +#define DEBUG_ASSERT_NO_CLIENTAPI ((void)0) +#endif + +// Retrieve ServerEnvironment pointer as `env` (no map lock) +#define GET_ENV_PTR_NO_MAP_LOCK \ + DEBUG_ASSERT_NO_CLIENTAPI; \ + ServerEnvironment *env = (ServerEnvironment *)getEnv(L); \ + if (env == NULL) \ + return 0 + +// Retrieve ServerEnvironment pointer as `env` +#define GET_ENV_PTR \ + MAP_LOCK_REQUIRED; \ + GET_ENV_PTR_NO_MAP_LOCK + +// Retrieve Environment pointer as `env` (no map lock) +#define GET_PLAIN_ENV_PTR_NO_MAP_LOCK \ + Environment *env = getEnv(L); \ + if (env == NULL) \ + return 0 + +// Retrieve Environment pointer as `env` +#define GET_PLAIN_ENV_PTR \ + MAP_LOCK_REQUIRED; \ + GET_PLAIN_ENV_PTR_NO_MAP_LOCK diff --git a/src/script/lua_api/l_inventory.cpp b/src/script/lua_api/l_inventory.cpp new file mode 100644 index 0000000..175047e --- /dev/null +++ b/src/script/lua_api/l_inventory.cpp @@ -0,0 +1,543 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_inventory.h" +#include "lua_api/l_internal.h" +#include "lua_api/l_item.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "server.h" +#include "server/serverinventorymgr.h" +#include "remoteplayer.h" + +/* + InvRef +*/ +InvRef* InvRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if(!ud) luaL_typerror(L, narg, className); + return *(InvRef**)ud; // unbox pointer +} + +Inventory* InvRef::getinv(lua_State *L, InvRef *ref) +{ + return getServerInventoryMgr(L)->getInventory(ref->m_loc); +} + +InventoryList* InvRef::getlist(lua_State *L, InvRef *ref, + const char *listname) +{ + NO_MAP_LOCK_REQUIRED; + Inventory *inv = getinv(L, ref); + if(!inv) + return NULL; + return inv->getList(listname); +} + +void InvRef::reportInventoryChange(lua_State *L, InvRef *ref) +{ + // Inform other things that the inventory has changed + getServerInventoryMgr(L)->setInventoryModified(ref->m_loc); +} + +// Exported functions + +// garbage collector +int InvRef::gc_object(lua_State *L) { + InvRef *o = *(InvRef **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +// is_empty(self, listname) -> true/false +int InvRef::l_is_empty(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + InventoryList *list = getlist(L, ref, listname); + if(list && list->getUsedSlots() > 0){ + lua_pushboolean(L, false); + } else { + lua_pushboolean(L, true); + } + return 1; +} + +// get_size(self, listname) +int InvRef::l_get_size(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + InventoryList *list = getlist(L, ref, listname); + if(list){ + lua_pushinteger(L, list->getSize()); + } else { + lua_pushinteger(L, 0); + } + return 1; +} + +// get_width(self, listname) +int InvRef::l_get_width(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + InventoryList *list = getlist(L, ref, listname); + if(list){ + lua_pushinteger(L, list->getWidth()); + } else { + lua_pushinteger(L, 0); + } + return 1; +} + +// set_size(self, listname, size) +int InvRef::l_set_size(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + + int newsize = luaL_checknumber(L, 3); + if (newsize < 0) { + lua_pushboolean(L, false); + return 1; + } + + Inventory *inv = getinv(L, ref); + if(inv == NULL){ + lua_pushboolean(L, false); + return 1; + } + if(newsize == 0){ + inv->deleteList(listname); + reportInventoryChange(L, ref); + lua_pushboolean(L, true); + return 1; + } + InventoryList *list = inv->getList(listname); + if(list){ + list->setSize(newsize); + } else { + list = inv->addList(listname, newsize); + if (!list) + { + lua_pushboolean(L, false); + return 1; + } + } + reportInventoryChange(L, ref); + lua_pushboolean(L, true); + return 1; +} + +// set_width(self, listname, size) +int InvRef::l_set_width(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + int newwidth = luaL_checknumber(L, 3); + Inventory *inv = getinv(L, ref); + if(inv == NULL){ + return 0; + } + InventoryList *list = inv->getList(listname); + if(list){ + list->setWidth(newwidth); + } else { + return 0; + } + reportInventoryChange(L, ref); + return 0; +} + +// get_stack(self, listname, i) -> itemstack +int InvRef::l_get_stack(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + int i = luaL_checknumber(L, 3) - 1; + InventoryList *list = getlist(L, ref, listname); + ItemStack item; + if(list != NULL && i >= 0 && i < (int) list->getSize()) + item = list->getItem(i); + LuaItemStack::create(L, item); + return 1; +} + +// set_stack(self, listname, i, stack) -> true/false +int InvRef::l_set_stack(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + int i = luaL_checknumber(L, 3) - 1; + ItemStack newitem = read_item(L, 4, getServer(L)->idef()); + InventoryList *list = getlist(L, ref, listname); + if(list != NULL && i >= 0 && i < (int) list->getSize()){ + list->changeItem(i, newitem); + reportInventoryChange(L, ref); + lua_pushboolean(L, true); + } else { + lua_pushboolean(L, false); + } + return 1; +} + +// get_list(self, listname) -> list or nil +int InvRef::l_get_list(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + Inventory *inv = getinv(L, ref); + if (!inv) { + lua_pushnil(L); + return 1; + } + InventoryList *invlist = inv->getList(listname); + if (!invlist) { + lua_pushnil(L); + return 1; + } + push_inventory_list(L, *invlist); + return 1; +} + +// set_list(self, listname, list) +int InvRef::l_set_list(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + Inventory *inv = getinv(L, ref); + if(inv == NULL){ + return 0; + } + InventoryList *list = inv->getList(listname); + if(list) + read_inventory_list(L, 3, inv, listname, + getServer(L), list->getSize()); + else + read_inventory_list(L, 3, inv, listname, getServer(L)); + reportInventoryChange(L, ref); + return 0; +} + +// get_lists(self) -> table that maps listnames to InventoryLists +int InvRef::l_get_lists(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + Inventory *inv = getinv(L, ref); + if (!inv) { + return 0; + } + push_inventory_lists(L, *inv); + return 1; +} + +// set_lists(self, lists) +int InvRef::l_set_lists(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + Inventory *inv = getinv(L, ref); + if (!inv) { + return 0; + } + + // Make a temporary inventory in case reading fails + Inventory *tempInv(inv); + tempInv->clear(); + + Server *server = getServer(L); + + lua_pushnil(L); + luaL_checktype(L, 2, LUA_TTABLE); + while (lua_next(L, 2)) { + const char *listname = lua_tostring(L, -2); + read_inventory_list(L, -1, tempInv, listname, server); + lua_pop(L, 1); + } + inv = tempInv; + return 0; +} + +// add_item(self, listname, itemstack or itemstring or table or nil) -> itemstack +// Returns the leftover stack +int InvRef::l_add_item(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + ItemStack item = read_item(L, 3, getServer(L)->idef()); + InventoryList *list = getlist(L, ref, listname); + if(list){ + ItemStack leftover = list->addItem(item); + if(leftover.count != item.count) + reportInventoryChange(L, ref); + LuaItemStack::create(L, leftover); + } else { + LuaItemStack::create(L, item); + } + return 1; +} + +// room_for_item(self, listname, itemstack or itemstring or table or nil) -> true/false +// Returns true if the item completely fits into the list +int InvRef::l_room_for_item(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + ItemStack item = read_item(L, 3, getServer(L)->idef()); + InventoryList *list = getlist(L, ref, listname); + if(list){ + lua_pushboolean(L, list->roomForItem(item)); + } else { + lua_pushboolean(L, false); + } + return 1; +} + +// contains_item(self, listname, itemstack or itemstring or table or nil, [match_meta]) -> true/false +// Returns true if the list contains the given count of the given item +int InvRef::l_contains_item(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + ItemStack item = read_item(L, 3, getServer(L)->idef()); + InventoryList *list = getlist(L, ref, listname); + bool match_meta = false; + if (lua_isboolean(L, 4)) + match_meta = readParam<bool>(L, 4); + if (list) { + lua_pushboolean(L, list->containsItem(item, match_meta)); + } else { + lua_pushboolean(L, false); + } + return 1; +} + +// remove_item(self, listname, itemstack or itemstring or table or nil) -> itemstack +// Returns the items that were actually removed +int InvRef::l_remove_item(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const char *listname = luaL_checkstring(L, 2); + ItemStack item = read_item(L, 3, getServer(L)->idef()); + InventoryList *list = getlist(L, ref, listname); + if(list){ + ItemStack removed = list->removeItem(item); + if(!removed.empty()) + reportInventoryChange(L, ref); + LuaItemStack::create(L, removed); + } else { + LuaItemStack::create(L, ItemStack()); + } + return 1; +} + +// get_location() -> location (like get_inventory(location)) +int InvRef::l_get_location(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + const InventoryLocation &loc = ref->m_loc; + switch(loc.type){ + case InventoryLocation::PLAYER: + lua_newtable(L); + lua_pushstring(L, "player"); + lua_setfield(L, -2, "type"); + lua_pushstring(L, loc.name.c_str()); + lua_setfield(L, -2, "name"); + return 1; + case InventoryLocation::NODEMETA: + lua_newtable(L); + lua_pushstring(L, "node"); + lua_setfield(L, -2, "type"); + push_v3s16(L, loc.p); + lua_setfield(L, -2, "pos"); + return 1; + case InventoryLocation::DETACHED: + lua_newtable(L); + lua_pushstring(L, "detached"); + lua_setfield(L, -2, "type"); + lua_pushstring(L, loc.name.c_str()); + lua_setfield(L, -2, "name"); + return 1; + case InventoryLocation::UNDEFINED: + case InventoryLocation::CURRENT_PLAYER: + break; + } + lua_newtable(L); + lua_pushstring(L, "undefined"); + lua_setfield(L, -2, "type"); + return 1; +} + + +InvRef::InvRef(const InventoryLocation &loc): + m_loc(loc) +{ +} + +// Creates an InvRef and leaves it on top of stack +// Not callable from Lua; all references are created on the C side. +void InvRef::create(lua_State *L, const InventoryLocation &loc) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *o = new InvRef(loc); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +void InvRef::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // drop methodtable + + // Cannot be created from Lua + //lua_register(L, className, create_object); +} + +const char InvRef::className[] = "InvRef"; +const luaL_Reg InvRef::methods[] = { + luamethod(InvRef, is_empty), + luamethod(InvRef, get_size), + luamethod(InvRef, set_size), + luamethod(InvRef, get_width), + luamethod(InvRef, set_width), + luamethod(InvRef, get_stack), + luamethod(InvRef, set_stack), + luamethod(InvRef, get_list), + luamethod(InvRef, set_list), + luamethod(InvRef, get_lists), + luamethod(InvRef, set_lists), + luamethod(InvRef, add_item), + luamethod(InvRef, room_for_item), + luamethod(InvRef, contains_item), + luamethod(InvRef, remove_item), + luamethod(InvRef, get_location), + {0,0} +}; + +// get_inventory(location) +int ModApiInventory::l_get_inventory(lua_State *L) +{ + InventoryLocation loc; + + lua_getfield(L, 1, "type"); + std::string type = luaL_checkstring(L, -1); + lua_pop(L, 1); + + if(type == "node"){ + MAP_LOCK_REQUIRED; + lua_getfield(L, 1, "pos"); + v3s16 pos = check_v3s16(L, -1); + loc.setNodeMeta(pos); + + if (getServerInventoryMgr(L)->getInventory(loc) != NULL) + InvRef::create(L, loc); + else + lua_pushnil(L); + return 1; + } + + NO_MAP_LOCK_REQUIRED; + if (type == "player") { + lua_getfield(L, 1, "name"); + loc.setPlayer(luaL_checkstring(L, -1)); + lua_pop(L, 1); + } else if (type == "detached") { + lua_getfield(L, 1, "name"); + loc.setDetached(luaL_checkstring(L, -1)); + lua_pop(L, 1); + } + + if (getServerInventoryMgr(L)->getInventory(loc) != NULL) + InvRef::create(L, loc); + else + lua_pushnil(L); + return 1; + // END NO_MAP_LOCK_REQUIRED; + +} + +// create_detached_inventory_raw(name, [player_name]) +int ModApiInventory::l_create_detached_inventory_raw(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *name = luaL_checkstring(L, 1); + std::string player = readParam<std::string>(L, 2, ""); + if (getServerInventoryMgr(L)->createDetachedInventory(name, getServer(L)->idef(), player) != NULL) { + InventoryLocation loc; + loc.setDetached(name); + InvRef::create(L, loc); + } else { + lua_pushnil(L); + } + return 1; +} + +// remove_detached_inventory_raw(name) +int ModApiInventory::l_remove_detached_inventory_raw(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const std::string &name = luaL_checkstring(L, 1); + lua_pushboolean(L, getServerInventoryMgr(L)->removeDetachedInventory(name)); + return 1; +} + +void ModApiInventory::Initialize(lua_State *L, int top) +{ + API_FCT(create_detached_inventory_raw); + API_FCT(remove_detached_inventory_raw); + API_FCT(get_inventory); +} diff --git a/src/script/lua_api/l_inventory.h b/src/script/lua_api/l_inventory.h new file mode 100644 index 0000000..6a75bac --- /dev/null +++ b/src/script/lua_api/l_inventory.h @@ -0,0 +1,127 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" + +#include "inventory.h" +#include "inventorymanager.h" + +class RemotePlayer; + +/* + InvRef +*/ + +class InvRef : public ModApiBase { +private: + InventoryLocation m_loc; + + static const char className[]; + static const luaL_Reg methods[]; + + static InvRef *checkobject(lua_State *L, int narg); + + static Inventory* getinv(lua_State *L, InvRef *ref); + + static InventoryList* getlist(lua_State *L, InvRef *ref, + const char *listname); + + static void reportInventoryChange(lua_State *L, InvRef *ref); + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + // is_empty(self, listname) -> true/false + static int l_is_empty(lua_State *L); + + // get_size(self, listname) + static int l_get_size(lua_State *L); + + // get_width(self, listname) + static int l_get_width(lua_State *L); + + // set_size(self, listname, size) + static int l_set_size(lua_State *L); + + // set_width(self, listname, size) + static int l_set_width(lua_State *L); + + // get_stack(self, listname, i) -> itemstack + static int l_get_stack(lua_State *L); + + // set_stack(self, listname, i, stack) -> true/false + static int l_set_stack(lua_State *L); + + // get_list(self, listname) -> list or nil + static int l_get_list(lua_State *L); + + // set_list(self, listname, list) + static int l_set_list(lua_State *L); + + // get_lists(self) -> list of InventoryLists + static int l_get_lists(lua_State *L); + + // set_lists(self, lists) + static int l_set_lists(lua_State *L); + + // add_item(self, listname, itemstack or itemstring or table or nil) -> itemstack + // Returns the leftover stack + static int l_add_item(lua_State *L); + + // room_for_item(self, listname, itemstack or itemstring or table or nil) -> true/false + // Returns true if the item completely fits into the list + static int l_room_for_item(lua_State *L); + + // contains_item(self, listname, itemstack or itemstring or table or nil, [match_meta]) -> true/false + // Returns true if the list contains the given count of the given item name + static int l_contains_item(lua_State *L); + + // remove_item(self, listname, itemstack or itemstring or table or nil) -> itemstack + // Returns the items that were actually removed + static int l_remove_item(lua_State *L); + + // get_location() -> location (like get_inventory(location)) + static int l_get_location(lua_State *L); + +public: + InvRef(const InventoryLocation &loc); + + ~InvRef() = default; + + // Creates an InvRef and leaves it on top of stack + // Not callable from Lua; all references are created on the C side. + static void create(lua_State *L, const InventoryLocation &loc); + static void Register(lua_State *L); +}; + +class ModApiInventory : public ModApiBase { +private: + static int l_create_detached_inventory_raw(lua_State *L); + + static int l_remove_detached_inventory_raw(lua_State *L); + + static int l_get_inventory(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp new file mode 100644 index 0000000..05473f4 --- /dev/null +++ b/src/script/lua_api/l_item.cpp @@ -0,0 +1,714 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_item.h" +#include "lua_api/l_itemstackmeta.h" +#include "lua_api/l_internal.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "common/c_packer.h" +#include "itemdef.h" +#include "nodedef.h" +#include "server.h" +#include "inventory.h" +#include "log.h" + + +// garbage collector +int LuaItemStack::gc_object(lua_State *L) +{ + LuaItemStack *o = *(LuaItemStack **)(lua_touserdata(L, 1)); + o->drop(); + return 0; +} + +// __tostring metamethod +int LuaItemStack::mt_tostring(lua_State *L) +{ + LuaItemStack *o = checkobject(L, 1); + std::string itemstring = o->m_stack.getItemString(false); + lua_pushfstring(L, "ItemStack(\"%s\")", itemstring.c_str()); + return 1; +} + +// is_empty(self) -> true/false +int LuaItemStack::l_is_empty(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + lua_pushboolean(L, item.empty()); + return 1; +} + +// get_name(self) -> string +int LuaItemStack::l_get_name(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + lua_pushstring(L, item.name.c_str()); + return 1; +} + +// set_name(self, name) +int LuaItemStack::l_set_name(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + + bool status = true; + item.name = luaL_checkstring(L, 2); + if (item.name.empty() || item.empty()) { + item.clear(); + status = false; + } + + lua_pushboolean(L, status); + return 1; +} + +// get_count(self) -> number +int LuaItemStack::l_get_count(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + lua_pushinteger(L, item.count); + return 1; +} + +// set_count(self, number) +int LuaItemStack::l_set_count(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + + bool status; + lua_Integer count = luaL_checkinteger(L, 2); + if (count > 0 && count <= 65535) { + item.count = count; + status = true; + } else { + item.clear(); + status = false; + } + + lua_pushboolean(L, status); + return 1; +} + +// get_wear(self) -> number +int LuaItemStack::l_get_wear(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + lua_pushinteger(L, item.wear); + return 1; +} + +// set_wear(self, number) +int LuaItemStack::l_set_wear(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + + bool status; + lua_Integer wear = luaL_checkinteger(L, 2); + if (wear <= 65535) { + item.wear = wear; + status = true; + } else { + item.clear(); + status = false; + } + + lua_pushboolean(L, status); + return 1; +} + +// get_meta(self) -> string +int LuaItemStack::l_get_meta(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStackMetaRef::create(L, o); + return 1; +} + +// DEPRECATED +// get_metadata(self) -> string +int LuaItemStack::l_get_metadata(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + const std::string &value = item.metadata.getString(""); + lua_pushlstring(L, value.c_str(), value.size()); + return 1; +} + +// DEPRECATED +// set_metadata(self, string) +int LuaItemStack::l_set_metadata(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + + size_t len = 0; + const char *ptr = luaL_checklstring(L, 2, &len); + item.metadata.setString("", std::string(ptr, len)); + + lua_pushboolean(L, true); + return 1; +} + +// get_description(self) +int LuaItemStack::l_get_description(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + std::string desc = o->m_stack.getDescription(getGameDef(L)->idef()); + lua_pushstring(L, desc.c_str()); + return 1; +} + +// get_short_description(self) +int LuaItemStack::l_get_short_description(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + std::string desc = o->m_stack.getShortDescription(getGameDef(L)->idef()); + lua_pushstring(L, desc.c_str()); + return 1; +} + +// clear(self) -> true +int LuaItemStack::l_clear(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + o->m_stack.clear(); + lua_pushboolean(L, true); + return 1; +} + +// replace(self, itemstack or itemstring or table or nil) -> true +int LuaItemStack::l_replace(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + o->m_stack = read_item(L, 2, getGameDef(L)->idef()); + lua_pushboolean(L, true); + return 1; +} + +// to_string(self) -> string +int LuaItemStack::l_to_string(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + std::string itemstring = o->m_stack.getItemString(); + lua_pushstring(L, itemstring.c_str()); + return 1; +} + +// to_table(self) -> table or nil +int LuaItemStack::l_to_table(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + const ItemStack &item = o->m_stack; + if(item.empty()) + { + lua_pushnil(L); + } + else + { + lua_newtable(L); + lua_pushstring(L, item.name.c_str()); + lua_setfield(L, -2, "name"); + lua_pushinteger(L, item.count); + lua_setfield(L, -2, "count"); + lua_pushinteger(L, item.wear); + lua_setfield(L, -2, "wear"); + + const std::string &metadata_str = item.metadata.getString(""); + lua_pushlstring(L, metadata_str.c_str(), metadata_str.size()); + lua_setfield(L, -2, "metadata"); + + lua_newtable(L); + const StringMap &fields = item.metadata.getStrings(); + for (const auto &field : fields) { + const std::string &name = field.first; + if (name.empty()) + continue; + const std::string &value = field.second; + lua_pushlstring(L, name.c_str(), name.size()); + lua_pushlstring(L, value.c_str(), value.size()); + lua_settable(L, -3); + } + lua_setfield(L, -2, "meta"); + } + return 1; +} + +// get_stack_max(self) -> number +int LuaItemStack::l_get_stack_max(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + lua_pushinteger(L, item.getStackMax(getGameDef(L)->idef())); + return 1; +} + +// get_free_space(self) -> number +int LuaItemStack::l_get_free_space(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + lua_pushinteger(L, item.freeSpace(getGameDef(L)->idef())); + return 1; +} + +// is_known(self) -> true/false +// Checks if the item is defined. +int LuaItemStack::l_is_known(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + bool is_known = item.isKnown(getGameDef(L)->idef()); + lua_pushboolean(L, is_known); + return 1; +} + +// get_definition(self) -> table +// Returns the item definition table from registered_items, +// or a fallback one (name="unknown") +int LuaItemStack::l_get_definition(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + + // Get registered_items[name] + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_items"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, item.name.c_str()); + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_getfield(L, -1, "unknown"); + } + return 1; +} + +// get_tool_capabilities(self) -> table +// Returns the effective tool digging properties. +// Returns those of the hand ("") if this item has none associated. +int LuaItemStack::l_get_tool_capabilities(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + const ToolCapabilities &prop = + item.getToolCapabilities(getGameDef(L)->idef()); + push_tool_capabilities(L, prop); + return 1; +} + +// add_wear(self, amount) -> true/false +// The range for "amount" is [0,65536]. Wear is only added if the item +// is a tool. Adding wear might destroy the item. +// Returns true if the item is (or was) a tool. +int LuaItemStack::l_add_wear(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + int amount = lua_tointeger(L, 2); + bool result = item.addWear(amount, getGameDef(L)->idef()); + lua_pushboolean(L, result); + return 1; +} + +// add_wear_by_uses(self, max_uses) -> true/false +// The range for "max_uses" is [0,65536]. +// Adds wear to the item in such a way that, if +// only this function is called to add wear, the item +// will be destroyed exactly after `max_uses` times of calling it. +// No-op if `max_uses` is 0 or item is not a tool. +// Returns true if the item is (or was) a tool. +int LuaItemStack::l_add_wear_by_uses(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + u32 max_uses = readParam<int>(L, 2); + u32 add_wear = calculateResultWear(max_uses, item.wear); + bool result = item.addWear(add_wear, getGameDef(L)->idef()); + lua_pushboolean(L, result); + return 1; +} + +// add_item(self, itemstack or itemstring or table or nil) -> itemstack +// Returns leftover item stack +int LuaItemStack::l_add_item(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + ItemStack newitem = read_item(L, -1, getGameDef(L)->idef()); + ItemStack leftover = item.addItem(newitem, getGameDef(L)->idef()); + create(L, leftover); + return 1; +} + +// item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack +// First return value is true iff the new item fits fully into the stack +// Second return value is the would-be-left-over item stack +int LuaItemStack::l_item_fits(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + ItemStack newitem = read_item(L, 2, getGameDef(L)->idef()); + ItemStack restitem; + bool fits = item.itemFits(newitem, &restitem, getGameDef(L)->idef()); + lua_pushboolean(L, fits); // first return value + create(L, restitem); // second return value + return 2; +} + +// take_item(self, takecount=1) -> itemstack +int LuaItemStack::l_take_item(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + u32 takecount = 1; + if(!lua_isnone(L, 2)) + takecount = luaL_checkinteger(L, 2); + ItemStack taken = item.takeItem(takecount); + create(L, taken); + return 1; +} + +// peek_item(self, peekcount=1) -> itemstack +int LuaItemStack::l_peek_item(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + u32 peekcount = 1; + if(!lua_isnone(L, 2)) + peekcount = lua_tointeger(L, 2); + ItemStack peekaboo = item.peekItem(peekcount); + create(L, peekaboo); + return 1; +} + +LuaItemStack::LuaItemStack(const ItemStack &item): + m_stack(item) +{ +} + +// LuaItemStack(itemstack or itemstring or table or nil) +// Creates an LuaItemStack and leaves it on top of stack +int LuaItemStack::create_object(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ItemStack item; + if (!lua_isnone(L, 1)) + item = read_item(L, 1, getGameDef(L)->idef()); + LuaItemStack *o = new LuaItemStack(item); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + +// Not callable from Lua +int LuaItemStack::create(lua_State *L, const ItemStack &item) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = new LuaItemStack(item); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + +LuaItemStack *LuaItemStack::checkobject(lua_State *L, int narg) +{ + return *(LuaItemStack **)luaL_checkudata(L, narg, className); +} + +void *LuaItemStack::packIn(lua_State *L, int idx) +{ + LuaItemStack *o = checkobject(L, idx); + return new ItemStack(o->getItem()); +} + +void LuaItemStack::packOut(lua_State *L, void *ptr) +{ + ItemStack *stack = reinterpret_cast<ItemStack*>(ptr); + if (L) + create(L, *stack); + delete stack; +} + +void LuaItemStack::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + // hide metatable from Lua getmetatable() + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pushliteral(L, "__tostring"); + lua_pushcfunction(L, mt_tostring); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // drop methodtable + + // Can be created from Lua (ItemStack(itemstack or itemstring or table or nil)) + lua_register(L, className, create_object); + + script_register_packer(L, className, packIn, packOut); +} + +const char LuaItemStack::className[] = "ItemStack"; +const luaL_Reg LuaItemStack::methods[] = { + luamethod(LuaItemStack, is_empty), + luamethod(LuaItemStack, get_name), + luamethod(LuaItemStack, set_name), + luamethod(LuaItemStack, get_count), + luamethod(LuaItemStack, set_count), + luamethod(LuaItemStack, get_wear), + luamethod(LuaItemStack, set_wear), + luamethod(LuaItemStack, get_meta), + luamethod(LuaItemStack, get_metadata), + luamethod(LuaItemStack, set_metadata), + luamethod(LuaItemStack, get_description), + luamethod(LuaItemStack, get_short_description), + luamethod(LuaItemStack, clear), + luamethod(LuaItemStack, replace), + luamethod(LuaItemStack, to_string), + luamethod(LuaItemStack, to_table), + luamethod(LuaItemStack, get_stack_max), + luamethod(LuaItemStack, get_free_space), + luamethod(LuaItemStack, is_known), + luamethod(LuaItemStack, get_definition), + luamethod(LuaItemStack, get_tool_capabilities), + luamethod(LuaItemStack, add_wear), + luamethod(LuaItemStack, add_wear_by_uses), + luamethod(LuaItemStack, add_item), + luamethod(LuaItemStack, item_fits), + luamethod(LuaItemStack, take_item), + luamethod(LuaItemStack, peek_item), + {0,0} +}; + +/* + ItemDefinition +*/ + +// register_item_raw({lots of stuff}) +int ModApiItemMod::l_register_item_raw(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + luaL_checktype(L, 1, LUA_TTABLE); + int table = 1; + + // Get the writable item and node definition managers from the server + IWritableItemDefManager *idef = + getServer(L)->getWritableItemDefManager(); + NodeDefManager *ndef = + getServer(L)->getWritableNodeDefManager(); + + // Check if name is defined + std::string name; + lua_getfield(L, table, "name"); + if(lua_isstring(L, -1)){ + name = readParam<std::string>(L, -1); + } else { + throw LuaError("register_item_raw: name is not defined or not a string"); + } + + // Check if on_use is defined + + ItemDefinition def; + // Set a distinctive default value to check if this is set + def.node_placement_prediction = "__default"; + + // Read the item definition + read_item_definition(L, table, def, def); + + // Default to having client-side placement prediction for nodes + // ("" in item definition sets it off) + if(def.node_placement_prediction == "__default"){ + if(def.type == ITEM_NODE) + def.node_placement_prediction = name; + else + def.node_placement_prediction = ""; + } + + // Register item definition + idef->registerItem(def); + + // Read the node definition (content features) and register it + if (def.type == ITEM_NODE) { + ContentFeatures f; + read_content_features(L, f, table); + // when a mod reregisters ignore, only texture changes and such should + // be done + if (f.name == "ignore") + return 0; + // This would break everything + if (f.name.empty()) + throw LuaError("Cannot register node with empty name"); + + content_t id = ndef->set(f.name, f); + + if (id > MAX_REGISTERED_CONTENT) { + throw LuaError("Number of registerable nodes (" + + itos(MAX_REGISTERED_CONTENT+1) + + ") exceeded (" + name + ")"); + } + } + + return 0; /* number of results */ +} + +// unregister_item(name) +int ModApiItemMod::l_unregister_item_raw(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string name = luaL_checkstring(L, 1); + + IWritableItemDefManager *idef = + getServer(L)->getWritableItemDefManager(); + + // Unregister the node + if (idef->get(name).type == ITEM_NODE) { + NodeDefManager *ndef = + getServer(L)->getWritableNodeDefManager(); + ndef->removeNode(name); + } + + idef->unregisterItem(name); + + return 0; /* number of results */ +} + +// register_alias_raw(name, convert_to_name) +int ModApiItemMod::l_register_alias_raw(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string name = luaL_checkstring(L, 1); + std::string convert_to = luaL_checkstring(L, 2); + + // Get the writable item definition manager from the server + IWritableItemDefManager *idef = + getServer(L)->getWritableItemDefManager(); + + idef->registerAlias(name, convert_to); + + return 0; /* number of results */ +} + +// get_content_id(name) +int ModApiItemMod::l_get_content_id(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string name = luaL_checkstring(L, 1); + + const IItemDefManager *idef = getGameDef(L)->idef(); + const NodeDefManager *ndef = getGameDef(L)->ndef(); + + // If this is called at mod load time, NodeDefManager isn't aware of + // aliases yet, so we need to handle them manually + std::string alias_name = idef->getAlias(name); + + content_t content_id; + if (alias_name != name) { + if (!ndef->getId(alias_name, content_id)) + throw LuaError("Unknown node: " + alias_name + + " (from alias " + name + ")"); + } else if (!ndef->getId(name, content_id)) { + throw LuaError("Unknown node: " + name); + } + + lua_pushinteger(L, content_id); + return 1; /* number of results */ +} + +// get_name_from_content_id(name) +int ModApiItemMod::l_get_name_from_content_id(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + content_t c = luaL_checkint(L, 1); + + const NodeDefManager *ndef = getGameDef(L)->ndef(); + const char *name = ndef->get(c).name.c_str(); + + lua_pushstring(L, name); + return 1; /* number of results */ +} + +void ModApiItemMod::Initialize(lua_State *L, int top) +{ + API_FCT(register_item_raw); + API_FCT(unregister_item_raw); + API_FCT(register_alias_raw); + API_FCT(get_content_id); + API_FCT(get_name_from_content_id); +} + +void ModApiItemMod::InitializeAsync(lua_State *L, int top) +{ + // all read-only functions + API_FCT(get_content_id); + API_FCT(get_name_from_content_id); +} diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h new file mode 100644 index 0000000..72b1922 --- /dev/null +++ b/src/script/lua_api/l_item.h @@ -0,0 +1,174 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" +#include "inventory.h" // ItemStack +#include "util/pointer.h" + +class LuaItemStack : public ModApiBase, public IntrusiveReferenceCounted { +private: + ItemStack m_stack; + + LuaItemStack(const ItemStack &item); + ~LuaItemStack() = default; + + static const char className[]; + static const luaL_Reg methods[]; + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + // __tostring metamethod + static int mt_tostring(lua_State *L); + + // is_empty(self) -> true/false + static int l_is_empty(lua_State *L); + + // get_name(self) -> string + static int l_get_name(lua_State *L); + + // set_name(self, name) + static int l_set_name(lua_State *L); + + // get_count(self) -> number + static int l_get_count(lua_State *L); + + // set_count(self, number) + static int l_set_count(lua_State *L); + + // get_wear(self) -> number + static int l_get_wear(lua_State *L); + + // set_wear(self, number) + static int l_set_wear(lua_State *L); + + // get_meta(self) -> string + static int l_get_meta(lua_State *L); + + // DEPRECATED + // get_metadata(self) -> string + static int l_get_metadata(lua_State *L); + + // DEPRECATED + // set_metadata(self, string) + static int l_set_metadata(lua_State *L); + + // get_description(self) + static int l_get_description(lua_State *L); + + // get_short_description(self) + static int l_get_short_description(lua_State *L); + + // clear(self) -> true + static int l_clear(lua_State *L); + + // replace(self, itemstack or itemstring or table or nil) -> true + static int l_replace(lua_State *L); + + // to_string(self) -> string + static int l_to_string(lua_State *L); + + // to_table(self) -> table or nil + static int l_to_table(lua_State *L); + + // get_stack_max(self) -> number + static int l_get_stack_max(lua_State *L); + + // get_free_space(self) -> number + static int l_get_free_space(lua_State *L); + + // is_known(self) -> true/false + // Checks if the item is defined. + static int l_is_known(lua_State *L); + + // get_definition(self) -> table + // Returns the item definition table from core.registered_items, + // or a fallback one (name="unknown") + static int l_get_definition(lua_State *L); + + // get_tool_capabilities(self) -> table + // Returns the effective tool digging properties. + // Returns those of the hand ("") if this item has none associated. + static int l_get_tool_capabilities(lua_State *L); + + // add_wear(self, amount) -> true/false + // The range for "amount" is [0,65536]. Wear is only added if the item + // is a tool. Adding wear might destroy the item. + // Returns true if the item is (or was) a tool. + static int l_add_wear(lua_State *L); + + // add_wear_by_uses(self, max_uses) -> true/false + // The range for "max_uses" is [0,65536]. + // Adds wear to the item in such a way that, if + // only this function is called to add wear, the item + // will be destroyed exactly after `max_uses` times of calling it. + // No-op if `max_uses` is 0 or item is not a tool. + // Returns true if the item is (or was) a tool. + static int l_add_wear_by_uses(lua_State *L); + + // add_item(self, itemstack or itemstring or table or nil) -> itemstack + // Returns leftover item stack + static int l_add_item(lua_State *L); + + // item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack + // First return value is true iff the new item fits fully into the stack + // Second return value is the would-be-left-over item stack + static int l_item_fits(lua_State *L); + + // take_item(self, takecount=1) -> itemstack + static int l_take_item(lua_State *L); + + // peek_item(self, peekcount=1) -> itemstack + static int l_peek_item(lua_State *L); + +public: + DISABLE_CLASS_COPY(LuaItemStack) + + inline const ItemStack& getItem() const { return m_stack; } + inline ItemStack& getItem() { return m_stack; } + + // LuaItemStack(itemstack or itemstring or table or nil) + // Creates an LuaItemStack and leaves it on top of stack + static int create_object(lua_State *L); + // Not callable from Lua + static int create(lua_State *L, const ItemStack &item); + static LuaItemStack* checkobject(lua_State *L, int narg); + + static void *packIn(lua_State *L, int idx); + static void packOut(lua_State *L, void *ptr); + + static void Register(lua_State *L); +}; + +class ModApiItemMod : public ModApiBase { +private: + static int l_register_item_raw(lua_State *L); + static int l_unregister_item_raw(lua_State *L); + static int l_register_alias_raw(lua_State *L); + static int l_get_content_id(lua_State *L); + static int l_get_name_from_content_id(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); + static void InitializeAsync(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_itemstackmeta.cpp b/src/script/lua_api/l_itemstackmeta.cpp new file mode 100644 index 0000000..c17bb89 --- /dev/null +++ b/src/script/lua_api/l_itemstackmeta.cpp @@ -0,0 +1,149 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.com> +Copyright (C) 2017 raymoo + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_itemstackmeta.h" +#include "lua_api/l_internal.h" +#include "common/c_content.h" + +/* + NodeMetaRef +*/ +ItemStackMetaRef* ItemStackMetaRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + + return *(ItemStackMetaRef**)ud; // unbox pointer +} + +Metadata* ItemStackMetaRef::getmeta(bool auto_create) +{ + return &istack->getItem().metadata; +} + +void ItemStackMetaRef::clearMeta() +{ + istack->getItem().metadata.clear(); +} + +void ItemStackMetaRef::reportMetadataChange(const std::string *name) +{ + // TODO +} + +// Exported functions +int ItemStackMetaRef::l_set_tool_capabilities(lua_State *L) +{ + ItemStackMetaRef *metaref = checkobject(L, 1); + if (lua_isnoneornil(L, 2)) { + metaref->clearToolCapabilities(); + } else if (lua_istable(L, 2)) { + ToolCapabilities caps = read_tool_capabilities(L, 2); + metaref->setToolCapabilities(caps); + } else { + luaL_typerror(L, 2, "table or nil"); + } + + return 0; +} + +ItemStackMetaRef::ItemStackMetaRef(LuaItemStack *istack): istack(istack) +{ + istack->grab(); +} + +ItemStackMetaRef::~ItemStackMetaRef() +{ + istack->drop(); +} + +// garbage collector +int ItemStackMetaRef::gc_object(lua_State *L) { + ItemStackMetaRef *o = *(ItemStackMetaRef **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +// Creates an NodeMetaRef and leaves it on top of stack +// Not callable from Lua; all references are created on the C side. +void ItemStackMetaRef::create(lua_State *L, LuaItemStack *istack) +{ + ItemStackMetaRef *o = new ItemStackMetaRef(istack); + //infostream<<"NodeMetaRef::create: o="<<o<<std::endl; + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +void ItemStackMetaRef::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "metadata_class"); + lua_pushlstring(L, className, strlen(className)); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pushliteral(L, "__eq"); + lua_pushcfunction(L, l_equals); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // drop methodtable + + // Cannot be created from Lua + //lua_register(L, className, create_object); +} + +const char ItemStackMetaRef::className[] = "ItemStackMetaRef"; +const luaL_Reg ItemStackMetaRef::methods[] = { + luamethod(MetaDataRef, contains), + luamethod(MetaDataRef, get), + luamethod(MetaDataRef, get_string), + luamethod(MetaDataRef, set_string), + luamethod(MetaDataRef, get_int), + luamethod(MetaDataRef, set_int), + luamethod(MetaDataRef, get_float), + luamethod(MetaDataRef, set_float), + luamethod(MetaDataRef, to_table), + luamethod(MetaDataRef, from_table), + luamethod(MetaDataRef, equals), + luamethod(ItemStackMetaRef, set_tool_capabilities), + {0,0} +}; diff --git a/src/script/lua_api/l_itemstackmeta.h b/src/script/lua_api/l_itemstackmeta.h new file mode 100644 index 0000000..68d2ba8 --- /dev/null +++ b/src/script/lua_api/l_itemstackmeta.h @@ -0,0 +1,72 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.com> +Copyright (C) 2017 raymoo + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" +#include "lua_api/l_metadata.h" +#include "lua_api/l_item.h" +#include "irrlichttypes_bloated.h" + +class ItemStackMetaRef : public MetaDataRef +{ +private: + LuaItemStack *istack; + + static const char className[]; + static const luaL_Reg methods[]; + + static ItemStackMetaRef *checkobject(lua_State *L, int narg); + + virtual Metadata* getmeta(bool auto_create); + + virtual void clearMeta(); + + virtual void reportMetadataChange(const std::string *name = nullptr); + + void setToolCapabilities(const ToolCapabilities &caps) + { + istack->getItem().metadata.setToolCapabilities(caps); + } + + void clearToolCapabilities() + { + istack->getItem().metadata.clearToolCapabilities(); + } + + // Exported functions + static int l_set_tool_capabilities(lua_State *L); + + // garbage collector + static int gc_object(lua_State *L); +public: + // takes a reference + ItemStackMetaRef(LuaItemStack *istack); + ~ItemStackMetaRef(); + + DISABLE_CLASS_COPY(ItemStackMetaRef) + + // Creates an ItemStackMetaRef and leaves it on top of stack + // Not callable from Lua; all references are created on the C side. + static void create(lua_State *L, LuaItemStack *istack); + + static void Register(lua_State *L); +}; diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp new file mode 100644 index 0000000..2efb976 --- /dev/null +++ b/src/script/lua_api/l_localplayer.cpp @@ -0,0 +1,495 @@ +/* +Minetest +Copyright (C) 2017 Dumbeldor, Vincent Glize <vincent.glize@live.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "l_localplayer.h" +#include "l_internal.h" +#include "lua_api/l_item.h" +#include "script/common/c_converter.h" +#include "client/localplayer.h" +#include "hud.h" +#include "common/c_content.h" +#include "client/content_cao.h" + +LuaLocalPlayer::LuaLocalPlayer(LocalPlayer *m) : m_localplayer(m) +{ +} + +void LuaLocalPlayer::create(lua_State *L, LocalPlayer *m) +{ + lua_getglobal(L, "core"); + luaL_checktype(L, -1, LUA_TTABLE); + int objectstable = lua_gettop(L); + lua_getfield(L, -1, "localplayer"); + + // Duplication check + if (lua_type(L, -1) == LUA_TUSERDATA) { + lua_pop(L, 1); + return; + } + + LuaLocalPlayer *o = new LuaLocalPlayer(m); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + + lua_pushvalue(L, lua_gettop(L)); + lua_setfield(L, objectstable, "localplayer"); +} + +int LuaLocalPlayer::l_get_velocity(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + push_v3f(L, player->getSpeed() / BS); + return 1; +} + +int LuaLocalPlayer::l_get_hp(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushinteger(L, player->hp); + return 1; +} + +int LuaLocalPlayer::l_get_name(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushstring(L, player->getName()); + return 1; +} + +// get_wield_index(self) +int LuaLocalPlayer::l_get_wield_index(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushinteger(L, player->getWieldIndex()); + return 1; +} + +// get_wielded_item(self) +int LuaLocalPlayer::l_get_wielded_item(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + ItemStack selected_item; + player->getWieldedItem(&selected_item, nullptr); + LuaItemStack::create(L, selected_item); + return 1; +} + +int LuaLocalPlayer::l_is_attached(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->getParent() != nullptr); + return 1; +} + +int LuaLocalPlayer::l_is_touching_ground(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->touching_ground); + return 1; +} + +int LuaLocalPlayer::l_is_in_liquid(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->in_liquid); + return 1; +} + +int LuaLocalPlayer::l_is_in_liquid_stable(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->in_liquid_stable); + return 1; +} + +int LuaLocalPlayer::l_get_move_resistance(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushinteger(L, player->move_resistance); + return 1; +} + +int LuaLocalPlayer::l_is_climbing(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->is_climbing); + return 1; +} + +int LuaLocalPlayer::l_swimming_vertical(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->swimming_vertical); + return 1; +} + +// get_physics_override(self) +int LuaLocalPlayer::l_get_physics_override(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_newtable(L); + lua_pushnumber(L, player->physics_override_speed); + lua_setfield(L, -2, "speed"); + + lua_pushnumber(L, player->physics_override_jump); + lua_setfield(L, -2, "jump"); + + lua_pushnumber(L, player->physics_override_gravity); + lua_setfield(L, -2, "gravity"); + + lua_pushboolean(L, player->physics_override_sneak); + lua_setfield(L, -2, "sneak"); + + lua_pushboolean(L, player->physics_override_sneak_glitch); + lua_setfield(L, -2, "sneak_glitch"); + + lua_pushboolean(L, player->physics_override_new_move); + lua_setfield(L, -2, "new_move"); + + return 1; +} + +int LuaLocalPlayer::l_get_last_pos(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + push_v3f(L, player->last_position / BS); + return 1; +} + +int LuaLocalPlayer::l_get_last_velocity(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + push_v3f(L, player->last_speed); + return 1; +} + +int LuaLocalPlayer::l_get_last_look_vertical(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushnumber(L, -1.0 * player->last_pitch * core::DEGTORAD); + return 1; +} + +int LuaLocalPlayer::l_get_last_look_horizontal(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushnumber(L, (player->last_yaw + 90.) * core::DEGTORAD); + return 1; +} + +// get_control(self) +int LuaLocalPlayer::l_get_control(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + const PlayerControl &c = player->getPlayerControl(); + + auto set = [L] (const char *name, bool value) { + lua_pushboolean(L, value); + lua_setfield(L, -2, name); + }; + + lua_createtable(L, 0, 12); + set("jump", c.jump); + set("aux1", c.aux1); + set("sneak", c.sneak); + set("zoom", c.zoom); + set("dig", c.dig); + set("place", c.place); + // Player movement in polar coordinates and non-binary speed + lua_pushnumber(L, c.movement_speed); + lua_setfield(L, -2, "movement_speed"); + lua_pushnumber(L, c.movement_direction); + lua_setfield(L, -2, "movement_direction"); + // Provide direction keys to ensure compatibility + set("up", c.direction_keys & (1 << 0)); + set("down", c.direction_keys & (1 << 1)); + set("left", c.direction_keys & (1 << 2)); + set("right", c.direction_keys & (1 << 3)); + + return 1; +} + +// get_breath(self) +int LuaLocalPlayer::l_get_breath(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushinteger(L, player->getBreath()); + return 1; +} + +// get_pos(self) +int LuaLocalPlayer::l_get_pos(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + push_v3f(L, player->getPosition() / BS); + return 1; +} + +// get_movement_acceleration(self) +int LuaLocalPlayer::l_get_movement_acceleration(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_newtable(L); + lua_pushnumber(L, player->movement_acceleration_default); + lua_setfield(L, -2, "default"); + + lua_pushnumber(L, player->movement_acceleration_air); + lua_setfield(L, -2, "air"); + + lua_pushnumber(L, player->movement_acceleration_fast); + lua_setfield(L, -2, "fast"); + + return 1; +} + +// get_movement_speed(self) +int LuaLocalPlayer::l_get_movement_speed(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_newtable(L); + lua_pushnumber(L, player->movement_speed_walk); + lua_setfield(L, -2, "walk"); + + lua_pushnumber(L, player->movement_speed_crouch); + lua_setfield(L, -2, "crouch"); + + lua_pushnumber(L, player->movement_speed_fast); + lua_setfield(L, -2, "fast"); + + lua_pushnumber(L, player->movement_speed_climb); + lua_setfield(L, -2, "climb"); + + lua_pushnumber(L, player->movement_speed_jump); + lua_setfield(L, -2, "jump"); + + return 1; +} + +// get_movement(self) +int LuaLocalPlayer::l_get_movement(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_newtable(L); + + lua_pushnumber(L, player->movement_liquid_fluidity); + lua_setfield(L, -2, "liquid_fluidity"); + + lua_pushnumber(L, player->movement_liquid_fluidity_smooth); + lua_setfield(L, -2, "liquid_fluidity_smooth"); + + lua_pushnumber(L, player->movement_liquid_sink); + lua_setfield(L, -2, "liquid_sink"); + + lua_pushnumber(L, player->movement_gravity); + lua_setfield(L, -2, "gravity"); + + return 1; +} + +// get_armor_groups(self) +int LuaLocalPlayer::l_get_armor_groups(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + push_groups(L, player->getCAO()->getGroups()); + return 1; +} + +// hud_add(self, form) +int LuaLocalPlayer::l_hud_add(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + HudElement *elem = new HudElement; + read_hud_element(L, elem); + + u32 id = player->addHud(elem); + if (id == U32_MAX) { + delete elem; + return 0; + } + lua_pushnumber(L, id); + return 1; +} + +// hud_remove(self, id) +int LuaLocalPlayer::l_hud_remove(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + u32 id = luaL_checkinteger(L, 2); + HudElement *element = player->removeHud(id); + if (!element) + lua_pushboolean(L, false); + else + lua_pushboolean(L, true); + delete element; + return 1; +} + +// hud_change(self, id, stat, data) +int LuaLocalPlayer::l_hud_change(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + u32 id = luaL_checkinteger(L, 2); + + HudElement *element = player->getHud(id); + if (!element) + return 0; + + HudElementStat stat; + void *unused; + bool ok = read_hud_change(L, stat, element, &unused); + + lua_pushboolean(L, ok); + return 1; +} + +// hud_get(self, id) +int LuaLocalPlayer::l_hud_get(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + u32 id = luaL_checkinteger(L, -1); + + HudElement *e = player->getHud(id); + if (!e) { + lua_pushnil(L); + return 1; + } + + push_hud_element(L, e); + return 1; +} + +LuaLocalPlayer *LuaLocalPlayer::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + + return *(LuaLocalPlayer **)ud; +} + +LocalPlayer *LuaLocalPlayer::getobject(LuaLocalPlayer *ref) +{ + return ref->m_localplayer; +} + +LocalPlayer *LuaLocalPlayer::getobject(lua_State *L, int narg) +{ + LuaLocalPlayer *ref = checkobject(L, narg); + assert(ref); + LocalPlayer *player = getobject(ref); + assert(player); + return player; +} + +int LuaLocalPlayer::gc_object(lua_State *L) +{ + LuaLocalPlayer *o = *(LuaLocalPlayer **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +void LuaLocalPlayer::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from lua getmetatable() + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); // Drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // Drop methodtable +} + +const char LuaLocalPlayer::className[] = "LocalPlayer"; +const luaL_Reg LuaLocalPlayer::methods[] = { + luamethod(LuaLocalPlayer, get_velocity), + luamethod(LuaLocalPlayer, get_hp), + luamethod(LuaLocalPlayer, get_name), + luamethod(LuaLocalPlayer, get_wield_index), + luamethod(LuaLocalPlayer, get_wielded_item), + luamethod(LuaLocalPlayer, is_attached), + luamethod(LuaLocalPlayer, is_touching_ground), + luamethod(LuaLocalPlayer, is_in_liquid), + luamethod(LuaLocalPlayer, is_in_liquid_stable), + luamethod(LuaLocalPlayer, is_climbing), + luamethod(LuaLocalPlayer, swimming_vertical), + luamethod(LuaLocalPlayer, get_physics_override), + // TODO: figure our if these are useful in any way + luamethod(LuaLocalPlayer, get_last_pos), + luamethod(LuaLocalPlayer, get_last_velocity), + luamethod(LuaLocalPlayer, get_last_look_horizontal), + luamethod(LuaLocalPlayer, get_last_look_vertical), + // + luamethod(LuaLocalPlayer, get_control), + luamethod(LuaLocalPlayer, get_breath), + luamethod(LuaLocalPlayer, get_pos), + luamethod(LuaLocalPlayer, get_movement_acceleration), + luamethod(LuaLocalPlayer, get_movement_speed), + luamethod(LuaLocalPlayer, get_movement), + luamethod(LuaLocalPlayer, get_armor_groups), + luamethod(LuaLocalPlayer, hud_add), + luamethod(LuaLocalPlayer, hud_remove), + luamethod(LuaLocalPlayer, hud_change), + luamethod(LuaLocalPlayer, hud_get), + + luamethod(LuaLocalPlayer, get_move_resistance), + + {0, 0} +}; diff --git a/src/script/lua_api/l_localplayer.h b/src/script/lua_api/l_localplayer.h new file mode 100644 index 0000000..041545a --- /dev/null +++ b/src/script/lua_api/l_localplayer.h @@ -0,0 +1,113 @@ +/* +Minetest +Copyright (C) 2017 Dumbeldor, Vincent Glize <vincent.glize@live.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "l_base.h" + +class LocalPlayer; + +class LuaLocalPlayer : public ModApiBase +{ +private: + static const char className[]; + static const luaL_Reg methods[]; + + // garbage collector + static int gc_object(lua_State *L); + + // get_velocity(self) + static int l_get_velocity(lua_State *L); + + // get_hp(self) + static int l_get_hp(lua_State *L); + + // get_name(self) + static int l_get_name(lua_State *L); + + // get_wield_index(self) + static int l_get_wield_index(lua_State *L); + + // get_wielded_item(self) + static int l_get_wielded_item(lua_State *L); + + static int l_is_attached(lua_State *L); + static int l_is_touching_ground(lua_State *L); + static int l_is_in_liquid(lua_State *L); + static int l_is_in_liquid_stable(lua_State *L); + static int l_is_climbing(lua_State *L); + static int l_swimming_vertical(lua_State *L); + + static int l_get_physics_override(lua_State *L); + + static int l_get_override_pos(lua_State *L); + + static int l_get_last_pos(lua_State *L); + static int l_get_last_velocity(lua_State *L); + static int l_get_last_look_vertical(lua_State *L); + static int l_get_last_look_horizontal(lua_State *L); + + // get_control(self) + static int l_get_control(lua_State *L); + + // get_breath(self) + static int l_get_breath(lua_State *L); + + // get_pos(self) + static int l_get_pos(lua_State *L); + + // get_movement_acceleration(self) + static int l_get_movement_acceleration(lua_State *L); + + // get_movement_speed(self) + static int l_get_movement_speed(lua_State *L); + + // get_movement(self) + static int l_get_movement(lua_State *L); + + // get_armor_groups(self) + static int l_get_armor_groups(lua_State *L); + + // hud_add(self, id, form) + static int l_hud_add(lua_State *L); + + // hud_rm(self, id) + static int l_hud_remove(lua_State *L); + + // hud_change(self, id, stat, data) + static int l_hud_change(lua_State *L); + // hud_get(self, id) + static int l_hud_get(lua_State *L); + + static int l_get_move_resistance(lua_State *L); + + LocalPlayer *m_localplayer = nullptr; + +public: + LuaLocalPlayer(LocalPlayer *m); + ~LuaLocalPlayer() = default; + + static void create(lua_State *L, LocalPlayer *m); + + static LuaLocalPlayer *checkobject(lua_State *L, int narg); + static LocalPlayer *getobject(LuaLocalPlayer *ref); + static LocalPlayer *getobject(lua_State *L, int narg); + + static void Register(lua_State *L); +}; diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp new file mode 100644 index 0000000..cf4a057 --- /dev/null +++ b/src/script/lua_api/l_mainmenu.cpp @@ -0,0 +1,1081 @@ +/* +Minetest +Copyright (C) 2013 sapier + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_mainmenu.h" +#include "lua_api/l_internal.h" +#include "common/c_content.h" +#include "cpp_api/s_async.h" +#include "scripting_mainmenu.h" +#include "gui/guiEngine.h" +#include "gui/guiMainMenu.h" +#include "gui/guiKeyChangeMenu.h" +#include "gui/guiPathSelectMenu.h" +#include "version.h" +#include "porting.h" +#include "filesys.h" +#include "convert_json.h" +#include "content/content.h" +#include "content/subgames.h" +#include "serverlist.h" +#include "mapgen/mapgen.h" +#include "settings.h" +#include "client/client.h" +#include "client/renderingengine.h" +#include "network/networkprotocol.h" +#include "content/mod_configuration.h" + +/******************************************************************************/ +std::string ModApiMainMenu::getTextData(lua_State *L, std::string name) +{ + lua_getglobal(L, "gamedata"); + + lua_getfield(L, -1, name.c_str()); + + if(lua_isnil(L, -1)) + return ""; + + return luaL_checkstring(L, -1); +} + +/******************************************************************************/ +int ModApiMainMenu::getIntegerData(lua_State *L, std::string name,bool& valid) +{ + lua_getglobal(L, "gamedata"); + + lua_getfield(L, -1, name.c_str()); + + if(lua_isnil(L, -1)) { + valid = false; + return -1; + } + + valid = true; + return luaL_checkinteger(L, -1); +} + +/******************************************************************************/ +int ModApiMainMenu::getBoolData(lua_State *L, std::string name,bool& valid) +{ + lua_getglobal(L, "gamedata"); + + lua_getfield(L, -1, name.c_str()); + + if(lua_isnil(L, -1)) { + valid = false; + return false; + } + + valid = true; + return readParam<bool>(L, -1); +} + +/******************************************************************************/ +int ModApiMainMenu::l_update_formspec(lua_State *L) +{ + GUIEngine* engine = getGuiEngine(L); + sanity_check(engine != NULL); + + if (engine->m_startgame) + return 0; + + //read formspec + std::string formspec(luaL_checkstring(L, 1)); + + if (engine->m_formspecgui != 0) { + engine->m_formspecgui->setForm(formspec); + } + + return 0; +} + +/******************************************************************************/ +int ModApiMainMenu::l_set_formspec_prepend(lua_State *L) +{ + GUIEngine *engine = getGuiEngine(L); + sanity_check(engine != NULL); + + if (engine->m_startgame) + return 0; + + std::string formspec(luaL_checkstring(L, 1)); + engine->setFormspecPrepend(formspec); + + return 0; +} + +/******************************************************************************/ +int ModApiMainMenu::l_start(lua_State *L) +{ + GUIEngine* engine = getGuiEngine(L); + sanity_check(engine != NULL); + + //update c++ gamedata from lua table + + bool valid = false; + + MainMenuData *data = engine->m_data; + + data->selected_world = getIntegerData(L, "selected_world",valid) -1; + data->simple_singleplayer_mode = getBoolData(L,"singleplayer",valid); + data->do_reconnect = getBoolData(L, "do_reconnect", valid); + if (!data->do_reconnect) { + data->name = getTextData(L,"playername"); + data->password = getTextData(L,"password"); + data->address = getTextData(L,"address"); + data->port = getTextData(L,"port"); + + const auto val = getTextData(L, "allow_login_or_register"); + if (val == "login") + data->allow_login_or_register = ELoginRegister::Login; + else if (val == "register") + data->allow_login_or_register = ELoginRegister::Register; + else + data->allow_login_or_register = ELoginRegister::Any; + } + data->serverdescription = getTextData(L,"serverdescription"); + data->servername = getTextData(L,"servername"); + + //close menu next time + engine->m_startgame = true; + return 0; +} + +/******************************************************************************/ +int ModApiMainMenu::l_close(lua_State *L) +{ + GUIEngine* engine = getGuiEngine(L); + sanity_check(engine != NULL); + + engine->m_kill = true; + return 0; +} + +/******************************************************************************/ +int ModApiMainMenu::l_set_background(lua_State *L) +{ + GUIEngine* engine = getGuiEngine(L); + sanity_check(engine != NULL); + + std::string backgroundlevel(luaL_checkstring(L, 1)); + std::string texturename(luaL_checkstring(L, 2)); + + bool tile_image = false; + bool retval = false; + unsigned int minsize = 16; + + if (!lua_isnone(L, 3)) { + tile_image = readParam<bool>(L, 3); + } + + if (!lua_isnone(L, 4)) { + minsize = lua_tonumber(L, 4); + } + + if (backgroundlevel == "background") { + retval |= engine->setTexture(TEX_LAYER_BACKGROUND, texturename, + tile_image, minsize); + } + + if (backgroundlevel == "overlay") { + retval |= engine->setTexture(TEX_LAYER_OVERLAY, texturename, + tile_image, minsize); + } + + if (backgroundlevel == "header") { + retval |= engine->setTexture(TEX_LAYER_HEADER, texturename, + tile_image, minsize); + } + + if (backgroundlevel == "footer") { + retval |= engine->setTexture(TEX_LAYER_FOOTER, texturename, + tile_image, minsize); + } + + lua_pushboolean(L,retval); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_set_clouds(lua_State *L) +{ + GUIEngine* engine = getGuiEngine(L); + sanity_check(engine != NULL); + + bool value = readParam<bool>(L,1); + + engine->m_clouds_enabled = value; + + return 0; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_textlist_index(lua_State *L) +{ + // get_table_index accepts both tables and textlists + return l_get_table_index(L); +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_table_index(lua_State *L) +{ + GUIEngine* engine = getGuiEngine(L); + sanity_check(engine != NULL); + + std::string tablename(luaL_checkstring(L, 1)); + GUITable *table = engine->m_menu->getTable(tablename); + s32 selection = table ? table->getSelected() : 0; + + if (selection >= 1) + lua_pushinteger(L, selection); + else + lua_pushnil(L); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_worlds(lua_State *L) +{ + std::vector<WorldSpec> worlds = getAvailableWorlds(); + + lua_newtable(L); + int top = lua_gettop(L); + unsigned int index = 1; + + for (const WorldSpec &world : worlds) { + lua_pushnumber(L,index); + + lua_newtable(L); + int top_lvl2 = lua_gettop(L); + + lua_pushstring(L,"path"); + lua_pushstring(L, world.path.c_str()); + lua_settable(L, top_lvl2); + + lua_pushstring(L,"name"); + lua_pushstring(L, world.name.c_str()); + lua_settable(L, top_lvl2); + + lua_pushstring(L,"gameid"); + lua_pushstring(L, world.gameid.c_str()); + lua_settable(L, top_lvl2); + + lua_settable(L, top); + index++; + } + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_games(lua_State *L) +{ + std::vector<SubgameSpec> games = getAvailableGames(); + + lua_newtable(L); + int top = lua_gettop(L); + unsigned int index = 1; + + for (const SubgameSpec &game : games) { + lua_pushnumber(L, index); + lua_newtable(L); + int top_lvl2 = lua_gettop(L); + + lua_pushstring(L, "id"); + lua_pushstring(L, game.id.c_str()); + lua_settable(L, top_lvl2); + + lua_pushstring(L, "path"); + lua_pushstring(L, game.path.c_str()); + lua_settable(L, top_lvl2); + + lua_pushstring(L, "type"); + lua_pushstring(L, "game"); + lua_settable(L, top_lvl2); + + lua_pushstring(L, "gamemods_path"); + lua_pushstring(L, game.gamemods_path.c_str()); + lua_settable(L, top_lvl2); + + lua_pushstring(L, "name"); + lua_pushstring(L, game.title.c_str()); + lua_settable(L, top_lvl2); + + lua_pushstring(L, "title"); + lua_pushstring(L, game.title.c_str()); + lua_settable(L, top_lvl2); + + lua_pushstring(L, "author"); + lua_pushstring(L, game.author.c_str()); + lua_settable(L, top_lvl2); + + lua_pushstring(L, "release"); + lua_pushinteger(L, game.release); + lua_settable(L, top_lvl2); + + lua_pushstring(L, "menuicon_path"); + lua_pushstring(L, game.menuicon_path.c_str()); + lua_settable(L, top_lvl2); + + lua_pushstring(L, "addon_mods_paths"); + lua_newtable(L); + int table2 = lua_gettop(L); + int internal_index = 1; + for (const auto &addon_mods_path : game.addon_mods_paths) { + lua_pushnumber(L, internal_index); + lua_pushstring(L, addon_mods_path.second.c_str()); + lua_settable(L, table2); + internal_index++; + } + lua_settable(L, top_lvl2); + lua_settable(L, top); + index++; + } + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_content_info(lua_State *L) +{ + std::string path = luaL_checkstring(L, 1); + + ContentSpec spec; + spec.path = path; + parseContentInfo(spec); + + lua_newtable(L); + + lua_pushstring(L, spec.name.c_str()); + lua_setfield(L, -2, "name"); + + lua_pushstring(L, spec.type.c_str()); + lua_setfield(L, -2, "type"); + + lua_pushstring(L, spec.author.c_str()); + lua_setfield(L, -2, "author"); + + if (!spec.title.empty()) { + lua_pushstring(L, spec.title.c_str()); + lua_setfield(L, -2, "title"); + } + + lua_pushinteger(L, spec.release); + lua_setfield(L, -2, "release"); + + lua_pushstring(L, spec.desc.c_str()); + lua_setfield(L, -2, "description"); + + lua_pushstring(L, spec.path.c_str()); + lua_setfield(L, -2, "path"); + + if (spec.type == "mod") { + ModSpec spec; + spec.path = path; + parseModContents(spec); + + // Dependencies + lua_newtable(L); + int i = 1; + for (const auto &dep : spec.depends) { + lua_pushstring(L, dep.c_str()); + lua_rawseti(L, -2, i++); + } + lua_setfield(L, -2, "depends"); + + // Optional Dependencies + lua_newtable(L); + i = 1; + for (const auto &dep : spec.optdepends) { + lua_pushstring(L, dep.c_str()); + lua_rawseti(L, -2, i++); + } + lua_setfield(L, -2, "optional_depends"); + } + + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_check_mod_configuration(lua_State *L) +{ + std::string worldpath = luaL_checkstring(L, 1); + + ModConfiguration modmgr; + + // Add all game mods + SubgameSpec gamespec = findWorldSubgame(worldpath); + modmgr.addGameMods(gamespec); + modmgr.addModsInPath(worldpath + DIR_DELIM + "worldmods", "worldmods"); + + // Add user-configured mods + std::vector<ModSpec> modSpecs; + + luaL_checktype(L, 2, LUA_TTABLE); + + lua_pushnil(L); + while (lua_next(L, 2)) { + // Ignore non-string keys + if (lua_type(L, -2) != LUA_TSTRING) { + throw LuaError( + "Unexpected non-string key in table passed to " + "core.check_mod_configuration"); + } + + std::string modpath = luaL_checkstring(L, -1); + lua_pop(L, 1); + std::string virtual_path = lua_tostring(L, -1); + + modSpecs.emplace_back(); + ModSpec &spec = modSpecs.back(); + spec.name = fs::GetFilenameFromPath(modpath.c_str()); + spec.path = modpath; + spec.virtual_path = virtual_path; + if (!parseModContents(spec)) { + throw LuaError("Not a mod!"); + } + } + + modmgr.addMods(modSpecs); + try { + modmgr.checkConflictsAndDeps(); + } catch (const ModError &err) { + errorstream << err.what() << std::endl; + + lua_newtable(L); + + lua_pushboolean(L, false); + lua_setfield(L, -2, "is_consistent"); + + lua_newtable(L); + lua_setfield(L, -2, "unsatisfied_mods"); + + lua_newtable(L); + lua_setfield(L, -2, "satisfied_mods"); + + lua_pushstring(L, err.what()); + lua_setfield(L, -2, "error_message"); + return 1; + } + + + lua_newtable(L); + + lua_pushboolean(L, modmgr.isConsistent()); + lua_setfield(L, -2, "is_consistent"); + + lua_newtable(L); + int top = lua_gettop(L); + unsigned int index = 1; + for (const auto &spec : modmgr.getUnsatisfiedMods()) { + lua_pushnumber(L, index); + push_mod_spec(L, spec, true); + lua_settable(L, top); + index++; + } + + lua_setfield(L, -2, "unsatisfied_mods"); + + lua_newtable(L); + top = lua_gettop(L); + index = 1; + for (const auto &spec : modmgr.getMods()) { + lua_pushnumber(L, index); + push_mod_spec(L, spec, false); + lua_settable(L, top); + index++; + } + lua_setfield(L, -2, "satisfied_mods"); + + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_show_keys_menu(lua_State *L) +{ + GUIEngine* engine = getGuiEngine(L); + sanity_check(engine != NULL); + + GUIKeyChangeMenu *kmenu = new GUIKeyChangeMenu( + engine->m_rendering_engine->get_gui_env(), + engine->m_parent, + -1, + engine->m_menumanager, + engine->m_texture_source); + kmenu->drop(); + return 0; +} + +/******************************************************************************/ +int ModApiMainMenu::l_create_world(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + int gameidx = luaL_checkinteger(L,2) -1; + + StringMap use_settings; + luaL_checktype(L, 3, LUA_TTABLE); + lua_pushnil(L); + while (lua_next(L, 3) != 0) { + // key at index -2 and value at index -1 + use_settings[luaL_checkstring(L, -2)] = luaL_checkstring(L, -1); + lua_pop(L, 1); + } + lua_pop(L, 1); + + std::string path = porting::path_user + DIR_DELIM + "worlds" + DIR_DELIM + + sanitizeDirName(name, "world_"); + + std::vector<SubgameSpec> games = getAvailableGames(); + if (gameidx < 0 || gameidx >= (int) games.size()) { + lua_pushstring(L, "Invalid game index"); + return 1; + } + + // Set the settings for world creation + // this is a bad hack but the best we have right now.. + StringMap backup; + for (auto it : use_settings) { + if (g_settings->existsLocal(it.first)) + backup[it.first] = g_settings->get(it.first); + g_settings->set(it.first, it.second); + } + + // Create world if it doesn't exist + try { + loadGameConfAndInitWorld(path, name, games[gameidx], true); + lua_pushnil(L); + } catch (const BaseException &e) { + auto err = std::string("Failed to initialize world: ") + e.what(); + lua_pushstring(L, err.c_str()); + } + + // Restore previous settings + for (auto it : use_settings) { + auto it2 = backup.find(it.first); + if (it2 == backup.end()) + g_settings->remove(it.first); // wasn't set before + else + g_settings->set(it.first, it2->second); // was set before + } + + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_delete_world(lua_State *L) +{ + int world_id = luaL_checkinteger(L, 1) - 1; + std::vector<WorldSpec> worlds = getAvailableWorlds(); + if (world_id < 0 || world_id >= (int) worlds.size()) { + lua_pushstring(L, "Invalid world index"); + return 1; + } + const WorldSpec &spec = worlds[world_id]; + if (!fs::RecursiveDelete(spec.path)) { + lua_pushstring(L, "Failed to delete world"); + return 1; + } + return 0; +} + +/******************************************************************************/ +int ModApiMainMenu::l_set_topleft_text(lua_State *L) +{ + GUIEngine* engine = getGuiEngine(L); + sanity_check(engine != NULL); + + std::string text; + + if (!lua_isnone(L,1) && !lua_isnil(L,1)) + text = luaL_checkstring(L, 1); + + engine->setTopleftText(text); + return 0; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_mapgen_names(lua_State *L) +{ + std::vector<const char *> names; + bool include_hidden = lua_isboolean(L, 1) && readParam<bool>(L, 1); + Mapgen::getMapgenNames(&names, include_hidden); + + lua_newtable(L); + for (size_t i = 0; i != names.size(); i++) { + lua_pushstring(L, names[i]); + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + + +/******************************************************************************/ +int ModApiMainMenu::l_get_user_path(lua_State *L) +{ + std::string path = fs::RemoveRelativePathComponents(porting::path_user); + lua_pushstring(L, path.c_str()); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_modpath(lua_State *L) +{ + std::string modpath = fs::RemoveRelativePathComponents( + porting::path_user + DIR_DELIM + "mods" + DIR_DELIM); + lua_pushstring(L, modpath.c_str()); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_modpaths(lua_State *L) +{ + lua_newtable(L); + + ModApiMainMenu::l_get_modpath(L); + lua_setfield(L, -2, "mods"); + + for (const std::string &component : getEnvModPaths()) { + lua_pushstring(L, component.c_str()); + lua_setfield(L, -2, fs::AbsolutePath(component).c_str()); + } + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_clientmodpath(lua_State *L) +{ + std::string modpath = fs::RemoveRelativePathComponents( + porting::path_user + DIR_DELIM + "clientmods" + DIR_DELIM); + lua_pushstring(L, modpath.c_str()); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_gamepath(lua_State *L) +{ + std::string gamepath = fs::RemoveRelativePathComponents( + porting::path_user + DIR_DELIM + "games" + DIR_DELIM); + lua_pushstring(L, gamepath.c_str()); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_texturepath(lua_State *L) +{ + std::string gamepath = fs::RemoveRelativePathComponents( + porting::path_user + DIR_DELIM + "textures"); + lua_pushstring(L, gamepath.c_str()); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_texturepath_share(lua_State *L) +{ + std::string gamepath = fs::RemoveRelativePathComponents( + porting::path_share + DIR_DELIM + "textures"); + lua_pushstring(L, gamepath.c_str()); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_cache_path(lua_State *L) +{ + lua_pushstring(L, fs::RemoveRelativePathComponents(porting::path_cache).c_str()); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_temp_path(lua_State *L) +{ + if (lua_isnoneornil(L, 1) || !lua_toboolean(L, 1)) + lua_pushstring(L, fs::TempPath().c_str()); + else + lua_pushstring(L, fs::CreateTempFile().c_str()); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_create_dir(lua_State *L) { + const char *path = luaL_checkstring(L, 1); + + if (ModApiMainMenu::mayModifyPath(path)) { + lua_pushboolean(L, fs::CreateAllDirs(path)); + return 1; + } + + lua_pushboolean(L, false); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_delete_dir(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + + std::string absolute_path = fs::RemoveRelativePathComponents(path); + + if (ModApiMainMenu::mayModifyPath(absolute_path)) { + lua_pushboolean(L, fs::RecursiveDelete(absolute_path)); + return 1; + } + + lua_pushboolean(L, false); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_copy_dir(lua_State *L) +{ + const char *source = luaL_checkstring(L, 1); + const char *destination = luaL_checkstring(L, 2); + + bool keep_source = true; + if (!lua_isnoneornil(L, 3)) + keep_source = readParam<bool>(L, 3); + + std::string abs_destination = fs::RemoveRelativePathComponents(destination); + std::string abs_source = fs::RemoveRelativePathComponents(source); + + if (!ModApiMainMenu::mayModifyPath(abs_destination) || + (!keep_source && !ModApiMainMenu::mayModifyPath(abs_source))) { + lua_pushboolean(L, false); + return 1; + } + + bool retval; + if (keep_source) + retval = fs::CopyDir(abs_source, abs_destination); + else + retval = fs::MoveDir(abs_source, abs_destination); + lua_pushboolean(L, retval); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_is_dir(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + + lua_pushboolean(L, fs::IsDir(path)); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_extract_zip(lua_State *L) +{ + const char *zipfile = luaL_checkstring(L, 1); + const char *destination = luaL_checkstring(L, 2); + + std::string absolute_destination = fs::RemoveRelativePathComponents(destination); + + if (ModApiMainMenu::mayModifyPath(absolute_destination)) { + auto fs = RenderingEngine::get_raw_device()->getFileSystem(); + bool ok = fs::extractZipFile(fs, zipfile, destination); + lua_pushboolean(L, ok); + return 1; + } + + lua_pushboolean(L,false); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_mainmenu_path(lua_State *L) +{ + GUIEngine* engine = getGuiEngine(L); + sanity_check(engine != NULL); + + lua_pushstring(L,engine->getScriptDir().c_str()); + return 1; +} + +/******************************************************************************/ +bool ModApiMainMenu::mayModifyPath(std::string path) +{ + path = fs::RemoveRelativePathComponents(path); + + if (fs::PathStartsWith(path, fs::TempPath())) + return true; + + std::string path_user = fs::RemoveRelativePathComponents(porting::path_user); + + if (fs::PathStartsWith(path, path_user + DIR_DELIM "client")) + return true; + if (fs::PathStartsWith(path, path_user + DIR_DELIM "games")) + return true; + if (fs::PathStartsWith(path, path_user + DIR_DELIM "mods")) + return true; + if (fs::PathStartsWith(path, path_user + DIR_DELIM "textures")) + return true; + if (fs::PathStartsWith(path, path_user + DIR_DELIM "worlds")) + return true; + + if (fs::PathStartsWith(path, fs::RemoveRelativePathComponents(porting::path_cache))) + return true; + + return false; +} + + +/******************************************************************************/ +int ModApiMainMenu::l_may_modify_path(lua_State *L) +{ + const char *target = luaL_checkstring(L, 1); + std::string absolute_destination = fs::RemoveRelativePathComponents(target); + lua_pushboolean(L, ModApiMainMenu::mayModifyPath(absolute_destination)); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_show_path_select_dialog(lua_State *L) +{ + GUIEngine* engine = getGuiEngine(L); + sanity_check(engine != NULL); + + const char *formname= luaL_checkstring(L, 1); + const char *title = luaL_checkstring(L, 2); + bool is_file_select = readParam<bool>(L, 3); + + GUIFileSelectMenu* fileOpenMenu = + new GUIFileSelectMenu(engine->m_rendering_engine->get_gui_env(), + engine->m_parent, + -1, + engine->m_menumanager, + title, + formname, + is_file_select); + fileOpenMenu->setTextDest(engine->m_buttonhandler); + fileOpenMenu->drop(); + return 0; +} + +/******************************************************************************/ +int ModApiMainMenu::l_download_file(lua_State *L) +{ + const char *url = luaL_checkstring(L, 1); + const char *target = luaL_checkstring(L, 2); + + //check path + std::string absolute_destination = fs::RemoveRelativePathComponents(target); + + if (ModApiMainMenu::mayModifyPath(absolute_destination)) { + if (GUIEngine::downloadFile(url,absolute_destination)) { + lua_pushboolean(L,true); + return 1; + } + } else { + errorstream << "DOWNLOAD denied: " << absolute_destination + << " isn't a allowed path" << std::endl; + } + lua_pushboolean(L,false); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_video_drivers(lua_State *L) +{ + std::vector<irr::video::E_DRIVER_TYPE> drivers = RenderingEngine::getSupportedVideoDrivers(); + + lua_newtable(L); + for (u32 i = 0; i != drivers.size(); i++) { + auto &info = RenderingEngine::getVideoDriverInfo(drivers[i]); + + lua_newtable(L); + lua_pushstring(L, info.name.c_str()); + lua_setfield(L, -2, "name"); + lua_pushstring(L, info.friendly_name.c_str()); + lua_setfield(L, -2, "friendly_name"); + + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_gettext(lua_State *L) +{ + const char *srctext = luaL_checkstring(L, 1); + const char *text = *srctext ? gettext(srctext) : ""; + lua_pushstring(L, text); + + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_screen_info(lua_State *L) +{ + lua_newtable(L); + int top = lua_gettop(L); + lua_pushstring(L,"density"); + lua_pushnumber(L,RenderingEngine::getDisplayDensity()); + lua_settable(L, top); + + const v2u32 &window_size = RenderingEngine::getWindowSize(); + lua_pushstring(L,"window_width"); + lua_pushnumber(L, window_size.X); + lua_settable(L, top); + + lua_pushstring(L,"window_height"); + lua_pushnumber(L, window_size.Y); + lua_settable(L, top); + + lua_pushstring(L, "render_info"); + lua_pushstring(L, wide_to_utf8(RenderingEngine::get_video_driver()->getName()).c_str()); + lua_settable(L, top); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_get_min_supp_proto(lua_State *L) +{ + lua_pushinteger(L, CLIENT_PROTOCOL_VERSION_MIN); + return 1; +} + +int ModApiMainMenu::l_get_max_supp_proto(lua_State *L) +{ + lua_pushinteger(L, CLIENT_PROTOCOL_VERSION_MAX); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_open_url(lua_State *L) +{ + std::string url = luaL_checkstring(L, 1); + lua_pushboolean(L, porting::open_url(url)); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_open_dir(lua_State *L) +{ + std::string path = luaL_checkstring(L, 1); + lua_pushboolean(L, porting::open_directory(path)); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_share_file(lua_State *L) +{ +#ifdef __ANDROID__ + std::string path = luaL_checkstring(L, 1); + porting::shareFileAndroid(path); + lua_pushboolean(L, true); +#else + lua_pushboolean(L, false); +#endif + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_do_async_callback(lua_State *L) +{ + MainMenuScripting *script = getScriptApi<MainMenuScripting>(L); + + size_t func_length, param_length; + const char* serialized_func_raw = luaL_checklstring(L, 1, &func_length); + const char* serialized_param_raw = luaL_checklstring(L, 2, ¶m_length); + + sanity_check(serialized_func_raw != NULL); + sanity_check(serialized_param_raw != NULL); + + u32 jobId = script->queueAsync( + std::string(serialized_func_raw, func_length), + std::string(serialized_param_raw, param_length)); + + lua_pushinteger(L, jobId); + + return 1; +} + +/******************************************************************************/ +void ModApiMainMenu::Initialize(lua_State *L, int top) +{ + API_FCT(update_formspec); + API_FCT(set_formspec_prepend); + API_FCT(set_clouds); + API_FCT(get_textlist_index); + API_FCT(get_table_index); + API_FCT(get_worlds); + API_FCT(get_games); + API_FCT(get_content_info); + API_FCT(check_mod_configuration); + API_FCT(start); + API_FCT(close); + API_FCT(show_keys_menu); + API_FCT(create_world); + API_FCT(delete_world); + API_FCT(set_background); + API_FCT(set_topleft_text); + API_FCT(get_mapgen_names); + API_FCT(get_user_path); + API_FCT(get_modpath); + API_FCT(get_modpaths); + API_FCT(get_clientmodpath); + API_FCT(get_gamepath); + API_FCT(get_texturepath); + API_FCT(get_texturepath_share); + API_FCT(get_cache_path); + API_FCT(get_temp_path); + API_FCT(create_dir); + API_FCT(delete_dir); + API_FCT(copy_dir); + API_FCT(is_dir); + API_FCT(extract_zip); + API_FCT(may_modify_path); + API_FCT(get_mainmenu_path); + API_FCT(show_path_select_dialog); + API_FCT(download_file); + API_FCT(gettext); + API_FCT(get_video_drivers); + API_FCT(get_screen_info); + API_FCT(get_min_supp_proto); + API_FCT(get_max_supp_proto); + API_FCT(open_url); + API_FCT(open_dir); + API_FCT(share_file); + API_FCT(do_async_callback); +} + +/******************************************************************************/ +void ModApiMainMenu::InitializeAsync(lua_State *L, int top) +{ + API_FCT(get_worlds); + API_FCT(get_games); + API_FCT(get_mapgen_names); + API_FCT(get_user_path); + API_FCT(get_modpath); + API_FCT(get_modpaths); + API_FCT(get_clientmodpath); + API_FCT(get_gamepath); + API_FCT(get_texturepath); + API_FCT(get_texturepath_share); + API_FCT(get_cache_path); + API_FCT(get_temp_path); + API_FCT(create_dir); + API_FCT(delete_dir); + API_FCT(copy_dir); + API_FCT(is_dir); + API_FCT(extract_zip); + API_FCT(may_modify_path); + API_FCT(download_file); + API_FCT(get_min_supp_proto); + API_FCT(get_max_supp_proto); + API_FCT(gettext); +} diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h new file mode 100644 index 0000000..9dc40c7 --- /dev/null +++ b/src/script/lua_api/l_mainmenu.h @@ -0,0 +1,174 @@ +/* +Minetest +Copyright (C) 2013 sapier + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" + +class AsyncEngine; + +/** Implementation of lua api support for mainmenu */ +class ModApiMainMenu: public ModApiBase +{ + +private: + /** + * read a text variable from gamedata table within lua stack + * @param L stack to read variable from + * @param name name of variable to read + * @return string value of requested variable + */ + static std::string getTextData(lua_State *L, std::string name); + + /** + * read a integer variable from gamedata table within lua stack + * @param L stack to read variable from + * @param name name of variable to read + * @return integer value of requested variable + */ + static int getIntegerData(lua_State *L, std::string name,bool& valid); + + /** + * read a bool variable from gamedata table within lua stack + * @param L stack to read variable from + * @param name name of variable to read + * @return bool value of requested variable + */ + static int getBoolData(lua_State *L, std::string name,bool& valid); + + /** + * Checks if a path may be modified. Paths in the temp directory or the user + * games, mods, textures, or worlds directories may be modified. + * @param path path to check + * @return true if the path may be modified + */ + static bool mayModifyPath(std::string path); + + //api calls + + static int l_start(lua_State *L); + + static int l_close(lua_State *L); + + static int l_create_world(lua_State *L); + + static int l_delete_world(lua_State *L); + + static int l_get_worlds(lua_State *L); + + static int l_get_mapgen_names(lua_State *L); + + static int l_gettext(lua_State *L); + + //packages + + static int l_get_games(lua_State *L); + + static int l_get_content_info(lua_State *L); + + static int l_check_mod_configuration(lua_State *L); + + //gui + + static int l_show_keys_menu(lua_State *L); + + static int l_show_path_select_dialog(lua_State *L); + + static int l_set_topleft_text(lua_State *L); + + static int l_set_clouds(lua_State *L); + + static int l_get_textlist_index(lua_State *L); + + static int l_get_table_index(lua_State *L); + + static int l_set_background(lua_State *L); + + static int l_update_formspec(lua_State *L); + + static int l_set_formspec_prepend(lua_State *L); + + static int l_get_screen_info(lua_State *L); + + //filesystem + + static int l_get_mainmenu_path(lua_State *L); + + static int l_get_user_path(lua_State *L); + + static int l_get_modpath(lua_State *L); + + static int l_get_modpaths(lua_State *L); + + static int l_get_clientmodpath(lua_State *L); + + static int l_get_gamepath(lua_State *L); + + static int l_get_texturepath(lua_State *L); + + static int l_get_texturepath_share(lua_State *L); + + static int l_get_cache_path(lua_State *L); + + static int l_get_temp_path(lua_State *L); + + static int l_create_dir(lua_State *L); + + static int l_delete_dir(lua_State *L); + + static int l_copy_dir(lua_State *L); + + static int l_is_dir(lua_State *L); + + static int l_extract_zip(lua_State *L); + + static int l_may_modify_path(lua_State *L); + + static int l_download_file(lua_State *L); + + static int l_get_video_drivers(lua_State *L); + + //version compatibility + static int l_get_min_supp_proto(lua_State *L); + + static int l_get_max_supp_proto(lua_State *L); + + // other + static int l_open_url(lua_State *L); + + static int l_open_dir(lua_State *L); + + static int l_share_file(lua_State *L); + + + // async + static int l_do_async_callback(lua_State *L); + +public: + + /** + * initialize this API module + * @param L lua stack to initialize + * @param top index (in lua stack) of global API table + */ + static void Initialize(lua_State *L, int top); + + static void InitializeAsync(lua_State *L, int top); + +}; diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp new file mode 100644 index 0000000..f173bd1 --- /dev/null +++ b/src/script/lua_api/l_mapgen.cpp @@ -0,0 +1,1808 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_mapgen.h" +#include "lua_api/l_internal.h" +#include "lua_api/l_vmanip.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "cpp_api/s_security.h" +#include "util/serialize.h" +#include "server.h" +#include "environment.h" +#include "emerge.h" +#include "mapgen/mg_biome.h" +#include "mapgen/mg_ore.h" +#include "mapgen/mg_decoration.h" +#include "mapgen/mg_schematic.h" +#include "mapgen/mapgen_v5.h" +#include "mapgen/mapgen_v7.h" +#include "filesys.h" +#include "settings.h" +#include "log.h" + +struct EnumString ModApiMapgen::es_BiomeTerrainType[] = +{ + {BIOMETYPE_NORMAL, "normal"}, + {0, NULL}, +}; + +struct EnumString ModApiMapgen::es_DecorationType[] = +{ + {DECO_SIMPLE, "simple"}, + {DECO_SCHEMATIC, "schematic"}, + {DECO_LSYSTEM, "lsystem"}, + {0, NULL}, +}; + +struct EnumString ModApiMapgen::es_MapgenObject[] = +{ + {MGOBJ_VMANIP, "voxelmanip"}, + {MGOBJ_HEIGHTMAP, "heightmap"}, + {MGOBJ_BIOMEMAP, "biomemap"}, + {MGOBJ_HEATMAP, "heatmap"}, + {MGOBJ_HUMIDMAP, "humiditymap"}, + {MGOBJ_GENNOTIFY, "gennotify"}, + {0, NULL}, +}; + +struct EnumString ModApiMapgen::es_OreType[] = +{ + {ORE_SCATTER, "scatter"}, + {ORE_SHEET, "sheet"}, + {ORE_PUFF, "puff"}, + {ORE_BLOB, "blob"}, + {ORE_VEIN, "vein"}, + {ORE_STRATUM, "stratum"}, + {0, NULL}, +}; + +struct EnumString ModApiMapgen::es_Rotation[] = +{ + {ROTATE_0, "0"}, + {ROTATE_90, "90"}, + {ROTATE_180, "180"}, + {ROTATE_270, "270"}, + {ROTATE_RAND, "random"}, + {0, NULL}, +}; + +struct EnumString ModApiMapgen::es_SchematicFormatType[] = +{ + {SCHEM_FMT_HANDLE, "handle"}, + {SCHEM_FMT_MTS, "mts"}, + {SCHEM_FMT_LUA, "lua"}, + {0, NULL}, +}; + +ObjDef *get_objdef(lua_State *L, int index, const ObjDefManager *objmgr); + +Biome *get_or_load_biome(lua_State *L, int index, + BiomeManager *biomemgr); +Biome *read_biome_def(lua_State *L, int index, const NodeDefManager *ndef); +size_t get_biome_list(lua_State *L, int index, + BiomeManager *biomemgr, std::unordered_set<biome_t> *biome_id_list); + +Schematic *get_or_load_schematic(lua_State *L, int index, + SchematicManager *schemmgr, StringMap *replace_names); +Schematic *load_schematic(lua_State *L, int index, const NodeDefManager *ndef, + StringMap *replace_names); +Schematic *load_schematic_from_def(lua_State *L, int index, + const NodeDefManager *ndef, StringMap *replace_names); +bool read_schematic_def(lua_State *L, int index, + Schematic *schem, std::vector<std::string> *names); + +bool read_deco_simple(lua_State *L, DecoSimple *deco); +bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic *deco); + + +/////////////////////////////////////////////////////////////////////////////// + +ObjDef *get_objdef(lua_State *L, int index, const ObjDefManager *objmgr) +{ + if (index < 0) + index = lua_gettop(L) + 1 + index; + + // If a number, assume this is a handle to an object def + if (lua_isnumber(L, index)) + return objmgr->get(lua_tointeger(L, index)); + + // If a string, assume a name is given instead + if (lua_isstring(L, index)) + return objmgr->getByName(lua_tostring(L, index)); + + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// + +Schematic *get_or_load_schematic(lua_State *L, int index, + SchematicManager *schemmgr, StringMap *replace_names) +{ + if (index < 0) + index = lua_gettop(L) + 1 + index; + + Schematic *schem = (Schematic *)get_objdef(L, index, schemmgr); + if (schem) + return schem; + + schem = load_schematic(L, index, schemmgr->getNodeDef(), + replace_names); + if (!schem) + return NULL; + + if (schemmgr->add(schem) == OBJDEF_INVALID_HANDLE) { + delete schem; + return NULL; + } + + return schem; +} + + +Schematic *load_schematic(lua_State *L, int index, const NodeDefManager *ndef, + StringMap *replace_names) +{ + if (index < 0) + index = lua_gettop(L) + 1 + index; + + Schematic *schem = NULL; + + if (lua_istable(L, index)) { + schem = load_schematic_from_def(L, index, ndef, + replace_names); + if (!schem) { + delete schem; + return NULL; + } + } else if (lua_isnumber(L, index)) { + return NULL; + } else if (lua_isstring(L, index)) { + schem = SchematicManager::create(SCHEMATIC_NORMAL); + + std::string filepath = lua_tostring(L, index); + if (!fs::IsPathAbsolute(filepath)) + filepath = ModApiBase::getCurrentModPath(L) + DIR_DELIM + filepath; + + if (!schem->loadSchematicFromFile(filepath, ndef, + replace_names)) { + delete schem; + return NULL; + } + } + + return schem; +} + + +Schematic *load_schematic_from_def(lua_State *L, int index, + const NodeDefManager *ndef, StringMap *replace_names) +{ + Schematic *schem = SchematicManager::create(SCHEMATIC_NORMAL); + + if (!read_schematic_def(L, index, schem, &schem->m_nodenames)) { + delete schem; + return NULL; + } + + size_t num_nodes = schem->m_nodenames.size(); + + schem->m_nnlistsizes.push_back(num_nodes); + + if (replace_names) { + for (size_t i = 0; i != num_nodes; i++) { + StringMap::iterator it = replace_names->find(schem->m_nodenames[i]); + if (it != replace_names->end()) + schem->m_nodenames[i] = it->second; + } + } + + if (ndef) + ndef->pendNodeResolve(schem); + + return schem; +} + + +bool read_schematic_def(lua_State *L, int index, + Schematic *schem, std::vector<std::string> *names) +{ + if (!lua_istable(L, index)) + return false; + + //// Get schematic size + lua_getfield(L, index, "size"); + v3s16 size = check_v3s16(L, -1); + lua_pop(L, 1); + + schem->size = size; + + //// Get schematic data + lua_getfield(L, index, "data"); + luaL_checktype(L, -1, LUA_TTABLE); + + u32 numnodes = size.X * size.Y * size.Z; + schem->schemdata = new MapNode[numnodes]; + + size_t names_base = names->size(); + std::unordered_map<std::string, content_t> name_id_map; + + u32 i = 0; + for (lua_pushnil(L); lua_next(L, -2); i++, lua_pop(L, 1)) { + if (i >= numnodes) + continue; + + //// Read name + std::string name; + if (!getstringfield(L, -1, "name", name)) + throw LuaError("Schematic data definition with missing name field"); + + //// Read param1/prob + u8 param1; + if (!getintfield(L, -1, "param1", param1) && + !getintfield(L, -1, "prob", param1)) + param1 = MTSCHEM_PROB_ALWAYS_OLD; + + //// Read param2 + u8 param2 = getintfield_default(L, -1, "param2", 0); + + //// Find or add new nodename-to-ID mapping + std::unordered_map<std::string, content_t>::iterator it = name_id_map.find(name); + content_t name_index; + if (it != name_id_map.end()) { + name_index = it->second; + } else { + name_index = names->size() - names_base; + name_id_map[name] = name_index; + names->push_back(name); + } + + //// Perform probability/force_place fixup on param1 + param1 >>= 1; + if (getboolfield_default(L, -1, "force_place", false)) + param1 |= MTSCHEM_FORCE_PLACE; + + //// Actually set the node in the schematic + schem->schemdata[i] = MapNode(name_index, param1, param2); + } + + if (i != numnodes) { + errorstream << "read_schematic_def: incorrect number of " + "nodes provided in raw schematic data (got " << i << + ", expected " << numnodes << ")." << std::endl; + return false; + } + + //// Get Y-slice probability values (if present) + schem->slice_probs = new u8[size.Y]; + for (i = 0; i != (u32) size.Y; i++) + schem->slice_probs[i] = MTSCHEM_PROB_ALWAYS; + + lua_getfield(L, index, "yslice_prob"); + if (lua_istable(L, -1)) { + for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { + u16 ypos; + if (!getintfield(L, -1, "ypos", ypos) || (ypos >= size.Y) || + !getintfield(L, -1, "prob", schem->slice_probs[ypos])) + continue; + + schem->slice_probs[ypos] >>= 1; + } + } + + return true; +} + + +void read_schematic_replacements(lua_State *L, int index, StringMap *replace_names) +{ + if (index < 0) + index = lua_gettop(L) + 1 + index; + + lua_pushnil(L); + while (lua_next(L, index)) { + std::string replace_from; + std::string replace_to; + + if (lua_istable(L, -1)) { // Old {{"x", "y"}, ...} format + lua_rawgeti(L, -1, 1); + if (!lua_isstring(L, -1)) + throw LuaError("schematics: replace_from field is not a string"); + replace_from = lua_tostring(L, -1); + lua_pop(L, 1); + + lua_rawgeti(L, -1, 2); + if (!lua_isstring(L, -1)) + throw LuaError("schematics: replace_to field is not a string"); + replace_to = lua_tostring(L, -1); + lua_pop(L, 1); + } else { // New {x = "y", ...} format + if (!lua_isstring(L, -2)) + throw LuaError("schematics: replace_from field is not a string"); + replace_from = lua_tostring(L, -2); + if (!lua_isstring(L, -1)) + throw LuaError("schematics: replace_to field is not a string"); + replace_to = lua_tostring(L, -1); + } + + replace_names->insert(std::make_pair(replace_from, replace_to)); + lua_pop(L, 1); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +Biome *get_or_load_biome(lua_State *L, int index, BiomeManager *biomemgr) +{ + if (index < 0) + index = lua_gettop(L) + 1 + index; + + Biome *biome = (Biome *)get_objdef(L, index, biomemgr); + if (biome) + return biome; + + biome = read_biome_def(L, index, biomemgr->getNodeDef()); + if (!biome) + return NULL; + + if (biomemgr->add(biome) == OBJDEF_INVALID_HANDLE) { + delete biome; + return NULL; + } + + return biome; +} + + +Biome *read_biome_def(lua_State *L, int index, const NodeDefManager *ndef) +{ + if (!lua_istable(L, index)) + return NULL; + + BiomeType biometype = (BiomeType)getenumfield(L, index, "type", + ModApiMapgen::es_BiomeTerrainType, BIOMETYPE_NORMAL); + Biome *b = BiomeManager::create(biometype); + + b->name = getstringfield_default(L, index, "name", ""); + b->depth_top = getintfield_default(L, index, "depth_top", 0); + b->depth_filler = getintfield_default(L, index, "depth_filler", -31000); + b->depth_water_top = getintfield_default(L, index, "depth_water_top", 0); + b->depth_riverbed = getintfield_default(L, index, "depth_riverbed", 0); + b->heat_point = getfloatfield_default(L, index, "heat_point", 0.f); + b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.f); + b->vertical_blend = getintfield_default(L, index, "vertical_blend", 0); + b->flags = 0; // reserved + + b->min_pos = getv3s16field_default( + L, index, "min_pos", v3s16(-31000, -31000, -31000)); + getintfield(L, index, "y_min", b->min_pos.Y); + b->max_pos = getv3s16field_default( + L, index, "max_pos", v3s16(31000, 31000, 31000)); + getintfield(L, index, "y_max", b->max_pos.Y); + + std::vector<std::string> &nn = b->m_nodenames; + nn.push_back(getstringfield_default(L, index, "node_top", "")); + nn.push_back(getstringfield_default(L, index, "node_filler", "")); + nn.push_back(getstringfield_default(L, index, "node_stone", "")); + nn.push_back(getstringfield_default(L, index, "node_water_top", "")); + nn.push_back(getstringfield_default(L, index, "node_water", "")); + nn.push_back(getstringfield_default(L, index, "node_river_water", "")); + nn.push_back(getstringfield_default(L, index, "node_riverbed", "")); + nn.push_back(getstringfield_default(L, index, "node_dust", "")); + + size_t nnames = getstringlistfield(L, index, "node_cave_liquid", &nn); + // If no cave liquids defined, set list to "ignore" to trigger old hardcoded + // cave liquid behaviour. + if (nnames == 0) { + nn.emplace_back("ignore"); + nnames = 1; + } + b->m_nnlistsizes.push_back(nnames); + + nn.push_back(getstringfield_default(L, index, "node_dungeon", "")); + nn.push_back(getstringfield_default(L, index, "node_dungeon_alt", "")); + nn.push_back(getstringfield_default(L, index, "node_dungeon_stair", "")); + ndef->pendNodeResolve(b); + + return b; +} + + +size_t get_biome_list(lua_State *L, int index, + BiomeManager *biomemgr, std::unordered_set<biome_t> *biome_id_list) +{ + if (index < 0) + index = lua_gettop(L) + 1 + index; + + if (lua_isnil(L, index)) + return 0; + + bool is_single = true; + if (lua_istable(L, index)) { + lua_getfield(L, index, "name"); + is_single = !lua_isnil(L, -1); + lua_pop(L, 1); + } + + if (is_single) { + Biome *biome = get_or_load_biome(L, index, biomemgr); + if (!biome) { + infostream << "get_biome_list: failed to get biome '" + << (lua_isstring(L, index) ? lua_tostring(L, index) : "") + << "'." << std::endl; + return 1; + } + + biome_id_list->insert(biome->index); + return 0; + } + + // returns number of failed resolutions + size_t fail_count = 0; + size_t count = 0; + + for (lua_pushnil(L); lua_next(L, index); lua_pop(L, 1)) { + count++; + Biome *biome = get_or_load_biome(L, -1, biomemgr); + if (!biome) { + fail_count++; + infostream << "get_biome_list: failed to get biome '" + << (lua_isstring(L, -1) ? lua_tostring(L, -1) : "") + << "'" << std::endl; + continue; + } + + biome_id_list->insert(biome->index); + } + + return fail_count; +} + +/////////////////////////////////////////////////////////////////////////////// + +// get_biome_id(biomename) +// returns the biome id as used in biomemap and returned by 'get_biome_data()' +int ModApiMapgen::l_get_biome_id(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + const char *biome_str = luaL_checkstring(L, 1); + + const BiomeManager *bmgr = getServer(L)->getEmergeManager()->getBiomeManager(); + if (!bmgr) + return 0; + + const Biome *biome = (Biome *)bmgr->getByName(biome_str); + if (!biome || biome->index == OBJDEF_INVALID_INDEX) + return 0; + + lua_pushinteger(L, biome->index); + + return 1; +} + + +// get_biome_name(biome_id) +// returns the biome name string +int ModApiMapgen::l_get_biome_name(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + int biome_id = luaL_checkinteger(L, 1); + + const BiomeManager *bmgr = getServer(L)->getEmergeManager()->getBiomeManager(); + if (!bmgr) + return 0; + + const Biome *b = (Biome *)bmgr->getRaw(biome_id); + lua_pushstring(L, b->name.c_str()); + + return 1; +} + + +// get_heat(pos) +// returns the heat at the position +int ModApiMapgen::l_get_heat(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + v3s16 pos = read_v3s16(L, 1); + + const BiomeGen *biomegen = getServer(L)->getEmergeManager()->getBiomeGen(); + + if (!biomegen || biomegen->getType() != BIOMEGEN_ORIGINAL) + return 0; + + float heat = ((BiomeGenOriginal*) biomegen)->calcHeatAtPoint(pos); + + lua_pushnumber(L, heat); + + return 1; +} + + +// get_humidity(pos) +// returns the humidity at the position +int ModApiMapgen::l_get_humidity(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + v3s16 pos = read_v3s16(L, 1); + + const BiomeGen *biomegen = getServer(L)->getEmergeManager()->getBiomeGen(); + + if (!biomegen || biomegen->getType() != BIOMEGEN_ORIGINAL) + return 0; + + float humidity = ((BiomeGenOriginal*) biomegen)->calcHumidityAtPoint(pos); + + lua_pushnumber(L, humidity); + + return 1; +} + + +// get_biome_data(pos) +// returns a table containing the biome id, heat and humidity at the position +int ModApiMapgen::l_get_biome_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + v3s16 pos = read_v3s16(L, 1); + + const BiomeGen *biomegen = getServer(L)->getEmergeManager()->getBiomeGen(); + if (!biomegen) + return 0; + + const Biome *biome = biomegen->calcBiomeAtPoint(pos); + if (!biome || biome->index == OBJDEF_INVALID_INDEX) + return 0; + + lua_newtable(L); + + lua_pushinteger(L, biome->index); + lua_setfield(L, -2, "biome"); + + if (biomegen->getType() == BIOMEGEN_ORIGINAL) { + float heat = ((BiomeGenOriginal*) biomegen)->calcHeatAtPoint(pos); + float humidity = ((BiomeGenOriginal*) biomegen)->calcHumidityAtPoint(pos); + + lua_pushnumber(L, heat); + lua_setfield(L, -2, "heat"); + + lua_pushnumber(L, humidity); + lua_setfield(L, -2, "humidity"); + } + + return 1; +} + + +// get_mapgen_object(objectname) +// returns the requested object used during map generation +int ModApiMapgen::l_get_mapgen_object(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + const char *mgobjstr = lua_tostring(L, 1); + + int mgobjint; + if (!string_to_enum(es_MapgenObject, mgobjint, mgobjstr ? mgobjstr : "")) + return 0; + + enum MapgenObject mgobj = (MapgenObject)mgobjint; + + EmergeManager *emerge = getServer(L)->getEmergeManager(); + Mapgen *mg = emerge->getCurrentMapgen(); + if (!mg) + throw LuaError("Must only be called in a mapgen thread!"); + + size_t maplen = mg->csize.X * mg->csize.Z; + + switch (mgobj) { + case MGOBJ_VMANIP: { + MMVManip *vm = mg->vm; + + // VoxelManip object + LuaVoxelManip *o = new LuaVoxelManip(vm, true); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, "VoxelManip"); + lua_setmetatable(L, -2); + + // emerged min pos + push_v3s16(L, vm->m_area.MinEdge); + + // emerged max pos + push_v3s16(L, vm->m_area.MaxEdge); + + return 3; + } + case MGOBJ_HEIGHTMAP: { + if (!mg->heightmap) + return 0; + + lua_createtable(L, maplen, 0); + for (size_t i = 0; i != maplen; i++) { + lua_pushinteger(L, mg->heightmap[i]); + lua_rawseti(L, -2, i + 1); + } + + return 1; + } + case MGOBJ_BIOMEMAP: { + if (!mg->biomegen) + return 0; + + lua_createtable(L, maplen, 0); + for (size_t i = 0; i != maplen; i++) { + lua_pushinteger(L, mg->biomegen->biomemap[i]); + lua_rawseti(L, -2, i + 1); + } + + return 1; + } + case MGOBJ_HEATMAP: { + if (!mg->biomegen || mg->biomegen->getType() != BIOMEGEN_ORIGINAL) + return 0; + + BiomeGenOriginal *bg = (BiomeGenOriginal *)mg->biomegen; + + lua_createtable(L, maplen, 0); + for (size_t i = 0; i != maplen; i++) { + lua_pushnumber(L, bg->heatmap[i]); + lua_rawseti(L, -2, i + 1); + } + + return 1; + } + + case MGOBJ_HUMIDMAP: { + if (!mg->biomegen || mg->biomegen->getType() != BIOMEGEN_ORIGINAL) + return 0; + + BiomeGenOriginal *bg = (BiomeGenOriginal *)mg->biomegen; + + lua_createtable(L, maplen, 0); + for (size_t i = 0; i != maplen; i++) { + lua_pushnumber(L, bg->humidmap[i]); + lua_rawseti(L, -2, i + 1); + } + + return 1; + } + case MGOBJ_GENNOTIFY: { + std::map<std::string, std::vector<v3s16> >event_map; + + mg->gennotify.getEvents(event_map); + + lua_createtable(L, 0, event_map.size()); + for (auto it = event_map.begin(); it != event_map.end(); ++it) { + lua_createtable(L, it->second.size(), 0); + + for (size_t j = 0; j != it->second.size(); j++) { + push_v3s16(L, it->second[j]); + lua_rawseti(L, -2, j + 1); + } + + lua_setfield(L, -2, it->first.c_str()); + } + + return 1; + } + } + + return 0; +} + + +// get_spawn_level(x = num, z = num) +int ModApiMapgen::l_get_spawn_level(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + s16 x = luaL_checkinteger(L, 1); + s16 z = luaL_checkinteger(L, 2); + + EmergeManager *emerge = getServer(L)->getEmergeManager(); + int spawn_level = emerge->getSpawnLevelAtPoint(v2s16(x, z)); + // Unsuitable spawn point + if (spawn_level == MAX_MAP_GENERATION_LIMIT) + return 0; + + // 'findSpawnPos()' in server.cpp adds at least 1 + lua_pushinteger(L, spawn_level + 1); + + return 1; +} + + +int ModApiMapgen::l_get_mapgen_params(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + log_deprecated(L, "get_mapgen_params is deprecated; " + "use get_mapgen_setting instead"); + + std::string value; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + lua_newtable(L); + + settingsmgr->getMapSetting("mg_name", &value); + lua_pushstring(L, value.c_str()); + lua_setfield(L, -2, "mgname"); + + settingsmgr->getMapSetting("seed", &value); + u64 seed = from_string<u64>(value); + lua_pushinteger(L, seed); + lua_setfield(L, -2, "seed"); + + settingsmgr->getMapSetting("water_level", &value); + lua_pushinteger(L, stoi(value, -32768, 32767)); + lua_setfield(L, -2, "water_level"); + + settingsmgr->getMapSetting("chunksize", &value); + lua_pushinteger(L, stoi(value, -32768, 32767)); + lua_setfield(L, -2, "chunksize"); + + settingsmgr->getMapSetting("mg_flags", &value); + lua_pushstring(L, value.c_str()); + lua_setfield(L, -2, "flags"); + + return 1; +} + + +// set_mapgen_params(params) +// set mapgen parameters +int ModApiMapgen::l_set_mapgen_params(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + log_deprecated(L, "set_mapgen_params is deprecated; " + "use set_mapgen_setting instead"); + + if (!lua_istable(L, 1)) + return 0; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + lua_getfield(L, 1, "mgname"); + if (lua_isstring(L, -1)) + settingsmgr->setMapSetting("mg_name", readParam<std::string>(L, -1), true); + + lua_getfield(L, 1, "seed"); + if (lua_isnumber(L, -1)) + settingsmgr->setMapSetting("seed", readParam<std::string>(L, -1), true); + + lua_getfield(L, 1, "water_level"); + if (lua_isnumber(L, -1)) + settingsmgr->setMapSetting("water_level", readParam<std::string>(L, -1), true); + + lua_getfield(L, 1, "chunksize"); + if (lua_isnumber(L, -1)) + settingsmgr->setMapSetting("chunksize", readParam<std::string>(L, -1), true); + + lua_getfield(L, 1, "flags"); + if (lua_isstring(L, -1)) + settingsmgr->setMapSetting("mg_flags", readParam<std::string>(L, -1), true); + + return 0; +} + +// get_mapgen_setting(name) +int ModApiMapgen::l_get_mapgen_setting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + std::string value; + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + if (!settingsmgr->getMapSetting(name, &value)) + return 0; + + lua_pushstring(L, value.c_str()); + return 1; +} + +// get_mapgen_setting_noiseparams(name) +int ModApiMapgen::l_get_mapgen_setting_noiseparams(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + NoiseParams np; + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + if (!settingsmgr->getMapSettingNoiseParams(name, &np)) + return 0; + + push_noiseparams(L, &np); + return 1; +} + +// set_mapgen_setting(name, value, override_meta) +// set mapgen config values +int ModApiMapgen::l_set_mapgen_setting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + const char *value = luaL_checkstring(L, 2); + bool override_meta = readParam<bool>(L, 3, false); + + if (!settingsmgr->setMapSetting(name, value, override_meta)) { + errorstream << "set_mapgen_setting: cannot set '" + << name << "' after initialization" << std::endl; + } + + return 0; +} + + +// set_mapgen_setting_noiseparams(name, noiseparams, set_default) +// set mapgen config values for noise parameters +int ModApiMapgen::l_set_mapgen_setting_noiseparams(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + + NoiseParams np; + if (!read_noiseparams(L, 2, &np)) { + errorstream << "set_mapgen_setting_noiseparams: cannot set '" << name + << "'; invalid noiseparams table" << std::endl; + return 0; + } + + bool override_meta = readParam<bool>(L, 3, false); + + if (!settingsmgr->setMapSettingNoiseParams(name, &np, override_meta)) { + errorstream << "set_mapgen_setting_noiseparams: cannot set '" + << name << "' after initialization" << std::endl; + } + + return 0; +} + + +// set_noiseparams(name, noiseparams, set_default) +// set global config values for noise parameters +int ModApiMapgen::l_set_noiseparams(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + const char *name = luaL_checkstring(L, 1); + + NoiseParams np; + if (!read_noiseparams(L, 2, &np)) { + errorstream << "set_noiseparams: cannot set '" << name + << "'; invalid noiseparams table" << std::endl; + return 0; + } + + bool set_default = !lua_isboolean(L, 3) || readParam<bool>(L, 3); + + Settings::getLayer(set_default ? SL_DEFAULTS : SL_GLOBAL)->setNoiseParams(name, np); + + return 0; +} + + +// get_noiseparams(name) +int ModApiMapgen::l_get_noiseparams(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + std::string name = luaL_checkstring(L, 1); + + NoiseParams np; + if (!g_settings->getNoiseParams(name, np)) + return 0; + + push_noiseparams(L, &np); + return 1; +} + + +// set_gen_notify(flags, {deco_id_table}) +int ModApiMapgen::l_set_gen_notify(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + u32 flags = 0, flagmask = 0; + EmergeManager *emerge = getServer(L)->getEmergeManager(); + + if (read_flags(L, 1, flagdesc_gennotify, &flags, &flagmask)) { + emerge->gen_notify_on &= ~flagmask; + emerge->gen_notify_on |= flags; + } + + if (lua_istable(L, 2)) { + lua_pushnil(L); + while (lua_next(L, 2)) { + if (lua_isnumber(L, -1)) + emerge->gen_notify_on_deco_ids.insert((u32)lua_tonumber(L, -1)); + lua_pop(L, 1); + } + } + + return 0; +} + + +// get_gen_notify() +int ModApiMapgen::l_get_gen_notify(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + EmergeManager *emerge = getServer(L)->getEmergeManager(); + push_flags_string(L, flagdesc_gennotify, emerge->gen_notify_on, + emerge->gen_notify_on); + + lua_newtable(L); + int i = 1; + for (u32 gen_notify_on_deco_id : emerge->gen_notify_on_deco_ids) { + lua_pushnumber(L, gen_notify_on_deco_id); + lua_rawseti(L, -2, i++); + } + return 2; +} + + +// get_decoration_id(decoration_name) +// returns the decoration ID as used in gennotify +int ModApiMapgen::l_get_decoration_id(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + const char *deco_str = luaL_checkstring(L, 1); + if (!deco_str) + return 0; + + const DecorationManager *dmgr = + getServer(L)->getEmergeManager()->getDecorationManager(); + + if (!dmgr) + return 0; + + Decoration *deco = (Decoration *)dmgr->getByName(deco_str); + + if (!deco) + return 0; + + lua_pushinteger(L, deco->index); + + return 1; +} + + +// register_biome({lots of stuff}) +int ModApiMapgen::l_register_biome(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + int index = 1; + luaL_checktype(L, index, LUA_TTABLE); + + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); + BiomeManager *bmgr = getServer(L)->getEmergeManager()->getWritableBiomeManager(); + + Biome *biome = read_biome_def(L, index, ndef); + if (!biome) + return 0; + + ObjDefHandle handle = bmgr->add(biome); + if (handle == OBJDEF_INVALID_HANDLE) { + delete biome; + return 0; + } + + lua_pushinteger(L, handle); + return 1; +} + + +// register_decoration({lots of stuff}) +int ModApiMapgen::l_register_decoration(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + int index = 1; + luaL_checktype(L, index, LUA_TTABLE); + + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); + EmergeManager *emerge = getServer(L)->getEmergeManager(); + DecorationManager *decomgr = emerge->getWritableDecorationManager(); + BiomeManager *biomemgr = emerge->getWritableBiomeManager(); + SchematicManager *schemmgr = emerge->getWritableSchematicManager(); + + enum DecorationType decotype = (DecorationType)getenumfield(L, index, + "deco_type", es_DecorationType, -1); + + Decoration *deco = decomgr->create(decotype); + if (!deco) { + errorstream << "register_decoration: decoration placement type " + << decotype << " not implemented" << std::endl; + return 0; + } + + deco->name = getstringfield_default(L, index, "name", ""); + deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02); + deco->y_min = getintfield_default(L, index, "y_min", -31000); + deco->y_max = getintfield_default(L, index, "y_max", 31000); + deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1); + deco->place_offset_y = getintfield_default(L, index, "place_offset_y", 0); + deco->sidelen = getintfield_default(L, index, "sidelen", 8); + if (deco->sidelen <= 0) { + errorstream << "register_decoration: sidelen must be " + "greater than 0" << std::endl; + delete deco; + return 0; + } + + //// Get node name(s) to place decoration on + size_t nread = getstringlistfield(L, index, "place_on", &deco->m_nodenames); + deco->m_nnlistsizes.push_back(nread); + + //// Get decoration flags + getflagsfield(L, index, "flags", flagdesc_deco, &deco->flags, NULL); + + //// Get NoiseParams to define how decoration is placed + lua_getfield(L, index, "noise_params"); + if (read_noiseparams(L, -1, &deco->np)) + deco->flags |= DECO_USE_NOISE; + lua_pop(L, 1); + + //// Get biomes associated with this decoration (if any) + lua_getfield(L, index, "biomes"); + if (get_biome_list(L, -1, biomemgr, &deco->biomes)) + infostream << "register_decoration: couldn't get all biomes " << std::endl; + lua_pop(L, 1); + + //// Get node name(s) to 'spawn by' + size_t nnames = getstringlistfield(L, index, "spawn_by", &deco->m_nodenames); + deco->m_nnlistsizes.push_back(nnames); + if (nnames == 0 && deco->nspawnby != -1) { + errorstream << "register_decoration: no spawn_by nodes defined," + " but num_spawn_by specified" << std::endl; + } + + //// Handle decoration type-specific parameters + bool success = false; + switch (decotype) { + case DECO_SIMPLE: + success = read_deco_simple(L, (DecoSimple *)deco); + break; + case DECO_SCHEMATIC: + success = read_deco_schematic(L, schemmgr, (DecoSchematic *)deco); + break; + case DECO_LSYSTEM: + break; + } + + if (!success) { + delete deco; + return 0; + } + + ndef->pendNodeResolve(deco); + + ObjDefHandle handle = decomgr->add(deco); + if (handle == OBJDEF_INVALID_HANDLE) { + delete deco; + return 0; + } + + lua_pushinteger(L, handle); + return 1; +} + + +bool read_deco_simple(lua_State *L, DecoSimple *deco) +{ + int index = 1; + int param2; + int param2_max; + + deco->deco_height = getintfield_default(L, index, "height", 1); + deco->deco_height_max = getintfield_default(L, index, "height_max", 0); + + if (deco->deco_height <= 0) { + errorstream << "register_decoration: simple decoration height" + " must be greater than 0" << std::endl; + return false; + } + + size_t nnames = getstringlistfield(L, index, "decoration", &deco->m_nodenames); + deco->m_nnlistsizes.push_back(nnames); + + if (nnames == 0) { + errorstream << "register_decoration: no decoration nodes " + "defined" << std::endl; + return false; + } + + param2 = getintfield_default(L, index, "param2", 0); + param2_max = getintfield_default(L, index, "param2_max", 0); + + if (param2 < 0 || param2 > 255 || param2_max < 0 || param2_max > 255) { + errorstream << "register_decoration: param2 or param2_max out of bounds (0-255)" + << std::endl; + return false; + } + + deco->deco_param2 = (u8)param2; + deco->deco_param2_max = (u8)param2_max; + + return true; +} + + +bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic *deco) +{ + int index = 1; + + deco->rotation = (Rotation)getenumfield(L, index, "rotation", + ModApiMapgen::es_Rotation, ROTATE_0); + + StringMap replace_names; + lua_getfield(L, index, "replacements"); + if (lua_istable(L, -1)) + read_schematic_replacements(L, -1, &replace_names); + lua_pop(L, 1); + + lua_getfield(L, index, "schematic"); + Schematic *schem = get_or_load_schematic(L, -1, schemmgr, &replace_names); + lua_pop(L, 1); + + deco->schematic = schem; + return schem != NULL; +} + + +// register_ore({lots of stuff}) +int ModApiMapgen::l_register_ore(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + int index = 1; + luaL_checktype(L, index, LUA_TTABLE); + + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); + EmergeManager *emerge = getServer(L)->getEmergeManager(); + BiomeManager *bmgr = emerge->getWritableBiomeManager(); + OreManager *oremgr = emerge->getWritableOreManager(); + + enum OreType oretype = (OreType)getenumfield(L, index, + "ore_type", es_OreType, ORE_SCATTER); + Ore *ore = oremgr->create(oretype); + if (!ore) { + errorstream << "register_ore: ore_type " << oretype << " not implemented\n"; + return 0; + } + + ore->name = getstringfield_default(L, index, "name", ""); + ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0); + ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1); + ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1); + ore->clust_size = getintfield_default(L, index, "clust_size", 0); + ore->noise = NULL; + ore->flags = 0; + + //// Get noise_threshold + warn_if_field_exists(L, index, "noise_threshhold", + "Deprecated: new name is \"noise_threshold\"."); + + float nthresh; + if (!getfloatfield(L, index, "noise_threshold", nthresh) && + !getfloatfield(L, index, "noise_threshhold", nthresh)) + nthresh = 0; + ore->nthresh = nthresh; + + //// Get y_min/y_max + warn_if_field_exists(L, index, "height_min", + "Deprecated: new name is \"y_min\"."); + warn_if_field_exists(L, index, "height_max", + "Deprecated: new name is \"y_max\"."); + + int ymin, ymax; + if (!getintfield(L, index, "y_min", ymin) && + !getintfield(L, index, "height_min", ymin)) + ymin = -31000; + if (!getintfield(L, index, "y_max", ymax) && + !getintfield(L, index, "height_max", ymax)) + ymax = 31000; + ore->y_min = ymin; + ore->y_max = ymax; + + if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) { + errorstream << "register_ore: clust_scarcity and clust_num_ores" + "must be greater than 0" << std::endl; + delete ore; + return 0; + } + + //// Get flags + getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL); + + //// Get biomes associated with this decoration (if any) + lua_getfield(L, index, "biomes"); + if (get_biome_list(L, -1, bmgr, &ore->biomes)) + infostream << "register_ore: couldn't get all biomes " << std::endl; + lua_pop(L, 1); + + //// Get noise parameters if needed + lua_getfield(L, index, "noise_params"); + if (read_noiseparams(L, -1, &ore->np)) { + ore->flags |= OREFLAG_USE_NOISE; + } else if (ore->needs_noise) { + log_deprecated(L, + "register_ore: ore type requires 'noise_params' but it is not specified, falling back to defaults"); + } + lua_pop(L, 1); + + //// Get type-specific parameters + switch (oretype) { + case ORE_SHEET: { + OreSheet *oresheet = (OreSheet *)ore; + + oresheet->column_height_min = getintfield_default(L, index, + "column_height_min", 1); + oresheet->column_height_max = getintfield_default(L, index, + "column_height_max", ore->clust_size); + oresheet->column_midpoint_factor = getfloatfield_default(L, index, + "column_midpoint_factor", 0.5f); + + break; + } + case ORE_PUFF: { + OrePuff *orepuff = (OrePuff *)ore; + + lua_getfield(L, index, "np_puff_top"); + read_noiseparams(L, -1, &orepuff->np_puff_top); + lua_pop(L, 1); + + lua_getfield(L, index, "np_puff_bottom"); + read_noiseparams(L, -1, &orepuff->np_puff_bottom); + lua_pop(L, 1); + + break; + } + case ORE_VEIN: { + OreVein *orevein = (OreVein *)ore; + + orevein->random_factor = getfloatfield_default(L, index, + "random_factor", 1.f); + + break; + } + case ORE_STRATUM: { + OreStratum *orestratum = (OreStratum *)ore; + + lua_getfield(L, index, "np_stratum_thickness"); + if (read_noiseparams(L, -1, &orestratum->np_stratum_thickness)) + ore->flags |= OREFLAG_USE_NOISE2; + lua_pop(L, 1); + + orestratum->stratum_thickness = getintfield_default(L, index, + "stratum_thickness", 8); + + break; + } + default: + break; + } + + ObjDefHandle handle = oremgr->add(ore); + if (handle == OBJDEF_INVALID_HANDLE) { + delete ore; + return 0; + } + + ore->m_nodenames.push_back(getstringfield_default(L, index, "ore", "")); + + size_t nnames = getstringlistfield(L, index, "wherein", &ore->m_nodenames); + ore->m_nnlistsizes.push_back(nnames); + + ndef->pendNodeResolve(ore); + + lua_pushinteger(L, handle); + return 1; +} + + +// register_schematic({schematic}, replacements={}) +int ModApiMapgen::l_register_schematic(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + SchematicManager *schemmgr = + getServer(L)->getEmergeManager()->getWritableSchematicManager(); + + StringMap replace_names; + if (lua_istable(L, 2)) + read_schematic_replacements(L, 2, &replace_names); + + Schematic *schem = load_schematic(L, 1, schemmgr->getNodeDef(), + &replace_names); + if (!schem) + return 0; + + ObjDefHandle handle = schemmgr->add(schem); + if (handle == OBJDEF_INVALID_HANDLE) { + delete schem; + return 0; + } + + lua_pushinteger(L, handle); + return 1; +} + + +// clear_registered_biomes() +int ModApiMapgen::l_clear_registered_biomes(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + BiomeManager *bmgr = + getServer(L)->getEmergeManager()->getWritableBiomeManager(); + bmgr->clear(); + return 0; +} + + +// clear_registered_decorations() +int ModApiMapgen::l_clear_registered_decorations(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + DecorationManager *dmgr = + getServer(L)->getEmergeManager()->getWritableDecorationManager(); + dmgr->clear(); + return 0; +} + + +// clear_registered_ores() +int ModApiMapgen::l_clear_registered_ores(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + OreManager *omgr = + getServer(L)->getEmergeManager()->getWritableOreManager(); + omgr->clear(); + return 0; +} + + +// clear_registered_schematics() +int ModApiMapgen::l_clear_registered_schematics(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + SchematicManager *smgr = + getServer(L)->getEmergeManager()->getWritableSchematicManager(); + smgr->clear(); + return 0; +} + + +// generate_ores(vm, p1, p2, [ore_id]) +int ModApiMapgen::l_generate_ores(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + EmergeManager *emerge = getServer(L)->getEmergeManager(); + if (!emerge || !emerge->mgparams) + return 0; + + Mapgen mg; + // Intentionally truncates to s32, see Mapgen::Mapgen() + mg.seed = (s32)emerge->mgparams->seed; + mg.vm = LuaVoxelManip::checkobject(L, 1)->vm; + mg.ndef = getServer(L)->getNodeDefManager(); + + v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) : + mg.vm->m_area.MinEdge + v3s16(1,1,1) * MAP_BLOCKSIZE; + v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) : + mg.vm->m_area.MaxEdge - v3s16(1,1,1) * MAP_BLOCKSIZE; + sortBoxVerticies(pmin, pmax); + + u32 blockseed = Mapgen::getBlockSeed(pmin, mg.seed); + + emerge->oremgr->placeAllOres(&mg, blockseed, pmin, pmax); + + return 0; +} + + +// generate_decorations(vm, p1, p2, [deco_id]) +int ModApiMapgen::l_generate_decorations(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + EmergeManager *emerge = getServer(L)->getEmergeManager(); + if (!emerge || !emerge->mgparams) + return 0; + + Mapgen mg; + // Intentionally truncates to s32, see Mapgen::Mapgen() + mg.seed = (s32)emerge->mgparams->seed; + mg.vm = LuaVoxelManip::checkobject(L, 1)->vm; + mg.ndef = getServer(L)->getNodeDefManager(); + + v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) : + mg.vm->m_area.MinEdge + v3s16(1,1,1) * MAP_BLOCKSIZE; + v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) : + mg.vm->m_area.MaxEdge - v3s16(1,1,1) * MAP_BLOCKSIZE; + sortBoxVerticies(pmin, pmax); + + u32 blockseed = Mapgen::getBlockSeed(pmin, mg.seed); + + emerge->decomgr->placeAllDecos(&mg, blockseed, pmin, pmax); + + return 0; +} + + +// create_schematic(p1, p2, probability_list, filename, y_slice_prob_list) +int ModApiMapgen::l_create_schematic(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); + + const char *filename = luaL_checkstring(L, 4); + CHECK_SECURE_PATH(L, filename, true); + + Map *map = &(getEnv(L)->getMap()); + Schematic schem; + + v3s16 p1 = check_v3s16(L, 1); + v3s16 p2 = check_v3s16(L, 2); + sortBoxVerticies(p1, p2); + + std::vector<std::pair<v3s16, u8> > prob_list; + if (lua_istable(L, 3)) { + lua_pushnil(L); + while (lua_next(L, 3)) { + if (lua_istable(L, -1)) { + lua_getfield(L, -1, "pos"); + v3s16 pos = check_v3s16(L, -1); + lua_pop(L, 1); + + u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); + prob_list.emplace_back(pos, prob); + } + + lua_pop(L, 1); + } + } + + std::vector<std::pair<s16, u8> > slice_prob_list; + if (lua_istable(L, 5)) { + lua_pushnil(L); + while (lua_next(L, 5)) { + if (lua_istable(L, -1)) { + s16 ypos = getintfield_default(L, -1, "ypos", 0); + u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); + slice_prob_list.emplace_back(ypos, prob); + } + + lua_pop(L, 1); + } + } + + if (!schem.getSchematicFromMap(map, p1, p2)) { + errorstream << "create_schematic: failed to get schematic " + "from map" << std::endl; + return 0; + } + + schem.applyProbabilities(p1, &prob_list, &slice_prob_list); + + schem.saveSchematicToFile(filename, ndef); + actionstream << "create_schematic: saved schematic file '" + << filename << "'." << std::endl; + + lua_pushboolean(L, true); + return 1; +} + + +// place_schematic(p, schematic, rotation, +// replacements, force_placement, flagstring) +int ModApiMapgen::l_place_schematic(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + GET_ENV_PTR; + + ServerMap *map = &(env->getServerMap()); + SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; + + //// Read position + v3s16 p = check_v3s16(L, 1); + + //// Read rotation + int rot = ROTATE_0; + std::string enumstr = readParam<std::string>(L, 3, ""); + if (!enumstr.empty()) + string_to_enum(es_Rotation, rot, enumstr); + + //// Read force placement + bool force_placement = true; + if (lua_isboolean(L, 5)) + force_placement = readParam<bool>(L, 5); + + //// Read node replacements + StringMap replace_names; + if (lua_istable(L, 4)) + read_schematic_replacements(L, 4, &replace_names); + + //// Read schematic + Schematic *schem = get_or_load_schematic(L, 2, schemmgr, &replace_names); + if (!schem) { + errorstream << "place_schematic: failed to get schematic" << std::endl; + return 0; + } + + //// Read flags + u32 flags = 0; + read_flags(L, 6, flagdesc_deco, &flags, NULL); + + schem->placeOnMap(map, p, flags, (Rotation)rot, force_placement); + + lua_pushboolean(L, true); + return 1; +} + + +// place_schematic_on_vmanip(vm, p, schematic, rotation, +// replacements, force_placement, flagstring) +int ModApiMapgen::l_place_schematic_on_vmanip(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; + + //// Read VoxelManip object + MMVManip *vm = LuaVoxelManip::checkobject(L, 1)->vm; + + //// Read position + v3s16 p = check_v3s16(L, 2); + + //// Read rotation + int rot = ROTATE_0; + std::string enumstr = readParam<std::string>(L, 4, ""); + if (!enumstr.empty()) + string_to_enum(es_Rotation, rot, std::string(enumstr)); + + //// Read force placement + bool force_placement = true; + if (lua_isboolean(L, 6)) + force_placement = readParam<bool>(L, 6); + + //// Read node replacements + StringMap replace_names; + if (lua_istable(L, 5)) + read_schematic_replacements(L, 5, &replace_names); + + //// Read schematic + Schematic *schem = get_or_load_schematic(L, 3, schemmgr, &replace_names); + if (!schem) { + errorstream << "place_schematic: failed to get schematic" << std::endl; + return 0; + } + + //// Read flags + u32 flags = 0; + read_flags(L, 7, flagdesc_deco, &flags, NULL); + + bool schematic_did_fit = schem->placeOnVManip( + vm, p, flags, (Rotation)rot, force_placement); + + lua_pushboolean(L, schematic_did_fit); + return 1; +} + + +// serialize_schematic(schematic, format, options={...}) +int ModApiMapgen::l_serialize_schematic(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + const SchematicManager *schemmgr = getServer(L)->getEmergeManager()->getSchematicManager(); + + //// Read options + bool use_comments = getboolfield_default(L, 3, "lua_use_comments", false); + u32 indent_spaces = getintfield_default(L, 3, "lua_num_indent_spaces", 0); + + //// Get schematic + bool was_loaded = false; + const Schematic *schem = (Schematic *)get_objdef(L, 1, schemmgr); + if (!schem) { + schem = load_schematic(L, 1, NULL, NULL); + was_loaded = true; + } + if (!schem) { + errorstream << "serialize_schematic: failed to get schematic" << std::endl; + return 0; + } + + //// Read format of definition to save as + int schem_format = SCHEM_FMT_MTS; + std::string enumstr = readParam<std::string>(L, 2, ""); + if (!enumstr.empty()) + string_to_enum(es_SchematicFormatType, schem_format, enumstr); + + //// Serialize to binary string + std::ostringstream os(std::ios_base::binary); + switch (schem_format) { + case SCHEM_FMT_MTS: + schem->serializeToMts(&os); + break; + case SCHEM_FMT_LUA: + schem->serializeToLua(&os, use_comments, indent_spaces); + break; + default: + return 0; + } + + if (was_loaded) + delete schem; + + std::string ser = os.str(); + lua_pushlstring(L, ser.c_str(), ser.length()); + return 1; +} + +// read_schematic(schematic, options={...}) +int ModApiMapgen::l_read_schematic(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + const SchematicManager *schemmgr = + getServer(L)->getEmergeManager()->getSchematicManager(); + + //// Read options + std::string write_yslice = getstringfield_default(L, 2, "write_yslice_prob", "all"); + + //// Get schematic + bool was_loaded = false; + Schematic *schem = (Schematic *)get_objdef(L, 1, schemmgr); + if (!schem) { + schem = load_schematic(L, 1, NULL, NULL); + was_loaded = true; + } + if (!schem) { + errorstream << "read_schematic: failed to get schematic" << std::endl; + return 0; + } + lua_pop(L, 2); + + //// Create the Lua table + u32 numnodes = schem->size.X * schem->size.Y * schem->size.Z; + const std::vector<std::string> &names = schem->m_nodenames; + + lua_createtable(L, 0, (write_yslice == "none") ? 2 : 3); + + // Create the size field + push_v3s16(L, schem->size); + lua_setfield(L, 1, "size"); + + // Create the yslice_prob field + if (write_yslice != "none") { + lua_createtable(L, schem->size.Y, 0); + for (u16 y = 0; y != schem->size.Y; ++y) { + u8 probability = schem->slice_probs[y] & MTSCHEM_PROB_MASK; + if (probability < MTSCHEM_PROB_ALWAYS || write_yslice != "low") { + lua_createtable(L, 0, 2); + lua_pushinteger(L, y); + lua_setfield(L, 3, "ypos"); + lua_pushinteger(L, probability * 2); + lua_setfield(L, 3, "prob"); + lua_rawseti(L, 2, y + 1); + } + } + lua_setfield(L, 1, "yslice_prob"); + } + + // Create the data field + lua_createtable(L, numnodes, 0); // data table + for (u32 i = 0; i < numnodes; ++i) { + MapNode node = schem->schemdata[i]; + u8 probability = node.param1 & MTSCHEM_PROB_MASK; + bool force_place = node.param1 & MTSCHEM_FORCE_PLACE; + lua_createtable(L, 0, force_place ? 4 : 3); + lua_pushstring(L, names[schem->schemdata[i].getContent()].c_str()); + lua_setfield(L, 3, "name"); + lua_pushinteger(L, probability * 2); + lua_setfield(L, 3, "prob"); + lua_pushinteger(L, node.param2); + lua_setfield(L, 3, "param2"); + if (force_place) { + lua_pushboolean(L, 1); + lua_setfield(L, 3, "force_place"); + } + lua_rawseti(L, 2, i + 1); + } + lua_setfield(L, 1, "data"); + + if (was_loaded) + delete schem; + + return 1; +} + + +void ModApiMapgen::Initialize(lua_State *L, int top) +{ + API_FCT(get_biome_id); + API_FCT(get_biome_name); + API_FCT(get_heat); + API_FCT(get_humidity); + API_FCT(get_biome_data); + API_FCT(get_mapgen_object); + API_FCT(get_spawn_level); + + API_FCT(get_mapgen_params); + API_FCT(set_mapgen_params); + API_FCT(get_mapgen_setting); + API_FCT(set_mapgen_setting); + API_FCT(get_mapgen_setting_noiseparams); + API_FCT(set_mapgen_setting_noiseparams); + API_FCT(set_noiseparams); + API_FCT(get_noiseparams); + API_FCT(set_gen_notify); + API_FCT(get_gen_notify); + API_FCT(get_decoration_id); + + API_FCT(register_biome); + API_FCT(register_decoration); + API_FCT(register_ore); + API_FCT(register_schematic); + + API_FCT(clear_registered_biomes); + API_FCT(clear_registered_decorations); + API_FCT(clear_registered_ores); + API_FCT(clear_registered_schematics); + + API_FCT(generate_ores); + API_FCT(generate_decorations); + API_FCT(create_schematic); + API_FCT(place_schematic); + API_FCT(place_schematic_on_vmanip); + API_FCT(serialize_schematic); + API_FCT(read_schematic); +} diff --git a/src/script/lua_api/l_mapgen.h b/src/script/lua_api/l_mapgen.h new file mode 100644 index 0000000..0bdc56f --- /dev/null +++ b/src/script/lua_api/l_mapgen.h @@ -0,0 +1,149 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" + +typedef u16 biome_t; // copy from mg_biome.h to avoid an unnecessary include + +class ModApiMapgen : public ModApiBase +{ +private: + // get_biome_id(biomename) + // returns the biome id as used in biomemap and returned by 'get_biome_data()' + static int l_get_biome_id(lua_State *L); + + // get_biome_name(biome_id) + // returns the biome name string + static int l_get_biome_name(lua_State *L); + + // get_heat(pos) + // returns the heat at the position + static int l_get_heat(lua_State *L); + + // get_humidity(pos) + // returns the humidity at the position + static int l_get_humidity(lua_State *L); + + // get_biome_data(pos) + // returns a table containing the biome id, heat and humidity at the position + static int l_get_biome_data(lua_State *L); + + // get_mapgen_object(objectname) + // returns the requested object used during map generation + static int l_get_mapgen_object(lua_State *L); + + // get_spawn_level(x = num, z = num) + static int l_get_spawn_level(lua_State *L); + + // get_mapgen_params() + // returns the currently active map generation parameter set + static int l_get_mapgen_params(lua_State *L); + + // set_mapgen_params(params) + // set mapgen parameters + static int l_set_mapgen_params(lua_State *L); + + // get_mapgen_setting(name) + static int l_get_mapgen_setting(lua_State *L); + + // set_mapgen_setting(name, value, override_meta) + static int l_set_mapgen_setting(lua_State *L); + + // get_mapgen_setting_noiseparams(name) + static int l_get_mapgen_setting_noiseparams(lua_State *L); + + // set_mapgen_setting_noiseparams(name, value, override_meta) + static int l_set_mapgen_setting_noiseparams(lua_State *L); + + // set_noiseparam_defaults(name, noiseparams, set_default) + static int l_set_noiseparams(lua_State *L); + + // get_noiseparam_defaults(name) + static int l_get_noiseparams(lua_State *L); + + // set_gen_notify(flags, {deco_id_table}) + static int l_set_gen_notify(lua_State *L); + + // get_gen_notify() + static int l_get_gen_notify(lua_State *L); + + // get_decoration_id(decoration_name) + // returns the decoration ID as used in gennotify + static int l_get_decoration_id(lua_State *L); + + // register_biome({lots of stuff}) + static int l_register_biome(lua_State *L); + + // register_decoration({lots of stuff}) + static int l_register_decoration(lua_State *L); + + // register_ore({lots of stuff}) + static int l_register_ore(lua_State *L); + + // register_schematic({schematic}, replacements={}) + static int l_register_schematic(lua_State *L); + + // clear_registered_biomes() + static int l_clear_registered_biomes(lua_State *L); + + // clear_registered_decorations() + static int l_clear_registered_decorations(lua_State *L); + + // clear_registered_schematics() + static int l_clear_registered_schematics(lua_State *L); + + // generate_ores(vm, p1, p2) + static int l_generate_ores(lua_State *L); + + // generate_decorations(vm, p1, p2) + static int l_generate_decorations(lua_State *L); + + // clear_registered_ores + static int l_clear_registered_ores(lua_State *L); + + // create_schematic(p1, p2, probability_list, filename) + static int l_create_schematic(lua_State *L); + + // place_schematic(p, schematic, rotation, + // replacements, force_placement, flagstring) + static int l_place_schematic(lua_State *L); + + // place_schematic_on_vmanip(vm, p, schematic, rotation, + // replacements, force_placement, flagstring) + static int l_place_schematic_on_vmanip(lua_State *L); + + // serialize_schematic(schematic, format, options={...}) + static int l_serialize_schematic(lua_State *L); + + // read_schematic(schematic, options={...}) + static int l_read_schematic(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); + + static struct EnumString es_BiomeTerrainType[]; + static struct EnumString es_DecorationType[]; + static struct EnumString es_MapgenObject[]; + static struct EnumString es_OreType[]; + static struct EnumString es_Rotation[]; + static struct EnumString es_SchematicFormatType[]; + static struct EnumString es_NodeResolveMethod[]; +}; diff --git a/src/script/lua_api/l_metadata.cpp b/src/script/lua_api/l_metadata.cpp new file mode 100644 index 0000000..d00cb4d --- /dev/null +++ b/src/script/lua_api/l_metadata.cpp @@ -0,0 +1,303 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_metadata.h" +#include "lua_api/l_internal.h" +#include "common/c_content.h" +#include "serverenvironment.h" +#include "map.h" +#include "server.h" + +// LUALIB_API +void *luaL_checkudata_is_metadataref(lua_State *L, int ud) { + void *p = lua_touserdata(L, ud); + if (p != NULL && // value is a userdata? + lua_getmetatable(L, ud)) { // does it have a metatable? + lua_getfield(L, -1, "metadata_class"); + if (lua_type(L, -1) == LUA_TSTRING) { // does it have a metadata_class field? + return p; + } + } + luaL_typerror(L, ud, "MetaDataRef"); + return NULL; +} + +MetaDataRef* MetaDataRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata_is_metadataref(L, narg); + if (!ud) + luaL_typerror(L, narg, "MetaDataRef"); + + return *(MetaDataRef**)ud; // unbox pointer +} + +// Exported functions + +// contains(self, name) +int MetaDataRef::l_contains(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + + Metadata *meta = ref->getmeta(false); + if (meta == NULL) + return 0; + + lua_pushboolean(L, meta->contains(name)); + return 1; +} + +// get(self, name) +int MetaDataRef::l_get(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + + Metadata *meta = ref->getmeta(false); + if (meta == NULL) + return 0; + + std::string str; + if (meta->getStringToRef(name, str)) { + lua_pushlstring(L, str.c_str(), str.size()); + } else { + lua_pushnil(L); + } + return 1; +} + +// get_string(self, name) +int MetaDataRef::l_get_string(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + + Metadata *meta = ref->getmeta(false); + if (meta == NULL) { + lua_pushlstring(L, "", 0); + return 1; + } + + const std::string &str = meta->getString(name); + lua_pushlstring(L, str.c_str(), str.size()); + return 1; +} + +// set_string(self, name, var) +int MetaDataRef::l_set_string(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + size_t len = 0; + const char *s = lua_tolstring(L, 3, &len); + std::string str(s, len); + + Metadata *meta = ref->getmeta(!str.empty()); + if (meta == NULL || str == meta->getString(name)) + return 0; + + meta->setString(name, str); + ref->reportMetadataChange(&name); + return 0; +} + +// get_int(self, name) +int MetaDataRef::l_get_int(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + + Metadata *meta = ref->getmeta(false); + if (meta == NULL) { + lua_pushnumber(L, 0); + return 1; + } + + const std::string &str = meta->getString(name); + lua_pushnumber(L, stoi(str)); + return 1; +} + +// set_int(self, name, var) +int MetaDataRef::l_set_int(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + int a = luaL_checkint(L, 3); + std::string str = itos(a); + + Metadata *meta = ref->getmeta(true); + if (meta == NULL || str == meta->getString(name)) + return 0; + + meta->setString(name, str); + ref->reportMetadataChange(&name); + return 0; +} + +// get_float(self, name) +int MetaDataRef::l_get_float(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + + Metadata *meta = ref->getmeta(false); + if (meta == NULL) { + lua_pushnumber(L, 0); + return 1; + } + + const std::string &str = meta->getString(name); + lua_pushnumber(L, stof(str)); + return 1; +} + +// set_float(self, name, var) +int MetaDataRef::l_set_float(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + float a = readParam<float>(L, 3); + std::string str = ftos(a); + + Metadata *meta = ref->getmeta(true); + if (meta == NULL || str == meta->getString(name)) + return 0; + + meta->setString(name, str); + ref->reportMetadataChange(&name); + return 0; +} + +// to_table(self) +int MetaDataRef::l_to_table(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + + Metadata *meta = ref->getmeta(true); + if (meta == NULL) { + lua_pushnil(L); + return 1; + } + lua_newtable(L); + + ref->handleToTable(L, meta); + + return 1; +} + +// from_table(self, table) +int MetaDataRef::l_from_table(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + int base = 2; + + ref->clearMeta(); + + if (!lua_istable(L, base)) { + // No metadata + lua_pushboolean(L, true); + return 1; + } + + // Create new metadata + Metadata *meta = ref->getmeta(true); + if (meta == NULL) { + lua_pushboolean(L, false); + return 1; + } + + bool was_successful = ref->handleFromTable(L, base, meta); + ref->reportMetadataChange(); + lua_pushboolean(L, was_successful); + return 1; +} + +void MetaDataRef::handleToTable(lua_State *L, Metadata *meta) +{ + lua_newtable(L); + { + const StringMap &fields = meta->getStrings(); + for (const auto &field : fields) { + const std::string &name = field.first; + const std::string &value = field.second; + lua_pushlstring(L, name.c_str(), name.size()); + lua_pushlstring(L, value.c_str(), value.size()); + lua_settable(L, -3); + } + } + lua_setfield(L, -2, "fields"); +} + +bool MetaDataRef::handleFromTable(lua_State *L, int table, Metadata *meta) +{ + // Set fields + lua_getfield(L, table, "fields"); + if (lua_istable(L, -1)) { + int fieldstable = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, fieldstable) != 0) { + // key at index -2 and value at index -1 + std::string name = readParam<std::string>(L, -2); + size_t cl; + const char *cs = lua_tolstring(L, -1, &cl); + meta->setString(name, std::string(cs, cl)); + lua_pop(L, 1); // Remove value, keep key for next iteration + } + lua_pop(L, 1); + } + + return true; +} + +// equals(self, other) +int MetaDataRef::l_equals(lua_State *L) +{ + MetaDataRef *ref1 = checkobject(L, 1); + Metadata *data1 = ref1->getmeta(false); + MetaDataRef *ref2 = checkobject(L, 2); + Metadata *data2 = ref2->getmeta(false); + if (data1 == NULL || data2 == NULL) + lua_pushboolean(L, data1 == data2); + else + lua_pushboolean(L, *data1 == *data2); + return 1; +} diff --git a/src/script/lua_api/l_metadata.h b/src/script/lua_api/l_metadata.h new file mode 100644 index 0000000..e655eb6 --- /dev/null +++ b/src/script/lua_api/l_metadata.h @@ -0,0 +1,81 @@ +/* +Minetest +Copyright (C) 2013-8 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +#include "lua_api/l_base.h" + +class Metadata; + +/* + NodeMetaRef +*/ + +class MetaDataRef : public ModApiBase +{ +public: + virtual ~MetaDataRef() = default; + +protected: + static MetaDataRef *checkobject(lua_State *L, int narg); + + virtual void reportMetadataChange(const std::string *name = nullptr) {} + virtual Metadata *getmeta(bool auto_create) = 0; + virtual void clearMeta() = 0; + + virtual void handleToTable(lua_State *L, Metadata *meta); + virtual bool handleFromTable(lua_State *L, int table, Metadata *meta); + + // Exported functions + + // contains(self, name) + static int l_contains(lua_State *L); + + // get(self, name) + static int l_get(lua_State *L); + + // get_string(self, name) + static int l_get_string(lua_State *L); + + // set_string(self, name, var) + static int l_set_string(lua_State *L); + + // get_int(self, name) + static int l_get_int(lua_State *L); + + // set_int(self, name, var) + static int l_set_int(lua_State *L); + + // get_float(self, name) + static int l_get_float(lua_State *L); + + // set_float(self, name, var) + static int l_set_float(lua_State *L); + + // to_table(self) + static int l_to_table(lua_State *L); + + // from_table(self, table) + static int l_from_table(lua_State *L); + + // equals(self, other) + static int l_equals(lua_State *L); +}; diff --git a/src/script/lua_api/l_minimap.cpp b/src/script/lua_api/l_minimap.cpp new file mode 100644 index 0000000..a135e0b --- /dev/null +++ b/src/script/lua_api/l_minimap.cpp @@ -0,0 +1,231 @@ +/* +Minetest +Copyright (C) 2017 Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "lua_api/l_minimap.h" +#include "lua_api/l_internal.h" +#include "common/c_converter.h" +#include "client/client.h" +#include "client/minimap.h" +#include "settings.h" + +LuaMinimap::LuaMinimap(Minimap *m) : m_minimap(m) +{ +} + +void LuaMinimap::create(lua_State *L, Minimap *m) +{ + LuaMinimap *o = new LuaMinimap(m); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + + // Keep minimap object stack id + int minimap_object = lua_gettop(L); + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "ui"); + luaL_checktype(L, -1, LUA_TTABLE); + int uitable = lua_gettop(L); + + lua_pushvalue(L, minimap_object); // Copy object to top of stack + lua_setfield(L, uitable, "minimap"); +} + +int LuaMinimap::l_get_pos(lua_State *L) +{ + LuaMinimap *ref = checkobject(L, 1); + Minimap *m = getobject(ref); + + push_v3s16(L, m->getPos()); + return 1; +} + +int LuaMinimap::l_set_pos(lua_State *L) +{ + LuaMinimap *ref = checkobject(L, 1); + Minimap *m = getobject(ref); + + m->setPos(read_v3s16(L, 2)); + return 1; +} + +int LuaMinimap::l_get_angle(lua_State *L) +{ + LuaMinimap *ref = checkobject(L, 1); + Minimap *m = getobject(ref); + + lua_pushinteger(L, m->getAngle()); + return 1; +} + +int LuaMinimap::l_set_angle(lua_State *L) +{ + LuaMinimap *ref = checkobject(L, 1); + Minimap *m = getobject(ref); + + m->setAngle(lua_tointeger(L, 2)); + return 1; +} + +int LuaMinimap::l_get_mode(lua_State *L) +{ + LuaMinimap *ref = checkobject(L, 1); + Minimap *m = getobject(ref); + + lua_pushinteger(L, m->getModeIndex()); + return 1; +} + +int LuaMinimap::l_set_mode(lua_State *L) +{ + LuaMinimap *ref = checkobject(L, 1); + Minimap *m = getobject(ref); + + u32 mode = lua_tointeger(L, 2); + if (mode >= m->getMaxModeIndex()) + return 0; + + m->setModeIndex(mode); + return 1; +} + +int LuaMinimap::l_set_shape(lua_State *L) +{ + LuaMinimap *ref = checkobject(L, 1); + Minimap *m = getobject(ref); + if (!lua_isnumber(L, 2)) + return 0; + + m->setMinimapShape((MinimapShape)((int)lua_tonumber(L, 2))); + return 0; +} + +int LuaMinimap::l_get_shape(lua_State *L) +{ + LuaMinimap *ref = checkobject(L, 1); + Minimap *m = getobject(ref); + + lua_pushnumber(L, (int)m->getMinimapShape()); + return 1; +} + +int LuaMinimap::l_show(lua_State *L) +{ + // If minimap is disabled by config, don't show it. + if (!g_settings->getBool("enable_minimap")) + return 1; + + Client *client = getClient(L); + assert(client); + + LuaMinimap *ref = checkobject(L, 1); + Minimap *m = getobject(ref); + + // This is not very adapted to new minimap mode management. Btw, tried + // to do something compatible. + + if (m->getModeIndex() == 0 && m->getMaxModeIndex() > 0) + m->setModeIndex(1); + + client->showMinimap(true); + return 1; +} + +int LuaMinimap::l_hide(lua_State *L) +{ + Client *client = getClient(L); + assert(client); + + LuaMinimap *ref = checkobject(L, 1); + Minimap *m = getobject(ref); + + // This is not very adapted to new minimap mode management. Btw, tried + // to do something compatible. + + if (m->getModeIndex() != 0) + m->setModeIndex(0); + + client->showMinimap(false); + return 1; +} + +LuaMinimap *LuaMinimap::checkobject(lua_State *L, int narg) +{ + NO_MAP_LOCK_REQUIRED; + + luaL_checktype(L, narg, LUA_TUSERDATA); + + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + + return *(LuaMinimap **)ud; // unbox pointer +} + +Minimap* LuaMinimap::getobject(LuaMinimap *ref) +{ + return ref->m_minimap; +} + +int LuaMinimap::gc_object(lua_State *L) { + LuaMinimap *o = *(LuaMinimap **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +void LuaMinimap::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // drop methodtable +} + +const char LuaMinimap::className[] = "Minimap"; +const luaL_Reg LuaMinimap::methods[] = { + luamethod(LuaMinimap, show), + luamethod(LuaMinimap, hide), + luamethod(LuaMinimap, get_pos), + luamethod(LuaMinimap, set_pos), + luamethod(LuaMinimap, get_angle), + luamethod(LuaMinimap, set_angle), + luamethod(LuaMinimap, get_mode), + luamethod(LuaMinimap, set_mode), + luamethod(LuaMinimap, set_shape), + luamethod(LuaMinimap, get_shape), + {0,0} +}; diff --git a/src/script/lua_api/l_minimap.h b/src/script/lua_api/l_minimap.h new file mode 100644 index 0000000..cc859ad --- /dev/null +++ b/src/script/lua_api/l_minimap.h @@ -0,0 +1,62 @@ +/* +Minetest +Copyright (C) 2017 Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "l_base.h" + +class Minimap; + +class LuaMinimap : public ModApiBase +{ +private: + static const char className[]; + static const luaL_Reg methods[]; + + // garbage collector + static int gc_object(lua_State *L); + + static int l_get_pos(lua_State *L); + static int l_set_pos(lua_State *L); + + static int l_get_angle(lua_State *L); + static int l_set_angle(lua_State *L); + + static int l_get_mode(lua_State *L); + static int l_set_mode(lua_State *L); + + static int l_show(lua_State *L); + static int l_hide(lua_State *L); + + static int l_set_shape(lua_State *L); + static int l_get_shape(lua_State *L); + + Minimap *m_minimap = nullptr; + +public: + LuaMinimap(Minimap *m); + ~LuaMinimap() = default; + + static void create(lua_State *L, Minimap *object); + + static LuaMinimap *checkobject(lua_State *L, int narg); + static Minimap *getobject(LuaMinimap *ref); + + static void Register(lua_State *L); +}; diff --git a/src/script/lua_api/l_modchannels.cpp b/src/script/lua_api/l_modchannels.cpp new file mode 100644 index 0000000..931c274 --- /dev/null +++ b/src/script/lua_api/l_modchannels.cpp @@ -0,0 +1,153 @@ +/* +Minetest +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <cassert> +#include <log.h> +#include "lua_api/l_modchannels.h" +#include "l_internal.h" +#include "modchannels.h" + +int ModApiChannels::l_mod_channel_join(lua_State *L) +{ + if (!lua_isstring(L, 1)) + return 0; + + std::string channel = luaL_checkstring(L, 1); + if (channel.empty()) + return 0; + + getGameDef(L)->joinModChannel(channel); + assert(getGameDef(L)->getModChannel(channel) != nullptr); + ModChannelRef::create(L, channel); + + int object = lua_gettop(L); + lua_pushvalue(L, object); + return 1; +} + +void ModApiChannels::Initialize(lua_State *L, int top) +{ + API_FCT(mod_channel_join); +} + +/* + * ModChannelRef + */ + +ModChannelRef::ModChannelRef(const std::string &modchannel) : + m_modchannel_name(modchannel) +{ +} + +int ModChannelRef::l_leave(lua_State *L) +{ + ModChannelRef *ref = checkobject(L, 1); + getGameDef(L)->leaveModChannel(ref->m_modchannel_name); + return 0; +} + +int ModChannelRef::l_send_all(lua_State *L) +{ + ModChannelRef *ref = checkobject(L, 1); + ModChannel *channel = getobject(L, ref); + if (!channel || !channel->canWrite()) + return 0; + + // @TODO serialize message + std::string message = luaL_checkstring(L, 2); + + getGameDef(L)->sendModChannelMessage(channel->getName(), message); + return 0; +} + +int ModChannelRef::l_is_writeable(lua_State *L) +{ + ModChannelRef *ref = checkobject(L, 1); + ModChannel *channel = getobject(L, ref); + if (!channel) + return 0; + + lua_pushboolean(L, channel->canWrite()); + return 1; +} +void ModChannelRef::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from lua getmetatable() + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); // Drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // Drop methodtable +} + +void ModChannelRef::create(lua_State *L, const std::string &channel) +{ + ModChannelRef *o = new ModChannelRef(channel); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +int ModChannelRef::gc_object(lua_State *L) +{ + ModChannelRef *o = *(ModChannelRef **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +ModChannelRef *ModChannelRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + + return *(ModChannelRef **)ud; // unbox pointer +} + +ModChannel *ModChannelRef::getobject(lua_State *L, ModChannelRef *ref) +{ + return getGameDef(L)->getModChannel(ref->m_modchannel_name); +} + +// clang-format off +const char ModChannelRef::className[] = "ModChannelRef"; +const luaL_Reg ModChannelRef::methods[] = { + luamethod(ModChannelRef, leave), + luamethod(ModChannelRef, is_writeable), + luamethod(ModChannelRef, send_all), + {0, 0}, +}; +// clang-format on diff --git a/src/script/lua_api/l_modchannels.h b/src/script/lua_api/l_modchannels.h new file mode 100644 index 0000000..9b94800 --- /dev/null +++ b/src/script/lua_api/l_modchannels.h @@ -0,0 +1,66 @@ +/* +Minetest +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" +#include "config.h" + +class ModChannel; + +class ModApiChannels : public ModApiBase +{ +private: + // mod_channel_join(name) + static int l_mod_channel_join(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); +}; + +class ModChannelRef : public ModApiBase +{ +public: + ModChannelRef(const std::string &modchannel); + ~ModChannelRef() = default; + + static void Register(lua_State *L); + static void create(lua_State *L, const std::string &channel); + + // leave() + static int l_leave(lua_State *L); + + // send(message) + static int l_send_all(lua_State *L); + + // is_writeable() + static int l_is_writeable(lua_State *L); + +private: + // garbage collector + static int gc_object(lua_State *L); + + static ModChannelRef *checkobject(lua_State *L, int narg); + static ModChannel *getobject(lua_State *L, ModChannelRef *ref); + + std::string m_modchannel_name; + + static const char className[]; + static const luaL_Reg methods[]; +}; diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp new file mode 100644 index 0000000..bdc4844 --- /dev/null +++ b/src/script/lua_api/l_nodemeta.cpp @@ -0,0 +1,280 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_nodemeta.h" +#include "lua_api/l_internal.h" +#include "lua_api/l_inventory.h" +#include "common/c_content.h" +#include "serverenvironment.h" +#include "map.h" +#include "mapblock.h" +#include "server.h" + +/* + NodeMetaRef +*/ +NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if(!ud) luaL_typerror(L, narg, className); + return *(NodeMetaRef**)ud; // unbox pointer +} + +Metadata* NodeMetaRef::getmeta(bool auto_create) +{ + if (m_is_local) + return m_local_meta; + + NodeMetadata *meta = m_env->getMap().getNodeMetadata(m_p); + if (meta == NULL && auto_create) { + meta = new NodeMetadata(m_env->getGameDef()->idef()); + if (!m_env->getMap().setNodeMetadata(m_p, meta)) { + delete meta; + return NULL; + } + } + return meta; +} + +void NodeMetaRef::clearMeta() +{ + SANITY_CHECK(!m_is_local); + m_env->getMap().removeNodeMetadata(m_p); +} + +void NodeMetaRef::reportMetadataChange(const std::string *name) +{ + SANITY_CHECK(!m_is_local); + // Inform other things that the metadata has changed + NodeMetadata *meta = dynamic_cast<NodeMetadata*>(getmeta(false)); + + // If the metadata is now empty, get rid of it + if (meta && meta->empty()) { + clearMeta(); + meta = nullptr; + } + + MapEditEvent event; + event.type = MEET_BLOCK_NODE_METADATA_CHANGED; + event.p = m_p; + event.is_private_change = name && meta && meta->isPrivate(*name); + m_env->getMap().dispatchEvent(event); +} + +// Exported functions + +// garbage collector +int NodeMetaRef::gc_object(lua_State *L) { + NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +// get_inventory(self) +int NodeMetaRef::l_get_inventory(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + NodeMetaRef *ref = checkobject(L, 1); + ref->getmeta(true); // try to ensure the metadata exists + + InventoryLocation loc; + loc.setNodeMeta(ref->m_p); + InvRef::create(L, loc); + return 1; +} + +// mark_as_private(self, <string> or {<string>, <string>, ...}) +int NodeMetaRef::l_mark_as_private(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + NodeMetaRef *ref = checkobject(L, 1); + NodeMetadata *meta = dynamic_cast<NodeMetadata*>(ref->getmeta(true)); + assert(meta); + + if (lua_istable(L, 2)) { + lua_pushnil(L); + while (lua_next(L, 2) != 0) { + // key at index -2 and value at index -1 + luaL_checktype(L, -1, LUA_TSTRING); + meta->markPrivate(readParam<std::string>(L, -1), true); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } else if (lua_isstring(L, 2)) { + meta->markPrivate(readParam<std::string>(L, 2), true); + } + ref->reportMetadataChange(); + + return 0; +} + +void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta) +{ + // fields + MetaDataRef::handleToTable(L, _meta); + + NodeMetadata *meta = (NodeMetadata *) _meta; + + // inventory + Inventory *inv = meta->getInventory(); + if (inv) { + push_inventory_lists(L, *inv); + } else { + lua_newtable(L); + } + lua_setfield(L, -2, "inventory"); +} + +// from_table(self, table) +bool NodeMetaRef::handleFromTable(lua_State *L, int table, Metadata *_meta) +{ + // fields + if (!MetaDataRef::handleFromTable(L, table, _meta)) + return false; + + NodeMetadata *meta = (NodeMetadata*) _meta; + + // inventory + Inventory *inv = meta->getInventory(); + lua_getfield(L, table, "inventory"); + if (lua_istable(L, -1)) { + int inventorytable = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, inventorytable) != 0) { + // key at index -2 and value at index -1 + std::string name = luaL_checkstring(L, -2); + read_inventory_list(L, -1, inv, name.c_str(), getServer(L)); + lua_pop(L, 1); // Remove value, keep key for next iteration + } + lua_pop(L, 1); + } + + return true; +} + + +NodeMetaRef::NodeMetaRef(v3s16 p, ServerEnvironment *env): + m_p(p), + m_env(env) +{ +} + +NodeMetaRef::NodeMetaRef(Metadata *meta): + m_is_local(true), + m_local_meta(meta) +{ +} + +// Creates an NodeMetaRef and leaves it on top of stack +// Not callable from Lua; all references are created on the C side. +void NodeMetaRef::create(lua_State *L, v3s16 p, ServerEnvironment *env) +{ + NodeMetaRef *o = new NodeMetaRef(p, env); + //infostream<<"NodeMetaRef::create: o="<<o<<std::endl; + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +// Client-sided version of the above +void NodeMetaRef::createClient(lua_State *L, Metadata *meta) +{ + NodeMetaRef *o = new NodeMetaRef(meta); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +const char NodeMetaRef::className[] = "NodeMetaRef"; +void NodeMetaRef::RegisterCommon(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "metadata_class"); + lua_pushlstring(L, className, strlen(className)); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pushliteral(L, "__eq"); + lua_pushcfunction(L, l_equals); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable +} + +void NodeMetaRef::Register(lua_State *L) +{ + RegisterCommon(L); + luaL_register(L, nullptr, methodsServer); // fill methodtable + lua_pop(L, 1); // drop methodtable +} + + +const luaL_Reg NodeMetaRef::methodsServer[] = { + luamethod(MetaDataRef, contains), + luamethod(MetaDataRef, get), + luamethod(MetaDataRef, get_string), + luamethod(MetaDataRef, set_string), + luamethod(MetaDataRef, get_int), + luamethod(MetaDataRef, set_int), + luamethod(MetaDataRef, get_float), + luamethod(MetaDataRef, set_float), + luamethod(MetaDataRef, to_table), + luamethod(MetaDataRef, from_table), + luamethod(NodeMetaRef, get_inventory), + luamethod(NodeMetaRef, mark_as_private), + luamethod(MetaDataRef, equals), + {0,0} +}; + + +void NodeMetaRef::RegisterClient(lua_State *L) +{ + RegisterCommon(L); + luaL_register(L, nullptr, methodsClient); // fill methodtable + lua_pop(L, 1); // drop methodtable +} + + +const luaL_Reg NodeMetaRef::methodsClient[] = { + luamethod(MetaDataRef, contains), + luamethod(MetaDataRef, get), + luamethod(MetaDataRef, get_string), + luamethod(MetaDataRef, get_int), + luamethod(MetaDataRef, get_float), + luamethod(MetaDataRef, to_table), + {0,0} +}; diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h new file mode 100644 index 0000000..265ece3 --- /dev/null +++ b/src/script/lua_api/l_nodemeta.h @@ -0,0 +1,97 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" +#include "lua_api/l_metadata.h" +#include "irrlichttypes_bloated.h" +#include "nodemetadata.h" + +class ServerEnvironment; +class NodeMetadata; + +/* + NodeMetaRef +*/ + +class NodeMetaRef : public MetaDataRef { +private: + bool m_is_local = false; + // Set for server metadata + v3s16 m_p; + ServerEnvironment *m_env = nullptr; + // Set for client metadata + Metadata *m_local_meta = nullptr; + + static const char className[]; + static const luaL_Reg methodsServer[]; + static const luaL_Reg methodsClient[]; + + static NodeMetaRef *checkobject(lua_State *L, int narg); + + /** + * Retrieve metadata for a node. + * If @p auto_create is set and the specified node has no metadata information + * associated with it yet, the method attempts to attach a new metadata object + * to the node and returns a pointer to the metadata when successful. + * + * However, it is NOT guaranteed that the method will return a pointer, + * and @c NULL may be returned in case of an error regardless of @p auto_create. + * + * @param ref specifies the node for which the associated metadata is retrieved. + * @param auto_create when true, try to create metadata information for the node if it has none. + * @return pointer to a @c NodeMetadata object or @c NULL in case of error. + */ + virtual Metadata* getmeta(bool auto_create); + virtual void clearMeta(); + + virtual void reportMetadataChange(const std::string *name = nullptr); + + virtual void handleToTable(lua_State *L, Metadata *_meta); + virtual bool handleFromTable(lua_State *L, int table, Metadata *_meta); + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + // get_inventory(self) + static int l_get_inventory(lua_State *L); + + // mark_as_private(self, <string> or {<string>, <string>, ...}) + static int l_mark_as_private(lua_State *L); + +public: + NodeMetaRef(v3s16 p, ServerEnvironment *env); + NodeMetaRef(Metadata *meta); + + ~NodeMetaRef() = default; + + // Creates an NodeMetaRef and leaves it on top of stack + // Not callable from Lua; all references are created on the C side. + static void create(lua_State *L, v3s16 p, ServerEnvironment *env); + + // Client-sided version of the above + static void createClient(lua_State *L, Metadata *meta); + + static void RegisterCommon(lua_State *L); + static void Register(lua_State *L); + static void RegisterClient(lua_State *L); +}; diff --git a/src/script/lua_api/l_nodetimer.cpp b/src/script/lua_api/l_nodetimer.cpp new file mode 100644 index 0000000..8a30214 --- /dev/null +++ b/src/script/lua_api/l_nodetimer.cpp @@ -0,0 +1,141 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_nodetimer.h" +#include "lua_api/l_internal.h" +#include "serverenvironment.h" +#include "map.h" + + +int NodeTimerRef::gc_object(lua_State *L) { + NodeTimerRef *o = *(NodeTimerRef **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +NodeTimerRef* NodeTimerRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if(!ud) luaL_typerror(L, narg, className); + return *(NodeTimerRef**)ud; // unbox pointer +} + +int NodeTimerRef::l_set(lua_State *L) +{ + MAP_LOCK_REQUIRED; + NodeTimerRef *o = checkobject(L, 1); + f32 t = readParam<float>(L,2); + f32 e = readParam<float>(L,3); + o->m_map->setNodeTimer(NodeTimer(t, e, o->m_p)); + return 0; +} + +int NodeTimerRef::l_start(lua_State *L) +{ + MAP_LOCK_REQUIRED; + NodeTimerRef *o = checkobject(L, 1); + f32 t = readParam<float>(L,2); + o->m_map->setNodeTimer(NodeTimer(t, 0, o->m_p)); + return 0; +} + +int NodeTimerRef::l_stop(lua_State *L) +{ + MAP_LOCK_REQUIRED; + NodeTimerRef *o = checkobject(L, 1); + o->m_map->removeNodeTimer(o->m_p); + return 0; +} + +int NodeTimerRef::l_is_started(lua_State *L) +{ + MAP_LOCK_REQUIRED; + NodeTimerRef *o = checkobject(L, 1); + NodeTimer t = o->m_map->getNodeTimer(o->m_p); + lua_pushboolean(L,(t.timeout != 0)); + return 1; +} + +int NodeTimerRef::l_get_timeout(lua_State *L) +{ + MAP_LOCK_REQUIRED; + NodeTimerRef *o = checkobject(L, 1); + NodeTimer t = o->m_map->getNodeTimer(o->m_p); + lua_pushnumber(L,t.timeout); + return 1; +} + +int NodeTimerRef::l_get_elapsed(lua_State *L) +{ + MAP_LOCK_REQUIRED; + NodeTimerRef *o = checkobject(L, 1); + NodeTimer t = o->m_map->getNodeTimer(o->m_p); + lua_pushnumber(L,t.elapsed); + return 1; +} + +// Creates an NodeTimerRef and leaves it on top of stack +// Not callable from Lua; all references are created on the C side. +void NodeTimerRef::create(lua_State *L, v3s16 p, ServerMap *map) +{ + NodeTimerRef *o = new NodeTimerRef(p, map); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +void NodeTimerRef::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // drop methodtable + + // Cannot be created from Lua + //lua_register(L, className, create_object); +} + +const char NodeTimerRef::className[] = "NodeTimerRef"; +const luaL_Reg NodeTimerRef::methods[] = { + luamethod(NodeTimerRef, start), + luamethod(NodeTimerRef, set), + luamethod(NodeTimerRef, stop), + luamethod(NodeTimerRef, is_started), + luamethod(NodeTimerRef, get_timeout), + luamethod(NodeTimerRef, get_elapsed), + {0,0} +}; diff --git a/src/script/lua_api/l_nodetimer.h b/src/script/lua_api/l_nodetimer.h new file mode 100644 index 0000000..bbc975f --- /dev/null +++ b/src/script/lua_api/l_nodetimer.h @@ -0,0 +1,61 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_v3d.h" +#include "lua_api/l_base.h" + +class ServerMap; + +class NodeTimerRef : public ModApiBase +{ +private: + v3s16 m_p; + ServerMap *m_map; + + static const char className[]; + static const luaL_Reg methods[]; + + static int gc_object(lua_State *L); + + static NodeTimerRef *checkobject(lua_State *L, int narg); + + static int l_set(lua_State *L); + + static int l_start(lua_State *L); + + static int l_stop(lua_State *L); + + static int l_is_started(lua_State *L); + + static int l_get_timeout(lua_State *L); + + static int l_get_elapsed(lua_State *L); + +public: + NodeTimerRef(v3s16 p, ServerMap *map) : m_p(p), m_map(map) {} + ~NodeTimerRef() = default; + + // Creates an NodeTimerRef and leaves it on top of stack + // Not callable from Lua; all references are created on the C side. + static void create(lua_State *L, v3s16 p, ServerMap *map); + + static void Register(lua_State *L); +}; diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp new file mode 100644 index 0000000..5561eae --- /dev/null +++ b/src/script/lua_api/l_noise.cpp @@ -0,0 +1,763 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_noise.h" +#include "lua_api/l_internal.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "common/c_packer.h" +#include "log.h" +#include "porting.h" +#include "util/numeric.h" + +/////////////////////////////////////// +/* + LuaPerlinNoise +*/ + +LuaPerlinNoise::LuaPerlinNoise(const NoiseParams *params) : + np(*params) +{ +} + + +int LuaPerlinNoise::l_get_2d(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaPerlinNoise *o = checkobject(L, 1); + v2f p = readParam<v2f>(L, 2); + lua_Number val = NoisePerlin2D(&o->np, p.X, p.Y, 0); + lua_pushnumber(L, val); + return 1; +} + + +int LuaPerlinNoise::l_get_3d(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaPerlinNoise *o = checkobject(L, 1); + v3f p = check_v3f(L, 2); + lua_Number val = NoisePerlin3D(&o->np, p.X, p.Y, p.Z, 0); + lua_pushnumber(L, val); + return 1; +} + + +int LuaPerlinNoise::create_object(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + NoiseParams params; + + if (lua_istable(L, 1)) { + read_noiseparams(L, 1, ¶ms); + } else { + params.seed = luaL_checkint(L, 1); + params.octaves = luaL_checkint(L, 2); + params.persist = readParam<float>(L, 3); + params.spread = v3f(1, 1, 1) * readParam<float>(L, 4); + } + + LuaPerlinNoise *o = new LuaPerlinNoise(¶ms); + + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + + +int LuaPerlinNoise::gc_object(lua_State *L) +{ + LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + + +LuaPerlinNoise *LuaPerlinNoise::checkobject(lua_State *L, int narg) +{ + NO_MAP_LOCK_REQUIRED; + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + return *(LuaPerlinNoise **)ud; +} + + +void *LuaPerlinNoise::packIn(lua_State *L, int idx) +{ + LuaPerlinNoise *o = checkobject(L, idx); + return new NoiseParams(o->np); +} + +void LuaPerlinNoise::packOut(lua_State *L, void *ptr) +{ + NoiseParams *np = reinterpret_cast<NoiseParams*>(ptr); + if (L) { + LuaPerlinNoise *o = new LuaPerlinNoise(np); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + } + delete np; +} + + +void LuaPerlinNoise::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); + + luaL_register(L, nullptr, methods); + lua_pop(L, 1); + + lua_register(L, className, create_object); + + script_register_packer(L, className, packIn, packOut); +} + + +const char LuaPerlinNoise::className[] = "PerlinNoise"; +luaL_Reg LuaPerlinNoise::methods[] = { + luamethod_aliased(LuaPerlinNoise, get_2d, get2d), + luamethod_aliased(LuaPerlinNoise, get_3d, get3d), + {0,0} +}; + +/////////////////////////////////////// +/* + LuaPerlinNoiseMap +*/ + +LuaPerlinNoiseMap::LuaPerlinNoiseMap(const NoiseParams *np, s32 seed, v3s16 size) +{ + try { + noise = new Noise(np, seed, size.X, size.Y, size.Z); + } catch (InvalidNoiseParamsException &e) { + throw LuaError(e.what()); + } +} + + +LuaPerlinNoiseMap::~LuaPerlinNoiseMap() +{ + delete noise; +} + + +int LuaPerlinNoiseMap::l_get_2d_map(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + size_t i = 0; + + LuaPerlinNoiseMap *o = checkobject(L, 1); + v2f p = readParam<v2f>(L, 2); + + Noise *n = o->noise; + n->perlinMap2D(p.X, p.Y); + + lua_createtable(L, n->sy, 0); + for (u32 y = 0; y != n->sy; y++) { + lua_createtable(L, n->sx, 0); + for (u32 x = 0; x != n->sx; x++) { + lua_pushnumber(L, n->result[i++]); + lua_rawseti(L, -2, x + 1); + } + lua_rawseti(L, -2, y + 1); + } + return 1; +} + + +int LuaPerlinNoiseMap::l_get_2d_map_flat(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaPerlinNoiseMap *o = checkobject(L, 1); + v2f p = readParam<v2f>(L, 2); + bool use_buffer = lua_istable(L, 3); + + Noise *n = o->noise; + n->perlinMap2D(p.X, p.Y); + + size_t maplen = n->sx * n->sy; + + if (use_buffer) + lua_pushvalue(L, 3); + else + lua_createtable(L, maplen, 0); + + for (size_t i = 0; i != maplen; i++) { + lua_pushnumber(L, n->result[i]); + lua_rawseti(L, -2, i + 1); + } + return 1; +} + + +int LuaPerlinNoiseMap::l_get_3d_map(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + size_t i = 0; + + LuaPerlinNoiseMap *o = checkobject(L, 1); + v3f p = check_v3f(L, 2); + + if (!o->is3D()) + return 0; + + Noise *n = o->noise; + n->perlinMap3D(p.X, p.Y, p.Z); + + lua_createtable(L, n->sz, 0); + for (u32 z = 0; z != n->sz; z++) { + lua_createtable(L, n->sy, 0); + for (u32 y = 0; y != n->sy; y++) { + lua_createtable(L, n->sx, 0); + for (u32 x = 0; x != n->sx; x++) { + lua_pushnumber(L, n->result[i++]); + lua_rawseti(L, -2, x + 1); + } + lua_rawseti(L, -2, y + 1); + } + lua_rawseti(L, -2, z + 1); + } + return 1; +} + + +int LuaPerlinNoiseMap::l_get_3d_map_flat(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaPerlinNoiseMap *o = checkobject(L, 1); + v3f p = check_v3f(L, 2); + bool use_buffer = lua_istable(L, 3); + + if (!o->is3D()) + return 0; + + Noise *n = o->noise; + n->perlinMap3D(p.X, p.Y, p.Z); + + size_t maplen = n->sx * n->sy * n->sz; + + if (use_buffer) + lua_pushvalue(L, 3); + else + lua_createtable(L, maplen, 0); + + for (size_t i = 0; i != maplen; i++) { + lua_pushnumber(L, n->result[i]); + lua_rawseti(L, -2, i + 1); + } + return 1; +} + + +int LuaPerlinNoiseMap::l_calc_2d_map(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaPerlinNoiseMap *o = checkobject(L, 1); + v2f p = readParam<v2f>(L, 2); + + Noise *n = o->noise; + n->perlinMap2D(p.X, p.Y); + + return 0; +} + +int LuaPerlinNoiseMap::l_calc_3d_map(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaPerlinNoiseMap *o = checkobject(L, 1); + v3f p = check_v3f(L, 2); + + if (!o->is3D()) + return 0; + + Noise *n = o->noise; + n->perlinMap3D(p.X, p.Y, p.Z); + + return 0; +} + + +int LuaPerlinNoiseMap::l_get_map_slice(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaPerlinNoiseMap *o = checkobject(L, 1); + v3s16 slice_offset = read_v3s16(L, 2); + v3s16 slice_size = read_v3s16(L, 3); + bool use_buffer = lua_istable(L, 4); + + Noise *n = o->noise; + + if (use_buffer) + lua_pushvalue(L, 4); + else + lua_newtable(L); + + write_array_slice_float(L, lua_gettop(L), n->result, + v3u16(n->sx, n->sy, n->sz), + v3u16(slice_offset.X, slice_offset.Y, slice_offset.Z), + v3u16(slice_size.X, slice_size.Y, slice_size.Z)); + + return 1; +} + + +int LuaPerlinNoiseMap::create_object(lua_State *L) +{ + NoiseParams np; + if (!read_noiseparams(L, 1, &np)) + return 0; + v3s16 size = read_v3s16(L, 2); + + LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(&np, 0, size); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + + +int LuaPerlinNoiseMap::gc_object(lua_State *L) +{ + LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + + +LuaPerlinNoiseMap *LuaPerlinNoiseMap::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + + return *(LuaPerlinNoiseMap **)ud; +} + + +struct NoiseMapParams { + NoiseParams np; + s32 seed; + v3s16 size; +}; + +void *LuaPerlinNoiseMap::packIn(lua_State *L, int idx) +{ + LuaPerlinNoiseMap *o = checkobject(L, idx); + NoiseMapParams *ret = new NoiseMapParams(); + ret->np = o->noise->np; + ret->seed = o->noise->seed; + ret->size = v3s16(o->noise->sx, o->noise->sy, o->noise->sz); + return ret; +} + +void LuaPerlinNoiseMap::packOut(lua_State *L, void *ptr) +{ + NoiseMapParams *p = reinterpret_cast<NoiseMapParams*>(ptr); + if (L) { + LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(&p->np, p->seed, p->size); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + } + delete p; +} + + +void LuaPerlinNoiseMap::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); + + luaL_register(L, nullptr, methods); + lua_pop(L, 1); + + lua_register(L, className, create_object); + + script_register_packer(L, className, packIn, packOut); +} + + +const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap"; +luaL_Reg LuaPerlinNoiseMap::methods[] = { + luamethod_aliased(LuaPerlinNoiseMap, get_2d_map, get2dMap), + luamethod_aliased(LuaPerlinNoiseMap, get_2d_map_flat, get2dMap_flat), + luamethod_aliased(LuaPerlinNoiseMap, calc_2d_map, calc2dMap), + luamethod_aliased(LuaPerlinNoiseMap, get_3d_map, get3dMap), + luamethod_aliased(LuaPerlinNoiseMap, get_3d_map_flat, get3dMap_flat), + luamethod_aliased(LuaPerlinNoiseMap, calc_3d_map, calc3dMap), + luamethod_aliased(LuaPerlinNoiseMap, get_map_slice, getMapSlice), + {0,0} +}; + +/////////////////////////////////////// +/* + LuaPseudoRandom +*/ + +int LuaPseudoRandom::l_next(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaPseudoRandom *o = checkobject(L, 1); + int min = 0; + int max = 32767; + lua_settop(L, 3); + if (lua_isnumber(L, 2)) + min = luaL_checkinteger(L, 2); + if (lua_isnumber(L, 3)) + max = luaL_checkinteger(L, 3); + if (max < min) { + errorstream<<"PseudoRandom.next(): max="<<max<<" min="<<min<<std::endl; + throw LuaError("PseudoRandom.next(): max < min"); + } + if(max - min != 32767 && max - min > 32767/5) + throw LuaError("PseudoRandom.next() max-min is not 32767" + " and is > 32768/5. This is disallowed due to" + " the bad random distribution the" + " implementation would otherwise make."); + PseudoRandom &pseudo = o->m_pseudo; + int val = pseudo.next(); + val = (val % (max-min+1)) + min; + lua_pushinteger(L, val); + return 1; +} + + +int LuaPseudoRandom::create_object(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + u64 seed = luaL_checknumber(L, 1); + LuaPseudoRandom *o = new LuaPseudoRandom(seed); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + + +int LuaPseudoRandom::gc_object(lua_State *L) +{ + LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + + +LuaPseudoRandom *LuaPseudoRandom::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + return *(LuaPseudoRandom **)ud; +} + + +void LuaPseudoRandom::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); + + luaL_register(L, nullptr, methods); + lua_pop(L, 1); + + lua_register(L, className, create_object); +} + + +const char LuaPseudoRandom::className[] = "PseudoRandom"; +const luaL_Reg LuaPseudoRandom::methods[] = { + luamethod(LuaPseudoRandom, next), + {0,0} +}; + +/////////////////////////////////////// +/* + LuaPcgRandom +*/ + +int LuaPcgRandom::l_next(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaPcgRandom *o = checkobject(L, 1); + u32 min = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : o->m_rnd.RANDOM_MIN; + u32 max = lua_isnumber(L, 3) ? lua_tointeger(L, 3) : o->m_rnd.RANDOM_MAX; + + lua_pushinteger(L, o->m_rnd.range(min, max)); + return 1; +} + + +int LuaPcgRandom::l_rand_normal_dist(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaPcgRandom *o = checkobject(L, 1); + u32 min = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : o->m_rnd.RANDOM_MIN; + u32 max = lua_isnumber(L, 3) ? lua_tointeger(L, 3) : o->m_rnd.RANDOM_MAX; + int num_trials = lua_isnumber(L, 4) ? lua_tointeger(L, 4) : 6; + + lua_pushinteger(L, o->m_rnd.randNormalDist(min, max, num_trials)); + return 1; +} + + +int LuaPcgRandom::create_object(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + u64 seed = luaL_checknumber(L, 1); + LuaPcgRandom *o = lua_isnumber(L, 2) ? + new LuaPcgRandom(seed, lua_tointeger(L, 2)) : + new LuaPcgRandom(seed); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + + +int LuaPcgRandom::gc_object(lua_State *L) +{ + LuaPcgRandom *o = *(LuaPcgRandom **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + + +LuaPcgRandom *LuaPcgRandom::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + return *(LuaPcgRandom **)ud; +} + + +void LuaPcgRandom::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); + + luaL_register(L, nullptr, methods); + lua_pop(L, 1); + + lua_register(L, className, create_object); +} + + +const char LuaPcgRandom::className[] = "PcgRandom"; +const luaL_Reg LuaPcgRandom::methods[] = { + luamethod(LuaPcgRandom, next), + luamethod(LuaPcgRandom, rand_normal_dist), + {0,0} +}; + +/////////////////////////////////////// +/* + LuaSecureRandom +*/ + +bool LuaSecureRandom::fillRandBuf() +{ + return porting::secure_rand_fill_buf(m_rand_buf, RAND_BUF_SIZE); +} + +int LuaSecureRandom::l_next_bytes(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaSecureRandom *o = checkobject(L, 1); + u32 count = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : 1; + + // Limit count + count = MYMIN(RAND_BUF_SIZE, count); + + // Find out whether we can pass directly from our array, or have to do some gluing + size_t count_remaining = RAND_BUF_SIZE - o->m_rand_idx; + if (count_remaining >= count) { + lua_pushlstring(L, o->m_rand_buf + o->m_rand_idx, count); + o->m_rand_idx += count; + } else { + char output_buf[RAND_BUF_SIZE]; + + // Copy over with what we have left from our current buffer + memcpy(output_buf, o->m_rand_buf + o->m_rand_idx, count_remaining); + + // Refill buffer and copy over the remainder of what was requested + o->fillRandBuf(); + memcpy(output_buf + count_remaining, o->m_rand_buf, count - count_remaining); + + // Update index + o->m_rand_idx = count - count_remaining; + + lua_pushlstring(L, output_buf, count); + } + + return 1; +} + + +int LuaSecureRandom::create_object(lua_State *L) +{ + LuaSecureRandom *o = new LuaSecureRandom(); + + // Fail and return nil if we can't securely fill the buffer + if (!o->fillRandBuf()) { + delete o; + return 0; + } + + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + + +int LuaSecureRandom::gc_object(lua_State *L) +{ + LuaSecureRandom *o = *(LuaSecureRandom **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + + +LuaSecureRandom *LuaSecureRandom::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + return *(LuaSecureRandom **)ud; +} + + +void LuaSecureRandom::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); + + luaL_register(L, nullptr, methods); + lua_pop(L, 1); + + lua_register(L, className, create_object); +} + +const char LuaSecureRandom::className[] = "SecureRandom"; +const luaL_Reg LuaSecureRandom::methods[] = { + luamethod(LuaSecureRandom, next_bytes), + {0,0} +}; diff --git a/src/script/lua_api/l_noise.h b/src/script/lua_api/l_noise.h new file mode 100644 index 0000000..5d34a47 --- /dev/null +++ b/src/script/lua_api/l_noise.h @@ -0,0 +1,201 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_v3d.h" +#include "lua_api/l_base.h" +#include "noise.h" + +/* + LuaPerlinNoise +*/ +class LuaPerlinNoise : public ModApiBase +{ +private: + NoiseParams np; + + static const char className[]; + static luaL_Reg methods[]; + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + static int l_get_2d(lua_State *L); + static int l_get_3d(lua_State *L); + +public: + LuaPerlinNoise(const NoiseParams *params); + ~LuaPerlinNoise() = default; + + // LuaPerlinNoise(seed, octaves, persistence, scale) + // Creates an LuaPerlinNoise and leaves it on top of stack + static int create_object(lua_State *L); + + static LuaPerlinNoise *checkobject(lua_State *L, int narg); + + static void *packIn(lua_State *L, int idx); + static void packOut(lua_State *L, void *ptr); + + static void Register(lua_State *L); +}; + +/* + LuaPerlinNoiseMap +*/ +class LuaPerlinNoiseMap : public ModApiBase +{ + Noise *noise; + + static const char className[]; + static luaL_Reg methods[]; + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + static int l_get_2d_map(lua_State *L); + static int l_get_2d_map_flat(lua_State *L); + static int l_get_3d_map(lua_State *L); + static int l_get_3d_map_flat(lua_State *L); + + static int l_calc_2d_map(lua_State *L); + static int l_calc_3d_map(lua_State *L); + static int l_get_map_slice(lua_State *L); + +public: + LuaPerlinNoiseMap(const NoiseParams *np, s32 seed, v3s16 size); + ~LuaPerlinNoiseMap(); + + inline bool is3D() const { return noise->sz > 1; } + + // LuaPerlinNoiseMap(np, size) + // Creates an LuaPerlinNoiseMap and leaves it on top of stack + static int create_object(lua_State *L); + + static LuaPerlinNoiseMap *checkobject(lua_State *L, int narg); + + static void *packIn(lua_State *L, int idx); + static void packOut(lua_State *L, void *ptr); + + static void Register(lua_State *L); +}; + +/* + LuaPseudoRandom +*/ +class LuaPseudoRandom : public ModApiBase +{ +private: + PseudoRandom m_pseudo; + + static const char className[]; + static const luaL_Reg methods[]; + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + // next(self, min=0, max=32767) -> get next value + static int l_next(lua_State *L); + +public: + LuaPseudoRandom(s32 seed) : m_pseudo(seed) {} + + // LuaPseudoRandom(seed) + // Creates an LuaPseudoRandom and leaves it on top of stack + static int create_object(lua_State *L); + + static LuaPseudoRandom *checkobject(lua_State *L, int narg); + + static void Register(lua_State *L); +}; + +/* + LuaPcgRandom +*/ +class LuaPcgRandom : public ModApiBase +{ +private: + PcgRandom m_rnd; + + static const char className[]; + static const luaL_Reg methods[]; + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + // next(self, min=-2147483648, max=2147483647) -> get next value + static int l_next(lua_State *L); + + // rand_normal_dist(self, min=-2147483648, max=2147483647, num_trials=6) -> + // get next normally distributed random value + static int l_rand_normal_dist(lua_State *L); + +public: + LuaPcgRandom(u64 seed) : m_rnd(seed) {} + LuaPcgRandom(u64 seed, u64 seq) : m_rnd(seed, seq) {} + + // LuaPcgRandom(seed) + // Creates an LuaPcgRandom and leaves it on top of stack + static int create_object(lua_State *L); + + static LuaPcgRandom *checkobject(lua_State *L, int narg); + + static void Register(lua_State *L); +}; + +/* + LuaSecureRandom +*/ +class LuaSecureRandom : public ModApiBase +{ +private: + static const size_t RAND_BUF_SIZE = 2048; + static const char className[]; + static const luaL_Reg methods[]; + + u32 m_rand_idx; + char m_rand_buf[RAND_BUF_SIZE]; + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + // next_bytes(self, count) -> get count many bytes + static int l_next_bytes(lua_State *L); + +public: + bool fillRandBuf(); + + // LuaSecureRandom() + // Creates an LuaSecureRandom and leaves it on top of stack + static int create_object(lua_State *L); + + static LuaSecureRandom *checkobject(lua_State *L, int narg); + + static void Register(lua_State *L); +}; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp new file mode 100644 index 0000000..d6498bf --- /dev/null +++ b/src/script/lua_api/l_object.cpp @@ -0,0 +1,2503 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_object.h" +#include <cmath> +#include "lua_api/l_internal.h" +#include "lua_api/l_inventory.h" +#include "lua_api/l_item.h" +#include "lua_api/l_playermeta.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "log.h" +#include "tool.h" +#include "remoteplayer.h" +#include "server.h" +#include "hud.h" +#include "scripting_server.h" +#include "server/luaentity_sao.h" +#include "server/player_sao.h" +#include "server/serverinventorymgr.h" + +/* + ObjectRef +*/ + + +ObjectRef* ObjectRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (ud == nullptr) + luaL_typerror(L, narg, className); + return *(ObjectRef**)ud; // unbox pointer +} + +ServerActiveObject* ObjectRef::getobject(ObjectRef *ref) +{ + ServerActiveObject *sao = ref->m_object; + if (sao && sao->isGone()) + return nullptr; + return sao; +} + +LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref) +{ + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return nullptr; + if (sao->getType() != ACTIVEOBJECT_TYPE_LUAENTITY) + return nullptr; + return (LuaEntitySAO*)sao; +} + +PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref) +{ + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return nullptr; + if (sao->getType() != ACTIVEOBJECT_TYPE_PLAYER) + return nullptr; + return (PlayerSAO*)sao; +} + +RemotePlayer *ObjectRef::getplayer(ObjectRef *ref) +{ + PlayerSAO *playersao = getplayersao(ref); + if (playersao == nullptr) + return nullptr; + return playersao->getPlayer(); +} + +// Exported functions + +// garbage collector +int ObjectRef::gc_object(lua_State *L) { + ObjectRef *obj = *(ObjectRef **)(lua_touserdata(L, 1)); + delete obj; + return 0; +} + +// remove(self) +int ObjectRef::l_remove(lua_State *L) +{ + GET_ENV_PTR; + + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) + return 0; + + sao->clearChildAttachments(); + sao->clearParentAttachment(); + + verbosestream << "ObjectRef::l_remove(): id=" << sao->getId() << std::endl; + sao->markForRemoval(); + return 0; +} + +// get_pos(self) +int ObjectRef::l_get_pos(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + push_v3f(L, sao->getBasePosition() / BS); + return 1; +} + +// set_pos(self, pos) +int ObjectRef::l_set_pos(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + v3f pos = checkFloatPos(L, 2); + + sao->setPos(pos); + return 0; +} + +// move_to(self, pos, continuous) +int ObjectRef::l_move_to(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + v3f pos = checkFloatPos(L, 2); + bool continuous = readParam<bool>(L, 3); + + sao->moveTo(pos, continuous); + return 0; +} + +// punch(self, puncher, time_from_last_punch, tool_capabilities, dir) +int ObjectRef::l_punch(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ObjectRef *puncher_ref = checkobject(L, 2); + ServerActiveObject *sao = getobject(ref); + ServerActiveObject *puncher = getobject(puncher_ref); + if (sao == nullptr || puncher == nullptr) + return 0; + + float time_from_last_punch = readParam<float>(L, 3, 1000000.0f); + ToolCapabilities toolcap = read_tool_capabilities(L, 4); + v3f dir = readParam<v3f>(L, 5, sao->getBasePosition() - puncher->getBasePosition()); + dir.normalize(); + + u32 wear = sao->punch(dir, &toolcap, puncher, time_from_last_punch); + lua_pushnumber(L, wear); + + return 1; +} + +// right_click(self, clicker) +int ObjectRef::l_right_click(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ObjectRef *ref2 = checkobject(L, 2); + ServerActiveObject *sao = getobject(ref); + ServerActiveObject *sao2 = getobject(ref2); + if (sao == nullptr || sao2 == nullptr) + return 0; + + sao->rightClick(sao2); + return 0; +} + +// set_hp(self, hp, reason) +int ObjectRef::l_set_hp(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + int hp = readParam<float>(L, 2); + PlayerHPChangeReason reason(PlayerHPChangeReason::SET_HP); + + reason.from_mod = true; + if (lua_istable(L, 3)) { + lua_pushvalue(L, 3); + + lua_getfield(L, -1, "type"); + if (lua_isstring(L, -1) && + !reason.setTypeFromString(readParam<std::string>(L, -1))) { + errorstream << "Bad type given!" << std::endl; + } + lua_pop(L, 1); + + reason.lua_reference = luaL_ref(L, LUA_REGISTRYINDEX); + } + + sao->setHP(hp, reason); + if (reason.hasLuaReference()) + luaL_unref(L, LUA_REGISTRYINDEX, reason.lua_reference); + return 0; +} + +// get_hp(self) +int ObjectRef::l_get_hp(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) { + // Default hp is 1 + lua_pushnumber(L, 1); + return 1; + } + + int hp = sao->getHP(); + + lua_pushnumber(L, hp); + return 1; +} + +// get_inventory(self) +int ObjectRef::l_get_inventory(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + InventoryLocation loc = sao->getInventoryLocation(); + if (getServerInventoryMgr(L)->getInventory(loc) != nullptr) + InvRef::create(L, loc); + else + lua_pushnil(L); // An object may have no inventory (nil) + return 1; +} + +// get_wield_list(self) +int ObjectRef::l_get_wield_list(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + lua_pushstring(L, sao->getWieldList().c_str()); + return 1; +} + +// get_wield_index(self) +int ObjectRef::l_get_wield_index(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + lua_pushinteger(L, sao->getWieldIndex() + 1); + return 1; +} + +// get_wielded_item(self) +int ObjectRef::l_get_wielded_item(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) { + // Empty ItemStack + LuaItemStack::create(L, ItemStack()); + return 1; + } + + ItemStack selected_item; + sao->getWieldedItem(&selected_item, nullptr); + LuaItemStack::create(L, selected_item); + return 1; +} + +// set_wielded_item(self, item) +int ObjectRef::l_set_wielded_item(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + ItemStack item = read_item(L, 2, getServer(L)->idef()); + + bool success = sao->setWieldedItem(item); + if (success && sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) { + getServer(L)->SendInventory((PlayerSAO *)sao, true); + } + lua_pushboolean(L, success); + return 1; +} + +// set_armor_groups(self, groups) +int ObjectRef::l_set_armor_groups(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + ItemGroupList groups; + + read_groups(L, 2, groups); + if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) { + if (!g_settings->getBool("enable_damage") && !itemgroup_get(groups, "immortal")) { + warningstream << "Mod tried to enable damage for a player, but it's " + "disabled globally. Ignoring." << std::endl; + infostream << script_get_backtrace(L) << std::endl; + groups["immortal"] = 1; + } + } + + sao->setArmorGroups(groups); + return 0; +} + +// get_armor_groups(self) +int ObjectRef::l_get_armor_groups(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + push_groups(L, sao->getArmorGroups()); + return 1; +} + +// set_animation(self, frame_range, frame_speed, frame_blend, frame_loop) +int ObjectRef::l_set_animation(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + v2f frame_range = readParam<v2f>(L, 2, v2f(1, 1)); + float frame_speed = readParam<float>(L, 3, 15.0f); + float frame_blend = readParam<float>(L, 4, 0.0f); + bool frame_loop = readParam<bool>(L, 5, true); + + sao->setAnimation(frame_range, frame_speed, frame_blend, frame_loop); + return 0; +} + +// get_animation(self) +int ObjectRef::l_get_animation(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + v2f frames = v2f(1, 1); + float frame_speed = 15; + float frame_blend = 0; + bool frame_loop = true; + + sao->getAnimation(&frames, &frame_speed, &frame_blend, &frame_loop); + push_v2f(L, frames); + lua_pushnumber(L, frame_speed); + lua_pushnumber(L, frame_blend); + lua_pushboolean(L, frame_loop); + return 4; +} + +// set_local_animation(self, idle, walk, dig, walk_while_dig, frame_speed) +int ObjectRef::l_set_local_animation(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + v2s32 frames[4]; + for (int i=0;i<4;i++) { + if (!lua_isnil(L, 2+1)) + frames[i] = read_v2s32(L, 2+i); + } + float frame_speed = readParam<float>(L, 6, 30.0f); + + getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed); + return 0; +} + +// get_local_animation(self) +int ObjectRef::l_get_local_animation(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + v2s32 frames[4]; + float frame_speed; + player->getLocalAnimations(frames, &frame_speed); + + for (const v2s32 &frame : frames) { + push_v2s32(L, frame); + } + + lua_pushnumber(L, frame_speed); + return 5; +} + +// set_eye_offset(self, firstperson, thirdperson) +int ObjectRef::l_set_eye_offset(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + v3f offset_first = readParam<v3f>(L, 2, v3f(0, 0, 0)); + v3f offset_third = readParam<v3f>(L, 3, v3f(0, 0, 0)); + + // Prevent abuse of offset values (keep player always visible) + offset_third.X = rangelim(offset_third.X,-10,10); + offset_third.Z = rangelim(offset_third.Z,-5,5); + /* TODO: if possible: improve the camera collision detection to allow Y <= -1.5) */ + offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS + + getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third); + return 0; +} + +// get_eye_offset(self) +int ObjectRef::l_get_eye_offset(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + push_v3f(L, player->eye_offset_first); + push_v3f(L, player->eye_offset_third); + return 2; +} + +// send_mapblock(self, pos) +int ObjectRef::l_send_mapblock(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + v3s16 pos = read_v3s16(L, 2); + + session_t peer_id = player->getPeerId(); + bool r = getServer(L)->SendBlock(peer_id, pos); + + lua_pushboolean(L, r); + return 1; +} + +// set_animation_frame_speed(self, frame_speed) +int ObjectRef::l_set_animation_frame_speed(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + if (!lua_isnil(L, 2)) { + float frame_speed = readParam<float>(L, 2); + sao->setAnimationSpeed(frame_speed); + lua_pushboolean(L, true); + } else { + lua_pushboolean(L, false); + } + return 1; +} + +// set_bone_position(self, bone, position, rotation) +int ObjectRef::l_set_bone_position(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + std::string bone = readParam<std::string>(L, 2, ""); + v3f position = readParam<v3f>(L, 3, v3f(0, 0, 0)); + v3f rotation = readParam<v3f>(L, 4, v3f(0, 0, 0)); + + sao->setBonePosition(bone, position, rotation); + return 0; +} + +// get_bone_position(self, bone) +int ObjectRef::l_get_bone_position(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + std::string bone = readParam<std::string>(L, 2, ""); + + v3f position = v3f(0, 0, 0); + v3f rotation = v3f(0, 0, 0); + sao->getBonePosition(bone, &position, &rotation); + + push_v3f(L, position); + push_v3f(L, rotation); + return 2; +} + +// set_attach(self, parent, bone, position, rotation, force_visible) +int ObjectRef::l_set_attach(lua_State *L) +{ + GET_ENV_PTR; + ObjectRef *ref = checkobject(L, 1); + ObjectRef *parent_ref = checkobject(L, 2); + ServerActiveObject *sao = getobject(ref); + ServerActiveObject *parent = getobject(parent_ref); + if (sao == nullptr || parent == nullptr) + return 0; + if (sao == parent) + throw LuaError("ObjectRef::set_attach: attaching object to itself is not allowed."); + + int parent_id; + std::string bone; + v3f position; + v3f rotation; + bool force_visible; + + sao->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible); + if (parent_id) { + ServerActiveObject *old_parent = env->getActiveObject(parent_id); + old_parent->removeAttachmentChild(sao->getId()); + } + + bone = readParam<std::string>(L, 3, ""); + position = readParam<v3f>(L, 4, v3f(0, 0, 0)); + rotation = readParam<v3f>(L, 5, v3f(0, 0, 0)); + force_visible = readParam<bool>(L, 6, false); + + sao->setAttachment(parent->getId(), bone, position, rotation, force_visible); + parent->addAttachmentChild(sao->getId()); + return 0; +} + +// get_attach(self) +int ObjectRef::l_get_attach(lua_State *L) +{ + GET_ENV_PTR; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + int parent_id; + std::string bone; + v3f position; + v3f rotation; + bool force_visible; + + sao->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible); + if (parent_id == 0) + return 0; + + ServerActiveObject *parent = env->getActiveObject(parent_id); + getScriptApiBase(L)->objectrefGetOrCreate(L, parent); + lua_pushlstring(L, bone.c_str(), bone.size()); + push_v3f(L, position); + push_v3f(L, rotation); + lua_pushboolean(L, force_visible); + return 5; +} + +// get_children(self) +int ObjectRef::l_get_children(lua_State *L) +{ + GET_ENV_PTR; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + const std::unordered_set<int> child_ids = sao->getAttachmentChildIds(); + int i = 0; + + lua_createtable(L, child_ids.size(), 0); + for (const int id : child_ids) { + ServerActiveObject *child = env->getActiveObject(id); + getScriptApiBase(L)->objectrefGetOrCreate(L, child); + lua_rawseti(L, -2, ++i); + } + return 1; +} + +// set_detach(self) +int ObjectRef::l_set_detach(lua_State *L) +{ + GET_ENV_PTR; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + sao->clearParentAttachment(); + return 0; +} + +// set_properties(self, properties) +int ObjectRef::l_set_properties(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + ObjectProperties *prop = sao->accessObjectProperties(); + if (prop == nullptr) + return 0; + + read_object_properties(L, 2, sao, prop, getServer(L)->idef()); + prop->validate(); + sao->notifyObjectPropertiesModified(); + return 0; +} + +// get_properties(self) +int ObjectRef::l_get_properties(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + ObjectProperties *prop = sao->accessObjectProperties(); + if (prop == nullptr) + return 0; + + push_object_properties(L, prop); + return 1; +} + +// is_player(self) +int ObjectRef::l_is_player(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + lua_pushboolean(L, (player != nullptr)); + return 1; +} + +// set_nametag_attributes(self, attributes) +int ObjectRef::l_set_nametag_attributes(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + ObjectProperties *prop = sao->accessObjectProperties(); + if (prop == nullptr) + return 0; + + lua_getfield(L, 2, "color"); + if (!lua_isnil(L, -1)) { + video::SColor color = prop->nametag_color; + read_color(L, -1, &color); + prop->nametag_color = color; + } + lua_pop(L, 1); + + lua_getfield(L, -1, "bgcolor"); + if (!lua_isnil(L, -1)) { + if (lua_toboolean(L, -1)) { + video::SColor color; + if (read_color(L, -1, &color)) + prop->nametag_bgcolor = color; + } else { + prop->nametag_bgcolor = nullopt; + } + } + lua_pop(L, 1); + + std::string nametag = getstringfield_default(L, 2, "text", ""); + prop->nametag = nametag; + + prop->validate(); + sao->notifyObjectPropertiesModified(); + return 0; +} + +// get_nametag_attributes(self) +int ObjectRef::l_get_nametag_attributes(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + ObjectProperties *prop = sao->accessObjectProperties(); + if (!prop) + return 0; + + lua_newtable(L); + + push_ARGB8(L, prop->nametag_color); + lua_setfield(L, -2, "color"); + + if (prop->nametag_bgcolor) { + push_ARGB8(L, prop->nametag_bgcolor.value()); + lua_setfield(L, -2, "bgcolor"); + } else { + lua_pushboolean(L, false); + lua_setfield(L, -2, "bgcolor"); + } + + lua_pushstring(L, prop->nametag.c_str()); + lua_setfield(L, -2, "text"); + + + + return 1; +} + +/* LuaEntitySAO-only */ + +// set_velocity(self, velocity) +int ObjectRef::l_set_velocity(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *sao = getluaobject(ref); + if (sao == nullptr) + return 0; + + v3f vel = checkFloatPos(L, 2); + + sao->setVelocity(vel); + return 0; +} + +// add_velocity(self, velocity) +int ObjectRef::l_add_velocity(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + v3f vel = checkFloatPos(L, 2); + + if (sao->getType() == ACTIVEOBJECT_TYPE_LUAENTITY) { + LuaEntitySAO *entitysao = dynamic_cast<LuaEntitySAO*>(sao); + entitysao->addVelocity(vel); + } else if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) { + PlayerSAO *playersao = dynamic_cast<PlayerSAO*>(sao); + playersao->setMaxSpeedOverride(vel); + getServer(L)->SendPlayerSpeed(playersao->getPeerID(), vel); + } + + return 0; +} + +// get_velocity(self) +int ObjectRef::l_get_velocity(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + if (sao->getType() == ACTIVEOBJECT_TYPE_LUAENTITY) { + LuaEntitySAO *entitysao = dynamic_cast<LuaEntitySAO*>(sao); + v3f vel = entitysao->getVelocity(); + pushFloatPos(L, vel); + return 1; + } else if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) { + RemotePlayer *player = dynamic_cast<PlayerSAO*>(sao)->getPlayer(); + push_v3f(L, player->getSpeed() / BS); + return 1; + } + + lua_pushnil(L); + return 1; +} + +// set_acceleration(self, acceleration) +int ObjectRef::l_set_acceleration(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + if (entitysao == nullptr) + return 0; + + v3f acceleration = checkFloatPos(L, 2); + + entitysao->setAcceleration(acceleration); + return 0; +} + +// get_acceleration(self) +int ObjectRef::l_get_acceleration(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + if (entitysao == nullptr) + return 0; + + v3f acceleration = entitysao->getAcceleration(); + pushFloatPos(L, acceleration); + return 1; +} + +// set_rotation(self, rotation) +int ObjectRef::l_set_rotation(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + if (entitysao == nullptr) + return 0; + + v3f rotation = check_v3f(L, 2) * core::RADTODEG; + + entitysao->setRotation(rotation); + return 0; +} + +// get_rotation(self) +int ObjectRef::l_get_rotation(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + if (entitysao == nullptr) + return 0; + + v3f rotation = entitysao->getRotation() * core::DEGTORAD; + + lua_newtable(L); + push_v3f(L, rotation); + return 1; +} + +// set_yaw(self, yaw) +int ObjectRef::l_set_yaw(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + if (entitysao == nullptr) + return 0; + + float yaw = readParam<float>(L, 2) * core::RADTODEG; + + entitysao->setRotation(v3f(0, yaw, 0)); + return 0; +} + +// get_yaw(self) +int ObjectRef::l_get_yaw(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + if (entitysao == nullptr) + return 0; + + float yaw = entitysao->getRotation().Y * core::DEGTORAD; + + lua_pushnumber(L, yaw); + return 1; +} + +// set_texture_mod(self, mod) +int ObjectRef::l_set_texture_mod(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + if (entitysao == nullptr) + return 0; + + std::string mod = readParam<std::string>(L, 2); + + entitysao->setTextureMod(mod); + return 0; +} + +// get_texture_mod(self) +int ObjectRef::l_get_texture_mod(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + if (entitysao == nullptr) + return 0; + + std::string mod = entitysao->getTextureMod(); + + lua_pushstring(L, mod.c_str()); + return 1; +} + +// set_sprite(self, start_frame, num_frames, framelength, select_x_by_camera) +int ObjectRef::l_set_sprite(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + if (entitysao == nullptr) + return 0; + + v2s16 start_frame = readParam<v2s16>(L, 2, v2s16(0,0)); + int num_frames = readParam<int>(L, 3, 1); + float framelength = readParam<float>(L, 4, 0.2f); + bool select_x_by_camera = readParam<bool>(L, 5, false); + + entitysao->setSprite(start_frame, num_frames, framelength, select_x_by_camera); + return 0; +} + +// DEPRECATED +// get_entity_name(self) +int ObjectRef::l_get_entity_name(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + log_deprecated(L,"Deprecated call to \"get_entity_name"); + if (entitysao == nullptr) + return 0; + + std::string name = entitysao->getName(); + + lua_pushstring(L, name.c_str()); + return 1; +} + +// get_luaentity(self) +int ObjectRef::l_get_luaentity(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + if (entitysao == nullptr) + return 0; + + luaentity_get(L, entitysao->getId()); + return 1; +} + +/* Player-only */ + +// get_player_name(self) +int ObjectRef::l_get_player_name(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) { + lua_pushlstring(L, "", 0); + return 1; + } + + lua_pushstring(L, player->getName()); + return 1; +} + +// get_look_dir(self) +int ObjectRef::l_get_look_dir(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + float pitch = playersao->getRadLookPitchDep(); + float yaw = playersao->getRadYawDep(); + v3f v(std::cos(pitch) * std::cos(yaw), std::sin(pitch), std::cos(pitch) * + std::sin(yaw)); + + push_v3f(L, v); + return 1; +} + +// DEPRECATED +// get_look_pitch(self) +int ObjectRef::l_get_look_pitch(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + log_deprecated(L, + "Deprecated call to get_look_pitch, use get_look_vertical instead"); + + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + lua_pushnumber(L, playersao->getRadLookPitchDep()); + return 1; +} + +// DEPRECATED +// get_look_yaw(self) +int ObjectRef::l_get_look_yaw(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + log_deprecated(L, + "Deprecated call to get_look_yaw, use get_look_horizontal instead"); + + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + lua_pushnumber(L, playersao->getRadYawDep()); + return 1; +} + +// get_look_vertical(self) +int ObjectRef::l_get_look_vertical(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + lua_pushnumber(L, playersao->getRadLookPitch()); + return 1; +} + +// get_look_horizontal(self) +int ObjectRef::l_get_look_horizontal(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + lua_pushnumber(L, playersao->getRadRotation().Y); + return 1; +} + +// set_look_vertical(self, radians) +int ObjectRef::l_set_look_vertical(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + float pitch = readParam<float>(L, 2) * core::RADTODEG; + + playersao->setLookPitchAndSend(pitch); + return 0; +} + +// set_look_horizontal(self, radians) +int ObjectRef::l_set_look_horizontal(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + float yaw = readParam<float>(L, 2) * core::RADTODEG; + + playersao->setPlayerYawAndSend(yaw); + return 0; +} + +// DEPRECATED +// set_look_pitch(self, radians) +int ObjectRef::l_set_look_pitch(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + log_deprecated(L, + "Deprecated call to set_look_pitch, use set_look_vertical instead."); + + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + float pitch = readParam<float>(L, 2) * core::RADTODEG; + + playersao->setLookPitchAndSend(pitch); + return 0; +} + +// DEPRECATED +// set_look_yaw(self, radians) +int ObjectRef::l_set_look_yaw(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + log_deprecated(L, + "Deprecated call to set_look_yaw, use set_look_horizontal instead."); + + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + float yaw = readParam<float>(L, 2) * core::RADTODEG; + + playersao->setPlayerYawAndSend(yaw); + return 0; +} + +// set_fov(self, degrees, is_multiplier, transition_time) +int ObjectRef::l_set_fov(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + float degrees = static_cast<f32>(luaL_checknumber(L, 2)); + bool is_multiplier = readParam<bool>(L, 3, false); + float transition_time = lua_isnumber(L, 4) ? + static_cast<f32>(luaL_checknumber(L, 4)) : 0.0f; + + player->setFov({degrees, is_multiplier, transition_time}); + getServer(L)->SendPlayerFov(player->getPeerId()); + return 0; +} + +// get_fov(self) +int ObjectRef::l_get_fov(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + PlayerFovSpec fov_spec = player->getFov(); + + lua_pushnumber(L, fov_spec.fov); + lua_pushboolean(L, fov_spec.is_multiplier); + lua_pushnumber(L, fov_spec.transition_time); + return 3; +} + +// set_breath(self, breath) +int ObjectRef::l_set_breath(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + u16 breath = luaL_checknumber(L, 2); + + playersao->setBreath(breath); + return 0; +} + +// get_breath(self) +int ObjectRef::l_get_breath(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + u16 breath = playersao->getBreath(); + + lua_pushinteger(L, breath); + return 1; +} + +// set_attribute(self, attribute, value) +int ObjectRef::l_set_attribute(lua_State *L) +{ + log_deprecated(L, + "Deprecated call to set_attribute, use MetaDataRef methods instead."); + + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + std::string attr = luaL_checkstring(L, 2); + if (lua_isnil(L, 3)) { + playersao->getMeta().removeString(attr); + } else { + std::string value = luaL_checkstring(L, 3); + playersao->getMeta().setString(attr, value); + } + return 1; +} + +// get_attribute(self, attribute) +int ObjectRef::l_get_attribute(lua_State *L) +{ + log_deprecated(L, + "Deprecated call to get_attribute, use MetaDataRef methods instead."); + + ObjectRef *ref = checkobject(L, 1); + PlayerSAO* playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + std::string attr = luaL_checkstring(L, 2); + + std::string value; + if (playersao->getMeta().getStringToRef(attr, value)) { + lua_pushstring(L, value.c_str()); + return 1; + } + + return 0; +} + + +// get_meta(self, attribute) +int ObjectRef::l_get_meta(lua_State *L) +{ + ObjectRef *ref = checkobject(L, 1); + PlayerSAO *playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + PlayerMetaRef::create(L, &playersao->getMeta()); + return 1; +} + + +// set_inventory_formspec(self, formspec) +int ObjectRef::l_set_inventory_formspec(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + std::string formspec = luaL_checkstring(L, 2); + + player->inventory_formspec = formspec; + getServer(L)->reportInventoryFormspecModified(player->getName()); + return 0; +} + +// get_inventory_formspec(self) -> formspec +int ObjectRef::l_get_inventory_formspec(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + std::string formspec = player->inventory_formspec; + + lua_pushlstring(L, formspec.c_str(), formspec.size()); + return 1; +} + +// set_formspec_prepend(self, formspec) +int ObjectRef::l_set_formspec_prepend(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + std::string formspec = luaL_checkstring(L, 2); + + player->formspec_prepend = formspec; + getServer(L)->reportFormspecPrependModified(player->getName()); + return 0; +} + +// get_formspec_prepend(self) +int ObjectRef::l_get_formspec_prepend(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + std::string formspec = player->formspec_prepend; + + lua_pushlstring(L, formspec.c_str(), formspec.size()); + return 1; +} + +// get_player_control(self) +int ObjectRef::l_get_player_control(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + + lua_newtable(L); + if (player == nullptr) + return 1; + + const PlayerControl &control = player->getPlayerControl(); + lua_pushboolean(L, control.direction_keys & (1 << 0)); + lua_setfield(L, -2, "up"); + lua_pushboolean(L, control.direction_keys & (1 << 1)); + lua_setfield(L, -2, "down"); + lua_pushboolean(L, control.direction_keys & (1 << 2)); + lua_setfield(L, -2, "left"); + lua_pushboolean(L, control.direction_keys & (1 << 3)); + lua_setfield(L, -2, "right"); + lua_pushboolean(L, control.jump); + lua_setfield(L, -2, "jump"); + lua_pushboolean(L, control.aux1); + lua_setfield(L, -2, "aux1"); + lua_pushboolean(L, control.sneak); + lua_setfield(L, -2, "sneak"); + lua_pushboolean(L, control.dig); + lua_setfield(L, -2, "dig"); + lua_pushboolean(L, control.place); + lua_setfield(L, -2, "place"); + // Legacy fields to ensure mod compatibility + lua_pushboolean(L, control.dig); + lua_setfield(L, -2, "LMB"); + lua_pushboolean(L, control.place); + lua_setfield(L, -2, "RMB"); + lua_pushboolean(L, control.zoom); + lua_setfield(L, -2, "zoom"); + return 1; +} + +// get_player_control_bits(self) +int ObjectRef::l_get_player_control_bits(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) { + lua_pushinteger(L, 0); + return 1; + } + + const auto &c = player->getPlayerControl(); + + // This is very close to PlayerControl::getKeysPressed() but duplicated + // here so the encoding in the API is not inadvertedly changed. + u32 keypress_bits = + c.direction_keys | + ( (u32)(c.jump & 1) << 4) | + ( (u32)(c.aux1 & 1) << 5) | + ( (u32)(c.sneak & 1) << 6) | + ( (u32)(c.dig & 1) << 7) | + ( (u32)(c.place & 1) << 8) | + ( (u32)(c.zoom & 1) << 9) + ; + + lua_pushinteger(L, keypress_bits); + return 1; +} + +// set_physics_override(self, override_table) +int ObjectRef::l_set_physics_override(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + PlayerSAO *playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + if (lua_istable(L, 2)) { + bool modified = false; + modified |= getfloatfield(L, 2, "speed", playersao->m_physics_override_speed); + modified |= getfloatfield(L, 2, "jump", playersao->m_physics_override_jump); + modified |= getfloatfield(L, 2, "gravity", playersao->m_physics_override_gravity); + modified |= getboolfield(L, 2, "sneak", playersao->m_physics_override_sneak); + modified |= getboolfield(L, 2, "sneak_glitch", playersao->m_physics_override_sneak_glitch); + modified |= getboolfield(L, 2, "new_move", playersao->m_physics_override_new_move); + if (modified) + playersao->m_physics_override_sent = false; + } else { + // old, non-table format + // TODO: Remove this code after version 5.4.0 + log_deprecated(L, "Deprecated use of set_physics_override(num, num, num)"); + + if (!lua_isnil(L, 2)) { + playersao->m_physics_override_speed = lua_tonumber(L, 2); + playersao->m_physics_override_sent = false; + } + if (!lua_isnil(L, 3)) { + playersao->m_physics_override_jump = lua_tonumber(L, 3); + playersao->m_physics_override_sent = false; + } + if (!lua_isnil(L, 4)) { + playersao->m_physics_override_gravity = lua_tonumber(L, 4); + playersao->m_physics_override_sent = false; + } + } + return 0; +} + +// get_physics_override(self) +int ObjectRef::l_get_physics_override(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + PlayerSAO *playersao = getplayersao(ref); + if (playersao == nullptr) + return 0; + + lua_newtable(L); + lua_pushnumber(L, playersao->m_physics_override_speed); + lua_setfield(L, -2, "speed"); + lua_pushnumber(L, playersao->m_physics_override_jump); + lua_setfield(L, -2, "jump"); + lua_pushnumber(L, playersao->m_physics_override_gravity); + lua_setfield(L, -2, "gravity"); + lua_pushboolean(L, playersao->m_physics_override_sneak); + lua_setfield(L, -2, "sneak"); + lua_pushboolean(L, playersao->m_physics_override_sneak_glitch); + lua_setfield(L, -2, "sneak_glitch"); + lua_pushboolean(L, playersao->m_physics_override_new_move); + lua_setfield(L, -2, "new_move"); + return 1; +} + +// hud_add(self, hud) +int ObjectRef::l_hud_add(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + HudElement *elem = new HudElement; + read_hud_element(L, elem); + + u32 id = getServer(L)->hudAdd(player, elem); + if (id == U32_MAX) { + delete elem; + return 0; + } + + lua_pushnumber(L, id); + return 1; +} + +// hud_remove(self, id) +int ObjectRef::l_hud_remove(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + u32 id = luaL_checkint(L, 2); + + if (!getServer(L)->hudRemove(player, id)) + return 0; + + lua_pushboolean(L, true); + return 1; +} + +// hud_change(self, id, stat, data) +int ObjectRef::l_hud_change(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + u32 id = luaL_checkint(L, 2); + + HudElement *elem = player->getHud(id); + if (elem == nullptr) + return 0; + + HudElementStat stat; + void *value = nullptr; + bool ok = read_hud_change(L, stat, elem, &value); + + if (ok) + getServer(L)->hudChange(player, id, stat, value); + + lua_pushboolean(L, ok); + return 1; +} + +// hud_get(self, id) +int ObjectRef::l_hud_get(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + u32 id = luaL_checkint(L, 2); + + HudElement *elem = player->getHud(id); + if (elem == nullptr) + return 0; + + push_hud_element(L, elem); + return 1; +} + +// hud_set_flags(self, flags) +int ObjectRef::l_hud_set_flags(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + u32 flags = 0; + u32 mask = 0; + bool flag; + + const EnumString *esp = es_HudBuiltinElement; + for (int i = 0; esp[i].str; i++) { + if (getboolfield(L, 2, esp[i].str, flag)) { + flags |= esp[i].num * flag; + mask |= esp[i].num; + } + } + if (!getServer(L)->hudSetFlags(player, flags, mask)) + return 0; + + return 0; +} + +// hud_get_flags(self) +int ObjectRef::l_hud_get_flags(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + lua_newtable(L); + const EnumString *esp = es_HudBuiltinElement; + for (int i = 0; esp[i].str; i++) { + lua_pushboolean(L, (player->hud_flags & esp[i].num) != 0); + lua_setfield(L, -2, esp[i].str); + } + return 1; +} + +// hud_set_hotbar_itemcount(self, hotbar_itemcount) +int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + s32 hotbar_itemcount = luaL_checkint(L, 2); + + if (!getServer(L)->hudSetHotbarItemcount(player, hotbar_itemcount)) + return 0; + + lua_pushboolean(L, true); + return 1; +} + +// hud_get_hotbar_itemcount(self) +int ObjectRef::l_hud_get_hotbar_itemcount(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + lua_pushnumber(L, player->getHotbarItemcount()); + return 1; +} + +// hud_set_hotbar_image(self, name) +int ObjectRef::l_hud_set_hotbar_image(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + std::string name = readParam<std::string>(L, 2); + + getServer(L)->hudSetHotbarImage(player, name); + return 1; +} + +// hud_get_hotbar_image(self) +int ObjectRef::l_hud_get_hotbar_image(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + const std::string &name = player->getHotbarImage(); + + lua_pushlstring(L, name.c_str(), name.size()); + return 1; +} + +// hud_set_hotbar_selected_image(self, name) +int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + std::string name = readParam<std::string>(L, 2); + + getServer(L)->hudSetHotbarSelectedImage(player, name); + return 1; +} + +// hud_get_hotbar_selected_image(self) +int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + const std::string &name = player->getHotbarSelectedImage(); + + lua_pushlstring(L, name.c_str(), name.size()); + return 1; +} + +// set_sky(self, sky_parameters) +int ObjectRef::l_set_sky(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + SkyboxParams sky_params = player->getSkyParams(); + + // reset if empty + if (lua_isnoneornil(L, 2) && lua_isnone(L, 3)) { + sky_params = SkyboxDefaults::getSkyDefaults(); + } else if (lua_istable(L, 2) && !is_color_table(L, 2)) { + lua_getfield(L, 2, "base_color"); + if (!lua_isnil(L, -1)) + read_color(L, -1, &sky_params.bgcolor); + lua_pop(L, 1); + + lua_getfield(L, 2, "type"); + if (!lua_isnil(L, -1)) + sky_params.type = luaL_checkstring(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 2, "textures"); + sky_params.textures.clear(); + if (lua_istable(L, -1) && sky_params.type == "skybox") { + lua_pushnil(L); + while (lua_next(L, -2) != 0) { + // Key is at index -2 and value at index -1 + sky_params.textures.emplace_back(readParam<std::string>(L, -1)); + // Removes the value, but keeps the key for iteration + lua_pop(L, 1); + } + } + lua_pop(L, 1); + + // Validate that we either have six or zero textures + if (sky_params.textures.size() != 6 && !sky_params.textures.empty()) + throw LuaError("Skybox expects 6 textures!"); + + sky_params.clouds = getboolfield_default(L, 2, "clouds", sky_params.clouds); + + lua_getfield(L, 2, "sky_color"); + if (lua_istable(L, -1)) { + lua_getfield(L, -1, "day_sky"); + read_color(L, -1, &sky_params.sky_color.day_sky); + lua_pop(L, 1); + + lua_getfield(L, -1, "day_horizon"); + read_color(L, -1, &sky_params.sky_color.day_horizon); + lua_pop(L, 1); + + lua_getfield(L, -1, "dawn_sky"); + read_color(L, -1, &sky_params.sky_color.dawn_sky); + lua_pop(L, 1); + + lua_getfield(L, -1, "dawn_horizon"); + read_color(L, -1, &sky_params.sky_color.dawn_horizon); + lua_pop(L, 1); + + lua_getfield(L, -1, "night_sky"); + read_color(L, -1, &sky_params.sky_color.night_sky); + lua_pop(L, 1); + + lua_getfield(L, -1, "night_horizon"); + read_color(L, -1, &sky_params.sky_color.night_horizon); + lua_pop(L, 1); + + lua_getfield(L, -1, "indoors"); + read_color(L, -1, &sky_params.sky_color.indoors); + lua_pop(L, 1); + + // Prevent flickering clouds at dawn/dusk: + sky_params.fog_sun_tint = video::SColor(255, 255, 255, 255); + lua_getfield(L, -1, "fog_sun_tint"); + read_color(L, -1, &sky_params.fog_sun_tint); + lua_pop(L, 1); + + sky_params.fog_moon_tint = video::SColor(255, 255, 255, 255); + lua_getfield(L, -1, "fog_moon_tint"); + read_color(L, -1, &sky_params.fog_moon_tint); + lua_pop(L, 1); + + lua_getfield(L, -1, "fog_tint_type"); + if (!lua_isnil(L, -1)) + sky_params.fog_tint_type = luaL_checkstring(L, -1); + lua_pop(L, 1); + + // pop "sky_color" table + lua_pop(L, 1); + } + } else { + // Handle old set_sky calls, and log deprecated: + log_deprecated(L, "Deprecated call to set_sky, please check lua_api.txt"); + + // Fix sun, moon and stars showing when classic textured skyboxes are used + SunParams sun_params = player->getSunParams(); + MoonParams moon_params = player->getMoonParams(); + StarParams star_params = player->getStarParams(); + + // Prevent erroneous background colors + sky_params.bgcolor = video::SColor(255, 255, 255, 255); + read_color(L, 2, &sky_params.bgcolor); + + sky_params.type = luaL_checkstring(L, 3); + + // Preserve old behaviour of the sun, moon and stars + // when using the old set_sky call. + if (sky_params.type == "regular") { + sun_params.visible = true; + sun_params.sunrise_visible = true; + moon_params.visible = true; + star_params.visible = true; + } else { + sun_params.visible = false; + sun_params.sunrise_visible = false; + moon_params.visible = false; + star_params.visible = false; + } + + sky_params.textures.clear(); + if (lua_istable(L, 4)) { + lua_pushnil(L); + while (lua_next(L, 4) != 0) { + // Key at index -2, and value at index -1 + sky_params.textures.emplace_back(readParam<std::string>(L, -1)); + // Remove the value, keep the key for the next iteration + lua_pop(L, 1); + } + } + if (sky_params.type == "skybox" && sky_params.textures.size() != 6) + throw LuaError("Skybox expects 6 textures."); + + sky_params.clouds = true; + if (lua_isboolean(L, 5)) + sky_params.clouds = readParam<bool>(L, 5); + + getServer(L)->setSun(player, sun_params); + getServer(L)->setMoon(player, moon_params); + getServer(L)->setStars(player, star_params); + } + + getServer(L)->setSky(player, sky_params); + return 0; +} + +static void push_sky_color(lua_State *L, const SkyboxParams ¶ms) +{ + lua_newtable(L); + if (params.type == "regular") { + push_ARGB8(L, params.sky_color.day_sky); + lua_setfield(L, -2, "day_sky"); + push_ARGB8(L, params.sky_color.day_horizon); + lua_setfield(L, -2, "day_horizon"); + push_ARGB8(L, params.sky_color.dawn_sky); + lua_setfield(L, -2, "dawn_sky"); + push_ARGB8(L, params.sky_color.dawn_horizon); + lua_setfield(L, -2, "dawn_horizon"); + push_ARGB8(L, params.sky_color.night_sky); + lua_setfield(L, -2, "night_sky"); + push_ARGB8(L, params.sky_color.night_horizon); + lua_setfield(L, -2, "night_horizon"); + push_ARGB8(L, params.sky_color.indoors); + lua_setfield(L, -2, "indoors"); + } + push_ARGB8(L, params.fog_sun_tint); + lua_setfield(L, -2, "fog_sun_tint"); + push_ARGB8(L, params.fog_moon_tint); + lua_setfield(L, -2, "fog_moon_tint"); + lua_pushstring(L, params.fog_tint_type.c_str()); + lua_setfield(L, -2, "fog_tint_type"); +} + +// get_sky(self, as_table) +int ObjectRef::l_get_sky(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + const SkyboxParams &skybox_params = player->getSkyParams(); + + // handle the deprecated version + if (!readParam<bool>(L, 2, false)) { + log_deprecated(L, "Deprecated call to get_sky, please check lua_api.txt"); + + push_ARGB8(L, skybox_params.bgcolor); + lua_pushlstring(L, skybox_params.type.c_str(), skybox_params.type.size()); + + lua_newtable(L); + s16 i = 1; + for (const std::string &texture : skybox_params.textures) { + lua_pushlstring(L, texture.c_str(), texture.size()); + lua_rawseti(L, -2, i++); + } + lua_pushboolean(L, skybox_params.clouds); + return 4; + } + + lua_newtable(L); + push_ARGB8(L, skybox_params.bgcolor); + lua_setfield(L, -2, "base_color"); + lua_pushlstring(L, skybox_params.type.c_str(), skybox_params.type.size()); + lua_setfield(L, -2, "type"); + + lua_newtable(L); + s16 i = 1; + for (const std::string &texture : skybox_params.textures) { + lua_pushlstring(L, texture.c_str(), texture.size()); + lua_rawseti(L, -2, i++); + } + lua_setfield(L, -2, "textures"); + lua_pushboolean(L, skybox_params.clouds); + lua_setfield(L, -2, "clouds"); + + push_sky_color(L, skybox_params); + lua_setfield(L, -2, "sky_color"); + return 1; +} + +// DEPRECATED +// get_sky_color(self) +int ObjectRef::l_get_sky_color(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + log_deprecated(L, "Deprecated call to get_sky_color, use get_sky instead"); + + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + const SkyboxParams &skybox_params = player->getSkyParams(); + push_sky_color(L, skybox_params); + return 1; +} + +// set_sun(self, sun_parameters) +int ObjectRef::l_set_sun(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + SunParams sun_params = player->getSunParams(); + + // reset if empty + if (lua_isnoneornil(L, 2)) { + sun_params = SkyboxDefaults::getSunDefaults(); + } else { + luaL_checktype(L, 2, LUA_TTABLE); + sun_params.visible = getboolfield_default(L, 2, "visible", sun_params.visible); + sun_params.texture = getstringfield_default(L, 2, "texture", sun_params.texture); + sun_params.tonemap = getstringfield_default(L, 2, "tonemap", sun_params.tonemap); + sun_params.sunrise = getstringfield_default(L, 2, "sunrise", sun_params.sunrise); + sun_params.sunrise_visible = getboolfield_default(L, 2, "sunrise_visible", sun_params.sunrise_visible); + sun_params.scale = getfloatfield_default(L, 2, "scale", sun_params.scale); + } + + getServer(L)->setSun(player, sun_params); + return 0; +} + +//get_sun(self) +int ObjectRef::l_get_sun(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + const SunParams &sun_params = player->getSunParams(); + + lua_newtable(L); + lua_pushboolean(L, sun_params.visible); + lua_setfield(L, -2, "visible"); + lua_pushstring(L, sun_params.texture.c_str()); + lua_setfield(L, -2, "texture"); + lua_pushstring(L, sun_params.tonemap.c_str()); + lua_setfield(L, -2, "tonemap"); + lua_pushstring(L, sun_params.sunrise.c_str()); + lua_setfield(L, -2, "sunrise"); + lua_pushboolean(L, sun_params.sunrise_visible); + lua_setfield(L, -2, "sunrise_visible"); + lua_pushnumber(L, sun_params.scale); + lua_setfield(L, -2, "scale"); + return 1; +} + +// set_moon(self, moon_parameters) +int ObjectRef::l_set_moon(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + MoonParams moon_params = player->getMoonParams(); + + // reset if empty + if (lua_isnoneornil(L, 2)) { + moon_params = SkyboxDefaults::getMoonDefaults(); + } else { + luaL_checktype(L, 2, LUA_TTABLE); + moon_params.visible = getboolfield_default(L, 2, "visible", moon_params.visible); + moon_params.texture = getstringfield_default(L, 2, "texture", moon_params.texture); + moon_params.tonemap = getstringfield_default(L, 2, "tonemap", moon_params.tonemap); + moon_params.scale = getfloatfield_default(L, 2, "scale", moon_params.scale); + } + + getServer(L)->setMoon(player, moon_params); + return 0; +} + +// get_moon(self) +int ObjectRef::l_get_moon(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + const MoonParams &moon_params = player->getMoonParams(); + + lua_newtable(L); + lua_pushboolean(L, moon_params.visible); + lua_setfield(L, -2, "visible"); + lua_pushstring(L, moon_params.texture.c_str()); + lua_setfield(L, -2, "texture"); + lua_pushstring(L, moon_params.tonemap.c_str()); + lua_setfield(L, -2, "tonemap"); + lua_pushnumber(L, moon_params.scale); + lua_setfield(L, -2, "scale"); + return 1; +} + +// set_stars(self, star_parameters) +int ObjectRef::l_set_stars(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + StarParams star_params = player->getStarParams(); + + // reset if empty + if (lua_isnoneornil(L, 2)) { + star_params = SkyboxDefaults::getStarDefaults(); + } else { + luaL_checktype(L, 2, LUA_TTABLE); + star_params.visible = getboolfield_default(L, 2, "visible", star_params.visible); + star_params.count = getintfield_default(L, 2, "count", star_params.count); + + lua_getfield(L, 2, "star_color"); + if (!lua_isnil(L, -1)) + read_color(L, -1, &star_params.starcolor); + lua_pop(L, 1); + + star_params.scale = getfloatfield_default(L, 2, + "scale", star_params.scale); + star_params.day_opacity = getfloatfield_default(L, 2, + "day_opacity", star_params.day_opacity); + } + + getServer(L)->setStars(player, star_params); + return 0; +} + +// get_stars(self) +int ObjectRef::l_get_stars(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + const StarParams &star_params = player->getStarParams(); + + lua_newtable(L); + lua_pushboolean(L, star_params.visible); + lua_setfield(L, -2, "visible"); + lua_pushnumber(L, star_params.count); + lua_setfield(L, -2, "count"); + push_ARGB8(L, star_params.starcolor); + lua_setfield(L, -2, "star_color"); + lua_pushnumber(L, star_params.scale); + lua_setfield(L, -2, "scale"); + lua_pushnumber(L, star_params.day_opacity); + lua_setfield(L, -2, "day_opacity"); + return 1; +} + +// set_clouds(self, cloud_parameters) +int ObjectRef::l_set_clouds(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + CloudParams cloud_params = player->getCloudParams(); + + // reset if empty + if (lua_isnoneornil(L, 2)) { + cloud_params = SkyboxDefaults::getCloudDefaults(); + } else { + luaL_checktype(L, 2, LUA_TTABLE); + cloud_params.density = getfloatfield_default(L, 2, "density", cloud_params.density); + + lua_getfield(L, 2, "color"); + if (!lua_isnil(L, -1)) + read_color(L, -1, &cloud_params.color_bright); + lua_pop(L, 1); + lua_getfield(L, 2, "ambient"); + if (!lua_isnil(L, -1)) + read_color(L, -1, &cloud_params.color_ambient); + lua_pop(L, 1); + + cloud_params.height = getfloatfield_default(L, 2, "height", cloud_params.height); + cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness); + + lua_getfield(L, 2, "speed"); + if (lua_istable(L, -1)) { + v2f new_speed; + new_speed.X = getfloatfield_default(L, -1, "x", 0); + new_speed.Y = getfloatfield_default(L, -1, "z", 0); + cloud_params.speed = new_speed; + } + lua_pop(L, 1); + } + + getServer(L)->setClouds(player, cloud_params); + return 0; +} + +int ObjectRef::l_get_clouds(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + const CloudParams &cloud_params = player->getCloudParams(); + + lua_newtable(L); + lua_pushnumber(L, cloud_params.density); + lua_setfield(L, -2, "density"); + push_ARGB8(L, cloud_params.color_bright); + lua_setfield(L, -2, "color"); + push_ARGB8(L, cloud_params.color_ambient); + lua_setfield(L, -2, "ambient"); + lua_pushnumber(L, cloud_params.height); + lua_setfield(L, -2, "height"); + lua_pushnumber(L, cloud_params.thickness); + lua_setfield(L, -2, "thickness"); + lua_newtable(L); + lua_pushnumber(L, cloud_params.speed.X); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, cloud_params.speed.Y); + lua_setfield(L, -2, "y"); + lua_setfield(L, -2, "speed"); + return 1; +} + + +// override_day_night_ratio(self, ratio) +int ObjectRef::l_override_day_night_ratio(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + bool do_override = false; + float ratio = 0.0f; + + if (!lua_isnil(L, 2)) { + do_override = true; + ratio = readParam<float>(L, 2); + luaL_argcheck(L, ratio >= 0.0f && ratio <= 1.0f, 1, + "value must be between 0 and 1"); + } + + getServer(L)->overrideDayNightRatio(player, do_override, ratio); + return 0; +} + +// get_day_night_ratio(self) +int ObjectRef::l_get_day_night_ratio(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + bool do_override; + float ratio; + player->getDayNightRatio(&do_override, &ratio); + + if (do_override) + lua_pushnumber(L, ratio); + else + lua_pushnil(L); + + return 1; +} + +// set_minimap_modes(self, modes, selected_mode) +int ObjectRef::l_set_minimap_modes(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + luaL_checktype(L, 2, LUA_TTABLE); + std::vector<MinimapMode> modes; + s16 selected_mode = readParam<s16>(L, 3); + + lua_pushnil(L); + while (lua_next(L, 2) != 0) { + /* key is at index -2, value is at index -1 */ + if (lua_istable(L, -1)) { + bool ok = true; + MinimapMode mode; + std::string type = getstringfield_default(L, -1, "type", ""); + if (type == "off") + mode.type = MINIMAP_TYPE_OFF; + else if (type == "surface") + mode.type = MINIMAP_TYPE_SURFACE; + else if (type == "radar") + mode.type = MINIMAP_TYPE_RADAR; + else if (type == "texture") { + mode.type = MINIMAP_TYPE_TEXTURE; + mode.texture = getstringfield_default(L, -1, "texture", ""); + mode.scale = getintfield_default(L, -1, "scale", 1); + } else { + warningstream << "Minimap mode of unknown type \"" << type.c_str() + << "\" ignored.\n" << std::endl; + ok = false; + } + + if (ok) { + mode.label = getstringfield_default(L, -1, "label", ""); + // Size is limited to 512. Performance gets poor if size too large, and + // segfaults have been experienced. + mode.size = rangelim(getintfield_default(L, -1, "size", 0), 1, 512); + modes.push_back(mode); + } + } + /* removes 'value'; keeps 'key' for next iteration */ + lua_pop(L, 1); + } + lua_pop(L, 1); // Remove key + + getServer(L)->SendMinimapModes(player->getPeerId(), modes, selected_mode); + return 0; +} + +// set_lighting(self, lighting) +int ObjectRef::l_set_lighting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + luaL_checktype(L, 2, LUA_TTABLE); + Lighting lighting = player->getLighting(); + lua_getfield(L, 2, "shadows"); + if (lua_istable(L, -1)) { + lighting.shadow_intensity = getfloatfield_default(L, -1, "intensity", lighting.shadow_intensity); + } + lua_pop(L, -1); + + getServer(L)->setLighting(player, lighting); + return 0; +} + +// get_lighting(self) +int ObjectRef::l_get_lighting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + const Lighting &lighting = player->getLighting(); + + lua_newtable(L); // result + lua_newtable(L); // "shadows" + lua_pushnumber(L, lighting.shadow_intensity); + lua_setfield(L, -2, "intensity"); + lua_setfield(L, -2, "shadows"); + return 1; +} + +// respawn(self) +int ObjectRef::l_respawn(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == nullptr) + return 0; + + getServer(L)->RespawnPlayer(player->getPeerId()); + lua_pushboolean(L, true); + return 1; +} + + +ObjectRef::ObjectRef(ServerActiveObject *object): + m_object(object) +{} + +// Creates an ObjectRef and leaves it on top of stack +// Not callable from Lua; all references are created on the C side. +void ObjectRef::create(lua_State *L, ServerActiveObject *object) +{ + ObjectRef *obj = new ObjectRef(object); + *(void **)(lua_newuserdata(L, sizeof(void *))) = obj; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +void ObjectRef::set_null(lua_State *L) +{ + ObjectRef *obj = checkobject(L, -1); + obj->m_object = nullptr; +} + +void ObjectRef::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // drop methodtable +} + +const char ObjectRef::className[] = "ObjectRef"; +luaL_Reg ObjectRef::methods[] = { + // ServerActiveObject + luamethod(ObjectRef, remove), + luamethod_aliased(ObjectRef, get_pos, getpos), + luamethod_aliased(ObjectRef, set_pos, setpos), + luamethod_aliased(ObjectRef, move_to, moveto), + luamethod(ObjectRef, punch), + luamethod(ObjectRef, right_click), + luamethod(ObjectRef, set_hp), + luamethod(ObjectRef, get_hp), + luamethod(ObjectRef, get_inventory), + luamethod(ObjectRef, get_wield_list), + luamethod(ObjectRef, get_wield_index), + luamethod(ObjectRef, get_wielded_item), + luamethod(ObjectRef, set_wielded_item), + luamethod(ObjectRef, set_armor_groups), + luamethod(ObjectRef, get_armor_groups), + luamethod(ObjectRef, set_animation), + luamethod(ObjectRef, get_animation), + luamethod(ObjectRef, set_animation_frame_speed), + luamethod(ObjectRef, set_bone_position), + luamethod(ObjectRef, get_bone_position), + luamethod(ObjectRef, set_attach), + luamethod(ObjectRef, get_attach), + luamethod(ObjectRef, get_children), + luamethod(ObjectRef, set_detach), + luamethod(ObjectRef, set_properties), + luamethod(ObjectRef, get_properties), + luamethod(ObjectRef, set_nametag_attributes), + luamethod(ObjectRef, get_nametag_attributes), + + luamethod_aliased(ObjectRef, set_velocity, setvelocity), + luamethod_aliased(ObjectRef, add_velocity, add_player_velocity), + luamethod_aliased(ObjectRef, get_velocity, getvelocity), + luamethod_dep(ObjectRef, get_velocity, get_player_velocity), + + // LuaEntitySAO-only + luamethod_aliased(ObjectRef, set_acceleration, setacceleration), + luamethod_aliased(ObjectRef, get_acceleration, getacceleration), + luamethod_aliased(ObjectRef, set_yaw, setyaw), + luamethod_aliased(ObjectRef, get_yaw, getyaw), + luamethod(ObjectRef, set_rotation), + luamethod(ObjectRef, get_rotation), + luamethod_aliased(ObjectRef, set_texture_mod, settexturemod), + luamethod(ObjectRef, get_texture_mod), + luamethod_aliased(ObjectRef, set_sprite, setsprite), + luamethod(ObjectRef, get_entity_name), + luamethod(ObjectRef, get_luaentity), + + // Player-only + luamethod(ObjectRef, is_player), + luamethod(ObjectRef, get_player_name), + luamethod(ObjectRef, get_look_dir), + luamethod(ObjectRef, get_look_pitch), + luamethod(ObjectRef, get_look_yaw), + luamethod(ObjectRef, get_look_vertical), + luamethod(ObjectRef, get_look_horizontal), + luamethod(ObjectRef, set_look_horizontal), + luamethod(ObjectRef, set_look_vertical), + luamethod(ObjectRef, set_look_yaw), + luamethod(ObjectRef, set_look_pitch), + luamethod(ObjectRef, get_fov), + luamethod(ObjectRef, set_fov), + luamethod(ObjectRef, get_breath), + luamethod(ObjectRef, set_breath), + luamethod(ObjectRef, get_attribute), + luamethod(ObjectRef, set_attribute), + luamethod(ObjectRef, get_meta), + luamethod(ObjectRef, set_inventory_formspec), + luamethod(ObjectRef, get_inventory_formspec), + luamethod(ObjectRef, set_formspec_prepend), + luamethod(ObjectRef, get_formspec_prepend), + luamethod(ObjectRef, get_player_control), + luamethod(ObjectRef, get_player_control_bits), + luamethod(ObjectRef, set_physics_override), + luamethod(ObjectRef, get_physics_override), + luamethod(ObjectRef, hud_add), + luamethod(ObjectRef, hud_remove), + luamethod(ObjectRef, hud_change), + luamethod(ObjectRef, hud_get), + luamethod(ObjectRef, hud_set_flags), + luamethod(ObjectRef, hud_get_flags), + luamethod(ObjectRef, hud_set_hotbar_itemcount), + luamethod(ObjectRef, hud_get_hotbar_itemcount), + luamethod(ObjectRef, hud_set_hotbar_image), + luamethod(ObjectRef, hud_get_hotbar_image), + luamethod(ObjectRef, hud_set_hotbar_selected_image), + luamethod(ObjectRef, hud_get_hotbar_selected_image), + luamethod(ObjectRef, set_sky), + luamethod(ObjectRef, get_sky), + luamethod(ObjectRef, get_sky_color), + luamethod(ObjectRef, set_sun), + luamethod(ObjectRef, get_sun), + luamethod(ObjectRef, set_moon), + luamethod(ObjectRef, get_moon), + luamethod(ObjectRef, set_stars), + luamethod(ObjectRef, get_stars), + luamethod(ObjectRef, set_clouds), + luamethod(ObjectRef, get_clouds), + luamethod(ObjectRef, override_day_night_ratio), + luamethod(ObjectRef, get_day_night_ratio), + luamethod(ObjectRef, set_local_animation), + luamethod(ObjectRef, get_local_animation), + luamethod(ObjectRef, set_eye_offset), + luamethod(ObjectRef, get_eye_offset), + luamethod(ObjectRef, send_mapblock), + luamethod(ObjectRef, set_minimap_modes), + luamethod(ObjectRef, set_lighting), + luamethod(ObjectRef, get_lighting), + luamethod(ObjectRef, respawn), + + {0,0} +}; diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h new file mode 100644 index 0000000..b36bab4 --- /dev/null +++ b/src/script/lua_api/l_object.h @@ -0,0 +1,388 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" +#include "irrlichttypes.h" + +class ServerActiveObject; +class LuaEntitySAO; +class PlayerSAO; +class RemotePlayer; + +/* + ObjectRef +*/ + +class ObjectRef : public ModApiBase { +public: + ObjectRef(ServerActiveObject *object); + + ~ObjectRef() = default; + + // Creates an ObjectRef and leaves it on top of stack + // Not callable from Lua; all references are created on the C side. + static void create(lua_State *L, ServerActiveObject *object); + + static void set_null(lua_State *L); + + static void Register(lua_State *L); + + static ObjectRef *checkobject(lua_State *L, int narg); + + static ServerActiveObject* getobject(ObjectRef *ref); +private: + ServerActiveObject *m_object = nullptr; + static const char className[]; + static luaL_Reg methods[]; + + + static LuaEntitySAO* getluaobject(ObjectRef *ref); + + static PlayerSAO* getplayersao(ObjectRef *ref); + + static RemotePlayer *getplayer(ObjectRef *ref); + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + // remove(self) + static int l_remove(lua_State *L); + + // get_pos(self) + static int l_get_pos(lua_State *L); + + // set_pos(self, pos) + static int l_set_pos(lua_State *L); + + // move_to(self, pos, continuous) + static int l_move_to(lua_State *L); + + // punch(self, puncher, time_from_last_punch, tool_capabilities, dir) + static int l_punch(lua_State *L); + + // right_click(self, clicker) + static int l_right_click(lua_State *L); + + // set_hp(self, hp, reason) + static int l_set_hp(lua_State *L); + + // get_hp(self) + static int l_get_hp(lua_State *L); + + // get_inventory(self) + static int l_get_inventory(lua_State *L); + + // get_wield_list(self) + static int l_get_wield_list(lua_State *L); + + // get_wield_index(self) + static int l_get_wield_index(lua_State *L); + + // get_wielded_item(self) + static int l_get_wielded_item(lua_State *L); + + // set_wielded_item(self, item) + static int l_set_wielded_item(lua_State *L); + + // set_armor_groups(self, groups) + static int l_set_armor_groups(lua_State *L); + + // get_armor_groups(self) + static int l_get_armor_groups(lua_State *L); + + // set_physics_override(self, override_table) + static int l_set_physics_override(lua_State *L); + + // get_physics_override(self) + static int l_get_physics_override(lua_State *L); + + // set_animation(self, frame_range, frame_speed, frame_blend, frame_loop) + static int l_set_animation(lua_State *L); + + // set_animation_frame_speed(self, frame_speed) + static int l_set_animation_frame_speed(lua_State *L); + + // get_animation(self) + static int l_get_animation(lua_State *L); + + // set_bone_position(self, bone, position, rotation) + static int l_set_bone_position(lua_State *L); + + // get_bone_position(self, bone) + static int l_get_bone_position(lua_State *L); + + // set_attach(self, parent, bone, position, rotation) + static int l_set_attach(lua_State *L); + + // get_attach(self) + static int l_get_attach(lua_State *L); + + // get_children(self) + static int l_get_children(lua_State *L); + + // set_detach(self) + static int l_set_detach(lua_State *L); + + // set_properties(self, properties) + static int l_set_properties(lua_State *L); + + // get_properties(self) + static int l_get_properties(lua_State *L); + + // is_player(self) + static int l_is_player(lua_State *L); + + /* LuaEntitySAO-only */ + + // set_velocity(self, velocity) + static int l_set_velocity(lua_State *L); + + // add_velocity(self, velocity) + static int l_add_velocity(lua_State *L); + + // get_velocity(self) + static int l_get_velocity(lua_State *L); + + // set_acceleration(self, acceleration) + static int l_set_acceleration(lua_State *L); + + // get_acceleration(self) + static int l_get_acceleration(lua_State *L); + + // set_rotation(self, rotation) + static int l_set_rotation(lua_State *L); + + // get_rotation(self) + static int l_get_rotation(lua_State *L); + + // set_yaw(self, yaw) + static int l_set_yaw(lua_State *L); + + // get_yaw(self) + static int l_get_yaw(lua_State *L); + + // set_texture_mod(self, mod) + static int l_set_texture_mod(lua_State *L); + + // l_get_texture_mod(self) + static int l_get_texture_mod(lua_State *L); + + // set_sprite(self, start_frame, num_frames, framelength, select_x_by_camera) + static int l_set_sprite(lua_State *L); + + // DEPRECATED + // get_entity_name(self) + static int l_get_entity_name(lua_State *L); + + // get_luaentity(self) + static int l_get_luaentity(lua_State *L); + + /* Player-only */ + + // get_player_name(self) + static int l_get_player_name(lua_State *L); + + // get_fov(self) + static int l_get_fov(lua_State *L); + + // get_look_dir(self) + static int l_get_look_dir(lua_State *L); + + // DEPRECATED + // get_look_pitch(self) + static int l_get_look_pitch(lua_State *L); + + // DEPRECATED + // get_look_yaw(self) + static int l_get_look_yaw(lua_State *L); + + // get_look_pitch2(self) + static int l_get_look_vertical(lua_State *L); + + // get_look_yaw2(self) + static int l_get_look_horizontal(lua_State *L); + + // set_fov(self, degrees, is_multiplier, transition_time) + static int l_set_fov(lua_State *L); + + // set_look_vertical(self, radians) + static int l_set_look_vertical(lua_State *L); + + // set_look_horizontal(self, radians) + static int l_set_look_horizontal(lua_State *L); + + // DEPRECATED + // set_look_pitch(self, radians) + static int l_set_look_pitch(lua_State *L); + + // DEPRECATED + // set_look_yaw(self, radians) + static int l_set_look_yaw(lua_State *L); + + // set_breath(self, breath) + static int l_set_breath(lua_State *L); + + // get_breath(self, breath) + static int l_get_breath(lua_State *L); + + // DEPRECATED + // set_attribute(self, attribute, value) + static int l_set_attribute(lua_State *L); + + // DEPRECATED + // get_attribute(self, attribute) + static int l_get_attribute(lua_State *L); + + // get_meta(self) + static int l_get_meta(lua_State *L); + + // set_inventory_formspec(self, formspec) + static int l_set_inventory_formspec(lua_State *L); + + // get_inventory_formspec(self) + static int l_get_inventory_formspec(lua_State *L); + + // set_formspec_prepend(self, formspec) + static int l_set_formspec_prepend(lua_State *L); + + // get_formspec_prepend(self) + static int l_get_formspec_prepend(lua_State *L); + + // get_player_control(self) + static int l_get_player_control(lua_State *L); + + // get_player_control_bits(self) + static int l_get_player_control_bits(lua_State *L); + + // hud_add(self, id, form) + static int l_hud_add(lua_State *L); + + // hud_rm(self, id) + static int l_hud_remove(lua_State *L); + + // hud_change(self, id, stat, data) + static int l_hud_change(lua_State *L); + + // hud_get_next_id(self) + static u32 hud_get_next_id(lua_State *L); + + // hud_get(self, id) + static int l_hud_get(lua_State *L); + + // hud_set_flags(self, flags) + static int l_hud_set_flags(lua_State *L); + + // hud_get_flags() + static int l_hud_get_flags(lua_State *L); + + // hud_set_hotbar_itemcount(self, hotbar_itemcount) + static int l_hud_set_hotbar_itemcount(lua_State *L); + + // hud_get_hotbar_itemcount(self) + static int l_hud_get_hotbar_itemcount(lua_State *L); + + // hud_set_hotbar_image(self, name) + static int l_hud_set_hotbar_image(lua_State *L); + + // hud_get_hotbar_image(self) + static int l_hud_get_hotbar_image(lua_State *L); + + // hud_set_hotbar_selected_image(self, name) + static int l_hud_set_hotbar_selected_image(lua_State *L); + + // hud_get_hotbar_selected_image(self) + static int l_hud_get_hotbar_selected_image(lua_State *L); + + // set_sky(self, sky_parameters) + static int l_set_sky(lua_State *L); + + // get_sky(self, as_table) + static int l_get_sky(lua_State *L); + + // DEPRECATED + // get_sky_color(self) + static int l_get_sky_color(lua_State* L); + + // set_sun(self, sun_parameters) + static int l_set_sun(lua_State *L); + + // get_sun(self) + static int l_get_sun(lua_State *L); + + // set_moon(self, moon_parameters) + static int l_set_moon(lua_State *L); + + // get_moon(self) + static int l_get_moon(lua_State *L); + + // set_stars(self, star_parameters) + static int l_set_stars(lua_State *L); + + // get_stars(self) + static int l_get_stars(lua_State *L); + + // set_clouds(self, cloud_parameters) + static int l_set_clouds(lua_State *L); + + // get_clouds(self) + static int l_get_clouds(lua_State *L); + + // override_day_night_ratio(self, type) + static int l_override_day_night_ratio(lua_State *L); + + // get_day_night_ratio(self) + static int l_get_day_night_ratio(lua_State *L); + + // set_local_animation(self, idle, walk, dig, walk_while_dig, frame_speed) + static int l_set_local_animation(lua_State *L); + + // get_local_animation(self) + static int l_get_local_animation(lua_State *L); + + // set_eye_offset(self, firstperson, thirdperson) + static int l_set_eye_offset(lua_State *L); + + // get_eye_offset(self) + static int l_get_eye_offset(lua_State *L); + + // set_nametag_attributes(self, attributes) + static int l_set_nametag_attributes(lua_State *L); + + // get_nametag_attributes(self) + static int l_get_nametag_attributes(lua_State *L); + + // send_mapblock(pos) + static int l_send_mapblock(lua_State *L); + + // set_minimap_modes(self, modes, wanted_mode) + static int l_set_minimap_modes(lua_State *L); + + // set_lighting(self, lighting) + static int l_set_lighting(lua_State *L); + + // get_lighting(self) + static int l_get_lighting(lua_State *L); + + // respawn(self) + static int l_respawn(lua_State *L); +}; diff --git a/src/script/lua_api/l_particleparams.h b/src/script/lua_api/l_particleparams.h new file mode 100644 index 0000000..03f11c0 --- /dev/null +++ b/src/script/lua_api/l_particleparams.h @@ -0,0 +1,282 @@ +/* +Minetest +Copyright (C) 2021 velartrill, Lexi Hale <lexi@hale.su> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "lua_api/l_particles.h" +#include "lua_api/l_object.h" +#include "lua_api/l_internal.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "server.h" +#include "particles.h" + +namespace LuaParticleParams +{ + using namespace ParticleParamTypes; + + template<typename T> + inline void readNumericLuaValue(lua_State* L, T& ret) + { + if (lua_isnil(L,-1)) + return; + + if (std::is_integral<T>()) + ret = lua_tointeger(L, -1); + else + ret = lua_tonumber(L, -1); + } + + template <typename T, size_t N> + inline void readNumericLuaValue(lua_State* L, Parameter<T,N>& ret) + { + readNumericLuaValue<T>(L, ret.val); + } + + // these are unfortunately necessary as C++ intentionally disallows function template + // specialization and there's no way to make template overloads reliably resolve correctly + inline void readLuaValue(lua_State* L, f32Parameter& ret) { readNumericLuaValue(L, ret); } + inline void readLuaValue(lua_State* L, f32& ret) { readNumericLuaValue(L, ret); } + inline void readLuaValue(lua_State* L, u16& ret) { readNumericLuaValue(L, ret); } + inline void readLuaValue(lua_State* L, u8& ret) { readNumericLuaValue(L, ret); } + + inline void readLuaValue(lua_State* L, v3fParameter& ret) + { + if (lua_isnil(L, -1)) + return; + + if (lua_isnumber(L, -1)) { // shortcut for uniform vectors + auto n = lua_tonumber(L, -1); + ret = v3fParameter(n,n,n); + } else { + ret = (v3fParameter)check_v3f(L, -1); + } + } + + inline void readLuaValue(lua_State* L, v2fParameter& ret) + { + if (lua_isnil(L, -1)) + return; + + if (lua_isnumber(L, -1)) { // shortcut for uniform vectors + auto n = lua_tonumber(L, -1); + ret = v2fParameter(n,n); + } else { + ret = (v2fParameter)check_v2f(L, -1); + } + } + + inline void readLuaValue(lua_State* L, TweenStyle& ret) + { + if (lua_isnil(L, -1)) + return; + + static const EnumString opts[] = { + {(int)TweenStyle::fwd, "fwd"}, + {(int)TweenStyle::rev, "rev"}, + {(int)TweenStyle::pulse, "pulse"}, + {(int)TweenStyle::flicker, "flicker"}, + {0, nullptr}, + }; + + luaL_checktype(L, -1, LUA_TSTRING); + int v = (int)TweenStyle::fwd; + if (!string_to_enum(opts, v, lua_tostring(L, -1))) { + throw LuaError("tween style must be one of ('fwd', 'rev', 'pulse', 'flicker')"); + } + ret = (TweenStyle)v; + } + + inline void readLuaValue(lua_State* L, AttractorKind& ret) + { + if (lua_isnil(L, -1)) + return; + + static const EnumString opts[] = { + {(int)AttractorKind::none, "none"}, + {(int)AttractorKind::point, "point"}, + {(int)AttractorKind::line, "line"}, + {(int)AttractorKind::plane, "plane"}, + {0, nullptr}, + }; + + luaL_checktype(L, -1, LUA_TSTRING); + int v = (int)AttractorKind::none; + if (!string_to_enum(opts, v, lua_tostring(L, -1))) { + throw LuaError("attractor kind must be one of ('none', 'point', 'line', 'plane')"); + } + ret = (AttractorKind)v; + } + + inline void readLuaValue(lua_State* L, BlendMode& ret) + { + if (lua_isnil(L, -1)) + return; + + static const EnumString opts[] = { + {(int)BlendMode::alpha, "alpha"}, + {(int)BlendMode::add, "add"}, + {(int)BlendMode::sub, "sub"}, + {(int)BlendMode::screen, "screen"}, + {0, nullptr}, + }; + + luaL_checktype(L, -1, LUA_TSTRING); + int v = (int)BlendMode::alpha; + if (!string_to_enum(opts, v, lua_tostring(L, -1))) { + throw LuaError("blend mode must be one of ('alpha', 'add', 'sub', 'screen')"); + } + ret = (BlendMode)v; + } + + template <typename T> void + readLuaValue(lua_State* L, RangedParameter<T>& field) + { + if (lua_isnil(L,-1)) + return; + if (!lua_istable(L,-1)) // is this is just a literal value? + goto set_uniform; + + lua_getfield(L, -1, "min"); + // handle convenience syntax for non-range values + if (lua_isnil(L,-1)) { + lua_pop(L, 1); + goto set_uniform; + } + readLuaValue(L,field.min); + lua_pop(L, 1); + + lua_getfield(L, -1, "max"); + readLuaValue(L,field.max); + lua_pop(L, 1); + + lua_getfield(L, -1, "bias"); + if (!lua_isnil(L,-1)) + readLuaValue(L,field.bias); + lua_pop(L, 1); + return; + + set_uniform: + readLuaValue(L, field.min); + readLuaValue(L, field.max); + } + + template <typename T> void + readLegacyValue(lua_State* L, const char* name, T& field) {} + + template <typename T> void + readLegacyValue(lua_State* L, const char* name, RangedParameter<T>& field) + { + int tbl = lua_gettop(L); + lua_pushliteral(L, "min"); + lua_pushstring(L, name); + lua_concat(L, 2); + lua_gettable(L, tbl); + if (!lua_isnil(L, -1)) { + readLuaValue(L, field.min); + } + lua_settop(L, tbl); + + lua_pushliteral(L, "max"); + lua_pushstring(L, name); + lua_concat(L, 2); + lua_gettable(L, tbl); + if (!lua_isnil(L, -1)) { + readLuaValue(L, field.max); + } + lua_settop(L, tbl); + } + + template <typename T> void + readTweenTable(lua_State* L, const char* name, TweenedParameter<T>& field) + { + int tbl = lua_gettop(L); + + lua_pushstring(L, name); + lua_pushliteral(L, "_tween"); + lua_concat(L, 2); + lua_gettable(L, tbl); + if(lua_istable(L, -1)) { + int tween = lua_gettop(L); + // get the starting value + lua_pushinteger(L, 1), lua_gettable(L, tween); + readLuaValue(L, field.start); + lua_pop(L, 1); + + // get the final value -- use len instead of 2 so that this + // gracefully degrades if keyframe support is later added + lua_pushinteger(L, (lua_Integer)lua_objlen(L, -1)), lua_gettable(L, tween); + readLuaValue(L, field.end); + lua_pop(L, 1); + + // get the effect settings + lua_getfield(L, -1, "style"); + if (!lua_isnil(L,-1)) + readLuaValue(L, field.style); + lua_pop(L, 1); + + lua_getfield(L, -1, "reps"); + if (!lua_isnil(L,-1)) + readLuaValue(L, field.reps); + lua_pop(L, 1); + + lua_getfield(L, -1, "start"); + if (!lua_isnil(L,-1)) + readLuaValue(L, field.beginning); + lua_pop(L, 1); + + goto done; + } else { + lua_pop(L,1); + } + // the table is not present; check for nonanimated values + + lua_getfield(L, tbl, name); + if(!lua_isnil(L, -1)) { + readLuaValue(L, field.start); + lua_settop(L, tbl); + goto set_uniform; + } else { + lua_pop(L,1); + } + + // the goto did not trigger, so this table is not present either + // check for pre-5.6.0 legacy values + readLegacyValue(L, name, field.start); + + set_uniform: + field.end = field.start; + done: + lua_settop(L, tbl); // clean up after ourselves + } + + inline u16 readAttachmentID(lua_State* L, const char* name) + { + u16 id = 0; + lua_getfield(L, -1, name); + if (!lua_isnil(L, -1)) { + ObjectRef *ref = ObjectRef::checkobject(L, -1); + if (auto obj = ObjectRef::getobject(ref)) + id = obj->getId(); + } + lua_pop(L, 1); + return id; + } + + void readTexValue(lua_State* L, ServerParticleTexture& tex); +} diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp new file mode 100644 index 0000000..586c7dc --- /dev/null +++ b/src/script/lua_api/l_particles.cpp @@ -0,0 +1,327 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_particles.h" +#include "lua_api/l_object.h" +#include "lua_api/l_internal.h" +#include "lua_api/l_particleparams.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "server.h" +#include "particles.h" + +void LuaParticleParams::readTexValue(lua_State* L, ServerParticleTexture& tex) +{ + StackUnroller unroll(L); + + tex.animated = false; + if (lua_isstring(L, -1)) { + tex.string = lua_tostring(L, -1); + return; + } + + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, "name"); + tex.string = luaL_checkstring(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "animation"); + if (! lua_isnil(L, -1)) { + tex.animated = true; + tex.animation = read_animation_definition(L, -1); + } + lua_pop(L, 1); + + lua_getfield(L, -1, "blend"); + LuaParticleParams::readLuaValue(L, tex.blendmode); + lua_pop(L, 1); + + LuaParticleParams::readTweenTable(L, "alpha", tex.alpha); + LuaParticleParams::readTweenTable(L, "scale", tex.scale); + +} + +// add_particle({...}) +int ModApiParticles::l_add_particle(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + // Get parameters + ParticleParameters p; + std::string playername; + + if (lua_gettop(L) > 1) // deprecated + { + log_deprecated(L, "Deprecated add_particle call with " + "individual parameters instead of definition"); + p.pos = check_v3f(L, 1); + p.vel = check_v3f(L, 2); + p.acc = check_v3f(L, 3); + p.expirationtime = luaL_checknumber(L, 4); + p.size = luaL_checknumber(L, 5); + p.collisiondetection = readParam<bool>(L, 6); + p.texture.string = luaL_checkstring(L, 7); + if (lua_gettop(L) == 8) // only spawn for a single player + playername = luaL_checkstring(L, 8); + } + else if (lua_istable(L, 1)) + { + lua_getfield(L, 1, "pos"); + if (lua_istable(L, -1)) + p.pos = check_v3f(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "vel"); + if (lua_istable(L, -1)) { + p.vel = check_v3f(L, -1); + log_deprecated(L, "The use of vel is deprecated. " + "Use velocity instead"); + } + lua_pop(L, 1); + + lua_getfield(L, 1, "velocity"); + if (lua_istable(L, -1)) + p.vel = check_v3f(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "acc"); + if (lua_istable(L, -1)) { + p.acc = check_v3f(L, -1); + log_deprecated(L, "The use of acc is deprecated. " + "Use acceleration instead"); + } + lua_pop(L, 1); + + lua_getfield(L, 1, "acceleration"); + if (lua_istable(L, -1)) + p.acc = check_v3f(L, -1); + lua_pop(L, 1); + + p.expirationtime = getfloatfield_default(L, 1, "expirationtime", + p.expirationtime); + p.size = getfloatfield_default(L, 1, "size", p.size); + p.collisiondetection = getboolfield_default(L, 1, + "collisiondetection", p.collisiondetection); + p.collision_removal = getboolfield_default(L, 1, + "collision_removal", p.collision_removal); + p.object_collision = getboolfield_default(L, 1, + "object_collision", p.object_collision); + p.vertical = getboolfield_default(L, 1, "vertical", p.vertical); + + lua_getfield(L, 1, "animation"); + p.animation = read_animation_definition(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "texture"); + if (!lua_isnil(L, -1)) { + LuaParticleParams::readTexValue(L, p.texture); + } + lua_pop(L, 1); + + p.glow = getintfield_default(L, 1, "glow", p.glow); + + lua_getfield(L, 1, "node"); + if (lua_istable(L, -1)) + p.node = readnode(L, -1, getGameDef(L)->ndef()); + lua_pop(L, 1); + + p.node_tile = getintfield_default(L, 1, "node_tile", p.node_tile); + + playername = getstringfield_default(L, 1, "playername", ""); + + lua_getfield(L, 1, "drag"); + if (lua_istable(L, -1)) + p.drag = check_v3f(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "jitter"); + LuaParticleParams::readLuaValue(L, p.jitter); + lua_pop(L, 1); + + lua_getfield(L, 1, "bounce"); + LuaParticleParams::readLuaValue(L, p.bounce); + lua_pop(L, 1); + } + + getServer(L)->spawnParticle(playername, p); + return 1; +} + +// add_particlespawner({...}) +int ModApiParticles::l_add_particlespawner(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + // Get parameters + ParticleSpawnerParameters p; + ServerActiveObject *attached = NULL; + std::string playername; + + using namespace ParticleParamTypes; + if (lua_gettop(L) > 1) //deprecated + { + log_deprecated(L, "Deprecated add_particlespawner call with " + "individual parameters instead of definition"); + p.amount = luaL_checknumber(L, 1); + p.time = luaL_checknumber(L, 2); + auto minpos = check_v3f(L, 3); + auto maxpos = check_v3f(L, 4); + auto minvel = check_v3f(L, 5); + auto maxvel = check_v3f(L, 6); + auto minacc = check_v3f(L, 7); + auto maxacc = check_v3f(L, 8); + auto minexptime = luaL_checknumber(L, 9); + auto maxexptime = luaL_checknumber(L, 10); + auto minsize = luaL_checknumber(L, 11); + auto maxsize = luaL_checknumber(L, 12); + p.pos = v3fRange(minpos, maxpos); + p.vel = v3fRange(minvel, maxvel); + p.acc = v3fRange(minacc, maxacc); + p.exptime = f32Range(minexptime, maxexptime); + p.size = f32Range(minsize, maxsize); + + p.collisiondetection = readParam<bool>(L, 13); + p.texture.string = luaL_checkstring(L, 14); + if (lua_gettop(L) == 15) // only spawn for a single player + playername = luaL_checkstring(L, 15); + } + else if (lua_istable(L, 1)) + { + p.amount = getintfield_default(L, 1, "amount", p.amount); + p.time = getfloatfield_default(L, 1, "time", p.time); + + // set default values + p.exptime = 1; + p.size = 1; + + // read spawner parameters from the table + LuaParticleParams::readTweenTable(L, "pos", p.pos); + LuaParticleParams::readTweenTable(L, "vel", p.vel); + LuaParticleParams::readTweenTable(L, "acc", p.acc); + LuaParticleParams::readTweenTable(L, "size", p.size); + LuaParticleParams::readTweenTable(L, "exptime", p.exptime); + LuaParticleParams::readTweenTable(L, "drag", p.drag); + LuaParticleParams::readTweenTable(L, "jitter", p.jitter); + LuaParticleParams::readTweenTable(L, "bounce", p.bounce); + lua_getfield(L, 1, "attract"); + if (!lua_isnil(L, -1)) { + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, "kind"); + LuaParticleParams::readLuaValue(L, p.attractor_kind); + lua_pop(L,1); + + lua_getfield(L, -1, "die_on_contact"); + if (!lua_isnil(L, -1)) + p.attractor_kill = readParam<bool>(L, -1); + lua_pop(L,1); + + if (p.attractor_kind != AttractorKind::none) { + LuaParticleParams::readTweenTable(L, "strength", p.attract); + LuaParticleParams::readTweenTable(L, "origin", p.attractor_origin); + p.attractor_attachment = LuaParticleParams::readAttachmentID(L, "origin_attached"); + if (p.attractor_kind != AttractorKind::point) { + LuaParticleParams::readTweenTable(L, "direction", p.attractor_direction); + p.attractor_direction_attachment = LuaParticleParams::readAttachmentID(L, "direction_attached"); + } + } + } else { + p.attractor_kind = AttractorKind::none; + } + lua_pop(L,1); + LuaParticleParams::readTweenTable(L, "radius", p.radius); + + p.collisiondetection = getboolfield_default(L, 1, + "collisiondetection", p.collisiondetection); + p.collision_removal = getboolfield_default(L, 1, + "collision_removal", p.collision_removal); + p.object_collision = getboolfield_default(L, 1, + "object_collision", p.object_collision); + + lua_getfield(L, 1, "animation"); + p.animation = read_animation_definition(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "attached"); + if (!lua_isnil(L, -1)) { + ObjectRef *ref = ObjectRef::checkobject(L, -1); + lua_pop(L, 1); + attached = ObjectRef::getobject(ref); + } + + lua_getfield(L, 1, "texture"); + if (!lua_isnil(L, -1)) { + LuaParticleParams::readTexValue(L, p.texture); + } + lua_pop(L, 1); + + p.vertical = getboolfield_default(L, 1, "vertical", p.vertical); + playername = getstringfield_default(L, 1, "playername", ""); + p.glow = getintfield_default(L, 1, "glow", p.glow); + + lua_getfield(L, 1, "texpool"); + if (lua_istable(L, -1)) { + size_t tl = lua_objlen(L, -1); + p.texpool.reserve(tl); + for (size_t i = 0; i < tl; ++i) { + lua_pushinteger(L, i+1), lua_gettable(L, -2); + p.texpool.emplace_back(); + LuaParticleParams::readTexValue(L, p.texpool.back()); + lua_pop(L,1); + } + } + lua_pop(L, 1); + + lua_getfield(L, 1, "node"); + if (lua_istable(L, -1)) + p.node = readnode(L, -1, getGameDef(L)->ndef()); + lua_pop(L, 1); + + p.node_tile = getintfield_default(L, 1, "node_tile", p.node_tile); + } + + u32 id = getServer(L)->addParticleSpawner(p, attached, playername); + lua_pushnumber(L, id); + + return 1; +} + +// delete_particlespawner(id, player) +// player (string) is optional +int ModApiParticles::l_delete_particlespawner(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + // Get parameters + u32 id = luaL_checknumber(L, 1); + std::string playername; + if (lua_gettop(L) == 2) { + playername = luaL_checkstring(L, 2); + } + + getServer(L)->deleteParticleSpawner(playername, id); + return 1; +} + +void ModApiParticles::Initialize(lua_State *L, int top) +{ + API_FCT(add_particle); + API_FCT(add_particlespawner); + API_FCT(delete_particlespawner); +} + diff --git a/src/script/lua_api/l_particles.h b/src/script/lua_api/l_particles.h new file mode 100644 index 0000000..122810b --- /dev/null +++ b/src/script/lua_api/l_particles.h @@ -0,0 +1,32 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" + +class ModApiParticles : public ModApiBase { +private: + static int l_add_particle(lua_State *L); + static int l_add_particlespawner(lua_State *L); + static int l_delete_particlespawner(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_particles_local.cpp b/src/script/lua_api/l_particles_local.cpp new file mode 100644 index 0000000..62cbab8 --- /dev/null +++ b/src/script/lua_api/l_particles_local.cpp @@ -0,0 +1,225 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 red-001 <red-001@outlook.ie> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_particles_local.h" +#include "common/c_content.h" +#include "common/c_converter.h" +#include "lua_api/l_internal.h" +#include "lua_api/l_object.h" +#include "lua_api/l_particleparams.h" +#include "client/particles.h" +#include "client/client.h" +#include "client/clientevent.h" + +int ModApiParticlesLocal::l_add_particle(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + + // Get parameters + ParticleParameters p; + + lua_getfield(L, 1, "pos"); + if (lua_istable(L, -1)) + p.pos = check_v3f(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "velocity"); + if (lua_istable(L, -1)) + p.vel = check_v3f(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "acceleration"); + if (lua_istable(L, -1)) + p.acc = check_v3f(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "drag"); + if (lua_istable(L, -1)) + p.drag = check_v3f(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "jitter"); + LuaParticleParams::readLuaValue(L, p.jitter); + lua_pop(L, 1); + + lua_getfield(L, 1, "bounce"); + LuaParticleParams::readLuaValue(L, p.bounce); + lua_pop(L, 1); + + p.expirationtime = getfloatfield_default(L, 1, "expirationtime", + p.expirationtime); + p.size = getfloatfield_default(L, 1, "size", p.size); + p.collisiondetection = getboolfield_default(L, 1, + "collisiondetection", p.collisiondetection); + p.collision_removal = getboolfield_default(L, 1, + "collision_removal", p.collision_removal); + p.object_collision = getboolfield_default(L, 1, + "object_collision", p.object_collision); + p.vertical = getboolfield_default(L, 1, "vertical", p.vertical); + + lua_getfield(L, 1, "animation"); + p.animation = read_animation_definition(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "texture"); + if (!lua_isnil(L, -1)) { + LuaParticleParams::readTexValue(L,p.texture); + } + lua_pop(L, 1); + p.glow = getintfield_default(L, 1, "glow", p.glow); + + lua_getfield(L, 1, "node"); + if (lua_istable(L, -1)) + p.node = readnode(L, -1, getGameDef(L)->ndef()); + lua_pop(L, 1); + + p.node_tile = getintfield_default(L, 1, "node_tile", p.node_tile); + + ClientEvent *event = new ClientEvent(); + event->type = CE_SPAWN_PARTICLE; + event->spawn_particle = new ParticleParameters(p); + getClient(L)->pushToEventQueue(event); + + return 0; +} + +int ModApiParticlesLocal::l_add_particlespawner(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + + // Get parameters + ParticleSpawnerParameters p; + p.amount = getintfield_default(L, 1, "amount", p.amount); + p.time = getfloatfield_default(L, 1, "time", p.time); + + // set default values + p.exptime = 1; + p.size = 1; + + // read spawner parameters from the table + using namespace ParticleParamTypes; + LuaParticleParams::readTweenTable(L, "pos", p.pos); + LuaParticleParams::readTweenTable(L, "vel", p.vel); + LuaParticleParams::readTweenTable(L, "acc", p.acc); + LuaParticleParams::readTweenTable(L, "size", p.size); + LuaParticleParams::readTweenTable(L, "exptime", p.exptime); + LuaParticleParams::readTweenTable(L, "drag", p.drag); + LuaParticleParams::readTweenTable(L, "jitter", p.jitter); + LuaParticleParams::readTweenTable(L, "bounce", p.bounce); + lua_getfield(L, 1, "attract"); + if (!lua_isnil(L, -1)) { + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, "kind"); + LuaParticleParams::readLuaValue(L, p.attractor_kind); + lua_pop(L,1); + + lua_getfield(L, -1, "die_on_contact"); + if (!lua_isnil(L, -1)) + p.attractor_kill = readParam<bool>(L, -1); + lua_pop(L,1); + + if (p.attractor_kind != AttractorKind::none) { + LuaParticleParams::readTweenTable(L, "strength", p.attract); + LuaParticleParams::readTweenTable(L, "origin", p.attractor_origin); + p.attractor_attachment = LuaParticleParams::readAttachmentID(L, "origin_attached"); + if (p.attractor_kind != AttractorKind::point) { + LuaParticleParams::readTweenTable(L, "direction", p.attractor_direction); + p.attractor_direction_attachment = LuaParticleParams::readAttachmentID(L, "direction_attached"); + } + } + } else { + p.attractor_kind = AttractorKind::none; + } + lua_pop(L,1); + LuaParticleParams::readTweenTable(L, "radius", p.radius); + + p.collisiondetection = getboolfield_default(L, 1, + "collisiondetection", p.collisiondetection); + p.collision_removal = getboolfield_default(L, 1, + "collision_removal", p.collision_removal); + p.object_collision = getboolfield_default(L, 1, + "object_collision", p.object_collision); + + lua_getfield(L, 1, "animation"); + p.animation = read_animation_definition(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "texture"); + if (!lua_isnil(L, -1)) { + LuaParticleParams::readTexValue(L, p.texture); + } + lua_pop(L, 1); + + p.vertical = getboolfield_default(L, 1, "vertical", p.vertical); + p.glow = getintfield_default(L, 1, "glow", p.glow); + + lua_getfield(L, 1, "texpool"); + if (lua_istable(L, -1)) { + size_t tl = lua_objlen(L, -1); + p.texpool.reserve(tl); + for (size_t i = 0; i < tl; ++i) { + lua_pushinteger(L, i+1), lua_gettable(L, -2); + p.texpool.emplace_back(); + LuaParticleParams::readTexValue(L, p.texpool.back()); + lua_pop(L,1); + } + } + lua_pop(L, 1); + + lua_getfield(L, 1, "node"); + if (lua_istable(L, -1)) + p.node = readnode(L, -1, getGameDef(L)->ndef()); + lua_pop(L, 1); + + p.node_tile = getintfield_default(L, 1, "node_tile", p.node_tile); + + u64 id = getClient(L)->getParticleManager()->generateSpawnerId(); + + auto event = new ClientEvent(); + event->type = CE_ADD_PARTICLESPAWNER; + event->add_particlespawner.p = new ParticleSpawnerParameters(p); + event->add_particlespawner.attached_id = 0; + event->add_particlespawner.id = id; + + getClient(L)->pushToEventQueue(event); + lua_pushnumber(L, id); + + return 1; +} + +int ModApiParticlesLocal::l_delete_particlespawner(lua_State *L) +{ + // Get parameters + u32 id = luaL_checknumber(L, 1); + + ClientEvent *event = new ClientEvent(); + event->type = CE_DELETE_PARTICLESPAWNER; + event->delete_particlespawner.id = id; + + getClient(L)->pushToEventQueue(event); + return 0; +} + +void ModApiParticlesLocal::Initialize(lua_State *L, int top) +{ + API_FCT(add_particle); + API_FCT(add_particlespawner); + API_FCT(delete_particlespawner); +} diff --git a/src/script/lua_api/l_particles_local.h b/src/script/lua_api/l_particles_local.h new file mode 100644 index 0000000..d8bb2b1 --- /dev/null +++ b/src/script/lua_api/l_particles_local.h @@ -0,0 +1,34 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 red-001 <red-001@outlook.ie> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" + +class ModApiParticlesLocal : public ModApiBase +{ +private: + static int l_add_particle(lua_State *L); + static int l_add_particlespawner(lua_State *L); + static int l_delete_particlespawner(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_playermeta.cpp b/src/script/lua_api/l_playermeta.cpp new file mode 100644 index 0000000..2706c99 --- /dev/null +++ b/src/script/lua_api/l_playermeta.cpp @@ -0,0 +1,123 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_playermeta.h" +#include "lua_api/l_internal.h" +#include "common/c_content.h" + +/* + PlayerMetaRef +*/ +PlayerMetaRef *PlayerMetaRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + + return *(PlayerMetaRef **)ud; // unbox pointer +} + +Metadata *PlayerMetaRef::getmeta(bool auto_create) +{ + return metadata; +} + +void PlayerMetaRef::clearMeta() +{ + metadata->clear(); +} + +void PlayerMetaRef::reportMetadataChange(const std::string *name) +{ + // TODO +} + +// garbage collector +int PlayerMetaRef::gc_object(lua_State *L) +{ + PlayerMetaRef *o = *(PlayerMetaRef **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +// Creates an PlayerMetaRef and leaves it on top of stack +// Not callable from Lua; all references are created on the C side. +void PlayerMetaRef::create(lua_State *L, Metadata *metadata) +{ + PlayerMetaRef *o = new PlayerMetaRef(metadata); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +void PlayerMetaRef::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "metadata_class"); + lua_pushlstring(L, className, strlen(className)); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pushliteral(L, "__eq"); + lua_pushcfunction(L, l_equals); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable + + luaL_register(L, nullptr, methods); + lua_pop(L, 1); + + // Cannot be created from Lua + // lua_register(L, className, create_object); +} + +// clang-format off +const char PlayerMetaRef::className[] = "PlayerMetaRef"; +const luaL_Reg PlayerMetaRef::methods[] = { + luamethod(MetaDataRef, contains), + luamethod(MetaDataRef, get), + luamethod(MetaDataRef, get_string), + luamethod(MetaDataRef, set_string), + luamethod(MetaDataRef, get_int), + luamethod(MetaDataRef, set_int), + luamethod(MetaDataRef, get_float), + luamethod(MetaDataRef, set_float), + luamethod(MetaDataRef, to_table), + luamethod(MetaDataRef, from_table), + luamethod(MetaDataRef, equals), + {0,0} +}; +// clang-format on diff --git a/src/script/lua_api/l_playermeta.h b/src/script/lua_api/l_playermeta.h new file mode 100644 index 0000000..9e23c07 --- /dev/null +++ b/src/script/lua_api/l_playermeta.h @@ -0,0 +1,57 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" +#include "lua_api/l_metadata.h" +#include "irrlichttypes_bloated.h" +#include "inventory.h" +#include "metadata.h" + +class PlayerMetaRef : public MetaDataRef +{ +private: + Metadata *metadata = nullptr; + + static const char className[]; + static const luaL_Reg methods[]; + + static PlayerMetaRef *checkobject(lua_State *L, int narg); + + virtual Metadata *getmeta(bool auto_create); + + virtual void clearMeta(); + + virtual void reportMetadataChange(const std::string *name = nullptr); + + // garbage collector + static int gc_object(lua_State *L); + +public: + PlayerMetaRef(Metadata *metadata) : metadata(metadata) {} + ~PlayerMetaRef() = default; + + // Creates an ItemStackMetaRef and leaves it on top of stack + // Not callable from Lua; all references are created on the C side. + static void create(lua_State *L, Metadata *metadata); + + static void Register(lua_State *L); +}; diff --git a/src/script/lua_api/l_rollback.cpp b/src/script/lua_api/l_rollback.cpp new file mode 100644 index 0000000..482b0cb --- /dev/null +++ b/src/script/lua_api/l_rollback.cpp @@ -0,0 +1,117 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_rollback.h" +#include "lua_api/l_internal.h" +#include "common/c_converter.h" +#include "server.h" +#include "rollback_interface.h" + + +void push_RollbackNode(lua_State *L, RollbackNode &node) +{ + lua_createtable(L, 0, 3); + lua_pushstring(L, node.name.c_str()); + lua_setfield(L, -2, "name"); + lua_pushnumber(L, node.param1); + lua_setfield(L, -2, "param1"); + lua_pushnumber(L, node.param2); + lua_setfield(L, -2, "param2"); +} + +// rollback_get_node_actions(pos, range, seconds, limit) -> {{actor, pos, time, oldnode, newnode}, ...} +int ModApiRollback::l_rollback_get_node_actions(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + v3s16 pos = read_v3s16(L, 1); + int range = luaL_checknumber(L, 2); + time_t seconds = (time_t) luaL_checknumber(L, 3); + int limit = luaL_checknumber(L, 4); + Server *server = getServer(L); + IRollbackManager *rollback = server->getRollbackManager(); + if (rollback == NULL) { + return 0; + } + + std::list<RollbackAction> actions = rollback->getNodeActors(pos, range, seconds, limit); + std::list<RollbackAction>::iterator iter = actions.begin(); + + lua_createtable(L, actions.size(), 0); + for (unsigned int i = 1; iter != actions.end(); ++iter, ++i) { + lua_createtable(L, 0, 5); // Make a table with enough space pre-allocated + + lua_pushstring(L, iter->actor.c_str()); + lua_setfield(L, -2, "actor"); + + push_v3s16(L, iter->p); + lua_setfield(L, -2, "pos"); + + lua_pushnumber(L, iter->unix_time); + lua_setfield(L, -2, "time"); + + push_RollbackNode(L, iter->n_old); + lua_setfield(L, -2, "oldnode"); + + push_RollbackNode(L, iter->n_new); + lua_setfield(L, -2, "newnode"); + + lua_rawseti(L, -2, i); // Add action table to main table + } + + return 1; +} + +// rollback_revert_actions_by(actor, seconds) -> bool, log messages +int ModApiRollback::l_rollback_revert_actions_by(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + std::string actor = luaL_checkstring(L, 1); + int seconds = luaL_checknumber(L, 2); + Server *server = getServer(L); + IRollbackManager *rollback = server->getRollbackManager(); + + // If rollback is disabled, tell it's not a success. + if (rollback == NULL) { + lua_pushboolean(L, false); + lua_newtable(L); + return 2; + } + std::list<RollbackAction> actions = rollback->getRevertActions(actor, seconds); + std::list<std::string> log; + bool success = server->rollbackRevertActions(actions, &log); + // Push boolean result + lua_pushboolean(L, success); + lua_createtable(L, log.size(), 0); + unsigned long i = 0; + for(std::list<std::string>::const_iterator iter = log.begin(); + iter != log.end(); ++i, ++iter) { + lua_pushnumber(L, i); + lua_pushstring(L, iter->c_str()); + lua_settable(L, -3); + } + return 2; +} + +void ModApiRollback::Initialize(lua_State *L, int top) +{ + API_FCT(rollback_get_node_actions); + API_FCT(rollback_revert_actions_by); +} diff --git a/src/script/lua_api/l_rollback.h b/src/script/lua_api/l_rollback.h new file mode 100644 index 0000000..c26ff63 --- /dev/null +++ b/src/script/lua_api/l_rollback.h @@ -0,0 +1,35 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" + +class ModApiRollback : public ModApiBase +{ +private: + // rollback_get_node_actions(pos, range, seconds) -> {{actor, pos, time, oldnode, newnode}, ...} + static int l_rollback_get_node_actions(lua_State *L); + + // rollback_revert_actions_by(actor, seconds) -> bool, log messages + static int l_rollback_revert_actions_by(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp new file mode 100644 index 0000000..a5daae3 --- /dev/null +++ b/src/script/lua_api/l_server.cpp @@ -0,0 +1,646 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_server.h" +#include "lua_api/l_internal.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "common/c_packer.h" +#include "cpp_api/s_base.h" +#include "cpp_api/s_security.h" +#include "scripting_server.h" +#include "server.h" +#include "environment.h" +#include "remoteplayer.h" +#include "log.h" +#include <algorithm> + +// request_shutdown() +int ModApiServer::l_request_shutdown(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *msg = lua_tolstring(L, 1, NULL); + bool reconnect = readParam<bool>(L, 2); + float seconds_before_shutdown = lua_tonumber(L, 3); + getServer(L)->requestShutdown(msg ? msg : "", reconnect, seconds_before_shutdown); + return 0; +} + +// get_server_status() +int ModApiServer::l_get_server_status(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + lua_pushstring(L, getServer(L)->getStatusString().c_str()); + return 1; +} + +// get_server_uptime() +int ModApiServer::l_get_server_uptime(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + lua_pushnumber(L, getServer(L)->getUptime()); + return 1; +} + +// get_server_max_lag() +int ModApiServer::l_get_server_max_lag(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + GET_ENV_PTR; + lua_pushnumber(L, env->getMaxLagEstimate()); + return 1; +} + +// print(text) +int ModApiServer::l_print(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string text; + text = luaL_checkstring(L, 1); + getServer(L)->printToConsoleOnly(text); + return 0; +} + +// chat_send_all(text) +int ModApiServer::l_chat_send_all(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *text = luaL_checkstring(L, 1); + // Get server from registry + Server *server = getServer(L); + // Send + server->notifyPlayers(utf8_to_wide(text)); + return 0; +} + +// chat_send_player(name, text) +int ModApiServer::l_chat_send_player(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *name = luaL_checkstring(L, 1); + const char *text = luaL_checkstring(L, 2); + + // Get server from registry + Server *server = getServer(L); + // Send + server->notifyPlayer(name, utf8_to_wide(text)); + return 0; +} + +// get_player_privs(name, text) +int ModApiServer::l_get_player_privs(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *name = luaL_checkstring(L, 1); + // Get server from registry + Server *server = getServer(L); + // Do it + lua_newtable(L); + int table = lua_gettop(L); + std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name); + for (const std::string &privs_ : privs_s) { + lua_pushboolean(L, true); + lua_setfield(L, table, privs_.c_str()); + } + lua_pushvalue(L, table); + return 1; +} + +// get_player_ip() +int ModApiServer::l_get_player_ip(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + Server *server = getServer(L); + + const char *name = luaL_checkstring(L, 1); + RemotePlayer *player = server->getEnv().getPlayer(name); + if (!player) { + lua_pushnil(L); // no such player + return 1; + } + + lua_pushstring(L, server->getPeerAddress(player->getPeerId()).serializeString().c_str()); + return 1; +} + +// get_player_information(name) +int ModApiServer::l_get_player_information(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + Server *server = getServer(L); + + const char *name = luaL_checkstring(L, 1); + RemotePlayer *player = server->getEnv().getPlayer(name); + if (!player) { + lua_pushnil(L); // no such player + return 1; + } + + /* + Be careful not to introduce a depdendency on the connection to + the peer here. This function is >>REQUIRED<< to still be able to return + values even when the peer unexpectedly disappears. + Hence all the ConInfo values here are optional. + */ + + auto getConInfo = [&] (con::rtt_stat_type type, float *value) -> bool { + return server->getClientConInfo(player->getPeerId(), type, value); + }; + + float min_rtt, max_rtt, avg_rtt, min_jitter, max_jitter, avg_jitter; + bool have_con_info = + getConInfo(con::MIN_RTT, &min_rtt) && + getConInfo(con::MAX_RTT, &max_rtt) && + getConInfo(con::AVG_RTT, &avg_rtt) && + getConInfo(con::MIN_JITTER, &min_jitter) && + getConInfo(con::MAX_JITTER, &max_jitter) && + getConInfo(con::AVG_JITTER, &avg_jitter); + + ClientInfo info; + if (!server->getClientInfo(player->getPeerId(), info)) { + warningstream << FUNCTION_NAME << ": no client info?!" << std::endl; + lua_pushnil(L); // error + return 1; + } + + lua_newtable(L); + int table = lua_gettop(L); + + lua_pushstring(L,"address"); + lua_pushstring(L, info.addr.serializeString().c_str()); + lua_settable(L, table); + + lua_pushstring(L,"ip_version"); + if (info.addr.getFamily() == AF_INET) { + lua_pushnumber(L, 4); + } else if (info.addr.getFamily() == AF_INET6) { + lua_pushnumber(L, 6); + } else { + lua_pushnumber(L, 0); + } + lua_settable(L, table); + + if (have_con_info) { // may be missing + lua_pushstring(L, "min_rtt"); + lua_pushnumber(L, min_rtt); + lua_settable(L, table); + + lua_pushstring(L, "max_rtt"); + lua_pushnumber(L, max_rtt); + lua_settable(L, table); + + lua_pushstring(L, "avg_rtt"); + lua_pushnumber(L, avg_rtt); + lua_settable(L, table); + + lua_pushstring(L, "min_jitter"); + lua_pushnumber(L, min_jitter); + lua_settable(L, table); + + lua_pushstring(L, "max_jitter"); + lua_pushnumber(L, max_jitter); + lua_settable(L, table); + + lua_pushstring(L, "avg_jitter"); + lua_pushnumber(L, avg_jitter); + lua_settable(L, table); + } + + lua_pushstring(L,"connection_uptime"); + lua_pushnumber(L, info.uptime); + lua_settable(L, table); + + lua_pushstring(L,"protocol_version"); + lua_pushnumber(L, info.prot_vers); + lua_settable(L, table); + + lua_pushstring(L, "formspec_version"); + lua_pushnumber(L, player->formspec_version); + lua_settable(L, table); + + lua_pushstring(L, "lang_code"); + lua_pushstring(L, info.lang_code.c_str()); + lua_settable(L, table); + +#ifndef NDEBUG + lua_pushstring(L,"serialization_version"); + lua_pushnumber(L, info.ser_vers); + lua_settable(L, table); + + lua_pushstring(L,"major"); + lua_pushnumber(L, info.major); + lua_settable(L, table); + + lua_pushstring(L,"minor"); + lua_pushnumber(L, info.minor); + lua_settable(L, table); + + lua_pushstring(L,"patch"); + lua_pushnumber(L, info.patch); + lua_settable(L, table); + + lua_pushstring(L,"version_string"); + lua_pushstring(L, info.vers_string.c_str()); + lua_settable(L, table); + + lua_pushstring(L,"state"); + lua_pushstring(L, ClientInterface::state2Name(info.state).c_str()); + lua_settable(L, table); +#endif + + return 1; +} + +// get_ban_list() +int ModApiServer::l_get_ban_list(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + lua_pushstring(L, getServer(L)->getBanDescription("").c_str()); + return 1; +} + +// get_ban_description() +int ModApiServer::l_get_ban_description(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char * ip_or_name = luaL_checkstring(L, 1); + lua_pushstring(L, getServer(L)->getBanDescription(std::string(ip_or_name)).c_str()); + return 1; +} + +// ban_player() +int ModApiServer::l_ban_player(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + if (!getEnv(L)) + throw LuaError("Can't ban player before server has started up"); + + Server *server = getServer(L); + const char *name = luaL_checkstring(L, 1); + RemotePlayer *player = server->getEnv().getPlayer(name); + if (!player) { + lua_pushboolean(L, false); // no such player + return 1; + } + + std::string ip_str = server->getPeerAddress(player->getPeerId()).serializeString(); + server->setIpBanned(ip_str, name); + lua_pushboolean(L, true); + return 1; +} + +// disconnect_player(name, [reason]) -> success +int ModApiServer::l_disconnect_player(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + if (!getEnv(L)) + throw LuaError("Can't kick player before server has started up"); + + const char *name = luaL_checkstring(L, 1); + std::string message; + if (lua_isstring(L, 2)) + message.append(readParam<std::string>(L, 2)); + else + message.append("Disconnected."); + + Server *server = getServer(L); + + RemotePlayer *player = server->getEnv().getPlayer(name); + if (!player) { + lua_pushboolean(L, false); // No such player + return 1; + } + + server->DenyAccess(player->getPeerId(), SERVER_ACCESSDENIED_CUSTOM_STRING, message); + lua_pushboolean(L, true); + return 1; +} + +int ModApiServer::l_remove_player(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string name = luaL_checkstring(L, 1); + ServerEnvironment *s_env = dynamic_cast<ServerEnvironment *>(getEnv(L)); + if (!s_env) + throw LuaError("Can't remove player before server has started up"); + + RemotePlayer *player = s_env->getPlayer(name.c_str()); + if (!player) + lua_pushinteger(L, s_env->removePlayerFromDatabase(name) ? 0 : 1); + else + lua_pushinteger(L, 2); + + return 1; +} + +// unban_player_or_ip() +int ModApiServer::l_unban_player_or_ip(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char * ip_or_name = luaL_checkstring(L, 1); + getServer(L)->unsetIpBanned(ip_or_name); + lua_pushboolean(L, true); + return 1; +} + +// show_formspec(playername,formname,formspec) +int ModApiServer::l_show_formspec(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *playername = luaL_checkstring(L, 1); + const char *formname = luaL_checkstring(L, 2); + const char *formspec = luaL_checkstring(L, 3); + + if(getServer(L)->showFormspec(playername,formspec,formname)) + { + lua_pushboolean(L, true); + }else{ + lua_pushboolean(L, false); + } + return 1; +} + +// get_current_modname() +int ModApiServer::l_get_current_modname(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); + return 1; +} + +// get_modpath(modname) +int ModApiServer::l_get_modpath(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string modname = luaL_checkstring(L, 1); + const ModSpec *mod = getGameDef(L)->getModSpec(modname); + if (!mod) + lua_pushnil(L); + else + lua_pushstring(L, mod->path.c_str()); + return 1; +} + +// get_modnames() +// the returned list is sorted alphabetically for you +int ModApiServer::l_get_modnames(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + // Get a list of mods + std::vector<std::string> modlist; + for (auto &it : getGameDef(L)->getMods()) + modlist.emplace_back(it.name); + + std::sort(modlist.begin(), modlist.end()); + + // Package them up for Lua + lua_createtable(L, modlist.size(), 0); + auto iter = modlist.begin(); + for (u16 i = 0; iter != modlist.end(); ++iter) { + lua_pushstring(L, iter->c_str()); + lua_rawseti(L, -2, ++i); + } + return 1; +} + +// get_worldpath() +int ModApiServer::l_get_worldpath(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const Server *srv = getServer(L); + lua_pushstring(L, srv->getWorldPath().c_str()); + return 1; +} + +// sound_play(spec, parameters, [ephemeral]) +int ModApiServer::l_sound_play(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ServerPlayingSound params; + read_soundspec(L, 1, params.spec); + read_server_sound_params(L, 2, params); + bool ephemeral = lua_gettop(L) > 2 && readParam<bool>(L, 3); + if (ephemeral) { + getServer(L)->playSound(params, true); + lua_pushnil(L); + } else { + s32 handle = getServer(L)->playSound(params); + lua_pushinteger(L, handle); + } + return 1; +} + +// sound_stop(handle) +int ModApiServer::l_sound_stop(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + s32 handle = luaL_checkinteger(L, 1); + getServer(L)->stopSound(handle); + return 0; +} + +int ModApiServer::l_sound_fade(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + s32 handle = luaL_checkinteger(L, 1); + float step = readParam<float>(L, 2); + float gain = readParam<float>(L, 3); + getServer(L)->fadeSound(handle, step, gain); + return 0; +} + +// dynamic_add_media(filepath) +int ModApiServer::l_dynamic_add_media(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + if (!getEnv(L)) + throw LuaError("Dynamic media cannot be added before server has started up"); + Server *server = getServer(L); + + std::string filepath; + std::string to_player; + bool ephemeral = false; + + if (lua_istable(L, 1)) { + getstringfield(L, 1, "filepath", filepath); + getstringfield(L, 1, "to_player", to_player); + getboolfield(L, 1, "ephemeral", ephemeral); + } else { + filepath = readParam<std::string>(L, 1); + } + if (filepath.empty()) + luaL_typerror(L, 1, "non-empty string"); + luaL_checktype(L, 2, LUA_TFUNCTION); + + CHECK_SECURE_PATH(L, filepath.c_str(), false); + + u32 token = server->getScriptIface()->allocateDynamicMediaCallback(L, 2); + + bool ok = server->dynamicAddMedia(filepath, token, to_player, ephemeral); + if (!ok) + server->getScriptIface()->freeDynamicMediaCallback(token); + lua_pushboolean(L, ok); + + return 1; +} + +// is_singleplayer() +int ModApiServer::l_is_singleplayer(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const Server *srv = getServer(L); + lua_pushboolean(L, srv->isSingleplayer()); + return 1; +} + +// notify_authentication_modified(name) +int ModApiServer::l_notify_authentication_modified(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string name; + if(lua_isstring(L, 1)) + name = readParam<std::string>(L, 1); + getServer(L)->reportPrivsModified(name); + return 0; +} + +// do_async_callback(func, params, mod_origin) +int ModApiServer::l_do_async_callback(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ServerScripting *script = getScriptApi<ServerScripting>(L); + + luaL_checktype(L, 1, LUA_TFUNCTION); + luaL_checktype(L, 2, LUA_TTABLE); + luaL_checktype(L, 3, LUA_TSTRING); + + call_string_dump(L, 1); + size_t func_length; + const char *serialized_func_raw = lua_tolstring(L, -1, &func_length); + + PackedValue *param = script_pack(L, 2); + + std::string mod_origin = readParam<std::string>(L, 3); + + u32 jobId = script->queueAsync( + std::string(serialized_func_raw, func_length), + param, mod_origin); + + lua_settop(L, 0); + lua_pushinteger(L, jobId); + return 1; +} + +// register_async_dofile(path) +int ModApiServer::l_register_async_dofile(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + std::string path = readParam<std::string>(L, 1); + CHECK_SECURE_PATH(L, path.c_str(), false); + + // Find currently running mod name (only at init time) + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); + if (!lua_isstring(L, -1)) + return 0; + std::string modname = readParam<std::string>(L, -1); + + getServer(L)->m_async_init_files.emplace_back(modname, path); + lua_pushboolean(L, true); + return 1; +} + +// serialize_roundtrip(value) +// Meant for unit testing the packer from Lua +int ModApiServer::l_serialize_roundtrip(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + int top = lua_gettop(L); + auto *pv = script_pack(L, 1); + if (top != lua_gettop(L)) + throw LuaError("stack values leaked"); + +#ifndef NDEBUG + script_dump_packed(pv); +#endif + + top = lua_gettop(L); + script_unpack(L, pv); + delete pv; + if (top + 1 != lua_gettop(L)) + throw LuaError("stack values leaked"); + + return 1; +} + +void ModApiServer::Initialize(lua_State *L, int top) +{ + API_FCT(request_shutdown); + API_FCT(get_server_status); + API_FCT(get_server_uptime); + API_FCT(get_server_max_lag); + API_FCT(get_worldpath); + API_FCT(is_singleplayer); + + API_FCT(get_current_modname); + API_FCT(get_modpath); + API_FCT(get_modnames); + + API_FCT(print); + + API_FCT(chat_send_all); + API_FCT(chat_send_player); + API_FCT(show_formspec); + API_FCT(sound_play); + API_FCT(sound_stop); + API_FCT(sound_fade); + API_FCT(dynamic_add_media); + + API_FCT(get_player_information); + API_FCT(get_player_privs); + API_FCT(get_player_ip); + API_FCT(get_ban_list); + API_FCT(get_ban_description); + API_FCT(ban_player); + API_FCT(disconnect_player); + API_FCT(remove_player); + API_FCT(unban_player_or_ip); + API_FCT(notify_authentication_modified); + + API_FCT(do_async_callback); + API_FCT(register_async_dofile); + API_FCT(serialize_roundtrip); +} + +void ModApiServer::InitializeAsync(lua_State *L, int top) +{ + API_FCT(get_worldpath); + API_FCT(is_singleplayer); + + API_FCT(get_current_modname); + API_FCT(get_modpath); + API_FCT(get_modnames); +} diff --git a/src/script/lua_api/l_server.h b/src/script/lua_api/l_server.h new file mode 100644 index 0000000..a4f38c3 --- /dev/null +++ b/src/script/lua_api/l_server.h @@ -0,0 +1,121 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" + +class ModApiServer : public ModApiBase +{ +private: + // request_shutdown([message], [reconnect]) + static int l_request_shutdown(lua_State *L); + + // get_server_status() + static int l_get_server_status(lua_State *L); + + // get_server_uptime() + static int l_get_server_uptime(lua_State *L); + + // get_server_max_lag() + static int l_get_server_max_lag(lua_State *L); + + // get_worldpath() + static int l_get_worldpath(lua_State *L); + + // is_singleplayer() + static int l_is_singleplayer(lua_State *L); + + // get_current_modname() + static int l_get_current_modname(lua_State *L); + + // get_modpath(modname) + static int l_get_modpath(lua_State *L); + + // get_modnames() + // the returned list is sorted alphabetically for you + static int l_get_modnames(lua_State *L); + + // print(text) + static int l_print(lua_State *L); + + // chat_send_all(text) + static int l_chat_send_all(lua_State *L); + + // chat_send_player(name, text) + static int l_chat_send_player(lua_State *L); + + // show_formspec(playername,formname,formspec) + static int l_show_formspec(lua_State *L); + + // sound_play(spec, parameters) + static int l_sound_play(lua_State *L); + + // sound_stop(handle) + static int l_sound_stop(lua_State *L); + + // sound_fade(handle, step, gain) + static int l_sound_fade(lua_State *L); + + // dynamic_add_media(filepath) + static int l_dynamic_add_media(lua_State *L); + + // get_player_privs(name, text) + static int l_get_player_privs(lua_State *L); + + // get_player_ip() + static int l_get_player_ip(lua_State *L); + + // get_player_information(name) + static int l_get_player_information(lua_State *L); + + // get_ban_list() + static int l_get_ban_list(lua_State *L); + + // get_ban_description() + static int l_get_ban_description(lua_State *L); + + // ban_player() + static int l_ban_player(lua_State *L); + + // unban_player_or_ip() + static int l_unban_player_or_ip(lua_State *L); + + // disconnect_player(name, [reason]) -> success + static int l_disconnect_player(lua_State *L); + + // remove_player(name) + static int l_remove_player(lua_State *L); + + // notify_authentication_modified(name) + static int l_notify_authentication_modified(lua_State *L); + + // do_async_callback(func, params, mod_origin) + static int l_do_async_callback(lua_State *L); + + // register_async_dofile(path) + static int l_register_async_dofile(lua_State *L); + + // serialize_roundtrip(obj) + static int l_serialize_roundtrip(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); + static void InitializeAsync(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_settings.cpp b/src/script/lua_api/l_settings.cpp new file mode 100644 index 0000000..3f3fda5 --- /dev/null +++ b/src/script/lua_api/l_settings.cpp @@ -0,0 +1,396 @@ +/* +Minetest +Copyright (C) 2013 PilzAdam <pilzadam@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_settings.h" +#include "lua_api/l_internal.h" +#include "cpp_api/s_security.h" +#include "threading/mutex_auto_lock.h" +#include "util/string.h" // FlagDesc +#include "settings.h" +#include "noise.h" +#include "log.h" + + +/* This protects the following from being set: + * 'secure.*' settings + * some security-relevant settings + * (better solution pending) + * some mapgen settings + * (not security-criticial, just to avoid messing up user configs) + */ +#define CHECK_SETTING_SECURITY(L, name) \ + if (o->m_settings == g_settings) { \ + if (checkSettingSecurity(L, name) == -1) \ + return 0; \ + } + +static inline int checkSettingSecurity(lua_State* L, const std::string &name) +{ + if (ScriptApiSecurity::isSecure(L) && name.compare(0, 7, "secure.") == 0) + throw LuaError("Attempted to set secure setting."); + + bool is_mainmenu = false; +#ifndef SERVER + is_mainmenu = ModApiBase::getGuiEngine(L) != nullptr; +#endif + if (!is_mainmenu && (name == "mg_name" || name == "mg_flags")) { + errorstream << "Tried to set global setting " << name << ", ignoring. " + "minetest.set_mapgen_setting() should be used instead." << std::endl; + infostream << script_get_backtrace(L) << std::endl; + return -1; + } + + const char *disallowed[] = { + "main_menu_script", "shader_path", "texture_path", "screenshot_path", + "serverlist_file", "serverlist_url", "map-dir", "contentdb_url", + }; + if (!is_mainmenu) { + for (const char *name2 : disallowed) { + if (name == name2) + throw LuaError("Attempted to set disallowed setting."); + } + } + + return 0; +} + +LuaSettings::LuaSettings(Settings *settings, const std::string &filename) : + m_settings(settings), + m_filename(filename) +{ +} + +LuaSettings::LuaSettings(const std::string &filename, bool write_allowed) : + m_filename(filename), + m_is_own_settings(true), + m_write_allowed(write_allowed) +{ + m_settings = new Settings(); + m_settings->readConfigFile(filename.c_str()); +} + +LuaSettings::~LuaSettings() +{ + if (m_is_own_settings) + delete m_settings; +} + + +void LuaSettings::create(lua_State *L, Settings *settings, + const std::string &filename) +{ + LuaSettings *o = new LuaSettings(settings, filename); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + + +// garbage collector +int LuaSettings::gc_object(lua_State* L) +{ + LuaSettings* o = *(LuaSettings **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + + +// get(self, key) -> value +int LuaSettings::l_get(lua_State* L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings* o = checkobject(L, 1); + + std::string key = std::string(luaL_checkstring(L, 2)); + if (o->m_settings->exists(key)) { + std::string value = o->m_settings->get(key); + lua_pushstring(L, value.c_str()); + } else { + lua_pushnil(L); + } + + return 1; +} + +// get_bool(self, key) -> boolean +int LuaSettings::l_get_bool(lua_State* L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings* o = checkobject(L, 1); + + std::string key = std::string(luaL_checkstring(L, 2)); + if (o->m_settings->exists(key)) { + bool value = o->m_settings->getBool(key); + lua_pushboolean(L, value); + } else { + // Push default value + if (lua_isboolean(L, 3)) + lua_pushboolean(L, readParam<bool>(L, 3)); + else + lua_pushnil(L); + } + + return 1; +} + +// get_np_group(self, key) -> value +int LuaSettings::l_get_np_group(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings *o = checkobject(L, 1); + + std::string key = std::string(luaL_checkstring(L, 2)); + if (o->m_settings->exists(key)) { + NoiseParams np; + o->m_settings->getNoiseParams(key, np); + push_noiseparams(L, &np); + } else { + lua_pushnil(L); + } + + return 1; +} + +// get_flags(self, key) -> table or nil +int LuaSettings::l_get_flags(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings *o = checkobject(L, 1); + std::string key = std::string(luaL_checkstring(L, 2)); + + u32 flags = 0; + auto flagdesc = o->m_settings->getFlagDescFallback(key); + if (o->m_settings->getFlagStrNoEx(key, flags, flagdesc)) { + lua_newtable(L); + int table = lua_gettop(L); + for (size_t i = 0; flagdesc[i].name; ++i) { + lua_pushboolean(L, flags & flagdesc[i].flag); + lua_setfield(L, table, flagdesc[i].name); + } + lua_pushvalue(L, table); + } else { + lua_pushnil(L); + } + + return 1; +} + +// set(self, key, value) +int LuaSettings::l_set(lua_State* L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings* o = checkobject(L, 1); + + std::string key = std::string(luaL_checkstring(L, 2)); + const char* value = luaL_checkstring(L, 3); + + CHECK_SETTING_SECURITY(L, key); + + if (!o->m_settings->set(key, value)) + throw LuaError("Invalid sequence found in setting parameters"); + + return 0; +} + +// set_bool(self, key, value) +int LuaSettings::l_set_bool(lua_State* L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings* o = checkobject(L, 1); + + std::string key = std::string(luaL_checkstring(L, 2)); + bool value = readParam<bool>(L, 3); + + CHECK_SETTING_SECURITY(L, key); + + o->m_settings->setBool(key, value); + + return 0; +} + +// set_np_group(self, key, value) +int LuaSettings::l_set_np_group(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings *o = checkobject(L, 1); + + std::string key = std::string(luaL_checkstring(L, 2)); + NoiseParams value; + read_noiseparams(L, 3, &value); + + CHECK_SETTING_SECURITY(L, key); + + o->m_settings->setNoiseParams(key, value); + + return 0; +} + +// remove(self, key) -> success +int LuaSettings::l_remove(lua_State* L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings* o = checkobject(L, 1); + + std::string key = std::string(luaL_checkstring(L, 2)); + + CHECK_SETTING_SECURITY(L, key); + + bool success = o->m_settings->remove(key); + lua_pushboolean(L, success); + + return 1; +} + +// get_names(self) -> {key1, ...} +int LuaSettings::l_get_names(lua_State* L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings* o = checkobject(L, 1); + + std::vector<std::string> keys = o->m_settings->getNames(); + + lua_newtable(L); + for (unsigned int i=0; i < keys.size(); i++) + { + lua_pushstring(L, keys[i].c_str()); + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +// write(self) -> success +int LuaSettings::l_write(lua_State* L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings* o = checkobject(L, 1); + + if (!o->m_write_allowed) { + throw LuaError("Settings: writing " + o->m_filename + + " not allowed with mod security on."); + } + + bool success = o->m_settings->updateConfigFile(o->m_filename.c_str()); + lua_pushboolean(L, success); + + return 1; +} + +static void push_settings_table(lua_State *L, const Settings *settings) +{ + std::vector<std::string> keys = settings->getNames(); + lua_newtable(L); + for (const std::string &key : keys) { + std::string value; + Settings *group = nullptr; + + if (settings->getNoEx(key, value)) { + lua_pushstring(L, value.c_str()); + } else if (settings->getGroupNoEx(key, group)) { + // Recursively push tables + push_settings_table(L, group); + } else { + // Impossible case (multithreading) due to MutexAutoLock + continue; + } + + lua_setfield(L, -2, key.c_str()); + } +} + +// to_table(self) -> {[key1]=value1,...} +int LuaSettings::l_to_table(lua_State* L) +{ + NO_MAP_LOCK_REQUIRED; + LuaSettings* o = checkobject(L, 1); + + MutexAutoLock(o->m_settings->m_mutex); + push_settings_table(L, o->m_settings); + return 1; +} + + +void LuaSettings::Register(lua_State* L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // drop methodtable + + // Can be created from Lua (Settings(filename)) + lua_register(L, className, create_object); +} + +// LuaSettings(filename) +// Creates a LuaSettings and leaves it on top of the stack +int LuaSettings::create_object(lua_State* L) +{ + NO_MAP_LOCK_REQUIRED; + bool write_allowed = true; + const char* filename = luaL_checkstring(L, 1); + CHECK_SECURE_PATH_POSSIBLE_WRITE(L, filename, &write_allowed); + LuaSettings* o = new LuaSettings(filename, write_allowed); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + +LuaSettings* LuaSettings::checkobject(lua_State* L, int narg) +{ + NO_MAP_LOCK_REQUIRED; + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + return *(LuaSettings**) ud; // unbox pointer +} + +const char LuaSettings::className[] = "Settings"; +const luaL_Reg LuaSettings::methods[] = { + luamethod(LuaSettings, get), + luamethod(LuaSettings, get_bool), + luamethod(LuaSettings, get_np_group), + luamethod(LuaSettings, get_flags), + luamethod(LuaSettings, set), + luamethod(LuaSettings, set_bool), + luamethod(LuaSettings, set_np_group), + luamethod(LuaSettings, remove), + luamethod(LuaSettings, get_names), + luamethod(LuaSettings, write), + luamethod(LuaSettings, to_table), + {0,0} +}; diff --git a/src/script/lua_api/l_settings.h b/src/script/lua_api/l_settings.h new file mode 100644 index 0000000..67d7b34 --- /dev/null +++ b/src/script/lua_api/l_settings.h @@ -0,0 +1,88 @@ +/* +Minetest +Copyright (C) 2013 PilzAdam <pilzadam@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "common/c_content.h" +#include "lua_api/l_base.h" + +class Settings; + +class LuaSettings : public ModApiBase +{ +private: + static const char className[]; + static const luaL_Reg methods[]; + + // garbage collector + static int gc_object(lua_State *L); + + // get(self, key) -> value + static int l_get(lua_State *L); + + // get_bool(self, key) -> boolean + static int l_get_bool(lua_State *L); + + // get_np_group(self, key) -> noiseparam + static int l_get_np_group(lua_State *L); + + // get_flags(self, key) -> key/value table + static int l_get_flags(lua_State *L); + + // set(self, key, value) + static int l_set(lua_State *L); + + // set_bool(self, key, value) + static int l_set_bool(lua_State *L); + + // set_np_group(self, key, value) + static int l_set_np_group(lua_State *L); + + // remove(self, key) -> success + static int l_remove(lua_State *L); + + // get_names(self) -> {key1, ...} + static int l_get_names(lua_State *L); + + // write(self) -> success + static int l_write(lua_State *L); + + // to_table(self) -> {[key1]=value1,...} + static int l_to_table(lua_State *L); + + Settings *m_settings = nullptr; + std::string m_filename; + bool m_is_own_settings = false; + bool m_write_allowed = true; + +public: + LuaSettings(Settings *settings, const std::string &filename); + LuaSettings(const std::string &filename, bool write_allowed); + ~LuaSettings(); + + static void create(lua_State *L, Settings *settings, const std::string &filename); + + // LuaSettings(filename) + // Creates a LuaSettings and leaves it on top of the stack + static int create_object(lua_State *L); + + static LuaSettings *checkobject(lua_State *L, int narg); + + static void Register(lua_State *L); +}; diff --git a/src/script/lua_api/l_sound.cpp b/src/script/lua_api/l_sound.cpp new file mode 100644 index 0000000..934b4a0 --- /dev/null +++ b/src/script/lua_api/l_sound.cpp @@ -0,0 +1,53 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "l_sound.h" +#include "l_internal.h" +#include "common/c_content.h" +#include "gui/guiEngine.h" + + +int ModApiSound::l_sound_play(lua_State *L) +{ + SimpleSoundSpec spec; + read_soundspec(L, 1, spec); + spec.loop = readParam<bool>(L, 2); + + s32 handle = getGuiEngine(L)->playSound(spec); + + lua_pushinteger(L, handle); + + return 1; +} + +int ModApiSound::l_sound_stop(lua_State *L) +{ + u32 handle = luaL_checkinteger(L, 1); + + getGuiEngine(L)->stopSound(handle); + + return 1; +} + +void ModApiSound::Initialize(lua_State *L, int top) +{ + API_FCT(sound_play); + API_FCT(sound_stop); +} diff --git a/src/script/lua_api/l_sound.h b/src/script/lua_api/l_sound.h new file mode 100644 index 0000000..888a0f3 --- /dev/null +++ b/src/script/lua_api/l_sound.h @@ -0,0 +1,33 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" + +class ModApiSound : public ModApiBase +{ +private: + static int l_sound_play(lua_State *L); + static int l_sound_stop(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_storage.cpp b/src/script/lua_api/l_storage.cpp new file mode 100644 index 0000000..b6c53e3 --- /dev/null +++ b/src/script/lua_api/l_storage.cpp @@ -0,0 +1,155 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_storage.h" +#include "l_internal.h" +#include "content/mods.h" +#include "server.h" + +int ModApiStorage::l_get_mod_storage(lua_State *L) +{ + // Note that this is wrapped in Lua, see builtin/common/mod_storage.lua + std::string mod_name = readParam<std::string>(L, 1); + + ModMetadata *store = nullptr; + + if (IGameDef *gamedef = getGameDef(L)) { + store = new ModMetadata(mod_name, gamedef->getModStorageDatabase()); + if (gamedef->registerModStorage(store)) { + StorageRef::create(L, store); + int object = lua_gettop(L); + lua_pushvalue(L, object); + return 1; + } + } else { + assert(false); // this should not happen + } + + delete store; + + lua_pushnil(L); + return 1; +} + +void ModApiStorage::Initialize(lua_State *L, int top) +{ + API_FCT(get_mod_storage); +} + +StorageRef::StorageRef(ModMetadata *object): + m_object(object) +{ +} + +StorageRef::~StorageRef() +{ + delete m_object; +} + +void StorageRef::create(lua_State *L, ModMetadata *object) +{ + StorageRef *o = new StorageRef(object); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +int StorageRef::gc_object(lua_State *L) +{ + StorageRef *o = *(StorageRef **)(lua_touserdata(L, 1)); + // Server side + if (IGameDef *gamedef = getGameDef(L)) + gamedef->unregisterModStorage(getobject(o)->getModName()); + delete o; + return 0; +} + +void StorageRef::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "metadata_class"); + lua_pushlstring(L, className, strlen(className)); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pushliteral(L, "__eq"); + lua_pushcfunction(L, l_equals); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // drop methodtable +} + +StorageRef* StorageRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) luaL_typerror(L, narg, className); + return *(StorageRef**)ud; // unbox pointer +} + +ModMetadata* StorageRef::getobject(StorageRef *ref) +{ + ModMetadata *co = ref->m_object; + return co; +} + +Metadata* StorageRef::getmeta(bool auto_create) +{ + return m_object; +} + +void StorageRef::clearMeta() +{ + m_object->clear(); +} + +const char StorageRef::className[] = "StorageRef"; +const luaL_Reg StorageRef::methods[] = { + luamethod(MetaDataRef, contains), + luamethod(MetaDataRef, get), + luamethod(MetaDataRef, get_string), + luamethod(MetaDataRef, set_string), + luamethod(MetaDataRef, get_int), + luamethod(MetaDataRef, set_int), + luamethod(MetaDataRef, get_float), + luamethod(MetaDataRef, set_float), + luamethod(MetaDataRef, to_table), + luamethod(MetaDataRef, from_table), + luamethod(MetaDataRef, equals), + {0,0} +}; diff --git a/src/script/lua_api/l_storage.h b/src/script/lua_api/l_storage.h new file mode 100644 index 0000000..bfcf5ef --- /dev/null +++ b/src/script/lua_api/l_storage.h @@ -0,0 +1,60 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "l_metadata.h" +#include "lua_api/l_base.h" + +class ModMetadata; + +class ModApiStorage : public ModApiBase +{ +protected: + static int l_get_mod_storage(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); +}; + +class StorageRef : public MetaDataRef +{ +private: + ModMetadata *m_object = nullptr; + + static const char className[]; + static const luaL_Reg methods[]; + + virtual Metadata *getmeta(bool auto_create); + virtual void clearMeta(); + + // garbage collector + static int gc_object(lua_State *L); + +public: + StorageRef(ModMetadata *object); + ~StorageRef(); + + static void Register(lua_State *L); + static void create(lua_State *L, ModMetadata *object); + + static StorageRef *checkobject(lua_State *L, int narg); + static ModMetadata *getobject(StorageRef *ref); +}; diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp new file mode 100644 index 0000000..f602aed --- /dev/null +++ b/src/script/lua_api/l_util.cpp @@ -0,0 +1,710 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "irrlichttypes_extrabloated.h" +#include "lua_api/l_util.h" +#include "lua_api/l_internal.h" +#include "lua_api/l_settings.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "cpp_api/s_async.h" +#include "serialization.h" +#include <json/json.h> +#include "cpp_api/s_security.h" +#include "porting.h" +#include "convert_json.h" +#include "debug.h" +#include "log.h" +#include "tool.h" +#include "filesys.h" +#include "settings.h" +#include "util/auth.h" +#include "util/base64.h" +#include "config.h" +#include "version.h" +#include "util/hex.h" +#include "util/sha1.h" +#include "util/png.h" +#include <cstdio> + +// log([level,] text) +// Writes a line to the logger. +// The one-argument version logs to LL_NONE. +// The two-argument version accepts a log level. +// Either the special case "deprecated" for deprecation notices, or any specified in +// Logger::stringToLevel(name). +int ModApiUtil::l_log(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string text; + LogLevel level = LL_NONE; + if (lua_isnone(L, 2)) { + text = luaL_checkstring(L, 1); + } else { + std::string name = luaL_checkstring(L, 1); + text = luaL_checkstring(L, 2); + if (name == "deprecated") { + log_deprecated(L, text, 2); + return 0; + } + level = Logger::stringToLevel(name); + if (level == LL_MAX) { + warningstream << "Tried to log at unknown level '" << name + << "'. Defaulting to \"none\"." << std::endl; + level = LL_NONE; + } + } + g_logger.log(level, text); + return 0; +} + +// get_us_time() +int ModApiUtil::l_get_us_time(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + lua_pushnumber(L, porting::getTimeUs()); + return 1; +} + +// parse_json(str[, nullvalue]) +int ModApiUtil::l_parse_json(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + const char *jsonstr = luaL_checkstring(L, 1); + + // Use passed nullvalue or default to nil + int nullindex = 2; + if (lua_isnone(L, nullindex)) { + lua_pushnil(L); + nullindex = lua_gettop(L); + } + + Json::Value root; + + { + std::istringstream stream(jsonstr); + + Json::CharReaderBuilder builder; + builder.settings_["collectComments"] = false; + std::string errs; + + if (!Json::parseFromStream(builder, stream, &root, &errs)) { + errorstream << "Failed to parse json data " << errs << std::endl; + size_t jlen = strlen(jsonstr); + if (jlen > 100) { + errorstream << "Data (" << jlen + << " bytes) printed to warningstream." << std::endl; + warningstream << "data: \"" << jsonstr << "\"" << std::endl; + } else { + errorstream << "data: \"" << jsonstr << "\"" << std::endl; + } + lua_pushnil(L); + return 1; + } + } + + if (!push_json_value(L, root, nullindex)) { + errorstream << "Failed to parse json data, " + << "depth exceeds lua stack limit" << std::endl; + errorstream << "data: \"" << jsonstr << "\"" << std::endl; + lua_pushnil(L); + } + return 1; +} + +// write_json(data[, styled]) -> string or nil and error message +int ModApiUtil::l_write_json(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + bool styled = false; + if (!lua_isnone(L, 2)) { + styled = readParam<bool>(L, 2); + lua_pop(L, 1); + } + + Json::Value root; + try { + read_json_value(L, root, 1); + } catch (SerializationError &e) { + lua_pushnil(L); + lua_pushstring(L, e.what()); + return 2; + } + + std::string out; + if (styled) { + out = root.toStyledString(); + } else { + out = fastWriteJson(root); + } + lua_pushlstring(L, out.c_str(), out.size()); + return 1; +} + +// get_tool_wear_after_use(uses[, initial_wear]) +int ModApiUtil::l_get_tool_wear_after_use(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + u32 uses = readParam<int>(L, 1); + u16 initial_wear = readParam<int>(L, 2, 0); + u16 wear = calculateResultWear(uses, initial_wear); + lua_pushnumber(L, wear); + return 1; +} + +// get_dig_params(groups, tool_capabilities[, wear]) +int ModApiUtil::l_get_dig_params(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ItemGroupList groups; + read_groups(L, 1, groups); + ToolCapabilities tp = read_tool_capabilities(L, 2); + if (lua_isnoneornil(L, 3)) { + push_dig_params(L, getDigParams(groups, &tp)); + } else { + u16 wear = readParam<int>(L, 3); + push_dig_params(L, getDigParams(groups, &tp, wear)); + } + return 1; +} + +// get_hit_params(groups, tool_capabilities[, time_from_last_punch, [, wear]]) +int ModApiUtil::l_get_hit_params(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::unordered_map<std::string, int> groups; + read_groups(L, 1, groups); + ToolCapabilities tp = read_tool_capabilities(L, 2); + float time_from_last_punch = readParam<float>(L, 3, 1000000); + int wear = readParam<int>(L, 4, 0); + push_hit_params(L, getHitParams(groups, &tp, + time_from_last_punch, wear)); + return 1; +} + +// check_password_entry(name, entry, password) +int ModApiUtil::l_check_password_entry(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string name = luaL_checkstring(L, 1); + std::string entry = luaL_checkstring(L, 2); + std::string password = luaL_checkstring(L, 3); + + if (base64_is_valid(entry)) { + std::string hash = translate_password(name, password); + lua_pushboolean(L, hash == entry); + return 1; + } + + std::string salt; + std::string verifier; + + if (!decode_srp_verifier_and_salt(entry, &verifier, &salt)) { + // invalid format + warningstream << "Invalid password format for " << name << std::endl; + lua_pushboolean(L, false); + return 1; + } + std::string gen_verifier = generate_srp_verifier(name, password, salt); + + lua_pushboolean(L, gen_verifier == verifier); + return 1; +} + +// get_password_hash(name, raw_password) +int ModApiUtil::l_get_password_hash(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string name = luaL_checkstring(L, 1); + std::string raw_password = luaL_checkstring(L, 2); + std::string hash = translate_password(name, raw_password); + lua_pushstring(L, hash.c_str()); + return 1; +} + +// is_yes(arg) +int ModApiUtil::l_is_yes(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + lua_getglobal(L, "tostring"); // function to be called + lua_pushvalue(L, 1); // 1st argument + lua_call(L, 1, 1); // execute function + std::string str = readParam<std::string>(L, -1); // get result + lua_pop(L, 1); + + bool yes = is_yes(str); + lua_pushboolean(L, yes); + return 1; +} + +// get_builtin_path() +int ModApiUtil::l_get_builtin_path(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + std::string path = porting::path_share + DIR_DELIM + "builtin" + DIR_DELIM; + lua_pushstring(L, path.c_str()); + + return 1; +} + +// get_user_path() +int ModApiUtil::l_get_user_path(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + std::string path = porting::path_user; + lua_pushstring(L, path.c_str()); + + return 1; +} + +// compress(data, method, level) +int ModApiUtil::l_compress(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + size_t size; + const char *data = luaL_checklstring(L, 1, &size); + + int level = -1; + if (!lua_isnoneornil(L, 3)) + level = readParam<int>(L, 3); + + std::ostringstream os(std::ios_base::binary); + compressZlib(reinterpret_cast<const u8 *>(data), size, os, level); + + std::string out = os.str(); + + lua_pushlstring(L, out.data(), out.size()); + return 1; +} + +// decompress(data, method) +int ModApiUtil::l_decompress(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + size_t size; + const char *data = luaL_checklstring(L, 1, &size); + + std::istringstream is(std::string(data, size), std::ios_base::binary); + std::ostringstream os(std::ios_base::binary); + decompressZlib(is, os); + + std::string out = os.str(); + + lua_pushlstring(L, out.data(), out.size()); + return 1; +} + +// encode_base64(string) +int ModApiUtil::l_encode_base64(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + size_t size; + const char *data = luaL_checklstring(L, 1, &size); + + std::string out = base64_encode((const unsigned char *)(data), size); + + lua_pushlstring(L, out.data(), out.size()); + return 1; +} + +// decode_base64(string) +int ModApiUtil::l_decode_base64(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + size_t size; + const char *d = luaL_checklstring(L, 1, &size); + const std::string data = std::string(d, size); + + if (!base64_is_valid(data)) + return 0; + + std::string out = base64_decode(data); + + lua_pushlstring(L, out.data(), out.size()); + return 1; +} + +// mkdir(path) +int ModApiUtil::l_mkdir(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *path = luaL_checkstring(L, 1); + CHECK_SECURE_PATH(L, path, true); + lua_pushboolean(L, fs::CreateAllDirs(path)); + return 1; +} + +// rmdir(path, recursive) +int ModApiUtil::l_rmdir(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *path = luaL_checkstring(L, 1); + CHECK_SECURE_PATH(L, path, true); + + bool recursive = readParam<bool>(L, 2, false); + + if (recursive) + lua_pushboolean(L, fs::RecursiveDelete(path)); + else + lua_pushboolean(L, fs::DeleteSingleFileOrEmptyDirectory(path)); + + return 1; +} + +// cpdir(source, destination) +int ModApiUtil::l_cpdir(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *source = luaL_checkstring(L, 1); + const char *destination = luaL_checkstring(L, 2); + CHECK_SECURE_PATH(L, source, false); + CHECK_SECURE_PATH(L, destination, true); + + lua_pushboolean(L, fs::CopyDir(source, destination)); + return 1; +} + +// mpdir(source, destination) +int ModApiUtil::l_mvdir(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *source = luaL_checkstring(L, 1); + const char *destination = luaL_checkstring(L, 2); + CHECK_SECURE_PATH(L, source, true); + CHECK_SECURE_PATH(L, destination, true); + + lua_pushboolean(L, fs::MoveDir(source, destination)); + return 1; +} + +// get_dir_list(path, is_dir) +int ModApiUtil::l_get_dir_list(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *path = luaL_checkstring(L, 1); + bool list_all = !lua_isboolean(L, 2); // if its not a boolean list all + bool list_dirs = readParam<bool>(L, 2); // true: list dirs, false: list files + + CHECK_SECURE_PATH(L, path, false); + + std::vector<fs::DirListNode> list = fs::GetDirListing(path); + + int index = 0; + lua_newtable(L); + + for (const fs::DirListNode &dln : list) { + if (list_all || list_dirs == dln.dir) { + lua_pushstring(L, dln.name.c_str()); + lua_rawseti(L, -2, ++index); + } + } + + return 1; +} + +// safe_file_write(path, content) +int ModApiUtil::l_safe_file_write(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *path = luaL_checkstring(L, 1); + size_t size; + const char *content = luaL_checklstring(L, 2, &size); + + CHECK_SECURE_PATH(L, path, true); + + bool ret = fs::safeWriteToFile(path, std::string(content, size)); + lua_pushboolean(L, ret); + + return 1; +} + +// request_insecure_environment() +int ModApiUtil::l_request_insecure_environment(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + // Just return _G if security is disabled + if (!ScriptApiSecurity::isSecure(L)) { + lua_getglobal(L, "_G"); + return 1; + } + + if (!ScriptApiSecurity::checkWhitelisted(L, "secure.trusted_mods")) { + return 0; + } + + // Push insecure environment + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP); + return 1; +} + +// get_version() +int ModApiUtil::l_get_version(lua_State *L) +{ + lua_createtable(L, 0, 3); + int table = lua_gettop(L); + + lua_pushstring(L, PROJECT_NAME_C); + lua_setfield(L, table, "project"); + + lua_pushstring(L, g_version_string); + lua_setfield(L, table, "string"); + + if (strcmp(g_version_string, g_version_hash) != 0) { + lua_pushstring(L, g_version_hash); + lua_setfield(L, table, "hash"); + } + + lua_pushboolean(L, DEVELOPMENT_BUILD); + lua_setfield(L, table, "is_dev"); + return 1; +} + +int ModApiUtil::l_sha1(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + size_t size; + const char *data = luaL_checklstring(L, 1, &size); + bool hex = !lua_isboolean(L, 2) || !readParam<bool>(L, 2); + + // Compute actual checksum of data + std::string data_sha1; + { + SHA1 ctx; + ctx.addBytes(data, size); + unsigned char *data_tmpdigest = ctx.getDigest(); + data_sha1.assign((char*) data_tmpdigest, 20); + free(data_tmpdigest); + } + + if (hex) { + std::string sha1_hex = hex_encode(data_sha1); + lua_pushstring(L, sha1_hex.c_str()); + } else { + lua_pushlstring(L, data_sha1.data(), data_sha1.size()); + } + + return 1; +} + +// colorspec_to_colorstring(colorspec) +int ModApiUtil::l_colorspec_to_colorstring(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + video::SColor color(0); + if (read_color(L, 1, &color)) { + char colorstring[10]; + snprintf(colorstring, 10, "#%02X%02X%02X%02X", + color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + lua_pushstring(L, colorstring); + return 1; + } + + return 0; +} + +// colorspec_to_bytes(colorspec) +int ModApiUtil::l_colorspec_to_bytes(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + video::SColor color(0); + if (read_color(L, 1, &color)) { + u8 colorbytes[4] = { + (u8) color.getRed(), + (u8) color.getGreen(), + (u8) color.getBlue(), + (u8) color.getAlpha(), + }; + lua_pushlstring(L, (const char*) colorbytes, 4); + return 1; + } + + return 0; +} + +// encode_png(w, h, data, level) +int ModApiUtil::l_encode_png(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + // The args are already pre-validated on the lua side. + u32 width = readParam<int>(L, 1); + u32 height = readParam<int>(L, 2); + const char *data = luaL_checklstring(L, 3, NULL); + s32 compression = readParam<int>(L, 4); + + std::string out = encodePNG((const u8*)data, width, height, compression); + + lua_pushlstring(L, out.data(), out.size()); + return 1; +} + +// get_last_run_mod() +int ModApiUtil::l_get_last_run_mod(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); + std::string current_mod = readParam<std::string>(L, -1, ""); + if (current_mod.empty()) { + lua_pop(L, 1); + lua_pushstring(L, getScriptApiBase(L)->getOrigin().c_str()); + } + return 1; +} + +// set_last_run_mod(modname) +int ModApiUtil::l_set_last_run_mod(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + const char *mod = luaL_checkstring(L, 1); + getScriptApiBase(L)->setOriginDirect(mod); + return 0; +} + +void ModApiUtil::Initialize(lua_State *L, int top) +{ + API_FCT(log); + + API_FCT(get_us_time); + + API_FCT(parse_json); + API_FCT(write_json); + + API_FCT(get_tool_wear_after_use); + API_FCT(get_dig_params); + API_FCT(get_hit_params); + + API_FCT(check_password_entry); + API_FCT(get_password_hash); + + API_FCT(is_yes); + + API_FCT(get_builtin_path); + API_FCT(get_user_path); + + API_FCT(compress); + API_FCT(decompress); + + API_FCT(mkdir); + API_FCT(rmdir); + API_FCT(cpdir); + API_FCT(mvdir); + API_FCT(get_dir_list); + API_FCT(safe_file_write); + + API_FCT(request_insecure_environment); + + API_FCT(encode_base64); + API_FCT(decode_base64); + + API_FCT(get_version); + API_FCT(sha1); + API_FCT(colorspec_to_colorstring); + API_FCT(colorspec_to_bytes); + + API_FCT(encode_png); + + API_FCT(get_last_run_mod); + API_FCT(set_last_run_mod); + + LuaSettings::create(L, g_settings, g_settings_path); + lua_setfield(L, top, "settings"); +} + +void ModApiUtil::InitializeClient(lua_State *L, int top) +{ + API_FCT(log); + + API_FCT(get_us_time); + + API_FCT(parse_json); + API_FCT(write_json); + + API_FCT(is_yes); + + API_FCT(compress); + API_FCT(decompress); + + API_FCT(encode_base64); + API_FCT(decode_base64); + + API_FCT(get_version); + API_FCT(sha1); + API_FCT(colorspec_to_colorstring); + API_FCT(colorspec_to_bytes); + + LuaSettings::create(L, g_settings, g_settings_path); + lua_setfield(L, top, "settings"); +} + +void ModApiUtil::InitializeAsync(lua_State *L, int top) +{ + API_FCT(log); + + API_FCT(get_us_time); + + API_FCT(parse_json); + API_FCT(write_json); + + API_FCT(is_yes); + + API_FCT(get_builtin_path); + API_FCT(get_user_path); + + API_FCT(compress); + API_FCT(decompress); + + API_FCT(mkdir); + API_FCT(rmdir); + API_FCT(cpdir); + API_FCT(mvdir); + API_FCT(get_dir_list); + API_FCT(safe_file_write); + + API_FCT(request_insecure_environment); + + API_FCT(encode_base64); + API_FCT(decode_base64); + + API_FCT(get_version); + API_FCT(sha1); + API_FCT(colorspec_to_colorstring); + API_FCT(colorspec_to_bytes); + + API_FCT(encode_png); + + API_FCT(get_last_run_mod); + API_FCT(set_last_run_mod); + + LuaSettings::create(L, g_settings, g_settings_path); + lua_setfield(L, top, "settings"); +} diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h new file mode 100644 index 0000000..ec86c66 --- /dev/null +++ b/src/script/lua_api/l_util.h @@ -0,0 +1,135 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "lua_api/l_base.h" + +class AsyncEngine; + +class ModApiUtil : public ModApiBase +{ +private: + /* + NOTE: + The functions in this module are available in the in-game API + as well as in the mainmenu API. + + All functions that don't require either a Server or + GUIEngine instance should be in here. + */ + + // log([level,] text) + // Writes a line to the logger. + // The one-argument version logs to LL_NONE. + // The two-argument version accepts a log level. + static int l_log(lua_State *L); + + // get us precision time + static int l_get_us_time(lua_State *L); + + // parse_json(str[, nullvalue]) + static int l_parse_json(lua_State *L); + + // write_json(data[, styled]) + static int l_write_json(lua_State *L); + + // get_tool_wear_after_use(uses[, initial_wear]) + static int l_get_tool_wear_after_use(lua_State *L); + + // get_dig_params(groups, tool_capabilities[, wear]) + static int l_get_dig_params(lua_State *L); + + // get_hit_params(groups, tool_capabilities[, time_from_last_punch[, wear]]) + static int l_get_hit_params(lua_State *L); + + // check_password_entry(name, entry, password) + static int l_check_password_entry(lua_State *L); + + // get_password_hash(name, raw_password) + static int l_get_password_hash(lua_State *L); + + // is_yes(arg) + static int l_is_yes(lua_State *L); + + // get_builtin_path() + static int l_get_builtin_path(lua_State *L); + + // get_user_path() + static int l_get_user_path(lua_State *L); + + // compress(data, method, ...) + static int l_compress(lua_State *L); + + // decompress(data, method, ...) + static int l_decompress(lua_State *L); + + // mkdir(path) + static int l_mkdir(lua_State *L); + + // rmdir(path, recursive) + static int l_rmdir(lua_State *L); + + // cpdir(source, destination, remove_source) + static int l_cpdir(lua_State *L); + + // mvdir(source, destination) + static int l_mvdir(lua_State *L); + + // get_dir_list(path, is_dir) + static int l_get_dir_list(lua_State *L); + + // safe_file_write(path, content) + static int l_safe_file_write(lua_State *L); + + // request_insecure_environment() + static int l_request_insecure_environment(lua_State *L); + + // encode_base64(string) + static int l_encode_base64(lua_State *L); + + // decode_base64(string) + static int l_decode_base64(lua_State *L); + + // get_version() + static int l_get_version(lua_State *L); + + // sha1(string, raw) + static int l_sha1(lua_State *L); + + // colorspec_to_colorstring(colorspec) + static int l_colorspec_to_colorstring(lua_State *L); + + // colorspec_to_bytes(colorspec) + static int l_colorspec_to_bytes(lua_State *L); + + // encode_png(w, h, data, level) + static int l_encode_png(lua_State *L); + + // get_last_run_mod() + static int l_get_last_run_mod(lua_State *L); + + // set_last_run_mod(modname) + static int l_set_last_run_mod(lua_State *L); + +public: + static void Initialize(lua_State *L, int top); + static void InitializeAsync(lua_State *L, int top); + static void InitializeClient(lua_State *L, int top); +}; diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp new file mode 100644 index 0000000..6187a47 --- /dev/null +++ b/src/script/lua_api/l_vmanip.cpp @@ -0,0 +1,512 @@ +/* +Minetest +Copyright (C) 2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <map> +#include "lua_api/l_vmanip.h" +#include "lua_api/l_internal.h" +#include "common/c_content.h" +#include "common/c_converter.h" +#include "common/c_packer.h" +#include "emerge.h" +#include "environment.h" +#include "map.h" +#include "mapblock.h" +#include "server.h" +#include "mapgen/mapgen.h" +#include "voxelalgorithms.h" + +// garbage collector +int LuaVoxelManip::gc_object(lua_State *L) +{ + LuaVoxelManip *o = *(LuaVoxelManip **)(lua_touserdata(L, 1)); + delete o; + + return 0; +} + +int LuaVoxelManip::l_read_from_map(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + if (vm->isOrphan()) + return 0; + + v3s16 bp1 = getNodeBlockPos(check_v3s16(L, 2)); + v3s16 bp2 = getNodeBlockPos(check_v3s16(L, 3)); + sortBoxVerticies(bp1, bp2); + + vm->initialEmerge(bp1, bp2); + + push_v3s16(L, vm->m_area.MinEdge); + push_v3s16(L, vm->m_area.MaxEdge); + + return 2; +} + +int LuaVoxelManip::l_get_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + bool use_buffer = lua_istable(L, 2); + + MMVManip *vm = o->vm; + + u32 volume = vm->m_area.getVolume(); + + if (use_buffer) + lua_pushvalue(L, 2); + else + lua_createtable(L, volume, 0); + + for (u32 i = 0; i != volume; i++) { + lua_Integer cid = vm->m_data[i].getContent(); + lua_pushinteger(L, cid); + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +int LuaVoxelManip::l_set_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + + if (!lua_istable(L, 2)) + throw LuaError("VoxelManip:set_data called with missing parameter"); + + u32 volume = vm->m_area.getVolume(); + for (u32 i = 0; i != volume; i++) { + lua_rawgeti(L, 2, i + 1); + content_t c = lua_tointeger(L, -1); + + vm->m_data[i].setContent(c); + + lua_pop(L, 1); + } + + return 0; +} + +int LuaVoxelManip::l_write_to_map(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + bool update_light = !lua_isboolean(L, 2) || readParam<bool>(L, 2); + + GET_ENV_PTR; + ServerMap *map = &(env->getServerMap()); + + std::map<v3s16, MapBlock*> modified_blocks; + if (o->is_mapgen_vm || !update_light) { + o->vm->blitBackAll(&modified_blocks); + } else { + voxalgo::blit_back_with_light(map, o->vm, &modified_blocks); + } + + MapEditEvent event; + event.type = MEET_OTHER; + for (const auto &it : modified_blocks) + event.modified_blocks.insert(it.first); + map->dispatchEvent(event); + + return 0; +} + +int LuaVoxelManip::l_get_node_at(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); + + LuaVoxelManip *o = checkobject(L, 1); + v3s16 pos = check_v3s16(L, 2); + + pushnode(L, o->vm->getNodeNoExNoEmerge(pos), ndef); + return 1; +} + +int LuaVoxelManip::l_set_node_at(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); + + LuaVoxelManip *o = checkobject(L, 1); + v3s16 pos = check_v3s16(L, 2); + MapNode n = readnode(L, 3, ndef); + + o->vm->setNodeNoEmerge(pos, n); + + return 0; +} + +int LuaVoxelManip::l_update_liquids(lua_State *L) +{ + GET_ENV_PTR; + + LuaVoxelManip *o = checkobject(L, 1); + + ServerMap *map = &(env->getServerMap()); + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); + MMVManip *vm = o->vm; + + Mapgen mg; + mg.vm = vm; + mg.ndef = ndef; + + mg.updateLiquid(&map->m_transforming_liquid, + vm->m_area.MinEdge, vm->m_area.MaxEdge); + + return 0; +} + +int LuaVoxelManip::l_calc_lighting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + if (!o->is_mapgen_vm) { + warningstream << "VoxelManip:calc_lighting called for a non-mapgen " + "VoxelManip object" << std::endl; + return 0; + } + + const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); + EmergeManager *emerge = getServer(L)->getEmergeManager(); + MMVManip *vm = o->vm; + + v3s16 yblock = v3s16(0, 1, 0) * MAP_BLOCKSIZE; + v3s16 fpmin = vm->m_area.MinEdge; + v3s16 fpmax = vm->m_area.MaxEdge; + v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) : fpmin + yblock; + v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) : fpmax - yblock; + bool propagate_shadow = !lua_isboolean(L, 4) || readParam<bool>(L, 4); + + sortBoxVerticies(pmin, pmax); + if (!vm->m_area.contains(VoxelArea(pmin, pmax))) + throw LuaError("Specified voxel area out of VoxelManipulator bounds"); + + Mapgen mg; + mg.vm = vm; + mg.ndef = ndef; + mg.water_level = emerge->mgparams->water_level; + + mg.calcLighting(pmin, pmax, fpmin, fpmax, propagate_shadow); + + return 0; +} + +int LuaVoxelManip::l_set_lighting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + if (!o->is_mapgen_vm) { + warningstream << "VoxelManip:set_lighting called for a non-mapgen " + "VoxelManip object" << std::endl; + return 0; + } + + if (!lua_istable(L, 2)) + throw LuaError("VoxelManip:set_lighting called with missing parameter"); + + u8 light; + light = (getintfield_default(L, 2, "day", 0) & 0x0F); + light |= (getintfield_default(L, 2, "night", 0) & 0x0F) << 4; + + MMVManip *vm = o->vm; + + v3s16 yblock = v3s16(0, 1, 0) * MAP_BLOCKSIZE; + v3s16 pmin = lua_istable(L, 3) ? check_v3s16(L, 3) : vm->m_area.MinEdge + yblock; + v3s16 pmax = lua_istable(L, 4) ? check_v3s16(L, 4) : vm->m_area.MaxEdge - yblock; + + sortBoxVerticies(pmin, pmax); + if (!vm->m_area.contains(VoxelArea(pmin, pmax))) + throw LuaError("Specified voxel area out of VoxelManipulator bounds"); + + Mapgen mg; + mg.vm = vm; + + mg.setLighting(light, pmin, pmax); + + return 0; +} + +int LuaVoxelManip::l_get_light_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + + u32 volume = vm->m_area.getVolume(); + + lua_createtable(L, volume, 0); + for (u32 i = 0; i != volume; i++) { + lua_Integer light = vm->m_data[i].param1; + lua_pushinteger(L, light); + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +int LuaVoxelManip::l_set_light_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + + if (!lua_istable(L, 2)) + throw LuaError("VoxelManip:set_light_data called with missing " + "parameter"); + + u32 volume = vm->m_area.getVolume(); + for (u32 i = 0; i != volume; i++) { + lua_rawgeti(L, 2, i + 1); + u8 light = lua_tointeger(L, -1); + + vm->m_data[i].param1 = light; + + lua_pop(L, 1); + } + + return 0; +} + +int LuaVoxelManip::l_get_param2_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + bool use_buffer = lua_istable(L, 2); + + MMVManip *vm = o->vm; + + u32 volume = vm->m_area.getVolume(); + + if (use_buffer) + lua_pushvalue(L, 2); + else + lua_createtable(L, volume, 0); + + for (u32 i = 0; i != volume; i++) { + lua_Integer param2 = vm->m_data[i].param2; + lua_pushinteger(L, param2); + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +int LuaVoxelManip::l_set_param2_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + + if (!lua_istable(L, 2)) + throw LuaError("VoxelManip:set_param2_data called with missing " + "parameter"); + + u32 volume = vm->m_area.getVolume(); + for (u32 i = 0; i != volume; i++) { + lua_rawgeti(L, 2, i + 1); + u8 param2 = lua_tointeger(L, -1); + + vm->m_data[i].param2 = param2; + + lua_pop(L, 1); + } + + return 0; +} + +int LuaVoxelManip::l_update_map(lua_State *L) +{ + return 0; +} + +int LuaVoxelManip::l_was_modified(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + + lua_pushboolean(L, vm->m_is_dirty); + + return 1; +} + +int LuaVoxelManip::l_get_emerged_area(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + + push_v3s16(L, o->vm->m_area.MinEdge); + push_v3s16(L, o->vm->m_area.MaxEdge); + + return 2; +} + +LuaVoxelManip::LuaVoxelManip(MMVManip *mmvm, bool is_mg_vm) : + is_mapgen_vm(is_mg_vm), + vm(mmvm) +{ +} + +LuaVoxelManip::LuaVoxelManip(Map *map) : vm(new MMVManip(map)) +{ +} + +LuaVoxelManip::LuaVoxelManip(Map *map, v3s16 p1, v3s16 p2) +{ + vm = new MMVManip(map); + + v3s16 bp1 = getNodeBlockPos(p1); + v3s16 bp2 = getNodeBlockPos(p2); + sortBoxVerticies(bp1, bp2); + vm->initialEmerge(bp1, bp2); +} + +LuaVoxelManip::~LuaVoxelManip() +{ + if (!is_mapgen_vm) + delete vm; +} + +// LuaVoxelManip() +// Creates an LuaVoxelManip and leaves it on top of stack +int LuaVoxelManip::create_object(lua_State *L) +{ + GET_ENV_PTR; + + Map *map = &(env->getMap()); + LuaVoxelManip *o = (lua_istable(L, 1) && lua_istable(L, 2)) ? + new LuaVoxelManip(map, check_v3s16(L, 1), check_v3s16(L, 2)) : + new LuaVoxelManip(map); + + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + +LuaVoxelManip *LuaVoxelManip::checkobject(lua_State *L, int narg) +{ + NO_MAP_LOCK_REQUIRED; + + luaL_checktype(L, narg, LUA_TUSERDATA); + + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + + return *(LuaVoxelManip **)ud; // unbox pointer +} + +void *LuaVoxelManip::packIn(lua_State *L, int idx) +{ + LuaVoxelManip *o = checkobject(L, idx); + + if (o->is_mapgen_vm) + throw LuaError("nope"); + return o->vm->clone(); +} + +void LuaVoxelManip::packOut(lua_State *L, void *ptr) +{ + MMVManip *vm = reinterpret_cast<MMVManip*>(ptr); + if (!L) { + delete vm; + return; + } + + // Associate vmanip with map if the Lua env has one + Environment *env = getEnv(L); + if (env) + vm->reparent(&(env->getMap())); + + LuaVoxelManip *o = new LuaVoxelManip(vm, false); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +void LuaVoxelManip::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); // drop metatable + + luaL_register(L, nullptr, methods); // fill methodtable + lua_pop(L, 1); // drop methodtable + + // Can be created from Lua (VoxelManip()) + lua_register(L, className, create_object); + + script_register_packer(L, className, packIn, packOut); +} + +const char LuaVoxelManip::className[] = "VoxelManip"; +const luaL_Reg LuaVoxelManip::methods[] = { + luamethod(LuaVoxelManip, read_from_map), + luamethod(LuaVoxelManip, get_data), + luamethod(LuaVoxelManip, set_data), + luamethod(LuaVoxelManip, get_node_at), + luamethod(LuaVoxelManip, set_node_at), + luamethod(LuaVoxelManip, write_to_map), + luamethod(LuaVoxelManip, update_map), + luamethod(LuaVoxelManip, update_liquids), + luamethod(LuaVoxelManip, calc_lighting), + luamethod(LuaVoxelManip, set_lighting), + luamethod(LuaVoxelManip, get_light_data), + luamethod(LuaVoxelManip, set_light_data), + luamethod(LuaVoxelManip, get_param2_data), + luamethod(LuaVoxelManip, set_param2_data), + luamethod(LuaVoxelManip, was_modified), + luamethod(LuaVoxelManip, get_emerged_area), + {0,0} +}; diff --git a/src/script/lua_api/l_vmanip.h b/src/script/lua_api/l_vmanip.h new file mode 100644 index 0000000..0051333 --- /dev/null +++ b/src/script/lua_api/l_vmanip.h @@ -0,0 +1,82 @@ +/* +Minetest +Copyright (C) 2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_v3d.h" +#include "lua_api/l_base.h" + +class Map; +class MapBlock; +class MMVManip; + +/* + VoxelManip + */ +class LuaVoxelManip : public ModApiBase +{ +private: + bool is_mapgen_vm = false; + + static const char className[]; + static const luaL_Reg methods[]; + + static int gc_object(lua_State *L); + + static int l_read_from_map(lua_State *L); + static int l_get_data(lua_State *L); + static int l_set_data(lua_State *L); + static int l_write_to_map(lua_State *L); + + static int l_get_node_at(lua_State *L); + static int l_set_node_at(lua_State *L); + + static int l_update_map(lua_State *L); + static int l_update_liquids(lua_State *L); + + static int l_calc_lighting(lua_State *L); + static int l_set_lighting(lua_State *L); + static int l_get_light_data(lua_State *L); + static int l_set_light_data(lua_State *L); + + static int l_get_param2_data(lua_State *L); + static int l_set_param2_data(lua_State *L); + + static int l_was_modified(lua_State *L); + static int l_get_emerged_area(lua_State *L); + +public: + MMVManip *vm = nullptr; + + LuaVoxelManip(MMVManip *mmvm, bool is_mapgen_vm); + LuaVoxelManip(Map *map, v3s16 p1, v3s16 p2); + LuaVoxelManip(Map *map); + ~LuaVoxelManip(); + + // LuaVoxelManip() + // Creates a LuaVoxelManip and leaves it on top of stack + static int create_object(lua_State *L); + + static LuaVoxelManip *checkobject(lua_State *L, int narg); + + static void *packIn(lua_State *L, int idx); + static void packOut(lua_State *L, void *ptr); + + static void Register(lua_State *L); +}; diff --git a/src/script/scripting_client.cpp b/src/script/scripting_client.cpp new file mode 100644 index 0000000..3772053 --- /dev/null +++ b/src/script/scripting_client.cpp @@ -0,0 +1,100 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "scripting_client.h" +#include "client/client.h" +#include "cpp_api/s_internal.h" +#include "lua_api/l_client.h" +#include "lua_api/l_env.h" +#include "lua_api/l_item.h" +#include "lua_api/l_itemstackmeta.h" +#include "lua_api/l_minimap.h" +#include "lua_api/l_modchannels.h" +#include "lua_api/l_particles_local.h" +#include "lua_api/l_storage.h" +#include "lua_api/l_sound.h" +#include "lua_api/l_util.h" +#include "lua_api/l_item.h" +#include "lua_api/l_nodemeta.h" +#include "lua_api/l_localplayer.h" +#include "lua_api/l_camera.h" +#include "lua_api/l_settings.h" + +ClientScripting::ClientScripting(Client *client): + ScriptApiBase(ScriptingType::Client) +{ + setGameDef(client); + + SCRIPTAPI_PRECHECKHEADER + + // Security is mandatory client side + initializeSecurityClient(); + + lua_getglobal(L, "core"); + int top = lua_gettop(L); + + lua_newtable(L); + lua_setfield(L, -2, "ui"); + + InitializeModApi(L, top); + lua_pop(L, 1); + + // Push builtin initialization type + lua_pushstring(L, "client"); + lua_setglobal(L, "INIT"); + + infostream << "SCRIPTAPI: Initialized client game modules" << std::endl; +} + +void ClientScripting::InitializeModApi(lua_State *L, int top) +{ + LuaItemStack::Register(L); + ItemStackMetaRef::Register(L); + LuaRaycast::Register(L); + StorageRef::Register(L); + LuaMinimap::Register(L); + NodeMetaRef::RegisterClient(L); + LuaLocalPlayer::Register(L); + LuaCamera::Register(L); + ModChannelRef::Register(L); + LuaSettings::Register(L); + + ModApiUtil::InitializeClient(L, top); + ModApiClient::Initialize(L, top); + ModApiStorage::Initialize(L, top); + ModApiEnvMod::InitializeClient(L, top); + ModApiChannels::Initialize(L, top); + ModApiParticlesLocal::Initialize(L, top); +} + +void ClientScripting::on_client_ready(LocalPlayer *localplayer) +{ + LuaLocalPlayer::create(getStack(), localplayer); +} + +void ClientScripting::on_camera_ready(Camera *camera) +{ + LuaCamera::create(getStack(), camera); +} + +void ClientScripting::on_minimap_ready(Minimap *minimap) +{ + LuaMinimap::create(getStack(), minimap); +} diff --git a/src/script/scripting_client.h b/src/script/scripting_client.h new file mode 100644 index 0000000..3088029 --- /dev/null +++ b/src/script/scripting_client.h @@ -0,0 +1,47 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" +#include "cpp_api/s_client.h" +#include "cpp_api/s_modchannels.h" +#include "cpp_api/s_security.h" + +class Client; +class LocalPlayer; +class Camera; +class Minimap; + +class ClientScripting: + virtual public ScriptApiBase, + public ScriptApiSecurity, + public ScriptApiClient, + public ScriptApiModChannels +{ +public: + ClientScripting(Client *client); + void on_client_ready(LocalPlayer *localplayer); + void on_camera_ready(Camera *camera); + void on_minimap_ready(Minimap *minimap); + +private: + virtual void InitializeModApi(lua_State *L, int top); +}; diff --git a/src/script/scripting_mainmenu.cpp b/src/script/scripting_mainmenu.cpp new file mode 100644 index 0000000..2a0cadb --- /dev/null +++ b/src/script/scripting_mainmenu.cpp @@ -0,0 +1,100 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "scripting_mainmenu.h" +#include "content/mods.h" +#include "cpp_api/s_internal.h" +#include "lua_api/l_base.h" +#include "lua_api/l_http.h" +#include "lua_api/l_mainmenu.h" +#include "lua_api/l_sound.h" +#include "lua_api/l_util.h" +#include "lua_api/l_settings.h" +#include "log.h" + +extern "C" { +#include "lualib.h" +} +#define MAINMENU_NUM_ASYNC_THREADS 4 + + +MainMenuScripting::MainMenuScripting(GUIEngine* guiengine): + ScriptApiBase(ScriptingType::MainMenu) +{ + setGuiEngine(guiengine); + + SCRIPTAPI_PRECHECKHEADER + + lua_getglobal(L, "core"); + int top = lua_gettop(L); + + lua_newtable(L); + lua_setglobal(L, "gamedata"); + + // Initialize our lua_api modules + initializeModApi(L, top); + lua_pop(L, 1); + + // Push builtin initialization type + lua_pushstring(L, "mainmenu"); + lua_setglobal(L, "INIT"); + + infostream << "SCRIPTAPI: Initialized main menu modules" << std::endl; +} + +/******************************************************************************/ +void MainMenuScripting::initializeModApi(lua_State *L, int top) +{ + registerLuaClasses(L, top); + + // Initialize mod API modules + ModApiMainMenu::Initialize(L, top); + ModApiUtil::Initialize(L, top); + ModApiSound::Initialize(L, top); + ModApiHttp::Initialize(L, top); + + asyncEngine.registerStateInitializer(registerLuaClasses); + asyncEngine.registerStateInitializer(ModApiMainMenu::InitializeAsync); + asyncEngine.registerStateInitializer(ModApiUtil::InitializeAsync); + asyncEngine.registerStateInitializer(ModApiHttp::InitializeAsync); + + // Initialize async environment + //TODO possibly make number of async threads configurable + asyncEngine.initialize(MAINMENU_NUM_ASYNC_THREADS); +} + +/******************************************************************************/ +void MainMenuScripting::registerLuaClasses(lua_State *L, int top) +{ + LuaSettings::Register(L); +} + +/******************************************************************************/ +void MainMenuScripting::step() +{ + asyncEngine.step(getStack()); +} + +/******************************************************************************/ +u32 MainMenuScripting::queueAsync(std::string &&serialized_func, + std::string &&serialized_param) +{ + return asyncEngine.queueAsyncJob(std::move(serialized_func), std::move(serialized_param)); +} + diff --git a/src/script/scripting_mainmenu.h b/src/script/scripting_mainmenu.h new file mode 100644 index 0000000..3c32965 --- /dev/null +++ b/src/script/scripting_mainmenu.h @@ -0,0 +1,49 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "cpp_api/s_base.h" +#include "cpp_api/s_mainmenu.h" +#include "cpp_api/s_async.h" + +/*****************************************************************************/ +/* Scripting <-> Main Menu Interface */ +/*****************************************************************************/ + +class MainMenuScripting + : virtual public ScriptApiBase, + public ScriptApiMainMenu +{ +public: + MainMenuScripting(GUIEngine* guiengine); + + // Global step handler to pass back async events + void step(); + + // Pass async events from engine to async threads + u32 queueAsync(std::string &&serialized_func, + std::string &&serialized_param); + +private: + void initializeModApi(lua_State *L, int top); + static void registerLuaClasses(lua_State *L, int top); + + AsyncEngine asyncEngine; +}; diff --git a/src/script/scripting_server.cpp b/src/script/scripting_server.cpp new file mode 100644 index 0000000..b462141 --- /dev/null +++ b/src/script/scripting_server.cpp @@ -0,0 +1,191 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "scripting_server.h" +#include "server.h" +#include "log.h" +#include "settings.h" +#include "cpp_api/s_internal.h" +#include "lua_api/l_areastore.h" +#include "lua_api/l_auth.h" +#include "lua_api/l_base.h" +#include "lua_api/l_craft.h" +#include "lua_api/l_env.h" +#include "lua_api/l_inventory.h" +#include "lua_api/l_item.h" +#include "lua_api/l_itemstackmeta.h" +#include "lua_api/l_mapgen.h" +#include "lua_api/l_modchannels.h" +#include "lua_api/l_nodemeta.h" +#include "lua_api/l_nodetimer.h" +#include "lua_api/l_noise.h" +#include "lua_api/l_object.h" +#include "lua_api/l_playermeta.h" +#include "lua_api/l_particles.h" +#include "lua_api/l_rollback.h" +#include "lua_api/l_server.h" +#include "lua_api/l_util.h" +#include "lua_api/l_vmanip.h" +#include "lua_api/l_settings.h" +#include "lua_api/l_http.h" +#include "lua_api/l_storage.h" + +extern "C" { +#include <lualib.h> +} + +ServerScripting::ServerScripting(Server* server): + ScriptApiBase(ScriptingType::Server), + asyncEngine(server) +{ + setGameDef(server); + + // setEnv(env) is called by ScriptApiEnv::initializeEnvironment() + // once the environment has been created + + SCRIPTAPI_PRECHECKHEADER + + if (g_settings->getBool("secure.enable_security")) { + initializeSecurity(); + } else { + warningstream << "\\!/ Mod security should never be disabled, as it allows any mod to " + << "access the host machine." + << "Mods should use minetest.request_insecure_environment() instead \\!/" << std::endl; + } + + lua_getglobal(L, "core"); + int top = lua_gettop(L); + + lua_newtable(L); + lua_setfield(L, -2, "object_refs"); + + lua_newtable(L); + lua_setfield(L, -2, "luaentities"); + + // Initialize our lua_api modules + InitializeModApi(L, top); + lua_pop(L, 1); + + // Push builtin initialization type + lua_pushstring(L, "game"); + lua_setglobal(L, "INIT"); + + infostream << "SCRIPTAPI: Initialized game modules" << std::endl; +} + +void ServerScripting::initAsync() +{ + // Save globals to transfer + { + lua_State *L = getStack(); + lua_getglobal(L, "core"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, "get_globals_to_transfer"); + lua_call(L, 0, 1); + auto *data = script_pack(L, -1); + assert(!data->contains_userdata); + getServer()->m_async_globals_data.reset(data); + lua_pushnil(L); + lua_setfield(L, -3, "get_globals_to_transfer"); // unset function too + lua_pop(L, 2); // pop 'core', return value + } + + infostream << "SCRIPTAPI: Initializing async engine" << std::endl; + asyncEngine.registerStateInitializer(InitializeAsync); + asyncEngine.registerStateInitializer(ModApiUtil::InitializeAsync); + asyncEngine.registerStateInitializer(ModApiCraft::InitializeAsync); + asyncEngine.registerStateInitializer(ModApiItemMod::InitializeAsync); + asyncEngine.registerStateInitializer(ModApiServer::InitializeAsync); + // not added: ModApiMapgen is a minefield for thread safety + // not added: ModApiHttp async api can't really work together with our jobs + // not added: ModApiStorage is probably not thread safe(?) + + asyncEngine.initialize(0); +} + +void ServerScripting::stepAsync() +{ + asyncEngine.step(getStack()); +} + +u32 ServerScripting::queueAsync(std::string &&serialized_func, + PackedValue *param, const std::string &mod_origin) +{ + return asyncEngine.queueAsyncJob(std::move(serialized_func), + param, mod_origin); +} + +void ServerScripting::InitializeModApi(lua_State *L, int top) +{ + // Register reference classes (userdata) + InvRef::Register(L); + ItemStackMetaRef::Register(L); + LuaAreaStore::Register(L); + LuaItemStack::Register(L); + LuaPerlinNoise::Register(L); + LuaPerlinNoiseMap::Register(L); + LuaPseudoRandom::Register(L); + LuaPcgRandom::Register(L); + LuaRaycast::Register(L); + LuaSecureRandom::Register(L); + LuaVoxelManip::Register(L); + NodeMetaRef::Register(L); + NodeTimerRef::Register(L); + ObjectRef::Register(L); + PlayerMetaRef::Register(L); + LuaSettings::Register(L); + StorageRef::Register(L); + ModChannelRef::Register(L); + + // Initialize mod api modules + ModApiAuth::Initialize(L, top); + ModApiCraft::Initialize(L, top); + ModApiEnvMod::Initialize(L, top); + ModApiInventory::Initialize(L, top); + ModApiItemMod::Initialize(L, top); + ModApiMapgen::Initialize(L, top); + ModApiParticles::Initialize(L, top); + ModApiRollback::Initialize(L, top); + ModApiServer::Initialize(L, top); + ModApiUtil::Initialize(L, top); + ModApiHttp::Initialize(L, top); + ModApiStorage::Initialize(L, top); + ModApiChannels::Initialize(L, top); +} + +void ServerScripting::InitializeAsync(lua_State *L, int top) +{ + // classes + LuaItemStack::Register(L); + LuaPerlinNoise::Register(L); + LuaPerlinNoiseMap::Register(L); + LuaPseudoRandom::Register(L); + LuaPcgRandom::Register(L); + LuaSecureRandom::Register(L); + LuaVoxelManip::Register(L); + LuaSettings::Register(L); + + // globals data + lua_getglobal(L, "core"); + luaL_checktype(L, -1, LUA_TTABLE); + auto *data = ModApiBase::getServer(L)->m_async_globals_data.get(); + script_unpack(L, data); + lua_setfield(L, -2, "transferred_globals"); + lua_pop(L, 1); // pop 'core' +} diff --git a/src/script/scripting_server.h b/src/script/scripting_server.h new file mode 100644 index 0000000..9803397 --- /dev/null +++ b/src/script/scripting_server.h @@ -0,0 +1,70 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include "cpp_api/s_base.h" +#include "cpp_api/s_entity.h" +#include "cpp_api/s_env.h" +#include "cpp_api/s_inventory.h" +#include "cpp_api/s_modchannels.h" +#include "cpp_api/s_node.h" +#include "cpp_api/s_player.h" +#include "cpp_api/s_server.h" +#include "cpp_api/s_security.h" +#include "cpp_api/s_async.h" + +struct PackedValue; + +/*****************************************************************************/ +/* Scripting <-> Server Game Interface */ +/*****************************************************************************/ + +class ServerScripting: + virtual public ScriptApiBase, + public ScriptApiDetached, + public ScriptApiEntity, + public ScriptApiEnv, + public ScriptApiModChannels, + public ScriptApiNode, + public ScriptApiPlayer, + public ScriptApiServer, + public ScriptApiSecurity +{ +public: + ServerScripting(Server* server); + + // use ScriptApiBase::loadMod() to load mods + + // Initialize async engine, call this AFTER loading all mods + void initAsync(); + + // Global step handler to collect async results + void stepAsync(); + + // Pass job to async threads + u32 queueAsync(std::string &&serialized_func, + PackedValue *param, const std::string &mod_origin); + +private: + void InitializeModApi(lua_State *L, int top); + + static void InitializeAsync(lua_State *L, int top); + + AsyncEngine asyncEngine; +}; diff --git a/src/serialization.cpp b/src/serialization.cpp new file mode 100644 index 0000000..dc34dd7 --- /dev/null +++ b/src/serialization.cpp @@ -0,0 +1,402 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "serialization.h" + +#include "util/serialize.h" + +#include <zlib.h> +#include <zstd.h> + +/* report a zlib or i/o error */ +static void zerr(int ret) +{ + dstream<<"zerr: "; + switch (ret) { + case Z_ERRNO: + if (ferror(stdin)) + dstream<<"error reading stdin"<<std::endl; + if (ferror(stdout)) + dstream<<"error writing stdout"<<std::endl; + break; + case Z_STREAM_ERROR: + dstream<<"invalid compression level"<<std::endl; + break; + case Z_DATA_ERROR: + dstream<<"invalid or incomplete deflate data"<<std::endl; + break; + case Z_MEM_ERROR: + dstream<<"out of memory"<<std::endl; + break; + case Z_VERSION_ERROR: + dstream<<"zlib version mismatch!"<<std::endl; + break; + default: + dstream<<"return value = "<<ret<<std::endl; + } +} + +// Make sure that z is deleted in case of exception +template <int (*F)(z_stream*)> +class ZlibAutoDeleter { +public: + ZlibAutoDeleter(z_stream *ptr) : ptr_(ptr) {} + ~ZlibAutoDeleter() { F(ptr_); } + +private: + z_stream *ptr_; +}; + +void compressZlib(const u8 *data, size_t data_size, std::ostream &os, int level) +{ + z_stream z; + const s32 bufsize = 16384; + char output_buffer[bufsize]; + int status = 0; + int ret; + + z.zalloc = Z_NULL; + z.zfree = Z_NULL; + z.opaque = Z_NULL; + + ret = deflateInit(&z, level); + if(ret != Z_OK) + throw SerializationError("compressZlib: deflateInit failed"); + + ZlibAutoDeleter<deflateEnd> deleter(&z); + + // Point zlib to our input buffer + z.next_in = (Bytef*)&data[0]; + z.avail_in = data_size; + // And get all output + for(;;) + { + z.next_out = (Bytef*)output_buffer; + z.avail_out = bufsize; + + status = deflate(&z, Z_FINISH); + if(status == Z_NEED_DICT || status == Z_DATA_ERROR + || status == Z_MEM_ERROR) + { + zerr(status); + throw SerializationError("compressZlib: deflate failed"); + } + int count = bufsize - z.avail_out; + if(count) + os.write(output_buffer, count); + // This determines zlib has given all output + if(status == Z_STREAM_END) + break; + } +} + +void compressZlib(const std::string &data, std::ostream &os, int level) +{ + compressZlib((u8*)data.c_str(), data.size(), os, level); +} + +void decompressZlib(std::istream &is, std::ostream &os, size_t limit) +{ + z_stream z; + const s32 bufsize = 16384; + char input_buffer[bufsize]; + char output_buffer[bufsize]; + int status = 0; + int ret; + int bytes_written = 0; + int input_buffer_len = 0; + + z.zalloc = Z_NULL; + z.zfree = Z_NULL; + z.opaque = Z_NULL; + + ret = inflateInit(&z); + if(ret != Z_OK) + throw SerializationError("dcompressZlib: inflateInit failed"); + + ZlibAutoDeleter<inflateEnd> deleter(&z); + + z.avail_in = 0; + + for(;;) + { + int output_size = bufsize; + z.next_out = (Bytef*)output_buffer; + z.avail_out = output_size; + + if (limit) { + int limit_remaining = limit - bytes_written; + if (limit_remaining <= 0) { + // we're aborting ahead of time - throw an error? + break; + } + if (limit_remaining < output_size) { + z.avail_out = output_size = limit_remaining; + } + } + + if(z.avail_in == 0) + { + z.next_in = (Bytef*)input_buffer; + is.read(input_buffer, bufsize); + input_buffer_len = is.gcount(); + z.avail_in = input_buffer_len; + } + if(z.avail_in == 0) + { + break; + } + + status = inflate(&z, Z_NO_FLUSH); + + if(status == Z_NEED_DICT || status == Z_DATA_ERROR + || status == Z_MEM_ERROR) + { + zerr(status); + throw SerializationError("decompressZlib: inflate failed"); + } + int count = output_size - z.avail_out; + if(count) + os.write(output_buffer, count); + bytes_written += count; + if(status == Z_STREAM_END) + { + // Unget all the data that inflate didn't take + is.clear(); // Just in case EOF is set + for(u32 i=0; i < z.avail_in; i++) + { + is.unget(); + if(is.fail() || is.bad()) + { + dstream<<"unget #"<<i<<" failed"<<std::endl; + dstream<<"fail="<<is.fail()<<" bad="<<is.bad()<<std::endl; + throw SerializationError("decompressZlib: unget failed"); + } + } + + break; + } + } +} + +struct ZSTD_Deleter { + void operator() (ZSTD_CStream* cstream) { + ZSTD_freeCStream(cstream); + } + + void operator() (ZSTD_DStream* dstream) { + ZSTD_freeDStream(dstream); + } +}; + +void compressZstd(const u8 *data, size_t data_size, std::ostream &os, int level) +{ + // reusing the context is recommended for performance + // it will be destroyed when the thread ends + thread_local std::unique_ptr<ZSTD_CStream, ZSTD_Deleter> stream(ZSTD_createCStream()); + + + ZSTD_initCStream(stream.get(), level); + + const size_t bufsize = 16384; + char output_buffer[bufsize]; + + ZSTD_inBuffer input = { data, data_size, 0 }; + ZSTD_outBuffer output = { output_buffer, bufsize, 0 }; + + while (input.pos < input.size) { + size_t ret = ZSTD_compressStream(stream.get(), &output, &input); + if (ZSTD_isError(ret)) { + dstream << ZSTD_getErrorName(ret) << std::endl; + throw SerializationError("compressZstd: failed"); + } + if (output.pos) { + os.write(output_buffer, output.pos); + output.pos = 0; + } + } + + size_t ret; + do { + ret = ZSTD_endStream(stream.get(), &output); + if (ZSTD_isError(ret)) { + dstream << ZSTD_getErrorName(ret) << std::endl; + throw SerializationError("compressZstd: failed"); + } + if (output.pos) { + os.write(output_buffer, output.pos); + output.pos = 0; + } + } while (ret != 0); + +} + +void compressZstd(const std::string &data, std::ostream &os, int level) +{ + compressZstd((u8*)data.c_str(), data.size(), os, level); +} + +void decompressZstd(std::istream &is, std::ostream &os) +{ + // reusing the context is recommended for performance + // it will be destroyed when the thread ends + thread_local std::unique_ptr<ZSTD_DStream, ZSTD_Deleter> stream(ZSTD_createDStream()); + + ZSTD_initDStream(stream.get()); + + const size_t bufsize = 16384; + char output_buffer[bufsize]; + char input_buffer[bufsize]; + + ZSTD_outBuffer output = { output_buffer, bufsize, 0 }; + ZSTD_inBuffer input = { input_buffer, 0, 0 }; + size_t ret; + do + { + if (input.size == input.pos) { + is.read(input_buffer, bufsize); + input.size = is.gcount(); + input.pos = 0; + } + + ret = ZSTD_decompressStream(stream.get(), &output, &input); + if (ZSTD_isError(ret)) { + dstream << ZSTD_getErrorName(ret) << std::endl; + throw SerializationError("decompressZstd: failed"); + } + if (output.pos) { + os.write(output_buffer, output.pos); + output.pos = 0; + } + } while (ret != 0); + + // Unget all the data that ZSTD_decompressStream didn't take + is.clear(); // Just in case EOF is set + for (u32 i = 0; i < input.size - input.pos; i++) { + is.unget(); + if (is.fail() || is.bad()) + throw SerializationError("decompressZstd: unget failed"); + } +} + +void compress(u8 *data, u32 size, std::ostream &os, u8 version, int level) +{ + if(version >= 29) + { + // map the zlib levels [0,9] to [1,10]. -1 becomes 0 which indicates the default (currently 3) + compressZstd(data, size, os, level + 1); + return; + } + + if(version >= 11) + { + compressZlib(data, size, os, level); + return; + } + + if(size == 0) + return; + + // Write length (u32) + + u8 tmp[4]; + writeU32(tmp, size); + os.write((char*)tmp, 4); + + // We will be writing 8-bit pairs of more_count and byte + u8 more_count = 0; + u8 current_byte = data[0]; + for(u32 i=1; i<size; i++) + { + if( + data[i] != current_byte + || more_count == 255 + ) + { + // write count and byte + os.write((char*)&more_count, 1); + os.write((char*)¤t_byte, 1); + more_count = 0; + current_byte = data[i]; + } + else + { + more_count++; + } + } + // write count and byte + os.write((char*)&more_count, 1); + os.write((char*)¤t_byte, 1); +} + +void compress(const SharedBuffer<u8> &data, std::ostream &os, u8 version, int level) +{ + compress(*data, data.getSize(), os, version, level); +} + +void compress(const std::string &data, std::ostream &os, u8 version, int level) +{ + compress((u8*)data.c_str(), data.size(), os, version, level); +} + +void decompress(std::istream &is, std::ostream &os, u8 version) +{ + if(version >= 29) + { + decompressZstd(is, os); + return; + } + + if(version >= 11) + { + decompressZlib(is, os); + return; + } + + // Read length (u32) + + u8 tmp[4]; + is.read((char*)tmp, 4); + u32 len = readU32(tmp); + + // We will be reading 8-bit pairs of more_count and byte + u32 count = 0; + for(;;) + { + u8 more_count=0; + u8 byte=0; + + is.read((char*)&more_count, 1); + + is.read((char*)&byte, 1); + + if(is.eof()) + throw SerializationError("decompress: stream ended halfway"); + + for(s32 i=0; i<(u16)more_count+1; i++) + os.write((char*)&byte, 1); + + count += (u16)more_count+1; + + if(count == len) + break; + } +} + + diff --git a/src/serialization.h b/src/serialization.h new file mode 100644 index 0000000..e83a8c1 --- /dev/null +++ b/src/serialization.h @@ -0,0 +1,101 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "exceptions.h" +#include <iostream> +#include "util/pointer.h" + +/* + Map format serialization version + -------------------------------- + + For map data (blocks, nodes, sectors). + + NOTE: The goal is to increment this so that saved maps will be + loadable by any version. Other compatibility is not + maintained. + + 0: original networked test with 1-byte nodes + 1: update with 2-byte nodes + 2: lighting is transmitted in param + 3: optional fetching of far blocks + 4: block compression + 5: sector objects NOTE: block compression was left accidentally out + 6: failed attempt at switching block compression on again + 7: block compression switched on again + 8: server-initiated block transfers and all kinds of stuff + 9: block objects + 10: water pressure + 11: zlib'd blocks, block flags + 12: UnlimitedHeightmap now uses interpolated areas + 13: Mapgen v2 + 14: NodeMetadata + 15: StaticObjects + 16: larger maximum size of node metadata, and compression + 17: MapBlocks contain timestamp + 18: new generator (not really necessary, but it's there) + 19: new content type handling + 20: many existing content types translated to extended ones + 21: dynamic content type allocation + 22: minerals removed, facedir & wallmounted changed + 23: new node metadata format + 24: 16-bit node ids and node timers (never released as stable) + 25: Improved node timer format + 26: Never written; read the same as 25 + 27: Added light spreading flags to blocks + 28: Added "private" flag to NodeMetadata + 29: Switched compression to zstd, a bit of reorganization +*/ +// This represents an uninitialized or invalid format +#define SER_FMT_VER_INVALID 255 +// Highest supported serialization version +#define SER_FMT_VER_HIGHEST_READ 29 +// Saved on disk version +#define SER_FMT_VER_HIGHEST_WRITE 29 +// Lowest supported serialization version +#define SER_FMT_VER_LOWEST_READ 0 +// Lowest serialization version for writing +// Can't do < 24 anymore; we have 16-bit dynamically allocated node IDs +// in memory; conversion just won't work in this direction. +#define SER_FMT_VER_LOWEST_WRITE 24 + +inline bool ser_ver_supported(s32 v) { + return v >= SER_FMT_VER_LOWEST_READ && v <= SER_FMT_VER_HIGHEST_READ; +} + +/* + Misc. serialization functions +*/ + +void compressZlib(const u8 *data, size_t data_size, std::ostream &os, int level = -1); +void compressZlib(const std::string &data, std::ostream &os, int level = -1); +void decompressZlib(std::istream &is, std::ostream &os, size_t limit = 0); + +void compressZstd(const u8 *data, size_t data_size, std::ostream &os, int level = 0); +void compressZstd(const std::string &data, std::ostream &os, int level = 0); +void decompressZstd(std::istream &is, std::ostream &os); + +// These choose between zlib and a self-made one according to version +void compress(const SharedBuffer<u8> &data, std::ostream &os, u8 version, int level = -1); +void compress(const std::string &data, std::ostream &os, u8 version, int level = -1); +void compress(u8 *data, u32 size, std::ostream &os, u8 version, int level = -1); +void decompress(std::istream &is, std::ostream &os, u8 version); diff --git a/src/server.cpp b/src/server.cpp new file mode 100644 index 0000000..93767da --- /dev/null +++ b/src/server.cpp @@ -0,0 +1,4147 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "server.h" +#include <iostream> +#include <queue> +#include <algorithm> +#include "network/connection.h" +#include "network/networkprotocol.h" +#include "network/serveropcodes.h" +#include "ban.h" +#include "environment.h" +#include "map.h" +#include "threading/mutex_auto_lock.h" +#include "constants.h" +#include "voxel.h" +#include "config.h" +#include "version.h" +#include "filesys.h" +#include "mapblock.h" +#include "server/serveractiveobject.h" +#include "settings.h" +#include "profiler.h" +#include "log.h" +#include "scripting_server.h" +#include "nodedef.h" +#include "itemdef.h" +#include "craftdef.h" +#include "emerge.h" +#include "mapgen/mapgen.h" +#include "mapgen/mg_biome.h" +#include "content_mapnode.h" +#include "content_nodemeta.h" +#include "content/mods.h" +#include "modchannels.h" +#include "serverlist.h" +#include "util/string.h" +#include "rollback.h" +#include "util/serialize.h" +#include "util/thread.h" +#include "defaultsettings.h" +#include "server/mods.h" +#include "util/base64.h" +#include "util/sha1.h" +#include "util/hex.h" +#include "database/database.h" +#include "chatmessage.h" +#include "chat_interface.h" +#include "remoteplayer.h" +#include "server/player_sao.h" +#include "server/serverinventorymgr.h" +#include "translation.h" +#include "database/database-sqlite3.h" +#include "database/database-files.h" +#include "database/database-dummy.h" +#include "gameparams.h" + +class ClientNotFoundException : public BaseException +{ +public: + ClientNotFoundException(const char *s): + BaseException(s) + {} +}; + +class ServerThread : public Thread +{ +public: + + ServerThread(Server *server): + Thread("Server"), + m_server(server) + {} + + void *run(); + +private: + Server *m_server; +}; + +void *ServerThread::run() +{ + BEGIN_DEBUG_EXCEPTION_HANDLER + + /* + * The real business of the server happens on the ServerThread. + * How this works: + * AsyncRunStep() runs an actual server step as soon as enough time has + * passed (dedicated_server_loop keeps track of that). + * Receive() blocks at least(!) 30ms waiting for a packet (so this loop + * doesn't busy wait) and will process any remaining packets. + */ + + try { + m_server->AsyncRunStep(true); + } catch (con::ConnectionBindFailed &e) { + m_server->setAsyncFatalError(e.what()); + } catch (LuaError &e) { + m_server->setAsyncFatalError(e); + } + + while (!stopRequested()) { + try { + m_server->AsyncRunStep(); + + m_server->Receive(); + + } catch (con::PeerNotFoundException &e) { + infostream<<"Server: PeerNotFoundException"<<std::endl; + } catch (ClientNotFoundException &e) { + } catch (con::ConnectionBindFailed &e) { + m_server->setAsyncFatalError(e.what()); + } catch (LuaError &e) { + m_server->setAsyncFatalError(e); + } + } + + END_DEBUG_EXCEPTION_HANDLER + + return nullptr; +} + +v3f ServerPlayingSound::getPos(ServerEnvironment *env, bool *pos_exists) const +{ + if (pos_exists) + *pos_exists = false; + + switch (type ){ + case SoundLocation::Local: + return v3f(0,0,0); + case SoundLocation::Position: + if (pos_exists) + *pos_exists = true; + return pos; + case SoundLocation::Object: + { + if (object == 0) + return v3f(0,0,0); + ServerActiveObject *sao = env->getActiveObject(object); + if (!sao) + return v3f(0,0,0); + if (pos_exists) + *pos_exists = true; + return sao->getBasePosition(); + } + } + + return v3f(0,0,0); +} + +void Server::ShutdownState::reset() +{ + m_timer = 0.0f; + message.clear(); + should_reconnect = false; + is_requested = false; +} + +void Server::ShutdownState::trigger(float delay, const std::string &msg, bool reconnect) +{ + m_timer = delay; + message = msg; + should_reconnect = reconnect; +} + +void Server::ShutdownState::tick(float dtime, Server *server) +{ + if (m_timer <= 0.0f) + return; + + // Timed shutdown + static const float shutdown_msg_times[] = + { + 1, 2, 3, 4, 5, 10, 20, 40, 60, 120, 180, 300, 600, 1200, 1800, 3600 + }; + + // Automated messages + if (m_timer < shutdown_msg_times[ARRLEN(shutdown_msg_times) - 1]) { + for (float t : shutdown_msg_times) { + // If shutdown timer matches an automessage, shot it + if (m_timer > t && m_timer - dtime < t) { + std::wstring periodicMsg = getShutdownTimerMessage(); + + infostream << wide_to_utf8(periodicMsg).c_str() << std::endl; + server->SendChatMessage(PEER_ID_INEXISTENT, periodicMsg); + break; + } + } + } + + m_timer -= dtime; + if (m_timer < 0.0f) { + m_timer = 0.0f; + is_requested = true; + } +} + +std::wstring Server::ShutdownState::getShutdownTimerMessage() const +{ + std::wstringstream ws; + ws << L"*** Server shutting down in " + << duration_to_string(myround(m_timer)).c_str() << "."; + return ws.str(); +} + +/* + Server +*/ + +Server::Server( + const std::string &path_world, + const SubgameSpec &gamespec, + bool simple_singleplayer_mode, + Address bind_addr, + bool dedicated, + ChatInterface *iface, + std::string *on_shutdown_errmsg + ): + m_bind_addr(bind_addr), + m_path_world(path_world), + m_gamespec(gamespec), + m_simple_singleplayer_mode(simple_singleplayer_mode), + m_dedicated(dedicated), + m_async_fatal_error(""), + m_con(std::make_shared<con::Connection>(PROTOCOL_ID, + 512, + CONNECTION_TIMEOUT, + m_bind_addr.isIPv6(), + this)), + m_itemdef(createItemDefManager()), + m_nodedef(createNodeDefManager()), + m_craftdef(createCraftDefManager()), + m_thread(new ServerThread(this)), + m_clients(m_con), + m_admin_chat(iface), + m_on_shutdown_errmsg(on_shutdown_errmsg), + m_modchannel_mgr(new ModChannelMgr()) +{ + if (m_path_world.empty()) + throw ServerError("Supplied empty world path"); + + if (!gamespec.isValid()) + throw ServerError("Supplied invalid gamespec"); + +#if USE_PROMETHEUS + m_metrics_backend = std::unique_ptr<MetricsBackend>(createPrometheusMetricsBackend()); +#else + m_metrics_backend = std::make_unique<MetricsBackend>(); +#endif + + m_uptime_counter = m_metrics_backend->addCounter("minetest_core_server_uptime", "Server uptime (in seconds)"); + m_player_gauge = m_metrics_backend->addGauge("minetest_core_player_number", "Number of connected players"); + + m_timeofday_gauge = m_metrics_backend->addGauge( + "minetest_core_timeofday", + "Time of day value"); + + m_lag_gauge = m_metrics_backend->addGauge( + "minetest_core_latency", + "Latency value (in seconds)"); + + + const std::string aom_types[] = {"reliable", "unreliable"}; + for (u32 i = 0; i < ARRLEN(aom_types); i++) { + std::string help_str("Number of active object messages generated ("); + help_str.append(aom_types[i]).append(")"); + m_aom_buffer_counter[i] = m_metrics_backend->addCounter( + "minetest_core_aom_generated_count", help_str, + {{"type", aom_types[i]}}); + } + + m_packet_recv_counter = m_metrics_backend->addCounter( + "minetest_core_server_packet_recv", + "Processable packets received"); + + m_packet_recv_processed_counter = m_metrics_backend->addCounter( + "minetest_core_server_packet_recv_processed", + "Valid received packets processed"); + + m_map_edit_event_counter = m_metrics_backend->addCounter( + "minetest_core_map_edit_events", + "Number of map edit events"); + + m_lag_gauge->set(g_settings->getFloat("dedicated_server_step")); +} + +Server::~Server() +{ + + // Send shutdown message + SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE, + L"*** Server shutting down")); + + if (m_env) { + MutexAutoLock envlock(m_env_mutex); + + infostream << "Server: Saving players" << std::endl; + m_env->saveLoadedPlayers(); + + infostream << "Server: Kicking players" << std::endl; + std::string kick_msg; + bool reconnect = false; + if (isShutdownRequested()) { + reconnect = m_shutdown_state.should_reconnect; + kick_msg = m_shutdown_state.message; + } + if (kick_msg.empty()) { + kick_msg = g_settings->get("kick_msg_shutdown"); + } + m_env->saveLoadedPlayers(true); + m_env->kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN, + kick_msg, reconnect); + } + + actionstream << "Server: Shutting down" << std::endl; + + // Do this before stopping the server in case mapgen callbacks need to access + // server-controlled resources (like ModStorages). Also do them before + // shutdown callbacks since they may modify state that is finalized in a + // callback. + if (m_emerge) + m_emerge->stopThreads(); + + if (m_env) { + MutexAutoLock envlock(m_env_mutex); + + // Execute script shutdown hooks + infostream << "Executing shutdown hooks" << std::endl; + try { + m_script->on_shutdown(); + } catch (ModError &e) { + errorstream << "ModError: " << e.what() << std::endl; + if (m_on_shutdown_errmsg) { + if (m_on_shutdown_errmsg->empty()) { + *m_on_shutdown_errmsg = std::string("ModError: ") + e.what(); + } else { + *m_on_shutdown_errmsg += std::string("\nModError: ") + e.what(); + } + } + } + + infostream << "Server: Saving environment metadata" << std::endl; + m_env->saveMeta(); + } + + // Stop threads + if (m_thread) { + stop(); + delete m_thread; + } + + // Write any changes before deletion. + if (m_mod_storage_database) + m_mod_storage_database->endSave(); + + // Delete things in the reverse order of creation + delete m_emerge; + delete m_env; + delete m_rollback; + delete m_mod_storage_database; + delete m_banmanager; + delete m_itemdef; + delete m_nodedef; + delete m_craftdef; + + // Deinitialize scripting + infostream << "Server: Deinitializing scripting" << std::endl; + delete m_script; + delete m_startup_server_map; // if available + delete m_game_settings; + + while (!m_unsent_map_edit_queue.empty()) { + delete m_unsent_map_edit_queue.front(); + m_unsent_map_edit_queue.pop(); + } +} + +void Server::init() +{ + infostream << "Server created for gameid \"" << m_gamespec.id << "\""; + if (m_simple_singleplayer_mode) + infostream << " in simple singleplayer mode" << std::endl; + else + infostream << std::endl; + infostream << "- world: " << m_path_world << std::endl; + infostream << "- game: " << m_gamespec.path << std::endl; + + m_game_settings = Settings::createLayer(SL_GAME); + + // Create world if it doesn't exist + try { + loadGameConfAndInitWorld(m_path_world, + fs::GetFilenameFromPath(m_path_world.c_str()), + m_gamespec, false); + } catch (const BaseException &e) { + throw ServerError(std::string("Failed to initialize world: ") + e.what()); + } + + // Create emerge manager + m_emerge = new EmergeManager(this, m_metrics_backend.get()); + + // Create ban manager + std::string ban_path = m_path_world + DIR_DELIM "ipban.txt"; + m_banmanager = new BanManager(ban_path); + + // Create mod storage database and begin a save for later + m_mod_storage_database = openModStorageDatabase(m_path_world); + m_mod_storage_database->beginSave(); + + m_modmgr = std::make_unique<ServerModManager>(m_path_world); + std::vector<ModSpec> unsatisfied_mods = m_modmgr->getUnsatisfiedMods(); + + // complain about mods with unsatisfied dependencies + if (!m_modmgr->isConsistent()) { + m_modmgr->printUnsatisfiedModsError(); + + warningstream + << "You have unsatisfied dependencies, loading your world anyway. " + << "This will become a fatal error in the future." << std::endl; + } + + //lock environment + MutexAutoLock envlock(m_env_mutex); + + // Create the Map (loads map_meta.txt, overriding configured mapgen params) + ServerMap *servermap = new ServerMap(m_path_world, this, m_emerge, m_metrics_backend.get()); + m_startup_server_map = servermap; + + // Initialize scripting + infostream << "Server: Initializing Lua" << std::endl; + + m_script = new ServerScripting(this); + + // Must be created before mod loading because we have some inventory creation + m_inventory_mgr = std::make_unique<ServerInventoryManager>(); + + m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME); + + m_gamespec.checkAndLog(); + m_modmgr->loadMods(m_script); + + // Read Textures and calculate sha1 sums + fillMediaCache(); + + // Apply item aliases in the node definition manager + m_nodedef->updateAliases(m_itemdef); + + // Apply texture overrides from texturepack/override.txt + std::vector<std::string> paths; + fs::GetRecursiveDirs(paths, g_settings->get("texture_path")); + fs::GetRecursiveDirs(paths, m_gamespec.path + DIR_DELIM + "textures"); + for (const std::string &path : paths) { + TextureOverrideSource override_source(path + DIR_DELIM + "override.txt"); + m_nodedef->applyTextureOverrides(override_source.getNodeTileOverrides()); + m_itemdef->applyTextureOverrides(override_source.getItemTextureOverrides()); + } + + m_nodedef->setNodeRegistrationStatus(true); + + // Perform pending node name resolutions + m_nodedef->runNodeResolveCallbacks(); + + // unmap node names in cross-references + m_nodedef->resolveCrossrefs(); + + // init the recipe hashes to speed up crafting + m_craftdef->initHashes(this); + + // Initialize Environment + m_startup_server_map = nullptr; // Ownership moved to ServerEnvironment + m_env = new ServerEnvironment(servermap, m_script, this, + m_path_world, m_metrics_backend.get()); + + m_inventory_mgr->setEnv(m_env); + m_clients.setEnv(m_env); + + if (!servermap->settings_mgr.makeMapgenParams()) + FATAL_ERROR("Couldn't create any mapgen type"); + + // Initialize mapgens + m_emerge->initMapgens(servermap->getMapgenParams()); + + if (g_settings->getBool("enable_rollback_recording")) { + // Create rollback manager + m_rollback = new RollbackManager(m_path_world, this); + } + + // Give environment reference to scripting api + m_script->initializeEnvironment(m_env); + + // Do this after regular script init is done + m_script->initAsync(); + + // Register us to receive map edit events + servermap->addEventReceiver(this); + + m_env->loadMeta(); + + // Those settings can be overwritten in world.mt, they are + // intended to be cached after environment loading. + m_liquid_transform_every = g_settings->getFloat("liquid_update"); + m_max_chatmessage_length = g_settings->getU16("chat_message_max_size"); + m_csm_restriction_flags = g_settings->getU64("csm_restriction_flags"); + m_csm_restriction_noderange = g_settings->getU32("csm_restriction_noderange"); +} + +void Server::start() +{ + init(); + + infostream << "Starting server on " << m_bind_addr.serializeString() + << "..." << std::endl; + + // Stop thread if already running + m_thread->stop(); + + // Initialize connection + m_con->SetTimeoutMs(30); + m_con->Serve(m_bind_addr); + + // Start thread + m_thread->start(); + + // ASCII art for the win! + std::cerr + << " __. __. __. " << std::endl + << " _____ |__| ____ _____ / |_ _____ _____ / |_ " << std::endl + << " / \\| |/ \\ / __ \\ _\\/ __ \\/ __> _\\" << std::endl + << "| Y Y \\ | | \\ ___/| | | ___/\\___ \\| | " << std::endl + << "|__|_| / |___| /\\______> | \\______>_____/| | " << std::endl + << " \\/ \\/ \\/ \\/ \\/ " << std::endl; + actionstream << "World at [" << m_path_world << "]" << std::endl; + actionstream << "Server for gameid=\"" << m_gamespec.id + << "\" listening on "; + m_bind_addr.print(actionstream); + actionstream << "." << std::endl; +} + +void Server::stop() +{ + infostream<<"Server: Stopping and waiting threads"<<std::endl; + + // Stop threads (set run=false first so both start stopping) + m_thread->stop(); + m_thread->wait(); + + infostream<<"Server: Threads stopped"<<std::endl; +} + +void Server::step(float dtime) +{ + // Limit a bit + if (dtime > 2.0) + dtime = 2.0; + { + MutexAutoLock lock(m_step_dtime_mutex); + m_step_dtime += dtime; + } + // Throw if fatal error occurred in thread + std::string async_err = m_async_fatal_error.get(); + if (!async_err.empty()) { + if (!m_simple_singleplayer_mode) { + m_env->kickAllPlayers(SERVER_ACCESSDENIED_CRASH, + g_settings->get("kick_msg_crash"), + g_settings->getBool("ask_reconnect_on_crash")); + } + throw ServerError("AsyncErr: " + async_err); + } +} + +void Server::AsyncRunStep(bool initial_step) +{ + + float dtime; + { + MutexAutoLock lock1(m_step_dtime_mutex); + dtime = m_step_dtime; + } + + { + // Send blocks to clients + SendBlocks(dtime); + } + + if((dtime < 0.001) && !initial_step) + return; + + ScopeProfiler sp(g_profiler, "Server::AsyncRunStep()", SPT_AVG); + + { + MutexAutoLock lock1(m_step_dtime_mutex); + m_step_dtime -= dtime; + } + + /* + Update uptime + */ + m_uptime_counter->increment(dtime); + + handlePeerChanges(); + + /* + Update time of day and overall game time + */ + m_env->setTimeOfDaySpeed(g_settings->getFloat("time_speed")); + + /* + Send to clients at constant intervals + */ + + m_time_of_day_send_timer -= dtime; + if (m_time_of_day_send_timer < 0.0) { + m_time_of_day_send_timer = g_settings->getFloat("time_send_interval"); + u16 time = m_env->getTimeOfDay(); + float time_speed = g_settings->getFloat("time_speed"); + SendTimeOfDay(PEER_ID_INEXISTENT, time, time_speed); + + m_timeofday_gauge->set(time); + } + + { + MutexAutoLock lock(m_env_mutex); + // Figure out and report maximum lag to environment + float max_lag = m_env->getMaxLagEstimate(); + max_lag *= 0.9998; // Decrease slowly (about half per 5 minutes) + if(dtime > max_lag){ + if(dtime > 0.1 && dtime > max_lag * 2.0) + infostream<<"Server: Maximum lag peaked to "<<dtime + <<" s"<<std::endl; + max_lag = dtime; + } + m_env->reportMaxLagEstimate(max_lag); + + // Step environment + m_env->step(dtime); + } + + static const float map_timer_and_unload_dtime = 2.92; + if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) + { + MutexAutoLock lock(m_env_mutex); + // Run Map's timers and unload unused data + ScopeProfiler sp(g_profiler, "Server: map timer and unload"); + m_env->getMap().timerUpdate(map_timer_and_unload_dtime, + std::max(g_settings->getFloat("server_unload_unused_data_timeout"), 0.0f), + -1); + } + + /* + Listen to the admin chat, if available + */ + if (m_admin_chat) { + if (!m_admin_chat->command_queue.empty()) { + MutexAutoLock lock(m_env_mutex); + while (!m_admin_chat->command_queue.empty()) { + ChatEvent *evt = m_admin_chat->command_queue.pop_frontNoEx(); + handleChatInterfaceEvent(evt); + delete evt; + } + } + m_admin_chat->outgoing_queue.push_back( + new ChatEventTimeInfo(m_env->getGameTime(), m_env->getTimeOfDay())); + } + + /* + Do background stuff + */ + + /* Transform liquids */ + m_liquid_transform_timer += dtime; + if(m_liquid_transform_timer >= m_liquid_transform_every) + { + m_liquid_transform_timer -= m_liquid_transform_every; + + MutexAutoLock lock(m_env_mutex); + + ScopeProfiler sp(g_profiler, "Server: liquid transform"); + + std::map<v3s16, MapBlock*> modified_blocks; + m_env->getServerMap().transformLiquids(modified_blocks, m_env); + + /* + Set the modified blocks unsent for all the clients + */ + if (!modified_blocks.empty()) { + SetBlocksNotSent(modified_blocks); + } + } + m_clients.step(dtime); + + // increase/decrease lag gauge gradually + if (m_lag_gauge->get() > dtime) { + m_lag_gauge->decrement(dtime/100); + } else { + m_lag_gauge->increment(dtime/100); + } + + { + float &counter = m_step_pending_dyn_media_timer; + counter += dtime; + if (counter >= 5.0f) { + stepPendingDynMediaCallbacks(counter); + counter = 0; + } + } + + +#if USE_CURL + // send masterserver announce + { + float &counter = m_masterserver_timer; + if (!isSingleplayer() && (!counter || counter >= 300.0) && + g_settings->getBool("server_announce")) { + ServerList::sendAnnounce(counter ? ServerList::AA_UPDATE : + ServerList::AA_START, + m_bind_addr.getPort(), + m_clients.getPlayerNames(), + m_uptime_counter->get(), + m_env->getGameTime(), + m_lag_gauge->get(), + m_gamespec.id, + Mapgen::getMapgenName(m_emerge->mgparams->mgtype), + m_modmgr->getMods(), + m_dedicated); + counter = 0.01; + } + counter += dtime; + } +#endif + + /* + Check added and deleted active objects + */ + { + //infostream<<"Server: Checking added and deleted active objects"<<std::endl; + MutexAutoLock envlock(m_env_mutex); + + { + ClientInterface::AutoLock clientlock(m_clients); + const RemoteClientMap &clients = m_clients.getClientList(); + ScopeProfiler sp(g_profiler, "Server: update objects within range"); + + m_player_gauge->set(clients.size()); + for (const auto &client_it : clients) { + RemoteClient *client = client_it.second; + + if (client->getState() < CS_DefinitionsSent) + continue; + + // This can happen if the client times out somehow + if (!m_env->getPlayer(client->peer_id)) + continue; + + PlayerSAO *playersao = getPlayerSAO(client->peer_id); + if (!playersao) + continue; + + SendActiveObjectRemoveAdd(client, playersao); + } + } + + // Write changes to the mod storage + m_mod_storage_save_timer -= dtime; + if (m_mod_storage_save_timer <= 0.0f) { + m_mod_storage_save_timer = g_settings->getFloat("server_map_save_interval"); + m_mod_storage_database->endSave(); + m_mod_storage_database->beginSave(); + } + } + + /* + Send object messages + */ + { + MutexAutoLock envlock(m_env_mutex); + ScopeProfiler sp(g_profiler, "Server: send SAO messages"); + + // Key = object id + // Value = data sent by object + std::unordered_map<u16, std::vector<ActiveObjectMessage>*> buffered_messages; + + // Get active object messages from environment + ActiveObjectMessage aom(0); + u32 count_reliable = 0, count_unreliable = 0; + for(;;) { + if (!m_env->getActiveObjectMessage(&aom)) + break; + if (aom.reliable) + count_reliable++; + else + count_unreliable++; + + std::vector<ActiveObjectMessage>* message_list = nullptr; + auto n = buffered_messages.find(aom.id); + if (n == buffered_messages.end()) { + message_list = new std::vector<ActiveObjectMessage>; + buffered_messages[aom.id] = message_list; + } else { + message_list = n->second; + } + message_list->push_back(std::move(aom)); + } + + m_aom_buffer_counter[0]->increment(count_reliable); + m_aom_buffer_counter[1]->increment(count_unreliable); + + { + ClientInterface::AutoLock clientlock(m_clients); + const RemoteClientMap &clients = m_clients.getClientList(); + // Route data to every client + std::string reliable_data, unreliable_data; + for (const auto &client_it : clients) { + reliable_data.clear(); + unreliable_data.clear(); + RemoteClient *client = client_it.second; + PlayerSAO *player = getPlayerSAO(client->peer_id); + // Go through all objects in message buffer + for (const auto &buffered_message : buffered_messages) { + // If object does not exist or is not known by client, skip it + u16 id = buffered_message.first; + ServerActiveObject *sao = m_env->getActiveObject(id); + if (!sao || client->m_known_objects.find(id) == client->m_known_objects.end()) + continue; + + // Get message list of object + std::vector<ActiveObjectMessage>* list = buffered_message.second; + // Go through every message + for (const ActiveObjectMessage &aom : *list) { + // Send position updates to players who do not see the attachment + if (aom.datastring[0] == AO_CMD_UPDATE_POSITION) { + if (sao->getId() == player->getId()) + continue; + + // Do not send position updates for attached players + // as long the parent is known to the client + ServerActiveObject *parent = sao->getParent(); + if (parent && client->m_known_objects.find(parent->getId()) != + client->m_known_objects.end()) + continue; + } + + // Add full new data to appropriate buffer + std::string &buffer = aom.reliable ? reliable_data : unreliable_data; + char idbuf[2]; + writeU16((u8*) idbuf, aom.id); + // u16 id + // std::string data + buffer.append(idbuf, sizeof(idbuf)); + buffer.append(serializeString16(aom.datastring)); + } + } + /* + reliable_data and unreliable_data are now ready. + Send them. + */ + if (!reliable_data.empty()) { + SendActiveObjectMessages(client->peer_id, reliable_data); + } + + if (!unreliable_data.empty()) { + SendActiveObjectMessages(client->peer_id, unreliable_data, false); + } + } + } + + // Clear buffered_messages + for (auto &buffered_message : buffered_messages) { + delete buffered_message.second; + } + } + + /* + Send queued-for-sending map edit events. + */ + { + // We will be accessing the environment + MutexAutoLock lock(m_env_mutex); + + // Single change sending is disabled if queue size is big + bool disable_single_change_sending = false; + if(m_unsent_map_edit_queue.size() >= 4) + disable_single_change_sending = true; + + const auto event_count = m_unsent_map_edit_queue.size(); + m_map_edit_event_counter->increment(event_count); + + // We'll log the amount of each + Profiler prof; + + std::unordered_set<v3s16> node_meta_updates; + + while (!m_unsent_map_edit_queue.empty()) { + MapEditEvent* event = m_unsent_map_edit_queue.front(); + m_unsent_map_edit_queue.pop(); + + // Players far away from the change are stored here. + // Instead of sending the changes, MapBlocks are set not sent + // for them. + std::unordered_set<u16> far_players; + + switch (event->type) { + case MEET_ADDNODE: + case MEET_SWAPNODE: + prof.add("MEET_ADDNODE", 1); + sendAddNode(event->p, event->n, &far_players, + disable_single_change_sending ? 5 : 30, + event->type == MEET_ADDNODE); + break; + case MEET_REMOVENODE: + prof.add("MEET_REMOVENODE", 1); + sendRemoveNode(event->p, &far_players, + disable_single_change_sending ? 5 : 30); + break; + case MEET_BLOCK_NODE_METADATA_CHANGED: { + prof.add("MEET_BLOCK_NODE_METADATA_CHANGED", 1); + if (!event->is_private_change) { + node_meta_updates.emplace(event->p); + } + + if (MapBlock *block = m_env->getMap().getBlockNoCreateNoEx( + getNodeBlockPos(event->p))) { + block->raiseModified(MOD_STATE_WRITE_NEEDED, + MOD_REASON_REPORT_META_CHANGE); + } + break; + } + case MEET_OTHER: + prof.add("MEET_OTHER", 1); + for (const v3s16 &modified_block : event->modified_blocks) { + m_clients.markBlockposAsNotSent(modified_block); + } + break; + default: + prof.add("unknown", 1); + warningstream << "Server: Unknown MapEditEvent " + << ((u32)event->type) << std::endl; + break; + } + + /* + Set blocks not sent to far players + */ + if (!far_players.empty()) { + // Convert list format to that wanted by SetBlocksNotSent + std::map<v3s16, MapBlock*> modified_blocks2; + for (const v3s16 &modified_block : event->modified_blocks) { + modified_blocks2[modified_block] = + m_env->getMap().getBlockNoCreateNoEx(modified_block); + } + + // Set blocks not sent + for (const u16 far_player : far_players) { + if (RemoteClient *client = getClient(far_player)) + client->SetBlocksNotSent(modified_blocks2); + } + } + + delete event; + } + + if (event_count >= 5) { + infostream << "Server: MapEditEvents:" << std::endl; + prof.print(infostream); + } else if (event_count != 0) { + verbosestream << "Server: MapEditEvents:" << std::endl; + prof.print(verbosestream); + } + + // Send all metadata updates + if (!node_meta_updates.empty()) + sendMetadataChanged(node_meta_updates); + } + + /* + Trigger emerge thread + Doing this every 2s is left over from old code, unclear if this is still needed. + */ + { + float &counter = m_emergethread_trigger_timer; + counter -= dtime; + if (counter <= 0.0f) { + counter = 2.0f; + + m_emerge->startThreads(); + } + } + + // Save map, players and auth stuff + { + float &counter = m_savemap_timer; + counter += dtime; + static thread_local const float save_interval = + g_settings->getFloat("server_map_save_interval"); + if (counter >= save_interval) { + counter = 0.0; + MutexAutoLock lock(m_env_mutex); + + ScopeProfiler sp(g_profiler, "Server: map saving (sum)"); + + // Save ban file + if (m_banmanager->isModified()) { + m_banmanager->save(); + } + + // Save changed parts of map + m_env->getMap().save(MOD_STATE_WRITE_NEEDED); + + // Save players + m_env->saveLoadedPlayers(); + + // Save environment metadata + m_env->saveMeta(); + } + } + + m_shutdown_state.tick(dtime, this); +} + +void Server::Receive() +{ + NetworkPacket pkt; + session_t peer_id; + bool first = true; + for (;;) { + pkt.clear(); + peer_id = 0; + try { + /* + In the first iteration *wait* for a packet, afterwards process + all packets that are immediately available (no waiting). + */ + if (first) { + m_con->Receive(&pkt); + first = false; + } else { + if (!m_con->TryReceive(&pkt)) + return; + } + + peer_id = pkt.getPeerId(); + m_packet_recv_counter->increment(); + ProcessData(&pkt); + m_packet_recv_processed_counter->increment(); + } catch (const con::InvalidIncomingDataException &e) { + infostream << "Server::Receive(): InvalidIncomingDataException: what()=" + << e.what() << std::endl; + } catch (const SerializationError &e) { + infostream << "Server::Receive(): SerializationError: what()=" + << e.what() << std::endl; + } catch (const ClientStateError &e) { + errorstream << "ProcessData: peer=" << peer_id << " what()=" + << e.what() << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_UNEXPECTED_DATA); + } catch (const con::PeerNotFoundException &e) { + // Do nothing + } catch (const con::NoIncomingDataException &e) { + return; + } + } +} + +PlayerSAO* Server::StageTwoClientInit(session_t peer_id) +{ + std::string playername; + PlayerSAO *playersao = NULL; + { + ClientInterface::AutoLock clientlock(m_clients); + RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone); + if (client) { + playername = client->getName(); + playersao = emergePlayer(playername.c_str(), peer_id, client->net_proto_version); + } + } + + RemotePlayer *player = m_env->getPlayer(playername.c_str()); + + // If failed, cancel + if (!playersao || !player) { + if (player && player->getPeerId() != PEER_ID_INEXISTENT) { + actionstream << "Server: Failed to emerge player \"" << playername + << "\" (player allocated to an another client)" << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_ALREADY_CONNECTED); + } else { + errorstream << "Server: " << playername << ": Failed to emerge player" + << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_SERVER_FAIL); + } + return nullptr; + } + + /* + Send complete position information + */ + SendMovePlayer(peer_id); + + // Send privileges + SendPlayerPrivileges(peer_id); + + // Send inventory formspec + SendPlayerInventoryFormspec(peer_id); + + // Send inventory + SendInventory(playersao, false); + + // Send HP + SendPlayerHP(playersao, false); + + // Send death screen + if (playersao->isDead()) + SendDeathscreen(peer_id, false, v3f(0,0,0)); + + // Send Breath + SendPlayerBreath(playersao); + + /* + Update player list and print action + */ + { + NetworkPacket notice_pkt(TOCLIENT_UPDATE_PLAYER_LIST, 0, PEER_ID_INEXISTENT); + notice_pkt << (u8) PLAYER_LIST_ADD << (u16) 1 << std::string(player->getName()); + m_clients.sendToAll(¬ice_pkt); + } + { + std::string ip_str = getPeerAddress(player->getPeerId()).serializeString(); + const auto &names = m_clients.getPlayerNames(); + + actionstream << player->getName() << " [" << ip_str << "] joins game. List of players: "; + for (const std::string &name : names) + actionstream << name << " "; + actionstream << player->getName() << std::endl; + } + return playersao; +} + +inline void Server::handleCommand(NetworkPacket *pkt) +{ + const ToServerCommandHandler &opHandle = toServerCommandTable[pkt->getCommand()]; + (this->*opHandle.handler)(pkt); +} + +void Server::ProcessData(NetworkPacket *pkt) +{ + // Environment is locked first. + MutexAutoLock envlock(m_env_mutex); + + ScopeProfiler sp(g_profiler, "Server: Process network packet (sum)"); + u32 peer_id = pkt->getPeerId(); + + try { + Address address = getPeerAddress(peer_id); + std::string addr_s = address.serializeString(); + + // FIXME: Isn't it a bit excessive to check this for every packet? + if (m_banmanager->isIpBanned(addr_s)) { + std::string ban_name = m_banmanager->getBanName(addr_s); + infostream << "Server: A banned client tried to connect from " + << addr_s << "; banned name was " << ban_name << std::endl; + DenyAccess(peer_id, SERVER_ACCESSDENIED_CUSTOM_STRING, + "Your IP is banned. Banned name was " + ban_name); + return; + } + } catch (con::PeerNotFoundException &e) { + /* + * no peer for this packet found + * most common reason is peer timeout, e.g. peer didn't + * respond for some time, your server was overloaded or + * things like that. + */ + infostream << "Server::ProcessData(): Canceling: peer " + << peer_id << " not found" << std::endl; + return; + } + + try { + ToServerCommand command = (ToServerCommand) pkt->getCommand(); + + // Command must be handled into ToServerCommandHandler + if (command >= TOSERVER_NUM_MSG_TYPES) { + infostream << "Server: Ignoring unknown command " + << command << std::endl; + return; + } + + if (toServerCommandTable[command].state == TOSERVER_STATE_NOT_CONNECTED) { + handleCommand(pkt); + return; + } + + u8 peer_ser_ver = getClient(peer_id, CS_InitDone)->serialization_version; + + if(peer_ser_ver == SER_FMT_VER_INVALID) { + errorstream << "Server::ProcessData(): Cancelling: Peer" + " serialization format invalid or not initialized." + " Skipping incoming command=" << command << std::endl; + return; + } + + /* Handle commands related to client startup */ + if (toServerCommandTable[command].state == TOSERVER_STATE_STARTUP) { + handleCommand(pkt); + return; + } + + if (m_clients.getClientState(peer_id) < CS_Active) { + if (command == TOSERVER_PLAYERPOS) return; + + errorstream << "Got packet command: " << command << " for peer id " + << peer_id << " but client isn't active yet. Dropping packet " + << std::endl; + return; + } + + handleCommand(pkt); + } catch (SendFailedException &e) { + errorstream << "Server::ProcessData(): SendFailedException: " + << "what=" << e.what() + << std::endl; + } catch (PacketError &e) { + actionstream << "Server::ProcessData(): PacketError: " + << "what=" << e.what() + << std::endl; + } +} + +void Server::setTimeOfDay(u32 time) +{ + m_env->setTimeOfDay(time); + m_time_of_day_send_timer = 0; +} + +void Server::onMapEditEvent(const MapEditEvent &event) +{ + if (m_ignore_map_edit_events_area.contains(event.getArea())) + return; + + m_unsent_map_edit_queue.push(new MapEditEvent(event)); +} + +void Server::SetBlocksNotSent(std::map<v3s16, MapBlock *>& block) +{ + std::vector<session_t> clients = m_clients.getClientIDs(); + ClientInterface::AutoLock clientlock(m_clients); + // Set the modified blocks unsent for all the clients + for (const session_t client_id : clients) { + if (RemoteClient *client = m_clients.lockedGetClientNoEx(client_id)) + client->SetBlocksNotSent(block); + } +} + +void Server::peerAdded(con::Peer *peer) +{ + verbosestream<<"Server::peerAdded(): peer->id=" + <<peer->id<<std::endl; + + m_peer_change_queue.push(con::PeerChange(con::PEER_ADDED, peer->id, false)); +} + +void Server::deletingPeer(con::Peer *peer, bool timeout) +{ + verbosestream<<"Server::deletingPeer(): peer->id=" + <<peer->id<<", timeout="<<timeout<<std::endl; + + m_clients.event(peer->id, CSE_Disconnect); + m_peer_change_queue.push(con::PeerChange(con::PEER_REMOVED, peer->id, timeout)); +} + +bool Server::getClientConInfo(session_t peer_id, con::rtt_stat_type type, float* retval) +{ + *retval = m_con->getPeerStat(peer_id,type); + return *retval != -1; +} + +bool Server::getClientInfo(session_t peer_id, ClientInfo &ret) +{ + ClientInterface::AutoLock clientlock(m_clients); + RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid); + + if (!client) + return false; + + ret.state = client->getState(); + ret.addr = client->getAddress(); + ret.uptime = client->uptime(); + ret.ser_vers = client->serialization_version; + ret.prot_vers = client->net_proto_version; + + ret.major = client->getMajor(); + ret.minor = client->getMinor(); + ret.patch = client->getPatch(); + ret.vers_string = client->getFullVer(); + + ret.lang_code = client->getLangCode(); + + return true; +} + +void Server::handlePeerChanges() +{ + while(!m_peer_change_queue.empty()) + { + con::PeerChange c = m_peer_change_queue.front(); + m_peer_change_queue.pop(); + + verbosestream<<"Server: Handling peer change: " + <<"id="<<c.peer_id<<", timeout="<<c.timeout + <<std::endl; + + switch(c.type) + { + case con::PEER_ADDED: + m_clients.CreateClient(c.peer_id); + break; + + case con::PEER_REMOVED: + DeleteClient(c.peer_id, c.timeout?CDR_TIMEOUT:CDR_LEAVE); + break; + + default: + FATAL_ERROR("Invalid peer change event received!"); + break; + } + } +} + +void Server::printToConsoleOnly(const std::string &text) +{ + if (m_admin_chat) { + m_admin_chat->outgoing_queue.push_back( + new ChatEventChat("", utf8_to_wide(text))); + } else { + std::cout << text << std::endl; + } +} + +void Server::Send(NetworkPacket *pkt) +{ + Send(pkt->getPeerId(), pkt); +} + +void Server::Send(session_t peer_id, NetworkPacket *pkt) +{ + m_clients.send(peer_id, + clientCommandFactoryTable[pkt->getCommand()].channel, + pkt, + clientCommandFactoryTable[pkt->getCommand()].reliable); +} + +void Server::SendMovement(session_t peer_id) +{ + std::ostringstream os(std::ios_base::binary); + + NetworkPacket pkt(TOCLIENT_MOVEMENT, 12 * sizeof(float), peer_id); + + pkt << g_settings->getFloat("movement_acceleration_default"); + pkt << g_settings->getFloat("movement_acceleration_air"); + pkt << g_settings->getFloat("movement_acceleration_fast"); + pkt << g_settings->getFloat("movement_speed_walk"); + pkt << g_settings->getFloat("movement_speed_crouch"); + pkt << g_settings->getFloat("movement_speed_fast"); + pkt << g_settings->getFloat("movement_speed_climb"); + pkt << g_settings->getFloat("movement_speed_jump"); + pkt << g_settings->getFloat("movement_liquid_fluidity"); + pkt << g_settings->getFloat("movement_liquid_fluidity_smooth"); + pkt << g_settings->getFloat("movement_liquid_sink"); + pkt << g_settings->getFloat("movement_gravity"); + + Send(&pkt); +} + +void Server::HandlePlayerHPChange(PlayerSAO *playersao, const PlayerHPChangeReason &reason) +{ + m_script->player_event(playersao, "health_changed"); + SendPlayerHP(playersao, reason.type != PlayerHPChangeReason::SET_HP_MAX); + + // Send to other clients + playersao->sendPunchCommand(); + + if (playersao->isDead()) + HandlePlayerDeath(playersao, reason); +} + +void Server::SendPlayerHP(PlayerSAO *playersao, bool effect) +{ + SendHP(playersao->getPeerID(), playersao->getHP(), effect); +} + +void Server::SendHP(session_t peer_id, u16 hp, bool effect) +{ + NetworkPacket pkt(TOCLIENT_HP, 3, peer_id); + pkt << hp << effect; + Send(&pkt); +} + +void Server::SendBreath(session_t peer_id, u16 breath) +{ + NetworkPacket pkt(TOCLIENT_BREATH, 2, peer_id); + pkt << (u16) breath; + Send(&pkt); +} + +void Server::SendAccessDenied(session_t peer_id, AccessDeniedCode reason, + const std::string &custom_reason, bool reconnect) +{ + assert(reason < SERVER_ACCESSDENIED_MAX); + + NetworkPacket pkt(TOCLIENT_ACCESS_DENIED, 1, peer_id); + pkt << (u8)reason; + if (reason == SERVER_ACCESSDENIED_CUSTOM_STRING) + pkt << custom_reason; + else if (reason == SERVER_ACCESSDENIED_SHUTDOWN || + reason == SERVER_ACCESSDENIED_CRASH) + pkt << custom_reason << (u8)reconnect; + Send(&pkt); +} + +void Server::SendDeathscreen(session_t peer_id, bool set_camera_point_target, + v3f camera_point_target) +{ + NetworkPacket pkt(TOCLIENT_DEATHSCREEN, 1 + sizeof(v3f), peer_id); + pkt << set_camera_point_target << camera_point_target; + Send(&pkt); +} + +void Server::SendItemDef(session_t peer_id, + IItemDefManager *itemdef, u16 protocol_version) +{ + NetworkPacket pkt(TOCLIENT_ITEMDEF, 0, peer_id); + + /* + u16 command + u32 length of the next item + zlib-compressed serialized ItemDefManager + */ + std::ostringstream tmp_os(std::ios::binary); + itemdef->serialize(tmp_os, protocol_version); + std::ostringstream tmp_os2(std::ios::binary); + compressZlib(tmp_os.str(), tmp_os2); + pkt.putLongString(tmp_os2.str()); + + // Make data buffer + verbosestream << "Server: Sending item definitions to id(" << peer_id + << "): size=" << pkt.getSize() << std::endl; + + Send(&pkt); +} + +void Server::SendNodeDef(session_t peer_id, + const NodeDefManager *nodedef, u16 protocol_version) +{ + NetworkPacket pkt(TOCLIENT_NODEDEF, 0, peer_id); + + /* + u16 command + u32 length of the next item + zlib-compressed serialized NodeDefManager + */ + std::ostringstream tmp_os(std::ios::binary); + nodedef->serialize(tmp_os, protocol_version); + std::ostringstream tmp_os2(std::ios::binary); + compressZlib(tmp_os.str(), tmp_os2); + + pkt.putLongString(tmp_os2.str()); + + // Make data buffer + verbosestream << "Server: Sending node definitions to id(" << peer_id + << "): size=" << pkt.getSize() << std::endl; + + Send(&pkt); +} + +/* + Non-static send methods +*/ + +void Server::SendInventory(PlayerSAO *sao, bool incremental) +{ + RemotePlayer *player = sao->getPlayer(); + + // Do not send new format to old clients + incremental &= player->protocol_version >= 38; + + UpdateCrafting(player); + + /* + Serialize it + */ + + NetworkPacket pkt(TOCLIENT_INVENTORY, 0, sao->getPeerID()); + + std::ostringstream os(std::ios::binary); + sao->getInventory()->serialize(os, incremental); + sao->getInventory()->setModified(false); + player->setModified(true); + + const std::string &s = os.str(); + pkt.putRawString(s.c_str(), s.size()); + Send(&pkt); +} + +void Server::SendChatMessage(session_t peer_id, const ChatMessage &message) +{ + NetworkPacket pkt(TOCLIENT_CHAT_MESSAGE, 0, peer_id); + u8 version = 1; + u8 type = message.type; + pkt << version << type << message.sender << message.message + << static_cast<u64>(message.timestamp); + + if (peer_id != PEER_ID_INEXISTENT) { + RemotePlayer *player = m_env->getPlayer(peer_id); + if (!player) + return; + + Send(&pkt); + } else { + m_clients.sendToAll(&pkt); + } +} + +void Server::SendShowFormspecMessage(session_t peer_id, const std::string &formspec, + const std::string &formname) +{ + NetworkPacket pkt(TOCLIENT_SHOW_FORMSPEC, 0, peer_id); + if (formspec.empty()){ + //the client should close the formspec + //but make sure there wasn't another one open in meantime + const auto it = m_formspec_state_data.find(peer_id); + if (it != m_formspec_state_data.end() && it->second == formname) { + m_formspec_state_data.erase(peer_id); + } + pkt.putLongString(""); + } else { + m_formspec_state_data[peer_id] = formname; + pkt.putLongString(formspec); + } + pkt << formname; + + Send(&pkt); +} + +// Spawns a particle on peer with peer_id +void Server::SendSpawnParticle(session_t peer_id, u16 protocol_version, + const ParticleParameters &p) +{ + static thread_local const float radius = + g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE * BS; + + if (peer_id == PEER_ID_INEXISTENT) { + std::vector<session_t> clients = m_clients.getClientIDs(); + const v3f pos = p.pos * BS; + const float radius_sq = radius * radius; + + for (const session_t client_id : clients) { + RemotePlayer *player = m_env->getPlayer(client_id); + if (!player) + continue; + + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + + // Do not send to distant clients + if (sao->getBasePosition().getDistanceFromSQ(pos) > radius_sq) + continue; + + SendSpawnParticle(client_id, player->protocol_version, p); + } + return; + } + assert(protocol_version != 0); + + NetworkPacket pkt(TOCLIENT_SPAWN_PARTICLE, 0, peer_id); + + { + // NetworkPacket and iostreams are incompatible... + std::ostringstream oss(std::ios_base::binary); + p.serialize(oss, protocol_version); + pkt.putRawString(oss.str()); + } + + Send(&pkt); +} + +// Adds a ParticleSpawner on peer with peer_id +void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version, + const ParticleSpawnerParameters &p, u16 attached_id, u32 id) +{ + static thread_local const float radius = + g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE * BS; + + if (peer_id == PEER_ID_INEXISTENT) { + std::vector<session_t> clients = m_clients.getClientIDs(); + const v3f pos = ( + p.pos.start.min.val + + p.pos.start.max.val + + p.pos.end.min.val + + p.pos.end.max.val + ) / 4.0f * BS; + const float radius_sq = radius * radius; + /* Don't send short-lived spawners to distant players. + * This could be replaced with proper tracking at some point. */ + const bool distance_check = !attached_id && p.time <= 1.0f; + + for (const session_t client_id : clients) { + RemotePlayer *player = m_env->getPlayer(client_id); + if (!player) + continue; + + if (distance_check) { + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + if (sao->getBasePosition().getDistanceFromSQ(pos) > radius_sq) + continue; + } + + SendAddParticleSpawner(client_id, player->protocol_version, + p, attached_id, id); + } + return; + } + assert(protocol_version != 0); + + NetworkPacket pkt(TOCLIENT_ADD_PARTICLESPAWNER, 100, peer_id); + + pkt << p.amount << p.time; + { // serialize legacy fields + std::ostringstream os(std::ios_base::binary); + p.pos.start.legacySerialize(os); + p.vel.start.legacySerialize(os); + p.acc.start.legacySerialize(os); + p.exptime.start.legacySerialize(os); + p.size.start.legacySerialize(os); + pkt.putRawString(os.str()); + } + pkt << p.collisiondetection; + + pkt.putLongString(p.texture.string); + + pkt << id << p.vertical << p.collision_removal << attached_id; + { + std::ostringstream os(std::ios_base::binary); + p.animation.serialize(os, protocol_version); + pkt.putRawString(os.str()); + } + pkt << p.glow << p.object_collision; + pkt << p.node.param0 << p.node.param2 << p.node_tile; + + { // serialize new fields + // initial bias for older properties + pkt << p.pos.start.bias + << p.vel.start.bias + << p.acc.start.bias + << p.exptime.start.bias + << p.size.start.bias; + + std::ostringstream os(std::ios_base::binary); + + // final tween frames of older properties + p.pos.end.serialize(os); + p.vel.end.serialize(os); + p.acc.end.serialize(os); + p.exptime.end.serialize(os); + p.size.end.serialize(os); + + // properties for legacy texture field + p.texture.serialize(os, protocol_version, true); + + // new properties + p.drag.serialize(os); + p.jitter.serialize(os); + p.bounce.serialize(os); + ParticleParamTypes::serializeParameterValue(os, p.attractor_kind); + if (p.attractor_kind != ParticleParamTypes::AttractorKind::none) { + p.attract.serialize(os); + p.attractor_origin.serialize(os); + writeU16(os, p.attractor_attachment); /* object ID */ + writeU8(os, p.attractor_kill); + if (p.attractor_kind != ParticleParamTypes::AttractorKind::point) { + p.attractor_direction.serialize(os); + writeU16(os, p.attractor_direction_attachment); + } + } + p.radius.serialize(os); + + ParticleParamTypes::serializeParameterValue(os, (u16)p.texpool.size()); + for (const auto& tex : p.texpool) { + tex.serialize(os, protocol_version); + } + + pkt.putRawString(os.str()); + } + + Send(&pkt); +} + +void Server::SendDeleteParticleSpawner(session_t peer_id, u32 id) +{ + NetworkPacket pkt(TOCLIENT_DELETE_PARTICLESPAWNER, 4, peer_id); + + pkt << id; + + if (peer_id != PEER_ID_INEXISTENT) + Send(&pkt); + else + m_clients.sendToAll(&pkt); + +} + +void Server::SendHUDAdd(session_t peer_id, u32 id, HudElement *form) +{ + NetworkPacket pkt(TOCLIENT_HUDADD, 0 , peer_id); + + pkt << id << (u8) form->type << form->pos << form->name << form->scale + << form->text << form->number << form->item << form->dir + << form->align << form->offset << form->world_pos << form->size + << form->z_index << form->text2 << form->style; + + Send(&pkt); +} + +void Server::SendHUDRemove(session_t peer_id, u32 id) +{ + NetworkPacket pkt(TOCLIENT_HUDRM, 4, peer_id); + pkt << id; + Send(&pkt); +} + +void Server::SendHUDChange(session_t peer_id, u32 id, HudElementStat stat, void *value) +{ + NetworkPacket pkt(TOCLIENT_HUDCHANGE, 0, peer_id); + pkt << id << (u8) stat; + + switch (stat) { + case HUD_STAT_POS: + case HUD_STAT_SCALE: + case HUD_STAT_ALIGN: + case HUD_STAT_OFFSET: + pkt << *(v2f *) value; + break; + case HUD_STAT_NAME: + case HUD_STAT_TEXT: + case HUD_STAT_TEXT2: + pkt << *(std::string *) value; + break; + case HUD_STAT_WORLD_POS: + pkt << *(v3f *) value; + break; + case HUD_STAT_SIZE: + pkt << *(v2s32 *) value; + break; + default: // all other types + pkt << *(u32 *) value; + break; + } + + Send(&pkt); +} + +void Server::SendHUDSetFlags(session_t peer_id, u32 flags, u32 mask) +{ + NetworkPacket pkt(TOCLIENT_HUD_SET_FLAGS, 4 + 4, peer_id); + + flags &= ~(HUD_FLAG_HEALTHBAR_VISIBLE | HUD_FLAG_BREATHBAR_VISIBLE); + + pkt << flags << mask; + + Send(&pkt); +} + +void Server::SendHUDSetParam(session_t peer_id, u16 param, const std::string &value) +{ + NetworkPacket pkt(TOCLIENT_HUD_SET_PARAM, 0, peer_id); + pkt << param << value; + Send(&pkt); +} + +void Server::SendSetSky(session_t peer_id, const SkyboxParams ¶ms) +{ + NetworkPacket pkt(TOCLIENT_SET_SKY, 0, peer_id); + + // Handle prior clients here + if (m_clients.getProtocolVersion(peer_id) < 39) { + pkt << params.bgcolor << params.type << (u16) params.textures.size(); + + for (const std::string& texture : params.textures) + pkt << texture; + + pkt << params.clouds; + } else { // Handle current clients and future clients + pkt << params.bgcolor << params.type + << params.clouds << params.fog_sun_tint + << params.fog_moon_tint << params.fog_tint_type; + + if (params.type == "skybox") { + pkt << (u16) params.textures.size(); + for (const std::string &texture : params.textures) + pkt << texture; + } else if (params.type == "regular") { + pkt << params.sky_color.day_sky << params.sky_color.day_horizon + << params.sky_color.dawn_sky << params.sky_color.dawn_horizon + << params.sky_color.night_sky << params.sky_color.night_horizon + << params.sky_color.indoors; + } + } + + Send(&pkt); +} + +void Server::SendSetSun(session_t peer_id, const SunParams ¶ms) +{ + NetworkPacket pkt(TOCLIENT_SET_SUN, 0, peer_id); + pkt << params.visible << params.texture + << params.tonemap << params.sunrise + << params.sunrise_visible << params.scale; + + Send(&pkt); +} +void Server::SendSetMoon(session_t peer_id, const MoonParams ¶ms) +{ + NetworkPacket pkt(TOCLIENT_SET_MOON, 0, peer_id); + + pkt << params.visible << params.texture + << params.tonemap << params.scale; + + Send(&pkt); +} +void Server::SendSetStars(session_t peer_id, const StarParams ¶ms) +{ + NetworkPacket pkt(TOCLIENT_SET_STARS, 0, peer_id); + + pkt << params.visible << params.count + << params.starcolor << params.scale + << params.day_opacity; + + Send(&pkt); +} + +void Server::SendCloudParams(session_t peer_id, const CloudParams ¶ms) +{ + NetworkPacket pkt(TOCLIENT_CLOUD_PARAMS, 0, peer_id); + pkt << params.density << params.color_bright << params.color_ambient + << params.height << params.thickness << params.speed; + Send(&pkt); +} + +void Server::SendOverrideDayNightRatio(session_t peer_id, bool do_override, + float ratio) +{ + NetworkPacket pkt(TOCLIENT_OVERRIDE_DAY_NIGHT_RATIO, + 1 + 2, peer_id); + + pkt << do_override << (u16) (ratio * 65535); + + Send(&pkt); +} + +void Server::SendSetLighting(session_t peer_id, const Lighting &lighting) +{ + NetworkPacket pkt(TOCLIENT_SET_LIGHTING, + 4, peer_id); + + pkt << lighting.shadow_intensity; + + Send(&pkt); +} + +void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed) +{ + NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id); + pkt << time << time_speed; + + if (peer_id == PEER_ID_INEXISTENT) { + m_clients.sendToAll(&pkt); + } + else { + Send(&pkt); + } +} + +void Server::SendPlayerBreath(PlayerSAO *sao) +{ + assert(sao); + + m_script->player_event(sao, "breath_changed"); + SendBreath(sao->getPeerID(), sao->getBreath()); +} + +void Server::SendMovePlayer(session_t peer_id) +{ + RemotePlayer *player = m_env->getPlayer(peer_id); + assert(player); + PlayerSAO *sao = player->getPlayerSAO(); + assert(sao); + + // Send attachment updates instantly to the client prior updating position + sao->sendOutdatedData(); + + NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id); + pkt << sao->getBasePosition() << sao->getLookPitch() << sao->getRotation().Y; + + { + v3f pos = sao->getBasePosition(); + verbosestream << "Server: Sending TOCLIENT_MOVE_PLAYER" + << " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")" + << " pitch=" << sao->getLookPitch() + << " yaw=" << sao->getRotation().Y + << std::endl; + } + + Send(&pkt); +} + +void Server::SendPlayerFov(session_t peer_id) +{ + NetworkPacket pkt(TOCLIENT_FOV, 4 + 1 + 4, peer_id); + + PlayerFovSpec fov_spec = m_env->getPlayer(peer_id)->getFov(); + pkt << fov_spec.fov << fov_spec.is_multiplier << fov_spec.transition_time; + + Send(&pkt); +} + +void Server::SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4], + f32 animation_speed) +{ + NetworkPacket pkt(TOCLIENT_LOCAL_PLAYER_ANIMATIONS, 0, + peer_id); + + pkt << animation_frames[0] << animation_frames[1] << animation_frames[2] + << animation_frames[3] << animation_speed; + + Send(&pkt); +} + +void Server::SendEyeOffset(session_t peer_id, v3f first, v3f third) +{ + NetworkPacket pkt(TOCLIENT_EYE_OFFSET, 0, peer_id); + pkt << first << third; + Send(&pkt); +} + +void Server::SendPlayerPrivileges(session_t peer_id) +{ + RemotePlayer *player = m_env->getPlayer(peer_id); + assert(player); + if(player->getPeerId() == PEER_ID_INEXISTENT) + return; + + std::set<std::string> privs; + m_script->getAuth(player->getName(), NULL, &privs); + + NetworkPacket pkt(TOCLIENT_PRIVILEGES, 0, peer_id); + pkt << (u16) privs.size(); + + for (const std::string &priv : privs) { + pkt << priv; + } + + Send(&pkt); +} + +void Server::SendPlayerInventoryFormspec(session_t peer_id) +{ + RemotePlayer *player = m_env->getPlayer(peer_id); + assert(player); + if (player->getPeerId() == PEER_ID_INEXISTENT) + return; + + NetworkPacket pkt(TOCLIENT_INVENTORY_FORMSPEC, 0, peer_id); + pkt.putLongString(player->inventory_formspec); + + Send(&pkt); +} + +void Server::SendPlayerFormspecPrepend(session_t peer_id) +{ + RemotePlayer *player = m_env->getPlayer(peer_id); + assert(player); + if (player->getPeerId() == PEER_ID_INEXISTENT) + return; + + NetworkPacket pkt(TOCLIENT_FORMSPEC_PREPEND, 0, peer_id); + pkt << player->formspec_prepend; + Send(&pkt); +} + +void Server::SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersao) +{ + // Radius inside which objects are active + static thread_local const s16 radius = + g_settings->getS16("active_object_send_range_blocks") * MAP_BLOCKSIZE; + + // Radius inside which players are active + static thread_local const bool is_transfer_limited = + g_settings->exists("unlimited_player_transfer_distance") && + !g_settings->getBool("unlimited_player_transfer_distance"); + + static thread_local const s16 player_transfer_dist = + g_settings->getS16("player_transfer_distance") * MAP_BLOCKSIZE; + + s16 player_radius = player_transfer_dist == 0 && is_transfer_limited ? + radius : player_transfer_dist; + + s16 my_radius = MYMIN(radius, playersao->getWantedRange() * MAP_BLOCKSIZE); + if (my_radius <= 0) + my_radius = radius; + + std::queue<u16> removed_objects, added_objects; + m_env->getRemovedActiveObjects(playersao, my_radius, player_radius, + client->m_known_objects, removed_objects); + m_env->getAddedActiveObjects(playersao, my_radius, player_radius, + client->m_known_objects, added_objects); + + int removed_count = removed_objects.size(); + int added_count = added_objects.size(); + + if (removed_objects.empty() && added_objects.empty()) + return; + + char buf[4]; + std::string data; + + // Handle removed objects + writeU16((u8*)buf, removed_objects.size()); + data.append(buf, 2); + while (!removed_objects.empty()) { + // Get object + u16 id = removed_objects.front(); + ServerActiveObject* obj = m_env->getActiveObject(id); + + // Add to data buffer for sending + writeU16((u8*)buf, id); + data.append(buf, 2); + + // Remove from known objects + client->m_known_objects.erase(id); + + if (obj && obj->m_known_by_count > 0) + obj->m_known_by_count--; + + removed_objects.pop(); + } + + // Handle added objects + writeU16((u8*)buf, added_objects.size()); + data.append(buf, 2); + while (!added_objects.empty()) { + // Get object + u16 id = added_objects.front(); + ServerActiveObject *obj = m_env->getActiveObject(id); + added_objects.pop(); + + if (!obj) { + warningstream << FUNCTION_NAME << ": NULL object id=" + << (int)id << std::endl; + continue; + } + + // Get object type + u8 type = obj->getSendType(); + + // Add to data buffer for sending + writeU16((u8*)buf, id); + data.append(buf, 2); + writeU8((u8*)buf, type); + data.append(buf, 1); + + data.append(serializeString32( + obj->getClientInitializationData(client->net_proto_version))); + + // Add to known objects + client->m_known_objects.insert(id); + + obj->m_known_by_count++; + } + + NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD, data.size(), client->peer_id); + pkt.putRawString(data.c_str(), data.size()); + Send(&pkt); + + verbosestream << "Server::SendActiveObjectRemoveAdd: " + << removed_count << " removed, " << added_count << " added, " + << "packet size is " << pkt.getSize() << std::endl; +} + +void Server::SendActiveObjectMessages(session_t peer_id, const std::string &datas, + bool reliable) +{ + NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_MESSAGES, + datas.size(), peer_id); + + pkt.putRawString(datas.c_str(), datas.size()); + + m_clients.send(pkt.getPeerId(), + reliable ? clientCommandFactoryTable[pkt.getCommand()].channel : 1, + &pkt, reliable); +} + +void Server::SendCSMRestrictionFlags(session_t peer_id) +{ + NetworkPacket pkt(TOCLIENT_CSM_RESTRICTION_FLAGS, + sizeof(m_csm_restriction_flags) + sizeof(m_csm_restriction_noderange), peer_id); + pkt << m_csm_restriction_flags << m_csm_restriction_noderange; + Send(&pkt); +} + +void Server::SendPlayerSpeed(session_t peer_id, const v3f &added_vel) +{ + NetworkPacket pkt(TOCLIENT_PLAYER_SPEED, 0, peer_id); + pkt << added_vel; + Send(&pkt); +} + +inline s32 Server::nextSoundId() +{ + s32 ret = m_next_sound_id; + if (m_next_sound_id == INT32_MAX) + m_next_sound_id = 0; // signed overflow is undefined + else + m_next_sound_id++; + return ret; +} + +s32 Server::playSound(ServerPlayingSound ¶ms, bool ephemeral) +{ + // Find out initial position of sound + bool pos_exists = false; + const v3f pos = params.getPos(m_env, &pos_exists); + // If position is not found while it should be, cancel sound + if(pos_exists != (params.type != SoundLocation::Local)) + return -1; + + // Filter destination clients + std::vector<session_t> dst_clients; + if (!params.to_player.empty()) { + RemotePlayer *player = m_env->getPlayer(params.to_player.c_str()); + if(!player){ + infostream<<"Server::playSound: Player \""<<params.to_player + <<"\" not found"<<std::endl; + return -1; + } + if (player->getPeerId() == PEER_ID_INEXISTENT) { + infostream<<"Server::playSound: Player \""<<params.to_player + <<"\" not connected"<<std::endl; + return -1; + } + dst_clients.push_back(player->getPeerId()); + } else { + std::vector<session_t> clients = m_clients.getClientIDs(); + + for (const session_t client_id : clients) { + RemotePlayer *player = m_env->getPlayer(client_id); + if (!player) + continue; + if (!params.exclude_player.empty() && + params.exclude_player == player->getName()) + continue; + + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + + if (pos_exists) { + if(sao->getBasePosition().getDistanceFrom(pos) > + params.max_hear_distance) + continue; + } + dst_clients.push_back(client_id); + } + } + + if(dst_clients.empty()) + return -1; + + // old clients will still use this, so pick a reserved ID (-1) + const s32 id = ephemeral ? -1 : nextSoundId(); + + float gain = params.gain * params.spec.gain; + NetworkPacket pkt(TOCLIENT_PLAY_SOUND, 0); + pkt << id << params.spec.name << gain + << (u8) params.type << pos << params.object + << params.spec.loop << params.spec.fade << params.spec.pitch + << ephemeral; + + bool as_reliable = !ephemeral; + + for (const session_t peer_id : dst_clients) { + if (!ephemeral) + params.clients.insert(peer_id); + m_clients.send(peer_id, 0, &pkt, as_reliable); + } + + if (!ephemeral) + m_playing_sounds[id] = std::move(params); + return id; +} +void Server::stopSound(s32 handle) +{ + auto it = m_playing_sounds.find(handle); + if (it == m_playing_sounds.end()) + return; + + ServerPlayingSound &psound = it->second; + + NetworkPacket pkt(TOCLIENT_STOP_SOUND, 4); + pkt << handle; + + for (session_t peer_id : psound.clients) { + // Send as reliable + m_clients.send(peer_id, 0, &pkt, true); + } + + // Remove sound reference + m_playing_sounds.erase(it); +} + +void Server::fadeSound(s32 handle, float step, float gain) +{ + auto it = m_playing_sounds.find(handle); + if (it == m_playing_sounds.end()) + return; + + ServerPlayingSound &psound = it->second; + psound.gain = gain; // destination gain + + NetworkPacket pkt(TOCLIENT_FADE_SOUND, 4); + pkt << handle << step << gain; + + for (session_t peer_id : psound.clients) { + // Send as reliable + m_clients.send(peer_id, 0, &pkt, true); + } + + // Remove sound reference + if (gain <= 0 || psound.clients.empty()) + m_playing_sounds.erase(it); +} + +void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players, + float far_d_nodes) +{ + float maxd = far_d_nodes * BS; + v3f p_f = intToFloat(p, BS); + v3s16 block_pos = getNodeBlockPos(p); + + NetworkPacket pkt(TOCLIENT_REMOVENODE, 6); + pkt << p; + + std::vector<session_t> clients = m_clients.getClientIDs(); + ClientInterface::AutoLock clientlock(m_clients); + + for (session_t client_id : clients) { + RemoteClient *client = m_clients.lockedGetClientNoEx(client_id); + if (!client) + continue; + + RemotePlayer *player = m_env->getPlayer(client_id); + PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr; + + // If player is far away, only set modified blocks not sent + if (!client->isBlockSent(block_pos) || (sao && + sao->getBasePosition().getDistanceFrom(p_f) > maxd)) { + if (far_players) + far_players->emplace(client_id); + else + client->SetBlockNotSent(block_pos); + continue; + } + + // Send as reliable + m_clients.send(client_id, 0, &pkt, true); + } +} + +void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_players, + float far_d_nodes, bool remove_metadata) +{ + float maxd = far_d_nodes * BS; + v3f p_f = intToFloat(p, BS); + v3s16 block_pos = getNodeBlockPos(p); + + NetworkPacket pkt(TOCLIENT_ADDNODE, 6 + 2 + 1 + 1 + 1); + pkt << p << n.param0 << n.param1 << n.param2 + << (u8) (remove_metadata ? 0 : 1); + + std::vector<session_t> clients = m_clients.getClientIDs(); + ClientInterface::AutoLock clientlock(m_clients); + + for (session_t client_id : clients) { + RemoteClient *client = m_clients.lockedGetClientNoEx(client_id); + if (!client) + continue; + + RemotePlayer *player = m_env->getPlayer(client_id); + PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr; + + // If player is far away, only set modified blocks not sent + if (!client->isBlockSent(block_pos) || (sao && + sao->getBasePosition().getDistanceFrom(p_f) > maxd)) { + if (far_players) + far_players->emplace(client_id); + else + client->SetBlockNotSent(block_pos); + continue; + } + + // Send as reliable + m_clients.send(client_id, 0, &pkt, true); + } +} + +void Server::sendMetadataChanged(const std::unordered_set<v3s16> &positions, float far_d_nodes) +{ + NodeMetadataList meta_updates_list(false); + std::ostringstream os(std::ios::binary); + + std::vector<session_t> clients = m_clients.getClientIDs(); + ClientInterface::AutoLock clientlock(m_clients); + + for (session_t i : clients) { + RemoteClient *client = m_clients.lockedGetClientNoEx(i); + if (!client) + continue; + + ServerActiveObject *player = getPlayerSAO(i); + v3s16 player_pos; + if (player) + player_pos = floatToInt(player->getBasePosition(), BS); + + for (const v3s16 pos : positions) { + NodeMetadata *meta = m_env->getMap().getNodeMetadata(pos); + + if (!meta) + continue; + + v3s16 block_pos = getNodeBlockPos(pos); + if (!client->isBlockSent(block_pos) || + player_pos.getDistanceFrom(pos) > far_d_nodes) { + client->SetBlockNotSent(block_pos); + continue; + } + + // Add the change to send list + meta_updates_list.set(pos, meta); + } + if (meta_updates_list.size() == 0) + continue; + + // Send the meta changes + os.str(""); + meta_updates_list.serialize(os, client->serialization_version, false, true, true); + std::string raw = os.str(); + os.str(""); + compressZlib(raw, os); + + NetworkPacket pkt(TOCLIENT_NODEMETA_CHANGED, 0, i); + pkt.putLongString(os.str()); + Send(&pkt); + + meta_updates_list.clear(); + } +} + +void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver, + u16 net_proto_version, SerializedBlockCache *cache) +{ + thread_local const int net_compression_level = rangelim(g_settings->getS16("map_compression_level_net"), -1, 9); + std::string s, *sptr = nullptr; + + if (cache) { + auto it = cache->find({block->getPos(), ver}); + if (it != cache->end()) + sptr = &it->second; + } + + // Serialize the block in the right format + if (!sptr) { + std::ostringstream os(std::ios_base::binary); + block->serialize(os, ver, false, net_compression_level); + block->serializeNetworkSpecific(os); + s = os.str(); + sptr = &s; + } + + NetworkPacket pkt(TOCLIENT_BLOCKDATA, 2 + 2 + 2 + sptr->size(), peer_id); + pkt << block->getPos(); + pkt.putRawString(*sptr); + Send(&pkt); + + // Store away in cache + if (cache && sptr == &s) + (*cache)[{block->getPos(), ver}] = std::move(s); +} + +void Server::SendBlocks(float dtime) +{ + MutexAutoLock envlock(m_env_mutex); + //TODO check if one big lock could be faster then multiple small ones + + std::vector<PrioritySortedBlockTransfer> queue; + + u32 total_sending = 0, unique_clients = 0; + + { + ScopeProfiler sp2(g_profiler, "Server::SendBlocks(): Collect list"); + + std::vector<session_t> clients = m_clients.getClientIDs(); + + ClientInterface::AutoLock clientlock(m_clients); + for (const session_t client_id : clients) { + RemoteClient *client = m_clients.lockedGetClientNoEx(client_id, CS_Active); + + if (!client) + continue; + + total_sending += client->getSendingCount(); + const auto old_count = queue.size(); + client->GetNextBlocks(m_env,m_emerge, dtime, queue); + unique_clients += queue.size() > old_count ? 1 : 0; + } + } + + // Sort. + // Lowest priority number comes first. + // Lowest is most important. + std::sort(queue.begin(), queue.end()); + + ClientInterface::AutoLock clientlock(m_clients); + + // Maximal total count calculation + // The per-client block sends is halved with the maximal online users + u32 max_blocks_to_send = (m_env->getPlayerCount() + g_settings->getU32("max_users")) * + g_settings->getU32("max_simultaneous_block_sends_per_client") / 4 + 1; + + ScopeProfiler sp(g_profiler, "Server::SendBlocks(): Send to clients"); + Map &map = m_env->getMap(); + + SerializedBlockCache cache, *cache_ptr = nullptr; + if (unique_clients > 1) { + // caching is pointless with a single client + cache_ptr = &cache; + } + + for (const PrioritySortedBlockTransfer &block_to_send : queue) { + if (total_sending >= max_blocks_to_send) + break; + + MapBlock *block = map.getBlockNoCreateNoEx(block_to_send.pos); + if (!block) + continue; + + RemoteClient *client = m_clients.lockedGetClientNoEx(block_to_send.peer_id, + CS_Active); + if (!client) + continue; + + SendBlockNoLock(block_to_send.peer_id, block, client->serialization_version, + client->net_proto_version, cache_ptr); + + client->SentBlock(block_to_send.pos); + total_sending++; + } +} + +bool Server::SendBlock(session_t peer_id, const v3s16 &blockpos) +{ + MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos); + if (!block) + return false; + + ClientInterface::AutoLock clientlock(m_clients); + RemoteClient *client = m_clients.lockedGetClientNoEx(peer_id, CS_Active); + if (!client || client->isBlockSent(blockpos)) + return false; + SendBlockNoLock(peer_id, block, client->serialization_version, + client->net_proto_version); + + return true; +} + +bool Server::addMediaFile(const std::string &filename, + const std::string &filepath, std::string *filedata_to, + std::string *digest_to) +{ + // If name contains illegal characters, ignore the file + if (!string_allowed(filename, TEXTURENAME_ALLOWED_CHARS)) { + infostream << "Server: ignoring illegal file name: \"" + << filename << "\"" << std::endl; + return false; + } + // If name is not in a supported format, ignore it + const char *supported_ext[] = { + ".png", ".jpg", ".bmp", ".tga", + ".ogg", + ".x", ".b3d", ".obj", + // Custom translation file format + ".tr", + NULL + }; + if (removeStringEnd(filename, supported_ext).empty()) { + infostream << "Server: ignoring unsupported file extension: \"" + << filename << "\"" << std::endl; + return false; + } + // Ok, attempt to load the file and add to cache + + // Read data + std::string filedata; + if (!fs::ReadFile(filepath, filedata)) { + errorstream << "Server::addMediaFile(): Failed to open \"" + << filename << "\" for reading" << std::endl; + return false; + } + + if (filedata.empty()) { + errorstream << "Server::addMediaFile(): Empty file \"" + << filepath << "\"" << std::endl; + return false; + } + + SHA1 sha1; + sha1.addBytes(filedata.c_str(), filedata.length()); + + unsigned char *digest = sha1.getDigest(); + std::string sha1_base64 = base64_encode(digest, 20); + std::string sha1_hex = hex_encode((char*) digest, 20); + if (digest_to) + *digest_to = std::string((char*) digest, 20); + free(digest); + + // Put in list + m_media[filename] = MediaInfo(filepath, sha1_base64); + verbosestream << "Server: " << sha1_hex << " is " << filename + << std::endl; + + if (filedata_to) + *filedata_to = std::move(filedata); + return true; +} + +void Server::fillMediaCache() +{ + infostream << "Server: Calculating media file checksums" << std::endl; + + // Collect all media file paths + std::vector<std::string> paths; + + // ordered in descending priority + paths.push_back(getBuiltinLuaPath() + DIR_DELIM + "locale"); + fs::GetRecursiveDirs(paths, porting::path_user + DIR_DELIM + "textures" + DIR_DELIM + "server"); + fs::GetRecursiveDirs(paths, m_gamespec.path + DIR_DELIM + "textures"); + m_modmgr->getModsMediaPaths(paths); + + // Collect media file information from paths into cache + for (const std::string &mediapath : paths) { + std::vector<fs::DirListNode> dirlist = fs::GetDirListing(mediapath); + for (const fs::DirListNode &dln : dirlist) { + if (dln.dir) // Ignore dirs (already in paths) + continue; + + const std::string &filename = dln.name; + if (m_media.find(filename) != m_media.end()) // Do not override + continue; + + std::string filepath = mediapath; + filepath.append(DIR_DELIM).append(filename); + addMediaFile(filename, filepath); + } + } + + infostream << "Server: " << m_media.size() << " media files collected" << std::endl; +} + +void Server::sendMediaAnnouncement(session_t peer_id, const std::string &lang_code) +{ + // Make packet + NetworkPacket pkt(TOCLIENT_ANNOUNCE_MEDIA, 0, peer_id); + + u16 media_sent = 0; + std::string lang_suffix; + lang_suffix.append(".").append(lang_code).append(".tr"); + for (const auto &i : m_media) { + if (i.second.no_announce) + continue; + if (str_ends_with(i.first, ".tr") && !str_ends_with(i.first, lang_suffix)) + continue; + media_sent++; + } + + pkt << media_sent; + + for (const auto &i : m_media) { + if (i.second.no_announce) + continue; + if (str_ends_with(i.first, ".tr") && !str_ends_with(i.first, lang_suffix)) + continue; + pkt << i.first << i.second.sha1_digest; + } + + pkt << g_settings->get("remote_media"); + Send(&pkt); + + verbosestream << "Server: Announcing files to id(" << peer_id + << "): count=" << media_sent << " size=" << pkt.getSize() << std::endl; +} + +struct SendableMedia +{ + std::string name; + std::string path; + std::string data; + + SendableMedia(const std::string &name, const std::string &path, + std::string &&data): + name(name), path(path), data(std::move(data)) + {} +}; + +void Server::sendRequestedMedia(session_t peer_id, + const std::vector<std::string> &tosend) +{ + verbosestream<<"Server::sendRequestedMedia(): " + <<"Sending files to client"<<std::endl; + + /* Read files */ + + // Put 5kB in one bunch (this is not accurate) + u32 bytes_per_bunch = 5000; + + std::vector< std::vector<SendableMedia> > file_bunches; + file_bunches.emplace_back(); + + u32 file_size_bunch_total = 0; + + for (const std::string &name : tosend) { + if (m_media.find(name) == m_media.end()) { + errorstream<<"Server::sendRequestedMedia(): Client asked for " + <<"unknown file \""<<(name)<<"\""<<std::endl; + continue; + } + + const auto &m = m_media[name]; + + // Read data + std::string data; + if (!fs::ReadFile(m.path, data)) { + errorstream << "Server::sendRequestedMedia(): Failed to read \"" + << name << "\"" << std::endl; + continue; + } + file_size_bunch_total += data.size(); + + // Put in list + file_bunches.back().emplace_back(name, m.path, std::move(data)); + + // Start next bunch if got enough data + if(file_size_bunch_total >= bytes_per_bunch) { + file_bunches.emplace_back(); + file_size_bunch_total = 0; + } + + } + + /* Create and send packets */ + + u16 num_bunches = file_bunches.size(); + for (u16 i = 0; i < num_bunches; i++) { + /* + u16 command + u16 total number of texture bunches + u16 index of this bunch + u32 number of files in this bunch + for each file { + u16 length of name + string name + u32 length of data + data + } + */ + + NetworkPacket pkt(TOCLIENT_MEDIA, 4 + 0, peer_id); + pkt << num_bunches << i << (u32) file_bunches[i].size(); + + for (const SendableMedia &j : file_bunches[i]) { + pkt << j.name; + pkt.putLongString(j.data); + } + + verbosestream << "Server::sendRequestedMedia(): bunch " + << i << "/" << num_bunches + << " files=" << file_bunches[i].size() + << " size=" << pkt.getSize() << std::endl; + Send(&pkt); + } +} + +void Server::stepPendingDynMediaCallbacks(float dtime) +{ + MutexAutoLock lock(m_env_mutex); + + for (auto it = m_pending_dyn_media.begin(); it != m_pending_dyn_media.end();) { + it->second.expiry_timer -= dtime; + bool del = it->second.waiting_players.empty() || it->second.expiry_timer < 0; + + if (!del) { + it++; + continue; + } + + const auto &name = it->second.filename; + if (!name.empty()) { + assert(m_media.count(name)); + // if no_announce isn't set we're definitely deleting the wrong file! + sanity_check(m_media[name].no_announce); + + fs::DeleteSingleFileOrEmptyDirectory(m_media[name].path); + m_media.erase(name); + } + getScriptIface()->freeDynamicMediaCallback(it->first); + it = m_pending_dyn_media.erase(it); + } +} + +void Server::SendMinimapModes(session_t peer_id, + std::vector<MinimapMode> &modes, size_t wanted_mode) +{ + RemotePlayer *player = m_env->getPlayer(peer_id); + assert(player); + if (player->getPeerId() == PEER_ID_INEXISTENT) + return; + + NetworkPacket pkt(TOCLIENT_MINIMAP_MODES, 0, peer_id); + pkt << (u16)modes.size() << (u16)wanted_mode; + + for (auto &mode : modes) + pkt << (u16)mode.type << mode.label << mode.size << mode.texture << mode.scale; + + Send(&pkt); +} + +void Server::sendDetachedInventory(Inventory *inventory, const std::string &name, session_t peer_id) +{ + NetworkPacket pkt(TOCLIENT_DETACHED_INVENTORY, 0, peer_id); + pkt << name; + + if (!inventory) { + pkt << false; // Remove inventory + } else { + pkt << true; // Update inventory + + // Serialization & NetworkPacket isn't a love story + std::ostringstream os(std::ios_base::binary); + inventory->serialize(os); + inventory->setModified(false); + + const std::string &os_str = os.str(); + pkt << static_cast<u16>(os_str.size()); // HACK: to keep compatibility with 5.0.0 clients + pkt.putRawString(os_str); + } + + if (peer_id == PEER_ID_INEXISTENT) + m_clients.sendToAll(&pkt); + else + Send(&pkt); +} + +void Server::sendDetachedInventories(session_t peer_id, bool incremental) +{ + // Lookup player name, to filter detached inventories just after + std::string peer_name; + if (peer_id != PEER_ID_INEXISTENT) { + peer_name = getClient(peer_id, CS_Created)->getName(); + } + + auto send_cb = [this, peer_id](const std::string &name, Inventory *inv) { + sendDetachedInventory(inv, name, peer_id); + }; + + m_inventory_mgr->sendDetachedInventories(peer_name, incremental, send_cb); +} + +/* + Something random +*/ + +void Server::HandlePlayerDeath(PlayerSAO *playersao, const PlayerHPChangeReason &reason) +{ + infostream << "Server::DiePlayer(): Player " + << playersao->getPlayer()->getName() + << " dies" << std::endl; + + playersao->clearParentAttachment(); + + // Trigger scripted stuff + m_script->on_dieplayer(playersao, reason); + + SendDeathscreen(playersao->getPeerID(), false, v3f(0,0,0)); +} + +void Server::RespawnPlayer(session_t peer_id) +{ + PlayerSAO *playersao = getPlayerSAO(peer_id); + assert(playersao); + + infostream << "Server::RespawnPlayer(): Player " + << playersao->getPlayer()->getName() + << " respawns" << std::endl; + + const auto *prop = playersao->accessObjectProperties(); + playersao->setHP(prop->hp_max, + PlayerHPChangeReason(PlayerHPChangeReason::RESPAWN)); + playersao->setBreath(prop->breath_max); + + bool repositioned = m_script->on_respawnplayer(playersao); + if (!repositioned) { + // setPos will send the new position to client + playersao->setPos(findSpawnPos()); + } +} + + +void Server::DenySudoAccess(session_t peer_id) +{ + NetworkPacket pkt(TOCLIENT_DENY_SUDO_MODE, 0, peer_id); + Send(&pkt); +} + + +void Server::DenyAccess(session_t peer_id, AccessDeniedCode reason, + const std::string &custom_reason, bool reconnect) +{ + SendAccessDenied(peer_id, reason, custom_reason, reconnect); + m_clients.event(peer_id, CSE_SetDenied); + DisconnectPeer(peer_id); +} + +void Server::DisconnectPeer(session_t peer_id) +{ + m_modchannel_mgr->leaveAllChannels(peer_id); + m_con->DisconnectPeer(peer_id); +} + +void Server::acceptAuth(session_t peer_id, bool forSudoMode) +{ + if (!forSudoMode) { + RemoteClient* client = getClient(peer_id, CS_Invalid); + + NetworkPacket resp_pkt(TOCLIENT_AUTH_ACCEPT, 1 + 6 + 8 + 4, peer_id); + + // Right now, the auth mechs don't change between login and sudo mode. + u32 sudo_auth_mechs = client->allowed_auth_mechs; + client->allowed_sudo_mechs = sudo_auth_mechs; + + resp_pkt << v3f(0,0,0) << (u64) m_env->getServerMap().getSeed() + << g_settings->getFloat("dedicated_server_step") + << sudo_auth_mechs; + + Send(&resp_pkt); + m_clients.event(peer_id, CSE_AuthAccept); + } else { + NetworkPacket resp_pkt(TOCLIENT_ACCEPT_SUDO_MODE, 1 + 6 + 8 + 4, peer_id); + + // We only support SRP right now + u32 sudo_auth_mechs = AUTH_MECHANISM_FIRST_SRP; + + resp_pkt << sudo_auth_mechs; + Send(&resp_pkt); + m_clients.event(peer_id, CSE_SudoSuccess); + } +} + +void Server::DeleteClient(session_t peer_id, ClientDeletionReason reason) +{ + std::wstring message; + { + /* + Clear references to playing sounds + */ + for (std::unordered_map<s32, ServerPlayingSound>::iterator + i = m_playing_sounds.begin(); i != m_playing_sounds.end();) { + ServerPlayingSound &psound = i->second; + psound.clients.erase(peer_id); + if (psound.clients.empty()) + m_playing_sounds.erase(i++); + else + ++i; + } + + // clear formspec info so the next client can't abuse the current state + m_formspec_state_data.erase(peer_id); + + RemotePlayer *player = m_env->getPlayer(peer_id); + + /* Run scripts and remove from environment */ + if (player) { + PlayerSAO *playersao = player->getPlayerSAO(); + assert(playersao); + + playersao->clearChildAttachments(); + playersao->clearParentAttachment(); + + // inform connected clients + const std::string &player_name = player->getName(); + NetworkPacket notice(TOCLIENT_UPDATE_PLAYER_LIST, 0, PEER_ID_INEXISTENT); + // (u16) 1 + std::string represents a vector serialization representation + notice << (u8) PLAYER_LIST_REMOVE << (u16) 1 << player_name; + m_clients.sendToAll(¬ice); + // run scripts + m_script->on_leaveplayer(playersao, reason == CDR_TIMEOUT); + + playersao->disconnected(); + } + + /* + Print out action + */ + { + if (player && reason != CDR_DENY) { + std::ostringstream os(std::ios_base::binary); + std::vector<session_t> clients = m_clients.getClientIDs(); + + for (const session_t client_id : clients) { + // Get player + RemotePlayer *player = m_env->getPlayer(client_id); + if (!player) + continue; + + // Get name of player + os << player->getName() << " "; + } + + std::string name = player->getName(); + actionstream << name << " " + << (reason == CDR_TIMEOUT ? "times out." : "leaves game.") + << " List of players: " << os.str() << std::endl; + if (m_admin_chat) + m_admin_chat->outgoing_queue.push_back( + new ChatEventNick(CET_NICK_REMOVE, name)); + } + } + { + MutexAutoLock env_lock(m_env_mutex); + m_clients.DeleteClient(peer_id); + } + } + + // Send leave chat message to all remaining clients + if (!message.empty()) { + SendChatMessage(PEER_ID_INEXISTENT, + ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE, message)); + } +} + +void Server::UpdateCrafting(RemotePlayer *player) +{ + InventoryList *clist = player->inventory.getList("craft"); + if (!clist || clist->getSize() == 0) + return; + + if (!clist->checkModified()) + return; + + // Get a preview for crafting + ItemStack preview; + InventoryLocation loc; + loc.setPlayer(player->getName()); + std::vector<ItemStack> output_replacements; + getCraftingResult(&player->inventory, preview, output_replacements, false, this); + m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(), + clist, loc); + + InventoryList *plist = player->inventory.getList("craftpreview"); + if (plist && plist->getSize() >= 1) { + // Put the new preview in + plist->changeItem(0, preview); + } +} + +void Server::handleChatInterfaceEvent(ChatEvent *evt) +{ + if (evt->type == CET_NICK_ADD) { + // The terminal informed us of its nick choice + m_admin_nick = ((ChatEventNick *)evt)->nick; + if (!m_script->getAuth(m_admin_nick, NULL, NULL)) { + errorstream << "You haven't set up an account." << std::endl + << "Please log in using the client as '" + << m_admin_nick << "' with a secure password." << std::endl + << "Until then, you can't execute admin tasks via the console," << std::endl + << "and everybody can claim the user account instead of you," << std::endl + << "giving them full control over this server." << std::endl; + } + } else { + assert(evt->type == CET_CHAT); + handleAdminChat((ChatEventChat *)evt); + } +} + +std::wstring Server::handleChat(const std::string &name, + std::wstring wmessage, bool check_shout_priv, RemotePlayer *player) +{ + // If something goes wrong, this player is to blame + RollbackScopeActor rollback_scope(m_rollback, + std::string("player:") + name); + + if (g_settings->getBool("strip_color_codes")) + wmessage = unescape_enriched(wmessage); + + if (player) { + switch (player->canSendChatMessage()) { + case RPLAYER_CHATRESULT_FLOODING: { + std::wstringstream ws; + ws << L"You cannot send more messages. You are limited to " + << g_settings->getFloat("chat_message_limit_per_10sec") + << L" messages per 10 seconds."; + return ws.str(); + } + case RPLAYER_CHATRESULT_KICK: + DenyAccess(player->getPeerId(), SERVER_ACCESSDENIED_CUSTOM_STRING, + "You have been kicked due to message flooding."); + return L""; + case RPLAYER_CHATRESULT_OK: + break; + default: + FATAL_ERROR("Unhandled chat filtering result found."); + } + } + + if (m_max_chatmessage_length > 0 + && wmessage.length() > m_max_chatmessage_length) { + return L"Your message exceed the maximum chat message limit set on the server. " + L"It was refused. Send a shorter message"; + } + + auto message = trim(wide_to_utf8(wmessage)); + if (message.empty()) + return L""; + + if (message.find_first_of("\n\r") != std::wstring::npos) { + return L"Newlines are not permitted in chat messages"; + } + + // Run script hook, exit if script ate the chat message + if (m_script->on_chat_message(name, message)) + return L""; + + // Line to send + std::wstring line; + // Whether to send line to the player that sent the message, or to all players + bool broadcast_line = true; + + if (check_shout_priv && !checkPriv(name, "shout")) { + line += L"-!- You don't have permission to shout."; + broadcast_line = false; + } else { + /* + Workaround for fixing chat on Android. Lua doesn't handle + the Cyrillic alphabet and some characters on older Android devices + */ +#ifdef __ANDROID__ + line += L"<" + utf8_to_wide(name) + L"> " + wmessage; +#else + line += utf8_to_wide(m_script->formatChatMessage(name, + wide_to_utf8(wmessage))); +#endif + } + + /* + Tell calling method to send the message to sender + */ + if (!broadcast_line) + return line; + + /* + Send the message to others + */ + actionstream << "CHAT: " << wide_to_utf8(unescape_enriched(line)) << std::endl; + + ChatMessage chatmsg(line); + + std::vector<session_t> clients = m_clients.getClientIDs(); + for (u16 cid : clients) + SendChatMessage(cid, chatmsg); + + return L""; +} + +void Server::handleAdminChat(const ChatEventChat *evt) +{ + std::string name = evt->nick; + std::wstring wmessage = evt->evt_msg; + + std::wstring answer = handleChat(name, wmessage); + + // If asked to send answer to sender + if (!answer.empty()) { + m_admin_chat->outgoing_queue.push_back(new ChatEventChat("", answer)); + } +} + +RemoteClient *Server::getClient(session_t peer_id, ClientState state_min) +{ + RemoteClient *client = getClientNoEx(peer_id,state_min); + if(!client) + throw ClientNotFoundException("Client not found"); + + return client; +} +RemoteClient *Server::getClientNoEx(session_t peer_id, ClientState state_min) +{ + return m_clients.getClientNoEx(peer_id, state_min); +} + +std::string Server::getPlayerName(session_t peer_id) +{ + RemotePlayer *player = m_env->getPlayer(peer_id); + if (!player) + return "[id="+itos(peer_id)+"]"; + return player->getName(); +} + +PlayerSAO *Server::getPlayerSAO(session_t peer_id) +{ + RemotePlayer *player = m_env->getPlayer(peer_id); + if (!player) + return NULL; + return player->getPlayerSAO(); +} + +std::string Server::getStatusString() +{ + std::ostringstream os(std::ios_base::binary); + os << "# Server: "; + // Version + os << "version: " << g_version_string; + // Game + os << " | game: " << (m_gamespec.title.empty() ? m_gamespec.id : m_gamespec.title); + // Uptime + os << " | uptime: " << duration_to_string((int) m_uptime_counter->get()); + // Max lag estimate + os << " | max lag: " << std::setprecision(3); + os << (m_env ? m_env->getMaxLagEstimate() : 0) << "s"; + + // Information about clients + bool first = true; + os << " | clients: "; + if (m_env) { + std::vector<session_t> clients = m_clients.getClientIDs(); + for (session_t client_id : clients) { + RemotePlayer *player = m_env->getPlayer(client_id); + + // Get name of player + const char *name = player ? player->getName() : "<unknown>"; + + // Add name to information string + if (!first) + os << ", "; + else + first = false; + os << name; + } + } + + if (m_env && !((ServerMap*)(&m_env->getMap()))->isSavingEnabled()) + os << std::endl << "# Server: " << " WARNING: Map saving is disabled."; + + if (!g_settings->get("motd").empty()) + os << std::endl << "# Server: " << g_settings->get("motd"); + + return os.str(); +} + +std::set<std::string> Server::getPlayerEffectivePrivs(const std::string &name) +{ + std::set<std::string> privs; + m_script->getAuth(name, NULL, &privs); + return privs; +} + +bool Server::checkPriv(const std::string &name, const std::string &priv) +{ + std::set<std::string> privs = getPlayerEffectivePrivs(name); + return (privs.count(priv) != 0); +} + +void Server::reportPrivsModified(const std::string &name) +{ + if (name.empty()) { + std::vector<session_t> clients = m_clients.getClientIDs(); + for (const session_t client_id : clients) { + RemotePlayer *player = m_env->getPlayer(client_id); + reportPrivsModified(player->getName()); + } + } else { + RemotePlayer *player = m_env->getPlayer(name.c_str()); + if (!player) + return; + SendPlayerPrivileges(player->getPeerId()); + PlayerSAO *sao = player->getPlayerSAO(); + if(!sao) + return; + sao->updatePrivileges( + getPlayerEffectivePrivs(name), + isSingleplayer()); + } +} + +void Server::reportInventoryFormspecModified(const std::string &name) +{ + RemotePlayer *player = m_env->getPlayer(name.c_str()); + if (!player) + return; + SendPlayerInventoryFormspec(player->getPeerId()); +} + +void Server::reportFormspecPrependModified(const std::string &name) +{ + RemotePlayer *player = m_env->getPlayer(name.c_str()); + if (!player) + return; + SendPlayerFormspecPrepend(player->getPeerId()); +} + +void Server::setIpBanned(const std::string &ip, const std::string &name) +{ + m_banmanager->add(ip, name); +} + +void Server::unsetIpBanned(const std::string &ip_or_name) +{ + m_banmanager->remove(ip_or_name); +} + +std::string Server::getBanDescription(const std::string &ip_or_name) +{ + return m_banmanager->getBanDescription(ip_or_name); +} + +void Server::notifyPlayer(const char *name, const std::wstring &msg) +{ + // m_env will be NULL if the server is initializing + if (!m_env) + return; + + if (m_admin_nick == name && !m_admin_nick.empty()) { + m_admin_chat->outgoing_queue.push_back(new ChatEventChat("", msg)); + } + + RemotePlayer *player = m_env->getPlayer(name); + if (!player) { + return; + } + + if (player->getPeerId() == PEER_ID_INEXISTENT) + return; + + SendChatMessage(player->getPeerId(), ChatMessage(msg)); +} + +bool Server::showFormspec(const char *playername, const std::string &formspec, + const std::string &formname) +{ + // m_env will be NULL if the server is initializing + if (!m_env) + return false; + + RemotePlayer *player = m_env->getPlayer(playername); + if (!player) + return false; + + SendShowFormspecMessage(player->getPeerId(), formspec, formname); + return true; +} + +u32 Server::hudAdd(RemotePlayer *player, HudElement *form) +{ + if (!player) + return -1; + + u32 id = player->addHud(form); + + SendHUDAdd(player->getPeerId(), id, form); + + return id; +} + +bool Server::hudRemove(RemotePlayer *player, u32 id) { + if (!player) + return false; + + HudElement* todel = player->removeHud(id); + + if (!todel) + return false; + + delete todel; + + SendHUDRemove(player->getPeerId(), id); + return true; +} + +bool Server::hudChange(RemotePlayer *player, u32 id, HudElementStat stat, void *data) +{ + if (!player) + return false; + + SendHUDChange(player->getPeerId(), id, stat, data); + return true; +} + +bool Server::hudSetFlags(RemotePlayer *player, u32 flags, u32 mask) +{ + if (!player) + return false; + + u32 new_hud_flags = (player->hud_flags & ~mask) | flags; + if (new_hud_flags == player->hud_flags) // no change + return true; + + SendHUDSetFlags(player->getPeerId(), flags, mask); + player->hud_flags = new_hud_flags; + + PlayerSAO* playersao = player->getPlayerSAO(); + + if (!playersao) + return false; + + m_script->player_event(playersao, "hud_changed"); + return true; +} + +bool Server::hudSetHotbarItemcount(RemotePlayer *player, s32 hotbar_itemcount) +{ + if (!player) + return false; + + if (hotbar_itemcount <= 0 || hotbar_itemcount > HUD_HOTBAR_ITEMCOUNT_MAX) + return false; + + player->setHotbarItemcount(hotbar_itemcount); + std::ostringstream os(std::ios::binary); + writeS32(os, hotbar_itemcount); + SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_ITEMCOUNT, os.str()); + return true; +} + +void Server::hudSetHotbarImage(RemotePlayer *player, const std::string &name) +{ + if (!player) + return; + + player->setHotbarImage(name); + SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_IMAGE, name); +} + +void Server::hudSetHotbarSelectedImage(RemotePlayer *player, const std::string &name) +{ + if (!player) + return; + + player->setHotbarSelectedImage(name); + SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_SELECTED_IMAGE, name); +} + +Address Server::getPeerAddress(session_t peer_id) +{ + // Note that this is only set after Init was received in Server::handleCommand_Init + return getClient(peer_id, CS_Invalid)->getAddress(); +} + +void Server::setLocalPlayerAnimations(RemotePlayer *player, + v2s32 animation_frames[4], f32 frame_speed) +{ + sanity_check(player); + player->setLocalAnimations(animation_frames, frame_speed); + SendLocalPlayerAnimations(player->getPeerId(), animation_frames, frame_speed); +} + +void Server::setPlayerEyeOffset(RemotePlayer *player, const v3f &first, const v3f &third) +{ + sanity_check(player); + player->eye_offset_first = first; + player->eye_offset_third = third; + SendEyeOffset(player->getPeerId(), first, third); +} + +void Server::setSky(RemotePlayer *player, const SkyboxParams ¶ms) +{ + sanity_check(player); + player->setSky(params); + SendSetSky(player->getPeerId(), params); +} + +void Server::setSun(RemotePlayer *player, const SunParams ¶ms) +{ + sanity_check(player); + player->setSun(params); + SendSetSun(player->getPeerId(), params); +} + +void Server::setMoon(RemotePlayer *player, const MoonParams ¶ms) +{ + sanity_check(player); + player->setMoon(params); + SendSetMoon(player->getPeerId(), params); +} + +void Server::setStars(RemotePlayer *player, const StarParams ¶ms) +{ + sanity_check(player); + player->setStars(params); + SendSetStars(player->getPeerId(), params); +} + +void Server::setClouds(RemotePlayer *player, const CloudParams ¶ms) +{ + sanity_check(player); + player->setCloudParams(params); + SendCloudParams(player->getPeerId(), params); +} + +void Server::overrideDayNightRatio(RemotePlayer *player, bool do_override, + float ratio) +{ + sanity_check(player); + player->overrideDayNightRatio(do_override, ratio); + SendOverrideDayNightRatio(player->getPeerId(), do_override, ratio); +} + +void Server::setLighting(RemotePlayer *player, const Lighting &lighting) +{ + sanity_check(player); + player->setLighting(lighting); + SendSetLighting(player->getPeerId(), lighting); +} + +void Server::notifyPlayers(const std::wstring &msg) +{ + SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(msg)); +} + +void Server::spawnParticle(const std::string &playername, + const ParticleParameters &p) +{ + // m_env will be NULL if the server is initializing + if (!m_env) + return; + + session_t peer_id = PEER_ID_INEXISTENT; + u16 proto_ver = 0; + if (!playername.empty()) { + RemotePlayer *player = m_env->getPlayer(playername.c_str()); + if (!player) + return; + peer_id = player->getPeerId(); + proto_ver = player->protocol_version; + } + + SendSpawnParticle(peer_id, proto_ver, p); +} + +u32 Server::addParticleSpawner(const ParticleSpawnerParameters &p, + ServerActiveObject *attached, const std::string &playername) +{ + // m_env will be NULL if the server is initializing + if (!m_env) + return -1; + + session_t peer_id = PEER_ID_INEXISTENT; + u16 proto_ver = 0; + if (!playername.empty()) { + RemotePlayer *player = m_env->getPlayer(playername.c_str()); + if (!player) + return -1; + peer_id = player->getPeerId(); + proto_ver = player->protocol_version; + } + + u16 attached_id = attached ? attached->getId() : 0; + + u32 id; + if (attached_id == 0) + id = m_env->addParticleSpawner(p.time); + else + id = m_env->addParticleSpawner(p.time, attached_id); + + SendAddParticleSpawner(peer_id, proto_ver, p, attached_id, id); + return id; +} + +void Server::deleteParticleSpawner(const std::string &playername, u32 id) +{ + // m_env will be NULL if the server is initializing + if (!m_env) + throw ServerError("Can't delete particle spawners during initialisation!"); + + session_t peer_id = PEER_ID_INEXISTENT; + if (!playername.empty()) { + RemotePlayer *player = m_env->getPlayer(playername.c_str()); + if (!player) + return; + peer_id = player->getPeerId(); + } + + m_env->deleteParticleSpawner(id); + SendDeleteParticleSpawner(peer_id, id); +} + +bool Server::dynamicAddMedia(std::string filepath, + const u32 token, const std::string &to_player, bool ephemeral) +{ + std::string filename = fs::GetFilenameFromPath(filepath.c_str()); + auto it = m_media.find(filename); + if (it != m_media.end()) { + // Allow the same path to be "added" again in certain conditions + if (ephemeral || it->second.path != filepath) { + errorstream << "Server::dynamicAddMedia(): file \"" << filename + << "\" already exists in media cache" << std::endl; + return false; + } + } + + // Load the file and add it to our media cache + std::string filedata, raw_hash; + bool ok = addMediaFile(filename, filepath, &filedata, &raw_hash); + if (!ok) + return false; + + if (ephemeral) { + // Create a copy of the file and swap out the path, this removes the + // requirement that mods keep the file accessible at the original path. + filepath = fs::CreateTempFile(); + bool ok = ([&] () -> bool { + if (filepath.empty()) + return false; + std::ofstream os(filepath.c_str(), std::ios::binary); + if (!os.good()) + return false; + os << filedata; + os.close(); + return !os.fail(); + })(); + if (!ok) { + errorstream << "Server: failed to create a copy of media file " + << "\"" << filename << "\"" << std::endl; + m_media.erase(filename); + return false; + } + verbosestream << "Server: \"" << filename << "\" temporarily copied to " + << filepath << std::endl; + + m_media[filename].path = filepath; + m_media[filename].no_announce = true; + // stepPendingDynMediaCallbacks will clean this up later. + } else if (!to_player.empty()) { + m_media[filename].no_announce = true; + } + + // Push file to existing clients + NetworkPacket pkt(TOCLIENT_MEDIA_PUSH, 0); + pkt << raw_hash << filename << (bool)ephemeral; + + NetworkPacket legacy_pkt = pkt; + + // Newer clients get asked to fetch the file (asynchronous) + pkt << token; + // Older clients have an awful hack that just throws the data at them + legacy_pkt.putLongString(filedata); + + std::unordered_set<session_t> delivered, waiting; + { + ClientInterface::AutoLock clientlock(m_clients); + for (auto &pair : m_clients.getClientList()) { + if (pair.second->getState() == CS_DefinitionsSent && !ephemeral) { + /* + If a client is in the DefinitionsSent state it is too late to + transfer the file via sendMediaAnnouncement() but at the same + time the client cannot accept a media push yet. + Short of artificially delaying the joining process there is no + way for the server to resolve this so we (currently) opt not to. + */ + warningstream << "The media \"" << filename << "\" (dynamic) could " + "not be delivered to " << pair.second->getName() + << " due to a race condition." << std::endl; + continue; + } + if (pair.second->getState() < CS_Active) + continue; + + const auto proto_ver = pair.second->net_proto_version; + if (proto_ver < 39) + continue; + + const session_t peer_id = pair.second->peer_id; + if (!to_player.empty() && getPlayerName(peer_id) != to_player) + continue; + + if (proto_ver < 40) { + delivered.emplace(peer_id); + /* + The network layer only guarantees ordered delivery inside a channel. + Since the very next packet could be one that uses the media, we have + to push the media over ALL channels to ensure it is processed before + it is used. In practice this means channels 1 and 0. + */ + m_clients.send(peer_id, 1, &legacy_pkt, true); + m_clients.send(peer_id, 0, &legacy_pkt, true); + } else { + waiting.emplace(peer_id); + Send(peer_id, &pkt); + } + } + } + + // Run callback for players that already had the file delivered (legacy-only) + for (session_t peer_id : delivered) { + if (auto player = m_env->getPlayer(peer_id)) + getScriptIface()->on_dynamic_media_added(token, player->getName()); + } + + // Save all others in our pending state + auto &state = m_pending_dyn_media[token]; + state.waiting_players = std::move(waiting); + // regardless of success throw away the callback after a while + state.expiry_timer = 60.0f; + if (ephemeral) + state.filename = filename; + + return true; +} + +// actions: time-reversed list +// Return value: success/failure +bool Server::rollbackRevertActions(const std::list<RollbackAction> &actions, + std::list<std::string> *log) +{ + infostream<<"Server::rollbackRevertActions(len="<<actions.size()<<")"<<std::endl; + ServerMap *map = (ServerMap*)(&m_env->getMap()); + + // Fail if no actions to handle + if (actions.empty()) { + assert(log); + log->push_back("Nothing to do."); + return false; + } + + int num_tried = 0; + int num_failed = 0; + + for (const RollbackAction &action : actions) { + num_tried++; + bool success = action.applyRevert(map, m_inventory_mgr.get(), this); + if(!success){ + num_failed++; + std::ostringstream os; + os<<"Revert of step ("<<num_tried<<") "<<action.toString()<<" failed"; + infostream<<"Map::rollbackRevertActions(): "<<os.str()<<std::endl; + if (log) + log->push_back(os.str()); + }else{ + std::ostringstream os; + os<<"Successfully reverted step ("<<num_tried<<") "<<action.toString(); + infostream<<"Map::rollbackRevertActions(): "<<os.str()<<std::endl; + if (log) + log->push_back(os.str()); + } + } + + infostream<<"Map::rollbackRevertActions(): "<<num_failed<<"/"<<num_tried + <<" failed"<<std::endl; + + // Call it done if less than half failed + return num_failed <= num_tried/2; +} + +// IGameDef interface +// Under envlock +IItemDefManager *Server::getItemDefManager() +{ + return m_itemdef; +} + +const NodeDefManager *Server::getNodeDefManager() +{ + return m_nodedef; +} + +ICraftDefManager *Server::getCraftDefManager() +{ + return m_craftdef; +} + +u16 Server::allocateUnknownNodeId(const std::string &name) +{ + return m_nodedef->allocateDummy(name); +} + +IWritableItemDefManager *Server::getWritableItemDefManager() +{ + return m_itemdef; +} + +NodeDefManager *Server::getWritableNodeDefManager() +{ + return m_nodedef; +} + +IWritableCraftDefManager *Server::getWritableCraftDefManager() +{ + return m_craftdef; +} + +const std::vector<ModSpec> & Server::getMods() const +{ + return m_modmgr->getMods(); +} + +const ModSpec *Server::getModSpec(const std::string &modname) const +{ + return m_modmgr->getModSpec(modname); +} + +std::string Server::getBuiltinLuaPath() +{ + return porting::path_share + DIR_DELIM + "builtin"; +} + +v3f Server::findSpawnPos() +{ + ServerMap &map = m_env->getServerMap(); + v3f nodeposf; + if (g_settings->getV3FNoEx("static_spawnpoint", nodeposf)) + return nodeposf * BS; + + bool is_good = false; + // Limit spawn range to mapgen edges (determined by 'mapgen_limit') + s32 range_max = map.getMapgenParams()->getSpawnRangeMax(); + + // Try to find a good place a few times + for (s32 i = 0; i < 4000 && !is_good; i++) { + s32 range = MYMIN(1 + i, range_max); + // We're going to try to throw the player to this position + v2s16 nodepos2d = v2s16( + -range + myrand_range(0, range*2), + -range + myrand_range(0, range*2)); + // Get spawn level at point + s16 spawn_level = m_emerge->getSpawnLevelAtPoint(nodepos2d); + // Continue if MAX_MAP_GENERATION_LIMIT was returned by the mapgen to + // signify an unsuitable spawn position, or if outside limits. + if (spawn_level >= MAX_MAP_GENERATION_LIMIT || + spawn_level <= -MAX_MAP_GENERATION_LIMIT) + continue; + + v3s16 nodepos(nodepos2d.X, spawn_level, nodepos2d.Y); + // Consecutive empty nodes + s32 air_count = 0; + + // Search upwards from 'spawn level' for 2 consecutive empty nodes, to + // avoid obstructions in already-generated mapblocks. + // In ungenerated mapblocks consisting of 'ignore' nodes, there will be + // no obstructions, but mapgen decorations are generated after spawn so + // the player may end up inside one. + for (s32 i = 0; i < 8; i++) { + v3s16 blockpos = getNodeBlockPos(nodepos); + map.emergeBlock(blockpos, true); + content_t c = map.getNode(nodepos).getContent(); + + // In generated mapblocks allow spawn in all 'airlike' drawtype nodes. + // In ungenerated mapblocks allow spawn in 'ignore' nodes. + if (m_nodedef->get(c).drawtype == NDT_AIRLIKE || c == CONTENT_IGNORE) { + air_count++; + if (air_count >= 2) { + // Spawn in lower empty node + nodepos.Y--; + nodeposf = intToFloat(nodepos, BS); + // Don't spawn the player outside map boundaries + if (objectpos_over_limit(nodeposf)) + // Exit this loop, positions above are probably over limit + break; + + // Good position found, cause an exit from main loop + is_good = true; + break; + } + } else { + air_count = 0; + } + nodepos.Y++; + } + } + + if (is_good) + return nodeposf; + + // No suitable spawn point found, return fallback 0,0,0 + return v3f(0.0f, 0.0f, 0.0f); +} + +void Server::requestShutdown(const std::string &msg, bool reconnect, float delay) +{ + if (delay == 0.0f) { + // No delay, shutdown immediately + m_shutdown_state.is_requested = true; + // only print to the infostream, a chat message saying + // "Server Shutting Down" is sent when the server destructs. + infostream << "*** Immediate Server shutdown requested." << std::endl; + } else if (delay < 0.0f && m_shutdown_state.isTimerRunning()) { + // Negative delay, cancel shutdown if requested + m_shutdown_state.reset(); + std::wstringstream ws; + + ws << L"*** Server shutdown canceled."; + + infostream << wide_to_utf8(ws.str()).c_str() << std::endl; + SendChatMessage(PEER_ID_INEXISTENT, ws.str()); + // m_shutdown_* are already handled, skip. + return; + } else if (delay > 0.0f) { + // Positive delay, tell the clients when the server will shut down + std::wstringstream ws; + + ws << L"*** Server shutting down in " + << duration_to_string(myround(delay)).c_str() + << "."; + + infostream << wide_to_utf8(ws.str()).c_str() << std::endl; + SendChatMessage(PEER_ID_INEXISTENT, ws.str()); + } + + m_shutdown_state.trigger(delay, msg, reconnect); +} + +PlayerSAO* Server::emergePlayer(const char *name, session_t peer_id, u16 proto_version) +{ + /* + Try to get an existing player + */ + RemotePlayer *player = m_env->getPlayer(name); + + // If player is already connected, cancel + if (player && player->getPeerId() != PEER_ID_INEXISTENT) { + infostream<<"emergePlayer(): Player already connected"<<std::endl; + return NULL; + } + + /* + If player with the wanted peer_id already exists, cancel. + */ + if (m_env->getPlayer(peer_id)) { + infostream<<"emergePlayer(): Player with wrong name but same" + " peer_id already exists"<<std::endl; + return NULL; + } + + if (!player) { + player = new RemotePlayer(name, idef()); + } + + bool newplayer = false; + + // Load player + PlayerSAO *playersao = m_env->loadPlayer(player, &newplayer, peer_id, isSingleplayer()); + + // Complete init with server parts + playersao->finalize(player, getPlayerEffectivePrivs(player->getName())); + player->protocol_version = proto_version; + + /* Run scripts */ + if (newplayer) { + m_script->on_newplayer(playersao); + } + + return playersao; +} + +bool Server::registerModStorage(ModMetadata *storage) +{ + if (m_mod_storages.find(storage->getModName()) != m_mod_storages.end()) { + errorstream << "Unable to register same mod storage twice. Storage name: " + << storage->getModName() << std::endl; + return false; + } + + m_mod_storages[storage->getModName()] = storage; + return true; +} + +void Server::unregisterModStorage(const std::string &name) +{ + std::unordered_map<std::string, ModMetadata *>::const_iterator it = m_mod_storages.find(name); + if (it != m_mod_storages.end()) + m_mod_storages.erase(name); +} + +void dedicated_server_loop(Server &server, bool &kill) +{ + verbosestream<<"dedicated_server_loop()"<<std::endl; + + IntervalLimiter m_profiler_interval; + + static thread_local const float steplen = + g_settings->getFloat("dedicated_server_step"); + static thread_local const float profiler_print_interval = + g_settings->getFloat("profiler_print_interval"); + + /* + * The dedicated server loop only does time-keeping (in Server::step) and + * provides a way to main.cpp to kill the server externally (bool &kill). + */ + + for(;;) { + // This is kind of a hack but can be done like this + // because server.step() is very light + sleep_ms((int)(steplen*1000.0)); + server.step(steplen); + + if (server.isShutdownRequested() || kill) + break; + + /* + Profiler + */ + if (profiler_print_interval != 0) { + if(m_profiler_interval.step(steplen, profiler_print_interval)) + { + infostream<<"Profiler:"<<std::endl; + g_profiler->print(infostream); + g_profiler->clear(); + } + } + } + + infostream << "Dedicated server quitting" << std::endl; +#if USE_CURL + if (g_settings->getBool("server_announce")) + ServerList::sendAnnounce(ServerList::AA_DELETE, + server.m_bind_addr.getPort()); +#endif +} + +/* + * Mod channels + */ + + +bool Server::joinModChannel(const std::string &channel) +{ + return m_modchannel_mgr->joinChannel(channel, PEER_ID_SERVER) && + m_modchannel_mgr->setChannelState(channel, MODCHANNEL_STATE_READ_WRITE); +} + +bool Server::leaveModChannel(const std::string &channel) +{ + return m_modchannel_mgr->leaveChannel(channel, PEER_ID_SERVER); +} + +bool Server::sendModChannelMessage(const std::string &channel, const std::string &message) +{ + if (!m_modchannel_mgr->canWriteOnChannel(channel)) + return false; + + broadcastModChannelMessage(channel, message, PEER_ID_SERVER); + return true; +} + +ModChannel* Server::getModChannel(const std::string &channel) +{ + return m_modchannel_mgr->getModChannel(channel); +} + +void Server::broadcastModChannelMessage(const std::string &channel, + const std::string &message, session_t from_peer) +{ + const std::vector<u16> &peers = m_modchannel_mgr->getChannelPeers(channel); + if (peers.empty()) + return; + + if (message.size() > STRING_MAX_LEN) { + warningstream << "ModChannel message too long, dropping before sending " + << " (" << message.size() << " > " << STRING_MAX_LEN << ", channel: " + << channel << ")" << std::endl; + return; + } + + std::string sender; + if (from_peer != PEER_ID_SERVER) { + sender = getPlayerName(from_peer); + } + + NetworkPacket resp_pkt(TOCLIENT_MODCHANNEL_MSG, + 2 + channel.size() + 2 + sender.size() + 2 + message.size()); + resp_pkt << channel << sender << message; + for (session_t peer_id : peers) { + // Ignore sender + if (peer_id == from_peer) + continue; + + Send(peer_id, &resp_pkt); + } + + if (from_peer != PEER_ID_SERVER) { + m_script->on_modchannel_message(channel, sender, message); + } +} + +Translations *Server::getTranslationLanguage(const std::string &lang_code) +{ + if (lang_code.empty()) + return nullptr; + + auto it = server_translations.find(lang_code); + if (it != server_translations.end()) + return &it->second; // Already loaded + + // [] will create an entry + auto *translations = &server_translations[lang_code]; + + std::string suffix = "." + lang_code + ".tr"; + for (const auto &i : m_media) { + if (str_ends_with(i.first, suffix)) { + std::string data; + if (fs::ReadFile(i.second.path, data)) { + translations->loadTranslation(data); + } + } + } + + return translations; +} + +ModMetadataDatabase *Server::openModStorageDatabase(const std::string &world_path) +{ + std::string world_mt_path = world_path + DIR_DELIM + "world.mt"; + Settings world_mt; + if (!world_mt.readConfigFile(world_mt_path.c_str())) + throw BaseException("Cannot read world.mt!"); + + std::string backend = world_mt.exists("mod_storage_backend") ? + world_mt.get("mod_storage_backend") : "files"; + if (backend == "files") + warningstream << "/!\\ You are using the old mod storage files backend. " + << "This backend is deprecated and may be removed in a future release /!\\" + << std::endl << "Switching to SQLite3 is advised, " + << "please read http://wiki.minetest.net/Database_backends." << std::endl; + + return openModStorageDatabase(backend, world_path, world_mt); +} + +ModMetadataDatabase *Server::openModStorageDatabase(const std::string &backend, + const std::string &world_path, const Settings &world_mt) +{ + if (backend == "sqlite3") + return new ModMetadataDatabaseSQLite3(world_path); + + if (backend == "files") + return new ModMetadataDatabaseFiles(world_path); + + if (backend == "dummy") + return new Database_Dummy(); + + throw BaseException("Mod storage database backend " + backend + " not supported"); +} + +bool Server::migrateModStorageDatabase(const GameParams &game_params, const Settings &cmd_args) +{ + std::string migrate_to = cmd_args.get("migrate-mod-storage"); + Settings world_mt; + std::string world_mt_path = game_params.world_path + DIR_DELIM + "world.mt"; + if (!world_mt.readConfigFile(world_mt_path.c_str())) { + errorstream << "Cannot read world.mt!" << std::endl; + return false; + } + + std::string backend = world_mt.exists("mod_storage_backend") ? + world_mt.get("mod_storage_backend") : "files"; + if (backend == migrate_to) { + errorstream << "Cannot migrate: new backend is same" + << " as the old one" << std::endl; + return false; + } + + ModMetadataDatabase *srcdb = nullptr; + ModMetadataDatabase *dstdb = nullptr; + + bool succeeded = false; + + try { + srcdb = Server::openModStorageDatabase(backend, game_params.world_path, world_mt); + dstdb = Server::openModStorageDatabase(migrate_to, game_params.world_path, world_mt); + + dstdb->beginSave(); + + std::vector<std::string> mod_list; + srcdb->listMods(&mod_list); + for (const std::string &modname : mod_list) { + StringMap meta; + srcdb->getModEntries(modname, &meta); + for (const auto &pair : meta) { + dstdb->setModEntry(modname, pair.first, pair.second); + } + } + + dstdb->endSave(); + + succeeded = true; + + actionstream << "Successfully migrated the metadata of " + << mod_list.size() << " mods" << std::endl; + world_mt.set("mod_storage_backend", migrate_to); + if (!world_mt.updateConfigFile(world_mt_path.c_str())) + errorstream << "Failed to update world.mt!" << std::endl; + else + actionstream << "world.mt updated" << std::endl; + + } catch (BaseException &e) { + errorstream << "An error occurred during migration: " << e.what() << std::endl; + } + + delete srcdb; + delete dstdb; + + if (succeeded && backend == "files") { + // Back up files + const std::string storage_path = game_params.world_path + DIR_DELIM + "mod_storage"; + const std::string backup_path = game_params.world_path + DIR_DELIM + "mod_storage.bak"; + if (!fs::Rename(storage_path, backup_path)) + warningstream << "After migration, " << storage_path + << " could not be renamed to " << backup_path << std::endl; + } + + return succeeded; +} diff --git a/src/server.h b/src/server.h new file mode 100644 index 0000000..cb7d770 --- /dev/null +++ b/src/server.h @@ -0,0 +1,731 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_v3d.h" +#include "map.h" +#include "hud.h" +#include "gamedef.h" +#include "serialization.h" // For SER_FMT_VER_INVALID +#include "content/mods.h" +#include "inventorymanager.h" +#include "content/subgames.h" +#include "tileanimation.h" // TileAnimationParams +#include "particles.h" // ParticleParams +#include "network/peerhandler.h" +#include "network/address.h" +#include "util/numeric.h" +#include "util/thread.h" +#include "util/basic_macros.h" +#include "util/metricsbackend.h" +#include "serverenvironment.h" +#include "clientiface.h" +#include "chatmessage.h" +#include "translation.h" +#include <string> +#include <list> +#include <map> +#include <vector> +#include <unordered_set> + +class ChatEvent; +struct ChatEventChat; +struct ChatInterface; +class IWritableItemDefManager; +class NodeDefManager; +class IWritableCraftDefManager; +class BanManager; +class EventManager; +class Inventory; +class ModChannelMgr; +class RemotePlayer; +class PlayerSAO; +struct PlayerHPChangeReason; +class IRollbackManager; +struct RollbackAction; +class EmergeManager; +class ServerScripting; +class ServerEnvironment; +struct SimpleSoundSpec; +struct CloudParams; +struct SkyboxParams; +struct SunParams; +struct MoonParams; +struct StarParams; +struct Lighting; +class ServerThread; +class ServerModManager; +class ServerInventoryManager; +struct PackedValue; + +enum ClientDeletionReason { + CDR_LEAVE, + CDR_TIMEOUT, + CDR_DENY +}; + +struct MediaInfo +{ + std::string path; + std::string sha1_digest; // base64-encoded + bool no_announce; // true: not announced in TOCLIENT_ANNOUNCE_MEDIA (at player join) + + MediaInfo(const std::string &path_="", + const std::string &sha1_digest_=""): + path(path_), + sha1_digest(sha1_digest_), + no_announce(false) + { + } +}; + +// Combines the pure sound (SimpleSoundSpec) with positional information +struct ServerPlayingSound +{ + SoundLocation type = SoundLocation::Local; + + float gain = 1.0f; // for amplification of the base sound + float max_hear_distance = 32 * BS; + v3f pos; + u16 object = 0; + std::string to_player; + std::string exclude_player; + + v3f getPos(ServerEnvironment *env, bool *pos_exists) const; + + SimpleSoundSpec spec; + + std::unordered_set<session_t> clients; // peer ids +}; + +struct MinimapMode { + MinimapType type = MINIMAP_TYPE_OFF; + std::string label; + u16 size = 0; + std::string texture; + u16 scale = 1; +}; + +// structure for everything getClientInfo returns, for convenience +struct ClientInfo { + ClientState state; + Address addr; + u32 uptime; + u8 ser_vers; + u16 prot_vers; + u8 major, minor, patch; + std::string vers_string, lang_code; +}; + +class Server : public con::PeerHandler, public MapEventReceiver, + public IGameDef +{ +public: + /* + NOTE: Every public method should be thread-safe + */ + + Server( + const std::string &path_world, + const SubgameSpec &gamespec, + bool simple_singleplayer_mode, + Address bind_addr, + bool dedicated, + ChatInterface *iface = nullptr, + std::string *on_shutdown_errmsg = nullptr + ); + ~Server(); + DISABLE_CLASS_COPY(Server); + + void start(); + void stop(); + // This is mainly a way to pass the time to the server. + // Actual processing is done in an another thread. + void step(float dtime); + // This is run by ServerThread and does the actual processing + void AsyncRunStep(bool initial_step=false); + void Receive(); + PlayerSAO* StageTwoClientInit(session_t peer_id); + + /* + * Command Handlers + */ + + void handleCommand(NetworkPacket* pkt); + + void handleCommand_Null(NetworkPacket* pkt) {}; + void handleCommand_Deprecated(NetworkPacket* pkt); + void handleCommand_Init(NetworkPacket* pkt); + void handleCommand_Init2(NetworkPacket* pkt); + void handleCommand_ModChannelJoin(NetworkPacket *pkt); + void handleCommand_ModChannelLeave(NetworkPacket *pkt); + void handleCommand_ModChannelMsg(NetworkPacket *pkt); + void handleCommand_RequestMedia(NetworkPacket* pkt); + void handleCommand_ClientReady(NetworkPacket* pkt); + void handleCommand_GotBlocks(NetworkPacket* pkt); + void handleCommand_PlayerPos(NetworkPacket* pkt); + void handleCommand_DeletedBlocks(NetworkPacket* pkt); + void handleCommand_InventoryAction(NetworkPacket* pkt); + void handleCommand_ChatMessage(NetworkPacket* pkt); + void handleCommand_Damage(NetworkPacket* pkt); + void handleCommand_PlayerItem(NetworkPacket* pkt); + void handleCommand_Respawn(NetworkPacket* pkt); + void handleCommand_Interact(NetworkPacket* pkt); + void handleCommand_RemovedSounds(NetworkPacket* pkt); + void handleCommand_NodeMetaFields(NetworkPacket* pkt); + void handleCommand_InventoryFields(NetworkPacket* pkt); + void handleCommand_FirstSrp(NetworkPacket* pkt); + void handleCommand_SrpBytesA(NetworkPacket* pkt); + void handleCommand_SrpBytesM(NetworkPacket* pkt); + void handleCommand_HaveMedia(NetworkPacket *pkt); + + void ProcessData(NetworkPacket *pkt); + + void Send(NetworkPacket *pkt); + void Send(session_t peer_id, NetworkPacket *pkt); + + // Helper for handleCommand_PlayerPos and handleCommand_Interact + void process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, + NetworkPacket *pkt); + + // Both setter and getter need no envlock, + // can be called freely from threads + void setTimeOfDay(u32 time); + + /* + Shall be called with the environment locked. + This is accessed by the map, which is inside the environment, + so it shouldn't be a problem. + */ + void onMapEditEvent(const MapEditEvent &event); + + // Connection must be locked when called + std::string getStatusString(); + inline double getUptime() const { return m_uptime_counter->get(); } + + // read shutdown state + inline bool isShutdownRequested() const { return m_shutdown_state.is_requested; } + + // request server to shutdown + void requestShutdown(const std::string &msg, bool reconnect, float delay = 0.0f); + + // Returns -1 if failed, sound handle on success + // Envlock + s32 playSound(ServerPlayingSound ¶ms, bool ephemeral=false); + void stopSound(s32 handle); + void fadeSound(s32 handle, float step, float gain); + + // Envlock + std::set<std::string> getPlayerEffectivePrivs(const std::string &name); + bool checkPriv(const std::string &name, const std::string &priv); + void reportPrivsModified(const std::string &name=""); // ""=all + void reportInventoryFormspecModified(const std::string &name); + void reportFormspecPrependModified(const std::string &name); + + void setIpBanned(const std::string &ip, const std::string &name); + void unsetIpBanned(const std::string &ip_or_name); + std::string getBanDescription(const std::string &ip_or_name); + + void notifyPlayer(const char *name, const std::wstring &msg); + void notifyPlayers(const std::wstring &msg); + + void spawnParticle(const std::string &playername, + const ParticleParameters &p); + + u32 addParticleSpawner(const ParticleSpawnerParameters &p, + ServerActiveObject *attached, const std::string &playername); + + void deleteParticleSpawner(const std::string &playername, u32 id); + + bool dynamicAddMedia(std::string filepath, u32 token, + const std::string &to_player, bool ephemeral); + + ServerInventoryManager *getInventoryMgr() const { return m_inventory_mgr.get(); } + void sendDetachedInventory(Inventory *inventory, const std::string &name, session_t peer_id); + + // Envlock and conlock should be locked when using scriptapi + ServerScripting *getScriptIface(){ return m_script; } + + // actions: time-reversed list + // Return value: success/failure + bool rollbackRevertActions(const std::list<RollbackAction> &actions, + std::list<std::string> *log); + + // IGameDef interface + // Under envlock + virtual IItemDefManager* getItemDefManager(); + virtual const NodeDefManager* getNodeDefManager(); + virtual ICraftDefManager* getCraftDefManager(); + virtual u16 allocateUnknownNodeId(const std::string &name); + IRollbackManager *getRollbackManager() { return m_rollback; } + virtual EmergeManager *getEmergeManager() { return m_emerge; } + virtual ModMetadataDatabase *getModStorageDatabase() { return m_mod_storage_database; } + + IWritableItemDefManager* getWritableItemDefManager(); + NodeDefManager* getWritableNodeDefManager(); + IWritableCraftDefManager* getWritableCraftDefManager(); + + virtual const std::vector<ModSpec> &getMods() const; + virtual const ModSpec* getModSpec(const std::string &modname) const; + static std::string getBuiltinLuaPath(); + virtual std::string getWorldPath() const { return m_path_world; } + + inline bool isSingleplayer() const + { return m_simple_singleplayer_mode; } + + inline void setAsyncFatalError(const std::string &error) + { m_async_fatal_error.set(error); } + inline void setAsyncFatalError(const LuaError &e) + { + setAsyncFatalError(std::string("Lua: ") + e.what()); + } + + bool showFormspec(const char *name, const std::string &formspec, const std::string &formname); + Map & getMap() { return m_env->getMap(); } + ServerEnvironment & getEnv() { return *m_env; } + v3f findSpawnPos(); + + u32 hudAdd(RemotePlayer *player, HudElement *element); + bool hudRemove(RemotePlayer *player, u32 id); + bool hudChange(RemotePlayer *player, u32 id, HudElementStat stat, void *value); + bool hudSetFlags(RemotePlayer *player, u32 flags, u32 mask); + bool hudSetHotbarItemcount(RemotePlayer *player, s32 hotbar_itemcount); + void hudSetHotbarImage(RemotePlayer *player, const std::string &name); + void hudSetHotbarSelectedImage(RemotePlayer *player, const std::string &name); + + Address getPeerAddress(session_t peer_id); + + void setLocalPlayerAnimations(RemotePlayer *player, v2s32 animation_frames[4], + f32 frame_speed); + void setPlayerEyeOffset(RemotePlayer *player, const v3f &first, const v3f &third); + + void setSky(RemotePlayer *player, const SkyboxParams ¶ms); + void setSun(RemotePlayer *player, const SunParams ¶ms); + void setMoon(RemotePlayer *player, const MoonParams ¶ms); + void setStars(RemotePlayer *player, const StarParams ¶ms); + + void setClouds(RemotePlayer *player, const CloudParams ¶ms); + + void overrideDayNightRatio(RemotePlayer *player, bool do_override, float brightness); + + void setLighting(RemotePlayer *player, const Lighting &lighting); + + void RespawnPlayer(session_t peer_id); + + /* con::PeerHandler implementation. */ + void peerAdded(con::Peer *peer); + void deletingPeer(con::Peer *peer, bool timeout); + + void DenySudoAccess(session_t peer_id); + void DenyAccess(session_t peer_id, AccessDeniedCode reason, + const std::string &custom_reason = "", bool reconnect = false); + void acceptAuth(session_t peer_id, bool forSudoMode); + void DisconnectPeer(session_t peer_id); + bool getClientConInfo(session_t peer_id, con::rtt_stat_type type, float *retval); + bool getClientInfo(session_t peer_id, ClientInfo &ret); + + void printToConsoleOnly(const std::string &text); + + void HandlePlayerHPChange(PlayerSAO *sao, const PlayerHPChangeReason &reason); + void SendPlayerHP(PlayerSAO *sao, bool effect); + void SendPlayerBreath(PlayerSAO *sao); + void SendInventory(PlayerSAO *playerSAO, bool incremental); + void SendMovePlayer(session_t peer_id); + void SendPlayerSpeed(session_t peer_id, const v3f &added_vel); + void SendPlayerFov(session_t peer_id); + + void SendMinimapModes(session_t peer_id, + std::vector<MinimapMode> &modes, + size_t wanted_mode); + + void sendDetachedInventories(session_t peer_id, bool incremental); + + virtual bool registerModStorage(ModMetadata *storage); + virtual void unregisterModStorage(const std::string &name); + + bool joinModChannel(const std::string &channel); + bool leaveModChannel(const std::string &channel); + bool sendModChannelMessage(const std::string &channel, const std::string &message); + ModChannel *getModChannel(const std::string &channel); + + // Send block to specific player only + bool SendBlock(session_t peer_id, const v3s16 &blockpos); + + // Get or load translations for a language + Translations *getTranslationLanguage(const std::string &lang_code); + + static ModMetadataDatabase *openModStorageDatabase(const std::string &world_path); + + static ModMetadataDatabase *openModStorageDatabase(const std::string &backend, + const std::string &world_path, const Settings &world_mt); + + static bool migrateModStorageDatabase(const GameParams &game_params, + const Settings &cmd_args); + + // Lua files registered for init of async env, pair of modname + path + std::vector<std::pair<std::string, std::string>> m_async_init_files; + + // Data transferred into async envs at init time + std::unique_ptr<PackedValue> m_async_globals_data; + + // Bind address + Address m_bind_addr; + + // Environment mutex (envlock) + std::mutex m_env_mutex; + +private: + friend class EmergeThread; + friend class RemoteClient; + friend class TestServerShutdownState; + + struct ShutdownState { + friend class TestServerShutdownState; + public: + bool is_requested = false; + bool should_reconnect = false; + std::string message; + + void reset(); + void trigger(float delay, const std::string &msg, bool reconnect); + void tick(float dtime, Server *server); + std::wstring getShutdownTimerMessage() const; + bool isTimerRunning() const { return m_timer > 0.0f; } + private: + float m_timer = 0.0f; + }; + + struct PendingDynamicMediaCallback { + std::string filename; // only set if media entry and file is to be deleted + float expiry_timer; + std::unordered_set<session_t> waiting_players; + }; + + // The standard library does not implement std::hash for pairs so we have this: + struct SBCHash { + size_t operator() (const std::pair<v3s16, u16> &p) const { + return std::hash<v3s16>()(p.first) ^ p.second; + } + }; + + typedef std::unordered_map<std::pair<v3s16, u16>, std::string, SBCHash> SerializedBlockCache; + + void init(); + + void SendMovement(session_t peer_id); + void SendHP(session_t peer_id, u16 hp, bool effect); + void SendBreath(session_t peer_id, u16 breath); + void SendAccessDenied(session_t peer_id, AccessDeniedCode reason, + const std::string &custom_reason, bool reconnect = false); + void SendAccessDenied_Legacy(session_t peer_id, const std::wstring &reason); + void SendDeathscreen(session_t peer_id, bool set_camera_point_target, + v3f camera_point_target); + void SendItemDef(session_t peer_id, IItemDefManager *itemdef, u16 protocol_version); + void SendNodeDef(session_t peer_id, const NodeDefManager *nodedef, + u16 protocol_version); + + /* mark blocks not sent for all clients */ + void SetBlocksNotSent(std::map<v3s16, MapBlock *>& block); + + + virtual void SendChatMessage(session_t peer_id, const ChatMessage &message); + void SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed); + + void SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4], + f32 animation_speed); + void SendEyeOffset(session_t peer_id, v3f first, v3f third); + void SendPlayerPrivileges(session_t peer_id); + void SendPlayerInventoryFormspec(session_t peer_id); + void SendPlayerFormspecPrepend(session_t peer_id); + void SendShowFormspecMessage(session_t peer_id, const std::string &formspec, + const std::string &formname); + void SendHUDAdd(session_t peer_id, u32 id, HudElement *form); + void SendHUDRemove(session_t peer_id, u32 id); + void SendHUDChange(session_t peer_id, u32 id, HudElementStat stat, void *value); + void SendHUDSetFlags(session_t peer_id, u32 flags, u32 mask); + void SendHUDSetParam(session_t peer_id, u16 param, const std::string &value); + void SendSetSky(session_t peer_id, const SkyboxParams ¶ms); + void SendSetSun(session_t peer_id, const SunParams ¶ms); + void SendSetMoon(session_t peer_id, const MoonParams ¶ms); + void SendSetStars(session_t peer_id, const StarParams ¶ms); + void SendCloudParams(session_t peer_id, const CloudParams ¶ms); + void SendOverrideDayNightRatio(session_t peer_id, bool do_override, float ratio); + void SendSetLighting(session_t peer_id, const Lighting &lighting); + void broadcastModChannelMessage(const std::string &channel, + const std::string &message, session_t from_peer); + + /* + Send a node removal/addition event to all clients except ignore_id. + Additionally, if far_players!=NULL, players further away than + far_d_nodes are ignored and their peer_ids are added to far_players + */ + // Envlock and conlock should be locked when calling these + void sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players = nullptr, + float far_d_nodes = 100); + void sendAddNode(v3s16 p, MapNode n, + std::unordered_set<u16> *far_players = nullptr, + float far_d_nodes = 100, bool remove_metadata = true); + + void sendMetadataChanged(const std::unordered_set<v3s16> &positions, + float far_d_nodes = 100); + + // Environment and Connection must be locked when called + // `cache` may only be very short lived! (invalidation not handeled) + void SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver, + u16 net_proto_version, SerializedBlockCache *cache = nullptr); + + // Sends blocks to clients (locks env and con on its own) + void SendBlocks(float dtime); + + bool addMediaFile(const std::string &filename, const std::string &filepath, + std::string *filedata = nullptr, std::string *digest = nullptr); + void fillMediaCache(); + void sendMediaAnnouncement(session_t peer_id, const std::string &lang_code); + void sendRequestedMedia(session_t peer_id, + const std::vector<std::string> &tosend); + void stepPendingDynMediaCallbacks(float dtime); + + // Adds a ParticleSpawner on peer with peer_id (PEER_ID_INEXISTENT == all) + void SendAddParticleSpawner(session_t peer_id, u16 protocol_version, + const ParticleSpawnerParameters &p, u16 attached_id, u32 id); + + void SendDeleteParticleSpawner(session_t peer_id, u32 id); + + // Spawns particle on peer with peer_id (PEER_ID_INEXISTENT == all) + void SendSpawnParticle(session_t peer_id, u16 protocol_version, + const ParticleParameters &p); + + void SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersao); + void SendActiveObjectMessages(session_t peer_id, const std::string &datas, + bool reliable = true); + void SendCSMRestrictionFlags(session_t peer_id); + + /* + Something random + */ + + void HandlePlayerDeath(PlayerSAO* sao, const PlayerHPChangeReason &reason); + void DeleteClient(session_t peer_id, ClientDeletionReason reason); + void UpdateCrafting(RemotePlayer *player); + bool checkInteractDistance(RemotePlayer *player, const f32 d, const std::string &what); + + void handleChatInterfaceEvent(ChatEvent *evt); + + // This returns the answer to the sender of wmessage, or "" if there is none + std::wstring handleChat(const std::string &name, std::wstring wmessage_input, + bool check_shout_priv = false, RemotePlayer *player = nullptr); + void handleAdminChat(const ChatEventChat *evt); + + // When called, connection mutex should be locked + RemoteClient* getClient(session_t peer_id, ClientState state_min = CS_Active); + RemoteClient* getClientNoEx(session_t peer_id, ClientState state_min = CS_Active); + + // When called, environment mutex should be locked + std::string getPlayerName(session_t peer_id); + PlayerSAO *getPlayerSAO(session_t peer_id); + + /* + Get a player from memory or creates one. + If player is already connected, return NULL + Does not verify/modify auth info and password. + + Call with env and con locked. + */ + PlayerSAO *emergePlayer(const char *name, session_t peer_id, u16 proto_version); + + void handlePeerChanges(); + + /* + Variables + */ + // World directory + std::string m_path_world; + // Subgame specification + SubgameSpec m_gamespec; + // If true, do not allow multiple players and hide some multiplayer + // functionality + bool m_simple_singleplayer_mode; + u16 m_max_chatmessage_length; + // For "dedicated" server list flag + bool m_dedicated; + Settings *m_game_settings = nullptr; + + // Thread can set; step() will throw as ServerError + MutexedVariable<std::string> m_async_fatal_error; + + // Some timers + float m_liquid_transform_timer = 0.0f; + float m_liquid_transform_every = 1.0f; + float m_masterserver_timer = 0.0f; + float m_emergethread_trigger_timer = 0.0f; + float m_savemap_timer = 0.0f; + IntervalLimiter m_map_timer_and_unload_interval; + + // Environment + ServerEnvironment *m_env = nullptr; + + // Reference to the server map until ServerEnvironment is initialized + // after that this variable must be a nullptr + ServerMap *m_startup_server_map = nullptr; + + // server connection + std::shared_ptr<con::Connection> m_con; + + // Ban checking + BanManager *m_banmanager = nullptr; + + // Rollback manager (behind m_env_mutex) + IRollbackManager *m_rollback = nullptr; + + // Emerge manager + EmergeManager *m_emerge = nullptr; + + // Scripting + // Envlock and conlock should be locked when using Lua + ServerScripting *m_script = nullptr; + + // Item definition manager + IWritableItemDefManager *m_itemdef; + + // Node definition manager + NodeDefManager *m_nodedef; + + // Craft definition manager + IWritableCraftDefManager *m_craftdef; + + // Mods + std::unique_ptr<ServerModManager> m_modmgr; + + std::unordered_map<std::string, Translations> server_translations; + + /* + Threads + */ + // A buffer for time steps + // step() increments and AsyncRunStep() run by m_thread reads it. + float m_step_dtime = 0.0f; + std::mutex m_step_dtime_mutex; + + // The server mainly operates in this thread + ServerThread *m_thread = nullptr; + + /* + Time related stuff + */ + // Timer for sending time of day over network + float m_time_of_day_send_timer = 0.0f; + + /* + Client interface + */ + ClientInterface m_clients; + + /* + Peer change queue. + Queues stuff from peerAdded() and deletingPeer() to + handlePeerChanges() + */ + std::queue<con::PeerChange> m_peer_change_queue; + + std::unordered_map<session_t, std::string> m_formspec_state_data; + + /* + Random stuff + */ + + ShutdownState m_shutdown_state; + + ChatInterface *m_admin_chat; + std::string m_admin_nick; + + // if a mod-error occurs in the on_shutdown callback, the error message will + // be written into this + std::string *const m_on_shutdown_errmsg; + + /* + Map edit event queue. Automatically receives all map edits. + The constructor of this class registers us to receive them through + onMapEditEvent + + NOTE: Should these be moved to actually be members of + ServerEnvironment? + */ + + /* + Queue of map edits from the environment for sending to the clients + This is behind m_env_mutex + */ + std::queue<MapEditEvent*> m_unsent_map_edit_queue; + /* + If a non-empty area, map edit events contained within are left + unsent. Done at map generation time to speed up editing of the + generated area, as it will be sent anyway. + This is behind m_env_mutex + */ + VoxelArea m_ignore_map_edit_events_area; + + // media files known to server + std::unordered_map<std::string, MediaInfo> m_media; + + // pending dynamic media callbacks, clients inform the server when they have a file fetched + std::unordered_map<u32, PendingDynamicMediaCallback> m_pending_dyn_media; + float m_step_pending_dyn_media_timer = 0.0f; + + /* + Sounds + */ + std::unordered_map<s32, ServerPlayingSound> m_playing_sounds; + s32 m_next_sound_id = 0; // positive values only + s32 nextSoundId(); + + std::unordered_map<std::string, ModMetadata *> m_mod_storages; + ModMetadataDatabase *m_mod_storage_database = nullptr; + float m_mod_storage_save_timer = 10.0f; + + // CSM restrictions byteflag + u64 m_csm_restriction_flags = CSMRestrictionFlags::CSM_RF_NONE; + u32 m_csm_restriction_noderange = 8; + + // ModChannel manager + std::unique_ptr<ModChannelMgr> m_modchannel_mgr; + + // Inventory manager + std::unique_ptr<ServerInventoryManager> m_inventory_mgr; + + // Global server metrics backend + std::unique_ptr<MetricsBackend> m_metrics_backend; + + // Server metrics + MetricCounterPtr m_uptime_counter; + MetricGaugePtr m_player_gauge; + MetricGaugePtr m_timeofday_gauge; + MetricGaugePtr m_lag_gauge; + MetricCounterPtr m_aom_buffer_counter[2]; // [0] = rel, [1] = unrel + MetricCounterPtr m_packet_recv_counter; + MetricCounterPtr m_packet_recv_processed_counter; + MetricCounterPtr m_map_edit_event_counter; +}; + +/* + Runs a simple dedicated server loop. + + Shuts down when kill is set to true. +*/ +void dedicated_server_loop(Server &server, bool &kill); diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt new file mode 100644 index 0000000..0a5a8f3 --- /dev/null +++ b/src/server/CMakeLists.txt @@ -0,0 +1,9 @@ +set(server_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/activeobjectmgr.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/luaentity_sao.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mods.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/player_sao.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/serveractiveobject.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/serverinventorymgr.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/unit_sao.cpp + PARENT_SCOPE) diff --git a/src/server/activeobjectmgr.cpp b/src/server/activeobjectmgr.cpp new file mode 100644 index 0000000..acd6611 --- /dev/null +++ b/src/server/activeobjectmgr.cpp @@ -0,0 +1,184 @@ +/* +Minetest +Copyright (C) 2010-2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <log.h> +#include "mapblock.h" +#include "profiler.h" +#include "activeobjectmgr.h" + +namespace server +{ + +void ActiveObjectMgr::clear(const std::function<bool(ServerActiveObject *, u16)> &cb) +{ + std::vector<u16> objects_to_remove; + for (auto &it : m_active_objects) { + if (cb(it.second, it.first)) { + // Id to be removed from m_active_objects + objects_to_remove.push_back(it.first); + } + } + + // Remove references from m_active_objects + for (u16 i : objects_to_remove) { + m_active_objects.erase(i); + } +} + +void ActiveObjectMgr::step( + float dtime, const std::function<void(ServerActiveObject *)> &f) +{ + g_profiler->avg("ActiveObjectMgr: SAO count [#]", m_active_objects.size()); + for (auto &ao_it : m_active_objects) { + f(ao_it.second); + } +} + +// clang-format off +bool ActiveObjectMgr::registerObject(ServerActiveObject *obj) +{ + assert(obj); // Pre-condition + if (obj->getId() == 0) { + u16 new_id = getFreeId(); + if (new_id == 0) { + errorstream << "Server::ActiveObjectMgr::addActiveObjectRaw(): " + << "no free id available" << std::endl; + if (obj->environmentDeletes()) + delete obj; + return false; + } + obj->setId(new_id); + } else { + verbosestream << "Server::ActiveObjectMgr::addActiveObjectRaw(): " + << "supplied with id " << obj->getId() << std::endl; + } + + if (!isFreeId(obj->getId())) { + errorstream << "Server::ActiveObjectMgr::addActiveObjectRaw(): " + << "id is not free (" << obj->getId() << ")" << std::endl; + if (obj->environmentDeletes()) + delete obj; + return false; + } + + if (objectpos_over_limit(obj->getBasePosition())) { + v3f p = obj->getBasePosition(); + warningstream << "Server::ActiveObjectMgr::addActiveObjectRaw(): " + << "object position (" << p.X << "," << p.Y << "," << p.Z + << ") outside maximum range" << std::endl; + if (obj->environmentDeletes()) + delete obj; + return false; + } + + m_active_objects[obj->getId()] = obj; + + verbosestream << "Server::ActiveObjectMgr::addActiveObjectRaw(): " + << "Added id=" << obj->getId() << "; there are now " + << m_active_objects.size() << " active objects." << std::endl; + return true; +} + +void ActiveObjectMgr::removeObject(u16 id) +{ + verbosestream << "Server::ActiveObjectMgr::removeObject(): " + << "id=" << id << std::endl; + ServerActiveObject *obj = getActiveObject(id); + if (!obj) { + infostream << "Server::ActiveObjectMgr::removeObject(): " + << "id=" << id << " not found" << std::endl; + return; + } + + m_active_objects.erase(id); + delete obj; +} + +// clang-format on +void ActiveObjectMgr::getObjectsInsideRadius(const v3f &pos, float radius, + std::vector<ServerActiveObject *> &result, + std::function<bool(ServerActiveObject *obj)> include_obj_cb) +{ + float r2 = radius * radius; + for (auto &activeObject : m_active_objects) { + ServerActiveObject *obj = activeObject.second; + const v3f &objectpos = obj->getBasePosition(); + if (objectpos.getDistanceFromSQ(pos) > r2) + continue; + + if (!include_obj_cb || include_obj_cb(obj)) + result.push_back(obj); + } +} + +void ActiveObjectMgr::getObjectsInArea(const aabb3f &box, + std::vector<ServerActiveObject *> &result, + std::function<bool(ServerActiveObject *obj)> include_obj_cb) +{ + for (auto &activeObject : m_active_objects) { + ServerActiveObject *obj = activeObject.second; + const v3f &objectpos = obj->getBasePosition(); + if (!box.isPointInside(objectpos)) + continue; + + if (!include_obj_cb || include_obj_cb(obj)) + result.push_back(obj); + } +} + +void ActiveObjectMgr::getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius, + f32 player_radius, std::set<u16> ¤t_objects, + std::queue<u16> &added_objects) +{ + /* + Go through the object list, + - discard removed/deactivated objects, + - discard objects that are too far away, + - discard objects that are found in current_objects. + - add remaining objects to added_objects + */ + for (auto &ao_it : m_active_objects) { + u16 id = ao_it.first; + + // Get object + ServerActiveObject *object = ao_it.second; + if (!object) + continue; + + if (object->isGone()) + continue; + + f32 distance_f = object->getBasePosition().getDistanceFrom(player_pos); + if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) { + // Discard if too far + if (distance_f > player_radius && player_radius != 0) + continue; + } else if (distance_f > radius) + continue; + + // Discard if already on current_objects + auto n = current_objects.find(id); + if (n != current_objects.end()) + continue; + // Add to added_objects + added_objects.push(id); + } +} + +} // namespace server diff --git a/src/server/activeobjectmgr.h b/src/server/activeobjectmgr.h new file mode 100644 index 0000000..d43f564 --- /dev/null +++ b/src/server/activeobjectmgr.h @@ -0,0 +1,49 @@ +/* +Minetest +Copyright (C) 2010-2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <functional> +#include <vector> +#include "../activeobjectmgr.h" +#include "serveractiveobject.h" + +namespace server +{ +class ActiveObjectMgr : public ::ActiveObjectMgr<ServerActiveObject> +{ +public: + void clear(const std::function<bool(ServerActiveObject *, u16)> &cb); + void step(float dtime, + const std::function<void(ServerActiveObject *)> &f) override; + bool registerObject(ServerActiveObject *obj) override; + void removeObject(u16 id) override; + + void getObjectsInsideRadius(const v3f &pos, float radius, + std::vector<ServerActiveObject *> &result, + std::function<bool(ServerActiveObject *obj)> include_obj_cb); + void getObjectsInArea(const aabb3f &box, + std::vector<ServerActiveObject *> &result, + std::function<bool(ServerActiveObject *obj)> include_obj_cb); + + void getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius, + f32 player_radius, std::set<u16> ¤t_objects, + std::queue<u16> &added_objects); +}; +} // namespace server diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp new file mode 100644 index 0000000..ab4a9e3 --- /dev/null +++ b/src/server/luaentity_sao.cpp @@ -0,0 +1,560 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013-2020 Minetest core developers & community + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "luaentity_sao.h" +#include "collision.h" +#include "constants.h" +#include "player_sao.h" +#include "scripting_server.h" +#include "server.h" +#include "serverenvironment.h" + +LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos, const std::string &data) + : UnitSAO(env, pos) +{ + std::string name; + std::string state; + u16 hp = 1; + v3f velocity; + v3f rotation; + + while (!data.empty()) { // breakable, run for one iteration + std::istringstream is(data, std::ios::binary); + // 'version' does not allow to incrementally extend the parameter list thus + // we need another variable to build on top of 'version=1'. Ugly hack but works™ + u8 version2 = 0; + u8 version = readU8(is); + + name = deSerializeString16(is); + state = deSerializeString32(is); + + if (version < 1) + break; + + hp = readU16(is); + velocity = readV3F1000(is); + // yaw must be yaw to be backwards-compatible + rotation.Y = readF1000(is); + + if (is.good()) // EOF for old formats + version2 = readU8(is); + + if (version2 < 1) // PROTOCOL_VERSION < 37 + break; + + // version2 >= 1 + rotation.X = readF1000(is); + rotation.Z = readF1000(is); + + // if (version2 < 2) + // break; + // <read new values> + break; + } + // create object + infostream << "LuaEntitySAO::create(name=\"" << name << "\" state=\"" + << state << "\")" << std::endl; + + m_init_name = name; + m_init_state = state; + m_hp = hp; + m_velocity = velocity; + m_rotation = rotation; +} + +LuaEntitySAO::~LuaEntitySAO() +{ + if(m_registered){ + m_env->getScriptIface()->luaentity_Remove(m_id); + } + + for (u32 attached_particle_spawner : m_attached_particle_spawners) { + m_env->deleteParticleSpawner(attached_particle_spawner, false); + } +} + +void LuaEntitySAO::addedToEnvironment(u32 dtime_s) +{ + ServerActiveObject::addedToEnvironment(dtime_s); + + // Create entity from name + m_registered = m_env->getScriptIface()-> + luaentity_Add(m_id, m_init_name.c_str()); + + if(m_registered){ + // Get properties + m_env->getScriptIface()-> + luaentity_GetProperties(m_id, this, &m_prop); + // Initialize HP from properties + m_hp = m_prop.hp_max; + // Activate entity, supplying serialized state + m_env->getScriptIface()-> + luaentity_Activate(m_id, m_init_state, dtime_s); + } else { + // It's an unknown object + // Use entitystring as infotext for debugging + m_prop.infotext = m_init_name; + // Set unknown object texture + m_prop.textures.clear(); + m_prop.textures.emplace_back("unknown_object.png"); + } +} + +void LuaEntitySAO::dispatchScriptDeactivate(bool removal) +{ + // Ensure that this is in fact a registered entity, + // and that it isn't already gone. + // The latter also prevents this from ever being called twice. + if (m_registered && !isGone()) + m_env->getScriptIface()->luaentity_Deactivate(m_id, removal); +} + +void LuaEntitySAO::step(float dtime, bool send_recommended) +{ + if(!m_properties_sent) + { + m_properties_sent = true; + std::string str = getPropertyPacket(); + // create message and add to list + m_messages_out.emplace(getId(), true, str); + } + + // If attached, check that our parent is still there. If it isn't, detach. + if (m_attachment_parent_id && !isAttached()) { + // This is handled when objects are removed from the map + warningstream << "LuaEntitySAO::step() id=" << m_id << + " is attached to nonexistent parent. This is a bug." << std::endl; + clearParentAttachment(); + sendPosition(false, true); + } + + m_last_sent_position_timer += dtime; + + collisionMoveResult moveresult, *moveresult_p = nullptr; + + // Each frame, parent position is copied if the object is attached, otherwise it's calculated normally + // If the object gets detached this comes into effect automatically from the last known origin + if (auto *parent = getParent()) { + m_base_position = parent->getBasePosition(); + m_velocity = v3f(0,0,0); + m_acceleration = v3f(0,0,0); + } else { + if(m_prop.physical){ + aabb3f box = m_prop.collisionbox; + box.MinEdge *= BS; + box.MaxEdge *= BS; + f32 pos_max_d = BS*0.25; // Distance per iteration + v3f p_pos = m_base_position; + v3f p_velocity = m_velocity; + v3f p_acceleration = m_acceleration; + moveresult = collisionMoveSimple(m_env, m_env->getGameDef(), + pos_max_d, box, m_prop.stepheight, dtime, + &p_pos, &p_velocity, p_acceleration, + this, m_prop.collideWithObjects); + moveresult_p = &moveresult; + + // Apply results + m_base_position = p_pos; + m_velocity = p_velocity; + m_acceleration = p_acceleration; + } else { + m_base_position += dtime * m_velocity + 0.5 * dtime + * dtime * m_acceleration; + m_velocity += dtime * m_acceleration; + } + + if (m_prop.automatic_face_movement_dir && + (fabs(m_velocity.Z) > 0.001 || fabs(m_velocity.X) > 0.001)) { + float target_yaw = atan2(m_velocity.Z, m_velocity.X) * 180 / M_PI + + m_prop.automatic_face_movement_dir_offset; + float max_rotation_per_sec = + m_prop.automatic_face_movement_max_rotation_per_sec; + + if (max_rotation_per_sec > 0) { + m_rotation.Y = wrapDegrees_0_360(m_rotation.Y); + wrappedApproachShortest(m_rotation.Y, target_yaw, + dtime * max_rotation_per_sec, 360.f); + } else { + // Negative values of max_rotation_per_sec mean disabled. + m_rotation.Y = target_yaw; + } + } + } + + if(m_registered) { + m_env->getScriptIface()->luaentity_Step(m_id, dtime, moveresult_p); + } + + if (!send_recommended) + return; + + if(!isAttached()) + { + // TODO: force send when acceleration changes enough? + float minchange = 0.2*BS; + if(m_last_sent_position_timer > 1.0){ + minchange = 0.01*BS; + } else if(m_last_sent_position_timer > 0.2){ + minchange = 0.05*BS; + } + float move_d = m_base_position.getDistanceFrom(m_last_sent_position); + move_d += m_last_sent_move_precision; + float vel_d = m_velocity.getDistanceFrom(m_last_sent_velocity); + if (move_d > minchange || vel_d > minchange || + std::fabs(m_rotation.X - m_last_sent_rotation.X) > 1.0f || + std::fabs(m_rotation.Y - m_last_sent_rotation.Y) > 1.0f || + std::fabs(m_rotation.Z - m_last_sent_rotation.Z) > 1.0f) { + + sendPosition(true, false); + } + } + + sendOutdatedData(); +} + +std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version) +{ + std::ostringstream os(std::ios::binary); + + // PROTOCOL_VERSION >= 37 + writeU8(os, 1); // version + os << serializeString16(""); // name + writeU8(os, 0); // is_player + writeU16(os, getId()); //id + writeV3F32(os, m_base_position); + writeV3F32(os, m_rotation); + writeU16(os, m_hp); + + std::ostringstream msg_os(std::ios::binary); + msg_os << serializeString32(getPropertyPacket()); // message 1 + msg_os << serializeString32(generateUpdateArmorGroupsCommand()); // 2 + msg_os << serializeString32(generateUpdateAnimationCommand()); // 3 + for (const auto &bone_pos : m_bone_position) { + msg_os << serializeString32(generateUpdateBonePositionCommand( + bone_pos.first, bone_pos.second.X, bone_pos.second.Y)); // 3 + N + } + msg_os << serializeString32(generateUpdateAttachmentCommand()); // 4 + m_bone_position.size + + int message_count = 4 + m_bone_position.size(); + + for (const auto &id : getAttachmentChildIds()) { + if (ServerActiveObject *obj = m_env->getActiveObject(id)) { + message_count++; + msg_os << serializeString32(obj->generateUpdateInfantCommand( + id, protocol_version)); + } + } + + msg_os << serializeString32(generateSetTextureModCommand()); + message_count++; + + writeU8(os, message_count); + std::string serialized = msg_os.str(); + os.write(serialized.c_str(), serialized.size()); + + // return result + return os.str(); +} + +void LuaEntitySAO::getStaticData(std::string *result) const +{ + verbosestream<<FUNCTION_NAME<<std::endl; + std::ostringstream os(std::ios::binary); + // version must be 1 to keep backwards-compatibility. See version2 + writeU8(os, 1); + // name + os<<serializeString16(m_init_name); + // state + if(m_registered){ + std::string state = m_env->getScriptIface()-> + luaentity_GetStaticdata(m_id); + os<<serializeString32(state); + } else { + os<<serializeString32(m_init_state); + } + writeU16(os, m_hp); + writeV3F1000(os, clampToF1000(m_velocity)); + // yaw + writeF1000(os, m_rotation.Y); + + // version2. Increase this variable for new values + writeU8(os, 1); // PROTOCOL_VERSION >= 37 + + writeF1000(os, m_rotation.X); + writeF1000(os, m_rotation.Z); + + // <write new values> + + *result = os.str(); +} + +u32 LuaEntitySAO::punch(v3f dir, + const ToolCapabilities *toolcap, + ServerActiveObject *puncher, + float time_from_last_punch, + u16 initial_wear) +{ + if (!m_registered) { + // Delete unknown LuaEntities when punched + markForRemoval(); + return 0; + } + + FATAL_ERROR_IF(!puncher, "Punch action called without SAO"); + + s32 old_hp = getHP(); + ItemStack selected_item, hand_item; + ItemStack tool_item = puncher->getWieldedItem(&selected_item, &hand_item); + + PunchDamageResult result = getPunchDamage( + m_armor_groups, + toolcap, + &tool_item, + time_from_last_punch, + initial_wear); + + bool damage_handled = m_env->getScriptIface()->luaentity_Punch(m_id, puncher, + time_from_last_punch, toolcap, dir, result.did_punch ? result.damage : 0); + + if (!damage_handled) { + if (result.did_punch) { + setHP((s32)getHP() - result.damage, + PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher)); + } + } + + actionstream << puncher->getDescription() << " (id=" << puncher->getId() << + ", hp=" << puncher->getHP() << ") punched " << + getDescription() << " (id=" << m_id << ", hp=" << m_hp << + "), damage=" << (old_hp - (s32)getHP()) << + (damage_handled ? " (handled by Lua)" : "") << std::endl; + + // TODO: give Lua control over wear + return result.wear; +} + +void LuaEntitySAO::rightClick(ServerActiveObject *clicker) +{ + if (!m_registered) + return; + + m_env->getScriptIface()->luaentity_Rightclick(m_id, clicker); +} + +void LuaEntitySAO::setPos(const v3f &pos) +{ + if(isAttached()) + return; + m_base_position = pos; + sendPosition(false, true); +} + +void LuaEntitySAO::moveTo(v3f pos, bool continuous) +{ + if(isAttached()) + return; + m_base_position = pos; + if(!continuous) + sendPosition(true, true); +} + +float LuaEntitySAO::getMinimumSavedMovement() +{ + return 0.1 * BS; +} + +std::string LuaEntitySAO::getDescription() +{ + std::ostringstream oss; + oss << "LuaEntitySAO \"" << m_init_name << "\" "; + auto pos = floatToInt(m_base_position, BS); + oss << "at " << PP(pos); + return oss.str(); +} + +void LuaEntitySAO::setHP(s32 hp, const PlayerHPChangeReason &reason) +{ + m_hp = rangelim(hp, 0, U16_MAX); + + sendPunchCommand(); + + if (m_hp == 0 && !isGone()) { + clearParentAttachment(); + clearChildAttachments(); + if (m_registered) { + ServerActiveObject *killer = nullptr; + if (reason.type == PlayerHPChangeReason::PLAYER_PUNCH) + killer = reason.object; + m_env->getScriptIface()->luaentity_on_death(m_id, killer); + } + markForRemoval(); + } +} + +u16 LuaEntitySAO::getHP() const +{ + return m_hp; +} + +void LuaEntitySAO::setVelocity(v3f velocity) +{ + m_velocity = velocity; +} + +v3f LuaEntitySAO::getVelocity() +{ + return m_velocity; +} + +void LuaEntitySAO::setAcceleration(v3f acceleration) +{ + m_acceleration = acceleration; +} + +v3f LuaEntitySAO::getAcceleration() +{ + return m_acceleration; +} + +void LuaEntitySAO::setTextureMod(const std::string &mod) +{ + m_current_texture_modifier = mod; + // create message and add to list + m_messages_out.emplace(getId(), true, generateSetTextureModCommand()); +} + +std::string LuaEntitySAO::getTextureMod() const +{ + return m_current_texture_modifier; +} + + +std::string LuaEntitySAO::generateSetTextureModCommand() const +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, AO_CMD_SET_TEXTURE_MOD); + // parameters + os << serializeString16(m_current_texture_modifier); + return os.str(); +} + +std::string LuaEntitySAO::generateSetSpriteCommand(v2s16 p, u16 num_frames, + f32 framelength, bool select_horiz_by_yawpitch) +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, AO_CMD_SET_SPRITE); + // parameters + writeV2S16(os, p); + writeU16(os, num_frames); + writeF32(os, framelength); + writeU8(os, select_horiz_by_yawpitch); + return os.str(); +} + +void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength, + bool select_horiz_by_yawpitch) +{ + std::string str = generateSetSpriteCommand( + p, + num_frames, + framelength, + select_horiz_by_yawpitch + ); + // create message and add to list + m_messages_out.emplace(getId(), true, str); +} + +std::string LuaEntitySAO::getName() +{ + return m_init_name; +} + +std::string LuaEntitySAO::getPropertyPacket() +{ + return generateSetPropertiesCommand(m_prop); +} + +void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end) +{ + // If the object is attached client-side, don't waste bandwidth sending its position to clients + if(isAttached()) + return; + + // Send attachment updates instantly to the client prior updating position + sendOutdatedData(); + + m_last_sent_move_precision = m_base_position.getDistanceFrom( + m_last_sent_position); + m_last_sent_position_timer = 0; + m_last_sent_position = m_base_position; + m_last_sent_velocity = m_velocity; + //m_last_sent_acceleration = m_acceleration; + m_last_sent_rotation = m_rotation; + + float update_interval = m_env->getSendRecommendedInterval(); + + std::string str = generateUpdatePositionCommand( + m_base_position, + m_velocity, + m_acceleration, + m_rotation, + do_interpolate, + is_movement_end, + update_interval + ); + // create message and add to list + m_messages_out.emplace(getId(), false, str); +} + +bool LuaEntitySAO::getCollisionBox(aabb3f *toset) const +{ + if (m_prop.physical) + { + //update collision box + toset->MinEdge = m_prop.collisionbox.MinEdge * BS; + toset->MaxEdge = m_prop.collisionbox.MaxEdge * BS; + + toset->MinEdge += m_base_position; + toset->MaxEdge += m_base_position; + + return true; + } + + return false; +} + +bool LuaEntitySAO::getSelectionBox(aabb3f *toset) const +{ + if (!m_prop.is_visible || !m_prop.pointable) { + return false; + } + + toset->MinEdge = m_prop.selectionbox.MinEdge * BS; + toset->MaxEdge = m_prop.selectionbox.MaxEdge * BS; + + return true; +} + +bool LuaEntitySAO::collideWithObjects() const +{ + return m_prop.collideWithObjects; +} diff --git a/src/server/luaentity_sao.h b/src/server/luaentity_sao.h new file mode 100644 index 0000000..1dc72b1 --- /dev/null +++ b/src/server/luaentity_sao.h @@ -0,0 +1,107 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013-2020 Minetest core developers & community + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "unit_sao.h" + +class LuaEntitySAO : public UnitSAO +{ +public: + LuaEntitySAO() = delete; + // Used by the environment to load SAO + LuaEntitySAO(ServerEnvironment *env, v3f pos, const std::string &data); + // Used by the Lua API + LuaEntitySAO(ServerEnvironment *env, v3f pos, const std::string &name, + const std::string &state) : + UnitSAO(env, pos), + m_init_name(name), m_init_state(state) + { + } + ~LuaEntitySAO(); + + ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_LUAENTITY; } + ActiveObjectType getSendType() const { return ACTIVEOBJECT_TYPE_GENERIC; } + virtual void addedToEnvironment(u32 dtime_s); + void step(float dtime, bool send_recommended); + std::string getClientInitializationData(u16 protocol_version); + + bool isStaticAllowed() const { return m_prop.static_save; } + bool shouldUnload() const { return true; } + void getStaticData(std::string *result) const; + + u32 punch(v3f dir, const ToolCapabilities *toolcap = nullptr, + ServerActiveObject *puncher = nullptr, + float time_from_last_punch = 1000000.0f, + u16 initial_wear = 0); + + void rightClick(ServerActiveObject *clicker); + + void setPos(const v3f &pos); + void moveTo(v3f pos, bool continuous); + float getMinimumSavedMovement(); + + std::string getDescription(); + + void setHP(s32 hp, const PlayerHPChangeReason &reason); + u16 getHP() const; + + /* LuaEntitySAO-specific */ + void setVelocity(v3f velocity); + void addVelocity(v3f velocity) { m_velocity += velocity; } + v3f getVelocity(); + void setAcceleration(v3f acceleration); + v3f getAcceleration(); + + void setTextureMod(const std::string &mod); + std::string getTextureMod() const; + void setSprite(v2s16 p, int num_frames, float framelength, + bool select_horiz_by_yawpitch); + std::string getName(); + bool getCollisionBox(aabb3f *toset) const; + bool getSelectionBox(aabb3f *toset) const; + bool collideWithObjects() const; + +protected: + void dispatchScriptDeactivate(bool removal); + virtual void onMarkedForDeactivation() { dispatchScriptDeactivate(false); } + virtual void onMarkedForRemoval() { dispatchScriptDeactivate(true); } + +private: + std::string getPropertyPacket(); + void sendPosition(bool do_interpolate, bool is_movement_end); + std::string generateSetTextureModCommand() const; + static std::string generateSetSpriteCommand(v2s16 p, u16 num_frames, + f32 framelength, bool select_horiz_by_yawpitch); + + std::string m_init_name; + std::string m_init_state; + bool m_registered = false; + + v3f m_velocity; + v3f m_acceleration; + + v3f m_last_sent_position; + v3f m_last_sent_velocity; + v3f m_last_sent_rotation; + float m_last_sent_position_timer = 0.0f; + float m_last_sent_move_precision = 0.0f; + std::string m_current_texture_modifier = ""; +}; diff --git a/src/server/mods.cpp b/src/server/mods.cpp new file mode 100644 index 0000000..f302d42 --- /dev/null +++ b/src/server/mods.cpp @@ -0,0 +1,108 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mods.h" +#include "filesys.h" +#include "log.h" +#include "scripting_server.h" +#include "content/subgames.h" +#include "porting.h" + +/** + * Manage server mods + * + * All new calls to this class must be tested in test_servermodmanager.cpp + */ + +/** + * Creates a ServerModManager which targets worldpath + * @param worldpath + */ +ServerModManager::ServerModManager(const std::string &worldpath): + configuration() +{ + SubgameSpec gamespec = findWorldSubgame(worldpath); + + // Add all game mods and all world mods + configuration.addGameMods(gamespec); + configuration.addModsInPath(worldpath + DIR_DELIM + "worldmods", "worldmods"); + + // Load normal mods + std::string worldmt = worldpath + DIR_DELIM + "world.mt"; + configuration.addModsFromConfig(worldmt, gamespec.addon_mods_paths); + configuration.checkConflictsAndDeps(); +} + +// clang-format off +// This function cannot be currenctly easily tested but it should be ASAP +void ServerModManager::loadMods(ServerScripting *script) +{ + // Print mods + infostream << "Server: Loading mods: "; + for (const ModSpec &mod : configuration.getMods()) { + infostream << mod.name << " "; + } + + infostream << std::endl; + // Load and run "mod" scripts + for (const ModSpec &mod : configuration.getMods()) { + mod.checkAndLog(); + + std::string script_path = mod.path + DIR_DELIM + "init.lua"; + auto t = porting::getTimeMs(); + script->loadMod(script_path, mod.name); + infostream << "Mod \"" << mod.name << "\" loaded after " + << (porting::getTimeMs() - t) << " ms" << std::endl; + } + + // Run a callback when mods are loaded + script->on_mods_loaded(); +} + +// clang-format on +const ModSpec *ServerModManager::getModSpec(const std::string &modname) const +{ + for (const auto &mod : configuration.getMods()) { + if (mod.name == modname) + return &mod; + } + + return nullptr; +} + +void ServerModManager::getModNames(std::vector<std::string> &modlist) const +{ + for (const ModSpec &spec : configuration.getMods()) + modlist.push_back(spec.name); +} + +void ServerModManager::getModsMediaPaths(std::vector<std::string> &paths) const +{ + // Iterate mods in reverse load order: Media loading expects higher priority media files first + // and mods loading later should be able to override media of already loaded mods + const auto &mods = configuration.getMods(); + for (auto it = mods.crbegin(); it != mods.crend(); it++) { + const ModSpec &spec = *it; + fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "textures"); + fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "sounds"); + fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "media"); + fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "models"); + fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "locale"); + } +} diff --git a/src/server/mods.h b/src/server/mods.h new file mode 100644 index 0000000..1d1b42d --- /dev/null +++ b/src/server/mods.h @@ -0,0 +1,73 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "content/mod_configuration.h" +#include <memory> + +class MetricsBackend; +class MetricCounter; +class ServerScripting; + +/** + * Manage server mods + * + * All new calls to this class must be tested in test_servermodmanager.cpp + */ +class ServerModManager +{ + ModConfiguration configuration; + +public: + /** + * Creates a ServerModManager which targets worldpath + * @param worldpath + */ + ServerModManager(const std::string &worldpath); + void loadMods(ServerScripting *script); + const ModSpec *getModSpec(const std::string &modname) const; + void getModNames(std::vector<std::string> &modlist) const; + + inline const std::vector<ModSpec> &getMods() const { + return configuration.getMods(); + } + + inline const std::vector<ModSpec> &getUnsatisfiedMods() const { + return configuration.getUnsatisfiedMods(); + } + + inline bool isConsistent() const { + return configuration.isConsistent(); + } + + inline void printUnsatisfiedModsError() const { + return configuration.printUnsatisfiedModsError(); + } + + /** + * Recursively gets all paths of mod folders that can contain media files. + * + * Result is ordered in descending priority, ie. files from an earlier path + * should not be replaced by files from a latter one. + * + * @param paths result vector + */ + void getModsMediaPaths(std::vector<std::string> &paths) const; +}; diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp new file mode 100644 index 0000000..a58a039 --- /dev/null +++ b/src/server/player_sao.cpp @@ -0,0 +1,679 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013-2020 Minetest core developers & community + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "player_sao.h" +#include "nodedef.h" +#include "remoteplayer.h" +#include "scripting_server.h" +#include "server.h" +#include "serverenvironment.h" + +PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t peer_id_, + bool is_singleplayer): + UnitSAO(env_, v3f(0,0,0)), + m_player(player_), + m_peer_id(peer_id_), + m_is_singleplayer(is_singleplayer) +{ + SANITY_CHECK(m_peer_id != PEER_ID_INEXISTENT); + + m_prop.hp_max = PLAYER_MAX_HP_DEFAULT; + m_prop.breath_max = PLAYER_MAX_BREATH_DEFAULT; + m_prop.physical = false; + m_prop.collisionbox = aabb3f(-0.3f, 0.0f, -0.3f, 0.3f, 1.77f, 0.3f); + m_prop.selectionbox = aabb3f(-0.3f, 0.0f, -0.3f, 0.3f, 1.77f, 0.3f); + m_prop.pointable = true; + // Start of default appearance, this should be overwritten by Lua + m_prop.visual = "upright_sprite"; + m_prop.visual_size = v3f(1, 2, 1); + m_prop.textures.clear(); + m_prop.textures.emplace_back("player.png"); + m_prop.textures.emplace_back("player_back.png"); + m_prop.colors.clear(); + m_prop.colors.emplace_back(255, 255, 255, 255); + m_prop.spritediv = v2s16(1,1); + m_prop.eye_height = 1.625f; + // End of default appearance + m_prop.is_visible = true; + m_prop.backface_culling = false; + m_prop.makes_footstep_sound = true; + m_prop.stepheight = PLAYER_DEFAULT_STEPHEIGHT * BS; + m_prop.show_on_minimap = true; + m_hp = m_prop.hp_max; + m_breath = m_prop.breath_max; + // Disable zoom in survival mode using a value of 0 + m_prop.zoom_fov = g_settings->getBool("creative_mode") ? 15.0f : 0.0f; + + if (!g_settings->getBool("enable_damage")) + m_armor_groups["immortal"] = 1; +} + +void PlayerSAO::finalize(RemotePlayer *player, const std::set<std::string> &privs) +{ + assert(player); + m_player = player; + m_privs = privs; +} + +v3f PlayerSAO::getEyeOffset() const +{ + return v3f(0, BS * m_prop.eye_height, 0); +} + +std::string PlayerSAO::getDescription() +{ + return std::string("player ") + m_player->getName(); +} + +// Called after id has been set and has been inserted in environment +void PlayerSAO::addedToEnvironment(u32 dtime_s) +{ + ServerActiveObject::addedToEnvironment(dtime_s); + ServerActiveObject::setBasePosition(m_base_position); + m_player->setPlayerSAO(this); + m_player->setPeerId(m_peer_id); + m_last_good_position = m_base_position; +} + +// Called before removing from environment +void PlayerSAO::removingFromEnvironment() +{ + ServerActiveObject::removingFromEnvironment(); + if (m_player->getPlayerSAO() == this) { + unlinkPlayerSessionAndSave(); + for (u32 attached_particle_spawner : m_attached_particle_spawners) { + m_env->deleteParticleSpawner(attached_particle_spawner, false); + } + } +} + +std::string PlayerSAO::getClientInitializationData(u16 protocol_version) +{ + std::ostringstream os(std::ios::binary); + + // Protocol >= 15 + writeU8(os, 1); // version + os << serializeString16(m_player->getName()); // name + writeU8(os, 1); // is_player + writeS16(os, getId()); // id + writeV3F32(os, m_base_position); + writeV3F32(os, m_rotation); + writeU16(os, getHP()); + + std::ostringstream msg_os(std::ios::binary); + msg_os << serializeString32(getPropertyPacket()); // message 1 + msg_os << serializeString32(generateUpdateArmorGroupsCommand()); // 2 + msg_os << serializeString32(generateUpdateAnimationCommand()); // 3 + for (const auto &bone_pos : m_bone_position) { + msg_os << serializeString32(generateUpdateBonePositionCommand( + bone_pos.first, bone_pos.second.X, bone_pos.second.Y)); // 3 + N + } + msg_os << serializeString32(generateUpdateAttachmentCommand()); // 4 + m_bone_position.size + msg_os << serializeString32(generateUpdatePhysicsOverrideCommand()); // 5 + m_bone_position.size + + int message_count = 5 + m_bone_position.size(); + + for (const auto &id : getAttachmentChildIds()) { + if (ServerActiveObject *obj = m_env->getActiveObject(id)) { + message_count++; + msg_os << serializeString32(obj->generateUpdateInfantCommand( + id, protocol_version)); + } + } + + writeU8(os, message_count); + std::string serialized = msg_os.str(); + os.write(serialized.c_str(), serialized.size()); + + // return result + return os.str(); +} + +void PlayerSAO::getStaticData(std::string * result) const +{ + FATAL_ERROR("This function shall not be called for PlayerSAO"); +} + +void PlayerSAO::step(float dtime, bool send_recommended) +{ + if (!isImmortal() && m_drowning_interval.step(dtime, 2.0f)) { + // Get nose/mouth position, approximate with eye position + v3s16 p = floatToInt(getEyePosition(), BS); + MapNode n = m_env->getMap().getNode(p); + const ContentFeatures &c = m_env->getGameDef()->ndef()->get(n); + // If node generates drown + if (c.drowning > 0 && m_hp > 0) { + if (m_breath > 0) + setBreath(m_breath - 1); + + // No more breath, damage player + if (m_breath == 0) { + PlayerHPChangeReason reason(PlayerHPChangeReason::DROWNING); + setHP(m_hp - c.drowning, reason); + } + } + } + + if (m_breathing_interval.step(dtime, 0.5f) && !isImmortal()) { + // Get nose/mouth position, approximate with eye position + v3s16 p = floatToInt(getEyePosition(), BS); + MapNode n = m_env->getMap().getNode(p); + const ContentFeatures &c = m_env->getGameDef()->ndef()->get(n); + // If player is alive & not drowning & not in ignore & not immortal, breathe + if (m_breath < m_prop.breath_max && c.drowning == 0 && + n.getContent() != CONTENT_IGNORE && m_hp > 0) + setBreath(m_breath + 1); + } + + if (!isImmortal() && m_node_hurt_interval.step(dtime, 1.0f)) { + u32 damage_per_second = 0; + std::string nodename; + // Lowest and highest damage points are 0.1 within collisionbox + float dam_top = m_prop.collisionbox.MaxEdge.Y - 0.1f; + + // Sequence of damage points, starting 0.1 above feet and progressing + // upwards in 1 node intervals, stopping below top damage point. + for (float dam_height = 0.1f; dam_height < dam_top; dam_height++) { + v3s16 p = floatToInt(m_base_position + + v3f(0.0f, dam_height * BS, 0.0f), BS); + MapNode n = m_env->getMap().getNode(p); + const ContentFeatures &c = m_env->getGameDef()->ndef()->get(n); + if (c.damage_per_second > damage_per_second) { + damage_per_second = c.damage_per_second; + nodename = c.name; + } + } + + // Top damage point + v3s16 ptop = floatToInt(m_base_position + + v3f(0.0f, dam_top * BS, 0.0f), BS); + MapNode ntop = m_env->getMap().getNode(ptop); + const ContentFeatures &c = m_env->getGameDef()->ndef()->get(ntop); + if (c.damage_per_second > damage_per_second) { + damage_per_second = c.damage_per_second; + nodename = c.name; + } + + if (damage_per_second != 0 && m_hp > 0) { + s32 newhp = (s32)m_hp - (s32)damage_per_second; + PlayerHPChangeReason reason(PlayerHPChangeReason::NODE_DAMAGE, nodename); + setHP(newhp, reason); + } + } + + if (!m_properties_sent) { + m_properties_sent = true; + std::string str = getPropertyPacket(); + // create message and add to list + m_messages_out.emplace(getId(), true, str); + m_env->getScriptIface()->player_event(this, "properties_changed"); + } + + // If attached, check that our parent is still there. If it isn't, detach. + if (m_attachment_parent_id && !isAttached()) { + // This is handled when objects are removed from the map + warningstream << "PlayerSAO::step() id=" << m_id << + " is attached to nonexistent parent. This is a bug." << std::endl; + clearParentAttachment(); + setBasePosition(m_last_good_position); + m_env->getGameDef()->SendMovePlayer(m_peer_id); + } + + //dstream<<"PlayerSAO::step: dtime: "<<dtime<<std::endl; + + // Set lag pool maximums based on estimated lag + const float LAG_POOL_MIN = 5.0f; + float lag_pool_max = m_env->getMaxLagEstimate() * 2.0f; + if(lag_pool_max < LAG_POOL_MIN) + lag_pool_max = LAG_POOL_MIN; + m_dig_pool.setMax(lag_pool_max); + m_move_pool.setMax(lag_pool_max); + + // Increment cheat prevention timers + m_dig_pool.add(dtime); + m_move_pool.add(dtime); + m_time_from_last_teleport += dtime; + m_time_from_last_punch += dtime; + m_nocheat_dig_time += dtime; + m_max_speed_override_time = MYMAX(m_max_speed_override_time - dtime, 0.0f); + + // Each frame, parent position is copied if the object is attached, + // otherwise it's calculated normally. + // If the object gets detached this comes into effect automatically from + // the last known origin. + if (auto *parent = getParent()) { + v3f pos = parent->getBasePosition(); + m_last_good_position = pos; + setBasePosition(pos); + + if (m_player) + m_player->setSpeed(v3f()); + } + + if (!send_recommended) + return; + + if (m_position_not_sent) { + m_position_not_sent = false; + float update_interval = m_env->getSendRecommendedInterval(); + v3f pos; + // When attached, the position is only sent to clients where the + // parent isn't known + if (isAttached()) + pos = m_last_good_position; + else + pos = m_base_position; + + std::string str = generateUpdatePositionCommand( + pos, + v3f(0.0f, 0.0f, 0.0f), + v3f(0.0f, 0.0f, 0.0f), + m_rotation, + true, + false, + update_interval + ); + // create message and add to list + m_messages_out.emplace(getId(), false, str); + } + + if (!m_physics_override_sent) { + m_physics_override_sent = true; + // create message and add to list + m_messages_out.emplace(getId(), true, generateUpdatePhysicsOverrideCommand()); + } + + sendOutdatedData(); +} + +std::string PlayerSAO::generateUpdatePhysicsOverrideCommand() const +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, AO_CMD_SET_PHYSICS_OVERRIDE); + // parameters + writeF32(os, m_physics_override_speed); + writeF32(os, m_physics_override_jump); + writeF32(os, m_physics_override_gravity); + // these are sent inverted so we get true when the server sends nothing + writeU8(os, !m_physics_override_sneak); + writeU8(os, !m_physics_override_sneak_glitch); + writeU8(os, !m_physics_override_new_move); + return os.str(); +} + +void PlayerSAO::setBasePosition(v3f position) +{ + if (m_player && position != m_base_position) + m_player->setDirty(true); + + // This needs to be ran for attachments too + ServerActiveObject::setBasePosition(position); + + // Updating is not wanted/required for player migration + if (m_env) { + m_position_not_sent = true; + } +} + +void PlayerSAO::setPos(const v3f &pos) +{ + if(isAttached()) + return; + + // Send mapblock of target location + v3s16 blockpos = v3s16(pos.X / MAP_BLOCKSIZE, pos.Y / MAP_BLOCKSIZE, pos.Z / MAP_BLOCKSIZE); + m_env->getGameDef()->SendBlock(m_peer_id, blockpos); + + setBasePosition(pos); + // Movement caused by this command is always valid + m_last_good_position = getBasePosition(); + m_move_pool.empty(); + m_time_from_last_teleport = 0.0; + m_env->getGameDef()->SendMovePlayer(m_peer_id); +} + +void PlayerSAO::moveTo(v3f pos, bool continuous) +{ + if(isAttached()) + return; + + setBasePosition(pos); + // Movement caused by this command is always valid + m_last_good_position = getBasePosition(); + m_move_pool.empty(); + m_time_from_last_teleport = 0.0; + m_env->getGameDef()->SendMovePlayer(m_peer_id); +} + +void PlayerSAO::setPlayerYaw(const float yaw) +{ + v3f rotation(0, yaw, 0); + if (m_player && yaw != m_rotation.Y) + m_player->setDirty(true); + + // Set player model yaw, not look view + UnitSAO::setRotation(rotation); +} + +void PlayerSAO::setFov(const float fov) +{ + if (m_player && fov != m_fov) + m_player->setDirty(true); + + m_fov = fov; +} + +void PlayerSAO::setWantedRange(const s16 range) +{ + if (m_player && range != m_wanted_range) + m_player->setDirty(true); + + m_wanted_range = range; +} + +void PlayerSAO::setPlayerYawAndSend(const float yaw) +{ + setPlayerYaw(yaw); + m_env->getGameDef()->SendMovePlayer(m_peer_id); +} + +void PlayerSAO::setLookPitch(const float pitch) +{ + if (m_player && pitch != m_pitch) + m_player->setDirty(true); + + m_pitch = pitch; +} + +void PlayerSAO::setLookPitchAndSend(const float pitch) +{ + setLookPitch(pitch); + m_env->getGameDef()->SendMovePlayer(m_peer_id); +} + +u32 PlayerSAO::punch(v3f dir, + const ToolCapabilities *toolcap, + ServerActiveObject *puncher, + float time_from_last_punch, + u16 initial_wear) +{ + if (!toolcap) + return 0; + + FATAL_ERROR_IF(!puncher, "Punch action called without SAO"); + + // No effect if PvP disabled or if immortal + if (isImmortal() || !g_settings->getBool("enable_pvp")) { + if (puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) { + // create message and add to list + sendPunchCommand(); + return 0; + } + } + + s32 old_hp = getHP(); + HitParams hitparams = getHitParams(m_armor_groups, toolcap, + time_from_last_punch, initial_wear); + + PlayerSAO *playersao = m_player->getPlayerSAO(); + + bool damage_handled = m_env->getScriptIface()->on_punchplayer(playersao, + puncher, time_from_last_punch, toolcap, dir, + hitparams.hp); + + if (!damage_handled) { + setHP((s32)getHP() - (s32)hitparams.hp, + PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher)); + } else { // override client prediction + if (puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) { + // create message and add to list + sendPunchCommand(); + } + } + + actionstream << puncher->getDescription() << " (id=" << puncher->getId() << + ", hp=" << puncher->getHP() << ") punched " << + getDescription() << " (id=" << m_id << ", hp=" << m_hp << + "), damage=" << (old_hp - (s32)getHP()) << + (damage_handled ? " (handled by Lua)" : "") << std::endl; + + return hitparams.wear; +} + +void PlayerSAO::rightClick(ServerActiveObject *clicker) +{ + m_env->getScriptIface()->on_rightclickplayer(this, clicker); +} + +void PlayerSAO::setHP(s32 target_hp, const PlayerHPChangeReason &reason, bool from_client) +{ + target_hp = rangelim(target_hp, 0, U16_MAX); + + if (target_hp == m_hp) + return; // Nothing to do + + s32 hp_change = m_env->getScriptIface()->on_player_hpchange(this, target_hp - (s32)m_hp, reason); + + s32 hp = (s32)m_hp + std::min(hp_change, U16_MAX); // Protection against s32 overflow + hp = rangelim(hp, 0, U16_MAX); + + if (hp > m_prop.hp_max) + hp = m_prop.hp_max; + + if (hp < m_hp && isImmortal()) + hp = m_hp; // Do not allow immortal players to be damaged + + // Update properties on death + if ((hp == 0) != (m_hp == 0)) + m_properties_sent = false; + + if (hp != m_hp) { + m_hp = hp; + m_env->getGameDef()->HandlePlayerHPChange(this, reason); + } else if (from_client) + m_env->getGameDef()->SendPlayerHP(this, true); +} + +void PlayerSAO::setBreath(const u16 breath, bool send) +{ + if (m_player && breath != m_breath) + m_player->setDirty(true); + + m_breath = rangelim(breath, 0, m_prop.breath_max); + + if (send) + m_env->getGameDef()->SendPlayerBreath(this); +} + +Inventory *PlayerSAO::getInventory() const +{ + return m_player ? &m_player->inventory : nullptr; +} + +InventoryLocation PlayerSAO::getInventoryLocation() const +{ + InventoryLocation loc; + loc.setPlayer(m_player->getName()); + return loc; +} + +u16 PlayerSAO::getWieldIndex() const +{ + return m_player->getWieldIndex(); +} + +ItemStack PlayerSAO::getWieldedItem(ItemStack *selected, ItemStack *hand) const +{ + return m_player->getWieldedItem(selected, hand); +} + +bool PlayerSAO::setWieldedItem(const ItemStack &item) +{ + InventoryList *mlist = m_player->inventory.getList(getWieldList()); + if (mlist) { + mlist->changeItem(m_player->getWieldIndex(), item); + return true; + } + return false; +} + +void PlayerSAO::disconnected() +{ + m_peer_id = PEER_ID_INEXISTENT; + markForRemoval(); +} + +void PlayerSAO::unlinkPlayerSessionAndSave() +{ + assert(m_player->getPlayerSAO() == this); + m_player->setPeerId(PEER_ID_INEXISTENT); + m_env->savePlayer(m_player); + m_player->setPlayerSAO(NULL); + m_env->removePlayer(m_player); +} + +std::string PlayerSAO::getPropertyPacket() +{ + m_prop.is_visible = (true); + return generateSetPropertiesCommand(m_prop); +} + +void PlayerSAO::setMaxSpeedOverride(const v3f &vel) +{ + if (m_max_speed_override_time == 0.0f) + m_max_speed_override = vel; + else + m_max_speed_override += vel; + if (m_player) { + float accel = MYMIN(m_player->movement_acceleration_default, + m_player->movement_acceleration_air); + m_max_speed_override_time = m_max_speed_override.getLength() / accel / BS; + } +} + +bool PlayerSAO::checkMovementCheat() +{ + if (m_is_singleplayer || + isAttached() || + g_settings->getBool("disable_anticheat")) { + m_last_good_position = m_base_position; + return false; + } + + bool cheated = false; + /* + Check player movements + + NOTE: Actually the server should handle player physics like the + client does and compare player's position to what is calculated + on our side. This is required when eg. players fly due to an + explosion. Altough a node-based alternative might be possible + too, and much more lightweight. + */ + + float override_max_H, override_max_V; + if (m_max_speed_override_time > 0.0f) { + override_max_H = MYMAX(fabs(m_max_speed_override.X), fabs(m_max_speed_override.Z)); + override_max_V = fabs(m_max_speed_override.Y); + } else { + override_max_H = override_max_V = 0.0f; + } + + float player_max_walk = 0; // horizontal movement + float player_max_jump = 0; // vertical upwards movement + + if (m_privs.count("fast") != 0) + player_max_walk = m_player->movement_speed_fast; // Fast speed + else + player_max_walk = m_player->movement_speed_walk; // Normal speed + player_max_walk *= m_physics_override_speed; + player_max_walk = MYMAX(player_max_walk, override_max_H); + + player_max_jump = m_player->movement_speed_jump * m_physics_override_jump; + // FIXME: Bouncy nodes cause practically unbound increase in Y speed, + // until this can be verified correctly, tolerate higher jumping speeds + player_max_jump *= 2.0; + player_max_jump = MYMAX(player_max_jump, override_max_V); + + // Don't divide by zero! + if (player_max_walk < 0.0001f) + player_max_walk = 0.0001f; + if (player_max_jump < 0.0001f) + player_max_jump = 0.0001f; + + v3f diff = (m_base_position - m_last_good_position); + float d_vert = diff.Y; + diff.Y = 0; + float d_horiz = diff.getLength(); + float required_time = d_horiz / player_max_walk; + + // FIXME: Checking downwards movement is not easily possible currently, + // the server could calculate speed differences to examine the gravity + if (d_vert > 0) { + // In certain cases (water, ladders) walking speed is applied vertically + float s = MYMAX(player_max_jump, player_max_walk); + required_time = MYMAX(required_time, d_vert / s); + } + + if (m_move_pool.grab(required_time)) { + m_last_good_position = m_base_position; + } else { + const float LAG_POOL_MIN = 5.0; + float lag_pool_max = m_env->getMaxLagEstimate() * 2.0; + lag_pool_max = MYMAX(lag_pool_max, LAG_POOL_MIN); + if (m_time_from_last_teleport > lag_pool_max) { + actionstream << "Server: " << m_player->getName() + << " moved too fast: V=" << d_vert << ", H=" << d_horiz + << "; resetting position." << std::endl; + cheated = true; + } + setBasePosition(m_last_good_position); + } + return cheated; +} + +bool PlayerSAO::getCollisionBox(aabb3f *toset) const +{ + //update collision box + toset->MinEdge = m_prop.collisionbox.MinEdge * BS; + toset->MaxEdge = m_prop.collisionbox.MaxEdge * BS; + + toset->MinEdge += m_base_position; + toset->MaxEdge += m_base_position; + return true; +} + +bool PlayerSAO::getSelectionBox(aabb3f *toset) const +{ + if (!m_prop.is_visible || !m_prop.pointable) { + return false; + } + + toset->MinEdge = m_prop.selectionbox.MinEdge * BS; + toset->MaxEdge = m_prop.selectionbox.MaxEdge * BS; + + return true; +} + +float PlayerSAO::getZoomFOV() const +{ + return m_prop.zoom_fov; +} diff --git a/src/server/player_sao.h b/src/server/player_sao.h new file mode 100644 index 0000000..5f48cae --- /dev/null +++ b/src/server/player_sao.h @@ -0,0 +1,306 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013-2020 Minetest core developers & community + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "constants.h" +#include "network/networkprotocol.h" +#include "unit_sao.h" +#include "util/numeric.h" + +/* + PlayerSAO needs some internals exposed. +*/ + +class LagPool +{ + float m_pool = 15.0f; + float m_max = 15.0f; + +public: + LagPool() = default; + + void setMax(float new_max) + { + m_max = new_max; + if (m_pool > new_max) + m_pool = new_max; + } + + void add(float dtime) + { + m_pool -= dtime; + if (m_pool < 0) + m_pool = 0; + } + + void empty() { m_pool = m_max; } + + bool grab(float dtime) + { + if (dtime <= 0) + return true; + if (m_pool + dtime > m_max) + return false; + m_pool += dtime; + return true; + } +}; + +class RemotePlayer; + +class PlayerSAO : public UnitSAO +{ +public: + PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t peer_id_, + bool is_singleplayer); + + ActiveObjectType getType() const override { return ACTIVEOBJECT_TYPE_PLAYER; } + ActiveObjectType getSendType() const override { return ACTIVEOBJECT_TYPE_GENERIC; } + std::string getDescription() override; + + /* + Active object <-> environment interface + */ + + void addedToEnvironment(u32 dtime_s) override; + void removingFromEnvironment() override; + bool isStaticAllowed() const override { return false; } + bool shouldUnload() const override { return false; } + std::string getClientInitializationData(u16 protocol_version) override; + void getStaticData(std::string *result) const override; + void step(float dtime, bool send_recommended) override; + void setBasePosition(v3f position); + void setPos(const v3f &pos) override; + void moveTo(v3f pos, bool continuous) override; + void setPlayerYaw(const float yaw); + // Data should not be sent at player initialization + void setPlayerYawAndSend(const float yaw); + void setLookPitch(const float pitch); + // Data should not be sent at player initialization + void setLookPitchAndSend(const float pitch); + f32 getLookPitch() const { return m_pitch; } + f32 getRadLookPitch() const { return m_pitch * core::DEGTORAD; } + // Deprecated + f32 getRadLookPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; } + void setFov(const float pitch); + f32 getFov() const { return m_fov; } + void setWantedRange(const s16 range); + s16 getWantedRange() const { return m_wanted_range; } + + /* + Interaction interface + */ + + u32 punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher, + float time_from_last_punch, u16 initial_wear = 0) override; + void rightClick(ServerActiveObject *clicker) override; + void setHP(s32 hp, const PlayerHPChangeReason &reason) override + { + return setHP(hp, reason, false); + } + void setHP(s32 hp, const PlayerHPChangeReason &reason, bool from_client); + void setHPRaw(u16 hp) { m_hp = hp; } + u16 getBreath() const { return m_breath; } + void setBreath(const u16 breath, bool send = true); + + /* + Inventory interface + */ + Inventory *getInventory() const override; + InventoryLocation getInventoryLocation() const override; + void setInventoryModified() override {} + std::string getWieldList() const override { return "main"; } + u16 getWieldIndex() const override; + ItemStack getWieldedItem(ItemStack *selected, ItemStack *hand = nullptr) const override; + bool setWieldedItem(const ItemStack &item) override; + + /* + PlayerSAO-specific + */ + + void disconnected(); + + RemotePlayer *getPlayer() { return m_player; } + session_t getPeerID() const { return m_peer_id; } + + // Cheat prevention + + v3f getLastGoodPosition() const { return m_last_good_position; } + float resetTimeFromLastPunch() + { + float r = m_time_from_last_punch; + m_time_from_last_punch = 0.0; + return r; + } + void noCheatDigStart(const v3s16 &p) + { + m_nocheat_dig_pos = p; + m_nocheat_dig_time = 0; + } + v3s16 getNoCheatDigPos() { return m_nocheat_dig_pos; } + float getNoCheatDigTime() { return m_nocheat_dig_time; } + void noCheatDigEnd() { m_nocheat_dig_pos = v3s16(32767, 32767, 32767); } + LagPool &getDigPool() { return m_dig_pool; } + void setMaxSpeedOverride(const v3f &vel); + // Returns true if cheated + bool checkMovementCheat(); + + // Other + + void updatePrivileges(const std::set<std::string> &privs, bool is_singleplayer) + { + m_privs = privs; + m_is_singleplayer = is_singleplayer; + } + + bool getCollisionBox(aabb3f *toset) const override; + bool getSelectionBox(aabb3f *toset) const override; + bool collideWithObjects() const override { return true; } + + void finalize(RemotePlayer *player, const std::set<std::string> &privs); + + v3f getEyePosition() const { return m_base_position + getEyeOffset(); } + v3f getEyeOffset() const; + float getZoomFOV() const; + + inline Metadata &getMeta() { return m_meta; } + +private: + std::string getPropertyPacket(); + void unlinkPlayerSessionAndSave(); + std::string generateUpdatePhysicsOverrideCommand() const; + + RemotePlayer *m_player = nullptr; + session_t m_peer_id = 0; + + // Cheat prevention + LagPool m_dig_pool; + LagPool m_move_pool; + v3f m_last_good_position; + float m_time_from_last_teleport = 0.0f; + float m_time_from_last_punch = 0.0f; + v3s16 m_nocheat_dig_pos = v3s16(32767, 32767, 32767); + float m_nocheat_dig_time = 0.0f; + float m_max_speed_override_time = 0.0f; + v3f m_max_speed_override = v3f(0.0f, 0.0f, 0.0f); + + // Timers + IntervalLimiter m_breathing_interval; + IntervalLimiter m_drowning_interval; + IntervalLimiter m_node_hurt_interval; + + bool m_position_not_sent = false; + + // Cached privileges for enforcement + std::set<std::string> m_privs; + bool m_is_singleplayer; + + u16 m_breath = PLAYER_MAX_BREATH_DEFAULT; + f32 m_pitch = 0.0f; + f32 m_fov = 0.0f; + s16 m_wanted_range = 0.0f; + + Metadata m_meta; + +public: + float m_physics_override_speed = 1.0f; + float m_physics_override_jump = 1.0f; + float m_physics_override_gravity = 1.0f; + bool m_physics_override_sneak = true; + bool m_physics_override_sneak_glitch = false; + bool m_physics_override_new_move = true; + bool m_physics_override_sent = false; +}; + +struct PlayerHPChangeReason +{ + enum Type : u8 + { + SET_HP, + SET_HP_MAX, // internal type to allow distinguishing hp reset and damage (for effects) + PLAYER_PUNCH, + FALL, + NODE_DAMAGE, + DROWNING, + RESPAWN + }; + + Type type = SET_HP; + bool from_mod = false; + int lua_reference = -1; + + // For PLAYER_PUNCH + ServerActiveObject *object = nullptr; + // For NODE_DAMAGE + std::string node; + + inline bool hasLuaReference() const { return lua_reference >= 0; } + + bool setTypeFromString(const std::string &typestr) + { + if (typestr == "set_hp") + type = SET_HP; + else if (typestr == "punch") + type = PLAYER_PUNCH; + else if (typestr == "fall") + type = FALL; + else if (typestr == "node_damage") + type = NODE_DAMAGE; + else if (typestr == "drown") + type = DROWNING; + else if (typestr == "respawn") + type = RESPAWN; + else + return false; + + return true; + } + + std::string getTypeAsString() const + { + switch (type) { + case PlayerHPChangeReason::SET_HP: + case PlayerHPChangeReason::SET_HP_MAX: + return "set_hp"; + case PlayerHPChangeReason::PLAYER_PUNCH: + return "punch"; + case PlayerHPChangeReason::FALL: + return "fall"; + case PlayerHPChangeReason::NODE_DAMAGE: + return "node_damage"; + case PlayerHPChangeReason::DROWNING: + return "drown"; + case PlayerHPChangeReason::RESPAWN: + return "respawn"; + default: + return "?"; + } + } + + PlayerHPChangeReason(Type type) : type(type) {} + + PlayerHPChangeReason(Type type, ServerActiveObject *object) : + type(type), object(object) + { + } + + PlayerHPChangeReason(Type type, std::string node) : type(type), node(node) {} +}; diff --git a/src/server/serveractiveobject.cpp b/src/server/serveractiveobject.cpp new file mode 100644 index 0000000..96b433d --- /dev/null +++ b/src/server/serveractiveobject.cpp @@ -0,0 +1,91 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "serveractiveobject.h" +#include <fstream> +#include "inventory.h" +#include "constants.h" // BS +#include "log.h" + +ServerActiveObject::ServerActiveObject(ServerEnvironment *env, v3f pos): + ActiveObject(0), + m_env(env), + m_base_position(pos) +{ +} + +float ServerActiveObject::getMinimumSavedMovement() +{ + return 2.0*BS; +} + +ItemStack ServerActiveObject::getWieldedItem(ItemStack *selected, ItemStack *hand) const +{ + *selected = ItemStack(); + if (hand) + *hand = ItemStack(); + + return ItemStack(); +} + +bool ServerActiveObject::setWieldedItem(const ItemStack &item) +{ + return false; +} + +std::string ServerActiveObject::generateUpdateInfantCommand(u16 infant_id, u16 protocol_version) +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, AO_CMD_SPAWN_INFANT); + // parameters + writeU16(os, infant_id); + writeU8(os, getSendType()); + if (protocol_version < 38) { + // Clients since 4aa9a66 so no longer need this data + // Version 38 is the first bump after that commit. + // See also: ClientEnvironment::addActiveObject + os << serializeString32(getClientInitializationData(protocol_version)); + } + return os.str(); +} + +void ServerActiveObject::dumpAOMessagesToQueue(std::queue<ActiveObjectMessage> &queue) +{ + while (!m_messages_out.empty()) { + queue.push(std::move(m_messages_out.front())); + m_messages_out.pop(); + } +} + +void ServerActiveObject::markForRemoval() +{ + if (!m_pending_removal) { + onMarkedForRemoval(); + m_pending_removal = true; + } +} + +void ServerActiveObject::markForDeactivation() +{ + if (!m_pending_deactivation) { + onMarkedForDeactivation(); + m_pending_deactivation = true; + } +} diff --git a/src/server/serveractiveobject.h b/src/server/serveractiveobject.h new file mode 100644 index 0000000..5b0ee2d --- /dev/null +++ b/src/server/serveractiveobject.h @@ -0,0 +1,274 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <unordered_set> +#include "irrlichttypes_bloated.h" +#include "activeobject.h" +#include "inventorymanager.h" +#include "itemgroup.h" +#include "util/container.h" + +/* + +Some planning +------------- + +* Server environment adds an active object, which gets the id 1 +* The active object list is scanned for each client once in a while, + and it finds out what objects have been added that are not known + by the client yet. This scan is initiated by the Server class and + the result ends up directly to the server. +* A network packet is created with the info and sent to the client. +* Environment converts objects to static data and static data to + objects, based on how close players are to them. + +*/ + +class ServerEnvironment; +struct ItemStack; +struct ToolCapabilities; +struct ObjectProperties; +struct PlayerHPChangeReason; + +class ServerActiveObject : public ActiveObject +{ +public: + /* + NOTE: m_env can be NULL, but step() isn't called if it is. + Prototypes are used that way. + */ + ServerActiveObject(ServerEnvironment *env, v3f pos); + virtual ~ServerActiveObject() = default; + + virtual ActiveObjectType getSendType() const + { return getType(); } + + // Called after id has been set and has been inserted in environment + virtual void addedToEnvironment(u32 dtime_s){}; + // Called before removing from environment + virtual void removingFromEnvironment(){}; + // Returns true if object's deletion is the job of the + // environment + virtual bool environmentDeletes() const + { return true; } + + // Safely mark the object for removal or deactivation + void markForRemoval(); + void markForDeactivation(); + + // Create a certain type of ServerActiveObject + static ServerActiveObject* create(ActiveObjectType type, + ServerEnvironment *env, u16 id, v3f pos, + const std::string &data); + + /* + Some simple getters/setters + */ + v3f getBasePosition() const { return m_base_position; } + void setBasePosition(v3f pos){ m_base_position = pos; } + ServerEnvironment* getEnv(){ return m_env; } + + /* + Some more dynamic interface + */ + + virtual void setPos(const v3f &pos) + { setBasePosition(pos); } + // continuous: if true, object does not stop immediately at pos + virtual void moveTo(v3f pos, bool continuous) + { setBasePosition(pos); } + // If object has moved less than this and data has not changed, + // saving to disk may be omitted + virtual float getMinimumSavedMovement(); + + virtual std::string getDescription(){return "SAO";} + + /* + Step object in time. + Messages added to messages are sent to client over network. + + send_recommended: + True at around 5-10 times a second, same for all objects. + This is used to let objects send most of the data at the + same time so that the data can be combined in a single + packet. + */ + virtual void step(float dtime, bool send_recommended){} + + /* + The return value of this is passed to the client-side object + when it is created + */ + virtual std::string getClientInitializationData(u16 protocol_version) {return "";} + + /* + The return value of this is passed to the server-side object + when it is created (converted from static to active - actually + the data is the static form) + */ + virtual void getStaticData(std::string *result) const + { + assert(isStaticAllowed()); + *result = ""; + } + + /* + Return false in here to never save and instead remove object + on unload. getStaticData() will not be called in that case. + */ + virtual bool isStaticAllowed() const + {return true;} + + /* + Return false here to never unload the object. + isStaticAllowed && shouldUnload -> unload when out of active block range + !isStaticAllowed && shouldUnload -> unload when block is unloaded + */ + virtual bool shouldUnload() const + { return true; } + + // Returns added tool wear + virtual u32 punch(v3f dir, + const ToolCapabilities *toolcap = nullptr, + ServerActiveObject *puncher = nullptr, + float time_from_last_punch = 1000000.0f, + u16 initial_wear = 0) + { return 0; } + virtual void rightClick(ServerActiveObject *clicker) + {} + virtual void setHP(s32 hp, const PlayerHPChangeReason &reason) + {} + virtual u16 getHP() const + { return 0; } + + virtual void setArmorGroups(const ItemGroupList &armor_groups) + {} + virtual const ItemGroupList &getArmorGroups() const + { static ItemGroupList rv; return rv; } + virtual void setAnimation(v2f frames, float frame_speed, float frame_blend, bool frame_loop) + {} + virtual void getAnimation(v2f *frames, float *frame_speed, float *frame_blend, bool *frame_loop) + {} + virtual void setAnimationSpeed(float frame_speed) + {} + virtual void setBonePosition(const std::string &bone, v3f position, v3f rotation) + {} + virtual void getBonePosition(const std::string &bone, v3f *position, v3f *lotation) + {} + virtual const std::unordered_set<int> &getAttachmentChildIds() const + { static std::unordered_set<int> rv; return rv; } + virtual ServerActiveObject *getParent() const { return nullptr; } + virtual ObjectProperties* accessObjectProperties() + { return NULL; } + virtual void notifyObjectPropertiesModified() + {} + + // Inventory and wielded item + virtual Inventory *getInventory() const + { return NULL; } + virtual InventoryLocation getInventoryLocation() const + { return InventoryLocation(); } + virtual void setInventoryModified() + {} + virtual std::string getWieldList() const + { return ""; } + virtual u16 getWieldIndex() const + { return 0; } + virtual ItemStack getWieldedItem(ItemStack *selected, + ItemStack *hand = nullptr) const; + virtual bool setWieldedItem(const ItemStack &item); + inline void attachParticleSpawner(u32 id) + { + m_attached_particle_spawners.insert(id); + } + inline void detachParticleSpawner(u32 id) + { + m_attached_particle_spawners.erase(id); + } + + std::string generateUpdateInfantCommand(u16 infant_id, u16 protocol_version); + + void dumpAOMessagesToQueue(std::queue<ActiveObjectMessage> &queue); + + /* + Number of players which know about this object. Object won't be + deleted until this is 0 to keep the id preserved for the right + object. + */ + u16 m_known_by_count = 0; + + /* + A getter that unifies the above to answer the question: + "Can the environment still interact with this object?" + */ + inline bool isGone() const + { return m_pending_removal || m_pending_deactivation; } + + inline bool isPendingRemoval() const + { return m_pending_removal; } + + /* + Whether the object's static data has been stored to a block + */ + bool m_static_exists = false; + /* + The block from which the object was loaded from, and in which + a copy of the static data resides. + */ + v3s16 m_static_block = v3s16(1337,1337,1337); + +protected: + virtual void onMarkedForDeactivation() {} + virtual void onMarkedForRemoval() {} + + virtual void onAttach(int parent_id) {} + virtual void onDetach(int parent_id) {} + + ServerEnvironment *m_env; + v3f m_base_position; + std::unordered_set<u32> m_attached_particle_spawners; + + /* + Same purpose as m_pending_removal but for deactivation. + deactvation = save static data in block, remove active object + + If this is set alongside with m_pending_removal, removal takes + priority. + Note: Do not assign this directly, use markForDeactivation() instead. + */ + bool m_pending_deactivation = false; + + /* + - Whether this object is to be removed when nobody knows about + it anymore. + - Removal is delayed to preserve the id for the time during which + it could be confused to some other object by some client. + - This is usually set to true by the step() method when the object wants + to be deleted but can be set by anything else too. + Note: Do not assign this directly, use markForRemoval() instead. + */ + bool m_pending_removal = false; + + /* + Queue of messages to be sent to the client + */ + std::queue<ActiveObjectMessage> m_messages_out; +}; diff --git a/src/server/serverinventorymgr.cpp b/src/server/serverinventorymgr.cpp new file mode 100644 index 0000000..63d1645 --- /dev/null +++ b/src/server/serverinventorymgr.cpp @@ -0,0 +1,210 @@ +/* +Minetest +Copyright (C) 2010-2020 Minetest core development team + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "serverinventorymgr.h" +#include "map.h" +#include "nodemetadata.h" +#include "player_sao.h" +#include "remoteplayer.h" +#include "server.h" +#include "serverenvironment.h" + +ServerInventoryManager::ServerInventoryManager() : InventoryManager() +{ +} + +ServerInventoryManager::~ServerInventoryManager() +{ + // Delete detached inventories + for (auto &detached_inventory : m_detached_inventories) { + delete detached_inventory.second.inventory; + } +} + +Inventory *ServerInventoryManager::getInventory(const InventoryLocation &loc) +{ + // No m_env check here: allow creation and modification of detached inventories + + switch (loc.type) { + case InventoryLocation::UNDEFINED: + case InventoryLocation::CURRENT_PLAYER: + break; + case InventoryLocation::PLAYER: { + if (!m_env) + return nullptr; + + RemotePlayer *player = m_env->getPlayer(loc.name.c_str()); + if (!player) + return NULL; + + PlayerSAO *playersao = player->getPlayerSAO(); + return playersao ? playersao->getInventory() : nullptr; + } break; + case InventoryLocation::NODEMETA: { + if (!m_env) + return nullptr; + + NodeMetadata *meta = m_env->getMap().getNodeMetadata(loc.p); + return meta ? meta->getInventory() : nullptr; + } break; + case InventoryLocation::DETACHED: { + auto it = m_detached_inventories.find(loc.name); + if (it == m_detached_inventories.end()) + return nullptr; + return it->second.inventory; + } break; + default: + sanity_check(false); // abort + break; + } + return NULL; +} + +void ServerInventoryManager::setInventoryModified(const InventoryLocation &loc) +{ + switch (loc.type) { + case InventoryLocation::UNDEFINED: + break; + case InventoryLocation::PLAYER: { + + RemotePlayer *player = m_env->getPlayer(loc.name.c_str()); + + if (!player) + return; + + player->setModified(true); + player->inventory.setModified(true); + // Updates are sent in ServerEnvironment::step() + } break; + case InventoryLocation::NODEMETA: { + MapEditEvent event; + event.type = MEET_BLOCK_NODE_METADATA_CHANGED; + event.p = loc.p; + m_env->getMap().dispatchEvent(event); + } break; + case InventoryLocation::DETACHED: { + // Updates are sent in ServerEnvironment::step() + } break; + default: + sanity_check(false); // abort + break; + } +} + +Inventory *ServerInventoryManager::createDetachedInventory( + const std::string &name, IItemDefManager *idef, const std::string &player) +{ + if (m_detached_inventories.count(name) > 0) { + infostream << "Server clearing detached inventory \"" << name << "\"" + << std::endl; + delete m_detached_inventories[name].inventory; + } else { + infostream << "Server creating detached inventory \"" << name << "\"" + << std::endl; + } + + Inventory *inv = new Inventory(idef); + sanity_check(inv); + m_detached_inventories[name].inventory = inv; + if (!player.empty()) { + m_detached_inventories[name].owner = player; + + if (!m_env) + return inv; // Mods are not loaded yet, ignore + + RemotePlayer *p = m_env->getPlayer(name.c_str()); + + // if player is connected, send him the inventory + if (p && p->getPeerId() != PEER_ID_INEXISTENT) { + m_env->getGameDef()->sendDetachedInventory( + inv, name, p->getPeerId()); + } + } else { + if (!m_env) + return inv; // Mods are not loaded yet, don't send + + // Inventory is for everybody, broadcast + m_env->getGameDef()->sendDetachedInventory(inv, name, PEER_ID_INEXISTENT); + } + + return inv; +} + +bool ServerInventoryManager::removeDetachedInventory(const std::string &name) +{ + const auto &inv_it = m_detached_inventories.find(name); + if (inv_it == m_detached_inventories.end()) + return false; + + delete inv_it->second.inventory; + const std::string &owner = inv_it->second.owner; + + if (!owner.empty()) { + if (m_env) { + RemotePlayer *player = m_env->getPlayer(owner.c_str()); + + if (player && player->getPeerId() != PEER_ID_INEXISTENT) + m_env->getGameDef()->sendDetachedInventory( + nullptr, name, player->getPeerId()); + } + } else if (m_env) { + // Notify all players about the change as soon ServerEnv exists + m_env->getGameDef()->sendDetachedInventory( + nullptr, name, PEER_ID_INEXISTENT); + } + + m_detached_inventories.erase(inv_it); + + return true; +} + +bool ServerInventoryManager::checkDetachedInventoryAccess( + const InventoryLocation &loc, const std::string &player) const +{ + SANITY_CHECK(loc.type == InventoryLocation::DETACHED); + + const auto &inv_it = m_detached_inventories.find(loc.name); + if (inv_it == m_detached_inventories.end()) + return false; + + return inv_it->second.owner.empty() || inv_it->second.owner == player; +} + +void ServerInventoryManager::sendDetachedInventories(const std::string &peer_name, + bool incremental, + std::function<void(const std::string &, Inventory *)> apply_cb) +{ + for (const auto &detached_inventory : m_detached_inventories) { + const DetachedInventory &dinv = detached_inventory.second; + if (incremental) { + if (!dinv.inventory || !dinv.inventory->checkModified()) + continue; + } + + // if we are pushing inventories to a specific player + // we should filter to send only the right inventories + if (!peer_name.empty()) { + const std::string &attached_player = dinv.owner; + if (!attached_player.empty() && peer_name != attached_player) + continue; + } + + apply_cb(detached_inventory.first, detached_inventory.second.inventory); + } +} diff --git a/src/server/serverinventorymgr.h b/src/server/serverinventorymgr.h new file mode 100644 index 0000000..0e4b724 --- /dev/null +++ b/src/server/serverinventorymgr.h @@ -0,0 +1,61 @@ +/* +Minetest +Copyright (C) 2010-2020 Minetest core development team + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "inventorymanager.h" +#include <functional> + +class ServerEnvironment; + +class ServerInventoryManager : public InventoryManager +{ +public: + ServerInventoryManager(); + virtual ~ServerInventoryManager(); + + void setEnv(ServerEnvironment *env) + { + assert(!m_env); + m_env = env; + } + + Inventory *getInventory(const InventoryLocation &loc); + void setInventoryModified(const InventoryLocation &loc); + + // Creates or resets inventory + Inventory *createDetachedInventory(const std::string &name, IItemDefManager *idef, + const std::string &player = ""); + bool removeDetachedInventory(const std::string &name); + bool checkDetachedInventoryAccess(const InventoryLocation &loc, const std::string &player) const; + + void sendDetachedInventories(const std::string &peer_name, bool incremental, + std::function<void(const std::string &, Inventory *)> apply_cb); + +private: + struct DetachedInventory + { + Inventory *inventory; + std::string owner; + }; + + ServerEnvironment *m_env = nullptr; + + std::unordered_map<std::string, DetachedInventory> m_detached_inventories; +}; diff --git a/src/server/unit_sao.cpp b/src/server/unit_sao.cpp new file mode 100644 index 0000000..9a49b0f --- /dev/null +++ b/src/server/unit_sao.cpp @@ -0,0 +1,369 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013-2020 Minetest core developers & community + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "unit_sao.h" +#include "scripting_server.h" +#include "serverenvironment.h" + +UnitSAO::UnitSAO(ServerEnvironment *env, v3f pos) : ServerActiveObject(env, pos) +{ + // Initialize something to armor groups + m_armor_groups["fleshy"] = 100; +} + +ServerActiveObject *UnitSAO::getParent() const +{ + if (!m_attachment_parent_id) + return nullptr; + // Check if the parent still exists + ServerActiveObject *obj = m_env->getActiveObject(m_attachment_parent_id); + + return obj; +} + +void UnitSAO::setArmorGroups(const ItemGroupList &armor_groups) +{ + m_armor_groups = armor_groups; + m_armor_groups_sent = false; +} + +const ItemGroupList &UnitSAO::getArmorGroups() const +{ + return m_armor_groups; +} + +void UnitSAO::setAnimation( + v2f frame_range, float frame_speed, float frame_blend, bool frame_loop) +{ + // store these so they can be updated to clients + m_animation_range = frame_range; + m_animation_speed = frame_speed; + m_animation_blend = frame_blend; + m_animation_loop = frame_loop; + m_animation_sent = false; +} + +void UnitSAO::getAnimation(v2f *frame_range, float *frame_speed, float *frame_blend, + bool *frame_loop) +{ + *frame_range = m_animation_range; + *frame_speed = m_animation_speed; + *frame_blend = m_animation_blend; + *frame_loop = m_animation_loop; +} + +void UnitSAO::setAnimationSpeed(float frame_speed) +{ + m_animation_speed = frame_speed; + m_animation_speed_sent = false; +} + +void UnitSAO::setBonePosition(const std::string &bone, v3f position, v3f rotation) +{ + // store these so they can be updated to clients + m_bone_position[bone] = core::vector2d<v3f>(position, rotation); + m_bone_position_sent = false; +} + +void UnitSAO::getBonePosition(const std::string &bone, v3f *position, v3f *rotation) +{ + auto it = m_bone_position.find(bone); + if (it != m_bone_position.end()) { + *position = it->second.X; + *rotation = it->second.Y; + } +} + +// clang-format off +void UnitSAO::sendOutdatedData() +{ + if (!m_armor_groups_sent) { + m_armor_groups_sent = true; + m_messages_out.emplace(getId(), true, generateUpdateArmorGroupsCommand()); + } + + if (!m_animation_sent) { + m_animation_sent = true; + m_animation_speed_sent = true; + m_messages_out.emplace(getId(), true, generateUpdateAnimationCommand()); + } else if (!m_animation_speed_sent) { + // Animation speed is also sent when 'm_animation_sent == false' + m_animation_speed_sent = true; + m_messages_out.emplace(getId(), true, generateUpdateAnimationSpeedCommand()); + } + + if (!m_bone_position_sent) { + m_bone_position_sent = true; + for (const auto &bone_pos : m_bone_position) { + m_messages_out.emplace(getId(), true, generateUpdateBonePositionCommand( + bone_pos.first, bone_pos.second.X, bone_pos.second.Y)); + } + } + + if (!m_attachment_sent) { + m_attachment_sent = true; + m_messages_out.emplace(getId(), true, generateUpdateAttachmentCommand()); + } +} +// clang-format on + +void UnitSAO::setAttachment(int parent_id, const std::string &bone, v3f position, + v3f rotation, bool force_visible) +{ + auto *obj = parent_id ? m_env->getActiveObject(parent_id) : nullptr; + if (obj) { + // Do checks to avoid circular references + // The chain of wanted parent must not refer or contain "this" + for (obj = obj->getParent(); obj; obj = obj->getParent()) { + if (obj == this) { + warningstream << "Mod bug: Attempted to attach object " << m_id << " to parent " + << parent_id << " but former is an (in)direct parent of latter." << std::endl; + return; + } + } + } + + // Attachments need to be handled on both the server and client. + // If we just attach on the server, we can only copy the position of the parent. + // Attachments are still sent to clients at an interval so players might see them + // lagging, plus we can't read and attach to skeletal bones. If we just attach on + // the client, the server still sees the child at its original location. This + // breaks some things so we also give the server the most accurate representation + // even if players only see the client changes. + + int old_parent = m_attachment_parent_id; + m_attachment_parent_id = parent_id; + + // The detach callbacks might call to setAttachment() again. + // Ensure the attachment params are applied after this callback is run. + if (parent_id != old_parent) + onDetach(old_parent); + + m_attachment_parent_id = parent_id; + m_attachment_bone = bone; + m_attachment_position = position; + m_attachment_rotation = rotation; + m_force_visible = force_visible; + m_attachment_sent = false; + + if (parent_id != old_parent) + onAttach(parent_id); +} + +void UnitSAO::getAttachment(int *parent_id, std::string *bone, v3f *position, + v3f *rotation, bool *force_visible) const +{ + *parent_id = m_attachment_parent_id; + *bone = m_attachment_bone; + *position = m_attachment_position; + *rotation = m_attachment_rotation; + *force_visible = m_force_visible; +} + +void UnitSAO::clearChildAttachments() +{ + for (int child_id : m_attachment_child_ids) { + // Child can be NULL if it was deleted earlier + if (ServerActiveObject *child = m_env->getActiveObject(child_id)) + child->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0), false); + } + m_attachment_child_ids.clear(); +} + +void UnitSAO::clearParentAttachment() +{ + ServerActiveObject *parent = nullptr; + if (m_attachment_parent_id) { + parent = m_env->getActiveObject(m_attachment_parent_id); + setAttachment(0, "", m_attachment_position, m_attachment_rotation, false); + } else { + setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0), false); + } + // Do it + if (parent) + parent->removeAttachmentChild(m_id); +} + +void UnitSAO::addAttachmentChild(int child_id) +{ + m_attachment_child_ids.insert(child_id); +} + +void UnitSAO::removeAttachmentChild(int child_id) +{ + m_attachment_child_ids.erase(child_id); +} + +const std::unordered_set<int> &UnitSAO::getAttachmentChildIds() const +{ + return m_attachment_child_ids; +} + +void UnitSAO::onAttach(int parent_id) +{ + if (!parent_id) + return; + + ServerActiveObject *parent = m_env->getActiveObject(parent_id); + + if (!parent || parent->isGone()) + return; // Do not try to notify soon gone parent + + if (parent->getType() == ACTIVEOBJECT_TYPE_LUAENTITY) { + // Call parent's on_attach field + m_env->getScriptIface()->luaentity_on_attach_child(parent_id, this); + } +} + +void UnitSAO::onDetach(int parent_id) +{ + if (!parent_id) + return; + + ServerActiveObject *parent = m_env->getActiveObject(parent_id); + if (getType() == ACTIVEOBJECT_TYPE_LUAENTITY) + m_env->getScriptIface()->luaentity_on_detach(m_id, parent); + + if (!parent || parent->isGone()) + return; // Do not try to notify soon gone parent + + if (parent->getType() == ACTIVEOBJECT_TYPE_LUAENTITY) + m_env->getScriptIface()->luaentity_on_detach_child(parent_id, this); +} + +ObjectProperties *UnitSAO::accessObjectProperties() +{ + return &m_prop; +} + +void UnitSAO::notifyObjectPropertiesModified() +{ + m_properties_sent = false; +} + +std::string UnitSAO::generateUpdateAttachmentCommand() const +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, AO_CMD_ATTACH_TO); + // parameters + writeS16(os, m_attachment_parent_id); + os << serializeString16(m_attachment_bone); + writeV3F32(os, m_attachment_position); + writeV3F32(os, m_attachment_rotation); + writeU8(os, m_force_visible); + return os.str(); +} + +std::string UnitSAO::generateUpdateBonePositionCommand( + const std::string &bone, const v3f &position, const v3f &rotation) +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, AO_CMD_SET_BONE_POSITION); + // parameters + os << serializeString16(bone); + writeV3F32(os, position); + writeV3F32(os, rotation); + return os.str(); +} + +std::string UnitSAO::generateUpdateAnimationSpeedCommand() const +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, AO_CMD_SET_ANIMATION_SPEED); + // parameters + writeF32(os, m_animation_speed); + return os.str(); +} + +std::string UnitSAO::generateUpdateAnimationCommand() const +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, AO_CMD_SET_ANIMATION); + // parameters + writeV2F32(os, m_animation_range); + writeF32(os, m_animation_speed); + writeF32(os, m_animation_blend); + // these are sent inverted so we get true when the server sends nothing + writeU8(os, !m_animation_loop); + return os.str(); +} + +std::string UnitSAO::generateUpdateArmorGroupsCommand() const +{ + std::ostringstream os(std::ios::binary); + writeU8(os, AO_CMD_UPDATE_ARMOR_GROUPS); + writeU16(os, m_armor_groups.size()); + for (const auto &armor_group : m_armor_groups) { + os << serializeString16(armor_group.first); + writeS16(os, armor_group.second); + } + return os.str(); +} + +std::string UnitSAO::generateUpdatePositionCommand(const v3f &position, + const v3f &velocity, const v3f &acceleration, const v3f &rotation, + bool do_interpolate, bool is_movement_end, f32 update_interval) +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, AO_CMD_UPDATE_POSITION); + // pos + writeV3F32(os, position); + // velocity + writeV3F32(os, velocity); + // acceleration + writeV3F32(os, acceleration); + // rotation + writeV3F32(os, rotation); + // do_interpolate + writeU8(os, do_interpolate); + // is_end_position (for interpolation) + writeU8(os, is_movement_end); + // update_interval (for interpolation) + writeF32(os, update_interval); + return os.str(); +} + +std::string UnitSAO::generateSetPropertiesCommand(const ObjectProperties &prop) const +{ + std::ostringstream os(std::ios::binary); + writeU8(os, AO_CMD_SET_PROPERTIES); + prop.serialize(os); + return os.str(); +} + +std::string UnitSAO::generatePunchCommand(u16 result_hp) const +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, AO_CMD_PUNCHED); + // result_hp + writeU16(os, result_hp); + return os.str(); +} + +void UnitSAO::sendPunchCommand() +{ + m_messages_out.emplace(getId(), true, generatePunchCommand(getHP())); +} diff --git a/src/server/unit_sao.h b/src/server/unit_sao.h new file mode 100644 index 0000000..a21e055 --- /dev/null +++ b/src/server/unit_sao.h @@ -0,0 +1,137 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2013-2020 Minetest core developers & community + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "object_properties.h" +#include "serveractiveobject.h" + +class UnitSAO : public ServerActiveObject +{ +public: + UnitSAO(ServerEnvironment *env, v3f pos); + virtual ~UnitSAO() = default; + + u16 getHP() const { return m_hp; } + // Use a function, if isDead can be defined by other conditions + bool isDead() const { return m_hp == 0; } + + // Rotation + void setRotation(v3f rotation) { m_rotation = rotation; } + const v3f &getRotation() const { return m_rotation; } + v3f getRadRotation() { return m_rotation * core::DEGTORAD; } + + // Deprecated + f32 getRadYawDep() const { return (m_rotation.Y + 90.) * core::DEGTORAD; } + + // Armor groups + inline bool isImmortal() const + { + return itemgroup_get(getArmorGroups(), "immortal"); + } + void setArmorGroups(const ItemGroupList &armor_groups); + const ItemGroupList &getArmorGroups() const; + + // Animation + void setAnimation(v2f frame_range, float frame_speed, float frame_blend, + bool frame_loop); + void getAnimation(v2f *frame_range, float *frame_speed, float *frame_blend, + bool *frame_loop); + void setAnimationSpeed(float frame_speed); + + // Bone position + void setBonePosition(const std::string &bone, v3f position, v3f rotation); + void getBonePosition(const std::string &bone, v3f *position, v3f *rotation); + + // Attachments + ServerActiveObject *getParent() const; + inline bool isAttached() const { return getParent(); } + void setAttachment(int parent_id, const std::string &bone, v3f position, + v3f rotation, bool force_visible); + void getAttachment(int *parent_id, std::string *bone, v3f *position, + v3f *rotation, bool *force_visible) const; + void clearChildAttachments(); + void clearParentAttachment(); + void addAttachmentChild(int child_id); + void removeAttachmentChild(int child_id); + const std::unordered_set<int> &getAttachmentChildIds() const; + + // Object properties + ObjectProperties *accessObjectProperties(); + void notifyObjectPropertiesModified(); + void sendOutdatedData(); + + // Update packets + std::string generateUpdateAttachmentCommand() const; + std::string generateUpdateAnimationSpeedCommand() const; + std::string generateUpdateAnimationCommand() const; + std::string generateUpdateArmorGroupsCommand() const; + static std::string generateUpdatePositionCommand(const v3f &position, + const v3f &velocity, const v3f &acceleration, const v3f &rotation, + bool do_interpolate, bool is_movement_end, f32 update_interval); + std::string generateSetPropertiesCommand(const ObjectProperties &prop) const; + static std::string generateUpdateBonePositionCommand(const std::string &bone, + const v3f &position, const v3f &rotation); + void sendPunchCommand(); + +protected: + u16 m_hp = 1; + + v3f m_rotation; + + ItemGroupList m_armor_groups; + + // Object properties + bool m_properties_sent = true; + ObjectProperties m_prop; + + // Stores position and rotation for each bone name + std::unordered_map<std::string, core::vector2d<v3f>> m_bone_position; + + int m_attachment_parent_id = 0; + +private: + void onAttach(int parent_id); + void onDetach(int parent_id); + + std::string generatePunchCommand(u16 result_hp) const; + + // Armor groups + bool m_armor_groups_sent = false; + + // Animation + v2f m_animation_range; + float m_animation_speed = 0.0f; + float m_animation_blend = 0.0f; + bool m_animation_loop = true; + bool m_animation_sent = false; + bool m_animation_speed_sent = false; + + // Bone positions + bool m_bone_position_sent = false; + + // Attachments + std::unordered_set<int> m_attachment_child_ids; + std::string m_attachment_bone = ""; + v3f m_attachment_position; + v3f m_attachment_rotation; + bool m_attachment_sent = false; + bool m_force_visible = false; +}; diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp new file mode 100644 index 0000000..8989fb0 --- /dev/null +++ b/src/serverenvironment.cpp @@ -0,0 +1,2436 @@ +/* +Minetest +Copyright (C) 2010-2017 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <algorithm> +#include "serverenvironment.h" +#include "settings.h" +#include "log.h" +#include "mapblock.h" +#include "nodedef.h" +#include "nodemetadata.h" +#include "gamedef.h" +#include "map.h" +#include "porting.h" +#include "profiler.h" +#include "raycast.h" +#include "remoteplayer.h" +#include "scripting_server.h" +#include "server.h" +#include "util/serialize.h" +#include "util/basic_macros.h" +#include "util/pointedthing.h" +#include "threading/mutex_auto_lock.h" +#include "filesys.h" +#include "gameparams.h" +#include "database/database-dummy.h" +#include "database/database-files.h" +#include "database/database-sqlite3.h" +#if USE_POSTGRESQL +#include "database/database-postgresql.h" +#endif +#if USE_LEVELDB +#include "database/database-leveldb.h" +#endif +#include "server/luaentity_sao.h" +#include "server/player_sao.h" + +#define LBM_NAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_:" + +// A number that is much smaller than the timeout for particle spawners should/could ever be +#define PARTICLE_SPAWNER_NO_EXPIRY -1024.f + +/* + ABMWithState +*/ + +ABMWithState::ABMWithState(ActiveBlockModifier *abm_): + abm(abm_) +{ + // Initialize timer to random value to spread processing + float itv = abm->getTriggerInterval(); + itv = MYMAX(0.001, itv); // No less than 1ms + int minval = MYMAX(-0.51*itv, -60); // Clamp to + int maxval = MYMIN(0.51*itv, 60); // +-60 seconds + timer = myrand_range(minval, maxval); +} + +/* + LBMManager +*/ + +void LBMContentMapping::deleteContents() +{ + for (auto &it : lbm_list) { + delete it; + } +} + +void LBMContentMapping::addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamedef) +{ + // Add the lbm_def to the LBMContentMapping. + // Unknown names get added to the global NameIdMapping. + const NodeDefManager *nodedef = gamedef->ndef(); + + lbm_list.push_back(lbm_def); + + for (const std::string &nodeTrigger: lbm_def->trigger_contents) { + std::vector<content_t> c_ids; + bool found = nodedef->getIds(nodeTrigger, c_ids); + if (!found) { + content_t c_id = gamedef->allocateUnknownNodeId(nodeTrigger); + if (c_id == CONTENT_IGNORE) { + // Seems it can't be allocated. + warningstream << "Could not internalize node name \"" << nodeTrigger + << "\" while loading LBM \"" << lbm_def->name << "\"." << std::endl; + continue; + } + c_ids.push_back(c_id); + } + + for (content_t c_id : c_ids) { + map[c_id].push_back(lbm_def); + } + } +} + +const std::vector<LoadingBlockModifierDef *> * +LBMContentMapping::lookup(content_t c) const +{ + lbm_map::const_iterator it = map.find(c); + if (it == map.end()) + return NULL; + // This first dereferences the iterator, returning + // a std::vector<LoadingBlockModifierDef *> + // reference, then we convert it to a pointer. + return &(it->second); +} + +LBMManager::~LBMManager() +{ + for (auto &m_lbm_def : m_lbm_defs) { + delete m_lbm_def.second; + } + + for (auto &it : m_lbm_lookup) { + (it.second).deleteContents(); + } +} + +void LBMManager::addLBMDef(LoadingBlockModifierDef *lbm_def) +{ + // Precondition, in query mode the map isn't used anymore + FATAL_ERROR_IF(m_query_mode, + "attempted to modify LBMManager in query mode"); + + if (!string_allowed(lbm_def->name, LBM_NAME_ALLOWED_CHARS)) { + throw ModError("Error adding LBM \"" + lbm_def->name + + "\": Does not follow naming conventions: " + "Only characters [a-z0-9_:] are allowed."); + } + + m_lbm_defs[lbm_def->name] = lbm_def; +} + +void LBMManager::loadIntroductionTimes(const std::string ×, + IGameDef *gamedef, u32 now) +{ + m_query_mode = true; + + // name -> time map. + // Storing it in a map first instead of + // handling the stuff directly in the loop + // removes all duplicate entries. + // TODO make this std::unordered_map + std::map<std::string, u32> introduction_times; + + /* + The introduction times string consists of name~time entries, + with each entry terminated by a semicolon. The time is decimal. + */ + + size_t idx = 0; + size_t idx_new; + while ((idx_new = times.find(';', idx)) != std::string::npos) { + std::string entry = times.substr(idx, idx_new - idx); + std::vector<std::string> components = str_split(entry, '~'); + if (components.size() != 2) + throw SerializationError("Introduction times entry \"" + + entry + "\" requires exactly one '~'!"); + const std::string &name = components[0]; + u32 time = from_string<u32>(components[1]); + introduction_times[name] = time; + idx = idx_new + 1; + } + + // Put stuff from introduction_times into m_lbm_lookup + for (std::map<std::string, u32>::const_iterator it = introduction_times.begin(); + it != introduction_times.end(); ++it) { + const std::string &name = it->first; + u32 time = it->second; + + std::map<std::string, LoadingBlockModifierDef *>::iterator def_it = + m_lbm_defs.find(name); + if (def_it == m_lbm_defs.end()) { + // This seems to be an LBM entry for + // an LBM we haven't loaded. Discard it. + continue; + } + LoadingBlockModifierDef *lbm_def = def_it->second; + if (lbm_def->run_at_every_load) { + // This seems to be an LBM entry for + // an LBM that runs at every load. + // Don't add it just yet. + continue; + } + + m_lbm_lookup[time].addLBM(lbm_def, gamedef); + + // Erase the entry so that we know later + // what elements didn't get put into m_lbm_lookup + m_lbm_defs.erase(name); + } + + // Now also add the elements from m_lbm_defs to m_lbm_lookup + // that weren't added in the previous step. + // They are introduced first time to this world, + // or are run at every load (introducement time hardcoded to U32_MAX). + + LBMContentMapping &lbms_we_introduce_now = m_lbm_lookup[now]; + LBMContentMapping &lbms_running_always = m_lbm_lookup[U32_MAX]; + + for (auto &m_lbm_def : m_lbm_defs) { + if (m_lbm_def.second->run_at_every_load) { + lbms_running_always.addLBM(m_lbm_def.second, gamedef); + } else { + lbms_we_introduce_now.addLBM(m_lbm_def.second, gamedef); + } + } + + // Clear the list, so that we don't delete remaining elements + // twice in the destructor + m_lbm_defs.clear(); +} + +std::string LBMManager::createIntroductionTimesString() +{ + // Precondition, we must be in query mode + FATAL_ERROR_IF(!m_query_mode, + "attempted to query on non fully set up LBMManager"); + + std::ostringstream oss; + for (const auto &it : m_lbm_lookup) { + u32 time = it.first; + const std::vector<LoadingBlockModifierDef *> &lbm_list = it.second.lbm_list; + for (const auto &lbm_def : lbm_list) { + // Don't add if the LBM runs at every load, + // then introducement time is hardcoded + // and doesn't need to be stored + if (lbm_def->run_at_every_load) + continue; + oss << lbm_def->name << "~" << time << ";"; + } + } + return oss.str(); +} + +void LBMManager::applyLBMs(ServerEnvironment *env, MapBlock *block, u32 stamp) +{ + // Precondition, we need m_lbm_lookup to be initialized + FATAL_ERROR_IF(!m_query_mode, + "attempted to query on non fully set up LBMManager"); + v3s16 pos_of_block = block->getPosRelative(); + v3s16 pos; + MapNode n; + content_t c; + bool pos_valid; // dummy, we know it's valid + auto it = getLBMsIntroducedAfter(stamp); + for (; it != m_lbm_lookup.end(); ++it) { + // Cache previous version to speedup lookup which has a very high performance + // penalty on each call + content_t previous_c = CONTENT_IGNORE; + const std::vector<LoadingBlockModifierDef *> *lbm_list = nullptr; + + for (pos.X = 0; pos.X < MAP_BLOCKSIZE; pos.X++) + for (pos.Y = 0; pos.Y < MAP_BLOCKSIZE; pos.Y++) + for (pos.Z = 0; pos.Z < MAP_BLOCKSIZE; pos.Z++) { + n = block->getNodeNoCheck(pos, &pos_valid); + c = n.getContent(); + + // If content_t are not matching perform an LBM lookup + if (previous_c != c) { + lbm_list = it->second.lookup(c); + previous_c = c; + } + + if (!lbm_list) + continue; + for (auto lbmdef : *lbm_list) { + lbmdef->trigger(env, pos + pos_of_block, n); + } + } + } +} + +/* + ActiveBlockList +*/ + +void fillRadiusBlock(v3s16 p0, s16 r, std::set<v3s16> &list) +{ + v3s16 p; + for(p.X=p0.X-r; p.X<=p0.X+r; p.X++) + for(p.Y=p0.Y-r; p.Y<=p0.Y+r; p.Y++) + for(p.Z=p0.Z-r; p.Z<=p0.Z+r; p.Z++) + { + // limit to a sphere + if (p.getDistanceFrom(p0) <= r) { + // Set in list + list.insert(p); + } + } +} + +void fillViewConeBlock(v3s16 p0, + const s16 r, + const v3f camera_pos, + const v3f camera_dir, + const float camera_fov, + std::set<v3s16> &list) +{ + v3s16 p; + const s16 r_nodes = r * BS * MAP_BLOCKSIZE; + for (p.X = p0.X - r; p.X <= p0.X+r; p.X++) + for (p.Y = p0.Y - r; p.Y <= p0.Y+r; p.Y++) + for (p.Z = p0.Z - r; p.Z <= p0.Z+r; p.Z++) { + if (isBlockInSight(p, camera_pos, camera_dir, camera_fov, r_nodes)) { + list.insert(p); + } + } +} + +void ActiveBlockList::update(std::vector<PlayerSAO*> &active_players, + s16 active_block_range, + s16 active_object_range, + std::set<v3s16> &blocks_removed, + std::set<v3s16> &blocks_added) +{ + /* + Create the new list + */ + std::set<v3s16> newlist = m_forceloaded_list; + m_abm_list = m_forceloaded_list; + for (const PlayerSAO *playersao : active_players) { + v3s16 pos = getNodeBlockPos(floatToInt(playersao->getBasePosition(), BS)); + fillRadiusBlock(pos, active_block_range, m_abm_list); + fillRadiusBlock(pos, active_block_range, newlist); + + s16 player_ao_range = std::min(active_object_range, playersao->getWantedRange()); + // only do this if this would add blocks + if (player_ao_range > active_block_range) { + v3f camera_dir = v3f(0,0,1); + camera_dir.rotateYZBy(playersao->getLookPitch()); + camera_dir.rotateXZBy(playersao->getRotation().Y); + fillViewConeBlock(pos, + player_ao_range, + playersao->getEyePosition(), + camera_dir, + playersao->getFov(), + newlist); + } + } + + /* + Find out which blocks on the old list are not on the new list + */ + // Go through old list + for (v3s16 p : m_list) { + // If not on new list, it's been removed + if (newlist.find(p) == newlist.end()) + blocks_removed.insert(p); + } + + /* + Find out which blocks on the new list are not on the old list + */ + // Go through new list + for (v3s16 p : newlist) { + // If not on old list, it's been added + if(m_list.find(p) == m_list.end()) + blocks_added.insert(p); + } + + /* + Update m_list + */ + m_list = std::move(newlist); +} + +/* + ServerEnvironment +*/ + +// Random device to seed pseudo random generators. +static std::random_device seed; + +ServerEnvironment::ServerEnvironment(ServerMap *map, + ServerScripting *scriptIface, Server *server, + const std::string &path_world, MetricsBackend *mb): + Environment(server), + m_map(map), + m_script(scriptIface), + m_server(server), + m_path_world(path_world), + m_rgen(seed()) +{ + // Determine which database backend to use + std::string conf_path = path_world + DIR_DELIM + "world.mt"; + Settings conf; + + std::string player_backend_name = "sqlite3"; + std::string auth_backend_name = "sqlite3"; + + bool succeeded = conf.readConfigFile(conf_path.c_str()); + + // If we open world.mt read the backend configurations. + if (succeeded) { + // Read those values before setting defaults + bool player_backend_exists = conf.exists("player_backend"); + bool auth_backend_exists = conf.exists("auth_backend"); + + // player backend is not set, assume it's legacy file backend. + if (!player_backend_exists) { + // fall back to files + conf.set("player_backend", "files"); + player_backend_name = "files"; + + if (!conf.updateConfigFile(conf_path.c_str())) { + errorstream << "ServerEnvironment::ServerEnvironment(): " + << "Failed to update world.mt!" << std::endl; + } + } else { + conf.getNoEx("player_backend", player_backend_name); + } + + // auth backend is not set, assume it's legacy file backend. + if (!auth_backend_exists) { + conf.set("auth_backend", "files"); + auth_backend_name = "files"; + + if (!conf.updateConfigFile(conf_path.c_str())) { + errorstream << "ServerEnvironment::ServerEnvironment(): " + << "Failed to update world.mt!" << std::endl; + } + } else { + conf.getNoEx("auth_backend", auth_backend_name); + } + } + + if (player_backend_name == "files") { + warningstream << "/!\\ You are using old player file backend. " + << "This backend is deprecated and will be removed in a future release /!\\" + << std::endl << "Switching to SQLite3 or PostgreSQL is advised, " + << "please read http://wiki.minetest.net/Database_backends." << std::endl; + } + + if (auth_backend_name == "files") { + warningstream << "/!\\ You are using old auth file backend. " + << "This backend is deprecated and will be removed in a future release /!\\" + << std::endl << "Switching to SQLite3 is advised, " + << "please read http://wiki.minetest.net/Database_backends." << std::endl; + } + + m_player_database = openPlayerDatabase(player_backend_name, path_world, conf); + m_auth_database = openAuthDatabase(auth_backend_name, path_world, conf); + + m_step_time_counter = mb->addCounter( + "minetest_env_step_time", "Time spent in environment step (in microseconds)"); + + m_active_block_gauge = mb->addGauge( + "minetest_env_active_blocks", "Number of active blocks"); + + m_active_object_gauge = mb->addGauge( + "minetest_env_active_objects", "Number of active objects"); +} + +ServerEnvironment::~ServerEnvironment() +{ + // Clear active block list. + // This makes the next one delete all active objects. + m_active_blocks.clear(); + + // Convert all objects to static and delete the active objects + deactivateFarObjects(true); + + // Drop/delete map + m_map->drop(); + + // Delete ActiveBlockModifiers + for (ABMWithState &m_abm : m_abms) { + delete m_abm.abm; + } + + // Deallocate players + for (RemotePlayer *m_player : m_players) { + delete m_player; + } + + delete m_player_database; + delete m_auth_database; +} + +Map & ServerEnvironment::getMap() +{ + return *m_map; +} + +ServerMap & ServerEnvironment::getServerMap() +{ + return *m_map; +} + +RemotePlayer *ServerEnvironment::getPlayer(const session_t peer_id) +{ + for (RemotePlayer *player : m_players) { + if (player->getPeerId() == peer_id) + return player; + } + return NULL; +} + +RemotePlayer *ServerEnvironment::getPlayer(const char* name) +{ + for (RemotePlayer *player : m_players) { + if (strcmp(player->getName(), name) == 0) + return player; + } + return NULL; +} + +void ServerEnvironment::addPlayer(RemotePlayer *player) +{ + /* + Check that peer_ids are unique. + Also check that names are unique. + Exception: there can be multiple players with peer_id=0 + */ + // If peer id is non-zero, it has to be unique. + if (player->getPeerId() != PEER_ID_INEXISTENT) + FATAL_ERROR_IF(getPlayer(player->getPeerId()) != NULL, "Peer id not unique"); + // Name has to be unique. + FATAL_ERROR_IF(getPlayer(player->getName()) != NULL, "Player name not unique"); + // Add. + m_players.push_back(player); +} + +void ServerEnvironment::removePlayer(RemotePlayer *player) +{ + for (std::vector<RemotePlayer *>::iterator it = m_players.begin(); + it != m_players.end(); ++it) { + if ((*it) == player) { + delete *it; + m_players.erase(it); + return; + } + } +} + +bool ServerEnvironment::removePlayerFromDatabase(const std::string &name) +{ + return m_player_database->removePlayer(name); +} + +void ServerEnvironment::kickAllPlayers(AccessDeniedCode reason, + const std::string &str_reason, bool reconnect) +{ + for (RemotePlayer *player : m_players) + m_server->DenyAccess(player->getPeerId(), reason, str_reason, reconnect); +} + +void ServerEnvironment::saveLoadedPlayers(bool force) +{ + for (RemotePlayer *player : m_players) { + if (force || player->checkModified() || (player->getPlayerSAO() && + player->getPlayerSAO()->getMeta().isModified())) { + try { + m_player_database->savePlayer(player); + } catch (DatabaseException &e) { + errorstream << "Failed to save player " << player->getName() << " exception: " + << e.what() << std::endl; + throw; + } + } + } +} + +void ServerEnvironment::savePlayer(RemotePlayer *player) +{ + try { + m_player_database->savePlayer(player); + } catch (DatabaseException &e) { + errorstream << "Failed to save player " << player->getName() << " exception: " + << e.what() << std::endl; + throw; + } +} + +PlayerSAO *ServerEnvironment::loadPlayer(RemotePlayer *player, bool *new_player, + session_t peer_id, bool is_singleplayer) +{ + PlayerSAO *playersao = new PlayerSAO(this, player, peer_id, is_singleplayer); + // Create player if it doesn't exist + if (!m_player_database->loadPlayer(player, playersao)) { + *new_player = true; + // Set player position + infostream << "Server: Finding spawn place for player \"" + << player->getName() << "\"" << std::endl; + playersao->setBasePosition(m_server->findSpawnPos()); + + // Make sure the player is saved + player->setModified(true); + } else { + // If the player exists, ensure that they respawn inside legal bounds + // This fixes an assert crash when the player can't be added + // to the environment + if (objectpos_over_limit(playersao->getBasePosition())) { + actionstream << "Respawn position for player \"" + << player->getName() << "\" outside limits, resetting" << std::endl; + playersao->setBasePosition(m_server->findSpawnPos()); + } + } + + // Add player to environment + addPlayer(player); + + /* Clean up old HUD elements from previous sessions */ + player->clearHud(); + + /* Add object to environment */ + addActiveObject(playersao); + + // Update active blocks asap so objects in those blocks appear on the client + m_force_update_active_blocks = true; + + return playersao; +} + +void ServerEnvironment::saveMeta() +{ + if (!m_meta_loaded) + return; + + std::string path = m_path_world + DIR_DELIM "env_meta.txt"; + + // Open file and serialize + std::ostringstream ss(std::ios_base::binary); + + Settings args("EnvArgsEnd"); + args.setU64("game_time", m_game_time); + args.setU64("time_of_day", getTimeOfDay()); + args.setU64("last_clear_objects_time", m_last_clear_objects_time); + args.setU64("lbm_introduction_times_version", 1); + args.set("lbm_introduction_times", + m_lbm_mgr.createIntroductionTimesString()); + args.setU64("day_count", m_day_count); + args.writeLines(ss); + + if(!fs::safeWriteToFile(path, ss.str())) + { + infostream<<"ServerEnvironment::saveMeta(): Failed to write " + <<path<<std::endl; + throw SerializationError("Couldn't save env meta"); + } +} + +void ServerEnvironment::loadMeta() +{ + SANITY_CHECK(!m_meta_loaded); + m_meta_loaded = true; + + // If file doesn't exist, load default environment metadata + if (!fs::PathExists(m_path_world + DIR_DELIM "env_meta.txt")) { + infostream << "ServerEnvironment: Loading default environment metadata" + << std::endl; + loadDefaultMeta(); + return; + } + + infostream << "ServerEnvironment: Loading environment metadata" << std::endl; + + std::string path = m_path_world + DIR_DELIM "env_meta.txt"; + + // Open file and deserialize + std::ifstream is(path.c_str(), std::ios_base::binary); + if (!is.good()) { + infostream << "ServerEnvironment::loadMeta(): Failed to open " + << path << std::endl; + throw SerializationError("Couldn't load env meta"); + } + + Settings args("EnvArgsEnd"); + + if (!args.parseConfigLines(is)) { + throw SerializationError("ServerEnvironment::loadMeta(): " + "EnvArgsEnd not found!"); + } + + try { + m_game_time = args.getU64("game_time"); + } catch (SettingNotFoundException &e) { + // Getting this is crucial, otherwise timestamps are useless + throw SerializationError("Couldn't load env meta game_time"); + } + + setTimeOfDay(args.exists("time_of_day") ? + // set day to early morning by default + args.getU64("time_of_day") : 5250); + + m_last_clear_objects_time = args.exists("last_clear_objects_time") ? + // If missing, do as if clearObjects was never called + args.getU64("last_clear_objects_time") : 0; + + std::string lbm_introduction_times; + try { + u64 ver = args.getU64("lbm_introduction_times_version"); + if (ver == 1) { + lbm_introduction_times = args.get("lbm_introduction_times"); + } else { + infostream << "ServerEnvironment::loadMeta(): Non-supported" + << " introduction time version " << ver << std::endl; + } + } catch (SettingNotFoundException &e) { + // No problem, this is expected. Just continue with an empty string + } + m_lbm_mgr.loadIntroductionTimes(lbm_introduction_times, m_server, m_game_time); + + m_day_count = args.exists("day_count") ? + args.getU64("day_count") : 0; +} + +/** + * called if env_meta.txt doesn't exist (e.g. new world) + */ +void ServerEnvironment::loadDefaultMeta() +{ + m_lbm_mgr.loadIntroductionTimes("", m_server, m_game_time); +} + +struct ActiveABM +{ + ActiveBlockModifier *abm; + int chance; + std::vector<content_t> required_neighbors; + bool check_required_neighbors; // false if required_neighbors is known to be empty + s16 min_y; + s16 max_y; +}; + +class ABMHandler +{ +private: + ServerEnvironment *m_env; + std::vector<std::vector<ActiveABM> *> m_aabms; +public: + ABMHandler(std::vector<ABMWithState> &abms, + float dtime_s, ServerEnvironment *env, + bool use_timers): + m_env(env) + { + if(dtime_s < 0.001) + return; + const NodeDefManager *ndef = env->getGameDef()->ndef(); + for (ABMWithState &abmws : abms) { + ActiveBlockModifier *abm = abmws.abm; + float trigger_interval = abm->getTriggerInterval(); + if(trigger_interval < 0.001) + trigger_interval = 0.001; + float actual_interval = dtime_s; + if(use_timers){ + abmws.timer += dtime_s; + if(abmws.timer < trigger_interval) + continue; + abmws.timer -= trigger_interval; + actual_interval = trigger_interval; + } + float chance = abm->getTriggerChance(); + if(chance == 0) + chance = 1; + ActiveABM aabm; + aabm.abm = abm; + if (abm->getSimpleCatchUp()) { + float intervals = actual_interval / trigger_interval; + if(intervals == 0) + continue; + aabm.chance = chance / intervals; + if(aabm.chance == 0) + aabm.chance = 1; + } else { + aabm.chance = chance; + } + // y limits + aabm.min_y = abm->getMinY(); + aabm.max_y = abm->getMaxY(); + + // Trigger neighbors + const std::vector<std::string> &required_neighbors_s = + abm->getRequiredNeighbors(); + for (const std::string &required_neighbor_s : required_neighbors_s) { + ndef->getIds(required_neighbor_s, aabm.required_neighbors); + } + aabm.check_required_neighbors = !required_neighbors_s.empty(); + + // Trigger contents + const std::vector<std::string> &contents_s = abm->getTriggerContents(); + for (const std::string &content_s : contents_s) { + std::vector<content_t> ids; + ndef->getIds(content_s, ids); + for (content_t c : ids) { + if (c >= m_aabms.size()) + m_aabms.resize(c + 256, NULL); + if (!m_aabms[c]) + m_aabms[c] = new std::vector<ActiveABM>; + m_aabms[c]->push_back(aabm); + } + } + } + } + + ~ABMHandler() + { + for (auto &aabms : m_aabms) + delete aabms; + } + + // Find out how many objects the given block and its neighbours contain. + // Returns the number of objects in the block, and also in 'wider' the + // number of objects in the block and all its neighbours. The latter + // may an estimate if any neighbours are unloaded. + u32 countObjects(MapBlock *block, ServerMap * map, u32 &wider) + { + wider = 0; + u32 wider_unknown_count = 0; + for(s16 x=-1; x<=1; x++) + for(s16 y=-1; y<=1; y++) + for(s16 z=-1; z<=1; z++) + { + MapBlock *block2 = map->getBlockNoCreateNoEx( + block->getPos() + v3s16(x,y,z)); + if(block2==NULL){ + wider_unknown_count++; + continue; + } + wider += block2->m_static_objects.m_active.size() + + block2->m_static_objects.m_stored.size(); + } + // Extrapolate + u32 active_object_count = block->m_static_objects.m_active.size(); + u32 wider_known_count = 3*3*3 - wider_unknown_count; + wider += wider_unknown_count * wider / wider_known_count; + return active_object_count; + + } + void apply(MapBlock *block, int &blocks_scanned, int &abms_run, int &blocks_cached) + { + if(m_aabms.empty() || block->isDummy()) + return; + + // Check the content type cache first + // to see whether there are any ABMs + // to be run at all for this block. + if (block->contents_cached) { + blocks_cached++; + bool run_abms = false; + for (content_t c : block->contents) { + if (c < m_aabms.size() && m_aabms[c]) { + run_abms = true; + break; + } + } + if (!run_abms) + return; + } else { + // Clear any caching + block->contents.clear(); + } + blocks_scanned++; + + ServerMap *map = &m_env->getServerMap(); + + u32 active_object_count_wider; + u32 active_object_count = this->countObjects(block, map, active_object_count_wider); + m_env->m_added_objects = 0; + + v3s16 p0; + for(p0.X=0; p0.X<MAP_BLOCKSIZE; p0.X++) + for(p0.Y=0; p0.Y<MAP_BLOCKSIZE; p0.Y++) + for(p0.Z=0; p0.Z<MAP_BLOCKSIZE; p0.Z++) + { + const MapNode &n = block->getNodeUnsafe(p0); + content_t c = n.getContent(); + // Cache content types as we go + if (!block->contents_cached && !block->do_not_cache_contents) { + block->contents.insert(c); + if (block->contents.size() > 64) { + // Too many different nodes... don't try to cache + block->do_not_cache_contents = true; + block->contents.clear(); + } + } + + if (c >= m_aabms.size() || !m_aabms[c]) + continue; + + v3s16 p = p0 + block->getPosRelative(); + for (ActiveABM &aabm : *m_aabms[c]) { + if ((p.Y < aabm.min_y) || (p.Y > aabm.max_y)) + continue; + + if (myrand() % aabm.chance != 0) + continue; + + // Check neighbors + if (aabm.check_required_neighbors) { + v3s16 p1; + for(p1.X = p0.X-1; p1.X <= p0.X+1; p1.X++) + for(p1.Y = p0.Y-1; p1.Y <= p0.Y+1; p1.Y++) + for(p1.Z = p0.Z-1; p1.Z <= p0.Z+1; p1.Z++) + { + if(p1 == p0) + continue; + content_t c; + if (block->isValidPosition(p1)) { + // if the neighbor is found on the same map block + // get it straight from there + const MapNode &n = block->getNodeUnsafe(p1); + c = n.getContent(); + } else { + // otherwise consult the map + MapNode n = map->getNode(p1 + block->getPosRelative()); + c = n.getContent(); + } + if (CONTAINS(aabm.required_neighbors, c)) + goto neighbor_found; + } + // No required neighbor found + continue; + } + neighbor_found: + + abms_run++; + // Call all the trigger variations + aabm.abm->trigger(m_env, p, n); + aabm.abm->trigger(m_env, p, n, + active_object_count, active_object_count_wider); + + // Count surrounding objects again if the abms added any + if(m_env->m_added_objects > 0) { + active_object_count = countObjects(block, map, active_object_count_wider); + m_env->m_added_objects = 0; + } + } + } + block->contents_cached = !block->do_not_cache_contents; + } +}; + +void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime) +{ + // Reset usage timer immediately, otherwise a block that becomes active + // again at around the same time as it would normally be unloaded will + // get unloaded incorrectly. (I think this still leaves a small possibility + // of a race condition between this and server::AsyncRunStep, which only + // some kind of synchronisation will fix, but it at least reduces the window + // of opportunity for it to break from seconds to nanoseconds) + block->resetUsageTimer(); + + // Get time difference + u32 dtime_s = 0; + u32 stamp = block->getTimestamp(); + if (m_game_time > stamp && stamp != BLOCK_TIMESTAMP_UNDEFINED) + dtime_s = m_game_time - stamp; + dtime_s += additional_dtime; + + /*infostream<<"ServerEnvironment::activateBlock(): block timestamp: " + <<stamp<<", game time: "<<m_game_time<<std::endl;*/ + + // Remove stored static objects if clearObjects was called since block's timestamp + if (stamp == BLOCK_TIMESTAMP_UNDEFINED || stamp < m_last_clear_objects_time) { + block->m_static_objects.m_stored.clear(); + // do not set changed flag to avoid unnecessary mapblock writes + } + + // Set current time as timestamp + block->setTimestampNoChangedFlag(m_game_time); + + /*infostream<<"ServerEnvironment::activateBlock(): block is " + <<dtime_s<<" seconds old."<<std::endl;*/ + + // Activate stored objects + activateObjects(block, dtime_s); + + /* Handle LoadingBlockModifiers */ + m_lbm_mgr.applyLBMs(this, block, stamp); + + // Run node timers + std::vector<NodeTimer> elapsed_timers = + block->m_node_timers.step((float)dtime_s); + if (!elapsed_timers.empty()) { + MapNode n; + for (const NodeTimer &elapsed_timer : elapsed_timers) { + n = block->getNodeNoEx(elapsed_timer.position); + v3s16 p = elapsed_timer.position + block->getPosRelative(); + if (m_script->node_on_timer(p, n, elapsed_timer.elapsed)) + block->setNodeTimer(NodeTimer(elapsed_timer.timeout, 0, + elapsed_timer.position)); + } + } +} + +void ServerEnvironment::addActiveBlockModifier(ActiveBlockModifier *abm) +{ + m_abms.emplace_back(abm); +} + +void ServerEnvironment::addLoadingBlockModifierDef(LoadingBlockModifierDef *lbm) +{ + m_lbm_mgr.addLBMDef(lbm); +} + +bool ServerEnvironment::setNode(v3s16 p, const MapNode &n) +{ + const NodeDefManager *ndef = m_server->ndef(); + MapNode n_old = m_map->getNode(p); + + const ContentFeatures &cf_old = ndef->get(n_old); + + // Call destructor + if (cf_old.has_on_destruct) + m_script->node_on_destruct(p, n_old); + + // Replace node + if (!m_map->addNodeWithEvent(p, n)) + return false; + + // Update active VoxelManipulator if a mapgen thread + m_map->updateVManip(p); + + // Call post-destructor + if (cf_old.has_after_destruct) + m_script->node_after_destruct(p, n_old); + + // Retrieve node content features + // if new node is same as old, reuse old definition to prevent a lookup + const ContentFeatures &cf_new = n_old == n ? cf_old : ndef->get(n); + + // Call constructor + if (cf_new.has_on_construct) + m_script->node_on_construct(p, n); + + return true; +} + +bool ServerEnvironment::removeNode(v3s16 p) +{ + const NodeDefManager *ndef = m_server->ndef(); + MapNode n_old = m_map->getNode(p); + + // Call destructor + if (ndef->get(n_old).has_on_destruct) + m_script->node_on_destruct(p, n_old); + + // Replace with air + // This is slightly optimized compared to addNodeWithEvent(air) + if (!m_map->removeNodeWithEvent(p)) + return false; + + // Update active VoxelManipulator if a mapgen thread + m_map->updateVManip(p); + + // Call post-destructor + if (ndef->get(n_old).has_after_destruct) + m_script->node_after_destruct(p, n_old); + + // Air doesn't require constructor + return true; +} + +bool ServerEnvironment::swapNode(v3s16 p, const MapNode &n) +{ + if (!m_map->addNodeWithEvent(p, n, false)) + return false; + + // Update active VoxelManipulator if a mapgen thread + m_map->updateVManip(p); + + return true; +} + +u8 ServerEnvironment::findSunlight(v3s16 pos) const +{ + // Directions for neighbouring nodes with specified order + static const v3s16 dirs[] = { + v3s16(-1, 0, 0), v3s16(1, 0, 0), v3s16(0, 0, -1), v3s16(0, 0, 1), + v3s16(0, -1, 0), v3s16(0, 1, 0) + }; + + const NodeDefManager *ndef = m_server->ndef(); + + // found_light remembers the highest known sunlight value at pos + u8 found_light = 0; + + struct stack_entry { + v3s16 pos; + s16 dist; + }; + std::stack<stack_entry> stack; + stack.push({pos, 0}); + + std::unordered_map<s64, s8> dists; + dists[MapDatabase::getBlockAsInteger(pos)] = 0; + + while (!stack.empty()) { + struct stack_entry e = stack.top(); + stack.pop(); + + v3s16 currentPos = e.pos; + s8 dist = e.dist + 1; + + for (const v3s16& off : dirs) { + v3s16 neighborPos = currentPos + off; + s64 neighborHash = MapDatabase::getBlockAsInteger(neighborPos); + + // Do not walk neighborPos multiple times unless the distance to the start + // position is shorter + auto it = dists.find(neighborHash); + if (it != dists.end() && dist >= it->second) + continue; + + // Position to walk + bool is_position_ok; + MapNode node = m_map->getNode(neighborPos, &is_position_ok); + if (!is_position_ok) { + // This happens very rarely because the map at currentPos is loaded + m_map->emergeBlock(neighborPos, false); + node = m_map->getNode(neighborPos, &is_position_ok); + if (!is_position_ok) + continue; // not generated + } + + const ContentFeatures &def = ndef->get(node); + if (!def.sunlight_propagates) { + // Do not test propagation here again + dists[neighborHash] = -1; + continue; + } + + // Sunlight could have come from here + dists[neighborHash] = dist; + u8 daylight = node.param1 & 0x0f; + + // In the special case where sunlight shines from above and thus + // does not decrease with upwards distance, daylight is always + // bigger than nightlight, which never reaches 15 + int possible_finlight = daylight - dist; + if (possible_finlight <= found_light) { + // Light from here cannot make a brighter light at currentPos than + // found_light + continue; + } + + u8 nightlight = node.param1 >> 4; + if (daylight > nightlight) { + // Found a valid daylight + found_light = possible_finlight; + } else { + // Sunlight may be darker, so walk the neighbours + stack.push({neighborPos, dist}); + } + } + } + return found_light; +} + +void ServerEnvironment::clearObjects(ClearObjectsMode mode) +{ + infostream << "ServerEnvironment::clearObjects(): " + << "Removing all active objects" << std::endl; + auto cb_removal = [this] (ServerActiveObject *obj, u16 id) { + if (obj->getType() == ACTIVEOBJECT_TYPE_PLAYER) + return false; + + // Delete static object if block is loaded + deleteStaticFromBlock(obj, id, MOD_REASON_CLEAR_ALL_OBJECTS, true); + + // If known by some client, don't delete immediately + if (obj->m_known_by_count > 0) { + obj->markForRemoval(); + return false; + } + + // Tell the object about removal + obj->removingFromEnvironment(); + // Deregister in scripting api + m_script->removeObjectReference(obj); + + // Delete active object + if (obj->environmentDeletes()) + delete obj; + + return true; + }; + + m_ao_manager.clear(cb_removal); + + // Get list of loaded blocks + std::vector<v3s16> loaded_blocks; + infostream << "ServerEnvironment::clearObjects(): " + << "Listing all loaded blocks" << std::endl; + m_map->listAllLoadedBlocks(loaded_blocks); + infostream << "ServerEnvironment::clearObjects(): " + << "Done listing all loaded blocks: " + << loaded_blocks.size()<<std::endl; + + // Get list of loadable blocks + std::vector<v3s16> loadable_blocks; + if (mode == CLEAR_OBJECTS_MODE_FULL) { + infostream << "ServerEnvironment::clearObjects(): " + << "Listing all loadable blocks" << std::endl; + m_map->listAllLoadableBlocks(loadable_blocks); + infostream << "ServerEnvironment::clearObjects(): " + << "Done listing all loadable blocks: " + << loadable_blocks.size() << std::endl; + } else { + loadable_blocks = loaded_blocks; + } + + actionstream << "ServerEnvironment::clearObjects(): " + << "Now clearing objects in " << loadable_blocks.size() + << " blocks" << std::endl; + + // Grab a reference on each loaded block to avoid unloading it + for (v3s16 p : loaded_blocks) { + MapBlock *block = m_map->getBlockNoCreateNoEx(p); + assert(block != NULL); + block->refGrab(); + } + + // Remove objects in all loadable blocks + u32 unload_interval = U32_MAX; + if (mode == CLEAR_OBJECTS_MODE_FULL) { + unload_interval = g_settings->getS32("max_clearobjects_extra_loaded_blocks"); + unload_interval = MYMAX(unload_interval, 1); + } + u32 report_interval = loadable_blocks.size() / 10; + u32 num_blocks_checked = 0; + u32 num_blocks_cleared = 0; + u32 num_objs_cleared = 0; + for (auto i = loadable_blocks.begin(); + i != loadable_blocks.end(); ++i) { + v3s16 p = *i; + MapBlock *block = m_map->emergeBlock(p, false); + if (!block) { + errorstream << "ServerEnvironment::clearObjects(): " + << "Failed to emerge block " << PP(p) << std::endl; + continue; + } + u32 num_stored = block->m_static_objects.m_stored.size(); + u32 num_active = block->m_static_objects.m_active.size(); + if (num_stored != 0 || num_active != 0) { + block->m_static_objects.m_stored.clear(); + block->m_static_objects.m_active.clear(); + block->raiseModified(MOD_STATE_WRITE_NEEDED, + MOD_REASON_CLEAR_ALL_OBJECTS); + num_objs_cleared += num_stored + num_active; + num_blocks_cleared++; + } + num_blocks_checked++; + + if (report_interval != 0 && + num_blocks_checked % report_interval == 0) { + float percent = 100.0 * (float)num_blocks_checked / + loadable_blocks.size(); + actionstream << "ServerEnvironment::clearObjects(): " + << "Cleared " << num_objs_cleared << " objects" + << " in " << num_blocks_cleared << " blocks (" + << percent << "%)" << std::endl; + } + if (num_blocks_checked % unload_interval == 0) { + m_map->unloadUnreferencedBlocks(); + } + } + m_map->unloadUnreferencedBlocks(); + + // Drop references that were added above + for (v3s16 p : loaded_blocks) { + MapBlock *block = m_map->getBlockNoCreateNoEx(p); + assert(block); + block->refDrop(); + } + + m_last_clear_objects_time = m_game_time; + + actionstream << "ServerEnvironment::clearObjects(): " + << "Finished: Cleared " << num_objs_cleared << " objects" + << " in " << num_blocks_cleared << " blocks" << std::endl; +} + +void ServerEnvironment::step(float dtime) +{ + ScopeProfiler sp2(g_profiler, "ServerEnv::step()", SPT_AVG); + const auto start_time = porting::getTimeUs(); + + /* Step time of day */ + stepTimeOfDay(dtime); + + // Update this one + // NOTE: This is kind of funny on a singleplayer game, but doesn't + // really matter that much. + static thread_local const float server_step = + g_settings->getFloat("dedicated_server_step"); + m_recommended_send_interval = server_step; + + /* + Increment game time + */ + { + m_game_time_fraction_counter += dtime; + u32 inc_i = (u32)m_game_time_fraction_counter; + m_game_time += inc_i; + m_game_time_fraction_counter -= (float)inc_i; + } + + /* + Handle players + */ + { + ScopeProfiler sp(g_profiler, "ServerEnv: move players", SPT_AVG); + for (RemotePlayer *player : m_players) { + // Ignore disconnected players + if (player->getPeerId() == PEER_ID_INEXISTENT) + continue; + + // Move + player->move(dtime, this, 100 * BS); + } + } + + /* + Manage active block list + */ + if (m_active_blocks_mgmt_interval.step(dtime, m_cache_active_block_mgmt_interval) || + m_force_update_active_blocks) { + ScopeProfiler sp(g_profiler, "ServerEnv: update active blocks", SPT_AVG); + + /* + Get player block positions + */ + std::vector<PlayerSAO*> players; + players.reserve(m_players.size()); + for (RemotePlayer *player : m_players) { + // Ignore disconnected players + if (player->getPeerId() == PEER_ID_INEXISTENT) + continue; + + PlayerSAO *playersao = player->getPlayerSAO(); + assert(playersao); + + players.push_back(playersao); + } + + /* + Update list of active blocks, collecting changes + */ + // use active_object_send_range_blocks since that is max distance + // for active objects sent the client anyway + static thread_local const s16 active_object_range = + g_settings->getS16("active_object_send_range_blocks"); + static thread_local const s16 active_block_range = + g_settings->getS16("active_block_range"); + std::set<v3s16> blocks_removed; + std::set<v3s16> blocks_added; + m_active_blocks.update(players, active_block_range, active_object_range, + blocks_removed, blocks_added); + + /* + Handle removed blocks + */ + + // Convert active objects that are no more in active blocks to static + deactivateFarObjects(false); + + for (const v3s16 &p: blocks_removed) { + MapBlock *block = m_map->getBlockNoCreateNoEx(p); + if (!block) + continue; + + // Set current time as timestamp (and let it set ChangedFlag) + block->setTimestamp(m_game_time); + } + + /* + Handle added blocks + */ + + for (const v3s16 &p: blocks_added) { + MapBlock *block = m_map->getBlockOrEmerge(p); + if (!block) { + // TODO: The blocks removed here will only be picked up again + // on the next cycle. To minimize the latency of objects being + // activated we could remember the blocks pending activating + // and activate them instantly as soon as they're loaded. + m_active_blocks.remove(p); + continue; + } + + activateBlock(block); + } + + // Some blocks may be removed again by the code above so do this here + m_active_block_gauge->set(m_active_blocks.size()); + } + m_force_update_active_blocks = false; + + /* + Mess around in active blocks + */ + if (m_active_blocks_nodemetadata_interval.step(dtime, m_cache_nodetimer_interval)) { + ScopeProfiler sp(g_profiler, "ServerEnv: Run node timers", SPT_AVG); + + float dtime = m_cache_nodetimer_interval; + + for (const v3s16 &p: m_active_blocks.m_list) { + MapBlock *block = m_map->getBlockNoCreateNoEx(p); + if (!block) + continue; + + // Reset block usage timer + block->resetUsageTimer(); + + // Set current time as timestamp + block->setTimestampNoChangedFlag(m_game_time); + // If time has changed much from the one on disk, + // set block to be saved when it is unloaded + if(block->getTimestamp() > block->getDiskTimestamp() + 60) + block->raiseModified(MOD_STATE_WRITE_AT_UNLOAD, + MOD_REASON_BLOCK_EXPIRED); + + // Run node timers + std::vector<NodeTimer> elapsed_timers = block->m_node_timers.step(dtime); + if (!elapsed_timers.empty()) { + MapNode n; + v3s16 p2; + for (const NodeTimer &elapsed_timer: elapsed_timers) { + n = block->getNodeNoEx(elapsed_timer.position); + p2 = elapsed_timer.position + block->getPosRelative(); + if (m_script->node_on_timer(p2, n, elapsed_timer.elapsed)) { + block->setNodeTimer(NodeTimer( + elapsed_timer.timeout, 0, elapsed_timer.position)); + } + } + } + } + } + + if (m_active_block_modifier_interval.step(dtime, m_cache_abm_interval)) { + ScopeProfiler sp(g_profiler, "SEnv: modify in blocks avg per interval", SPT_AVG); + TimeTaker timer("modify in active blocks per interval"); + + // Initialize handling of ActiveBlockModifiers + ABMHandler abmhandler(m_abms, m_cache_abm_interval, this, true); + + int blocks_scanned = 0; + int abms_run = 0; + int blocks_cached = 0; + + std::vector<v3s16> output(m_active_blocks.m_abm_list.size()); + + // Shuffle the active blocks so that each block gets an equal chance + // of having its ABMs run. + std::copy(m_active_blocks.m_abm_list.begin(), m_active_blocks.m_abm_list.end(), output.begin()); + std::shuffle(output.begin(), output.end(), m_rgen); + + int i = 0; + // determine the time budget for ABMs + u32 max_time_ms = m_cache_abm_interval * 1000 * m_cache_abm_time_budget; + for (const v3s16 &p : output) { + MapBlock *block = m_map->getBlockNoCreateNoEx(p); + if (!block) + continue; + + i++; + + // Set current time as timestamp + block->setTimestampNoChangedFlag(m_game_time); + + /* Handle ActiveBlockModifiers */ + abmhandler.apply(block, blocks_scanned, abms_run, blocks_cached); + + u32 time_ms = timer.getTimerTime(); + + if (time_ms > max_time_ms) { + warningstream << "active block modifiers took " + << time_ms << "ms (processed " << i << " of " + << output.size() << " active blocks)" << std::endl; + break; + } + } + g_profiler->avg("ServerEnv: active blocks", m_active_blocks.m_abm_list.size()); + g_profiler->avg("ServerEnv: active blocks cached", blocks_cached); + g_profiler->avg("ServerEnv: active blocks scanned for ABMs", blocks_scanned); + g_profiler->avg("ServerEnv: ABMs run", abms_run); + + timer.stop(true); + } + + /* + Step script environment (run global on_step()) + */ + m_script->environment_Step(dtime); + + m_script->stepAsync(); + + /* + Step active objects + */ + { + ScopeProfiler sp(g_profiler, "ServerEnv: Run SAO::step()", SPT_AVG); + + // This helps the objects to send data at the same time + bool send_recommended = false; + m_send_recommended_timer += dtime; + if (m_send_recommended_timer > getSendRecommendedInterval()) { + m_send_recommended_timer -= getSendRecommendedInterval(); + send_recommended = true; + } + + u32 object_count = 0; + + auto cb_state = [&] (ServerActiveObject *obj) { + if (obj->isGone()) + return; + object_count++; + + // Step object + obj->step(dtime, send_recommended); + // Read messages from object + obj->dumpAOMessagesToQueue(m_active_object_messages); + }; + m_ao_manager.step(dtime, cb_state); + + m_active_object_gauge->set(object_count); + } + + /* + Manage active objects + */ + if (m_object_management_interval.step(dtime, 0.5)) { + removeRemovedObjects(); + } + + /* + Manage particle spawner expiration + */ + if (m_particle_management_interval.step(dtime, 1.0)) { + for (std::unordered_map<u32, float>::iterator i = m_particle_spawners.begin(); + i != m_particle_spawners.end(); ) { + //non expiring spawners + if (i->second == PARTICLE_SPAWNER_NO_EXPIRY) { + ++i; + continue; + } + + i->second -= 1.0f; + if (i->second <= 0.f) + m_particle_spawners.erase(i++); + else + ++i; + } + } + + // Send outdated player inventories + for (RemotePlayer *player : m_players) { + if (player->getPeerId() == PEER_ID_INEXISTENT) + continue; + + PlayerSAO *sao = player->getPlayerSAO(); + if (sao && player->inventory.checkModified()) + m_server->SendInventory(sao, true); + } + + // Send outdated detached inventories + m_server->sendDetachedInventories(PEER_ID_INEXISTENT, true); + + const auto end_time = porting::getTimeUs(); + m_step_time_counter->increment(end_time - start_time); +} + +ServerEnvironment::BlockStatus ServerEnvironment::getBlockStatus(v3s16 blockpos) +{ + if (m_active_blocks.contains(blockpos)) + return BS_ACTIVE; + + const MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos); + if (block && !block->isDummy()) + return BS_LOADED; + + if (m_map->isBlockInQueue(blockpos)) + return BS_EMERGING; + + return BS_UNKNOWN; +} + +u32 ServerEnvironment::addParticleSpawner(float exptime) +{ + // Timers with lifetime 0 do not expire + float time = exptime > 0.f ? exptime : PARTICLE_SPAWNER_NO_EXPIRY; + + u32 id = 0; + for (;;) { // look for unused particlespawner id + id++; + std::unordered_map<u32, float>::iterator f = m_particle_spawners.find(id); + if (f == m_particle_spawners.end()) { + m_particle_spawners[id] = time; + break; + } + } + return id; +} + +u32 ServerEnvironment::addParticleSpawner(float exptime, u16 attached_id) +{ + u32 id = addParticleSpawner(exptime); + m_particle_spawner_attachments[id] = attached_id; + if (ServerActiveObject *obj = getActiveObject(attached_id)) { + obj->attachParticleSpawner(id); + } + return id; +} + +void ServerEnvironment::deleteParticleSpawner(u32 id, bool remove_from_object) +{ + m_particle_spawners.erase(id); + const auto &it = m_particle_spawner_attachments.find(id); + if (it != m_particle_spawner_attachments.end()) { + u16 obj_id = it->second; + ServerActiveObject *sao = getActiveObject(obj_id); + if (sao != NULL && remove_from_object) { + sao->detachParticleSpawner(id); + } + m_particle_spawner_attachments.erase(id); + } +} + +u16 ServerEnvironment::addActiveObject(ServerActiveObject *object) +{ + assert(object); // Pre-condition + m_added_objects++; + u16 id = addActiveObjectRaw(object, true, 0); + return id; +} + +/* + Finds out what new objects have been added to + inside a radius around a position +*/ +void ServerEnvironment::getAddedActiveObjects(PlayerSAO *playersao, s16 radius, + s16 player_radius, + std::set<u16> ¤t_objects, + std::queue<u16> &added_objects) +{ + f32 radius_f = radius * BS; + f32 player_radius_f = player_radius * BS; + + if (player_radius_f < 0.0f) + player_radius_f = 0.0f; + + m_ao_manager.getAddedActiveObjectsAroundPos(playersao->getBasePosition(), radius_f, + player_radius_f, current_objects, added_objects); +} + +/* + Finds out what objects have been removed from + inside a radius around a position +*/ +void ServerEnvironment::getRemovedActiveObjects(PlayerSAO *playersao, s16 radius, + s16 player_radius, + std::set<u16> ¤t_objects, + std::queue<u16> &removed_objects) +{ + f32 radius_f = radius * BS; + f32 player_radius_f = player_radius * BS; + + if (player_radius_f < 0) + player_radius_f = 0; + /* + Go through current_objects; object is removed if: + - object is not found in m_active_objects (this is actually an + error condition; objects should be removed only after all clients + have been informed about removal), or + - object is to be removed or deactivated, or + - object is too far away + */ + for (u16 id : current_objects) { + ServerActiveObject *object = getActiveObject(id); + + if (object == NULL) { + infostream << "ServerEnvironment::getRemovedActiveObjects():" + << " object in current_objects is NULL" << std::endl; + removed_objects.push(id); + continue; + } + + if (object->isGone()) { + removed_objects.push(id); + continue; + } + + f32 distance_f = object->getBasePosition().getDistanceFrom(playersao->getBasePosition()); + if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) { + if (distance_f <= player_radius_f || player_radius_f == 0) + continue; + } else if (distance_f <= radius_f) + continue; + + // Object is no longer visible + removed_objects.push(id); + } +} + +void ServerEnvironment::setStaticForActiveObjectsInBlock( + v3s16 blockpos, bool static_exists, v3s16 static_block) +{ + MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos); + if (!block) + return; + + for (auto &so_it : block->m_static_objects.m_active) { + // Get the ServerActiveObject counterpart to this StaticObject + ServerActiveObject *sao = m_ao_manager.getActiveObject(so_it.first); + if (!sao) { + // If this ever happens, there must be some kind of nasty bug. + errorstream << "ServerEnvironment::setStaticForObjectsInBlock(): " + "Object from MapBlock::m_static_objects::m_active not found " + "in m_active_objects"; + continue; + } + + sao->m_static_exists = static_exists; + sao->m_static_block = static_block; + } +} + +bool ServerEnvironment::getActiveObjectMessage(ActiveObjectMessage *dest) +{ + if(m_active_object_messages.empty()) + return false; + + *dest = std::move(m_active_object_messages.front()); + m_active_object_messages.pop(); + return true; +} + +void ServerEnvironment::getSelectedActiveObjects( + const core::line3d<f32> &shootline_on_map, + std::vector<PointedThing> &objects) +{ + std::vector<ServerActiveObject *> objs; + getObjectsInsideRadius(objs, shootline_on_map.start, + shootline_on_map.getLength() + 10.0f, nullptr); + const v3f line_vector = shootline_on_map.getVector(); + + for (auto obj : objs) { + if (obj->isGone()) + continue; + aabb3f selection_box; + if (!obj->getSelectionBox(&selection_box)) + continue; + + v3f pos = obj->getBasePosition(); + + aabb3f offsetted_box(selection_box.MinEdge + pos, + selection_box.MaxEdge + pos); + + v3f current_intersection; + v3s16 current_normal; + if (boxLineCollision(offsetted_box, shootline_on_map.start, line_vector, + ¤t_intersection, ¤t_normal)) { + objects.emplace_back( + (s16) obj->getId(), current_intersection, current_normal, + (current_intersection - shootline_on_map.start).getLengthSQ()); + } + } +} + +/* + ************ Private methods ************* +*/ + +u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object, + bool set_changed, u32 dtime_s) +{ + if (!m_ao_manager.registerObject(object)) { + return 0; + } + + // Register reference in scripting api (must be done before post-init) + m_script->addObjectReference(object); + // Post-initialize object + object->addedToEnvironment(dtime_s); + + // Add static data to block + if (object->isStaticAllowed()) { + // Add static object to active static list of the block + v3f objectpos = object->getBasePosition(); + StaticObject s_obj(object, objectpos); + // Add to the block where the object is located in + v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS)); + MapBlock *block = m_map->emergeBlock(blockpos); + if(block){ + block->m_static_objects.m_active[object->getId()] = s_obj; + object->m_static_exists = true; + object->m_static_block = blockpos; + + if(set_changed) + block->raiseModified(MOD_STATE_WRITE_NEEDED, + MOD_REASON_ADD_ACTIVE_OBJECT_RAW); + } else { + v3s16 p = floatToInt(objectpos, BS); + errorstream<<"ServerEnvironment::addActiveObjectRaw(): " + <<"could not emerge block for storing id="<<object->getId() + <<" statically (pos="<<PP(p)<<")"<<std::endl; + } + } + + return object->getId(); +} + +/* + Remove objects that satisfy (isGone() && m_known_by_count==0) +*/ +void ServerEnvironment::removeRemovedObjects() +{ + ScopeProfiler sp(g_profiler, "ServerEnvironment::removeRemovedObjects()", SPT_AVG); + + auto clear_cb = [this] (ServerActiveObject *obj, u16 id) { + // This shouldn't happen but check it + if (!obj) { + errorstream << "ServerEnvironment::removeRemovedObjects(): " + << "NULL object found. id=" << id << std::endl; + return true; + } + + /* + We will handle objects marked for removal or deactivation + */ + if (!obj->isGone()) + return false; + + /* + Delete static data from block if removed + */ + if (obj->isPendingRemoval()) + deleteStaticFromBlock(obj, id, MOD_REASON_REMOVE_OBJECTS_REMOVE, false); + + // If still known by clients, don't actually remove. On some future + // invocation this will be 0, which is when removal will continue. + if(obj->m_known_by_count > 0) + return false; + + /* + Move static data from active to stored if deactivated + */ + if (!obj->isPendingRemoval() && obj->m_static_exists) { + MapBlock *block = m_map->emergeBlock(obj->m_static_block, false); + if (block) { + const auto i = block->m_static_objects.m_active.find(id); + if (i != block->m_static_objects.m_active.end()) { + block->m_static_objects.m_stored.push_back(i->second); + block->m_static_objects.m_active.erase(id); + block->raiseModified(MOD_STATE_WRITE_NEEDED, + MOD_REASON_REMOVE_OBJECTS_DEACTIVATE); + } else { + warningstream << "ServerEnvironment::removeRemovedObjects(): " + << "id=" << id << " m_static_exists=true but " + << "static data doesn't actually exist in " + << PP(obj->m_static_block) << std::endl; + } + } else { + infostream << "Failed to emerge block from which an object to " + << "be deactivated was loaded from. id=" << id << std::endl; + } + } + + // Tell the object about removal + obj->removingFromEnvironment(); + // Deregister in scripting api + m_script->removeObjectReference(obj); + + // Delete + if (obj->environmentDeletes()) + delete obj; + + return true; + }; + + m_ao_manager.clear(clear_cb); +} + +static void print_hexdump(std::ostream &o, const std::string &data) +{ + const int linelength = 16; + for(int l=0; ; l++){ + int i0 = linelength * l; + bool at_end = false; + int thislinelength = linelength; + if(i0 + thislinelength > (int)data.size()){ + thislinelength = data.size() - i0; + at_end = true; + } + for(int di=0; di<linelength; di++){ + int i = i0 + di; + char buf[4]; + if(di<thislinelength) + porting::mt_snprintf(buf, sizeof(buf), "%.2x ", data[i]); + else + porting::mt_snprintf(buf, sizeof(buf), " "); + o<<buf; + } + o<<" "; + for(int di=0; di<thislinelength; di++){ + int i = i0 + di; + if(data[i] >= 32) + o<<data[i]; + else + o<<"."; + } + o<<std::endl; + if(at_end) + break; + } +} + +ServerActiveObject* ServerEnvironment::createSAO(ActiveObjectType type, v3f pos, + const std::string &data) +{ + switch (type) { + case ACTIVEOBJECT_TYPE_LUAENTITY: + return new LuaEntitySAO(this, pos, data); + default: + warningstream << "ServerActiveObject: No factory for type=" << type << std::endl; + } + return nullptr; +} + +/* + Convert stored objects from blocks near the players to active. +*/ +void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s) +{ + if(block == NULL) + return; + + // Ignore if no stored objects (to not set changed flag) + if(block->m_static_objects.m_stored.empty()) + return; + + verbosestream<<"ServerEnvironment::activateObjects(): " + <<"activating objects of block "<<PP(block->getPos()) + <<" ("<<block->m_static_objects.m_stored.size() + <<" objects)"<<std::endl; + bool large_amount = (block->m_static_objects.m_stored.size() > g_settings->getU16("max_objects_per_block")); + if (large_amount) { + errorstream<<"suspiciously large amount of objects detected: " + <<block->m_static_objects.m_stored.size()<<" in " + <<PP(block->getPos()) + <<"; removing all of them."<<std::endl; + // Clear stored list + block->m_static_objects.m_stored.clear(); + block->raiseModified(MOD_STATE_WRITE_NEEDED, + MOD_REASON_TOO_MANY_OBJECTS); + return; + } + + // Activate stored objects + std::vector<StaticObject> new_stored; + for (const StaticObject &s_obj : block->m_static_objects.m_stored) { + // Create an active object from the data + ServerActiveObject *obj = createSAO((ActiveObjectType) s_obj.type, s_obj.pos, + s_obj.data); + // If couldn't create object, store static data back. + if (!obj) { + errorstream<<"ServerEnvironment::activateObjects(): " + <<"failed to create active object from static object " + <<"in block "<<PP(s_obj.pos/BS) + <<" type="<<(int)s_obj.type<<" data:"<<std::endl; + print_hexdump(verbosestream, s_obj.data); + + new_stored.push_back(s_obj); + continue; + } + verbosestream<<"ServerEnvironment::activateObjects(): " + <<"activated static object pos="<<PP(s_obj.pos/BS) + <<" type="<<(int)s_obj.type<<std::endl; + // This will also add the object to the active static list + addActiveObjectRaw(obj, false, dtime_s); + } + + // Clear stored list + block->m_static_objects.m_stored.clear(); + // Add leftover failed stuff to stored list + for (const StaticObject &s_obj : new_stored) { + block->m_static_objects.m_stored.push_back(s_obj); + } + + /* + Note: Block hasn't really been modified here. + The objects have just been activated and moved from the stored + static list to the active static list. + As such, the block is essentially the same. + Thus, do not call block->raiseModified(MOD_STATE_WRITE_NEEDED). + Otherwise there would be a huge amount of unnecessary I/O. + */ +} + +/* + Convert objects that are not standing inside active blocks to static. + + If m_known_by_count != 0, active object is not deleted, but static + data is still updated. + + If force_delete is set, active object is deleted nevertheless. It + shall only be set so in the destructor of the environment. + + If block wasn't generated (not in memory or on disk), +*/ +void ServerEnvironment::deactivateFarObjects(bool _force_delete) +{ + auto cb_deactivate = [this, _force_delete] (ServerActiveObject *obj, u16 id) { + // force_delete might be overriden per object + bool force_delete = _force_delete; + + // Do not deactivate if disallowed + if (!force_delete && !obj->shouldUnload()) + return false; + + // removeRemovedObjects() is responsible for these + if (!force_delete && obj->isGone()) + return false; + + const v3f &objectpos = obj->getBasePosition(); + + // The block in which the object resides in + v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS)); + + // If object's static data is stored in a deactivated block and object + // is actually located in an active block, re-save to the block in + // which the object is actually located in. + if (!force_delete && obj->m_static_exists && + !m_active_blocks.contains(obj->m_static_block) && + m_active_blocks.contains(blockpos_o)) { + + // Delete from block where object was located + deleteStaticFromBlock(obj, id, MOD_REASON_STATIC_DATA_REMOVED, false); + + StaticObject s_obj(obj, objectpos); + // Save to block where object is located + saveStaticToBlock(blockpos_o, id, obj, s_obj, MOD_REASON_STATIC_DATA_ADDED); + + return false; + } + + // If block is still active, don't remove + bool still_active = obj->isStaticAllowed() ? + m_active_blocks.contains(blockpos_o) : + getMap().getBlockNoCreateNoEx(blockpos_o) != nullptr; + if (!force_delete && still_active) + return false; + + verbosestream << "ServerEnvironment::deactivateFarObjects(): " + << "deactivating object id=" << id << " on inactive block " + << PP(blockpos_o) << std::endl; + + // If known by some client, don't immediately delete. + bool pending_delete = (obj->m_known_by_count > 0 && !force_delete); + + /* + Update the static data + */ + if (obj->isStaticAllowed()) { + // Create new static object + StaticObject s_obj(obj, objectpos); + + bool stays_in_same_block = false; + bool data_changed = true; + + // Check if static data has changed considerably + if (obj->m_static_exists) { + if (obj->m_static_block == blockpos_o) + stays_in_same_block = true; + + MapBlock *block = m_map->emergeBlock(obj->m_static_block, false); + + if (block) { + const auto n = block->m_static_objects.m_active.find(id); + if (n != block->m_static_objects.m_active.end()) { + StaticObject static_old = n->second; + + float save_movem = obj->getMinimumSavedMovement(); + + if (static_old.data == s_obj.data && + (static_old.pos - objectpos).getLength() < save_movem) + data_changed = false; + } else { + warningstream << "ServerEnvironment::deactivateFarObjects(): " + << "id=" << id << " m_static_exists=true but " + << "static data doesn't actually exist in " + << PP(obj->m_static_block) << std::endl; + } + } + } + + /* + While changes are always saved, blocks are only marked as modified + if the object has moved or different staticdata. (see above) + */ + bool shall_be_written = (!stays_in_same_block || data_changed); + u32 reason = shall_be_written ? MOD_REASON_STATIC_DATA_CHANGED : MOD_REASON_UNKNOWN; + + // Delete old static object + deleteStaticFromBlock(obj, id, reason, false); + + // Add to the block where the object is located in + v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS)); + u16 store_id = pending_delete ? id : 0; + if (!saveStaticToBlock(blockpos, store_id, obj, s_obj, reason)) + force_delete = true; + } + + // Regardless of what happens to the object at this point, deactivate it first. + // This ensures that LuaEntity on_deactivate is always called. + obj->markForDeactivation(); + + /* + If known by some client, set pending deactivation. + Otherwise delete it immediately. + */ + if (pending_delete && !force_delete) { + verbosestream << "ServerEnvironment::deactivateFarObjects(): " + << "object id=" << id << " is known by clients" + << "; not deleting yet" << std::endl; + + return false; + } + + verbosestream << "ServerEnvironment::deactivateFarObjects(): " + << "object id=" << id << " is not known by clients" + << "; deleting" << std::endl; + + // Tell the object about removal + obj->removingFromEnvironment(); + // Deregister in scripting api + m_script->removeObjectReference(obj); + + // Delete active object + if (obj->environmentDeletes()) + delete obj; + + return true; + }; + + m_ao_manager.clear(cb_deactivate); +} + +void ServerEnvironment::deleteStaticFromBlock( + ServerActiveObject *obj, u16 id, u32 mod_reason, bool no_emerge) +{ + if (!obj->m_static_exists) + return; + + MapBlock *block; + if (no_emerge) + block = m_map->getBlockNoCreateNoEx(obj->m_static_block); + else + block = m_map->emergeBlock(obj->m_static_block, false); + if (!block) { + if (!no_emerge) + errorstream << "ServerEnv: Failed to emerge block " << PP(obj->m_static_block) + << " when deleting static data of object from it. id=" << id << std::endl; + return; + } + + block->m_static_objects.remove(id); + if (mod_reason != MOD_REASON_UNKNOWN) // Do not mark as modified if requested + block->raiseModified(MOD_STATE_WRITE_NEEDED, mod_reason); + + obj->m_static_exists = false; +} + +bool ServerEnvironment::saveStaticToBlock( + v3s16 blockpos, u16 store_id, + ServerActiveObject *obj, const StaticObject &s_obj, + u32 mod_reason) +{ + MapBlock *block = nullptr; + try { + block = m_map->emergeBlock(blockpos); + } catch (InvalidPositionException &e) { + // Handled via NULL pointer + // NOTE: emergeBlock's failure is usually determined by it + // actually returning NULL + } + + if (!block) { + errorstream << "ServerEnv: Failed to emerge block " << PP(obj->m_static_block) + << " when saving static data of object to it. id=" << store_id << std::endl; + return false; + } + if (block->m_static_objects.m_stored.size() >= g_settings->getU16("max_objects_per_block")) { + warningstream << "ServerEnv: Trying to store id = " << store_id + << " statically but block " << PP(blockpos) + << " already contains " + << block->m_static_objects.m_stored.size() + << " objects." << std::endl; + return false; + } + + block->m_static_objects.insert(store_id, s_obj); + if (mod_reason != MOD_REASON_UNKNOWN) // Do not mark as modified if requested + block->raiseModified(MOD_STATE_WRITE_NEEDED, mod_reason); + + obj->m_static_exists = true; + obj->m_static_block = blockpos; + + return true; +} + +PlayerDatabase *ServerEnvironment::openPlayerDatabase(const std::string &name, + const std::string &savedir, const Settings &conf) +{ + + if (name == "sqlite3") + return new PlayerDatabaseSQLite3(savedir); + + if (name == "dummy") + return new Database_Dummy(); + +#if USE_POSTGRESQL + if (name == "postgresql") { + std::string connect_string; + conf.getNoEx("pgsql_player_connection", connect_string); + return new PlayerDatabasePostgreSQL(connect_string); + } +#endif + +#if USE_LEVELDB + if (name == "leveldb") + return new PlayerDatabaseLevelDB(savedir); +#endif + + if (name == "files") + return new PlayerDatabaseFiles(savedir + DIR_DELIM + "players"); + + throw BaseException(std::string("Database backend ") + name + " not supported."); +} + +bool ServerEnvironment::migratePlayersDatabase(const GameParams &game_params, + const Settings &cmd_args) +{ + std::string migrate_to = cmd_args.get("migrate-players"); + Settings world_mt; + std::string world_mt_path = game_params.world_path + DIR_DELIM + "world.mt"; + if (!world_mt.readConfigFile(world_mt_path.c_str())) { + errorstream << "Cannot read world.mt!" << std::endl; + return false; + } + + if (!world_mt.exists("player_backend")) { + errorstream << "Please specify your current backend in world.mt:" + << std::endl + << " player_backend = {files|sqlite3|leveldb|postgresql}" + << std::endl; + return false; + } + + std::string backend = world_mt.get("player_backend"); + if (backend == migrate_to) { + errorstream << "Cannot migrate: new backend is same" + << " as the old one" << std::endl; + return false; + } + + const std::string players_backup_path = game_params.world_path + DIR_DELIM + + "players.bak"; + + if (backend == "files") { + // Create backup directory + fs::CreateDir(players_backup_path); + } + + try { + PlayerDatabase *srcdb = ServerEnvironment::openPlayerDatabase(backend, + game_params.world_path, world_mt); + PlayerDatabase *dstdb = ServerEnvironment::openPlayerDatabase(migrate_to, + game_params.world_path, world_mt); + + std::vector<std::string> player_list; + srcdb->listPlayers(player_list); + for (std::vector<std::string>::const_iterator it = player_list.begin(); + it != player_list.end(); ++it) { + actionstream << "Migrating player " << it->c_str() << std::endl; + RemotePlayer player(it->c_str(), NULL); + PlayerSAO playerSAO(NULL, &player, 15000, false); + + srcdb->loadPlayer(&player, &playerSAO); + + playerSAO.finalize(&player, std::set<std::string>()); + player.setPlayerSAO(&playerSAO); + + dstdb->savePlayer(&player); + + // For files source, move player files to backup dir + if (backend == "files") { + fs::Rename( + game_params.world_path + DIR_DELIM + "players" + DIR_DELIM + (*it), + players_backup_path + DIR_DELIM + (*it)); + } + } + + actionstream << "Successfully migrated " << player_list.size() << " players" + << std::endl; + world_mt.set("player_backend", migrate_to); + if (!world_mt.updateConfigFile(world_mt_path.c_str())) + errorstream << "Failed to update world.mt!" << std::endl; + else + actionstream << "world.mt updated" << std::endl; + + // When migration is finished from file backend, remove players directory if empty + if (backend == "files") { + fs::DeleteSingleFileOrEmptyDirectory(game_params.world_path + DIR_DELIM + + "players"); + } + + delete srcdb; + delete dstdb; + + } catch (BaseException &e) { + errorstream << "An error occurred during migration: " << e.what() << std::endl; + return false; + } + return true; +} + +AuthDatabase *ServerEnvironment::openAuthDatabase( + const std::string &name, const std::string &savedir, const Settings &conf) +{ + if (name == "sqlite3") + return new AuthDatabaseSQLite3(savedir); + +#if USE_POSTGRESQL + if (name == "postgresql") { + std::string connect_string; + conf.getNoEx("pgsql_auth_connection", connect_string); + return new AuthDatabasePostgreSQL(connect_string); + } +#endif + + if (name == "files") + return new AuthDatabaseFiles(savedir); + +#if USE_LEVELDB + if (name == "leveldb") + return new AuthDatabaseLevelDB(savedir); +#endif + + throw BaseException(std::string("Database backend ") + name + " not supported."); +} + +bool ServerEnvironment::migrateAuthDatabase( + const GameParams &game_params, const Settings &cmd_args) +{ + std::string migrate_to = cmd_args.get("migrate-auth"); + Settings world_mt; + std::string world_mt_path = game_params.world_path + DIR_DELIM + "world.mt"; + if (!world_mt.readConfigFile(world_mt_path.c_str())) { + errorstream << "Cannot read world.mt!" << std::endl; + return false; + } + + std::string backend = "files"; + if (world_mt.exists("auth_backend")) + backend = world_mt.get("auth_backend"); + else + warningstream << "No auth_backend found in world.mt, " + "assuming \"files\"." << std::endl; + + if (backend == migrate_to) { + errorstream << "Cannot migrate: new backend is same" + << " as the old one" << std::endl; + return false; + } + + try { + const std::unique_ptr<AuthDatabase> srcdb(ServerEnvironment::openAuthDatabase( + backend, game_params.world_path, world_mt)); + const std::unique_ptr<AuthDatabase> dstdb(ServerEnvironment::openAuthDatabase( + migrate_to, game_params.world_path, world_mt)); + + std::vector<std::string> names_list; + srcdb->listNames(names_list); + for (const std::string &name : names_list) { + actionstream << "Migrating auth entry for " << name << std::endl; + bool success; + AuthEntry authEntry; + success = srcdb->getAuth(name, authEntry); + success = success && dstdb->createAuth(authEntry); + if (!success) + errorstream << "Failed to migrate " << name << std::endl; + } + + actionstream << "Successfully migrated " << names_list.size() + << " auth entries" << std::endl; + world_mt.set("auth_backend", migrate_to); + if (!world_mt.updateConfigFile(world_mt_path.c_str())) + errorstream << "Failed to update world.mt!" << std::endl; + else + actionstream << "world.mt updated" << std::endl; + + if (backend == "files") { + // special-case files migration: + // move auth.txt to auth.txt.bak if possible + std::string auth_txt_path = + game_params.world_path + DIR_DELIM + "auth.txt"; + std::string auth_bak_path = auth_txt_path + ".bak"; + if (!fs::PathExists(auth_bak_path)) + if (fs::Rename(auth_txt_path, auth_bak_path)) + actionstream << "Renamed auth.txt to auth.txt.bak" + << std::endl; + else + errorstream << "Could not rename auth.txt to " + "auth.txt.bak" << std::endl; + else + warningstream << "auth.txt.bak already exists, auth.txt " + "not renamed" << std::endl; + } + + } catch (BaseException &e) { + errorstream << "An error occurred during migration: " << e.what() + << std::endl; + return false; + } + return true; +} diff --git a/src/serverenvironment.h b/src/serverenvironment.h new file mode 100644 index 0000000..0018442 --- /dev/null +++ b/src/serverenvironment.h @@ -0,0 +1,506 @@ +/* +Minetest +Copyright (C) 2010-2017 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "activeobject.h" +#include "environment.h" +#include "mapnode.h" +#include "settings.h" +#include "server/activeobjectmgr.h" +#include "util/numeric.h" +#include "util/metricsbackend.h" +#include <set> +#include <random> + +class IGameDef; +class ServerMap; +struct GameParams; +class MapBlock; +class RemotePlayer; +class PlayerDatabase; +class AuthDatabase; +class PlayerSAO; +class ServerEnvironment; +class ActiveBlockModifier; +struct StaticObject; +class ServerActiveObject; +class Server; +class ServerScripting; + +/* + {Active, Loading} block modifier interface. + + These are fed into ServerEnvironment at initialization time; + ServerEnvironment handles deleting them. +*/ + +class ActiveBlockModifier +{ +public: + ActiveBlockModifier() = default; + virtual ~ActiveBlockModifier() = default; + + // Set of contents to trigger on + virtual const std::vector<std::string> &getTriggerContents() const = 0; + // Set of required neighbors (trigger doesn't happen if none are found) + // Empty = do not check neighbors + virtual const std::vector<std::string> &getRequiredNeighbors() const = 0; + // Trigger interval in seconds + virtual float getTriggerInterval() = 0; + // Random chance of (1 / return value), 0 is disallowed + virtual u32 getTriggerChance() = 0; + // Whether to modify chance to simulate time lost by an unnattended block + virtual bool getSimpleCatchUp() = 0; + // get min Y for apply abm + virtual s16 getMinY() = 0; + // get max Y for apply abm + virtual s16 getMaxY() = 0; + // This is called usually at interval for 1/chance of the nodes + virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n){}; + virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n, + u32 active_object_count, u32 active_object_count_wider){}; +}; + +struct ABMWithState +{ + ActiveBlockModifier *abm; + float timer = 0.0f; + + ABMWithState(ActiveBlockModifier *abm_); +}; + +struct LoadingBlockModifierDef +{ + // Set of contents to trigger on + std::set<std::string> trigger_contents; + std::string name; + bool run_at_every_load = false; + + virtual ~LoadingBlockModifierDef() = default; + + virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n){}; +}; + +struct LBMContentMapping +{ + typedef std::unordered_map<content_t, std::vector<LoadingBlockModifierDef *>> lbm_map; + lbm_map map; + + std::vector<LoadingBlockModifierDef *> lbm_list; + + // Needs to be separate method (not inside destructor), + // because the LBMContentMapping may be copied and destructed + // many times during operation in the lbm_lookup_map. + void deleteContents(); + void addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamedef); + const std::vector<LoadingBlockModifierDef *> *lookup(content_t c) const; +}; + +class LBMManager +{ +public: + LBMManager() = default; + ~LBMManager(); + + // Don't call this after loadIntroductionTimes() ran. + void addLBMDef(LoadingBlockModifierDef *lbm_def); + + void loadIntroductionTimes(const std::string ×, + IGameDef *gamedef, u32 now); + + // Don't call this before loadIntroductionTimes() ran. + std::string createIntroductionTimesString(); + + // Don't call this before loadIntroductionTimes() ran. + void applyLBMs(ServerEnvironment *env, MapBlock *block, u32 stamp); + + // Warning: do not make this std::unordered_map, order is relevant here + typedef std::map<u32, LBMContentMapping> lbm_lookup_map; + +private: + // Once we set this to true, we can only query, + // not modify + bool m_query_mode = false; + + // For m_query_mode == false: + // The key of the map is the LBM def's name. + // TODO make this std::unordered_map + std::map<std::string, LoadingBlockModifierDef *> m_lbm_defs; + + // For m_query_mode == true: + // The key of the map is the LBM def's first introduction time. + lbm_lookup_map m_lbm_lookup; + + // Returns an iterator to the LBMs that were introduced + // after the given time. This is guaranteed to return + // valid values for everything + lbm_lookup_map::const_iterator getLBMsIntroducedAfter(u32 time) + { return m_lbm_lookup.lower_bound(time); } +}; + +/* + List of active blocks, used by ServerEnvironment +*/ + +class ActiveBlockList +{ +public: + void update(std::vector<PlayerSAO*> &active_players, + s16 active_block_range, + s16 active_object_range, + std::set<v3s16> &blocks_removed, + std::set<v3s16> &blocks_added); + + bool contains(v3s16 p) const { + return (m_list.find(p) != m_list.end()); + } + + auto size() const { + return m_list.size(); + } + + void clear() { + m_list.clear(); + } + + void remove(v3s16 p) { + m_list.erase(p); + m_abm_list.erase(p); + } + + std::set<v3s16> m_list; + std::set<v3s16> m_abm_list; + // list of blocks that are always active, not modified by this class + std::set<v3s16> m_forceloaded_list; +}; + +/* + Operation mode for ServerEnvironment::clearObjects() +*/ +enum ClearObjectsMode { + // Load and go through every mapblock, clearing objects + CLEAR_OBJECTS_MODE_FULL, + + // Clear objects immediately in loaded mapblocks; + // clear objects in unloaded mapblocks only when the mapblocks are next activated. + CLEAR_OBJECTS_MODE_QUICK, +}; + +class ServerEnvironment : public Environment +{ +public: + ServerEnvironment(ServerMap *map, ServerScripting *scriptIface, + Server *server, const std::string &path_world, MetricsBackend *mb); + ~ServerEnvironment(); + + Map & getMap(); + + ServerMap & getServerMap(); + + //TODO find way to remove this fct! + ServerScripting* getScriptIface() + { return m_script; } + + Server *getGameDef() + { return m_server; } + + float getSendRecommendedInterval() + { return m_recommended_send_interval; } + + void kickAllPlayers(AccessDeniedCode reason, + const std::string &str_reason, bool reconnect); + // Save players + void saveLoadedPlayers(bool force = false); + void savePlayer(RemotePlayer *player); + PlayerSAO *loadPlayer(RemotePlayer *player, bool *new_player, session_t peer_id, + bool is_singleplayer); + void addPlayer(RemotePlayer *player); + void removePlayer(RemotePlayer *player); + bool removePlayerFromDatabase(const std::string &name); + + /* + Save and load time of day and game timer + */ + void saveMeta(); + void loadMeta(); + + u32 addParticleSpawner(float exptime); + u32 addParticleSpawner(float exptime, u16 attached_id); + void deleteParticleSpawner(u32 id, bool remove_from_object = true); + + /* + External ActiveObject interface + ------------------------------------------- + */ + + ServerActiveObject* getActiveObject(u16 id) + { + return m_ao_manager.getActiveObject(id); + } + + /* + Add an active object to the environment. + Environment handles deletion of object. + Object may be deleted by environment immediately. + If id of object is 0, assigns a free id to it. + Returns the id of the object. + Returns 0 if not added and thus deleted. + */ + u16 addActiveObject(ServerActiveObject *object); + + /* + Add an active object as a static object to the corresponding + MapBlock. + Caller allocates memory, ServerEnvironment frees memory. + Return value: true if succeeded, false if failed. + (note: not used, pending removal from engine) + */ + //bool addActiveObjectAsStatic(ServerActiveObject *object); + + /* + Find out what new objects have been added to + inside a radius around a position + */ + void getAddedActiveObjects(PlayerSAO *playersao, s16 radius, + s16 player_radius, + std::set<u16> ¤t_objects, + std::queue<u16> &added_objects); + + /* + Find out what new objects have been removed from + inside a radius around a position + */ + void getRemovedActiveObjects(PlayerSAO *playersao, s16 radius, + s16 player_radius, + std::set<u16> ¤t_objects, + std::queue<u16> &removed_objects); + + /* + Get the next message emitted by some active object. + Returns false if no messages are available, true otherwise. + */ + bool getActiveObjectMessage(ActiveObjectMessage *dest); + + virtual void getSelectedActiveObjects( + const core::line3d<f32> &shootline_on_map, + std::vector<PointedThing> &objects + ); + + /* + Activate objects and dynamically modify for the dtime determined + from timestamp and additional_dtime + */ + void activateBlock(MapBlock *block, u32 additional_dtime=0); + + /* + {Active,Loading}BlockModifiers + ------------------------------------------- + */ + + void addActiveBlockModifier(ActiveBlockModifier *abm); + void addLoadingBlockModifierDef(LoadingBlockModifierDef *lbm); + + /* + Other stuff + ------------------------------------------- + */ + + // Script-aware node setters + bool setNode(v3s16 p, const MapNode &n); + bool removeNode(v3s16 p); + bool swapNode(v3s16 p, const MapNode &n); + + // Find the daylight value at pos with a Depth First Search + u8 findSunlight(v3s16 pos) const; + + // Find all active objects inside a radius around a point + void getObjectsInsideRadius(std::vector<ServerActiveObject *> &objects, const v3f &pos, float radius, + std::function<bool(ServerActiveObject *obj)> include_obj_cb) + { + return m_ao_manager.getObjectsInsideRadius(pos, radius, objects, include_obj_cb); + } + + // Find all active objects inside a box + void getObjectsInArea(std::vector<ServerActiveObject *> &objects, const aabb3f &box, + std::function<bool(ServerActiveObject *obj)> include_obj_cb) + { + return m_ao_manager.getObjectsInArea(box, objects, include_obj_cb); + } + + // Clear objects, loading and going through every MapBlock + void clearObjects(ClearObjectsMode mode); + + // This makes stuff happen + void step(f32 dtime); + + u32 getGameTime() const { return m_game_time; } + + void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; } + float getMaxLagEstimate() { return m_max_lag_estimate; } + + std::set<v3s16>* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; } + + // Sorted by how ready a mapblock is + enum BlockStatus { + BS_UNKNOWN, + BS_EMERGING, + BS_LOADED, + BS_ACTIVE // always highest value + }; + BlockStatus getBlockStatus(v3s16 blockpos); + + // Sets the static object status all the active objects in the specified block + // This is only really needed for deleting blocks from the map + void setStaticForActiveObjectsInBlock(v3s16 blockpos, + bool static_exists, v3s16 static_block=v3s16(0,0,0)); + + RemotePlayer *getPlayer(const session_t peer_id); + RemotePlayer *getPlayer(const char* name); + const std::vector<RemotePlayer *> getPlayers() const { return m_players; } + u32 getPlayerCount() const { return m_players.size(); } + + static bool migratePlayersDatabase(const GameParams &game_params, + const Settings &cmd_args); + + AuthDatabase *getAuthDatabase() { return m_auth_database; } + static bool migrateAuthDatabase(const GameParams &game_params, + const Settings &cmd_args); +private: + + /** + * called if env_meta.txt doesn't exist (e.g. new world) + */ + void loadDefaultMeta(); + + static PlayerDatabase *openPlayerDatabase(const std::string &name, + const std::string &savedir, const Settings &conf); + static AuthDatabase *openAuthDatabase(const std::string &name, + const std::string &savedir, const Settings &conf); + /* + Internal ActiveObject interface + ------------------------------------------- + */ + + /* + Add an active object to the environment. + + Called by addActiveObject. + + Object may be deleted by environment immediately. + If id of object is 0, assigns a free id to it. + Returns the id of the object. + Returns 0 if not added and thus deleted. + */ + u16 addActiveObjectRaw(ServerActiveObject *object, bool set_changed, u32 dtime_s); + + /* + Remove all objects that satisfy (isGone() && m_known_by_count==0) + */ + void removeRemovedObjects(); + + /* + Convert stored objects from block to active + */ + void activateObjects(MapBlock *block, u32 dtime_s); + + /* + Convert objects that are not in active blocks to static. + + If m_known_by_count != 0, active object is not deleted, but static + data is still updated. + + If force_delete is set, active object is deleted nevertheless. It + shall only be set so in the destructor of the environment. + */ + void deactivateFarObjects(bool force_delete); + + /* + A few helpers used by the three above methods + */ + void deleteStaticFromBlock( + ServerActiveObject *obj, u16 id, u32 mod_reason, bool no_emerge); + bool saveStaticToBlock(v3s16 blockpos, u16 store_id, + ServerActiveObject *obj, const StaticObject &s_obj, u32 mod_reason); + + /* + Member variables + */ + + // The map + ServerMap *m_map; + // Lua state + ServerScripting* m_script; + // Server definition + Server *m_server; + // Active Object Manager + server::ActiveObjectMgr m_ao_manager; + // World path + const std::string m_path_world; + // Outgoing network message buffer for active objects + std::queue<ActiveObjectMessage> m_active_object_messages; + // Some timers + float m_send_recommended_timer = 0.0f; + IntervalLimiter m_object_management_interval; + // List of active blocks + ActiveBlockList m_active_blocks; + bool m_force_update_active_blocks = false; + IntervalLimiter m_active_blocks_mgmt_interval; + IntervalLimiter m_active_block_modifier_interval; + IntervalLimiter m_active_blocks_nodemetadata_interval; + // Whether the variables below have been read from file yet + bool m_meta_loaded = false; + // Time from the beginning of the game in seconds. + // Incremented in step(). + u32 m_game_time = 0; + // A helper variable for incrementing the latter + float m_game_time_fraction_counter = 0.0f; + // Time of last clearObjects call (game time). + // When a mapblock older than this is loaded, its objects are cleared. + u32 m_last_clear_objects_time = 0; + // Active block modifiers + std::vector<ABMWithState> m_abms; + LBMManager m_lbm_mgr; + // An interval for generally sending object positions and stuff + float m_recommended_send_interval = 0.1f; + // Estimate for general maximum lag as determined by server. + // Can raise to high values like 15s with eg. map generation mods. + float m_max_lag_estimate = 0.1f; + + // peer_ids in here should be unique, except that there may be many 0s + std::vector<RemotePlayer*> m_players; + + PlayerDatabase *m_player_database = nullptr; + AuthDatabase *m_auth_database = nullptr; + + // Pseudo random generator for shuffling, etc. + std::mt19937 m_rgen; + + // Particles + IntervalLimiter m_particle_management_interval; + std::unordered_map<u32, float> m_particle_spawners; + std::unordered_map<u32, u16> m_particle_spawner_attachments; + + // Environment metrics + MetricCounterPtr m_step_time_counter; + MetricGaugePtr m_active_block_gauge; + MetricGaugePtr m_active_object_gauge; + + ServerActiveObject* createSAO(ActiveObjectType type, v3f pos, const std::string &data); +}; diff --git a/src/serverlist.cpp b/src/serverlist.cpp new file mode 100644 index 0000000..29e3ac9 --- /dev/null +++ b/src/serverlist.cpp @@ -0,0 +1,109 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <iostream> +#include "version.h" +#include "settings.h" +#include "serverlist.h" +#include "filesys.h" +#include "log.h" +#include "network/networkprotocol.h" +#include <json/json.h> +#include "convert_json.h" +#include "httpfetch.h" + +namespace ServerList +{ +#if USE_CURL +void sendAnnounce(AnnounceAction action, + const u16 port, + const std::vector<std::string> &clients_names, + const double uptime, + const u32 game_time, + const float lag, + const std::string &gameid, + const std::string &mg_name, + const std::vector<ModSpec> &mods, + bool dedicated) +{ + static const char *aa_names[] = {"start", "update", "delete"}; + Json::Value server; + server["action"] = aa_names[action]; + server["port"] = port; + if (g_settings->exists("server_address")) { + server["address"] = g_settings->get("server_address"); + } + if (action != AA_DELETE) { + bool strict_checking = g_settings->getBool("strict_protocol_version_checking"); + server["name"] = g_settings->get("server_name"); + server["description"] = g_settings->get("server_description"); + server["version"] = g_version_string; + server["proto_min"] = strict_checking ? LATEST_PROTOCOL_VERSION : SERVER_PROTOCOL_VERSION_MIN; + server["proto_max"] = strict_checking ? LATEST_PROTOCOL_VERSION : SERVER_PROTOCOL_VERSION_MAX; + server["url"] = g_settings->get("server_url"); + server["creative"] = g_settings->getBool("creative_mode"); + server["damage"] = g_settings->getBool("enable_damage"); + server["password"] = g_settings->getBool("disallow_empty_password"); + server["pvp"] = g_settings->getBool("enable_pvp"); + server["uptime"] = (int) uptime; + server["game_time"] = game_time; + server["clients"] = (int) clients_names.size(); + server["clients_max"] = g_settings->getU16("max_users"); + server["clients_list"] = Json::Value(Json::arrayValue); + for (const std::string &clients_name : clients_names) { + server["clients_list"].append(clients_name); + } + if (!gameid.empty()) + server["gameid"] = gameid; + } + + if (action == AA_START) { + server["dedicated"] = dedicated; + server["rollback"] = g_settings->getBool("enable_rollback_recording"); + server["mapgen"] = mg_name; + server["privs"] = g_settings->get("default_privs"); + server["can_see_far_names"] = g_settings->getS16("player_transfer_distance") <= 0; + server["mods"] = Json::Value(Json::arrayValue); + for (const ModSpec &mod : mods) { + server["mods"].append(mod.name); + } + } else if (action == AA_UPDATE) { + if (lag) + server["lag"] = lag; + } + + if (action == AA_START) { + actionstream << "Announcing " << aa_names[action] << " to " << + g_settings->get("serverlist_url") << std::endl; + } else { + infostream << "Announcing " << aa_names[action] << " to " << + g_settings->get("serverlist_url") << std::endl; + } + + HTTPFetchRequest fetch_request; + fetch_request.caller = HTTPFETCH_PRINT_ERR; + fetch_request.url = g_settings->get("serverlist_url") + std::string("/announce"); + fetch_request.method = HTTP_POST; + fetch_request.fields["json"] = fastWriteJson(server); + fetch_request.multipart = true; + httpfetch_async(fetch_request); +} +#endif + +} // namespace ServerList diff --git a/src/serverlist.h b/src/serverlist.h new file mode 100644 index 0000000..4a0bd5e --- /dev/null +++ b/src/serverlist.h @@ -0,0 +1,39 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <iostream> +#include "config.h" +#include "content/mods.h" +#include <json/json.h> + +#pragma once + +namespace ServerList +{ +#if USE_CURL +enum AnnounceAction {AA_START, AA_UPDATE, AA_DELETE}; +void sendAnnounce(AnnounceAction, u16 port, + const std::vector<std::string> &clients_names = std::vector<std::string>(), + double uptime = 0, u32 game_time = 0, float lag = 0, + const std::string &gameid = "", const std::string &mg_name = "", + const std::vector<ModSpec> &mods = std::vector<ModSpec>(), + bool dedicated = false); +#endif + +} // namespace ServerList diff --git a/src/settings.cpp b/src/settings.cpp new file mode 100644 index 0000000..a0225bc --- /dev/null +++ b/src/settings.cpp @@ -0,0 +1,1101 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "settings.h" +#include "irrlichttypes_bloated.h" +#include "exceptions.h" +#include "threading/mutex_auto_lock.h" +#include "util/numeric.h" // rangelim +#include "util/strfnd.h" +#include <iostream> +#include <fstream> +#include <sstream> +#include "debug.h" +#include "log.h" +#include "util/serialize.h" +#include "filesys.h" +#include "noise.h" +#include <cctype> +#include <algorithm> + +Settings *g_settings = nullptr; +static SettingsHierarchy g_hierarchy; +std::string g_settings_path; + +std::unordered_map<std::string, const FlagDesc *> Settings::s_flags; + +/* Settings hierarchy implementation */ + +SettingsHierarchy::SettingsHierarchy(Settings *fallback) +{ + layers.push_back(fallback); +} + + +Settings *SettingsHierarchy::getLayer(int layer) const +{ + if (layer < 0 || layer >= (int)layers.size()) + throw BaseException("Invalid settings layer"); + return layers[layer]; +} + + +Settings *SettingsHierarchy::getParent(int layer) const +{ + assert(layer >= 0 && layer < (int)layers.size()); + // iterate towards the origin (0) to find the next fallback layer + for (int i = layer - 1; i >= 0; --i) { + if (layers[i]) + return layers[i]; + } + + return nullptr; +} + + +void SettingsHierarchy::onLayerCreated(int layer, Settings *obj) +{ + if (layer < 0) + throw BaseException("Invalid settings layer"); + if ((int)layers.size() < layer + 1) + layers.resize(layer + 1); + + Settings *&pos = layers[layer]; + if (pos) + throw BaseException("Setting layer " + itos(layer) + " already exists"); + + pos = obj; + // This feels bad + if (this == &g_hierarchy && layer == (int)SL_GLOBAL) + g_settings = obj; +} + + +void SettingsHierarchy::onLayerRemoved(int layer) +{ + assert(layer >= 0 && layer < (int)layers.size()); + layers[layer] = nullptr; + if (this == &g_hierarchy && layer == (int)SL_GLOBAL) + g_settings = nullptr; +} + +/* Settings implementation */ + +Settings *Settings::createLayer(SettingsLayer sl, const std::string &end_tag) +{ + return new Settings(end_tag, &g_hierarchy, (int)sl); +} + + +Settings *Settings::getLayer(SettingsLayer sl) +{ + return g_hierarchy.getLayer(sl); +} + + +Settings::Settings(const std::string &end_tag, SettingsHierarchy *h, + int settings_layer) : + m_end_tag(end_tag), + m_hierarchy(h), + m_settingslayer(settings_layer) +{ + if (m_hierarchy) + m_hierarchy->onLayerCreated(m_settingslayer, this); +} + + +Settings::~Settings() +{ + MutexAutoLock lock(m_mutex); + + if (m_hierarchy) + m_hierarchy->onLayerRemoved(m_settingslayer); + + clearNoLock(); +} + + +Settings & Settings::operator = (const Settings &other) +{ + if (&other == this) + return *this; + + // TODO: Avoid copying Settings objects. Make this private. + FATAL_ERROR_IF(m_hierarchy || other.m_hierarchy, + "Cannot copy or overwrite Settings object that belongs to a hierarchy"); + + MutexAutoLock lock(m_mutex); + MutexAutoLock lock2(other.m_mutex); + + clearNoLock(); + m_settings = other.m_settings; + m_callbacks = other.m_callbacks; + + return *this; +} + + +bool Settings::checkNameValid(const std::string &name) +{ + bool valid = name.find_first_of("=\"{}#") == std::string::npos; + if (valid) + valid = std::find_if(name.begin(), name.end(), ::isspace) == name.end(); + + if (!valid) { + errorstream << "Invalid setting name \"" << name << "\"" + << std::endl; + return false; + } + return true; +} + + +bool Settings::checkValueValid(const std::string &value) +{ + if (value.substr(0, 3) == "\"\"\"" || + value.find("\n\"\"\"") != std::string::npos) { + errorstream << "Invalid character sequence '\"\"\"' found in" + " setting value!" << std::endl; + return false; + } + return true; +} + +std::string Settings::getMultiline(std::istream &is, size_t *num_lines) +{ + size_t lines = 1; + std::string value; + std::string line; + + while (is.good()) { + lines++; + std::getline(is, line); + if (line == "\"\"\"") + break; + value += line; + value.push_back('\n'); + } + + size_t len = value.size(); + if (len) + value.erase(len - 1); + + if (num_lines) + *num_lines = lines; + + return value; +} + + +bool Settings::readConfigFile(const char *filename) +{ + std::ifstream is(filename); + if (!is.good()) + return false; + + return parseConfigLines(is); +} + + +bool Settings::parseConfigLines(std::istream &is) +{ + MutexAutoLock lock(m_mutex); + + std::string line, name, value; + + while (is.good()) { + std::getline(is, line); + SettingsParseEvent event = parseConfigObject(line, name, value); + + switch (event) { + case SPE_NONE: + case SPE_INVALID: + case SPE_COMMENT: + break; + case SPE_KVPAIR: + m_settings[name] = SettingsEntry(value); + break; + case SPE_END: + return true; + case SPE_GROUP: { + Settings *group = new Settings("}"); + if (!group->parseConfigLines(is)) { + delete group; + return false; + } + m_settings[name] = SettingsEntry(group); + break; + } + case SPE_MULTILINE: + m_settings[name] = SettingsEntry(getMultiline(is)); + break; + } + } + + // false (failure) if end tag not found + return m_end_tag.empty(); +} + + +void Settings::writeLines(std::ostream &os, u32 tab_depth) const +{ + MutexAutoLock lock(m_mutex); + + for (const auto &setting_it : m_settings) + printEntry(os, setting_it.first, setting_it.second, tab_depth); + + // For groups this must be "}" ! + if (!m_end_tag.empty()) { + for (u32 i = 0; i < tab_depth; i++) + os << "\t"; + + os << m_end_tag << "\n"; + } +} + + +void Settings::printEntry(std::ostream &os, const std::string &name, + const SettingsEntry &entry, u32 tab_depth) +{ + for (u32 i = 0; i != tab_depth; i++) + os << "\t"; + + if (entry.is_group) { + os << name << " = {\n"; + + entry.group->writeLines(os, tab_depth + 1); + + // Closing bracket handled by writeLines + } else { + os << name << " = "; + + if (entry.value.find('\n') != std::string::npos) + os << "\"\"\"\n" << entry.value << "\n\"\"\"\n"; + else + os << entry.value << "\n"; + } +} + + +bool Settings::updateConfigObject(std::istream &is, std::ostream &os, u32 tab_depth) +{ + SettingEntries::const_iterator it; + std::set<std::string> present_entries; + std::string line, name, value; + bool was_modified = false; + bool end_found = false; + + // Add any settings that exist in the config file with the current value + // in the object if existing + while (is.good() && !end_found) { + std::getline(is, line); + SettingsParseEvent event = parseConfigObject(line, name, value); + + switch (event) { + case SPE_END: + // Skip end tag. Append later. + end_found = true; + break; + case SPE_MULTILINE: + value = getMultiline(is); + /* FALLTHROUGH */ + case SPE_KVPAIR: + it = m_settings.find(name); + if (it != m_settings.end() && + (it->second.is_group || it->second.value != value)) { + printEntry(os, name, it->second, tab_depth); + was_modified = true; + } else if (it == m_settings.end()) { + // Remove by skipping + was_modified = true; + break; + } else { + os << line << "\n"; + if (event == SPE_MULTILINE) + os << value << "\n\"\"\"\n"; + } + present_entries.insert(name); + break; + case SPE_GROUP: + it = m_settings.find(name); + if (it != m_settings.end() && it->second.is_group) { + os << line << "\n"; + sanity_check(it->second.group != NULL); + was_modified |= it->second.group->updateConfigObject(is, os, tab_depth + 1); + } else if (it == m_settings.end()) { + // Remove by skipping + was_modified = true; + Settings removed_group("}"); // Move 'is' to group end + std::stringstream ss; + removed_group.updateConfigObject(is, ss, tab_depth + 1); + break; + } else { + printEntry(os, name, it->second, tab_depth); + was_modified = true; + } + present_entries.insert(name); + break; + default: + os << line << (is.eof() ? "" : "\n"); + break; + } + } + + if (!line.empty() && is.eof()) + os << "\n"; + + // Add any settings in the object that don't exist in the config file yet + for (it = m_settings.begin(); it != m_settings.end(); ++it) { + if (present_entries.find(it->first) != present_entries.end()) + continue; + + printEntry(os, it->first, it->second, tab_depth); + was_modified = true; + } + + // Append ending tag + if (!m_end_tag.empty()) { + os << m_end_tag << "\n"; + was_modified |= !end_found; + } + + return was_modified; +} + + +bool Settings::updateConfigFile(const char *filename) +{ + MutexAutoLock lock(m_mutex); + + std::ifstream is(filename); + std::ostringstream os(std::ios_base::binary); + + bool was_modified = updateConfigObject(is, os); + is.close(); + + if (!was_modified) + return true; + + if (!fs::safeWriteToFile(filename, os.str())) { + errorstream << "Error writing configuration file: \"" + << filename << "\"" << std::endl; + return false; + } + + return true; +} + + +bool Settings::parseCommandLine(int argc, char *argv[], + std::map<std::string, ValueSpec> &allowed_options) +{ + int nonopt_index = 0; + for (int i = 1; i < argc; i++) { + std::string arg_name = argv[i]; + if (arg_name.substr(0, 2) != "--") { + // If option doesn't start with -, read it in as nonoptX + if (arg_name[0] != '-'){ + std::string name = "nonopt"; + name += itos(nonopt_index); + set(name, arg_name); + nonopt_index++; + continue; + } + errorstream << "Invalid command-line parameter \"" + << arg_name << "\": --<option> expected." << std::endl; + return false; + } + + std::string name = arg_name.substr(2); + + std::map<std::string, ValueSpec>::iterator n; + n = allowed_options.find(name); + if (n == allowed_options.end()) { + errorstream << "Unknown command-line parameter \"" + << arg_name << "\"" << std::endl; + return false; + } + + ValueType type = n->second.type; + + std::string value; + + if (type == VALUETYPE_FLAG) { + value = "true"; + } else { + if ((i + 1) >= argc) { + errorstream << "Invalid command-line parameter \"" + << name << "\": missing value" << std::endl; + return false; + } + value = argv[++i]; + } + + set(name, value); + } + + return true; +} + + + +/*********** + * Getters * + ***********/ + +Settings *Settings::getParent() const +{ + return m_hierarchy ? m_hierarchy->getParent(m_settingslayer) : nullptr; +} + + +const SettingsEntry &Settings::getEntry(const std::string &name) const +{ + { + MutexAutoLock lock(m_mutex); + + SettingEntries::const_iterator n; + if ((n = m_settings.find(name)) != m_settings.end()) + return n->second; + } + + if (auto parent = getParent()) + return parent->getEntry(name); + + throw SettingNotFoundException("Setting [" + name + "] not found."); +} + + +Settings *Settings::getGroup(const std::string &name) const +{ + const SettingsEntry &entry = getEntry(name); + if (!entry.is_group) + throw SettingNotFoundException("Setting [" + name + "] is not a group."); + return entry.group; +} + + +const std::string &Settings::get(const std::string &name) const +{ + const SettingsEntry &entry = getEntry(name); + if (entry.is_group) + throw SettingNotFoundException("Setting [" + name + "] is a group."); + return entry.value; +} + + +bool Settings::getBool(const std::string &name) const +{ + return is_yes(get(name)); +} + + +u16 Settings::getU16(const std::string &name) const +{ + return stoi(get(name), 0, 65535); +} + + +s16 Settings::getS16(const std::string &name) const +{ + return stoi(get(name), -32768, 32767); +} + + +u32 Settings::getU32(const std::string &name) const +{ + return (u32) stoi(get(name)); +} + +s32 Settings::getS32(const std::string &name) const +{ + return stoi(get(name)); +} + + +float Settings::getFloat(const std::string &name) const +{ + return stof(get(name)); +} + + +float Settings::getFloat(const std::string &name, float min, float max) const +{ + float val = stof(get(name)); + return rangelim(val, min, max); +} + + +u64 Settings::getU64(const std::string &name) const +{ + std::string s = get(name); + return from_string<u64>(s); +} + + +v2f Settings::getV2F(const std::string &name) const +{ + v2f value; + Strfnd f(get(name)); + f.next("("); + value.X = stof(f.next(",")); + value.Y = stof(f.next(")")); + return value; +} + + +v3f Settings::getV3F(const std::string &name) const +{ + v3f value; + Strfnd f(get(name)); + f.next("("); + value.X = stof(f.next(",")); + value.Y = stof(f.next(",")); + value.Z = stof(f.next(")")); + return value; +} + + +u32 Settings::getFlagStr(const std::string &name, const FlagDesc *flagdesc, + u32 *flagmask) const +{ + u32 flags = 0; + + // Read default value (if there is any) + if (auto parent = getParent()) + flags = parent->getFlagStr(name, flagdesc, flagmask); + + // Apply custom flags "on top" + if (m_settings.find(name) != m_settings.end()) { + std::string value = get(name); + u32 flags_user; + u32 mask_user = U32_MAX; + flags_user = std::isdigit(value[0]) + ? stoi(value) // Override default + : readFlagString(value, flagdesc, &mask_user); + + flags &= ~mask_user; + flags |= flags_user; + if (flagmask) + *flagmask |= mask_user; + } + + return flags; +} + + +bool Settings::getNoiseParams(const std::string &name, NoiseParams &np) const +{ + if (getNoiseParamsFromGroup(name, np) || getNoiseParamsFromValue(name, np)) + return true; + if (auto parent = getParent()) + return parent->getNoiseParams(name, np); + + return false; +} + + +bool Settings::getNoiseParamsFromValue(const std::string &name, + NoiseParams &np) const +{ + std::string value; + + if (!getNoEx(name, value)) + return false; + + // Format: f32,f32,(f32,f32,f32),s32,s32,f32[,f32] + Strfnd f(value); + + np.offset = stof(f.next(",")); + np.scale = stof(f.next(",")); + f.next("("); + np.spread.X = stof(f.next(",")); + np.spread.Y = stof(f.next(",")); + np.spread.Z = stof(f.next(")")); + f.next(","); + np.seed = stoi(f.next(",")); + np.octaves = stoi(f.next(",")); + np.persist = stof(f.next(",")); + + std::string optional_params = f.next(""); + if (!optional_params.empty()) + np.lacunarity = stof(optional_params); + + return true; +} + + +bool Settings::getNoiseParamsFromGroup(const std::string &name, + NoiseParams &np) const +{ + Settings *group = NULL; + + if (!getGroupNoEx(name, group)) + return false; + + group->getFloatNoEx("offset", np.offset); + group->getFloatNoEx("scale", np.scale); + group->getV3FNoEx("spread", np.spread); + group->getS32NoEx("seed", np.seed); + group->getU16NoEx("octaves", np.octaves); + group->getFloatNoEx("persistence", np.persist); + group->getFloatNoEx("lacunarity", np.lacunarity); + + np.flags = 0; + if (!group->getFlagStrNoEx("flags", np.flags, flagdesc_noiseparams)) + np.flags = NOISE_FLAG_DEFAULTS; + + return true; +} + + +bool Settings::exists(const std::string &name) const +{ + if (existsLocal(name)) + return true; + if (auto parent = getParent()) + return parent->exists(name); + return false; +} + + +bool Settings::existsLocal(const std::string &name) const +{ + MutexAutoLock lock(m_mutex); + + return m_settings.find(name) != m_settings.end(); +} + + +std::vector<std::string> Settings::getNames() const +{ + MutexAutoLock lock(m_mutex); + + std::vector<std::string> names; + names.reserve(m_settings.size()); + for (const auto &settings_it : m_settings) { + names.push_back(settings_it.first); + } + return names; +} + + + +/*************************************** + * Getters that don't throw exceptions * + ***************************************/ + +bool Settings::getGroupNoEx(const std::string &name, Settings *&val) const +{ + try { + val = getGroup(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getNoEx(const std::string &name, std::string &val) const +{ + try { + val = get(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getFlag(const std::string &name) const +{ + try { + return getBool(name); + } catch(SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getFloatNoEx(const std::string &name, float &val) const +{ + try { + val = getFloat(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getU16NoEx(const std::string &name, u16 &val) const +{ + try { + val = getU16(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getS16NoEx(const std::string &name, s16 &val) const +{ + try { + val = getS16(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + +bool Settings::getU32NoEx(const std::string &name, u32 &val) const +{ + try { + val = getU32(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + +bool Settings::getS32NoEx(const std::string &name, s32 &val) const +{ + try { + val = getS32(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getU64NoEx(const std::string &name, u64 &val) const +{ + try { + val = getU64(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getV2FNoEx(const std::string &name, v2f &val) const +{ + try { + val = getV2F(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getV3FNoEx(const std::string &name, v3f &val) const +{ + try { + val = getV3F(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getFlagStrNoEx(const std::string &name, u32 &val, + const FlagDesc *flagdesc) const +{ + if (!flagdesc) { + if (!(flagdesc = getFlagDescFallback(name))) + return false; // Not found + } + + try { + val = getFlagStr(name, flagdesc, nullptr); + + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +/*********** + * Setters * + ***********/ + +bool Settings::setEntry(const std::string &name, const void *data, + bool set_group) +{ + if (!checkNameValid(name)) + return false; + if (!set_group && !checkValueValid(*(const std::string *)data)) + return false; + + Settings *old_group = NULL; + { + MutexAutoLock lock(m_mutex); + + SettingsEntry &entry = m_settings[name]; + old_group = entry.group; + + entry.value = set_group ? "" : *(const std::string *)data; + entry.group = set_group ? *(Settings **)data : NULL; + entry.is_group = set_group; + if (set_group) + entry.group->m_end_tag = "}"; + } + + delete old_group; + + return true; +} + + +bool Settings::set(const std::string &name, const std::string &value) +{ + if (!setEntry(name, &value, false)) + return false; + + doCallbacks(name); + return true; +} + + +// TODO: Remove this function +bool Settings::setDefault(const std::string &name, const std::string &value) +{ + FATAL_ERROR_IF(m_hierarchy != &g_hierarchy, "setDefault is only valid on " + "global settings"); + return getLayer(SL_DEFAULTS)->set(name, value); +} + + +bool Settings::setGroup(const std::string &name, const Settings &group) +{ + // Settings must own the group pointer + // avoid double-free by copying the source + Settings *copy = new Settings(); + *copy = group; + return setEntry(name, ©, true); +} + + +bool Settings::setBool(const std::string &name, bool value) +{ + return set(name, value ? "true" : "false"); +} + + +bool Settings::setS16(const std::string &name, s16 value) +{ + return set(name, itos(value)); +} + + +bool Settings::setU16(const std::string &name, u16 value) +{ + return set(name, itos(value)); +} + + +bool Settings::setS32(const std::string &name, s32 value) +{ + return set(name, itos(value)); +} + + +bool Settings::setU64(const std::string &name, u64 value) +{ + std::ostringstream os; + os << value; + return set(name, os.str()); +} + + +bool Settings::setFloat(const std::string &name, float value) +{ + return set(name, ftos(value)); +} + + +bool Settings::setV2F(const std::string &name, v2f value) +{ + std::ostringstream os; + os << "(" << value.X << "," << value.Y << ")"; + return set(name, os.str()); +} + + +bool Settings::setV3F(const std::string &name, v3f value) +{ + std::ostringstream os; + os << "(" << value.X << "," << value.Y << "," << value.Z << ")"; + return set(name, os.str()); +} + + +bool Settings::setFlagStr(const std::string &name, u32 flags, + const FlagDesc *flagdesc, u32 flagmask) +{ + if (!flagdesc) { + if (!(flagdesc = getFlagDescFallback(name))) + return false; // Not found + } + + return set(name, writeFlagString(flags, flagdesc, flagmask)); +} + + +bool Settings::setNoiseParams(const std::string &name, const NoiseParams &np) +{ + Settings *group = new Settings; + + group->setFloat("offset", np.offset); + group->setFloat("scale", np.scale); + group->setV3F("spread", np.spread); + group->setS32("seed", np.seed); + group->setU16("octaves", np.octaves); + group->setFloat("persistence", np.persist); + group->setFloat("lacunarity", np.lacunarity); + group->setFlagStr("flags", np.flags, flagdesc_noiseparams, np.flags); + + return setEntry(name, &group, true); +} + + +bool Settings::remove(const std::string &name) +{ + // Lock as short as possible, unlock before doCallbacks() + m_mutex.lock(); + + SettingEntries::iterator it = m_settings.find(name); + if (it != m_settings.end()) { + delete it->second.group; + m_settings.erase(it); + m_mutex.unlock(); + + doCallbacks(name); + return true; + } + + m_mutex.unlock(); + return false; +} + + +SettingsParseEvent Settings::parseConfigObject(const std::string &line, + std::string &name, std::string &value) +{ + std::string trimmed_line = trim(line); + + if (trimmed_line.empty()) + return SPE_NONE; + if (trimmed_line[0] == '#') + return SPE_COMMENT; + if (trimmed_line == m_end_tag) + return SPE_END; + + size_t pos = trimmed_line.find('='); + if (pos == std::string::npos) + return SPE_INVALID; + + name = trim(trimmed_line.substr(0, pos)); + value = trim(trimmed_line.substr(pos + 1)); + + if (value == "{") + return SPE_GROUP; + if (value == "\"\"\"") + return SPE_MULTILINE; + + return SPE_KVPAIR; +} + + +void Settings::clearNoLock() +{ + for (SettingEntries::const_iterator it = m_settings.begin(); + it != m_settings.end(); ++it) + delete it->second.group; + m_settings.clear(); +} + + +void Settings::setDefault(const std::string &name, const FlagDesc *flagdesc, + u32 flags) +{ + s_flags[name] = flagdesc; + setDefault(name, writeFlagString(flags, flagdesc, U32_MAX)); +} + +const FlagDesc *Settings::getFlagDescFallback(const std::string &name) const +{ + auto it = s_flags.find(name); + return it == s_flags.end() ? nullptr : it->second; +} + +void Settings::registerChangedCallback(const std::string &name, + SettingsChangedCallback cbf, void *userdata) +{ + MutexAutoLock lock(m_callback_mutex); + m_callbacks[name].emplace_back(cbf, userdata); +} + +void Settings::deregisterChangedCallback(const std::string &name, + SettingsChangedCallback cbf, void *userdata) +{ + MutexAutoLock lock(m_callback_mutex); + SettingsCallbackMap::iterator it_cbks = m_callbacks.find(name); + + if (it_cbks != m_callbacks.end()) { + SettingsCallbackList &cbks = it_cbks->second; + + SettingsCallbackList::iterator position = + std::find(cbks.begin(), cbks.end(), std::make_pair(cbf, userdata)); + + if (position != cbks.end()) + cbks.erase(position); + } +} + +void Settings::removeSecureSettings() +{ + for (const auto &name : getNames()) { + if (name.compare(0, 7, "secure.") != 0) + continue; + + errorstream << "Secure setting " << name + << " isn't allowed, so was ignored." + << std::endl; + remove(name); + } +} + +void Settings::doCallbacks(const std::string &name) const +{ + MutexAutoLock lock(m_callback_mutex); + + SettingsCallbackMap::const_iterator it_cbks = m_callbacks.find(name); + if (it_cbks != m_callbacks.end()) { + SettingsCallbackList::const_iterator it; + for (it = it_cbks->second.begin(); it != it_cbks->second.end(); ++it) + (it->first)(name, it->second); + } +} diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 0000000..4b07873 --- /dev/null +++ b/src/settings.h @@ -0,0 +1,298 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +#include "util/string.h" +#include "util/basic_macros.h" +#include <string> +#include <list> +#include <set> +#include <mutex> + +class Settings; +struct NoiseParams; + +// Global objects +extern Settings *g_settings; // Same as Settings::getLayer(SL_GLOBAL); +extern std::string g_settings_path; + +// Type for a settings changed callback function +typedef void (*SettingsChangedCallback)(const std::string &name, void *data); + +typedef std::vector< + std::pair< + SettingsChangedCallback, + void * + > +> SettingsCallbackList; + +typedef std::unordered_map<std::string, SettingsCallbackList> SettingsCallbackMap; + +enum ValueType { + VALUETYPE_STRING, + VALUETYPE_FLAG // Doesn't take any arguments +}; + +enum SettingsParseEvent { + SPE_NONE, + SPE_INVALID, + SPE_COMMENT, + SPE_KVPAIR, + SPE_END, + SPE_GROUP, + SPE_MULTILINE, +}; + +// Describes the global setting layers, SL_GLOBAL is where settings are read from +enum SettingsLayer { + SL_DEFAULTS, + SL_GAME, + SL_GLOBAL, + SL_TOTAL_COUNT +}; + +// Implements the hierarchy a settings object may be part of +class SettingsHierarchy { +public: + /* + * A settings object that may be part of another hierarchy can + * occupy the index 0 as a fallback. If not set you can use 0 on your own. + */ + SettingsHierarchy(Settings *fallback = nullptr); + + DISABLE_CLASS_COPY(SettingsHierarchy) + + Settings *getLayer(int layer) const; + +private: + friend class Settings; + Settings *getParent(int layer) const; + void onLayerCreated(int layer, Settings *obj); + void onLayerRemoved(int layer); + + std::vector<Settings*> layers; +}; + +struct ValueSpec { + ValueSpec(ValueType a_type, const char *a_help=NULL) + { + type = a_type; + help = a_help; + } + + ValueType type; + const char *help; +}; + +struct SettingsEntry { + SettingsEntry() = default; + + SettingsEntry(const std::string &value_) : + value(value_) + {} + + SettingsEntry(Settings *group_) : + group(group_), + is_group(true) + {} + + std::string value = ""; + Settings *group = nullptr; + bool is_group = false; +}; + +typedef std::unordered_map<std::string, SettingsEntry> SettingEntries; + +class Settings { +public: + /* These functions operate on the global hierarchy! */ + static Settings *createLayer(SettingsLayer sl, const std::string &end_tag = ""); + static Settings *getLayer(SettingsLayer sl); + /**/ + + Settings(const std::string &end_tag = "") : + m_end_tag(end_tag) + {} + Settings(const std::string &end_tag, SettingsHierarchy *h, int settings_layer); + ~Settings(); + + Settings & operator += (const Settings &other); + Settings & operator = (const Settings &other); + + /*********************** + * Reading and writing * + ***********************/ + + // Read configuration file. Returns success. + bool readConfigFile(const char *filename); + //Updates configuration file. Returns success. + bool updateConfigFile(const char *filename); + // NOTE: Types of allowed_options are ignored. Returns success. + bool parseCommandLine(int argc, char *argv[], + std::map<std::string, ValueSpec> &allowed_options); + bool parseConfigLines(std::istream &is); + void writeLines(std::ostream &os, u32 tab_depth=0) const; + + /*********** + * Getters * + ***********/ + + Settings *getGroup(const std::string &name) const; + const std::string &get(const std::string &name) const; + bool getBool(const std::string &name) const; + u16 getU16(const std::string &name) const; + s16 getS16(const std::string &name) const; + u32 getU32(const std::string &name) const; + s32 getS32(const std::string &name) const; + u64 getU64(const std::string &name) const; + float getFloat(const std::string &name) const; + float getFloat(const std::string &name, float min, float max) const; + v2f getV2F(const std::string &name) const; + v3f getV3F(const std::string &name) const; + u32 getFlagStr(const std::string &name, const FlagDesc *flagdesc, + u32 *flagmask) const; + bool getNoiseParams(const std::string &name, NoiseParams &np) const; + bool getNoiseParamsFromValue(const std::string &name, NoiseParams &np) const; + bool getNoiseParamsFromGroup(const std::string &name, NoiseParams &np) const; + + // return all keys used in this object + std::vector<std::string> getNames() const; + // check if setting exists anywhere in the hierarchy + bool exists(const std::string &name) const; + // check if setting exists in this object ("locally") + bool existsLocal(const std::string &name) const; + + + /*************************************** + * Getters that don't throw exceptions * + ***************************************/ + + bool getGroupNoEx(const std::string &name, Settings *&val) const; + bool getNoEx(const std::string &name, std::string &val) const; + bool getFlag(const std::string &name) const; + bool getU16NoEx(const std::string &name, u16 &val) const; + bool getS16NoEx(const std::string &name, s16 &val) const; + bool getU32NoEx(const std::string &name, u32 &val) const; + bool getS32NoEx(const std::string &name, s32 &val) const; + bool getU64NoEx(const std::string &name, u64 &val) const; + bool getFloatNoEx(const std::string &name, float &val) const; + bool getV2FNoEx(const std::string &name, v2f &val) const; + bool getV3FNoEx(const std::string &name, v3f &val) const; + + // Like other getters, but handling each flag individualy: + // 1) Read default flags (or 0) + // 2) Override using user-defined flags + bool getFlagStrNoEx(const std::string &name, u32 &val, + const FlagDesc *flagdesc) const; + + + /*********** + * Setters * + ***********/ + + // N.B. Groups not allocated with new must be set to NULL in the settings + // tree before object destruction. + bool setEntry(const std::string &name, const void *entry, + bool set_group); + bool set(const std::string &name, const std::string &value); + bool setDefault(const std::string &name, const std::string &value); + bool setGroup(const std::string &name, const Settings &group); + bool setBool(const std::string &name, bool value); + bool setS16(const std::string &name, s16 value); + bool setU16(const std::string &name, u16 value); + bool setS32(const std::string &name, s32 value); + bool setU64(const std::string &name, u64 value); + bool setFloat(const std::string &name, float value); + bool setV2F(const std::string &name, v2f value); + bool setV3F(const std::string &name, v3f value); + bool setFlagStr(const std::string &name, u32 flags, + const FlagDesc *flagdesc = nullptr, u32 flagmask = U32_MAX); + bool setNoiseParams(const std::string &name, const NoiseParams &np); + + // remove a setting + bool remove(const std::string &name); + + /***************** + * Miscellaneous * + *****************/ + + void setDefault(const std::string &name, const FlagDesc *flagdesc, u32 flags); + const FlagDesc *getFlagDescFallback(const std::string &name) const; + + void registerChangedCallback(const std::string &name, + SettingsChangedCallback cbf, void *userdata = NULL); + void deregisterChangedCallback(const std::string &name, + SettingsChangedCallback cbf, void *userdata = NULL); + + void removeSecureSettings(); + + // Returns the settings layer this object is. + // If within the global hierarchy you can cast this to enum SettingsLayer + inline int getLayer() const { return m_settingslayer; } + +private: + /*********************** + * Reading and writing * + ***********************/ + + SettingsParseEvent parseConfigObject(const std::string &line, + std::string &name, std::string &value); + bool updateConfigObject(std::istream &is, std::ostream &os, + u32 tab_depth=0); + + static bool checkNameValid(const std::string &name); + static bool checkValueValid(const std::string &value); + static std::string getMultiline(std::istream &is, size_t *num_lines=NULL); + static void printEntry(std::ostream &os, const std::string &name, + const SettingsEntry &entry, u32 tab_depth=0); + + /*********** + * Getters * + ***********/ + Settings *getParent() const; + + const SettingsEntry &getEntry(const std::string &name) const; + + // Allow TestSettings to run sanity checks using private functions. + friend class TestSettings; + // For sane mutex locking when iterating + friend class LuaSettings; + + void updateNoLock(const Settings &other); + void clearNoLock(); + void clearDefaultsNoLock(); + + void doCallbacks(const std::string &name) const; + + SettingEntries m_settings; + SettingsCallbackMap m_callbacks; + std::string m_end_tag; + + mutable std::mutex m_callback_mutex; + + // All methods that access m_settings/m_defaults directly should lock this. + mutable std::mutex m_mutex; + + SettingsHierarchy *m_hierarchy = nullptr; + int m_settingslayer = -1; + + static std::unordered_map<std::string, const FlagDesc *> s_flags; +}; diff --git a/src/settings_translation_file.cpp b/src/settings_translation_file.cpp new file mode 100644 index 0000000..03bb564 --- /dev/null +++ b/src/settings_translation_file.cpp @@ -0,0 +1,1161 @@ +// This file is automatically generated +// It contains a bunch of fake gettext calls, to tell xgettext about the strings in config files +// To update it, refer to the bottom of builtin/mainmenu/dlg_settings_advanced.lua + +fake_function() { + gettext("Controls"); + gettext("General"); + gettext("Build inside player"); + gettext("If enabled, you can place blocks at the position (feet + eye level) where you stand.\nThis is helpful when working with nodeboxes in small areas."); + gettext("Cinematic mode"); + gettext("Smooths camera when looking around. Also called look or mouse smoothing.\nUseful for recording videos."); + gettext("Camera smoothing"); + gettext("Smooths rotation of camera. 0 to disable."); + gettext("Camera smoothing in cinematic mode"); + gettext("Smooths rotation of camera in cinematic mode. 0 to disable."); + gettext("Aux1 key for climbing/descending"); + gettext("If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down and\ndescending."); + gettext("Double tap jump for fly"); + gettext("Double-tapping the jump key toggles fly mode."); + gettext("Always fly fast"); + gettext("If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\nenabled."); + gettext("Place repetition interval"); + gettext("The time in seconds it takes between repeated node placements when holding\nthe place button."); + gettext("Automatic jumping"); + gettext("Automatically jump up single-node obstacles."); + gettext("Safe digging and placing"); + gettext("Prevent digging and placing from repeating when holding the mouse buttons.\nEnable this when you dig or place too often by accident."); + gettext("Keyboard and Mouse"); + gettext("Invert mouse"); + gettext("Invert vertical mouse movement."); + gettext("Mouse sensitivity"); + gettext("Mouse sensitivity multiplier."); + gettext("Touchscreen"); + gettext("Touch screen threshold"); + gettext("The length in pixels it takes for touch screen interaction to start."); + gettext("Fixed virtual joystick"); + gettext("(Android) Fixes the position of virtual joystick.\nIf disabled, virtual joystick will center to first-touch's position."); + gettext("Virtual joystick triggers Aux1 button"); + gettext("(Android) Use virtual joystick to trigger \"Aux1\" button.\nIf enabled, virtual joystick will also tap \"Aux1\" button when out of main circle."); + gettext("Graphics and Audio"); + gettext("Graphics"); + gettext("Screen"); + gettext("Screen width"); + gettext("Width component of the initial window size. Ignored in fullscreen mode."); + gettext("Screen height"); + gettext("Height component of the initial window size. Ignored in fullscreen mode."); + gettext("Autosave screen size"); + gettext("Save window size automatically when modified."); + gettext("Full screen"); + gettext("Fullscreen mode."); + gettext("Pause on lost window focus"); + gettext("Open the pause menu when the window's focus is lost. Does not pause if a formspec is\nopen."); + gettext("FPS"); + gettext("Maximum FPS"); + gettext("If FPS would go higher than this, limit it by sleeping\nto not waste CPU power for no benefit."); + gettext("VSync"); + gettext("Vertical screen synchronization."); + gettext("FPS when unfocused or paused"); + gettext("Maximum FPS when the window is not focused, or when the game is paused."); + gettext("Viewing range"); + gettext("View distance in nodes."); + gettext("Undersampling"); + gettext("Undersampling is similar to using a lower screen resolution, but it applies\nto the game world only, keeping the GUI intact.\nIt should give a significant performance boost at the cost of less detailed image.\nHigher values result in a less detailed image."); + gettext("Graphics Effects"); + gettext("Opaque liquids"); + gettext("Makes all liquids opaque"); + gettext("Leaves style"); + gettext("Leaves style:\n- Fancy: all faces visible\n- Simple: only outer faces, if defined special_tiles are used\n- Opaque: disable transparency"); + gettext("Connect glass"); + gettext("Connects glass if supported by node."); + gettext("Smooth lighting"); + gettext("Enable smooth lighting with simple ambient occlusion.\nDisable for speed or for different looks."); + gettext("Tradeoffs for performance"); + gettext("Enables tradeoffs that reduce CPU load or increase rendering performance\nat the expense of minor visual glitches that do not impact game playability."); + gettext("Digging particles"); + gettext("Adds particles when digging a node."); + gettext("3d"); + gettext("3D mode"); + gettext("3D support.\nCurrently supported:\n- none: no 3d output.\n- anaglyph: cyan/magenta color 3d.\n- interlaced: odd/even line based polarisation screen support.\n- topbottom: split screen top/bottom.\n- sidebyside: split screen side by side.\n- crossview: Cross-eyed 3d\n- pageflip: quadbuffer based 3d.\nNote that the interlaced mode requires shaders to be enabled."); + gettext("3D mode parallax strength"); + gettext("Strength of 3D mode parallax."); + gettext("Bobbing"); + gettext("Arm inertia"); + gettext("Arm inertia, gives a more realistic movement of\nthe arm when the camera moves."); + gettext("View bobbing factor"); + gettext("Enable view bobbing and amount of view bobbing.\nFor example: 0 for no view bobbing; 1.0 for normal; 2.0 for double."); + gettext("Fall bobbing factor"); + gettext("Multiplier for fall bobbing.\nFor example: 0 for no view bobbing; 1.0 for normal; 2.0 for double."); + gettext("Camera"); + gettext("Near plane"); + gettext("Camera 'near clipping plane' distance in nodes, between 0 and 0.25\nOnly works on GLES platforms. Most users will not need to change this.\nIncreasing can reduce artifacting on weaker GPUs.\n0.1 = Default, 0.25 = Good value for weaker tablets."); + gettext("Field of view"); + gettext("Field of view in degrees."); + gettext("Light curve gamma"); + gettext("Alters the light curve by applying 'gamma correction' to it.\nHigher values make middle and lower light levels brighter.\nValue '1.0' leaves the light curve unaltered.\nThis only has significant effect on daylight and artificial\nlight, it has very little effect on natural night light."); + gettext("Ambient occlusion gamma"); + gettext("The strength (darkness) of node ambient-occlusion shading.\nLower is darker, Higher is lighter. The valid range of values for this\nsetting is 0.25 to 4.0 inclusive. If the value is out of range it will be\nset to the nearest valid value."); + gettext("Screenshots"); + gettext("Screenshot folder"); + gettext("Path to save screenshots at. Can be an absolute or relative path.\nThe folder will be created if it doesn't already exist."); + gettext("Screenshot format"); + gettext("Format of screenshots."); + gettext("Screenshot quality"); + gettext("Screenshot quality. Only used for JPEG format.\n1 means worst quality; 100 means best quality.\nUse 0 for default quality."); + gettext("Node and Entity Highlighting"); + gettext("Node highlighting"); + gettext("Method used to highlight selected object."); + gettext("Show entity selection boxes"); + gettext("Show entity selection boxes\nA restart is required after changing this."); + gettext("Selection box color"); + gettext("Selection box border color (R,G,B)."); + gettext("Selection box width"); + gettext("Width of the selection box lines around nodes."); + gettext("Crosshair color"); + gettext("Crosshair color (R,G,B).\nAlso controls the object crosshair color"); + gettext("Crosshair alpha"); + gettext("Crosshair alpha (opaqueness, between 0 and 255).\nThis also applies to the object crosshair."); + gettext("Fog"); + gettext("Fog"); + gettext("Whether to fog out the end of the visible area."); + gettext("Colored fog"); + gettext("Make fog and sky colors depend on daytime (dawn/sunset) and view direction."); + gettext("Fog start"); + gettext("Fraction of the visible distance at which fog starts to be rendered"); + gettext("Clouds"); + gettext("Clouds"); + gettext("Clouds are a client side effect."); + gettext("3D clouds"); + gettext("Use 3D cloud look instead of flat."); + gettext("Filtering and Antialiasing"); + gettext("Mipmapping"); + gettext("Use mipmapping to scale textures. May slightly increase performance,\nespecially when using a high resolution texture pack.\nGamma correct downscaling is not supported."); + gettext("Anisotropic filtering"); + gettext("Use anisotropic filtering when viewing at textures from an angle."); + gettext("Bilinear filtering"); + gettext("Use bilinear filtering when scaling textures."); + gettext("Trilinear filtering"); + gettext("Use trilinear filtering when scaling textures."); + gettext("Clean transparent textures"); + gettext("Filtered textures can blend RGB values with fully-transparent neighbors,\nwhich PNG optimizers usually discard, often resulting in dark or\nlight edges to transparent textures. Apply a filter to clean that up\nat texture load time. This is automatically enabled if mipmapping is enabled."); + gettext("Minimum texture size"); + gettext("When using bilinear/trilinear/anisotropic filters, low-resolution textures\ncan be blurred, so automatically upscale them with nearest-neighbor\ninterpolation to preserve crisp pixels. This sets the minimum texture size\nfor the upscaled textures; higher values look sharper, but require more\nmemory. Powers of 2 are recommended. This setting is ONLY applied if\nbilinear/trilinear/anisotropic filtering is enabled.\nThis is also used as the base node texture size for world-aligned\ntexture autoscaling."); + gettext("FSAA"); + gettext("Use multi-sample antialiasing (MSAA) to smooth out block edges.\nThis algorithm smooths out the 3D viewport while keeping the image sharp,\nbut it doesn't affect the insides of textures\n(which is especially noticeable with transparent textures).\nVisible spaces appear between nodes when shaders are disabled.\nIf set to 0, MSAA is disabled.\nA restart is required after changing this option."); + gettext("Shaders"); + gettext("Shaders"); + gettext("Shaders allow advanced visual effects and may increase performance on some video\ncards.\nThis only works with the OpenGL video backend."); + gettext("Tone Mapping"); + gettext("Filmic tone mapping"); + gettext("Enables Hable's 'Uncharted 2' filmic tone mapping.\nSimulates the tone curve of photographic film and how this approximates the\nappearance of high dynamic range images. Mid-range contrast is slightly\nenhanced, highlights and shadows are gradually compressed."); + gettext("Waving Nodes"); + gettext("Waving leaves"); + gettext("Set to true to enable waving leaves.\nRequires shaders to be enabled."); + gettext("Waving plants"); + gettext("Set to true to enable waving plants.\nRequires shaders to be enabled."); + gettext("Waving liquids"); + gettext("Set to true to enable waving liquids (like water).\nRequires shaders to be enabled."); + gettext("Waving liquids wave height"); + gettext("The maximum height of the surface of waving liquids.\n4.0 = Wave height is two nodes.\n0.0 = Wave doesn't move at all.\nDefault is 1.0 (1/2 node).\nRequires waving liquids to be enabled."); + gettext("Waving liquids wavelength"); + gettext("Length of liquid waves.\nRequires waving liquids to be enabled."); + gettext("Waving liquids wave speed"); + gettext("How fast liquid waves will move. Higher = faster.\nIf negative, liquid waves will move backwards.\nRequires waving liquids to be enabled."); + gettext("Dynamic shadows"); + gettext("Dynamic shadows"); + gettext("Set to true to enable Shadow Mapping.\nRequires shaders to be enabled."); + gettext("Shadow strength gamma"); + gettext("Set the shadow strength gamma.\nAdjusts the intensity of in-game dynamic shadows.\nLower value means lighter shadows, higher value means darker shadows."); + gettext("Shadow map max distance in nodes to render shadows"); + gettext("Maximum distance to render shadows."); + gettext("Shadow map texture size"); + gettext("Texture size to render the shadow map on.\nThis must be a power of two.\nBigger numbers create better shadows but it is also more expensive."); + gettext("Shadow map texture in 32 bits"); + gettext("Sets shadow texture quality to 32 bits.\nOn false, 16 bits texture will be used.\nThis can cause much more artifacts in the shadow."); + gettext("Poisson filtering"); + gettext("Enable Poisson disk filtering.\nOn true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF filtering."); + gettext("Shadow filter quality"); + gettext("Define shadow filtering quality.\nThis simulates the soft shadows effect by applying a PCF or Poisson disk\nbut also uses more resources."); + gettext("Colored shadows"); + gettext("Enable colored shadows.\nOn true translucent nodes cast colored shadows. This is expensive."); + gettext("Map shadows update frames"); + gettext("Spread a complete update of shadow map over given amount of frames.\nHigher values might make shadows laggy, lower values\nwill consume more resources.\nMinimum value: 1; maximum value: 16"); + gettext("Soft shadow radius"); + gettext("Set the soft shadow radius size.\nLower values mean sharper shadows, bigger values mean softer shadows.\nMinimum value: 1.0; maximum value: 15.0"); + gettext("Sky Body Orbit Tilt"); + gettext("Set the tilt of Sun/Moon orbit in degrees.\nValue of 0 means no tilt / vertical orbit.\nMinimum value: 0.0; maximum value: 60.0"); + gettext("Audio"); + gettext("Volume"); + gettext("Volume of all sounds.\nRequires the sound system to be enabled."); + gettext("Mute sound"); + gettext("Whether to mute sounds. You can unmute sounds at any time, unless the\nsound system is disabled (enable_sound=false).\nIn-game, you can toggle the mute state with the mute key or by using the\npause menu."); + gettext("User Interfaces"); + gettext("Language"); + gettext("Set the language. Leave empty to use the system language.\nA restart is required after changing this."); + gettext("GUIs"); + gettext("GUI scaling"); + gettext("Scale GUI by a user specified value.\nUse a nearest-neighbor-anti-alias filter to scale the GUI.\nThis will smooth over some of the rough edges, and blend\npixels when scaling down, at the cost of blurring some\nedge pixels when images are scaled by non-integer sizes."); + gettext("Inventory items animations"); + gettext("Enables animation of inventory items."); + gettext("Formspec Full-Screen Background Opacity"); + gettext("Formspec full-screen background opacity (between 0 and 255)."); + gettext("Formspec Full-Screen Background Color"); + gettext("Formspec full-screen background color (R,G,B)."); + gettext("GUI scaling filter"); + gettext("When gui_scaling_filter is true, all GUI images need to be\nfiltered in software, but some images are generated directly\nto hardware (e.g. render-to-texture for nodes in inventory)."); + gettext("GUI scaling filter txr2img"); + gettext("When gui_scaling_filter_txr2img is true, copy those images\nfrom hardware to software for scaling. When false, fall back\nto the old scaling method, for video drivers that don't\nproperly support downloading textures back from hardware."); + gettext("Tooltip delay"); + gettext("Delay showing tooltips, stated in milliseconds."); + gettext("Append item name"); + gettext("Append item name to tooltip."); + gettext("Clouds in menu"); + gettext("Use a cloud animation for the main menu background."); + gettext("HUD"); + gettext("HUD scaling"); + gettext("Modifies the size of the HUD elements."); + gettext("Show name tag backgrounds by default"); + gettext("Whether name tag backgrounds should be shown by default.\nMods may still set a background."); + gettext("Chat"); + gettext("Recent Chat Messages"); + gettext("Maximum number of recent chat messages to show"); + gettext("Console height"); + gettext("In-game chat console height, between 0.1 (10%) and 1.0 (100%)."); + gettext("Console color"); + gettext("In-game chat console background color (R,G,B)."); + gettext("Console alpha"); + gettext("In-game chat console background alpha (opaqueness, between 0 and 255)."); + gettext("Maximum hotbar width"); + gettext("Maximum proportion of current window to be used for hotbar.\nUseful if there's something to be displayed right or left of hotbar."); + gettext("Chat weblinks"); + gettext("Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output."); + gettext("Weblink color"); + gettext("Optional override for chat weblink color."); + gettext("Chat font size"); + gettext("Font size of the recent chat text and chat prompt in point (pt).\nValue 0 will use the default font size."); + gettext("Content Repository"); + gettext("ContentDB URL"); + gettext("The URL for the content repository"); + gettext("ContentDB Flag Blacklist"); + gettext("Comma-separated list of flags to hide in the content repository.\n\"nonfree\" can be used to hide packages which do not qualify as 'free software',\nas defined by the Free Software Foundation.\nYou can also specify content ratings.\nThese flags are independent from Minetest versions,\nso see a full list at https://content.minetest.net/help/content_flags/"); + gettext("ContentDB Max Concurrent Downloads"); + gettext("Maximum number of concurrent downloads. Downloads exceeding this limit will be queued.\nThis should be lower than curl_parallel_limit."); + gettext("Client and Server"); + gettext("Client"); + gettext("Saving map received from server"); + gettext("Save the map received by the client on disk."); + gettext("Serverlist URL"); + gettext("URL to the server list displayed in the Multiplayer Tab."); + gettext("Enable split login/register"); + gettext("If enabled, account registration is separate from login in the UI.\nIf disabled, new accounts will be registered automatically when logging in."); + gettext("Server"); + gettext("Admin name"); + gettext("Name of the player.\nWhen running a server, clients connecting with this name are admins.\nWhen starting from the main menu, this is overridden."); + gettext("Serverlist and MOTD"); + gettext("Server name"); + gettext("Name of the server, to be displayed when players join and in the serverlist."); + gettext("Server description"); + gettext("Description of server, to be displayed when players join and in the serverlist."); + gettext("Server address"); + gettext("Domain name of server, to be displayed in the serverlist."); + gettext("Server URL"); + gettext("Homepage of server, to be displayed in the serverlist."); + gettext("Announce server"); + gettext("Automatically report to the serverlist."); + gettext("Serverlist URL"); + gettext("Announce to this serverlist."); + gettext("Message of the day"); + gettext("Message of the day displayed to players connecting."); + gettext("Maximum users"); + gettext("Maximum number of players that can be connected simultaneously."); + gettext("Static spawnpoint"); + gettext("If this is set, players will always (re)spawn at the given position."); + gettext("Networking"); + gettext("Server port"); + gettext("Network port to listen (UDP).\nThis value will be overridden when starting from the main menu."); + gettext("Bind address"); + gettext("The network interface that the server listens on."); + gettext("Strict protocol checking"); + gettext("Enable to disallow old clients from connecting.\nOlder clients are compatible in the sense that they will not crash when connecting\nto new servers, but they may not support all new features that you are expecting."); + gettext("Remote media"); + gettext("Specifies URL from which client fetches media instead of using UDP.\n$filename should be accessible from $remote_media$filename via cURL\n(obviously, remote_media should end with a slash).\nFiles that are not present will be fetched the usual way."); + gettext("IPv6 server"); + gettext("Enable/disable running an IPv6 server.\nIgnored if bind_address is set.\nNeeds enable_ipv6 to be enabled."); + gettext("Server Security"); + gettext("Default password"); + gettext("New users need to input this password."); + gettext("Disallow empty passwords"); + gettext("If enabled, players cannot join without a password or change theirs to an empty password."); + gettext("Default privileges"); + gettext("The privileges that new users automatically get.\nSee /privs in game for a full list on your server and mod configuration."); + gettext("Basic privileges"); + gettext("Privileges that players with basic_privs can grant"); + gettext("Disable anticheat"); + gettext("If enabled, disable cheat prevention in multiplayer."); + gettext("Rollback recording"); + gettext("If enabled, actions are recorded for rollback.\nThis option is only read when server starts."); + gettext("Client-side Modding"); + gettext("Client side modding restrictions"); + gettext("Restricts the access of certain client-side functions on servers.\nCombine the byteflags below to restrict client-side features, or set to 0\nfor no restrictions:\nLOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\nCHAT_MESSAGES: 2 (disable send_chat_message call client-side)\nREAD_ITEMDEFS: 4 (disable get_item_def call client-side)\nREAD_NODEDEFS: 8 (disable get_node_def call client-side)\nLOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\ncsm_restriction_noderange)\nREAD_PLAYERINFO: 32 (disable get_player_names call client-side)"); + gettext("Client side node lookup range restriction"); + gettext("If the CSM restriction for node range is enabled, get_node calls are limited\nto this distance from the player to the node."); + gettext("Chat"); + gettext("Strip color codes"); + gettext("Remove color codes from incoming chat messages\nUse this to stop players from being able to use color in their messages"); + gettext("Chat message max length"); + gettext("Set the maximum length of a chat message (in characters) sent by clients."); + gettext("Chat message count limit"); + gettext("Amount of messages a player may send per 10 seconds."); + gettext("Chat message kick threshold"); + gettext("Kick players who sent more than X messages per 10 seconds."); + gettext("Server Gameplay"); + gettext("Time speed"); + gettext("Controls length of day/night cycle.\nExamples:\n72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged."); + gettext("World start time"); + gettext("Time of day when a new world is started, in millihours (0-23999)."); + gettext("Item entity TTL"); + gettext("Time in seconds for item entity (dropped items) to live.\nSetting it to -1 disables the feature."); + gettext("Default stack size"); + gettext("Specifies the default stack size of nodes, items and tools.\nNote that mods or games may explicitly set a stack for certain (or all) items."); + gettext("Physics"); + gettext("Default acceleration"); + gettext("Horizontal and vertical acceleration on ground or when climbing,\nin nodes per second per second."); + gettext("Acceleration in air"); + gettext("Horizontal acceleration in air when jumping or falling,\nin nodes per second per second."); + gettext("Fast mode acceleration"); + gettext("Horizontal and vertical acceleration in fast mode,\nin nodes per second per second."); + gettext("Walking speed"); + gettext("Walking and flying speed, in nodes per second."); + gettext("Sneaking speed"); + gettext("Sneaking speed, in nodes per second."); + gettext("Fast mode speed"); + gettext("Walking, flying and climbing speed in fast mode, in nodes per second."); + gettext("Climbing speed"); + gettext("Vertical climbing speed, in nodes per second."); + gettext("Jumping speed"); + gettext("Initial vertical speed when jumping, in nodes per second."); + gettext("Liquid fluidity"); + gettext("How much you are slowed down when moving inside a liquid.\nDecrease this to increase liquid resistance to movement."); + gettext("Liquid fluidity smoothing"); + gettext("Maximum liquid resistance. Controls deceleration when entering liquid at\nhigh speed."); + gettext("Liquid sinking"); + gettext("Controls sinking speed in liquid when idling. Negative values will cause\nyou to rise instead."); + gettext("Gravity"); + gettext("Acceleration of gravity, in nodes per second per second."); + gettext("Mapgen"); + gettext("Fixed map seed"); + gettext("A chosen map seed for a new map, leave empty for random.\nWill be overridden when creating a new world in the main menu."); + gettext("Mapgen name"); + gettext("Name of map generator to be used when creating a new world.\nCreating a world in the main menu will override this.\nCurrent mapgens in a highly unstable state:\n- The optional floatlands of v7 (disabled by default)."); + gettext("Water level"); + gettext("Water surface level of the world."); + gettext("Max block generate distance"); + gettext("From how far blocks are generated for clients, stated in mapblocks (16 nodes)."); + gettext("Map generation limit"); + gettext("Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\nOnly mapchunks completely within the mapgen limit are generated.\nValue is stored per-world."); + gettext("Mapgen flags"); + gettext("Global map generation attributes.\nIn Mapgen v6 the 'decorations' flag controls all decorations except trees\nand jungle grass, in all other mapgens this flag controls all decorations."); + gettext("Biome API noise parameters"); + gettext("Heat noise"); + gettext("Temperature variation for biomes."); + gettext("Heat blend noise"); + gettext("Small-scale temperature variation for blending biomes on borders."); + gettext("Humidity noise"); + gettext("Humidity variation for biomes."); + gettext("Humidity blend noise"); + gettext("Small-scale humidity variation for blending biomes on borders."); + gettext("Mapgen V5"); + gettext("Mapgen V5 specific flags"); + gettext("Map generation attributes specific to Mapgen v5."); + gettext("Cave width"); + gettext("Controls width of tunnels, a smaller value creates wider tunnels.\nValue >= 10.0 completely disables generation of tunnels and avoids the\nintensive noise calculations."); + gettext("Large cave depth"); + gettext("Y of upper limit of large caves."); + gettext("Small cave minimum number"); + gettext("Minimum limit of random number of small caves per mapchunk."); + gettext("Small cave maximum number"); + gettext("Maximum limit of random number of small caves per mapchunk."); + gettext("Large cave minimum number"); + gettext("Minimum limit of random number of large caves per mapchunk."); + gettext("Large cave maximum number"); + gettext("Maximum limit of random number of large caves per mapchunk."); + gettext("Large cave proportion flooded"); + gettext("Proportion of large caves that contain liquid."); + gettext("Cavern limit"); + gettext("Y-level of cavern upper limit."); + gettext("Cavern taper"); + gettext("Y-distance over which caverns expand to full size."); + gettext("Cavern threshold"); + gettext("Defines full size of caverns, smaller values create larger caverns."); + gettext("Dungeon minimum Y"); + gettext("Lower Y limit of dungeons."); + gettext("Dungeon maximum Y"); + gettext("Upper Y limit of dungeons."); + gettext("Noises"); + gettext("Filler depth noise"); + gettext("Variation of biome filler depth."); + gettext("Factor noise"); + gettext("Variation of terrain vertical scale.\nWhen noise is < -0.55 terrain is near-flat."); + gettext("Height noise"); + gettext("Y-level of average terrain surface."); + gettext("Cave1 noise"); + gettext("First of two 3D noises that together define tunnels."); + gettext("Cave2 noise"); + gettext("Second of two 3D noises that together define tunnels."); + gettext("Cavern noise"); + gettext("3D noise defining giant caverns."); + gettext("Ground noise"); + gettext("3D noise defining terrain."); + gettext("Dungeon noise"); + gettext("3D noise that determines number of dungeons per mapchunk."); + gettext("Mapgen V6"); + gettext("Mapgen V6 specific flags"); + gettext("Map generation attributes specific to Mapgen v6.\nThe 'snowbiomes' flag enables the new 5 biome system.\nWhen the 'snowbiomes' flag is enabled jungles are automatically enabled and\nthe 'jungles' flag is ignored."); + gettext("Desert noise threshold"); + gettext("Deserts occur when np_biome exceeds this value.\nWhen the 'snowbiomes' flag is enabled, this is ignored."); + gettext("Beach noise threshold"); + gettext("Sandy beaches occur when np_beach exceeds this value."); + gettext("Dungeon minimum Y"); + gettext("Lower Y limit of dungeons."); + gettext("Dungeon maximum Y"); + gettext("Upper Y limit of dungeons."); + gettext("Noises"); + gettext("Terrain base noise"); + gettext("Y-level of lower terrain and seabed."); + gettext("Terrain higher noise"); + gettext("Y-level of higher terrain that creates cliffs."); + gettext("Steepness noise"); + gettext("Varies steepness of cliffs."); + gettext("Height select noise"); + gettext("Defines distribution of higher terrain."); + gettext("Mud noise"); + gettext("Varies depth of biome surface nodes."); + gettext("Beach noise"); + gettext("Defines areas with sandy beaches."); + gettext("Biome noise"); + gettext("Temperature variation for biomes."); + gettext("Cave noise"); + gettext("Variation of number of caves."); + gettext("Humidity noise"); + gettext("Humidity variation for biomes."); + gettext("Trees noise"); + gettext("Defines tree areas and tree density."); + gettext("Apple trees noise"); + gettext("Defines areas where trees have apples."); + gettext("Mapgen V7"); + gettext("Mapgen V7 specific flags"); + gettext("Map generation attributes specific to Mapgen v7.\n'ridges': Rivers.\n'floatlands': Floating land masses in the atmosphere.\n'caverns': Giant caves deep underground."); + gettext("Mountain zero level"); + gettext("Y of mountain density gradient zero level. Used to shift mountains vertically."); + gettext("Floatland minimum Y"); + gettext("Lower Y limit of floatlands."); + gettext("Floatland maximum Y"); + gettext("Upper Y limit of floatlands."); + gettext("Floatland tapering distance"); + gettext("Y-distance over which floatlands taper from full density to nothing.\nTapering starts at this distance from the Y limit.\nFor a solid floatland layer, this controls the height of hills/mountains.\nMust be less than or equal to half the distance between the Y limits."); + gettext("Floatland taper exponent"); + gettext("Exponent of the floatland tapering. Alters the tapering behaviour.\nValue = 1.0 creates a uniform, linear tapering.\nValues > 1.0 create a smooth tapering suitable for the default separated\nfloatlands.\nValues < 1.0 (for example 0.25) create a more defined surface level with\nflatter lowlands, suitable for a solid floatland layer."); + gettext("Floatland density"); + gettext("Adjusts the density of the floatland layer.\nIncrease value to increase density. Can be positive or negative.\nValue = 0.0: 50% of volume is floatland.\nValue = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\nto be sure) creates a solid floatland layer."); + gettext("Floatland water level"); + gettext("Surface level of optional water placed on a solid floatland layer.\nWater is disabled by default and will only be placed if this value is set\nto above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\nupper tapering).\n***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\nWhen enabling water placement the floatlands must be configured and tested\nto be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\nrequired value depending on 'mgv7_np_floatland'), to avoid\nserver-intensive extreme water flow and to avoid vast flooding of the\nworld surface below."); + gettext("Cave width"); + gettext("Controls width of tunnels, a smaller value creates wider tunnels.\nValue >= 10.0 completely disables generation of tunnels and avoids the\nintensive noise calculations."); + gettext("Large cave depth"); + gettext("Y of upper limit of large caves."); + gettext("Small cave minimum number"); + gettext("Minimum limit of random number of small caves per mapchunk."); + gettext("Small cave maximum number"); + gettext("Maximum limit of random number of small caves per mapchunk."); + gettext("Large cave minimum number"); + gettext("Minimum limit of random number of large caves per mapchunk."); + gettext("Large cave maximum number"); + gettext("Maximum limit of random number of large caves per mapchunk."); + gettext("Large cave proportion flooded"); + gettext("Proportion of large caves that contain liquid."); + gettext("Cavern limit"); + gettext("Y-level of cavern upper limit."); + gettext("Cavern taper"); + gettext("Y-distance over which caverns expand to full size."); + gettext("Cavern threshold"); + gettext("Defines full size of caverns, smaller values create larger caverns."); + gettext("Dungeon minimum Y"); + gettext("Lower Y limit of dungeons."); + gettext("Dungeon maximum Y"); + gettext("Upper Y limit of dungeons."); + gettext("Noises"); + gettext("Terrain base noise"); + gettext("Y-level of higher terrain that creates cliffs."); + gettext("Terrain alternative noise"); + gettext("Y-level of lower terrain and seabed."); + gettext("Terrain persistence noise"); + gettext("Varies roughness of terrain.\nDefines the 'persistence' value for terrain_base and terrain_alt noises."); + gettext("Height select noise"); + gettext("Defines distribution of higher terrain and steepness of cliffs."); + gettext("Filler depth noise"); + gettext("Variation of biome filler depth."); + gettext("Mountain height noise"); + gettext("Variation of maximum mountain height (in nodes)."); + gettext("Ridge underwater noise"); + gettext("Defines large-scale river channel structure."); + gettext("Mountain noise"); + gettext("3D noise defining mountain structure and height.\nAlso defines structure of floatland mountain terrain."); + gettext("Ridge noise"); + gettext("3D noise defining structure of river canyon walls."); + gettext("Floatland noise"); + gettext("3D noise defining structure of floatlands.\nIf altered from the default, the noise 'scale' (0.7 by default) may need\nto be adjusted, as floatland tapering functions best when this noise has\na value range of approximately -2.0 to 2.0."); + gettext("Cavern noise"); + gettext("3D noise defining giant caverns."); + gettext("Cave1 noise"); + gettext("First of two 3D noises that together define tunnels."); + gettext("Cave2 noise"); + gettext("Second of two 3D noises that together define tunnels."); + gettext("Dungeon noise"); + gettext("3D noise that determines number of dungeons per mapchunk."); + gettext("Mapgen Carpathian"); + gettext("Mapgen Carpathian specific flags"); + gettext("Map generation attributes specific to Mapgen Carpathian."); + gettext("Base ground level"); + gettext("Defines the base ground level."); + gettext("River channel width"); + gettext("Defines the width of the river channel."); + gettext("River channel depth"); + gettext("Defines the depth of the river channel."); + gettext("River valley width"); + gettext("Defines the width of the river valley."); + gettext("Cave width"); + gettext("Controls width of tunnels, a smaller value creates wider tunnels.\nValue >= 10.0 completely disables generation of tunnels and avoids the\nintensive noise calculations."); + gettext("Large cave depth"); + gettext("Y of upper limit of large caves."); + gettext("Small cave minimum number"); + gettext("Minimum limit of random number of small caves per mapchunk."); + gettext("Small cave maximum number"); + gettext("Maximum limit of random number of small caves per mapchunk."); + gettext("Large cave minimum number"); + gettext("Minimum limit of random number of large caves per mapchunk."); + gettext("Large cave maximum number"); + gettext("Maximum limit of random number of large caves per mapchunk."); + gettext("Large cave proportion flooded"); + gettext("Proportion of large caves that contain liquid."); + gettext("Cavern limit"); + gettext("Y-level of cavern upper limit."); + gettext("Cavern taper"); + gettext("Y-distance over which caverns expand to full size."); + gettext("Cavern threshold"); + gettext("Defines full size of caverns, smaller values create larger caverns."); + gettext("Dungeon minimum Y"); + gettext("Lower Y limit of dungeons."); + gettext("Dungeon maximum Y"); + gettext("Upper Y limit of dungeons."); + gettext("Noises"); + gettext("Filler depth noise"); + gettext("Variation of biome filler depth."); + gettext("Hilliness1 noise"); + gettext("First of 4 2D noises that together define hill/mountain range height."); + gettext("Hilliness2 noise"); + gettext("Second of 4 2D noises that together define hill/mountain range height."); + gettext("Hilliness3 noise"); + gettext("Third of 4 2D noises that together define hill/mountain range height."); + gettext("Hilliness4 noise"); + gettext("Fourth of 4 2D noises that together define hill/mountain range height."); + gettext("Rolling hills spread noise"); + gettext("2D noise that controls the size/occurrence of rolling hills."); + gettext("Ridge mountain spread noise"); + gettext("2D noise that controls the size/occurrence of ridged mountain ranges."); + gettext("Step mountain spread noise"); + gettext("2D noise that controls the size/occurrence of step mountain ranges."); + gettext("Rolling hill size noise"); + gettext("2D noise that controls the shape/size of rolling hills."); + gettext("Ridged mountain size noise"); + gettext("2D noise that controls the shape/size of ridged mountains."); + gettext("Step mountain size noise"); + gettext("2D noise that controls the shape/size of step mountains."); + gettext("River noise"); + gettext("2D noise that locates the river valleys and channels."); + gettext("Mountain variation noise"); + gettext("3D noise for mountain overhangs, cliffs, etc. Usually small variations."); + gettext("Cave1 noise"); + gettext("First of two 3D noises that together define tunnels."); + gettext("Cave2 noise"); + gettext("Second of two 3D noises that together define tunnels."); + gettext("Cavern noise"); + gettext("3D noise defining giant caverns."); + gettext("Dungeon noise"); + gettext("3D noise that determines number of dungeons per mapchunk."); + gettext("Mapgen Flat"); + gettext("Mapgen Flat specific flags"); + gettext("Map generation attributes specific to Mapgen Flat.\nOccasional lakes and hills can be added to the flat world."); + gettext("Ground level"); + gettext("Y of flat ground."); + gettext("Large cave depth"); + gettext("Y of upper limit of large caves."); + gettext("Small cave minimum number"); + gettext("Minimum limit of random number of small caves per mapchunk."); + gettext("Small cave maximum number"); + gettext("Maximum limit of random number of small caves per mapchunk."); + gettext("Large cave minimum number"); + gettext("Minimum limit of random number of large caves per mapchunk."); + gettext("Large cave maximum number"); + gettext("Maximum limit of random number of large caves per mapchunk."); + gettext("Large cave proportion flooded"); + gettext("Proportion of large caves that contain liquid."); + gettext("Cave width"); + gettext("Controls width of tunnels, a smaller value creates wider tunnels.\nValue >= 10.0 completely disables generation of tunnels and avoids the\nintensive noise calculations."); + gettext("Lake threshold"); + gettext("Terrain noise threshold for lakes.\nControls proportion of world area covered by lakes.\nAdjust towards 0.0 for a larger proportion."); + gettext("Lake steepness"); + gettext("Controls steepness/depth of lake depressions."); + gettext("Hill threshold"); + gettext("Terrain noise threshold for hills.\nControls proportion of world area covered by hills.\nAdjust towards 0.0 for a larger proportion."); + gettext("Hill steepness"); + gettext("Controls steepness/height of hills."); + gettext("Cavern limit"); + gettext("Y-level of cavern upper limit."); + gettext("Cavern taper"); + gettext("Y-distance over which caverns expand to full size."); + gettext("Cavern threshold"); + gettext("Defines full size of caverns, smaller values create larger caverns."); + gettext("Dungeon minimum Y"); + gettext("Lower Y limit of dungeons."); + gettext("Dungeon maximum Y"); + gettext("Upper Y limit of dungeons."); + gettext("Noises"); + gettext("Terrain noise"); + gettext("Defines location and terrain of optional hills and lakes."); + gettext("Filler depth noise"); + gettext("Variation of biome filler depth."); + gettext("Cave1 noise"); + gettext("First of two 3D noises that together define tunnels."); + gettext("Cave2 noise"); + gettext("Second of two 3D noises that together define tunnels."); + gettext("Cavern noise"); + gettext("3D noise defining giant caverns."); + gettext("Dungeon noise"); + gettext("3D noise that determines number of dungeons per mapchunk."); + gettext("Mapgen Fractal"); + gettext("Mapgen Fractal specific flags"); + gettext("Map generation attributes specific to Mapgen Fractal.\n'terrain' enables the generation of non-fractal terrain:\nocean, islands and underground."); + gettext("Cave width"); + gettext("Controls width of tunnels, a smaller value creates wider tunnels.\nValue >= 10.0 completely disables generation of tunnels and avoids the\nintensive noise calculations."); + gettext("Large cave depth"); + gettext("Y of upper limit of large caves."); + gettext("Small cave minimum number"); + gettext("Minimum limit of random number of small caves per mapchunk."); + gettext("Small cave maximum number"); + gettext("Maximum limit of random number of small caves per mapchunk."); + gettext("Large cave minimum number"); + gettext("Minimum limit of random number of large caves per mapchunk."); + gettext("Large cave maximum number"); + gettext("Maximum limit of random number of large caves per mapchunk."); + gettext("Large cave proportion flooded"); + gettext("Proportion of large caves that contain liquid."); + gettext("Dungeon minimum Y"); + gettext("Lower Y limit of dungeons."); + gettext("Dungeon maximum Y"); + gettext("Upper Y limit of dungeons."); + gettext("Fractal type"); + gettext("Selects one of 18 fractal types.\n1 = 4D \"Roundy\" Mandelbrot set.\n2 = 4D \"Roundy\" Julia set.\n3 = 4D \"Squarry\" Mandelbrot set.\n4 = 4D \"Squarry\" Julia set.\n5 = 4D \"Mandy Cousin\" Mandelbrot set.\n6 = 4D \"Mandy Cousin\" Julia set.\n7 = 4D \"Variation\" Mandelbrot set.\n8 = 4D \"Variation\" Julia set.\n9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n11 = 3D \"Christmas Tree\" Mandelbrot set.\n12 = 3D \"Christmas Tree\" Julia set.\n13 = 3D \"Mandelbulb\" Mandelbrot set.\n14 = 3D \"Mandelbulb\" Julia set.\n15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n16 = 3D \"Cosine Mandelbulb\" Julia set.\n17 = 4D \"Mandelbulb\" Mandelbrot set.\n18 = 4D \"Mandelbulb\" Julia set."); + gettext("Iterations"); + gettext("Iterations of the recursive function.\nIncreasing this increases the amount of fine detail, but also\nincreases processing load.\nAt iterations = 20 this mapgen has a similar load to mapgen V7."); + gettext("Scale"); + gettext("(X,Y,Z) scale of fractal in nodes.\nActual fractal size will be 2 to 3 times larger.\nThese numbers can be made very large, the fractal does\nnot have to fit inside the world.\nIncrease these to 'zoom' into the detail of the fractal.\nDefault is for a vertically-squashed shape suitable for\nan island, set all 3 numbers equal for the raw shape."); + gettext("Offset"); + gettext("(X,Y,Z) offset of fractal from world center in units of 'scale'.\nCan be used to move a desired point to (0, 0) to create a\nsuitable spawn point, or to allow 'zooming in' on a desired\npoint by increasing 'scale'.\nThe default is tuned for a suitable spawn point for Mandelbrot\nsets with default parameters, it may need altering in other\nsituations.\nRange roughly -2 to 2. Multiply by 'scale' for offset in nodes."); + gettext("Slice w"); + gettext("W coordinate of the generated 3D slice of a 4D fractal.\nDetermines which 3D slice of the 4D shape is generated.\nAlters the shape of the fractal.\nHas no effect on 3D fractals.\nRange roughly -2 to 2."); + gettext("Julia x"); + gettext("Julia set only.\nX component of hypercomplex constant.\nAlters the shape of the fractal.\nRange roughly -2 to 2."); + gettext("Julia y"); + gettext("Julia set only.\nY component of hypercomplex constant.\nAlters the shape of the fractal.\nRange roughly -2 to 2."); + gettext("Julia z"); + gettext("Julia set only.\nZ component of hypercomplex constant.\nAlters the shape of the fractal.\nRange roughly -2 to 2."); + gettext("Julia w"); + gettext("Julia set only.\nW component of hypercomplex constant.\nAlters the shape of the fractal.\nHas no effect on 3D fractals.\nRange roughly -2 to 2."); + gettext("Noises"); + gettext("Seabed noise"); + gettext("Y-level of seabed."); + gettext("Filler depth noise"); + gettext("Variation of biome filler depth."); + gettext("Cave1 noise"); + gettext("First of two 3D noises that together define tunnels."); + gettext("Cave2 noise"); + gettext("Second of two 3D noises that together define tunnels."); + gettext("Dungeon noise"); + gettext("3D noise that determines number of dungeons per mapchunk."); + gettext("Mapgen Valleys"); + gettext("Mapgen Valleys specific flags"); + gettext("Map generation attributes specific to Mapgen Valleys.\n'altitude_chill': Reduces heat with altitude.\n'humid_rivers': Increases humidity around rivers.\n'vary_river_depth': If enabled, low humidity and high heat causes rivers\nto become shallower and occasionally dry.\n'altitude_dry': Reduces humidity with altitude."); + gettext("Altitude chill"); + gettext("The vertical distance over which heat drops by 20 if 'altitude_chill' is\nenabled. Also the vertical distance over which humidity drops by 10 if\n'altitude_dry' is enabled."); + gettext("Large cave depth"); + gettext("Depth below which you'll find large caves."); + gettext("Small cave minimum number"); + gettext("Minimum limit of random number of small caves per mapchunk."); + gettext("Small cave maximum number"); + gettext("Maximum limit of random number of small caves per mapchunk."); + gettext("Large cave minimum number"); + gettext("Minimum limit of random number of large caves per mapchunk."); + gettext("Large cave maximum number"); + gettext("Maximum limit of random number of large caves per mapchunk."); + gettext("Large cave proportion flooded"); + gettext("Proportion of large caves that contain liquid."); + gettext("Cavern upper limit"); + gettext("Depth below which you'll find giant caverns."); + gettext("Cavern taper"); + gettext("Y-distance over which caverns expand to full size."); + gettext("Cavern threshold"); + gettext("Defines full size of caverns, smaller values create larger caverns."); + gettext("River depth"); + gettext("How deep to make rivers."); + gettext("River size"); + gettext("How wide to make rivers."); + gettext("Cave width"); + gettext("Controls width of tunnels, a smaller value creates wider tunnels.\nValue >= 10.0 completely disables generation of tunnels and avoids the\nintensive noise calculations."); + gettext("Dungeon minimum Y"); + gettext("Lower Y limit of dungeons."); + gettext("Dungeon maximum Y"); + gettext("Upper Y limit of dungeons."); + gettext("Noises"); + gettext("Cave noise #1"); + gettext("First of two 3D noises that together define tunnels."); + gettext("Cave noise #2"); + gettext("Second of two 3D noises that together define tunnels."); + gettext("Filler depth"); + gettext("The depth of dirt or other biome filler node."); + gettext("Cavern noise"); + gettext("3D noise defining giant caverns."); + gettext("River noise"); + gettext("Defines large-scale river channel structure."); + gettext("Terrain height"); + gettext("Base terrain height."); + gettext("Valley depth"); + gettext("Raises terrain to make valleys around the rivers."); + gettext("Valley fill"); + gettext("Slope and fill work together to modify the heights."); + gettext("Valley profile"); + gettext("Amplifies the valleys."); + gettext("Valley slope"); + gettext("Slope and fill work together to modify the heights."); + gettext("Dungeon noise"); + gettext("3D noise that determines number of dungeons per mapchunk."); + gettext("Advanced"); + gettext("Developer Options"); + gettext("Client modding"); + gettext("Enable Lua modding support on client.\nThis support is experimental and API can change."); + gettext("Main menu script"); + gettext("Replaces the default main menu with a custom one."); + gettext("Mod Security"); + gettext("Enable mod security"); + gettext("Prevent mods from doing insecure things like running shell commands."); + gettext("Trusted mods"); + gettext("Comma-separated list of trusted mods that are allowed to access insecure\nfunctions even when mod security is on (via request_insecure_environment())."); + gettext("HTTP mods"); + gettext("Comma-separated list of mods that are allowed to access HTTP APIs, which\nallow them to upload and download data to/from the internet."); + gettext("Debugging"); + gettext("Debug log level"); + gettext("Level of logging to be written to debug.txt:\n- <nothing> (no logging)\n- none (messages with no level)\n- error\n- warning\n- action\n- info\n- verbose\n- trace"); + gettext("Debug log file size threshold"); + gettext("If the file size of debug.txt exceeds the number of megabytes specified in\nthis setting when it is opened, the file is moved to debug.txt.1,\ndeleting an older debug.txt.1 if it exists.\ndebug.txt is only moved if this setting is positive."); + gettext("Chat log level"); + gettext("Minimal level of logging to be written to chat."); + gettext("Deprecated Lua API handling"); + gettext("Handling for deprecated Lua API calls:\n- none: Do not log deprecated calls\n- log: mimic and log backtrace of deprecated call (default).\n- error: abort on usage of deprecated call (suggested for mod developers)."); + gettext("Random input"); + gettext("Enable random user input (only used for testing)."); + gettext("Mod channels"); + gettext("Enable mod channels support."); + gettext("Mod Profiler"); + gettext("Load the game profiler"); + gettext("Load the game profiler to collect game profiling data.\nProvides a /profiler command to access the compiled profile.\nUseful for mod developers and server operators."); + gettext("Default report format"); + gettext("The default format in which profiles are being saved,\nwhen calling `/profiler save [format]` without format."); + gettext("Report path"); + gettext("The file path relative to your worldpath in which profiles will be saved to."); + gettext("Entity methods"); + gettext("Instrument the methods of entities on registration."); + gettext("Active Block Modifiers"); + gettext("Instrument the action function of Active Block Modifiers on registration."); + gettext("Loading Block Modifiers"); + gettext("Instrument the action function of Loading Block Modifiers on registration."); + gettext("Chat commands"); + gettext("Instrument chat commands on registration."); + gettext("Global callbacks"); + gettext("Instrument global callback functions on registration.\n(anything you pass to a minetest.register_*() function)"); + gettext("Builtin"); + gettext("Instrument builtin.\nThis is usually only needed by core/builtin contributors"); + gettext("Profiler"); + gettext("Have the profiler instrument itself:\n* Instrument an empty function.\nThis estimates the overhead, that instrumentation is adding (+1 function call).\n* Instrument the sampler being used to update the statistics."); + gettext("Engine profiler"); + gettext("Engine profiling data print interval"); + gettext("Print the engine's profiling data in regular intervals (in seconds).\n0 = disable. Useful for developers."); + gettext("Advanced"); + gettext("IPv6"); + gettext("Enable IPv6 support (for both client and server).\nRequired for IPv6 connections to work at all."); + gettext("Ignore world errors"); + gettext("If enabled, invalid world data won't cause the server to shut down.\nOnly enable this if you know what you are doing."); + gettext("Graphics"); + gettext("Shader path"); + gettext("Path to shader directory. If no path is defined, default location will be used."); + gettext("Video driver"); + gettext("The rendering back-end.\nA restart is required after changing this.\nNote: On Android, stick with OGLES1 if unsure! App may fail to start otherwise.\nOn other platforms, OpenGL is recommended.\nShaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"); + gettext("Transparency Sorting Distance"); + gettext("Distance in nodes at which transparency depth sorting is enabled\nUse this to limit the performance impact of transparency depth sorting"); + gettext("VBO"); + gettext("Enable vertex buffer objects.\nThis should greatly improve graphics performance."); + gettext("Cloud radius"); + gettext("Radius of cloud area stated in number of 64 node cloud squares.\nValues larger than 26 will start to produce sharp cutoffs at cloud area corners."); + gettext("Desynchronize block animation"); + gettext("Whether node texture animations should be desynchronized per mapblock."); + gettext("Mesh cache"); + gettext("Enables caching of facedir rotated meshes."); + gettext("Mapblock mesh generation delay"); + gettext("Delay between mesh updates on the client in ms. Increasing this will slow\ndown the rate of mesh updates, thus reducing jitter on slower clients."); + gettext("Mapblock mesh generator's MapBlock cache size in MB"); + gettext("Size of the MapBlock cache of the mesh generator. Increasing this will\nincrease the cache hit %, reducing the data being copied from the main\nthread, thus reducing jitter."); + gettext("Minimap scan height"); + gettext("True = 256\nFalse = 128\nUsable to make minimap smoother on slower machines."); + gettext("World-aligned textures mode"); + gettext("Textures on a node may be aligned either to the node or to the world.\nThe former mode suits better things like machines, furniture, etc., while\nthe latter makes stairs and microblocks fit surroundings better.\nHowever, as this possibility is new, thus may not be used by older servers,\nthis option allows enforcing it for certain node types. Note though that\nthat is considered EXPERIMENTAL and may not work properly."); + gettext("Autoscaling mode"); + gettext("World-aligned textures may be scaled to span several nodes. However,\nthe server may not send the scale you want, especially if you use\na specially-designed texture pack; with this option, the client tries\nto determine the scale automatically basing on the texture size.\nSee also texture_min_size.\nWarning: This option is EXPERIMENTAL!"); + gettext("Font"); + gettext("Font bold by default"); + gettext("Font italic by default"); + gettext("Font shadow"); + gettext("Shadow offset (in pixels) of the default font. If 0, then shadow will not be drawn."); + gettext("Font shadow alpha"); + gettext("Opaqueness (alpha) of the shadow behind the default font, between 0 and 255."); + gettext("Font size"); + gettext("Font size of the default font where 1 unit = 1 pixel at 96 DPI"); + gettext("Font size divisible by"); + gettext("For pixel-style fonts that do not scale well, this ensures that font sizes used\nwith this font will always be divisible by this value, in pixels. For instance,\na pixel font 16 pixels tall should have this set to 16, so it will only ever be\nsized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."); + gettext("Regular font path"); + gettext("Path to the default font. Must be a TrueType font.\nThe fallback font will be used if the font cannot be loaded."); + gettext("Bold font path"); + gettext("Italic font path"); + gettext("Bold and italic font path"); + gettext("Monospace font size"); + gettext("Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"); + gettext("Monospace font size divisible by"); + gettext("For pixel-style fonts that do not scale well, this ensures that font sizes used\nwith this font will always be divisible by this value, in pixels. For instance,\na pixel font 16 pixels tall should have this set to 16, so it will only ever be\nsized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."); + gettext("Monospace font path"); + gettext("Path to the monospace font. Must be a TrueType font.\nThis font is used for e.g. the console and profiler screen."); + gettext("Bold monospace font path"); + gettext("Italic monospace font path"); + gettext("Bold and italic monospace font path"); + gettext("Fallback font path"); + gettext("Path of the fallback font. Must be a TrueType font.\nThis font will be used for certain languages or if the default font is unavailable."); + gettext("Lighting"); + gettext("Light curve low gradient"); + gettext("Gradient of light curve at minimum light level.\nControls the contrast of the lowest light levels."); + gettext("Light curve high gradient"); + gettext("Gradient of light curve at maximum light level.\nControls the contrast of the highest light levels."); + gettext("Light curve boost"); + gettext("Strength of light curve boost.\nThe 3 'boost' parameters define a range of the light\ncurve that is boosted in brightness."); + gettext("Light curve boost center"); + gettext("Center of light curve boost range.\nWhere 0.0 is minimum light level, 1.0 is maximum light level."); + gettext("Light curve boost spread"); + gettext("Spread of light curve boost range.\nControls the width of the range to be boosted.\nStandard deviation of the light curve boost Gaussian."); + gettext("Networking"); + gettext("Prometheus listener address"); + gettext("Prometheus listener address.\nIf Minetest is compiled with ENABLE_PROMETHEUS option enabled,\nenable metrics listener for Prometheus on that address.\nMetrics can be fetched on http://127.0.0.1:30000/metrics"); + gettext("Maximum size of the out chat queue"); + gettext("Maximum size of the out chat queue.\n0 to disable queueing and -1 to make the queue size unlimited."); + gettext("Mapblock unload timeout"); + gettext("Timeout for client to remove unused map data from memory, in seconds."); + gettext("Mapblock limit"); + gettext("Maximum number of mapblocks for client to be kept in memory.\nSet to -1 for unlimited amount."); + gettext("Show debug info"); + gettext("Whether to show the client debug info (has the same effect as hitting F5)."); + gettext("Maximum simultaneous block sends per client"); + gettext("Maximum number of blocks that are simultaneously sent per client.\nThe maximum total count is calculated dynamically:\nmax_total = ceil((#clients + max_users) * per_client / 4)"); + gettext("Delay in sending blocks after building"); + gettext("To reduce lag, block transfers are slowed down when a player is building something.\nThis determines how long they are slowed down after placing or removing a node."); + gettext("Max. packets per iteration"); + gettext("Maximum number of packets sent per send step, if you have a slow connection\ntry reducing it, but don't reduce it to a number below double of targeted\nclient number."); + gettext("Map Compression Level for Network Transfer"); + gettext("Compression level to use when sending mapblocks to the client.\n-1 - use default compression level\n0 - least compression, fastest\n9 - best compression, slowest"); + gettext("Server"); + gettext("Chat message format"); + gettext("Format of player chat messages. The following strings are valid placeholders:\n@name, @message, @timestamp (optional)"); + gettext("Chat command time message threshold"); + gettext("If the execution of a chat command takes longer than this specified time in\nseconds, add the time information to the chat command message"); + gettext("Shutdown message"); + gettext("A message to be displayed to all clients when the server shuts down."); + gettext("Crash message"); + gettext("A message to be displayed to all clients when the server crashes."); + gettext("Ask to reconnect after crash"); + gettext("Whether to ask clients to reconnect after a (Lua) crash.\nSet this to true if your server is set up to restart automatically."); + gettext("Server/Env Performance"); + gettext("Dedicated server step"); + gettext("Length of a server tick and the interval at which objects are generally updated over\nnetwork, stated in seconds."); + gettext("Unlimited player transfer distance"); + gettext("Whether players are shown to clients without any range limit.\nDeprecated, use the setting player_transfer_distance instead."); + gettext("Player transfer distance"); + gettext("Defines the maximal player transfer distance in blocks (0 = unlimited)."); + gettext("Active object send range"); + gettext("From how far clients know about objects, stated in mapblocks (16 nodes).\n\nSetting this larger than active_block_range will also cause the server\nto maintain active objects up to this distance in the direction the\nplayer is looking. (This can avoid mobs suddenly disappearing from view)"); + gettext("Active block range"); + gettext("The radius of the volume of blocks around every player that is subject to the\nactive block stuff, stated in mapblocks (16 nodes).\nIn active blocks objects are loaded and ABMs run.\nThis is also the minimum range in which active objects (mobs) are maintained.\nThis should be configured together with active_object_send_range_blocks."); + gettext("Max block send distance"); + gettext("From how far blocks are sent to clients, stated in mapblocks (16 nodes)."); + gettext("Maximum forceloaded blocks"); + gettext("Maximum number of forceloaded mapblocks."); + gettext("Time send interval"); + gettext("Interval of sending time of day to clients, stated in seconds."); + gettext("Map save interval"); + gettext("Interval of saving important changes in the world, stated in seconds."); + gettext("Unload unused server data"); + gettext("How long the server will wait before unloading unused mapblocks, stated in seconds.\nHigher value is smoother, but will use more RAM."); + gettext("Maximum objects per block"); + gettext("Maximum number of statically stored objects in a block."); + gettext("Active block management interval"); + gettext("Length of time between active block management cycles, stated in seconds."); + gettext("ABM interval"); + gettext("Length of time between Active Block Modifier (ABM) execution cycles, stated in seconds."); + gettext("ABM time budget"); + gettext("The time budget allowed for ABMs to execute on each step\n(as a fraction of the ABM Interval)"); + gettext("NodeTimer interval"); + gettext("Length of time between NodeTimer execution cycles, stated in seconds."); + gettext("Liquid loop max"); + gettext("Max liquids processed per step."); + gettext("Liquid queue purge time"); + gettext("The time (in seconds) that the liquids queue may grow beyond processing\ncapacity until an attempt is made to decrease its size by dumping old queue\nitems. A value of 0 disables the functionality."); + gettext("Liquid update tick"); + gettext("Liquid update interval in seconds."); + gettext("Block send optimize distance"); + gettext("At this distance the server will aggressively optimize which blocks are sent to\nclients.\nSmall values potentially improve performance a lot, at the expense of visible\nrendering glitches (some blocks will not be rendered under water and in caves,\nas well as sometimes on land).\nSetting this to a value greater than max_block_send_distance disables this\noptimization.\nStated in mapblocks (16 nodes)."); + gettext("Server side occlusion culling"); + gettext("If enabled the server will perform map block occlusion culling based on\non the eye position of the player. This can reduce the number of blocks\nsent to the client 50-80%. The client will not longer receive most invisible\nso that the utility of noclip mode is reduced."); + gettext("Mapgen"); + gettext("Chunk size"); + gettext("Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\nWARNING!: There is no benefit, and there are several dangers, in\nincreasing this value above 5.\nReducing this value increases cave and dungeon density.\nAltering this value is for special usage, leaving it unchanged is\nrecommended."); + gettext("Mapgen debug"); + gettext("Dump the mapgen debug information."); + gettext("Absolute limit of queued blocks to emerge"); + gettext("Maximum number of blocks that can be queued for loading."); + gettext("Per-player limit of queued blocks load from disk"); + gettext("Maximum number of blocks to be queued that are to be loaded from file.\nThis limit is enforced per player."); + gettext("Per-player limit of queued blocks to generate"); + gettext("Maximum number of blocks to be queued that are to be generated.\nThis limit is enforced per player."); + gettext("Number of emerge threads"); + gettext("Number of emerge threads to use.\nValue 0:\n- Automatic selection. The number of emerge threads will be\n- 'number of processors - 2', with a lower limit of 1.\nAny other value:\n- Specifies the number of emerge threads, with a lower limit of 1.\nWARNING: Increasing the number of emerge threads increases engine mapgen\nspeed, but this may harm game performance by interfering with other\nprocesses, especially in singleplayer and/or when running Lua code in\n'on_generated'. For many users the optimum setting may be '1'."); + gettext("cURL"); + gettext("cURL interactive timeout"); + gettext("Maximum time an interactive request (e.g. server list fetch) may take, stated in milliseconds."); + gettext("cURL parallel limit"); + gettext("Limits number of parallel HTTP requests. Affects:\n- Media fetch if server uses remote_media setting.\n- Serverlist download and server announcement.\n- Downloads performed by main menu (e.g. mod manager).\nOnly has an effect if compiled with cURL."); + gettext("cURL file download timeout"); + gettext("Maximum time a file download (e.g. a mod download) may take, stated in milliseconds."); + gettext("Misc"); + gettext("DPI"); + gettext("Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens."); + gettext("Display Density Scaling Factor"); + gettext("Adjust the detected display density, used for scaling UI elements."); + gettext("Enable console window"); + gettext("Windows systems only: Start Minetest with the command line window in the background.\nContains the same information as the file debug.txt (default name)."); + gettext("Max. clearobjects extra blocks"); + gettext("Number of extra blocks that can be loaded by /clearobjects at once.\nThis is a trade-off between SQLite transaction overhead and\nmemory consumption (4096=100MB, as a rule of thumb)."); + gettext("Map directory"); + gettext("World directory (everything in the world is stored here).\nNot needed if starting from the main menu."); + gettext("Synchronous SQLite"); + gettext("See https://www.sqlite.org/pragma.html#pragma_synchronous"); + gettext("Map Compression Level for Disk Storage"); + gettext("Compression level to use when saving mapblocks to disk.\n-1 - use default compression level\n0 - least compression, fastest\n9 - best compression, slowest"); + gettext("Connect to external media server"); + gettext("Enable usage of remote media server (if provided by server).\nRemote servers offer a significantly faster way to download media (e.g. textures)\nwhen connecting to the server."); + gettext("Serverlist file"); + gettext("File in client/serverlist/ that contains your favorite servers displayed in the\nMultiplayer Tab."); + gettext("Gamepads"); + gettext("Enable joysticks"); + gettext("Enable joysticks. Requires a restart to take effect"); + gettext("Joystick ID"); + gettext("The identifier of the joystick to use"); + gettext("Joystick type"); + gettext("The type of joystick"); + gettext("Joystick button repetition interval"); + gettext("The time in seconds it takes between repeated events\nwhen holding down a joystick button combination."); + gettext("Joystick dead zone"); + gettext("The dead zone of the joystick"); + gettext("Joystick frustum sensitivity"); + gettext("The sensitivity of the joystick axes for moving the\nin-game view frustum around."); + gettext("Temporary Settings"); + gettext("Texture path"); + gettext("Path to texture directory. All textures are first searched from here."); + gettext("Minimap"); + gettext("Enables minimap."); + gettext("Round minimap"); + gettext("Shape of the minimap. Enabled = round, disabled = square."); + gettext("Server address"); + gettext("Address to connect to.\nLeave this blank to start a local server.\nNote that the address field in the main menu overrides this setting."); + gettext("Remote port"); + gettext("Port to connect to (UDP).\nNote that the port field in the main menu overrides this setting."); + gettext("Default game"); + gettext("Default game when creating a new world.\nThis will be overridden when creating a world from the main menu."); + gettext("Damage"); + gettext("Enable players getting damage and dying."); + gettext("Creative"); + gettext("Enable creative mode for all players"); + gettext("Player versus player"); + gettext("Whether to allow players to damage and kill each other."); + gettext("Flying"); + gettext("Player is able to fly without being affected by gravity.\nThis requires the \"fly\" privilege on the server."); + gettext("Pitch move mode"); + gettext("If enabled, makes move directions relative to the player's pitch when flying or swimming."); + gettext("Fast movement"); + gettext("Fast movement (via the \"Aux1\" key).\nThis requires the \"fast\" privilege on the server."); + gettext("Noclip"); + gettext("If enabled together with fly mode, player is able to fly through solid nodes.\nThis requires the \"noclip\" privilege on the server."); + gettext("Continuous forward"); + gettext("Continuous forward movement, toggled by autoforward key.\nPress the autoforward key again or the backwards movement to disable."); + gettext("Formspec Default Background Opacity"); + gettext("Formspec default background opacity (between 0 and 255)."); + gettext("Formspec Default Background Color"); + gettext("Formspec default background color (R,G,B)."); + gettext("Show technical names"); + gettext("Whether to show technical names.\nAffects mods and texture packs in the Content and Select Mods menus, as well as\nsetting names in All Settings.\nControlled by the checkbox in the \"All settings\" menu."); + gettext("Sound"); + gettext("Enables the sound system.\nIf disabled, this completely disables all sounds everywhere and the in-game\nsound controls will be non-functional.\nChanging this setting requires a restart."); + gettext("Forward key"); + gettext("Key for moving the player forward.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Backward key"); + gettext("Key for moving the player backward.\nWill also disable autoforward, when active.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Left key"); + gettext("Key for moving the player left.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Right key"); + gettext("Key for moving the player right.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Jump key"); + gettext("Key for jumping.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Sneak key"); + gettext("Key for sneaking.\nAlso used for climbing down and descending in water if aux1_descends is disabled.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Dig key"); + gettext("Key for digging.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Place key"); + gettext("Key for placing.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Inventory key"); + gettext("Key for opening the inventory.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Aux1 key"); + gettext("Key for moving fast in fast mode.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Chat key"); + gettext("Key for opening the chat window.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Command key"); + gettext("Key for opening the chat window to type commands.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Command key"); + gettext("Key for opening the chat window to type local commands.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Range select key"); + gettext("Key for toggling unlimited view range.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Fly key"); + gettext("Key for toggling flying.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Pitch move key"); + gettext("Key for toggling pitch move mode.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Fast key"); + gettext("Key for toggling fast mode.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Noclip key"); + gettext("Key for toggling noclip mode.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar next key"); + gettext("Key for selecting the next item in the hotbar.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar previous key"); + gettext("Key for selecting the previous item in the hotbar.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Mute key"); + gettext("Key for muting the game.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Inc. volume key"); + gettext("Key for increasing the volume.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Dec. volume key"); + gettext("Key for decreasing the volume.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Automatic forward key"); + gettext("Key for toggling autoforward.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Cinematic mode key"); + gettext("Key for toggling cinematic mode.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Minimap key"); + gettext("Key for toggling display of minimap.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Screenshot"); + gettext("Key for taking screenshots.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Drop item key"); + gettext("Key for dropping the currently selected item.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("View zoom key"); + gettext("Key to use view zoom when possible.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 1 key"); + gettext("Key for selecting the first hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 2 key"); + gettext("Key for selecting the second hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 3 key"); + gettext("Key for selecting the third hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 4 key"); + gettext("Key for selecting the fourth hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 5 key"); + gettext("Key for selecting the fifth hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 6 key"); + gettext("Key for selecting the sixth hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 7 key"); + gettext("Key for selecting the seventh hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 8 key"); + gettext("Key for selecting the eighth hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 9 key"); + gettext("Key for selecting the ninth hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 10 key"); + gettext("Key for selecting the tenth hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 11 key"); + gettext("Key for selecting the 11th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 12 key"); + gettext("Key for selecting the 12th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 13 key"); + gettext("Key for selecting the 13th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 14 key"); + gettext("Key for selecting the 14th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 15 key"); + gettext("Key for selecting the 15th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 16 key"); + gettext("Key for selecting the 16th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 17 key"); + gettext("Key for selecting the 17th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 18 key"); + gettext("Key for selecting the 18th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 19 key"); + gettext("Key for selecting the 19th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 20 key"); + gettext("Key for selecting the 20th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 21 key"); + gettext("Key for selecting the 21st hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 22 key"); + gettext("Key for selecting the 22nd hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 23 key"); + gettext("Key for selecting the 23rd hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 24 key"); + gettext("Key for selecting the 24th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 25 key"); + gettext("Key for selecting the 25th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 26 key"); + gettext("Key for selecting the 26th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 27 key"); + gettext("Key for selecting the 27th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 28 key"); + gettext("Key for selecting the 28th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 29 key"); + gettext("Key for selecting the 29th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 30 key"); + gettext("Key for selecting the 30th hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 31 key"); + gettext("Key for selecting the 31st hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Hotbar slot 32 key"); + gettext("Key for selecting the 32nd hotbar slot.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("HUD toggle key"); + gettext("Key for toggling the display of the HUD.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Chat toggle key"); + gettext("Key for toggling the display of chat.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Large chat console key"); + gettext("Key for toggling the display of the large chat console.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Fog toggle key"); + gettext("Key for toggling the display of fog.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Camera update toggle key"); + gettext("Key for toggling the camera update. Only used for development\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Debug info toggle key"); + gettext("Key for toggling the display of debug info.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Profiler toggle key"); + gettext("Key for toggling the display of the profiler. Used for development.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("Toggle camera mode key"); + gettext("Key for switching between first- and third-person camera.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("View range increase key"); + gettext("Key for increasing the viewing range.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); + gettext("View range decrease key"); + gettext("Key for decreasing the viewing range.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3"); +} diff --git a/src/skyparams.h b/src/skyparams.h new file mode 100644 index 0000000..0706863 --- /dev/null +++ b/src/skyparams.h @@ -0,0 +1,160 @@ +/* +Minetest +Copyright (C) 2019 Jordach, Jordan Snelling <jordach.snelling@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +struct SkyColor +{ + video::SColor day_sky; + video::SColor day_horizon; + video::SColor dawn_sky; + video::SColor dawn_horizon; + video::SColor night_sky; + video::SColor night_horizon; + video::SColor indoors; +}; + +struct SkyboxParams +{ + video::SColor bgcolor; + std::string type; + std::vector<std::string> textures; + bool clouds; + SkyColor sky_color; + video::SColor fog_sun_tint; + video::SColor fog_moon_tint; + std::string fog_tint_type; +}; + +struct SunParams +{ + bool visible; + std::string texture; + std::string tonemap; + std::string sunrise; + bool sunrise_visible; + f32 scale; +}; + +struct MoonParams +{ + bool visible; + std::string texture; + std::string tonemap; + f32 scale; +}; + +struct StarParams +{ + bool visible; + u32 count; + video::SColor starcolor; + f32 scale; + f32 day_opacity; +}; + +struct CloudParams +{ + float density; + video::SColor color_bright; + video::SColor color_ambient; + float thickness; + float height; + v2f speed; +}; + +// Utility class for setting default sky, sun, moon, stars values: +class SkyboxDefaults +{ +public: + SkyboxDefaults() = delete; + + static const SkyboxParams getSkyDefaults() + { + SkyboxParams sky; + sky.bgcolor = video::SColor(255, 255, 255, 255); + sky.type = "regular"; + sky.clouds = true; + sky.sky_color = getSkyColorDefaults(); + sky.fog_sun_tint = video::SColor(255, 244, 125, 29); + sky.fog_moon_tint = video::SColorf(0.5, 0.6, 0.8, 1).toSColor(); + sky.fog_tint_type = "default"; + return sky; + } + + static const SkyColor getSkyColorDefaults() + { + SkyColor sky; + // Horizon colors + sky.day_horizon = video::SColor(255, 144, 211, 246); + sky.indoors = video::SColor(255, 100, 100, 100); + sky.dawn_horizon = video::SColor(255, 186, 193, 240); + sky.night_horizon = video::SColor(255, 64, 144, 255); + // Sky colors + sky.day_sky = video::SColor(255, 97, 181, 245); + sky.dawn_sky = video::SColor(255, 180, 186, 250); + sky.night_sky = video::SColor(255, 0, 107, 255); + return sky; + } + + static const SunParams getSunDefaults() + { + SunParams sun; + sun.visible = true; + sun.sunrise_visible = true; + sun.texture = "sun.png"; + sun.tonemap = "sun_tonemap.png"; + sun.sunrise = "sunrisebg.png"; + sun.scale = 1; + return sun; + } + + static const MoonParams getMoonDefaults() + { + MoonParams moon; + moon.visible = true; + moon.texture = "moon.png"; + moon.tonemap = "moon_tonemap.png"; + moon.scale = 1; + return moon; + } + + static const StarParams getStarDefaults() + { + StarParams stars; + stars.visible = true; + stars.count = 1000; + stars.starcolor = video::SColor(105, 235, 235, 255); + stars.scale = 1; + stars.day_opacity = 0; + return stars; + } + + static const CloudParams getCloudDefaults() + { + CloudParams clouds; + clouds.density = 0.4f; + clouds.color_bright = video::SColor(229, 240, 240, 255); + clouds.color_ambient = video::SColor(255, 0, 0, 0); + clouds.thickness = 16.0f; + clouds.height = 120; + clouds.speed = v2f(0.0f, -2.0f); + return clouds; + } +}; diff --git a/src/sound.h b/src/sound.h new file mode 100644 index 0000000..801c552 --- /dev/null +++ b/src/sound.h @@ -0,0 +1,69 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <set> +#include <string> +#include "util/serialize.h" +#include "irrlichttypes_bloated.h" + +// This class describes the basic sound information for playback. +// Positional handling is done separately. + +struct SimpleSoundSpec +{ + SimpleSoundSpec(const std::string &name = "", float gain = 1.0f, + bool loop = false, float fade = 0.0f, float pitch = 1.0f) : + name(name), gain(gain), fade(fade), pitch(pitch), loop(loop) + { + } + + bool exists() const { return !name.empty(); } + + void serialize(std::ostream &os, u16 protocol_version) const + { + os << serializeString16(name); + writeF32(os, gain); + writeF32(os, pitch); + writeF32(os, fade); + } + + void deSerialize(std::istream &is, u16 protocol_version) + { + name = deSerializeString16(is); + gain = readF32(is); + pitch = readF32(is); + fade = readF32(is); + } + + std::string name; + float gain = 1.0f; + float fade = 0.0f; + float pitch = 1.0f; + bool loop = false; +}; + + +// The order must not be changed. This is sent over the network. +enum class SoundLocation : u8 { + Local, + Position, + Object +}; diff --git a/src/staticobject.cpp b/src/staticobject.cpp new file mode 100644 index 0000000..f92995d --- /dev/null +++ b/src/staticobject.cpp @@ -0,0 +1,123 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "staticobject.h" +#include "util/serialize.h" +#include "server/serveractiveobject.h" + +StaticObject::StaticObject(const ServerActiveObject *s_obj, const v3f &pos_): + type(s_obj->getType()), + pos(pos_) +{ + s_obj->getStaticData(&data); +} + +void StaticObject::serialize(std::ostream &os) const +{ + // type + writeU8(os, type); + // pos + writeV3F1000(os, clampToF1000(pos)); + // data + os<<serializeString16(data); +} + +void StaticObject::deSerialize(std::istream &is, u8 version) +{ + // type + type = readU8(is); + // pos + pos = readV3F1000(is); + // data + data = deSerializeString16(is); +} + +void StaticObjectList::serialize(std::ostream &os) +{ + // Check for problems first + auto problematic = [] (StaticObject &obj) -> bool { + if (obj.data.size() > U16_MAX) { + errorstream << "StaticObjectList::serialize(): " + "object has excessive static data (" << obj.data.size() << + "), deleting it." << std::endl; + return true; + } + return false; + }; + for (auto it = m_stored.begin(); it != m_stored.end(); ) { + if (problematic(*it)) + it = m_stored.erase(it); + else + it++; + } + for (auto it = m_active.begin(); it != m_active.end(); ) { + if (problematic(it->second)) + it = m_active.erase(it); + else + it++; + } + + // version + u8 version = 0; + writeU8(os, version); + + // count + size_t count = m_stored.size() + m_active.size(); + // Make sure it fits into u16, else it would get truncated and cause e.g. + // issue #2610 (Invalid block data in database: unsupported NameIdMapping version). + if (count > U16_MAX) { + errorstream << "StaticObjectList::serialize(): " + << "too many objects (" << count << ") in list, " + << "not writing them to disk." << std::endl; + writeU16(os, 0); // count = 0 + return; + } + writeU16(os, count); + + for (StaticObject &s_obj : m_stored) { + s_obj.serialize(os); + } + + for (auto &i : m_active) { + StaticObject s_obj = i.second; + s_obj.serialize(os); + } +} +void StaticObjectList::deSerialize(std::istream &is) +{ + if (m_active.size()) { + errorstream << "StaticObjectList::deSerialize(): " + << "deserializing objects while " << m_active.size() + << " active objects already exist (not cleared). " + << m_stored.size() << " stored objects _were_ cleared" + << std::endl; + } + m_stored.clear(); + + // version + u8 version = readU8(is); + // count + u16 count = readU16(is); + for(u16 i = 0; i < count; i++) { + StaticObject s_obj; + s_obj.deSerialize(is, version); + m_stored.push_back(s_obj); + } +} + diff --git a/src/staticobject.h b/src/staticobject.h new file mode 100644 index 0000000..03cd23c --- /dev/null +++ b/src/staticobject.h @@ -0,0 +1,93 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +#include <string> +#include <sstream> +#include <vector> +#include <map> +#include "debug.h" + +class ServerActiveObject; + +struct StaticObject +{ + u8 type = 0; + v3f pos; + std::string data; + + StaticObject() = default; + StaticObject(const ServerActiveObject *s_obj, const v3f &pos_); + + void serialize(std::ostream &os) const; + void deSerialize(std::istream &is, u8 version); +}; + +class StaticObjectList +{ +public: + /* + Inserts an object to the container. + Id must be unique (active) or 0 (stored). + */ + void insert(u16 id, const StaticObject &obj) + { + if(id == 0) + { + m_stored.push_back(obj); + } + else + { + if(m_active.find(id) != m_active.end()) + { + dstream<<"ERROR: StaticObjectList::insert(): " + <<"id already exists"<<std::endl; + FATAL_ERROR("StaticObjectList::insert()"); + } + m_active[id] = obj; + } + } + + void remove(u16 id) + { + assert(id != 0); // Pre-condition + if(m_active.find(id) == m_active.end()) + { + warningstream<<"StaticObjectList::remove(): id="<<id + <<" not found"<<std::endl; + return; + } + m_active.erase(id); + } + + void serialize(std::ostream &os); + void deSerialize(std::istream &is); + + /* + NOTE: When an object is transformed to active, it is removed + from m_stored and inserted to m_active. + The caller directly manipulates these containers. + */ + std::vector<StaticObject> m_stored; + std::map<u16, StaticObject> m_active; + +private: +}; diff --git a/src/terminal_chat_console.cpp b/src/terminal_chat_console.cpp new file mode 100644 index 0000000..b12261c --- /dev/null +++ b/src/terminal_chat_console.cpp @@ -0,0 +1,457 @@ +/* +Minetest +Copyright (C) 2015 est31 <MTest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <inttypes.h> +#include "config.h" +#if USE_CURSES +#include "version.h" +#include "terminal_chat_console.h" +#include "porting.h" +#include "settings.h" +#include "util/numeric.h" +#include "util/string.h" +#include "chat_interface.h" + +TerminalChatConsole g_term_console; + +// include this last to avoid any conflicts +// (likes to set macros to common names, conflicting various stuff) +#if CURSES_HAVE_NCURSESW_NCURSES_H +#include <ncursesw/ncurses.h> +#elif CURSES_HAVE_NCURSESW_CURSES_H +#include <ncursesw/curses.h> +#elif CURSES_HAVE_CURSES_H +#include <curses.h> +#elif CURSES_HAVE_NCURSES_H +#include <ncurses.h> +#elif CURSES_HAVE_NCURSES_NCURSES_H +#include <ncurses/ncurses.h> +#elif CURSES_HAVE_NCURSES_CURSES_H +#include <ncurses/curses.h> +#endif + +// Some functions to make drawing etc position independent +static bool reformat_backend(ChatBackend *backend, int rows, int cols) +{ + if (rows < 2) + return false; + backend->reformat(cols, rows - 2); + return true; +} + +static void move_for_backend(int row, int col) +{ + move(row + 1, col); +} + +void TerminalChatConsole::initOfCurses() +{ + initscr(); + cbreak(); //raw(); + noecho(); + keypad(stdscr, TRUE); + nodelay(stdscr, TRUE); + timeout(100); + + // To make esc not delay up to one second. According to the internet, + // this is the value vim uses, too. + set_escdelay(25); + + getmaxyx(stdscr, m_rows, m_cols); + m_can_draw_text = reformat_backend(&m_chat_backend, m_rows, m_cols); +} + +void TerminalChatConsole::deInitOfCurses() +{ + endwin(); +} + +void *TerminalChatConsole::run() +{ + BEGIN_DEBUG_EXCEPTION_HANDLER + + std::cout << "========================" << std::endl; + std::cout << "Begin log output over terminal" + << " (no stdout/stderr backlog during that)" << std::endl; + // Make the loggers to stdout/stderr shut up. + // Go over our own loggers instead. + LogLevelMask err_mask = g_logger.removeOutput(&stderr_output); + LogLevelMask out_mask = g_logger.removeOutput(&stdout_output); + + g_logger.addOutput(&m_log_output); + + // Inform the server of our nick + m_chat_interface->command_queue.push_back( + new ChatEventNick(CET_NICK_ADD, m_nick)); + + { + // Ensures that curses is deinitialized even on an exception being thrown + CursesInitHelper helper(this); + + while (!stopRequested()) { + + int ch = getch(); + if (stopRequested()) + break; + + step(ch); + } + } + + if (m_kill_requested) + *m_kill_requested = true; + + g_logger.removeOutput(&m_log_output); + g_logger.addOutputMasked(&stderr_output, err_mask); + g_logger.addOutputMasked(&stdout_output, out_mask); + + std::cout << "End log output over terminal" + << " (no stdout/stderr backlog during that)" << std::endl; + std::cout << "========================" << std::endl; + + END_DEBUG_EXCEPTION_HANDLER + + return NULL; +} + +void TerminalChatConsole::typeChatMessage(const std::wstring &msg) +{ + // Discard empty line + if (msg.empty()) + return; + + // Send to server + m_chat_interface->command_queue.push_back( + new ChatEventChat(m_nick, msg)); + + // Print if its a command (gets eaten by server otherwise) + if (msg[0] == L'/') { + m_chat_backend.addMessage(L"", (std::wstring)L"Issued command: " + msg); + } +} + +void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) +{ + ChatPrompt &prompt = m_chat_backend.getPrompt(); + // Helpful if you want to collect key codes that aren't documented + /*if (ch != ERR) { + m_chat_backend.addMessage(L"", + (std::wstring)L"Pressed key " + utf8_to_wide( + std::string(keyname(ch)) + " (code " + itos(ch) + ")")); + complete_redraw_needed = true; + }//*/ + + // All the key codes below are compatible to xterm + // Only add new ones if you have tried them there, + // to ensure compatibility with not just xterm but the wide + // range of terminals that are compatible to xterm. + + switch (ch) { + case ERR: // no input + break; + case 27: // ESC + // Toggle ESC mode + m_esc_mode = !m_esc_mode; + break; + case KEY_PPAGE: + m_chat_backend.scrollPageUp(); + complete_redraw_needed = true; + break; + case KEY_NPAGE: + m_chat_backend.scrollPageDown(); + complete_redraw_needed = true; + break; + case KEY_ENTER: + case '\r': + case '\n': { + prompt.addToHistory(prompt.getLine()); + typeChatMessage(prompt.replace(L"")); + break; + } + case KEY_UP: + prompt.historyPrev(); + break; + case KEY_DOWN: + prompt.historyNext(); + break; + case KEY_LEFT: + // Left pressed + // move character to the left + prompt.cursorOperation( + ChatPrompt::CURSOROP_MOVE, + ChatPrompt::CURSOROP_DIR_LEFT, + ChatPrompt::CURSOROP_SCOPE_CHARACTER); + break; + case 545: + // Ctrl-Left pressed + // move word to the left + prompt.cursorOperation( + ChatPrompt::CURSOROP_MOVE, + ChatPrompt::CURSOROP_DIR_LEFT, + ChatPrompt::CURSOROP_SCOPE_WORD); + break; + case KEY_RIGHT: + // Right pressed + // move character to the right + prompt.cursorOperation( + ChatPrompt::CURSOROP_MOVE, + ChatPrompt::CURSOROP_DIR_RIGHT, + ChatPrompt::CURSOROP_SCOPE_CHARACTER); + break; + case 560: + // Ctrl-Right pressed + // move word to the right + prompt.cursorOperation( + ChatPrompt::CURSOROP_MOVE, + ChatPrompt::CURSOROP_DIR_RIGHT, + ChatPrompt::CURSOROP_SCOPE_WORD); + break; + case KEY_HOME: + // Home pressed + // move to beginning of line + prompt.cursorOperation( + ChatPrompt::CURSOROP_MOVE, + ChatPrompt::CURSOROP_DIR_LEFT, + ChatPrompt::CURSOROP_SCOPE_LINE); + break; + case KEY_END: + // End pressed + // move to end of line + prompt.cursorOperation( + ChatPrompt::CURSOROP_MOVE, + ChatPrompt::CURSOROP_DIR_RIGHT, + ChatPrompt::CURSOROP_SCOPE_LINE); + break; + case KEY_BACKSPACE: + case '\b': + case 127: + // Backspace pressed + // delete character to the left + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_LEFT, + ChatPrompt::CURSOROP_SCOPE_CHARACTER); + break; + case KEY_DC: + // Delete pressed + // delete character to the right + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_RIGHT, + ChatPrompt::CURSOROP_SCOPE_CHARACTER); + break; + case 519: + // Ctrl-Delete pressed + // delete word to the right + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_RIGHT, + ChatPrompt::CURSOROP_SCOPE_WORD); + break; + case 21: + // Ctrl-U pressed + // kill line to left end + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_LEFT, + ChatPrompt::CURSOROP_SCOPE_LINE); + break; + case 11: + // Ctrl-K pressed + // kill line to right end + prompt.cursorOperation( + ChatPrompt::CURSOROP_DELETE, + ChatPrompt::CURSOROP_DIR_RIGHT, + ChatPrompt::CURSOROP_SCOPE_LINE); + break; + case KEY_TAB: + // Tab pressed + // Nick completion + prompt.nickCompletion(m_nicks, false); + break; + default: + // Add character to the prompt, + // assuming UTF-8. + if (IS_UTF8_MULTB_START(ch)) { + m_pending_utf8_bytes.append(1, (char)ch); + m_utf8_bytes_to_wait += UTF8_MULTB_START_LEN(ch) - 1; + } else if (m_utf8_bytes_to_wait != 0) { + m_pending_utf8_bytes.append(1, (char)ch); + m_utf8_bytes_to_wait--; + if (m_utf8_bytes_to_wait == 0) { + std::wstring w = utf8_to_wide(m_pending_utf8_bytes); + m_pending_utf8_bytes = ""; + // hopefully only one char in the wstring... + for (size_t i = 0; i < w.size(); i++) { + prompt.input(w.c_str()[i]); + } + } + } else if (IS_ASCII_PRINTABLE_CHAR(ch)) { + prompt.input(ch); + } else { + // Silently ignore characters we don't handle + + //warningstream << "Pressed invalid character '" + // << keyname(ch) << "' (code " << itos(ch) << ")" << std::endl; + } + break; + } +} + +void TerminalChatConsole::step(int ch) +{ + bool complete_redraw_needed = false; + + // empty queues + while (!m_chat_interface->outgoing_queue.empty()) { + ChatEvent *evt = m_chat_interface->outgoing_queue.pop_frontNoEx(); + switch (evt->type) { + case CET_NICK_REMOVE: + m_nicks.remove(((ChatEventNick *)evt)->nick); + break; + case CET_NICK_ADD: + m_nicks.push_back(((ChatEventNick *)evt)->nick); + break; + case CET_CHAT: + complete_redraw_needed = true; + // This is only used for direct replies from commands + // or for lua's print() functionality + m_chat_backend.addMessage(L"", ((ChatEventChat *)evt)->evt_msg); + break; + case CET_TIME_INFO: + ChatEventTimeInfo *tevt = (ChatEventTimeInfo *)evt; + m_game_time = tevt->game_time; + m_time_of_day = tevt->time; + }; + delete evt; + } + while (!m_log_output.queue.empty()) { + complete_redraw_needed = true; + std::pair<LogLevel, std::string> p = m_log_output.queue.pop_frontNoEx(); + if (p.first > m_log_level) + continue; + + std::wstring error_message = utf8_to_wide(Logger::getLevelLabel(p.first)); + if (!g_settings->getBool("disable_escape_sequences")) { + error_message = std::wstring(L"\x1b(c@red)").append(error_message) + .append(L"\x1b(c@white)"); + } + m_chat_backend.addMessage(error_message, utf8_to_wide(p.second)); + } + + // handle input + if (!m_esc_mode) { + handleInput(ch, complete_redraw_needed); + } else { + switch (ch) { + case ERR: // no input + break; + case 27: // ESC + // Toggle ESC mode + m_esc_mode = !m_esc_mode; + break; + case 'L': + m_log_level--; + m_log_level = MYMAX(m_log_level, LL_NONE + 1); // LL_NONE isn't accessible + break; + case 'l': + m_log_level++; + m_log_level = MYMIN(m_log_level, LL_MAX - 1); + break; + } + } + + // was there a resize? + int xn, yn; + getmaxyx(stdscr, yn, xn); + if (xn != m_cols || yn != m_rows) { + m_cols = xn; + m_rows = yn; + m_can_draw_text = reformat_backend(&m_chat_backend, m_rows, m_cols); + complete_redraw_needed = true; + } + + // draw title + move(0, 0); + clrtoeol(); + addstr(PROJECT_NAME_C); + addstr(" "); + addstr(g_version_hash); + + u32 minutes = m_time_of_day % 1000; + u32 hours = m_time_of_day / 1000; + minutes = (float)minutes / 1000 * 60; + + if (m_game_time) + printw(" | Game %" PRIu64 " Time of day %02d:%02d ", + m_game_time, hours, minutes); + + // draw text + if (complete_redraw_needed && m_can_draw_text) + draw_text(); + + // draw prompt + if (!m_esc_mode) { + // normal prompt + ChatPrompt& prompt = m_chat_backend.getPrompt(); + std::string prompt_text = wide_to_utf8(prompt.getVisiblePortion()); + move(m_rows - 1, 0); + clrtoeol(); + addstr(prompt_text.c_str()); + // Draw cursor + s32 cursor_pos = prompt.getVisibleCursorPosition(); + if (cursor_pos >= 0) { + move(m_rows - 1, cursor_pos); + } + } else { + // esc prompt + move(m_rows - 1, 0); + clrtoeol(); + printw("[ESC] Toggle ESC mode |" + " [CTRL+C] Shut down |" + " (L) in-, (l) decrease loglevel %s", + Logger::getLevelLabel((LogLevel) m_log_level).c_str()); + } + + refresh(); +} + +void TerminalChatConsole::draw_text() +{ + ChatBuffer& buf = m_chat_backend.getConsoleBuffer(); + for (u32 row = 0; row < buf.getRows(); row++) { + move_for_backend(row, 0); + clrtoeol(); + const ChatFormattedLine& line = buf.getFormattedLine(row); + if (line.fragments.empty()) + continue; + for (const ChatFormattedFragment &fragment : line.fragments) { + addstr(wide_to_utf8(fragment.text.getString()).c_str()); + } + } +} + +void TerminalChatConsole::stopAndWaitforThread() +{ + clearKillStatus(); + stop(); + wait(); +} + +#endif diff --git a/src/terminal_chat_console.h b/src/terminal_chat_console.h new file mode 100644 index 0000000..eae7c6b --- /dev/null +++ b/src/terminal_chat_console.h @@ -0,0 +1,124 @@ +/* +Minetest +Copyright (C) 2015 est31 <MTest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "chat.h" +#include "threading/thread.h" +#include "util/container.h" +#include "log.h" +#include <sstream> + + +struct ChatInterface; + +class TermLogOutput : public ILogOutput { +public: + + void logRaw(LogLevel lev, const std::string &line) + { + queue.push_back(std::make_pair(lev, line)); + } + + virtual void log(LogLevel lev, const std::string &combined, + const std::string &time, const std::string &thread_name, + const std::string &payload_text) + { + std::ostringstream os(std::ios_base::binary); + os << time << ": [" << thread_name << "] " << payload_text; + + queue.push_back(std::make_pair(lev, os.str())); + } + + MutexedQueue<std::pair<LogLevel, std::string> > queue; +}; + +class TerminalChatConsole : public Thread { +public: + + TerminalChatConsole() : + Thread("TerminalThread") + {} + + void setup( + ChatInterface *iface, + bool *kill_requested, + const std::string &nick) + { + m_nick = nick; + m_kill_requested = kill_requested; + m_chat_interface = iface; + } + + virtual void *run(); + + // Highly required! + void clearKillStatus() { m_kill_requested = nullptr; } + + void stopAndWaitforThread(); + +private: + // these have stupid names so that nobody missclassifies them + // as curses functions. Oh, curses has stupid names too? + // Well, at least it was worth a try... + void initOfCurses(); + void deInitOfCurses(); + + void draw_text(); + + void typeChatMessage(const std::wstring &m); + + void handleInput(int ch, bool &complete_redraw_needed); + + void step(int ch); + + // Used to ensure the deinitialisation is always called. + struct CursesInitHelper { + TerminalChatConsole *cons; + CursesInitHelper(TerminalChatConsole * a_console) + : cons(a_console) + { cons->initOfCurses(); } + ~CursesInitHelper() { cons->deInitOfCurses(); } + }; + + int m_log_level = LL_ACTION; + std::string m_nick; + + u8 m_utf8_bytes_to_wait = 0; + std::string m_pending_utf8_bytes; + + std::list<std::string> m_nicks; + + int m_cols; + int m_rows; + bool m_can_draw_text; + + bool *m_kill_requested = nullptr; + ChatBackend m_chat_backend; + ChatInterface *m_chat_interface; + + TermLogOutput m_log_output; + + bool m_esc_mode = false; + + u64 m_game_time = 0; + u32 m_time_of_day = 0; +}; + +extern TerminalChatConsole g_term_console; diff --git a/src/texture_override.cpp b/src/texture_override.cpp new file mode 100644 index 0000000..effdb0e --- /dev/null +++ b/src/texture_override.cpp @@ -0,0 +1,134 @@ +/* +Minetest +Copyright (C) 2020 Hugues Ross <hugues.ross@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "texture_override.h" + +#include "log.h" +#include "util/string.h" +#include <algorithm> +#include <fstream> + +#define override_cast static_cast<override_t> + +TextureOverrideSource::TextureOverrideSource(std::string filepath) +{ + std::ifstream infile(filepath.c_str()); + std::string line; + int line_index = 0; + while (std::getline(infile, line)) { + line_index++; + + // Also trim '\r' on DOS-style files + line = trim(line); + + // Ignore empty lines and comments + if (line.empty() || line[0] == '#') + continue; + + std::vector<std::string> splitted = str_split(line, ' '); + if (splitted.size() != 3) { + warningstream << filepath << ":" << line_index + << " Syntax error in texture override \"" << line + << "\": Expected 3 arguments, got " << splitted.size() + << std::endl; + continue; + } + + TextureOverride texture_override = {}; + texture_override.id = splitted[0]; + texture_override.texture = splitted[2]; + + // Parse the target mask + std::vector<std::string> targets = str_split(splitted[1], ','); + for (const std::string &target : targets) { + if (target == "top") + texture_override.target |= override_cast(OverrideTarget::TOP); + else if (target == "bottom") + texture_override.target |= override_cast(OverrideTarget::BOTTOM); + else if (target == "left") + texture_override.target |= override_cast(OverrideTarget::LEFT); + else if (target == "right") + texture_override.target |= override_cast(OverrideTarget::RIGHT); + else if (target == "front") + texture_override.target |= override_cast(OverrideTarget::FRONT); + else if (target == "back") + texture_override.target |= override_cast(OverrideTarget::BACK); + else if (target == "inventory") + texture_override.target |= override_cast(OverrideTarget::INVENTORY); + else if (target == "wield") + texture_override.target |= override_cast(OverrideTarget::WIELD); + else if (target == "special1") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_1); + else if (target == "special2") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_2); + else if (target == "special3") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_3); + else if (target == "special4") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_4); + else if (target == "special5") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_5); + else if (target == "special6") + texture_override.target |= override_cast(OverrideTarget::SPECIAL_6); + else if (target == "sides") + texture_override.target |= override_cast(OverrideTarget::SIDES); + else if (target == "all" || target == "*") + texture_override.target |= override_cast(OverrideTarget::ALL_FACES); + else { + // Report invalid target + warningstream << filepath << ":" << line_index + << " Syntax error in texture override \"" << line + << "\": Unknown target \"" << target << "\"" + << std::endl; + } + } + + // If there are no valid targets, skip adding this override + if (texture_override.target == override_cast(OverrideTarget::INVALID)) { + continue; + } + + m_overrides.push_back(texture_override); + } +} + +//! Get all overrides that apply to item definitions +std::vector<TextureOverride> TextureOverrideSource::getItemTextureOverrides() +{ + std::vector<TextureOverride> found_overrides; + + for (const TextureOverride &texture_override : m_overrides) { + if (texture_override.hasTarget(OverrideTarget::ITEM_TARGETS)) + found_overrides.push_back(texture_override); + } + + return found_overrides; +} + +//! Get all overrides that apply to node definitions +std::vector<TextureOverride> TextureOverrideSource::getNodeTileOverrides() +{ + std::vector<TextureOverride> found_overrides; + + for (const TextureOverride &texture_override : m_overrides) { + if (texture_override.hasTarget(OverrideTarget::NODE_TARGETS)) + found_overrides.push_back(texture_override); + } + + return found_overrides; +} diff --git a/src/texture_override.h b/src/texture_override.h new file mode 100644 index 0000000..bdc95e7 --- /dev/null +++ b/src/texture_override.h @@ -0,0 +1,84 @@ +/* +Minetest +Copyright (C) 2020 Hugues Ross <hugues.ross@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include <string> +#include <vector> + +typedef u16 override_t; + +//! Bitmask enum specifying what a texture override should apply to +enum class OverrideTarget : override_t +{ + INVALID = 0, + TOP = 1 << 0, + BOTTOM = 1 << 1, + LEFT = 1 << 2, + RIGHT = 1 << 3, + FRONT = 1 << 4, + BACK = 1 << 5, + INVENTORY = 1 << 6, + WIELD = 1 << 7, + SPECIAL_1 = 1 << 8, + SPECIAL_2 = 1 << 9, + SPECIAL_3 = 1 << 10, + SPECIAL_4 = 1 << 11, + SPECIAL_5 = 1 << 12, + SPECIAL_6 = 1 << 13, + + // clang-format off + SIDES = LEFT | RIGHT | FRONT | BACK, + ALL_FACES = TOP | BOTTOM | SIDES, + ALL_SPECIAL = SPECIAL_1 | SPECIAL_2 | SPECIAL_3 | SPECIAL_4 | SPECIAL_5 | SPECIAL_6, + NODE_TARGETS = ALL_FACES | ALL_SPECIAL, + ITEM_TARGETS = INVENTORY | WIELD, + // clang-format on +}; + +struct TextureOverride +{ + std::string id; + std::string texture; + override_t target; + + // Helper function for checking if an OverrideTarget is found in + // a TextureOverride without casting + inline bool hasTarget(OverrideTarget overrideTarget) const + { + return (target & static_cast<override_t>(overrideTarget)) != 0; + } +}; + +//! Class that provides texture override information from a texture pack +class TextureOverrideSource +{ +public: + TextureOverrideSource(std::string filepath); + + //! Get all overrides that apply to item definitions + std::vector<TextureOverride> getItemTextureOverrides(); + + //! Get all overrides that apply to node definitions + std::vector<TextureOverride> getNodeTileOverrides(); + +private: + std::vector<TextureOverride> m_overrides; +}; diff --git a/src/threading/CMakeLists.txt b/src/threading/CMakeLists.txt new file mode 100644 index 0000000..8f86158 --- /dev/null +++ b/src/threading/CMakeLists.txt @@ -0,0 +1,6 @@ +set(JTHREAD_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/event.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/thread.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/semaphore.cpp + PARENT_SCOPE) + diff --git a/src/threading/event.cpp b/src/threading/event.cpp new file mode 100644 index 0000000..885e732 --- /dev/null +++ b/src/threading/event.cpp @@ -0,0 +1,44 @@ +/* +This file is a part of the JThread package, which contains some object- +oriented thread wrappers for different thread implementations. + +Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com) + +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. +*/ + +#include "threading/event.h" +#include "threading/mutex_auto_lock.h" + +void Event::wait() +{ + MutexAutoLock lock(mutex); + while (!notified) { + cv.wait(lock); + } + notified = false; +} + + +void Event::signal() +{ + MutexAutoLock lock(mutex); + notified = true; + cv.notify_one(); +} diff --git a/src/threading/event.h b/src/threading/event.h new file mode 100644 index 0000000..ac6bd51 --- /dev/null +++ b/src/threading/event.h @@ -0,0 +1,46 @@ +/* +This file is a part of the JThread package, which contains some object- +oriented thread wrappers for different thread implementations. + +Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com) + +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. +*/ + +#pragma once + +#include <condition_variable> + +/** A syncronization primitive that will wake up one waiting thread when signaled. + * Calling @c signal() multiple times before a waiting thread has had a chance + * to notice the signal will wake only one thread. Additionally, if no threads + * are waiting on the event when it is signaled, the next call to @c wait() + * will return (almost) immediately. + */ +class Event +{ +public: + void wait(); + void signal(); + +private: + std::condition_variable cv; + std::mutex mutex; + bool notified = false; +}; diff --git a/src/threading/mutex_auto_lock.h b/src/threading/mutex_auto_lock.h new file mode 100644 index 0000000..c809ff8 --- /dev/null +++ b/src/threading/mutex_auto_lock.h @@ -0,0 +1,30 @@ +/* +This file is a part of the JThread package, which contains some object- +oriented thread wrappers for different thread implementations. + +Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com) + +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. +*/ + +#pragma once + +#include <mutex> +using MutexAutoLock = std::unique_lock<std::mutex>; +using RecursiveMutexAutoLock = std::unique_lock<std::recursive_mutex>; diff --git a/src/threading/semaphore.cpp b/src/threading/semaphore.cpp new file mode 100644 index 0000000..ce22dcd --- /dev/null +++ b/src/threading/semaphore.cpp @@ -0,0 +1,167 @@ +/* +Minetest +Copyright (C) 2013 sapier <sapier AT gmx DOT net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "threading/semaphore.h" + +#include <iostream> +#include <cstdlib> +#include <cassert> + +#define UNUSED(expr) do { (void)(expr); } while (0) + +#ifdef _WIN32 + #include <climits> + #define MAX_SEMAPHORE_COUNT LONG_MAX - 1 +#else + #include <cerrno> + #include <sys/time.h> + #include <pthread.h> + #if defined(__MACH__) && defined(__APPLE__) + #include <mach/mach.h> + #include <mach/task.h> + #include <mach/semaphore.h> + #include <sys/semaphore.h> + #include <unistd.h> + + #undef sem_t + #undef sem_init + #undef sem_wait + #undef sem_post + #undef sem_destroy + #define sem_t semaphore_t + #define sem_init(s, p, c) semaphore_create(mach_task_self(), (s), 0, (c)) + #define sem_wait(s) semaphore_wait(*(s)) + #define sem_post(s) semaphore_signal(*(s)) + #define sem_destroy(s) semaphore_destroy(mach_task_self(), *(s)) + #endif +#endif + + +Semaphore::Semaphore(int val) +{ +#ifdef _WIN32 + semaphore = CreateSemaphore(NULL, val, MAX_SEMAPHORE_COUNT, NULL); +#else + int ret = sem_init(&semaphore, 0, val); + assert(!ret); + UNUSED(ret); +#endif +} + + +Semaphore::~Semaphore() +{ +#ifdef _WIN32 + CloseHandle(semaphore); +#else + int ret = sem_destroy(&semaphore); +#ifdef __ANDROID__ + // Workaround for broken bionic semaphore implementation! + assert(!ret || errno == EBUSY); +#else + assert(!ret); +#endif + UNUSED(ret); +#endif +} + + +void Semaphore::post(unsigned int num) +{ + assert(num > 0); +#ifdef _WIN32 + ReleaseSemaphore(semaphore, num, NULL); +#else + for (unsigned i = 0; i < num; i++) { + int ret = sem_post(&semaphore); + assert(!ret); + UNUSED(ret); + } +#endif +} + + +void Semaphore::wait() +{ +#ifdef _WIN32 + WaitForSingleObject(semaphore, INFINITE); +#else + int ret = sem_wait(&semaphore); + assert(!ret); + UNUSED(ret); +#endif +} + + +bool Semaphore::wait(unsigned int time_ms) +{ +#ifdef _WIN32 + unsigned int ret = WaitForSingleObject(semaphore, time_ms); + + if (ret == WAIT_OBJECT_0) { + return true; + } else { + assert(ret == WAIT_TIMEOUT); + return false; + } +#else +# if defined(__MACH__) && defined(__APPLE__) + mach_timespec_t wait_time; + wait_time.tv_sec = time_ms / 1000; + wait_time.tv_nsec = 1000000 * (time_ms % 1000); + + errno = 0; + int ret = semaphore_timedwait(semaphore, wait_time); + switch (ret) { + case KERN_OPERATION_TIMED_OUT: + errno = ETIMEDOUT; + break; + case KERN_ABORTED: + errno = EINTR; + break; + default: + if (ret) + errno = EINVAL; + } +# else + int ret; + if (time_ms > 0) { + struct timespec wait_time; + struct timeval now; + + if (gettimeofday(&now, NULL) == -1) { + std::cerr << "Semaphore::wait(ms): Unable to get time with gettimeofday!" << std::endl; + abort(); + } + + wait_time.tv_nsec = ((time_ms % 1000) * 1000 * 1000) + (now.tv_usec * 1000); + wait_time.tv_sec = (time_ms / 1000) + (wait_time.tv_nsec / (1000 * 1000 * 1000)) + now.tv_sec; + wait_time.tv_nsec %= 1000 * 1000 * 1000; + + ret = sem_timedwait(&semaphore, &wait_time); + } else { + ret = sem_trywait(&semaphore); + } +# endif + + assert(!ret || (errno == ETIMEDOUT || errno == EINTR || errno == EAGAIN)); + return !ret; +#endif +} + diff --git a/src/threading/semaphore.h b/src/threading/semaphore.h new file mode 100644 index 0000000..a8847a1 --- /dev/null +++ b/src/threading/semaphore.h @@ -0,0 +1,52 @@ +/* +Minetest +Copyright (C) 2013 sapier <sapier AT gmx DOT net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#if defined(_WIN32) +#include <windows.h> +#elif defined(__MACH__) && defined(__APPLE__) +#include <mach/semaphore.h> +#else +#include <semaphore.h> +#endif + +#include "util/basic_macros.h" + +class Semaphore +{ +public: + Semaphore(int val = 0); + ~Semaphore(); + + DISABLE_CLASS_COPY(Semaphore); + + void post(unsigned int num = 1); + void wait(); + bool wait(unsigned int time_ms); + +private: +#if defined(WIN32) + HANDLE semaphore; +#elif defined(__MACH__) && defined(__APPLE__) + semaphore_t semaphore; +#else + sem_t semaphore; +#endif +}; diff --git a/src/threading/thread.cpp b/src/threading/thread.cpp new file mode 100644 index 0000000..ef025ac --- /dev/null +++ b/src/threading/thread.cpp @@ -0,0 +1,347 @@ +/* +This file is a part of the JThread package, which contains some object- +oriented thread wrappers for different thread implementations. + +Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com) + +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. +*/ + +#include "threading/thread.h" +#include "threading/mutex_auto_lock.h" +#include "log.h" +#include "porting.h" + +// for setName +#if defined(__linux__) + #include <sys/prctl.h> +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) + #include <pthread_np.h> +#elif defined(__NetBSD__) + #include <sched.h> +#elif defined(_MSC_VER) + struct THREADNAME_INFO { + DWORD dwType; // Must be 0x1000 + LPCSTR szName; // Pointer to name (in user addr space) + DWORD dwThreadID; // Thread ID (-1=caller thread) + DWORD dwFlags; // Reserved for future use, must be zero + }; +#endif + +// for bindToProcessor +#if __FreeBSD_version >= 702106 + typedef cpuset_t cpu_set_t; +#elif defined(__sun) || defined(sun) + #include <sys/types.h> + #include <sys/processor.h> + #include <sys/procset.h> +#elif defined(_AIX) + #include <sys/processor.h> + #include <sys/thread.h> +#elif defined(__APPLE__) + #include <mach/mach_init.h> + #include <mach/thread_act.h> +#endif + + +Thread::Thread(const std::string &name) : + m_name(name), + m_request_stop(false), + m_running(false) +{ +#ifdef _AIX + m_kernel_thread_id = -1; +#endif +} + + +Thread::~Thread() +{ + // kill the thread if running + if (!m_running) { + wait(); + } else { + + m_running = false; + +#if defined(_WIN32) + // See https://msdn.microsoft.com/en-us/library/hh920601.aspx#thread__native_handle_method + TerminateThread((HANDLE) m_thread_obj->native_handle(), 0); + CloseHandle((HANDLE) m_thread_obj->native_handle()); +#else + // We need to pthread_kill instead on Android since NDKv5's pthread + // implementation is incomplete. +# ifdef __ANDROID__ + pthread_kill(getThreadHandle(), SIGKILL); +# else + pthread_cancel(getThreadHandle()); +# endif + wait(); +#endif + } + + // Make sure start finished mutex is unlocked before it's destroyed + if (m_start_finished_mutex.try_lock()) + m_start_finished_mutex.unlock(); + +} + + +bool Thread::start() +{ + MutexAutoLock lock(m_mutex); + + if (m_running) + return false; + + m_request_stop = false; + + // The mutex may already be locked if the thread is being restarted + m_start_finished_mutex.try_lock(); + + try { + m_thread_obj = new std::thread(threadProc, this); + } catch (const std::system_error &e) { + return false; + } + + while (!m_running) + sleep_ms(1); + + // Allow spawned thread to continue + m_start_finished_mutex.unlock(); + + m_joinable = true; + + return true; +} + + +bool Thread::stop() +{ + m_request_stop = true; + return true; +} + + +bool Thread::wait() +{ + MutexAutoLock lock(m_mutex); + + if (!m_joinable) + return false; + + + m_thread_obj->join(); + + delete m_thread_obj; + m_thread_obj = nullptr; + + assert(m_running == false); + m_joinable = false; + return true; +} + + + +bool Thread::getReturnValue(void **ret) +{ + if (m_running) + return false; + + *ret = m_retval; + return true; +} + + +void Thread::threadProc(Thread *thr) +{ +#ifdef _AIX + thr->m_kernel_thread_id = thread_self(); +#endif + + thr->setName(thr->m_name); + + g_logger.registerThread(thr->m_name); + thr->m_running = true; + + // Wait for the thread that started this one to finish initializing the + // thread handle so that getThreadId/getThreadHandle will work. + thr->m_start_finished_mutex.lock(); + + thr->m_retval = thr->run(); + + thr->m_running = false; + // Unlock m_start_finished_mutex to prevent data race condition on Windows. + // On Windows with VS2017 build TerminateThread is called and this mutex is not + // released. We try to unlock it from caller thread and it's refused by system. + thr->m_start_finished_mutex.unlock(); + g_logger.deregisterThread(); +} + + +void Thread::setName(const std::string &name) +{ +#if defined(__linux__) + + // It would be cleaner to do this with pthread_setname_np, + // which was added to glibc in version 2.12, but some major + // distributions are still runing 2.11 and previous versions. + prctl(PR_SET_NAME, name.c_str()); + +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) + + pthread_set_name_np(pthread_self(), name.c_str()); + +#elif defined(__NetBSD__) + + pthread_setname_np(pthread_self(), "%s", const_cast<char*>(name.c_str())); + +#elif defined(__APPLE__) + + pthread_setname_np(name.c_str()); + +#elif defined(__HAIKU__) + + rename_thread(find_thread(NULL), name.c_str()); + +#elif defined(_MSC_VER) + + // Windows itself doesn't support thread names, + // but the MSVC debugger does... + THREADNAME_INFO info; + + info.dwType = 0x1000; + info.szName = name.c_str(); + info.dwThreadID = -1; + info.dwFlags = 0; + + __try { + RaiseException(0x406D1388, 0, + sizeof(info) / sizeof(DWORD), (ULONG_PTR *)&info); + } __except (EXCEPTION_CONTINUE_EXECUTION) { + } + +#elif defined(_WIN32) || defined(__GNU__) + + // These platforms are known to not support thread names. + // Silently ignore the request. + +#else + #warning "Unrecognized platform, thread names will not be available." +#endif +} + + +unsigned int Thread::getNumberOfProcessors() +{ + return std::thread::hardware_concurrency(); +} + + +bool Thread::bindToProcessor(unsigned int proc_number) +{ +#if defined(__ANDROID__) + + return false; + +#elif _MSC_VER + + return SetThreadAffinityMask(getThreadHandle(), 1 << proc_number); + +#elif __MINGW32__ + + return SetThreadAffinityMask(pthread_gethandle(getThreadHandle()), 1 << proc_number); + +#elif __FreeBSD_version >= 702106 || defined(__linux__) || defined(__DragonFly__) + + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(proc_number, &cpuset); + + return pthread_setaffinity_np(getThreadHandle(), sizeof(cpuset), &cpuset) == 0; +#elif defined(__NetBSD__) + + cpuset_t *cpuset = cpuset_create(); + if (cpuset == NULL) + return false; + int r = pthread_setaffinity_np(getThreadHandle(), cpuset_size(cpuset), cpuset); + cpuset_destroy(cpuset); + return r == 0; +#elif defined(__sun) || defined(sun) + + return processor_bind(P_LWPID, P_MYID, proc_number, NULL) == 0 + +#elif defined(_AIX) + + return bindprocessor(BINDTHREAD, m_kernel_thread_id, proc_number) == 0; + +#elif defined(__hpux) || defined(hpux) + + pthread_spu_t answer; + + return pthread_processor_bind_np(PTHREAD_BIND_ADVISORY_NP, + &answer, proc_number, getThreadHandle()) == 0; + +#elif defined(__APPLE__) + + struct thread_affinity_policy tapol; + + thread_port_t threadport = pthread_mach_thread_np(getThreadHandle()); + tapol.affinity_tag = proc_number + 1; + return thread_policy_set(threadport, THREAD_AFFINITY_POLICY, + (thread_policy_t)&tapol, + THREAD_AFFINITY_POLICY_COUNT) == KERN_SUCCESS; + +#else + + return false; + +#endif +} + + +bool Thread::setPriority(int prio) +{ +#ifdef _MSC_VER + + return SetThreadPriority(getThreadHandle(), prio); + +#elif __MINGW32__ + + return SetThreadPriority(pthread_gethandle(getThreadHandle()), prio); + +#else + + struct sched_param sparam; + int policy; + + if (pthread_getschedparam(getThreadHandle(), &policy, &sparam) != 0) + return false; + + int min = sched_get_priority_min(policy); + int max = sched_get_priority_max(policy); + + sparam.sched_priority = min + prio * (max - min) / THREAD_PRIORITY_HIGHEST; + return pthread_setschedparam(getThreadHandle(), policy, &sparam) == 0; + +#endif +} + diff --git a/src/threading/thread.h b/src/threading/thread.h new file mode 100644 index 0000000..45fb171 --- /dev/null +++ b/src/threading/thread.h @@ -0,0 +1,160 @@ +/* +This file is a part of the JThread package, which contains some object- +oriented thread wrappers for different thread implementations. + +Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com) + +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. +*/ + +#pragma once + +#include "util/basic_macros.h" + +#include <string> +#include <atomic> +#include <thread> +#include <mutex> + +#ifdef _AIX + #include <sys/thread.h> // for tid_t +#endif + +#ifdef __HAIKU__ + #include <kernel/OS.h> +#endif + +/* + * On platforms using pthreads, these five priority classes correlate to + * even divisions between the minimum and maximum reported thread priority. + */ +#if !defined(_WIN32) + #define THREAD_PRIORITY_LOWEST 0 + #define THREAD_PRIORITY_BELOW_NORMAL 1 + #define THREAD_PRIORITY_NORMAL 2 + #define THREAD_PRIORITY_ABOVE_NORMAL 3 + #define THREAD_PRIORITY_HIGHEST 4 +#endif + + + +class Thread { +public: + Thread(const std::string &name=""); + virtual ~Thread(); + DISABLE_CLASS_COPY(Thread) + + /* + * Begins execution of a new thread at the pure virtual method Thread::run(). + * Execution of the thread is guaranteed to have started after this function + * returns. + */ + bool start(); + + /* + * Requests that the thread exit gracefully. + * Returns immediately; thread execution is guaranteed to be complete after + * a subsequent call to Thread::wait. + */ + bool stop(); + + /* + * Waits for thread to finish. + * Note: This does not stop a thread, you have to do this on your own. + * Returns false immediately if the thread is not started or has been waited + * on before. + */ + bool wait(); + + /* + * Returns true if the calling thread is this Thread object. + */ + bool isCurrentThread() { return std::this_thread::get_id() == getThreadId(); } + + bool isRunning() { return m_running; } + bool stopRequested() { return m_request_stop; } + + std::thread::id getThreadId() { return m_thread_obj->get_id(); } + + /* + * Gets the thread return value. + * Returns true if the thread has exited and the return value was available, + * or false if the thread has yet to finish. + */ + bool getReturnValue(void **ret); + + /* + * Binds (if possible, otherwise sets the affinity of) the thread to the + * specific processor specified by proc_number. + */ + bool bindToProcessor(unsigned int proc_number); + + /* + * Sets the thread priority to the specified priority. + * + * prio can be one of: THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, + * THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST. + * On Windows, any of the other priorites as defined by SetThreadPriority + * are supported as well. + * + * Note that it may be necessary to first set the threading policy or + * scheduling algorithm to one that supports thread priorities if not + * supported by default, otherwise this call will have no effect. + */ + bool setPriority(int prio); + + /* + * Sets the currently executing thread's name to where supported; useful + * for debugging. + */ + static void setName(const std::string &name); + + /* + * Returns the number of processors/cores configured and active on this machine. + */ + static unsigned int getNumberOfProcessors(); + +protected: + std::string m_name; + + virtual void *run() = 0; + +private: + std::thread::native_handle_type getThreadHandle() + { return m_thread_obj->native_handle(); } + + static void threadProc(Thread *thr); + + void *m_retval = nullptr; + bool m_joinable = false; + std::atomic<bool> m_request_stop; + std::atomic<bool> m_running; + std::mutex m_mutex; + std::mutex m_start_finished_mutex; + + std::thread *m_thread_obj = nullptr; + + +#ifdef _AIX + // For AIX, there does not exist any mapping from pthread_t to tid_t + // available to us, so we maintain one ourselves. This is set on thread start. + tid_t m_kernel_thread_id; +#endif +}; + diff --git a/src/tileanimation.cpp b/src/tileanimation.cpp new file mode 100644 index 0000000..025d27d --- /dev/null +++ b/src/tileanimation.cpp @@ -0,0 +1,116 @@ +/* +Minetest +Copyright (C) 2016 sfan5 <sfan5@live.de> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "tileanimation.h" +#include "util/serialize.h" + +void TileAnimationParams::serialize(std::ostream &os, u16 protocol_ver) const +{ + // The particle code overloads the length parameter so that negative numbers + // indicate an extra feature which old clients don't understand (crash). + // In hindsight it would have been better to use an extra parameter for this + // but we're stuck with this now. + const bool need_abs = protocol_ver < 40; + + writeU8(os, type); + if (type == TAT_VERTICAL_FRAMES) { + writeU16(os, vertical_frames.aspect_w); + writeU16(os, vertical_frames.aspect_h); + writeF32(os, need_abs ? fabs(vertical_frames.length) : vertical_frames.length); + } else if (type == TAT_SHEET_2D) { + writeU8(os, sheet_2d.frames_w); + writeU8(os, sheet_2d.frames_h); + writeF32(os, need_abs ? fabs(sheet_2d.frame_length) : sheet_2d.frame_length); + } +} + +void TileAnimationParams::deSerialize(std::istream &is, u16 protocol_ver) +{ + type = (TileAnimationType) readU8(is); + + if (type == TAT_VERTICAL_FRAMES) { + vertical_frames.aspect_w = readU16(is); + vertical_frames.aspect_h = readU16(is); + vertical_frames.length = readF32(is); + } else if (type == TAT_SHEET_2D) { + sheet_2d.frames_w = readU8(is); + sheet_2d.frames_h = readU8(is); + sheet_2d.frame_length = readF32(is); + } +} + +void TileAnimationParams::determineParams(v2u32 texture_size, int *frame_count, + int *frame_length_ms, v2u32 *frame_size) const +{ + if (type == TAT_VERTICAL_FRAMES) { + int frame_height = (float)texture_size.X / + (float)vertical_frames.aspect_w * + (float)vertical_frames.aspect_h; + int _frame_count = texture_size.Y / frame_height; + if (frame_count) + *frame_count = _frame_count; + if (frame_length_ms) + *frame_length_ms = 1000.0 * vertical_frames.length / _frame_count; + if (frame_size) + *frame_size = v2u32(texture_size.X, frame_height); + } else if (type == TAT_SHEET_2D) { + if (frame_count) + *frame_count = sheet_2d.frames_w * sheet_2d.frames_h; + if (frame_length_ms) + *frame_length_ms = 1000 * sheet_2d.frame_length; + if (frame_size) + *frame_size = v2u32(texture_size.X / sheet_2d.frames_w, texture_size.Y / sheet_2d.frames_h); + } + // caller should check for TAT_NONE +} + +void TileAnimationParams::getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const +{ + if (type == TAT_NONE) + return; + if (type == TAT_VERTICAL_FRAMES) { + int frame_count; + determineParams(texture_size, &frame_count, NULL, NULL); + os << "^[verticalframe:" << frame_count << ":" << frame; + } else if (type == TAT_SHEET_2D) { + int q, r; + q = frame / sheet_2d.frames_w; + r = frame % sheet_2d.frames_w; + os << "^[sheet:" << sheet_2d.frames_w << "x" << sheet_2d.frames_h + << ":" << r << "," << q; + } +} + +v2f TileAnimationParams::getTextureCoords(v2u32 texture_size, int frame) const +{ + v2u32 ret(0, 0); + if (type == TAT_VERTICAL_FRAMES) { + int frame_height = (float)texture_size.X / + (float)vertical_frames.aspect_w * + (float)vertical_frames.aspect_h; + ret = v2u32(0, frame_height * frame); + } else if (type == TAT_SHEET_2D) { + v2u32 frame_size; + determineParams(texture_size, NULL, NULL, &frame_size); + int q, r; + q = frame / sheet_2d.frames_w; + r = frame % sheet_2d.frames_w; + ret = v2u32(r * frame_size.X, q * frame_size.Y); + } + return v2f(ret.X / (float) texture_size.X, ret.Y / (float) texture_size.Y); +} diff --git a/src/tileanimation.h b/src/tileanimation.h new file mode 100644 index 0000000..45b9165 --- /dev/null +++ b/src/tileanimation.h @@ -0,0 +1,59 @@ +/* +Minetest +Copyright (C) 2016 sfan5 <sfan5@live.de> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <iostream> +#include "irrlichttypes_bloated.h" + +enum TileAnimationType +{ + TAT_NONE = 0, + TAT_VERTICAL_FRAMES = 1, + TAT_SHEET_2D = 2, +}; + +struct TileAnimationParams +{ + enum TileAnimationType type; + union + { + // struct { + // } none; + struct + { + int aspect_w; // width for aspect ratio + int aspect_h; // height for aspect ratio + float length; // seconds + } vertical_frames; + struct + { + int frames_w; // number of frames left-to-right + int frames_h; // number of frames top-to-bottom + float frame_length; // seconds + } sheet_2d; + }; + + void serialize(std::ostream &os, u16 protocol_ver) const; + void deSerialize(std::istream &is, u16 protocol_ver); + void determineParams(v2u32 texture_size, int *frame_count, int *frame_length_ms, + v2u32 *frame_size) const; + void getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const; + v2f getTextureCoords(v2u32 texture_size, int frame) const; +}; diff --git a/src/tool.cpp b/src/tool.cpp new file mode 100644 index 0000000..821ddf0 --- /dev/null +++ b/src/tool.cpp @@ -0,0 +1,383 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "tool.h" +#include "itemdef.h" +#include "itemgroup.h" +#include "log.h" +#include "inventory.h" +#include "exceptions.h" +#include "convert_json.h" +#include "util/serialize.h" +#include "util/numeric.h" + +void ToolGroupCap::toJson(Json::Value &object) const +{ + object["maxlevel"] = maxlevel; + object["uses"] = uses; + + Json::Value times_object; + for (auto time : times) + times_object[time.first] = time.second; + object["times"] = times_object; +} + +void ToolGroupCap::fromJson(const Json::Value &json) +{ + if (json.isObject()) { + if (json["maxlevel"].isInt()) + maxlevel = json["maxlevel"].asInt(); + if (json["uses"].isInt()) + uses = json["uses"].asInt(); + const Json::Value ×_object = json["times"]; + if (times_object.isArray()) { + Json::ArrayIndex size = times_object.size(); + for (Json::ArrayIndex i = 0; i < size; ++i) + if (times_object[i].isDouble()) + times[i] = times_object[i].asFloat(); + } + } +} + +void ToolCapabilities::serialize(std::ostream &os, u16 protocol_version) const +{ + if (protocol_version >= 38) + writeU8(os, 5); + else + writeU8(os, 4); // proto == 37 + writeF32(os, full_punch_interval); + writeS16(os, max_drop_level); + writeU32(os, groupcaps.size()); + for (const auto &groupcap : groupcaps) { + const std::string *name = &groupcap.first; + const ToolGroupCap *cap = &groupcap.second; + os << serializeString16(*name); + writeS16(os, cap->uses); + writeS16(os, cap->maxlevel); + writeU32(os, cap->times.size()); + for (const auto &time : cap->times) { + writeS16(os, time.first); + writeF32(os, time.second); + } + } + + writeU32(os, damageGroups.size()); + + for (const auto &damageGroup : damageGroups) { + os << serializeString16(damageGroup.first); + writeS16(os, damageGroup.second); + } + + if (protocol_version >= 38) + writeU16(os, rangelim(punch_attack_uses, 0, U16_MAX)); +} + +void ToolCapabilities::deSerialize(std::istream &is) +{ + int version = readU8(is); + if (version < 4) + throw SerializationError("unsupported ToolCapabilities version"); + + full_punch_interval = readF32(is); + max_drop_level = readS16(is); + groupcaps.clear(); + u32 groupcaps_size = readU32(is); + for (u32 i = 0; i < groupcaps_size; i++) { + std::string name = deSerializeString16(is); + ToolGroupCap cap; + cap.uses = readS16(is); + cap.maxlevel = readS16(is); + u32 times_size = readU32(is); + for(u32 i = 0; i < times_size; i++) { + int level = readS16(is); + float time = readF32(is); + cap.times[level] = time; + } + groupcaps[name] = cap; + } + + u32 damage_groups_size = readU32(is); + for (u32 i = 0; i < damage_groups_size; i++) { + std::string name = deSerializeString16(is); + s16 rating = readS16(is); + damageGroups[name] = rating; + } + + if (version >= 5) + punch_attack_uses = readU16(is); +} + +void ToolCapabilities::serializeJson(std::ostream &os) const +{ + Json::Value root; + root["full_punch_interval"] = full_punch_interval; + root["max_drop_level"] = max_drop_level; + root["punch_attack_uses"] = punch_attack_uses; + + Json::Value groupcaps_object; + for (const auto &groupcap : groupcaps) { + groupcap.second.toJson(groupcaps_object[groupcap.first]); + } + root["groupcaps"] = groupcaps_object; + + Json::Value damage_groups_object; + DamageGroup::const_iterator dgiter; + for (dgiter = damageGroups.begin(); dgiter != damageGroups.end(); ++dgiter) { + damage_groups_object[dgiter->first] = dgiter->second; + } + root["damage_groups"] = damage_groups_object; + + fastWriteJson(root, os); +} + +void ToolCapabilities::deserializeJson(std::istream &is) +{ + Json::Value root; + is >> root; + if (root.isObject()) { + if (root["full_punch_interval"].isDouble()) + full_punch_interval = root["full_punch_interval"].asFloat(); + if (root["max_drop_level"].isInt()) + max_drop_level = root["max_drop_level"].asInt(); + if (root["punch_attack_uses"].isInt()) + punch_attack_uses = root["punch_attack_uses"].asInt(); + + Json::Value &groupcaps_object = root["groupcaps"]; + if (groupcaps_object.isObject()) { + Json::ValueIterator gciter; + for (gciter = groupcaps_object.begin(); + gciter != groupcaps_object.end(); ++gciter) { + ToolGroupCap groupcap; + groupcap.fromJson(*gciter); + groupcaps[gciter.key().asString()] = groupcap; + } + } + + Json::Value &damage_groups_object = root["damage_groups"]; + if (damage_groups_object.isObject()) { + Json::ValueIterator dgiter; + for (dgiter = damage_groups_object.begin(); + dgiter != damage_groups_object.end(); ++dgiter) { + Json::Value &value = *dgiter; + if (value.isInt()) + damageGroups[dgiter.key().asString()] = + value.asInt(); + } + } + } +} + +u32 calculateResultWear(const u32 uses, const u16 initial_wear) +{ + if (uses == 0) { + // Trivial case: Infinite uses + return 0; + } + /* Finite uses. This is not trivial, + as the maximum wear is not neatly evenly divisible by + most possible uses numbers. For example, for 128 + uses, the calculation of wear is trivial, as + 65536 / 128 uses = 512 wear, + so the tool will get 512 wear 128 times in its lifetime. + But for a number like 130, this does not work: + 65536 / 130 uses = 504.123... wear. + Since wear must be an integer, we will get + 504*130 = 65520, which would lead to the wrong number + of uses. + + Instead, we partition the "wear range" into blocks: + A block represents a single use and can be + of two possible sizes: normal and oversized. + A normal block is equal to floor(65536 / uses). + An oversized block is a normal block plus 1. + Then we determine how many oversized and normal + blocks we need and finally, whether we add + the normal wear or the oversized wear. + + Example for 130 uses: + * Normal wear = 504 + * Number of normal blocks = 114 + * Oversized wear = 505 + * Number of oversized blocks = 16 + + If we add everything together, we get: + 114*504 + 16*505 = 65536 + */ + u32 result_wear; + u32 wear_normal = ((U16_MAX+1) / uses); + // Will be non-zero if its not evenly divisible + u16 blocks_oversize = (U16_MAX+1) % uses; + // Whether to add one extra wear point in case + // of oversized wear. + u16 wear_extra = 0; + if (blocks_oversize > 0) { + u16 blocks_normal = uses - blocks_oversize; + /* When the wear has reached this value, we + know that wear_normal has been applied + for blocks_normal times, therefore, + only oversized blocks remain. + This also implies the raw tool wear number + increases a bit faster after this point, + but this should be barely noticable by the + player. + */ + u16 wear_extra_at = blocks_normal * wear_normal; + if (initial_wear >= wear_extra_at) { + wear_extra = 1; + } + } + result_wear = wear_normal + wear_extra; + return result_wear; +} + +DigParams getDigParams(const ItemGroupList &groups, + const ToolCapabilities *tp, + const u16 initial_wear) +{ + + // Group dig_immediate defaults to fixed time and no wear + if (tp->groupcaps.find("dig_immediate") == tp->groupcaps.cend()) { + switch (itemgroup_get(groups, "dig_immediate")) { + case 2: + return DigParams(true, 0.5, 0, "dig_immediate"); + case 3: + return DigParams(true, 0, 0, "dig_immediate"); + default: + break; + } + } + + // Values to be returned (with a bit of conversion) + bool result_diggable = false; + float result_time = 0.0; + u32 result_wear = 0; + std::string result_main_group; + + int level = itemgroup_get(groups, "level"); + for (const auto &groupcap : tp->groupcaps) { + const ToolGroupCap &cap = groupcap.second; + + int leveldiff = cap.maxlevel - level; + if (leveldiff < 0) + continue; + + const std::string &groupname = groupcap.first; + float time = 0; + int rating = itemgroup_get(groups, groupname); + bool time_exists = cap.getTime(rating, &time); + if (!time_exists) + continue; + + if (leveldiff > 1) + time /= leveldiff; + if (!result_diggable || time < result_time) { + result_time = time; + result_diggable = true; + // The actual number of uses increases + // exponentially with leveldiff. + // If the levels are equal, real_uses equals cap.uses. + u32 real_uses = cap.uses * pow(3.0, leveldiff); + real_uses = MYMIN(real_uses, U16_MAX); + result_wear = calculateResultWear(real_uses, initial_wear); + result_main_group = groupname; + } + } + + return DigParams(result_diggable, result_time, result_wear, result_main_group); +} + +HitParams getHitParams(const ItemGroupList &armor_groups, + const ToolCapabilities *tp, float time_from_last_punch, + u16 initial_wear) +{ + s32 damage = 0; + float result_wear = 0.0f; + float punch_interval_multiplier = + rangelim(time_from_last_punch / tp->full_punch_interval, 0.0f, 1.0f); + + for (const auto &damageGroup : tp->damageGroups) { + s16 armor = itemgroup_get(armor_groups, damageGroup.first); + damage += damageGroup.second * punch_interval_multiplier * armor / 100.0; + } + + if (tp->punch_attack_uses > 0) { + result_wear = calculateResultWear(tp->punch_attack_uses, initial_wear); + result_wear *= punch_interval_multiplier; + } + // Keep damage in sane bounds for simplicity + damage = rangelim(damage, -U16_MAX, U16_MAX); + + u32 wear_i = (u32) result_wear; + return {damage, wear_i}; +} + +HitParams getHitParams(const ItemGroupList &armor_groups, + const ToolCapabilities *tp) +{ + return getHitParams(armor_groups, tp, 1000000); +} + +PunchDamageResult getPunchDamage( + const ItemGroupList &armor_groups, + const ToolCapabilities *toolcap, + const ItemStack *punchitem, + float time_from_last_punch, + u16 initial_wear +){ + bool do_hit = true; + { + if (do_hit && punchitem) { + if (itemgroup_get(armor_groups, "punch_operable") && + (toolcap == NULL || punchitem->name.empty())) + do_hit = false; + } + + if (do_hit) { + if(itemgroup_get(armor_groups, "immortal")) + do_hit = false; + } + } + + PunchDamageResult result; + if(do_hit) + { + HitParams hitparams = getHitParams(armor_groups, toolcap, + time_from_last_punch, + punchitem->wear); + result.did_punch = true; + result.wear = hitparams.wear; + result.damage = hitparams.hp; + } + + return result; +} + +f32 getToolRange(const ItemDefinition &def_selected, const ItemDefinition &def_hand) +{ + float max_d = def_selected.range; + float max_d_hand = def_hand.range; + + if (max_d < 0 && max_d_hand >= 0) + max_d = max_d_hand; + else if (max_d < 0) + max_d = 4.0f; + + return max_d; +} + diff --git a/src/tool.h b/src/tool.h new file mode 100644 index 0000000..c2444a8 --- /dev/null +++ b/src/tool.h @@ -0,0 +1,146 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include <string> +#include <iostream> +#include "itemgroup.h" +#include <json/json.h> + +struct ItemDefinition; + +struct ToolGroupCap +{ + std::unordered_map<int, float> times; + int maxlevel = 1; + int uses = 20; + + ToolGroupCap() = default; + + bool getTime(int rating, float *time) const + { + std::unordered_map<int, float>::const_iterator i = times.find(rating); + if (i == times.end()) { + *time = 0; + return false; + } + *time = i->second; + return true; + } + + void toJson(Json::Value &object) const; + void fromJson(const Json::Value &json); +}; + + +typedef std::unordered_map<std::string, struct ToolGroupCap> ToolGCMap; +typedef std::unordered_map<std::string, s16> DamageGroup; + +struct ToolCapabilities +{ + float full_punch_interval; + int max_drop_level; + ToolGCMap groupcaps; + DamageGroup damageGroups; + int punch_attack_uses; + + ToolCapabilities( + float full_punch_interval_ = 1.4f, + int max_drop_level_ = 1, + const ToolGCMap &groupcaps_ = ToolGCMap(), + const DamageGroup &damageGroups_ = DamageGroup(), + int punch_attack_uses_ = 0 + ): + full_punch_interval(full_punch_interval_), + max_drop_level(max_drop_level_), + groupcaps(groupcaps_), + damageGroups(damageGroups_), + punch_attack_uses(punch_attack_uses_) + {} + + void serialize(std::ostream &os, u16 version) const; + void deSerialize(std::istream &is); + void serializeJson(std::ostream &os) const; + void deserializeJson(std::istream &is); +}; + +struct DigParams +{ + bool diggable; + // Digging time in seconds + float time; + // Caused wear + u32 wear; // u32 because wear could be 65536 (single-use tool) + std::string main_group; + + DigParams(bool a_diggable = false, float a_time = 0.0f, u32 a_wear = 0, + const std::string &a_main_group = ""): + diggable(a_diggable), + time(a_time), + wear(a_wear), + main_group(a_main_group) + {} +}; + +DigParams getDigParams(const ItemGroupList &groups, + const ToolCapabilities *tp, + const u16 initial_wear = 0); + +struct HitParams +{ + s32 hp; + // Caused wear + u32 wear; // u32 because wear could be 65536 (single-use weapon) + + HitParams(s32 hp_ = 0, u32 wear_ = 0): + hp(hp_), + wear(wear_) + {} +}; + +HitParams getHitParams(const ItemGroupList &armor_groups, + const ToolCapabilities *tp, float time_from_last_punch, + u16 initial_wear = 0); + +HitParams getHitParams(const ItemGroupList &armor_groups, + const ToolCapabilities *tp); + +struct PunchDamageResult +{ + bool did_punch = false; + int damage = 0; + int wear = 0; + + PunchDamageResult() = default; +}; + +struct ItemStack; + +PunchDamageResult getPunchDamage( + const ItemGroupList &armor_groups, + const ToolCapabilities *toolcap, + const ItemStack *punchitem, + float time_from_last_punch, + u16 initial_wear = 0 +); + +u32 calculateResultWear(const u32 uses, const u16 initial_wear); +f32 getToolRange(const ItemDefinition &def_selected, const ItemDefinition &def_hand); diff --git a/src/translation.cpp b/src/translation.cpp new file mode 100644 index 0000000..eabd0ec --- /dev/null +++ b/src/translation.cpp @@ -0,0 +1,162 @@ +/* +Minetest +Copyright (C) 2017 Nore, Nathanaëlle Courant <nore@mesecons.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "translation.h" +#include "log.h" +#include "util/string.h" +#include <unordered_map> + + +#ifndef SERVER +// Client translations +Translations client_translations; +Translations *g_client_translations = &client_translations; +#endif + + +void Translations::clear() +{ + m_translations.clear(); +} + +const std::wstring &Translations::getTranslation( + const std::wstring &textdomain, const std::wstring &s) +{ + std::wstring key = textdomain + L"|" + s; + try { + return m_translations.at(key); + } catch (const std::out_of_range &) { + verbosestream << "Translations: can't find translation for string \"" + << wide_to_utf8(s) << "\" in textdomain \"" + << wide_to_utf8(textdomain) << "\"" << std::endl; + // Silence that warning in the future + m_translations[key] = s; + return s; + } +} + +void Translations::loadTranslation(const std::string &data) +{ + std::istringstream is(data); + std::wstring textdomain; + std::string line; + + while (is.good()) { + std::getline(is, line); + // Trim last character if file was using a \r\n line ending + if (line.length () > 0 && line[line.length() - 1] == '\r') + line.resize(line.length() - 1); + + if (str_starts_with(line, "# textdomain:")) { + auto parts = str_split(line, ':'); + if (parts.size() < 2) { + errorstream << "Invalid textdomain translation line \"" << line + << "\"" << std::endl; + continue; + } + textdomain = utf8_to_wide(trim(parts[1])); + } + if (line.empty() || line[0] == '#') + continue; + + std::wstring wline = utf8_to_wide(line); + if (wline.empty()) + continue; + + // Read line + // '=' marks the key-value pair, but may be escaped by an '@'. + // '\n' may also be escaped by '@'. + // All other escapes are preserved. + + size_t i = 0; + std::wostringstream word1, word2; + while (i < wline.length() && wline[i] != L'=') { + if (wline[i] == L'@') { + if (i + 1 < wline.length()) { + if (wline[i + 1] == L'=') { + word1.put(L'='); + } else if (wline[i + 1] == L'n') { + word1.put(L'\n'); + } else { + word1.put(L'@'); + word1.put(wline[i + 1]); + } + i += 2; + } else { + // End of line, go to the next one. + word1.put(L'\n'); + if (!is.good()) { + break; + } + i = 0; + std::getline(is, line); + wline = utf8_to_wide(line); + } + } else { + word1.put(wline[i]); + i++; + } + } + + if (i == wline.length()) { + errorstream << "Malformed translation line \"" << line << "\"" + << std::endl; + continue; + } + i++; + + while (i < wline.length()) { + if (wline[i] == L'@') { + if (i + 1 < wline.length()) { + if (wline[i + 1] == L'=') { + word2.put(L'='); + } else if (wline[i + 1] == L'n') { + word2.put(L'\n'); + } else { + word2.put(L'@'); + word2.put(wline[i + 1]); + } + i += 2; + } else { + // End of line, go to the next one. + word2.put(L'\n'); + if (!is.good()) { + break; + } + i = 0; + std::getline(is, line); + wline = utf8_to_wide(line); + } + } else { + word2.put(wline[i]); + i++; + } + } + + std::wstring oword1 = word1.str(), oword2 = word2.str(); + if (!oword2.empty()) { + std::wstring translation_index = textdomain + L"|"; + translation_index.append(oword1); + m_translations[translation_index] = oword2; + } else { + infostream << "Ignoring empty translation for \"" + << wide_to_utf8(oword1) << "\"" << std::endl; + } + } +} diff --git a/src/translation.h b/src/translation.h new file mode 100644 index 0000000..e3f5b21 --- /dev/null +++ b/src/translation.h @@ -0,0 +1,40 @@ +/* +Minetest +Copyright (C) 2017 Nore, Nathanaëlle Courant <nore@mesecons.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <unordered_map> +#include <string> + +class Translations; +#ifndef SERVER +extern Translations *g_client_translations; +#endif + +class Translations +{ +public: + void loadTranslation(const std::string &data); + void clear(); + const std::wstring &getTranslation( + const std::wstring &textdomain, const std::wstring &s); + +private: + std::unordered_map<std::wstring, std::wstring> m_translations; +}; diff --git a/src/unittest/CMakeLists.txt b/src/unittest/CMakeLists.txt new file mode 100644 index 0000000..84f769e --- /dev/null +++ b/src/unittest/CMakeLists.txt @@ -0,0 +1,55 @@ +set (UNITTEST_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/test.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_address.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_authdatabase.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_activeobject.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_areastore.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_ban.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_collision.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_compression.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_connection.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_filepath.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_inventory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_irrptr.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_lua.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_map.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_map_settings_manager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_mapnode.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_modchannels.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_modmetadatadatabase.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_nodedef.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_noderesolver.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_noise.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_objdef.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_profiler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_random.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_schematic.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_serialization.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_serveractiveobjectmgr.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_server_shutdown_state.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_settings.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_socket.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_servermodmanager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_threading.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_utilities.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_voxelarea.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_voxelalgorithms.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_voxelmanipulator.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_gettext.cpp + PARENT_SCOPE) + +set (UNITTEST_CLIENT_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/test_clientactiveobjectmgr.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_eventmanager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_gameui.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_keycode.cpp + PARENT_SCOPE) + +set (TEST_WORLDDIR ${CMAKE_CURRENT_SOURCE_DIR}/test_world) +set (TEST_SUBGAME_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../games/devtest) +set (TEST_MOD_PATH ${CMAKE_CURRENT_SOURCE_DIR}/test_mod) + +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/test_config.h.in" + "${PROJECT_BINARY_DIR}/test_config.h" +) diff --git a/src/unittest/test.cpp b/src/unittest/test.cpp new file mode 100644 index 0000000..af30c20 --- /dev/null +++ b/src/unittest/test.cpp @@ -0,0 +1,678 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "client/sound.h" +#include "nodedef.h" +#include "itemdef.h" +#include "gamedef.h" +#include "modchannels.h" +#include "content/mods.h" +#include "database/database-dummy.h" +#include "util/numeric.h" +#include "porting.h" + +content_t t_CONTENT_STONE; +content_t t_CONTENT_GRASS; +content_t t_CONTENT_TORCH; +content_t t_CONTENT_WATER; +content_t t_CONTENT_LAVA; +content_t t_CONTENT_BRICK; + +//////////////////////////////////////////////////////////////////////////////// + +//// +//// TestGameDef +//// + +class TestGameDef : public IGameDef { +public: + TestGameDef(); + ~TestGameDef(); + + IItemDefManager *getItemDefManager() { return m_itemdef; } + const NodeDefManager *getNodeDefManager() { return m_nodedef; } + ICraftDefManager *getCraftDefManager() { return m_craftdef; } + ITextureSource *getTextureSource() { return m_texturesrc; } + IShaderSource *getShaderSource() { return m_shadersrc; } + ISoundManager *getSoundManager() { return m_soundmgr; } + scene::ISceneManager *getSceneManager() { return m_scenemgr; } + IRollbackManager *getRollbackManager() { return m_rollbackmgr; } + EmergeManager *getEmergeManager() { return m_emergemgr; } + ModMetadataDatabase *getModStorageDatabase() { return m_mod_storage_database; } + + scene::IAnimatedMesh *getMesh(const std::string &filename) { return NULL; } + bool checkLocalPrivilege(const std::string &priv) { return false; } + u16 allocateUnknownNodeId(const std::string &name) { return 0; } + + void defineSomeNodes(); + + virtual const std::vector<ModSpec> &getMods() const + { + static std::vector<ModSpec> testmodspec; + return testmodspec; + } + virtual const ModSpec* getModSpec(const std::string &modname) const { return NULL; } + virtual bool registerModStorage(ModMetadata *meta) { return true; } + virtual void unregisterModStorage(const std::string &name) {} + bool joinModChannel(const std::string &channel); + bool leaveModChannel(const std::string &channel); + bool sendModChannelMessage(const std::string &channel, const std::string &message); + ModChannel *getModChannel(const std::string &channel) + { + return m_modchannel_mgr->getModChannel(channel); + } + +private: + IItemDefManager *m_itemdef = nullptr; + const NodeDefManager *m_nodedef = nullptr; + ICraftDefManager *m_craftdef = nullptr; + ITextureSource *m_texturesrc = nullptr; + IShaderSource *m_shadersrc = nullptr; + ISoundManager *m_soundmgr = nullptr; + scene::ISceneManager *m_scenemgr = nullptr; + IRollbackManager *m_rollbackmgr = nullptr; + EmergeManager *m_emergemgr = nullptr; + ModMetadataDatabase *m_mod_storage_database = nullptr; + std::unique_ptr<ModChannelMgr> m_modchannel_mgr; +}; + + +TestGameDef::TestGameDef() : + m_mod_storage_database(new Database_Dummy()), + m_modchannel_mgr(new ModChannelMgr()) +{ + m_itemdef = createItemDefManager(); + m_nodedef = createNodeDefManager(); + + defineSomeNodes(); +} + + +TestGameDef::~TestGameDef() +{ + delete m_itemdef; + delete m_nodedef; + delete m_mod_storage_database; +} + + +void TestGameDef::defineSomeNodes() +{ + IWritableItemDefManager *idef = (IWritableItemDefManager *)m_itemdef; + NodeDefManager *ndef = (NodeDefManager *)m_nodedef; + + ItemDefinition itemdef; + ContentFeatures f; + + //// Stone + itemdef = ItemDefinition(); + itemdef.type = ITEM_NODE; + itemdef.name = "default:stone"; + itemdef.description = "Stone"; + itemdef.groups["cracky"] = 3; + itemdef.inventory_image = "[inventorycube" + "{default_stone.png" + "{default_stone.png" + "{default_stone.png"; + f = ContentFeatures(); + f.name = itemdef.name; + for (TileDef &tiledef : f.tiledef) + tiledef.name = "default_stone.png"; + f.is_ground_content = true; + idef->registerItem(itemdef); + t_CONTENT_STONE = ndef->set(f.name, f); + + //// Grass + itemdef = ItemDefinition(); + itemdef.type = ITEM_NODE; + itemdef.name = "default:dirt_with_grass"; + itemdef.description = "Dirt with grass"; + itemdef.groups["crumbly"] = 3; + itemdef.inventory_image = "[inventorycube" + "{default_grass.png" + "{default_dirt.png&default_grass_side.png" + "{default_dirt.png&default_grass_side.png"; + f = ContentFeatures(); + f.name = itemdef.name; + f.tiledef[0].name = "default_grass.png"; + f.tiledef[1].name = "default_dirt.png"; + for(int i = 2; i < 6; i++) + f.tiledef[i].name = "default_dirt.png^default_grass_side.png"; + f.is_ground_content = true; + idef->registerItem(itemdef); + t_CONTENT_GRASS = ndef->set(f.name, f); + + //// Torch (minimal definition for lighting tests) + itemdef = ItemDefinition(); + itemdef.type = ITEM_NODE; + itemdef.name = "default:torch"; + f = ContentFeatures(); + f.name = itemdef.name; + f.param_type = CPT_LIGHT; + f.light_propagates = true; + f.sunlight_propagates = true; + f.light_source = LIGHT_MAX-1; + idef->registerItem(itemdef); + t_CONTENT_TORCH = ndef->set(f.name, f); + + //// Water + itemdef = ItemDefinition(); + itemdef.type = ITEM_NODE; + itemdef.name = "default:water"; + itemdef.description = "Water"; + itemdef.inventory_image = "[inventorycube" + "{default_water.png" + "{default_water.png" + "{default_water.png"; + f = ContentFeatures(); + f.name = itemdef.name; + f.alpha = ALPHAMODE_BLEND; + f.liquid_type = LIQUID_SOURCE; + f.liquid_viscosity = 4; + f.is_ground_content = true; + f.groups["liquids"] = 3; + for (TileDef &tiledef : f.tiledef) + tiledef.name = "default_water.png"; + idef->registerItem(itemdef); + t_CONTENT_WATER = ndef->set(f.name, f); + + //// Lava + itemdef = ItemDefinition(); + itemdef.type = ITEM_NODE; + itemdef.name = "default:lava"; + itemdef.description = "Lava"; + itemdef.inventory_image = "[inventorycube" + "{default_lava.png" + "{default_lava.png" + "{default_lava.png"; + f = ContentFeatures(); + f.name = itemdef.name; + f.alpha = ALPHAMODE_OPAQUE; + f.liquid_type = LIQUID_SOURCE; + f.liquid_viscosity = 7; + f.light_source = LIGHT_MAX-1; + f.is_ground_content = true; + f.groups["liquids"] = 3; + for (TileDef &tiledef : f.tiledef) + tiledef.name = "default_lava.png"; + idef->registerItem(itemdef); + t_CONTENT_LAVA = ndef->set(f.name, f); + + + //// Brick + itemdef = ItemDefinition(); + itemdef.type = ITEM_NODE; + itemdef.name = "default:brick"; + itemdef.description = "Brick"; + itemdef.groups["cracky"] = 3; + itemdef.inventory_image = "[inventorycube" + "{default_brick.png" + "{default_brick.png" + "{default_brick.png"; + f = ContentFeatures(); + f.name = itemdef.name; + for (TileDef &tiledef : f.tiledef) + tiledef.name = "default_brick.png"; + f.is_ground_content = true; + idef->registerItem(itemdef); + t_CONTENT_BRICK = ndef->set(f.name, f); +} + +bool TestGameDef::joinModChannel(const std::string &channel) +{ + return m_modchannel_mgr->joinChannel(channel, PEER_ID_SERVER); +} + +bool TestGameDef::leaveModChannel(const std::string &channel) +{ + return m_modchannel_mgr->leaveChannel(channel, PEER_ID_SERVER); +} + +bool TestGameDef::sendModChannelMessage(const std::string &channel, + const std::string &message) +{ + if (!m_modchannel_mgr->channelRegistered(channel)) + return false; + + return true; +} + +//// +//// run_tests +//// + +bool run_tests() +{ + u64 t1 = porting::getTimeMs(); + TestGameDef gamedef; + + g_logger.setLevelSilenced(LL_ERROR, true); + + u32 num_modules_failed = 0; + u32 num_total_tests_failed = 0; + u32 num_total_tests_run = 0; + std::vector<TestBase *> &testmods = TestManager::getTestModules(); + for (size_t i = 0; i != testmods.size(); i++) { + if (!testmods[i]->testModule(&gamedef)) + num_modules_failed++; + + num_total_tests_failed += testmods[i]->num_tests_failed; + num_total_tests_run += testmods[i]->num_tests_run; + } + + u64 tdiff = porting::getTimeMs() - t1; + + g_logger.setLevelSilenced(LL_ERROR, false); + + const char *overall_status = (num_modules_failed == 0) ? "PASSED" : "FAILED"; + + rawstream + << "++++++++++++++++++++++++++++++++++++++++" + << "++++++++++++++++++++++++++++++++++++++++" << std::endl + << "Unit Test Results: " << overall_status << std::endl + << " " << num_modules_failed << " / " << testmods.size() + << " failed modules (" << num_total_tests_failed << " / " + << num_total_tests_run << " failed individual tests)." << std::endl + << " Testing took " << tdiff << "ms total." << std::endl + << "++++++++++++++++++++++++++++++++++++++++" + << "++++++++++++++++++++++++++++++++++++++++" << std::endl; + + return num_modules_failed; +} + +//// +//// TestBase +//// + +bool TestBase::testModule(IGameDef *gamedef) +{ + rawstream << "======== Testing module " << getName() << std::endl; + u64 t1 = porting::getTimeMs(); + + + runTests(gamedef); + + u64 tdiff = porting::getTimeMs() - t1; + rawstream << "======== Module " << getName() << " " + << (num_tests_failed ? "failed" : "passed") << " (" << num_tests_failed + << " failures / " << num_tests_run << " tests) - " << tdiff + << "ms" << std::endl; + + if (!m_test_dir.empty()) + fs::RecursiveDelete(m_test_dir); + + return num_tests_failed == 0; +} + +std::string TestBase::getTestTempDirectory() +{ + if (!m_test_dir.empty()) + return m_test_dir; + + char buf[32]; + porting::mt_snprintf(buf, sizeof(buf), "%08X", myrand()); + + m_test_dir = fs::TempPath() + DIR_DELIM "mttest_" + buf; + if (!fs::CreateDir(m_test_dir)) + throw TestFailedException(); + + return m_test_dir; +} + +std::string TestBase::getTestTempFile() +{ + char buf[32]; + porting::mt_snprintf(buf, sizeof(buf), "%08X", myrand()); + + return getTestTempDirectory() + DIR_DELIM + buf + ".tmp"; +} + + +/* + NOTE: These tests became non-working then NodeContainer was removed. + These should be redone, utilizing some kind of a virtual + interface for Map (IMap would be fine). +*/ +#if 0 +struct TestMapBlock: public TestBase +{ + class TC : public NodeContainer + { + public: + + MapNode node; + bool position_valid; + std::list<v3s16> validity_exceptions; + + TC() + { + position_valid = true; + } + + virtual bool isValidPosition(v3s16 p) + { + //return position_valid ^ (p==position_valid_exception); + bool exception = false; + for(std::list<v3s16>::iterator i=validity_exceptions.begin(); + i != validity_exceptions.end(); i++) + { + if(p == *i) + { + exception = true; + break; + } + } + return exception ? !position_valid : position_valid; + } + + virtual MapNode getNode(v3s16 p) + { + if(isValidPosition(p) == false) + throw InvalidPositionException(); + return node; + } + + virtual void setNode(v3s16 p, MapNode & n) + { + if(isValidPosition(p) == false) + throw InvalidPositionException(); + }; + + virtual u16 nodeContainerId() const + { + return 666; + } + }; + + void Run() + { + TC parent; + + MapBlock b(&parent, v3s16(1,1,1)); + v3s16 relpos(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE); + + UASSERT(b.getPosRelative() == relpos); + + UASSERT(b.getBox().MinEdge.X == MAP_BLOCKSIZE); + UASSERT(b.getBox().MaxEdge.X == MAP_BLOCKSIZE*2-1); + UASSERT(b.getBox().MinEdge.Y == MAP_BLOCKSIZE); + UASSERT(b.getBox().MaxEdge.Y == MAP_BLOCKSIZE*2-1); + UASSERT(b.getBox().MinEdge.Z == MAP_BLOCKSIZE); + UASSERT(b.getBox().MaxEdge.Z == MAP_BLOCKSIZE*2-1); + + UASSERT(b.isValidPosition(v3s16(0,0,0)) == true); + UASSERT(b.isValidPosition(v3s16(-1,0,0)) == false); + UASSERT(b.isValidPosition(v3s16(-1,-142,-2341)) == false); + UASSERT(b.isValidPosition(v3s16(-124,142,2341)) == false); + UASSERT(b.isValidPosition(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1)) == true); + UASSERT(b.isValidPosition(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE,MAP_BLOCKSIZE-1)) == false); + + /* + TODO: this method should probably be removed + if the block size isn't going to be set variable + */ + /*UASSERT(b.getSizeNodes() == v3s16(MAP_BLOCKSIZE, + MAP_BLOCKSIZE, MAP_BLOCKSIZE));*/ + + // Changed flag should be initially set + UASSERT(b.getModified() == MOD_STATE_WRITE_NEEDED); + b.resetModified(); + UASSERT(b.getModified() == MOD_STATE_CLEAN); + + // All nodes should have been set to + // .d=CONTENT_IGNORE and .getLight() = 0 + for(u16 z=0; z<MAP_BLOCKSIZE; z++) + for(u16 y=0; y<MAP_BLOCKSIZE; y++) + for(u16 x=0; x<MAP_BLOCKSIZE; x++) + { + //UASSERT(b.getNode(v3s16(x,y,z)).getContent() == CONTENT_AIR); + UASSERT(b.getNode(v3s16(x,y,z)).getContent() == CONTENT_IGNORE); + UASSERT(b.getNode(v3s16(x,y,z)).getLight(LIGHTBANK_DAY) == 0); + UASSERT(b.getNode(v3s16(x,y,z)).getLight(LIGHTBANK_NIGHT) == 0); + } + + { + MapNode n(CONTENT_AIR); + for(u16 z=0; z<MAP_BLOCKSIZE; z++) + for(u16 y=0; y<MAP_BLOCKSIZE; y++) + for(u16 x=0; x<MAP_BLOCKSIZE; x++) + { + b.setNode(v3s16(x,y,z), n); + } + } + + /* + Parent fetch functions + */ + parent.position_valid = false; + parent.node.setContent(5); + + MapNode n; + + // Positions in the block should still be valid + UASSERT(b.isValidPositionParent(v3s16(0,0,0)) == true); + UASSERT(b.isValidPositionParent(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1)) == true); + n = b.getNodeParent(v3s16(0,MAP_BLOCKSIZE-1,0)); + UASSERT(n.getContent() == CONTENT_AIR); + + // ...but outside the block they should be invalid + UASSERT(b.isValidPositionParent(v3s16(-121,2341,0)) == false); + UASSERT(b.isValidPositionParent(v3s16(-1,0,0)) == false); + UASSERT(b.isValidPositionParent(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE)) == false); + + { + bool exception_thrown = false; + try{ + // This should throw an exception + MapNode n = b.getNodeParent(v3s16(0,0,-1)); + } + catch(InvalidPositionException &e) + { + exception_thrown = true; + } + UASSERT(exception_thrown); + } + + parent.position_valid = true; + // Now the positions outside should be valid + UASSERT(b.isValidPositionParent(v3s16(-121,2341,0)) == true); + UASSERT(b.isValidPositionParent(v3s16(-1,0,0)) == true); + UASSERT(b.isValidPositionParent(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE)) == true); + n = b.getNodeParent(v3s16(0,0,MAP_BLOCKSIZE)); + UASSERT(n.getContent() == 5); + + /* + Set a node + */ + v3s16 p(1,2,0); + n.setContent(4); + b.setNode(p, n); + UASSERT(b.getNode(p).getContent() == 4); + //TODO: Update to new system + /*UASSERT(b.getNodeTile(p) == 4); + UASSERT(b.getNodeTile(v3s16(-1,-1,0)) == 5);*/ + + /* + propagateSunlight() + */ + // Set lighting of all nodes to 0 + for(u16 z=0; z<MAP_BLOCKSIZE; z++){ + for(u16 y=0; y<MAP_BLOCKSIZE; y++){ + for(u16 x=0; x<MAP_BLOCKSIZE; x++){ + MapNode n = b.getNode(v3s16(x,y,z)); + n.setLight(LIGHTBANK_DAY, 0); + n.setLight(LIGHTBANK_NIGHT, 0); + b.setNode(v3s16(x,y,z), n); + } + } + } + { + /* + Check how the block handles being a lonely sky block + */ + parent.position_valid = true; + b.setIsUnderground(false); + parent.node.setContent(CONTENT_AIR); + parent.node.setLight(LIGHTBANK_DAY, LIGHT_SUN); + parent.node.setLight(LIGHTBANK_NIGHT, 0); + std::map<v3s16, bool> light_sources; + // The bottom block is invalid, because we have a shadowing node + UASSERT(b.propagateSunlight(light_sources) == false); + UASSERT(b.getNode(v3s16(1,4,0)).getLight(LIGHTBANK_DAY) == LIGHT_SUN); + UASSERT(b.getNode(v3s16(1,3,0)).getLight(LIGHTBANK_DAY) == LIGHT_SUN); + UASSERT(b.getNode(v3s16(1,2,0)).getLight(LIGHTBANK_DAY) == 0); + UASSERT(b.getNode(v3s16(1,1,0)).getLight(LIGHTBANK_DAY) == 0); + UASSERT(b.getNode(v3s16(1,0,0)).getLight(LIGHTBANK_DAY) == 0); + UASSERT(b.getNode(v3s16(1,2,3)).getLight(LIGHTBANK_DAY) == LIGHT_SUN); + UASSERT(b.getFaceLight2(1000, p, v3s16(0,1,0)) == LIGHT_SUN); + UASSERT(b.getFaceLight2(1000, p, v3s16(0,-1,0)) == 0); + UASSERT(b.getFaceLight2(0, p, v3s16(0,-1,0)) == 0); + // According to MapBlock::getFaceLight, + // The face on the z+ side should have double-diminished light + //UASSERT(b.getFaceLight(p, v3s16(0,0,1)) == diminish_light(diminish_light(LIGHT_MAX))); + // The face on the z+ side should have diminished light + UASSERT(b.getFaceLight2(1000, p, v3s16(0,0,1)) == diminish_light(LIGHT_MAX)); + } + /* + Check how the block handles being in between blocks with some non-sunlight + while being underground + */ + { + // Make neighbours to exist and set some non-sunlight to them + parent.position_valid = true; + b.setIsUnderground(true); + parent.node.setLight(LIGHTBANK_DAY, LIGHT_MAX/2); + std::map<v3s16, bool> light_sources; + // The block below should be valid because there shouldn't be + // sunlight in there either + UASSERT(b.propagateSunlight(light_sources, true) == true); + // Should not touch nodes that are not affected (that is, all of them) + //UASSERT(b.getNode(v3s16(1,2,3)).getLight() == LIGHT_SUN); + // Should set light of non-sunlighted blocks to 0. + UASSERT(b.getNode(v3s16(1,2,3)).getLight(LIGHTBANK_DAY) == 0); + } + /* + Set up a situation where: + - There is only air in this block + - There is a valid non-sunlighted block at the bottom, and + - Invalid blocks elsewhere. + - the block is not underground. + + This should result in bottom block invalidity + */ + { + b.setIsUnderground(false); + // Clear block + for(u16 z=0; z<MAP_BLOCKSIZE; z++){ + for(u16 y=0; y<MAP_BLOCKSIZE; y++){ + for(u16 x=0; x<MAP_BLOCKSIZE; x++){ + MapNode n; + n.setContent(CONTENT_AIR); + n.setLight(LIGHTBANK_DAY, 0); + b.setNode(v3s16(x,y,z), n); + } + } + } + // Make neighbours invalid + parent.position_valid = false; + // Add exceptions to the top of the bottom block + for(u16 x=0; x<MAP_BLOCKSIZE; x++) + for(u16 z=0; z<MAP_BLOCKSIZE; z++) + { + parent.validity_exceptions.push_back(v3s16(MAP_BLOCKSIZE+x, MAP_BLOCKSIZE-1, MAP_BLOCKSIZE+z)); + } + // Lighting value for the valid nodes + parent.node.setLight(LIGHTBANK_DAY, LIGHT_MAX/2); + std::map<v3s16, bool> light_sources; + // Bottom block is not valid + UASSERT(b.propagateSunlight(light_sources) == false); + } + } +}; + +struct TestMapSector: public TestBase +{ + class TC : public NodeContainer + { + public: + + MapNode node; + bool position_valid; + + TC() + { + position_valid = true; + } + + virtual bool isValidPosition(v3s16 p) + { + return position_valid; + } + + virtual MapNode getNode(v3s16 p) + { + if(position_valid == false) + throw InvalidPositionException(); + return node; + } + + virtual void setNode(v3s16 p, MapNode & n) + { + if(position_valid == false) + throw InvalidPositionException(); + }; + + virtual u16 nodeContainerId() const + { + return 666; + } + }; + + void Run() + { + TC parent; + parent.position_valid = false; + + // Create one with no heightmaps + ServerMapSector sector(&parent, v2s16(1,1)); + + UASSERT(sector.getBlockNoCreateNoEx(0) == nullptr); + UASSERT(sector.getBlockNoCreateNoEx(1) == nullptr); + + MapBlock * bref = sector.createBlankBlock(-2); + + UASSERT(sector.getBlockNoCreateNoEx(0) == nullptr); + UASSERT(sector.getBlockNoCreateNoEx(-2) == bref); + + //TODO: Check for AlreadyExistsException + + /*bool exception_thrown = false; + try{ + sector.getBlock(0); + } + catch(InvalidPositionException &e){ + exception_thrown = true; + } + UASSERT(exception_thrown);*/ + + } +}; +#endif diff --git a/src/unittest/test.h b/src/unittest/test.h new file mode 100644 index 0000000..79ea094 --- /dev/null +++ b/src/unittest/test.h @@ -0,0 +1,142 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <exception> +#include <vector> + +#include "irrlichttypes_extrabloated.h" +#include "porting.h" +#include "filesys.h" +#include "mapnode.h" + +class TestFailedException : public std::exception { +}; + +// Runs a unit test and reports results +#define TEST(fxn, ...) { \ + u64 t1 = porting::getTimeMs(); \ + try { \ + fxn(__VA_ARGS__); \ + rawstream << "[PASS] "; \ + } catch (TestFailedException &e) { \ + rawstream << "[FAIL] "; \ + num_tests_failed++; \ + } catch (std::exception &e) { \ + rawstream << "Caught unhandled exception: " << e.what() << std::endl; \ + rawstream << "[FAIL] "; \ + num_tests_failed++; \ + } \ + num_tests_run++; \ + u64 tdiff = porting::getTimeMs() - t1; \ + rawstream << #fxn << " - " << tdiff << "ms" << std::endl; \ +} + +// Asserts the specified condition is true, or fails the current unit test +#define UASSERT(x) \ + if (!(x)) { \ + rawstream << "Test assertion failed: " #x << std::endl \ + << " at " << fs::GetFilenameFromPath(__FILE__) \ + << ":" << __LINE__ << std::endl; \ + throw TestFailedException(); \ + } + +// Asserts the specified condition is true, or fails the current unit test +// and prints the format specifier fmt +#define UTEST(x, fmt, ...) \ + if (!(x)) { \ + char utest_buf[1024]; \ + snprintf(utest_buf, sizeof(utest_buf), fmt, __VA_ARGS__); \ + rawstream << "Test assertion failed: " << utest_buf << std::endl \ + << " at " << fs::GetFilenameFromPath(__FILE__) \ + << ":" << __LINE__ << std::endl; \ + throw TestFailedException(); \ + } + +// Asserts the comparison specified by CMP is true, or fails the current unit test +#define UASSERTCMP(T, CMP, actual, expected) { \ + T a = (actual); \ + T e = (expected); \ + if (!(a CMP e)) { \ + rawstream \ + << "Test assertion failed: " << #actual << " " << #CMP << " " \ + << #expected << std::endl \ + << " at " << fs::GetFilenameFromPath(__FILE__) << ":" \ + << __LINE__ << std::endl \ + << " actual : " << a << std::endl << " expected: " \ + << e << std::endl; \ + throw TestFailedException(); \ + } \ +} + +#define UASSERTEQ(T, actual, expected) UASSERTCMP(T, ==, actual, expected) + +// UASSERTs that the specified exception occurs +#define EXCEPTION_CHECK(EType, code) { \ + bool exception_thrown = false; \ + try { \ + code; \ + } catch (EType &e) { \ + exception_thrown = true; \ + } \ + UASSERT(exception_thrown); \ +} + +class IGameDef; + +class TestBase { +public: + bool testModule(IGameDef *gamedef); + std::string getTestTempDirectory(); + std::string getTestTempFile(); + + virtual void runTests(IGameDef *gamedef) = 0; + virtual const char *getName() = 0; + + u32 num_tests_failed; + u32 num_tests_run; + +private: + std::string m_test_dir; +}; + +class TestManager { +public: + static std::vector<TestBase *> &getTestModules() + { + static std::vector<TestBase *> m_modules_to_test; + return m_modules_to_test; + } + + static void registerTestModule(TestBase *module) + { + getTestModules().push_back(module); + } +}; + +// A few item and node definitions for those tests that need them +extern content_t t_CONTENT_STONE; +extern content_t t_CONTENT_GRASS; +extern content_t t_CONTENT_TORCH; +extern content_t t_CONTENT_WATER; +extern content_t t_CONTENT_LAVA; +extern content_t t_CONTENT_BRICK; + +bool run_tests(); diff --git a/src/unittest/test_activeobject.cpp b/src/unittest/test_activeobject.cpp new file mode 100644 index 0000000..84c46fd --- /dev/null +++ b/src/unittest/test_activeobject.cpp @@ -0,0 +1,60 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "activeobject.h" + +class TestActiveObject : public TestBase +{ +public: + TestActiveObject() { TestManager::registerTestModule(this); } + const char *getName() { return "TestActiveObject"; } + + void runTests(IGameDef *gamedef); + + void testAOAttributes(); +}; + +static TestActiveObject g_test_instance; + +void TestActiveObject::runTests(IGameDef *gamedef) +{ + TEST(testAOAttributes); +} + +class TestAO : public ActiveObject +{ +public: + TestAO(u16 id) : ActiveObject(id) {} + + virtual ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_TEST; } + virtual bool getCollisionBox(aabb3f *toset) const { return false; } + virtual bool getSelectionBox(aabb3f *toset) const { return false; } + virtual bool collideWithObjects() const { return false; } +}; + +void TestActiveObject::testAOAttributes() +{ + TestAO ao(44); + UASSERT(ao.getId() == 44); + + ao.setId(558); + UASSERT(ao.getId() == 558); +} diff --git a/src/unittest/test_address.cpp b/src/unittest/test_address.cpp new file mode 100644 index 0000000..f461355 --- /dev/null +++ b/src/unittest/test_address.cpp @@ -0,0 +1,67 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "log.h" +#include "settings.h" +#include "network/socket.h" + +class TestAddress : public TestBase +{ +public: + TestAddress() { TestManager::registerTestModule(this); } + + const char *getName() { return "TestAddress"; } + + void runTests(IGameDef *gamedef); + + void testIsLocalhost(); +}; + +static TestAddress g_test_instance; + +void TestAddress::runTests(IGameDef *gamedef) +{ + TEST(testIsLocalhost); +} + +void TestAddress::testIsLocalhost() +{ + // v4 + UASSERT(Address(127, 0, 0, 1, 0).isLocalhost()); + UASSERT(Address(127, 254, 12, 99, 0).isLocalhost()); + UASSERT(Address(127, 188, 255, 247, 0).isLocalhost()); + UASSERT(!Address(126, 255, 255, 255, 0).isLocalhost()); + UASSERT(!Address(128, 0, 0, 0, 0).isLocalhost()); + UASSERT(!Address(1, 0, 0, 0, 0).isLocalhost()); + UASSERT(!Address(255, 255, 255, 255, 0).isLocalhost()); + UASSERT(!Address(36, 45, 99, 158, 0).isLocalhost()); + UASSERT(!Address(172, 45, 37, 68, 0).isLocalhost()); + + // v6 + auto ipv6Bytes = std::make_unique<IPv6AddressBytes>(); + std::vector<u8> ipv6RawAddr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + memcpy(ipv6Bytes->bytes, &ipv6RawAddr[0], 16); + UASSERT(Address(ipv6Bytes.get(), 0).isLocalhost()) + + ipv6RawAddr = {16, 34, 0, 0, 0, 0, 29, 0, 0, 0, 188, 0, 0, 0, 0, 14}; + memcpy(ipv6Bytes->bytes, &ipv6RawAddr[0], 16); + UASSERT(!Address(ipv6Bytes.get(), 0).isLocalhost()) +} diff --git a/src/unittest/test_areastore.cpp b/src/unittest/test_areastore.cpp new file mode 100644 index 0000000..2af3ca9 --- /dev/null +++ b/src/unittest/test_areastore.cpp @@ -0,0 +1,173 @@ +/* +Minetest +Copyright (C) 2015 est31, <MTest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "util/areastore.h" + +class TestAreaStore : public TestBase { +public: + TestAreaStore() { TestManager::registerTestModule(this); } + const char *getName() { return "TestAreaStore"; } + + void runTests(IGameDef *gamedef); + + void genericStoreTest(AreaStore *store); + void testVectorStore(); + void testSpatialStore(); + void testSerialization(); +}; + +static TestAreaStore g_test_instance; + +void TestAreaStore::runTests(IGameDef *gamedef) +{ + TEST(testVectorStore); +#if USE_SPATIAL + TEST(testSpatialStore); +#endif + TEST(testSerialization); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestAreaStore::testVectorStore() +{ + VectorAreaStore store; + genericStoreTest(&store); +} + +void TestAreaStore::testSpatialStore() +{ +#if USE_SPATIAL + SpatialAreaStore store; + genericStoreTest(&store); +#endif +} + +void TestAreaStore::genericStoreTest(AreaStore *store) +{ + Area a(v3s16(-10, -3, 5), v3s16(0, 29, 7)); + Area b(v3s16(-5, -2, 5), v3s16(0, 28, 6)); + Area c(v3s16(-7, -3, 6), v3s16(-1, 27, 7)); + std::vector<Area *> res; + + UASSERTEQ(size_t, store->size(), 0); + store->reserve(2); // sic + store->insertArea(&a); + store->insertArea(&b); + store->insertArea(&c); + UASSERTEQ(size_t, store->size(), 3); + + store->getAreasForPos(&res, v3s16(-1, 0, 6)); + UASSERTEQ(size_t, res.size(), 3); + res.clear(); + store->getAreasForPos(&res, v3s16(0, 0, 7)); + UASSERTEQ(size_t, res.size(), 1); + res.clear(); + + store->removeArea(a.id); + + store->getAreasForPos(&res, v3s16(0, 0, 7)); + UASSERTEQ(size_t, res.size(), 0); + res.clear(); + + store->insertArea(&a); + + store->getAreasForPos(&res, v3s16(0, 0, 7)); + UASSERTEQ(size_t, res.size(), 1); + res.clear(); + + store->getAreasInArea(&res, v3s16(-10, -3, 5), v3s16(0, 29, 7), false); + UASSERTEQ(size_t, res.size(), 3); + res.clear(); + + store->getAreasInArea(&res, v3s16(-100, 0, 6), v3s16(200, 0, 6), false); + UASSERTEQ(size_t, res.size(), 0); + res.clear(); + + store->getAreasInArea(&res, v3s16(-100, 0, 6), v3s16(200, 0, 6), true); + UASSERTEQ(size_t, res.size(), 3); + res.clear(); + + store->removeArea(a.id); + store->removeArea(b.id); + store->removeArea(c.id); + + Area d(v3s16(-100, -300, -200), v3s16(-50, -200, -100)); + d.data = "Hi!"; + store->insertArea(&d); + + store->getAreasForPos(&res, v3s16(-75, -250, -150)); + UASSERTEQ(size_t, res.size(), 1); + UASSERTEQ(u16, res[0]->data.size(), 3); + UASSERT(strncmp(res[0]->data.c_str(), "Hi!", 3) == 0); + res.clear(); + + store->removeArea(d.id); +} + +void TestAreaStore::testSerialization() +{ + VectorAreaStore store; + + Area a(v3s16(-1, 0, 1), v3s16(0, 1, 2)); + a.data = "Area AA"; + store.insertArea(&a); + + Area b(v3s16(123, 456, 789), v3s16(32000, 100, 10)); + b.data = "Area BB"; + store.insertArea(&b); + + std::ostringstream os(std::ios_base::binary); + store.serialize(os); + std::string str = os.str(); + + std::string str_wanted("\x00" // Version + "\x00\x02" // Count + "\xFF\xFF\x00\x00\x00\x01" // Area A min edge + "\x00\x00\x00\x01\x00\x02" // Area A max edge + "\x00\x07" // Area A data length + "Area AA" // Area A data + "\x00\x7B\x00\x64\x00\x0A" // Area B min edge (last two swapped with max edge for sorting) + "\x7D\x00\x01\xC8\x03\x15" // Area B max edge (^) + "\x00\x07" // Area B data length + "Area BB" // Area B data + "\x00\x00\x00\x00" // ID A = 0 + "\x00\x00\x00\x01", // ID B = 1 + 1 + 2 + + (6 + 6 + 2 + 7) * 2 + // min/max edge, length, data + 2 * 4); // Area IDs + + UASSERTEQ(const std::string &, str, str_wanted); + + std::istringstream is(str, std::ios_base::binary); + store.deserialize(is); + + // deserialize() doesn't clear the store + // But existing IDs are overridden + UASSERTEQ(size_t, store.size(), 2); + + Area c(v3s16(33, -2, -6), v3s16(4, 77, -76)); + c.data = "Area CC"; + store.insertArea(&c); + + UASSERTEQ(u32, c.id, 2); +} + diff --git a/src/unittest/test_authdatabase.cpp b/src/unittest/test_authdatabase.cpp new file mode 100644 index 0000000..1e1744d --- /dev/null +++ b/src/unittest/test_authdatabase.cpp @@ -0,0 +1,296 @@ +/* +Minetest +Copyright (C) 2018 bendeutsch, Ben Deutsch <ben@bendeutsch.de> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <algorithm> +#include "database/database-files.h" +#include "database/database-sqlite3.h" +#include "util/string.h" +#include "filesys.h" + +namespace +{ +// Anonymous namespace to create classes that are only +// visible to this file +// +// These are helpers that return a *AuthDatabase and +// allow us to run the same tests on different databases and +// database acquisition strategies. + +class AuthDatabaseProvider +{ +public: + virtual ~AuthDatabaseProvider() = default; + virtual AuthDatabase *getAuthDatabase() = 0; +}; + +class FixedProvider : public AuthDatabaseProvider +{ +public: + FixedProvider(AuthDatabase *auth_db) : auth_db(auth_db){}; + virtual ~FixedProvider(){}; + virtual AuthDatabase *getAuthDatabase() { return auth_db; }; + +private: + AuthDatabase *auth_db; +}; + +class FilesProvider : public AuthDatabaseProvider +{ +public: + FilesProvider(const std::string &dir) : dir(dir){}; + virtual ~FilesProvider() { delete auth_db; }; + virtual AuthDatabase *getAuthDatabase() + { + delete auth_db; + auth_db = new AuthDatabaseFiles(dir); + return auth_db; + }; + +private: + std::string dir; + AuthDatabase *auth_db = nullptr; +}; + +class SQLite3Provider : public AuthDatabaseProvider +{ +public: + SQLite3Provider(const std::string &dir) : dir(dir){}; + virtual ~SQLite3Provider() { delete auth_db; }; + virtual AuthDatabase *getAuthDatabase() + { + delete auth_db; + auth_db = new AuthDatabaseSQLite3(dir); + return auth_db; + }; + +private: + std::string dir; + AuthDatabase *auth_db = nullptr; +}; +} + +class TestAuthDatabase : public TestBase +{ +public: + TestAuthDatabase() { TestManager::registerTestModule(this); } + const char *getName() { return "TestAuthDatabase"; } + + void runTests(IGameDef *gamedef); + void runTestsForCurrentDB(); + + void testRecallFail(); + void testCreate(); + void testRecall(); + void testChange(); + void testRecallChanged(); + void testChangePrivileges(); + void testRecallChangedPrivileges(); + void testListNames(); + void testDelete(); + +private: + AuthDatabaseProvider *auth_provider; +}; + +static TestAuthDatabase g_test_instance; + +void TestAuthDatabase::runTests(IGameDef *gamedef) +{ + // fixed directory, for persistence + thread_local const std::string test_dir = getTestTempDirectory(); + + // Each set of tests is run twice for each database type: + // one where we reuse the same AuthDatabase object (to test local caching), + // and one where we create a new AuthDatabase object for each call + // (to test actual persistence). + + rawstream << "-------- Files database (same object)" << std::endl; + + AuthDatabase *auth_db = new AuthDatabaseFiles(test_dir); + auth_provider = new FixedProvider(auth_db); + + runTestsForCurrentDB(); + + delete auth_db; + delete auth_provider; + + // reset database + fs::DeleteSingleFileOrEmptyDirectory(test_dir + DIR_DELIM + "auth.txt"); + + rawstream << "-------- Files database (new objects)" << std::endl; + + auth_provider = new FilesProvider(test_dir); + + runTestsForCurrentDB(); + + delete auth_provider; + + rawstream << "-------- SQLite3 database (same object)" << std::endl; + + auth_db = new AuthDatabaseSQLite3(test_dir); + auth_provider = new FixedProvider(auth_db); + + runTestsForCurrentDB(); + + delete auth_db; + delete auth_provider; + + // reset database + fs::DeleteSingleFileOrEmptyDirectory(test_dir + DIR_DELIM + "auth.sqlite"); + + rawstream << "-------- SQLite3 database (new objects)" << std::endl; + + auth_provider = new SQLite3Provider(test_dir); + + runTestsForCurrentDB(); + + delete auth_provider; +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestAuthDatabase::runTestsForCurrentDB() +{ + TEST(testRecallFail); + TEST(testCreate); + TEST(testRecall); + TEST(testChange); + TEST(testRecallChanged); + TEST(testChangePrivileges); + TEST(testRecallChangedPrivileges); + TEST(testListNames); + TEST(testDelete); + TEST(testRecallFail); +} + +void TestAuthDatabase::testRecallFail() +{ + AuthDatabase *auth_db = auth_provider->getAuthDatabase(); + AuthEntry authEntry; + + // no such user yet + UASSERT(!auth_db->getAuth("TestName", authEntry)); +} + +void TestAuthDatabase::testCreate() +{ + AuthDatabase *auth_db = auth_provider->getAuthDatabase(); + AuthEntry authEntry; + + authEntry.name = "TestName"; + authEntry.password = "TestPassword"; + authEntry.privileges.emplace_back("shout"); + authEntry.privileges.emplace_back("interact"); + authEntry.last_login = 1000; + UASSERT(auth_db->createAuth(authEntry)); +} + +void TestAuthDatabase::testRecall() +{ + AuthDatabase *auth_db = auth_provider->getAuthDatabase(); + AuthEntry authEntry; + + UASSERT(auth_db->getAuth("TestName", authEntry)); + UASSERTEQ(std::string, authEntry.name, "TestName"); + UASSERTEQ(std::string, authEntry.password, "TestPassword"); + // the order of privileges is unimportant + std::sort(authEntry.privileges.begin(), authEntry.privileges.end()); + UASSERTEQ(std::string, str_join(authEntry.privileges, ","), "interact,shout"); +} + +void TestAuthDatabase::testChange() +{ + AuthDatabase *auth_db = auth_provider->getAuthDatabase(); + AuthEntry authEntry; + + UASSERT(auth_db->getAuth("TestName", authEntry)); + authEntry.password = "NewPassword"; + authEntry.last_login = 1002; + UASSERT(auth_db->saveAuth(authEntry)); +} + +void TestAuthDatabase::testRecallChanged() +{ + AuthDatabase *auth_db = auth_provider->getAuthDatabase(); + AuthEntry authEntry; + + UASSERT(auth_db->getAuth("TestName", authEntry)); + UASSERTEQ(std::string, authEntry.password, "NewPassword"); + // the order of privileges is unimportant + std::sort(authEntry.privileges.begin(), authEntry.privileges.end()); + UASSERTEQ(std::string, str_join(authEntry.privileges, ","), "interact,shout"); + UASSERTEQ(u64, authEntry.last_login, 1002); +} + +void TestAuthDatabase::testChangePrivileges() +{ + AuthDatabase *auth_db = auth_provider->getAuthDatabase(); + AuthEntry authEntry; + + UASSERT(auth_db->getAuth("TestName", authEntry)); + authEntry.privileges.clear(); + authEntry.privileges.emplace_back("interact"); + authEntry.privileges.emplace_back("fly"); + authEntry.privileges.emplace_back("dig"); + UASSERT(auth_db->saveAuth(authEntry)); +} + +void TestAuthDatabase::testRecallChangedPrivileges() +{ + AuthDatabase *auth_db = auth_provider->getAuthDatabase(); + AuthEntry authEntry; + + UASSERT(auth_db->getAuth("TestName", authEntry)); + // the order of privileges is unimportant + std::sort(authEntry.privileges.begin(), authEntry.privileges.end()); + UASSERTEQ(std::string, str_join(authEntry.privileges, ","), "dig,fly,interact"); +} + +void TestAuthDatabase::testListNames() +{ + + AuthDatabase *auth_db = auth_provider->getAuthDatabase(); + std::vector<std::string> list; + + AuthEntry authEntry; + + authEntry.name = "SecondName"; + authEntry.password = "SecondPassword"; + authEntry.privileges.emplace_back("shout"); + authEntry.privileges.emplace_back("interact"); + authEntry.last_login = 1003; + auth_db->createAuth(authEntry); + + auth_db->listNames(list); + // not necessarily sorted, so sort before comparing + std::sort(list.begin(), list.end()); + UASSERTEQ(std::string, str_join(list, ","), "SecondName,TestName"); +} + +void TestAuthDatabase::testDelete() +{ + AuthDatabase *auth_db = auth_provider->getAuthDatabase(); + + UASSERT(!auth_db->deleteAuth("NoSuchName")); + UASSERT(auth_db->deleteAuth("TestName")); + // second try, expect failure + UASSERT(!auth_db->deleteAuth("TestName")); +} diff --git a/src/unittest/test_ban.cpp b/src/unittest/test_ban.cpp new file mode 100644 index 0000000..bab2b9e --- /dev/null +++ b/src/unittest/test_ban.cpp @@ -0,0 +1,170 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "ban.h" + +class TestBan : public TestBase +{ +public: + TestBan() { TestManager::registerTestModule(this); } + const char *getName() { return "TestBan"; } + + void runTests(IGameDef *gamedef); + +private: + void testCreate(); + void testAdd(); + void testRemove(); + void testModificationFlag(); + void testGetBanName(); + void testGetBanDescription(); + + void reinitTestEnv(); +}; + +static TestBan g_test_instance; + +void TestBan::runTests(IGameDef *gamedef) +{ + reinitTestEnv(); + TEST(testCreate); + + reinitTestEnv(); + TEST(testAdd); + + reinitTestEnv(); + TEST(testRemove); + + reinitTestEnv(); + TEST(testModificationFlag); + + reinitTestEnv(); + TEST(testGetBanName); + + reinitTestEnv(); + TEST(testGetBanDescription); + + // Delete leftover files + reinitTestEnv(); +} + +// This module is stateful due to disk writes, add helper to remove files +void TestBan::reinitTestEnv() +{ + fs::DeleteSingleFileOrEmptyDirectory("testbm.txt"); + fs::DeleteSingleFileOrEmptyDirectory("testbm2.txt"); +} + +void TestBan::testCreate() +{ + // test save on object removal + { + BanManager bm("testbm.txt"); + } + + UASSERT(std::ifstream("testbm.txt", std::ios::binary).is_open()); + + // test manual save + { + BanManager bm("testbm2.txt"); + bm.save(); + UASSERT(std::ifstream("testbm2.txt", std::ios::binary).is_open()); + } +} + +void TestBan::testAdd() +{ + std::string bm_test1_entry = "192.168.0.246"; + std::string bm_test1_result = "test_username"; + + BanManager bm("testbm.txt"); + bm.add(bm_test1_entry, bm_test1_result); + + UASSERT(bm.getBanName(bm_test1_entry) == bm_test1_result); +} + +void TestBan::testRemove() +{ + std::string bm_test1_entry = "192.168.0.249"; + std::string bm_test1_result = "test_username"; + + std::string bm_test2_entry = "192.168.0.250"; + std::string bm_test2_result = "test_username7"; + + BanManager bm("testbm.txt"); + + // init data + bm.add(bm_test1_entry, bm_test1_result); + bm.add(bm_test2_entry, bm_test2_result); + + // the test + bm.remove(bm_test1_entry); + UASSERT(bm.getBanName(bm_test1_entry).empty()); + + bm.remove(bm_test2_result); + UASSERT(bm.getBanName(bm_test2_result).empty()); +} + +void TestBan::testModificationFlag() +{ + BanManager bm("testbm.txt"); + bm.add("192.168.0.247", "test_username"); + UASSERT(bm.isModified()); + + bm.remove("192.168.0.247"); + UASSERT(bm.isModified()); + + // Clear the modification flag + bm.save(); + + // Test modification flag is entry was not present + bm.remove("test_username"); + UASSERT(!bm.isModified()); +} + +void TestBan::testGetBanName() +{ + std::string bm_test1_entry = "192.168.0.247"; + std::string bm_test1_result = "test_username"; + + BanManager bm("testbm.txt"); + bm.add(bm_test1_entry, bm_test1_result); + + // Test with valid entry + UASSERT(bm.getBanName(bm_test1_entry) == bm_test1_result); + + // Test with invalid entry + UASSERT(bm.getBanName("---invalid---").empty()); +} + +void TestBan::testGetBanDescription() +{ + std::string bm_test1_entry = "192.168.0.247"; + std::string bm_test1_entry2 = "test_username"; + + std::string bm_test1_result = "192.168.0.247|test_username"; + + BanManager bm("testbm.txt"); + bm.add(bm_test1_entry, bm_test1_entry2); + + UASSERT(bm.getBanDescription(bm_test1_entry) == bm_test1_result); + UASSERT(bm.getBanDescription(bm_test1_entry2) == bm_test1_result); +} diff --git a/src/unittest/test_clientactiveobjectmgr.cpp b/src/unittest/test_clientactiveobjectmgr.cpp new file mode 100644 index 0000000..2d508cf --- /dev/null +++ b/src/unittest/test_clientactiveobjectmgr.cpp @@ -0,0 +1,118 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "client/activeobjectmgr.h" +#include <algorithm> +#include "test.h" + +#include "profiler.h" + +class TestClientActiveObject : public ClientActiveObject +{ +public: + TestClientActiveObject() : ClientActiveObject(0, nullptr, nullptr) {} + ~TestClientActiveObject() = default; + ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_TEST; } + virtual void addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr) {} +}; + +class TestClientActiveObjectMgr : public TestBase +{ +public: + TestClientActiveObjectMgr() { TestManager::registerTestModule(this); } + const char *getName() { return "TestClientActiveObjectMgr"; } + + void runTests(IGameDef *gamedef); + + void testFreeID(); + void testRegisterObject(); + void testRemoveObject(); +}; + +static TestClientActiveObjectMgr g_test_instance; + +void TestClientActiveObjectMgr::runTests(IGameDef *gamedef) +{ + TEST(testFreeID); + TEST(testRegisterObject) + TEST(testRemoveObject) +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestClientActiveObjectMgr::testFreeID() +{ + client::ActiveObjectMgr caomgr; + std::vector<u16> aoids; + + u16 aoid = caomgr.getFreeId(); + // Ensure it's not the same id + UASSERT(caomgr.getFreeId() != aoid); + + aoids.push_back(aoid); + + // Register basic objects, ensure we never found + for (u8 i = 0; i < UINT8_MAX; i++) { + // Register an object + auto tcao = new TestClientActiveObject(); + caomgr.registerObject(tcao); + aoids.push_back(tcao->getId()); + + // Ensure next id is not in registered list + UASSERT(std::find(aoids.begin(), aoids.end(), caomgr.getFreeId()) == + aoids.end()); + } + + caomgr.clear(); +} + +void TestClientActiveObjectMgr::testRegisterObject() +{ + client::ActiveObjectMgr caomgr; + auto tcao = new TestClientActiveObject(); + UASSERT(caomgr.registerObject(tcao)); + + u16 id = tcao->getId(); + + auto tcaoToCompare = caomgr.getActiveObject(id); + UASSERT(tcaoToCompare->getId() == id); + UASSERT(tcaoToCompare == tcao); + + tcao = new TestClientActiveObject(); + UASSERT(caomgr.registerObject(tcao)); + UASSERT(caomgr.getActiveObject(tcao->getId()) == tcao); + UASSERT(caomgr.getActiveObject(tcao->getId()) != tcaoToCompare); + + caomgr.clear(); +} + +void TestClientActiveObjectMgr::testRemoveObject() +{ + client::ActiveObjectMgr caomgr; + auto tcao = new TestClientActiveObject(); + UASSERT(caomgr.registerObject(tcao)); + + u16 id = tcao->getId(); + UASSERT(caomgr.getActiveObject(id) != nullptr) + + caomgr.removeObject(tcao->getId()); + UASSERT(caomgr.getActiveObject(id) == nullptr) + + caomgr.clear(); +} diff --git a/src/unittest/test_collision.cpp b/src/unittest/test_collision.cpp new file mode 100644 index 0000000..2f39c24 --- /dev/null +++ b/src/unittest/test_collision.cpp @@ -0,0 +1,180 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "collision.h" + +class TestCollision : public TestBase { +public: + TestCollision() { TestManager::registerTestModule(this); } + const char *getName() { return "TestCollision"; } + + void runTests(IGameDef *gamedef); + + void testAxisAlignedCollision(); +}; + +static TestCollision g_test_instance; + +void TestCollision::runTests(IGameDef *gamedef) +{ + TEST(testAxisAlignedCollision); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestCollision::testAxisAlignedCollision() +{ + for (s16 bx = -3; bx <= 3; bx++) + for (s16 by = -3; by <= 3; by++) + for (s16 bz = -3; bz <= 3; bz++) { + // X- + { + aabb3f s(bx, by, bz, bx+1, by+1, bz+1); + aabb3f m(bx-2, by, bz, bx-1, by+1, bz+1); + v3f v(1, 0, 0); + f32 dtime = 1.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 0); + UASSERT(fabs(dtime - 1.000) < 0.001); + } + { + aabb3f s(bx, by, bz, bx+1, by+1, bz+1); + aabb3f m(bx-2, by, bz, bx-1, by+1, bz+1); + v3f v(-1, 0, 0); + f32 dtime = 1.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == -1); + } + { + aabb3f s(bx, by, bz, bx+1, by+1, bz+1); + aabb3f m(bx-2, by+1.5, bz, bx-1, by+2.5, bz-1); + v3f v(1, 0, 0); + f32 dtime = 1.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == -1); + } + { + aabb3f s(bx, by, bz, bx+1, by+1, bz+1); + aabb3f m(bx-2, by-1.5, bz, bx-1.5, by+0.5, bz+1); + v3f v(0.5, 0.1, 0); + f32 dtime = 3.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 0); + UASSERT(fabs(dtime - 3.000) < 0.001); + } + { + aabb3f s(bx, by, bz, bx+1, by+1, bz+1); + aabb3f m(bx-2, by-1.5, bz, bx-1.5, by+0.5, bz+1); + v3f v(0.5, 0.1, 0); + f32 dtime = 3.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 0); + UASSERT(fabs(dtime - 3.000) < 0.001); + } + + // X+ + { + aabb3f s(bx, by, bz, bx+1, by+1, bz+1); + aabb3f m(bx+2, by, bz, bx+3, by+1, bz+1); + v3f v(-1, 0, 0); + f32 dtime = 1.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 0); + UASSERT(fabs(dtime - 1.000) < 0.001); + } + { + aabb3f s(bx, by, bz, bx+1, by+1, bz+1); + aabb3f m(bx+2, by, bz, bx+3, by+1, bz+1); + v3f v(1, 0, 0); + f32 dtime = 1.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == -1); + } + { + aabb3f s(bx, by, bz, bx+1, by+1, bz+1); + aabb3f m(bx+2, by, bz+1.5, bx+3, by+1, bz+3.5); + v3f v(-1, 0, 0); + f32 dtime = 1.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == -1); + } + { + aabb3f s(bx, by, bz, bx+1, by+1, bz+1); + aabb3f m(bx+2, by-1.5, bz, bx+2.5, by-0.5, bz+1); + v3f v(-0.5, 0.2, 0); + f32 dtime = 2.5f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 1); // Y, not X! + UASSERT(fabs(dtime - 2.500) < 0.001); + } + { + aabb3f s(bx, by, bz, bx+1, by+1, bz+1); + aabb3f m(bx+2, by-1.5, bz, bx+2.5, by-0.5, bz+1); + v3f v(-0.5, 0.3, 0); + f32 dtime = 2.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 0); + UASSERT(fabs(dtime - 2.000) < 0.001); + } + + // TODO: Y-, Y+, Z-, Z+ + + // misc + { + aabb3f s(bx, by, bz, bx+2, by+2, bz+2); + aabb3f m(bx+2.3, by+2.29, bz+2.29, bx+4.2, by+4.2, bz+4.2); + v3f v(-1./3, -1./3, -1./3); + f32 dtime = 1.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 0); + UASSERT(fabs(dtime - 0.9) < 0.001); + } + { + aabb3f s(bx, by, bz, bx+2, by+2, bz+2); + aabb3f m(bx+2.29, by+2.3, bz+2.29, bx+4.2, by+4.2, bz+4.2); + v3f v(-1./3, -1./3, -1./3); + f32 dtime = 1.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 1); + UASSERT(fabs(dtime - 0.9) < 0.001); + } + { + aabb3f s(bx, by, bz, bx+2, by+2, bz+2); + aabb3f m(bx+2.29, by+2.29, bz+2.3, bx+4.2, by+4.2, bz+4.2); + v3f v(-1./3, -1./3, -1./3); + f32 dtime = 1.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 2); + UASSERT(fabs(dtime - 0.9) < 0.001); + } + { + aabb3f s(bx, by, bz, bx+2, by+2, bz+2); + aabb3f m(bx-4.2, by-4.2, bz-4.2, bx-2.3, by-2.29, bz-2.29); + v3f v(1./7, 1./7, 1./7); + f32 dtime = 17.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 0); + UASSERT(fabs(dtime - 16.1) < 0.001); + } + { + aabb3f s(bx, by, bz, bx+2, by+2, bz+2); + aabb3f m(bx-4.2, by-4.2, bz-4.2, bx-2.29, by-2.3, bz-2.29); + v3f v(1./7, 1./7, 1./7); + f32 dtime = 17.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 1); + UASSERT(fabs(dtime - 16.1) < 0.001); + } + { + aabb3f s(bx, by, bz, bx+2, by+2, bz+2); + aabb3f m(bx-4.2, by-4.2, bz-4.2, bx-2.29, by-2.29, bz-2.3); + v3f v(1./7, 1./7, 1./7); + f32 dtime = 17.0f; + UASSERT(axisAlignedCollision(s, m, v, &dtime) == 2); + UASSERT(fabs(dtime - 16.1) < 0.001); + } + } +} diff --git a/src/unittest/test_compression.cpp b/src/unittest/test_compression.cpp new file mode 100644 index 0000000..a96282f --- /dev/null +++ b/src/unittest/test_compression.cpp @@ -0,0 +1,273 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <sstream> + +#include "irrlichttypes_extrabloated.h" +#include "log.h" +#include "serialization.h" +#include "nodedef.h" +#include "noise.h" + +class TestCompression : public TestBase { +public: + TestCompression() { TestManager::registerTestModule(this); } + const char *getName() { return "TestCompression"; } + + void runTests(IGameDef *gamedef); + + void testRLECompression(); + void testZlibCompression(); + void testZlibLargeData(); + void testZstdLargeData(); + void testZlibLimit(); + void _testZlibLimit(u32 size, u32 limit); +}; + +static TestCompression g_test_instance; + +void TestCompression::runTests(IGameDef *gamedef) +{ + TEST(testRLECompression); + TEST(testZlibCompression); + TEST(testZlibLargeData); + TEST(testZstdLargeData); + TEST(testZlibLimit); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestCompression::testRLECompression() +{ + SharedBuffer<u8> fromdata(4); + fromdata[0]=1; + fromdata[1]=5; + fromdata[2]=5; + fromdata[3]=1; + + std::ostringstream os(std::ios_base::binary); + compress(fromdata, os, 0); + + std::string str_out = os.str(); + + infostream << "str_out.size()="<<str_out.size()<<std::endl; + infostream << "TestCompress: 1,5,5,1 -> "; + for (char i : str_out) + infostream << (u32) i << ","; + infostream << std::endl; + + UASSERT(str_out.size() == 10); + + UASSERT(str_out[0] == 0); + UASSERT(str_out[1] == 0); + UASSERT(str_out[2] == 0); + UASSERT(str_out[3] == 4); + UASSERT(str_out[4] == 0); + UASSERT(str_out[5] == 1); + UASSERT(str_out[6] == 1); + UASSERT(str_out[7] == 5); + UASSERT(str_out[8] == 0); + UASSERT(str_out[9] == 1); + + std::istringstream is(str_out, std::ios_base::binary); + std::ostringstream os2(std::ios_base::binary); + + decompress(is, os2, 0); + std::string str_out2 = os2.str(); + + infostream << "decompress: "; + for (char i : str_out2) + infostream << (u32) i << ","; + infostream << std::endl; + + UASSERTEQ(size_t, str_out2.size(), fromdata.getSize()); + + for (u32 i = 0; i < str_out2.size(); i++) + UASSERT(str_out2[i] == fromdata[i]); +} + +void TestCompression::testZlibCompression() +{ + SharedBuffer<u8> fromdata(4); + fromdata[0]=1; + fromdata[1]=5; + fromdata[2]=5; + fromdata[3]=1; + + std::ostringstream os(std::ios_base::binary); + compressZlib(*fromdata, fromdata.getSize(), os); + + std::string str_out = os.str(); + + infostream << "str_out.size()=" << str_out.size() <<std::endl; + infostream << "TestCompress: 1,5,5,1 -> "; + for (char i : str_out) + infostream << (u32) i << ","; + infostream << std::endl; + + std::istringstream is(str_out, std::ios_base::binary); + std::ostringstream os2(std::ios_base::binary); + + decompressZlib(is, os2); + std::string str_out2 = os2.str(); + + infostream << "decompress: "; + for (char i : str_out2) + infostream << (u32) i << ","; + infostream << std::endl; + + UASSERTEQ(size_t, str_out2.size(), fromdata.getSize()); + + for (u32 i = 0; i < str_out2.size(); i++) + UASSERT(str_out2[i] == fromdata[i]); +} + +void TestCompression::testZlibLargeData() +{ + infostream << "Test: Testing zlib wrappers with a large amount " + "of pseudorandom data" << std::endl; + + u32 size = 50000; + infostream << "Test: Input size of large compressZlib is " + << size << std::endl; + + std::string data_in; + data_in.resize(size); + PseudoRandom pseudorandom(9420); + for (u32 i = 0; i < size; i++) + data_in[i] = pseudorandom.range(0, 255); + + std::ostringstream os_compressed(std::ios::binary); + compressZlib(data_in, os_compressed); + infostream << "Test: Output size of large compressZlib is " + << os_compressed.str().size()<<std::endl; + + std::istringstream is_compressed(os_compressed.str(), std::ios::binary); + std::ostringstream os_decompressed(std::ios::binary); + decompressZlib(is_compressed, os_decompressed); + infostream << "Test: Output size of large decompressZlib is " + << os_decompressed.str().size() << std::endl; + + std::string str_decompressed = os_decompressed.str(); + UASSERTEQ(size_t, str_decompressed.size(), data_in.size()); + + for (u32 i = 0; i < size && i < str_decompressed.size(); i++) { + UTEST(str_decompressed[i] == data_in[i], + "index out[%i]=%i differs from in[%i]=%i", + i, str_decompressed[i], i, data_in[i]); + } +} + +void TestCompression::testZstdLargeData() +{ + infostream << "Test: Testing zstd wrappers with a large amount " + "of pseudorandom data" << std::endl; + + u32 size = 500000; + infostream << "Test: Input size of large compressZstd is " + << size << std::endl; + + std::string data_in; + data_in.resize(size); + PseudoRandom pseudorandom(9420); + for (u32 i = 0; i < size; i++) + data_in[i] = pseudorandom.range(0, 255); + + std::ostringstream os_compressed(std::ios::binary); + compressZstd(data_in, os_compressed, 0); + infostream << "Test: Output size of large compressZstd is " + << os_compressed.str().size()<<std::endl; + + std::istringstream is_compressed(os_compressed.str(), std::ios::binary); + std::ostringstream os_decompressed(std::ios::binary); + decompressZstd(is_compressed, os_decompressed); + infostream << "Test: Output size of large decompressZstd is " + << os_decompressed.str().size() << std::endl; + + std::string str_decompressed = os_decompressed.str(); + UASSERTEQ(size_t, str_decompressed.size(), data_in.size()); + + for (u32 i = 0; i < size && i < str_decompressed.size(); i++) { + UTEST(str_decompressed[i] == data_in[i], + "index out[%i]=%i differs from in[%i]=%i", + i, str_decompressed[i], i, data_in[i]); + } +} + +void TestCompression::testZlibLimit() +{ + // edge cases + _testZlibLimit(1024, 1023); + _testZlibLimit(1024, 1024); + _testZlibLimit(1024, 1025); + + // test around buffer borders + u32 bufsize = 16384; // as in implementation + for (int s = -1; s <= 1; s++) + { + for (int l = -1; l <= 1; l++) + { + _testZlibLimit(bufsize + s, bufsize + l); + } + } + // span multiple buffers + _testZlibLimit(35000, 22000); + _testZlibLimit(22000, 35000); +} + +void TestCompression::_testZlibLimit(u32 size, u32 limit) +{ + infostream << "Test: Testing zlib wrappers with a decompression " + "memory limit of " << limit << std::endl; + + infostream << "Test: Input size of compressZlib for limit is " + << size << std::endl; + + // how much data we expect to get + u32 expected = size < limit ? size : limit; + + // create recognizable data + std::string data_in; + data_in.resize(size); + for (u32 i = 0; i < size; i++) + data_in[i] = (u8)(i % 256); + + std::ostringstream os_compressed(std::ios::binary); + compressZlib(data_in, os_compressed); + infostream << "Test: Output size of compressZlib for limit is " + << os_compressed.str().size()<<std::endl; + + std::istringstream is_compressed(os_compressed.str(), std::ios::binary); + std::ostringstream os_decompressed(std::ios::binary); + decompressZlib(is_compressed, os_decompressed, limit); + infostream << "Test: Output size of decompressZlib with limit is " + << os_decompressed.str().size() << std::endl; + + std::string str_decompressed = os_decompressed.str(); + UASSERTEQ(size_t, str_decompressed.size(), expected); + + for (u32 i = 0; i < size && i < str_decompressed.size(); i++) { + UTEST(str_decompressed[i] == data_in[i], + "index out[%i]=%i differs from in[%i]=%i", + i, str_decompressed[i], i, data_in[i]); + } +} + diff --git a/src/unittest/test_config.h.in b/src/unittest/test_config.h.in new file mode 100644 index 0000000..50d2398 --- /dev/null +++ b/src/unittest/test_config.h.in @@ -0,0 +1,7 @@ +// Filled in by the build system + +#pragma once + +#define TEST_WORLDDIR "@TEST_WORLDDIR@" +#define TEST_SUBGAME_PATH "@TEST_SUBGAME_PATH@" +#define TEST_MOD_PATH "@TEST_MOD_PATH@" diff --git a/src/unittest/test_connection.cpp b/src/unittest/test_connection.cpp new file mode 100644 index 0000000..04fea90 --- /dev/null +++ b/src/unittest/test_connection.cpp @@ -0,0 +1,378 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "log.h" +#include "porting.h" +#include "settings.h" +#include "util/serialize.h" +#include "network/connection.h" +#include "network/networkpacket.h" +#include "network/socket.h" + +class TestConnection : public TestBase { +public: + TestConnection() + { + if (INTERNET_SIMULATOR == false) + TestManager::registerTestModule(this); + } + + const char *getName() { return "TestConnection"; } + + void runTests(IGameDef *gamedef); + + void testNetworkPacketSerialize(); + void testHelpers(); + void testConnectSendReceive(); +}; + +static TestConnection g_test_instance; + +void TestConnection::runTests(IGameDef *gamedef) +{ + TEST(testNetworkPacketSerialize); + TEST(testHelpers); + TEST(testConnectSendReceive); +} + +//////////////////////////////////////////////////////////////////////////////// + +struct Handler : public con::PeerHandler +{ + Handler(const char *a_name) : name(a_name) {} + + void peerAdded(con::Peer *peer) + { + infostream << "Handler(" << name << ")::peerAdded(): " + "id=" << peer->id << std::endl; + last_id = peer->id; + count++; + } + + void deletingPeer(con::Peer *peer, bool timeout) + { + infostream << "Handler(" << name << ")::deletingPeer(): " + "id=" << peer->id << ", timeout=" << timeout << std::endl; + last_id = peer->id; + count--; + } + + s32 count = 0; + u16 last_id = 0; + const char *name; +}; + +void TestConnection::testNetworkPacketSerialize() +{ + const static u8 expected[] = { + 0x00, 0x7b, + 0x00, 0x02, 0xd8, 0x42, 0xdf, 0x9a + }; + + if (sizeof(wchar_t) == 2) + warningstream << __FUNCTION__ << " may fail on this platform." << std::endl; + + { + NetworkPacket pkt(123, 0); + + // serializing wide strings should do surrogate encoding, we test that here + pkt << std::wstring(L"\U00020b9a"); + + auto buf = pkt.oldForgePacket(); + UASSERTEQ(int, buf.getSize(), sizeof(expected)); + UASSERT(!memcmp(expected, &buf[0], buf.getSize())); + } + + { + NetworkPacket pkt; + pkt.putRawPacket(expected, sizeof(expected), 0); + + // same for decoding + std::wstring pkt_s; + pkt >> pkt_s; + + UASSERT(pkt_s == L"\U00020b9a"); + } +} + +void TestConnection::testHelpers() +{ + // Some constants for testing + u32 proto_id = 0x12345678; + session_t peer_id = 123; + u8 channel = 2; + SharedBuffer<u8> data1(1); + data1[0] = 100; + Address a(127,0,0,1, 10); + const u16 seqnum = 34352; + + con::BufferedPacketPtr p1 = con::makePacket(a, data1, + proto_id, peer_id, channel); + /* + We should now have a packet with this data: + Header: + [0] u32 protocol_id + [4] session_t sender_peer_id + [6] u8 channel + Data: + [7] u8 data1[0] + */ + UASSERT(readU32(&p1->data[0]) == proto_id); + UASSERT(readU16(&p1->data[4]) == peer_id); + UASSERT(readU8(&p1->data[6]) == channel); + UASSERT(readU8(&p1->data[7]) == data1[0]); + + //infostream<<"initial data1[0]="<<((u32)data1[0]&0xff)<<std::endl; + + SharedBuffer<u8> p2 = con::makeReliablePacket(data1, seqnum); + + /*infostream<<"p2.getSize()="<<p2.getSize()<<", data1.getSize()=" + <<data1.getSize()<<std::endl; + infostream<<"readU8(&p2[3])="<<readU8(&p2[3]) + <<" p2[3]="<<((u32)p2[3]&0xff)<<std::endl; + infostream<<"data1[0]="<<((u32)data1[0]&0xff)<<std::endl;*/ + + UASSERT(p2.getSize() == 3 + data1.getSize()); + UASSERT(readU8(&p2[0]) == con::PACKET_TYPE_RELIABLE); + UASSERT(readU16(&p2[1]) == seqnum); + UASSERT(readU8(&p2[3]) == data1[0]); +} + + +void TestConnection::testConnectSendReceive() +{ + /* + Test some real connections + + NOTE: This mostly tests the legacy interface. + */ + + u32 proto_id = 0xad26846a; + + Handler hand_server("server"); + Handler hand_client("client"); + + Address address(0, 0, 0, 0, 30001); + Address bind_addr(0, 0, 0, 0, 30001); + /* + * Try to use the bind_address for servers with no localhost address + * For example: FreeBSD jails + */ + std::string bind_str = g_settings->get("bind_address"); + try { + bind_addr.Resolve(bind_str.c_str()); + + if (!bind_addr.isIPv6()) { + address = bind_addr; + } + } catch (ResolveError &e) { + } + + infostream << "** Creating server Connection" << std::endl; + con::Connection server(proto_id, 512, 5.0, false, &hand_server); + server.Serve(address); + + infostream << "** Creating client Connection" << std::endl; + con::Connection client(proto_id, 512, 5.0, false, &hand_client); + + UASSERT(hand_server.count == 0); + UASSERT(hand_client.count == 0); + + sleep_ms(50); + + Address server_address(127, 0, 0, 1, 30001); + if (address != Address(0, 0, 0, 0, 30001)) { + server_address = bind_addr; + } + + infostream << "** running client.Connect()" << std::endl; + client.Connect(server_address); + + sleep_ms(50); + + // Client should not have added client yet + UASSERT(hand_client.count == 0); + + try { + NetworkPacket pkt; + infostream << "** running client.Receive()" << std::endl; + client.Receive(&pkt); + infostream << "** Client received: peer_id=" << pkt.getPeerId() + << ", size=" << pkt.getSize() << std::endl; + } catch (con::NoIncomingDataException &e) { + } + + // Client should have added server now + UASSERT(hand_client.count == 1); + UASSERT(hand_client.last_id == 1); + // Server should not have added client yet + UASSERT(hand_server.count == 0); + + sleep_ms(100); + + try { + NetworkPacket pkt; + infostream << "** running server.Receive()" << std::endl; + server.Receive(&pkt); + infostream << "** Server received: peer_id=" << pkt.getPeerId() + << ", size=" << pkt.getSize() + << std::endl; + } catch (con::NoIncomingDataException &e) { + // No actual data received, but the client has + // probably been connected + } + + // Client should be the same + UASSERT(hand_client.count == 1); + UASSERT(hand_client.last_id == 1); + // Server should have the client + UASSERT(hand_server.count == 1); + UASSERT(hand_server.last_id == 2); + + //sleep_ms(50); + + while (client.Connected() == false) { + try { + NetworkPacket pkt; + infostream << "** running client.Receive()" << std::endl; + client.Receive(&pkt); + infostream << "** Client received: peer_id=" << pkt.getPeerId() + << ", size=" << pkt.getSize() << std::endl; + } catch (con::NoIncomingDataException &e) { + } + sleep_ms(50); + } + + sleep_ms(50); + + try { + NetworkPacket pkt; + infostream << "** running server.Receive()" << std::endl; + server.Receive(&pkt); + infostream << "** Server received: peer_id=" << pkt.getPeerId() + << ", size=" << pkt.getSize() + << std::endl; + } catch (con::NoIncomingDataException &e) { + } + + /* + Simple send-receive test + */ + { + NetworkPacket pkt; + pkt.putRawPacket((u8*) "Hello World !", 14, 0); + + auto sentdata = pkt.oldForgePacket(); + + infostream<<"** running client.Send()"<<std::endl; + client.Send(PEER_ID_SERVER, 0, &pkt, true); + + sleep_ms(50); + + NetworkPacket recvpacket; + infostream << "** running server.Receive()" << std::endl; + server.Receive(&recvpacket); + infostream << "** Server received: peer_id=" << pkt.getPeerId() + << ", size=" << pkt.getSize() + << ", data=" << (const char*)pkt.getU8Ptr(0) + << std::endl; + + auto recvdata = pkt.oldForgePacket(); + + UASSERT(memcmp(*sentdata, *recvdata, recvdata.getSize()) == 0); + } + + session_t peer_id_client = 2; + /* + Send a large packet + */ + { + const int datasize = 30000; + NetworkPacket pkt(0, datasize); + for (u16 i=0; i<datasize; i++) { + pkt << (u8) i/4; + } + + infostream << "Sending data (size=" << datasize << "):"; + for (int i = 0; i < datasize && i < 20; i++) { + if (i % 2 == 0) + infostream << " "; + char buf[10]; + porting::mt_snprintf(buf, sizeof(buf), "%.2X", + ((int)((const char *)pkt.getU8Ptr(0))[i]) & 0xff); + infostream<<buf; + } + if (datasize > 20) + infostream << "..."; + infostream << std::endl; + + auto sentdata = pkt.oldForgePacket(); + + server.Send(peer_id_client, 0, &pkt, true); + + //sleep_ms(3000); + + Buffer<u8> recvdata; + infostream << "** running client.Receive()" << std::endl; + session_t peer_id = 132; + u16 size = 0; + bool received = false; + u64 timems0 = porting::getTimeMs(); + for (;;) { + if (porting::getTimeMs() - timems0 > 5000 || received) + break; + try { + NetworkPacket pkt; + client.Receive(&pkt); + size = pkt.getSize(); + peer_id = pkt.getPeerId(); + recvdata = pkt.oldForgePacket(); + received = true; + } catch (con::NoIncomingDataException &e) { + } + sleep_ms(10); + } + UASSERT(received); + infostream << "** Client received: peer_id=" << peer_id + << ", size=" << size << std::endl; + + infostream << "Received data (size=" << size << "): "; + for (int i = 0; i < size && i < 20; i++) { + if (i % 2 == 0) + infostream << " "; + char buf[10]; + porting::mt_snprintf(buf, sizeof(buf), "%.2X", ((int)(recvdata[i])) & 0xff); + infostream << buf; + } + if (size > 20) + infostream << "..."; + infostream << std::endl; + + UASSERT(memcmp(*sentdata, *recvdata, recvdata.getSize()) == 0); + UASSERT(peer_id == PEER_ID_SERVER); + } + + // Check peer handlers + UASSERT(hand_client.count == 1); + UASSERT(hand_client.last_id == 1); + UASSERT(hand_server.count == 1); + UASSERT(hand_server.last_id == 2); +} diff --git a/src/unittest/test_eventmanager.cpp b/src/unittest/test_eventmanager.cpp new file mode 100644 index 0000000..fec57f9 --- /dev/null +++ b/src/unittest/test_eventmanager.cpp @@ -0,0 +1,112 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <unordered_map> +#include "test.h" +#include "client/event_manager.h" + +class TestEventManager : public TestBase +{ +public: + TestEventManager() { TestManager::registerTestModule(this); } + const char *getName() override { return "TestEventManager"; } + + void runTests(IGameDef *gamedef) override; + + void testRegister(); + void testDeregister(); + void testRealEvent(); + void testRealEventAfterDereg(); +}; + +// EventManager test class +class EventManagerTest : public EventManager +{ +public: + static void eventTest(MtEvent *e, void *data) + { + UASSERT(e->getType() >= 0); + UASSERT(e->getType() < MtEvent::TYPE_MAX); + EventManagerTest *emt = (EventManagerTest *)data; + emt->m_test_value = e->getType(); + } + + u64 getTestValue() const { return m_test_value; } + void resetValue() { m_test_value = 0; } + +private: + u64 m_test_value = 0; +}; + +static TestEventManager g_test_instance; + +void TestEventManager::runTests(IGameDef *gamedef) +{ + TEST(testRegister); + TEST(testDeregister); + TEST(testRealEvent); + TEST(testRealEventAfterDereg); +} + +void TestEventManager::testRegister() +{ + EventManager ev; + ev.reg(MtEvent::PLAYER_DAMAGE, nullptr, nullptr); + ev.reg(MtEvent::PLAYER_DAMAGE, nullptr, nullptr); +} + +void TestEventManager::testDeregister() +{ + EventManager ev; + ev.dereg(MtEvent::NODE_DUG, nullptr, nullptr); + ev.reg(MtEvent::PLAYER_DAMAGE, nullptr, nullptr); + ev.dereg(MtEvent::PLAYER_DAMAGE, nullptr, nullptr); +} + +void TestEventManager::testRealEvent() +{ + EventManager ev; + auto emt = std::make_unique<EventManagerTest>(); + ev.reg(MtEvent::PLAYER_REGAIN_GROUND, EventManagerTest::eventTest, emt.get()); + + // Put event & verify event value + ev.put(new SimpleTriggerEvent(MtEvent::PLAYER_REGAIN_GROUND)); + UASSERT(emt->getTestValue() == MtEvent::PLAYER_REGAIN_GROUND); +} + +void TestEventManager::testRealEventAfterDereg() +{ + EventManager ev; + auto emt = std::make_unique<EventManagerTest>(); + ev.reg(MtEvent::PLAYER_REGAIN_GROUND, EventManagerTest::eventTest, emt.get()); + + // Put event & verify event value + ev.put(new SimpleTriggerEvent(MtEvent::PLAYER_REGAIN_GROUND)); + UASSERT(emt->getTestValue() == MtEvent::PLAYER_REGAIN_GROUND); + + // Reset internal value + emt->resetValue(); + + // Remove the registered event + ev.dereg(MtEvent::PLAYER_REGAIN_GROUND, EventManagerTest::eventTest, emt.get()); + + // Push the new event & ensure we target the default value + ev.put(new SimpleTriggerEvent(MtEvent::PLAYER_REGAIN_GROUND)); + UASSERT(emt->getTestValue() == 0); +} \ No newline at end of file diff --git a/src/unittest/test_filepath.cpp b/src/unittest/test_filepath.cpp new file mode 100644 index 0000000..ac2d69b --- /dev/null +++ b/src/unittest/test_filepath.cpp @@ -0,0 +1,264 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <sstream> + +#include "log.h" +#include "serialization.h" +#include "nodedef.h" +#include "noise.h" + +class TestFilePath : public TestBase { +public: + TestFilePath() { TestManager::registerTestModule(this); } + const char *getName() { return "TestFilePath"; } + + void runTests(IGameDef *gamedef); + + void testIsDirDelimiter(); + void testPathStartsWith(); + void testRemoveLastPathComponent(); + void testRemoveLastPathComponentWithTrailingDelimiter(); + void testRemoveRelativePathComponent(); +}; + +static TestFilePath g_test_instance; + +void TestFilePath::runTests(IGameDef *gamedef) +{ + TEST(testIsDirDelimiter); + TEST(testPathStartsWith); + TEST(testRemoveLastPathComponent); + TEST(testRemoveLastPathComponentWithTrailingDelimiter); + TEST(testRemoveRelativePathComponent); +} + +//////////////////////////////////////////////////////////////////////////////// + +// adjusts a POSIX path to system-specific conventions +// -> changes '/' to DIR_DELIM +// -> absolute paths start with "C:\\" on windows +std::string p(std::string path) +{ + for (size_t i = 0; i < path.size(); ++i) { + if (path[i] == '/') { + path.replace(i, 1, DIR_DELIM); + i += std::string(DIR_DELIM).size() - 1; // generally a no-op + } + } + + #ifdef _WIN32 + if (path[0] == '\\') + path = "C:" + path; + #endif + + return path; +} + + +void TestFilePath::testIsDirDelimiter() +{ + UASSERT(fs::IsDirDelimiter('/') == true); + UASSERT(fs::IsDirDelimiter('A') == false); + UASSERT(fs::IsDirDelimiter(0) == false); +#ifdef _WIN32 + UASSERT(fs::IsDirDelimiter('\\') == true); +#else + UASSERT(fs::IsDirDelimiter('\\') == false); +#endif +} + + +void TestFilePath::testPathStartsWith() +{ + const int numpaths = 12; + std::string paths[numpaths] = { + "", + p("/"), + p("/home/user/minetest"), + p("/home/user/minetest/bin"), + p("/home/user/.minetest"), + p("/tmp/dir/file"), + p("/tmp/file/"), + p("/tmP/file"), + p("/tmp"), + p("/tmp/dir"), + p("/home/user2/minetest/worlds"), + p("/home/user2/minetest/world"), + }; + /* + expected fs::PathStartsWith results + 0 = returns false + 1 = returns true + 2 = returns false on windows, true elsewhere + 3 = returns true on windows, false elsewhere + 4 = returns true if and only if + FILESYS_CASE_INSENSITIVE is true + */ + int expected_results[numpaths][numpaths] = { + {1,2,0,0,0,0,0,0,0,0,0,0}, + {1,1,0,0,0,0,0,0,0,0,0,0}, + {1,1,1,0,0,0,0,0,0,0,0,0}, + {1,1,1,1,0,0,0,0,0,0,0,0}, + {1,1,0,0,1,0,0,0,0,0,0,0}, + {1,1,0,0,0,1,0,0,1,1,0,0}, + {1,1,0,0,0,0,1,4,1,0,0,0}, + {1,1,0,0,0,0,4,1,4,0,0,0}, + {1,1,0,0,0,0,0,0,1,0,0,0}, + {1,1,0,0,0,0,0,0,1,1,0,0}, + {1,1,0,0,0,0,0,0,0,0,1,0}, + {1,1,0,0,0,0,0,0,0,0,0,1}, + }; + + for (int i = 0; i < numpaths; i++) + for (int j = 0; j < numpaths; j++){ + /*verbosestream<<"testing fs::PathStartsWith(\"" + <<paths[i]<<"\", \"" + <<paths[j]<<"\")"<<std::endl;*/ + bool starts = fs::PathStartsWith(paths[i], paths[j]); + int expected = expected_results[i][j]; + if(expected == 0){ + UASSERT(starts == false); + } + else if(expected == 1){ + UASSERT(starts == true); + } + #ifdef _WIN32 + else if(expected == 2){ + UASSERT(starts == false); + } + else if(expected == 3){ + UASSERT(starts == true); + } + #else + else if(expected == 2){ + UASSERT(starts == true); + } + else if(expected == 3){ + UASSERT(starts == false); + } + #endif + else if(expected == 4){ + UASSERT(starts == (bool)FILESYS_CASE_INSENSITIVE); + } + } +} + + +void TestFilePath::testRemoveLastPathComponent() +{ + std::string path, result, removed; + + UASSERT(fs::RemoveLastPathComponent("") == ""); + path = p("/home/user/minetest/bin/..//worlds/world1"); + result = fs::RemoveLastPathComponent(path, &removed, 0); + UASSERT(result == path); + UASSERT(removed == ""); + result = fs::RemoveLastPathComponent(path, &removed, 1); + UASSERT(result == p("/home/user/minetest/bin/..//worlds")); + UASSERT(removed == p("world1")); + result = fs::RemoveLastPathComponent(path, &removed, 2); + UASSERT(result == p("/home/user/minetest/bin/..")); + UASSERT(removed == p("worlds/world1")); + result = fs::RemoveLastPathComponent(path, &removed, 3); + UASSERT(result == p("/home/user/minetest/bin")); + UASSERT(removed == p("../worlds/world1")); + result = fs::RemoveLastPathComponent(path, &removed, 4); + UASSERT(result == p("/home/user/minetest")); + UASSERT(removed == p("bin/../worlds/world1")); + result = fs::RemoveLastPathComponent(path, &removed, 5); + UASSERT(result == p("/home/user")); + UASSERT(removed == p("minetest/bin/../worlds/world1")); + result = fs::RemoveLastPathComponent(path, &removed, 6); + UASSERT(result == p("/home")); + UASSERT(removed == p("user/minetest/bin/../worlds/world1")); + result = fs::RemoveLastPathComponent(path, &removed, 7); +#ifdef _WIN32 + UASSERT(result == "C:"); +#else + UASSERT(result == ""); +#endif + UASSERT(removed == p("home/user/minetest/bin/../worlds/world1")); +} + + +void TestFilePath::testRemoveLastPathComponentWithTrailingDelimiter() +{ + std::string path, result, removed; + + path = p("/home/user/minetest/bin/..//worlds/world1/"); + result = fs::RemoveLastPathComponent(path, &removed, 0); + UASSERT(result == path); + UASSERT(removed == ""); + result = fs::RemoveLastPathComponent(path, &removed, 1); + UASSERT(result == p("/home/user/minetest/bin/..//worlds")); + UASSERT(removed == p("world1")); + result = fs::RemoveLastPathComponent(path, &removed, 2); + UASSERT(result == p("/home/user/minetest/bin/..")); + UASSERT(removed == p("worlds/world1")); + result = fs::RemoveLastPathComponent(path, &removed, 3); + UASSERT(result == p("/home/user/minetest/bin")); + UASSERT(removed == p("../worlds/world1")); + result = fs::RemoveLastPathComponent(path, &removed, 4); + UASSERT(result == p("/home/user/minetest")); + UASSERT(removed == p("bin/../worlds/world1")); + result = fs::RemoveLastPathComponent(path, &removed, 5); + UASSERT(result == p("/home/user")); + UASSERT(removed == p("minetest/bin/../worlds/world1")); + result = fs::RemoveLastPathComponent(path, &removed, 6); + UASSERT(result == p("/home")); + UASSERT(removed == p("user/minetest/bin/../worlds/world1")); + result = fs::RemoveLastPathComponent(path, &removed, 7); +#ifdef _WIN32 + UASSERT(result == "C:"); +#else + UASSERT(result == ""); +#endif + UASSERT(removed == p("home/user/minetest/bin/../worlds/world1")); +} + + +void TestFilePath::testRemoveRelativePathComponent() +{ + std::string path, result, removed; + + path = p("/home/user/minetest/bin"); + result = fs::RemoveRelativePathComponents(path); + UASSERT(result == path); + path = p("/home/user/minetest/bin/../worlds/world1"); + result = fs::RemoveRelativePathComponents(path); + UASSERT(result == p("/home/user/minetest/worlds/world1")); + path = p("/home/user/minetest/bin/../worlds/world1/"); + result = fs::RemoveRelativePathComponents(path); + UASSERT(result == p("/home/user/minetest/worlds/world1")); + path = p("."); + result = fs::RemoveRelativePathComponents(path); + UASSERT(result == ""); + path = p("../a"); + result = fs::RemoveRelativePathComponents(path); + UASSERT(result == ""); + path = p("./subdir/../.."); + result = fs::RemoveRelativePathComponents(path); + UASSERT(result == ""); + path = p("/a/b/c/.././../d/../e/f/g/../h/i/j/../../../.."); + result = fs::RemoveRelativePathComponents(path); + UASSERT(result == p("/a/e")); +} diff --git a/src/unittest/test_gameui.cpp b/src/unittest/test_gameui.cpp new file mode 100644 index 0000000..a6d853f --- /dev/null +++ b/src/unittest/test_gameui.cpp @@ -0,0 +1,93 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "client/gameui.h" + +class TestGameUI : public TestBase +{ +public: + TestGameUI() { TestManager::registerTestModule(this); } + const char *getName() { return "TestGameUI"; } + + void runTests(IGameDef *gamedef); + + void testInit(); + void testFlagSetters(); + void testInfoText(); + void testStatusText(); +}; + +static TestGameUI g_test_instance; + +void TestGameUI::runTests(IGameDef *gamedef) +{ + TEST(testInit); + TEST(testFlagSetters); + TEST(testInfoText); + TEST(testStatusText); +} + +void TestGameUI::testInit() +{ + GameUI gui{}; + // Ensure flags on GameUI init + UASSERT(gui.getFlags().show_chat) + UASSERT(gui.getFlags().show_hud) + UASSERT(!gui.getFlags().show_minimap) + UASSERT(!gui.getFlags().show_profiler_graph) + + // And after the initFlags init stage + gui.initFlags(); + UASSERT(gui.getFlags().show_chat) + UASSERT(gui.getFlags().show_hud) + UASSERT(!gui.getFlags().show_minimap) + UASSERT(!gui.getFlags().show_profiler_graph) + + // @TODO verify if we can create non UI nulldevice to test this function + // gui.init(); +} + +void TestGameUI::testFlagSetters() +{ + GameUI gui{}; + gui.showMinimap(true); + UASSERT(gui.getFlags().show_minimap); + + gui.showMinimap(false); + UASSERT(!gui.getFlags().show_minimap); +} + +void TestGameUI::testStatusText() +{ + GameUI gui{}; + gui.showStatusText(L"test status"); + + UASSERT(gui.m_statustext_time == 0.0f); + UASSERT(gui.m_statustext == L"test status"); +} + +void TestGameUI::testInfoText() +{ + GameUI gui{}; + gui.setInfoText(L"test info"); + + UASSERT(gui.m_infotext == L"test info"); +} diff --git a/src/unittest/test_gettext.cpp b/src/unittest/test_gettext.cpp new file mode 100644 index 0000000..338a416 --- /dev/null +++ b/src/unittest/test_gettext.cpp @@ -0,0 +1,43 @@ +#include "test.h" +#include "porting.h" +#include "gettext.h" + +class TestGettext : public TestBase +{ +public: + TestGettext() { + TestManager::registerTestModule(this); + } + + const char *getName() { return "TestGettext"; } + + void runTests(IGameDef *gamedef); + + void testFmtgettext(); +}; + +static TestGettext g_test_instance; + +void TestGettext::runTests(IGameDef *gamedef) +{ + TEST(testFmtgettext); +} + +// Make sure updatepo.sh does not pick up the strings +#define dummyname fmtgettext + +void TestGettext::testFmtgettext() +{ + std::string buf = dummyname("sample text %d", 12); + UASSERTEQ(std::string, buf, "sample text 12"); + + std::string src, expect; + src = "You are about to join this server with the name \"%s\".\n"; + expect = "You are about to join this server with the name \"foo\".\n"; + for (int i = 0; i < 20; i++) { + src.append("loooong text"); + expect.append("loooong text"); + } + buf = dummyname(src.c_str(), "foo"); + UASSERTEQ(const std::string &, buf, expect); +} diff --git a/src/unittest/test_inventory.cpp b/src/unittest/test_inventory.cpp new file mode 100644 index 0000000..5f71636 --- /dev/null +++ b/src/unittest/test_inventory.cpp @@ -0,0 +1,126 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <sstream> + +#include "gamedef.h" +#include "inventory.h" + +class TestInventory : public TestBase { +public: + TestInventory() { TestManager::registerTestModule(this); } + const char *getName() { return "TestInventory"; } + + void runTests(IGameDef *gamedef); + + void testSerializeDeserialize(IItemDefManager *idef); + + static const char *serialized_inventory_in; + static const char *serialized_inventory_out; + static const char *serialized_inventory_inc; +}; + +static TestInventory g_test_instance; + +void TestInventory::runTests(IGameDef *gamedef) +{ + TEST(testSerializeDeserialize, gamedef->getItemDefManager()); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestInventory::testSerializeDeserialize(IItemDefManager *idef) +{ + Inventory inv(idef); + std::istringstream is(serialized_inventory_in, std::ios::binary); + + inv.deSerialize(is); + UASSERT(inv.getList("0")); + UASSERT(!inv.getList("main")); + + inv.getList("0")->setName("main"); + UASSERT(!inv.getList("0")); + UASSERT(inv.getList("main")); + UASSERTEQ(u32, inv.getList("main")->getWidth(), 3); + + inv.getList("main")->setWidth(5); + std::ostringstream inv_os(std::ios::binary); + inv.serialize(inv_os, false); + UASSERTEQ(std::string, inv_os.str(), serialized_inventory_out); + + inv.setModified(false); + inv_os.str(""); + inv_os.clear(); + inv.serialize(inv_os, true); + UASSERTEQ(std::string, inv_os.str(), serialized_inventory_inc); + + ItemStack leftover = inv.getList("main")->takeItem(7, 99 - 12); + ItemStack wanted = ItemStack("default:dirt", 99 - 12, 0, idef); + UASSERT(leftover == wanted); + leftover = inv.getList("main")->getItem(7); + wanted.count = 12; + UASSERT(leftover == wanted); +} + +const char *TestInventory::serialized_inventory_in = + "List 0 10\n" + "Width 3\n" + "Empty\n" + "Empty\n" + "Item default:cobble 61\n" + "Empty\n" + "Empty\n" + "Item default:dirt 71\n" + "Empty\n" + "Item default:dirt 99\n" + "Item default:cobble 38\n" + "Empty\n" + "EndInventoryList\n" + "List abc 1\n" + "Item default:stick 3\n" + "Width 0\n" + "EndInventoryList\n" + "EndInventory\n"; + +const char *TestInventory::serialized_inventory_out = + "List main 10\n" + "Width 5\n" + "Empty\n" + "Empty\n" + "Item default:cobble 61\n" + "Empty\n" + "Empty\n" + "Item default:dirt 71\n" + "Empty\n" + "Item default:dirt 99\n" + "Item default:cobble 38\n" + "Empty\n" + "EndInventoryList\n" + "List abc 1\n" + "Width 0\n" + "Item default:stick 3\n" + "EndInventoryList\n" + "EndInventory\n"; + +const char *TestInventory::serialized_inventory_inc = + "KeepList main\n" + "KeepList abc\n" + "EndInventory\n"; diff --git a/src/unittest/test_irrptr.cpp b/src/unittest/test_irrptr.cpp new file mode 100644 index 0000000..2fb7cfc --- /dev/null +++ b/src/unittest/test_irrptr.cpp @@ -0,0 +1,143 @@ +/* +Minetest +Copyright (C) 2018 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "exceptions.h" +#include "irr_ptr.h" + +class TestIrrPtr : public TestBase +{ +public: + TestIrrPtr() { TestManager::registerTestModule(this); } + const char *getName() { return "TestIrrPtr"; } + + void runTests(IGameDef *gamedef); + + void testRefCounting(); + void testSelfAssignment(); + void testNullHandling(); +}; + +static TestIrrPtr g_test_instance; + +void TestIrrPtr::runTests(IGameDef *gamedef) +{ + TEST(testRefCounting); + TEST(testSelfAssignment); + TEST(testNullHandling); +} + +//////////////////////////////////////////////////////////////////////////////// + +#define UASSERT_REFERENCE_COUNT(object, value, info) \ + UTEST((object)->getReferenceCount() == value, \ + info "Reference count is %d instead of " #value, \ + (object)->getReferenceCount()) + +void TestIrrPtr::testRefCounting() +{ + IReferenceCounted *obj = new IReferenceCounted(); // RC=1 + obj->grab(); + UASSERT_REFERENCE_COUNT(obj, 2, "Pre-condition failed: "); + { + irr_ptr<IReferenceCounted> p1{obj}; // move semantics + UASSERT(p1.get() == obj); + UASSERT_REFERENCE_COUNT(obj, 2, ); + + irr_ptr<IReferenceCounted> p2{p1}; // copy ctor + UASSERT(p1.get() == obj); + UASSERT(p2.get() == obj); + UASSERT_REFERENCE_COUNT(obj, 3, ); + + irr_ptr<IReferenceCounted> p3{std::move(p1)}; // move ctor + UASSERT(p1.get() == nullptr); + UASSERT(p3.get() == obj); + UASSERT_REFERENCE_COUNT(obj, 3, ); + + p1 = std::move(p2); // move assignment + UASSERT(p1.get() == obj); + UASSERT(p2.get() == nullptr); + UASSERT_REFERENCE_COUNT(obj, 3, ); + + p2 = p3; // copy assignment + UASSERT(p2.get() == obj); + UASSERT(p3.get() == obj); + UASSERT_REFERENCE_COUNT(obj, 4, ); + + p1.release(); + UASSERT(p1.get() == nullptr); + UASSERT_REFERENCE_COUNT(obj, 4, ); + } + UASSERT_REFERENCE_COUNT(obj, 2, ); + obj->drop(); + UTEST(obj->drop(), "Dropping failed: reference count is %d", + obj->getReferenceCount()); +} + +#if defined(__clang__) + #pragma GCC diagnostic push + #if __clang_major__ >= 7 + #pragma GCC diagnostic ignored "-Wself-assign-overloaded" + #endif + #pragma GCC diagnostic ignored "-Wself-move" +#endif + +void TestIrrPtr::testSelfAssignment() +{ + irr_ptr<IReferenceCounted> p1{new IReferenceCounted()}; + UASSERT(p1); + UASSERT_REFERENCE_COUNT(p1, 1, ); + p1 = p1; + UASSERT(p1); + UASSERT_REFERENCE_COUNT(p1, 1, ); + p1 = std::move(p1); + UASSERT(p1); + UASSERT_REFERENCE_COUNT(p1, 1, ); +} + +void TestIrrPtr::testNullHandling() +{ + // In the case of an error, it will probably crash with SEGV. + // Nevertheless, UASSERTs are used to catch possible corner cases. + irr_ptr<IReferenceCounted> p1{new IReferenceCounted()}; + UASSERT(p1); + irr_ptr<IReferenceCounted> p2; + UASSERT(!p2); + irr_ptr<IReferenceCounted> p3{p2}; + UASSERT(!p2); + UASSERT(!p3); + irr_ptr<IReferenceCounted> p4{std::move(p2)}; + UASSERT(!p2); + UASSERT(!p4); + p2 = p2; + UASSERT(!p2); + p2 = std::move(p2); + UASSERT(!p2); + p3 = p2; + UASSERT(!p2); + UASSERT(!p3); + p3 = std::move(p2); + UASSERT(!p2); + UASSERT(!p3); +} + +#if defined(__clang__) + #pragma GCC diagnostic pop +#endif diff --git a/src/unittest/test_keycode.cpp b/src/unittest/test_keycode.cpp new file mode 100644 index 0000000..3813af9 --- /dev/null +++ b/src/unittest/test_keycode.cpp @@ -0,0 +1,129 @@ +/* +Minetest +Copyright (C) 2016 sfan5 <sfan5@live.de> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <string> +#include "exceptions.h" +#include "client/keycode.h" + +class TestKeycode : public TestBase { +public: + TestKeycode() { TestManager::registerTestModule(this); } + const char *getName() { return "TestKeycode"; } + + void runTests(IGameDef *gamedef); + + void testCreateFromString(); + void testCreateFromSKeyInput(); + void testCompare(); +}; + +static TestKeycode g_test_instance; + +void TestKeycode::runTests(IGameDef *gamedef) +{ + TEST(testCreateFromString); + TEST(testCreateFromSKeyInput); + TEST(testCompare); +} + +//////////////////////////////////////////////////////////////////////////////// + +#define UASSERTEQ_STR(one, two) UASSERT(strcmp(one, two) == 0) + +void TestKeycode::testCreateFromString() +{ + KeyPress k; + + // Character key, from char + k = KeyPress("R"); + UASSERTEQ_STR(k.sym(), "KEY_KEY_R"); + UASSERTCMP(int, >, strlen(k.name()), 0); // should have human description + + // Character key, from identifier + k = KeyPress("KEY_KEY_B"); + UASSERTEQ_STR(k.sym(), "KEY_KEY_B"); + UASSERTCMP(int, >, strlen(k.name()), 0); + + // Non-Character key, from identifier + k = KeyPress("KEY_UP"); + UASSERTEQ_STR(k.sym(), "KEY_UP"); + UASSERTCMP(int, >, strlen(k.name()), 0); + + k = KeyPress("KEY_F6"); + UASSERTEQ_STR(k.sym(), "KEY_F6"); + UASSERTCMP(int, >, strlen(k.name()), 0); + + // Irrlicht-unknown key, from char + k = KeyPress("/"); + UASSERTEQ_STR(k.sym(), "/"); + UASSERTCMP(int, >, strlen(k.name()), 0); +} + +void TestKeycode::testCreateFromSKeyInput() +{ + KeyPress k; + irr::SEvent::SKeyInput in; + + // Character key + in.Key = irr::KEY_KEY_3; + in.Char = L'3'; + k = KeyPress(in); + UASSERTEQ_STR(k.sym(), "KEY_KEY_3"); + + // Non-Character key + in.Key = irr::KEY_RSHIFT; + in.Char = L'\0'; + k = KeyPress(in); + UASSERTEQ_STR(k.sym(), "KEY_RSHIFT"); + + // Irrlicht-unknown key + in.Key = irr::KEY_KEY_CODES_COUNT; + in.Char = L'?'; + k = KeyPress(in); + UASSERTEQ_STR(k.sym(), "?"); + + // prefer_character mode + in.Key = irr::KEY_COMMA; + in.Char = L'G'; + k = KeyPress(in, true); + UASSERTEQ_STR(k.sym(), "KEY_KEY_G"); +} + +void TestKeycode::testCompare() +{ + // Basic comparison + UASSERT(KeyPress("5") == KeyPress("KEY_KEY_5")); + UASSERT(!(KeyPress("5") == KeyPress("KEY_NUMPAD_5"))); + + // Matching char suffices + // note: This is a real-world example, Irrlicht maps XK_equal to irr::KEY_PLUS on Linux + irr::SEvent::SKeyInput in; + in.Key = irr::KEY_PLUS; + in.Char = L'='; + UASSERT(KeyPress("=") == KeyPress(in)); + + // Matching keycode suffices + irr::SEvent::SKeyInput in2; + in.Key = in2.Key = irr::KEY_OEM_CLEAR; + in.Char = L'\0'; + in2.Char = L';'; + UASSERT(KeyPress(in) == KeyPress(in2)); +} diff --git a/src/unittest/test_lua.cpp b/src/unittest/test_lua.cpp new file mode 100644 index 0000000..fc8f895 --- /dev/null +++ b/src/unittest/test_lua.cpp @@ -0,0 +1,79 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2021 TurkeyMcMac, Jude Melton-Houghton <jwmhjwmh@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +} + +class TestLua : public TestBase +{ +public: + TestLua() { TestManager::registerTestModule(this); } + const char *getName() { return "TestLua"; } + + void runTests(IGameDef *gamedef); + + void testLuaDestructors(); +}; + +static TestLua g_test_instance; + +void TestLua::runTests(IGameDef *gamedef) +{ + TEST(testLuaDestructors); +} + +//////////////////////////////////////////////////////////////////////////////// + +namespace +{ + + class DestructorDetector { + bool *did_destruct; + public: + DestructorDetector(bool *did_destruct) : did_destruct(did_destruct) + { + *did_destruct = false; + } + ~DestructorDetector() + { + *did_destruct = true; + } + }; + +} + +void TestLua::testLuaDestructors() +{ + bool did_destruct = false; + + lua_State *L = luaL_newstate(); + lua_cpcall(L, [](lua_State *L) -> int { + DestructorDetector d(reinterpret_cast<bool*>(lua_touserdata(L, 1))); + luaL_error(L, "error"); + return 0; + }, &did_destruct); + lua_close(L); + + UASSERT(did_destruct); +} diff --git a/src/unittest/test_map.cpp b/src/unittest/test_map.cpp new file mode 100644 index 0000000..82e55e1 --- /dev/null +++ b/src/unittest/test_map.cpp @@ -0,0 +1,68 @@ +/* +Minetest + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <cstdio> +#include "mapblock.h" + +class TestMap : public TestBase +{ +public: + TestMap() { TestManager::registerTestModule(this); } + const char *getName() { return "TestMap"; } + + void runTests(IGameDef *gamedef); + + void testMaxMapgenLimit(); +}; + +static TestMap g_test_instance; + +void TestMap::runTests(IGameDef *gamedef) +{ + TEST(testMaxMapgenLimit); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestMap::testMaxMapgenLimit() +{ + // limit must end on a mapblock boundary + UASSERTEQ(int, MAX_MAP_GENERATION_LIMIT % MAP_BLOCKSIZE, MAP_BLOCKSIZE - 1); + + // objectpos_over_limit should do exactly this except the last node + // actually spans from LIMIT-0.5 to LIMIT+0.5 + float limit_times_bs = MAX_MAP_GENERATION_LIMIT * BS; + UASSERT(objectpos_over_limit(v3f(limit_times_bs-BS/2)) == false); + UASSERT(objectpos_over_limit(v3f(limit_times_bs)) == false); + UASSERT(objectpos_over_limit(v3f(limit_times_bs+BS/2)) == false); + UASSERT(objectpos_over_limit(v3f(limit_times_bs+BS)) == true); + + UASSERT(objectpos_over_limit(v3f(-limit_times_bs+BS/2)) == false); + UASSERT(objectpos_over_limit(v3f(-limit_times_bs)) == false); + UASSERT(objectpos_over_limit(v3f(-limit_times_bs-BS/2)) == false); + UASSERT(objectpos_over_limit(v3f(-limit_times_bs-BS)) == true); + + // blockpos_over_max_limit + s16 limit_block = MAX_MAP_GENERATION_LIMIT / MAP_BLOCKSIZE; + UASSERT(blockpos_over_max_limit(v3s16(limit_block)) == false); + UASSERT(blockpos_over_max_limit(v3s16(limit_block+1)) == true); + UASSERT(blockpos_over_max_limit(v3s16(-limit_block)) == false); + UASSERT(blockpos_over_max_limit(v3s16(-limit_block-1)) == true); +} diff --git a/src/unittest/test_map_settings_manager.cpp b/src/unittest/test_map_settings_manager.cpp new file mode 100644 index 0000000..17c31fe --- /dev/null +++ b/src/unittest/test_map_settings_manager.cpp @@ -0,0 +1,266 @@ + /* +Minetest +Copyright (C) 2010-2014 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "noise.h" +#include "settings.h" +#include "mapgen/mapgen_v5.h" +#include "util/sha1.h" +#include "map_settings_manager.h" + +class TestMapSettingsManager : public TestBase { +public: + TestMapSettingsManager() { TestManager::registerTestModule(this); } + const char *getName() { return "TestMapSettingsManager"; } + + void makeUserConfig(); + std::string makeMetaFile(bool make_corrupt); + + void runTests(IGameDef *gamedef); + + void testMapSettingsManager(); + void testMapMetaSaveLoad(); + void testMapMetaFailures(); +}; + +static TestMapSettingsManager g_test_instance; + +void TestMapSettingsManager::runTests(IGameDef *gamedef) +{ + TEST(testMapSettingsManager); + TEST(testMapMetaSaveLoad); + TEST(testMapMetaFailures); +} + +//////////////////////////////////////////////////////////////////////////////// + + +void check_noise_params(const NoiseParams *np1, const NoiseParams *np2) +{ + UASSERTEQ(float, np1->offset, np2->offset); + UASSERTEQ(float, np1->scale, np2->scale); + UASSERT(np1->spread == np2->spread); + UASSERTEQ(s32, np1->seed, np2->seed); + UASSERTEQ(u16, np1->octaves, np2->octaves); + UASSERTEQ(float, np1->persist, np2->persist); + UASSERTEQ(float, np1->lacunarity, np2->lacunarity); + UASSERTEQ(u32, np1->flags, np2->flags); +} + + +void TestMapSettingsManager::makeUserConfig() +{ + delete Settings::getLayer(SL_GLOBAL); + Settings *conf = Settings::createLayer(SL_GLOBAL); + + conf->set("mg_name", "v7"); + conf->set("seed", "5678"); + conf->set("water_level", "20"); + conf->set("mgv5_np_factor", "0, 12, (500, 250, 500), 920382, 5, 0.45, 3.0"); + conf->set("mgv5_np_height", "0, 15, (500, 250, 500), 841746, 5, 0.5, 3.0"); + conf->set("mgv5_np_filler_depth", "20, 1, (150, 150, 150), 261, 4, 0.7, 1.0"); + conf->set("mgv5_np_ground", "-43, 40, (80, 80, 80), 983240, 4, 0.55, 2.0"); +} + + +std::string TestMapSettingsManager::makeMetaFile(bool make_corrupt) +{ + std::string metafile = getTestTempFile(); + + const char *metafile_contents = + "mg_name = v5\n" + "seed = 1234\n" + "mg_flags = light\n" + "mgv5_np_filler_depth = 20, 1, (150, 150, 150), 261, 4, 0.7, 1.0\n" + "mgv5_np_height = 20, 10, (250, 250, 250), 84174, 4, 0.5, 1.0\n"; + + FILE *f = fopen(metafile.c_str(), "wb"); + UASSERT(f != NULL); + + fputs(metafile_contents, f); + if (!make_corrupt) + fputs("[end_of_params]\n", f); + + fclose(f); + + return metafile; +} + + +void TestMapSettingsManager::testMapSettingsManager() +{ + makeUserConfig(); + + std::string test_mapmeta_path = makeMetaFile(false); + + MapSettingsManager mgr(test_mapmeta_path); + std::string value; + + UASSERT(mgr.getMapSetting("mg_name", &value)); + UASSERT(value == "v7"); + + // Pretend we're initializing the ServerMap + UASSERT(mgr.loadMapMeta()); + + // Pretend some scripts are requesting mapgen params + UASSERT(mgr.getMapSetting("mg_name", &value)); + UASSERT(value == "v5"); + UASSERT(mgr.getMapSetting("seed", &value)); + UASSERT(value == "1234"); + UASSERT(mgr.getMapSetting("water_level", &value)); + UASSERT(value == "20"); + + // Pretend we have some mapgen settings configured from the scripting + UASSERT(mgr.setMapSetting("water_level", "15")); + UASSERT(mgr.setMapSetting("seed", "02468")); + UASSERT(mgr.setMapSetting("mg_flags", "nolight", true)); + + NoiseParams script_np_filler_depth(0, 100, v3f(200, 100, 200), 261, 4, 0.7, 2.0); + NoiseParams script_np_factor(0, 100, v3f(50, 50, 50), 920381, 3, 0.45, 2.0); + NoiseParams script_np_height(0, 100, v3f(450, 450, 450), 84174, 4, 0.5, 2.0); + NoiseParams meta_np_height(20, 10, v3f(250, 250, 250), 84174, 4, 0.5, 1.0); + NoiseParams user_np_ground(-43, 40, v3f(80, 80, 80), 983240, 4, 0.55, 2.0, NOISE_FLAG_EASED); + + mgr.setMapSettingNoiseParams("mgv5_np_filler_depth", &script_np_filler_depth, true); + mgr.setMapSettingNoiseParams("mgv5_np_height", &script_np_height); + mgr.setMapSettingNoiseParams("mgv5_np_factor", &script_np_factor); + + { + NoiseParams dummy; + mgr.getMapSettingNoiseParams("mgv5_np_factor", &dummy); + check_noise_params(&dummy, &script_np_factor); + } + + // The settings manager MUST leave user settings alone + mgr.setMapSetting("testname", "1"); + mgr.setMapSetting("testname", "1", true); + UASSERT(!Settings::getLayer(SL_GLOBAL)->exists("testname")); + + // Now make our Params and see if the values are correctly sourced + MapgenParams *params = mgr.makeMapgenParams(); + UASSERT(params->mgtype == MAPGEN_V5); + UASSERT(params->chunksize == 5); + UASSERT(params->water_level == 15); + UASSERT(params->seed == 1234); + UASSERT((params->flags & MG_LIGHT) == 0); + + MapgenV5Params *v5params = (MapgenV5Params *)params; + + check_noise_params(&v5params->np_filler_depth, &script_np_filler_depth); + check_noise_params(&v5params->np_factor, &script_np_factor); + check_noise_params(&v5params->np_height, &meta_np_height); + check_noise_params(&v5params->np_ground, &user_np_ground); + + UASSERT(mgr.setMapSetting("foobar", "25") == false); + + // Pretend the ServerMap is shutting down + UASSERT(mgr.saveMapMeta()); + + // Make sure our interface expectations are met + UASSERT(mgr.mapgen_params == params); + UASSERT(mgr.makeMapgenParams() == params); + +#if 0 + // TODO(paramat or hmmmm): change this to compare the result against a static file + + // Load the resulting map_meta.txt and make sure it contains what we expect + unsigned char expected_contents_hash[20] = { + 0x48, 0x3f, 0x88, 0x5a, 0xc0, 0x7a, 0x14, 0x48, 0xa4, 0x71, + 0x78, 0x56, 0x95, 0x2d, 0xdc, 0x6a, 0xf7, 0x61, 0x36, 0x5f + }; + + SHA1 ctx; + std::string metafile_contents; + UASSERT(fs::ReadFile(test_mapmeta_path, metafile_contents)); + ctx.addBytes(&metafile_contents[0], metafile_contents.size()); + unsigned char *sha1_result = ctx.getDigest(); + int resultdiff = memcmp(sha1_result, expected_contents_hash, 20); + free(sha1_result); + + UASSERT(!resultdiff); +#endif +} + + +void TestMapSettingsManager::testMapMetaSaveLoad() +{ + std::string path = getTestTempDirectory() + + DIR_DELIM + "foobar" + DIR_DELIM + "map_meta.txt"; + + makeUserConfig(); + Settings &conf = *Settings::getLayer(SL_GLOBAL); + + // There cannot be two MapSettingsManager + // copy the mapgen params to compare them + MapgenParams params1, params2; + // Create a set of mapgen params and save them to map meta + { + conf.set("seed", "12345"); + conf.set("water_level", "5"); + MapSettingsManager mgr(path); + MapgenParams *params = mgr.makeMapgenParams(); + UASSERT(params); + params1 = *params; + params1.bparams = nullptr; // No double-free + UASSERT(mgr.saveMapMeta()); + } + + // Now try loading the map meta to mapgen params + { + conf.set("seed", "67890"); + conf.set("water_level", "32"); + MapSettingsManager mgr(path); + UASSERT(mgr.loadMapMeta()); + MapgenParams *params = mgr.makeMapgenParams(); + UASSERT(params); + params2 = *params; + params2.bparams = nullptr; // No double-free + } + + // Check that both results are correct + UASSERTEQ(u64, params1.seed, 12345); + UASSERTEQ(s16, params1.water_level, 5); + UASSERTEQ(u64, params2.seed, 12345); + UASSERTEQ(s16, params2.water_level, 5); +} + + +void TestMapSettingsManager::testMapMetaFailures() +{ + std::string test_mapmeta_path; + + // Check to see if it'll fail on a non-existent map meta file + { + test_mapmeta_path = "woobawooba/fgdfg/map_meta.txt"; + UASSERT(!fs::PathExists(test_mapmeta_path)); + + MapSettingsManager mgr1(test_mapmeta_path); + UASSERT(!mgr1.loadMapMeta()); + } + + // Check to see if it'll fail on a corrupt map meta file + { + test_mapmeta_path = makeMetaFile(true); + UASSERT(fs::PathExists(test_mapmeta_path)); + + MapSettingsManager mgr2(test_mapmeta_path); + UASSERT(!mgr2.loadMapMeta()); + } +} diff --git a/src/unittest/test_mapnode.cpp b/src/unittest/test_mapnode.cpp new file mode 100644 index 0000000..365ee0c --- /dev/null +++ b/src/unittest/test_mapnode.cpp @@ -0,0 +1,57 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "gamedef.h" +#include "nodedef.h" +#include "content_mapnode.h" + +class TestMapNode : public TestBase +{ +public: + TestMapNode() { TestManager::registerTestModule(this); } + const char *getName() { return "TestMapNode"; } + + void runTests(IGameDef *gamedef); + + void testNodeProperties(const NodeDefManager *nodedef); +}; + +static TestMapNode g_test_instance; + +void TestMapNode::runTests(IGameDef *gamedef) +{ + TEST(testNodeProperties, gamedef->getNodeDefManager()); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestMapNode::testNodeProperties(const NodeDefManager *nodedef) +{ + MapNode n(CONTENT_AIR); + + UASSERT(n.getContent() == CONTENT_AIR); + UASSERT(n.getLight(LIGHTBANK_DAY, nodedef) == 0); + UASSERT(n.getLight(LIGHTBANK_NIGHT, nodedef) == 0); + + // Transparency + n.setContent(CONTENT_AIR); + UASSERT(nodedef->get(n).light_propagates == true); +} diff --git a/src/unittest/test_mod/test_mod/init.lua b/src/unittest/test_mod/test_mod/init.lua new file mode 100644 index 0000000..724a863 --- /dev/null +++ b/src/unittest/test_mod/test_mod/init.lua @@ -0,0 +1 @@ +-- deliberately empty diff --git a/src/unittest/test_mod/test_mod/mod.conf b/src/unittest/test_mod/test_mod/mod.conf new file mode 100644 index 0000000..56c64b2 --- /dev/null +++ b/src/unittest/test_mod/test_mod/mod.conf @@ -0,0 +1,2 @@ +name = test_mod +description = A mod doing nothing, to test if MINETEST_MOD_PATH is recognised diff --git a/src/unittest/test_modchannels.cpp b/src/unittest/test_modchannels.cpp new file mode 100644 index 0000000..069f439 --- /dev/null +++ b/src/unittest/test_modchannels.cpp @@ -0,0 +1,76 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "gamedef.h" +#include "modchannels.h" + +class TestModChannels : public TestBase +{ +public: + TestModChannels() { TestManager::registerTestModule(this); } + const char *getName() { return "TestModChannels"; } + + void runTests(IGameDef *gamedef); + + void testJoinChannel(IGameDef *gamedef); + void testLeaveChannel(IGameDef *gamedef); + void testSendMessageToChannel(IGameDef *gamedef); +}; + +static TestModChannels g_test_instance; + +void TestModChannels::runTests(IGameDef *gamedef) +{ + TEST(testJoinChannel, gamedef); + TEST(testLeaveChannel, gamedef); + TEST(testSendMessageToChannel, gamedef); +} + +void TestModChannels::testJoinChannel(IGameDef *gamedef) +{ + // Test join + UASSERT(gamedef->joinModChannel("test_join_channel")); + // Test join (fail, already join) + UASSERT(!gamedef->joinModChannel("test_join_channel")); +} + +void TestModChannels::testLeaveChannel(IGameDef *gamedef) +{ + // Test leave (not joined) + UASSERT(!gamedef->leaveModChannel("test_leave_channel")); + + UASSERT(gamedef->joinModChannel("test_leave_channel")); + + // Test leave (joined) + UASSERT(gamedef->leaveModChannel("test_leave_channel")); +} + +void TestModChannels::testSendMessageToChannel(IGameDef *gamedef) +{ + // Test sendmsg (not joined) + UASSERT(!gamedef->sendModChannelMessage( + "test_sendmsg_channel", "testmsgchannel")); + + UASSERT(gamedef->joinModChannel("test_sendmsg_channel")); + + // Test sendmsg (joined) + UASSERT(gamedef->sendModChannelMessage("test_sendmsg_channel", "testmsgchannel")); +} diff --git a/src/unittest/test_modmetadatadatabase.cpp b/src/unittest/test_modmetadatadatabase.cpp new file mode 100644 index 0000000..be97fae --- /dev/null +++ b/src/unittest/test_modmetadatadatabase.cpp @@ -0,0 +1,253 @@ +/* +Minetest +Copyright (C) 2018 bendeutsch, Ben Deutsch <ben@bendeutsch.de> +Copyright (C) 2021 TurkeyMcMac, Jude Melton-Houghton <jwmhjwmh@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +// This file is an edited copy of test_authdatabase.cpp + +#include "test.h" + +#include <algorithm> +#include "database/database-files.h" +#include "database/database-sqlite3.h" +#include "filesys.h" + +namespace +{ +// Anonymous namespace to create classes that are only +// visible to this file +// +// These are helpers that return a *ModMetadataDatabase and +// allow us to run the same tests on different databases and +// database acquisition strategies. + +class ModMetadataDatabaseProvider +{ +public: + virtual ~ModMetadataDatabaseProvider() = default; + virtual ModMetadataDatabase *getModMetadataDatabase() = 0; +}; + +class FixedProvider : public ModMetadataDatabaseProvider +{ +public: + FixedProvider(ModMetadataDatabase *mod_meta_db) : mod_meta_db(mod_meta_db){}; + virtual ~FixedProvider(){}; + virtual ModMetadataDatabase *getModMetadataDatabase() { return mod_meta_db; }; + +private: + ModMetadataDatabase *mod_meta_db; +}; + +class FilesProvider : public ModMetadataDatabaseProvider +{ +public: + FilesProvider(const std::string &dir) : dir(dir){}; + virtual ~FilesProvider() + { + if (mod_meta_db) + mod_meta_db->endSave(); + delete mod_meta_db; + } + virtual ModMetadataDatabase *getModMetadataDatabase() + { + if (mod_meta_db) + mod_meta_db->endSave(); + delete mod_meta_db; + mod_meta_db = new ModMetadataDatabaseFiles(dir); + mod_meta_db->beginSave(); + return mod_meta_db; + }; + +private: + std::string dir; + ModMetadataDatabase *mod_meta_db = nullptr; +}; + +class SQLite3Provider : public ModMetadataDatabaseProvider +{ +public: + SQLite3Provider(const std::string &dir) : dir(dir){}; + virtual ~SQLite3Provider() + { + if (mod_meta_db) + mod_meta_db->endSave(); + delete mod_meta_db; + } + virtual ModMetadataDatabase *getModMetadataDatabase() + { + if (mod_meta_db) + mod_meta_db->endSave(); + delete mod_meta_db; + mod_meta_db = new ModMetadataDatabaseSQLite3(dir); + mod_meta_db->beginSave(); + return mod_meta_db; + }; + +private: + std::string dir; + ModMetadataDatabase *mod_meta_db = nullptr; +}; +} + +class TestModMetadataDatabase : public TestBase +{ +public: + TestModMetadataDatabase() { TestManager::registerTestModule(this); } + const char *getName() { return "TestModMetadataDatabase"; } + + void runTests(IGameDef *gamedef); + void runTestsForCurrentDB(); + + void testRecallFail(); + void testCreate(); + void testRecall(); + void testChange(); + void testRecallChanged(); + void testListMods(); + void testRemove(); + +private: + ModMetadataDatabaseProvider *mod_meta_provider; +}; + +static TestModMetadataDatabase g_test_instance; + +void TestModMetadataDatabase::runTests(IGameDef *gamedef) +{ + // fixed directory, for persistence + thread_local const std::string test_dir = getTestTempDirectory(); + + // Each set of tests is run twice for each database type: + // one where we reuse the same ModMetadataDatabase object (to test local caching), + // and one where we create a new ModMetadataDatabase object for each call + // (to test actual persistence). + + rawstream << "-------- Files database (same object)" << std::endl; + + ModMetadataDatabase *mod_meta_db = new ModMetadataDatabaseFiles(test_dir); + mod_meta_provider = new FixedProvider(mod_meta_db); + + runTestsForCurrentDB(); + + delete mod_meta_db; + delete mod_meta_provider; + + // reset database + fs::RecursiveDelete(test_dir + DIR_DELIM + "mod_storage"); + + rawstream << "-------- Files database (new objects)" << std::endl; + + mod_meta_provider = new FilesProvider(test_dir); + + runTestsForCurrentDB(); + + delete mod_meta_provider; + + rawstream << "-------- SQLite3 database (same object)" << std::endl; + + mod_meta_db = new ModMetadataDatabaseSQLite3(test_dir); + mod_meta_provider = new FixedProvider(mod_meta_db); + + runTestsForCurrentDB(); + + delete mod_meta_db; + delete mod_meta_provider; + + // reset database + fs::DeleteSingleFileOrEmptyDirectory(test_dir + DIR_DELIM + "mod_storage.sqlite"); + + rawstream << "-------- SQLite3 database (new objects)" << std::endl; + + mod_meta_provider = new SQLite3Provider(test_dir); + + runTestsForCurrentDB(); + + delete mod_meta_provider; +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestModMetadataDatabase::runTestsForCurrentDB() +{ + TEST(testRecallFail); + TEST(testCreate); + TEST(testRecall); + TEST(testChange); + TEST(testRecallChanged); + TEST(testListMods); + TEST(testRemove); + TEST(testRecallFail); +} + +void TestModMetadataDatabase::testRecallFail() +{ + ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase(); + StringMap recalled; + mod_meta_db->getModEntries("mod1", &recalled); + UASSERT(recalled.empty()); +} + +void TestModMetadataDatabase::testCreate() +{ + ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase(); + StringMap recalled; + UASSERT(mod_meta_db->setModEntry("mod1", "key1", "value1")); +} + +void TestModMetadataDatabase::testRecall() +{ + ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase(); + StringMap recalled; + mod_meta_db->getModEntries("mod1", &recalled); + UASSERT(recalled.size() == 1); + UASSERT(recalled["key1"] == "value1"); +} + +void TestModMetadataDatabase::testChange() +{ + ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase(); + StringMap recalled; + UASSERT(mod_meta_db->setModEntry("mod1", "key1", "value2")); +} + +void TestModMetadataDatabase::testRecallChanged() +{ + ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase(); + StringMap recalled; + mod_meta_db->getModEntries("mod1", &recalled); + UASSERT(recalled.size() == 1); + UASSERT(recalled["key1"] == "value2"); +} + +void TestModMetadataDatabase::testListMods() +{ + ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase(); + UASSERT(mod_meta_db->setModEntry("mod2", "key1", "value1")); + std::vector<std::string> mod_list; + mod_meta_db->listMods(&mod_list); + UASSERT(mod_list.size() == 2); + UASSERT(std::find(mod_list.cbegin(), mod_list.cend(), "mod1") != mod_list.cend()); + UASSERT(std::find(mod_list.cbegin(), mod_list.cend(), "mod2") != mod_list.cend()); +} + +void TestModMetadataDatabase::testRemove() +{ + ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase(); + UASSERT(mod_meta_db->removeModEntry("mod1", "key1")); +} diff --git a/src/unittest/test_nodedef.cpp b/src/unittest/test_nodedef.cpp new file mode 100644 index 0000000..acf6697 --- /dev/null +++ b/src/unittest/test_nodedef.cpp @@ -0,0 +1,67 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <sstream> + +#include "gamedef.h" +#include "nodedef.h" +#include "network/networkprotocol.h" + +class TestNodeDef : public TestBase +{ +public: + TestNodeDef() { TestManager::registerTestModule(this); } + const char *getName() { return "TestNodeDef"; } + + void runTests(IGameDef *gamedef); + + void testContentFeaturesSerialization(); +}; + +static TestNodeDef g_test_instance; + +void TestNodeDef::runTests(IGameDef *gamedef) +{ + TEST(testContentFeaturesSerialization); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestNodeDef::testContentFeaturesSerialization() +{ + ContentFeatures f; + + f.name = "default:stone"; + for (TileDef &tiledef : f.tiledef) + tiledef.name = "default_stone.png"; + f.is_ground_content = true; + + std::ostringstream os(std::ios::binary); + f.serialize(os, LATEST_PROTOCOL_VERSION); + // verbosestream<<"Test ContentFeatures size: "<<os.str().size()<<std::endl; + + std::istringstream is(os.str(), std::ios::binary); + ContentFeatures f2; + f2.deSerialize(is, LATEST_PROTOCOL_VERSION); + + UASSERT(f.walkable == f2.walkable); + UASSERT(f.node_box.type == f2.node_box.type); +} diff --git a/src/unittest/test_noderesolver.cpp b/src/unittest/test_noderesolver.cpp new file mode 100644 index 0000000..ed66093 --- /dev/null +++ b/src/unittest/test_noderesolver.cpp @@ -0,0 +1,212 @@ +/* +Minetest +Copyright (C) 2010-2014 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "util/numeric.h" +#include "exceptions.h" +#include "gamedef.h" +#include "nodedef.h" + +#include <algorithm> + + +class TestNodeResolver : public TestBase { +public: + TestNodeResolver() { TestManager::registerTestModule(this); } + const char *getName() { return "TestNodeResolver"; } + + void runTests(IGameDef *gamedef); + + void testNodeResolving(NodeDefManager *ndef); + void testPendingResolveCancellation(NodeDefManager *ndef); + void testDirectResolveMethod(NodeDefManager *ndef); + void testNoneResolveMethod(NodeDefManager *ndef); +}; + +static TestNodeResolver g_test_instance; + +void TestNodeResolver::runTests(IGameDef *gamedef) +{ + NodeDefManager *ndef = + (NodeDefManager *)gamedef->getNodeDefManager(); + + ndef->resetNodeResolveState(); + TEST(testNodeResolving, ndef); + + ndef->resetNodeResolveState(); + TEST(testPendingResolveCancellation, ndef); +} + +class Foobar : public NodeResolver { +public: + friend class TestNodeResolver; // m_ndef + + void resolveNodeNames(); + + content_t test_nr_node1; + content_t test_nr_node2; + content_t test_nr_node3; + content_t test_nr_node4; + content_t test_nr_node5; + std::vector<content_t> test_nr_list; + std::vector<content_t> test_nr_list_group; + std::vector<content_t> test_nr_list_required; + std::vector<content_t> test_nr_list_empty; +}; + +class Foobaz : public NodeResolver { +public: + void resolveNodeNames(); + + content_t test_content1; + content_t test_content2; +}; + +//////////////////////////////////////////////////////////////////////////////// + +void Foobar::resolveNodeNames() +{ + UASSERT(getIdFromNrBacklog(&test_nr_node1, "", CONTENT_IGNORE) == true); + UASSERT(getIdsFromNrBacklog(&test_nr_list) == true); + UASSERT(getIdsFromNrBacklog(&test_nr_list_group) == true); + UASSERT(getIdsFromNrBacklog(&test_nr_list_required, + true, CONTENT_AIR) == false); + UASSERT(getIdsFromNrBacklog(&test_nr_list_empty) == true); + + UASSERT(getIdFromNrBacklog(&test_nr_node2, "", CONTENT_IGNORE) == true); + UASSERT(getIdFromNrBacklog(&test_nr_node3, + "default:brick", CONTENT_IGNORE) == true); + UASSERT(getIdFromNrBacklog(&test_nr_node4, + "default:gobbledygook", CONTENT_AIR) == false); + UASSERT(getIdFromNrBacklog(&test_nr_node5, "", CONTENT_IGNORE) == false); +} + + +void Foobaz::resolveNodeNames() +{ + UASSERT(getIdFromNrBacklog(&test_content1, "", CONTENT_IGNORE) == true); + UASSERT(getIdFromNrBacklog(&test_content2, "", CONTENT_IGNORE) == false); +} + + +void TestNodeResolver::testNodeResolving(NodeDefManager *ndef) +{ + Foobar foobar; + size_t i; + + foobar.m_nodenames.emplace_back("default:torch"); + + foobar.m_nodenames.emplace_back("default:dirt_with_grass"); + foobar.m_nodenames.emplace_back("default:water"); + foobar.m_nodenames.emplace_back("default:abloobloobloo"); + foobar.m_nodenames.emplace_back("default:stone"); + foobar.m_nodenames.emplace_back("default:shmegoldorf"); + foobar.m_nnlistsizes.push_back(5); + + foobar.m_nodenames.emplace_back("group:liquids"); + foobar.m_nnlistsizes.push_back(1); + + foobar.m_nodenames.emplace_back("default:warf"); + foobar.m_nodenames.emplace_back("default:stone"); + foobar.m_nodenames.emplace_back("default:bloop"); + foobar.m_nnlistsizes.push_back(3); + + foobar.m_nnlistsizes.push_back(0); + + foobar.m_nodenames.emplace_back("default:brick"); + foobar.m_nodenames.emplace_back("default:desert_stone"); + foobar.m_nodenames.emplace_back("default:shnitzle"); + + ndef->pendNodeResolve(&foobar); + UASSERT(foobar.m_ndef == ndef); + + ndef->setNodeRegistrationStatus(true); + ndef->runNodeResolveCallbacks(); + + // Check that we read single nodes successfully + UASSERTEQ(content_t, foobar.test_nr_node1, t_CONTENT_TORCH); + UASSERTEQ(content_t, foobar.test_nr_node2, t_CONTENT_BRICK); + UASSERTEQ(content_t, foobar.test_nr_node3, t_CONTENT_BRICK); + UASSERTEQ(content_t, foobar.test_nr_node4, CONTENT_AIR); + UASSERTEQ(content_t, foobar.test_nr_node5, CONTENT_IGNORE); + + // Check that we read all the regular list items + static const content_t expected_test_nr_list[] = { + t_CONTENT_GRASS, + t_CONTENT_WATER, + t_CONTENT_STONE, + }; + UASSERTEQ(size_t, foobar.test_nr_list.size(), 3); + for (i = 0; i != foobar.test_nr_list.size(); i++) + UASSERTEQ(content_t, foobar.test_nr_list[i], expected_test_nr_list[i]); + + // Check that we read all the list items that were from a group entry + static const content_t expected_test_nr_list_group[] = { + t_CONTENT_WATER, + t_CONTENT_LAVA, + }; + UASSERTEQ(size_t, foobar.test_nr_list_group.size(), 2); + for (i = 0; i != foobar.test_nr_list_group.size(); i++) { + UASSERT(CONTAINS(foobar.test_nr_list_group, + expected_test_nr_list_group[i])); + } + + // Check that we read all the items we're able to in a required list + static const content_t expected_test_nr_list_required[] = { + CONTENT_AIR, + t_CONTENT_STONE, + CONTENT_AIR, + }; + UASSERTEQ(size_t, foobar.test_nr_list_required.size(), 3); + for (i = 0; i != foobar.test_nr_list_required.size(); i++) + UASSERTEQ(content_t, foobar.test_nr_list_required[i], + expected_test_nr_list_required[i]); + + // Check that the edge case of 0 is successful + UASSERTEQ(size_t, foobar.test_nr_list_empty.size(), 0); +} + + +void TestNodeResolver::testPendingResolveCancellation(NodeDefManager *ndef) +{ + Foobaz foobaz1; + foobaz1.test_content1 = 1234; + foobaz1.test_content2 = 5678; + foobaz1.m_nodenames.emplace_back("default:dirt_with_grass"); + foobaz1.m_nodenames.emplace_back("default:abloobloobloo"); + ndef->pendNodeResolve(&foobaz1); + + Foobaz foobaz2; + foobaz2.test_content1 = 1234; + foobaz2.test_content2 = 5678; + foobaz2.m_nodenames.emplace_back("default:dirt_with_grass"); + foobaz2.m_nodenames.emplace_back("default:abloobloobloo"); + ndef->pendNodeResolve(&foobaz2); + + ndef->cancelNodeResolveCallback(&foobaz1); + + ndef->setNodeRegistrationStatus(true); + ndef->runNodeResolveCallbacks(); + + UASSERT(foobaz1.test_content1 == 1234); + UASSERT(foobaz1.test_content2 == 5678); + UASSERT(foobaz2.test_content1 == t_CONTENT_GRASS); + UASSERT(foobaz2.test_content2 == CONTENT_IGNORE); +} diff --git a/src/unittest/test_noise.cpp b/src/unittest/test_noise.cpp new file mode 100644 index 0000000..12b155f --- /dev/null +++ b/src/unittest/test_noise.cpp @@ -0,0 +1,340 @@ +/* +Minetest +Copyright (C) 2010-2014 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <cmath> +#include "exceptions.h" +#include "noise.h" + +class TestNoise : public TestBase { +public: + TestNoise() { TestManager::registerTestModule(this); } + const char *getName() { return "TestNoise"; } + + void runTests(IGameDef *gamedef); + + void testNoise2dAtOriginWithZeroSeed(); + void testNoise2dWithMaxSeed(); + void testNoise2dWithFunPrimes(); + void testNoise2dPoint(); + void testNoise2dBulk(); + void testNoise3dAtOriginWithZeroSeed(); + void testNoise3dWithMaxSeed(); + void testNoise3dWithFunPrimes(); + void testNoise3dPoint(); + void testNoise3dBulk(); + void testNoiseInvalidParams(); + + static const float expected_2d_results[10 * 10]; + static const float expected_3d_results[10 * 10 * 10]; +}; + +static TestNoise g_test_instance; + +void TestNoise::runTests(IGameDef *gamedef) +{ + TEST(testNoise2dAtOriginWithZeroSeed); + TEST(testNoise2dWithMaxSeed); + TEST(testNoise2dWithFunPrimes); + TEST(testNoise2dPoint); + TEST(testNoise2dBulk); + TEST(testNoise3dAtOriginWithZeroSeed); + TEST(testNoise3dWithMaxSeed); + TEST(testNoise3dWithFunPrimes); + TEST(testNoise3dPoint); + TEST(testNoise3dBulk); + TEST(testNoiseInvalidParams); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestNoise::testNoise2dAtOriginWithZeroSeed() +{ + float actual{ noise2d(0, 0, 0) }; + constexpr float expected{ -0.281791f }; + UASSERT(std::fabs(actual - expected) <= 0.00001); +} + +void TestNoise::testNoise2dWithMaxSeed() +{ + float actual{ noise2d(4096, 4096, 2147483647) }; + constexpr float expected{ 0.950606f }; + UASSERT(std::fabs(actual - expected) <= 0.00001); +} + +void TestNoise::testNoise2dWithFunPrimes() +{ + float actual{ noise2d(-3947, -2333, 7027) }; + constexpr float expected{ -0.294907f }; + UASSERT(std::fabs(actual - expected) <= 0.00001); +} + +void TestNoise::testNoise2dPoint() +{ + NoiseParams np_normal(20, 40, v3f(50, 50, 50), 9, 5, 0.6, 2.0); + + u32 i = 0; + for (u32 y = 0; y != 10; y++) + for (u32 x = 0; x != 10; x++, i++) { + float actual = NoisePerlin2D(&np_normal, x, y, 1337); + float expected = expected_2d_results[i]; + UASSERT(std::fabs(actual - expected) <= 0.00001); + } +} + +void TestNoise::testNoise2dBulk() +{ + NoiseParams np_normal(20, 40, v3f(50, 50, 50), 9, 5, 0.6, 2.0); + Noise noise_normal_2d(&np_normal, 1337, 10, 10); + float *noisevals = noise_normal_2d.perlinMap2D(0, 0, NULL); + + for (u32 i = 0; i != 10 * 10; i++) { + float actual = noisevals[i]; + float expected = expected_2d_results[i]; + UASSERT(std::fabs(actual - expected) <= 0.00001); + } +} + +void TestNoise::testNoise3dAtOriginWithZeroSeed() +{ + float actual{ noise2d(0, 0, 0) }; + constexpr float expected{ -0.281791f }; + UASSERT(std::fabs(actual - expected) <= 0.00001); +} + +void TestNoise::testNoise3dWithMaxSeed() +{ + float actual{ noise3d(4096, 4096, 4096, 2147483647) }; + constexpr float expected{ -0.775243f }; + UASSERT(std::fabs(actual - expected) <= 0.00001); +} + +void TestNoise::testNoise3dWithFunPrimes() +{ + float actual{ noise2d(3903, -1723, 7411) }; + constexpr float expected{ 0.989124f }; + UASSERT(std::fabs(actual - expected) <= 0.00001); +} + +void TestNoise::testNoise3dPoint() +{ + NoiseParams np_normal(20, 40, v3f(50, 50, 50), 9, 5, 0.6, 2.0); + + u32 i = 0; + for (u32 z = 0; z != 10; z++) + for (u32 y = 0; y != 10; y++) + for (u32 x = 0; x != 10; x++, i++) { + float actual = NoisePerlin3D(&np_normal, x, y, z, 1337); + float expected = expected_3d_results[i]; + UASSERT(std::fabs(actual - expected) <= 0.00001); + } +} + +void TestNoise::testNoise3dBulk() +{ + NoiseParams np_normal(20, 40, v3f(50, 50, 50), 9, 5, 0.6, 2.0); + Noise noise_normal_3d(&np_normal, 1337, 10, 10, 10); + float *noisevals = noise_normal_3d.perlinMap3D(0, 0, 0, NULL); + + for (u32 i = 0; i != 10 * 10 * 10; i++) { + float actual = noisevals[i]; + float expected = expected_3d_results[i]; + UASSERT(std::fabs(actual - expected) <= 0.00001); + } +} + +void TestNoise::testNoiseInvalidParams() +{ + bool exception_thrown = false; + + try { + NoiseParams np_highmem(4, 70, v3f(1, 1, 1), 5, 60, 0.7, 10.0); + Noise noise_highmem_3d(&np_highmem, 1337, 200, 200, 200); + noise_highmem_3d.perlinMap3D(0, 0, 0, NULL); + } catch (InvalidNoiseParamsException &) { + exception_thrown = true; + } + + UASSERT(exception_thrown); +} + +const float TestNoise::expected_2d_results[10 * 10] = { + 19.11726, 18.49626, 16.48476, 15.02135, 14.75713, 16.26008, 17.54822, + 18.06860, 18.57016, 18.48407, 18.49649, 17.89160, 15.94162, 14.54901, + 14.31298, 15.72643, 16.94669, 17.55494, 18.58796, 18.87925, 16.08101, + 15.53764, 13.83844, 12.77139, 12.73648, 13.95632, 14.97904, 15.81829, + 18.37694, 19.73759, 13.19182, 12.71924, 11.34560, 10.78025, 11.18980, + 12.52303, 13.45012, 14.30001, 17.43298, 19.15244, 10.93217, 10.48625, + 9.30923, 9.18632, 10.16251, 12.11264, 13.19697, 13.80801, 16.39567, + 17.66203, 10.40222, 9.86070, 8.47223, 8.45471, 10.04780, 13.54730, + 15.33709, 15.48503, 16.46177, 16.52508, 10.80333, 10.19045, 8.59420, + 8.47646, 10.22676, 14.43173, 16.48353, 16.24859, 16.20863, 15.52847, + 11.01179, 10.45209, 8.98678, 8.83986, 10.43004, 14.46054, 16.29387, + 15.73521, 15.01744, 13.85542, 10.55201, 10.33375, 9.85102, 10.07821, + 11.58235, 15.62046, 17.35505, 16.13181, 12.66011, 9.51853, 11.50994, + 11.54074, 11.77989, 12.29790, 13.76139, 17.81982, 19.49008, 17.79470, + 12.34344, 7.78363, +}; + +const float TestNoise::expected_3d_results[10 * 10 * 10] = { + 19.11726, 18.01059, 16.90392, 15.79725, 16.37154, 17.18597, 18.00040, + 18.33467, 18.50889, 18.68311, 17.85386, 16.90585, 15.95785, 15.00985, + 15.61132, 16.43415, 17.25697, 17.95415, 18.60942, 19.26471, 16.59046, + 15.80112, 15.01178, 14.22244, 14.85110, 15.68232, 16.51355, 17.57361, + 18.70996, 19.84631, 15.32705, 14.69638, 14.06571, 13.43504, 14.09087, + 14.93050, 15.77012, 17.19309, 18.81050, 20.42790, 15.06729, 14.45855, + 13.84981, 13.24107, 14.39364, 15.79782, 17.20201, 18.42640, 19.59085, + 20.75530, 14.95090, 14.34456, 13.73821, 13.13187, 14.84825, 16.89645, + 18.94465, 19.89025, 20.46832, 21.04639, 14.83452, 14.23057, 13.62662, + 13.02267, 15.30287, 17.99508, 20.68730, 21.35411, 21.34580, 21.33748, + 15.39817, 15.03590, 14.67364, 14.31137, 16.78242, 19.65824, 22.53405, + 22.54626, 21.60395, 20.66164, 16.18850, 16.14768, 16.10686, 16.06603, + 18.60362, 21.50956, 24.41549, 23.64784, 21.65566, 19.66349, 16.97884, + 17.25946, 17.54008, 17.82069, 20.42482, 23.36088, 26.29694, 24.74942, + 21.70738, 18.66534, 18.78506, 17.51834, 16.25162, 14.98489, 15.14217, + 15.50287, 15.86357, 16.40597, 17.00895, 17.61193, 18.20160, 16.98795, + 15.77430, 14.56065, 14.85059, 15.35533, 15.86007, 16.63399, 17.49763, + 18.36128, 17.61814, 16.45757, 15.29699, 14.13641, 14.55902, 15.20779, + 15.85657, 16.86200, 17.98632, 19.11064, 17.03468, 15.92718, 14.81968, + 13.71218, 14.26744, 15.06026, 15.85306, 17.09001, 18.47501, 19.86000, + 16.67870, 15.86256, 15.04641, 14.23026, 15.31397, 16.66909, 18.02420, + 18.89042, 19.59369, 20.29695, 16.35522, 15.86447, 15.37372, 14.88297, + 16.55165, 18.52883, 20.50600, 20.91547, 20.80237, 20.68927, 16.03174, + 15.86639, 15.70103, 15.53568, 17.78933, 20.38857, 22.98780, 22.94051, + 22.01105, 21.08159, 16.42434, 16.61407, 16.80381, 16.99355, 19.16133, + 21.61169, 24.06204, 23.65252, 22.28970, 20.92689, 17.05562, 17.61035, + 18.16508, 18.71981, 20.57809, 22.62260, 24.66711, 23.92686, 22.25835, + 20.58984, 17.68691, 18.60663, 19.52635, 20.44607, 21.99486, 23.63352, + 25.27217, 24.20119, 22.22699, 20.25279, 18.45285, 17.02608, 15.59931, + 14.17254, 13.91279, 13.81976, 13.72674, 14.47727, 15.50900, 16.54073, + 18.54934, 17.07005, 15.59076, 14.11146, 14.08987, 14.27651, 14.46316, + 15.31383, 16.38584, 17.45785, 18.64582, 17.11401, 15.58220, 14.05039, + 14.26694, 14.73326, 15.19958, 16.15038, 17.26268, 18.37498, 18.74231, + 17.15798, 15.57364, 13.98932, 14.44402, 15.19001, 15.93600, 16.98694, + 18.13952, 19.29210, 18.29012, 17.26656, 16.24301, 15.21946, 16.23430, + 17.54035, 18.84639, 19.35445, 19.59653, 19.83860, 17.75954, 17.38438, + 17.00923, 16.63407, 18.25505, 20.16120, 22.06734, 21.94068, 21.13642, + 20.33215, 17.22896, 17.50220, 17.77544, 18.04868, 20.27580, 22.78205, + 25.28829, 24.52691, 22.67631, 20.82571, 17.45050, 18.19224, 18.93398, + 19.67573, 21.54024, 23.56514, 25.59004, 24.75878, 22.97546, 21.19213, + 17.92274, 19.07302, 20.22330, 21.37358, 22.55256, 23.73565, 24.91873, + 24.20587, 22.86103, 21.51619, 18.39499, 19.95381, 21.51263, 23.07145, + 23.56490, 23.90615, 24.24741, 23.65296, 22.74660, 21.84024, 18.12065, + 16.53382, 14.94700, 13.36018, 12.68341, 12.13666, 11.58990, 12.54858, + 14.00906, 15.46955, 18.89708, 17.15214, 15.40721, 13.66227, 13.32914, + 13.19769, 13.06625, 13.99367, 15.27405, 16.55443, 19.67351, 17.77046, + 15.86741, 13.96436, 13.97486, 14.25873, 14.54260, 15.43877, 16.53904, + 17.63931, 20.44994, 18.38877, 16.32761, 14.26645, 14.62059, 15.31977, + 16.01895, 16.88387, 17.80403, 18.72419, 19.90153, 18.67057, 17.43962, + 16.20866, 17.15464, 18.41161, 19.66858, 19.81848, 19.59936, 19.38024, + 19.16386, 18.90429, 18.64473, 18.38517, 19.95845, 21.79357, 23.62868, + 22.96589, 21.47046, 19.97503, 18.42618, 19.13802, 19.84985, 20.56168, + 22.76226, 25.17553, 27.58879, 26.11330, 23.34156, 20.56982, 18.47667, + 19.77041, 21.06416, 22.35790, 23.91914, 25.51859, 27.11804, 25.86504, + 23.66121, 21.45738, 18.78986, 20.53570, 22.28153, 24.02736, 24.52704, + 24.84869, 25.17035, 24.48488, 23.46371, 22.44254, 19.10306, 21.30098, + 23.49890, 25.69682, 25.13494, 24.17879, 23.22265, 23.10473, 23.26621, + 23.42769, 17.93453, 16.72707, 15.51962, 14.31216, 12.96039, 11.58800, + 10.21561, 11.29675, 13.19573, 15.09471, 18.05853, 16.85308, 15.64762, + 14.44216, 13.72634, 13.08047, 12.43459, 13.48912, 15.11045, 16.73179, + 18.18253, 16.97908, 15.77562, 14.57217, 14.49229, 14.57293, 14.65357, + 15.68150, 17.02518, 18.36887, 18.30654, 17.10508, 15.90363, 14.70217, + 15.25825, 16.06540, 16.87255, 17.87387, 18.93991, 20.00595, 17.54117, + 17.32369, 17.10622, 16.88875, 18.07494, 19.46166, 20.84837, 21.12988, + 21.04298, 20.95609, 16.64874, 17.55554, 18.46234, 19.36913, 21.18461, + 23.12989, 25.07517, 24.53784, 23.17297, 21.80810, 15.75632, 17.78738, + 19.81845, 21.84951, 24.29427, 26.79812, 29.30198, 27.94580, 25.30295, + 22.66010, 15.98046, 18.43027, 20.88008, 23.32989, 25.21976, 27.02964, + 28.83951, 27.75863, 25.71416, 23.66970, 16.57679, 19.21017, 21.84355, + 24.47693, 25.41719, 26.11557, 26.81396, 26.37308, 25.55245, 24.73182, + 17.17313, 19.99008, 22.80702, 25.62397, 25.61462, 25.20151, 24.78840, + 24.98753, 25.39074, 25.79395, 17.76927, 17.01824, 16.26722, 15.51620, + 13.45256, 11.20141, 8.95025, 10.14162, 12.48049, 14.81936, 17.05051, + 16.49955, 15.94860, 15.39764, 14.28896, 13.10061, 11.91225, 13.10109, + 15.08232, 17.06355, 16.33175, 15.98086, 15.62998, 15.27909, 15.12537, + 14.99981, 14.87425, 16.06056, 17.68415, 19.30775, 15.61299, 15.46217, + 15.31136, 15.16054, 15.96177, 16.89901, 17.83625, 19.02003, 20.28599, + 21.55194, 14.61341, 15.58383, 16.55426, 17.52469, 18.99524, 20.53725, + 22.07925, 22.56233, 22.69243, 22.82254, 13.57371, 15.79697, 18.02024, + 20.24351, 22.34258, 24.42392, 26.50526, 26.18790, 25.07097, 23.95404, + 12.53401, 16.01011, 19.48622, 22.96232, 25.68993, 28.31060, 30.93126, + 29.81347, 27.44951, 25.08555, 12.98106, 16.67323, 20.36540, 24.05756, + 26.36633, 28.47748, 30.58862, 29.76471, 27.96244, 26.16016, 13.92370, + 17.48634, 21.04897, 24.61161, 26.15244, 27.40443, 28.65643, 28.49117, + 27.85349, 27.21581, 14.86633, 18.29944, 21.73255, 25.16566, 25.93854, + 26.33138, 26.72423, 27.21763, 27.74455, 28.27147, 17.60401, 17.30942, + 17.01482, 16.72023, 13.94473, 10.81481, 7.68490, 8.98648, 11.76524, + 14.54400, 16.04249, 16.14603, 16.24958, 16.35312, 14.85158, 13.12075, + 11.38991, 12.71305, 15.05418, 17.39531, 14.48097, 14.98265, 15.48433, + 15.98602, 15.75844, 15.42668, 15.09493, 16.43962, 18.34312, 20.24663, + 12.91945, 13.81927, 14.71909, 15.61891, 16.66530, 17.73262, 18.79995, + 20.16619, 21.63206, 23.09794, 11.68565, 13.84398, 16.00230, 18.16062, + 19.91554, 21.61284, 23.31013, 23.99478, 24.34188, 24.68898, 10.49868, + 14.03841, 17.57814, 21.11788, 23.50056, 25.71795, 27.93534, 27.83796, + 26.96897, 26.09999, 9.31170, 14.23284, 19.15399, 24.07513, 27.08558, + 29.82307, 32.56055, 31.68113, 29.59606, 27.51099, 9.98166, 14.91619, + 19.85071, 24.78524, 27.51291, 29.92532, 32.33773, 31.77077, 30.21070, + 28.65063, 11.27060, 15.76250, 20.25440, 24.74629, 26.88768, 28.69329, + 30.49889, 30.60925, 30.15453, 29.69981, 12.55955, 16.60881, 20.65808, + 24.70735, 26.26245, 27.46126, 28.66005, 29.44773, 30.09835, 30.74898, + 15.20134, 15.53016, 15.85898, 16.18780, 13.53087, 10.44740, 7.36393, + 8.95806, 12.11139, 15.26472, 13.87432, 14.52378, 15.17325, 15.82272, + 14.49093, 12.87611, 11.26130, 12.73342, 15.23453, 17.73563, 12.54730, + 13.51741, 14.48752, 15.45763, 15.45100, 15.30483, 15.15867, 16.50878, + 18.35766, 20.20654, 11.22027, 12.51103, 13.80179, 15.09254, 16.41106, + 17.73355, 19.05603, 20.28415, 21.48080, 22.67745, 10.27070, 12.53633, + 14.80195, 17.06758, 19.04654, 20.98454, 22.92254, 23.63840, 23.94687, + 24.25534, 9.37505, 12.70901, 16.04297, 19.37693, 21.92136, 24.35300, + 26.78465, 26.93249, 26.31907, 25.70565, 8.47939, 12.88168, 17.28398, + 21.68627, 24.79618, 27.72146, 30.64674, 30.22658, 28.69127, 27.15597, + 9.77979, 13.97583, 18.17186, 22.36790, 25.18828, 27.81215, 30.43601, + 30.34293, 29.34420, 28.34548, 11.81220, 15.37712, 18.94204, 22.50695, + 24.75282, 26.81024, 28.86766, 29.40003, 29.42404, 29.44806, 13.84461, + 16.77841, 19.71221, 22.64601, 24.31735, 25.80833, 27.29932, 28.45713, + 29.50388, 30.55064, 12.05287, 13.06077, 14.06866, 15.07656, 12.81500, + 10.08638, 7.35776, 9.30520, 12.81134, 16.31747, 11.31943, 12.47863, + 13.63782, 14.79702, 13.82253, 12.54323, 11.26392, 12.88993, 15.48436, + 18.07880, 10.58600, 11.89649, 13.20698, 14.51747, 14.83005, 15.00007, + 15.17009, 16.47465, 18.15739, 19.84013, 9.85256, 11.31435, 12.77614, + 14.23793, 15.83757, 17.45691, 19.07625, 20.05937, 20.83042, 21.60147, + 9.36002, 11.37275, 13.38548, 15.39822, 17.58109, 19.78828, 21.99546, + 22.68573, 22.87036, 23.05500, 8.90189, 11.52266, 14.14343, 16.76420, + 19.42976, 22.10172, 24.77368, 25.17519, 24.81987, 24.46455, 8.44375, + 11.67256, 14.90137, 18.13018, 21.27843, 24.41516, 27.55190, 27.66464, + 26.76937, 25.87411, 10.51042, 13.30769, 16.10496, 18.90222, 21.70659, + 24.51197, 27.31734, 27.77045, 27.43945, 27.10846, 13.41869, 15.43789, + 17.45709, 19.47628, 21.66124, 23.86989, 26.07853, 27.08170, 27.68305, + 28.28440, 16.32697, 17.56809, 18.80922, 20.05033, 21.61590, 23.22781, + 24.83972, 26.39296, 27.92665, 29.46033, 8.90439, 10.59137, 12.27835, + 13.96532, 12.09914, 9.72536, 7.35159, 9.65235, 13.51128, 17.37022, + 8.76455, 10.43347, 12.10239, 13.77132, 13.15412, 12.21033, 11.26655, + 13.04643, 15.73420, 18.42198, 8.62470, 10.27557, 11.92644, 13.57731, + 14.20910, 14.69531, 15.18151, 16.44051, 17.95712, 19.47373, 8.48485, + 10.11767, 11.75049, 13.38331, 15.26408, 17.18027, 19.09647, 19.83460, + 20.18004, 20.52548, 8.44933, 10.20917, 11.96901, 13.72885, 16.11565, + 18.59202, 21.06838, 21.73307, 21.79386, 21.85465, 8.42872, 10.33631, + 12.24389, 14.15147, 16.93816, 19.85044, 22.76272, 23.41788, 23.32067, + 23.22346, 8.40812, 10.46344, 12.51877, 14.57409, 17.76068, 21.10886, + 24.45705, 25.10269, 24.84748, 24.59226, 11.24106, 12.63955, 14.03805, + 15.43654, 18.22489, 21.21178, 24.19868, 25.19796, 25.53469, 25.87143, + 15.02519, 15.49866, 15.97213, 16.44560, 18.56967, 20.92953, 23.28940, + 24.76337, 25.94205, 27.12073, 18.80933, 18.35777, 17.90622, 17.45466, + 18.91445, 20.64729, 22.38013, 24.32880, 26.34941, 28.37003, +}; diff --git a/src/unittest/test_objdef.cpp b/src/unittest/test_objdef.cpp new file mode 100644 index 0000000..40f7faa --- /dev/null +++ b/src/unittest/test_objdef.cpp @@ -0,0 +1,174 @@ +/* +Minetest +Copyright (C) 2010-2014 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "exceptions.h" +#include "objdef.h" + +class TestObjDef : public TestBase +{ +public: + TestObjDef() { TestManager::registerTestModule(this); } + const char *getName() { return "TestObjDef"; } + + void runTests(IGameDef *gamedef); + + void testHandles(); + void testAddGetSetClear(); + void testClone(); +}; + +static TestObjDef g_test_instance; + +void TestObjDef::runTests(IGameDef *gamedef) +{ + TEST(testHandles); + TEST(testAddGetSetClear); + TEST(testClone); +} + +//////////////////////////////////////////////////////////////////////////////// + +/* Minimal implementation of ObjDef and ObjDefManager subclass */ + +class MyObjDef : public ObjDef +{ +public: + ObjDef *clone() const + { + auto def = new MyObjDef(); + ObjDef::cloneTo(def); + def->testvalue = testvalue; + return def; + }; + + u32 testvalue; +}; + +class MyObjDefManager : public ObjDefManager +{ +public: + MyObjDefManager(ObjDefType type) : ObjDefManager(NULL, type){}; + MyObjDefManager *clone() const + { + auto mgr = new MyObjDefManager(); + ObjDefManager::cloneTo(mgr); + return mgr; + }; + +protected: + MyObjDefManager(){}; +}; + +void TestObjDef::testHandles() +{ + u32 uid = 0; + u32 index = 0; + ObjDefType type = OBJDEF_GENERIC; + + ObjDefHandle handle = ObjDefManager::createHandle(9530, OBJDEF_ORE, 47); + + UASSERTEQ(ObjDefHandle, 0xAF507B55, handle); + + UASSERT(ObjDefManager::decodeHandle(handle, &index, &type, &uid)); + + UASSERTEQ(u32, 9530, index); + UASSERTEQ(u32, 47, uid); + UASSERTEQ(ObjDefHandle, OBJDEF_ORE, type); +} + +void TestObjDef::testAddGetSetClear() +{ + ObjDefManager testmgr(NULL, OBJDEF_GENERIC); + ObjDefHandle hObj0, hObj1, hObj2, hObj3; + ObjDef *obj0, *obj1, *obj2, *obj3; + + UASSERTEQ(ObjDefType, testmgr.getType(), OBJDEF_GENERIC); + + obj0 = new MyObjDef; + obj0->name = "foobar"; + hObj0 = testmgr.add(obj0); + UASSERT(hObj0 != OBJDEF_INVALID_HANDLE); + UASSERTEQ(u32, obj0->index, 0); + + obj1 = new MyObjDef; + obj1->name = "FooBaz"; + hObj1 = testmgr.add(obj1); + UASSERT(hObj1 != OBJDEF_INVALID_HANDLE); + UASSERTEQ(u32, obj1->index, 1); + + obj2 = new MyObjDef; + obj2->name = "asdf"; + hObj2 = testmgr.add(obj2); + UASSERT(hObj2 != OBJDEF_INVALID_HANDLE); + UASSERTEQ(u32, obj2->index, 2); + + obj3 = new MyObjDef; + obj3->name = "foobaz"; + hObj3 = testmgr.add(obj3); + UASSERT(hObj3 == OBJDEF_INVALID_HANDLE); + + UASSERTEQ(size_t, testmgr.getNumObjects(), 3); + + UASSERT(testmgr.get(hObj0) == obj0); + UASSERT(testmgr.getByName("FOOBAZ") == obj1); + + UASSERT(testmgr.set(hObj0, obj3) == obj0); + UASSERT(testmgr.get(hObj0) == obj3); + delete obj0; + + testmgr.clear(); + UASSERTEQ(size_t, testmgr.getNumObjects(), 0); +} + +void TestObjDef::testClone() +{ + MyObjDefManager testmgr(OBJDEF_GENERIC); + ObjDefManager *mgrcopy; + MyObjDef *obj, *temp2; + ObjDef *temp1; + ObjDefHandle hObj; + + obj = new MyObjDef; + obj->testvalue = 0xee00ff11; + hObj = testmgr.add(obj); + UASSERT(hObj != OBJDEF_INVALID_HANDLE); + + mgrcopy = testmgr.clone(); + UASSERT(mgrcopy); + UASSERTEQ(ObjDefType, mgrcopy->getType(), testmgr.getType()); + UASSERTEQ(size_t, mgrcopy->getNumObjects(), testmgr.getNumObjects()); + + // 1) check that the same handle is still valid on the copy + temp1 = mgrcopy->get(hObj); + UASSERT(temp1); + UASSERT(temp1 == mgrcopy->getRaw(0)); + // 2) check that the copy has the correct C++ class + temp2 = dynamic_cast<MyObjDef *>(temp1); + UASSERT(temp2); + // 3) check that it was correctly copied + UASSERTEQ(u32, obj->testvalue, temp2->testvalue); + // 4) check that it was copied AT ALL (not the same) + UASSERT(obj != temp2); + + testmgr.clear(); + mgrcopy->clear(); + delete mgrcopy; +} diff --git a/src/unittest/test_profiler.cpp b/src/unittest/test_profiler.cpp new file mode 100644 index 0000000..92d336a --- /dev/null +++ b/src/unittest/test_profiler.cpp @@ -0,0 +1,73 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "profiler.h" + +class TestProfiler : public TestBase +{ +public: + TestProfiler() { TestManager::registerTestModule(this); } + const char *getName() { return "TestProfiler"; } + + void runTests(IGameDef *gamedef); + + void testProfilerAverage(); +}; + +static TestProfiler g_test_instance; + +void TestProfiler::runTests(IGameDef *gamedef) +{ + TEST(testProfilerAverage); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestProfiler::testProfilerAverage() +{ + Profiler p; + + p.avg("Test1", 1.f); + UASSERT(p.getValue("Test1") == 1.f); + + p.avg("Test1", 2.f); + UASSERT(p.getValue("Test1") == 1.5f); + + p.avg("Test1", 3.f); + UASSERT(p.getValue("Test1") == 2.f); + + p.avg("Test1", 486.f); + UASSERT(p.getValue("Test1") == 123.f); + + p.avg("Test1", 8); + UASSERT(p.getValue("Test1") == 100.f); + + p.avg("Test1", 700); + UASSERT(p.getValue("Test1") == 200.f); + + p.avg("Test1", 10000); + UASSERT(p.getValue("Test1") == 1600.f); + + p.avg("Test2", 123.56); + p.avg("Test2", 123.58); + + UASSERT(p.getValue("Test2") == 123.57f); +} diff --git a/src/unittest/test_random.cpp b/src/unittest/test_random.cpp new file mode 100644 index 0000000..14de764 --- /dev/null +++ b/src/unittest/test_random.cpp @@ -0,0 +1,275 @@ + /* +Minetest +Copyright (C) 2010-2014 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <cmath> +#include "util/numeric.h" +#include "exceptions.h" +#include "noise.h" + +class TestRandom : public TestBase { +public: + TestRandom() { TestManager::registerTestModule(this); } + const char *getName() { return "TestRandom"; } + + void runTests(IGameDef *gamedef); + + void testPseudoRandom(); + void testPseudoRandomRange(); + void testPcgRandom(); + void testPcgRandomRange(); + void testPcgRandomBytes(); + void testPcgRandomNormalDist(); + + static const int expected_pseudorandom_results[256]; + static const u32 expected_pcgrandom_results[256]; + static const u8 expected_pcgrandom_bytes_result[24]; + static const u8 expected_pcgrandom_bytes_result2[24]; +}; + +static TestRandom g_test_instance; + +void TestRandom::runTests(IGameDef *gamedef) +{ + TEST(testPseudoRandom); + TEST(testPseudoRandomRange); + TEST(testPcgRandom); + TEST(testPcgRandomRange); + TEST(testPcgRandomBytes); + TEST(testPcgRandomNormalDist); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestRandom::testPseudoRandom() +{ + PseudoRandom pr(814538); + + for (u32 i = 0; i != 256; i++) + UASSERTEQ(int, pr.next(), expected_pseudorandom_results[i]); +} + + +void TestRandom::testPseudoRandomRange() +{ + PseudoRandom pr((int)time(NULL)); + + EXCEPTION_CHECK(PrngException, pr.range(2000, 6000)); + EXCEPTION_CHECK(PrngException, pr.range(5, 1)); + + for (u32 i = 0; i != 32768; i++) { + int min = (pr.next() % 3000) - 500; + int max = (pr.next() % 3000) - 500; + if (min > max) + SWAP(int, min, max); + + int randval = pr.range(min, max); + UASSERT(randval >= min); + UASSERT(randval <= max); + } +} + + +void TestRandom::testPcgRandom() +{ + PcgRandom pr(814538, 998877); + + for (u32 i = 0; i != 256; i++) + UASSERTEQ(u32, pr.next(), expected_pcgrandom_results[i]); +} + + +void TestRandom::testPcgRandomRange() +{ + PcgRandom pr((int)time(NULL)); + + EXCEPTION_CHECK(PrngException, pr.range(5, 1)); + + // Regression test for bug 3027 + pr.range(pr.RANDOM_MIN, pr.RANDOM_MAX); + + for (u32 i = 0; i != 32768; i++) { + int min = (pr.next() % 3000) - 500; + int max = (pr.next() % 3000) - 500; + if (min > max) + SWAP(int, min, max); + + int randval = pr.range(min, max); + UASSERT(randval >= min); + UASSERT(randval <= max); + } +} + + +void TestRandom::testPcgRandomBytes() +{ + char buf[32]; + PcgRandom r(1538, 877); + + memset(buf, 0, sizeof(buf)); + r.bytes(buf + 5, 23); + UASSERT(memcmp(buf + 5, expected_pcgrandom_bytes_result, + sizeof(expected_pcgrandom_bytes_result)) == 0); + + memset(buf, 0, sizeof(buf)); + r.bytes(buf, 17); + UASSERT(memcmp(buf, expected_pcgrandom_bytes_result2, + sizeof(expected_pcgrandom_bytes_result2)) == 0); +} + + +void TestRandom::testPcgRandomNormalDist() +{ + static const int max = 120; + static const int min = -120; + static const int num_trials = 20; + static const u32 num_samples = 61000; + s32 bins[max - min + 1]; + memset(bins, 0, sizeof(bins)); + + PcgRandom r(486179 + (int)time(NULL)); + + for (u32 i = 0; i != num_samples; i++) { + s32 randval = r.randNormalDist(min, max, num_trials); + UASSERT(randval <= max); + UASSERT(randval >= min); + bins[randval - min]++; + } + + // Note that here we divide variance by the number of trials; + // this is because variance is a biased estimator. + int range = (max - min + 1); + float mean = (max + min) / 2; + float variance = ((range * range - 1) / 12) / num_trials; + float stddev = std::sqrt(variance); + + static const float prediction_intervals[] = { + 0.68269f, // 1.0 + 0.86639f, // 1.5 + 0.95450f, // 2.0 + 0.98758f, // 2.5 + 0.99730f, // 3.0 + }; + + //// Simple normality test using the 68-95-99.7% rule + for (u32 i = 0; i != ARRLEN(prediction_intervals); i++) { + float deviations = i / 2.f + 1.f; + int lbound = myround(mean - deviations * stddev); + int ubound = myround(mean + deviations * stddev); + UASSERT(lbound >= min); + UASSERT(ubound <= max); + + int accum = 0; + for (int j = lbound; j != ubound; j++) + accum += bins[j - min]; + + float actual = (float)accum / num_samples; + UASSERT(std::fabs(actual - prediction_intervals[i]) < 0.02f); + } +} + + +const int TestRandom::expected_pseudorandom_results[256] = { + 0x02fa, 0x60d5, 0x6c10, 0x606b, 0x098b, 0x5f1e, 0x4f56, 0x3fbd, 0x77af, + 0x4fe9, 0x419a, 0x6fe1, 0x177b, 0x6858, 0x36f8, 0x6d83, 0x14fc, 0x2d62, + 0x1077, 0x23e2, 0x041b, 0x7a7e, 0x5b52, 0x215d, 0x682b, 0x4716, 0x47e3, + 0x08c0, 0x1952, 0x56ae, 0x146d, 0x4b4f, 0x239f, 0x3fd0, 0x6794, 0x7796, + 0x7be2, 0x75b7, 0x5691, 0x28ee, 0x2656, 0x40c0, 0x133c, 0x63cd, 0x2aeb, + 0x518f, 0x7dbc, 0x6ad8, 0x736e, 0x5b05, 0x160b, 0x589f, 0x6f64, 0x5edc, + 0x092c, 0x0a39, 0x199e, 0x1927, 0x562b, 0x2689, 0x3ba3, 0x366f, 0x46da, + 0x4e49, 0x0abb, 0x40a1, 0x3846, 0x40db, 0x7adb, 0x6ec1, 0x6efa, 0x01cc, + 0x6335, 0x4352, 0x72fb, 0x4b2d, 0x509a, 0x257e, 0x2f7d, 0x5891, 0x2195, + 0x6107, 0x5269, 0x56e3, 0x4849, 0x38f7, 0x2791, 0x04f2, 0x4e05, 0x78ff, + 0x6bae, 0x50b3, 0x74ad, 0x31af, 0x531e, 0x7d56, 0x11c9, 0x0b5e, 0x405e, + 0x1e15, 0x7f6a, 0x5bd3, 0x6649, 0x71b4, 0x3ec2, 0x6ab4, 0x520e, 0x6ad6, + 0x287e, 0x10b8, 0x18f2, 0x7107, 0x46ea, 0x1d85, 0x25cc, 0x2689, 0x35c1, + 0x3065, 0x6237, 0x3edd, 0x23d9, 0x6fb5, 0x37a1, 0x3211, 0x526a, 0x4b09, + 0x23f1, 0x58cc, 0x2e42, 0x341f, 0x5e16, 0x3d1a, 0x5e8c, 0x7a82, 0x4635, + 0x2bf8, 0x6577, 0x3603, 0x1daf, 0x539f, 0x2e91, 0x6bd8, 0x42d3, 0x7a93, + 0x26e3, 0x5a91, 0x6c67, 0x1b66, 0x3ac7, 0x18bf, 0x20d8, 0x7153, 0x558d, + 0x7262, 0x653d, 0x417d, 0x3ed3, 0x3117, 0x600d, 0x6d04, 0x719c, 0x3afd, + 0x6ba5, 0x17c5, 0x4935, 0x346c, 0x5479, 0x6ff6, 0x1fcc, 0x1054, 0x3f14, + 0x6266, 0x3acc, 0x3b77, 0x71d8, 0x478b, 0x20fa, 0x4e46, 0x7e77, 0x5554, + 0x3652, 0x719c, 0x072b, 0x61ad, 0x399f, 0x621d, 0x1bba, 0x41d0, 0x7fdc, + 0x3e6c, 0x6a2a, 0x5253, 0x094e, 0x0c10, 0x3f43, 0x73eb, 0x4c5f, 0x1f23, + 0x12c9, 0x0902, 0x5238, 0x50c0, 0x1b77, 0x3ffd, 0x0124, 0x302a, 0x26b9, + 0x3648, 0x30a6, 0x1abc, 0x3031, 0x4029, 0x6358, 0x6696, 0x74e8, 0x6142, + 0x4284, 0x0c00, 0x7e50, 0x41e3, 0x3782, 0x79a5, 0x60fe, 0x2d15, 0x3ed2, + 0x7f70, 0x2b27, 0x6366, 0x5100, 0x7c44, 0x3ee0, 0x4e76, 0x7d34, 0x3a60, + 0x140e, 0x613d, 0x1193, 0x268d, 0x1e2f, 0x3123, 0x6d61, 0x4e0b, 0x51ce, + 0x13bf, 0x58d4, 0x4f43, 0x05c6, 0x4d6a, 0x7eb5, 0x2921, 0x2c36, 0x1c89, + 0x63b9, 0x1555, 0x1f41, 0x2d9f, +}; + +const u32 TestRandom::expected_pcgrandom_results[256] = { + 0x48c593f8, 0x054f59f5, 0x0d062dc1, 0x23852a23, 0x7fbbc97b, 0x1f9f141e, + 0x364e6ed8, 0x995bba58, 0xc9307dc0, 0x73fb34c4, 0xcd8de88d, 0x52e8ce08, + 0x1c4a78e4, 0x25c0882e, 0x8a82e2e0, 0xe3bc3311, 0xb8068d42, 0x73186110, + 0x19988df4, 0x69bd970b, 0x7214728c, 0x0aee320c, 0x2a5a536c, 0xaf48d715, + 0x00bce504, 0xd2b8f548, 0x520df366, 0x96d8fff5, 0xa1bb510b, 0x63477049, + 0xb85990b7, 0x7e090689, 0x275fb468, 0x50206257, 0x8bab4f8a, 0x0d6823db, + 0x63faeaac, 0x2d92deeb, 0x2ba78024, 0x0d30f631, 0x338923a0, 0xd07248d8, + 0xa5db62d3, 0xddba8af6, 0x0ad454e9, 0x6f0fd13a, 0xbbfde2bf, 0x91188009, + 0x966b394d, 0xbb9d2012, 0x7e6926cb, 0x95183860, 0x5ff4c59b, 0x035f628a, + 0xb67085ef, 0x33867e23, 0x68d1b887, 0x2e3298d7, 0x84fd0650, 0x8bc91141, + 0x6fcb0452, 0x2836fee9, 0x2e83c0a3, 0xf1bafdc5, 0x9ff77777, 0xfdfbba87, + 0x527aebeb, 0x423e5248, 0xd1756490, 0xe41148fa, 0x3361f7b4, 0xa2824f23, + 0xf4e08072, 0xc50442be, 0x35adcc21, 0x36be153c, 0xc7709012, 0xf0eeb9f2, + 0x3d73114e, 0x1c1574ee, 0x92095b9c, 0x1503d01c, 0xd6ce0677, 0x026a8ec1, + 0x76d0084d, 0x86c23633, 0x36f75ce6, 0x08fa7bbe, 0x35f6ff2a, 0x31cc9525, + 0x2c1a35e6, 0x8effcd62, 0xc782fa07, 0x8a86e248, 0x8fdb7a9b, 0x77246626, + 0x5767723f, 0x3a78b699, 0xe548ce1c, 0x5820f37d, 0x148ed9b8, 0xf6796254, + 0x32232c20, 0x392bf3a2, 0xe9af6625, 0xd40b0d88, 0x636cfa23, 0x6a5de514, + 0xc4a69183, 0xc785c853, 0xab0de901, 0x16ae7e44, 0x376f13b5, 0x070f7f31, + 0x34cbc93b, 0xe6184345, 0x1b7f911f, 0x631fbe4b, 0x86d6e023, 0xc689b518, + 0x88ef4f7c, 0xddf06b45, 0xc97f18d4, 0x2aaee94b, 0x45694723, 0x6db111d2, + 0x91974fce, 0xe33e29e2, 0xc5e99494, 0x8017e02b, 0x3ebd8143, 0x471ffb80, + 0xc0d7ca1b, 0x4954c860, 0x48935d6a, 0xf2d27999, 0xb93d608d, 0x40696e90, + 0x60b18162, 0x1a156998, 0x09b8bbab, 0xc80a79b6, 0x8adbcfbc, 0xc375248c, + 0xa584e2ea, 0x5b46fe11, 0x58e84680, 0x8a8bc456, 0xd668b94f, 0x8b9035be, + 0x278509d4, 0x6663a140, 0x81a9817a, 0xd4f9d3cf, 0x6dc5f607, 0x6ae04450, + 0x694f22a4, 0x1d061788, 0x2e39ad8b, 0x748f4db2, 0xee569b52, 0xd157166d, + 0xdabc161e, 0xc8d50176, 0x7e3110e5, 0x9f7d033b, 0x128df67f, 0xb0078583, + 0xa3a75d26, 0xc1ad8011, 0x07dd89ec, 0xef04f456, 0x91bf866c, 0x6aac5306, + 0xdd5a1573, 0xf73ff97a, 0x4e1186ad, 0xb9680680, 0xc8894515, 0xdc95a08e, + 0xc894fd8e, 0xf84ade15, 0xd787f8c1, 0x40dcecca, 0x1b24743e, 0x1ce6ab23, + 0x72321653, 0xb80fbaf7, 0x1bcf099b, 0x1ff26805, 0x78f66c8e, 0xf93bf51a, + 0xfb0c06fe, 0xe50d48cf, 0x310947e0, 0x1b78804a, 0xe73e2c14, 0x8deb8381, + 0xe576122a, 0xe5a8df39, 0x42397c5e, 0xf5503f3c, 0xbe3dbf8d, 0x1b360e5c, + 0x9254caaf, 0x7a9f6744, 0x6d4144fa, 0xd77c65fe, 0x44ca7b12, 0xf58a4c00, + 0x159500d0, 0x92769857, 0x7134fdd4, 0xa3fea693, 0xbd044831, 0xeded39a1, + 0xe4570204, 0xaea37f2f, 0x9a302971, 0x620f8402, 0x1d2f3e5e, 0xf9c2f49c, + 0x738e813a, 0xb3c92251, 0x7ecba63b, 0xbe7eebc7, 0xf800267c, 0x3fdeb760, + 0xf12d5e7d, 0x5a18dce1, 0xb35a539c, 0xe565f057, 0x2babf38c, 0xae5800ad, + 0x421004dd, 0x6715acb6, 0xff529b64, 0xd520d207, 0x7cb193e7, 0xe9b18e4c, + 0xfd2a8a59, 0x47826ae3, 0x56ba43f8, 0x453b3d99, 0x8ae1675f, 0xf66f5c34, + 0x057a6ac1, 0x010769e4, 0xa8324158, 0x410379a5, 0x5dfc8c97, 0x72848afe, + 0x59f169e5, 0xe32acb78, 0x5dfaa9c4, 0x51bb956a, +}; + +const u8 TestRandom::expected_pcgrandom_bytes_result[24] = { + 0xf3, 0x79, 0x8f, 0x31, 0xac, 0xd9, 0x34, 0xf8, 0x3c, 0x6e, 0x82, 0x37, + 0x6b, 0x4b, 0x77, 0xe3, 0xbd, 0x0a, 0xee, 0x22, 0x79, 0x6e, 0x40, 0x00, +}; + +const u8 TestRandom::expected_pcgrandom_bytes_result2[24] = { + 0x47, 0x9e, 0x08, 0x3e, 0xd4, 0x21, 0x2d, 0xf6, 0xb4, 0xb1, 0x9d, 0x7a, + 0x60, 0x02, 0x5a, 0xb2, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; diff --git a/src/unittest/test_schematic.cpp b/src/unittest/test_schematic.cpp new file mode 100644 index 0000000..d2f027e --- /dev/null +++ b/src/unittest/test_schematic.cpp @@ -0,0 +1,286 @@ + /* +Minetest +Copyright (C) 2010-2014 kwolekr, Ryan Kwolek <kwolekr@minetest.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "mapgen/mg_schematic.h" +#include "gamedef.h" +#include "nodedef.h" + +class TestSchematic : public TestBase { +public: + TestSchematic() { TestManager::registerTestModule(this); } + const char *getName() { return "TestSchematic"; } + + void runTests(IGameDef *gamedef); + + void testMtsSerializeDeserialize(const NodeDefManager *ndef); + void testLuaTableSerialize(const NodeDefManager *ndef); + void testFileSerializeDeserialize(const NodeDefManager *ndef); + + static const content_t test_schem1_data[7 * 6 * 4]; + static const content_t test_schem2_data[3 * 3 * 3]; + static const u8 test_schem2_prob[3 * 3 * 3]; + static const char *expected_lua_output; +}; + +static TestSchematic g_test_instance; + +void TestSchematic::runTests(IGameDef *gamedef) +{ + NodeDefManager *ndef = + (NodeDefManager *)gamedef->getNodeDefManager(); + + ndef->setNodeRegistrationStatus(true); + + TEST(testMtsSerializeDeserialize, ndef); + TEST(testLuaTableSerialize, ndef); + TEST(testFileSerializeDeserialize, ndef); + + ndef->resetNodeResolveState(); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestSchematic::testMtsSerializeDeserialize(const NodeDefManager *ndef) +{ + static const v3s16 size(7, 6, 4); + static const u32 volume = size.X * size.Y * size.Z; + + std::stringstream ss(std::ios_base::binary | + std::ios_base::in | std::ios_base::out); + + Schematic schem; + { + std::vector<std::string> &names = schem.m_nodenames; + names.emplace_back("foo"); + names.emplace_back("bar"); + names.emplace_back("baz"); + names.emplace_back("qux"); + } + + schem.flags = 0; + schem.size = size; + schem.schemdata = new MapNode[volume]; + schem.slice_probs = new u8[size.Y]; + for (size_t i = 0; i != volume; i++) + schem.schemdata[i] = MapNode(test_schem1_data[i], MTSCHEM_PROB_ALWAYS, 0); + for (s16 y = 0; y != size.Y; y++) + schem.slice_probs[y] = MTSCHEM_PROB_ALWAYS; + + UASSERT(schem.serializeToMts(&ss)); + + ss.seekg(0); + + Schematic schem2; + UASSERT(schem2.deserializeFromMts(&ss)); + + { + std::vector<std::string> &names = schem2.m_nodenames; + UASSERTEQ(size_t, names.size(), 4); + UASSERTEQ(std::string, names[0], "foo"); + UASSERTEQ(std::string, names[1], "bar"); + UASSERTEQ(std::string, names[2], "baz"); + UASSERTEQ(std::string, names[3], "qux"); + } + + UASSERT(schem2.size == size); + for (size_t i = 0; i != volume; i++) + UASSERT(schem2.schemdata[i] == schem.schemdata[i]); + for (s16 y = 0; y != size.Y; y++) + UASSERTEQ(u8, schem2.slice_probs[y], schem.slice_probs[y]); +} + + +void TestSchematic::testLuaTableSerialize(const NodeDefManager *ndef) +{ + static const v3s16 size(3, 3, 3); + static const u32 volume = size.X * size.Y * size.Z; + + Schematic schem; + + schem.flags = 0; + schem.size = size; + schem.schemdata = new MapNode[volume]; + schem.slice_probs = new u8[size.Y]; + for (size_t i = 0; i != volume; i++) + schem.schemdata[i] = MapNode(test_schem2_data[i], test_schem2_prob[i], 0); + for (s16 y = 0; y != size.Y; y++) + schem.slice_probs[y] = MTSCHEM_PROB_ALWAYS; + + std::vector<std::string> &names = schem.m_nodenames; + names.emplace_back("air"); + names.emplace_back("default:lava_source"); + names.emplace_back("default:glass"); + + std::ostringstream ss(std::ios_base::binary); + + UASSERT(schem.serializeToLua(&ss, false, 0)); + UASSERTEQ(std::string, ss.str(), expected_lua_output); +} + + +void TestSchematic::testFileSerializeDeserialize(const NodeDefManager *ndef) +{ + static const v3s16 size(3, 3, 3); + static const u32 volume = size.X * size.Y * size.Z; + static const content_t content_map[] = { + CONTENT_AIR, + t_CONTENT_STONE, + t_CONTENT_LAVA, + }; + static const content_t content_map2[] = { + CONTENT_AIR, + t_CONTENT_STONE, + t_CONTENT_WATER, + }; + StringMap replace_names; + replace_names["default:lava"] = "default:water"; + + Schematic schem1, schem2; + + //// Construct the schematic to save + schem1.flags = 0; + schem1.size = size; + schem1.schemdata = new MapNode[volume]; + schem1.slice_probs = new u8[size.Y]; + schem1.slice_probs[0] = 80; + schem1.slice_probs[1] = 160; + schem1.slice_probs[2] = 240; + // Node resolving happened manually. + schem1.m_resolve_done = true; + + for (size_t i = 0; i != volume; i++) { + content_t c = content_map[test_schem2_data[i]]; + schem1.schemdata[i] = MapNode(c, test_schem2_prob[i], 0); + } + + std::string temp_file = getTestTempFile(); + UASSERT(schem1.saveSchematicToFile(temp_file, ndef)); + UASSERT(schem2.loadSchematicFromFile(temp_file, ndef, &replace_names)); + + UASSERT(schem2.size == size); + UASSERT(schem2.slice_probs[0] == 80); + UASSERT(schem2.slice_probs[1] == 160); + UASSERT(schem2.slice_probs[2] == 240); + + for (size_t i = 0; i != volume; i++) { + content_t c = content_map2[test_schem2_data[i]]; + UASSERT(schem2.schemdata[i] == MapNode(c, test_schem2_prob[i], 0)); + } +} + + +// Should form a cross-shaped-thing...? +const content_t TestSchematic::test_schem1_data[7 * 6 * 4] = { + 3, 3, 1, 1, 1, 3, 3, // Y=0, Z=0 + 3, 0, 1, 2, 1, 0, 3, // Y=1, Z=0 + 3, 0, 1, 2, 1, 0, 3, // Y=2, Z=0 + 3, 1, 1, 2, 1, 1, 3, // Y=3, Z=0 + 3, 2, 2, 2, 2, 2, 3, // Y=4, Z=0 + 3, 1, 1, 2, 1, 1, 3, // Y=5, Z=0 + + 0, 0, 1, 1, 1, 0, 0, // Y=0, Z=1 + 0, 0, 1, 2, 1, 0, 0, // Y=1, Z=1 + 0, 0, 1, 2, 1, 0, 0, // Y=2, Z=1 + 1, 1, 1, 2, 1, 1, 1, // Y=3, Z=1 + 1, 2, 2, 2, 2, 2, 1, // Y=4, Z=1 + 1, 1, 1, 2, 1, 1, 1, // Y=5, Z=1 + + 0, 0, 1, 1, 1, 0, 0, // Y=0, Z=2 + 0, 0, 1, 2, 1, 0, 0, // Y=1, Z=2 + 0, 0, 1, 2, 1, 0, 0, // Y=2, Z=2 + 1, 1, 1, 2, 1, 1, 1, // Y=3, Z=2 + 1, 2, 2, 2, 2, 2, 1, // Y=4, Z=2 + 1, 1, 1, 2, 1, 1, 1, // Y=5, Z=2 + + 3, 3, 1, 1, 1, 3, 3, // Y=0, Z=3 + 3, 0, 1, 2, 1, 0, 3, // Y=1, Z=3 + 3, 0, 1, 2, 1, 0, 3, // Y=2, Z=3 + 3, 1, 1, 2, 1, 1, 3, // Y=3, Z=3 + 3, 2, 2, 2, 2, 2, 3, // Y=4, Z=3 + 3, 1, 1, 2, 1, 1, 3, // Y=5, Z=3 +}; + +const content_t TestSchematic::test_schem2_data[3 * 3 * 3] = { + 0, 0, 0, + 0, 2, 0, + 0, 0, 0, + + 0, 2, 0, + 2, 1, 2, + 0, 2, 0, + + 0, 0, 0, + 0, 2, 0, + 0, 0, 0, +}; + +const u8 TestSchematic::test_schem2_prob[3 * 3 * 3] = { + 0x00, 0x00, 0x00, + 0x00, 0xFF, 0x00, + 0x00, 0x00, 0x00, + + 0x00, 0xFF, 0x00, + 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0x00, + + 0x00, 0x00, 0x00, + 0x00, 0xFF, 0x00, + 0x00, 0x00, 0x00, +}; + +const char *TestSchematic::expected_lua_output = + "schematic = {\n" + "\tsize = {x=3, y=3, z=3},\n" + "\tyslice_prob = {\n" + "\t\t{ypos=0, prob=254},\n" + "\t\t{ypos=1, prob=254},\n" + "\t\t{ypos=2, prob=254},\n" + "\t},\n" + "\tdata = {\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n" + "\t\t{name=\"default:lava_source\", prob=254, param2=0, force_place=true},\n" + "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t\t{name=\"air\", prob=0, param2=0},\n" + "\t},\n" + "}\n"; diff --git a/src/unittest/test_serialization.cpp b/src/unittest/test_serialization.cpp new file mode 100644 index 0000000..ff6b575 --- /dev/null +++ b/src/unittest/test_serialization.cpp @@ -0,0 +1,439 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "util/string.h" +#include "util/serialize.h" +#include <cmath> + +class TestSerialization : public TestBase { +public: + TestSerialization() { TestManager::registerTestModule(this); } + const char *getName() { return "TestSerialization"; } + + void runTests(IGameDef *gamedef); + void buildTestStrings(); + + void testSerializeString(); + void testSerializeLongString(); + void testSerializeJsonString(); + void testDeSerializeString(); + void testDeSerializeLongString(); + void testStreamRead(); + void testStreamWrite(); + void testFloatFormat(); + + std::string teststring2; + std::wstring teststring2_w; + std::string teststring2_w_encoded; + + static const u8 test_serialized_data[12 * 11 - 2]; +}; + +static TestSerialization g_test_instance; + +void TestSerialization::runTests(IGameDef *gamedef) +{ + buildTestStrings(); + + TEST(testSerializeString); + TEST(testDeSerializeString); + TEST(testSerializeLongString); + TEST(testDeSerializeLongString); + TEST(testSerializeJsonString); + TEST(testStreamRead); + TEST(testStreamWrite); + TEST(testFloatFormat); +} + +//////////////////////////////////////////////////////////////////////////////// + +// To be used like this: +// mkstr("Some\0string\0with\0embedded\0nuls") +// since std::string("...") doesn't work as expected in that case. +template<size_t N> std::string mkstr(const char (&s)[N]) +{ + return std::string(s, N - 1); +} + +void TestSerialization::buildTestStrings() +{ + std::ostringstream tmp_os; + std::wostringstream tmp_os_w; + std::ostringstream tmp_os_w_encoded; + for (int i = 0; i < 256; i++) { + tmp_os << (char)i; + tmp_os_w << (wchar_t)i; + tmp_os_w_encoded << (char)0 << (char)i; + } + teststring2 = tmp_os.str(); + teststring2_w = tmp_os_w.str(); + teststring2_w_encoded = tmp_os_w_encoded.str(); +} + +void TestSerialization::testSerializeString() +{ + // Test blank string + UASSERT(serializeString16("") == mkstr("\0\0")); + + // Test basic string + UASSERT(serializeString16("Hello world!") == mkstr("\0\14Hello world!")); + + // Test character range + UASSERT(serializeString16(teststring2) == mkstr("\1\0") + teststring2); +} + +void TestSerialization::testDeSerializeString() +{ + // Test deserialize + { + std::istringstream is(serializeString16(teststring2), std::ios::binary); + UASSERT(deSerializeString16(is) == teststring2); + UASSERT(!is.eof()); + is.get(); + UASSERT(is.eof()); + } + + // Test deserialize an incomplete length specifier + { + std::istringstream is(mkstr("\x53"), std::ios::binary); + EXCEPTION_CHECK(SerializationError, deSerializeString16(is)); + } + + // Test deserialize a string with incomplete data + { + std::istringstream is(mkstr("\x00\x55 abcdefg"), std::ios::binary); + EXCEPTION_CHECK(SerializationError, deSerializeString16(is)); + } +} + +void TestSerialization::testSerializeLongString() +{ + // Test blank string + UASSERT(serializeString32("") == mkstr("\0\0\0\0")); + + // Test basic string + UASSERT(serializeString32("Hello world!") == mkstr("\0\0\0\14Hello world!")); + + // Test character range + UASSERT(serializeString32(teststring2) == mkstr("\0\0\1\0") + teststring2); +} + +void TestSerialization::testDeSerializeLongString() +{ + // Test deserialize + { + std::istringstream is(serializeString32(teststring2), std::ios::binary); + UASSERT(deSerializeString32(is) == teststring2); + UASSERT(!is.eof()); + is.get(); + UASSERT(is.eof()); + } + + // Test deserialize an incomplete length specifier + { + std::istringstream is(mkstr("\x53"), std::ios::binary); + EXCEPTION_CHECK(SerializationError, deSerializeString32(is)); + } + + // Test deserialize a string with incomplete data + { + std::istringstream is(mkstr("\x00\x00\x00\x05 abc"), std::ios::binary); + EXCEPTION_CHECK(SerializationError, deSerializeString32(is)); + } + + // Test deserialize a string with a length too large + { + std::istringstream is(mkstr("\xFF\xFF\xFF\xFF blah"), std::ios::binary); + EXCEPTION_CHECK(SerializationError, deSerializeString32(is)); + } +} + + +void TestSerialization::testSerializeJsonString() +{ + std::istringstream is(std::ios::binary); + const auto reset_is = [&] (const std::string &s) { + is.clear(); + is.str(s); + }; + const auto assert_at_eof = [] (std::istream &is) { + is.get(); + UASSERT(is.eof()); + }; + + // Test blank string + UASSERTEQ(std::string, serializeJsonString(""), "\"\""); + reset_is("\"\""); + UASSERTEQ(std::string, deSerializeJsonString(is), ""); + assert_at_eof(is); + + // Test basic string + UASSERTEQ(std::string, serializeJsonString("Hello world!"), "\"Hello world!\""); + reset_is("\"Hello world!\""); + UASSERTEQ(std::string, deSerializeJsonString(is), "Hello world!"); + assert_at_eof(is); + + // Test optional serialization + const std::pair<const char*, const char*> test_pairs[] = { + { "abc", "abc" }, + { "x y z", "\"x y z\"" }, + { "\"", "\"\\\"\"" }, + }; + for (auto it : test_pairs) { + UASSERTEQ(std::string, serializeJsonStringIfNeeded(it.first), it.second); + reset_is(it.second); + UASSERTEQ(std::string, deSerializeJsonStringIfNeeded(is), it.first); + assert_at_eof(is); + } + + // Test all byte values + const std::string bs = "\\"; // MSVC fails when directly using "\\\\" + const std::string expected = mkstr("\"") + + "\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007" + + "\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f" + + "\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017" + + "\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f" + + " !\\\"" + teststring2.substr(0x23, 0x5c-0x23) + + bs + bs + teststring2.substr(0x5d, 0x7f-0x5d) + "\\u007f" + + "\\u0080\\u0081\\u0082\\u0083\\u0084\\u0085\\u0086\\u0087" + + "\\u0088\\u0089\\u008a\\u008b\\u008c\\u008d\\u008e\\u008f" + + "\\u0090\\u0091\\u0092\\u0093\\u0094\\u0095\\u0096\\u0097" + + "\\u0098\\u0099\\u009a\\u009b\\u009c\\u009d\\u009e\\u009f" + + "\\u00a0\\u00a1\\u00a2\\u00a3\\u00a4\\u00a5\\u00a6\\u00a7" + + "\\u00a8\\u00a9\\u00aa\\u00ab\\u00ac\\u00ad\\u00ae\\u00af" + + "\\u00b0\\u00b1\\u00b2\\u00b3\\u00b4\\u00b5\\u00b6\\u00b7" + + "\\u00b8\\u00b9\\u00ba\\u00bb\\u00bc\\u00bd\\u00be\\u00bf" + + "\\u00c0\\u00c1\\u00c2\\u00c3\\u00c4\\u00c5\\u00c6\\u00c7" + + "\\u00c8\\u00c9\\u00ca\\u00cb\\u00cc\\u00cd\\u00ce\\u00cf" + + "\\u00d0\\u00d1\\u00d2\\u00d3\\u00d4\\u00d5\\u00d6\\u00d7" + + "\\u00d8\\u00d9\\u00da\\u00db\\u00dc\\u00dd\\u00de\\u00df" + + "\\u00e0\\u00e1\\u00e2\\u00e3\\u00e4\\u00e5\\u00e6\\u00e7" + + "\\u00e8\\u00e9\\u00ea\\u00eb\\u00ec\\u00ed\\u00ee\\u00ef" + + "\\u00f0\\u00f1\\u00f2\\u00f3\\u00f4\\u00f5\\u00f6\\u00f7" + + "\\u00f8\\u00f9\\u00fa\\u00fb\\u00fc\\u00fd\\u00fe\\u00ff" + + "\""; + std::string serialized = serializeJsonString(teststring2); + UASSERTEQ(std::string, serialized, expected); + + reset_is(serialized); + UASSERTEQ(std::string, deSerializeJsonString(is), teststring2); + UASSERT(!is.eof()); // should have stopped at " so eof must not be set yet + assert_at_eof(is); + + // Test that deserialization leaves rest of stream alone + std::string tmp; + reset_is("\"foo\"bar"); + UASSERTEQ(std::string, deSerializeJsonString(is), "foo"); + std::getline(is, tmp, '\0'); + UASSERTEQ(std::string, tmp, "bar"); + + reset_is("\"x y z\"bar"); + UASSERTEQ(std::string, deSerializeJsonStringIfNeeded(is), "x y z"); + std::getline(is, tmp, '\0'); + UASSERTEQ(std::string, tmp, "bar"); + + reset_is("foo bar"); + UASSERTEQ(std::string, deSerializeJsonStringIfNeeded(is), "foo"); + std::getline(is, tmp, '\0'); + UASSERTEQ(std::string, tmp, " bar"); +} + + +void TestSerialization::testStreamRead() +{ + std::string datastr( + (const char *)test_serialized_data, + sizeof(test_serialized_data)); + std::istringstream is(datastr, std::ios_base::binary); + + UASSERT(readU8(is) == 0x11); + UASSERT(readU16(is) == 0x2233); + UASSERT(readU32(is) == 0x44556677); + UASSERT(readU64(is) == 0x8899AABBCCDDEEFFLL); + + UASSERT(readS8(is) == -128); + UASSERT(readS16(is) == 30000); + UASSERT(readS32(is) == -6); + UASSERT(readS64(is) == -43); + + UASSERT(readF1000(is) == 53.534f); + UASSERT(readF1000(is) == -300000.32f); + UASSERT(readF1000(is) == F1000_MIN); + UASSERT(readF1000(is) == F1000_MAX); + + UASSERT(deSerializeString16(is) == "foobar!"); + + UASSERT(readV2S16(is) == v2s16(500, 500)); + UASSERT(readV3S16(is) == v3s16(4207, 604, -30)); + UASSERT(readV2S32(is) == v2s32(1920, 1080)); + UASSERT(readV3S32(is) == v3s32(-400, 6400054, 290549855)); + + UASSERT(readV3F1000(is) == v3f(500, 10024.2f, -192.54f)); + UASSERT(readARGB8(is) == video::SColor(255, 128, 50, 128)); + + UASSERT(deSerializeString32(is) == "some longer string here"); + + UASSERT(is.rdbuf()->in_avail() == 2); + UASSERT(readU16(is) == 0xF00D); + UASSERT(is.rdbuf()->in_avail() == 0); +} + + +void TestSerialization::testStreamWrite() +{ + std::ostringstream os(std::ios_base::binary); + std::string data; + + writeU8(os, 0x11); + writeU16(os, 0x2233); + writeU32(os, 0x44556677); + writeU64(os, 0x8899AABBCCDDEEFFLL); + + writeS8(os, -128); + writeS16(os, 30000); + writeS32(os, -6); + writeS64(os, -43); + + writeF1000(os, 53.53467f); + writeF1000(os, -300000.32f); + writeF1000(os, F1000_MIN); + writeF1000(os, F1000_MAX); + + os << serializeString16("foobar!"); + + data = os.str(); + UASSERT(data.size() < sizeof(test_serialized_data)); + UASSERT(!memcmp(&data[0], test_serialized_data, data.size())); + + writeV2S16(os, v2s16(500, 500)); + writeV3S16(os, v3s16(4207, 604, -30)); + writeV2S32(os, v2s32(1920, 1080)); + writeV3S32(os, v3s32(-400, 6400054, 290549855)); + + writeV3F1000(os, v3f(500, 10024.2f, -192.54f)); + writeARGB8(os, video::SColor(255, 128, 50, 128)); + + os << serializeString32("some longer string here"); + + writeU16(os, 0xF00D); + + data = os.str(); + UASSERT(data.size() == sizeof(test_serialized_data)); + UASSERT(!memcmp(&data[0], test_serialized_data, sizeof(test_serialized_data))); +} + + +void TestSerialization::testFloatFormat() +{ + FloatType type = getFloatSerializationType(); + u32 i; + f32 fs, fm; + + // Check precision of float calculations on this platform + const std::unordered_map<f32, u32> float_results = { + { 0.0f, 0x00000000UL }, + { 1.0f, 0x3F800000UL }, + { -1.0f, 0xBF800000UL }, + { 0.1f, 0x3DCCCCCDUL }, + { -0.1f, 0xBDCCCCCDUL }, + { 1945329.25f, 0x49ED778AUL }, + { -23298764.f, 0xCBB1C166UL }, + { 0.5f, 0x3F000000UL }, + { -0.5f, 0xBF000000UL } + }; + for (const auto &v : float_results) { + i = f32Tou32Slow(v.first); + if (std::abs((s64)v.second - i) > 32) { + printf("Inaccurate float values on %.9g, expected 0x%X, actual 0x%X\n", + v.first, v.second, i); + UASSERT(false); + } + + fs = u32Tof32Slow(v.second); + if (std::fabs(v.first - fs) > std::fabs(v.first * 0.000005f)) { + printf("Inaccurate float values on 0x%X, expected %.9g, actual 0x%.9g\n", + v.second, v.first, fs); + UASSERT(false); + } + } + + if (type == FLOATTYPE_SLOW) { + // conversion using memcpy is not possible + // Skip exact float comparison checks below + return; + } + + // The code below compares the IEEE conversion functions with a + // known good IEC559/IEEE754 implementation. This test neeeds + // IEC559 compliance in the compiler. +#if defined(__GNUC__) && (!defined(__STDC_IEC_559__) || defined(__FAST_MATH__)) + // GNU C++ lies about its IEC559 support when -ffast-math is active. + // https://gcc.gnu.org/bugzilla//show_bug.cgi?id=84949 + bool is_iec559 = false; +#else + bool is_iec559 = std::numeric_limits<f32>::is_iec559; +#endif + if (!is_iec559) + return; + + auto test_single = [&fs, &fm](const u32 &i) -> bool { + memcpy(&fm, &i, 4); + fs = u32Tof32Slow(i); + if (fm != fs) { + printf("u32Tof32Slow failed on 0x%X, expected %.9g, actual %.9g\n", + i, fm, fs); + return false; + } + if (f32Tou32Slow(fs) != i) { + printf("f32Tou32Slow failed on %.9g, expected 0x%X, actual 0x%X\n", + fs, i, f32Tou32Slow(fs)); + return false; + } + return true; + }; + + // Use step of prime 277 to speed things up from 3 minutes to a few seconds + // Test from 0 to 0xFF800000UL (positive) + for (i = 0x00000000UL; i <= 0x7F800000UL; i += 277) + UASSERT(test_single(i)); + + // Ensure +inf and -inf are tested + UASSERT(test_single(0x7F800000UL)); + UASSERT(test_single(0xFF800000UL)); + + // Test from 0x80000000UL to 0xFF800000UL (negative) + for (i = 0x80000000UL; i <= 0xFF800000UL; i += 277) + UASSERT(test_single(i)); +} + +const u8 TestSerialization::test_serialized_data[12 * 11 - 2] = { + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0x80, 0x75, 0x30, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x00, 0x00, 0xd1, 0x1e, 0xee, 0x1e, + 0x5b, 0xc0, 0x80, 0x00, 0x02, 0x80, 0x7F, 0xFF, 0xFD, 0x80, 0x00, 0x07, + 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x21, 0x01, 0xf4, 0x01, 0xf4, 0x10, + 0x6f, 0x02, 0x5c, 0xff, 0xe2, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x04, + 0x38, 0xff, 0xff, 0xfe, 0x70, 0x00, 0x61, 0xa8, 0x36, 0x11, 0x51, 0x70, + 0x5f, 0x00, 0x07, 0xa1, 0x20, 0x00, 0x98, 0xf5, 0x08, 0xff, + 0xfd, 0x0f, 0xe4, 0xff, 0x80, 0x32, 0x80, 0x00, 0x00, 0x00, 0x17, 0x73, + 0x6f, 0x6d, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x65, 0x72, 0x65, 0xF0, 0x0D, +}; diff --git a/src/unittest/test_server_shutdown_state.cpp b/src/unittest/test_server_shutdown_state.cpp new file mode 100644 index 0000000..50305e7 --- /dev/null +++ b/src/unittest/test_server_shutdown_state.cpp @@ -0,0 +1,120 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <server.h> +#include "test.h" + +#include "util/string.h" +#include "util/serialize.h" + +class FakeServer : public Server +{ +public: + FakeServer() : Server("fakeworld", SubgameSpec("fakespec", "fakespec"), true, + Address(), true, nullptr) + { + } + +private: + void SendChatMessage(session_t peer_id, const ChatMessage &message) + { + // NOOP + } +}; + +class TestServerShutdownState : public TestBase +{ +public: + TestServerShutdownState() { TestManager::registerTestModule(this); } + const char *getName() { return "TestServerShutdownState"; } + + void runTests(IGameDef *gamedef); + + void testInit(); + void testReset(); + void testTrigger(); + void testTick(); +}; + +static TestServerShutdownState g_test_instance; + +void TestServerShutdownState::runTests(IGameDef *gamedef) +{ + TEST(testInit); + TEST(testReset); + TEST(testTrigger); + TEST(testTick); +} + +void TestServerShutdownState::testInit() +{ + Server::ShutdownState ss; + UASSERT(!ss.is_requested); + UASSERT(!ss.should_reconnect); + UASSERT(ss.message.empty()); + UASSERT(ss.m_timer == 0.0f); +} + +void TestServerShutdownState::testReset() +{ + Server::ShutdownState ss; + ss.reset(); + UASSERT(!ss.is_requested); + UASSERT(!ss.should_reconnect); + UASSERT(ss.message.empty()); + UASSERT(ss.m_timer == 0.0f); +} + +void TestServerShutdownState::testTrigger() +{ + Server::ShutdownState ss; + ss.trigger(3.0f, "testtrigger", true); + UASSERT(!ss.is_requested); + UASSERT(ss.should_reconnect); + UASSERT(ss.message == "testtrigger"); + UASSERT(ss.m_timer == 3.0f); +} + +void TestServerShutdownState::testTick() +{ + auto fakeServer = std::make_unique<FakeServer>(); + Server::ShutdownState ss; + ss.trigger(28.0f, "testtrigger", true); + ss.tick(0.0f, fakeServer.get()); + + // Tick with no time should not change anything + UASSERT(!ss.is_requested); + UASSERT(ss.should_reconnect); + UASSERT(ss.message == "testtrigger"); + UASSERT(ss.m_timer == 28.0f); + + // Tick 2 seconds + ss.tick(2.0f, fakeServer.get()); + UASSERT(!ss.is_requested); + UASSERT(ss.should_reconnect); + UASSERT(ss.message == "testtrigger"); + UASSERT(ss.m_timer == 26.0f); + + // Tick remaining seconds + additional expire + ss.tick(26.1f, fakeServer.get()); + UASSERT(ss.is_requested); + UASSERT(ss.should_reconnect); + UASSERT(ss.message == "testtrigger"); + UASSERT(ss.m_timer == 0.0f); +} diff --git a/src/unittest/test_serveractiveobjectmgr.cpp b/src/unittest/test_serveractiveobjectmgr.cpp new file mode 100644 index 0000000..aa00474 --- /dev/null +++ b/src/unittest/test_serveractiveobjectmgr.cpp @@ -0,0 +1,200 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "server/activeobjectmgr.h" +#include <algorithm> +#include <queue> +#include "test.h" + +#include "profiler.h" + +class TestServerActiveObject : public ServerActiveObject +{ +public: + TestServerActiveObject(const v3f &p = v3f()) : ServerActiveObject(nullptr, p) {} + ~TestServerActiveObject() = default; + ActiveObjectType getType() const override { return ACTIVEOBJECT_TYPE_TEST; } + bool getCollisionBox(aabb3f *toset) const override { return false; } + bool getSelectionBox(aabb3f *toset) const override { return false; } + bool collideWithObjects() const override { return false; } +}; + +class TestServerActiveObjectMgr : public TestBase +{ +public: + TestServerActiveObjectMgr() { TestManager::registerTestModule(this); } + const char *getName() { return "TestServerActiveObjectMgr"; } + + void runTests(IGameDef *gamedef); + + void testFreeID(); + void testRegisterObject(); + void testRemoveObject(); + void testGetObjectsInsideRadius(); + void testGetAddedActiveObjectsAroundPos(); +}; + +static TestServerActiveObjectMgr g_test_instance; + +void TestServerActiveObjectMgr::runTests(IGameDef *gamedef) +{ + TEST(testFreeID); + TEST(testRegisterObject) + TEST(testRemoveObject) + TEST(testGetObjectsInsideRadius); + TEST(testGetAddedActiveObjectsAroundPos); +} + +void clearSAOMgr(server::ActiveObjectMgr *saomgr) +{ + auto clear_cb = [](ServerActiveObject *obj, u16 id) { + delete obj; + return true; + }; + saomgr->clear(clear_cb); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestServerActiveObjectMgr::testFreeID() +{ + server::ActiveObjectMgr saomgr; + std::vector<u16> aoids; + + u16 aoid = saomgr.getFreeId(); + // Ensure it's not the same id + UASSERT(saomgr.getFreeId() != aoid); + + aoids.push_back(aoid); + + // Register basic objects, ensure we never found + for (u8 i = 0; i < UINT8_MAX; i++) { + // Register an object + auto tsao = new TestServerActiveObject(); + saomgr.registerObject(tsao); + aoids.push_back(tsao->getId()); + + // Ensure next id is not in registered list + UASSERT(std::find(aoids.begin(), aoids.end(), saomgr.getFreeId()) == + aoids.end()); + } + + clearSAOMgr(&saomgr); +} + +void TestServerActiveObjectMgr::testRegisterObject() +{ + server::ActiveObjectMgr saomgr; + auto tsao = new TestServerActiveObject(); + UASSERT(saomgr.registerObject(tsao)); + + u16 id = tsao->getId(); + + auto tsaoToCompare = saomgr.getActiveObject(id); + UASSERT(tsaoToCompare->getId() == id); + UASSERT(tsaoToCompare == tsao); + + tsao = new TestServerActiveObject(); + UASSERT(saomgr.registerObject(tsao)); + UASSERT(saomgr.getActiveObject(tsao->getId()) == tsao); + UASSERT(saomgr.getActiveObject(tsao->getId()) != tsaoToCompare); + + clearSAOMgr(&saomgr); +} + +void TestServerActiveObjectMgr::testRemoveObject() +{ + server::ActiveObjectMgr saomgr; + auto tsao = new TestServerActiveObject(); + UASSERT(saomgr.registerObject(tsao)); + + u16 id = tsao->getId(); + UASSERT(saomgr.getActiveObject(id) != nullptr) + + saomgr.removeObject(tsao->getId()); + UASSERT(saomgr.getActiveObject(id) == nullptr); + + clearSAOMgr(&saomgr); +} + +void TestServerActiveObjectMgr::testGetObjectsInsideRadius() +{ + server::ActiveObjectMgr saomgr; + static const v3f sao_pos[] = { + v3f(10, 40, 10), + v3f(740, 100, -304), + v3f(-200, 100, -304), + v3f(740, -740, -304), + v3f(1500, -740, -304), + }; + + for (const auto &p : sao_pos) { + saomgr.registerObject(new TestServerActiveObject(p)); + } + + std::vector<ServerActiveObject *> result; + saomgr.getObjectsInsideRadius(v3f(), 50, result, nullptr); + UASSERTCMP(int, ==, result.size(), 1); + + result.clear(); + saomgr.getObjectsInsideRadius(v3f(), 750, result, nullptr); + UASSERTCMP(int, ==, result.size(), 2); + + result.clear(); + saomgr.getObjectsInsideRadius(v3f(), 750000, result, nullptr); + UASSERTCMP(int, ==, result.size(), 5); + + result.clear(); + auto include_obj_cb = [](ServerActiveObject *obj) { + return (obj->getBasePosition().X != 10); + }; + + saomgr.getObjectsInsideRadius(v3f(), 750000, result, include_obj_cb); + UASSERTCMP(int, ==, result.size(), 4); + + clearSAOMgr(&saomgr); +} + +void TestServerActiveObjectMgr::testGetAddedActiveObjectsAroundPos() +{ + server::ActiveObjectMgr saomgr; + static const v3f sao_pos[] = { + v3f(10, 40, 10), + v3f(740, 100, -304), + v3f(-200, 100, -304), + v3f(740, -740, -304), + v3f(1500, -740, -304), + }; + + for (const auto &p : sao_pos) { + saomgr.registerObject(new TestServerActiveObject(p)); + } + + std::queue<u16> result; + std::set<u16> cur_objects; + saomgr.getAddedActiveObjectsAroundPos(v3f(), 100, 50, cur_objects, result); + UASSERTCMP(int, ==, result.size(), 1); + + result = std::queue<u16>(); + cur_objects.clear(); + saomgr.getAddedActiveObjectsAroundPos(v3f(), 740, 50, cur_objects, result); + UASSERTCMP(int, ==, result.size(), 2); + + clearSAOMgr(&saomgr); +} diff --git a/src/unittest/test_servermodmanager.cpp b/src/unittest/test_servermodmanager.cpp new file mode 100644 index 0000000..91bf5d3 --- /dev/null +++ b/src/unittest/test_servermodmanager.cpp @@ -0,0 +1,201 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" +#include <algorithm> +#include "server/mods.h" +#include "settings.h" +#include "test_config.h" +#include "util/string.h" + +class TestServerModManager : public TestBase +{ +public: + TestServerModManager() { TestManager::registerTestModule(this); } + const char *getName() { return "TestServerModManager"; } + + void runTests(IGameDef *gamedef); + + void testCreation(); + void testIsConsistent(); + void testUnsatisfiedMods(); + void testGetMods(); + void testGetModsWrongDir(); + void testGetModspec(); + void testGetModNamesWrongDir(); + void testGetModNames(); + void testGetModMediaPathsWrongDir(); + void testGetModMediaPaths(); +}; + +static TestServerModManager g_test_instance; + +void TestServerModManager::runTests(IGameDef *gamedef) +{ + const char *saved_env_mt_subgame_path = getenv("MINETEST_SUBGAME_PATH"); + const char *saved_env_mt_mod_path = getenv("MINETEST_MOD_PATH"); +#ifdef WIN32 + { + std::string subgame_path("MINETEST_SUBGAME_PATH="); + subgame_path.append(TEST_SUBGAME_PATH); + _putenv(subgame_path.c_str()); + + std::string mod_path("MINETEST_MOD_PATH="); + mod_path.append(TEST_MOD_PATH); + _putenv(mod_path.c_str()); + } +#else + setenv("MINETEST_SUBGAME_PATH", TEST_SUBGAME_PATH, 1); + setenv("MINETEST_MOD_PATH", TEST_MOD_PATH, 1); +#endif + + TEST(testCreation); + TEST(testIsConsistent); + TEST(testGetModsWrongDir); + TEST(testUnsatisfiedMods); + TEST(testGetMods); + TEST(testGetModspec); + TEST(testGetModNamesWrongDir); + TEST(testGetModNames); + TEST(testGetModMediaPathsWrongDir); + TEST(testGetModMediaPaths); + +#ifdef WIN32 + { + std::string subgame_path("MINETEST_SUBGAME_PATH="); + if (saved_env_mt_subgame_path) + subgame_path.append(saved_env_mt_subgame_path); + _putenv(subgame_path.c_str()); + + std::string mod_path("MINETEST_MOD_PATH="); + if (saved_env_mt_mod_path) + mod_path.append(saved_env_mt_mod_path); + _putenv(mod_path.c_str()); + } +#else + if (saved_env_mt_subgame_path) + setenv("MINETEST_SUBGAME_PATH", saved_env_mt_subgame_path, 1); + else + unsetenv("MINETEST_SUBGAME_PATH"); + if (saved_env_mt_mod_path) + setenv("MINETEST_MOD_PATH", saved_env_mt_mod_path, 1); + else + unsetenv("MINETEST_MOD_PATH"); +#endif +} + +void TestServerModManager::testCreation() +{ + std::string path = std::string(TEST_WORLDDIR) + DIR_DELIM + "world.mt"; + Settings world_config; + world_config.set("gameid", "devtest"); + world_config.set("load_mod_test_mod", "true"); + UASSERTEQ(bool, world_config.updateConfigFile(path.c_str()), true); + ServerModManager sm(TEST_WORLDDIR); +} + +void TestServerModManager::testGetModsWrongDir() +{ + // Test in non worlddir to ensure no mods are found + ServerModManager sm(std::string(TEST_WORLDDIR) + DIR_DELIM + ".."); + UASSERTEQ(bool, sm.getMods().empty(), true); +} + +void TestServerModManager::testUnsatisfiedMods() +{ + ServerModManager sm(std::string(TEST_WORLDDIR)); + UASSERTEQ(bool, sm.getUnsatisfiedMods().empty(), true); +} + +void TestServerModManager::testIsConsistent() +{ + ServerModManager sm(std::string(TEST_WORLDDIR)); + UASSERTEQ(bool, sm.isConsistent(), true); +} + +void TestServerModManager::testGetMods() +{ + ServerModManager sm(std::string(TEST_WORLDDIR)); + const auto &mods = sm.getMods(); + UASSERTEQ(bool, mods.empty(), false); + + // Ensure we found basenodes mod (part of devtest) + // and test_mod (for testing MINETEST_MOD_PATH). + bool default_found = false; + bool test_mod_found = false; + for (const auto &m : mods) { + if (m.name == "basenodes") + default_found = true; + if (m.name == "test_mod") + test_mod_found = true; + + // Verify if paths are not empty + UASSERTEQ(bool, m.path.empty(), false); + } + + UASSERTEQ(bool, default_found, true); + UASSERTEQ(bool, test_mod_found, true); +} + +void TestServerModManager::testGetModspec() +{ + ServerModManager sm(std::string(TEST_WORLDDIR)); + UASSERTEQ(const ModSpec *, sm.getModSpec("wrongmod"), NULL); + UASSERT(sm.getModSpec("basenodes") != NULL); +} + +void TestServerModManager::testGetModNamesWrongDir() +{ + ServerModManager sm(std::string(TEST_WORLDDIR) + DIR_DELIM + ".."); + std::vector<std::string> result; + sm.getModNames(result); + UASSERTEQ(bool, result.empty(), true); +} + +void TestServerModManager::testGetModNames() +{ + ServerModManager sm(std::string(TEST_WORLDDIR)); + std::vector<std::string> result; + sm.getModNames(result); + UASSERTEQ(bool, result.empty(), false); + UASSERT(std::find(result.begin(), result.end(), "basenodes") != result.end()); +} + +void TestServerModManager::testGetModMediaPathsWrongDir() +{ + ServerModManager sm(std::string(TEST_WORLDDIR) + DIR_DELIM + ".."); + std::vector<std::string> result; + sm.getModsMediaPaths(result); + UASSERTEQ(bool, result.empty(), true); +} + +void TestServerModManager::testGetModMediaPaths() +{ + ServerModManager sm(std::string(TEST_WORLDDIR)); + std::vector<std::string> result; + sm.getModsMediaPaths(result); + UASSERTEQ(bool, result.empty(), false); + + // Test media overriding: + // unittests depends on basenodes to override default_dirt.png, + // thus the unittests texture path must come first in the returned media paths to take priority + auto it = std::find(result.begin(), result.end(), sm.getModSpec("unittests")->path + DIR_DELIM + "textures"); + UASSERT(it != result.end()); + UASSERT(std::find(++it, result.end(), sm.getModSpec("basenodes")->path + DIR_DELIM + "textures") != result.end()); +} diff --git a/src/unittest/test_settings.cpp b/src/unittest/test_settings.cpp new file mode 100644 index 0000000..6b493c9 --- /dev/null +++ b/src/unittest/test_settings.cpp @@ -0,0 +1,296 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <cmath> +#include "settings.h" +#include "defaultsettings.h" +#include "noise.h" + +class TestSettings : public TestBase { +public: + TestSettings() { TestManager::registerTestModule(this); } + const char *getName() { return "TestSettings"; } + + void runTests(IGameDef *gamedef); + + void testAllSettings(); + void testDefaults(); + void testFlagDesc(); + + static const char *config_text_before; + static const std::string config_text_after; +}; + +static TestSettings g_test_instance; + +void TestSettings::runTests(IGameDef *gamedef) +{ + TEST(testAllSettings); + TEST(testDefaults); + TEST(testFlagDesc); +} + +//////////////////////////////////////////////////////////////////////////////// + +const char *TestSettings::config_text_before = + "leet = 1337\n" + "leetleet = 13371337\n" + "leetleet_neg = -13371337\n" + "floaty_thing = 1.1\n" + "stringy_thing = asd /( ¤%&(/\" BLÖÄRP\n" + "coord = (1, 2, 4.5)\n" + " # this is just a comment\n" + "this is an invalid line\n" + "asdf = {\n" + " a = 5\n" + " bb = 2.5\n" + " ccc = \"\"\"\n" + "testy\n" + " testa \n" + "\"\"\"\n" + "\n" + "}\n" + "blarg = \"\"\" \n" + "some multiline text\n" + " with leading whitespace!\n" + "\"\"\"\n" + "np_terrain = 5, 40, (250, 250, 250), 12341, 5, 0.7, 2.4\n" + "zoop = true\n" + "[dummy_eof_end_tag]\n"; + +const std::string TestSettings::config_text_after = + "leet = 1337\n" + "leetleet = 13371337\n" + "leetleet_neg = -13371337\n" + "floaty_thing = 1.1\n" + "stringy_thing = asd /( ¤%&(/\" BLÖÄRP\n" + "coord = (1, 2, 4.5)\n" + " # this is just a comment\n" + "this is an invalid line\n" + "asdf = {\n" + " a = 5\n" + " bb = 2.5\n" + " ccc = \"\"\"\n" + "testy\n" + " testa \n" + "\"\"\"\n" + "\n" + "}\n" + "blarg = \"\"\" \n" + "some multiline text\n" + " with leading whitespace!\n" + "\"\"\"\n" + "np_terrain = {\n" + " flags = defaults\n" + " lacunarity = 2.4\n" + " octaves = 6\n" + " offset = 3.5\n" + " persistence = 0.7\n" + " scale = 40\n" + " seed = 12341\n" + " spread = (250,250,250)\n" + "}\n" + "zoop = true\n" + "coord2 = (1,2,3.3)\n" + "floaty_thing_2 = 1.2\n" + "groupy_thing = {\n" + " animals = cute\n" + " num_apples = 4\n" + " num_oranges = 53\n" + "}\n" + "[dummy_eof_end_tag]"; + +void compare_settings(const std::string &name, Settings *a, Settings *b) +{ + auto keys = a->getNames(); + Settings *group1, *group2; + std::string value1, value2; + for (auto &key : keys) { + if (a->getGroupNoEx(key, group1)) { + UASSERT(b->getGroupNoEx(key, group2)); + + compare_settings(name + "->" + key, group1, group2); + continue; + } + + UASSERT(b->getNoEx(key, value1)); + // For identification + value1 = name + "->" + key + "=" + value1; + value2 = name + "->" + key + "=" + a->get(key); + UASSERTCMP(std::string, ==, value2, value1); + } +} + +void TestSettings::testAllSettings() +{ + try { + Settings s("[dummy_eof_end_tag]"); + + // Test reading of settings + std::istringstream is(config_text_before); + s.parseConfigLines(is); + + UASSERT(s.getS32("leet") == 1337); + UASSERT(s.getS16("leetleet") == 32767); + UASSERT(s.getS16("leetleet_neg") == -32768); + + // Not sure if 1.1 is an exact value as a float, but doesn't matter + UASSERT(fabs(s.getFloat("floaty_thing") - 1.1) < 0.001); + UASSERT(s.get("stringy_thing") == "asd /( ¤%&(/\" BLÖÄRP"); + UASSERT(fabs(s.getV3F("coord").X - 1.0) < 0.001); + UASSERT(fabs(s.getV3F("coord").Y - 2.0) < 0.001); + UASSERT(fabs(s.getV3F("coord").Z - 4.5) < 0.001); + + // Test the setting of settings too + s.setFloat("floaty_thing_2", 1.2); + s.setV3F("coord2", v3f(1, 2, 3.3)); + UASSERT(s.get("floaty_thing_2").substr(0,3) == "1.2"); + UASSERT(fabs(s.getFloat("floaty_thing_2") - 1.2) < 0.001); + UASSERT(fabs(s.getV3F("coord2").X - 1.0) < 0.001); + UASSERT(fabs(s.getV3F("coord2").Y - 2.0) < 0.001); + UASSERT(fabs(s.getV3F("coord2").Z - 3.3) < 0.001); + + // Test settings groups + Settings *group = s.getGroup("asdf"); + UASSERT(group != NULL); + UASSERT(s.getGroupNoEx("zoop", group) == false); + UASSERT(group->getS16("a") == 5); + UASSERT(fabs(group->getFloat("bb") - 2.5) < 0.001); + + Settings group3; + group3.set("cat", "meow"); + group3.set("dog", "woof"); + + Settings group2; + group2.setS16("num_apples", 4); + group2.setS16("num_oranges", 53); + group2.setGroup("animals", group3); + group2.set("animals", "cute"); //destroys group 3 + s.setGroup("groupy_thing", group2); + + // Test set failure conditions + UASSERT(s.set("Zoop = Poop\nsome_other_setting", "false") == false); + UASSERT(s.set("sneaky", "\"\"\"\njabberwocky = false") == false); + UASSERT(s.set("hehe", "asdfasdf\n\"\"\"\nsomething = false") == false); + + // Test multiline settings + UASSERT(group->get("ccc") == "testy\n testa "); + + UASSERT(s.get("blarg") == + "some multiline text\n" + " with leading whitespace!"); + + // Test NoiseParams + UASSERT(s.getEntry("np_terrain").is_group == false); + + NoiseParams np; + UASSERT(s.getNoiseParams("np_terrain", np) == true); + UASSERT(std::fabs(np.offset - 5) < 0.001f); + UASSERT(std::fabs(np.scale - 40) < 0.001f); + UASSERT(std::fabs(np.spread.X - 250) < 0.001f); + UASSERT(std::fabs(np.spread.Y - 250) < 0.001f); + UASSERT(std::fabs(np.spread.Z - 250) < 0.001f); + UASSERT(np.seed == 12341); + UASSERT(np.octaves == 5); + UASSERT(std::fabs(np.persist - 0.7) < 0.001f); + + np.offset = 3.5; + np.octaves = 6; + s.setNoiseParams("np_terrain", np); + + UASSERT(s.getEntry("np_terrain").is_group == true); + + // Test writing + std::ostringstream os(std::ios_base::binary); + is.clear(); + is.seekg(0); + + UASSERT(s.updateConfigObject(is, os, 0) == true); + + { + // Confirm settings + Settings s2("[dummy_eof_end_tag]"); + std::istringstream is(config_text_after, std::ios_base::binary); + UASSERT(s2.parseConfigLines(is) == true); + + compare_settings("(main)", &s, &s2); + } + + } catch (SettingNotFoundException &e) { + UASSERT(!"Setting not found!"); + } +} + +void TestSettings::testDefaults() +{ + Settings *game = Settings::createLayer(SL_GAME); + Settings *def = Settings::getLayer(SL_DEFAULTS); + + def->set("name", "FooBar"); + UASSERT(def->get("name") == "FooBar"); + UASSERT(game->get("name") == "FooBar"); + + game->set("name", "Baz"); + UASSERT(game->get("name") == "Baz"); + + delete game; + + // Restore default settings + delete Settings::getLayer(SL_DEFAULTS); + set_default_settings(); +} + +void TestSettings::testFlagDesc() +{ + Settings &s = *Settings::createLayer(SL_GAME); + FlagDesc flagdesc[] = { + { "biomes", 0x01 }, + { "trees", 0x02 }, + { "jungles", 0x04 }, + { "oranges", 0x08 }, + { "tables", 0x10 }, + { nullptr, 0 } + }; + + // Enabled: biomes, jungles, oranges (default) + s.setDefault("test_desc", flagdesc, readFlagString( + "biomes,notrees,jungles,oranges", flagdesc, nullptr)); + UASSERT(s.getFlagStr("test_desc", flagdesc, nullptr) == (0x01 | 0x04 | 0x08)); + + // Enabled: jungles, oranges, tables + s.set("test_desc", "nobiomes,tables"); + UASSERT(s.getFlagStr("test_desc", flagdesc, nullptr) == (0x04 | 0x08 | 0x10)); + + // Enabled: (nothing) + s.set("test_desc", "nobiomes,nojungles,nooranges,notables"); + UASSERT(s.getFlagStr("test_desc", flagdesc, nullptr) == 0x00); + + // Numeric flag tests (override) + // Enabled: trees, tables + s.setDefault("test_flags", flagdesc, 0x02 | 0x10); + UASSERT(s.getFlagStr("test_flags", flagdesc, nullptr) == (0x02 | 0x10)); + + // Enabled: tables + s.set("test_flags", "16"); + UASSERT(s.getFlagStr("test_flags", flagdesc, nullptr) == 0x10); + + delete &s; +} diff --git a/src/unittest/test_socket.cpp b/src/unittest/test_socket.cpp new file mode 100644 index 0000000..620021b --- /dev/null +++ b/src/unittest/test_socket.cpp @@ -0,0 +1,149 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "log.h" +#include "settings.h" +#include "network/socket.h" + +class TestSocket : public TestBase { +public: + TestSocket() + { + if (INTERNET_SIMULATOR == false) + TestManager::registerTestModule(this); + } + + const char *getName() { return "TestSocket"; } + + void runTests(IGameDef *gamedef); + + void testIPv4Socket(); + void testIPv6Socket(); + + static const int port = 30003; +}; + +static TestSocket g_test_instance; + +void TestSocket::runTests(IGameDef *gamedef) +{ + TEST(testIPv4Socket); + + if (g_settings->getBool("enable_ipv6")) + TEST(testIPv6Socket); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestSocket::testIPv4Socket() +{ + Address address(0, 0, 0, 0, port); + Address bind_addr(0, 0, 0, 0, port); + + /* + * Try to use the bind_address for servers with no localhost address + * For example: FreeBSD jails + */ + std::string bind_str = g_settings->get("bind_address"); + try { + bind_addr.Resolve(bind_str.c_str()); + + if (!bind_addr.isIPv6()) { + address = bind_addr; + } + } catch (ResolveError &e) { + } + + UDPSocket socket(false); + socket.Bind(address); + + const char sendbuffer[] = "hello world!"; + /* + * If there is a bind address, use it. + * It's useful in container environments + */ + if (address != Address(0, 0, 0, 0, port)) + socket.Send(address, sendbuffer, sizeof(sendbuffer)); + else + socket.Send(Address(127, 0, 0, 1, port), sendbuffer, sizeof(sendbuffer)); + + sleep_ms(50); + + char rcvbuffer[256] = { 0 }; + Address sender; + for (;;) { + if (socket.Receive(sender, rcvbuffer, sizeof(rcvbuffer)) < 0) + break; + } + //FIXME: This fails on some systems + UASSERT(strncmp(sendbuffer, rcvbuffer, sizeof(sendbuffer)) == 0); + + if (address != Address(0, 0, 0, 0, port)) { + UASSERT(sender.getAddress().s_addr == + address.getAddress().s_addr); + } else { + UASSERT(sender.getAddress().s_addr == + Address(127, 0, 0, 1, 0).getAddress().s_addr); + } +} + +void TestSocket::testIPv6Socket() +{ + Address address6((IPv6AddressBytes *)NULL, port); + UDPSocket socket6; + + if (!socket6.init(true, true)) { + /* Note: Failing to create an IPv6 socket is not technically an + error because the OS may not support IPv6 or it may + have been disabled. IPv6 is not /required/ by + minetest and therefore this should not cause the unit + test to fail + */ + dstream << "WARNING: IPv6 socket creation failed (unit test)" + << std::endl; + return; + } + + const char sendbuffer[] = "hello world!"; + IPv6AddressBytes bytes; + bytes.bytes[15] = 1; + + socket6.Bind(address6); + + { + socket6.Send(Address(&bytes, port), sendbuffer, sizeof(sendbuffer)); + + sleep_ms(50); + + char rcvbuffer[256] = { 0 }; + Address sender; + + for(;;) { + if (socket6.Receive(sender, rcvbuffer, sizeof(rcvbuffer)) < 0) + break; + } + //FIXME: This fails on some systems + UASSERT(strncmp(sendbuffer, rcvbuffer, sizeof(sendbuffer)) == 0); + + UASSERT(memcmp(sender.getAddress6().s6_addr, + Address(&bytes, 0).getAddress6().s6_addr, 16) == 0); + } +} diff --git a/src/unittest/test_threading.cpp b/src/unittest/test_threading.cpp new file mode 100644 index 0000000..65ef7c0 --- /dev/null +++ b/src/unittest/test_threading.cpp @@ -0,0 +1,158 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <atomic> +#include "threading/semaphore.h" +#include "threading/thread.h" + + +class TestThreading : public TestBase { +public: + TestThreading() { TestManager::registerTestModule(this); } + const char *getName() { return "TestThreading"; } + void runTests(IGameDef *gamedef); + + void testStartStopWait(); + void testAtomicSemaphoreThread(); +}; + +static TestThreading g_test_instance; + +void TestThreading::runTests(IGameDef *gamedef) +{ + TEST(testStartStopWait); + TEST(testAtomicSemaphoreThread); +} + +class SimpleTestThread : public Thread { +public: + SimpleTestThread(unsigned int interval) : + Thread("SimpleTest"), + m_interval(interval) + { + } + +private: + void *run() + { + void *retval = this; + + if (isCurrentThread() == false) + retval = (void *)0xBAD; + + while (!stopRequested()) + sleep_ms(m_interval); + + return retval; + } + + unsigned int m_interval; +}; + +void TestThreading::testStartStopWait() +{ + void *thread_retval; + SimpleTestThread *thread = new SimpleTestThread(25); + + // Try this a couple times, since a Thread should be reusable after waiting + for (size_t i = 0; i != 5; i++) { + // Can't wait() on a joined, stopped thread + UASSERT(thread->wait() == false); + + // start() should work the first time, but not the second. + UASSERT(thread->start() == true); + UASSERT(thread->start() == false); + + UASSERT(thread->isRunning() == true); + UASSERT(thread->isCurrentThread() == false); + + // Let it loop a few times... + sleep_ms(70); + + // It's still running, so the return value shouldn't be available to us. + UASSERT(thread->getReturnValue(&thread_retval) == false); + + // stop() should always succeed + UASSERT(thread->stop() == true); + + // wait() only needs to wait the first time - the other two are no-ops. + UASSERT(thread->wait() == true); + UASSERT(thread->wait() == false); + UASSERT(thread->wait() == false); + + // Now that the thread is stopped, we should be able to get the + // return value, and it should be the object itself. + thread_retval = NULL; + UASSERT(thread->getReturnValue(&thread_retval) == true); + UASSERT(thread_retval == thread); + } + + delete thread; +} + + + +class AtomicTestThread : public Thread { +public: + AtomicTestThread(std::atomic<u32> &v, Semaphore &trigger) : + Thread("AtomicTest"), + val(v), + trigger(trigger) + { + } + +private: + void *run() + { + trigger.wait(); + for (u32 i = 0; i < 0x10000; ++i) + ++val; + return NULL; + } + + std::atomic<u32> &val; + Semaphore &trigger; +}; + + +void TestThreading::testAtomicSemaphoreThread() +{ + std::atomic<u32> val; + val = 0; + Semaphore trigger; + static const u8 num_threads = 4; + + AtomicTestThread *threads[num_threads]; + for (auto &thread : threads) { + thread = new AtomicTestThread(val, trigger); + UASSERT(thread->start()); + } + + trigger.post(num_threads); + + for (AtomicTestThread *thread : threads) { + thread->wait(); + delete thread; + } + + UASSERT(val == num_threads * 0x10000); +} + diff --git a/src/unittest/test_utilities.cpp b/src/unittest/test_utilities.cpp new file mode 100644 index 0000000..98a143d --- /dev/null +++ b/src/unittest/test_utilities.cpp @@ -0,0 +1,638 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <cmath> +#include "util/enriched_string.h" +#include "util/numeric.h" +#include "util/string.h" +#include "util/base64.h" + +class TestUtilities : public TestBase { +public: + TestUtilities() { TestManager::registerTestModule(this); } + const char *getName() { return "TestUtilities"; } + + void runTests(IGameDef *gamedef); + + void testAngleWrapAround(); + void testWrapDegrees_0_360_v3f(); + void testLowercase(); + void testTrim(); + void testIsYes(); + void testRemoveStringEnd(); + void testUrlEncode(); + void testUrlDecode(); + void testPadString(); + void testStartsWith(); + void testStrEqual(); + void testStrToIntConversion(); + void testStringReplace(); + void testStringAllowed(); + void testAsciiPrintableHelper(); + void testUTF8(); + void testRemoveEscapes(); + void testWrapRows(); + void testEnrichedString(); + void testIsNumber(); + void testIsPowerOfTwo(); + void testMyround(); + void testStringJoin(); + void testEulerConversion(); + void testBase64(); + void testSanitizeDirName(); +}; + +static TestUtilities g_test_instance; + +void TestUtilities::runTests(IGameDef *gamedef) +{ + TEST(testAngleWrapAround); + TEST(testWrapDegrees_0_360_v3f); + TEST(testLowercase); + TEST(testTrim); + TEST(testIsYes); + TEST(testRemoveStringEnd); + TEST(testUrlEncode); + TEST(testUrlDecode); + TEST(testPadString); + TEST(testStartsWith); + TEST(testStrEqual); + TEST(testStrToIntConversion); + TEST(testStringReplace); + TEST(testStringAllowed); + TEST(testAsciiPrintableHelper); + TEST(testUTF8); + TEST(testRemoveEscapes); + TEST(testWrapRows); + TEST(testEnrichedString); + TEST(testIsNumber); + TEST(testIsPowerOfTwo); + TEST(testMyround); + TEST(testStringJoin); + TEST(testEulerConversion); + TEST(testBase64); + TEST(testSanitizeDirName); +} + +//////////////////////////////////////////////////////////////////////////////// + +inline float ref_WrapDegrees180(float f) +{ + // This is a slower alternative to the wrapDegrees_180() function; + // used as a reference for testing + float value = fmodf(f + 180, 360); + if (value < 0) + value += 360; + return value - 180; +} + + +inline float ref_WrapDegrees_0_360(float f) +{ + // This is a slower alternative to the wrapDegrees_0_360() function; + // used as a reference for testing + float value = fmodf(f, 360); + if (value < 0) + value += 360; + return value < 0 ? value + 360 : value; +} + + +void TestUtilities::testAngleWrapAround() { + UASSERT(fabs(modulo360f(100.0) - 100.0) < 0.001); + UASSERT(fabs(modulo360f(720.5) - 0.5) < 0.001); + UASSERT(fabs(modulo360f(-0.5) - (-0.5)) < 0.001); + UASSERT(fabs(modulo360f(-365.5) - (-5.5)) < 0.001); + + for (float f = -720; f <= -360; f += 0.25) { + UASSERT(std::fabs(modulo360f(f) - modulo360f(f + 360)) < 0.001); + } + + for (float f = -1440; f <= 1440; f += 0.25) { + UASSERT(std::fabs(modulo360f(f) - fmodf(f, 360)) < 0.001); + UASSERT(std::fabs(wrapDegrees_180(f) - ref_WrapDegrees180(f)) < 0.001); + UASSERT(std::fabs(wrapDegrees_0_360(f) - ref_WrapDegrees_0_360(f)) < 0.001); + UASSERT(wrapDegrees_0_360( + std::fabs(wrapDegrees_180(f) - wrapDegrees_0_360(f))) < 0.001); + } + +} + +void TestUtilities::testWrapDegrees_0_360_v3f() +{ + // only x test with little step + for (float x = -720.f; x <= 720; x += 0.05) { + v3f r = wrapDegrees_0_360_v3f(v3f(x, 0, 0)); + UASSERT(r.X >= 0.0f && r.X < 360.0f) + UASSERT(r.Y == 0.0f) + UASSERT(r.Z == 0.0f) + } + + // only y test with little step + for (float y = -720.f; y <= 720; y += 0.05) { + v3f r = wrapDegrees_0_360_v3f(v3f(0, y, 0)); + UASSERT(r.X == 0.0f) + UASSERT(r.Y >= 0.0f && r.Y < 360.0f) + UASSERT(r.Z == 0.0f) + } + + // only z test with little step + for (float z = -720.f; z <= 720; z += 0.05) { + v3f r = wrapDegrees_0_360_v3f(v3f(0, 0, z)); + UASSERT(r.X == 0.0f) + UASSERT(r.Y == 0.0f) + UASSERT(r.Z >= 0.0f && r.Z < 360.0f) + } + + // test the whole coordinate translation + for (float x = -720.f; x <= 720; x += 2.5) { + for (float y = -720.f; y <= 720; y += 2.5) { + for (float z = -720.f; z <= 720; z += 2.5) { + v3f r = wrapDegrees_0_360_v3f(v3f(x, y, z)); + UASSERT(r.X >= 0.0f && r.X < 360.0f) + UASSERT(r.Y >= 0.0f && r.Y < 360.0f) + UASSERT(r.Z >= 0.0f && r.Z < 360.0f) + } + } + } +} + + +void TestUtilities::testLowercase() +{ + UASSERT(lowercase("Foo bAR") == "foo bar"); + UASSERT(lowercase("eeeeeeaaaaaaaaaaaààààà") == "eeeeeeaaaaaaaaaaaààààà"); + UASSERT(lowercase("MINETEST-powa") == "minetest-powa"); +} + + +void TestUtilities::testTrim() +{ + UASSERT(trim("") == ""); + UASSERT(trim("dirt_with_grass") == "dirt_with_grass"); + UASSERT(trim("\n \t\r Foo bAR \r\n\t\t ") == "Foo bAR"); + UASSERT(trim("\n \t\r \r\n\t\t ") == ""); + UASSERT(trim(" a") == "a"); + UASSERT(trim("a ") == "a"); +} + + +void TestUtilities::testIsYes() +{ + UASSERT(is_yes("YeS") == true); + UASSERT(is_yes("") == false); + UASSERT(is_yes("FAlse") == false); + UASSERT(is_yes("-1") == true); + UASSERT(is_yes("0") == false); + UASSERT(is_yes("1") == true); + UASSERT(is_yes("2") == true); +} + + +void TestUtilities::testRemoveStringEnd() +{ + const char *ends[] = {"abc", "c", "bc", "", NULL}; + UASSERT(removeStringEnd("abc", ends) == ""); + UASSERT(removeStringEnd("bc", ends) == "b"); + UASSERT(removeStringEnd("12c", ends) == "12"); + UASSERT(removeStringEnd("foo", ends) == ""); +} + + +void TestUtilities::testUrlEncode() +{ + UASSERT(urlencode("\"Aardvarks lurk, OK?\"") + == "%22Aardvarks%20lurk%2C%20OK%3F%22"); +} + + +void TestUtilities::testUrlDecode() +{ + UASSERT(urldecode("%22Aardvarks%20lurk%2C%20OK%3F%22") + == "\"Aardvarks lurk, OK?\""); +} + + +void TestUtilities::testPadString() +{ + UASSERT(padStringRight("hello", 8) == "hello "); +} + +void TestUtilities::testStartsWith() +{ + UASSERT(str_starts_with(std::string(), std::string()) == true); + UASSERT(str_starts_with(std::string("the sharp pickaxe"), + std::string()) == true); + UASSERT(str_starts_with(std::string("the sharp pickaxe"), + std::string("the")) == true); + UASSERT(str_starts_with(std::string("the sharp pickaxe"), + std::string("The")) == false); + UASSERT(str_starts_with(std::string("the sharp pickaxe"), + std::string("The"), true) == true); + UASSERT(str_starts_with(std::string("T"), std::string("The")) == false); +} + +void TestUtilities::testStrEqual() +{ + UASSERT(str_equal(utf8_to_wide("abc"), utf8_to_wide("abc"))); + UASSERT(str_equal(utf8_to_wide("ABC"), utf8_to_wide("abc"), true)); +} + + +void TestUtilities::testStrToIntConversion() +{ + UASSERT(mystoi("123", 0, 1000) == 123); + UASSERT(mystoi("123", 0, 10) == 10); +} + + +void TestUtilities::testStringReplace() +{ + std::string test_str; + test_str = "Hello there"; + str_replace(test_str, "there", "world"); + UASSERT(test_str == "Hello world"); + test_str = "ThisAisAaAtest"; + str_replace(test_str, 'A', ' '); + UASSERT(test_str == "This is a test"); +} + + +void TestUtilities::testStringAllowed() +{ + UASSERT(string_allowed("hello", "abcdefghijklmno") == true); + UASSERT(string_allowed("123", "abcdefghijklmno") == false); + UASSERT(string_allowed_blacklist("hello", "123") == true); + UASSERT(string_allowed_blacklist("hello123", "123") == false); +} + +void TestUtilities::testAsciiPrintableHelper() +{ + UASSERT(IS_ASCII_PRINTABLE_CHAR('e') == true); + UASSERT(IS_ASCII_PRINTABLE_CHAR('\0') == false); + + // Ensures that there is no cutting off going on... + // If there were, 331 would be cut to 75 in this example + // and 73 is a valid ASCII char. + int ch = 331; + UASSERT(IS_ASCII_PRINTABLE_CHAR(ch) == false); +} + +void TestUtilities::testUTF8() +{ + UASSERT(utf8_to_wide("¤") == L"¤"); + + UASSERT(wide_to_utf8(L"¤") == "¤"); + + UASSERTEQ(std::string, wide_to_utf8(utf8_to_wide("")), ""); + UASSERTEQ(std::string, wide_to_utf8(utf8_to_wide("the shovel dug a crumbly node!")), + "the shovel dug a crumbly node!"); + UASSERTEQ(std::string, wide_to_utf8(utf8_to_wide("-ä-")), + "-ä-"); + UASSERTEQ(std::string, wide_to_utf8(utf8_to_wide("-\xF0\xA0\x80\x8B-")), + "-\xF0\xA0\x80\x8B-"); + +} + +void TestUtilities::testRemoveEscapes() +{ + UASSERT(unescape_enriched<wchar_t>( + L"abc\x1bXdef") == L"abcdef"); + UASSERT(unescape_enriched<wchar_t>( + L"abc\x1b(escaped)def") == L"abcdef"); + UASSERT(unescape_enriched<wchar_t>( + L"abc\x1b((escaped with parenthesis\\))def") == L"abcdef"); + UASSERT(unescape_enriched<wchar_t>( + L"abc\x1b(incomplete") == L"abc"); + UASSERT(unescape_enriched<wchar_t>( + L"escape at the end\x1b") == L"escape at the end"); + // Nested escapes not supported + UASSERT(unescape_enriched<wchar_t>( + L"abc\x1b(outer \x1b(inner escape)escape)def") == L"abcescape)def"); +} + +void TestUtilities::testWrapRows() +{ + UASSERT(wrap_rows("12345678",4) == "1234\n5678"); + // test that wrap_rows doesn't wrap inside multibyte sequences + { + const unsigned char s[] = { + 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2f, 0x72, 0x61, 0x70, 0x74, 0x6f, + 0x72, 0x2f, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0x2f, + 0x6d, 0x69, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x62, 0x69, + 0x6e, 0x2f, 0x2e, 0x2e, 0}; + std::string str((char *)s); + UASSERT(utf8_to_wide(wrap_rows(str, 20)) != L"<invalid UTF-8 string>"); + }; + { + const unsigned char s[] = { + 0x74, 0x65, 0x73, 0x74, 0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, + 0xd1, 0x82, 0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, + 0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0}; + std::string str((char *)s); + UASSERT(utf8_to_wide(wrap_rows(str, 8)) != L"<invalid UTF-8 string>"); + } +} + +void TestUtilities::testEnrichedString() +{ + EnrichedString str(L"Test bar"); + irr::video::SColor color(0xFF, 0, 0, 0xFF); + + UASSERT(str.substr(1, 3).getString() == L"est"); + str += L" BUZZ"; + UASSERT(str.substr(9, std::string::npos).getString() == L"BUZZ"); + str.setDefaultColor(color); // Blue foreground + UASSERT(str.getColors()[5] == color); + // Green background, then white and yellow text + str = L"\x1b(b@#0F0)Regular \x1b(c@#FF0)yellow"; + UASSERT(str.getColors()[2] == 0xFFFFFFFF); + str.setDefaultColor(color); // Blue foreground + UASSERT(str.getColors()[13] == 0xFFFFFF00); // Still yellow text + UASSERT(str.getBackground() == 0xFF00FF00); // Green background +} + +void TestUtilities::testIsNumber() +{ + UASSERT(is_number("123") == true); + UASSERT(is_number("") == false); + UASSERT(is_number("123a") == false); +} + + +void TestUtilities::testIsPowerOfTwo() +{ + UASSERT(is_power_of_two(0) == false); + UASSERT(is_power_of_two(1) == true); + UASSERT(is_power_of_two(2) == true); + UASSERT(is_power_of_two(3) == false); + for (int exponent = 2; exponent <= 31; ++exponent) { + UASSERT(is_power_of_two((1U << exponent) - 1) == false); + UASSERT(is_power_of_two((1U << exponent)) == true); + UASSERT(is_power_of_two((1U << exponent) + 1) == false); + } + UASSERT(is_power_of_two(U32_MAX) == false); +} + +void TestUtilities::testMyround() +{ + UASSERT(myround(4.6f) == 5); + UASSERT(myround(1.2f) == 1); + UASSERT(myround(-3.1f) == -3); + UASSERT(myround(-6.5f) == -7); +} + +void TestUtilities::testStringJoin() +{ + std::vector<std::string> input; + UASSERT(str_join(input, ",") == ""); + + input.emplace_back("one"); + UASSERT(str_join(input, ",") == "one"); + + input.emplace_back("two"); + UASSERT(str_join(input, ",") == "one,two"); + + input.emplace_back("three"); + UASSERT(str_join(input, ",") == "one,two,three"); + + input[1] = ""; + UASSERT(str_join(input, ",") == "one,,three"); + + input[1] = "two"; + UASSERT(str_join(input, " and ") == "one and two and three"); +} + + +static bool within(const f32 value1, const f32 value2, const f32 precision) +{ + return std::fabs(value1 - value2) <= precision; +} + +static bool within(const v3f &v1, const v3f &v2, const f32 precision) +{ + return within(v1.X, v2.X, precision) && within(v1.Y, v2.Y, precision) + && within(v1.Z, v2.Z, precision); +} + +static bool within(const core::matrix4 &m1, const core::matrix4 &m2, + const f32 precision) +{ + const f32 *M1 = m1.pointer(); + const f32 *M2 = m2.pointer(); + for (int i = 0; i < 16; i++) + if (! within(M1[i], M2[i], precision)) + return false; + return true; +} + +static bool roundTripsDeg(const v3f &v, const f32 precision) +{ + core::matrix4 m; + setPitchYawRoll(m, v); + return within(v, getPitchYawRoll(m), precision); +} + +void TestUtilities::testEulerConversion() +{ + // This test may fail on non-IEEE systems. + // Low tolerance is 4 ulp(1.0) for binary floats with 24 bit mantissa. + // (ulp = unit in the last place; ulp(1.0) = 2^-23). + const f32 tolL = 4.76837158203125e-7f; + // High tolerance is 2 ulp(180.0), needed for numbers in degrees. + // ulp(180.0) = 2^-16 + const f32 tolH = 3.0517578125e-5f; + v3f v1, v2; + core::matrix4 m1, m2; + const f32 *M1 = m1.pointer(); + const f32 *M2 = m2.pointer(); + + // Check that the radians version and the degrees version + // produce the same results. Check also that the conversion + // works both ways for these values. + v1 = v3f(M_PI/3.0, M_PI/5.0, M_PI/4.0); + v2 = v3f(60.0f, 36.0f, 45.0f); + setPitchYawRollRad(m1, v1); + setPitchYawRoll(m2, v2); + UASSERT(within(m1, m2, tolL)); + UASSERT(within(getPitchYawRollRad(m1), v1, tolL)); + UASSERT(within(getPitchYawRoll(m2), v2, tolH)); + + // Check the rotation matrix produced. + UASSERT(within(M1[0], 0.932004869f, tolL)); + UASSERT(within(M1[1], 0.353553385f, tolL)); + UASSERT(within(M1[2], 0.0797927827f, tolL)); + UASSERT(within(M1[4], -0.21211791f, tolL)); + UASSERT(within(M1[5], 0.353553355f, tolL)); + UASSERT(within(M1[6], 0.911046684f, tolL)); + UASSERT(within(M1[8], 0.293892622f, tolL)); + UASSERT(within(M1[9], -0.866025448f, tolL)); + UASSERT(within(M1[10], 0.404508471f, tolL)); + + // Check that the matrix is still homogeneous with no translation + UASSERT(M1[3] == 0.0f); + UASSERT(M1[7] == 0.0f); + UASSERT(M1[11] == 0.0f); + UASSERT(M1[12] == 0.0f); + UASSERT(M1[13] == 0.0f); + UASSERT(M1[14] == 0.0f); + UASSERT(M1[15] == 1.0f); + UASSERT(M2[3] == 0.0f); + UASSERT(M2[7] == 0.0f); + UASSERT(M2[11] == 0.0f); + UASSERT(M2[12] == 0.0f); + UASSERT(M2[13] == 0.0f); + UASSERT(M2[14] == 0.0f); + UASSERT(M2[15] == 1.0f); + + // Compare to Irrlicht's results. To be comparable, the + // angles must come in a different order and the matrix + // elements to compare are different too. + m2.setRotationRadians(v3f(v1.Z, v1.X, v1.Y)); + UASSERT(within(M1[0], M2[5], tolL)); + UASSERT(within(M1[1], M2[6], tolL)); + UASSERT(within(M1[2], M2[4], tolL)); + + UASSERT(within(M1[4], M2[9], tolL)); + UASSERT(within(M1[5], M2[10], tolL)); + UASSERT(within(M1[6], M2[8], tolL)); + + UASSERT(within(M1[8], M2[1], tolL)); + UASSERT(within(M1[9], M2[2], tolL)); + UASSERT(within(M1[10], M2[0], tolL)); + + // Check that Eulers that produce near gimbal-lock still round-trip + UASSERT(roundTripsDeg(v3f(89.9999f, 17.f, 0.f), tolH)); + UASSERT(roundTripsDeg(v3f(89.9999f, 0.f, 19.f), tolH)); + UASSERT(roundTripsDeg(v3f(89.9999f, 17.f, 19.f), tolH)); + + // Check that Eulers at an angle > 90 degrees may not round-trip... + v1 = v3f(90.00001f, 1.f, 1.f); + setPitchYawRoll(m1, v1); + v2 = getPitchYawRoll(m1); + //UASSERT(within(v1, v2, tolL)); // this is typically false + // ... however the rotation matrix is the same for both + setPitchYawRoll(m2, v2); + UASSERT(within(m1, m2, tolL)); +} + +void TestUtilities::testBase64() +{ + // Test character set + UASSERT(base64_is_valid("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/") == true); + UASSERT(base64_is_valid("/+9876543210" + "zyxwvutsrqponmlkjihgfedcba" + "ZYXWVUTSRQPONMLKJIHGFEDCBA") == true); + UASSERT(base64_is_valid("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+.") == false); + UASSERT(base64_is_valid("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789 /") == false); + + // Test empty string + UASSERT(base64_is_valid("") == true); + + // Test different lengths, with and without padding, + // with correct and incorrect padding + UASSERT(base64_is_valid("A") == false); + UASSERT(base64_is_valid("AA") == true); + UASSERT(base64_is_valid("AAA") == true); + UASSERT(base64_is_valid("AAAA") == true); + UASSERT(base64_is_valid("AAAAA") == false); + UASSERT(base64_is_valid("AAAAAA") == true); + UASSERT(base64_is_valid("AAAAAAA") == true); + UASSERT(base64_is_valid("AAAAAAAA") == true); + UASSERT(base64_is_valid("A===") == false); + UASSERT(base64_is_valid("AA==") == true); + UASSERT(base64_is_valid("AAA=") == true); + UASSERT(base64_is_valid("AAAA") == true); + UASSERT(base64_is_valid("AAAA====") == false); + UASSERT(base64_is_valid("AAAAA===") == false); + UASSERT(base64_is_valid("AAAAAA==") == true); + UASSERT(base64_is_valid("AAAAAAA=") == true); + UASSERT(base64_is_valid("AAAAAAA==") == false); + UASSERT(base64_is_valid("AAAAAAA===") == false); + UASSERT(base64_is_valid("AAAAAAA====") == false); + UASSERT(base64_is_valid("AAAAAAAA") == true); + UASSERT(base64_is_valid("AAAAAAAA=") == false); + UASSERT(base64_is_valid("AAAAAAAA==") == false); + UASSERT(base64_is_valid("AAAAAAAA===") == false); + UASSERT(base64_is_valid("AAAAAAAA====") == false); + + // Test if canonical encoding + // Last character limitations, length % 4 == 3 + UASSERT(base64_is_valid("AAB") == false); + UASSERT(base64_is_valid("AAE") == true); + UASSERT(base64_is_valid("AAQ") == true); + UASSERT(base64_is_valid("AAB=") == false); + UASSERT(base64_is_valid("AAE=") == true); + UASSERT(base64_is_valid("AAQ=") == true); + UASSERT(base64_is_valid("AAAAAAB=") == false); + UASSERT(base64_is_valid("AAAAAAE=") == true); + UASSERT(base64_is_valid("AAAAAAQ=") == true); + // Last character limitations, length % 4 == 2 + UASSERT(base64_is_valid("AB") == false); + UASSERT(base64_is_valid("AE") == false); + UASSERT(base64_is_valid("AQ") == true); + UASSERT(base64_is_valid("AB==") == false); + UASSERT(base64_is_valid("AE==") == false); + UASSERT(base64_is_valid("AQ==") == true); + UASSERT(base64_is_valid("AAAAAB==") == false); + UASSERT(base64_is_valid("AAAAAE==") == false); + UASSERT(base64_is_valid("AAAAAQ==") == true); + + // Extraneous character present + UASSERT(base64_is_valid(".") == false); + UASSERT(base64_is_valid("A.") == false); + UASSERT(base64_is_valid("AA.") == false); + UASSERT(base64_is_valid("AAA.") == false); + UASSERT(base64_is_valid("AAAA.") == false); + UASSERT(base64_is_valid("AAAAA.") == false); + UASSERT(base64_is_valid("A.A") == false); + UASSERT(base64_is_valid("AA.A") == false); + UASSERT(base64_is_valid("AAA.A") == false); + UASSERT(base64_is_valid("AAAA.A") == false); + UASSERT(base64_is_valid("AAAAA.A") == false); + UASSERT(base64_is_valid("\xE1""AAA") == false); + + // Padding in wrong position + UASSERT(base64_is_valid("A=A") == false); + UASSERT(base64_is_valid("AA=A") == false); + UASSERT(base64_is_valid("AAA=A") == false); + UASSERT(base64_is_valid("AAAA=A") == false); + UASSERT(base64_is_valid("AAAAA=A") == false); +} + + +void TestUtilities::testSanitizeDirName() +{ + UASSERT(sanitizeDirName("a", "~") == "a"); + UASSERT(sanitizeDirName(" ", "~") == "__"); + UASSERT(sanitizeDirName(" a ", "~") == "_a_"); + UASSERT(sanitizeDirName("COM1", "~") == "~COM1"); + UASSERT(sanitizeDirName("COM1", ":") == "_COM1"); + UASSERT(sanitizeDirName("cOm\u00B2", "~") == "~cOm\u00B2"); + UASSERT(sanitizeDirName("cOnIn$", "~") == "~cOnIn$"); + UASSERT(sanitizeDirName(" cOnIn$ ", "~") == "_cOnIn$_"); +} diff --git a/src/unittest/test_voxelalgorithms.cpp b/src/unittest/test_voxelalgorithms.cpp new file mode 100644 index 0000000..0ffd24b --- /dev/null +++ b/src/unittest/test_voxelalgorithms.cpp @@ -0,0 +1,101 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "gamedef.h" +#include "voxelalgorithms.h" +#include "util/numeric.h" + +class TestVoxelAlgorithms : public TestBase { +public: + TestVoxelAlgorithms() { TestManager::registerTestModule(this); } + const char *getName() { return "TestVoxelAlgorithms"; } + + void runTests(IGameDef *gamedef); + + void testVoxelLineIterator(const NodeDefManager *ndef); +}; + +static TestVoxelAlgorithms g_test_instance; + +void TestVoxelAlgorithms::runTests(IGameDef *gamedef) +{ + const NodeDefManager *ndef = gamedef->getNodeDefManager(); + + TEST(testVoxelLineIterator, ndef); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestVoxelAlgorithms::testVoxelLineIterator(const NodeDefManager *ndef) +{ + // Test some lines + // Do not test lines that start or end on the border of + // two voxels as rounding errors can make the test fail! + std::vector<core::line3d<f32> > lines; + for (f32 x = -9.1; x < 9; x += 3.124) { + for (f32 y = -9.2; y < 9; y += 3.123) { + for (f32 z = -9.3; z < 9; z += 3.122) { + lines.emplace_back(-x, -y, -z, x, y, z); + } + } + } + lines.emplace_back(0, 0, 0, 0, 0, 0); + // Test every line + std::vector<core::line3d<f32> >::iterator it = lines.begin(); + for (; it < lines.end(); it++) { + core::line3d<f32> l = *it; + + // Initialize test + voxalgo::VoxelLineIterator iterator(l.start, l.getVector()); + + //Test the first voxel + v3s16 start_voxel = floatToInt(l.start, 1); + UASSERT(iterator.m_current_node_pos == start_voxel); + + // Values for testing + v3s16 end_voxel = floatToInt(l.end, 1); + v3s16 voxel_vector = end_voxel - start_voxel; + int nodecount = abs(voxel_vector.X) + abs(voxel_vector.Y) + + abs(voxel_vector.Z); + int actual_nodecount = 0; + v3s16 old_voxel = iterator.m_current_node_pos; + + while (iterator.hasNext()) { + iterator.next(); + actual_nodecount++; + v3s16 new_voxel = iterator.m_current_node_pos; + // This must be a neighbor of the old voxel + UASSERTEQ(f32, (new_voxel - old_voxel).getLengthSQ(), 1); + // The line must intersect with the voxel + v3f voxel_center = intToFloat(iterator.m_current_node_pos, 1); + aabb3f box(voxel_center - v3f(0.5, 0.5, 0.5), + voxel_center + v3f(0.5, 0.5, 0.5)); + UASSERT(box.intersectsWithLine(l)); + // Update old voxel + old_voxel = new_voxel; + } + + // Test last node + UASSERT(iterator.m_current_node_pos == end_voxel); + // Test node count + UASSERTEQ(int, actual_nodecount, nodecount); + } +} diff --git a/src/unittest/test_voxelarea.cpp b/src/unittest/test_voxelarea.cpp new file mode 100644 index 0000000..a79c977 --- /dev/null +++ b/src/unittest/test_voxelarea.cpp @@ -0,0 +1,388 @@ +/* +Minetest +Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" +#include "voxel.h" + +class TestVoxelArea : public TestBase +{ +public: + TestVoxelArea() { TestManager::registerTestModule(this); } + const char *getName() { return "TestVoxelArea"; } + + void runTests(IGameDef *gamedef); + + void test_addarea(); + void test_pad(); + void test_extent(); + void test_volume(); + void test_contains_voxelarea(); + void test_contains_point(); + void test_contains_i(); + void test_equal(); + void test_plus(); + void test_minor(); + void test_index_xyz_all_pos(); + void test_index_xyz_x_neg(); + void test_index_xyz_y_neg(); + void test_index_xyz_z_neg(); + void test_index_xyz_xy_neg(); + void test_index_xyz_xz_neg(); + void test_index_xyz_yz_neg(); + void test_index_xyz_all_neg(); + void test_index_v3s16_all_pos(); + void test_index_v3s16_x_neg(); + void test_index_v3s16_y_neg(); + void test_index_v3s16_z_neg(); + void test_index_v3s16_xy_neg(); + void test_index_v3s16_xz_neg(); + void test_index_v3s16_yz_neg(); + void test_index_v3s16_all_neg(); + void test_add_x(); + void test_add_y(); + void test_add_z(); + void test_add_p(); +}; + +static TestVoxelArea g_test_instance; + +void TestVoxelArea::runTests(IGameDef *gamedef) +{ + TEST(test_addarea); + TEST(test_pad); + TEST(test_extent); + TEST(test_volume); + TEST(test_contains_voxelarea); + TEST(test_contains_point); + TEST(test_contains_i); + TEST(test_equal); + TEST(test_plus); + TEST(test_minor); + TEST(test_index_xyz_all_pos); + TEST(test_index_xyz_x_neg); + TEST(test_index_xyz_y_neg); + TEST(test_index_xyz_z_neg); + TEST(test_index_xyz_xy_neg); + TEST(test_index_xyz_xz_neg); + TEST(test_index_xyz_yz_neg); + TEST(test_index_xyz_all_neg); + TEST(test_index_v3s16_all_pos); + TEST(test_index_v3s16_x_neg); + TEST(test_index_v3s16_y_neg); + TEST(test_index_v3s16_z_neg); + TEST(test_index_v3s16_xy_neg); + TEST(test_index_v3s16_xz_neg); + TEST(test_index_v3s16_yz_neg); + TEST(test_index_v3s16_all_neg); + TEST(test_add_x); + TEST(test_add_y); + TEST(test_add_z); + TEST(test_add_p); +} + +void TestVoxelArea::test_addarea() +{ + VoxelArea v1(v3s16(-1447, 8854, -875), v3s16(-147, -9547, 669)); + VoxelArea v2(v3s16(-887, 4445, -5478), v3s16(447, -8779, 4778)); + + v1.addArea(v2); + UASSERT(v1.MinEdge == v3s16(-1447, 4445, -5478)); + UASSERT(v1.MaxEdge == v3s16(447, -8779, 4778)); +} + +void TestVoxelArea::test_pad() +{ + VoxelArea v1(v3s16(-1447, 8854, -875), v3s16(-147, -9547, 669)); + v1.pad(v3s16(100, 200, 300)); + + UASSERT(v1.MinEdge == v3s16(-1547, 8654, -1175)); + UASSERT(v1.MaxEdge == v3s16(-47, -9347, 969)); +} + +void TestVoxelArea::test_extent() +{ + VoxelArea v1(v3s16(-1337, -547, -789), v3s16(-147, 447, 669)); + UASSERT(v1.getExtent() == v3s16(1191, 995, 1459)); + + VoxelArea v2(v3s16(32493, -32507, 32752), v3s16(32508, -32492, 32767)); + UASSERT(v2.getExtent() == v3s16(16, 16, 16)); +} + +void TestVoxelArea::test_volume() +{ + VoxelArea v1(v3s16(-1337, -547, -789), v3s16(-147, 447, 669)); + UASSERTEQ(s32, v1.getVolume(), 1728980655); + + VoxelArea v2(v3s16(32493, -32507, 32752), v3s16(32508, -32492, 32767)); + UASSERTEQ(s32, v2.getVolume(), 4096); +} + +void TestVoxelArea::test_contains_voxelarea() +{ + VoxelArea v1(v3s16(-1337, -9547, -789), v3s16(-147, 750, 669)); + UASSERTEQ(bool, v1.contains(VoxelArea(v3s16(-200, 10, 10), v3s16(-150, 10, 10))), + true); + UASSERTEQ(bool, v1.contains(VoxelArea(v3s16(-2550, 10, 10), v3s16(10, 10, 10))), + false); + UASSERTEQ(bool, v1.contains(VoxelArea(v3s16(-10, 10, 10), v3s16(3500, 10, 10))), + false); + UASSERTEQ(bool, + v1.contains(VoxelArea( + v3s16(-800, -400, 669), v3s16(-500, 200, 669))), + true); + UASSERTEQ(bool, + v1.contains(VoxelArea( + v3s16(-800, -400, 670), v3s16(-500, 200, 670))), + false); +} + +void TestVoxelArea::test_contains_point() +{ + VoxelArea v1(v3s16(-1337, -9547, -789), v3s16(-147, 750, 669)); + UASSERTEQ(bool, v1.contains(v3s16(-200, 10, 10)), true); + UASSERTEQ(bool, v1.contains(v3s16(-10000, 10, 10)), false); + UASSERTEQ(bool, v1.contains(v3s16(-100, 10000, 10)), false); + UASSERTEQ(bool, v1.contains(v3s16(-100, 100, 10000)), false); + UASSERTEQ(bool, v1.contains(v3s16(-100, 100, -10000)), false); + UASSERTEQ(bool, v1.contains(v3s16(10000, 100, 10)), false); +} + +void TestVoxelArea::test_contains_i() +{ + VoxelArea v1(v3s16(-1337, -9547, -789), v3s16(-147, 750, 669)); + UASSERTEQ(bool, v1.contains(10), true); + UASSERTEQ(bool, v1.contains(v1.getVolume()), false); + UASSERTEQ(bool, v1.contains(v1.getVolume() - 1), true); + UASSERTEQ(bool, v1.contains(v1.getVolume() + 1), false); + UASSERTEQ(bool, v1.contains(-1), false) + + VoxelArea v2(v3s16(10, 10, 10), v3s16(30, 30, 30)); + UASSERTEQ(bool, v2.contains(10), true); + UASSERTEQ(bool, v2.contains(0), true); + UASSERTEQ(bool, v2.contains(-1), false); +} + +void TestVoxelArea::test_equal() +{ + VoxelArea v1(v3s16(-1337, -9547, -789), v3s16(-147, 750, 669)); + UASSERTEQ(bool, v1 == VoxelArea(v3s16(-1337, -9547, -789), v3s16(-147, 750, 669)), + true); + UASSERTEQ(bool, v1 == VoxelArea(v3s16(0, 0, 0), v3s16(-147, 750, 669)), false); + UASSERTEQ(bool, v1 == VoxelArea(v3s16(0, 0, 0), v3s16(-147, 750, 669)), false); + UASSERTEQ(bool, v1 == VoxelArea(v3s16(0, 0, 0), v3s16(0, 0, 0)), false); +} + +void TestVoxelArea::test_plus() +{ + VoxelArea v1(v3s16(-10, -10, -10), v3s16(100, 100, 100)); + UASSERT(v1 + v3s16(10, 0, 0) == + VoxelArea(v3s16(0, -10, -10), v3s16(110, 100, 100))); + UASSERT(v1 + v3s16(10, -10, 0) == + VoxelArea(v3s16(0, -20, -10), v3s16(110, 90, 100))); + UASSERT(v1 + v3s16(0, 0, 35) == + VoxelArea(v3s16(-10, -10, 25), v3s16(100, 100, 135))); +} + +void TestVoxelArea::test_minor() +{ + VoxelArea v1(v3s16(-10, -10, -10), v3s16(100, 100, 100)); + UASSERT(v1 - v3s16(10, 0, 0) == + VoxelArea(v3s16(-20, -10, -10), v3s16(90, 100, 100))); + UASSERT(v1 - v3s16(10, -10, 0) == + VoxelArea(v3s16(-20, 0, -10), v3s16(90, 110, 100))); + UASSERT(v1 - v3s16(0, 0, 35) == + VoxelArea(v3s16(-10, -10, -45), v3s16(100, 100, 65))); +} + +void TestVoxelArea::test_index_xyz_all_pos() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(156, 25, 236), 155); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(156, 25, 236), 1267138774); +} + +void TestVoxelArea::test_index_xyz_x_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(-147, 25, 366), -148); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(-147, 25, 366), -870244825); +} + +void TestVoxelArea::test_index_xyz_y_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(247, -269, 100), 246); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(247, -269, 100), -989760747); +} + +void TestVoxelArea::test_index_xyz_z_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(244, 336, -887), 243); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(244, 336, -887), -191478876); +} + +void TestVoxelArea::test_index_xyz_xy_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(-365, -47, 6978), -366); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(-365, -47, 6978), 1493679101); +} + +void TestVoxelArea::test_index_xyz_yz_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(66, -58, -789), 65); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(66, -58, -789), 1435362734); +} + +void TestVoxelArea::test_index_xyz_xz_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(-36, 589, -992), -37); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(-36, 589, -992), -1934371362); +} + +void TestVoxelArea::test_index_xyz_all_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(-88, -99, -1474), -89); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(-88, -99, -1474), -1343473846); +} + +void TestVoxelArea::test_index_v3s16_all_pos() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(v3s16(156, 25, 236)), 155); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(v3s16(156, 25, 236)), 1267138774); +} + +void TestVoxelArea::test_index_v3s16_x_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(v3s16(-147, 25, 366)), -148); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(v3s16(-147, 25, 366)), -870244825); +} + +void TestVoxelArea::test_index_v3s16_y_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(v3s16(247, -269, 100)), 246); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(v3s16(247, -269, 100)), -989760747); +} + +void TestVoxelArea::test_index_v3s16_z_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(v3s16(244, 336, -887)), 243); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(v3s16(244, 336, -887)), -191478876); +} + +void TestVoxelArea::test_index_v3s16_xy_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(v3s16(-365, -47, 6978)), -366); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(v3s16(-365, -47, 6978)), 1493679101); +} + +void TestVoxelArea::test_index_v3s16_yz_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(v3s16(66, -58, -789)), 65); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(v3s16(66, -58, -789)), 1435362734); +} + +void TestVoxelArea::test_index_v3s16_xz_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(v3s16(-36, 589, -992)), -37); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(v3s16(-36, 589, -992)), -1934371362); +} + +void TestVoxelArea::test_index_v3s16_all_neg() +{ + VoxelArea v1; + UASSERTEQ(s32, v1.index(v3s16(-88, -99, -1474)), -89); + + VoxelArea v2(v3s16(756, 8854, -875), v3s16(-147, -9547, 669)); + UASSERTEQ(s32, v2.index(v3s16(-88, -99, -1474)), -1343473846); +} + +void TestVoxelArea::test_add_x() +{ + v3s16 extent; + u32 i = 4; + VoxelArea::add_x(extent, i, 8); + UASSERTEQ(u32, i, 12) +} + +void TestVoxelArea::test_add_y() +{ + v3s16 extent(740, 16, 87); + u32 i = 8; + VoxelArea::add_y(extent, i, 88); + UASSERTEQ(u32, i, 65128) +} + +void TestVoxelArea::test_add_z() +{ + v3s16 extent(114, 80, 256); + u32 i = 4; + VoxelArea::add_z(extent, i, 8); + UASSERTEQ(u32, i, 72964) +} + +void TestVoxelArea::test_add_p() +{ + v3s16 extent(33, 14, 742); + v3s16 a(15, 12, 369); + u32 i = 4; + VoxelArea::add_p(extent, i, a); + UASSERTEQ(u32, i, 170893) +} diff --git a/src/unittest/test_voxelmanipulator.cpp b/src/unittest/test_voxelmanipulator.cpp new file mode 100644 index 0000000..acc2707 --- /dev/null +++ b/src/unittest/test_voxelmanipulator.cpp @@ -0,0 +1,108 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include <algorithm> + +#include "gamedef.h" +#include "log.h" +#include "voxel.h" + +class TestVoxelManipulator : public TestBase { +public: + TestVoxelManipulator() { TestManager::registerTestModule(this); } + const char *getName() { return "TestVoxelManipulator"; } + + void runTests(IGameDef *gamedef); + + void testVoxelArea(); + void testVoxelManipulator(const NodeDefManager *nodedef); +}; + +static TestVoxelManipulator g_test_instance; + +void TestVoxelManipulator::runTests(IGameDef *gamedef) +{ + TEST(testVoxelArea); + TEST(testVoxelManipulator, gamedef->getNodeDefManager()); +} + +//////////////////////////////////////////////////////////////////////////////// + +void TestVoxelManipulator::testVoxelArea() +{ + VoxelArea a(v3s16(-1,-1,-1), v3s16(1,1,1)); + UASSERT(a.index(0,0,0) == 1*3*3 + 1*3 + 1); + UASSERT(a.index(-1,-1,-1) == 0); + + VoxelArea c(v3s16(-2,-2,-2), v3s16(2,2,2)); + // An area that is 1 bigger in x+ and z- + VoxelArea d(v3s16(-2,-2,-3), v3s16(3,2,2)); + + std::list<VoxelArea> aa; + d.diff(c, aa); + + // Correct results + std::vector<VoxelArea> results; + results.emplace_back(v3s16(-2,-2,-3), v3s16(3,2,-3)); + results.emplace_back(v3s16(3,-2,-2), v3s16(3,2,2)); + + UASSERT(aa.size() == results.size()); + + infostream<<"Result of diff:"<<std::endl; + for (std::list<VoxelArea>::const_iterator + it = aa.begin(); it != aa.end(); ++it) { + it->print(infostream); + infostream << std::endl; + + std::vector<VoxelArea>::iterator j; + j = std::find(results.begin(), results.end(), *it); + UASSERT(j != results.end()); + results.erase(j); + } +} + + +void TestVoxelManipulator::testVoxelManipulator(const NodeDefManager *nodedef) +{ + VoxelManipulator v; + + v.print(infostream, nodedef); + + infostream << "*** Setting (-1,0,-1)=2 ***" << std::endl; + v.setNodeNoRef(v3s16(-1,0,-1), MapNode(t_CONTENT_GRASS)); + + v.print(infostream, nodedef); + UASSERT(v.getNode(v3s16(-1,0,-1)).getContent() == t_CONTENT_GRASS); + + infostream << "*** Reading from inexistent (0,0,-1) ***" << std::endl; + + EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,0,-1))); + v.print(infostream, nodedef); + + infostream << "*** Adding area ***" << std::endl; + + VoxelArea a(v3s16(-1,-1,-1), v3s16(1,1,1)); + v.addArea(a); + v.print(infostream, nodedef); + + UASSERT(v.getNode(v3s16(-1,0,-1)).getContent() == t_CONTENT_GRASS); + EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,1,1))); +} diff --git a/src/unittest/test_world/do_not_remove.txt b/src/unittest/test_world/do_not_remove.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt new file mode 100644 index 0000000..6bc9791 --- /dev/null +++ b/src/util/CMakeLists.txt @@ -0,0 +1,19 @@ +set(UTIL_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/areastore.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/auth.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/base64.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/directiontables.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/enriched_string.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ieee_float.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/metricsbackend.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/numeric.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/pointedthing.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/quicktune.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/serialize.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/sha1.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/sha256.c + ${CMAKE_CURRENT_SOURCE_DIR}/string.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/srp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/timetaker.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/png.cpp + PARENT_SCOPE) diff --git a/src/util/Optional.h b/src/util/Optional.h new file mode 100644 index 0000000..eda7fff --- /dev/null +++ b/src/util/Optional.h @@ -0,0 +1,105 @@ +/* +Minetest +Copyright (C) 2021 rubenwardy + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <utility> +#include "debug.h" + +struct nullopt_t +{ +}; +constexpr nullopt_t nullopt{}; + +/** + * An implementation of optional for C++11, which aims to be + * compatible with a subset of std::optional features. + * + * Unfortunately, Minetest doesn't use C++17 yet. + * + * @tparam T The type to be stored + */ +template <typename T> +class Optional +{ + bool m_has_value = false; + T m_value; + +public: + Optional() noexcept {} + Optional(nullopt_t) noexcept {} + + Optional(const T &value) noexcept : m_has_value(true), m_value(value) {} + Optional(T &&value) noexcept : m_has_value(true), m_value(std::move(value)) {} + + Optional(const Optional<T> &other) noexcept : + m_has_value(other.m_has_value), m_value(other.m_value) + {} + Optional(Optional<T> &&other) noexcept : + m_has_value(other.m_has_value), m_value(std::move(other.m_value)) + { + other.m_has_value = false; + } + + Optional<T> &operator=(nullopt_t) noexcept { m_has_value = false; return *this; } + + Optional<T> &operator=(const Optional<T> &other) noexcept + { + if (&other == this) + return *this; + m_has_value = other.m_has_value; + m_value = other.m_value; + return *this; + } + + Optional<T> &operator=(Optional<T> &&other) noexcept + { + if (&other == this) + return *this; + m_has_value = other.m_has_value; + m_value = std::move(other.m_value); + other.m_has_value = false; + return *this; + } + + T &value() + { + FATAL_ERROR_IF(!m_has_value, "optional doesn't have value"); + return m_value; + } + + const T &value() const + { + FATAL_ERROR_IF(!m_has_value, "optional doesn't have value"); + return m_value; + } + + const T &value_or(const T &def) const { return m_has_value ? m_value : def; } + + // Unchecked access consistent with std::optional + T* operator->() { return &m_value; } + const T* operator->() const { return &m_value; } + + T& operator*() { return m_value; } + const T& operator*() const { return m_value; } + + bool has_value() const noexcept { return m_has_value; } + + explicit operator bool() const { return m_has_value; } +}; diff --git a/src/util/areastore.cpp b/src/util/areastore.cpp new file mode 100644 index 0000000..bf75147 --- /dev/null +++ b/src/util/areastore.cpp @@ -0,0 +1,329 @@ +/* +Minetest +Copyright (C) 2015 est31 <mtest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "util/areastore.h" +#include "util/serialize.h" +#include "util/container.h" + +#if USE_SPATIAL + #include <spatialindex/SpatialIndex.h> + #include <spatialindex/RTree.h> + #include <spatialindex/Point.h> +#endif + +#define AST_SMALLER_EQ_AS(p, q) (((p).X <= (q).X) && ((p).Y <= (q).Y) && ((p).Z <= (q).Z)) + +#define AST_OVERLAPS_IN_DIMENSION(amine, amaxe, b, d) \ + (!(((amine).d > (b)->maxedge.d) || ((amaxe).d < (b)->minedge.d))) + +#define AST_CONTAINS_PT(a, p) (AST_SMALLER_EQ_AS((a)->minedge, (p)) && \ + AST_SMALLER_EQ_AS((p), (a)->maxedge)) + +#define AST_CONTAINS_AREA(amine, amaxe, b) \ + (AST_SMALLER_EQ_AS((amine), (b)->minedge) \ + && AST_SMALLER_EQ_AS((b)->maxedge, (amaxe))) + +#define AST_AREAS_OVERLAP(amine, amaxe, b) \ + (AST_OVERLAPS_IN_DIMENSION((amine), (amaxe), (b), X) && \ + AST_OVERLAPS_IN_DIMENSION((amine), (amaxe), (b), Y) && \ + AST_OVERLAPS_IN_DIMENSION((amine), (amaxe), (b), Z)) + + +AreaStore *AreaStore::getOptimalImplementation() +{ +#if USE_SPATIAL + return new SpatialAreaStore(); +#else + return new VectorAreaStore(); +#endif +} + +const Area *AreaStore::getArea(u32 id) const +{ + AreaMap::const_iterator it = areas_map.find(id); + if (it == areas_map.end()) + return nullptr; + return &it->second; +} + +void AreaStore::serialize(std::ostream &os) const +{ + // WARNING: + // Before 5.1.0-dev: version != 0 throws SerializationError + // After 5.1.0-dev: version >= 5 throws SerializationError + // Forwards-compatibility is assumed before version 5. + + writeU8(os, 0); // Serialisation version + + // TODO: Compression? + writeU16(os, areas_map.size()); + for (const auto &it : areas_map) { + const Area &a = it.second; + writeV3S16(os, a.minedge); + writeV3S16(os, a.maxedge); + writeU16(os, a.data.size()); + os.write(a.data.data(), a.data.size()); + } + + // Serialize IDs + for (const auto &it : areas_map) + writeU32(os, it.second.id); +} + +void AreaStore::deserialize(std::istream &is) +{ + u8 ver = readU8(is); + // Assume forwards-compatibility before version 5 + if (ver >= 5) + throw SerializationError("Unknown AreaStore " + "serialization version!"); + + u16 num_areas = readU16(is); + std::vector<Area> areas; + areas.reserve(num_areas); + for (u32 i = 0; i < num_areas; ++i) { + Area a(U32_MAX); + a.minedge = readV3S16(is); + a.maxedge = readV3S16(is); + u16 data_len = readU16(is); + a.data = std::string(data_len, '\0'); + is.read(&a.data[0], data_len); + areas.emplace_back(std::move(a)); + } + + bool read_ids = is.good(); // EOF for old formats + + for (auto &area : areas) { + if (read_ids) + area.id = readU32(is); + insertArea(&area); + } +} + +void AreaStore::invalidateCache() +{ + if (m_cache_enabled) { + m_res_cache.invalidate(); + } +} + +u32 AreaStore::getNextId() const +{ + u32 free_id = 0; + for (const auto &area : areas_map) { + if (area.first > free_id) + return free_id; // Found gap + + free_id = area.first + 1; + } + // End of map + return free_id; +} + +void AreaStore::setCacheParams(bool enabled, u8 block_radius, size_t limit) +{ + m_cache_enabled = enabled; + m_cacheblock_radius = MYMAX(block_radius, 16); + m_res_cache.setLimit(MYMAX(limit, 20)); + invalidateCache(); +} + +void AreaStore::cacheMiss(void *data, const v3s16 &mpos, std::vector<Area *> *dest) +{ + AreaStore *as = (AreaStore *)data; + u8 r = as->m_cacheblock_radius; + + // get the points at the edges of the mapblock + v3s16 minedge(mpos.X * r, mpos.Y * r, mpos.Z * r); + v3s16 maxedge( + minedge.X + r - 1, + minedge.Y + r - 1, + minedge.Z + r - 1); + + as->getAreasInArea(dest, minedge, maxedge, true); + + /* infostream << "Cache miss with " << dest->size() << " areas, between (" + << minedge.X << ", " << minedge.Y << ", " << minedge.Z + << ") and (" + << maxedge.X << ", " << maxedge.Y << ", " << maxedge.Z + << ")" << std::endl; // */ +} + +void AreaStore::getAreasForPos(std::vector<Area *> *result, v3s16 pos) +{ + if (m_cache_enabled) { + v3s16 mblock = getContainerPos(pos, m_cacheblock_radius); + const std::vector<Area *> *pre_list = m_res_cache.lookupCache(mblock); + + size_t s_p_l = pre_list->size(); + for (size_t i = 0; i < s_p_l; i++) { + Area *b = (*pre_list)[i]; + if (AST_CONTAINS_PT(b, pos)) { + result->push_back(b); + } + } + } else { + return getAreasForPosImpl(result, pos); + } +} + + +//// +// VectorAreaStore +//// + + +bool VectorAreaStore::insertArea(Area *a) +{ + if (a->id == U32_MAX) + a->id = getNextId(); + std::pair<AreaMap::iterator, bool> res = + areas_map.insert(std::make_pair(a->id, *a)); + if (!res.second) + // ID is not unique + return false; + m_areas.push_back(&res.first->second); + invalidateCache(); + return true; +} + +bool VectorAreaStore::removeArea(u32 id) +{ + AreaMap::iterator it = areas_map.find(id); + if (it == areas_map.end()) + return false; + Area *a = &it->second; + for (std::vector<Area *>::iterator v_it = m_areas.begin(); + v_it != m_areas.end(); ++v_it) { + if (*v_it == a) { + m_areas.erase(v_it); + break; + } + } + areas_map.erase(it); + invalidateCache(); + return true; +} + +void VectorAreaStore::getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos) +{ + for (Area *area : m_areas) { + if (AST_CONTAINS_PT(area, pos)) { + result->push_back(area); + } + } +} + +void VectorAreaStore::getAreasInArea(std::vector<Area *> *result, + v3s16 minedge, v3s16 maxedge, bool accept_overlap) +{ + for (Area *area : m_areas) { + if (accept_overlap ? AST_AREAS_OVERLAP(minedge, maxedge, area) : + AST_CONTAINS_AREA(minedge, maxedge, area)) { + result->push_back(area); + } + } +} + +#if USE_SPATIAL + +static inline SpatialIndex::Region get_spatial_region(const v3s16 minedge, + const v3s16 maxedge) +{ + const double p_low[] = {(double)minedge.X, + (double)minedge.Y, (double)minedge.Z}; + const double p_high[] = {(double)maxedge.X, (double)maxedge.Y, + (double)maxedge.Z}; + return SpatialIndex::Region(p_low, p_high, 3); +} + +static inline SpatialIndex::Point get_spatial_point(const v3s16 pos) +{ + const double p[] = {(double)pos.X, (double)pos.Y, (double)pos.Z}; + return SpatialIndex::Point(p, 3); +} + + +bool SpatialAreaStore::insertArea(Area *a) +{ + if (a->id == U32_MAX) + a->id = getNextId(); + if (!areas_map.insert(std::make_pair(a->id, *a)).second) + // ID is not unique + return false; + m_tree->insertData(0, nullptr, get_spatial_region(a->minedge, a->maxedge), a->id); + invalidateCache(); + return true; +} + +bool SpatialAreaStore::removeArea(u32 id) +{ + std::map<u32, Area>::iterator itr = areas_map.find(id); + if (itr != areas_map.end()) { + Area *a = &itr->second; + bool result = m_tree->deleteData(get_spatial_region(a->minedge, + a->maxedge), id); + areas_map.erase(itr); + invalidateCache(); + return result; + } else { + return false; + } +} + +void SpatialAreaStore::getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos) +{ + VectorResultVisitor visitor(result, this); + m_tree->pointLocationQuery(get_spatial_point(pos), visitor); +} + +void SpatialAreaStore::getAreasInArea(std::vector<Area *> *result, + v3s16 minedge, v3s16 maxedge, bool accept_overlap) +{ + VectorResultVisitor visitor(result, this); + if (accept_overlap) { + m_tree->intersectsWithQuery(get_spatial_region(minedge, maxedge), + visitor); + } else { + m_tree->containsWhatQuery(get_spatial_region(minedge, maxedge), visitor); + } +} + +SpatialAreaStore::~SpatialAreaStore() +{ + delete m_tree; + delete m_storagemanager; +} + +SpatialAreaStore::SpatialAreaStore() +{ + m_storagemanager = + SpatialIndex::StorageManager::createNewMemoryStorageManager(); + SpatialIndex::id_type id; + m_tree = SpatialIndex::RTree::createNewRTree( + *m_storagemanager, + .7, // Fill factor + 100, // Index capacity + 100, // Leaf capacity + 3, // dimension :) + SpatialIndex::RTree::RV_RSTAR, + id); +} + +#endif diff --git a/src/util/areastore.h b/src/util/areastore.h new file mode 100644 index 0000000..150a043 --- /dev/null +++ b/src/util/areastore.h @@ -0,0 +1,197 @@ +/* +Minetest +Copyright (C) 2015 est31 <mtest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irr_v3d.h" +#include "noise.h" // for PcgRandom +#include <map> +#include <list> +#include <vector> +#include <istream> +#include "util/container.h" +#include "util/numeric.h" +#ifndef ANDROID + #include "cmake_config.h" +#endif +#if USE_SPATIAL + #include <spatialindex/SpatialIndex.h> + #include "util/serialize.h" +#endif + + +struct Area { + Area(u32 area_id) : id(area_id) {} + + Area(const v3s16 &mine, const v3s16 &maxe, u32 area_id = U32_MAX) : + id(area_id), minedge(mine), maxedge(maxe) + { + sortBoxVerticies(minedge, maxedge); + } + + u32 id; + v3s16 minedge, maxedge; + std::string data; +}; + + +class AreaStore { +public: + AreaStore() : + m_res_cache(1000, &cacheMiss, this) + {} + + virtual ~AreaStore() = default; + + static AreaStore *getOptimalImplementation(); + + virtual void reserve(size_t count) {}; + size_t size() const { return areas_map.size(); } + + /// Add an area to the store. + /// Updates the area's ID if it hasn't already been set. + /// @return Whether the area insertion was successful. + virtual bool insertArea(Area *a) = 0; + + /// Removes an area from the store by ID. + /// @return Whether the area was in the store and removed. + virtual bool removeArea(u32 id) = 0; + + /// Finds areas that the passed position is contained in. + /// Stores output in passed vector. + void getAreasForPos(std::vector<Area *> *result, v3s16 pos); + + /// Finds areas that are completely contained inside the area defined + /// by the passed edges. If @p accept_overlap is true this finds any + /// areas that intersect with the passed area at any point. + virtual void getAreasInArea(std::vector<Area *> *result, + v3s16 minedge, v3s16 maxedge, bool accept_overlap) = 0; + + /// Sets cache parameters. + void setCacheParams(bool enabled, u8 block_radius, size_t limit); + + /// Returns a pointer to the area coresponding to the passed ID, + /// or NULL if it doesn't exist. + const Area *getArea(u32 id) const; + + /// Serializes the store's areas to a binary ostream. + void serialize(std::ostream &is) const; + + /// Deserializes the Areas from a binary istream. + /// This does not currently clear the AreaStore before adding the + /// areas, making it possible to deserialize multiple serialized + /// AreaStores. + void deserialize(std::istream &is); + +protected: + /// Invalidates the getAreasForPos cache. + /// Call after adding or removing an area. + void invalidateCache(); + + /// Implementation of getAreasForPos. + /// getAreasForPos calls this if the cache is disabled. + virtual void getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos) = 0; + + /// Returns the next area ID and increments it. + u32 getNextId() const; + + // Note: This can't be an unordered_map, since all + // references would be invalidated on rehash. + typedef std::map<u32, Area> AreaMap; + AreaMap areas_map; + +private: + /// Called by the cache when a value isn't found in the cache. + static void cacheMiss(void *data, const v3s16 &mpos, std::vector<Area *> *dest); + + bool m_cache_enabled = true; + /// Range, in nodes, of the getAreasForPos cache. + /// If you modify this, call invalidateCache() + u8 m_cacheblock_radius = 64; + LRUCache<v3s16, std::vector<Area *> > m_res_cache; +}; + + +class VectorAreaStore : public AreaStore { +public: + virtual void reserve(size_t count) { m_areas.reserve(count); } + virtual bool insertArea(Area *a); + virtual bool removeArea(u32 id); + virtual void getAreasInArea(std::vector<Area *> *result, + v3s16 minedge, v3s16 maxedge, bool accept_overlap); + +protected: + virtual void getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos); + +private: + std::vector<Area *> m_areas; +}; + + +#if USE_SPATIAL + +class SpatialAreaStore : public AreaStore { +public: + SpatialAreaStore(); + virtual ~SpatialAreaStore(); + + virtual bool insertArea(Area *a); + virtual bool removeArea(u32 id); + virtual void getAreasInArea(std::vector<Area *> *result, + v3s16 minedge, v3s16 maxedge, bool accept_overlap); + +protected: + virtual void getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos); + +private: + SpatialIndex::ISpatialIndex *m_tree = nullptr; + SpatialIndex::IStorageManager *m_storagemanager = nullptr; + + class VectorResultVisitor : public SpatialIndex::IVisitor { + public: + VectorResultVisitor(std::vector<Area *> *result, SpatialAreaStore *store) : + m_store(store), + m_result(result) + {} + ~VectorResultVisitor() {} + + virtual void visitNode(const SpatialIndex::INode &in) {} + + virtual void visitData(const SpatialIndex::IData &in) + { + u32 id = in.getIdentifier(); + + std::map<u32, Area>::iterator itr = m_store->areas_map.find(id); + assert(itr != m_store->areas_map.end()); + m_result->push_back(&itr->second); + } + + virtual void visitData(std::vector<const SpatialIndex::IData *> &v) + { + for (size_t i = 0; i < v.size(); i++) + visitData(*(v[i])); + } + + private: + SpatialAreaStore *m_store = nullptr; + std::vector<Area *> *m_result = nullptr; + }; +}; + +#endif // USE_SPATIAL diff --git a/src/util/auth.cpp b/src/util/auth.cpp new file mode 100644 index 0000000..3dd5a9a --- /dev/null +++ b/src/util/auth.cpp @@ -0,0 +1,137 @@ +/* +Minetest +Copyright (C) 2015, 2016 est31 <MTest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include <algorithm> +#include <string> +#include "auth.h" +#include "base64.h" +#include "sha1.h" +#include "srp.h" +#include "util/string.h" +#include "debug.h" + +// Get an sha-1 hash of the player's name combined with +// the password entered. That's what the server uses as +// their password. (Exception : if the password field is +// blank, we send a blank password - this is for backwards +// compatibility with password-less players). +std::string translate_password(const std::string &name, + const std::string &password) +{ + if (password.length() == 0) + return ""; + + std::string slt = name + password; + SHA1 sha1; + sha1.addBytes(slt.c_str(), slt.length()); + unsigned char *digest = sha1.getDigest(); + std::string pwd = base64_encode(digest, 20); + free(digest); + return pwd; +} + +// Call lower level SRP code to generate a verifier with the +// given pointers. Contains the preparations, call parameters +// and error checking common to all srp verifier generation code. +// See docs of srp_create_salted_verification_key for more info. +static inline void gen_srp_v(const std::string &name, + const std::string &password, char **salt, size_t *salt_len, + char **bytes_v, size_t *len_v) +{ + std::string n_name = lowercase(name); + SRP_Result res = srp_create_salted_verification_key(SRP_SHA256, SRP_NG_2048, + n_name.c_str(), (const unsigned char *)password.c_str(), + password.size(), (unsigned char **)salt, salt_len, + (unsigned char **)bytes_v, len_v, NULL, NULL); + FATAL_ERROR_IF(res != SRP_OK, "Couldn't create salted SRP verifier"); +} + +/// Creates a verification key with given salt and password. +std::string generate_srp_verifier(const std::string &name, + const std::string &password, const std::string &salt) +{ + size_t salt_len = salt.size(); + // The API promises us that the salt doesn't + // get modified if &salt_ptr isn't NULL. + char *salt_ptr = (char *)salt.c_str(); + + char *bytes_v = nullptr; + size_t verifier_len = 0; + gen_srp_v(name, password, &salt_ptr, &salt_len, &bytes_v, &verifier_len); + std::string verifier = std::string(bytes_v, verifier_len); + free(bytes_v); + return verifier; +} + +/// Creates a verification key and salt with given password. +void generate_srp_verifier_and_salt(const std::string &name, + const std::string &password, std::string *verifier, + std::string *salt) +{ + char *bytes_v = nullptr; + size_t verifier_len; + char *salt_ptr = nullptr; + size_t salt_len; + gen_srp_v(name, password, &salt_ptr, &salt_len, &bytes_v, &verifier_len); + *verifier = std::string(bytes_v, verifier_len); + *salt = std::string(salt_ptr, salt_len); + free(bytes_v); + free(salt_ptr); +} + +/// Gets an SRP verifier, generating a salt, +/// and encodes it as DB-ready string. +std::string get_encoded_srp_verifier(const std::string &name, + const std::string &password) +{ + std::string verifier; + std::string salt; + generate_srp_verifier_and_salt(name, password, &verifier, &salt); + return encode_srp_verifier(verifier, salt); +} + +/// Converts the passed SRP verifier into a DB-ready format. +std::string encode_srp_verifier(const std::string &verifier, + const std::string &salt) +{ + std::ostringstream ret_str; + ret_str << "#1#" + << base64_encode((unsigned char *)salt.c_str(), salt.size()) << "#" + << base64_encode((unsigned char *)verifier.c_str(), verifier.size()); + return ret_str.str(); +} + +/// Reads the DB-formatted SRP verifier and gets the verifier +/// and salt components. +bool decode_srp_verifier_and_salt(const std::string &encoded, + std::string *verifier, std::string *salt) +{ + std::vector<std::string> components = str_split(encoded, '#'); + + if ((components.size() != 4) + || (components[1] != "1") // 1 means srp + || !base64_is_valid(components[2]) + || !base64_is_valid(components[3])) + return false; + + *salt = base64_decode(components[2]); + *verifier = base64_decode(components[3]); + return true; + +} diff --git a/src/util/auth.h b/src/util/auth.h new file mode 100644 index 0000000..ba827f3 --- /dev/null +++ b/src/util/auth.h @@ -0,0 +1,47 @@ +/* +Minetest +Copyright (C) 2015, 2016 est31 <MTest31@outlook.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +/// Gets the base64 encoded legacy password db entry. +std::string translate_password(const std::string &name, + const std::string &password); + +/// Creates a verification key with given salt and password. +std::string generate_srp_verifier(const std::string &name, + const std::string &password, const std::string &salt); + +/// Creates a verification key and salt with given password. +void generate_srp_verifier_and_salt(const std::string &name, + const std::string &password, std::string *verifier, + std::string *salt); + +/// Gets an SRP verifier, generating a salt, +/// and encodes it as DB-ready string. +std::string get_encoded_srp_verifier(const std::string &name, + const std::string &password); + +/// Converts the passed SRP verifier into a DB-ready format. +std::string encode_srp_verifier(const std::string &verifier, + const std::string &salt); + +/// Reads the DB-formatted SRP verifier and gets the verifier +/// and salt components. +bool decode_srp_verifier_and_salt(const std::string &encoded, + std::string *verifier, std::string *salt); diff --git a/src/util/base64.cpp b/src/util/base64.cpp new file mode 100644 index 0000000..0c24552 --- /dev/null +++ b/src/util/base64.cpp @@ -0,0 +1,154 @@ +/* +base64.cpp and base64.h + +Copyright (C) 2004-2008 René Nyffenegger + +This source code is provided 'as-is', without any express or implied +warranty. In no event will the author 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 source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + 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 source code. + +3. This notice may not be removed or altered from any source distribution. + +René Nyffenegger rene.nyffenegger@adp-gmbh.ch + +*/ + +#include "base64.h" +#include <iostream> + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +static const std::string base64_chars_padding_1 = "AEIMQUYcgkosw048"; +static const std::string base64_chars_padding_2 = "AQgw"; + +static inline bool is_base64(unsigned char c) +{ + return (c >= '0' && c <= '9') + || (c >= 'A' && c <= 'Z') + || (c >= 'a' && c <= 'z') + || c == '+' || c == '/'; +} + +bool base64_is_valid(std::string const& s) +{ + size_t i = 0; + for (; i < s.size(); ++i) + if (!is_base64(s[i])) + break; + unsigned char padding = 3 - ((i + 3) % 4); + if ((padding == 1 && base64_chars_padding_1.find(s[i - 1]) == std::string::npos) + || (padding == 2 && base64_chars_padding_2.find(s[i - 1]) == std::string::npos) + || padding == 3) + return false; + int actual_padding = s.size() - i; + // omission of padding characters is allowed + if (actual_padding == 0) + return true; + + // remaining characters (max. 2) may only be padding + for (; i < s.size(); ++i) + if (s[i] != '=') + return false; + // number of padding characters needs to match + return padding == actual_padding; +} + +std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (in_len--) { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; (i <4) ; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + // Don't pad it with = + /*while((i++ < 3)) + ret += '=';*/ + + } + + return ret; + +} + +std::string base64_decode(std::string const& encoded_string) { + int in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::string ret; + + while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; in_++; + if (i ==4) { + for (i = 0; i <4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret += char_array_3[i]; + i = 0; + } + } + + if (i) { + for (j = i; j <4; j++) + char_array_4[j] = 0; + + for (j = 0; j <4; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; + } + + return ret; +} diff --git a/src/util/base64.h b/src/util/base64.h new file mode 100644 index 0000000..7f2bf13 --- /dev/null +++ b/src/util/base64.h @@ -0,0 +1,26 @@ +/* +Minetest +Copyright (C) 2013-2017 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> + +bool base64_is_valid(std::string const& s); +std::string base64_encode(unsigned char const* , unsigned int len); +std::string base64_decode(std::string const& s); diff --git a/src/util/basic_macros.h b/src/util/basic_macros.h new file mode 100644 index 0000000..3910c61 --- /dev/null +++ b/src/util/basic_macros.h @@ -0,0 +1,64 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#define ARRLEN(x) (sizeof(x) / sizeof((x)[0])) + +#define MYMIN(a, b) ((a) < (b) ? (a) : (b)) + +#define MYMAX(a, b) ((a) > (b) ? (a) : (b)) + +// Requires <algorithm> +#define CONTAINS(c, v) (std::find((c).begin(), (c).end(), (v)) != (c).end()) + +// To disable copy constructors and assignment operations for some class +// 'Foobar', add the macro DISABLE_CLASS_COPY(Foobar) in the class definition. +// Note this also disables copying for any classes derived from 'Foobar' as well +// as classes having a 'Foobar' member. +#define DISABLE_CLASS_COPY(C) \ + C(const C &) = delete; \ + C &operator=(const C &) = delete; + +// If you have used DISABLE_CLASS_COPY with a class but still want to permit moving +// use this macro to add the default move constructors back. +#define ALLOW_CLASS_MOVE(C) \ + C(C &&other) = default; \ + C &operator=(C &&) = default; + +#ifndef _MSC_VER + #define UNUSED_ATTRIBUTE __attribute__ ((unused)) +#else + #define UNUSED_ATTRIBUTE +#endif + +// Fail compilation if condition expr is not met. +// Note that 'msg' must follow the format of a valid identifier, e.g. +// STATIC_ASSERT(sizeof(foobar_t) == 40), foobar_t_is_wrong_size); +#define STATIC_ASSERT(expr, msg) \ + UNUSED_ATTRIBUTE typedef char msg[!!(expr) * 2 - 1] + +// Macros to facilitate writing position vectors to a stream +// Usage: +// v3s16 pos(1,2,3); +// mystream << "message " << PP(pos) << std::endl; + +#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" + +#define PP2(x) "("<<(x).X<<","<<(x).Y<<")" diff --git a/src/util/container.h b/src/util/container.h new file mode 100644 index 0000000..0010665 --- /dev/null +++ b/src/util/container.h @@ -0,0 +1,307 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "exceptions.h" +#include "threading/mutex_auto_lock.h" +#include "threading/semaphore.h" +#include <list> +#include <vector> +#include <map> +#include <set> +#include <queue> + +/* +Queue with unique values with fast checking of value existence +*/ + +template<typename Value> +class UniqueQueue +{ +public: + + /* + Does nothing if value is already queued. + Return value: + true: value added + false: value already exists + */ + bool push_back(const Value& value) + { + if (m_set.insert(value).second) + { + m_queue.push(value); + return true; + } + return false; + } + + void pop_front() + { + m_set.erase(m_queue.front()); + m_queue.pop(); + } + + const Value& front() const + { + return m_queue.front(); + } + + u32 size() const + { + return m_queue.size(); + } + +private: + std::set<Value> m_set; + std::queue<Value> m_queue; +}; + +template<typename Key, typename Value> +class MutexedMap +{ +public: + MutexedMap() = default; + + void set(const Key &name, const Value &value) + { + MutexAutoLock lock(m_mutex); + m_values[name] = value; + } + + bool get(const Key &name, Value *result) const + { + MutexAutoLock lock(m_mutex); + auto n = m_values.find(name); + if (n == m_values.end()) + return false; + if (result) + *result = n->second; + return true; + } + + std::vector<Value> getValues() const + { + MutexAutoLock lock(m_mutex); + std::vector<Value> result; + result.reserve(m_values.size()); + for (auto it = m_values.begin(); it != m_values.end(); ++it) + result.push_back(it->second); + return result; + } + + void clear() { m_values.clear(); } + +private: + std::map<Key, Value> m_values; + mutable std::mutex m_mutex; +}; + + +// Thread-safe Double-ended queue + +template<typename T> +class MutexedQueue +{ +public: + template<typename Key, typename U, typename Caller, typename CallerData> + friend class RequestQueue; + + MutexedQueue() = default; + + bool empty() const + { + MutexAutoLock lock(m_mutex); + return m_queue.empty(); + } + + void push_back(const T &t) + { + MutexAutoLock lock(m_mutex); + m_queue.push_back(t); + m_signal.post(); + } + + void push_back(T &&t) + { + MutexAutoLock lock(m_mutex); + m_queue.push_back(std::move(t)); + m_signal.post(); + } + + /* this version of pop_front returns a empty element of T on timeout. + * Make sure default constructor of T creates a recognizable "empty" element + */ + T pop_frontNoEx(u32 wait_time_max_ms) + { + if (m_signal.wait(wait_time_max_ms)) { + MutexAutoLock lock(m_mutex); + + T t = std::move(m_queue.front()); + m_queue.pop_front(); + return t; + } + + return T(); + } + + T pop_front(u32 wait_time_max_ms) + { + if (m_signal.wait(wait_time_max_ms)) { + MutexAutoLock lock(m_mutex); + + T t = std::move(m_queue.front()); + m_queue.pop_front(); + return t; + } + + throw ItemNotFoundException("MutexedQueue: queue is empty"); + } + + T pop_frontNoEx() + { + m_signal.wait(); + + MutexAutoLock lock(m_mutex); + + T t = std::move(m_queue.front()); + m_queue.pop_front(); + return t; + } + + T pop_back(u32 wait_time_max_ms=0) + { + if (m_signal.wait(wait_time_max_ms)) { + MutexAutoLock lock(m_mutex); + + T t = std::move(m_queue.back()); + m_queue.pop_back(); + return t; + } + + throw ItemNotFoundException("MutexedQueue: queue is empty"); + } + + /* this version of pop_back returns a empty element of T on timeout. + * Make sure default constructor of T creates a recognizable "empty" element + */ + T pop_backNoEx(u32 wait_time_max_ms) + { + if (m_signal.wait(wait_time_max_ms)) { + MutexAutoLock lock(m_mutex); + + T t = std::move(m_queue.back()); + m_queue.pop_back(); + return t; + } + + return T(); + } + + T pop_backNoEx() + { + m_signal.wait(); + + MutexAutoLock lock(m_mutex); + + T t = std::move(m_queue.back()); + m_queue.pop_back(); + return t; + } + +protected: + std::mutex &getMutex() { return m_mutex; } + + std::deque<T> &getQueue() { return m_queue; } + + std::deque<T> m_queue; + mutable std::mutex m_mutex; + Semaphore m_signal; +}; + +template<typename K, typename V> +class LRUCache +{ +public: + LRUCache(size_t limit, void (*cache_miss)(void *data, const K &key, V *dest), + void *data) + { + m_limit = limit; + m_cache_miss = cache_miss; + m_cache_miss_data = data; + } + + void setLimit(size_t limit) + { + m_limit = limit; + invalidate(); + } + + void invalidate() + { + m_map.clear(); + m_queue.clear(); + } + + const V *lookupCache(K key) + { + typename cache_type::iterator it = m_map.find(key); + V *ret; + if (it != m_map.end()) { + // found! + + cache_entry_t &entry = it->second; + + ret = &entry.second; + + // update the usage information + m_queue.erase(entry.first); + m_queue.push_front(key); + entry.first = m_queue.begin(); + } else { + // cache miss -- enter into cache + cache_entry_t &entry = + m_map[key]; + ret = &entry.second; + m_cache_miss(m_cache_miss_data, key, &entry.second); + + // delete old entries + if (m_queue.size() == m_limit) { + const K &id = m_queue.back(); + m_map.erase(id); + m_queue.pop_back(); + } + + m_queue.push_front(key); + entry.first = m_queue.begin(); + } + return ret; + } +private: + void (*m_cache_miss)(void *data, const K &key, V *dest); + void *m_cache_miss_data; + size_t m_limit; + typedef typename std::template pair<typename std::template list<K>::iterator, V> cache_entry_t; + typedef std::template map<K, cache_entry_t> cache_type; + cache_type m_map; + // we can't use std::deque here, because its iterators get invalidated + std::list<K> m_queue; +}; diff --git a/src/util/directiontables.cpp b/src/util/directiontables.cpp new file mode 100644 index 0000000..296585f --- /dev/null +++ b/src/util/directiontables.cpp @@ -0,0 +1,120 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "directiontables.h" + +const v3s16 g_6dirs[6] = +{ + // +right, +top, +back + v3s16( 0, 0, 1), // back + v3s16( 0, 1, 0), // top + v3s16( 1, 0, 0), // right + v3s16( 0, 0,-1), // front + v3s16( 0,-1, 0), // bottom + v3s16(-1, 0, 0) // left +}; + +const v3s16 g_7dirs[7] = +{ + v3s16(0,0,1), // back + v3s16(0,1,0), // top + v3s16(1,0,0), // right + v3s16(0,0,-1), // front + v3s16(0,-1,0), // bottom + v3s16(-1,0,0), // left + v3s16(0,0,0), // self +}; + +const v3s16 g_26dirs[26] = +{ + // +right, +top, +back + v3s16( 0, 0, 1), // back + v3s16( 0, 1, 0), // top + v3s16( 1, 0, 0), // right + v3s16( 0, 0,-1), // front + v3s16( 0,-1, 0), // bottom + v3s16(-1, 0, 0), // left + // 6 + v3s16(-1, 1, 0), // top left + v3s16( 1, 1, 0), // top right + v3s16( 0, 1, 1), // top back + v3s16( 0, 1,-1), // top front + v3s16(-1, 0, 1), // back left + v3s16( 1, 0, 1), // back right + v3s16(-1, 0,-1), // front left + v3s16( 1, 0,-1), // front right + v3s16(-1,-1, 0), // bottom left + v3s16( 1,-1, 0), // bottom right + v3s16( 0,-1, 1), // bottom back + v3s16( 0,-1,-1), // bottom front + // 18 + v3s16(-1, 1, 1), // top back-left + v3s16( 1, 1, 1), // top back-right + v3s16(-1, 1,-1), // top front-left + v3s16( 1, 1,-1), // top front-right + v3s16(-1,-1, 1), // bottom back-left + v3s16( 1,-1, 1), // bottom back-right + v3s16(-1,-1,-1), // bottom front-left + v3s16( 1,-1,-1), // bottom front-right + // 26 +}; + +const v3s16 g_27dirs[27] = +{ + // +right, +top, +back + v3s16( 0, 0, 1), // back + v3s16( 0, 1, 0), // top + v3s16( 1, 0, 0), // right + v3s16( 0, 0,-1), // front + v3s16( 0,-1, 0), // bottom + v3s16(-1, 0, 0), // left + // 6 + v3s16(-1, 1, 0), // top left + v3s16( 1, 1, 0), // top right + v3s16( 0, 1, 1), // top back + v3s16( 0, 1,-1), // top front + v3s16(-1, 0, 1), // back left + v3s16( 1, 0, 1), // back right + v3s16(-1, 0,-1), // front left + v3s16( 1, 0,-1), // front right + v3s16(-1,-1, 0), // bottom left + v3s16( 1,-1, 0), // bottom right + v3s16( 0,-1, 1), // bottom back + v3s16( 0,-1,-1), // bottom front + // 18 + v3s16(-1, 1, 1), // top back-left + v3s16( 1, 1, 1), // top back-right + v3s16(-1, 1,-1), // top front-left + v3s16( 1, 1,-1), // top front-right + v3s16(-1,-1, 1), // bottom back-left + v3s16( 1,-1, 1), // bottom back-right + v3s16(-1,-1,-1), // bottom front-left + v3s16( 1,-1,-1), // bottom front-right + // 26 + v3s16(0,0,0), +}; + +const u8 wallmounted_to_facedir[6] = { + 20, + 0, + 16 + 1, + 12 + 3, + 8, + 4 + 2 +}; diff --git a/src/util/directiontables.h b/src/util/directiontables.h new file mode 100644 index 0000000..ef00e3b --- /dev/null +++ b/src/util/directiontables.h @@ -0,0 +1,89 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "irr_v3d.h" + +extern const v3s16 g_6dirs[6]; + +extern const v3s16 g_7dirs[7]; + +extern const v3s16 g_26dirs[26]; + +// 26th is (0,0,0) +extern const v3s16 g_27dirs[27]; + +extern const u8 wallmounted_to_facedir[6]; + +/// Direction in the 6D format. g_27dirs contains corresponding vectors. +/// Here P means Positive, N stands for Negative. +enum Direction6D { +// 0 + D6D_ZP, + D6D_YP, + D6D_XP, + D6D_ZN, + D6D_YN, + D6D_XN, +// 6 + D6D_XN_YP, + D6D_XP_YP, + D6D_YP_ZP, + D6D_YP_ZN, + D6D_XN_ZP, + D6D_XP_ZP, + D6D_XN_ZN, + D6D_XP_ZN, + D6D_XN_YN, + D6D_XP_YN, + D6D_YN_ZP, + D6D_YN_ZN, +// 18 + D6D_XN_YP_ZP, + D6D_XP_YP_ZP, + D6D_XN_YP_ZN, + D6D_XP_YP_ZN, + D6D_XN_YN_ZP, + D6D_XP_YN_ZP, + D6D_XN_YN_ZN, + D6D_XP_YN_ZN, +// 26 + D6D, + +// aliases + D6D_BACK = D6D_ZP, + D6D_TOP = D6D_YP, + D6D_RIGHT = D6D_XP, + D6D_FRONT = D6D_ZN, + D6D_BOTTOM = D6D_YN, + D6D_LEFT = D6D_XN, +}; + +/// Direction in the wallmounted format. +/// P is Positive, N is Negative. +enum DirectionWallmounted { + DWM_YP, + DWM_YN, + DWM_XP, + DWM_XN, + DWM_ZP, + DWM_ZN, +}; diff --git a/src/util/enriched_string.cpp b/src/util/enriched_string.cpp new file mode 100644 index 0000000..941f8b0 --- /dev/null +++ b/src/util/enriched_string.cpp @@ -0,0 +1,211 @@ +/* +Copyright (C) 2013 xyz, Ilya Zhuravlev <whatever@xyz.is> +Copyright (C) 2016 Nore, Nathanaëlle Courant <nore@mesecons.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "enriched_string.h" +#include "util/string.h" +#include "debug.h" +#include "log.h" + +using namespace irr::video; + +EnrichedString::EnrichedString() +{ + clear(); +} + +EnrichedString::EnrichedString(const std::wstring &string, + const std::vector<SColor> &colors) +{ + clear(); + m_string = string; + m_colors = colors; +} + +EnrichedString::EnrichedString(const std::wstring &s, const SColor &color) +{ + clear(); + addAtEnd(translate_string(s), color); +} + +EnrichedString::EnrichedString(const wchar_t *str, const SColor &color) +{ + clear(); + addAtEnd(translate_string(std::wstring(str)), color); +} + +void EnrichedString::clear() +{ + m_string.clear(); + m_colors.clear(); + m_has_background = false; + m_default_length = 0; + m_default_color = irr::video::SColor(255, 255, 255, 255); + m_background = irr::video::SColor(0, 0, 0, 0); +} + +void EnrichedString::operator=(const wchar_t *str) +{ + clear(); + addAtEnd(translate_string(std::wstring(str)), m_default_color); +} + +void EnrichedString::addAtEnd(const std::wstring &s, SColor initial_color) +{ + SColor color(initial_color); + bool use_default = (m_default_length == m_string.size() && + color == m_default_color); + + m_colors.reserve(m_colors.size() + s.size()); + + size_t i = 0; + while (i < s.length()) { + if (s[i] != L'\x1b') { + m_string += s[i]; + m_colors.push_back(color); + ++i; + continue; + } + ++i; + size_t start_index = i; + size_t length; + if (i == s.length()) { + break; + } + if (s[i] == L'(') { + ++i; + ++start_index; + while (i < s.length() && s[i] != L')') { + if (s[i] == L'\\') { + ++i; + } + ++i; + } + length = i - start_index; + ++i; + } else { + ++i; + length = 1; + } + std::wstring escape_sequence(s, start_index, length); + std::vector<std::wstring> parts = split(escape_sequence, L'@'); + if (parts[0] == L"c") { + if (parts.size() < 2) { + continue; + } + parseColorString(wide_to_utf8(parts[1]), color, true); + + // No longer use default color after first escape + if (use_default) { + m_default_length = m_string.size(); + use_default = false; + } + } else if (parts[0] == L"b") { + if (parts.size() < 2) { + continue; + } + parseColorString(wide_to_utf8(parts[1]), m_background, true); + m_has_background = true; + } + } + + // Update if no escape character was found + if (use_default) + m_default_length = m_string.size(); +} + +void EnrichedString::addChar(const EnrichedString &source, size_t i) +{ + m_string += source.m_string[i]; + m_colors.push_back(source.m_colors[i]); +} + +void EnrichedString::addCharNoColor(wchar_t c) +{ + m_string += c; + if (m_colors.empty()) { + m_colors.emplace_back(m_default_color); + } else { + m_colors.push_back(m_colors[m_colors.size() - 1]); + } +} + +EnrichedString EnrichedString::operator+(const EnrichedString &other) const +{ + EnrichedString result = *this; + result += other; + return result; +} + +void EnrichedString::operator+=(const EnrichedString &other) +{ + bool update_default_color = m_default_length == m_string.size(); + + m_string += other.m_string; + m_colors.insert(m_colors.end(), other.m_colors.begin(), other.m_colors.end()); + + if (update_default_color) { + m_default_length += other.m_default_length; + updateDefaultColor(); + } +} + +EnrichedString EnrichedString::substr(size_t pos, size_t len) const +{ + if (pos >= m_string.length()) + return EnrichedString(); + + if (len == std::string::npos || pos + len > m_string.length()) + len = m_string.length() - pos; + + EnrichedString str( + m_string.substr(pos, len), + std::vector<SColor>(m_colors.begin() + pos, m_colors.begin() + pos + len) + ); + + str.m_has_background = m_has_background; + str.m_background = m_background; + + if (pos < m_default_length) + str.m_default_length = std::min(m_default_length - pos, str.size()); + str.setDefaultColor(m_default_color); + return str; +} + +const wchar_t *EnrichedString::c_str() const +{ + return m_string.c_str(); +} + +const std::vector<SColor> &EnrichedString::getColors() const +{ + return m_colors; +} + +const std::wstring &EnrichedString::getString() const +{ + return m_string; +} + +void EnrichedString::updateDefaultColor() +{ + sanity_check(m_default_length <= m_colors.size()); + + for (size_t i = 0; i < m_default_length; ++i) + m_colors[i] = m_default_color; +} diff --git a/src/util/enriched_string.h b/src/util/enriched_string.h new file mode 100644 index 0000000..4e249ea --- /dev/null +++ b/src/util/enriched_string.h @@ -0,0 +1,110 @@ +/* +Copyright (C) 2013 xyz, Ilya Zhuravlev <whatever@xyz.is> +Copyright (C) 2016 Nore, Nathanaëlle Courant <nore@mesecons.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include <vector> +#include <SColor.h> + +using namespace irr; + +class EnrichedString { +public: + EnrichedString(); + EnrichedString(const std::wstring &s, + const video::SColor &color = video::SColor(255, 255, 255, 255)); + EnrichedString(const wchar_t *str, + const video::SColor &color = video::SColor(255, 255, 255, 255)); + EnrichedString(const std::wstring &string, + const std::vector<video::SColor> &colors); + void operator=(const wchar_t *str); + + void clear(); + + void addAtEnd(const std::wstring &s, video::SColor color); + + // Adds the character source[i] at the end. + // An EnrichedString should always be able to be copied + // to the end of an existing EnrichedString that way. + void addChar(const EnrichedString &source, size_t i); + + // Adds a single character at the end, without specifying its + // color. The color used will be the one from the last character. + void addCharNoColor(wchar_t c); + + EnrichedString substr(size_t pos = 0, size_t len = std::string::npos) const; + EnrichedString operator+(const EnrichedString &other) const; + void operator+=(const EnrichedString &other); + const wchar_t *c_str() const; + const std::vector<video::SColor> &getColors() const; + const std::wstring &getString() const; + + inline void setDefaultColor(video::SColor color) + { + m_default_color = color; + updateDefaultColor(); + } + void updateDefaultColor(); + inline const video::SColor &getDefaultColor() const + { + return m_default_color; + } + + inline bool operator==(const EnrichedString &other) const + { + return (m_string == other.m_string && m_colors == other.m_colors); + } + inline bool operator!=(const EnrichedString &other) const + { + return !(*this == other); + } + inline bool empty() const + { + return m_string.empty(); + } + inline size_t size() const + { + return m_string.size(); + } + + inline bool hasBackground() const + { + return m_has_background; + } + inline video::SColor getBackground() const + { + return m_background; + } + inline void setBackground(video::SColor color) + { + m_background = color; + m_has_background = true; + } + +private: + std::wstring m_string; + std::vector<video::SColor> m_colors; + bool m_has_background; + video::SColor m_default_color; + video::SColor m_background; + // This variable defines the length of the default-colored text. + // Change this to a std::vector if an "end coloring" tag is wanted. + size_t m_default_length = 0; +}; diff --git a/src/util/hex.h b/src/util/hex.h new file mode 100644 index 0000000..708f330 --- /dev/null +++ b/src/util/hex.h @@ -0,0 +1,60 @@ +/* +Minetest +Copyright (C) 2013 Jonathan Neuschäfer <j.neuschaefer@gmx.net> + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> + +static const char hex_chars[] = "0123456789abcdef"; + +static inline std::string hex_encode(const char *data, unsigned int data_size) +{ + std::string ret; + ret.reserve(data_size * 2); + + char buf2[3]; + buf2[2] = '\0'; + + for (unsigned int i = 0; i < data_size; i++) { + unsigned char c = (unsigned char)data[i]; + buf2[0] = hex_chars[(c & 0xf0) >> 4]; + buf2[1] = hex_chars[c & 0x0f]; + ret.append(buf2); + } + + return ret; +} + +static inline std::string hex_encode(const std::string &data) +{ + return hex_encode(data.c_str(), data.size()); +} + +static inline bool hex_digit_decode(char hexdigit, unsigned char &value) +{ + if (hexdigit >= '0' && hexdigit <= '9') + value = hexdigit - '0'; + else if (hexdigit >= 'A' && hexdigit <= 'F') + value = hexdigit - 'A' + 10; + else if (hexdigit >= 'a' && hexdigit <= 'f') + value = hexdigit - 'a' + 10; + else + return false; + return true; +} diff --git a/src/util/ieee_float.cpp b/src/util/ieee_float.cpp new file mode 100644 index 0000000..b73763c --- /dev/null +++ b/src/util/ieee_float.cpp @@ -0,0 +1,136 @@ +/* + * Conversion of f32 to IEEE-754 and vice versa. + * + * © Copyright 2018 Pedro Gimeno Fortea. + * + * 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. + */ +#include "ieee_float.h" +#include "log.h" +#include "porting.h" +#include <limits> +#include <cmath> + +// Given an unsigned 32-bit integer representing an IEEE-754 single-precision +// float, return the float. +f32 u32Tof32Slow(u32 i) +{ + // clang-format off + int exp = (i >> 23) & 0xFF; + u32 sign = i & 0x80000000UL; + u32 imant = i & 0x7FFFFFUL; + if (exp == 0xFF) { + // Inf/NaN + if (imant == 0) { + if (std::numeric_limits<f32>::has_infinity) + return sign ? -std::numeric_limits<f32>::infinity() : + std::numeric_limits<f32>::infinity(); + return sign ? std::numeric_limits<f32>::max() : + std::numeric_limits<f32>::lowest(); + } + return std::numeric_limits<f32>::has_quiet_NaN ? + std::numeric_limits<f32>::quiet_NaN() : -0.f; + } + + if (!exp) { + // Denormal or zero + return sign ? -ldexpf((f32)imant, -149) : ldexpf((f32)imant, -149); + } + + return sign ? -ldexpf((f32)(imant | 0x800000UL), exp - 150) : + ldexpf((f32)(imant | 0x800000UL), exp - 150); + // clang-format on +} + +// Given a float, return an unsigned 32-bit integer representing the f32 +// in IEEE-754 single-precision format. +u32 f32Tou32Slow(f32 f) +{ + u32 signbit = std::copysign(1.0f, f) == 1.0f ? 0 : 0x80000000UL; + if (f == 0.f) + return signbit; + if (std::isnan(f)) + return signbit | 0x7FC00000UL; + if (std::isinf(f)) + return signbit | 0x7F800000UL; + int exp = 0; // silence warning + f32 mant = frexpf(f, &exp); + u32 imant = (u32)std::floor((signbit ? -16777216.f : 16777216.f) * mant); + exp += 126; + if (exp <= 0) { + // Denormal + return signbit | (exp <= -31 ? 0 : imant >> (1 - exp)); + } + + if (exp >= 255) { + // Overflow due to the platform having exponents bigger than IEEE ones. + // Return signed infinity. + return signbit | 0x7F800000UL; + } + + // Regular number + return signbit | (exp << 23) | (imant & 0x7FFFFFUL); +} + +// This test needs the following requisites in order to work: +// - The float type must be a 32 bits IEEE-754 single-precision float. +// - The endianness of f32s and integers must match. +FloatType getFloatSerializationType() +{ + // clang-format off + const f32 cf = -22220490.f; + const u32 cu = 0xCBA98765UL; + if (std::numeric_limits<f32>::is_iec559 && sizeof(cf) == 4 && + sizeof(cu) == 4 && !memcmp(&cf, &cu, 4)) { + // u32Tof32Slow and f32Tou32Slow are not needed, use memcpy + return FLOATTYPE_SYSTEM; + } + + // Run quick tests to ensure the custom functions provide acceptable results + warningstream << "floatSerialization: f32 and u32 endianness are " + "not equal or machine is not IEEE-754 compliant" << std::endl; + u32 i; + char buf[128]; + + // NaN checks aren't included in the main loop + if (!std::isnan(u32Tof32Slow(0x7FC00000UL))) { + porting::mt_snprintf(buf, sizeof(buf), + "u32Tof32Slow(0x7FC00000) failed to produce a NaN, actual: %.9g", + u32Tof32Slow(0x7FC00000UL)); + infostream << buf << std::endl; + } + if (!std::isnan(u32Tof32Slow(0xFFC00000UL))) { + porting::mt_snprintf(buf, sizeof(buf), + "u32Tof32Slow(0xFFC00000) failed to produce a NaN, actual: %.9g", + u32Tof32Slow(0xFFC00000UL)); + infostream << buf << std::endl; + } + + i = f32Tou32Slow(std::numeric_limits<f32>::quiet_NaN()); + // check that it corresponds to a NaN encoding + if ((i & 0x7F800000UL) != 0x7F800000UL || (i & 0x7FFFFFUL) == 0) { + porting::mt_snprintf(buf, sizeof(buf), + "f32Tou32Slow(NaN) failed to encode NaN, actual: 0x%X", i); + infostream << buf << std::endl; + } + + return FLOATTYPE_SLOW; + // clang-format on +} diff --git a/src/util/ieee_float.h b/src/util/ieee_float.h new file mode 100644 index 0000000..42b8641 --- /dev/null +++ b/src/util/ieee_float.h @@ -0,0 +1,34 @@ +/* +Minetest +Copyright (C) 2018 SmallJoker <mk939@ymail.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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" + +enum FloatType +{ + FLOATTYPE_UNKNOWN, + FLOATTYPE_SLOW, + FLOATTYPE_SYSTEM +}; + +f32 u32Tof32Slow(u32 i); +u32 f32Tou32Slow(f32 f); + +FloatType getFloatSerializationType(); diff --git a/src/util/md32_common.h b/src/util/md32_common.h new file mode 100644 index 0000000..2c050b7 --- /dev/null +++ b/src/util/md32_common.h @@ -0,0 +1,430 @@ +/* md32_common.h file used by sha256 implementation */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +/*- + * This is a generic 32 bit "collector" for message digest algorithms. + * Whenever needed it collects input character stream into chunks of + * 32 bit values and invokes a block function that performs actual hash + * calculations. + * + * Porting guide. + * + * Obligatory macros: + * + * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN + * this macro defines byte order of input stream. + * HASH_CBLOCK + * size of a unit chunk HASH_BLOCK operates on. + * HASH_LONG + * has to be at lest 32 bit wide, if it's wider, then + * HASH_LONG_LOG2 *has to* be defined along + * HASH_CTX + * context structure that at least contains following + * members: + * typedef struct { + * ... + * HASH_LONG Nl,Nh; + * either { + * HASH_LONG data[HASH_LBLOCK]; + * unsigned char data[HASH_CBLOCK]; + * }; + * unsigned int num; + * ... + * } HASH_CTX; + * data[] vector is expected to be zeroed upon first call to + * HASH_UPDATE. + * HASH_UPDATE + * name of "Update" function, implemented here. + * HASH_TRANSFORM + * name of "Transform" function, implemented here. + * HASH_FINAL + * name of "Final" function, implemented here. + * HASH_BLOCK_DATA_ORDER + * name of "block" function capable of treating *unaligned* input + * message in original (data) byte order, implemented externally. + * HASH_MAKE_STRING + * macro convering context variables to an ASCII hash string. + * + * MD5 example: + * + * #define DATA_ORDER_IS_LITTLE_ENDIAN + * + * #define HASH_LONG MD5_LONG + * #define HASH_LONG_LOG2 MD5_LONG_LOG2 + * #define HASH_CTX MD5_CTX + * #define HASH_CBLOCK MD5_CBLOCK + * #define HASH_UPDATE MD5_Update + * #define HASH_TRANSFORM MD5_Transform + * #define HASH_FINAL MD5_Final + * #define HASH_BLOCK_DATA_ORDER md5_block_data_order + * + * <appro@fy.chalmers.se> + */ + +#pragma once + +#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) +# error "DATA_ORDER must be defined!" +#endif + +#ifndef HASH_CBLOCK +# error "HASH_CBLOCK must be defined!" +#endif +#ifndef HASH_LONG +# error "HASH_LONG must be defined!" +#endif +#ifndef HASH_CTX +# error "HASH_CTX must be defined!" +#endif + +#ifndef HASH_UPDATE +# error "HASH_UPDATE must be defined!" +#endif +#ifndef HASH_TRANSFORM +# error "HASH_TRANSFORM must be defined!" +#endif +#ifndef HASH_FINAL +# error "HASH_FINAL must be defined!" +#endif + +#ifndef HASH_BLOCK_DATA_ORDER +# error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif + +/* + * Engage compiler specific rotate intrinsic function if available. + */ +#undef ROTATE +#ifndef PEDANTIC +# if defined(_MSC_VER) +# define ROTATE(a,n) _lrotl(a,n) +# elif defined(__ICC) +# define ROTATE(a,n) _rotl(a,n) +# elif defined(__MWERKS__) +# if defined(__POWERPC__) +# define ROTATE(a,n) __rlwinm(a,n,0,31) +# elif defined(__MC68K__) + /* Motorola specific tweak. <appro@fy.chalmers.se> */ +# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) ) +# else +# define ROTATE(a,n) __rol(a,n) +# endif +# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) + /* + * Some GNU C inline assembler templates. Note that these are + * rotates by *constant* number of bits! But that's exactly + * what we need here... + * <appro@fy.chalmers.se> + */ +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ( \ + "roll %1,%0" \ + : "=r"(ret) \ + : "I"(n), "0"((unsigned int)(a)) \ + : "cc"); \ + ret; \ + }) +# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ + defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ( \ + "rlwinm %0,%1,%2,0,31" \ + : "=r"(ret) \ + : "r"(a), "I"(n)); \ + ret; \ + }) +# elif defined(__s390x__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ("rll %0,%1,%2" \ + : "=r"(ret) \ + : "r"(a), "I"(n)); \ + ret; \ + }) +# endif +# endif +#endif /* PEDANTIC */ + +#ifndef ROTATE +# define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#endif + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +# ifndef PEDANTIC +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \ + (defined(__x86_64) || defined(__x86_64__)) +# if !defined(B_ENDIAN) + /* + * This gives ~30-40% performance improvement in SHA-256 compiled + * with gcc [on P4]. Well, first macro to be frank. We can pull + * this trick on x86* platforms only, because these CPUs can fetch + * unaligned data without raising an exception. + */ +# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \ + asm ("bswapl %0":"=r"(r):"0"(r)); \ + (c)+=4; (l)=r; }) +# define HOST_l2c(l,c) ({ unsigned int r=(l); \ + asm ("bswapl %0":"=r"(r):"0"(r)); \ + *((unsigned int *)(c))=r; (c)+=4; r; }) +# endif +# elif defined(__aarch64__) +# if defined(__BYTE_ORDER__) +# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ +# define HOST_c2l(c,l) ({ unsigned int r; \ + asm ("rev %w0,%w1" \ + :"=r"(r) \ + :"r"(*((const unsigned int *)(c))));\ + (c)+=4; (l)=r; }) +# define HOST_l2c(l,c) ({ unsigned int r; \ + asm ("rev %w0,%w1" \ + :"=r"(r) \ + :"r"((unsigned int)(l)));\ + *((unsigned int *)(c))=r; (c)+=4; r; }) +# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ +# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l)) +# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l)) +# endif +# endif +# endif +# endif +# if defined(__s390__) || defined(__s390x__) +# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l)) +# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l)) +# endif +# endif + +# ifndef HOST_c2l +# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++))) ) ) +# endif +# ifndef HOST_l2c +# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff), \ + l) +# endif + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +# ifndef PEDANTIC +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(__s390x__) +# define HOST_c2l(c,l) ({ asm ("lrv %0,%1" \ + :"=d"(l) :"m"(*(const unsigned int *)(c)));\ + (c)+=4; (l); }) +# define HOST_l2c(l,c) ({ asm ("strv %1,%0" \ + :"=m"(*(unsigned int *)(c)) :"d"(l));\ + (c)+=4; (l); }) +# endif +# endif +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# ifndef B_ENDIAN + /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */ +# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l) +# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l) +# endif +# endif +# endif + +# ifndef HOST_c2l +# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24) ) +# endif +# ifndef HOST_l2c +# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + l) +# endif + +#endif + +/* + * Time for some action:-) + */ + +int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) +{ + const unsigned char *data = (const unsigned char *)data_; + unsigned char *p; + HASH_LONG l; + size_t n; + + if (len == 0) + return 1; + + l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL; + /* + * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai + * <weidai@eskimo.com> for pointing it out. + */ + if (l < c->Nl) /* overflow */ + c->Nh++; + c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on + * 16-bit */ + c->Nl = l; + + n = c->num; + if (n != 0) { + p = (unsigned char *)c->data; + + if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { + memcpy(p + n, data, HASH_CBLOCK - n); + HASH_BLOCK_DATA_ORDER(c, p, 1); + n = HASH_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + memset(p, 0, HASH_CBLOCK); /* keep it zeroed */ + } else { + memcpy(p + n, data, len); + c->num += (unsigned int)len; + return 1; + } + } + + n = len / HASH_CBLOCK; + if (n > 0) { + HASH_BLOCK_DATA_ORDER(c, data, n); + n *= HASH_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + p = (unsigned char *)c->data; + c->num = (unsigned int)len; + memcpy(p, data, len); + } + return 1; +} + +void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data) +{ + HASH_BLOCK_DATA_ORDER(c, data, 1); +} + +int HASH_FINAL(unsigned char *md, HASH_CTX *c) +{ + unsigned char *p = (unsigned char *)c->data; + size_t n = c->num; + + p[n] = 0x80; /* there is always room for one */ + n++; + + if (n > (HASH_CBLOCK - 8)) { + memset(p + n, 0, HASH_CBLOCK - n); + n = 0; + HASH_BLOCK_DATA_ORDER(c, p, 1); + } + memset(p + n, 0, HASH_CBLOCK - 8 - n); + + p += HASH_CBLOCK - 8; +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + (void)HOST_l2c(c->Nh, p); + (void)HOST_l2c(c->Nl, p); +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + (void)HOST_l2c(c->Nl, p); + (void)HOST_l2c(c->Nh, p); +#endif + p -= HASH_CBLOCK; + HASH_BLOCK_DATA_ORDER(c, p, 1); + c->num = 0; + memset(p, 0, HASH_CBLOCK); + +#ifndef HASH_MAKE_STRING +# error "HASH_MAKE_STRING must be defined!" +#else + HASH_MAKE_STRING(c, md); +#endif + + return 1; +} + +#ifndef MD32_REG_T +# if defined(__alpha) || defined(__sparcv9) || defined(__mips) +# define MD32_REG_T long +/* + * This comment was originaly written for MD5, which is why it + * discusses A-D. But it basically applies to all 32-bit digests, + * which is why it was moved to common header file. + * + * In case you wonder why A-D are declared as long and not + * as MD5_LONG. Doing so results in slight performance + * boost on LP64 architectures. The catch is we don't + * really care if 32 MSBs of a 64-bit register get polluted + * with eventual overflows as we *save* only 32 LSBs in + * *either* case. Now declaring 'em long excuses the compiler + * from keeping 32 MSBs zeroed resulting in 13% performance + * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. + * Well, to be honest it should say that this *prevents* + * performance degradation. + * <appro@fy.chalmers.se> + */ +# else +/* + * Above is not absolute and there are LP64 compilers that + * generate better code if MD32_REG_T is defined int. The above + * pre-processor condition reflects the circumstances under which + * the conclusion was made and is subject to further extension. + * <appro@fy.chalmers.se> + */ +# define MD32_REG_T int +# endif +#endif diff --git a/src/util/metricsbackend.cpp b/src/util/metricsbackend.cpp new file mode 100644 index 0000000..63b49ac --- /dev/null +++ b/src/util/metricsbackend.cpp @@ -0,0 +1,204 @@ +/* +Minetest +Copyright (C) 2013-2020 Minetest core developers team + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "metricsbackend.h" +#include "util/thread.h" +#if USE_PROMETHEUS +#include <prometheus/exposer.h> +#include <prometheus/registry.h> +#include <prometheus/counter.h> +#include <prometheus/gauge.h> +#include "log.h" +#include "settings.h" +#endif + +/* Plain implementation */ + +class SimpleMetricCounter : public MetricCounter +{ +public: + SimpleMetricCounter() : MetricCounter(), m_counter(0.0) {} + + virtual ~SimpleMetricCounter() {} + + void increment(double number) override + { + MutexAutoLock lock(m_mutex); + m_counter += number; + } + double get() const override + { + MutexAutoLock lock(m_mutex); + return m_counter; + } + +private: + mutable std::mutex m_mutex; + double m_counter; +}; + +class SimpleMetricGauge : public MetricGauge +{ +public: + SimpleMetricGauge() : MetricGauge(), m_gauge(0.0) {} + + virtual ~SimpleMetricGauge() {} + + void increment(double number) override + { + MutexAutoLock lock(m_mutex); + m_gauge += number; + } + void decrement(double number) override + { + MutexAutoLock lock(m_mutex); + m_gauge -= number; + } + void set(double number) override + { + MutexAutoLock lock(m_mutex); + m_gauge = number; + } + double get() const override + { + MutexAutoLock lock(m_mutex); + return m_gauge; + } + +private: + mutable std::mutex m_mutex; + double m_gauge; +}; + +MetricCounterPtr MetricsBackend::addCounter( + const std::string &name, const std::string &help_str, Labels labels) +{ + return std::make_shared<SimpleMetricCounter>(); +} + +MetricGaugePtr MetricsBackend::addGauge( + const std::string &name, const std::string &help_str, Labels labels) +{ + return std::make_shared<SimpleMetricGauge>(); +} + +/* Prometheus backend */ + +#if USE_PROMETHEUS + +class PrometheusMetricCounter : public MetricCounter +{ +public: + PrometheusMetricCounter() = delete; + + PrometheusMetricCounter(const std::string &name, const std::string &help_str, + MetricsBackend::Labels labels, + std::shared_ptr<prometheus::Registry> registry) : + MetricCounter(), + m_family(prometheus::BuildCounter() + .Name(name) + .Help(help_str) + .Register(*registry)), + m_counter(m_family.Add(labels)) + { + } + + virtual ~PrometheusMetricCounter() {} + + virtual void increment(double number) { m_counter.Increment(number); } + virtual double get() const { return m_counter.Value(); } + +private: + prometheus::Family<prometheus::Counter> &m_family; + prometheus::Counter &m_counter; +}; + +class PrometheusMetricGauge : public MetricGauge +{ +public: + PrometheusMetricGauge() = delete; + + PrometheusMetricGauge(const std::string &name, const std::string &help_str, + MetricsBackend::Labels labels, + std::shared_ptr<prometheus::Registry> registry) : + MetricGauge(), + m_family(prometheus::BuildGauge() + .Name(name) + .Help(help_str) + .Register(*registry)), + m_gauge(m_family.Add(labels)) + { + } + + virtual ~PrometheusMetricGauge() {} + + virtual void increment(double number) { m_gauge.Increment(number); } + virtual void decrement(double number) { m_gauge.Decrement(number); } + virtual void set(double number) { m_gauge.Set(number); } + virtual double get() const { return m_gauge.Value(); } + +private: + prometheus::Family<prometheus::Gauge> &m_family; + prometheus::Gauge &m_gauge; +}; + +class PrometheusMetricsBackend : public MetricsBackend +{ +public: + PrometheusMetricsBackend(const std::string &addr) : + MetricsBackend(), m_exposer(std::make_unique<prometheus::Exposer>(addr)), + m_registry(std::make_shared<prometheus::Registry>()) + { + m_exposer->RegisterCollectable(m_registry); + } + + virtual ~PrometheusMetricsBackend() {} + + MetricCounterPtr addCounter( + const std::string &name, const std::string &help_str, + Labels labels = {}) override; + MetricGaugePtr addGauge( + const std::string &name, const std::string &help_str, + Labels labels = {}) override; + +private: + std::unique_ptr<prometheus::Exposer> m_exposer; + std::shared_ptr<prometheus::Registry> m_registry; +}; + +MetricCounterPtr PrometheusMetricsBackend::addCounter( + const std::string &name, const std::string &help_str, Labels labels) +{ + return std::make_shared<PrometheusMetricCounter>(name, help_str, labels, m_registry); +} + +MetricGaugePtr PrometheusMetricsBackend::addGauge( + const std::string &name, const std::string &help_str, Labels labels) +{ + return std::make_shared<PrometheusMetricGauge>(name, help_str, labels, m_registry); +} + +MetricsBackend *createPrometheusMetricsBackend() +{ + std::string addr; + g_settings->getNoEx("prometheus_listener_address", addr); + return new PrometheusMetricsBackend(addr); +} + +#endif diff --git a/src/util/metricsbackend.h b/src/util/metricsbackend.h new file mode 100644 index 0000000..644c733 --- /dev/null +++ b/src/util/metricsbackend.h @@ -0,0 +1,72 @@ +/* +Minetest +Copyright (C) 2013-2020 Minetest core developers team + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include <memory> +#include <string> +#include <utility> +#include "config.h" + +class MetricCounter +{ +public: + MetricCounter() = default; + + virtual ~MetricCounter() {} + + virtual void increment(double number = 1.0) = 0; + virtual double get() const = 0; +}; + +typedef std::shared_ptr<MetricCounter> MetricCounterPtr; + +class MetricGauge +{ +public: + MetricGauge() = default; + virtual ~MetricGauge() {} + + virtual void increment(double number = 1.0) = 0; + virtual void decrement(double number = 1.0) = 0; + virtual void set(double number) = 0; + virtual double get() const = 0; +}; + +typedef std::shared_ptr<MetricGauge> MetricGaugePtr; + +class MetricsBackend +{ +public: + MetricsBackend() = default; + + virtual ~MetricsBackend() {} + + typedef std::initializer_list<std::pair<const std::string, std::string>> Labels; + + virtual MetricCounterPtr addCounter( + const std::string &name, const std::string &help_str, + Labels labels = {}); + virtual MetricGaugePtr addGauge( + const std::string &name, const std::string &help_str, + Labels labels = {}); +}; + +#if USE_PROMETHEUS +MetricsBackend *createPrometheusMetricsBackend(); +#endif diff --git a/src/util/numeric.cpp b/src/util/numeric.cpp new file mode 100644 index 0000000..aa3bb84 --- /dev/null +++ b/src/util/numeric.cpp @@ -0,0 +1,223 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "numeric.h" + +#include "log.h" +#include "constants.h" // BS, MAP_BLOCKSIZE +#include "noise.h" // PseudoRandom, PcgRandom +#include "threading/mutex_auto_lock.h" +#include <cstring> +#include <cmath> + + +// myrand + +PcgRandom g_pcgrand; + +u32 myrand() +{ + return g_pcgrand.next(); +} + +void mysrand(unsigned int seed) +{ + g_pcgrand.seed(seed); +} + +void myrand_bytes(void *out, size_t len) +{ + g_pcgrand.bytes(out, len); +} + +float myrand_float() +{ + u32 uv = g_pcgrand.next(); + return (float)uv / (float)U32_MAX; +} + +int myrand_range(int min, int max) +{ + return g_pcgrand.range(min, max); +} + +float myrand_range(float min, float max) +{ + return (max-min) * myrand_float() + min; +} + + +/* + 64-bit unaligned version of MurmurHash +*/ +u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed) +{ + const u64 m = 0xc6a4a7935bd1e995ULL; + const int r = 47; + u64 h = seed ^ (len * m); + + const u8 *data = (const u8 *)key; + const u8 *end = data + (len / 8) * 8; + + while (data != end) { + u64 k; + memcpy(&k, data, sizeof(u64)); + data += sizeof(u64); + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + h *= m; + } + + const unsigned char *data2 = (const unsigned char *)data; + switch (len & 7) { + case 7: h ^= (u64)data2[6] << 48; + case 6: h ^= (u64)data2[5] << 40; + case 5: h ^= (u64)data2[4] << 32; + case 4: h ^= (u64)data2[3] << 24; + case 3: h ^= (u64)data2[2] << 16; + case 2: h ^= (u64)data2[1] << 8; + case 1: h ^= (u64)data2[0]; + h *= m; + } + + h ^= h >> r; + h *= m; + h ^= h >> r; + + return h; +} + +/* + blockpos_b: position of block in block coordinates + camera_pos: position of camera in nodes + camera_dir: an unit vector pointing to camera direction + range: viewing range + distance_ptr: return location for distance from the camera +*/ +bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, + f32 camera_fov, f32 range, f32 *distance_ptr) +{ + v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE; + + // Block center position + v3f blockpos( + ((float)blockpos_nodes.X + MAP_BLOCKSIZE/2) * BS, + ((float)blockpos_nodes.Y + MAP_BLOCKSIZE/2) * BS, + ((float)blockpos_nodes.Z + MAP_BLOCKSIZE/2) * BS + ); + + // Block position relative to camera + v3f blockpos_relative = blockpos - camera_pos; + + // Total distance + f32 d = MYMAX(0, blockpos_relative.getLength() - BLOCK_MAX_RADIUS); + + if (distance_ptr) + *distance_ptr = d; + + // If block is far away, it's not in sight + if (d > range) + return false; + + // If block is (nearly) touching the camera, don't + // bother validating further (that is, render it anyway) + if (d == 0) + return true; + + // Adjust camera position, for purposes of computing the angle, + // such that a block that has any portion visible with the + // current camera position will have the center visible at the + // adjusted postion + f32 adjdist = BLOCK_MAX_RADIUS / cos((M_PI - camera_fov) / 2); + + // Block position relative to adjusted camera + v3f blockpos_adj = blockpos - (camera_pos - camera_dir * adjdist); + + // Distance in camera direction (+=front, -=back) + f32 dforward = blockpos_adj.dotProduct(camera_dir); + + // Cosine of the angle between the camera direction + // and the block direction (camera_dir is an unit vector) + f32 cosangle = dforward / blockpos_adj.getLength(); + + // If block is not in the field of view, skip it + // HOTFIX: use sligthly increased angle (+10%) to fix too agressive + // culling. Somebody have to find out whats wrong with the math here. + // Previous value: camera_fov / 2 + if (cosangle < std::cos(camera_fov * 0.55f)) + return false; + + return true; +} + +inline float adjustDist(float dist, float zoom_fov) +{ + // 1.775 ~= 72 * PI / 180 * 1.4, the default FOV on the client. + // The heuristic threshold for zooming is half of that. + static constexpr const float threshold_fov = 1.775f / 2.0f; + if (zoom_fov < 0.001f || zoom_fov > threshold_fov) + return dist; + + return dist * std::cbrt((1.0f - std::cos(threshold_fov)) / + (1.0f - std::cos(zoom_fov / 2.0f))); +} + +s16 adjustDist(s16 dist, float zoom_fov) +{ + return std::round(adjustDist((float)dist, zoom_fov)); +} + +void setPitchYawRollRad(core::matrix4 &m, const v3f &rot) +{ + f64 a1 = rot.Z, a2 = rot.X, a3 = rot.Y; + f64 c1 = cos(a1), s1 = sin(a1); + f64 c2 = cos(a2), s2 = sin(a2); + f64 c3 = cos(a3), s3 = sin(a3); + f32 *M = m.pointer(); + + M[0] = s1 * s2 * s3 + c1 * c3; + M[1] = s1 * c2; + M[2] = s1 * s2 * c3 - c1 * s3; + + M[4] = c1 * s2 * s3 - s1 * c3; + M[5] = c1 * c2; + M[6] = c1 * s2 * c3 + s1 * s3; + + M[8] = c2 * s3; + M[9] = -s2; + M[10] = c2 * c3; +} + +v3f getPitchYawRollRad(const core::matrix4 &m) +{ + const f32 *M = m.pointer(); + + f64 a1 = atan2(M[1], M[5]); + f32 c2 = std::sqrt((f64)M[10]*M[10] + (f64)M[8]*M[8]); + f32 a2 = atan2f(-M[9], c2); + f64 c1 = cos(a1); + f64 s1 = sin(a1); + f32 a3 = atan2f(s1*M[6] - c1*M[2], c1*M[0] - s1*M[4]); + + return v3f(a2, a3, a1); +} diff --git a/src/util/numeric.h b/src/util/numeric.h new file mode 100644 index 0000000..265046a --- /dev/null +++ b/src/util/numeric.h @@ -0,0 +1,471 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "basic_macros.h" +#include "constants.h" +#include "irrlichttypes.h" +#include "irr_v2d.h" +#include "irr_v3d.h" +#include "irr_aabb3d.h" +#include "SColor.h" +#include <matrix4.h> + +#define rangelim(d, min, max) ((d) < (min) ? (min) : ((d) > (max) ? (max) : (d))) +#define myfloor(x) ((x) < 0.0 ? (int)(x) - 1 : (int)(x)) +// The naive swap performs better than the xor version +#define SWAP(t, x, y) do { \ + t temp = x; \ + x = y; \ + y = temp; \ +} while (0) + +// Maximum radius of a block. The magic number is +// sqrt(3.0) / 2.0 in literal form. +static constexpr const f32 BLOCK_MAX_RADIUS = 0.866025403784f * MAP_BLOCKSIZE * BS; + +inline s16 getContainerPos(s16 p, s16 d) +{ + return (p >= 0 ? p : p - d + 1) / d; +} + +inline v2s16 getContainerPos(v2s16 p, s16 d) +{ + return v2s16( + getContainerPos(p.X, d), + getContainerPos(p.Y, d) + ); +} + +inline v3s16 getContainerPos(v3s16 p, s16 d) +{ + return v3s16( + getContainerPos(p.X, d), + getContainerPos(p.Y, d), + getContainerPos(p.Z, d) + ); +} + +inline v2s16 getContainerPos(v2s16 p, v2s16 d) +{ + return v2s16( + getContainerPos(p.X, d.X), + getContainerPos(p.Y, d.Y) + ); +} + +inline v3s16 getContainerPos(v3s16 p, v3s16 d) +{ + return v3s16( + getContainerPos(p.X, d.X), + getContainerPos(p.Y, d.Y), + getContainerPos(p.Z, d.Z) + ); +} + +inline void getContainerPosWithOffset(s16 p, s16 d, s16 &container, s16 &offset) +{ + container = (p >= 0 ? p : p - d + 1) / d; + offset = p & (d - 1); +} + +inline void getContainerPosWithOffset(const v2s16 &p, s16 d, v2s16 &container, v2s16 &offset) +{ + getContainerPosWithOffset(p.X, d, container.X, offset.X); + getContainerPosWithOffset(p.Y, d, container.Y, offset.Y); +} + +inline void getContainerPosWithOffset(const v3s16 &p, s16 d, v3s16 &container, v3s16 &offset) +{ + getContainerPosWithOffset(p.X, d, container.X, offset.X); + getContainerPosWithOffset(p.Y, d, container.Y, offset.Y); + getContainerPosWithOffset(p.Z, d, container.Z, offset.Z); +} + + +inline bool isInArea(v3s16 p, s16 d) +{ + return ( + p.X >= 0 && p.X < d && + p.Y >= 0 && p.Y < d && + p.Z >= 0 && p.Z < d + ); +} + +inline bool isInArea(v2s16 p, s16 d) +{ + return ( + p.X >= 0 && p.X < d && + p.Y >= 0 && p.Y < d + ); +} + +inline bool isInArea(v3s16 p, v3s16 d) +{ + return ( + p.X >= 0 && p.X < d.X && + p.Y >= 0 && p.Y < d.Y && + p.Z >= 0 && p.Z < d.Z + ); +} + +inline void sortBoxVerticies(v3s16 &p1, v3s16 &p2) { + if (p1.X > p2.X) + SWAP(s16, p1.X, p2.X); + if (p1.Y > p2.Y) + SWAP(s16, p1.Y, p2.Y); + if (p1.Z > p2.Z) + SWAP(s16, p1.Z, p2.Z); +} + +inline v3s16 componentwise_min(const v3s16 &a, const v3s16 &b) +{ + return v3s16(MYMIN(a.X, b.X), MYMIN(a.Y, b.Y), MYMIN(a.Z, b.Z)); +} + +inline v3s16 componentwise_max(const v3s16 &a, const v3s16 &b) +{ + return v3s16(MYMAX(a.X, b.X), MYMAX(a.Y, b.Y), MYMAX(a.Z, b.Z)); +} + + +/** Returns \p f wrapped to the range [-360, 360] + * + * See test.cpp for example cases. + * + * \note This is also used in cases where degrees wrapped to the range [0, 360] + * is innapropriate (e.g. pitch needs negative values) + * + * \internal functionally equivalent -- although precision may vary slightly -- + * to fmodf((f), 360.0f) however empirical tests indicate that this approach is + * faster. + */ +inline float modulo360f(float f) +{ + int sign; + int whole; + float fraction; + + if (f < 0) { + f = -f; + sign = -1; + } else { + sign = 1; + } + + whole = f; + + fraction = f - whole; + whole %= 360; + + return sign * (whole + fraction); +} + + +/** Returns \p f wrapped to the range [0, 360] + */ +inline float wrapDegrees_0_360(float f) +{ + float value = modulo360f(f); + return value < 0 ? value + 360 : value; +} + + +/** Returns \p v3f wrapped to the range [0, 360] + */ +inline v3f wrapDegrees_0_360_v3f(v3f v) +{ + v3f value_v3f; + value_v3f.X = modulo360f(v.X); + value_v3f.Y = modulo360f(v.Y); + value_v3f.Z = modulo360f(v.Z); + + // Now that values are wrapped, use to get values for certain ranges + value_v3f.X = value_v3f.X < 0 ? value_v3f.X + 360 : value_v3f.X; + value_v3f.Y = value_v3f.Y < 0 ? value_v3f.Y + 360 : value_v3f.Y; + value_v3f.Z = value_v3f.Z < 0 ? value_v3f.Z + 360 : value_v3f.Z; + return value_v3f; +} + + +/** Returns \p f wrapped to the range [-180, 180] + */ +inline float wrapDegrees_180(float f) +{ + float value = modulo360f(f + 180); + if (value < 0) + value += 360; + return value - 180; +} + +/* + Pseudo-random (VC++ rand() sucks) +*/ +#define MYRAND_RANGE 0xffffffff +u32 myrand(); +void mysrand(unsigned int seed); +void myrand_bytes(void *out, size_t len); +int myrand_range(int min, int max); +float myrand_range(float min, float max); +float myrand_float(); + +/* + Miscellaneous functions +*/ + +inline u32 get_bits(u32 x, u32 pos, u32 len) +{ + u32 mask = (1 << len) - 1; + return (x >> pos) & mask; +} + +inline void set_bits(u32 *x, u32 pos, u32 len, u32 val) +{ + u32 mask = (1 << len) - 1; + *x &= ~(mask << pos); + *x |= (val & mask) << pos; +} + +inline u32 calc_parity(u32 v) +{ + v ^= v >> 16; + v ^= v >> 8; + v ^= v >> 4; + v &= 0xf; + return (0x6996 >> v) & 1; +} + +u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed); + +bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, + f32 camera_fov, f32 range, f32 *distance_ptr=NULL); + +s16 adjustDist(s16 dist, float zoom_fov); + +/* + Returns nearest 32-bit integer for given floating point number. + <cmath> and <math.h> in VC++ don't provide round(). +*/ +inline s32 myround(f32 f) +{ + return (s32)(f < 0.f ? (f - 0.5f) : (f + 0.5f)); +} + +inline constexpr f32 sqr(f32 f) +{ + return f * f; +} + +/* + Returns integer position of node in given floating point position +*/ +inline v3s16 floatToInt(v3f p, f32 d) +{ + return v3s16( + (p.X + (p.X > 0 ? d / 2 : -d / 2)) / d, + (p.Y + (p.Y > 0 ? d / 2 : -d / 2)) / d, + (p.Z + (p.Z > 0 ? d / 2 : -d / 2)) / d); +} + +/* + Returns integer position of node in given double precision position + */ +inline v3s16 doubleToInt(v3d p, double d) +{ + return v3s16( + (p.X + (p.X > 0 ? d / 2 : -d / 2)) / d, + (p.Y + (p.Y > 0 ? d / 2 : -d / 2)) / d, + (p.Z + (p.Z > 0 ? d / 2 : -d / 2)) / d); +} + +/* + Returns floating point position of node in given integer position +*/ +inline v3f intToFloat(v3s16 p, f32 d) +{ + return v3f( + (f32)p.X * d, + (f32)p.Y * d, + (f32)p.Z * d + ); +} + +// Random helper. Usually d=BS +inline aabb3f getNodeBox(v3s16 p, float d) +{ + return aabb3f( + (float)p.X * d - 0.5f * d, + (float)p.Y * d - 0.5f * d, + (float)p.Z * d - 0.5f * d, + (float)p.X * d + 0.5f * d, + (float)p.Y * d + 0.5f * d, + (float)p.Z * d + 0.5f * d + ); +} + + +class IntervalLimiter +{ +public: + IntervalLimiter() = default; + + /* + dtime: time from last call to this method + wanted_interval: interval wanted + return value: + true: action should be skipped + false: action should be done + */ + bool step(float dtime, float wanted_interval) + { + m_accumulator += dtime; + if (m_accumulator < wanted_interval) + return false; + m_accumulator -= wanted_interval; + return true; + } + +private: + float m_accumulator = 0.0f; +}; + + +/* + Splits a list into "pages". For example, the list [1,2,3,4,5] split + into two pages would be [1,2,3],[4,5]. This function computes the + minimum and maximum indices of a single page. + + length: Length of the list that should be split + page: Page number, 1 <= page <= pagecount + pagecount: The number of pages, >= 1 + minindex: Receives the minimum index (inclusive). + maxindex: Receives the maximum index (exclusive). + + Ensures 0 <= minindex <= maxindex <= length. +*/ +inline void paging(u32 length, u32 page, u32 pagecount, u32 &minindex, u32 &maxindex) +{ + if (length < 1 || pagecount < 1 || page < 1 || page > pagecount) { + // Special cases or invalid parameters + minindex = maxindex = 0; + } else if(pagecount <= length) { + // Less pages than entries in the list: + // Each page contains at least one entry + minindex = (length * (page-1) + (pagecount-1)) / pagecount; + maxindex = (length * page + (pagecount-1)) / pagecount; + } else { + // More pages than entries in the list: + // Make sure the empty pages are at the end + if (page < length) { + minindex = page-1; + maxindex = page; + } else { + minindex = 0; + maxindex = 0; + } + } +} + +inline float cycle_shift(float value, float by = 0, float max = 1) +{ + if (value + by < 0) return value + by + max; + if (value + by > max) return value + by - max; + return value + by; +} + +inline bool is_power_of_two(u32 n) +{ + return n != 0 && (n & (n - 1)) == 0; +} + +// Compute next-higher power of 2 efficiently, e.g. for power-of-2 texture sizes. +// Public Domain: https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 +inline u32 npot2(u32 orig) { + orig--; + orig |= orig >> 1; + orig |= orig >> 2; + orig |= orig >> 4; + orig |= orig >> 8; + orig |= orig >> 16; + return orig + 1; +} + +// Gradual steps towards the target value in a wrapped (circular) system +// using the shorter of both ways +template<typename T> +inline void wrappedApproachShortest(T ¤t, const T target, const T stepsize, + const T maximum) +{ + T delta = target - current; + if (delta < 0) + delta += maximum; + + if (delta > stepsize && maximum - delta > stepsize) { + current += (delta < maximum / 2) ? stepsize : -stepsize; + if (current >= maximum) + current -= maximum; + } else { + current = target; + } +} + +void setPitchYawRollRad(core::matrix4 &m, const v3f &rot); + +inline void setPitchYawRoll(core::matrix4 &m, const v3f &rot) +{ + setPitchYawRollRad(m, rot * core::DEGTORAD64); +} + +v3f getPitchYawRollRad(const core::matrix4 &m); + +inline v3f getPitchYawRoll(const core::matrix4 &m) +{ + return getPitchYawRollRad(m) * core::RADTODEG64; +} + +// Muliply the RGB value of a color linearly, and clamp to black/white +inline irr::video::SColor multiplyColorValue(const irr::video::SColor &color, float mod) +{ + return irr::video::SColor(color.getAlpha(), + core::clamp<u32>(color.getRed() * mod, 0, 255), + core::clamp<u32>(color.getGreen() * mod, 0, 255), + core::clamp<u32>(color.getBlue() * mod, 0, 255)); +} + +template <typename T> inline T numericAbsolute(T v) { return v < 0 ? T(-v) : v; } +template <typename T> inline T numericSign(T v) { return T(v < 0 ? -1 : (v == 0 ? 0 : 1)); } + +inline v3f vecAbsolute(v3f v) +{ + return v3f( + numericAbsolute(v.X), + numericAbsolute(v.Y), + numericAbsolute(v.Z) + ); +} + +inline v3f vecSign(v3f v) +{ + return v3f( + numericSign(v.X), + numericSign(v.Y), + numericSign(v.Z) + ); +} diff --git a/src/util/png.cpp b/src/util/png.cpp new file mode 100644 index 0000000..698cbc9 --- /dev/null +++ b/src/util/png.cpp @@ -0,0 +1,68 @@ +/* +Minetest +Copyright (C) 2021 hecks + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "png.h" +#include <string> +#include <sstream> +#include <zlib.h> +#include <cassert> +#include "util/serialize.h" +#include "serialization.h" +#include "irrlichttypes.h" + +static void writeChunk(std::ostringstream &target, const std::string &chunk_str) +{ + assert(chunk_str.size() >= 4); + assert(chunk_str.size() - 4 < U32_MAX); + writeU32(target, chunk_str.size() - 4); // Write length minus the identifier + target << chunk_str; + writeU32(target, crc32(0,(const u8*)chunk_str.data(), chunk_str.size())); +} + +std::string encodePNG(const u8 *data, u32 width, u32 height, s32 compression) +{ + std::ostringstream file(std::ios::binary); + file << "\x89PNG\r\n\x1a\n"; + + { + std::ostringstream IHDR(std::ios::binary); + IHDR << "IHDR"; + writeU32(IHDR, width); + writeU32(IHDR, height); + // 8 bpp, color type 6 (RGBA) + IHDR.write("\x08\x06\x00\x00\x00", 5); + writeChunk(file, IHDR.str()); + } + + { + std::ostringstream IDAT(std::ios::binary); + IDAT << "IDAT"; + std::ostringstream scanlines(std::ios::binary); + for(u32 i = 0; i < height; i++) { + scanlines.write("\x00", 1); // Null predictor + scanlines.write((const char*) data + width * 4 * i, width * 4); + } + compressZlib(scanlines.str(), IDAT, compression); + writeChunk(file, IDAT.str()); + } + + file.write("\x00\x00\x00\x00IEND\xae\x42\x60\x82", 12); + + return file.str(); +} diff --git a/src/util/png.h b/src/util/png.h new file mode 100644 index 0000000..92387ae --- /dev/null +++ b/src/util/png.h @@ -0,0 +1,27 @@ +/* +Minetest +Copyright (C) 2021 hecks + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> +#include "irrlichttypes.h" + +/* Simple PNG encoder. Encodes an RGBA image with no predictors. + Returns a binary string. */ +std::string encodePNG(const u8 *data, u32 width, u32 height, s32 compression); diff --git a/src/util/pointedthing.cpp b/src/util/pointedthing.cpp new file mode 100644 index 0000000..b906264 --- /dev/null +++ b/src/util/pointedthing.cpp @@ -0,0 +1,134 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "pointedthing.h" + +#include "serialize.h" +#include "exceptions.h" +#include <sstream> + +PointedThing::PointedThing(const v3s16 &under, const v3s16 &above, + const v3s16 &real_under, const v3f &point, const v3s16 &normal, + u16 box_id, f32 distSq): + type(POINTEDTHING_NODE), + node_undersurface(under), + node_abovesurface(above), + node_real_undersurface(real_under), + intersection_point(point), + intersection_normal(normal), + box_id(box_id), + distanceSq(distSq) +{} + +PointedThing::PointedThing(s16 id, const v3f &point, const v3s16 &normal, + f32 distSq) : + type(POINTEDTHING_OBJECT), + object_id(id), + intersection_point(point), + intersection_normal(normal), + distanceSq(distSq) +{} + +std::string PointedThing::dump() const +{ + std::ostringstream os(std::ios::binary); + switch (type) { + case POINTEDTHING_NOTHING: + os << "[nothing]"; + break; + case POINTEDTHING_NODE: + { + const v3s16 &u = node_undersurface; + const v3s16 &a = node_abovesurface; + os << "[node under=" << u.X << "," << u.Y << "," << u.Z << " above=" + << a.X << "," << a.Y << "," << a.Z << "]"; + } + break; + case POINTEDTHING_OBJECT: + os << "[object " << object_id << "]"; + break; + default: + os << "[unknown PointedThing]"; + } + return os.str(); +} + +void PointedThing::serialize(std::ostream &os) const +{ + writeU8(os, 0); // version + writeU8(os, (u8)type); + switch (type) { + case POINTEDTHING_NOTHING: + break; + case POINTEDTHING_NODE: + writeV3S16(os, node_undersurface); + writeV3S16(os, node_abovesurface); + break; + case POINTEDTHING_OBJECT: + writeS16(os, object_id); + break; + } +} + +void PointedThing::deSerialize(std::istream &is) +{ + int version = readU8(is); + if (version != 0) throw SerializationError( + "unsupported PointedThing version"); + type = (PointedThingType) readU8(is); + switch (type) { + case POINTEDTHING_NOTHING: + break; + case POINTEDTHING_NODE: + node_undersurface = readV3S16(is); + node_abovesurface = readV3S16(is); + break; + case POINTEDTHING_OBJECT: + object_id = readS16(is); + break; + default: + throw SerializationError("unsupported PointedThingType"); + } +} + +bool PointedThing::operator==(const PointedThing &pt2) const +{ + if (type != pt2.type) + { + return false; + } + if (type == POINTEDTHING_NODE) + { + if ((node_undersurface != pt2.node_undersurface) + || (node_abovesurface != pt2.node_abovesurface) + || (node_real_undersurface != pt2.node_real_undersurface)) + return false; + } + else if (type == POINTEDTHING_OBJECT) + { + if (object_id != pt2.object_id) + return false; + } + return true; +} + +bool PointedThing::operator!=(const PointedThing &pt2) const +{ + return !(*this == pt2); +} diff --git a/src/util/pointedthing.h b/src/util/pointedthing.h new file mode 100644 index 0000000..5b30ed0 --- /dev/null +++ b/src/util/pointedthing.h @@ -0,0 +1,105 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "irr_v3d.h" +#include <iostream> +#include <string> + +enum PointedThingType +{ + POINTEDTHING_NOTHING, + POINTEDTHING_NODE, + POINTEDTHING_OBJECT +}; + +//! An active object or node which is selected by a ray on the map. +struct PointedThing +{ + //! The type of the pointed object. + PointedThingType type = POINTEDTHING_NOTHING; + /*! + * Only valid if type is POINTEDTHING_NODE. + * The coordinates of the node which owns the + * nodebox that the ray hits first. + * This may differ from node_real_undersurface if + * a nodebox exceeds the limits of its node. + */ + v3s16 node_undersurface; + /*! + * Only valid if type is POINTEDTHING_NODE. + * The coordinates of the last node the ray intersects + * before node_undersurface. Same as node_undersurface + * if the ray starts in a nodebox. + */ + v3s16 node_abovesurface; + /*! + * Only valid if type is POINTEDTHING_NODE. + * The coordinates of the node which contains the + * point of the collision and the nodebox of the node. + */ + v3s16 node_real_undersurface; + /*! + * Only valid if type is POINTEDTHING_OBJECT. + * The ID of the object the ray hit. + */ + s16 object_id = -1; + /*! + * Only valid if type isn't POINTEDTHING_NONE. + * First intersection point of the ray and the nodebox in irrlicht + * coordinates. + */ + v3f intersection_point; + /*! + * Only valid if type isn't POINTEDTHING_NONE. + * Normal vector of the intersection. + * This is perpendicular to the face the ray hits, + * points outside of the box and it's length is 1. + */ + v3s16 intersection_normal; + /*! + * Only valid if type isn't POINTEDTHING_NONE. + * Indicates which selection box is selected, if there are more of them. + */ + u16 box_id = 0; + /*! + * Square of the distance between the pointing + * ray's start point and the intersection point in irrlicht coordinates. + */ + f32 distanceSq = 0; + + //! Constructor for POINTEDTHING_NOTHING + PointedThing() = default; + //! Constructor for POINTEDTHING_NODE + PointedThing(const v3s16 &under, const v3s16 &above, + const v3s16 &real_under, const v3f &point, const v3s16 &normal, + u16 box_id, f32 distSq); + //! Constructor for POINTEDTHING_OBJECT + PointedThing(s16 id, const v3f &point, const v3s16 &normal, f32 distSq); + std::string dump() const; + void serialize(std::ostream &os) const; + void deSerialize(std::istream &is); + /*! + * This function ignores the intersection point and normal. + */ + bool operator==(const PointedThing &pt2) const; + bool operator!=(const PointedThing &pt2) const; +}; diff --git a/src/util/pointer.h b/src/util/pointer.h new file mode 100644 index 0000000..f4b70f8 --- /dev/null +++ b/src/util/pointer.h @@ -0,0 +1,273 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "debug.h" // For assert() +#include <cstring> +#include <memory> // std::shared_ptr + + +template<typename T> class ConstSharedPtr { +public: + ConstSharedPtr(T *ptr) : ptr(ptr) {} + ConstSharedPtr(const std::shared_ptr<T> &ptr) : ptr(ptr) {} + + const T* get() const noexcept { return ptr.get(); } + const T& operator*() const noexcept { return *ptr.get(); } + const T* operator->() const noexcept { return ptr.get(); } + +private: + std::shared_ptr<T> ptr; +}; + +template <typename T> +class Buffer +{ +public: + Buffer() + { + m_size = 0; + data = nullptr; + } + Buffer(unsigned int size) + { + m_size = size; + if(size != 0) + data = new T[size]; + else + data = nullptr; + } + + // Disable class copy + Buffer(const Buffer &) = delete; + Buffer &operator=(const Buffer &) = delete; + + Buffer(Buffer &&buffer) + { + m_size = buffer.m_size; + if(m_size != 0) + { + data = buffer.data; + buffer.data = nullptr; + buffer.m_size = 0; + } + else + data = nullptr; + } + // Copies whole buffer + Buffer(const T *t, unsigned int size) + { + m_size = size; + if(size != 0) + { + data = new T[size]; + memcpy(data, t, size); + } + else + data = nullptr; + } + + ~Buffer() + { + drop(); + } + + Buffer& operator=(Buffer &&buffer) + { + if(this == &buffer) + return *this; + drop(); + m_size = buffer.m_size; + if(m_size != 0) + { + data = buffer.data; + buffer.data = nullptr; + buffer.m_size = 0; + } + else + data = nullptr; + return *this; + } + + void copyTo(Buffer &buffer) const + { + buffer.drop(); + buffer.m_size = m_size; + if (m_size != 0) { + buffer.data = new T[m_size]; + memcpy(buffer.data, data, m_size); + } else { + buffer.data = nullptr; + } + } + + T & operator[](unsigned int i) const + { + return data[i]; + } + T * operator*() const + { + return data; + } + + unsigned int getSize() const + { + return m_size; + } + +private: + void drop() + { + delete[] data; + } + T *data; + unsigned int m_size; +}; + +/************************************************ + * !!! W A R N I N G !!! * + * * + * This smart pointer class is NOT thread safe. * + * ONLY use in a single-threaded context! * + * * + ************************************************/ +template <typename T> +class SharedBuffer +{ +public: + SharedBuffer() + { + m_size = 0; + data = NULL; + refcount = new unsigned int; + (*refcount) = 1; + } + SharedBuffer(unsigned int size) + { + m_size = size; + if(m_size != 0) + data = new T[m_size]; + else + data = nullptr; + refcount = new unsigned int; + memset(data,0,sizeof(T)*m_size); + (*refcount) = 1; + } + SharedBuffer(const SharedBuffer &buffer) + { + m_size = buffer.m_size; + data = buffer.data; + refcount = buffer.refcount; + (*refcount)++; + } + SharedBuffer & operator=(const SharedBuffer & buffer) + { + if(this == &buffer) + return *this; + drop(); + m_size = buffer.m_size; + data = buffer.data; + refcount = buffer.refcount; + (*refcount)++; + return *this; + } + /* + Copies whole buffer + */ + SharedBuffer(const T *t, unsigned int size) + { + m_size = size; + if(m_size != 0) + { + data = new T[m_size]; + memcpy(data, t, m_size); + } + else + data = nullptr; + refcount = new unsigned int; + (*refcount) = 1; + } + /* + Copies whole buffer + */ + SharedBuffer(const Buffer<T> &buffer) + { + m_size = buffer.getSize(); + if (m_size != 0) { + data = new T[m_size]; + memcpy(data, *buffer, buffer.getSize()); + } + else + data = nullptr; + refcount = new unsigned int; + (*refcount) = 1; + } + ~SharedBuffer() + { + drop(); + } + T & operator[](unsigned int i) const + { + assert(i < m_size); + return data[i]; + } + T * operator*() const + { + return data; + } + unsigned int getSize() const + { + return m_size; + } + operator Buffer<T>() const + { + return Buffer<T>(data, m_size); + } +private: + void drop() + { + assert((*refcount) > 0); + (*refcount)--; + if(*refcount == 0) + { + delete[] data; + delete refcount; + } + } + T *data; + unsigned int m_size; + unsigned int *refcount; +}; + +// This class is not thread-safe! +class IntrusiveReferenceCounted { +public: + IntrusiveReferenceCounted() = default; + virtual ~IntrusiveReferenceCounted() = default; + void grab() noexcept { ++m_refcount; } + void drop() noexcept { if (--m_refcount == 0) delete this; } + + // Preserve own reference count. + IntrusiveReferenceCounted(const IntrusiveReferenceCounted &) {} + IntrusiveReferenceCounted &operator=(const IntrusiveReferenceCounted &) { return *this; } +private: + u32 m_refcount = 1; +}; diff --git a/src/util/quicktune.cpp b/src/util/quicktune.cpp new file mode 100644 index 0000000..37d4933 --- /dev/null +++ b/src/util/quicktune.cpp @@ -0,0 +1,104 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "quicktune.h" +#include "threading/mutex_auto_lock.h" +#include "util/string.h" + +std::string QuicktuneValue::getString() +{ + switch(type){ + case QVT_NONE: + return "(none)"; + case QVT_FLOAT: + return ftos(value_QVT_FLOAT.current); + } + return "<invalid type>"; +} +void QuicktuneValue::relativeAdd(float amount) +{ + switch(type){ + case QVT_NONE: + break; + case QVT_FLOAT: + value_QVT_FLOAT.current += amount * (value_QVT_FLOAT.max - value_QVT_FLOAT.min); + if(value_QVT_FLOAT.current > value_QVT_FLOAT.max) + value_QVT_FLOAT.current = value_QVT_FLOAT.max; + if(value_QVT_FLOAT.current < value_QVT_FLOAT.min) + value_QVT_FLOAT.current = value_QVT_FLOAT.min; + break; + } +} + +static std::map<std::string, QuicktuneValue> g_values; +static std::vector<std::string> g_names; +std::mutex *g_mutex = NULL; + +static void makeMutex() +{ + if(!g_mutex){ + g_mutex = new std::mutex(); + } +} + +std::vector<std::string> getQuicktuneNames() +{ + return g_names; +} + +QuicktuneValue getQuicktuneValue(const std::string &name) +{ + makeMutex(); + MutexAutoLock lock(*g_mutex); + std::map<std::string, QuicktuneValue>::iterator i = g_values.find(name); + if(i == g_values.end()){ + QuicktuneValue val; + val.type = QVT_NONE; + return val; + } + return i->second; +} + +void setQuicktuneValue(const std::string &name, const QuicktuneValue &val) +{ + makeMutex(); + MutexAutoLock lock(*g_mutex); + g_values[name] = val; + g_values[name].modified = true; +} + +void updateQuicktuneValue(const std::string &name, QuicktuneValue &val) +{ + makeMutex(); + MutexAutoLock lock(*g_mutex); + std::map<std::string, QuicktuneValue>::iterator i = g_values.find(name); + if(i == g_values.end()){ + g_values[name] = val; + g_names.push_back(name); + return; + } + QuicktuneValue &ref = i->second; + if(ref.modified) + val = ref; + else{ + ref = val; + ref.modified = false; + } +} + diff --git a/src/util/quicktune.h b/src/util/quicktune.h new file mode 100644 index 0000000..1943d19 --- /dev/null +++ b/src/util/quicktune.h @@ -0,0 +1,98 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/* + Used for tuning constants when developing. + + Eg. if you have this constant somewhere that you just can't get right + by changing it and recompiling all over again: + v3f wield_position = v3f(55, -35, 65); + + Make it look like this: + v3f wield_position = v3f(55, -35, 65); + QUICKTUNE_AUTONAME(QVT_FLOAT, wield_position.X, 0, 100); + QUICKTUNE_AUTONAME(QVT_FLOAT, wield_position.Y, -80, 20); + QUICKTUNE_AUTONAME(QVT_FLOAT, wield_position.Z, 0, 100); + + Then you can modify the values at runtime, using the keys + keymap_quicktune_prev + keymap_quicktune_next + keymap_quicktune_dec + keymap_quicktune_inc + + Once you have modified the values at runtime and then quit, the game + will print out all the modified values at the end: + Modified quicktune values: + wield_position.X = 60 + wield_position.Y = -30 + wield_position.Z = 65 + + The QUICKTUNE macros shouldn't generally be left in committed code. +*/ + +#pragma once + +#include <string> +#include <map> +#include <vector> + +enum QuicktuneValueType{ + QVT_NONE, + QVT_FLOAT +}; +struct QuicktuneValue +{ + QuicktuneValueType type = QVT_NONE; + union{ + struct{ + float current; + float min; + float max; + } value_QVT_FLOAT; + }; + bool modified = false; + + QuicktuneValue() = default; + + std::string getString(); + void relativeAdd(float amount); +}; + +std::vector<std::string> getQuicktuneNames(); +QuicktuneValue getQuicktuneValue(const std::string &name); +void setQuicktuneValue(const std::string &name, const QuicktuneValue &val); + +void updateQuicktuneValue(const std::string &name, QuicktuneValue &val); + +#ifndef NDEBUG + #define QUICKTUNE(type_, var, min_, max_, name){\ + QuicktuneValue qv;\ + qv.type = type_;\ + qv.value_##type_.current = var;\ + qv.value_##type_.min = min_;\ + qv.value_##type_.max = max_;\ + updateQuicktuneValue(name, qv);\ + var = qv.value_##type_.current;\ + } +#else // NDEBUG + #define QUICKTUNE(type, var, min_, max_, name){} +#endif + +#define QUICKTUNE_AUTONAME(type_, var, min_, max_)\ + QUICKTUNE(type_, var, min_, max_, #var) diff --git a/src/util/quicktune_shortcutter.h b/src/util/quicktune_shortcutter.h new file mode 100644 index 0000000..70a7b70 --- /dev/null +++ b/src/util/quicktune_shortcutter.h @@ -0,0 +1,84 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "quicktune.h" + +class QuicktuneShortcutter +{ +private: + std::vector<std::string> m_names; + u32 m_selected_i; + std::string m_message; +public: + bool hasMessage() const + { + return !m_message.empty(); + } + + std::string getMessage() + { + std::string s = m_message; + m_message = ""; + if (!s.empty()) + return std::string("[quicktune] ") + s; + return ""; + } + std::string getSelectedName() + { + if(m_selected_i < m_names.size()) + return m_names[m_selected_i]; + return "(nothing)"; + } + void next() + { + m_names = getQuicktuneNames(); + if(m_selected_i < m_names.size()-1) + m_selected_i++; + else + m_selected_i = 0; + m_message = std::string("Selected \"")+getSelectedName()+"\""; + } + void prev() + { + m_names = getQuicktuneNames(); + if(m_selected_i > 0) + m_selected_i--; + else + m_selected_i = m_names.size()-1; + m_message = std::string("Selected \"")+getSelectedName()+"\""; + } + void inc() + { + QuicktuneValue val = getQuicktuneValue(getSelectedName()); + val.relativeAdd(0.05); + m_message = std::string("\"")+getSelectedName() + +"\" = "+val.getString(); + setQuicktuneValue(getSelectedName(), val); + } + void dec() + { + QuicktuneValue val = getQuicktuneValue(getSelectedName()); + val.relativeAdd(-0.05); + m_message = std::string("\"")+getSelectedName() + +"\" = "+val.getString(); + setQuicktuneValue(getSelectedName(), val); + } +}; diff --git a/src/util/serialize.cpp b/src/util/serialize.cpp new file mode 100644 index 0000000..ee46fd9 --- /dev/null +++ b/src/util/serialize.cpp @@ -0,0 +1,294 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "serialize.h" +#include "porting.h" +#include "util/string.h" +#include "util/hex.h" +#include "exceptions.h" +#include "irrlichttypes.h" + +#include <iostream> +#include <cassert> + +FloatType g_serialize_f32_type = FLOATTYPE_UNKNOWN; + + +//// +//// String +//// + +std::string serializeString16(const std::string &plain) +{ + std::string s; + char buf[2]; + + if (plain.size() > STRING_MAX_LEN) + throw SerializationError("String too long for serializeString16"); + s.reserve(2 + plain.size()); + + writeU16((u8 *)&buf[0], plain.size()); + s.append(buf, 2); + + s.append(plain); + return s; +} + +std::string deSerializeString16(std::istream &is) +{ + std::string s; + char buf[2]; + + is.read(buf, 2); + if (is.gcount() != 2) + throw SerializationError("deSerializeString16: size not read"); + + u16 s_size = readU16((u8 *)buf); + if (s_size == 0) + return s; + + s.resize(s_size); + is.read(&s[0], s_size); + if (is.gcount() != s_size) + throw SerializationError("deSerializeString16: couldn't read all chars"); + + return s; +} + + +//// +//// Long String +//// + +std::string serializeString32(const std::string &plain) +{ + std::string s; + char buf[4]; + + if (plain.size() > LONG_STRING_MAX_LEN) + throw SerializationError("String too long for serializeLongString"); + s.reserve(4 + plain.size()); + + writeU32((u8*)&buf[0], plain.size()); + s.append(buf, 4); + s.append(plain); + return s; +} + +std::string deSerializeString32(std::istream &is) +{ + std::string s; + char buf[4]; + + is.read(buf, 4); + if (is.gcount() != 4) + throw SerializationError("deSerializeLongString: size not read"); + + u32 s_size = readU32((u8 *)buf); + if (s_size == 0) + return s; + + // We don't really want a remote attacker to force us to allocate 4GB... + if (s_size > LONG_STRING_MAX_LEN) { + throw SerializationError("deSerializeLongString: " + "string too long: " + itos(s_size) + " bytes"); + } + + s.resize(s_size); + is.read(&s[0], s_size); + if ((u32)is.gcount() != s_size) + throw SerializationError("deSerializeLongString: couldn't read all chars"); + + return s; +} + +//// +//// JSON-like strings +//// + +std::string serializeJsonString(const std::string &plain) +{ + std::string tmp; + + tmp.reserve(plain.size() + 2); + tmp.push_back('"'); + + for (char c : plain) { + switch (c) { + case '"': + tmp.append("\\\""); + break; + case '\\': + tmp.append("\\\\"); + break; + case '\b': + tmp.append("\\b"); + break; + case '\f': + tmp.append("\\f"); + break; + case '\n': + tmp.append("\\n"); + break; + case '\r': + tmp.append("\\r"); + break; + case '\t': + tmp.append("\\t"); + break; + default: { + if (c >= 32 && c <= 126) { + tmp.push_back(c); + } else { + // We pretend that Unicode codepoints map to bytes (they don't) + u8 cnum = static_cast<u8>(c); + tmp.append("\\u00"); + tmp.push_back(hex_chars[cnum >> 4]); + tmp.push_back(hex_chars[cnum & 0xf]); + } + break; + } + } + } + + tmp.push_back('"'); + return tmp; +} + +static void deSerializeJsonString(std::string &s) +{ + assert(s.size() >= 2); + assert(s.front() == '"' && s.back() == '"'); + + size_t w = 0; // write index + size_t i = 1; // read index + const size_t len = s.size() - 1; // string length with trailing quote removed + + while (i < len) { + char c = s[i++]; + assert(c != '"'); + + if (c != '\\') { + s[w++] = c; + continue; + } + + if (i >= len) + throw SerializationError("JSON string ended prematurely"); + char c2 = s[i++]; + switch (c2) { + case 'b': + s[w++] = '\b'; + break; + case 'f': + s[w++] = '\f'; + break; + case 'n': + s[w++] = '\n'; + break; + case 'r': + s[w++] = '\r'; + break; + case 't': + s[w++] = '\t'; + break; + case 'u': { + if (i + 3 >= len) + throw SerializationError("JSON string ended prematurely"); + unsigned char v[4] = {}; + for (int j = 0; j < 4; j++) + hex_digit_decode(s[i+j], v[j]); + i += 4; + u32 hexnumber = (v[0] << 12) | (v[1] << 8) | (v[2] << 4) | v[3]; + // Note that this does not work for anything other than ASCII + // but these functions do not actually interact with real JSON input. + s[w++] = (int) hexnumber; + break; + } + default: + s[w++] = c2; + break; + } + } + + assert(w <= i && i <= len); + // Truncate string to current write index + s.resize(w); +} + +std::string deSerializeJsonString(std::istream &is) +{ + std::string tmp; + char c; + bool was_backslash = false; + + // Parse initial doublequote + c = is.get(); + if (c != '"') + throw SerializationError("JSON string must start with doublequote"); + tmp.push_back(c); + + // Grab the entire json string + for (;;) { + c = is.get(); + if (is.eof()) + throw SerializationError("JSON string ended prematurely"); + + tmp.push_back(c); + if (was_backslash) + was_backslash = false; + else if (c == '\\') + was_backslash = true; + else if (c == '"') + break; // found end of string + } + + deSerializeJsonString(tmp); + return tmp; +} + +std::string serializeJsonStringIfNeeded(const std::string &s) +{ + for (size_t i = 0; i < s.size(); ++i) { + if (s[i] <= 0x1f || s[i] >= 0x7f || s[i] == ' ' || s[i] == '\"') + return serializeJsonString(s); + } + return s; +} + +std::string deSerializeJsonStringIfNeeded(std::istream &is) +{ + // Check for initial quote + char c = is.peek(); + if (is.eof()) + return ""; + + if (c == '"') { + // json string: defer to the right implementation + return deSerializeJsonString(is); + } + + // not a json string: + std::string tmp; + std::getline(is, tmp, ' '); + if (!is.eof()) + is.unget(); // we hit a space, put it back + return tmp; +} + diff --git a/src/util/serialize.h b/src/util/serialize.h new file mode 100644 index 0000000..4dc1a54 --- /dev/null +++ b/src/util/serialize.h @@ -0,0 +1,475 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +#include "exceptions.h" // for SerializationError +#include "debug.h" // for assert +#include "ieee_float.h" + +#include "config.h" +#if HAVE_ENDIAN_H + #ifdef _WIN32 + #define __BYTE_ORDER 0 + #define __LITTLE_ENDIAN 0 + #define __BIG_ENDIAN 1 + #elif defined(__MACH__) && defined(__APPLE__) + #include <machine/endian.h> + #elif defined(__FreeBSD__) || defined(__DragonFly__) + #include <sys/endian.h> + #else + #include <endian.h> + #endif +#endif +#include <cstring> // for memcpy +#include <iostream> +#include <string> +#include <vector> + +#define FIXEDPOINT_FACTOR 1000.0f + +// 0x7FFFFFFF / 1000.0f is not serializable. +// The limited float precision at this magnitude may cause the result to round +// to a greater value than can be represented by a 32 bit integer when increased +// by a factor of FIXEDPOINT_FACTOR. As a result, [F1000_MIN..F1000_MAX] does +// not represent the full range, but rather the largest safe range, of values on +// all supported architectures. Note: This definition makes assumptions on +// platform float-to-int conversion behavior. +#define F1000_MIN ((float)(s32)((float)(-0x7FFFFFFF - 1) / FIXEDPOINT_FACTOR)) +#define F1000_MAX ((float)(s32)((float)(0x7FFFFFFF) / FIXEDPOINT_FACTOR)) + +#define STRING_MAX_LEN 0xFFFF +#define WIDE_STRING_MAX_LEN 0xFFFF +// 64 MB ought to be enough for anybody - Billy G. +#define LONG_STRING_MAX_LEN (64 * 1024 * 1024) + + +extern FloatType g_serialize_f32_type; + +#if HAVE_ENDIAN_H +// use machine native byte swapping routines +// Note: memcpy below is optimized out by modern compilers + +inline u16 readU16(const u8 *data) +{ + u16 val; + memcpy(&val, data, 2); + return be16toh(val); +} + +inline u32 readU32(const u8 *data) +{ + u32 val; + memcpy(&val, data, 4); + return be32toh(val); +} + +inline u64 readU64(const u8 *data) +{ + u64 val; + memcpy(&val, data, 8); + return be64toh(val); +} + +inline void writeU16(u8 *data, u16 i) +{ + u16 val = htobe16(i); + memcpy(data, &val, 2); +} + +inline void writeU32(u8 *data, u32 i) +{ + u32 val = htobe32(i); + memcpy(data, &val, 4); +} + +inline void writeU64(u8 *data, u64 i) +{ + u64 val = htobe64(i); + memcpy(data, &val, 8); +} + +#else +// generic byte-swapping implementation + +inline u16 readU16(const u8 *data) +{ + return + ((u16)data[0] << 8) | ((u16)data[1] << 0); +} + +inline u32 readU32(const u8 *data) +{ + return + ((u32)data[0] << 24) | ((u32)data[1] << 16) | + ((u32)data[2] << 8) | ((u32)data[3] << 0); +} + +inline u64 readU64(const u8 *data) +{ + return + ((u64)data[0] << 56) | ((u64)data[1] << 48) | + ((u64)data[2] << 40) | ((u64)data[3] << 32) | + ((u64)data[4] << 24) | ((u64)data[5] << 16) | + ((u64)data[6] << 8) | ((u64)data[7] << 0); +} + +inline void writeU16(u8 *data, u16 i) +{ + data[0] = (i >> 8) & 0xFF; + data[1] = (i >> 0) & 0xFF; +} + +inline void writeU32(u8 *data, u32 i) +{ + data[0] = (i >> 24) & 0xFF; + data[1] = (i >> 16) & 0xFF; + data[2] = (i >> 8) & 0xFF; + data[3] = (i >> 0) & 0xFF; +} + +inline void writeU64(u8 *data, u64 i) +{ + data[0] = (i >> 56) & 0xFF; + data[1] = (i >> 48) & 0xFF; + data[2] = (i >> 40) & 0xFF; + data[3] = (i >> 32) & 0xFF; + data[4] = (i >> 24) & 0xFF; + data[5] = (i >> 16) & 0xFF; + data[6] = (i >> 8) & 0xFF; + data[7] = (i >> 0) & 0xFF; +} + +#endif // HAVE_ENDIAN_H + +//////////////// read routines //////////////// + +inline u8 readU8(const u8 *data) +{ + return ((u8)data[0] << 0); +} + +inline s8 readS8(const u8 *data) +{ + return (s8)readU8(data); +} + +inline s16 readS16(const u8 *data) +{ + return (s16)readU16(data); +} + +inline s32 readS32(const u8 *data) +{ + return (s32)readU32(data); +} + +inline s64 readS64(const u8 *data) +{ + return (s64)readU64(data); +} + +inline f32 readF1000(const u8 *data) +{ + return (f32)readS32(data) / FIXEDPOINT_FACTOR; +} + +inline f32 readF32(const u8 *data) +{ + u32 u = readU32(data); + + switch (g_serialize_f32_type) { + case FLOATTYPE_SYSTEM: { + f32 f; + memcpy(&f, &u, 4); + return f; + } + case FLOATTYPE_SLOW: + return u32Tof32Slow(u); + case FLOATTYPE_UNKNOWN: // First initialization + g_serialize_f32_type = getFloatSerializationType(); + return readF32(data); + } + throw SerializationError("readF32: Unreachable code"); +} + +inline video::SColor readARGB8(const u8 *data) +{ + video::SColor p(readU32(data)); + return p; +} + +inline v2s16 readV2S16(const u8 *data) +{ + v2s16 p; + p.X = readS16(&data[0]); + p.Y = readS16(&data[2]); + return p; +} + +inline v3s16 readV3S16(const u8 *data) +{ + v3s16 p; + p.X = readS16(&data[0]); + p.Y = readS16(&data[2]); + p.Z = readS16(&data[4]); + return p; +} + +inline v2s32 readV2S32(const u8 *data) +{ + v2s32 p; + p.X = readS32(&data[0]); + p.Y = readS32(&data[4]); + return p; +} + +inline v3s32 readV3S32(const u8 *data) +{ + v3s32 p; + p.X = readS32(&data[0]); + p.Y = readS32(&data[4]); + p.Z = readS32(&data[8]); + return p; +} + +inline v3f readV3F1000(const u8 *data) +{ + v3f p; + p.X = readF1000(&data[0]); + p.Y = readF1000(&data[4]); + p.Z = readF1000(&data[8]); + return p; +} + +inline v2f readV2F32(const u8 *data) +{ + v2f p; + p.X = readF32(&data[0]); + p.Y = readF32(&data[4]); + return p; +} + +inline v3f readV3F32(const u8 *data) +{ + v3f p; + p.X = readF32(&data[0]); + p.Y = readF32(&data[4]); + p.Z = readF32(&data[8]); + return p; +} + +/////////////// write routines //////////////// + +inline void writeU8(u8 *data, u8 i) +{ + data[0] = (i >> 0) & 0xFF; +} + +inline void writeS8(u8 *data, s8 i) +{ + writeU8(data, (u8)i); +} + +inline void writeS16(u8 *data, s16 i) +{ + writeU16(data, (u16)i); +} + +inline void writeS32(u8 *data, s32 i) +{ + writeU32(data, (u32)i); +} + +inline void writeS64(u8 *data, s64 i) +{ + writeU64(data, (u64)i); +} + +inline void writeF1000(u8 *data, f32 i) +{ + assert(i >= F1000_MIN && i <= F1000_MAX); + writeS32(data, i * FIXEDPOINT_FACTOR); +} + +inline void writeF32(u8 *data, f32 i) +{ + switch (g_serialize_f32_type) { + case FLOATTYPE_SYSTEM: { + u32 u; + memcpy(&u, &i, 4); + return writeU32(data, u); + } + case FLOATTYPE_SLOW: + return writeU32(data, f32Tou32Slow(i)); + case FLOATTYPE_UNKNOWN: // First initialization + g_serialize_f32_type = getFloatSerializationType(); + return writeF32(data, i); + } + throw SerializationError("writeF32: Unreachable code"); +} + +inline void writeARGB8(u8 *data, video::SColor p) +{ + writeU32(data, p.color); +} + +inline void writeV2S16(u8 *data, v2s16 p) +{ + writeS16(&data[0], p.X); + writeS16(&data[2], p.Y); +} + +inline void writeV3S16(u8 *data, v3s16 p) +{ + writeS16(&data[0], p.X); + writeS16(&data[2], p.Y); + writeS16(&data[4], p.Z); +} + +inline void writeV2S32(u8 *data, v2s32 p) +{ + writeS32(&data[0], p.X); + writeS32(&data[4], p.Y); +} + +inline void writeV3S32(u8 *data, v3s32 p) +{ + writeS32(&data[0], p.X); + writeS32(&data[4], p.Y); + writeS32(&data[8], p.Z); +} + +inline void writeV3F1000(u8 *data, v3f p) +{ + writeF1000(&data[0], p.X); + writeF1000(&data[4], p.Y); + writeF1000(&data[8], p.Z); +} + +inline void writeV2F32(u8 *data, v2f p) +{ + writeF32(&data[0], p.X); + writeF32(&data[4], p.Y); +} + +inline void writeV3F32(u8 *data, v3f p) +{ + writeF32(&data[0], p.X); + writeF32(&data[4], p.Y); + writeF32(&data[8], p.Z); +} + +//// +//// Iostream wrapper for data read/write +//// + +#define MAKE_STREAM_READ_FXN(T, N, S) \ + inline T read ## N(std::istream &is) \ + { \ + char buf[S] = {0}; \ + is.read(buf, sizeof(buf)); \ + return read ## N((u8 *)buf); \ + } + +#define MAKE_STREAM_WRITE_FXN(T, N, S) \ + inline void write ## N(std::ostream &os, T val) \ + { \ + char buf[S]; \ + write ## N((u8 *)buf, val); \ + os.write(buf, sizeof(buf)); \ + } + +MAKE_STREAM_READ_FXN(u8, U8, 1); +MAKE_STREAM_READ_FXN(u16, U16, 2); +MAKE_STREAM_READ_FXN(u32, U32, 4); +MAKE_STREAM_READ_FXN(u64, U64, 8); +MAKE_STREAM_READ_FXN(s8, S8, 1); +MAKE_STREAM_READ_FXN(s16, S16, 2); +MAKE_STREAM_READ_FXN(s32, S32, 4); +MAKE_STREAM_READ_FXN(s64, S64, 8); +MAKE_STREAM_READ_FXN(f32, F1000, 4); +MAKE_STREAM_READ_FXN(f32, F32, 4); +MAKE_STREAM_READ_FXN(v2s16, V2S16, 4); +MAKE_STREAM_READ_FXN(v3s16, V3S16, 6); +MAKE_STREAM_READ_FXN(v2s32, V2S32, 8); +MAKE_STREAM_READ_FXN(v3s32, V3S32, 12); +MAKE_STREAM_READ_FXN(v3f, V3F1000, 12); +MAKE_STREAM_READ_FXN(v2f, V2F32, 8); +MAKE_STREAM_READ_FXN(v3f, V3F32, 12); +MAKE_STREAM_READ_FXN(video::SColor, ARGB8, 4); + +MAKE_STREAM_WRITE_FXN(u8, U8, 1); +MAKE_STREAM_WRITE_FXN(u16, U16, 2); +MAKE_STREAM_WRITE_FXN(u32, U32, 4); +MAKE_STREAM_WRITE_FXN(u64, U64, 8); +MAKE_STREAM_WRITE_FXN(s8, S8, 1); +MAKE_STREAM_WRITE_FXN(s16, S16, 2); +MAKE_STREAM_WRITE_FXN(s32, S32, 4); +MAKE_STREAM_WRITE_FXN(s64, S64, 8); +MAKE_STREAM_WRITE_FXN(f32, F1000, 4); +MAKE_STREAM_WRITE_FXN(f32, F32, 4); +MAKE_STREAM_WRITE_FXN(v2s16, V2S16, 4); +MAKE_STREAM_WRITE_FXN(v3s16, V3S16, 6); +MAKE_STREAM_WRITE_FXN(v2s32, V2S32, 8); +MAKE_STREAM_WRITE_FXN(v3s32, V3S32, 12); +MAKE_STREAM_WRITE_FXN(v3f, V3F1000, 12); +MAKE_STREAM_WRITE_FXN(v2f, V2F32, 8); +MAKE_STREAM_WRITE_FXN(v3f, V3F32, 12); +MAKE_STREAM_WRITE_FXN(video::SColor, ARGB8, 4); + +//// +//// More serialization stuff +//// + +inline float clampToF1000(float v) +{ + return core::clamp(v, F1000_MIN, F1000_MAX); +} + +inline v3f clampToF1000(v3f v) +{ + return {clampToF1000(v.X), clampToF1000(v.Y), clampToF1000(v.Z)}; +} + +// Creates a string with the length as the first two bytes +std::string serializeString16(const std::string &plain); + +// Reads a string with the length as the first two bytes +std::string deSerializeString16(std::istream &is); + +// Creates a string with the length as the first four bytes +std::string serializeString32(const std::string &plain); + +// Reads a string with the length as the first four bytes +std::string deSerializeString32(std::istream &is); + +// Creates a string encoded in JSON format (almost equivalent to a C string literal) +std::string serializeJsonString(const std::string &plain); + +// Reads a string encoded in JSON format +std::string deSerializeJsonString(std::istream &is); + +// If the string contains spaces, quotes or control characters, encodes as JSON. +// Else returns the string unmodified. +std::string serializeJsonStringIfNeeded(const std::string &s); + +// Parses a string serialized by serializeJsonStringIfNeeded. +std::string deSerializeJsonStringIfNeeded(std::istream &is); diff --git a/src/util/sha1.cpp b/src/util/sha1.cpp new file mode 100644 index 0000000..d61b262 --- /dev/null +++ b/src/util/sha1.cpp @@ -0,0 +1,198 @@ +/* sha1.cpp + +Copyright (c) 2005 Michael D. Leonhard + +http://tamale.net/ + +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. + +*/ + +#include <cstdio> +#include <cstring> +#include <cstdlib> +#include <cassert> + +#include "sha1.h" + +// print out memory in hexadecimal +void SHA1::hexPrinter( unsigned char* c, int l ) +{ + assert( c ); + assert( l > 0 ); + while( l > 0 ) + { + printf( " %02x", *c ); + l--; + c++; + } +} + +// circular left bit rotation. MSB wraps around to LSB +Uint32 SHA1::lrot( Uint32 x, int bits ) +{ + return (x<<bits) | (x>>(32 - bits)); +}; + +// Save a 32-bit unsigned integer to memory, in big-endian order +void SHA1::storeBigEndianUint32( unsigned char* byte, Uint32 num ) +{ + assert( byte ); + byte[0] = (unsigned char)(num>>24); + byte[1] = (unsigned char)(num>>16); + byte[2] = (unsigned char)(num>>8); + byte[3] = (unsigned char)num; +} + + +// Constructor ******************************************************* +SHA1::SHA1() +{ + // make sure that the data type is the right size + assert( sizeof( Uint32 ) * 5 == 20 ); +} + +// Destructor ******************************************************** +SHA1::~SHA1() +{ + // erase data + H0 = H1 = H2 = H3 = H4 = 0; + for( int c = 0; c < 64; c++ ) bytes[c] = 0; + unprocessedBytes = size = 0; +} + +// process *********************************************************** +void SHA1::process() +{ + assert( unprocessedBytes == 64 ); + //printf( "process: " ); hexPrinter( bytes, 64 ); printf( "\n" ); + int t; + Uint32 a, b, c, d, e, K, f, W[80]; + // starting values + a = H0; + b = H1; + c = H2; + d = H3; + e = H4; + // copy and expand the message block + for( t = 0; t < 16; t++ ) W[t] = (bytes[t*4] << 24) + +(bytes[t*4 + 1] << 16) + +(bytes[t*4 + 2] << 8) + + bytes[t*4 + 3]; + for(; t< 80; t++ ) W[t] = lrot( W[t-3]^W[t-8]^W[t-14]^W[t-16], 1 ); + + /* main loop */ + Uint32 temp; + for( t = 0; t < 80; t++ ) + { + if( t < 20 ) { + K = 0x5a827999; + f = (b & c) | ((b ^ 0xFFFFFFFF) & d);//TODO: try using ~ + } else if( t < 40 ) { + K = 0x6ed9eba1; + f = b ^ c ^ d; + } else if( t < 60 ) { + K = 0x8f1bbcdc; + f = (b & c) | (b & d) | (c & d); + } else { + K = 0xca62c1d6; + f = b ^ c ^ d; + } + temp = lrot(a,5) + f + e + W[t] + K; + e = d; + d = c; + c = lrot(b,30); + b = a; + a = temp; + //printf( "t=%d %08x %08x %08x %08x %08x\n",t,a,b,c,d,e ); + } + /* add variables */ + H0 += a; + H1 += b; + H2 += c; + H3 += d; + H4 += e; + //printf( "Current: %08x %08x %08x %08x %08x\n",H0,H1,H2,H3,H4 ); + /* all bytes have been processed */ + unprocessedBytes = 0; +} + +// addBytes ********************************************************** +void SHA1::addBytes( const char* data, int num ) +{ + assert( data ); + assert( num >= 0 ); + // add these bytes to the running total + size += num; + // repeat until all data is processed + while( num > 0 ) + { + // number of bytes required to complete block + int needed = 64 - unprocessedBytes; + assert( needed > 0 ); + // number of bytes to copy (use smaller of two) + int toCopy = (num < needed) ? num : needed; + // Copy the bytes + memcpy( bytes + unprocessedBytes, data, toCopy ); + // Bytes have been copied + num -= toCopy; + data += toCopy; + unprocessedBytes += toCopy; + + // there is a full block + if( unprocessedBytes == 64 ) process(); + } +} + +// digest ************************************************************ +unsigned char* SHA1::getDigest() +{ + // save the message size + Uint32 totalBitsL = size << 3; + Uint32 totalBitsH = size >> 29; + // add 0x80 to the message + addBytes( "\x80", 1 ); + + unsigned char footer[64] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + // block has no room for 8-byte filesize, so finish it + if( unprocessedBytes > 56 ) + addBytes( (char*)footer, 64 - unprocessedBytes); + assert( unprocessedBytes <= 56 ); + // how many zeros do we need + int neededZeros = 56 - unprocessedBytes; + // store file size (in bits) in big-endian format + storeBigEndianUint32( footer + neededZeros , totalBitsH ); + storeBigEndianUint32( footer + neededZeros + 4, totalBitsL ); + // finish the final block + addBytes( (char*)footer, neededZeros + 8 ); + // allocate memory for the digest bytes + unsigned char* digest = (unsigned char*)malloc( 20 ); + // copy the digest bytes + storeBigEndianUint32( digest, H0 ); + storeBigEndianUint32( digest + 4, H1 ); + storeBigEndianUint32( digest + 8, H2 ); + storeBigEndianUint32( digest + 12, H3 ); + storeBigEndianUint32( digest + 16, H4 ); + // return the digest + return digest; +} diff --git a/src/util/sha1.h b/src/util/sha1.h new file mode 100644 index 0000000..20f89ea --- /dev/null +++ b/src/util/sha1.h @@ -0,0 +1,54 @@ +/* sha1.h + +Copyright (c) 2005 Michael D. Leonhard + +http://tamale.net/ + +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. + +*/ + +#pragma once + +typedef unsigned int Uint32; + +class SHA1 +{ +private: + // fields + Uint32 H0 = 0x67452301; + Uint32 H1 = 0xefcdab89; + Uint32 H2 = 0x98badcfe; + Uint32 H3 = 0x10325476; + Uint32 H4 = 0xc3d2e1f0; + unsigned char bytes[64]; + int unprocessedBytes = 0; + Uint32 size = 0; + void process(); + +public: + SHA1(); + ~SHA1(); + void addBytes(const char *data, int num); + unsigned char *getDigest(); + // utility methods + static Uint32 lrot(Uint32 x, int bits); + static void storeBigEndianUint32(unsigned char *byte, Uint32 num); + static void hexPrinter(unsigned char *c, int l); +}; diff --git a/src/util/sha2.h b/src/util/sha2.h new file mode 100644 index 0000000..7d74626 --- /dev/null +++ b/src/util/sha2.h @@ -0,0 +1,154 @@ +/* crypto/sha/sha.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#pragma once + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1)) +#error SHA is disabled. +#endif + +#if defined(OPENSSL_FIPS) +#define FIPS_SHA_SIZE_T size_t +#endif + +/* + Compat stuff from OpenSSL land + */ + +/* crypto.h */ + +#define fips_md_init(alg) fips_md_init_ctx(alg, alg) + +#define fips_md_init_ctx(alg, cx) int alg##_Init(cx##_CTX *c) +#define fips_cipher_abort(alg) while (0) + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! SHA_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#if defined(__LP32__) +#define SHA_LONG unsigned long +#elif defined(__ILP64__) +#define SHA_LONG unsigned long +#define SHA_LONG_LOG2 3 +#else +#define SHA_LONG unsigned int +#endif + +#define SHA_LBLOCK 16 +#define SHA_CBLOCK \ + (SHA_LBLOCK * 4) /* SHA treats input data as a \ + * contiguous array of 32 bit wide \ + * big-endian values. */ +#define SHA_LAST_BLOCK (SHA_CBLOCK - 8) +#define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st +{ + SHA_LONG h0, h1, h2, h3, h4; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; +} SHA_CTX; + +#define SHA256_CBLOCK \ + (SHA_LBLOCK * 4) /* SHA-256 treats input data as a \ + * contiguous array of 32 bit wide \ + * big-endian values. */ +#define SHA224_DIGEST_LENGTH 28 +#define SHA256_DIGEST_LENGTH 32 + +typedef struct SHA256state_st +{ + SHA_LONG h[8]; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num, md_len; +} SHA256_CTX; + +#ifndef OPENSSL_NO_SHA256 +#ifdef OPENSSL_FIPS +int private_SHA224_Init(SHA256_CTX *c); +int private_SHA256_Init(SHA256_CTX *c); +#endif +int SHA224_Init(SHA256_CTX *c); +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA224_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md); +int SHA256_Init(SHA256_CTX *c); +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA256_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md); +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); +#endif + +#define SHA384_DIGEST_LENGTH 48 +#define SHA512_DIGEST_LENGTH 64 + +#ifdef __cplusplus +} +#endif diff --git a/src/util/sha256.c b/src/util/sha256.c new file mode 100644 index 0000000..5c8266f --- /dev/null +++ b/src/util/sha256.c @@ -0,0 +1,399 @@ +/* crypto/sha/sha256.c */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved + * according to the OpenSSL license [found in ../../LICENSE]. + * ==================================================================== + */ +# include <stdlib.h> +# include <string.h> + +# include <util/sha2.h> + +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2a 19 Mar 2015" +# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT + +const char SHA256_version[] = "SHA-256" OPENSSL_VERSION_PTEXT; + +/* mem_clr.c */ +unsigned static char cleanse_ctr = 0; +static void OPENSSL_cleanse(void *ptr, size_t len) +{ + unsigned char *p = (unsigned char *)ptr; + size_t loop = len, ctr = cleanse_ctr; + while (loop--) { + *(p++) = (unsigned char)ctr; + ctr += (17 + ((size_t)p & 0xF)); + } + p = (unsigned char *)memchr(ptr, (unsigned char)ctr, len); + if (p) + ctr += (63 + (size_t)p); + cleanse_ctr = (unsigned char)ctr; +} + +fips_md_init_ctx(SHA224, SHA256) +{ + memset(c, 0, sizeof(*c)); + c->h[0] = 0xc1059ed8UL; + c->h[1] = 0x367cd507UL; + c->h[2] = 0x3070dd17UL; + c->h[3] = 0xf70e5939UL; + c->h[4] = 0xffc00b31UL; + c->h[5] = 0x68581511UL; + c->h[6] = 0x64f98fa7UL; + c->h[7] = 0xbefa4fa4UL; + c->md_len = SHA224_DIGEST_LENGTH; + return 1; +} + +fips_md_init(SHA256) +{ + memset(c, 0, sizeof(*c)); + c->h[0] = 0x6a09e667UL; + c->h[1] = 0xbb67ae85UL; + c->h[2] = 0x3c6ef372UL; + c->h[3] = 0xa54ff53aUL; + c->h[4] = 0x510e527fUL; + c->h[5] = 0x9b05688cUL; + c->h[6] = 0x1f83d9abUL; + c->h[7] = 0x5be0cd19UL; + c->md_len = SHA256_DIGEST_LENGTH; + return 1; +} + +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA256_CTX c; + static unsigned char m[SHA224_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + SHA224_Init(&c); + SHA256_Update(&c, d, n); + SHA256_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} + +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA256_CTX c; + static unsigned char m[SHA256_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + SHA256_Init(&c); + SHA256_Update(&c, d, n); + SHA256_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} + +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) +{ + return SHA256_Update(c, data, len); +} + +int SHA224_Final(unsigned char *md, SHA256_CTX *c) +{ + return SHA256_Final(md, c); +} + +# define DATA_ORDER_IS_BIG_ENDIAN + +# define HASH_LONG SHA_LONG +# define HASH_CTX SHA256_CTX +# define HASH_CBLOCK SHA_CBLOCK +/* + * Note that FIPS180-2 discusses "Truncation of the Hash Function Output." + * default: case below covers for it. It's not clear however if it's + * permitted to truncate to amount of bytes not divisible by 4. I bet not, + * but if it is, then default: case shall be extended. For reference. + * Idea behind separate cases for pre-defined lenghts is to let the + * compiler decide if it's appropriate to unroll small loops. + */ +# define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + unsigned int nn; \ + switch ((c)->md_len) \ + { case SHA224_DIGEST_LENGTH: \ + for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++) \ + { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \ + break; \ + case SHA256_DIGEST_LENGTH: \ + for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++) \ + { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \ + break; \ + default: \ + if ((c)->md_len > SHA256_DIGEST_LENGTH) \ + return 0; \ + for (nn=0;nn<(c)->md_len/4;nn++) \ + { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \ + break; \ + } \ + } while (0) + +# define HASH_UPDATE SHA256_Update +# define HASH_TRANSFORM SHA256_Transform +# define HASH_FINAL SHA256_Final +# define HASH_BLOCK_DATA_ORDER sha256_block_data_order +# ifndef SHA256_ASM +static +# endif +void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num); + +# include "md32_common.h" + +# ifndef SHA256_ASM +static const SHA_LONG K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* + * FIPS specification refers to right rotations, while our ROTATE macro + * is left one. This is why you might notice that rotation coefficients + * differ from those observed in FIPS document by 32-N... + */ +# define Sigma0(x) (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10)) +# define Sigma1(x) (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7)) +# define sigma0(x) (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3)) +# define sigma1(x) (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10)) + +# define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +# define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +# ifdef OPENSSL_SMALL_FOOTPRINT + +static void sha256_block_data_order(SHA256_CTX *ctx, const void *in, + size_t num) +{ + unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1, T2; + SHA_LONG X[16], l; + int i; + const unsigned char *data = in; + + while (num--) { + + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + + for (i = 0; i < 16; i++) { + HOST_c2l(data, l); + T1 = X[i] = l; + T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; + T2 = Sigma0(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + for (; i < 64; i++) { + s0 = X[(i + 1) & 0x0f]; + s0 = sigma0(s0); + s1 = X[(i + 14) & 0x0f]; + s1 = sigma1(s1); + + T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf]; + T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; + T2 = Sigma0(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + + } +} + +# else + +# define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ + T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; \ + h = Sigma0(a) + Maj(a,b,c); \ + d += T1; h += T1; } while (0) + +# define ROUND_16_63(i,a,b,c,d,e,f,g,h,X) do { \ + s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ + s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ + T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ + ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) + +static void sha256_block_data_order(SHA256_CTX *ctx, const void *in, + size_t num) +{ + unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1; + SHA_LONG X[16]; + int i; + const unsigned char *data = (const unsigned char *)in; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + while (num--) { + + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + + if (!is_endian.little && sizeof(SHA_LONG) == 4 + && ((size_t)in % 4) == 0) { + const SHA_LONG *W = (const SHA_LONG *)data; + + T1 = X[0] = W[0]; + ROUND_00_15(0, a, b, c, d, e, f, g, h); + T1 = X[1] = W[1]; + ROUND_00_15(1, h, a, b, c, d, e, f, g); + T1 = X[2] = W[2]; + ROUND_00_15(2, g, h, a, b, c, d, e, f); + T1 = X[3] = W[3]; + ROUND_00_15(3, f, g, h, a, b, c, d, e); + T1 = X[4] = W[4]; + ROUND_00_15(4, e, f, g, h, a, b, c, d); + T1 = X[5] = W[5]; + ROUND_00_15(5, d, e, f, g, h, a, b, c); + T1 = X[6] = W[6]; + ROUND_00_15(6, c, d, e, f, g, h, a, b); + T1 = X[7] = W[7]; + ROUND_00_15(7, b, c, d, e, f, g, h, a); + T1 = X[8] = W[8]; + ROUND_00_15(8, a, b, c, d, e, f, g, h); + T1 = X[9] = W[9]; + ROUND_00_15(9, h, a, b, c, d, e, f, g); + T1 = X[10] = W[10]; + ROUND_00_15(10, g, h, a, b, c, d, e, f); + T1 = X[11] = W[11]; + ROUND_00_15(11, f, g, h, a, b, c, d, e); + T1 = X[12] = W[12]; + ROUND_00_15(12, e, f, g, h, a, b, c, d); + T1 = X[13] = W[13]; + ROUND_00_15(13, d, e, f, g, h, a, b, c); + T1 = X[14] = W[14]; + ROUND_00_15(14, c, d, e, f, g, h, a, b); + T1 = X[15] = W[15]; + ROUND_00_15(15, b, c, d, e, f, g, h, a); + + data += SHA256_CBLOCK; + } else { + SHA_LONG l; + + HOST_c2l(data, l); + T1 = X[0] = l; + ROUND_00_15(0, a, b, c, d, e, f, g, h); + HOST_c2l(data, l); + T1 = X[1] = l; + ROUND_00_15(1, h, a, b, c, d, e, f, g); + HOST_c2l(data, l); + T1 = X[2] = l; + ROUND_00_15(2, g, h, a, b, c, d, e, f); + HOST_c2l(data, l); + T1 = X[3] = l; + ROUND_00_15(3, f, g, h, a, b, c, d, e); + HOST_c2l(data, l); + T1 = X[4] = l; + ROUND_00_15(4, e, f, g, h, a, b, c, d); + HOST_c2l(data, l); + T1 = X[5] = l; + ROUND_00_15(5, d, e, f, g, h, a, b, c); + HOST_c2l(data, l); + T1 = X[6] = l; + ROUND_00_15(6, c, d, e, f, g, h, a, b); + HOST_c2l(data, l); + T1 = X[7] = l; + ROUND_00_15(7, b, c, d, e, f, g, h, a); + HOST_c2l(data, l); + T1 = X[8] = l; + ROUND_00_15(8, a, b, c, d, e, f, g, h); + HOST_c2l(data, l); + T1 = X[9] = l; + ROUND_00_15(9, h, a, b, c, d, e, f, g); + HOST_c2l(data, l); + T1 = X[10] = l; + ROUND_00_15(10, g, h, a, b, c, d, e, f); + HOST_c2l(data, l); + T1 = X[11] = l; + ROUND_00_15(11, f, g, h, a, b, c, d, e); + HOST_c2l(data, l); + T1 = X[12] = l; + ROUND_00_15(12, e, f, g, h, a, b, c, d); + HOST_c2l(data, l); + T1 = X[13] = l; + ROUND_00_15(13, d, e, f, g, h, a, b, c); + HOST_c2l(data, l); + T1 = X[14] = l; + ROUND_00_15(14, c, d, e, f, g, h, a, b); + HOST_c2l(data, l); + T1 = X[15] = l; + ROUND_00_15(15, b, c, d, e, f, g, h, a); + } + + for (i = 16; i < 64; i += 8) { + ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X); + ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X); + ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X); + ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X); + ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X); + ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X); + ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X); + ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X); + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + + } +} + +# endif +# endif /* SHA256_ASM */ diff --git a/src/util/srp.cpp b/src/util/srp.cpp new file mode 100644 index 0000000..daa7f33 --- /dev/null +++ b/src/util/srp.cpp @@ -0,0 +1,1040 @@ +/* + * Secure Remote Password 6a implementation + * https://github.com/est31/csrp-gmp + * + * The MIT License (MIT) + * + * Copyright (c) 2010, 2013 Tom Cocagne, 2015 est31 <MTest31@outlook.com> + * + * 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. + * + */ + +// clang-format off + +#include <cstddef> + +#ifdef WIN32 + #include <windows.h> + #include <wincrypt.h> +#else + #include <ctime> + +#endif +// clang-format on + +#include <cstdlib> +#include <cstring> +#include <cstdio> +#include <cstdint> + +#include <config.h> + +#if USE_SYSTEM_GMP + #include <gmp.h> +#else + #include <mini-gmp.h> +#endif + +#include <util/sha2.h> + +#include "srp.h" +//#define CSRP_USE_SHA1 +#define CSRP_USE_SHA256 + +#define srp_dbg_data(data, datalen, prevtext) ; +/*void srp_dbg_data(unsigned char * data, size_t datalen, char * prevtext) +{ + printf(prevtext); + size_t i; + for (i = 0; i < datalen; i++) + { + printf("%02X", data[i]); + } + printf("\n"); +}*/ + +static int g_initialized = 0; + +#define RAND_BUFF_MAX 128 +static unsigned int g_rand_idx; +static unsigned char g_rand_buff[RAND_BUFF_MAX]; + +void *(*srp_alloc)(size_t) = &malloc; +void *(*srp_realloc)(void *, size_t) = &realloc; +void (*srp_free)(void *) = &free; + +// clang-format off +void srp_set_memory_functions( + void *(*new_srp_alloc)(size_t), + void *(*new_srp_realloc)(void *, size_t), + void (*new_srp_free)(void *)) +{ + srp_alloc = new_srp_alloc; + srp_realloc = new_srp_realloc; + srp_free = new_srp_free; +} +// clang-format on + +typedef struct { + mpz_t N; + mpz_t g; +} NGConstant; + +struct NGHex { + const char *n_hex; + const char *g_hex; +}; + +/* All constants here were pulled from Appendix A of RFC 5054 */ +static struct NGHex global_Ng_constants[] = { + {/* 1024 */ + "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C" + "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4" + "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29" + "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A" + "FD5138FE8376435B9FC61D2FC0EB06E3", + "2"}, + {/* 2048 */ + "AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC319294" + "3DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310D" + "CD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FB" + "D5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF74" + "7359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A" + "436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D" + "5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E73" + "03CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB6" + "94B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F" + "9E4AFF73", + "2"}, + {/* 4096 */ + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" + "FFFFFFFFFFFFFFFF", + "5"}, + {/* 8192 */ + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + "6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA" + "3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C" + "5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC886" + "2F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A6" + "6D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC5" + "0846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268" + "359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6" + "FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF", + "13"}, + {0, 0} /* null sentinel */ +}; + +static void delete_ng(NGConstant *ng) +{ + if (ng) { + mpz_clear(ng->N); + mpz_clear(ng->g); + srp_free(ng); + } +} + +static NGConstant *new_ng(SRP_NGType ng_type, const char *n_hex, const char *g_hex) +{ + NGConstant *ng = (NGConstant *)srp_alloc(sizeof(NGConstant)); + + if (!ng) return 0; + + mpz_init(ng->N); + mpz_init(ng->g); + + if (ng_type != SRP_NG_CUSTOM) { + n_hex = global_Ng_constants[ng_type].n_hex; + g_hex = global_Ng_constants[ng_type].g_hex; + } + + int rv = 0; + rv = mpz_set_str(ng->N, n_hex, 16); + rv = rv | mpz_set_str(ng->g, g_hex, 16); + + if (rv) { + delete_ng(ng); + return 0; + } + + return ng; +} + +typedef union { + SHA_CTX sha; + SHA256_CTX sha256; + // SHA512_CTX sha512; +} HashCTX; + +struct SRPVerifier { + SRP_HashAlgorithm hash_alg; + NGConstant *ng; + + char *username; + unsigned char *bytes_B; + int authenticated; + + unsigned char M[SHA512_DIGEST_LENGTH]; + unsigned char H_AMK[SHA512_DIGEST_LENGTH]; + unsigned char session_key[SHA512_DIGEST_LENGTH]; +}; + +struct SRPUser { + SRP_HashAlgorithm hash_alg; + NGConstant *ng; + + mpz_t a; + mpz_t A; + mpz_t S; + + unsigned char *bytes_A; + int authenticated; + + char *username; + char *username_verifier; + unsigned char *password; + size_t password_len; + + unsigned char M[SHA512_DIGEST_LENGTH]; + unsigned char H_AMK[SHA512_DIGEST_LENGTH]; + unsigned char session_key[SHA512_DIGEST_LENGTH]; +}; + +// clang-format off +static int hash_init(SRP_HashAlgorithm alg, HashCTX *c) +{ + switch (alg) { +#ifdef CSRP_USE_SHA1 + case SRP_SHA1: return SHA1_Init(&c->sha); +#endif + /* + case SRP_SHA224: return SHA224_Init(&c->sha256); + */ +#ifdef CSRP_USE_SHA256 + case SRP_SHA256: return SHA256_Init(&c->sha256); +#endif + /* + case SRP_SHA384: return SHA384_Init(&c->sha512); + case SRP_SHA512: return SHA512_Init(&c->sha512); + */ + default: return -1; + }; +} +static int hash_update( SRP_HashAlgorithm alg, HashCTX *c, const void *data, size_t len ) +{ + switch (alg) { +#ifdef CSRP_USE_SHA1 + case SRP_SHA1: return SHA1_Update(&c->sha, data, len); +#endif + /* + case SRP_SHA224: return SHA224_Update(&c->sha256, data, len); + */ +#ifdef CSRP_USE_SHA256 + case SRP_SHA256: return SHA256_Update(&c->sha256, data, len); +#endif + /* + case SRP_SHA384: return SHA384_Update(&c->sha512, data, len); + case SRP_SHA512: return SHA512_Update(&c->sha512, data, len); + */ + default: return -1; + }; +} +static int hash_final( SRP_HashAlgorithm alg, HashCTX *c, unsigned char *md ) +{ + switch (alg) { +#ifdef CSRP_USE_SHA1 + case SRP_SHA1: return SHA1_Final(md, &c->sha); +#endif + /* + case SRP_SHA224: return SHA224_Final(md, &c->sha256); + */ +#ifdef CSRP_USE_SHA256 + case SRP_SHA256: return SHA256_Final(md, &c->sha256); +#endif + /* + case SRP_SHA384: return SHA384_Final(md, &c->sha512); + case SRP_SHA512: return SHA512_Final(md, &c->sha512); + */ + default: return -1; + }; +} +static unsigned char *hash(SRP_HashAlgorithm alg, const unsigned char *d, size_t n, unsigned char *md) +{ + switch (alg) { +#ifdef CSRP_USE_SHA1 + case SRP_SHA1: return SHA1(d, n, md); +#endif + /* + case SRP_SHA224: return SHA224( d, n, md ); + */ +#ifdef CSRP_USE_SHA256 + case SRP_SHA256: return SHA256(d, n, md); +#endif + /* + case SRP_SHA384: return SHA384( d, n, md ); + case SRP_SHA512: return SHA512( d, n, md ); + */ + default: return 0; + }; +} +static size_t hash_length(SRP_HashAlgorithm alg) +{ + switch (alg) { +#ifdef CSRP_USE_SHA1 + case SRP_SHA1: return SHA_DIGEST_LENGTH; +#endif + /* + case SRP_SHA224: return SHA224_DIGEST_LENGTH; + */ +#ifdef CSRP_USE_SHA256 + case SRP_SHA256: return SHA256_DIGEST_LENGTH; +#endif + /* + case SRP_SHA384: return SHA384_DIGEST_LENGTH; + case SRP_SHA512: return SHA512_DIGEST_LENGTH; + */ + default: return 0; + }; +} +// clang-format on + +inline static int mpz_num_bytes(const mpz_t op) +{ + return (mpz_sizeinbase(op, 2) + 7) / 8; +} + +inline static void mpz_to_bin(const mpz_t op, unsigned char *to) +{ + mpz_export(to, NULL, 1, 1, 1, 0, op); +} + +inline static void mpz_from_bin(const unsigned char *s, size_t len, mpz_t ret) +{ + mpz_import(ret, len, 1, 1, 1, 0, s); +} + +// set op to (op1 * op2) mod d, using tmp for the calculation +inline static void mpz_mulm( + mpz_t op, const mpz_t op1, const mpz_t op2, const mpz_t d, mpz_t tmp) +{ + mpz_mul(tmp, op1, op2); + mpz_mod(op, tmp, d); +} + +// set op to (op1 + op2) mod d, using tmp for the calculation +inline static void mpz_addm( + mpz_t op, const mpz_t op1, const mpz_t op2, const mpz_t d, mpz_t tmp) +{ + mpz_add(tmp, op1, op2); + mpz_mod(op, tmp, d); +} + +// set op to (op1 - op2) mod d, using tmp for the calculation +inline static void mpz_subm( + mpz_t op, const mpz_t op1, const mpz_t op2, const mpz_t d, mpz_t tmp) +{ + mpz_sub(tmp, op1, op2); + mpz_mod(op, tmp, d); +} + +static SRP_Result H_nn( + mpz_t result, SRP_HashAlgorithm alg, const mpz_t N, const mpz_t n1, const mpz_t n2) +{ + unsigned char buff[SHA512_DIGEST_LENGTH]; + size_t len_N = mpz_num_bytes(N); + size_t len_n1 = mpz_num_bytes(n1); + size_t len_n2 = mpz_num_bytes(n2); + size_t nbytes = len_N + len_N; + unsigned char *bin = (unsigned char *)srp_alloc(nbytes); + if (!bin) return SRP_ERR; + if (len_n1 > len_N || len_n2 > len_N) { + srp_free(bin); + return SRP_ERR; + } + memset(bin, 0, nbytes); + mpz_to_bin(n1, bin + (len_N - len_n1)); + mpz_to_bin(n2, bin + (len_N + len_N - len_n2)); + hash(alg, bin, nbytes, buff); + srp_free(bin); + mpz_from_bin(buff, hash_length(alg), result); + return SRP_OK; +} + +static SRP_Result H_ns(mpz_t result, SRP_HashAlgorithm alg, const unsigned char *n, + size_t len_n, const unsigned char *bytes, size_t len_bytes) +{ + unsigned char buff[SHA512_DIGEST_LENGTH]; + size_t nbytes = len_n + len_bytes; + unsigned char *bin = (unsigned char *)srp_alloc(nbytes); + if (!bin) return SRP_ERR; + memcpy(bin, n, len_n); + memcpy(bin + len_n, bytes, len_bytes); + hash(alg, bin, nbytes, buff); + srp_free(bin); + mpz_from_bin(buff, hash_length(alg), result); + return SRP_OK; +} + +static int calculate_x(mpz_t result, SRP_HashAlgorithm alg, const unsigned char *salt, + size_t salt_len, const char *username, const unsigned char *password, + size_t password_len) +{ + unsigned char ucp_hash[SHA512_DIGEST_LENGTH]; + HashCTX ctx; + hash_init(alg, &ctx); + + srp_dbg_data((char *)username, strlen(username), "Username for x: "); + srp_dbg_data((char *)password, password_len, "Password for x: "); + hash_update(alg, &ctx, username, strlen(username)); + hash_update(alg, &ctx, ":", 1); + hash_update(alg, &ctx, password, password_len); + + hash_final(alg, &ctx, ucp_hash); + + return H_ns(result, alg, salt, salt_len, ucp_hash, hash_length(alg)); +} + +static SRP_Result update_hash_n(SRP_HashAlgorithm alg, HashCTX *ctx, const mpz_t n) +{ + size_t len = mpz_num_bytes(n); + unsigned char *n_bytes = (unsigned char *)srp_alloc(len); + if (!n_bytes) return SRP_ERR; + mpz_to_bin(n, n_bytes); + hash_update(alg, ctx, n_bytes, len); + srp_free(n_bytes); + return SRP_OK; +} + +static SRP_Result hash_num(SRP_HashAlgorithm alg, const mpz_t n, unsigned char *dest) +{ + int nbytes = mpz_num_bytes(n); + unsigned char *bin = (unsigned char *)srp_alloc(nbytes); + if (!bin) return SRP_ERR; + mpz_to_bin(n, bin); + hash(alg, bin, nbytes, dest); + srp_free(bin); + return SRP_OK; +} + +static SRP_Result calculate_M(SRP_HashAlgorithm alg, NGConstant *ng, unsigned char *dest, + const char *I, const unsigned char *s_bytes, size_t s_len, const mpz_t A, + const mpz_t B, const unsigned char *K) +{ + unsigned char H_N[SHA512_DIGEST_LENGTH]; + unsigned char H_g[SHA512_DIGEST_LENGTH]; + unsigned char H_I[SHA512_DIGEST_LENGTH]; + unsigned char H_xor[SHA512_DIGEST_LENGTH]; + HashCTX ctx; + size_t i = 0; + size_t hash_len = hash_length(alg); + + if (!hash_num(alg, ng->N, H_N)) return SRP_ERR; + if (!hash_num(alg, ng->g, H_g)) return SRP_ERR; + + hash(alg, (const unsigned char *)I, strlen(I), H_I); + + for (i = 0; i < hash_len; i++) + H_xor[i] = H_N[i] ^ H_g[i]; + + hash_init(alg, &ctx); + + hash_update(alg, &ctx, H_xor, hash_len); + hash_update(alg, &ctx, H_I, hash_len); + hash_update(alg, &ctx, s_bytes, s_len); + if (!update_hash_n(alg, &ctx, A)) return SRP_ERR; + if (!update_hash_n(alg, &ctx, B)) return SRP_ERR; + hash_update(alg, &ctx, K, hash_len); + + hash_final(alg, &ctx, dest); + return SRP_OK; +} + +static SRP_Result calculate_H_AMK(SRP_HashAlgorithm alg, unsigned char *dest, + const mpz_t A, const unsigned char *M, const unsigned char *K) +{ + HashCTX ctx; + + hash_init(alg, &ctx); + + if (!update_hash_n(alg, &ctx, A)) return SRP_ERR; + hash_update(alg, &ctx, M, hash_length(alg)); + hash_update(alg, &ctx, K, hash_length(alg)); + + hash_final(alg, &ctx, dest); + return SRP_OK; +} + +static SRP_Result fill_buff() +{ + g_rand_idx = 0; + +#ifdef WIN32 + HCRYPTPROV wctx; +#else + FILE *fp = 0; +#endif + +#ifdef WIN32 + + if (!CryptAcquireContext(&wctx, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + return SRP_ERR; + if (!CryptGenRandom(wctx, sizeof(g_rand_buff), (BYTE *)g_rand_buff)) return SRP_ERR; + if (!CryptReleaseContext(wctx, 0)) return SRP_ERR; + +#else + fp = fopen("/dev/urandom", "r"); + + if (!fp) return SRP_ERR; + + if (fread(g_rand_buff, sizeof(g_rand_buff), 1, fp) != 1) { fclose(fp); return SRP_ERR; } + if (fclose(fp)) return SRP_ERR; +#endif + return SRP_OK; +} + +static SRP_Result mpz_fill_random(mpz_t num) +{ + // was call: BN_rand(num, 256, -1, 0); + if (RAND_BUFF_MAX - g_rand_idx < 32) + if (fill_buff() != SRP_OK) return SRP_ERR; + mpz_from_bin((const unsigned char *)(&g_rand_buff[g_rand_idx]), 32, num); + g_rand_idx += 32; + return SRP_OK; +} + +static SRP_Result init_random() +{ + if (g_initialized) return SRP_OK; + SRP_Result ret = fill_buff(); + g_initialized = (ret == SRP_OK); + return ret; +} + +#define srp_dbg_num(num, text) ; +/*void srp_dbg_num(mpz_t num, char * prevtext) +{ + int len_num = mpz_num_bytes(num); + char *bytes_num = (char*) srp_alloc(len_num); + mpz_to_bin(num, (unsigned char *) bytes_num); + srp_dbg_data(bytes_num, len_num, prevtext); + srp_free(bytes_num); + +}*/ + +/*********************************************************************************************************** + * + * Exported Functions + * + ***********************************************************************************************************/ + +// clang-format off +SRP_Result srp_create_salted_verification_key( SRP_HashAlgorithm alg, + SRP_NGType ng_type, const char *username_for_verifier, + const unsigned char *password, size_t len_password, + unsigned char **bytes_s, size_t *len_s, + unsigned char **bytes_v, size_t *len_v, + const char *n_hex, const char *g_hex ) +{ + SRP_Result ret = SRP_OK; + + mpz_t v; mpz_init(v); + mpz_t x; mpz_init(x); + // clang-format on + + NGConstant *ng = new_ng(ng_type, n_hex, g_hex); + + if (!ng) goto error_and_exit; + + if (init_random() != SRP_OK) /* Only happens once */ + goto error_and_exit; + + if (*bytes_s == NULL) { + size_t size_to_fill = 16; + *len_s = size_to_fill; + if (RAND_BUFF_MAX - g_rand_idx < size_to_fill) + if (fill_buff() != SRP_OK) goto error_and_exit; + *bytes_s = (unsigned char *)srp_alloc(size_to_fill); + if (!*bytes_s) goto error_and_exit; + memcpy(*bytes_s, &g_rand_buff[g_rand_idx], size_to_fill); + g_rand_idx += size_to_fill; + } + + if (!calculate_x( + x, alg, *bytes_s, *len_s, username_for_verifier, password, len_password)) + goto error_and_exit; + + srp_dbg_num(x, "Server calculated x: "); + + mpz_powm(v, ng->g, x, ng->N); + + *len_v = mpz_num_bytes(v); + + *bytes_v = (unsigned char *)srp_alloc(*len_v); + + if (!*bytes_v) goto error_and_exit; + + mpz_to_bin(v, *bytes_v); + +cleanup_and_exit: + delete_ng(ng); + mpz_clear(v); + mpz_clear(x); + return ret; +error_and_exit: + ret = SRP_ERR; + goto cleanup_and_exit; +} + +// clang-format off + +/* Out: bytes_B, len_B. + * + * On failure, bytes_B will be set to NULL and len_B will be set to 0 + */ +struct SRPVerifier *srp_verifier_new(SRP_HashAlgorithm alg, + SRP_NGType ng_type, const char *username, + const unsigned char *bytes_s, size_t len_s, + const unsigned char *bytes_v, size_t len_v, + const unsigned char *bytes_A, size_t len_A, + const unsigned char *bytes_b, size_t len_b, + unsigned char **bytes_B, size_t *len_B, + const char *n_hex, const char *g_hex ) +{ + mpz_t v; mpz_init(v); mpz_from_bin(bytes_v, len_v, v); + mpz_t A; mpz_init(A); mpz_from_bin(bytes_A, len_A, A); + mpz_t u; mpz_init(u); + mpz_t B; mpz_init(B); + mpz_t S; mpz_init(S); + mpz_t b; mpz_init(b); + mpz_t k; mpz_init(k); + mpz_t tmp1; mpz_init(tmp1); + mpz_t tmp2; mpz_init(tmp2); + mpz_t tmp3; mpz_init(tmp3); + // clang-format on + size_t ulen = strlen(username) + 1; + NGConstant *ng = new_ng(ng_type, n_hex, g_hex); + struct SRPVerifier *ver = 0; + + *len_B = 0; + *bytes_B = 0; + + if (!ng) goto cleanup_and_exit; + + ver = (struct SRPVerifier *)srp_alloc(sizeof(struct SRPVerifier)); + + if (!ver) goto cleanup_and_exit; + + if (init_random() != SRP_OK) { /* Only happens once */ + srp_free(ver); + ver = 0; + goto cleanup_and_exit; + } + + ver->username = (char *)srp_alloc(ulen); + ver->hash_alg = alg; + ver->ng = ng; + + if (!ver->username) { + srp_free(ver); + ver = 0; + goto cleanup_and_exit; + } + + memcpy(ver->username, username, ulen); + + ver->authenticated = 0; + + /* SRP-6a safety check */ + mpz_mod(tmp1, A, ng->N); + if (mpz_sgn(tmp1) != 0) { + if (bytes_b) { + mpz_from_bin(bytes_b, len_b, b); + } else { + if (!mpz_fill_random(b)) goto ver_cleanup_and_exit; + } + + if (!H_nn(k, alg, ng->N, ng->N, ng->g)) goto ver_cleanup_and_exit; + + /* B = kv + g^b */ + mpz_mulm(tmp1, k, v, ng->N, tmp3); + mpz_powm(tmp2, ng->g, b, ng->N); + mpz_addm(B, tmp1, tmp2, ng->N, tmp3); + + if (!H_nn(u, alg, ng->N, A, B)) goto ver_cleanup_and_exit; + + srp_dbg_num(u, "Server calculated u: "); + + /* S = (A *(v^u)) ^ b */ + mpz_powm(tmp1, v, u, ng->N); + mpz_mulm(tmp2, A, tmp1, ng->N, tmp3); + mpz_powm(S, tmp2, b, ng->N); + + if (!hash_num(alg, S, ver->session_key)) goto ver_cleanup_and_exit; + + if (!calculate_M( + alg, ng, ver->M, username, bytes_s, len_s, A, B, ver->session_key)) { + goto ver_cleanup_and_exit; + } + if (!calculate_H_AMK(alg, ver->H_AMK, A, ver->M, ver->session_key)) { + goto ver_cleanup_and_exit; + } + + *len_B = mpz_num_bytes(B); + *bytes_B = (unsigned char *)srp_alloc(*len_B); + + if (!*bytes_B) { + *len_B = 0; + goto ver_cleanup_and_exit; + } + + mpz_to_bin(B, *bytes_B); + + ver->bytes_B = *bytes_B; + } else { + srp_free(ver); + ver = 0; + } + +cleanup_and_exit: + mpz_clear(v); + mpz_clear(A); + mpz_clear(u); + mpz_clear(k); + mpz_clear(B); + mpz_clear(S); + mpz_clear(b); + mpz_clear(tmp1); + mpz_clear(tmp2); + mpz_clear(tmp3); + return ver; +ver_cleanup_and_exit: + srp_free(ver->username); + srp_free(ver); + ver = 0; + goto cleanup_and_exit; +} + +void srp_verifier_delete(struct SRPVerifier *ver) +{ + if (ver) { + delete_ng(ver->ng); + srp_free(ver->username); + srp_free(ver->bytes_B); + memset(ver, 0, sizeof(*ver)); + srp_free(ver); + } +} + +int srp_verifier_is_authenticated(struct SRPVerifier *ver) +{ + return ver->authenticated; +} + +const char *srp_verifier_get_username(struct SRPVerifier *ver) +{ + return ver->username; +} + +const unsigned char *srp_verifier_get_session_key( + struct SRPVerifier *ver, size_t *key_length) +{ + if (key_length) *key_length = hash_length(ver->hash_alg); + return ver->session_key; +} + +size_t srp_verifier_get_session_key_length(struct SRPVerifier *ver) +{ + return hash_length(ver->hash_alg); +} + +/* user_M must be exactly SHA512_DIGEST_LENGTH bytes in size */ +void srp_verifier_verify_session( + struct SRPVerifier *ver, const unsigned char *user_M, unsigned char **bytes_HAMK) +{ + if (memcmp(ver->M, user_M, hash_length(ver->hash_alg)) == 0) { + ver->authenticated = 1; + *bytes_HAMK = ver->H_AMK; + } else + *bytes_HAMK = NULL; +} + +/*******************************************************************************/ + +struct SRPUser *srp_user_new(SRP_HashAlgorithm alg, SRP_NGType ng_type, + const char *username, const char *username_for_verifier, + const unsigned char *bytes_password, size_t len_password, const char *n_hex, + const char *g_hex) +{ + struct SRPUser *usr = (struct SRPUser *)srp_alloc(sizeof(struct SRPUser)); + size_t ulen = strlen(username) + 1; + size_t uvlen = strlen(username_for_verifier) + 1; + + if (!usr) goto err_exit; + + if (init_random() != SRP_OK) /* Only happens once */ + goto err_exit; + + usr->hash_alg = alg; + usr->ng = new_ng(ng_type, n_hex, g_hex); + + mpz_init(usr->a); + mpz_init(usr->A); + mpz_init(usr->S); + + if (!usr->ng) goto err_exit; + + usr->username = (char *)srp_alloc(ulen); + usr->username_verifier = (char *)srp_alloc(uvlen); + usr->password = (unsigned char *)srp_alloc(len_password); + usr->password_len = len_password; + + if (!usr->username || !usr->password || !usr->username_verifier) goto err_exit; + + memcpy(usr->username, username, ulen); + memcpy(usr->username_verifier, username_for_verifier, uvlen); + memcpy(usr->password, bytes_password, len_password); + + usr->authenticated = 0; + + usr->bytes_A = 0; + + return usr; + +err_exit: + if (usr) { + mpz_clear(usr->a); + mpz_clear(usr->A); + mpz_clear(usr->S); + delete_ng(usr->ng); + srp_free(usr->username); + srp_free(usr->username_verifier); + if (usr->password) { + memset(usr->password, 0, usr->password_len); + srp_free(usr->password); + } + srp_free(usr); + } + + return 0; +} + +void srp_user_delete(struct SRPUser *usr) +{ + if (usr) { + mpz_clear(usr->a); + mpz_clear(usr->A); + mpz_clear(usr->S); + + delete_ng(usr->ng); + + memset(usr->password, 0, usr->password_len); + + srp_free(usr->username); + srp_free(usr->username_verifier); + srp_free(usr->password); + + if (usr->bytes_A) srp_free(usr->bytes_A); + + memset(usr, 0, sizeof(*usr)); + srp_free(usr); + } +} + +int srp_user_is_authenticated(struct SRPUser *usr) +{ + return usr->authenticated; +} + +const char *srp_user_get_username(struct SRPUser *usr) +{ + return usr->username; +} + +const unsigned char *srp_user_get_session_key(struct SRPUser *usr, size_t *key_length) +{ + if (key_length) *key_length = hash_length(usr->hash_alg); + return usr->session_key; +} + +size_t srp_user_get_session_key_length(struct SRPUser *usr) +{ + return hash_length(usr->hash_alg); +} + +// clang-format off +/* Output: username, bytes_A, len_A */ +SRP_Result srp_user_start_authentication(struct SRPUser *usr, char **username, + const unsigned char *bytes_a, size_t len_a, + unsigned char **bytes_A, size_t *len_A) +{ + // clang-format on + if (bytes_a) { + mpz_from_bin(bytes_a, len_a, usr->a); + } else { + if (!mpz_fill_random(usr->a)) goto error_and_exit; + } + + mpz_powm(usr->A, usr->ng->g, usr->a, usr->ng->N); + + *len_A = mpz_num_bytes(usr->A); + *bytes_A = (unsigned char *)srp_alloc(*len_A); + + if (!*bytes_A) goto error_and_exit; + + mpz_to_bin(usr->A, *bytes_A); + + usr->bytes_A = *bytes_A; + if (username) *username = usr->username; + + return SRP_OK; + +error_and_exit: + *len_A = 0; + *bytes_A = 0; + *username = 0; + return SRP_ERR; +} + +// clang-format off +/* Output: bytes_M. Buffer length is SHA512_DIGEST_LENGTH */ +void srp_user_process_challenge(struct SRPUser *usr, + const unsigned char *bytes_s, size_t len_s, + const unsigned char *bytes_B, size_t len_B, + unsigned char **bytes_M, size_t *len_M) +{ + mpz_t B; mpz_init(B); mpz_from_bin(bytes_B, len_B, B); + mpz_t u; mpz_init(u); + mpz_t x; mpz_init(x); + mpz_t k; mpz_init(k); + mpz_t v; mpz_init(v); + mpz_t tmp1; mpz_init(tmp1); + mpz_t tmp2; mpz_init(tmp2); + mpz_t tmp3; mpz_init(tmp3); + mpz_t tmp4; mpz_init(tmp4); + // clang-format on + + *len_M = 0; + *bytes_M = 0; + + if (!H_nn(u, usr->hash_alg, usr->ng->N, usr->A, B)) goto cleanup_and_exit; + + srp_dbg_num(u, "Client calculated u: "); + + if (!calculate_x(x, usr->hash_alg, bytes_s, len_s, usr->username_verifier, + usr->password, usr->password_len)) + goto cleanup_and_exit; + + srp_dbg_num(x, "Client calculated x: "); + + if (!H_nn(k, usr->hash_alg, usr->ng->N, usr->ng->N, usr->ng->g)) + goto cleanup_and_exit; + + /* SRP-6a safety check */ + if (mpz_sgn(B) != 0 && mpz_sgn(u) != 0) { + mpz_powm(v, usr->ng->g, x, usr->ng->N); + + srp_dbg_num(v, "Client calculated v: "); + + // clang-format off + /* S = (B - k*(g^x)) ^ (a + ux) */ + mpz_mul(tmp1, u, x); + mpz_add(tmp2, usr->a, tmp1); /* tmp2 = (a + ux) */ + mpz_powm(tmp1, usr->ng->g, x, usr->ng->N); /* tmp1 = g^x */ + mpz_mulm(tmp3, k, tmp1, usr->ng->N, tmp4); /* tmp3 = k*(g^x) */ + mpz_subm(tmp1, B, tmp3, usr->ng->N, tmp4); /* tmp1 = (B - K*(g^x)) */ + mpz_powm(usr->S, tmp1, tmp2, usr->ng->N); + // clang-format on + + if (!hash_num(usr->hash_alg, usr->S, usr->session_key)) goto cleanup_and_exit; + + if (!calculate_M(usr->hash_alg, usr->ng, usr->M, usr->username, bytes_s, len_s, + usr->A, B, usr->session_key)) + goto cleanup_and_exit; + if (!calculate_H_AMK(usr->hash_alg, usr->H_AMK, usr->A, usr->M, usr->session_key)) + goto cleanup_and_exit; + + *bytes_M = usr->M; + *len_M = hash_length(usr->hash_alg); + } else { + *bytes_M = NULL; + *len_M = 0; + } + +cleanup_and_exit: + mpz_clear(B); + mpz_clear(u); + mpz_clear(x); + mpz_clear(k); + mpz_clear(v); + mpz_clear(tmp1); + mpz_clear(tmp2); + mpz_clear(tmp3); + mpz_clear(tmp4); +} + +void srp_user_verify_session(struct SRPUser *usr, const unsigned char *bytes_HAMK) +{ + if (memcmp(usr->H_AMK, bytes_HAMK, hash_length(usr->hash_alg)) == 0) + usr->authenticated = 1; +} diff --git a/src/util/srp.h b/src/util/srp.h new file mode 100644 index 0000000..cf2bdec --- /dev/null +++ b/src/util/srp.h @@ -0,0 +1,191 @@ +/* + * Secure Remote Password 6a implementation + * https://github.com/est31/csrp-gmp + * + * The MIT License (MIT) + * + * Copyright (c) 2010, 2013 Tom Cocagne, 2015 est31 <MTest31@outlook.com> + * + * 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. + * + */ + +/* + * + * Purpose: This is a direct implementation of the Secure Remote Password + * Protocol version 6a as described by + * http://srp.stanford.edu/design.html + * + * Author: tom.cocagne@gmail.com (Tom Cocagne) + * + * Dependencies: LibGMP + * + * Usage: Refer to test_srp.c for a demonstration + * + * Notes: + * This library allows multiple combinations of hashing algorithms and + * prime number constants. For authentication to succeed, the hash and + * prime number constants must match between + * srp_create_salted_verification_key(), srp_user_new(), + * and srp_verifier_new(). A recommended approach is to determine the + * desired level of security for an application and globally define the + * hash and prime number constants to the predetermined values. + * + * As one might suspect, more bits means more security. As one might also + * suspect, more bits also means more processing time. The test_srp.c + * program can be easily modified to profile various combinations of + * hash & prime number pairings. + */ + +#pragma once + +struct SRPVerifier; +struct SRPUser; + +typedef enum { + SRP_NG_1024, + SRP_NG_2048, + SRP_NG_4096, + SRP_NG_8192, + SRP_NG_CUSTOM +} SRP_NGType; + +typedef enum { + /*SRP_SHA1,*/ + /*SRP_SHA224,*/ + SRP_SHA256, + /*SRP_SHA384, + SRP_SHA512*/ +} SRP_HashAlgorithm; + +typedef enum { + SRP_ERR, + SRP_OK, +} SRP_Result; + +// clang-format off + +/* Sets the memory functions used by srp. + * Note: this doesn't set the memory functions used by gmp, + * but it is supported to have different functions for srp and gmp. + * Don't call this after you have already allocated srp structures. + */ +void srp_set_memory_functions( + void *(*new_srp_alloc) (size_t), + void *(*new_srp_realloc) (void *, size_t), + void (*new_srp_free) (void *)); + +/* Out: bytes_v, len_v + * + * The caller is responsible for freeing the memory allocated for bytes_v + * + * The n_hex and g_hex parameters should be 0 unless SRP_NG_CUSTOM is used for ng_type. + * If provided, they must contain ASCII text of the hexidecimal notation. + * + * If bytes_s == NULL, it is filled with random data. + * The caller is responsible for freeing. + * + * Returns SRP_OK on success, and SRP_ERR on error. + * bytes_s might be in this case invalid, don't free it. + */ +SRP_Result srp_create_salted_verification_key(SRP_HashAlgorithm alg, + SRP_NGType ng_type, const char *username_for_verifier, + const unsigned char *password, size_t len_password, + unsigned char **bytes_s, size_t *len_s, + unsigned char **bytes_v, size_t *len_v, + const char *n_hex, const char *g_hex); + +/* Out: bytes_B, len_B. + * + * On failure, bytes_B will be set to NULL and len_B will be set to 0 + * + * The n_hex and g_hex parameters should be 0 unless SRP_NG_CUSTOM is used for ng_type + * + * If bytes_b == NULL, random data is used for b. + * + * Returns pointer to SRPVerifier on success, and NULL on error. + */ +struct SRPVerifier* srp_verifier_new(SRP_HashAlgorithm alg, SRP_NGType ng_type, + const char *username, + const unsigned char *bytes_s, size_t len_s, + const unsigned char *bytes_v, size_t len_v, + const unsigned char *bytes_A, size_t len_A, + const unsigned char *bytes_b, size_t len_b, + unsigned char** bytes_B, size_t *len_B, + const char* n_hex, const char* g_hex); + +// clang-format on + +void srp_verifier_delete(struct SRPVerifier *ver); + +// srp_verifier_verify_session must have been called before +int srp_verifier_is_authenticated(struct SRPVerifier *ver); + +const char *srp_verifier_get_username(struct SRPVerifier *ver); + +/* key_length may be null */ +const unsigned char *srp_verifier_get_session_key( + struct SRPVerifier *ver, size_t *key_length); + +size_t srp_verifier_get_session_key_length(struct SRPVerifier *ver); + +/* Verifies session, on success, it writes bytes_HAMK. + * user_M must be exactly srp_verifier_get_session_key_length() bytes in size + */ +void srp_verifier_verify_session( + struct SRPVerifier *ver, const unsigned char *user_M, unsigned char **bytes_HAMK); + +/*******************************************************************************/ + +/* The n_hex and g_hex parameters should be 0 unless SRP_NG_CUSTOM is used for ng_type */ +struct SRPUser *srp_user_new(SRP_HashAlgorithm alg, SRP_NGType ng_type, + const char *username, const char *username_for_verifier, + const unsigned char *bytes_password, size_t len_password, const char *n_hex, + const char *g_hex); + +void srp_user_delete(struct SRPUser *usr); + +int srp_user_is_authenticated(struct SRPUser *usr); + +const char *srp_user_get_username(struct SRPUser *usr); + +/* key_length may be null */ +const unsigned char *srp_user_get_session_key(struct SRPUser *usr, size_t *key_length); + +size_t srp_user_get_session_key_length(struct SRPUser *usr); + +// clang-format off + +/* Output: username, bytes_A, len_A. + * If you don't want it get written, set username to NULL. + * If bytes_a == NULL, random data is used for a. */ +SRP_Result srp_user_start_authentication(struct SRPUser* usr, char **username, + const unsigned char *bytes_a, size_t len_a, + unsigned char **bytes_A, size_t* len_A); + +/* Output: bytes_M, len_M (len_M may be null and will always be + * srp_user_get_session_key_length() bytes in size) */ +void srp_user_process_challenge(struct SRPUser *usr, + const unsigned char *bytes_s, size_t len_s, + const unsigned char *bytes_B, size_t len_B, + unsigned char **bytes_M, size_t *len_M); +// clang-format on + +/* bytes_HAMK must be exactly srp_user_get_session_key_length() bytes in size */ +void srp_user_verify_session(struct SRPUser *usr, const unsigned char *bytes_HAMK); diff --git a/src/util/stream.h b/src/util/stream.h new file mode 100644 index 0000000..2e61b46 --- /dev/null +++ b/src/util/stream.h @@ -0,0 +1,70 @@ +/* +Minetest +Copyright (C) 2022 Minetest Authors + +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.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <iostream> +#include <string> +#include <functional> + +template<int BufferLength, typename Emitter = std::function<void(const std::string &)> > +class StringStreamBuffer : public std::streambuf { +public: + StringStreamBuffer(Emitter emitter) : m_emitter(emitter) { + buffer_index = 0; + } + + int overflow(int c) { + push_back(c); + return c; + } + + void push_back(char c) { + if (c == '\n' || c == '\r') { + if (buffer_index) + m_emitter(std::string(buffer, buffer_index)); + buffer_index = 0; + } else { + buffer[buffer_index++] = c; + if (buffer_index >= BufferLength) { + m_emitter(std::string(buffer, buffer_index)); + buffer_index = 0; + } + } + } + + std::streamsize xsputn(const char *s, std::streamsize n) { + for (int i = 0; i < n; ++i) + push_back(s[i]); + return n; + } +private: + Emitter m_emitter; + char buffer[BufferLength]; + int buffer_index; +}; + +class DummyStreamBuffer : public std::streambuf { + int overflow(int c) { + return c; + } + std::streamsize xsputn(const char *s, std::streamsize n) { + return n; + } +}; diff --git a/src/util/strfnd.h b/src/util/strfnd.h new file mode 100644 index 0000000..96cf1b4 --- /dev/null +++ b/src/util/strfnd.h @@ -0,0 +1,78 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include <string> + +template <typename T> +class BasicStrfnd { + typedef std::basic_string<T> String; + String str; + size_t pos; +public: + BasicStrfnd(const String &s) : str(s), pos(0) {} + void start(const String &s) { str = s; pos = 0; } + size_t where() { return pos; } + void to(size_t i) { pos = i; } + bool at_end() { return pos >= str.size(); } + String what() { return str; } + + String next(const String &sep) + { + if (pos >= str.size()) + return String(); + + size_t n; + if (sep.empty() || (n = str.find(sep, pos)) == String::npos) { + n = str.size(); + } + String ret = str.substr(pos, n - pos); + pos = n + sep.size(); + return ret; + } + + // Returns substr up to the next occurence of sep that isn't escaped with esc ('\\') + String next_esc(const String &sep, T esc=static_cast<T>('\\')) + { + if (pos >= str.size()) + return String(); + + size_t n, old_p = pos; + do { + if (sep.empty() || (n = str.find(sep, pos)) == String::npos) { + pos = n = str.size(); + break; + } + pos = n + sep.length(); + } while (n > 0 && str[n - 1] == esc); + + return str.substr(old_p, n - old_p); + } + + void skip_over(const String &chars) + { + size_t p = str.find_first_not_of(chars, pos); + if (p != String::npos) + pos = p; + } +}; + +typedef BasicStrfnd<char> Strfnd; +typedef BasicStrfnd<wchar_t> WStrfnd; diff --git a/src/util/string.cpp b/src/util/string.cpp new file mode 100644 index 0000000..778e4d1 --- /dev/null +++ b/src/util/string.cpp @@ -0,0 +1,908 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "string.h" +#include "pointer.h" +#include "numeric.h" +#include "log.h" + +#include "hex.h" +#include "porting.h" +#include "translation.h" + +#include <algorithm> +#include <array> +#include <sstream> +#include <iomanip> +#include <unordered_map> + +#ifndef _WIN32 + #include <iconv.h> +#else + #define _WIN32_WINNT 0x0501 + #include <windows.h> +#endif + +#ifndef _WIN32 + +static bool convert(const char *to, const char *from, char *outbuf, + size_t *outbuf_size, char *inbuf, size_t inbuf_size) +{ + iconv_t cd = iconv_open(to, from); + + char *inbuf_ptr = inbuf; + char *outbuf_ptr = outbuf; + + size_t *inbuf_left_ptr = &inbuf_size; + + const size_t old_outbuf_size = *outbuf_size; + size_t old_size = inbuf_size; + while (inbuf_size > 0) { + iconv(cd, &inbuf_ptr, inbuf_left_ptr, &outbuf_ptr, outbuf_size); + if (inbuf_size == old_size) { + iconv_close(cd); + return false; + } + old_size = inbuf_size; + } + + iconv_close(cd); + *outbuf_size = old_outbuf_size - *outbuf_size; + return true; +} + +#ifdef __ANDROID__ +// On Android iconv disagrees how big a wchar_t is for whatever reason +const char *DEFAULT_ENCODING = "UTF-32LE"; +#elif defined(__NetBSD__) || defined(__OpenBSD__) + // NetBSD does not allow "WCHAR_T" as a charset input to iconv. + #include <sys/endian.h> + #if BYTE_ORDER == BIG_ENDIAN + const char *DEFAULT_ENCODING = "UTF-32BE"; + #else + const char *DEFAULT_ENCODING = "UTF-32LE"; + #endif +#else +const char *DEFAULT_ENCODING = "WCHAR_T"; +#endif + +std::wstring utf8_to_wide(const std::string &input) +{ + const size_t inbuf_size = input.length(); + // maximum possible size, every character is sizeof(wchar_t) bytes + size_t outbuf_size = input.length() * sizeof(wchar_t); + + char *inbuf = new char[inbuf_size]; // intentionally NOT null-terminated + memcpy(inbuf, input.c_str(), inbuf_size); + std::wstring out; + out.resize(outbuf_size / sizeof(wchar_t)); + +#if defined(__ANDROID__) || defined(__NetBSD__) || defined(__OpenBSD__) + static_assert(sizeof(wchar_t) == 4, "Unexpected wide char size"); +#endif + + char *outbuf = reinterpret_cast<char*>(&out[0]); + if (!convert(DEFAULT_ENCODING, "UTF-8", outbuf, &outbuf_size, inbuf, inbuf_size)) { + infostream << "Couldn't convert UTF-8 string 0x" << hex_encode(input) + << " into wstring" << std::endl; + delete[] inbuf; + return L"<invalid UTF-8 string>"; + } + delete[] inbuf; + + out.resize(outbuf_size / sizeof(wchar_t)); + return out; +} + +std::string wide_to_utf8(const std::wstring &input) +{ + const size_t inbuf_size = input.length() * sizeof(wchar_t); + // maximum possible size: utf-8 encodes codepoints using 1 up to 4 bytes + size_t outbuf_size = input.length() * 4; + + char *inbuf = new char[inbuf_size]; // intentionally NOT null-terminated + memcpy(inbuf, input.c_str(), inbuf_size); + std::string out; + out.resize(outbuf_size); + + if (!convert("UTF-8", DEFAULT_ENCODING, &out[0], &outbuf_size, inbuf, inbuf_size)) { + infostream << "Couldn't convert wstring 0x" << hex_encode(inbuf, inbuf_size) + << " into UTF-8 string" << std::endl; + delete[] inbuf; + return "<invalid wide string>"; + } + delete[] inbuf; + + out.resize(outbuf_size); + return out; +} + +#else // _WIN32 + +std::wstring utf8_to_wide(const std::string &input) +{ + size_t outbuf_size = input.size() + 1; + wchar_t *outbuf = new wchar_t[outbuf_size]; + memset(outbuf, 0, outbuf_size * sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, input.c_str(), input.size(), + outbuf, outbuf_size); + std::wstring out(outbuf); + delete[] outbuf; + return out; +} + +std::string wide_to_utf8(const std::wstring &input) +{ + size_t outbuf_size = (input.size() + 1) * 6; + char *outbuf = new char[outbuf_size]; + memset(outbuf, 0, outbuf_size); + WideCharToMultiByte(CP_UTF8, 0, input.c_str(), input.size(), + outbuf, outbuf_size, NULL, NULL); + std::string out(outbuf); + delete[] outbuf; + return out; +} + +#endif // _WIN32 + +wchar_t *utf8_to_wide_c(const char *str) +{ + std::wstring ret = utf8_to_wide(std::string(str)); + size_t len = ret.length(); + wchar_t *ret_c = new wchar_t[len + 1]; + memcpy(ret_c, ret.c_str(), (len + 1) * sizeof(wchar_t)); + return ret_c; +} + + +std::string urlencode(const std::string &str) +{ + // Encodes non-unreserved URI characters by a percent sign + // followed by two hex digits. See RFC 3986, section 2.3. + static const char url_hex_chars[] = "0123456789ABCDEF"; + std::ostringstream oss(std::ios::binary); + for (unsigned char c : str) { + if (isalnum(c) || c == '-' || c == '.' || c == '_' || c == '~') { + oss << c; + } else { + oss << "%" + << url_hex_chars[(c & 0xf0) >> 4] + << url_hex_chars[c & 0x0f]; + } + } + return oss.str(); +} + +std::string urldecode(const std::string &str) +{ + // Inverse of urlencode + std::ostringstream oss(std::ios::binary); + for (u32 i = 0; i < str.size(); i++) { + unsigned char highvalue, lowvalue; + if (str[i] == '%' && + hex_digit_decode(str[i+1], highvalue) && + hex_digit_decode(str[i+2], lowvalue)) { + oss << (char) ((highvalue << 4) | lowvalue); + i += 2; + } else { + oss << str[i]; + } + } + return oss.str(); +} + +u32 readFlagString(std::string str, const FlagDesc *flagdesc, u32 *flagmask) +{ + u32 result = 0; + u32 mask = 0; + char *s = &str[0]; + char *flagstr; + char *strpos = nullptr; + + while ((flagstr = strtok_r(s, ",", &strpos))) { + s = nullptr; + + while (*flagstr == ' ' || *flagstr == '\t') + flagstr++; + + bool flagset = true; + if (!strncasecmp(flagstr, "no", 2)) { + flagset = false; + flagstr += 2; + } + + for (int i = 0; flagdesc[i].name; i++) { + if (!strcasecmp(flagstr, flagdesc[i].name)) { + mask |= flagdesc[i].flag; + if (flagset) + result |= flagdesc[i].flag; + break; + } + } + } + + if (flagmask) + *flagmask = mask; + + return result; +} + +std::string writeFlagString(u32 flags, const FlagDesc *flagdesc, u32 flagmask) +{ + std::string result; + + for (int i = 0; flagdesc[i].name; i++) { + if (flagmask & flagdesc[i].flag) { + if (!(flags & flagdesc[i].flag)) + result += "no"; + + result += flagdesc[i].name; + result += ", "; + } + } + + size_t len = result.length(); + if (len >= 2) + result.erase(len - 2, 2); + + return result; +} + +size_t mystrlcpy(char *dst, const char *src, size_t size) +{ + size_t srclen = strlen(src) + 1; + size_t copylen = MYMIN(srclen, size); + + if (copylen > 0) { + memcpy(dst, src, copylen); + dst[copylen - 1] = '\0'; + } + + return srclen; +} + +char *mystrtok_r(char *s, const char *sep, char **lasts) +{ + char *t; + + if (!s) + s = *lasts; + + while (*s && strchr(sep, *s)) + s++; + + if (!*s) + return nullptr; + + t = s; + while (*t) { + if (strchr(sep, *t)) { + *t++ = '\0'; + break; + } + t++; + } + + *lasts = t; + return s; +} + +u64 read_seed(const char *str) +{ + char *endptr; + u64 num; + + if (str[0] == '0' && str[1] == 'x') + num = strtoull(str, &endptr, 16); + else + num = strtoull(str, &endptr, 10); + + if (*endptr) + num = murmur_hash_64_ua(str, (int)strlen(str), 0x1337); + + return num; +} + +static bool parseHexColorString(const std::string &value, video::SColor &color, + unsigned char default_alpha) +{ + u8 components[] = {0x00, 0x00, 0x00, default_alpha}; // R,G,B,A + + size_t len = value.size(); + bool short_form; + + if (len == 9 || len == 7) // #RRGGBBAA or #RRGGBB + short_form = false; + else if (len == 5 || len == 4) // #RGBA or #RGB + short_form = true; + else + return false; + + for (size_t pos = 1, cc = 0; pos < len; pos++, cc++) { + if (short_form) { + u8 d; + if (!hex_digit_decode(value[pos], d)) + return false; + + components[cc] = (d & 0xf) << 4 | (d & 0xf); + } else { + u8 d1, d2; + if (!hex_digit_decode(value[pos], d1) || + !hex_digit_decode(value[pos+1], d2)) + return false; + + components[cc] = (d1 & 0xf) << 4 | (d2 & 0xf); + pos++; // skip the second digit -- it's already used + } + } + + color.setRed(components[0]); + color.setGreen(components[1]); + color.setBlue(components[2]); + color.setAlpha(components[3]); + + return true; +} + +const static std::unordered_map<std::string, u32> s_named_colors = { + {"aliceblue", 0xf0f8ff}, + {"antiquewhite", 0xfaebd7}, + {"aqua", 0x00ffff}, + {"aquamarine", 0x7fffd4}, + {"azure", 0xf0ffff}, + {"beige", 0xf5f5dc}, + {"bisque", 0xffe4c4}, + {"black", 00000000}, + {"blanchedalmond", 0xffebcd}, + {"blue", 0x0000ff}, + {"blueviolet", 0x8a2be2}, + {"brown", 0xa52a2a}, + {"burlywood", 0xdeb887}, + {"cadetblue", 0x5f9ea0}, + {"chartreuse", 0x7fff00}, + {"chocolate", 0xd2691e}, + {"coral", 0xff7f50}, + {"cornflowerblue", 0x6495ed}, + {"cornsilk", 0xfff8dc}, + {"crimson", 0xdc143c}, + {"cyan", 0x00ffff}, + {"darkblue", 0x00008b}, + {"darkcyan", 0x008b8b}, + {"darkgoldenrod", 0xb8860b}, + {"darkgray", 0xa9a9a9}, + {"darkgreen", 0x006400}, + {"darkgrey", 0xa9a9a9}, + {"darkkhaki", 0xbdb76b}, + {"darkmagenta", 0x8b008b}, + {"darkolivegreen", 0x556b2f}, + {"darkorange", 0xff8c00}, + {"darkorchid", 0x9932cc}, + {"darkred", 0x8b0000}, + {"darksalmon", 0xe9967a}, + {"darkseagreen", 0x8fbc8f}, + {"darkslateblue", 0x483d8b}, + {"darkslategray", 0x2f4f4f}, + {"darkslategrey", 0x2f4f4f}, + {"darkturquoise", 0x00ced1}, + {"darkviolet", 0x9400d3}, + {"deeppink", 0xff1493}, + {"deepskyblue", 0x00bfff}, + {"dimgray", 0x696969}, + {"dimgrey", 0x696969}, + {"dodgerblue", 0x1e90ff}, + {"firebrick", 0xb22222}, + {"floralwhite", 0xfffaf0}, + {"forestgreen", 0x228b22}, + {"fuchsia", 0xff00ff}, + {"gainsboro", 0xdcdcdc}, + {"ghostwhite", 0xf8f8ff}, + {"gold", 0xffd700}, + {"goldenrod", 0xdaa520}, + {"gray", 0x808080}, + {"green", 0x008000}, + {"greenyellow", 0xadff2f}, + {"grey", 0x808080}, + {"honeydew", 0xf0fff0}, + {"hotpink", 0xff69b4}, + {"indianred", 0xcd5c5c}, + {"indigo", 0x4b0082}, + {"ivory", 0xfffff0}, + {"khaki", 0xf0e68c}, + {"lavender", 0xe6e6fa}, + {"lavenderblush", 0xfff0f5}, + {"lawngreen", 0x7cfc00}, + {"lemonchiffon", 0xfffacd}, + {"lightblue", 0xadd8e6}, + {"lightcoral", 0xf08080}, + {"lightcyan", 0xe0ffff}, + {"lightgoldenrodyellow", 0xfafad2}, + {"lightgray", 0xd3d3d3}, + {"lightgreen", 0x90ee90}, + {"lightgrey", 0xd3d3d3}, + {"lightpink", 0xffb6c1}, + {"lightsalmon", 0xffa07a}, + {"lightseagreen", 0x20b2aa}, + {"lightskyblue", 0x87cefa}, + {"lightslategray", 0x778899}, + {"lightslategrey", 0x778899}, + {"lightsteelblue", 0xb0c4de}, + {"lightyellow", 0xffffe0}, + {"lime", 0x00ff00}, + {"limegreen", 0x32cd32}, + {"linen", 0xfaf0e6}, + {"magenta", 0xff00ff}, + {"maroon", 0x800000}, + {"mediumaquamarine", 0x66cdaa}, + {"mediumblue", 0x0000cd}, + {"mediumorchid", 0xba55d3}, + {"mediumpurple", 0x9370db}, + {"mediumseagreen", 0x3cb371}, + {"mediumslateblue", 0x7b68ee}, + {"mediumspringgreen", 0x00fa9a}, + {"mediumturquoise", 0x48d1cc}, + {"mediumvioletred", 0xc71585}, + {"midnightblue", 0x191970}, + {"mintcream", 0xf5fffa}, + {"mistyrose", 0xffe4e1}, + {"moccasin", 0xffe4b5}, + {"navajowhite", 0xffdead}, + {"navy", 0x000080}, + {"oldlace", 0xfdf5e6}, + {"olive", 0x808000}, + {"olivedrab", 0x6b8e23}, + {"orange", 0xffa500}, + {"orangered", 0xff4500}, + {"orchid", 0xda70d6}, + {"palegoldenrod", 0xeee8aa}, + {"palegreen", 0x98fb98}, + {"paleturquoise", 0xafeeee}, + {"palevioletred", 0xdb7093}, + {"papayawhip", 0xffefd5}, + {"peachpuff", 0xffdab9}, + {"peru", 0xcd853f}, + {"pink", 0xffc0cb}, + {"plum", 0xdda0dd}, + {"powderblue", 0xb0e0e6}, + {"purple", 0x800080}, + {"rebeccapurple", 0x663399}, + {"red", 0xff0000}, + {"rosybrown", 0xbc8f8f}, + {"royalblue", 0x4169e1}, + {"saddlebrown", 0x8b4513}, + {"salmon", 0xfa8072}, + {"sandybrown", 0xf4a460}, + {"seagreen", 0x2e8b57}, + {"seashell", 0xfff5ee}, + {"sienna", 0xa0522d}, + {"silver", 0xc0c0c0}, + {"skyblue", 0x87ceeb}, + {"slateblue", 0x6a5acd}, + {"slategray", 0x708090}, + {"slategrey", 0x708090}, + {"snow", 0xfffafa}, + {"springgreen", 0x00ff7f}, + {"steelblue", 0x4682b4}, + {"tan", 0xd2b48c}, + {"teal", 0x008080}, + {"thistle", 0xd8bfd8}, + {"tomato", 0xff6347}, + {"turquoise", 0x40e0d0}, + {"violet", 0xee82ee}, + {"wheat", 0xf5deb3}, + {"white", 0xffffff}, + {"whitesmoke", 0xf5f5f5}, + {"yellow", 0xffff00}, + {"yellowgreen", 0x9acd32} +}; + +static bool parseNamedColorString(const std::string &value, video::SColor &color) +{ + std::string color_name; + std::string alpha_string; + + /* If the string has a # in it, assume this is the start of a specified + * alpha value (if it isn't the string is invalid and the error will be + * caught later on, either because the color name won't be found or the + * alpha value will fail conversion) + */ + size_t alpha_pos = value.find('#'); + if (alpha_pos != std::string::npos) { + color_name = value.substr(0, alpha_pos); + alpha_string = value.substr(alpha_pos + 1); + } else { + color_name = value; + } + + color_name = lowercase(color_name); + + auto it = s_named_colors.find(color_name); + if (it == s_named_colors.end()) + return false; + + u32 color_temp = it->second; + + /* An empty string for alpha is ok (none of the color table entries + * have an alpha value either). Color strings without an alpha specified + * are interpreted as fully opaque + */ + if (!alpha_string.empty()) { + if (alpha_string.size() == 1) { + u8 d; + if (!hex_digit_decode(alpha_string[0], d)) + return false; + + color_temp |= ((d & 0xf) << 4 | (d & 0xf)) << 24; + } else if (alpha_string.size() == 2) { + u8 d1, d2; + if (!hex_digit_decode(alpha_string[0], d1) + || !hex_digit_decode(alpha_string[1], d2)) + return false; + + color_temp |= ((d1 & 0xf) << 4 | (d2 & 0xf)) << 24; + } else { + return false; + } + } else { + color_temp |= 0xff << 24; // Fully opaque + } + + color = video::SColor(color_temp); + + return true; +} + +bool parseColorString(const std::string &value, video::SColor &color, bool quiet, + unsigned char default_alpha) +{ + bool success; + + if (value[0] == '#') + success = parseHexColorString(value, color, default_alpha); + else + success = parseNamedColorString(value, color); + + if (!success && !quiet) + errorstream << "Invalid color: \"" << value << "\"" << std::endl; + + return success; +} + +void str_replace(std::string &str, char from, char to) +{ + std::replace(str.begin(), str.end(), from, to); +} + +/* Translated strings have the following format: + * \x1bT marks the beginning of a translated string + * \x1bE marks its end + * + * \x1bF marks the beginning of an argument, and \x1bE its end. + * + * Arguments are *not* translated, as they may contain escape codes. + * Thus, if you want a translated argument, it should be inside \x1bT/\x1bE tags as well. + * + * This representation is chosen so that clients ignoring escape codes will + * see untranslated strings. + * + * For instance, suppose we have a string such as "@1 Wool" with the argument "White" + * The string will be sent as "\x1bT\x1bF\x1bTWhite\x1bE\x1bE Wool\x1bE" + * To translate this string, we extract what is inside \x1bT/\x1bE tags. + * When we notice the \x1bF tag, we recursively extract what is there up to the \x1bE end tag, + * translating it as well. + * We get the argument "White", translated, and create a template string with "@1" instead of it. + * We finally get the template "@1 Wool" that was used in the beginning, which we translate + * before filling it again. + */ + +void translate_all(const std::wstring &s, size_t &i, + Translations *translations, std::wstring &res); + +void translate_string(const std::wstring &s, Translations *translations, + const std::wstring &textdomain, size_t &i, std::wstring &res) +{ + std::wostringstream output; + std::vector<std::wstring> args; + int arg_number = 1; + while (i < s.length()) { + // Not an escape sequence: just add the character. + if (s[i] != '\x1b') { + output.put(s[i]); + // The character is a literal '@'; add it twice + // so that it is not mistaken for an argument. + if (s[i] == L'@') + output.put(L'@'); + ++i; + continue; + } + + // We have an escape sequence: locate it and its data + // It is either a single character, or it begins with '(' + // and extends up to the following ')', with '\' as an escape character. + ++i; + size_t start_index = i; + size_t length; + if (i == s.length()) { + length = 0; + } else if (s[i] == L'(') { + ++i; + ++start_index; + while (i < s.length() && s[i] != L')') { + if (s[i] == L'\\') + ++i; + ++i; + } + length = i - start_index; + ++i; + if (i > s.length()) + i = s.length(); + } else { + ++i; + length = 1; + } + std::wstring escape_sequence(s, start_index, length); + + // The escape sequence is now reconstructed. + std::vector<std::wstring> parts = split(escape_sequence, L'@'); + if (parts[0] == L"E") { + // "End of translation" escape sequence. We are done locating the string to translate. + break; + } else if (parts[0] == L"F") { + // "Start of argument" escape sequence. + // Recursively translate the argument, and add it to the argument list. + // Add an "@n" instead of the argument to the template to translate. + if (arg_number >= 10) { + errorstream << "Ignoring too many arguments to translation" << std::endl; + std::wstring arg; + translate_all(s, i, translations, arg); + args.push_back(arg); + continue; + } + output.put(L'@'); + output << arg_number; + ++arg_number; + std::wstring arg; + translate_all(s, i, translations, arg); + args.push_back(arg); + } else { + // This is an escape sequence *inside* the template string to translate itself. + // This should not happen, show an error message. + errorstream << "Ignoring escape sequence '" + << wide_to_utf8(escape_sequence) << "' in translation" << std::endl; + } + } + + std::wstring toutput; + // Translate the template. + if (translations != nullptr) + toutput = translations->getTranslation( + textdomain, output.str()); + else + toutput = output.str(); + + // Put back the arguments in the translated template. + std::wostringstream result; + size_t j = 0; + while (j < toutput.length()) { + // Normal character, add it to output and continue. + if (toutput[j] != L'@' || j == toutput.length() - 1) { + result.put(toutput[j]); + ++j; + continue; + } + + ++j; + // Literal escape for '@'. + if (toutput[j] == L'@') { + result.put(L'@'); + ++j; + continue; + } + + // Here we have an argument; get its index and add the translated argument to the output. + int arg_index = toutput[j] - L'1'; + ++j; + if (0 <= arg_index && (size_t)arg_index < args.size()) { + result << args[arg_index]; + } else { + // This is not allowed: show an error message + errorstream << "Ignoring out-of-bounds argument escape sequence in translation" << std::endl; + } + } + res = result.str(); +} + +void translate_all(const std::wstring &s, size_t &i, + Translations *translations, std::wstring &res) +{ + std::wostringstream output; + while (i < s.length()) { + // Not an escape sequence: just add the character. + if (s[i] != '\x1b') { + output.put(s[i]); + ++i; + continue; + } + + // We have an escape sequence: locate it and its data + // It is either a single character, or it begins with '(' + // and extends up to the following ')', with '\' as an escape character. + size_t escape_start = i; + ++i; + size_t start_index = i; + size_t length; + if (i == s.length()) { + length = 0; + } else if (s[i] == L'(') { + ++i; + ++start_index; + while (i < s.length() && s[i] != L')') { + if (s[i] == L'\\') { + ++i; + } + ++i; + } + length = i - start_index; + ++i; + if (i > s.length()) + i = s.length(); + } else { + ++i; + length = 1; + } + std::wstring escape_sequence(s, start_index, length); + + // The escape sequence is now reconstructed. + std::vector<std::wstring> parts = split(escape_sequence, L'@'); + if (parts[0] == L"E") { + // "End of argument" escape sequence. Exit. + break; + } else if (parts[0] == L"T") { + // Beginning of translated string. + std::wstring textdomain; + if (parts.size() > 1) + textdomain = parts[1]; + std::wstring translated; + translate_string(s, translations, textdomain, i, translated); + output << translated; + } else { + // Another escape sequence, such as colors. Preserve it. + output << std::wstring(s, escape_start, i - escape_start); + } + } + + res = output.str(); +} + +// Translate string server side +std::wstring translate_string(const std::wstring &s, Translations *translations) +{ + size_t i = 0; + std::wstring res; + translate_all(s, i, translations, res); + return res; +} + +// Translate string client side +std::wstring translate_string(const std::wstring &s) +{ +#ifdef SERVER + return translate_string(s, nullptr); +#else + return translate_string(s, g_client_translations); +#endif +} + +static const std::array<std::wstring, 30> disallowed_dir_names = { + // Problematic filenames from here: + // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#file-and-directory-names + // Plus undocumented values from here: + // https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html + L"CON", + L"PRN", + L"AUX", + L"NUL", + L"COM1", + L"COM2", + L"COM3", + L"COM4", + L"COM5", + L"COM6", + L"COM7", + L"COM8", + L"COM9", + L"COM\u00B2", + L"COM\u00B3", + L"COM\u00B9", + L"LPT1", + L"LPT2", + L"LPT3", + L"LPT4", + L"LPT5", + L"LPT6", + L"LPT7", + L"LPT8", + L"LPT9", + L"LPT\u00B2", + L"LPT\u00B3", + L"LPT\u00B9", + L"CONIN$", + L"CONOUT$", +}; + +/** + * List of characters that are blacklisted from created directories + */ +static const std::wstring disallowed_path_chars = L"<>:\"/\\|?*."; + + +std::string sanitizeDirName(const std::string &str, const std::string &optional_prefix) +{ + std::wstring safe_name = utf8_to_wide(str); + + for (std::wstring disallowed_name : disallowed_dir_names) { + if (str_equal(safe_name, disallowed_name, true)) { + safe_name = utf8_to_wide(optional_prefix) + safe_name; + break; + } + } + + // Replace leading and trailing spaces with underscores. + size_t start = safe_name.find_first_not_of(L' '); + size_t end = safe_name.find_last_not_of(L' '); + if (start == std::wstring::npos || end == std::wstring::npos) + start = end = safe_name.size(); + for (size_t i = 0; i < start; i++) + safe_name[i] = L'_'; + for (size_t i = end + 1; i < safe_name.size(); i++) + safe_name[i] = L'_'; + + // Replace other disallowed characters with underscores + for (size_t i = 0; i < safe_name.length(); i++) { + bool is_valid = true; + + // Unlikely, but control characters should always be blacklisted + if (safe_name[i] < 32) { + is_valid = false; + } else if (safe_name[i] < 128) { + is_valid = disallowed_path_chars.find_first_of(safe_name[i]) + == std::wstring::npos; + } + + if (!is_valid) + safe_name[i] = L'_'; + } + + return wide_to_utf8(safe_name); +} + + +void safe_print_string(std::ostream &os, const std::string &str) +{ + std::ostream::fmtflags flags = os.flags(); + os << std::hex; + for (const char c : str) { + if (IS_ASCII_PRINTABLE_CHAR(c) || IS_UTF8_MULTB_START(c) || + IS_UTF8_MULTB_INNER(c) || c == '\n' || c == '\t') { + os << c; + } else { + os << '<' << std::setw(2) << (int)c << '>'; + } + } + os.setf(flags); +} diff --git a/src/util/string.h b/src/util/string.h new file mode 100644 index 0000000..aa4329f --- /dev/null +++ b/src/util/string.h @@ -0,0 +1,763 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes_bloated.h" +#include "irrString.h" +#include <cstdlib> +#include <string> +#include <cstring> +#include <vector> +#include <map> +#include <sstream> +#include <iomanip> +#include <cctype> +#include <unordered_map> + +class Translations; + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +// Checks whether a value is an ASCII printable character +#define IS_ASCII_PRINTABLE_CHAR(x) \ + (((unsigned int)(x) >= 0x20) && \ + ( (unsigned int)(x) <= 0x7e)) + +// Checks whether a byte is an inner byte for an utf-8 multibyte sequence +#define IS_UTF8_MULTB_INNER(x) \ + (((unsigned char)(x) >= 0x80) && \ + ( (unsigned char)(x) <= 0xbf)) + +// Checks whether a byte is a start byte for an utf-8 multibyte sequence +#define IS_UTF8_MULTB_START(x) \ + (((unsigned char)(x) >= 0xc2) && \ + ( (unsigned char)(x) <= 0xf4)) + +// Given a start byte x for an utf-8 multibyte sequence +// it gives the length of the whole sequence in bytes. +#define UTF8_MULTB_START_LEN(x) \ + (((unsigned char)(x) < 0xe0) ? 2 : \ + (((unsigned char)(x) < 0xf0) ? 3 : 4)) + +typedef std::unordered_map<std::string, std::string> StringMap; + +struct FlagDesc { + const char *name; + u32 flag; +}; + +// Try to avoid converting between wide and UTF-8 unless you need to +// input/output stuff via Irrlicht +std::wstring utf8_to_wide(const std::string &input); +std::string wide_to_utf8(const std::wstring &input); + +// You must free the returned string! +// The returned string is allocated using new[] +wchar_t *utf8_to_wide_c(const char *str); + +std::string urlencode(const std::string &str); +std::string urldecode(const std::string &str); +u32 readFlagString(std::string str, const FlagDesc *flagdesc, u32 *flagmask); +std::string writeFlagString(u32 flags, const FlagDesc *flagdesc, u32 flagmask); +size_t mystrlcpy(char *dst, const char *src, size_t size); +char *mystrtok_r(char *s, const char *sep, char **lasts); +u64 read_seed(const char *str); +bool parseColorString(const std::string &value, video::SColor &color, bool quiet, + unsigned char default_alpha = 0xff); + + +/** + * Returns a copy of \p str with spaces inserted at the right hand side to ensure + * that the string is \p len characters in length. If \p str is <= \p len then the + * returned string will be identical to str. + */ +inline std::string padStringRight(std::string str, size_t len) +{ + if (len > str.size()) + str.insert(str.end(), len - str.size(), ' '); + + return str; +} + +/** + * Returns a version of \p str with the first occurrence of a string + * contained within ends[] removed from the end of the string. + * + * @param str + * @param ends A NULL- or ""- terminated array of strings to remove from s in + * the copy produced. Note that once one of these strings is removed + * that no further postfixes contained within this array are removed. + * + * @return If no end could be removed then "" is returned. + */ +inline std::string removeStringEnd(const std::string &str, + const char *ends[]) +{ + const char **p = ends; + + for (; *p && (*p)[0] != '\0'; p++) { + std::string end = *p; + if (str.size() < end.size()) + continue; + if (str.compare(str.size() - end.size(), end.size(), end) == 0) + return str.substr(0, str.size() - end.size()); + } + + return ""; +} + + +/** + * Check two strings for equivalence. If \p case_insensitive is true + * then the case of the strings is ignored (default is false). + * + * @param s1 + * @param s2 + * @param case_insensitive + * @return true if the strings match + */ +template <typename T> +inline bool str_equal(const std::basic_string<T> &s1, + const std::basic_string<T> &s2, + bool case_insensitive = false) +{ + if (!case_insensitive) + return s1 == s2; + + if (s1.size() != s2.size()) + return false; + + for (size_t i = 0; i < s1.size(); ++i) + if(tolower(s1[i]) != tolower(s2[i])) + return false; + + return true; +} + + +/** + * Check whether \p str begins with the string prefix. If \p case_insensitive + * is true then the check is case insensitve (default is false; i.e. case is + * significant). + * + * @param str + * @param prefix + * @param case_insensitive + * @return true if the str begins with prefix + */ +template <typename T> +inline bool str_starts_with(const std::basic_string<T> &str, + const std::basic_string<T> &prefix, + bool case_insensitive = false) +{ + if (str.size() < prefix.size()) + return false; + + if (!case_insensitive) + return str.compare(0, prefix.size(), prefix) == 0; + + for (size_t i = 0; i < prefix.size(); ++i) + if (tolower(str[i]) != tolower(prefix[i])) + return false; + return true; +} + +/** + * Check whether \p str begins with the string prefix. If \p case_insensitive + * is true then the check is case insensitve (default is false; i.e. case is + * significant). + * + * @param str + * @param prefix + * @param case_insensitive + * @return true if the str begins with prefix + */ +template <typename T> +inline bool str_starts_with(const std::basic_string<T> &str, + const T *prefix, + bool case_insensitive = false) +{ + return str_starts_with(str, std::basic_string<T>(prefix), + case_insensitive); +} + + +/** + * Check whether \p str ends with the string suffix. If \p case_insensitive + * is true then the check is case insensitve (default is false; i.e. case is + * significant). + * + * @param str + * @param suffix + * @param case_insensitive + * @return true if the str begins with suffix + */ +template <typename T> +inline bool str_ends_with(const std::basic_string<T> &str, + const std::basic_string<T> &suffix, + bool case_insensitive = false) +{ + if (str.size() < suffix.size()) + return false; + + size_t start = str.size() - suffix.size(); + if (!case_insensitive) + return str.compare(start, suffix.size(), suffix) == 0; + + for (size_t i = 0; i < suffix.size(); ++i) + if (tolower(str[start + i]) != tolower(suffix[i])) + return false; + return true; +} + + +/** + * Check whether \p str ends with the string suffix. If \p case_insensitive + * is true then the check is case insensitve (default is false; i.e. case is + * significant). + * + * @param str + * @param suffix + * @param case_insensitive + * @return true if the str begins with suffix + */ +template <typename T> +inline bool str_ends_with(const std::basic_string<T> &str, + const T *suffix, + bool case_insensitive = false) +{ + return str_ends_with(str, std::basic_string<T>(suffix), + case_insensitive); +} + + +/** + * Splits a string into its component parts separated by the character + * \p delimiter. + * + * @return An std::vector<std::basic_string<T> > of the component parts + */ +template <typename T> +inline std::vector<std::basic_string<T> > str_split( + const std::basic_string<T> &str, + T delimiter) +{ + std::vector<std::basic_string<T> > parts; + std::basic_stringstream<T> sstr(str); + std::basic_string<T> part; + + while (std::getline(sstr, part, delimiter)) + parts.push_back(part); + + return parts; +} + + +/** + * @param str + * @return A copy of \p str converted to all lowercase characters. + */ +inline std::string lowercase(const std::string &str) +{ + std::string s2; + + s2.reserve(str.size()); + + for (char i : str) + s2 += tolower(i); + + return s2; +} + + +/** + * @param str + * @return A copy of \p str with leading and trailing whitespace removed. + */ +inline std::string trim(const std::string &str) +{ + size_t front = 0; + size_t back = str.size(); + + while (front < back && std::isspace(str[front])) + ++front; + + while (back > front && std::isspace(str[back - 1])) + --back; + + return str.substr(front, back - front); +} + + +/** + * Returns whether \p str should be regarded as (bool) true. Case and leading + * and trailing whitespace are ignored. Values that will return + * true are "y", "yes", "true" and any number that is not 0. + * @param str + */ +inline bool is_yes(const std::string &str) +{ + std::string s2 = lowercase(trim(str)); + + return s2 == "y" || s2 == "yes" || s2 == "true" || atoi(s2.c_str()) != 0; +} + + +/** + * Converts the string \p str to a signed 32-bit integer. The converted value + * is constrained so that min <= value <= max. + * + * @see atoi(3) for limitations + * + * @param str + * @param min Range minimum + * @param max Range maximum + * @return The value converted to a signed 32-bit integer and constrained + * within the range defined by min and max (inclusive) + */ +inline s32 mystoi(const std::string &str, s32 min, s32 max) +{ + s32 i = atoi(str.c_str()); + + if (i < min) + i = min; + if (i > max) + i = max; + + return i; +} + +/** + * Returns a 32-bit value reprensented by the string \p str (decimal). + * @see atoi(3) for further limitations + */ +inline s32 mystoi(const std::string &str) +{ + return atoi(str.c_str()); +} + +/** + * Returns a float reprensented by the string \p str (decimal). + * @see atof(3) + */ +inline float mystof(const std::string &str) +{ + return atof(str.c_str()); +} + +#define stoi mystoi +#define stof mystof + +/// Returns a value represented by the string \p val. +template <typename T> +inline T from_string(const std::string &str) +{ + std::stringstream tmp(str); + T t; + tmp >> t; + return t; +} + +/// Returns a 64-bit signed value represented by the string \p str (decimal). +inline s64 stoi64(const std::string &str) { return from_string<s64>(str); } + +#if __cplusplus < 201103L +namespace std { + +/// Returns a string representing the value \p val. +template <typename T> +inline string to_string(T val) +{ + ostringstream oss; + oss << val; + return oss.str(); +} +#define DEFINE_STD_TOSTRING_FLOATINGPOINT(T) \ + template <> \ + inline string to_string<T>(T val) \ + { \ + ostringstream oss; \ + oss << std::fixed \ + << std::setprecision(6) \ + << val; \ + return oss.str(); \ + } +DEFINE_STD_TOSTRING_FLOATINGPOINT(float) +DEFINE_STD_TOSTRING_FLOATINGPOINT(double) +DEFINE_STD_TOSTRING_FLOATINGPOINT(long double) + +#undef DEFINE_STD_TOSTRING_FLOATINGPOINT + +/// Returns a wide string representing the value \p val +template <typename T> +inline wstring to_wstring(T val) +{ + return utf8_to_wide(to_string(val)); +} +} +#endif + +/// Returns a string representing the decimal value of the 32-bit value \p i. +inline std::string itos(s32 i) { return std::to_string(i); } +/// Returns a string representing the decimal value of the 64-bit value \p i. +inline std::string i64tos(s64 i) { return std::to_string(i); } + +// std::to_string uses the '%.6f' conversion, which is inconsistent with +// std::ostream::operator<<() and impractical too. ftos() uses the +// more generic and std::ostream::operator<<()-compatible '%G' format. +/// Returns a string representing the decimal value of the float value \p f. +inline std::string ftos(float f) +{ + std::ostringstream oss; + oss << f; + return oss.str(); +} + + +/** + * Replace all occurrences of \p pattern in \p str with \p replacement. + * + * @param str String to replace pattern with replacement within. + * @param pattern The pattern to replace. + * @param replacement What to replace the pattern with. + */ +inline void str_replace(std::string &str, const std::string &pattern, + const std::string &replacement) +{ + std::string::size_type start = str.find(pattern, 0); + while (start != str.npos) { + str.replace(start, pattern.size(), replacement); + start = str.find(pattern, start + replacement.size()); + } +} + +/** + * Escapes characters [ ] \ , ; that can not be used in formspecs + */ +inline void str_formspec_escape(std::string &str) +{ + str_replace(str, "\\", "\\\\"); + str_replace(str, "]", "\\]"); + str_replace(str, "[", "\\["); + str_replace(str, ";", "\\;"); + str_replace(str, ",", "\\,"); +} + +/** + * Replace all occurrences of the character \p from in \p str with \p to. + * + * @param str The string to (potentially) modify. + * @param from The character in str to replace. + * @param to The replacement character. + */ +void str_replace(std::string &str, char from, char to); + + +/** + * Check that a string only contains whitelisted characters. This is the + * opposite of string_allowed_blacklist(). + * + * @param str The string to be checked. + * @param allowed_chars A string containing permitted characters. + * @return true if the string is allowed, otherwise false. + * + * @see string_allowed_blacklist() + */ +inline bool string_allowed(const std::string &str, const std::string &allowed_chars) +{ + return str.find_first_not_of(allowed_chars) == str.npos; +} + + +/** + * Check that a string contains no blacklisted characters. This is the + * opposite of string_allowed(). + * + * @param str The string to be checked. + * @param blacklisted_chars A string containing prohibited characters. + * @return true if the string is allowed, otherwise false. + + * @see string_allowed() + */ +inline bool string_allowed_blacklist(const std::string &str, + const std::string &blacklisted_chars) +{ + return str.find_first_of(blacklisted_chars) == str.npos; +} + + +/** + * Create a string based on \p from where a newline is forcefully inserted + * every \p row_len characters. + * + * @note This function does not honour word wraps and blindy inserts a newline + * every \p row_len characters whether it breaks a word or not. It is + * intended to be used for, for example, showing paths in the GUI. + * + * @note This function doesn't wrap inside utf-8 multibyte sequences and also + * counts multibyte sequences correcly as single characters. + * + * @param from The (utf-8) string to be wrapped into rows. + * @param row_len The row length (in characters). + * @return A new string with the wrapping applied. + */ +inline std::string wrap_rows(const std::string &from, + unsigned row_len) +{ + std::string to; + + size_t character_idx = 0; + for (size_t i = 0; i < from.size(); i++) { + if (!IS_UTF8_MULTB_INNER(from[i])) { + // Wrap string after last inner byte of char + if (character_idx > 0 && character_idx % row_len == 0) + to += '\n'; + character_idx++; + } + to += from[i]; + } + + return to; +} + + +/** + * Removes backslashes from an escaped string (FormSpec strings) + */ +template <typename T> +inline std::basic_string<T> unescape_string(const std::basic_string<T> &s) +{ + std::basic_string<T> res; + + for (size_t i = 0; i < s.length(); i++) { + if (s[i] == '\\') { + i++; + if (i >= s.length()) + break; + } + res += s[i]; + } + + return res; +} + +/** + * Remove all escape sequences in \p s. + * + * @param s The string in which to remove escape sequences. + * @return \p s, with escape sequences removed. + */ +template <typename T> +std::basic_string<T> unescape_enriched(const std::basic_string<T> &s) +{ + std::basic_string<T> output; + size_t i = 0; + while (i < s.length()) { + if (s[i] == '\x1b') { + ++i; + if (i == s.length()) continue; + if (s[i] == '(') { + ++i; + while (i < s.length() && s[i] != ')') { + if (s[i] == '\\') { + ++i; + } + ++i; + } + ++i; + } else { + ++i; + } + continue; + } + output += s[i]; + ++i; + } + return output; +} + +template <typename T> +std::vector<std::basic_string<T> > split(const std::basic_string<T> &s, T delim) +{ + std::vector<std::basic_string<T> > tokens; + + std::basic_string<T> current; + bool last_was_escape = false; + for (size_t i = 0; i < s.length(); i++) { + T si = s[i]; + if (last_was_escape) { + current += '\\'; + current += si; + last_was_escape = false; + } else { + if (si == delim) { + tokens.push_back(current); + current = std::basic_string<T>(); + last_was_escape = false; + } else if (si == '\\') { + last_was_escape = true; + } else { + current += si; + last_was_escape = false; + } + } + } + //push last element + tokens.push_back(current); + + return tokens; +} + +std::wstring translate_string(const std::wstring &s, Translations *translations); + +std::wstring translate_string(const std::wstring &s); + +inline std::wstring unescape_translate(const std::wstring &s) { + return unescape_enriched(translate_string(s)); +} + +/** + * Checks that all characters in \p to_check are a decimal digits. + * + * @param to_check + * @return true if to_check is not empty and all characters in to_check are + * decimal digits, otherwise false + */ +inline bool is_number(const std::string &to_check) +{ + for (char i : to_check) + if (!std::isdigit(i)) + return false; + + return !to_check.empty(); +} + + +/** + * Returns a C-string, either "true" or "false", corresponding to \p val. + * + * @return If \p val is true, then "true" is returned, otherwise "false". + */ +inline const char *bool_to_cstr(bool val) +{ + return val ? "true" : "false"; +} + +/** + * Converts a duration in seconds to a pretty-printed duration in + * days, hours, minutes and seconds. + * + * @param sec duration in seconds + * @return pretty-printed duration + */ +inline const std::string duration_to_string(int sec) +{ + std::ostringstream ss; + const char *neg = ""; + if (sec < 0) { + sec = -sec; + neg = "-"; + } + int total_sec = sec; + int min = sec / 60; + sec %= 60; + int hour = min / 60; + min %= 60; + int day = hour / 24; + hour %= 24; + + if (day > 0) { + ss << neg << day << "d"; + if (hour > 0 || min > 0 || sec > 0) + ss << " "; + } + + if (hour > 0) { + ss << neg << hour << "h"; + if (min > 0 || sec > 0) + ss << " "; + } + + if (min > 0) { + ss << neg << min << "min"; + if (sec > 0) + ss << " "; + } + + if (sec > 0 || total_sec == 0) { + ss << neg << sec << "s"; + } + + return ss.str(); +} + +/** + * Joins a vector of strings by the string \p delimiter. + * + * @return A std::string + */ +inline std::string str_join(const std::vector<std::string> &list, + const std::string &delimiter) +{ + std::ostringstream oss; + bool first = true; + for (const auto &part : list) { + if (!first) + oss << delimiter; + oss << part; + first = false; + } + return oss.str(); +} + +/** + * Create a UTF8 std::string from a irr::core::stringw. + */ +inline std::string stringw_to_utf8(const irr::core::stringw &input) +{ + std::wstring str(input.c_str()); + return wide_to_utf8(str); +} + + /** + * Create a irr::core:stringw from a UTF8 std::string. + */ +inline irr::core::stringw utf8_to_stringw(const std::string &input) +{ + std::wstring str = utf8_to_wide(input); + return irr::core::stringw(str.c_str()); +} + +/** + * Sanitize the name of a new directory. This consists of two stages: + * 1. Check for 'reserved filenames' that can't be used on some filesystems + * and add a prefix to them + * 2. Remove 'unsafe' characters from the name by replacing them with '_' + */ +std::string sanitizeDirName(const std::string &str, const std::string &optional_prefix); + +/** + * Prints a sanitized version of a string without control characters. + * '\t' and '\n' are allowed, as are UTF-8 control characters (e.g. RTL). + * ASCII control characters are replaced with their hex encoding in angle + * brackets (e.g. "a\x1eb" -> "a<1e>b"). + */ +void safe_print_string(std::ostream &os, const std::string &str); diff --git a/src/util/thread.h b/src/util/thread.h new file mode 100644 index 0000000..73e9beb --- /dev/null +++ b/src/util/thread.h @@ -0,0 +1,228 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "threading/thread.h" +#include "threading/mutex_auto_lock.h" +#include "porting.h" +#include "log.h" +#include "container.h" + +template<typename T> +class MutexedVariable +{ +public: + MutexedVariable(const T &value): + m_value(value) + {} + + T get() + { + MutexAutoLock lock(m_mutex); + return m_value; + } + + void set(const T &value) + { + MutexAutoLock lock(m_mutex); + m_value = value; + } + + // You pretty surely want to grab the lock when accessing this + T m_value; +private: + std::mutex m_mutex; +}; + +/* + A single worker thread - multiple client threads queue framework. +*/ +template<typename Key, typename T, typename Caller, typename CallerData> +class GetResult { +public: + Key key; + T item; + std::pair<Caller, CallerData> caller; +}; + +template<typename Key, typename T, typename Caller, typename CallerData> +class ResultQueue : public MutexedQueue<GetResult<Key, T, Caller, CallerData> > { +}; + +template<typename Caller, typename Data, typename Key, typename T> +class CallerInfo { +public: + Caller caller; + Data data; + ResultQueue<Key, T, Caller, Data> *dest; +}; + +template<typename Key, typename T, typename Caller, typename CallerData> +class GetRequest { +public: + GetRequest() = default; + ~GetRequest() = default; + + GetRequest(const Key &a_key): key(a_key) + { + } + + Key key; + std::list<CallerInfo<Caller, CallerData, Key, T> > callers; +}; + +/** + * Notes for RequestQueue usage + * @param Key unique key to identify a request for a specific resource + * @param T ? + * @param Caller unique id of calling thread + * @param CallerData data passed back to caller + */ +template<typename Key, typename T, typename Caller, typename CallerData> +class RequestQueue { +public: + bool empty() + { + return m_queue.empty(); + } + + void add(const Key &key, Caller caller, CallerData callerdata, + ResultQueue<Key, T, Caller, CallerData> *dest) + { + typename std::deque<GetRequest<Key, T, Caller, CallerData> >::iterator i; + typename std::list<CallerInfo<Caller, CallerData, Key, T> >::iterator j; + + { + MutexAutoLock lock(m_queue.getMutex()); + + /* + If the caller is already on the list, only update CallerData + */ + for (i = m_queue.getQueue().begin(); i != m_queue.getQueue().end(); ++i) { + GetRequest<Key, T, Caller, CallerData> &request = *i; + if (request.key != key) + continue; + + for (j = request.callers.begin(); j != request.callers.end(); ++j) { + CallerInfo<Caller, CallerData, Key, T> &ca = *j; + if (ca.caller == caller) { + ca.data = callerdata; + return; + } + } + + CallerInfo<Caller, CallerData, Key, T> ca; + ca.caller = caller; + ca.data = callerdata; + ca.dest = dest; + request.callers.push_back(ca); + return; + } + } + + /* + Else add a new request to the queue + */ + + GetRequest<Key, T, Caller, CallerData> request; + request.key = key; + CallerInfo<Caller, CallerData, Key, T> ca; + ca.caller = caller; + ca.data = callerdata; + ca.dest = dest; + request.callers.push_back(ca); + + m_queue.push_back(request); + } + + GetRequest<Key, T, Caller, CallerData> pop(unsigned int timeout_ms) + { + return m_queue.pop_front(timeout_ms); + } + + GetRequest<Key, T, Caller, CallerData> pop() + { + return m_queue.pop_frontNoEx(); + } + + void pushResult(GetRequest<Key, T, Caller, CallerData> req, T res) + { + for (typename std::list<CallerInfo<Caller, CallerData, Key, T> >::iterator + i = req.callers.begin(); + i != req.callers.end(); ++i) { + CallerInfo<Caller, CallerData, Key, T> &ca = *i; + + GetResult<Key,T,Caller,CallerData> result; + + result.key = req.key; + result.item = res; + result.caller.first = ca.caller; + result.caller.second = ca.data; + + ca.dest->push_back(result); + } + } + +private: + MutexedQueue<GetRequest<Key, T, Caller, CallerData> > m_queue; +}; + +class UpdateThread : public Thread +{ +public: + UpdateThread(const std::string &name) : Thread(name + "Update") {} + ~UpdateThread() = default; + + void deferUpdate() { m_update_sem.post(); } + + void stop() + { + Thread::stop(); + + // give us a nudge + m_update_sem.post(); + } + + void *run() + { + BEGIN_DEBUG_EXCEPTION_HANDLER + + while (!stopRequested()) { + m_update_sem.wait(); + // Set semaphore to 0 + while (m_update_sem.wait(0)); + + if (stopRequested()) break; + + doUpdate(); + } + + END_DEBUG_EXCEPTION_HANDLER + + return NULL; + } + +protected: + virtual void doUpdate() = 0; + +private: + Semaphore m_update_sem; +}; diff --git a/src/util/timetaker.cpp b/src/util/timetaker.cpp new file mode 100644 index 0000000..717449c --- /dev/null +++ b/src/util/timetaker.cpp @@ -0,0 +1,63 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "timetaker.h" + +#include "porting.h" +#include "log.h" +#include <ostream> + +TimeTaker::TimeTaker(const std::string &name, u64 *result, TimePrecision prec) +{ + m_name = name; + m_result = result; + m_precision = prec; + m_time1 = porting::getTime(prec); +} + +u64 TimeTaker::stop(bool quiet) +{ + if (m_running) { + u64 dtime = porting::getTime(m_precision) - m_time1; + if (m_result != nullptr) { + (*m_result) += dtime; + } else { + if (!quiet) { + static const char* const units[] = { + "s" /* PRECISION_SECONDS */, + "ms" /* PRECISION_MILLI */, + "us" /* PRECISION_MICRO */, + "ns" /* PRECISION_NANO */, + }; + infostream << m_name << " took " + << dtime << units[m_precision] + << std::endl; + } + } + m_running = false; + return dtime; + } + return 0; +} + +u64 TimeTaker::getTimerTime() +{ + return porting::getTime(m_precision) - m_time1; +} + diff --git a/src/util/timetaker.h b/src/util/timetaker.h new file mode 100644 index 0000000..bc3d4a8 --- /dev/null +++ b/src/util/timetaker.h @@ -0,0 +1,50 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "gettime.h" + +/* + TimeTaker +*/ + +class TimeTaker +{ +public: + TimeTaker(const std::string &name, u64 *result=nullptr, + TimePrecision prec=PRECISION_MILLI); + + ~TimeTaker() + { + stop(); + } + + u64 stop(bool quiet=false); + + u64 getTimerTime(); + +private: + std::string m_name; + u64 m_time1; + bool m_running = true; + TimePrecision m_precision; + u64 *m_result = nullptr; +}; diff --git a/src/version.cpp b/src/version.cpp new file mode 100644 index 0000000..f2aac37 --- /dev/null +++ b/src/version.cpp @@ -0,0 +1,45 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "version.h" +#include "config.h" + +#if USE_CMAKE_CONFIG_H + #include "cmake_config_githash.h" +#endif + +#ifndef VERSION_GITHASH + #define VERSION_GITHASH VERSION_STRING +#endif + +const char *g_version_string = VERSION_STRING; +const char *g_version_hash = VERSION_GITHASH; +const char *g_build_info = + "BUILD_TYPE=" BUILD_TYPE "\n" + "RUN_IN_PLACE=" STR(RUN_IN_PLACE) "\n" + "USE_CURL=" STR(USE_CURL) "\n" +#ifndef SERVER + "USE_GETTEXT=" STR(USE_GETTEXT) "\n" + "USE_SOUND=" STR(USE_SOUND) "\n" +#endif + "STATIC_SHAREDIR=" STR(STATIC_SHAREDIR) +#if USE_GETTEXT && defined(STATIC_LOCALEDIR) + "\n" "STATIC_LOCALEDIR=" STR(STATIC_LOCALEDIR) +#endif +; diff --git a/src/version.h b/src/version.h new file mode 100644 index 0000000..30bb81f --- /dev/null +++ b/src/version.h @@ -0,0 +1,24 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +extern const char *g_version_string; +extern const char *g_version_hash; +extern const char *g_build_info; diff --git a/src/voxel.cpp b/src/voxel.cpp new file mode 100644 index 0000000..1f1d253 --- /dev/null +++ b/src/voxel.cpp @@ -0,0 +1,320 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "voxel.h" +#include "map.h" +#include "gettime.h" +#include "nodedef.h" +#include "util/directiontables.h" +#include "util/timetaker.h" +#include <cstring> // memcpy, memset + +/* + Debug stuff +*/ +u64 addarea_time = 0; +u64 emerge_time = 0; +u64 emerge_load_time = 0; +u64 clearflag_time = 0; + +VoxelManipulator::~VoxelManipulator() +{ + clear(); +} + +void VoxelManipulator::clear() +{ + // Reset area to volume=0 + m_area = VoxelArea(); + delete[] m_data; + m_data = nullptr; + delete[] m_flags; + m_flags = nullptr; +} + +void VoxelManipulator::print(std::ostream &o, const NodeDefManager *ndef, + VoxelPrintMode mode) +{ + const v3s16 &em = m_area.getExtent(); + v3s16 of = m_area.MinEdge; + o<<"size: "<<em.X<<"x"<<em.Y<<"x"<<em.Z + <<" offset: ("<<of.X<<","<<of.Y<<","<<of.Z<<")"<<std::endl; + + for(s32 y=m_area.MaxEdge.Y; y>=m_area.MinEdge.Y; y--) + { + if(em.X >= 3 && em.Y >= 3) + { + if (y==m_area.MinEdge.Y+2) o<<"^ "; + else if(y==m_area.MinEdge.Y+1) o<<"| "; + else if(y==m_area.MinEdge.Y+0) o<<"y x-> "; + else o<<" "; + } + + for(s32 z=m_area.MinEdge.Z; z<=m_area.MaxEdge.Z; z++) + { + for(s32 x=m_area.MinEdge.X; x<=m_area.MaxEdge.X; x++) + { + u8 f = m_flags[m_area.index(x,y,z)]; + char c; + if(f & VOXELFLAG_NO_DATA) + c = 'N'; + else + { + c = 'X'; + MapNode n = m_data[m_area.index(x,y,z)]; + content_t m = n.getContent(); + u8 pr = n.param2; + if(mode == VOXELPRINT_MATERIAL) + { + if(m <= 9) + c = m + '0'; + } + else if(mode == VOXELPRINT_WATERPRESSURE) + { + if(ndef->get(m).isLiquid()) + { + c = 'w'; + if(pr <= 9) + c = pr + '0'; + } + else if(m == CONTENT_AIR) + { + c = ' '; + } + else + { + c = '#'; + } + } + else if(mode == VOXELPRINT_LIGHT_DAY) + { + if(ndef->get(m).light_source != 0) + c = 'S'; + else if(!ndef->get(m).light_propagates) + c = 'X'; + else + { + u8 light = n.getLight(LIGHTBANK_DAY, ndef); + if(light < 10) + c = '0' + light; + else + c = 'a' + (light-10); + } + } + } + o<<c; + } + o<<' '; + } + o<<std::endl; + } +} + +void VoxelManipulator::addArea(const VoxelArea &area) +{ + // Cancel if requested area has zero volume + if (area.hasEmptyExtent()) + return; + + // Cancel if m_area already contains the requested area + if(m_area.contains(area)) + return; + + TimeTaker timer("addArea", &addarea_time); + + // Calculate new area + VoxelArea new_area; + // New area is the requested area if m_area has zero volume + if(m_area.hasEmptyExtent()) + { + new_area = area; + } + // Else add requested area to m_area + else + { + new_area = m_area; + new_area.addArea(area); + } + + s32 new_size = new_area.getVolume(); + + /*dstream<<"adding area "; + area.print(dstream); + dstream<<", old area "; + m_area.print(dstream); + dstream<<", new area "; + new_area.print(dstream); + dstream<<", new_size="<<new_size; + dstream<<std::endl;*/ + + // Allocate new data and clear flags + MapNode *new_data = new MapNode[new_size]; + assert(new_data); + u8 *new_flags = new u8[new_size]; + assert(new_flags); + memset(new_flags, VOXELFLAG_NO_DATA, new_size); + + // Copy old data + s32 old_x_width = m_area.MaxEdge.X - m_area.MinEdge.X + 1; + for(s32 z=m_area.MinEdge.Z; z<=m_area.MaxEdge.Z; z++) + for(s32 y=m_area.MinEdge.Y; y<=m_area.MaxEdge.Y; y++) + { + unsigned int old_index = m_area.index(m_area.MinEdge.X,y,z); + unsigned int new_index = new_area.index(m_area.MinEdge.X,y,z); + + memcpy(&new_data[new_index], &m_data[old_index], + old_x_width * sizeof(MapNode)); + memcpy(&new_flags[new_index], &m_flags[old_index], + old_x_width * sizeof(u8)); + } + + // Replace area, data and flags + + m_area = new_area; + + MapNode *old_data = m_data; + u8 *old_flags = m_flags; + + /*dstream<<"old_data="<<(int)old_data<<", new_data="<<(int)new_data + <<", old_flags="<<(int)m_flags<<", new_flags="<<(int)new_flags<<std::endl;*/ + + m_data = new_data; + m_flags = new_flags; + + delete[] old_data; + delete[] old_flags; + + //dstream<<"addArea done"<<std::endl; +} + +void VoxelManipulator::copyFrom(MapNode *src, const VoxelArea& src_area, + v3s16 from_pos, v3s16 to_pos, const v3s16 &size) +{ + /* The reason for this optimised code is that we're a member function + * and the data type/layout of m_data is know to us: it's stored as + * [z*h*w + y*h + x]. Therefore we can take the calls to m_area index + * (which performs the preceding mapping/indexing of m_data) out of the + * inner loop and calculate the next index as we're iterating to gain + * performance. + * + * src_step and dest_step is the amount required to be added to our index + * every time y increments. Because the destination area may be larger + * than the source area we need one additional variable (otherwise we could + * just continue adding dest_step as is done for the source data): dest_mod. + * dest_mod is the difference in size between a "row" in the source data + * and a "row" in the destination data (I am using the term row loosely + * and for illustrative purposes). E.g. + * + * src <-------------------->|'''''' dest mod '''''''' + * dest <---------------------------------------------> + * + * dest_mod (it's essentially a modulus) is added to the destination index + * after every full iteration of the y span. + * + * This method falls under the category "linear array and incrementing + * index". + */ + + s32 src_step = src_area.getExtent().X; + s32 dest_step = m_area.getExtent().X; + s32 dest_mod = m_area.index(to_pos.X, to_pos.Y, to_pos.Z + 1) + - m_area.index(to_pos.X, to_pos.Y, to_pos.Z) + - dest_step * size.Y; + + s32 i_src = src_area.index(from_pos.X, from_pos.Y, from_pos.Z); + s32 i_local = m_area.index(to_pos.X, to_pos.Y, to_pos.Z); + + for (s16 z = 0; z < size.Z; z++) { + for (s16 y = 0; y < size.Y; y++) { + memcpy(&m_data[i_local], &src[i_src], size.X * sizeof(*m_data)); + memset(&m_flags[i_local], 0, size.X); + i_src += src_step; + i_local += dest_step; + } + i_local += dest_mod; + } +} + +void VoxelManipulator::copyTo(MapNode *dst, const VoxelArea& dst_area, + v3s16 dst_pos, v3s16 from_pos, const v3s16 &size) +{ + for(s16 z=0; z<size.Z; z++) + for(s16 y=0; y<size.Y; y++) + { + s32 i_dst = dst_area.index(dst_pos.X, dst_pos.Y+y, dst_pos.Z+z); + s32 i_local = m_area.index(from_pos.X, from_pos.Y+y, from_pos.Z+z); + for (s16 x = 0; x < size.X; x++) { + if (m_data[i_local].getContent() != CONTENT_IGNORE) + dst[i_dst] = m_data[i_local]; + i_dst++; + i_local++; + } + } +} + +/* + Algorithms + ----------------------------------------------------- +*/ + +void VoxelManipulator::clearFlag(u8 flags) +{ + // 0-1ms on moderate area + TimeTaker timer("clearFlag", &clearflag_time); + + //v3s16 s = m_area.getExtent(); + + /*dstream<<"clearFlag clearing area of size " + <<""<<s.X<<"x"<<s.Y<<"x"<<s.Z<<"" + <<std::endl;*/ + + //s32 count = 0; + + /*for(s32 z=m_area.MinEdge.Z; z<=m_area.MaxEdge.Z; z++) + for(s32 y=m_area.MinEdge.Y; y<=m_area.MaxEdge.Y; y++) + for(s32 x=m_area.MinEdge.X; x<=m_area.MaxEdge.X; x++) + { + u8 f = m_flags[m_area.index(x,y,z)]; + m_flags[m_area.index(x,y,z)] &= ~flags; + if(m_flags[m_area.index(x,y,z)] != f) + count++; + }*/ + + s32 volume = m_area.getVolume(); + for(s32 i=0; i<volume; i++) + { + m_flags[i] &= ~flags; + } + + /*s32 volume = m_area.getVolume(); + for(s32 i=0; i<volume; i++) + { + u8 f = m_flags[i]; + m_flags[i] &= ~flags; + if(m_flags[i] != f) + count++; + } + + dstream<<"clearFlag changed "<<count<<" flags out of " + <<volume<<" nodes"<<std::endl;*/ +} + +const MapNode VoxelManipulator::ContentIgnoreNode = MapNode(CONTENT_IGNORE); + +//END diff --git a/src/voxel.h b/src/voxel.h new file mode 100644 index 0000000..16540e5 --- /dev/null +++ b/src/voxel.h @@ -0,0 +1,508 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "irr_v3d.h" +#include <iostream> +#include <cassert> +#include "exceptions.h" +#include "mapnode.h" +#include <set> +#include <list> +#include "util/basic_macros.h" + +class NodeDefManager; + +// For VC++ +#undef min +#undef max + +/* + A fast voxel manipulator class. + + In normal operation, it fetches more map when it is requested. + It can also be used so that all allowed area is fetched at the + start, using ManualMapVoxelManipulator. + + Not thread-safe. +*/ + +/* + Debug stuff +*/ +extern u64 emerge_time; +extern u64 emerge_load_time; + +/* + This class resembles aabbox3d<s16> a lot, but has inclusive + edges for saner handling of integer sizes +*/ +class VoxelArea +{ +public: + // Starts as zero sized + VoxelArea() = default; + + VoxelArea(const v3s16 &min_edge, const v3s16 &max_edge): + MinEdge(min_edge), + MaxEdge(max_edge) + { + cacheExtent(); + } + + VoxelArea(const v3s16 &p): + MinEdge(p), + MaxEdge(p) + { + cacheExtent(); + } + + /* + Modifying methods + */ + + void addArea(const VoxelArea &a) + { + if (hasEmptyExtent()) + { + *this = a; + return; + } + if(a.MinEdge.X < MinEdge.X) MinEdge.X = a.MinEdge.X; + if(a.MinEdge.Y < MinEdge.Y) MinEdge.Y = a.MinEdge.Y; + if(a.MinEdge.Z < MinEdge.Z) MinEdge.Z = a.MinEdge.Z; + if(a.MaxEdge.X > MaxEdge.X) MaxEdge.X = a.MaxEdge.X; + if(a.MaxEdge.Y > MaxEdge.Y) MaxEdge.Y = a.MaxEdge.Y; + if(a.MaxEdge.Z > MaxEdge.Z) MaxEdge.Z = a.MaxEdge.Z; + cacheExtent(); + } + + void addPoint(const v3s16 &p) + { + if(hasEmptyExtent()) + { + MinEdge = p; + MaxEdge = p; + cacheExtent(); + return; + } + if(p.X < MinEdge.X) MinEdge.X = p.X; + if(p.Y < MinEdge.Y) MinEdge.Y = p.Y; + if(p.Z < MinEdge.Z) MinEdge.Z = p.Z; + if(p.X > MaxEdge.X) MaxEdge.X = p.X; + if(p.Y > MaxEdge.Y) MaxEdge.Y = p.Y; + if(p.Z > MaxEdge.Z) MaxEdge.Z = p.Z; + cacheExtent(); + } + + // Pad with d nodes + void pad(const v3s16 &d) + { + MinEdge -= d; + MaxEdge += d; + } + + /* + const methods + */ + + const v3s16 &getExtent() const + { + return m_cache_extent; + } + + /* Because MaxEdge and MinEdge are included in the voxel area an empty extent + * is not represented by (0, 0, 0), but instead (-1, -1, -1) + */ + bool hasEmptyExtent() const + { + return MaxEdge - MinEdge == v3s16(-1, -1, -1); + } + + s32 getVolume() const + { + return (s32)m_cache_extent.X * (s32)m_cache_extent.Y * (s32)m_cache_extent.Z; + } + + bool contains(const VoxelArea &a) const + { + // No area contains an empty area + // NOTE: Algorithms depend on this, so do not change. + if(a.hasEmptyExtent()) + return false; + + return( + a.MinEdge.X >= MinEdge.X && a.MaxEdge.X <= MaxEdge.X && + a.MinEdge.Y >= MinEdge.Y && a.MaxEdge.Y <= MaxEdge.Y && + a.MinEdge.Z >= MinEdge.Z && a.MaxEdge.Z <= MaxEdge.Z + ); + } + bool contains(v3s16 p) const + { + return( + p.X >= MinEdge.X && p.X <= MaxEdge.X && + p.Y >= MinEdge.Y && p.Y <= MaxEdge.Y && + p.Z >= MinEdge.Z && p.Z <= MaxEdge.Z + ); + } + bool contains(s32 i) const + { + return (i >= 0 && i < getVolume()); + } + bool operator==(const VoxelArea &other) const + { + return (MinEdge == other.MinEdge + && MaxEdge == other.MaxEdge); + } + + VoxelArea operator+(const v3s16 &off) const + { + return {MinEdge+off, MaxEdge+off}; + } + + VoxelArea operator-(const v3s16 &off) const + { + return {MinEdge-off, MaxEdge-off}; + } + + /* + Returns 0-6 non-overlapping areas that can be added to + a to make up this area. + + a: area inside *this + */ + void diff(const VoxelArea &a, std::list<VoxelArea> &result) + { + /* + This can result in a maximum of 6 areas + */ + + // If a is an empty area, return the current area as a whole + if(a.getExtent() == v3s16(0,0,0)) + { + VoxelArea b = *this; + if(b.getVolume() != 0) + result.push_back(b); + return; + } + + assert(contains(a)); // pre-condition + + // Take back area, XY inclusive + { + v3s16 min(MinEdge.X, MinEdge.Y, a.MaxEdge.Z+1); + v3s16 max(MaxEdge.X, MaxEdge.Y, MaxEdge.Z); + VoxelArea b(min, max); + if(b.getVolume() != 0) + result.push_back(b); + } + + // Take front area, XY inclusive + { + v3s16 min(MinEdge.X, MinEdge.Y, MinEdge.Z); + v3s16 max(MaxEdge.X, MaxEdge.Y, a.MinEdge.Z-1); + VoxelArea b(min, max); + if(b.getVolume() != 0) + result.push_back(b); + } + + // Take top area, X inclusive + { + v3s16 min(MinEdge.X, a.MaxEdge.Y+1, a.MinEdge.Z); + v3s16 max(MaxEdge.X, MaxEdge.Y, a.MaxEdge.Z); + VoxelArea b(min, max); + if(b.getVolume() != 0) + result.push_back(b); + } + + // Take bottom area, X inclusive + { + v3s16 min(MinEdge.X, MinEdge.Y, a.MinEdge.Z); + v3s16 max(MaxEdge.X, a.MinEdge.Y-1, a.MaxEdge.Z); + VoxelArea b(min, max); + if(b.getVolume() != 0) + result.push_back(b); + } + + // Take left area, non-inclusive + { + v3s16 min(MinEdge.X, a.MinEdge.Y, a.MinEdge.Z); + v3s16 max(a.MinEdge.X-1, a.MaxEdge.Y, a.MaxEdge.Z); + VoxelArea b(min, max); + if(b.getVolume() != 0) + result.push_back(b); + } + + // Take right area, non-inclusive + { + v3s16 min(a.MaxEdge.X+1, a.MinEdge.Y, a.MinEdge.Z); + v3s16 max(MaxEdge.X, a.MaxEdge.Y, a.MaxEdge.Z); + VoxelArea b(min, max); + if(b.getVolume() != 0) + result.push_back(b); + } + + } + + /* + Translates position from virtual coordinates to array index + */ + s32 index(s16 x, s16 y, s16 z) const + { + s32 i = (s32)(z - MinEdge.Z) * m_cache_extent.Y * m_cache_extent.X + + (y - MinEdge.Y) * m_cache_extent.X + + (x - MinEdge.X); + return i; + } + s32 index(v3s16 p) const + { + return index(p.X, p.Y, p.Z); + } + + /** + * Translate index in the X coordinate + */ + static void add_x(const v3s16 &extent, u32 &i, s16 a) + { + i += a; + } + + /** + * Translate index in the Y coordinate + */ + static void add_y(const v3s16 &extent, u32 &i, s16 a) + { + i += a * extent.X; + } + + /** + * Translate index in the Z coordinate + */ + static void add_z(const v3s16 &extent, u32 &i, s16 a) + { + i += a * extent.X * extent.Y; + } + + /** + * Translate index in space + */ + static void add_p(const v3s16 &extent, u32 &i, v3s16 a) + { + i += a.Z * extent.X * extent.Y + a.Y * extent.X + a.X; + } + + /* + Print method for debugging + */ + void print(std::ostream &o) const + { + o << PP(MinEdge) << PP(MaxEdge) << "=" + << m_cache_extent.X << "x" << m_cache_extent.Y << "x" << m_cache_extent.Z + << "=" << getVolume(); + } + + // Edges are inclusive + v3s16 MinEdge = v3s16(1,1,1); + v3s16 MaxEdge; +private: + void cacheExtent() + { + m_cache_extent = MaxEdge - MinEdge + v3s16(1,1,1); + } + + v3s16 m_cache_extent = v3s16(0,0,0); +}; + +// unused +#define VOXELFLAG_UNUSED (1 << 0) +// no data about that node +#define VOXELFLAG_NO_DATA (1 << 1) +// Algorithm-dependent +#define VOXELFLAG_CHECKED1 (1 << 2) +// Algorithm-dependent +#define VOXELFLAG_CHECKED2 (1 << 3) +// Algorithm-dependent +#define VOXELFLAG_CHECKED3 (1 << 4) +// Algorithm-dependent +#define VOXELFLAG_CHECKED4 (1 << 5) + +enum VoxelPrintMode +{ + VOXELPRINT_NOTHING, + VOXELPRINT_MATERIAL, + VOXELPRINT_WATERPRESSURE, + VOXELPRINT_LIGHT_DAY, +}; + +class VoxelManipulator +{ +public: + VoxelManipulator() = default; + virtual ~VoxelManipulator(); + + /* + These are a bit slow and shouldn't be used internally. + Use m_data[m_area.index(p)] instead. + */ + MapNode getNode(const v3s16 &p) + { + VoxelArea voxel_area(p); + addArea(voxel_area); + + if (m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA) { + /*dstream<<"EXCEPT: VoxelManipulator::getNode(): " + <<"p=("<<p.X<<","<<p.Y<<","<<p.Z<<")" + <<", index="<<m_area.index(p) + <<", flags="<<(int)m_flags[m_area.index(p)] + <<" is inexistent"<<std::endl;*/ + throw InvalidPositionException + ("VoxelManipulator: getNode: inexistent"); + } + + return m_data[m_area.index(p)]; + } + MapNode getNodeNoEx(const v3s16 &p) + { + VoxelArea voxel_area(p); + addArea(voxel_area); + + if (m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA) { + return {CONTENT_IGNORE}; + } + + return m_data[m_area.index(p)]; + } + MapNode getNodeNoExNoEmerge(const v3s16 &p) + { + if (!m_area.contains(p)) + return {CONTENT_IGNORE}; + if (m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA) + return {CONTENT_IGNORE}; + return m_data[m_area.index(p)]; + } + // Stuff explodes if non-emerged area is touched with this. + // Emerge first, and check VOXELFLAG_NO_DATA if appropriate. + MapNode & getNodeRefUnsafe(const v3s16 &p) + { + return m_data[m_area.index(p)]; + } + + const MapNode & getNodeRefUnsafeCheckFlags(const v3s16 &p) + { + s32 index = m_area.index(p); + + if (m_flags[index] & VOXELFLAG_NO_DATA) + return ContentIgnoreNode; + + return m_data[index]; + } + + u8 & getFlagsRefUnsafe(const v3s16 &p) + { + return m_flags[m_area.index(p)]; + } + + bool exists(const v3s16 &p) + { + return m_area.contains(p) && + !(getFlagsRefUnsafe(p) & VOXELFLAG_NO_DATA); + } + + void setNode(const v3s16 &p, const MapNode &n) + { + VoxelArea voxel_area(p); + addArea(voxel_area); + + m_data[m_area.index(p)] = n; + m_flags[m_area.index(p)] &= ~VOXELFLAG_NO_DATA; + } + // TODO: Should be removed and replaced with setNode + void setNodeNoRef(const v3s16 &p, const MapNode &n) + { + setNode(p, n); + } + + /* + Set stuff if available without an emerge. + Return false if failed. + This is convenient but slower than playing around directly + with the m_data table with indices. + */ + bool setNodeNoEmerge(const v3s16 &p, MapNode n) + { + if(!m_area.contains(p)) + return false; + m_data[m_area.index(p)] = n; + return true; + } + + /* + Control + */ + + virtual void clear(); + + void print(std::ostream &o, const NodeDefManager *nodemgr, + VoxelPrintMode mode=VOXELPRINT_MATERIAL); + + void addArea(const VoxelArea &area); + + /* + Copy data and set flags to 0 + dst_area.getExtent() <= src_area.getExtent() + */ + void copyFrom(MapNode *src, const VoxelArea& src_area, + v3s16 from_pos, v3s16 to_pos, const v3s16 &size); + + // Copy data + void copyTo(MapNode *dst, const VoxelArea& dst_area, + v3s16 dst_pos, v3s16 from_pos, const v3s16 &size); + + /* + Algorithms + */ + + void clearFlag(u8 flag); + + /* + Member variables + */ + + /* + The area that is stored in m_data. + addInternalBox should not be used if getExtent() == v3s16(0,0,0) + MaxEdge is 1 higher than maximum allowed position + */ + VoxelArea m_area; + + /* + nullptr if data size is 0 (extent (0,0,0)) + Data is stored as [z*h*w + y*h + x] + */ + MapNode *m_data = nullptr; + + /* + Flags of all nodes + */ + u8 *m_flags = nullptr; + + static const MapNode ContentIgnoreNode; +}; diff --git a/src/voxelalgorithms.cpp b/src/voxelalgorithms.cpp new file mode 100644 index 0000000..ffb70aa --- /dev/null +++ b/src/voxelalgorithms.cpp @@ -0,0 +1,1332 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "voxelalgorithms.h" +#include "nodedef.h" +#include "mapblock.h" +#include "map.h" + +namespace voxalgo +{ + +/*! + * A direction. + * 0=X+ + * 1=Y+ + * 2=Z+ + * 3=Z- + * 4=Y- + * 5=X- + * 6=no direction + * Two directions are opposite only if their sum is 5. + */ +typedef u8 direction; +/*! + * Relative node position. + * This represents a node's position in its map block. + * All coordinates must be between 0 and 15. + */ +typedef v3s16 relative_v3; +/*! + * Position of a map block (block coordinates). + * One block_pos unit is as long as 16 node position units. + */ +typedef v3s16 mapblock_v3; + +//! Contains information about a node whose light is about to change. +struct ChangingLight { + //! Relative position of the node in its map block. + relative_v3 rel_position; + //! Position of the node's block. + mapblock_v3 block_position; + //! Pointer to the node's block. + MapBlock *block = NULL; + /*! + * Direction from the node that caused this node's changing + * to this node. + */ + direction source_direction = 6; + + ChangingLight() = default; + + ChangingLight(relative_v3 rel_pos, mapblock_v3 block_pos, + MapBlock *b, direction source_dir) : + rel_position(rel_pos), + block_position(block_pos), + block(b), + source_direction(source_dir) + {} +}; + +/*! + * A fast, priority queue-like container to contain ChangingLights. + * The ChangingLights are ordered by the given light levels. + * The brightest ChangingLight is returned first. + */ +struct LightQueue { + //! For each light level there is a vector. + std::vector<ChangingLight> lights[LIGHT_SUN + 1]; + //! Light of the brightest ChangingLight in the queue. + u8 max_light; + + /*! + * Creates a LightQueue. + * \param reserve for each light level that many slots are reserved. + */ + LightQueue(size_t reserve) + { + max_light = LIGHT_SUN; + for (u8 i = 0; i <= LIGHT_SUN; i++) { + lights[i].reserve(reserve); + } + } + + /*! + * Returns the next brightest ChangingLight and + * removes it from the queue. + * If there were no elements in the queue, the given parameters + * remain unmodified. + * \param light light level of the popped ChangingLight + * \param data the ChangingLight that was popped + * \returns true if there was a ChangingLight in the queue. + */ + bool next(u8 &light, ChangingLight &data) + { + while (lights[max_light].empty()) { + if (max_light == 0) { + return false; + } + max_light--; + } + light = max_light; + data = lights[max_light].back(); + lights[max_light].pop_back(); + return true; + } + + /*! + * Adds an element to the queue. + * The parameters are the same as in ChangingLight's constructor. + * \param light light level of the ChangingLight + */ + inline void push(u8 light, relative_v3 rel_pos, + mapblock_v3 block_pos, MapBlock *block, + direction source_dir) + { + assert(light <= LIGHT_SUN); + lights[light].emplace_back(rel_pos, block_pos, block, source_dir); + } +}; + +/*! + * This type of light queue is for unlighting. + * A node can be pushed in it only if its raw light is zero. + * This prevents pushing nodes twice into this queue. + * The light of the pushed ChangingLight must be the + * light of the node before unlighting it. + */ +typedef LightQueue UnlightQueue; +/*! + * This type of light queue is for spreading lights. + * While spreading lights, all the nodes in it must + * have the same light as the light level the ChangingLights + * were pushed into this queue with. This prevents unnecessary + * re-pushing of the nodes into the queue. + * If a node doesn't let light trough but emits light, it can be added + * too. + */ +typedef LightQueue ReLightQueue; + +/*! + * neighbor_dirs[i] points towards + * the direction i. + * See the definition of the type "direction" + */ +const static v3s16 neighbor_dirs[6] = { + v3s16(1, 0, 0), // right + v3s16(0, 1, 0), // top + v3s16(0, 0, 1), // back + v3s16(0, 0, -1), // front + v3s16(0, -1, 0), // bottom + v3s16(-1, 0, 0), // left +}; + +/*! + * Transforms the given map block offset by one node towards + * the specified direction. + * \param dir the direction of the transformation + * \param rel_pos the node's relative position in its map block + * \param block_pos position of the node's block + */ +bool step_rel_block_pos(direction dir, relative_v3 &rel_pos, + mapblock_v3 &block_pos) +{ + switch (dir) { + case 0: + if (rel_pos.X < MAP_BLOCKSIZE - 1) { + rel_pos.X++; + } else { + rel_pos.X = 0; + block_pos.X++; + return true; + } + break; + case 1: + if (rel_pos.Y < MAP_BLOCKSIZE - 1) { + rel_pos.Y++; + } else { + rel_pos.Y = 0; + block_pos.Y++; + return true; + } + break; + case 2: + if (rel_pos.Z < MAP_BLOCKSIZE - 1) { + rel_pos.Z++; + } else { + rel_pos.Z = 0; + block_pos.Z++; + return true; + } + break; + case 3: + if (rel_pos.Z > 0) { + rel_pos.Z--; + } else { + rel_pos.Z = MAP_BLOCKSIZE - 1; + block_pos.Z--; + return true; + } + break; + case 4: + if (rel_pos.Y > 0) { + rel_pos.Y--; + } else { + rel_pos.Y = MAP_BLOCKSIZE - 1; + block_pos.Y--; + return true; + } + break; + case 5: + if (rel_pos.X > 0) { + rel_pos.X--; + } else { + rel_pos.X = MAP_BLOCKSIZE - 1; + block_pos.X--; + return true; + } + break; + } + return false; +} + +/* + * Removes all light that is potentially emitted by the specified + * light sources. These nodes will have zero light. + * Returns all nodes whose light became zero but should be re-lighted. + * + * \param bank the light bank in which the procedure operates + * \param from_nodes nodes whose light is removed + * \param light_sources nodes that should be re-lighted + * \param modified_blocks output, all modified map blocks are added to this + */ +void unspread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank, + UnlightQueue &from_nodes, ReLightQueue &light_sources, + std::map<v3s16, MapBlock*> &modified_blocks) +{ + // Stores data popped from from_nodes + u8 current_light; + ChangingLight current; + // Data of the current neighbor + mapblock_v3 neighbor_block_pos; + relative_v3 neighbor_rel_pos; + // A dummy boolean + bool is_valid_position; + // Direction of the brightest neighbor of the node + direction source_dir; + while (from_nodes.next(current_light, current)) { + // For all nodes that need unlighting + + // There is no brightest neighbor + source_dir = 6; + // The current node + const MapNode &node = current.block->getNodeNoCheck( + current.rel_position, &is_valid_position); + const ContentFeatures &f = nodemgr->get(node); + // If the node emits light, it behaves like it had a + // brighter neighbor. + u8 brightest_neighbor_light = f.light_source + 1; + for (direction i = 0; i < 6; i++) { + //For each neighbor + + // The node that changed this node has already zero light + // and it can't give light to this node + if (current.source_direction + i == 5) { + continue; + } + // Get the neighbor's position and block + neighbor_rel_pos = current.rel_position; + neighbor_block_pos = current.block_position; + MapBlock *neighbor_block; + if (step_rel_block_pos(i, neighbor_rel_pos, neighbor_block_pos)) { + neighbor_block = map->getBlockNoCreateNoEx(neighbor_block_pos); + if (neighbor_block == NULL) { + current.block->setLightingComplete(bank, i, false); + continue; + } + } else { + neighbor_block = current.block; + } + // Get the neighbor itself + MapNode neighbor = neighbor_block->getNodeNoCheck(neighbor_rel_pos, + &is_valid_position); + const ContentFeatures &neighbor_f = nodemgr->get( + neighbor.getContent()); + u8 neighbor_light = neighbor.getLightRaw(bank, neighbor_f); + // If the neighbor has at least as much light as this node, then + // it won't lose its light, since it should have been added to + // from_nodes earlier, so its light would be zero. + if (neighbor_f.light_propagates && neighbor_light < current_light) { + // Unlight, but only if the node has light. + if (neighbor_light > 0) { + neighbor.setLight(bank, 0, neighbor_f); + neighbor_block->setNodeNoCheck(neighbor_rel_pos, neighbor); + from_nodes.push(neighbor_light, neighbor_rel_pos, + neighbor_block_pos, neighbor_block, i); + // The current node was modified earlier, so its block + // is in modified_blocks. + if (current.block != neighbor_block) { + modified_blocks[neighbor_block_pos] = neighbor_block; + } + } + } else { + // The neighbor can light up this node. + if (neighbor_light < neighbor_f.light_source) { + neighbor_light = neighbor_f.light_source; + } + if (brightest_neighbor_light < neighbor_light) { + brightest_neighbor_light = neighbor_light; + source_dir = i; + } + } + } + // If the brightest neighbor is able to light up this node, + // then add this node to the output nodes. + if (brightest_neighbor_light > 1 && f.light_propagates) { + brightest_neighbor_light--; + light_sources.push(brightest_neighbor_light, current.rel_position, + current.block_position, current.block, + (source_dir == 6) ? 6 : 5 - source_dir + /* with opposite direction*/); + } + } +} + +/* + * Spreads light from the specified starting nodes. + * + * Before calling this procedure, make sure that all ChangingLights + * in light_sources have as much light on the map as they have in + * light_sources (if the queue contains a node multiple times, the brightest + * occurrence counts). + * + * \param bank the light bank in which the procedure operates + * \param light_sources starting nodes + * \param modified_blocks output, all modified map blocks are added to this + */ +void spread_light(Map *map, const NodeDefManager *nodemgr, LightBank bank, + LightQueue &light_sources, + std::map<v3s16, MapBlock*> &modified_blocks) +{ + // The light the current node can provide to its neighbors. + u8 spreading_light; + // The ChangingLight for the current node. + ChangingLight current; + // Position of the current neighbor. + mapblock_v3 neighbor_block_pos; + relative_v3 neighbor_rel_pos; + // A dummy boolean. + bool is_valid_position; + while (light_sources.next(spreading_light, current)) { + spreading_light--; + for (direction i = 0; i < 6; i++) { + // This node can't light up its light source + if (current.source_direction + i == 5) { + continue; + } + // Get the neighbor's position and block + neighbor_rel_pos = current.rel_position; + neighbor_block_pos = current.block_position; + MapBlock *neighbor_block; + if (step_rel_block_pos(i, neighbor_rel_pos, neighbor_block_pos)) { + neighbor_block = map->getBlockNoCreateNoEx(neighbor_block_pos); + if (neighbor_block == NULL) { + current.block->setLightingComplete(bank, i, false); + continue; + } + } else { + neighbor_block = current.block; + } + // Get the neighbor itself + MapNode neighbor = neighbor_block->getNodeNoCheck(neighbor_rel_pos, + &is_valid_position); + const ContentFeatures &f = nodemgr->get(neighbor.getContent()); + if (f.light_propagates) { + // Light up the neighbor, if it has less light than it should. + u8 neighbor_light = neighbor.getLightRaw(bank, f); + if (neighbor_light < spreading_light) { + neighbor.setLight(bank, spreading_light, f); + neighbor_block->setNodeNoCheck(neighbor_rel_pos, neighbor); + light_sources.push(spreading_light, neighbor_rel_pos, + neighbor_block_pos, neighbor_block, i); + // The current node was modified earlier, so its block + // is in modified_blocks. + if (current.block != neighbor_block) { + modified_blocks[neighbor_block_pos] = neighbor_block; + } + } + } + } + } +} + +struct SunlightPropagationUnit{ + v2s16 relative_pos; + bool is_sunlit; + + SunlightPropagationUnit(v2s16 relpos, bool sunlit): + relative_pos(relpos), + is_sunlit(sunlit) + {} +}; + +struct SunlightPropagationData{ + std::vector<SunlightPropagationUnit> data; + v3s16 target_block; +}; + +/*! + * Returns true if the node gets sunlight from the + * node above it. + * + * \param pos position of the node. + */ +bool is_sunlight_above(Map *map, v3s16 pos, const NodeDefManager *ndef) +{ + bool sunlight = true; + mapblock_v3 source_block_pos; + relative_v3 source_rel_pos; + getNodeBlockPosWithOffset(pos + v3s16(0, 1, 0), source_block_pos, + source_rel_pos); + // If the node above has sunlight, this node also can get it. + MapBlock *source_block = map->getBlockNoCreateNoEx(source_block_pos); + if (source_block == NULL) { + // But if there is no node above, then use heuristics + MapBlock *node_block = map->getBlockNoCreateNoEx(getNodeBlockPos(pos)); + if (node_block == NULL) { + sunlight = false; + } else { + sunlight = !node_block->getIsUnderground(); + } + } else { + bool is_valid_position; + MapNode above = source_block->getNodeNoCheck(source_rel_pos, + &is_valid_position); + if (is_valid_position) { + if (above.getContent() == CONTENT_IGNORE) { + // Trust heuristics + if (source_block->getIsUnderground()) { + sunlight = false; + } + } else if (above.getLight(LIGHTBANK_DAY, ndef) != LIGHT_SUN) { + // If the node above doesn't have sunlight, this + // node is in shadow. + sunlight = false; + } + } + } + return sunlight; +} + +static const LightBank banks[] = { LIGHTBANK_DAY, LIGHTBANK_NIGHT }; + +void update_lighting_nodes(Map *map, + const std::vector<std::pair<v3s16, MapNode>> &oldnodes, + std::map<v3s16, MapBlock*> &modified_blocks) +{ + const NodeDefManager *ndef = map->getNodeDefManager(); + // For node getter functions + bool is_valid_position; + + // Process each light bank separately + for (LightBank bank : banks) { + UnlightQueue disappearing_lights(256); + ReLightQueue light_sources(256); + // Nodes that are brighter than the brightest modified node was + // won't change, since they didn't get their light from a + // modified node. + u8 min_safe_light = 0; + for (auto it = oldnodes.cbegin(); it < oldnodes.cend(); ++it) { + u8 old_light = it->second.getLight(bank, ndef); + if (old_light > min_safe_light) { + min_safe_light = old_light; + } + } + // If only one node changed, even nodes with the same brightness + // didn't get their light from the changed node. + if (oldnodes.size() > 1) { + min_safe_light++; + } + // For each changed node process sunlight and initialize + for (auto it = oldnodes.cbegin(); it < oldnodes.cend(); ++it) { + // Get position and block of the changed node + v3s16 p = it->first; + relative_v3 rel_pos; + mapblock_v3 block_pos; + getNodeBlockPosWithOffset(p, block_pos, rel_pos); + MapBlock *block = map->getBlockNoCreateNoEx(block_pos); + if (block == NULL || block->isDummy()) { + continue; + } + // Get the new node + MapNode n = block->getNodeNoCheck(rel_pos, &is_valid_position); + if (!is_valid_position) { + break; + } + + // Light of the old node + u8 old_light = it->second.getLight(bank, ndef); + + // Add the block of the added node to modified_blocks + modified_blocks[block_pos] = block; + + // Get new light level of the node + u8 new_light = 0; + if (ndef->get(n).light_propagates) { + if (bank == LIGHTBANK_DAY && ndef->get(n).sunlight_propagates + && is_sunlight_above(map, p, ndef)) { + new_light = LIGHT_SUN; + } else { + new_light = ndef->get(n).light_source; + for (const v3s16 &neighbor_dir : neighbor_dirs) { + v3s16 p2 = p + neighbor_dir; + bool is_valid; + MapNode n2 = map->getNode(p2, &is_valid); + if (is_valid) { + u8 spread = n2.getLight(bank, ndef); + // If it is sure that the neighbor won't be + // unlighted, its light can spread to this node. + if (spread > new_light && spread >= min_safe_light) { + new_light = spread - 1; + } + } + } + } + } else { + // If this is an opaque node, it still can emit light. + new_light = ndef->get(n).light_source; + } + + if (new_light > 0) { + light_sources.push(new_light, rel_pos, block_pos, block, 6); + } + + if (new_light < old_light) { + // The node became opaque or doesn't provide as much + // light as the previous one, so it must be unlighted. + + // Add to unlight queue + n.setLight(bank, 0, ndef); + block->setNodeNoCheck(rel_pos, n); + disappearing_lights.push(old_light, rel_pos, block_pos, block, + 6); + + // Remove sunlight, if there was any + if (bank == LIGHTBANK_DAY && old_light == LIGHT_SUN) { + for (s16 y = p.Y - 1;; y--) { + v3s16 n2pos(p.X, y, p.Z); + + MapNode n2; + + n2 = map->getNode(n2pos, &is_valid_position); + if (!is_valid_position) + break; + + // If this node doesn't have sunlight, the nodes below + // it don't have too. + if (n2.getLight(LIGHTBANK_DAY, ndef) != LIGHT_SUN) { + break; + } + // Remove sunlight and add to unlight queue. + n2.setLight(LIGHTBANK_DAY, 0, ndef); + map->setNode(n2pos, n2); + relative_v3 rel_pos2; + mapblock_v3 block_pos2; + getNodeBlockPosWithOffset(n2pos, block_pos2, rel_pos2); + MapBlock *block2 = map->getBlockNoCreateNoEx( + block_pos2); + disappearing_lights.push(LIGHT_SUN, rel_pos2, + block_pos2, block2, + 4 /* The node above caused the change */); + } + } + } else if (new_light > old_light) { + // It is sure that the node provides more light than the previous + // one, unlighting is not necessary. + // Propagate sunlight + if (bank == LIGHTBANK_DAY && new_light == LIGHT_SUN) { + for (s16 y = p.Y - 1;; y--) { + v3s16 n2pos(p.X, y, p.Z); + + MapNode n2; + + n2 = map->getNode(n2pos, &is_valid_position); + if (!is_valid_position) + break; + + // This should not happen, but if the node has sunlight + // then the iteration should stop. + if (n2.getLight(LIGHTBANK_DAY, ndef) == LIGHT_SUN) { + break; + } + // If the node terminates sunlight, stop. + if (!ndef->get(n2).sunlight_propagates) { + break; + } + relative_v3 rel_pos2; + mapblock_v3 block_pos2; + getNodeBlockPosWithOffset(n2pos, block_pos2, rel_pos2); + MapBlock *block2 = map->getBlockNoCreateNoEx( + block_pos2); + // Mark node for lighting. + light_sources.push(LIGHT_SUN, rel_pos2, block_pos2, + block2, 4); + } + } + } + + } + // Remove lights + unspread_light(map, ndef, bank, disappearing_lights, light_sources, + modified_blocks); + // Initialize light values for light spreading. + for (u8 i = 0; i <= LIGHT_SUN; i++) { + const std::vector<ChangingLight> &lights = light_sources.lights[i]; + for (std::vector<ChangingLight>::const_iterator it = lights.begin(); + it < lights.end(); ++it) { + MapNode n = it->block->getNodeNoCheck(it->rel_position, + &is_valid_position); + n.setLight(bank, i, ndef); + it->block->setNodeNoCheck(it->rel_position, n); + } + } + // Spread lights. + spread_light(map, ndef, bank, light_sources, modified_blocks); + } +} + +/*! + * Borders of a map block in relative node coordinates. + * Compatible with type 'direction'. + */ +const VoxelArea block_borders[] = { + VoxelArea(v3s16(15, 0, 0), v3s16(15, 15, 15)), //X+ + VoxelArea(v3s16(0, 15, 0), v3s16(15, 15, 15)), //Y+ + VoxelArea(v3s16(0, 0, 15), v3s16(15, 15, 15)), //Z+ + VoxelArea(v3s16(0, 0, 0), v3s16(15, 15, 0)), //Z- + VoxelArea(v3s16(0, 0, 0), v3s16(15, 0, 15)), //Y- + VoxelArea(v3s16(0, 0, 0), v3s16(0, 15, 15)) //X- +}; + +/*! + * Returns true if: + * -the node has unloaded neighbors + * -the node doesn't have light + * -the node's light is the same as the maximum of + * its light source and its brightest neighbor minus one. + * . + */ +bool is_light_locally_correct(Map *map, const NodeDefManager *ndef, + LightBank bank, v3s16 pos) +{ + bool is_valid_position; + MapNode n = map->getNode(pos, &is_valid_position); + const ContentFeatures &f = ndef->get(n); + if (f.param_type != CPT_LIGHT) { + return true; + } + u8 light = n.getLightNoChecks(bank, &f); + assert(f.light_source <= LIGHT_MAX); + u8 brightest_neighbor = f.light_source + 1; + for (const v3s16 &neighbor_dir : neighbor_dirs) { + MapNode n2 = map->getNode(pos + neighbor_dir, + &is_valid_position); + u8 light2 = n2.getLight(bank, ndef); + if (brightest_neighbor < light2) { + brightest_neighbor = light2; + } + } + assert(light <= LIGHT_SUN); + return brightest_neighbor == light + 1; +} + +void update_block_border_lighting(Map *map, MapBlock *block, + std::map<v3s16, MapBlock*> &modified_blocks) +{ + const NodeDefManager *ndef = map->getNodeDefManager(); + bool is_valid_position; + for (LightBank bank : banks) { + // Since invalid light is not common, do not allocate + // memory if not needed. + UnlightQueue disappearing_lights(0); + ReLightQueue light_sources(0); + // Get incorrect lights + for (direction d = 0; d < 6; d++) { + // For each direction + // Get neighbor block + v3s16 otherpos = block->getPos() + neighbor_dirs[d]; + MapBlock *other = map->getBlockNoCreateNoEx(otherpos); + if (other == NULL) { + continue; + } + // Only update if lighting was not completed. + if (block->isLightingComplete(bank, d) && + other->isLightingComplete(bank, 5 - d)) + continue; + // Reset flags + block->setLightingComplete(bank, d, true); + other->setLightingComplete(bank, 5 - d, true); + // The two blocks and their connecting surfaces + MapBlock *blocks[] = {block, other}; + VoxelArea areas[] = {block_borders[d], block_borders[5 - d]}; + // For both blocks + for (u8 blocknum = 0; blocknum < 2; blocknum++) { + MapBlock *b = blocks[blocknum]; + VoxelArea a = areas[blocknum]; + // For all nodes + for (s32 x = a.MinEdge.X; x <= a.MaxEdge.X; x++) + for (s32 z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) + for (s32 y = a.MinEdge.Y; y <= a.MaxEdge.Y; y++) { + MapNode n = b->getNodeNoCheck(x, y, z, + &is_valid_position); + u8 light = n.getLight(bank, ndef); + // Sunlight is fixed + if (light < LIGHT_SUN) { + // Unlight if not correct + if (!is_light_locally_correct(map, ndef, bank, + v3s16(x, y, z) + b->getPosRelative())) { + // Initialize for unlighting + n.setLight(bank, 0, ndef); + b->setNodeNoCheck(x, y, z, n); + modified_blocks[b->getPos()]=b; + disappearing_lights.push(light, + relative_v3(x, y, z), b->getPos(), b, + 6); + } + } + } + } + } + // Remove lights + unspread_light(map, ndef, bank, disappearing_lights, light_sources, + modified_blocks); + // Initialize light values for light spreading. + for (u8 i = 0; i <= LIGHT_SUN; i++) { + const std::vector<ChangingLight> &lights = light_sources.lights[i]; + for (std::vector<ChangingLight>::const_iterator it = lights.begin(); + it < lights.end(); ++it) { + MapNode n = it->block->getNodeNoCheck(it->rel_position, + &is_valid_position); + n.setLight(bank, i, ndef); + it->block->setNodeNoCheck(it->rel_position, n); + } + } + // Spread lights. + spread_light(map, ndef, bank, light_sources, modified_blocks); + } +} + +/*! + * Resets the lighting of the given VoxelManipulator to + * complete darkness and full sunlight. + * Operates in one map sector. + * + * \param offset contains the least x and z node coordinates + * of the map sector. + * \param light incoming sunlight, light[x][z] is true if there + * is sunlight above the voxel manipulator at the given x-z coordinates. + * The array's indices are relative node coordinates in the sector. + * After the procedure returns, this contains outgoing light at + * the bottom of the voxel manipulator. + */ +void fill_with_sunlight(MMVManip *vm, const NodeDefManager *ndef, v2s16 offset, + bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE]) +{ + // Distance in array between two nodes on top of each other. + s16 ystride = vm->m_area.getExtent().X; + // Cache the ignore node. + MapNode ignore = MapNode(CONTENT_IGNORE); + // For each column of nodes: + for (s16 z = 0; z < MAP_BLOCKSIZE; z++) + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { + // Position of the column on the map. + v2s16 realpos = offset + v2s16(x, z); + // Array indices in the voxel manipulator + s32 maxindex = vm->m_area.index(realpos.X, vm->m_area.MaxEdge.Y, + realpos.Y); + s32 minindex = vm->m_area.index(realpos.X, vm->m_area.MinEdge.Y, + realpos.Y); + // True if the current node has sunlight. + bool lig = light[z][x]; + // For each node, downwards: + for (s32 i = maxindex; i >= minindex; i -= ystride) { + MapNode *n; + if (vm->m_flags[i] & VOXELFLAG_NO_DATA) + n = &ignore; + else + n = &vm->m_data[i]; + // Ignore IGNORE nodes, these are not generated yet. + if(n->getContent() == CONTENT_IGNORE) + continue; + const ContentFeatures &f = ndef->get(n->getContent()); + if (lig && !f.sunlight_propagates) + // Sunlight is stopped. + lig = false; + // Reset light + n->setLight(LIGHTBANK_DAY, lig ? 15 : 0, f); + n->setLight(LIGHTBANK_NIGHT, 0, f); + } + // Output outgoing light. + light[z][x] = lig; + } +} + +/*! + * Returns incoming sunlight for one map block. + * If block above is not found, it is loaded. + * + * \param pos position of the map block that gets the sunlight. + * \param light incoming sunlight, light[z][x] is true if there + * is sunlight above the block at the given z-x relative + * node coordinates. + */ +void is_sunlight_above_block(ServerMap *map, mapblock_v3 pos, + const NodeDefManager *ndef, bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE]) +{ + mapblock_v3 source_block_pos = pos + v3s16(0, 1, 0); + // Get or load source block. + // It might take a while to load, but correcting incorrect + // sunlight may be even slower. + MapBlock *source_block = map->emergeBlock(source_block_pos, false); + // Trust only generated blocks. + if (source_block == NULL || source_block->isDummy() + || !source_block->isGenerated()) { + // But if there is no block above, then use heuristics + bool sunlight = true; + MapBlock *node_block = map->getBlockNoCreateNoEx(pos); + if (node_block == NULL) + // This should not happen. + sunlight = false; + else + sunlight = !node_block->getIsUnderground(); + for (s16 z = 0; z < MAP_BLOCKSIZE; z++) + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) + light[z][x] = sunlight; + } else { + // Dummy boolean, the position is valid. + bool is_valid_position; + // For each column: + for (s16 z = 0; z < MAP_BLOCKSIZE; z++) + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { + // Get the bottom block. + MapNode above = source_block->getNodeNoCheck(x, 0, z, + &is_valid_position); + light[z][x] = above.getLight(LIGHTBANK_DAY, ndef) == LIGHT_SUN; + } + } +} + +/*! + * Propagates sunlight down in a given map block. + * + * \param data contains incoming sunlight and shadow and + * the coordinates of the target block. + * \param unlight propagated shadow is inserted here + * \param relight propagated sunlight is inserted here + * + * \returns true if the block was modified, false otherwise. + */ +bool propagate_block_sunlight(Map *map, const NodeDefManager *ndef, + SunlightPropagationData *data, UnlightQueue *unlight, ReLightQueue *relight) +{ + bool modified = false; + // Get the block. + MapBlock *block = map->getBlockNoCreateNoEx(data->target_block); + if (block == NULL || block->isDummy()) { + // The work is done if the block does not contain data. + data->data.clear(); + return false; + } + // Dummy boolean + bool is_valid; + // For each changing column of nodes: + size_t index; + for (index = 0; index < data->data.size(); index++) { + SunlightPropagationUnit it = data->data[index]; + // Relative position of the currently inspected node. + relative_v3 current_pos(it.relative_pos.X, MAP_BLOCKSIZE - 1, + it.relative_pos.Y); + if (it.is_sunlit) { + // Propagate sunlight. + // For each node downwards: + for (; current_pos.Y >= 0; current_pos.Y--) { + MapNode n = block->getNodeNoCheck(current_pos, &is_valid); + const ContentFeatures &f = ndef->get(n); + if (n.getLightRaw(LIGHTBANK_DAY, f) < LIGHT_SUN + && f.sunlight_propagates) { + // This node gets sunlight. + n.setLight(LIGHTBANK_DAY, LIGHT_SUN, f); + block->setNodeNoCheck(current_pos, n); + modified = true; + relight->push(LIGHT_SUN, current_pos, data->target_block, + block, 4); + } else { + // Light already valid, propagation stopped. + break; + } + } + } else { + // Propagate shadow. + // For each node downwards: + for (; current_pos.Y >= 0; current_pos.Y--) { + MapNode n = block->getNodeNoCheck(current_pos, &is_valid); + const ContentFeatures &f = ndef->get(n); + if (n.getLightRaw(LIGHTBANK_DAY, f) == LIGHT_SUN) { + // The sunlight is no longer valid. + n.setLight(LIGHTBANK_DAY, 0, f); + block->setNodeNoCheck(current_pos, n); + modified = true; + unlight->push(LIGHT_SUN, current_pos, data->target_block, + block, 4); + } else { + // Reached shadow, propagation stopped. + break; + } + } + } + if (current_pos.Y >= 0) { + // Propagation stopped, remove from data. + data->data[index] = data->data.back(); + data->data.pop_back(); + index--; + } + } + return modified; +} + +/*! + * Borders of a map block in relative node coordinates. + * The areas do not overlap. + * Compatible with type 'direction'. + */ +const VoxelArea block_pad[] = { + VoxelArea(v3s16(15, 0, 0), v3s16(15, 15, 15)), //X+ + VoxelArea(v3s16(1, 15, 0), v3s16(14, 15, 15)), //Y+ + VoxelArea(v3s16(1, 1, 15), v3s16(14, 14, 15)), //Z+ + VoxelArea(v3s16(1, 1, 0), v3s16(14, 14, 0)), //Z- + VoxelArea(v3s16(1, 0, 0), v3s16(14, 0, 15)), //Y- + VoxelArea(v3s16(0, 0, 0), v3s16(0, 15, 15)) //X- +}; + +/*! + * The common part of bulk light updates - it is always executed. + * The procedure takes the nodes that should be unlit, and the + * full modified area. + * + * The procedure handles the correction of all lighting except + * direct sunlight spreading. + * + * \param minblock least coordinates of the changed area in block + * coordinates + * \param maxblock greatest coordinates of the changed area in block + * coordinates + * \param unlight the first queue is for day light, the second is for + * night light. Contains all nodes on the borders that need to be unlit. + * \param relight the first queue is for day light, the second is for + * night light. Contains nodes that were not modified, but got sunlight + * because the changes. + * \param modified_blocks the procedure adds all modified blocks to + * this map + */ +void finish_bulk_light_update(Map *map, mapblock_v3 minblock, + mapblock_v3 maxblock, UnlightQueue unlight[2], ReLightQueue relight[2], + std::map<v3s16, MapBlock*> *modified_blocks) +{ + const NodeDefManager *ndef = map->getNodeDefManager(); + // dummy boolean + bool is_valid; + + // --- STEP 1: Do unlighting + + for (size_t bank = 0; bank < 2; bank++) { + LightBank b = banks[bank]; + unspread_light(map, ndef, b, unlight[bank], relight[bank], + *modified_blocks); + } + + // --- STEP 2: Get all newly inserted light sources + + // For each block: + v3s16 blockpos; + v3s16 relpos; + for (blockpos.X = minblock.X; blockpos.X <= maxblock.X; blockpos.X++) + for (blockpos.Y = minblock.Y; blockpos.Y <= maxblock.Y; blockpos.Y++) + for (blockpos.Z = minblock.Z; blockpos.Z <= maxblock.Z; blockpos.Z++) { + MapBlock *block = map->getBlockNoCreateNoEx(blockpos); + if (!block || block->isDummy()) + // Skip not existing blocks + continue; + // For each node in the block: + for (relpos.X = 0; relpos.X < MAP_BLOCKSIZE; relpos.X++) + for (relpos.Z = 0; relpos.Z < MAP_BLOCKSIZE; relpos.Z++) + for (relpos.Y = 0; relpos.Y < MAP_BLOCKSIZE; relpos.Y++) { + MapNode node = block->getNodeNoCheck(relpos.X, relpos.Y, relpos.Z, &is_valid); + const ContentFeatures &f = ndef->get(node); + + // For each light bank + for (size_t b = 0; b < 2; b++) { + LightBank bank = banks[b]; + u8 light = f.param_type == CPT_LIGHT ? + node.getLightNoChecks(bank, &f): + f.light_source; + if (light > 1) + relight[b].push(light, relpos, blockpos, block, 6); + } // end of banks + } // end of nodes + } // end of blocks + + // --- STEP 3: do light spreading + + // For each light bank: + for (size_t b = 0; b < 2; b++) { + LightBank bank = banks[b]; + // Sunlight is already initialized. + u8 maxlight = (b == 0) ? LIGHT_MAX : LIGHT_SUN; + // Initialize light values for light spreading. + for (u8 i = 0; i <= maxlight; i++) { + const std::vector<ChangingLight> &lights = relight[b].lights[i]; + for (std::vector<ChangingLight>::const_iterator it = lights.begin(); + it < lights.end(); ++it) { + MapNode n = it->block->getNodeNoCheck(it->rel_position, + &is_valid); + n.setLight(bank, i, ndef); + it->block->setNodeNoCheck(it->rel_position, n); + } + } + // Spread lights. + spread_light(map, ndef, bank, relight[b], *modified_blocks); + } +} + +void blit_back_with_light(ServerMap *map, MMVManip *vm, + std::map<v3s16, MapBlock*> *modified_blocks) +{ + const NodeDefManager *ndef = map->getNodeDefManager(); + mapblock_v3 minblock = getNodeBlockPos(vm->m_area.MinEdge); + mapblock_v3 maxblock = getNodeBlockPos(vm->m_area.MaxEdge); + // First queue is for day light, second is for night light. + UnlightQueue unlight[] = { UnlightQueue(256), UnlightQueue(256) }; + ReLightQueue relight[] = { ReLightQueue(256), ReLightQueue(256) }; + // Will hold sunlight data. + bool lights[MAP_BLOCKSIZE][MAP_BLOCKSIZE]; + SunlightPropagationData data; + // Dummy boolean. + bool is_valid; + + // --- STEP 1: reset everything to sunlight + + // For each map block: + for (s16 x = minblock.X; x <= maxblock.X; x++) + for (s16 z = minblock.Z; z <= maxblock.Z; z++) { + // Extract sunlight above. + is_sunlight_above_block(map, v3s16(x, maxblock.Y, z), ndef, lights); + v2s16 offset(x, z); + offset *= MAP_BLOCKSIZE; + // Reset the voxel manipulator. + fill_with_sunlight(vm, ndef, offset, lights); + // Copy sunlight data + data.target_block = v3s16(x, minblock.Y - 1, z); + for (s16 z = 0; z < MAP_BLOCKSIZE; z++) + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) + data.data.emplace_back(v2s16(x, z), lights[z][x]); + // Propagate sunlight and shadow below the voxel manipulator. + while (!data.data.empty()) { + if (propagate_block_sunlight(map, ndef, &data, &unlight[0], + &relight[0])) + (*modified_blocks)[data.target_block] = + map->getBlockNoCreateNoEx(data.target_block); + // Step downwards. + data.target_block.Y--; + } + } + + // --- STEP 2: Get nodes from borders to unlight + v3s16 blockpos; + v3s16 relpos; + + // In case there are unloaded holes in the voxel manipulator + // unlight each block. + // For each block: + for (blockpos.X = minblock.X; blockpos.X <= maxblock.X; blockpos.X++) + for (blockpos.Y = minblock.Y; blockpos.Y <= maxblock.Y; blockpos.Y++) + for (blockpos.Z = minblock.Z; blockpos.Z <= maxblock.Z; blockpos.Z++) { + MapBlock *block = map->getBlockNoCreateNoEx(blockpos); + if (!block || block->isDummy()) + // Skip not existing blocks. + continue; + v3s16 offset = block->getPosRelative(); + // For each border of the block: + for (const VoxelArea &a : block_pad) { + // For each node of the border: + for (relpos.X = a.MinEdge.X; relpos.X <= a.MaxEdge.X; relpos.X++) + for (relpos.Z = a.MinEdge.Z; relpos.Z <= a.MaxEdge.Z; relpos.Z++) + for (relpos.Y = a.MinEdge.Y; relpos.Y <= a.MaxEdge.Y; relpos.Y++) { + + // Get old and new node + MapNode oldnode = block->getNodeNoCheck(relpos, &is_valid); + const ContentFeatures &oldf = ndef->get(oldnode); + MapNode newnode = vm->getNodeNoExNoEmerge(relpos + offset); + const ContentFeatures &newf = oldnode == newnode ? oldf : + ndef->get(newnode); + + // For each light bank + for (size_t b = 0; b < 2; b++) { + LightBank bank = banks[b]; + u8 oldlight = oldf.param_type == CPT_LIGHT ? + oldnode.getLightNoChecks(bank, &oldf): + LIGHT_SUN; // no light information, force unlighting + u8 newlight = newf.param_type == CPT_LIGHT ? + newnode.getLightNoChecks(bank, &newf): + newf.light_source; + // If the new node is dimmer, unlight. + if (oldlight > newlight) { + unlight[b].push( + oldlight, relpos, blockpos, block, 6); + } + } // end of banks + } // end of nodes + } // end of borders + } // end of blocks + + // --- STEP 3: All information extracted, overwrite + + vm->blitBackAll(modified_blocks, true); + + // --- STEP 4: Finish light update + + finish_bulk_light_update(map, minblock, maxblock, unlight, relight, + modified_blocks); +} + +/*! + * Resets the lighting of the given map block to + * complete darkness and full sunlight. + * + * \param light incoming sunlight, light[x][z] is true if there + * is sunlight above the map block at the given x-z coordinates. + * The array's indices are relative node coordinates in the block. + * After the procedure returns, this contains outgoing light at + * the bottom of the map block. + */ +void fill_with_sunlight(MapBlock *block, const NodeDefManager *ndef, + bool light[MAP_BLOCKSIZE][MAP_BLOCKSIZE]) +{ + if (block->isDummy()) + return; + // dummy boolean + bool is_valid; + // For each column of nodes: + for (s16 z = 0; z < MAP_BLOCKSIZE; z++) + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { + // True if the current node has sunlight. + bool lig = light[z][x]; + // For each node, downwards: + for (s16 y = MAP_BLOCKSIZE - 1; y >= 0; y--) { + MapNode n = block->getNodeNoCheck(x, y, z, &is_valid); + // Ignore IGNORE nodes, these are not generated yet. + if (n.getContent() == CONTENT_IGNORE) + continue; + const ContentFeatures &f = ndef->get(n.getContent()); + if (lig && !f.sunlight_propagates) { + // Sunlight is stopped. + lig = false; + } + // Reset light + n.setLight(LIGHTBANK_DAY, lig ? 15 : 0, f); + n.setLight(LIGHTBANK_NIGHT, 0, f); + block->setNodeNoCheck(x, y, z, n); + } + // Output outgoing light. + light[z][x] = lig; + } +} + +void repair_block_light(ServerMap *map, MapBlock *block, + std::map<v3s16, MapBlock*> *modified_blocks) +{ + if (!block || block->isDummy()) + return; + const NodeDefManager *ndef = map->getNodeDefManager(); + // First queue is for day light, second is for night light. + UnlightQueue unlight[] = { UnlightQueue(256), UnlightQueue(256) }; + ReLightQueue relight[] = { ReLightQueue(256), ReLightQueue(256) }; + // Will hold sunlight data. + bool lights[MAP_BLOCKSIZE][MAP_BLOCKSIZE]; + SunlightPropagationData data; + // Dummy boolean. + bool is_valid; + + // --- STEP 1: reset everything to sunlight + + mapblock_v3 blockpos = block->getPos(); + (*modified_blocks)[blockpos] = block; + // For each map block: + // Extract sunlight above. + is_sunlight_above_block(map, blockpos, ndef, lights); + // Reset the voxel manipulator. + fill_with_sunlight(block, ndef, lights); + // Copy sunlight data + data.target_block = v3s16(blockpos.X, blockpos.Y - 1, blockpos.Z); + for (s16 z = 0; z < MAP_BLOCKSIZE; z++) + for (s16 x = 0; x < MAP_BLOCKSIZE; x++) { + data.data.emplace_back(v2s16(x, z), lights[z][x]); + } + // Propagate sunlight and shadow below the voxel manipulator. + while (!data.data.empty()) { + if (propagate_block_sunlight(map, ndef, &data, &unlight[0], + &relight[0])) + (*modified_blocks)[data.target_block] = + map->getBlockNoCreateNoEx(data.target_block); + // Step downwards. + data.target_block.Y--; + } + + // --- STEP 2: Get nodes from borders to unlight + + // For each border of the block: + for (const VoxelArea &a : block_pad) { + v3s16 relpos; + // For each node of the border: + for (relpos.X = a.MinEdge.X; relpos.X <= a.MaxEdge.X; relpos.X++) + for (relpos.Z = a.MinEdge.Z; relpos.Z <= a.MaxEdge.Z; relpos.Z++) + for (relpos.Y = a.MinEdge.Y; relpos.Y <= a.MaxEdge.Y; relpos.Y++) { + + // Get node + MapNode node = block->getNodeNoCheck(relpos, &is_valid); + const ContentFeatures &f = ndef->get(node); + // For each light bank + for (size_t b = 0; b < 2; b++) { + LightBank bank = banks[b]; + u8 light = f.param_type == CPT_LIGHT ? + node.getLightNoChecks(bank, &f): + f.light_source; + // If the new node is dimmer than sunlight, unlight. + // (if it has maximal light, it is pointless to remove + // surrounding light, as it can only become brighter) + if (LIGHT_SUN > light) { + unlight[b].push( + LIGHT_SUN, relpos, blockpos, block, 6); + } + } // end of banks + } // end of nodes + } // end of borders + + // STEP 3: Remove and spread light + + finish_bulk_light_update(map, blockpos, blockpos, unlight, relight, + modified_blocks); +} + +VoxelLineIterator::VoxelLineIterator(const v3f &start_position, const v3f &line_vector) : + m_start_position(start_position), + m_line_vector(line_vector) +{ + m_current_node_pos = floatToInt(m_start_position, 1); + m_start_node_pos = m_current_node_pos; + m_last_index = getIndex(floatToInt(start_position + line_vector, 1)); + + if (m_line_vector.X > 0) { + m_next_intersection_multi.X = (floorf(m_start_position.X - 0.5) + 1.5 + - m_start_position.X) / m_line_vector.X; + m_intersection_multi_inc.X = 1 / m_line_vector.X; + } else if (m_line_vector.X < 0) { + m_next_intersection_multi.X = (floorf(m_start_position.X - 0.5) + - m_start_position.X + 0.5) / m_line_vector.X; + m_intersection_multi_inc.X = -1 / m_line_vector.X; + m_step_directions.X = -1; + } + + if (m_line_vector.Y > 0) { + m_next_intersection_multi.Y = (floorf(m_start_position.Y - 0.5) + 1.5 + - m_start_position.Y) / m_line_vector.Y; + m_intersection_multi_inc.Y = 1 / m_line_vector.Y; + } else if (m_line_vector.Y < 0) { + m_next_intersection_multi.Y = (floorf(m_start_position.Y - 0.5) + - m_start_position.Y + 0.5) / m_line_vector.Y; + m_intersection_multi_inc.Y = -1 / m_line_vector.Y; + m_step_directions.Y = -1; + } + + if (m_line_vector.Z > 0) { + m_next_intersection_multi.Z = (floorf(m_start_position.Z - 0.5) + 1.5 + - m_start_position.Z) / m_line_vector.Z; + m_intersection_multi_inc.Z = 1 / m_line_vector.Z; + } else if (m_line_vector.Z < 0) { + m_next_intersection_multi.Z = (floorf(m_start_position.Z - 0.5) + - m_start_position.Z + 0.5) / m_line_vector.Z; + m_intersection_multi_inc.Z = -1 / m_line_vector.Z; + m_step_directions.Z = -1; + } +} + +void VoxelLineIterator::next() +{ + m_current_index++; + if ((m_next_intersection_multi.X < m_next_intersection_multi.Y) + && (m_next_intersection_multi.X < m_next_intersection_multi.Z)) { + m_next_intersection_multi.X += m_intersection_multi_inc.X; + m_current_node_pos.X += m_step_directions.X; + } else if ((m_next_intersection_multi.Y < m_next_intersection_multi.Z)) { + m_next_intersection_multi.Y += m_intersection_multi_inc.Y; + m_current_node_pos.Y += m_step_directions.Y; + } else { + m_next_intersection_multi.Z += m_intersection_multi_inc.Z; + m_current_node_pos.Z += m_step_directions.Z; + } +} + +s16 VoxelLineIterator::getIndex(v3s16 voxel){ + return + abs(voxel.X - m_start_node_pos.X) + + abs(voxel.Y - m_start_node_pos.Y) + + abs(voxel.Z - m_start_node_pos.Z); +} + +} // namespace voxalgo + diff --git a/src/voxelalgorithms.h b/src/voxelalgorithms.h new file mode 100644 index 0000000..bcbd3b5 --- /dev/null +++ b/src/voxelalgorithms.h @@ -0,0 +1,157 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@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; either version 2.1 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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "voxel.h" +#include "mapnode.h" +#include "util/container.h" + +class Map; +class ServerMap; +class MapBlock; +class MMVManip; + +namespace voxalgo +{ + +/*! + * Updates the lighting on the map. + * The result will be correct only if + * no nodes were changed except the given ones. + * Before calling this procedure make sure that all new nodes on + * the map have zero light level! + * + * \param oldnodes contains the MapNodes that were replaced by the new + * MapNodes and their positions + * \param modified_blocks output, contains all map blocks that + * the function modified + */ +void update_lighting_nodes( + Map *map, + const std::vector<std::pair<v3s16, MapNode>> &oldnodes, + std::map<v3s16, MapBlock*> &modified_blocks); + +/*! + * Updates borders of the given mapblock. + * Only updates if the block was marked with incomplete + * lighting and the neighbor is also loaded. + * + * \param block the block to update + * \param modified_blocks output, contains all map blocks that + * the function modified + */ +void update_block_border_lighting(Map *map, MapBlock *block, + std::map<v3s16, MapBlock*> &modified_blocks); + +/*! + * Copies back nodes from a voxel manipulator + * to the map and updates lighting. + * For server use only. + * + * \param modified_blocks output, contains all map blocks that + * the function modified + */ +void blit_back_with_light(ServerMap *map, MMVManip *vm, + std::map<v3s16, MapBlock*> *modified_blocks); + +/*! + * Corrects the light in a map block. + * For server use only. + * + * \param block the block to update + */ +void repair_block_light(ServerMap *map, MapBlock *block, + std::map<v3s16, MapBlock*> *modified_blocks); + +/*! + * This class iterates trough voxels that intersect with + * a line. The collision detection does not see nodeboxes, + * every voxel is a cube and is returned. + * This iterator steps to all nodes exactly once. + */ +struct VoxelLineIterator +{ +public: + //! Starting position of the line in world coordinates. + v3f m_start_position; + //! Direction and length of the line in world coordinates. + v3f m_line_vector; + /*! + * Each component stores the next smallest positive number, by + * which multiplying the line's vector gives a vector that ends + * on the intersection of two nodes. + */ + v3f m_next_intersection_multi { 10000.0f, 10000.0f, 10000.0f }; + /*! + * Each component stores the smallest positive number, by which + * m_next_intersection_multi's components can be increased. + */ + v3f m_intersection_multi_inc { 10000.0f, 10000.0f, 10000.0f }; + /*! + * Direction of the line. Each component can be -1 or 1 (if a + * component of the line's vector is 0, then there will be 1). + */ + v3s16 m_step_directions { 1, 1, 1 }; + //! Position of the current node. + v3s16 m_current_node_pos; + //! Index of the current node + s16 m_current_index = 0; + //! Position of the start node. + v3s16 m_start_node_pos; + //! Index of the last node + s16 m_last_index; + + /*! + * Creates a voxel line iterator with the given line. + * @param start_position starting point of the line + * in voxel coordinates + * @param line_vector length and direction of the + * line in voxel coordinates. start_position+line_vector + * is the end of the line + */ + VoxelLineIterator(const v3f &start_position,const v3f &line_vector); + + /*! + * Steps to the next voxel. + * Updates m_current_node_pos and + * m_previous_node_pos. + * Note that it works even if hasNext() is false, + * continuing the line as a ray. + */ + void next(); + + /*! + * Returns true if the next voxel intersects the given line. + */ + inline bool hasNext() const + { + return m_current_index < m_last_index; + } + + /*! + * Returns how many times next() must be called until + * voxel==m_current_node_pos. + * If voxel does not intersect with the line, + * the result is undefined. + */ + s16 getIndex(v3s16 voxel); +}; + +} // namespace voxalgo diff --git a/textures/base/pack/air.png b/textures/base/pack/air.png new file mode 100644 index 0000000..e2c4872 Binary files /dev/null and b/textures/base/pack/air.png differ diff --git a/textures/base/pack/aux1_btn.png b/textures/base/pack/aux1_btn.png new file mode 100644 index 0000000..8ceb095 Binary files /dev/null and b/textures/base/pack/aux1_btn.png differ diff --git a/textures/base/pack/blank.png b/textures/base/pack/blank.png new file mode 100644 index 0000000..85e0250 Binary files /dev/null and b/textures/base/pack/blank.png differ diff --git a/textures/base/pack/bubble.png b/textures/base/pack/bubble.png new file mode 100644 index 0000000..799327c Binary files /dev/null and b/textures/base/pack/bubble.png differ diff --git a/textures/base/pack/bubble_gone.png b/textures/base/pack/bubble_gone.png new file mode 100644 index 0000000..240ca4f Binary files /dev/null and b/textures/base/pack/bubble_gone.png differ diff --git a/textures/base/pack/camera_btn.png b/textures/base/pack/camera_btn.png new file mode 100644 index 0000000..9327dc4 Binary files /dev/null and b/textures/base/pack/camera_btn.png differ diff --git a/textures/base/pack/cdb_add.png b/textures/base/pack/cdb_add.png new file mode 100644 index 0000000..3e3d067 Binary files /dev/null and b/textures/base/pack/cdb_add.png differ diff --git a/textures/base/pack/cdb_clear.png b/textures/base/pack/cdb_clear.png new file mode 100644 index 0000000..4490d41 Binary files /dev/null and b/textures/base/pack/cdb_clear.png differ diff --git a/textures/base/pack/cdb_downloading.png b/textures/base/pack/cdb_downloading.png new file mode 100644 index 0000000..8cba383 Binary files /dev/null and b/textures/base/pack/cdb_downloading.png differ diff --git a/textures/base/pack/cdb_queued.png b/textures/base/pack/cdb_queued.png new file mode 100644 index 0000000..6972f7f Binary files /dev/null and b/textures/base/pack/cdb_queued.png differ diff --git a/textures/base/pack/cdb_update.png b/textures/base/pack/cdb_update.png new file mode 100644 index 0000000..262e42d Binary files /dev/null and b/textures/base/pack/cdb_update.png differ diff --git a/textures/base/pack/cdb_viewonline.png b/textures/base/pack/cdb_viewonline.png new file mode 100644 index 0000000..ae2a146 Binary files /dev/null and b/textures/base/pack/cdb_viewonline.png differ diff --git a/textures/base/pack/chat_btn.png b/textures/base/pack/chat_btn.png new file mode 100644 index 0000000..be4477d Binary files /dev/null and b/textures/base/pack/chat_btn.png differ diff --git a/textures/base/pack/chat_hide_btn.png b/textures/base/pack/chat_hide_btn.png new file mode 100644 index 0000000..92a8ece Binary files /dev/null and b/textures/base/pack/chat_hide_btn.png differ diff --git a/textures/base/pack/chat_show_btn.png b/textures/base/pack/chat_show_btn.png new file mode 100644 index 0000000..b260d25 Binary files /dev/null and b/textures/base/pack/chat_show_btn.png differ diff --git a/textures/base/pack/checkbox_16.png b/textures/base/pack/checkbox_16.png new file mode 100644 index 0000000..db6101f Binary files /dev/null and b/textures/base/pack/checkbox_16.png differ diff --git a/textures/base/pack/checkbox_16_white.png b/textures/base/pack/checkbox_16_white.png new file mode 100644 index 0000000..0cf0f3e Binary files /dev/null and b/textures/base/pack/checkbox_16_white.png differ diff --git a/textures/base/pack/checkbox_32.png b/textures/base/pack/checkbox_32.png new file mode 100644 index 0000000..f5ff59a Binary files /dev/null and b/textures/base/pack/checkbox_32.png differ diff --git a/textures/base/pack/checkbox_64.png b/textures/base/pack/checkbox_64.png new file mode 100644 index 0000000..03eb90b Binary files /dev/null and b/textures/base/pack/checkbox_64.png differ diff --git a/textures/base/pack/clear.png b/textures/base/pack/clear.png new file mode 100644 index 0000000..9244264 Binary files /dev/null and b/textures/base/pack/clear.png differ diff --git a/textures/base/pack/crack_anylength.png b/textures/base/pack/crack_anylength.png new file mode 100644 index 0000000..d9b49f9 Binary files /dev/null and b/textures/base/pack/crack_anylength.png differ diff --git a/textures/base/pack/debug_btn.png b/textures/base/pack/debug_btn.png new file mode 100644 index 0000000..ab210a6 Binary files /dev/null and b/textures/base/pack/debug_btn.png differ diff --git a/textures/base/pack/down.png b/textures/base/pack/down.png new file mode 100644 index 0000000..c290d3a Binary files /dev/null and b/textures/base/pack/down.png differ diff --git a/textures/base/pack/drop_btn.png b/textures/base/pack/drop_btn.png new file mode 100644 index 0000000..4403ce6 Binary files /dev/null and b/textures/base/pack/drop_btn.png differ diff --git a/textures/base/pack/end_icon.png b/textures/base/pack/end_icon.png new file mode 100644 index 0000000..4fb4d52 Binary files /dev/null and b/textures/base/pack/end_icon.png differ diff --git a/textures/base/pack/error_icon_orange.png b/textures/base/pack/error_icon_orange.png new file mode 100644 index 0000000..1f1586f Binary files /dev/null and b/textures/base/pack/error_icon_orange.png differ diff --git a/textures/base/pack/error_icon_red.png b/textures/base/pack/error_icon_red.png new file mode 100644 index 0000000..1f5bafb Binary files /dev/null and b/textures/base/pack/error_icon_red.png differ diff --git a/textures/base/pack/error_screenshot.png b/textures/base/pack/error_screenshot.png new file mode 100644 index 0000000..e35a0a3 Binary files /dev/null and b/textures/base/pack/error_screenshot.png differ diff --git a/textures/base/pack/fast_btn.png b/textures/base/pack/fast_btn.png new file mode 100644 index 0000000..aeb4d3c Binary files /dev/null and b/textures/base/pack/fast_btn.png differ diff --git a/textures/base/pack/fly_btn.png b/textures/base/pack/fly_btn.png new file mode 100644 index 0000000..641d0fa Binary files /dev/null and b/textures/base/pack/fly_btn.png differ diff --git a/textures/base/pack/gear_icon.png b/textures/base/pack/gear_icon.png new file mode 100644 index 0000000..520e82e Binary files /dev/null and b/textures/base/pack/gear_icon.png differ diff --git a/textures/base/pack/halo.png b/textures/base/pack/halo.png new file mode 100644 index 0000000..ed3ff9d Binary files /dev/null and b/textures/base/pack/halo.png differ diff --git a/textures/base/pack/heart.png b/textures/base/pack/heart.png new file mode 100644 index 0000000..13db59b Binary files /dev/null and b/textures/base/pack/heart.png differ diff --git a/textures/base/pack/heart_gone.png b/textures/base/pack/heart_gone.png new file mode 100644 index 0000000..240ca4f Binary files /dev/null and b/textures/base/pack/heart_gone.png differ diff --git a/textures/base/pack/ignore.png b/textures/base/pack/ignore.png new file mode 100644 index 0000000..a73d222 Binary files /dev/null and b/textures/base/pack/ignore.png differ diff --git a/textures/base/pack/inventory_btn.png b/textures/base/pack/inventory_btn.png new file mode 100644 index 0000000..278ce39 Binary files /dev/null and b/textures/base/pack/inventory_btn.png differ diff --git a/textures/base/pack/joystick_bg.png b/textures/base/pack/joystick_bg.png new file mode 100644 index 0000000..4061939 Binary files /dev/null and b/textures/base/pack/joystick_bg.png differ diff --git a/textures/base/pack/joystick_center.png b/textures/base/pack/joystick_center.png new file mode 100644 index 0000000..1e4754d Binary files /dev/null and b/textures/base/pack/joystick_center.png differ diff --git a/textures/base/pack/joystick_off.png b/textures/base/pack/joystick_off.png new file mode 100644 index 0000000..6dfbc7a Binary files /dev/null and b/textures/base/pack/joystick_off.png differ diff --git a/textures/base/pack/jump_btn.png b/textures/base/pack/jump_btn.png new file mode 100644 index 0000000..d21b4a9 Binary files /dev/null and b/textures/base/pack/jump_btn.png differ diff --git a/textures/base/pack/loading_screenshot.png b/textures/base/pack/loading_screenshot.png new file mode 100644 index 0000000..4d65a5d Binary files /dev/null and b/textures/base/pack/loading_screenshot.png differ diff --git a/textures/base/pack/logo.png b/textures/base/pack/logo.png new file mode 100644 index 0000000..4879367 Binary files /dev/null and b/textures/base/pack/logo.png differ diff --git a/textures/base/pack/menu_bg.png b/textures/base/pack/menu_bg.png new file mode 100644 index 0000000..ed7e34f Binary files /dev/null and b/textures/base/pack/menu_bg.png differ diff --git a/textures/base/pack/menu_header.png b/textures/base/pack/menu_header.png new file mode 100644 index 0000000..0769a01 Binary files /dev/null and b/textures/base/pack/menu_header.png differ diff --git a/textures/base/pack/minimap_btn.png b/textures/base/pack/minimap_btn.png new file mode 100644 index 0000000..727ba1e Binary files /dev/null and b/textures/base/pack/minimap_btn.png differ diff --git a/textures/base/pack/minimap_mask_round.png b/textures/base/pack/minimap_mask_round.png new file mode 100644 index 0000000..a0c6b2d Binary files /dev/null and b/textures/base/pack/minimap_mask_round.png differ diff --git a/textures/base/pack/minimap_mask_square.png b/textures/base/pack/minimap_mask_square.png new file mode 100644 index 0000000..160b6fa Binary files /dev/null and b/textures/base/pack/minimap_mask_square.png differ diff --git a/textures/base/pack/minimap_overlay_round.png b/textures/base/pack/minimap_overlay_round.png new file mode 100644 index 0000000..16e3c41 Binary files /dev/null and b/textures/base/pack/minimap_overlay_round.png differ diff --git a/textures/base/pack/minimap_overlay_square.png b/textures/base/pack/minimap_overlay_square.png new file mode 100644 index 0000000..c971c4b Binary files /dev/null and b/textures/base/pack/minimap_overlay_square.png differ diff --git a/textures/base/pack/next_icon.png b/textures/base/pack/next_icon.png new file mode 100644 index 0000000..03f9609 Binary files /dev/null and b/textures/base/pack/next_icon.png differ diff --git a/textures/base/pack/no_screenshot.png b/textures/base/pack/no_screenshot.png new file mode 100644 index 0000000..14df091 Binary files /dev/null and b/textures/base/pack/no_screenshot.png differ diff --git a/textures/base/pack/no_texture.png b/textures/base/pack/no_texture.png new file mode 100644 index 0000000..681b810 Binary files /dev/null and b/textures/base/pack/no_texture.png differ diff --git a/textures/base/pack/no_texture_airlike.png b/textures/base/pack/no_texture_airlike.png new file mode 100644 index 0000000..634ee8c Binary files /dev/null and b/textures/base/pack/no_texture_airlike.png differ diff --git a/textures/base/pack/noclip_btn.png b/textures/base/pack/noclip_btn.png new file mode 100644 index 0000000..5d7372d Binary files /dev/null and b/textures/base/pack/noclip_btn.png differ diff --git a/textures/base/pack/object_marker_red.png b/textures/base/pack/object_marker_red.png new file mode 100644 index 0000000..f345d03 Binary files /dev/null and b/textures/base/pack/object_marker_red.png differ diff --git a/textures/base/pack/player.png b/textures/base/pack/player.png new file mode 100644 index 0000000..6d61c43 Binary files /dev/null and b/textures/base/pack/player.png differ diff --git a/textures/base/pack/player_back.png b/textures/base/pack/player_back.png new file mode 100644 index 0000000..5e9ef05 Binary files /dev/null and b/textures/base/pack/player_back.png differ diff --git a/textures/base/pack/player_marker.png b/textures/base/pack/player_marker.png new file mode 100644 index 0000000..f2cc2c6 Binary files /dev/null and b/textures/base/pack/player_marker.png differ diff --git a/textures/base/pack/plus.png b/textures/base/pack/plus.png new file mode 100644 index 0000000..64680b5 Binary files /dev/null and b/textures/base/pack/plus.png differ diff --git a/textures/base/pack/prev_icon.png b/textures/base/pack/prev_icon.png new file mode 100644 index 0000000..71509e7 Binary files /dev/null and b/textures/base/pack/prev_icon.png differ diff --git a/textures/base/pack/progress_bar.png b/textures/base/pack/progress_bar.png new file mode 100644 index 0000000..e803671 Binary files /dev/null and b/textures/base/pack/progress_bar.png differ diff --git a/textures/base/pack/progress_bar_bg.png b/textures/base/pack/progress_bar_bg.png new file mode 100644 index 0000000..4e30ae8 Binary files /dev/null and b/textures/base/pack/progress_bar_bg.png differ diff --git a/textures/base/pack/rangeview_btn.png b/textures/base/pack/rangeview_btn.png new file mode 100644 index 0000000..e49a1b6 Binary files /dev/null and b/textures/base/pack/rangeview_btn.png differ diff --git a/textures/base/pack/rare_controls.png b/textures/base/pack/rare_controls.png new file mode 100644 index 0000000..953d9e0 Binary files /dev/null and b/textures/base/pack/rare_controls.png differ diff --git a/textures/base/pack/refresh.png b/textures/base/pack/refresh.png new file mode 100644 index 0000000..7193677 Binary files /dev/null and b/textures/base/pack/refresh.png differ diff --git a/textures/base/pack/search.png b/textures/base/pack/search.png new file mode 100644 index 0000000..aace804 Binary files /dev/null and b/textures/base/pack/search.png differ diff --git a/textures/base/pack/server_favorite.png b/textures/base/pack/server_favorite.png new file mode 100644 index 0000000..6a3fc5e Binary files /dev/null and b/textures/base/pack/server_favorite.png differ diff --git a/textures/base/pack/server_favorite_delete.png b/textures/base/pack/server_favorite_delete.png new file mode 100644 index 0000000..e35c6aa Binary files /dev/null and b/textures/base/pack/server_favorite_delete.png differ diff --git a/textures/base/pack/server_flags_creative.png b/textures/base/pack/server_flags_creative.png new file mode 100644 index 0000000..fa37a19 Binary files /dev/null and b/textures/base/pack/server_flags_creative.png differ diff --git a/textures/base/pack/server_flags_damage.png b/textures/base/pack/server_flags_damage.png new file mode 100644 index 0000000..3f0bf0d Binary files /dev/null and b/textures/base/pack/server_flags_damage.png differ diff --git a/textures/base/pack/server_flags_pvp.png b/textures/base/pack/server_flags_pvp.png new file mode 100644 index 0000000..977dfdc Binary files /dev/null and b/textures/base/pack/server_flags_pvp.png differ diff --git a/textures/base/pack/server_incompatible.png b/textures/base/pack/server_incompatible.png new file mode 100644 index 0000000..9076ab5 Binary files /dev/null and b/textures/base/pack/server_incompatible.png differ diff --git a/textures/base/pack/server_ping_1.png b/textures/base/pack/server_ping_1.png new file mode 100644 index 0000000..ba5bba1 Binary files /dev/null and b/textures/base/pack/server_ping_1.png differ diff --git a/textures/base/pack/server_ping_2.png b/textures/base/pack/server_ping_2.png new file mode 100644 index 0000000..8dca0be Binary files /dev/null and b/textures/base/pack/server_ping_2.png differ diff --git a/textures/base/pack/server_ping_3.png b/textures/base/pack/server_ping_3.png new file mode 100644 index 0000000..c2cab01 Binary files /dev/null and b/textures/base/pack/server_ping_3.png differ diff --git a/textures/base/pack/server_ping_4.png b/textures/base/pack/server_ping_4.png new file mode 100644 index 0000000..03b4b5b Binary files /dev/null and b/textures/base/pack/server_ping_4.png differ diff --git a/textures/base/pack/server_public.png b/textures/base/pack/server_public.png new file mode 100644 index 0000000..46a48fa Binary files /dev/null and b/textures/base/pack/server_public.png differ diff --git a/textures/base/pack/smoke_puff.png b/textures/base/pack/smoke_puff.png new file mode 100644 index 0000000..488b50f Binary files /dev/null and b/textures/base/pack/smoke_puff.png differ diff --git a/textures/base/pack/start_icon.png b/textures/base/pack/start_icon.png new file mode 100644 index 0000000..3830fb3 Binary files /dev/null and b/textures/base/pack/start_icon.png differ diff --git a/textures/base/pack/sunrisebg.png b/textures/base/pack/sunrisebg.png new file mode 100644 index 0000000..3352317 Binary files /dev/null and b/textures/base/pack/sunrisebg.png differ diff --git a/textures/base/pack/unknown_item.png b/textures/base/pack/unknown_item.png new file mode 100644 index 0000000..c8cf616 Binary files /dev/null and b/textures/base/pack/unknown_item.png differ diff --git a/textures/base/pack/unknown_node.png b/textures/base/pack/unknown_node.png new file mode 100644 index 0000000..cb59ff4 Binary files /dev/null and b/textures/base/pack/unknown_node.png differ diff --git a/textures/base/pack/unknown_object.png b/textures/base/pack/unknown_object.png new file mode 100644 index 0000000..c0166c3 Binary files /dev/null and b/textures/base/pack/unknown_object.png differ diff --git a/textures/base/pack/wieldhand.png b/textures/base/pack/wieldhand.png new file mode 100644 index 0000000..ff2283a Binary files /dev/null and b/textures/base/pack/wieldhand.png differ diff --git a/textures/base/pack/zoom.png b/textures/base/pack/zoom.png new file mode 100644 index 0000000..b27c8c8 Binary files /dev/null and b/textures/base/pack/zoom.png differ diff --git a/util/buildbot/buildwin32.sh b/util/buildbot/buildwin32.sh new file mode 100644 index 0000000..3df48f1 --- /dev/null +++ b/util/buildbot/buildwin32.sh @@ -0,0 +1,190 @@ +#!/bin/bash +set -e + +CORE_GIT=https://github.com/minetest/minetest +CORE_BRANCH=master +CORE_NAME=minetest +GAME_GIT=https://github.com/minetest/minetest_game +GAME_BRANCH=master +GAME_NAME=minetest_game + +topdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +if [ $# -ne 1 ]; then + echo "Usage: $0 <build directory>" + exit 1 +fi +builddir=$1 +mkdir -p $builddir +builddir="$( cd "$builddir" && pwd )" +libdir=$builddir/libs + +# Test which win32 compiler is present +command -v i686-w64-mingw32-gcc >/dev/null && + compiler=i686-w64-mingw32-gcc +command -v i686-w64-mingw32-gcc-posix >/dev/null && + compiler=i686-w64-mingw32-gcc-posix + +if [ -z "$compiler" ]; then + echo "Unable to determine which MinGW compiler to use" + exit 1 +fi +toolchain_file=$topdir/toolchain_${compiler/-gcc/}.cmake +echo "Using $toolchain_file" + +# Try to find runtime DLLs in various paths (varies by distribution, sigh) +tmp=$(dirname "$(command -v $compiler)")/.. +runtime_dlls= +for name in lib{gcc_,stdc++-,winpthread-}'*'.dll; do + for dir in $tmp/i686-w64-mingw32/{bin,lib} $tmp/lib/gcc/i686-w64-mingw32/*; do + [ -d "$dir" ] || continue + file=$(echo $dir/$name) + [ -f "$file" ] && { runtime_dlls+="$file;"; break; } + done +done +[ -z "$runtime_dlls" ] && + echo "The compiler runtime DLLs could not be found, they might be missing in the final package." + +# Get stuff +irrlicht_version=$(cat $topdir/../../misc/irrlichtmt_tag.txt) +ogg_version=1.3.5 +openal_version=1.21.1 +vorbis_version=1.3.7 +curl_version=7.81.0 +gettext_version=0.20.1 +freetype_version=2.11.1 +sqlite3_version=3.37.2 +luajit_version=2.1.0-beta3 +leveldb_version=1.23 +zlib_version=1.2.11 +zstd_version=1.5.2 + +mkdir -p $libdir + +download () { + local url=$1 + local filename=$2 + [ -z "$filename" ] && filename=${url##*/} + local foldername=${filename%%[.-]*} + local extract=$3 + [ -z "$extract" ] && extract=unzip + + [ -d "./$foldername" ] && return 0 + wget "$url" -c -O "./$filename" + if [ "$extract" = "unzip" ]; then + unzip -o "$filename" -d "$foldername" + elif [ "$extract" = "unzip_nofolder" ]; then + unzip -o "$filename" + else + return 1 + fi +} + +# 'dw2' just points to rebuilt versions after a toolchain change +# this distinction should be gotten rid of next time + +cd $libdir +download "https://github.com/minetest/irrlicht/releases/download/$irrlicht_version/win32.zip" irrlicht-$irrlicht_version.zip +download "http://minetest.kitsunemimi.pw/dw2/zlib-$zlib_version-win32.zip" +download "http://minetest.kitsunemimi.pw/zstd-$zstd_version-win32.zip" +download "http://minetest.kitsunemimi.pw/libogg-$ogg_version-win32.zip" +download "http://minetest.kitsunemimi.pw/dw2/libvorbis-$vorbis_version-win32.zip" +download "http://minetest.kitsunemimi.pw/curl-$curl_version-win32.zip" +download "http://minetest.kitsunemimi.pw/dw2/gettext-$gettext_version-win32.zip" +download "http://minetest.kitsunemimi.pw/freetype2-$freetype_version-win32.zip" freetype-$freetype_version.zip +download "http://minetest.kitsunemimi.pw/sqlite3-$sqlite3_version-win32.zip" +download "http://minetest.kitsunemimi.pw/dw2/luajit-$luajit_version-win32.zip" +download "http://minetest.kitsunemimi.pw/dw2/libleveldb-$leveldb_version-win32.zip" leveldb-$leveldb_version.zip +download "http://minetest.kitsunemimi.pw/openal-soft-$openal_version-win32.zip" + +# Set source dir, downloading Minetest as needed +if [ -n "$EXISTING_MINETEST_DIR" ]; then + sourcedir="$( cd "$EXISTING_MINETEST_DIR" && pwd )" +else + cd $builddir + sourcedir=$PWD/$CORE_NAME + [ -d $CORE_NAME ] && { pushd $CORE_NAME; git pull; popd; } || \ + git clone -b $CORE_BRANCH $CORE_GIT $CORE_NAME + if [ -z "$NO_MINETEST_GAME" ]; then + cd $sourcedir + [ -d games/$GAME_NAME ] && { pushd games/$GAME_NAME; git pull; popd; } || \ + git clone -b $GAME_BRANCH $GAME_GIT games/$GAME_NAME + fi +fi + +git_hash=$(cd $sourcedir && git rev-parse --short HEAD) + +# Build the thing +cd $builddir +[ -d build ] && rm -rf build + +irr_dlls=$(echo $libdir/irrlicht/lib/*.dll | tr ' ' ';') +vorbis_dlls=$(echo $libdir/libvorbis/bin/libvorbis{,file}-*.dll | tr ' ' ';') +gettext_dlls=$(echo $libdir/gettext/bin/lib{intl,iconv}-*.dll | tr ' ' ';') + +cmake -S $sourcedir -B build \ + -DCMAKE_TOOLCHAIN_FILE=$toolchain_file \ + -DCMAKE_INSTALL_PREFIX=/tmp \ + -DVERSION_EXTRA=$git_hash \ + -DBUILD_CLIENT=1 -DBUILD_SERVER=0 \ + -DEXTRA_DLL="$runtime_dlls" \ + \ + -DENABLE_SOUND=1 \ + -DENABLE_CURL=1 \ + -DENABLE_GETTEXT=1 \ + -DENABLE_LEVELDB=1 \ + \ + -DCMAKE_PREFIX_PATH=$libdir/irrlicht \ + -DIRRLICHT_DLL="$irr_dlls" \ + \ + -DZLIB_INCLUDE_DIR=$libdir/zlib/include \ + -DZLIB_LIBRARY=$libdir/zlib/lib/libz.dll.a \ + -DZLIB_DLL=$libdir/zlib/bin/zlib1.dll \ + \ + -DZSTD_INCLUDE_DIR=$libdir/zstd/include \ + -DZSTD_LIBRARY=$libdir/zstd/lib/libzstd.dll.a \ + -DZSTD_DLL=$libdir/zstd/bin/libzstd.dll \ + \ + -DLUA_INCLUDE_DIR=$libdir/luajit/include \ + -DLUA_LIBRARY=$libdir/luajit/libluajit.a \ + \ + -DOGG_INCLUDE_DIR=$libdir/libogg/include \ + -DOGG_LIBRARY=$libdir/libogg/lib/libogg.dll.a \ + -DOGG_DLL=$libdir/libogg/bin/libogg-0.dll \ + \ + -DVORBIS_INCLUDE_DIR=$libdir/libvorbis/include \ + -DVORBIS_LIBRARY=$libdir/libvorbis/lib/libvorbis.dll.a \ + -DVORBIS_DLL="$vorbis_dlls" \ + -DVORBISFILE_LIBRARY=$libdir/libvorbis/lib/libvorbisfile.dll.a \ + \ + -DOPENAL_INCLUDE_DIR=$libdir/openal/include/AL \ + -DOPENAL_LIBRARY=$libdir/openal/lib/libOpenAL32.dll.a \ + -DOPENAL_DLL=$libdir/openal/bin/OpenAL32.dll \ + \ + -DCURL_DLL=$libdir/curl/bin/libcurl-4.dll \ + -DCURL_INCLUDE_DIR=$libdir/curl/include \ + -DCURL_LIBRARY=$libdir/curl/lib/libcurl.dll.a \ + \ + -DGETTEXT_MSGFMT=`command -v msgfmt` \ + -DGETTEXT_DLL="$gettext_dlls" \ + -DGETTEXT_INCLUDE_DIR=$libdir/gettext/include \ + -DGETTEXT_LIBRARY=$libdir/gettext/lib/libintl.dll.a \ + \ + -DFREETYPE_INCLUDE_DIR_freetype2=$libdir/freetype/include/freetype2 \ + -DFREETYPE_INCLUDE_DIR_ft2build=$libdir/freetype/include/freetype2 \ + -DFREETYPE_LIBRARY=$libdir/freetype/lib/libfreetype.dll.a \ + -DFREETYPE_DLL=$libdir/freetype/bin/libfreetype-6.dll \ + \ + -DSQLITE3_INCLUDE_DIR=$libdir/sqlite3/include \ + -DSQLITE3_LIBRARY=$libdir/sqlite3/lib/libsqlite3.dll.a \ + -DSQLITE3_DLL=$libdir/sqlite3/bin/libsqlite3-0.dll \ + \ + -DLEVELDB_INCLUDE_DIR=$libdir/leveldb/include \ + -DLEVELDB_LIBRARY=$libdir/leveldb/lib/libleveldb.dll.a \ + -DLEVELDB_DLL=$libdir/leveldb/bin/libleveldb.dll + +cmake --build build -j$(nproc) + +[ -z "$NO_PACKAGE" ] && cmake --build build --target package + +exit 0 +# EOF diff --git a/util/buildbot/buildwin64.sh b/util/buildbot/buildwin64.sh new file mode 100644 index 0000000..9d222ab --- /dev/null +++ b/util/buildbot/buildwin64.sh @@ -0,0 +1,187 @@ +#!/bin/bash +set -e + +CORE_GIT=https://github.com/minetest/minetest +CORE_BRANCH=master +CORE_NAME=minetest +GAME_GIT=https://github.com/minetest/minetest_game +GAME_BRANCH=master +GAME_NAME=minetest_game + +topdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +if [ $# -ne 1 ]; then + echo "Usage: $0 <build directory>" + exit 1 +fi +builddir=$1 +mkdir -p $builddir +builddir="$( cd "$builddir" && pwd )" +libdir=$builddir/libs + +# Test which win64 compiler is present +command -v x86_64-w64-mingw32-gcc >/dev/null && + compiler=x86_64-w64-mingw32-gcc +command -v x86_64-w64-mingw32-gcc-posix >/dev/null && + compiler=x86_64-w64-mingw32-gcc-posix + +if [ -z "$compiler" ]; then + echo "Unable to determine which MinGW compiler to use" + exit 1 +fi +toolchain_file=$topdir/toolchain_${compiler/-gcc/}.cmake +echo "Using $toolchain_file" + +# Try to find runtime DLLs in various paths (varies by distribution, sigh) +tmp=$(dirname "$(command -v $compiler)")/.. +runtime_dlls= +for name in lib{gcc_,stdc++-,winpthread-}'*'.dll; do + for dir in $tmp/x86_64-w64-mingw32/{bin,lib} $tmp/lib/gcc/x86_64-w64-mingw32/*; do + [ -d "$dir" ] || continue + file=$(echo $dir/$name) + [ -f "$file" ] && { runtime_dlls+="$file;"; break; } + done +done +[ -z "$runtime_dlls" ] && + echo "The compiler runtime DLLs could not be found, they might be missing in the final package." + +# Get stuff +irrlicht_version=$(cat $topdir/../../misc/irrlichtmt_tag.txt) +ogg_version=1.3.5 +openal_version=1.21.1 +vorbis_version=1.3.7 +curl_version=7.81.0 +gettext_version=0.20.1 +freetype_version=2.11.1 +sqlite3_version=3.37.2 +luajit_version=2.1.0-beta3 +leveldb_version=1.23 +zlib_version=1.2.11 +zstd_version=1.5.2 + +mkdir -p $libdir + +download () { + local url=$1 + local filename=$2 + [ -z "$filename" ] && filename=${url##*/} + local foldername=${filename%%[.-]*} + local extract=$3 + [ -z "$extract" ] && extract=unzip + + [ -d "./$foldername" ] && return 0 + wget "$url" -c -O "./$filename" + if [ "$extract" = "unzip" ]; then + unzip -o "$filename" -d "$foldername" + elif [ "$extract" = "unzip_nofolder" ]; then + unzip -o "$filename" + else + return 1 + fi +} + +cd $libdir +download "https://github.com/minetest/irrlicht/releases/download/$irrlicht_version/win64.zip" irrlicht-$irrlicht_version.zip +download "http://minetest.kitsunemimi.pw/zlib-$zlib_version-win64.zip" +download "http://minetest.kitsunemimi.pw/zstd-$zstd_version-win64.zip" +download "http://minetest.kitsunemimi.pw/libogg-$ogg_version-win64.zip" +download "http://minetest.kitsunemimi.pw/libvorbis-$vorbis_version-win64.zip" +download "http://minetest.kitsunemimi.pw/curl-$curl_version-win64.zip" +download "http://minetest.kitsunemimi.pw/gettext-$gettext_version-win64.zip" +download "http://minetest.kitsunemimi.pw/freetype2-$freetype_version-win64.zip" freetype-$freetype_version.zip +download "http://minetest.kitsunemimi.pw/sqlite3-$sqlite3_version-win64.zip" +download "http://minetest.kitsunemimi.pw/luajit-$luajit_version-win64.zip" +download "http://minetest.kitsunemimi.pw/libleveldb-$leveldb_version-win64.zip" leveldb-$leveldb_version.zip +download "http://minetest.kitsunemimi.pw/openal-soft-$openal_version-win64.zip" + +# Set source dir, downloading Minetest as needed +if [ -n "$EXISTING_MINETEST_DIR" ]; then + sourcedir="$( cd "$EXISTING_MINETEST_DIR" && pwd )" +else + cd $builddir + sourcedir=$PWD/$CORE_NAME + [ -d $CORE_NAME ] && { pushd $CORE_NAME; git pull; popd; } || \ + git clone -b $CORE_BRANCH $CORE_GIT $CORE_NAME + if [ -z "$NO_MINETEST_GAME" ]; then + cd $sourcedir + [ -d games/$GAME_NAME ] && { pushd games/$GAME_NAME; git pull; popd; } || \ + git clone -b $GAME_BRANCH $GAME_GIT games/$GAME_NAME + fi +fi + +git_hash=$(cd $sourcedir && git rev-parse --short HEAD) + +# Build the thing +cd $builddir +[ -d build ] && rm -rf build + +irr_dlls=$(echo $libdir/irrlicht/lib/*.dll | tr ' ' ';') +vorbis_dlls=$(echo $libdir/libvorbis/bin/libvorbis{,file}-*.dll | tr ' ' ';') +gettext_dlls=$(echo $libdir/gettext/bin/lib{intl,iconv}-*.dll | tr ' ' ';') + +cmake -S $sourcedir -B build \ + -DCMAKE_TOOLCHAIN_FILE=$toolchain_file \ + -DCMAKE_INSTALL_PREFIX=/tmp \ + -DVERSION_EXTRA=$git_hash \ + -DBUILD_CLIENT=1 -DBUILD_SERVER=0 \ + -DEXTRA_DLL="$runtime_dlls" \ + \ + -DENABLE_SOUND=1 \ + -DENABLE_CURL=1 \ + -DENABLE_GETTEXT=1 \ + -DENABLE_LEVELDB=1 \ + \ + -DCMAKE_PREFIX_PATH=$libdir/irrlicht \ + -DIRRLICHT_DLL="$irr_dlls" \ + \ + -DZLIB_INCLUDE_DIR=$libdir/zlib/include \ + -DZLIB_LIBRARY=$libdir/zlib/lib/libz.dll.a \ + -DZLIB_DLL=$libdir/zlib/bin/zlib1.dll \ + \ + -DZSTD_INCLUDE_DIR=$libdir/zstd/include \ + -DZSTD_LIBRARY=$libdir/zstd/lib/libzstd.dll.a \ + -DZSTD_DLL=$libdir/zstd/bin/libzstd.dll \ + \ + -DLUA_INCLUDE_DIR=$libdir/luajit/include \ + -DLUA_LIBRARY=$libdir/luajit/libluajit.a \ + \ + -DOGG_INCLUDE_DIR=$libdir/libogg/include \ + -DOGG_LIBRARY=$libdir/libogg/lib/libogg.dll.a \ + -DOGG_DLL=$libdir/libogg/bin/libogg-0.dll \ + \ + -DVORBIS_INCLUDE_DIR=$libdir/libvorbis/include \ + -DVORBIS_LIBRARY=$libdir/libvorbis/lib/libvorbis.dll.a \ + -DVORBIS_DLL="$vorbis_dlls" \ + -DVORBISFILE_LIBRARY=$libdir/libvorbis/lib/libvorbisfile.dll.a \ + \ + -DOPENAL_INCLUDE_DIR=$libdir/openal/include/AL \ + -DOPENAL_LIBRARY=$libdir/openal/lib/libOpenAL32.dll.a \ + -DOPENAL_DLL=$libdir/openal/bin/OpenAL32.dll \ + \ + -DCURL_DLL=$libdir/curl/bin/libcurl-4.dll \ + -DCURL_INCLUDE_DIR=$libdir/curl/include \ + -DCURL_LIBRARY=$libdir/curl/lib/libcurl.dll.a \ + \ + -DGETTEXT_MSGFMT=`command -v msgfmt` \ + -DGETTEXT_DLL="$gettext_dlls" \ + -DGETTEXT_INCLUDE_DIR=$libdir/gettext/include \ + -DGETTEXT_LIBRARY=$libdir/gettext/lib/libintl.dll.a \ + \ + -DFREETYPE_INCLUDE_DIR_freetype2=$libdir/freetype/include/freetype2 \ + -DFREETYPE_INCLUDE_DIR_ft2build=$libdir/freetype/include/freetype2 \ + -DFREETYPE_LIBRARY=$libdir/freetype/lib/libfreetype.dll.a \ + -DFREETYPE_DLL=$libdir/freetype/bin/libfreetype-6.dll \ + \ + -DSQLITE3_INCLUDE_DIR=$libdir/sqlite3/include \ + -DSQLITE3_LIBRARY=$libdir/sqlite3/lib/libsqlite3.dll.a \ + -DSQLITE3_DLL=$libdir/sqlite3/bin/libsqlite3-0.dll \ + \ + -DLEVELDB_INCLUDE_DIR=$libdir/leveldb/include \ + -DLEVELDB_LIBRARY=$libdir/leveldb/lib/libleveldb.dll.a \ + -DLEVELDB_DLL=$libdir/leveldb/bin/libleveldb.dll + +cmake --build build -j$(nproc) + +[ -z "$NO_PACKAGE" ] && cmake --build build --target package + +exit 0 +# EOF diff --git a/util/buildbot/toolchain_i686-w64-mingw32-posix.cmake b/util/buildbot/toolchain_i686-w64-mingw32-posix.cmake new file mode 100644 index 0000000..b5d9ba5 --- /dev/null +++ b/util/buildbot/toolchain_i686-w64-mingw32-posix.cmake @@ -0,0 +1,19 @@ +# name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +# which compilers to use for C and C++ +# *-posix is Ubuntu's naming for the MinGW variant that comes with support +# for pthreads / std::thread (required by MT) +SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc-posix) +SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++-posix) +SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) + +# here is the target environment located +SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/util/buildbot/toolchain_i686-w64-mingw32.cmake b/util/buildbot/toolchain_i686-w64-mingw32.cmake new file mode 100644 index 0000000..015baa2 --- /dev/null +++ b/util/buildbot/toolchain_i686-w64-mingw32.cmake @@ -0,0 +1,17 @@ +# name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +# which compilers to use for C and C++ +SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc) +SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) +SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) + +# here is the target environment located +SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/util/buildbot/toolchain_x86_64-w64-mingw32-posix.cmake b/util/buildbot/toolchain_x86_64-w64-mingw32-posix.cmake new file mode 100644 index 0000000..b6b2376 --- /dev/null +++ b/util/buildbot/toolchain_x86_64-w64-mingw32-posix.cmake @@ -0,0 +1,19 @@ +# name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +# which compilers to use for C and C++ +# *-posix is Ubuntu's naming for the MinGW variant that comes with support +# for pthreads / std::thread (required by MT) +SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc-posix) +SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++-posix) +SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) + +# here is the target environment located +SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/util/buildbot/toolchain_x86_64-w64-mingw32.cmake b/util/buildbot/toolchain_x86_64-w64-mingw32.cmake new file mode 100644 index 0000000..9a7ed82 --- /dev/null +++ b/util/buildbot/toolchain_x86_64-w64-mingw32.cmake @@ -0,0 +1,17 @@ +# name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +# which compilers to use for C and C++ +SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) +SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) +SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) + +# here is the target environment located +SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/util/bump_version.sh b/util/bump_version.sh new file mode 100644 index 0000000..271886d --- /dev/null +++ b/util/bump_version.sh @@ -0,0 +1,144 @@ +#!/bin/bash -e + +prompt_for_number() { + local prompt_text=$1 + local default_value=$2 + local tmp="" + while true; do + read -p "$prompt_text [$default_value]: " tmp + if [ "$tmp" = "" ]; then + echo "$default_value"; return + elif echo "$tmp" | grep -q -E '^[0-9]+$'; then + echo "$tmp"; return + fi + done +} + +# On a release the following actions are performed +# * DEVELOPMENT_BUILD is set to false +# * android versionCode is bumped +# * appdata release version and date are updated +# * Commit the changes +# * Tag with current version +perform_release() { + RELEASE_DATE=$(date +%Y-%m-%d) + + sed -i -re "s/^set\(DEVELOPMENT_BUILD TRUE\)$/set(DEVELOPMENT_BUILD FALSE)/" CMakeLists.txt + + sed -i 's/project.ext.set("versionExtra", "-dev")/project.ext.set("versionExtra", "")/' android/build.gradle + sed -i 's/project.ext.set("developmentBuild", 1)/project.ext.set("developmentBuild", 0)/' android/build.gradle + sed -i -re "s/\"versionCode\", [0-9]+/\"versionCode\", $NEW_ANDROID_VERSION_CODE/" android/build.gradle + + sed -i '/\<release/s/\(version\)="[^"]*"/\1="'"$RELEASE_VERSION"'"/' misc/net.minetest.minetest.appdata.xml + sed -i 's/\(<release date\)="[^"]*"/\1="'"$RELEASE_DATE"'"/' misc/net.minetest.minetest.appdata.xml + + git add -f CMakeLists.txt android/build.gradle misc/net.minetest.minetest.appdata.xml + + git commit -m "Bump version to $RELEASE_VERSION" + + echo "Tagging $RELEASE_VERSION" + + git tag -a "$RELEASE_VERSION" -m "$RELEASE_VERSION" +} + +# After release +# * Set DEVELOPMENT_BUILD to true +# * Bump version in CMakeLists and docs +# * Commit the changes +back_to_devel() { + echo 'Creating "return back to development" commit' + + # Update CMakeList.txt versions + sed -i -re 's/^set\(DEVELOPMENT_BUILD FALSE\)$/set(DEVELOPMENT_BUILD TRUE)/' CMakeLists.txt + sed -i -re "s/^set\(VERSION_MAJOR [0-9]+\)$/set(VERSION_MAJOR $NEXT_VERSION_MAJOR)/" CMakeLists.txt + sed -i -re "s/^set\(VERSION_MINOR [0-9]+\)$/set(VERSION_MINOR $NEXT_VERSION_MINOR)/" CMakeLists.txt + sed -i -re "s/^set\(VERSION_PATCH [0-9]+\)$/set(VERSION_PATCH $NEXT_VERSION_PATCH)/" CMakeLists.txt + + # Update Android versions + sed -i 's/set("versionExtra", "")/set("versionExtra", "-dev")/' android/build.gradle + sed -i 's/project.ext.set("developmentBuild", 0)/project.ext.set("developmentBuild", 1)/' android/build.gradle + sed -i -re "s/set\(\"versionMajor\", [0-9]+\)/set(\"versionMajor\", $NEXT_VERSION_MAJOR)/" android/build.gradle + sed -i -re "s/set\(\"versionMinor\", [0-9]+\)/set(\"versionMinor\", $NEXT_VERSION_MINOR)/" android/build.gradle + sed -i -re "s/set\(\"versionPatch\", [0-9]+\)/set(\"versionPatch\", $NEXT_VERSION_PATCH)/" android/build.gradle + + # Update doc versions + sed -i -re "1s/[0-9]+\.[0-9]+\.[0-9]+/$NEXT_VERSION/g" doc/menu_lua_api.txt + sed -i -re "1s/[0-9]+\.[0-9]+\.[0-9]+/$NEXT_VERSION/g" doc/client_lua_api.txt + + # Commit + git add -f CMakeLists.txt android/build.gradle doc/menu_lua_api.txt doc/client_lua_api.txt + git commit -m "Continue with $NEXT_VERSION-dev" +} +################################## +# Switch to top minetest directory +################################## + +cd ${0%/*}/.. + + +####################### +# Determine old version +####################### + +# Make sure all the files we need exist +grep -q -E '^set\(VERSION_MAJOR [0-9]+\)$' CMakeLists.txt +grep -q -E '^set\(VERSION_MINOR [0-9]+\)$' CMakeLists.txt +grep -q -E '^set\(VERSION_PATCH [0-9]+\)$' CMakeLists.txt +grep -q -E '\("versionCode", [0-9]+\)' android/build.gradle + +VERSION_MAJOR=$(grep -E '^set\(VERSION_MAJOR [0-9]+\)$' CMakeLists.txt | tr -dC 0-9) +VERSION_MINOR=$(grep -E '^set\(VERSION_MINOR [0-9]+\)$' CMakeLists.txt | tr -dC 0-9) +VERSION_PATCH=$(grep -E '^set\(VERSION_PATCH [0-9]+\)$' CMakeLists.txt | tr -dC 0-9) +ANDROID_VERSION_CODE=$(grep -E '"versionCode", [0-9]+' android/build.gradle | tr -dC 0-9) + +RELEASE_VERSION="$VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH" + +echo "Current Minetest version: $RELEASE_VERSION" +echo "Current Android version code: $ANDROID_VERSION_CODE" + +# +1 for ARM and +1 for ARM64 APKs +NEW_ANDROID_VERSION_CODE=$(expr $ANDROID_VERSION_CODE + 2) +NEW_ANDROID_VERSION_CODE=$(prompt_for_number "Set android version code" $NEW_ANDROID_VERSION_CODE) + +echo +echo "New android version code: $NEW_ANDROID_VERSION_CODE" + +######################## +# Perform release +######################## + +perform_release + +######################## +# Prompt for next version +######################## + +NEXT_VERSION_MAJOR=$VERSION_MAJOR +NEXT_VERSION_MINOR=$VERSION_MINOR +NEXT_VERSION_PATCH=$(expr $VERSION_PATCH + 1) + +NEXT_VERSION_MAJOR=$(prompt_for_number "Set next major" $NEXT_VERSION_MAJOR) + +if [ "$NEXT_VERSION_MAJOR" != "$VERSION_MAJOR" ]; then + NEXT_VERSION_MINOR=0 + NEXT_VERSION_PATCH=0 +fi + +NEXT_VERSION_MINOR=$(prompt_for_number "Set next minor" $NEXT_VERSION_MINOR) + +if [ "$NEXT_VERSION_MINOR" != "$VERSION_MINOR" ]; then + NEXT_VERSION_PATCH=0 +fi + +NEXT_VERSION_PATCH=$(prompt_for_number "Set next patch" $NEXT_VERSION_PATCH) + +NEXT_VERSION="$NEXT_VERSION_MAJOR.$NEXT_VERSION_MINOR.$NEXT_VERSION_PATCH" + +echo +echo "New version: $NEXT_VERSION" + +######################## +# Return back to devel +######################## + +back_to_devel diff --git a/util/ci/build.sh b/util/ci/build.sh new file mode 100644 index 0000000..88349b8 --- /dev/null +++ b/util/ci/build.sh @@ -0,0 +1,10 @@ +#! /bin/bash -e + +cmake -B build \ + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-Debug} \ + -DRUN_IN_PLACE=TRUE \ + -DENABLE_GETTEXT=${CMAKE_ENABLE_GETTEXT:-TRUE} \ + -DBUILD_SERVER=${CMAKE_BUILD_SERVER:-TRUE} \ + ${CMAKE_FLAGS} + +cmake --build build --parallel $(($(nproc) + 1)) diff --git a/util/ci/build_prometheus_cpp.sh b/util/ci/build_prometheus_cpp.sh new file mode 100644 index 0000000..f3e4a55 --- /dev/null +++ b/util/ci/build_prometheus_cpp.sh @@ -0,0 +1,13 @@ +#! /bin/bash -eu + +cd /tmp +git clone --recursive https://github.com/jupp0r/prometheus-cpp +mkdir prometheus-cpp/build +cd prometheus-cpp/build +cmake .. \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_BUILD_TYPE=Release \ + -DENABLE_TESTING=0 +make -j$(nproc) +sudo make install + diff --git a/util/ci/clang-format-whitelist.txt b/util/ci/clang-format-whitelist.txt new file mode 100644 index 0000000..5cbc262 --- /dev/null +++ b/util/ci/clang-format-whitelist.txt @@ -0,0 +1,500 @@ +src/activeobject.h +src/ban.cpp +src/camera.cpp +src/camera.h +src/chat.cpp +src/chat.h +src/chat_interface.h +src/client/clientlauncher.cpp +src/client/clientlauncher.h +src/client/sound_openal.cpp +src/client.cpp +src/clientenvironment.cpp +src/clientenvironment.h +src/client/gameui.cpp +src/client.h +src/client/hud.cpp +src/client/hud.h +src/clientiface.cpp +src/clientiface.h +src/client/joystick_controller.cpp +src/client/joystick_controller.h +src/clientmap.cpp +src/clientmap.h +src/clientmedia.cpp +src/clientmedia.h +src/clientobject.cpp +src/clientobject.h +src/client/render/core.cpp +src/client/renderingengine.cpp +src/client/render/interlaced.cpp +src/client/render/plain.cpp +src/client/render/sidebyside.cpp +src/client/render/stereo.cpp +src/client/tile.cpp +src/client/tile.h +src/client/fontengine.h +src/client/clientenvironment.cpp +src/client/mapblock_mesh.cpp +src/client/sound_openal.h +src/client/clouds.cpp +src/client/fontengine.cpp +src/client/camera.h +src/client/hud.cpp +src/client/clientmap.cpp +src/client/sound_openal.cpp +src/client/minimap.h +src/client/content_cao.cpp +src/client/localplayer.h +src/client/mapblock_mesh.h +src/client/mesh.cpp +src/client/sound.cpp +src/client/guiscalingfilter.cpp +src/client/content_cso.cpp +src/client/gameui.cpp +src/client/wieldmesh.cpp +src/client/clientmedia.h +src/client/game.cpp +src/client/keys.h +src/client/client.h +src/client/shader.cpp +src/client/clientmap.h +src/client/inputhandler.h +src/client/content_mapblock.h +src/client/game.h +src/client/mesh.h +src/client/camera.cpp +src/client/sky.h +src/client/mesh_generator_thread.cpp +src/client/guiscalingfilter.h +src/client/clientobject.cpp +src/client/tile.cpp +src/client/hud.h +src/client/inputhandler.cpp +src/client/clientevent.h +src/client/gameui.h +src/client/content_cso.h +src/client/sky.cpp +src/client/localplayer.cpp +src/client/content_mapblock.cpp +src/client/clientobject.h +src/client/filecache.cpp +src/client/particles.h +src/client/clientenvironment.h +src/client/imagefilters.h +src/client/renderingengine.cpp +src/client/tile.h +src/client/clientmedia.cpp +src/client/event_manager.h +src/client/joystick_controller.h +src/client/clouds.h +src/client/clientlauncher.h +src/client/content_cao.h +src/client/minimap.cpp +src/client/sound.h +src/client/keycode.cpp +src/client/particles.cpp +src/client/joystick_controller.cpp +src/client/keycode.h +src/client/wieldmesh.h +src/client/filecache.h +src/client/shader.h +src/client/mesh_generator_thread.h +src/client/renderingengine.h +src/client/client.cpp +src/client/imagefilters.cpp +src/client/clientlauncher.cpp +src/clouds.cpp +src/clouds.h +src/collision.cpp +src/collision.h +src/config.h +src/content_cao.cpp +src/content_cao.h +src/content_cso.cpp +src/content_cso.h +src/content_mapblock.cpp +src/content_mapblock.h +src/content_mapnode.cpp +src/content_nodemeta.cpp +src/content_nodemeta.h +src/convert_json.cpp +src/convert_json.h +src/craftdef.cpp +src/craftdef.h +src/database/database.cpp +src/database/database-dummy.cpp +src/database/database-files.cpp +src/database/database-leveldb.cpp +src/database/database-postgresql.cpp +src/database/database-postgresql.h +src/database/database-redis.cpp +src/database/database-sqlite3.cpp +src/database/database-sqlite3.h +src/daynightratio.h +src/debug.cpp +src/debug.h +src/defaultsettings.cpp +src/emerge.cpp +src/emerge.h +src/environment.cpp +src/exceptions.h +src/face_position_cache.cpp +src/face_position_cache.h +src/filecache.cpp +src/filesys.cpp +src/filesys.h +src/fontengine.cpp +src/fontengine.h +src/game.cpp +src/gamedef.h +src/game.h +src/gettext.cpp +src/gettext.h +src/gui/guiAnimatedImage.cpp +src/gui/guiAnimatedImage.h +src/gui/guiBackgroundImage.cpp +src/gui/guiBackgroundImage.h +src/gui/guiBox.cpp +src/gui/guiBox.h +src/gui/guiButton.cpp +src/gui/guiButton.h +src/gui/guiButtonImage.cpp +src/gui/guiButtonImage.h +src/gui/guiButtonItemImage.cpp +src/gui/guiButtonItemImage.h +src/gui/guiChatConsole.cpp +src/gui/guiChatConsole.h +src/gui/guiConfirmRegistration.cpp +src/gui/guiEditBoxWithScrollbar.cpp +src/gui/guiEditBoxWithScrollbar.h +src/gui/guiEngine.cpp +src/gui/guiEngine.h +src/gui/guiFormSpecMenu.cpp +src/gui/guiFormSpecMenu.h +src/gui/guiKeyChangeMenu.cpp +src/gui/guiHyperText.cpp +src/gui/guiHyperText.h +src/gui/guiInventoryList.cpp +src/gui/guiInventoryList.h +src/gui/guiItemImage.cpp +src/gui/guiItemImage.h +src/gui/guiMainMenu.h +src/gui/guiPasswordChange.cpp +src/gui/guiPathSelectMenu.cpp +src/gui/guiPathSelectMenu.h +src/gui/guiScene.cpp +src/gui/guiScene.h +src/gui/guiScrollBar.cpp +src/gui/guiSkin.cpp +src/gui/guiSkin.h +src/gui/guiTable.cpp +src/gui/guiTable.h +src/gui/guiVolumeChange.cpp +src/gui/guiVolumeChange.h +src/gui/mainmenumanager.h +src/gui/modalMenu.h +src/guiscalingfilter.cpp +src/guiscalingfilter.h +src/gui/StyleSpec.h +src/gui/touchscreengui.cpp +src/httpfetch.cpp +src/hud.cpp +src/hud.h +src/imagefilters.cpp +src/imagefilters.h +src/inventory.cpp +src/inventory.h +src/inventorymanager.cpp +src/inventorymanager.h +src/irrlicht_changes/CGUITTFont.cpp +src/irrlicht_changes/CGUITTFont.h +src/irrlicht_changes/irrUString.h +src/irrlicht_changes/static_text.cpp +src/irrlicht_changes/static_text.h +src/irrlichttypes.h +src/itemdef.cpp +src/itemdef.h +src/itemstackmetadata.cpp +src/keycode.cpp +src/light.cpp +src/localplayer.cpp +src/log.cpp +src/log.h +src/main.cpp +src/mapblock.cpp +src/mapblock.h +src/mapblock_mesh.cpp +src/mapblock_mesh.h +src/map.cpp +src/mapgen/cavegen.cpp +src/mapgen/cavegen.h +src/mapgen/dungeongen.cpp +src/mapgen/dungeongen.h +src/mapgen/mapgen.cpp +src/mapgen/mapgen.h +src/mapgen/mapgen_carpathian.cpp +src/mapgen/mapgen_carpathian.h +src/mapgen/mapgen_flat.cpp +src/mapgen/mapgen_flat.h +src/mapgen/mapgen_fractal.cpp +src/mapgen/mapgen_fractal.h +src/mapgen/mapgen_singlenode.cpp +src/mapgen/mapgen_singlenode.h +src/mapgen/mapgen_v5.cpp +src/mapgen/mapgen_v5.h +src/mapgen/mapgen_v6.cpp +src/mapgen/mapgen_v6.h +src/mapgen/mapgen_v7.cpp +src/mapgen/mapgen_v7.h +src/mapgen/mapgen_valleys.cpp +src/mapgen/mapgen_valleys.h +src/mapgen/mg_biome.cpp +src/mapgen/mg_biome.h +src/mapgen/mg_decoration.cpp +src/mapgen/mg_decoration.h +src/mapgen/mg_ore.cpp +src/mapgen/mg_ore.h +src/mapgen/mg_schematic.cpp +src/mapgen/mg_schematic.h +src/mapgen/treegen.cpp +src/mapgen/treegen.h +src/map.h +src/mapnode.cpp +src/mapnode.h +src/mapsector.cpp +src/mapsector.h +src/map_settings_manager.cpp +src/map_settings_manager.h +src/mesh.cpp +src/mesh_generator_thread.cpp +src/mesh.h +src/metadata.h +src/minimap.cpp +src/minimap.h +src/mods.cpp +src/mods.h +src/network/address.cpp +src/network/clientopcodes.cpp +src/network/clientopcodes.h +src/network/clientpackethandler.cpp +src/network/connection.cpp +src/network/connection.h +src/network/connectionthreads.cpp +src/network/networkpacket.cpp +src/network/networkprotocol.h +src/network/serveropcodes.cpp +src/network/serveropcodes.h +src/network/serverpackethandler.cpp +src/nodedef.cpp +src/nodedef.h +src/nodemetadata.cpp +src/nodemetadata.h +src/nodetimer.cpp +src/nodetimer.h +src/noise.cpp +src/noise.h +src/objdef.cpp +src/objdef.h +src/object_properties.cpp +src/object_properties.h +src/particles.cpp +src/particles.h +src/pathfinder.cpp +src/pathfinder.h +src/player.cpp +src/player.h +src/porting_android.cpp +src/porting_android.h +src/porting.cpp +src/porting.h +src/profiler.h +src/raycast.cpp +src/raycast.h +src/reflowscan.cpp +src/reflowscan.h +src/remoteplayer.cpp +src/rollback.cpp +src/rollback.h +src/rollback_interface.cpp +src/rollback_interface.h +src/script/common/c_content.cpp +src/script/common/c_content.h +src/script/common/c_converter.cpp +src/script/common/c_converter.h +src/script/common/c_internal.cpp +src/script/common/c_internal.h +src/script/common/c_types.cpp +src/script/common/c_types.h +src/script/cpp_api/s_async.cpp +src/script/cpp_api/s_async.h +src/script/cpp_api/s_base.cpp +src/script/cpp_api/s_base.h +src/script/cpp_api/s_client.cpp +src/script/cpp_api/s_entity.cpp +src/script/cpp_api/s_entity.h +src/script/cpp_api/s_env.cpp +src/script/cpp_api/s_env.h +src/script/cpp_api/s_internal.h +src/script/cpp_api/s_inventory.cpp +src/script/cpp_api/s_inventory.h +src/script/cpp_api/s_item.cpp +src/script/cpp_api/s_item.h +src/script/cpp_api/s_mainmenu.h +src/script/cpp_api/s_node.cpp +src/script/cpp_api/s_node.h +src/script/cpp_api/s_nodemeta.cpp +src/script/cpp_api/s_nodemeta.h +src/script/cpp_api/s_player.cpp +src/script/cpp_api/s_player.h +src/script/cpp_api/s_security.cpp +src/script/cpp_api/s_security.h +src/script/cpp_api/s_server.cpp +src/script/cpp_api/s_server.h +src/script/lua_api/l_areastore.cpp +src/script/lua_api/l_base.cpp +src/script/lua_api/l_base.h +src/script/lua_api/l_client.cpp +src/script/lua_api/l_craft.cpp +src/script/lua_api/l_craft.h +src/script/lua_api/l_env.cpp +src/script/lua_api/l_env.h +src/script/lua_api/l_http.cpp +src/script/lua_api/l_http.h +src/script/lua_api/l_internal.h +src/script/lua_api/l_inventory.cpp +src/script/lua_api/l_inventory.h +src/script/lua_api/l_item.cpp +src/script/lua_api/l_item.h +src/script/lua_api/l_itemstackmeta.cpp +src/script/lua_api/l_itemstackmeta.h +src/script/lua_api/l_localplayer.cpp +src/script/lua_api/l_mainmenu.cpp +src/script/lua_api/l_mainmenu.h +src/script/lua_api/l_mapgen.cpp +src/script/lua_api/l_mapgen.h +src/script/lua_api/l_metadata.cpp +src/script/lua_api/l_minimap.cpp +src/script/lua_api/l_nodemeta.cpp +src/script/lua_api/l_nodemeta.h +src/script/lua_api/l_nodetimer.cpp +src/script/lua_api/l_noise.cpp +src/script/lua_api/l_object.cpp +src/script/lua_api/l_object.h +src/script/lua_api/l_particles.cpp +src/script/lua_api/l_particles.h +src/script/lua_api/l_particles_local.cpp +src/script/lua_api/l_rollback.cpp +src/script/lua_api/l_rollback.h +src/script/lua_api/l_server.cpp +src/script/lua_api/l_settings.cpp +src/script/lua_api/l_sound.cpp +src/script/lua_api/l_storage.cpp +src/script/lua_api/l_util.cpp +src/script/lua_api/l_vmanip.cpp +src/script/scripting_client.cpp +src/script/scripting_client.h +src/script/scripting_mainmenu.cpp +src/script/scripting_mainmenu.h +src/script/scripting_server.cpp +src/script/scripting_server.h +src/serialization.cpp +src/serialization.h +src/server.cpp +src/serverenvironment.cpp +src/serverenvironment.h +src/server.h +src/serverlist.cpp +src/serverlist.h +src/server/luaentity_sao.cpp +src/server/player_sao.cpp +src/server/serveractiveobject.cpp +src/server/serveractiveobject.h +src/settings.cpp +src/settings.h +src/settings_translation_file.cpp +src/shader.cpp +src/shader.h +src/sky.cpp +src/sound.cpp +src/staticobject.cpp +src/staticobject.h +src/subgame.cpp +src/subgame.h +src/terminal_chat_console.cpp +src/terminal_chat_console.h +src/texture_override.cpp +src/threading/atomic.h +src/threading/event.cpp +src/threading/mutex_auto_lock.h +src/threading/mutex.cpp +src/threading/mutex.h +src/threading/semaphore.cpp +src/threading/thread.cpp +src/threading/thread.h +src/threads.h +src/tileanimation.cpp +src/tileanimation.h +src/tool.cpp +src/tool.h +src/translation.cpp +src/unittest/test_areastore.cpp +src/unittest/test_collision.cpp +src/unittest/test_compression.cpp +src/unittest/test_connection.cpp +src/unittest/test.cpp +src/unittest/test_filepath.cpp +src/unittest/test.h +src/unittest/test_inventory.cpp +src/unittest/test_keycode.cpp +src/unittest/test_map_settings_manager.cpp +src/unittest/test_noderesolver.cpp +src/unittest/test_noise.cpp +src/unittest/test_random.cpp +src/unittest/test_schematic.cpp +src/unittest/test_serialization.cpp +src/unittest/test_settings.cpp +src/unittest/test_socket.cpp +src/unittest/test_threading.cpp +src/unittest/test_utilities.cpp +src/unittest/test_voxelalgorithms.cpp +src/unittest/test_voxelmanipulator.cpp +src/util/areastore.cpp +src/util/areastore.h +src/util/auth.cpp +src/util/auth.h +src/util/base64.cpp +src/util/base64.h +src/util/basic_macros.h +src/util/container.h +src/util/directiontables.cpp +src/util/directiontables.h +src/util/enriched_string.cpp +src/util/enriched_string.h +src/util/md32_common.h +src/util/numeric.cpp +src/util/numeric.h +src/util/pointedthing.cpp +src/util/pointedthing.h +src/util/pointer.h +src/util/quicktune.h +src/util/quicktune_shortcutter.h +src/util/quicktune.cpp +src/util/serialize.cpp +src/util/serialize.h +src/util/sha1.cpp +src/util/srp.cpp +src/util/srp.h +src/util/strfnd.h +src/util/string.cpp +src/util/string.h +src/util/thread.h +src/util/timetaker.cpp +src/util/timetaker.h +src/version.cpp +src/version.h +src/voxelalgorithms.cpp +src/voxelalgorithms.h +src/voxel.cpp +src/voxel.h +src/wieldmesh.cpp diff --git a/util/ci/clang-format.sh b/util/ci/clang-format.sh new file mode 100644 index 0000000..89576c6 --- /dev/null +++ b/util/ci/clang-format.sh @@ -0,0 +1,64 @@ +#! /bin/bash + +function setup_for_format() { + if [ -z "${CLANG_FORMAT}" ]; then + CLANG_FORMAT=clang-format + fi + echo "LINT: Using binary $CLANG_FORMAT" + CLANG_FORMAT_WHITELIST="util/ci/clang-format-whitelist.txt" + + files_to_lint="$(find src/ -name '*.cpp' -or -name '*.h')" +} + +function check_format() { + echo "Checking format..." + + setup_for_format + + local errorcount=0 + local fail=0 + for f in ${files_to_lint}; do + d=$(diff -u "$f" <(${CLANG_FORMAT} "$f") || true) + + if ! [ -z "$d" ]; then + whitelisted=$(awk '$1 == "'$f'" { print 1 }' "$CLANG_FORMAT_WHITELIST") + + # If file is not whitelisted, mark a failure + if [ -z "${whitelisted}" ]; then + errorcount=$((errorcount+1)) + + printf "The file %s is not compliant with the coding style" "$f" + if [ ${errorcount} -gt 50 ]; then + printf "\nToo many errors encountered previously, this diff is hidden.\n" + else + printf ":\n%s\n" "$d" + fi + + fail=1 + fi + fi + done + + if [ "$fail" = 1 ]; then + echo "LINT reports failure." + exit 1 + fi + + echo "LINT OK" +} + + + +function fix_format() { + echo "Fixing format..." + + setup_for_format + + for f in ${files_to_lint}; do + whitelisted=$(awk '$1 == "'$f'" { print 1 }' "$CLANG_FORMAT_WHITELIST") + if [ -z "${whitelisted}" ]; then + echo "$f" + $CLANG_FORMAT -i "$f" + fi + done +} diff --git a/util/ci/clang-tidy.sh b/util/ci/clang-tidy.sh new file mode 100644 index 0000000..e678cf3 --- /dev/null +++ b/util/ci/clang-tidy.sh @@ -0,0 +1,13 @@ +#! /bin/bash -eu + +cmake -B build -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ + -DRUN_IN_PLACE=TRUE \ + -DENABLE_{GETTEXT,SOUND}=FALSE \ + -DBUILD_SERVER=TRUE +cmake --build build --target GenerateVersion + +./util/ci/run-clang-tidy.py \ + -clang-tidy-binary=clang-tidy-9 -p build \ + -quiet -config="$(cat .clang-tidy)" \ + 'src/.*' diff --git a/util/ci/common.sh b/util/ci/common.sh new file mode 100644 index 0000000..c9271e8 --- /dev/null +++ b/util/ci/common.sh @@ -0,0 +1,34 @@ +#!/bin/bash -e + +# Linux build only +install_linux_deps() { + local pkgs=( + cmake gettext + libpng-dev libjpeg-dev libxi-dev libgl1-mesa-dev + libsqlite3-dev libhiredis-dev libogg-dev libgmp-dev libvorbis-dev + libopenal-dev libpq-dev libleveldb-dev libcurl4-openssl-dev libzstd-dev + ) + + if [[ "$1" == "--no-irr" ]]; then + shift + else + local ver=$(cat misc/irrlichtmt_tag.txt) + wget "https://github.com/minetest/irrlicht/releases/download/$ver/ubuntu-bionic.tar.gz" + sudo tar -xaf ubuntu-bionic.tar.gz -C /usr/local + fi + + sudo apt-get update + sudo apt-get install -y --no-install-recommends "${pkgs[@]}" "$@" +} + +# macOS build only +install_macos_deps() { + local pkgs=( + cmake gettext freetype gmp jpeg-turbo jsoncpp leveldb + libogg libpng libvorbis luajit zstd + ) + brew update + brew install "${pkgs[@]}" + brew unlink $(brew ls --formula) + brew link "${pkgs[@]}" +} diff --git a/util/ci/run-clang-tidy.py b/util/ci/run-clang-tidy.py new file mode 100644 index 0000000..6ad0ff2 --- /dev/null +++ b/util/ci/run-clang-tidy.py @@ -0,0 +1,321 @@ +#!/usr/bin/env python +# +#===- run-clang-tidy.py - Parallel clang-tidy runner ---------*- python -*--===# +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +#===------------------------------------------------------------------------===# +# FIXME: Integrate with clang-tidy-diff.py + +""" +Parallel clang-tidy runner +========================== + +Runs clang-tidy over all files in a compilation database. Requires clang-tidy +and clang-apply-replacements in $PATH. + +Example invocations. +- Run clang-tidy on all files in the current working directory with a default + set of checks and show warnings in the cpp files and all project headers. + run-clang-tidy.py $PWD + +- Fix all header guards. + run-clang-tidy.py -fix -checks=-*,llvm-header-guard + +- Fix all header guards included from clang-tidy and header guards + for clang-tidy headers. + run-clang-tidy.py -fix -checks=-*,llvm-header-guard extra/clang-tidy \ + -header-filter=extra/clang-tidy + +Compilation database setup: +http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html +""" + +from __future__ import print_function + +import argparse +import glob +import json +import multiprocessing +import os +import re +import shutil +import subprocess +import sys +import tempfile +import threading +import traceback + +try: + import yaml +except ImportError: + yaml = None + +is_py2 = sys.version[0] == '2' + +if is_py2: + import Queue as queue +else: + import queue as queue + +def find_compilation_database(path): + """Adjusts the directory until a compilation database is found.""" + result = './' + while not os.path.isfile(os.path.join(result, path)): + if os.path.realpath(result) == '/': + print('Error: could not find compilation database.') + sys.exit(1) + result += '../' + return os.path.realpath(result) + + +def make_absolute(f, directory): + if os.path.isabs(f): + return f + return os.path.normpath(os.path.join(directory, f)) + + +def get_tidy_invocation(f, clang_tidy_binary, checks, tmpdir, build_path, + header_filter, extra_arg, extra_arg_before, quiet, + config): + """Gets a command line for clang-tidy.""" + start = [clang_tidy_binary] + if header_filter is not None: + start.append('-header-filter=' + header_filter) + if checks: + start.append('-checks=' + checks) + if tmpdir is not None: + start.append('-export-fixes') + # Get a temporary file. We immediately close the handle so clang-tidy can + # overwrite it. + (handle, name) = tempfile.mkstemp(suffix='.yaml', dir=tmpdir) + os.close(handle) + start.append(name) + for arg in extra_arg: + start.append('-extra-arg=%s' % arg) + for arg in extra_arg_before: + start.append('-extra-arg-before=%s' % arg) + start.append('-p=' + build_path) + if quiet: + start.append('-quiet') + if config: + start.append('-config=' + config) + start.append(f) + return start + + +def merge_replacement_files(tmpdir, mergefile): + """Merge all replacement files in a directory into a single file""" + # The fixes suggested by clang-tidy >= 4.0.0 are given under + # the top level key 'Diagnostics' in the output yaml files + mergekey="Diagnostics" + merged=[] + for replacefile in glob.iglob(os.path.join(tmpdir, '*.yaml')): + content = yaml.safe_load(open(replacefile, 'r')) + if not content: + continue # Skip empty files. + merged.extend(content.get(mergekey, [])) + + if merged: + # MainSourceFile: The key is required by the definition inside + # include/clang/Tooling/ReplacementsYaml.h, but the value + # is actually never used inside clang-apply-replacements, + # so we set it to '' here. + output = { 'MainSourceFile': '', mergekey: merged } + with open(mergefile, 'w') as out: + yaml.safe_dump(output, out) + else: + # Empty the file: + open(mergefile, 'w').close() + + +def check_clang_apply_replacements_binary(args): + """Checks if invoking supplied clang-apply-replacements binary works.""" + try: + subprocess.check_call([args.clang_apply_replacements_binary, '--version']) + except: + print('Unable to run clang-apply-replacements. Is clang-apply-replacements ' + 'binary correctly specified?', file=sys.stderr) + traceback.print_exc() + sys.exit(1) + + +def apply_fixes(args, tmpdir): + """Calls clang-apply-fixes on a given directory.""" + invocation = [args.clang_apply_replacements_binary] + if args.format: + invocation.append('-format') + if args.style: + invocation.append('-style=' + args.style) + invocation.append(tmpdir) + subprocess.call(invocation) + + +def run_tidy(args, tmpdir, build_path, queue, lock, failed_files): + """Takes filenames out of queue and runs clang-tidy on them.""" + while True: + name = queue.get() + invocation = get_tidy_invocation(name, args.clang_tidy_binary, args.checks, + tmpdir, build_path, args.header_filter, + args.extra_arg, args.extra_arg_before, + args.quiet, args.config) + + proc = subprocess.Popen(invocation) + proc.wait() + if proc.returncode != 0: + failed_files.append(name) + queue.task_done() + + +def main(): + parser = argparse.ArgumentParser(description='Runs clang-tidy over all files ' + 'in a compilation database. Requires ' + 'clang-tidy and clang-apply-replacements in ' + '$PATH.') + parser.add_argument('-clang-tidy-binary', metavar='PATH', + default='clang-tidy', + help='path to clang-tidy binary') + parser.add_argument('-clang-apply-replacements-binary', metavar='PATH', + default='clang-apply-replacements', + help='path to clang-apply-replacements binary') + parser.add_argument('-checks', default=None, + help='checks filter, when not specified, use clang-tidy ' + 'default') + parser.add_argument('-config', default=None, + help='Specifies a configuration in YAML/JSON format: ' + ' -config="{Checks: \'*\', ' + ' CheckOptions: [{key: x, ' + ' value: y}]}" ' + 'When the value is empty, clang-tidy will ' + 'attempt to find a file named .clang-tidy for ' + 'each source file in its parent directories.') + parser.add_argument('-header-filter', default=None, + help='regular expression matching the names of the ' + 'headers to output diagnostics from. Diagnostics from ' + 'the main file of each translation unit are always ' + 'displayed.') + if yaml: + parser.add_argument('-export-fixes', metavar='filename', dest='export_fixes', + help='Create a yaml file to store suggested fixes in, ' + 'which can be applied with clang-apply-replacements.') + parser.add_argument('-j', type=int, default=0, + help='number of tidy instances to be run in parallel.') + parser.add_argument('files', nargs='*', default=['.*'], + help='files to be processed (regex on path)') + parser.add_argument('-fix', action='store_true', help='apply fix-its') + parser.add_argument('-format', action='store_true', help='Reformat code ' + 'after applying fixes') + parser.add_argument('-style', default='file', help='The style of reformat ' + 'code after applying fixes') + parser.add_argument('-p', dest='build_path', + help='Path used to read a compile command database.') + parser.add_argument('-extra-arg', dest='extra_arg', + action='append', default=[], + help='Additional argument to append to the compiler ' + 'command line.') + parser.add_argument('-extra-arg-before', dest='extra_arg_before', + action='append', default=[], + help='Additional argument to prepend to the compiler ' + 'command line.') + parser.add_argument('-quiet', action='store_true', + help='Run clang-tidy in quiet mode') + args = parser.parse_args() + + db_path = 'compile_commands.json' + + if args.build_path is not None: + build_path = args.build_path + else: + # Find our database + build_path = find_compilation_database(db_path) + + try: + invocation = [args.clang_tidy_binary, '-list-checks'] + invocation.append('-p=' + build_path) + if args.checks: + invocation.append('-checks=' + args.checks) + invocation.append('-') + if args.quiet: + # Even with -quiet we still want to check if we can call clang-tidy. + with open(os.devnull, 'w') as dev_null: + subprocess.check_call(invocation, stdout=dev_null) + else: + subprocess.check_call(invocation) + except: + print("Unable to run clang-tidy.", file=sys.stderr) + sys.exit(1) + + # Load the database and extract all files. + database = json.load(open(os.path.join(build_path, db_path))) + files = [make_absolute(entry['file'], entry['directory']) + for entry in database] + + max_task = args.j + if max_task == 0: + max_task = multiprocessing.cpu_count() + + tmpdir = None + if args.fix or (yaml and args.export_fixes): + check_clang_apply_replacements_binary(args) + tmpdir = tempfile.mkdtemp() + + # Build up a big regexy filter from all command line arguments. + file_name_re = re.compile('|'.join(args.files)) + + return_code = 0 + try: + # Spin up a bunch of tidy-launching threads. + task_queue = queue.Queue(max_task) + # List of files with a non-zero return code. + failed_files = [] + lock = threading.Lock() + for _ in range(max_task): + t = threading.Thread(target=run_tidy, + args=(args, tmpdir, build_path, task_queue, lock, failed_files)) + t.daemon = True + t.start() + + # Fill the queue with files. + for name in files: + if file_name_re.search(name): + task_queue.put(name) + + # Wait for all threads to be done. + task_queue.join() + if len(failed_files): + return_code = 1 + + except KeyboardInterrupt: + # This is a sad hack. Unfortunately subprocess goes + # bonkers with ctrl-c and we start forking merrily. + print('\nCtrl-C detected, goodbye.') + if tmpdir: + shutil.rmtree(tmpdir) + os.kill(0, 9) + + if yaml and args.export_fixes: + print('Writing fixes to ' + args.export_fixes + ' ...') + try: + merge_replacement_files(tmpdir, args.export_fixes) + except: + print('Error exporting fixes.\n', file=sys.stderr) + traceback.print_exc() + return_code=1 + + if args.fix: + print('Applying fixes ...') + try: + apply_fixes(args, tmpdir) + except: + print('Error applying fixes.\n', file=sys.stderr) + traceback.print_exc() + return_code=1 + + if tmpdir: + shutil.rmtree(tmpdir) + sys.exit(return_code) + +if __name__ == '__main__': + main() diff --git a/util/fix_format.sh b/util/fix_format.sh new file mode 100644 index 0000000..3cef6f5 --- /dev/null +++ b/util/fix_format.sh @@ -0,0 +1,5 @@ +#!/bin/bash -e + +. ./util/ci/clang-format.sh + +fix_format diff --git a/util/gather_git_credits.py b/util/gather_git_credits.py new file mode 100644 index 0000000..1b28651 --- /dev/null +++ b/util/gather_git_credits.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +import subprocess +import re +from collections import defaultdict + +codefiles = r"(\.[ch](pp)?|\.lua|\.md|\.cmake|\.java|\.gradle|Makefile|CMakeLists\.txt)$" + +# two minor versions back, for "Active Contributors" +REVS_ACTIVE = "5.2.0..HEAD" +# all time, for "Previous Contributors" +REVS_PREVIOUS = "HEAD" + +CUTOFF_ACTIVE = 3 +CUTOFF_PREVIOUS = 21 + +# For a description of the points system see: +# https://github.com/minetest/minetest/pull/9593#issue-398677198 + +def load(revs): + points = defaultdict(int) + p = subprocess.Popen(["git", "log", "--mailmap", "--pretty=format:%h %aN <%aE>", revs], + stdout=subprocess.PIPE, universal_newlines=True) + for line in p.stdout: + hash, author = line.strip().split(" ", 1) + n = 0 + + p2 = subprocess.Popen(["git", "show", "--numstat", "--pretty=format:", hash], + stdout=subprocess.PIPE, universal_newlines=True) + for line in p2.stdout: + added, deleted, filename = re.split(r"\s+", line.strip(), 2) + if re.search(codefiles, filename) and added != "-": + n += int(added) + p2.wait() + + if n == 0: + continue + if n > 1200: + n = 8 + elif n > 700: + n = 4 + elif n > 100: + n = 2 + else: + n = 1 + points[author] += n + p.wait() + + # Some authors duplicate? Don't add manual workarounds here, edit the .mailmap! + for author in ("updatepo.sh <script@mt>", "Weblate <42@minetest.ru>"): + points.pop(author, None) + return points + +points_active = load(REVS_ACTIVE) +points_prev = load(REVS_PREVIOUS) + +with open("results.txt", "w") as f: + for author, points in sorted(points_active.items(), key=(lambda e: e[1]), reverse=True): + if points < CUTOFF_ACTIVE: break + points_prev.pop(author, None) # active authors don't appear in previous + f.write("%d\t%s\n" % (points, author)) + f.write('\n---------\n\n') + once = True + for author, points in sorted(points_prev.items(), key=(lambda e: e[1]), reverse=True): + if points < CUTOFF_PREVIOUS and once: + f.write('\n---------\n\n') + once = False + f.write("%d\t%s\n" % (points, author)) diff --git a/util/helper_mod/init.lua b/util/helper_mod/init.lua new file mode 100644 index 0000000..4da832e --- /dev/null +++ b/util/helper_mod/init.lua @@ -0,0 +1,51 @@ +local mode = core.settings:get("helper_mode") + +if mode == "devtest" then + + -- Provide feedback to script by creating files in world path + core.after(0, function() + io.close(io.open(core.get_worldpath() .. "/startup", "w")) + end) + local function callback(test_ok) + if not test_ok then + io.close(io.open(core.get_worldpath() .. "/test_failure", "w")) + end + io.close(io.open(core.get_worldpath() .. "/done", "w")) + core.request_shutdown("", false, 2) + end + -- If tests are enabled exit when they're done, otherwise exit on player join + if core.settings:get_bool("devtest_unittests_autostart") and core.global_exists("unittests") then + unittests.on_finished = callback + else + core.register_on_joinplayer(function() callback(true) end) + end + +elseif mode == "mapgen" then + + -- Stress-test mapgen by constantly generating new area + local csize = tonumber(core.settings:get("chunksize")) * core.MAP_BLOCKSIZE + local MINP, MAXP = vector.new(0, -csize, 0), vector.new(csize*3, csize*2, csize) + local DIR = "x" + local pstart = vector.new(0, 0, 0) + local next_, callback + next_ = function(arg) + print("emerging " .. core.pos_to_string(pstart)) + core.emerge_area( + vector.add(pstart, MINP), vector.add(pstart, MAXP), + callback, arg + ) + end + local trig = {} + callback = function(blockpos, action, calls_rem, n) + if action == core.EMERGE_CANCELLED or action == core.EMERGE_ERRORED then + return + end + if calls_rem <= 20 and not trig[n] then + trig[n] = true + pstart[DIR] = pstart[DIR] + (MAXP[DIR] - MINP[DIR]) + next_(n + 1) + end + end + core.after(0, next_, 1) + +end diff --git a/util/helper_mod/mod.conf b/util/helper_mod/mod.conf new file mode 100644 index 0000000..efdd9ea --- /dev/null +++ b/util/helper_mod/mod.conf @@ -0,0 +1,3 @@ +name = helper_mod +description = Helper used by various test scripts +optional_depends = unittests diff --git a/util/reorder_translation_commits.py b/util/reorder_translation_commits.py new file mode 100644 index 0000000..465cf0b --- /dev/null +++ b/util/reorder_translation_commits.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +import sys +import subprocess + +ret = subprocess.run(["git", "config", "rebase.instructionFormat"], capture_output=True) +if ret.returncode != 0 or ret.stdout.decode('ascii').strip() != "(%an <%ae>) %s": + print("Git is using the wrong rebase instruction format, reconfigure it.") + exit(1) + +try: + f = open(".git/rebase-merge/git-rebase-todo", "r") +except: + print("Initiate the rebase first!") + exit(1) +lines = list(s.strip("\r\n") for s in f.readlines()) +f.close() + +for i in range(len(lines)): + line = lines[i] + if line.startswith("#") or " Translated using Weblate " not in line: continue + pos = line.rfind("(") + lang = line[pos:] + author = line[line.find("("):line.rfind(")", 0, pos)+1] + # try to grab the next commit by the same author for the same language + for j in range(i+1, len(lines)): + if lines[j].startswith("#") or not lines[j].endswith(lang): continue + if author in lines[j]: + lines.insert(i+1, "f " + lines.pop(j)[5:]) + break + +with open(".git/rebase-merge/git-rebase-todo", "w") as f: + f.write("\n".join(lines) + "\n") +print("You can now continue with the rebase.") diff --git a/util/stress_mapgen.sh b/util/stress_mapgen.sh new file mode 100644 index 0000000..6bbe574 --- /dev/null +++ b/util/stress_mapgen.sh @@ -0,0 +1,30 @@ +#!/bin/bash +dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +gameid=${gameid:-devtest} +minetest=$dir/../bin/minetest +testspath=$dir/../tests +conf_server=$testspath/server.conf +worldpath=$testspath/world + +run () { + if [ -n "$PERF" ]; then + perf record -z --call-graph dwarf -- "$@" + else + "$@" + fi +} + +[ -e "$minetest" ] || { echo "executable $minetest missing"; exit 1; } + +rm -rf "$worldpath" +mkdir -p "$worldpath/worldmods" + +settings=(sqlite_synchronous=0 helper_mode=mapgen) +[ -n "$PROFILER" ] && settings+=(profiler_print_interval=15) +printf '%s\n' "${settings[@]}" >"$testspath/server.conf" \ + +ln -s "$dir/helper_mod" "$worldpath/worldmods/" + +args=(--config "$conf_server" --world "$worldpath" --gameid $gameid) +[ -n "$PROFILER" ] && args+=(--verbose) +run "$minetest" --server "${args[@]}" diff --git a/util/test_multiplayer.sh b/util/test_multiplayer.sh new file mode 100644 index 0000000..1fcf298 --- /dev/null +++ b/util/test_multiplayer.sh @@ -0,0 +1,57 @@ +#!/bin/bash +dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +gameid=${gameid:-devtest} +minetest=$dir/../bin/minetest +testspath=$dir/../tests +conf_client1=$testspath/client1.conf +conf_server=$testspath/server.conf +worldpath=$testspath/world + +waitfor () { + n=30 + while [ $n -gt 0 ]; do + [ -f "$1" ] && return 0 + sleep 0.5 + ((n-=1)) + done + echo "Waiting for ${1##*/} timed out" + pkill -P $$ + exit 1 +} + +gdbrun () { + gdb -q -batch -ex 'set confirm off' -ex 'r' -ex 'bt' --args "$@" +} + +[ -e "$minetest" ] || { echo "executable $minetest missing"; exit 1; } + +rm -rf "$worldpath" +mkdir -p "$worldpath/worldmods" + +printf '%s\n' >"$testspath/client1.conf" \ + video_driver=null name=client1 viewing_range=10 \ + enable_{sound,minimap,shaders}=false + +printf '%s\n' >"$testspath/server.conf" \ + max_block_send_distance=1 devtest_unittests_autostart=true \ + helper_mode=devtest + +ln -s "$dir/helper_mod" "$worldpath/worldmods/" + +echo "Starting server" +gdbrun "$minetest" --server --config "$conf_server" --world "$worldpath" --gameid $gameid 2>&1 | sed -u 's/^/(server) /' & +waitfor "$worldpath/startup" + +echo "Starting client" +gdbrun "$minetest" --config "$conf_client1" --go --address 127.0.0.1 2>&1 | sed -u 's/^/(client) /' & +waitfor "$worldpath/done" + +echo "Waiting for client and server to exit" +wait + +if [ -f "$worldpath/test_failure" ]; then + echo "There were test failures." + exit 1 +fi +echo "Success" +exit 0 diff --git a/util/updatepo.sh b/util/updatepo.sh new file mode 100644 index 0000000..23e2c61 --- /dev/null +++ b/util/updatepo.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +# Update/create minetest po files + +# an auxiliary function to abort processing with an optional error +# message +abort() { + test -n "$1" && echo >&2 "$1" + exit 1 +} + +# The po/ directory is assumed to be parallel to the directory where +# this script is. Relative paths are fine for us so we can just +# use the following trick (works both for manual invocations and for +# script found from PATH) +scriptisin="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# The script is executed from the parent of po/, which is also the +# parent of the script directory and of the src/ directory. +# We go through $scriptisin so that it can be executed from whatever +# directory and still work correctly +cd "$scriptisin/.." + +test -e po || abort "po/ directory not found" +test -d po || abort "po/ is not a directory!" + +# Get a list of the languages we have to update/create + +cd po || abort "couldn't change directory to po!" + +# This assumes that we won't have dirnames with space, which is +# the case for language codes, which are the only subdirs we expect to +# find in po/ anyway. If you put anything else there, you need to suffer +# the consequences of your actions, so we don't do sanity checks +langs="" + +for lang in * ; do + if test ! -d $lang; then + continue + fi + langs="$langs $lang" +done + +# go back +cd .. + +# First thing first, update the .pot template. We place it in the po/ +# directory at the top level. You a recent enough xgettext that supports +# --package-name +potfile=po/minetest.pot +xgettext --package-name=minetest \ + --add-comments='~' \ + --sort-by-file \ + --add-location=file \ + --keyword=N_ \ + --keyword=wgettext \ + --keyword=fwgettext \ + --keyword=fgettext \ + --keyword=fgettext_ne \ + --keyword=strgettext \ + --keyword=wstrgettext \ + --keyword=core.gettext \ + --keyword=showTranslatedStatusText \ + --keyword=fmtgettext \ + --output $potfile \ + --from-code=utf-8 \ + `find src/ -name '*.cpp' -o -name '*.h'` \ + `find builtin/ -name '*.lua'` + +# Now iterate on all languages and create the po file if missing, or update it +# if it exists already +for lang in $langs ; do # note the missing quotes around $langs + pofile=po/$lang/minetest.po + if test -e $pofile; then + echo "[$lang]: updating strings" + msgmerge --update --sort-by-file $pofile $potfile + else + # This will ask for the translator identity + echo "[$lang]: NEW strings" + msginit --locale=$lang --output-file=$pofile --input=$potfile + fi +done diff --git a/util/wireshark/minetest.lua b/util/wireshark/minetest.lua new file mode 100644 index 0000000..40e1956 --- /dev/null +++ b/util/wireshark/minetest.lua @@ -0,0 +1,1415 @@ +-- minetest.lua +-- Packet dissector for the UDP-based Minetest protocol +-- Copy this to $HOME/.wireshark/plugins/ + + +-- +-- Minetest +-- Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com> +-- +-- This program is free software; 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. +-- + + +-- Wireshark documentation: +-- https://web.archive.org/web/20170711121726/https://www.wireshark.org/docs/wsdg_html_chunked/lua_module_Proto.html +-- https://web.archive.org/web/20170711121844/https://www.wireshark.org/docs/wsdg_html_chunked/lua_module_Tree.html +-- https://web.archive.org/web/20170711121917/https://www.wireshark.org/docs/wsdg_html_chunked/lua_module_Tvb.html + + +-- Table of Contents: +-- Part 1: Utility functions +-- Part 2: Client command dissectors (TOSERVER_*) +-- Part 3: Server command dissectors (TOCLIENT_*) +-- Part 4: Wrapper protocol subdissectors +-- Part 5: Wrapper protocol main dissector +-- Part 6: Utility functions part 2 + + +----------------------- +-- Part 1 -- +-- Utility functions -- +----------------------- + +-- Creates two ProtoFields to hold a length and variable-length text content +-- lentype must be either "uint16" or "uint32" +function minetest_field_helper(lentype, name, abbr) + local f_textlen = ProtoField[lentype](name .. "len", abbr .. " (length)", base.DEC) + local f_text = ProtoField.string(name, abbr) + return f_textlen, f_text +end + + + + +-------------------------------------------- +-- Part 2 -- +-- Client command dissectors (TOSERVER_*) -- +-------------------------------------------- + +minetest_client_commands = {} +minetest_client_obsolete = {} + +-- TOSERVER_INIT + +do + local abbr = "minetest.client.init_" + + local f_ser_fmt = ProtoField.uint8(abbr.."ser_version", + "Maximum serialization format version", base.DEC) + local f_comp_modes = ProtoField.uint16(abbr.."compression", + "Supported compression modes", base.DEC, { [0] = "No compression" }) + local f_proto_min = ProtoField.uint16(abbr.."proto_min", "Minimum protocol version", base.DEC) + local f_proto_max = ProtoField.uint16(abbr.."_proto_max", "Maximum protocol version", base.DEC) + local f_player_namelen, f_player_name = + minetest_field_helper("uint16", abbr.."player_name", "Player Name") + + minetest_client_commands[0x02] = { + "INIT", -- Command name + 11, -- Minimum message length including code + { f_ser_fmt, -- List of fields [optional] + f_comp_modes, + f_proto_min, + f_proto_max, + f_player_namelen, + f_player_name }, + function(buffer, pinfo, tree, t) -- Dissector function [optional] + t:add(f_ser_fmt, buffer(2,1)) + t:add(f_comp_modes, buffer(3,2)) + t:add(f_proto_min, buffer(5,2)) + t:add(f_proto_max, buffer(7,2)) + minetest_decode_helper_ascii(buffer, t, "uint16", 9, f_player_namelen, f_player_name) + end + } +end + +-- TOSERVER_INIT_LEGACY (obsolete) + +minetest_client_commands[0x10] = { "INIT_LEGACY", 53 } +minetest_client_obsolete[0x10] = true + +-- TOSERVER_INIT2 + +do + local f_langlen, f_lang = + minetest_field_helper("uint16", "minetest.client.init2_language", "Language Code") + + minetest_client_commands[0x11] = { + "INIT2", + 2, + { f_langlen, + f_lang }, + function(buffer, pinfo, tree, t) + minetest_decode_helper_ascii(buffer, t, "uint16", 2, f_langlen, f_lang) + end + } +end + +-- TOSERVER_MODCHANNEL_JOIN + +minetest_client_commands[0x17] = { "MODCHANNEL_JOIN", 2 } + +-- TOSERVER_MODCHANNEL_LEAVE + +minetest_client_commands[0x18] = { "MODCHANNEL_LEAVE", 2 } + +-- TOSERVER_MODCHANNEL_MSG + +minetest_client_commands[0x19] = { "MODCHANNEL_MSG", 2 } + +-- TOSERVER_GETBLOCK (obsolete) + +minetest_client_commands[0x20] = { "GETBLOCK", 2 } +minetest_client_obsolete[0x20] = true + +-- TOSERVER_ADDNODE (obsolete) + +minetest_client_commands[0x21] = { "ADDNODE", 2 } +minetest_client_obsolete[0x21] = true + +-- TOSERVER_REMOVENODE (obsolete) + +minetest_client_commands[0x22] = { "REMOVENODE", 2 } +minetest_client_obsolete[0x22] = true + +-- TOSERVER_PLAYERPOS + +do + local abbr = "minetest.client.playerpos_" + + local f_x = ProtoField.int32(abbr.."x", "Position X", base.DEC) + local f_y = ProtoField.int32(abbr.."y", "Position Y", base.DEC) + local f_z = ProtoField.int32(abbr.."z", "Position Z", base.DEC) + local f_speed_x = ProtoField.int32(abbr.."speed_x", "Speed X", base.DEC) + local f_speed_y = ProtoField.int32(abbr.."speed_y", "Speed Y", base.DEC) + local f_speed_z = ProtoField.int32(abbr.."speed_z", "Speed Z", base.DEC) + local f_pitch = ProtoField.int32(abbr.."pitch", "Pitch", base.DEC) + local f_yaw = ProtoField.int32(abbr.."yaw", "Yaw", base.DEC) + local f_key_pressed = ProtoField.bytes(abbr.."key_pressed", "Pressed keys") + local f_fov = ProtoField.uint8(abbr.."fov", "FOV", base.DEC) + local f_wanted_range = ProtoField.uint8(abbr.."wanted_range", "Requested view range", base.DEC) + + minetest_client_commands[0x23] = { + "PLAYERPOS", 34, + { f_x, f_y, f_z, f_speed_x, f_speed_y, f_speed_z, f_pitch, f_yaw, + f_key_pressed, f_fov, f_wanted_range }, + function(buffer, pinfo, tree, t) + t:add(f_x, buffer(2,4)) + t:add(f_y, buffer(6,4)) + t:add(f_z, buffer(10,4)) + t:add(f_speed_x, buffer(14,4)) + t:add(f_speed_y, buffer(18,4)) + t:add(f_speed_z, buffer(22,4)) + t:add(f_pitch, buffer(26,4)) + t:add(f_yaw, buffer(30,4)) + t:add(f_key_pressed, buffer(34,4)) + t:add(f_fov, buffer(38,1)) + t:add(f_wanted_range, buffer(39,1)) + end + } +end + +-- TOSERVER_GOTBLOCKS + +do + local f_count = ProtoField.uint8("minetest.client.gotblocks_count", "Count", base.DEC) + local f_block = ProtoField.bytes("minetest.client.gotblocks_block", "Block", base.NONE) + local f_x = ProtoField.int16("minetest.client.gotblocks_x", "Block position X", base.DEC) + local f_y = ProtoField.int16("minetest.client.gotblocks_y", "Block position Y", base.DEC) + local f_z = ProtoField.int16("minetest.client.gotblocks_z", "Block position Z", base.DEC) + + minetest_client_commands[0x24] = { + "GOTBLOCKS", 3, + { f_count, f_block, f_x, f_y, f_z }, + function(buffer, pinfo, tree, t) + t:add(f_count, buffer(2,1)) + local count = buffer(2,1):uint() + if minetest_check_length(buffer, 3 + 6*count, t) then + pinfo.cols.info:append(" * " .. count) + local index + for index = 0, count - 1 do + local pos = 3 + 6*index + local t2 = t:add(f_block, buffer(pos, 6)) + t2:set_text("Block, X: " .. buffer(pos, 2):int() + .. ", Y: " .. buffer(pos + 2, 2):int() + .. ", Z: " .. buffer(pos + 4, 2):int()) + t2:add(f_x, buffer(pos, 2)) + t2:add(f_y, buffer(pos + 2, 2)) + t2:add(f_z, buffer(pos + 4, 2)) + end + end + end + } +end + +-- TOSERVER_DELETEDBLOCKS + +do + local f_count = ProtoField.uint8("minetest.client.deletedblocks_count", "Count", base.DEC) + local f_block = ProtoField.bytes("minetest.client.deletedblocks_block", "Block", base.NONE) + local f_x = ProtoField.int16("minetest.client.deletedblocks_x", "Block position X", base.DEC) + local f_y = ProtoField.int16("minetest.client.deletedblocks_y", "Block position Y", base.DEC) + local f_z = ProtoField.int16("minetest.client.deletedblocks_z", "Block position Z", base.DEC) + + minetest_client_commands[0x25] = { + "DELETEDBLOCKS", 3, + { f_count, f_block, f_x, f_y, f_z }, + function(buffer, pinfo, tree, t) + t:add(f_count, buffer(2,1)) + local count = buffer(2,1):uint() + if minetest_check_length(buffer, 3 + 6*count, t) then + pinfo.cols.info:append(" * " .. count) + local index + for index = 0, count - 1 do + local pos = 3 + 6*index + local t2 = t:add(f_block, buffer(pos, 6)) + t2:set_text("Block, X: " .. buffer(pos, 2):int() + .. ", Y: " .. buffer(pos + 2, 2):int() + .. ", Z: " .. buffer(pos + 4, 2):int()) + t2:add(f_x, buffer(pos, 2)) + t2:add(f_y, buffer(pos + 2, 2)) + t2:add(f_z, buffer(pos + 4, 2)) + end + end + end + } +end + +-- TOSERVER_ADDNODE_FROM_INVENTORY (obsolete) + +minetest_client_commands[0x26] = { "ADDNODE_FROM_INVENTORY", 2 } +minetest_client_obsolete[0x26] = true + +-- TOSERVER_CLICK_OBJECT (obsolete) + +minetest_client_commands[0x27] = { "CLICK_OBJECT", 2 } +minetest_client_obsolete[0x27] = true + +-- TOSERVER_GROUND_ACTION (obsolete) + +minetest_client_commands[0x28] = { "GROUND_ACTION", 2 } +minetest_client_obsolete[0x28] = true + +-- TOSERVER_RELEASE (obsolete) + +minetest_client_commands[0x29] = { "RELEASE", 2 } +minetest_client_obsolete[0x29] = true + +-- TOSERVER_SIGNTEXT (obsolete) + +minetest_client_commands[0x30] = { "SIGNTEXT", 2 } +minetest_client_obsolete[0x30] = true + +-- TOSERVER_INVENTORY_ACTION + +do + local f_action = ProtoField.string("minetest.client.inventory_action", "Action") + + minetest_client_commands[0x31] = { + "INVENTORY_ACTION", 2, + { f_action }, + function(buffer, pinfo, tree, t) + t:add(f_action, buffer(2, buffer:len() - 2)) + end + } +end + +-- TOSERVER_CHAT_MESSAGE + +do + local f_length = ProtoField.uint16("minetest.client.chat_message_length", "Length", base.DEC) + local f_message = ProtoField.string("minetest.client.chat_message", "Message") + + minetest_client_commands[0x32] = { + "CHAT_MESSAGE", 4, + { f_length, f_message }, + function(buffer, pinfo, tree, t) + t:add(f_length, buffer(2,2)) + local textlen = buffer(2,2):uint() + if minetest_check_length(buffer, 4 + textlen*2, t) then + t:add(f_message, buffer(4, textlen*2), buffer(4, textlen*2):ustring()) + end + end + } +end + +-- TOSERVER_SIGNNODETEXT (obsolete) + +minetest_client_commands[0x33] = { "SIGNNODETEXT", 2 } +minetest_client_obsolete[0x33] = true + + +-- TOSERVER_CLICK_ACTIVEOBJECT (obsolete) + +minetest_client_commands[0x34] = { "CLICK_ACTIVEOBJECT", 2 } +minetest_client_obsolete[0x34] = true + +-- TOSERVER_DAMAGE + +do + local f_amount = ProtoField.uint8("minetest.client.damage_amount", "Amount", base.DEC) + + minetest_client_commands[0x35] = { + "DAMAGE", 3, + { f_amount }, + function(buffer, pinfo, tree, t) + t:add(f_amount, buffer(2,1)) + end + } +end + +-- TOSERVER_PASSWORD (obsolete) + +minetest_client_commands[0x36] = { "CLICK_ACTIVEOBJECT", 2 } +minetest_client_obsolete[0x36] = true + +-- TOSERVER_PLAYERITEM + +do + local f_item = ProtoField.uint16("minetest.client.playeritem_item", "Wielded item") + + minetest_client_commands[0x37] = { + "PLAYERITEM", 4, + { f_item }, + function(buffer, pinfo, tree, t) + t:add(f_item, buffer(2,2)) + end + } +end + +-- TOSERVER_RESPAWN + +minetest_client_commands[0x38] = { "RESPAWN", 2 } + +-- TOSERVER_INTERACT + +do + local abbr = "minetest.client.interact_" + local vs_action = { + [0] = "Start digging", + [1] = "Stop digging", + [2] = "Digging completed", + [3] = "Place block or item", + [4] = "Use item", + [5] = "Activate held item", + } + local vs_pointed_type = { + [0] = "Nothing", + [1] = "Node", + [2] = "Object", + } + + local f_action = ProtoField.uint8(abbr.."action", "Action", base.DEC, vs_action) + local f_item = ProtoField.uint16(abbr.."item", "Item Index", base.DEC) + local f_plen = ProtoField.uint32(abbr.."plen", "Length of pointed thing", base.DEC) + local f_pointed_version = ProtoField.uint8(abbr.."pointed_version", + "Pointed Thing Version", base.DEC) + local f_pointed_type = ProtoField.uint8(abbr.."pointed_version", + "Pointed Thing Type", base.DEC, vs_pointed_type) + local f_pointed_under_x = ProtoField.int16(abbr.."pointed_under_x", + "Node position (under surface) X") + local f_pointed_under_y = ProtoField.int16(abbr.."pointed_under_y", + "Node position (under surface) Y") + local f_pointed_under_z = ProtoField.int16(abbr.."pointed_under_z", + "Node position (under surface) Z") + local f_pointed_above_x = ProtoField.int16(abbr.."pointed_above_x", + "Node position (above surface) X") + local f_pointed_above_y = ProtoField.int16(abbr.."pointed_above_y", + "Node position (above surface) Y") + local f_pointed_above_z = ProtoField.int16(abbr.."pointed_above_z", + "Node position (above surface) Z") + local f_pointed_object_id = ProtoField.int16(abbr.."pointed_object_id", + "Object ID") + -- mising: additional playerpos data just like in TOSERVER_PLAYERPOS + + minetest_client_commands[0x39] = { + "INTERACT", 11, + { f_action, + f_item, + f_plen, + f_pointed_version, + f_pointed_type, + f_pointed_under_x, + f_pointed_under_y, + f_pointed_under_z, + f_pointed_above_x, + f_pointed_above_y, + f_pointed_above_z, + f_pointed_object_id }, + function(buffer, pinfo, tree, t) + t:add(f_action, buffer(2,1)) + t:add(f_item, buffer(3,2)) + t:add(f_plen, buffer(5,4)) + local plen = buffer(5,4):uint() + if minetest_check_length(buffer, 9 + plen, t) then + t:add(f_pointed_version, buffer(9,1)) + t:add(f_pointed_type, buffer(10,1)) + local ptype = buffer(10,1):uint() + if ptype == 1 then -- Node + t:add(f_pointed_under_x, buffer(11,2)) + t:add(f_pointed_under_y, buffer(13,2)) + t:add(f_pointed_under_z, buffer(15,2)) + t:add(f_pointed_above_x, buffer(17,2)) + t:add(f_pointed_above_y, buffer(19,2)) + t:add(f_pointed_above_z, buffer(21,2)) + elseif ptype == 2 then -- Object + t:add(f_pointed_object_id, buffer(11,2)) + end + end + end + } +end + +-- ... + +minetest_client_commands[0x3a] = { "REMOVED_SOUNDS", 2 } +minetest_client_commands[0x3b] = { "NODEMETA_FIELDS", 2 } +minetest_client_commands[0x3c] = { "INVENTORY_FIELDS", 2 } +minetest_client_commands[0x40] = { "REQUEST_MEDIA", 2 } +minetest_client_commands[0x41] = { "RECEIVED_MEDIA", 2 } + +-- TOSERVER_BREATH (obsolete) + +minetest_client_commands[0x42] = { "BREATH", 2 } +minetest_client_obsolete[0x42] = true + +-- TOSERVER_CLIENT_READY + +do + local abbr = "minetest.client.client_ready_" + local f_major = ProtoField.uint8(abbr.."major","Version Major") + local f_minor = ProtoField.uint8(abbr.."minor","Version Minor") + local f_patch = ProtoField.uint8(abbr.."patch","Version Patch") + local f_reserved = ProtoField.uint8(abbr.."reserved","Reserved") + local f_versionlen, f_version = + minetest_field_helper("uint16", abbr.."version", "Full Version String") + local f_formspec_ver = ProtoField.uint16(abbr.."formspec_version", + "Formspec API version") + + minetest_client_commands[0x43] = { + "CLIENT_READY", + 8, + { f_major, f_minor, f_patch, f_reserved, f_versionlen, + f_version, f_formspec_ver }, + function(buffer, pinfo, tree, t) + t:add(f_major, buffer(2,1)) + t:add(f_minor, buffer(3,1)) + t:add(f_patch, buffer(4,1)) + t:add(f_reserved, buffer(5,1)) + local off = minetest_decode_helper_ascii(buffer, t, "uint16", 6, + f_versionlen, f_version) + if off and minetest_check_length(buffer, off + 2, t) then + t:add(f_formspec_ver, buffer(off,2)) + end + end + } +end + +-- ... + +minetest_client_commands[0x50] = { "FIRST_SRP", 2 } +minetest_client_commands[0x51] = { "SRP_BYTES_A", 2 } +minetest_client_commands[0x52] = { "SRP_BYTES_M", 2 } + + + +-------------------------------------------- +-- Part 3 -- +-- Server command dissectors (TOCLIENT_*) -- +-------------------------------------------- + +minetest_server_commands = {} +minetest_server_obsolete = {} + +-- TOCLIENT_HELLO + +do + local abbr = "minetest.server.hello_" + + local f_ser_fmt = ProtoField.uint8(abbr.."ser_version", + "Deployed serialization format version", base.DEC) + local f_comp_mode = ProtoField.uint16(abbr.."compression", + "Deployed compression mode", base.DEC, { [0] = "No compression" }) + local f_proto = ProtoField.uint16(abbr.."proto", + "Deployed protocol version", base.DEC) + local f_auth_methods = ProtoField.bytes(abbr.."auth_modes", + "Supported authentication modes") + local f_legacy_namelen, f_legacy_name = minetest_field_helper("uint16", + abbr.."legacy_name", "Legacy player name for hashing") + + minetest_server_commands[0x02] = { + "HELLO", + 13, + { f_ser_fmt, f_comp_mode, f_proto, f_auth_methods, + f_legacy_namelen, f_legacy_name }, + function(buffer, pinfo, tree, t) + t:add(f_ser_fmt, buffer(2,1)) + t:add(f_comp_mode, buffer(3,2)) + t:add(f_proto, buffer(5,2)) + t:add(f_auth_methods, buffer(7,4)) + minetest_decode_helper_ascii(buffer, t, "uint16", 11, f_legacy_namelen, f_legacy_name) + end + } +end + +-- TOCLIENT_AUTH_ACCEPT + +do + local abbr = "minetest.server.auth_accept_" + + local f_player_x = ProtoField.float(abbr.."player_x", "Player position X") + local f_player_y = ProtoField.float(abbr.."player_y", "Player position Y") + local f_player_z = ProtoField.float(abbr.."player_z", "Player position Z") + local f_map_seed = ProtoField.uint64(abbr.."map_seed", "Map seed") + local f_send_interval = ProtoField.float(abbr.."send_interval", + "Recommended send interval") + local f_sudo_auth_methods = ProtoField.bytes(abbr.."sudo_auth_methods", + "Supported auth methods for sudo mode") + + minetest_server_commands[0x03] = { + "AUTH_ACCEPT", + 30, + { f_player_x, f_player_y, f_player_z, f_map_seed, + f_send_interval, f_sudo_auth_methods }, + function(buffer, pinfo, tree, t) + t:add(f_player_x, buffer(2,4)) + t:add(f_player_y, buffer(6,4)) + t:add(f_player_z, buffer(10,4)) + t:add(f_map_seed, buffer(14,8)) + t:add(f_send_interval, buffer(22,4)) + t:add(f_sudo_auth_methods, buffer(26,4)) + end + } +end + +-- ... + +minetest_server_commands[0x04] = {"ACCEPT_SUDO_MODE", 2} +minetest_server_commands[0x05] = {"DENY_SUDO_MODE", 2} +minetest_server_commands[0x0A] = {"ACCESS_DENIED", 2} + +-- TOCLIENT_INIT (obsolete) + +minetest_server_commands[0x10] = { "INIT", 2 } +minetest_server_obsolete[0x10] = true + +-- TOCLIENT_BLOCKDATA + +do + local f_x = ProtoField.int16("minetest.server.blockdata_x", "Block position X", base.DEC) + local f_y = ProtoField.int16("minetest.server.blockdata_y", "Block position Y", base.DEC) + local f_z = ProtoField.int16("minetest.server.blockdata_z", "Block position Z", base.DEC) + local f_data = ProtoField.bytes("minetest.server.blockdata_block", "Serialized MapBlock") + + minetest_server_commands[0x20] = { + "BLOCKDATA", 8, + { f_x, f_y, f_z, f_data }, + function(buffer, pinfo, tree, t) + t:add(f_x, buffer(2,2)) + t:add(f_y, buffer(4,2)) + t:add(f_z, buffer(6,2)) + t:add(f_data, buffer(8, buffer:len() - 8)) + end + } +end + +-- TOCLIENT_ADDNODE + +do + local f_x = ProtoField.int16("minetest.server.addnode_x", "Position X", base.DEC) + local f_y = ProtoField.int16("minetest.server.addnode_y", "Position Y", base.DEC) + local f_z = ProtoField.int16("minetest.server.addnode_z", "Position Z", base.DEC) + local f_data = ProtoField.bytes("minetest.server.addnode_node", "Serialized MapNode") + + minetest_server_commands[0x21] = { + "ADDNODE", 8, + { f_x, f_y, f_z, f_data }, + function(buffer, pinfo, tree, t) + t:add(f_x, buffer(2,2)) + t:add(f_y, buffer(4,2)) + t:add(f_z, buffer(6,2)) + t:add(f_data, buffer(8, buffer:len() - 8)) + end + } +end + +-- TOCLIENT_REMOVENODE + +do + local f_x = ProtoField.int16("minetest.server.removenode_x", "Position X", base.DEC) + local f_y = ProtoField.int16("minetest.server.removenode_y", "Position Y", base.DEC) + local f_z = ProtoField.int16("minetest.server.removenode_z", "Position Z", base.DEC) + + minetest_server_commands[0x22] = { + "REMOVENODE", 8, + { f_x, f_y, f_z }, + function(buffer, pinfo, tree, t) + t:add(f_x, buffer(2,2)) + t:add(f_y, buffer(4,2)) + t:add(f_z, buffer(6,2)) + end + } +end + +-- TOCLIENT_PLAYERPOS (obsolete) + +minetest_server_commands[0x23] = { "PLAYERPOS", 2 } +minetest_server_obsolete[0x23] = true + +-- TOCLIENT_PLAYERINFO (obsolete) + +minetest_server_commands[0x24] = { "PLAYERINFO", 2 } +minetest_server_obsolete[0x24] = true + +-- TOCLIENT_OPT_BLOCK_NOT_FOUND (obsolete) + +minetest_server_commands[0x25] = { "OPT_BLOCK_NOT_FOUND", 2 } +minetest_server_obsolete[0x25] = true + +-- TOCLIENT_SECTORMETA (obsolete) + +minetest_server_commands[0x26] = { "SECTORMETA", 2 } +minetest_server_obsolete[0x26] = true + +-- TOCLIENT_INVENTORY + +do + local f_inventory = ProtoField.string("minetest.server.inventory", "Inventory") + + minetest_server_commands[0x27] = { + "INVENTORY", 2, + { f_inventory }, + function(buffer, pinfo, tree, t) + t:add(f_inventory, buffer(2, buffer:len() - 2)) + end + } +end + +-- TOCLIENT_OBJECTDATA (obsolete) + +minetest_server_commands[0x28] = { "OBJECTDATA", 2 } +minetest_server_obsolete[0x28] = true + +-- TOCLIENT_TIME_OF_DAY + +do + local f_time = ProtoField.uint16("minetest.server.time_of_day", "Time", base.DEC) + local f_time_speed = ProtoField.float("minetest.server.time_speed", "Time Speed", base.DEC) + + minetest_server_commands[0x29] = { + "TIME_OF_DAY", 4, + { f_time, f_time_speed }, + function(buffer, pinfo, tree, t) + t:add(f_time, buffer(2,2)) + t:add(f_time_speed, buffer(4,4)) + end + } +end + +-- TOCLIENT_CSM_RESTRICTION_FLAGS + +minetest_server_commands[0x2a] = { "CSM_RESTRICTION_FLAGS", 2 } + +-- TOCLIENT_PLAYER_SPEED + +minetest_server_commands[0x2b] = { "PLAYER_SPEED", 2 } + +-- TOCLIENT_CHAT_MESSAGE + +do + local abbr = "minetest.server.chat_message_" + local vs_type = { + [0] = "Raw", + [1] = "Normal", + [2] = "Announce", + [3] = "System", + } + + local f_version = ProtoField.uint8(abbr.."version", "Version") + local f_type = ProtoField.uint8(abbr.."type", "Message Type", base.DEC, vs_type) + local f_senderlen, f_sender = minetest_field_helper("uint16", abbr.."sender", + "Message sender") + local f_messagelen, f_message = minetest_field_helper("uint16", abbr:sub(1,-2), + "Message") + + minetest_server_commands[0x2f] = { + "CHAT_MESSAGE", 8, + { f_version, f_type, f_senderlen, f_sender, + f_messagelen, f_message }, + function(buffer, pinfo, tree, t) + t:add(f_version, buffer(2,1)) + t:add(f_type, buffer(3,1)) + local off = 4 + off = minetest_decode_helper_utf16(buffer, t, "uint16", off, f_senderlen, f_sender) + if off then + off = minetest_decode_helper_utf16(buffer, t, "uint16", off, f_messagelen, f_message) + end + end + } +end + +-- TOCLIENT_CHAT_MESSAGE_OLD (obsolete) + +minetest_server_commands[0x30] = { "CHAT_MESSAGE_OLD", 2 } +minetest_server_obsolete[0x30] = true + +-- TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD + +do + local f_removed_count = ProtoField.uint16( + "minetest.server.active_object_remove_add_removed_count", + "Count of removed objects", base.DEC) + local f_removed = ProtoField.bytes( + "minetest.server.active_object_remove_add_removed", + "Removed object") + local f_removed_id = ProtoField.uint16( + "minetest.server.active_object_remove_add_removed_id", + "ID", base.DEC) + + local f_added_count = ProtoField.uint16( + "minetest.server.active_object_remove_add_added_count", + "Count of added objects", base.DEC) + local f_added = ProtoField.bytes( + "minetest.server.active_object_remove_add_added", + "Added object") + local f_added_id = ProtoField.uint16( + "minetest.server.active_object_remove_add_added_id", + "ID", base.DEC) + local f_added_type = ProtoField.uint8( + "minetest.server.active_object_remove_add_added_type", + "Type", base.DEC) + local f_added_init_length = ProtoField.uint32( + "minetest.server.active_object_remove_add_added_init_length", + "Initialization data length", base.DEC) + local f_added_init_data = ProtoField.bytes( + "minetest.server.active_object_remove_add_added_init_data", + "Initialization data") + + minetest_server_commands[0x31] = { + "ACTIVE_OBJECT_REMOVE_ADD", 6, + { f_removed_count, f_removed, f_removed_id, + f_added_count, f_added, f_added_id, + f_added_type, f_added_init_length, f_added_init_data }, + function(buffer, pinfo, tree, t) + local t2, index, pos + + local removed_count_pos = 2 + local removed_count = buffer(removed_count_pos, 2):uint() + t:add(f_removed_count, buffer(removed_count_pos, 2)) + + local added_count_pos = removed_count_pos + 2 + 2 * removed_count + if not minetest_check_length(buffer, added_count_pos + 2, t) then + return + end + + -- Loop through removed active objects + for index = 0, removed_count - 1 do + pos = removed_count_pos + 2 + 2 * index + t2 = t:add(f_removed, buffer(pos, 2)) + t2:set_text("Removed object, ID = " .. buffer(pos, 2):uint()) + t2:add(f_removed_id, buffer(pos, 2)) + end + + local added_count = buffer(added_count_pos, 2):uint() + t:add(f_added_count, buffer(added_count_pos, 2)) + + -- Loop through added active objects + pos = added_count_pos + 2 + for index = 0, added_count - 1 do + if not minetest_check_length(buffer, pos + 7, t) then + return + end + + local init_length = buffer(pos + 3, 4):uint() + if not minetest_check_length(buffer, pos + 7 + init_length, t) then + return + end + + t2 = t:add(f_added, buffer(pos, 7 + init_length)) + t2:set_text("Added object, ID = " .. buffer(pos, 2):uint()) + t2:add(f_added_id, buffer(pos, 2)) + t2:add(f_added_type, buffer(pos + 2, 1)) + t2:add(f_added_init_length, buffer(pos + 3, 4)) + t2:add(f_added_init_data, buffer(pos + 7, init_length)) + + pos = pos + 7 + init_length + end + + pinfo.cols.info:append(" * " .. (removed_count + added_count)) + end + } +end + +-- TOCLIENT_ACTIVE_OBJECT_MESSAGES + +do + local f_object_count = ProtoField.uint16( + "minetest.server.active_object_messages_object_count", + "Count of objects", base.DEC) + local f_object = ProtoField.bytes( + "minetest.server.active_object_messages_object", + "Object") + local f_object_id = ProtoField.uint16( + "minetest.server.active_object_messages_id", + "ID", base.DEC) + local f_message_length = ProtoField.uint16( + "minetest.server.active_object_messages_message_length", + "Message length", base.DEC) + local f_message = ProtoField.bytes( + "minetest.server.active_object_messages_message", + "Message") + + minetest_server_commands[0x32] = { + "ACTIVE_OBJECT_MESSAGES", 2, + { f_object_count, f_object, f_object_id, f_message_length, f_message }, + function(buffer, pinfo, tree, t) + local t2, count, pos, message_length + + count = 0 + pos = 2 + while pos < buffer:len() do + if not minetest_check_length(buffer, pos + 4, t) then + return + end + message_length = buffer(pos + 2, 2):uint() + if not minetest_check_length(buffer, pos + 4 + message_length, t) then + return + end + count = count + 1 + pos = pos + 4 + message_length + end + + pinfo.cols.info:append(" * " .. count) + t:add(f_object_count, count):set_generated() + + pos = 2 + while pos < buffer:len() do + message_length = buffer(pos + 2, 2):uint() + + t2 = t:add(f_object, buffer(pos, 4 + message_length)) + t2:set_text("Object, ID = " .. buffer(pos, 2):uint()) + t2:add(f_object_id, buffer(pos, 2)) + t2:add(f_message_length, buffer(pos + 2, 2)) + t2:add(f_message, buffer(pos + 4, message_length)) + + pos = pos + 4 + message_length + end + end + } +end + +-- TOCLIENT_HP + +do + local f_hp = ProtoField.uint16("minetest.server.hp", "Health points", base.DEC) + + minetest_server_commands[0x33] = { + "HP", 4, + { f_hp }, + function(buffer, pinfo, tree, t) + t:add(f_hp, buffer(2,2)) + end + } +end + +-- TOCLIENT_MOVE_PLAYER + +do + local abbr = "minetest.server.move_player_" + + local f_x = ProtoField.float(abbr.."x", "Position X") + local f_y = ProtoField.float(abbr.."y", "Position Y") + local f_z = ProtoField.float(abbr.."z", "Position Z") + local f_pitch = ProtoField.float(abbr.."_pitch", "Pitch") + local f_yaw = ProtoField.float(abbr.."yaw", "Yaw") + + minetest_server_commands[0x34] = { + "MOVE_PLAYER", 22, + { f_x, f_y, f_z, f_pitch, f_yaw, f_garbage }, + function(buffer, pinfo, tree, t) + t:add(f_x, buffer(2, 4)) + t:add(f_y, buffer(6, 4)) + t:add(f_z, buffer(10, 4)) + t:add(f_pitch, buffer(14, 4)) + t:add(f_yaw, buffer(18, 4)) + end + } +end + +-- TOCLIENT_ACCESS_DENIED_LEGACY + +do + local f_reason_length = ProtoField.uint16("minetest.server.access_denied_reason_length", "Reason length", base.DEC) + local f_reason = ProtoField.string("minetest.server.access_denied_reason", "Reason") + + minetest_server_commands[0x35] = { + "ACCESS_DENIED_LEGACY", 4, + { f_reason_length, f_reason }, + function(buffer, pinfo, tree, t) + t:add(f_reason_length, buffer(2,2)) + local reason_length = buffer(2,2):uint() + if minetest_check_length(buffer, 4 + reason_length * 2, t) then + t:add(f_reason, minetest_convert_utf16(buffer(4, reason_length * 2), "Converted reason message")) + end + end + } +end + +-- TOCLIENT_FOV + +minetest_server_commands[0x36] = { "FOV", 2 } + +-- TOCLIENT_DEATHSCREEN + +do + local f_set_camera_point_target = ProtoField.bool( + "minetest.server.deathscreen_set_camera_point_target", + "Set camera point target") + local f_camera_point_target_x = ProtoField.int32( + "minetest.server.deathscreen_camera_point_target_x", + "Camera point target X", base.DEC) + local f_camera_point_target_y = ProtoField.int32( + "minetest.server.deathscreen_camera_point_target_y", + "Camera point target Y", base.DEC) + local f_camera_point_target_z = ProtoField.int32( + "minetest.server.deathscreen_camera_point_target_z", + "Camera point target Z", base.DEC) + + minetest_server_commands[0x37] = { + "DEATHSCREEN", 15, + { f_set_camera_point_target, f_camera_point_target_x, + f_camera_point_target_y, f_camera_point_target_z}, + function(buffer, pinfo, tree, t) + t:add(f_set_camera_point_target, buffer(2,1)) + t:add(f_camera_point_target_x, buffer(3,4)) + t:add(f_camera_point_target_y, buffer(7,4)) + t:add(f_camera_point_target_z, buffer(11,4)) + end + } +end + +-- TOCLIENT_MEDIA + +minetest_server_commands[0x38] = {"MEDIA", 2} + +-- TOCLIENT_TOOLDEF (obsolete) + +minetest_server_commands[0x39] = {"TOOLDEF", 2} +minetest_server_obsolete[0x39] = true + +-- TOCLIENT_NODEDEF + +minetest_server_commands[0x3a] = {"NODEDEF", 2} + +-- TOCLIENT_CRAFTITEMDEF (obsolete) + +minetest_server_commands[0x3b] = {"CRAFTITEMDEF", 2} +minetest_server_obsolete[0x3b] = true + +-- ... + +minetest_server_commands[0x3c] = {"ANNOUNCE_MEDIA", 2} +minetest_server_commands[0x3d] = {"ITEMDEF", 2} +minetest_server_commands[0x3f] = {"PLAY_SOUND", 2} +minetest_server_commands[0x40] = {"STOP_SOUND", 2} +minetest_server_commands[0x41] = {"PRIVILEGES", 2} +minetest_server_commands[0x42] = {"INVENTORY_FORMSPEC", 2} +minetest_server_commands[0x43] = {"DETACHED_INVENTORY", 2} +minetest_server_commands[0x44] = {"SHOW_FORMSPEC", 2} +minetest_server_commands[0x45] = {"MOVEMENT", 2} +minetest_server_commands[0x46] = {"SPAWN_PARTICLE", 2} +minetest_server_commands[0x47] = {"ADD_PARTICLE_SPAWNER", 2} + +-- TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY (obsolete) + +minetest_server_commands[0x48] = {"DELETE_PARTICLESPAWNER_LEGACY", 2} +minetest_server_obsolete[0x48] = true + +-- ... + +minetest_server_commands[0x49] = {"HUDADD", 2} +minetest_server_commands[0x4a] = {"HUDRM", 2} +minetest_server_commands[0x4b] = {"HUDCHANGE", 2} +minetest_server_commands[0x4c] = {"HUD_SET_FLAGS", 2} +minetest_server_commands[0x4d] = {"HUD_SET_PARAM", 2} +minetest_server_commands[0x4e] = {"BREATH", 2} +minetest_server_commands[0x4f] = {"SET_SKY", 2} +minetest_server_commands[0x50] = {"OVERRIDE_DAY_NIGHT_RATIO", 2} +minetest_server_commands[0x51] = {"LOCAL_PLAYER_ANIMATIONS", 2} +minetest_server_commands[0x52] = {"EYE_OFFSET", 2} +minetest_server_commands[0x53] = {"DELETE_PARTICLESPAWNER", 2} +minetest_server_commands[0x54] = {"CLOUD_PARAMS", 2} +minetest_server_commands[0x55] = {"FADE_SOUND", 2} + +-- TOCLIENT_UPDATE_PLAYER_LIST + +do + local abbr = "minetest.server.update_player_list_" + local vs_type = { + [0] = "Init", + [1] = "Add", + [2] = "Remove", + } + + local f_type = ProtoField.uint8(abbr.."type", "Type", base.DEC, vs_type) + local f_count = ProtoField.uint16(abbr.."count", "Number of players", base.DEC) + local f_name = ProtoField.string(abbr.."name", "Name") + + minetest_server_commands[0x56] = { + "UPDATE_PLAYER_LIST", + 5, + { f_type, f_count, f_name }, + function(buffer, pinfo, tree, t) + t:add(f_type, buffer(2,1)) + t:add(f_count, buffer(3,2)) + local count = buffer(3,2):uint() + local off = 5 + for i = 1, count do + if not minetest_check_length(buffer, off + 2, t) then + return + end + off = minetest_decode_helper_ascii(buffer, t, "uint16", off, nil, f_name) + if not off then + return + end + end + end + } +end + +-- ... + +minetest_server_commands[0x57] = {"MODCHANNEL_MSG", 2} +minetest_server_commands[0x58] = {"MODCHANNEL_SIGNAL", 2} +minetest_server_commands[0x59] = {"NODEMETA_CHANGED", 2} +minetest_server_commands[0x5a] = {"SET_SUN", 2} +minetest_server_commands[0x5b] = {"SET_MOON", 2} +minetest_server_commands[0x5c] = {"SET_STARS", 2} +minetest_server_commands[0x60] = {"SRP_BYTES_S_B", 2} +minetest_server_commands[0x61] = {"FORMSPEC_PREPEND", 2} + + +------------------------------------ +-- Part 4 -- +-- Wrapper protocol subdissectors -- +------------------------------------ + +-- minetest.control dissector + +do + local p_control = Proto("minetest.control", "Minetest Control") + + local vs_control_type = { + [0] = "Ack", + [1] = "Set Peer ID", + [2] = "Ping", + [3] = "Disco" + } + + local f_control_type = ProtoField.uint8("minetest.control.type", "Control Type", base.DEC, vs_control_type) + local f_control_ack = ProtoField.uint16("minetest.control.ack", "ACK sequence number", base.DEC) + local f_control_peerid = ProtoField.uint8("minetest.control.peerid", "New peer ID", base.DEC) + p_control.fields = { f_control_type, f_control_ack, f_control_peerid } + + local data_dissector = Dissector.get("data") + + function p_control.dissector(buffer, pinfo, tree) + local t = tree:add(p_control, buffer(0,1)) + t:add(f_control_type, buffer(0,1)) + + pinfo.cols.info = "Control message" + + local pos = 1 + if buffer(0,1):uint() == 0 then + pos = 3 + t:set_len(3) + t:add(f_control_ack, buffer(1,2)) + pinfo.cols.info = "Ack " .. buffer(1,2):uint() + elseif buffer(0,1):uint() == 1 then + pos = 3 + t:set_len(3) + t:add(f_control_peerid, buffer(1,2)) + pinfo.cols.info = "Set peer ID " .. buffer(1,2):uint() + elseif buffer(0,1):uint() == 2 then + pinfo.cols.info = "Ping" + elseif buffer(0,1):uint() == 3 then + pinfo.cols.info = "Disco" + end + + data_dissector:call(buffer(pos):tvb(), pinfo, tree) + end +end + +-- minetest.client dissector +-- minetest.server dissector + +-- Defines the minetest.client or minetest.server Proto. These two protocols +-- are created by the same function because they are so similar. +-- Parameter: proto: the Proto object +-- Parameter: this_peer: "Client" or "Server" +-- Parameter: other_peer: "Server" or "Client" +-- Parameter: commands: table of command information, built above +-- Parameter: obsolete: table of obsolete commands, built above +function minetest_define_client_or_server_proto(is_client) + -- Differences between minetest.client and minetest.server + local proto_name, this_peer, other_peer, empty_message_info + local commands, obsolete + if is_client then + proto_name = "minetest.client" + this_peer = "Client" + other_peer = "Server" + empty_message_info = "Empty message / Connect" + commands = minetest_client_commands -- defined in Part 2 + obsolete = minetest_client_obsolete -- defined in Part 2 + else + proto_name = "minetest.server" + this_peer = "Server" + other_peer = "Client" + empty_message_info = "Empty message" + commands = minetest_server_commands -- defined in Part 3 + obsolete = minetest_server_obsolete -- defined in Part 3 + end + + -- Create the protocol object. + local proto = Proto(proto_name, "Minetest " .. this_peer .. " to " .. other_peer) + + -- Create a table vs_command that maps command codes to command names. + local vs_command = {} + local code, command_info + for code, command_info in pairs(commands) do + local command_name = command_info[1] + vs_command[code] = "TO" .. other_peer:upper() .. "_" .. command_name + end + + -- Field definitions + local f_command = ProtoField.uint16(proto_name .. ".command", "Command", base.HEX, vs_command) + local f_empty = ProtoField.bool(proto_name .. ".empty", "Is empty", BASE_NONE) + proto.fields = { f_command, f_empty } + + -- Add command-specific fields to the protocol + for code, command_info in pairs(commands) do + local command_fields = command_info[3] + if command_fields ~= nil then + for index, field in ipairs(command_fields) do + assert(field ~= nil) + table.insert(proto.fields, field) + end + end + end + + -- minetest.client or minetest.server dissector function + function proto.dissector(buffer, pinfo, tree) + local t = tree:add(proto, buffer) + + pinfo.cols.info = this_peer + + if buffer:len() == 0 then + -- Empty message. + t:add(f_empty, 1):set_generated() + pinfo.cols.info:append(": " .. empty_message_info) + + elseif minetest_check_length(buffer, 2, t) then + -- Get the command code. + t:add(f_command, buffer(0,2)) + local code = buffer(0,2):uint() + local command_info = commands[code] + if command_info == nil then + -- Error: Unknown command. + pinfo.cols.info:append(": Unknown command") + t:add_expert_info(PI_UNDECODED, PI_WARN, "Unknown " .. this_peer .. " to " .. other_peer .. " command") + else + -- Process a known command + local command_name = command_info[1] + local command_min_length = command_info[2] + local command_fields = command_info[3] + local command_dissector = command_info[4] + if minetest_check_length(buffer, command_min_length, t) then + pinfo.cols.info:append(": " .. command_name) + if command_dissector ~= nil then + command_dissector(buffer, pinfo, tree, t) + end + end + if obsolete[code] then + t:add_expert_info(PI_REQUEST_CODE, PI_WARN, "Obsolete command.") + end + end + end + end +end + +minetest_define_client_or_server_proto(true) -- minetest.client +minetest_define_client_or_server_proto(false) -- minetest.server + +-- minetest.split dissector + +do + local p_split = Proto("minetest.split", "Minetest Split Message") + + local f_split_seq = ProtoField.uint16("minetest.split.seq", "Sequence number", base.DEC) + local f_split_chunkcount = ProtoField.uint16("minetest.split.chunkcount", "Chunk count", base.DEC) + local f_split_chunknum = ProtoField.uint16("minetest.split.chunknum", "Chunk number", base.DEC) + local f_split_data = ProtoField.bytes("minetest.split.data", "Split message data") + p_split.fields = { f_split_seq, f_split_chunkcount, f_split_chunknum, f_split_data } + + function p_split.dissector(buffer, pinfo, tree) + local t = tree:add(p_split, buffer(0,6)) + t:add(f_split_seq, buffer(0,2)) + t:add(f_split_chunkcount, buffer(2,2)) + t:add(f_split_chunknum, buffer(4,2)) + t:add(f_split_data, buffer(6)) + pinfo.cols.info:append(" " .. buffer(0,2):uint() .. " chunk " .. buffer(4,2):uint() .. "/" .. buffer(2,2):uint()) + end +end + + + + +------------------------------------- +-- Part 5 -- +-- Wrapper protocol main dissector -- +------------------------------------- + +-- minetest dissector + +do + local p_minetest = Proto("minetest", "Minetest") + + local minetest_id = 0x4f457403 + local vs_id = { + [minetest_id] = "Valid" + } + + local vs_peer = { + [0] = "Inexistent", + [1] = "Server" + } + + local vs_type = { + [0] = "Control", + [1] = "Original", + [2] = "Split", + [3] = "Reliable" + } + + local f_id = ProtoField.uint32("minetest.id", "ID", base.HEX, vs_id) + local f_peer = ProtoField.uint16("minetest.peer", "Peer", base.DEC, vs_peer) + local f_channel = ProtoField.uint8("minetest.channel", "Channel", base.DEC) + local f_type = ProtoField.uint8("minetest.type", "Type", base.DEC, vs_type) + local f_seq = ProtoField.uint16("minetest.seq", "Sequence number", base.DEC) + local f_subtype = ProtoField.uint8("minetest.subtype", "Subtype", base.DEC, vs_type) + + p_minetest.fields = { f_id, f_peer, f_channel, f_type, f_seq, f_subtype } + + local data_dissector = Dissector.get("data") + local control_dissector = Dissector.get("minetest.control") + local client_dissector = Dissector.get("minetest.client") + local server_dissector = Dissector.get("minetest.server") + local split_dissector = Dissector.get("minetest.split") + + function p_minetest.dissector(buffer, pinfo, tree) + + -- Add Minetest tree item and verify the ID + local t = tree:add(p_minetest, buffer(0,8)) + t:add(f_id, buffer(0,4)) + if buffer(0,4):uint() ~= minetest_id then + t:add_expert_info(PI_UNDECODED, PI_WARN, "Invalid ID, this is not a Minetest packet") + return + end + + -- ID is valid, so replace packet's shown protocol + pinfo.cols.protocol = "Minetest" + pinfo.cols.info = "Minetest" + + -- Set the other header fields + t:add(f_peer, buffer(4,2)) + t:add(f_channel, buffer(6,1)) + t:add(f_type, buffer(7,1)) + t:set_text("Minetest, Peer: " .. buffer(4,2):uint() .. ", Channel: " .. buffer(6,1):uint()) + + local reliability_info + if buffer(7,1):uint() == 3 then + -- Reliable message + reliability_info = "Seq=" .. buffer(8,2):uint() + t:set_len(11) + t:add(f_seq, buffer(8,2)) + t:add(f_subtype, buffer(10,1)) + pos = 10 + else + -- Unreliable message + reliability_info = "Unrel" + pos = 7 + end + + if buffer(pos,1):uint() == 0 then + -- Control message, possibly reliable + control_dissector:call(buffer(pos+1):tvb(), pinfo, tree) + elseif buffer(pos,1):uint() == 1 then + -- Original message, possibly reliable + if buffer(4,2):uint() == 1 then + server_dissector:call(buffer(pos+1):tvb(), pinfo, tree) + else + client_dissector:call(buffer(pos+1):tvb(), pinfo, tree) + end + elseif buffer(pos,1):uint() == 2 then + -- Split message, possibly reliable + if buffer(4,2):uint() == 1 then + pinfo.cols.info = "Server: Split message" + else + pinfo.cols.info = "Client: Split message" + end + split_dissector:call(buffer(pos+1):tvb(), pinfo, tree) + elseif buffer(pos,1):uint() == 3 then + -- Doubly reliable message?? + t:add_expert_info(PI_MALFORMED, PI_ERROR, "Reliable message wrapped in reliable message") + else + data_dissector:call(buffer(pos+1):tvb(), pinfo, tree) + end + + pinfo.cols.info:append(" (" .. reliability_info .. ")") + + end + + -- FIXME Is there a way to let the dissector table check if the first payload bytes are 0x4f457403? + DissectorTable.get("udp.port"):add(30000, p_minetest) + DissectorTable.get("udp.port"):add(30001, p_minetest) +end + + + + +------------------------------ +-- Part 6 -- +-- Utility functions part 2 -- +------------------------------ + +-- Checks if a (sub-)Tvb is long enough to be further dissected. +-- If it is long enough, sets the dissector tree item length to min_len +-- and returns true. If it is not long enough, adds expert info to the +-- dissector tree and returns false. +-- Parameter: tvb: the Tvb +-- Parameter: min_len: required minimum length +-- Parameter: t: dissector tree item +-- Returns: true if tvb:len() >= min_len, false otherwise +function minetest_check_length(tvb, min_len, t) + if tvb:len() >= min_len then + t:set_len(min_len) + return true + + -- TODO: check if other parts of + -- the dissector could benefit from reported_length_remaining + elseif tvb:reported_length_remaining() >= min_len then + t:add_expert_info(PI_UNDECODED, PI_INFO, "Only part of this packet was captured, unable to decode.") + return false + + else + t:add_expert_info(PI_MALFORMED, PI_ERROR, "Message is too short") + return false + end +end + +-- Decodes a variable-length string as ASCII text +-- t_textlen, t_text should be the ProtoFields created by minetest_field_helper +-- alternatively t_text can be a ProtoField.string and t_textlen can be nil +-- lentype must be the type of the length field (as passed to minetest_field_helper) +-- returns nil if length check failed +function minetest_decode_helper_ascii(tvb, t, lentype, offset, f_textlen, f_text) + local n = ({uint16 = 2, uint32 = 4})[lentype] + assert(n) + + if f_textlen then + t:add(f_textlen, tvb(offset, n)) + end + local textlen = tvb(offset, n):uint() + if minetest_check_length(tvb, offset + n + textlen, t) then + t:add(f_text, tvb(offset + n, textlen)) + return offset + n + textlen + end +end + +-- Decodes a variable-length string as UTF-16 text +-- (see minetest_decode_helper_ascii) +function minetest_decode_helper_utf16(tvb, t, lentype, offset, f_textlen, f_text) + local n = ({uint16 = 2, uint32 = 4})[lentype] + assert(n) + + if f_textlen then + t:add(f_textlen, tvb(offset, n)) + end + local textlen = tvb(offset, n):uint() * 2 + if minetest_check_length(tvb, offset + n + textlen, t) then + t:add(f_text, tvb(offset + n, textlen), tvb(offset + n, textlen):ustring()) + return offset + n + textlen + end +end